summaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/Kconfig1263
-rw-r--r--drivers/media/video/Makefile218
-rw-r--r--drivers/media/video/adp1653.c487
-rw-r--r--drivers/media/video/adv7170.c410
-rw-r--r--drivers/media/video/adv7175.c460
-rw-r--r--drivers/media/video/adv7180.c667
-rw-r--r--drivers/media/video/adv7183.c699
-rw-r--r--drivers/media/video/adv7183_regs.h107
-rw-r--r--drivers/media/video/adv7343.c476
-rw-r--r--drivers/media/video/adv7343_regs.h181
-rw-r--r--drivers/media/video/adv7393.c487
-rw-r--r--drivers/media/video/adv7393_regs.h188
-rw-r--r--drivers/media/video/ak881x.c359
-rw-r--r--drivers/media/video/aptina-pll.c173
-rw-r--r--drivers/media/video/aptina-pll.h56
-rw-r--r--drivers/media/video/arv.c885
-rw-r--r--drivers/media/video/as3645a.c888
-rw-r--r--drivers/media/video/atmel-isi.c1099
-rw-r--r--drivers/media/video/au0828/Kconfig18
-rw-r--r--drivers/media/video/au0828/Makefile9
-rw-r--r--drivers/media/video/au0828/au0828-cards.c339
-rw-r--r--drivers/media/video/au0828/au0828-cards.h27
-rw-r--r--drivers/media/video/au0828/au0828-core.c295
-rw-r--r--drivers/media/video/au0828/au0828-dvb.c458
-rw-r--r--drivers/media/video/au0828/au0828-i2c.c390
-rw-r--r--drivers/media/video/au0828/au0828-reg.h65
-rw-r--r--drivers/media/video/au0828/au0828-vbi.c138
-rw-r--r--drivers/media/video/au0828/au0828-video.c1998
-rw-r--r--drivers/media/video/au0828/au0828.h302
-rw-r--r--drivers/media/video/blackfin/Kconfig10
-rw-r--r--drivers/media/video/blackfin/Makefile2
-rw-r--r--drivers/media/video/blackfin/bfin_capture.c1063
-rw-r--r--drivers/media/video/blackfin/ppi.c271
-rw-r--r--drivers/media/video/bt819.c517
-rw-r--r--drivers/media/video/bt856.c273
-rw-r--r--drivers/media/video/bt866.c243
-rw-r--r--drivers/media/video/bt8xx/Kconfig27
-rw-r--r--drivers/media/video/bt8xx/Makefile13
-rw-r--r--drivers/media/video/bt8xx/bt848.h369
-rw-r--r--drivers/media/video/bt8xx/bttv-audio-hook.c382
-rw-r--r--drivers/media/video/bt8xx/bttv-audio-hook.h23
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c4895
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c4630
-rw-r--r--drivers/media/video/bt8xx/bttv-gpio.c189
-rw-r--r--drivers/media/video/bt8xx/bttv-i2c.c397
-rw-r--r--drivers/media/video/bt8xx/bttv-if.c121
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c589
-rw-r--r--drivers/media/video/bt8xx/bttv-risc.c909
-rw-r--r--drivers/media/video/bt8xx/bttv-vbi.c459
-rw-r--r--drivers/media/video/bt8xx/bttv.h376
-rw-r--r--drivers/media/video/bt8xx/bttvp.h535
-rw-r--r--drivers/media/video/btcx-risc.c260
-rw-r--r--drivers/media/video/btcx-risc.h34
-rw-r--r--drivers/media/video/bw-qcam.c1113
-rw-r--r--drivers/media/video/c-qcam.c883
-rw-r--r--drivers/media/video/cpia2/Kconfig9
-rw-r--r--drivers/media/video/cpia2/Makefile3
-rw-r--r--drivers/media/video/cpia2/cpia2.h487
-rw-r--r--drivers/media/video/cpia2/cpia2_core.c2413
-rw-r--r--drivers/media/video/cpia2/cpia2_registers.h476
-rw-r--r--drivers/media/video/cpia2/cpia2_usb.c955
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c1250
-rw-r--r--drivers/media/video/cs5345.c252
-rw-r--r--drivers/media/video/cs53l32a.c251
-rw-r--r--drivers/media/video/cx18/Kconfig35
-rw-r--r--drivers/media/video/cx18/Makefile13
-rw-r--r--drivers/media/video/cx18/cx18-alsa-main.c295
-rw-r--r--drivers/media/video/cx18/cx18-alsa-mixer.c175
-rw-r--r--drivers/media/video/cx18/cx18-alsa-mixer.h23
-rw-r--r--drivers/media/video/cx18/cx18-alsa-pcm.c356
-rw-r--r--drivers/media/video/cx18/cx18-alsa-pcm.h27
-rw-r--r--drivers/media/video/cx18/cx18-alsa.h75
-rw-r--r--drivers/media/video/cx18/cx18-audio.c92
-rw-r--r--drivers/media/video/cx18/cx18-audio.h24
-rw-r--r--drivers/media/video/cx18/cx18-av-audio.c471
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c1401
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h391
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c223
-rw-r--r--drivers/media/video/cx18/cx18-av-vbi.c311
-rw-r--r--drivers/media/video/cx18/cx18-cards.c638
-rw-r--r--drivers/media/video/cx18/cx18-cards.h157
-rw-r--r--drivers/media/video/cx18/cx18-controls.c131
-rw-r--r--drivers/media/video/cx18/cx18-controls.h24
-rw-r--r--drivers/media/video/cx18/cx18-driver.c1359
-rw-r--r--drivers/media/video/cx18/cx18-driver.h730
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c605
-rw-r--r--drivers/media/video/cx18/cx18-dvb.h25
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c881
-rw-r--r--drivers/media/video/cx18/cx18-fileops.h41
-rw-r--r--drivers/media/video/cx18/cx18-firmware.c453
-rw-r--r--drivers/media/video/cx18/cx18-firmware.h25
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c347
-rw-r--r--drivers/media/video/cx18/cx18-gpio.h34
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c330
-rw-r--r--drivers/media/video/cx18/cx18-i2c.h29
-rw-r--r--drivers/media/video/cx18/cx18-io.c97
-rw-r--r--drivers/media/video/cx18/cx18-io.h191
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c1194
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.h31
-rw-r--r--drivers/media/video/cx18/cx18-irq.c81
-rw-r--r--drivers/media/video/cx18/cx18-irq.h35
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c870
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.h95
-rw-r--r--drivers/media/video/cx18/cx18-queue.c443
-rw-r--r--drivers/media/video/cx18/cx18-queue.h98
-rw-r--r--drivers/media/video/cx18/cx18-scb.c122
-rw-r--r--drivers/media/video/cx18/cx18-scb.h280
-rw-r--r--drivers/media/video/cx18/cx18-streams.c1060
-rw-r--r--drivers/media/video/cx18/cx18-streams.h62
-rw-r--r--drivers/media/video/cx18/cx18-vbi.c277
-rw-r--r--drivers/media/video/cx18/cx18-vbi.h26
-rw-r--r--drivers/media/video/cx18/cx18-version.h28
-rw-r--r--drivers/media/video/cx18/cx18-video.c32
-rw-r--r--drivers/media/video/cx18/cx18-video.h22
-rw-r--r--drivers/media/video/cx18/cx23418.h492
-rw-r--r--drivers/media/video/cx231xx/Kconfig51
-rw-r--r--drivers/media/video/cx231xx/Makefile16
-rw-r--r--drivers/media/video/cx231xx/cx231xx-417.c2195
-rw-r--r--drivers/media/video/cx231xx/cx231xx-audio.c780
-rw-r--r--drivers/media/video/cx231xx/cx231xx-avcore.c3087
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c1370
-rw-r--r--drivers/media/video/cx231xx/cx231xx-conf-reg.h495
-rw-r--r--drivers/media/video/cx231xx/cx231xx-core.c1736
-rw-r--r--drivers/media/video/cx231xx/cx231xx-dif.h3178
-rw-r--r--drivers/media/video/cx231xx/cx231xx-dvb.c796
-rw-r--r--drivers/media/video/cx231xx/cx231xx-i2c.c532
-rw-r--r--drivers/media/video/cx231xx/cx231xx-input.c119
-rw-r--r--drivers/media/video/cx231xx/cx231xx-pcb-cfg.c795
-rw-r--r--drivers/media/video/cx231xx/cx231xx-pcb-cfg.h231
-rw-r--r--drivers/media/video/cx231xx/cx231xx-reg.h1564
-rw-r--r--drivers/media/video/cx231xx/cx231xx-vbi.c710
-rw-r--r--drivers/media/video/cx231xx/cx231xx-vbi.h65
-rw-r--r--drivers/media/video/cx231xx/cx231xx-video.c2645
-rw-r--r--drivers/media/video/cx231xx/cx231xx.h1012
-rw-r--r--drivers/media/video/cx2341x.c1726
-rw-r--r--drivers/media/video/cx23885/Kconfig46
-rw-r--r--drivers/media/video/cx23885/Makefile15
-rw-r--r--drivers/media/video/cx23885/altera-ci.c837
-rw-r--r--drivers/media/video/cx23885/altera-ci.h100
-rw-r--r--drivers/media/video/cx23885/cimax2.c536
-rw-r--r--drivers/media/video/cx23885/cimax2.h47
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c1788
-rw-r--r--drivers/media/video/cx23885/cx23885-alsa.c535
-rw-r--r--drivers/media/video/cx23885/cx23885-av.c35
-rw-r--r--drivers/media/video/cx23885/cx23885-av.h27
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c1680
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c2234
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c1357
-rw-r--r--drivers/media/video/cx23885/cx23885-f300.c177
-rw-r--r--drivers/media/video/cx23885/cx23885-f300.h2
-rw-r--r--drivers/media/video/cx23885/cx23885-i2c.c396
-rw-r--r--drivers/media/video/cx23885/cx23885-input.c356
-rw-r--r--drivers/media/video/cx23885/cx23885-input.h30
-rw-r--r--drivers/media/video/cx23885/cx23885-ioctl.c208
-rw-r--r--drivers/media/video/cx23885/cx23885-ioctl.h39
-rw-r--r--drivers/media/video/cx23885/cx23885-ir.c117
-rw-r--r--drivers/media/video/cx23885/cx23885-ir.h31
-rw-r--r--drivers/media/video/cx23885/cx23885-reg.h452
-rw-r--r--drivers/media/video/cx23885/cx23885-vbi.c295
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c1926
-rw-r--r--drivers/media/video/cx23885/cx23885.h653
-rw-r--r--drivers/media/video/cx23885/cx23888-ir.c1271
-rw-r--r--drivers/media/video/cx23885/cx23888-ir.h28
-rw-r--r--drivers/media/video/cx23885/netup-eeprom.c107
-rw-r--r--drivers/media/video/cx23885/netup-eeprom.h42
-rw-r--r--drivers/media/video/cx23885/netup-init.c125
-rw-r--r--drivers/media/video/cx23885/netup-init.h25
-rw-r--r--drivers/media/video/cx25821/Kconfig34
-rw-r--r--drivers/media/video/cx25821/Makefile13
-rw-r--r--drivers/media/video/cx25821/cx25821-alsa.c784
-rw-r--r--drivers/media/video/cx25821/cx25821-audio-upstream.c778
-rw-r--r--drivers/media/video/cx25821/cx25821-audio-upstream.h62
-rw-r--r--drivers/media/video/cx25821/cx25821-audio.h62
-rw-r--r--drivers/media/video/cx25821/cx25821-biffuncs.h45
-rw-r--r--drivers/media/video/cx25821/cx25821-cards.c72
-rw-r--r--drivers/media/video/cx25821/cx25821-core.c1502
-rw-r--r--drivers/media/video/cx25821/cx25821-gpio.c98
-rw-r--r--drivers/media/video/cx25821/cx25821-i2c.c416
-rw-r--r--drivers/media/video/cx25821/cx25821-medusa-defines.h42
-rw-r--r--drivers/media/video/cx25821/cx25821-medusa-reg.h455
-rw-r--r--drivers/media/video/cx25821/cx25821-medusa-video.c787
-rw-r--r--drivers/media/video/cx25821/cx25821-medusa-video.h49
-rw-r--r--drivers/media/video/cx25821/cx25821-reg.h1592
-rw-r--r--drivers/media/video/cx25821/cx25821-sram.h261
-rw-r--r--drivers/media/video/cx25821/cx25821-video-upstream-ch2.c802
-rw-r--r--drivers/media/video/cx25821/cx25821-video-upstream-ch2.h138
-rw-r--r--drivers/media/video/cx25821/cx25821-video-upstream.c856
-rw-r--r--drivers/media/video/cx25821/cx25821-video-upstream.h139
-rw-r--r--drivers/media/video/cx25821/cx25821-video.c1990
-rw-r--r--drivers/media/video/cx25821/cx25821-video.h186
-rw-r--r--drivers/media/video/cx25821/cx25821.h615
-rw-r--r--drivers/media/video/cx25840/Kconfig8
-rw-r--r--drivers/media/video/cx25840/Makefile6
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c571
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c5340
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h137
-rw-r--r--drivers/media/video/cx25840/cx25840-firmware.c166
-rw-r--r--drivers/media/video/cx25840/cx25840-ir.c1281
-rw-r--r--drivers/media/video/cx25840/cx25840-vbi.c256
-rw-r--r--drivers/media/video/cx88/Kconfig86
-rw-r--r--drivers/media/video/cx88/Makefile16
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c975
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c1299
-rw-r--r--drivers/media/video/cx88/cx88-cards.c3811
-rw-r--r--drivers/media/video/cx88/cx88-core.c1131
-rw-r--r--drivers/media/video/cx88/cx88-dsp.c322
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c1778
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c184
-rw-r--r--drivers/media/video/cx88/cx88-input.c635
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c929
-rw-r--r--drivers/media/video/cx88/cx88-reg.h836
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c1059
-rw-r--r--drivers/media/video/cx88/cx88-vbi.c245
-rw-r--r--drivers/media/video/cx88/cx88-video.c2075
-rw-r--r--drivers/media/video/cx88/cx88-vp3054-i2c.c159
-rw-r--r--drivers/media/video/cx88/cx88-vp3054-i2c.h41
-rw-r--r--drivers/media/video/cx88/cx88.h748
-rw-r--r--drivers/media/video/davinci/Kconfig121
-rw-r--r--drivers/media/video/davinci/Makefile20
-rw-r--r--drivers/media/video/davinci/ccdc_hw_device.h110
-rw-r--r--drivers/media/video/davinci/dm355_ccdc.c1072
-rw-r--r--drivers/media/video/davinci/dm355_ccdc_regs.h310
-rw-r--r--drivers/media/video/davinci/dm644x_ccdc.c1081
-rw-r--r--drivers/media/video/davinci/dm644x_ccdc_regs.h153
-rw-r--r--drivers/media/video/davinci/isif.c1162
-rw-r--r--drivers/media/video/davinci/isif_regs.h269
-rw-r--r--drivers/media/video/davinci/vpbe.c886
-rw-r--r--drivers/media/video/davinci/vpbe_display.c1830
-rw-r--r--drivers/media/video/davinci/vpbe_osd.c1605
-rw-r--r--drivers/media/video/davinci/vpbe_osd_regs.h364
-rw-r--r--drivers/media/video/davinci/vpbe_venc.c706
-rw-r--r--drivers/media/video/davinci/vpbe_venc_regs.h177
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c2079
-rw-r--r--drivers/media/video/davinci/vpif.c514
-rw-r--r--drivers/media/video/davinci/vpif.h688
-rw-r--r--drivers/media/video/davinci/vpif_capture.c2444
-rw-r--r--drivers/media/video/davinci/vpif_capture.h170
-rw-r--r--drivers/media/video/davinci/vpif_display.c1998
-rw-r--r--drivers/media/video/davinci/vpif_display.h181
-rw-r--r--drivers/media/video/davinci/vpss.c482
-rw-r--r--drivers/media/video/em28xx/Kconfig58
-rw-r--r--drivers/media/video/em28xx/Makefile15
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c752
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c3417
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c1264
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c1197
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c568
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c645
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h226
-rw-r--r--drivers/media/video/em28xx/em28xx-vbi.c145
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c2606
-rw-r--r--drivers/media/video/em28xx/em28xx.h809
-rw-r--r--drivers/media/video/fsl-viu.c1673
-rw-r--r--drivers/media/video/gspca/Kconfig425
-rw-r--r--drivers/media/video/gspca/Makefile93
-rw-r--r--drivers/media/video/gspca/autogain_functions.c178
-rw-r--r--drivers/media/video/gspca/autogain_functions.h183
-rw-r--r--drivers/media/video/gspca/benq.c289
-rw-r--r--drivers/media/video/gspca/conex.c966
-rw-r--r--drivers/media/video/gspca/cpia1.c1905
-rw-r--r--drivers/media/video/gspca/etoms.c799
-rw-r--r--drivers/media/video/gspca/finepix.c306
-rw-r--r--drivers/media/video/gspca/gl860/Kconfig8
-rw-r--r--drivers/media/video/gspca/gl860/Makefile10
-rw-r--r--drivers/media/video/gspca/gl860/gl860-mi1320.c536
-rw-r--r--drivers/media/video/gspca/gl860/gl860-mi2020.c733
-rw-r--r--drivers/media/video/gspca/gl860/gl860-ov2640.c489
-rw-r--r--drivers/media/video/gspca/gl860/gl860-ov9655.c336
-rw-r--r--drivers/media/video/gspca/gl860/gl860.c725
-rw-r--r--drivers/media/video/gspca/gl860/gl860.h105
-rw-r--r--drivers/media/video/gspca/gspca.c2456
-rw-r--r--drivers/media/video/gspca/gspca.h259
-rw-r--r--drivers/media/video/gspca/jeilinj.c548
-rw-r--r--drivers/media/video/gspca/jl2005bcd.c557
-rw-r--r--drivers/media/video/gspca/jpeg.h168
-rw-r--r--drivers/media/video/gspca/kinect.c408
-rw-r--r--drivers/media/video/gspca/konica.c487
-rw-r--r--drivers/media/video/gspca/m5602/Kconfig11
-rw-r--r--drivers/media/video/gspca/m5602/Makefile11
-rw-r--r--drivers/media/video/gspca/m5602/m5602_bridge.h163
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c424
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.c647
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.h271
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.c488
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.h260
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c881
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.h307
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.c763
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.h272
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c726
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.h283
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c605
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.h193
-rw-r--r--drivers/media/video/gspca/m5602/m5602_sensor.h70
-rw-r--r--drivers/media/video/gspca/mars.c439
-rw-r--r--drivers/media/video/gspca/mr97310a.c1091
-rw-r--r--drivers/media/video/gspca/nw80x.c2110
-rw-r--r--drivers/media/video/gspca/ov519.c4991
-rw-r--r--drivers/media/video/gspca/ov534.c1544
-rw-r--r--drivers/media/video/gspca/ov534_9.c1500
-rw-r--r--drivers/media/video/gspca/pac207.c469
-rw-r--r--drivers/media/video/gspca/pac7302.c932
-rw-r--r--drivers/media/video/gspca/pac7311.c701
-rw-r--r--drivers/media/video/gspca/pac_common.h134
-rw-r--r--drivers/media/video/gspca/se401.c739
-rw-r--r--drivers/media/video/gspca/se401.h90
-rw-r--r--drivers/media/video/gspca/sn9c2028.c735
-rw-r--r--drivers/media/video/gspca/sn9c2028.h51
-rw-r--r--drivers/media/video/gspca/sn9c20x.c2428
-rw-r--r--drivers/media/video/gspca/sonixb.c1493
-rw-r--r--drivers/media/video/gspca/sonixj.c3206
-rw-r--r--drivers/media/video/gspca/spca1528.c444
-rw-r--r--drivers/media/video/gspca/spca500.c990
-rw-r--r--drivers/media/video/gspca/spca501.c2054
-rw-r--r--drivers/media/video/gspca/spca505.c807
-rw-r--r--drivers/media/video/gspca/spca506.c612
-rw-r--r--drivers/media/video/gspca/spca508.c1540
-rw-r--r--drivers/media/video/gspca/spca561.c936
-rw-r--r--drivers/media/video/gspca/sq905.c440
-rw-r--r--drivers/media/video/gspca/sq905c.c347
-rw-r--r--drivers/media/video/gspca/sq930x.c1172
-rw-r--r--drivers/media/video/gspca/stk014.c446
-rw-r--r--drivers/media/video/gspca/stv0680.c353
-rw-r--r--drivers/media/video/gspca/stv06xx/Kconfig9
-rw-r--r--drivers/media/video/gspca/stv06xx/Makefile10
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c634
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.h116
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c540
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h206
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c434
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h144
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_sensor.h87
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_st6422.c285
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_st6422.h52
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c272
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h255
-rw-r--r--drivers/media/video/gspca/sunplus.c1085
-rw-r--r--drivers/media/video/gspca/t613.c1054
-rw-r--r--drivers/media/video/gspca/topro.c4969
-rw-r--r--drivers/media/video/gspca/tv8532.c378
-rw-r--r--drivers/media/video/gspca/vc032x.c3853
-rw-r--r--drivers/media/video/gspca/vicam.c365
-rw-r--r--drivers/media/video/gspca/w996Xcf.c567
-rw-r--r--drivers/media/video/gspca/xirlink_cit.c3145
-rw-r--r--drivers/media/video/gspca/zc3xx-reg.h251
-rw-r--r--drivers/media/video/gspca/zc3xx.c7024
-rw-r--r--drivers/media/video/hdpvr/Kconfig10
-rw-r--r--drivers/media/video/hdpvr/Makefile7
-rw-r--r--drivers/media/video/hdpvr/hdpvr-control.c200
-rw-r--r--drivers/media/video/hdpvr/hdpvr-core.c472
-rw-r--r--drivers/media/video/hdpvr/hdpvr-i2c.c231
-rw-r--r--drivers/media/video/hdpvr/hdpvr-video.c1289
-rw-r--r--drivers/media/video/hdpvr/hdpvr.h317
-rw-r--r--drivers/media/video/hexium_gemini.c430
-rw-r--r--drivers/media/video/hexium_orion.c502
-rw-r--r--drivers/media/video/imx074.c475
-rw-r--r--drivers/media/video/indycam.c390
-rw-r--r--drivers/media/video/indycam.h93
-rw-r--r--drivers/media/video/ir-kbd-i2c.c489
-rw-r--r--drivers/media/video/ivtv/Kconfig45
-rw-r--r--drivers/media/video/ivtv/Makefile14
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.c1370
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h309
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.c163
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.h28
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c1498
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h839
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c1038
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.h44
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.c398
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.h31
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.c374
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.h29
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c760
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.h32
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c1899
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.h35
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c1038
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.h53
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.c387
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.h35
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.c297
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.h96
-rw-r--r--drivers/media/video/ivtv/ivtv-routing.c119
-rw-r--r--drivers/media/video/ivtv/ivtv-routing.h27
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c1018
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.h37
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.c234
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.h48
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c549
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.h34
-rw-r--r--drivers/media/video/ivtv/ivtv-version.h26
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c1296
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.h44
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c1317
-rw-r--r--drivers/media/video/ks0127.c724
-rw-r--r--drivers/media/video/ks0127.h51
-rw-r--r--drivers/media/video/m52790.c216
-rw-r--r--drivers/media/video/m5mols/Kconfig6
-rw-r--r--drivers/media/video/m5mols/Makefile3
-rw-r--r--drivers/media/video/m5mols/m5mols.h334
-rw-r--r--drivers/media/video/m5mols/m5mols_capture.c155
-rw-r--r--drivers/media/video/m5mols/m5mols_controls.c628
-rw-r--r--drivers/media/video/m5mols/m5mols_core.c990
-rw-r--r--drivers/media/video/m5mols/m5mols_reg.h362
-rw-r--r--drivers/media/video/marvell-ccic/Kconfig23
-rw-r--r--drivers/media/video/marvell-ccic/Makefile6
-rw-r--r--drivers/media/video/marvell-ccic/cafe-driver.c654
-rw-r--r--drivers/media/video/marvell-ccic/mcam-core.c1878
-rw-r--r--drivers/media/video/marvell-ccic/mcam-core.h322
-rw-r--r--drivers/media/video/marvell-ccic/mmp-driver.c380
-rw-r--r--drivers/media/video/mem2mem_testdev.c1120
-rw-r--r--drivers/media/video/meye.c1964
-rw-r--r--drivers/media/video/meye.h324
-rw-r--r--drivers/media/video/msp3400-driver.c899
-rw-r--r--drivers/media/video/msp3400-driver.h137
-rw-r--r--drivers/media/video/msp3400-kthreads.c1165
-rw-r--r--drivers/media/video/mt9m001.c737
-rw-r--r--drivers/media/video/mt9m032.c878
-rw-r--r--drivers/media/video/mt9m111.c1014
-rw-r--r--drivers/media/video/mt9p031.c1071
-rw-r--r--drivers/media/video/mt9t001.c833
-rw-r--r--drivers/media/video/mt9t031.c857
-rw-r--r--drivers/media/video/mt9t112.c1125
-rw-r--r--drivers/media/video/mt9v011.c712
-rw-r--r--drivers/media/video/mt9v022.c879
-rw-r--r--drivers/media/video/mt9v032.c763
-rw-r--r--drivers/media/video/mx1_camera.c889
-rw-r--r--drivers/media/video/mx2_camera.c1884
-rw-r--r--drivers/media/video/mx2_emmaprp.c1016
-rw-r--r--drivers/media/video/mx3_camera.c1292
-rw-r--r--drivers/media/video/mxb.c886
-rw-r--r--drivers/media/video/noon010pc30.c851
-rw-r--r--drivers/media/video/omap/Kconfig14
-rw-r--r--drivers/media/video/omap/Makefile8
-rw-r--r--drivers/media/video/omap/omap_vout.c2290
-rw-r--r--drivers/media/video/omap/omap_vout_vrfb.c390
-rw-r--r--drivers/media/video/omap/omap_vout_vrfb.h40
-rw-r--r--drivers/media/video/omap/omap_voutdef.h225
-rw-r--r--drivers/media/video/omap/omap_voutlib.c339
-rw-r--r--drivers/media/video/omap/omap_voutlib.h36
-rw-r--r--drivers/media/video/omap1_camera.c1723
-rw-r--r--drivers/media/video/omap24xxcam-dma.c601
-rw-r--r--drivers/media/video/omap24xxcam.c1881
-rw-r--r--drivers/media/video/omap24xxcam.h593
-rw-r--r--drivers/media/video/omap3isp/Makefile11
-rw-r--r--drivers/media/video/omap3isp/cfa_coef_table.h61
-rw-r--r--drivers/media/video/omap3isp/gamma_table.h90
-rw-r--r--drivers/media/video/omap3isp/isp.c2232
-rw-r--r--drivers/media/video/omap3isp/isp.h351
-rw-r--r--drivers/media/video/omap3isp/ispccdc.c2535
-rw-r--r--drivers/media/video/omap3isp/ispccdc.h209
-rw-r--r--drivers/media/video/omap3isp/ispccp2.c1171
-rw-r--r--drivers/media/video/omap3isp/ispccp2.h98
-rw-r--r--drivers/media/video/omap3isp/ispcsi2.c1305
-rw-r--r--drivers/media/video/omap3isp/ispcsi2.h165
-rw-r--r--drivers/media/video/omap3isp/ispcsiphy.c249
-rw-r--r--drivers/media/video/omap3isp/ispcsiphy.h63
-rw-r--r--drivers/media/video/omap3isp/isph3a.h117
-rw-r--r--drivers/media/video/omap3isp/isph3a_aewb.c374
-rw-r--r--drivers/media/video/omap3isp/isph3a_af.c429
-rw-r--r--drivers/media/video/omap3isp/isphist.c520
-rw-r--r--drivers/media/video/omap3isp/isphist.h40
-rw-r--r--drivers/media/video/omap3isp/isppreview.c2369
-rw-r--r--drivers/media/video/omap3isp/isppreview.h173
-rw-r--r--drivers/media/video/omap3isp/ispqueue.c1157
-rw-r--r--drivers/media/video/omap3isp/ispqueue.h187
-rw-r--r--drivers/media/video/omap3isp/ispreg.h1586
-rw-r--r--drivers/media/video/omap3isp/ispresizer.c1776
-rw-r--r--drivers/media/video/omap3isp/ispresizer.h146
-rw-r--r--drivers/media/video/omap3isp/ispstat.c1102
-rw-r--r--drivers/media/video/omap3isp/ispstat.h169
-rw-r--r--drivers/media/video/omap3isp/ispvideo.c1392
-rw-r--r--drivers/media/video/omap3isp/ispvideo.h214
-rw-r--r--drivers/media/video/omap3isp/luma_enhance_table.h42
-rw-r--r--drivers/media/video/omap3isp/noise_filter_table.h30
-rw-r--r--drivers/media/video/ov2640.c1108
-rw-r--r--drivers/media/video/ov5642.c1073
-rw-r--r--drivers/media/video/ov6650.c1053
-rw-r--r--drivers/media/video/ov7670.c1586
-rw-r--r--drivers/media/video/ov772x.c1126
-rw-r--r--drivers/media/video/ov9640.c746
-rw-r--r--drivers/media/video/ov9640.h207
-rw-r--r--drivers/media/video/ov9740.c1005
-rw-r--r--drivers/media/video/pms.c1152
-rw-r--r--drivers/media/video/pvrusb2/Kconfig65
-rw-r--r--drivers/media/video/pvrusb2/Makefile22
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.c96
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.h37
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-context.c431
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-context.h94
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c95
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h48
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ctrl.c609
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ctrl.h122
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c166
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h52
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debug.h69
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.c335
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.h52
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c569
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h199
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-dvb.c435
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-dvb.h41
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-eeprom.c164
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-eeprom.h39
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.c552
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.h42
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h72
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h406
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c5202
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h360
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c698
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.h40
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-io.c695
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-io.h102
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ioread.c512
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ioread.h48
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c182
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-std.c411
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-std.h59
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c861
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.h46
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-util.h62
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c1413
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.h39
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.c114
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.h48
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.c70
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.h52
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2.h42
-rw-r--r--drivers/media/video/pwc/Kconfig48
-rw-r--r--drivers/media/video/pwc/Makefile4
-rw-r--r--drivers/media/video/pwc/philips.txt236
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c553
-rw-r--r--drivers/media/video/pwc/pwc-dec1.c32
-rw-r--r--drivers/media/video/pwc/pwc-dec1.h39
-rw-r--r--drivers/media/video/pwc/pwc-dec23.c691
-rw-r--r--drivers/media/video/pwc/pwc-dec23.h61
-rw-r--r--drivers/media/video/pwc/pwc-if.c1165
-rw-r--r--drivers/media/video/pwc/pwc-kiara.c892
-rw-r--r--drivers/media/video/pwc/pwc-kiara.h48
-rw-r--r--drivers/media/video/pwc/pwc-misc.c93
-rw-r--r--drivers/media/video/pwc/pwc-nala.h66
-rw-r--r--drivers/media/video/pwc/pwc-timon.c1448
-rw-r--r--drivers/media/video/pwc/pwc-timon.h63
-rw-r--r--drivers/media/video/pwc/pwc-uncompress.c107
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c1053
-rw-r--r--drivers/media/video/pwc/pwc.h393
-rw-r--r--drivers/media/video/pxa_camera.c1852
-rw-r--r--drivers/media/video/rj54n1cb0c.c1414
-rw-r--r--drivers/media/video/s2255drv.c2689
-rw-r--r--drivers/media/video/s5k6aa.c1670
-rw-r--r--drivers/media/video/s5p-fimc/Kconfig48
-rw-r--r--drivers/media/video/s5p-fimc/Makefile7
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c1738
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c1239
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h713
-rw-r--r--drivers/media/video/s5p-fimc/fimc-lite-reg.c300
-rw-r--r--drivers/media/video/s5p-fimc/fimc-lite-reg.h150
-rw-r--r--drivers/media/video/s5p-fimc/fimc-lite.c1606
-rw-r--r--drivers/media/video/s5p-fimc/fimc-lite.h213
-rw-r--r--drivers/media/video/s5p-fimc/fimc-m2m.c854
-rw-r--r--drivers/media/video/s5p-fimc/fimc-mdevice.c1037
-rw-r--r--drivers/media/video/s5p-fimc/fimc-mdevice.h120
-rw-r--r--drivers/media/video/s5p-fimc/fimc-reg.c775
-rw-r--r--drivers/media/video/s5p-fimc/fimc-reg.h326
-rw-r--r--drivers/media/video/s5p-fimc/mipi-csis.c722
-rw-r--r--drivers/media/video/s5p-fimc/mipi-csis.h25
-rw-r--r--drivers/media/video/s5p-g2d/Makefile3
-rw-r--r--drivers/media/video/s5p-g2d/g2d-hw.c109
-rw-r--r--drivers/media/video/s5p-g2d/g2d-regs.h115
-rw-r--r--drivers/media/video/s5p-g2d/g2d.c832
-rw-r--r--drivers/media/video/s5p-g2d/g2d.h86
-rw-r--r--drivers/media/video/s5p-jpeg/Makefile2
-rw-r--r--drivers/media/video/s5p-jpeg/jpeg-core.c1515
-rw-r--r--drivers/media/video/s5p-jpeg/jpeg-core.h150
-rw-r--r--drivers/media/video/s5p-jpeg/jpeg-hw.h357
-rw-r--r--drivers/media/video/s5p-jpeg/jpeg-regs.h170
-rw-r--r--drivers/media/video/s5p-mfc/Makefile5
-rw-r--r--drivers/media/video/s5p-mfc/regs-mfc.h418
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc.c1223
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_cmd.c120
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_cmd.h30
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_common.h570
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c343
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h29
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_debug.h48
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_dec.c1044
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_dec.h23
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_enc.c1834
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_enc.h23
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_intr.c92
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_intr.h26
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_opr.c1397
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_opr.h93
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_pm.c137
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_pm.h24
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_shm.c47
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_shm.h90
-rw-r--r--drivers/media/video/s5p-tv/Kconfig86
-rw-r--r--drivers/media/video/s5p-tv/Makefile19
-rw-r--r--drivers/media/video/s5p-tv/hdmi_drv.c1007
-rw-r--r--drivers/media/video/s5p-tv/hdmiphy_drv.c329
-rw-r--r--drivers/media/video/s5p-tv/mixer.h365
-rw-r--r--drivers/media/video/s5p-tv/mixer_drv.c487
-rw-r--r--drivers/media/video/s5p-tv/mixer_grp_layer.c270
-rw-r--r--drivers/media/video/s5p-tv/mixer_reg.c553
-rw-r--r--drivers/media/video/s5p-tv/mixer_video.c1112
-rw-r--r--drivers/media/video/s5p-tv/mixer_vp_layer.c241
-rw-r--r--drivers/media/video/s5p-tv/regs-hdmi.h146
-rw-r--r--drivers/media/video/s5p-tv/regs-mixer.h122
-rw-r--r--drivers/media/video/s5p-tv/regs-sdo.h63
-rw-r--r--drivers/media/video/s5p-tv/regs-vp.h88
-rw-r--r--drivers/media/video/s5p-tv/sdo_drv.c452
-rw-r--r--drivers/media/video/s5p-tv/sii9234_drv.c422
-rw-r--r--drivers/media/video/saa6588.c542
-rw-r--r--drivers/media/video/saa7110.c494
-rw-r--r--drivers/media/video/saa7115.c1727
-rw-r--r--drivers/media/video/saa711x_regs.h549
-rw-r--r--drivers/media/video/saa7127.c855
-rw-r--r--drivers/media/video/saa7134/Kconfig64
-rw-r--r--drivers/media/video/saa7134/Makefile16
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c1012
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c1209
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c8026
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c1368
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c1936
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c590
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c435
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c1045
-rw-r--r--drivers/media/video/saa7134/saa7134-reg.h378
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c327
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c1087
-rw-r--r--drivers/media/video/saa7134/saa7134-vbi.c255
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c2661
-rw-r--r--drivers/media/video/saa7134/saa7134.h856
-rw-r--r--drivers/media/video/saa7164/Kconfig18
-rw-r--r--drivers/media/video/saa7164/Makefile12
-rw-r--r--drivers/media/video/saa7164/saa7164-api.c1519
-rw-r--r--drivers/media/video/saa7164/saa7164-buffer.c322
-rw-r--r--drivers/media/video/saa7164/saa7164-bus.c475
-rw-r--r--drivers/media/video/saa7164/saa7164-cards.c773
-rw-r--r--drivers/media/video/saa7164/saa7164-cmd.c589
-rw-r--r--drivers/media/video/saa7164/saa7164-core.c1526
-rw-r--r--drivers/media/video/saa7164/saa7164-dvb.c556
-rw-r--r--drivers/media/video/saa7164/saa7164-encoder.c1500
-rw-r--r--drivers/media/video/saa7164/saa7164-fw.c613
-rw-r--r--drivers/media/video/saa7164/saa7164-i2c.c125
-rw-r--r--drivers/media/video/saa7164/saa7164-reg.h219
-rw-r--r--drivers/media/video/saa7164/saa7164-types.h442
-rw-r--r--drivers/media/video/saa7164/saa7164-vbi.c1374
-rw-r--r--drivers/media/video/saa7164/saa7164.h617
-rw-r--r--drivers/media/video/saa717x.c1378
-rw-r--r--drivers/media/video/saa7185.c377
-rw-r--r--drivers/media/video/saa7191.c659
-rw-r--r--drivers/media/video/saa7191.h245
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c2331
-rw-r--r--drivers/media/video/sh_mobile_csi2.c398
-rw-r--r--drivers/media/video/sh_vou.c1497
-rw-r--r--drivers/media/video/smiapp-pll.c418
-rw-r--r--drivers/media/video/smiapp-pll.h103
-rw-r--r--drivers/media/video/smiapp/Kconfig7
-rw-r--r--drivers/media/video/smiapp/Makefile5
-rw-r--r--drivers/media/video/smiapp/smiapp-core.c2895
-rw-r--r--drivers/media/video/smiapp/smiapp-limits.c132
-rw-r--r--drivers/media/video/smiapp/smiapp-limits.h128
-rw-r--r--drivers/media/video/smiapp/smiapp-quirk.c306
-rw-r--r--drivers/media/video/smiapp/smiapp-quirk.h83
-rw-r--r--drivers/media/video/smiapp/smiapp-reg-defs.h503
-rw-r--r--drivers/media/video/smiapp/smiapp-reg.h122
-rw-r--r--drivers/media/video/smiapp/smiapp-regs.c273
-rw-r--r--drivers/media/video/smiapp/smiapp-regs.h49
-rw-r--r--drivers/media/video/smiapp/smiapp.h252
-rw-r--r--drivers/media/video/sn9c102/Kconfig14
-rw-r--r--drivers/media/video/sn9c102/Makefile15
-rw-r--r--drivers/media/video/sn9c102/sn9c102.h211
-rw-r--r--drivers/media/video/sn9c102/sn9c102_config.h86
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c3421
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h147
-rw-r--r--drivers/media/video/sn9c102/sn9c102_hv7131d.c264
-rw-r--r--drivers/media/video/sn9c102/sn9c102_hv7131r.c363
-rw-r--r--drivers/media/video/sn9c102/sn9c102_mi0343.c352
-rw-r--r--drivers/media/video/sn9c102/sn9c102_mi0360.c453
-rw-r--r--drivers/media/video/sn9c102/sn9c102_mt9v111.c260
-rw-r--r--drivers/media/video/sn9c102/sn9c102_ov7630.c626
-rw-r--r--drivers/media/video/sn9c102/sn9c102_ov7660.c538
-rw-r--r--drivers/media/video/sn9c102/sn9c102_pas106b.c302
-rw-r--r--drivers/media/video/sn9c102/sn9c102_pas202bcb.c335
-rw-r--r--drivers/media/video/sn9c102/sn9c102_sensor.h307
-rw-r--r--drivers/media/video/sn9c102/sn9c102_tas5110c1b.c154
-rw-r--r--drivers/media/video/sn9c102/sn9c102_tas5110d.c119
-rw-r--r--drivers/media/video/sn9c102/sn9c102_tas5130d1b.c165
-rw-r--r--drivers/media/video/soc_camera.c1546
-rw-r--r--drivers/media/video/soc_camera_platform.c197
-rw-r--r--drivers/media/video/soc_mediabus.c493
-rw-r--r--drivers/media/video/sr030pc30.c871
-rw-r--r--drivers/media/video/sta2x11_vip.c1550
-rw-r--r--drivers/media/video/sta2x11_vip.h40
-rw-r--r--drivers/media/video/stk-sensor.c595
-rw-r--r--drivers/media/video/stk-webcam.c1380
-rw-r--r--drivers/media/video/stk-webcam.h134
-rw-r--r--drivers/media/video/tcm825x.c937
-rw-r--r--drivers/media/video/tcm825x.h200
-rw-r--r--drivers/media/video/tda7432.c485
-rw-r--r--drivers/media/video/tda9840.c224
-rw-r--r--drivers/media/video/tea6415c.c187
-rw-r--r--drivers/media/video/tea6415c.h27
-rw-r--r--drivers/media/video/tea6420.c169
-rw-r--r--drivers/media/video/tea6420.h24
-rw-r--r--drivers/media/video/ths7303.c140
-rw-r--r--drivers/media/video/timblogiw.c880
-rw-r--r--drivers/media/video/tlg2300/Kconfig16
-rw-r--r--drivers/media/video/tlg2300/Makefile9
-rw-r--r--drivers/media/video/tlg2300/pd-alsa.c332
-rw-r--r--drivers/media/video/tlg2300/pd-common.h281
-rw-r--r--drivers/media/video/tlg2300/pd-dvb.c596
-rw-r--r--drivers/media/video/tlg2300/pd-main.c536
-rw-r--r--drivers/media/video/tlg2300/pd-radio.c421
-rw-r--r--drivers/media/video/tlg2300/pd-video.c1668
-rw-r--r--drivers/media/video/tlg2300/vendorcmds.h243
-rw-r--r--drivers/media/video/tlv320aic23b.c230
-rw-r--r--drivers/media/video/tm6000/Kconfig33
-rw-r--r--drivers/media/video/tm6000/Makefile15
-rw-r--r--drivers/media/video/tm6000/tm6000-alsa.c528
-rw-r--r--drivers/media/video/tm6000/tm6000-cards.c1413
-rw-r--r--drivers/media/video/tm6000/tm6000-core.c935
-rw-r--r--drivers/media/video/tm6000/tm6000-dvb.c467
-rw-r--r--drivers/media/video/tm6000/tm6000-i2c.c334
-rw-r--r--drivers/media/video/tm6000/tm6000-input.c498
-rw-r--r--drivers/media/video/tm6000/tm6000-regs.h600
-rw-r--r--drivers/media/video/tm6000/tm6000-stds.c638
-rw-r--r--drivers/media/video/tm6000/tm6000-usb-isoc.h50
-rw-r--r--drivers/media/video/tm6000/tm6000-video.c1818
-rw-r--r--drivers/media/video/tm6000/tm6000.h399
-rw-r--r--drivers/media/video/tuner-core.c1354
-rw-r--r--drivers/media/video/tvaudio.c2118
-rw-r--r--drivers/media/video/tveeprom.c792
-rw-r--r--drivers/media/video/tvp514x.c1166
-rw-r--r--drivers/media/video/tvp514x_regs.h287
-rw-r--r--drivers/media/video/tvp5150.c1274
-rw-r--r--drivers/media/video/tvp5150_reg.h139
-rw-r--r--drivers/media/video/tvp7002.c1145
-rw-r--r--drivers/media/video/tvp7002_reg.h150
-rw-r--r--drivers/media/video/tw9910.c956
-rw-r--r--drivers/media/video/upd64031a.c274
-rw-r--r--drivers/media/video/upd64083.c246
-rw-r--r--drivers/media/video/usbvision/Kconfig12
-rw-r--r--drivers/media/video/usbvision/Makefile6
-rw-r--r--drivers/media/video/usbvision/usbvision-cards.c1133
-rw-r--r--drivers/media/video/usbvision/usbvision-cards.h69
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c2518
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c456
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c1690
-rw-r--r--drivers/media/video/usbvision/usbvision.h535
-rw-r--r--drivers/media/video/uvc/Kconfig19
-rw-r--r--drivers/media/video/uvc/Makefile6
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c2165
-rw-r--r--drivers/media/video/uvc/uvc_debugfs.c136
-rw-r--r--drivers/media/video/uvc/uvc_driver.c2448
-rw-r--r--drivers/media/video/uvc/uvc_entity.c126
-rw-r--r--drivers/media/video/uvc/uvc_isight.c137
-rw-r--r--drivers/media/video/uvc/uvc_queue.c360
-rw-r--r--drivers/media/video/uvc/uvc_status.c237
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c1317
-rw-r--r--drivers/media/video/uvc/uvc_video.c1861
-rw-r--r--drivers/media/video/uvc/uvcvideo.h709
-rw-r--r--drivers/media/video/v4l2-common.c623
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c1045
-rw-r--r--drivers/media/video/v4l2-ctrls.c2651
-rw-r--r--drivers/media/video/v4l2-dev.c1038
-rw-r--r--drivers/media/video/v4l2-device.c280
-rw-r--r--drivers/media/video/v4l2-event.c313
-rw-r--r--drivers/media/video/v4l2-fh.c120
-rw-r--r--drivers/media/video/v4l2-int-device.c164
-rw-r--r--drivers/media/video/v4l2-ioctl.c2330
-rw-r--r--drivers/media/video/v4l2-mem2mem.c647
-rw-r--r--drivers/media/video/v4l2-subdev.c470
-rw-r--r--drivers/media/video/via-camera.c1514
-rw-r--r--drivers/media/video/via-camera.h93
-rw-r--r--drivers/media/video/videobuf-core.c1189
-rw-r--r--drivers/media/video/videobuf-dma-contig.c510
-rw-r--r--drivers/media/video/videobuf-dma-sg.c633
-rw-r--r--drivers/media/video/videobuf-dvb.c403
-rw-r--r--drivers/media/video/videobuf-vmalloc.c349
-rw-r--r--drivers/media/video/videobuf2-core.c2387
-rw-r--r--drivers/media/video/videobuf2-dma-contig.c186
-rw-r--r--drivers/media/video/videobuf2-dma-sg.c283
-rw-r--r--drivers/media/video/videobuf2-memops.c227
-rw-r--r--drivers/media/video/videobuf2-vmalloc.c222
-rw-r--r--drivers/media/video/vino.c4349
-rw-r--r--drivers/media/video/vino.h138
-rw-r--r--drivers/media/video/vivi.c1385
-rw-r--r--drivers/media/video/vp27smpx.c211
-rw-r--r--drivers/media/video/vpx3220.c591
-rw-r--r--drivers/media/video/vs6624.c928
-rw-r--r--drivers/media/video/vs6624_regs.h337
-rw-r--r--drivers/media/video/w9966.c981
-rw-r--r--drivers/media/video/wm8739.c294
-rw-r--r--drivers/media/video/wm8775.c342
-rw-r--r--drivers/media/video/zoran/Kconfig74
-rw-r--r--drivers/media/video/zoran/Makefile6
-rw-r--r--drivers/media/video/zoran/videocodec.c407
-rw-r--r--drivers/media/video/zoran/videocodec.h353
-rw-r--r--drivers/media/video/zoran/zoran.h403
-rw-r--r--drivers/media/video/zoran/zoran_card.c1524
-rw-r--r--drivers/media/video/zoran/zoran_card.h54
-rw-r--r--drivers/media/video/zoran/zoran_device.c1640
-rw-r--r--drivers/media/video/zoran/zoran_device.h95
-rw-r--r--drivers/media/video/zoran/zoran_driver.c3090
-rw-r--r--drivers/media/video/zoran/zoran_procfs.c225
-rw-r--r--drivers/media/video/zoran/zoran_procfs.h36
-rw-r--r--drivers/media/video/zoran/zr36016.c524
-rw-r--r--drivers/media/video/zoran/zr36016.h111
-rw-r--r--drivers/media/video/zoran/zr36050.c900
-rw-r--r--drivers/media/video/zoran/zr36050.h184
-rw-r--r--drivers/media/video/zoran/zr36057.h168
-rw-r--r--drivers/media/video/zoran/zr36060.c1010
-rw-r--r--drivers/media/video/zoran/zr36060.h220
-rw-r--r--drivers/media/video/zr364xx.c1643
820 files changed, 0 insertions, 524653 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
deleted file mode 100644
index c128fac0ce2..00000000000
--- a/drivers/media/video/Kconfig
+++ /dev/null
@@ -1,1263 +0,0 @@
-#
-# Generic video config states
-#
-
-config VIDEO_V4L2
- tristate
- depends on VIDEO_DEV && VIDEO_V4L2_COMMON
- default y
-
-config VIDEOBUF_GEN
- tristate
-
-config VIDEOBUF_DMA_SG
- depends on HAS_DMA
- select VIDEOBUF_GEN
- tristate
-
-config VIDEOBUF_VMALLOC
- select VIDEOBUF_GEN
- tristate
-
-config VIDEOBUF_DMA_CONTIG
- depends on HAS_DMA
- select VIDEOBUF_GEN
- tristate
-
-config VIDEOBUF_DVB
- tristate
- select VIDEOBUF_GEN
-
-config VIDEO_BTCX
- depends on PCI
- tristate
-
-config VIDEO_TVEEPROM
- tristate
- depends on I2C
-
-config VIDEO_TUNER
- tristate
- depends on MEDIA_TUNER
-
-config V4L2_MEM2MEM_DEV
- tristate
- depends on VIDEOBUF2_CORE
-
-config VIDEOBUF2_CORE
- tristate
-
-config VIDEOBUF2_MEMOPS
- tristate
-
-config VIDEOBUF2_DMA_CONTIG
- select VIDEOBUF2_CORE
- select VIDEOBUF2_MEMOPS
- tristate
-
-config VIDEOBUF2_VMALLOC
- select VIDEOBUF2_CORE
- select VIDEOBUF2_MEMOPS
- tristate
-
-
-config VIDEOBUF2_DMA_SG
- #depends on HAS_DMA
- select VIDEOBUF2_CORE
- select VIDEOBUF2_MEMOPS
- tristate
-#
-# Multimedia Video device configuration
-#
-
-menuconfig VIDEO_CAPTURE_DRIVERS
- bool "Video capture adapters"
- depends on VIDEO_V4L2
- depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT
- default y
- ---help---
- Say Y here to enable selecting the video adapters for
- webcams, analog TV, and hybrid analog/digital TV.
- Some of those devices also supports FM radio.
-
-if VIDEO_CAPTURE_DRIVERS && VIDEO_V4L2
-
-config VIDEO_ADV_DEBUG
- bool "Enable advanced debug functionality"
- default n
- ---help---
- Say Y here to enable advanced debugging functionality on some
- V4L devices.
- In doubt, say N.
-
-config VIDEO_FIXED_MINOR_RANGES
- bool "Enable old-style fixed minor ranges for video devices"
- default n
- ---help---
- Say Y here to enable the old-style fixed-range minor assignments.
- Only useful if you rely on the old behavior and use mknod instead of udev.
-
- When in doubt, say N.
-
-config VIDEO_HELPER_CHIPS_AUTO
- bool "Autoselect pertinent encoders/decoders and other helper chips"
- default y if !EXPERT
- ---help---
- Most video cards may require additional modules to encode or
- decode audio/video standards. This option will autoselect
- all pertinent modules to each selected video module.
-
- Unselect this only if you know exactly what you are doing, since
- it may break support on some boards.
-
- In doubt, say Y.
-
-config VIDEO_IR_I2C
- tristate "I2C module for IR" if !VIDEO_HELPER_CHIPS_AUTO
- depends on I2C && RC_CORE
- default y
- ---help---
- Most boards have an IR chip directly connected via GPIO. However,
- some video boards have the IR connected via I2C bus.
-
- If your board doesn't have an I2C IR chip, you may disable this
- option.
-
- In doubt, say Y.
-
-#
-# Encoder / Decoder module configuration
-#
-
-menu "Encoders, decoders, sensors and other helper chips"
- visible if !VIDEO_HELPER_CHIPS_AUTO
-
-comment "Audio decoders, processors and mixers"
-
-config VIDEO_TVAUDIO
- tristate "Simple audio decoder chips"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for several audio decoder chips found on some bt8xx boards:
- Philips: tda9840, tda9873h, tda9874h/a, tda9850, tda985x, tea6300,
- tea6320, tea6420, tda8425, ta8874z.
- Microchip: pic16c54 based design on ProVideo PV951 board.
-
- To compile this driver as a module, choose M here: the
- module will be called tvaudio.
-
-config VIDEO_TDA7432
- tristate "Philips TDA7432 audio processor"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for tda7432 audio decoder chip found on some bt8xx boards.
-
- To compile this driver as a module, choose M here: the
- module will be called tda7432.
-
-config VIDEO_TDA9840
- tristate "Philips TDA9840 audio processor"
- depends on I2C
- ---help---
- Support for tda9840 audio decoder chip found on some Zoran boards.
-
- To compile this driver as a module, choose M here: the
- module will be called tda9840.
-
-config VIDEO_TEA6415C
- tristate "Philips TEA6415C audio processor"
- depends on I2C
- ---help---
- Support for tea6415c audio decoder chip found on some bt8xx boards.
-
- To compile this driver as a module, choose M here: the
- module will be called tea6415c.
-
-config VIDEO_TEA6420
- tristate "Philips TEA6420 audio processor"
- depends on I2C
- ---help---
- Support for tea6420 audio decoder chip found on some bt8xx boards.
-
- To compile this driver as a module, choose M here: the
- module will be called tea6420.
-
-config VIDEO_MSP3400
- tristate "Micronas MSP34xx audio decoders"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Micronas MSP34xx series of audio decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called msp3400.
-
-config VIDEO_CS5345
- tristate "Cirrus Logic CS5345 audio ADC"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Cirrus Logic CS5345 24-bit, 192 kHz
- stereo A/D converter.
-
- To compile this driver as a module, choose M here: the
- module will be called cs5345.
-
-config VIDEO_CS53L32A
- tristate "Cirrus Logic CS53L32A audio ADC"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Cirrus Logic CS53L32A low voltage
- stereo A/D converter.
-
- To compile this driver as a module, choose M here: the
- module will be called cs53l32a.
-
-config VIDEO_TLV320AIC23B
- tristate "Texas Instruments TLV320AIC23B audio codec"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
- ---help---
- Support for the Texas Instruments TLV320AIC23B audio codec.
-
- To compile this driver as a module, choose M here: the
- module will be called tlv320aic23b.
-
-config VIDEO_WM8775
- tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Wolfson Microelectronics WM8775 high
- performance stereo A/D Converter with a 4 channel input mixer.
-
- To compile this driver as a module, choose M here: the
- module will be called wm8775.
-
-config VIDEO_WM8739
- tristate "Wolfson Microelectronics WM8739 stereo audio ADC"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Wolfson Microelectronics WM8739
- stereo A/D Converter.
-
- To compile this driver as a module, choose M here: the
- module will be called wm8739.
-
-config VIDEO_VP27SMPX
- tristate "Panasonic VP27s internal MPX"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the internal MPX of the Panasonic VP27s tuner.
-
- To compile this driver as a module, choose M here: the
- module will be called vp27smpx.
-
-comment "RDS decoders"
-
-config VIDEO_SAA6588
- tristate "SAA6588 Radio Chip RDS decoder support"
- depends on VIDEO_V4L2 && I2C
-
- help
- Support for this Radio Data System (RDS) decoder. This allows
- seeing radio station identification transmitted using this
- standard.
-
- To compile this driver as a module, choose M here: the
- module will be called saa6588.
-
-comment "Video decoders"
-
-config VIDEO_ADV7180
- tristate "Analog Devices ADV7180 decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Analog Devices ADV7180 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called adv7180.
-
-config VIDEO_ADV7183
- tristate "Analog Devices ADV7183 decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- V4l2 subdevice driver for the Analog Devices
- ADV7183 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called adv7183.
-
-config VIDEO_BT819
- tristate "BT819A VideoStream decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for BT819A video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called bt819.
-
-config VIDEO_BT856
- tristate "BT856 VideoStream decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for BT856 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called bt856.
-
-config VIDEO_BT866
- tristate "BT866 VideoStream decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for BT866 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called bt866.
-
-config VIDEO_KS0127
- tristate "KS0127 video decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for KS0127 video decoder.
-
- This chip is used on AverMedia AVS6EYES Zoran-based MJPEG
- cards.
-
- To compile this driver as a module, choose M here: the
- module will be called ks0127.
-
-config VIDEO_SAA7110
- tristate "Philips SAA7110 video decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Philips SAA7110 video decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7110.
-
-config VIDEO_SAA711X
- tristate "Philips SAA7111/3/4/5 video decoders"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Philips SAA7111/3/4/5 video decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7115.
-
-config VIDEO_SAA7191
- tristate "Philips SAA7191 video decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Philips SAA7191 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7191.
-
-config VIDEO_TVP514X
- tristate "Texas Instruments TVP514x video decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- This is a Video4Linux2 sensor-level driver for the TI TVP5146/47
- decoder. It is currently working with the TI OMAP3 camera
- controller.
-
- To compile this driver as a module, choose M here: the
- module will be called tvp514x.
-
-config VIDEO_TVP5150
- tristate "Texas Instruments TVP5150 video decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Texas Instruments TVP5150 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called tvp5150.
-
-config VIDEO_TVP7002
- tristate "Texas Instruments TVP7002 video decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Texas Instruments TVP7002 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called tvp7002.
-
-config VIDEO_VPX3220
- tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for VPX322x video decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called vpx3220.
-
-comment "Video and audio decoders"
-
-config VIDEO_SAA717X
- tristate "Philips SAA7171/3/4 audio/video decoders"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Philips SAA7171/3/4 audio/video decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called saa717x.
-
-source "drivers/media/video/cx25840/Kconfig"
-
-comment "MPEG video encoders"
-
-config VIDEO_CX2341X
- tristate "Conexant CX2341x MPEG encoders"
- depends on VIDEO_V4L2 && VIDEO_V4L2_COMMON
- ---help---
- Support for the Conexant CX23416 MPEG encoders
- and CX23415 MPEG encoder/decoders.
-
- This module currently supports the encoding functions only.
-
- To compile this driver as a module, choose M here: the
- module will be called cx2341x.
-
-comment "Video encoders"
-
-config VIDEO_SAA7127
- tristate "Philips SAA7127/9 digital video encoders"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Philips SAA7127/9 digital video encoders.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7127.
-
-config VIDEO_SAA7185
- tristate "Philips SAA7185 video encoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Philips SAA7185 video encoder.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7185.
-
-config VIDEO_ADV7170
- tristate "Analog Devices ADV7170 video encoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Analog Devices ADV7170 video encoder driver
-
- To compile this driver as a module, choose M here: the
- module will be called adv7170.
-
-config VIDEO_ADV7175
- tristate "Analog Devices ADV7175 video encoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Analog Devices ADV7175 video encoder driver
-
- To compile this driver as a module, choose M here: the
- module will be called adv7175.
-
-config VIDEO_ADV7343
- tristate "ADV7343 video encoder"
- depends on I2C
- help
- Support for Analog Devices I2C bus based ADV7343 encoder.
-
- To compile this driver as a module, choose M here: the
- module will be called adv7343.
-
-config VIDEO_ADV7393
- tristate "ADV7393 video encoder"
- depends on I2C
- help
- Support for Analog Devices I2C bus based ADV7393 encoder.
-
- To compile this driver as a module, choose M here: the
- module will be called adv7393.
-
-config VIDEO_AK881X
- tristate "AK8813/AK8814 video encoders"
- depends on I2C
- help
- Video output driver for AKM AK8813 and AK8814 TV encoders
-
-comment "Camera sensor devices"
-
-config VIDEO_APTINA_PLL
- tristate
-
-config VIDEO_SMIAPP_PLL
- tristate
-
-config VIDEO_OV7670
- tristate "OmniVision OV7670 sensor support"
- depends on I2C && VIDEO_V4L2
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a Video4Linux2 sensor-level driver for the OmniVision
- OV7670 VGA camera. It currently only works with the M88ALP01
- controller.
-
-config VIDEO_VS6624
- tristate "ST VS6624 sensor support"
- depends on VIDEO_V4L2 && I2C
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a Video4Linux2 sensor-level driver for the ST VS6624
- camera.
-
- To compile this driver as a module, choose M here: the
- module will be called vs6624.
-
-config VIDEO_MT9M032
- tristate "MT9M032 camera sensor support"
- depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
- depends on MEDIA_CAMERA_SUPPORT
- select VIDEO_APTINA_PLL
- ---help---
- This driver supports MT9M032 camera sensors from Aptina, monochrome
- models only.
-
-config VIDEO_MT9P031
- tristate "Aptina MT9P031 support"
- depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
- depends on MEDIA_CAMERA_SUPPORT
- select VIDEO_APTINA_PLL
- ---help---
- This is a Video4Linux2 sensor-level driver for the Aptina
- (Micron) mt9p031 5 Mpixel camera.
-
-config VIDEO_MT9T001
- tristate "Aptina MT9T001 support"
- depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a Video4Linux2 sensor-level driver for the Aptina
- (Micron) mt0t001 3 Mpixel camera.
-
-config VIDEO_MT9V011
- tristate "Micron mt9v011 sensor support"
- depends on I2C && VIDEO_V4L2
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a Video4Linux2 sensor-level driver for the Micron
- mt0v011 1.3 Mpixel camera. It currently only works with the
- em28xx driver.
-
-config VIDEO_MT9V032
- tristate "Micron MT9V032 sensor support"
- depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a Video4Linux2 sensor-level driver for the Micron
- MT9V032 752x480 CMOS sensor.
-
-config VIDEO_TCM825X
- tristate "TCM825x camera sensor support"
- depends on I2C && VIDEO_V4L2
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a driver for the Toshiba TCM825x VGA camera sensor.
- It is used for example in Nokia N800.
-
-config VIDEO_SR030PC30
- tristate "Siliconfile SR030PC30 sensor support"
- depends on I2C && VIDEO_V4L2
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This driver supports SR030PC30 VGA camera from Siliconfile
-
-config VIDEO_NOON010PC30
- tristate "Siliconfile NOON010PC30 sensor support"
- depends on I2C && VIDEO_V4L2 && EXPERIMENTAL && VIDEO_V4L2_SUBDEV_API
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This driver supports NOON010PC30 CIF camera from Siliconfile
-
-source "drivers/media/video/m5mols/Kconfig"
-
-config VIDEO_S5K6AA
- tristate "Samsung S5K6AAFX sensor support"
- depends on MEDIA_CAMERA_SUPPORT
- depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
- ---help---
- This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M
- camera sensor with an embedded SoC image signal processor.
-
-source "drivers/media/video/smiapp/Kconfig"
-
-comment "Flash devices"
-
-config VIDEO_ADP1653
- tristate "ADP1653 flash support"
- depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a driver for the ADP1653 flash controller. It is used for
- example in Nokia N900.
-
-config VIDEO_AS3645A
- tristate "AS3645A flash driver support"
- depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a driver for the AS3645A and LM3555 flash controllers. It has
- build in control for flash, torch and indicator LEDs.
-
-comment "Video improvement chips"
-
-config VIDEO_UPD64031A
- tristate "NEC Electronics uPD64031A Ghost Reduction"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the NEC Electronics uPD64031A Ghost Reduction
- video chip. It is most often found in NTSC TV cards made for
- Japan and is used to reduce the 'ghosting' effect that can
- be present in analog TV broadcasts.
-
- To compile this driver as a module, choose M here: the
- module will be called upd64031a.
-
-config VIDEO_UPD64083
- tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the NEC Electronics uPD64083 3-Dimensional Y/C
- separation video chip. It is used to improve the quality of
- the colors of a composite signal.
-
- To compile this driver as a module, choose M here: the
- module will be called upd64083.
-
-comment "Miscelaneous helper chips"
-
-config VIDEO_THS7303
- tristate "THS7303 Video Amplifier"
- depends on I2C
- help
- Support for TI THS7303 video amplifier
-
- To compile this driver as a module, choose M here: the
- module will be called ths7303.
-
-config VIDEO_M52790
- tristate "Mitsubishi M52790 A/V switch"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Mitsubishi M52790 A/V switch.
-
- To compile this driver as a module, choose M here: the
- module will be called m52790.
-
-endmenu # encoder / decoder chips
-
-config VIDEO_VIVI
- tristate "Virtual Video Driver"
- depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
- depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
- select FONT_8x16
- select VIDEOBUF2_VMALLOC
- default n
- ---help---
- Enables a virtual video driver. This device shows a color bar
- and a timestamp, as a real device would generate by using V4L2
- api.
- Say Y here if you want to test video apps or debug V4L devices.
- In doubt, say N.
-
-#
-# USB Multimedia device configuration
-#
-
-menuconfig V4L_USB_DRIVERS
- bool "V4L USB devices"
- depends on USB
- default y
-
-if V4L_USB_DRIVERS && MEDIA_CAMERA_SUPPORT
-
- comment "Webcam devices"
-
-source "drivers/media/video/uvc/Kconfig"
-
-source "drivers/media/video/gspca/Kconfig"
-
-source "drivers/media/video/pwc/Kconfig"
-
-source "drivers/media/video/cpia2/Kconfig"
-
-config USB_ZR364XX
- tristate "USB ZR364XX Camera support"
- depends on VIDEO_V4L2
- select VIDEOBUF_GEN
- select VIDEOBUF_VMALLOC
- ---help---
- Say Y here if you want to connect this type of camera to your
- computer's USB port.
- See <file:Documentation/video4linux/zr364xx.txt> for more info
- and list of supported cameras.
-
- To compile this driver as a module, choose M here: the
- module will be called zr364xx.
-
-config USB_STKWEBCAM
- tristate "USB Syntek DC1125 Camera support"
- depends on VIDEO_V4L2 && EXPERIMENTAL
- ---help---
- Say Y here if you want to use this type of camera.
- Supported devices are typically found in some Asus laptops,
- with USB id 174f:a311 and 05e1:0501. Other Syntek cameras
- may be supported by the stk11xx driver, from which this is
- derived, see <http://sourceforge.net/projects/syntekdriver/>
-
- To compile this driver as a module, choose M here: the
- module will be called stkwebcam.
-
-config USB_S2255
- tristate "USB Sensoray 2255 video capture device"
- depends on VIDEO_V4L2
- select VIDEOBUF_VMALLOC
- default n
- help
- Say Y here if you want support for the Sensoray 2255 USB device.
- This driver can be compiled as a module, called s2255drv.
-
-source "drivers/media/video/sn9c102/Kconfig"
-
-endif # V4L_USB_DRIVERS && MEDIA_CAMERA_SUPPORT
-
-if V4L_USB_DRIVERS
-
- comment "Webcam and/or TV USB devices"
-
-source "drivers/media/video/em28xx/Kconfig"
-
-endif
-
-if V4L_USB_DRIVERS && MEDIA_ANALOG_TV_SUPPORT
-
- comment "TV USB devices"
-
-source "drivers/media/video/au0828/Kconfig"
-
-source "drivers/media/video/pvrusb2/Kconfig"
-
-source "drivers/media/video/hdpvr/Kconfig"
-
-source "drivers/media/video/tlg2300/Kconfig"
-
-source "drivers/media/video/cx231xx/Kconfig"
-
-source "drivers/media/video/tm6000/Kconfig"
-
-source "drivers/media/video/usbvision/Kconfig"
-
-endif # V4L_USB_DRIVERS
-
-#
-# PCI drivers configuration - No devices here are for webcams
-#
-
-menuconfig V4L_PCI_DRIVERS
- bool "V4L PCI(e) devices"
- depends on PCI
- depends on MEDIA_ANALOG_TV_SUPPORT
- default y
- ---help---
- Say Y here to enable support for these PCI(e) drivers.
-
-if V4L_PCI_DRIVERS
-
-source "drivers/media/video/bt8xx/Kconfig"
-
-source "drivers/media/video/cx18/Kconfig"
-
-source "drivers/media/video/cx23885/Kconfig"
-
-source "drivers/media/video/cx25821/Kconfig"
-
-source "drivers/media/video/cx88/Kconfig"
-
-config VIDEO_HEXIUM_GEMINI
- tristate "Hexium Gemini frame grabber"
- depends on PCI && VIDEO_V4L2 && I2C
- select VIDEO_SAA7146_VV
- ---help---
- This is a video4linux driver for the Hexium Gemini frame
- grabber card by Hexium. Please note that the Gemini Dual
- card is *not* fully supported.
-
- To compile this driver as a module, choose M here: the
- module will be called hexium_gemini.
-
-config VIDEO_HEXIUM_ORION
- tristate "Hexium HV-PCI6 and Orion frame grabber"
- depends on PCI && VIDEO_V4L2 && I2C
- select VIDEO_SAA7146_VV
- ---help---
- This is a video4linux driver for the Hexium HV-PCI6 and
- Orion frame grabber cards by Hexium.
-
- To compile this driver as a module, choose M here: the
- module will be called hexium_orion.
-
-source "drivers/media/video/ivtv/Kconfig"
-
-config VIDEO_MEYE
- tristate "Sony Vaio Picturebook Motion Eye Video For Linux"
- depends on PCI && SONY_LAPTOP && VIDEO_V4L2
- ---help---
- This is the video4linux driver for the Motion Eye camera found
- in the Vaio Picturebook laptops. Please read the material in
- <file:Documentation/video4linux/meye.txt> for more information.
-
- If you say Y or M here, you need to say Y or M to "Sony Laptop
- Extras" in the misc device section.
-
- To compile this driver as a module, choose M here: the
- module will be called meye.
-
-config VIDEO_MXB
- tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
- depends on PCI && VIDEO_V4L2 && I2C
- select VIDEO_SAA7146_VV
- select VIDEO_TUNER
- select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TEA6420 if VIDEO_HELPER_CHIPS_AUTO
- ---help---
- This is a video4linux driver for the 'Multimedia eXtension Board'
- TV card by Siemens-Nixdorf.
-
- To compile this driver as a module, choose M here: the
- module will be called mxb.
-
-source "drivers/media/video/saa7134/Kconfig"
-
-source "drivers/media/video/saa7164/Kconfig"
-
-source "drivers/media/video/zoran/Kconfig"
-
-config STA2X11_VIP
- tristate "STA2X11 VIP Video For Linux"
- depends on STA2X11
- select VIDEO_ADV7180 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEOBUF_DMA_CONTIG
- depends on PCI && VIDEO_V4L2 && VIRT_TO_BUS
- help
- Say Y for support for STA2X11 VIP (Video Input Port) capture
- device.
-
- To compile this driver as a module, choose M here: the
- module will be called sta2x11_vip.
-
-endif # V4L_PCI_DRIVERS
-
-#
-# ISA & parallel port drivers configuration
-# All devices here are webcam or grabber devices
-#
-
-menuconfig V4L_ISA_PARPORT_DRIVERS
- bool "V4L ISA and parallel port devices"
- depends on ISA || PARPORT
- depends on MEDIA_CAMERA_SUPPORT
- default n
- ---help---
- Say Y here to enable support for these ISA and parallel port drivers.
-
-if V4L_ISA_PARPORT_DRIVERS
-
-config VIDEO_BWQCAM
- tristate "Quickcam BW Video For Linux"
- depends on PARPORT && VIDEO_V4L2
- help
- Say Y have if you the black and white version of the QuickCam
- camera. See the next option for the color version.
-
- To compile this driver as a module, choose M here: the
- module will be called bw-qcam.
-
-config VIDEO_CQCAM
- tristate "QuickCam Colour Video For Linux"
- depends on PARPORT && VIDEO_V4L2
- help
- This is the video4linux driver for the colour version of the
- Connectix QuickCam. If you have one of these cameras, say Y here,
- otherwise say N. This driver does not work with the original
- monochrome QuickCam, QuickCam VC or QuickClip. It is also available
- as a module (c-qcam).
- Read <file:Documentation/video4linux/CQcam.txt> for more information.
-
-config VIDEO_PMS
- tristate "Mediavision Pro Movie Studio Video For Linux"
- depends on ISA && VIDEO_V4L2
- help
- Say Y if you have the ISA Mediavision Pro Movie Studio
- capture card.
-
- To compile this driver as a module, choose M here: the
- module will be called pms.
-
-config VIDEO_W9966
- tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux"
- depends on PARPORT_1284 && PARPORT && VIDEO_V4L2
- help
- Video4linux driver for Winbond's w9966 based Webcams.
- Currently tested with the LifeView FlyCam Supra.
- If you have one of these cameras, say Y here
- otherwise say N.
- This driver is also available as a module (w9966).
-
- Check out <file:Documentation/video4linux/w9966.txt> for more
- information.
-
-endif # V4L_ISA_PARPORT_DRIVERS
-
-#
-# Platform drivers
-# All drivers here are currently for webcam support
-
-menuconfig V4L_PLATFORM_DRIVERS
- bool "V4L platform devices"
- depends on MEDIA_CAMERA_SUPPORT
- default n
- ---help---
- Say Y here to enable support for platform-specific V4L drivers.
-
-if V4L_PLATFORM_DRIVERS
-
-source "drivers/media/video/marvell-ccic/Kconfig"
-
-config VIDEO_VIA_CAMERA
- tristate "VIAFB camera controller support"
- depends on FB_VIA
- select VIDEOBUF_DMA_SG
- select VIDEO_OV7670
- help
- Driver support for the integrated camera controller in VIA
- Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems
- with ov7670 sensors.
-
-#
-# Platform multimedia device configuration
-#
-
-source "drivers/media/video/davinci/Kconfig"
-
-source "drivers/media/video/omap/Kconfig"
-
-source "drivers/media/video/blackfin/Kconfig"
-
-config VIDEO_SH_VOU
- tristate "SuperH VOU video output driver"
- depends on VIDEO_DEV && ARCH_SHMOBILE
- select VIDEOBUF_DMA_CONTIG
- help
- Support for the Video Output Unit (VOU) on SuperH SoCs.
-
-config VIDEO_VIU
- tristate "Freescale VIU Video Driver"
- depends on VIDEO_V4L2 && PPC_MPC512x
- select VIDEOBUF_DMA_CONTIG
- default y
- ---help---
- Support for Freescale VIU video driver. This device captures
- video data, or overlays video on DIU frame buffer.
-
- Say Y here if you want to enable VIU device on MPC5121e Rev2+.
- In doubt, say N.
-
-config VIDEO_TIMBERDALE
- tristate "Support for timberdale Video In/LogiWIN"
- depends on VIDEO_V4L2 && I2C && DMADEVICES
- select DMA_ENGINE
- select TIMB_DMA
- select VIDEO_ADV7180
- select VIDEOBUF_DMA_CONTIG
- ---help---
- Add support for the Video In peripherial of the timberdale FPGA.
-
-config VIDEO_VINO
- tristate "SGI Vino Video For Linux"
- depends on I2C && SGI_IP22 && VIDEO_V4L2
- select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO
- help
- Say Y here to build in support for the Vino video input system found
- on SGI Indy machines.
-
-config VIDEO_M32R_AR
- tristate "AR devices"
- depends on M32R && VIDEO_V4L2
- ---help---
- This is a video4linux driver for the Renesas AR (Artificial Retina)
- camera module.
-
-config VIDEO_M32R_AR_M64278
- tristate "AR device with color module M64278(VGA)"
- depends on PLAT_M32700UT
- select VIDEO_M32R_AR
- ---help---
- This is a video4linux driver for the Renesas AR (Artificial
- Retina) with M64278E-800 camera module.
- This module supports VGA(640x480 pixels) resolutions.
-
- To compile this driver as a module, choose M here: the
- module will be called arv.
-
-config VIDEO_OMAP3
- tristate "OMAP 3 Camera support (EXPERIMENTAL)"
- depends on OMAP_IOVMM && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3 && EXPERIMENTAL
- ---help---
- Driver for an OMAP 3 camera controller.
-
-config VIDEO_OMAP3_DEBUG
- bool "OMAP 3 Camera debug messages"
- depends on VIDEO_OMAP3
- ---help---
- Enable debug messages on OMAP 3 camera controller driver.
-
-config SOC_CAMERA
- tristate "SoC camera support"
- depends on VIDEO_V4L2 && HAS_DMA && I2C
- select VIDEOBUF_GEN
- select VIDEOBUF2_CORE
- help
- SoC Camera is a common API to several cameras, not connecting
- over a bus like PCI or USB. For example some i2c camera connected
- directly to the data bus of an SoC.
-
-config SOC_CAMERA_IMX074
- tristate "imx074 support"
- depends on SOC_CAMERA && I2C
- help
- This driver supports IMX074 cameras from Sony
-
-config SOC_CAMERA_MT9M001
- tristate "mt9m001 support"
- depends on SOC_CAMERA && I2C
- select GPIO_PCA953X if MT9M001_PCA9536_SWITCH
- help
- This driver supports MT9M001 cameras from Micron, monochrome
- and colour models.
-
-config SOC_CAMERA_MT9M111
- tristate "mt9m111, mt9m112 and mt9m131 support"
- depends on SOC_CAMERA && I2C
- help
- This driver supports MT9M111, MT9M112 and MT9M131 cameras from
- Micron/Aptina
-
-config SOC_CAMERA_MT9T031
- tristate "mt9t031 support"
- depends on SOC_CAMERA && I2C
- help
- This driver supports MT9T031 cameras from Micron.
-
-config SOC_CAMERA_MT9T112
- tristate "mt9t112 support"
- depends on SOC_CAMERA && I2C
- help
- This driver supports MT9T112 cameras from Aptina.
-
-config SOC_CAMERA_MT9V022
- tristate "mt9v022 support"
- depends on SOC_CAMERA && I2C
- select GPIO_PCA953X if MT9V022_PCA9536_SWITCH
- help
- This driver supports MT9V022 cameras from Micron
-
-config SOC_CAMERA_RJ54N1
- tristate "rj54n1cb0c support"
- depends on SOC_CAMERA && I2C
- help
- This is a rj54n1cb0c video driver
-
-config SOC_CAMERA_TW9910
- tristate "tw9910 support"
- depends on SOC_CAMERA && I2C
- help
- This is a tw9910 video driver
-
-config SOC_CAMERA_PLATFORM
- tristate "platform camera support"
- depends on SOC_CAMERA
- help
- This is a generic SoC camera platform driver, useful for testing
-
-config SOC_CAMERA_OV2640
- tristate "ov2640 camera support"
- depends on SOC_CAMERA && I2C
- help
- This is a ov2640 camera driver
-
-config SOC_CAMERA_OV5642
- tristate "ov5642 camera support"
- depends on SOC_CAMERA && I2C
- help
- This is a V4L2 camera driver for the OmniVision OV5642 sensor
-
-config SOC_CAMERA_OV6650
- tristate "ov6650 sensor support"
- depends on SOC_CAMERA && I2C
- ---help---
- This is a V4L2 SoC camera driver for the OmniVision OV6650 sensor
-
-config SOC_CAMERA_OV772X
- tristate "ov772x camera support"
- depends on SOC_CAMERA && I2C
- help
- This is a ov772x camera driver
-
-config SOC_CAMERA_OV9640
- tristate "ov9640 camera support"
- depends on SOC_CAMERA && I2C
- help
- This is a ov9640 camera driver
-
-config SOC_CAMERA_OV9740
- tristate "ov9740 camera support"
- depends on SOC_CAMERA && I2C
- help
- This is a ov9740 camera driver
-
-config MX1_VIDEO
- bool
-
-config VIDEO_MX1
- tristate "i.MX1/i.MXL CMOS Sensor Interface driver"
- depends on VIDEO_DEV && ARCH_MX1 && SOC_CAMERA
- select FIQ
- select VIDEOBUF_DMA_CONTIG
- select MX1_VIDEO
- ---help---
- This is a v4l2 driver for the i.MX1/i.MXL CMOS Sensor Interface
-
-config MX3_VIDEO
- bool
-
-config VIDEO_MX3
- tristate "i.MX3x Camera Sensor Interface driver"
- depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
- select VIDEOBUF2_DMA_CONTIG
- select MX3_VIDEO
- ---help---
- This is a v4l2 driver for the i.MX3x Camera Sensor Interface
-
-config VIDEO_PXA27x
- tristate "PXA27x Quick Capture Interface driver"
- depends on VIDEO_DEV && PXA27x && SOC_CAMERA
- select VIDEOBUF_DMA_SG
- ---help---
- This is a v4l2 driver for the PXA27x Quick Capture Interface
-
-config VIDEO_SH_MOBILE_CSI2
- tristate "SuperH Mobile MIPI CSI-2 Interface driver"
- depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK
- ---help---
- This is a v4l2 driver for the SuperH MIPI CSI-2 Interface
-
-config VIDEO_SH_MOBILE_CEU
- tristate "SuperH Mobile CEU Interface driver"
- depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK
- select VIDEOBUF2_DMA_CONTIG
- ---help---
- This is a v4l2 driver for the SuperH Mobile CEU Interface
-
-config VIDEO_OMAP1
- tristate "OMAP1 Camera Interface driver"
- depends on VIDEO_DEV && ARCH_OMAP1 && SOC_CAMERA
- select VIDEOBUF_DMA_CONTIG
- select VIDEOBUF_DMA_SG
- ---help---
- This is a v4l2 driver for the TI OMAP1 camera interface
-
-config VIDEO_OMAP2
- tristate "OMAP2 Camera Capture Interface driver"
- depends on VIDEO_DEV && ARCH_OMAP2
- select VIDEOBUF_DMA_SG
- ---help---
- This is a v4l2 driver for the TI OMAP2 camera capture interface
-
-config VIDEO_MX2_HOSTSUPPORT
- bool
-
-config VIDEO_MX2
- tristate "i.MX27/i.MX25 Camera Sensor Interface driver"
- depends on VIDEO_DEV && SOC_CAMERA && (MACH_MX27 || ARCH_MX25)
- select VIDEOBUF2_DMA_CONTIG
- select VIDEO_MX2_HOSTSUPPORT
- ---help---
- This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor
- Interface
-
-config VIDEO_ATMEL_ISI
- tristate "ATMEL Image Sensor Interface (ISI) support"
- depends on VIDEO_DEV && SOC_CAMERA && ARCH_AT91
- select VIDEOBUF2_DMA_CONTIG
- ---help---
- This module makes the ATMEL Image Sensor Interface available
- as a v4l2 device.
-
-source "drivers/media/video/s5p-fimc/Kconfig"
-source "drivers/media/video/s5p-tv/Kconfig"
-
-endif # V4L_PLATFORM_DRIVERS
-endif # VIDEO_CAPTURE_DRIVERS
-
-menuconfig V4L_MEM2MEM_DRIVERS
- bool "Memory-to-memory multimedia devices"
- depends on VIDEO_V4L2
- default n
- ---help---
- Say Y here to enable selecting drivers for V4L devices that
- use system memory for both source and destination buffers, as opposed
- to capture and output drivers, which use memory buffers for just
- one of those.
-
-if V4L_MEM2MEM_DRIVERS
-
-config VIDEO_MEM2MEM_TESTDEV
- tristate "Virtual test device for mem2mem framework"
- depends on VIDEO_DEV && VIDEO_V4L2
- select VIDEOBUF2_VMALLOC
- select V4L2_MEM2MEM_DEV
- default n
- ---help---
- This is a virtual test device for the memory-to-memory driver
- framework.
-
-config VIDEO_SAMSUNG_S5P_G2D
- tristate "Samsung S5P and EXYNOS4 G2D 2d graphics accelerator driver"
- depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
- select VIDEOBUF2_DMA_CONTIG
- select V4L2_MEM2MEM_DEV
- default n
- ---help---
- This is a v4l2 driver for Samsung S5P and EXYNOS4 G2D
- 2d graphics accelerator.
-
-config VIDEO_SAMSUNG_S5P_JPEG
- tristate "Samsung S5P/Exynos4 JPEG codec driver (EXPERIMENTAL)"
- depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P && EXPERIMENTAL
- select VIDEOBUF2_DMA_CONTIG
- select V4L2_MEM2MEM_DEV
- ---help---
- This is a v4l2 driver for Samsung S5P and EXYNOS4 JPEG codec
-
-config VIDEO_SAMSUNG_S5P_MFC
- tristate "Samsung S5P MFC 5.1 Video Codec"
- depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
- select VIDEOBUF2_DMA_CONTIG
- default n
- help
- MFC 5.1 driver for V4L2.
-
-config VIDEO_MX2_EMMAPRP
- tristate "MX2 eMMa-PrP support"
- depends on VIDEO_DEV && VIDEO_V4L2 && SOC_IMX27
- select VIDEOBUF2_DMA_CONTIG
- select V4L2_MEM2MEM_DEV
- help
- MX2X chips have a PrP that can be used to process buffers from
- memory to memory. Operations include resizing and format
- conversion.
-
-endif # V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
deleted file mode 100644
index b7da9faa3b0..00000000000
--- a/drivers/media/video/Makefile
+++ /dev/null
@@ -1,218 +0,0 @@
-#
-# Makefile for the video capture/playback device drivers.
-#
-
-tuner-objs := tuner-core.o
-
-msp3400-objs := msp3400-driver.o msp3400-kthreads.o
-
-stkwebcam-objs := stk-webcam.o stk-sensor.o
-
-omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o
-
-videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
- v4l2-event.o v4l2-ctrls.o v4l2-subdev.o
-ifeq ($(CONFIG_COMPAT),y)
- videodev-objs += v4l2-compat-ioctl32.o
-endif
-
-# V4L2 core modules
-
-obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o
-obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
-
-# Helper modules
-
-obj-$(CONFIG_VIDEO_APTINA_PLL) += aptina-pll.o
-
-# All i2c modules must come first:
-
-obj-$(CONFIG_VIDEO_TUNER) += tuner.o
-obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
-obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
-obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
-obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
-obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o
-obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o
-obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o
-obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
-obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o
-obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
-obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
-obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o
-obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
-obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
-obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o
-obj-$(CONFIG_VIDEO_ADV7183) += adv7183.o
-obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
-obj-$(CONFIG_VIDEO_ADV7393) += adv7393.o
-obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
-obj-$(CONFIG_VIDEO_VS6624) += vs6624.o
-obj-$(CONFIG_VIDEO_BT819) += bt819.o
-obj-$(CONFIG_VIDEO_BT856) += bt856.o
-obj-$(CONFIG_VIDEO_BT866) += bt866.o
-obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
-obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
-obj-$(CONFIG_VIDEO_VINO) += indycam.o
-obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
-obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
-obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
-obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
-obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
-obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
-obj-$(CONFIG_VIDEO_M52790) += m52790.o
-obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
-obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
-obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
-obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
-obj-$(CONFIG_VIDEO_CX25840) += cx25840/
-obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
-obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
-obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
-obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
-obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
-obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
-obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o
-obj-$(CONFIG_VIDEO_MT9T001) += mt9t001.o
-obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
-obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
-obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
-obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o
-obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/
-obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o
-obj-$(CONFIG_VIDEO_SMIAPP) += smiapp/
-obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o
-obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o
-
-obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o
-
-obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o
-obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
-obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
-obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
-obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o
-obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
-obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o
-obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o
-obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o
-obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
-obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
-obj-$(CONFIG_SOC_CAMERA_OV9740) += ov9740.o
-obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o
-obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
-
-# And now the v4l2 drivers:
-
-obj-$(CONFIG_VIDEO_BT848) += bt8xx/
-obj-$(CONFIG_VIDEO_ZORAN) += zoran/
-obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
-obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
-obj-$(CONFIG_VIDEO_W9966) += w9966.o
-obj-$(CONFIG_VIDEO_PMS) += pms.o
-obj-$(CONFIG_VIDEO_VINO) += vino.o
-obj-$(CONFIG_VIDEO_MEYE) += meye.o
-obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
-obj-$(CONFIG_VIDEO_CX88) += cx88/
-obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
-obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/
-obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
-obj-$(CONFIG_VIDEO_CX25821) += cx25821/
-obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
-obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
-obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
-obj-$(CONFIG_VIDEO_TM6000) += tm6000/
-obj-$(CONFIG_VIDEO_MXB) += mxb.o
-obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
-obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
-obj-$(CONFIG_STA2X11_VIP) += sta2x11_vip.o
-obj-$(CONFIG_VIDEO_TIMBERDALE) += timblogiw.o
-
-obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
-obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
-obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
-obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
-obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
-obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
-
-obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o
-obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
-obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o
-obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o
-obj-$(CONFIG_VIDEOBUF2_DMA_SG) += videobuf2-dma-sg.o
-
-obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
-
-obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
-
-obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
-
-obj-$(CONFIG_VIDEO_CAFE_CCIC) += marvell-ccic/
-obj-$(CONFIG_VIDEO_MMP_CAMERA) += marvell-ccic/
-
-obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o
-
-obj-$(CONFIG_VIDEO_OMAP3) += omap3isp/
-
-obj-$(CONFIG_USB_ZR364XX) += zr364xx.o
-obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o
-
-obj-$(CONFIG_USB_SN9C102) += sn9c102/
-obj-$(CONFIG_USB_PWC) += pwc/
-obj-$(CONFIG_USB_GSPCA) += gspca/
-
-obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/
-
-obj-$(CONFIG_USB_S2255) += s2255drv.o
-
-obj-$(CONFIG_VIDEO_IVTV) += ivtv/
-obj-$(CONFIG_VIDEO_CX18) += cx18/
-
-obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o
-obj-$(CONFIG_VIDEO_VIVI) += vivi.o
-obj-$(CONFIG_VIDEO_MEM2MEM_TESTDEV) += mem2mem_testdev.o
-obj-$(CONFIG_VIDEO_CX23885) += cx23885/
-
-obj-$(CONFIG_VIDEO_AK881X) += ak881x.o
-
-obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
-obj-$(CONFIG_SOC_CAMERA) += soc_camera.o soc_mediabus.o
-obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
-# soc-camera host drivers have to be linked after camera drivers
-obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o
-obj-$(CONFIG_VIDEO_MX2) += mx2_camera.o
-obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
-obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
-obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o
-obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
-obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o
-obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
-
-obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
-
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg/
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV) += s5p-tv/
-
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d/
-
-obj-$(CONFIG_BLACKFIN) += blackfin/
-
-obj-$(CONFIG_ARCH_DAVINCI) += davinci/
-
-obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o
-
-obj-$(CONFIG_VIDEO_AU0828) += au0828/
-
-obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/
-obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
-
-obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
-
-obj-y += davinci/
-
-obj-$(CONFIG_ARCH_OMAP) += omap/
-
-ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
diff --git a/drivers/media/video/adp1653.c b/drivers/media/video/adp1653.c
deleted file mode 100644
index 57e87090388..00000000000
--- a/drivers/media/video/adp1653.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * drivers/media/video/adp1653.c
- *
- * Copyright (C) 2008--2011 Nokia Corporation
- *
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * Contributors:
- * Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- * Tuukka Toivonen <tuukkat76@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- * TODO:
- * - fault interrupt handling
- * - hardware strobe
- * - power doesn't need to be ON if all lights are off
- *
- */
-
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <media/adp1653.h>
-#include <media/v4l2-device.h>
-
-#define TIMEOUT_MAX 820000
-#define TIMEOUT_STEP 54600
-#define TIMEOUT_MIN (TIMEOUT_MAX - ADP1653_REG_CONFIG_TMR_SET_MAX \
- * TIMEOUT_STEP)
-#define TIMEOUT_US_TO_CODE(t) ((TIMEOUT_MAX + (TIMEOUT_STEP / 2) - (t)) \
- / TIMEOUT_STEP)
-#define TIMEOUT_CODE_TO_US(c) (TIMEOUT_MAX - (c) * TIMEOUT_STEP)
-
-/* Write values into ADP1653 registers. */
-static int adp1653_update_hw(struct adp1653_flash *flash)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- u8 out_sel;
- u8 config = 0;
- int rval;
-
- out_sel = ADP1653_INDICATOR_INTENSITY_uA_TO_REG(
- flash->indicator_intensity->val)
- << ADP1653_REG_OUT_SEL_ILED_SHIFT;
-
- switch (flash->led_mode->val) {
- case V4L2_FLASH_LED_MODE_NONE:
- break;
- case V4L2_FLASH_LED_MODE_FLASH:
- /* Flash mode, light on with strobe, duration from timer */
- config = ADP1653_REG_CONFIG_TMR_CFG;
- config |= TIMEOUT_US_TO_CODE(flash->flash_timeout->val)
- << ADP1653_REG_CONFIG_TMR_SET_SHIFT;
- break;
- case V4L2_FLASH_LED_MODE_TORCH:
- /* Torch mode, light immediately on, duration indefinite */
- out_sel |= ADP1653_FLASH_INTENSITY_mA_TO_REG(
- flash->torch_intensity->val)
- << ADP1653_REG_OUT_SEL_HPLED_SHIFT;
- break;
- }
-
- rval = i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL, out_sel);
- if (rval < 0)
- return rval;
-
- rval = i2c_smbus_write_byte_data(client, ADP1653_REG_CONFIG, config);
- if (rval < 0)
- return rval;
-
- return 0;
-}
-
-static int adp1653_get_fault(struct adp1653_flash *flash)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- int fault;
- int rval;
-
- fault = i2c_smbus_read_byte_data(client, ADP1653_REG_FAULT);
- if (IS_ERR_VALUE(fault))
- return fault;
-
- flash->fault |= fault;
-
- if (!flash->fault)
- return 0;
-
- /* Clear faults. */
- rval = i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL, 0);
- if (IS_ERR_VALUE(rval))
- return rval;
-
- flash->led_mode->val = V4L2_FLASH_LED_MODE_NONE;
-
- rval = adp1653_update_hw(flash);
- if (IS_ERR_VALUE(rval))
- return rval;
-
- return flash->fault;
-}
-
-static int adp1653_strobe(struct adp1653_flash *flash, int enable)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- u8 out_sel = ADP1653_INDICATOR_INTENSITY_uA_TO_REG(
- flash->indicator_intensity->val)
- << ADP1653_REG_OUT_SEL_ILED_SHIFT;
- int rval;
-
- if (flash->led_mode->val != V4L2_FLASH_LED_MODE_FLASH)
- return -EBUSY;
-
- if (!enable)
- return i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL,
- out_sel);
-
- out_sel |= ADP1653_FLASH_INTENSITY_mA_TO_REG(
- flash->flash_intensity->val)
- << ADP1653_REG_OUT_SEL_HPLED_SHIFT;
- rval = i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL, out_sel);
- if (rval)
- return rval;
-
- /* Software strobe using i2c */
- rval = i2c_smbus_write_byte_data(client, ADP1653_REG_SW_STROBE,
- ADP1653_REG_SW_STROBE_SW_STROBE);
- if (rval)
- return rval;
- return i2c_smbus_write_byte_data(client, ADP1653_REG_SW_STROBE, 0);
-}
-
-/* --------------------------------------------------------------------------
- * V4L2 controls
- */
-
-static int adp1653_get_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct adp1653_flash *flash =
- container_of(ctrl->handler, struct adp1653_flash, ctrls);
- int rval;
-
- rval = adp1653_get_fault(flash);
- if (IS_ERR_VALUE(rval))
- return rval;
-
- ctrl->cur.val = 0;
-
- if (flash->fault & ADP1653_REG_FAULT_FLT_SCP)
- ctrl->cur.val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
- if (flash->fault & ADP1653_REG_FAULT_FLT_OT)
- ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE;
- if (flash->fault & ADP1653_REG_FAULT_FLT_TMR)
- ctrl->cur.val |= V4L2_FLASH_FAULT_TIMEOUT;
- if (flash->fault & ADP1653_REG_FAULT_FLT_OV)
- ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_VOLTAGE;
-
- flash->fault = 0;
-
- return 0;
-}
-
-static int adp1653_set_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct adp1653_flash *flash =
- container_of(ctrl->handler, struct adp1653_flash, ctrls);
- int rval;
-
- rval = adp1653_get_fault(flash);
- if (IS_ERR_VALUE(rval))
- return rval;
- if ((rval & (ADP1653_REG_FAULT_FLT_SCP |
- ADP1653_REG_FAULT_FLT_OT |
- ADP1653_REG_FAULT_FLT_OV)) &&
- (ctrl->id == V4L2_CID_FLASH_STROBE ||
- ctrl->id == V4L2_CID_FLASH_TORCH_INTENSITY ||
- ctrl->id == V4L2_CID_FLASH_LED_MODE))
- return -EBUSY;
-
- switch (ctrl->id) {
- case V4L2_CID_FLASH_STROBE:
- return adp1653_strobe(flash, 1);
- case V4L2_CID_FLASH_STROBE_STOP:
- return adp1653_strobe(flash, 0);
- }
-
- return adp1653_update_hw(flash);
-}
-
-static const struct v4l2_ctrl_ops adp1653_ctrl_ops = {
- .g_volatile_ctrl = adp1653_get_ctrl,
- .s_ctrl = adp1653_set_ctrl,
-};
-
-static int adp1653_init_controls(struct adp1653_flash *flash)
-{
- struct v4l2_ctrl *fault;
-
- v4l2_ctrl_handler_init(&flash->ctrls, 9);
-
- flash->led_mode =
- v4l2_ctrl_new_std_menu(&flash->ctrls, &adp1653_ctrl_ops,
- V4L2_CID_FLASH_LED_MODE,
- V4L2_FLASH_LED_MODE_TORCH, ~0x7, 0);
- v4l2_ctrl_new_std_menu(&flash->ctrls, &adp1653_ctrl_ops,
- V4L2_CID_FLASH_STROBE_SOURCE,
- V4L2_FLASH_STROBE_SOURCE_SOFTWARE, ~0x1, 0);
- v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
- V4L2_CID_FLASH_STROBE, 0, 0, 0, 0);
- v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
- V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0);
- flash->flash_timeout =
- v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
- V4L2_CID_FLASH_TIMEOUT, TIMEOUT_MIN,
- flash->platform_data->max_flash_timeout,
- TIMEOUT_STEP,
- flash->platform_data->max_flash_timeout);
- flash->flash_intensity =
- v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
- V4L2_CID_FLASH_INTENSITY,
- ADP1653_FLASH_INTENSITY_MIN,
- flash->platform_data->max_flash_intensity,
- 1, flash->platform_data->max_flash_intensity);
- flash->torch_intensity =
- v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
- V4L2_CID_FLASH_TORCH_INTENSITY,
- ADP1653_TORCH_INTENSITY_MIN,
- flash->platform_data->max_torch_intensity,
- ADP1653_FLASH_INTENSITY_STEP,
- flash->platform_data->max_torch_intensity);
- flash->indicator_intensity =
- v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
- V4L2_CID_FLASH_INDICATOR_INTENSITY,
- ADP1653_INDICATOR_INTENSITY_MIN,
- flash->platform_data->max_indicator_intensity,
- ADP1653_INDICATOR_INTENSITY_STEP,
- ADP1653_INDICATOR_INTENSITY_MIN);
- fault = v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
- V4L2_CID_FLASH_FAULT, 0,
- V4L2_FLASH_FAULT_OVER_VOLTAGE
- | V4L2_FLASH_FAULT_OVER_TEMPERATURE
- | V4L2_FLASH_FAULT_SHORT_CIRCUIT, 0, 0);
-
- if (flash->ctrls.error)
- return flash->ctrls.error;
-
- fault->flags |= V4L2_CTRL_FLAG_VOLATILE;
-
- flash->subdev.ctrl_handler = &flash->ctrls;
- return 0;
-}
-
-/* --------------------------------------------------------------------------
- * V4L2 subdev operations
- */
-
-static int
-adp1653_init_device(struct adp1653_flash *flash)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- int rval;
-
- /* Clear FAULT register by writing zero to OUT_SEL */
- rval = i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL, 0);
- if (rval < 0) {
- dev_err(&client->dev, "failed writing fault register\n");
- return -EIO;
- }
-
- mutex_lock(flash->ctrls.lock);
- /* Reset faults before reading new ones. */
- flash->fault = 0;
- rval = adp1653_get_fault(flash);
- mutex_unlock(flash->ctrls.lock);
- if (rval > 0) {
- dev_err(&client->dev, "faults detected: 0x%1.1x\n", rval);
- return -EIO;
- }
-
- mutex_lock(flash->ctrls.lock);
- rval = adp1653_update_hw(flash);
- mutex_unlock(flash->ctrls.lock);
- if (rval) {
- dev_err(&client->dev,
- "adp1653_update_hw failed at %s\n", __func__);
- return -EIO;
- }
-
- return 0;
-}
-
-static int
-__adp1653_set_power(struct adp1653_flash *flash, int on)
-{
- int ret;
-
- ret = flash->platform_data->power(&flash->subdev, on);
- if (ret < 0)
- return ret;
-
- if (!on)
- return 0;
-
- ret = adp1653_init_device(flash);
- if (ret < 0)
- flash->platform_data->power(&flash->subdev, 0);
-
- return ret;
-}
-
-static int
-adp1653_set_power(struct v4l2_subdev *subdev, int on)
-{
- struct adp1653_flash *flash = to_adp1653_flash(subdev);
- int ret = 0;
-
- mutex_lock(&flash->power_lock);
-
- /* If the power count is modified from 0 to != 0 or from != 0 to 0,
- * update the power state.
- */
- if (flash->power_count == !on) {
- ret = __adp1653_set_power(flash, !!on);
- if (ret < 0)
- goto done;
- }
-
- /* Update the power count. */
- flash->power_count += on ? 1 : -1;
- WARN_ON(flash->power_count < 0);
-
-done:
- mutex_unlock(&flash->power_lock);
- return ret;
-}
-
-static int adp1653_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- return adp1653_set_power(sd, 1);
-}
-
-static int adp1653_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- return adp1653_set_power(sd, 0);
-}
-
-static const struct v4l2_subdev_core_ops adp1653_core_ops = {
- .s_power = adp1653_set_power,
-};
-
-static const struct v4l2_subdev_ops adp1653_ops = {
- .core = &adp1653_core_ops,
-};
-
-static const struct v4l2_subdev_internal_ops adp1653_internal_ops = {
- .open = adp1653_open,
- .close = adp1653_close,
-};
-
-/* --------------------------------------------------------------------------
- * I2C driver
- */
-#ifdef CONFIG_PM
-
-static int adp1653_suspend(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct adp1653_flash *flash = to_adp1653_flash(subdev);
-
- if (!flash->power_count)
- return 0;
-
- return __adp1653_set_power(flash, 0);
-}
-
-static int adp1653_resume(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct adp1653_flash *flash = to_adp1653_flash(subdev);
-
- if (!flash->power_count)
- return 0;
-
- return __adp1653_set_power(flash, 1);
-}
-
-#else
-
-#define adp1653_suspend NULL
-#define adp1653_resume NULL
-
-#endif /* CONFIG_PM */
-
-static int adp1653_probe(struct i2c_client *client,
- const struct i2c_device_id *devid)
-{
- struct adp1653_flash *flash;
- int ret;
-
- /* we couldn't work without platform data */
- if (client->dev.platform_data == NULL)
- return -ENODEV;
-
- flash = kzalloc(sizeof(*flash), GFP_KERNEL);
- if (flash == NULL)
- return -ENOMEM;
-
- flash->platform_data = client->dev.platform_data;
-
- mutex_init(&flash->power_lock);
-
- v4l2_i2c_subdev_init(&flash->subdev, client, &adp1653_ops);
- flash->subdev.internal_ops = &adp1653_internal_ops;
- flash->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- ret = adp1653_init_controls(flash);
- if (ret)
- goto free_and_quit;
-
- ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0);
- if (ret < 0)
- goto free_and_quit;
-
- flash->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
-
- return 0;
-
-free_and_quit:
- v4l2_ctrl_handler_free(&flash->ctrls);
- kfree(flash);
- return ret;
-}
-
-static int __exit adp1653_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct adp1653_flash *flash = to_adp1653_flash(subdev);
-
- v4l2_device_unregister_subdev(&flash->subdev);
- v4l2_ctrl_handler_free(&flash->ctrls);
- media_entity_cleanup(&flash->subdev.entity);
- kfree(flash);
- return 0;
-}
-
-static const struct i2c_device_id adp1653_id_table[] = {
- { ADP1653_NAME, 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, adp1653_id_table);
-
-static struct dev_pm_ops adp1653_pm_ops = {
- .suspend = adp1653_suspend,
- .resume = adp1653_resume,
-};
-
-static struct i2c_driver adp1653_i2c_driver = {
- .driver = {
- .name = ADP1653_NAME,
- .pm = &adp1653_pm_ops,
- },
- .probe = adp1653_probe,
- .remove = __exit_p(adp1653_remove),
- .id_table = adp1653_id_table,
-};
-
-module_i2c_driver(adp1653_i2c_driver);
-
-MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>");
-MODULE_DESCRIPTION("Analog Devices ADP1653 LED flash driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c
deleted file mode 100644
index 6bc01fb98ff..00000000000
--- a/drivers/media/video/adv7170.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * adv7170 - adv7170, adv7171 video encoder driver version 0.0.1
- *
- * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
- *
- * Based on adv7176 driver by:
- *
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- * - some corrections for Pinnacle Systems Inc. DC10plus card.
- *
- * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
- * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-
-MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver");
-MODULE_AUTHOR("Maxim Yevtyushkin");
-MODULE_LICENSE("GPL");
-
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-/* ----------------------------------------------------------------------- */
-
-struct adv7170 {
- struct v4l2_subdev sd;
- unsigned char reg[128];
-
- v4l2_std_id norm;
- int input;
-};
-
-static inline struct adv7170 *to_adv7170(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct adv7170, sd);
-}
-
-static char *inputs[] = { "pass_through", "play_back" };
-
-static enum v4l2_mbus_pixelcode adv7170_codes[] = {
- V4L2_MBUS_FMT_UYVY8_2X8,
- V4L2_MBUS_FMT_UYVY8_1X16,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static inline int adv7170_write(struct v4l2_subdev *sd, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct adv7170 *encoder = to_adv7170(sd);
-
- encoder->reg[reg] = value;
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static inline int adv7170_read(struct v4l2_subdev *sd, u8 reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int adv7170_write_block(struct v4l2_subdev *sd,
- const u8 *data, unsigned int len)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct adv7170 *encoder = to_adv7170(sd);
- int ret = -1;
- u8 reg;
-
- /* the adv7170 has an autoincrement function, use it if
- * the adapter understands raw I2C */
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- /* do raw I2C, not smbus compatible */
- u8 block_data[32];
- int block_len;
-
- while (len >= 2) {
- block_len = 0;
- block_data[block_len++] = reg = data[0];
- do {
- block_data[block_len++] =
- encoder->reg[reg++] = data[1];
- len -= 2;
- data += 2;
- } while (len >= 2 && data[0] == reg && block_len < 32);
- ret = i2c_master_send(client, block_data, block_len);
- if (ret < 0)
- break;
- }
- } else {
- /* do some slow I2C emulation kind of thing */
- while (len >= 2) {
- reg = *data++;
- ret = adv7170_write(sd, reg, *data++);
- if (ret < 0)
- break;
- len -= 2;
- }
- }
- return ret;
-}
-
-/* ----------------------------------------------------------------------- */
-
-#define TR0MODE 0x4c
-#define TR0RST 0x80
-
-#define TR1CAPT 0x00
-#define TR1PLAY 0x00
-
-static const unsigned char init_NTSC[] = {
- 0x00, 0x10, /* MR0 */
- 0x01, 0x20, /* MR1 */
- 0x02, 0x0e, /* MR2 RTC control: bits 2 and 1 */
- 0x03, 0x80, /* MR3 */
- 0x04, 0x30, /* MR4 */
- 0x05, 0x00, /* Reserved */
- 0x06, 0x00, /* Reserved */
- 0x07, TR0MODE, /* TM0 */
- 0x08, TR1CAPT, /* TM1 */
- 0x09, 0x16, /* Fsc0 */
- 0x0a, 0x7c, /* Fsc1 */
- 0x0b, 0xf0, /* Fsc2 */
- 0x0c, 0x21, /* Fsc3 */
- 0x0d, 0x00, /* Subcarrier Phase */
- 0x0e, 0x00, /* Closed Capt. Ext 0 */
- 0x0f, 0x00, /* Closed Capt. Ext 1 */
- 0x10, 0x00, /* Closed Capt. 0 */
- 0x11, 0x00, /* Closed Capt. 1 */
- 0x12, 0x00, /* Pedestal Ctl 0 */
- 0x13, 0x00, /* Pedestal Ctl 1 */
- 0x14, 0x00, /* Pedestal Ctl 2 */
- 0x15, 0x00, /* Pedestal Ctl 3 */
- 0x16, 0x00, /* CGMS_WSS_0 */
- 0x17, 0x00, /* CGMS_WSS_1 */
- 0x18, 0x00, /* CGMS_WSS_2 */
- 0x19, 0x00, /* Teletext Ctl */
-};
-
-static const unsigned char init_PAL[] = {
- 0x00, 0x71, /* MR0 */
- 0x01, 0x20, /* MR1 */
- 0x02, 0x0e, /* MR2 RTC control: bits 2 and 1 */
- 0x03, 0x80, /* MR3 */
- 0x04, 0x30, /* MR4 */
- 0x05, 0x00, /* Reserved */
- 0x06, 0x00, /* Reserved */
- 0x07, TR0MODE, /* TM0 */
- 0x08, TR1CAPT, /* TM1 */
- 0x09, 0xcb, /* Fsc0 */
- 0x0a, 0x8a, /* Fsc1 */
- 0x0b, 0x09, /* Fsc2 */
- 0x0c, 0x2a, /* Fsc3 */
- 0x0d, 0x00, /* Subcarrier Phase */
- 0x0e, 0x00, /* Closed Capt. Ext 0 */
- 0x0f, 0x00, /* Closed Capt. Ext 1 */
- 0x10, 0x00, /* Closed Capt. 0 */
- 0x11, 0x00, /* Closed Capt. 1 */
- 0x12, 0x00, /* Pedestal Ctl 0 */
- 0x13, 0x00, /* Pedestal Ctl 1 */
- 0x14, 0x00, /* Pedestal Ctl 2 */
- 0x15, 0x00, /* Pedestal Ctl 3 */
- 0x16, 0x00, /* CGMS_WSS_0 */
- 0x17, 0x00, /* CGMS_WSS_1 */
- 0x18, 0x00, /* CGMS_WSS_2 */
- 0x19, 0x00, /* Teletext Ctl */
-};
-
-
-static int adv7170_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct adv7170 *encoder = to_adv7170(sd);
-
- v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
-
- if (std & V4L2_STD_NTSC) {
- adv7170_write_block(sd, init_NTSC, sizeof(init_NTSC));
- if (encoder->input == 0)
- adv7170_write(sd, 0x02, 0x0e); /* Enable genlock */
- adv7170_write(sd, 0x07, TR0MODE | TR0RST);
- adv7170_write(sd, 0x07, TR0MODE);
- } else if (std & V4L2_STD_PAL) {
- adv7170_write_block(sd, init_PAL, sizeof(init_PAL));
- if (encoder->input == 0)
- adv7170_write(sd, 0x02, 0x0e); /* Enable genlock */
- adv7170_write(sd, 0x07, TR0MODE | TR0RST);
- adv7170_write(sd, 0x07, TR0MODE);
- } else {
- v4l2_dbg(1, debug, sd, "illegal norm: %llx\n",
- (unsigned long long)std);
- return -EINVAL;
- }
- v4l2_dbg(1, debug, sd, "switched to %llx\n", (unsigned long long)std);
- encoder->norm = std;
- return 0;
-}
-
-static int adv7170_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct adv7170 *encoder = to_adv7170(sd);
-
- /* RJ: input = 0: input is from decoder
- input = 1: input is from ZR36060
- input = 2: color bar */
-
- v4l2_dbg(1, debug, sd, "set input from %s\n",
- input == 0 ? "decoder" : "ZR36060");
-
- switch (input) {
- case 0:
- adv7170_write(sd, 0x01, 0x20);
- adv7170_write(sd, 0x08, TR1CAPT); /* TR1 */
- adv7170_write(sd, 0x02, 0x0e); /* Enable genlock */
- adv7170_write(sd, 0x07, TR0MODE | TR0RST);
- adv7170_write(sd, 0x07, TR0MODE);
- /* udelay(10); */
- break;
-
- case 1:
- adv7170_write(sd, 0x01, 0x00);
- adv7170_write(sd, 0x08, TR1PLAY); /* TR1 */
- adv7170_write(sd, 0x02, 0x08);
- adv7170_write(sd, 0x07, TR0MODE | TR0RST);
- adv7170_write(sd, 0x07, TR0MODE);
- /* udelay(10); */
- break;
-
- default:
- v4l2_dbg(1, debug, sd, "illegal input: %d\n", input);
- return -EINVAL;
- }
- v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[input]);
- encoder->input = input;
- return 0;
-}
-
-static int adv7170_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index >= ARRAY_SIZE(adv7170_codes))
- return -EINVAL;
-
- *code = adv7170_codes[index];
- return 0;
-}
-
-static int adv7170_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- u8 val = adv7170_read(sd, 0x7);
-
- if ((val & 0x40) == (1 << 6))
- mf->code = V4L2_MBUS_FMT_UYVY8_1X16;
- else
- mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
-
- mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
- mf->width = 0;
- mf->height = 0;
- mf->field = V4L2_FIELD_ANY;
-
- return 0;
-}
-
-static int adv7170_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- u8 val = adv7170_read(sd, 0x7);
- int ret;
-
- switch (mf->code) {
- case V4L2_MBUS_FMT_UYVY8_2X8:
- val &= ~0x40;
- break;
-
- case V4L2_MBUS_FMT_UYVY8_1X16:
- val |= 0x40;
- break;
-
- default:
- v4l2_dbg(1, debug, sd,
- "illegal v4l2_mbus_framefmt code: %d\n", mf->code);
- return -EINVAL;
- }
-
- ret = adv7170_write(sd, 0x7, val);
-
- return ret;
-}
-
-static int adv7170_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7170, 0);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops adv7170_core_ops = {
- .g_chip_ident = adv7170_g_chip_ident,
-};
-
-static const struct v4l2_subdev_video_ops adv7170_video_ops = {
- .s_std_output = adv7170_s_std_output,
- .s_routing = adv7170_s_routing,
- .s_mbus_fmt = adv7170_s_fmt,
- .g_mbus_fmt = adv7170_g_fmt,
- .enum_mbus_fmt = adv7170_enum_fmt,
-};
-
-static const struct v4l2_subdev_ops adv7170_ops = {
- .core = &adv7170_core_ops,
- .video = &adv7170_video_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int adv7170_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct adv7170 *encoder;
- struct v4l2_subdev *sd;
- int i;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL);
- if (encoder == NULL)
- return -ENOMEM;
- sd = &encoder->sd;
- v4l2_i2c_subdev_init(sd, client, &adv7170_ops);
- encoder->norm = V4L2_STD_NTSC;
- encoder->input = 0;
-
- i = adv7170_write_block(sd, init_NTSC, sizeof(init_NTSC));
- if (i >= 0) {
- i = adv7170_write(sd, 0x07, TR0MODE | TR0RST);
- i = adv7170_write(sd, 0x07, TR0MODE);
- i = adv7170_read(sd, 0x12);
- v4l2_dbg(1, debug, sd, "revision %d\n", i & 1);
- }
- if (i < 0)
- v4l2_dbg(1, debug, sd, "init error 0x%x\n", i);
- return 0;
-}
-
-static int adv7170_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(to_adv7170(sd));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id adv7170_id[] = {
- { "adv7170", 0 },
- { "adv7171", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, adv7170_id);
-
-static struct i2c_driver adv7170_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "adv7170",
- },
- .probe = adv7170_probe,
- .remove = adv7170_remove,
- .id_table = adv7170_id,
-};
-
-module_i2c_driver(adv7170_driver);
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c
deleted file mode 100644
index c7640fab573..00000000000
--- a/drivers/media/video/adv7175.c
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * adv7175 - adv7175a video encoder driver version 0.0.3
- *
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- * - some corrections for Pinnacle Systems Inc. DC10plus card.
- *
- * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
- * - moved over to linux>=2.4.x i2c protocol (9/9/2002)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-
-MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
-MODULE_AUTHOR("Dave Perks");
-MODULE_LICENSE("GPL");
-
-#define I2C_ADV7175 0xd4
-#define I2C_ADV7176 0x54
-
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-/* ----------------------------------------------------------------------- */
-
-struct adv7175 {
- struct v4l2_subdev sd;
- v4l2_std_id norm;
- int input;
-};
-
-static inline struct adv7175 *to_adv7175(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct adv7175, sd);
-}
-
-static char *inputs[] = { "pass_through", "play_back", "color_bar" };
-
-static enum v4l2_mbus_pixelcode adv7175_codes[] = {
- V4L2_MBUS_FMT_UYVY8_2X8,
- V4L2_MBUS_FMT_UYVY8_1X16,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static inline int adv7175_write(struct v4l2_subdev *sd, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static inline int adv7175_read(struct v4l2_subdev *sd, u8 reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int adv7175_write_block(struct v4l2_subdev *sd,
- const u8 *data, unsigned int len)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret = -1;
- u8 reg;
-
- /* the adv7175 has an autoincrement function, use it if
- * the adapter understands raw I2C */
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- /* do raw I2C, not smbus compatible */
- u8 block_data[32];
- int block_len;
-
- while (len >= 2) {
- block_len = 0;
- block_data[block_len++] = reg = data[0];
- do {
- block_data[block_len++] = data[1];
- reg++;
- len -= 2;
- data += 2;
- } while (len >= 2 && data[0] == reg && block_len < 32);
- ret = i2c_master_send(client, block_data, block_len);
- if (ret < 0)
- break;
- }
- } else {
- /* do some slow I2C emulation kind of thing */
- while (len >= 2) {
- reg = *data++;
- ret = adv7175_write(sd, reg, *data++);
- if (ret < 0)
- break;
- len -= 2;
- }
- }
-
- return ret;
-}
-
-static void set_subcarrier_freq(struct v4l2_subdev *sd, int pass_through)
-{
- /* for some reason pass_through NTSC needs
- * a different sub-carrier freq to remain stable. */
- if (pass_through)
- adv7175_write(sd, 0x02, 0x00);
- else
- adv7175_write(sd, 0x02, 0x55);
-
- adv7175_write(sd, 0x03, 0x55);
- adv7175_write(sd, 0x04, 0x55);
- adv7175_write(sd, 0x05, 0x25);
-}
-
-/* ----------------------------------------------------------------------- */
-/* Output filter: S-Video Composite */
-
-#define MR050 0x11 /* 0x09 */
-#define MR060 0x14 /* 0x0c */
-
-/* ----------------------------------------------------------------------- */
-
-#define TR0MODE 0x46
-#define TR0RST 0x80
-
-#define TR1CAPT 0x80
-#define TR1PLAY 0x00
-
-static const unsigned char init_common[] = {
-
- 0x00, MR050, /* MR0, PAL enabled */
- 0x01, 0x00, /* MR1 */
- 0x02, 0x0c, /* subc. freq. */
- 0x03, 0x8c, /* subc. freq. */
- 0x04, 0x79, /* subc. freq. */
- 0x05, 0x26, /* subc. freq. */
- 0x06, 0x40, /* subc. phase */
-
- 0x07, TR0MODE, /* TR0, 16bit */
- 0x08, 0x21, /* */
- 0x09, 0x00, /* */
- 0x0a, 0x00, /* */
- 0x0b, 0x00, /* */
- 0x0c, TR1CAPT, /* TR1 */
- 0x0d, 0x4f, /* MR2 */
- 0x0e, 0x00, /* */
- 0x0f, 0x00, /* */
- 0x10, 0x00, /* */
- 0x11, 0x00, /* */
-};
-
-static const unsigned char init_pal[] = {
- 0x00, MR050, /* MR0, PAL enabled */
- 0x01, 0x00, /* MR1 */
- 0x02, 0x0c, /* subc. freq. */
- 0x03, 0x8c, /* subc. freq. */
- 0x04, 0x79, /* subc. freq. */
- 0x05, 0x26, /* subc. freq. */
- 0x06, 0x40, /* subc. phase */
-};
-
-static const unsigned char init_ntsc[] = {
- 0x00, MR060, /* MR0, NTSC enabled */
- 0x01, 0x00, /* MR1 */
- 0x02, 0x55, /* subc. freq. */
- 0x03, 0x55, /* subc. freq. */
- 0x04, 0x55, /* subc. freq. */
- 0x05, 0x25, /* subc. freq. */
- 0x06, 0x1a, /* subc. phase */
-};
-
-static int adv7175_init(struct v4l2_subdev *sd, u32 val)
-{
- /* This is just for testing!!! */
- adv7175_write_block(sd, init_common, sizeof(init_common));
- adv7175_write(sd, 0x07, TR0MODE | TR0RST);
- adv7175_write(sd, 0x07, TR0MODE);
- return 0;
-}
-
-static int adv7175_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct adv7175 *encoder = to_adv7175(sd);
-
- if (std & V4L2_STD_NTSC) {
- adv7175_write_block(sd, init_ntsc, sizeof(init_ntsc));
- if (encoder->input == 0)
- adv7175_write(sd, 0x0d, 0x4f); /* Enable genlock */
- adv7175_write(sd, 0x07, TR0MODE | TR0RST);
- adv7175_write(sd, 0x07, TR0MODE);
- } else if (std & V4L2_STD_PAL) {
- adv7175_write_block(sd, init_pal, sizeof(init_pal));
- if (encoder->input == 0)
- adv7175_write(sd, 0x0d, 0x4f); /* Enable genlock */
- adv7175_write(sd, 0x07, TR0MODE | TR0RST);
- adv7175_write(sd, 0x07, TR0MODE);
- } else if (std & V4L2_STD_SECAM) {
- /* This is an attempt to convert
- * SECAM->PAL (typically it does not work
- * due to genlock: when decoder is in SECAM
- * and encoder in in PAL the subcarrier can
- * not be syncronized with horizontal
- * quency) */
- adv7175_write_block(sd, init_pal, sizeof(init_pal));
- if (encoder->input == 0)
- adv7175_write(sd, 0x0d, 0x49); /* Disable genlock */
- adv7175_write(sd, 0x07, TR0MODE | TR0RST);
- adv7175_write(sd, 0x07, TR0MODE);
- } else {
- v4l2_dbg(1, debug, sd, "illegal norm: %llx\n",
- (unsigned long long)std);
- return -EINVAL;
- }
- v4l2_dbg(1, debug, sd, "switched to %llx\n", (unsigned long long)std);
- encoder->norm = std;
- return 0;
-}
-
-static int adv7175_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct adv7175 *encoder = to_adv7175(sd);
-
- /* RJ: input = 0: input is from decoder
- input = 1: input is from ZR36060
- input = 2: color bar */
-
- switch (input) {
- case 0:
- adv7175_write(sd, 0x01, 0x00);
-
- if (encoder->norm & V4L2_STD_NTSC)
- set_subcarrier_freq(sd, 1);
-
- adv7175_write(sd, 0x0c, TR1CAPT); /* TR1 */
- if (encoder->norm & V4L2_STD_SECAM)
- adv7175_write(sd, 0x0d, 0x49); /* Disable genlock */
- else
- adv7175_write(sd, 0x0d, 0x4f); /* Enable genlock */
- adv7175_write(sd, 0x07, TR0MODE | TR0RST);
- adv7175_write(sd, 0x07, TR0MODE);
- /*udelay(10);*/
- break;
-
- case 1:
- adv7175_write(sd, 0x01, 0x00);
-
- if (encoder->norm & V4L2_STD_NTSC)
- set_subcarrier_freq(sd, 0);
-
- adv7175_write(sd, 0x0c, TR1PLAY); /* TR1 */
- adv7175_write(sd, 0x0d, 0x49);
- adv7175_write(sd, 0x07, TR0MODE | TR0RST);
- adv7175_write(sd, 0x07, TR0MODE);
- /* udelay(10); */
- break;
-
- case 2:
- adv7175_write(sd, 0x01, 0x80);
-
- if (encoder->norm & V4L2_STD_NTSC)
- set_subcarrier_freq(sd, 0);
-
- adv7175_write(sd, 0x0d, 0x49);
- adv7175_write(sd, 0x07, TR0MODE | TR0RST);
- adv7175_write(sd, 0x07, TR0MODE);
- /* udelay(10); */
- break;
-
- default:
- v4l2_dbg(1, debug, sd, "illegal input: %d\n", input);
- return -EINVAL;
- }
- v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[input]);
- encoder->input = input;
- return 0;
-}
-
-static int adv7175_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index >= ARRAY_SIZE(adv7175_codes))
- return -EINVAL;
-
- *code = adv7175_codes[index];
- return 0;
-}
-
-static int adv7175_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- u8 val = adv7175_read(sd, 0x7);
-
- if ((val & 0x40) == (1 << 6))
- mf->code = V4L2_MBUS_FMT_UYVY8_1X16;
- else
- mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
-
- mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
- mf->width = 0;
- mf->height = 0;
- mf->field = V4L2_FIELD_ANY;
-
- return 0;
-}
-
-static int adv7175_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- u8 val = adv7175_read(sd, 0x7);
- int ret;
-
- switch (mf->code) {
- case V4L2_MBUS_FMT_UYVY8_2X8:
- val &= ~0x40;
- break;
-
- case V4L2_MBUS_FMT_UYVY8_1X16:
- val |= 0x40;
- break;
-
- default:
- v4l2_dbg(1, debug, sd,
- "illegal v4l2_mbus_framefmt code: %d\n", mf->code);
- return -EINVAL;
- }
-
- ret = adv7175_write(sd, 0x7, val);
-
- return ret;
-}
-
-static int adv7175_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7175, 0);
-}
-
-static int adv7175_s_power(struct v4l2_subdev *sd, int on)
-{
- if (on)
- adv7175_write(sd, 0x01, 0x00);
- else
- adv7175_write(sd, 0x01, 0x78);
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops adv7175_core_ops = {
- .g_chip_ident = adv7175_g_chip_ident,
- .init = adv7175_init,
- .s_power = adv7175_s_power,
-};
-
-static const struct v4l2_subdev_video_ops adv7175_video_ops = {
- .s_std_output = adv7175_s_std_output,
- .s_routing = adv7175_s_routing,
- .s_mbus_fmt = adv7175_s_fmt,
- .g_mbus_fmt = adv7175_g_fmt,
- .enum_mbus_fmt = adv7175_enum_fmt,
-};
-
-static const struct v4l2_subdev_ops adv7175_ops = {
- .core = &adv7175_core_ops,
- .video = &adv7175_video_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int adv7175_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int i;
- struct adv7175 *encoder;
- struct v4l2_subdev *sd;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
- if (encoder == NULL)
- return -ENOMEM;
- sd = &encoder->sd;
- v4l2_i2c_subdev_init(sd, client, &adv7175_ops);
- encoder->norm = V4L2_STD_NTSC;
- encoder->input = 0;
-
- i = adv7175_write_block(sd, init_common, sizeof(init_common));
- if (i >= 0) {
- i = adv7175_write(sd, 0x07, TR0MODE | TR0RST);
- i = adv7175_write(sd, 0x07, TR0MODE);
- i = adv7175_read(sd, 0x12);
- v4l2_dbg(1, debug, sd, "revision %d\n", i & 1);
- }
- if (i < 0)
- v4l2_dbg(1, debug, sd, "init error 0x%x\n", i);
- return 0;
-}
-
-static int adv7175_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(to_adv7175(sd));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id adv7175_id[] = {
- { "adv7175", 0 },
- { "adv7176", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, adv7175_id);
-
-static struct i2c_driver adv7175_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "adv7175",
- },
- .probe = adv7175_probe,
- .remove = adv7175_remove,
- .id_table = adv7175_id,
-};
-
-module_i2c_driver(adv7175_driver);
diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c
deleted file mode 100644
index 45ecf8db1ea..00000000000
--- a/drivers/media/video/adv7180.c
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- * adv7180.c Analog Devices ADV7180 video decoder driver
- * Copyright (c) 2009 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <media/v4l2-ioctl.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
-#include <linux/mutex.h>
-
-#define ADV7180_INPUT_CONTROL_REG 0x00
-#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM 0x00
-#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM_PED 0x10
-#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_J_SECAM 0x20
-#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_M_SECAM 0x30
-#define ADV7180_INPUT_CONTROL_NTSC_J 0x40
-#define ADV7180_INPUT_CONTROL_NTSC_M 0x50
-#define ADV7180_INPUT_CONTROL_PAL60 0x60
-#define ADV7180_INPUT_CONTROL_NTSC_443 0x70
-#define ADV7180_INPUT_CONTROL_PAL_BG 0x80
-#define ADV7180_INPUT_CONTROL_PAL_N 0x90
-#define ADV7180_INPUT_CONTROL_PAL_M 0xa0
-#define ADV7180_INPUT_CONTROL_PAL_M_PED 0xb0
-#define ADV7180_INPUT_CONTROL_PAL_COMB_N 0xc0
-#define ADV7180_INPUT_CONTROL_PAL_COMB_N_PED 0xd0
-#define ADV7180_INPUT_CONTROL_PAL_SECAM 0xe0
-#define ADV7180_INPUT_CONTROL_PAL_SECAM_PED 0xf0
-#define ADV7180_INPUT_CONTROL_INSEL_MASK 0x0f
-
-#define ADV7180_EXTENDED_OUTPUT_CONTROL_REG 0x04
-#define ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS 0xC5
-
-#define ADV7180_AUTODETECT_ENABLE_REG 0x07
-#define ADV7180_AUTODETECT_DEFAULT 0x7f
-/* Contrast */
-#define ADV7180_CON_REG 0x08 /*Unsigned */
-#define ADV7180_CON_MIN 0
-#define ADV7180_CON_DEF 128
-#define ADV7180_CON_MAX 255
-/* Brightness*/
-#define ADV7180_BRI_REG 0x0a /*Signed */
-#define ADV7180_BRI_MIN -128
-#define ADV7180_BRI_DEF 0
-#define ADV7180_BRI_MAX 127
-/* Hue */
-#define ADV7180_HUE_REG 0x0b /*Signed, inverted */
-#define ADV7180_HUE_MIN -127
-#define ADV7180_HUE_DEF 0
-#define ADV7180_HUE_MAX 128
-
-#define ADV7180_ADI_CTRL_REG 0x0e
-#define ADV7180_ADI_CTRL_IRQ_SPACE 0x20
-
-#define ADV7180_PWR_MAN_REG 0x0f
-#define ADV7180_PWR_MAN_ON 0x04
-#define ADV7180_PWR_MAN_OFF 0x24
-#define ADV7180_PWR_MAN_RES 0x80
-
-#define ADV7180_STATUS1_REG 0x10
-#define ADV7180_STATUS1_IN_LOCK 0x01
-#define ADV7180_STATUS1_AUTOD_MASK 0x70
-#define ADV7180_STATUS1_AUTOD_NTSM_M_J 0x00
-#define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10
-#define ADV7180_STATUS1_AUTOD_PAL_M 0x20
-#define ADV7180_STATUS1_AUTOD_PAL_60 0x30
-#define ADV7180_STATUS1_AUTOD_PAL_B_G 0x40
-#define ADV7180_STATUS1_AUTOD_SECAM 0x50
-#define ADV7180_STATUS1_AUTOD_PAL_COMB 0x60
-#define ADV7180_STATUS1_AUTOD_SECAM_525 0x70
-
-#define ADV7180_IDENT_REG 0x11
-#define ADV7180_ID_7180 0x18
-
-#define ADV7180_ICONF1_ADI 0x40
-#define ADV7180_ICONF1_ACTIVE_LOW 0x01
-#define ADV7180_ICONF1_PSYNC_ONLY 0x10
-#define ADV7180_ICONF1_ACTIVE_TO_CLR 0xC0
-/* Saturation */
-#define ADV7180_SD_SAT_CB_REG 0xe3 /*Unsigned */
-#define ADV7180_SD_SAT_CR_REG 0xe4 /*Unsigned */
-#define ADV7180_SAT_MIN 0
-#define ADV7180_SAT_DEF 128
-#define ADV7180_SAT_MAX 255
-
-#define ADV7180_IRQ1_LOCK 0x01
-#define ADV7180_IRQ1_UNLOCK 0x02
-#define ADV7180_ISR1_ADI 0x42
-#define ADV7180_ICR1_ADI 0x43
-#define ADV7180_IMR1_ADI 0x44
-#define ADV7180_IMR2_ADI 0x48
-#define ADV7180_IRQ3_AD_CHANGE 0x08
-#define ADV7180_ISR3_ADI 0x4A
-#define ADV7180_ICR3_ADI 0x4B
-#define ADV7180_IMR3_ADI 0x4C
-#define ADV7180_IMR4_ADI 0x50
-
-#define ADV7180_NTSC_V_BIT_END_REG 0xE6
-#define ADV7180_NTSC_V_BIT_END_MANUAL_NVEND 0x4F
-
-struct adv7180_state {
- struct v4l2_ctrl_handler ctrl_hdl;
- struct v4l2_subdev sd;
- struct work_struct work;
- struct mutex mutex; /* mutual excl. when accessing chip */
- int irq;
- v4l2_std_id curr_norm;
- bool autodetect;
- u8 input;
-};
-#define to_adv7180_sd(_ctrl) (&container_of(_ctrl->handler, \
- struct adv7180_state, \
- ctrl_hdl)->sd)
-
-static v4l2_std_id adv7180_std_to_v4l2(u8 status1)
-{
- switch (status1 & ADV7180_STATUS1_AUTOD_MASK) {
- case ADV7180_STATUS1_AUTOD_NTSM_M_J:
- return V4L2_STD_NTSC;
- case ADV7180_STATUS1_AUTOD_NTSC_4_43:
- return V4L2_STD_NTSC_443;
- case ADV7180_STATUS1_AUTOD_PAL_M:
- return V4L2_STD_PAL_M;
- case ADV7180_STATUS1_AUTOD_PAL_60:
- return V4L2_STD_PAL_60;
- case ADV7180_STATUS1_AUTOD_PAL_B_G:
- return V4L2_STD_PAL;
- case ADV7180_STATUS1_AUTOD_SECAM:
- return V4L2_STD_SECAM;
- case ADV7180_STATUS1_AUTOD_PAL_COMB:
- return V4L2_STD_PAL_Nc | V4L2_STD_PAL_N;
- case ADV7180_STATUS1_AUTOD_SECAM_525:
- return V4L2_STD_SECAM;
- default:
- return V4L2_STD_UNKNOWN;
- }
-}
-
-static int v4l2_std_to_adv7180(v4l2_std_id std)
-{
- if (std == V4L2_STD_PAL_60)
- return ADV7180_INPUT_CONTROL_PAL60;
- if (std == V4L2_STD_NTSC_443)
- return ADV7180_INPUT_CONTROL_NTSC_443;
- if (std == V4L2_STD_PAL_N)
- return ADV7180_INPUT_CONTROL_PAL_N;
- if (std == V4L2_STD_PAL_M)
- return ADV7180_INPUT_CONTROL_PAL_M;
- if (std == V4L2_STD_PAL_Nc)
- return ADV7180_INPUT_CONTROL_PAL_COMB_N;
-
- if (std & V4L2_STD_PAL)
- return ADV7180_INPUT_CONTROL_PAL_BG;
- if (std & V4L2_STD_NTSC)
- return ADV7180_INPUT_CONTROL_NTSC_M;
- if (std & V4L2_STD_SECAM)
- return ADV7180_INPUT_CONTROL_PAL_SECAM;
-
- return -EINVAL;
-}
-
-static u32 adv7180_status_to_v4l2(u8 status1)
-{
- if (!(status1 & ADV7180_STATUS1_IN_LOCK))
- return V4L2_IN_ST_NO_SIGNAL;
-
- return 0;
-}
-
-static int __adv7180_status(struct i2c_client *client, u32 *status,
- v4l2_std_id *std)
-{
- int status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
-
- if (status1 < 0)
- return status1;
-
- if (status)
- *status = adv7180_status_to_v4l2(status1);
- if (std)
- *std = adv7180_std_to_v4l2(status1);
-
- return 0;
-}
-
-static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct adv7180_state, sd);
-}
-
-static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
-{
- struct adv7180_state *state = to_state(sd);
- int err = mutex_lock_interruptible(&state->mutex);
- if (err)
- return err;
-
- /* when we are interrupt driven we know the state */
- if (!state->autodetect || state->irq > 0)
- *std = state->curr_norm;
- else
- err = __adv7180_status(v4l2_get_subdevdata(sd), NULL, std);
-
- mutex_unlock(&state->mutex);
- return err;
-}
-
-static int adv7180_s_routing(struct v4l2_subdev *sd, u32 input,
- u32 output, u32 config)
-{
- struct adv7180_state *state = to_state(sd);
- int ret = mutex_lock_interruptible(&state->mutex);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (ret)
- return ret;
-
- /* We cannot discriminate between LQFP and 40-pin LFCSP, so accept
- * all inputs and let the card driver take care of validation
- */
- if ((input & ADV7180_INPUT_CONTROL_INSEL_MASK) != input)
- goto out;
-
- ret = i2c_smbus_read_byte_data(client, ADV7180_INPUT_CONTROL_REG);
-
- if (ret < 0)
- goto out;
-
- ret &= ~ADV7180_INPUT_CONTROL_INSEL_MASK;
- ret = i2c_smbus_write_byte_data(client,
- ADV7180_INPUT_CONTROL_REG, ret | input);
- state->input = input;
-out:
- mutex_unlock(&state->mutex);
- return ret;
-}
-
-static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status)
-{
- struct adv7180_state *state = to_state(sd);
- int ret = mutex_lock_interruptible(&state->mutex);
- if (ret)
- return ret;
-
- ret = __adv7180_status(v4l2_get_subdevdata(sd), status, NULL);
- mutex_unlock(&state->mutex);
- return ret;
-}
-
-static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0);
-}
-
-static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct adv7180_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret = mutex_lock_interruptible(&state->mutex);
- if (ret)
- return ret;
-
- /* all standards -> autodetect */
- if (std == V4L2_STD_ALL) {
- ret =
- i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
- ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM
- | state->input);
- if (ret < 0)
- goto out;
-
- __adv7180_status(client, NULL, &state->curr_norm);
- state->autodetect = true;
- } else {
- ret = v4l2_std_to_adv7180(std);
- if (ret < 0)
- goto out;
-
- ret = i2c_smbus_write_byte_data(client,
- ADV7180_INPUT_CONTROL_REG,
- ret | state->input);
- if (ret < 0)
- goto out;
-
- state->curr_norm = std;
- state->autodetect = false;
- }
- ret = 0;
-out:
- mutex_unlock(&state->mutex);
- return ret;
-}
-
-static int adv7180_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_adv7180_sd(ctrl);
- struct adv7180_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret = mutex_lock_interruptible(&state->mutex);
- int val;
-
- if (ret)
- return ret;
- val = ctrl->val;
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- ret = i2c_smbus_write_byte_data(client, ADV7180_BRI_REG, val);
- break;
- case V4L2_CID_HUE:
- /*Hue is inverted according to HSL chart */
- ret = i2c_smbus_write_byte_data(client, ADV7180_HUE_REG, -val);
- break;
- case V4L2_CID_CONTRAST:
- ret = i2c_smbus_write_byte_data(client, ADV7180_CON_REG, val);
- break;
- case V4L2_CID_SATURATION:
- /*
- *This could be V4L2_CID_BLUE_BALANCE/V4L2_CID_RED_BALANCE
- *Let's not confuse the user, everybody understands saturation
- */
- ret = i2c_smbus_write_byte_data(client, ADV7180_SD_SAT_CB_REG,
- val);
- if (ret < 0)
- break;
- ret = i2c_smbus_write_byte_data(client, ADV7180_SD_SAT_CR_REG,
- val);
- break;
- default:
- ret = -EINVAL;
- }
-
- mutex_unlock(&state->mutex);
- return ret;
-}
-
-static const struct v4l2_ctrl_ops adv7180_ctrl_ops = {
- .s_ctrl = adv7180_s_ctrl,
-};
-
-static int adv7180_init_controls(struct adv7180_state *state)
-{
- v4l2_ctrl_handler_init(&state->ctrl_hdl, 4);
-
- v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
- V4L2_CID_BRIGHTNESS, ADV7180_BRI_MIN,
- ADV7180_BRI_MAX, 1, ADV7180_BRI_DEF);
- v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
- V4L2_CID_CONTRAST, ADV7180_CON_MIN,
- ADV7180_CON_MAX, 1, ADV7180_CON_DEF);
- v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
- V4L2_CID_SATURATION, ADV7180_SAT_MIN,
- ADV7180_SAT_MAX, 1, ADV7180_SAT_DEF);
- v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
- V4L2_CID_HUE, ADV7180_HUE_MIN,
- ADV7180_HUE_MAX, 1, ADV7180_HUE_DEF);
- state->sd.ctrl_handler = &state->ctrl_hdl;
- if (state->ctrl_hdl.error) {
- int err = state->ctrl_hdl.error;
-
- v4l2_ctrl_handler_free(&state->ctrl_hdl);
- return err;
- }
- v4l2_ctrl_handler_setup(&state->ctrl_hdl);
-
- return 0;
-}
-static void adv7180_exit_controls(struct adv7180_state *state)
-{
- v4l2_ctrl_handler_free(&state->ctrl_hdl);
-}
-
-static const struct v4l2_subdev_video_ops adv7180_video_ops = {
- .querystd = adv7180_querystd,
- .g_input_status = adv7180_g_input_status,
- .s_routing = adv7180_s_routing,
-};
-
-static const struct v4l2_subdev_core_ops adv7180_core_ops = {
- .g_chip_ident = adv7180_g_chip_ident,
- .s_std = adv7180_s_std,
- .queryctrl = v4l2_subdev_queryctrl,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
-};
-
-static const struct v4l2_subdev_ops adv7180_ops = {
- .core = &adv7180_core_ops,
- .video = &adv7180_video_ops,
-};
-
-static void adv7180_work(struct work_struct *work)
-{
- struct adv7180_state *state = container_of(work, struct adv7180_state,
- work);
- struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
- u8 isr3;
-
- mutex_lock(&state->mutex);
- i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
- ADV7180_ADI_CTRL_IRQ_SPACE);
- isr3 = i2c_smbus_read_byte_data(client, ADV7180_ISR3_ADI);
- /* clear */
- i2c_smbus_write_byte_data(client, ADV7180_ICR3_ADI, isr3);
- i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 0);
-
- if (isr3 & ADV7180_IRQ3_AD_CHANGE && state->autodetect)
- __adv7180_status(client, NULL, &state->curr_norm);
- mutex_unlock(&state->mutex);
-
- enable_irq(state->irq);
-}
-
-static irqreturn_t adv7180_irq(int irq, void *devid)
-{
- struct adv7180_state *state = devid;
-
- schedule_work(&state->work);
-
- disable_irq_nosync(state->irq);
-
- return IRQ_HANDLED;
-}
-
-static int init_device(struct i2c_client *client, struct adv7180_state *state)
-{
- int ret;
-
- /* Initialize adv7180 */
- /* Enable autodetection */
- if (state->autodetect) {
- ret =
- i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
- ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM
- | state->input);
- if (ret < 0)
- return ret;
-
- ret =
- i2c_smbus_write_byte_data(client,
- ADV7180_AUTODETECT_ENABLE_REG,
- ADV7180_AUTODETECT_DEFAULT);
- if (ret < 0)
- return ret;
- } else {
- ret = v4l2_std_to_adv7180(state->curr_norm);
- if (ret < 0)
- return ret;
-
- ret =
- i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
- ret | state->input);
- if (ret < 0)
- return ret;
-
- }
- /* ITU-R BT.656-4 compatible */
- ret = i2c_smbus_write_byte_data(client,
- ADV7180_EXTENDED_OUTPUT_CONTROL_REG,
- ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
- if (ret < 0)
- return ret;
-
- /* Manually set V bit end position in NTSC mode */
- ret = i2c_smbus_write_byte_data(client,
- ADV7180_NTSC_V_BIT_END_REG,
- ADV7180_NTSC_V_BIT_END_MANUAL_NVEND);
- if (ret < 0)
- return ret;
-
- /* read current norm */
- __adv7180_status(client, NULL, &state->curr_norm);
-
- /* register for interrupts */
- if (state->irq > 0) {
- ret = request_irq(state->irq, adv7180_irq, 0, KBUILD_MODNAME,
- state);
- if (ret)
- return ret;
-
- ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
- ADV7180_ADI_CTRL_IRQ_SPACE);
- if (ret < 0)
- return ret;
-
- /* config the Interrupt pin to be active low */
- ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI,
- ADV7180_ICONF1_ACTIVE_LOW |
- ADV7180_ICONF1_PSYNC_ONLY);
- if (ret < 0)
- return ret;
-
- ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0);
- if (ret < 0)
- return ret;
-
- ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0);
- if (ret < 0)
- return ret;
-
- /* enable AD change interrupts interrupts */
- ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI,
- ADV7180_IRQ3_AD_CHANGE);
- if (ret < 0)
- return ret;
-
- ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0);
- if (ret < 0)
- return ret;
-
- ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
- 0);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-static __devinit int adv7180_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct adv7180_state *state;
- struct v4l2_subdev *sd;
- int ret;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- v4l_info(client, "chip found @ 0x%02x (%s)\n",
- client->addr, client->adapter->name);
-
- state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
- if (state == NULL) {
- ret = -ENOMEM;
- goto err;
- }
-
- state->irq = client->irq;
- INIT_WORK(&state->work, adv7180_work);
- mutex_init(&state->mutex);
- state->autodetect = true;
- state->input = 0;
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
-
- ret = adv7180_init_controls(state);
- if (ret)
- goto err_unreg_subdev;
- ret = init_device(client, state);
- if (ret)
- goto err_free_ctrl;
- return 0;
-
-err_free_ctrl:
- adv7180_exit_controls(state);
-err_unreg_subdev:
- mutex_destroy(&state->mutex);
- v4l2_device_unregister_subdev(sd);
- kfree(state);
-err:
- printk(KERN_ERR KBUILD_MODNAME ": Failed to probe: %d\n", ret);
- return ret;
-}
-
-static __devexit int adv7180_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct adv7180_state *state = to_state(sd);
-
- if (state->irq > 0) {
- free_irq(client->irq, state);
- if (cancel_work_sync(&state->work)) {
- /*
- * Work was pending, therefore we need to enable
- * IRQ here to balance the disable_irq() done in the
- * interrupt handler.
- */
- enable_irq(state->irq);
- }
- }
-
- mutex_destroy(&state->mutex);
- v4l2_device_unregister_subdev(sd);
- kfree(to_state(sd));
- return 0;
-}
-
-static const struct i2c_device_id adv7180_id[] = {
- {KBUILD_MODNAME, 0},
- {},
-};
-
-#ifdef CONFIG_PM
-static int adv7180_suspend(struct i2c_client *client, pm_message_t state)
-{
- int ret;
-
- ret = i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG,
- ADV7180_PWR_MAN_OFF);
- if (ret < 0)
- return ret;
- return 0;
-}
-
-static int adv7180_resume(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct adv7180_state *state = to_state(sd);
- int ret;
-
- ret = i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG,
- ADV7180_PWR_MAN_ON);
- if (ret < 0)
- return ret;
- ret = init_device(client, state);
- if (ret < 0)
- return ret;
- return 0;
-}
-#endif
-
-MODULE_DEVICE_TABLE(i2c, adv7180_id);
-
-static struct i2c_driver adv7180_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = KBUILD_MODNAME,
- },
- .probe = adv7180_probe,
- .remove = __devexit_p(adv7180_remove),
-#ifdef CONFIG_PM
- .suspend = adv7180_suspend,
- .resume = adv7180_resume,
-#endif
- .id_table = adv7180_id,
-};
-
-module_i2c_driver(adv7180_driver);
-
-MODULE_DESCRIPTION("Analog Devices ADV7180 video decoder driver");
-MODULE_AUTHOR("Mocean Laboratories");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/adv7183.c b/drivers/media/video/adv7183.c
deleted file mode 100644
index e1d4c89d714..00000000000
--- a/drivers/media/video/adv7183.c
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- * adv7183.c Analog Devices ADV7183 video decoder driver
- *
- * Copyright (c) 2011 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-
-#include <media/adv7183.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-
-#include "adv7183_regs.h"
-
-struct adv7183 {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
-
- v4l2_std_id std; /* Current set standard */
- u32 input;
- u32 output;
- unsigned reset_pin;
- unsigned oe_pin;
- struct v4l2_mbus_framefmt fmt;
-};
-
-/* EXAMPLES USING 27 MHz CLOCK
- * Mode 1 CVBS Input (Composite Video on AIN5)
- * All standards are supported through autodetect, 8-bit, 4:2:2, ITU-R BT.656 output on P15 to P8.
- */
-static const unsigned char adv7183_init_regs[] = {
- ADV7183_IN_CTRL, 0x04, /* CVBS input on AIN5 */
- ADV7183_DIGI_CLAMP_CTRL_1, 0x00, /* Slow down digital clamps */
- ADV7183_SHAP_FILT_CTRL, 0x41, /* Set CSFM to SH1 */
- ADV7183_ADC_CTRL, 0x16, /* Power down ADC 1 and ADC 2 */
- ADV7183_CTI_DNR_CTRL_4, 0x04, /* Set DNR threshold to 4 for flat response */
- /* ADI recommended programming sequence */
- ADV7183_ADI_CTRL, 0x80,
- ADV7183_CTI_DNR_CTRL_4, 0x20,
- 0x52, 0x18,
- 0x58, 0xED,
- 0x77, 0xC5,
- 0x7C, 0x93,
- 0x7D, 0x00,
- 0xD0, 0x48,
- 0xD5, 0xA0,
- 0xD7, 0xEA,
- ADV7183_SD_SATURATION_CR, 0x3E,
- ADV7183_PAL_V_END, 0x3E,
- ADV7183_PAL_F_TOGGLE, 0x0F,
- ADV7183_ADI_CTRL, 0x00,
-};
-
-static inline struct adv7183 *to_adv7183(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct adv7183, sd);
-}
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct adv7183, hdl)->sd;
-}
-
-static inline int adv7183_read(struct v4l2_subdev *sd, unsigned char reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-static inline int adv7183_write(struct v4l2_subdev *sd, unsigned char reg,
- unsigned char value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static int adv7183_writeregs(struct v4l2_subdev *sd,
- const unsigned char *regs, unsigned int num)
-{
- unsigned char reg, data;
- unsigned int cnt = 0;
-
- if (num & 0x1) {
- v4l2_err(sd, "invalid regs array\n");
- return -1;
- }
-
- while (cnt < num) {
- reg = *regs++;
- data = *regs++;
- cnt += 2;
-
- adv7183_write(sd, reg, data);
- }
- return 0;
-}
-
-static int adv7183_log_status(struct v4l2_subdev *sd)
-{
- struct adv7183 *decoder = to_adv7183(sd);
-
- v4l2_info(sd, "adv7183: Input control = 0x%02x\n",
- adv7183_read(sd, ADV7183_IN_CTRL));
- v4l2_info(sd, "adv7183: Video selection = 0x%02x\n",
- adv7183_read(sd, ADV7183_VD_SEL));
- v4l2_info(sd, "adv7183: Output control = 0x%02x\n",
- adv7183_read(sd, ADV7183_OUT_CTRL));
- v4l2_info(sd, "adv7183: Extended output control = 0x%02x\n",
- adv7183_read(sd, ADV7183_EXT_OUT_CTRL));
- v4l2_info(sd, "adv7183: Autodetect enable = 0x%02x\n",
- adv7183_read(sd, ADV7183_AUTO_DET_EN));
- v4l2_info(sd, "adv7183: Contrast = 0x%02x\n",
- adv7183_read(sd, ADV7183_CONTRAST));
- v4l2_info(sd, "adv7183: Brightness = 0x%02x\n",
- adv7183_read(sd, ADV7183_BRIGHTNESS));
- v4l2_info(sd, "adv7183: Hue = 0x%02x\n",
- adv7183_read(sd, ADV7183_HUE));
- v4l2_info(sd, "adv7183: Default value Y = 0x%02x\n",
- adv7183_read(sd, ADV7183_DEF_Y));
- v4l2_info(sd, "adv7183: Default value C = 0x%02x\n",
- adv7183_read(sd, ADV7183_DEF_C));
- v4l2_info(sd, "adv7183: ADI control = 0x%02x\n",
- adv7183_read(sd, ADV7183_ADI_CTRL));
- v4l2_info(sd, "adv7183: Power Management = 0x%02x\n",
- adv7183_read(sd, ADV7183_POW_MANAGE));
- v4l2_info(sd, "adv7183: Status 1 2 and 3 = 0x%02x 0x%02x 0x%02x\n",
- adv7183_read(sd, ADV7183_STATUS_1),
- adv7183_read(sd, ADV7183_STATUS_2),
- adv7183_read(sd, ADV7183_STATUS_3));
- v4l2_info(sd, "adv7183: Ident = 0x%02x\n",
- adv7183_read(sd, ADV7183_IDENT));
- v4l2_info(sd, "adv7183: Analog clamp control = 0x%02x\n",
- adv7183_read(sd, ADV7183_ANAL_CLAMP_CTRL));
- v4l2_info(sd, "adv7183: Digital clamp control 1 = 0x%02x\n",
- adv7183_read(sd, ADV7183_DIGI_CLAMP_CTRL_1));
- v4l2_info(sd, "adv7183: Shaping filter control 1 and 2 = 0x%02x 0x%02x\n",
- adv7183_read(sd, ADV7183_SHAP_FILT_CTRL),
- adv7183_read(sd, ADV7183_SHAP_FILT_CTRL_2));
- v4l2_info(sd, "adv7183: Comb filter control = 0x%02x\n",
- adv7183_read(sd, ADV7183_COMB_FILT_CTRL));
- v4l2_info(sd, "adv7183: ADI control 2 = 0x%02x\n",
- adv7183_read(sd, ADV7183_ADI_CTRL_2));
- v4l2_info(sd, "adv7183: Pixel delay control = 0x%02x\n",
- adv7183_read(sd, ADV7183_PIX_DELAY_CTRL));
- v4l2_info(sd, "adv7183: Misc gain control = 0x%02x\n",
- adv7183_read(sd, ADV7183_MISC_GAIN_CTRL));
- v4l2_info(sd, "adv7183: AGC mode control = 0x%02x\n",
- adv7183_read(sd, ADV7183_AGC_MODE_CTRL));
- v4l2_info(sd, "adv7183: Chroma gain control 1 and 2 = 0x%02x 0x%02x\n",
- adv7183_read(sd, ADV7183_CHRO_GAIN_CTRL_1),
- adv7183_read(sd, ADV7183_CHRO_GAIN_CTRL_2));
- v4l2_info(sd, "adv7183: Luma gain control 1 and 2 = 0x%02x 0x%02x\n",
- adv7183_read(sd, ADV7183_LUMA_GAIN_CTRL_1),
- adv7183_read(sd, ADV7183_LUMA_GAIN_CTRL_2));
- v4l2_info(sd, "adv7183: Vsync field control 1 2 and 3 = 0x%02x 0x%02x 0x%02x\n",
- adv7183_read(sd, ADV7183_VS_FIELD_CTRL_1),
- adv7183_read(sd, ADV7183_VS_FIELD_CTRL_2),
- adv7183_read(sd, ADV7183_VS_FIELD_CTRL_3));
- v4l2_info(sd, "adv7183: Hsync positon control 1 2 and 3 = 0x%02x 0x%02x 0x%02x\n",
- adv7183_read(sd, ADV7183_HS_POS_CTRL_1),
- adv7183_read(sd, ADV7183_HS_POS_CTRL_2),
- adv7183_read(sd, ADV7183_HS_POS_CTRL_3));
- v4l2_info(sd, "adv7183: Polarity = 0x%02x\n",
- adv7183_read(sd, ADV7183_POLARITY));
- v4l2_info(sd, "adv7183: ADC control = 0x%02x\n",
- adv7183_read(sd, ADV7183_ADC_CTRL));
- v4l2_info(sd, "adv7183: SD offset Cb and Cr = 0x%02x 0x%02x\n",
- adv7183_read(sd, ADV7183_SD_OFFSET_CB),
- adv7183_read(sd, ADV7183_SD_OFFSET_CR));
- v4l2_info(sd, "adv7183: SD saturation Cb and Cr = 0x%02x 0x%02x\n",
- adv7183_read(sd, ADV7183_SD_SATURATION_CB),
- adv7183_read(sd, ADV7183_SD_SATURATION_CR));
- v4l2_info(sd, "adv7183: Drive strength = 0x%02x\n",
- adv7183_read(sd, ADV7183_DRIVE_STR));
- v4l2_ctrl_handler_log_status(&decoder->hdl, sd->name);
- return 0;
-}
-
-static int adv7183_g_std(struct v4l2_subdev *sd, v4l2_std_id *std)
-{
- struct adv7183 *decoder = to_adv7183(sd);
-
- *std = decoder->std;
- return 0;
-}
-
-static int adv7183_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct adv7183 *decoder = to_adv7183(sd);
- int reg;
-
- reg = adv7183_read(sd, ADV7183_IN_CTRL) & 0xF;
- if (std == V4L2_STD_PAL_60)
- reg |= 0x60;
- else if (std == V4L2_STD_NTSC_443)
- reg |= 0x70;
- else if (std == V4L2_STD_PAL_N)
- reg |= 0x90;
- else if (std == V4L2_STD_PAL_M)
- reg |= 0xA0;
- else if (std == V4L2_STD_PAL_Nc)
- reg |= 0xC0;
- else if (std & V4L2_STD_PAL)
- reg |= 0x80;
- else if (std & V4L2_STD_NTSC)
- reg |= 0x50;
- else if (std & V4L2_STD_SECAM)
- reg |= 0xE0;
- else
- return -EINVAL;
- adv7183_write(sd, ADV7183_IN_CTRL, reg);
-
- decoder->std = std;
-
- return 0;
-}
-
-static int adv7183_reset(struct v4l2_subdev *sd, u32 val)
-{
- int reg;
-
- reg = adv7183_read(sd, ADV7183_POW_MANAGE) | 0x80;
- adv7183_write(sd, ADV7183_POW_MANAGE, reg);
- /* wait 5ms before any further i2c writes are performed */
- usleep_range(5000, 10000);
- return 0;
-}
-
-static int adv7183_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct adv7183 *decoder = to_adv7183(sd);
- int reg;
-
- if ((input > ADV7183_COMPONENT1) || (output > ADV7183_16BIT_OUT))
- return -EINVAL;
-
- if (input != decoder->input) {
- decoder->input = input;
- reg = adv7183_read(sd, ADV7183_IN_CTRL) & 0xF0;
- switch (input) {
- case ADV7183_COMPOSITE1:
- reg |= 0x1;
- break;
- case ADV7183_COMPOSITE2:
- reg |= 0x2;
- break;
- case ADV7183_COMPOSITE3:
- reg |= 0x3;
- break;
- case ADV7183_COMPOSITE4:
- reg |= 0x4;
- break;
- case ADV7183_COMPOSITE5:
- reg |= 0x5;
- break;
- case ADV7183_COMPOSITE6:
- reg |= 0xB;
- break;
- case ADV7183_COMPOSITE7:
- reg |= 0xC;
- break;
- case ADV7183_COMPOSITE8:
- reg |= 0xD;
- break;
- case ADV7183_COMPOSITE9:
- reg |= 0xE;
- break;
- case ADV7183_COMPOSITE10:
- reg |= 0xF;
- break;
- case ADV7183_SVIDEO0:
- reg |= 0x6;
- break;
- case ADV7183_SVIDEO1:
- reg |= 0x7;
- break;
- case ADV7183_SVIDEO2:
- reg |= 0x8;
- break;
- case ADV7183_COMPONENT0:
- reg |= 0x9;
- break;
- case ADV7183_COMPONENT1:
- reg |= 0xA;
- break;
- default:
- break;
- }
- adv7183_write(sd, ADV7183_IN_CTRL, reg);
- }
-
- if (output != decoder->output) {
- decoder->output = output;
- reg = adv7183_read(sd, ADV7183_OUT_CTRL) & 0xC0;
- switch (output) {
- case ADV7183_16BIT_OUT:
- reg |= 0x9;
- break;
- default:
- reg |= 0xC;
- break;
- }
- adv7183_write(sd, ADV7183_OUT_CTRL, reg);
- }
-
- return 0;
-}
-
-static int adv7183_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- int val = ctrl->val;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- if (val < 0)
- val = 127 - val;
- adv7183_write(sd, ADV7183_BRIGHTNESS, val);
- break;
- case V4L2_CID_CONTRAST:
- adv7183_write(sd, ADV7183_CONTRAST, val);
- break;
- case V4L2_CID_SATURATION:
- adv7183_write(sd, ADV7183_SD_SATURATION_CB, val >> 8);
- adv7183_write(sd, ADV7183_SD_SATURATION_CR, (val & 0xFF));
- break;
- case V4L2_CID_HUE:
- adv7183_write(sd, ADV7183_SD_OFFSET_CB, val >> 8);
- adv7183_write(sd, ADV7183_SD_OFFSET_CR, (val & 0xFF));
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int adv7183_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
-{
- struct adv7183 *decoder = to_adv7183(sd);
- int reg;
-
- /* enable autodetection block */
- reg = adv7183_read(sd, ADV7183_IN_CTRL) & 0xF;
- adv7183_write(sd, ADV7183_IN_CTRL, reg);
-
- /* wait autodetection switch */
- mdelay(10);
-
- /* get autodetection result */
- reg = adv7183_read(sd, ADV7183_STATUS_1);
- switch ((reg >> 0x4) & 0x7) {
- case 0:
- *std = V4L2_STD_NTSC;
- break;
- case 1:
- *std = V4L2_STD_NTSC_443;
- break;
- case 2:
- *std = V4L2_STD_PAL_M;
- break;
- case 3:
- *std = V4L2_STD_PAL_60;
- break;
- case 4:
- *std = V4L2_STD_PAL;
- break;
- case 5:
- *std = V4L2_STD_SECAM;
- break;
- case 6:
- *std = V4L2_STD_PAL_Nc;
- break;
- case 7:
- *std = V4L2_STD_SECAM;
- break;
- default:
- *std = V4L2_STD_UNKNOWN;
- break;
- }
-
- /* after std detection, write back user set std */
- adv7183_s_std(sd, decoder->std);
- return 0;
-}
-
-static int adv7183_g_input_status(struct v4l2_subdev *sd, u32 *status)
-{
- int reg;
-
- *status = V4L2_IN_ST_NO_SIGNAL;
- reg = adv7183_read(sd, ADV7183_STATUS_1);
- if (reg < 0)
- return reg;
- if (reg & 0x1)
- *status = 0;
- return 0;
-}
-
-static int adv7183_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index > 0)
- return -EINVAL;
-
- *code = V4L2_MBUS_FMT_UYVY8_2X8;
- return 0;
-}
-
-static int adv7183_try_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *fmt)
-{
- struct adv7183 *decoder = to_adv7183(sd);
-
- fmt->code = V4L2_MBUS_FMT_UYVY8_2X8;
- fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
- if (decoder->std & V4L2_STD_525_60) {
- fmt->field = V4L2_FIELD_SEQ_TB;
- fmt->width = 720;
- fmt->height = 480;
- } else {
- fmt->field = V4L2_FIELD_SEQ_BT;
- fmt->width = 720;
- fmt->height = 576;
- }
- return 0;
-}
-
-static int adv7183_s_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *fmt)
-{
- struct adv7183 *decoder = to_adv7183(sd);
-
- adv7183_try_mbus_fmt(sd, fmt);
- decoder->fmt = *fmt;
- return 0;
-}
-
-static int adv7183_g_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *fmt)
-{
- struct adv7183 *decoder = to_adv7183(sd);
-
- *fmt = decoder->fmt;
- return 0;
-}
-
-static int adv7183_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct adv7183 *decoder = to_adv7183(sd);
-
- if (enable)
- gpio_direction_output(decoder->oe_pin, 0);
- else
- gpio_direction_output(decoder->oe_pin, 1);
- udelay(1);
- return 0;
-}
-
-static int adv7183_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- int rev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- /* 0x11 for adv7183, 0x13 for adv7183b */
- rev = adv7183_read(sd, ADV7183_IDENT);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7183, rev);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int adv7183_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- reg->val = adv7183_read(sd, reg->reg & 0xff);
- reg->size = 1;
- return 0;
-}
-
-static int adv7183_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- adv7183_write(sd, reg->reg & 0xff, reg->val & 0xff);
- return 0;
-}
-#endif
-
-static const struct v4l2_ctrl_ops adv7183_ctrl_ops = {
- .s_ctrl = adv7183_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops adv7183_core_ops = {
- .log_status = adv7183_log_status,
- .g_std = adv7183_g_std,
- .s_std = adv7183_s_std,
- .reset = adv7183_reset,
- .g_chip_ident = adv7183_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = adv7183_g_register,
- .s_register = adv7183_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_video_ops adv7183_video_ops = {
- .s_routing = adv7183_s_routing,
- .querystd = adv7183_querystd,
- .g_input_status = adv7183_g_input_status,
- .enum_mbus_fmt = adv7183_enum_mbus_fmt,
- .try_mbus_fmt = adv7183_try_mbus_fmt,
- .s_mbus_fmt = adv7183_s_mbus_fmt,
- .g_mbus_fmt = adv7183_g_mbus_fmt,
- .s_stream = adv7183_s_stream,
-};
-
-static const struct v4l2_subdev_ops adv7183_ops = {
- .core = &adv7183_core_ops,
- .video = &adv7183_video_ops,
-};
-
-static int adv7183_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct adv7183 *decoder;
- struct v4l2_subdev *sd;
- struct v4l2_ctrl_handler *hdl;
- int ret;
- struct v4l2_mbus_framefmt fmt;
- const unsigned *pin_array;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- v4l_info(client, "chip found @ 0x%02x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- pin_array = client->dev.platform_data;
- if (pin_array == NULL)
- return -EINVAL;
-
- decoder = kzalloc(sizeof(struct adv7183), GFP_KERNEL);
- if (decoder == NULL)
- return -ENOMEM;
-
- decoder->reset_pin = pin_array[0];
- decoder->oe_pin = pin_array[1];
-
- if (gpio_request(decoder->reset_pin, "ADV7183 Reset")) {
- v4l_err(client, "failed to request GPIO %d\n", decoder->reset_pin);
- ret = -EBUSY;
- goto err_free_decoder;
- }
-
- if (gpio_request(decoder->oe_pin, "ADV7183 Output Enable")) {
- v4l_err(client, "failed to request GPIO %d\n", decoder->oe_pin);
- ret = -EBUSY;
- goto err_free_reset;
- }
-
- sd = &decoder->sd;
- v4l2_i2c_subdev_init(sd, client, &adv7183_ops);
-
- hdl = &decoder->hdl;
- v4l2_ctrl_handler_init(hdl, 4);
- v4l2_ctrl_new_std(hdl, &adv7183_ctrl_ops,
- V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
- v4l2_ctrl_new_std(hdl, &adv7183_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 0xFF, 1, 0x80);
- v4l2_ctrl_new_std(hdl, &adv7183_ctrl_ops,
- V4L2_CID_SATURATION, 0, 0xFFFF, 1, 0x8080);
- v4l2_ctrl_new_std(hdl, &adv7183_ctrl_ops,
- V4L2_CID_HUE, 0, 0xFFFF, 1, 0x8080);
- /* hook the control handler into the driver */
- sd->ctrl_handler = hdl;
- if (hdl->error) {
- ret = hdl->error;
-
- v4l2_ctrl_handler_free(hdl);
- goto err_free_oe;
- }
-
- /* v4l2 doesn't support an autodetect standard, pick PAL as default */
- decoder->std = V4L2_STD_PAL;
- decoder->input = ADV7183_COMPOSITE4;
- decoder->output = ADV7183_8BIT_OUT;
-
- gpio_direction_output(decoder->oe_pin, 1);
- /* reset chip */
- gpio_direction_output(decoder->reset_pin, 0);
- /* reset pulse width at least 5ms */
- mdelay(10);
- gpio_direction_output(decoder->reset_pin, 1);
- /* wait 5ms before any further i2c writes are performed */
- mdelay(5);
-
- adv7183_writeregs(sd, adv7183_init_regs, ARRAY_SIZE(adv7183_init_regs));
- adv7183_s_std(sd, decoder->std);
- fmt.width = 720;
- fmt.height = 576;
- adv7183_s_mbus_fmt(sd, &fmt);
-
- /* initialize the hardware to the default control values */
- ret = v4l2_ctrl_handler_setup(hdl);
- if (ret) {
- v4l2_ctrl_handler_free(hdl);
- goto err_free_oe;
- }
-
- return 0;
-err_free_oe:
- gpio_free(decoder->oe_pin);
-err_free_reset:
- gpio_free(decoder->reset_pin);
-err_free_decoder:
- kfree(decoder);
- return ret;
-}
-
-static int adv7183_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct adv7183 *decoder = to_adv7183(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(sd->ctrl_handler);
- gpio_free(decoder->oe_pin);
- gpio_free(decoder->reset_pin);
- kfree(decoder);
- return 0;
-}
-
-static const struct i2c_device_id adv7183_id[] = {
- {"adv7183", 0},
- {},
-};
-
-MODULE_DEVICE_TABLE(i2c, adv7183_id);
-
-static struct i2c_driver adv7183_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "adv7183",
- },
- .probe = adv7183_probe,
- .remove = __devexit_p(adv7183_remove),
- .id_table = adv7183_id,
-};
-
-static __init int adv7183_init(void)
-{
- return i2c_add_driver(&adv7183_driver);
-}
-
-static __exit void adv7183_exit(void)
-{
- i2c_del_driver(&adv7183_driver);
-}
-
-module_init(adv7183_init);
-module_exit(adv7183_exit);
-
-MODULE_DESCRIPTION("Analog Devices ADV7183 video decoder driver");
-MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/adv7183_regs.h b/drivers/media/video/adv7183_regs.h
deleted file mode 100644
index 4a5b7d211d2..00000000000
--- a/drivers/media/video/adv7183_regs.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * adv7183 - Analog Devices ADV7183 video decoder registers
- *
- * Copyright (c) 2011 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ADV7183_REGS_H_
-#define _ADV7183_REGS_H_
-
-#define ADV7183_IN_CTRL 0x00 /* Input control */
-#define ADV7183_VD_SEL 0x01 /* Video selection */
-#define ADV7183_OUT_CTRL 0x03 /* Output control */
-#define ADV7183_EXT_OUT_CTRL 0x04 /* Extended output control */
-#define ADV7183_AUTO_DET_EN 0x07 /* Autodetect enable */
-#define ADV7183_CONTRAST 0x08 /* Contrast */
-#define ADV7183_BRIGHTNESS 0x0A /* Brightness */
-#define ADV7183_HUE 0x0B /* Hue */
-#define ADV7183_DEF_Y 0x0C /* Default value Y */
-#define ADV7183_DEF_C 0x0D /* Default value C */
-#define ADV7183_ADI_CTRL 0x0E /* ADI control */
-#define ADV7183_POW_MANAGE 0x0F /* Power Management */
-#define ADV7183_STATUS_1 0x10 /* Status 1 */
-#define ADV7183_IDENT 0x11 /* Ident */
-#define ADV7183_STATUS_2 0x12 /* Status 2 */
-#define ADV7183_STATUS_3 0x13 /* Status 3 */
-#define ADV7183_ANAL_CLAMP_CTRL 0x14 /* Analog clamp control */
-#define ADV7183_DIGI_CLAMP_CTRL_1 0x15 /* Digital clamp control 1 */
-#define ADV7183_SHAP_FILT_CTRL 0x17 /* Shaping filter control */
-#define ADV7183_SHAP_FILT_CTRL_2 0x18 /* Shaping filter control 2 */
-#define ADV7183_COMB_FILT_CTRL 0x19 /* Comb filter control */
-#define ADV7183_ADI_CTRL_2 0x1D /* ADI control 2 */
-#define ADV7183_PIX_DELAY_CTRL 0x27 /* Pixel delay control */
-#define ADV7183_MISC_GAIN_CTRL 0x2B /* Misc gain control */
-#define ADV7183_AGC_MODE_CTRL 0x2C /* AGC mode control */
-#define ADV7183_CHRO_GAIN_CTRL_1 0x2D /* Chroma gain control 1 */
-#define ADV7183_CHRO_GAIN_CTRL_2 0x2E /* Chroma gain control 2 */
-#define ADV7183_LUMA_GAIN_CTRL_1 0x2F /* Luma gain control 1 */
-#define ADV7183_LUMA_GAIN_CTRL_2 0x30 /* Luma gain control 2 */
-#define ADV7183_VS_FIELD_CTRL_1 0x31 /* Vsync field control 1 */
-#define ADV7183_VS_FIELD_CTRL_2 0x32 /* Vsync field control 2 */
-#define ADV7183_VS_FIELD_CTRL_3 0x33 /* Vsync field control 3 */
-#define ADV7183_HS_POS_CTRL_1 0x34 /* Hsync positon control 1 */
-#define ADV7183_HS_POS_CTRL_2 0x35 /* Hsync positon control 2 */
-#define ADV7183_HS_POS_CTRL_3 0x36 /* Hsync positon control 3 */
-#define ADV7183_POLARITY 0x37 /* Polarity */
-#define ADV7183_NTSC_COMB_CTRL 0x38 /* NTSC comb control */
-#define ADV7183_PAL_COMB_CTRL 0x39 /* PAL comb control */
-#define ADV7183_ADC_CTRL 0x3A /* ADC control */
-#define ADV7183_MAN_WIN_CTRL 0x3D /* Manual window control */
-#define ADV7183_RESAMPLE_CTRL 0x41 /* Resample control */
-#define ADV7183_GEMSTAR_CTRL_1 0x48 /* Gemstar ctrl 1 */
-#define ADV7183_GEMSTAR_CTRL_2 0x49 /* Gemstar ctrl 2 */
-#define ADV7183_GEMSTAR_CTRL_3 0x4A /* Gemstar ctrl 3 */
-#define ADV7183_GEMSTAR_CTRL_4 0x4B /* Gemstar ctrl 4 */
-#define ADV7183_GEMSTAR_CTRL_5 0x4C /* Gemstar ctrl 5 */
-#define ADV7183_CTI_DNR_CTRL_1 0x4D /* CTI DNR ctrl 1 */
-#define ADV7183_CTI_DNR_CTRL_2 0x4E /* CTI DNR ctrl 2 */
-#define ADV7183_CTI_DNR_CTRL_4 0x50 /* CTI DNR ctrl 4 */
-#define ADV7183_LOCK_CNT 0x51 /* Lock count */
-#define ADV7183_FREE_LINE_LEN 0x8F /* Free-Run line length 1 */
-#define ADV7183_VBI_INFO 0x90 /* VBI info */
-#define ADV7183_WSS_1 0x91 /* WSS 1 */
-#define ADV7183_WSS_2 0x92 /* WSS 2 */
-#define ADV7183_EDTV_1 0x93 /* EDTV 1 */
-#define ADV7183_EDTV_2 0x94 /* EDTV 2 */
-#define ADV7183_EDTV_3 0x95 /* EDTV 3 */
-#define ADV7183_CGMS_1 0x96 /* CGMS 1 */
-#define ADV7183_CGMS_2 0x97 /* CGMS 2 */
-#define ADV7183_CGMS_3 0x98 /* CGMS 3 */
-#define ADV7183_CCAP_1 0x99 /* CCAP 1 */
-#define ADV7183_CCAP_2 0x9A /* CCAP 2 */
-#define ADV7183_LETTERBOX_1 0x9B /* Letterbox 1 */
-#define ADV7183_LETTERBOX_2 0x9C /* Letterbox 2 */
-#define ADV7183_LETTERBOX_3 0x9D /* Letterbox 3 */
-#define ADV7183_CRC_EN 0xB2 /* CRC enable */
-#define ADV7183_ADC_SWITCH_1 0xC3 /* ADC switch 1 */
-#define ADV7183_ADC_SWITCH_2 0xC4 /* ADC swithc 2 */
-#define ADV7183_LETTERBOX_CTRL_1 0xDC /* Letterbox control 1 */
-#define ADV7183_LETTERBOX_CTRL_2 0xDD /* Letterbox control 2 */
-#define ADV7183_SD_OFFSET_CB 0xE1 /* SD offset Cb */
-#define ADV7183_SD_OFFSET_CR 0xE2 /* SD offset Cr */
-#define ADV7183_SD_SATURATION_CB 0xE3 /* SD saturation Cb */
-#define ADV7183_SD_SATURATION_CR 0xE4 /* SD saturation Cr */
-#define ADV7183_NTSC_V_BEGIN 0xE5 /* NTSC V bit begin */
-#define ADV7183_NTSC_V_END 0xE6 /* NTSC V bit end */
-#define ADV7183_NTSC_F_TOGGLE 0xE7 /* NTSC F bit toggle */
-#define ADV7183_PAL_V_BEGIN 0xE8 /* PAL V bit begin */
-#define ADV7183_PAL_V_END 0xE9 /* PAL V bit end */
-#define ADV7183_PAL_F_TOGGLE 0xEA /* PAL F bit toggle */
-#define ADV7183_DRIVE_STR 0xF4 /* Drive strength */
-#define ADV7183_IF_COMP_CTRL 0xF8 /* IF comp control */
-#define ADV7183_VS_MODE_CTRL 0xF9 /* VS mode control */
-
-#endif
diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c
deleted file mode 100644
index 2b5aa676a84..00000000000
--- a/drivers/media/video/adv7343.c
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * adv7343 - ADV7343 Video Encoder Driver
- *
- * The encoder hardware does not support SECAM.
- *
- * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ctype.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/videodev2.h>
-#include <linux/uaccess.h>
-
-#include <media/adv7343.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-
-#include "adv7343_regs.h"
-
-MODULE_DESCRIPTION("ADV7343 video encoder driver");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level 0-1");
-
-struct adv7343_state {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- u8 reg00;
- u8 reg01;
- u8 reg02;
- u8 reg35;
- u8 reg80;
- u8 reg82;
- u32 output;
- v4l2_std_id std;
-};
-
-static inline struct adv7343_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct adv7343_state, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct adv7343_state, hdl)->sd;
-}
-
-static inline int adv7343_write(struct v4l2_subdev *sd, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static const u8 adv7343_init_reg_val[] = {
- ADV7343_SOFT_RESET, ADV7343_SOFT_RESET_DEFAULT,
- ADV7343_POWER_MODE_REG, ADV7343_POWER_MODE_REG_DEFAULT,
-
- ADV7343_HD_MODE_REG1, ADV7343_HD_MODE_REG1_DEFAULT,
- ADV7343_HD_MODE_REG2, ADV7343_HD_MODE_REG2_DEFAULT,
- ADV7343_HD_MODE_REG3, ADV7343_HD_MODE_REG3_DEFAULT,
- ADV7343_HD_MODE_REG4, ADV7343_HD_MODE_REG4_DEFAULT,
- ADV7343_HD_MODE_REG5, ADV7343_HD_MODE_REG5_DEFAULT,
- ADV7343_HD_MODE_REG6, ADV7343_HD_MODE_REG6_DEFAULT,
- ADV7343_HD_MODE_REG7, ADV7343_HD_MODE_REG7_DEFAULT,
-
- ADV7343_SD_MODE_REG1, ADV7343_SD_MODE_REG1_DEFAULT,
- ADV7343_SD_MODE_REG2, ADV7343_SD_MODE_REG2_DEFAULT,
- ADV7343_SD_MODE_REG3, ADV7343_SD_MODE_REG3_DEFAULT,
- ADV7343_SD_MODE_REG4, ADV7343_SD_MODE_REG4_DEFAULT,
- ADV7343_SD_MODE_REG5, ADV7343_SD_MODE_REG5_DEFAULT,
- ADV7343_SD_MODE_REG6, ADV7343_SD_MODE_REG6_DEFAULT,
- ADV7343_SD_MODE_REG7, ADV7343_SD_MODE_REG7_DEFAULT,
- ADV7343_SD_MODE_REG8, ADV7343_SD_MODE_REG8_DEFAULT,
-
- ADV7343_SD_HUE_REG, ADV7343_SD_HUE_REG_DEFAULT,
- ADV7343_SD_CGMS_WSS0, ADV7343_SD_CGMS_WSS0_DEFAULT,
- ADV7343_SD_BRIGHTNESS_WSS, ADV7343_SD_BRIGHTNESS_WSS_DEFAULT,
-};
-
-/*
- * 2^32
- * FSC(reg) = FSC (HZ) * --------
- * 27000000
- */
-static const struct adv7343_std_info stdinfo[] = {
- {
- /* FSC(Hz) = 3,579,545.45 Hz */
- SD_STD_NTSC, 569408542, V4L2_STD_NTSC,
- }, {
- /* FSC(Hz) = 3,575,611.00 Hz */
- SD_STD_PAL_M, 568782678, V4L2_STD_PAL_M,
- }, {
- /* FSC(Hz) = 3,582,056.00 */
- SD_STD_PAL_N, 569807903, V4L2_STD_PAL_Nc,
- }, {
- /* FSC(Hz) = 4,433,618.75 Hz */
- SD_STD_PAL_N, 705268427, V4L2_STD_PAL_N,
- }, {
- /* FSC(Hz) = 4,433,618.75 Hz */
- SD_STD_PAL_BDGHI, 705268427, V4L2_STD_PAL,
- }, {
- /* FSC(Hz) = 4,433,618.75 Hz */
- SD_STD_NTSC, 705268427, V4L2_STD_NTSC_443,
- }, {
- /* FSC(Hz) = 4,433,618.75 Hz */
- SD_STD_PAL_M, 705268427, V4L2_STD_PAL_60,
- },
-};
-
-static int adv7343_setstd(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct adv7343_state *state = to_state(sd);
- struct adv7343_std_info *std_info;
- int num_std;
- char *fsc_ptr;
- u8 reg, val;
- int err = 0;
- int i = 0;
-
- std_info = (struct adv7343_std_info *)stdinfo;
- num_std = ARRAY_SIZE(stdinfo);
-
- for (i = 0; i < num_std; i++) {
- if (std_info[i].stdid & std)
- break;
- }
-
- if (i == num_std) {
- v4l2_dbg(1, debug, sd,
- "Invalid std or std is not supported: %llx\n",
- (unsigned long long)std);
- return -EINVAL;
- }
-
- /* Set the standard */
- val = state->reg80 & (~(SD_STD_MASK));
- val |= std_info[i].standard_val3;
- err = adv7343_write(sd, ADV7343_SD_MODE_REG1, val);
- if (err < 0)
- goto setstd_exit;
-
- state->reg80 = val;
-
- /* Configure the input mode register */
- val = state->reg01 & (~((u8) INPUT_MODE_MASK));
- val |= SD_INPUT_MODE;
- err = adv7343_write(sd, ADV7343_MODE_SELECT_REG, val);
- if (err < 0)
- goto setstd_exit;
-
- state->reg01 = val;
-
- /* Program the sub carrier frequency registers */
- fsc_ptr = (unsigned char *)&std_info[i].fsc_val;
- reg = ADV7343_FSC_REG0;
- for (i = 0; i < 4; i++, reg++, fsc_ptr++) {
- err = adv7343_write(sd, reg, *fsc_ptr);
- if (err < 0)
- goto setstd_exit;
- }
-
- val = state->reg80;
-
- /* Filter settings */
- if (std & (V4L2_STD_NTSC | V4L2_STD_NTSC_443))
- val &= 0x03;
- else if (std & ~V4L2_STD_SECAM)
- val |= 0x04;
-
- err = adv7343_write(sd, ADV7343_SD_MODE_REG1, val);
- if (err < 0)
- goto setstd_exit;
-
- state->reg80 = val;
-
-setstd_exit:
- if (err != 0)
- v4l2_err(sd, "Error setting std, write failed\n");
-
- return err;
-}
-
-static int adv7343_setoutput(struct v4l2_subdev *sd, u32 output_type)
-{
- struct adv7343_state *state = to_state(sd);
- unsigned char val;
- int err = 0;
-
- if (output_type > ADV7343_SVIDEO_ID) {
- v4l2_dbg(1, debug, sd,
- "Invalid output type or output type not supported:%d\n",
- output_type);
- return -EINVAL;
- }
-
- /* Enable Appropriate DAC */
- val = state->reg00 & 0x03;
-
- if (output_type == ADV7343_COMPOSITE_ID)
- val |= ADV7343_COMPOSITE_POWER_VALUE;
- else if (output_type == ADV7343_COMPONENT_ID)
- val |= ADV7343_COMPONENT_POWER_VALUE;
- else
- val |= ADV7343_SVIDEO_POWER_VALUE;
-
- err = adv7343_write(sd, ADV7343_POWER_MODE_REG, val);
- if (err < 0)
- goto setoutput_exit;
-
- state->reg00 = val;
-
- /* Enable YUV output */
- val = state->reg02 | YUV_OUTPUT_SELECT;
- err = adv7343_write(sd, ADV7343_MODE_REG0, val);
- if (err < 0)
- goto setoutput_exit;
-
- state->reg02 = val;
-
- /* configure SD DAC Output 2 and SD DAC Output 1 bit to zero */
- val = state->reg82 & (SD_DAC_1_DI & SD_DAC_2_DI);
- err = adv7343_write(sd, ADV7343_SD_MODE_REG2, val);
- if (err < 0)
- goto setoutput_exit;
-
- state->reg82 = val;
-
- /* configure ED/HD Color DAC Swap and ED/HD RGB Input Enable bit to
- * zero */
- val = state->reg35 & (HD_RGB_INPUT_DI & HD_DAC_SWAP_DI);
- err = adv7343_write(sd, ADV7343_HD_MODE_REG6, val);
- if (err < 0)
- goto setoutput_exit;
-
- state->reg35 = val;
-
-setoutput_exit:
- if (err != 0)
- v4l2_err(sd, "Error setting output, write failed\n");
-
- return err;
-}
-
-static int adv7343_log_status(struct v4l2_subdev *sd)
-{
- struct adv7343_state *state = to_state(sd);
-
- v4l2_info(sd, "Standard: %llx\n", (unsigned long long)state->std);
- v4l2_info(sd, "Output: %s\n", (state->output == 0) ? "Composite" :
- ((state->output == 1) ? "Component" : "S-Video"));
- return 0;
-}
-
-static int adv7343_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- return adv7343_write(sd, ADV7343_SD_BRIGHTNESS_WSS,
- ctrl->val);
-
- case V4L2_CID_HUE:
- return adv7343_write(sd, ADV7343_SD_HUE_REG, ctrl->val);
-
- case V4L2_CID_GAIN:
- return adv7343_write(sd, ADV7343_DAC2_OUTPUT_LEVEL, ctrl->val);
- }
- return -EINVAL;
-}
-
-static int adv7343_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7343, 0);
-}
-
-static const struct v4l2_ctrl_ops adv7343_ctrl_ops = {
- .s_ctrl = adv7343_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops adv7343_core_ops = {
- .log_status = adv7343_log_status,
- .g_chip_ident = adv7343_g_chip_ident,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
-};
-
-static int adv7343_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct adv7343_state *state = to_state(sd);
- int err = 0;
-
- if (state->std == std)
- return 0;
-
- err = adv7343_setstd(sd, std);
- if (!err)
- state->std = std;
-
- return err;
-}
-
-static int adv7343_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct adv7343_state *state = to_state(sd);
- int err = 0;
-
- if (state->output == output)
- return 0;
-
- err = adv7343_setoutput(sd, output);
- if (!err)
- state->output = output;
-
- return err;
-}
-
-static const struct v4l2_subdev_video_ops adv7343_video_ops = {
- .s_std_output = adv7343_s_std_output,
- .s_routing = adv7343_s_routing,
-};
-
-static const struct v4l2_subdev_ops adv7343_ops = {
- .core = &adv7343_core_ops,
- .video = &adv7343_video_ops,
-};
-
-static int adv7343_initialize(struct v4l2_subdev *sd)
-{
- struct adv7343_state *state = to_state(sd);
- int err = 0;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(adv7343_init_reg_val); i += 2) {
-
- err = adv7343_write(sd, adv7343_init_reg_val[i],
- adv7343_init_reg_val[i+1]);
- if (err) {
- v4l2_err(sd, "Error initializing\n");
- return err;
- }
- }
-
- /* Configure for default video standard */
- err = adv7343_setoutput(sd, state->output);
- if (err < 0) {
- v4l2_err(sd, "Error setting output during init\n");
- return -EINVAL;
- }
-
- err = adv7343_setstd(sd, state->std);
- if (err < 0) {
- v4l2_err(sd, "Error setting std during init\n");
- return -EINVAL;
- }
-
- return err;
-}
-
-static int adv7343_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct adv7343_state *state;
- int err;
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- state = kzalloc(sizeof(struct adv7343_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
-
- state->reg00 = 0x80;
- state->reg01 = 0x00;
- state->reg02 = 0x20;
- state->reg35 = 0x00;
- state->reg80 = ADV7343_SD_MODE_REG1_DEFAULT;
- state->reg82 = ADV7343_SD_MODE_REG2_DEFAULT;
-
- state->output = ADV7343_COMPOSITE_ID;
- state->std = V4L2_STD_NTSC;
-
- v4l2_i2c_subdev_init(&state->sd, client, &adv7343_ops);
-
- v4l2_ctrl_handler_init(&state->hdl, 2);
- v4l2_ctrl_new_std(&state->hdl, &adv7343_ctrl_ops,
- V4L2_CID_BRIGHTNESS, ADV7343_BRIGHTNESS_MIN,
- ADV7343_BRIGHTNESS_MAX, 1,
- ADV7343_BRIGHTNESS_DEF);
- v4l2_ctrl_new_std(&state->hdl, &adv7343_ctrl_ops,
- V4L2_CID_HUE, ADV7343_HUE_MIN,
- ADV7343_HUE_MAX, 1,
- ADV7343_HUE_DEF);
- v4l2_ctrl_new_std(&state->hdl, &adv7343_ctrl_ops,
- V4L2_CID_GAIN, ADV7343_GAIN_MIN,
- ADV7343_GAIN_MAX, 1,
- ADV7343_GAIN_DEF);
- state->sd.ctrl_handler = &state->hdl;
- if (state->hdl.error) {
- int err = state->hdl.error;
-
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return err;
- }
- v4l2_ctrl_handler_setup(&state->hdl);
-
- err = adv7343_initialize(&state->sd);
- if (err) {
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- }
- return err;
-}
-
-static int adv7343_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct adv7343_state *state = to_state(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
-
- return 0;
-}
-
-static const struct i2c_device_id adv7343_id[] = {
- {"adv7343", 0},
- {},
-};
-
-MODULE_DEVICE_TABLE(i2c, adv7343_id);
-
-static struct i2c_driver adv7343_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "adv7343",
- },
- .probe = adv7343_probe,
- .remove = adv7343_remove,
- .id_table = adv7343_id,
-};
-
-module_i2c_driver(adv7343_driver);
diff --git a/drivers/media/video/adv7343_regs.h b/drivers/media/video/adv7343_regs.h
deleted file mode 100644
index 44660676434..00000000000
--- a/drivers/media/video/adv7343_regs.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * ADV7343 encoder related structure and register definitions
- *
- * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef ADV7343_REG_H
-#define ADV7343_REGS_H
-
-struct adv7343_std_info {
- u32 standard_val3;
- u32 fsc_val;
- v4l2_std_id stdid;
-};
-
-/* Register offset macros */
-#define ADV7343_POWER_MODE_REG (0x00)
-#define ADV7343_MODE_SELECT_REG (0x01)
-#define ADV7343_MODE_REG0 (0x02)
-
-#define ADV7343_DAC2_OUTPUT_LEVEL (0x0b)
-
-#define ADV7343_SOFT_RESET (0x17)
-
-#define ADV7343_HD_MODE_REG1 (0x30)
-#define ADV7343_HD_MODE_REG2 (0x31)
-#define ADV7343_HD_MODE_REG3 (0x32)
-#define ADV7343_HD_MODE_REG4 (0x33)
-#define ADV7343_HD_MODE_REG5 (0x34)
-#define ADV7343_HD_MODE_REG6 (0x35)
-
-#define ADV7343_HD_MODE_REG7 (0x39)
-
-#define ADV7343_SD_MODE_REG1 (0x80)
-#define ADV7343_SD_MODE_REG2 (0x82)
-#define ADV7343_SD_MODE_REG3 (0x83)
-#define ADV7343_SD_MODE_REG4 (0x84)
-#define ADV7343_SD_MODE_REG5 (0x86)
-#define ADV7343_SD_MODE_REG6 (0x87)
-#define ADV7343_SD_MODE_REG7 (0x88)
-#define ADV7343_SD_MODE_REG8 (0x89)
-
-#define ADV7343_FSC_REG0 (0x8C)
-#define ADV7343_FSC_REG1 (0x8D)
-#define ADV7343_FSC_REG2 (0x8E)
-#define ADV7343_FSC_REG3 (0x8F)
-
-#define ADV7343_SD_CGMS_WSS0 (0x99)
-
-#define ADV7343_SD_HUE_REG (0xA0)
-#define ADV7343_SD_BRIGHTNESS_WSS (0xA1)
-
-/* Default values for the registers */
-#define ADV7343_POWER_MODE_REG_DEFAULT (0x10)
-#define ADV7343_HD_MODE_REG1_DEFAULT (0x3C) /* Changed Default
- 720p EAVSAV code*/
-#define ADV7343_HD_MODE_REG2_DEFAULT (0x01) /* Changed Pixel data
- valid */
-#define ADV7343_HD_MODE_REG3_DEFAULT (0x00) /* Color delay 0 clks */
-#define ADV7343_HD_MODE_REG4_DEFAULT (0xE8) /* Changed */
-#define ADV7343_HD_MODE_REG5_DEFAULT (0x08)
-#define ADV7343_HD_MODE_REG6_DEFAULT (0x00)
-#define ADV7343_HD_MODE_REG7_DEFAULT (0x00)
-#define ADV7343_SD_MODE_REG8_DEFAULT (0x00)
-#define ADV7343_SOFT_RESET_DEFAULT (0x02)
-#define ADV7343_COMPOSITE_POWER_VALUE (0x80)
-#define ADV7343_COMPONENT_POWER_VALUE (0x1C)
-#define ADV7343_SVIDEO_POWER_VALUE (0x60)
-#define ADV7343_SD_HUE_REG_DEFAULT (127)
-#define ADV7343_SD_BRIGHTNESS_WSS_DEFAULT (0x03)
-
-#define ADV7343_SD_CGMS_WSS0_DEFAULT (0x10)
-
-#define ADV7343_SD_MODE_REG1_DEFAULT (0x00)
-#define ADV7343_SD_MODE_REG2_DEFAULT (0xC9)
-#define ADV7343_SD_MODE_REG3_DEFAULT (0x10)
-#define ADV7343_SD_MODE_REG4_DEFAULT (0x01)
-#define ADV7343_SD_MODE_REG5_DEFAULT (0x02)
-#define ADV7343_SD_MODE_REG6_DEFAULT (0x0C)
-#define ADV7343_SD_MODE_REG7_DEFAULT (0x04)
-#define ADV7343_SD_MODE_REG8_DEFAULT (0x00)
-
-/* Bit masks for Mode Select Register */
-#define INPUT_MODE_MASK (0x70)
-#define SD_INPUT_MODE (0x00)
-#define HD_720P_INPUT_MODE (0x10)
-#define HD_1080I_INPUT_MODE (0x10)
-
-/* Bit masks for Mode Register 0 */
-#define TEST_PATTERN_BLACK_BAR_EN (0x04)
-#define YUV_OUTPUT_SELECT (0x20)
-#define RGB_OUTPUT_SELECT (0xDF)
-
-/* Bit masks for DAC output levels */
-#define DAC_OUTPUT_LEVEL_MASK (0xFF)
-
-/* Bit masks for soft reset register */
-#define SOFT_RESET (0x02)
-
-/* Bit masks for HD Mode Register 1 */
-#define OUTPUT_STD_MASK (0x03)
-#define OUTPUT_STD_SHIFT (0)
-#define OUTPUT_STD_EIA0_2 (0x00)
-#define OUTPUT_STD_EIA0_1 (0x01)
-#define OUTPUT_STD_FULL (0x02)
-#define EMBEDDED_SYNC (0x04)
-#define EXTERNAL_SYNC (0xFB)
-#define STD_MODE_SHIFT (3)
-#define STD_MODE_MASK (0x1F)
-#define STD_MODE_720P (0x05)
-#define STD_MODE_720P_25 (0x08)
-#define STD_MODE_720P_30 (0x07)
-#define STD_MODE_720P_50 (0x06)
-#define STD_MODE_1080I (0x0D)
-#define STD_MODE_1080I_25fps (0x0E)
-#define STD_MODE_1080P_24 (0x12)
-#define STD_MODE_1080P_25 (0x10)
-#define STD_MODE_1080P_30 (0x0F)
-#define STD_MODE_525P (0x00)
-#define STD_MODE_625P (0x03)
-
-/* Bit masks for SD Mode Register 1 */
-#define SD_STD_MASK (0x03)
-#define SD_STD_NTSC (0x00)
-#define SD_STD_PAL_BDGHI (0x01)
-#define SD_STD_PAL_M (0x02)
-#define SD_STD_PAL_N (0x03)
-#define SD_LUMA_FLTR_MASK (0x7)
-#define SD_LUMA_FLTR_SHIFT (0x2)
-#define SD_CHROMA_FLTR_MASK (0x7)
-#define SD_CHROMA_FLTR_SHIFT (0x5)
-
-/* Bit masks for SD Mode Register 2 */
-#define SD_PBPR_SSAF_EN (0x01)
-#define SD_PBPR_SSAF_DI (0xFE)
-#define SD_DAC_1_DI (0xFD)
-#define SD_DAC_2_DI (0xFB)
-#define SD_PEDESTAL_EN (0x08)
-#define SD_PEDESTAL_DI (0xF7)
-#define SD_SQUARE_PIXEL_EN (0x10)
-#define SD_SQUARE_PIXEL_DI (0xEF)
-#define SD_PIXEL_DATA_VALID (0x40)
-#define SD_ACTIVE_EDGE_EN (0x80)
-#define SD_ACTIVE_EDGE_DI (0x7F)
-
-/* Bit masks for HD Mode Register 6 */
-#define HD_RGB_INPUT_EN (0x02)
-#define HD_RGB_INPUT_DI (0xFD)
-#define HD_PBPR_SYNC_EN (0x04)
-#define HD_PBPR_SYNC_DI (0xFB)
-#define HD_DAC_SWAP_EN (0x08)
-#define HD_DAC_SWAP_DI (0xF7)
-#define HD_GAMMA_CURVE_A (0xEF)
-#define HD_GAMMA_CURVE_B (0x10)
-#define HD_GAMMA_EN (0x20)
-#define HD_GAMMA_DI (0xDF)
-#define HD_ADPT_FLTR_MODEB (0x40)
-#define HD_ADPT_FLTR_MODEA (0xBF)
-#define HD_ADPT_FLTR_EN (0x80)
-#define HD_ADPT_FLTR_DI (0x7F)
-
-#define ADV7343_BRIGHTNESS_MAX (127)
-#define ADV7343_BRIGHTNESS_MIN (0)
-#define ADV7343_BRIGHTNESS_DEF (3)
-#define ADV7343_HUE_MAX (255)
-#define ADV7343_HUE_MIN (0)
-#define ADV7343_HUE_DEF (127)
-#define ADV7343_GAIN_MAX (64)
-#define ADV7343_GAIN_MIN (-64)
-#define ADV7343_GAIN_DEF (0)
-
-#endif
diff --git a/drivers/media/video/adv7393.c b/drivers/media/video/adv7393.c
deleted file mode 100644
index 3dc6098c726..00000000000
--- a/drivers/media/video/adv7393.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * adv7393 - ADV7393 Video Encoder Driver
- *
- * The encoder hardware does not support SECAM.
- *
- * Copyright (C) 2010-2012 ADVANSEE - http://www.advansee.com/
- * Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
- *
- * Based on ADV7343 driver,
- *
- * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ctype.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/videodev2.h>
-#include <linux/uaccess.h>
-
-#include <media/adv7393.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-
-#include "adv7393_regs.h"
-
-MODULE_DESCRIPTION("ADV7393 video encoder driver");
-MODULE_LICENSE("GPL");
-
-static bool debug;
-module_param(debug, bool, 0644);
-MODULE_PARM_DESC(debug, "Debug level 0-1");
-
-struct adv7393_state {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- u8 reg00;
- u8 reg01;
- u8 reg02;
- u8 reg35;
- u8 reg80;
- u8 reg82;
- u32 output;
- v4l2_std_id std;
-};
-
-static inline struct adv7393_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct adv7393_state, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct adv7393_state, hdl)->sd;
-}
-
-static inline int adv7393_write(struct v4l2_subdev *sd, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static const u8 adv7393_init_reg_val[] = {
- ADV7393_SOFT_RESET, ADV7393_SOFT_RESET_DEFAULT,
- ADV7393_POWER_MODE_REG, ADV7393_POWER_MODE_REG_DEFAULT,
-
- ADV7393_HD_MODE_REG1, ADV7393_HD_MODE_REG1_DEFAULT,
- ADV7393_HD_MODE_REG2, ADV7393_HD_MODE_REG2_DEFAULT,
- ADV7393_HD_MODE_REG3, ADV7393_HD_MODE_REG3_DEFAULT,
- ADV7393_HD_MODE_REG4, ADV7393_HD_MODE_REG4_DEFAULT,
- ADV7393_HD_MODE_REG5, ADV7393_HD_MODE_REG5_DEFAULT,
- ADV7393_HD_MODE_REG6, ADV7393_HD_MODE_REG6_DEFAULT,
- ADV7393_HD_MODE_REG7, ADV7393_HD_MODE_REG7_DEFAULT,
-
- ADV7393_SD_MODE_REG1, ADV7393_SD_MODE_REG1_DEFAULT,
- ADV7393_SD_MODE_REG2, ADV7393_SD_MODE_REG2_DEFAULT,
- ADV7393_SD_MODE_REG3, ADV7393_SD_MODE_REG3_DEFAULT,
- ADV7393_SD_MODE_REG4, ADV7393_SD_MODE_REG4_DEFAULT,
- ADV7393_SD_MODE_REG5, ADV7393_SD_MODE_REG5_DEFAULT,
- ADV7393_SD_MODE_REG6, ADV7393_SD_MODE_REG6_DEFAULT,
- ADV7393_SD_MODE_REG7, ADV7393_SD_MODE_REG7_DEFAULT,
- ADV7393_SD_MODE_REG8, ADV7393_SD_MODE_REG8_DEFAULT,
-
- ADV7393_SD_TIMING_REG0, ADV7393_SD_TIMING_REG0_DEFAULT,
-
- ADV7393_SD_HUE_ADJUST, ADV7393_SD_HUE_ADJUST_DEFAULT,
- ADV7393_SD_CGMS_WSS0, ADV7393_SD_CGMS_WSS0_DEFAULT,
- ADV7393_SD_BRIGHTNESS_WSS, ADV7393_SD_BRIGHTNESS_WSS_DEFAULT,
-};
-
-/*
- * 2^32
- * FSC(reg) = FSC (HZ) * --------
- * 27000000
- */
-static const struct adv7393_std_info stdinfo[] = {
- {
- /* FSC(Hz) = 4,433,618.75 Hz */
- SD_STD_NTSC, 705268427, V4L2_STD_NTSC_443,
- }, {
- /* FSC(Hz) = 3,579,545.45 Hz */
- SD_STD_NTSC, 569408542, V4L2_STD_NTSC,
- }, {
- /* FSC(Hz) = 3,575,611.00 Hz */
- SD_STD_PAL_M, 568782678, V4L2_STD_PAL_M,
- }, {
- /* FSC(Hz) = 3,582,056.00 Hz */
- SD_STD_PAL_N, 569807903, V4L2_STD_PAL_Nc,
- }, {
- /* FSC(Hz) = 4,433,618.75 Hz */
- SD_STD_PAL_N, 705268427, V4L2_STD_PAL_N,
- }, {
- /* FSC(Hz) = 4,433,618.75 Hz */
- SD_STD_PAL_M, 705268427, V4L2_STD_PAL_60,
- }, {
- /* FSC(Hz) = 4,433,618.75 Hz */
- SD_STD_PAL_BDGHI, 705268427, V4L2_STD_PAL,
- },
-};
-
-static int adv7393_setstd(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct adv7393_state *state = to_state(sd);
- const struct adv7393_std_info *std_info;
- int num_std;
- u8 reg;
- u32 val;
- int err = 0;
- int i;
-
- num_std = ARRAY_SIZE(stdinfo);
-
- for (i = 0; i < num_std; i++) {
- if (stdinfo[i].stdid & std)
- break;
- }
-
- if (i == num_std) {
- v4l2_dbg(1, debug, sd,
- "Invalid std or std is not supported: %llx\n",
- (unsigned long long)std);
- return -EINVAL;
- }
-
- std_info = &stdinfo[i];
-
- /* Set the standard */
- val = state->reg80 & ~SD_STD_MASK;
- val |= std_info->standard_val3;
- err = adv7393_write(sd, ADV7393_SD_MODE_REG1, val);
- if (err < 0)
- goto setstd_exit;
-
- state->reg80 = val;
-
- /* Configure the input mode register */
- val = state->reg01 & ~INPUT_MODE_MASK;
- val |= SD_INPUT_MODE;
- err = adv7393_write(sd, ADV7393_MODE_SELECT_REG, val);
- if (err < 0)
- goto setstd_exit;
-
- state->reg01 = val;
-
- /* Program the sub carrier frequency registers */
- val = std_info->fsc_val;
- for (reg = ADV7393_FSC_REG0; reg <= ADV7393_FSC_REG3; reg++) {
- err = adv7393_write(sd, reg, val);
- if (err < 0)
- goto setstd_exit;
- val >>= 8;
- }
-
- val = state->reg82;
-
- /* Pedestal settings */
- if (std & (V4L2_STD_NTSC | V4L2_STD_NTSC_443))
- val |= SD_PEDESTAL_EN;
- else
- val &= SD_PEDESTAL_DI;
-
- err = adv7393_write(sd, ADV7393_SD_MODE_REG2, val);
- if (err < 0)
- goto setstd_exit;
-
- state->reg82 = val;
-
-setstd_exit:
- if (err != 0)
- v4l2_err(sd, "Error setting std, write failed\n");
-
- return err;
-}
-
-static int adv7393_setoutput(struct v4l2_subdev *sd, u32 output_type)
-{
- struct adv7393_state *state = to_state(sd);
- u8 val;
- int err = 0;
-
- if (output_type > ADV7393_SVIDEO_ID) {
- v4l2_dbg(1, debug, sd,
- "Invalid output type or output type not supported:%d\n",
- output_type);
- return -EINVAL;
- }
-
- /* Enable Appropriate DAC */
- val = state->reg00 & 0x03;
-
- if (output_type == ADV7393_COMPOSITE_ID)
- val |= ADV7393_COMPOSITE_POWER_VALUE;
- else if (output_type == ADV7393_COMPONENT_ID)
- val |= ADV7393_COMPONENT_POWER_VALUE;
- else
- val |= ADV7393_SVIDEO_POWER_VALUE;
-
- err = adv7393_write(sd, ADV7393_POWER_MODE_REG, val);
- if (err < 0)
- goto setoutput_exit;
-
- state->reg00 = val;
-
- /* Enable YUV output */
- val = state->reg02 | YUV_OUTPUT_SELECT;
- err = adv7393_write(sd, ADV7393_MODE_REG0, val);
- if (err < 0)
- goto setoutput_exit;
-
- state->reg02 = val;
-
- /* configure SD DAC Output 1 bit */
- val = state->reg82;
- if (output_type == ADV7393_COMPONENT_ID)
- val &= SD_DAC_OUT1_DI;
- else
- val |= SD_DAC_OUT1_EN;
- err = adv7393_write(sd, ADV7393_SD_MODE_REG2, val);
- if (err < 0)
- goto setoutput_exit;
-
- state->reg82 = val;
-
- /* configure ED/HD Color DAC Swap bit to zero */
- val = state->reg35 & HD_DAC_SWAP_DI;
- err = adv7393_write(sd, ADV7393_HD_MODE_REG6, val);
- if (err < 0)
- goto setoutput_exit;
-
- state->reg35 = val;
-
-setoutput_exit:
- if (err != 0)
- v4l2_err(sd, "Error setting output, write failed\n");
-
- return err;
-}
-
-static int adv7393_log_status(struct v4l2_subdev *sd)
-{
- struct adv7393_state *state = to_state(sd);
-
- v4l2_info(sd, "Standard: %llx\n", (unsigned long long)state->std);
- v4l2_info(sd, "Output: %s\n", (state->output == 0) ? "Composite" :
- ((state->output == 1) ? "Component" : "S-Video"));
- return 0;
-}
-
-static int adv7393_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- return adv7393_write(sd, ADV7393_SD_BRIGHTNESS_WSS,
- ctrl->val & SD_BRIGHTNESS_VALUE_MASK);
-
- case V4L2_CID_HUE:
- return adv7393_write(sd, ADV7393_SD_HUE_ADJUST,
- ctrl->val - ADV7393_HUE_MIN);
-
- case V4L2_CID_GAIN:
- return adv7393_write(sd, ADV7393_DAC123_OUTPUT_LEVEL,
- ctrl->val);
- }
- return -EINVAL;
-}
-
-static int adv7393_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7393, 0);
-}
-
-static const struct v4l2_ctrl_ops adv7393_ctrl_ops = {
- .s_ctrl = adv7393_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops adv7393_core_ops = {
- .log_status = adv7393_log_status,
- .g_chip_ident = adv7393_g_chip_ident,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
-};
-
-static int adv7393_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct adv7393_state *state = to_state(sd);
- int err = 0;
-
- if (state->std == std)
- return 0;
-
- err = adv7393_setstd(sd, std);
- if (!err)
- state->std = std;
-
- return err;
-}
-
-static int adv7393_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct adv7393_state *state = to_state(sd);
- int err = 0;
-
- if (state->output == output)
- return 0;
-
- err = adv7393_setoutput(sd, output);
- if (!err)
- state->output = output;
-
- return err;
-}
-
-static const struct v4l2_subdev_video_ops adv7393_video_ops = {
- .s_std_output = adv7393_s_std_output,
- .s_routing = adv7393_s_routing,
-};
-
-static const struct v4l2_subdev_ops adv7393_ops = {
- .core = &adv7393_core_ops,
- .video = &adv7393_video_ops,
-};
-
-static int adv7393_initialize(struct v4l2_subdev *sd)
-{
- struct adv7393_state *state = to_state(sd);
- int err = 0;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(adv7393_init_reg_val); i += 2) {
-
- err = adv7393_write(sd, adv7393_init_reg_val[i],
- adv7393_init_reg_val[i+1]);
- if (err) {
- v4l2_err(sd, "Error initializing\n");
- return err;
- }
- }
-
- /* Configure for default video standard */
- err = adv7393_setoutput(sd, state->output);
- if (err < 0) {
- v4l2_err(sd, "Error setting output during init\n");
- return -EINVAL;
- }
-
- err = adv7393_setstd(sd, state->std);
- if (err < 0) {
- v4l2_err(sd, "Error setting std during init\n");
- return -EINVAL;
- }
-
- return err;
-}
-
-static int adv7393_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct adv7393_state *state;
- int err;
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- state = kzalloc(sizeof(struct adv7393_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
-
- state->reg00 = ADV7393_POWER_MODE_REG_DEFAULT;
- state->reg01 = 0x00;
- state->reg02 = 0x20;
- state->reg35 = ADV7393_HD_MODE_REG6_DEFAULT;
- state->reg80 = ADV7393_SD_MODE_REG1_DEFAULT;
- state->reg82 = ADV7393_SD_MODE_REG2_DEFAULT;
-
- state->output = ADV7393_COMPOSITE_ID;
- state->std = V4L2_STD_NTSC;
-
- v4l2_i2c_subdev_init(&state->sd, client, &adv7393_ops);
-
- v4l2_ctrl_handler_init(&state->hdl, 3);
- v4l2_ctrl_new_std(&state->hdl, &adv7393_ctrl_ops,
- V4L2_CID_BRIGHTNESS, ADV7393_BRIGHTNESS_MIN,
- ADV7393_BRIGHTNESS_MAX, 1,
- ADV7393_BRIGHTNESS_DEF);
- v4l2_ctrl_new_std(&state->hdl, &adv7393_ctrl_ops,
- V4L2_CID_HUE, ADV7393_HUE_MIN,
- ADV7393_HUE_MAX, 1,
- ADV7393_HUE_DEF);
- v4l2_ctrl_new_std(&state->hdl, &adv7393_ctrl_ops,
- V4L2_CID_GAIN, ADV7393_GAIN_MIN,
- ADV7393_GAIN_MAX, 1,
- ADV7393_GAIN_DEF);
- state->sd.ctrl_handler = &state->hdl;
- if (state->hdl.error) {
- int err = state->hdl.error;
-
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return err;
- }
- v4l2_ctrl_handler_setup(&state->hdl);
-
- err = adv7393_initialize(&state->sd);
- if (err) {
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- }
- return err;
-}
-
-static int adv7393_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct adv7393_state *state = to_state(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
-
- return 0;
-}
-
-static const struct i2c_device_id adv7393_id[] = {
- {"adv7393", 0},
- {},
-};
-MODULE_DEVICE_TABLE(i2c, adv7393_id);
-
-static struct i2c_driver adv7393_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "adv7393",
- },
- .probe = adv7393_probe,
- .remove = adv7393_remove,
- .id_table = adv7393_id,
-};
-module_i2c_driver(adv7393_driver);
diff --git a/drivers/media/video/adv7393_regs.h b/drivers/media/video/adv7393_regs.h
deleted file mode 100644
index 78968330f0b..00000000000
--- a/drivers/media/video/adv7393_regs.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * ADV7393 encoder related structure and register definitions
- *
- * Copyright (C) 2010-2012 ADVANSEE - http://www.advansee.com/
- * Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
- *
- * Based on ADV7343 driver,
- *
- * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef ADV7393_REGS_H
-#define ADV7393_REGS_H
-
-struct adv7393_std_info {
- u32 standard_val3;
- u32 fsc_val;
- v4l2_std_id stdid;
-};
-
-/* Register offset macros */
-#define ADV7393_POWER_MODE_REG (0x00)
-#define ADV7393_MODE_SELECT_REG (0x01)
-#define ADV7393_MODE_REG0 (0x02)
-
-#define ADV7393_DAC123_OUTPUT_LEVEL (0x0B)
-
-#define ADV7393_SOFT_RESET (0x17)
-
-#define ADV7393_HD_MODE_REG1 (0x30)
-#define ADV7393_HD_MODE_REG2 (0x31)
-#define ADV7393_HD_MODE_REG3 (0x32)
-#define ADV7393_HD_MODE_REG4 (0x33)
-#define ADV7393_HD_MODE_REG5 (0x34)
-#define ADV7393_HD_MODE_REG6 (0x35)
-
-#define ADV7393_HD_MODE_REG7 (0x39)
-
-#define ADV7393_SD_MODE_REG1 (0x80)
-#define ADV7393_SD_MODE_REG2 (0x82)
-#define ADV7393_SD_MODE_REG3 (0x83)
-#define ADV7393_SD_MODE_REG4 (0x84)
-#define ADV7393_SD_MODE_REG5 (0x86)
-#define ADV7393_SD_MODE_REG6 (0x87)
-#define ADV7393_SD_MODE_REG7 (0x88)
-#define ADV7393_SD_MODE_REG8 (0x89)
-
-#define ADV7393_SD_TIMING_REG0 (0x8A)
-
-#define ADV7393_FSC_REG0 (0x8C)
-#define ADV7393_FSC_REG1 (0x8D)
-#define ADV7393_FSC_REG2 (0x8E)
-#define ADV7393_FSC_REG3 (0x8F)
-
-#define ADV7393_SD_CGMS_WSS0 (0x99)
-
-#define ADV7393_SD_HUE_ADJUST (0xA0)
-#define ADV7393_SD_BRIGHTNESS_WSS (0xA1)
-
-/* Default values for the registers */
-#define ADV7393_POWER_MODE_REG_DEFAULT (0x10)
-#define ADV7393_HD_MODE_REG1_DEFAULT (0x3C) /* Changed Default
- 720p EAV/SAV code*/
-#define ADV7393_HD_MODE_REG2_DEFAULT (0x01) /* Changed Pixel data
- valid */
-#define ADV7393_HD_MODE_REG3_DEFAULT (0x00) /* Color delay 0 clks */
-#define ADV7393_HD_MODE_REG4_DEFAULT (0xEC) /* Changed */
-#define ADV7393_HD_MODE_REG5_DEFAULT (0x08)
-#define ADV7393_HD_MODE_REG6_DEFAULT (0x00)
-#define ADV7393_HD_MODE_REG7_DEFAULT (0x00)
-#define ADV7393_SOFT_RESET_DEFAULT (0x02)
-#define ADV7393_COMPOSITE_POWER_VALUE (0x10)
-#define ADV7393_COMPONENT_POWER_VALUE (0x1C)
-#define ADV7393_SVIDEO_POWER_VALUE (0x0C)
-#define ADV7393_SD_HUE_ADJUST_DEFAULT (0x80)
-#define ADV7393_SD_BRIGHTNESS_WSS_DEFAULT (0x00)
-
-#define ADV7393_SD_CGMS_WSS0_DEFAULT (0x10)
-
-#define ADV7393_SD_MODE_REG1_DEFAULT (0x10)
-#define ADV7393_SD_MODE_REG2_DEFAULT (0xC9)
-#define ADV7393_SD_MODE_REG3_DEFAULT (0x00)
-#define ADV7393_SD_MODE_REG4_DEFAULT (0x00)
-#define ADV7393_SD_MODE_REG5_DEFAULT (0x02)
-#define ADV7393_SD_MODE_REG6_DEFAULT (0x8C)
-#define ADV7393_SD_MODE_REG7_DEFAULT (0x14)
-#define ADV7393_SD_MODE_REG8_DEFAULT (0x00)
-
-#define ADV7393_SD_TIMING_REG0_DEFAULT (0x0C)
-
-/* Bit masks for Mode Select Register */
-#define INPUT_MODE_MASK (0x70)
-#define SD_INPUT_MODE (0x00)
-#define HD_720P_INPUT_MODE (0x10)
-#define HD_1080I_INPUT_MODE (0x10)
-
-/* Bit masks for Mode Register 0 */
-#define TEST_PATTERN_BLACK_BAR_EN (0x04)
-#define YUV_OUTPUT_SELECT (0x20)
-#define RGB_OUTPUT_SELECT (0xDF)
-
-/* Bit masks for SD brightness/WSS */
-#define SD_BRIGHTNESS_VALUE_MASK (0x7F)
-#define SD_BLANK_WSS_DATA_MASK (0x80)
-
-/* Bit masks for soft reset register */
-#define SOFT_RESET (0x02)
-
-/* Bit masks for HD Mode Register 1 */
-#define OUTPUT_STD_MASK (0x03)
-#define OUTPUT_STD_SHIFT (0)
-#define OUTPUT_STD_EIA0_2 (0x00)
-#define OUTPUT_STD_EIA0_1 (0x01)
-#define OUTPUT_STD_FULL (0x02)
-#define EMBEDDED_SYNC (0x04)
-#define EXTERNAL_SYNC (0xFB)
-#define STD_MODE_MASK (0x1F)
-#define STD_MODE_SHIFT (3)
-#define STD_MODE_720P (0x05)
-#define STD_MODE_720P_25 (0x08)
-#define STD_MODE_720P_30 (0x07)
-#define STD_MODE_720P_50 (0x06)
-#define STD_MODE_1080I (0x0D)
-#define STD_MODE_1080I_25 (0x0E)
-#define STD_MODE_1080P_24 (0x11)
-#define STD_MODE_1080P_25 (0x10)
-#define STD_MODE_1080P_30 (0x0F)
-#define STD_MODE_525P (0x00)
-#define STD_MODE_625P (0x03)
-
-/* Bit masks for SD Mode Register 1 */
-#define SD_STD_MASK (0x03)
-#define SD_STD_NTSC (0x00)
-#define SD_STD_PAL_BDGHI (0x01)
-#define SD_STD_PAL_M (0x02)
-#define SD_STD_PAL_N (0x03)
-#define SD_LUMA_FLTR_MASK (0x07)
-#define SD_LUMA_FLTR_SHIFT (2)
-#define SD_CHROMA_FLTR_MASK (0x07)
-#define SD_CHROMA_FLTR_SHIFT (5)
-
-/* Bit masks for SD Mode Register 2 */
-#define SD_PRPB_SSAF_EN (0x01)
-#define SD_PRPB_SSAF_DI (0xFE)
-#define SD_DAC_OUT1_EN (0x02)
-#define SD_DAC_OUT1_DI (0xFD)
-#define SD_PEDESTAL_EN (0x08)
-#define SD_PEDESTAL_DI (0xF7)
-#define SD_SQUARE_PIXEL_EN (0x10)
-#define SD_SQUARE_PIXEL_DI (0xEF)
-#define SD_PIXEL_DATA_VALID (0x40)
-#define SD_ACTIVE_EDGE_EN (0x80)
-#define SD_ACTIVE_EDGE_DI (0x7F)
-
-/* Bit masks for HD Mode Register 6 */
-#define HD_PRPB_SYNC_EN (0x04)
-#define HD_PRPB_SYNC_DI (0xFB)
-#define HD_DAC_SWAP_EN (0x08)
-#define HD_DAC_SWAP_DI (0xF7)
-#define HD_GAMMA_CURVE_A (0xEF)
-#define HD_GAMMA_CURVE_B (0x10)
-#define HD_GAMMA_EN (0x20)
-#define HD_GAMMA_DI (0xDF)
-#define HD_ADPT_FLTR_MODEA (0xBF)
-#define HD_ADPT_FLTR_MODEB (0x40)
-#define HD_ADPT_FLTR_EN (0x80)
-#define HD_ADPT_FLTR_DI (0x7F)
-
-#define ADV7393_BRIGHTNESS_MAX (63)
-#define ADV7393_BRIGHTNESS_MIN (-64)
-#define ADV7393_BRIGHTNESS_DEF (0)
-#define ADV7393_HUE_MAX (127)
-#define ADV7393_HUE_MIN (-128)
-#define ADV7393_HUE_DEF (0)
-#define ADV7393_GAIN_MAX (64)
-#define ADV7393_GAIN_MIN (-64)
-#define ADV7393_GAIN_DEF (0)
-
-#endif
diff --git a/drivers/media/video/ak881x.c b/drivers/media/video/ak881x.c
deleted file mode 100644
index ba674656b10..00000000000
--- a/drivers/media/video/ak881x.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Driver for AK8813 / AK8814 TV-ecoders from Asahi Kasei Microsystems Co., Ltd. (AKM)
- *
- * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/module.h>
-
-#include <media/ak881x.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-
-#define AK881X_INTERFACE_MODE 0
-#define AK881X_VIDEO_PROCESS1 1
-#define AK881X_VIDEO_PROCESS2 2
-#define AK881X_VIDEO_PROCESS3 3
-#define AK881X_DAC_MODE 5
-#define AK881X_STATUS 0x24
-#define AK881X_DEVICE_ID 0x25
-#define AK881X_DEVICE_REVISION 0x26
-
-struct ak881x {
- struct v4l2_subdev subdev;
- struct ak881x_pdata *pdata;
- unsigned int lines;
- int id; /* DEVICE_ID code V4L2_IDENT_AK881X code from v4l2-chip-ident.h */
- char revision; /* DEVICE_REVISION content */
-};
-
-static int reg_read(struct i2c_client *client, const u8 reg)
-{
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int reg_write(struct i2c_client *client, const u8 reg,
- const u8 data)
-{
- return i2c_smbus_write_byte_data(client, reg, data);
-}
-
-static int reg_set(struct i2c_client *client, const u8 reg,
- const u8 data, u8 mask)
-{
- int ret = reg_read(client, reg);
- if (ret < 0)
- return ret;
- return reg_write(client, reg, (ret & ~mask) | (data & mask));
-}
-
-static struct ak881x *to_ak881x(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client), struct ak881x, subdev);
-}
-
-static int ak881x_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ak881x *ak881x = to_ak881x(client);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = ak881x->id;
- id->revision = ak881x->revision;
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ak881x_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x26)
- return -EINVAL;
-
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
- reg->val = reg_read(client, reg->reg);
-
- if (reg->val > 0xffff)
- return -EIO;
-
- return 0;
-}
-
-static int ak881x_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x26)
- return -EINVAL;
-
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
- if (reg_write(client, reg->reg, reg->val) < 0)
- return -EIO;
-
- return 0;
-}
-#endif
-
-static int ak881x_try_g_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ak881x *ak881x = to_ak881x(client);
-
- v4l_bound_align_image(&mf->width, 0, 720, 2,
- &mf->height, 0, ak881x->lines, 1, 0);
- mf->field = V4L2_FIELD_INTERLACED;
- mf->code = V4L2_MBUS_FMT_YUYV8_2X8;
- mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
-
- return 0;
-}
-
-static int ak881x_s_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- if (mf->field != V4L2_FIELD_INTERLACED ||
- mf->code != V4L2_MBUS_FMT_YUYV8_2X8)
- return -EINVAL;
-
- return ak881x_try_g_mbus_fmt(sd, mf);
-}
-
-static int ak881x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index)
- return -EINVAL;
-
- *code = V4L2_MBUS_FMT_YUYV8_2X8;
- return 0;
-}
-
-static int ak881x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ak881x *ak881x = to_ak881x(client);
-
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = 720;
- a->bounds.height = ak881x->lines;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int ak881x_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ak881x *ak881x = to_ak881x(client);
- u8 vp1;
-
- if (std == V4L2_STD_NTSC_443) {
- vp1 = 3;
- ak881x->lines = 480;
- } else if (std == V4L2_STD_PAL_M) {
- vp1 = 5;
- ak881x->lines = 480;
- } else if (std == V4L2_STD_PAL_60) {
- vp1 = 7;
- ak881x->lines = 480;
- } else if (std && !(std & ~V4L2_STD_PAL)) {
- vp1 = 0xf;
- ak881x->lines = 576;
- } else if (std && !(std & ~V4L2_STD_NTSC)) {
- vp1 = 0;
- ak881x->lines = 480;
- } else {
- /* No SECAM or PAL_N/Nc supported */
- return -EINVAL;
- }
-
- reg_set(client, AK881X_VIDEO_PROCESS1, vp1, 0xf);
-
- return 0;
-}
-
-static int ak881x_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ak881x *ak881x = to_ak881x(client);
-
- if (enable) {
- u8 dac;
- /* For colour-bar testing set bit 6 of AK881X_VIDEO_PROCESS1 */
- /* Default: composite output */
- if (ak881x->pdata->flags & AK881X_COMPONENT)
- dac = 3;
- else
- dac = 4;
- /* Turn on the DAC(s) */
- reg_write(client, AK881X_DAC_MODE, dac);
- dev_dbg(&client->dev, "chip status 0x%x\n",
- reg_read(client, AK881X_STATUS));
- } else {
- /* ...and clear bit 6 of AK881X_VIDEO_PROCESS1 here */
- reg_write(client, AK881X_DAC_MODE, 0);
- dev_dbg(&client->dev, "chip status 0x%x\n",
- reg_read(client, AK881X_STATUS));
- }
-
- return 0;
-}
-
-static struct v4l2_subdev_core_ops ak881x_subdev_core_ops = {
- .g_chip_ident = ak881x_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = ak881x_g_register,
- .s_register = ak881x_s_register,
-#endif
-};
-
-static struct v4l2_subdev_video_ops ak881x_subdev_video_ops = {
- .s_mbus_fmt = ak881x_s_mbus_fmt,
- .g_mbus_fmt = ak881x_try_g_mbus_fmt,
- .try_mbus_fmt = ak881x_try_g_mbus_fmt,
- .cropcap = ak881x_cropcap,
- .enum_mbus_fmt = ak881x_enum_mbus_fmt,
- .s_std_output = ak881x_s_std_output,
- .s_stream = ak881x_s_stream,
-};
-
-static struct v4l2_subdev_ops ak881x_subdev_ops = {
- .core = &ak881x_subdev_core_ops,
- .video = &ak881x_subdev_video_ops,
-};
-
-static int ak881x_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- struct ak881x *ak881x;
- u8 ifmode, data;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_warn(&adapter->dev,
- "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
- return -EIO;
- }
-
- ak881x = kzalloc(sizeof(struct ak881x), GFP_KERNEL);
- if (!ak881x)
- return -ENOMEM;
-
- v4l2_i2c_subdev_init(&ak881x->subdev, client, &ak881x_subdev_ops);
-
- data = reg_read(client, AK881X_DEVICE_ID);
-
- switch (data) {
- case 0x13:
- ak881x->id = V4L2_IDENT_AK8813;
- break;
- case 0x14:
- ak881x->id = V4L2_IDENT_AK8814;
- break;
- default:
- dev_err(&client->dev,
- "No ak881x chip detected, register read %x\n", data);
- kfree(ak881x);
- return -ENODEV;
- }
-
- ak881x->revision = reg_read(client, AK881X_DEVICE_REVISION);
- ak881x->pdata = client->dev.platform_data;
-
- if (ak881x->pdata) {
- if (ak881x->pdata->flags & AK881X_FIELD)
- ifmode = 4;
- else
- ifmode = 0;
-
- switch (ak881x->pdata->flags & AK881X_IF_MODE_MASK) {
- case AK881X_IF_MODE_BT656:
- ifmode |= 1;
- break;
- case AK881X_IF_MODE_MASTER:
- ifmode |= 2;
- break;
- case AK881X_IF_MODE_SLAVE:
- default:
- break;
- }
-
- dev_dbg(&client->dev, "IF mode %x\n", ifmode);
-
- /*
- * "Line Blanking No." seems to be the same as the number of
- * "black" lines on, e.g., SuperH VOU, whose default value of 20
- * "incidentally" matches ak881x' default
- */
- reg_write(client, AK881X_INTERFACE_MODE, ifmode | (20 << 3));
- }
-
- /* Hardware default: NTSC-M */
- ak881x->lines = 480;
-
- dev_info(&client->dev, "Detected an ak881x chip ID %x, revision %x\n",
- data, ak881x->revision);
-
- return 0;
-}
-
-static int ak881x_remove(struct i2c_client *client)
-{
- struct ak881x *ak881x = to_ak881x(client);
-
- v4l2_device_unregister_subdev(&ak881x->subdev);
- kfree(ak881x);
-
- return 0;
-}
-
-static const struct i2c_device_id ak881x_id[] = {
- { "ak8813", 0 },
- { "ak8814", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ak881x_id);
-
-static struct i2c_driver ak881x_i2c_driver = {
- .driver = {
- .name = "ak881x",
- },
- .probe = ak881x_probe,
- .remove = ak881x_remove,
- .id_table = ak881x_id,
-};
-
-module_i2c_driver(ak881x_i2c_driver);
-
-MODULE_DESCRIPTION("TV-output driver for ak8813/ak8814");
-MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/aptina-pll.c b/drivers/media/video/aptina-pll.c
deleted file mode 100644
index 8153a449846..00000000000
--- a/drivers/media/video/aptina-pll.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Aptina Sensor PLL Configuration
- *
- * Copyright (C) 2012 Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/device.h>
-#include <linux/gcd.h>
-#include <linux/kernel.h>
-#include <linux/lcm.h>
-#include <linux/module.h>
-
-#include "aptina-pll.h"
-
-int aptina_pll_calculate(struct device *dev,
- const struct aptina_pll_limits *limits,
- struct aptina_pll *pll)
-{
- unsigned int mf_min;
- unsigned int mf_max;
- unsigned int p1_min;
- unsigned int p1_max;
- unsigned int p1;
- unsigned int div;
-
- dev_dbg(dev, "PLL: ext clock %u pix clock %u\n",
- pll->ext_clock, pll->pix_clock);
-
- if (pll->ext_clock < limits->ext_clock_min ||
- pll->ext_clock > limits->ext_clock_max) {
- dev_err(dev, "pll: invalid external clock frequency.\n");
- return -EINVAL;
- }
-
- if (pll->pix_clock == 0 || pll->pix_clock > limits->pix_clock_max) {
- dev_err(dev, "pll: invalid pixel clock frequency.\n");
- return -EINVAL;
- }
-
- /* Compute the multiplier M and combined N*P1 divisor. */
- div = gcd(pll->pix_clock, pll->ext_clock);
- pll->m = pll->pix_clock / div;
- div = pll->ext_clock / div;
-
- /* We now have the smallest M and N*P1 values that will result in the
- * desired pixel clock frequency, but they might be out of the valid
- * range. Compute the factor by which we should multiply them given the
- * following constraints:
- *
- * - minimum/maximum multiplier
- * - minimum/maximum multiplier output clock frequency assuming the
- * minimum/maximum N value
- * - minimum/maximum combined N*P1 divisor
- */
- mf_min = DIV_ROUND_UP(limits->m_min, pll->m);
- mf_min = max(mf_min, limits->out_clock_min /
- (pll->ext_clock / limits->n_min * pll->m));
- mf_min = max(mf_min, limits->n_min * limits->p1_min / div);
- mf_max = limits->m_max / pll->m;
- mf_max = min(mf_max, limits->out_clock_max /
- (pll->ext_clock / limits->n_max * pll->m));
- mf_max = min(mf_max, DIV_ROUND_UP(limits->n_max * limits->p1_max, div));
-
- dev_dbg(dev, "pll: mf min %u max %u\n", mf_min, mf_max);
- if (mf_min > mf_max) {
- dev_err(dev, "pll: no valid combined N*P1 divisor.\n");
- return -EINVAL;
- }
-
- /*
- * We're looking for the highest acceptable P1 value for which a
- * multiplier factor MF exists that fulfills the following conditions:
- *
- * 1. p1 is in the [p1_min, p1_max] range given by the limits and is
- * even
- * 2. mf is in the [mf_min, mf_max] range computed above
- * 3. div * mf is a multiple of p1, in order to compute
- * n = div * mf / p1
- * m = pll->m * mf
- * 4. the internal clock frequency, given by ext_clock / n, is in the
- * [int_clock_min, int_clock_max] range given by the limits
- * 5. the output clock frequency, given by ext_clock / n * m, is in the
- * [out_clock_min, out_clock_max] range given by the limits
- *
- * The first naive approach is to iterate over all p1 values acceptable
- * according to (1) and all mf values acceptable according to (2), and
- * stop at the first combination that fulfills (3), (4) and (5). This
- * has a O(n^2) complexity.
- *
- * Instead of iterating over all mf values in the [mf_min, mf_max] range
- * we can compute the mf increment between two acceptable values
- * according to (3) with
- *
- * mf_inc = p1 / gcd(div, p1) (6)
- *
- * and round the minimum up to the nearest multiple of mf_inc. This will
- * restrict the number of mf values to be checked.
- *
- * Furthermore, conditions (4) and (5) only restrict the range of
- * acceptable p1 and mf values by modifying the minimum and maximum
- * limits. (5) can be expressed as
- *
- * ext_clock / (div * mf / p1) * m * mf >= out_clock_min
- * ext_clock / (div * mf / p1) * m * mf <= out_clock_max
- *
- * or
- *
- * p1 >= out_clock_min * div / (ext_clock * m) (7)
- * p1 <= out_clock_max * div / (ext_clock * m)
- *
- * Similarly, (4) can be expressed as
- *
- * mf >= ext_clock * p1 / (int_clock_max * div) (8)
- * mf <= ext_clock * p1 / (int_clock_min * div)
- *
- * We can thus iterate over the restricted p1 range defined by the
- * combination of (1) and (7), and then compute the restricted mf range
- * defined by the combination of (2), (6) and (8). If the resulting mf
- * range is not empty, any value in the mf range is acceptable. We thus
- * select the mf lwoer bound and the corresponding p1 value.
- */
- if (limits->p1_min == 0) {
- dev_err(dev, "pll: P1 minimum value must be >0.\n");
- return -EINVAL;
- }
-
- p1_min = max(limits->p1_min, DIV_ROUND_UP(limits->out_clock_min * div,
- pll->ext_clock * pll->m));
- p1_max = min(limits->p1_max, limits->out_clock_max * div /
- (pll->ext_clock * pll->m));
-
- for (p1 = p1_max & ~1; p1 >= p1_min; p1 -= 2) {
- unsigned int mf_inc = p1 / gcd(div, p1);
- unsigned int mf_high;
- unsigned int mf_low;
-
- mf_low = roundup(max(mf_min, DIV_ROUND_UP(pll->ext_clock * p1,
- limits->int_clock_max * div)), mf_inc);
- mf_high = min(mf_max, pll->ext_clock * p1 /
- (limits->int_clock_min * div));
-
- if (mf_low > mf_high)
- continue;
-
- pll->n = div * mf_low / p1;
- pll->m *= mf_low;
- pll->p1 = p1;
- dev_dbg(dev, "PLL: N %u M %u P1 %u\n", pll->n, pll->m, pll->p1);
- return 0;
- }
-
- dev_err(dev, "pll: no valid N and P1 divisors found.\n");
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(aptina_pll_calculate);
-
-MODULE_DESCRIPTION("Aptina PLL Helpers");
-MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/aptina-pll.h b/drivers/media/video/aptina-pll.h
deleted file mode 100644
index b370e341e75..00000000000
--- a/drivers/media/video/aptina-pll.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Aptina Sensor PLL Configuration
- *
- * Copyright (C) 2012 Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef __APTINA_PLL_H
-#define __APTINA_PLL_H
-
-struct aptina_pll {
- unsigned int ext_clock;
- unsigned int pix_clock;
-
- unsigned int n;
- unsigned int m;
- unsigned int p1;
-};
-
-struct aptina_pll_limits {
- unsigned int ext_clock_min;
- unsigned int ext_clock_max;
- unsigned int int_clock_min;
- unsigned int int_clock_max;
- unsigned int out_clock_min;
- unsigned int out_clock_max;
- unsigned int pix_clock_max;
-
- unsigned int n_min;
- unsigned int n_max;
- unsigned int m_min;
- unsigned int m_max;
- unsigned int p1_min;
- unsigned int p1_max;
-};
-
-struct device;
-
-int aptina_pll_calculate(struct device *dev,
- const struct aptina_pll_limits *limits,
- struct aptina_pll *pll);
-
-#endif /* __APTINA_PLL_H */
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
deleted file mode 100644
index e346d32d08c..00000000000
--- a/drivers/media/video/arv.c
+++ /dev/null
@@ -1,885 +0,0 @@
-/*
- * Colour AR M64278(VGA) driver for Video4Linux
- *
- * Copyright (C) 2003 Takeo Takahashi <takahashi.takeo@renesas.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Some code is taken from AR driver sample program for M3T-M32700UT.
- *
- * AR driver sample (M32R SDK):
- * Copyright (c) 2003 RENESAS TECHNOROGY CORPORATION
- * AND RENESAS SOLUTIONS CORPORATION
- * All Rights Reserved.
- *
- * 2003-09-01: Support w3cam by Takeo Takahashi
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-fh.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-#include <asm/m32r.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/byteorder.h>
-
-#if 0
-#define DEBUG(n, args...) printk(KERN_INFO args)
-#define CHECK_LOST 1
-#else
-#define DEBUG(n, args...)
-#define CHECK_LOST 0
-#endif
-
-/*
- * USE_INT is always 0, interrupt mode is not available
- * on linux due to lack of speed
- */
-#define USE_INT 0 /* Don't modify */
-
-#define VERSION "0.0.5"
-
-#define ar_inl(addr) inl((unsigned long)(addr))
-#define ar_outl(val, addr) outl((unsigned long)(val), (unsigned long)(addr))
-
-extern struct cpuinfo_m32r boot_cpu_data;
-
-/*
- * CCD pixel size
- * Note that M32700UT does not support CIF mode, but QVGA is
- * supported by M32700UT hardware using VGA mode of AR LSI.
- *
- * Supported: VGA (Normal mode, Interlace mode)
- * QVGA (Always Interlace mode of VGA)
- *
- */
-#define AR_WIDTH_VGA 640
-#define AR_HEIGHT_VGA 480
-#define AR_WIDTH_QVGA 320
-#define AR_HEIGHT_QVGA 240
-#define MIN_AR_WIDTH AR_WIDTH_QVGA
-#define MIN_AR_HEIGHT AR_HEIGHT_QVGA
-#define MAX_AR_WIDTH AR_WIDTH_VGA
-#define MAX_AR_HEIGHT AR_HEIGHT_VGA
-
-/* bits & bytes per pixel */
-#define AR_BITS_PER_PIXEL 16
-#define AR_BYTES_PER_PIXEL (AR_BITS_PER_PIXEL / 8)
-
-/* line buffer size */
-#define AR_LINE_BYTES_VGA (AR_WIDTH_VGA * AR_BYTES_PER_PIXEL)
-#define AR_LINE_BYTES_QVGA (AR_WIDTH_QVGA * AR_BYTES_PER_PIXEL)
-#define MAX_AR_LINE_BYTES AR_LINE_BYTES_VGA
-
-/* frame size & type */
-#define AR_FRAME_BYTES_VGA \
- (AR_WIDTH_VGA * AR_HEIGHT_VGA * AR_BYTES_PER_PIXEL)
-#define AR_FRAME_BYTES_QVGA \
- (AR_WIDTH_QVGA * AR_HEIGHT_QVGA * AR_BYTES_PER_PIXEL)
-#define MAX_AR_FRAME_BYTES \
- (MAX_AR_WIDTH * MAX_AR_HEIGHT * AR_BYTES_PER_PIXEL)
-
-#define AR_MAX_FRAME 15
-
-/* capture size */
-#define AR_SIZE_VGA 0
-#define AR_SIZE_QVGA 1
-
-/* capture mode */
-#define AR_MODE_INTERLACE 0
-#define AR_MODE_NORMAL 1
-
-struct ar {
- struct v4l2_device v4l2_dev;
- struct video_device vdev;
- unsigned int start_capture; /* duaring capture in INT. mode. */
-#if USE_INT
- unsigned char *line_buff; /* DMA line buffer */
-#endif
- unsigned char *frame[MAX_AR_HEIGHT]; /* frame data */
- short size; /* capture size */
- short mode; /* capture mode */
- int width, height;
- int frame_bytes, line_bytes;
- wait_queue_head_t wait;
- struct mutex lock;
-};
-
-static struct ar ardev;
-
-static int video_nr = -1; /* video device number (first free) */
-static unsigned char yuv[MAX_AR_FRAME_BYTES];
-
-/* module parameters */
-/* default frequency */
-#define DEFAULT_FREQ 50 /* 50 or 75 (MHz) is available as BCLK */
-static int freq = DEFAULT_FREQ; /* BCLK: available 50 or 70 (MHz) */
-static int vga; /* default mode(0:QVGA mode, other:VGA mode) */
-static int vga_interlace; /* 0 is normal mode for, else interlace mode */
-module_param(freq, int, 0);
-module_param(vga, int, 0);
-module_param(vga_interlace, int, 0);
-
-static void wait_for_vsync(void)
-{
- while (ar_inl(ARVCR0) & ARVCR0_VDS) /* wait for VSYNC */
- cpu_relax();
- while (!(ar_inl(ARVCR0) & ARVCR0_VDS)) /* wait for VSYNC */
- cpu_relax();
-}
-
-static void wait_acknowledge(void)
-{
- int i;
-
- for (i = 0; i < 1000; i++)
- cpu_relax();
- while (ar_inl(PLDI2CSTS) & PLDI2CSTS_NOACK)
- cpu_relax();
-}
-
-/*******************************************************************
- * I2C functions
- *******************************************************************/
-static void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2,
- unsigned long data3)
-{
- int i;
-
- /* Slave Address */
- ar_outl(addr, PLDI2CDATA);
- wait_for_vsync();
-
- /* Start */
- ar_outl(1, PLDI2CCND);
- wait_acknowledge();
-
- /* Transfer data 1 */
- ar_outl(data1, PLDI2CDATA);
- wait_for_vsync();
- ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
- wait_acknowledge();
-
- /* Transfer data 2 */
- ar_outl(data2, PLDI2CDATA);
- wait_for_vsync();
- ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
- wait_acknowledge();
-
- if (n == 3) {
- /* Transfer data 3 */
- ar_outl(data3, PLDI2CDATA);
- wait_for_vsync();
- ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
- wait_acknowledge();
- }
-
- /* Stop */
- for (i = 0; i < 100; i++)
- cpu_relax();
- ar_outl(2, PLDI2CCND);
- ar_outl(2, PLDI2CCND);
-
- while (ar_inl(PLDI2CSTS) & PLDI2CSTS_BB)
- cpu_relax();
-}
-
-
-static void init_iic(void)
-{
- DEBUG(1, "init_iic:\n");
-
- /*
- * ICU Setting (iic)
- */
- /* I2C Setting */
- ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */
- ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */
- ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */
-
- /* I2C CLK */
- /* 50MH-100k */
- if (freq == 75)
- ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */
- else if (freq == 50)
- ar_outl(244, PLDI2CFREQ); /* BCLK = 50MHz */
- else
- ar_outl(244, PLDI2CFREQ); /* default: BCLK = 50MHz */
- ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */
-}
-
-/**************************************************************************
- *
- * Video4Linux Interface functions
- *
- **************************************************************************/
-
-static inline void disable_dma(void)
-{
- ar_outl(0x8000, M32R_DMAEN_PORTL); /* disable DMA0 */
-}
-
-static inline void enable_dma(void)
-{
- ar_outl(0x8080, M32R_DMAEN_PORTL); /* enable DMA0 */
-}
-
-static inline void clear_dma_status(void)
-{
- ar_outl(0x8000, M32R_DMAEDET_PORTL); /* clear status */
-}
-
-static void wait_for_vertical_sync(struct ar *ar, int exp_line)
-{
-#if CHECK_LOST
- int tmout = 10000; /* FIXME */
- int l;
-
- /*
- * check HCOUNT because we cannot check vertical sync.
- */
- for (; tmout >= 0; tmout--) {
- l = ar_inl(ARVHCOUNT);
- if (l == exp_line)
- break;
- }
- if (tmout < 0)
- v4l2_err(&ar->v4l2_dev, "lost %d -> %d\n", exp_line, l);
-#else
- while (ar_inl(ARVHCOUNT) != exp_line)
- cpu_relax();
-#endif
-}
-
-static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
-{
- struct ar *ar = video_drvdata(file);
- long ret = ar->frame_bytes; /* return read bytes */
- unsigned long arvcr1 = 0;
- unsigned long flags;
- unsigned char *p;
- int h, w;
- unsigned char *py, *pu, *pv;
-#if !USE_INT
- int l;
-#endif
-
- DEBUG(1, "ar_read()\n");
-
- if (ar->size == AR_SIZE_QVGA)
- arvcr1 |= ARVCR1_QVGA;
- if (ar->mode == AR_MODE_NORMAL)
- arvcr1 |= ARVCR1_NORMAL;
-
- mutex_lock(&ar->lock);
-
-#if USE_INT
- local_irq_save(flags);
- disable_dma();
- ar_outl(0xa1871300, M32R_DMA0CR0_PORTL);
- ar_outl(0x01000000, M32R_DMA0CR1_PORTL);
-
- /* set AR FIFO address as source(BSEL5) */
- ar_outl(ARDATA32, M32R_DMA0CSA_PORTL);
- ar_outl(ARDATA32, M32R_DMA0RSA_PORTL);
- ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* destination addr. */
- ar_outl(ar->line_buff, M32R_DMA0RDA_PORTL); /* reload address */
- ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL); /* byte count (bytes) */
- ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */
-
- /*
- * Okay, kick AR LSI to invoke an interrupt
- */
- ar->start_capture = 0;
- ar_outl(arvcr1 | ARVCR1_HIEN, ARVCR1);
- local_irq_restore(flags);
- /* .... AR interrupts .... */
- interruptible_sleep_on(&ar->wait);
- if (signal_pending(current)) {
- printk(KERN_ERR "arv: interrupted while get frame data.\n");
- ret = -EINTR;
- goto out_up;
- }
-#else /* ! USE_INT */
- /* polling */
- ar_outl(arvcr1, ARVCR1);
- disable_dma();
- ar_outl(0x8000, M32R_DMAEDET_PORTL);
- ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
- ar_outl(0x01000000, M32R_DMA0CR1_PORTL);
- ar_outl(ARDATA32, M32R_DMA0CSA_PORTL);
- ar_outl(ARDATA32, M32R_DMA0RSA_PORTL);
- ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL);
- ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL);
-
- local_irq_save(flags);
- while (ar_inl(ARVHCOUNT) != 0) /* wait for 0 */
- cpu_relax();
- if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
- for (h = 0; h < ar->height; h++) {
- wait_for_vertical_sync(ar, h);
- if (h < (AR_HEIGHT_VGA/2))
- l = h << 1;
- else
- l = (((h - (AR_HEIGHT_VGA/2)) << 1) + 1);
- ar_outl(virt_to_phys(ar->frame[l]), M32R_DMA0CDA_PORTL);
- enable_dma();
- while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000))
- cpu_relax();
- disable_dma();
- clear_dma_status();
- ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
- }
- } else {
- for (h = 0; h < ar->height; h++) {
- wait_for_vertical_sync(ar, h);
- ar_outl(virt_to_phys(ar->frame[h]), M32R_DMA0CDA_PORTL);
- enable_dma();
- while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000))
- cpu_relax();
- disable_dma();
- clear_dma_status();
- ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
- }
- }
- local_irq_restore(flags);
-#endif /* ! USE_INT */
-
- /*
- * convert YUV422 to YUV422P
- * +--------------------+
- * | Y0,Y1,... |
- * | ..............Yn |
- * +--------------------+
- * | U0,U1,........Un |
- * +--------------------+
- * | V0,V1,........Vn |
- * +--------------------+
- */
- py = yuv;
- pu = py + (ar->frame_bytes / 2);
- pv = pu + (ar->frame_bytes / 4);
- for (h = 0; h < ar->height; h++) {
- p = ar->frame[h];
- for (w = 0; w < ar->line_bytes; w += 4) {
- *py++ = *p++;
- *pu++ = *p++;
- *py++ = *p++;
- *pv++ = *p++;
- }
- }
- if (copy_to_user(buf, yuv, ar->frame_bytes)) {
- v4l2_err(&ar->v4l2_dev, "failed while copy_to_user yuv.\n");
- ret = -EFAULT;
- goto out_up;
- }
- DEBUG(1, "ret = %d\n", ret);
-out_up:
- mutex_unlock(&ar->lock);
- return ret;
-}
-
-static int ar_querycap(struct file *file, void *priv,
- struct v4l2_capability *vcap)
-{
- struct ar *ar = video_drvdata(file);
-
- strlcpy(vcap->driver, ar->vdev.name, sizeof(vcap->driver));
- strlcpy(vcap->card, "Colour AR VGA", sizeof(vcap->card));
- strlcpy(vcap->bus_info, "Platform", sizeof(vcap->bus_info));
- vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
- vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
- return 0;
-}
-
-static int ar_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
-{
- if (vin->index > 0)
- return -EINVAL;
- strlcpy(vin->name, "Camera", sizeof(vin->name));
- vin->type = V4L2_INPUT_TYPE_CAMERA;
- vin->audioset = 0;
- vin->tuner = 0;
- vin->std = V4L2_STD_ALL;
- vin->status = 0;
- return 0;
-}
-
-static int ar_g_input(struct file *file, void *fh, unsigned int *inp)
-{
- *inp = 0;
- return 0;
-}
-
-static int ar_s_input(struct file *file, void *fh, unsigned int inp)
-{
- return inp ? -EINVAL : 0;
-}
-
-static int ar_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ar *ar = video_drvdata(file);
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
-
- pix->width = ar->width;
- pix->height = ar->height;
- pix->pixelformat = V4L2_PIX_FMT_YUV422P;
- pix->field = (ar->mode == AR_MODE_NORMAL) ? V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED;
- pix->bytesperline = ar->width;
- pix->sizeimage = 2 * ar->width * ar->height;
- /* Just a guess */
- pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
- return 0;
-}
-
-static int ar_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ar *ar = video_drvdata(file);
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
-
- if (pix->height <= AR_HEIGHT_QVGA || pix->width <= AR_WIDTH_QVGA) {
- pix->height = AR_HEIGHT_QVGA;
- pix->width = AR_WIDTH_QVGA;
- pix->field = V4L2_FIELD_INTERLACED;
- } else {
- pix->height = AR_HEIGHT_VGA;
- pix->width = AR_WIDTH_VGA;
- pix->field = vga_interlace ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
- }
- pix->pixelformat = V4L2_PIX_FMT_YUV422P;
- pix->bytesperline = ar->width;
- pix->sizeimage = 2 * ar->width * ar->height;
- /* Just a guess */
- pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
- return 0;
-}
-
-static int ar_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ar *ar = video_drvdata(file);
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
- int ret = ar_try_fmt_vid_cap(file, fh, fmt);
-
- if (ret)
- return ret;
- mutex_lock(&ar->lock);
- ar->width = pix->width;
- ar->height = pix->height;
- if (ar->width == AR_WIDTH_VGA) {
- ar->size = AR_SIZE_VGA;
- ar->frame_bytes = AR_FRAME_BYTES_VGA;
- ar->line_bytes = AR_LINE_BYTES_VGA;
- if (vga_interlace)
- ar->mode = AR_MODE_INTERLACE;
- else
- ar->mode = AR_MODE_NORMAL;
- } else {
- ar->size = AR_SIZE_QVGA;
- ar->frame_bytes = AR_FRAME_BYTES_QVGA;
- ar->line_bytes = AR_LINE_BYTES_QVGA;
- ar->mode = AR_MODE_INTERLACE;
- }
- /* Ok we figured out what to use from our wide choice */
- mutex_unlock(&ar->lock);
- return 0;
-}
-
-static int ar_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
-{
- static struct v4l2_fmtdesc formats[] = {
- { 0, 0, 0,
- "YUV 4:2:2 Planar", V4L2_PIX_FMT_YUV422P,
- { 0, 0, 0, 0 }
- },
- };
- enum v4l2_buf_type type = fmt->type;
-
- if (fmt->index > 0)
- return -EINVAL;
-
- *fmt = formats[fmt->index];
- fmt->type = type;
- return 0;
-}
-
-#if USE_INT
-/*
- * Interrupt handler
- */
-static void ar_interrupt(int irq, void *dev)
-{
- struct ar *ar = dev;
- unsigned int line_count;
- unsigned int line_number;
- unsigned int arvcr1;
-
- line_count = ar_inl(ARVHCOUNT); /* line number */
- if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
- /* operations for interlace mode */
- if (line_count < (AR_HEIGHT_VGA / 2)) /* even line */
- line_number = (line_count << 1);
- else /* odd line */
- line_number =
- (((line_count - (AR_HEIGHT_VGA / 2)) << 1) + 1);
- } else {
- line_number = line_count;
- }
-
- if (line_number == 0) {
- /*
- * It is an interrupt for line 0.
- * we have to start capture.
- */
- disable_dma();
-#if 0
- ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* needless? */
-#endif
- memcpy(ar->frame[0], ar->line_buff, ar->line_bytes);
-#if 0
- ar_outl(0xa1861300, M32R_DMA0CR0_PORTL);
-#endif
- enable_dma();
- ar->start_capture = 1; /* during capture */
- return;
- }
-
- if (ar->start_capture == 1 && line_number <= (ar->height - 1)) {
- disable_dma();
- memcpy(ar->frame[line_number], ar->line_buff, ar->line_bytes);
-
- /*
- * if captured all line of a frame, disable AR interrupt
- * and wake a process up.
- */
- if (line_number == (ar->height - 1)) { /* end of line */
-
- ar->start_capture = 0;
-
- /* disable AR interrupt request */
- arvcr1 = ar_inl(ARVCR1);
- arvcr1 &= ~ARVCR1_HIEN; /* clear int. flag */
- ar_outl(arvcr1, ARVCR1); /* disable */
- wake_up_interruptible(&ar->wait);
- } else {
-#if 0
- ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL);
- ar_outl(0xa1861300, M32R_DMA0CR0_PORTL);
-#endif
- enable_dma();
- }
- }
-}
-#endif
-
-/*
- * ar_initialize()
- * ar_initialize() is called by video_register_device() and
- * initializes AR LSI and peripherals.
- *
- * -1 is returned in all failures.
- * 0 is returned in success.
- *
- */
-static int ar_initialize(struct ar *ar)
-{
- unsigned long cr = 0;
- int i, found = 0;
-
- DEBUG(1, "ar_initialize:\n");
-
- /*
- * initialize AR LSI
- */
- ar_outl(0, ARVCR0); /* assert reset of AR LSI */
- for (i = 0; i < 0x18; i++) /* wait for over 10 cycles @ 27MHz */
- cpu_relax();
- ar_outl(ARVCR0_RST, ARVCR0); /* negate reset of AR LSI (enable) */
- for (i = 0; i < 0x40d; i++) /* wait for over 420 cycles @ 27MHz */
- cpu_relax();
-
- /* AR uses INT3 of CPU as interrupt pin. */
- ar_outl(ARINTSEL_INT3, ARINTSEL);
-
- if (ar->size == AR_SIZE_QVGA)
- cr |= ARVCR1_QVGA;
- if (ar->mode == AR_MODE_NORMAL)
- cr |= ARVCR1_NORMAL;
- ar_outl(cr, ARVCR1);
-
- /*
- * Initialize IIC so that CPU can communicate with AR LSI,
- * and send boot commands to AR LSI.
- */
- init_iic();
-
- for (i = 0; i < 0x100000; i++) { /* > 0xa1d10, 56ms */
- if ((ar_inl(ARVCR0) & ARVCR0_VDS)) { /* VSYNC */
- found = 1;
- break;
- }
- }
-
- if (found == 0)
- return -ENODEV;
-
- v4l2_info(&ar->v4l2_dev, "Initializing ");
-
- iic(2, 0x78, 0x11, 0x01, 0x00); /* start */
- iic(3, 0x78, 0x12, 0x00, 0x06);
- iic(3, 0x78, 0x12, 0x12, 0x30);
- iic(3, 0x78, 0x12, 0x15, 0x58);
- iic(3, 0x78, 0x12, 0x17, 0x30);
- printk(KERN_CONT ".");
- iic(3, 0x78, 0x12, 0x1a, 0x97);
- iic(3, 0x78, 0x12, 0x1b, 0xff);
- iic(3, 0x78, 0x12, 0x1c, 0xff);
- iic(3, 0x78, 0x12, 0x26, 0x10);
- iic(3, 0x78, 0x12, 0x27, 0x00);
- printk(KERN_CONT ".");
- iic(2, 0x78, 0x34, 0x02, 0x00);
- iic(2, 0x78, 0x7a, 0x10, 0x00);
- iic(2, 0x78, 0x80, 0x39, 0x00);
- iic(2, 0x78, 0x81, 0xe6, 0x00);
- iic(2, 0x78, 0x8d, 0x00, 0x00);
- printk(KERN_CONT ".");
- iic(2, 0x78, 0x8e, 0x0c, 0x00);
- iic(2, 0x78, 0x8f, 0x00, 0x00);
-#if 0
- iic(2, 0x78, 0x90, 0x00, 0x00); /* AWB on=1 off=0 */
-#endif
- iic(2, 0x78, 0x93, 0x01, 0x00);
- iic(2, 0x78, 0x94, 0xcd, 0x00);
- iic(2, 0x78, 0x95, 0x00, 0x00);
- printk(KERN_CONT ".");
- iic(2, 0x78, 0x96, 0xa0, 0x00);
- iic(2, 0x78, 0x97, 0x00, 0x00);
- iic(2, 0x78, 0x98, 0x60, 0x00);
- iic(2, 0x78, 0x99, 0x01, 0x00);
- iic(2, 0x78, 0x9a, 0x19, 0x00);
- printk(KERN_CONT ".");
- iic(2, 0x78, 0x9b, 0x02, 0x00);
- iic(2, 0x78, 0x9c, 0xe8, 0x00);
- iic(2, 0x78, 0x9d, 0x02, 0x00);
- iic(2, 0x78, 0x9e, 0x2e, 0x00);
- iic(2, 0x78, 0xb8, 0x78, 0x00);
- iic(2, 0x78, 0xba, 0x05, 0x00);
-#if 0
- iic(2, 0x78, 0x83, 0x8c, 0x00); /* brightness */
-#endif
- printk(KERN_CONT ".");
-
- /* color correction */
- iic(3, 0x78, 0x49, 0x00, 0x95); /* a */
- iic(3, 0x78, 0x49, 0x01, 0x96); /* b */
- iic(3, 0x78, 0x49, 0x03, 0x85); /* c */
- iic(3, 0x78, 0x49, 0x04, 0x97); /* d */
- iic(3, 0x78, 0x49, 0x02, 0x7e); /* e(Lo) */
- iic(3, 0x78, 0x49, 0x05, 0xa4); /* f(Lo) */
- iic(3, 0x78, 0x49, 0x06, 0x04); /* e(Hi) */
- iic(3, 0x78, 0x49, 0x07, 0x04); /* e(Hi) */
- iic(2, 0x78, 0x48, 0x01, 0x00); /* on=1 off=0 */
-
- printk(KERN_CONT ".");
- iic(2, 0x78, 0x11, 0x00, 0x00); /* end */
- printk(KERN_CONT " done\n");
- return 0;
-}
-
-
-/****************************************************************************
- *
- * Video4Linux Module functions
- *
- ****************************************************************************/
-
-static const struct v4l2_file_operations ar_fops = {
- .owner = THIS_MODULE,
- .open = v4l2_fh_open,
- .release = v4l2_fh_release,
- .read = ar_read,
- .unlocked_ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops ar_ioctl_ops = {
- .vidioc_querycap = ar_querycap,
- .vidioc_g_input = ar_g_input,
- .vidioc_s_input = ar_s_input,
- .vidioc_enum_input = ar_enum_input,
- .vidioc_enum_fmt_vid_cap = ar_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = ar_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = ar_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = ar_try_fmt_vid_cap,
-};
-
-#define ALIGN4(x) ((((int)(x)) & 0x3) == 0)
-
-static int __init ar_init(void)
-{
- struct ar *ar;
- struct v4l2_device *v4l2_dev;
- int ret;
- int i;
-
- ar = &ardev;
- v4l2_dev = &ar->v4l2_dev;
- strlcpy(v4l2_dev->name, "arv", sizeof(v4l2_dev->name));
- v4l2_info(v4l2_dev, "Colour AR VGA driver %s\n", VERSION);
-
- ret = v4l2_device_register(NULL, v4l2_dev);
- if (ret < 0) {
- v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
- return ret;
- }
- ret = -EIO;
-
-#if USE_INT
- /* allocate a DMA buffer for 1 line. */
- ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA);
- if (ar->line_buff == NULL || !ALIGN4(ar->line_buff)) {
- v4l2_err(v4l2_dev, "buffer allocation failed for DMA.\n");
- ret = -ENOMEM;
- goto out_end;
- }
-#endif
- /* allocate buffers for a frame */
- for (i = 0; i < MAX_AR_HEIGHT; i++) {
- ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL);
- if (ar->frame[i] == NULL || !ALIGN4(ar->frame[i])) {
- v4l2_err(v4l2_dev, "buffer allocation failed for frame.\n");
- ret = -ENOMEM;
- goto out_line_buff;
- }
- }
-
- strlcpy(ar->vdev.name, "Colour AR VGA", sizeof(ar->vdev.name));
- ar->vdev.v4l2_dev = v4l2_dev;
- ar->vdev.fops = &ar_fops;
- ar->vdev.ioctl_ops = &ar_ioctl_ops;
- ar->vdev.release = video_device_release_empty;
- set_bit(V4L2_FL_USE_FH_PRIO, &ar->vdev.flags);
- video_set_drvdata(&ar->vdev, ar);
-
- if (vga) {
- ar->width = AR_WIDTH_VGA;
- ar->height = AR_HEIGHT_VGA;
- ar->size = AR_SIZE_VGA;
- ar->frame_bytes = AR_FRAME_BYTES_VGA;
- ar->line_bytes = AR_LINE_BYTES_VGA;
- if (vga_interlace)
- ar->mode = AR_MODE_INTERLACE;
- else
- ar->mode = AR_MODE_NORMAL;
- } else {
- ar->width = AR_WIDTH_QVGA;
- ar->height = AR_HEIGHT_QVGA;
- ar->size = AR_SIZE_QVGA;
- ar->frame_bytes = AR_FRAME_BYTES_QVGA;
- ar->line_bytes = AR_LINE_BYTES_QVGA;
- ar->mode = AR_MODE_INTERLACE;
- }
- mutex_init(&ar->lock);
- init_waitqueue_head(&ar->wait);
-
-#if USE_INT
- if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) {
- v4l2_err("request_irq(%d) failed.\n", M32R_IRQ_INT3);
- ret = -EIO;
- goto out_irq;
- }
-#endif
-
- if (ar_initialize(ar) != 0) {
- v4l2_err(v4l2_dev, "M64278 not found.\n");
- ret = -ENODEV;
- goto out_dev;
- }
-
- /*
- * ok, we can initialize h/w according to parameters,
- * so register video device as a frame grabber type.
- * device is named "video[0-64]".
- * video_register_device() initializes h/w using ar_initialize().
- */
- if (video_register_device(&ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) {
- /* return -1, -ENFILE(full) or others */
- v4l2_err(v4l2_dev, "register video (Colour AR) failed.\n");
- ret = -ENODEV;
- goto out_dev;
- }
-
- v4l2_info(v4l2_dev, "%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
- video_device_node_name(&ar->vdev), M32R_IRQ_INT3, freq);
-
- return 0;
-
-out_dev:
-#if USE_INT
- free_irq(M32R_IRQ_INT3, ar);
-
-out_irq:
-#endif
- for (i = 0; i < MAX_AR_HEIGHT; i++)
- kfree(ar->frame[i]);
-
-out_line_buff:
-#if USE_INT
- kfree(ar->line_buff);
-
-out_end:
-#endif
- v4l2_device_unregister(&ar->v4l2_dev);
- return ret;
-}
-
-
-static int __init ar_init_module(void)
-{
- freq = (boot_cpu_data.bus_clock / 1000000);
- printk(KERN_INFO "arv: Bus clock %d\n", freq);
- if (freq != 50 && freq != 75)
- freq = DEFAULT_FREQ;
- return ar_init();
-}
-
-static void __exit ar_cleanup_module(void)
-{
- struct ar *ar;
- int i;
-
- ar = &ardev;
- video_unregister_device(&ar->vdev);
-#if USE_INT
- free_irq(M32R_IRQ_INT3, ar);
-#endif
- for (i = 0; i < MAX_AR_HEIGHT; i++)
- kfree(ar->frame[i]);
-#if USE_INT
- kfree(ar->line_buff);
-#endif
- v4l2_device_unregister(&ar->v4l2_dev);
-}
-
-module_init(ar_init_module);
-module_exit(ar_cleanup_module);
-
-MODULE_AUTHOR("Takeo Takahashi <takahashi.takeo@renesas.com>");
-MODULE_DESCRIPTION("Colour AR M64278(VGA) for Video4Linux");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(VERSION);
diff --git a/drivers/media/video/as3645a.c b/drivers/media/video/as3645a.c
deleted file mode 100644
index c4b03572dce..00000000000
--- a/drivers/media/video/as3645a.c
+++ /dev/null
@@ -1,888 +0,0 @@
-/*
- * drivers/media/video/as3645a.c - AS3645A and LM3555 flash controllers driver
- *
- * Copyright (C) 2008-2011 Nokia Corporation
- * Copyright (c) 2011, Intel Corporation.
- *
- * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- * TODO:
- * - Check hardware FSTROBE control when sensor driver add support for this
- *
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-
-#include <media/as3645a.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-
-#define AS_TIMER_MS_TO_CODE(t) (((t) - 100) / 50)
-#define AS_TIMER_CODE_TO_MS(c) (50 * (c) + 100)
-
-/* Register definitions */
-
-/* Read-only Design info register: Reset state: xxxx 0001 */
-#define AS_DESIGN_INFO_REG 0x00
-#define AS_DESIGN_INFO_FACTORY(x) (((x) >> 4))
-#define AS_DESIGN_INFO_MODEL(x) ((x) & 0x0f)
-
-/* Read-only Version control register: Reset state: 0000 0000
- * for first engineering samples
- */
-#define AS_VERSION_CONTROL_REG 0x01
-#define AS_VERSION_CONTROL_RFU(x) (((x) >> 4))
-#define AS_VERSION_CONTROL_VERSION(x) ((x) & 0x0f)
-
-/* Read / Write (Indicator and timer register): Reset state: 0000 1111 */
-#define AS_INDICATOR_AND_TIMER_REG 0x02
-#define AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT 0
-#define AS_INDICATOR_AND_TIMER_VREF_SHIFT 4
-#define AS_INDICATOR_AND_TIMER_INDICATOR_SHIFT 6
-
-/* Read / Write (Current set register): Reset state: 0110 1001 */
-#define AS_CURRENT_SET_REG 0x03
-#define AS_CURRENT_ASSIST_LIGHT_SHIFT 0
-#define AS_CURRENT_LED_DET_ON (1 << 3)
-#define AS_CURRENT_FLASH_CURRENT_SHIFT 4
-
-/* Read / Write (Control register): Reset state: 1011 0100 */
-#define AS_CONTROL_REG 0x04
-#define AS_CONTROL_MODE_SETTING_SHIFT 0
-#define AS_CONTROL_STROBE_ON (1 << 2)
-#define AS_CONTROL_OUT_ON (1 << 3)
-#define AS_CONTROL_EXT_TORCH_ON (1 << 4)
-#define AS_CONTROL_STROBE_TYPE_EDGE (0 << 5)
-#define AS_CONTROL_STROBE_TYPE_LEVEL (1 << 5)
-#define AS_CONTROL_COIL_PEAK_SHIFT 6
-
-/* Read only (D3 is read / write) (Fault and info): Reset state: 0000 x000 */
-#define AS_FAULT_INFO_REG 0x05
-#define AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT (1 << 1)
-#define AS_FAULT_INFO_INDICATOR_LED (1 << 2)
-#define AS_FAULT_INFO_LED_AMOUNT (1 << 3)
-#define AS_FAULT_INFO_TIMEOUT (1 << 4)
-#define AS_FAULT_INFO_OVER_TEMPERATURE (1 << 5)
-#define AS_FAULT_INFO_SHORT_CIRCUIT (1 << 6)
-#define AS_FAULT_INFO_OVER_VOLTAGE (1 << 7)
-
-/* Boost register */
-#define AS_BOOST_REG 0x0d
-#define AS_BOOST_CURRENT_DISABLE (0 << 0)
-#define AS_BOOST_CURRENT_ENABLE (1 << 0)
-
-/* Password register is used to unlock boost register writing */
-#define AS_PASSWORD_REG 0x0f
-#define AS_PASSWORD_UNLOCK_VALUE 0x55
-
-enum as_mode {
- AS_MODE_EXT_TORCH = 0 << AS_CONTROL_MODE_SETTING_SHIFT,
- AS_MODE_INDICATOR = 1 << AS_CONTROL_MODE_SETTING_SHIFT,
- AS_MODE_ASSIST = 2 << AS_CONTROL_MODE_SETTING_SHIFT,
- AS_MODE_FLASH = 3 << AS_CONTROL_MODE_SETTING_SHIFT,
-};
-
-/*
- * struct as3645a
- *
- * @subdev: V4L2 subdev
- * @pdata: Flash platform data
- * @power_lock: Protects power_count
- * @power_count: Power reference count
- * @led_mode: V4L2 flash LED mode
- * @timeout: Flash timeout in microseconds
- * @flash_current: Flash current (0=200mA ... 15=500mA). Maximum
- * values are 400mA for two LEDs and 500mA for one LED.
- * @assist_current: Torch/Assist light current (0=20mA, 1=40mA ... 7=160mA)
- * @indicator_current: Indicator LED current (0=0mA, 1=2.5mA ... 4=10mA)
- * @strobe_source: Flash strobe source (software or external)
- */
-struct as3645a {
- struct v4l2_subdev subdev;
- const struct as3645a_platform_data *pdata;
-
- struct mutex power_lock;
- int power_count;
-
- /* Controls */
- struct v4l2_ctrl_handler ctrls;
-
- enum v4l2_flash_led_mode led_mode;
- unsigned int timeout;
- u8 flash_current;
- u8 assist_current;
- u8 indicator_current;
- enum v4l2_flash_strobe_source strobe_source;
-};
-
-#define to_as3645a(sd) container_of(sd, struct as3645a, subdev)
-
-/* Return negative errno else zero on success */
-static int as3645a_write(struct as3645a *flash, u8 addr, u8 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- int rval;
-
- rval = i2c_smbus_write_byte_data(client, addr, val);
-
- dev_dbg(&client->dev, "Write Addr:%02X Val:%02X %s\n", addr, val,
- rval < 0 ? "fail" : "ok");
-
- return rval;
-}
-
-/* Return negative errno else a data byte received from the device. */
-static int as3645a_read(struct as3645a *flash, u8 addr)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- int rval;
-
- rval = i2c_smbus_read_byte_data(client, addr);
-
- dev_dbg(&client->dev, "Read Addr:%02X Val:%02X %s\n", addr, rval,
- rval < 0 ? "fail" : "ok");
-
- return rval;
-}
-
-/* -----------------------------------------------------------------------------
- * Hardware configuration and trigger
- */
-
-/*
- * as3645a_set_config - Set flash configuration registers
- * @flash: The flash
- *
- * Configure the hardware with flash, assist and indicator currents, as well as
- * flash timeout.
- *
- * Return 0 on success, or a negative error code if an I2C communication error
- * occurred.
- */
-static int as3645a_set_config(struct as3645a *flash)
-{
- int ret;
- u8 val;
-
- val = (flash->flash_current << AS_CURRENT_FLASH_CURRENT_SHIFT)
- | (flash->assist_current << AS_CURRENT_ASSIST_LIGHT_SHIFT)
- | AS_CURRENT_LED_DET_ON;
-
- ret = as3645a_write(flash, AS_CURRENT_SET_REG, val);
- if (ret < 0)
- return ret;
-
- val = AS_TIMER_MS_TO_CODE(flash->timeout / 1000)
- << AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT;
-
- val |= (flash->pdata->vref << AS_INDICATOR_AND_TIMER_VREF_SHIFT)
- | ((flash->indicator_current ? flash->indicator_current - 1 : 0)
- << AS_INDICATOR_AND_TIMER_INDICATOR_SHIFT);
-
- return as3645a_write(flash, AS_INDICATOR_AND_TIMER_REG, val);
-}
-
-/*
- * as3645a_set_control - Set flash control register
- * @flash: The flash
- * @mode: Desired output mode
- * @on: Desired output state
- *
- * Configure the hardware with output mode and state.
- *
- * Return 0 on success, or a negative error code if an I2C communication error
- * occurred.
- */
-static int
-as3645a_set_control(struct as3645a *flash, enum as_mode mode, bool on)
-{
- u8 reg;
-
- /* Configure output parameters and operation mode. */
- reg = (flash->pdata->peak << AS_CONTROL_COIL_PEAK_SHIFT)
- | (on ? AS_CONTROL_OUT_ON : 0)
- | mode;
-
- if (flash->led_mode == V4L2_FLASH_LED_MODE_FLASH &&
- flash->strobe_source == V4L2_FLASH_STROBE_SOURCE_EXTERNAL) {
- reg |= AS_CONTROL_STROBE_TYPE_LEVEL
- | AS_CONTROL_STROBE_ON;
- }
-
- return as3645a_write(flash, AS_CONTROL_REG, reg);
-}
-
-/*
- * as3645a_set_output - Configure output and operation mode
- * @flash: Flash controller
- * @strobe: Strobe the flash (only valid in flash mode)
- *
- * Turn the LEDs output on/off and set the operation mode based on the current
- * parameters.
- *
- * The AS3645A can't control the indicator LED independently of the flash/torch
- * LED. If the flash controller is in V4L2_FLASH_LED_MODE_NONE mode, set the
- * chip to indicator mode. Otherwise set it to assist light (torch) or flash
- * mode.
- *
- * In indicator and assist modes, turn the output on/off based on the indicator
- * and torch currents. In software strobe flash mode, turn the output on/off
- * based on the strobe parameter.
- */
-static int as3645a_set_output(struct as3645a *flash, bool strobe)
-{
- enum as_mode mode;
- bool on;
-
- switch (flash->led_mode) {
- case V4L2_FLASH_LED_MODE_NONE:
- on = flash->indicator_current != 0;
- mode = AS_MODE_INDICATOR;
- break;
- case V4L2_FLASH_LED_MODE_TORCH:
- on = true;
- mode = AS_MODE_ASSIST;
- break;
- case V4L2_FLASH_LED_MODE_FLASH:
- on = strobe;
- mode = AS_MODE_FLASH;
- break;
- default:
- BUG();
- }
-
- /* Configure output parameters and operation mode. */
- return as3645a_set_control(flash, mode, on);
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 controls
- */
-
-static int as3645a_is_active(struct as3645a *flash)
-{
- int ret;
-
- ret = as3645a_read(flash, AS_CONTROL_REG);
- return ret < 0 ? ret : !!(ret & AS_CONTROL_OUT_ON);
-}
-
-static int as3645a_read_fault(struct as3645a *flash)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- int rval;
-
- /* NOTE: reading register clear fault status */
- rval = as3645a_read(flash, AS_FAULT_INFO_REG);
- if (rval < 0)
- return rval;
-
- if (rval & AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT)
- dev_dbg(&client->dev, "Inductor Peak limit fault\n");
-
- if (rval & AS_FAULT_INFO_INDICATOR_LED)
- dev_dbg(&client->dev, "Indicator LED fault: "
- "Short circuit or open loop\n");
-
- dev_dbg(&client->dev, "%u connected LEDs\n",
- rval & AS_FAULT_INFO_LED_AMOUNT ? 2 : 1);
-
- if (rval & AS_FAULT_INFO_TIMEOUT)
- dev_dbg(&client->dev, "Timeout fault\n");
-
- if (rval & AS_FAULT_INFO_OVER_TEMPERATURE)
- dev_dbg(&client->dev, "Over temperature fault\n");
-
- if (rval & AS_FAULT_INFO_SHORT_CIRCUIT)
- dev_dbg(&client->dev, "Short circuit fault\n");
-
- if (rval & AS_FAULT_INFO_OVER_VOLTAGE)
- dev_dbg(&client->dev, "Over voltage fault: "
- "Indicates missing capacitor or open connection\n");
-
- return rval;
-}
-
-static int as3645a_get_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct as3645a *flash =
- container_of(ctrl->handler, struct as3645a, ctrls);
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- int value;
-
- switch (ctrl->id) {
- case V4L2_CID_FLASH_FAULT:
- value = as3645a_read_fault(flash);
- if (value < 0)
- return value;
-
- ctrl->cur.val = 0;
- if (value & AS_FAULT_INFO_SHORT_CIRCUIT)
- ctrl->cur.val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
- if (value & AS_FAULT_INFO_OVER_TEMPERATURE)
- ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE;
- if (value & AS_FAULT_INFO_TIMEOUT)
- ctrl->cur.val |= V4L2_FLASH_FAULT_TIMEOUT;
- if (value & AS_FAULT_INFO_OVER_VOLTAGE)
- ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_VOLTAGE;
- if (value & AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT)
- ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_CURRENT;
- if (value & AS_FAULT_INFO_INDICATOR_LED)
- ctrl->cur.val |= V4L2_FLASH_FAULT_INDICATOR;
- break;
-
- case V4L2_CID_FLASH_STROBE_STATUS:
- if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) {
- ctrl->cur.val = 0;
- break;
- }
-
- value = as3645a_is_active(flash);
- if (value < 0)
- return value;
-
- ctrl->cur.val = value;
- break;
- }
-
- dev_dbg(&client->dev, "G_CTRL %08x:%d\n", ctrl->id, ctrl->cur.val);
-
- return 0;
-}
-
-static int as3645a_set_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct as3645a *flash =
- container_of(ctrl->handler, struct as3645a, ctrls);
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- int ret;
-
- dev_dbg(&client->dev, "S_CTRL %08x:%d\n", ctrl->id, ctrl->val);
-
- /* If a control that doesn't apply to the current mode is modified,
- * we store the value and return immediately. The setting will be
- * applied when the LED mode is changed. Otherwise we apply the setting
- * immediately.
- */
-
- switch (ctrl->id) {
- case V4L2_CID_FLASH_LED_MODE:
- if (flash->indicator_current)
- return -EBUSY;
-
- ret = as3645a_set_config(flash);
- if (ret < 0)
- return ret;
-
- flash->led_mode = ctrl->val;
- return as3645a_set_output(flash, false);
-
- case V4L2_CID_FLASH_STROBE_SOURCE:
- flash->strobe_source = ctrl->val;
-
- /* Applies to flash mode only. */
- if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
- break;
-
- return as3645a_set_output(flash, false);
-
- case V4L2_CID_FLASH_STROBE:
- if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
- return -EBUSY;
-
- return as3645a_set_output(flash, true);
-
- case V4L2_CID_FLASH_STROBE_STOP:
- if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
- return -EBUSY;
-
- return as3645a_set_output(flash, false);
-
- case V4L2_CID_FLASH_TIMEOUT:
- flash->timeout = ctrl->val;
-
- /* Applies to flash mode only. */
- if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
- break;
-
- return as3645a_set_config(flash);
-
- case V4L2_CID_FLASH_INTENSITY:
- flash->flash_current = (ctrl->val - AS3645A_FLASH_INTENSITY_MIN)
- / AS3645A_FLASH_INTENSITY_STEP;
-
- /* Applies to flash mode only. */
- if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
- break;
-
- return as3645a_set_config(flash);
-
- case V4L2_CID_FLASH_TORCH_INTENSITY:
- flash->assist_current =
- (ctrl->val - AS3645A_TORCH_INTENSITY_MIN)
- / AS3645A_TORCH_INTENSITY_STEP;
-
- /* Applies to torch mode only. */
- if (flash->led_mode != V4L2_FLASH_LED_MODE_TORCH)
- break;
-
- return as3645a_set_config(flash);
-
- case V4L2_CID_FLASH_INDICATOR_INTENSITY:
- if (flash->led_mode != V4L2_FLASH_LED_MODE_NONE)
- return -EBUSY;
-
- flash->indicator_current =
- (ctrl->val - AS3645A_INDICATOR_INTENSITY_MIN)
- / AS3645A_INDICATOR_INTENSITY_STEP;
-
- ret = as3645a_set_config(flash);
- if (ret < 0)
- return ret;
-
- if ((ctrl->val == 0) == (ctrl->cur.val == 0))
- break;
-
- return as3645a_set_output(flash, false);
- }
-
- return 0;
-}
-
-static const struct v4l2_ctrl_ops as3645a_ctrl_ops = {
- .g_volatile_ctrl = as3645a_get_ctrl,
- .s_ctrl = as3645a_set_ctrl,
-};
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev core operations
- */
-
-/* Put device into know state. */
-static int as3645a_setup(struct as3645a *flash)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- int ret;
-
- /* clear errors */
- ret = as3645a_read(flash, AS_FAULT_INFO_REG);
- if (ret < 0)
- return ret;
-
- dev_dbg(&client->dev, "Fault info: %02x\n", ret);
-
- ret = as3645a_set_config(flash);
- if (ret < 0)
- return ret;
-
- ret = as3645a_set_output(flash, false);
- if (ret < 0)
- return ret;
-
- /* read status */
- ret = as3645a_read_fault(flash);
- if (ret < 0)
- return ret;
-
- dev_dbg(&client->dev, "AS_INDICATOR_AND_TIMER_REG: %02x\n",
- as3645a_read(flash, AS_INDICATOR_AND_TIMER_REG));
- dev_dbg(&client->dev, "AS_CURRENT_SET_REG: %02x\n",
- as3645a_read(flash, AS_CURRENT_SET_REG));
- dev_dbg(&client->dev, "AS_CONTROL_REG: %02x\n",
- as3645a_read(flash, AS_CONTROL_REG));
-
- return ret & ~AS_FAULT_INFO_LED_AMOUNT ? -EIO : 0;
-}
-
-static int __as3645a_set_power(struct as3645a *flash, int on)
-{
- int ret;
-
- if (!on)
- as3645a_set_control(flash, AS_MODE_EXT_TORCH, false);
-
- if (flash->pdata->set_power) {
- ret = flash->pdata->set_power(&flash->subdev, on);
- if (ret < 0)
- return ret;
- }
-
- if (!on)
- return 0;
-
- ret = as3645a_setup(flash);
- if (ret < 0) {
- if (flash->pdata->set_power)
- flash->pdata->set_power(&flash->subdev, 0);
- }
-
- return ret;
-}
-
-static int as3645a_set_power(struct v4l2_subdev *sd, int on)
-{
- struct as3645a *flash = to_as3645a(sd);
- int ret = 0;
-
- mutex_lock(&flash->power_lock);
-
- if (flash->power_count == !on) {
- ret = __as3645a_set_power(flash, !!on);
- if (ret < 0)
- goto done;
- }
-
- flash->power_count += on ? 1 : -1;
- WARN_ON(flash->power_count < 0);
-
-done:
- mutex_unlock(&flash->power_lock);
- return ret;
-}
-
-static int as3645a_registered(struct v4l2_subdev *sd)
-{
- struct as3645a *flash = to_as3645a(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int rval, man, model, rfu, version;
- const char *vendor;
-
- /* Power up the flash driver and read manufacturer ID, model ID, RFU
- * and version.
- */
- rval = as3645a_set_power(&flash->subdev, 1);
- if (rval < 0)
- return rval;
-
- rval = as3645a_read(flash, AS_DESIGN_INFO_REG);
- if (rval < 0)
- goto power_off;
-
- man = AS_DESIGN_INFO_FACTORY(rval);
- model = AS_DESIGN_INFO_MODEL(rval);
-
- rval = as3645a_read(flash, AS_VERSION_CONTROL_REG);
- if (rval < 0)
- goto power_off;
-
- rfu = AS_VERSION_CONTROL_RFU(rval);
- version = AS_VERSION_CONTROL_VERSION(rval);
-
- /* Verify the chip model and version. */
- if (model != 0x01 || rfu != 0x00) {
- dev_err(&client->dev, "AS3645A not detected "
- "(model %d rfu %d)\n", model, rfu);
- rval = -ENODEV;
- goto power_off;
- }
-
- switch (man) {
- case 1:
- vendor = "AMS, Austria Micro Systems";
- break;
- case 2:
- vendor = "ADI, Analog Devices Inc.";
- break;
- case 3:
- vendor = "NSC, National Semiconductor";
- break;
- case 4:
- vendor = "NXP";
- break;
- case 5:
- vendor = "TI, Texas Instrument";
- break;
- default:
- vendor = "Unknown";
- }
-
- dev_info(&client->dev, "Chip vendor: %s (%d) Version: %d\n", vendor,
- man, version);
-
- rval = as3645a_write(flash, AS_PASSWORD_REG, AS_PASSWORD_UNLOCK_VALUE);
- if (rval < 0)
- goto power_off;
-
- rval = as3645a_write(flash, AS_BOOST_REG, AS_BOOST_CURRENT_DISABLE);
- if (rval < 0)
- goto power_off;
-
- /* Setup default values. This makes sure that the chip is in a known
- * state, in case the power rail can't be controlled.
- */
- rval = as3645a_setup(flash);
-
-power_off:
- as3645a_set_power(&flash->subdev, 0);
-
- return rval;
-}
-
-static int as3645a_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- return as3645a_set_power(sd, 1);
-}
-
-static int as3645a_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- return as3645a_set_power(sd, 0);
-}
-
-static const struct v4l2_subdev_core_ops as3645a_core_ops = {
- .s_power = as3645a_set_power,
-};
-
-static const struct v4l2_subdev_ops as3645a_ops = {
- .core = &as3645a_core_ops,
-};
-
-static const struct v4l2_subdev_internal_ops as3645a_internal_ops = {
- .registered = as3645a_registered,
- .open = as3645a_open,
- .close = as3645a_close,
-};
-
-/* -----------------------------------------------------------------------------
- * I2C driver
- */
-#ifdef CONFIG_PM
-
-static int as3645a_suspend(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct as3645a *flash = to_as3645a(subdev);
- int rval;
-
- if (flash->power_count == 0)
- return 0;
-
- rval = __as3645a_set_power(flash, 0);
-
- dev_dbg(&client->dev, "Suspend %s\n", rval < 0 ? "failed" : "ok");
-
- return rval;
-}
-
-static int as3645a_resume(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct as3645a *flash = to_as3645a(subdev);
- int rval;
-
- if (flash->power_count == 0)
- return 0;
-
- rval = __as3645a_set_power(flash, 1);
-
- dev_dbg(&client->dev, "Resume %s\n", rval < 0 ? "fail" : "ok");
-
- return rval;
-}
-
-#else
-
-#define as3645a_suspend NULL
-#define as3645a_resume NULL
-
-#endif /* CONFIG_PM */
-
-/*
- * as3645a_init_controls - Create controls
- * @flash: The flash
- *
- * The number of LEDs reported in platform data is used to compute default
- * limits. Parameters passed through platform data can override those limits.
- */
-static int __devinit as3645a_init_controls(struct as3645a *flash)
-{
- const struct as3645a_platform_data *pdata = flash->pdata;
- struct v4l2_ctrl *ctrl;
- int maximum;
-
- v4l2_ctrl_handler_init(&flash->ctrls, 10);
-
- /* V4L2_CID_FLASH_LED_MODE */
- v4l2_ctrl_new_std_menu(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_LED_MODE, 2, ~7,
- V4L2_FLASH_LED_MODE_NONE);
-
- /* V4L2_CID_FLASH_STROBE_SOURCE */
- v4l2_ctrl_new_std_menu(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_STROBE_SOURCE,
- pdata->ext_strobe ? 1 : 0,
- pdata->ext_strobe ? ~3 : ~1,
- V4L2_FLASH_STROBE_SOURCE_SOFTWARE);
-
- flash->strobe_source = V4L2_FLASH_STROBE_SOURCE_SOFTWARE;
-
- /* V4L2_CID_FLASH_STROBE */
- v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_STROBE, 0, 0, 0, 0);
-
- /* V4L2_CID_FLASH_STROBE_STOP */
- v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0);
-
- /* V4L2_CID_FLASH_STROBE_STATUS */
- ctrl = v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_STROBE_STATUS, 0, 1, 1, 1);
- if (ctrl != NULL)
- ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
-
- /* V4L2_CID_FLASH_TIMEOUT */
- maximum = pdata->timeout_max;
-
- v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_TIMEOUT, AS3645A_FLASH_TIMEOUT_MIN,
- maximum, AS3645A_FLASH_TIMEOUT_STEP, maximum);
-
- flash->timeout = maximum;
-
- /* V4L2_CID_FLASH_INTENSITY */
- maximum = pdata->flash_max_current;
-
- v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_INTENSITY, AS3645A_FLASH_INTENSITY_MIN,
- maximum, AS3645A_FLASH_INTENSITY_STEP, maximum);
-
- flash->flash_current = (maximum - AS3645A_FLASH_INTENSITY_MIN)
- / AS3645A_FLASH_INTENSITY_STEP;
-
- /* V4L2_CID_FLASH_TORCH_INTENSITY */
- maximum = pdata->torch_max_current;
-
- v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_TORCH_INTENSITY,
- AS3645A_TORCH_INTENSITY_MIN, maximum,
- AS3645A_TORCH_INTENSITY_STEP,
- AS3645A_TORCH_INTENSITY_MIN);
-
- flash->assist_current = 0;
-
- /* V4L2_CID_FLASH_INDICATOR_INTENSITY */
- v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_INDICATOR_INTENSITY,
- AS3645A_INDICATOR_INTENSITY_MIN,
- AS3645A_INDICATOR_INTENSITY_MAX,
- AS3645A_INDICATOR_INTENSITY_STEP,
- AS3645A_INDICATOR_INTENSITY_MIN);
-
- flash->indicator_current = 0;
-
- /* V4L2_CID_FLASH_FAULT */
- ctrl = v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_FAULT, 0,
- V4L2_FLASH_FAULT_OVER_VOLTAGE |
- V4L2_FLASH_FAULT_TIMEOUT |
- V4L2_FLASH_FAULT_OVER_TEMPERATURE |
- V4L2_FLASH_FAULT_SHORT_CIRCUIT, 0, 0);
- if (ctrl != NULL)
- ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
-
- flash->subdev.ctrl_handler = &flash->ctrls;
-
- return flash->ctrls.error;
-}
-
-static int __devinit as3645a_probe(struct i2c_client *client,
- const struct i2c_device_id *devid)
-{
- struct as3645a *flash;
- int ret;
-
- if (client->dev.platform_data == NULL)
- return -ENODEV;
-
- flash = kzalloc(sizeof(*flash), GFP_KERNEL);
- if (flash == NULL)
- return -ENOMEM;
-
- flash->pdata = client->dev.platform_data;
-
- v4l2_i2c_subdev_init(&flash->subdev, client, &as3645a_ops);
- flash->subdev.internal_ops = &as3645a_internal_ops;
- flash->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- ret = as3645a_init_controls(flash);
- if (ret < 0)
- goto done;
-
- ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0);
- if (ret < 0)
- goto done;
-
- flash->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
-
- mutex_init(&flash->power_lock);
-
- flash->led_mode = V4L2_FLASH_LED_MODE_NONE;
-
-done:
- if (ret < 0) {
- v4l2_ctrl_handler_free(&flash->ctrls);
- kfree(flash);
- }
-
- return ret;
-}
-
-static int __devexit as3645a_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct as3645a *flash = to_as3645a(subdev);
-
- v4l2_device_unregister_subdev(subdev);
- v4l2_ctrl_handler_free(&flash->ctrls);
- media_entity_cleanup(&flash->subdev.entity);
- mutex_destroy(&flash->power_lock);
- kfree(flash);
-
- return 0;
-}
-
-static const struct i2c_device_id as3645a_id_table[] = {
- { AS3645A_NAME, 0 },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, as3645a_id_table);
-
-static const struct dev_pm_ops as3645a_pm_ops = {
- .suspend = as3645a_suspend,
- .resume = as3645a_resume,
-};
-
-static struct i2c_driver as3645a_i2c_driver = {
- .driver = {
- .name = AS3645A_NAME,
- .pm = &as3645a_pm_ops,
- },
- .probe = as3645a_probe,
- .remove = __devexit_p(as3645a_remove),
- .id_table = as3645a_id_table,
-};
-
-module_i2c_driver(as3645a_i2c_driver);
-
-MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
-MODULE_DESCRIPTION("LED flash driver for AS3645A, LM3555 and their clones");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/atmel-isi.c b/drivers/media/video/atmel-isi.c
deleted file mode 100644
index 6274a91c25c..00000000000
--- a/drivers/media/video/atmel-isi.c
+++ /dev/null
@@ -1,1099 +0,0 @@
-/*
- * Copyright (c) 2011 Atmel Corporation
- * Josh Wu, <josh.wu@atmel.com>
- *
- * Based on previous work by Lars Haring, <lars.haring@atmel.com>
- * and Sedji Gaouaou
- * Based on the bttv driver for Bt848 with respective copyright holders
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/clk.h>
-#include <linux/completion.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <media/atmel-isi.h>
-#include <media/soc_camera.h>
-#include <media/soc_mediabus.h>
-#include <media/videobuf2-dma-contig.h>
-
-#define MAX_BUFFER_NUM 32
-#define MAX_SUPPORT_WIDTH 2048
-#define MAX_SUPPORT_HEIGHT 2048
-#define VID_LIMIT_BYTES (16 * 1024 * 1024)
-#define MIN_FRAME_RATE 15
-#define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE)
-
-/* ISI states */
-enum {
- ISI_STATE_IDLE = 0,
- ISI_STATE_READY,
- ISI_STATE_WAIT_SOF,
-};
-
-/* Frame buffer descriptor */
-struct fbd {
- /* Physical address of the frame buffer */
- u32 fb_address;
- /* DMA Control Register(only in HISI2) */
- u32 dma_ctrl;
- /* Physical address of the next fbd */
- u32 next_fbd_address;
-};
-
-static void set_dma_ctrl(struct fbd *fb_desc, u32 ctrl)
-{
- fb_desc->dma_ctrl = ctrl;
-}
-
-struct isi_dma_desc {
- struct list_head list;
- struct fbd *p_fbd;
- u32 fbd_phys;
-};
-
-/* Frame buffer data */
-struct frame_buffer {
- struct vb2_buffer vb;
- struct isi_dma_desc *p_dma_desc;
- struct list_head list;
-};
-
-struct atmel_isi {
- /* Protects the access of variables shared with the ISR */
- spinlock_t lock;
- void __iomem *regs;
-
- int sequence;
- /* State of the ISI module in capturing mode */
- int state;
-
- /* Wait queue for waiting for SOF */
- wait_queue_head_t vsync_wq;
-
- struct vb2_alloc_ctx *alloc_ctx;
-
- /* Allocate descriptors for dma buffer use */
- struct fbd *p_fb_descriptors;
- u32 fb_descriptors_phys;
- struct list_head dma_desc_head;
- struct isi_dma_desc dma_desc[MAX_BUFFER_NUM];
-
- struct completion complete;
- /* ISI peripherial clock */
- struct clk *pclk;
- /* ISI_MCK, feed to camera sensor to generate pixel clock */
- struct clk *mck;
- unsigned int irq;
-
- struct isi_platform_data *pdata;
- u16 width_flags; /* max 12 bits */
-
- struct list_head video_buffer_list;
- struct frame_buffer *active;
-
- struct soc_camera_device *icd;
- struct soc_camera_host soc_host;
-};
-
-static void isi_writel(struct atmel_isi *isi, u32 reg, u32 val)
-{
- writel(val, isi->regs + reg);
-}
-static u32 isi_readl(struct atmel_isi *isi, u32 reg)
-{
- return readl(isi->regs + reg);
-}
-
-static int configure_geometry(struct atmel_isi *isi, u32 width,
- u32 height, enum v4l2_mbus_pixelcode code)
-{
- u32 cfg2, cr;
-
- switch (code) {
- /* YUV, including grey */
- case V4L2_MBUS_FMT_Y8_1X8:
- cr = ISI_CFG2_GRAYSCALE;
- break;
- case V4L2_MBUS_FMT_UYVY8_2X8:
- cr = ISI_CFG2_YCC_SWAP_MODE_3;
- break;
- case V4L2_MBUS_FMT_VYUY8_2X8:
- cr = ISI_CFG2_YCC_SWAP_MODE_2;
- break;
- case V4L2_MBUS_FMT_YUYV8_2X8:
- cr = ISI_CFG2_YCC_SWAP_MODE_1;
- break;
- case V4L2_MBUS_FMT_YVYU8_2X8:
- cr = ISI_CFG2_YCC_SWAP_DEFAULT;
- break;
- /* RGB, TODO */
- default:
- return -EINVAL;
- }
-
- isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
-
- cfg2 = isi_readl(isi, ISI_CFG2);
- cfg2 |= cr;
- /* Set width */
- cfg2 &= ~(ISI_CFG2_IM_HSIZE_MASK);
- cfg2 |= ((width - 1) << ISI_CFG2_IM_HSIZE_OFFSET) &
- ISI_CFG2_IM_HSIZE_MASK;
- /* Set height */
- cfg2 &= ~(ISI_CFG2_IM_VSIZE_MASK);
- cfg2 |= ((height - 1) << ISI_CFG2_IM_VSIZE_OFFSET)
- & ISI_CFG2_IM_VSIZE_MASK;
- isi_writel(isi, ISI_CFG2, cfg2);
-
- return 0;
-}
-
-static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi)
-{
- if (isi->active) {
- struct vb2_buffer *vb = &isi->active->vb;
- struct frame_buffer *buf = isi->active;
-
- list_del_init(&buf->list);
- do_gettimeofday(&vb->v4l2_buf.timestamp);
- vb->v4l2_buf.sequence = isi->sequence++;
- vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
- }
-
- if (list_empty(&isi->video_buffer_list)) {
- isi->active = NULL;
- } else {
- /* start next dma frame. */
- isi->active = list_entry(isi->video_buffer_list.next,
- struct frame_buffer, list);
- isi_writel(isi, ISI_DMA_C_DSCR,
- isi->active->p_dma_desc->fbd_phys);
- isi_writel(isi, ISI_DMA_C_CTRL,
- ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
- isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
- }
- return IRQ_HANDLED;
-}
-
-/* ISI interrupt service routine */
-static irqreturn_t isi_interrupt(int irq, void *dev_id)
-{
- struct atmel_isi *isi = dev_id;
- u32 status, mask, pending;
- irqreturn_t ret = IRQ_NONE;
-
- spin_lock(&isi->lock);
-
- status = isi_readl(isi, ISI_STATUS);
- mask = isi_readl(isi, ISI_INTMASK);
- pending = status & mask;
-
- if (pending & ISI_CTRL_SRST) {
- complete(&isi->complete);
- isi_writel(isi, ISI_INTDIS, ISI_CTRL_SRST);
- ret = IRQ_HANDLED;
- } else if (pending & ISI_CTRL_DIS) {
- complete(&isi->complete);
- isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS);
- ret = IRQ_HANDLED;
- } else {
- if ((pending & ISI_SR_VSYNC) &&
- (isi->state == ISI_STATE_IDLE)) {
- isi->state = ISI_STATE_READY;
- wake_up_interruptible(&isi->vsync_wq);
- ret = IRQ_HANDLED;
- }
- if (likely(pending & ISI_SR_CXFR_DONE))
- ret = atmel_isi_handle_streaming(isi);
- }
-
- spin_unlock(&isi->lock);
- return ret;
-}
-
-#define WAIT_ISI_RESET 1
-#define WAIT_ISI_DISABLE 0
-static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
-{
- unsigned long timeout;
- /*
- * The reset or disable will only succeed if we have a
- * pixel clock from the camera.
- */
- init_completion(&isi->complete);
-
- if (wait_reset) {
- isi_writel(isi, ISI_INTEN, ISI_CTRL_SRST);
- isi_writel(isi, ISI_CTRL, ISI_CTRL_SRST);
- } else {
- isi_writel(isi, ISI_INTEN, ISI_CTRL_DIS);
- isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
- }
-
- timeout = wait_for_completion_timeout(&isi->complete,
- msecs_to_jiffies(100));
- if (timeout == 0)
- return -ETIMEDOUT;
-
- return 0;
-}
-
-/* ------------------------------------------------------------------
- Videobuf operations
- ------------------------------------------------------------------*/
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
- unsigned int *nbuffers, unsigned int *nplanes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct atmel_isi *isi = ici->priv;
- unsigned long size;
- int ret;
-
- /* Reset ISI */
- ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET);
- if (ret < 0) {
- dev_err(icd->parent, "Reset ISI timed out\n");
- return ret;
- }
- /* Disable all interrupts */
- isi_writel(isi, ISI_INTDIS, ~0UL);
-
- size = icd->sizeimage;
-
- if (!*nbuffers || *nbuffers > MAX_BUFFER_NUM)
- *nbuffers = MAX_BUFFER_NUM;
-
- if (size * *nbuffers > VID_LIMIT_BYTES)
- *nbuffers = VID_LIMIT_BYTES / size;
-
- *nplanes = 1;
- sizes[0] = size;
- alloc_ctxs[0] = isi->alloc_ctx;
-
- isi->sequence = 0;
- isi->active = NULL;
-
- dev_dbg(icd->parent, "%s, count=%d, size=%ld\n", __func__,
- *nbuffers, size);
-
- return 0;
-}
-
-static int buffer_init(struct vb2_buffer *vb)
-{
- struct frame_buffer *buf = container_of(vb, struct frame_buffer, vb);
-
- buf->p_dma_desc = NULL;
- INIT_LIST_HEAD(&buf->list);
-
- return 0;
-}
-
-static int buffer_prepare(struct vb2_buffer *vb)
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
- struct frame_buffer *buf = container_of(vb, struct frame_buffer, vb);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct atmel_isi *isi = ici->priv;
- unsigned long size;
- struct isi_dma_desc *desc;
-
- size = icd->sizeimage;
-
- if (vb2_plane_size(vb, 0) < size) {
- dev_err(icd->parent, "%s data will not fit into plane (%lu < %lu)\n",
- __func__, vb2_plane_size(vb, 0), size);
- return -EINVAL;
- }
-
- vb2_set_plane_payload(&buf->vb, 0, size);
-
- if (!buf->p_dma_desc) {
- if (list_empty(&isi->dma_desc_head)) {
- dev_err(icd->parent, "Not enough dma descriptors.\n");
- return -EINVAL;
- } else {
- /* Get an available descriptor */
- desc = list_entry(isi->dma_desc_head.next,
- struct isi_dma_desc, list);
- /* Delete the descriptor since now it is used */
- list_del_init(&desc->list);
-
- /* Initialize the dma descriptor */
- desc->p_fbd->fb_address =
- vb2_dma_contig_plane_dma_addr(vb, 0);
- desc->p_fbd->next_fbd_address = 0;
- set_dma_ctrl(desc->p_fbd, ISI_DMA_CTRL_WB);
-
- buf->p_dma_desc = desc;
- }
- }
- return 0;
-}
-
-static void buffer_cleanup(struct vb2_buffer *vb)
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct atmel_isi *isi = ici->priv;
- struct frame_buffer *buf = container_of(vb, struct frame_buffer, vb);
-
- /* This descriptor is available now and we add to head list */
- if (buf->p_dma_desc)
- list_add(&buf->p_dma_desc->list, &isi->dma_desc_head);
-}
-
-static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer)
-{
- u32 ctrl, cfg1;
-
- cfg1 = isi_readl(isi, ISI_CFG1);
- /* Enable irq: cxfr for the codec path, pxfr for the preview path */
- isi_writel(isi, ISI_INTEN,
- ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
-
- /* Check if already in a frame */
- if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
- dev_err(isi->icd->parent, "Already in frame handling.\n");
- return;
- }
-
- isi_writel(isi, ISI_DMA_C_DSCR, buffer->p_dma_desc->fbd_phys);
- isi_writel(isi, ISI_DMA_C_CTRL, ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
- isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
-
- /* Enable linked list */
- cfg1 |= isi->pdata->frate | ISI_CFG1_DISCR;
-
- /* Enable codec path and ISI */
- ctrl = ISI_CTRL_CDC | ISI_CTRL_EN;
- isi_writel(isi, ISI_CTRL, ctrl);
- isi_writel(isi, ISI_CFG1, cfg1);
-}
-
-static void buffer_queue(struct vb2_buffer *vb)
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct atmel_isi *isi = ici->priv;
- struct frame_buffer *buf = container_of(vb, struct frame_buffer, vb);
- unsigned long flags = 0;
-
- spin_lock_irqsave(&isi->lock, flags);
- list_add_tail(&buf->list, &isi->video_buffer_list);
-
- if (isi->active == NULL) {
- isi->active = buf;
- if (vb2_is_streaming(vb->vb2_queue))
- start_dma(isi, buf);
- }
- spin_unlock_irqrestore(&isi->lock, flags);
-}
-
-static int start_streaming(struct vb2_queue *vq, unsigned int count)
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct atmel_isi *isi = ici->priv;
-
- u32 sr = 0;
- int ret;
-
- spin_lock_irq(&isi->lock);
- isi->state = ISI_STATE_IDLE;
- /* Clear any pending SOF interrupt */
- sr = isi_readl(isi, ISI_STATUS);
- /* Enable VSYNC interrupt for SOF */
- isi_writel(isi, ISI_INTEN, ISI_SR_VSYNC);
- isi_writel(isi, ISI_CTRL, ISI_CTRL_EN);
- spin_unlock_irq(&isi->lock);
-
- dev_dbg(icd->parent, "Waiting for SOF\n");
- ret = wait_event_interruptible(isi->vsync_wq,
- isi->state != ISI_STATE_IDLE);
- if (ret)
- goto err;
-
- if (isi->state != ISI_STATE_READY) {
- ret = -EIO;
- goto err;
- }
-
- spin_lock_irq(&isi->lock);
- isi->state = ISI_STATE_WAIT_SOF;
- isi_writel(isi, ISI_INTDIS, ISI_SR_VSYNC);
- if (count)
- start_dma(isi, isi->active);
- spin_unlock_irq(&isi->lock);
-
- return 0;
-err:
- isi->active = NULL;
- isi->sequence = 0;
- INIT_LIST_HEAD(&isi->video_buffer_list);
- return ret;
-}
-
-/* abort streaming and wait for last buffer */
-static int stop_streaming(struct vb2_queue *vq)
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct atmel_isi *isi = ici->priv;
- struct frame_buffer *buf, *node;
- int ret = 0;
- unsigned long timeout;
-
- spin_lock_irq(&isi->lock);
- isi->active = NULL;
- /* Release all active buffers */
- list_for_each_entry_safe(buf, node, &isi->video_buffer_list, list) {
- list_del_init(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- }
- spin_unlock_irq(&isi->lock);
-
- timeout = jiffies + FRAME_INTERVAL_MILLI_SEC * HZ;
- /* Wait until the end of the current frame. */
- while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) &&
- time_before(jiffies, timeout))
- msleep(1);
-
- if (time_after(jiffies, timeout)) {
- dev_err(icd->parent,
- "Timeout waiting for finishing codec request\n");
- return -ETIMEDOUT;
- }
-
- /* Disable interrupts */
- isi_writel(isi, ISI_INTDIS,
- ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
-
- /* Disable ISI and wait for it is done */
- ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE);
- if (ret < 0)
- dev_err(icd->parent, "Disable ISI timed out\n");
-
- return ret;
-}
-
-static struct vb2_ops isi_video_qops = {
- .queue_setup = queue_setup,
- .buf_init = buffer_init,
- .buf_prepare = buffer_prepare,
- .buf_cleanup = buffer_cleanup,
- .buf_queue = buffer_queue,
- .start_streaming = start_streaming,
- .stop_streaming = stop_streaming,
- .wait_prepare = soc_camera_unlock,
- .wait_finish = soc_camera_lock,
-};
-
-/* ------------------------------------------------------------------
- SOC camera operations for the device
- ------------------------------------------------------------------*/
-static int isi_camera_init_videobuf(struct vb2_queue *q,
- struct soc_camera_device *icd)
-{
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- q->io_modes = VB2_MMAP;
- q->drv_priv = icd;
- q->buf_struct_size = sizeof(struct frame_buffer);
- q->ops = &isi_video_qops;
- q->mem_ops = &vb2_dma_contig_memops;
-
- return vb2_queue_init(q);
-}
-
-static int isi_camera_set_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct atmel_isi *isi = ici->priv;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- int ret;
-
- xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
- if (!xlate) {
- dev_warn(icd->parent, "Format %x not found\n",
- pix->pixelformat);
- return -EINVAL;
- }
-
- dev_dbg(icd->parent, "Plan to set format %dx%d\n",
- pix->width, pix->height);
-
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- if (mf.code != xlate->code)
- return -EINVAL;
-
- ret = configure_geometry(isi, pix->width, pix->height, xlate->code);
- if (ret < 0)
- return ret;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
- icd->current_fmt = xlate;
-
- dev_dbg(icd->parent, "Finally set format %dx%d\n",
- pix->width, pix->height);
-
- return ret;
-}
-
-static int isi_camera_try_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- u32 pixfmt = pix->pixelformat;
- int ret;
-
- xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
- if (pixfmt && !xlate) {
- dev_warn(icd->parent, "Format %x not found\n", pixfmt);
- return -EINVAL;
- }
-
- /* limit to Atmel ISI hardware capabilities */
- if (pix->height > MAX_SUPPORT_HEIGHT)
- pix->height = MAX_SUPPORT_HEIGHT;
- if (pix->width > MAX_SUPPORT_WIDTH)
- pix->width = MAX_SUPPORT_WIDTH;
-
- /* limit to sensor capabilities */
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->colorspace = mf.colorspace;
-
- switch (mf.field) {
- case V4L2_FIELD_ANY:
- pix->field = V4L2_FIELD_NONE;
- break;
- case V4L2_FIELD_NONE:
- break;
- default:
- dev_err(icd->parent, "Field type %d unsupported.\n",
- mf.field);
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static const struct soc_mbus_pixelfmt isi_camera_formats[] = {
- {
- .fourcc = V4L2_PIX_FMT_YUYV,
- .name = "Packed YUV422 16 bit",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-};
-
-/* This will be corrected as we get more formats */
-static bool isi_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
-{
- return fmt->packing == SOC_MBUS_PACKING_NONE ||
- (fmt->bits_per_sample == 8 &&
- fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
- (fmt->bits_per_sample > 8 &&
- fmt->packing == SOC_MBUS_PACKING_EXTEND16);
-}
-
-#define ISI_BUS_PARAM (V4L2_MBUS_MASTER | \
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
- V4L2_MBUS_HSYNC_ACTIVE_LOW | \
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
- V4L2_MBUS_VSYNC_ACTIVE_LOW | \
- V4L2_MBUS_PCLK_SAMPLE_RISING | \
- V4L2_MBUS_PCLK_SAMPLE_FALLING | \
- V4L2_MBUS_DATA_ACTIVE_HIGH)
-
-static int isi_camera_try_bus_param(struct soc_camera_device *icd,
- unsigned char buswidth)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct atmel_isi *isi = ici->priv;
- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
- unsigned long common_flags;
- int ret;
-
- ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
- if (!ret) {
- common_flags = soc_mbus_config_compatible(&cfg,
- ISI_BUS_PARAM);
- if (!common_flags) {
- dev_warn(icd->parent,
- "Flags incompatible: camera 0x%x, host 0x%x\n",
- cfg.flags, ISI_BUS_PARAM);
- return -EINVAL;
- }
- } else if (ret != -ENOIOCTLCMD) {
- return ret;
- }
-
- if ((1 << (buswidth - 1)) & isi->width_flags)
- return 0;
- return -EINVAL;
-}
-
-
-static int isi_camera_get_formats(struct soc_camera_device *icd,
- unsigned int idx,
- struct soc_camera_format_xlate *xlate)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- int formats = 0, ret;
- /* sensor format */
- enum v4l2_mbus_pixelcode code;
- /* soc camera host format */
- const struct soc_mbus_pixelfmt *fmt;
-
- ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
- if (ret < 0)
- /* No more formats */
- return 0;
-
- fmt = soc_mbus_get_fmtdesc(code);
- if (!fmt) {
- dev_err(icd->parent,
- "Invalid format code #%u: %d\n", idx, code);
- return 0;
- }
-
- /* This also checks support for the requested bits-per-sample */
- ret = isi_camera_try_bus_param(icd, fmt->bits_per_sample);
- if (ret < 0) {
- dev_err(icd->parent,
- "Fail to try the bus parameters.\n");
- return 0;
- }
-
- switch (code) {
- case V4L2_MBUS_FMT_UYVY8_2X8:
- case V4L2_MBUS_FMT_VYUY8_2X8:
- case V4L2_MBUS_FMT_YUYV8_2X8:
- case V4L2_MBUS_FMT_YVYU8_2X8:
- formats++;
- if (xlate) {
- xlate->host_fmt = &isi_camera_formats[0];
- xlate->code = code;
- xlate++;
- dev_dbg(icd->parent, "Providing format %s using code %d\n",
- isi_camera_formats[0].name, code);
- }
- break;
- default:
- if (!isi_camera_packing_supported(fmt))
- return 0;
- if (xlate)
- dev_dbg(icd->parent,
- "Providing format %s in pass-through mode\n",
- fmt->name);
- }
-
- /* Generic pass-through */
- formats++;
- if (xlate) {
- xlate->host_fmt = fmt;
- xlate->code = code;
- xlate++;
- }
-
- return formats;
-}
-
-/* Called with .video_lock held */
-static int isi_camera_add_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct atmel_isi *isi = ici->priv;
- int ret;
-
- if (isi->icd)
- return -EBUSY;
-
- ret = clk_enable(isi->pclk);
- if (ret)
- return ret;
-
- ret = clk_enable(isi->mck);
- if (ret) {
- clk_disable(isi->pclk);
- return ret;
- }
-
- isi->icd = icd;
- dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n",
- icd->devnum);
- return 0;
-}
-/* Called with .video_lock held */
-static void isi_camera_remove_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct atmel_isi *isi = ici->priv;
-
- BUG_ON(icd != isi->icd);
-
- clk_disable(isi->mck);
- clk_disable(isi->pclk);
- isi->icd = NULL;
-
- dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n",
- icd->devnum);
-}
-
-static unsigned int isi_camera_poll(struct file *file, poll_table *pt)
-{
- struct soc_camera_device *icd = file->private_data;
-
- return vb2_poll(&icd->vb2_vidq, file, pt);
-}
-
-static int isi_camera_querycap(struct soc_camera_host *ici,
- struct v4l2_capability *cap)
-{
- strcpy(cap->driver, "atmel-isi");
- strcpy(cap->card, "Atmel Image Sensor Interface");
- cap->capabilities = (V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_STREAMING);
- return 0;
-}
-
-static int isi_camera_set_bus_param(struct soc_camera_device *icd)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct atmel_isi *isi = ici->priv;
- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
- unsigned long common_flags;
- int ret;
- u32 cfg1 = 0;
-
- ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
- if (!ret) {
- common_flags = soc_mbus_config_compatible(&cfg,
- ISI_BUS_PARAM);
- if (!common_flags) {
- dev_warn(icd->parent,
- "Flags incompatible: camera 0x%x, host 0x%x\n",
- cfg.flags, ISI_BUS_PARAM);
- return -EINVAL;
- }
- } else if (ret != -ENOIOCTLCMD) {
- return ret;
- } else {
- common_flags = ISI_BUS_PARAM;
- }
- dev_dbg(icd->parent, "Flags cam: 0x%x host: 0x%x common: 0x%lx\n",
- cfg.flags, ISI_BUS_PARAM, common_flags);
-
- /* Make choises, based on platform preferences */
- if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
- (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
- if (isi->pdata->hsync_act_low)
- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
- else
- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
- }
-
- if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
- (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
- if (isi->pdata->vsync_act_low)
- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
- else
- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
- }
-
- if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
- (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
- if (isi->pdata->pclk_act_falling)
- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
- else
- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
- }
-
- cfg.flags = common_flags;
- ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
- if (ret < 0 && ret != -ENOIOCTLCMD) {
- dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
- common_flags, ret);
- return ret;
- }
-
- /* set bus param for ISI */
- if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
- cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW;
- if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
- cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW;
- if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
- cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
-
- if (isi->pdata->has_emb_sync)
- cfg1 |= ISI_CFG1_EMB_SYNC;
- if (isi->pdata->full_mode)
- cfg1 |= ISI_CFG1_FULL_MODE;
-
- isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
- isi_writel(isi, ISI_CFG1, cfg1);
-
- return 0;
-}
-
-static struct soc_camera_host_ops isi_soc_camera_host_ops = {
- .owner = THIS_MODULE,
- .add = isi_camera_add_device,
- .remove = isi_camera_remove_device,
- .set_fmt = isi_camera_set_fmt,
- .try_fmt = isi_camera_try_fmt,
- .get_formats = isi_camera_get_formats,
- .init_videobuf2 = isi_camera_init_videobuf,
- .poll = isi_camera_poll,
- .querycap = isi_camera_querycap,
- .set_bus_param = isi_camera_set_bus_param,
-};
-
-/* -----------------------------------------------------------------------*/
-static int __devexit atmel_isi_remove(struct platform_device *pdev)
-{
- struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
- struct atmel_isi *isi = container_of(soc_host,
- struct atmel_isi, soc_host);
-
- free_irq(isi->irq, isi);
- soc_camera_host_unregister(soc_host);
- vb2_dma_contig_cleanup_ctx(isi->alloc_ctx);
- dma_free_coherent(&pdev->dev,
- sizeof(struct fbd) * MAX_BUFFER_NUM,
- isi->p_fb_descriptors,
- isi->fb_descriptors_phys);
-
- iounmap(isi->regs);
- clk_unprepare(isi->mck);
- clk_put(isi->mck);
- clk_unprepare(isi->pclk);
- clk_put(isi->pclk);
- kfree(isi);
-
- return 0;
-}
-
-static int __devinit atmel_isi_probe(struct platform_device *pdev)
-{
- unsigned int irq;
- struct atmel_isi *isi;
- struct clk *pclk;
- struct resource *regs;
- int ret, i;
- struct device *dev = &pdev->dev;
- struct soc_camera_host *soc_host;
- struct isi_platform_data *pdata;
-
- pdata = dev->platform_data;
- if (!pdata || !pdata->data_width_flags || !pdata->mck_hz) {
- dev_err(&pdev->dev,
- "No config available for Atmel ISI\n");
- return -EINVAL;
- }
-
- regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!regs)
- return -ENXIO;
-
- pclk = clk_get(&pdev->dev, "isi_clk");
- if (IS_ERR(pclk))
- return PTR_ERR(pclk);
-
- ret = clk_prepare(pclk);
- if (ret)
- goto err_clk_prepare_pclk;
-
- isi = kzalloc(sizeof(struct atmel_isi), GFP_KERNEL);
- if (!isi) {
- ret = -ENOMEM;
- dev_err(&pdev->dev, "Can't allocate interface!\n");
- goto err_alloc_isi;
- }
-
- isi->pclk = pclk;
- isi->pdata = pdata;
- isi->active = NULL;
- spin_lock_init(&isi->lock);
- init_waitqueue_head(&isi->vsync_wq);
- INIT_LIST_HEAD(&isi->video_buffer_list);
- INIT_LIST_HEAD(&isi->dma_desc_head);
-
- /* Get ISI_MCK, provided by programmable clock or external clock */
- isi->mck = clk_get(dev, "isi_mck");
- if (IS_ERR(isi->mck)) {
- dev_err(dev, "Failed to get isi_mck\n");
- ret = PTR_ERR(isi->mck);
- goto err_clk_get;
- }
-
- ret = clk_prepare(isi->mck);
- if (ret)
- goto err_clk_prepare_mck;
-
- /* Set ISI_MCK's frequency, it should be faster than pixel clock */
- ret = clk_set_rate(isi->mck, pdata->mck_hz);
- if (ret < 0)
- goto err_set_mck_rate;
-
- isi->p_fb_descriptors = dma_alloc_coherent(&pdev->dev,
- sizeof(struct fbd) * MAX_BUFFER_NUM,
- &isi->fb_descriptors_phys,
- GFP_KERNEL);
- if (!isi->p_fb_descriptors) {
- ret = -ENOMEM;
- dev_err(&pdev->dev, "Can't allocate descriptors!\n");
- goto err_alloc_descriptors;
- }
-
- for (i = 0; i < MAX_BUFFER_NUM; i++) {
- isi->dma_desc[i].p_fbd = isi->p_fb_descriptors + i;
- isi->dma_desc[i].fbd_phys = isi->fb_descriptors_phys +
- i * sizeof(struct fbd);
- list_add(&isi->dma_desc[i].list, &isi->dma_desc_head);
- }
-
- isi->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
- if (IS_ERR(isi->alloc_ctx)) {
- ret = PTR_ERR(isi->alloc_ctx);
- goto err_alloc_ctx;
- }
-
- isi->regs = ioremap(regs->start, resource_size(regs));
- if (!isi->regs) {
- ret = -ENOMEM;
- goto err_ioremap;
- }
-
- if (pdata->data_width_flags & ISI_DATAWIDTH_8)
- isi->width_flags = 1 << 7;
- if (pdata->data_width_flags & ISI_DATAWIDTH_10)
- isi->width_flags |= 1 << 9;
-
- isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = irq;
- goto err_req_irq;
- }
-
- ret = request_irq(irq, isi_interrupt, 0, "isi", isi);
- if (ret) {
- dev_err(&pdev->dev, "Unable to request irq %d\n", irq);
- goto err_req_irq;
- }
- isi->irq = irq;
-
- soc_host = &isi->soc_host;
- soc_host->drv_name = "isi-camera";
- soc_host->ops = &isi_soc_camera_host_ops;
- soc_host->priv = isi;
- soc_host->v4l2_dev.dev = &pdev->dev;
- soc_host->nr = pdev->id;
-
- ret = soc_camera_host_register(soc_host);
- if (ret) {
- dev_err(&pdev->dev, "Unable to register soc camera host\n");
- goto err_register_soc_camera_host;
- }
- return 0;
-
-err_register_soc_camera_host:
- free_irq(isi->irq, isi);
-err_req_irq:
- iounmap(isi->regs);
-err_ioremap:
- vb2_dma_contig_cleanup_ctx(isi->alloc_ctx);
-err_alloc_ctx:
- dma_free_coherent(&pdev->dev,
- sizeof(struct fbd) * MAX_BUFFER_NUM,
- isi->p_fb_descriptors,
- isi->fb_descriptors_phys);
-err_alloc_descriptors:
-err_set_mck_rate:
- clk_unprepare(isi->mck);
-err_clk_prepare_mck:
- clk_put(isi->mck);
-err_clk_get:
- kfree(isi);
-err_alloc_isi:
- clk_unprepare(pclk);
-err_clk_prepare_pclk:
- clk_put(pclk);
-
- return ret;
-}
-
-static struct platform_driver atmel_isi_driver = {
- .probe = atmel_isi_probe,
- .remove = __devexit_p(atmel_isi_remove),
- .driver = {
- .name = "atmel_isi",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init atmel_isi_init_module(void)
-{
- return platform_driver_probe(&atmel_isi_driver, &atmel_isi_probe);
-}
-
-static void __exit atmel_isi_exit(void)
-{
- platform_driver_unregister(&atmel_isi_driver);
-}
-module_init(atmel_isi_init_module);
-module_exit(atmel_isi_exit);
-
-MODULE_AUTHOR("Josh Wu <josh.wu@atmel.com>");
-MODULE_DESCRIPTION("The V4L2 driver for Atmel Linux");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("video");
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
deleted file mode 100644
index 23f7fd22f0e..00000000000
--- a/drivers/media/video/au0828/Kconfig
+++ /dev/null
@@ -1,18 +0,0 @@
-
-config VIDEO_AU0828
- tristate "Auvitek AU0828 support"
- depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2
- depends on DVB_CAPTURE_DRIVERS
- select I2C_ALGOBIT
- select VIDEO_TVEEPROM
- select VIDEOBUF_VMALLOC
- select DVB_AU8522_DTV if !DVB_FE_CUSTOMISE
- select DVB_AU8522_V4L if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
- ---help---
- This is a video4linux driver for Auvitek's USB device.
-
- To compile this driver as a module, choose M here: the
- module will be called au0828
diff --git a/drivers/media/video/au0828/Makefile b/drivers/media/video/au0828/Makefile
deleted file mode 100644
index bd22223f8d9..00000000000
--- a/drivers/media/video/au0828/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o au0828-video.o au0828-vbi.o
-
-obj-$(CONFIG_VIDEO_AU0828) += au0828.o
-
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
-
-ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
deleted file mode 100644
index e3fe9a6637f..00000000000
--- a/drivers/media/video/au0828/au0828-cards.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Driver for the Auvitek USB bridge
- *
- * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "au0828.h"
-#include "au0828-cards.h"
-#include "au8522.h"
-#include "media/tuner.h"
-#include "media/v4l2-common.h"
-
-void hvr950q_cs5340_audio(void *priv, int enable)
-{
- /* Because the HVR-950q shares an i2s bus between the cs5340 and the
- au8522, we need to hold cs5340 in reset when using the au8522 */
- struct au0828_dev *dev = priv;
- if (enable == 1)
- au0828_set(dev, REG_000, 0x10);
- else
- au0828_clear(dev, REG_000, 0x10);
-}
-
-struct au0828_board au0828_boards[] = {
- [AU0828_BOARD_UNKNOWN] = {
- .name = "Unknown board",
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [AU0828_BOARD_HAUPPAUGE_HVR850] = {
- .name = "Hauppauge HVR850",
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0x61,
- .i2c_clk_divider = AU0828_I2C_CLK_30KHZ,
- .input = {
- {
- .type = AU0828_VMUX_TELEVISION,
- .vmux = AU8522_COMPOSITE_CH4_SIF,
- .amux = AU8522_AUDIO_SIF,
- },
- {
- .type = AU0828_VMUX_COMPOSITE,
- .vmux = AU8522_COMPOSITE_CH1,
- .amux = AU8522_AUDIO_NONE,
- .audio_setup = hvr950q_cs5340_audio,
- },
- {
- .type = AU0828_VMUX_SVIDEO,
- .vmux = AU8522_SVIDEO_CH13,
- .amux = AU8522_AUDIO_NONE,
- .audio_setup = hvr950q_cs5340_audio,
- },
- },
- },
- [AU0828_BOARD_HAUPPAUGE_HVR950Q] = {
- .name = "Hauppauge HVR950Q",
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0x61,
- /* The au0828 hardware i2c implementation does not properly
- support the xc5000's i2c clock stretching. So we need to
- lower the clock frequency enough where the 15us clock
- stretch fits inside of a normal clock cycle, or else the
- au0828 fails to set the STOP bit. A 30 KHz clock puts the
- clock pulse width at 18us */
- .i2c_clk_divider = AU0828_I2C_CLK_30KHZ,
- .input = {
- {
- .type = AU0828_VMUX_TELEVISION,
- .vmux = AU8522_COMPOSITE_CH4_SIF,
- .amux = AU8522_AUDIO_SIF,
- },
- {
- .type = AU0828_VMUX_COMPOSITE,
- .vmux = AU8522_COMPOSITE_CH1,
- .amux = AU8522_AUDIO_NONE,
- .audio_setup = hvr950q_cs5340_audio,
- },
- {
- .type = AU0828_VMUX_SVIDEO,
- .vmux = AU8522_SVIDEO_CH13,
- .amux = AU8522_AUDIO_NONE,
- .audio_setup = hvr950q_cs5340_audio,
- },
- },
- },
- [AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = {
- .name = "Hauppauge HVR950Q rev xxF8",
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
- },
- [AU0828_BOARD_DVICO_FUSIONHDTV7] = {
- .name = "DViCO FusionHDTV USB",
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
- },
- [AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
- .name = "Hauppauge Woodbury",
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
- },
-};
-
-/* Tuner callback function for au0828 boards. Currently only needed
- * for HVR1500Q, which has an xc5000 tuner.
- */
-int au0828_tuner_callback(void *priv, int component, int command, int arg)
-{
- struct au0828_dev *dev = priv;
-
- dprintk(1, "%s()\n", __func__);
-
- switch (dev->boardnr) {
- case AU0828_BOARD_HAUPPAUGE_HVR850:
- case AU0828_BOARD_HAUPPAUGE_HVR950Q:
- case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
- case AU0828_BOARD_DVICO_FUSIONHDTV7:
- if (command == 0) {
- /* Tuner Reset Command from xc5000 */
- /* Drive the tuner into reset and out */
- au0828_clear(dev, REG_001, 2);
- mdelay(10);
- au0828_set(dev, REG_001, 2);
- mdelay(10);
- return 0;
- } else {
- printk(KERN_ERR
- "%s(): Unknown command.\n", __func__);
- return -EINVAL;
- }
- break;
- }
-
- return 0; /* Should never be here */
-}
-
-static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
-{
- struct tveeprom tv;
-
- tveeprom_hauppauge_analog(&dev->i2c_client, &tv, eeprom_data);
- dev->board.tuner_type = tv.tuner_type;
-
- /* Make sure we support the board model */
- switch (tv.model) {
- case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */
- case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */
- case 72101: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */
- case 72201: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
- case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
- case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
- case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
- case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and analog video */
- case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */
- case 72261: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
- case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and analog video */
- case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */
- break;
- default:
- printk(KERN_WARNING "%s: warning: "
- "unknown hauppauge model #%d\n", __func__, tv.model);
- break;
- }
-
- printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n",
- __func__, tv.model);
-}
-
-void au0828_card_setup(struct au0828_dev *dev)
-{
- static u8 eeprom[256];
- struct tuner_setup tun_setup;
- struct v4l2_subdev *sd;
- unsigned int mode_mask = T_ANALOG_TV;
-
- dprintk(1, "%s()\n", __func__);
-
- memcpy(&dev->board, &au0828_boards[dev->boardnr], sizeof(dev->board));
-
- if (dev->i2c_rc == 0) {
- dev->i2c_client.addr = 0xa0 >> 1;
- tveeprom_read(&dev->i2c_client, eeprom, sizeof(eeprom));
- }
-
- switch (dev->boardnr) {
- case AU0828_BOARD_HAUPPAUGE_HVR850:
- case AU0828_BOARD_HAUPPAUGE_HVR950Q:
- case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
- case AU0828_BOARD_HAUPPAUGE_WOODBURY:
- if (dev->i2c_rc == 0)
- hauppauge_eeprom(dev, eeprom+0xa0);
- break;
- }
-
- if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED) {
- /* Load the analog demodulator driver (note this would need to
- be abstracted out if we ever need to support a different
- demod) */
- sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- "au8522", 0x8e >> 1, NULL);
- if (sd == NULL)
- printk(KERN_ERR "analog subdev registration failed\n");
- }
-
- /* Setup tuners */
- if (dev->board.tuner_type != TUNER_ABSENT) {
- /* Load the tuner module, which does the attach */
- sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- "tuner", dev->board.tuner_addr, NULL);
- if (sd == NULL)
- printk(KERN_ERR "tuner subdev registration fail\n");
-
- tun_setup.mode_mask = mode_mask;
- tun_setup.type = dev->board.tuner_type;
- tun_setup.addr = dev->board.tuner_addr;
- tun_setup.tuner_callback = au0828_tuner_callback;
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr,
- &tun_setup);
- }
-}
-
-/*
- * The bridge has between 8 and 12 gpios.
- * Regs 1 and 0 deal with output enables.
- * Regs 3 and 2 deal with direction.
- */
-void au0828_gpio_setup(struct au0828_dev *dev)
-{
- dprintk(1, "%s()\n", __func__);
-
- switch (dev->boardnr) {
- case AU0828_BOARD_HAUPPAUGE_HVR850:
- case AU0828_BOARD_HAUPPAUGE_HVR950Q:
- case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
- case AU0828_BOARD_HAUPPAUGE_WOODBURY:
- /* GPIO's
- * 4 - CS5340
- * 5 - AU8522 Demodulator
- * 6 - eeprom W/P
- * 7 - power supply
- * 9 - XC5000 Tuner
- */
-
- /* Into reset */
- au0828_write(dev, REG_003, 0x02);
- au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10);
- au0828_write(dev, REG_001, 0x0);
- au0828_write(dev, REG_000, 0x0);
- msleep(100);
-
- /* Out of reset (leave the cs5340 in reset until needed) */
- au0828_write(dev, REG_003, 0x02);
- au0828_write(dev, REG_001, 0x02);
- au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10);
- au0828_write(dev, REG_000, 0x80 | 0x40 | 0x20);
-
- msleep(250);
- break;
- case AU0828_BOARD_DVICO_FUSIONHDTV7:
- /* GPIO's
- * 6 - ?
- * 8 - AU8522 Demodulator
- * 9 - XC5000 Tuner
- */
-
- /* Into reset */
- au0828_write(dev, REG_003, 0x02);
- au0828_write(dev, REG_002, 0xa0);
- au0828_write(dev, REG_001, 0x0);
- au0828_write(dev, REG_000, 0x0);
- msleep(100);
-
- /* Out of reset */
- au0828_write(dev, REG_003, 0x02);
- au0828_write(dev, REG_002, 0xa0);
- au0828_write(dev, REG_001, 0x02);
- au0828_write(dev, REG_000, 0xa0);
- msleep(250);
- break;
- }
-}
-
-/* table of devices that work with this driver */
-struct usb_device_id au0828_usb_id_table[] = {
- { USB_DEVICE(0x2040, 0x7200),
- .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
- { USB_DEVICE(0x2040, 0x7240),
- .driver_info = AU0828_BOARD_HAUPPAUGE_HVR850 },
- { USB_DEVICE(0x0fe9, 0xd620),
- .driver_info = AU0828_BOARD_DVICO_FUSIONHDTV7 },
- { USB_DEVICE(0x2040, 0x7210),
- .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
- { USB_DEVICE(0x2040, 0x7217),
- .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
- { USB_DEVICE(0x2040, 0x721b),
- .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
- { USB_DEVICE(0x2040, 0x721e),
- .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
- { USB_DEVICE(0x2040, 0x721f),
- .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
- { USB_DEVICE(0x2040, 0x7280),
- .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
- { USB_DEVICE(0x0fd9, 0x0008),
- .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
- { USB_DEVICE(0x2040, 0x7201),
- .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
- { USB_DEVICE(0x2040, 0x7211),
- .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
- { USB_DEVICE(0x2040, 0x7281),
- .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
- { USB_DEVICE(0x05e1, 0x0480),
- .driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY },
- { USB_DEVICE(0x2040, 0x8200),
- .driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY },
- { USB_DEVICE(0x2040, 0x7260),
- .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
- { USB_DEVICE(0x2040, 0x7213),
- .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
- { },
-};
-
-MODULE_DEVICE_TABLE(usb, au0828_usb_id_table);
diff --git a/drivers/media/video/au0828/au0828-cards.h b/drivers/media/video/au0828/au0828-cards.h
deleted file mode 100644
index 48a1882c2b6..00000000000
--- a/drivers/media/video/au0828/au0828-cards.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Driver for the Auvitek USB bridge
- *
- * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define AU0828_BOARD_UNKNOWN 0
-#define AU0828_BOARD_HAUPPAUGE_HVR950Q 1
-#define AU0828_BOARD_HAUPPAUGE_HVR850 2
-#define AU0828_BOARD_DVICO_FUSIONHDTV7 3
-#define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL 4
-#define AU0828_BOARD_HAUPPAUGE_WOODBURY 5
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
deleted file mode 100644
index 1e4ce5068ec..00000000000
--- a/drivers/media/video/au0828/au0828-core.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Driver for the Auvitek USB bridge
- *
- * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <linux/mutex.h>
-
-#include "au0828.h"
-
-/*
- * 1 = General debug messages
- * 2 = USB handling
- * 4 = I2C related
- * 8 = Bridge related
- */
-int au0828_debug;
-module_param_named(debug, au0828_debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debug messages");
-
-static unsigned int disable_usb_speed_check;
-module_param(disable_usb_speed_check, int, 0444);
-MODULE_PARM_DESC(disable_usb_speed_check,
- "override min bandwidth requirement of 480M bps");
-
-#define _AU0828_BULKPIPE 0x03
-#define _BULKPIPESIZE 0xffff
-
-static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value,
- u16 index, unsigned char *cp, u16 size);
-static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value,
- u16 index, unsigned char *cp, u16 size);
-
-/* USB Direction */
-#define CMD_REQUEST_IN 0x00
-#define CMD_REQUEST_OUT 0x01
-
-u32 au0828_readreg(struct au0828_dev *dev, u16 reg)
-{
- recv_control_msg(dev, CMD_REQUEST_IN, 0, reg, dev->ctrlmsg, 1);
- dprintk(8, "%s(0x%04x) = 0x%02x\n", __func__, reg, dev->ctrlmsg[0]);
- return dev->ctrlmsg[0];
-}
-
-u32 au0828_writereg(struct au0828_dev *dev, u16 reg, u32 val)
-{
- dprintk(8, "%s(0x%04x, 0x%02x)\n", __func__, reg, val);
- return send_control_msg(dev, CMD_REQUEST_OUT, val, reg,
- dev->ctrlmsg, 0);
-}
-
-static void cmd_msg_dump(struct au0828_dev *dev)
-{
- int i;
-
- for (i = 0; i < sizeof(dev->ctrlmsg); i += 16)
- dprintk(2, "%s() %02x %02x %02x %02x %02x %02x %02x %02x "
- "%02x %02x %02x %02x %02x %02x %02x %02x\n",
- __func__,
- dev->ctrlmsg[i+0], dev->ctrlmsg[i+1],
- dev->ctrlmsg[i+2], dev->ctrlmsg[i+3],
- dev->ctrlmsg[i+4], dev->ctrlmsg[i+5],
- dev->ctrlmsg[i+6], dev->ctrlmsg[i+7],
- dev->ctrlmsg[i+8], dev->ctrlmsg[i+9],
- dev->ctrlmsg[i+10], dev->ctrlmsg[i+11],
- dev->ctrlmsg[i+12], dev->ctrlmsg[i+13],
- dev->ctrlmsg[i+14], dev->ctrlmsg[i+15]);
-}
-
-static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value,
- u16 index, unsigned char *cp, u16 size)
-{
- int status = -ENODEV;
- mutex_lock(&dev->mutex);
- if (dev->usbdev) {
-
- /* cp must be memory that has been allocated by kmalloc */
- status = usb_control_msg(dev->usbdev,
- usb_sndctrlpipe(dev->usbdev, 0),
- request,
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_DEVICE,
- value, index,
- cp, size, 1000);
-
- status = min(status, 0);
-
- if (status < 0) {
- printk(KERN_ERR "%s() Failed sending control message, error %d.\n",
- __func__, status);
- }
-
- }
- mutex_unlock(&dev->mutex);
- return status;
-}
-
-static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value,
- u16 index, unsigned char *cp, u16 size)
-{
- int status = -ENODEV;
- mutex_lock(&dev->mutex);
- if (dev->usbdev) {
-
- memset(dev->ctrlmsg, 0, sizeof(dev->ctrlmsg));
-
- /* cp must be memory that has been allocated by kmalloc */
- status = usb_control_msg(dev->usbdev,
- usb_rcvctrlpipe(dev->usbdev, 0),
- request,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index,
- cp, size, 1000);
-
- status = min(status, 0);
-
- if (status < 0) {
- printk(KERN_ERR "%s() Failed receiving control message, error %d.\n",
- __func__, status);
- } else
- cmd_msg_dump(dev);
- }
- mutex_unlock(&dev->mutex);
- return status;
-}
-
-static void au0828_usb_disconnect(struct usb_interface *interface)
-{
- struct au0828_dev *dev = usb_get_intfdata(interface);
-
- dprintk(1, "%s()\n", __func__);
-
- /* Digital TV */
- au0828_dvb_unregister(dev);
-
- if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED)
- au0828_analog_unregister(dev);
-
- /* I2C */
- au0828_i2c_unregister(dev);
-
- v4l2_device_unregister(&dev->v4l2_dev);
-
- usb_set_intfdata(interface, NULL);
-
- mutex_lock(&dev->mutex);
- dev->usbdev = NULL;
- mutex_unlock(&dev->mutex);
-
- kfree(dev);
-
-}
-
-static int au0828_usb_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- int ifnum, retval;
- struct au0828_dev *dev;
- struct usb_device *usbdev = interface_to_usbdev(interface);
-
- ifnum = interface->altsetting->desc.bInterfaceNumber;
-
- if (ifnum != 0)
- return -ENODEV;
-
- dprintk(1, "%s() vendor id 0x%x device id 0x%x ifnum:%d\n", __func__,
- le16_to_cpu(usbdev->descriptor.idVendor),
- le16_to_cpu(usbdev->descriptor.idProduct),
- ifnum);
-
- /*
- * Make sure we have 480 Mbps of bandwidth, otherwise things like
- * video stream wouldn't likely work, since 12 Mbps is generally
- * not enough even for most Digital TV streams.
- */
- if (usbdev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) {
- printk(KERN_ERR "au0828: Device initialization failed.\n");
- printk(KERN_ERR "au0828: Device must be connected to a "
- "high-speed USB 2.0 port.\n");
- return -ENODEV;
- }
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL) {
- printk(KERN_ERR "%s() Unable to allocate memory\n", __func__);
- return -ENOMEM;
- }
-
- mutex_init(&dev->mutex);
- mutex_init(&dev->dvb.lock);
- dev->usbdev = usbdev;
- dev->boardnr = id->driver_info;
-
- /* Create the v4l2_device */
- retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
- if (retval) {
- printk(KERN_ERR "%s() v4l2_device_register failed\n",
- __func__);
- kfree(dev);
- return -EIO;
- }
-
- /* Power Up the bridge */
- au0828_write(dev, REG_600, 1 << 4);
-
- /* Bring up the GPIO's and supporting devices */
- au0828_gpio_setup(dev);
-
- /* I2C */
- au0828_i2c_register(dev);
-
- /* Setup */
- au0828_card_setup(dev);
-
- /* Analog TV */
- if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED)
- au0828_analog_register(dev, interface);
-
- /* Digital TV */
- au0828_dvb_register(dev);
-
- /* Store the pointer to the au0828_dev so it can be accessed in
- au0828_usb_disconnect */
- usb_set_intfdata(interface, dev);
-
- printk(KERN_INFO "Registered device AU0828 [%s]\n",
- dev->board.name == NULL ? "Unset" : dev->board.name);
-
- return 0;
-}
-
-static struct usb_driver au0828_usb_driver = {
- .name = DRIVER_NAME,
- .probe = au0828_usb_probe,
- .disconnect = au0828_usb_disconnect,
- .id_table = au0828_usb_id_table,
-};
-
-static int __init au0828_init(void)
-{
- int ret;
-
- if (au0828_debug & 1)
- printk(KERN_INFO "%s() Debugging is enabled\n", __func__);
-
- if (au0828_debug & 2)
- printk(KERN_INFO "%s() USB Debugging is enabled\n", __func__);
-
- if (au0828_debug & 4)
- printk(KERN_INFO "%s() I2C Debugging is enabled\n", __func__);
-
- if (au0828_debug & 8)
- printk(KERN_INFO "%s() Bridge Debugging is enabled\n",
- __func__);
-
- printk(KERN_INFO "au0828 driver loaded\n");
-
- ret = usb_register(&au0828_usb_driver);
- if (ret)
- printk(KERN_ERR "usb_register failed, error = %d\n", ret);
-
- return ret;
-}
-
-static void __exit au0828_exit(void)
-{
- usb_deregister(&au0828_usb_driver);
-}
-
-module_init(au0828_init);
-module_exit(au0828_exit);
-
-MODULE_DESCRIPTION("Driver for Auvitek AU0828 based products");
-MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.2");
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
deleted file mode 100644
index 39ece8e2498..00000000000
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * Driver for the Auvitek USB bridge
- *
- * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/suspend.h>
-#include <media/v4l2-common.h>
-#include <media/tuner.h>
-
-#include "au0828.h"
-#include "au8522.h"
-#include "xc5000.h"
-#include "mxl5007t.h"
-#include "tda18271.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define _AU0828_BULKPIPE 0x83
-#define _BULKPIPESIZE 0xe522
-
-static u8 hauppauge_hvr950q_led_states[] = {
- 0x00, /* off */
- 0x02, /* yellow */
- 0x04, /* green */
-};
-
-static struct au8522_led_config hauppauge_hvr950q_led_cfg = {
- .gpio_output = 0x00e0,
- .gpio_output_enable = 0x6006,
- .gpio_output_disable = 0x0660,
-
- .gpio_leds = 0x00e2,
- .led_states = hauppauge_hvr950q_led_states,
- .num_led_states = sizeof(hauppauge_hvr950q_led_states),
-
- .vsb8_strong = 20 /* dB */ * 10,
- .qam64_strong = 25 /* dB */ * 10,
- .qam256_strong = 32 /* dB */ * 10,
-};
-
-static struct au8522_config hauppauge_hvr950q_config = {
- .demod_address = 0x8e >> 1,
- .status_mode = AU8522_DEMODLOCKING,
- .qam_if = AU8522_IF_6MHZ,
- .vsb_if = AU8522_IF_6MHZ,
- .led_cfg = &hauppauge_hvr950q_led_cfg,
-};
-
-static struct au8522_config fusionhdtv7usb_config = {
- .demod_address = 0x8e >> 1,
- .status_mode = AU8522_DEMODLOCKING,
- .qam_if = AU8522_IF_6MHZ,
- .vsb_if = AU8522_IF_6MHZ,
-};
-
-static struct au8522_config hauppauge_woodbury_config = {
- .demod_address = 0x8e >> 1,
- .status_mode = AU8522_DEMODLOCKING,
- .qam_if = AU8522_IF_4MHZ,
- .vsb_if = AU8522_IF_3_25MHZ,
-};
-
-static struct xc5000_config hauppauge_xc5000a_config = {
- .i2c_address = 0x61,
- .if_khz = 6000,
- .chip_id = XC5000A,
-};
-
-static struct xc5000_config hauppauge_xc5000c_config = {
- .i2c_address = 0x61,
- .if_khz = 6000,
- .chip_id = XC5000C,
-};
-
-static struct mxl5007t_config mxl5007t_hvr950q_config = {
- .xtal_freq_hz = MxL_XTAL_24_MHZ,
- .if_freq_hz = MxL_IF_6_MHZ,
-};
-
-static struct tda18271_config hauppauge_woodbury_tunerconfig = {
- .gate = TDA18271_GATE_DIGITAL,
-};
-
-/*-------------------------------------------------------------------*/
-static void urb_completion(struct urb *purb)
-{
- struct au0828_dev *dev = purb->context;
- int ptype = usb_pipetype(purb->pipe);
-
- dprintk(2, "%s()\n", __func__);
-
- if (!dev)
- return;
-
- if (dev->urb_streaming == 0)
- return;
-
- if (ptype != PIPE_BULK) {
- printk(KERN_ERR "%s() Unsupported URB type %d\n",
- __func__, ptype);
- return;
- }
-
- /* Feed the transport payload into the kernel demux */
- dvb_dmx_swfilter_packets(&dev->dvb.demux,
- purb->transfer_buffer, purb->actual_length / 188);
-
- /* Clean the buffer before we requeue */
- memset(purb->transfer_buffer, 0, URB_BUFSIZE);
-
- /* Requeue URB */
- usb_submit_urb(purb, GFP_ATOMIC);
-}
-
-static int stop_urb_transfer(struct au0828_dev *dev)
-{
- int i;
-
- dprintk(2, "%s()\n", __func__);
-
- for (i = 0; i < URB_COUNT; i++) {
- usb_kill_urb(dev->urbs[i]);
- kfree(dev->urbs[i]->transfer_buffer);
- usb_free_urb(dev->urbs[i]);
- }
-
- dev->urb_streaming = 0;
-
- return 0;
-}
-
-static int start_urb_transfer(struct au0828_dev *dev)
-{
- struct urb *purb;
- int i, ret = -ENOMEM;
-
- dprintk(2, "%s()\n", __func__);
-
- if (dev->urb_streaming) {
- dprintk(2, "%s: bulk xfer already running!\n", __func__);
- return 0;
- }
-
- for (i = 0; i < URB_COUNT; i++) {
-
- dev->urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->urbs[i])
- goto err;
-
- purb = dev->urbs[i];
-
- purb->transfer_buffer = kzalloc(URB_BUFSIZE, GFP_KERNEL);
- if (!purb->transfer_buffer) {
- usb_free_urb(purb);
- dev->urbs[i] = NULL;
- goto err;
- }
-
- purb->status = -EINPROGRESS;
- usb_fill_bulk_urb(purb,
- dev->usbdev,
- usb_rcvbulkpipe(dev->usbdev,
- _AU0828_BULKPIPE),
- purb->transfer_buffer,
- URB_BUFSIZE,
- urb_completion,
- dev);
-
- }
-
- for (i = 0; i < URB_COUNT; i++) {
- ret = usb_submit_urb(dev->urbs[i], GFP_ATOMIC);
- if (ret != 0) {
- stop_urb_transfer(dev);
- printk(KERN_ERR "%s: failed urb submission, "
- "err = %d\n", __func__, ret);
- return ret;
- }
- }
-
- dev->urb_streaming = 1;
- ret = 0;
-
-err:
- return ret;
-}
-
-static int au0828_dvb_start_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct au0828_dev *dev = (struct au0828_dev *) demux->priv;
- struct au0828_dvb *dvb = &dev->dvb;
- int ret = 0;
-
- dprintk(1, "%s()\n", __func__);
-
- if (!demux->dmx.frontend)
- return -EINVAL;
-
- if (dvb) {
- mutex_lock(&dvb->lock);
- if (dvb->feeding++ == 0) {
- /* Start transport */
- au0828_write(dev, 0x608, 0x90);
- au0828_write(dev, 0x609, 0x72);
- au0828_write(dev, 0x60a, 0x71);
- au0828_write(dev, 0x60b, 0x01);
- ret = start_urb_transfer(dev);
- }
- mutex_unlock(&dvb->lock);
- }
-
- return ret;
-}
-
-static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct au0828_dev *dev = (struct au0828_dev *) demux->priv;
- struct au0828_dvb *dvb = &dev->dvb;
- int ret = 0;
-
- dprintk(1, "%s()\n", __func__);
-
- if (dvb) {
- mutex_lock(&dvb->lock);
- if (--dvb->feeding == 0) {
- /* Stop transport */
- au0828_write(dev, 0x608, 0x00);
- au0828_write(dev, 0x609, 0x00);
- au0828_write(dev, 0x60a, 0x00);
- au0828_write(dev, 0x60b, 0x00);
- ret = stop_urb_transfer(dev);
- }
- mutex_unlock(&dvb->lock);
- }
-
- return ret;
-}
-
-static int dvb_register(struct au0828_dev *dev)
-{
- struct au0828_dvb *dvb = &dev->dvb;
- int result;
-
- dprintk(1, "%s()\n", __func__);
-
- /* register adapter */
- result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE,
- &dev->usbdev->dev, adapter_nr);
- if (result < 0) {
- printk(KERN_ERR "%s: dvb_register_adapter failed "
- "(errno = %d)\n", DRIVER_NAME, result);
- goto fail_adapter;
- }
- dvb->adapter.priv = dev;
-
- /* register frontend */
- result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
- if (result < 0) {
- printk(KERN_ERR "%s: dvb_register_frontend failed "
- "(errno = %d)\n", DRIVER_NAME, result);
- goto fail_frontend;
- }
-
- /* register demux stuff */
- dvb->demux.dmx.capabilities =
- DMX_TS_FILTERING | DMX_SECTION_FILTERING |
- DMX_MEMORY_BASED_FILTERING;
- dvb->demux.priv = dev;
- dvb->demux.filternum = 256;
- dvb->demux.feednum = 256;
- dvb->demux.start_feed = au0828_dvb_start_feed;
- dvb->demux.stop_feed = au0828_dvb_stop_feed;
- result = dvb_dmx_init(&dvb->demux);
- if (result < 0) {
- printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n",
- DRIVER_NAME, result);
- goto fail_dmx;
- }
-
- dvb->dmxdev.filternum = 256;
- dvb->dmxdev.demux = &dvb->demux.dmx;
- dvb->dmxdev.capabilities = 0;
- result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
- if (result < 0) {
- printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n",
- DRIVER_NAME, result);
- goto fail_dmxdev;
- }
-
- dvb->fe_hw.source = DMX_FRONTEND_0;
- result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- if (result < 0) {
- printk(KERN_ERR "%s: add_frontend failed "
- "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result);
- goto fail_fe_hw;
- }
-
- dvb->fe_mem.source = DMX_MEMORY_FE;
- result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
- if (result < 0) {
- printk(KERN_ERR "%s: add_frontend failed "
- "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result);
- goto fail_fe_mem;
- }
-
- result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- if (result < 0) {
- printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n",
- DRIVER_NAME, result);
- goto fail_fe_conn;
- }
-
- /* register network adapter */
- dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
- return 0;
-
-fail_fe_conn:
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
-fail_fe_mem:
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
-fail_fe_hw:
- dvb_dmxdev_release(&dvb->dmxdev);
-fail_dmxdev:
- dvb_dmx_release(&dvb->demux);
-fail_dmx:
- dvb_unregister_frontend(dvb->frontend);
-fail_frontend:
- dvb_frontend_detach(dvb->frontend);
- dvb_unregister_adapter(&dvb->adapter);
-fail_adapter:
- return result;
-}
-
-void au0828_dvb_unregister(struct au0828_dev *dev)
-{
- struct au0828_dvb *dvb = &dev->dvb;
-
- dprintk(1, "%s()\n", __func__);
-
- if (dvb->frontend == NULL)
- return;
-
- dvb_net_release(&dvb->net);
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- dvb_dmxdev_release(&dvb->dmxdev);
- dvb_dmx_release(&dvb->demux);
- dvb_unregister_frontend(dvb->frontend);
- dvb_frontend_detach(dvb->frontend);
- dvb_unregister_adapter(&dvb->adapter);
-}
-
-/* All the DVB attach calls go here, this function get's modified
- * for each new card. No other function in this file needs
- * to change.
- */
-int au0828_dvb_register(struct au0828_dev *dev)
-{
- struct au0828_dvb *dvb = &dev->dvb;
- int ret;
-
- dprintk(1, "%s()\n", __func__);
-
- /* init frontend */
- switch (dev->boardnr) {
- case AU0828_BOARD_HAUPPAUGE_HVR850:
- case AU0828_BOARD_HAUPPAUGE_HVR950Q:
- dvb->frontend = dvb_attach(au8522_attach,
- &hauppauge_hvr950q_config,
- &dev->i2c_adap);
- if (dvb->frontend != NULL)
- switch (dev->board.tuner_type) {
- default:
- case TUNER_XC5000:
- dvb_attach(xc5000_attach, dvb->frontend,
- &dev->i2c_adap,
- &hauppauge_xc5000a_config);
- break;
- case TUNER_XC5000C:
- dvb_attach(xc5000_attach, dvb->frontend,
- &dev->i2c_adap,
- &hauppauge_xc5000c_config);
- break;
- }
- break;
- case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
- dvb->frontend = dvb_attach(au8522_attach,
- &hauppauge_hvr950q_config,
- &dev->i2c_adap);
- if (dvb->frontend != NULL)
- dvb_attach(mxl5007t_attach, dvb->frontend,
- &dev->i2c_adap, 0x60,
- &mxl5007t_hvr950q_config);
- break;
- case AU0828_BOARD_HAUPPAUGE_WOODBURY:
- dvb->frontend = dvb_attach(au8522_attach,
- &hauppauge_woodbury_config,
- &dev->i2c_adap);
- if (dvb->frontend != NULL)
- dvb_attach(tda18271_attach, dvb->frontend,
- 0x60, &dev->i2c_adap,
- &hauppauge_woodbury_tunerconfig);
- break;
- case AU0828_BOARD_DVICO_FUSIONHDTV7:
- dvb->frontend = dvb_attach(au8522_attach,
- &fusionhdtv7usb_config,
- &dev->i2c_adap);
- if (dvb->frontend != NULL) {
- dvb_attach(xc5000_attach, dvb->frontend,
- &dev->i2c_adap,
- &hauppauge_xc5000a_config);
- }
- break;
- default:
- printk(KERN_WARNING "The frontend of your DVB/ATSC card "
- "isn't supported yet\n");
- break;
- }
- if (NULL == dvb->frontend) {
- printk(KERN_ERR "%s() Frontend initialization failed\n",
- __func__);
- return -1;
- }
- /* define general-purpose callback pointer */
- dvb->frontend->callback = au0828_tuner_callback;
-
- /* register everything */
- ret = dvb_register(dev);
- if (ret < 0) {
- if (dvb->frontend->ops.release)
- dvb->frontend->ops.release(dvb->frontend);
- return ret;
- }
-
- return 0;
-}
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c
deleted file mode 100644
index 05c299fa5d7..00000000000
--- a/drivers/media/video/au0828/au0828-i2c.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Driver for the Auvitek AU0828 USB bridge
- *
- * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-
-#include "au0828.h"
-
-#include <media/v4l2-common.h>
-
-static int i2c_scan;
-module_param(i2c_scan, int, 0444);
-MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
-
-#define I2C_WAIT_DELAY 512
-#define I2C_WAIT_RETRY 64
-
-static inline int i2c_slave_did_write_ack(struct i2c_adapter *i2c_adap)
-{
- struct au0828_dev *dev = i2c_adap->algo_data;
- return au0828_read(dev, AU0828_I2C_STATUS_201) &
- AU0828_I2C_STATUS_NO_WRITE_ACK ? 0 : 1;
-}
-
-static inline int i2c_slave_did_read_ack(struct i2c_adapter *i2c_adap)
-{
- struct au0828_dev *dev = i2c_adap->algo_data;
- return au0828_read(dev, AU0828_I2C_STATUS_201) &
- AU0828_I2C_STATUS_NO_READ_ACK ? 0 : 1;
-}
-
-static int i2c_wait_read_ack(struct i2c_adapter *i2c_adap)
-{
- int count;
-
- for (count = 0; count < I2C_WAIT_RETRY; count++) {
- if (!i2c_slave_did_read_ack(i2c_adap))
- break;
- udelay(I2C_WAIT_DELAY);
- }
-
- if (I2C_WAIT_RETRY == count)
- return 0;
-
- return 1;
-}
-
-static inline int i2c_is_read_busy(struct i2c_adapter *i2c_adap)
-{
- struct au0828_dev *dev = i2c_adap->algo_data;
- return au0828_read(dev, AU0828_I2C_STATUS_201) &
- AU0828_I2C_STATUS_READ_DONE ? 0 : 1;
-}
-
-static int i2c_wait_read_done(struct i2c_adapter *i2c_adap)
-{
- int count;
-
- for (count = 0; count < I2C_WAIT_RETRY; count++) {
- if (!i2c_is_read_busy(i2c_adap))
- break;
- udelay(I2C_WAIT_DELAY);
- }
-
- if (I2C_WAIT_RETRY == count)
- return 0;
-
- return 1;
-}
-
-static inline int i2c_is_write_done(struct i2c_adapter *i2c_adap)
-{
- struct au0828_dev *dev = i2c_adap->algo_data;
- return au0828_read(dev, AU0828_I2C_STATUS_201) &
- AU0828_I2C_STATUS_WRITE_DONE ? 1 : 0;
-}
-
-static int i2c_wait_write_done(struct i2c_adapter *i2c_adap)
-{
- int count;
-
- for (count = 0; count < I2C_WAIT_RETRY; count++) {
- if (i2c_is_write_done(i2c_adap))
- break;
- udelay(I2C_WAIT_DELAY);
- }
-
- if (I2C_WAIT_RETRY == count)
- return 0;
-
- return 1;
-}
-
-static inline int i2c_is_busy(struct i2c_adapter *i2c_adap)
-{
- struct au0828_dev *dev = i2c_adap->algo_data;
- return au0828_read(dev, AU0828_I2C_STATUS_201) &
- AU0828_I2C_STATUS_BUSY ? 1 : 0;
-}
-
-static int i2c_wait_done(struct i2c_adapter *i2c_adap)
-{
- int count;
-
- for (count = 0; count < I2C_WAIT_RETRY; count++) {
- if (!i2c_is_busy(i2c_adap))
- break;
- udelay(I2C_WAIT_DELAY);
- }
-
- if (I2C_WAIT_RETRY == count)
- return 0;
-
- return 1;
-}
-
-/* FIXME: Implement join handling correctly */
-static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
- const struct i2c_msg *msg, int joined_rlen)
-{
- int i, strobe = 0;
- struct au0828_dev *dev = i2c_adap->algo_data;
-
- dprintk(4, "%s()\n", __func__);
-
- au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
-
- /* Set the I2C clock */
- au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
- dev->board.i2c_clk_divider);
-
- /* Hardware needs 8 bit addresses */
- au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);
-
- dprintk(4, "SEND: %02x\n", msg->addr);
-
- /* Deal with i2c_scan */
- if (msg->len == 0) {
- /* The analog tuner detection code makes use of the SMBUS_QUICK
- message (which involves a zero length i2c write). To avoid
- checking the status register when we didn't strobe out any
- actual bytes to the bus, just do a read check. This is
- consistent with how I saw i2c device checking done in the
- USB trace of the Windows driver */
- au0828_write(dev, AU0828_I2C_TRIGGER_200,
- AU0828_I2C_TRIGGER_READ);
-
- if (!i2c_wait_done(i2c_adap))
- return -EIO;
-
- if (i2c_wait_read_ack(i2c_adap))
- return -EIO;
-
- return 0;
- }
-
- for (i = 0; i < msg->len;) {
-
- dprintk(4, " %02x\n", msg->buf[i]);
-
- au0828_write(dev, AU0828_I2C_WRITE_FIFO_205, msg->buf[i]);
-
- strobe++;
- i++;
-
- if ((strobe >= 4) || (i >= msg->len)) {
-
- /* Strobe the byte into the bus */
- if (i < msg->len)
- au0828_write(dev, AU0828_I2C_TRIGGER_200,
- AU0828_I2C_TRIGGER_WRITE |
- AU0828_I2C_TRIGGER_HOLD);
- else
- au0828_write(dev, AU0828_I2C_TRIGGER_200,
- AU0828_I2C_TRIGGER_WRITE);
-
- /* Reset strobe trigger */
- strobe = 0;
-
- if (!i2c_wait_write_done(i2c_adap))
- return -EIO;
-
- }
-
- }
- if (!i2c_wait_done(i2c_adap))
- return -EIO;
-
- dprintk(4, "\n");
-
- return msg->len;
-}
-
-/* FIXME: Implement join handling correctly */
-static int i2c_readbytes(struct i2c_adapter *i2c_adap,
- const struct i2c_msg *msg, int joined)
-{
- struct au0828_dev *dev = i2c_adap->algo_data;
- int i;
-
- dprintk(4, "%s()\n", __func__);
-
- au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
-
- /* Set the I2C clock */
- au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
- dev->board.i2c_clk_divider);
-
- /* Hardware needs 8 bit addresses */
- au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);
-
- dprintk(4, " RECV:\n");
-
- /* Deal with i2c_scan */
- if (msg->len == 0) {
- au0828_write(dev, AU0828_I2C_TRIGGER_200,
- AU0828_I2C_TRIGGER_READ);
-
- if (i2c_wait_read_ack(i2c_adap))
- return -EIO;
- return 0;
- }
-
- for (i = 0; i < msg->len;) {
-
- i++;
-
- if (i < msg->len)
- au0828_write(dev, AU0828_I2C_TRIGGER_200,
- AU0828_I2C_TRIGGER_READ |
- AU0828_I2C_TRIGGER_HOLD);
- else
- au0828_write(dev, AU0828_I2C_TRIGGER_200,
- AU0828_I2C_TRIGGER_READ);
-
- if (!i2c_wait_read_done(i2c_adap))
- return -EIO;
-
- msg->buf[i-1] = au0828_read(dev, AU0828_I2C_READ_FIFO_209) &
- 0xff;
-
- dprintk(4, " %02x\n", msg->buf[i-1]);
- }
- if (!i2c_wait_done(i2c_adap))
- return -EIO;
-
- dprintk(4, "\n");
-
- return msg->len;
-}
-
-static int i2c_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg *msgs, int num)
-{
- int i, retval = 0;
-
- dprintk(4, "%s(num = %d)\n", __func__, num);
-
- for (i = 0; i < num; i++) {
- dprintk(4, "%s(num = %d) addr = 0x%02x len = 0x%x\n",
- __func__, num, msgs[i].addr, msgs[i].len);
- if (msgs[i].flags & I2C_M_RD) {
- /* read */
- retval = i2c_readbytes(i2c_adap, &msgs[i], 0);
- } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
- msgs[i].addr == msgs[i + 1].addr) {
- /* write then read from same address */
- retval = i2c_sendbytes(i2c_adap, &msgs[i],
- msgs[i + 1].len);
- if (retval < 0)
- goto err;
- i++;
- retval = i2c_readbytes(i2c_adap, &msgs[i], 1);
- } else {
- /* write */
- retval = i2c_sendbytes(i2c_adap, &msgs[i], 0);
- }
- if (retval < 0)
- goto err;
- }
- return num;
-
-err:
- return retval;
-}
-
-static u32 au0828_functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm au0828_i2c_algo_template = {
- .master_xfer = i2c_xfer,
- .functionality = au0828_functionality,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static struct i2c_adapter au0828_i2c_adap_template = {
- .name = DRIVER_NAME,
- .owner = THIS_MODULE,
- .algo = &au0828_i2c_algo_template,
-};
-
-static struct i2c_client au0828_i2c_client_template = {
- .name = "au0828 internal",
-};
-
-static char *i2c_devs[128] = {
- [0x8e >> 1] = "au8522",
- [0xa0 >> 1] = "eeprom",
- [0xc2 >> 1] = "tuner/xc5000",
-};
-
-static void do_i2c_scan(char *name, struct i2c_client *c)
-{
- unsigned char buf;
- int i, rc;
-
- for (i = 0; i < 128; i++) {
- c->addr = i;
- rc = i2c_master_recv(c, &buf, 0);
- if (rc < 0)
- continue;
- printk(KERN_INFO "%s: i2c scan: found device @ 0x%x [%s]\n",
- name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
- }
-}
-
-/* init + register i2c adapter */
-int au0828_i2c_register(struct au0828_dev *dev)
-{
- dprintk(1, "%s()\n", __func__);
-
- memcpy(&dev->i2c_adap, &au0828_i2c_adap_template,
- sizeof(dev->i2c_adap));
- memcpy(&dev->i2c_algo, &au0828_i2c_algo_template,
- sizeof(dev->i2c_algo));
- memcpy(&dev->i2c_client, &au0828_i2c_client_template,
- sizeof(dev->i2c_client));
-
- dev->i2c_adap.dev.parent = &dev->usbdev->dev;
-
- strlcpy(dev->i2c_adap.name, DRIVER_NAME,
- sizeof(dev->i2c_adap.name));
-
- dev->i2c_adap.algo = &dev->i2c_algo;
- dev->i2c_adap.algo_data = dev;
- i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
- i2c_add_adapter(&dev->i2c_adap);
-
- dev->i2c_client.adapter = &dev->i2c_adap;
-
- if (0 == dev->i2c_rc) {
- printk(KERN_INFO "%s: i2c bus registered\n", DRIVER_NAME);
- if (i2c_scan)
- do_i2c_scan(DRIVER_NAME, &dev->i2c_client);
- } else
- printk(KERN_INFO "%s: i2c bus register FAILED\n", DRIVER_NAME);
-
- return dev->i2c_rc;
-}
-
-int au0828_i2c_unregister(struct au0828_dev *dev)
-{
- i2c_del_adapter(&dev->i2c_adap);
- return 0;
-}
-
diff --git a/drivers/media/video/au0828/au0828-reg.h b/drivers/media/video/au0828/au0828-reg.h
deleted file mode 100644
index c39f3d2b721..00000000000
--- a/drivers/media/video/au0828/au0828-reg.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Driver for the Auvitek USB bridge
- *
- * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* We'll start to rename these registers once we have a better
- * understanding of their meaning.
- */
-#define REG_000 0x000
-#define REG_001 0x001
-#define REG_002 0x002
-#define REG_003 0x003
-
-#define AU0828_SENSORCTRL_100 0x100
-#define AU0828_SENSORCTRL_VBI_103 0x103
-
-/* I2C registers */
-#define AU0828_I2C_TRIGGER_200 0x200
-#define AU0828_I2C_STATUS_201 0x201
-#define AU0828_I2C_CLK_DIVIDER_202 0x202
-#define AU0828_I2C_DEST_ADDR_203 0x203
-#define AU0828_I2C_WRITE_FIFO_205 0x205
-#define AU0828_I2C_READ_FIFO_209 0x209
-#define AU0828_I2C_MULTIBYTE_MODE_2FF 0x2ff
-
-/* Audio registers */
-#define AU0828_AUDIOCTRL_50C 0x50C
-
-#define REG_600 0x600
-
-/*********************************************************************/
-/* Here are constants for values associated with the above registers */
-
-/* I2C Trigger (Reg 0x200) */
-#define AU0828_I2C_TRIGGER_WRITE 0x01
-#define AU0828_I2C_TRIGGER_READ 0x20
-#define AU0828_I2C_TRIGGER_HOLD 0x40
-
-/* I2C Status (Reg 0x201) */
-#define AU0828_I2C_STATUS_READ_DONE 0x01
-#define AU0828_I2C_STATUS_NO_READ_ACK 0x02
-#define AU0828_I2C_STATUS_WRITE_DONE 0x04
-#define AU0828_I2C_STATUS_NO_WRITE_ACK 0x08
-#define AU0828_I2C_STATUS_BUSY 0x10
-
-/* I2C Clock Divider (Reg 0x202) */
-#define AU0828_I2C_CLK_250KHZ 0x07
-#define AU0828_I2C_CLK_100KHZ 0x14
-#define AU0828_I2C_CLK_30KHZ 0x40
diff --git a/drivers/media/video/au0828/au0828-vbi.c b/drivers/media/video/au0828/au0828-vbi.c
deleted file mode 100644
index 63f593070ee..00000000000
--- a/drivers/media/video/au0828/au0828-vbi.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- au0828-vbi.c - VBI driver for au0828
-
- Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
-
- This work was sponsored by GetWellNetwork Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-
-#include "au0828.h"
-
-static unsigned int vbibufs = 5;
-module_param(vbibufs, int, 0644);
-MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32");
-
-/* ------------------------------------------------------------------ */
-
-static void
-free_buffer(struct videobuf_queue *vq, struct au0828_buffer *buf)
-{
- struct au0828_fh *fh = vq->priv_data;
- struct au0828_dev *dev = fh->dev;
- unsigned long flags = 0;
- if (in_interrupt())
- BUG();
-
- /* We used to wait for the buffer to finish here, but this didn't work
- because, as we were keeping the state as VIDEOBUF_QUEUED,
- videobuf_queue_cancel marked it as finished for us.
- (Also, it could wedge forever if the hardware was misconfigured.)
-
- This should be safe; by the time we get here, the buffer isn't
- queued anymore. If we ever start marking the buffers as
- VIDEOBUF_ACTIVE, it won't be, though.
- */
- spin_lock_irqsave(&dev->slock, flags);
- if (dev->isoc_ctl.vbi_buf == buf)
- dev->isoc_ctl.vbi_buf = NULL;
- spin_unlock_irqrestore(&dev->slock, flags);
-
- videobuf_vmalloc_free(&buf->vb);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int
-vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
-{
- struct au0828_fh *fh = q->priv_data;
- struct au0828_dev *dev = fh->dev;
-
- *size = dev->vbi_width * dev->vbi_height * 2;
-
- if (0 == *count)
- *count = vbibufs;
- if (*count < 2)
- *count = 2;
- if (*count > 32)
- *count = 32;
- return 0;
-}
-
-static int
-vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct au0828_fh *fh = q->priv_data;
- struct au0828_dev *dev = fh->dev;
- struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
- int rc = 0;
-
- buf->vb.size = dev->vbi_width * dev->vbi_height * 2;
-
- if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
- return -EINVAL;
-
- buf->vb.width = dev->vbi_width;
- buf->vb.height = dev->vbi_height;
- buf->vb.field = field;
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- rc = videobuf_iolock(q, &buf->vb, NULL);
- if (rc < 0)
- goto fail;
- }
-
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
-fail:
- free_buffer(q, buf);
- return rc;
-}
-
-static void
-vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct au0828_buffer *buf = container_of(vb,
- struct au0828_buffer,
- vb);
- struct au0828_fh *fh = vq->priv_data;
- struct au0828_dev *dev = fh->dev;
- struct au0828_dmaqueue *vbiq = &dev->vbiq;
-
- buf->vb.state = VIDEOBUF_QUEUED;
- list_add_tail(&buf->vb.queue, &vbiq->active);
-}
-
-static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
- free_buffer(q, buf);
-}
-
-struct videobuf_queue_ops au0828_vbi_qops = {
- .buf_setup = vbi_setup,
- .buf_prepare = vbi_prepare,
- .buf_queue = vbi_queue,
- .buf_release = vbi_release,
-};
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
deleted file mode 100644
index ac3dd733ab8..00000000000
--- a/drivers/media/video/au0828/au0828-video.c
+++ /dev/null
@@ -1,1998 +0,0 @@
-/*
- * Auvitek AU0828 USB Bridge (Analog video support)
- *
- * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
- * Copyright (C) 2005-2008 Auvitek International, Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * As published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/* Developer Notes:
- *
- * VBI support is not yet working
- * The hardware scaler supported is unimplemented
- * AC97 audio support is unimplemented (only i2s audio mode)
- *
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/suspend.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/tuner.h>
-#include "au0828.h"
-#include "au0828-reg.h"
-
-static DEFINE_MUTEX(au0828_sysfs_lock);
-
-/* ------------------------------------------------------------------
- Videobuf operations
- ------------------------------------------------------------------*/
-
-static unsigned int isoc_debug;
-module_param(isoc_debug, int, 0644);
-MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
-
-#define au0828_isocdbg(fmt, arg...) \
-do {\
- if (isoc_debug) { \
- printk(KERN_INFO "au0828 %s :"fmt, \
- __func__ , ##arg); \
- } \
- } while (0)
-
-static inline void print_err_status(struct au0828_dev *dev,
- int packet, int status)
-{
- char *errmsg = "Unknown";
-
- switch (status) {
- case -ENOENT:
- errmsg = "unlinked synchronuously";
- break;
- case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
- break;
- case -ENOSR:
- errmsg = "Buffer error (overrun)";
- break;
- case -EPIPE:
- errmsg = "Stalled (device not responding)";
- break;
- case -EOVERFLOW:
- errmsg = "Babble (bad cable?)";
- break;
- case -EPROTO:
- errmsg = "Bit-stuff error (bad cable?)";
- break;
- case -EILSEQ:
- errmsg = "CRC/Timeout (could be anything)";
- break;
- case -ETIME:
- errmsg = "Device does not respond";
- break;
- }
- if (packet < 0) {
- au0828_isocdbg("URB status %d [%s].\n", status, errmsg);
- } else {
- au0828_isocdbg("URB packet %d, status %d [%s].\n",
- packet, status, errmsg);
- }
-}
-
-static int check_dev(struct au0828_dev *dev)
-{
- if (dev->dev_state & DEV_DISCONNECTED) {
- printk(KERN_INFO "v4l2 ioctl: device not present\n");
- return -ENODEV;
- }
-
- if (dev->dev_state & DEV_MISCONFIGURED) {
- printk(KERN_INFO "v4l2 ioctl: device is misconfigured; "
- "close and open it again\n");
- return -EIO;
- }
- return 0;
-}
-
-/*
- * IRQ callback, called by URB callback
- */
-static void au0828_irq_callback(struct urb *urb)
-{
- struct au0828_dmaqueue *dma_q = urb->context;
- struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
- unsigned long flags = 0;
- int i;
-
- switch (urb->status) {
- case 0: /* success */
- case -ETIMEDOUT: /* NAK */
- break;
- case -ECONNRESET: /* kill */
- case -ENOENT:
- case -ESHUTDOWN:
- au0828_isocdbg("au0828_irq_callback called: status kill\n");
- return;
- default: /* unknown error */
- au0828_isocdbg("urb completition error %d.\n", urb->status);
- break;
- }
-
- /* Copy data from URB */
- spin_lock_irqsave(&dev->slock, flags);
- dev->isoc_ctl.isoc_copy(dev, urb);
- spin_unlock_irqrestore(&dev->slock, flags);
-
- /* Reset urb buffers */
- for (i = 0; i < urb->number_of_packets; i++) {
- urb->iso_frame_desc[i].status = 0;
- urb->iso_frame_desc[i].actual_length = 0;
- }
- urb->status = 0;
-
- urb->status = usb_submit_urb(urb, GFP_ATOMIC);
- if (urb->status) {
- au0828_isocdbg("urb resubmit failed (error=%i)\n",
- urb->status);
- }
-}
-
-/*
- * Stop and Deallocate URBs
- */
-void au0828_uninit_isoc(struct au0828_dev *dev)
-{
- struct urb *urb;
- int i;
-
- au0828_isocdbg("au0828: called au0828_uninit_isoc\n");
-
- dev->isoc_ctl.nfields = -1;
- for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
- urb = dev->isoc_ctl.urb[i];
- if (urb) {
- if (!irqs_disabled())
- usb_kill_urb(urb);
- else
- usb_unlink_urb(urb);
-
- if (dev->isoc_ctl.transfer_buffer[i]) {
- usb_free_coherent(dev->usbdev,
- urb->transfer_buffer_length,
- dev->isoc_ctl.transfer_buffer[i],
- urb->transfer_dma);
- }
- usb_free_urb(urb);
- dev->isoc_ctl.urb[i] = NULL;
- }
- dev->isoc_ctl.transfer_buffer[i] = NULL;
- }
-
- kfree(dev->isoc_ctl.urb);
- kfree(dev->isoc_ctl.transfer_buffer);
-
- dev->isoc_ctl.urb = NULL;
- dev->isoc_ctl.transfer_buffer = NULL;
- dev->isoc_ctl.num_bufs = 0;
-}
-
-/*
- * Allocate URBs and start IRQ
- */
-int au0828_init_isoc(struct au0828_dev *dev, int max_packets,
- int num_bufs, int max_pkt_size,
- int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb))
-{
- struct au0828_dmaqueue *dma_q = &dev->vidq;
- int i;
- int sb_size, pipe;
- struct urb *urb;
- int j, k;
- int rc;
-
- au0828_isocdbg("au0828: called au0828_prepare_isoc\n");
-
- /* De-allocates all pending stuff */
- au0828_uninit_isoc(dev);
-
- dev->isoc_ctl.isoc_copy = isoc_copy;
- dev->isoc_ctl.num_bufs = num_bufs;
-
- dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
- if (!dev->isoc_ctl.urb) {
- au0828_isocdbg("cannot alloc memory for usb buffers\n");
- return -ENOMEM;
- }
-
- dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
- GFP_KERNEL);
- if (!dev->isoc_ctl.transfer_buffer) {
- au0828_isocdbg("cannot allocate memory for usb transfer\n");
- kfree(dev->isoc_ctl.urb);
- return -ENOMEM;
- }
-
- dev->isoc_ctl.max_pkt_size = max_pkt_size;
- dev->isoc_ctl.buf = NULL;
-
- sb_size = max_packets * dev->isoc_ctl.max_pkt_size;
-
- /* allocate urbs and transfer buffers */
- for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
- urb = usb_alloc_urb(max_packets, GFP_KERNEL);
- if (!urb) {
- au0828_isocdbg("cannot alloc isoc_ctl.urb %i\n", i);
- au0828_uninit_isoc(dev);
- return -ENOMEM;
- }
- dev->isoc_ctl.urb[i] = urb;
-
- dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->usbdev,
- sb_size, GFP_KERNEL, &urb->transfer_dma);
- if (!dev->isoc_ctl.transfer_buffer[i]) {
- printk("unable to allocate %i bytes for transfer"
- " buffer %i%s\n",
- sb_size, i,
- in_interrupt() ? " while in int" : "");
- au0828_uninit_isoc(dev);
- return -ENOMEM;
- }
- memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
-
- pipe = usb_rcvisocpipe(dev->usbdev,
- dev->isoc_in_endpointaddr),
-
- usb_fill_int_urb(urb, dev->usbdev, pipe,
- dev->isoc_ctl.transfer_buffer[i], sb_size,
- au0828_irq_callback, dma_q, 1);
-
- urb->number_of_packets = max_packets;
- urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
-
- k = 0;
- for (j = 0; j < max_packets; j++) {
- urb->iso_frame_desc[j].offset = k;
- urb->iso_frame_desc[j].length =
- dev->isoc_ctl.max_pkt_size;
- k += dev->isoc_ctl.max_pkt_size;
- }
- }
-
- init_waitqueue_head(&dma_q->wq);
-
- /* submit urbs and enables IRQ */
- for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
- rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
- if (rc) {
- au0828_isocdbg("submit of urb %i failed (error=%i)\n",
- i, rc);
- au0828_uninit_isoc(dev);
- return rc;
- }
- }
-
- return 0;
-}
-
-/*
- * Announces that a buffer were filled and request the next
- */
-static inline void buffer_filled(struct au0828_dev *dev,
- struct au0828_dmaqueue *dma_q,
- struct au0828_buffer *buf)
-{
- /* Advice that buffer was filled */
- au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
-
- buf->vb.state = VIDEOBUF_DONE;
- buf->vb.field_count++;
- do_gettimeofday(&buf->vb.ts);
-
- dev->isoc_ctl.buf = NULL;
-
- list_del(&buf->vb.queue);
- wake_up(&buf->vb.done);
-}
-
-static inline void vbi_buffer_filled(struct au0828_dev *dev,
- struct au0828_dmaqueue *dma_q,
- struct au0828_buffer *buf)
-{
- /* Advice that buffer was filled */
- au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
-
- buf->vb.state = VIDEOBUF_DONE;
- buf->vb.field_count++;
- do_gettimeofday(&buf->vb.ts);
-
- dev->isoc_ctl.vbi_buf = NULL;
-
- list_del(&buf->vb.queue);
- wake_up(&buf->vb.done);
-}
-
-/*
- * Identify the buffer header type and properly handles
- */
-static void au0828_copy_video(struct au0828_dev *dev,
- struct au0828_dmaqueue *dma_q,
- struct au0828_buffer *buf,
- unsigned char *p,
- unsigned char *outp, unsigned long len)
-{
- void *fieldstart, *startwrite, *startread;
- int linesdone, currlinedone, offset, lencopy, remain;
- int bytesperline = dev->width << 1; /* Assumes 16-bit depth @@@@ */
-
- if (len == 0)
- return;
-
- if (dma_q->pos + len > buf->vb.size)
- len = buf->vb.size - dma_q->pos;
-
- startread = p;
- remain = len;
-
- /* Interlaces frame */
- if (buf->top_field)
- fieldstart = outp;
- else
- fieldstart = outp + bytesperline;
-
- linesdone = dma_q->pos / bytesperline;
- currlinedone = dma_q->pos % bytesperline;
- offset = linesdone * bytesperline * 2 + currlinedone;
- startwrite = fieldstart + offset;
- lencopy = bytesperline - currlinedone;
- lencopy = lencopy > remain ? remain : lencopy;
-
- if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
- au0828_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
- ((char *)startwrite + lencopy) -
- ((char *)outp + buf->vb.size));
- remain = (char *)outp + buf->vb.size - (char *)startwrite;
- lencopy = remain;
- }
- if (lencopy <= 0)
- return;
- memcpy(startwrite, startread, lencopy);
-
- remain -= lencopy;
-
- while (remain > 0) {
- startwrite += lencopy + bytesperline;
- startread += lencopy;
- if (bytesperline > remain)
- lencopy = remain;
- else
- lencopy = bytesperline;
-
- if ((char *)startwrite + lencopy > (char *)outp +
- buf->vb.size) {
- au0828_isocdbg("Overflow %zi bytes past buf end (2)\n",
- ((char *)startwrite + lencopy) -
- ((char *)outp + buf->vb.size));
- lencopy = remain = (char *)outp + buf->vb.size -
- (char *)startwrite;
- }
- if (lencopy <= 0)
- break;
-
- memcpy(startwrite, startread, lencopy);
-
- remain -= lencopy;
- }
-
- if (offset > 1440) {
- /* We have enough data to check for greenscreen */
- if (outp[0] < 0x60 && outp[1440] < 0x60)
- dev->greenscreen_detected = 1;
- }
-
- dma_q->pos += len;
-}
-
-/*
- * video-buf generic routine to get the next available buffer
- */
-static inline void get_next_buf(struct au0828_dmaqueue *dma_q,
- struct au0828_buffer **buf)
-{
- struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
-
- if (list_empty(&dma_q->active)) {
- au0828_isocdbg("No active queue to serve\n");
- dev->isoc_ctl.buf = NULL;
- *buf = NULL;
- return;
- }
-
- /* Get the next buffer */
- *buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue);
- dev->isoc_ctl.buf = *buf;
-
- return;
-}
-
-static void au0828_copy_vbi(struct au0828_dev *dev,
- struct au0828_dmaqueue *dma_q,
- struct au0828_buffer *buf,
- unsigned char *p,
- unsigned char *outp, unsigned long len)
-{
- unsigned char *startwrite, *startread;
- int bytesperline;
- int i, j = 0;
-
- if (dev == NULL) {
- au0828_isocdbg("dev is null\n");
- return;
- }
-
- if (dma_q == NULL) {
- au0828_isocdbg("dma_q is null\n");
- return;
- }
- if (buf == NULL)
- return;
- if (p == NULL) {
- au0828_isocdbg("p is null\n");
- return;
- }
- if (outp == NULL) {
- au0828_isocdbg("outp is null\n");
- return;
- }
-
- bytesperline = dev->vbi_width;
-
- if (dma_q->pos + len > buf->vb.size)
- len = buf->vb.size - dma_q->pos;
-
- startread = p;
- startwrite = outp + (dma_q->pos / 2);
-
- /* Make sure the bottom field populates the second half of the frame */
- if (buf->top_field == 0)
- startwrite += bytesperline * dev->vbi_height;
-
- for (i = 0; i < len; i += 2)
- startwrite[j++] = startread[i+1];
-
- dma_q->pos += len;
-}
-
-
-/*
- * video-buf generic routine to get the next available VBI buffer
- */
-static inline void vbi_get_next_buf(struct au0828_dmaqueue *dma_q,
- struct au0828_buffer **buf)
-{
- struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vbiq);
- char *outp;
-
- if (list_empty(&dma_q->active)) {
- au0828_isocdbg("No active queue to serve\n");
- dev->isoc_ctl.vbi_buf = NULL;
- *buf = NULL;
- return;
- }
-
- /* Get the next buffer */
- *buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue);
- /* Cleans up buffer - Useful for testing for frame/URB loss */
- outp = videobuf_to_vmalloc(&(*buf)->vb);
- memset(outp, 0x00, (*buf)->vb.size);
-
- dev->isoc_ctl.vbi_buf = *buf;
-
- return;
-}
-
-/*
- * Controls the isoc copy of each urb packet
- */
-static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
-{
- struct au0828_buffer *buf;
- struct au0828_buffer *vbi_buf;
- struct au0828_dmaqueue *dma_q = urb->context;
- struct au0828_dmaqueue *vbi_dma_q = &dev->vbiq;
- unsigned char *outp = NULL;
- unsigned char *vbioutp = NULL;
- int i, len = 0, rc = 1;
- unsigned char *p;
- unsigned char fbyte;
- unsigned int vbi_field_size;
- unsigned int remain, lencopy;
-
- if (!dev)
- return 0;
-
- if ((dev->dev_state & DEV_DISCONNECTED) ||
- (dev->dev_state & DEV_MISCONFIGURED))
- return 0;
-
- if (urb->status < 0) {
- print_err_status(dev, -1, urb->status);
- if (urb->status == -ENOENT)
- return 0;
- }
-
- buf = dev->isoc_ctl.buf;
- if (buf != NULL)
- outp = videobuf_to_vmalloc(&buf->vb);
-
- vbi_buf = dev->isoc_ctl.vbi_buf;
- if (vbi_buf != NULL)
- vbioutp = videobuf_to_vmalloc(&vbi_buf->vb);
-
- for (i = 0; i < urb->number_of_packets; i++) {
- int status = urb->iso_frame_desc[i].status;
-
- if (status < 0) {
- print_err_status(dev, i, status);
- if (urb->iso_frame_desc[i].status != -EPROTO)
- continue;
- }
-
- if (urb->iso_frame_desc[i].actual_length <= 0)
- continue;
-
- if (urb->iso_frame_desc[i].actual_length >
- dev->max_pkt_size) {
- au0828_isocdbg("packet bigger than packet size");
- continue;
- }
-
- p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
- fbyte = p[0];
- len = urb->iso_frame_desc[i].actual_length - 4;
- p += 4;
-
- if (fbyte & 0x80) {
- len -= 4;
- p += 4;
- au0828_isocdbg("Video frame %s\n",
- (fbyte & 0x40) ? "odd" : "even");
- if (fbyte & 0x40) {
- /* VBI */
- if (vbi_buf != NULL)
- vbi_buffer_filled(dev,
- vbi_dma_q,
- vbi_buf);
- vbi_get_next_buf(vbi_dma_q, &vbi_buf);
- if (vbi_buf == NULL)
- vbioutp = NULL;
- else
- vbioutp = videobuf_to_vmalloc(
- &vbi_buf->vb);
-
- /* Video */
- if (buf != NULL)
- buffer_filled(dev, dma_q, buf);
- get_next_buf(dma_q, &buf);
- if (buf == NULL)
- outp = NULL;
- else
- outp = videobuf_to_vmalloc(&buf->vb);
-
- /* As long as isoc traffic is arriving, keep
- resetting the timer */
- if (dev->vid_timeout_running)
- mod_timer(&dev->vid_timeout,
- jiffies + (HZ / 10));
- if (dev->vbi_timeout_running)
- mod_timer(&dev->vbi_timeout,
- jiffies + (HZ / 10));
- }
-
- if (buf != NULL) {
- if (fbyte & 0x40)
- buf->top_field = 1;
- else
- buf->top_field = 0;
- }
-
- if (vbi_buf != NULL) {
- if (fbyte & 0x40)
- vbi_buf->top_field = 1;
- else
- vbi_buf->top_field = 0;
- }
-
- dev->vbi_read = 0;
- vbi_dma_q->pos = 0;
- dma_q->pos = 0;
- }
-
- vbi_field_size = dev->vbi_width * dev->vbi_height * 2;
- if (dev->vbi_read < vbi_field_size) {
- remain = vbi_field_size - dev->vbi_read;
- if (len < remain)
- lencopy = len;
- else
- lencopy = remain;
-
- if (vbi_buf != NULL)
- au0828_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
- vbioutp, len);
-
- len -= lencopy;
- p += lencopy;
- dev->vbi_read += lencopy;
- }
-
- if (dev->vbi_read >= vbi_field_size && buf != NULL)
- au0828_copy_video(dev, dma_q, buf, p, outp, len);
- }
- return rc;
-}
-
-static int
-buffer_setup(struct videobuf_queue *vq, unsigned int *count,
- unsigned int *size)
-{
- struct au0828_fh *fh = vq->priv_data;
- *size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
-
- if (0 == *count)
- *count = AU0828_DEF_BUF;
-
- if (*count < AU0828_MIN_BUF)
- *count = AU0828_MIN_BUF;
- return 0;
-}
-
-/* This is called *without* dev->slock held; please keep it that way */
-static void free_buffer(struct videobuf_queue *vq, struct au0828_buffer *buf)
-{
- struct au0828_fh *fh = vq->priv_data;
- struct au0828_dev *dev = fh->dev;
- unsigned long flags = 0;
- if (in_interrupt())
- BUG();
-
- /* We used to wait for the buffer to finish here, but this didn't work
- because, as we were keeping the state as VIDEOBUF_QUEUED,
- videobuf_queue_cancel marked it as finished for us.
- (Also, it could wedge forever if the hardware was misconfigured.)
-
- This should be safe; by the time we get here, the buffer isn't
- queued anymore. If we ever start marking the buffers as
- VIDEOBUF_ACTIVE, it won't be, though.
- */
- spin_lock_irqsave(&dev->slock, flags);
- if (dev->isoc_ctl.buf == buf)
- dev->isoc_ctl.buf = NULL;
- spin_unlock_irqrestore(&dev->slock, flags);
-
- videobuf_vmalloc_free(&buf->vb);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int
-buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct au0828_fh *fh = vq->priv_data;
- struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
- struct au0828_dev *dev = fh->dev;
- int rc = 0, urb_init = 0;
-
- buf->vb.size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
-
- if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
- return -EINVAL;
-
- buf->vb.width = dev->width;
- buf->vb.height = dev->height;
- buf->vb.field = field;
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- rc = videobuf_iolock(vq, &buf->vb, NULL);
- if (rc < 0) {
- printk(KERN_INFO "videobuf_iolock failed\n");
- goto fail;
- }
- }
-
- if (!dev->isoc_ctl.num_bufs)
- urb_init = 1;
-
- if (urb_init) {
- rc = au0828_init_isoc(dev, AU0828_ISO_PACKETS_PER_URB,
- AU0828_MAX_ISO_BUFS, dev->max_pkt_size,
- au0828_isoc_copy);
- if (rc < 0) {
- printk(KERN_INFO "au0828_init_isoc failed\n");
- goto fail;
- }
- }
-
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
-fail:
- free_buffer(vq, buf);
- return rc;
-}
-
-static void
-buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct au0828_buffer *buf = container_of(vb,
- struct au0828_buffer,
- vb);
- struct au0828_fh *fh = vq->priv_data;
- struct au0828_dev *dev = fh->dev;
- struct au0828_dmaqueue *vidq = &dev->vidq;
-
- buf->vb.state = VIDEOBUF_QUEUED;
- list_add_tail(&buf->vb.queue, &vidq->active);
-}
-
-static void buffer_release(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct au0828_buffer *buf = container_of(vb,
- struct au0828_buffer,
- vb);
-
- free_buffer(vq, buf);
-}
-
-static struct videobuf_queue_ops au0828_video_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-/* ------------------------------------------------------------------
- V4L2 interface
- ------------------------------------------------------------------*/
-
-static int au0828_i2s_init(struct au0828_dev *dev)
-{
- /* Enable i2s mode */
- au0828_writereg(dev, AU0828_AUDIOCTRL_50C, 0x01);
- return 0;
-}
-
-/*
- * Auvitek au0828 analog stream enable
- * Please set interface0 to AS5 before enable the stream
- */
-int au0828_analog_stream_enable(struct au0828_dev *d)
-{
- dprintk(1, "au0828_analog_stream_enable called\n");
- au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
- au0828_writereg(d, 0x106, 0x00);
- /* set x position */
- au0828_writereg(d, 0x110, 0x00);
- au0828_writereg(d, 0x111, 0x00);
- au0828_writereg(d, 0x114, 0xa0);
- au0828_writereg(d, 0x115, 0x05);
- /* set y position */
- au0828_writereg(d, 0x112, 0x00);
- au0828_writereg(d, 0x113, 0x00);
- au0828_writereg(d, 0x116, 0xf2);
- au0828_writereg(d, 0x117, 0x00);
- au0828_writereg(d, AU0828_SENSORCTRL_100, 0xb3);
-
- return 0;
-}
-
-int au0828_analog_stream_disable(struct au0828_dev *d)
-{
- dprintk(1, "au0828_analog_stream_disable called\n");
- au0828_writereg(d, AU0828_SENSORCTRL_100, 0x0);
- return 0;
-}
-
-void au0828_analog_stream_reset(struct au0828_dev *dev)
-{
- dprintk(1, "au0828_analog_stream_reset called\n");
- au0828_writereg(dev, AU0828_SENSORCTRL_100, 0x0);
- mdelay(30);
- au0828_writereg(dev, AU0828_SENSORCTRL_100, 0xb3);
-}
-
-/*
- * Some operations needs to stop current streaming
- */
-static int au0828_stream_interrupt(struct au0828_dev *dev)
-{
- int ret = 0;
-
- dev->stream_state = STREAM_INTERRUPT;
- if (dev->dev_state == DEV_DISCONNECTED)
- return -ENODEV;
- else if (ret) {
- dev->dev_state = DEV_MISCONFIGURED;
- dprintk(1, "%s device is misconfigured!\n", __func__);
- return ret;
- }
- return 0;
-}
-
-/*
- * au0828_release_resources
- * unregister v4l2 devices
- */
-void au0828_analog_unregister(struct au0828_dev *dev)
-{
- dprintk(1, "au0828_release_resources called\n");
- mutex_lock(&au0828_sysfs_lock);
-
- if (dev->vdev)
- video_unregister_device(dev->vdev);
- if (dev->vbi_dev)
- video_unregister_device(dev->vbi_dev);
-
- mutex_unlock(&au0828_sysfs_lock);
-}
-
-
-/* Usage lock check functions */
-static int res_get(struct au0828_fh *fh, unsigned int bit)
-{
- struct au0828_dev *dev = fh->dev;
-
- if (fh->resources & bit)
- /* have it already allocated */
- return 1;
-
- /* is it free? */
- mutex_lock(&dev->lock);
- if (dev->resources & bit) {
- /* no, someone else uses it */
- mutex_unlock(&dev->lock);
- return 0;
- }
- /* it's free, grab it */
- fh->resources |= bit;
- dev->resources |= bit;
- dprintk(1, "res: get %d\n", bit);
- mutex_unlock(&dev->lock);
- return 1;
-}
-
-static int res_check(struct au0828_fh *fh, unsigned int bit)
-{
- return fh->resources & bit;
-}
-
-static int res_locked(struct au0828_dev *dev, unsigned int bit)
-{
- return dev->resources & bit;
-}
-
-static void res_free(struct au0828_fh *fh, unsigned int bits)
-{
- struct au0828_dev *dev = fh->dev;
-
- BUG_ON((fh->resources & bits) != bits);
-
- mutex_lock(&dev->lock);
- fh->resources &= ~bits;
- dev->resources &= ~bits;
- dprintk(1, "res: put %d\n", bits);
- mutex_unlock(&dev->lock);
-}
-
-static int get_ressource(struct au0828_fh *fh)
-{
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- return AU0828_RESOURCE_VIDEO;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- return AU0828_RESOURCE_VBI;
- default:
- BUG();
- return 0;
- }
-}
-
-/* This function ensures that video frames continue to be delivered even if
- the ITU-656 input isn't receiving any data (thereby preventing applications
- such as tvtime from hanging) */
-void au0828_vid_buffer_timeout(unsigned long data)
-{
- struct au0828_dev *dev = (struct au0828_dev *) data;
- struct au0828_dmaqueue *dma_q = &dev->vidq;
- struct au0828_buffer *buf;
- unsigned char *vid_data;
- unsigned long flags = 0;
-
- spin_lock_irqsave(&dev->slock, flags);
-
- buf = dev->isoc_ctl.buf;
- if (buf != NULL) {
- vid_data = videobuf_to_vmalloc(&buf->vb);
- memset(vid_data, 0x00, buf->vb.size); /* Blank green frame */
- buffer_filled(dev, dma_q, buf);
- }
- get_next_buf(dma_q, &buf);
-
- if (dev->vid_timeout_running == 1)
- mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
-
- spin_unlock_irqrestore(&dev->slock, flags);
-}
-
-void au0828_vbi_buffer_timeout(unsigned long data)
-{
- struct au0828_dev *dev = (struct au0828_dev *) data;
- struct au0828_dmaqueue *dma_q = &dev->vbiq;
- struct au0828_buffer *buf;
- unsigned char *vbi_data;
- unsigned long flags = 0;
-
- spin_lock_irqsave(&dev->slock, flags);
-
- buf = dev->isoc_ctl.vbi_buf;
- if (buf != NULL) {
- vbi_data = videobuf_to_vmalloc(&buf->vb);
- memset(vbi_data, 0x00, buf->vb.size);
- vbi_buffer_filled(dev, dma_q, buf);
- }
- vbi_get_next_buf(dma_q, &buf);
-
- if (dev->vbi_timeout_running == 1)
- mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
- spin_unlock_irqrestore(&dev->slock, flags);
-}
-
-
-static int au0828_v4l2_open(struct file *filp)
-{
- int ret = 0;
- struct video_device *vdev = video_devdata(filp);
- struct au0828_dev *dev = video_drvdata(filp);
- struct au0828_fh *fh;
- int type;
-
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- case VFL_TYPE_VBI:
- type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- default:
- return -EINVAL;
- }
-
- fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL);
- if (NULL == fh) {
- dprintk(1, "Failed allocate au0828_fh struct!\n");
- return -ENOMEM;
- }
-
- fh->type = type;
- fh->dev = dev;
- filp->private_data = fh;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
- /* set au0828 interface0 to AS5 here again */
- ret = usb_set_interface(dev->usbdev, 0, 5);
- if (ret < 0) {
- printk(KERN_INFO "Au0828 can't set alternate to 5!\n");
- return -EBUSY;
- }
- dev->width = NTSC_STD_W;
- dev->height = NTSC_STD_H;
- dev->frame_size = dev->width * dev->height * 2;
- dev->field_size = dev->width * dev->height;
- dev->bytesperline = dev->width * 2;
-
- au0828_analog_stream_enable(dev);
- au0828_analog_stream_reset(dev);
-
- /* If we were doing ac97 instead of i2s, it would go here...*/
- au0828_i2s_init(dev);
-
- dev->stream_state = STREAM_OFF;
- dev->dev_state |= DEV_INITIALIZED;
- }
-
- dev->users++;
-
- videobuf_queue_vmalloc_init(&fh->vb_vidq, &au0828_video_qops,
- NULL, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct au0828_buffer), fh, NULL);
-
- /* VBI Setup */
- dev->vbi_width = 720;
- dev->vbi_height = 1;
- videobuf_queue_vmalloc_init(&fh->vb_vbiq, &au0828_vbi_qops,
- NULL, &dev->slock,
- V4L2_BUF_TYPE_VBI_CAPTURE,
- V4L2_FIELD_SEQ_TB,
- sizeof(struct au0828_buffer), fh, NULL);
-
- return ret;
-}
-
-static int au0828_v4l2_close(struct file *filp)
-{
- int ret;
- struct au0828_fh *fh = filp->private_data;
- struct au0828_dev *dev = fh->dev;
-
- if (res_check(fh, AU0828_RESOURCE_VIDEO)) {
- /* Cancel timeout thread in case they didn't call streamoff */
- dev->vid_timeout_running = 0;
- del_timer_sync(&dev->vid_timeout);
-
- videobuf_stop(&fh->vb_vidq);
- res_free(fh, AU0828_RESOURCE_VIDEO);
- }
-
- if (res_check(fh, AU0828_RESOURCE_VBI)) {
- /* Cancel timeout thread in case they didn't call streamoff */
- dev->vbi_timeout_running = 0;
- del_timer_sync(&dev->vbi_timeout);
-
- videobuf_stop(&fh->vb_vbiq);
- res_free(fh, AU0828_RESOURCE_VBI);
- }
-
- if (dev->users == 1) {
- if (dev->dev_state & DEV_DISCONNECTED) {
- au0828_analog_unregister(dev);
- kfree(dev);
- return 0;
- }
-
- au0828_analog_stream_disable(dev);
-
- au0828_uninit_isoc(dev);
-
- /* Save some power by putting tuner to sleep */
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
-
- /* When close the device, set the usb intf0 into alt0 to free
- USB bandwidth */
- ret = usb_set_interface(dev->usbdev, 0, 0);
- if (ret < 0)
- printk(KERN_INFO "Au0828 can't set alternate to 0!\n");
- }
-
- videobuf_mmap_free(&fh->vb_vidq);
- videobuf_mmap_free(&fh->vb_vbiq);
- kfree(fh);
- dev->users--;
- wake_up_interruptible_nr(&dev->open, 1);
- return 0;
-}
-
-static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf,
- size_t count, loff_t *pos)
-{
- struct au0828_fh *fh = filp->private_data;
- struct au0828_dev *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- if (res_locked(dev, AU0828_RESOURCE_VIDEO))
- return -EBUSY;
-
- return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
- filp->f_flags & O_NONBLOCK);
- }
-
- if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- if (!res_get(fh, AU0828_RESOURCE_VBI))
- return -EBUSY;
-
- if (dev->vbi_timeout_running == 0) {
- /* Handle case where caller tries to read without
- calling streamon first */
- dev->vbi_timeout_running = 1;
- mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
- }
-
- return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
- filp->f_flags & O_NONBLOCK);
- }
-
- return 0;
-}
-
-static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait)
-{
- struct au0828_fh *fh = filp->private_data;
- struct au0828_dev *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- if (!res_get(fh, AU0828_RESOURCE_VIDEO))
- return POLLERR;
- return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
- } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- if (!res_get(fh, AU0828_RESOURCE_VBI))
- return POLLERR;
- return videobuf_poll_stream(filp, &fh->vb_vbiq, wait);
- } else {
- return POLLERR;
- }
-}
-
-static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- struct au0828_fh *fh = filp->private_data;
- struct au0828_dev *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
- else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
- rc = videobuf_mmap_mapper(&fh->vb_vbiq, vma);
-
- return rc;
-}
-
-static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
- struct v4l2_format *format)
-{
- int ret;
- int width = format->fmt.pix.width;
- int height = format->fmt.pix.height;
-
- if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- /* If they are demanding a format other than the one we support,
- bail out (tvtime asks for UYVY and then retries with YUYV) */
- if (format->fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY)
- return -EINVAL;
-
- /* format->fmt.pix.width only support 720 and height 480 */
- if (width != 720)
- width = 720;
- if (height != 480)
- height = 480;
-
- format->fmt.pix.width = width;
- format->fmt.pix.height = height;
- format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
- format->fmt.pix.bytesperline = width * 2;
- format->fmt.pix.sizeimage = width * height * 2;
- format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- format->fmt.pix.field = V4L2_FIELD_INTERLACED;
-
- if (cmd == VIDIOC_TRY_FMT)
- return 0;
-
- /* maybe set new image format, driver current only support 720*480 */
- dev->width = width;
- dev->height = height;
- dev->frame_size = width * height * 2;
- dev->field_size = width * height;
- dev->bytesperline = width * 2;
-
- if (dev->stream_state == STREAM_ON) {
- dprintk(1, "VIDIOC_SET_FMT: interrupting stream!\n");
- ret = au0828_stream_interrupt(dev);
- if (ret != 0) {
- dprintk(1, "error interrupting video stream!\n");
- return ret;
- }
- }
-
- /* set au0828 interface0 to AS5 here again */
- ret = usb_set_interface(dev->usbdev, 0, 5);
- if (ret < 0) {
- printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
- return -EBUSY;
- }
-
- au0828_analog_stream_enable(dev);
-
- return 0;
-}
-
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qc)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc);
- if (qc->type)
- return 0;
- else
- return -EINVAL;
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
-
- strlcpy(cap->driver, "au0828", sizeof(cap->driver));
- strlcpy(cap->card, dev->board.name, sizeof(cap->card));
- strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
-
- /*set the device capabilities */
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_VBI_CAPTURE |
- V4L2_CAP_AUDIO |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING |
- V4L2_CAP_TUNER;
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (f->index)
- return -EINVAL;
-
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- strcpy(f->description, "Packed YUV2");
-
- f->flags = 0;
- f->pixelformat = V4L2_PIX_FMT_UYVY;
-
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
-
- f->fmt.pix.width = dev->width;
- f->fmt.pix.height = dev->height;
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
- f->fmt.pix.bytesperline = dev->bytesperline;
- f->fmt.pix.sizeimage = dev->frame_size;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */
- f->fmt.pix.field = V4L2_FIELD_INTERLACED;
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
-
- return au0828_set_format(dev, VIDIOC_TRY_FMT, f);
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- mutex_lock(&dev->lock);
-
- if (videobuf_queue_is_busy(&fh->vb_vidq)) {
- printk(KERN_INFO "%s queue busy\n", __func__);
- rc = -EBUSY;
- goto out;
- }
-
- rc = au0828_set_format(dev, VIDIOC_S_FMT, f);
-out:
- mutex_unlock(&dev->lock);
- return rc;
-}
-
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
-
- /* FIXME: when we support something other than NTSC, we are going to
- have to make the au0828 bridge adjust the size of its capture
- buffer, which is currently hardcoded at 720x480 */
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, *norm);
- return 0;
-}
-
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *input)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- unsigned int tmp;
-
- static const char *inames[] = {
- [AU0828_VMUX_UNDEFINED] = "Undefined",
- [AU0828_VMUX_COMPOSITE] = "Composite",
- [AU0828_VMUX_SVIDEO] = "S-Video",
- [AU0828_VMUX_CABLE] = "Cable TV",
- [AU0828_VMUX_TELEVISION] = "Television",
- [AU0828_VMUX_DVB] = "DVB",
- [AU0828_VMUX_DEBUG] = "tv debug"
- };
-
- tmp = input->index;
-
- if (tmp >= AU0828_MAX_INPUT)
- return -EINVAL;
- if (AUVI_INPUT(tmp).type == 0)
- return -EINVAL;
-
- input->index = tmp;
- strcpy(input->name, inames[AUVI_INPUT(tmp).type]);
- if ((AUVI_INPUT(tmp).type == AU0828_VMUX_TELEVISION) ||
- (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE))
- input->type |= V4L2_INPUT_TYPE_TUNER;
- else
- input->type |= V4L2_INPUT_TYPE_CAMERA;
-
- input->std = dev->vdev->tvnorms;
-
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- *i = dev->ctrl_input;
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- int i;
-
- dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __func__,
- index);
- if (index >= AU0828_MAX_INPUT)
- return -EINVAL;
- if (AUVI_INPUT(index).type == 0)
- return -EINVAL;
- dev->ctrl_input = index;
-
- switch (AUVI_INPUT(index).type) {
- case AU0828_VMUX_SVIDEO:
- dev->input_type = AU0828_VMUX_SVIDEO;
- break;
- case AU0828_VMUX_COMPOSITE:
- dev->input_type = AU0828_VMUX_COMPOSITE;
- break;
- case AU0828_VMUX_TELEVISION:
- dev->input_type = AU0828_VMUX_TELEVISION;
- break;
- default:
- dprintk(1, "VIDIOC_S_INPUT unknown input type set [%d]\n",
- AUVI_INPUT(index).type);
- break;
- }
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
- AUVI_INPUT(index).vmux, 0, 0);
-
- for (i = 0; i < AU0828_MAX_INPUT; i++) {
- int enable = 0;
- if (AUVI_INPUT(i).audio_setup == NULL)
- continue;
-
- if (i == index)
- enable = 1;
- else
- enable = 0;
- if (enable) {
- (AUVI_INPUT(i).audio_setup)(dev, enable);
- } else {
- /* Make sure we leave it turned on if some
- other input is routed to this callback */
- if ((AUVI_INPUT(i).audio_setup) !=
- ((AUVI_INPUT(index).audio_setup))) {
- (AUVI_INPUT(i).audio_setup)(dev, enable);
- }
- }
- }
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
- AUVI_INPUT(index).amux, 0, 0);
- return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- unsigned int index = a->index;
-
- if (a->index > 1)
- return -EINVAL;
-
- index = dev->ctrl_ainput;
- if (index == 0)
- strcpy(a->name, "Television");
- else
- strcpy(a->name, "Line in");
-
- a->capability = V4L2_AUDCAP_STEREO;
- a->index = index;
- return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- if (a->index != dev->ctrl_ainput)
- return -EINVAL;
- return 0;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
- return 0;
-
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
- return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
-
- if (t->index != 0)
- return -EINVAL;
-
- strcpy(t->name, "Auvitek tuner");
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
- return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
-
- if (t->index != 0)
- return -EINVAL;
-
- t->type = V4L2_TUNER_ANALOG_TV;
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
- dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal,
- t->afc);
- return 0;
-
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *freq)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
-
- freq->type = V4L2_TUNER_ANALOG_TV;
- freq->frequency = dev->ctrl_freq;
- return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *freq)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
-
- if (freq->tuner != 0)
- return -EINVAL;
- if (freq->type != V4L2_TUNER_ANALOG_TV)
- return -EINVAL;
-
- dev->ctrl_freq = freq->frequency;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, freq);
-
- au0828_analog_stream_reset(dev);
-
- return 0;
-}
-
-
-/* RAW VBI ioctls */
-
-static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
- struct v4l2_format *format)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
-
- format->fmt.vbi.samples_per_line = dev->vbi_width;
- format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
- format->fmt.vbi.offset = 0;
- format->fmt.vbi.flags = 0;
- format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
-
- format->fmt.vbi.count[0] = dev->vbi_height;
- format->fmt.vbi.count[1] = dev->vbi_height;
- format->fmt.vbi.start[0] = 21;
- format->fmt.vbi.start[1] = 284;
-
- return 0;
-}
-
-static int vidioc_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
-
- if (v4l2_chip_match_host(&chip->match)) {
- chip->ident = V4L2_IDENT_AU0828;
- return 0;
- }
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
- if (chip->ident == V4L2_IDENT_NONE)
- return -EINVAL;
-
- return 0;
-}
-
-static int vidioc_cropcap(struct file *file, void *priv,
- struct v4l2_cropcap *cc)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
-
- if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- cc->bounds.left = 0;
- cc->bounds.top = 0;
- cc->bounds.width = dev->width;
- cc->bounds.height = dev->height;
-
- cc->defrect = cc->bounds;
-
- cc->pixelaspect.numerator = 54;
- cc->pixelaspect.denominator = 59;
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- int rc = -EINVAL;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (unlikely(type != fh->type))
- return -EINVAL;
-
- dprintk(1, "vidioc_streamon fh=%p t=%d fh->res=%d dev->res=%d\n",
- fh, type, fh->resources, dev->resources);
-
- if (unlikely(!res_get(fh, get_ressource(fh))))
- return -EBUSY;
-
- if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- au0828_analog_stream_enable(dev);
- v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
- }
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- rc = videobuf_streamon(&fh->vb_vidq);
- dev->vid_timeout_running = 1;
- mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
- } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- rc = videobuf_streamon(&fh->vb_vbiq);
- dev->vbi_timeout_running = 1;
- mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
- }
-
- return rc;
-}
-
-static int vidioc_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- int rc;
- int i;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
- fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)
- return -EINVAL;
- if (type != fh->type)
- return -EINVAL;
-
- dprintk(1, "vidioc_streamoff fh=%p t=%d fh->res=%d dev->res=%d\n",
- fh, type, fh->resources, dev->resources);
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- dev->vid_timeout_running = 0;
- del_timer_sync(&dev->vid_timeout);
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
- rc = au0828_stream_interrupt(dev);
- if (rc != 0)
- return rc;
-
- for (i = 0; i < AU0828_MAX_INPUT; i++) {
- if (AUVI_INPUT(i).audio_setup == NULL)
- continue;
- (AUVI_INPUT(i).audio_setup)(dev, 0);
- }
-
- videobuf_streamoff(&fh->vb_vidq);
- res_free(fh, AU0828_RESOURCE_VIDEO);
- } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- dev->vbi_timeout_running = 0;
- del_timer_sync(&dev->vbi_timeout);
-
- videobuf_streamoff(&fh->vb_vbiq);
- res_free(fh, AU0828_RESOURCE_VBI);
- }
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vidioc_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
-
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static int vidioc_s_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
-
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
- return 0;
- default:
- return -EINVAL;
- }
- return 0;
-}
-#endif
-
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *rb)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- rc = videobuf_reqbufs(&fh->vb_vidq, rb);
- else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
- rc = videobuf_reqbufs(&fh->vb_vbiq, rb);
-
- return rc;
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- rc = videobuf_querybuf(&fh->vb_vidq, b);
- else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
- rc = videobuf_querybuf(&fh->vb_vbiq, b);
-
- return rc;
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- rc = videobuf_qbuf(&fh->vb_vidq, b);
- else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
- rc = videobuf_qbuf(&fh->vb_vbiq, b);
-
- return rc;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- /* Workaround for a bug in the au0828 hardware design that sometimes
- results in the colorspace being inverted */
- if (dev->greenscreen_detected == 1) {
- dprintk(1, "Detected green frame. Resetting stream...\n");
- au0828_analog_stream_reset(dev);
- dev->greenscreen_detected = 0;
- }
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- rc = videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
- else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
- rc = videobuf_dqbuf(&fh->vb_vbiq, b, file->f_flags & O_NONBLOCK);
-
- return rc;
-}
-
-static struct v4l2_file_operations au0828_v4l_fops = {
- .owner = THIS_MODULE,
- .open = au0828_v4l2_open,
- .release = au0828_v4l2_close,
- .read = au0828_v4l2_read,
- .poll = au0828_v4l2_poll,
- .mmap = au0828_v4l2_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
- .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_cropcap = vidioc_cropcap,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vidioc_g_register,
- .vidioc_s_register = vidioc_s_register,
-#endif
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
-};
-
-static const struct video_device au0828_video_template = {
- .fops = &au0828_v4l_fops,
- .release = video_device_release,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = V4L2_STD_NTSC_M,
- .current_norm = V4L2_STD_NTSC_M,
-};
-
-/**************************************************************************/
-
-int au0828_analog_register(struct au0828_dev *dev,
- struct usb_interface *interface)
-{
- int retval = -ENOMEM;
- struct usb_host_interface *iface_desc;
- struct usb_endpoint_descriptor *endpoint;
- int i, ret;
-
- dprintk(1, "au0828_analog_register called!\n");
-
- /* set au0828 usb interface0 to as5 */
- retval = usb_set_interface(dev->usbdev,
- interface->cur_altsetting->desc.bInterfaceNumber, 5);
- if (retval != 0) {
- printk(KERN_INFO "Failure setting usb interface0 to as5\n");
- return retval;
- }
-
- /* Figure out which endpoint has the isoc interface */
- iface_desc = interface->cur_altsetting;
- for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
- endpoint = &iface_desc->endpoint[i].desc;
- if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
- == USB_DIR_IN) &&
- ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
- == USB_ENDPOINT_XFER_ISOC)) {
-
- /* we find our isoc in endpoint */
- u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize);
- dev->max_pkt_size = (tmp & 0x07ff) *
- (((tmp & 0x1800) >> 11) + 1);
- dev->isoc_in_endpointaddr = endpoint->bEndpointAddress;
- }
- }
- if (!(dev->isoc_in_endpointaddr)) {
- printk(KERN_INFO "Could not locate isoc endpoint\n");
- kfree(dev);
- return -ENODEV;
- }
-
- init_waitqueue_head(&dev->open);
- spin_lock_init(&dev->slock);
- mutex_init(&dev->lock);
-
- /* init video dma queues */
- INIT_LIST_HEAD(&dev->vidq.active);
- INIT_LIST_HEAD(&dev->vidq.queued);
- INIT_LIST_HEAD(&dev->vbiq.active);
- INIT_LIST_HEAD(&dev->vbiq.queued);
-
- dev->vid_timeout.function = au0828_vid_buffer_timeout;
- dev->vid_timeout.data = (unsigned long) dev;
- init_timer(&dev->vid_timeout);
-
- dev->vbi_timeout.function = au0828_vbi_buffer_timeout;
- dev->vbi_timeout.data = (unsigned long) dev;
- init_timer(&dev->vbi_timeout);
-
- dev->width = NTSC_STD_W;
- dev->height = NTSC_STD_H;
- dev->field_size = dev->width * dev->height;
- dev->frame_size = dev->field_size << 1;
- dev->bytesperline = dev->width << 1;
- dev->ctrl_ainput = 0;
-
- /* allocate and fill v4l2 video struct */
- dev->vdev = video_device_alloc();
- if (NULL == dev->vdev) {
- dprintk(1, "Can't allocate video_device.\n");
- return -ENOMEM;
- }
-
- /* allocate the VBI struct */
- dev->vbi_dev = video_device_alloc();
- if (NULL == dev->vbi_dev) {
- dprintk(1, "Can't allocate vbi_device.\n");
- ret = -ENOMEM;
- goto err_vdev;
- }
-
- /* Fill the video capture device struct */
- *dev->vdev = au0828_video_template;
- dev->vdev->parent = &dev->usbdev->dev;
- strcpy(dev->vdev->name, "au0828a video");
-
- /* Setup the VBI device */
- *dev->vbi_dev = au0828_video_template;
- dev->vbi_dev->parent = &dev->usbdev->dev;
- strcpy(dev->vbi_dev->name, "au0828a vbi");
-
- /* Register the v4l2 device */
- video_set_drvdata(dev->vdev, dev);
- retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1);
- if (retval != 0) {
- dprintk(1, "unable to register video device (error = %d).\n",
- retval);
- ret = -ENODEV;
- goto err_vbi_dev;
- }
-
- /* Register the vbi device */
- video_set_drvdata(dev->vbi_dev, dev);
- retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1);
- if (retval != 0) {
- dprintk(1, "unable to register vbi device (error = %d).\n",
- retval);
- ret = -ENODEV;
- goto err_vbi_dev;
- }
-
- dprintk(1, "%s completed!\n", __func__);
-
- return 0;
-
-err_vbi_dev:
- video_device_release(dev->vbi_dev);
-err_vdev:
- video_device_release(dev->vdev);
- return ret;
-}
-
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
deleted file mode 100644
index 9cde3532182..00000000000
--- a/drivers/media/video/au0828/au0828.h
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Driver for the Auvitek AU0828 USB bridge
- *
- * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <media/tveeprom.h>
-
-/* Analog */
-#include <linux/videodev2.h>
-#include <media/videobuf-vmalloc.h>
-#include <media/v4l2-device.h>
-
-/* DVB */
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
-
-#include "au0828-reg.h"
-#include "au0828-cards.h"
-
-#define DRIVER_NAME "au0828"
-#define URB_COUNT 16
-#define URB_BUFSIZE (0xe522)
-
-/* Analog constants */
-#define NTSC_STD_W 720
-#define NTSC_STD_H 480
-
-#define AU0828_INTERLACED_DEFAULT 1
-#define V4L2_CID_PRIVATE_SHARPNESS (V4L2_CID_PRIVATE_BASE + 0)
-
-/* Defination for AU0828 USB transfer */
-#define AU0828_MAX_ISO_BUFS 12 /* maybe resize this value in the future */
-#define AU0828_ISO_PACKETS_PER_URB 128
-
-#define AU0828_MIN_BUF 4
-#define AU0828_DEF_BUF 8
-
-#define AU0828_MAX_INPUT 4
-
-/* au0828 resource types (used for res_get/res_lock etc */
-#define AU0828_RESOURCE_VIDEO 0x01
-#define AU0828_RESOURCE_VBI 0x02
-
-enum au0828_itype {
- AU0828_VMUX_UNDEFINED = 0,
- AU0828_VMUX_COMPOSITE,
- AU0828_VMUX_SVIDEO,
- AU0828_VMUX_CABLE,
- AU0828_VMUX_TELEVISION,
- AU0828_VMUX_DVB,
- AU0828_VMUX_DEBUG
-};
-
-struct au0828_input {
- enum au0828_itype type;
- unsigned int vmux;
- unsigned int amux;
- void (*audio_setup) (void *priv, int enable);
-};
-
-struct au0828_board {
- char *name;
- unsigned int tuner_type;
- unsigned char tuner_addr;
- unsigned char i2c_clk_divider;
- struct au0828_input input[AU0828_MAX_INPUT];
-
-};
-
-struct au0828_dvb {
- struct mutex lock;
- struct dvb_adapter adapter;
- struct dvb_frontend *frontend;
- struct dvb_demux demux;
- struct dmxdev dmxdev;
- struct dmx_frontend fe_hw;
- struct dmx_frontend fe_mem;
- struct dvb_net net;
- int feeding;
-};
-
-enum au0828_stream_state {
- STREAM_OFF,
- STREAM_INTERRUPT,
- STREAM_ON
-};
-
-#define AUVI_INPUT(nr) (dev->board.input[nr])
-
-/* device state */
-enum au0828_dev_state {
- DEV_INITIALIZED = 0x01,
- DEV_DISCONNECTED = 0x02,
- DEV_MISCONFIGURED = 0x04
-};
-
-struct au0828_fh {
- struct au0828_dev *dev;
- unsigned int resources;
-
- struct videobuf_queue vb_vidq;
- struct videobuf_queue vb_vbiq;
- enum v4l2_buf_type type;
-};
-
-struct au0828_usb_isoc_ctl {
- /* max packet size of isoc transaction */
- int max_pkt_size;
-
- /* number of allocated urbs */
- int num_bufs;
-
- /* urb for isoc transfers */
- struct urb **urb;
-
- /* transfer buffers for isoc transfer */
- char **transfer_buffer;
-
- /* Last buffer command and region */
- u8 cmd;
- int pos, size, pktsize;
-
- /* Last field: ODD or EVEN? */
- int field;
-
- /* Stores incomplete commands */
- u32 tmp_buf;
- int tmp_buf_len;
-
- /* Stores already requested buffers */
- struct au0828_buffer *buf;
- struct au0828_buffer *vbi_buf;
-
- /* Stores the number of received fields */
- int nfields;
-
- /* isoc urb callback */
- int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb);
-
-};
-
-/* buffer for one video frame */
-struct au0828_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
-
- struct list_head frame;
- int top_field;
- int receiving;
-};
-
-struct au0828_dmaqueue {
- struct list_head active;
- struct list_head queued;
-
- wait_queue_head_t wq;
-
- /* Counters to control buffer fill */
- int pos;
-};
-
-struct au0828_dev {
- struct mutex mutex;
- struct usb_device *usbdev;
- int boardnr;
- struct au0828_board board;
- u8 ctrlmsg[64];
-
- /* I2C */
- struct i2c_adapter i2c_adap;
- struct i2c_algorithm i2c_algo;
- struct i2c_client i2c_client;
- u32 i2c_rc;
-
- /* Digital */
- struct au0828_dvb dvb;
-
- /* Analog */
- struct v4l2_device v4l2_dev;
- int users;
- unsigned int resources; /* resources in use */
- struct video_device *vdev;
- struct video_device *vbi_dev;
- struct timer_list vid_timeout;
- int vid_timeout_running;
- struct timer_list vbi_timeout;
- int vbi_timeout_running;
- int width;
- int height;
- int vbi_width;
- int vbi_height;
- u32 vbi_read;
- u32 field_size;
- u32 frame_size;
- u32 bytesperline;
- int type;
- u8 ctrl_ainput;
- __u8 isoc_in_endpointaddr;
- u8 isoc_init_ok;
- int greenscreen_detected;
- unsigned int frame_count;
- int ctrl_freq;
- int input_type;
- unsigned int ctrl_input;
- enum au0828_dev_state dev_state;
- enum au0828_stream_state stream_state;
- wait_queue_head_t open;
-
- struct mutex lock;
-
- /* Isoc control struct */
- struct au0828_dmaqueue vidq;
- struct au0828_dmaqueue vbiq;
- struct au0828_usb_isoc_ctl isoc_ctl;
- spinlock_t slock;
-
- /* usb transfer */
- int alt; /* alternate */
- int max_pkt_size; /* max packet size of isoc transaction */
- int num_alt; /* Number of alternative settings */
- unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
- struct urb *urb[AU0828_MAX_ISO_BUFS]; /* urb for isoc transfers */
- char *transfer_buffer[AU0828_MAX_ISO_BUFS];/* transfer buffers for isoc
- transfer */
-
- /* USB / URB Related */
- int urb_streaming;
- struct urb *urbs[URB_COUNT];
-};
-
-/* ----------------------------------------------------------- */
-#define au0828_read(dev, reg) au0828_readreg(dev, reg)
-#define au0828_write(dev, reg, value) au0828_writereg(dev, reg, value)
-#define au0828_andor(dev, reg, mask, value) \
- au0828_writereg(dev, reg, \
- (au0828_readreg(dev, reg) & ~(mask)) | ((value) & (mask)))
-
-#define au0828_set(dev, reg, bit) au0828_andor(dev, (reg), (bit), (bit))
-#define au0828_clear(dev, reg, bit) au0828_andor(dev, (reg), (bit), 0)
-
-/* ----------------------------------------------------------- */
-/* au0828-core.c */
-extern u32 au0828_read(struct au0828_dev *dev, u16 reg);
-extern u32 au0828_write(struct au0828_dev *dev, u16 reg, u32 val);
-extern int au0828_debug;
-
-/* ----------------------------------------------------------- */
-/* au0828-cards.c */
-extern struct au0828_board au0828_boards[];
-extern struct usb_device_id au0828_usb_id_table[];
-extern void au0828_gpio_setup(struct au0828_dev *dev);
-extern int au0828_tuner_callback(void *priv, int component,
- int command, int arg);
-extern void au0828_card_setup(struct au0828_dev *dev);
-
-/* ----------------------------------------------------------- */
-/* au0828-i2c.c */
-extern int au0828_i2c_register(struct au0828_dev *dev);
-extern int au0828_i2c_unregister(struct au0828_dev *dev);
-
-/* ----------------------------------------------------------- */
-/* au0828-video.c */
-int au0828_analog_register(struct au0828_dev *dev,
- struct usb_interface *interface);
-int au0828_analog_stream_disable(struct au0828_dev *d);
-void au0828_analog_unregister(struct au0828_dev *dev);
-
-/* ----------------------------------------------------------- */
-/* au0828-dvb.c */
-extern int au0828_dvb_register(struct au0828_dev *dev);
-extern void au0828_dvb_unregister(struct au0828_dev *dev);
-
-/* au0828-vbi.c */
-extern struct videobuf_queue_ops au0828_vbi_qops;
-
-#define dprintk(level, fmt, arg...)\
- do { if (au0828_debug & level)\
- printk(KERN_DEBUG DRIVER_NAME "/0: " fmt, ## arg);\
- } while (0)
diff --git a/drivers/media/video/blackfin/Kconfig b/drivers/media/video/blackfin/Kconfig
deleted file mode 100644
index ecd5323768b..00000000000
--- a/drivers/media/video/blackfin/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config VIDEO_BLACKFIN_CAPTURE
- tristate "Blackfin Video Capture Driver"
- depends on VIDEO_V4L2 && BLACKFIN && I2C
- select VIDEOBUF2_DMA_CONTIG
- help
- V4L2 bridge driver for Blackfin video capture device.
- Choose PPI or EPPI as its interface.
-
- To compile this driver as a module, choose M here: the
- module will be called bfin_video_capture.
diff --git a/drivers/media/video/blackfin/Makefile b/drivers/media/video/blackfin/Makefile
deleted file mode 100644
index aa3a0a21638..00000000000
--- a/drivers/media/video/blackfin/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-bfin_video_capture-objs := bfin_capture.o ppi.o
-obj-$(CONFIG_VIDEO_BLACKFIN_CAPTURE) += bfin_video_capture.o
diff --git a/drivers/media/video/blackfin/bfin_capture.c b/drivers/media/video/blackfin/bfin_capture.c
deleted file mode 100644
index 0aba45e34f7..00000000000
--- a/drivers/media/video/blackfin/bfin_capture.c
+++ /dev/null
@@ -1,1063 +0,0 @@
-/*
- * Analog Devices video capture driver
- *
- * Copyright (c) 2011 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/completion.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/types.h>
-
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include <asm/dma.h>
-
-#include <media/blackfin/bfin_capture.h>
-#include <media/blackfin/ppi.h>
-
-#define CAPTURE_DRV_NAME "bfin_capture"
-#define BCAP_MIN_NUM_BUF 2
-
-struct bcap_format {
- char *desc;
- u32 pixelformat;
- enum v4l2_mbus_pixelcode mbus_code;
- int bpp; /* bits per pixel */
-};
-
-struct bcap_buffer {
- struct vb2_buffer vb;
- struct list_head list;
-};
-
-struct bcap_device {
- /* capture device instance */
- struct v4l2_device v4l2_dev;
- /* v4l2 control handler */
- struct v4l2_ctrl_handler ctrl_handler;
- /* device node data */
- struct video_device *video_dev;
- /* sub device instance */
- struct v4l2_subdev *sd;
- /* capture config */
- struct bfin_capture_config *cfg;
- /* ppi interface */
- struct ppi_if *ppi;
- /* current input */
- unsigned int cur_input;
- /* current selected standard */
- v4l2_std_id std;
- /* used to store pixel format */
- struct v4l2_pix_format fmt;
- /* bits per pixel*/
- int bpp;
- /* used to store sensor supported format */
- struct bcap_format *sensor_formats;
- /* number of sensor formats array */
- int num_sensor_formats;
- /* pointing to current video buffer */
- struct bcap_buffer *cur_frm;
- /* pointing to next video buffer */
- struct bcap_buffer *next_frm;
- /* buffer queue used in videobuf2 */
- struct vb2_queue buffer_queue;
- /* allocator-specific contexts for each plane */
- struct vb2_alloc_ctx *alloc_ctx;
- /* queue of filled frames */
- struct list_head dma_queue;
- /* used in videobuf2 callback */
- spinlock_t lock;
- /* used to access capture device */
- struct mutex mutex;
- /* used to wait ppi to complete one transfer */
- struct completion comp;
- /* prepare to stop */
- bool stop;
-};
-
-struct bcap_fh {
- struct v4l2_fh fh;
- /* indicates whether this file handle is doing IO */
- bool io_allowed;
-};
-
-static const struct bcap_format bcap_formats[] = {
- {
- .desc = "YCbCr 4:2:2 Interleaved UYVY",
- .pixelformat = V4L2_PIX_FMT_UYVY,
- .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
- .bpp = 16,
- },
- {
- .desc = "YCbCr 4:2:2 Interleaved YUYV",
- .pixelformat = V4L2_PIX_FMT_YUYV,
- .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
- .bpp = 16,
- },
- {
- .desc = "RGB 565",
- .pixelformat = V4L2_PIX_FMT_RGB565,
- .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE,
- .bpp = 16,
- },
- {
- .desc = "RGB 444",
- .pixelformat = V4L2_PIX_FMT_RGB444,
- .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE,
- .bpp = 16,
- },
-
-};
-#define BCAP_MAX_FMTS ARRAY_SIZE(bcap_formats)
-
-static irqreturn_t bcap_isr(int irq, void *dev_id);
-
-static struct bcap_buffer *to_bcap_vb(struct vb2_buffer *vb)
-{
- return container_of(vb, struct bcap_buffer, vb);
-}
-
-static int bcap_init_sensor_formats(struct bcap_device *bcap_dev)
-{
- enum v4l2_mbus_pixelcode code;
- struct bcap_format *sf;
- unsigned int num_formats = 0;
- int i, j;
-
- while (!v4l2_subdev_call(bcap_dev->sd, video,
- enum_mbus_fmt, num_formats, &code))
- num_formats++;
- if (!num_formats)
- return -ENXIO;
-
- sf = kzalloc(num_formats * sizeof(*sf), GFP_KERNEL);
- if (!sf)
- return -ENOMEM;
-
- for (i = 0; i < num_formats; i++) {
- v4l2_subdev_call(bcap_dev->sd, video,
- enum_mbus_fmt, i, &code);
- for (j = 0; j < BCAP_MAX_FMTS; j++)
- if (code == bcap_formats[j].mbus_code)
- break;
- if (j == BCAP_MAX_FMTS) {
- /* we don't allow this sensor working with our bridge */
- kfree(sf);
- return -EINVAL;
- }
- sf[i] = bcap_formats[j];
- }
- bcap_dev->sensor_formats = sf;
- bcap_dev->num_sensor_formats = num_formats;
- return 0;
-}
-
-static void bcap_free_sensor_formats(struct bcap_device *bcap_dev)
-{
- bcap_dev->num_sensor_formats = 0;
- kfree(bcap_dev->sensor_formats);
- bcap_dev->sensor_formats = NULL;
-}
-
-static int bcap_open(struct file *file)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
- struct video_device *vfd = bcap_dev->video_dev;
- struct bcap_fh *bcap_fh;
-
- if (!bcap_dev->sd) {
- v4l2_err(&bcap_dev->v4l2_dev, "No sub device registered\n");
- return -ENODEV;
- }
-
- bcap_fh = kzalloc(sizeof(*bcap_fh), GFP_KERNEL);
- if (!bcap_fh) {
- v4l2_err(&bcap_dev->v4l2_dev,
- "unable to allocate memory for file handle object\n");
- return -ENOMEM;
- }
-
- v4l2_fh_init(&bcap_fh->fh, vfd);
-
- /* store pointer to v4l2_fh in private_data member of file */
- file->private_data = &bcap_fh->fh;
- v4l2_fh_add(&bcap_fh->fh);
- bcap_fh->io_allowed = false;
- return 0;
-}
-
-static int bcap_release(struct file *file)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
- struct v4l2_fh *fh = file->private_data;
- struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
-
- /* if this instance is doing IO */
- if (bcap_fh->io_allowed)
- vb2_queue_release(&bcap_dev->buffer_queue);
-
- file->private_data = NULL;
- v4l2_fh_del(&bcap_fh->fh);
- v4l2_fh_exit(&bcap_fh->fh);
- kfree(bcap_fh);
- return 0;
-}
-
-static int bcap_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- return vb2_mmap(&bcap_dev->buffer_queue, vma);
-}
-
-#ifndef CONFIG_MMU
-static unsigned long bcap_get_unmapped_area(struct file *file,
- unsigned long addr,
- unsigned long len,
- unsigned long pgoff,
- unsigned long flags)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- return vb2_get_unmapped_area(&bcap_dev->buffer_queue,
- addr,
- len,
- pgoff,
- flags);
-}
-#endif
-
-static unsigned int bcap_poll(struct file *file, poll_table *wait)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- return vb2_poll(&bcap_dev->buffer_queue, file, wait);
-}
-
-static int bcap_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
- unsigned int *nbuffers, unsigned int *nplanes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
-
- if (*nbuffers < BCAP_MIN_NUM_BUF)
- *nbuffers = BCAP_MIN_NUM_BUF;
-
- *nplanes = 1;
- sizes[0] = bcap_dev->fmt.sizeimage;
- alloc_ctxs[0] = bcap_dev->alloc_ctx;
-
- return 0;
-}
-
-static int bcap_buffer_init(struct vb2_buffer *vb)
-{
- struct bcap_buffer *buf = to_bcap_vb(vb);
-
- INIT_LIST_HEAD(&buf->list);
- return 0;
-}
-
-static int bcap_buffer_prepare(struct vb2_buffer *vb)
-{
- struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue);
- struct bcap_buffer *buf = to_bcap_vb(vb);
- unsigned long size;
-
- size = bcap_dev->fmt.sizeimage;
- if (vb2_plane_size(vb, 0) < size) {
- v4l2_err(&bcap_dev->v4l2_dev, "buffer too small (%lu < %lu)\n",
- vb2_plane_size(vb, 0), size);
- return -EINVAL;
- }
- vb2_set_plane_payload(&buf->vb, 0, size);
-
- return 0;
-}
-
-static void bcap_buffer_queue(struct vb2_buffer *vb)
-{
- struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue);
- struct bcap_buffer *buf = to_bcap_vb(vb);
- unsigned long flags;
-
- spin_lock_irqsave(&bcap_dev->lock, flags);
- list_add_tail(&buf->list, &bcap_dev->dma_queue);
- spin_unlock_irqrestore(&bcap_dev->lock, flags);
-}
-
-static void bcap_buffer_cleanup(struct vb2_buffer *vb)
-{
- struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue);
- struct bcap_buffer *buf = to_bcap_vb(vb);
- unsigned long flags;
-
- spin_lock_irqsave(&bcap_dev->lock, flags);
- list_del_init(&buf->list);
- spin_unlock_irqrestore(&bcap_dev->lock, flags);
-}
-
-static void bcap_lock(struct vb2_queue *vq)
-{
- struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
- mutex_lock(&bcap_dev->mutex);
-}
-
-static void bcap_unlock(struct vb2_queue *vq)
-{
- struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
- mutex_unlock(&bcap_dev->mutex);
-}
-
-static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
- struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
- struct ppi_if *ppi = bcap_dev->ppi;
- struct ppi_params params;
- int ret;
-
- /* enable streamon on the sub device */
- ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 1);
- if (ret && (ret != -ENOIOCTLCMD)) {
- v4l2_err(&bcap_dev->v4l2_dev, "stream on failed in subdev\n");
- return ret;
- }
-
- /* set ppi params */
- params.width = bcap_dev->fmt.width;
- params.height = bcap_dev->fmt.height;
- params.bpp = bcap_dev->bpp;
- params.ppi_control = bcap_dev->cfg->ppi_control;
- params.int_mask = bcap_dev->cfg->int_mask;
- params.blank_clocks = bcap_dev->cfg->blank_clocks;
- ret = ppi->ops->set_params(ppi, &params);
- if (ret < 0) {
- v4l2_err(&bcap_dev->v4l2_dev,
- "Error in setting ppi params\n");
- return ret;
- }
-
- /* attach ppi DMA irq handler */
- ret = ppi->ops->attach_irq(ppi, bcap_isr);
- if (ret < 0) {
- v4l2_err(&bcap_dev->v4l2_dev,
- "Error in attaching interrupt handler\n");
- return ret;
- }
-
- INIT_COMPLETION(bcap_dev->comp);
- bcap_dev->stop = false;
- return 0;
-}
-
-static int bcap_stop_streaming(struct vb2_queue *vq)
-{
- struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
- struct ppi_if *ppi = bcap_dev->ppi;
- int ret;
-
- if (!vb2_is_streaming(vq))
- return 0;
-
- bcap_dev->stop = true;
- wait_for_completion(&bcap_dev->comp);
- ppi->ops->stop(ppi);
- ppi->ops->detach_irq(ppi);
- ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 0);
- if (ret && (ret != -ENOIOCTLCMD))
- v4l2_err(&bcap_dev->v4l2_dev,
- "stream off failed in subdev\n");
-
- /* release all active buffers */
- while (!list_empty(&bcap_dev->dma_queue)) {
- bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next,
- struct bcap_buffer, list);
- list_del(&bcap_dev->next_frm->list);
- vb2_buffer_done(&bcap_dev->next_frm->vb, VB2_BUF_STATE_ERROR);
- }
- return 0;
-}
-
-static struct vb2_ops bcap_video_qops = {
- .queue_setup = bcap_queue_setup,
- .buf_init = bcap_buffer_init,
- .buf_prepare = bcap_buffer_prepare,
- .buf_cleanup = bcap_buffer_cleanup,
- .buf_queue = bcap_buffer_queue,
- .wait_prepare = bcap_unlock,
- .wait_finish = bcap_lock,
- .start_streaming = bcap_start_streaming,
- .stop_streaming = bcap_stop_streaming,
-};
-
-static int bcap_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *req_buf)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
- struct vb2_queue *vq = &bcap_dev->buffer_queue;
- struct v4l2_fh *fh = file->private_data;
- struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
-
- if (vb2_is_busy(vq))
- return -EBUSY;
-
- bcap_fh->io_allowed = true;
-
- return vb2_reqbufs(vq, req_buf);
-}
-
-static int bcap_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- return vb2_querybuf(&bcap_dev->buffer_queue, buf);
-}
-
-static int bcap_qbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
- struct v4l2_fh *fh = file->private_data;
- struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
-
- if (!bcap_fh->io_allowed)
- return -EBUSY;
-
- return vb2_qbuf(&bcap_dev->buffer_queue, buf);
-}
-
-static int bcap_dqbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
- struct v4l2_fh *fh = file->private_data;
- struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
-
- if (!bcap_fh->io_allowed)
- return -EBUSY;
-
- return vb2_dqbuf(&bcap_dev->buffer_queue,
- buf, file->f_flags & O_NONBLOCK);
-}
-
-static irqreturn_t bcap_isr(int irq, void *dev_id)
-{
- struct ppi_if *ppi = dev_id;
- struct bcap_device *bcap_dev = ppi->priv;
- struct timeval timevalue;
- struct vb2_buffer *vb = &bcap_dev->cur_frm->vb;
- dma_addr_t addr;
-
- spin_lock(&bcap_dev->lock);
-
- if (bcap_dev->cur_frm != bcap_dev->next_frm) {
- do_gettimeofday(&timevalue);
- vb->v4l2_buf.timestamp = timevalue;
- vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
- bcap_dev->cur_frm = bcap_dev->next_frm;
- }
-
- ppi->ops->stop(ppi);
-
- if (bcap_dev->stop) {
- complete(&bcap_dev->comp);
- } else {
- if (!list_empty(&bcap_dev->dma_queue)) {
- bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next,
- struct bcap_buffer, list);
- list_del(&bcap_dev->next_frm->list);
- addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->next_frm->vb, 0);
- ppi->ops->update_addr(ppi, (unsigned long)addr);
- }
- ppi->ops->start(ppi);
- }
-
- spin_unlock(&bcap_dev->lock);
-
- return IRQ_HANDLED;
-}
-
-static int bcap_streamon(struct file *file, void *priv,
- enum v4l2_buf_type buf_type)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
- struct bcap_fh *fh = file->private_data;
- struct ppi_if *ppi = bcap_dev->ppi;
- dma_addr_t addr;
- int ret;
-
- if (!fh->io_allowed)
- return -EBUSY;
-
- /* call streamon to start streaming in videobuf */
- ret = vb2_streamon(&bcap_dev->buffer_queue, buf_type);
- if (ret)
- return ret;
-
- /* if dma queue is empty, return error */
- if (list_empty(&bcap_dev->dma_queue)) {
- v4l2_err(&bcap_dev->v4l2_dev, "dma queue is empty\n");
- ret = -EINVAL;
- goto err;
- }
-
- /* get the next frame from the dma queue */
- bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next,
- struct bcap_buffer, list);
- bcap_dev->cur_frm = bcap_dev->next_frm;
- /* remove buffer from the dma queue */
- list_del(&bcap_dev->cur_frm->list);
- addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0);
- /* update DMA address */
- ppi->ops->update_addr(ppi, (unsigned long)addr);
- /* enable ppi */
- ppi->ops->start(ppi);
-
- return 0;
-err:
- vb2_streamoff(&bcap_dev->buffer_queue, buf_type);
- return ret;
-}
-
-static int bcap_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type buf_type)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
- struct bcap_fh *fh = file->private_data;
-
- if (!fh->io_allowed)
- return -EBUSY;
-
- return vb2_streamoff(&bcap_dev->buffer_queue, buf_type);
-}
-
-static int bcap_querystd(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- return v4l2_subdev_call(bcap_dev->sd, video, querystd, std);
-}
-
-static int bcap_g_std(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- *std = bcap_dev->std;
- return 0;
-}
-
-static int bcap_s_std(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
- int ret;
-
- if (vb2_is_busy(&bcap_dev->buffer_queue))
- return -EBUSY;
-
- ret = v4l2_subdev_call(bcap_dev->sd, core, s_std, *std);
- if (ret < 0)
- return ret;
-
- bcap_dev->std = *std;
- return 0;
-}
-
-static int bcap_enum_input(struct file *file, void *priv,
- struct v4l2_input *input)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
- struct bfin_capture_config *config = bcap_dev->cfg;
- int ret;
- u32 status;
-
- if (input->index >= config->num_inputs)
- return -EINVAL;
-
- *input = config->inputs[input->index];
- /* get input status */
- ret = v4l2_subdev_call(bcap_dev->sd, video, g_input_status, &status);
- if (!ret)
- input->status = status;
- return 0;
-}
-
-static int bcap_g_input(struct file *file, void *priv, unsigned int *index)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- *index = bcap_dev->cur_input;
- return 0;
-}
-
-static int bcap_s_input(struct file *file, void *priv, unsigned int index)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
- struct bfin_capture_config *config = bcap_dev->cfg;
- struct bcap_route *route;
- int ret;
-
- if (vb2_is_busy(&bcap_dev->buffer_queue))
- return -EBUSY;
-
- if (index >= config->num_inputs)
- return -EINVAL;
-
- route = &config->routes[index];
- ret = v4l2_subdev_call(bcap_dev->sd, video, s_routing,
- route->input, route->output, 0);
- if ((ret < 0) && (ret != -ENOIOCTLCMD)) {
- v4l2_err(&bcap_dev->v4l2_dev, "Failed to set input\n");
- return ret;
- }
- bcap_dev->cur_input = index;
- return 0;
-}
-
-static int bcap_try_format(struct bcap_device *bcap,
- struct v4l2_pix_format *pixfmt,
- enum v4l2_mbus_pixelcode *mbus_code,
- int *bpp)
-{
- struct bcap_format *sf = bcap->sensor_formats;
- struct bcap_format *fmt = NULL;
- struct v4l2_mbus_framefmt mbus_fmt;
- int ret, i;
-
- for (i = 0; i < bcap->num_sensor_formats; i++) {
- fmt = &sf[i];
- if (pixfmt->pixelformat == fmt->pixelformat)
- break;
- }
- if (i == bcap->num_sensor_formats)
- fmt = &sf[0];
-
- if (mbus_code)
- *mbus_code = fmt->mbus_code;
- if (bpp)
- *bpp = fmt->bpp;
- v4l2_fill_mbus_format(&mbus_fmt, pixfmt, fmt->mbus_code);
- ret = v4l2_subdev_call(bcap->sd, video,
- try_mbus_fmt, &mbus_fmt);
- if (ret < 0)
- return ret;
- v4l2_fill_pix_format(pixfmt, &mbus_fmt);
- pixfmt->bytesperline = pixfmt->width * fmt->bpp / 8;
- pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
- return 0;
-}
-
-static int bcap_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *fmt)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
- struct bcap_format *sf = bcap_dev->sensor_formats;
-
- if (fmt->index >= bcap_dev->num_sensor_formats)
- return -EINVAL;
-
- fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- strlcpy(fmt->description,
- sf[fmt->index].desc,
- sizeof(fmt->description));
- fmt->pixelformat = sf[fmt->index].pixelformat;
- return 0;
-}
-
-static int bcap_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
- struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-
- return bcap_try_format(bcap_dev, pixfmt, NULL, NULL);
-}
-
-static int bcap_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- fmt->fmt.pix = bcap_dev->fmt;
- return 0;
-}
-
-static int bcap_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
- struct v4l2_mbus_framefmt mbus_fmt;
- enum v4l2_mbus_pixelcode mbus_code;
- struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
- int ret, bpp;
-
- if (vb2_is_busy(&bcap_dev->buffer_queue))
- return -EBUSY;
-
- /* see if format works */
- ret = bcap_try_format(bcap_dev, pixfmt, &mbus_code, &bpp);
- if (ret < 0)
- return ret;
-
- v4l2_fill_mbus_format(&mbus_fmt, pixfmt, mbus_code);
- ret = v4l2_subdev_call(bcap_dev->sd, video, s_mbus_fmt, &mbus_fmt);
- if (ret < 0)
- return ret;
- bcap_dev->fmt = *pixfmt;
- bcap_dev->bpp = bpp;
- return 0;
-}
-
-static int bcap_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
- strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
- strlcpy(cap->bus_info, "Blackfin Platform", sizeof(cap->bus_info));
- strlcpy(cap->card, bcap_dev->cfg->card_name, sizeof(cap->card));
- return 0;
-}
-
-static int bcap_g_parm(struct file *file, void *fh,
- struct v4l2_streamparm *a)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- return v4l2_subdev_call(bcap_dev->sd, video, g_parm, a);
-}
-
-static int bcap_s_parm(struct file *file, void *fh,
- struct v4l2_streamparm *a)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- return v4l2_subdev_call(bcap_dev->sd, video, s_parm, a);
-}
-
-static int bcap_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
- chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- return v4l2_subdev_call(bcap_dev->sd, core,
- g_chip_ident, chip);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int bcap_dbg_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- return v4l2_subdev_call(bcap_dev->sd, core,
- g_register, reg);
-}
-
-static int bcap_dbg_s_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- return v4l2_subdev_call(bcap_dev->sd, core,
- s_register, reg);
-}
-#endif
-
-static int bcap_log_status(struct file *file, void *priv)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
- /* status for sub devices */
- v4l2_device_call_all(&bcap_dev->v4l2_dev, 0, core, log_status);
- return 0;
-}
-
-static const struct v4l2_ioctl_ops bcap_ioctl_ops = {
- .vidioc_querycap = bcap_querycap,
- .vidioc_g_fmt_vid_cap = bcap_g_fmt_vid_cap,
- .vidioc_enum_fmt_vid_cap = bcap_enum_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = bcap_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = bcap_try_fmt_vid_cap,
- .vidioc_enum_input = bcap_enum_input,
- .vidioc_g_input = bcap_g_input,
- .vidioc_s_input = bcap_s_input,
- .vidioc_querystd = bcap_querystd,
- .vidioc_s_std = bcap_s_std,
- .vidioc_g_std = bcap_g_std,
- .vidioc_reqbufs = bcap_reqbufs,
- .vidioc_querybuf = bcap_querybuf,
- .vidioc_qbuf = bcap_qbuf,
- .vidioc_dqbuf = bcap_dqbuf,
- .vidioc_streamon = bcap_streamon,
- .vidioc_streamoff = bcap_streamoff,
- .vidioc_g_parm = bcap_g_parm,
- .vidioc_s_parm = bcap_s_parm,
- .vidioc_g_chip_ident = bcap_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = bcap_dbg_g_register,
- .vidioc_s_register = bcap_dbg_s_register,
-#endif
- .vidioc_log_status = bcap_log_status,
-};
-
-static struct v4l2_file_operations bcap_fops = {
- .owner = THIS_MODULE,
- .open = bcap_open,
- .release = bcap_release,
- .unlocked_ioctl = video_ioctl2,
- .mmap = bcap_mmap,
-#ifndef CONFIG_MMU
- .get_unmapped_area = bcap_get_unmapped_area,
-#endif
- .poll = bcap_poll
-};
-
-static int __devinit bcap_probe(struct platform_device *pdev)
-{
- struct bcap_device *bcap_dev;
- struct video_device *vfd;
- struct i2c_adapter *i2c_adap;
- struct bfin_capture_config *config;
- struct vb2_queue *q;
- int ret;
-
- config = pdev->dev.platform_data;
- if (!config) {
- v4l2_err(pdev->dev.driver, "Unable to get board config\n");
- return -ENODEV;
- }
-
- bcap_dev = kzalloc(sizeof(*bcap_dev), GFP_KERNEL);
- if (!bcap_dev) {
- v4l2_err(pdev->dev.driver, "Unable to alloc bcap_dev\n");
- return -ENOMEM;
- }
-
- bcap_dev->cfg = config;
-
- bcap_dev->ppi = ppi_create_instance(config->ppi_info);
- if (!bcap_dev->ppi) {
- v4l2_err(pdev->dev.driver, "Unable to create ppi\n");
- ret = -ENODEV;
- goto err_free_dev;
- }
- bcap_dev->ppi->priv = bcap_dev;
-
- bcap_dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
- if (IS_ERR(bcap_dev->alloc_ctx)) {
- ret = PTR_ERR(bcap_dev->alloc_ctx);
- goto err_free_ppi;
- }
-
- vfd = video_device_alloc();
- if (!vfd) {
- ret = -ENOMEM;
- v4l2_err(pdev->dev.driver, "Unable to alloc video device\n");
- goto err_cleanup_ctx;
- }
-
- /* initialize field of video device */
- vfd->release = video_device_release;
- vfd->fops = &bcap_fops;
- vfd->ioctl_ops = &bcap_ioctl_ops;
- vfd->tvnorms = 0;
- vfd->v4l2_dev = &bcap_dev->v4l2_dev;
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
- strncpy(vfd->name, CAPTURE_DRV_NAME, sizeof(vfd->name));
- bcap_dev->video_dev = vfd;
-
- ret = v4l2_device_register(&pdev->dev, &bcap_dev->v4l2_dev);
- if (ret) {
- v4l2_err(pdev->dev.driver,
- "Unable to register v4l2 device\n");
- goto err_release_vdev;
- }
- v4l2_info(&bcap_dev->v4l2_dev, "v4l2 device registered\n");
-
- bcap_dev->v4l2_dev.ctrl_handler = &bcap_dev->ctrl_handler;
- ret = v4l2_ctrl_handler_init(&bcap_dev->ctrl_handler, 0);
- if (ret) {
- v4l2_err(&bcap_dev->v4l2_dev,
- "Unable to init control handler\n");
- goto err_unreg_v4l2;
- }
-
- spin_lock_init(&bcap_dev->lock);
- /* initialize queue */
- q = &bcap_dev->buffer_queue;
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- q->io_modes = VB2_MMAP;
- q->drv_priv = bcap_dev;
- q->buf_struct_size = sizeof(struct bcap_buffer);
- q->ops = &bcap_video_qops;
- q->mem_ops = &vb2_dma_contig_memops;
-
- vb2_queue_init(q);
-
- mutex_init(&bcap_dev->mutex);
- init_completion(&bcap_dev->comp);
-
- /* init video dma queues */
- INIT_LIST_HEAD(&bcap_dev->dma_queue);
-
- vfd->lock = &bcap_dev->mutex;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
-
- /* register video device */
- ret = video_register_device(bcap_dev->video_dev, VFL_TYPE_GRABBER, -1);
- if (ret) {
- v4l2_err(&bcap_dev->v4l2_dev,
- "Unable to register video device\n");
- goto err_free_handler;
- }
- video_set_drvdata(bcap_dev->video_dev, bcap_dev);
- v4l2_info(&bcap_dev->v4l2_dev, "video device registered as: %s\n",
- video_device_node_name(vfd));
-
- /* load up the subdevice */
- i2c_adap = i2c_get_adapter(config->i2c_adapter_id);
- if (!i2c_adap) {
- v4l2_err(&bcap_dev->v4l2_dev,
- "Unable to find i2c adapter\n");
- goto err_unreg_vdev;
-
- }
- bcap_dev->sd = v4l2_i2c_new_subdev_board(&bcap_dev->v4l2_dev,
- i2c_adap,
- &config->board_info,
- NULL);
- if (bcap_dev->sd) {
- int i;
- /* update tvnorms from the sub devices */
- for (i = 0; i < config->num_inputs; i++)
- vfd->tvnorms |= config->inputs[i].std;
- } else {
- v4l2_err(&bcap_dev->v4l2_dev,
- "Unable to register sub device\n");
- goto err_unreg_vdev;
- }
-
- v4l2_info(&bcap_dev->v4l2_dev, "v4l2 sub device registered\n");
-
- /* now we can probe the default state */
- if (vfd->tvnorms) {
- v4l2_std_id std;
- ret = v4l2_subdev_call(bcap_dev->sd, core, g_std, &std);
- if (ret) {
- v4l2_err(&bcap_dev->v4l2_dev,
- "Unable to get std\n");
- goto err_unreg_vdev;
- }
- bcap_dev->std = std;
- }
- ret = bcap_init_sensor_formats(bcap_dev);
- if (ret) {
- v4l2_err(&bcap_dev->v4l2_dev,
- "Unable to create sensor formats table\n");
- goto err_unreg_vdev;
- }
- return 0;
-err_unreg_vdev:
- video_unregister_device(bcap_dev->video_dev);
- bcap_dev->video_dev = NULL;
-err_free_handler:
- v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler);
-err_unreg_v4l2:
- v4l2_device_unregister(&bcap_dev->v4l2_dev);
-err_release_vdev:
- if (bcap_dev->video_dev)
- video_device_release(bcap_dev->video_dev);
-err_cleanup_ctx:
- vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx);
-err_free_ppi:
- ppi_delete_instance(bcap_dev->ppi);
-err_free_dev:
- kfree(bcap_dev);
- return ret;
-}
-
-static int __devexit bcap_remove(struct platform_device *pdev)
-{
- struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
- struct bcap_device *bcap_dev = container_of(v4l2_dev,
- struct bcap_device, v4l2_dev);
-
- bcap_free_sensor_formats(bcap_dev);
- video_unregister_device(bcap_dev->video_dev);
- v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler);
- v4l2_device_unregister(v4l2_dev);
- vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx);
- ppi_delete_instance(bcap_dev->ppi);
- kfree(bcap_dev);
- return 0;
-}
-
-static struct platform_driver bcap_driver = {
- .driver = {
- .name = CAPTURE_DRV_NAME,
- .owner = THIS_MODULE,
- },
- .probe = bcap_probe,
- .remove = __devexit_p(bcap_remove),
-};
-
-static __init int bcap_init(void)
-{
- return platform_driver_register(&bcap_driver);
-}
-
-static __exit void bcap_exit(void)
-{
- platform_driver_unregister(&bcap_driver);
-}
-
-module_init(bcap_init);
-module_exit(bcap_exit);
-
-MODULE_DESCRIPTION("Analog Devices blackfin video capture driver");
-MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/blackfin/ppi.c b/drivers/media/video/blackfin/ppi.c
deleted file mode 100644
index d29592186b0..00000000000
--- a/drivers/media/video/blackfin/ppi.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * ppi.c Analog Devices Parallel Peripheral Interface driver
- *
- * Copyright (c) 2011 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/slab.h>
-
-#include <asm/bfin_ppi.h>
-#include <asm/blackfin.h>
-#include <asm/cacheflush.h>
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#include <media/blackfin/ppi.h>
-
-static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler);
-static void ppi_detach_irq(struct ppi_if *ppi);
-static int ppi_start(struct ppi_if *ppi);
-static int ppi_stop(struct ppi_if *ppi);
-static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params);
-static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr);
-
-static const struct ppi_ops ppi_ops = {
- .attach_irq = ppi_attach_irq,
- .detach_irq = ppi_detach_irq,
- .start = ppi_start,
- .stop = ppi_stop,
- .set_params = ppi_set_params,
- .update_addr = ppi_update_addr,
-};
-
-static irqreturn_t ppi_irq_err(int irq, void *dev_id)
-{
- struct ppi_if *ppi = dev_id;
- const struct ppi_info *info = ppi->info;
-
- switch (info->type) {
- case PPI_TYPE_PPI:
- {
- struct bfin_ppi_regs *reg = info->base;
- unsigned short status;
-
- /* register on bf561 is cleared when read
- * others are W1C
- */
- status = bfin_read16(&reg->status);
- bfin_write16(&reg->status, 0xff00);
- break;
- }
- case PPI_TYPE_EPPI:
- {
- struct bfin_eppi_regs *reg = info->base;
- bfin_write16(&reg->status, 0xffff);
- break;
- }
- default:
- break;
- }
-
- return IRQ_HANDLED;
-}
-
-static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler)
-{
- const struct ppi_info *info = ppi->info;
- int ret;
-
- ret = request_dma(info->dma_ch, "PPI_DMA");
-
- if (ret) {
- pr_err("Unable to allocate DMA channel for PPI\n");
- return ret;
- }
- set_dma_callback(info->dma_ch, handler, ppi);
-
- if (ppi->err_int) {
- ret = request_irq(info->irq_err, ppi_irq_err, 0, "PPI ERROR", ppi);
- if (ret) {
- pr_err("Unable to allocate IRQ for PPI\n");
- free_dma(info->dma_ch);
- }
- }
- return ret;
-}
-
-static void ppi_detach_irq(struct ppi_if *ppi)
-{
- const struct ppi_info *info = ppi->info;
-
- if (ppi->err_int)
- free_irq(info->irq_err, ppi);
- free_dma(info->dma_ch);
-}
-
-static int ppi_start(struct ppi_if *ppi)
-{
- const struct ppi_info *info = ppi->info;
-
- /* enable DMA */
- enable_dma(info->dma_ch);
-
- /* enable PPI */
- ppi->ppi_control |= PORT_EN;
- switch (info->type) {
- case PPI_TYPE_PPI:
- {
- struct bfin_ppi_regs *reg = info->base;
- bfin_write16(&reg->control, ppi->ppi_control);
- break;
- }
- case PPI_TYPE_EPPI:
- {
- struct bfin_eppi_regs *reg = info->base;
- bfin_write32(&reg->control, ppi->ppi_control);
- break;
- }
- default:
- return -EINVAL;
- }
-
- SSYNC();
- return 0;
-}
-
-static int ppi_stop(struct ppi_if *ppi)
-{
- const struct ppi_info *info = ppi->info;
-
- /* disable PPI */
- ppi->ppi_control &= ~PORT_EN;
- switch (info->type) {
- case PPI_TYPE_PPI:
- {
- struct bfin_ppi_regs *reg = info->base;
- bfin_write16(&reg->control, ppi->ppi_control);
- break;
- }
- case PPI_TYPE_EPPI:
- {
- struct bfin_eppi_regs *reg = info->base;
- bfin_write32(&reg->control, ppi->ppi_control);
- break;
- }
- default:
- return -EINVAL;
- }
-
- /* disable DMA */
- clear_dma_irqstat(info->dma_ch);
- disable_dma(info->dma_ch);
-
- SSYNC();
- return 0;
-}
-
-static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params)
-{
- const struct ppi_info *info = ppi->info;
- int dma32 = 0;
- int dma_config, bytes_per_line, lines_per_frame;
-
- bytes_per_line = params->width * params->bpp / 8;
- lines_per_frame = params->height;
- if (params->int_mask == 0xFFFFFFFF)
- ppi->err_int = false;
- else
- ppi->err_int = true;
-
- dma_config = (DMA_FLOW_STOP | WNR | RESTART | DMA2D | DI_EN);
- ppi->ppi_control = params->ppi_control & ~PORT_EN;
- switch (info->type) {
- case PPI_TYPE_PPI:
- {
- struct bfin_ppi_regs *reg = info->base;
-
- if (params->ppi_control & DMA32)
- dma32 = 1;
-
- bfin_write16(&reg->control, ppi->ppi_control);
- bfin_write16(&reg->count, bytes_per_line - 1);
- bfin_write16(&reg->frame, lines_per_frame);
- break;
- }
- case PPI_TYPE_EPPI:
- {
- struct bfin_eppi_regs *reg = info->base;
-
- if ((params->ppi_control & PACK_EN)
- || (params->ppi_control & 0x38000) > DLEN_16)
- dma32 = 1;
-
- bfin_write32(&reg->control, ppi->ppi_control);
- bfin_write16(&reg->line, bytes_per_line + params->blank_clocks);
- bfin_write16(&reg->frame, lines_per_frame);
- bfin_write16(&reg->hdelay, 0);
- bfin_write16(&reg->vdelay, 0);
- bfin_write16(&reg->hcount, bytes_per_line);
- bfin_write16(&reg->vcount, lines_per_frame);
- break;
- }
- default:
- return -EINVAL;
- }
-
- if (dma32) {
- dma_config |= WDSIZE_32;
- set_dma_x_count(info->dma_ch, bytes_per_line >> 2);
- set_dma_x_modify(info->dma_ch, 4);
- set_dma_y_modify(info->dma_ch, 4);
- } else {
- dma_config |= WDSIZE_16;
- set_dma_x_count(info->dma_ch, bytes_per_line >> 1);
- set_dma_x_modify(info->dma_ch, 2);
- set_dma_y_modify(info->dma_ch, 2);
- }
- set_dma_y_count(info->dma_ch, lines_per_frame);
- set_dma_config(info->dma_ch, dma_config);
-
- SSYNC();
- return 0;
-}
-
-static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr)
-{
- set_dma_start_addr(ppi->info->dma_ch, addr);
-}
-
-struct ppi_if *ppi_create_instance(const struct ppi_info *info)
-{
- struct ppi_if *ppi;
-
- if (!info || !info->pin_req)
- return NULL;
-
- if (peripheral_request_list(info->pin_req, KBUILD_MODNAME)) {
- pr_err("request peripheral failed\n");
- return NULL;
- }
-
- ppi = kzalloc(sizeof(*ppi), GFP_KERNEL);
- if (!ppi) {
- peripheral_free_list(info->pin_req);
- pr_err("unable to allocate memory for ppi handle\n");
- return NULL;
- }
- ppi->ops = &ppi_ops;
- ppi->info = info;
-
- pr_info("ppi probe success\n");
- return ppi;
-}
-
-void ppi_delete_instance(struct ppi_if *ppi)
-{
- peripheral_free_list(ppi->info->pin_req);
- kfree(ppi);
-}
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
deleted file mode 100644
index 377bf05b1ef..00000000000
--- a/drivers/media/video/bt819.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- * bt819 - BT819A VideoStream Decoder (Rockwell Part)
- *
- * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- *
- * Modifications for LML33/DC10plus unified driver
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- *
- * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
- * - moved over to linux>=2.4.x i2c protocol (9/9/2002)
- *
- * This code was modify/ported from the saa7111 driver written
- * by Dave Perks.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-#include <media/bt819.h>
-
-MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
-MODULE_AUTHOR("Mike Bernson & Dave Perks");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-
-/* ----------------------------------------------------------------------- */
-
-struct bt819 {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- unsigned char reg[32];
-
- v4l2_std_id norm;
- int ident;
- int input;
- int enable;
-};
-
-static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct bt819, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct bt819, hdl)->sd;
-}
-
-struct timing {
- int hactive;
- int hdelay;
- int vactive;
- int vdelay;
- int hscale;
- int vscale;
-};
-
-/* for values, see the bt819 datasheet */
-static struct timing timing_data[] = {
- {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
- {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
-};
-
-/* ----------------------------------------------------------------------- */
-
-static inline int bt819_write(struct bt819 *decoder, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
-
- decoder->reg[reg] = value;
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static inline int bt819_setbit(struct bt819 *decoder, u8 reg, u8 bit, u8 value)
-{
- return bt819_write(decoder, reg,
- (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
-}
-
-static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int len)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
- int ret = -1;
- u8 reg;
-
- /* the bt819 has an autoincrement function, use it if
- * the adapter understands raw I2C */
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- /* do raw I2C, not smbus compatible */
- u8 block_data[32];
- int block_len;
-
- while (len >= 2) {
- block_len = 0;
- block_data[block_len++] = reg = data[0];
- do {
- block_data[block_len++] =
- decoder->reg[reg++] = data[1];
- len -= 2;
- data += 2;
- } while (len >= 2 && data[0] == reg && block_len < 32);
- ret = i2c_master_send(client, block_data, block_len);
- if (ret < 0)
- break;
- }
- } else {
- /* do some slow I2C emulation kind of thing */
- while (len >= 2) {
- reg = *data++;
- ret = bt819_write(decoder, reg, *data++);
- if (ret < 0)
- break;
- len -= 2;
- }
- }
-
- return ret;
-}
-
-static inline int bt819_read(struct bt819 *decoder, u8 reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
-
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int bt819_init(struct v4l2_subdev *sd)
-{
- static unsigned char init[] = {
- /*0x1f, 0x00,*/ /* Reset */
- 0x01, 0x59, /* 0x01 input format */
- 0x02, 0x00, /* 0x02 temporal decimation */
- 0x03, 0x12, /* 0x03 Cropping msb */
- 0x04, 0x16, /* 0x04 Vertical Delay, lsb */
- 0x05, 0xe0, /* 0x05 Vertical Active lsb */
- 0x06, 0x80, /* 0x06 Horizontal Delay lsb */
- 0x07, 0xd0, /* 0x07 Horizontal Active lsb */
- 0x08, 0x00, /* 0x08 Horizontal Scaling msb */
- 0x09, 0xf8, /* 0x09 Horizontal Scaling lsb */
- 0x0a, 0x00, /* 0x0a Brightness control */
- 0x0b, 0x30, /* 0x0b Miscellaneous control */
- 0x0c, 0xd8, /* 0x0c Luma Gain lsb */
- 0x0d, 0xfe, /* 0x0d Chroma Gain (U) lsb */
- 0x0e, 0xb4, /* 0x0e Chroma Gain (V) msb */
- 0x0f, 0x00, /* 0x0f Hue control */
- 0x12, 0x04, /* 0x12 Output Format */
- 0x13, 0x20, /* 0x13 Vertial Scaling msb 0x00
- chroma comb OFF, line drop scaling, interlace scaling
- BUG? Why does turning the chroma comb on fuck up color?
- Bug in the bt819 stepping on my board?
- */
- 0x14, 0x00, /* 0x14 Vertial Scaling lsb */
- 0x16, 0x07, /* 0x16 Video Timing Polarity
- ACTIVE=active low
- FIELD: high=odd,
- vreset=active high,
- hreset=active high */
- 0x18, 0x68, /* 0x18 AGC Delay */
- 0x19, 0x5d, /* 0x19 Burst Gate Delay */
- 0x1a, 0x80, /* 0x1a ADC Interface */
- };
-
- struct bt819 *decoder = to_bt819(sd);
- struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0];
-
- init[0x03 * 2 - 1] =
- (((timing->vdelay >> 8) & 0x03) << 6) |
- (((timing->vactive >> 8) & 0x03) << 4) |
- (((timing->hdelay >> 8) & 0x03) << 2) |
- ((timing->hactive >> 8) & 0x03);
- init[0x04 * 2 - 1] = timing->vdelay & 0xff;
- init[0x05 * 2 - 1] = timing->vactive & 0xff;
- init[0x06 * 2 - 1] = timing->hdelay & 0xff;
- init[0x07 * 2 - 1] = timing->hactive & 0xff;
- init[0x08 * 2 - 1] = timing->hscale >> 8;
- init[0x09 * 2 - 1] = timing->hscale & 0xff;
- /* 0x15 in array is address 0x19 */
- init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93; /* Chroma burst delay */
- /* reset */
- bt819_write(decoder, 0x1f, 0x00);
- mdelay(1);
-
- /* init */
- return bt819_write_block(decoder, init, sizeof(init));
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int bt819_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
-{
- struct bt819 *decoder = to_bt819(sd);
- int status = bt819_read(decoder, 0x00);
- int res = V4L2_IN_ST_NO_SIGNAL;
- v4l2_std_id std;
-
- if ((status & 0x80))
- res = 0;
-
- if ((status & 0x10))
- std = V4L2_STD_PAL;
- else
- std = V4L2_STD_NTSC;
- if (pstd)
- *pstd = std;
- if (pstatus)
- *pstatus = res;
-
- v4l2_dbg(1, debug, sd, "get status %x\n", status);
- return 0;
-}
-
-static int bt819_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
-{
- return bt819_status(sd, NULL, std);
-}
-
-static int bt819_g_input_status(struct v4l2_subdev *sd, u32 *status)
-{
- return bt819_status(sd, status, NULL);
-}
-
-static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct bt819 *decoder = to_bt819(sd);
- struct timing *timing = NULL;
-
- v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
-
- if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
- v4l2_err(sd, "no notify found!\n");
-
- if (std & V4L2_STD_NTSC) {
- v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
- bt819_setbit(decoder, 0x01, 0, 1);
- bt819_setbit(decoder, 0x01, 1, 0);
- bt819_setbit(decoder, 0x01, 5, 0);
- bt819_write(decoder, 0x18, 0x68);
- bt819_write(decoder, 0x19, 0x5d);
- /* bt819_setbit(decoder, 0x1a, 5, 1); */
- timing = &timing_data[1];
- } else if (std & V4L2_STD_PAL) {
- v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
- bt819_setbit(decoder, 0x01, 0, 1);
- bt819_setbit(decoder, 0x01, 1, 1);
- bt819_setbit(decoder, 0x01, 5, 1);
- bt819_write(decoder, 0x18, 0x7f);
- bt819_write(decoder, 0x19, 0x72);
- /* bt819_setbit(decoder, 0x1a, 5, 0); */
- timing = &timing_data[0];
- } else {
- v4l2_dbg(1, debug, sd, "unsupported norm %llx\n",
- (unsigned long long)std);
- return -EINVAL;
- }
- bt819_write(decoder, 0x03,
- (((timing->vdelay >> 8) & 0x03) << 6) |
- (((timing->vactive >> 8) & 0x03) << 4) |
- (((timing->hdelay >> 8) & 0x03) << 2) |
- ((timing->hactive >> 8) & 0x03));
- bt819_write(decoder, 0x04, timing->vdelay & 0xff);
- bt819_write(decoder, 0x05, timing->vactive & 0xff);
- bt819_write(decoder, 0x06, timing->hdelay & 0xff);
- bt819_write(decoder, 0x07, timing->hactive & 0xff);
- bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff);
- bt819_write(decoder, 0x09, timing->hscale & 0xff);
- decoder->norm = std;
- v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
- return 0;
-}
-
-static int bt819_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct bt819 *decoder = to_bt819(sd);
-
- v4l2_dbg(1, debug, sd, "set input %x\n", input);
-
- if (input > 7)
- return -EINVAL;
-
- if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
- v4l2_err(sd, "no notify found!\n");
-
- if (decoder->input != input) {
- v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
- decoder->input = input;
- /* select mode */
- if (decoder->input == 0) {
- bt819_setbit(decoder, 0x0b, 6, 0);
- bt819_setbit(decoder, 0x1a, 1, 1);
- } else {
- bt819_setbit(decoder, 0x0b, 6, 1);
- bt819_setbit(decoder, 0x1a, 1, 0);
- }
- v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
- }
- return 0;
-}
-
-static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct bt819 *decoder = to_bt819(sd);
-
- v4l2_dbg(1, debug, sd, "enable output %x\n", enable);
-
- if (decoder->enable != enable) {
- decoder->enable = enable;
- bt819_setbit(decoder, 0x16, 7, !enable);
- }
- return 0;
-}
-
-static int bt819_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct bt819 *decoder = to_bt819(sd);
- int temp;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- bt819_write(decoder, 0x0a, ctrl->val);
- break;
-
- case V4L2_CID_CONTRAST:
- bt819_write(decoder, 0x0c, ctrl->val & 0xff);
- bt819_setbit(decoder, 0x0b, 2, ((ctrl->val >> 8) & 0x01));
- break;
-
- case V4L2_CID_SATURATION:
- bt819_write(decoder, 0x0d, (ctrl->val >> 7) & 0xff);
- bt819_setbit(decoder, 0x0b, 1, ((ctrl->val >> 15) & 0x01));
-
- /* Ratio between U gain and V gain must stay the same as
- the ratio between the default U and V gain values. */
- temp = (ctrl->val * 180) / 254;
- bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
- bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
- break;
-
- case V4L2_CID_HUE:
- bt819_write(decoder, 0x0f, ctrl->val);
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct bt819 *decoder = to_bt819(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
- .s_ctrl = bt819_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops bt819_core_ops = {
- .g_chip_ident = bt819_g_chip_ident,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
- .s_std = bt819_s_std,
-};
-
-static const struct v4l2_subdev_video_ops bt819_video_ops = {
- .s_routing = bt819_s_routing,
- .s_stream = bt819_s_stream,
- .querystd = bt819_querystd,
- .g_input_status = bt819_g_input_status,
-};
-
-static const struct v4l2_subdev_ops bt819_ops = {
- .core = &bt819_core_ops,
- .video = &bt819_video_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int bt819_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int i, ver;
- struct bt819 *decoder;
- struct v4l2_subdev *sd;
- const char *name;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
- if (decoder == NULL)
- return -ENOMEM;
- sd = &decoder->sd;
- v4l2_i2c_subdev_init(sd, client, &bt819_ops);
-
- ver = bt819_read(decoder, 0x17);
- switch (ver & 0xf0) {
- case 0x70:
- name = "bt819a";
- decoder->ident = V4L2_IDENT_BT819A;
- break;
- case 0x60:
- name = "bt817a";
- decoder->ident = V4L2_IDENT_BT817A;
- break;
- case 0x20:
- name = "bt815a";
- decoder->ident = V4L2_IDENT_BT815A;
- break;
- default:
- v4l2_dbg(1, debug, sd,
- "unknown chip version 0x%02x\n", ver);
- return -ENODEV;
- }
-
- v4l_info(client, "%s found @ 0x%x (%s)\n", name,
- client->addr << 1, client->adapter->name);
-
- decoder->norm = V4L2_STD_NTSC;
- decoder->input = 0;
- decoder->enable = 1;
-
- i = bt819_init(sd);
- if (i < 0)
- v4l2_dbg(1, debug, sd, "init status %d\n", i);
-
- v4l2_ctrl_handler_init(&decoder->hdl, 4);
- v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
- V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
- v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 511, 1, 0xd8);
- v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
- V4L2_CID_SATURATION, 0, 511, 1, 0xfe);
- v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
- V4L2_CID_HUE, -128, 127, 1, 0);
- sd->ctrl_handler = &decoder->hdl;
- if (decoder->hdl.error) {
- int err = decoder->hdl.error;
-
- v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(decoder);
- return err;
- }
- v4l2_ctrl_handler_setup(&decoder->hdl);
- return 0;
-}
-
-static int bt819_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct bt819 *decoder = to_bt819(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(decoder);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id bt819_id[] = {
- { "bt819a", 0 },
- { "bt817a", 0 },
- { "bt815a", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, bt819_id);
-
-static struct i2c_driver bt819_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "bt819",
- },
- .probe = bt819_probe,
- .remove = bt819_remove,
- .id_table = bt819_id,
-};
-
-module_i2c_driver(bt819_driver);
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
deleted file mode 100644
index 7e5bd365c23..00000000000
--- a/drivers/media/video/bt856.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * bt856 - BT856A Digital Video Encoder (Rockwell Part)
- *
- * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- *
- * Modifications for LML33/DC10plus unified driver
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- *
- * This code was modify/ported from the saa7111 driver written
- * by Dave Perks.
- *
- * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
- * - moved over to linux>=2.4.x i2c protocol (9/9/2002)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-
-MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
-MODULE_AUTHOR("Mike Bernson & Dave Perks");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-
-/* ----------------------------------------------------------------------- */
-
-#define BT856_REG_OFFSET 0xDA
-#define BT856_NR_REG 6
-
-struct bt856 {
- struct v4l2_subdev sd;
- unsigned char reg[BT856_NR_REG];
-
- v4l2_std_id norm;
-};
-
-static inline struct bt856 *to_bt856(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct bt856, sd);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static inline int bt856_write(struct bt856 *encoder, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd);
-
- encoder->reg[reg - BT856_REG_OFFSET] = value;
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static inline int bt856_setbit(struct bt856 *encoder, u8 reg, u8 bit, u8 value)
-{
- return bt856_write(encoder, reg,
- (encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) |
- (value ? (1 << bit) : 0));
-}
-
-static void bt856_dump(struct bt856 *encoder)
-{
- int i;
-
- v4l2_info(&encoder->sd, "register dump:\n");
- for (i = 0; i < BT856_NR_REG; i += 2)
- printk(KERN_CONT " %02x", encoder->reg[i]);
- printk(KERN_CONT "\n");
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int bt856_init(struct v4l2_subdev *sd, u32 arg)
-{
- struct bt856 *encoder = to_bt856(sd);
-
- /* This is just for testing!!! */
- v4l2_dbg(1, debug, sd, "init\n");
- bt856_write(encoder, 0xdc, 0x18);
- bt856_write(encoder, 0xda, 0);
- bt856_write(encoder, 0xde, 0);
-
- bt856_setbit(encoder, 0xdc, 3, 1);
- /*bt856_setbit(encoder, 0xdc, 6, 0);*/
- bt856_setbit(encoder, 0xdc, 4, 1);
-
- if (encoder->norm & V4L2_STD_NTSC)
- bt856_setbit(encoder, 0xdc, 2, 0);
- else
- bt856_setbit(encoder, 0xdc, 2, 1);
-
- bt856_setbit(encoder, 0xdc, 1, 1);
- bt856_setbit(encoder, 0xde, 4, 0);
- bt856_setbit(encoder, 0xde, 3, 1);
- if (debug != 0)
- bt856_dump(encoder);
- return 0;
-}
-
-static int bt856_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct bt856 *encoder = to_bt856(sd);
-
- v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
-
- if (std & V4L2_STD_NTSC) {
- bt856_setbit(encoder, 0xdc, 2, 0);
- } else if (std & V4L2_STD_PAL) {
- bt856_setbit(encoder, 0xdc, 2, 1);
- bt856_setbit(encoder, 0xda, 0, 0);
- /*bt856_setbit(encoder, 0xda, 0, 1);*/
- } else {
- return -EINVAL;
- }
- encoder->norm = std;
- if (debug != 0)
- bt856_dump(encoder);
- return 0;
-}
-
-static int bt856_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct bt856 *encoder = to_bt856(sd);
-
- v4l2_dbg(1, debug, sd, "set input %d\n", input);
-
- /* We only have video bus.
- * input= 0: input is from bt819
- * input= 1: input is from ZR36060 */
- switch (input) {
- case 0:
- bt856_setbit(encoder, 0xde, 4, 0);
- bt856_setbit(encoder, 0xde, 3, 1);
- bt856_setbit(encoder, 0xdc, 3, 1);
- bt856_setbit(encoder, 0xdc, 6, 0);
- break;
- case 1:
- bt856_setbit(encoder, 0xde, 4, 0);
- bt856_setbit(encoder, 0xde, 3, 1);
- bt856_setbit(encoder, 0xdc, 3, 1);
- bt856_setbit(encoder, 0xdc, 6, 1);
- break;
- case 2: /* Color bar */
- bt856_setbit(encoder, 0xdc, 3, 0);
- bt856_setbit(encoder, 0xde, 4, 1);
- break;
- default:
- return -EINVAL;
- }
-
- if (debug != 0)
- bt856_dump(encoder);
- return 0;
-}
-
-static int bt856_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT856, 0);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops bt856_core_ops = {
- .g_chip_ident = bt856_g_chip_ident,
- .init = bt856_init,
-};
-
-static const struct v4l2_subdev_video_ops bt856_video_ops = {
- .s_std_output = bt856_s_std_output,
- .s_routing = bt856_s_routing,
-};
-
-static const struct v4l2_subdev_ops bt856_ops = {
- .core = &bt856_core_ops,
- .video = &bt856_video_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int bt856_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct bt856 *encoder;
- struct v4l2_subdev *sd;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
- if (encoder == NULL)
- return -ENOMEM;
- sd = &encoder->sd;
- v4l2_i2c_subdev_init(sd, client, &bt856_ops);
- encoder->norm = V4L2_STD_NTSC;
-
- bt856_write(encoder, 0xdc, 0x18);
- bt856_write(encoder, 0xda, 0);
- bt856_write(encoder, 0xde, 0);
-
- bt856_setbit(encoder, 0xdc, 3, 1);
- /*bt856_setbit(encoder, 0xdc, 6, 0);*/
- bt856_setbit(encoder, 0xdc, 4, 1);
-
- if (encoder->norm & V4L2_STD_NTSC)
- bt856_setbit(encoder, 0xdc, 2, 0);
- else
- bt856_setbit(encoder, 0xdc, 2, 1);
-
- bt856_setbit(encoder, 0xdc, 1, 1);
- bt856_setbit(encoder, 0xde, 4, 0);
- bt856_setbit(encoder, 0xde, 3, 1);
-
- if (debug != 0)
- bt856_dump(encoder);
- return 0;
-}
-
-static int bt856_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(to_bt856(sd));
- return 0;
-}
-
-static const struct i2c_device_id bt856_id[] = {
- { "bt856", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, bt856_id);
-
-static struct i2c_driver bt856_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "bt856",
- },
- .probe = bt856_probe,
- .remove = bt856_remove,
- .id_table = bt856_id,
-};
-
-module_i2c_driver(bt856_driver);
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c
deleted file mode 100644
index 905320b67a1..00000000000
--- a/drivers/media/video/bt866.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- bt866 - BT866 Digital Video Encoder (Rockwell Part)
-
- Copyright (C) 1999 Mike Bernson <mike@mlb.org>
- Copyright (C) 1998 Dave Perks <dperks@ibm.net>
-
- Modifications for LML33/DC10plus unified driver
- Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
-
- This code was modify/ported from the saa7111 driver written
- by Dave Perks.
-
- This code was adapted for the bt866 by Christer Weinigel and ported
- to 2.6 by Martin Samuelsson.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-
-MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
-MODULE_AUTHOR("Mike Bernson & Dave Perks");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-
-/* ----------------------------------------------------------------------- */
-
-struct bt866 {
- struct v4l2_subdev sd;
- u8 reg[256];
-};
-
-static inline struct bt866 *to_bt866(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct bt866, sd);
-}
-
-static int bt866_write(struct bt866 *encoder, u8 subaddr, u8 data)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd);
- u8 buffer[2];
- int err;
-
- buffer[0] = subaddr;
- buffer[1] = data;
-
- encoder->reg[subaddr] = data;
-
- v4l_dbg(1, debug, client, "write 0x%02x = 0x%02x\n", subaddr, data);
-
- for (err = 0; err < 3;) {
- if (i2c_master_send(client, buffer, 2) == 2)
- break;
- err++;
- v4l_warn(client, "error #%d writing to 0x%02x\n",
- err, subaddr);
- schedule_timeout_interruptible(msecs_to_jiffies(100));
- }
- if (err == 3) {
- v4l_warn(client, "giving up\n");
- return -1;
- }
-
- return 0;
-}
-
-static int bt866_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
-
- /* Only PAL supported by this driver at the moment! */
- if (!(std & V4L2_STD_NTSC))
- return -EINVAL;
- return 0;
-}
-
-static int bt866_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- static const __u8 init[] = {
- 0xc8, 0xcc, /* CRSCALE */
- 0xca, 0x91, /* CBSCALE */
- 0xcc, 0x24, /* YC16 | OSDNUM */
- 0xda, 0x00, /* */
- 0xdc, 0x24, /* SETMODE | PAL */
- 0xde, 0x02, /* EACTIVE */
-
- /* overlay colors */
- 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
- 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
- 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
- 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
- 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
- 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
- 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
- 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
-
- 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
- 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
- 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
- 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
- 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
- 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
- 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
- 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
- };
- struct bt866 *encoder = to_bt866(sd);
- u8 val;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
- bt866_write(encoder, init[i], init[i+1]);
-
- val = encoder->reg[0xdc];
-
- if (input == 0)
- val |= 0x40; /* CBSWAP */
- else
- val &= ~0x40; /* !CBSWAP */
-
- bt866_write(encoder, 0xdc, val);
-
- val = encoder->reg[0xcc];
- if (input == 2)
- val |= 0x01; /* OSDBAR */
- else
- val &= ~0x01; /* !OSDBAR */
- bt866_write(encoder, 0xcc, val);
-
- v4l2_dbg(1, debug, sd, "set input %d\n", input);
-
- switch (input) {
- case 0:
- case 1:
- case 2:
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-#if 0
-/* Code to setup square pixels, might be of some use in the future,
- but is currently unused. */
- val = encoder->reg[0xdc];
- if (*iarg)
- val |= 1; /* SQUARE */
- else
- val &= ~1; /* !SQUARE */
- bt866_write(client, 0xdc, val);
-#endif
-
-static int bt866_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT866, 0);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops bt866_core_ops = {
- .g_chip_ident = bt866_g_chip_ident,
-};
-
-static const struct v4l2_subdev_video_ops bt866_video_ops = {
- .s_std_output = bt866_s_std_output,
- .s_routing = bt866_s_routing,
-};
-
-static const struct v4l2_subdev_ops bt866_ops = {
- .core = &bt866_core_ops,
- .video = &bt866_video_ops,
-};
-
-static int bt866_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct bt866 *encoder;
- struct v4l2_subdev *sd;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
- if (encoder == NULL)
- return -ENOMEM;
- sd = &encoder->sd;
- v4l2_i2c_subdev_init(sd, client, &bt866_ops);
- return 0;
-}
-
-static int bt866_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(to_bt866(sd));
- return 0;
-}
-
-static const struct i2c_device_id bt866_id[] = {
- { "bt866", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, bt866_id);
-
-static struct i2c_driver bt866_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "bt866",
- },
- .probe = bt866_probe,
- .remove = bt866_remove,
- .id_table = bt866_id,
-};
-
-module_i2c_driver(bt866_driver);
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
deleted file mode 100644
index 7da5c2e1fc1..00000000000
--- a/drivers/media/video/bt8xx/Kconfig
+++ /dev/null
@@ -1,27 +0,0 @@
-config VIDEO_BT848
- tristate "BT848 Video For Linux"
- depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2
- select I2C_ALGOBIT
- select VIDEO_BTCX
- select VIDEOBUF_DMA_SG
- depends on RC_CORE
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TDA7432 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO
- ---help---
- Support for BT848 based frame grabber/overlay boards. This includes
- the Miro, Hauppauge and STB boards. Please read the material in
- <file:Documentation/video4linux/bttv/> for more information.
-
- To compile this driver as a module, choose M here: the
- module will be called bttv.
-
-config VIDEO_BT848_DVB
- bool "DVB/ATSC Support for bt878 based TV cards"
- depends on VIDEO_BT848 && DVB_CORE
- select DVB_BT8XX
- ---help---
- This adds support for DVB/ATSC cards based on the BT878 chip.
diff --git a/drivers/media/video/bt8xx/Makefile b/drivers/media/video/bt8xx/Makefile
deleted file mode 100644
index 3f9a2b22d3d..00000000000
--- a/drivers/media/video/bt8xx/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Makefile for the video capture/playback device drivers.
-#
-
-bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
- bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \
- bttv-input.o bttv-audio-hook.o
-
-obj-$(CONFIG_VIDEO_BT848) += bttv.o
-
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
diff --git a/drivers/media/video/bt8xx/bt848.h b/drivers/media/video/bt8xx/bt848.h
deleted file mode 100644
index c37e6acffde..00000000000
--- a/drivers/media/video/bt8xx/bt848.h
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- bt848.h - Bt848 register offsets
-
- Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _BT848_H_
-#define _BT848_H_
-
-#ifndef PCI_VENDOR_ID_BROOKTREE
-#define PCI_VENDOR_ID_BROOKTREE 0x109e
-#endif
-#ifndef PCI_DEVICE_ID_BT848
-#define PCI_DEVICE_ID_BT848 0x350
-#endif
-#ifndef PCI_DEVICE_ID_BT849
-#define PCI_DEVICE_ID_BT849 0x351
-#endif
-#ifndef PCI_DEVICE_ID_FUSION879
-#define PCI_DEVICE_ID_FUSION879 0x36c
-#endif
-
-#ifndef PCI_DEVICE_ID_BT878
-#define PCI_DEVICE_ID_BT878 0x36e
-#endif
-#ifndef PCI_DEVICE_ID_BT879
-#define PCI_DEVICE_ID_BT879 0x36f
-#endif
-
-/* Brooktree 848 registers */
-
-#define BT848_DSTATUS 0x000
-#define BT848_DSTATUS_PRES (1<<7)
-#define BT848_DSTATUS_HLOC (1<<6)
-#define BT848_DSTATUS_FIELD (1<<5)
-#define BT848_DSTATUS_NUML (1<<4)
-#define BT848_DSTATUS_CSEL (1<<3)
-#define BT848_DSTATUS_PLOCK (1<<2)
-#define BT848_DSTATUS_LOF (1<<1)
-#define BT848_DSTATUS_COF (1<<0)
-
-#define BT848_IFORM 0x004
-#define BT848_IFORM_HACTIVE (1<<7)
-#define BT848_IFORM_MUXSEL (3<<5)
-#define BT848_IFORM_MUX0 (2<<5)
-#define BT848_IFORM_MUX1 (3<<5)
-#define BT848_IFORM_MUX2 (1<<5)
-#define BT848_IFORM_XTSEL (3<<3)
-#define BT848_IFORM_XT0 (1<<3)
-#define BT848_IFORM_XT1 (2<<3)
-#define BT848_IFORM_XTAUTO (3<<3)
-#define BT848_IFORM_XTBOTH (3<<3)
-#define BT848_IFORM_NTSC 1
-#define BT848_IFORM_NTSC_J 2
-#define BT848_IFORM_PAL_BDGHI 3
-#define BT848_IFORM_PAL_M 4
-#define BT848_IFORM_PAL_N 5
-#define BT848_IFORM_SECAM 6
-#define BT848_IFORM_PAL_NC 7
-#define BT848_IFORM_AUTO 0
-#define BT848_IFORM_NORM 7
-
-#define BT848_TDEC 0x008
-#define BT848_TDEC_DEC_FIELD (1<<7)
-#define BT848_TDEC_FLDALIGN (1<<6)
-#define BT848_TDEC_DEC_RAT (0x1f)
-
-#define BT848_E_CROP 0x00C
-#define BT848_O_CROP 0x08C
-
-#define BT848_E_VDELAY_LO 0x010
-#define BT848_O_VDELAY_LO 0x090
-
-#define BT848_E_VACTIVE_LO 0x014
-#define BT848_O_VACTIVE_LO 0x094
-
-#define BT848_E_HDELAY_LO 0x018
-#define BT848_O_HDELAY_LO 0x098
-
-#define BT848_E_HACTIVE_LO 0x01C
-#define BT848_O_HACTIVE_LO 0x09C
-
-#define BT848_E_HSCALE_HI 0x020
-#define BT848_O_HSCALE_HI 0x0A0
-
-#define BT848_E_HSCALE_LO 0x024
-#define BT848_O_HSCALE_LO 0x0A4
-
-#define BT848_BRIGHT 0x028
-
-#define BT848_E_CONTROL 0x02C
-#define BT848_O_CONTROL 0x0AC
-#define BT848_CONTROL_LNOTCH (1<<7)
-#define BT848_CONTROL_COMP (1<<6)
-#define BT848_CONTROL_LDEC (1<<5)
-#define BT848_CONTROL_CBSENSE (1<<4)
-#define BT848_CONTROL_CON_MSB (1<<2)
-#define BT848_CONTROL_SAT_U_MSB (1<<1)
-#define BT848_CONTROL_SAT_V_MSB (1<<0)
-
-#define BT848_CONTRAST_LO 0x030
-#define BT848_SAT_U_LO 0x034
-#define BT848_SAT_V_LO 0x038
-#define BT848_HUE 0x03C
-
-#define BT848_E_SCLOOP 0x040
-#define BT848_O_SCLOOP 0x0C0
-#define BT848_SCLOOP_CAGC (1<<6)
-#define BT848_SCLOOP_CKILL (1<<5)
-#define BT848_SCLOOP_HFILT_AUTO (0<<3)
-#define BT848_SCLOOP_HFILT_CIF (1<<3)
-#define BT848_SCLOOP_HFILT_QCIF (2<<3)
-#define BT848_SCLOOP_HFILT_ICON (3<<3)
-
-#define BT848_SCLOOP_PEAK (1<<7)
-#define BT848_SCLOOP_HFILT_MINP (1<<3)
-#define BT848_SCLOOP_HFILT_MEDP (2<<3)
-#define BT848_SCLOOP_HFILT_MAXP (3<<3)
-
-
-#define BT848_OFORM 0x048
-#define BT848_OFORM_RANGE (1<<7)
-#define BT848_OFORM_CORE0 (0<<5)
-#define BT848_OFORM_CORE8 (1<<5)
-#define BT848_OFORM_CORE16 (2<<5)
-#define BT848_OFORM_CORE32 (3<<5)
-
-#define BT848_E_VSCALE_HI 0x04C
-#define BT848_O_VSCALE_HI 0x0CC
-#define BT848_VSCALE_YCOMB (1<<7)
-#define BT848_VSCALE_COMB (1<<6)
-#define BT848_VSCALE_INT (1<<5)
-#define BT848_VSCALE_HI 15
-
-#define BT848_E_VSCALE_LO 0x050
-#define BT848_O_VSCALE_LO 0x0D0
-#define BT848_TEST 0x054
-#define BT848_ADELAY 0x060
-#define BT848_BDELAY 0x064
-
-#define BT848_ADC 0x068
-#define BT848_ADC_RESERVED (2<<6)
-#define BT848_ADC_SYNC_T (1<<5)
-#define BT848_ADC_AGC_EN (1<<4)
-#define BT848_ADC_CLK_SLEEP (1<<3)
-#define BT848_ADC_Y_SLEEP (1<<2)
-#define BT848_ADC_C_SLEEP (1<<1)
-#define BT848_ADC_CRUSH (1<<0)
-
-#define BT848_WC_UP 0x044
-#define BT848_WC_DOWN 0x078
-
-#define BT848_E_VTC 0x06C
-#define BT848_O_VTC 0x0EC
-#define BT848_VTC_HSFMT (1<<7)
-#define BT848_VTC_VFILT_2TAP 0
-#define BT848_VTC_VFILT_3TAP 1
-#define BT848_VTC_VFILT_4TAP 2
-#define BT848_VTC_VFILT_5TAP 3
-
-#define BT848_SRESET 0x07C
-
-#define BT848_COLOR_FMT 0x0D4
-#define BT848_COLOR_FMT_O_RGB32 (0<<4)
-#define BT848_COLOR_FMT_O_RGB24 (1<<4)
-#define BT848_COLOR_FMT_O_RGB16 (2<<4)
-#define BT848_COLOR_FMT_O_RGB15 (3<<4)
-#define BT848_COLOR_FMT_O_YUY2 (4<<4)
-#define BT848_COLOR_FMT_O_BtYUV (5<<4)
-#define BT848_COLOR_FMT_O_Y8 (6<<4)
-#define BT848_COLOR_FMT_O_RGB8 (7<<4)
-#define BT848_COLOR_FMT_O_YCrCb422 (8<<4)
-#define BT848_COLOR_FMT_O_YCrCb411 (9<<4)
-#define BT848_COLOR_FMT_O_RAW (14<<4)
-#define BT848_COLOR_FMT_E_RGB32 0
-#define BT848_COLOR_FMT_E_RGB24 1
-#define BT848_COLOR_FMT_E_RGB16 2
-#define BT848_COLOR_FMT_E_RGB15 3
-#define BT848_COLOR_FMT_E_YUY2 4
-#define BT848_COLOR_FMT_E_BtYUV 5
-#define BT848_COLOR_FMT_E_Y8 6
-#define BT848_COLOR_FMT_E_RGB8 7
-#define BT848_COLOR_FMT_E_YCrCb422 8
-#define BT848_COLOR_FMT_E_YCrCb411 9
-#define BT848_COLOR_FMT_E_RAW 14
-
-#define BT848_COLOR_FMT_RGB32 0x00
-#define BT848_COLOR_FMT_RGB24 0x11
-#define BT848_COLOR_FMT_RGB16 0x22
-#define BT848_COLOR_FMT_RGB15 0x33
-#define BT848_COLOR_FMT_YUY2 0x44
-#define BT848_COLOR_FMT_BtYUV 0x55
-#define BT848_COLOR_FMT_Y8 0x66
-#define BT848_COLOR_FMT_RGB8 0x77
-#define BT848_COLOR_FMT_YCrCb422 0x88
-#define BT848_COLOR_FMT_YCrCb411 0x99
-#define BT848_COLOR_FMT_RAW 0xee
-
-#define BT848_VTOTAL_LO 0xB0
-#define BT848_VTOTAL_HI 0xB4
-
-#define BT848_COLOR_CTL 0x0D8
-#define BT848_COLOR_CTL_EXT_FRMRATE (1<<7)
-#define BT848_COLOR_CTL_COLOR_BARS (1<<6)
-#define BT848_COLOR_CTL_RGB_DED (1<<5)
-#define BT848_COLOR_CTL_GAMMA (1<<4)
-#define BT848_COLOR_CTL_WSWAP_ODD (1<<3)
-#define BT848_COLOR_CTL_WSWAP_EVEN (1<<2)
-#define BT848_COLOR_CTL_BSWAP_ODD (1<<1)
-#define BT848_COLOR_CTL_BSWAP_EVEN (1<<0)
-
-#define BT848_CAP_CTL 0x0DC
-#define BT848_CAP_CTL_DITH_FRAME (1<<4)
-#define BT848_CAP_CTL_CAPTURE_VBI_ODD (1<<3)
-#define BT848_CAP_CTL_CAPTURE_VBI_EVEN (1<<2)
-#define BT848_CAP_CTL_CAPTURE_ODD (1<<1)
-#define BT848_CAP_CTL_CAPTURE_EVEN (1<<0)
-
-#define BT848_VBI_PACK_SIZE 0x0E0
-
-#define BT848_VBI_PACK_DEL 0x0E4
-#define BT848_VBI_PACK_DEL_VBI_HDELAY 0xfc
-#define BT848_VBI_PACK_DEL_EXT_FRAME 2
-#define BT848_VBI_PACK_DEL_VBI_PKT_HI 1
-
-
-#define BT848_INT_STAT 0x100
-#define BT848_INT_MASK 0x104
-
-#define BT848_INT_ETBF (1<<23)
-
-#define BT848_INT_RISCS (0xf<<28)
-#define BT848_INT_RISC_EN (1<<27)
-#define BT848_INT_RACK (1<<25)
-#define BT848_INT_FIELD (1<<24)
-#define BT848_INT_SCERR (1<<19)
-#define BT848_INT_OCERR (1<<18)
-#define BT848_INT_PABORT (1<<17)
-#define BT848_INT_RIPERR (1<<16)
-#define BT848_INT_PPERR (1<<15)
-#define BT848_INT_FDSR (1<<14)
-#define BT848_INT_FTRGT (1<<13)
-#define BT848_INT_FBUS (1<<12)
-#define BT848_INT_RISCI (1<<11)
-#define BT848_INT_GPINT (1<<9)
-#define BT848_INT_I2CDONE (1<<8)
-#define BT848_INT_VPRES (1<<5)
-#define BT848_INT_HLOCK (1<<4)
-#define BT848_INT_OFLOW (1<<3)
-#define BT848_INT_HSYNC (1<<2)
-#define BT848_INT_VSYNC (1<<1)
-#define BT848_INT_FMTCHG (1<<0)
-
-
-#define BT848_GPIO_DMA_CTL 0x10C
-#define BT848_GPIO_DMA_CTL_GPINTC (1<<15)
-#define BT848_GPIO_DMA_CTL_GPINTI (1<<14)
-#define BT848_GPIO_DMA_CTL_GPWEC (1<<13)
-#define BT848_GPIO_DMA_CTL_GPIOMODE (3<<11)
-#define BT848_GPIO_DMA_CTL_GPCLKMODE (1<<10)
-#define BT848_GPIO_DMA_CTL_PLTP23_4 (0<<6)
-#define BT848_GPIO_DMA_CTL_PLTP23_8 (1<<6)
-#define BT848_GPIO_DMA_CTL_PLTP23_16 (2<<6)
-#define BT848_GPIO_DMA_CTL_PLTP23_32 (3<<6)
-#define BT848_GPIO_DMA_CTL_PLTP1_4 (0<<4)
-#define BT848_GPIO_DMA_CTL_PLTP1_8 (1<<4)
-#define BT848_GPIO_DMA_CTL_PLTP1_16 (2<<4)
-#define BT848_GPIO_DMA_CTL_PLTP1_32 (3<<4)
-#define BT848_GPIO_DMA_CTL_PKTP_4 (0<<2)
-#define BT848_GPIO_DMA_CTL_PKTP_8 (1<<2)
-#define BT848_GPIO_DMA_CTL_PKTP_16 (2<<2)
-#define BT848_GPIO_DMA_CTL_PKTP_32 (3<<2)
-#define BT848_GPIO_DMA_CTL_RISC_ENABLE (1<<1)
-#define BT848_GPIO_DMA_CTL_FIFO_ENABLE (1<<0)
-
-#define BT848_I2C 0x110
-#define BT878_I2C_MODE (1<<7)
-#define BT878_I2C_RATE (1<<6)
-#define BT878_I2C_NOSTOP (1<<5)
-#define BT878_I2C_NOSTART (1<<4)
-#define BT848_I2C_DIV (0xf<<4)
-#define BT848_I2C_SYNC (1<<3)
-#define BT848_I2C_W3B (1<<2)
-#define BT848_I2C_SCL (1<<1)
-#define BT848_I2C_SDA (1<<0)
-
-#define BT848_RISC_STRT_ADD 0x114
-#define BT848_GPIO_OUT_EN 0x118
-#define BT848_GPIO_REG_INP 0x11C
-#define BT848_RISC_COUNT 0x120
-#define BT848_GPIO_DATA 0x200
-
-
-/* Bt848 RISC commands */
-
-/* only for the SYNC RISC command */
-#define BT848_FIFO_STATUS_FM1 0x06
-#define BT848_FIFO_STATUS_FM3 0x0e
-#define BT848_FIFO_STATUS_SOL 0x02
-#define BT848_FIFO_STATUS_EOL4 0x01
-#define BT848_FIFO_STATUS_EOL3 0x0d
-#define BT848_FIFO_STATUS_EOL2 0x09
-#define BT848_FIFO_STATUS_EOL1 0x05
-#define BT848_FIFO_STATUS_VRE 0x04
-#define BT848_FIFO_STATUS_VRO 0x0c
-#define BT848_FIFO_STATUS_PXV 0x00
-
-#define BT848_RISC_RESYNC (1<<15)
-
-/* WRITE and SKIP */
-/* disable which bytes of each DWORD */
-#define BT848_RISC_BYTE0 (1U<<12)
-#define BT848_RISC_BYTE1 (1U<<13)
-#define BT848_RISC_BYTE2 (1U<<14)
-#define BT848_RISC_BYTE3 (1U<<15)
-#define BT848_RISC_BYTE_ALL (0x0fU<<12)
-#define BT848_RISC_BYTE_NONE 0
-/* cause RISCI */
-#define BT848_RISC_IRQ (1U<<24)
-/* RISC command is last one in this line */
-#define BT848_RISC_EOL (1U<<26)
-/* RISC command is first one in this line */
-#define BT848_RISC_SOL (1U<<27)
-
-#define BT848_RISC_WRITE (0x01U<<28)
-#define BT848_RISC_SKIP (0x02U<<28)
-#define BT848_RISC_WRITEC (0x05U<<28)
-#define BT848_RISC_JUMP (0x07U<<28)
-#define BT848_RISC_SYNC (0x08U<<28)
-
-#define BT848_RISC_WRITE123 (0x09U<<28)
-#define BT848_RISC_SKIP123 (0x0aU<<28)
-#define BT848_RISC_WRITE1S23 (0x0bU<<28)
-
-
-/* Bt848A and higher only !! */
-#define BT848_TGLB 0x080
-#define BT848_TGCTRL 0x084
-#define BT848_FCAP 0x0E8
-#define BT848_PLL_F_LO 0x0F0
-#define BT848_PLL_F_HI 0x0F4
-
-#define BT848_PLL_XCI 0x0F8
-#define BT848_PLL_X (1<<7)
-#define BT848_PLL_C (1<<6)
-
-#define BT848_DVSIF 0x0FC
-
-/* Bt878 register */
-
-#define BT878_DEVCTRL 0x40
-#define BT878_EN_TBFX 0x02
-#define BT878_EN_VSFX 0x04
-
-#endif
diff --git a/drivers/media/video/bt8xx/bttv-audio-hook.c b/drivers/media/video/bt8xx/bttv-audio-hook.c
deleted file mode 100644
index 2364d16586b..00000000000
--- a/drivers/media/video/bt8xx/bttv-audio-hook.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Handlers for board audio hooks, splitted from bttv-cards
- *
- * Copyright (c) 2006 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License
- */
-
-#include "bttv-audio-hook.h"
-
-#include <linux/delay.h>
-
-/* ----------------------------------------------------------------------- */
-/* winview */
-
-void winview_volume(struct bttv *btv, __u16 volume)
-{
- /* PT2254A programming Jon Tombs, jon@gte.esi.us.es */
- int bits_out, loops, vol, data;
-
- /* 32 levels logarithmic */
- vol = 32 - ((volume>>11));
- /* units */
- bits_out = (PT2254_DBS_IN_2>>(vol%5));
- /* tens */
- bits_out |= (PT2254_DBS_IN_10>>(vol/5));
- bits_out |= PT2254_L_CHANNEL | PT2254_R_CHANNEL;
- data = gpio_read();
- data &= ~(WINVIEW_PT2254_CLK| WINVIEW_PT2254_DATA|
- WINVIEW_PT2254_STROBE);
- for (loops = 17; loops >= 0 ; loops--) {
- if (bits_out & (1<<loops))
- data |= WINVIEW_PT2254_DATA;
- else
- data &= ~WINVIEW_PT2254_DATA;
- gpio_write(data);
- udelay(5);
- data |= WINVIEW_PT2254_CLK;
- gpio_write(data);
- udelay(5);
- data &= ~WINVIEW_PT2254_CLK;
- gpio_write(data);
- }
- data |= WINVIEW_PT2254_STROBE;
- data &= ~WINVIEW_PT2254_DATA;
- gpio_write(data);
- udelay(10);
- data &= ~WINVIEW_PT2254_STROBE;
- gpio_write(data);
-}
-
-/* ----------------------------------------------------------------------- */
-/* mono/stereo control for various cards (which don't use i2c chips but */
-/* connect something to the GPIO pins */
-
-void gvbctv3pci_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
-{
- unsigned int con = 0;
-
- if (set) {
- gpio_inout(0x300, 0x300);
- if (t->audmode & V4L2_TUNER_MODE_LANG1)
- con = 0x000;
- if (t->audmode & V4L2_TUNER_MODE_LANG2)
- con = 0x300;
- if (t->audmode & V4L2_TUNER_MODE_STEREO)
- con = 0x200;
-/* if (t->audmode & V4L2_TUNER_MODE_MONO)
- * con = 0x100; */
- gpio_bits(0x300, con);
- } else {
- t->audmode = V4L2_TUNER_MODE_STEREO |
- V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
- }
-}
-
-void gvbctv5pci_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
-{
- unsigned int val, con;
-
- if (btv->radio_user)
- return;
-
- val = gpio_read();
- if (set) {
- con = 0x000;
- if (t->audmode & V4L2_TUNER_MODE_LANG2) {
- if (t->audmode & V4L2_TUNER_MODE_LANG1) {
- /* LANG1 + LANG2 */
- con = 0x100;
- }
- else {
- /* LANG2 */
- con = 0x300;
- }
- }
- if (con != (val & 0x300)) {
- gpio_bits(0x300, con);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"gvbctv5pci");
- }
- } else {
- switch (val & 0x70) {
- case 0x10:
- t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- break;
- case 0x30:
- t->rxsubchans = V4L2_TUNER_SUB_LANG2;
- break;
- case 0x50:
- t->rxsubchans = V4L2_TUNER_SUB_LANG1;
- break;
- case 0x60:
- t->rxsubchans = V4L2_TUNER_SUB_STEREO;
- break;
- case 0x70:
- t->rxsubchans = V4L2_TUNER_SUB_MONO;
- break;
- default:
- t->rxsubchans = V4L2_TUNER_SUB_MONO |
- V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_LANG1 |
- V4L2_TUNER_SUB_LANG2;
- }
- t->audmode = V4L2_TUNER_MODE_STEREO |
- V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
- }
-}
-
-/*
- * Mario Medina Nussbaum <medisoft@alohabbs.org.mx>
- * I discover that on BT848_GPIO_DATA address a byte 0xcce enable stereo,
- * 0xdde enables mono and 0xccd enables sap
- *
- * Petr Vandrovec <VANDROVE@vc.cvut.cz>
- * P.S.: At least mask in line above is wrong - GPIO pins 3,2 select
- * input/output sound connection, so both must be set for output mode.
- *
- * Looks like it's needed only for the "tvphone", the "tvphone 98"
- * handles this with a tda9840
- *
- */
-
-void avermedia_tvphone_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
-{
- int val = 0;
-
- if (set) {
- if (t->audmode & V4L2_TUNER_MODE_LANG2) /* SAP */
- val = 0x02;
- if (t->audmode & V4L2_TUNER_MODE_STEREO)
- val = 0x01;
- if (val) {
- gpio_bits(0x03,val);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"avermedia");
- }
- } else {
- t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
- V4L2_TUNER_MODE_LANG1;
- return;
- }
-}
-
-
-void avermedia_tv_stereo_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
-{
- int val = 0;
-
- if (set) {
- if (t->audmode & V4L2_TUNER_MODE_LANG2) /* SAP */
- val = 0x01;
- if (t->audmode & V4L2_TUNER_MODE_STEREO) /* STEREO */
- val = 0x02;
- btaor(val, ~0x03, BT848_GPIO_DATA);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"avermedia");
- } else {
- t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
- V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
- return;
- }
-}
-
-/* Lifetec 9415 handling */
-
-void lt9415_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
-{
- int val = 0;
-
- if (gpio_read() & 0x4000) {
- t->audmode = V4L2_TUNER_MODE_MONO;
- return;
- }
-
- if (set) {
- if (t->audmode & V4L2_TUNER_MODE_LANG2) /* A2 SAP */
- val = 0x0080;
- if (t->audmode & V4L2_TUNER_MODE_STEREO) /* A2 stereo */
- val = 0x0880;
- if ((t->audmode & V4L2_TUNER_MODE_LANG1) ||
- (t->audmode & V4L2_TUNER_MODE_MONO))
- val = 0;
- gpio_bits(0x0880, val);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"lt9415");
- } else {
- /* autodetect doesn't work with this card :-( */
- t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
- V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
- return;
- }
-}
-
-/* TDA9821 on TerraTV+ Bt848, Bt878 */
-void terratv_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
-{
- unsigned int con = 0;
-
- if (set) {
- gpio_inout(0x180000,0x180000);
- if (t->audmode & V4L2_TUNER_MODE_LANG2)
- con = 0x080000;
- if (t->audmode & V4L2_TUNER_MODE_STEREO)
- con = 0x180000;
- gpio_bits(0x180000, con);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"terratv");
- } else {
- t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
- V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
- }
-}
-
-
-void winfast2000_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
-{
- unsigned long val = 0;
-
- if (set) {
- /*btor (0xc32000, BT848_GPIO_OUT_EN);*/
- if (t->audmode & V4L2_TUNER_MODE_MONO) /* Mono */
- val = 0x420000;
- if (t->audmode & V4L2_TUNER_MODE_LANG1) /* Mono */
- val = 0x420000;
- if (t->audmode & V4L2_TUNER_MODE_LANG2) /* SAP */
- val = 0x410000;
- if (t->audmode & V4L2_TUNER_MODE_STEREO) /* Stereo */
- val = 0x020000;
- if (val) {
- gpio_bits(0x430000, val);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"winfast2000");
- }
- } else {
- t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
- V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
- }
-}
-
-/*
- * Dariusz Kowalewski <darekk@automex.pl>
- * sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM
- * revision 9B has on-board TDA9874A sound decoder).
- *
- * Note: There are card variants without tda9874a. Forcing the "stereo sound route"
- * will mute this cards.
- */
-void pvbt878p9b_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
-{
- unsigned int val = 0;
-
- if (btv->radio_user)
- return;
-
- if (set) {
- if (t->audmode & V4L2_TUNER_MODE_MONO) {
- val = 0x01;
- }
- if ((t->audmode & (V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2))
- || (t->audmode & V4L2_TUNER_MODE_STEREO)) {
- val = 0x02;
- }
- if (val) {
- gpio_bits(0x03,val);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"pvbt878p9b");
- }
- } else {
- t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
- V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
- }
-}
-
-/*
- * Dariusz Kowalewski <darekk@automex.pl>
- * sound control for FlyVideo 2000S (with tda9874 decoder)
- * based on pvbt878p9b_audio() - this is not tested, please fix!!!
- */
-void fv2000s_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
-{
- unsigned int val = 0xffff;
-
- if (btv->radio_user)
- return;
-
- if (set) {
- if (t->audmode & V4L2_TUNER_MODE_MONO) {
- val = 0x0000;
- }
- if ((t->audmode & (V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2))
- || (t->audmode & V4L2_TUNER_MODE_STEREO)) {
- val = 0x1080; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */
- }
- if (val != 0xffff) {
- gpio_bits(0x1800, val);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"fv2000s");
- }
- } else {
- t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
- V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
- }
-}
-
-/*
- * sound control for Canopus WinDVR PCI
- * Masaki Suzuki <masaki@btree.org>
- */
-void windvr_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
-{
- unsigned long val = 0;
-
- if (set) {
- if (t->audmode & V4L2_TUNER_MODE_MONO)
- val = 0x040000;
- if (t->audmode & V4L2_TUNER_MODE_LANG1)
- val = 0;
- if (t->audmode & V4L2_TUNER_MODE_LANG2)
- val = 0x100000;
- if (t->audmode & V4L2_TUNER_MODE_STEREO)
- val = 0;
- if (val) {
- gpio_bits(0x140000, val);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"windvr");
- }
- } else {
- t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
- V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
- }
-}
-
-/*
- * sound control for AD-TVK503
- * Hiroshi Takekawa <sian@big.or.jp>
- */
-void adtvk503_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
-{
- unsigned int con = 0xffffff;
-
- /* btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); */
-
- if (set) {
- /* btor(***, BT848_GPIO_OUT_EN); */
- if (t->audmode & V4L2_TUNER_MODE_LANG1)
- con = 0x00000000;
- if (t->audmode & V4L2_TUNER_MODE_LANG2)
- con = 0x00180000;
- if (t->audmode & V4L2_TUNER_MODE_STEREO)
- con = 0x00000000;
- if (t->audmode & V4L2_TUNER_MODE_MONO)
- con = 0x00060000;
- if (con != 0xffffff) {
- gpio_bits(0x1e0000,con);
- if (bttv_gpio)
- bttv_gpio_tracking(btv, "adtvk503");
- }
- } else {
- t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
- V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
- }
-}
diff --git a/drivers/media/video/bt8xx/bttv-audio-hook.h b/drivers/media/video/bt8xx/bttv-audio-hook.h
deleted file mode 100644
index 159d07adeff..00000000000
--- a/drivers/media/video/bt8xx/bttv-audio-hook.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Handlers for board audio hooks, splitted from bttv-cards
- *
- * Copyright (c) 2006 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License
- */
-
-#include "bttvp.h"
-
-void winview_volume (struct bttv *btv, __u16 volume);
-
-void lt9415_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-void avermedia_tvphone_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-void avermedia_tv_stereo_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-void terratv_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-void gvbctv3pci_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-void gvbctv5pci_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-void winfast2000_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-void pvbt878p9b_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-void fv2000s_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-void windvr_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-void adtvk503_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
deleted file mode 100644
index 38952faaffd..00000000000
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ /dev/null
@@ -1,4895 +0,0 @@
-/*
-
- bttv-cards.c
-
- this file has configuration informations - card-specific stuff
- like the big tvcards array for the most part
-
- Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
- (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/kmod.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/vmalloc.h>
-#include <linux/firmware.h>
-#include <net/checksum.h>
-
-#include <asm/unaligned.h>
-#include <asm/io.h>
-
-#include "bttvp.h"
-#include <media/v4l2-common.h>
-#include <media/tvaudio.h>
-#include "bttv-audio-hook.h"
-
-/* fwd decl */
-static void boot_msp34xx(struct bttv *btv, int pin);
-static void hauppauge_eeprom(struct bttv *btv);
-static void avermedia_eeprom(struct bttv *btv);
-static void osprey_eeprom(struct bttv *btv, const u8 ee[256]);
-static void modtec_eeprom(struct bttv *btv);
-static void init_PXC200(struct bttv *btv);
-static void init_RTV24(struct bttv *btv);
-
-static void rv605_muxsel(struct bttv *btv, unsigned int input);
-static void eagle_muxsel(struct bttv *btv, unsigned int input);
-static void xguard_muxsel(struct bttv *btv, unsigned int input);
-static void ivc120_muxsel(struct bttv *btv, unsigned int input);
-static void gvc1100_muxsel(struct bttv *btv, unsigned int input);
-
-static void PXC200_muxsel(struct bttv *btv, unsigned int input);
-
-static void picolo_tetra_muxsel(struct bttv *btv, unsigned int input);
-static void picolo_tetra_init(struct bttv *btv);
-
-static void tibetCS16_muxsel(struct bttv *btv, unsigned int input);
-static void tibetCS16_init(struct bttv *btv);
-
-static void kodicom4400r_muxsel(struct bttv *btv, unsigned int input);
-static void kodicom4400r_init(struct bttv *btv);
-
-static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input);
-static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input);
-
-static void geovision_muxsel(struct bttv *btv, unsigned int input);
-
-static void phytec_muxsel(struct bttv *btv, unsigned int input);
-
-static void gv800s_muxsel(struct bttv *btv, unsigned int input);
-static void gv800s_init(struct bttv *btv);
-
-static void td3116_muxsel(struct bttv *btv, unsigned int input);
-
-static int terratec_active_radio_upgrade(struct bttv *btv);
-static int tea5757_read(struct bttv *btv);
-static int tea5757_write(struct bttv *btv, int value);
-static void identify_by_eeprom(struct bttv *btv,
- unsigned char eeprom_data[256]);
-static int __devinit pvr_boot(struct bttv *btv);
-
-/* config variables */
-static unsigned int triton1;
-static unsigned int vsfx;
-static unsigned int latency = UNSET;
-int no_overlay=-1;
-
-static unsigned int card[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
-static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
-static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
-static unsigned int svhs[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
-static unsigned int remote[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
-static unsigned int audiodev[BTTV_MAX];
-static unsigned int saa6588[BTTV_MAX];
-static struct bttv *master[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = NULL };
-static unsigned int autoload = UNSET;
-static unsigned int gpiomask = UNSET;
-static unsigned int audioall = UNSET;
-static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET };
-
-/* insmod options */
-module_param(triton1, int, 0444);
-module_param(vsfx, int, 0444);
-module_param(no_overlay, int, 0444);
-module_param(latency, int, 0444);
-module_param(gpiomask, int, 0444);
-module_param(audioall, int, 0444);
-module_param(autoload, int, 0444);
-
-module_param_array(card, int, NULL, 0444);
-module_param_array(pll, int, NULL, 0444);
-module_param_array(tuner, int, NULL, 0444);
-module_param_array(svhs, int, NULL, 0444);
-module_param_array(remote, int, NULL, 0444);
-module_param_array(audiodev, int, NULL, 0444);
-module_param_array(audiomux, int, NULL, 0444);
-
-MODULE_PARM_DESC(triton1,"set ETBF pci config bit "
- "[enable bug compatibility for triton1 + others]");
-MODULE_PARM_DESC(vsfx,"set VSFX pci config bit "
- "[yet another chipset flaw workaround]");
-MODULE_PARM_DESC(latency,"pci latency timer");
-MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
-MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)");
-MODULE_PARM_DESC(tuner,"specify installed tuner type");
-MODULE_PARM_DESC(autoload, "obsolete option, please do not use anymore");
-MODULE_PARM_DESC(audiodev, "specify audio device:\n"
- "\t\t-1 = no audio\n"
- "\t\t 0 = autodetect (default)\n"
- "\t\t 1 = msp3400\n"
- "\t\t 2 = tda7432\n"
- "\t\t 3 = tvaudio");
-MODULE_PARM_DESC(saa6588, "if 1, then load the saa6588 RDS module, default (0) is to use the card definition.");
-MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)"
- " [some VIA/SIS chipsets are known to have problem with overlay]");
-
-/* ----------------------------------------------------------------------- */
-/* list of card IDs for bt878+ cards */
-
-static struct CARD {
- unsigned id;
- int cardnr;
- char *name;
-} cards[] __devinitdata = {
- { 0x13eb0070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV" },
- { 0x39000070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV-D" },
- { 0x45000070, BTTV_BOARD_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" },
- { 0xff000070, BTTV_BOARD_OSPREY1x0, "Osprey-100" },
- { 0xff010070, BTTV_BOARD_OSPREY2x0_SVID,"Osprey-200" },
- { 0xff020070, BTTV_BOARD_OSPREY500, "Osprey-500" },
- { 0xff030070, BTTV_BOARD_OSPREY2000, "Osprey-2000" },
- { 0xff040070, BTTV_BOARD_OSPREY540, "Osprey-540" },
- { 0xff070070, BTTV_BOARD_OSPREY440, "Osprey-440" },
-
- { 0x00011002, BTTV_BOARD_ATI_TVWONDER, "ATI TV Wonder" },
- { 0x00031002, BTTV_BOARD_ATI_TVWONDERVE,"ATI TV Wonder/VE" },
-
- { 0x6606107d, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
- { 0x6607107d, BTTV_BOARD_WINFASTVC100, "Leadtek WinFast VC 100" },
- { 0x6609107d, BTTV_BOARD_WINFAST2000, "Leadtek TV 2000 XP" },
- { 0x263610b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
- { 0x264510b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
- { 0x402010fc, BTTV_BOARD_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" },
- { 0x405010fc, BTTV_BOARD_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" },
- { 0x407010fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
- { 0xd01810fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
-
- { 0x001211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" },
- /* some cards ship with byteswapped IDs ... */
- { 0x1200bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" },
- { 0xff00bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" },
- /* this seems to happen as well ... */
- { 0xff1211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" },
-
- { 0x3000121a, BTTV_BOARD_VOODOOTV_200, "3Dfx VoodooTV 200" },
- { 0x263710b4, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM" },
- { 0x3060121a, BTTV_BOARD_STB2, "3Dfx VoodooTV 100/ STB OEM" },
-
- { 0x3000144f, BTTV_BOARD_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" },
- { 0xa005144f, BTTV_BOARD_MAGICTVIEW063, "CPH06X TView99-Card" },
- { 0x3002144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" },
- { 0x3005144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" },
- { 0x5000144f, BTTV_BOARD_MAGICTVIEW061, "Askey CPH050" },
- { 0x300014ff, BTTV_BOARD_MAGICTVIEW061, "TView 99 (CPH061)" },
- { 0x300214ff, BTTV_BOARD_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" },
-
- { 0x00011461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" },
- { 0x00021461, BTTV_BOARD_AVERMEDIA98, "AVermedia TVCapture 98" },
- { 0x00031461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" },
- { 0x00041461, BTTV_BOARD_AVERMEDIA98, "AVerMedia TVCapture 98" },
- { 0x03001461, BTTV_BOARD_AVERMEDIA98, "VDOMATE TV TUNER CARD" },
-
- { 0x1117153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" },
- { 0x1118153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" },
- { 0x1119153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL I)" },
- { 0x111a153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL I)" },
-
- { 0x1123153b, BTTV_BOARD_TERRATVRADIO, "Terratec TV Radio+" },
- { 0x1127153b, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.05)" },
- /* clashes with FlyVideo
- *{ 0x18521852, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.10)" }, */
- { 0x1134153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (LR102)" },
- { 0x1135153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */
- { 0x5018153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue" }, /* ?? */
- { 0xff3b153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */
-
- { 0x400015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
- { 0x400a15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
- { 0x400d15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
- { 0x401015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
- { 0x401615b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
-
- { 0x1430aa00, BTTV_BOARD_PV143, "Provideo PV143A" },
- { 0x1431aa00, BTTV_BOARD_PV143, "Provideo PV143B" },
- { 0x1432aa00, BTTV_BOARD_PV143, "Provideo PV143C" },
- { 0x1433aa00, BTTV_BOARD_PV143, "Provideo PV143D" },
- { 0x1433aa03, BTTV_BOARD_PV143, "Security Eyes" },
-
- { 0x1460aa00, BTTV_BOARD_PV150, "Provideo PV150A-1" },
- { 0x1461aa01, BTTV_BOARD_PV150, "Provideo PV150A-2" },
- { 0x1462aa02, BTTV_BOARD_PV150, "Provideo PV150A-3" },
- { 0x1463aa03, BTTV_BOARD_PV150, "Provideo PV150A-4" },
-
- { 0x1464aa04, BTTV_BOARD_PV150, "Provideo PV150B-1" },
- { 0x1465aa05, BTTV_BOARD_PV150, "Provideo PV150B-2" },
- { 0x1466aa06, BTTV_BOARD_PV150, "Provideo PV150B-3" },
- { 0x1467aa07, BTTV_BOARD_PV150, "Provideo PV150B-4" },
-
- { 0xa132ff00, BTTV_BOARD_IVC100, "IVC-100" },
- { 0xa1550000, BTTV_BOARD_IVC200, "IVC-200" },
- { 0xa1550001, BTTV_BOARD_IVC200, "IVC-200" },
- { 0xa1550002, BTTV_BOARD_IVC200, "IVC-200" },
- { 0xa1550003, BTTV_BOARD_IVC200, "IVC-200" },
- { 0xa1550100, BTTV_BOARD_IVC200, "IVC-200G" },
- { 0xa1550101, BTTV_BOARD_IVC200, "IVC-200G" },
- { 0xa1550102, BTTV_BOARD_IVC200, "IVC-200G" },
- { 0xa1550103, BTTV_BOARD_IVC200, "IVC-200G" },
- { 0xa1550800, BTTV_BOARD_IVC200, "IVC-200" },
- { 0xa1550801, BTTV_BOARD_IVC200, "IVC-200" },
- { 0xa1550802, BTTV_BOARD_IVC200, "IVC-200" },
- { 0xa1550803, BTTV_BOARD_IVC200, "IVC-200" },
- { 0xa182ff00, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff01, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff02, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff03, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff04, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff05, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff06, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff07, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff08, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff09, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff0a, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff0b, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff0c, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff0d, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff0e, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xa182ff0f, BTTV_BOARD_IVC120, "IVC-120G" },
- { 0xf0500000, BTTV_BOARD_IVCE8784, "IVCE-8784" },
- { 0xf0500001, BTTV_BOARD_IVCE8784, "IVCE-8784" },
- { 0xf0500002, BTTV_BOARD_IVCE8784, "IVCE-8784" },
- { 0xf0500003, BTTV_BOARD_IVCE8784, "IVCE-8784" },
-
- { 0x41424344, BTTV_BOARD_GRANDTEC, "GrandTec Multi Capture" },
- { 0x01020304, BTTV_BOARD_XGUARD, "Grandtec Grand X-Guard" },
-
- { 0x18501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
- { 0xa0501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
- { 0x18511851, BTTV_BOARD_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" },
- { 0x18521852, BTTV_BOARD_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" },
- { 0x41a0a051, BTTV_BOARD_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" },
- { 0x18501f7f, BTTV_BOARD_FLYVIDEO_98, "Lifeview Flyvideo 98" },
-
- { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" },
- { 0x010114c7, BTTV_BOARD_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" },
-
- { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" },
- { 0x217d6606, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
- { 0xfff6f6ff, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
- { 0x03116000, BTTV_BOARD_SENSORAY311_611, "Sensoray 311" },
- { 0x06116000, BTTV_BOARD_SENSORAY311_611, "Sensoray 611" },
- { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" },
- { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" },
- { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" },
- { 0x146caa0c, BTTV_BOARD_PV951, "ituner spectra8" },
- { 0x200a1295, BTTV_BOARD_PXC200, "ImageNation PXC200A" },
-
- { 0x40111554, BTTV_BOARD_PV_BT878P_9B, "Prolink Pixelview PV-BT" },
- { 0x17de0a01, BTTV_BOARD_KWORLD, "Mecer TV/FM/Video Tuner" },
-
- { 0x01051805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" },
- { 0x01061805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" },
- { 0x01071805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" },
- { 0x01081805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" },
-
- { 0x15409511, BTTV_BOARD_ACORP_Y878F, "Acorp Y878F" },
-
- { 0x53534149, BTTV_BOARD_SSAI_SECURITY, "SSAI Security Video Interface" },
- { 0x5353414a, BTTV_BOARD_SSAI_ULTRASOUND, "SSAI Ultrasound Video Interface" },
-
- /* likely broken, vendor id doesn't match the other magic views ...
- * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
-
- /* Duplicate PCI ID, reconfigure for this board during the eeprom read.
- * { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB, "Hauppauge ImpactVCB" }, */
-
- { 0x109e036e, BTTV_BOARD_CONCEPTRONIC_CTVFMI2, "Conceptronic CTVFMi v2"},
-
- /* DVB cards (using pci function .1 for mpeg data xfer) */
- { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" },
- { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
- { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"},
- { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" },
- { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" },
- { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
- { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
- { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
- { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
- { 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" },
- { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
- { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini "},
- { 0xd200dbc0, BTTV_BOARD_DVICO_FUSIONHDTV_2, "DViCO FusionHDTV 2" },
- { 0x763c008a, BTTV_BOARD_GEOVISION_GV600, "GeoVision GV-600" },
- { 0x18011000, BTTV_BOARD_ENLTV_FM_2, "Encore ENL TV-FM-2" },
- { 0x763d800a, BTTV_BOARD_GEOVISION_GV800S, "GeoVision GV-800(S) (master)" },
- { 0x763d800b, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" },
- { 0x763d800c, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" },
- { 0x763d800d, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" },
-
- { 0x15401830, BTTV_BOARD_PV183, "Provideo PV183-1" },
- { 0x15401831, BTTV_BOARD_PV183, "Provideo PV183-2" },
- { 0x15401832, BTTV_BOARD_PV183, "Provideo PV183-3" },
- { 0x15401833, BTTV_BOARD_PV183, "Provideo PV183-4" },
- { 0x15401834, BTTV_BOARD_PV183, "Provideo PV183-5" },
- { 0x15401835, BTTV_BOARD_PV183, "Provideo PV183-6" },
- { 0x15401836, BTTV_BOARD_PV183, "Provideo PV183-7" },
- { 0x15401837, BTTV_BOARD_PV183, "Provideo PV183-8" },
- { 0x3116f200, BTTV_BOARD_TVT_TD3116, "Tongwei Video Technology TD-3116" },
- { 0x02280279, BTTV_BOARD_APOSONIC_WDVR, "Aposonic W-DVR" },
- { 0, -1, NULL }
-};
-
-/* ----------------------------------------------------------------------- */
-/* array with description for bt848 / bt878 tv/grabber cards */
-
-struct tvcard bttv_tvcards[] = {
- /* ---- card 0x00 ---------------------------------- */
- [BTTV_BOARD_UNKNOWN] = {
- .name = " *** UNKNOWN/GENERIC *** ",
- .video_inputs = 4,
- .svhs = 2,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_MIRO] = {
- .name = "MIRO PCTV",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 2, 0, 0, 0 },
- .gpiomute = 10,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_HAUPPAUGE] = {
- .name = "Hauppauge (bt848)",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 7,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 1, 2, 3 },
- .gpiomute = 4,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_STB] = {
- .name = "STB, Gateway P/N 6000699 (bt848)",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 7,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 4, 0, 2, 3 },
- .gpiomute = 1,
- .no_msp34xx = 1,
- .tuner_type = TUNER_PHILIPS_NTSC,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .has_radio = 1,
- },
-
- /* ---- card 0x04 ---------------------------------- */
- [BTTV_BOARD_INTEL] = {
- .name = "Intel Create and Share PCI/ Smart Video Recorder III",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = 2,
- .gpiomask = 0,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0 },
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_DIAMOND] = {
- .name = "Diamond DTV2000",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 3,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .gpiomux = { 0, 1, 0, 1 },
- .gpiomute = 3,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_AVERMEDIA] = {
- .name = "AVerMedia TVPhone",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 3,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomask = 0x0f,
- .gpiomux = { 0x0c, 0x04, 0x08, 0x04 },
- /* 0x04 for some cards ?? */
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .audio_mode_gpio= avermedia_tvphone_audio,
- .has_remote = 1,
- },
- [BTTV_BOARD_MATRIX_VISION] = {
- .name = "MATRIX-Vision MV-Delta",
- .video_inputs = 5,
- /* .audio_inputs= 1, */
- .svhs = 3,
- .gpiomask = 0,
- .muxsel = MUXSEL(2, 3, 1, 0, 0),
- .gpiomux = { 0 },
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x08 ---------------------------------- */
- [BTTV_BOARD_FLYVIDEO] = {
- .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0xc00,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0xc00, 0x800, 0x400 },
- .gpiomute = 0xc00,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_TURBOTV] = {
- .name = "IMS/IXmicro TurboTV",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 3,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 1, 1, 2, 3 },
- .pll = PLL_28,
- .tuner_type = TUNER_TEMIC_PAL,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_HAUPPAUGE878] = {
- .name = "Hauppauge (bt878)",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x0f, /* old: 7 */
- .muxsel = MUXSEL(2, 0, 1, 1),
- .gpiomux = { 0, 1, 2, 3 },
- .gpiomute = 4,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_MIROPRO] = {
- .name = "MIRO PCTV pro",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x3014f,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x20001,0x10001, 0, 0 },
- .gpiomute = 10,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x0c ---------------------------------- */
- [BTTV_BOARD_ADSTECH_TV] = {
- .name = "ADS Technologies Channel Surfer TV (bt848)",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 13, 14, 11, 7 },
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_AVERMEDIA98] = {
- .name = "AVerMedia TVCapture 98",
- .video_inputs = 3,
- /* .audio_inputs= 4, */
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 13, 14, 11, 7 },
- .msp34xx_alt = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .audio_mode_gpio= avermedia_tv_stereo_audio,
- .no_gpioirq = 1,
- },
- [BTTV_BOARD_VHX] = {
- .name = "Aimslab Video Highway Xtreme (VHX)",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 7,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */
- .gpiomute = 4,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_ZOLTRIX] = {
- .name = "Zoltrix TV-Max",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0, 1, 0 },
- .gpiomute = 10,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x10 ---------------------------------- */
- [BTTV_BOARD_PIXVIEWPLAYTV] = {
- .name = "Prolink Pixelview PlayTV (bt878)",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x01fe00,
- .muxsel = MUXSEL(2, 3, 1, 1),
- /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
- .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 },
- .gpiomute = 0x002000,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_WINVIEW_601] = {
- .name = "Leadtek WinView 601",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x8300f8,
- .muxsel = MUXSEL(2, 3, 1, 1, 0),
- .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 },
- .gpiomute = 0xcfa007,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .volume_gpio = winview_volume,
- .has_radio = 1,
- },
- [BTTV_BOARD_AVEC_INTERCAP] = {
- .name = "AVEC Intercapture",
- .video_inputs = 3,
- /* .audio_inputs= 2, */
- .svhs = 2,
- .gpiomask = 0,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 1, 0, 0, 0 },
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_LIFE_FLYKIT] = {
- .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = NO_SVHS,
- .gpiomask = 0x8dff00,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x14 ---------------------------------- */
- [BTTV_BOARD_CEI_RAFFLES] = {
- .name = "CEI Raffles Card",
- .video_inputs = 3,
- /* .audio_inputs= 3, */
- .svhs = 2,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_CONFERENCETV] = {
- .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
- .video_inputs = 4,
- /* .audio_inputs= 2, tuner, line in */
- .svhs = 2,
- .gpiomask = 0x1800,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
- .gpiomute = 0x1800,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL_I,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_PHOEBE_TVMAS] = {
- .name = "Askey CPH050/ Phoebe Tv Master + FM",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0xc00,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 1, 0x800, 0x400 },
- .gpiomute = 0xc00,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_MODTEC_205] = {
- .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = NO_SVHS,
- .has_dig_in = 1,
- .gpiomask = 7,
- .muxsel = MUXSEL(2, 3, 0), /* input 2 is digital */
- /* .digital_mode= DIGITAL_MODE_CAMERA, */
- .gpiomux = { 0, 0, 0, 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ALPS_TSBB5_PAL_I,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x18 ---------------------------------- */
- [BTTV_BOARD_MAGICTVIEW061] = {
- .name = "Askey CPH05X/06X (bt878) [many vendors]",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0xe00,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = {0x400, 0x400, 0x400, 0x400 },
- .gpiomute = 0xc00,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
- .has_radio = 1, /* not every card has radio */
- },
- [BTTV_BOARD_VOBIS_BOOSTAR] = {
- .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x1f0fff,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x20000, 0x30000, 0x10000, 0 },
- .gpiomute = 0x40000,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .audio_mode_gpio= terratv_audio,
- },
- [BTTV_BOARD_HAUPPAUG_WCAM] = {
- .name = "Hauppauge WinCam newer (bt878)",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 3,
- .gpiomask = 7,
- .muxsel = MUXSEL(2, 0, 1, 1),
- .gpiomux = { 0, 1, 2, 3 },
- .gpiomute = 4,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_MAXI] = {
- .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
- .video_inputs = 4,
- /* .audio_inputs= 2, */
- .svhs = 2,
- .gpiomask = 0x1800,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
- .gpiomute = 0x1800,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_SECAM,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x1c ---------------------------------- */
- [BTTV_BOARD_TERRATV] = {
- .name = "Terratec TerraTV+ Version 1.1 (bt878)",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x1f0fff,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 },
- .gpiomute = 0x40000,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .audio_mode_gpio= terratv_audio,
- /* GPIO wiring:
- External 20 pin connector (for Active Radio Upgrade board)
- gpio00: i2c-sda
- gpio01: i2c-scl
- gpio02: om5610-data
- gpio03: om5610-clk
- gpio04: om5610-wre
- gpio05: om5610-stereo
- gpio06: rds6588-davn
- gpio07: Pin 7 n.c.
- gpio08: nIOW
- gpio09+10: nIOR, nSEL ?? (bt878)
- gpio09: nIOR (bt848)
- gpio10: nSEL (bt848)
- Sound Routing:
- gpio16: u2-A0 (1st 4052bt)
- gpio17: u2-A1
- gpio18: u2-nEN
- gpio19: u4-A0 (2nd 4052)
- gpio20: u4-A1
- u4-nEN - GND
- Btspy:
- 00000 : Cdrom (internal audio input)
- 10000 : ext. Video audio input
- 20000 : TV Mono
- a0000 : TV Mono/2
- 1a0000 : TV Stereo
- 30000 : Radio
- 40000 : Mute
- */
-
- },
- [BTTV_BOARD_PXC200] = {
- /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
- .name = "Imagenation PXC200",
- .video_inputs = 5,
- /* .audio_inputs= 1, */
- .svhs = 1, /* was: 4 */
- .gpiomask = 0,
- .muxsel = MUXSEL(2, 3, 1, 0, 0),
- .gpiomux = { 0 },
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .muxsel_hook = PXC200_muxsel,
-
- },
- [BTTV_BOARD_FLYVIDEO_98] = {
- .name = "Lifeview FlyVideo 98 LR50",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x1800, /* 0x8dfe00 */
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0x0800, 0x1000, 0x1000 },
- .gpiomute = 0x1800,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_IPROTV] = {
- .name = "Formac iProTV, Formac ProTV I (bt848)",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 3,
- .gpiomask = 1,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 1, 0, 0, 0 },
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x20 ---------------------------------- */
- [BTTV_BOARD_INTEL_C_S_PCI] = {
- .name = "Intel Create and Share PCI/ Smart Video Recorder III",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = 2,
- .gpiomask = 0,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0 },
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_TERRATVALUE] = {
- .name = "Terratec TerraTValue Version Bt878",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0xffff00,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x500, 0, 0x300, 0x900 },
- .gpiomute = 0x900,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_WINFAST2000] = {
- .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- /* TV, CVid, SVid, CVid over SVid connector */
- .muxsel = MUXSEL(2, 3, 1, 1, 0),
- /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
- .gpiomask = 0xb33000,
- .gpiomux = { 0x122000,0x1000,0x0000,0x620000 },
- .gpiomute = 0x800000,
- /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
- gpio23 -- hef4052:nEnable (0x800000)
- gpio12 -- hef4052:A1
- gpio13 -- hef4052:A0
- 0x0000: external audio
- 0x1000: FM
- 0x2000: TV
- 0x3000: n.c.
- Note: There exists another variant "Winfast 2000" with tv stereo !?
- Note: eeprom only contains FF and pci subsystem id 107d:6606
- */
- .pll = PLL_28,
- .has_radio = 1,
- .tuner_type = TUNER_PHILIPS_PAL, /* default for now, gpio reads BFFF06 for Pal bg+dk */
- .tuner_addr = ADDR_UNSET,
- .audio_mode_gpio= winfast2000_audio,
- .has_remote = 1,
- },
- [BTTV_BOARD_CHRONOS_VS2] = {
- .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
- .video_inputs = 4,
- /* .audio_inputs= 3, */
- .svhs = 2,
- .gpiomask = 0x1800,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
- .gpiomute = 0x1800,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x24 ---------------------------------- */
- [BTTV_BOARD_TYPHOON_TVIEW] = {
- .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
- .video_inputs = 4,
- /* .audio_inputs= 3, */
- .svhs = 2,
- .gpiomask = 0x1800,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
- .gpiomute = 0x1800,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
- },
- [BTTV_BOARD_PXELVWPLTVPRO] = {
- .name = "Prolink PixelView PlayTV pro",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0xff,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x21, 0x20, 0x24, 0x2c },
- .gpiomute = 0x29,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_MAGICTVIEW063] = {
- .name = "Askey CPH06X TView99",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x551e00,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .gpiomux = { 0x551400, 0x551200, 0, 0 },
- .gpiomute = 0x551c00,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL_I,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
- },
- [BTTV_BOARD_PINNACLE] = {
- .name = "Pinnacle PCTV Studio/Rave",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x03000F,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 2, 0xd0001, 0, 0 },
- .gpiomute = 1,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x28 ---------------------------------- */
- [BTTV_BOARD_STB2] = {
- .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 7,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 4, 0, 2, 3 },
- .gpiomute = 1,
- .no_msp34xx = 1,
- .tuner_type = TUNER_PHILIPS_NTSC,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .has_radio = 1,
- },
- [BTTV_BOARD_AVPHONE98] = {
- .name = "AVerMedia TVPhone 98",
- .video_inputs = 3,
- /* .audio_inputs= 4, */
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 13, 4, 11, 7 },
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
- .audio_mode_gpio= avermedia_tvphone_audio,
- },
- [BTTV_BOARD_PV951] = {
- .name = "ProVideo PV951", /* pic16c54 */
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0, 0, 0},
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL_I,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_ONAIR_TV] = {
- .name = "Little OnAir TV",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0xe00b,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 },
- .gpiomute = 0xff3ffc,
- .no_msp34xx = 1,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x2c ---------------------------------- */
- [BTTV_BOARD_SIGMA_TVII_FM] = {
- .name = "Sigma TVII-FM",
- .video_inputs = 2,
- /* .audio_inputs= 1, */
- .svhs = NO_SVHS,
- .gpiomask = 3,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 1, 1, 0, 2 },
- .gpiomute = 3,
- .no_msp34xx = 1,
- .pll = PLL_NONE,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_MATRIX_VISION2] = {
- .name = "MATRIX-Vision MV-Delta 2",
- .video_inputs = 5,
- /* .audio_inputs= 1, */
- .svhs = 3,
- .gpiomask = 0,
- .muxsel = MUXSEL(2, 3, 1, 0, 0),
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_ZOLTRIX_GENIE] = {
- .name = "Zoltrix Genie TV/FM",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0xbcf03f,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0 },
- .gpiomute = 0xbcb03f,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_TEMIC_4039FR5_NTSC,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_TERRATVRADIO] = {
- .name = "Terratec TV/Radio+",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x70000,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x20000, 0x30000, 0x10000, 0 },
- .gpiomute = 0x40000,
- .no_msp34xx = 1,
- .pll = PLL_35,
- .tuner_type = TUNER_PHILIPS_PAL_I,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
- },
-
- /* ---- card 0x30 ---------------------------------- */
- [BTTV_BOARD_DYNALINK] = {
- .name = "Askey CPH03x/ Dynalink Magic TView",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = {2,0,0,0 },
- .gpiomute = 1,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_GVBCTV3PCI] = {
- .name = "IODATA GV-BCTV3/PCI",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x010f00,
- .muxsel = MUXSEL(2, 3, 0, 0),
- .gpiomux = {0x10000, 0, 0x10000, 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ALPS_TSHC6_NTSC,
- .tuner_addr = ADDR_UNSET,
- .audio_mode_gpio= gvbctv3pci_audio,
- },
- [BTTV_BOARD_PXELVWPLTVPAK] = {
- .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
- .video_inputs = 5,
- /* .audio_inputs= 1, */
- .svhs = 3,
- .has_dig_in = 1,
- .gpiomask = 0xAA0000,
- .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */
- /* .digital_mode= DIGITAL_MODE_CAMERA, */
- .gpiomux = { 0x20000, 0, 0x80000, 0x80000 },
- .gpiomute = 0xa8000,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL_I,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
- /* GPIO wiring: (different from Rev.4C !)
- GPIO17: U4.A0 (first hef4052bt)
- GPIO19: U4.A1
- GPIO20: U5.A1 (second hef4052bt)
- GPIO21: U4.nEN
- GPIO22: BT832 Reset Line
- GPIO23: A5,A0, U5,nEN
- Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
- */
- },
- [BTTV_BOARD_EAGLE] = {
- .name = "Eagle Wireless Capricorn2 (bt878A)",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 7,
- .muxsel = MUXSEL(2, 0, 1, 1),
- .gpiomux = { 0, 1, 2, 3 },
- .gpiomute = 4,
- .pll = PLL_28,
- .tuner_type = UNSET /* TUNER_ALPS_TMDH2_NTSC */,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x34 ---------------------------------- */
- [BTTV_BOARD_PINNACLEPRO] = {
- /* David Härdeman <david@2gen.com> */
- .name = "Pinnacle PCTV Studio Pro",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 3,
- .gpiomask = 0x03000F,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 1, 0xd0001, 0, 0 },
- .gpiomute = 10,
- /* sound path (5 sources):
- MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
- 0= ext. Audio IN
- 1= from MUX2
- 2= Mono TV sound from Tuner
- 3= not connected
- MUX2 (mask 0x30000):
- 0,2,3= from MSP34xx
- 1= FM stereo Radio from Tuner */
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_TVIEW_RDS_FM] = {
- /* Claas Langbehn <claas@bigfoot.com>,
- Sven Grothklags <sven@upb.de> */
- .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
- .video_inputs = 4,
- /* .audio_inputs= 3, */
- .svhs = 2,
- .gpiomask = 0x1c,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0, 0x10, 8 },
- .gpiomute = 4,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
- },
- [BTTV_BOARD_LIFETEC_9415] = {
- /* Tim Röstermundt <rosterm@uni-muenster.de>
- in de.comp.os.unix.linux.hardware:
- options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
- gpiomux =0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
- options tuner type=5 */
- .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x18e0,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x0000,0x0800,0x1000,0x1000 },
- .gpiomute = 0x18e0,
- /* For cards with tda9820/tda9821:
- 0x0000: Tuner normal stereo
- 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
- 0x0880: Tuner A2 stereo */
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_BESTBUY_EASYTV] = {
- /* Miguel Angel Alvarez <maacruz@navegalia.com>
- old Easy TV BT848 version (model CPH031) */
- .name = "Askey CPH031/ BESTBUY Easy TV",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0xF,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .gpiomux = { 2, 0, 0, 0 },
- .gpiomute = 10,
- .pll = PLL_28,
- .tuner_type = TUNER_TEMIC_PAL,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x38 ---------------------------------- */
- [BTTV_BOARD_FLYVIDEO_98FM] = {
- /* Gordon Heydon <gjheydon@bigfoot.com ('98) */
- .name = "Lifeview FlyVideo 98FM LR50",
- .video_inputs = 4,
- /* .audio_inputs= 3, */
- .svhs = 2,
- .gpiomask = 0x1800,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
- .gpiomute = 0x1800,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- },
- /* This is the ultimate cheapo capture card
- * just a BT848A on a small PCB!
- * Steve Hosgood <steve@equiinet.com> */
- [BTTV_BOARD_GRANDTEC] = {
- .name = "GrandTec 'Grand Video Capture' (Bt848)",
- .video_inputs = 2,
- /* .audio_inputs= 0, */
- .svhs = 1,
- .gpiomask = 0,
- .muxsel = MUXSEL(3, 1),
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_35,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_ASKEY_CPH060] = {
- /* Daniel Herrington <daniel.herrington@home.com> */
- .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0xe00,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x400, 0x400, 0x400, 0x400 },
- .gpiomute = 0x800,
- .pll = PLL_28,
- .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_ASKEY_CPH03X] = {
- /* Matti Mottus <mottus@physic.ut.ee> */
- .name = "Askey CPH03x TV Capturer",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x03000F,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .gpiomux = { 2, 0, 0, 0 },
- .gpiomute = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_TEMIC_PAL,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
- },
-
- /* ---- card 0x3c ---------------------------------- */
- [BTTV_BOARD_MM100PCTV] = {
- /* Philip Blundell <philb@gnu.org> */
- .name = "Modular Technology MM100PCTV",
- .video_inputs = 2,
- /* .audio_inputs= 2, */
- .svhs = NO_SVHS,
- .gpiomask = 11,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 2, 0, 0, 1 },
- .gpiomute = 8,
- .pll = PLL_35,
- .tuner_type = TUNER_TEMIC_PAL,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_GMV1] = {
- /* Adrian Cox <adrian@humboldt.co.uk */
- .name = "AG Electronics GMV1",
- .video_inputs = 2,
- /* .audio_inputs= 0, */
- .svhs = 1,
- .gpiomask = 0xF,
- .muxsel = MUXSEL(2, 2),
- .gpiomux = { },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_BESTBUY_EASYTV2] = {
- /* Miguel Angel Alvarez <maacruz@navegalia.com>
- new Easy TV BT878 version (model CPH061)
- special thanks to Informatica Mieres for providing the card */
- .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
- .video_inputs = 3,
- /* .audio_inputs= 2, */
- .svhs = 2,
- .gpiomask = 0xFF,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .gpiomux = { 1, 0, 4, 4 },
- .gpiomute = 9,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_ATI_TVWONDER] = {
- /* Lukas Gebauer <geby@volny.cz> */
- .name = "ATI TV-Wonder",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0xf03f,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .gpiomux = { 0xbffe, 0, 0xbfff, 0 },
- .gpiomute = 0xbffe,
- .pll = PLL_28,
- .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x40 ---------------------------------- */
- [BTTV_BOARD_ATI_TVWONDERVE] = {
- /* Lukas Gebauer <geby@volny.cz> */
- .name = "ATI TV-Wonder VE",
- .video_inputs = 2,
- /* .audio_inputs= 1, */
- .svhs = NO_SVHS,
- .gpiomask = 1,
- .muxsel = MUXSEL(2, 3, 0, 1),
- .gpiomux = { 0, 0, 1, 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_FLYVIDEO2000] = {
- /* DeeJay <deejay@westel900.net (2000S) */
- .name = "Lifeview FlyVideo 2000S LR90",
- .video_inputs = 3,
- /* .audio_inputs= 3, */
- .svhs = 2,
- .gpiomask = 0x18e0,
- .muxsel = MUXSEL(2, 3, 0, 1),
- /* Radio changed from 1e80 to 0x800 to make
- FlyVideo2000S in .hu happy (gm)*/
- /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
- .gpiomux = { 0x0000,0x0800,0x1000,0x1000 },
- .gpiomute = 0x1800,
- .audio_mode_gpio= fv2000s_audio,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_TERRATVALUER] = {
- .name = "Terratec TValueRadio",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0xffff00,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x500, 0x500, 0x300, 0x900 },
- .gpiomute = 0x900,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
- },
- [BTTV_BOARD_GVBCTV4PCI] = {
- /* TANAKA Kei <peg00625@nifty.com> */
- .name = "IODATA GV-BCTV4/PCI",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x010f00,
- .muxsel = MUXSEL(2, 3, 0, 0),
- .gpiomux = {0x10000, 0, 0x10000, 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
- .tuner_addr = ADDR_UNSET,
- .audio_mode_gpio= gvbctv3pci_audio,
- },
-
- /* ---- card 0x44 ---------------------------------- */
- [BTTV_BOARD_VOODOOTV_FM] = {
- .name = "3Dfx VoodooTV FM (Euro)",
- /* try "insmod msp3400 simple=0" if you have
- * sound problems with this card. */
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = NO_SVHS,
- .gpiomask = 0x4f8a00,
- /* 0x100000: 1=MSP enabled (0=disable again)
- * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
- .gpiomux = {0x947fff, 0x987fff,0x947fff,0x947fff },
- .gpiomute = 0x947fff,
- /* tvtuner, radio, external,internal, mute, stereo
- * tuner, Composit, SVid, Composit-on-Svid-adapter */
- .muxsel = MUXSEL(2, 3, 0, 1),
- .tuner_type = TUNER_MT2032,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .has_radio = 1,
- },
- [BTTV_BOARD_VOODOOTV_200] = {
- .name = "VoodooTV 200 (USA)",
- /* try "insmod msp3400 simple=0" if you have
- * sound problems with this card. */
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = NO_SVHS,
- .gpiomask = 0x4f8a00,
- /* 0x100000: 1=MSP enabled (0=disable again)
- * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
- .gpiomux = {0x947fff, 0x987fff,0x947fff,0x947fff },
- .gpiomute = 0x947fff,
- /* tvtuner, radio, external,internal, mute, stereo
- * tuner, Composit, SVid, Composit-on-Svid-adapter */
- .muxsel = MUXSEL(2, 3, 0, 1),
- .tuner_type = TUNER_MT2032,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .has_radio = 1,
- },
- [BTTV_BOARD_AIMMS] = {
- /* Philip Blundell <pb@nexus.co.uk> */
- .name = "Active Imaging AIMMS",
- .video_inputs = 1,
- /* .audio_inputs= 0, */
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .muxsel = MUXSEL(2),
- .gpiomask = 0
- },
- [BTTV_BOARD_PV_BT878P_PLUS] = {
- /* Tomasz Pyra <hellfire@sedez.iq.pl> */
- .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
- .video_inputs = 3,
- /* .audio_inputs= 4, */
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */
- .gpiomute = 13,
- .pll = PLL_28,
- .tuner_type = TUNER_LG_PAL_I_FM,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
- /* GPIO wiring:
- GPIO0: U4.A0 (hef4052bt)
- GPIO1: U4.A1
- GPIO2: U4.A1 (second hef4052bt)
- GPIO3: U4.nEN, U5.A0, A5.nEN
- GPIO8-15: vrd866b ?
- */
- },
- [BTTV_BOARD_FLYVIDEO98EZ] = {
- .name = "Lifeview FlyVideo 98EZ (capture only) LR51",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = 2,
- /* AV1, AV2, SVHS, CVid adapter on SVHS */
- .muxsel = MUXSEL(2, 3, 1, 1),
- .pll = PLL_28,
- .no_msp34xx = 1,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x48 ---------------------------------- */
- [BTTV_BOARD_PV_BT878P_9B] = {
- /* Dariusz Kowalewski <darekk@automex.pl> */
- .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x3f,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x01, 0x00, 0x03, 0x03 },
- .gpiomute = 0x09,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .audio_mode_gpio= pvbt878p9b_audio, /* Note: not all cards have stereo */
- .has_radio = 1, /* Note: not all cards have radio */
- .has_remote = 1,
- /* GPIO wiring:
- GPIO0: A0 hef4052
- GPIO1: A1 hef4052
- GPIO3: nEN hef4052
- GPIO8-15: vrd866b
- GPIO20,22,23: R30,R29,R28
- */
- },
- [BTTV_BOARD_SENSORAY311_611] = {
- /* Clay Kunz <ckunz@mail.arc.nasa.gov> */
- /* you must jumper JP5 for the 311 card (PC/104+) to work */
- .name = "Sensoray 311/611",
- .video_inputs = 5,
- /* .audio_inputs= 0, */
- .svhs = 4,
- .gpiomask = 0,
- .muxsel = MUXSEL(2, 3, 1, 0, 0),
- .gpiomux = { 0 },
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_RV605] = {
- /* Miguel Freitas <miguel@cetuc.puc-rio.br> */
- .name = "RemoteVision MX (RV605)",
- .video_inputs = 16,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .gpiomask = 0x00,
- .gpiomask2 = 0x07ff,
- .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
- .no_msp34xx = 1,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .muxsel_hook = rv605_muxsel,
- },
- [BTTV_BOARD_POWERCLR_MTV878] = {
- .name = "Powercolor MTV878/ MTV878R/ MTV878F",
- .video_inputs = 3,
- /* .audio_inputs= 2, */
- .svhs = 2,
- .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
- .muxsel = MUXSEL(2, 1, 1),
- .gpiomux = { 0, 1, 2, 2 },
- .gpiomute = 4,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .has_radio = 1,
- },
-
- /* ---- card 0x4c ---------------------------------- */
- [BTTV_BOARD_WINDVR] = {
- /* Masaki Suzuki <masaki@btree.org> */
- .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x140007,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 1, 2, 3 },
- .gpiomute = 4,
- .tuner_type = TUNER_PHILIPS_NTSC,
- .tuner_addr = ADDR_UNSET,
- .audio_mode_gpio= windvr_audio,
- },
- [BTTV_BOARD_GRANDTEC_MULTI] = {
- .name = "GrandTec Multi Capture Card (Bt878)",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .gpiomask = 0,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_KWORLD] = {
- .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
- .video_inputs = 4,
- /* .audio_inputs= 3, */
- .svhs = 2,
- .gpiomask = 7,
- /* Tuner, SVid, SVHS, SVid to SVHS connector */
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0, 4, 4 },/* Yes, this tuner uses the same audio output for TV and FM radio!
- * This card lacks external Audio In, so we mute it on Ext. & Int.
- * The PCB can take a sbx1637/sbx1673, wiring unknown.
- * This card lacks PCI subsystem ID, sigh.
- * gpiomux =1: lower volume, 2+3: mute
- * btwincap uses 0x80000/0x80003
- */
- .gpiomute = 4,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
- radio signal strength indicators work fine. */
- .has_radio = 1,
- /* GPIO Info:
- GPIO0,1: HEF4052 A0,A1
- GPIO2: HEF4052 nENABLE
- GPIO3-7: n.c.
- GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card]
- GPIO14,15: ??
- GPIO16-21: n.c.
- GPIO22,23: ??
- ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/
- },
- [BTTV_BOARD_DSP_TCVIDEO] = {
- /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
- .name = "DSP Design TCVIDEO",
- .video_inputs = 4,
- .svhs = NO_SVHS,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x50 ---------------------------------- */
- [BTTV_BOARD_HAUPPAUGEPVR] = {
- .name = "Hauppauge WinTV PVR",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .muxsel = MUXSEL(2, 0, 1, 1),
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
-
- .gpiomask = 7,
- .gpiomux = {7},
- },
- [BTTV_BOARD_GVBCTV5PCI] = {
- .name = "IODATA GV-BCTV5/PCI",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x0f0f80,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .gpiomux = {0x030000, 0x010000, 0, 0 },
- .gpiomute = 0x020000,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .tuner_addr = ADDR_UNSET,
- .audio_mode_gpio= gvbctv5pci_audio,
- .has_radio = 1,
- },
- [BTTV_BOARD_OSPREY1x0] = {
- .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
- .video_inputs = 4, /* id-inputs-clock */
- /* .audio_inputs= 0, */
- .svhs = 3,
- .muxsel = MUXSEL(3, 2, 0, 1),
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- },
- [BTTV_BOARD_OSPREY1x0_848] = {
- .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
- .video_inputs = 3,
- /* .audio_inputs= 0, */
- .svhs = 2,
- .muxsel = MUXSEL(2, 3, 1),
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- },
-
- /* ---- card 0x54 ---------------------------------- */
- [BTTV_BOARD_OSPREY101_848] = {
- .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */
- .video_inputs = 2,
- /* .audio_inputs= 0, */
- .svhs = 1,
- .muxsel = MUXSEL(3, 1),
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- },
- [BTTV_BOARD_OSPREY1x1] = {
- .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
- .video_inputs = 1,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .muxsel = MUXSEL(0),
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- },
- [BTTV_BOARD_OSPREY1x1_SVID] = {
- .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
- .video_inputs = 2,
- /* .audio_inputs= 0, */
- .svhs = 1,
- .muxsel = MUXSEL(0, 1),
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- },
- [BTTV_BOARD_OSPREY2xx] = {
- .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
- .video_inputs = 1,
- /* .audio_inputs= 1, */
- .svhs = NO_SVHS,
- .muxsel = MUXSEL(0),
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- },
-
- /* ---- card 0x58 ---------------------------------- */
- [BTTV_BOARD_OSPREY2x0_SVID] = {
- .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */
- .video_inputs = 2,
- /* .audio_inputs= 1, */
- .svhs = 1,
- .muxsel = MUXSEL(0, 1),
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- },
- [BTTV_BOARD_OSPREY2x0] = {
- .name = "Osprey 210/220/230", /* 0x1(A|B)-04C0-C1 */
- .video_inputs = 2,
- /* .audio_inputs= 1, */
- .svhs = 1,
- .muxsel = MUXSEL(2, 3),
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- },
- [BTTV_BOARD_OSPREY500] = {
- .name = "Osprey 500", /* 500 */
- .video_inputs = 2,
- /* .audio_inputs= 1, */
- .svhs = 1,
- .muxsel = MUXSEL(2, 3),
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- },
- [BTTV_BOARD_OSPREY540] = {
- .name = "Osprey 540", /* 540 */
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- },
-
- /* ---- card 0x5C ---------------------------------- */
- [BTTV_BOARD_OSPREY2000] = {
- .name = "Osprey 2000", /* 2000 */
- .video_inputs = 2,
- /* .audio_inputs= 1, */
- .svhs = 1,
- .muxsel = MUXSEL(2, 3),
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
- },
- [BTTV_BOARD_IDS_EAGLE] = {
- /* M G Berberich <berberic@forwiss.uni-passau.de> */
- .name = "IDS Eagle",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .svhs = NO_SVHS,
- .gpiomask = 0,
- .muxsel = MUXSEL(2, 2, 2, 2),
- .muxsel_hook = eagle_muxsel,
- .no_msp34xx = 1,
- .pll = PLL_28,
- },
- [BTTV_BOARD_PINNACLESAT] = {
- .name = "Pinnacle PCTV Sat",
- .video_inputs = 2,
- /* .audio_inputs= 0, */
- .svhs = 1,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .muxsel = MUXSEL(3, 1),
- .pll = PLL_28,
- .no_gpioirq = 1,
- .has_dvb = 1,
- },
- [BTTV_BOARD_FORMAC_PROTV] = {
- .name = "Formac ProTV II (bt878)",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 3,
- .gpiomask = 2,
- /* TV, Comp1, Composite over SVID con, SVID */
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 2, 2, 0, 0 },
- .pll = PLL_28,
- .has_radio = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- /* sound routing:
- GPIO=0x00,0x01,0x03: mute (?)
- 0x02: both TV and radio (tuner: FM1216/I)
- The card has onboard audio connectors labeled "cdrom" and "board",
- not soldered here, though unknown wiring.
- Card lacks: external audio in, pci subsystem id.
- */
- },
-
- /* ---- card 0x60 ---------------------------------- */
- [BTTV_BOARD_MACHTV] = {
- .name = "MachTV",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = NO_SVHS,
- .gpiomask = 7,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 1, 2, 3},
- .gpiomute = 4,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- },
- [BTTV_BOARD_EURESYS_PICOLO] = {
- .name = "Euresys Picolo",
- .video_inputs = 3,
- /* .audio_inputs= 0, */
- .svhs = 2,
- .gpiomask = 0,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .muxsel = MUXSEL(2, 0, 1),
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_PV150] = {
- /* Luc Van Hoeylandt <luc@e-magic.be> */
- .name = "ProVideo PV150", /* 0x4f */
- .video_inputs = 2,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .gpiomask = 0,
- .muxsel = MUXSEL(2, 3),
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_AD_TVK503] = {
- /* Hiroshi Takekawa <sian@big.or.jp> */
- /* This card lacks subsystem ID */
- .name = "AD-TVK503", /* 0x63 */
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x001e8007,
- .muxsel = MUXSEL(2, 3, 1, 0),
- /* Tuner, Radio, external, internal, off, on */
- .gpiomux = { 0x08, 0x0f, 0x0a, 0x08 },
- .gpiomute = 0x0f,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_NTSC,
- .tuner_addr = ADDR_UNSET,
- .audio_mode_gpio= adtvk503_audio,
- },
-
- /* ---- card 0x64 ---------------------------------- */
- [BTTV_BOARD_HERCULES_SM_TV] = {
- .name = "Hercules Smart TV Stereo",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x00,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- /* Notes:
- - card lacks subsystem ID
- - stereo variant w/ daughter board with tda9874a @0xb0
- - Audio Routing:
- always from tda9874 independent of GPIO (?)
- external line in: unknown
- - Other chips: em78p156elp @ 0x96 (probably IR remote control)
- hef4053 (instead 4052) for unknown function
- */
- },
- [BTTV_BOARD_PACETV] = {
- .name = "Pace TV & Radio Card",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- /* Tuner, CVid, SVid, CVid over SVid connector */
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomask = 0,
- .no_tda7432 = 1,
- .tuner_type = TUNER_PHILIPS_PAL_I,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
- .pll = PLL_28,
- /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
- only internal line out: (4pin header) RGGL
- Radio must be decoded by msp3410d (not routed through)*/
- /*
- .digital_mode = DIGITAL_MODE_CAMERA, todo!
- */
- },
- [BTTV_BOARD_IVC200] = {
- /* Chris Willing <chris@vislab.usyd.edu.au> */
- .name = "IVC-200",
- .video_inputs = 1,
- /* .audio_inputs= 0, */
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .svhs = NO_SVHS,
- .gpiomask = 0xdf,
- .muxsel = MUXSEL(2),
- .pll = PLL_28,
- },
- [BTTV_BOARD_IVCE8784] = {
- .name = "IVCE-8784",
- .video_inputs = 1,
- /* .audio_inputs= 0, */
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .svhs = NO_SVHS,
- .gpiomask = 0xdf,
- .muxsel = MUXSEL(2),
- .pll = PLL_28,
- },
- [BTTV_BOARD_XGUARD] = {
- .name = "Grand X-Guard / Trust 814PCI",
- .video_inputs = 16,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .gpiomask2 = 0xff,
- .muxsel = MUXSEL(2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0),
- .muxsel_hook = xguard_muxsel,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .pll = PLL_28,
- },
-
- /* ---- card 0x68 ---------------------------------- */
- [BTTV_BOARD_NEBULA_DIGITV] = {
- .name = "Nebula Electronics DigiTV",
- .video_inputs = 1,
- .svhs = NO_SVHS,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .has_dvb = 1,
- .has_remote = 1,
- .gpiomask = 0x1b,
- .no_gpioirq = 1,
- },
- [BTTV_BOARD_PV143] = {
- /* Jorge Boncompte - DTI2 <jorge@dti2.net> */
- .name = "ProVideo PV143",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .gpiomask = 0,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_VD009X1_VD011_MINIDIN] = {
- /* M.Klahr@phytec.de */
- .name = "PHYTEC VD-009-X1 VD-011 MiniDIN (bt878)",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = 3,
- .gpiomask = 0x00,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_VD009X1_VD011_COMBI] = {
- .name = "PHYTEC VD-009-X1 VD-011 Combi (bt878)",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = 3,
- .gpiomask = 0x00,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
-
- /* ---- card 0x6c ---------------------------------- */
- [BTTV_BOARD_VD009_MINIDIN] = {
- .name = "PHYTEC VD-009 MiniDIN (bt878)",
- .video_inputs = 10,
- /* .audio_inputs= 0, */
- .svhs = 9,
- .gpiomask = 0x00,
- .gpiomask2 = 0x03, /* used for external vodeo mux */
- .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 0),
- .muxsel_hook = phytec_muxsel,
- .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_VD009_COMBI] = {
- .name = "PHYTEC VD-009 Combi (bt878)",
- .video_inputs = 10,
- /* .audio_inputs= 0, */
- .svhs = 9,
- .gpiomask = 0x00,
- .gpiomask2 = 0x03, /* used for external vodeo mux */
- .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1),
- .muxsel_hook = phytec_muxsel,
- .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_IVC100] = {
- .name = "IVC-100",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .svhs = NO_SVHS,
- .gpiomask = 0xdf,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .pll = PLL_28,
- },
- [BTTV_BOARD_IVC120] = {
- /* IVC-120G - Alan Garfield <alan@fromorbit.com> */
- .name = "IVC-120G",
- .video_inputs = 16,
- /* .audio_inputs= 0, */
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .svhs = NO_SVHS, /* card has no svhs */
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .gpiomask = 0x00,
- .muxsel = MUXSEL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- .muxsel_hook = ivc120_muxsel,
- .pll = PLL_28,
- },
-
- /* ---- card 0x70 ---------------------------------- */
- [BTTV_BOARD_PC_HDTV] = {
- .name = "pcHDTV HD-2000 TV",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .tuner_type = TUNER_PHILIPS_FCV1236D,
- .tuner_addr = ADDR_UNSET,
- .has_dvb = 1,
- },
- [BTTV_BOARD_TWINHAN_DST] = {
- .name = "Twinhan DST + clones",
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_video = 1,
- .has_dvb = 1,
- },
- [BTTV_BOARD_WINFASTVC100] = {
- .name = "Winfast VC100",
- .video_inputs = 3,
- /* .audio_inputs= 0, */
- .svhs = 1,
- /* Vid In, SVid In, Vid over SVid in connector */
- .muxsel = MUXSEL(3, 1, 1, 3),
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- },
- [BTTV_BOARD_TEV560] = {
- .name = "Teppro TEV-560/InterVision IV-560",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 3,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 1, 1, 1, 1 },
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_35,
- },
-
- /* ---- card 0x74 ---------------------------------- */
- [BTTV_BOARD_SIMUS_GVC1100] = {
- .name = "SIMUS GVC1100",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .muxsel = MUXSEL(2, 2, 2, 2),
- .gpiomask = 0x3F,
- .muxsel_hook = gvc1100_muxsel,
- },
- [BTTV_BOARD_NGSTV_PLUS] = {
- /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
- .name = "NGS NGSTV+",
- .video_inputs = 3,
- .svhs = 2,
- .gpiomask = 0x008007,
- .muxsel = MUXSEL(2, 3, 0, 0),
- .gpiomux = { 0, 0, 0, 0 },
- .gpiomute = 0x000003,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
- },
- [BTTV_BOARD_LMLBT4] = {
- /* http://linuxmedialabs.com */
- .name = "LMLBT4",
- .video_inputs = 4, /* IN1,IN2,IN3,IN4 */
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_TEKRAM_M205] = {
- /* Helmroos Harri <harri.helmroos@pp.inet.fi> */
- .name = "Tekram M205 PRO",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .svhs = 2,
- .gpiomask = 0x68,
- .muxsel = MUXSEL(2, 3, 1),
- .gpiomux = { 0x68, 0x68, 0x61, 0x61 },
- .pll = PLL_28,
- },
-
- /* ---- card 0x78 ---------------------------------- */
- [BTTV_BOARD_CONTVFMI] = {
- /* Javier Cendan Ares <jcendan@lycos.es> */
- /* bt878 TV + FM without subsystem ID */
- .name = "Conceptronic CONTVFMi",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x008007,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 1, 2, 2 },
- .gpiomute = 3,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
- .has_radio = 1,
- },
- [BTTV_BOARD_PICOLO_TETRA_CHIP] = {
- /*Eric DEBIEF <debief@telemsa.com>*/
- /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controlled*/
- /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the following declaration strucure, and #define BTTV_BOARD_PICOLO_TETRA_CHIP*/
- /*0x79 in bttv.h*/
- .name = "Euresys Picolo Tetra",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .gpiomask = 0,
- .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- /*878A input is always MUX0, see above.*/
- .muxsel = MUXSEL(2, 2, 2, 2),
- .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
- .pll = PLL_28,
- .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_SPIRIT_TV] = {
- /* Spirit TV Tuner from http://spiritmodems.com.au */
- /* Stafford Goodsell <surge@goliath.homeunix.org> */
- .name = "Spirit TV Tuner",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x0000000f,
- .muxsel = MUXSEL(2, 1, 1),
- .gpiomux = { 0x02, 0x00, 0x00, 0x00 },
- .tuner_type = TUNER_TEMIC_PAL,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- },
- [BTTV_BOARD_AVDVBT_771] = {
- /* Wolfram Joost <wojo@frokaschwei.de> */
- .name = "AVerMedia AVerTV DVB-T 771",
- .video_inputs = 2,
- .svhs = 1,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .muxsel = MUXSEL(3, 3),
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .pll = PLL_28,
- .has_dvb = 1,
- .no_gpioirq = 1,
- .has_remote = 1,
- },
- /* ---- card 0x7c ---------------------------------- */
- [BTTV_BOARD_AVDVBT_761] = {
- /* Matt Jesson <dvb@jesson.eclipse.co.uk> */
- /* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */
- .name = "AverMedia AverTV DVB-T 761",
- .video_inputs = 2,
- .svhs = 1,
- .muxsel = MUXSEL(3, 1, 2, 0), /* Comp0, S-Video, ?, ? */
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .has_dvb = 1,
- .no_gpioirq = 1,
- .has_remote = 1,
- },
- [BTTV_BOARD_MATRIX_VISIONSQ] = {
- /* andre.schwarz@matrix-vision.de */
- .name = "MATRIX Vision Sigma-SQ",
- .video_inputs = 16,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .gpiomask = 0x0,
- .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3),
- .muxsel_hook = sigmaSQ_muxsel,
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_MATRIX_VISIONSLC] = {
- /* andre.schwarz@matrix-vision.de */
- .name = "MATRIX Vision Sigma-SLC",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .gpiomask = 0x0,
- .muxsel = MUXSEL(2, 2, 2, 2),
- .muxsel_hook = sigmaSLC_muxsel,
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- /* BTTV_BOARD_APAC_VIEWCOMP */
- [BTTV_BOARD_APAC_VIEWCOMP] = {
- /* Attila Kondoros <attila.kondoros@chello.hu> */
- /* bt878 TV + FM 0x00000000 subsystem ID */
- .name = "APAC Viewcomp 878(AMAX)",
- .video_inputs = 2,
- /* .audio_inputs= 1, */
- .svhs = NO_SVHS,
- .gpiomask = 0xFF,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 2, 0, 0, 0 },
- .gpiomute = 10,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
- .has_radio = 1, /* not every card has radio */
- },
-
- /* ---- card 0x80 ---------------------------------- */
- [BTTV_BOARD_DVICO_DVBT_LITE] = {
- /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
- .name = "DViCO FusionHDTV DVB-T Lite",
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .pll = PLL_28,
- .no_video = 1,
- .has_dvb = 1,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_VGEAR_MYVCD] = {
- /* Steven <photon38@pchome.com.tw> */
- .name = "V-Gear MyVCD",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x3f,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .gpiomux = {0x31, 0x31, 0x31, 0x31 },
- .gpiomute = 0x31,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 0,
- },
- [BTTV_BOARD_SUPER_TV] = {
- /* Rick C <cryptdragoon@gmail.com> */
- .name = "Super TV Tuner",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .tuner_type = TUNER_PHILIPS_NTSC,
- .tuner_addr = ADDR_UNSET,
- .gpiomask = 0x008007,
- .gpiomux = { 0, 0x000001,0,0 },
- .has_radio = 1,
- },
- [BTTV_BOARD_TIBET_CS16] = {
- /* Chris Fanning <video4linux@haydon.net> */
- .name = "Tibet Systems 'Progress DVR' CS16",
- .video_inputs = 16,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
- .pll = PLL_28,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .muxsel_hook = tibetCS16_muxsel,
- },
- [BTTV_BOARD_KODICOM_4400R] = {
- /* Bill Brack <wbrack@mmm.com.hk> */
- /*
- * Note that, because of the card's wiring, the "master"
- * BT878A chip (i.e. the one which controls the analog switch
- * and must use this card type) is the 2nd one detected. The
- * other 3 chips should use card type 0x85, whose description
- * follows this one. There is a EEPROM on the card (which is
- * connected to the I2C of one of those other chips), but is
- * not currently handled. There is also a facility for a
- * "monitor", which is also not currently implemented.
- */
- .name = "Kodicom 4400R (master)",
- .video_inputs = 16,
- /* .audio_inputs= 0, */
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .svhs = NO_SVHS,
- /* GPIO bits 0-9 used for analog switch:
- * 00 - 03: camera selector
- * 04 - 06: channel (controller) selector
- * 07: data (1->on, 0->off)
- * 08: strobe
- * 09: reset
- * bit 16 is input from sync separator for the channel
- */
- .gpiomask = 0x0003ff,
- .no_gpioirq = 1,
- .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
- .pll = PLL_28,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .muxsel_hook = kodicom4400r_muxsel,
- },
- [BTTV_BOARD_KODICOM_4400R_SL] = {
- /* Bill Brack <wbrack@mmm.com.hk> */
- /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the
- * one which controls the analog switch, and must use the card type)
- * is the 2nd one detected. The other 3 chips should use this card
- * type
- */
- .name = "Kodicom 4400R (slave)",
- .video_inputs = 16,
- /* .audio_inputs= 0, */
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .svhs = NO_SVHS,
- .gpiomask = 0x010000,
- .no_gpioirq = 1,
- .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
- .pll = PLL_28,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .muxsel_hook = kodicom4400r_muxsel,
- },
- /* ---- card 0x86---------------------------------- */
- [BTTV_BOARD_ADLINK_RTV24] = {
- /* Michael Henson <mhenson@clarityvi.com> */
- /* Adlink RTV24 with special unlock codes */
- .name = "Adlink RTV24",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- },
- /* ---- card 0x87---------------------------------- */
- [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = {
- /* Michael Krufky <mkrufky@m1k.net> */
- .name = "DViCO FusionHDTV 5 Lite",
- .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */
- .tuner_addr = ADDR_UNSET,
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .muxsel = MUXSEL(2, 3, 1),
- .gpiomask = 0x00e00007,
- .gpiomux = { 0x00400005, 0, 0x00000001, 0 },
- .gpiomute = 0x00c00007,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .has_dvb = 1,
- },
- /* ---- card 0x88---------------------------------- */
- [BTTV_BOARD_ACORP_Y878F] = {
- /* Mauro Carvalho Chehab <mchehab@infradead.org> */
- .name = "Acorp Y878F",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x01fe00,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 },
- .gpiomute = 0x002000,
- .pll = PLL_28,
- .tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
- .tuner_addr = 0xc1 >>1,
- .has_radio = 1,
- },
- /* ---- card 0x89 ---------------------------------- */
- [BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = {
- .name = "Conceptronic CTVFMi v2",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x001c0007,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 1, 2, 2 },
- .gpiomute = 3,
- .pll = PLL_28,
- .tuner_type = TUNER_TENA_9533_DI,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
- .has_radio = 1,
- },
- /* ---- card 0x8a ---------------------------------- */
- [BTTV_BOARD_PV_BT878P_2E] = {
- .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
- .video_inputs = 5,
- /* .audio_inputs= 1, */
- .svhs = 3,
- .has_dig_in = 1,
- .gpiomask = 0x01fe00,
- .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */
- /* .digital_mode= DIGITAL_MODE_CAMERA, */
- .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 },
- .gpiomute = 0x12400,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_LG_PAL_FM,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
- },
- /* ---- card 0x8b ---------------------------------- */
- [BTTV_BOARD_PV_M4900] = {
- /* Sérgio Fortier <sergiofortier@yahoo.com.br> */
- .name = "Prolink PixelView PlayTV MPEG2 PV-M4900",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x3f,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x21, 0x20, 0x24, 0x2c },
- .gpiomute = 0x29,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_YMEC_TVF_5533MF,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
- .has_remote = 1,
- },
- /* ---- card 0x8c ---------------------------------- */
- /* Has four Bt878 chips behind a PCI bridge, each chip has:
- one external BNC composite input (mux 2)
- three internal composite inputs (unknown muxes)
- an 18-bit stereo A/D (CS5331A), which has:
- one external stereo unblanced (RCA) audio connection
- one (or 3?) internal stereo balanced (XLR) audio connection
- input is selected via gpio to a 14052B mux
- (mask=0x300, unbal=0x000, bal=0x100, ??=0x200,0x300)
- gain is controlled via an X9221A chip on the I2C bus @0x28
- sample rate is controlled via gpio to an MK1413S
- (mask=0x3, 32kHz=0x0, 44.1kHz=0x1, 48kHz=0x2, ??=0x3)
- There is neither a tuner nor an svideo input. */
- [BTTV_BOARD_OSPREY440] = {
- .name = "Osprey 440",
- .video_inputs = 4,
- /* .audio_inputs= 2, */
- .svhs = NO_SVHS,
- .muxsel = MUXSEL(2, 3, 0, 1), /* 3,0,1 are guesses */
- .gpiomask = 0x303,
- .gpiomute = 0x000, /* int + 32kHz */
- .gpiomux = { 0, 0, 0x000, 0x100},
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- },
- /* ---- card 0x8d ---------------------------------- */
- [BTTV_BOARD_ASOUND_SKYEYE] = {
- .name = "Asound Skyeye PCTV",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 2, 0, 0, 0 },
- .gpiomute = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_NTSC,
- .tuner_addr = ADDR_UNSET,
- },
- /* ---- card 0x8e ---------------------------------- */
- [BTTV_BOARD_SABRENT_TVFM] = {
- .name = "Sabrent TV-FM (bttv version)",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x108007,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 100000, 100002, 100002, 100000 },
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_TNF_5335MF,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
- },
- /* ---- card 0x8f ---------------------------------- */
- [BTTV_BOARD_HAUPPAUGE_IMPACTVCB] = {
- .name = "Hauppauge ImpactVCB (bt878)",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .gpiomask = 0x0f, /* old: 7 */
- .muxsel = MUXSEL(0, 1, 3, 2), /* Composite 0-3 */
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_MACHTV_MAGICTV] = {
- /* Julian Calaby <julian.calaby@gmail.com>
- * Slightly different from original MachTV definition (0x60)
-
- * FIXME: RegSpy says gpiomask should be "0x001c800f", but it
- * stuffs up remote chip. Bug is a pin on the jaecs is not set
- * properly (methinks) causing no keyup bits being set */
-
- .name = "MagicTV", /* rebranded MachTV */
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 7,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 1, 2, 3 },
- .gpiomute = 4,
- .tuner_type = TUNER_TEMIC_4009FR5_PAL,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .has_radio = 1,
- .has_remote = 1,
- },
- [BTTV_BOARD_SSAI_SECURITY] = {
- .name = "SSAI Security Video Interface",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .muxsel = MUXSEL(0, 1, 2, 3),
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_SSAI_ULTRASOUND] = {
- .name = "SSAI Ultrasound Video Interface",
- .video_inputs = 2,
- /* .audio_inputs= 0, */
- .svhs = 1,
- .muxsel = MUXSEL(2, 0, 1, 3),
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- /* ---- card 0x94---------------------------------- */
- [BTTV_BOARD_DVICO_FUSIONHDTV_2] = {
- .name = "DViCO FusionHDTV 2",
- .tuner_type = TUNER_PHILIPS_FCV1236D,
- .tuner_addr = ADDR_UNSET,
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .muxsel = MUXSEL(2, 3, 1),
- .gpiomask = 0x00e00007,
- .gpiomux = { 0x00400005, 0, 0x00000001, 0 },
- .gpiomute = 0x00c00007,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- },
- /* ---- card 0x95---------------------------------- */
- [BTTV_BOARD_TYPHOON_TVTUNERPCI] = {
- .name = "Typhoon TV-Tuner PCI (50684)",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x3014f,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x20001,0x10001, 0, 0 },
- .gpiomute = 10,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL_I,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_GEOVISION_GV600] = {
- /* emhn@usb.ve */
- .name = "Geovision GV-600",
- .video_inputs = 16,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .gpiomask = 0x0,
- .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
- .muxsel_hook = geovision_muxsel,
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_KOZUMI_KTV_01C] = {
- /* Mauro Lacy <mauro@lacy.com.ar>
- * Based on MagicTV and Conceptronic CONTVFMi */
-
- .name = "Kozumi KTV-01C",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- .gpiomask = 0x008007,
- .muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 1, 2, 2 }, /* CONTVFMi */
- .gpiomute = 3, /* CONTVFMi */
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .has_radio = 1,
- .has_remote = 1,
- },
- [BTTV_BOARD_ENLTV_FM_2] = {
- /* Encore TV Tuner Pro ENL TV-FM-2
- Mauro Carvalho Chehab <mchehab@infradead.org */
- .name = "Encore ENL TV-FM-2",
- .video_inputs = 3,
- /* .audio_inputs= 1, */
- .svhs = 2,
- /* bit 6 -> IR disabled
- bit 18/17 = 00 -> mute
- 01 -> enable external audio input
- 10 -> internal audio input (mono?)
- 11 -> internal audio input
- */
- .gpiomask = 0x060040,
- .muxsel = MUXSEL(2, 3, 3),
- .gpiomux = { 0x60000, 0x60000, 0x20000, 0x20000 },
- .gpiomute = 0,
- .tuner_type = TUNER_TCL_MF02GIP_5N,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .has_radio = 1,
- .has_remote = 1,
- },
- [BTTV_BOARD_VD012] = {
- /* D.Heer@Phytec.de */
- .name = "PHYTEC VD-012 (bt878)",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .gpiomask = 0x00,
- .muxsel = MUXSEL(0, 2, 3, 1),
- .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_VD012_X1] = {
- /* D.Heer@Phytec.de */
- .name = "PHYTEC VD-012-X1 (bt878)",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = 3,
- .gpiomask = 0x00,
- .muxsel = MUXSEL(2, 3, 1),
- .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_VD012_X2] = {
- /* D.Heer@Phytec.de */
- .name = "PHYTEC VD-012-X2 (bt878)",
- .video_inputs = 4,
- /* .audio_inputs= 0, */
- .svhs = 3,
- .gpiomask = 0x00,
- .muxsel = MUXSEL(3, 2, 1),
- .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_GEOVISION_GV800S] = {
- /* Bruno Christo <bchristo@inf.ufsm.br>
- *
- * GeoVision GV-800(S) has 4 Conexant Fusion 878A:
- * 1 audio input per BT878A = 4 audio inputs
- * 4 video inputs per BT878A = 16 video inputs
- * This is the first BT878A chip of the GV-800(S). It's the
- * "master" chip and it controls the video inputs through an
- * analog multiplexer (a CD22M3494) via some GPIO pins. The
- * slaves should use card type 0x9e (following this one).
- * There is a EEPROM on the card which is currently not handled.
- * The audio input is not working yet.
- */
- .name = "Geovision GV-800(S) (master)",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .svhs = NO_SVHS,
- .gpiomask = 0xf107f,
- .no_gpioirq = 1,
- .muxsel = MUXSEL(2, 2, 2, 2),
- .pll = PLL_28,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .muxsel_hook = gv800s_muxsel,
- },
- [BTTV_BOARD_GEOVISION_GV800S_SL] = {
- /* Bruno Christo <bchristo@inf.ufsm.br>
- *
- * GeoVision GV-800(S) has 4 Conexant Fusion 878A:
- * 1 audio input per BT878A = 4 audio inputs
- * 4 video inputs per BT878A = 16 video inputs
- * The 3 other BT878A chips are "slave" chips of the GV-800(S)
- * and should use this card type.
- * The audio input is not working yet.
- */
- .name = "Geovision GV-800(S) (slave)",
- .video_inputs = 4,
- /* .audio_inputs= 1, */
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .svhs = NO_SVHS,
- .gpiomask = 0x00,
- .no_gpioirq = 1,
- .muxsel = MUXSEL(2, 2, 2, 2),
- .pll = PLL_28,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .muxsel_hook = gv800s_muxsel,
- },
- [BTTV_BOARD_PV183] = {
- .name = "ProVideo PV183", /* 0x9f */
- .video_inputs = 2,
- /* .audio_inputs= 0, */
- .svhs = NO_SVHS,
- .gpiomask = 0,
- .muxsel = MUXSEL(2, 3),
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- },
- [BTTV_BOARD_TVT_TD3116] = {
- .name = "Tongwei Video Technology TD-3116",
- .video_inputs = 16,
- .gpiomask = 0xc00ff,
- .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
- .muxsel_hook = td3116_muxsel,
- .svhs = NO_SVHS,
- .pll = PLL_28,
- .tuner_type = TUNER_ABSENT,
- },
- [BTTV_BOARD_APOSONIC_WDVR] = {
- .name = "Aposonic W-DVR",
- .video_inputs = 4,
- .svhs = NO_SVHS,
- .muxsel = MUXSEL(2, 3, 1, 0),
- .tuner_type = TUNER_ABSENT,
- },
-
-};
-
-static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
-
-/* ----------------------------------------------------------------------- */
-
-static unsigned char eeprom_data[256];
-
-/*
- * identify card
- */
-void __devinit bttv_idcard(struct bttv *btv)
-{
- unsigned int gpiobits;
- int i,type;
-
- /* read PCI subsystem ID */
- btv->cardid = btv->c.pci->subsystem_device << 16;
- btv->cardid |= btv->c.pci->subsystem_vendor;
-
- if (0 != btv->cardid && 0xffffffff != btv->cardid) {
- /* look for the card */
- for (type = -1, i = 0; cards[i].id != 0; i++)
- if (cards[i].id == btv->cardid)
- type = i;
-
- if (type != -1) {
- /* found it */
- pr_info("%d: detected: %s [card=%d], PCI subsystem ID is %04x:%04x\n",
- btv->c.nr, cards[type].name, cards[type].cardnr,
- btv->cardid & 0xffff,
- (btv->cardid >> 16) & 0xffff);
- btv->c.type = cards[type].cardnr;
- } else {
- /* 404 */
- pr_info("%d: subsystem: %04x:%04x (UNKNOWN)\n",
- btv->c.nr, btv->cardid & 0xffff,
- (btv->cardid >> 16) & 0xffff);
- pr_debug("please mail id, board name and the correct card= insmod option to linux-media@vger.kernel.org\n");
- }
- }
-
- /* let the user override the autodetected type */
- if (card[btv->c.nr] < bttv_num_tvcards)
- btv->c.type=card[btv->c.nr];
-
- /* print which card config we are using */
- pr_info("%d: using: %s [card=%d,%s]\n",
- btv->c.nr, bttv_tvcards[btv->c.type].name, btv->c.type,
- card[btv->c.nr] < bttv_num_tvcards
- ? "insmod option" : "autodetected");
-
- /* overwrite gpio stuff ?? */
- if (UNSET == audioall && UNSET == audiomux[0])
- return;
-
- if (UNSET != audiomux[0]) {
- gpiobits = 0;
- for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
- bttv_tvcards[btv->c.type].gpiomux[i] = audiomux[i];
- gpiobits |= audiomux[i];
- }
- } else {
- gpiobits = audioall;
- for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
- bttv_tvcards[btv->c.type].gpiomux[i] = audioall;
- }
- }
- bttv_tvcards[btv->c.type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits;
- pr_info("%d: gpio config override: mask=0x%x, mux=",
- btv->c.nr, bttv_tvcards[btv->c.type].gpiomask);
- for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
- pr_cont("%s0x%x",
- i ? "," : "", bttv_tvcards[btv->c.type].gpiomux[i]);
- }
- pr_cont("\n");
-}
-
-/*
- * (most) board specific initialisations goes here
- */
-
-/* Some Modular Technology cards have an eeprom, but no subsystem ID */
-static void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
-{
- int type = -1;
-
- if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13))
- type = BTTV_BOARD_MODTEC_205;
- else if (0 == strncmp(eeprom_data+20,"Picolo",7))
- type = BTTV_BOARD_EURESYS_PICOLO;
- else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0)
- type = BTTV_BOARD_HAUPPAUGE; /* old bt848 */
-
- if (-1 != type) {
- btv->c.type = type;
- pr_info("%d: detected by eeprom: %s [card=%d]\n",
- btv->c.nr, bttv_tvcards[btv->c.type].name, btv->c.type);
- }
-}
-
-static void flyvideo_gpio(struct bttv *btv)
-{
- int gpio, has_remote, has_radio, is_capture_only;
- int is_lr90, has_tda9820_tda9821;
- int tuner_type = UNSET, ttype;
-
- gpio_inout(0xffffff, 0);
- udelay(8); /* without this we would see the 0x1800 mask */
- gpio = gpio_read();
- /* FIXME: must restore OUR_EN ??? */
-
- /* all cards provide GPIO info, some have an additional eeprom
- * LR50: GPIO coding can be found lower right CP1 .. CP9
- * CP9=GPIO23 .. CP1=GPIO15; when OPEN, the corresponding GPIO reads 1.
- * GPIO14-12: n.c.
- * LR90: GP9=GPIO23 .. GP1=GPIO15 (right above the bt878)
-
- * lowest 3 bytes are remote control codes (no handshake needed)
- * xxxFFF: No remote control chip soldered
- * xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered
- * Note: Some bits are Audio_Mask !
- */
- ttype = (gpio & 0x0f0000) >> 16;
- switch (ttype) {
- case 0x0:
- tuner_type = 2; /* NTSC, e.g. TPI8NSR11P */
- break;
- case 0x2:
- tuner_type = 39; /* LG NTSC (newer TAPC series) TAPC-H701P */
- break;
- case 0x4:
- tuner_type = 5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */
- break;
- case 0x6:
- tuner_type = 37; /* LG PAL (newer TAPC series) TAPC-G702P */
- break;
- case 0xC:
- tuner_type = 3; /* Philips SECAM(+PAL) FQ1216ME or FI1216MF */
- break;
- default:
- pr_info("%d: FlyVideo_gpio: unknown tuner type\n", btv->c.nr);
- break;
- }
-
- has_remote = gpio & 0x800000;
- has_radio = gpio & 0x400000;
- /* unknown 0x200000;
- * unknown2 0x100000; */
- is_capture_only = !(gpio & 0x008000); /* GPIO15 */
- has_tda9820_tda9821 = !(gpio & 0x004000);
- is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */
- /*
- * gpio & 0x001000 output bit for audio routing */
-
- if (is_capture_only)
- tuner_type = TUNER_ABSENT; /* No tuner present */
-
- pr_info("%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n",
- btv->c.nr, has_radio ? "yes" : "no",
- has_remote ? "yes" : "no", tuner_type, gpio);
- pr_info("%d: FlyVideo LR90=%s tda9821/tda9820=%s capture_only=%s\n",
- btv->c.nr, is_lr90 ? "yes" : "no",
- has_tda9820_tda9821 ? "yes" : "no",
- is_capture_only ? "yes" : "no");
-
- if (tuner_type != UNSET) /* only set if known tuner autodetected, else let insmod option through */
- btv->tuner_type = tuner_type;
- btv->has_radio = has_radio;
-
- /* LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80
- * LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00
- * Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute */
- if (has_tda9820_tda9821)
- btv->audio_mode_gpio = lt9415_audio;
- /* todo: if(has_tda9874) btv->audio_mode_gpio = fv2000s_audio; */
-}
-
-static int miro_tunermap[] = { 0,6,2,3, 4,5,6,0, 3,0,4,5, 5,2,16,1,
- 14,2,17,1, 4,1,4,3, 1,2,16,1, 4,4,4,4 };
-static int miro_fmtuner[] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1,
- 1,1,1,1, 1,1,1,0, 0,0,0,0, 0,1,0,0 };
-
-static void miro_pinnacle_gpio(struct bttv *btv)
-{
- int id,msp,gpio;
- char *info;
-
- gpio_inout(0xffffff, 0);
- gpio = gpio_read();
- id = ((gpio>>10) & 63) -1;
- msp = bttv_I2CRead(btv, I2C_ADDR_MSP3400, "MSP34xx");
- if (id < 32) {
- btv->tuner_type = miro_tunermap[id];
- if (0 == (gpio & 0x20)) {
- btv->has_radio = 1;
- if (!miro_fmtuner[id]) {
- btv->has_matchbox = 1;
- btv->mbox_we = (1<<6);
- btv->mbox_most = (1<<7);
- btv->mbox_clk = (1<<8);
- btv->mbox_data = (1<<9);
- btv->mbox_mask = (1<<6)|(1<<7)|(1<<8)|(1<<9);
- }
- } else {
- btv->has_radio = 0;
- }
- if (-1 != msp) {
- if (btv->c.type == BTTV_BOARD_MIRO)
- btv->c.type = BTTV_BOARD_MIROPRO;
- if (btv->c.type == BTTV_BOARD_PINNACLE)
- btv->c.type = BTTV_BOARD_PINNACLEPRO;
- }
- pr_info("%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
- btv->c.nr, id+1, btv->tuner_type,
- !btv->has_radio ? "no" :
- (btv->has_matchbox ? "matchbox" : "fmtuner"),
- (-1 == msp) ? "no" : "yes");
- } else {
- /* new cards with microtune tuner */
- id = 63 - id;
- btv->has_radio = 0;
- switch (id) {
- case 1:
- info = "PAL / mono";
- btv->tda9887_conf = TDA9887_INTERCARRIER;
- break;
- case 2:
- info = "PAL+SECAM / stereo";
- btv->has_radio = 1;
- btv->tda9887_conf = TDA9887_QSS;
- break;
- case 3:
- info = "NTSC / stereo";
- btv->has_radio = 1;
- btv->tda9887_conf = TDA9887_QSS;
- break;
- case 4:
- info = "PAL+SECAM / mono";
- btv->tda9887_conf = TDA9887_QSS;
- break;
- case 5:
- info = "NTSC / mono";
- btv->tda9887_conf = TDA9887_INTERCARRIER;
- break;
- case 6:
- info = "NTSC / stereo";
- btv->tda9887_conf = TDA9887_INTERCARRIER;
- break;
- case 7:
- info = "PAL / stereo";
- btv->tda9887_conf = TDA9887_INTERCARRIER;
- break;
- default:
- info = "oops: unknown card";
- break;
- }
- if (-1 != msp)
- btv->c.type = BTTV_BOARD_PINNACLEPRO;
- pr_info("%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n",
- btv->c.nr, id, info, btv->has_radio ? "yes" : "no");
- btv->tuner_type = TUNER_MT2032;
- }
-}
-
-/* GPIO21 L: Buffer aktiv, H: Buffer inaktiv */
-#define LM1882_SYNC_DRIVE 0x200000L
-
-static void init_ids_eagle(struct bttv *btv)
-{
- gpio_inout(0xffffff,0xFFFF37);
- gpio_write(0x200020);
-
- /* flash strobe inverter ?! */
- gpio_write(0x200024);
-
- /* switch sync drive off */
- gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE);
-
- /* set BT848 muxel to 2 */
- btaor((2)<<5, ~(2<<5), BT848_IFORM);
-}
-
-/* Muxsel helper for the IDS Eagle.
- * the eagles does not use the standard muxsel-bits but
- * has its own multiplexer */
-static void eagle_muxsel(struct bttv *btv, unsigned int input)
-{
- gpio_bits(3, input & 3);
-
- /* composite */
- /* set chroma ADC to sleep */
- btor(BT848_ADC_C_SLEEP, BT848_ADC);
- /* set to composite video */
- btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
- btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
-
- /* switch sync drive off */
- gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE);
-}
-
-static void gvc1100_muxsel(struct bttv *btv, unsigned int input)
-{
- static const int masks[] = {0x30, 0x01, 0x12, 0x23};
- gpio_write(masks[input%4]);
-}
-
-/* LMLBT4x initialization - to allow access to GPIO bits for sensors input and
- alarms output
-
- GPIObit | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- assignment | TI | O3|INx| O2| O1|IN4|IN3|IN2|IN1| | |
-
- IN - sensor inputs, INx - sensor inputs and TI XORed together
- O1,O2,O3 - alarm outputs (relays)
-
- OUT ENABLE 1 1 0 . 1 1 0 0 . 0 0 0 0 = 0x6C0
-
-*/
-
-static void init_lmlbt4x(struct bttv *btv)
-{
- pr_debug("LMLBT4x init\n");
- btwrite(0x000000, BT848_GPIO_REG_INP);
- gpio_inout(0xffffff, 0x0006C0);
- gpio_write(0x000000);
-}
-
-static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input)
-{
- unsigned int inmux = input % 8;
- gpio_inout( 0xf, 0xf );
- gpio_bits( 0xf, inmux );
-}
-
-static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input)
-{
- unsigned int inmux = input % 4;
- gpio_inout( 3<<9, 3<<9 );
- gpio_bits( 3<<9, inmux<<9 );
-}
-
-static void geovision_muxsel(struct bttv *btv, unsigned int input)
-{
- unsigned int inmux = input % 16;
- gpio_inout(0xf, 0xf);
- gpio_bits(0xf, inmux);
-}
-
-/*
- * The TD3116 has 2 74HC4051 muxes wired to the MUX0 input of a bt878.
- * The first 74HC4051 has the lower 8 inputs, the second one the higher 8.
- * The muxes are controlled via a 74HC373 latch which is connected to
- * GPIOs 0-7. GPIO 18 is connected to the LE signal of the latch.
- * Q0 of the latch is connected to the Enable (~E) input of the first
- * 74HC4051. Q1 - Q3 are connected to S0 - S2 of the same 74HC4051.
- * Q4 - Q7 are connected to the second 74HC4051 in the same way.
- */
-
-static void td3116_latch_value(struct bttv *btv, u32 value)
-{
- gpio_bits((1<<18) | 0xff, value);
- gpio_bits((1<<18) | 0xff, (1<<18) | value);
- udelay(1);
- gpio_bits((1<<18) | 0xff, value);
-}
-
-static void td3116_muxsel(struct bttv *btv, unsigned int input)
-{
- u32 value;
- u32 highbit;
-
- highbit = (input & 0x8) >> 3 ;
-
- /* Disable outputs and set value in the mux */
- value = 0x11; /* Disable outputs */
- value |= ((input & 0x7) << 1) << (4 * highbit);
- td3116_latch_value(btv, value);
-
- /* Enable the correct output */
- value &= ~0x11;
- value |= ((highbit ^ 0x1) << 4) | highbit;
- td3116_latch_value(btv, value);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static void bttv_reset_audio(struct bttv *btv)
-{
- /*
- * BT878A has a audio-reset register.
- * 1. This register is an audio reset function but it is in
- * function-0 (video capture) address space.
- * 2. It is enough to do this once per power-up of the card.
- * 3. There is a typo in the Conexant doc -- it is not at
- * 0x5B, but at 0x058. (B is an odd-number, obviously a typo!).
- * --//Shrikumar 030609
- */
- if (btv->id != 878)
- return;
-
- if (bttv_debug)
- pr_debug("%d: BT878A ARESET\n", btv->c.nr);
- btwrite((1<<7), 0x058);
- udelay(10);
- btwrite( 0, 0x058);
-}
-
-/* initialization part one -- before registering i2c bus */
-void __devinit bttv_init_card1(struct bttv *btv)
-{
- switch (btv->c.type) {
- case BTTV_BOARD_HAUPPAUGE:
- case BTTV_BOARD_HAUPPAUGE878:
- boot_msp34xx(btv,5);
- break;
- case BTTV_BOARD_VOODOOTV_200:
- case BTTV_BOARD_VOODOOTV_FM:
- boot_msp34xx(btv,20);
- break;
- case BTTV_BOARD_AVERMEDIA98:
- boot_msp34xx(btv,11);
- break;
- case BTTV_BOARD_HAUPPAUGEPVR:
- pvr_boot(btv);
- break;
- case BTTV_BOARD_TWINHAN_DST:
- case BTTV_BOARD_AVDVBT_771:
- case BTTV_BOARD_PINNACLESAT:
- btv->use_i2c_hw = 1;
- break;
- case BTTV_BOARD_ADLINK_RTV24:
- init_RTV24( btv );
- break;
-
- }
- if (!bttv_tvcards[btv->c.type].has_dvb)
- bttv_reset_audio(btv);
-}
-
-/* initialization part two -- after registering i2c bus */
-void __devinit bttv_init_card2(struct bttv *btv)
-{
- btv->tuner_type = UNSET;
-
- if (BTTV_BOARD_UNKNOWN == btv->c.type) {
- bttv_readee(btv,eeprom_data,0xa0);
- identify_by_eeprom(btv,eeprom_data);
- }
-
- switch (btv->c.type) {
- case BTTV_BOARD_MIRO:
- case BTTV_BOARD_MIROPRO:
- case BTTV_BOARD_PINNACLE:
- case BTTV_BOARD_PINNACLEPRO:
- /* miro/pinnacle */
- miro_pinnacle_gpio(btv);
- break;
- case BTTV_BOARD_FLYVIDEO_98:
- case BTTV_BOARD_MAXI:
- case BTTV_BOARD_LIFE_FLYKIT:
- case BTTV_BOARD_FLYVIDEO:
- case BTTV_BOARD_TYPHOON_TVIEW:
- case BTTV_BOARD_CHRONOS_VS2:
- case BTTV_BOARD_FLYVIDEO_98FM:
- case BTTV_BOARD_FLYVIDEO2000:
- case BTTV_BOARD_FLYVIDEO98EZ:
- case BTTV_BOARD_CONFERENCETV:
- case BTTV_BOARD_LIFETEC_9415:
- flyvideo_gpio(btv);
- break;
- case BTTV_BOARD_HAUPPAUGE:
- case BTTV_BOARD_HAUPPAUGE878:
- case BTTV_BOARD_HAUPPAUGEPVR:
- /* pick up some config infos from the eeprom */
- bttv_readee(btv,eeprom_data,0xa0);
- hauppauge_eeprom(btv);
- break;
- case BTTV_BOARD_AVERMEDIA98:
- case BTTV_BOARD_AVPHONE98:
- bttv_readee(btv,eeprom_data,0xa0);
- avermedia_eeprom(btv);
- break;
- case BTTV_BOARD_PXC200:
- init_PXC200(btv);
- break;
- case BTTV_BOARD_PICOLO_TETRA_CHIP:
- picolo_tetra_init(btv);
- break;
- case BTTV_BOARD_VHX:
- btv->has_radio = 1;
- btv->has_matchbox = 1;
- btv->mbox_we = 0x20;
- btv->mbox_most = 0;
- btv->mbox_clk = 0x08;
- btv->mbox_data = 0x10;
- btv->mbox_mask = 0x38;
- break;
- case BTTV_BOARD_VOBIS_BOOSTAR:
- case BTTV_BOARD_TERRATV:
- terratec_active_radio_upgrade(btv);
- break;
- case BTTV_BOARD_MAGICTVIEW061:
- if (btv->cardid == 0x3002144f) {
- btv->has_radio=1;
- pr_info("%d: radio detected by subsystem id (CPH05x)\n",
- btv->c.nr);
- }
- break;
- case BTTV_BOARD_STB2:
- if (btv->cardid == 0x3060121a) {
- /* Fix up entry for 3DFX VoodooTV 100,
- which is an OEM STB card variant. */
- btv->has_radio=0;
- btv->tuner_type=TUNER_TEMIC_NTSC;
- }
- break;
- case BTTV_BOARD_OSPREY1x0:
- case BTTV_BOARD_OSPREY1x0_848:
- case BTTV_BOARD_OSPREY101_848:
- case BTTV_BOARD_OSPREY1x1:
- case BTTV_BOARD_OSPREY1x1_SVID:
- case BTTV_BOARD_OSPREY2xx:
- case BTTV_BOARD_OSPREY2x0_SVID:
- case BTTV_BOARD_OSPREY2x0:
- case BTTV_BOARD_OSPREY440:
- case BTTV_BOARD_OSPREY500:
- case BTTV_BOARD_OSPREY540:
- case BTTV_BOARD_OSPREY2000:
- bttv_readee(btv,eeprom_data,0xa0);
- osprey_eeprom(btv, eeprom_data);
- break;
- case BTTV_BOARD_IDS_EAGLE:
- init_ids_eagle(btv);
- break;
- case BTTV_BOARD_MODTEC_205:
- bttv_readee(btv,eeprom_data,0xa0);
- modtec_eeprom(btv);
- break;
- case BTTV_BOARD_LMLBT4:
- init_lmlbt4x(btv);
- break;
- case BTTV_BOARD_TIBET_CS16:
- tibetCS16_init(btv);
- break;
- case BTTV_BOARD_KODICOM_4400R:
- kodicom4400r_init(btv);
- break;
- case BTTV_BOARD_GEOVISION_GV800S:
- gv800s_init(btv);
- break;
- }
-
- /* pll configuration */
- if (!(btv->id==848 && btv->revision==0x11)) {
- /* defaults from card list */
- if (PLL_28 == bttv_tvcards[btv->c.type].pll) {
- btv->pll.pll_ifreq=28636363;
- btv->pll.pll_crystal=BT848_IFORM_XT0;
- }
- if (PLL_35 == bttv_tvcards[btv->c.type].pll) {
- btv->pll.pll_ifreq=35468950;
- btv->pll.pll_crystal=BT848_IFORM_XT1;
- }
- /* insmod options can override */
- switch (pll[btv->c.nr]) {
- case 0: /* none */
- btv->pll.pll_crystal = 0;
- btv->pll.pll_ifreq = 0;
- btv->pll.pll_ofreq = 0;
- break;
- case 1: /* 28 MHz */
- case 28:
- btv->pll.pll_ifreq = 28636363;
- btv->pll.pll_ofreq = 0;
- btv->pll.pll_crystal = BT848_IFORM_XT0;
- break;
- case 2: /* 35 MHz */
- case 35:
- btv->pll.pll_ifreq = 35468950;
- btv->pll.pll_ofreq = 0;
- btv->pll.pll_crystal = BT848_IFORM_XT1;
- break;
- }
- }
- btv->pll.pll_current = -1;
-
- /* tuner configuration (from card list / autodetect / insmod option) */
- if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
- if (UNSET == btv->tuner_type)
- btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
- if (UNSET != tuner[btv->c.nr])
- btv->tuner_type = tuner[btv->c.nr];
-
- if (btv->tuner_type == TUNER_ABSENT)
- pr_info("%d: tuner absent\n", btv->c.nr);
- else if (btv->tuner_type == UNSET)
- pr_warn("%d: tuner type unset\n", btv->c.nr);
- else
- pr_info("%d: tuner type=%d\n", btv->c.nr, btv->tuner_type);
-
- if (autoload != UNSET) {
- pr_warn("%d: the autoload option is obsolete\n", btv->c.nr);
- pr_warn("%d: use option msp3400, tda7432 or tvaudio to override which audio module should be used\n",
- btv->c.nr);
- }
-
- if (UNSET == btv->tuner_type)
- btv->tuner_type = TUNER_ABSENT;
-
- btv->dig = bttv_tvcards[btv->c.type].has_dig_in ?
- bttv_tvcards[btv->c.type].video_inputs - 1 : UNSET;
- btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ?
- UNSET : bttv_tvcards[btv->c.type].svhs;
- if (svhs[btv->c.nr] != UNSET)
- btv->svhs = svhs[btv->c.nr];
- if (remote[btv->c.nr] != UNSET)
- btv->has_remote = remote[btv->c.nr];
-
- if (bttv_tvcards[btv->c.type].has_radio)
- btv->has_radio = 1;
- if (bttv_tvcards[btv->c.type].has_remote)
- btv->has_remote = 1;
- if (!bttv_tvcards[btv->c.type].no_gpioirq)
- btv->gpioirq = 1;
- if (bttv_tvcards[btv->c.type].volume_gpio)
- btv->volume_gpio = bttv_tvcards[btv->c.type].volume_gpio;
- if (bttv_tvcards[btv->c.type].audio_mode_gpio)
- btv->audio_mode_gpio = bttv_tvcards[btv->c.type].audio_mode_gpio;
-
- if (btv->tuner_type == TUNER_ABSENT)
- return; /* no tuner or related drivers to load */
-
- if (btv->has_saa6588 || saa6588[btv->c.nr]) {
- /* Probe for RDS receiver chip */
- static const unsigned short addrs[] = {
- 0x20 >> 1,
- 0x22 >> 1,
- I2C_CLIENT_END
- };
- struct v4l2_subdev *sd;
-
- sd = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, "saa6588", 0, addrs);
- btv->has_saa6588 = (sd != NULL);
- }
-
- /* try to detect audio/fader chips */
-
- /* First check if the user specified the audio chip via a module
- option. */
-
- switch (audiodev[btv->c.nr]) {
- case -1:
- return; /* do not load any audio module */
-
- case 0: /* autodetect */
- break;
-
- case 1: {
- /* The user specified that we should probe for msp3400 */
- static const unsigned short addrs[] = {
- I2C_ADDR_MSP3400 >> 1,
- I2C_ADDR_MSP3400_ALT >> 1,
- I2C_CLIENT_END
- };
-
- btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, "msp3400", 0, addrs);
- if (btv->sd_msp34xx)
- return;
- goto no_audio;
- }
-
- case 2: {
- /* The user specified that we should probe for tda7432 */
- static const unsigned short addrs[] = {
- I2C_ADDR_TDA7432 >> 1,
- I2C_CLIENT_END
- };
-
- if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, "tda7432", 0, addrs))
- return;
- goto no_audio;
- }
-
- case 3: {
- /* The user specified that we should probe for tvaudio */
- btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs());
- if (btv->sd_tvaudio)
- return;
- goto no_audio;
- }
-
- default:
- pr_warn("%d: unknown audiodev value!\n", btv->c.nr);
- return;
- }
-
- /* There were no overrides, so now we try to discover this through the
- card definition */
-
- /* probe for msp3400 first: this driver can detect whether or not
- it really is a msp3400, so it will return NULL when the device
- found is really something else (e.g. a tea6300). */
- if (!bttv_tvcards[btv->c.type].no_msp34xx) {
- btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, "msp3400",
- 0, I2C_ADDRS(I2C_ADDR_MSP3400 >> 1));
- } else if (bttv_tvcards[btv->c.type].msp34xx_alt) {
- btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, "msp3400",
- 0, I2C_ADDRS(I2C_ADDR_MSP3400_ALT >> 1));
- }
-
- /* If we found a msp34xx, then we're done. */
- if (btv->sd_msp34xx)
- return;
-
- /* it might also be a tda7432. */
- if (!bttv_tvcards[btv->c.type].no_tda7432) {
- static const unsigned short addrs[] = {
- I2C_ADDR_TDA7432 >> 1,
- I2C_CLIENT_END
- };
-
- if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, "tda7432", 0, addrs))
- return;
- }
-
- /* Now see if we can find one of the tvaudio devices. */
- btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs());
- if (btv->sd_tvaudio)
- return;
-
-no_audio:
- pr_warn("%d: audio absent, no audio device found!\n", btv->c.nr);
-}
-
-
-/* initialize the tuner */
-void __devinit bttv_init_tuner(struct bttv *btv)
-{
- int addr = ADDR_UNSET;
-
- if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
- addr = bttv_tvcards[btv->c.type].tuner_addr;
-
- if (btv->tuner_type != TUNER_ABSENT) {
- struct tuner_setup tun_setup;
-
- /* Load tuner module before issuing tuner config call! */
- if (btv->has_radio)
- v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, "tuner",
- 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
- v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, "tuner",
- 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
- v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, "tuner",
- 0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
-
- tun_setup.mode_mask = T_ANALOG_TV;
- tun_setup.type = btv->tuner_type;
- tun_setup.addr = addr;
-
- if (btv->has_radio)
- tun_setup.mode_mask |= T_RADIO;
-
- bttv_call_all(btv, tuner, s_type_addr, &tun_setup);
- }
-
- if (btv->tda9887_conf) {
- struct v4l2_priv_tun_config tda9887_cfg;
-
- tda9887_cfg.tuner = TUNER_TDA9887;
- tda9887_cfg.priv = &btv->tda9887_conf;
-
- bttv_call_all(btv, tuner, s_config, &tda9887_cfg);
- }
-}
-
-/* ----------------------------------------------------------------------- */
-
-static void modtec_eeprom(struct bttv *btv)
-{
- if( strncmp(&(eeprom_data[0x1e]),"Temic 4066 FY5",14) ==0) {
- btv->tuner_type=TUNER_TEMIC_4066FY5_PAL_I;
- pr_info("%d: Modtec: Tuner autodetected by eeprom: %s\n",
- btv->c.nr, &eeprom_data[0x1e]);
- } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) {
- btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I;
- pr_info("%d: Modtec: Tuner autodetected by eeprom: %s\n",
- btv->c.nr, &eeprom_data[0x1e]);
- } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) {
- btv->tuner_type=TUNER_PHILIPS_NTSC;
- pr_info("%d: Modtec: Tuner autodetected by eeprom: %s\n",
- btv->c.nr, &eeprom_data[0x1e]);
- } else {
- pr_info("%d: Modtec: Unknown TunerString: %s\n",
- btv->c.nr, &eeprom_data[0x1e]);
- }
-}
-
-static void __devinit hauppauge_eeprom(struct bttv *btv)
-{
- struct tveeprom tv;
-
- tveeprom_hauppauge_analog(&btv->i2c_client, &tv, eeprom_data);
- btv->tuner_type = tv.tuner_type;
- btv->has_radio = tv.has_radio;
-
- pr_info("%d: Hauppauge eeprom indicates model#%d\n",
- btv->c.nr, tv.model);
-
- /*
- * Some of the 878 boards have duplicate PCI IDs. Switch the board
- * type based on model #.
- */
- if(tv.model == 64900) {
- pr_info("%d: Switching board type from %s to %s\n",
- btv->c.nr,
- bttv_tvcards[btv->c.type].name,
- bttv_tvcards[BTTV_BOARD_HAUPPAUGE_IMPACTVCB].name);
- btv->c.type = BTTV_BOARD_HAUPPAUGE_IMPACTVCB;
- }
-
- /* The 61334 needs the msp3410 to do the radio demod to get sound */
- if (tv.model == 61334)
- btv->radio_uses_msp_demodulator = 1;
-}
-
-static int terratec_active_radio_upgrade(struct bttv *btv)
-{
- int freq;
-
- btv->has_radio = 1;
- btv->has_matchbox = 1;
- btv->mbox_we = 0x10;
- btv->mbox_most = 0x20;
- btv->mbox_clk = 0x08;
- btv->mbox_data = 0x04;
- btv->mbox_mask = 0x3c;
-
- btv->mbox_iow = 1 << 8;
- btv->mbox_ior = 1 << 9;
- btv->mbox_csel = 1 << 10;
-
- freq=88000/62.5;
- tea5757_write(btv, 5 * freq + 0x358); /* write 0x1ed8 */
- if (0x1ed8 == tea5757_read(btv)) {
- pr_info("%d: Terratec Active Radio Upgrade found\n", btv->c.nr);
- btv->has_radio = 1;
- btv->has_saa6588 = 1;
- btv->has_matchbox = 1;
- } else {
- btv->has_radio = 0;
- btv->has_matchbox = 0;
- }
- return 0;
-}
-
-
-/* ----------------------------------------------------------------------- */
-
-/*
- * minimal bootstrap for the WinTV/PVR -- upload altera firmware.
- *
- * The hcwamc.rbf firmware file is on the Hauppauge driver CD. Have
- * a look at Pvr/pvr45xxx.EXE (self-extracting zip archive, can be
- * unpacked with unzip).
- */
-#define PVR_GPIO_DELAY 10
-
-#define BTTV_ALT_DATA 0x000001
-#define BTTV_ALT_DCLK 0x100000
-#define BTTV_ALT_NCONFIG 0x800000
-
-static int __devinit pvr_altera_load(struct bttv *btv, const u8 *micro,
- u32 microlen)
-{
- u32 n;
- u8 bits;
- int i;
-
- gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG);
- gpio_write(0);
- udelay(PVR_GPIO_DELAY);
-
- gpio_write(BTTV_ALT_NCONFIG);
- udelay(PVR_GPIO_DELAY);
-
- for (n = 0; n < microlen; n++) {
- bits = micro[n];
- for (i = 0 ; i < 8 ; i++) {
- gpio_bits(BTTV_ALT_DCLK,0);
- if (bits & 0x01)
- gpio_bits(BTTV_ALT_DATA,BTTV_ALT_DATA);
- else
- gpio_bits(BTTV_ALT_DATA,0);
- gpio_bits(BTTV_ALT_DCLK,BTTV_ALT_DCLK);
- bits >>= 1;
- }
- }
- gpio_bits(BTTV_ALT_DCLK,0);
- udelay(PVR_GPIO_DELAY);
-
- /* begin Altera init loop (Not necessary,but doesn't hurt) */
- for (i = 0 ; i < 30 ; i++) {
- gpio_bits(BTTV_ALT_DCLK,0);
- gpio_bits(BTTV_ALT_DCLK,BTTV_ALT_DCLK);
- }
- gpio_bits(BTTV_ALT_DCLK,0);
- return 0;
-}
-
-static int __devinit pvr_boot(struct bttv *btv)
-{
- const struct firmware *fw_entry;
- int rc;
-
- rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev);
- if (rc != 0) {
- pr_warn("%d: no altera firmware [via hotplug]\n", btv->c.nr);
- return rc;
- }
- rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size);
- pr_info("%d: altera firmware upload %s\n",
- btv->c.nr, (rc < 0) ? "failed" : "ok");
- release_firmware(fw_entry);
- return rc;
-}
-
-/* ----------------------------------------------------------------------- */
-/* some osprey specific stuff */
-
-static void __devinit osprey_eeprom(struct bttv *btv, const u8 ee[256])
-{
- int i;
- u32 serial = 0;
- int cardid = -1;
-
- /* This code will nevery actually get called in this case.... */
- if (btv->c.type == BTTV_BOARD_UNKNOWN) {
- /* this might be an antique... check for MMAC label in eeprom */
- if (!strncmp(ee, "MMAC", 4)) {
- u8 checksum = 0;
- for (i = 0; i < 21; i++)
- checksum += ee[i];
- if (checksum != ee[21])
- return;
- cardid = BTTV_BOARD_OSPREY1x0_848;
- for (i = 12; i < 21; i++)
- serial *= 10, serial += ee[i] - '0';
- }
- } else {
- unsigned short type;
-
- for (i = 4*16; i < 8*16; i += 16) {
- u16 checksum = ip_compute_csum(ee + i, 16);
-
- if ((checksum&0xff) + (checksum>>8) == 0xff)
- break;
- }
- if (i >= 8*16)
- return;
- ee += i;
-
- /* found a valid descriptor */
- type = get_unaligned_be16((__be16 *)(ee+4));
-
- switch(type) {
- /* 848 based */
- case 0x0004:
- cardid = BTTV_BOARD_OSPREY1x0_848;
- break;
- case 0x0005:
- cardid = BTTV_BOARD_OSPREY101_848;
- break;
-
- /* 878 based */
- case 0x0012:
- case 0x0013:
- cardid = BTTV_BOARD_OSPREY1x0;
- break;
- case 0x0014:
- case 0x0015:
- cardid = BTTV_BOARD_OSPREY1x1;
- break;
- case 0x0016:
- case 0x0017:
- case 0x0020:
- cardid = BTTV_BOARD_OSPREY1x1_SVID;
- break;
- case 0x0018:
- case 0x0019:
- case 0x001E:
- case 0x001F:
- cardid = BTTV_BOARD_OSPREY2xx;
- break;
- case 0x001A:
- case 0x001B:
- cardid = BTTV_BOARD_OSPREY2x0_SVID;
- break;
- case 0x0040:
- cardid = BTTV_BOARD_OSPREY500;
- break;
- case 0x0050:
- case 0x0056:
- cardid = BTTV_BOARD_OSPREY540;
- /* bttv_osprey_540_init(btv); */
- break;
- case 0x0060:
- case 0x0070:
- case 0x00A0:
- cardid = BTTV_BOARD_OSPREY2x0;
- /* enable output on select control lines */
- gpio_inout(0xffffff,0x000303);
- break;
- case 0x00D8:
- cardid = BTTV_BOARD_OSPREY440;
- break;
- default:
- /* unknown...leave generic, but get serial # */
- pr_info("%d: osprey eeprom: unknown card type 0x%04x\n",
- btv->c.nr, type);
- break;
- }
- serial = get_unaligned_be32((__be32 *)(ee+6));
- }
-
- pr_info("%d: osprey eeprom: card=%d '%s' serial=%u\n",
- btv->c.nr, cardid,
- cardid > 0 ? bttv_tvcards[cardid].name : "Unknown", serial);
-
- if (cardid<0 || btv->c.type == cardid)
- return;
-
- /* card type isn't set correctly */
- if (card[btv->c.nr] < bttv_num_tvcards) {
- pr_warn("%d: osprey eeprom: Not overriding user specified card type\n",
- btv->c.nr);
- } else {
- pr_info("%d: osprey eeprom: Changing card type from %d to %d\n",
- btv->c.nr, btv->c.type, cardid);
- btv->c.type = cardid;
- }
-}
-
-/* ----------------------------------------------------------------------- */
-/* AVermedia specific stuff, from bktr_card.c */
-
-static int tuner_0_table[] = {
- TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/,
- TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/,
- TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL,
- TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
- TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL,
- TUNER_PHILIPS_FM1216ME_MK3 };
-
-static int tuner_1_table[] = {
- TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL,
- TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
- TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
- TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */
- TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};
-
-static void __devinit avermedia_eeprom(struct bttv *btv)
-{
- int tuner_make, tuner_tv_fm, tuner_format, tuner_type = 0;
-
- tuner_make = (eeprom_data[0x41] & 0x7);
- tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3;
- tuner_format = (eeprom_data[0x42] & 0xf0) >> 4;
- btv->has_remote = (eeprom_data[0x42] & 0x01);
-
- if (tuner_make == 0 || tuner_make == 2)
- if (tuner_format <= 0x0a)
- tuner_type = tuner_0_table[tuner_format];
- if (tuner_make == 1)
- if (tuner_format <= 9)
- tuner_type = tuner_1_table[tuner_format];
-
- if (tuner_make == 4)
- if (tuner_format == 0x09)
- tuner_type = TUNER_LG_NTSC_NEW_TAPC; /* TAPC-G702P */
-
- pr_info("%d: Avermedia eeprom[0x%02x%02x]: tuner=",
- btv->c.nr, eeprom_data[0x41], eeprom_data[0x42]);
- if (tuner_type) {
- btv->tuner_type = tuner_type;
- pr_cont("%d", tuner_type);
- } else
- pr_cont("Unknown type");
- pr_cont(" radio:%s remote control:%s\n",
- tuner_tv_fm ? "yes" : "no",
- btv->has_remote ? "yes" : "no");
-}
-
-/*
- * For Voodoo TV/FM and Voodoo 200. These cards' tuners use a TDA9880
- * analog demod, which is not I2C controlled like the newer and more common
- * TDA9887 series. Instead is has two tri-state input pins, S0 and S1,
- * that control the IF for the video and audio. Apparently, bttv GPIO
- * 0x10000 is connected to S0. S0 low selects a 38.9 MHz VIF for B/G/D/K/I
- * (i.e., PAL) while high selects 45.75 MHz for M/N (i.e., NTSC).
- */
-u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits)
-{
-
- if (btv->audio == TVAUDIO_INPUT_TUNER) {
- if (bttv_tvnorms[btv->tvnorm].v4l2_id & V4L2_STD_MN)
- gpiobits |= 0x10000;
- else
- gpiobits &= ~0x10000;
- }
-
- gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpiobits);
- return gpiobits;
-}
-
-
-/*
- * reset/enable the MSP on some Hauppauge cards
- * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)!
- *
- * Hauppauge: pin 5
- * Voodoo: pin 20
- */
-static void __devinit boot_msp34xx(struct bttv *btv, int pin)
-{
- int mask = (1 << pin);
-
- gpio_inout(mask,mask);
- gpio_bits(mask,0);
- mdelay(2);
- udelay(500);
- gpio_bits(mask,mask);
-
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"msp34xx");
- if (bttv_verbose)
- pr_info("%d: Hauppauge/Voodoo msp34xx: reset line init [%d]\n",
- btv->c.nr, pin);
-}
-
-/* ----------------------------------------------------------------------- */
-/* Imagenation L-Model PXC200 Framegrabber */
-/* This is basically the same procedure as
- * used by Alessandro Rubini in his pxc200
- * driver, but using BTTV functions */
-
-static void __devinit init_PXC200(struct bttv *btv)
-{
- static int vals[] __devinitdata = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d,
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
- 0x00 };
- unsigned int i;
- int tmp;
- u32 val;
-
- /* Initialise GPIO-connevted stuff */
- gpio_inout(0xffffff, (1<<13));
- gpio_write(0);
- udelay(3);
- gpio_write(1<<13);
- /* GPIO inputs are pulled up, so no need to drive
- * reset pin any longer */
- gpio_bits(0xffffff, 0);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"pxc200");
-
- /* we could/should try and reset/control the AD pots? but
- right now we simply turned off the crushing. Without
- this the AGC drifts drifts
- remember the EN is reverse logic -->
- setting BT848_ADC_AGC_EN disable the AGC
- tboult@eecs.lehigh.edu
- */
-
- btwrite(BT848_ADC_RESERVED|BT848_ADC_AGC_EN, BT848_ADC);
-
- /* Initialise MAX517 DAC */
- pr_info("Setting DAC reference voltage level ...\n");
- bttv_I2CWrite(btv,0x5E,0,0x80,1);
-
- /* Initialise 12C508 PIC */
- /* The I2CWrite and I2CRead commmands are actually to the
- * same chips - but the R/W bit is included in the address
- * argument so the numbers are different */
-
-
- pr_info("Initialising 12C508 PIC chip ...\n");
-
- /* First of all, enable the clock line. This is used in the PXC200-F */
- val = btread(BT848_GPIO_DMA_CTL);
- val |= BT848_GPIO_DMA_CTL_GPCLKMODE;
- btwrite(val, BT848_GPIO_DMA_CTL);
-
- /* Then, push to 0 the reset pin long enough to reset the *
- * device same as above for the reset line, but not the same
- * value sent to the GPIO-connected stuff
- * which one is the good one? */
- gpio_inout(0xffffff,(1<<2));
- gpio_write(0);
- udelay(10);
- gpio_write(1<<2);
-
- for (i = 0; i < ARRAY_SIZE(vals); i++) {
- tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1);
- if (tmp != -1) {
- pr_info("I2C Write(%2.2x) = %i\nI2C Read () = %2.2x\n\n",
- vals[i],tmp,bttv_I2CRead(btv,0x1F,NULL));
- }
- }
-
- pr_info("PXC200 Initialised\n");
-}
-
-
-
-/* ----------------------------------------------------------------------- */
-/*
- * The Adlink RTV-24 (aka Angelo) has some special initialisation to unlock
- * it. This apparently involves the following procedure for each 878 chip:
- *
- * 1) write 0x00C3FEFF to the GPIO_OUT_EN register
- *
- * 2) write to GPIO_DATA
- * - 0x0E
- * - sleep 1ms
- * - 0x10 + 0x0E
- * - sleep 10ms
- * - 0x0E
- * read from GPIO_DATA into buf (uint_32)
- * - if ( data>>18 & 0x01 != 0) || ( buf>>19 & 0x01 != 1 )
- * error. ERROR_CPLD_Check_Failed stop.
- *
- * 3) write to GPIO_DATA
- * - write 0x4400 + 0x0E
- * - sleep 10ms
- * - write 0x4410 + 0x0E
- * - sleep 1ms
- * - write 0x0E
- * read from GPIO_DATA into buf (uint_32)
- * - if ( buf>>18 & 0x01 ) || ( buf>>19 & 0x01 != 0 )
- * error. ERROR_CPLD_Check_Failed.
- */
-/* ----------------------------------------------------------------------- */
-static void
-init_RTV24 (struct bttv *btv)
-{
- uint32_t dataRead = 0;
- long watchdog_value = 0x0E;
-
- pr_info("%d: Adlink RTV-24 initialisation in progress ...\n",
- btv->c.nr);
-
- btwrite (0x00c3feff, BT848_GPIO_OUT_EN);
-
- btwrite (0 + watchdog_value, BT848_GPIO_DATA);
- msleep (1);
- btwrite (0x10 + watchdog_value, BT848_GPIO_DATA);
- msleep (10);
- btwrite (0 + watchdog_value, BT848_GPIO_DATA);
-
- dataRead = btread (BT848_GPIO_DATA);
-
- if ((((dataRead >> 18) & 0x01) != 0) || (((dataRead >> 19) & 0x01) != 1)) {
- pr_info("%d: Adlink RTV-24 initialisation(1) ERROR_CPLD_Check_Failed (read %d)\n",
- btv->c.nr, dataRead);
- }
-
- btwrite (0x4400 + watchdog_value, BT848_GPIO_DATA);
- msleep (10);
- btwrite (0x4410 + watchdog_value, BT848_GPIO_DATA);
- msleep (1);
- btwrite (watchdog_value, BT848_GPIO_DATA);
- msleep (1);
- dataRead = btread (BT848_GPIO_DATA);
-
- if ((((dataRead >> 18) & 0x01) != 0) || (((dataRead >> 19) & 0x01) != 0)) {
- pr_info("%d: Adlink RTV-24 initialisation(2) ERROR_CPLD_Check_Failed (read %d)\n",
- btv->c.nr, dataRead);
-
- return;
- }
-
- pr_info("%d: Adlink RTV-24 initialisation complete\n", btv->c.nr);
-}
-
-
-
-/* ----------------------------------------------------------------------- */
-/* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */
-/*
- * Copyright (c) 1999 Csaba Halasz <qgehali@uni-miskolc.hu>
- * This code is placed under the terms of the GNU General Public License
- *
- * Brutally hacked by Dan Sheridan <dan.sheridan@contact.org.uk> djs52 8/3/00
- */
-
-static void bus_low(struct bttv *btv, int bit)
-{
- if (btv->mbox_ior) {
- gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
- btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
- udelay(5);
- }
-
- gpio_bits(bit,0);
- udelay(5);
-
- if (btv->mbox_ior) {
- gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
- udelay(5);
- }
-}
-
-static void bus_high(struct bttv *btv, int bit)
-{
- if (btv->mbox_ior) {
- gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
- btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
- udelay(5);
- }
-
- gpio_bits(bit,bit);
- udelay(5);
-
- if (btv->mbox_ior) {
- gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
- udelay(5);
- }
-}
-
-static int bus_in(struct bttv *btv, int bit)
-{
- if (btv->mbox_ior) {
- gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
- btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
- udelay(5);
-
- gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
- udelay(5);
- }
- return gpio_read() & (bit);
-}
-
-/* TEA5757 register bits */
-#define TEA_FREQ 0:14
-#define TEA_BUFFER 15:15
-
-#define TEA_SIGNAL_STRENGTH 16:17
-
-#define TEA_PORT1 18:18
-#define TEA_PORT0 19:19
-
-#define TEA_BAND 20:21
-#define TEA_BAND_FM 0
-#define TEA_BAND_MW 1
-#define TEA_BAND_LW 2
-#define TEA_BAND_SW 3
-
-#define TEA_MONO 22:22
-#define TEA_ALLOW_STEREO 0
-#define TEA_FORCE_MONO 1
-
-#define TEA_SEARCH_DIRECTION 23:23
-#define TEA_SEARCH_DOWN 0
-#define TEA_SEARCH_UP 1
-
-#define TEA_STATUS 24:24
-#define TEA_STATUS_TUNED 0
-#define TEA_STATUS_SEARCHING 1
-
-/* Low-level stuff */
-static int tea5757_read(struct bttv *btv)
-{
- unsigned long timeout;
- int value = 0;
- int i;
-
- /* better safe than sorry */
- gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we);
-
- if (btv->mbox_ior) {
- gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
- btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
- udelay(5);
- }
-
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"tea5757 read");
-
- bus_low(btv,btv->mbox_we);
- bus_low(btv,btv->mbox_clk);
-
- udelay(10);
- timeout= jiffies + msecs_to_jiffies(1000);
-
- /* wait for DATA line to go low; error if it doesn't */
- while (bus_in(btv,btv->mbox_data) && time_before(jiffies, timeout))
- schedule();
- if (bus_in(btv,btv->mbox_data)) {
- pr_warn("%d: tea5757: read timeout\n", btv->c.nr);
- return -1;
- }
-
- dprintk("%d: tea5757:", btv->c.nr);
- for (i = 0; i < 24; i++) {
- udelay(5);
- bus_high(btv,btv->mbox_clk);
- udelay(5);
- dprintk_cont("%c",
- bus_in(btv, btv->mbox_most) == 0 ? 'T' : '-');
- bus_low(btv,btv->mbox_clk);
- value <<= 1;
- value |= (bus_in(btv,btv->mbox_data) == 0)?0:1; /* MSB first */
- dprintk_cont("%c",
- bus_in(btv, btv->mbox_most) == 0 ? 'S' : 'M');
- }
- dprintk_cont("\n");
- dprintk("%d: tea5757: read 0x%X\n", btv->c.nr, value);
- return value;
-}
-
-static int tea5757_write(struct bttv *btv, int value)
-{
- int i;
- int reg = value;
-
- gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we | btv->mbox_data);
-
- if (btv->mbox_ior) {
- gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
- btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
- udelay(5);
- }
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"tea5757 write");
-
- dprintk("%d: tea5757: write 0x%X\n", btv->c.nr, value);
- bus_low(btv,btv->mbox_clk);
- bus_high(btv,btv->mbox_we);
- for (i = 0; i < 25; i++) {
- if (reg & 0x1000000)
- bus_high(btv,btv->mbox_data);
- else
- bus_low(btv,btv->mbox_data);
- reg <<= 1;
- bus_high(btv,btv->mbox_clk);
- udelay(10);
- bus_low(btv,btv->mbox_clk);
- udelay(10);
- }
- bus_low(btv,btv->mbox_we); /* unmute !!! */
- return 0;
-}
-
-void tea5757_set_freq(struct bttv *btv, unsigned short freq)
-{
- dprintk("tea5757_set_freq %d\n",freq);
- tea5757_write(btv, 5 * freq + 0x358); /* add 10.7MHz (see docs) */
-}
-
-/* RemoteVision MX (rv605) muxsel helper [Miguel Freitas]
- *
- * This is needed because rv605 don't use a normal multiplex, but a crosspoint
- * switch instead (CD22M3494E). This IC can have multiple active connections
- * between Xn (input) and Yn (output) pins. We need to clear any existing
- * connection prior to establish a new one, pulsing the STROBE pin.
- *
- * The board hardwire Y0 (xpoint) to MUX1 and MUXOUT to Yin.
- * GPIO pins are wired as:
- * GPIO[0:3] - AX[0:3] (xpoint) - P1[0:3] (microcontroller)
- * GPIO[4:6] - AY[0:2] (xpoint) - P1[4:6] (microcontroller)
- * GPIO[7] - DATA (xpoint) - P1[7] (microcontroller)
- * GPIO[8] - - P3[5] (microcontroller)
- * GPIO[9] - RESET (xpoint) - P3[6] (microcontroller)
- * GPIO[10] - STROBE (xpoint) - P3[7] (microcontroller)
- * GPINTR - - P3[4] (microcontroller)
- *
- * The microcontroller is a 80C32 like. It should be possible to change xpoint
- * configuration either directly (as we are doing) or using the microcontroller
- * which is also wired to I2C interface. I have no further info on the
- * microcontroller features, one would need to disassembly the firmware.
- * note: the vendor refused to give any information on this product, all
- * that stuff was found using a multimeter! :)
- */
-static void rv605_muxsel(struct bttv *btv, unsigned int input)
-{
- static const u8 muxgpio[] = { 0x3, 0x1, 0x2, 0x4, 0xf, 0x7, 0xe, 0x0,
- 0xd, 0xb, 0xc, 0x6, 0x9, 0x5, 0x8, 0xa };
-
- gpio_bits(0x07f, muxgpio[input]);
-
- /* reset all conections */
- gpio_bits(0x200,0x200);
- mdelay(1);
- gpio_bits(0x200,0x000);
- mdelay(1);
-
- /* create a new connection */
- gpio_bits(0x480,0x480);
- mdelay(1);
- gpio_bits(0x480,0x080);
- mdelay(1);
-}
-
-/* Tibet Systems 'Progress DVR' CS16 muxsel helper [Chris Fanning]
- *
- * The CS16 (available on eBay cheap) is a PCI board with four Fusion
- * 878A chips, a PCI bridge, an Atmel microcontroller, four sync separator
- * chips, ten eight input analog multiplexors, a not chip and a few
- * other components.
- *
- * 16 inputs on a secondary bracket are provided and can be selected
- * from each of the four capture chips. Two of the eight input
- * multiplexors are used to select from any of the 16 input signals.
- *
- * Unsupported hardware capabilities:
- * . A video output monitor on the secondary bracket can be selected from
- * one of the 878A chips.
- * . Another passthrough but I haven't spent any time investigating it.
- * . Digital I/O (logic level connected to GPIO) is available from an
- * onboard header.
- *
- * The on chip input mux should always be set to 2.
- * GPIO[16:19] - Video input selection
- * GPIO[0:3] - Video output monitor select (only available from one 878A)
- * GPIO[?:?] - Digital I/O.
- *
- * There is an ATMEL microcontroller with an 8031 core on board. I have not
- * determined what function (if any) it provides. With the microcontroller
- * and sync separator chips a guess is that it might have to do with video
- * switching and maybe some digital I/O.
- */
-static void tibetCS16_muxsel(struct bttv *btv, unsigned int input)
-{
- /* video mux */
- gpio_bits(0x0f0000, input << 16);
-}
-
-static void tibetCS16_init(struct bttv *btv)
-{
- /* enable gpio bits, mask obtained via btSpy */
- gpio_inout(0xffffff, 0x0f7fff);
- gpio_write(0x0f7fff);
-}
-
-/*
- * The following routines for the Kodicom-4400r get a little mind-twisting.
- * There is a "master" controller and three "slave" controllers, together
- * an analog switch which connects any of 16 cameras to any of the BT87A's.
- * The analog switch is controlled by the "master", but the detection order
- * of the four BT878A chips is in an order which I just don't understand.
- * The "master" is actually the second controller to be detected. The
- * logic on the board uses logical numbers for the 4 controllers, but
- * those numbers are different from the detection sequence. When working
- * with the analog switch, we need to "map" from the detection sequence
- * over to the board's logical controller number. This mapping sequence
- * is {3, 0, 2, 1}, i.e. the first controller to be detected is logical
- * unit 3, the second (which is the master) is logical unit 0, etc.
- * We need to maintain the status of the analog switch (which of the 16
- * cameras is connected to which of the 4 controllers). Rather than
- * add to the bttv structure for this, we use the data reserved for
- * the mbox (unused for this card type).
- */
-
-/*
- * First a routine to set the analog switch, which controls which camera
- * is routed to which controller. The switch comprises an X-address
- * (gpio bits 0-3, representing the camera, ranging from 0-15), and a
- * Y-address (gpio bits 4-6, representing the controller, ranging from 0-3).
- * A data value (gpio bit 7) of '1' enables the switch, and '0' disables
- * the switch. A STROBE bit (gpio bit 8) latches the data value into the
- * specified address. The idea is to set the address and data, then bring
- * STROBE high, and finally bring STROBE back to low.
- */
-static void kodicom4400r_write(struct bttv *btv,
- unsigned char xaddr,
- unsigned char yaddr,
- unsigned char data) {
- unsigned int udata;
-
- udata = (data << 7) | ((yaddr&3) << 4) | (xaddr&0xf);
- gpio_bits(0x1ff, udata); /* write ADDR and DAT */
- gpio_bits(0x1ff, udata | (1 << 8)); /* strobe high */
- gpio_bits(0x1ff, udata); /* strobe low */
-}
-
-/*
- * Next the mux select. Both the "master" and "slave" 'cards' (controllers)
- * use this routine. The routine finds the "master" for the card, maps
- * the controller number from the detected position over to the logical
- * number, writes the appropriate data to the analog switch, and housekeeps
- * the local copy of the switch information. The parameter 'input' is the
- * requested camera number (0 - 15).
- */
-static void kodicom4400r_muxsel(struct bttv *btv, unsigned int input)
-{
- char *sw_status;
- int xaddr, yaddr;
- struct bttv *mctlr;
- static unsigned char map[4] = {3, 0, 2, 1};
-
- mctlr = master[btv->c.nr];
- if (mctlr == NULL) { /* ignore if master not yet detected */
- return;
- }
- yaddr = (btv->c.nr - mctlr->c.nr + 1) & 3; /* the '&' is for safety */
- yaddr = map[yaddr];
- sw_status = (char *)(&mctlr->mbox_we);
- xaddr = input & 0xf;
- /* Check if the controller/camera pair has changed, else ignore */
- if (sw_status[yaddr] != xaddr)
- {
- /* "open" the old switch, "close" the new one, save the new */
- kodicom4400r_write(mctlr, sw_status[yaddr], yaddr, 0);
- sw_status[yaddr] = xaddr;
- kodicom4400r_write(mctlr, xaddr, yaddr, 1);
- }
-}
-
-/*
- * During initialisation, we need to reset the analog switch. We
- * also preset the switch to map the 4 connectors on the card to the
- * *user's* (see above description of kodicom4400r_muxsel) channels
- * 0 through 3
- */
-static void kodicom4400r_init(struct bttv *btv)
-{
- char *sw_status = (char *)(&btv->mbox_we);
- int ix;
-
- gpio_inout(0x0003ff, 0x0003ff);
- gpio_write(1 << 9); /* reset MUX */
- gpio_write(0);
- /* Preset camera 0 to the 4 controllers */
- for (ix = 0; ix < 4; ix++) {
- sw_status[ix] = ix;
- kodicom4400r_write(btv, ix, ix, 1);
- }
- /*
- * Since this is the "master", we need to set up the
- * other three controller chips' pointers to this structure
- * for later use in the muxsel routine.
- */
- if ((btv->c.nr<1) || (btv->c.nr>BTTV_MAX-3))
- return;
- master[btv->c.nr-1] = btv;
- master[btv->c.nr] = btv;
- master[btv->c.nr+1] = btv;
- master[btv->c.nr+2] = btv;
-}
-
-/* The Grandtec X-Guard framegrabber card uses two Dual 4-channel
- * video multiplexers to provide up to 16 video inputs. These
- * multiplexers are controlled by the lower 8 GPIO pins of the
- * bt878. The multiplexers probably Pericom PI5V331Q or similar.
-
- * xxx0 is pin xxx of multiplexer U5,
- * yyy1 is pin yyy of multiplexer U2
- */
-#define ENA0 0x01
-#define ENB0 0x02
-#define ENA1 0x04
-#define ENB1 0x08
-
-#define IN10 0x10
-#define IN00 0x20
-#define IN11 0x40
-#define IN01 0x80
-
-static void xguard_muxsel(struct bttv *btv, unsigned int input)
-{
- static const int masks[] = {
- ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10,
- ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10,
- ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11,
- ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11,
- };
- gpio_write(masks[input%16]);
-}
-static void picolo_tetra_init(struct bttv *btv)
-{
- /*This is the video input redirection fonctionality : I DID NOT USED IT. */
- btwrite (0x08<<16,BT848_GPIO_DATA);/*GPIO[19] [==> 4053 B+C] set to 1 */
- btwrite (0x04<<16,BT848_GPIO_DATA);/*GPIO[18] [==> 4053 A] set to 1*/
-}
-static void picolo_tetra_muxsel (struct bttv* btv, unsigned int input)
-{
-
- dprintk("%d : picolo_tetra_muxsel => input = %d\n", btv->c.nr, input);
- /*Just set the right path in the analog multiplexers : channel 1 -> 4 ==> Analog Mux ==> MUX0*/
- /*GPIO[20]&GPIO[21] used to choose the right input*/
- btwrite (input<<20,BT848_GPIO_DATA);
-
-}
-
-/*
- * ivc120_muxsel [Added by Alan Garfield <alan@fromorbit.com>]
- *
- * The IVC120G security card has 4 i2c controlled TDA8540 matrix
- * swichers to provide 16 channels to MUX0. The TDA8540's have
- * 4 independent outputs and as such the IVC120G also has the
- * optional "Monitor Out" bus. This allows the card to be looking
- * at one input while the monitor is looking at another.
- *
- * Since I've couldn't be bothered figuring out how to add an
- * independent muxsel for the monitor bus, I've just set it to
- * whatever the card is looking at.
- *
- * OUT0 of the TDA8540's is connected to MUX0 (0x03)
- * OUT1 of the TDA8540's is connected to "Monitor Out" (0x0C)
- *
- * TDA8540_ALT3 IN0-3 = Channel 13 - 16 (0x03)
- * TDA8540_ALT4 IN0-3 = Channel 1 - 4 (0x03)
- * TDA8540_ALT5 IN0-3 = Channel 5 - 8 (0x03)
- * TDA8540_ALT6 IN0-3 = Channel 9 - 12 (0x03)
- *
- */
-
-/* All 7 possible sub-ids for the TDA8540 Matrix Switcher */
-#define I2C_TDA8540 0x90
-#define I2C_TDA8540_ALT1 0x92
-#define I2C_TDA8540_ALT2 0x94
-#define I2C_TDA8540_ALT3 0x96
-#define I2C_TDA8540_ALT4 0x98
-#define I2C_TDA8540_ALT5 0x9a
-#define I2C_TDA8540_ALT6 0x9c
-
-static void ivc120_muxsel(struct bttv *btv, unsigned int input)
-{
- /* Simple maths */
- int key = input % 4;
- int matrix = input / 4;
-
- dprintk("%d: ivc120_muxsel: Input - %02d | TDA - %02d | In - %02d\n",
- btv->c.nr, input, matrix, key);
-
- /* Handles the input selection on the TDA8540's */
- bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x00,
- ((matrix == 3) ? (key | key << 2) : 0x00), 1);
- bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x00,
- ((matrix == 0) ? (key | key << 2) : 0x00), 1);
- bttv_I2CWrite(btv, I2C_TDA8540_ALT5, 0x00,
- ((matrix == 1) ? (key | key << 2) : 0x00), 1);
- bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x00,
- ((matrix == 2) ? (key | key << 2) : 0x00), 1);
-
- /* Handles the output enables on the TDA8540's */
- bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x02,
- ((matrix == 3) ? 0x03 : 0x00), 1); /* 13 - 16 */
- bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x02,
- ((matrix == 0) ? 0x03 : 0x00), 1); /* 1-4 */
- bttv_I2CWrite(btv, I2C_TDA8540_ALT5, 0x02,
- ((matrix == 1) ? 0x03 : 0x00), 1); /* 5-8 */
- bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02,
- ((matrix == 2) ? 0x03 : 0x00), 1); /* 9-12 */
-
- /* 878's MUX0 is already selected for input via muxsel values */
-}
-
-
-/* PXC200 muxsel helper
- * luke@syseng.anu.edu.au
- * another transplant
- * from Alessandro Rubini (rubini@linux.it)
- *
- * There are 4 kinds of cards:
- * PXC200L which is bt848
- * PXC200F which is bt848 with PIC controlling mux
- * PXC200AL which is bt878
- * PXC200AF which is bt878 with PIC controlling mux
- */
-#define PX_CFG_PXC200F 0x01
-#define PX_FLAG_PXC200A 0x00001000 /* a pxc200A is bt-878 based */
-#define PX_I2C_PIC 0x0f
-#define PX_PXC200A_CARDID 0x200a1295
-#define PX_I2C_CMD_CFG 0x00
-
-static void PXC200_muxsel(struct bttv *btv, unsigned int input)
-{
- int rc;
- long mux;
- int bitmask;
- unsigned char buf[2];
-
- /* Read PIC config to determine if this is a PXC200F */
- /* PX_I2C_CMD_CFG*/
- buf[0]=0;
- buf[1]=0;
- rc=bttv_I2CWrite(btv,(PX_I2C_PIC<<1),buf[0],buf[1],1);
- if (rc) {
- pr_debug("%d: PXC200_muxsel: pic cfg write failed:%d\n",
- btv->c.nr, rc);
- /* not PXC ? do nothing */
- return;
- }
-
- rc=bttv_I2CRead(btv,(PX_I2C_PIC<<1),NULL);
- if (!(rc & PX_CFG_PXC200F)) {
- pr_debug("%d: PXC200_muxsel: not PXC200F rc:%d\n",
- btv->c.nr, rc);
- return;
- }
-
-
- /* The multiplexer in the 200F is handled by the GPIO port */
- /* get correct mapping between inputs */
- /* mux = bttv_tvcards[btv->type].muxsel[input] & 3; */
- /* ** not needed!? */
- mux = input;
-
- /* make sure output pins are enabled */
- /* bitmask=0x30f; */
- bitmask=0x302;
- /* check whether we have a PXC200A */
- if (btv->cardid == PX_PXC200A_CARDID) {
- bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */
- bitmask |= 7<<4; /* the DAC */
- }
- btwrite(bitmask, BT848_GPIO_OUT_EN);
-
- bitmask = btread(BT848_GPIO_DATA);
- if (btv->cardid == PX_PXC200A_CARDID)
- bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7);
- else /* older device */
- bitmask = (bitmask & ~0x300) | ((mux & 3) << 8);
- btwrite(bitmask,BT848_GPIO_DATA);
-
- /*
- * Was "to be safe, set the bt848 to input 0"
- * Actually, since it's ok at load time, better not messing
- * with these bits (on PXC200AF you need to set mux 2 here)
- *
- * needed because bttv-driver sets mux before calling this function
- */
- if (btv->cardid == PX_PXC200A_CARDID)
- btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM);
- else /* older device */
- btand(~BT848_IFORM_MUXSEL,BT848_IFORM);
-
- pr_debug("%d: setting input channel to:%d\n", btv->c.nr, (int)mux);
-}
-
-static void phytec_muxsel(struct bttv *btv, unsigned int input)
-{
- unsigned int mux = input % 4;
-
- if (input == btv->svhs)
- mux = 0;
-
- gpio_bits(0x3, mux);
-}
-
-/*
- * GeoVision GV-800(S) functions
- * Bruno Christo <bchristo@inf.ufsm.br>
-*/
-
-/* This is a function to control the analog switch, which determines which
- * camera is routed to which controller. The switch comprises an X-address
- * (gpio bits 0-3, representing the camera, ranging from 0-15), and a
- * Y-address (gpio bits 4-6, representing the controller, ranging from 0-3).
- * A data value (gpio bit 18) of '1' enables the switch, and '0' disables
- * the switch. A STROBE bit (gpio bit 17) latches the data value into the
- * specified address. There is also a chip select (gpio bit 16).
- * The idea is to set the address and chip select together, bring
- * STROBE high, write the data, and finally bring STROBE back to low.
- */
-static void gv800s_write(struct bttv *btv,
- unsigned char xaddr,
- unsigned char yaddr,
- unsigned char data) {
- /* On the "master" 878A:
- * GPIO bits 0-9 are used for the analog switch:
- * 00 - 03: camera selector
- * 04 - 06: 878A (controller) selector
- * 16: cselect
- * 17: strobe
- * 18: data (1->on, 0->off)
- * 19: reset
- */
- const u32 ADDRESS = ((xaddr&0xf) | (yaddr&3)<<4);
- const u32 CSELECT = 1<<16;
- const u32 STROBE = 1<<17;
- const u32 DATA = data<<18;
-
- gpio_bits(0x1007f, ADDRESS | CSELECT); /* write ADDRESS and CSELECT */
- gpio_bits(0x20000, STROBE); /* STROBE high */
- gpio_bits(0x40000, DATA); /* write DATA */
- gpio_bits(0x20000, ~STROBE); /* STROBE low */
-}
-
-/*
- * GeoVision GV-800(S) muxsel
- *
- * Each of the 4 cards (controllers) use this function.
- * The controller using this function selects the input through the GPIO pins
- * of the "master" card. A pointer to this card is stored in master[btv->c.nr].
- *
- * The parameter 'input' is the requested camera number (0-4) on the controller.
- * The map array has the address of each input. Note that the addresses in the
- * array are in the sequence the original GeoVision driver uses, that is, set
- * every controller to input 0, then to input 1, 2, 3, repeat. This means that
- * the physical "camera 1" connector corresponds to controller 0 input 0,
- * "camera 2" corresponds to controller 1 input 0, and so on.
- *
- * After getting the input address, the function then writes the appropriate
- * data to the analog switch, and housekeeps the local copy of the switch
- * information.
- */
-static void gv800s_muxsel(struct bttv *btv, unsigned int input)
-{
- struct bttv *mctlr;
- char *sw_status;
- int xaddr, yaddr;
- static unsigned int map[4][4] = { { 0x0, 0x4, 0xa, 0x6 },
- { 0x1, 0x5, 0xb, 0x7 },
- { 0x2, 0x8, 0xc, 0xe },
- { 0x3, 0x9, 0xd, 0xf } };
- input = input%4;
- mctlr = master[btv->c.nr];
- if (mctlr == NULL) {
- /* do nothing until the "master" is detected */
- return;
- }
- yaddr = (btv->c.nr - mctlr->c.nr) & 3;
- sw_status = (char *)(&mctlr->mbox_we);
- xaddr = map[yaddr][input] & 0xf;
-
- /* Check if the controller/camera pair has changed, ignore otherwise */
- if (sw_status[yaddr] != xaddr) {
- /* disable the old switch, enable the new one and save status */
- gv800s_write(mctlr, sw_status[yaddr], yaddr, 0);
- sw_status[yaddr] = xaddr;
- gv800s_write(mctlr, xaddr, yaddr, 1);
- }
-}
-
-/* GeoVision GV-800(S) "master" chip init */
-static void gv800s_init(struct bttv *btv)
-{
- char *sw_status = (char *)(&btv->mbox_we);
- int ix;
-
- gpio_inout(0xf107f, 0xf107f);
- gpio_write(1<<19); /* reset the analog MUX */
- gpio_write(0);
-
- /* Preset camera 0 to the 4 controllers */
- for (ix = 0; ix < 4; ix++) {
- sw_status[ix] = ix;
- gv800s_write(btv, ix, ix, 1);
- }
-
- /* Inputs on the "master" controller need this brightness fix */
- bttv_I2CWrite(btv, 0x18, 0x5, 0x90, 1);
-
- if (btv->c.nr > BTTV_MAX-4)
- return;
- /*
- * Store the "master" controller pointer in the master
- * array for later use in the muxsel function.
- */
- master[btv->c.nr] = btv;
- master[btv->c.nr+1] = btv;
- master[btv->c.nr+2] = btv;
- master[btv->c.nr+3] = btv;
-}
-
-/* ----------------------------------------------------------------------- */
-/* motherboard chipset specific stuff */
-
-void __init bttv_check_chipset(void)
-{
- int pcipci_fail = 0;
- struct pci_dev *dev = NULL;
-
- if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) /* should check if target is AGP */
- pcipci_fail = 1;
- if (pci_pci_problems & (PCIPCI_TRITON|PCIPCI_NATOMA|PCIPCI_VIAETBF))
- triton1 = 1;
- if (pci_pci_problems & PCIPCI_VSFX)
- vsfx = 1;
-#ifdef PCIPCI_ALIMAGIK
- if (pci_pci_problems & PCIPCI_ALIMAGIK)
- latency = 0x0A;
-#endif
-
-
- /* print warnings about any quirks found */
- if (triton1)
- pr_info("Host bridge needs ETBF enabled\n");
- if (vsfx)
- pr_info("Host bridge needs VSFX enabled\n");
- if (pcipci_fail) {
- pr_info("bttv and your chipset may not work together\n");
- if (!no_overlay) {
- pr_info("overlay will be disabled\n");
- no_overlay = 1;
- } else {
- pr_info("overlay forced. Use this option at your own risk.\n");
- }
- }
- if (UNSET != latency)
- pr_info("pci latency fixup [%d]\n", latency);
- while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82441, dev))) {
- unsigned char b;
- pci_read_config_byte(dev, 0x53, &b);
- if (bttv_debug)
- pr_info("Host bridge: 82441FX Natoma, bufcon=0x%02x\n",
- b);
- }
-}
-
-int __devinit bttv_handle_chipset(struct bttv *btv)
-{
- unsigned char command;
-
- if (!triton1 && !vsfx && UNSET == latency)
- return 0;
-
- if (bttv_verbose) {
- if (triton1)
- pr_info("%d: enabling ETBF (430FX/VP3 compatibility)\n",
- btv->c.nr);
- if (vsfx && btv->id >= 878)
- pr_info("%d: enabling VSFX\n", btv->c.nr);
- if (UNSET != latency)
- pr_info("%d: setting pci timer to %d\n",
- btv->c.nr, latency);
- }
-
- if (btv->id < 878) {
- /* bt848 (mis)uses a bit in the irq mask for etbf */
- if (triton1)
- btv->triton1 = BT848_INT_ETBF;
- } else {
- /* bt878 has a bit in the pci config space for it */
- pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command);
- if (triton1)
- command |= BT878_EN_TBFX;
- if (vsfx)
- command |= BT878_EN_VSFX;
- pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command);
- }
- if (UNSET != latency)
- pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency);
- return 0;
-}
-
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
deleted file mode 100644
index 2ce7179a386..00000000000
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ /dev/null
@@ -1,4630 +0,0 @@
-/*
-
- bttv - Bt848 frame grabber driver
-
- Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de>
- & Marcus Metzler <mocm@thp.uni-koeln.de>
- (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org>
-
- some v4l2 code lines are taken from Justin's bttv2 driver which is
- (c) 2000 Justin Schoeman <justin@suntiger.ee.up.ac.za>
-
- V4L1 removal from:
- (c) 2005-2006 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
-
- Fixes to be fully V4L2 compliant by
- (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org>
-
- Cropping and overscan support
- Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at>
- Sponsored by OPQ Systems AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/kdev_t.h>
-#include "bttvp.h"
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/tvaudio.h>
-#include <media/msp3400.h>
-
-#include <linux/dma-mapping.h>
-
-#include <asm/io.h>
-#include <asm/byteorder.h>
-
-#include <media/saa6588.h>
-
-#define BTTV_VERSION "0.9.19"
-
-unsigned int bttv_num; /* number of Bt848s in use */
-struct bttv *bttvs[BTTV_MAX];
-
-unsigned int bttv_debug;
-unsigned int bttv_verbose = 1;
-unsigned int bttv_gpio;
-
-/* config variables */
-#ifdef __BIG_ENDIAN
-static unsigned int bigendian=1;
-#else
-static unsigned int bigendian;
-#endif
-static unsigned int radio[BTTV_MAX];
-static unsigned int irq_debug;
-static unsigned int gbuffers = 8;
-static unsigned int gbufsize = 0x208000;
-static unsigned int reset_crop = 1;
-
-static int video_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };
-static int radio_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };
-static int vbi_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };
-static int debug_latency;
-static int disable_ir;
-
-static unsigned int fdsr;
-
-/* options */
-static unsigned int combfilter;
-static unsigned int lumafilter;
-static unsigned int automute = 1;
-static unsigned int chroma_agc;
-static unsigned int adc_crush = 1;
-static unsigned int whitecrush_upper = 0xCF;
-static unsigned int whitecrush_lower = 0x7F;
-static unsigned int vcr_hack;
-static unsigned int irq_iswitch;
-static unsigned int uv_ratio = 50;
-static unsigned int full_luma_range;
-static unsigned int coring;
-
-/* API features (turn on/off stuff for testing) */
-static unsigned int v4l2 = 1;
-
-/* insmod args */
-module_param(bttv_verbose, int, 0644);
-module_param(bttv_gpio, int, 0644);
-module_param(bttv_debug, int, 0644);
-module_param(irq_debug, int, 0644);
-module_param(debug_latency, int, 0644);
-module_param(disable_ir, int, 0444);
-
-module_param(fdsr, int, 0444);
-module_param(gbuffers, int, 0444);
-module_param(gbufsize, int, 0444);
-module_param(reset_crop, int, 0444);
-
-module_param(v4l2, int, 0644);
-module_param(bigendian, int, 0644);
-module_param(irq_iswitch, int, 0644);
-module_param(combfilter, int, 0444);
-module_param(lumafilter, int, 0444);
-module_param(automute, int, 0444);
-module_param(chroma_agc, int, 0444);
-module_param(adc_crush, int, 0444);
-module_param(whitecrush_upper, int, 0444);
-module_param(whitecrush_lower, int, 0444);
-module_param(vcr_hack, int, 0444);
-module_param(uv_ratio, int, 0444);
-module_param(full_luma_range, int, 0444);
-module_param(coring, int, 0444);
-
-module_param_array(radio, int, NULL, 0444);
-module_param_array(video_nr, int, NULL, 0444);
-module_param_array(radio_nr, int, NULL, 0444);
-module_param_array(vbi_nr, int, NULL, 0444);
-
-MODULE_PARM_DESC(radio,"The TV card supports radio, default is 0 (no)");
-MODULE_PARM_DESC(bigendian,"byte order of the framebuffer, default is native endian");
-MODULE_PARM_DESC(bttv_verbose,"verbose startup messages, default is 1 (yes)");
-MODULE_PARM_DESC(bttv_gpio,"log gpio changes, default is 0 (no)");
-MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)");
-MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)");
-MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
-MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8");
-MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");
-MODULE_PARM_DESC(reset_crop,"reset cropping parameters at open(), default "
- "is 1 (yes) for compatibility with older applications");
-MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)");
-MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)");
-MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)");
-MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is 207");
-MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127");
-MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)");
-MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler");
-MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50");
-MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)");
-MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)");
-MODULE_PARM_DESC(video_nr, "video device numbers");
-MODULE_PARM_DESC(vbi_nr, "vbi device numbers");
-MODULE_PARM_DESC(radio_nr, "radio device numbers");
-
-MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");
-MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(BTTV_VERSION);
-
-/* ----------------------------------------------------------------------- */
-/* sysfs */
-
-static ssize_t show_card(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vfd = container_of(cd, struct video_device, dev);
- struct bttv *btv = video_get_drvdata(vfd);
- return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
-}
-static DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
-
-/* ----------------------------------------------------------------------- */
-/* dvb auto-load setup */
-#if defined(CONFIG_MODULES) && defined(MODULE)
-static void request_module_async(struct work_struct *work)
-{
- request_module("dvb-bt8xx");
-}
-
-static void request_modules(struct bttv *dev)
-{
- INIT_WORK(&dev->request_module_wk, request_module_async);
- schedule_work(&dev->request_module_wk);
-}
-
-static void flush_request_modules(struct bttv *dev)
-{
- flush_work(&dev->request_module_wk);
-}
-#else
-#define request_modules(dev)
-#define flush_request_modules(dev)
-#endif /* CONFIG_MODULES */
-
-
-/* ----------------------------------------------------------------------- */
-/* static data */
-
-/* special timing tables from conexant... */
-static u8 SRAM_Table[][60] =
-{
- /* PAL digital input over GPIO[7:0] */
- {
- 45, // 45 bytes following
- 0x36,0x11,0x01,0x00,0x90,0x02,0x05,0x10,0x04,0x16,
- 0x12,0x05,0x11,0x00,0x04,0x12,0xC0,0x00,0x31,0x00,
- 0x06,0x51,0x08,0x03,0x89,0x08,0x07,0xC0,0x44,0x00,
- 0x81,0x01,0x01,0xA9,0x0D,0x02,0x02,0x50,0x03,0x37,
- 0x37,0x00,0xAF,0x21,0x00
- },
- /* NTSC digital input over GPIO[7:0] */
- {
- 51, // 51 bytes following
- 0x0C,0xC0,0x00,0x00,0x90,0x02,0x03,0x10,0x03,0x06,
- 0x10,0x04,0x12,0x12,0x05,0x02,0x13,0x04,0x19,0x00,
- 0x04,0x39,0x00,0x06,0x59,0x08,0x03,0x83,0x08,0x07,
- 0x03,0x50,0x00,0xC0,0x40,0x00,0x86,0x01,0x01,0xA6,
- 0x0D,0x02,0x03,0x11,0x01,0x05,0x37,0x00,0xAC,0x21,
- 0x00,
- },
- // TGB_NTSC392 // quartzsight
- // This table has been modified to be used for Fusion Rev D
- {
- 0x2A, // size of table = 42
- 0x06, 0x08, 0x04, 0x0a, 0xc0, 0x00, 0x18, 0x08, 0x03, 0x24,
- 0x08, 0x07, 0x02, 0x90, 0x02, 0x08, 0x10, 0x04, 0x0c, 0x10,
- 0x05, 0x2c, 0x11, 0x04, 0x55, 0x48, 0x00, 0x05, 0x50, 0x00,
- 0xbf, 0x0c, 0x02, 0x2f, 0x3d, 0x00, 0x2f, 0x3f, 0x00, 0xc3,
- 0x20, 0x00
- }
-};
-
-/* minhdelayx1 first video pixel we can capture on a line and
- hdelayx1 start of active video, both relative to rising edge of
- /HRESET pulse (0H) in 1 / fCLKx1.
- swidth width of active video and
- totalwidth total line width, both in 1 / fCLKx1.
- sqwidth total line width in square pixels.
- vdelay start of active video in 2 * field lines relative to
- trailing edge of /VRESET pulse (VDELAY register).
- sheight height of active video in 2 * field lines.
- videostart0 ITU-R frame line number of the line corresponding
- to vdelay in the first field. */
-#define CROPCAP(minhdelayx1, hdelayx1, swidth, totalwidth, sqwidth, \
- vdelay, sheight, videostart0) \
- .cropcap.bounds.left = minhdelayx1, \
- /* * 2 because vertically we count field lines times two, */ \
- /* e.g. 23 * 2 to 23 * 2 + 576 in PAL-BGHI defrect. */ \
- .cropcap.bounds.top = (videostart0) * 2 - (vdelay) + MIN_VDELAY, \
- /* 4 is a safety margin at the end of the line. */ \
- .cropcap.bounds.width = (totalwidth) - (minhdelayx1) - 4, \
- .cropcap.bounds.height = (sheight) + (vdelay) - MIN_VDELAY, \
- .cropcap.defrect.left = hdelayx1, \
- .cropcap.defrect.top = (videostart0) * 2, \
- .cropcap.defrect.width = swidth, \
- .cropcap.defrect.height = sheight, \
- .cropcap.pixelaspect.numerator = totalwidth, \
- .cropcap.pixelaspect.denominator = sqwidth,
-
-const struct bttv_tvnorm bttv_tvnorms[] = {
- /* PAL-BDGHI */
- /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
- /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
- {
- .v4l2_id = V4L2_STD_PAL,
- .name = "PAL",
- .Fsc = 35468950,
- .swidth = 924,
- .sheight = 576,
- .totalwidth = 1135,
- .adelay = 0x7f,
- .bdelay = 0x72,
- .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
- .scaledtwidth = 1135,
- .hdelayx1 = 186,
- .hactivex1 = 924,
- .vdelay = 0x20,
- .vbipack = 255, /* min (2048 / 4, 0x1ff) & 0xff */
- .sram = 0,
- /* ITU-R frame line number of the first VBI line
- we can capture, of the first and second field.
- The last line is determined by cropcap.bounds. */
- .vbistart = { 7, 320 },
- CROPCAP(/* minhdelayx1 */ 68,
- /* hdelayx1 */ 186,
- /* Should be (768 * 1135 + 944 / 2) / 944.
- cropcap.defrect is used for image width
- checks, so we keep the old value 924. */
- /* swidth */ 924,
- /* totalwidth */ 1135,
- /* sqwidth */ 944,
- /* vdelay */ 0x20,
- /* sheight */ 576,
- /* videostart0 */ 23)
- /* bt878 (and bt848?) can capture another
- line below active video. */
- .cropcap.bounds.height = (576 + 2) + 0x20 - 2,
- },{
- .v4l2_id = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
- .name = "NTSC",
- .Fsc = 28636363,
- .swidth = 768,
- .sheight = 480,
- .totalwidth = 910,
- .adelay = 0x68,
- .bdelay = 0x5d,
- .iform = (BT848_IFORM_NTSC|BT848_IFORM_XT0),
- .scaledtwidth = 910,
- .hdelayx1 = 128,
- .hactivex1 = 910,
- .vdelay = 0x1a,
- .vbipack = 144, /* min (1600 / 4, 0x1ff) & 0xff */
- .sram = 1,
- .vbistart = { 10, 273 },
- CROPCAP(/* minhdelayx1 */ 68,
- /* hdelayx1 */ 128,
- /* Should be (640 * 910 + 780 / 2) / 780? */
- /* swidth */ 768,
- /* totalwidth */ 910,
- /* sqwidth */ 780,
- /* vdelay */ 0x1a,
- /* sheight */ 480,
- /* videostart0 */ 23)
- },{
- .v4l2_id = V4L2_STD_SECAM,
- .name = "SECAM",
- .Fsc = 35468950,
- .swidth = 924,
- .sheight = 576,
- .totalwidth = 1135,
- .adelay = 0x7f,
- .bdelay = 0xb0,
- .iform = (BT848_IFORM_SECAM|BT848_IFORM_XT1),
- .scaledtwidth = 1135,
- .hdelayx1 = 186,
- .hactivex1 = 922,
- .vdelay = 0x20,
- .vbipack = 255,
- .sram = 0, /* like PAL, correct? */
- .vbistart = { 7, 320 },
- CROPCAP(/* minhdelayx1 */ 68,
- /* hdelayx1 */ 186,
- /* swidth */ 924,
- /* totalwidth */ 1135,
- /* sqwidth */ 944,
- /* vdelay */ 0x20,
- /* sheight */ 576,
- /* videostart0 */ 23)
- },{
- .v4l2_id = V4L2_STD_PAL_Nc,
- .name = "PAL-Nc",
- .Fsc = 28636363,
- .swidth = 640,
- .sheight = 576,
- .totalwidth = 910,
- .adelay = 0x68,
- .bdelay = 0x5d,
- .iform = (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),
- .scaledtwidth = 780,
- .hdelayx1 = 130,
- .hactivex1 = 734,
- .vdelay = 0x1a,
- .vbipack = 144,
- .sram = -1,
- .vbistart = { 7, 320 },
- CROPCAP(/* minhdelayx1 */ 68,
- /* hdelayx1 */ 130,
- /* swidth */ (640 * 910 + 780 / 2) / 780,
- /* totalwidth */ 910,
- /* sqwidth */ 780,
- /* vdelay */ 0x1a,
- /* sheight */ 576,
- /* videostart0 */ 23)
- },{
- .v4l2_id = V4L2_STD_PAL_M,
- .name = "PAL-M",
- .Fsc = 28636363,
- .swidth = 640,
- .sheight = 480,
- .totalwidth = 910,
- .adelay = 0x68,
- .bdelay = 0x5d,
- .iform = (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
- .scaledtwidth = 780,
- .hdelayx1 = 135,
- .hactivex1 = 754,
- .vdelay = 0x1a,
- .vbipack = 144,
- .sram = -1,
- .vbistart = { 10, 273 },
- CROPCAP(/* minhdelayx1 */ 68,
- /* hdelayx1 */ 135,
- /* swidth */ (640 * 910 + 780 / 2) / 780,
- /* totalwidth */ 910,
- /* sqwidth */ 780,
- /* vdelay */ 0x1a,
- /* sheight */ 480,
- /* videostart0 */ 23)
- },{
- .v4l2_id = V4L2_STD_PAL_N,
- .name = "PAL-N",
- .Fsc = 35468950,
- .swidth = 768,
- .sheight = 576,
- .totalwidth = 1135,
- .adelay = 0x7f,
- .bdelay = 0x72,
- .iform = (BT848_IFORM_PAL_N|BT848_IFORM_XT1),
- .scaledtwidth = 944,
- .hdelayx1 = 186,
- .hactivex1 = 922,
- .vdelay = 0x20,
- .vbipack = 144,
- .sram = -1,
- .vbistart = { 7, 320 },
- CROPCAP(/* minhdelayx1 */ 68,
- /* hdelayx1 */ 186,
- /* swidth */ (768 * 1135 + 944 / 2) / 944,
- /* totalwidth */ 1135,
- /* sqwidth */ 944,
- /* vdelay */ 0x20,
- /* sheight */ 576,
- /* videostart0 */ 23)
- },{
- .v4l2_id = V4L2_STD_NTSC_M_JP,
- .name = "NTSC-JP",
- .Fsc = 28636363,
- .swidth = 640,
- .sheight = 480,
- .totalwidth = 910,
- .adelay = 0x68,
- .bdelay = 0x5d,
- .iform = (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),
- .scaledtwidth = 780,
- .hdelayx1 = 135,
- .hactivex1 = 754,
- .vdelay = 0x16,
- .vbipack = 144,
- .sram = -1,
- .vbistart = { 10, 273 },
- CROPCAP(/* minhdelayx1 */ 68,
- /* hdelayx1 */ 135,
- /* swidth */ (640 * 910 + 780 / 2) / 780,
- /* totalwidth */ 910,
- /* sqwidth */ 780,
- /* vdelay */ 0x16,
- /* sheight */ 480,
- /* videostart0 */ 23)
- },{
- /* that one hopefully works with the strange timing
- * which video recorders produce when playing a NTSC
- * tape on a PAL TV ... */
- .v4l2_id = V4L2_STD_PAL_60,
- .name = "PAL-60",
- .Fsc = 35468950,
- .swidth = 924,
- .sheight = 480,
- .totalwidth = 1135,
- .adelay = 0x7f,
- .bdelay = 0x72,
- .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
- .scaledtwidth = 1135,
- .hdelayx1 = 186,
- .hactivex1 = 924,
- .vdelay = 0x1a,
- .vbipack = 255,
- .vtotal = 524,
- .sram = -1,
- .vbistart = { 10, 273 },
- CROPCAP(/* minhdelayx1 */ 68,
- /* hdelayx1 */ 186,
- /* swidth */ 924,
- /* totalwidth */ 1135,
- /* sqwidth */ 944,
- /* vdelay */ 0x1a,
- /* sheight */ 480,
- /* videostart0 */ 23)
- }
-};
-static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms);
-
-/* ----------------------------------------------------------------------- */
-/* bttv format list
- packed pixel formats must come first */
-static const struct bttv_format formats[] = {
- {
- .name = "8 bpp, gray",
- .fourcc = V4L2_PIX_FMT_GREY,
- .btformat = BT848_COLOR_FMT_Y8,
- .depth = 8,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "8 bpp, dithered color",
- .fourcc = V4L2_PIX_FMT_HI240,
- .btformat = BT848_COLOR_FMT_RGB8,
- .depth = 8,
- .flags = FORMAT_FLAGS_PACKED | FORMAT_FLAGS_DITHER,
- },{
- .name = "15 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_RGB555,
- .btformat = BT848_COLOR_FMT_RGB15,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "15 bpp RGB, be",
- .fourcc = V4L2_PIX_FMT_RGB555X,
- .btformat = BT848_COLOR_FMT_RGB15,
- .btswap = 0x03, /* byteswap */
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "16 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_RGB565,
- .btformat = BT848_COLOR_FMT_RGB16,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "16 bpp RGB, be",
- .fourcc = V4L2_PIX_FMT_RGB565X,
- .btformat = BT848_COLOR_FMT_RGB16,
- .btswap = 0x03, /* byteswap */
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "24 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_BGR24,
- .btformat = BT848_COLOR_FMT_RGB24,
- .depth = 24,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "32 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_BGR32,
- .btformat = BT848_COLOR_FMT_RGB32,
- .depth = 32,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "32 bpp RGB, be",
- .fourcc = V4L2_PIX_FMT_RGB32,
- .btformat = BT848_COLOR_FMT_RGB32,
- .btswap = 0x0f, /* byte+word swap */
- .depth = 32,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "4:2:2, packed, YUYV",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .btformat = BT848_COLOR_FMT_YUY2,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "4:2:2, packed, UYVY",
- .fourcc = V4L2_PIX_FMT_UYVY,
- .btformat = BT848_COLOR_FMT_YUY2,
- .btswap = 0x03, /* byteswap */
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "4:2:2, planar, Y-Cb-Cr",
- .fourcc = V4L2_PIX_FMT_YUV422P,
- .btformat = BT848_COLOR_FMT_YCrCb422,
- .depth = 16,
- .flags = FORMAT_FLAGS_PLANAR,
- .hshift = 1,
- .vshift = 0,
- },{
- .name = "4:2:0, planar, Y-Cb-Cr",
- .fourcc = V4L2_PIX_FMT_YUV420,
- .btformat = BT848_COLOR_FMT_YCrCb422,
- .depth = 12,
- .flags = FORMAT_FLAGS_PLANAR,
- .hshift = 1,
- .vshift = 1,
- },{
- .name = "4:2:0, planar, Y-Cr-Cb",
- .fourcc = V4L2_PIX_FMT_YVU420,
- .btformat = BT848_COLOR_FMT_YCrCb422,
- .depth = 12,
- .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb,
- .hshift = 1,
- .vshift = 1,
- },{
- .name = "4:1:1, planar, Y-Cb-Cr",
- .fourcc = V4L2_PIX_FMT_YUV411P,
- .btformat = BT848_COLOR_FMT_YCrCb411,
- .depth = 12,
- .flags = FORMAT_FLAGS_PLANAR,
- .hshift = 2,
- .vshift = 0,
- },{
- .name = "4:1:0, planar, Y-Cb-Cr",
- .fourcc = V4L2_PIX_FMT_YUV410,
- .btformat = BT848_COLOR_FMT_YCrCb411,
- .depth = 9,
- .flags = FORMAT_FLAGS_PLANAR,
- .hshift = 2,
- .vshift = 2,
- },{
- .name = "4:1:0, planar, Y-Cr-Cb",
- .fourcc = V4L2_PIX_FMT_YVU410,
- .btformat = BT848_COLOR_FMT_YCrCb411,
- .depth = 9,
- .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb,
- .hshift = 2,
- .vshift = 2,
- },{
- .name = "raw scanlines",
- .fourcc = -1,
- .btformat = BT848_COLOR_FMT_RAW,
- .depth = 8,
- .flags = FORMAT_FLAGS_RAW,
- }
-};
-static const unsigned int FORMATS = ARRAY_SIZE(formats);
-
-/* ----------------------------------------------------------------------- */
-
-#define V4L2_CID_PRIVATE_CHROMA_AGC (V4L2_CID_PRIVATE_BASE + 0)
-#define V4L2_CID_PRIVATE_COMBFILTER (V4L2_CID_PRIVATE_BASE + 1)
-#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_PRIVATE_BASE + 2)
-#define V4L2_CID_PRIVATE_LUMAFILTER (V4L2_CID_PRIVATE_BASE + 3)
-#define V4L2_CID_PRIVATE_AGC_CRUSH (V4L2_CID_PRIVATE_BASE + 4)
-#define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5)
-#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6)
-#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_PRIVATE_BASE + 7)
-#define V4L2_CID_PRIVATE_UV_RATIO (V4L2_CID_PRIVATE_BASE + 8)
-#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE (V4L2_CID_PRIVATE_BASE + 9)
-#define V4L2_CID_PRIVATE_CORING (V4L2_CID_PRIVATE_BASE + 10)
-#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 11)
-
-static const struct v4l2_queryctrl no_ctl = {
- .name = "42",
- .flags = V4L2_CTRL_FLAG_DISABLED,
-};
-static const struct v4l2_queryctrl bttv_ctls[] = {
- /* --- video --- */
- {
- .id = V4L2_CID_BRIGHTNESS,
- .name = "Brightness",
- .minimum = 0,
- .maximum = 65535,
- .step = 256,
- .default_value = 32768,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_CONTRAST,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 65535,
- .step = 128,
- .default_value = 27648,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_SATURATION,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 65535,
- .step = 128,
- .default_value = 32768,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_HUE,
- .name = "Hue",
- .minimum = 0,
- .maximum = 65535,
- .step = 256,
- .default_value = 32768,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
- /* --- audio --- */
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 65535/100,
- .default_value = 65535,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_AUDIO_BALANCE,
- .name = "Balance",
- .minimum = 0,
- .maximum = 65535,
- .step = 65535/100,
- .default_value = 32768,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_AUDIO_BASS,
- .name = "Bass",
- .minimum = 0,
- .maximum = 65535,
- .step = 65535/100,
- .default_value = 32768,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_AUDIO_TREBLE,
- .name = "Treble",
- .minimum = 0,
- .maximum = 65535,
- .step = 65535/100,
- .default_value = 32768,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
- /* --- private --- */
- {
- .id = V4L2_CID_PRIVATE_CHROMA_AGC,
- .name = "chroma agc",
- .minimum = 0,
- .maximum = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_PRIVATE_COMBFILTER,
- .name = "combfilter",
- .minimum = 0,
- .maximum = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_PRIVATE_AUTOMUTE,
- .name = "automute",
- .minimum = 0,
- .maximum = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_PRIVATE_LUMAFILTER,
- .name = "luma decimation filter",
- .minimum = 0,
- .maximum = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_PRIVATE_AGC_CRUSH,
- .name = "agc crush",
- .minimum = 0,
- .maximum = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_PRIVATE_VCR_HACK,
- .name = "vcr hack",
- .minimum = 0,
- .maximum = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_PRIVATE_WHITECRUSH_UPPER,
- .name = "whitecrush upper",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 0xCF,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_PRIVATE_WHITECRUSH_LOWER,
- .name = "whitecrush lower",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 0x7F,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_PRIVATE_UV_RATIO,
- .name = "uv ratio",
- .minimum = 0,
- .maximum = 100,
- .step = 1,
- .default_value = 50,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_PRIVATE_FULL_LUMA_RANGE,
- .name = "full luma range",
- .minimum = 0,
- .maximum = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_PRIVATE_CORING,
- .name = "coring",
- .minimum = 0,
- .maximum = 3,
- .step = 1,
- .default_value = 0,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-
-
-
-};
-
-static const struct v4l2_queryctrl *ctrl_by_id(int id)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(bttv_ctls); i++)
- if (bttv_ctls[i].id == id)
- return bttv_ctls+i;
-
- return NULL;
-}
-
-/* ----------------------------------------------------------------------- */
-/* resource management */
-
-/*
- RESOURCE_ allocated by freed by
-
- VIDEO_READ bttv_read 1) bttv_read 2)
-
- VIDEO_STREAM VIDIOC_STREAMON VIDIOC_STREAMOFF
- VIDIOC_QBUF 1) bttv_release
- VIDIOCMCAPTURE 1)
-
- OVERLAY VIDIOCCAPTURE on VIDIOCCAPTURE off
- VIDIOC_OVERLAY on VIDIOC_OVERLAY off
- 3) bttv_release
-
- VBI VIDIOC_STREAMON VIDIOC_STREAMOFF
- VIDIOC_QBUF 1) bttv_release
- bttv_read, bttv_poll 1) 4)
-
- 1) The resource must be allocated when we enter buffer prepare functions
- and remain allocated while buffers are in the DMA queue.
- 2) This is a single frame read.
- 3) VIDIOC_S_FBUF and VIDIOC_S_FMT (OVERLAY) still work when
- RESOURCE_OVERLAY is allocated.
- 4) This is a continuous read, implies VIDIOC_STREAMON.
-
- Note this driver permits video input and standard changes regardless if
- resources are allocated.
-*/
-
-#define VBI_RESOURCES (RESOURCE_VBI)
-#define VIDEO_RESOURCES (RESOURCE_VIDEO_READ | \
- RESOURCE_VIDEO_STREAM | \
- RESOURCE_OVERLAY)
-
-static
-int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit)
-{
- int xbits; /* mutual exclusive resources */
-
- if (fh->resources & bit)
- /* have it already allocated */
- return 1;
-
- xbits = bit;
- if (bit & (RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM))
- xbits |= RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM;
-
- /* is it free? */
- if (btv->resources & xbits) {
- /* no, someone else uses it */
- goto fail;
- }
-
- if ((bit & VIDEO_RESOURCES)
- && 0 == (btv->resources & VIDEO_RESOURCES)) {
- /* Do crop - use current, don't - use default parameters. */
- __s32 top = btv->crop[!!fh->do_crop].rect.top;
-
- if (btv->vbi_end > top)
- goto fail;
-
- /* We cannot capture the same line as video and VBI data.
- Claim scan lines crop[].rect.top to bottom. */
- btv->crop_start = top;
- } else if (bit & VBI_RESOURCES) {
- __s32 end = fh->vbi_fmt.end;
-
- if (end > btv->crop_start)
- goto fail;
-
- /* Claim scan lines above fh->vbi_fmt.end. */
- btv->vbi_end = end;
- }
-
- /* it's free, grab it */
- fh->resources |= bit;
- btv->resources |= bit;
- return 1;
-
- fail:
- return 0;
-}
-
-static
-int check_btres(struct bttv_fh *fh, int bit)
-{
- return (fh->resources & bit);
-}
-
-static
-int locked_btres(struct bttv *btv, int bit)
-{
- return (btv->resources & bit);
-}
-
-/* Call with btv->lock down. */
-static void
-disclaim_vbi_lines(struct bttv *btv)
-{
- btv->vbi_end = 0;
-}
-
-/* Call with btv->lock down. */
-static void
-disclaim_video_lines(struct bttv *btv)
-{
- const struct bttv_tvnorm *tvnorm;
- u8 crop;
-
- tvnorm = &bttv_tvnorms[btv->tvnorm];
- btv->crop_start = tvnorm->cropcap.bounds.top
- + tvnorm->cropcap.bounds.height;
-
- /* VBI capturing ends at VDELAY, start of video capturing, no
- matter how many lines the VBI RISC program expects. When video
- capturing is off, it shall no longer "preempt" VBI capturing,
- so we set VDELAY to maximum. */
- crop = btread(BT848_E_CROP) | 0xc0;
- btwrite(crop, BT848_E_CROP);
- btwrite(0xfe, BT848_E_VDELAY_LO);
- btwrite(crop, BT848_O_CROP);
- btwrite(0xfe, BT848_O_VDELAY_LO);
-}
-
-static
-void free_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bits)
-{
- if ((fh->resources & bits) != bits) {
- /* trying to free resources not allocated by us ... */
- pr_err("BUG! (btres)\n");
- }
- fh->resources &= ~bits;
- btv->resources &= ~bits;
-
- bits = btv->resources;
-
- if (0 == (bits & VIDEO_RESOURCES))
- disclaim_video_lines(btv);
-
- if (0 == (bits & VBI_RESOURCES))
- disclaim_vbi_lines(btv);
-}
-
-/* ----------------------------------------------------------------------- */
-/* If Bt848a or Bt849, use PLL for PAL/SECAM and crystal for NTSC */
-
-/* Frequency = (F_input / PLL_X) * PLL_I.PLL_F/PLL_C
- PLL_X = Reference pre-divider (0=1, 1=2)
- PLL_C = Post divider (0=6, 1=4)
- PLL_I = Integer input
- PLL_F = Fractional input
-
- F_input = 28.636363 MHz:
- PAL (CLKx2 = 35.46895 MHz): PLL_X = 1, PLL_I = 0x0E, PLL_F = 0xDCF9, PLL_C = 0
-*/
-
-static void set_pll_freq(struct bttv *btv, unsigned int fin, unsigned int fout)
-{
- unsigned char fl, fh, fi;
-
- /* prevent overflows */
- fin/=4;
- fout/=4;
-
- fout*=12;
- fi=fout/fin;
-
- fout=(fout%fin)*256;
- fh=fout/fin;
-
- fout=(fout%fin)*256;
- fl=fout/fin;
-
- btwrite(fl, BT848_PLL_F_LO);
- btwrite(fh, BT848_PLL_F_HI);
- btwrite(fi|BT848_PLL_X, BT848_PLL_XCI);
-}
-
-static void set_pll(struct bttv *btv)
-{
- int i;
-
- if (!btv->pll.pll_crystal)
- return;
-
- if (btv->pll.pll_ofreq == btv->pll.pll_current) {
- dprintk("%d: PLL: no change required\n", btv->c.nr);
- return;
- }
-
- if (btv->pll.pll_ifreq == btv->pll.pll_ofreq) {
- /* no PLL needed */
- if (btv->pll.pll_current == 0)
- return;
- if (bttv_verbose)
- pr_info("%d: PLL can sleep, using XTAL (%d)\n",
- btv->c.nr, btv->pll.pll_ifreq);
- btwrite(0x00,BT848_TGCTRL);
- btwrite(0x00,BT848_PLL_XCI);
- btv->pll.pll_current = 0;
- return;
- }
-
- if (bttv_verbose)
- pr_info("%d: Setting PLL: %d => %d (needs up to 100ms)\n",
- btv->c.nr,
- btv->pll.pll_ifreq, btv->pll.pll_ofreq);
- set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq);
-
- for (i=0; i<10; i++) {
- /* Let other people run while the PLL stabilizes */
- msleep(10);
-
- if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) {
- btwrite(0,BT848_DSTATUS);
- } else {
- btwrite(0x08,BT848_TGCTRL);
- btv->pll.pll_current = btv->pll.pll_ofreq;
- if (bttv_verbose)
- pr_info("PLL set ok\n");
- return;
- }
- }
- btv->pll.pll_current = -1;
- if (bttv_verbose)
- pr_info("Setting PLL failed\n");
- return;
-}
-
-/* used to switch between the bt848's analog/digital video capture modes */
-static void bt848A_set_timing(struct bttv *btv)
-{
- int i, len;
- int table_idx = bttv_tvnorms[btv->tvnorm].sram;
- int fsc = bttv_tvnorms[btv->tvnorm].Fsc;
-
- if (btv->input == btv->dig) {
- dprintk("%d: load digital timing table (table_idx=%d)\n",
- btv->c.nr,table_idx);
-
- /* timing change...reset timing generator address */
- btwrite(0x00, BT848_TGCTRL);
- btwrite(0x02, BT848_TGCTRL);
- btwrite(0x00, BT848_TGCTRL);
-
- len=SRAM_Table[table_idx][0];
- for(i = 1; i <= len; i++)
- btwrite(SRAM_Table[table_idx][i],BT848_TGLB);
- btv->pll.pll_ofreq = 27000000;
-
- set_pll(btv);
- btwrite(0x11, BT848_TGCTRL);
- btwrite(0x41, BT848_DVSIF);
- } else {
- btv->pll.pll_ofreq = fsc;
- set_pll(btv);
- btwrite(0x0, BT848_DVSIF);
- }
-}
-
-/* ----------------------------------------------------------------------- */
-
-static void bt848_bright(struct bttv *btv, int bright)
-{
- int value;
-
- // printk("set bright: %d\n", bright); // DEBUG
- btv->bright = bright;
-
- /* We want -128 to 127 we get 0-65535 */
- value = (bright >> 8) - 128;
- btwrite(value & 0xff, BT848_BRIGHT);
-}
-
-static void bt848_hue(struct bttv *btv, int hue)
-{
- int value;
-
- btv->hue = hue;
-
- /* -128 to 127 */
- value = (hue >> 8) - 128;
- btwrite(value & 0xff, BT848_HUE);
-}
-
-static void bt848_contrast(struct bttv *btv, int cont)
-{
- int value,hibit;
-
- btv->contrast = cont;
-
- /* 0-511 */
- value = (cont >> 7);
- hibit = (value >> 6) & 4;
- btwrite(value & 0xff, BT848_CONTRAST_LO);
- btaor(hibit, ~4, BT848_E_CONTROL);
- btaor(hibit, ~4, BT848_O_CONTROL);
-}
-
-static void bt848_sat(struct bttv *btv, int color)
-{
- int val_u,val_v,hibits;
-
- btv->saturation = color;
-
- /* 0-511 for the color */
- val_u = ((color * btv->opt_uv_ratio) / 50) >> 7;
- val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254;
- hibits = (val_u >> 7) & 2;
- hibits |= (val_v >> 8) & 1;
- btwrite(val_u & 0xff, BT848_SAT_U_LO);
- btwrite(val_v & 0xff, BT848_SAT_V_LO);
- btaor(hibits, ~3, BT848_E_CONTROL);
- btaor(hibits, ~3, BT848_O_CONTROL);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int
-video_mux(struct bttv *btv, unsigned int input)
-{
- int mux,mask2;
-
- if (input >= bttv_tvcards[btv->c.type].video_inputs)
- return -EINVAL;
-
- /* needed by RemoteVideo MX */
- mask2 = bttv_tvcards[btv->c.type].gpiomask2;
- if (mask2)
- gpio_inout(mask2,mask2);
-
- if (input == btv->svhs) {
- btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
- btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
- } else {
- btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
- btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
- }
- mux = bttv_muxsel(btv, input);
- btaor(mux<<5, ~(3<<5), BT848_IFORM);
- dprintk("%d: video mux: input=%d mux=%d\n", btv->c.nr, input, mux);
-
- /* card specific hook */
- if(bttv_tvcards[btv->c.type].muxsel_hook)
- bttv_tvcards[btv->c.type].muxsel_hook (btv, input);
- return 0;
-}
-
-static char *audio_modes[] = {
- "audio: tuner", "audio: radio", "audio: extern",
- "audio: intern", "audio: mute"
-};
-
-static int
-audio_mux(struct bttv *btv, int input, int mute)
-{
- int gpio_val, signal;
- struct v4l2_control ctrl;
-
- gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
- bttv_tvcards[btv->c.type].gpiomask);
- signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC;
-
- btv->mute = mute;
- btv->audio = input;
-
- /* automute */
- mute = mute || (btv->opt_automute && !signal && !btv->radio_user);
-
- if (mute)
- gpio_val = bttv_tvcards[btv->c.type].gpiomute;
- else
- gpio_val = bttv_tvcards[btv->c.type].gpiomux[input];
-
- switch (btv->c.type) {
- case BTTV_BOARD_VOODOOTV_FM:
- case BTTV_BOARD_VOODOOTV_200:
- gpio_val = bttv_tda9880_setnorm(btv, gpio_val);
- break;
-
- default:
- gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val);
- }
-
- if (bttv_gpio)
- bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]);
- if (in_interrupt())
- return 0;
-
- ctrl.id = V4L2_CID_AUDIO_MUTE;
- ctrl.value = btv->mute;
- bttv_call_all(btv, core, s_ctrl, &ctrl);
- if (btv->sd_msp34xx) {
- u32 in;
-
- /* Note: the inputs tuner/radio/extern/intern are translated
- to msp routings. This assumes common behavior for all msp3400
- based TV cards. When this assumption fails, then the
- specific MSP routing must be added to the card table.
- For now this is sufficient. */
- switch (input) {
- case TVAUDIO_INPUT_RADIO:
- /* Some boards need the msp do to the radio demod */
- if (btv->radio_uses_msp_demodulator) {
- in = MSP_INPUT_DEFAULT;
- break;
- }
- in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
- MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
- break;
- case TVAUDIO_INPUT_EXTERN:
- in = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
- MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
- break;
- case TVAUDIO_INPUT_INTERN:
- /* Yes, this is the same input as for RADIO. I doubt
- if this is ever used. The only board with an INTERN
- input is the BTTV_BOARD_AVERMEDIA98. I wonder how
- that was tested. My guess is that the whole INTERN
- input does not work. */
- in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
- MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
- break;
- case TVAUDIO_INPUT_TUNER:
- default:
- /* This is the only card that uses TUNER2, and afaik,
- is the only difference between the VOODOOTV_FM
- and VOODOOTV_200 */
- if (btv->c.type == BTTV_BOARD_VOODOOTV_200)
- in = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER2, \
- MSP_DSP_IN_TUNER, MSP_DSP_IN_TUNER);
- else
- in = MSP_INPUT_DEFAULT;
- break;
- }
- v4l2_subdev_call(btv->sd_msp34xx, audio, s_routing,
- in, MSP_OUTPUT_DEFAULT, 0);
- }
- if (btv->sd_tvaudio) {
- v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing,
- input, 0, 0);
- }
- return 0;
-}
-
-static inline int
-audio_mute(struct bttv *btv, int mute)
-{
- return audio_mux(btv, btv->audio, mute);
-}
-
-static inline int
-audio_input(struct bttv *btv, int input)
-{
- return audio_mux(btv, input, btv->mute);
-}
-
-static void
-bttv_crop_calc_limits(struct bttv_crop *c)
-{
- /* Scale factor min. 1:1, max. 16:1. Min. image size
- 48 x 32. Scaled width must be a multiple of 4. */
-
- if (1) {
- /* For bug compatibility with VIDIOCGCAP and image
- size checks in earlier driver versions. */
- c->min_scaled_width = 48;
- c->min_scaled_height = 32;
- } else {
- c->min_scaled_width =
- (max(48, c->rect.width >> 4) + 3) & ~3;
- c->min_scaled_height =
- max(32, c->rect.height >> 4);
- }
-
- c->max_scaled_width = c->rect.width & ~3;
- c->max_scaled_height = c->rect.height;
-}
-
-static void
-bttv_crop_reset(struct bttv_crop *c, unsigned int norm)
-{
- c->rect = bttv_tvnorms[norm].cropcap.defrect;
- bttv_crop_calc_limits(c);
-}
-
-/* Call with btv->lock down. */
-static int
-set_tvnorm(struct bttv *btv, unsigned int norm)
-{
- const struct bttv_tvnorm *tvnorm;
- v4l2_std_id id;
-
- BUG_ON(norm >= BTTV_TVNORMS);
- BUG_ON(btv->tvnorm >= BTTV_TVNORMS);
-
- tvnorm = &bttv_tvnorms[norm];
-
- if (memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap,
- sizeof (tvnorm->cropcap))) {
- bttv_crop_reset(&btv->crop[0], norm);
- btv->crop[1] = btv->crop[0]; /* current = default */
-
- if (0 == (btv->resources & VIDEO_RESOURCES)) {
- btv->crop_start = tvnorm->cropcap.bounds.top
- + tvnorm->cropcap.bounds.height;
- }
- }
-
- btv->tvnorm = norm;
-
- btwrite(tvnorm->adelay, BT848_ADELAY);
- btwrite(tvnorm->bdelay, BT848_BDELAY);
- btaor(tvnorm->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH),
- BT848_IFORM);
- btwrite(tvnorm->vbipack, BT848_VBI_PACK_SIZE);
- btwrite(1, BT848_VBI_PACK_DEL);
- bt848A_set_timing(btv);
-
- switch (btv->c.type) {
- case BTTV_BOARD_VOODOOTV_FM:
- case BTTV_BOARD_VOODOOTV_200:
- bttv_tda9880_setnorm(btv, gpio_read());
- break;
- }
- id = tvnorm->v4l2_id;
- bttv_call_all(btv, core, s_std, id);
-
- return 0;
-}
-
-/* Call with btv->lock down. */
-static void
-set_input(struct bttv *btv, unsigned int input, unsigned int norm)
-{
- unsigned long flags;
-
- btv->input = input;
- if (irq_iswitch) {
- spin_lock_irqsave(&btv->s_lock,flags);
- if (btv->curr.frame_irq) {
- /* active capture -> delayed input switch */
- btv->new_input = input;
- } else {
- video_mux(btv,input);
- }
- spin_unlock_irqrestore(&btv->s_lock,flags);
- } else {
- video_mux(btv,input);
- }
- audio_input(btv, (btv->tuner_type != TUNER_ABSENT && input == 0) ?
- TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN);
- set_tvnorm(btv, norm);
-}
-
-static void init_irqreg(struct bttv *btv)
-{
- /* clear status */
- btwrite(0xfffffUL, BT848_INT_STAT);
-
- if (bttv_tvcards[btv->c.type].no_video) {
- /* i2c only */
- btwrite(BT848_INT_I2CDONE,
- BT848_INT_MASK);
- } else {
- /* full video */
- btwrite((btv->triton1) |
- (btv->gpioirq ? BT848_INT_GPINT : 0) |
- BT848_INT_SCERR |
- (fdsr ? BT848_INT_FDSR : 0) |
- BT848_INT_RISCI | BT848_INT_OCERR |
- BT848_INT_FMTCHG|BT848_INT_HLOCK|
- BT848_INT_I2CDONE,
- BT848_INT_MASK);
- }
-}
-
-static void init_bt848(struct bttv *btv)
-{
- int val;
-
- if (bttv_tvcards[btv->c.type].no_video) {
- /* very basic init only */
- init_irqreg(btv);
- return;
- }
-
- btwrite(0x00, BT848_CAP_CTL);
- btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);
- btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM);
-
- /* set planar and packed mode trigger points and */
- /* set rising edge of inverted GPINTR pin as irq trigger */
- btwrite(BT848_GPIO_DMA_CTL_PKTP_32|
- BT848_GPIO_DMA_CTL_PLTP1_16|
- BT848_GPIO_DMA_CTL_PLTP23_16|
- BT848_GPIO_DMA_CTL_GPINTC|
- BT848_GPIO_DMA_CTL_GPINTI,
- BT848_GPIO_DMA_CTL);
-
- val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
- btwrite(val, BT848_E_SCLOOP);
- btwrite(val, BT848_O_SCLOOP);
-
- btwrite(0x20, BT848_E_VSCALE_HI);
- btwrite(0x20, BT848_O_VSCALE_HI);
- btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
- BT848_ADC);
-
- btwrite(whitecrush_upper, BT848_WC_UP);
- btwrite(whitecrush_lower, BT848_WC_DOWN);
-
- if (btv->opt_lumafilter) {
- btwrite(0, BT848_E_CONTROL);
- btwrite(0, BT848_O_CONTROL);
- } else {
- btwrite(BT848_CONTROL_LDEC, BT848_E_CONTROL);
- btwrite(BT848_CONTROL_LDEC, BT848_O_CONTROL);
- }
-
- bt848_bright(btv, btv->bright);
- bt848_hue(btv, btv->hue);
- bt848_contrast(btv, btv->contrast);
- bt848_sat(btv, btv->saturation);
-
- /* interrupt */
- init_irqreg(btv);
-}
-
-static void bttv_reinit_bt848(struct bttv *btv)
-{
- unsigned long flags;
-
- if (bttv_verbose)
- pr_info("%d: reset, reinitialize\n", btv->c.nr);
- spin_lock_irqsave(&btv->s_lock,flags);
- btv->errors=0;
- bttv_set_dma(btv,0);
- spin_unlock_irqrestore(&btv->s_lock,flags);
-
- init_bt848(btv);
- btv->pll.pll_current = -1;
- set_input(btv, btv->input, btv->tvnorm);
-}
-
-static int bttv_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *c)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
-
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- c->value = btv->bright;
- break;
- case V4L2_CID_HUE:
- c->value = btv->hue;
- break;
- case V4L2_CID_CONTRAST:
- c->value = btv->contrast;
- break;
- case V4L2_CID_SATURATION:
- c->value = btv->saturation;
- break;
-
- case V4L2_CID_AUDIO_MUTE:
- case V4L2_CID_AUDIO_VOLUME:
- case V4L2_CID_AUDIO_BALANCE:
- case V4L2_CID_AUDIO_BASS:
- case V4L2_CID_AUDIO_TREBLE:
- bttv_call_all(btv, core, g_ctrl, c);
- break;
-
- case V4L2_CID_PRIVATE_CHROMA_AGC:
- c->value = btv->opt_chroma_agc;
- break;
- case V4L2_CID_PRIVATE_COMBFILTER:
- c->value = btv->opt_combfilter;
- break;
- case V4L2_CID_PRIVATE_LUMAFILTER:
- c->value = btv->opt_lumafilter;
- break;
- case V4L2_CID_PRIVATE_AUTOMUTE:
- c->value = btv->opt_automute;
- break;
- case V4L2_CID_PRIVATE_AGC_CRUSH:
- c->value = btv->opt_adc_crush;
- break;
- case V4L2_CID_PRIVATE_VCR_HACK:
- c->value = btv->opt_vcr_hack;
- break;
- case V4L2_CID_PRIVATE_WHITECRUSH_UPPER:
- c->value = btv->opt_whitecrush_upper;
- break;
- case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
- c->value = btv->opt_whitecrush_lower;
- break;
- case V4L2_CID_PRIVATE_UV_RATIO:
- c->value = btv->opt_uv_ratio;
- break;
- case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
- c->value = btv->opt_full_luma_range;
- break;
- case V4L2_CID_PRIVATE_CORING:
- c->value = btv->opt_coring;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int bttv_s_ctrl(struct file *file, void *f,
- struct v4l2_control *c)
-{
- int err;
- int val;
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
-
- err = v4l2_prio_check(&btv->prio, fh->prio);
- if (0 != err)
- return err;
-
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- bt848_bright(btv, c->value);
- break;
- case V4L2_CID_HUE:
- bt848_hue(btv, c->value);
- break;
- case V4L2_CID_CONTRAST:
- bt848_contrast(btv, c->value);
- break;
- case V4L2_CID_SATURATION:
- bt848_sat(btv, c->value);
- break;
- case V4L2_CID_AUDIO_MUTE:
- audio_mute(btv, c->value);
- /* fall through */
- case V4L2_CID_AUDIO_VOLUME:
- if (btv->volume_gpio)
- btv->volume_gpio(btv, c->value);
-
- bttv_call_all(btv, core, s_ctrl, c);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- case V4L2_CID_AUDIO_BASS:
- case V4L2_CID_AUDIO_TREBLE:
- bttv_call_all(btv, core, s_ctrl, c);
- break;
-
- case V4L2_CID_PRIVATE_CHROMA_AGC:
- btv->opt_chroma_agc = c->value;
- val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
- btwrite(val, BT848_E_SCLOOP);
- btwrite(val, BT848_O_SCLOOP);
- break;
- case V4L2_CID_PRIVATE_COMBFILTER:
- btv->opt_combfilter = c->value;
- break;
- case V4L2_CID_PRIVATE_LUMAFILTER:
- btv->opt_lumafilter = c->value;
- if (btv->opt_lumafilter) {
- btand(~BT848_CONTROL_LDEC, BT848_E_CONTROL);
- btand(~BT848_CONTROL_LDEC, BT848_O_CONTROL);
- } else {
- btor(BT848_CONTROL_LDEC, BT848_E_CONTROL);
- btor(BT848_CONTROL_LDEC, BT848_O_CONTROL);
- }
- break;
- case V4L2_CID_PRIVATE_AUTOMUTE:
- btv->opt_automute = c->value;
- break;
- case V4L2_CID_PRIVATE_AGC_CRUSH:
- btv->opt_adc_crush = c->value;
- btwrite(BT848_ADC_RESERVED |
- (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
- BT848_ADC);
- break;
- case V4L2_CID_PRIVATE_VCR_HACK:
- btv->opt_vcr_hack = c->value;
- break;
- case V4L2_CID_PRIVATE_WHITECRUSH_UPPER:
- btv->opt_whitecrush_upper = c->value;
- btwrite(c->value, BT848_WC_UP);
- break;
- case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
- btv->opt_whitecrush_lower = c->value;
- btwrite(c->value, BT848_WC_DOWN);
- break;
- case V4L2_CID_PRIVATE_UV_RATIO:
- btv->opt_uv_ratio = c->value;
- bt848_sat(btv, btv->saturation);
- break;
- case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
- btv->opt_full_luma_range = c->value;
- btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM);
- break;
- case V4L2_CID_PRIVATE_CORING:
- btv->opt_coring = c->value;
- btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-void bttv_gpio_tracking(struct bttv *btv, char *comment)
-{
- unsigned int outbits, data;
- outbits = btread(BT848_GPIO_OUT_EN);
- data = btread(BT848_GPIO_DATA);
- pr_debug("%d: gpio: en=%08x, out=%08x in=%08x [%s]\n",
- btv->c.nr, outbits, data & outbits, data & ~outbits, comment);
-}
-
-static void bttv_field_count(struct bttv *btv)
-{
- int need_count = 0;
-
- if (btv->users)
- need_count++;
-
- if (need_count) {
- /* start field counter */
- btor(BT848_INT_VSYNC,BT848_INT_MASK);
- } else {
- /* stop field counter */
- btand(~BT848_INT_VSYNC,BT848_INT_MASK);
- btv->field_count = 0;
- }
-}
-
-static const struct bttv_format*
-format_by_fourcc(int fourcc)
-{
- unsigned int i;
-
- for (i = 0; i < FORMATS; i++) {
- if (-1 == formats[i].fourcc)
- continue;
- if (formats[i].fourcc == fourcc)
- return formats+i;
- }
- return NULL;
-}
-
-/* ----------------------------------------------------------------------- */
-/* misc helpers */
-
-static int
-bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
- struct bttv_buffer *new)
-{
- struct bttv_buffer *old;
- unsigned long flags;
- int retval = 0;
-
- dprintk("switch_overlay: enter [new=%p]\n", new);
- if (new)
- new->vb.state = VIDEOBUF_DONE;
- spin_lock_irqsave(&btv->s_lock,flags);
- old = btv->screen;
- btv->screen = new;
- btv->loop_irq |= 1;
- bttv_set_dma(btv, 0x03);
- spin_unlock_irqrestore(&btv->s_lock,flags);
- if (NULL != old) {
- dprintk("switch_overlay: old=%p state is %d\n",
- old, old->vb.state);
- bttv_dma_free(&fh->cap,btv, old);
- kfree(old);
- }
- if (NULL == new)
- free_btres_lock(btv,fh,RESOURCE_OVERLAY);
- dprintk("switch_overlay: done\n");
- return retval;
-}
-
-/* ----------------------------------------------------------------------- */
-/* video4linux (1) interface */
-
-static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv,
- struct bttv_buffer *buf,
- const struct bttv_format *fmt,
- unsigned int width, unsigned int height,
- enum v4l2_field field)
-{
- struct bttv_fh *fh = q->priv_data;
- int redo_dma_risc = 0;
- struct bttv_crop c;
- int norm;
- int rc;
-
- /* check settings */
- if (NULL == fmt)
- return -EINVAL;
- if (fmt->btformat == BT848_COLOR_FMT_RAW) {
- width = RAW_BPL;
- height = RAW_LINES*2;
- if (width*height > buf->vb.bsize)
- return -EINVAL;
- buf->vb.size = buf->vb.bsize;
-
- /* Make sure tvnorm and vbi_end remain consistent
- until we're done. */
-
- norm = btv->tvnorm;
-
- /* In this mode capturing always starts at defrect.top
- (default VDELAY), ignoring cropping parameters. */
- if (btv->vbi_end > bttv_tvnorms[norm].cropcap.defrect.top) {
- return -EINVAL;
- }
-
- c.rect = bttv_tvnorms[norm].cropcap.defrect;
- } else {
- norm = btv->tvnorm;
- c = btv->crop[!!fh->do_crop];
-
- if (width < c.min_scaled_width ||
- width > c.max_scaled_width ||
- height < c.min_scaled_height)
- return -EINVAL;
-
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- case V4L2_FIELD_ALTERNATE:
- /* btv->crop counts frame lines. Max. scale
- factor is 16:1 for frames, 8:1 for fields. */
- if (height * 2 > c.max_scaled_height)
- return -EINVAL;
- break;
-
- default:
- if (height > c.max_scaled_height)
- return -EINVAL;
- break;
- }
-
- buf->vb.size = (width * height * fmt->depth) >> 3;
- if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
- return -EINVAL;
- }
-
- /* alloc + fill struct bttv_buffer (if changed) */
- if (buf->vb.width != width || buf->vb.height != height ||
- buf->vb.field != field ||
- buf->tvnorm != norm || buf->fmt != fmt ||
- buf->crop.top != c.rect.top ||
- buf->crop.left != c.rect.left ||
- buf->crop.width != c.rect.width ||
- buf->crop.height != c.rect.height) {
- buf->vb.width = width;
- buf->vb.height = height;
- buf->vb.field = field;
- buf->tvnorm = norm;
- buf->fmt = fmt;
- buf->crop = c.rect;
- redo_dma_risc = 1;
- }
-
- /* alloc risc memory */
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- redo_dma_risc = 1;
- if (0 != (rc = videobuf_iolock(q,&buf->vb,&btv->fbuf)))
- goto fail;
- }
-
- if (redo_dma_risc)
- if (0 != (rc = bttv_buffer_risc(btv,buf)))
- goto fail;
-
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
- fail:
- bttv_dma_free(q,btv,buf);
- return rc;
-}
-
-static int
-buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
-{
- struct bttv_fh *fh = q->priv_data;
-
- *size = fh->fmt->depth*fh->width*fh->height >> 3;
- if (0 == *count)
- *count = gbuffers;
- if (*size * *count > gbuffers * gbufsize)
- *count = (gbuffers * gbufsize) / *size;
- return 0;
-}
-
-static int
-buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
- struct bttv_fh *fh = q->priv_data;
-
- return bttv_prepare_buffer(q,fh->btv, buf, fh->fmt,
- fh->width, fh->height, field);
-}
-
-static void
-buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
- struct bttv_fh *fh = q->priv_data;
- struct bttv *btv = fh->btv;
-
- buf->vb.state = VIDEOBUF_QUEUED;
- list_add_tail(&buf->vb.queue,&btv->capture);
- if (!btv->curr.frame_irq) {
- btv->loop_irq |= 1;
- bttv_set_dma(btv, 0x03);
- }
-}
-
-static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
- struct bttv_fh *fh = q->priv_data;
-
- bttv_dma_free(q,fh->btv,buf);
-}
-
-static struct videobuf_queue_ops bttv_video_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
- unsigned int i;
- int err;
-
- err = v4l2_prio_check(&btv->prio, fh->prio);
- if (err)
- goto err;
-
- for (i = 0; i < BTTV_TVNORMS; i++)
- if (*id & bttv_tvnorms[i].v4l2_id)
- break;
- if (i == BTTV_TVNORMS) {
- err = -EINVAL;
- goto err;
- }
-
- set_tvnorm(btv, i);
-
-err:
-
- return err;
-}
-
-static int bttv_querystd(struct file *file, void *f, v4l2_std_id *id)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
-
- if (btread(BT848_DSTATUS) & BT848_DSTATUS_NUML)
- *id = V4L2_STD_625_50;
- else
- *id = V4L2_STD_525_60;
- return 0;
-}
-
-static int bttv_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
- int rc = 0;
-
- if (i->index >= bttv_tvcards[btv->c.type].video_inputs) {
- rc = -EINVAL;
- goto err;
- }
-
- i->type = V4L2_INPUT_TYPE_CAMERA;
- i->audioset = 1;
-
- if (btv->tuner_type != TUNER_ABSENT && i->index == 0) {
- sprintf(i->name, "Television");
- i->type = V4L2_INPUT_TYPE_TUNER;
- i->tuner = 0;
- } else if (i->index == btv->svhs) {
- sprintf(i->name, "S-Video");
- } else {
- sprintf(i->name, "Composite%d", i->index);
- }
-
- if (i->index == btv->input) {
- __u32 dstatus = btread(BT848_DSTATUS);
- if (0 == (dstatus & BT848_DSTATUS_PRES))
- i->status |= V4L2_IN_ST_NO_SIGNAL;
- if (0 == (dstatus & BT848_DSTATUS_HLOC))
- i->status |= V4L2_IN_ST_NO_H_LOCK;
- }
-
- i->std = BTTV_NORMS;
-
-err:
-
- return rc;
-}
-
-static int bttv_g_input(struct file *file, void *priv, unsigned int *i)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
-
- *i = btv->input;
-
- return 0;
-}
-
-static int bttv_s_input(struct file *file, void *priv, unsigned int i)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
-
- int err;
-
- err = v4l2_prio_check(&btv->prio, fh->prio);
- if (unlikely(err))
- goto err;
-
- if (i > bttv_tvcards[btv->c.type].video_inputs) {
- err = -EINVAL;
- goto err;
- }
-
- set_input(btv, i, btv->tvnorm);
-
-err:
- return 0;
-}
-
-static int bttv_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
- int err;
-
- if (unlikely(0 != t->index))
- return -EINVAL;
-
- if (unlikely(btv->tuner_type == TUNER_ABSENT)) {
- err = -EINVAL;
- goto err;
- }
-
- err = v4l2_prio_check(&btv->prio, fh->prio);
- if (unlikely(err))
- goto err;
-
- bttv_call_all(btv, tuner, s_tuner, t);
-
- if (btv->audio_mode_gpio)
- btv->audio_mode_gpio(btv, t, 1);
-
-err:
-
- return 0;
-}
-
-static int bttv_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
-
- f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- f->frequency = btv->freq;
-
- return 0;
-}
-
-static int bttv_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
- int err;
-
- if (unlikely(f->tuner != 0))
- return -EINVAL;
-
- err = v4l2_prio_check(&btv->prio, fh->prio);
- if (unlikely(err))
- goto err;
-
- if (unlikely(f->type != (btv->radio_user
- ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV))) {
- err = -EINVAL;
- goto err;
- }
- btv->freq = f->frequency;
- bttv_call_all(btv, tuner, s_frequency, f);
- if (btv->has_matchbox && btv->radio_user)
- tea5757_set_freq(btv, btv->freq);
-err:
-
- return 0;
-}
-
-static int bttv_log_status(struct file *file, void *f)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
-
- bttv_call_all(btv, core, log_status);
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int bttv_g_register(struct file *file, void *f,
- struct v4l2_dbg_register *reg)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- if (!v4l2_chip_match_host(&reg->match))
- return -EINVAL;
-
- /* bt848 has a 12-bit register space */
- reg->reg &= 0xfff;
- reg->val = btread(reg->reg);
- reg->size = 1;
-
- return 0;
-}
-
-static int bttv_s_register(struct file *file, void *f,
- struct v4l2_dbg_register *reg)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- if (!v4l2_chip_match_host(&reg->match))
- return -EINVAL;
-
- /* bt848 has a 12-bit register space */
- reg->reg &= 0xfff;
- btwrite(reg->val, reg->reg);
-
- return 0;
-}
-#endif
-
-/* Given cropping boundaries b and the scaled width and height of a
- single field or frame, which must not exceed hardware limits, this
- function adjusts the cropping parameters c. */
-static void
-bttv_crop_adjust (struct bttv_crop * c,
- const struct v4l2_rect * b,
- __s32 width,
- __s32 height,
- enum v4l2_field field)
-{
- __s32 frame_height = height << !V4L2_FIELD_HAS_BOTH(field);
- __s32 max_left;
- __s32 max_top;
-
- if (width < c->min_scaled_width) {
- /* Max. hor. scale factor 16:1. */
- c->rect.width = width * 16;
- } else if (width > c->max_scaled_width) {
- /* Min. hor. scale factor 1:1. */
- c->rect.width = width;
-
- max_left = b->left + b->width - width;
- max_left = min(max_left, (__s32) MAX_HDELAY);
- if (c->rect.left > max_left)
- c->rect.left = max_left;
- }
-
- if (height < c->min_scaled_height) {
- /* Max. vert. scale factor 16:1, single fields 8:1. */
- c->rect.height = height * 16;
- } else if (frame_height > c->max_scaled_height) {
- /* Min. vert. scale factor 1:1.
- Top and height count field lines times two. */
- c->rect.height = (frame_height + 1) & ~1;
-
- max_top = b->top + b->height - c->rect.height;
- if (c->rect.top > max_top)
- c->rect.top = max_top;
- }
-
- bttv_crop_calc_limits(c);
-}
-
-/* Returns an error if scaling to a frame or single field with the given
- width and height is not possible with the current cropping parameters
- and width aligned according to width_mask. If adjust_size is TRUE the
- function may adjust the width and/or height instead, rounding width
- to (width + width_bias) & width_mask. If adjust_crop is TRUE it may
- also adjust the current cropping parameters to get closer to the
- desired image size. */
-static int
-limit_scaled_size_lock (struct bttv_fh * fh,
- __s32 * width,
- __s32 * height,
- enum v4l2_field field,
- unsigned int width_mask,
- unsigned int width_bias,
- int adjust_size,
- int adjust_crop)
-{
- struct bttv *btv = fh->btv;
- const struct v4l2_rect *b;
- struct bttv_crop *c;
- __s32 min_width;
- __s32 min_height;
- __s32 max_width;
- __s32 max_height;
- int rc;
-
- BUG_ON((int) width_mask >= 0 ||
- width_bias >= (unsigned int) -width_mask);
-
- /* Make sure tvnorm, vbi_end and the current cropping parameters
- remain consistent until we're done. */
-
- b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds;
-
- /* Do crop - use current, don't - use default parameters. */
- c = &btv->crop[!!fh->do_crop];
-
- if (fh->do_crop
- && adjust_size
- && adjust_crop
- && !locked_btres(btv, VIDEO_RESOURCES)) {
- min_width = 48;
- min_height = 32;
-
- /* We cannot scale up. When the scaled image is larger
- than crop.rect we adjust the crop.rect as required
- by the V4L2 spec, hence cropcap.bounds are our limit. */
- max_width = min(b->width, (__s32) MAX_HACTIVE);
- max_height = b->height;
-
- /* We cannot capture the same line as video and VBI data.
- Note btv->vbi_end is really a minimum, see
- bttv_vbi_try_fmt(). */
- if (btv->vbi_end > b->top) {
- max_height -= btv->vbi_end - b->top;
- rc = -EBUSY;
- if (min_height > max_height)
- goto fail;
- }
- } else {
- rc = -EBUSY;
- if (btv->vbi_end > c->rect.top)
- goto fail;
-
- min_width = c->min_scaled_width;
- min_height = c->min_scaled_height;
- max_width = c->max_scaled_width;
- max_height = c->max_scaled_height;
-
- adjust_crop = 0;
- }
-
- min_width = (min_width - width_mask - 1) & width_mask;
- max_width = max_width & width_mask;
-
- /* Max. scale factor is 16:1 for frames, 8:1 for fields. */
- min_height = min_height;
- /* Min. scale factor is 1:1. */
- max_height >>= !V4L2_FIELD_HAS_BOTH(field);
-
- if (adjust_size) {
- *width = clamp(*width, min_width, max_width);
- *height = clamp(*height, min_height, max_height);
-
- /* Round after clamping to avoid overflow. */
- *width = (*width + width_bias) & width_mask;
-
- if (adjust_crop) {
- bttv_crop_adjust(c, b, *width, *height, field);
-
- if (btv->vbi_end > c->rect.top) {
- /* Move the crop window out of the way. */
- c->rect.top = btv->vbi_end;
- }
- }
- } else {
- rc = -EINVAL;
- if (*width < min_width ||
- *height < min_height ||
- *width > max_width ||
- *height > max_height ||
- 0 != (*width & ~width_mask))
- goto fail;
- }
-
- rc = 0; /* success */
-
- fail:
-
- return rc;
-}
-
-/* Returns an error if the given overlay window dimensions are not
- possible with the current cropping parameters. If adjust_size is
- TRUE the function may adjust the window width and/or height
- instead, however it always rounds the horizontal position and
- width as btcx_align() does. If adjust_crop is TRUE the function
- may also adjust the current cropping parameters to get closer
- to the desired window size. */
-static int
-verify_window_lock (struct bttv_fh * fh,
- struct v4l2_window * win,
- int adjust_size,
- int adjust_crop)
-{
- enum v4l2_field field;
- unsigned int width_mask;
- int rc;
-
- if (win->w.width < 48 || win->w.height < 32)
- return -EINVAL;
- if (win->clipcount > 2048)
- return -EINVAL;
-
- field = win->field;
-
- if (V4L2_FIELD_ANY == field) {
- __s32 height2;
-
- height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1;
- field = (win->w.height > height2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_TOP;
- }
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- case V4L2_FIELD_INTERLACED:
- break;
- default:
- return -EINVAL;
- }
-
- /* 4-byte alignment. */
- if (NULL == fh->ovfmt)
- return -EINVAL;
- width_mask = ~0;
- switch (fh->ovfmt->depth) {
- case 8:
- case 24:
- width_mask = ~3;
- break;
- case 16:
- width_mask = ~1;
- break;
- case 32:
- break;
- default:
- BUG();
- }
-
- win->w.width -= win->w.left & ~width_mask;
- win->w.left = (win->w.left - width_mask - 1) & width_mask;
-
- rc = limit_scaled_size_lock(fh, &win->w.width, &win->w.height,
- field, width_mask,
- /* width_bias: round down */ 0,
- adjust_size, adjust_crop);
- if (0 != rc)
- return rc;
-
- win->field = field;
- return 0;
-}
-
-static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv,
- struct v4l2_window *win, int fixup)
-{
- struct v4l2_clip *clips = NULL;
- int n,size,retval = 0;
-
- if (NULL == fh->ovfmt)
- return -EINVAL;
- if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED))
- return -EINVAL;
- retval = verify_window_lock(fh, win,
- /* adjust_size */ fixup,
- /* adjust_crop */ fixup);
- if (0 != retval)
- return retval;
-
- /* copy clips -- luckily v4l1 + v4l2 are binary
- compatible here ...*/
- n = win->clipcount;
- size = sizeof(*clips)*(n+4);
- clips = kmalloc(size,GFP_KERNEL);
- if (NULL == clips)
- return -ENOMEM;
- if (n > 0) {
- if (copy_from_user(clips,win->clips,sizeof(struct v4l2_clip)*n)) {
- kfree(clips);
- return -EFAULT;
- }
- }
-
- /* clip against screen */
- if (NULL != btv->fbuf.base)
- n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height,
- &win->w, clips, n);
- btcx_sort_clips(clips,n);
-
- /* 4-byte alignments */
- switch (fh->ovfmt->depth) {
- case 8:
- case 24:
- btcx_align(&win->w, clips, n, 3);
- break;
- case 16:
- btcx_align(&win->w, clips, n, 1);
- break;
- case 32:
- /* no alignment fixups needed */
- break;
- default:
- BUG();
- }
-
- kfree(fh->ov.clips);
- fh->ov.clips = clips;
- fh->ov.nclips = n;
-
- fh->ov.w = win->w;
- fh->ov.field = win->field;
- fh->ov.setup_ok = 1;
-
- btv->init.ov.w.width = win->w.width;
- btv->init.ov.w.height = win->w.height;
- btv->init.ov.field = win->field;
-
- /* update overlay if needed */
- retval = 0;
- if (check_btres(fh, RESOURCE_OVERLAY)) {
- struct bttv_buffer *new;
-
- new = videobuf_sg_alloc(sizeof(*new));
- new->crop = btv->crop[!!fh->do_crop].rect;
- bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
- retval = bttv_switch_overlay(btv,fh,new);
- }
- return retval;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static struct videobuf_queue* bttv_queue(struct bttv_fh *fh)
-{
- struct videobuf_queue* q = NULL;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- q = &fh->cap;
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- q = &fh->vbi;
- break;
- default:
- BUG();
- }
- return q;
-}
-
-static int bttv_resource(struct bttv_fh *fh)
-{
- int res = 0;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- res = RESOURCE_VIDEO_STREAM;
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- res = RESOURCE_VBI;
- break;
- default:
- BUG();
- }
- return res;
-}
-
-static int bttv_switch_type(struct bttv_fh *fh, enum v4l2_buf_type type)
-{
- struct videobuf_queue *q = bttv_queue(fh);
- int res = bttv_resource(fh);
-
- if (check_btres(fh,res))
- return -EBUSY;
- if (videobuf_queue_is_busy(q))
- return -EBUSY;
- fh->type = type;
- return 0;
-}
-
-static void
-pix_format_set_size (struct v4l2_pix_format * f,
- const struct bttv_format * fmt,
- unsigned int width,
- unsigned int height)
-{
- f->width = width;
- f->height = height;
-
- if (fmt->flags & FORMAT_FLAGS_PLANAR) {
- f->bytesperline = width; /* Y plane */
- f->sizeimage = (width * height * fmt->depth) >> 3;
- } else {
- f->bytesperline = (width * fmt->depth) >> 3;
- f->sizeimage = height * f->bytesperline;
- }
-}
-
-static int bttv_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct bttv_fh *fh = priv;
-
- pix_format_set_size(&f->fmt.pix, fh->fmt,
- fh->width, fh->height);
- f->fmt.pix.field = fh->cap.field;
- f->fmt.pix.pixelformat = fh->fmt->fourcc;
-
- return 0;
-}
-
-static int bttv_g_fmt_vid_overlay(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct bttv_fh *fh = priv;
-
- f->fmt.win.w = fh->ov.w;
- f->fmt.win.field = fh->ov.field;
-
- return 0;
-}
-
-static int bttv_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- const struct bttv_format *fmt;
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
- enum v4l2_field field;
- __s32 width, height;
- int rc;
-
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- if (NULL == fmt)
- return -EINVAL;
-
- field = f->fmt.pix.field;
-
- if (V4L2_FIELD_ANY == field) {
- __s32 height2;
-
- height2 = btv->crop[!!fh->do_crop].rect.height >> 1;
- field = (f->fmt.pix.height > height2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_BOTTOM;
- }
-
- if (V4L2_FIELD_SEQ_BT == field)
- field = V4L2_FIELD_SEQ_TB;
-
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- case V4L2_FIELD_ALTERNATE:
- case V4L2_FIELD_INTERLACED:
- break;
- case V4L2_FIELD_SEQ_TB:
- if (fmt->flags & FORMAT_FLAGS_PLANAR)
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
-
- width = f->fmt.pix.width;
- height = f->fmt.pix.height;
-
- rc = limit_scaled_size_lock(fh, &width, &height, field,
- /* width_mask: 4 pixels */ ~3,
- /* width_bias: nearest */ 2,
- /* adjust_size */ 1,
- /* adjust_crop */ 0);
- if (0 != rc)
- return rc;
-
- /* update data for the application */
- f->fmt.pix.field = field;
- pix_format_set_size(&f->fmt.pix, fmt, width, height);
-
- return 0;
-}
-
-static int bttv_try_fmt_vid_overlay(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct bttv_fh *fh = priv;
-
- return verify_window_lock(fh, &f->fmt.win,
- /* adjust_size */ 1,
- /* adjust_crop */ 0);
-}
-
-static int bttv_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- int retval;
- const struct bttv_format *fmt;
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
- __s32 width, height;
- enum v4l2_field field;
-
- retval = bttv_switch_type(fh, f->type);
- if (0 != retval)
- return retval;
-
- retval = bttv_try_fmt_vid_cap(file, priv, f);
- if (0 != retval)
- return retval;
-
- width = f->fmt.pix.width;
- height = f->fmt.pix.height;
- field = f->fmt.pix.field;
-
- retval = limit_scaled_size_lock(fh, &width, &height, f->fmt.pix.field,
- /* width_mask: 4 pixels */ ~3,
- /* width_bias: nearest */ 2,
- /* adjust_size */ 1,
- /* adjust_crop */ 1);
- if (0 != retval)
- return retval;
-
- f->fmt.pix.field = field;
-
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
-
- /* update our state informations */
- fh->fmt = fmt;
- fh->cap.field = f->fmt.pix.field;
- fh->cap.last = V4L2_FIELD_NONE;
- fh->width = f->fmt.pix.width;
- fh->height = f->fmt.pix.height;
- btv->init.fmt = fmt;
- btv->init.width = f->fmt.pix.width;
- btv->init.height = f->fmt.pix.height;
-
- return 0;
-}
-
-static int bttv_s_fmt_vid_overlay(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
-
- if (no_overlay > 0) {
- pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
- return -EINVAL;
- }
-
- return setup_window_lock(fh, btv, &f->fmt.win, 1);
-}
-
-static int bttv_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
-
- if (0 == v4l2)
- return -EINVAL;
-
- strlcpy(cap->driver, "bttv", sizeof(cap->driver));
- strlcpy(cap->card, btv->video_dev->name, sizeof(cap->card));
- snprintf(cap->bus_info, sizeof(cap->bus_info),
- "PCI:%s", pci_name(btv->c.pci));
- cap->capabilities =
- V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_VBI_CAPTURE |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING;
- if (no_overlay <= 0)
- cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
-
- /*
- * No need to lock here: those vars are initialized during board
- * probe and remains untouched during the rest of the driver lifecycle
- */
- if (btv->has_saa6588)
- cap->capabilities |= V4L2_CAP_RDS_CAPTURE;
- if (btv->tuner_type != TUNER_ABSENT)
- cap->capabilities |= V4L2_CAP_TUNER;
- return 0;
-}
-
-static int bttv_enum_fmt_cap_ovr(struct v4l2_fmtdesc *f)
-{
- int index = -1, i;
-
- for (i = 0; i < FORMATS; i++) {
- if (formats[i].fourcc != -1)
- index++;
- if ((unsigned int)index == f->index)
- break;
- }
- if (FORMATS == i)
- return -EINVAL;
-
- f->pixelformat = formats[i].fourcc;
- strlcpy(f->description, formats[i].name, sizeof(f->description));
-
- return i;
-}
-
-static int bttv_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- int rc = bttv_enum_fmt_cap_ovr(f);
-
- if (rc < 0)
- return rc;
-
- return 0;
-}
-
-static int bttv_enum_fmt_vid_overlay(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- int rc;
-
- if (no_overlay > 0) {
- pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
- return -EINVAL;
- }
-
- rc = bttv_enum_fmt_cap_ovr(f);
-
- if (rc < 0)
- return rc;
-
- if (!(formats[rc].flags & FORMAT_FLAGS_PACKED))
- return -EINVAL;
-
- return 0;
-}
-
-static int bttv_g_fbuf(struct file *file, void *f,
- struct v4l2_framebuffer *fb)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
-
- *fb = btv->fbuf;
- fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
- if (fh->ovfmt)
- fb->fmt.pixelformat = fh->ovfmt->fourcc;
- return 0;
-}
-
-static int bttv_overlay(struct file *file, void *f, unsigned int on)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
- struct bttv_buffer *new;
- int retval = 0;
-
- if (on) {
- /* verify args */
- if (unlikely(!btv->fbuf.base)) {
- return -EINVAL;
- }
- if (unlikely(!fh->ov.setup_ok)) {
- dprintk("%d: overlay: !setup_ok\n", btv->c.nr);
- retval = -EINVAL;
- }
- if (retval)
- return retval;
- }
-
- if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY))
- return -EBUSY;
-
- if (on) {
- fh->ov.tvnorm = btv->tvnorm;
- new = videobuf_sg_alloc(sizeof(*new));
- new->crop = btv->crop[!!fh->do_crop].rect;
- bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
- } else {
- new = NULL;
- }
-
- /* switch over */
- retval = bttv_switch_overlay(btv, fh, new);
- return retval;
-}
-
-static int bttv_s_fbuf(struct file *file, void *f,
- struct v4l2_framebuffer *fb)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
- const struct bttv_format *fmt;
- int retval;
-
- if (!capable(CAP_SYS_ADMIN) &&
- !capable(CAP_SYS_RAWIO))
- return -EPERM;
-
- /* check args */
- fmt = format_by_fourcc(fb->fmt.pixelformat);
- if (NULL == fmt)
- return -EINVAL;
- if (0 == (fmt->flags & FORMAT_FLAGS_PACKED))
- return -EINVAL;
-
- retval = -EINVAL;
- if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
- __s32 width = fb->fmt.width;
- __s32 height = fb->fmt.height;
-
- retval = limit_scaled_size_lock(fh, &width, &height,
- V4L2_FIELD_INTERLACED,
- /* width_mask */ ~3,
- /* width_bias */ 2,
- /* adjust_size */ 0,
- /* adjust_crop */ 0);
- if (0 != retval)
- return retval;
- }
-
- /* ok, accept it */
- btv->fbuf.base = fb->base;
- btv->fbuf.fmt.width = fb->fmt.width;
- btv->fbuf.fmt.height = fb->fmt.height;
- if (0 != fb->fmt.bytesperline)
- btv->fbuf.fmt.bytesperline = fb->fmt.bytesperline;
- else
- btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fmt->depth/8;
-
- retval = 0;
- fh->ovfmt = fmt;
- btv->init.ovfmt = fmt;
- if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
- fh->ov.w.left = 0;
- fh->ov.w.top = 0;
- fh->ov.w.width = fb->fmt.width;
- fh->ov.w.height = fb->fmt.height;
- btv->init.ov.w.width = fb->fmt.width;
- btv->init.ov.w.height = fb->fmt.height;
- kfree(fh->ov.clips);
- fh->ov.clips = NULL;
- fh->ov.nclips = 0;
-
- if (check_btres(fh, RESOURCE_OVERLAY)) {
- struct bttv_buffer *new;
-
- new = videobuf_sg_alloc(sizeof(*new));
- new->crop = btv->crop[!!fh->do_crop].rect;
- bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
- retval = bttv_switch_overlay(btv, fh, new);
- }
- }
- return retval;
-}
-
-static int bttv_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct bttv_fh *fh = priv;
- return videobuf_reqbufs(bttv_queue(fh), p);
-}
-
-static int bttv_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct bttv_fh *fh = priv;
- return videobuf_querybuf(bttv_queue(fh), b);
-}
-
-static int bttv_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
- int res = bttv_resource(fh);
-
- if (!check_alloc_btres_lock(btv, fh, res))
- return -EBUSY;
-
- return videobuf_qbuf(bttv_queue(fh), b);
-}
-
-static int bttv_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct bttv_fh *fh = priv;
- return videobuf_dqbuf(bttv_queue(fh), b,
- file->f_flags & O_NONBLOCK);
-}
-
-static int bttv_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
- int res = bttv_resource(fh);
-
- if (!check_alloc_btres_lock(btv, fh, res))
- return -EBUSY;
- return videobuf_streamon(bttv_queue(fh));
-}
-
-
-static int bttv_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
- int retval;
- int res = bttv_resource(fh);
-
-
- retval = videobuf_streamoff(bttv_queue(fh));
- if (retval < 0)
- return retval;
- free_btres_lock(btv, fh, res);
- return 0;
-}
-
-static int bttv_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *c)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
- const struct v4l2_queryctrl *ctrl;
-
- if ((c->id < V4L2_CID_BASE ||
- c->id >= V4L2_CID_LASTP1) &&
- (c->id < V4L2_CID_PRIVATE_BASE ||
- c->id >= V4L2_CID_PRIVATE_LASTP1))
- return -EINVAL;
-
- if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME))
- *c = no_ctl;
- else {
- ctrl = ctrl_by_id(c->id);
-
- *c = (NULL != ctrl) ? *ctrl : no_ctl;
- }
-
- return 0;
-}
-
-static int bttv_g_parm(struct file *file, void *f,
- struct v4l2_streamparm *parm)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
-
- v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id,
- &parm->parm.capture.timeperframe);
-
- return 0;
-}
-
-static int bttv_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
-
- if (btv->tuner_type == TUNER_ABSENT)
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
-
- t->rxsubchans = V4L2_TUNER_SUB_MONO;
- bttv_call_all(btv, tuner, g_tuner, t);
- strcpy(t->name, "Television");
- t->capability = V4L2_TUNER_CAP_NORM;
- t->type = V4L2_TUNER_ANALOG_TV;
- if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC)
- t->signal = 0xffff;
-
- if (btv->audio_mode_gpio)
- btv->audio_mode_gpio(btv, t, 0);
-
- return 0;
-}
-
-static int bttv_g_priority(struct file *file, void *f, enum v4l2_priority *p)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
-
- *p = v4l2_prio_max(&btv->prio);
-
- return 0;
-}
-
-static int bttv_s_priority(struct file *file, void *f,
- enum v4l2_priority prio)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
- int rc;
-
- rc = v4l2_prio_change(&btv->prio, &fh->prio, prio);
-
- return rc;
-}
-
-static int bttv_cropcap(struct file *file, void *priv,
- struct v4l2_cropcap *cap)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
-
- if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
- cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
- return -EINVAL;
-
- *cap = bttv_tvnorms[btv->tvnorm].cropcap;
-
- return 0;
-}
-
-static int bttv_g_crop(struct file *file, void *f, struct v4l2_crop *crop)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
- crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
- return -EINVAL;
-
- /* No fh->do_crop = 1; because btv->crop[1] may be
- inconsistent with fh->width or fh->height and apps
- do not expect a change here. */
-
- crop->c = btv->crop[!!fh->do_crop].rect;
-
- return 0;
-}
-
-static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
- const struct v4l2_rect *b;
- int retval;
- struct bttv_crop c;
- __s32 b_left;
- __s32 b_top;
- __s32 b_right;
- __s32 b_bottom;
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
- crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
- return -EINVAL;
-
- /* Make sure tvnorm, vbi_end and the current cropping
- parameters remain consistent until we're done. Note
- read() may change vbi_end in check_alloc_btres_lock(). */
- retval = v4l2_prio_check(&btv->prio, fh->prio);
- if (0 != retval) {
- return retval;
- }
-
- retval = -EBUSY;
-
- if (locked_btres(fh->btv, VIDEO_RESOURCES)) {
- return retval;
- }
-
- b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds;
-
- b_left = b->left;
- b_right = b_left + b->width;
- b_bottom = b->top + b->height;
-
- b_top = max(b->top, btv->vbi_end);
- if (b_top + 32 >= b_bottom) {
- return retval;
- }
-
- /* Min. scaled size 48 x 32. */
- c.rect.left = clamp(crop->c.left, b_left, b_right - 48);
- c.rect.left = min(c.rect.left, (__s32) MAX_HDELAY);
-
- c.rect.width = clamp(crop->c.width,
- 48, b_right - c.rect.left);
-
- c.rect.top = clamp(crop->c.top, b_top, b_bottom - 32);
- /* Top and height must be a multiple of two. */
- c.rect.top = (c.rect.top + 1) & ~1;
-
- c.rect.height = clamp(crop->c.height,
- 32, b_bottom - c.rect.top);
- c.rect.height = (c.rect.height + 1) & ~1;
-
- bttv_crop_calc_limits(&c);
-
- btv->crop[1] = c;
-
- fh->do_crop = 1;
-
- if (fh->width < c.min_scaled_width) {
- fh->width = c.min_scaled_width;
- btv->init.width = c.min_scaled_width;
- } else if (fh->width > c.max_scaled_width) {
- fh->width = c.max_scaled_width;
- btv->init.width = c.max_scaled_width;
- }
-
- if (fh->height < c.min_scaled_height) {
- fh->height = c.min_scaled_height;
- btv->init.height = c.min_scaled_height;
- } else if (fh->height > c.max_scaled_height) {
- fh->height = c.max_scaled_height;
- btv->init.height = c.max_scaled_height;
- }
-
- return 0;
-}
-
-static int bttv_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- if (unlikely(a->index))
- return -EINVAL;
-
- strcpy(a->name, "audio");
- return 0;
-}
-
-static int bttv_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- if (unlikely(a->index))
- return -EINVAL;
-
- return 0;
-}
-
-static ssize_t bttv_read(struct file *file, char __user *data,
- size_t count, loff_t *ppos)
-{
- struct bttv_fh *fh = file->private_data;
- int retval = 0;
-
- if (fh->btv->errors)
- bttv_reinit_bt848(fh->btv);
- dprintk("%d: read count=%d type=%s\n",
- fh->btv->c.nr, (int)count, v4l2_type_names[fh->type]);
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (!check_alloc_btres_lock(fh->btv, fh, RESOURCE_VIDEO_READ)) {
- /* VIDEO_READ in use by another fh,
- or VIDEO_STREAM by any fh. */
- return -EBUSY;
- }
- retval = videobuf_read_one(&fh->cap, data, count, ppos,
- file->f_flags & O_NONBLOCK);
- free_btres_lock(fh->btv, fh, RESOURCE_VIDEO_READ);
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (!check_alloc_btres_lock(fh->btv,fh,RESOURCE_VBI))
- return -EBUSY;
- retval = videobuf_read_stream(&fh->vbi, data, count, ppos, 1,
- file->f_flags & O_NONBLOCK);
- break;
- default:
- BUG();
- }
- return retval;
-}
-
-static unsigned int bttv_poll(struct file *file, poll_table *wait)
-{
- struct bttv_fh *fh = file->private_data;
- struct bttv_buffer *buf;
- enum v4l2_field field;
- unsigned int rc = POLLERR;
-
- if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
- if (!check_alloc_btres_lock(fh->btv,fh,RESOURCE_VBI))
- return POLLERR;
- return videobuf_poll_stream(file, &fh->vbi, wait);
- }
-
- if (check_btres(fh,RESOURCE_VIDEO_STREAM)) {
- /* streaming capture */
- if (list_empty(&fh->cap.stream))
- goto err;
- buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
- } else {
- /* read() capture */
- if (NULL == fh->cap.read_buf) {
- /* need to capture a new frame */
- if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM))
- goto err;
- fh->cap.read_buf = videobuf_sg_alloc(fh->cap.msize);
- if (NULL == fh->cap.read_buf)
- goto err;
- fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
- field = videobuf_next_field(&fh->cap);
- if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {
- kfree (fh->cap.read_buf);
- fh->cap.read_buf = NULL;
- goto err;
- }
- fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
- fh->cap.read_off = 0;
- }
- buf = (struct bttv_buffer*)fh->cap.read_buf;
- }
-
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE ||
- buf->vb.state == VIDEOBUF_ERROR)
- rc = POLLIN|POLLRDNORM;
- else
- rc = 0;
-err:
- return rc;
-}
-
-static int bttv_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct bttv *btv = video_drvdata(file);
- struct bttv_fh *fh;
- enum v4l2_buf_type type = 0;
-
- dprintk("open dev=%s\n", video_device_node_name(vdev));
-
- if (vdev->vfl_type == VFL_TYPE_GRABBER) {
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- } else if (vdev->vfl_type == VFL_TYPE_VBI) {
- type = V4L2_BUF_TYPE_VBI_CAPTURE;
- } else {
- WARN_ON(1);
- return -ENODEV;
- }
-
- dprintk("%d: open called (type=%s)\n",
- btv->c.nr, v4l2_type_names[type]);
-
- /* allocate per filehandle data */
- fh = kmalloc(sizeof(*fh), GFP_KERNEL);
- if (unlikely(!fh))
- return -ENOMEM;
- file->private_data = fh;
-
- *fh = btv->init;
-
- fh->type = type;
- fh->ov.setup_ok = 0;
-
- v4l2_prio_open(&btv->prio, &fh->prio);
-
- videobuf_queue_sg_init(&fh->cap, &bttv_video_qops,
- &btv->c.pci->dev, &btv->s_lock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct bttv_buffer),
- fh, &btv->lock);
- videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops,
- &btv->c.pci->dev, &btv->s_lock,
- V4L2_BUF_TYPE_VBI_CAPTURE,
- V4L2_FIELD_SEQ_TB,
- sizeof(struct bttv_buffer),
- fh, &btv->lock);
- set_tvnorm(btv,btv->tvnorm);
- set_input(btv, btv->input, btv->tvnorm);
-
- btv->users++;
-
- /* The V4L2 spec requires one global set of cropping parameters
- which only change on request. These are stored in btv->crop[1].
- However for compatibility with V4L apps and cropping unaware
- V4L2 apps we now reset the cropping parameters as seen through
- this fh, which is to say VIDIOC_G_CROP and scaling limit checks
- will use btv->crop[0], the default cropping parameters for the
- current video standard, and VIDIOC_S_FMT will not implicitely
- change the cropping parameters until VIDIOC_S_CROP has been
- called. */
- fh->do_crop = !reset_crop; /* module parameter */
-
- /* Likewise there should be one global set of VBI capture
- parameters, but for compatibility with V4L apps and earlier
- driver versions each fh has its own parameters. */
- bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm);
-
- bttv_field_count(btv);
- return 0;
-}
-
-static int bttv_release(struct file *file)
-{
- struct bttv_fh *fh = file->private_data;
- struct bttv *btv = fh->btv;
-
- /* turn off overlay */
- if (check_btres(fh, RESOURCE_OVERLAY))
- bttv_switch_overlay(btv,fh,NULL);
-
- /* stop video capture */
- if (check_btres(fh, RESOURCE_VIDEO_STREAM)) {
- videobuf_streamoff(&fh->cap);
- free_btres_lock(btv,fh,RESOURCE_VIDEO_STREAM);
- }
- if (fh->cap.read_buf) {
- buffer_release(&fh->cap,fh->cap.read_buf);
- kfree(fh->cap.read_buf);
- }
- if (check_btres(fh, RESOURCE_VIDEO_READ)) {
- free_btres_lock(btv, fh, RESOURCE_VIDEO_READ);
- }
-
- /* stop vbi capture */
- if (check_btres(fh, RESOURCE_VBI)) {
- videobuf_stop(&fh->vbi);
- free_btres_lock(btv,fh,RESOURCE_VBI);
- }
-
- /* free stuff */
-
- videobuf_mmap_free(&fh->cap);
- videobuf_mmap_free(&fh->vbi);
- v4l2_prio_close(&btv->prio, fh->prio);
- file->private_data = NULL;
- kfree(fh);
-
- btv->users--;
- bttv_field_count(btv);
-
- if (!btv->users)
- audio_mute(btv, 1);
-
- return 0;
-}
-
-static int
-bttv_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct bttv_fh *fh = file->private_data;
-
- dprintk("%d: mmap type=%s 0x%lx+%ld\n",
- fh->btv->c.nr, v4l2_type_names[fh->type],
- vma->vm_start, vma->vm_end - vma->vm_start);
- return videobuf_mmap_mapper(bttv_queue(fh),vma);
-}
-
-static const struct v4l2_file_operations bttv_fops =
-{
- .owner = THIS_MODULE,
- .open = bttv_open,
- .release = bttv_release,
- .unlocked_ioctl = video_ioctl2,
- .read = bttv_read,
- .mmap = bttv_mmap,
- .poll = bttv_poll,
-};
-
-static const struct v4l2_ioctl_ops bttv_ioctl_ops = {
- .vidioc_querycap = bttv_querycap,
- .vidioc_enum_fmt_vid_cap = bttv_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = bttv_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = bttv_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = bttv_s_fmt_vid_cap,
- .vidioc_enum_fmt_vid_overlay = bttv_enum_fmt_vid_overlay,
- .vidioc_g_fmt_vid_overlay = bttv_g_fmt_vid_overlay,
- .vidioc_try_fmt_vid_overlay = bttv_try_fmt_vid_overlay,
- .vidioc_s_fmt_vid_overlay = bttv_s_fmt_vid_overlay,
- .vidioc_g_fmt_vbi_cap = bttv_g_fmt_vbi_cap,
- .vidioc_try_fmt_vbi_cap = bttv_try_fmt_vbi_cap,
- .vidioc_s_fmt_vbi_cap = bttv_s_fmt_vbi_cap,
- .vidioc_g_audio = bttv_g_audio,
- .vidioc_s_audio = bttv_s_audio,
- .vidioc_cropcap = bttv_cropcap,
- .vidioc_reqbufs = bttv_reqbufs,
- .vidioc_querybuf = bttv_querybuf,
- .vidioc_qbuf = bttv_qbuf,
- .vidioc_dqbuf = bttv_dqbuf,
- .vidioc_s_std = bttv_s_std,
- .vidioc_enum_input = bttv_enum_input,
- .vidioc_g_input = bttv_g_input,
- .vidioc_s_input = bttv_s_input,
- .vidioc_queryctrl = bttv_queryctrl,
- .vidioc_g_ctrl = bttv_g_ctrl,
- .vidioc_s_ctrl = bttv_s_ctrl,
- .vidioc_streamon = bttv_streamon,
- .vidioc_streamoff = bttv_streamoff,
- .vidioc_g_tuner = bttv_g_tuner,
- .vidioc_s_tuner = bttv_s_tuner,
- .vidioc_g_crop = bttv_g_crop,
- .vidioc_s_crop = bttv_s_crop,
- .vidioc_g_fbuf = bttv_g_fbuf,
- .vidioc_s_fbuf = bttv_s_fbuf,
- .vidioc_overlay = bttv_overlay,
- .vidioc_g_priority = bttv_g_priority,
- .vidioc_s_priority = bttv_s_priority,
- .vidioc_g_parm = bttv_g_parm,
- .vidioc_g_frequency = bttv_g_frequency,
- .vidioc_s_frequency = bttv_s_frequency,
- .vidioc_log_status = bttv_log_status,
- .vidioc_querystd = bttv_querystd,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = bttv_g_register,
- .vidioc_s_register = bttv_s_register,
-#endif
-};
-
-static struct video_device bttv_video_template = {
- .fops = &bttv_fops,
- .ioctl_ops = &bttv_ioctl_ops,
- .tvnorms = BTTV_NORMS,
- .current_norm = V4L2_STD_PAL,
-};
-
-/* ----------------------------------------------------------------------- */
-/* radio interface */
-
-static int radio_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct bttv *btv = video_drvdata(file);
- struct bttv_fh *fh;
-
- dprintk("open dev=%s\n", video_device_node_name(vdev));
-
- dprintk("%d: open called (radio)\n", btv->c.nr);
-
- /* allocate per filehandle data */
- fh = kmalloc(sizeof(*fh), GFP_KERNEL);
- if (unlikely(!fh))
- return -ENOMEM;
- file->private_data = fh;
- *fh = btv->init;
-
- v4l2_prio_open(&btv->prio, &fh->prio);
-
- btv->radio_user++;
-
- bttv_call_all(btv, tuner, s_radio);
- audio_input(btv,TVAUDIO_INPUT_RADIO);
-
- return 0;
-}
-
-static int radio_release(struct file *file)
-{
- struct bttv_fh *fh = file->private_data;
- struct bttv *btv = fh->btv;
- struct saa6588_command cmd;
-
- v4l2_prio_close(&btv->prio, fh->prio);
- file->private_data = NULL;
- kfree(fh);
-
- btv->radio_user--;
-
- bttv_call_all(btv, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
-
- return 0;
-}
-
-static int radio_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
-
- strcpy(cap->driver, "bttv");
- strlcpy(cap->card, btv->radio_dev->name, sizeof(cap->card));
- sprintf(cap->bus_info, "PCI:%s", pci_name(btv->c.pci));
- cap->capabilities = V4L2_CAP_TUNER;
-
- return 0;
-}
-
-static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
-
- if (btv->tuner_type == TUNER_ABSENT)
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
- strcpy(t->name, "Radio");
- t->type = V4L2_TUNER_RADIO;
-
- bttv_call_all(btv, tuner, g_tuner, t);
-
- if (btv->audio_mode_gpio)
- btv->audio_mode_gpio(btv, t, 0);
-
- return 0;
-}
-
-static int radio_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- if (i->index != 0)
- return -EINVAL;
-
- strcpy(i->name, "Radio");
- i->type = V4L2_INPUT_TYPE_TUNER;
-
- return 0;
-}
-
-static int radio_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (unlikely(a->index))
- return -EINVAL;
-
- strcpy(a->name, "Radio");
-
- return 0;
-}
-
-static int radio_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct bttv_fh *fh = priv;
- struct bttv *btv = fh->btv;
-
- if (0 != t->index)
- return -EINVAL;
-
- bttv_call_all(btv, tuner, s_tuner, t);
- return 0;
-}
-
-static int radio_s_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (unlikely(a->index))
- return -EINVAL;
-
- return 0;
-}
-
-static int radio_s_input(struct file *filp, void *priv, unsigned int i)
-{
- if (unlikely(i))
- return -EINVAL;
-
- return 0;
-}
-
-static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm)
-{
- return 0;
-}
-
-static int radio_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *c)
-{
- const struct v4l2_queryctrl *ctrl;
-
- if (c->id < V4L2_CID_BASE ||
- c->id >= V4L2_CID_LASTP1)
- return -EINVAL;
-
- if (c->id == V4L2_CID_AUDIO_MUTE) {
- ctrl = ctrl_by_id(c->id);
- *c = *ctrl;
- } else
- *c = no_ctl;
-
- return 0;
-}
-
-static int radio_g_input(struct file *filp, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static ssize_t radio_read(struct file *file, char __user *data,
- size_t count, loff_t *ppos)
-{
- struct bttv_fh *fh = file->private_data;
- struct bttv *btv = fh->btv;
- struct saa6588_command cmd;
- cmd.block_count = count/3;
- cmd.buffer = data;
- cmd.instance = file;
- cmd.result = -ENODEV;
-
- bttv_call_all(btv, core, ioctl, SAA6588_CMD_READ, &cmd);
-
- return cmd.result;
-}
-
-static unsigned int radio_poll(struct file *file, poll_table *wait)
-{
- struct bttv_fh *fh = file->private_data;
- struct bttv *btv = fh->btv;
- struct saa6588_command cmd;
- cmd.instance = file;
- cmd.event_list = wait;
- cmd.result = -ENODEV;
- bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd);
-
- return cmd.result;
-}
-
-static const struct v4l2_file_operations radio_fops =
-{
- .owner = THIS_MODULE,
- .open = radio_open,
- .read = radio_read,
- .release = radio_release,
- .unlocked_ioctl = video_ioctl2,
- .poll = radio_poll,
-};
-
-static const struct v4l2_ioctl_ops radio_ioctl_ops = {
- .vidioc_querycap = radio_querycap,
- .vidioc_g_tuner = radio_g_tuner,
- .vidioc_enum_input = radio_enum_input,
- .vidioc_g_audio = radio_g_audio,
- .vidioc_s_tuner = radio_s_tuner,
- .vidioc_s_audio = radio_s_audio,
- .vidioc_s_input = radio_s_input,
- .vidioc_s_std = radio_s_std,
- .vidioc_queryctrl = radio_queryctrl,
- .vidioc_g_input = radio_g_input,
- .vidioc_g_ctrl = bttv_g_ctrl,
- .vidioc_s_ctrl = bttv_s_ctrl,
- .vidioc_g_frequency = bttv_g_frequency,
- .vidioc_s_frequency = bttv_s_frequency,
-};
-
-static struct video_device radio_template = {
- .fops = &radio_fops,
- .ioctl_ops = &radio_ioctl_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-/* some debug code */
-
-static int bttv_risc_decode(u32 risc)
-{
- static char *instr[16] = {
- [ BT848_RISC_WRITE >> 28 ] = "write",
- [ BT848_RISC_SKIP >> 28 ] = "skip",
- [ BT848_RISC_WRITEC >> 28 ] = "writec",
- [ BT848_RISC_JUMP >> 28 ] = "jump",
- [ BT848_RISC_SYNC >> 28 ] = "sync",
- [ BT848_RISC_WRITE123 >> 28 ] = "write123",
- [ BT848_RISC_SKIP123 >> 28 ] = "skip123",
- [ BT848_RISC_WRITE1S23 >> 28 ] = "write1s23",
- };
- static int incr[16] = {
- [ BT848_RISC_WRITE >> 28 ] = 2,
- [ BT848_RISC_JUMP >> 28 ] = 2,
- [ BT848_RISC_SYNC >> 28 ] = 2,
- [ BT848_RISC_WRITE123 >> 28 ] = 5,
- [ BT848_RISC_SKIP123 >> 28 ] = 2,
- [ BT848_RISC_WRITE1S23 >> 28 ] = 3,
- };
- static char *bits[] = {
- "be0", "be1", "be2", "be3/resync",
- "set0", "set1", "set2", "set3",
- "clr0", "clr1", "clr2", "clr3",
- "irq", "res", "eol", "sol",
- };
- int i;
-
- pr_cont("0x%08x [ %s", risc,
- instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
- for (i = ARRAY_SIZE(bits)-1; i >= 0; i--)
- if (risc & (1 << (i + 12)))
- pr_cont(" %s", bits[i]);
- pr_cont(" count=%d ]\n", risc & 0xfff);
- return incr[risc >> 28] ? incr[risc >> 28] : 1;
-}
-
-static void bttv_risc_disasm(struct bttv *btv,
- struct btcx_riscmem *risc)
-{
- unsigned int i,j,n;
-
- pr_info("%s: risc disasm: %p [dma=0x%08lx]\n",
- btv->c.v4l2_dev.name, risc->cpu, (unsigned long)risc->dma);
- for (i = 0; i < (risc->size >> 2); i += n) {
- pr_info("%s: 0x%lx: ",
- btv->c.v4l2_dev.name,
- (unsigned long)(risc->dma + (i<<2)));
- n = bttv_risc_decode(le32_to_cpu(risc->cpu[i]));
- for (j = 1; j < n; j++)
- pr_info("%s: 0x%lx: 0x%08x [ arg #%d ]\n",
- btv->c.v4l2_dev.name,
- (unsigned long)(risc->dma + ((i+j)<<2)),
- risc->cpu[i+j], j);
- if (0 == risc->cpu[i])
- break;
- }
-}
-
-static void bttv_print_riscaddr(struct bttv *btv)
-{
- pr_info(" main: %08llx\n", (unsigned long long)btv->main.dma);
- pr_info(" vbi : o=%08llx e=%08llx\n",
- btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
- btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0);
- pr_info(" cap : o=%08llx e=%08llx\n",
- btv->curr.top
- ? (unsigned long long)btv->curr.top->top.dma : 0,
- btv->curr.bottom
- ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
- pr_info(" scr : o=%08llx e=%08llx\n",
- btv->screen ? (unsigned long long)btv->screen->top.dma : 0,
- btv->screen ? (unsigned long long)btv->screen->bottom.dma : 0);
- bttv_risc_disasm(btv, &btv->main);
-}
-
-/* ----------------------------------------------------------------------- */
-/* irq handler */
-
-static char *irq_name[] = {
- "FMTCHG", // format change detected (525 vs. 625)
- "VSYNC", // vertical sync (new field)
- "HSYNC", // horizontal sync
- "OFLOW", // chroma/luma AGC overflow
- "HLOCK", // horizontal lock changed
- "VPRES", // video presence changed
- "6", "7",
- "I2CDONE", // hw irc operation finished
- "GPINT", // gpio port triggered irq
- "10",
- "RISCI", // risc instruction triggered irq
- "FBUS", // pixel data fifo dropped data (high pci bus latencies)
- "FTRGT", // pixel data fifo overrun
- "FDSR", // fifo data stream resyncronisation
- "PPERR", // parity error (data transfer)
- "RIPERR", // parity error (read risc instructions)
- "PABORT", // pci abort
- "OCERR", // risc instruction error
- "SCERR", // syncronisation error
-};
-
-static void bttv_print_irqbits(u32 print, u32 mark)
-{
- unsigned int i;
-
- pr_cont("bits:");
- for (i = 0; i < ARRAY_SIZE(irq_name); i++) {
- if (print & (1 << i))
- pr_cont(" %s", irq_name[i]);
- if (mark & (1 << i))
- pr_cont("*");
- }
-}
-
-static void bttv_irq_debug_low_latency(struct bttv *btv, u32 rc)
-{
- pr_warn("%d: irq: skipped frame [main=%lx,o_vbi=%lx,o_field=%lx,rc=%lx]\n",
- btv->c.nr,
- (unsigned long)btv->main.dma,
- (unsigned long)le32_to_cpu(btv->main.cpu[RISC_SLOT_O_VBI+1]),
- (unsigned long)le32_to_cpu(btv->main.cpu[RISC_SLOT_O_FIELD+1]),
- (unsigned long)rc);
-
- if (0 == (btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC)) {
- pr_notice("%d: Oh, there (temporarily?) is no input signal. "
- "Ok, then this is harmless, don't worry ;)\n",
- btv->c.nr);
- return;
- }
- pr_notice("%d: Uhm. Looks like we have unusual high IRQ latencies\n",
- btv->c.nr);
- pr_notice("%d: Lets try to catch the culpit red-handed ...\n",
- btv->c.nr);
- dump_stack();
-}
-
-static int
-bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set)
-{
- struct bttv_buffer *item;
-
- memset(set,0,sizeof(*set));
-
- /* capture request ? */
- if (!list_empty(&btv->capture)) {
- set->frame_irq = 1;
- item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
- if (V4L2_FIELD_HAS_TOP(item->vb.field))
- set->top = item;
- if (V4L2_FIELD_HAS_BOTTOM(item->vb.field))
- set->bottom = item;
-
- /* capture request for other field ? */
- if (!V4L2_FIELD_HAS_BOTH(item->vb.field) &&
- (item->vb.queue.next != &btv->capture)) {
- item = list_entry(item->vb.queue.next, struct bttv_buffer, vb.queue);
- /* Mike Isely <isely@pobox.com> - Only check
- * and set up the bottom field in the logic
- * below. Don't ever do the top field. This
- * of course means that if we set up the
- * bottom field in the above code that we'll
- * actually skip a field. But that's OK.
- * Having processed only a single buffer this
- * time, then the next time around the first
- * available buffer should be for a top field.
- * That will then cause us here to set up a
- * top then a bottom field in the normal way.
- * The alternative to this understanding is
- * that we set up the second available buffer
- * as a top field, but that's out of order
- * since this driver always processes the top
- * field first - the effect will be the two
- * buffers being returned in the wrong order,
- * with the second buffer also being delayed
- * by one field time (owing to the fifo nature
- * of videobuf). Worse still, we'll be stuck
- * doing fields out of order now every time
- * until something else causes a field to be
- * dropped. By effectively forcing a field to
- * drop this way then we always get back into
- * sync within a single frame time. (Out of
- * order fields can screw up deinterlacing
- * algorithms.) */
- if (!V4L2_FIELD_HAS_BOTH(item->vb.field)) {
- if (NULL == set->bottom &&
- V4L2_FIELD_BOTTOM == item->vb.field) {
- set->bottom = item;
- }
- if (NULL != set->top && NULL != set->bottom)
- set->top_irq = 2;
- }
- }
- }
-
- /* screen overlay ? */
- if (NULL != btv->screen) {
- if (V4L2_FIELD_HAS_BOTH(btv->screen->vb.field)) {
- if (NULL == set->top && NULL == set->bottom) {
- set->top = btv->screen;
- set->bottom = btv->screen;
- }
- } else {
- if (V4L2_FIELD_TOP == btv->screen->vb.field &&
- NULL == set->top) {
- set->top = btv->screen;
- }
- if (V4L2_FIELD_BOTTOM == btv->screen->vb.field &&
- NULL == set->bottom) {
- set->bottom = btv->screen;
- }
- }
- }
-
- dprintk("%d: next set: top=%p bottom=%p [screen=%p,irq=%d,%d]\n",
- btv->c.nr, set->top, set->bottom,
- btv->screen, set->frame_irq, set->top_irq);
- return 0;
-}
-
-static void
-bttv_irq_wakeup_video(struct bttv *btv, struct bttv_buffer_set *wakeup,
- struct bttv_buffer_set *curr, unsigned int state)
-{
- struct timeval ts;
-
- do_gettimeofday(&ts);
-
- if (wakeup->top == wakeup->bottom) {
- if (NULL != wakeup->top && curr->top != wakeup->top) {
- if (irq_debug > 1)
- pr_debug("%d: wakeup: both=%p\n",
- btv->c.nr, wakeup->top);
- wakeup->top->vb.ts = ts;
- wakeup->top->vb.field_count = btv->field_count;
- wakeup->top->vb.state = state;
- wake_up(&wakeup->top->vb.done);
- }
- } else {
- if (NULL != wakeup->top && curr->top != wakeup->top) {
- if (irq_debug > 1)
- pr_debug("%d: wakeup: top=%p\n",
- btv->c.nr, wakeup->top);
- wakeup->top->vb.ts = ts;
- wakeup->top->vb.field_count = btv->field_count;
- wakeup->top->vb.state = state;
- wake_up(&wakeup->top->vb.done);
- }
- if (NULL != wakeup->bottom && curr->bottom != wakeup->bottom) {
- if (irq_debug > 1)
- pr_debug("%d: wakeup: bottom=%p\n",
- btv->c.nr, wakeup->bottom);
- wakeup->bottom->vb.ts = ts;
- wakeup->bottom->vb.field_count = btv->field_count;
- wakeup->bottom->vb.state = state;
- wake_up(&wakeup->bottom->vb.done);
- }
- }
-}
-
-static void
-bttv_irq_wakeup_vbi(struct bttv *btv, struct bttv_buffer *wakeup,
- unsigned int state)
-{
- struct timeval ts;
-
- if (NULL == wakeup)
- return;
-
- do_gettimeofday(&ts);
- wakeup->vb.ts = ts;
- wakeup->vb.field_count = btv->field_count;
- wakeup->vb.state = state;
- wake_up(&wakeup->vb.done);
-}
-
-static void bttv_irq_timeout(unsigned long data)
-{
- struct bttv *btv = (struct bttv *)data;
- struct bttv_buffer_set old,new;
- struct bttv_buffer *ovbi;
- struct bttv_buffer *item;
- unsigned long flags;
-
- if (bttv_verbose) {
- pr_info("%d: timeout: drop=%d irq=%d/%d, risc=%08x, ",
- btv->c.nr, btv->framedrop, btv->irq_me, btv->irq_total,
- btread(BT848_RISC_COUNT));
- bttv_print_irqbits(btread(BT848_INT_STAT),0);
- pr_cont("\n");
- }
-
- spin_lock_irqsave(&btv->s_lock,flags);
-
- /* deactivate stuff */
- memset(&new,0,sizeof(new));
- old = btv->curr;
- ovbi = btv->cvbi;
- btv->curr = new;
- btv->cvbi = NULL;
- btv->loop_irq = 0;
- bttv_buffer_activate_video(btv, &new);
- bttv_buffer_activate_vbi(btv, NULL);
- bttv_set_dma(btv, 0);
-
- /* wake up */
- bttv_irq_wakeup_video(btv, &old, &new, VIDEOBUF_ERROR);
- bttv_irq_wakeup_vbi(btv, ovbi, VIDEOBUF_ERROR);
-
- /* cancel all outstanding capture / vbi requests */
- while (!list_empty(&btv->capture)) {
- item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
- list_del(&item->vb.queue);
- item->vb.state = VIDEOBUF_ERROR;
- wake_up(&item->vb.done);
- }
- while (!list_empty(&btv->vcapture)) {
- item = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue);
- list_del(&item->vb.queue);
- item->vb.state = VIDEOBUF_ERROR;
- wake_up(&item->vb.done);
- }
-
- btv->errors++;
- spin_unlock_irqrestore(&btv->s_lock,flags);
-}
-
-static void
-bttv_irq_wakeup_top(struct bttv *btv)
-{
- struct bttv_buffer *wakeup = btv->curr.top;
-
- if (NULL == wakeup)
- return;
-
- spin_lock(&btv->s_lock);
- btv->curr.top_irq = 0;
- btv->curr.top = NULL;
- bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
-
- do_gettimeofday(&wakeup->vb.ts);
- wakeup->vb.field_count = btv->field_count;
- wakeup->vb.state = VIDEOBUF_DONE;
- wake_up(&wakeup->vb.done);
- spin_unlock(&btv->s_lock);
-}
-
-static inline int is_active(struct btcx_riscmem *risc, u32 rc)
-{
- if (rc < risc->dma)
- return 0;
- if (rc > risc->dma + risc->size)
- return 0;
- return 1;
-}
-
-static void
-bttv_irq_switch_video(struct bttv *btv)
-{
- struct bttv_buffer_set new;
- struct bttv_buffer_set old;
- dma_addr_t rc;
-
- spin_lock(&btv->s_lock);
-
- /* new buffer set */
- bttv_irq_next_video(btv, &new);
- rc = btread(BT848_RISC_COUNT);
- if ((btv->curr.top && is_active(&btv->curr.top->top, rc)) ||
- (btv->curr.bottom && is_active(&btv->curr.bottom->bottom, rc))) {
- btv->framedrop++;
- if (debug_latency)
- bttv_irq_debug_low_latency(btv, rc);
- spin_unlock(&btv->s_lock);
- return;
- }
-
- /* switch over */
- old = btv->curr;
- btv->curr = new;
- btv->loop_irq &= ~1;
- bttv_buffer_activate_video(btv, &new);
- bttv_set_dma(btv, 0);
-
- /* switch input */
- if (UNSET != btv->new_input) {
- video_mux(btv,btv->new_input);
- btv->new_input = UNSET;
- }
-
- /* wake up finished buffers */
- bttv_irq_wakeup_video(btv, &old, &new, VIDEOBUF_DONE);
- spin_unlock(&btv->s_lock);
-}
-
-static void
-bttv_irq_switch_vbi(struct bttv *btv)
-{
- struct bttv_buffer *new = NULL;
- struct bttv_buffer *old;
- u32 rc;
-
- spin_lock(&btv->s_lock);
-
- if (!list_empty(&btv->vcapture))
- new = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue);
- old = btv->cvbi;
-
- rc = btread(BT848_RISC_COUNT);
- if (NULL != old && (is_active(&old->top, rc) ||
- is_active(&old->bottom, rc))) {
- btv->framedrop++;
- if (debug_latency)
- bttv_irq_debug_low_latency(btv, rc);
- spin_unlock(&btv->s_lock);
- return;
- }
-
- /* switch */
- btv->cvbi = new;
- btv->loop_irq &= ~4;
- bttv_buffer_activate_vbi(btv, new);
- bttv_set_dma(btv, 0);
-
- bttv_irq_wakeup_vbi(btv, old, VIDEOBUF_DONE);
- spin_unlock(&btv->s_lock);
-}
-
-static irqreturn_t bttv_irq(int irq, void *dev_id)
-{
- u32 stat,astat;
- u32 dstat;
- int count;
- struct bttv *btv;
- int handled = 0;
-
- btv=(struct bttv *)dev_id;
-
- count=0;
- while (1) {
- /* get/clear interrupt status bits */
- stat=btread(BT848_INT_STAT);
- astat=stat&btread(BT848_INT_MASK);
- if (!astat)
- break;
- handled = 1;
- btwrite(stat,BT848_INT_STAT);
-
- /* get device status bits */
- dstat=btread(BT848_DSTATUS);
-
- if (irq_debug) {
- pr_debug("%d: irq loop=%d fc=%d riscs=%x, riscc=%08x, ",
- btv->c.nr, count, btv->field_count,
- stat>>28, btread(BT848_RISC_COUNT));
- bttv_print_irqbits(stat,astat);
- if (stat & BT848_INT_HLOCK)
- pr_cont(" HLOC => %s",
- dstat & BT848_DSTATUS_HLOC
- ? "yes" : "no");
- if (stat & BT848_INT_VPRES)
- pr_cont(" PRES => %s",
- dstat & BT848_DSTATUS_PRES
- ? "yes" : "no");
- if (stat & BT848_INT_FMTCHG)
- pr_cont(" NUML => %s",
- dstat & BT848_DSTATUS_NUML
- ? "625" : "525");
- pr_cont("\n");
- }
-
- if (astat&BT848_INT_VSYNC)
- btv->field_count++;
-
- if ((astat & BT848_INT_GPINT) && btv->remote) {
- bttv_input_irq(btv);
- }
-
- if (astat & BT848_INT_I2CDONE) {
- btv->i2c_done = stat;
- wake_up(&btv->i2c_queue);
- }
-
- if ((astat & BT848_INT_RISCI) && (stat & (4<<28)))
- bttv_irq_switch_vbi(btv);
-
- if ((astat & BT848_INT_RISCI) && (stat & (2<<28)))
- bttv_irq_wakeup_top(btv);
-
- if ((astat & BT848_INT_RISCI) && (stat & (1<<28)))
- bttv_irq_switch_video(btv);
-
- if ((astat & BT848_INT_HLOCK) && btv->opt_automute)
- audio_mute(btv, btv->mute); /* trigger automute */
-
- if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) {
- pr_info("%d: %s%s @ %08x,",
- btv->c.nr,
- (astat & BT848_INT_SCERR) ? "SCERR" : "",
- (astat & BT848_INT_OCERR) ? "OCERR" : "",
- btread(BT848_RISC_COUNT));
- bttv_print_irqbits(stat,astat);
- pr_cont("\n");
- if (bttv_debug)
- bttv_print_riscaddr(btv);
- }
- if (fdsr && astat & BT848_INT_FDSR) {
- pr_info("%d: FDSR @ %08x\n",
- btv->c.nr, btread(BT848_RISC_COUNT));
- if (bttv_debug)
- bttv_print_riscaddr(btv);
- }
-
- count++;
- if (count > 4) {
-
- if (count > 8 || !(astat & BT848_INT_GPINT)) {
- btwrite(0, BT848_INT_MASK);
-
- pr_err("%d: IRQ lockup, cleared int mask [",
- btv->c.nr);
- } else {
- pr_err("%d: IRQ lockup, clearing GPINT from int mask [",
- btv->c.nr);
-
- btwrite(btread(BT848_INT_MASK) & (-1 ^ BT848_INT_GPINT),
- BT848_INT_MASK);
- };
-
- bttv_print_irqbits(stat,astat);
-
- pr_cont("]\n");
- }
- }
- btv->irq_total++;
- if (handled)
- btv->irq_me++;
- return IRQ_RETVAL(handled);
-}
-
-
-/* ----------------------------------------------------------------------- */
-/* initialitation */
-
-static struct video_device *vdev_init(struct bttv *btv,
- const struct video_device *template,
- const char *type_name)
-{
- struct video_device *vfd;
-
- vfd = video_device_alloc();
- if (NULL == vfd)
- return NULL;
- *vfd = *template;
- vfd->v4l2_dev = &btv->c.v4l2_dev;
- vfd->release = video_device_release;
- vfd->debug = bttv_debug;
- video_set_drvdata(vfd, btv);
- snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
- btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
- type_name, bttv_tvcards[btv->c.type].name);
- return vfd;
-}
-
-static void bttv_unregister_video(struct bttv *btv)
-{
- if (btv->video_dev) {
- if (video_is_registered(btv->video_dev))
- video_unregister_device(btv->video_dev);
- else
- video_device_release(btv->video_dev);
- btv->video_dev = NULL;
- }
- if (btv->vbi_dev) {
- if (video_is_registered(btv->vbi_dev))
- video_unregister_device(btv->vbi_dev);
- else
- video_device_release(btv->vbi_dev);
- btv->vbi_dev = NULL;
- }
- if (btv->radio_dev) {
- if (video_is_registered(btv->radio_dev))
- video_unregister_device(btv->radio_dev);
- else
- video_device_release(btv->radio_dev);
- btv->radio_dev = NULL;
- }
-}
-
-/* register video4linux devices */
-static int __devinit bttv_register_video(struct bttv *btv)
-{
- if (no_overlay > 0)
- pr_notice("Overlay support disabled\n");
-
- /* video */
- btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
-
- if (NULL == btv->video_dev)
- goto err;
- if (video_register_device(btv->video_dev, VFL_TYPE_GRABBER,
- video_nr[btv->c.nr]) < 0)
- goto err;
- pr_info("%d: registered device %s\n",
- btv->c.nr, video_device_node_name(btv->video_dev));
- if (device_create_file(&btv->video_dev->dev,
- &dev_attr_card)<0) {
- pr_err("%d: device_create_file 'card' failed\n", btv->c.nr);
- goto err;
- }
-
- /* vbi */
- btv->vbi_dev = vdev_init(btv, &bttv_video_template, "vbi");
-
- if (NULL == btv->vbi_dev)
- goto err;
- if (video_register_device(btv->vbi_dev, VFL_TYPE_VBI,
- vbi_nr[btv->c.nr]) < 0)
- goto err;
- pr_info("%d: registered device %s\n",
- btv->c.nr, video_device_node_name(btv->vbi_dev));
-
- if (!btv->has_radio)
- return 0;
- /* radio */
- btv->radio_dev = vdev_init(btv, &radio_template, "radio");
- if (NULL == btv->radio_dev)
- goto err;
- if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,
- radio_nr[btv->c.nr]) < 0)
- goto err;
- pr_info("%d: registered device %s\n",
- btv->c.nr, video_device_node_name(btv->radio_dev));
-
- /* all done */
- return 0;
-
- err:
- bttv_unregister_video(btv);
- return -1;
-}
-
-
-/* on OpenFirmware machines (PowerMac at least), PCI memory cycle */
-/* response on cards with no firmware is not enabled by OF */
-static void pci_set_command(struct pci_dev *dev)
-{
-#if defined(__powerpc__)
- unsigned int cmd;
-
- pci_read_config_dword(dev, PCI_COMMAND, &cmd);
- cmd = (cmd | PCI_COMMAND_MEMORY );
- pci_write_config_dword(dev, PCI_COMMAND, cmd);
-#endif
-}
-
-static int __devinit bttv_probe(struct pci_dev *dev,
- const struct pci_device_id *pci_id)
-{
- int result;
- unsigned char lat;
- struct bttv *btv;
-
- if (bttv_num == BTTV_MAX)
- return -ENOMEM;
- pr_info("Bt8xx card found (%d)\n", bttv_num);
- bttvs[bttv_num] = btv = kzalloc(sizeof(*btv), GFP_KERNEL);
- if (btv == NULL) {
- pr_err("out of memory\n");
- return -ENOMEM;
- }
- btv->c.nr = bttv_num;
- snprintf(btv->c.v4l2_dev.name, sizeof(btv->c.v4l2_dev.name),
- "bttv%d", btv->c.nr);
-
- /* initialize structs / fill in defaults */
- mutex_init(&btv->lock);
- spin_lock_init(&btv->s_lock);
- spin_lock_init(&btv->gpio_lock);
- init_waitqueue_head(&btv->i2c_queue);
- INIT_LIST_HEAD(&btv->c.subs);
- INIT_LIST_HEAD(&btv->capture);
- INIT_LIST_HEAD(&btv->vcapture);
- v4l2_prio_init(&btv->prio);
-
- init_timer(&btv->timeout);
- btv->timeout.function = bttv_irq_timeout;
- btv->timeout.data = (unsigned long)btv;
-
- btv->i2c_rc = -1;
- btv->tuner_type = UNSET;
- btv->new_input = UNSET;
- btv->has_radio=radio[btv->c.nr];
-
- /* pci stuff (init, get irq/mmio, ... */
- btv->c.pci = dev;
- btv->id = dev->device;
- if (pci_enable_device(dev)) {
- pr_warn("%d: Can't enable device\n", btv->c.nr);
- return -EIO;
- }
- if (pci_set_dma_mask(dev, DMA_BIT_MASK(32))) {
- pr_warn("%d: No suitable DMA available\n", btv->c.nr);
- return -EIO;
- }
- if (!request_mem_region(pci_resource_start(dev,0),
- pci_resource_len(dev,0),
- btv->c.v4l2_dev.name)) {
- pr_warn("%d: can't request iomem (0x%llx)\n",
- btv->c.nr,
- (unsigned long long)pci_resource_start(dev, 0));
- return -EBUSY;
- }
- pci_set_master(dev);
- pci_set_command(dev);
-
- result = v4l2_device_register(&dev->dev, &btv->c.v4l2_dev);
- if (result < 0) {
- pr_warn("%d: v4l2_device_register() failed\n", btv->c.nr);
- goto fail0;
- }
-
- btv->revision = dev->revision;
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
- pr_info("%d: Bt%d (rev %d) at %s, irq: %d, latency: %d, mmio: 0x%llx\n",
- bttv_num, btv->id, btv->revision, pci_name(dev),
- btv->c.pci->irq, lat,
- (unsigned long long)pci_resource_start(dev, 0));
- schedule();
-
- btv->bt848_mmio = ioremap(pci_resource_start(dev, 0), 0x1000);
- if (NULL == btv->bt848_mmio) {
- pr_err("%d: ioremap() failed\n", btv->c.nr);
- result = -EIO;
- goto fail1;
- }
-
- /* identify card */
- bttv_idcard(btv);
-
- /* disable irqs, register irq handler */
- btwrite(0, BT848_INT_MASK);
- result = request_irq(btv->c.pci->irq, bttv_irq,
- IRQF_SHARED | IRQF_DISABLED, btv->c.v4l2_dev.name, (void *)btv);
- if (result < 0) {
- pr_err("%d: can't get IRQ %d\n",
- bttv_num, btv->c.pci->irq);
- goto fail1;
- }
-
- if (0 != bttv_handle_chipset(btv)) {
- result = -EIO;
- goto fail2;
- }
-
- /* init options from insmod args */
- btv->opt_combfilter = combfilter;
- btv->opt_lumafilter = lumafilter;
- btv->opt_automute = automute;
- btv->opt_chroma_agc = chroma_agc;
- btv->opt_adc_crush = adc_crush;
- btv->opt_vcr_hack = vcr_hack;
- btv->opt_whitecrush_upper = whitecrush_upper;
- btv->opt_whitecrush_lower = whitecrush_lower;
- btv->opt_uv_ratio = uv_ratio;
- btv->opt_full_luma_range = full_luma_range;
- btv->opt_coring = coring;
-
- /* fill struct bttv with some useful defaults */
- btv->init.btv = btv;
- btv->init.ov.w.width = 320;
- btv->init.ov.w.height = 240;
- btv->init.fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
- btv->init.width = 320;
- btv->init.height = 240;
- btv->input = 0;
-
- /* initialize hardware */
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"pre-init");
-
- bttv_risc_init_main(btv);
- init_bt848(btv);
-
- /* gpio */
- btwrite(0x00, BT848_GPIO_REG_INP);
- btwrite(0x00, BT848_GPIO_OUT_EN);
- if (bttv_verbose)
- bttv_gpio_tracking(btv,"init");
-
- /* needs to be done before i2c is registered */
- bttv_init_card1(btv);
-
- /* register i2c + gpio */
- init_bttv_i2c(btv);
-
- /* some card-specific stuff (needs working i2c) */
- bttv_init_card2(btv);
- bttv_init_tuner(btv);
- init_irqreg(btv);
-
- /* register video4linux + input */
- if (!bttv_tvcards[btv->c.type].no_video) {
- bttv_register_video(btv);
- bt848_bright(btv,32768);
- bt848_contrast(btv, 27648);
- bt848_hue(btv,32768);
- bt848_sat(btv,32768);
- audio_mute(btv, 1);
- set_input(btv, 0, btv->tvnorm);
- bttv_crop_reset(&btv->crop[0], btv->tvnorm);
- btv->crop[1] = btv->crop[0]; /* current = default */
- disclaim_vbi_lines(btv);
- disclaim_video_lines(btv);
- }
-
- /* add subdevices and autoload dvb-bt8xx if needed */
- if (bttv_tvcards[btv->c.type].has_dvb) {
- bttv_sub_add_device(&btv->c, "dvb");
- request_modules(btv);
- }
-
- if (!disable_ir) {
- init_bttv_i2c_ir(btv);
- bttv_input_init(btv);
- }
-
- /* everything is fine */
- bttv_num++;
- return 0;
-
-fail2:
- free_irq(btv->c.pci->irq,btv);
-
-fail1:
- v4l2_device_unregister(&btv->c.v4l2_dev);
-
-fail0:
- if (btv->bt848_mmio)
- iounmap(btv->bt848_mmio);
- release_mem_region(pci_resource_start(btv->c.pci,0),
- pci_resource_len(btv->c.pci,0));
- return result;
-}
-
-static void __devexit bttv_remove(struct pci_dev *pci_dev)
-{
- struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
- struct bttv *btv = to_bttv(v4l2_dev);
-
- if (bttv_verbose)
- pr_info("%d: unloading\n", btv->c.nr);
-
- if (bttv_tvcards[btv->c.type].has_dvb)
- flush_request_modules(btv);
-
- /* shutdown everything (DMA+IRQs) */
- btand(~15, BT848_GPIO_DMA_CTL);
- btwrite(0, BT848_INT_MASK);
- btwrite(~0x0, BT848_INT_STAT);
- btwrite(0x0, BT848_GPIO_OUT_EN);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"cleanup");
-
- /* tell gpio modules we are leaving ... */
- btv->shutdown=1;
- bttv_input_fini(btv);
- bttv_sub_del_devices(&btv->c);
-
- /* unregister i2c_bus + input */
- fini_bttv_i2c(btv);
-
- /* unregister video4linux */
- bttv_unregister_video(btv);
-
- /* free allocated memory */
- btcx_riscmem_free(btv->c.pci,&btv->main);
-
- /* free ressources */
- free_irq(btv->c.pci->irq,btv);
- iounmap(btv->bt848_mmio);
- release_mem_region(pci_resource_start(btv->c.pci,0),
- pci_resource_len(btv->c.pci,0));
-
- v4l2_device_unregister(&btv->c.v4l2_dev);
- bttvs[btv->c.nr] = NULL;
- kfree(btv);
-
- return;
-}
-
-#ifdef CONFIG_PM
-static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
-{
- struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
- struct bttv *btv = to_bttv(v4l2_dev);
- struct bttv_buffer_set idle;
- unsigned long flags;
-
- dprintk("%d: suspend %d\n", btv->c.nr, state.event);
-
- /* stop dma + irqs */
- spin_lock_irqsave(&btv->s_lock,flags);
- memset(&idle, 0, sizeof(idle));
- btv->state.video = btv->curr;
- btv->state.vbi = btv->cvbi;
- btv->state.loop_irq = btv->loop_irq;
- btv->curr = idle;
- btv->loop_irq = 0;
- bttv_buffer_activate_video(btv, &idle);
- bttv_buffer_activate_vbi(btv, NULL);
- bttv_set_dma(btv, 0);
- btwrite(0, BT848_INT_MASK);
- spin_unlock_irqrestore(&btv->s_lock,flags);
-
- /* save bt878 state */
- btv->state.gpio_enable = btread(BT848_GPIO_OUT_EN);
- btv->state.gpio_data = gpio_read();
-
- /* save pci state */
- pci_save_state(pci_dev);
- if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
- pci_disable_device(pci_dev);
- btv->state.disabled = 1;
- }
- return 0;
-}
-
-static int bttv_resume(struct pci_dev *pci_dev)
-{
- struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
- struct bttv *btv = to_bttv(v4l2_dev);
- unsigned long flags;
- int err;
-
- dprintk("%d: resume\n", btv->c.nr);
-
- /* restore pci state */
- if (btv->state.disabled) {
- err=pci_enable_device(pci_dev);
- if (err) {
- pr_warn("%d: Can't enable device\n", btv->c.nr);
- return err;
- }
- btv->state.disabled = 0;
- }
- err=pci_set_power_state(pci_dev, PCI_D0);
- if (err) {
- pci_disable_device(pci_dev);
- pr_warn("%d: Can't enable device\n", btv->c.nr);
- btv->state.disabled = 1;
- return err;
- }
-
- pci_restore_state(pci_dev);
-
- /* restore bt878 state */
- bttv_reinit_bt848(btv);
- gpio_inout(0xffffff, btv->state.gpio_enable);
- gpio_write(btv->state.gpio_data);
-
- /* restart dma */
- spin_lock_irqsave(&btv->s_lock,flags);
- btv->curr = btv->state.video;
- btv->cvbi = btv->state.vbi;
- btv->loop_irq = btv->state.loop_irq;
- bttv_buffer_activate_video(btv, &btv->curr);
- bttv_buffer_activate_vbi(btv, btv->cvbi);
- bttv_set_dma(btv, 0);
- spin_unlock_irqrestore(&btv->s_lock,flags);
- return 0;
-}
-#endif
-
-static struct pci_device_id bttv_pci_tbl[] = {
- {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT848), 0},
- {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT849), 0},
- {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT878), 0},
- {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT879), 0},
- {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_FUSION879), 0},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
-
-static struct pci_driver bttv_pci_driver = {
- .name = "bttv",
- .id_table = bttv_pci_tbl,
- .probe = bttv_probe,
- .remove = __devexit_p(bttv_remove),
-#ifdef CONFIG_PM
- .suspend = bttv_suspend,
- .resume = bttv_resume,
-#endif
-};
-
-static int __init bttv_init_module(void)
-{
- int ret;
-
- bttv_num = 0;
-
- pr_info("driver version %s loaded\n", BTTV_VERSION);
- if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
- gbuffers = 2;
- if (gbufsize > BTTV_MAX_FBUF)
- gbufsize = BTTV_MAX_FBUF;
- gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
- if (bttv_verbose)
- pr_info("using %d buffers with %dk (%d pages) each for capture\n",
- gbuffers, gbufsize >> 10, gbufsize >> PAGE_SHIFT);
-
- bttv_check_chipset();
-
- ret = bus_register(&bttv_sub_bus_type);
- if (ret < 0) {
- pr_warn("bus_register error: %d\n", ret);
- return ret;
- }
- ret = pci_register_driver(&bttv_pci_driver);
- if (ret < 0)
- bus_unregister(&bttv_sub_bus_type);
-
- return ret;
-}
-
-static void __exit bttv_cleanup_module(void)
-{
- pci_unregister_driver(&bttv_pci_driver);
- bus_unregister(&bttv_sub_bus_type);
-}
-
-module_init(bttv_init_module);
-module_exit(bttv_cleanup_module);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/bt8xx/bttv-gpio.c b/drivers/media/video/bt8xx/bttv-gpio.c
deleted file mode 100644
index 922e8233fd0..00000000000
--- a/drivers/media/video/bt8xx/bttv-gpio.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
-
- bttv-gpio.c -- gpio sub drivers
-
- sysfs-based sub driver interface for bttv
- mainly intended for gpio access
-
-
- Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
- (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-
-#include "bttvp.h"
-
-/* ----------------------------------------------------------------------- */
-/* internal: the bttv "bus" */
-
-static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv)
-{
- struct bttv_sub_driver *sub = to_bttv_sub_drv(drv);
- int len = strlen(sub->wanted);
-
- if (0 == strncmp(dev_name(dev), sub->wanted, len))
- return 1;
- return 0;
-}
-
-static int bttv_sub_probe(struct device *dev)
-{
- struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
- struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
-
- return sub->probe ? sub->probe(sdev) : -ENODEV;
-}
-
-static int bttv_sub_remove(struct device *dev)
-{
- struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
- struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
-
- if (sub->remove)
- sub->remove(sdev);
- return 0;
-}
-
-struct bus_type bttv_sub_bus_type = {
- .name = "bttv-sub",
- .match = &bttv_sub_bus_match,
- .probe = bttv_sub_probe,
- .remove = bttv_sub_remove,
-};
-
-static void release_sub_device(struct device *dev)
-{
- struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
- kfree(sub);
-}
-
-int bttv_sub_add_device(struct bttv_core *core, char *name)
-{
- struct bttv_sub_device *sub;
- int err;
-
- sub = kzalloc(sizeof(*sub),GFP_KERNEL);
- if (NULL == sub)
- return -ENOMEM;
-
- sub->core = core;
- sub->dev.parent = &core->pci->dev;
- sub->dev.bus = &bttv_sub_bus_type;
- sub->dev.release = release_sub_device;
- dev_set_name(&sub->dev, "%s%d", name, core->nr);
-
- err = device_register(&sub->dev);
- if (0 != err) {
- kfree(sub);
- return err;
- }
- pr_info("%d: add subdevice \"%s\"\n", core->nr, dev_name(&sub->dev));
- list_add_tail(&sub->list,&core->subs);
- return 0;
-}
-
-int bttv_sub_del_devices(struct bttv_core *core)
-{
- struct bttv_sub_device *sub, *save;
-
- list_for_each_entry_safe(sub, save, &core->subs, list) {
- list_del(&sub->list);
- device_unregister(&sub->dev);
- }
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-/* external: sub-driver register/unregister */
-
-int bttv_sub_register(struct bttv_sub_driver *sub, char *wanted)
-{
- sub->drv.bus = &bttv_sub_bus_type;
- snprintf(sub->wanted,sizeof(sub->wanted),"%s",wanted);
- return driver_register(&sub->drv);
-}
-EXPORT_SYMBOL(bttv_sub_register);
-
-int bttv_sub_unregister(struct bttv_sub_driver *sub)
-{
- driver_unregister(&sub->drv);
- return 0;
-}
-EXPORT_SYMBOL(bttv_sub_unregister);
-
-/* ----------------------------------------------------------------------- */
-/* external: gpio access functions */
-
-void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits)
-{
- struct bttv *btv = container_of(core, struct bttv, c);
- unsigned long flags;
- u32 data;
-
- spin_lock_irqsave(&btv->gpio_lock,flags);
- data = btread(BT848_GPIO_OUT_EN);
- data = data & ~mask;
- data = data | (mask & outbits);
- btwrite(data,BT848_GPIO_OUT_EN);
- spin_unlock_irqrestore(&btv->gpio_lock,flags);
-}
-
-u32 bttv_gpio_read(struct bttv_core *core)
-{
- struct bttv *btv = container_of(core, struct bttv, c);
- u32 value;
-
- value = btread(BT848_GPIO_DATA);
- return value;
-}
-
-void bttv_gpio_write(struct bttv_core *core, u32 value)
-{
- struct bttv *btv = container_of(core, struct bttv, c);
-
- btwrite(value,BT848_GPIO_DATA);
-}
-
-void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits)
-{
- struct bttv *btv = container_of(core, struct bttv, c);
- unsigned long flags;
- u32 data;
-
- spin_lock_irqsave(&btv->gpio_lock,flags);
- data = btread(BT848_GPIO_DATA);
- data = data & ~mask;
- data = data | (mask & bits);
- btwrite(data,BT848_GPIO_DATA);
- spin_unlock_irqrestore(&btv->gpio_lock,flags);
-}
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
deleted file mode 100644
index 580c8e68239..00000000000
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
-
- bttv-i2c.c -- all the i2c code is here
-
- bttv - Bt848 frame grabber driver
-
- Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
- (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
-
- (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
- - Multituner support and i2c address binding
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include "bttvp.h"
-#include <media/v4l2-common.h>
-#include <linux/jiffies.h>
-#include <asm/io.h>
-
-static int i2c_debug;
-static int i2c_hw;
-static int i2c_scan;
-module_param(i2c_debug, int, 0644);
-MODULE_PARM_DESC(i2c_debug, "configure i2c debug level");
-module_param(i2c_hw, int, 0444);
-MODULE_PARM_DESC(i2c_hw,"force use of hardware i2c support, "
- "instead of software bitbang");
-module_param(i2c_scan, int, 0444);
-MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
-
-static unsigned int i2c_udelay = 5;
-module_param(i2c_udelay, int, 0444);
-MODULE_PARM_DESC(i2c_udelay,"soft i2c delay at insmod time, in usecs "
- "(should be 5 or higher). Lower value means higher bus speed.");
-
-/* ----------------------------------------------------------------------- */
-/* I2C functions - bitbanging adapter (software i2c) */
-
-static void bttv_bit_setscl(void *data, int state)
-{
- struct bttv *btv = (struct bttv*)data;
-
- if (state)
- btv->i2c_state |= 0x02;
- else
- btv->i2c_state &= ~0x02;
- btwrite(btv->i2c_state, BT848_I2C);
- btread(BT848_I2C);
-}
-
-static void bttv_bit_setsda(void *data, int state)
-{
- struct bttv *btv = (struct bttv*)data;
-
- if (state)
- btv->i2c_state |= 0x01;
- else
- btv->i2c_state &= ~0x01;
- btwrite(btv->i2c_state, BT848_I2C);
- btread(BT848_I2C);
-}
-
-static int bttv_bit_getscl(void *data)
-{
- struct bttv *btv = (struct bttv*)data;
- int state;
-
- state = btread(BT848_I2C) & 0x02 ? 1 : 0;
- return state;
-}
-
-static int bttv_bit_getsda(void *data)
-{
- struct bttv *btv = (struct bttv*)data;
- int state;
-
- state = btread(BT848_I2C) & 0x01;
- return state;
-}
-
-static struct i2c_algo_bit_data __devinitdata bttv_i2c_algo_bit_template = {
- .setsda = bttv_bit_setsda,
- .setscl = bttv_bit_setscl,
- .getsda = bttv_bit_getsda,
- .getscl = bttv_bit_getscl,
- .udelay = 16,
- .timeout = 200,
-};
-
-/* ----------------------------------------------------------------------- */
-/* I2C functions - hardware i2c */
-
-static u32 functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_SMBUS_EMUL;
-}
-
-static int
-bttv_i2c_wait_done(struct bttv *btv)
-{
- int rc = 0;
-
- /* timeout */
- if (wait_event_interruptible_timeout(btv->i2c_queue,
- btv->i2c_done, msecs_to_jiffies(85)) == -ERESTARTSYS)
- rc = -EIO;
-
- if (btv->i2c_done & BT848_INT_RACK)
- rc = 1;
- btv->i2c_done = 0;
- return rc;
-}
-
-#define I2C_HW (BT878_I2C_MODE | BT848_I2C_SYNC |\
- BT848_I2C_SCL | BT848_I2C_SDA)
-
-static int
-bttv_i2c_sendbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
-{
- u32 xmit;
- int retval,cnt;
-
- /* sanity checks */
- if (0 == msg->len)
- return -EINVAL;
-
- /* start, address + first byte */
- xmit = (msg->addr << 25) | (msg->buf[0] << 16) | I2C_HW;
- if (msg->len > 1 || !last)
- xmit |= BT878_I2C_NOSTOP;
- btwrite(xmit, BT848_I2C);
- retval = bttv_i2c_wait_done(btv);
- if (retval < 0)
- goto err;
- if (retval == 0)
- goto eio;
- if (i2c_debug) {
- pr_cont(" <W %02x %02x", msg->addr << 1, msg->buf[0]);
- }
-
- for (cnt = 1; cnt < msg->len; cnt++ ) {
- /* following bytes */
- xmit = (msg->buf[cnt] << 24) | I2C_HW | BT878_I2C_NOSTART;
- if (cnt < msg->len-1 || !last)
- xmit |= BT878_I2C_NOSTOP;
- btwrite(xmit, BT848_I2C);
- retval = bttv_i2c_wait_done(btv);
- if (retval < 0)
- goto err;
- if (retval == 0)
- goto eio;
- if (i2c_debug)
- pr_cont(" %02x", msg->buf[cnt]);
- }
- if (!(xmit & BT878_I2C_NOSTOP))
- pr_cont(">\n");
- return msg->len;
-
- eio:
- retval = -EIO;
- err:
- if (i2c_debug)
- pr_cont(" ERR: %d\n",retval);
- return retval;
-}
-
-static int
-bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
-{
- u32 xmit;
- u32 cnt;
- int retval;
-
- for (cnt = 0; cnt < msg->len; cnt++) {
- xmit = (msg->addr << 25) | (1 << 24) | I2C_HW;
- if (cnt < msg->len-1)
- xmit |= BT848_I2C_W3B;
- if (cnt < msg->len-1 || !last)
- xmit |= BT878_I2C_NOSTOP;
- if (cnt)
- xmit |= BT878_I2C_NOSTART;
-
- if (i2c_debug) {
- if (!(xmit & BT878_I2C_NOSTART))
- pr_cont(" <R %02x", (msg->addr << 1) +1);
- }
-
- btwrite(xmit, BT848_I2C);
- retval = bttv_i2c_wait_done(btv);
- if (retval < 0)
- goto err;
- if (retval == 0)
- goto eio;
- msg->buf[cnt] = ((u32)btread(BT848_I2C) >> 8) & 0xff;
- if (i2c_debug) {
- pr_cont(" =%02x", msg->buf[cnt]);
- }
- if (i2c_debug && !(xmit & BT878_I2C_NOSTOP))
- pr_cont(" >\n");
- }
-
-
- return msg->len;
-
- eio:
- retval = -EIO;
- err:
- if (i2c_debug)
- pr_cont(" ERR: %d\n",retval);
- return retval;
-}
-
-static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
-{
- struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap);
- struct bttv *btv = to_bttv(v4l2_dev);
- int retval = 0;
- int i;
-
- if (i2c_debug)
- pr_debug("bt-i2c:");
-
- btwrite(BT848_INT_I2CDONE|BT848_INT_RACK, BT848_INT_STAT);
- for (i = 0 ; i < num; i++) {
- if (msgs[i].flags & I2C_M_RD) {
- /* read */
- retval = bttv_i2c_readbytes(btv, &msgs[i], i+1 == num);
- if (retval < 0)
- goto err;
- } else {
- /* write */
- retval = bttv_i2c_sendbytes(btv, &msgs[i], i+1 == num);
- if (retval < 0)
- goto err;
- }
- }
- return num;
-
- err:
- return retval;
-}
-
-static const struct i2c_algorithm bttv_algo = {
- .master_xfer = bttv_i2c_xfer,
- .functionality = functionality,
-};
-
-/* ----------------------------------------------------------------------- */
-/* I2C functions - common stuff */
-
-/* read I2C */
-int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
-{
- unsigned char buffer = 0;
-
- if (0 != btv->i2c_rc)
- return -1;
- if (bttv_verbose && NULL != probe_for)
- pr_info("%d: i2c: checking for %s @ 0x%02x... ",
- btv->c.nr, probe_for, addr);
- btv->i2c_client.addr = addr >> 1;
- if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) {
- if (NULL != probe_for) {
- if (bttv_verbose)
- pr_cont("not found\n");
- } else
- pr_warn("%d: i2c read 0x%x: error\n",
- btv->c.nr, addr);
- return -1;
- }
- if (bttv_verbose && NULL != probe_for)
- pr_cont("found\n");
- return buffer;
-}
-
-/* write I2C */
-int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
- unsigned char b2, int both)
-{
- unsigned char buffer[2];
- int bytes = both ? 2 : 1;
-
- if (0 != btv->i2c_rc)
- return -1;
- btv->i2c_client.addr = addr >> 1;
- buffer[0] = b1;
- buffer[1] = b2;
- if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes))
- return -1;
- return 0;
-}
-
-/* read EEPROM content */
-void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr)
-{
- memset(eedata, 0, 256);
- if (0 != btv->i2c_rc)
- return;
- btv->i2c_client.addr = addr >> 1;
- tveeprom_read(&btv->i2c_client, eedata, 256);
-}
-
-static char *i2c_devs[128] = {
- [ 0x1c >> 1 ] = "lgdt330x",
- [ 0x30 >> 1 ] = "IR (hauppauge)",
- [ 0x80 >> 1 ] = "msp34xx",
- [ 0x86 >> 1 ] = "tda9887",
- [ 0xa0 >> 1 ] = "eeprom",
- [ 0xc0 >> 1 ] = "tuner (analog)",
- [ 0xc2 >> 1 ] = "tuner (analog)",
-};
-
-static void do_i2c_scan(char *name, struct i2c_client *c)
-{
- unsigned char buf;
- int i,rc;
-
- for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
- c->addr = i;
- rc = i2c_master_recv(c,&buf,0);
- if (rc < 0)
- continue;
- pr_info("%s: i2c scan: found device @ 0x%x [%s]\n",
- name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
- }
-}
-
-/* init + register i2c adapter */
-int __devinit init_bttv_i2c(struct bttv *btv)
-{
- strlcpy(btv->i2c_client.name, "bttv internal", I2C_NAME_SIZE);
-
- if (i2c_hw)
- btv->use_i2c_hw = 1;
- if (btv->use_i2c_hw) {
- /* bt878 */
- strlcpy(btv->c.i2c_adap.name, "bt878",
- sizeof(btv->c.i2c_adap.name));
- btv->c.i2c_adap.algo = &bttv_algo;
- } else {
- /* bt848 */
- /* Prevents usage of invalid delay values */
- if (i2c_udelay<5)
- i2c_udelay=5;
-
- strlcpy(btv->c.i2c_adap.name, "bttv",
- sizeof(btv->c.i2c_adap.name));
- memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template,
- sizeof(bttv_i2c_algo_bit_template));
- btv->i2c_algo.udelay = i2c_udelay;
- btv->i2c_algo.data = btv;
- btv->c.i2c_adap.algo_data = &btv->i2c_algo;
- }
- btv->c.i2c_adap.owner = THIS_MODULE;
-
- btv->c.i2c_adap.dev.parent = &btv->c.pci->dev;
- snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name),
- "bt%d #%d [%s]", btv->id, btv->c.nr,
- btv->use_i2c_hw ? "hw" : "sw");
-
- i2c_set_adapdata(&btv->c.i2c_adap, &btv->c.v4l2_dev);
- btv->i2c_client.adapter = &btv->c.i2c_adap;
-
-
- if (btv->use_i2c_hw) {
- btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap);
- } else {
- bttv_bit_setscl(btv,1);
- bttv_bit_setsda(btv,1);
- btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap);
- }
- if (0 == btv->i2c_rc && i2c_scan)
- do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client);
-
- return btv->i2c_rc;
-}
diff --git a/drivers/media/video/bt8xx/bttv-if.c b/drivers/media/video/bt8xx/bttv-if.c
deleted file mode 100644
index a6a540dc9e4..00000000000
--- a/drivers/media/video/bt8xx/bttv-if.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-
- bttv-if.c -- old gpio interface to other kernel modules
- don't use in new code, will go away in 2.7
- have a look at bttv-gpio.c instead.
-
- bttv - Bt848 frame grabber driver
-
- Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
- (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-
-#include "bttvp.h"
-
-EXPORT_SYMBOL(bttv_get_pcidev);
-EXPORT_SYMBOL(bttv_gpio_enable);
-EXPORT_SYMBOL(bttv_read_gpio);
-EXPORT_SYMBOL(bttv_write_gpio);
-
-/* ----------------------------------------------------------------------- */
-/* Exported functions - for other modules which want to access the */
-/* gpio ports (IR for example) */
-/* see bttv.h for comments */
-
-struct pci_dev* bttv_get_pcidev(unsigned int card)
-{
- if (card >= bttv_num)
- return NULL;
- if (!bttvs[card])
- return NULL;
-
- return bttvs[card]->c.pci;
-}
-
-
-int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data)
-{
- struct bttv *btv;
-
- if (card >= bttv_num) {
- return -EINVAL;
- }
-
- btv = bttvs[card];
- if (!btv)
- return -ENODEV;
-
- gpio_inout(mask,data);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"extern enable");
- return 0;
-}
-
-int bttv_read_gpio(unsigned int card, unsigned long *data)
-{
- struct bttv *btv;
-
- if (card >= bttv_num) {
- return -EINVAL;
- }
-
- btv = bttvs[card];
- if (!btv)
- return -ENODEV;
-
- if(btv->shutdown) {
- return -ENODEV;
- }
-
-/* prior setting BT848_GPIO_REG_INP is (probably) not needed
- because we set direct input on init */
- *data = gpio_read();
- return 0;
-}
-
-int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data)
-{
- struct bttv *btv;
-
- if (card >= bttv_num) {
- return -EINVAL;
- }
-
- btv = bttvs[card];
- if (!btv)
- return -ENODEV;
-
-/* prior setting BT848_GPIO_REG_INP is (probably) not needed
- because direct input is set on init */
- gpio_bits(mask,data);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"extern write");
- return 0;
-}
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
deleted file mode 100644
index ef4c7cd4198..00000000000
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- *
- * Copyright (c) 2003 Gerd Knorr
- * Copyright (c) 2003 Pavel Machek
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/input.h>
-#include <linux/slab.h>
-
-#include "bttv.h"
-#include "bttvp.h"
-
-
-static int ir_debug;
-module_param(ir_debug, int, 0644);
-
-static int ir_rc5_remote_gap = 885;
-module_param(ir_rc5_remote_gap, int, 0644);
-
-#undef dprintk
-#define dprintk(fmt, ...) \
-do { \
- if (ir_debug >= 1) \
- pr_info(fmt, ##__VA_ARGS__); \
-} while (0)
-
-#define DEVNAME "bttv-input"
-
-#define MODULE_NAME "bttv"
-
-/* ---------------------------------------------------------------------- */
-
-static void ir_handle_key(struct bttv *btv)
-{
- struct bttv_ir *ir = btv->remote;
- u32 gpio,data;
-
- /* read gpio value */
- gpio = bttv_gpio_read(&btv->c);
- if (ir->polling) {
- if (ir->last_gpio == gpio)
- return;
- ir->last_gpio = gpio;
- }
-
- /* extract data */
- data = ir_extract_bits(gpio, ir->mask_keycode);
- dprintk("irq gpio=0x%x code=%d | %s%s%s\n",
- gpio, data,
- ir->polling ? "poll" : "irq",
- (gpio & ir->mask_keydown) ? " down" : "",
- (gpio & ir->mask_keyup) ? " up" : "");
-
- if ((ir->mask_keydown && (gpio & ir->mask_keydown)) ||
- (ir->mask_keyup && !(gpio & ir->mask_keyup))) {
- rc_keydown_notimeout(ir->dev, data, 0);
- } else {
- /* HACK: Probably, ir->mask_keydown is missing
- for this board */
- if (btv->c.type == BTTV_BOARD_WINFAST2000)
- rc_keydown_notimeout(ir->dev, data, 0);
-
- rc_keyup(ir->dev);
- }
-}
-
-static void ir_enltv_handle_key(struct bttv *btv)
-{
- struct bttv_ir *ir = btv->remote;
- u32 gpio, data, keyup;
-
- /* read gpio value */
- gpio = bttv_gpio_read(&btv->c);
-
- /* extract data */
- data = ir_extract_bits(gpio, ir->mask_keycode);
-
- /* Check if it is keyup */
- keyup = (gpio & ir->mask_keyup) ? 1 << 31 : 0;
-
- if ((ir->last_gpio & 0x7f) != data) {
- dprintk("gpio=0x%x code=%d | %s\n",
- gpio, data,
- (gpio & ir->mask_keyup) ? " up" : "up/down");
-
- rc_keydown_notimeout(ir->dev, data, 0);
- if (keyup)
- rc_keyup(ir->dev);
- } else {
- if ((ir->last_gpio & 1 << 31) == keyup)
- return;
-
- dprintk("(cnt) gpio=0x%x code=%d | %s\n",
- gpio, data,
- (gpio & ir->mask_keyup) ? " up" : "down");
-
- if (keyup)
- rc_keyup(ir->dev);
- else
- rc_keydown_notimeout(ir->dev, data, 0);
- }
-
- ir->last_gpio = data | keyup;
-}
-
-static int bttv_rc5_irq(struct bttv *btv);
-
-void bttv_input_irq(struct bttv *btv)
-{
- struct bttv_ir *ir = btv->remote;
-
- if (ir->rc5_gpio)
- bttv_rc5_irq(btv);
- else if (!ir->polling)
- ir_handle_key(btv);
-}
-
-static void bttv_input_timer(unsigned long data)
-{
- struct bttv *btv = (struct bttv*)data;
- struct bttv_ir *ir = btv->remote;
-
- if (btv->c.type == BTTV_BOARD_ENLTV_FM_2)
- ir_enltv_handle_key(btv);
- else
- ir_handle_key(btv);
- mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
-}
-
-/*
- * FIXME: Nebula digi uses the legacy way to decode RC5, instead of relying
- * on the rc-core way. As we need to be sure that both IRQ transitions are
- * properly triggered, Better to touch it only with this hardware for
- * testing.
- */
-
-#define RC5_START(x) (((x) >> 12) & 3)
-#define RC5_TOGGLE(x) (((x) >> 11) & 1)
-#define RC5_ADDR(x) (((x) >> 6) & 31)
-#define RC5_INSTR(x) ((x) & 63)
-
-/* decode raw bit pattern to RC5 code */
-static u32 bttv_rc5_decode(unsigned int code)
-{
- unsigned int org_code = code;
- unsigned int pair;
- unsigned int rc5 = 0;
- int i;
-
- for (i = 0; i < 14; ++i) {
- pair = code & 0x3;
- code >>= 2;
-
- rc5 <<= 1;
- switch (pair) {
- case 0:
- case 2:
- break;
- case 1:
- rc5 |= 1;
- break;
- case 3:
- dprintk("rc5_decode(%x) bad code\n",
- org_code);
- return 0;
- }
- }
- dprintk("code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
- "instr=%x\n", rc5, org_code, RC5_START(rc5),
- RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
- return rc5;
-}
-
-static void bttv_rc5_timer_end(unsigned long data)
-{
- struct bttv_ir *ir = (struct bttv_ir *)data;
- struct timeval tv;
- u32 gap;
- u32 rc5 = 0;
-
- /* get time */
- do_gettimeofday(&tv);
-
- /* avoid overflow with gap >1s */
- if (tv.tv_sec - ir->base_time.tv_sec > 1) {
- gap = 200000;
- } else {
- gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
- tv.tv_usec - ir->base_time.tv_usec;
- }
-
- /* signal we're ready to start a new code */
- ir->active = false;
-
- /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
- if (gap < 28000) {
- dprintk("spurious timer_end\n");
- return;
- }
-
- if (ir->last_bit < 20) {
- /* ignore spurious codes (caused by light/other remotes) */
- dprintk("short code: %x\n", ir->code);
- } else {
- ir->code = (ir->code << ir->shift_by) | 1;
- rc5 = bttv_rc5_decode(ir->code);
-
- /* two start bits? */
- if (RC5_START(rc5) != ir->start) {
- pr_info(DEVNAME ":"
- " rc5 start bits invalid: %u\n", RC5_START(rc5));
-
- /* right address? */
- } else if (RC5_ADDR(rc5) == ir->addr) {
- u32 toggle = RC5_TOGGLE(rc5);
- u32 instr = RC5_INSTR(rc5);
-
- /* Good code */
- rc_keydown(ir->dev, instr, toggle);
- dprintk("instruction %x, toggle %x\n",
- instr, toggle);
- }
- }
-}
-
-static int bttv_rc5_irq(struct bttv *btv)
-{
- struct bttv_ir *ir = btv->remote;
- struct timeval tv;
- u32 gpio;
- u32 gap;
- unsigned long current_jiffies;
-
- /* read gpio port */
- gpio = bttv_gpio_read(&btv->c);
-
- /* get time of bit */
- current_jiffies = jiffies;
- do_gettimeofday(&tv);
-
- /* avoid overflow with gap >1s */
- if (tv.tv_sec - ir->base_time.tv_sec > 1) {
- gap = 200000;
- } else {
- gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
- tv.tv_usec - ir->base_time.tv_usec;
- }
-
- dprintk("RC5 IRQ: gap %d us for %s\n",
- gap, (gpio & 0x20) ? "mark" : "space");
-
- /* remote IRQ? */
- if (!(gpio & 0x20))
- return 0;
-
- /* active code => add bit */
- if (ir->active) {
- /* only if in the code (otherwise spurious IRQ or timer
- late) */
- if (ir->last_bit < 28) {
- ir->last_bit = (gap - ir_rc5_remote_gap / 2) /
- ir_rc5_remote_gap;
- ir->code |= 1 << ir->last_bit;
- }
- /* starting new code */
- } else {
- ir->active = true;
- ir->code = 0;
- ir->base_time = tv;
- ir->last_bit = 0;
-
- mod_timer(&ir->timer, current_jiffies + msecs_to_jiffies(30));
- }
-
- /* toggle GPIO pin 4 to reset the irq */
- bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
- bttv_gpio_write(&btv->c, gpio | (1 << 4));
- return 1;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir)
-{
- if (ir->polling) {
- setup_timer(&ir->timer, bttv_input_timer, (unsigned long)btv);
- ir->timer.expires = jiffies + msecs_to_jiffies(1000);
- add_timer(&ir->timer);
- } else if (ir->rc5_gpio) {
- /* set timer_end for code completion */
- setup_timer(&ir->timer, bttv_rc5_timer_end, (unsigned long)ir);
- ir->shift_by = 1;
- ir->start = 3;
- ir->addr = 0x0;
- ir->rc5_remote_gap = ir_rc5_remote_gap;
- }
-}
-
-static void bttv_ir_stop(struct bttv *btv)
-{
- if (btv->remote->polling)
- del_timer_sync(&btv->remote->timer);
-
- if (btv->remote->rc5_gpio) {
- u32 gpio;
-
- del_timer_sync(&btv->remote->timer);
-
- gpio = bttv_gpio_read(&btv->c);
- bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
- }
-}
-
-/*
- * Get_key functions used by I2C remotes
- */
-
-static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- unsigned char b;
-
- /* poll IR chip */
- if (1 != i2c_master_recv(ir->c, &b, 1)) {
- dprintk("read error\n");
- return -EIO;
- }
-
- /* ignore 0xaa */
- if (b==0xaa)
- return 0;
- dprintk("key %02x\n", b);
-
- /*
- * NOTE:
- * lirc_i2c maps the pv951 code as:
- * addr = 0x61D6
- * cmd = bit_reverse (b)
- * So, it seems that this device uses NEC extended
- * I decided to not fix the table, due to two reasons:
- * 1) Without the actual device, this is only a guess;
- * 2) As the addr is not reported via I2C, nor can be changed,
- * the device is bound to the vendor-provided RC.
- */
-
- *ir_key = b;
- *ir_raw = b;
- return 1;
-}
-
-/* Instantiate the I2C IR receiver device, if present */
-void __devinit init_bttv_i2c_ir(struct bttv *btv)
-{
- const unsigned short addr_list[] = {
- 0x1a, 0x18, 0x64, 0x30, 0x71,
- I2C_CLIENT_END
- };
- struct i2c_board_info info;
-
- if (0 != btv->i2c_rc)
- return;
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- memset(&btv->init_data, 0, sizeof(btv->init_data));
- strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
-
- switch (btv->c.type) {
- case BTTV_BOARD_PV951:
- btv->init_data.name = "PV951";
- btv->init_data.get_key = get_key_pv951;
- btv->init_data.ir_codes = RC_MAP_PV951;
- info.addr = 0x4b;
- break;
- default:
- /*
- * The external IR receiver is at i2c address 0x34 (0x35 for
- * reads). Future Hauppauge cards will have an internal
- * receiver at 0x30 (0x31 for reads). In theory, both can be
- * fitted, and Hauppauge suggest an external overrides an
- * internal.
- * That's why we probe 0x1a (~0x34) first. CB
- */
-
- i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list, NULL);
- return;
- }
-
- if (btv->init_data.name)
- info.platform_data = &btv->init_data;
- i2c_new_device(&btv->c.i2c_adap, &info);
-
- return;
-}
-
-int __devexit fini_bttv_i2c(struct bttv *btv)
-{
- if (0 != btv->i2c_rc)
- return 0;
-
- return i2c_del_adapter(&btv->c.i2c_adap);
-}
-
-int bttv_input_init(struct bttv *btv)
-{
- struct bttv_ir *ir;
- char *ir_codes = NULL;
- struct rc_dev *rc;
- int err = -ENOMEM;
-
- if (!btv->has_remote)
- return -ENODEV;
-
- ir = kzalloc(sizeof(*ir),GFP_KERNEL);
- rc = rc_allocate_device();
- if (!ir || !rc)
- goto err_out_free;
-
- /* detect & configure */
- switch (btv->c.type) {
- case BTTV_BOARD_AVERMEDIA:
- case BTTV_BOARD_AVPHONE98:
- case BTTV_BOARD_AVERMEDIA98:
- ir_codes = RC_MAP_AVERMEDIA;
- ir->mask_keycode = 0xf88000;
- ir->mask_keydown = 0x010000;
- ir->polling = 50; // ms
- break;
-
- case BTTV_BOARD_AVDVBT_761:
- case BTTV_BOARD_AVDVBT_771:
- ir_codes = RC_MAP_AVERMEDIA_DVBT;
- ir->mask_keycode = 0x0f00c0;
- ir->mask_keydown = 0x000020;
- ir->polling = 50; // ms
- break;
-
- case BTTV_BOARD_PXELVWPLTVPAK:
- ir_codes = RC_MAP_PIXELVIEW;
- ir->mask_keycode = 0x003e00;
- ir->mask_keyup = 0x010000;
- ir->polling = 50; // ms
- break;
- case BTTV_BOARD_PV_M4900:
- case BTTV_BOARD_PV_BT878P_9B:
- case BTTV_BOARD_PV_BT878P_PLUS:
- ir_codes = RC_MAP_PIXELVIEW;
- ir->mask_keycode = 0x001f00;
- ir->mask_keyup = 0x008000;
- ir->polling = 50; // ms
- break;
-
- case BTTV_BOARD_WINFAST2000:
- ir_codes = RC_MAP_WINFAST;
- ir->mask_keycode = 0x1f8;
- break;
- case BTTV_BOARD_MAGICTVIEW061:
- case BTTV_BOARD_MAGICTVIEW063:
- ir_codes = RC_MAP_WINFAST;
- ir->mask_keycode = 0x0008e000;
- ir->mask_keydown = 0x00200000;
- break;
- case BTTV_BOARD_APAC_VIEWCOMP:
- ir_codes = RC_MAP_APAC_VIEWCOMP;
- ir->mask_keycode = 0x001f00;
- ir->mask_keyup = 0x008000;
- ir->polling = 50; // ms
- break;
- case BTTV_BOARD_ASKEY_CPH03X:
- case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
- case BTTV_BOARD_CONTVFMI:
- ir_codes = RC_MAP_PIXELVIEW;
- ir->mask_keycode = 0x001F00;
- ir->mask_keyup = 0x006000;
- ir->polling = 50; // ms
- break;
- case BTTV_BOARD_NEBULA_DIGITV:
- ir_codes = RC_MAP_NEBULA;
- ir->rc5_gpio = true;
- break;
- case BTTV_BOARD_MACHTV_MAGICTV:
- ir_codes = RC_MAP_APAC_VIEWCOMP;
- ir->mask_keycode = 0x001F00;
- ir->mask_keyup = 0x004000;
- ir->polling = 50; /* ms */
- break;
- case BTTV_BOARD_KOZUMI_KTV_01C:
- ir_codes = RC_MAP_PCTV_SEDNA;
- ir->mask_keycode = 0x001f00;
- ir->mask_keyup = 0x006000;
- ir->polling = 50; /* ms */
- break;
- case BTTV_BOARD_ENLTV_FM_2:
- ir_codes = RC_MAP_ENCORE_ENLTV2;
- ir->mask_keycode = 0x00fd00;
- ir->mask_keyup = 0x000080;
- ir->polling = 1; /* ms */
- ir->last_gpio = ir_extract_bits(bttv_gpio_read(&btv->c),
- ir->mask_keycode);
- break;
- }
- if (NULL == ir_codes) {
- dprintk("Ooops: IR config error [card=%d]\n", btv->c.type);
- err = -ENODEV;
- goto err_out_free;
- }
-
- if (ir->rc5_gpio) {
- u32 gpio;
- /* enable remote irq */
- bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4);
- gpio = bttv_gpio_read(&btv->c);
- bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
- bttv_gpio_write(&btv->c, gpio | (1 << 4));
- } else {
- /* init hardware-specific stuff */
- bttv_gpio_inout(&btv->c, ir->mask_keycode | ir->mask_keydown, 0);
- }
-
- /* init input device */
- ir->dev = rc;
-
- snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
- btv->c.type);
- snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
- pci_name(btv->c.pci));
-
- rc->input_name = ir->name;
- rc->input_phys = ir->phys;
- rc->input_id.bustype = BUS_PCI;
- rc->input_id.version = 1;
- if (btv->c.pci->subsystem_vendor) {
- rc->input_id.vendor = btv->c.pci->subsystem_vendor;
- rc->input_id.product = btv->c.pci->subsystem_device;
- } else {
- rc->input_id.vendor = btv->c.pci->vendor;
- rc->input_id.product = btv->c.pci->device;
- }
- rc->dev.parent = &btv->c.pci->dev;
- rc->map_name = ir_codes;
- rc->driver_name = MODULE_NAME;
-
- btv->remote = ir;
- bttv_ir_start(btv, ir);
-
- /* all done */
- err = rc_register_device(rc);
- if (err)
- goto err_out_stop;
-
- return 0;
-
- err_out_stop:
- bttv_ir_stop(btv);
- btv->remote = NULL;
- err_out_free:
- rc_free_device(rc);
- kfree(ir);
- return err;
-}
-
-void bttv_input_fini(struct bttv *btv)
-{
- if (btv->remote == NULL)
- return;
-
- bttv_ir_stop(btv);
- rc_unregister_device(btv->remote->dev);
- kfree(btv->remote);
- btv->remote = NULL;
-}
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c
deleted file mode 100644
index 82cc47d2e3f..00000000000
--- a/drivers/media/video/bt8xx/bttv-risc.c
+++ /dev/null
@@ -1,909 +0,0 @@
-/*
-
- bttv-risc.c -- interfaces to other kernel modules
-
- bttv risc code handling
- - memory management
- - generation
-
- (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/vmalloc.h>
-#include <linux/interrupt.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <media/v4l2-ioctl.h>
-
-#include "bttvp.h"
-
-#define VCR_HACK_LINES 4
-
-/* ---------------------------------------------------------- */
-/* risc code generators */
-
-int
-bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
- struct scatterlist *sglist,
- unsigned int offset, unsigned int bpl,
- unsigned int padding, unsigned int skip_lines,
- unsigned int store_lines)
-{
- u32 instructions,line,todo;
- struct scatterlist *sg;
- __le32 *rp;
- int rc;
-
- /* estimate risc mem: worst case is one write per page border +
- one write per scan line + sync + jump (all 2 dwords). padding
- can cause next bpl to start close to a page border. First DMA
- region may be smaller than PAGE_SIZE */
- instructions = skip_lines * 4;
- instructions += (1 + ((bpl + padding) * store_lines)
- / PAGE_SIZE + store_lines) * 8;
- instructions += 2 * 8;
- if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions)) < 0)
- return rc;
-
- /* sync instruction */
- rp = risc->cpu;
- *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
- *(rp++) = cpu_to_le32(0);
-
- while (skip_lines-- > 0) {
- *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL |
- BT848_RISC_EOL | bpl);
- }
-
- /* scan lines */
- sg = sglist;
- for (line = 0; line < store_lines; line++) {
- if ((btv->opt_vcr_hack) &&
- (line >= (store_lines - VCR_HACK_LINES)))
- continue;
- while (offset && offset >= sg_dma_len(sg)) {
- offset -= sg_dma_len(sg);
- sg++;
- }
- if (bpl <= sg_dma_len(sg)-offset) {
- /* fits into current chunk */
- *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
- BT848_RISC_EOL|bpl);
- *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
- offset+=bpl;
- } else {
- /* scanline needs to be splitted */
- todo = bpl;
- *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
- (sg_dma_len(sg)-offset));
- *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
- todo -= (sg_dma_len(sg)-offset);
- offset = 0;
- sg++;
- while (todo > sg_dma_len(sg)) {
- *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
- sg_dma_len(sg));
- *(rp++)=cpu_to_le32(sg_dma_address(sg));
- todo -= sg_dma_len(sg);
- sg++;
- }
- *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
- todo);
- *(rp++)=cpu_to_le32(sg_dma_address(sg));
- offset += todo;
- }
- offset += padding;
- }
-
- /* save pointer to jmp instruction address */
- risc->jmp = rp;
- BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
- return 0;
-}
-
-static int
-bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
- struct scatterlist *sglist,
- unsigned int yoffset, unsigned int ybpl,
- unsigned int ypadding, unsigned int ylines,
- unsigned int uoffset, unsigned int voffset,
- unsigned int hshift, unsigned int vshift,
- unsigned int cpadding)
-{
- unsigned int instructions,line,todo,ylen,chroma;
- __le32 *rp;
- u32 ri;
- struct scatterlist *ysg;
- struct scatterlist *usg;
- struct scatterlist *vsg;
- int topfield = (0 == yoffset);
- int rc;
-
- /* estimate risc mem: worst case is one write per page border +
- one write per scan line (5 dwords)
- plus sync + jump (2 dwords) */
- instructions = ((3 + (ybpl + ypadding) * ylines * 2)
- / PAGE_SIZE) + ylines;
- instructions += 2;
- if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
- return rc;
-
- /* sync instruction */
- rp = risc->cpu;
- *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
- *(rp++) = cpu_to_le32(0);
-
- /* scan lines */
- ysg = sglist;
- usg = sglist;
- vsg = sglist;
- for (line = 0; line < ylines; line++) {
- if ((btv->opt_vcr_hack) &&
- (line >= (ylines - VCR_HACK_LINES)))
- continue;
- switch (vshift) {
- case 0:
- chroma = 1;
- break;
- case 1:
- if (topfield)
- chroma = ((line & 1) == 0);
- else
- chroma = ((line & 1) == 1);
- break;
- case 2:
- if (topfield)
- chroma = ((line & 3) == 0);
- else
- chroma = ((line & 3) == 2);
- break;
- default:
- chroma = 0;
- break;
- }
-
- for (todo = ybpl; todo > 0; todo -= ylen) {
- /* go to next sg entry if needed */
- while (yoffset && yoffset >= sg_dma_len(ysg)) {
- yoffset -= sg_dma_len(ysg);
- ysg++;
- }
- while (uoffset && uoffset >= sg_dma_len(usg)) {
- uoffset -= sg_dma_len(usg);
- usg++;
- }
- while (voffset && voffset >= sg_dma_len(vsg)) {
- voffset -= sg_dma_len(vsg);
- vsg++;
- }
-
- /* calculate max number of bytes we can write */
- ylen = todo;
- if (yoffset + ylen > sg_dma_len(ysg))
- ylen = sg_dma_len(ysg) - yoffset;
- if (chroma) {
- if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
- ylen = (sg_dma_len(usg) - uoffset) << hshift;
- if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
- ylen = (sg_dma_len(vsg) - voffset) << hshift;
- ri = BT848_RISC_WRITE123;
- } else {
- ri = BT848_RISC_WRITE1S23;
- }
- if (ybpl == todo)
- ri |= BT848_RISC_SOL;
- if (ylen == todo)
- ri |= BT848_RISC_EOL;
-
- /* write risc instruction */
- *(rp++)=cpu_to_le32(ri | ylen);
- *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
- (ylen >> hshift));
- *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
- yoffset += ylen;
- if (chroma) {
- *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
- uoffset += ylen >> hshift;
- *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
- voffset += ylen >> hshift;
- }
- }
- yoffset += ypadding;
- if (chroma) {
- uoffset += cpadding;
- voffset += cpadding;
- }
- }
-
- /* save pointer to jmp instruction address */
- risc->jmp = rp;
- BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
- return 0;
-}
-
-static int
-bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
- const struct bttv_format *fmt, struct bttv_overlay *ov,
- int skip_even, int skip_odd)
-{
- int dwords, rc, line, maxy, start, end;
- unsigned skip, nskips;
- struct btcx_skiplist *skips;
- __le32 *rp;
- u32 ri,ra;
- u32 addr;
-
- /* skip list for window clipping */
- if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
- return -ENOMEM;
-
- /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
- + sync + jump (all 2 dwords) */
- dwords = (3 * ov->nclips + 2) *
- ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height);
- dwords += 4;
- if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
- kfree(skips);
- return rc;
- }
-
- /* sync instruction */
- rp = risc->cpu;
- *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
- *(rp++) = cpu_to_le32(0);
-
- addr = (unsigned long)btv->fbuf.base;
- addr += btv->fbuf.fmt.bytesperline * ov->w.top;
- addr += (fmt->depth >> 3) * ov->w.left;
-
- /* scan lines */
- for (maxy = -1, line = 0; line < ov->w.height;
- line++, addr += btv->fbuf.fmt.bytesperline) {
- if ((btv->opt_vcr_hack) &&
- (line >= (ov->w.height - VCR_HACK_LINES)))
- continue;
- if ((line%2) == 0 && skip_even)
- continue;
- if ((line%2) == 1 && skip_odd)
- continue;
-
- /* calculate clipping */
- if (line > maxy)
- btcx_calc_skips(line, ov->w.width, &maxy,
- skips, &nskips, ov->clips, ov->nclips);
-
- /* write out risc code */
- for (start = 0, skip = 0; start < ov->w.width; start = end) {
- if (skip >= nskips) {
- ri = BT848_RISC_WRITE;
- end = ov->w.width;
- } else if (start < skips[skip].start) {
- ri = BT848_RISC_WRITE;
- end = skips[skip].start;
- } else {
- ri = BT848_RISC_SKIP;
- end = skips[skip].end;
- skip++;
- }
- if (BT848_RISC_WRITE == ri)
- ra = addr + (fmt->depth>>3)*start;
- else
- ra = 0;
-
- if (0 == start)
- ri |= BT848_RISC_SOL;
- if (ov->w.width == end)
- ri |= BT848_RISC_EOL;
- ri |= (fmt->depth>>3) * (end-start);
-
- *(rp++)=cpu_to_le32(ri);
- if (0 != ra)
- *(rp++)=cpu_to_le32(ra);
- }
- }
-
- /* save pointer to jmp instruction address */
- risc->jmp = rp;
- BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
- kfree(skips);
- return 0;
-}
-
-/* ---------------------------------------------------------- */
-
-static void
-bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
- int width, int height, int interleaved,
- const struct bttv_tvnorm *tvnorm)
-{
- u32 xsf, sr;
- int vdelay;
-
- int swidth = tvnorm->swidth;
- int totalwidth = tvnorm->totalwidth;
- int scaledtwidth = tvnorm->scaledtwidth;
-
- if (btv->input == btv->dig) {
- swidth = 720;
- totalwidth = 858;
- scaledtwidth = 858;
- }
-
- vdelay = tvnorm->vdelay;
-
- xsf = (width*scaledtwidth)/swidth;
- geo->hscale = ((totalwidth*4096UL)/xsf-4096);
- geo->hdelay = tvnorm->hdelayx1;
- geo->hdelay = (geo->hdelay*width)/swidth;
- geo->hdelay &= 0x3fe;
- sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
- geo->vscale = (0x10000UL-sr) & 0x1fff;
- geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
- ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
- geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
- geo->vdelay = vdelay;
- geo->width = width;
- geo->sheight = tvnorm->sheight;
- geo->vtotal = tvnorm->vtotal;
-
- if (btv->opt_combfilter) {
- geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
- geo->comb = (width < 769) ? 1 : 0;
- } else {
- geo->vtc = 0;
- geo->comb = 0;
- }
-}
-
-static void
-bttv_calc_geo (struct bttv * btv,
- struct bttv_geometry * geo,
- unsigned int width,
- unsigned int height,
- int both_fields,
- const struct bttv_tvnorm * tvnorm,
- const struct v4l2_rect * crop)
-{
- unsigned int c_width;
- unsigned int c_height;
- u32 sr;
-
- if ((crop->left == tvnorm->cropcap.defrect.left
- && crop->top == tvnorm->cropcap.defrect.top
- && crop->width == tvnorm->cropcap.defrect.width
- && crop->height == tvnorm->cropcap.defrect.height
- && width <= tvnorm->swidth /* see PAL-Nc et al */)
- || btv->input == btv->dig) {
- bttv_calc_geo_old(btv, geo, width, height,
- both_fields, tvnorm);
- return;
- }
-
- /* For bug compatibility the image size checks permit scale
- factors > 16. See bttv_crop_calc_limits(). */
- c_width = min((unsigned int) crop->width, width * 16);
- c_height = min((unsigned int) crop->height, height * 16);
-
- geo->width = width;
- geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096;
- /* Even to store Cb first, odd for Cr. */
- geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1;
-
- geo->sheight = c_height;
- geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY;
- sr = c_height >> !both_fields;
- sr = (sr * 512U + (height >> 1)) / height - 512;
- geo->vscale = (0x10000UL - sr) & 0x1fff;
- geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0;
- geo->vtotal = tvnorm->vtotal;
-
- geo->crop = (((geo->width >> 8) & 0x03) |
- ((geo->hdelay >> 6) & 0x0c) |
- ((geo->sheight >> 4) & 0x30) |
- ((geo->vdelay >> 2) & 0xc0));
-
- if (btv->opt_combfilter) {
- geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
- geo->comb = (width < 769) ? 1 : 0;
- } else {
- geo->vtc = 0;
- geo->comb = 0;
- }
-}
-
-static void
-bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
-{
- int off = odd ? 0x80 : 0x00;
-
- if (geo->comb)
- btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
- else
- btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
-
- btwrite(geo->vtc, BT848_E_VTC+off);
- btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
- btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
- btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
- btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
- btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
- btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
- btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
- btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
- btwrite(geo->crop, BT848_E_CROP+off);
- btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
- btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
-}
-
-/* ---------------------------------------------------------- */
-/* risc group / risc main loop / dma management */
-
-void
-bttv_set_dma(struct bttv *btv, int override)
-{
- unsigned long cmd;
- int capctl;
-
- btv->cap_ctl = 0;
- if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
- if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
- if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
-
- capctl = 0;
- capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
- capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
- capctl |= override;
-
- d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n",
- btv->c.nr,capctl,btv->loop_irq,
- btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
- btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
- btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
- btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
-
- cmd = BT848_RISC_JUMP;
- if (btv->loop_irq) {
- cmd |= BT848_RISC_IRQ;
- cmd |= (btv->loop_irq & 0x0f) << 16;
- cmd |= (~btv->loop_irq & 0x0f) << 20;
- }
- if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
- mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
- } else {
- del_timer(&btv->timeout);
- }
- btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
-
- btaor(capctl, ~0x0f, BT848_CAP_CTL);
- if (capctl) {
- if (btv->dma_on)
- return;
- btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
- btor(3, BT848_GPIO_DMA_CTL);
- btv->dma_on = 1;
- } else {
- if (!btv->dma_on)
- return;
- btand(~3, BT848_GPIO_DMA_CTL);
- btv->dma_on = 0;
- }
- return;
-}
-
-int
-bttv_risc_init_main(struct bttv *btv)
-{
- int rc;
-
- if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
- return rc;
- dprintk("%d: risc main @ %08llx\n",
- btv->c.nr, (unsigned long long)btv->main.dma);
-
- btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
- BT848_FIFO_STATUS_VRE);
- btv->main.cpu[1] = cpu_to_le32(0);
- btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
- btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
-
- /* top field */
- btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
- btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
- btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
- btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
-
- btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
- BT848_FIFO_STATUS_VRO);
- btv->main.cpu[9] = cpu_to_le32(0);
-
- /* bottom field */
- btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
- btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
- btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
- btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
-
- /* jump back to top field */
- btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
- btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
-
- return 0;
-}
-
-int
-bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
- int irqflags)
-{
- unsigned long cmd;
- unsigned long next = btv->main.dma + ((slot+2) << 2);
-
- if (NULL == risc) {
- d2printk("%d: risc=%p slot[%d]=NULL\n", btv->c.nr, risc, slot);
- btv->main.cpu[slot+1] = cpu_to_le32(next);
- } else {
- d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n",
- btv->c.nr, risc, slot,
- (unsigned long long)risc->dma, irqflags);
- cmd = BT848_RISC_JUMP;
- if (irqflags) {
- cmd |= BT848_RISC_IRQ;
- cmd |= (irqflags & 0x0f) << 16;
- cmd |= (~irqflags & 0x0f) << 20;
- }
- risc->jmp[0] = cpu_to_le32(cmd);
- risc->jmp[1] = cpu_to_le32(next);
- btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
- }
- return 0;
-}
-
-void
-bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
-{
- struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
-
- BUG_ON(in_interrupt());
- videobuf_waiton(q, &buf->vb, 0, 0);
- videobuf_dma_unmap(q->dev, dma);
- videobuf_dma_free(dma);
- btcx_riscmem_free(btv->c.pci,&buf->bottom);
- btcx_riscmem_free(btv->c.pci,&buf->top);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-int
-bttv_buffer_activate_vbi(struct bttv *btv,
- struct bttv_buffer *vbi)
-{
- struct btcx_riscmem *top;
- struct btcx_riscmem *bottom;
- int top_irq_flags;
- int bottom_irq_flags;
-
- top = NULL;
- bottom = NULL;
- top_irq_flags = 0;
- bottom_irq_flags = 0;
-
- if (vbi) {
- unsigned int crop, vdelay;
-
- vbi->vb.state = VIDEOBUF_ACTIVE;
- list_del(&vbi->vb.queue);
-
- /* VDELAY is start of video, end of VBI capturing. */
- crop = btread(BT848_E_CROP);
- vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
-
- if (vbi->geo.vdelay > vdelay) {
- vdelay = vbi->geo.vdelay & 0xfe;
- crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
-
- btwrite(vdelay, BT848_E_VDELAY_LO);
- btwrite(crop, BT848_E_CROP);
- btwrite(vdelay, BT848_O_VDELAY_LO);
- btwrite(crop, BT848_O_CROP);
- }
-
- if (vbi->vbi_count[0] > 0) {
- top = &vbi->top;
- top_irq_flags = 4;
- }
-
- if (vbi->vbi_count[1] > 0) {
- top_irq_flags = 0;
- bottom = &vbi->bottom;
- bottom_irq_flags = 4;
- }
- }
-
- bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
- bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
-
- return 0;
-}
-
-int
-bttv_buffer_activate_video(struct bttv *btv,
- struct bttv_buffer_set *set)
-{
- /* video capture */
- if (NULL != set->top && NULL != set->bottom) {
- if (set->top == set->bottom) {
- set->top->vb.state = VIDEOBUF_ACTIVE;
- if (set->top->vb.queue.next)
- list_del(&set->top->vb.queue);
- } else {
- set->top->vb.state = VIDEOBUF_ACTIVE;
- set->bottom->vb.state = VIDEOBUF_ACTIVE;
- if (set->top->vb.queue.next)
- list_del(&set->top->vb.queue);
- if (set->bottom->vb.queue.next)
- list_del(&set->bottom->vb.queue);
- }
- bttv_apply_geo(btv, &set->top->geo, 1);
- bttv_apply_geo(btv, &set->bottom->geo,0);
- bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
- set->top_irq);
- bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
- set->frame_irq);
- btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
- ~0xff, BT848_COLOR_FMT);
- btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
- ~0x0f, BT848_COLOR_CTL);
- } else if (NULL != set->top) {
- set->top->vb.state = VIDEOBUF_ACTIVE;
- if (set->top->vb.queue.next)
- list_del(&set->top->vb.queue);
- bttv_apply_geo(btv, &set->top->geo,1);
- bttv_apply_geo(btv, &set->top->geo,0);
- bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
- set->frame_irq);
- bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
- btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
- btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
- } else if (NULL != set->bottom) {
- set->bottom->vb.state = VIDEOBUF_ACTIVE;
- if (set->bottom->vb.queue.next)
- list_del(&set->bottom->vb.queue);
- bttv_apply_geo(btv, &set->bottom->geo,1);
- bttv_apply_geo(btv, &set->bottom->geo,0);
- bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
- bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
- set->frame_irq);
- btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
- btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
- } else {
- bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
- bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
- }
- return 0;
-}
-
-/* ---------------------------------------------------------- */
-
-/* calculate geometry, build risc code */
-int
-bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
-{
- const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
- struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
-
- dprintk("%d: buffer field: %s format: %s size: %dx%d\n",
- btv->c.nr, v4l2_field_names[buf->vb.field],
- buf->fmt->name, buf->vb.width, buf->vb.height);
-
- /* packed pixel modes */
- if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
- int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
- int bpf = bpl * (buf->vb.height >> 1);
-
- bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
- V4L2_FIELD_HAS_BOTH(buf->vb.field),
- tvnorm,&buf->crop);
-
- switch (buf->vb.field) {
- case V4L2_FIELD_TOP:
- bttv_risc_packed(btv,&buf->top,dma->sglist,
- /* offset */ 0,bpl,
- /* padding */ 0,/* skip_lines */ 0,
- buf->vb.height);
- break;
- case V4L2_FIELD_BOTTOM:
- bttv_risc_packed(btv,&buf->bottom,dma->sglist,
- 0,bpl,0,0,buf->vb.height);
- break;
- case V4L2_FIELD_INTERLACED:
- bttv_risc_packed(btv,&buf->top,dma->sglist,
- 0,bpl,bpl,0,buf->vb.height >> 1);
- bttv_risc_packed(btv,&buf->bottom,dma->sglist,
- bpl,bpl,bpl,0,buf->vb.height >> 1);
- break;
- case V4L2_FIELD_SEQ_TB:
- bttv_risc_packed(btv,&buf->top,dma->sglist,
- 0,bpl,0,0,buf->vb.height >> 1);
- bttv_risc_packed(btv,&buf->bottom,dma->sglist,
- bpf,bpl,0,0,buf->vb.height >> 1);
- break;
- default:
- BUG();
- }
- }
-
- /* planar modes */
- if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
- int uoffset, voffset;
- int ypadding, cpadding, lines;
-
- /* calculate chroma offsets */
- uoffset = buf->vb.width * buf->vb.height;
- voffset = buf->vb.width * buf->vb.height;
- if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
- /* Y-Cr-Cb plane order */
- uoffset >>= buf->fmt->hshift;
- uoffset >>= buf->fmt->vshift;
- uoffset += voffset;
- } else {
- /* Y-Cb-Cr plane order */
- voffset >>= buf->fmt->hshift;
- voffset >>= buf->fmt->vshift;
- voffset += uoffset;
- }
-
- switch (buf->vb.field) {
- case V4L2_FIELD_TOP:
- bttv_calc_geo(btv,&buf->geo,buf->vb.width,
- buf->vb.height,/* both_fields */ 0,
- tvnorm,&buf->crop);
- bttv_risc_planar(btv, &buf->top, dma->sglist,
- 0,buf->vb.width,0,buf->vb.height,
- uoffset,voffset,buf->fmt->hshift,
- buf->fmt->vshift,0);
- break;
- case V4L2_FIELD_BOTTOM:
- bttv_calc_geo(btv,&buf->geo,buf->vb.width,
- buf->vb.height,0,
- tvnorm,&buf->crop);
- bttv_risc_planar(btv, &buf->bottom, dma->sglist,
- 0,buf->vb.width,0,buf->vb.height,
- uoffset,voffset,buf->fmt->hshift,
- buf->fmt->vshift,0);
- break;
- case V4L2_FIELD_INTERLACED:
- bttv_calc_geo(btv,&buf->geo,buf->vb.width,
- buf->vb.height,1,
- tvnorm,&buf->crop);
- lines = buf->vb.height >> 1;
- ypadding = buf->vb.width;
- cpadding = buf->vb.width >> buf->fmt->hshift;
- bttv_risc_planar(btv,&buf->top,
- dma->sglist,
- 0,buf->vb.width,ypadding,lines,
- uoffset,voffset,
- buf->fmt->hshift,
- buf->fmt->vshift,
- cpadding);
- bttv_risc_planar(btv,&buf->bottom,
- dma->sglist,
- ypadding,buf->vb.width,ypadding,lines,
- uoffset+cpadding,
- voffset+cpadding,
- buf->fmt->hshift,
- buf->fmt->vshift,
- cpadding);
- break;
- case V4L2_FIELD_SEQ_TB:
- bttv_calc_geo(btv,&buf->geo,buf->vb.width,
- buf->vb.height,1,
- tvnorm,&buf->crop);
- lines = buf->vb.height >> 1;
- ypadding = buf->vb.width;
- cpadding = buf->vb.width >> buf->fmt->hshift;
- bttv_risc_planar(btv,&buf->top,
- dma->sglist,
- 0,buf->vb.width,0,lines,
- uoffset >> 1,
- voffset >> 1,
- buf->fmt->hshift,
- buf->fmt->vshift,
- 0);
- bttv_risc_planar(btv,&buf->bottom,
- dma->sglist,
- lines * ypadding,buf->vb.width,0,lines,
- lines * ypadding + (uoffset >> 1),
- lines * ypadding + (voffset >> 1),
- buf->fmt->hshift,
- buf->fmt->vshift,
- 0);
- break;
- default:
- BUG();
- }
- }
-
- /* raw data */
- if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
- /* build risc code */
- buf->vb.field = V4L2_FIELD_SEQ_TB;
- bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
- 1,tvnorm,&buf->crop);
- bttv_risc_packed(btv, &buf->top, dma->sglist,
- /* offset */ 0, RAW_BPL, /* padding */ 0,
- /* skip_lines */ 0, RAW_LINES);
- bttv_risc_packed(btv, &buf->bottom, dma->sglist,
- buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
- }
-
- /* copy format info */
- buf->btformat = buf->fmt->btformat;
- buf->btswap = buf->fmt->btswap;
- return 0;
-}
-
-/* ---------------------------------------------------------- */
-
-/* calculate geometry, build risc code */
-int
-bttv_overlay_risc(struct bttv *btv,
- struct bttv_overlay *ov,
- const struct bttv_format *fmt,
- struct bttv_buffer *buf)
-{
- /* check interleave, bottom+top fields */
- dprintk("%d: overlay fields: %s format: %s size: %dx%d\n",
- btv->c.nr, v4l2_field_names[buf->vb.field],
- fmt->name, ov->w.width, ov->w.height);
-
- /* calculate geometry */
- bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
- V4L2_FIELD_HAS_BOTH(ov->field),
- &bttv_tvnorms[ov->tvnorm],&buf->crop);
-
- /* build risc code */
- switch (ov->field) {
- case V4L2_FIELD_TOP:
- bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
- break;
- case V4L2_FIELD_BOTTOM:
- bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
- break;
- case V4L2_FIELD_INTERLACED:
- bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
- bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
- break;
- default:
- BUG();
- }
-
- /* copy format info */
- buf->btformat = fmt->btformat;
- buf->btswap = fmt->btswap;
- buf->vb.field = ov->field;
- return 0;
-}
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c
deleted file mode 100644
index b433267d9aa..00000000000
--- a/drivers/media/video/bt8xx/bttv-vbi.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
-
- bttv - Bt848 frame grabber driver
- vbi interface
-
- (c) 2002 Gerd Knorr <kraxel@bytesex.org>
-
- Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at>
- Sponsored by OPQ Systems AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/kdev_t.h>
-#include <media/v4l2-ioctl.h>
-#include <asm/io.h>
-#include "bttvp.h"
-
-/* Offset from line sync pulse leading edge (0H) to start of VBI capture,
- in fCLKx2 pixels. According to the datasheet, VBI capture starts
- VBI_HDELAY fCLKx1 pixels from the tailing edgeof /HRESET, and /HRESET
- is 64 fCLKx1 pixels wide. VBI_HDELAY is set to 0, so this should be
- (64 + 0) * 2 = 128 fCLKx2 pixels. But it's not! The datasheet is
- Just Plain Wrong. The real value appears to be different for
- different revisions of the bt8x8 chips, and to be affected by the
- horizontal scaling factor. Experimentally, the value is measured
- to be about 244. */
-#define VBI_OFFSET 244
-
-/* 2048 for compatibility with earlier driver versions. The driver
- really stores 1024 + tvnorm->vbipack * 4 samples per line in the
- buffer. Note tvnorm->vbipack is <= 0xFF (limit of VBIPACK_LO + HI
- is 0x1FF DWORDs) and VBI read()s store a frame counter in the last
- four bytes of the VBI image. */
-#define VBI_BPL 2048
-
-/* Compatibility. */
-#define VBI_DEFLINES 16
-
-static unsigned int vbibufs = 4;
-static unsigned int vbi_debug;
-
-module_param(vbibufs, int, 0444);
-module_param(vbi_debug, int, 0644);
-MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32, default 4");
-MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)");
-
-#ifdef dprintk
-# undef dprintk
-#endif
-#define dprintk(fmt, ...) \
-do { \
- if (vbi_debug) \
- pr_debug("%d: " fmt, btv->c.nr, ##__VA_ARGS__); \
-} while (0)
-
-#define IMAGE_SIZE(fmt) \
- (((fmt)->count[0] + (fmt)->count[1]) * (fmt)->samples_per_line)
-
-/* ----------------------------------------------------------------------- */
-/* vbi risc code + mm */
-
-static int vbi_buffer_setup(struct videobuf_queue *q,
- unsigned int *count, unsigned int *size)
-{
- struct bttv_fh *fh = q->priv_data;
- struct bttv *btv = fh->btv;
-
- if (0 == *count)
- *count = vbibufs;
-
- *size = IMAGE_SIZE(&fh->vbi_fmt.fmt);
-
- dprintk("setup: samples=%u start=%d,%d count=%u,%u\n",
- fh->vbi_fmt.fmt.samples_per_line,
- fh->vbi_fmt.fmt.start[0],
- fh->vbi_fmt.fmt.start[1],
- fh->vbi_fmt.fmt.count[0],
- fh->vbi_fmt.fmt.count[1]);
-
- return 0;
-}
-
-static int vbi_buffer_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct bttv_fh *fh = q->priv_data;
- struct bttv *btv = fh->btv;
- struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
- const struct bttv_tvnorm *tvnorm;
- unsigned int skip_lines0, skip_lines1, min_vdelay;
- int redo_dma_risc;
- int rc;
-
- buf->vb.size = IMAGE_SIZE(&fh->vbi_fmt.fmt);
- if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
- return -EINVAL;
-
- tvnorm = fh->vbi_fmt.tvnorm;
-
- /* There's no VBI_VDELAY register, RISC must skip the lines
- we don't want. With default parameters we skip zero lines
- as earlier driver versions did. The driver permits video
- standard changes while capturing, so we use vbi_fmt.tvnorm
- instead of btv->tvnorm to skip zero lines after video
- standard changes as well. */
-
- skip_lines0 = 0;
- skip_lines1 = 0;
-
- if (fh->vbi_fmt.fmt.count[0] > 0)
- skip_lines0 = max(0, (fh->vbi_fmt.fmt.start[0]
- - tvnorm->vbistart[0]));
- if (fh->vbi_fmt.fmt.count[1] > 0)
- skip_lines1 = max(0, (fh->vbi_fmt.fmt.start[1]
- - tvnorm->vbistart[1]));
-
- redo_dma_risc = 0;
-
- if (buf->vbi_skip[0] != skip_lines0 ||
- buf->vbi_skip[1] != skip_lines1 ||
- buf->vbi_count[0] != fh->vbi_fmt.fmt.count[0] ||
- buf->vbi_count[1] != fh->vbi_fmt.fmt.count[1]) {
- buf->vbi_skip[0] = skip_lines0;
- buf->vbi_skip[1] = skip_lines1;
- buf->vbi_count[0] = fh->vbi_fmt.fmt.count[0];
- buf->vbi_count[1] = fh->vbi_fmt.fmt.count[1];
- redo_dma_risc = 1;
- }
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- redo_dma_risc = 1;
- if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))
- goto fail;
- }
-
- if (redo_dma_risc) {
- unsigned int bpl, padding, offset;
- struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
-
- bpl = 2044; /* max. vbipack */
- padding = VBI_BPL - bpl;
-
- if (fh->vbi_fmt.fmt.count[0] > 0) {
- rc = bttv_risc_packed(btv, &buf->top,
- dma->sglist,
- /* offset */ 0, bpl,
- padding, skip_lines0,
- fh->vbi_fmt.fmt.count[0]);
- if (0 != rc)
- goto fail;
- }
-
- if (fh->vbi_fmt.fmt.count[1] > 0) {
- offset = fh->vbi_fmt.fmt.count[0] * VBI_BPL;
-
- rc = bttv_risc_packed(btv, &buf->bottom,
- dma->sglist,
- offset, bpl,
- padding, skip_lines1,
- fh->vbi_fmt.fmt.count[1]);
- if (0 != rc)
- goto fail;
- }
- }
-
- /* VBI capturing ends at VDELAY, start of video capturing,
- no matter where the RISC program ends. VDELAY minimum is 2,
- bounds.top is the corresponding first field line number
- times two. VDELAY counts half field lines. */
- min_vdelay = MIN_VDELAY;
- if (fh->vbi_fmt.end >= tvnorm->cropcap.bounds.top)
- min_vdelay += fh->vbi_fmt.end - tvnorm->cropcap.bounds.top;
-
- /* For bttv_buffer_activate_vbi(). */
- buf->geo.vdelay = min_vdelay;
-
- buf->vb.state = VIDEOBUF_PREPARED;
- buf->vb.field = field;
- dprintk("buf prepare %p: top=%p bottom=%p field=%s\n",
- vb, &buf->top, &buf->bottom,
- v4l2_field_names[buf->vb.field]);
- return 0;
-
- fail:
- bttv_dma_free(q,btv,buf);
- return rc;
-}
-
-static void
-vbi_buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct bttv_fh *fh = q->priv_data;
- struct bttv *btv = fh->btv;
- struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
-
- dprintk("queue %p\n",vb);
- buf->vb.state = VIDEOBUF_QUEUED;
- list_add_tail(&buf->vb.queue,&btv->vcapture);
- if (NULL == btv->cvbi) {
- fh->btv->loop_irq |= 4;
- bttv_set_dma(btv,0x0c);
- }
-}
-
-static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct bttv_fh *fh = q->priv_data;
- struct bttv *btv = fh->btv;
- struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
-
- dprintk("free %p\n",vb);
- bttv_dma_free(q,fh->btv,buf);
-}
-
-struct videobuf_queue_ops bttv_vbi_qops = {
- .buf_setup = vbi_buffer_setup,
- .buf_prepare = vbi_buffer_prepare,
- .buf_queue = vbi_buffer_queue,
- .buf_release = vbi_buffer_release,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int try_fmt(struct v4l2_vbi_format *f, const struct bttv_tvnorm *tvnorm,
- __s32 crop_start)
-{
- __s32 min_start, max_start, max_end, f2_offset;
- unsigned int i;
-
- /* For compatibility with earlier driver versions we must pretend
- the VBI and video capture window may overlap. In reality RISC
- magic aborts VBI capturing at the first line of video capturing,
- leaving the rest of the buffer unchanged, usually all zero.
- VBI capturing must always start before video capturing. >> 1
- because cropping counts field lines times two. */
- min_start = tvnorm->vbistart[0];
- max_start = (crop_start >> 1) - 1;
- max_end = (tvnorm->cropcap.bounds.top
- + tvnorm->cropcap.bounds.height) >> 1;
-
- if (min_start > max_start)
- return -EBUSY;
-
- BUG_ON(max_start >= max_end);
-
- f->sampling_rate = tvnorm->Fsc;
- f->samples_per_line = VBI_BPL;
- f->sample_format = V4L2_PIX_FMT_GREY;
- f->offset = VBI_OFFSET;
-
- f2_offset = tvnorm->vbistart[1] - tvnorm->vbistart[0];
-
- for (i = 0; i < 2; ++i) {
- if (0 == f->count[i]) {
- /* No data from this field. We leave f->start[i]
- alone because VIDIOCSVBIFMT is w/o and EINVALs
- when a driver does not support exactly the
- requested parameters. */
- } else {
- s64 start, count;
-
- start = clamp(f->start[i], min_start, max_start);
- /* s64 to prevent overflow. */
- count = (s64) f->start[i] + f->count[i] - start;
- f->start[i] = start;
- f->count[i] = clamp(count, (s64) 1,
- max_end - start);
- }
-
- min_start += f2_offset;
- max_start += f2_offset;
- max_end += f2_offset;
- }
-
- if (0 == (f->count[0] | f->count[1])) {
- /* As in earlier driver versions. */
- f->start[0] = tvnorm->vbistart[0];
- f->start[1] = tvnorm->vbistart[1];
- f->count[0] = 1;
- f->count[1] = 1;
- }
-
- f->flags = 0;
-
- f->reserved[0] = 0;
- f->reserved[1] = 0;
-
- return 0;
-}
-
-int bttv_try_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
- const struct bttv_tvnorm *tvnorm;
- __s32 crop_start;
-
- mutex_lock(&btv->lock);
-
- tvnorm = &bttv_tvnorms[btv->tvnorm];
- crop_start = btv->crop_start;
-
- mutex_unlock(&btv->lock);
-
- return try_fmt(&frt->fmt.vbi, tvnorm, crop_start);
-}
-
-
-int bttv_s_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
- const struct bttv_tvnorm *tvnorm;
- __s32 start1, end;
- int rc;
-
- mutex_lock(&btv->lock);
-
- rc = -EBUSY;
- if (fh->resources & RESOURCE_VBI)
- goto fail;
-
- tvnorm = &bttv_tvnorms[btv->tvnorm];
-
- rc = try_fmt(&frt->fmt.vbi, tvnorm, btv->crop_start);
- if (0 != rc)
- goto fail;
-
- start1 = frt->fmt.vbi.start[1] - tvnorm->vbistart[1] +
- tvnorm->vbistart[0];
-
- /* First possible line of video capturing. Should be
- max(f->start[0] + f->count[0], start1 + f->count[1]) * 2
- when capturing both fields. But for compatibility we must
- pretend the VBI and video capture window may overlap,
- so end = start + 1, the lowest possible value, times two
- because vbi_fmt.end counts field lines times two. */
- end = max(frt->fmt.vbi.start[0], start1) * 2 + 2;
-
- mutex_lock(&fh->vbi.vb_lock);
-
- fh->vbi_fmt.fmt = frt->fmt.vbi;
- fh->vbi_fmt.tvnorm = tvnorm;
- fh->vbi_fmt.end = end;
-
- mutex_unlock(&fh->vbi.vb_lock);
-
- rc = 0;
-
- fail:
- mutex_unlock(&btv->lock);
-
- return rc;
-}
-
-
-int bttv_g_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
-{
- struct bttv_fh *fh = f;
- const struct bttv_tvnorm *tvnorm;
-
- frt->fmt.vbi = fh->vbi_fmt.fmt;
-
- tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
-
- if (tvnorm != fh->vbi_fmt.tvnorm) {
- __s32 max_end;
- unsigned int i;
-
- /* As in vbi_buffer_prepare() this imitates the
- behaviour of earlier driver versions after video
- standard changes, with default parameters anyway. */
-
- max_end = (tvnorm->cropcap.bounds.top
- + tvnorm->cropcap.bounds.height) >> 1;
-
- frt->fmt.vbi.sampling_rate = tvnorm->Fsc;
-
- for (i = 0; i < 2; ++i) {
- __s32 new_start;
-
- new_start = frt->fmt.vbi.start[i]
- + tvnorm->vbistart[i]
- - fh->vbi_fmt.tvnorm->vbistart[i];
-
- frt->fmt.vbi.start[i] = min(new_start, max_end - 1);
- frt->fmt.vbi.count[i] =
- min((__s32) frt->fmt.vbi.count[i],
- max_end - frt->fmt.vbi.start[i]);
-
- max_end += tvnorm->vbistart[1]
- - tvnorm->vbistart[0];
- }
- }
- return 0;
-}
-
-void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm)
-{
- const struct bttv_tvnorm *tvnorm;
- unsigned int real_samples_per_line;
- unsigned int real_count;
-
- tvnorm = &bttv_tvnorms[norm];
-
- f->fmt.sampling_rate = tvnorm->Fsc;
- f->fmt.samples_per_line = VBI_BPL;
- f->fmt.sample_format = V4L2_PIX_FMT_GREY;
- f->fmt.offset = VBI_OFFSET;
- f->fmt.start[0] = tvnorm->vbistart[0];
- f->fmt.start[1] = tvnorm->vbistart[1];
- f->fmt.count[0] = VBI_DEFLINES;
- f->fmt.count[1] = VBI_DEFLINES;
- f->fmt.flags = 0;
- f->fmt.reserved[0] = 0;
- f->fmt.reserved[1] = 0;
-
- /* For compatibility the buffer size must be 2 * VBI_DEFLINES *
- VBI_BPL regardless of the current video standard. */
- real_samples_per_line = 1024 + tvnorm->vbipack * 4;
- real_count = ((tvnorm->cropcap.defrect.top >> 1)
- - tvnorm->vbistart[0]);
-
- BUG_ON(real_samples_per_line > VBI_BPL);
- BUG_ON(real_count > VBI_DEFLINES);
-
- f->tvnorm = tvnorm;
-
- /* See bttv_vbi_fmt_set(). */
- f->end = tvnorm->vbistart[0] * 2 + 2;
-}
-
-/* ----------------------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h
deleted file mode 100644
index 79a11240a59..00000000000
--- a/drivers/media/video/bt8xx/bttv.h
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- *
- * bttv - Bt848 frame grabber driver
- *
- * card ID's and external interfaces of the bttv driver
- * basically stuff needed by other drivers (i2c, lirc, ...)
- * and is supported not to change much over time.
- *
- * Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de)
- * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
- *
- */
-
-#ifndef _BTTV_H_
-#define _BTTV_H_
-
-#include <linux/videodev2.h>
-#include <linux/i2c.h>
-#include <media/v4l2-device.h>
-#include <media/i2c-addr.h>
-#include <media/tuner.h>
-
-/* ---------------------------------------------------------- */
-/* exported by bttv-cards.c */
-
-#define BTTV_BOARD_UNKNOWN 0x00
-#define BTTV_BOARD_MIRO 0x01
-#define BTTV_BOARD_HAUPPAUGE 0x02
-#define BTTV_BOARD_STB 0x03
-#define BTTV_BOARD_INTEL 0x04
-#define BTTV_BOARD_DIAMOND 0x05
-#define BTTV_BOARD_AVERMEDIA 0x06
-#define BTTV_BOARD_MATRIX_VISION 0x07
-#define BTTV_BOARD_FLYVIDEO 0x08
-#define BTTV_BOARD_TURBOTV 0x09
-#define BTTV_BOARD_HAUPPAUGE878 0x0a
-#define BTTV_BOARD_MIROPRO 0x0b
-#define BTTV_BOARD_ADSTECH_TV 0x0c
-#define BTTV_BOARD_AVERMEDIA98 0x0d
-#define BTTV_BOARD_VHX 0x0e
-#define BTTV_BOARD_ZOLTRIX 0x0f
-#define BTTV_BOARD_PIXVIEWPLAYTV 0x10
-#define BTTV_BOARD_WINVIEW_601 0x11
-#define BTTV_BOARD_AVEC_INTERCAP 0x12
-#define BTTV_BOARD_LIFE_FLYKIT 0x13
-#define BTTV_BOARD_CEI_RAFFLES 0x14
-#define BTTV_BOARD_CONFERENCETV 0x15
-#define BTTV_BOARD_PHOEBE_TVMAS 0x16
-#define BTTV_BOARD_MODTEC_205 0x17
-#define BTTV_BOARD_MAGICTVIEW061 0x18
-#define BTTV_BOARD_VOBIS_BOOSTAR 0x19
-#define BTTV_BOARD_HAUPPAUG_WCAM 0x1a
-#define BTTV_BOARD_MAXI 0x1b
-#define BTTV_BOARD_TERRATV 0x1c
-#define BTTV_BOARD_PXC200 0x1d
-#define BTTV_BOARD_FLYVIDEO_98 0x1e
-#define BTTV_BOARD_IPROTV 0x1f
-#define BTTV_BOARD_INTEL_C_S_PCI 0x20
-#define BTTV_BOARD_TERRATVALUE 0x21
-#define BTTV_BOARD_WINFAST2000 0x22
-#define BTTV_BOARD_CHRONOS_VS2 0x23
-#define BTTV_BOARD_TYPHOON_TVIEW 0x24
-#define BTTV_BOARD_PXELVWPLTVPRO 0x25
-#define BTTV_BOARD_MAGICTVIEW063 0x26
-#define BTTV_BOARD_PINNACLE 0x27
-#define BTTV_BOARD_STB2 0x28
-#define BTTV_BOARD_AVPHONE98 0x29
-#define BTTV_BOARD_PV951 0x2a
-#define BTTV_BOARD_ONAIR_TV 0x2b
-#define BTTV_BOARD_SIGMA_TVII_FM 0x2c
-#define BTTV_BOARD_MATRIX_VISION2 0x2d
-#define BTTV_BOARD_ZOLTRIX_GENIE 0x2e
-#define BTTV_BOARD_TERRATVRADIO 0x2f
-#define BTTV_BOARD_DYNALINK 0x30
-#define BTTV_BOARD_GVBCTV3PCI 0x31
-#define BTTV_BOARD_PXELVWPLTVPAK 0x32
-#define BTTV_BOARD_EAGLE 0x33
-#define BTTV_BOARD_PINNACLEPRO 0x34
-#define BTTV_BOARD_TVIEW_RDS_FM 0x35
-#define BTTV_BOARD_LIFETEC_9415 0x36
-#define BTTV_BOARD_BESTBUY_EASYTV 0x37
-#define BTTV_BOARD_FLYVIDEO_98FM 0x38
-#define BTTV_BOARD_GRANDTEC 0x39
-#define BTTV_BOARD_ASKEY_CPH060 0x3a
-#define BTTV_BOARD_ASKEY_CPH03X 0x3b
-#define BTTV_BOARD_MM100PCTV 0x3c
-#define BTTV_BOARD_GMV1 0x3d
-#define BTTV_BOARD_BESTBUY_EASYTV2 0x3e
-#define BTTV_BOARD_ATI_TVWONDER 0x3f
-#define BTTV_BOARD_ATI_TVWONDERVE 0x40
-#define BTTV_BOARD_FLYVIDEO2000 0x41
-#define BTTV_BOARD_TERRATVALUER 0x42
-#define BTTV_BOARD_GVBCTV4PCI 0x43
-#define BTTV_BOARD_VOODOOTV_FM 0x44
-#define BTTV_BOARD_AIMMS 0x45
-#define BTTV_BOARD_PV_BT878P_PLUS 0x46
-#define BTTV_BOARD_FLYVIDEO98EZ 0x47
-#define BTTV_BOARD_PV_BT878P_9B 0x48
-#define BTTV_BOARD_SENSORAY311_611 0x49
-#define BTTV_BOARD_RV605 0x4a
-#define BTTV_BOARD_POWERCLR_MTV878 0x4b
-#define BTTV_BOARD_WINDVR 0x4c
-#define BTTV_BOARD_GRANDTEC_MULTI 0x4d
-#define BTTV_BOARD_KWORLD 0x4e
-#define BTTV_BOARD_DSP_TCVIDEO 0x4f
-#define BTTV_BOARD_HAUPPAUGEPVR 0x50
-#define BTTV_BOARD_GVBCTV5PCI 0x51
-#define BTTV_BOARD_OSPREY1x0 0x52
-#define BTTV_BOARD_OSPREY1x0_848 0x53
-#define BTTV_BOARD_OSPREY101_848 0x54
-#define BTTV_BOARD_OSPREY1x1 0x55
-#define BTTV_BOARD_OSPREY1x1_SVID 0x56
-#define BTTV_BOARD_OSPREY2xx 0x57
-#define BTTV_BOARD_OSPREY2x0_SVID 0x58
-#define BTTV_BOARD_OSPREY2x0 0x59
-#define BTTV_BOARD_OSPREY500 0x5a
-#define BTTV_BOARD_OSPREY540 0x5b
-#define BTTV_BOARD_OSPREY2000 0x5c
-#define BTTV_BOARD_IDS_EAGLE 0x5d
-#define BTTV_BOARD_PINNACLESAT 0x5e
-#define BTTV_BOARD_FORMAC_PROTV 0x5f
-#define BTTV_BOARD_MACHTV 0x60
-#define BTTV_BOARD_EURESYS_PICOLO 0x61
-#define BTTV_BOARD_PV150 0x62
-#define BTTV_BOARD_AD_TVK503 0x63
-#define BTTV_BOARD_HERCULES_SM_TV 0x64
-#define BTTV_BOARD_PACETV 0x65
-#define BTTV_BOARD_IVC200 0x66
-#define BTTV_BOARD_XGUARD 0x67
-#define BTTV_BOARD_NEBULA_DIGITV 0x68
-#define BTTV_BOARD_PV143 0x69
-#define BTTV_BOARD_VD009X1_VD011_MINIDIN 0x6a
-#define BTTV_BOARD_VD009X1_VD011_COMBI 0x6b
-#define BTTV_BOARD_VD009_MINIDIN 0x6c
-#define BTTV_BOARD_VD009_COMBI 0x6d
-#define BTTV_BOARD_IVC100 0x6e
-#define BTTV_BOARD_IVC120 0x6f
-#define BTTV_BOARD_PC_HDTV 0x70
-#define BTTV_BOARD_TWINHAN_DST 0x71
-#define BTTV_BOARD_WINFASTVC100 0x72
-#define BTTV_BOARD_TEV560 0x73
-#define BTTV_BOARD_SIMUS_GVC1100 0x74
-#define BTTV_BOARD_NGSTV_PLUS 0x75
-#define BTTV_BOARD_LMLBT4 0x76
-#define BTTV_BOARD_TEKRAM_M205 0x77
-#define BTTV_BOARD_CONTVFMI 0x78
-#define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79
-#define BTTV_BOARD_SPIRIT_TV 0x7a
-#define BTTV_BOARD_AVDVBT_771 0x7b
-#define BTTV_BOARD_AVDVBT_761 0x7c
-#define BTTV_BOARD_MATRIX_VISIONSQ 0x7d
-#define BTTV_BOARD_MATRIX_VISIONSLC 0x7e
-#define BTTV_BOARD_APAC_VIEWCOMP 0x7f
-#define BTTV_BOARD_DVICO_DVBT_LITE 0x80
-#define BTTV_BOARD_VGEAR_MYVCD 0x81
-#define BTTV_BOARD_SUPER_TV 0x82
-#define BTTV_BOARD_TIBET_CS16 0x83
-#define BTTV_BOARD_KODICOM_4400R 0x84
-#define BTTV_BOARD_KODICOM_4400R_SL 0x85
-#define BTTV_BOARD_ADLINK_RTV24 0x86
-#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
-#define BTTV_BOARD_ACORP_Y878F 0x88
-#define BTTV_BOARD_CONCEPTRONIC_CTVFMI2 0x89
-#define BTTV_BOARD_PV_BT878P_2E 0x8a
-#define BTTV_BOARD_PV_M4900 0x8b
-#define BTTV_BOARD_OSPREY440 0x8c
-#define BTTV_BOARD_ASOUND_SKYEYE 0x8d
-#define BTTV_BOARD_SABRENT_TVFM 0x8e
-#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f
-#define BTTV_BOARD_MACHTV_MAGICTV 0x90
-#define BTTV_BOARD_SSAI_SECURITY 0x91
-#define BTTV_BOARD_SSAI_ULTRASOUND 0x92
-#define BTTV_BOARD_VOODOOTV_200 0x93
-#define BTTV_BOARD_DVICO_FUSIONHDTV_2 0x94
-#define BTTV_BOARD_TYPHOON_TVTUNERPCI 0x95
-#define BTTV_BOARD_GEOVISION_GV600 0x96
-#define BTTV_BOARD_KOZUMI_KTV_01C 0x97
-#define BTTV_BOARD_ENLTV_FM_2 0x98
-#define BTTV_BOARD_VD012 0x99
-#define BTTV_BOARD_VD012_X1 0x9a
-#define BTTV_BOARD_VD012_X2 0x9b
-#define BTTV_BOARD_IVCE8784 0x9c
-#define BTTV_BOARD_GEOVISION_GV800S 0x9d
-#define BTTV_BOARD_GEOVISION_GV800S_SL 0x9e
-#define BTTV_BOARD_PV183 0x9f
-#define BTTV_BOARD_TVT_TD3116 0xa0
-#define BTTV_BOARD_APOSONIC_WDVR 0xa1
-
-/* more card-specific defines */
-#define PT2254_L_CHANNEL 0x10
-#define PT2254_R_CHANNEL 0x08
-#define PT2254_DBS_IN_2 0x400
-#define PT2254_DBS_IN_10 0x20000
-#define WINVIEW_PT2254_CLK 0x40
-#define WINVIEW_PT2254_DATA 0x20
-#define WINVIEW_PT2254_STROBE 0x80
-
-struct bttv_core {
- /* device structs */
- struct v4l2_device v4l2_dev;
- struct pci_dev *pci;
- struct i2c_adapter i2c_adap;
- struct list_head subs; /* struct bttv_sub_device */
-
- /* device config */
- unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */
- unsigned int type; /* card type (pointer into tvcards[]) */
-};
-
-struct bttv;
-
-struct tvcard {
- char *name;
- void (*volume_gpio)(struct bttv *btv, __u16 volume);
- void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set);
- void (*muxsel_hook)(struct bttv *btv, unsigned int input);
-
- /* MUX bits for each input, two bits per input starting with the LSB */
- u32 muxsel; /* Use MUXSEL() to set */
-
- u32 gpiomask;
- u32 gpiomux[4]; /* Tuner, Radio, external, internal */
- u32 gpiomute; /* GPIO mute setting */
- u32 gpiomask2; /* GPIO MUX mask */
-
- unsigned int tuner_type;
- u8 tuner_addr;
- u8 video_inputs; /* Number of inputs */
- unsigned int svhs:4; /* Which input is s-video */
-#define NO_SVHS 15
- unsigned int pll:2;
-#define PLL_NONE 0
-#define PLL_28 1
-#define PLL_35 2
-
- /* i2c audio flags */
- unsigned int no_msp34xx:1;
- unsigned int no_tda7432:1;
- unsigned int msp34xx_alt:1;
- /* Note: currently no card definition needs to mark the presence
- of a RDS saa6588 chip. If this is ever needed, then add a new
- 'has_saa6588' bit here. */
-
- unsigned int no_video:1; /* video pci function is unused */
- unsigned int has_dvb:1;
- unsigned int has_remote:1;
- unsigned int has_radio:1;
- unsigned int has_dig_in:1; /* Has digital input (always last input) */
- unsigned int no_gpioirq:1;
-};
-
-extern struct tvcard bttv_tvcards[];
-
-/*
- * This bit of cpp voodoo is used to create a macro with a variable number of
- * arguments (1 to 16). It will pack each argument into a word two bits at a
- * time. It can't be a function because it needs to be compile time constant to
- * initialize structures. Since each argument must fit in two bits, it's ok
- * that they are changed to octal. One should not use hex number, macros, or
- * anything else with this macro. Just use plain integers from 0 to 3.
- */
-#define _MUXSELf(a) 0##a << 30
-#define _MUXSELe(a, b...) 0##a << 28 | _MUXSELf(b)
-#define _MUXSELd(a, b...) 0##a << 26 | _MUXSELe(b)
-#define _MUXSELc(a, b...) 0##a << 24 | _MUXSELd(b)
-#define _MUXSELb(a, b...) 0##a << 22 | _MUXSELc(b)
-#define _MUXSELa(a, b...) 0##a << 20 | _MUXSELb(b)
-#define _MUXSEL9(a, b...) 0##a << 18 | _MUXSELa(b)
-#define _MUXSEL8(a, b...) 0##a << 16 | _MUXSEL9(b)
-#define _MUXSEL7(a, b...) 0##a << 14 | _MUXSEL8(b)
-#define _MUXSEL6(a, b...) 0##a << 12 | _MUXSEL7(b)
-#define _MUXSEL5(a, b...) 0##a << 10 | _MUXSEL6(b)
-#define _MUXSEL4(a, b...) 0##a << 8 | _MUXSEL5(b)
-#define _MUXSEL3(a, b...) 0##a << 6 | _MUXSEL4(b)
-#define _MUXSEL2(a, b...) 0##a << 4 | _MUXSEL3(b)
-#define _MUXSEL1(a, b...) 0##a << 2 | _MUXSEL2(b)
-#define MUXSEL(a, b...) (a | _MUXSEL1(b))
-
-/* identification / initialization of the card */
-extern void bttv_idcard(struct bttv *btv);
-extern void bttv_init_card1(struct bttv *btv);
-extern void bttv_init_card2(struct bttv *btv);
-extern void bttv_init_tuner(struct bttv *btv);
-
-/* card-specific funtions */
-extern void tea5757_set_freq(struct bttv *btv, unsigned short freq);
-extern u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits);
-
-/* extra tweaks for some chipsets */
-extern void bttv_check_chipset(void);
-extern int bttv_handle_chipset(struct bttv *btv);
-
-/* ---------------------------------------------------------- */
-/* exported by bttv-if.c */
-
-/* this obsolete -- please use the sysfs-based
- interface below for new code */
-
-extern struct pci_dev* bttv_get_pcidev(unsigned int card);
-
-/* sets GPOE register (BT848_GPIO_OUT_EN) to new value:
- data | (current_GPOE_value & ~mask)
- returns negative value if error occurred
-*/
-extern int bttv_gpio_enable(unsigned int card,
- unsigned long mask, unsigned long data);
-
-/* fills data with GPDATA register contents
- returns negative value if error occurred
-*/
-extern int bttv_read_gpio(unsigned int card, unsigned long *data);
-
-/* sets GPDATA register to new value:
- (data & mask) | (current_GPDATA_value & ~mask)
- returns negative value if error occurred
-*/
-extern int bttv_write_gpio(unsigned int card,
- unsigned long mask, unsigned long data);
-
-
-
-
-/* ---------------------------------------------------------- */
-/* sysfs/driver-moded based gpio access interface */
-
-struct bttv_sub_device {
- struct device dev;
- struct bttv_core *core;
- struct list_head list;
-};
-#define to_bttv_sub_dev(x) container_of((x), struct bttv_sub_device, dev)
-
-struct bttv_sub_driver {
- struct device_driver drv;
- char wanted[20];
- int (*probe)(struct bttv_sub_device *sub);
- void (*remove)(struct bttv_sub_device *sub);
-};
-#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv)
-
-int bttv_sub_register(struct bttv_sub_driver *drv, char *wanted);
-int bttv_sub_unregister(struct bttv_sub_driver *drv);
-
-/* gpio access functions */
-void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits);
-u32 bttv_gpio_read(struct bttv_core *core);
-void bttv_gpio_write(struct bttv_core *core, u32 value);
-void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits);
-
-#define gpio_inout(mask,bits) bttv_gpio_inout(&btv->c, mask, bits)
-#define gpio_read() bttv_gpio_read(&btv->c)
-#define gpio_write(value) bttv_gpio_write(&btv->c, value)
-#define gpio_bits(mask,bits) bttv_gpio_bits(&btv->c, mask, bits)
-
-
-/* ---------------------------------------------------------- */
-/* i2c */
-
-#define bttv_call_all(btv, o, f, args...) \
- v4l2_device_call_all(&btv->c.v4l2_dev, 0, o, f, ##args)
-
-extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for);
-extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
- unsigned char b2, int both);
-extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr);
-
-extern int bttv_input_init(struct bttv *dev);
-extern void bttv_input_fini(struct bttv *dev);
-extern void bttv_input_irq(struct bttv *dev);
-
-#endif /* _BTTV_H_ */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
deleted file mode 100644
index 70fd4f23f60..00000000000
--- a/drivers/media/video/bt8xx/bttvp.h
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
-
- bttv - Bt848 frame grabber driver
-
- bttv's *private* header file -- nobody other than bttv itself
- should ever include this file.
-
- (c) 2000-2002 Gerd Knorr <kraxel@bytesex.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _BTTVP_H_
-#define _BTTVP_H_
-
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/pci.h>
-#include <linux/input.h>
-#include <linux/mutex.h>
-#include <linux/scatterlist.h>
-#include <asm/io.h>
-#include <media/v4l2-common.h>
-#include <linux/device.h>
-#include <media/videobuf-dma-sg.h>
-#include <media/tveeprom.h>
-#include <media/rc-core.h>
-#include <media/ir-kbd-i2c.h>
-
-#include "bt848.h"
-#include "bttv.h"
-#include "btcx-risc.h"
-
-#ifdef __KERNEL__
-
-#define FORMAT_FLAGS_DITHER 0x01
-#define FORMAT_FLAGS_PACKED 0x02
-#define FORMAT_FLAGS_PLANAR 0x04
-#define FORMAT_FLAGS_RAW 0x08
-#define FORMAT_FLAGS_CrCb 0x10
-
-#define RISC_SLOT_O_VBI 4
-#define RISC_SLOT_O_FIELD 6
-#define RISC_SLOT_E_VBI 10
-#define RISC_SLOT_E_FIELD 12
-#define RISC_SLOT_LOOP 14
-
-#define RESOURCE_OVERLAY 1
-#define RESOURCE_VIDEO_STREAM 2
-#define RESOURCE_VBI 4
-#define RESOURCE_VIDEO_READ 8
-
-#define RAW_LINES 640
-#define RAW_BPL 1024
-
-#define UNSET (-1U)
-
-/* Min. value in VDELAY register. */
-#define MIN_VDELAY 2
-/* Even to get Cb first, odd for Cr. */
-#define MAX_HDELAY (0x3FF & -2)
-/* Limits scaled width, which must be a multiple of 4. */
-#define MAX_HACTIVE (0x3FF & -4)
-
-#define BTTV_NORMS (\
- V4L2_STD_PAL | V4L2_STD_PAL_N | \
- V4L2_STD_PAL_Nc | V4L2_STD_SECAM | \
- V4L2_STD_NTSC | V4L2_STD_PAL_M | \
- V4L2_STD_PAL_60)
-/* ---------------------------------------------------------- */
-
-struct bttv_tvnorm {
- int v4l2_id;
- char *name;
- u32 Fsc;
- u16 swidth, sheight; /* scaled standard width, height */
- u16 totalwidth;
- u8 adelay, bdelay, iform;
- u32 scaledtwidth;
- u16 hdelayx1, hactivex1;
- u16 vdelay;
- u8 vbipack;
- u16 vtotal;
- int sram;
- /* ITU-R frame line number of the first VBI line we can
- capture, of the first and second field. The last possible line
- is determined by cropcap.bounds. */
- u16 vbistart[2];
- /* Horizontally this counts fCLKx1 samples following the leading
- edge of the horizontal sync pulse, vertically ITU-R frame line
- numbers of the first field times two (2, 4, 6, ... 524 or 624). */
- struct v4l2_cropcap cropcap;
-};
-extern const struct bttv_tvnorm bttv_tvnorms[];
-
-struct bttv_format {
- char *name;
- int fourcc; /* video4linux 2 */
- int btformat; /* BT848_COLOR_FMT_* */
- int btswap; /* BT848_COLOR_CTL_* */
- int depth; /* bit/pixel */
- int flags;
- int hshift,vshift; /* for planar modes */
-};
-
-struct bttv_ir {
- struct rc_dev *dev;
- struct timer_list timer;
-
- char name[32];
- char phys[32];
-
- /* Usual gpio signalling */
- u32 mask_keycode;
- u32 mask_keydown;
- u32 mask_keyup;
- u32 polling;
- u32 last_gpio;
- int shift_by;
- int start; // What should RC5_START() be
- int addr; // What RC5_ADDR() should be.
- int rc5_remote_gap;
-
- /* RC5 gpio */
- bool rc5_gpio; /* Is RC5 legacy GPIO enabled? */
- u32 last_bit; /* last raw bit seen */
- u32 code; /* raw code under construction */
- struct timeval base_time; /* time of last seen code */
- bool active; /* building raw code */
-};
-
-
-/* ---------------------------------------------------------- */
-
-struct bttv_geometry {
- u8 vtc,crop,comb;
- u16 width,hscale,hdelay;
- u16 sheight,vscale,vdelay,vtotal;
-};
-
-struct bttv_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
-
- /* bttv specific */
- const struct bttv_format *fmt;
- unsigned int tvnorm;
- int btformat;
- int btswap;
- struct bttv_geometry geo;
- struct btcx_riscmem top;
- struct btcx_riscmem bottom;
- struct v4l2_rect crop;
- unsigned int vbi_skip[2];
- unsigned int vbi_count[2];
-};
-
-struct bttv_buffer_set {
- struct bttv_buffer *top; /* top field buffer */
- struct bttv_buffer *bottom; /* bottom field buffer */
- unsigned int top_irq;
- unsigned int frame_irq;
-};
-
-struct bttv_overlay {
- unsigned int tvnorm;
- struct v4l2_rect w;
- enum v4l2_field field;
- struct v4l2_clip *clips;
- int nclips;
- int setup_ok;
-};
-
-struct bttv_vbi_fmt {
- struct v4l2_vbi_format fmt;
-
- /* fmt.start[] and count[] refer to this video standard. */
- const struct bttv_tvnorm *tvnorm;
-
- /* Earliest possible start of video capturing with this
- v4l2_vbi_format, in struct bttv_crop.rect units. */
- __s32 end;
-};
-
-/* bttv-vbi.c */
-void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm);
-
-struct bttv_crop {
- /* A cropping rectangle in struct bttv_tvnorm.cropcap units. */
- struct v4l2_rect rect;
-
- /* Scaled image size limits with this crop rect. Divide
- max_height, but not min_height, by two when capturing
- single fields. See also bttv_crop_reset() and
- bttv_crop_adjust() in bttv-driver.c. */
- __s32 min_scaled_width;
- __s32 min_scaled_height;
- __s32 max_scaled_width;
- __s32 max_scaled_height;
-};
-
-struct bttv_fh {
- struct bttv *btv;
- int resources;
-#ifdef VIDIOC_G_PRIORITY
- enum v4l2_priority prio;
-#endif
- enum v4l2_buf_type type;
-
- /* video capture */
- struct videobuf_queue cap;
- const struct bttv_format *fmt;
- int width;
- int height;
-
- /* video overlay */
- const struct bttv_format *ovfmt;
- struct bttv_overlay ov;
-
- /* Application called VIDIOC_S_CROP. */
- int do_crop;
-
- /* vbi capture */
- struct videobuf_queue vbi;
- /* Current VBI capture window as seen through this fh (cannot
- be global for compatibility with earlier drivers). Protected
- by struct bttv.lock and struct bttv_fh.vbi.lock. */
- struct bttv_vbi_fmt vbi_fmt;
-};
-
-/* ---------------------------------------------------------- */
-/* bttv-risc.c */
-
-/* risc code generators - capture */
-int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
- struct scatterlist *sglist,
- unsigned int offset, unsigned int bpl,
- unsigned int pitch, unsigned int skip_lines,
- unsigned int store_lines);
-
-/* control dma register + risc main loop */
-void bttv_set_dma(struct bttv *btv, int override);
-int bttv_risc_init_main(struct bttv *btv);
-int bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
- int irqflags);
-
-/* capture buffer handling */
-int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf);
-int bttv_buffer_activate_video(struct bttv *btv,
- struct bttv_buffer_set *set);
-int bttv_buffer_activate_vbi(struct bttv *btv,
- struct bttv_buffer *vbi);
-void bttv_dma_free(struct videobuf_queue *q, struct bttv *btv,
- struct bttv_buffer *buf);
-
-/* overlay handling */
-int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov,
- const struct bttv_format *fmt,
- struct bttv_buffer *buf);
-
-
-/* ---------------------------------------------------------- */
-/* bttv-vbi.c */
-
-int bttv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f);
-int bttv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f);
-int bttv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f);
-
-extern struct videobuf_queue_ops bttv_vbi_qops;
-
-/* ---------------------------------------------------------- */
-/* bttv-gpio.c */
-
-extern struct bus_type bttv_sub_bus_type;
-int bttv_sub_add_device(struct bttv_core *core, char *name);
-int bttv_sub_del_devices(struct bttv_core *core);
-
-/* ---------------------------------------------------------- */
-/* bttv-cards.c */
-
-extern int no_overlay;
-
-/* ---------------------------------------------------------- */
-/* bttv-input.c */
-
-extern void init_bttv_i2c_ir(struct bttv *btv);
-extern int fini_bttv_i2c(struct bttv *btv);
-
-/* ---------------------------------------------------------- */
-/* bttv-driver.c */
-
-/* insmod options */
-extern unsigned int bttv_verbose;
-extern unsigned int bttv_debug;
-extern unsigned int bttv_gpio;
-extern void bttv_gpio_tracking(struct bttv *btv, char *comment);
-extern int init_bttv_i2c(struct bttv *btv);
-
-#define dprintk(fmt, ...) \
-do { \
- if (bttv_debug >= 1) \
- pr_debug(fmt, ##__VA_ARGS__); \
-} while (0)
-#define dprintk_cont(fmt, ...) \
-do { \
- if (bttv_debug >= 1) \
- pr_cont(fmt, ##__VA_ARGS__); \
-} while (0)
-#define d2printk(fmt, ...) \
-do { \
- if (bttv_debug >= 2) \
- printk(fmt, ##__VA_ARGS__); \
-} while (0)
-
-#define BTTV_MAX_FBUF 0x208000
-#define BTTV_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
-#define BTTV_FREE_IDLE msecs_to_jiffies(1000) /* one second */
-
-
-struct bttv_pll_info {
- unsigned int pll_ifreq; /* PLL input frequency */
- unsigned int pll_ofreq; /* PLL output frequency */
- unsigned int pll_crystal; /* Crystal used for input */
- unsigned int pll_current; /* Currently programmed ofreq */
-};
-
-/* for gpio-connected remote control */
-struct bttv_input {
- struct input_dev *dev;
- char name[32];
- char phys[32];
- u32 mask_keycode;
- u32 mask_keydown;
-};
-
-struct bttv_suspend_state {
- u32 gpio_enable;
- u32 gpio_data;
- int disabled;
- int loop_irq;
- struct bttv_buffer_set video;
- struct bttv_buffer *vbi;
-};
-
-struct bttv {
- struct bttv_core c;
-
- /* pci device config */
- unsigned short id;
- unsigned char revision;
- unsigned char __iomem *bt848_mmio; /* pointer to mmio */
-
- /* card configuration info */
- unsigned int cardid; /* pci subsystem id (bt878 based ones) */
- unsigned int tuner_type; /* tuner chip type */
- unsigned int tda9887_conf;
- unsigned int svhs, dig;
- unsigned int has_saa6588:1;
- struct bttv_pll_info pll;
- int triton1;
- int gpioirq;
-
- int use_i2c_hw;
-
- /* old gpio interface */
- int shutdown;
-
- void (*volume_gpio)(struct bttv *btv, __u16 volume);
- void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-
- /* new gpio interface */
- spinlock_t gpio_lock;
-
- /* i2c layer */
- struct i2c_algo_bit_data i2c_algo;
- struct i2c_client i2c_client;
- int i2c_state, i2c_rc;
- int i2c_done;
- wait_queue_head_t i2c_queue;
- struct v4l2_subdev *sd_msp34xx;
- struct v4l2_subdev *sd_tvaudio;
-
- /* video4linux (1) */
- struct video_device *video_dev;
- struct video_device *radio_dev;
- struct video_device *vbi_dev;
-
- /* infrared remote */
- int has_remote;
- struct bttv_ir *remote;
-
- /* I2C remote data */
- struct IR_i2c_init_data init_data;
-
- /* locking */
- spinlock_t s_lock;
- struct mutex lock;
- int resources;
-#ifdef VIDIOC_G_PRIORITY
- struct v4l2_prio_state prio;
-#endif
-
- /* video state */
- unsigned int input;
- unsigned int audio;
- unsigned int mute;
- unsigned long freq;
- unsigned int tvnorm;
- int hue, contrast, bright, saturation;
- struct v4l2_framebuffer fbuf;
- unsigned int field_count;
-
- /* various options */
- int opt_combfilter;
- int opt_lumafilter;
- int opt_automute;
- int opt_chroma_agc;
- int opt_adc_crush;
- int opt_vcr_hack;
- int opt_whitecrush_upper;
- int opt_whitecrush_lower;
- int opt_uv_ratio;
- int opt_full_luma_range;
- int opt_coring;
-
- /* radio data/state */
- int has_radio;
- int radio_user;
- int radio_uses_msp_demodulator;
-
- /* miro/pinnacle + Aimslab VHX
- philips matchbox (tea5757 radio tuner) support */
- int has_matchbox;
- int mbox_we;
- int mbox_data;
- int mbox_clk;
- int mbox_most;
- int mbox_mask;
-
- /* ISA stuff (Terratec Active Radio Upgrade) */
- int mbox_ior;
- int mbox_iow;
- int mbox_csel;
-
- /* risc memory management data
- - must acquire s_lock before changing these
- - only the irq handler is supported to touch top + bottom + vcurr */
- struct btcx_riscmem main;
- struct bttv_buffer *screen; /* overlay */
- struct list_head capture; /* video capture queue */
- struct list_head vcapture; /* vbi capture queue */
- struct bttv_buffer_set curr; /* active buffers */
- struct bttv_buffer *cvbi; /* active vbi buffer */
- int loop_irq;
- int new_input;
-
- unsigned long cap_ctl;
- unsigned long dma_on;
- struct timer_list timeout;
- struct bttv_suspend_state state;
-
- /* stats */
- unsigned int errors;
- unsigned int framedrop;
- unsigned int irq_total;
- unsigned int irq_me;
-
- unsigned int users;
- struct bttv_fh init;
-
- /* used to make dvb-bt8xx autoloadable */
- struct work_struct request_module_wk;
-
- /* Default (0) and current (1) video capturing and overlay
- cropping parameters in bttv_tvnorm.cropcap units. Protected
- by bttv.lock. */
- struct bttv_crop crop[2];
-
- /* Earliest possible start of video capturing in
- bttv_tvnorm.cropcap line units. Set by check_alloc_btres()
- and free_btres(). Protected by bttv.lock. */
- __s32 vbi_end;
-
- /* Latest possible end of VBI capturing (= crop[x].rect.top when
- VIDEO_RESOURCES are locked). Set by check_alloc_btres()
- and free_btres(). Protected by bttv.lock. */
- __s32 crop_start;
-};
-
-static inline struct bttv *to_bttv(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct bttv, c.v4l2_dev);
-}
-
-/* our devices */
-#define BTTV_MAX 32
-extern unsigned int bttv_num;
-extern struct bttv *bttvs[BTTV_MAX];
-
-static inline unsigned int bttv_muxsel(const struct bttv *btv,
- unsigned int input)
-{
- return (bttv_tvcards[btv->c.type].muxsel >> (input * 2)) & 3;
-}
-
-#endif
-
-#define btwrite(dat,adr) writel((dat), btv->bt848_mmio+(adr))
-#define btread(adr) readl(btv->bt848_mmio+(adr))
-
-#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
-#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
-#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
-
-#endif /* _BTTVP_H_ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/btcx-risc.c b/drivers/media/video/btcx-risc.c
deleted file mode 100644
index ac1b2687a20..00000000000
--- a/drivers/media/video/btcx-risc.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
-
- btcx-risc.c
-
- bt848/bt878/cx2388x risc code generator.
-
- (c) 2000-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/videodev2.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-#include "btcx-risc.h"
-
-MODULE_DESCRIPTION("some code shared by bttv and cx88xx drivers");
-MODULE_AUTHOR("Gerd Knorr");
-MODULE_LICENSE("GPL");
-
-static unsigned int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug,"debug messages, default is 0 (no)");
-
-/* ---------------------------------------------------------- */
-/* allocate/free risc memory */
-
-static int memcnt;
-
-void btcx_riscmem_free(struct pci_dev *pci,
- struct btcx_riscmem *risc)
-{
- if (NULL == risc->cpu)
- return;
- if (debug) {
- memcnt--;
- printk("btcx: riscmem free [%d] dma=%lx\n",
- memcnt, (unsigned long)risc->dma);
- }
- pci_free_consistent(pci, risc->size, risc->cpu, risc->dma);
- memset(risc,0,sizeof(*risc));
-}
-
-int btcx_riscmem_alloc(struct pci_dev *pci,
- struct btcx_riscmem *risc,
- unsigned int size)
-{
- __le32 *cpu;
- dma_addr_t dma = 0;
-
- if (NULL != risc->cpu && risc->size < size)
- btcx_riscmem_free(pci,risc);
- if (NULL == risc->cpu) {
- cpu = pci_alloc_consistent(pci, size, &dma);
- if (NULL == cpu)
- return -ENOMEM;
- risc->cpu = cpu;
- risc->dma = dma;
- risc->size = size;
- if (debug) {
- memcnt++;
- printk("btcx: riscmem alloc [%d] dma=%lx cpu=%p size=%d\n",
- memcnt, (unsigned long)dma, cpu, size);
- }
- }
- memset(risc->cpu,0,risc->size);
- return 0;
-}
-
-/* ---------------------------------------------------------- */
-/* screen overlay helpers */
-
-int
-btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
- struct v4l2_clip *clips, unsigned int n)
-{
- if (win->left < 0) {
- /* left */
- clips[n].c.left = 0;
- clips[n].c.top = 0;
- clips[n].c.width = -win->left;
- clips[n].c.height = win->height;
- n++;
- }
- if (win->left + win->width > swidth) {
- /* right */
- clips[n].c.left = swidth - win->left;
- clips[n].c.top = 0;
- clips[n].c.width = win->width - clips[n].c.left;
- clips[n].c.height = win->height;
- n++;
- }
- if (win->top < 0) {
- /* top */
- clips[n].c.left = 0;
- clips[n].c.top = 0;
- clips[n].c.width = win->width;
- clips[n].c.height = -win->top;
- n++;
- }
- if (win->top + win->height > sheight) {
- /* bottom */
- clips[n].c.left = 0;
- clips[n].c.top = sheight - win->top;
- clips[n].c.width = win->width;
- clips[n].c.height = win->height - clips[n].c.top;
- n++;
- }
- return n;
-}
-
-int
-btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, unsigned int n, int mask)
-{
- s32 nx,nw,dx;
- unsigned int i;
-
- /* fixup window */
- nx = (win->left + mask) & ~mask;
- nw = (win->width) & ~mask;
- if (nx + nw > win->left + win->width)
- nw -= mask+1;
- dx = nx - win->left;
- win->left = nx;
- win->width = nw;
- if (debug)
- printk(KERN_DEBUG "btcx: window align %dx%d+%d+%d [dx=%d]\n",
- win->width, win->height, win->left, win->top, dx);
-
- /* fixup clips */
- for (i = 0; i < n; i++) {
- nx = (clips[i].c.left-dx) & ~mask;
- nw = (clips[i].c.width) & ~mask;
- if (nx + nw < clips[i].c.left-dx + clips[i].c.width)
- nw += mask+1;
- clips[i].c.left = nx;
- clips[i].c.width = nw;
- if (debug)
- printk(KERN_DEBUG "btcx: clip align %dx%d+%d+%d\n",
- clips[i].c.width, clips[i].c.height,
- clips[i].c.left, clips[i].c.top);
- }
- return 0;
-}
-
-void
-btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips)
-{
- struct v4l2_clip swap;
- int i,j,n;
-
- if (nclips < 2)
- return;
- for (i = nclips-2; i >= 0; i--) {
- for (n = 0, j = 0; j <= i; j++) {
- if (clips[j].c.left > clips[j+1].c.left) {
- swap = clips[j];
- clips[j] = clips[j+1];
- clips[j+1] = swap;
- n++;
- }
- }
- if (0 == n)
- break;
- }
-}
-
-void
-btcx_calc_skips(int line, int width, int *maxy,
- struct btcx_skiplist *skips, unsigned int *nskips,
- const struct v4l2_clip *clips, unsigned int nclips)
-{
- unsigned int clip,skip;
- int end, maxline;
-
- skip=0;
- maxline = 9999;
- for (clip = 0; clip < nclips; clip++) {
-
- /* sanity checks */
- if (clips[clip].c.left + clips[clip].c.width <= 0)
- continue;
- if (clips[clip].c.left > (signed)width)
- break;
-
- /* vertical range */
- if (line > clips[clip].c.top+clips[clip].c.height-1)
- continue;
- if (line < clips[clip].c.top) {
- if (maxline > clips[clip].c.top-1)
- maxline = clips[clip].c.top-1;
- continue;
- }
- if (maxline > clips[clip].c.top+clips[clip].c.height-1)
- maxline = clips[clip].c.top+clips[clip].c.height-1;
-
- /* horizontal range */
- if (0 == skip || clips[clip].c.left > skips[skip-1].end) {
- /* new one */
- skips[skip].start = clips[clip].c.left;
- if (skips[skip].start < 0)
- skips[skip].start = 0;
- skips[skip].end = clips[clip].c.left + clips[clip].c.width;
- if (skips[skip].end > width)
- skips[skip].end = width;
- skip++;
- } else {
- /* overlaps -- expand last one */
- end = clips[clip].c.left + clips[clip].c.width;
- if (skips[skip-1].end < end)
- skips[skip-1].end = end;
- if (skips[skip-1].end > width)
- skips[skip-1].end = width;
- }
- }
- *nskips = skip;
- *maxy = maxline;
-
- if (debug) {
- printk(KERN_DEBUG "btcx: skips line %d-%d:",line,maxline);
- for (skip = 0; skip < *nskips; skip++) {
- printk(" %d-%d",skips[skip].start,skips[skip].end);
- }
- printk("\n");
- }
-}
-
-/* ---------------------------------------------------------- */
-
-EXPORT_SYMBOL(btcx_riscmem_alloc);
-EXPORT_SYMBOL(btcx_riscmem_free);
-
-EXPORT_SYMBOL(btcx_screen_clips);
-EXPORT_SYMBOL(btcx_align);
-EXPORT_SYMBOL(btcx_sort_clips);
-EXPORT_SYMBOL(btcx_calc_skips);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/btcx-risc.h b/drivers/media/video/btcx-risc.h
deleted file mode 100644
index f8bc6e8e7b5..00000000000
--- a/drivers/media/video/btcx-risc.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- */
-struct btcx_riscmem {
- unsigned int size;
- __le32 *cpu;
- __le32 *jmp;
- dma_addr_t dma;
-};
-
-struct btcx_skiplist {
- int start;
- int end;
-};
-
-int btcx_riscmem_alloc(struct pci_dev *pci,
- struct btcx_riscmem *risc,
- unsigned int size);
-void btcx_riscmem_free(struct pci_dev *pci,
- struct btcx_riscmem *risc);
-
-int btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
- struct v4l2_clip *clips, unsigned int n);
-int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips,
- unsigned int n, int mask);
-void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips);
-void btcx_calc_skips(int line, int width, int *maxy,
- struct btcx_skiplist *skips, unsigned int *nskips,
- const struct v4l2_clip *clips, unsigned int nclips);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
deleted file mode 100644
index 5b75a64b199..00000000000
--- a/drivers/media/video/bw-qcam.c
+++ /dev/null
@@ -1,1113 +0,0 @@
-/*
- * QuickCam Driver For Video4Linux.
- *
- * Video4Linux conversion work by Alan Cox.
- * Parport compatibility by Phil Blundell.
- * Busy loop avoidance by Mark Cooke.
- *
- * Module parameters:
- *
- * maxpoll=<1 - 5000>
- *
- * When polling the QuickCam for a response, busy-wait for a
- * maximum of this many loops. The default of 250 gives little
- * impact on interactive response.
- *
- * NOTE: If this parameter is set too high, the processor
- * will busy wait until this loop times out, and then
- * slowly poll for a further 5 seconds before failing
- * the transaction. You have been warned.
- *
- * yieldlines=<1 - 250>
- *
- * When acquiring a frame from the camera, the data gathering
- * loop will yield back to the scheduler after completing
- * this many lines. The default of 4 provides a trade-off
- * between increased frame acquisition time and impact on
- * interactive response.
- */
-
-/* qcam-lib.c -- Library for programming with the Connectix QuickCam.
- * See the included documentation for usage instructions and details
- * of the protocol involved. */
-
-
-/* Version 0.5, August 4, 1996 */
-/* Version 0.7, August 27, 1996 */
-/* Version 0.9, November 17, 1996 */
-
-
-/******************************************************************
-
-Copyright (C) 1996 by Scott Laird
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-******************************************************************/
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/parport.h>
-#include <linux/sched.h>
-#include <linux/videodev2.h>
-#include <linux/mutex.h>
-#include <asm/uaccess.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
-
-/* One from column A... */
-#define QC_NOTSET 0
-#define QC_UNIDIR 1
-#define QC_BIDIR 2
-#define QC_SERIAL 3
-
-/* ... and one from column B */
-#define QC_ANY 0x00
-#define QC_FORCE_UNIDIR 0x10
-#define QC_FORCE_BIDIR 0x20
-#define QC_FORCE_SERIAL 0x30
-/* in the port_mode member */
-
-#define QC_MODE_MASK 0x07
-#define QC_FORCE_MASK 0x70
-
-#define MAX_HEIGHT 243
-#define MAX_WIDTH 336
-
-/* Bit fields for status flags */
-#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
-
-struct qcam {
- struct v4l2_device v4l2_dev;
- struct video_device vdev;
- struct v4l2_ctrl_handler hdl;
- struct pardevice *pdev;
- struct parport *pport;
- struct mutex lock;
- int width, height;
- int bpp;
- int mode;
- int contrast, brightness, whitebal;
- int port_mode;
- int transfer_scale;
- int top, left;
- int status;
- unsigned int saved_bits;
- unsigned long in_use;
-};
-
-static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */
-static unsigned int yieldlines = 4; /* Yield after this many during capture */
-static int video_nr = -1;
-static unsigned int force_init; /* Whether to probe aggressively */
-
-module_param(maxpoll, int, 0);
-module_param(yieldlines, int, 0);
-module_param(video_nr, int, 0);
-
-/* Set force_init=1 to avoid detection by polling status register and
- * immediately attempt to initialize qcam */
-module_param(force_init, int, 0);
-
-#define MAX_CAMS 4
-static struct qcam *qcams[MAX_CAMS];
-static unsigned int num_cams;
-
-static inline int read_lpstatus(struct qcam *q)
-{
- return parport_read_status(q->pport);
-}
-
-static inline int read_lpdata(struct qcam *q)
-{
- return parport_read_data(q->pport);
-}
-
-static inline void write_lpdata(struct qcam *q, int d)
-{
- parport_write_data(q->pport, d);
-}
-
-static void write_lpcontrol(struct qcam *q, int d)
-{
- if (d & 0x20) {
- /* Set bidirectional mode to reverse (data in) */
- parport_data_reverse(q->pport);
- } else {
- /* Set bidirectional mode to forward (data out) */
- parport_data_forward(q->pport);
- }
-
- /* Now issue the regular port command, but strip out the
- * direction flag */
- d &= ~0x20;
- parport_write_control(q->pport, d);
-}
-
-
-/* qc_waithand busy-waits for a handshake signal from the QuickCam.
- * Almost all communication with the camera requires handshaking. */
-
-static int qc_waithand(struct qcam *q, int val)
-{
- int status;
- int runs = 0;
-
- if (val) {
- while (!((status = read_lpstatus(q)) & 8)) {
- /* 1000 is enough spins on the I/O for all normal
- cases, at that point we start to poll slowly
- until the camera wakes up. However, we are
- busy blocked until the camera responds, so
- setting it lower is much better for interactive
- response. */
-
- if (runs++ > maxpoll)
- msleep_interruptible(5);
- if (runs > (maxpoll + 1000)) /* 5 seconds */
- return -1;
- }
- } else {
- while (((status = read_lpstatus(q)) & 8)) {
- /* 1000 is enough spins on the I/O for all normal
- cases, at that point we start to poll slowly
- until the camera wakes up. However, we are
- busy blocked until the camera responds, so
- setting it lower is much better for interactive
- response. */
-
- if (runs++ > maxpoll)
- msleep_interruptible(5);
- if (runs++ > (maxpoll + 1000)) /* 5 seconds */
- return -1;
- }
- }
-
- return status;
-}
-
-/* Waithand2 is used when the qcam is in bidirectional mode, and the
- * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1
- * (bit 3 of status register). It also returns the last value read,
- * since this data is useful. */
-
-static unsigned int qc_waithand2(struct qcam *q, int val)
-{
- unsigned int status;
- int runs = 0;
-
- do {
- status = read_lpdata(q);
- /* 1000 is enough spins on the I/O for all normal
- cases, at that point we start to poll slowly
- until the camera wakes up. However, we are
- busy blocked until the camera responds, so
- setting it lower is much better for interactive
- response. */
-
- if (runs++ > maxpoll)
- msleep_interruptible(5);
- if (runs++ > (maxpoll + 1000)) /* 5 seconds */
- return 0;
- } while ((status & 1) != val);
-
- return status;
-}
-
-/* qc_command is probably a bit of a misnomer -- it's used to send
- * bytes *to* the camera. Generally, these bytes are either commands
- * or arguments to commands, so the name fits, but it still bugs me a
- * bit. See the documentation for a list of commands. */
-
-static int qc_command(struct qcam *q, int command)
-{
- int n1, n2;
- int cmd;
-
- write_lpdata(q, command);
- write_lpcontrol(q, 6);
-
- n1 = qc_waithand(q, 1);
-
- write_lpcontrol(q, 0xe);
- n2 = qc_waithand(q, 0);
-
- cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
- return cmd;
-}
-
-static int qc_readparam(struct qcam *q)
-{
- int n1, n2;
- int cmd;
-
- write_lpcontrol(q, 6);
- n1 = qc_waithand(q, 1);
-
- write_lpcontrol(q, 0xe);
- n2 = qc_waithand(q, 0);
-
- cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
- return cmd;
-}
-
-
-/* Try to detect a QuickCam. It appears to flash the upper 4 bits of
- the status register at 5-10 Hz. This is only used in the autoprobe
- code. Be aware that this isn't the way Connectix detects the
- camera (they send a reset and try to handshake), but this should be
- almost completely safe, while their method screws up my printer if
- I plug it in before the camera. */
-
-static int qc_detect(struct qcam *q)
-{
- int reg, lastreg;
- int count = 0;
- int i;
-
- if (force_init)
- return 1;
-
- lastreg = reg = read_lpstatus(q) & 0xf0;
-
- for (i = 0; i < 500; i++) {
- reg = read_lpstatus(q) & 0xf0;
- if (reg != lastreg)
- count++;
- lastreg = reg;
- mdelay(2);
- }
-
-
-#if 0
- /* Force camera detection during testing. Sometimes the camera
- won't be flashing these bits. Possibly unloading the module
- in the middle of a grab? Or some timeout condition?
- I've seen this parameter as low as 19 on my 450Mhz box - mpc */
- printk(KERN_DEBUG "Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count);
- return 1;
-#endif
-
- /* Be (even more) liberal in what you accept... */
-
- if (count > 20 && count < 400) {
- return 1; /* found */
- } else {
- printk(KERN_ERR "No Quickcam found on port %s\n",
- q->pport->name);
- printk(KERN_DEBUG "Quickcam detection counter: %u\n", count);
- return 0; /* not found */
- }
-}
-
-/* Decide which scan mode to use. There's no real requirement that
- * the scanmode match the resolution in q->height and q-> width -- the
- * camera takes the picture at the resolution specified in the
- * "scanmode" and then returns the image at the resolution specified
- * with the resolution commands. If the scan is bigger than the
- * requested resolution, the upper-left hand corner of the scan is
- * returned. If the scan is smaller, then the rest of the image
- * returned contains garbage. */
-
-static int qc_setscanmode(struct qcam *q)
-{
- int old_mode = q->mode;
-
- switch (q->transfer_scale) {
- case 1:
- q->mode = 0;
- break;
- case 2:
- q->mode = 4;
- break;
- case 4:
- q->mode = 8;
- break;
- }
-
- switch (q->bpp) {
- case 4:
- break;
- case 6:
- q->mode += 2;
- break;
- }
-
- switch (q->port_mode & QC_MODE_MASK) {
- case QC_BIDIR:
- q->mode += 1;
- break;
- case QC_NOTSET:
- case QC_UNIDIR:
- break;
- }
-
- if (q->mode != old_mode)
- q->status |= QC_PARAM_CHANGE;
-
- return 0;
-}
-
-
-/* Reset the QuickCam. This uses the same sequence the Windows
- * QuickPic program uses. Someone with a bi-directional port should
- * check that bi-directional mode is detected right, and then
- * implement bi-directional mode in qc_readbyte(). */
-
-static void qc_reset(struct qcam *q)
-{
- switch (q->port_mode & QC_FORCE_MASK) {
- case QC_FORCE_UNIDIR:
- q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
- break;
-
- case QC_FORCE_BIDIR:
- q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
- break;
-
- case QC_ANY:
- write_lpcontrol(q, 0x20);
- write_lpdata(q, 0x75);
-
- if (read_lpdata(q) != 0x75)
- q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
- else
- q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
- break;
- }
-
- write_lpcontrol(q, 0xb);
- udelay(250);
- write_lpcontrol(q, 0xe);
- qc_setscanmode(q); /* in case port_mode changed */
-}
-
-
-
-/* Reset the QuickCam and program for brightness, contrast,
- * white-balance, and resolution. */
-
-static void qc_set(struct qcam *q)
-{
- int val;
- int val2;
-
- qc_reset(q);
-
- /* Set the brightness. Yes, this is repetitive, but it works.
- * Shorter versions seem to fail subtly. Feel free to try :-). */
- /* I think the problem was in qc_command, not here -- bls */
-
- qc_command(q, 0xb);
- qc_command(q, q->brightness);
-
- val = q->height / q->transfer_scale;
- qc_command(q, 0x11);
- qc_command(q, val);
- if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) {
- /* The normal "transfers per line" calculation doesn't seem to work
- as expected here (and yet it works fine in qc_scan). No idea
- why this case is the odd man out. Fortunately, Laird's original
- working version gives me a good way to guess at working values.
- -- bls */
- val = q->width;
- val2 = q->transfer_scale * 4;
- } else {
- val = q->width * q->bpp;
- val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
- q->transfer_scale;
- }
- val = DIV_ROUND_UP(val, val2);
- qc_command(q, 0x13);
- qc_command(q, val);
-
- /* Setting top and left -- bls */
- qc_command(q, 0xd);
- qc_command(q, q->top);
- qc_command(q, 0xf);
- qc_command(q, q->left / 2);
-
- qc_command(q, 0x19);
- qc_command(q, q->contrast);
- qc_command(q, 0x1f);
- qc_command(q, q->whitebal);
-
- /* Clear flag that we must update the grabbing parameters on the camera
- before we grab the next frame */
- q->status &= (~QC_PARAM_CHANGE);
-}
-
-/* Qc_readbytes reads some bytes from the QC and puts them in
- the supplied buffer. It returns the number of bytes read,
- or -1 on error. */
-
-static inline int qc_readbytes(struct qcam *q, char buffer[])
-{
- int ret = 1;
- unsigned int hi, lo;
- unsigned int hi2, lo2;
- static int state;
-
- if (buffer == NULL) {
- state = 0;
- return 0;
- }
-
- switch (q->port_mode & QC_MODE_MASK) {
- case QC_BIDIR: /* Bi-directional Port */
- write_lpcontrol(q, 0x26);
- lo = (qc_waithand2(q, 1) >> 1);
- hi = (read_lpstatus(q) >> 3) & 0x1f;
- write_lpcontrol(q, 0x2e);
- lo2 = (qc_waithand2(q, 0) >> 1);
- hi2 = (read_lpstatus(q) >> 3) & 0x1f;
- switch (q->bpp) {
- case 4:
- buffer[0] = lo & 0xf;
- buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
- buffer[2] = (hi & 0x1e) >> 1;
- buffer[3] = lo2 & 0xf;
- buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
- buffer[5] = (hi2 & 0x1e) >> 1;
- ret = 6;
- break;
- case 6:
- buffer[0] = lo & 0x3f;
- buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
- buffer[2] = lo2 & 0x3f;
- buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
- ret = 4;
- break;
- }
- break;
-
- case QC_UNIDIR: /* Unidirectional Port */
- write_lpcontrol(q, 6);
- lo = (qc_waithand(q, 1) & 0xf0) >> 4;
- write_lpcontrol(q, 0xe);
- hi = (qc_waithand(q, 0) & 0xf0) >> 4;
-
- switch (q->bpp) {
- case 4:
- buffer[0] = lo;
- buffer[1] = hi;
- ret = 2;
- break;
- case 6:
- switch (state) {
- case 0:
- buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
- q->saved_bits = (hi & 3) << 4;
- state = 1;
- ret = 1;
- break;
- case 1:
- buffer[0] = lo | q->saved_bits;
- q->saved_bits = hi << 2;
- state = 2;
- ret = 1;
- break;
- case 2:
- buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
- buffer[1] = ((lo & 3) << 4) | hi;
- state = 0;
- ret = 2;
- break;
- }
- break;
- }
- break;
- }
- return ret;
-}
-
-/* requests a scan from the camera. It sends the correct instructions
- * to the camera and then reads back the correct number of bytes. In
- * previous versions of this routine the return structure contained
- * the raw output from the camera, and there was a 'qc_convertscan'
- * function that converted that to a useful format. In version 0.3 I
- * rolled qc_convertscan into qc_scan and now I only return the
- * converted scan. The format is just an one-dimensional array of
- * characters, one for each pixel, with 0=black up to n=white, where
- * n=2^(bit depth)-1. Ask me for more details if you don't understand
- * this. */
-
-static long qc_capture(struct qcam *q, char __user *buf, unsigned long len)
-{
- int i, j, k, yield;
- int bytes;
- int linestotrans, transperline;
- int divisor;
- int pixels_per_line;
- int pixels_read = 0;
- int got = 0;
- char buffer[6];
- int shift = 8 - q->bpp;
- char invert;
-
- if (q->mode == -1)
- return -ENXIO;
-
- qc_command(q, 0x7);
- qc_command(q, q->mode);
-
- if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) {
- write_lpcontrol(q, 0x2e); /* turn port around */
- write_lpcontrol(q, 0x26);
- qc_waithand(q, 1);
- write_lpcontrol(q, 0x2e);
- qc_waithand(q, 0);
- }
-
- /* strange -- should be 15:63 below, but 4bpp is odd */
- invert = (q->bpp == 4) ? 16 : 63;
-
- linestotrans = q->height / q->transfer_scale;
- pixels_per_line = q->width / q->transfer_scale;
- transperline = q->width * q->bpp;
- divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
- q->transfer_scale;
- transperline = DIV_ROUND_UP(transperline, divisor);
-
- for (i = 0, yield = yieldlines; i < linestotrans; i++) {
- for (pixels_read = j = 0; j < transperline; j++) {
- bytes = qc_readbytes(q, buffer);
- for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) {
- int o;
- if (buffer[k] == 0 && invert == 16) {
- /* 4bpp is odd (again) -- inverter is 16, not 15, but output
- must be 0-15 -- bls */
- buffer[k] = 16;
- }
- o = i * pixels_per_line + pixels_read + k;
- if (o < len) {
- u8 ch = invert - buffer[k];
- got++;
- put_user(ch << shift, buf + o);
- }
- }
- pixels_read += bytes;
- }
- qc_readbytes(q, NULL); /* reset state machine */
-
- /* Grabbing an entire frame from the quickcam is a lengthy
- process. We don't (usually) want to busy-block the
- processor for the entire frame. yieldlines is a module
- parameter. If we yield every line, the minimum frame
- time will be 240 / 200 = 1.2 seconds. The compile-time
- default is to yield every 4 lines. */
- if (i >= yield) {
- msleep_interruptible(5);
- yield = i + yieldlines;
- }
- }
-
- if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) {
- write_lpcontrol(q, 2);
- write_lpcontrol(q, 6);
- udelay(3);
- write_lpcontrol(q, 0xe);
- }
- if (got < len)
- return got;
- return len;
-}
-
-/*
- * Video4linux interfacing
- */
-
-static int qcam_querycap(struct file *file, void *priv,
- struct v4l2_capability *vcap)
-{
- struct qcam *qcam = video_drvdata(file);
-
- strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
- strlcpy(vcap->card, "Connectix B&W Quickcam", sizeof(vcap->card));
- strlcpy(vcap->bus_info, qcam->pport->name, sizeof(vcap->bus_info));
- vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
- vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
- return 0;
-}
-
-static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
-{
- if (vin->index > 0)
- return -EINVAL;
- strlcpy(vin->name, "Camera", sizeof(vin->name));
- vin->type = V4L2_INPUT_TYPE_CAMERA;
- vin->audioset = 0;
- vin->tuner = 0;
- vin->std = 0;
- vin->status = 0;
- return 0;
-}
-
-static int qcam_g_input(struct file *file, void *fh, unsigned int *inp)
-{
- *inp = 0;
- return 0;
-}
-
-static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
-{
- return (inp > 0) ? -EINVAL : 0;
-}
-
-static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct qcam *qcam = video_drvdata(file);
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
-
- pix->width = qcam->width / qcam->transfer_scale;
- pix->height = qcam->height / qcam->transfer_scale;
- pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6;
- pix->field = V4L2_FIELD_NONE;
- pix->bytesperline = pix->width;
- pix->sizeimage = pix->width * pix->height;
- /* Just a guess */
- pix->colorspace = V4L2_COLORSPACE_SRGB;
- return 0;
-}
-
-static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
-
- if (pix->height <= 60 || pix->width <= 80) {
- pix->height = 60;
- pix->width = 80;
- } else if (pix->height <= 120 || pix->width <= 160) {
- pix->height = 120;
- pix->width = 160;
- } else {
- pix->height = 240;
- pix->width = 320;
- }
- if (pix->pixelformat != V4L2_PIX_FMT_Y4 &&
- pix->pixelformat != V4L2_PIX_FMT_Y6)
- pix->pixelformat = V4L2_PIX_FMT_Y4;
- pix->field = V4L2_FIELD_NONE;
- pix->bytesperline = pix->width;
- pix->sizeimage = pix->width * pix->height;
- /* Just a guess */
- pix->colorspace = V4L2_COLORSPACE_SRGB;
- return 0;
-}
-
-static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct qcam *qcam = video_drvdata(file);
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
- int ret = qcam_try_fmt_vid_cap(file, fh, fmt);
-
- if (ret)
- return ret;
- qcam->width = 320;
- qcam->height = 240;
- if (pix->height == 60)
- qcam->transfer_scale = 4;
- else if (pix->height == 120)
- qcam->transfer_scale = 2;
- else
- qcam->transfer_scale = 1;
- if (pix->pixelformat == V4L2_PIX_FMT_Y6)
- qcam->bpp = 6;
- else
- qcam->bpp = 4;
-
- mutex_lock(&qcam->lock);
- qc_setscanmode(qcam);
- /* We must update the camera before we grab. We could
- just have changed the grab size */
- qcam->status |= QC_PARAM_CHANGE;
- mutex_unlock(&qcam->lock);
- return 0;
-}
-
-static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
-{
- static struct v4l2_fmtdesc formats[] = {
- { 0, 0, 0,
- "4-Bit Monochrome", V4L2_PIX_FMT_Y4,
- { 0, 0, 0, 0 }
- },
- { 1, 0, 0,
- "6-Bit Monochrome", V4L2_PIX_FMT_Y6,
- { 0, 0, 0, 0 }
- },
- };
- enum v4l2_buf_type type = fmt->type;
-
- if (fmt->index > 1)
- return -EINVAL;
-
- *fmt = formats[fmt->index];
- fmt->type = type;
- return 0;
-}
-
-static int qcam_enum_framesizes(struct file *file, void *fh,
- struct v4l2_frmsizeenum *fsize)
-{
- static const struct v4l2_frmsize_discrete sizes[] = {
- { 80, 60 },
- { 160, 120 },
- { 320, 240 },
- };
-
- if (fsize->index > 2)
- return -EINVAL;
- if (fsize->pixel_format != V4L2_PIX_FMT_Y4 &&
- fsize->pixel_format != V4L2_PIX_FMT_Y6)
- return -EINVAL;
- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fsize->discrete = sizes[fsize->index];
- return 0;
-}
-
-static ssize_t qcam_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct qcam *qcam = video_drvdata(file);
- int len;
- parport_claim_or_block(qcam->pdev);
-
- mutex_lock(&qcam->lock);
-
- qc_reset(qcam);
-
- /* Update the camera parameters if we need to */
- if (qcam->status & QC_PARAM_CHANGE)
- qc_set(qcam);
-
- len = qc_capture(qcam, buf, count);
-
- mutex_unlock(&qcam->lock);
-
- parport_release(qcam->pdev);
- return len;
-}
-
-static unsigned int qcam_poll(struct file *filp, poll_table *wait)
-{
- return v4l2_ctrl_poll(filp, wait) | POLLIN | POLLRDNORM;
-}
-
-static int qcam_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct qcam *qcam =
- container_of(ctrl->handler, struct qcam, hdl);
- int ret = 0;
-
- mutex_lock(&qcam->lock);
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- qcam->brightness = ctrl->val;
- break;
- case V4L2_CID_CONTRAST:
- qcam->contrast = ctrl->val;
- break;
- case V4L2_CID_GAMMA:
- qcam->whitebal = ctrl->val;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- if (ret == 0) {
- qc_setscanmode(qcam);
- qcam->status |= QC_PARAM_CHANGE;
- }
- mutex_unlock(&qcam->lock);
- return ret;
-}
-
-static const struct v4l2_file_operations qcam_fops = {
- .owner = THIS_MODULE,
- .open = v4l2_fh_open,
- .release = v4l2_fh_release,
- .poll = qcam_poll,
- .unlocked_ioctl = video_ioctl2,
- .read = qcam_read,
-};
-
-static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
- .vidioc_querycap = qcam_querycap,
- .vidioc_g_input = qcam_g_input,
- .vidioc_s_input = qcam_s_input,
- .vidioc_enum_input = qcam_enum_input,
- .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
- .vidioc_enum_framesizes = qcam_enum_framesizes,
- .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
- .vidioc_log_status = v4l2_ctrl_log_status,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static const struct v4l2_ctrl_ops qcam_ctrl_ops = {
- .s_ctrl = qcam_s_ctrl,
-};
-
-/* Initialize the QuickCam driver control structure. This is where
- * defaults are set for people who don't have a config file.*/
-
-static struct qcam *qcam_init(struct parport *port)
-{
- struct qcam *qcam;
- struct v4l2_device *v4l2_dev;
-
- qcam = kzalloc(sizeof(struct qcam), GFP_KERNEL);
- if (qcam == NULL)
- return NULL;
-
- v4l2_dev = &qcam->v4l2_dev;
- snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "bw-qcam%d", num_cams);
-
- if (v4l2_device_register(port->dev, v4l2_dev) < 0) {
- v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
- kfree(qcam);
- return NULL;
- }
-
- v4l2_ctrl_handler_init(&qcam->hdl, 3);
- v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 180);
- v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 192);
- v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
- V4L2_CID_GAMMA, 0, 255, 1, 105);
- if (qcam->hdl.error) {
- v4l2_err(v4l2_dev, "couldn't register controls\n");
- v4l2_ctrl_handler_free(&qcam->hdl);
- kfree(qcam);
- return NULL;
- }
- qcam->pport = port;
- qcam->pdev = parport_register_device(port, v4l2_dev->name, NULL, NULL,
- NULL, 0, NULL);
- if (qcam->pdev == NULL) {
- v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
- v4l2_ctrl_handler_free(&qcam->hdl);
- kfree(qcam);
- return NULL;
- }
-
- strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name));
- qcam->vdev.v4l2_dev = v4l2_dev;
- qcam->vdev.ctrl_handler = &qcam->hdl;
- qcam->vdev.fops = &qcam_fops;
- qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
- set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags);
- qcam->vdev.release = video_device_release_empty;
- video_set_drvdata(&qcam->vdev, qcam);
-
- mutex_init(&qcam->lock);
-
- qcam->port_mode = (QC_ANY | QC_NOTSET);
- qcam->width = 320;
- qcam->height = 240;
- qcam->bpp = 4;
- qcam->transfer_scale = 2;
- qcam->contrast = 192;
- qcam->brightness = 180;
- qcam->whitebal = 105;
- qcam->top = 1;
- qcam->left = 14;
- qcam->mode = -1;
- qcam->status = QC_PARAM_CHANGE;
- return qcam;
-}
-
-static int qc_calibrate(struct qcam *q)
-{
- /*
- * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
- * The white balance is an individual value for each
- * quickcam.
- */
-
- int value;
- int count = 0;
-
- qc_command(q, 27); /* AutoAdjustOffset */
- qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
-
- /* GetOffset (33) will read 255 until autocalibration */
- /* is finished. After that, a value of 1-254 will be */
- /* returned. */
-
- do {
- qc_command(q, 33);
- value = qc_readparam(q);
- mdelay(1);
- schedule();
- count++;
- } while (value == 0xff && count < 2048);
-
- q->whitebal = value;
- return value;
-}
-
-static int init_bwqcam(struct parport *port)
-{
- struct qcam *qcam;
-
- if (num_cams == MAX_CAMS) {
- printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
- return -ENOSPC;
- }
-
- qcam = qcam_init(port);
- if (qcam == NULL)
- return -ENODEV;
-
- parport_claim_or_block(qcam->pdev);
-
- qc_reset(qcam);
-
- if (qc_detect(qcam) == 0) {
- parport_release(qcam->pdev);
- parport_unregister_device(qcam->pdev);
- kfree(qcam);
- return -ENODEV;
- }
- qc_calibrate(qcam);
- v4l2_ctrl_handler_setup(&qcam->hdl);
-
- parport_release(qcam->pdev);
-
- v4l2_info(&qcam->v4l2_dev, "Connectix Quickcam on %s\n", qcam->pport->name);
-
- if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
- parport_unregister_device(qcam->pdev);
- kfree(qcam);
- return -ENODEV;
- }
-
- qcams[num_cams++] = qcam;
-
- return 0;
-}
-
-static void close_bwqcam(struct qcam *qcam)
-{
- video_unregister_device(&qcam->vdev);
- v4l2_ctrl_handler_free(&qcam->hdl);
- parport_unregister_device(qcam->pdev);
- kfree(qcam);
-}
-
-/* The parport parameter controls which parports will be scanned.
- * Scanning all parports causes some printers to print a garbage page.
- * -- March 14, 1999 Billy Donahue <billy@escape.com> */
-#ifdef MODULE
-static char *parport[MAX_CAMS] = { NULL, };
-module_param_array(parport, charp, NULL, 0);
-#endif
-
-static int accept_bwqcam(struct parport *port)
-{
-#ifdef MODULE
- int n;
-
- if (parport[0] && strncmp(parport[0], "auto", 4) != 0) {
- /* user gave parport parameters */
- for (n = 0; n < MAX_CAMS && parport[n]; n++) {
- char *ep;
- unsigned long r;
- r = simple_strtoul(parport[n], &ep, 0);
- if (ep == parport[n]) {
- printk(KERN_ERR
- "bw-qcam: bad port specifier \"%s\"\n",
- parport[n]);
- continue;
- }
- if (r == port->number)
- return 1;
- }
- return 0;
- }
-#endif
- return 1;
-}
-
-static void bwqcam_attach(struct parport *port)
-{
- if (accept_bwqcam(port))
- init_bwqcam(port);
-}
-
-static void bwqcam_detach(struct parport *port)
-{
- int i;
- for (i = 0; i < num_cams; i++) {
- struct qcam *qcam = qcams[i];
- if (qcam && qcam->pdev->port == port) {
- qcams[i] = NULL;
- close_bwqcam(qcam);
- }
- }
-}
-
-static struct parport_driver bwqcam_driver = {
- .name = "bw-qcam",
- .attach = bwqcam_attach,
- .detach = bwqcam_detach,
-};
-
-static void __exit exit_bw_qcams(void)
-{
- parport_unregister_driver(&bwqcam_driver);
-}
-
-static int __init init_bw_qcams(void)
-{
-#ifdef MODULE
- /* Do some sanity checks on the module parameters. */
- if (maxpoll > 5000) {
- printk(KERN_INFO "Connectix Quickcam max-poll was above 5000. Using 5000.\n");
- maxpoll = 5000;
- }
-
- if (yieldlines < 1) {
- printk(KERN_INFO "Connectix Quickcam yieldlines was less than 1. Using 1.\n");
- yieldlines = 1;
- }
-#endif
- return parport_register_driver(&bwqcam_driver);
-}
-
-module_init(init_bw_qcams);
-module_exit(exit_bw_qcams);
-
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.3");
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
deleted file mode 100644
index ec51e1f12e8..00000000000
--- a/drivers/media/video/c-qcam.c
+++ /dev/null
@@ -1,883 +0,0 @@
-/*
- * Video4Linux Colour QuickCam driver
- * Copyright 1997-2000 Philip Blundell <philb@gnu.org>
- *
- * Module parameters:
- *
- * parport=auto -- probe all parports (default)
- * parport=0 -- parport0 becomes qcam1
- * parport=2,0,1 -- parports 2,0,1 are tried in that order
- *
- * probe=0 -- do no probing, assume camera is present
- * probe=1 -- use IEEE-1284 autoprobe data only (default)
- * probe=2 -- probe aggressively for cameras
- *
- * force_rgb=1 -- force data format to RGB (default is BGR)
- *
- * The parport parameter controls which parports will be scanned.
- * Scanning all parports causes some printers to print a garbage page.
- * -- March 14, 1999 Billy Donahue <billy@escape.com>
- *
- * Fixed data format to BGR, added force_rgb parameter. Added missing
- * parport_unregister_driver() on module removal.
- * -- May 28, 2000 Claudio Matsuoka <claudio@conectiva.com>
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/parport.h>
-#include <linux/sched.h>
-#include <linux/mutex.h>
-#include <linux/jiffies.h>
-#include <linux/videodev2.h>
-#include <asm/uaccess.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
-
-struct qcam {
- struct v4l2_device v4l2_dev;
- struct video_device vdev;
- struct v4l2_ctrl_handler hdl;
- struct pardevice *pdev;
- struct parport *pport;
- int width, height;
- int ccd_width, ccd_height;
- int mode;
- int contrast, brightness, whitebal;
- int top, left;
- unsigned int bidirectional;
- struct mutex lock;
-};
-
-/* cameras maximum */
-#define MAX_CAMS 4
-
-/* The three possible QuickCam modes */
-#define QC_MILLIONS 0x18
-#define QC_BILLIONS 0x10
-#define QC_THOUSANDS 0x08 /* with VIDEC compression (not supported) */
-
-/* The three possible decimations */
-#define QC_DECIMATION_1 0
-#define QC_DECIMATION_2 2
-#define QC_DECIMATION_4 4
-
-#define BANNER "Colour QuickCam for Video4Linux v0.06"
-
-static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
-static int probe = 2;
-static bool force_rgb;
-static int video_nr = -1;
-
-/* FIXME: parport=auto would never have worked, surely? --RR */
-MODULE_PARM_DESC(parport, "parport=<auto|n[,n]...> for port detection method\n"
- "probe=<0|1|2> for camera detection method\n"
- "force_rgb=<0|1> for RGB data format (default BGR)");
-module_param_array(parport, int, NULL, 0);
-module_param(probe, int, 0);
-module_param(force_rgb, bool, 0);
-module_param(video_nr, int, 0);
-
-static struct qcam *qcams[MAX_CAMS];
-static unsigned int num_cams;
-
-static inline void qcam_set_ack(struct qcam *qcam, unsigned int i)
-{
- /* note: the QC specs refer to the PCAck pin by voltage, not
- software level. PC ports have builtin inverters. */
- parport_frob_control(qcam->pport, 8, i ? 8 : 0);
-}
-
-static inline unsigned int qcam_ready1(struct qcam *qcam)
-{
- return (parport_read_status(qcam->pport) & 0x8) ? 1 : 0;
-}
-
-static inline unsigned int qcam_ready2(struct qcam *qcam)
-{
- return (parport_read_data(qcam->pport) & 0x1) ? 1 : 0;
-}
-
-static unsigned int qcam_await_ready1(struct qcam *qcam, int value)
-{
- struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
- unsigned long oldjiffies = jiffies;
- unsigned int i;
-
- for (oldjiffies = jiffies;
- time_before(jiffies, oldjiffies + msecs_to_jiffies(40));)
- if (qcam_ready1(qcam) == value)
- return 0;
-
- /* If the camera didn't respond within 1/25 second, poll slowly
- for a while. */
- for (i = 0; i < 50; i++) {
- if (qcam_ready1(qcam) == value)
- return 0;
- msleep_interruptible(100);
- }
-
- /* Probably somebody pulled the plug out. Not much we can do. */
- v4l2_err(v4l2_dev, "ready1 timeout (%d) %x %x\n", value,
- parport_read_status(qcam->pport),
- parport_read_control(qcam->pport));
- return 1;
-}
-
-static unsigned int qcam_await_ready2(struct qcam *qcam, int value)
-{
- struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
- unsigned long oldjiffies = jiffies;
- unsigned int i;
-
- for (oldjiffies = jiffies;
- time_before(jiffies, oldjiffies + msecs_to_jiffies(40));)
- if (qcam_ready2(qcam) == value)
- return 0;
-
- /* If the camera didn't respond within 1/25 second, poll slowly
- for a while. */
- for (i = 0; i < 50; i++) {
- if (qcam_ready2(qcam) == value)
- return 0;
- msleep_interruptible(100);
- }
-
- /* Probably somebody pulled the plug out. Not much we can do. */
- v4l2_err(v4l2_dev, "ready2 timeout (%d) %x %x %x\n", value,
- parport_read_status(qcam->pport),
- parport_read_control(qcam->pport),
- parport_read_data(qcam->pport));
- return 1;
-}
-
-static int qcam_read_data(struct qcam *qcam)
-{
- unsigned int idata;
-
- qcam_set_ack(qcam, 0);
- if (qcam_await_ready1(qcam, 1))
- return -1;
- idata = parport_read_status(qcam->pport) & 0xf0;
- qcam_set_ack(qcam, 1);
- if (qcam_await_ready1(qcam, 0))
- return -1;
- idata |= parport_read_status(qcam->pport) >> 4;
- return idata;
-}
-
-static int qcam_write_data(struct qcam *qcam, unsigned int data)
-{
- struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
- unsigned int idata;
-
- parport_write_data(qcam->pport, data);
- idata = qcam_read_data(qcam);
- if (data != idata) {
- v4l2_warn(v4l2_dev, "sent %x but received %x\n", data,
- idata);
- return 1;
- }
- return 0;
-}
-
-static inline int qcam_set(struct qcam *qcam, unsigned int cmd, unsigned int data)
-{
- if (qcam_write_data(qcam, cmd))
- return -1;
- if (qcam_write_data(qcam, data))
- return -1;
- return 0;
-}
-
-static inline int qcam_get(struct qcam *qcam, unsigned int cmd)
-{
- if (qcam_write_data(qcam, cmd))
- return -1;
- return qcam_read_data(qcam);
-}
-
-static int qc_detect(struct qcam *qcam)
-{
- unsigned int stat, ostat, i, count = 0;
-
- /* The probe routine below is not very reliable. The IEEE-1284
- probe takes precedence. */
- /* XXX Currently parport provides no way to distinguish between
- "the IEEE probe was not done" and "the probe was done, but
- no device was found". Fix this one day. */
- if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA
- && qcam->pport->probe_info[0].model
- && !strcmp(qcam->pdev->port->probe_info[0].model,
- "Color QuickCam 2.0")) {
- printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n");
- return 1;
- }
-
- if (probe < 2)
- return 0;
-
- parport_write_control(qcam->pport, 0xc);
-
- /* look for a heartbeat */
- ostat = stat = parport_read_status(qcam->pport);
- for (i = 0; i < 250; i++) {
- mdelay(1);
- stat = parport_read_status(qcam->pport);
- if (ostat != stat) {
- if (++count >= 3)
- return 1;
- ostat = stat;
- }
- }
-
- /* Reset the camera and try again */
- parport_write_control(qcam->pport, 0xc);
- parport_write_control(qcam->pport, 0x8);
- mdelay(1);
- parport_write_control(qcam->pport, 0xc);
- mdelay(1);
- count = 0;
-
- ostat = stat = parport_read_status(qcam->pport);
- for (i = 0; i < 250; i++) {
- mdelay(1);
- stat = parport_read_status(qcam->pport);
- if (ostat != stat) {
- if (++count >= 3)
- return 1;
- ostat = stat;
- }
- }
-
- /* no (or flatline) camera, give up */
- return 0;
-}
-
-static void qc_reset(struct qcam *qcam)
-{
- parport_write_control(qcam->pport, 0xc);
- parport_write_control(qcam->pport, 0x8);
- mdelay(1);
- parport_write_control(qcam->pport, 0xc);
- mdelay(1);
-}
-
-/* Reset the QuickCam and program for brightness, contrast,
- * white-balance, and resolution. */
-
-static void qc_setup(struct qcam *qcam)
-{
- qc_reset(qcam);
-
- /* Set the brightness. */
- qcam_set(qcam, 11, qcam->brightness);
-
- /* Set the height and width. These refer to the actual
- CCD area *before* applying the selected decimation. */
- qcam_set(qcam, 17, qcam->ccd_height);
- qcam_set(qcam, 19, qcam->ccd_width / 2);
-
- /* Set top and left. */
- qcam_set(qcam, 0xd, qcam->top);
- qcam_set(qcam, 0xf, qcam->left);
-
- /* Set contrast and white balance. */
- qcam_set(qcam, 0x19, qcam->contrast);
- qcam_set(qcam, 0x1f, qcam->whitebal);
-
- /* Set the speed. */
- qcam_set(qcam, 45, 2);
-}
-
-/* Read some bytes from the camera and put them in the buffer.
- nbytes should be a multiple of 3, because bidirectional mode gives
- us three bytes at a time. */
-
-static unsigned int qcam_read_bytes(struct qcam *qcam, unsigned char *buf, unsigned int nbytes)
-{
- unsigned int bytes = 0;
-
- qcam_set_ack(qcam, 0);
- if (qcam->bidirectional) {
- /* It's a bidirectional port */
- while (bytes < nbytes) {
- unsigned int lo1, hi1, lo2, hi2;
- unsigned char r, g, b;
-
- if (qcam_await_ready2(qcam, 1))
- return bytes;
- lo1 = parport_read_data(qcam->pport) >> 1;
- hi1 = ((parport_read_status(qcam->pport) >> 3) & 0x1f) ^ 0x10;
- qcam_set_ack(qcam, 1);
- if (qcam_await_ready2(qcam, 0))
- return bytes;
- lo2 = parport_read_data(qcam->pport) >> 1;
- hi2 = ((parport_read_status(qcam->pport) >> 3) & 0x1f) ^ 0x10;
- qcam_set_ack(qcam, 0);
- r = lo1 | ((hi1 & 1) << 7);
- g = ((hi1 & 0x1e) << 3) | ((hi2 & 0x1e) >> 1);
- b = lo2 | ((hi2 & 1) << 7);
- if (force_rgb) {
- buf[bytes++] = r;
- buf[bytes++] = g;
- buf[bytes++] = b;
- } else {
- buf[bytes++] = b;
- buf[bytes++] = g;
- buf[bytes++] = r;
- }
- }
- } else {
- /* It's a unidirectional port */
- int i = 0, n = bytes;
- unsigned char rgb[3];
-
- while (bytes < nbytes) {
- unsigned int hi, lo;
-
- if (qcam_await_ready1(qcam, 1))
- return bytes;
- hi = (parport_read_status(qcam->pport) & 0xf0);
- qcam_set_ack(qcam, 1);
- if (qcam_await_ready1(qcam, 0))
- return bytes;
- lo = (parport_read_status(qcam->pport) & 0xf0);
- qcam_set_ack(qcam, 0);
- /* flip some bits */
- rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88;
- if (i >= 2) {
-get_fragment:
- if (force_rgb) {
- buf[n++] = rgb[0];
- buf[n++] = rgb[1];
- buf[n++] = rgb[2];
- } else {
- buf[n++] = rgb[2];
- buf[n++] = rgb[1];
- buf[n++] = rgb[0];
- }
- }
- }
- if (i) {
- i = 0;
- goto get_fragment;
- }
- }
- return bytes;
-}
-
-#define BUFSZ 150
-
-static long qc_capture(struct qcam *qcam, char __user *buf, unsigned long len)
-{
- struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
- unsigned lines, pixelsperline;
- unsigned int is_bi_dir = qcam->bidirectional;
- size_t wantlen, outptr = 0;
- char tmpbuf[BUFSZ];
-
- if (!access_ok(VERIFY_WRITE, buf, len))
- return -EFAULT;
-
- /* Wait for camera to become ready */
- for (;;) {
- int i = qcam_get(qcam, 41);
-
- if (i == -1) {
- qc_setup(qcam);
- return -EIO;
- }
- if ((i & 0x80) == 0)
- break;
- schedule();
- }
-
- if (qcam_set(qcam, 7, (qcam->mode | (is_bi_dir ? 1 : 0)) + 1))
- return -EIO;
-
- lines = qcam->height;
- pixelsperline = qcam->width;
-
- if (is_bi_dir) {
- /* Turn the port around */
- parport_data_reverse(qcam->pport);
- mdelay(3);
- qcam_set_ack(qcam, 0);
- if (qcam_await_ready1(qcam, 1)) {
- qc_setup(qcam);
- return -EIO;
- }
- qcam_set_ack(qcam, 1);
- if (qcam_await_ready1(qcam, 0)) {
- qc_setup(qcam);
- return -EIO;
- }
- }
-
- wantlen = lines * pixelsperline * 24 / 8;
-
- while (wantlen) {
- size_t t, s;
-
- s = (wantlen > BUFSZ) ? BUFSZ : wantlen;
- t = qcam_read_bytes(qcam, tmpbuf, s);
- if (outptr < len) {
- size_t sz = len - outptr;
-
- if (sz > t)
- sz = t;
- if (__copy_to_user(buf + outptr, tmpbuf, sz))
- break;
- outptr += sz;
- }
- wantlen -= t;
- if (t < s)
- break;
- cond_resched();
- }
-
- len = outptr;
-
- if (wantlen) {
- v4l2_err(v4l2_dev, "short read.\n");
- if (is_bi_dir)
- parport_data_forward(qcam->pport);
- qc_setup(qcam);
- return len;
- }
-
- if (is_bi_dir) {
- int l;
-
- do {
- l = qcam_read_bytes(qcam, tmpbuf, 3);
- cond_resched();
- } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
- if (force_rgb) {
- if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
- v4l2_err(v4l2_dev, "bad EOF\n");
- } else {
- if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
- v4l2_err(v4l2_dev, "bad EOF\n");
- }
- qcam_set_ack(qcam, 0);
- if (qcam_await_ready1(qcam, 1)) {
- v4l2_err(v4l2_dev, "no ack after EOF\n");
- parport_data_forward(qcam->pport);
- qc_setup(qcam);
- return len;
- }
- parport_data_forward(qcam->pport);
- mdelay(3);
- qcam_set_ack(qcam, 1);
- if (qcam_await_ready1(qcam, 0)) {
- v4l2_err(v4l2_dev, "no ack to port turnaround\n");
- qc_setup(qcam);
- return len;
- }
- } else {
- int l;
-
- do {
- l = qcam_read_bytes(qcam, tmpbuf, 1);
- cond_resched();
- } while (l && tmpbuf[0] == 0x7e);
- l = qcam_read_bytes(qcam, tmpbuf + 1, 2);
- if (force_rgb) {
- if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
- v4l2_err(v4l2_dev, "bad EOF\n");
- } else {
- if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
- v4l2_err(v4l2_dev, "bad EOF\n");
- }
- }
-
- qcam_write_data(qcam, 0);
- return len;
-}
-
-/*
- * Video4linux interfacing
- */
-
-static int qcam_querycap(struct file *file, void *priv,
- struct v4l2_capability *vcap)
-{
- struct qcam *qcam = video_drvdata(file);
-
- strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
- strlcpy(vcap->card, "Color Quickcam", sizeof(vcap->card));
- strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
- vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
- vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
- return 0;
-}
-
-static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
-{
- if (vin->index > 0)
- return -EINVAL;
- strlcpy(vin->name, "Camera", sizeof(vin->name));
- vin->type = V4L2_INPUT_TYPE_CAMERA;
- vin->audioset = 0;
- vin->tuner = 0;
- vin->std = 0;
- vin->status = 0;
- return 0;
-}
-
-static int qcam_g_input(struct file *file, void *fh, unsigned int *inp)
-{
- *inp = 0;
- return 0;
-}
-
-static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
-{
- return (inp > 0) ? -EINVAL : 0;
-}
-
-static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct qcam *qcam = video_drvdata(file);
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
-
- pix->width = qcam->width;
- pix->height = qcam->height;
- pix->pixelformat = V4L2_PIX_FMT_RGB24;
- pix->field = V4L2_FIELD_NONE;
- pix->bytesperline = 3 * qcam->width;
- pix->sizeimage = 3 * qcam->width * qcam->height;
- /* Just a guess */
- pix->colorspace = V4L2_COLORSPACE_SRGB;
- return 0;
-}
-
-static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
-
- if (pix->height < 60 || pix->width < 80) {
- pix->height = 60;
- pix->width = 80;
- } else if (pix->height < 120 || pix->width < 160) {
- pix->height = 120;
- pix->width = 160;
- } else {
- pix->height = 240;
- pix->width = 320;
- }
- pix->pixelformat = V4L2_PIX_FMT_RGB24;
- pix->field = V4L2_FIELD_NONE;
- pix->bytesperline = 3 * pix->width;
- pix->sizeimage = 3 * pix->width * pix->height;
- /* Just a guess */
- pix->colorspace = V4L2_COLORSPACE_SRGB;
- return 0;
-}
-
-static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct qcam *qcam = video_drvdata(file);
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
- int ret = qcam_try_fmt_vid_cap(file, fh, fmt);
-
- if (ret)
- return ret;
- switch (pix->height) {
- case 60:
- qcam->mode = QC_DECIMATION_4;
- break;
- case 120:
- qcam->mode = QC_DECIMATION_2;
- break;
- default:
- qcam->mode = QC_DECIMATION_1;
- break;
- }
-
- mutex_lock(&qcam->lock);
- qcam->mode |= QC_MILLIONS;
- qcam->height = pix->height;
- qcam->width = pix->width;
- parport_claim_or_block(qcam->pdev);
- qc_setup(qcam);
- parport_release(qcam->pdev);
- mutex_unlock(&qcam->lock);
- return 0;
-}
-
-static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
-{
- static struct v4l2_fmtdesc formats[] = {
- { 0, 0, 0,
- "RGB 8:8:8", V4L2_PIX_FMT_RGB24,
- { 0, 0, 0, 0 }
- },
- };
- enum v4l2_buf_type type = fmt->type;
-
- if (fmt->index > 0)
- return -EINVAL;
-
- *fmt = formats[fmt->index];
- fmt->type = type;
- return 0;
-}
-
-static ssize_t qcam_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct qcam *qcam = video_drvdata(file);
- int len;
-
- mutex_lock(&qcam->lock);
- parport_claim_or_block(qcam->pdev);
- /* Probably should have a semaphore against multiple users */
- len = qc_capture(qcam, buf, count);
- parport_release(qcam->pdev);
- mutex_unlock(&qcam->lock);
- return len;
-}
-
-static int qcam_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct qcam *qcam =
- container_of(ctrl->handler, struct qcam, hdl);
- int ret = 0;
-
- mutex_lock(&qcam->lock);
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- qcam->brightness = ctrl->val;
- break;
- case V4L2_CID_CONTRAST:
- qcam->contrast = ctrl->val;
- break;
- case V4L2_CID_GAMMA:
- qcam->whitebal = ctrl->val;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- if (ret == 0) {
- parport_claim_or_block(qcam->pdev);
- qc_setup(qcam);
- parport_release(qcam->pdev);
- }
- mutex_unlock(&qcam->lock);
- return ret;
-}
-
-static const struct v4l2_file_operations qcam_fops = {
- .owner = THIS_MODULE,
- .open = v4l2_fh_open,
- .release = v4l2_fh_release,
- .poll = v4l2_ctrl_poll,
- .unlocked_ioctl = video_ioctl2,
- .read = qcam_read,
-};
-
-static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
- .vidioc_querycap = qcam_querycap,
- .vidioc_g_input = qcam_g_input,
- .vidioc_s_input = qcam_s_input,
- .vidioc_enum_input = qcam_enum_input,
- .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
- .vidioc_log_status = v4l2_ctrl_log_status,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static const struct v4l2_ctrl_ops qcam_ctrl_ops = {
- .s_ctrl = qcam_s_ctrl,
-};
-
-/* Initialize the QuickCam driver control structure. */
-
-static struct qcam *qcam_init(struct parport *port)
-{
- struct qcam *qcam;
- struct v4l2_device *v4l2_dev;
-
- qcam = kzalloc(sizeof(*qcam), GFP_KERNEL);
- if (qcam == NULL)
- return NULL;
-
- v4l2_dev = &qcam->v4l2_dev;
- strlcpy(v4l2_dev->name, "c-qcam", sizeof(v4l2_dev->name));
-
- if (v4l2_device_register(NULL, v4l2_dev) < 0) {
- v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
- kfree(qcam);
- return NULL;
- }
-
- v4l2_ctrl_handler_init(&qcam->hdl, 3);
- v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 240);
- v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 192);
- v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
- V4L2_CID_GAMMA, 0, 255, 1, 128);
- if (qcam->hdl.error) {
- v4l2_err(v4l2_dev, "couldn't register controls\n");
- v4l2_ctrl_handler_free(&qcam->hdl);
- kfree(qcam);
- return NULL;
- }
-
- qcam->pport = port;
- qcam->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
- NULL, 0, NULL);
-
- qcam->bidirectional = (qcam->pport->modes & PARPORT_MODE_TRISTATE) ? 1 : 0;
-
- if (qcam->pdev == NULL) {
- v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
- v4l2_ctrl_handler_free(&qcam->hdl);
- kfree(qcam);
- return NULL;
- }
-
- strlcpy(qcam->vdev.name, "Colour QuickCam", sizeof(qcam->vdev.name));
- qcam->vdev.v4l2_dev = v4l2_dev;
- qcam->vdev.fops = &qcam_fops;
- qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
- qcam->vdev.release = video_device_release_empty;
- qcam->vdev.ctrl_handler = &qcam->hdl;
- set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags);
- video_set_drvdata(&qcam->vdev, qcam);
-
- mutex_init(&qcam->lock);
- qcam->width = qcam->ccd_width = 320;
- qcam->height = qcam->ccd_height = 240;
- qcam->mode = QC_MILLIONS | QC_DECIMATION_1;
- qcam->contrast = 192;
- qcam->brightness = 240;
- qcam->whitebal = 128;
- qcam->top = 1;
- qcam->left = 14;
- return qcam;
-}
-
-static int init_cqcam(struct parport *port)
-{
- struct qcam *qcam;
- struct v4l2_device *v4l2_dev;
-
- if (parport[0] != -1) {
- /* The user gave specific instructions */
- int i, found = 0;
-
- for (i = 0; i < MAX_CAMS && parport[i] != -1; i++) {
- if (parport[0] == port->number)
- found = 1;
- }
- if (!found)
- return -ENODEV;
- }
-
- if (num_cams == MAX_CAMS)
- return -ENOSPC;
-
- qcam = qcam_init(port);
- if (qcam == NULL)
- return -ENODEV;
-
- v4l2_dev = &qcam->v4l2_dev;
-
- parport_claim_or_block(qcam->pdev);
-
- qc_reset(qcam);
-
- if (probe && qc_detect(qcam) == 0) {
- parport_release(qcam->pdev);
- parport_unregister_device(qcam->pdev);
- kfree(qcam);
- return -ENODEV;
- }
-
- qc_setup(qcam);
-
- parport_release(qcam->pdev);
-
- if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
- v4l2_err(v4l2_dev, "Unable to register Colour QuickCam on %s\n",
- qcam->pport->name);
- parport_unregister_device(qcam->pdev);
- kfree(qcam);
- return -ENODEV;
- }
-
- v4l2_info(v4l2_dev, "%s: Colour QuickCam found on %s\n",
- video_device_node_name(&qcam->vdev), qcam->pport->name);
-
- qcams[num_cams++] = qcam;
-
- return 0;
-}
-
-static void close_cqcam(struct qcam *qcam)
-{
- video_unregister_device(&qcam->vdev);
- v4l2_ctrl_handler_free(&qcam->hdl);
- parport_unregister_device(qcam->pdev);
- kfree(qcam);
-}
-
-static void cq_attach(struct parport *port)
-{
- init_cqcam(port);
-}
-
-static void cq_detach(struct parport *port)
-{
- /* Write this some day. */
-}
-
-static struct parport_driver cqcam_driver = {
- .name = "cqcam",
- .attach = cq_attach,
- .detach = cq_detach,
-};
-
-static int __init cqcam_init(void)
-{
- printk(KERN_INFO BANNER "\n");
-
- return parport_register_driver(&cqcam_driver);
-}
-
-static void __exit cqcam_cleanup(void)
-{
- unsigned int i;
-
- for (i = 0; i < num_cams; i++)
- close_cqcam(qcams[i]);
-
- parport_unregister_driver(&cqcam_driver);
-}
-
-MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
-MODULE_DESCRIPTION(BANNER);
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.4");
-
-module_init(cqcam_init);
-module_exit(cqcam_cleanup);
diff --git a/drivers/media/video/cpia2/Kconfig b/drivers/media/video/cpia2/Kconfig
deleted file mode 100644
index 66e9283f599..00000000000
--- a/drivers/media/video/cpia2/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-config VIDEO_CPIA2
- tristate "CPiA2 Video For Linux"
- depends on VIDEO_DEV && USB && VIDEO_V4L2
- ---help---
- This is the video4linux driver for cameras based on Vision's CPiA2
- (Colour Processor Interface ASIC), such as the Digital Blue QX5
- Microscope. If you have one of these cameras, say Y here
-
- This driver is also available as a module (cpia2).
diff --git a/drivers/media/video/cpia2/Makefile b/drivers/media/video/cpia2/Makefile
deleted file mode 100644
index 828cf1b1df8..00000000000
--- a/drivers/media/video/cpia2/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-cpia2-objs := cpia2_v4l.o cpia2_usb.o cpia2_core.o
-
-obj-$(CONFIG_VIDEO_CPIA2) += cpia2.o
diff --git a/drivers/media/video/cpia2/cpia2.h b/drivers/media/video/cpia2/cpia2.h
deleted file mode 100644
index cdef677d57e..00000000000
--- a/drivers/media/video/cpia2/cpia2.h
+++ /dev/null
@@ -1,487 +0,0 @@
-/****************************************************************************
- *
- * Filename: cpia2.h
- *
- * Copyright 2001, STMicrolectronics, Inc.
- *
- * Contact: steve.miller@st.com
- *
- * Description:
- * This is a USB driver for CPiA2 based video cameras.
- *
- * This driver is modelled on the cpia usb driver by
- * Jochen Scharrlach and Johannes Erdfeldt.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************************/
-
-#ifndef __CPIA2_H__
-#define __CPIA2_H__
-
-#include <linux/videodev2.h>
-#include <linux/usb.h>
-#include <linux/poll.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-
-#include "cpia2_registers.h"
-
-/* define for verbose debug output */
-//#define _CPIA2_DEBUG_
-
-/***
- * Image defines
- ***/
-
-/* Misc constants */
-#define ALLOW_CORRUPT 0 /* Causes collater to discard checksum */
-
-/* USB Transfer mode */
-#define XFER_ISOC 0
-#define XFER_BULK 1
-
-/* USB Alternates */
-#define USBIF_CMDONLY 0
-#define USBIF_BULK 1
-#define USBIF_ISO_1 2 /* 128 bytes/ms */
-#define USBIF_ISO_2 3 /* 384 bytes/ms */
-#define USBIF_ISO_3 4 /* 640 bytes/ms */
-#define USBIF_ISO_4 5 /* 768 bytes/ms */
-#define USBIF_ISO_5 6 /* 896 bytes/ms */
-#define USBIF_ISO_6 7 /* 1023 bytes/ms */
-
-/* Flicker Modes */
-#define NEVER_FLICKER 0
-#define FLICKER_60 60
-#define FLICKER_50 50
-
-/* Debug flags */
-#define DEBUG_NONE 0
-#define DEBUG_REG 0x00000001
-#define DEBUG_DUMP_PATCH 0x00000002
-#define DEBUG_DUMP_REGS 0x00000004
-
-/***
- * Video frame sizes
- ***/
-enum {
- VIDEOSIZE_VGA = 0, /* 640x480 */
- VIDEOSIZE_CIF, /* 352x288 */
- VIDEOSIZE_QVGA, /* 320x240 */
- VIDEOSIZE_QCIF, /* 176x144 */
- VIDEOSIZE_288_216,
- VIDEOSIZE_256_192,
- VIDEOSIZE_224_168,
- VIDEOSIZE_192_144,
-};
-
-#define STV_IMAGE_CIF_ROWS 288
-#define STV_IMAGE_CIF_COLS 352
-
-#define STV_IMAGE_QCIF_ROWS 144
-#define STV_IMAGE_QCIF_COLS 176
-
-#define STV_IMAGE_VGA_ROWS 480
-#define STV_IMAGE_VGA_COLS 640
-
-#define STV_IMAGE_QVGA_ROWS 240
-#define STV_IMAGE_QVGA_COLS 320
-
-#define JPEG_MARKER_COM (1<<6) /* Comment segment */
-
-/***
- * Enums
- ***/
-/* Sensor types available with cpia2 asics */
-enum sensors {
- CPIA2_SENSOR_410,
- CPIA2_SENSOR_500
-};
-
-/* Asic types available in the CPiA2 architecture */
-#define CPIA2_ASIC_672 0x67
-
-/* Device types (stv672, stv676, etc) */
-#define DEVICE_STV_672 0x0001
-#define DEVICE_STV_676 0x0002
-
-enum frame_status {
- FRAME_EMPTY,
- FRAME_READING, /* In the process of being grabbed into */
- FRAME_READY, /* Ready to be read */
- FRAME_ERROR,
-};
-
-/***
- * Register access (for USB request byte)
- ***/
-enum {
- CAMERAACCESS_SYSTEM = 0,
- CAMERAACCESS_VC,
- CAMERAACCESS_VP,
- CAMERAACCESS_IDATA
-};
-
-#define CAMERAACCESS_TYPE_BLOCK 0x00
-#define CAMERAACCESS_TYPE_RANDOM 0x04
-#define CAMERAACCESS_TYPE_MASK 0x08
-#define CAMERAACCESS_TYPE_REPEAT 0x0C
-
-#define TRANSFER_READ 0
-#define TRANSFER_WRITE 1
-
-#define DEFAULT_ALT USBIF_ISO_6
-#define DEFAULT_BRIGHTNESS 0x46
-#define DEFAULT_CONTRAST 0x93
-#define DEFAULT_SATURATION 0x7f
-
-/* Power state */
-#define HI_POWER_MODE CPIA2_SYSTEM_CONTROL_HIGH_POWER
-#define LO_POWER_MODE CPIA2_SYSTEM_CONTROL_LOW_POWER
-
-
-/********
- * Commands
- *******/
-enum {
- CPIA2_CMD_NONE = 0,
- CPIA2_CMD_GET_VERSION,
- CPIA2_CMD_GET_PNP_ID,
- CPIA2_CMD_GET_ASIC_TYPE,
- CPIA2_CMD_GET_SENSOR,
- CPIA2_CMD_GET_VP_DEVICE,
- CPIA2_CMD_GET_VP_BRIGHTNESS,
- CPIA2_CMD_SET_VP_BRIGHTNESS,
- CPIA2_CMD_GET_CONTRAST,
- CPIA2_CMD_SET_CONTRAST,
- CPIA2_CMD_GET_VP_SATURATION,
- CPIA2_CMD_SET_VP_SATURATION,
- CPIA2_CMD_GET_VP_GPIO_DIRECTION,
- CPIA2_CMD_SET_VP_GPIO_DIRECTION,
- CPIA2_CMD_GET_VP_GPIO_DATA,
- CPIA2_CMD_SET_VP_GPIO_DATA,
- CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION,
- CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
- CPIA2_CMD_GET_VC_MP_GPIO_DATA,
- CPIA2_CMD_SET_VC_MP_GPIO_DATA,
- CPIA2_CMD_ENABLE_PACKET_CTRL,
- CPIA2_CMD_GET_FLICKER_MODES,
- CPIA2_CMD_SET_FLICKER_MODES,
- CPIA2_CMD_RESET_FIFO, /* clear fifo and enable stream block */
- CPIA2_CMD_SET_HI_POWER,
- CPIA2_CMD_SET_LOW_POWER,
- CPIA2_CMD_CLEAR_V2W_ERR,
- CPIA2_CMD_SET_USER_MODE,
- CPIA2_CMD_GET_USER_MODE,
- CPIA2_CMD_FRAMERATE_REQ,
- CPIA2_CMD_SET_COMPRESSION_STATE,
- CPIA2_CMD_GET_WAKEUP,
- CPIA2_CMD_SET_WAKEUP,
- CPIA2_CMD_GET_PW_CONTROL,
- CPIA2_CMD_SET_PW_CONTROL,
- CPIA2_CMD_GET_SYSTEM_CTRL,
- CPIA2_CMD_SET_SYSTEM_CTRL,
- CPIA2_CMD_GET_VP_SYSTEM_STATE,
- CPIA2_CMD_GET_VP_SYSTEM_CTRL,
- CPIA2_CMD_SET_VP_SYSTEM_CTRL,
- CPIA2_CMD_GET_VP_EXP_MODES,
- CPIA2_CMD_SET_VP_EXP_MODES,
- CPIA2_CMD_GET_DEVICE_CONFIG,
- CPIA2_CMD_SET_DEVICE_CONFIG,
- CPIA2_CMD_SET_SERIAL_ADDR,
- CPIA2_CMD_SET_SENSOR_CR1,
- CPIA2_CMD_GET_VC_CONTROL,
- CPIA2_CMD_SET_VC_CONTROL,
- CPIA2_CMD_SET_TARGET_KB,
- CPIA2_CMD_SET_DEF_JPEG_OPT,
- CPIA2_CMD_REHASH_VP4,
- CPIA2_CMD_GET_USER_EFFECTS,
- CPIA2_CMD_SET_USER_EFFECTS
-};
-
-enum user_cmd {
- COMMAND_NONE = 0x00000001,
- COMMAND_SET_FPS = 0x00000002,
- COMMAND_SET_COLOR_PARAMS = 0x00000004,
- COMMAND_GET_COLOR_PARAMS = 0x00000008,
- COMMAND_SET_FORMAT = 0x00000010, /* size, etc */
- COMMAND_SET_FLICKER = 0x00000020
-};
-
-/***
- * Some defines specific to the 676 chip
- ***/
-#define CAMACC_CIF 0x01
-#define CAMACC_VGA 0x02
-#define CAMACC_QCIF 0x04
-#define CAMACC_QVGA 0x08
-
-
-struct cpia2_register {
- u8 index;
- u8 value;
-};
-
-struct cpia2_reg_mask {
- u8 index;
- u8 and_mask;
- u8 or_mask;
- u8 fill;
-};
-
-struct cpia2_command {
- u32 command;
- u8 req_mode; /* (Block or random) | registerBank */
- u8 reg_count;
- u8 direction;
- u8 start;
- union reg_types {
- struct cpia2_register registers[32];
- struct cpia2_reg_mask masks[16];
- u8 block_data[64];
- u8 *patch_data; /* points to function defined block */
- } buffer;
-};
-
-struct camera_params {
- struct {
- u8 firmware_revision_hi; /* For system register set (bank 0) */
- u8 firmware_revision_lo;
- u8 asic_id; /* Video Compressor set (bank 1) */
- u8 asic_rev;
- u8 vp_device_hi; /* Video Processor set (bank 2) */
- u8 vp_device_lo;
- u8 sensor_flags;
- u8 sensor_rev;
- } version;
-
- struct {
- u32 device_type; /* enumerated from vendor/product ids.
- * Currently, either STV_672 or STV_676 */
- u16 vendor;
- u16 product;
- u16 device_revision;
- } pnp_id;
-
- struct {
- u8 brightness; /* CPIA2_VP_EXPOSURE_TARGET */
- u8 contrast; /* Note: this is CPIA2_VP_YRANGE */
- u8 saturation; /* CPIA2_VP_SATURATION */
- } color_params;
-
- struct {
- u8 cam_register;
- u8 flicker_mode_req; /* 1 if flicker on, else never flicker */
- } flicker_control;
-
- struct {
- u8 jpeg_options;
- u8 creep_period;
- u8 user_squeeze;
- u8 inhibit_htables;
- } compression;
-
- struct {
- u8 ohsize; /* output image size */
- u8 ovsize;
- u8 hcrop; /* cropping start_pos/4 */
- u8 vcrop;
- u8 hphase; /* scaling registers */
- u8 vphase;
- u8 hispan;
- u8 vispan;
- u8 hicrop;
- u8 vicrop;
- u8 hifraction;
- u8 vifraction;
- } image_size;
-
- struct {
- int width; /* actual window width */
- int height; /* actual window height */
- } roi;
-
- struct {
- u8 video_mode;
- u8 frame_rate;
- u8 video_size; /* Not a register, just a convenience for cropped sizes */
- u8 gpio_direction;
- u8 gpio_data;
- u8 system_ctrl;
- u8 system_state;
- u8 lowlight_boost; /* Bool: 0 = off, 1 = on */
- u8 device_config;
- u8 exposure_modes;
- u8 user_effects;
- } vp_params;
-
- struct {
- u8 pw_control;
- u8 wakeup;
- u8 vc_control;
- u8 vc_mp_direction;
- u8 vc_mp_data;
- u8 quality;
- } vc_params;
-
- struct {
- u8 power_mode;
- u8 system_ctrl;
- u8 stream_mode; /* This is the current alternate for usb drivers */
- u8 allow_corrupt;
- } camera_state;
-};
-
-#define NUM_SBUF 2
-
-struct cpia2_sbuf {
- char *data;
- struct urb *urb;
-};
-
-struct framebuf {
- struct timeval timestamp;
- unsigned long seq;
- int num;
- int length;
- int max_length;
- volatile enum frame_status status;
- u8 *data;
- struct framebuf *next;
-};
-
-struct camera_data {
- /* locks */
- struct v4l2_device v4l2_dev;
- struct mutex v4l2_lock; /* serialize file operations */
- struct v4l2_ctrl_handler hdl;
- struct {
- /* Lights control cluster */
- struct v4l2_ctrl *top_light;
- struct v4l2_ctrl *bottom_light;
- };
- struct v4l2_ctrl *usb_alt;
-
- /* camera status */
- int first_image_seen;
- enum sensors sensor_type;
- u8 flush;
- struct v4l2_fh *stream_fh;
- u8 mmapped;
- int streaming; /* 0 = no, 1 = yes */
- int xfer_mode; /* XFER_BULK or XFER_ISOC */
- struct camera_params params; /* camera settings */
-
- /* v4l */
- int video_size; /* VIDEO_SIZE_ */
- struct video_device vdev; /* v4l videodev */
- u32 width;
- u32 height; /* Its size */
- __u32 pixelformat; /* Format fourcc */
-
- /* USB */
- struct usb_device *dev;
- unsigned char iface;
- unsigned int cur_alt;
- unsigned int old_alt;
- struct cpia2_sbuf sbuf[NUM_SBUF]; /* Double buffering */
-
- wait_queue_head_t wq_stream;
-
- /* Buffering */
- u32 frame_size;
- int num_frames;
- unsigned long frame_count;
- u8 *frame_buffer; /* frame buffer data */
- struct framebuf *buffers;
- struct framebuf * volatile curbuff;
- struct framebuf *workbuff;
-
- /* MJPEG Extension */
- int APPn; /* Number of APP segment to be written, must be 0..15 */
- int APP_len; /* Length of data in JPEG APPn segment */
- char APP_data[60]; /* Data in the JPEG APPn segment. */
-
- int COM_len; /* Length of data in JPEG COM segment */
- char COM_data[60]; /* Data in JPEG COM segment */
-};
-
-/* v4l */
-int cpia2_register_camera(struct camera_data *cam);
-void cpia2_unregister_camera(struct camera_data *cam);
-void cpia2_camera_release(struct v4l2_device *v4l2_dev);
-
-/* core */
-int cpia2_reset_camera(struct camera_data *cam);
-int cpia2_set_low_power(struct camera_data *cam);
-void cpia2_dbg_dump_registers(struct camera_data *cam);
-int cpia2_match_video_size(int width, int height);
-void cpia2_set_camera_state(struct camera_data *cam);
-void cpia2_save_camera_state(struct camera_data *cam);
-void cpia2_set_color_params(struct camera_data *cam);
-void cpia2_set_brightness(struct camera_data *cam, unsigned char value);
-void cpia2_set_contrast(struct camera_data *cam, unsigned char value);
-void cpia2_set_saturation(struct camera_data *cam, unsigned char value);
-int cpia2_set_flicker_mode(struct camera_data *cam, int mode);
-void cpia2_set_format(struct camera_data *cam);
-int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd);
-int cpia2_do_command(struct camera_data *cam,
- unsigned int command,
- unsigned char direction, unsigned char param);
-struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf);
-int cpia2_init_camera(struct camera_data *cam);
-int cpia2_allocate_buffers(struct camera_data *cam);
-void cpia2_free_buffers(struct camera_data *cam);
-long cpia2_read(struct camera_data *cam,
- char __user *buf, unsigned long count, int noblock);
-unsigned int cpia2_poll(struct camera_data *cam,
- struct file *filp, poll_table *wait);
-int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma);
-void cpia2_set_property_flip(struct camera_data *cam, int prop_val);
-void cpia2_set_property_mirror(struct camera_data *cam, int prop_val);
-int cpia2_set_gpio(struct camera_data *cam, unsigned char setting);
-int cpia2_set_fps(struct camera_data *cam, int framerate);
-
-/* usb */
-int cpia2_usb_init(void);
-void cpia2_usb_cleanup(void);
-int cpia2_usb_transfer_cmd(struct camera_data *cam, void *registers,
- u8 request, u8 start, u8 count, u8 direction);
-int cpia2_usb_stream_start(struct camera_data *cam, unsigned int alternate);
-int cpia2_usb_stream_stop(struct camera_data *cam);
-int cpia2_usb_stream_pause(struct camera_data *cam);
-int cpia2_usb_stream_resume(struct camera_data *cam);
-int cpia2_usb_change_streaming_alternate(struct camera_data *cam,
- unsigned int alt);
-
-
-/* ----------------------- debug functions ---------------------- */
-#ifdef _CPIA2_DEBUG_
-#define ALOG(lev, fmt, args...) printk(lev "%s:%d %s(): " fmt, __FILE__, __LINE__, __func__, ## args)
-#define LOG(fmt, args...) ALOG(KERN_INFO, fmt, ## args)
-#define ERR(fmt, args...) ALOG(KERN_ERR, fmt, ## args)
-#define DBG(fmt, args...) ALOG(KERN_DEBUG, fmt, ## args)
-#else
-#define ALOG(fmt,args...) printk(fmt,##args)
-#define LOG(fmt,args...) ALOG(KERN_INFO "cpia2: "fmt,##args)
-#define ERR(fmt,args...) ALOG(KERN_ERR "cpia2: "fmt,##args)
-#define DBG(fmn,args...) do {} while(0)
-#endif
-/* No function or lineno, for shorter lines */
-#define KINFO(fmt, args...) printk(KERN_INFO fmt,##args)
-
-#endif
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c
deleted file mode 100644
index 17188e23477..00000000000
--- a/drivers/media/video/cpia2/cpia2_core.c
+++ /dev/null
@@ -1,2413 +0,0 @@
-/****************************************************************************
- *
- * Filename: cpia2_core.c
- *
- * Copyright 2001, STMicrolectronics, Inc.
- * Contact: steve.miller@st.com
- *
- * Description:
- * This is a USB driver for CPia2 based video cameras.
- * The infrastructure of this driver is based on the cpia usb driver by
- * Jochen Scharrlach and Johannes Erdfeldt.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Stripped of 2.4 stuff ready for main kernel submit by
- * Alan Cox <alan@lxorguk.ukuu.org.uk>
- *
- ****************************************************************************/
-
-#include "cpia2.h"
-
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/firmware.h>
-
-/* #define _CPIA2_DEBUG_ */
-
-#ifdef _CPIA2_DEBUG_
-
-static const char *block_name[] = {
- "System",
- "VC",
- "VP",
- "IDATA"
-};
-#endif
-
-static unsigned int debugs_on; /* default 0 - DEBUG_REG */
-
-
-/******************************************************************************
- *
- * Forward Declarations
- *
- *****************************************************************************/
-static int apply_vp_patch(struct camera_data *cam);
-static int set_default_user_mode(struct camera_data *cam);
-static int set_vw_size(struct camera_data *cam, int size);
-static int configure_sensor(struct camera_data *cam,
- int reqwidth, int reqheight);
-static int config_sensor_410(struct camera_data *cam,
- int reqwidth, int reqheight);
-static int config_sensor_500(struct camera_data *cam,
- int reqwidth, int reqheight);
-static int set_all_properties(struct camera_data *cam);
-static void wake_system(struct camera_data *cam);
-static void set_lowlight_boost(struct camera_data *cam);
-static void reset_camera_struct(struct camera_data *cam);
-static int cpia2_set_high_power(struct camera_data *cam);
-
-/* Here we want the physical address of the memory.
- * This is used when initializing the contents of the
- * area and marking the pages as reserved.
- */
-static inline unsigned long kvirt_to_pa(unsigned long adr)
-{
- unsigned long kva, ret;
-
- kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
- kva |= adr & (PAGE_SIZE-1); /* restore the offset */
- ret = __pa(kva);
- return ret;
-}
-
-static void *rvmalloc(unsigned long size)
-{
- void *mem;
- unsigned long adr;
-
- /* Round it off to PAGE_SIZE */
- size = PAGE_ALIGN(size);
-
- mem = vmalloc_32(size);
- if (!mem)
- return NULL;
-
- memset(mem, 0, size); /* Clear the ram out, no junk to the user */
- adr = (unsigned long) mem;
-
- while ((long)size > 0) {
- SetPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- return mem;
-}
-
-static void rvfree(void *mem, unsigned long size)
-{
- unsigned long adr;
-
- if (!mem)
- return;
-
- size = PAGE_ALIGN(size);
-
- adr = (unsigned long) mem;
- while ((long)size > 0) {
- ClearPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- vfree(mem);
-}
-
-/******************************************************************************
- *
- * cpia2_do_command
- *
- * Send an arbitrary command to the camera. For commands that read from
- * the camera, copy the buffers into the proper param structures.
- *****************************************************************************/
-int cpia2_do_command(struct camera_data *cam,
- u32 command, u8 direction, u8 param)
-{
- int retval = 0;
- struct cpia2_command cmd;
- unsigned int device = cam->params.pnp_id.device_type;
-
- cmd.command = command;
- cmd.reg_count = 2; /* default */
- cmd.direction = direction;
-
- /***
- * Set up the command.
- ***/
- switch (command) {
- case CPIA2_CMD_GET_VERSION:
- cmd.req_mode =
- CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
- cmd.start = CPIA2_SYSTEM_DEVICE_HI;
- break;
- case CPIA2_CMD_GET_PNP_ID:
- cmd.req_mode =
- CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
- cmd.reg_count = 8;
- cmd.start = CPIA2_SYSTEM_DESCRIP_VID_HI;
- break;
- case CPIA2_CMD_GET_ASIC_TYPE:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
- cmd.start = CPIA2_VC_ASIC_ID;
- break;
- case CPIA2_CMD_GET_SENSOR:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.start = CPIA2_VP_SENSOR_FLAGS;
- break;
- case CPIA2_CMD_GET_VP_DEVICE:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.start = CPIA2_VP_DEVICEH;
- break;
- case CPIA2_CMD_SET_VP_BRIGHTNESS:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_VP_BRIGHTNESS:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- if (device == DEVICE_STV_672)
- cmd.start = CPIA2_VP4_EXPOSURE_TARGET;
- else
- cmd.start = CPIA2_VP5_EXPOSURE_TARGET;
- break;
- case CPIA2_CMD_SET_CONTRAST:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_CONTRAST:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- cmd.start = CPIA2_VP_YRANGE;
- break;
- case CPIA2_CMD_SET_VP_SATURATION:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_VP_SATURATION:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- if (device == DEVICE_STV_672)
- cmd.start = CPIA2_VP_SATURATION;
- else
- cmd.start = CPIA2_VP5_MCUVSATURATION;
- break;
- case CPIA2_CMD_SET_VP_GPIO_DATA:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_VP_GPIO_DATA:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- cmd.start = CPIA2_VP_GPIO_DATA;
- break;
- case CPIA2_CMD_SET_VP_GPIO_DIRECTION:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_VP_GPIO_DIRECTION:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- cmd.start = CPIA2_VP_GPIO_DIRECTION;
- break;
- case CPIA2_CMD_SET_VC_MP_GPIO_DATA:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_VC_MP_GPIO_DATA:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
- cmd.reg_count = 1;
- cmd.start = CPIA2_VC_MP_DATA;
- break;
- case CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
- cmd.reg_count = 1;
- cmd.start = CPIA2_VC_MP_DIR;
- break;
- case CPIA2_CMD_ENABLE_PACKET_CTRL:
- cmd.req_mode =
- CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
- cmd.start = CPIA2_SYSTEM_INT_PACKET_CTRL;
- cmd.reg_count = 1;
- cmd.buffer.block_data[0] = param;
- break;
- case CPIA2_CMD_SET_FLICKER_MODES:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_FLICKER_MODES:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- cmd.start = CPIA2_VP_FLICKER_MODES;
- break;
- case CPIA2_CMD_RESET_FIFO: /* clear fifo and enable stream block */
- cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
- cmd.reg_count = 2;
- cmd.start = 0;
- cmd.buffer.registers[0].index = CPIA2_VC_ST_CTRL;
- cmd.buffer.registers[0].value = CPIA2_VC_ST_CTRL_SRC_VC |
- CPIA2_VC_ST_CTRL_DST_USB | CPIA2_VC_ST_CTRL_EOF_DETECT;
- cmd.buffer.registers[1].index = CPIA2_VC_ST_CTRL;
- cmd.buffer.registers[1].value = CPIA2_VC_ST_CTRL_SRC_VC |
- CPIA2_VC_ST_CTRL_DST_USB |
- CPIA2_VC_ST_CTRL_EOF_DETECT |
- CPIA2_VC_ST_CTRL_FIFO_ENABLE;
- break;
- case CPIA2_CMD_SET_HI_POWER:
- cmd.req_mode =
- CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_SYSTEM;
- cmd.reg_count = 2;
- cmd.buffer.registers[0].index =
- CPIA2_SYSTEM_SYSTEM_CONTROL;
- cmd.buffer.registers[1].index =
- CPIA2_SYSTEM_SYSTEM_CONTROL;
- cmd.buffer.registers[0].value = CPIA2_SYSTEM_CONTROL_CLEAR_ERR;
- cmd.buffer.registers[1].value =
- CPIA2_SYSTEM_CONTROL_HIGH_POWER;
- break;
- case CPIA2_CMD_SET_LOW_POWER:
- cmd.req_mode =
- CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
- cmd.reg_count = 1;
- cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL;
- cmd.buffer.block_data[0] = 0;
- break;
- case CPIA2_CMD_CLEAR_V2W_ERR:
- cmd.req_mode =
- CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
- cmd.reg_count = 1;
- cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL;
- cmd.buffer.block_data[0] = CPIA2_SYSTEM_CONTROL_CLEAR_ERR;
- break;
- case CPIA2_CMD_SET_USER_MODE: /* Then fall through */
- cmd.buffer.block_data[0] = param;
- case CPIA2_CMD_GET_USER_MODE:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- if (device == DEVICE_STV_672)
- cmd.start = CPIA2_VP4_USER_MODE;
- else
- cmd.start = CPIA2_VP5_USER_MODE;
- break;
- case CPIA2_CMD_FRAMERATE_REQ:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- if (device == DEVICE_STV_672)
- cmd.start = CPIA2_VP4_FRAMERATE_REQUEST;
- else
- cmd.start = CPIA2_VP5_FRAMERATE_REQUEST;
- cmd.buffer.block_data[0] = param;
- break;
- case CPIA2_CMD_SET_WAKEUP:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_WAKEUP:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
- cmd.reg_count = 1;
- cmd.start = CPIA2_VC_WAKEUP;
- break;
- case CPIA2_CMD_SET_PW_CONTROL:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_PW_CONTROL:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
- cmd.reg_count = 1;
- cmd.start = CPIA2_VC_PW_CTRL;
- break;
- case CPIA2_CMD_GET_VP_SYSTEM_STATE:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- cmd.start = CPIA2_VP_SYSTEMSTATE;
- break;
- case CPIA2_CMD_SET_SYSTEM_CTRL:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_SYSTEM_CTRL:
- cmd.req_mode =
- CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
- cmd.reg_count = 1;
- cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL;
- break;
- case CPIA2_CMD_SET_VP_SYSTEM_CTRL:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_VP_SYSTEM_CTRL:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- cmd.start = CPIA2_VP_SYSTEMCTRL;
- break;
- case CPIA2_CMD_SET_VP_EXP_MODES:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_VP_EXP_MODES:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- cmd.start = CPIA2_VP_EXPOSURE_MODES;
- break;
- case CPIA2_CMD_SET_DEVICE_CONFIG:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_DEVICE_CONFIG:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- cmd.start = CPIA2_VP_DEVICE_CONFIG;
- break;
- case CPIA2_CMD_SET_SERIAL_ADDR:
- cmd.buffer.block_data[0] = param;
- cmd.req_mode =
- CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
- cmd.reg_count = 1;
- cmd.start = CPIA2_SYSTEM_VP_SERIAL_ADDR;
- break;
- case CPIA2_CMD_SET_SENSOR_CR1:
- cmd.buffer.block_data[0] = param;
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- cmd.start = CPIA2_SENSOR_CR1;
- break;
- case CPIA2_CMD_SET_VC_CONTROL:
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_VC_CONTROL:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
- cmd.reg_count = 1;
- cmd.start = CPIA2_VC_VC_CTRL;
- break;
- case CPIA2_CMD_SET_TARGET_KB:
- cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
- cmd.reg_count = 1;
- cmd.buffer.registers[0].index = CPIA2_VC_VC_TARGET_KB;
- cmd.buffer.registers[0].value = param;
- break;
- case CPIA2_CMD_SET_DEF_JPEG_OPT:
- cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
- cmd.reg_count = 4;
- cmd.buffer.registers[0].index = CPIA2_VC_VC_JPEG_OPT;
- cmd.buffer.registers[0].value =
- CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE;
- cmd.buffer.registers[1].index = CPIA2_VC_VC_USER_SQUEEZE;
- cmd.buffer.registers[1].value = 20;
- cmd.buffer.registers[2].index = CPIA2_VC_VC_CREEP_PERIOD;
- cmd.buffer.registers[2].value = 2;
- cmd.buffer.registers[3].index = CPIA2_VC_VC_JPEG_OPT;
- cmd.buffer.registers[3].value = CPIA2_VC_VC_JPEG_OPT_DEFAULT;
- break;
- case CPIA2_CMD_REHASH_VP4:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- cmd.start = CPIA2_VP_REHASH_VALUES;
- cmd.buffer.block_data[0] = param;
- break;
- case CPIA2_CMD_SET_USER_EFFECTS: /* Note: Be careful with this as
- this register can also affect
- flicker modes */
- cmd.buffer.block_data[0] = param; /* Then fall through */
- case CPIA2_CMD_GET_USER_EFFECTS:
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 1;
- if (device == DEVICE_STV_672)
- cmd.start = CPIA2_VP4_USER_EFFECTS;
- else
- cmd.start = CPIA2_VP5_USER_EFFECTS;
- break;
- default:
- LOG("DoCommand received invalid command\n");
- return -EINVAL;
- }
-
- retval = cpia2_send_command(cam, &cmd);
- if (retval) {
- return retval;
- }
-
- /***
- * Now copy any results from a read into the appropriate param struct.
- ***/
- switch (command) {
- case CPIA2_CMD_GET_VERSION:
- cam->params.version.firmware_revision_hi =
- cmd.buffer.block_data[0];
- cam->params.version.firmware_revision_lo =
- cmd.buffer.block_data[1];
- break;
- case CPIA2_CMD_GET_PNP_ID:
- cam->params.pnp_id.vendor = (cmd.buffer.block_data[0] << 8) |
- cmd.buffer.block_data[1];
- cam->params.pnp_id.product = (cmd.buffer.block_data[2] << 8) |
- cmd.buffer.block_data[3];
- cam->params.pnp_id.device_revision =
- (cmd.buffer.block_data[4] << 8) |
- cmd.buffer.block_data[5];
- if (cam->params.pnp_id.vendor == 0x553) {
- if (cam->params.pnp_id.product == 0x100) {
- cam->params.pnp_id.device_type = DEVICE_STV_672;
- } else if (cam->params.pnp_id.product == 0x140 ||
- cam->params.pnp_id.product == 0x151) {
- cam->params.pnp_id.device_type = DEVICE_STV_676;
- }
- }
- break;
- case CPIA2_CMD_GET_ASIC_TYPE:
- cam->params.version.asic_id = cmd.buffer.block_data[0];
- cam->params.version.asic_rev = cmd.buffer.block_data[1];
- break;
- case CPIA2_CMD_GET_SENSOR:
- cam->params.version.sensor_flags = cmd.buffer.block_data[0];
- cam->params.version.sensor_rev = cmd.buffer.block_data[1];
- break;
- case CPIA2_CMD_GET_VP_DEVICE:
- cam->params.version.vp_device_hi = cmd.buffer.block_data[0];
- cam->params.version.vp_device_lo = cmd.buffer.block_data[1];
- break;
- case CPIA2_CMD_GET_VP_GPIO_DATA:
- cam->params.vp_params.gpio_data = cmd.buffer.block_data[0];
- break;
- case CPIA2_CMD_GET_VP_GPIO_DIRECTION:
- cam->params.vp_params.gpio_direction = cmd.buffer.block_data[0];
- break;
- case CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION:
- cam->params.vc_params.vc_mp_direction =cmd.buffer.block_data[0];
- break;
- case CPIA2_CMD_GET_VC_MP_GPIO_DATA:
- cam->params.vc_params.vc_mp_data = cmd.buffer.block_data[0];
- break;
- case CPIA2_CMD_GET_FLICKER_MODES:
- cam->params.flicker_control.cam_register =
- cmd.buffer.block_data[0];
- break;
- case CPIA2_CMD_GET_WAKEUP:
- cam->params.vc_params.wakeup = cmd.buffer.block_data[0];
- break;
- case CPIA2_CMD_GET_PW_CONTROL:
- cam->params.vc_params.pw_control = cmd.buffer.block_data[0];
- break;
- case CPIA2_CMD_GET_SYSTEM_CTRL:
- cam->params.camera_state.system_ctrl = cmd.buffer.block_data[0];
- break;
- case CPIA2_CMD_GET_VP_SYSTEM_STATE:
- cam->params.vp_params.system_state = cmd.buffer.block_data[0];
- break;
- case CPIA2_CMD_GET_VP_SYSTEM_CTRL:
- cam->params.vp_params.system_ctrl = cmd.buffer.block_data[0];
- break;
- case CPIA2_CMD_GET_VP_EXP_MODES:
- cam->params.vp_params.exposure_modes = cmd.buffer.block_data[0];
- break;
- case CPIA2_CMD_GET_DEVICE_CONFIG:
- cam->params.vp_params.device_config = cmd.buffer.block_data[0];
- break;
- case CPIA2_CMD_GET_VC_CONTROL:
- cam->params.vc_params.vc_control = cmd.buffer.block_data[0];
- break;
- case CPIA2_CMD_GET_USER_MODE:
- cam->params.vp_params.video_mode = cmd.buffer.block_data[0];
- break;
- case CPIA2_CMD_GET_USER_EFFECTS:
- cam->params.vp_params.user_effects = cmd.buffer.block_data[0];
- break;
- default:
- break;
- }
- return retval;
-}
-
-/******************************************************************************
- *
- * cpia2_send_command
- *
- *****************************************************************************/
-
-#define DIR(cmd) ((cmd->direction == TRANSFER_WRITE) ? "Write" : "Read")
-#define BINDEX(cmd) (cmd->req_mode & 0x03)
-
-int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd)
-{
- u8 count;
- u8 start;
- u8 *buffer;
- int retval;
-
- switch (cmd->req_mode & 0x0c) {
- case CAMERAACCESS_TYPE_RANDOM:
- count = cmd->reg_count * sizeof(struct cpia2_register);
- start = 0;
- buffer = (u8 *) & cmd->buffer;
- if (debugs_on & DEBUG_REG)
- DBG("%s Random: Register block %s\n", DIR(cmd),
- block_name[BINDEX(cmd)]);
- break;
- case CAMERAACCESS_TYPE_BLOCK:
- count = cmd->reg_count;
- start = cmd->start;
- buffer = cmd->buffer.block_data;
- if (debugs_on & DEBUG_REG)
- DBG("%s Block: Register block %s\n", DIR(cmd),
- block_name[BINDEX(cmd)]);
- break;
- case CAMERAACCESS_TYPE_MASK:
- count = cmd->reg_count * sizeof(struct cpia2_reg_mask);
- start = 0;
- buffer = (u8 *) & cmd->buffer;
- if (debugs_on & DEBUG_REG)
- DBG("%s Mask: Register block %s\n", DIR(cmd),
- block_name[BINDEX(cmd)]);
- break;
- case CAMERAACCESS_TYPE_REPEAT: /* For patch blocks only */
- count = cmd->reg_count;
- start = cmd->start;
- buffer = cmd->buffer.block_data;
- if (debugs_on & DEBUG_REG)
- DBG("%s Repeat: Register block %s\n", DIR(cmd),
- block_name[BINDEX(cmd)]);
- break;
- default:
- LOG("%s: invalid request mode\n",__func__);
- return -EINVAL;
- }
-
- retval = cpia2_usb_transfer_cmd(cam,
- buffer,
- cmd->req_mode,
- start, count, cmd->direction);
-#ifdef _CPIA2_DEBUG_
- if (debugs_on & DEBUG_REG) {
- int i;
- for (i = 0; i < cmd->reg_count; i++) {
- if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_BLOCK)
- KINFO("%s Block: [0x%02X] = 0x%02X\n",
- DIR(cmd), start + i, buffer[i]);
- if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_RANDOM)
- KINFO("%s Random: [0x%02X] = 0x%02X\n",
- DIR(cmd), cmd->buffer.registers[i].index,
- cmd->buffer.registers[i].value);
- }
- }
-#endif
-
- return retval;
-};
-
-/*************
- * Functions to implement camera functionality
- *************/
-/******************************************************************************
- *
- * cpia2_get_version_info
- *
- *****************************************************************************/
-static void cpia2_get_version_info(struct camera_data *cam)
-{
- cpia2_do_command(cam, CPIA2_CMD_GET_VERSION, TRANSFER_READ, 0);
- cpia2_do_command(cam, CPIA2_CMD_GET_PNP_ID, TRANSFER_READ, 0);
- cpia2_do_command(cam, CPIA2_CMD_GET_ASIC_TYPE, TRANSFER_READ, 0);
- cpia2_do_command(cam, CPIA2_CMD_GET_SENSOR, TRANSFER_READ, 0);
- cpia2_do_command(cam, CPIA2_CMD_GET_VP_DEVICE, TRANSFER_READ, 0);
-}
-
-/******************************************************************************
- *
- * cpia2_reset_camera
- *
- * Called at least during the open process, sets up initial params.
- *****************************************************************************/
-int cpia2_reset_camera(struct camera_data *cam)
-{
- u8 tmp_reg;
- int retval = 0;
- int target_kb;
- int i;
- struct cpia2_command cmd;
-
- /***
- * VC setup
- ***/
- retval = configure_sensor(cam,
- cam->params.roi.width,
- cam->params.roi.height);
- if (retval < 0) {
- ERR("Couldn't configure sensor, error=%d\n", retval);
- return retval;
- }
-
- /* Clear FIFO and route/enable stream block */
- cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
- cmd.direction = TRANSFER_WRITE;
- cmd.reg_count = 2;
- cmd.buffer.registers[0].index = CPIA2_VC_ST_CTRL;
- cmd.buffer.registers[0].value = CPIA2_VC_ST_CTRL_SRC_VC |
- CPIA2_VC_ST_CTRL_DST_USB | CPIA2_VC_ST_CTRL_EOF_DETECT;
- cmd.buffer.registers[1].index = CPIA2_VC_ST_CTRL;
- cmd.buffer.registers[1].value = CPIA2_VC_ST_CTRL_SRC_VC |
- CPIA2_VC_ST_CTRL_DST_USB |
- CPIA2_VC_ST_CTRL_EOF_DETECT | CPIA2_VC_ST_CTRL_FIFO_ENABLE;
-
- cpia2_send_command(cam, &cmd);
-
- cpia2_set_high_power(cam);
-
- if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
- /* Enable button notification */
- cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_SYSTEM;
- cmd.buffer.registers[0].index = CPIA2_SYSTEM_INT_PACKET_CTRL;
- cmd.buffer.registers[0].value =
- CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_SW_XX;
- cmd.reg_count = 1;
- cpia2_send_command(cam, &cmd);
- }
-
- schedule_timeout_interruptible(msecs_to_jiffies(100));
-
- if (cam->params.pnp_id.device_type == DEVICE_STV_672)
- retval = apply_vp_patch(cam);
-
- /* wait for vp to go to sleep */
- schedule_timeout_interruptible(msecs_to_jiffies(100));
-
- /***
- * If this is a 676, apply VP5 fixes before we start streaming
- ***/
- if (cam->params.pnp_id.device_type == DEVICE_STV_676) {
- cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP;
-
- /* The following writes improve the picture */
- cmd.buffer.registers[0].index = CPIA2_VP5_MYBLACK_LEVEL;
- cmd.buffer.registers[0].value = 0; /* reduce from the default
- * rec 601 pedestal of 16 */
- cmd.buffer.registers[1].index = CPIA2_VP5_MCYRANGE;
- cmd.buffer.registers[1].value = 0x92; /* increase from 100% to
- * (256/256 - 31) to fill
- * available range */
- cmd.buffer.registers[2].index = CPIA2_VP5_MYCEILING;
- cmd.buffer.registers[2].value = 0xFF; /* Increase from the
- * default rec 601 ceiling
- * of 240 */
- cmd.buffer.registers[3].index = CPIA2_VP5_MCUVSATURATION;
- cmd.buffer.registers[3].value = 0xFF; /* Increase from the rec
- * 601 100% level (128)
- * to 145-192 */
- cmd.buffer.registers[4].index = CPIA2_VP5_ANTIFLKRSETUP;
- cmd.buffer.registers[4].value = 0x80; /* Inhibit the
- * anti-flicker */
-
- /* The following 4 writes are a fix to allow QVGA to work at 30 fps */
- cmd.buffer.registers[5].index = CPIA2_VP_RAM_ADDR_H;
- cmd.buffer.registers[5].value = 0x01;
- cmd.buffer.registers[6].index = CPIA2_VP_RAM_ADDR_L;
- cmd.buffer.registers[6].value = 0xE3;
- cmd.buffer.registers[7].index = CPIA2_VP_RAM_DATA;
- cmd.buffer.registers[7].value = 0x02;
- cmd.buffer.registers[8].index = CPIA2_VP_RAM_DATA;
- cmd.buffer.registers[8].value = 0xFC;
-
- cmd.direction = TRANSFER_WRITE;
- cmd.reg_count = 9;
-
- cpia2_send_command(cam, &cmd);
- }
-
- /* Activate all settings and start the data stream */
- /* Set user mode */
- set_default_user_mode(cam);
-
- /* Give VP time to wake up */
- schedule_timeout_interruptible(msecs_to_jiffies(100));
-
- set_all_properties(cam);
-
- cpia2_do_command(cam, CPIA2_CMD_GET_USER_MODE, TRANSFER_READ, 0);
- DBG("After SetAllProperties(cam), user mode is 0x%0X\n",
- cam->params.vp_params.video_mode);
-
- /***
- * Set audio regulator off. This and the code to set the compresison
- * state are too complex to form a CPIA2_CMD_, and seem to be somewhat
- * intertwined. This stuff came straight from the windows driver.
- ***/
- /* Turn AutoExposure off in VP and enable the serial bridge to the sensor */
- cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_CTRL, TRANSFER_READ, 0);
- tmp_reg = cam->params.vp_params.system_ctrl;
- cmd.buffer.registers[0].value = tmp_reg &
- (tmp_reg & (CPIA2_VP_SYSTEMCTRL_HK_CONTROL ^ 0xFF));
-
- cpia2_do_command(cam, CPIA2_CMD_GET_DEVICE_CONFIG, TRANSFER_READ, 0);
- cmd.buffer.registers[1].value = cam->params.vp_params.device_config |
- CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE;
- cmd.buffer.registers[0].index = CPIA2_VP_SYSTEMCTRL;
- cmd.buffer.registers[1].index = CPIA2_VP_DEVICE_CONFIG;
- cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP;
- cmd.reg_count = 2;
- cmd.direction = TRANSFER_WRITE;
- cmd.start = 0;
- cpia2_send_command(cam, &cmd);
-
- /* Set the correct I2C address in the CPiA-2 system register */
- cpia2_do_command(cam,
- CPIA2_CMD_SET_SERIAL_ADDR,
- TRANSFER_WRITE,
- CPIA2_SYSTEM_VP_SERIAL_ADDR_SENSOR);
-
- /* Now have sensor access - set bit to turn the audio regulator off */
- cpia2_do_command(cam,
- CPIA2_CMD_SET_SENSOR_CR1,
- TRANSFER_WRITE, CPIA2_SENSOR_CR1_DOWN_AUDIO_REGULATOR);
-
- /* Set the correct I2C address in the CPiA-2 system register */
- if (cam->params.pnp_id.device_type == DEVICE_STV_672)
- cpia2_do_command(cam,
- CPIA2_CMD_SET_SERIAL_ADDR,
- TRANSFER_WRITE,
- CPIA2_SYSTEM_VP_SERIAL_ADDR_VP); // 0x88
- else
- cpia2_do_command(cam,
- CPIA2_CMD_SET_SERIAL_ADDR,
- TRANSFER_WRITE,
- CPIA2_SYSTEM_VP_SERIAL_ADDR_676_VP); // 0x8a
-
- /* increase signal drive strength */
- if (cam->params.pnp_id.device_type == DEVICE_STV_676)
- cpia2_do_command(cam,
- CPIA2_CMD_SET_VP_EXP_MODES,
- TRANSFER_WRITE,
- CPIA2_VP_EXPOSURE_MODES_COMPILE_EXP);
-
- /* Start autoexposure */
- cpia2_do_command(cam, CPIA2_CMD_GET_DEVICE_CONFIG, TRANSFER_READ, 0);
- cmd.buffer.registers[0].value = cam->params.vp_params.device_config &
- (CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE ^ 0xFF);
-
- cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_CTRL, TRANSFER_READ, 0);
- cmd.buffer.registers[1].value =
- cam->params.vp_params.system_ctrl | CPIA2_VP_SYSTEMCTRL_HK_CONTROL;
-
- cmd.buffer.registers[0].index = CPIA2_VP_DEVICE_CONFIG;
- cmd.buffer.registers[1].index = CPIA2_VP_SYSTEMCTRL;
- cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP;
- cmd.reg_count = 2;
- cmd.direction = TRANSFER_WRITE;
-
- cpia2_send_command(cam, &cmd);
-
- /* Set compression state */
- cpia2_do_command(cam, CPIA2_CMD_GET_VC_CONTROL, TRANSFER_READ, 0);
- if (cam->params.compression.inhibit_htables) {
- tmp_reg = cam->params.vc_params.vc_control |
- CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES;
- } else {
- tmp_reg = cam->params.vc_params.vc_control &
- ~CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES;
- }
- cpia2_do_command(cam, CPIA2_CMD_SET_VC_CONTROL, TRANSFER_WRITE,tmp_reg);
-
- /* Set target size (kb) on vc
- This is a heuristic based on the quality parameter and the raw
- framesize in kB divided by 16 (the compression factor when the
- quality is 100%) */
- target_kb = (cam->width * cam->height * 2 / 16384) *
- cam->params.vc_params.quality / 100;
- if (target_kb < 1)
- target_kb = 1;
- cpia2_do_command(cam, CPIA2_CMD_SET_TARGET_KB,
- TRANSFER_WRITE, target_kb);
-
- /* Wiggle VC Reset */
- /***
- * First read and wait a bit.
- ***/
- for (i = 0; i < 50; i++) {
- cpia2_do_command(cam, CPIA2_CMD_GET_PW_CONTROL,
- TRANSFER_READ, 0);
- }
-
- tmp_reg = cam->params.vc_params.pw_control;
- tmp_reg &= ~CPIA2_VC_PW_CTRL_VC_RESET_N;
-
- cpia2_do_command(cam, CPIA2_CMD_SET_PW_CONTROL, TRANSFER_WRITE,tmp_reg);
-
- tmp_reg |= CPIA2_VC_PW_CTRL_VC_RESET_N;
- cpia2_do_command(cam, CPIA2_CMD_SET_PW_CONTROL, TRANSFER_WRITE,tmp_reg);
-
- cpia2_do_command(cam, CPIA2_CMD_SET_DEF_JPEG_OPT, TRANSFER_WRITE, 0);
-
- cpia2_do_command(cam, CPIA2_CMD_GET_USER_MODE, TRANSFER_READ, 0);
- DBG("After VC RESET, user mode is 0x%0X\n",
- cam->params.vp_params.video_mode);
-
- return retval;
-}
-
-/******************************************************************************
- *
- * cpia2_set_high_power
- *
- *****************************************************************************/
-static int cpia2_set_high_power(struct camera_data *cam)
-{
- int i;
- for (i = 0; i <= 50; i++) {
- /* Read system status */
- cpia2_do_command(cam,CPIA2_CMD_GET_SYSTEM_CTRL,TRANSFER_READ,0);
-
- /* If there is an error, clear it */
- if(cam->params.camera_state.system_ctrl &
- CPIA2_SYSTEM_CONTROL_V2W_ERR)
- cpia2_do_command(cam, CPIA2_CMD_CLEAR_V2W_ERR,
- TRANSFER_WRITE, 0);
-
- /* Try to set high power mode */
- cpia2_do_command(cam, CPIA2_CMD_SET_SYSTEM_CTRL,
- TRANSFER_WRITE, 1);
-
- /* Try to read something in VP to check if everything is awake */
- cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_STATE,
- TRANSFER_READ, 0);
- if (cam->params.vp_params.system_state &
- CPIA2_VP_SYSTEMSTATE_HK_ALIVE) {
- break;
- } else if (i == 50) {
- cam->params.camera_state.power_mode = LO_POWER_MODE;
- ERR("Camera did not wake up\n");
- return -EIO;
- }
- }
-
- DBG("System now in high power state\n");
- cam->params.camera_state.power_mode = HI_POWER_MODE;
- return 0;
-}
-
-/******************************************************************************
- *
- * cpia2_set_low_power
- *
- *****************************************************************************/
-int cpia2_set_low_power(struct camera_data *cam)
-{
- cam->params.camera_state.power_mode = LO_POWER_MODE;
- cpia2_do_command(cam, CPIA2_CMD_SET_SYSTEM_CTRL, TRANSFER_WRITE, 0);
- return 0;
-}
-
-/******************************************************************************
- *
- * apply_vp_patch
- *
- *****************************************************************************/
-static int cpia2_send_onebyte_command(struct camera_data *cam,
- struct cpia2_command *cmd,
- u8 start, u8 datum)
-{
- cmd->buffer.block_data[0] = datum;
- cmd->start = start;
- cmd->reg_count = 1;
- return cpia2_send_command(cam, cmd);
-}
-
-static int apply_vp_patch(struct camera_data *cam)
-{
- const struct firmware *fw;
- const char fw_name[] = "cpia2/stv0672_vp4.bin";
- int i, ret;
- struct cpia2_command cmd;
-
- ret = request_firmware(&fw, fw_name, &cam->dev->dev);
- if (ret) {
- printk(KERN_ERR "cpia2: failed to load VP patch \"%s\"\n",
- fw_name);
- return ret;
- }
-
- cmd.req_mode = CAMERAACCESS_TYPE_REPEAT | CAMERAACCESS_VP;
- cmd.direction = TRANSFER_WRITE;
-
- /* First send the start address... */
- cpia2_send_onebyte_command(cam, &cmd, 0x0A, fw->data[0]); /* hi */
- cpia2_send_onebyte_command(cam, &cmd, 0x0B, fw->data[1]); /* lo */
-
- /* ... followed by the data payload */
- for (i = 2; i < fw->size; i += 64) {
- cmd.start = 0x0C; /* Data */
- cmd.reg_count = min_t(int, 64, fw->size - i);
- memcpy(cmd.buffer.block_data, &fw->data[i], cmd.reg_count);
- cpia2_send_command(cam, &cmd);
- }
-
- /* Next send the start address... */
- cpia2_send_onebyte_command(cam, &cmd, 0x0A, fw->data[0]); /* hi */
- cpia2_send_onebyte_command(cam, &cmd, 0x0B, fw->data[1]); /* lo */
-
- /* ... followed by the 'goto' command */
- cpia2_send_onebyte_command(cam, &cmd, 0x0D, 1);
-
- release_firmware(fw);
- return 0;
-}
-
-/******************************************************************************
- *
- * set_default_user_mode
- *
- *****************************************************************************/
-static int set_default_user_mode(struct camera_data *cam)
-{
- unsigned char user_mode;
- unsigned char frame_rate;
- int width = cam->params.roi.width;
- int height = cam->params.roi.height;
-
- switch (cam->params.version.sensor_flags) {
- case CPIA2_VP_SENSOR_FLAGS_404:
- case CPIA2_VP_SENSOR_FLAGS_407:
- case CPIA2_VP_SENSOR_FLAGS_409:
- case CPIA2_VP_SENSOR_FLAGS_410:
- if ((width > STV_IMAGE_QCIF_COLS)
- || (height > STV_IMAGE_QCIF_ROWS)) {
- user_mode = CPIA2_VP_USER_MODE_CIF;
- } else {
- user_mode = CPIA2_VP_USER_MODE_QCIFDS;
- }
- frame_rate = CPIA2_VP_FRAMERATE_30;
- break;
- case CPIA2_VP_SENSOR_FLAGS_500:
- if ((width > STV_IMAGE_CIF_COLS)
- || (height > STV_IMAGE_CIF_ROWS)) {
- user_mode = CPIA2_VP_USER_MODE_VGA;
- } else {
- user_mode = CPIA2_VP_USER_MODE_QVGADS;
- }
- if (cam->params.pnp_id.device_type == DEVICE_STV_672)
- frame_rate = CPIA2_VP_FRAMERATE_15;
- else
- frame_rate = CPIA2_VP_FRAMERATE_30;
- break;
- default:
- LOG("%s: Invalid sensor flag value 0x%0X\n",__func__,
- cam->params.version.sensor_flags);
- return -EINVAL;
- }
-
- DBG("Sensor flag = 0x%0x, user mode = 0x%0x, frame rate = 0x%X\n",
- cam->params.version.sensor_flags, user_mode, frame_rate);
- cpia2_do_command(cam, CPIA2_CMD_SET_USER_MODE, TRANSFER_WRITE,
- user_mode);
- if(cam->params.vp_params.frame_rate > 0 &&
- frame_rate > cam->params.vp_params.frame_rate)
- frame_rate = cam->params.vp_params.frame_rate;
-
- cpia2_set_fps(cam, frame_rate);
-
-// if (cam->params.pnp_id.device_type == DEVICE_STV_676)
-// cpia2_do_command(cam,
-// CPIA2_CMD_SET_VP_SYSTEM_CTRL,
-// TRANSFER_WRITE,
-// CPIA2_VP_SYSTEMCTRL_HK_CONTROL |
-// CPIA2_VP_SYSTEMCTRL_POWER_CONTROL);
-
- return 0;
-}
-
-/******************************************************************************
- *
- * cpia2_match_video_size
- *
- * return the best match, where 'best' is as always
- * the largest that is not bigger than what is requested.
- *****************************************************************************/
-int cpia2_match_video_size(int width, int height)
-{
- if (width >= STV_IMAGE_VGA_COLS && height >= STV_IMAGE_VGA_ROWS)
- return VIDEOSIZE_VGA;
-
- if (width >= STV_IMAGE_CIF_COLS && height >= STV_IMAGE_CIF_ROWS)
- return VIDEOSIZE_CIF;
-
- if (width >= STV_IMAGE_QVGA_COLS && height >= STV_IMAGE_QVGA_ROWS)
- return VIDEOSIZE_QVGA;
-
- if (width >= 288 && height >= 216)
- return VIDEOSIZE_288_216;
-
- if (width >= 256 && height >= 192)
- return VIDEOSIZE_256_192;
-
- if (width >= 224 && height >= 168)
- return VIDEOSIZE_224_168;
-
- if (width >= 192 && height >= 144)
- return VIDEOSIZE_192_144;
-
- if (width >= STV_IMAGE_QCIF_COLS && height >= STV_IMAGE_QCIF_ROWS)
- return VIDEOSIZE_QCIF;
-
- return -1;
-}
-
-/******************************************************************************
- *
- * SetVideoSize
- *
- *****************************************************************************/
-static int set_vw_size(struct camera_data *cam, int size)
-{
- int retval = 0;
-
- cam->params.vp_params.video_size = size;
-
- switch (size) {
- case VIDEOSIZE_VGA:
- DBG("Setting size to VGA\n");
- cam->params.roi.width = STV_IMAGE_VGA_COLS;
- cam->params.roi.height = STV_IMAGE_VGA_ROWS;
- cam->width = STV_IMAGE_VGA_COLS;
- cam->height = STV_IMAGE_VGA_ROWS;
- break;
- case VIDEOSIZE_CIF:
- DBG("Setting size to CIF\n");
- cam->params.roi.width = STV_IMAGE_CIF_COLS;
- cam->params.roi.height = STV_IMAGE_CIF_ROWS;
- cam->width = STV_IMAGE_CIF_COLS;
- cam->height = STV_IMAGE_CIF_ROWS;
- break;
- case VIDEOSIZE_QVGA:
- DBG("Setting size to QVGA\n");
- cam->params.roi.width = STV_IMAGE_QVGA_COLS;
- cam->params.roi.height = STV_IMAGE_QVGA_ROWS;
- cam->width = STV_IMAGE_QVGA_COLS;
- cam->height = STV_IMAGE_QVGA_ROWS;
- break;
- case VIDEOSIZE_288_216:
- cam->params.roi.width = 288;
- cam->params.roi.height = 216;
- cam->width = 288;
- cam->height = 216;
- break;
- case VIDEOSIZE_256_192:
- cam->width = 256;
- cam->height = 192;
- cam->params.roi.width = 256;
- cam->params.roi.height = 192;
- break;
- case VIDEOSIZE_224_168:
- cam->width = 224;
- cam->height = 168;
- cam->params.roi.width = 224;
- cam->params.roi.height = 168;
- break;
- case VIDEOSIZE_192_144:
- cam->width = 192;
- cam->height = 144;
- cam->params.roi.width = 192;
- cam->params.roi.height = 144;
- break;
- case VIDEOSIZE_QCIF:
- DBG("Setting size to QCIF\n");
- cam->params.roi.width = STV_IMAGE_QCIF_COLS;
- cam->params.roi.height = STV_IMAGE_QCIF_ROWS;
- cam->width = STV_IMAGE_QCIF_COLS;
- cam->height = STV_IMAGE_QCIF_ROWS;
- break;
- default:
- retval = -EINVAL;
- }
- return retval;
-}
-
-/******************************************************************************
- *
- * configure_sensor
- *
- *****************************************************************************/
-static int configure_sensor(struct camera_data *cam,
- int req_width, int req_height)
-{
- int retval;
-
- switch (cam->params.version.sensor_flags) {
- case CPIA2_VP_SENSOR_FLAGS_404:
- case CPIA2_VP_SENSOR_FLAGS_407:
- case CPIA2_VP_SENSOR_FLAGS_409:
- case CPIA2_VP_SENSOR_FLAGS_410:
- retval = config_sensor_410(cam, req_width, req_height);
- break;
- case CPIA2_VP_SENSOR_FLAGS_500:
- retval = config_sensor_500(cam, req_width, req_height);
- break;
- default:
- return -EINVAL;
- }
-
- return retval;
-}
-
-/******************************************************************************
- *
- * config_sensor_410
- *
- *****************************************************************************/
-static int config_sensor_410(struct camera_data *cam,
- int req_width, int req_height)
-{
- struct cpia2_command cmd;
- int i = 0;
- int image_size;
- int image_type;
- int width = req_width;
- int height = req_height;
-
- /***
- * Make sure size doesn't exceed CIF.
- ***/
- if (width > STV_IMAGE_CIF_COLS)
- width = STV_IMAGE_CIF_COLS;
- if (height > STV_IMAGE_CIF_ROWS)
- height = STV_IMAGE_CIF_ROWS;
-
- image_size = cpia2_match_video_size(width, height);
-
- DBG("Config 410: width = %d, height = %d\n", width, height);
- DBG("Image size returned is %d\n", image_size);
- if (image_size >= 0) {
- set_vw_size(cam, image_size);
- width = cam->params.roi.width;
- height = cam->params.roi.height;
-
- DBG("After set_vw_size(), width = %d, height = %d\n",
- width, height);
- if (width <= 176 && height <= 144) {
- DBG("image type = VIDEOSIZE_QCIF\n");
- image_type = VIDEOSIZE_QCIF;
- }
- else if (width <= 320 && height <= 240) {
- DBG("image type = VIDEOSIZE_QVGA\n");
- image_type = VIDEOSIZE_QVGA;
- }
- else {
- DBG("image type = VIDEOSIZE_CIF\n");
- image_type = VIDEOSIZE_CIF;
- }
- } else {
- ERR("ConfigSensor410 failed\n");
- return -EINVAL;
- }
-
- cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
- cmd.direction = TRANSFER_WRITE;
-
- /* VC Format */
- cmd.buffer.registers[i].index = CPIA2_VC_VC_FORMAT;
- if (image_type == VIDEOSIZE_CIF) {
- cmd.buffer.registers[i++].value =
- (u8) (CPIA2_VC_VC_FORMAT_UFIRST |
- CPIA2_VC_VC_FORMAT_SHORTLINE);
- } else {
- cmd.buffer.registers[i++].value =
- (u8) CPIA2_VC_VC_FORMAT_UFIRST;
- }
-
- /* VC Clocks */
- cmd.buffer.registers[i].index = CPIA2_VC_VC_CLOCKS;
- if (image_type == VIDEOSIZE_QCIF) {
- if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
- cmd.buffer.registers[i++].value=
- (u8)(CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 |
- CPIA2_VC_VC_672_CLOCKS_SCALING |
- CPIA2_VC_VC_CLOCKS_LOGDIV2);
- DBG("VC_Clocks (0xc4) should be B\n");
- }
- else {
- cmd.buffer.registers[i++].value=
- (u8)(CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 |
- CPIA2_VC_VC_CLOCKS_LOGDIV2);
- }
- } else {
- if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
- cmd.buffer.registers[i++].value =
- (u8) (CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 |
- CPIA2_VC_VC_CLOCKS_LOGDIV0);
- }
- else {
- cmd.buffer.registers[i++].value =
- (u8) (CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 |
- CPIA2_VC_VC_676_CLOCKS_SCALING |
- CPIA2_VC_VC_CLOCKS_LOGDIV0);
- }
- }
- DBG("VC_Clocks (0xc4) = 0x%0X\n", cmd.buffer.registers[i-1].value);
-
- /* Input reqWidth from VC */
- cmd.buffer.registers[i].index = CPIA2_VC_VC_IHSIZE_LO;
- if (image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value =
- (u8) (STV_IMAGE_QCIF_COLS / 4);
- else
- cmd.buffer.registers[i++].value =
- (u8) (STV_IMAGE_CIF_COLS / 4);
-
- /* Timings */
- cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_HI;
- if (image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value = (u8) 0;
- else
- cmd.buffer.registers[i++].value = (u8) 1;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_LO;
- if (image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value = (u8) 208;
- else
- cmd.buffer.registers[i++].value = (u8) 160;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_HI;
- if (image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value = (u8) 0;
- else
- cmd.buffer.registers[i++].value = (u8) 1;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_LO;
- if (image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value = (u8) 160;
- else
- cmd.buffer.registers[i++].value = (u8) 64;
-
- /* Output Image Size */
- cmd.buffer.registers[i].index = CPIA2_VC_VC_OHSIZE;
- cmd.buffer.registers[i++].value = cam->params.roi.width / 4;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_OVSIZE;
- cmd.buffer.registers[i++].value = cam->params.roi.height / 4;
-
- /* Cropping */
- cmd.buffer.registers[i].index = CPIA2_VC_VC_HCROP;
- if (image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value =
- (u8) (((STV_IMAGE_QCIF_COLS / 4) - (width / 4)) / 2);
- else
- cmd.buffer.registers[i++].value =
- (u8) (((STV_IMAGE_CIF_COLS / 4) - (width / 4)) / 2);
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_VCROP;
- if (image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value =
- (u8) (((STV_IMAGE_QCIF_ROWS / 4) - (height / 4)) / 2);
- else
- cmd.buffer.registers[i++].value =
- (u8) (((STV_IMAGE_CIF_ROWS / 4) - (height / 4)) / 2);
-
- /* Scaling registers (defaults) */
- cmd.buffer.registers[i].index = CPIA2_VC_VC_HPHASE;
- cmd.buffer.registers[i++].value = (u8) 0;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_VPHASE;
- cmd.buffer.registers[i++].value = (u8) 0;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_HISPAN;
- cmd.buffer.registers[i++].value = (u8) 31;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_VISPAN;
- cmd.buffer.registers[i++].value = (u8) 31;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_HICROP;
- cmd.buffer.registers[i++].value = (u8) 0;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_VICROP;
- cmd.buffer.registers[i++].value = (u8) 0;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_HFRACT;
- cmd.buffer.registers[i++].value = (u8) 0x81; /* = 8/1 = 8 (HIBYTE/LOBYTE) */
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_VFRACT;
- cmd.buffer.registers[i++].value = (u8) 0x81; /* = 8/1 = 8 (HIBYTE/LOBYTE) */
-
- cmd.reg_count = i;
-
- cpia2_send_command(cam, &cmd);
-
- return i;
-}
-
-
-/******************************************************************************
- *
- * config_sensor_500(cam)
- *
- *****************************************************************************/
-static int config_sensor_500(struct camera_data *cam,
- int req_width, int req_height)
-{
- struct cpia2_command cmd;
- int i = 0;
- int image_size = VIDEOSIZE_CIF;
- int image_type = VIDEOSIZE_VGA;
- int width = req_width;
- int height = req_height;
- unsigned int device = cam->params.pnp_id.device_type;
-
- image_size = cpia2_match_video_size(width, height);
-
- if (width > STV_IMAGE_CIF_COLS || height > STV_IMAGE_CIF_ROWS)
- image_type = VIDEOSIZE_VGA;
- else if (width > STV_IMAGE_QVGA_COLS || height > STV_IMAGE_QVGA_ROWS)
- image_type = VIDEOSIZE_CIF;
- else if (width > STV_IMAGE_QCIF_COLS || height > STV_IMAGE_QCIF_ROWS)
- image_type = VIDEOSIZE_QVGA;
- else
- image_type = VIDEOSIZE_QCIF;
-
- if (image_size >= 0) {
- set_vw_size(cam, image_size);
- width = cam->params.roi.width;
- height = cam->params.roi.height;
- } else {
- ERR("ConfigSensor500 failed\n");
- return -EINVAL;
- }
-
- DBG("image_size = %d, width = %d, height = %d, type = %d\n",
- image_size, width, height, image_type);
-
- cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
- cmd.direction = TRANSFER_WRITE;
- i = 0;
-
- /* VC Format */
- cmd.buffer.registers[i].index = CPIA2_VC_VC_FORMAT;
- cmd.buffer.registers[i].value = (u8) CPIA2_VC_VC_FORMAT_UFIRST;
- if (image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i].value |= (u8) CPIA2_VC_VC_FORMAT_DECIMATING;
- i++;
-
- /* VC Clocks */
- cmd.buffer.registers[i].index = CPIA2_VC_VC_CLOCKS;
- if (device == DEVICE_STV_672) {
- if (image_type == VIDEOSIZE_VGA)
- cmd.buffer.registers[i].value =
- (u8)CPIA2_VC_VC_CLOCKS_LOGDIV1;
- else
- cmd.buffer.registers[i].value =
- (u8)(CPIA2_VC_VC_672_CLOCKS_SCALING |
- CPIA2_VC_VC_CLOCKS_LOGDIV3);
- } else {
- if (image_type == VIDEOSIZE_VGA)
- cmd.buffer.registers[i].value =
- (u8)CPIA2_VC_VC_CLOCKS_LOGDIV0;
- else
- cmd.buffer.registers[i].value =
- (u8)(CPIA2_VC_VC_676_CLOCKS_SCALING |
- CPIA2_VC_VC_CLOCKS_LOGDIV2);
- }
- i++;
-
- DBG("VC_CLOCKS = 0x%X\n", cmd.buffer.registers[i-1].value);
-
- /* Input width from VP */
- cmd.buffer.registers[i].index = CPIA2_VC_VC_IHSIZE_LO;
- if (image_type == VIDEOSIZE_VGA)
- cmd.buffer.registers[i].value =
- (u8) (STV_IMAGE_VGA_COLS / 4);
- else
- cmd.buffer.registers[i].value =
- (u8) (STV_IMAGE_QVGA_COLS / 4);
- i++;
- DBG("Input width = %d\n", cmd.buffer.registers[i-1].value);
-
- /* Timings */
- cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_HI;
- if (image_type == VIDEOSIZE_VGA)
- cmd.buffer.registers[i++].value = (u8) 2;
- else
- cmd.buffer.registers[i++].value = (u8) 1;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_LO;
- if (image_type == VIDEOSIZE_VGA)
- cmd.buffer.registers[i++].value = (u8) 250;
- else if (image_type == VIDEOSIZE_QVGA)
- cmd.buffer.registers[i++].value = (u8) 125;
- else
- cmd.buffer.registers[i++].value = (u8) 160;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_HI;
- if (image_type == VIDEOSIZE_VGA)
- cmd.buffer.registers[i++].value = (u8) 2;
- else
- cmd.buffer.registers[i++].value = (u8) 1;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_LO;
- if (image_type == VIDEOSIZE_VGA)
- cmd.buffer.registers[i++].value = (u8) 12;
- else if (image_type == VIDEOSIZE_QVGA)
- cmd.buffer.registers[i++].value = (u8) 64;
- else
- cmd.buffer.registers[i++].value = (u8) 6;
-
- /* Output Image Size */
- cmd.buffer.registers[i].index = CPIA2_VC_VC_OHSIZE;
- if (image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value = STV_IMAGE_CIF_COLS / 4;
- else
- cmd.buffer.registers[i++].value = width / 4;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_OVSIZE;
- if (image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value = STV_IMAGE_CIF_ROWS / 4;
- else
- cmd.buffer.registers[i++].value = height / 4;
-
- /* Cropping */
- cmd.buffer.registers[i].index = CPIA2_VC_VC_HCROP;
- if (image_type == VIDEOSIZE_VGA)
- cmd.buffer.registers[i++].value =
- (u8) (((STV_IMAGE_VGA_COLS / 4) - (width / 4)) / 2);
- else if (image_type == VIDEOSIZE_QVGA)
- cmd.buffer.registers[i++].value =
- (u8) (((STV_IMAGE_QVGA_COLS / 4) - (width / 4)) / 2);
- else if (image_type == VIDEOSIZE_CIF)
- cmd.buffer.registers[i++].value =
- (u8) (((STV_IMAGE_CIF_COLS / 4) - (width / 4)) / 2);
- else /*if (image_type == VIDEOSIZE_QCIF)*/
- cmd.buffer.registers[i++].value =
- (u8) (((STV_IMAGE_QCIF_COLS / 4) - (width / 4)) / 2);
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_VCROP;
- if (image_type == VIDEOSIZE_VGA)
- cmd.buffer.registers[i++].value =
- (u8) (((STV_IMAGE_VGA_ROWS / 4) - (height / 4)) / 2);
- else if (image_type == VIDEOSIZE_QVGA)
- cmd.buffer.registers[i++].value =
- (u8) (((STV_IMAGE_QVGA_ROWS / 4) - (height / 4)) / 2);
- else if (image_type == VIDEOSIZE_CIF)
- cmd.buffer.registers[i++].value =
- (u8) (((STV_IMAGE_CIF_ROWS / 4) - (height / 4)) / 2);
- else /*if (image_type == VIDEOSIZE_QCIF)*/
- cmd.buffer.registers[i++].value =
- (u8) (((STV_IMAGE_QCIF_ROWS / 4) - (height / 4)) / 2);
-
- /* Scaling registers (defaults) */
- cmd.buffer.registers[i].index = CPIA2_VC_VC_HPHASE;
- if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value = (u8) 36;
- else
- cmd.buffer.registers[i++].value = (u8) 0;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_VPHASE;
- if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value = (u8) 32;
- else
- cmd.buffer.registers[i++].value = (u8) 0;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_HISPAN;
- if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value = (u8) 26;
- else
- cmd.buffer.registers[i++].value = (u8) 31;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_VISPAN;
- if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value = (u8) 21;
- else
- cmd.buffer.registers[i++].value = (u8) 31;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_HICROP;
- cmd.buffer.registers[i++].value = (u8) 0;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_VICROP;
- cmd.buffer.registers[i++].value = (u8) 0;
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_HFRACT;
- if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value = (u8) 0x2B; /* 2/11 */
- else
- cmd.buffer.registers[i++].value = (u8) 0x81; /* 8/1 */
-
- cmd.buffer.registers[i].index = CPIA2_VC_VC_VFRACT;
- if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
- cmd.buffer.registers[i++].value = (u8) 0x13; /* 1/3 */
- else
- cmd.buffer.registers[i++].value = (u8) 0x81; /* 8/1 */
-
- cmd.reg_count = i;
-
- cpia2_send_command(cam, &cmd);
-
- return i;
-}
-
-
-/******************************************************************************
- *
- * setallproperties
- *
- * This sets all user changeable properties to the values in cam->params.
- *****************************************************************************/
-static int set_all_properties(struct camera_data *cam)
-{
- /**
- * Don't set target_kb here, it will be set later.
- * framerate and user_mode were already set (set_default_user_mode).
- **/
-
- cpia2_usb_change_streaming_alternate(cam,
- cam->params.camera_state.stream_mode);
-
- cpia2_do_command(cam,
- CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
- TRANSFER_WRITE, cam->params.vp_params.gpio_direction);
- cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA, TRANSFER_WRITE,
- cam->params.vp_params.gpio_data);
-
- v4l2_ctrl_handler_setup(&cam->hdl);
-
- wake_system(cam);
-
- set_lowlight_boost(cam);
-
- return 0;
-}
-
-/******************************************************************************
- *
- * cpia2_save_camera_state
- *
- *****************************************************************************/
-void cpia2_save_camera_state(struct camera_data *cam)
-{
- cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0);
- cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION, TRANSFER_READ,
- 0);
- cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DATA, TRANSFER_READ, 0);
- /* Don't get framerate or target_kb. Trust the values we already have */
-}
-
-
-/******************************************************************************
- *
- * cpia2_set_flicker_mode
- *
- *****************************************************************************/
-int cpia2_set_flicker_mode(struct camera_data *cam, int mode)
-{
- unsigned char cam_reg;
- int err = 0;
-
- if(cam->params.pnp_id.device_type != DEVICE_STV_672)
- return -EINVAL;
-
- /* Set the appropriate bits in FLICKER_MODES, preserving the rest */
- if((err = cpia2_do_command(cam, CPIA2_CMD_GET_FLICKER_MODES,
- TRANSFER_READ, 0)))
- return err;
- cam_reg = cam->params.flicker_control.cam_register;
-
- switch(mode) {
- case NEVER_FLICKER:
- cam_reg |= CPIA2_VP_FLICKER_MODES_NEVER_FLICKER;
- cam_reg &= ~CPIA2_VP_FLICKER_MODES_50HZ;
- break;
- case FLICKER_60:
- cam_reg &= ~CPIA2_VP_FLICKER_MODES_NEVER_FLICKER;
- cam_reg &= ~CPIA2_VP_FLICKER_MODES_50HZ;
- break;
- case FLICKER_50:
- cam_reg &= ~CPIA2_VP_FLICKER_MODES_NEVER_FLICKER;
- cam_reg |= CPIA2_VP_FLICKER_MODES_50HZ;
- break;
- default:
- return -EINVAL;
- }
-
- if((err = cpia2_do_command(cam, CPIA2_CMD_SET_FLICKER_MODES,
- TRANSFER_WRITE, cam_reg)))
- return err;
-
- /* Set the appropriate bits in EXP_MODES, preserving the rest */
- if((err = cpia2_do_command(cam, CPIA2_CMD_GET_VP_EXP_MODES,
- TRANSFER_READ, 0)))
- return err;
- cam_reg = cam->params.vp_params.exposure_modes;
-
- if (mode == NEVER_FLICKER) {
- cam_reg |= CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER;
- } else {
- cam_reg &= ~CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER;
- }
-
- if((err = cpia2_do_command(cam, CPIA2_CMD_SET_VP_EXP_MODES,
- TRANSFER_WRITE, cam_reg)))
- return err;
-
- if((err = cpia2_do_command(cam, CPIA2_CMD_REHASH_VP4,
- TRANSFER_WRITE, 1)))
- return err;
-
- switch(mode) {
- case NEVER_FLICKER:
- case FLICKER_60:
- case FLICKER_50:
- cam->params.flicker_control.flicker_mode_req = mode;
- break;
- default:
- err = -EINVAL;
- }
-
- return err;
-}
-
-/******************************************************************************
- *
- * cpia2_set_property_flip
- *
- *****************************************************************************/
-void cpia2_set_property_flip(struct camera_data *cam, int prop_val)
-{
- unsigned char cam_reg;
-
- cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0);
- cam_reg = cam->params.vp_params.user_effects;
-
- if (prop_val)
- {
- cam_reg |= CPIA2_VP_USER_EFFECTS_FLIP;
- }
- else
- {
- cam_reg &= ~CPIA2_VP_USER_EFFECTS_FLIP;
- }
- cam->params.vp_params.user_effects = cam_reg;
- cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
- cam_reg);
-}
-
-/******************************************************************************
- *
- * cpia2_set_property_mirror
- *
- *****************************************************************************/
-void cpia2_set_property_mirror(struct camera_data *cam, int prop_val)
-{
- unsigned char cam_reg;
-
- cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0);
- cam_reg = cam->params.vp_params.user_effects;
-
- if (prop_val)
- {
- cam_reg |= CPIA2_VP_USER_EFFECTS_MIRROR;
- }
- else
- {
- cam_reg &= ~CPIA2_VP_USER_EFFECTS_MIRROR;
- }
- cam->params.vp_params.user_effects = cam_reg;
- cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
- cam_reg);
-}
-
-/******************************************************************************
- *
- * cpia2_set_gpio
- *
- *****************************************************************************/
-int cpia2_set_gpio(struct camera_data *cam, unsigned char setting)
-{
- int ret;
-
- /* Set the microport direction (register 0x90, should be defined
- * already) to 1 (user output), and set the microport data (0x91) to
- * the value in the ioctl argument.
- */
-
- ret = cpia2_do_command(cam,
- CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
- CPIA2_VC_MP_DIR_OUTPUT,
- 255);
- if (ret < 0)
- return ret;
- cam->params.vp_params.gpio_direction = 255;
-
- ret = cpia2_do_command(cam,
- CPIA2_CMD_SET_VC_MP_GPIO_DATA,
- CPIA2_VC_MP_DIR_OUTPUT,
- setting);
- if (ret < 0)
- return ret;
- cam->params.vp_params.gpio_data = setting;
-
- return 0;
-}
-
-/******************************************************************************
- *
- * cpia2_set_fps
- *
- *****************************************************************************/
-int cpia2_set_fps(struct camera_data *cam, int framerate)
-{
- int retval;
-
- switch(framerate) {
- case CPIA2_VP_FRAMERATE_30:
- case CPIA2_VP_FRAMERATE_25:
- if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
- cam->params.version.sensor_flags ==
- CPIA2_VP_SENSOR_FLAGS_500) {
- return -EINVAL;
- }
- /* Fall through */
- case CPIA2_VP_FRAMERATE_15:
- case CPIA2_VP_FRAMERATE_12_5:
- case CPIA2_VP_FRAMERATE_7_5:
- case CPIA2_VP_FRAMERATE_6_25:
- break;
- default:
- return -EINVAL;
- }
-
- if (cam->params.pnp_id.device_type == DEVICE_STV_672 &&
- framerate == CPIA2_VP_FRAMERATE_15)
- framerate = 0; /* Work around bug in VP4 */
-
- retval = cpia2_do_command(cam,
- CPIA2_CMD_FRAMERATE_REQ,
- TRANSFER_WRITE,
- framerate);
-
- if(retval == 0)
- cam->params.vp_params.frame_rate = framerate;
-
- return retval;
-}
-
-/******************************************************************************
- *
- * cpia2_set_brightness
- *
- *****************************************************************************/
-void cpia2_set_brightness(struct camera_data *cam, unsigned char value)
-{
- /***
- * Don't let the register be set to zero - bug in VP4 - flash of full
- * brightness
- ***/
- if (cam->params.pnp_id.device_type == DEVICE_STV_672 && value == 0)
- value++;
- DBG("Setting brightness to %d (0x%0x)\n", value, value);
- cpia2_do_command(cam, CPIA2_CMD_SET_VP_BRIGHTNESS, TRANSFER_WRITE, value);
-}
-
-/******************************************************************************
- *
- * cpia2_set_contrast
- *
- *****************************************************************************/
-void cpia2_set_contrast(struct camera_data *cam, unsigned char value)
-{
- DBG("Setting contrast to %d (0x%0x)\n", value, value);
- cpia2_do_command(cam, CPIA2_CMD_SET_CONTRAST, TRANSFER_WRITE, value);
-}
-
-/******************************************************************************
- *
- * cpia2_set_saturation
- *
- *****************************************************************************/
-void cpia2_set_saturation(struct camera_data *cam, unsigned char value)
-{
- DBG("Setting saturation to %d (0x%0x)\n", value, value);
- cpia2_do_command(cam,CPIA2_CMD_SET_VP_SATURATION, TRANSFER_WRITE,value);
-}
-
-/******************************************************************************
- *
- * wake_system
- *
- *****************************************************************************/
-static void wake_system(struct camera_data *cam)
-{
- cpia2_do_command(cam, CPIA2_CMD_SET_WAKEUP, TRANSFER_WRITE, 0);
-}
-
-/******************************************************************************
- *
- * set_lowlight_boost
- *
- * Valid for STV500 sensor only
- *****************************************************************************/
-static void set_lowlight_boost(struct camera_data *cam)
-{
- struct cpia2_command cmd;
-
- if (cam->params.pnp_id.device_type != DEVICE_STV_672 ||
- cam->params.version.sensor_flags != CPIA2_VP_SENSOR_FLAGS_500)
- return;
-
- cmd.direction = TRANSFER_WRITE;
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 3;
- cmd.start = CPIA2_VP_RAM_ADDR_H;
-
- cmd.buffer.block_data[0] = 0; /* High byte of address to write to */
- cmd.buffer.block_data[1] = 0x59; /* Low byte of address to write to */
- cmd.buffer.block_data[2] = 0; /* High byte of data to write */
-
- cpia2_send_command(cam, &cmd);
-
- if (cam->params.vp_params.lowlight_boost) {
- cmd.buffer.block_data[0] = 0x02; /* Low byte data to write */
- } else {
- cmd.buffer.block_data[0] = 0x06;
- }
- cmd.start = CPIA2_VP_RAM_DATA;
- cmd.reg_count = 1;
- cpia2_send_command(cam, &cmd);
-
- /* Rehash the VP4 values */
- cpia2_do_command(cam, CPIA2_CMD_REHASH_VP4, TRANSFER_WRITE, 1);
-}
-
-/******************************************************************************
- *
- * cpia2_set_format
- *
- * Assumes that new size is already set in param struct.
- *****************************************************************************/
-void cpia2_set_format(struct camera_data *cam)
-{
- cam->flush = true;
-
- cpia2_usb_stream_pause(cam);
-
- /* reset camera to new size */
- cpia2_set_low_power(cam);
- cpia2_reset_camera(cam);
- cam->flush = false;
-
- cpia2_dbg_dump_registers(cam);
-
- cpia2_usb_stream_resume(cam);
-}
-
-/******************************************************************************
- *
- * cpia2_dbg_dump_registers
- *
- *****************************************************************************/
-void cpia2_dbg_dump_registers(struct camera_data *cam)
-{
-#ifdef _CPIA2_DEBUG_
- struct cpia2_command cmd;
-
- if (!(debugs_on & DEBUG_DUMP_REGS))
- return;
-
- cmd.direction = TRANSFER_READ;
-
- /* Start with bank 0 (SYSTEM) */
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
- cmd.reg_count = 3;
- cmd.start = 0;
- cpia2_send_command(cam, &cmd);
- printk(KERN_DEBUG "System Device Hi = 0x%X\n",
- cmd.buffer.block_data[0]);
- printk(KERN_DEBUG "System Device Lo = 0x%X\n",
- cmd.buffer.block_data[1]);
- printk(KERN_DEBUG "System_system control = 0x%X\n",
- cmd.buffer.block_data[2]);
-
- /* Bank 1 (VC) */
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
- cmd.reg_count = 4;
- cmd.start = 0x80;
- cpia2_send_command(cam, &cmd);
- printk(KERN_DEBUG "ASIC_ID = 0x%X\n",
- cmd.buffer.block_data[0]);
- printk(KERN_DEBUG "ASIC_REV = 0x%X\n",
- cmd.buffer.block_data[1]);
- printk(KERN_DEBUG "PW_CONTRL = 0x%X\n",
- cmd.buffer.block_data[2]);
- printk(KERN_DEBUG "WAKEUP = 0x%X\n",
- cmd.buffer.block_data[3]);
-
- cmd.start = 0xA0; /* ST_CTRL */
- cmd.reg_count = 1;
- cpia2_send_command(cam, &cmd);
- printk(KERN_DEBUG "Stream ctrl = 0x%X\n",
- cmd.buffer.block_data[0]);
-
- cmd.start = 0xA4; /* Stream status */
- cpia2_send_command(cam, &cmd);
- printk(KERN_DEBUG "Stream status = 0x%X\n",
- cmd.buffer.block_data[0]);
-
- cmd.start = 0xA8; /* USB status */
- cmd.reg_count = 3;
- cpia2_send_command(cam, &cmd);
- printk(KERN_DEBUG "USB_CTRL = 0x%X\n",
- cmd.buffer.block_data[0]);
- printk(KERN_DEBUG "USB_STRM = 0x%X\n",
- cmd.buffer.block_data[1]);
- printk(KERN_DEBUG "USB_STATUS = 0x%X\n",
- cmd.buffer.block_data[2]);
-
- cmd.start = 0xAF; /* USB settings */
- cmd.reg_count = 1;
- cpia2_send_command(cam, &cmd);
- printk(KERN_DEBUG "USB settings = 0x%X\n",
- cmd.buffer.block_data[0]);
-
- cmd.start = 0xC0; /* VC stuff */
- cmd.reg_count = 26;
- cpia2_send_command(cam, &cmd);
- printk(KERN_DEBUG "VC Control = 0x%0X\n",
- cmd.buffer.block_data[0]);
- printk(KERN_DEBUG "VC Format = 0x%0X\n",
- cmd.buffer.block_data[3]);
- printk(KERN_DEBUG "VC Clocks = 0x%0X\n",
- cmd.buffer.block_data[4]);
- printk(KERN_DEBUG "VC IHSize = 0x%0X\n",
- cmd.buffer.block_data[5]);
- printk(KERN_DEBUG "VC Xlim Hi = 0x%0X\n",
- cmd.buffer.block_data[6]);
- printk(KERN_DEBUG "VC XLim Lo = 0x%0X\n",
- cmd.buffer.block_data[7]);
- printk(KERN_DEBUG "VC YLim Hi = 0x%0X\n",
- cmd.buffer.block_data[8]);
- printk(KERN_DEBUG "VC YLim Lo = 0x%0X\n",
- cmd.buffer.block_data[9]);
- printk(KERN_DEBUG "VC OHSize = 0x%0X\n",
- cmd.buffer.block_data[10]);
- printk(KERN_DEBUG "VC OVSize = 0x%0X\n",
- cmd.buffer.block_data[11]);
- printk(KERN_DEBUG "VC HCrop = 0x%0X\n",
- cmd.buffer.block_data[12]);
- printk(KERN_DEBUG "VC VCrop = 0x%0X\n",
- cmd.buffer.block_data[13]);
- printk(KERN_DEBUG "VC HPhase = 0x%0X\n",
- cmd.buffer.block_data[14]);
- printk(KERN_DEBUG "VC VPhase = 0x%0X\n",
- cmd.buffer.block_data[15]);
- printk(KERN_DEBUG "VC HIspan = 0x%0X\n",
- cmd.buffer.block_data[16]);
- printk(KERN_DEBUG "VC VIspan = 0x%0X\n",
- cmd.buffer.block_data[17]);
- printk(KERN_DEBUG "VC HiCrop = 0x%0X\n",
- cmd.buffer.block_data[18]);
- printk(KERN_DEBUG "VC ViCrop = 0x%0X\n",
- cmd.buffer.block_data[19]);
- printk(KERN_DEBUG "VC HiFract = 0x%0X\n",
- cmd.buffer.block_data[20]);
- printk(KERN_DEBUG "VC ViFract = 0x%0X\n",
- cmd.buffer.block_data[21]);
- printk(KERN_DEBUG "VC JPeg Opt = 0x%0X\n",
- cmd.buffer.block_data[22]);
- printk(KERN_DEBUG "VC Creep Per = 0x%0X\n",
- cmd.buffer.block_data[23]);
- printk(KERN_DEBUG "VC User Sq. = 0x%0X\n",
- cmd.buffer.block_data[24]);
- printk(KERN_DEBUG "VC Target KB = 0x%0X\n",
- cmd.buffer.block_data[25]);
-
- /*** VP ***/
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
- cmd.reg_count = 14;
- cmd.start = 0;
- cpia2_send_command(cam, &cmd);
-
- printk(KERN_DEBUG "VP Dev Hi = 0x%0X\n",
- cmd.buffer.block_data[0]);
- printk(KERN_DEBUG "VP Dev Lo = 0x%0X\n",
- cmd.buffer.block_data[1]);
- printk(KERN_DEBUG "VP Sys State = 0x%0X\n",
- cmd.buffer.block_data[2]);
- printk(KERN_DEBUG "VP Sys Ctrl = 0x%0X\n",
- cmd.buffer.block_data[3]);
- printk(KERN_DEBUG "VP Sensor flg = 0x%0X\n",
- cmd.buffer.block_data[5]);
- printk(KERN_DEBUG "VP Sensor Rev = 0x%0X\n",
- cmd.buffer.block_data[6]);
- printk(KERN_DEBUG "VP Dev Config = 0x%0X\n",
- cmd.buffer.block_data[7]);
- printk(KERN_DEBUG "VP GPIO_DIR = 0x%0X\n",
- cmd.buffer.block_data[8]);
- printk(KERN_DEBUG "VP GPIO_DATA = 0x%0X\n",
- cmd.buffer.block_data[9]);
- printk(KERN_DEBUG "VP Ram ADDR H = 0x%0X\n",
- cmd.buffer.block_data[10]);
- printk(KERN_DEBUG "VP Ram ADDR L = 0x%0X\n",
- cmd.buffer.block_data[11]);
- printk(KERN_DEBUG "VP RAM Data = 0x%0X\n",
- cmd.buffer.block_data[12]);
- printk(KERN_DEBUG "Do Call = 0x%0X\n",
- cmd.buffer.block_data[13]);
-
- if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
- cmd.reg_count = 9;
- cmd.start = 0x0E;
- cpia2_send_command(cam, &cmd);
- printk(KERN_DEBUG "VP Clock Ctrl = 0x%0X\n",
- cmd.buffer.block_data[0]);
- printk(KERN_DEBUG "VP Patch Rev = 0x%0X\n",
- cmd.buffer.block_data[1]);
- printk(KERN_DEBUG "VP Vid Mode = 0x%0X\n",
- cmd.buffer.block_data[2]);
- printk(KERN_DEBUG "VP Framerate = 0x%0X\n",
- cmd.buffer.block_data[3]);
- printk(KERN_DEBUG "VP UserEffect = 0x%0X\n",
- cmd.buffer.block_data[4]);
- printk(KERN_DEBUG "VP White Bal = 0x%0X\n",
- cmd.buffer.block_data[5]);
- printk(KERN_DEBUG "VP WB thresh = 0x%0X\n",
- cmd.buffer.block_data[6]);
- printk(KERN_DEBUG "VP Exp Modes = 0x%0X\n",
- cmd.buffer.block_data[7]);
- printk(KERN_DEBUG "VP Exp Target = 0x%0X\n",
- cmd.buffer.block_data[8]);
-
- cmd.reg_count = 1;
- cmd.start = 0x1B;
- cpia2_send_command(cam, &cmd);
- printk(KERN_DEBUG "VP FlickerMds = 0x%0X\n",
- cmd.buffer.block_data[0]);
- } else {
- cmd.reg_count = 8 ;
- cmd.start = 0x0E;
- cpia2_send_command(cam, &cmd);
- printk(KERN_DEBUG "VP Clock Ctrl = 0x%0X\n",
- cmd.buffer.block_data[0]);
- printk(KERN_DEBUG "VP Patch Rev = 0x%0X\n",
- cmd.buffer.block_data[1]);
- printk(KERN_DEBUG "VP Vid Mode = 0x%0X\n",
- cmd.buffer.block_data[5]);
- printk(KERN_DEBUG "VP Framerate = 0x%0X\n",
- cmd.buffer.block_data[6]);
- printk(KERN_DEBUG "VP UserEffect = 0x%0X\n",
- cmd.buffer.block_data[7]);
-
- cmd.reg_count = 1;
- cmd.start = CPIA2_VP5_EXPOSURE_TARGET;
- cpia2_send_command(cam, &cmd);
- printk(KERN_DEBUG "VP5 Exp Target= 0x%0X\n",
- cmd.buffer.block_data[0]);
-
- cmd.reg_count = 4;
- cmd.start = 0x3A;
- cpia2_send_command(cam, &cmd);
- printk(KERN_DEBUG "VP5 MY Black = 0x%0X\n",
- cmd.buffer.block_data[0]);
- printk(KERN_DEBUG "VP5 MCY Range = 0x%0X\n",
- cmd.buffer.block_data[1]);
- printk(KERN_DEBUG "VP5 MYCEILING = 0x%0X\n",
- cmd.buffer.block_data[2]);
- printk(KERN_DEBUG "VP5 MCUV Sat = 0x%0X\n",
- cmd.buffer.block_data[3]);
- }
-#endif
-}
-
-/******************************************************************************
- *
- * reset_camera_struct
- *
- * Sets all values to the defaults
- *****************************************************************************/
-static void reset_camera_struct(struct camera_data *cam)
-{
- /***
- * The following parameter values are the defaults from the register map.
- ***/
- cam->params.vp_params.lowlight_boost = 0;
-
- /* FlickerModes */
- cam->params.flicker_control.flicker_mode_req = NEVER_FLICKER;
-
- /* jpeg params */
- cam->params.compression.jpeg_options = CPIA2_VC_VC_JPEG_OPT_DEFAULT;
- cam->params.compression.creep_period = 2;
- cam->params.compression.user_squeeze = 20;
- cam->params.compression.inhibit_htables = false;
-
- /* gpio params */
- cam->params.vp_params.gpio_direction = 0; /* write, the default safe mode */
- cam->params.vp_params.gpio_data = 0;
-
- /* Target kb params */
- cam->params.vc_params.quality = 100;
-
- /***
- * Set Sensor FPS as fast as possible.
- ***/
- if(cam->params.pnp_id.device_type == DEVICE_STV_672) {
- if(cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500)
- cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_15;
- else
- cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_30;
- } else {
- cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_30;
- }
-
- /***
- * Set default video mode as large as possible :
- * for vga sensor set to vga, for cif sensor set to CIF.
- ***/
- if (cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500) {
- cam->sensor_type = CPIA2_SENSOR_500;
- cam->video_size = VIDEOSIZE_VGA;
- cam->params.roi.width = STV_IMAGE_VGA_COLS;
- cam->params.roi.height = STV_IMAGE_VGA_ROWS;
- } else {
- cam->sensor_type = CPIA2_SENSOR_410;
- cam->video_size = VIDEOSIZE_CIF;
- cam->params.roi.width = STV_IMAGE_CIF_COLS;
- cam->params.roi.height = STV_IMAGE_CIF_ROWS;
- }
-
- cam->width = cam->params.roi.width;
- cam->height = cam->params.roi.height;
-}
-
-/******************************************************************************
- *
- * cpia2_init_camera_struct
- *
- * Initializes camera struct, does not call reset to fill in defaults.
- *****************************************************************************/
-struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf)
-{
- struct camera_data *cam;
-
- cam = kzalloc(sizeof(*cam), GFP_KERNEL);
-
- if (!cam) {
- ERR("couldn't kmalloc cpia2 struct\n");
- return NULL;
- }
-
- cam->v4l2_dev.release = cpia2_camera_release;
- if (v4l2_device_register(&intf->dev, &cam->v4l2_dev) < 0) {
- v4l2_err(&cam->v4l2_dev, "couldn't register v4l2_device\n");
- kfree(cam);
- return NULL;
- }
-
- mutex_init(&cam->v4l2_lock);
- init_waitqueue_head(&cam->wq_stream);
-
- return cam;
-}
-
-/******************************************************************************
- *
- * cpia2_init_camera
- *
- * Initializes camera.
- *****************************************************************************/
-int cpia2_init_camera(struct camera_data *cam)
-{
- DBG("Start\n");
-
- cam->mmapped = false;
-
- /* Get sensor and asic types before reset. */
- cpia2_set_high_power(cam);
- cpia2_get_version_info(cam);
- if (cam->params.version.asic_id != CPIA2_ASIC_672) {
- ERR("Device IO error (asicID has incorrect value of 0x%X\n",
- cam->params.version.asic_id);
- return -ENODEV;
- }
-
- /* Set GPIO direction and data to a safe state. */
- cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
- TRANSFER_WRITE, 0);
- cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA,
- TRANSFER_WRITE, 0);
-
- /* resetting struct requires version info for sensor and asic types */
- reset_camera_struct(cam);
-
- cpia2_set_low_power(cam);
-
- DBG("End\n");
-
- return 0;
-}
-
-/******************************************************************************
- *
- * cpia2_allocate_buffers
- *
- *****************************************************************************/
-int cpia2_allocate_buffers(struct camera_data *cam)
-{
- int i;
-
- if(!cam->buffers) {
- u32 size = cam->num_frames*sizeof(struct framebuf);
- cam->buffers = kmalloc(size, GFP_KERNEL);
- if(!cam->buffers) {
- ERR("couldn't kmalloc frame buffer structures\n");
- return -ENOMEM;
- }
- }
-
- if(!cam->frame_buffer) {
- cam->frame_buffer = rvmalloc(cam->frame_size*cam->num_frames);
- if (!cam->frame_buffer) {
- ERR("couldn't vmalloc frame buffer data area\n");
- kfree(cam->buffers);
- cam->buffers = NULL;
- return -ENOMEM;
- }
- }
-
- for(i=0; i<cam->num_frames-1; ++i) {
- cam->buffers[i].next = &cam->buffers[i+1];
- cam->buffers[i].data = cam->frame_buffer +i*cam->frame_size;
- cam->buffers[i].status = FRAME_EMPTY;
- cam->buffers[i].length = 0;
- cam->buffers[i].max_length = 0;
- cam->buffers[i].num = i;
- }
- cam->buffers[i].next = cam->buffers;
- cam->buffers[i].data = cam->frame_buffer +i*cam->frame_size;
- cam->buffers[i].status = FRAME_EMPTY;
- cam->buffers[i].length = 0;
- cam->buffers[i].max_length = 0;
- cam->buffers[i].num = i;
- cam->curbuff = cam->buffers;
- cam->workbuff = cam->curbuff->next;
- DBG("buffers=%p, curbuff=%p, workbuff=%p\n", cam->buffers, cam->curbuff,
- cam->workbuff);
- return 0;
-}
-
-/******************************************************************************
- *
- * cpia2_free_buffers
- *
- *****************************************************************************/
-void cpia2_free_buffers(struct camera_data *cam)
-{
- if(cam->buffers) {
- kfree(cam->buffers);
- cam->buffers = NULL;
- }
- if(cam->frame_buffer) {
- rvfree(cam->frame_buffer, cam->frame_size*cam->num_frames);
- cam->frame_buffer = NULL;
- }
-}
-
-/******************************************************************************
- *
- * cpia2_read
- *
- *****************************************************************************/
-long cpia2_read(struct camera_data *cam,
- char __user *buf, unsigned long count, int noblock)
-{
- struct framebuf *frame;
-
- if (!count)
- return 0;
-
- if (!buf) {
- ERR("%s: buffer NULL\n",__func__);
- return -EINVAL;
- }
-
- if (!cam) {
- ERR("%s: Internal error, camera_data NULL!\n",__func__);
- return -EINVAL;
- }
-
- if (!cam->streaming) {
- /* Start streaming */
- cpia2_usb_stream_start(cam,
- cam->params.camera_state.stream_mode);
- }
-
- /* Copy cam->curbuff in case it changes while we're processing */
- frame = cam->curbuff;
- if (noblock && frame->status != FRAME_READY) {
- return -EAGAIN;
- }
-
- if (frame->status != FRAME_READY) {
- mutex_unlock(&cam->v4l2_lock);
- wait_event_interruptible(cam->wq_stream,
- !video_is_registered(&cam->vdev) ||
- (frame = cam->curbuff)->status == FRAME_READY);
- mutex_lock(&cam->v4l2_lock);
- if (signal_pending(current))
- return -ERESTARTSYS;
- if (!video_is_registered(&cam->vdev))
- return 0;
- }
-
- /* copy data to user space */
- if (frame->length > count)
- return -EFAULT;
- if (copy_to_user(buf, frame->data, frame->length))
- return -EFAULT;
-
- count = frame->length;
-
- frame->status = FRAME_EMPTY;
-
- return count;
-}
-
-/******************************************************************************
- *
- * cpia2_poll
- *
- *****************************************************************************/
-unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
- poll_table *wait)
-{
- unsigned int status = v4l2_ctrl_poll(filp, wait);
-
- if ((poll_requested_events(wait) & (POLLIN | POLLRDNORM)) &&
- !cam->streaming) {
- /* Start streaming */
- cpia2_usb_stream_start(cam,
- cam->params.camera_state.stream_mode);
- }
-
- poll_wait(filp, &cam->wq_stream, wait);
-
- if (cam->curbuff->status == FRAME_READY)
- status |= POLLIN | POLLRDNORM;
-
- return status;
-}
-
-/******************************************************************************
- *
- * cpia2_remap_buffer
- *
- *****************************************************************************/
-int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
-{
- const char *adr = (const char *)vma->vm_start;
- unsigned long size = vma->vm_end-vma->vm_start;
- unsigned long start_offset = vma->vm_pgoff << PAGE_SHIFT;
- unsigned long start = (unsigned long) adr;
- unsigned long page, pos;
-
- DBG("mmap offset:%ld size:%ld\n", start_offset, size);
-
- if (!video_is_registered(&cam->vdev))
- return -ENODEV;
-
- if (size > cam->frame_size*cam->num_frames ||
- (start_offset % cam->frame_size) != 0 ||
- (start_offset+size > cam->frame_size*cam->num_frames))
- return -EINVAL;
-
- pos = ((unsigned long) (cam->frame_buffer)) + start_offset;
- while (size > 0) {
- page = kvirt_to_pa(pos);
- if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED))
- return -EAGAIN;
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- if (size > PAGE_SIZE)
- size -= PAGE_SIZE;
- else
- size = 0;
- }
-
- cam->mmapped = true;
- return 0;
-}
diff --git a/drivers/media/video/cpia2/cpia2_registers.h b/drivers/media/video/cpia2/cpia2_registers.h
deleted file mode 100644
index 3bbec514a96..00000000000
--- a/drivers/media/video/cpia2/cpia2_registers.h
+++ /dev/null
@@ -1,476 +0,0 @@
-/****************************************************************************
- *
- * Filename: cpia2registers.h
- *
- * Copyright 2001, STMicrolectronics, Inc.
- *
- * Description:
- * Definitions for the CPia2 register set
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************************/
-
-#ifndef CPIA2_REGISTER_HEADER
-#define CPIA2_REGISTER_HEADER
-
-/***
- * System register set (Bank 0)
- ***/
-#define CPIA2_SYSTEM_DEVICE_HI 0x00
-#define CPIA2_SYSTEM_DEVICE_LO 0x01
-
-#define CPIA2_SYSTEM_SYSTEM_CONTROL 0x02
-#define CPIA2_SYSTEM_CONTROL_LOW_POWER 0x00
-#define CPIA2_SYSTEM_CONTROL_HIGH_POWER 0x01
-#define CPIA2_SYSTEM_CONTROL_SUSPEND 0x02
-#define CPIA2_SYSTEM_CONTROL_V2W_ERR 0x10
-#define CPIA2_SYSTEM_CONTROL_RB_ERR 0x10
-#define CPIA2_SYSTEM_CONTROL_CLEAR_ERR 0x80
-
-#define CPIA2_SYSTEM_INT_PACKET_CTRL 0x04
-#define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_SW_XX 0x01
-#define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_EOF 0x02
-#define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_INT1 0x04
-
-#define CPIA2_SYSTEM_CACHE_CTRL 0x05
-#define CPIA2_SYSTEM_CACHE_CTRL_CACHE_RESET 0x01
-#define CPIA2_SYSTEM_CACHE_CTRL_CACHE_FLUSH 0x02
-
-#define CPIA2_SYSTEM_SERIAL_CTRL 0x06
-#define CPIA2_SYSTEM_SERIAL_CTRL_NULL_CMD 0x00
-#define CPIA2_SYSTEM_SERIAL_CTRL_START_CMD 0x01
-#define CPIA2_SYSTEM_SERIAL_CTRL_STOP_CMD 0x02
-#define CPIA2_SYSTEM_SERIAL_CTRL_WRITE_CMD 0x03
-#define CPIA2_SYSTEM_SERIAL_CTRL_READ_ACK_CMD 0x04
-#define CPIA2_SYSTEM_SERIAL_CTRL_READ_NACK_CMD 0x05
-
-#define CPIA2_SYSTEM_SERIAL_DATA 0x07
-
-#define CPIA2_SYSTEM_VP_SERIAL_ADDR 0x08
-
-/***
- * I2C addresses for various devices in CPiA2
- ***/
-#define CPIA2_SYSTEM_VP_SERIAL_ADDR_SENSOR 0x20
-#define CPIA2_SYSTEM_VP_SERIAL_ADDR_VP 0x88
-#define CPIA2_SYSTEM_VP_SERIAL_ADDR_676_VP 0x8A
-
-#define CPIA2_SYSTEM_SPARE_REG1 0x09
-#define CPIA2_SYSTEM_SPARE_REG2 0x0A
-#define CPIA2_SYSTEM_SPARE_REG3 0x0B
-
-#define CPIA2_SYSTEM_MC_PORT_0 0x0C
-#define CPIA2_SYSTEM_MC_PORT_1 0x0D
-#define CPIA2_SYSTEM_MC_PORT_2 0x0E
-#define CPIA2_SYSTEM_MC_PORT_3 0x0F
-
-#define CPIA2_SYSTEM_STATUS_PKT 0x20
-#define CPIA2_SYSTEM_STATUS_PKT_END 0x27
-
-#define CPIA2_SYSTEM_DESCRIP_VID_HI 0x30
-#define CPIA2_SYSTEM_DESCRIP_VID_LO 0x31
-#define CPIA2_SYSTEM_DESCRIP_PID_HI 0x32
-#define CPIA2_SYSTEM_DESCRIP_PID_LO 0x33
-
-#define CPIA2_SYSTEM_FW_VERSION_HI 0x34
-#define CPIA2_SYSTEM_FW_VERSION_LO 0x35
-
-#define CPIA2_SYSTEM_CACHE_START_INDEX 0x80
-#define CPIA2_SYSTEM_CACHE_MAX_WRITES 0x10
-
-/***
- * VC register set (Bank 1)
- ***/
-#define CPIA2_VC_ASIC_ID 0x80
-
-#define CPIA2_VC_ASIC_REV 0x81
-
-#define CPIA2_VC_PW_CTRL 0x82
-#define CPIA2_VC_PW_CTRL_COLDSTART 0x01
-#define CPIA2_VC_PW_CTRL_CP_CLK_EN 0x02
-#define CPIA2_VC_PW_CTRL_VP_RESET_N 0x04
-#define CPIA2_VC_PW_CTRL_VC_CLK_EN 0x08
-#define CPIA2_VC_PW_CTRL_VC_RESET_N 0x10
-#define CPIA2_VC_PW_CTRL_GOTO_SUSPEND 0x20
-#define CPIA2_VC_PW_CTRL_UDC_SUSPEND 0x40
-#define CPIA2_VC_PW_CTRL_PWR_DOWN 0x80
-
-#define CPIA2_VC_WAKEUP 0x83
-#define CPIA2_VC_WAKEUP_SW_ENABLE 0x01
-#define CPIA2_VC_WAKEUP_XX_ENABLE 0x02
-#define CPIA2_VC_WAKEUP_SW_ATWAKEUP 0x04
-#define CPIA2_VC_WAKEUP_XX_ATWAKEUP 0x08
-
-#define CPIA2_VC_CLOCK_CTRL 0x84
-#define CPIA2_VC_CLOCK_CTRL_TESTUP72 0x01
-
-#define CPIA2_VC_INT_ENABLE 0x88
-#define CPIA2_VC_INT_ENABLE_XX_IE 0x01
-#define CPIA2_VC_INT_ENABLE_SW_IE 0x02
-#define CPIA2_VC_INT_ENABLE_VC_IE 0x04
-#define CPIA2_VC_INT_ENABLE_USBDATA_IE 0x08
-#define CPIA2_VC_INT_ENABLE_USBSETUP_IE 0x10
-#define CPIA2_VC_INT_ENABLE_USBCFG_IE 0x20
-
-#define CPIA2_VC_INT_FLAG 0x89
-#define CPIA2_VC_INT_ENABLE_XX_FLAG 0x01
-#define CPIA2_VC_INT_ENABLE_SW_FLAG 0x02
-#define CPIA2_VC_INT_ENABLE_VC_FLAG 0x04
-#define CPIA2_VC_INT_ENABLE_USBDATA_FLAG 0x08
-#define CPIA2_VC_INT_ENABLE_USBSETUP_FLAG 0x10
-#define CPIA2_VC_INT_ENABLE_USBCFG_FLAG 0x20
-#define CPIA2_VC_INT_ENABLE_SET_RESET_BIT 0x80
-
-#define CPIA2_VC_INT_STATE 0x8A
-#define CPIA2_VC_INT_STATE_XX_STATE 0x01
-#define CPIA2_VC_INT_STATE_SW_STATE 0x02
-
-#define CPIA2_VC_MP_DIR 0x90
-#define CPIA2_VC_MP_DIR_INPUT 0x00
-#define CPIA2_VC_MP_DIR_OUTPUT 0x01
-
-#define CPIA2_VC_MP_DATA 0x91
-
-#define CPIA2_VC_DP_CTRL 0x98
-#define CPIA2_VC_DP_CTRL_MODE_0 0x00
-#define CPIA2_VC_DP_CTRL_MODE_A 0x01
-#define CPIA2_VC_DP_CTRL_MODE_B 0x02
-#define CPIA2_VC_DP_CTRL_MODE_C 0x03
-#define CPIA2_VC_DP_CTRL_FAKE_FST 0x04
-
-#define CPIA2_VC_AD_CTRL 0x99
-#define CPIA2_VC_AD_CTRL_SRC_0 0x00
-#define CPIA2_VC_AD_CTRL_SRC_DIGI_A 0x01
-#define CPIA2_VC_AD_CTRL_SRC_REG 0x02
-#define CPIA2_VC_AD_CTRL_DST_USB 0x00
-#define CPIA2_VC_AD_CTRL_DST_REG 0x04
-
-#define CPIA2_VC_AD_TEST_IN 0x9B
-
-#define CPIA2_VC_AD_TEST_OUT 0x9C
-
-#define CPIA2_VC_AD_STATUS 0x9D
-#define CPIA2_VC_AD_STATUS_EMPTY 0x01
-#define CPIA2_VC_AD_STATUS_FULL 0x02
-
-#define CPIA2_VC_DP_DATA 0x9E
-
-#define CPIA2_VC_ST_CTRL 0xA0
-#define CPIA2_VC_ST_CTRL_SRC_VC 0x00
-#define CPIA2_VC_ST_CTRL_SRC_DP 0x01
-#define CPIA2_VC_ST_CTRL_SRC_REG 0x02
-
-#define CPIA2_VC_ST_CTRL_RAW_SELECT 0x04
-
-#define CPIA2_VC_ST_CTRL_DST_USB 0x00
-#define CPIA2_VC_ST_CTRL_DST_DP 0x08
-#define CPIA2_VC_ST_CTRL_DST_REG 0x10
-
-#define CPIA2_VC_ST_CTRL_FIFO_ENABLE 0x20
-#define CPIA2_VC_ST_CTRL_EOF_DETECT 0x40
-
-#define CPIA2_VC_ST_TEST 0xA1
-#define CPIA2_VC_ST_TEST_MODE_MANUAL 0x00
-#define CPIA2_VC_ST_TEST_MODE_INCREMENT 0x02
-
-#define CPIA2_VC_ST_TEST_AUTO_FILL 0x08
-
-#define CPIA2_VC_ST_TEST_REPEAT_FIFO 0x10
-
-#define CPIA2_VC_ST_TEST_IN 0xA2
-
-#define CPIA2_VC_ST_TEST_OUT 0xA3
-
-#define CPIA2_VC_ST_STATUS 0xA4
-#define CPIA2_VC_ST_STATUS_EMPTY 0x01
-#define CPIA2_VC_ST_STATUS_FULL 0x02
-
-#define CPIA2_VC_ST_FRAME_DETECT_1 0xA5
-
-#define CPIA2_VC_ST_FRAME_DETECT_2 0xA6
-
-#define CPIA2_VC_USB_CTRL 0xA8
-#define CPIA2_VC_USB_CTRL_CMD_STALLED 0x01
-#define CPIA2_VC_USB_CTRL_CMD_READY 0x02
-#define CPIA2_VC_USB_CTRL_CMD_STATUS 0x04
-#define CPIA2_VC_USB_CTRL_CMD_STATUS_DIR 0x08
-#define CPIA2_VC_USB_CTRL_CMD_NO_CLASH 0x10
-#define CPIA2_VC_USB_CTRL_CMD_MICRO_ACCESS 0x80
-
-#define CPIA2_VC_USB_STRM 0xA9
-#define CPIA2_VC_USB_STRM_ISO_ENABLE 0x01
-#define CPIA2_VC_USB_STRM_BLK_ENABLE 0x02
-#define CPIA2_VC_USB_STRM_INT_ENABLE 0x04
-#define CPIA2_VC_USB_STRM_AUD_ENABLE 0x08
-
-#define CPIA2_VC_USB_STATUS 0xAA
-#define CPIA2_VC_USB_STATUS_CMD_IN_PROGRESS 0x01
-#define CPIA2_VC_USB_STATUS_CMD_STATUS_STALL 0x02
-#define CPIA2_VC_USB_STATUS_CMD_HANDSHAKE 0x04
-#define CPIA2_VC_USB_STATUS_CMD_OVERRIDE 0x08
-#define CPIA2_VC_USB_STATUS_CMD_FIFO_BUSY 0x10
-#define CPIA2_VC_USB_STATUS_BULK_REPEAT_TXN 0x20
-#define CPIA2_VC_USB_STATUS_CONFIG_DONE 0x40
-#define CPIA2_VC_USB_STATUS_USB_SUSPEND 0x80
-
-#define CPIA2_VC_USB_CMDW 0xAB
-
-#define CPIA2_VC_USB_DATARW 0xAC
-
-#define CPIA2_VC_USB_INFO 0xAD
-
-#define CPIA2_VC_USB_CONFIG 0xAE
-
-#define CPIA2_VC_USB_SETTINGS 0xAF
-#define CPIA2_VC_USB_SETTINGS_CONFIG_MASK 0x03
-#define CPIA2_VC_USB_SETTINGS_INTERFACE_MASK 0x0C
-#define CPIA2_VC_USB_SETTINGS_ALTERNATE_MASK 0x70
-
-#define CPIA2_VC_USB_ISOLIM 0xB0
-
-#define CPIA2_VC_USB_ISOFAILS 0xB1
-
-#define CPIA2_VC_USB_ISOMAXPKTHI 0xB2
-
-#define CPIA2_VC_USB_ISOMAXPKTLO 0xB3
-
-#define CPIA2_VC_V2W_CTRL 0xB8
-#define CPIA2_VC_V2W_SELECT 0x01
-
-#define CPIA2_VC_V2W_SCL 0xB9
-
-#define CPIA2_VC_V2W_SDA 0xBA
-
-#define CPIA2_VC_VC_CTRL 0xC0
-#define CPIA2_VC_VC_CTRL_RUN 0x01
-#define CPIA2_VC_VC_CTRL_SINGLESHOT 0x02
-#define CPIA2_VC_VC_CTRL_IDLING 0x04
-#define CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES 0x10
-#define CPIA2_VC_VC_CTRL_INHIBIT_Q_TABLES 0x20
-#define CPIA2_VC_VC_CTRL_INHIBIT_PRIVATE 0x40
-
-#define CPIA2_VC_VC_RESTART_IVAL_HI 0xC1
-
-#define CPIA2_VC_VC_RESTART_IVAL_LO 0xC2
-
-#define CPIA2_VC_VC_FORMAT 0xC3
-#define CPIA2_VC_VC_FORMAT_UFIRST 0x01
-#define CPIA2_VC_VC_FORMAT_MONO 0x02
-#define CPIA2_VC_VC_FORMAT_DECIMATING 0x04
-#define CPIA2_VC_VC_FORMAT_SHORTLINE 0x08
-#define CPIA2_VC_VC_FORMAT_SELFTEST 0x10
-
-#define CPIA2_VC_VC_CLOCKS 0xC4
-#define CPIA2_VC_VC_CLOCKS_CLKDIV_MASK 0x03
-#define CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 0x04
-#define CPIA2_VC_VC_672_CLOCKS_SCALING 0x08
-#define CPIA2_VC_VC_CLOCKS_LOGDIV0 0x00
-#define CPIA2_VC_VC_CLOCKS_LOGDIV1 0x01
-#define CPIA2_VC_VC_CLOCKS_LOGDIV2 0x02
-#define CPIA2_VC_VC_CLOCKS_LOGDIV3 0x03
-#define CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 0x08
-#define CPIA2_VC_VC_676_CLOCKS_SCALING 0x10
-
-#define CPIA2_VC_VC_IHSIZE_LO 0xC5
-
-#define CPIA2_VC_VC_XLIM_HI 0xC6
-
-#define CPIA2_VC_VC_XLIM_LO 0xC7
-
-#define CPIA2_VC_VC_YLIM_HI 0xC8
-
-#define CPIA2_VC_VC_YLIM_LO 0xC9
-
-#define CPIA2_VC_VC_OHSIZE 0xCA
-
-#define CPIA2_VC_VC_OVSIZE 0xCB
-
-#define CPIA2_VC_VC_HCROP 0xCC
-
-#define CPIA2_VC_VC_VCROP 0xCD
-
-#define CPIA2_VC_VC_HPHASE 0xCE
-
-#define CPIA2_VC_VC_VPHASE 0xCF
-
-#define CPIA2_VC_VC_HISPAN 0xD0
-
-#define CPIA2_VC_VC_VISPAN 0xD1
-
-#define CPIA2_VC_VC_HICROP 0xD2
-
-#define CPIA2_VC_VC_VICROP 0xD3
-
-#define CPIA2_VC_VC_HFRACT 0xD4
-#define CPIA2_VC_VC_HFRACT_DEN_MASK 0x0F
-#define CPIA2_VC_VC_HFRACT_NUM_MASK 0xF0
-
-#define CPIA2_VC_VC_VFRACT 0xD5
-#define CPIA2_VC_VC_VFRACT_DEN_MASK 0x0F
-#define CPIA2_VC_VC_VFRACT_NUM_MASK 0xF0
-
-#define CPIA2_VC_VC_JPEG_OPT 0xD6
-#define CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE 0x01
-#define CPIA2_VC_VC_JPEG_OPT_NO_DC_AUTO_SQUEEZE 0x02
-#define CPIA2_VC_VC_JPEG_OPT_AUTO_SQUEEZE 0x04
-#define CPIA2_VC_VC_JPEG_OPT_DEFAULT (CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE|\
- CPIA2_VC_VC_JPEG_OPT_AUTO_SQUEEZE)
-
-
-#define CPIA2_VC_VC_CREEP_PERIOD 0xD7
-#define CPIA2_VC_VC_USER_SQUEEZE 0xD8
-#define CPIA2_VC_VC_TARGET_KB 0xD9
-
-#define CPIA2_VC_VC_AUTO_SQUEEZE 0xE6
-
-
-/***
- * VP register set (Bank 2)
- ***/
-#define CPIA2_VP_DEVICEH 0
-#define CPIA2_VP_DEVICEL 1
-
-#define CPIA2_VP_SYSTEMSTATE 0x02
-#define CPIA2_VP_SYSTEMSTATE_HK_ALIVE 0x01
-
-#define CPIA2_VP_SYSTEMCTRL 0x03
-#define CPIA2_VP_SYSTEMCTRL_REQ_CLEAR_ERROR 0x80
-#define CPIA2_VP_SYSTEMCTRL_POWER_DOWN_PLL 0x20
-#define CPIA2_VP_SYSTEMCTRL_REQ_SUSPEND_STATE 0x10
-#define CPIA2_VP_SYSTEMCTRL_REQ_SERIAL_WAKEUP 0x08
-#define CPIA2_VP_SYSTEMCTRL_REQ_AUTOLOAD 0x04
-#define CPIA2_VP_SYSTEMCTRL_HK_CONTROL 0x02
-#define CPIA2_VP_SYSTEMCTRL_POWER_CONTROL 0x01
-
-#define CPIA2_VP_SENSOR_FLAGS 0x05
-#define CPIA2_VP_SENSOR_FLAGS_404 0x01
-#define CPIA2_VP_SENSOR_FLAGS_407 0x02
-#define CPIA2_VP_SENSOR_FLAGS_409 0x04
-#define CPIA2_VP_SENSOR_FLAGS_410 0x08
-#define CPIA2_VP_SENSOR_FLAGS_500 0x10
-
-#define CPIA2_VP_SENSOR_REV 0x06
-
-#define CPIA2_VP_DEVICE_CONFIG 0x07
-#define CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE 0x01
-
-#define CPIA2_VP_GPIO_DIRECTION 0x08
-#define CPIA2_VP_GPIO_READ 0xFF
-#define CPIA2_VP_GPIO_WRITE 0x00
-
-#define CPIA2_VP_GPIO_DATA 0x09
-
-#define CPIA2_VP_RAM_ADDR_H 0x0A
-#define CPIA2_VP_RAM_ADDR_L 0x0B
-#define CPIA2_VP_RAM_DATA 0x0C
-
-#define CPIA2_VP_PATCH_REV 0x0F
-
-#define CPIA2_VP4_USER_MODE 0x10
-#define CPIA2_VP5_USER_MODE 0x13
-#define CPIA2_VP_USER_MODE_CIF 0x01
-#define CPIA2_VP_USER_MODE_QCIFDS 0x02
-#define CPIA2_VP_USER_MODE_QCIFPTC 0x04
-#define CPIA2_VP_USER_MODE_QVGADS 0x08
-#define CPIA2_VP_USER_MODE_QVGAPTC 0x10
-#define CPIA2_VP_USER_MODE_VGA 0x20
-
-#define CPIA2_VP4_FRAMERATE_REQUEST 0x11
-#define CPIA2_VP5_FRAMERATE_REQUEST 0x14
-#define CPIA2_VP_FRAMERATE_60 0x80
-#define CPIA2_VP_FRAMERATE_50 0x40
-#define CPIA2_VP_FRAMERATE_30 0x20
-#define CPIA2_VP_FRAMERATE_25 0x10
-#define CPIA2_VP_FRAMERATE_15 0x08
-#define CPIA2_VP_FRAMERATE_12_5 0x04
-#define CPIA2_VP_FRAMERATE_7_5 0x02
-#define CPIA2_VP_FRAMERATE_6_25 0x01
-
-#define CPIA2_VP4_USER_EFFECTS 0x12
-#define CPIA2_VP5_USER_EFFECTS 0x15
-#define CPIA2_VP_USER_EFFECTS_COLBARS 0x01
-#define CPIA2_VP_USER_EFFECTS_COLBARS_GRAD 0x02
-#define CPIA2_VP_USER_EFFECTS_MIRROR 0x04
-#define CPIA2_VP_USER_EFFECTS_FLIP 0x40 // VP5 only
-
-/* NOTE: CPIA2_VP_EXPOSURE_MODES shares the same register as VP5 User
- * Effects */
-#define CPIA2_VP_EXPOSURE_MODES 0x15
-#define CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER 0x20
-#define CPIA2_VP_EXPOSURE_MODES_COMPILE_EXP 0x10
-
-#define CPIA2_VP4_EXPOSURE_TARGET 0x16 // VP4
-#define CPIA2_VP5_EXPOSURE_TARGET 0x20 // VP5
-
-#define CPIA2_VP_FLICKER_MODES 0x1B
-#define CPIA2_VP_FLICKER_MODES_50HZ 0x80
-#define CPIA2_VP_FLICKER_MODES_CUSTOM_FLT_FFREQ 0x40
-#define CPIA2_VP_FLICKER_MODES_NEVER_FLICKER 0x20
-#define CPIA2_VP_FLICKER_MODES_INHIBIT_RUB 0x10
-#define CPIA2_VP_FLICKER_MODES_ADJUST_LINE_FREQ 0x08
-#define CPIA2_VP_FLICKER_MODES_CUSTOM_INT_FFREQ 0x04
-
-#define CPIA2_VP_UMISC 0x1D
-#define CPIA2_VP_UMISC_FORCE_MONO 0x80
-#define CPIA2_VP_UMISC_FORCE_ID_MASK 0x40
-#define CPIA2_VP_UMISC_INHIBIT_AUTO_FGS 0x20
-#define CPIA2_VP_UMISC_INHIBIT_AUTO_DIMS 0x08
-#define CPIA2_VP_UMISC_OPT_FOR_SENSOR_DS 0x04
-#define CPIA2_VP_UMISC_INHIBIT_AUTO_MODE_INT 0x02
-
-#define CPIA2_VP5_ANTIFLKRSETUP 0x22 //34
-
-#define CPIA2_VP_INTERPOLATION 0x24
-#define CPIA2_VP_INTERPOLATION_EVEN_FIRST 0x40
-#define CPIA2_VP_INTERPOLATION_HJOG 0x20
-#define CPIA2_VP_INTERPOLATION_VJOG 0x10
-
-#define CPIA2_VP_GAMMA 0x25
-#define CPIA2_VP_DEFAULT_GAMMA 0x10
-
-#define CPIA2_VP_YRANGE 0x26
-
-#define CPIA2_VP_SATURATION 0x27
-
-#define CPIA2_VP5_MYBLACK_LEVEL 0x3A //58
-#define CPIA2_VP5_MCYRANGE 0x3B //59
-#define CPIA2_VP5_MYCEILING 0x3C //60
-#define CPIA2_VP5_MCUVSATURATION 0x3D //61
-
-
-#define CPIA2_VP_REHASH_VALUES 0x60
-
-
-/***
- * Common sensor registers
- ***/
-#define CPIA2_SENSOR_DEVICE_H 0x00
-#define CPIA2_SENSOR_DEVICE_L 0x01
-
-#define CPIA2_SENSOR_DATA_FORMAT 0x16
-#define CPIA2_SENSOR_DATA_FORMAT_HMIRROR 0x08
-#define CPIA2_SENSOR_DATA_FORMAT_VMIRROR 0x10
-
-#define CPIA2_SENSOR_CR1 0x76
-#define CPIA2_SENSOR_CR1_STAND_BY 0x01
-#define CPIA2_SENSOR_CR1_DOWN_RAMP_GEN 0x02
-#define CPIA2_SENSOR_CR1_DOWN_COLUMN_ADC 0x04
-#define CPIA2_SENSOR_CR1_DOWN_CAB_REGULATOR 0x08
-#define CPIA2_SENSOR_CR1_DOWN_AUDIO_REGULATOR 0x10
-#define CPIA2_SENSOR_CR1_DOWN_VRT_AMP 0x20
-#define CPIA2_SENSOR_CR1_DOWN_BAND_GAP 0x40
-
-#endif
diff --git a/drivers/media/video/cpia2/cpia2_usb.c b/drivers/media/video/cpia2/cpia2_usb.c
deleted file mode 100644
index 95b5d6e7cdc..00000000000
--- a/drivers/media/video/cpia2/cpia2_usb.c
+++ /dev/null
@@ -1,955 +0,0 @@
-/****************************************************************************
- *
- * Filename: cpia2_usb.c
- *
- * Copyright 2001, STMicrolectronics, Inc.
- * Contact: steve.miller@st.com
- *
- * Description:
- * This is a USB driver for CPia2 based video cameras.
- * The infrastructure of this driver is based on the cpia usb driver by
- * Jochen Scharrlach and Johannes Erdfeldt.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Stripped of 2.4 stuff ready for main kernel submit by
- * Alan Cox <alan@lxorguk.ukuu.org.uk>
- ****************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/module.h>
-
-#include "cpia2.h"
-
-static int frame_sizes[] = {
- 0, // USBIF_CMDONLY
- 0, // USBIF_BULK
- 128, // USBIF_ISO_1
- 384, // USBIF_ISO_2
- 640, // USBIF_ISO_3
- 768, // USBIF_ISO_4
- 896, // USBIF_ISO_5
- 1023, // USBIF_ISO_6
-};
-
-#define FRAMES_PER_DESC 10
-#define FRAME_SIZE_PER_DESC frame_sizes[cam->cur_alt]
-
-static void process_frame(struct camera_data *cam);
-static void cpia2_usb_complete(struct urb *urb);
-static int cpia2_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id);
-static void cpia2_usb_disconnect(struct usb_interface *intf);
-static int cpia2_usb_suspend(struct usb_interface *intf, pm_message_t message);
-static int cpia2_usb_resume(struct usb_interface *intf);
-
-static void free_sbufs(struct camera_data *cam);
-static void add_APPn(struct camera_data *cam);
-static void add_COM(struct camera_data *cam);
-static int submit_urbs(struct camera_data *cam);
-static int set_alternate(struct camera_data *cam, unsigned int alt);
-static int configure_transfer_mode(struct camera_data *cam, unsigned int alt);
-
-static struct usb_device_id cpia2_id_table[] = {
- {USB_DEVICE(0x0553, 0x0100)},
- {USB_DEVICE(0x0553, 0x0140)},
- {USB_DEVICE(0x0553, 0x0151)}, /* STV0676 */
- {} /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, cpia2_id_table);
-
-static struct usb_driver cpia2_driver = {
- .name = "cpia2",
- .probe = cpia2_usb_probe,
- .disconnect = cpia2_usb_disconnect,
- .suspend = cpia2_usb_suspend,
- .resume = cpia2_usb_resume,
- .reset_resume = cpia2_usb_resume,
- .id_table = cpia2_id_table
-};
-
-
-/******************************************************************************
- *
- * process_frame
- *
- *****************************************************************************/
-static void process_frame(struct camera_data *cam)
-{
- static int frame_count;
-
- unsigned char *inbuff = cam->workbuff->data;
-
- DBG("Processing frame #%d, current:%d\n",
- cam->workbuff->num, cam->curbuff->num);
-
- if(cam->workbuff->length > cam->workbuff->max_length)
- cam->workbuff->max_length = cam->workbuff->length;
-
- if ((inbuff[0] == 0xFF) && (inbuff[1] == 0xD8)) {
- frame_count++;
- } else {
- cam->workbuff->status = FRAME_ERROR;
- DBG("Start of frame not found\n");
- return;
- }
-
- /***
- * Now the output buffer should have a JPEG image in it.
- ***/
- if(!cam->first_image_seen) {
- /* Always skip the first image after streaming
- * starts. It is almost certainly corrupt. */
- cam->first_image_seen = 1;
- cam->workbuff->status = FRAME_EMPTY;
- return;
- }
- if (cam->workbuff->length > 3) {
- if(cam->mmapped &&
- cam->workbuff->length < cam->workbuff->max_length) {
- /* No junk in the buffers */
- memset(cam->workbuff->data+cam->workbuff->length,
- 0, cam->workbuff->max_length-
- cam->workbuff->length);
- }
- cam->workbuff->max_length = cam->workbuff->length;
- cam->workbuff->status = FRAME_READY;
-
- if(!cam->mmapped && cam->num_frames > 2) {
- /* During normal reading, the most recent
- * frame will be read. If the current frame
- * hasn't started reading yet, it will never
- * be read, so mark it empty. If the buffer is
- * mmapped, or we have few buffers, we need to
- * wait for the user to free the buffer.
- *
- * NOTE: This is not entirely foolproof with 3
- * buffers, but it would take an EXTREMELY
- * overloaded system to cause problems (possible
- * image data corruption). Basically, it would
- * need to take more time to execute cpia2_read
- * than it would for the camera to send
- * cam->num_frames-2 frames before problems
- * could occur.
- */
- cam->curbuff->status = FRAME_EMPTY;
- }
- cam->curbuff = cam->workbuff;
- cam->workbuff = cam->workbuff->next;
- DBG("Changed buffers, work:%d, current:%d\n",
- cam->workbuff->num, cam->curbuff->num);
- return;
- } else {
- DBG("Not enough data for an image.\n");
- }
-
- cam->workbuff->status = FRAME_ERROR;
- return;
-}
-
-/******************************************************************************
- *
- * add_APPn
- *
- * Adds a user specified APPn record
- *****************************************************************************/
-static void add_APPn(struct camera_data *cam)
-{
- if(cam->APP_len > 0) {
- cam->workbuff->data[cam->workbuff->length++] = 0xFF;
- cam->workbuff->data[cam->workbuff->length++] = 0xE0+cam->APPn;
- cam->workbuff->data[cam->workbuff->length++] = 0;
- cam->workbuff->data[cam->workbuff->length++] = cam->APP_len+2;
- memcpy(cam->workbuff->data+cam->workbuff->length,
- cam->APP_data, cam->APP_len);
- cam->workbuff->length += cam->APP_len;
- }
-}
-
-/******************************************************************************
- *
- * add_COM
- *
- * Adds a user specified COM record
- *****************************************************************************/
-static void add_COM(struct camera_data *cam)
-{
- if(cam->COM_len > 0) {
- cam->workbuff->data[cam->workbuff->length++] = 0xFF;
- cam->workbuff->data[cam->workbuff->length++] = 0xFE;
- cam->workbuff->data[cam->workbuff->length++] = 0;
- cam->workbuff->data[cam->workbuff->length++] = cam->COM_len+2;
- memcpy(cam->workbuff->data+cam->workbuff->length,
- cam->COM_data, cam->COM_len);
- cam->workbuff->length += cam->COM_len;
- }
-}
-
-/******************************************************************************
- *
- * cpia2_usb_complete
- *
- * callback when incoming packet is received
- *****************************************************************************/
-static void cpia2_usb_complete(struct urb *urb)
-{
- int i;
- unsigned char *cdata;
- static int frame_ready = false;
- struct camera_data *cam = (struct camera_data *) urb->context;
-
- if (urb->status!=0) {
- if (!(urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN))
- {
- DBG("urb->status = %d!\n", urb->status);
- }
- DBG("Stopping streaming\n");
- return;
- }
-
- if (!cam->streaming || !video_is_registered(&cam->vdev)) {
- LOG("Will now stop the streaming: streaming = %d, present=%d\n",
- cam->streaming, video_is_registered(&cam->vdev));
- return;
- }
-
- /***
- * Packet collater
- ***/
- //DBG("Collating %d packets\n", urb->number_of_packets);
- for (i = 0; i < urb->number_of_packets; i++) {
- u16 checksum, iso_checksum;
- int j;
- int n = urb->iso_frame_desc[i].actual_length;
- int st = urb->iso_frame_desc[i].status;
-
- if(cam->workbuff->status == FRAME_READY) {
- struct framebuf *ptr;
- /* Try to find an available buffer */
- DBG("workbuff full, searching\n");
- for (ptr = cam->workbuff->next;
- ptr != cam->workbuff;
- ptr = ptr->next)
- {
- if (ptr->status == FRAME_EMPTY) {
- ptr->status = FRAME_READING;
- ptr->length = 0;
- break;
- }
- }
- if (ptr == cam->workbuff)
- break; /* No READING or EMPTY buffers left */
-
- cam->workbuff = ptr;
- }
-
- if (cam->workbuff->status == FRAME_EMPTY ||
- cam->workbuff->status == FRAME_ERROR) {
- cam->workbuff->status = FRAME_READING;
- cam->workbuff->length = 0;
- }
-
- //DBG(" Packet %d length = %d, status = %d\n", i, n, st);
- cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
-
- if (st) {
- LOG("cpia2 data error: [%d] len=%d, status = %d\n",
- i, n, st);
- if(!ALLOW_CORRUPT)
- cam->workbuff->status = FRAME_ERROR;
- continue;
- }
-
- if(n<=2)
- continue;
-
- checksum = 0;
- for(j=0; j<n-2; ++j)
- checksum += cdata[j];
- iso_checksum = cdata[j] + cdata[j+1]*256;
- if(checksum != iso_checksum) {
- LOG("checksum mismatch: [%d] len=%d, calculated = %x, checksum = %x\n",
- i, n, (int)checksum, (int)iso_checksum);
- if(!ALLOW_CORRUPT) {
- cam->workbuff->status = FRAME_ERROR;
- continue;
- }
- }
- n -= 2;
-
- if(cam->workbuff->status != FRAME_READING) {
- if((0xFF == cdata[0] && 0xD8 == cdata[1]) ||
- (0xD8 == cdata[0] && 0xFF == cdata[1] &&
- 0 != cdata[2])) {
- /* frame is skipped, but increment total
- * frame count anyway */
- cam->frame_count++;
- }
- DBG("workbuff not reading, status=%d\n",
- cam->workbuff->status);
- continue;
- }
-
- if (cam->frame_size < cam->workbuff->length + n) {
- ERR("buffer overflow! length: %d, n: %d\n",
- cam->workbuff->length, n);
- cam->workbuff->status = FRAME_ERROR;
- if(cam->workbuff->length > cam->workbuff->max_length)
- cam->workbuff->max_length =
- cam->workbuff->length;
- continue;
- }
-
- if (cam->workbuff->length == 0) {
- int data_offset;
- if ((0xD8 == cdata[0]) && (0xFF == cdata[1])) {
- data_offset = 1;
- } else if((0xFF == cdata[0]) && (0xD8 == cdata[1])
- && (0xFF == cdata[2])) {
- data_offset = 2;
- } else {
- DBG("Ignoring packet, not beginning!\n");
- continue;
- }
- DBG("Start of frame pattern found\n");
- do_gettimeofday(&cam->workbuff->timestamp);
- cam->workbuff->seq = cam->frame_count++;
- cam->workbuff->data[0] = 0xFF;
- cam->workbuff->data[1] = 0xD8;
- cam->workbuff->length = 2;
- add_APPn(cam);
- add_COM(cam);
- memcpy(cam->workbuff->data+cam->workbuff->length,
- cdata+data_offset, n-data_offset);
- cam->workbuff->length += n-data_offset;
- } else if (cam->workbuff->length > 0) {
- memcpy(cam->workbuff->data + cam->workbuff->length,
- cdata, n);
- cam->workbuff->length += n;
- }
-
- if ((cam->workbuff->length >= 3) &&
- (cam->workbuff->data[cam->workbuff->length - 3] == 0xFF) &&
- (cam->workbuff->data[cam->workbuff->length - 2] == 0xD9) &&
- (cam->workbuff->data[cam->workbuff->length - 1] == 0xFF)) {
- frame_ready = true;
- cam->workbuff->data[cam->workbuff->length - 1] = 0;
- cam->workbuff->length -= 1;
- } else if ((cam->workbuff->length >= 2) &&
- (cam->workbuff->data[cam->workbuff->length - 2] == 0xFF) &&
- (cam->workbuff->data[cam->workbuff->length - 1] == 0xD9)) {
- frame_ready = true;
- }
-
- if (frame_ready) {
- DBG("Workbuff image size = %d\n",cam->workbuff->length);
- process_frame(cam);
-
- frame_ready = false;
-
- if (waitqueue_active(&cam->wq_stream))
- wake_up_interruptible(&cam->wq_stream);
- }
- }
-
- if(cam->streaming) {
- /* resubmit */
- urb->dev = cam->dev;
- if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0)
- ERR("%s: usb_submit_urb ret %d!\n", __func__, i);
- }
-}
-
-/******************************************************************************
- *
- * configure_transfer_mode
- *
- *****************************************************************************/
-static int configure_transfer_mode(struct camera_data *cam, unsigned int alt)
-{
- static unsigned char iso_regs[8][4] = {
- {0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00},
- {0xB9, 0x00, 0x00, 0x7E},
- {0xB9, 0x00, 0x01, 0x7E},
- {0xB9, 0x00, 0x02, 0x7E},
- {0xB9, 0x00, 0x02, 0xFE},
- {0xB9, 0x00, 0x03, 0x7E},
- {0xB9, 0x00, 0x03, 0xFD}
- };
- struct cpia2_command cmd;
- unsigned char reg;
-
- if (!video_is_registered(&cam->vdev))
- return -ENODEV;
-
- /***
- * Write the isoc registers according to the alternate selected
- ***/
- cmd.direction = TRANSFER_WRITE;
- cmd.buffer.block_data[0] = iso_regs[alt][0];
- cmd.buffer.block_data[1] = iso_regs[alt][1];
- cmd.buffer.block_data[2] = iso_regs[alt][2];
- cmd.buffer.block_data[3] = iso_regs[alt][3];
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
- cmd.start = CPIA2_VC_USB_ISOLIM;
- cmd.reg_count = 4;
- cpia2_send_command(cam, &cmd);
-
- /***
- * Enable relevant streams before starting polling.
- * First read USB Stream Config Register.
- ***/
- cmd.direction = TRANSFER_READ;
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
- cmd.start = CPIA2_VC_USB_STRM;
- cmd.reg_count = 1;
- cpia2_send_command(cam, &cmd);
- reg = cmd.buffer.block_data[0];
-
- /* Clear iso, bulk, and int */
- reg &= ~(CPIA2_VC_USB_STRM_BLK_ENABLE |
- CPIA2_VC_USB_STRM_ISO_ENABLE |
- CPIA2_VC_USB_STRM_INT_ENABLE);
-
- if (alt == USBIF_BULK) {
- DBG("Enabling bulk xfer\n");
- reg |= CPIA2_VC_USB_STRM_BLK_ENABLE; /* Enable Bulk */
- cam->xfer_mode = XFER_BULK;
- } else if (alt >= USBIF_ISO_1) {
- DBG("Enabling ISOC xfer\n");
- reg |= CPIA2_VC_USB_STRM_ISO_ENABLE;
- cam->xfer_mode = XFER_ISOC;
- }
-
- cmd.buffer.block_data[0] = reg;
- cmd.direction = TRANSFER_WRITE;
- cmd.start = CPIA2_VC_USB_STRM;
- cmd.reg_count = 1;
- cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
- cpia2_send_command(cam, &cmd);
-
- return 0;
-}
-
-/******************************************************************************
- *
- * cpia2_usb_change_streaming_alternate
- *
- *****************************************************************************/
-int cpia2_usb_change_streaming_alternate(struct camera_data *cam,
- unsigned int alt)
-{
- int ret = 0;
-
- if(alt < USBIF_ISO_1 || alt > USBIF_ISO_6)
- return -EINVAL;
-
- if(alt == cam->params.camera_state.stream_mode)
- return 0;
-
- cpia2_usb_stream_pause(cam);
-
- configure_transfer_mode(cam, alt);
-
- cam->params.camera_state.stream_mode = alt;
-
- /* Reset the camera to prevent image quality degradation */
- cpia2_reset_camera(cam);
-
- cpia2_usb_stream_resume(cam);
-
- return ret;
-}
-
-/******************************************************************************
- *
- * set_alternate
- *
- *****************************************************************************/
-static int set_alternate(struct camera_data *cam, unsigned int alt)
-{
- int ret = 0;
-
- if(alt == cam->cur_alt)
- return 0;
-
- if (cam->cur_alt != USBIF_CMDONLY) {
- DBG("Changing from alt %d to %d\n", cam->cur_alt, USBIF_CMDONLY);
- ret = usb_set_interface(cam->dev, cam->iface, USBIF_CMDONLY);
- if (ret != 0)
- return ret;
- }
- if (alt != USBIF_CMDONLY) {
- DBG("Changing from alt %d to %d\n", USBIF_CMDONLY, alt);
- ret = usb_set_interface(cam->dev, cam->iface, alt);
- if (ret != 0)
- return ret;
- }
-
- cam->old_alt = cam->cur_alt;
- cam->cur_alt = alt;
-
- return ret;
-}
-
-/******************************************************************************
- *
- * free_sbufs
- *
- * Free all cam->sbuf[]. All non-NULL .data and .urb members that are non-NULL
- * are assumed to be allocated. Non-NULL .urb members are also assumed to be
- * submitted (and must therefore be killed before they are freed).
- *****************************************************************************/
-static void free_sbufs(struct camera_data *cam)
-{
- int i;
-
- for (i = 0; i < NUM_SBUF; i++) {
- if(cam->sbuf[i].urb) {
- usb_kill_urb(cam->sbuf[i].urb);
- usb_free_urb(cam->sbuf[i].urb);
- cam->sbuf[i].urb = NULL;
- }
- if(cam->sbuf[i].data) {
- kfree(cam->sbuf[i].data);
- cam->sbuf[i].data = NULL;
- }
- }
-}
-
-/*******
-* Convenience functions
-*******/
-/****************************************************************************
- *
- * write_packet
- *
- ***************************************************************************/
-static int write_packet(struct usb_device *udev,
- u8 request, u8 * registers, u16 start, size_t size)
-{
- if (!registers || size <= 0)
- return -EINVAL;
-
- return usb_control_msg(udev,
- usb_sndctrlpipe(udev, 0),
- request,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- start, /* value */
- 0, /* index */
- registers, /* buffer */
- size,
- HZ);
-}
-
-/****************************************************************************
- *
- * read_packet
- *
- ***************************************************************************/
-static int read_packet(struct usb_device *udev,
- u8 request, u8 * registers, u16 start, size_t size)
-{
- if (!registers || size <= 0)
- return -EINVAL;
-
- return usb_control_msg(udev,
- usb_rcvctrlpipe(udev, 0),
- request,
- USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE,
- start, /* value */
- 0, /* index */
- registers, /* buffer */
- size,
- HZ);
-}
-
-/******************************************************************************
- *
- * cpia2_usb_transfer_cmd
- *
- *****************************************************************************/
-int cpia2_usb_transfer_cmd(struct camera_data *cam,
- void *registers,
- u8 request, u8 start, u8 count, u8 direction)
-{
- int err = 0;
- struct usb_device *udev = cam->dev;
-
- if (!udev) {
- ERR("%s: Internal driver error: udev is NULL\n", __func__);
- return -EINVAL;
- }
-
- if (!registers) {
- ERR("%s: Internal driver error: register array is NULL\n", __func__);
- return -EINVAL;
- }
-
- if (direction == TRANSFER_READ) {
- err = read_packet(udev, request, (u8 *)registers, start, count);
- if (err > 0)
- err = 0;
- } else if (direction == TRANSFER_WRITE) {
- err =write_packet(udev, request, (u8 *)registers, start, count);
- if (err < 0) {
- LOG("Control message failed, err val = %d\n", err);
- LOG("Message: request = 0x%0X, start = 0x%0X\n",
- request, start);
- LOG("Message: count = %d, register[0] = 0x%0X\n",
- count, ((unsigned char *) registers)[0]);
- } else
- err=0;
- } else {
- LOG("Unexpected first byte of direction: %d\n",
- direction);
- return -EINVAL;
- }
-
- if(err != 0)
- LOG("Unexpected error: %d\n", err);
- return err;
-}
-
-
-/******************************************************************************
- *
- * submit_urbs
- *
- *****************************************************************************/
-static int submit_urbs(struct camera_data *cam)
-{
- struct urb *urb;
- int fx, err, i, j;
-
- for(i=0; i<NUM_SBUF; ++i) {
- if (cam->sbuf[i].data)
- continue;
- cam->sbuf[i].data =
- kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
- if (!cam->sbuf[i].data) {
- while (--i >= 0) {
- kfree(cam->sbuf[i].data);
- cam->sbuf[i].data = NULL;
- }
- return -ENOMEM;
- }
- }
-
- /* We double buffer the Isoc lists, and also know the polling
- * interval is every frame (1 == (1 << (bInterval -1))).
- */
- for(i=0; i<NUM_SBUF; ++i) {
- if(cam->sbuf[i].urb) {
- continue;
- }
- urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
- if (!urb) {
- ERR("%s: usb_alloc_urb error!\n", __func__);
- for (j = 0; j < i; j++)
- usb_free_urb(cam->sbuf[j].urb);
- return -ENOMEM;
- }
-
- cam->sbuf[i].urb = urb;
- urb->dev = cam->dev;
- urb->context = cam;
- urb->pipe = usb_rcvisocpipe(cam->dev, 1 /*ISOC endpoint*/);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = cam->sbuf[i].data;
- urb->complete = cpia2_usb_complete;
- urb->number_of_packets = FRAMES_PER_DESC;
- urb->interval = 1;
- urb->transfer_buffer_length =
- FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;
-
- for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
- urb->iso_frame_desc[fx].offset =
- FRAME_SIZE_PER_DESC * fx;
- urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
- }
- }
-
-
- /* Queue the ISO urbs, and resubmit in the completion handler */
- for(i=0; i<NUM_SBUF; ++i) {
- err = usb_submit_urb(cam->sbuf[i].urb, GFP_KERNEL);
- if (err) {
- ERR("usb_submit_urb[%d]() = %d\n", i, err);
- return err;
- }
- }
-
- return 0;
-}
-
-/******************************************************************************
- *
- * cpia2_usb_stream_start
- *
- *****************************************************************************/
-int cpia2_usb_stream_start(struct camera_data *cam, unsigned int alternate)
-{
- int ret;
- int old_alt;
-
- if(cam->streaming)
- return 0;
-
- if (cam->flush) {
- int i;
- DBG("Flushing buffers\n");
- for(i=0; i<cam->num_frames; ++i) {
- cam->buffers[i].status = FRAME_EMPTY;
- cam->buffers[i].length = 0;
- }
- cam->curbuff = &cam->buffers[0];
- cam->workbuff = cam->curbuff->next;
- cam->flush = false;
- }
-
- old_alt = cam->params.camera_state.stream_mode;
- cam->params.camera_state.stream_mode = 0;
- ret = cpia2_usb_change_streaming_alternate(cam, alternate);
- if (ret < 0) {
- int ret2;
- ERR("cpia2_usb_change_streaming_alternate() = %d!\n", ret);
- cam->params.camera_state.stream_mode = old_alt;
- ret2 = set_alternate(cam, USBIF_CMDONLY);
- if (ret2 < 0) {
- ERR("cpia2_usb_change_streaming_alternate(%d) =%d has already "
- "failed. Then tried to call "
- "set_alternate(USBIF_CMDONLY) = %d.\n",
- alternate, ret, ret2);
- }
- } else {
- cam->frame_count = 0;
- cam->streaming = 1;
- ret = cpia2_usb_stream_resume(cam);
- }
- return ret;
-}
-
-/******************************************************************************
- *
- * cpia2_usb_stream_pause
- *
- *****************************************************************************/
-int cpia2_usb_stream_pause(struct camera_data *cam)
-{
- int ret = 0;
- if(cam->streaming) {
- free_sbufs(cam);
- ret = set_alternate(cam, USBIF_CMDONLY);
- }
- return ret;
-}
-
-/******************************************************************************
- *
- * cpia2_usb_stream_resume
- *
- *****************************************************************************/
-int cpia2_usb_stream_resume(struct camera_data *cam)
-{
- int ret = 0;
- if(cam->streaming) {
- cam->first_image_seen = 0;
- ret = set_alternate(cam, cam->params.camera_state.stream_mode);
- if(ret == 0) {
- /* for some reason the user effects need to be set
- again when starting streaming. */
- cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
- cam->params.vp_params.user_effects);
- ret = submit_urbs(cam);
- }
- }
- return ret;
-}
-
-/******************************************************************************
- *
- * cpia2_usb_stream_stop
- *
- *****************************************************************************/
-int cpia2_usb_stream_stop(struct camera_data *cam)
-{
- int ret;
-
- ret = cpia2_usb_stream_pause(cam);
- cam->streaming = 0;
- configure_transfer_mode(cam, 0);
- return ret;
-}
-
-/******************************************************************************
- *
- * cpia2_usb_probe
- *
- * Probe and initialize.
- *****************************************************************************/
-static int cpia2_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct usb_interface_descriptor *interface;
- struct camera_data *cam;
- int ret;
-
- /* A multi-config CPiA2 camera? */
- if (udev->descriptor.bNumConfigurations != 1)
- return -ENODEV;
- interface = &intf->cur_altsetting->desc;
-
- /* If we get to this point, we found a CPiA2 camera */
- LOG("CPiA2 USB camera found\n");
-
- cam = cpia2_init_camera_struct(intf);
- if (cam == NULL)
- return -ENOMEM;
-
- cam->dev = udev;
- cam->iface = interface->bInterfaceNumber;
-
- ret = set_alternate(cam, USBIF_CMDONLY);
- if (ret < 0) {
- ERR("%s: usb_set_interface error (ret = %d)\n", __func__, ret);
- kfree(cam);
- return ret;
- }
-
-
- if((ret = cpia2_init_camera(cam)) < 0) {
- ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret);
- kfree(cam);
- return ret;
- }
- LOG(" CPiA Version: %d.%02d (%d.%d)\n",
- cam->params.version.firmware_revision_hi,
- cam->params.version.firmware_revision_lo,
- cam->params.version.asic_id,
- cam->params.version.asic_rev);
- LOG(" CPiA PnP-ID: %04x:%04x:%04x\n",
- cam->params.pnp_id.vendor,
- cam->params.pnp_id.product,
- cam->params.pnp_id.device_revision);
- LOG(" SensorID: %d.(version %d)\n",
- cam->params.version.sensor_flags,
- cam->params.version.sensor_rev);
-
- usb_set_intfdata(intf, cam);
-
- ret = cpia2_register_camera(cam);
- if (ret < 0) {
- ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret);
- kfree(cam);
- return ret;
- }
-
- return 0;
-}
-
-/******************************************************************************
- *
- * cpia2_disconnect
- *
- *****************************************************************************/
-static void cpia2_usb_disconnect(struct usb_interface *intf)
-{
- struct camera_data *cam = usb_get_intfdata(intf);
- usb_set_intfdata(intf, NULL);
-
- DBG("Stopping stream\n");
- cpia2_usb_stream_stop(cam);
-
- mutex_lock(&cam->v4l2_lock);
- DBG("Unregistering camera\n");
- cpia2_unregister_camera(cam);
- v4l2_device_disconnect(&cam->v4l2_dev);
- mutex_unlock(&cam->v4l2_lock);
- v4l2_device_put(&cam->v4l2_dev);
-
- if(cam->buffers) {
- DBG("Wakeup waiting processes\n");
- cam->curbuff->status = FRAME_READY;
- cam->curbuff->length = 0;
- if (waitqueue_active(&cam->wq_stream))
- wake_up_interruptible(&cam->wq_stream);
- }
-
- DBG("Releasing interface\n");
- usb_driver_release_interface(&cpia2_driver, intf);
-
- LOG("CPiA2 camera disconnected.\n");
-}
-
-static int cpia2_usb_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct camera_data *cam = usb_get_intfdata(intf);
-
- mutex_lock(&cam->v4l2_lock);
- if (cam->streaming) {
- cpia2_usb_stream_stop(cam);
- cam->streaming = 1;
- }
- mutex_unlock(&cam->v4l2_lock);
-
- dev_info(&intf->dev, "going into suspend..\n");
- return 0;
-}
-
-/* Resume device - start device. */
-static int cpia2_usb_resume(struct usb_interface *intf)
-{
- struct camera_data *cam = usb_get_intfdata(intf);
-
- mutex_lock(&cam->v4l2_lock);
- v4l2_ctrl_handler_setup(&cam->hdl);
- if (cam->streaming) {
- cam->streaming = 0;
- cpia2_usb_stream_start(cam,
- cam->params.camera_state.stream_mode);
- }
- mutex_unlock(&cam->v4l2_lock);
-
- dev_info(&intf->dev, "coming out of suspend..\n");
- return 0;
-}
-
-/******************************************************************************
- *
- * usb_cpia2_init
- *
- *****************************************************************************/
-int cpia2_usb_init(void)
-{
- return usb_register(&cpia2_driver);
-}
-
-/******************************************************************************
- *
- * usb_cpia_cleanup
- *
- *****************************************************************************/
-void cpia2_usb_cleanup(void)
-{
- schedule_timeout(2 * HZ);
- usb_deregister(&cpia2_driver);
-}
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
deleted file mode 100644
index a62a7b73999..00000000000
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ /dev/null
@@ -1,1250 +0,0 @@
-/****************************************************************************
- *
- * Filename: cpia2_v4l.c
- *
- * Copyright 2001, STMicrolectronics, Inc.
- * Contact: steve.miller@st.com
- * Copyright 2001,2005, Scott J. Bertin <scottbertin@yahoo.com>
- *
- * Description:
- * This is a USB driver for CPia2 based video cameras.
- * The infrastructure of this driver is based on the cpia usb driver by
- * Jochen Scharrlach and Johannes Erdfeldt.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Stripped of 2.4 stuff ready for main kernel submit by
- * Alan Cox <alan@lxorguk.ukuu.org.uk>
- ****************************************************************************/
-
-#define CPIA_VERSION "3.0.1"
-
-#include <linux/module.h>
-#include <linux/time.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/videodev2.h>
-#include <linux/stringify.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-event.h>
-
-#include "cpia2.h"
-
-static int video_nr = -1;
-module_param(video_nr, int, 0);
-MODULE_PARM_DESC(video_nr, "video device to register (0=/dev/video0, etc)");
-
-static int buffer_size = 68 * 1024;
-module_param(buffer_size, int, 0);
-MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)");
-
-static int num_buffers = 3;
-module_param(num_buffers, int, 0);
-MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-"
- __stringify(VIDEO_MAX_FRAME) ", default 3)");
-
-static int alternate = DEFAULT_ALT;
-module_param(alternate, int, 0);
-MODULE_PARM_DESC(alternate, "USB Alternate (" __stringify(USBIF_ISO_1) "-"
- __stringify(USBIF_ISO_6) ", default "
- __stringify(DEFAULT_ALT) ")");
-
-static int flicker_mode;
-module_param(flicker_mode, int, 0);
-MODULE_PARM_DESC(flicker_mode, "Flicker frequency (0 (disabled), " __stringify(50) " or "
- __stringify(60) ", default 0)");
-
-MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>");
-MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras");
-MODULE_SUPPORTED_DEVICE("video");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(CPIA_VERSION);
-
-#define ABOUT "V4L-Driver for Vision CPiA2 based cameras"
-#define CPIA2_CID_USB_ALT (V4L2_CID_USER_BASE | 0xf000)
-
-/******************************************************************************
- *
- * cpia2_open
- *
- *****************************************************************************/
-static int cpia2_open(struct file *file)
-{
- struct camera_data *cam = video_drvdata(file);
- int retval = v4l2_fh_open(file);
-
- if (retval)
- return retval;
-
- if (v4l2_fh_is_singular_file(file)) {
- if (cpia2_allocate_buffers(cam)) {
- v4l2_fh_release(file);
- return -ENOMEM;
- }
-
- /* reset the camera */
- if (cpia2_reset_camera(cam) < 0) {
- v4l2_fh_release(file);
- return -EIO;
- }
-
- cam->APP_len = 0;
- cam->COM_len = 0;
- }
-
- cpia2_dbg_dump_registers(cam);
- return 0;
-}
-
-/******************************************************************************
- *
- * cpia2_close
- *
- *****************************************************************************/
-static int cpia2_close(struct file *file)
-{
- struct video_device *dev = video_devdata(file);
- struct camera_data *cam = video_get_drvdata(dev);
-
- if (video_is_registered(&cam->vdev) && v4l2_fh_is_singular_file(file)) {
- cpia2_usb_stream_stop(cam);
-
- /* save camera state for later open */
- cpia2_save_camera_state(cam);
-
- cpia2_set_low_power(cam);
- cpia2_free_buffers(cam);
- }
-
- if (cam->stream_fh == file->private_data) {
- cam->stream_fh = NULL;
- cam->mmapped = 0;
- }
- return v4l2_fh_release(file);
-}
-
-/******************************************************************************
- *
- * cpia2_v4l_read
- *
- *****************************************************************************/
-static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count,
- loff_t *off)
-{
- struct camera_data *cam = video_drvdata(file);
- int noblock = file->f_flags&O_NONBLOCK;
-
- if(!cam)
- return -EINVAL;
-
- return cpia2_read(cam, buf, count, noblock);
-}
-
-
-/******************************************************************************
- *
- * cpia2_v4l_poll
- *
- *****************************************************************************/
-static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait)
-{
- struct camera_data *cam = video_drvdata(filp);
-
- return cpia2_poll(cam, filp, wait);
-}
-
-
-static int sync(struct camera_data *cam, int frame_nr)
-{
- struct framebuf *frame = &cam->buffers[frame_nr];
-
- while (1) {
- if (frame->status == FRAME_READY)
- return 0;
-
- if (!cam->streaming) {
- frame->status = FRAME_READY;
- frame->length = 0;
- return 0;
- }
-
- mutex_unlock(&cam->v4l2_lock);
- wait_event_interruptible(cam->wq_stream,
- !cam->streaming ||
- frame->status == FRAME_READY);
- mutex_lock(&cam->v4l2_lock);
- if (signal_pending(current))
- return -ERESTARTSYS;
- if (!video_is_registered(&cam->vdev))
- return -ENOTTY;
- }
-}
-
-/******************************************************************************
- *
- * ioctl_querycap
- *
- * V4L2 device capabilities
- *
- *****************************************************************************/
-
-static int cpia2_querycap(struct file *file, void *fh, struct v4l2_capability *vc)
-{
- struct camera_data *cam = video_drvdata(file);
-
- strcpy(vc->driver, "cpia2");
-
- if (cam->params.pnp_id.product == 0x151)
- strcpy(vc->card, "QX5 Microscope");
- else
- strcpy(vc->card, "CPiA2 Camera");
- switch (cam->params.pnp_id.device_type) {
- case DEVICE_STV_672:
- strcat(vc->card, " (672/");
- break;
- case DEVICE_STV_676:
- strcat(vc->card, " (676/");
- break;
- default:
- strcat(vc->card, " (XXX/");
- break;
- }
- switch (cam->params.version.sensor_flags) {
- case CPIA2_VP_SENSOR_FLAGS_404:
- strcat(vc->card, "404)");
- break;
- case CPIA2_VP_SENSOR_FLAGS_407:
- strcat(vc->card, "407)");
- break;
- case CPIA2_VP_SENSOR_FLAGS_409:
- strcat(vc->card, "409)");
- break;
- case CPIA2_VP_SENSOR_FLAGS_410:
- strcat(vc->card, "410)");
- break;
- case CPIA2_VP_SENSOR_FLAGS_500:
- strcat(vc->card, "500)");
- break;
- default:
- strcat(vc->card, "XXX)");
- break;
- }
-
- if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) <0)
- memset(vc->bus_info,0, sizeof(vc->bus_info));
-
- vc->device_caps = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING;
- vc->capabilities = vc->device_caps |
- V4L2_CAP_DEVICE_CAPS;
-
- return 0;
-}
-
-/******************************************************************************
- *
- * ioctl_input
- *
- * V4L2 input get/set/enumerate
- *
- *****************************************************************************/
-
-static int cpia2_enum_input(struct file *file, void *fh, struct v4l2_input *i)
-{
- if (i->index)
- return -EINVAL;
- strcpy(i->name, "Camera");
- i->type = V4L2_INPUT_TYPE_CAMERA;
- return 0;
-}
-
-static int cpia2_g_input(struct file *file, void *fh, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int cpia2_s_input(struct file *file, void *fh, unsigned int i)
-{
- return i ? -EINVAL : 0;
-}
-
-/******************************************************************************
- *
- * ioctl_enum_fmt
- *
- * V4L2 format enumerate
- *
- *****************************************************************************/
-
-static int cpia2_enum_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_fmtdesc *f)
-{
- int index = f->index;
-
- if (index < 0 || index > 1)
- return -EINVAL;
-
- memset(f, 0, sizeof(*f));
- f->index = index;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- f->flags = V4L2_FMT_FLAG_COMPRESSED;
- switch(index) {
- case 0:
- strcpy(f->description, "MJPEG");
- f->pixelformat = V4L2_PIX_FMT_MJPEG;
- break;
- case 1:
- strcpy(f->description, "JPEG");
- f->pixelformat = V4L2_PIX_FMT_JPEG;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/******************************************************************************
- *
- * ioctl_try_fmt
- *
- * V4L2 format try
- *
- *****************************************************************************/
-
-static int cpia2_try_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct camera_data *cam = video_drvdata(file);
-
- if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
- f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
- return -EINVAL;
-
- f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage = cam->frame_size;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
- f->fmt.pix.priv = 0;
-
- switch (cpia2_match_video_size(f->fmt.pix.width, f->fmt.pix.height)) {
- case VIDEOSIZE_VGA:
- f->fmt.pix.width = 640;
- f->fmt.pix.height = 480;
- break;
- case VIDEOSIZE_CIF:
- f->fmt.pix.width = 352;
- f->fmt.pix.height = 288;
- break;
- case VIDEOSIZE_QVGA:
- f->fmt.pix.width = 320;
- f->fmt.pix.height = 240;
- break;
- case VIDEOSIZE_288_216:
- f->fmt.pix.width = 288;
- f->fmt.pix.height = 216;
- break;
- case VIDEOSIZE_256_192:
- f->fmt.pix.width = 256;
- f->fmt.pix.height = 192;
- break;
- case VIDEOSIZE_224_168:
- f->fmt.pix.width = 224;
- f->fmt.pix.height = 168;
- break;
- case VIDEOSIZE_192_144:
- f->fmt.pix.width = 192;
- f->fmt.pix.height = 144;
- break;
- case VIDEOSIZE_QCIF:
- default:
- f->fmt.pix.width = 176;
- f->fmt.pix.height = 144;
- break;
- }
-
- return 0;
-}
-
-/******************************************************************************
- *
- * ioctl_set_fmt
- *
- * V4L2 format set
- *
- *****************************************************************************/
-
-static int cpia2_s_fmt_vid_cap(struct file *file, void *_fh,
- struct v4l2_format *f)
-{
- struct camera_data *cam = video_drvdata(file);
- int err, frame;
-
- err = cpia2_try_fmt_vid_cap(file, _fh, f);
- if(err != 0)
- return err;
-
- cam->pixelformat = f->fmt.pix.pixelformat;
-
- /* NOTE: This should be set to 1 for MJPEG, but some apps don't handle
- * the missing Huffman table properly. */
- cam->params.compression.inhibit_htables = 0;
- /*f->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG;*/
-
- /* we set the video window to something smaller or equal to what
- * is requested by the user???
- */
- DBG("Requested width = %d, height = %d\n",
- f->fmt.pix.width, f->fmt.pix.height);
- if (f->fmt.pix.width != cam->width ||
- f->fmt.pix.height != cam->height) {
- cam->width = f->fmt.pix.width;
- cam->height = f->fmt.pix.height;
- cam->params.roi.width = f->fmt.pix.width;
- cam->params.roi.height = f->fmt.pix.height;
- cpia2_set_format(cam);
- }
-
- for (frame = 0; frame < cam->num_frames; ++frame) {
- if (cam->buffers[frame].status == FRAME_READING)
- if ((err = sync(cam, frame)) < 0)
- return err;
-
- cam->buffers[frame].status = FRAME_EMPTY;
- }
-
- return 0;
-}
-
-/******************************************************************************
- *
- * ioctl_get_fmt
- *
- * V4L2 format get
- *
- *****************************************************************************/
-
-static int cpia2_g_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct camera_data *cam = video_drvdata(file);
-
- f->fmt.pix.width = cam->width;
- f->fmt.pix.height = cam->height;
- f->fmt.pix.pixelformat = cam->pixelformat;
- f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage = cam->frame_size;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
- f->fmt.pix.priv = 0;
-
- return 0;
-}
-
-/******************************************************************************
- *
- * ioctl_cropcap
- *
- * V4L2 query cropping capabilities
- * NOTE: cropping is currently disabled
- *
- *****************************************************************************/
-
-static int cpia2_cropcap(struct file *file, void *fh, struct v4l2_cropcap *c)
-{
- struct camera_data *cam = video_drvdata(file);
-
- if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- c->bounds.left = 0;
- c->bounds.top = 0;
- c->bounds.width = cam->width;
- c->bounds.height = cam->height;
- c->defrect.left = 0;
- c->defrect.top = 0;
- c->defrect.width = cam->width;
- c->defrect.height = cam->height;
- c->pixelaspect.numerator = 1;
- c->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-struct framerate_info {
- int value;
- struct v4l2_fract period;
-};
-
-static const struct framerate_info framerate_controls[] = {
- { CPIA2_VP_FRAMERATE_6_25, { 4, 25 } },
- { CPIA2_VP_FRAMERATE_7_5, { 2, 15 } },
- { CPIA2_VP_FRAMERATE_12_5, { 2, 25 } },
- { CPIA2_VP_FRAMERATE_15, { 1, 15 } },
- { CPIA2_VP_FRAMERATE_25, { 1, 25 } },
- { CPIA2_VP_FRAMERATE_30, { 1, 30 } },
-};
-
-static int cpia2_g_parm(struct file *file, void *fh, struct v4l2_streamparm *p)
-{
- struct camera_data *cam = video_drvdata(file);
- struct v4l2_captureparm *cap = &p->parm.capture;
- int i;
-
- if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- cap->capability = V4L2_CAP_TIMEPERFRAME;
- cap->readbuffers = cam->num_frames;
- for (i = 0; i < ARRAY_SIZE(framerate_controls); i++)
- if (cam->params.vp_params.frame_rate == framerate_controls[i].value) {
- cap->timeperframe = framerate_controls[i].period;
- break;
- }
- return 0;
-}
-
-static int cpia2_s_parm(struct file *file, void *fh, struct v4l2_streamparm *p)
-{
- struct camera_data *cam = video_drvdata(file);
- struct v4l2_captureparm *cap = &p->parm.capture;
- struct v4l2_fract tpf = cap->timeperframe;
- int max = ARRAY_SIZE(framerate_controls) - 1;
- int ret;
- int i;
-
- ret = cpia2_g_parm(file, fh, p);
- if (ret || !tpf.denominator || !tpf.numerator)
- return ret;
-
- /* Maximum 15 fps for this model */
- if (cam->params.pnp_id.device_type == DEVICE_STV_672 &&
- cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500)
- max -= 2;
- for (i = 0; i <= max; i++) {
- struct v4l2_fract f1 = tpf;
- struct v4l2_fract f2 = framerate_controls[i].period;
-
- f1.numerator *= f2.denominator;
- f2.numerator *= f1.denominator;
- if (f1.numerator >= f2.numerator)
- break;
- }
- if (i > max)
- i = max;
- cap->timeperframe = framerate_controls[i].period;
- return cpia2_set_fps(cam, framerate_controls[i].value);
-}
-
-static const struct {
- u32 width;
- u32 height;
-} cpia2_framesizes[] = {
- { 640, 480 },
- { 352, 288 },
- { 320, 240 },
- { 288, 216 },
- { 256, 192 },
- { 224, 168 },
- { 192, 144 },
- { 176, 144 },
-};
-
-static int cpia2_enum_framesizes(struct file *file, void *fh,
- struct v4l2_frmsizeenum *fsize)
-{
-
- if (fsize->pixel_format != V4L2_PIX_FMT_MJPEG &&
- fsize->pixel_format != V4L2_PIX_FMT_JPEG)
- return -EINVAL;
- if (fsize->index >= ARRAY_SIZE(cpia2_framesizes))
- return -EINVAL;
- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fsize->discrete.width = cpia2_framesizes[fsize->index].width;
- fsize->discrete.height = cpia2_framesizes[fsize->index].height;
-
- return 0;
-}
-
-static int cpia2_enum_frameintervals(struct file *file, void *fh,
- struct v4l2_frmivalenum *fival)
-{
- struct camera_data *cam = video_drvdata(file);
- int max = ARRAY_SIZE(framerate_controls) - 1;
- int i;
-
- if (fival->pixel_format != V4L2_PIX_FMT_MJPEG &&
- fival->pixel_format != V4L2_PIX_FMT_JPEG)
- return -EINVAL;
-
- /* Maximum 15 fps for this model */
- if (cam->params.pnp_id.device_type == DEVICE_STV_672 &&
- cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500)
- max -= 2;
- if (fival->index > max)
- return -EINVAL;
- for (i = 0; i < ARRAY_SIZE(cpia2_framesizes); i++)
- if (fival->width == cpia2_framesizes[i].width &&
- fival->height == cpia2_framesizes[i].height)
- break;
- if (i == ARRAY_SIZE(cpia2_framesizes))
- return -EINVAL;
- fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
- fival->discrete = framerate_controls[fival->index].period;
- return 0;
-}
-
-/******************************************************************************
- *
- * ioctl_s_ctrl
- *
- * V4L2 set the value of a control variable
- *
- *****************************************************************************/
-
-static int cpia2_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct camera_data *cam =
- container_of(ctrl->handler, struct camera_data, hdl);
- static const int flicker_table[] = {
- NEVER_FLICKER,
- FLICKER_50,
- FLICKER_60,
- };
-
- DBG("Set control id:%d, value:%d\n", ctrl->id, ctrl->val);
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- cpia2_set_brightness(cam, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- cpia2_set_contrast(cam, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- cpia2_set_saturation(cam, ctrl->val);
- break;
- case V4L2_CID_HFLIP:
- cpia2_set_property_mirror(cam, ctrl->val);
- break;
- case V4L2_CID_VFLIP:
- cpia2_set_property_flip(cam, ctrl->val);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY:
- return cpia2_set_flicker_mode(cam, flicker_table[ctrl->val]);
- case V4L2_CID_ILLUMINATORS_1:
- return cpia2_set_gpio(cam, (cam->top_light->val << 6) |
- (cam->bottom_light->val << 7));
- case V4L2_CID_JPEG_ACTIVE_MARKER:
- cam->params.compression.inhibit_htables =
- !(ctrl->val & V4L2_JPEG_ACTIVE_MARKER_DHT);
- break;
- case V4L2_CID_JPEG_COMPRESSION_QUALITY:
- cam->params.vc_params.quality = ctrl->val;
- break;
- case CPIA2_CID_USB_ALT:
- cam->params.camera_state.stream_mode = ctrl->val;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/******************************************************************************
- *
- * ioctl_g_jpegcomp
- *
- * V4L2 get the JPEG compression parameters
- *
- *****************************************************************************/
-
-static int cpia2_g_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompression *parms)
-{
- struct camera_data *cam = video_drvdata(file);
-
- memset(parms, 0, sizeof(*parms));
-
- parms->quality = 80; // TODO: Can this be made meaningful?
-
- parms->jpeg_markers = V4L2_JPEG_MARKER_DQT | V4L2_JPEG_MARKER_DRI;
- if(!cam->params.compression.inhibit_htables) {
- parms->jpeg_markers |= V4L2_JPEG_MARKER_DHT;
- }
-
- parms->APPn = cam->APPn;
- parms->APP_len = cam->APP_len;
- if(cam->APP_len > 0) {
- memcpy(parms->APP_data, cam->APP_data, cam->APP_len);
- parms->jpeg_markers |= V4L2_JPEG_MARKER_APP;
- }
-
- parms->COM_len = cam->COM_len;
- if(cam->COM_len > 0) {
- memcpy(parms->COM_data, cam->COM_data, cam->COM_len);
- parms->jpeg_markers |= JPEG_MARKER_COM;
- }
-
- DBG("G_JPEGCOMP APP_len:%d COM_len:%d\n",
- parms->APP_len, parms->COM_len);
-
- return 0;
-}
-
-/******************************************************************************
- *
- * ioctl_s_jpegcomp
- *
- * V4L2 set the JPEG compression parameters
- * NOTE: quality and some jpeg_markers are ignored.
- *
- *****************************************************************************/
-
-static int cpia2_s_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompression *parms)
-{
- struct camera_data *cam = video_drvdata(file);
-
- DBG("S_JPEGCOMP APP_len:%d COM_len:%d\n",
- parms->APP_len, parms->COM_len);
-
- cam->params.compression.inhibit_htables =
- !(parms->jpeg_markers & V4L2_JPEG_MARKER_DHT);
- parms->jpeg_markers &= V4L2_JPEG_MARKER_DQT | V4L2_JPEG_MARKER_DRI |
- V4L2_JPEG_MARKER_DHT;
-
- if(parms->APP_len != 0) {
- if(parms->APP_len > 0 &&
- parms->APP_len <= sizeof(cam->APP_data) &&
- parms->APPn >= 0 && parms->APPn <= 15) {
- cam->APPn = parms->APPn;
- cam->APP_len = parms->APP_len;
- memcpy(cam->APP_data, parms->APP_data, parms->APP_len);
- } else {
- LOG("Bad APPn Params n=%d len=%d\n",
- parms->APPn, parms->APP_len);
- return -EINVAL;
- }
- } else {
- cam->APP_len = 0;
- }
-
- if(parms->COM_len != 0) {
- if(parms->COM_len > 0 &&
- parms->COM_len <= sizeof(cam->COM_data)) {
- cam->COM_len = parms->COM_len;
- memcpy(cam->COM_data, parms->COM_data, parms->COM_len);
- } else {
- LOG("Bad COM_len=%d\n", parms->COM_len);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-/******************************************************************************
- *
- * ioctl_reqbufs
- *
- * V4L2 Initiate memory mapping.
- * NOTE: The user's request is ignored. For now the buffers are fixed.
- *
- *****************************************************************************/
-
-static int cpia2_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *req)
-{
- struct camera_data *cam = video_drvdata(file);
-
- if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- req->memory != V4L2_MEMORY_MMAP)
- return -EINVAL;
-
- DBG("REQBUFS requested:%d returning:%d\n", req->count, cam->num_frames);
- req->count = cam->num_frames;
- memset(&req->reserved, 0, sizeof(req->reserved));
-
- return 0;
-}
-
-/******************************************************************************
- *
- * ioctl_querybuf
- *
- * V4L2 Query memory buffer status.
- *
- *****************************************************************************/
-
-static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
-{
- struct camera_data *cam = video_drvdata(file);
-
- if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- buf->index > cam->num_frames)
- return -EINVAL;
-
- buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
- buf->length = cam->frame_size;
-
- buf->memory = V4L2_MEMORY_MMAP;
-
- if(cam->mmapped)
- buf->flags = V4L2_BUF_FLAG_MAPPED;
- else
- buf->flags = 0;
-
- switch (cam->buffers[buf->index].status) {
- case FRAME_EMPTY:
- case FRAME_ERROR:
- case FRAME_READING:
- buf->bytesused = 0;
- buf->flags = V4L2_BUF_FLAG_QUEUED;
- break;
- case FRAME_READY:
- buf->bytesused = cam->buffers[buf->index].length;
- buf->timestamp = cam->buffers[buf->index].timestamp;
- buf->sequence = cam->buffers[buf->index].seq;
- buf->flags = V4L2_BUF_FLAG_DONE;
- break;
- }
-
- DBG("QUERYBUF index:%d offset:%d flags:%d seq:%d bytesused:%d\n",
- buf->index, buf->m.offset, buf->flags, buf->sequence,
- buf->bytesused);
-
- return 0;
-}
-
-/******************************************************************************
- *
- * ioctl_qbuf
- *
- * V4L2 User is freeing buffer
- *
- *****************************************************************************/
-
-static int cpia2_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
-{
- struct camera_data *cam = video_drvdata(file);
-
- if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- buf->memory != V4L2_MEMORY_MMAP ||
- buf->index > cam->num_frames)
- return -EINVAL;
-
- DBG("QBUF #%d\n", buf->index);
-
- if(cam->buffers[buf->index].status == FRAME_READY)
- cam->buffers[buf->index].status = FRAME_EMPTY;
-
- return 0;
-}
-
-/******************************************************************************
- *
- * find_earliest_filled_buffer
- *
- * Helper for ioctl_dqbuf. Find the next ready buffer.
- *
- *****************************************************************************/
-
-static int find_earliest_filled_buffer(struct camera_data *cam)
-{
- int i;
- int found = -1;
- for (i=0; i<cam->num_frames; i++) {
- if(cam->buffers[i].status == FRAME_READY) {
- if(found < 0) {
- found = i;
- } else {
- /* find which buffer is earlier */
- struct timeval *tv1, *tv2;
- tv1 = &cam->buffers[i].timestamp;
- tv2 = &cam->buffers[found].timestamp;
- if(tv1->tv_sec < tv2->tv_sec ||
- (tv1->tv_sec == tv2->tv_sec &&
- tv1->tv_usec < tv2->tv_usec))
- found = i;
- }
- }
- }
- return found;
-}
-
-/******************************************************************************
- *
- * ioctl_dqbuf
- *
- * V4L2 User is asking for a filled buffer.
- *
- *****************************************************************************/
-
-static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
-{
- struct camera_data *cam = video_drvdata(file);
- int frame;
-
- if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- buf->memory != V4L2_MEMORY_MMAP)
- return -EINVAL;
-
- frame = find_earliest_filled_buffer(cam);
-
- if(frame < 0 && file->f_flags&O_NONBLOCK)
- return -EAGAIN;
-
- if(frame < 0) {
- /* Wait for a frame to become available */
- struct framebuf *cb=cam->curbuff;
- mutex_unlock(&cam->v4l2_lock);
- wait_event_interruptible(cam->wq_stream,
- !video_is_registered(&cam->vdev) ||
- (cb=cam->curbuff)->status == FRAME_READY);
- mutex_lock(&cam->v4l2_lock);
- if (signal_pending(current))
- return -ERESTARTSYS;
- if (!video_is_registered(&cam->vdev))
- return -ENOTTY;
- frame = cb->num;
- }
-
-
- buf->index = frame;
- buf->bytesused = cam->buffers[buf->index].length;
- buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
- buf->field = V4L2_FIELD_NONE;
- buf->timestamp = cam->buffers[buf->index].timestamp;
- buf->sequence = cam->buffers[buf->index].seq;
- buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
- buf->length = cam->frame_size;
- buf->reserved2 = 0;
- buf->reserved = 0;
- memset(&buf->timecode, 0, sizeof(buf->timecode));
-
- DBG("DQBUF #%d status:%d seq:%d length:%d\n", buf->index,
- cam->buffers[buf->index].status, buf->sequence, buf->bytesused);
-
- return 0;
-}
-
-static int cpia2_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
-{
- struct camera_data *cam = video_drvdata(file);
- int ret = -EINVAL;
-
- DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming);
- if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (!cam->streaming) {
- ret = cpia2_usb_stream_start(cam,
- cam->params.camera_state.stream_mode);
- if (!ret)
- v4l2_ctrl_grab(cam->usb_alt, true);
- }
- return ret;
-}
-
-static int cpia2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
-{
- struct camera_data *cam = video_drvdata(file);
- int ret = -EINVAL;
-
- DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming);
- if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (cam->streaming) {
- ret = cpia2_usb_stream_stop(cam);
- if (!ret)
- v4l2_ctrl_grab(cam->usb_alt, false);
- }
- return ret;
-}
-
-/******************************************************************************
- *
- * cpia2_mmap
- *
- *****************************************************************************/
-static int cpia2_mmap(struct file *file, struct vm_area_struct *area)
-{
- struct camera_data *cam = video_drvdata(file);
- int retval;
-
- retval = cpia2_remap_buffer(cam, area);
-
- if(!retval)
- cam->stream_fh = file->private_data;
- return retval;
-}
-
-/******************************************************************************
- *
- * reset_camera_struct_v4l
- *
- * Sets all values to the defaults
- *****************************************************************************/
-static void reset_camera_struct_v4l(struct camera_data *cam)
-{
- cam->width = cam->params.roi.width;
- cam->height = cam->params.roi.height;
-
- cam->frame_size = buffer_size;
- cam->num_frames = num_buffers;
-
- /* Flicker modes */
- cam->params.flicker_control.flicker_mode_req = flicker_mode;
-
- /* stream modes */
- cam->params.camera_state.stream_mode = alternate;
-
- cam->pixelformat = V4L2_PIX_FMT_JPEG;
-}
-
-static const struct v4l2_ioctl_ops cpia2_ioctl_ops = {
- .vidioc_querycap = cpia2_querycap,
- .vidioc_enum_input = cpia2_enum_input,
- .vidioc_g_input = cpia2_g_input,
- .vidioc_s_input = cpia2_s_input,
- .vidioc_enum_fmt_vid_cap = cpia2_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cpia2_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = cpia2_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cpia2_try_fmt_vid_cap,
- .vidioc_g_jpegcomp = cpia2_g_jpegcomp,
- .vidioc_s_jpegcomp = cpia2_s_jpegcomp,
- .vidioc_cropcap = cpia2_cropcap,
- .vidioc_reqbufs = cpia2_reqbufs,
- .vidioc_querybuf = cpia2_querybuf,
- .vidioc_qbuf = cpia2_qbuf,
- .vidioc_dqbuf = cpia2_dqbuf,
- .vidioc_streamon = cpia2_streamon,
- .vidioc_streamoff = cpia2_streamoff,
- .vidioc_s_parm = cpia2_s_parm,
- .vidioc_g_parm = cpia2_g_parm,
- .vidioc_enum_framesizes = cpia2_enum_framesizes,
- .vidioc_enum_frameintervals = cpia2_enum_frameintervals,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-/***
- * The v4l video device structure initialized for this device
- ***/
-static const struct v4l2_file_operations cpia2_fops = {
- .owner = THIS_MODULE,
- .open = cpia2_open,
- .release = cpia2_close,
- .read = cpia2_v4l_read,
- .poll = cpia2_v4l_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = cpia2_mmap,
-};
-
-static struct video_device cpia2_template = {
- /* I could not find any place for the old .initialize initializer?? */
- .name = "CPiA2 Camera",
- .fops = &cpia2_fops,
- .ioctl_ops = &cpia2_ioctl_ops,
- .release = video_device_release_empty,
-};
-
-void cpia2_camera_release(struct v4l2_device *v4l2_dev)
-{
- struct camera_data *cam =
- container_of(v4l2_dev, struct camera_data, v4l2_dev);
-
- v4l2_ctrl_handler_free(&cam->hdl);
- v4l2_device_unregister(&cam->v4l2_dev);
- kfree(cam);
-}
-
-static const struct v4l2_ctrl_ops cpia2_ctrl_ops = {
- .s_ctrl = cpia2_s_ctrl,
-};
-
-/******************************************************************************
- *
- * cpia2_register_camera
- *
- *****************************************************************************/
-int cpia2_register_camera(struct camera_data *cam)
-{
- struct v4l2_ctrl_handler *hdl = &cam->hdl;
- struct v4l2_ctrl_config cpia2_usb_alt = {
- .ops = &cpia2_ctrl_ops,
- .id = CPIA2_CID_USB_ALT,
- .name = "USB Alternate",
- .type = V4L2_CTRL_TYPE_INTEGER,
- .min = USBIF_ISO_1,
- .max = USBIF_ISO_6,
- .step = 1,
- };
- int ret;
-
- v4l2_ctrl_handler_init(hdl, 12);
- v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
- V4L2_CID_BRIGHTNESS,
- cam->params.pnp_id.device_type == DEVICE_STV_672 ? 1 : 0,
- 255, 1, DEFAULT_BRIGHTNESS);
- v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, DEFAULT_CONTRAST);
- v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, DEFAULT_SATURATION);
- v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
- V4L2_CID_JPEG_ACTIVE_MARKER, 0,
- V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
- V4L2_JPEG_ACTIVE_MARKER_DHT);
- v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
- V4L2_CID_JPEG_COMPRESSION_QUALITY, 1,
- 100, 1, 100);
- cpia2_usb_alt.def = alternate;
- cam->usb_alt = v4l2_ctrl_new_custom(hdl, &cpia2_usb_alt, NULL);
- /* VP5 Only */
- if (cam->params.pnp_id.device_type != DEVICE_STV_672)
- v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- /* Flicker control only valid for 672 */
- if (cam->params.pnp_id.device_type == DEVICE_STV_672)
- v4l2_ctrl_new_std_menu(hdl, &cpia2_ctrl_ops,
- V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0);
- /* Light control only valid for the QX5 Microscope */
- if (cam->params.pnp_id.product == 0x151) {
- cam->top_light = v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
- V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0);
- cam->bottom_light = v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
- V4L2_CID_ILLUMINATORS_2, 0, 1, 1, 0);
- v4l2_ctrl_cluster(2, &cam->top_light);
- }
-
- if (hdl->error) {
- ret = hdl->error;
- v4l2_ctrl_handler_free(hdl);
- return ret;
- }
-
- cam->vdev = cpia2_template;
- video_set_drvdata(&cam->vdev, cam);
- cam->vdev.lock = &cam->v4l2_lock;
- cam->vdev.ctrl_handler = hdl;
- cam->vdev.v4l2_dev = &cam->v4l2_dev;
- set_bit(V4L2_FL_USE_FH_PRIO, &cam->vdev.flags);
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &cam->vdev.flags);
-
- reset_camera_struct_v4l(cam);
-
- /* register v4l device */
- if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
- ERR("video_register_device failed\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-/******************************************************************************
- *
- * cpia2_unregister_camera
- *
- *****************************************************************************/
-void cpia2_unregister_camera(struct camera_data *cam)
-{
- video_unregister_device(&cam->vdev);
-}
-
-/******************************************************************************
- *
- * check_parameters
- *
- * Make sure that all user-supplied parameters are sensible
- *****************************************************************************/
-static void __init check_parameters(void)
-{
- if(buffer_size < PAGE_SIZE) {
- buffer_size = PAGE_SIZE;
- LOG("buffer_size too small, setting to %d\n", buffer_size);
- } else if(buffer_size > 1024*1024) {
- /* arbitrary upper limiit */
- buffer_size = 1024*1024;
- LOG("buffer_size ridiculously large, setting to %d\n",
- buffer_size);
- } else {
- buffer_size += PAGE_SIZE-1;
- buffer_size &= ~(PAGE_SIZE-1);
- }
-
- if(num_buffers < 1) {
- num_buffers = 1;
- LOG("num_buffers too small, setting to %d\n", num_buffers);
- } else if(num_buffers > VIDEO_MAX_FRAME) {
- num_buffers = VIDEO_MAX_FRAME;
- LOG("num_buffers too large, setting to %d\n", num_buffers);
- }
-
- if(alternate < USBIF_ISO_1 || alternate > USBIF_ISO_6) {
- alternate = DEFAULT_ALT;
- LOG("alternate specified is invalid, using %d\n", alternate);
- }
-
- if (flicker_mode != 0 && flicker_mode != FLICKER_50 && flicker_mode != FLICKER_60) {
- flicker_mode = 0;
- LOG("Flicker mode specified is invalid, using %d\n",
- flicker_mode);
- }
-
- DBG("Using %d buffers, each %d bytes, alternate=%d\n",
- num_buffers, buffer_size, alternate);
-}
-
-/************ Module Stuff ***************/
-
-
-/******************************************************************************
- *
- * cpia2_init/module_init
- *
- *****************************************************************************/
-static int __init cpia2_init(void)
-{
- LOG("%s v%s\n",
- ABOUT, CPIA_VERSION);
- check_parameters();
- cpia2_usb_init();
- return 0;
-}
-
-
-/******************************************************************************
- *
- * cpia2_exit/module_exit
- *
- *****************************************************************************/
-static void __exit cpia2_exit(void)
-{
- cpia2_usb_cleanup();
- schedule_timeout(2 * HZ);
-}
-
-module_init(cpia2_init);
-module_exit(cpia2_exit);
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
deleted file mode 100644
index c8581e26fa9..00000000000
--- a/drivers/media/video/cs5345.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * cs5345 Cirrus Logic 24-bit, 192 kHz Stereo Audio ADC
- * Copyright (C) 2007 Hans Verkuil
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-
-MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC");
-MODULE_AUTHOR("Hans Verkuil");
-MODULE_LICENSE("GPL");
-
-static bool debug;
-
-module_param(debug, bool, 0644);
-
-MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On");
-
-struct cs5345_state {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
-};
-
-static inline struct cs5345_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct cs5345_state, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct cs5345_state, hdl)->sd;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static inline int cs5345_write(struct v4l2_subdev *sd, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static inline int cs5345_read(struct v4l2_subdev *sd, u8 reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int cs5345_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- if ((input & 0xf) > 6) {
- v4l2_err(sd, "Invalid input %d.\n", input);
- return -EINVAL;
- }
- cs5345_write(sd, 0x09, input & 0xf);
- cs5345_write(sd, 0x05, input & 0xf0);
- return 0;
-}
-
-static int cs5345_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- cs5345_write(sd, 0x04, ctrl->val ? 0x80 : 0);
- return 0;
- case V4L2_CID_AUDIO_VOLUME:
- cs5345_write(sd, 0x07, ((u8)ctrl->val) & 0x3f);
- cs5345_write(sd, 0x08, ((u8)ctrl->val) & 0x3f);
- return 0;
- }
- return -EINVAL;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int cs5345_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- reg->size = 1;
- reg->val = cs5345_read(sd, reg->reg & 0x1f);
- return 0;
-}
-
-static int cs5345_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- cs5345_write(sd, reg->reg & 0x1f, reg->val & 0xff);
- return 0;
-}
-#endif
-
-static int cs5345_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_CS5345, 0);
-}
-
-static int cs5345_log_status(struct v4l2_subdev *sd)
-{
- u8 v = cs5345_read(sd, 0x09) & 7;
- u8 m = cs5345_read(sd, 0x04);
- int vol = cs5345_read(sd, 0x08) & 0x3f;
-
- v4l2_info(sd, "Input: %d%s\n", v,
- (m & 0x80) ? " (muted)" : "");
- if (vol >= 32)
- vol = vol - 64;
- v4l2_info(sd, "Volume: %d dB\n", vol);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_ctrl_ops cs5345_ctrl_ops = {
- .s_ctrl = cs5345_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops cs5345_core_ops = {
- .log_status = cs5345_log_status,
- .g_chip_ident = cs5345_g_chip_ident,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = cs5345_g_register,
- .s_register = cs5345_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_audio_ops cs5345_audio_ops = {
- .s_routing = cs5345_s_routing,
-};
-
-static const struct v4l2_subdev_ops cs5345_ops = {
- .core = &cs5345_core_ops,
- .audio = &cs5345_audio_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int cs5345_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct cs5345_state *state;
- struct v4l2_subdev *sd;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- state = kzalloc(sizeof(struct cs5345_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &cs5345_ops);
-
- v4l2_ctrl_handler_init(&state->hdl, 2);
- v4l2_ctrl_new_std(&state->hdl, &cs5345_ctrl_ops,
- V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&state->hdl, &cs5345_ctrl_ops,
- V4L2_CID_AUDIO_VOLUME, -24, 24, 1, 0);
- sd->ctrl_handler = &state->hdl;
- if (state->hdl.error) {
- int err = state->hdl.error;
-
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return err;
- }
- /* set volume/mute */
- v4l2_ctrl_handler_setup(&state->hdl);
-
- cs5345_write(sd, 0x02, 0x00);
- cs5345_write(sd, 0x04, 0x01);
- cs5345_write(sd, 0x09, 0x01);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int cs5345_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct cs5345_state *state = to_state(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id cs5345_id[] = {
- { "cs5345", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, cs5345_id);
-
-static struct i2c_driver cs5345_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "cs5345",
- },
- .probe = cs5345_probe,
- .remove = cs5345_remove,
- .id_table = cs5345_id,
-};
-
-module_i2c_driver(cs5345_driver);
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
deleted file mode 100644
index b293912206e..00000000000
--- a/drivers/media/video/cs53l32a.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * cs53l32a (Adaptec AVC-2010 and AVC-2410) i2c ivtv driver.
- * Copyright (C) 2005 Martin Vaughan
- *
- * Audio source switching for Adaptec AVC-2410 added by Trev Jackson
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-
-MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
-MODULE_AUTHOR("Martin Vaughan");
-MODULE_LICENSE("GPL");
-
-static bool debug;
-
-module_param(debug, bool, 0644);
-
-MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On");
-
-
-struct cs53l32a_state {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
-};
-
-static inline struct cs53l32a_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct cs53l32a_state, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct cs53l32a_state, hdl)->sd;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int cs53l32a_write(struct v4l2_subdev *sd, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static int cs53l32a_read(struct v4l2_subdev *sd, u8 reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int cs53l32a_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- /* There are 2 physical inputs, but the second input can be
- placed in two modes, the first mode bypasses the PGA (gain),
- the second goes through the PGA. Hence there are three
- possible inputs to choose from. */
- if (input > 2) {
- v4l2_err(sd, "Invalid input %d.\n", input);
- return -EINVAL;
- }
- cs53l32a_write(sd, 0x01, 0x01 + (input << 4));
- return 0;
-}
-
-static int cs53l32a_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- cs53l32a_write(sd, 0x03, ctrl->val ? 0xf0 : 0x30);
- return 0;
- case V4L2_CID_AUDIO_VOLUME:
- cs53l32a_write(sd, 0x04, (u8)ctrl->val);
- cs53l32a_write(sd, 0x05, (u8)ctrl->val);
- return 0;
- }
- return -EINVAL;
-}
-
-static int cs53l32a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client,
- chip, V4L2_IDENT_CS53l32A, 0);
-}
-
-static int cs53l32a_log_status(struct v4l2_subdev *sd)
-{
- struct cs53l32a_state *state = to_state(sd);
- u8 v = cs53l32a_read(sd, 0x01);
-
- v4l2_info(sd, "Input: %d\n", (v >> 4) & 3);
- v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_ctrl_ops cs53l32a_ctrl_ops = {
- .s_ctrl = cs53l32a_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops cs53l32a_core_ops = {
- .log_status = cs53l32a_log_status,
- .g_chip_ident = cs53l32a_g_chip_ident,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
-};
-
-static const struct v4l2_subdev_audio_ops cs53l32a_audio_ops = {
- .s_routing = cs53l32a_s_routing,
-};
-
-static const struct v4l2_subdev_ops cs53l32a_ops = {
- .core = &cs53l32a_core_ops,
- .audio = &cs53l32a_audio_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-/* i2c implementation */
-
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-
-static int cs53l32a_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct cs53l32a_state *state;
- struct v4l2_subdev *sd;
- int i;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- if (!id)
- strlcpy(client->name, "cs53l32a", sizeof(client->name));
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- state = kzalloc(sizeof(struct cs53l32a_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &cs53l32a_ops);
-
- for (i = 1; i <= 7; i++) {
- u8 v = cs53l32a_read(sd, i);
-
- v4l2_dbg(1, debug, sd, "Read Reg %d %02x\n", i, v);
- }
-
- v4l2_ctrl_handler_init(&state->hdl, 2);
- v4l2_ctrl_new_std(&state->hdl, &cs53l32a_ctrl_ops,
- V4L2_CID_AUDIO_VOLUME, -96, 12, 1, 0);
- v4l2_ctrl_new_std(&state->hdl, &cs53l32a_ctrl_ops,
- V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
- sd->ctrl_handler = &state->hdl;
- if (state->hdl.error) {
- int err = state->hdl.error;
-
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return err;
- }
-
- /* Set cs53l32a internal register for Adaptec 2010/2410 setup */
-
- cs53l32a_write(sd, 0x01, 0x21);
- cs53l32a_write(sd, 0x02, 0x29);
- cs53l32a_write(sd, 0x03, 0x30);
- cs53l32a_write(sd, 0x04, 0x00);
- cs53l32a_write(sd, 0x05, 0x00);
- cs53l32a_write(sd, 0x06, 0x00);
- cs53l32a_write(sd, 0x07, 0x00);
-
- /* Display results, should be 0x21,0x29,0x30,0x00,0x00,0x00,0x00 */
-
- for (i = 1; i <= 7; i++) {
- u8 v = cs53l32a_read(sd, i);
-
- v4l2_dbg(1, debug, sd, "Read Reg %d %02x\n", i, v);
- }
- return 0;
-}
-
-static int cs53l32a_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct cs53l32a_state *state = to_state(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return 0;
-}
-
-static const struct i2c_device_id cs53l32a_id[] = {
- { "cs53l32a", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, cs53l32a_id);
-
-static struct i2c_driver cs53l32a_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "cs53l32a",
- },
- .probe = cs53l32a_probe,
- .remove = cs53l32a_remove,
- .id_table = cs53l32a_id,
-};
-
-module_i2c_driver(cs53l32a_driver);
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
deleted file mode 100644
index 53b3c770257..00000000000
--- a/drivers/media/video/cx18/Kconfig
+++ /dev/null
@@ -1,35 +0,0 @@
-config VIDEO_CX18
- tristate "Conexant cx23418 MPEG encoder support"
- depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
- select I2C_ALGOBIT
- select VIDEOBUF_VMALLOC
- depends on RC_CORE
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- select VIDEO_CX2341X
- select VIDEO_CS5345
- select DVB_S5H1409 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
- select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
- ---help---
- This is a video4linux driver for Conexant cx23418 based
- PCI combo video recorder devices.
-
- This is used in devices such as the Hauppauge HVR-1600
- cards.
-
- To compile this driver as a module, choose M here: the
- module will be called cx18.
-
-config VIDEO_CX18_ALSA
- tristate "Conexant 23418 DMA audio support"
- depends on VIDEO_CX18 && SND && EXPERIMENTAL
- select SND_PCM
- ---help---
- This is a video4linux driver for direct (DMA) audio on
- Conexant 23418 based TV cards using ALSA.
-
- To compile this driver as a module, choose M here: the
- module will be called cx18-alsa.
diff --git a/drivers/media/video/cx18/Makefile b/drivers/media/video/cx18/Makefile
deleted file mode 100644
index a86bab5893e..00000000000
--- a/drivers/media/video/cx18/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-cx18-objs := cx18-driver.o cx18-cards.o cx18-i2c.o cx18-firmware.o cx18-gpio.o \
- cx18-queue.o cx18-streams.o cx18-fileops.o cx18-ioctl.o cx18-controls.o \
- cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \
- cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \
- cx18-dvb.o cx18-io.o
-cx18-alsa-objs := cx18-alsa-main.o cx18-alsa-pcm.o
-
-obj-$(CONFIG_VIDEO_CX18) += cx18.o
-obj-$(CONFIG_VIDEO_CX18_ALSA) += cx18-alsa.o
-
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
-ccflags-y += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/video/cx18/cx18-alsa-main.c
deleted file mode 100644
index 6d2a98246b6..00000000000
--- a/drivers/media/video/cx18/cx18-alsa-main.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * ALSA interface to cx18 PCM capture streams
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
- *
- * Portions of this work were sponsored by ONELAN Limited.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/spinlock.h>
-
-#include <media/v4l2-device.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-
-#include "cx18-driver.h"
-#include "cx18-version.h"
-#include "cx18-alsa.h"
-#include "cx18-alsa-mixer.h"
-#include "cx18-alsa-pcm.h"
-
-int cx18_alsa_debug;
-
-#define CX18_DEBUG_ALSA_INFO(fmt, arg...) \
- do { \
- if (cx18_alsa_debug & 2) \
- printk(KERN_INFO "%s: " fmt, "cx18-alsa", ## arg); \
- } while (0);
-
-module_param_named(debug, cx18_alsa_debug, int, 0644);
-MODULE_PARM_DESC(debug,
- "Debug level (bitmask). Default: 0\n"
- "\t\t\t 1/0x0001: warning\n"
- "\t\t\t 2/0x0002: info\n");
-
-MODULE_AUTHOR("Andy Walls");
-MODULE_DESCRIPTION("CX23418 ALSA Interface");
-MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder");
-MODULE_LICENSE("GPL");
-
-MODULE_VERSION(CX18_VERSION);
-
-static inline
-struct snd_cx18_card *to_snd_cx18_card(struct v4l2_device *v4l2_dev)
-{
- return to_cx18(v4l2_dev)->alsa;
-}
-
-static inline
-struct snd_cx18_card *p_to_snd_cx18_card(struct v4l2_device **v4l2_dev)
-{
- return container_of(v4l2_dev, struct snd_cx18_card, v4l2_dev);
-}
-
-static void snd_cx18_card_free(struct snd_cx18_card *cxsc)
-{
- if (cxsc == NULL)
- return;
-
- if (cxsc->v4l2_dev != NULL)
- to_cx18(cxsc->v4l2_dev)->alsa = NULL;
-
- /* FIXME - take any other stopping actions needed */
-
- kfree(cxsc);
-}
-
-static void snd_cx18_card_private_free(struct snd_card *sc)
-{
- if (sc == NULL)
- return;
- snd_cx18_card_free(sc->private_data);
- sc->private_data = NULL;
- sc->private_free = NULL;
-}
-
-static int snd_cx18_card_create(struct v4l2_device *v4l2_dev,
- struct snd_card *sc,
- struct snd_cx18_card **cxsc)
-{
- *cxsc = kzalloc(sizeof(struct snd_cx18_card), GFP_KERNEL);
- if (*cxsc == NULL)
- return -ENOMEM;
-
- (*cxsc)->v4l2_dev = v4l2_dev;
- (*cxsc)->sc = sc;
-
- sc->private_data = *cxsc;
- sc->private_free = snd_cx18_card_private_free;
-
- return 0;
-}
-
-static int snd_cx18_card_set_names(struct snd_cx18_card *cxsc)
-{
- struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
- struct snd_card *sc = cxsc->sc;
-
- /* sc->driver is used by alsa-lib's configurator: simple, unique */
- strlcpy(sc->driver, "CX23418", sizeof(sc->driver));
-
- /* sc->shortname is a symlink in /proc/asound: CX18-M -> cardN */
- snprintf(sc->shortname, sizeof(sc->shortname), "CX18-%d",
- cx->instance);
-
- /* sc->longname is read from /proc/asound/cards */
- snprintf(sc->longname, sizeof(sc->longname),
- "CX23418 #%d %s TV/FM Radio/Line-In Capture",
- cx->instance, cx->card_name);
-
- return 0;
-}
-
-static int snd_cx18_init(struct v4l2_device *v4l2_dev)
-{
- struct cx18 *cx = to_cx18(v4l2_dev);
- struct snd_card *sc = NULL;
- struct snd_cx18_card *cxsc;
- int ret;
-
- /* Numbrs steps from "Writing an ALSA Driver" by Takashi Iwai */
-
- /* (1) Check and increment the device index */
- /* This is a no-op for us. We'll use the cx->instance */
-
- /* (2) Create a card instance */
- ret = snd_card_create(SNDRV_DEFAULT_IDX1, /* use first available id */
- SNDRV_DEFAULT_STR1, /* xid from end of shortname*/
- THIS_MODULE, 0, &sc);
- if (ret) {
- CX18_ALSA_ERR("%s: snd_card_create() failed with err %d\n",
- __func__, ret);
- goto err_exit;
- }
-
- /* (3) Create a main component */
- ret = snd_cx18_card_create(v4l2_dev, sc, &cxsc);
- if (ret) {
- CX18_ALSA_ERR("%s: snd_cx18_card_create() failed with err %d\n",
- __func__, ret);
- goto err_exit_free;
- }
-
- /* (4) Set the driver ID and name strings */
- snd_cx18_card_set_names(cxsc);
-
-
- ret = snd_cx18_pcm_create(cxsc);
- if (ret) {
- CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
- __func__, ret);
- goto err_exit_free;
- }
- /* FIXME - proc files */
-
- /* (7) Set the driver data and return 0 */
- /* We do this out of normal order for PCI drivers to avoid races */
- cx->alsa = cxsc;
-
- /* (6) Register the card instance */
- ret = snd_card_register(sc);
- if (ret) {
- cx->alsa = NULL;
- CX18_ALSA_ERR("%s: snd_card_register() failed with err %d\n",
- __func__, ret);
- goto err_exit_free;
- }
-
- return 0;
-
-err_exit_free:
- if (sc != NULL)
- snd_card_free(sc);
- kfree(cxsc);
-err_exit:
- return ret;
-}
-
-int cx18_alsa_load(struct cx18 *cx)
-{
- struct v4l2_device *v4l2_dev = &cx->v4l2_dev;
- struct cx18_stream *s;
-
- if (v4l2_dev == NULL) {
- printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
- __func__);
- return 0;
- }
-
- cx = to_cx18(v4l2_dev);
- if (cx == NULL) {
- printk(KERN_ERR "cx18-alsa cx is NULL\n");
- return 0;
- }
-
- s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
- if (s->video_dev == NULL) {
- CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - "
- "skipping\n", __func__);
- return 0;
- }
-
- if (cx->alsa != NULL) {
- CX18_ALSA_ERR("%s: struct snd_cx18_card * already exists\n",
- __func__);
- return 0;
- }
-
- if (snd_cx18_init(v4l2_dev)) {
- CX18_ALSA_ERR("%s: failed to create struct snd_cx18_card\n",
- __func__);
- } else {
- CX18_DEBUG_ALSA_INFO("%s: created cx18 ALSA interface instance "
- "\n", __func__);
- }
- return 0;
-}
-
-static int __init cx18_alsa_init(void)
-{
- printk(KERN_INFO "cx18-alsa: module loading...\n");
- cx18_ext_init = &cx18_alsa_load;
- return 0;
-}
-
-static void __exit snd_cx18_exit(struct snd_cx18_card *cxsc)
-{
- struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
-
- /* FIXME - pointer checks & shutdown cxsc */
-
- snd_card_free(cxsc->sc);
- cx->alsa = NULL;
-}
-
-static int __exit cx18_alsa_exit_callback(struct device *dev, void *data)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
- struct snd_cx18_card *cxsc;
-
- if (v4l2_dev == NULL) {
- printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
- __func__);
- return 0;
- }
-
- cxsc = to_snd_cx18_card(v4l2_dev);
- if (cxsc == NULL) {
- CX18_ALSA_WARN("%s: struct snd_cx18_card * is NULL\n",
- __func__);
- return 0;
- }
-
- snd_cx18_exit(cxsc);
- return 0;
-}
-
-static void __exit cx18_alsa_exit(void)
-{
- struct device_driver *drv;
- int ret;
-
- printk(KERN_INFO "cx18-alsa: module unloading...\n");
-
- drv = driver_find("cx18", &pci_bus_type);
- ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback);
- (void)ret; /* suppress compiler warning */
-
- cx18_ext_init = NULL;
- printk(KERN_INFO "cx18-alsa: module unload complete\n");
-}
-
-module_init(cx18_alsa_init);
-module_exit(cx18_alsa_exit);
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.c b/drivers/media/video/cx18/cx18-alsa-mixer.c
deleted file mode 100644
index 341bddc00b7..00000000000
--- a/drivers/media/video/cx18/cx18-alsa-mixer.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * ALSA mixer controls for the
- * ALSA interface to cx18 PCM capture streams
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/spinlock.h>
-#include <linux/videodev2.h>
-
-#include <media/v4l2-device.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-
-#include "cx18-alsa.h"
-#include "cx18-driver.h"
-
-/*
- * Note the cx18-av-core volume scale is funny, due to the alignment of the
- * scale with another chip's range:
- *
- * v4l2_control value /512 indicated dB actual dB reg 0x8d4
- * 0x0000 - 0x01ff 0 -119 -96 228
- * 0x0200 - 0x02ff 1 -118 -96 228
- * ...
- * 0x2c00 - 0x2dff 22 -97 -96 228
- * 0x2e00 - 0x2fff 23 -96 -96 228
- * 0x3000 - 0x31ff 24 -95 -95 226
- * ...
- * 0xee00 - 0xefff 119 0 0 36
- * ...
- * 0xfe00 - 0xffff 127 +8 +8 20
- */
-static inline int dB_to_cx18_av_vol(int dB)
-{
- if (dB < -96)
- dB = -96;
- else if (dB > 8)
- dB = 8;
- return (dB + 119) << 9;
-}
-
-static inline int cx18_av_vol_to_dB(int v)
-{
- if (v < (23 << 9))
- v = (23 << 9);
- else if (v > (127 << 9))
- v = (127 << 9);
- return (v >> 9) - 119;
-}
-
-static int snd_cx18_mixer_tv_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- /* We're already translating values, just keep this control in dB */
- uinfo->value.integer.min = -96;
- uinfo->value.integer.max = 8;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-static int snd_cx18_mixer_tv_vol_get(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl);
- struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
- struct v4l2_control vctrl;
- int ret;
-
- vctrl.id = V4L2_CID_AUDIO_VOLUME;
- vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
-
- snd_cx18_lock(cxsc);
- ret = v4l2_subdev_call(cx->sd_av, core, g_ctrl, &vctrl);
- snd_cx18_unlock(cxsc);
-
- if (!ret)
- uctl->value.integer.value[0] = cx18_av_vol_to_dB(vctrl.value);
- return ret;
-}
-
-static int snd_cx18_mixer_tv_vol_put(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl);
- struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
- struct v4l2_control vctrl;
- int ret;
-
- vctrl.id = V4L2_CID_AUDIO_VOLUME;
- vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
-
- snd_cx18_lock(cxsc);
-
- /* Fetch current state */
- ret = v4l2_subdev_call(cx->sd_av, core, g_ctrl, &vctrl);
-
- if (ret ||
- (cx18_av_vol_to_dB(vctrl.value) != uctl->value.integer.value[0])) {
-
- /* Set, if needed */
- vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
- ret = v4l2_subdev_call(cx->sd_av, core, s_ctrl, &vctrl);
- if (!ret)
- ret = 1; /* Indicate control was changed w/o error */
- }
- snd_cx18_unlock(cxsc);
-
- return ret;
-}
-
-
-/* This is a bit of overkill, the slider is already in dB internally */
-static DECLARE_TLV_DB_SCALE(snd_cx18_mixer_tv_vol_db_scale, -9600, 100, 0);
-
-static struct snd_kcontrol_new snd_cx18_mixer_tv_vol __initdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog TV Capture Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = snd_cx18_mixer_tv_volume_info,
- .get = snd_cx18_mixer_tv_volume_get,
- .put = snd_cx18_mixer_tv_volume_put,
- .tlv.p = snd_cx18_mixer_tv_vol_db_scale
-};
-
-/* FIXME - add mute switch and balance, bass, treble sliders:
- V4L2_CID_AUDIO_MUTE
-
- V4L2_CID_AUDIO_BALANCE
-
- V4L2_CID_AUDIO_BASS
- V4L2_CID_AUDIO_TREBLE
-*/
-
-/* FIXME - add stereo, lang1, lang2, mono menu */
-/* FIXME - add CS5345 I2S volume for HVR-1600 */
-
-int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc)
-{
- struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
- struct snd_card *sc = cxsc->sc;
- int ret;
-
- strlcpy(sc->mixername, "CX23418 Mixer", sizeof(sc->mixername));
-
- ret = snd_ctl_add(sc, snd_ctl_new1(snd_cx18_mixer_tv_vol, cxsc));
- if (ret) {
- CX18_ALSA_WARN("%s: failed to add %s control, err %d\n",
- __func__, snd_cx18_mixer_tv_vol.name, ret);
- }
- return ret;
-}
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.h b/drivers/media/video/cx18/cx18-alsa-mixer.h
deleted file mode 100644
index ec9238793f6..00000000000
--- a/drivers/media/video/cx18/cx18-alsa-mixer.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * ALSA mixer controls for the
- * ALSA interface to cx18 PCM capture streams
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc);
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/video/cx18/cx18-alsa-pcm.c
deleted file mode 100644
index 7a5b84a86bb..00000000000
--- a/drivers/media/video/cx18/cx18-alsa-pcm.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * ALSA PCM device for the
- * ALSA interface to cx18 PCM capture streams
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
- *
- * Portions of this work were sponsored by ONELAN Limited.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/vmalloc.h>
-
-#include <media/v4l2-device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "cx18-driver.h"
-#include "cx18-queue.h"
-#include "cx18-streams.h"
-#include "cx18-fileops.h"
-#include "cx18-alsa.h"
-
-static unsigned int pcm_debug;
-module_param(pcm_debug, int, 0644);
-MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm");
-
-#define dprintk(fmt, arg...) do { \
- if (pcm_debug) \
- printk(KERN_INFO "cx18-alsa-pcm %s: " fmt, \
- __func__, ##arg); \
- } while (0)
-
-static struct snd_pcm_hardware snd_cx18_hw_capture = {
- .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID,
-
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
-
- .rates = SNDRV_PCM_RATE_48000,
-
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */
- .period_bytes_min = 64, /* 12544/2, */
- .period_bytes_max = 12544,
- .periods_min = 2,
- .periods_max = 98, /* 12544, */
-};
-
-void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data,
- size_t num_bytes)
-{
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- unsigned int oldptr;
- unsigned int stride;
- int period_elapsed = 0;
- int length;
-
- dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%zd\n", cxsc,
- pcm_data, num_bytes);
-
- substream = cxsc->capture_pcm_substream;
- if (substream == NULL) {
- dprintk("substream was NULL\n");
- return;
- }
-
- runtime = substream->runtime;
- if (runtime == NULL) {
- dprintk("runtime was NULL\n");
- return;
- }
-
- stride = runtime->frame_bits >> 3;
- if (stride == 0) {
- dprintk("stride is zero\n");
- return;
- }
-
- length = num_bytes / stride;
- if (length == 0) {
- dprintk("%s: length was zero\n", __func__);
- return;
- }
-
- if (runtime->dma_area == NULL) {
- dprintk("dma area was NULL - ignoring\n");
- return;
- }
-
- oldptr = cxsc->hwptr_done_capture;
- if (oldptr + length >= runtime->buffer_size) {
- unsigned int cnt =
- runtime->buffer_size - oldptr;
- memcpy(runtime->dma_area + oldptr * stride, pcm_data,
- cnt * stride);
- memcpy(runtime->dma_area, pcm_data + cnt * stride,
- length * stride - cnt * stride);
- } else {
- memcpy(runtime->dma_area + oldptr * stride, pcm_data,
- length * stride);
- }
- snd_pcm_stream_lock(substream);
-
- cxsc->hwptr_done_capture += length;
- if (cxsc->hwptr_done_capture >=
- runtime->buffer_size)
- cxsc->hwptr_done_capture -=
- runtime->buffer_size;
-
- cxsc->capture_transfer_done += length;
- if (cxsc->capture_transfer_done >=
- runtime->period_size) {
- cxsc->capture_transfer_done -=
- runtime->period_size;
- period_elapsed = 1;
- }
-
- snd_pcm_stream_unlock(substream);
-
- if (period_elapsed)
- snd_pcm_period_elapsed(substream);
-}
-
-static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
- struct cx18 *cx = to_cx18(v4l2_dev);
- struct cx18_stream *s;
- struct cx18_open_id item;
- int ret;
-
- /* Instruct the cx18 to start sending packets */
- snd_cx18_lock(cxsc);
- s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
-
- item.cx = cx;
- item.type = s->type;
- item.open_id = cx->open_id++;
-
- /* See if the stream is available */
- if (cx18_claim_stream(&item, item.type)) {
- /* No, it's already in use */
- snd_cx18_unlock(cxsc);
- return -EBUSY;
- }
-
- if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
- test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
- /* We're already streaming. No additional action required */
- snd_cx18_unlock(cxsc);
- return 0;
- }
-
-
- runtime->hw = snd_cx18_hw_capture;
- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- cxsc->capture_pcm_substream = substream;
- runtime->private_data = cx;
-
- cx->pcm_announce_callback = cx18_alsa_announce_pcm_data;
-
- /* Not currently streaming, so start it up */
- set_bit(CX18_F_S_STREAMING, &s->s_flags);
- ret = cx18_start_v4l2_encode_stream(s);
- snd_cx18_unlock(cxsc);
-
- return ret;
-}
-
-static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
- struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
- struct cx18 *cx = to_cx18(v4l2_dev);
- struct cx18_stream *s;
-
- /* Instruct the cx18 to stop sending packets */
- snd_cx18_lock(cxsc);
- s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
- cx18_stop_v4l2_encode_stream(s, 0);
- clear_bit(CX18_F_S_STREAMING, &s->s_flags);
-
- cx18_release_stream(s);
-
- cx->pcm_announce_callback = NULL;
- snd_cx18_unlock(cxsc);
-
- return 0;
-}
-
-static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream,
- unsigned int cmd, void *arg)
-{
- struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
- int ret;
-
- snd_cx18_lock(cxsc);
- ret = snd_pcm_lib_ioctl(substream, cmd, arg);
- snd_cx18_unlock(cxsc);
- return ret;
-}
-
-
-static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
- size_t size)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
-
- dprintk("Allocating vbuffer\n");
- if (runtime->dma_area) {
- if (runtime->dma_bytes > size)
- return 0;
-
- vfree(runtime->dma_area);
- }
- runtime->dma_area = vmalloc(size);
- if (!runtime->dma_area)
- return -ENOMEM;
-
- runtime->dma_bytes = size;
-
- return 0;
-}
-
-static int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- dprintk("%s called\n", __func__);
-
- return snd_pcm_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(params));
-}
-
-static int snd_cx18_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
- unsigned long flags;
-
- spin_lock_irqsave(&cxsc->slock, flags);
- if (substream->runtime->dma_area) {
- dprintk("freeing pcm capture region\n");
- vfree(substream->runtime->dma_area);
- substream->runtime->dma_area = NULL;
- }
- spin_unlock_irqrestore(&cxsc->slock, flags);
-
- return 0;
-}
-
-static int snd_cx18_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
-
- cxsc->hwptr_done_capture = 0;
- cxsc->capture_transfer_done = 0;
-
- return 0;
-}
-
-static int snd_cx18_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- return 0;
-}
-
-static
-snd_pcm_uframes_t snd_cx18_pcm_pointer(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- snd_pcm_uframes_t hwptr_done;
- struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
-
- spin_lock_irqsave(&cxsc->slock, flags);
- hwptr_done = cxsc->hwptr_done_capture;
- spin_unlock_irqrestore(&cxsc->slock, flags);
-
- return hwptr_done;
-}
-
-static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
- unsigned long offset)
-{
- void *pageptr = subs->runtime->dma_area + offset;
-
- return vmalloc_to_page(pageptr);
-}
-
-static struct snd_pcm_ops snd_cx18_pcm_capture_ops = {
- .open = snd_cx18_pcm_capture_open,
- .close = snd_cx18_pcm_capture_close,
- .ioctl = snd_cx18_pcm_ioctl,
- .hw_params = snd_cx18_pcm_hw_params,
- .hw_free = snd_cx18_pcm_hw_free,
- .prepare = snd_cx18_pcm_prepare,
- .trigger = snd_cx18_pcm_trigger,
- .pointer = snd_cx18_pcm_pointer,
- .page = snd_pcm_get_vmalloc_page,
-};
-
-int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
-{
- struct snd_pcm *sp;
- struct snd_card *sc = cxsc->sc;
- struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
- struct cx18 *cx = to_cx18(v4l2_dev);
- int ret;
-
- ret = snd_pcm_new(sc, "CX23418 PCM",
- 0, /* PCM device 0, the only one for this card */
- 0, /* 0 playback substreams */
- 1, /* 1 capture substream */
- &sp);
- if (ret) {
- CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
- __func__, ret);
- goto err_exit;
- }
-
- spin_lock_init(&cxsc->slock);
-
- snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
- &snd_cx18_pcm_capture_ops);
- sp->info_flags = 0;
- sp->private_data = cxsc;
- strlcpy(sp->name, cx->card_name, sizeof(sp->name));
-
- return 0;
-
-err_exit:
- return ret;
-}
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.h b/drivers/media/video/cx18/cx18-alsa-pcm.h
deleted file mode 100644
index d26e51f9457..00000000000
--- a/drivers/media/video/cx18/cx18-alsa-pcm.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * ALSA PCM device for the
- * ALSA interface to cx18 PCM capture streams
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-int __init snd_cx18_pcm_create(struct snd_cx18_card *cxsc);
-
-/* Used by cx18-mailbox to announce the PCM data to the module */
-void cx18_alsa_announce_pcm_data(struct snd_cx18_card *card, u8 *pcm_data,
- size_t num_bytes);
diff --git a/drivers/media/video/cx18/cx18-alsa.h b/drivers/media/video/cx18/cx18-alsa.h
deleted file mode 100644
index 447da374c9e..00000000000
--- a/drivers/media/video/cx18/cx18-alsa.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * ALSA interface to cx18 PCM capture streams
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-struct snd_card;
-
-struct snd_cx18_card {
- struct v4l2_device *v4l2_dev;
- struct snd_card *sc;
- unsigned int capture_transfer_done;
- unsigned int hwptr_done_capture;
- struct snd_pcm_substream *capture_pcm_substream;
- spinlock_t slock;
-};
-
-extern int cx18_alsa_debug;
-
-/*
- * File operations that manipulate the encoder or video or audio subdevices
- * need to be serialized. Use the same lock we use for v4l2 file ops.
- */
-static inline void snd_cx18_lock(struct snd_cx18_card *cxsc)
-{
- struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
- mutex_lock(&cx->serialize_lock);
-}
-
-static inline void snd_cx18_unlock(struct snd_cx18_card *cxsc)
-{
- struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
- mutex_unlock(&cx->serialize_lock);
-}
-
-#define CX18_ALSA_DBGFLG_WARN (1 << 0)
-#define CX18_ALSA_DBGFLG_WARN (1 << 0)
-#define CX18_ALSA_DBGFLG_INFO (1 << 1)
-
-#define CX18_ALSA_DEBUG(x, type, fmt, args...) \
- do { \
- if ((x) & cx18_alsa_debug) \
- printk(KERN_INFO "%s-alsa: " type ": " fmt, \
- v4l2_dev->name , ## args); \
- } while (0)
-
-#define CX18_ALSA_DEBUG_WARN(fmt, args...) \
- CX18_ALSA_DEBUG(CX18_ALSA_DBGFLG_WARN, "warning", fmt , ## args)
-
-#define CX18_ALSA_DEBUG_INFO(fmt, args...) \
- CX18_ALSA_DEBUG(CX18_ALSA_DBGFLG_INFO, "info", fmt , ## args)
-
-#define CX18_ALSA_ERR(fmt, args...) \
- printk(KERN_ERR "%s-alsa: " fmt, v4l2_dev->name , ## args)
-
-#define CX18_ALSA_WARN(fmt, args...) \
- printk(KERN_WARNING "%s-alsa: " fmt, v4l2_dev->name , ## args)
-
-#define CX18_ALSA_INFO(fmt, args...) \
- printk(KERN_INFO "%s-alsa: " fmt, v4l2_dev->name , ## args)
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
deleted file mode 100644
index 35268923911..00000000000
--- a/drivers/media/video/cx18/cx18-audio.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * cx18 audio-related functions
- *
- * Derived from ivtv-audio.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-cards.h"
-#include "cx18-audio.h"
-
-#define CX18_AUDIO_ENABLE 0xc72014
-#define CX18_AI1_MUX_MASK 0x30
-#define CX18_AI1_MUX_I2S1 0x00
-#define CX18_AI1_MUX_I2S2 0x10
-#define CX18_AI1_MUX_843_I2S 0x20
-
-/* Selects the audio input and output according to the current
- settings. */
-int cx18_audio_set_io(struct cx18 *cx)
-{
- const struct cx18_card_audio_input *in;
- u32 u, v;
- int err;
-
- /* Determine which input to use */
- if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
- in = &cx->card->radio_input;
- else
- in = &cx->card->audio_inputs[cx->audio_input];
-
- /* handle muxer chips */
- v4l2_subdev_call(cx->sd_extmux, audio, s_routing,
- (u32) in->muxer_input, 0, 0);
-
- err = cx18_call_hw_err(cx, cx->card->hw_audio_ctrl,
- audio, s_routing, in->audio_input, 0, 0);
- if (err)
- return err;
-
- /* FIXME - this internal mux should be abstracted to a subdev */
- u = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
- v = u & ~CX18_AI1_MUX_MASK;
- switch (in->audio_input) {
- case CX18_AV_AUDIO_SERIAL1:
- v |= CX18_AI1_MUX_I2S1;
- break;
- case CX18_AV_AUDIO_SERIAL2:
- v |= CX18_AI1_MUX_I2S2;
- break;
- default:
- v |= CX18_AI1_MUX_843_I2S;
- break;
- }
- if (v == u) {
- /* force a toggle of some AI1 MUX control bits */
- u &= ~CX18_AI1_MUX_MASK;
- switch (in->audio_input) {
- case CX18_AV_AUDIO_SERIAL1:
- u |= CX18_AI1_MUX_843_I2S;
- break;
- case CX18_AV_AUDIO_SERIAL2:
- u |= CX18_AI1_MUX_843_I2S;
- break;
- default:
- u |= CX18_AI1_MUX_I2S1;
- break;
- }
- cx18_write_reg_expect(cx, u | 0xb00, CX18_AUDIO_ENABLE,
- u, CX18_AI1_MUX_MASK);
- }
- cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
- v, CX18_AI1_MUX_MASK);
- return 0;
-}
diff --git a/drivers/media/video/cx18/cx18-audio.h b/drivers/media/video/cx18/cx18-audio.h
deleted file mode 100644
index 2731d29b0ab..00000000000
--- a/drivers/media/video/cx18/cx18-audio.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * cx18 audio-related functions
- *
- * Derived from ivtv-audio.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-int cx18_audio_set_io(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c
deleted file mode 100644
index 4a24ffb17a7..00000000000
--- a/drivers/media/video/cx18/cx18-av-audio.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
- * cx18 ADEC audio functions
- *
- * Derived from cx25840-audio.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include "cx18-driver.h"
-
-static int set_audclk_freq(struct cx18 *cx, u32 freq)
-{
- struct cx18_av_state *state = &cx->av_state;
-
- if (freq != 32000 && freq != 44100 && freq != 48000)
- return -EINVAL;
-
- /*
- * The PLL parameters are based on the external crystal frequency that
- * would ideally be:
- *
- * NTSC Color subcarrier freq * 8 =
- * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
- *
- * The accidents of history and rationale that explain from where this
- * combination of magic numbers originate can be found in:
- *
- * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in
- * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80
- *
- * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the
- * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83
- *
- * As Mike Bradley has rightly pointed out, it's not the exact crystal
- * frequency that matters, only that all parts of the driver and
- * firmware are using the same value (close to the ideal value).
- *
- * Since I have a strong suspicion that, if the firmware ever assumes a
- * crystal value at all, it will assume 28.636360 MHz, the crystal
- * freq used in calculations in this driver will be:
- *
- * xtal_freq = 28.636360 MHz
- *
- * an error of less than 0.13 ppm which is way, way better than any off
- * the shelf crystal will have for accuracy anyway.
- *
- * Below I aim to run the PLLs' VCOs near 400 MHz to minimze error.
- *
- * Many thanks to Jeff Campbell and Mike Bradley for their extensive
- * investigation, experimentation, testing, and suggested solutions of
- * of audio/video sync problems with SVideo and CVBS captures.
- */
-
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- switch (freq) {
- case 32000:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x20
- */
- cx18_av_write4(cx, 0x108, 0x200d040f);
-
- /* VID_PLL Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
- cx18_av_write4(cx, 0x10c, 0x002be2fe);
-
- /* AUX_PLL Fraction = 0x176740c */
- /* xtal * 0xd.bb3a060/0x20 = 32000 * 384: 393 MHz p-pd*/
- cx18_av_write4(cx, 0x110, 0x0176740c);
-
- /* src3/4/6_ctl */
- /* 0x1.f77f = (4 * xtal/8*2/455) / 32000 */
- cx18_av_write4(cx, 0x900, 0x0801f77f);
- cx18_av_write4(cx, 0x904, 0x0801f77f);
- cx18_av_write4(cx, 0x90c, 0x0801f77f);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x20 */
- cx18_av_write(cx, 0x127, 0x60);
-
- /* AUD_COUNT = 0x2fff = 8 samples * 4 * 384 - 1 */
- cx18_av_write4(cx, 0x12c, 0x11202fff);
-
- /*
- * EN_AV_LOCK = 0
- * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
- * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
- */
- cx18_av_write4(cx, 0x128, 0xa00d2ef8);
- break;
-
- case 44100:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x18
- */
- cx18_av_write4(cx, 0x108, 0x180e040f);
-
- /* VID_PLL Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
- cx18_av_write4(cx, 0x10c, 0x002be2fe);
-
- /* AUX_PLL Fraction = 0x062a1f2 */
- /* xtal * 0xe.3150f90/0x18 = 44100 * 384: 406 MHz p-pd*/
- cx18_av_write4(cx, 0x110, 0x0062a1f2);
-
- /* src3/4/6_ctl */
- /* 0x1.6d59 = (4 * xtal/8*2/455) / 44100 */
- cx18_av_write4(cx, 0x900, 0x08016d59);
- cx18_av_write4(cx, 0x904, 0x08016d59);
- cx18_av_write4(cx, 0x90c, 0x08016d59);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x18 */
- cx18_av_write(cx, 0x127, 0x58);
-
- /* AUD_COUNT = 0x92ff = 49 samples * 2 * 384 - 1 */
- cx18_av_write4(cx, 0x12c, 0x112092ff);
-
- /*
- * EN_AV_LOCK = 0
- * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
- * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
- */
- cx18_av_write4(cx, 0x128, 0xa01d4bf8);
- break;
-
- case 48000:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x16
- */
- cx18_av_write4(cx, 0x108, 0x160e040f);
-
- /* VID_PLL Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
- cx18_av_write4(cx, 0x10c, 0x002be2fe);
-
- /* AUX_PLL Fraction = 0x05227ad */
- /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz p-pd*/
- cx18_av_write4(cx, 0x110, 0x005227ad);
-
- /* src3/4/6_ctl */
- /* 0x1.4faa = (4 * xtal/8*2/455) / 48000 */
- cx18_av_write4(cx, 0x900, 0x08014faa);
- cx18_av_write4(cx, 0x904, 0x08014faa);
- cx18_av_write4(cx, 0x90c, 0x08014faa);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
- cx18_av_write(cx, 0x127, 0x56);
-
- /* AUD_COUNT = 0x5fff = 4 samples * 16 * 384 - 1 */
- cx18_av_write4(cx, 0x12c, 0x11205fff);
-
- /*
- * EN_AV_LOCK = 0
- * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
- * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
- */
- cx18_av_write4(cx, 0x128, 0xa01193f8);
- break;
- }
- } else {
- switch (freq) {
- case 32000:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x30
- */
- cx18_av_write4(cx, 0x108, 0x300d040f);
-
- /* VID_PLL Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
- cx18_av_write4(cx, 0x10c, 0x002be2fe);
-
- /* AUX_PLL Fraction = 0x176740c */
- /* xtal * 0xd.bb3a060/0x30 = 32000 * 256: 393 MHz p-pd*/
- cx18_av_write4(cx, 0x110, 0x0176740c);
-
- /* src1_ctl */
- /* 0x1.0000 = 32000/32000 */
- cx18_av_write4(cx, 0x8f8, 0x08010000);
-
- /* src3/4/6_ctl */
- /* 0x2.0000 = 2 * (32000/32000) */
- cx18_av_write4(cx, 0x900, 0x08020000);
- cx18_av_write4(cx, 0x904, 0x08020000);
- cx18_av_write4(cx, 0x90c, 0x08020000);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x30 */
- cx18_av_write(cx, 0x127, 0x70);
-
- /* AUD_COUNT = 0x1fff = 8 samples * 4 * 256 - 1 */
- cx18_av_write4(cx, 0x12c, 0x11201fff);
-
- /*
- * EN_AV_LOCK = 0
- * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
- * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
- */
- cx18_av_write4(cx, 0x128, 0xa00d2ef8);
- break;
-
- case 44100:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x24
- */
- cx18_av_write4(cx, 0x108, 0x240e040f);
-
- /* VID_PLL Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
- cx18_av_write4(cx, 0x10c, 0x002be2fe);
-
- /* AUX_PLL Fraction = 0x062a1f2 */
- /* xtal * 0xe.3150f90/0x24 = 44100 * 256: 406 MHz p-pd*/
- cx18_av_write4(cx, 0x110, 0x0062a1f2);
-
- /* src1_ctl */
- /* 0x1.60cd = 44100/32000 */
- cx18_av_write4(cx, 0x8f8, 0x080160cd);
-
- /* src3/4/6_ctl */
- /* 0x1.7385 = 2 * (32000/44100) */
- cx18_av_write4(cx, 0x900, 0x08017385);
- cx18_av_write4(cx, 0x904, 0x08017385);
- cx18_av_write4(cx, 0x90c, 0x08017385);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x24 */
- cx18_av_write(cx, 0x127, 0x64);
-
- /* AUD_COUNT = 0x61ff = 49 samples * 2 * 256 - 1 */
- cx18_av_write4(cx, 0x12c, 0x112061ff);
-
- /*
- * EN_AV_LOCK = 0
- * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
- * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
- */
- cx18_av_write4(cx, 0x128, 0xa01d4bf8);
- break;
-
- case 48000:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x20
- */
- cx18_av_write4(cx, 0x108, 0x200d040f);
-
- /* VID_PLL Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
- cx18_av_write4(cx, 0x10c, 0x002be2fe);
-
- /* AUX_PLL Fraction = 0x176740c */
- /* xtal * 0xd.bb3a060/0x20 = 48000 * 256: 393 MHz p-pd*/
- cx18_av_write4(cx, 0x110, 0x0176740c);
-
- /* src1_ctl */
- /* 0x1.8000 = 48000/32000 */
- cx18_av_write4(cx, 0x8f8, 0x08018000);
-
- /* src3/4/6_ctl */
- /* 0x1.5555 = 2 * (32000/48000) */
- cx18_av_write4(cx, 0x900, 0x08015555);
- cx18_av_write4(cx, 0x904, 0x08015555);
- cx18_av_write4(cx, 0x90c, 0x08015555);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x20 */
- cx18_av_write(cx, 0x127, 0x60);
-
- /* AUD_COUNT = 0x3fff = 4 samples * 16 * 256 - 1 */
- cx18_av_write4(cx, 0x12c, 0x11203fff);
-
- /*
- * EN_AV_LOCK = 0
- * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
- * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
- */
- cx18_av_write4(cx, 0x128, 0xa01193f8);
- break;
- }
- }
-
- state->audclk_freq = freq;
-
- return 0;
-}
-
-void cx18_av_audio_set_path(struct cx18 *cx)
-{
- struct cx18_av_state *state = &cx->av_state;
- u8 v;
-
- /* stop microcontroller */
- v = cx18_av_read(cx, 0x803) & ~0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
-
- /* assert soft reset */
- v = cx18_av_read(cx, 0x810) | 0x01;
- cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
-
- /* Mute everything to prevent the PFFT! */
- cx18_av_write(cx, 0x8d3, 0x1f);
-
- if (state->aud_input <= CX18_AV_AUDIO_SERIAL2) {
- /* Set Path1 to Serial Audio Input */
- cx18_av_write4(cx, 0x8d0, 0x01011012);
-
- /* The microcontroller should not be started for the
- * non-tuner inputs: autodetection is specific for
- * TV audio. */
- } else {
- /* Set Path1 to Analog Demod Main Channel */
- cx18_av_write4(cx, 0x8d0, 0x1f063870);
- }
-
- set_audclk_freq(cx, state->audclk_freq);
-
- /* deassert soft reset */
- v = cx18_av_read(cx, 0x810) & ~0x01;
- cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
-
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- /* When the microcontroller detects the
- * audio format, it will unmute the lines */
- v = cx18_av_read(cx, 0x803) | 0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- }
-}
-
-static void set_volume(struct cx18 *cx, int volume)
-{
- /* First convert the volume to msp3400 values (0-127) */
- int vol = volume >> 9;
- /* now scale it up to cx18_av values
- * -114dB to -96dB maps to 0
- * this should be 19, but in my testing that was 4dB too loud */
- if (vol <= 23)
- vol = 0;
- else
- vol -= 23;
-
- /* PATH1_VOLUME */
- cx18_av_write(cx, 0x8d4, 228 - (vol * 2));
-}
-
-static void set_bass(struct cx18 *cx, int bass)
-{
- /* PATH1_EQ_BASS_VOL */
- cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
-}
-
-static void set_treble(struct cx18 *cx, int treble)
-{
- /* PATH1_EQ_TREBLE_VOL */
- cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
-}
-
-static void set_balance(struct cx18 *cx, int balance)
-{
- int bal = balance >> 8;
- if (bal > 0x80) {
- /* PATH1_BAL_LEFT */
- cx18_av_and_or(cx, 0x8d5, 0x7f, 0x80);
- /* PATH1_BAL_LEVEL */
- cx18_av_and_or(cx, 0x8d5, ~0x7f, bal & 0x7f);
- } else {
- /* PATH1_BAL_LEFT */
- cx18_av_and_or(cx, 0x8d5, 0x7f, 0x00);
- /* PATH1_BAL_LEVEL */
- cx18_av_and_or(cx, 0x8d5, ~0x7f, 0x80 - bal);
- }
-}
-
-static void set_mute(struct cx18 *cx, int mute)
-{
- struct cx18_av_state *state = &cx->av_state;
- u8 v;
-
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- /* Must turn off microcontroller in order to mute sound.
- * Not sure if this is the best method, but it does work.
- * If the microcontroller is running, then it will undo any
- * changes to the mute register. */
- v = cx18_av_read(cx, 0x803);
- if (mute) {
- /* disable microcontroller */
- v &= ~0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- cx18_av_write(cx, 0x8d3, 0x1f);
- } else {
- /* enable microcontroller */
- v |= 0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- }
- } else {
- /* SRC1_MUTE_EN */
- cx18_av_and_or(cx, 0x8d3, ~0x2, mute ? 0x02 : 0x00);
- }
-}
-
-int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- struct cx18_av_state *state = &cx->av_state;
- int retval;
- u8 v;
-
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- v = cx18_av_read(cx, 0x803) & ~0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- cx18_av_write(cx, 0x8d3, 0x1f);
- }
- v = cx18_av_read(cx, 0x810) | 0x1;
- cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
-
- retval = set_audclk_freq(cx, freq);
-
- v = cx18_av_read(cx, 0x810) & ~0x1;
- cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- v = cx18_av_read(cx, 0x803) | 0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- }
- return retval;
-}
-
-static int cx18_av_audio_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- set_volume(cx, ctrl->val);
- break;
- case V4L2_CID_AUDIO_BASS:
- set_bass(cx, ctrl->val);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- set_treble(cx, ctrl->val);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- set_balance(cx, ctrl->val);
- break;
- case V4L2_CID_AUDIO_MUTE:
- set_mute(cx, ctrl->val);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-const struct v4l2_ctrl_ops cx18_av_audio_ctrl_ops = {
- .s_ctrl = cx18_av_audio_s_ctrl,
-};
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
deleted file mode 100644
index f164b7f610a..00000000000
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ /dev/null
@@ -1,1401 +0,0 @@
-/*
- * cx18 ADEC audio functions
- *
- * Derived from cx25840-core.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <media/v4l2-chip-ident.h>
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-cards.h"
-
-int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
-{
- u32 reg = 0xc40000 + (addr & ~3);
- u32 mask = 0xff;
- int shift = (addr & 3) * 8;
- u32 x = cx18_read_reg(cx, reg);
-
- x = (x & ~(mask << shift)) | ((u32)value << shift);
- cx18_write_reg(cx, x, reg);
- return 0;
-}
-
-int cx18_av_write_expect(struct cx18 *cx, u16 addr, u8 value, u8 eval, u8 mask)
-{
- u32 reg = 0xc40000 + (addr & ~3);
- int shift = (addr & 3) * 8;
- u32 x = cx18_read_reg(cx, reg);
-
- x = (x & ~((u32)0xff << shift)) | ((u32)value << shift);
- cx18_write_reg_expect(cx, x, reg,
- ((u32)eval << shift), ((u32)mask << shift));
- return 0;
-}
-
-int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value)
-{
- cx18_write_reg(cx, value, 0xc40000 + addr);
- return 0;
-}
-
-int
-cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval, u32 mask)
-{
- cx18_write_reg_expect(cx, value, 0xc40000 + addr, eval, mask);
- return 0;
-}
-
-int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value)
-{
- cx18_write_reg_noretry(cx, value, 0xc40000 + addr);
- return 0;
-}
-
-u8 cx18_av_read(struct cx18 *cx, u16 addr)
-{
- u32 x = cx18_read_reg(cx, 0xc40000 + (addr & ~3));
- int shift = (addr & 3) * 8;
-
- return (x >> shift) & 0xff;
-}
-
-u32 cx18_av_read4(struct cx18 *cx, u16 addr)
-{
- return cx18_read_reg(cx, 0xc40000 + addr);
-}
-
-int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask,
- u8 or_value)
-{
- return cx18_av_write(cx, addr,
- (cx18_av_read(cx, addr) & and_mask) |
- or_value);
-}
-
-int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
- u32 or_value)
-{
- return cx18_av_write4(cx, addr,
- (cx18_av_read4(cx, addr) & and_mask) |
- or_value);
-}
-
-static void cx18_av_init(struct cx18 *cx)
-{
- /*
- * The crystal freq used in calculations in this driver will be
- * 28.636360 MHz.
- * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
- */
-
- /*
- * VDCLK Integer = 0x0f, Post Divider = 0x04
- * AIMCLK Integer = 0x0e, Post Divider = 0x16
- */
- cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
-
- /* VDCLK Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
- cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
-
- /* AIMCLK Fraction = 0x05227ad */
- /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
- cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
- cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
-}
-
-static void cx18_av_initialize(struct v4l2_subdev *sd)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- int default_volume;
- u32 v;
-
- cx18_av_loadfw(cx);
- /* Stop 8051 code execution */
- cx18_av_write4_expect(cx, CXADEC_DL_CTL, 0x03000000,
- 0x03000000, 0x13000000);
-
- /* initallize the PLL by toggling sleep bit */
- v = cx18_av_read4(cx, CXADEC_HOST_REG1);
- /* enable sleep mode - register appears to be read only... */
- cx18_av_write4_expect(cx, CXADEC_HOST_REG1, v | 1, v, 0xfffe);
- /* disable sleep mode */
- cx18_av_write4_expect(cx, CXADEC_HOST_REG1, v & 0xfffe,
- v & 0xfffe, 0xffff);
-
- /* initialize DLLs */
- v = cx18_av_read4(cx, CXADEC_DLL1_DIAG_CTRL) & 0xE1FFFEFF;
- /* disable FLD */
- cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v);
- /* enable FLD */
- cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v | 0x10000100);
-
- v = cx18_av_read4(cx, CXADEC_DLL2_DIAG_CTRL) & 0xE1FFFEFF;
- /* disable FLD */
- cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v);
- /* enable FLD */
- cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v | 0x06000100);
-
- /* set analog bias currents. Set Vreg to 1.20V. */
- cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL1, 0x000A1802);
-
- v = cx18_av_read4(cx, CXADEC_AFE_DIAG_CTRL3) | 1;
- /* enable TUNE_FIL_RST */
- cx18_av_write4_expect(cx, CXADEC_AFE_DIAG_CTRL3, v, v, 0x03009F0F);
- /* disable TUNE_FIL_RST */
- cx18_av_write4_expect(cx, CXADEC_AFE_DIAG_CTRL3,
- v & 0xFFFFFFFE, v & 0xFFFFFFFE, 0x03009F0F);
-
- /* enable 656 output */
- cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x040C00);
-
- /* video output drive strength */
- cx18_av_and_or4(cx, CXADEC_PIN_CTRL2, ~0, 0x2);
-
- /* reset video */
- cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000);
- cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0);
-
- /*
- * Disable Video Auto-config of the Analog Front End and Video PLL.
- *
- * Since we only use BT.656 pixel mode, which works for both 525 and 625
- * line systems, it's just easier for us to set registers
- * 0x102 (CXADEC_CHIP_CTRL), 0x104-0x106 (CXADEC_AFE_CTRL),
- * 0x108-0x109 (CXADEC_PLL_CTRL1), and 0x10c-0x10f (CXADEC_VID_PLL_FRAC)
- * ourselves, than to run around cleaning up after the auto-config.
- *
- * (Note: my CX23418 chip doesn't seem to let the ACFG_DIS bit
- * get set to 1, but OTOH, it doesn't seem to do AFE and VID PLL
- * autoconfig either.)
- *
- * As a default, also turn off Dual mode for ADC2 and set ADC2 to CH3.
- */
- cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000);
-
- /* Setup the Video and and Aux/Audio PLLs */
- cx18_av_init(cx);
-
- /* set video to auto-detect */
- /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */
- /* set the comb notch = 1 */
- cx18_av_and_or4(cx, CXADEC_MODE_CTRL, 0xFFF7E7F0, 0x02040800);
-
- /* Enable wtw_en in CRUSH_CTRL (Set bit 22) */
- /* Enable maj_sel in CRUSH_CTRL (Set bit 20) */
- cx18_av_and_or4(cx, CXADEC_CRUSH_CTRL, ~0, 0x00500000);
-
- /* Set VGA_TRACK_RANGE to 0x20 */
- cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000);
-
- /*
- * Initial VBI setup
- * VIP-1.1, 10 bit mode, enable Raw, disable sliced,
- * don't clamp raw samples when codes are in use, 1 byte user D-words,
- * IDID0 has line #, RP code V bit transition on VBLANK, data during
- * blanking intervals
- */
- cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4013252e);
-
- /* Set the video input.
- The setting in MODE_CTRL gets lost when we do the above setup */
- /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */
- /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */
-
- /*
- * Analog Front End (AFE)
- * Default to luma on ch1/ADC1, chroma on ch2/ADC2, SIF on ch3/ADC2
- * bypass_ch[1-3] use filter
- * droop_comp_ch[1-3] disable
- * clamp_en_ch[1-3] disable
- * aud_in_sel ADC2
- * luma_in_sel ADC1
- * chroma_in_sel ADC2
- * clamp_sel_ch[2-3] midcode
- * clamp_sel_ch1 video decoder
- * vga_sel_ch3 audio decoder
- * vga_sel_ch[1-2] video decoder
- * half_bw_ch[1-3] disable
- * +12db_ch[1-3] disable
- */
- cx18_av_and_or4(cx, CXADEC_AFE_CTRL, 0xFF000000, 0x00005D00);
-
-/* if(dwEnable && dw3DCombAvailable) { */
-/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
-/* } else { */
-/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
-/* } */
- cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
- default_volume = cx18_av_read(cx, 0x8d4);
- /*
- * Enforce the legacy volume scale mapping limits to avoid
- * -ERANGE errors when initializing the volume control
- */
- if (default_volume > 228) {
- /* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */
- default_volume = 228;
- cx18_av_write(cx, 0x8d4, 228);
- } else if (default_volume < 20) {
- /* Top out at + 8 dB, v4l2 vol range 0xfe00-0xffff */
- default_volume = 20;
- cx18_av_write(cx, 0x8d4, 20);
- }
- default_volume = (((228 - default_volume) >> 1) + 23) << 9;
- state->volume->cur.val = state->volume->default_value = default_volume;
- v4l2_ctrl_handler_setup(&state->hdl);
-}
-
-static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
-{
- cx18_av_initialize(sd);
- return 0;
-}
-
-static int cx18_av_load_fw(struct v4l2_subdev *sd)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
-
- if (!state->is_initialized) {
- /* initialize on first use */
- state->is_initialized = 1;
- cx18_av_initialize(sd);
- }
- return 0;
-}
-
-void cx18_av_std_setup(struct cx18 *cx)
-{
- struct cx18_av_state *state = &cx->av_state;
- struct v4l2_subdev *sd = &state->sd;
- v4l2_std_id std = state->std;
-
- /*
- * Video ADC crystal clock to pixel clock SRC decimation ratio
- * 28.636360 MHz/13.5 Mpps * 256 = 0x21f.07b
- */
- const int src_decimation = 0x21f;
-
- int hblank, hactive, burst, vblank, vactive, sc;
- int vblank656;
- int luma_lpf, uv_lpf, comb;
- u32 pll_int, pll_frac, pll_post;
-
- /* datasheet startup, step 8d */
- if (std & ~V4L2_STD_NTSC)
- cx18_av_write(cx, 0x49f, 0x11);
- else
- cx18_av_write(cx, 0x49f, 0x14);
-
- /*
- * Note: At the end of a field, there are 3 sets of half line duration
- * (double horizontal rate) pulses:
- *
- * 5 (625) or 6 (525) half-lines to blank for the vertical retrace
- * 5 (625) or 6 (525) vertical sync pulses of half line duration
- * 5 (625) or 6 (525) half-lines of equalization pulses
- */
- if (std & V4L2_STD_625_50) {
- /*
- * The following relationships of half line counts should hold:
- * 625 = vblank656 + vactive
- * 10 = vblank656 - vblank = vsync pulses + equalization pulses
- *
- * vblank656: half lines after line 625/mid-313 of blanked video
- * vblank: half lines, after line 5/317, of blanked video
- * vactive: half lines of active video +
- * 5 half lines after the end of active video
- *
- * As far as I can tell:
- * vblank656 starts counting from the falling edge of the first
- * vsync pulse (start of line 1 or mid-313)
- * vblank starts counting from the after the 5 vsync pulses and
- * 5 or 4 equalization pulses (start of line 6 or 318)
- *
- * For 625 line systems the driver will extract VBI information
- * from lines 6-23 and lines 318-335 (but the slicer can only
- * handle 17 lines, not the 18 in the vblank region).
- * In addition, we need vblank656 and vblank to be one whole
- * line longer, to cover line 24 and 336, so the SAV/EAV RP
- * codes get generated such that the encoder can actually
- * extract line 23 & 335 (WSS). We'll lose 1 line in each field
- * at the top of the screen.
- *
- * It appears the 5 half lines that happen after active
- * video must be included in vactive (579 instead of 574),
- * otherwise the colors get badly displayed in various regions
- * of the screen. I guess the chroma comb filter gets confused
- * without them (at least when a PVR-350 is the PAL source).
- */
- vblank656 = 48; /* lines 1 - 24 & 313 - 336 */
- vblank = 38; /* lines 6 - 24 & 318 - 336 */
- vactive = 579; /* lines 24 - 313 & 337 - 626 */
-
- /*
- * For a 13.5 Mpps clock and 15,625 Hz line rate, a line is
- * is 864 pixels = 720 active + 144 blanking. ITU-R BT.601
- * specifies 12 luma clock periods or ~ 0.9 * 13.5 Mpps after
- * the end of active video to start a horizontal line, so that
- * leaves 132 pixels of hblank to ignore.
- */
- hblank = 132;
- hactive = 720;
-
- /*
- * Burst gate delay (for 625 line systems)
- * Hsync leading edge to color burst rise = 5.6 us
- * Color burst width = 2.25 us
- * Gate width = 4 pixel clocks
- * (5.6 us + 2.25/2 us) * 13.5 Mpps + 4/2 clocks = 92.79 clocks
- */
- burst = 93;
- luma_lpf = 2;
- if (std & V4L2_STD_PAL) {
- uv_lpf = 1;
- comb = 0x20;
- /* sc = 4433618.75 * src_decimation/28636360 * 2^13 */
- sc = 688700;
- } else if (std == V4L2_STD_PAL_Nc) {
- uv_lpf = 1;
- comb = 0x20;
- /* sc = 3582056.25 * src_decimation/28636360 * 2^13 */
- sc = 556422;
- } else { /* SECAM */
- uv_lpf = 0;
- comb = 0;
- /* (fr + fb)/2 = (4406260 + 4250000)/2 = 4328130 */
- /* sc = 4328130 * src_decimation/28636360 * 2^13 */
- sc = 672314;
- }
- } else {
- /*
- * The following relationships of half line counts should hold:
- * 525 = prevsync + vblank656 + vactive
- * 12 = vblank656 - vblank = vsync pulses + equalization pulses
- *
- * prevsync: 6 half-lines before the vsync pulses
- * vblank656: half lines, after line 3/mid-266, of blanked video
- * vblank: half lines, after line 9/272, of blanked video
- * vactive: half lines of active video
- *
- * As far as I can tell:
- * vblank656 starts counting from the falling edge of the first
- * vsync pulse (start of line 4 or mid-266)
- * vblank starts counting from the after the 6 vsync pulses and
- * 6 or 5 equalization pulses (start of line 10 or 272)
- *
- * For 525 line systems the driver will extract VBI information
- * from lines 10-21 and lines 273-284.
- */
- vblank656 = 38; /* lines 4 - 22 & 266 - 284 */
- vblank = 26; /* lines 10 - 22 & 272 - 284 */
- vactive = 481; /* lines 23 - 263 & 285 - 525 */
-
- /*
- * For a 13.5 Mpps clock and 15,734.26 Hz line rate, a line is
- * is 858 pixels = 720 active + 138 blanking. The Hsync leading
- * edge should happen 1.2 us * 13.5 Mpps ~= 16 pixels after the
- * end of active video, leaving 122 pixels of hblank to ignore
- * before active video starts.
- */
- hactive = 720;
- hblank = 122;
- luma_lpf = 1;
- uv_lpf = 1;
-
- /*
- * Burst gate delay (for 525 line systems)
- * Hsync leading edge to color burst rise = 5.3 us
- * Color burst width = 2.5 us
- * Gate width = 4 pixel clocks
- * (5.3 us + 2.5/2 us) * 13.5 Mpps + 4/2 clocks = 90.425 clocks
- */
- if (std == V4L2_STD_PAL_60) {
- burst = 90;
- luma_lpf = 2;
- comb = 0x20;
- /* sc = 4433618.75 * src_decimation/28636360 * 2^13 */
- sc = 688700;
- } else if (std == V4L2_STD_PAL_M) {
- /* The 97 needs to be verified against PAL-M timings */
- burst = 97;
- comb = 0x20;
- /* sc = 3575611.49 * src_decimation/28636360 * 2^13 */
- sc = 555421;
- } else {
- burst = 90;
- comb = 0x66;
- /* sc = 3579545.45.. * src_decimation/28636360 * 2^13 */
- sc = 556032;
- }
- }
-
- /* DEBUG: Displays configured PLL frequency */
- pll_int = cx18_av_read(cx, 0x108);
- pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff;
- pll_post = cx18_av_read(cx, 0x109);
- CX18_DEBUG_INFO_DEV(sd, "PLL regs = int: %u, frac: %u, post: %u\n",
- pll_int, pll_frac, pll_post);
-
- if (pll_post) {
- int fsc, pll;
- u64 tmp;
-
- pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25;
- pll /= pll_post;
- CX18_DEBUG_INFO_DEV(sd, "Video PLL = %d.%06d MHz\n",
- pll / 1000000, pll % 1000000);
- CX18_DEBUG_INFO_DEV(sd, "Pixel rate = %d.%06d Mpixel/sec\n",
- pll / 8000000, (pll / 8) % 1000000);
-
- CX18_DEBUG_INFO_DEV(sd, "ADC XTAL/pixel clock decimation ratio "
- "= %d.%03d\n", src_decimation / 256,
- ((src_decimation % 256) * 1000) / 256);
-
- tmp = 28636360 * (u64) sc;
- do_div(tmp, src_decimation);
- fsc = tmp >> 13;
- CX18_DEBUG_INFO_DEV(sd,
- "Chroma sub-carrier initial freq = %d.%06d "
- "MHz\n", fsc / 1000000, fsc % 1000000);
-
- CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, "
- "vactive %i, vblank656 %i, src_dec %i, "
- "burst 0x%02x, luma_lpf %i, uv_lpf %i, "
- "comb 0x%02x, sc 0x%06x\n",
- hblank, hactive, vblank, vactive, vblank656,
- src_decimation, burst, luma_lpf, uv_lpf,
- comb, sc);
- }
-
- /* Sets horizontal blanking delay and active lines */
- cx18_av_write(cx, 0x470, hblank);
- cx18_av_write(cx, 0x471, 0xff & (((hblank >> 8) & 0x3) |
- (hactive << 4)));
- cx18_av_write(cx, 0x472, hactive >> 4);
-
- /* Sets burst gate delay */
- cx18_av_write(cx, 0x473, burst);
-
- /* Sets vertical blanking delay and active duration */
- cx18_av_write(cx, 0x474, vblank);
- cx18_av_write(cx, 0x475, 0xff & (((vblank >> 8) & 0x3) |
- (vactive << 4)));
- cx18_av_write(cx, 0x476, vactive >> 4);
- cx18_av_write(cx, 0x477, vblank656);
-
- /* Sets src decimation rate */
- cx18_av_write(cx, 0x478, 0xff & src_decimation);
- cx18_av_write(cx, 0x479, 0xff & (src_decimation >> 8));
-
- /* Sets Luma and UV Low pass filters */
- cx18_av_write(cx, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));
-
- /* Enables comb filters */
- cx18_av_write(cx, 0x47b, comb);
-
- /* Sets SC Step*/
- cx18_av_write(cx, 0x47c, sc);
- cx18_av_write(cx, 0x47d, 0xff & sc >> 8);
- cx18_av_write(cx, 0x47e, 0xff & sc >> 16);
-
- if (std & V4L2_STD_625_50) {
- state->slicer_line_delay = 1;
- state->slicer_line_offset = (6 + state->slicer_line_delay - 2);
- } else {
- state->slicer_line_delay = 0;
- state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
- }
- cx18_av_write(cx, 0x47f, state->slicer_line_delay);
-}
-
-static void input_change(struct cx18 *cx)
-{
- struct cx18_av_state *state = &cx->av_state;
- v4l2_std_id std = state->std;
- u8 v;
-
- /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
- cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
- cx18_av_and_or(cx, 0x401, ~0x60, 0);
- cx18_av_and_or(cx, 0x401, ~0x60, 0x60);
-
- if (std & V4L2_STD_525_60) {
- if (std == V4L2_STD_NTSC_M_JP) {
- /* Japan uses EIAJ audio standard */
- cx18_av_write_expect(cx, 0x808, 0xf7, 0xf7, 0xff);
- cx18_av_write_expect(cx, 0x80b, 0x02, 0x02, 0x3f);
- } else if (std == V4L2_STD_NTSC_M_KR) {
- /* South Korea uses A2 audio standard */
- cx18_av_write_expect(cx, 0x808, 0xf8, 0xf8, 0xff);
- cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
- } else {
- /* Others use the BTSC audio standard */
- cx18_av_write_expect(cx, 0x808, 0xf6, 0xf6, 0xff);
- cx18_av_write_expect(cx, 0x80b, 0x01, 0x01, 0x3f);
- }
- } else if (std & V4L2_STD_PAL) {
- /* Follow tuner change procedure for PAL */
- cx18_av_write_expect(cx, 0x808, 0xff, 0xff, 0xff);
- cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
- } else if (std & V4L2_STD_SECAM) {
- /* Select autodetect for SECAM */
- cx18_av_write_expect(cx, 0x808, 0xff, 0xff, 0xff);
- cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
- }
-
- v = cx18_av_read(cx, 0x803);
- if (v & 0x10) {
- /* restart audio decoder microcontroller */
- v &= ~0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- v |= 0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- }
-}
-
-static int cx18_av_s_frequency(struct v4l2_subdev *sd,
- struct v4l2_frequency *freq)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- input_change(cx);
- return 0;
-}
-
-static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
- enum cx18_av_audio_input aud_input)
-{
- struct cx18_av_state *state = &cx->av_state;
- struct v4l2_subdev *sd = &state->sd;
-
- enum analog_signal_type {
- NONE, CVBS, Y, C, SIF, Pb, Pr
- } ch[3] = {NONE, NONE, NONE};
-
- u8 afe_mux_cfg;
- u8 adc2_cfg;
- u8 input_mode;
- u32 afe_cfg;
- int i;
-
- CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n",
- vid_input, aud_input);
-
- if (vid_input >= CX18_AV_COMPOSITE1 &&
- vid_input <= CX18_AV_COMPOSITE8) {
- afe_mux_cfg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
- ch[0] = CVBS;
- input_mode = 0x0;
- } else if (vid_input >= CX18_AV_COMPONENT_LUMA1) {
- int luma = vid_input & 0xf000;
- int r_chroma = vid_input & 0xf0000;
- int b_chroma = vid_input & 0xf00000;
-
- if ((vid_input & ~0xfff000) ||
- luma < CX18_AV_COMPONENT_LUMA1 ||
- luma > CX18_AV_COMPONENT_LUMA8 ||
- r_chroma < CX18_AV_COMPONENT_R_CHROMA4 ||
- r_chroma > CX18_AV_COMPONENT_R_CHROMA6 ||
- b_chroma < CX18_AV_COMPONENT_B_CHROMA7 ||
- b_chroma > CX18_AV_COMPONENT_B_CHROMA8) {
- CX18_ERR_DEV(sd, "0x%06x is not a valid video input!\n",
- vid_input);
- return -EINVAL;
- }
- afe_mux_cfg = (luma - CX18_AV_COMPONENT_LUMA1) >> 12;
- ch[0] = Y;
- afe_mux_cfg |= (r_chroma - CX18_AV_COMPONENT_R_CHROMA4) >> 12;
- ch[1] = Pr;
- afe_mux_cfg |= (b_chroma - CX18_AV_COMPONENT_B_CHROMA7) >> 14;
- ch[2] = Pb;
- input_mode = 0x6;
- } else {
- int luma = vid_input & 0xf0;
- int chroma = vid_input & 0xf00;
-
- if ((vid_input & ~0xff0) ||
- luma < CX18_AV_SVIDEO_LUMA1 ||
- luma > CX18_AV_SVIDEO_LUMA8 ||
- chroma < CX18_AV_SVIDEO_CHROMA4 ||
- chroma > CX18_AV_SVIDEO_CHROMA8) {
- CX18_ERR_DEV(sd, "0x%06x is not a valid video input!\n",
- vid_input);
- return -EINVAL;
- }
- afe_mux_cfg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
- ch[0] = Y;
- if (chroma >= CX18_AV_SVIDEO_CHROMA7) {
- afe_mux_cfg &= 0x3f;
- afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2;
- ch[2] = C;
- } else {
- afe_mux_cfg &= 0xcf;
- afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
- ch[1] = C;
- }
- input_mode = 0x2;
- }
-
- switch (aud_input) {
- case CX18_AV_AUDIO_SERIAL1:
- case CX18_AV_AUDIO_SERIAL2:
- /* do nothing, use serial audio input */
- break;
- case CX18_AV_AUDIO4:
- afe_mux_cfg &= ~0x30;
- ch[1] = SIF;
- break;
- case CX18_AV_AUDIO5:
- afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x10;
- ch[1] = SIF;
- break;
- case CX18_AV_AUDIO6:
- afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x20;
- ch[1] = SIF;
- break;
- case CX18_AV_AUDIO7:
- afe_mux_cfg &= ~0xc0;
- ch[2] = SIF;
- break;
- case CX18_AV_AUDIO8:
- afe_mux_cfg = (afe_mux_cfg & ~0xc0) | 0x40;
- ch[2] = SIF;
- break;
-
- default:
- CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n",
- aud_input);
- return -EINVAL;
- }
-
- /* Set up analog front end multiplexers */
- cx18_av_write_expect(cx, 0x103, afe_mux_cfg, afe_mux_cfg, 0xf7);
- /* Set INPUT_MODE to Composite, S-Video, or Component */
- cx18_av_and_or(cx, 0x401, ~0x6, input_mode);
-
- /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
- adc2_cfg = cx18_av_read(cx, 0x102);
- if (ch[2] == NONE)
- adc2_cfg &= ~0x2; /* No sig on CH3, set ADC2 to CH2 for input */
- else
- adc2_cfg |= 0x2; /* Signal on CH3, set ADC2 to CH3 for input */
-
- /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
- if (ch[1] != NONE && ch[2] != NONE)
- adc2_cfg |= 0x4; /* Set dual mode */
- else
- adc2_cfg &= ~0x4; /* Clear dual mode */
- cx18_av_write_expect(cx, 0x102, adc2_cfg, adc2_cfg, 0x17);
-
- /* Configure the analog front end */
- afe_cfg = cx18_av_read4(cx, CXADEC_AFE_CTRL);
- afe_cfg &= 0xff000000;
- afe_cfg |= 0x00005000; /* CHROMA_IN, AUD_IN: ADC2; LUMA_IN: ADC1 */
- if (ch[1] != NONE && ch[2] != NONE)
- afe_cfg |= 0x00000030; /* half_bw_ch[2-3] since in dual mode */
-
- for (i = 0; i < 3; i++) {
- switch (ch[i]) {
- default:
- case NONE:
- /* CLAMP_SEL = Fixed to midcode clamp level */
- afe_cfg |= (0x00000200 << i);
- break;
- case CVBS:
- case Y:
- if (i > 0)
- afe_cfg |= 0x00002000; /* LUMA_IN_SEL: ADC2 */
- break;
- case C:
- case Pb:
- case Pr:
- /* CLAMP_SEL = Fixed to midcode clamp level */
- afe_cfg |= (0x00000200 << i);
- if (i == 0 && ch[i] == C)
- afe_cfg &= ~0x00001000; /* CHROMA_IN_SEL ADC1 */
- break;
- case SIF:
- /*
- * VGA_GAIN_SEL = Audio Decoder
- * CLAMP_SEL = Fixed to midcode clamp level
- */
- afe_cfg |= (0x00000240 << i);
- if (i == 0)
- afe_cfg &= ~0x00004000; /* AUD_IN_SEL ADC1 */
- break;
- }
- }
-
- cx18_av_write4(cx, CXADEC_AFE_CTRL, afe_cfg);
-
- state->vid_input = vid_input;
- state->aud_input = aud_input;
- cx18_av_audio_set_path(cx);
- input_change(cx);
- return 0;
-}
-
-static int cx18_av_s_video_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- return set_input(cx, input, state->aud_input);
-}
-
-static int cx18_av_s_audio_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- return set_input(cx, state->vid_input, input);
-}
-
-static int cx18_av_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- u8 vpres;
- u8 mode;
- int val = 0;
-
- if (state->radio)
- return 0;
-
- vpres = cx18_av_read(cx, 0x40e) & 0x20;
- vt->signal = vpres ? 0xffff : 0x0;
-
- vt->capability |=
- V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
- V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
-
- mode = cx18_av_read(cx, 0x804);
-
- /* get rxsubchans and audmode */
- if ((mode & 0xf) == 1)
- val |= V4L2_TUNER_SUB_STEREO;
- else
- val |= V4L2_TUNER_SUB_MONO;
-
- if (mode == 2 || mode == 4)
- val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
-
- if (mode & 0x10)
- val |= V4L2_TUNER_SUB_SAP;
-
- vt->rxsubchans = val;
- vt->audmode = state->audmode;
- return 0;
-}
-
-static int cx18_av_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- u8 v;
-
- if (state->radio)
- return 0;
-
- v = cx18_av_read(cx, 0x809);
- v &= ~0xf;
-
- switch (vt->audmode) {
- case V4L2_TUNER_MODE_MONO:
- /* mono -> mono
- stereo -> mono
- bilingual -> lang1 */
- break;
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang1 */
- v |= 0x4;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang1/lang2 */
- v |= 0x7;
- break;
- case V4L2_TUNER_MODE_LANG2:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang2 */
- v |= 0x1;
- break;
- default:
- return -EINVAL;
- }
- cx18_av_write_expect(cx, 0x809, v, v, 0xff);
- state->audmode = vt->audmode;
- return 0;
-}
-
-static int cx18_av_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- u8 fmt = 0; /* zero is autodetect */
- u8 pal_m = 0;
-
- if (state->radio == 0 && state->std == norm)
- return 0;
-
- state->radio = 0;
- state->std = norm;
-
- /* First tests should be against specific std */
- if (state->std == V4L2_STD_NTSC_M_JP) {
- fmt = 0x2;
- } else if (state->std == V4L2_STD_NTSC_443) {
- fmt = 0x3;
- } else if (state->std == V4L2_STD_PAL_M) {
- pal_m = 1;
- fmt = 0x5;
- } else if (state->std == V4L2_STD_PAL_N) {
- fmt = 0x6;
- } else if (state->std == V4L2_STD_PAL_Nc) {
- fmt = 0x7;
- } else if (state->std == V4L2_STD_PAL_60) {
- fmt = 0x8;
- } else {
- /* Then, test against generic ones */
- if (state->std & V4L2_STD_NTSC)
- fmt = 0x1;
- else if (state->std & V4L2_STD_PAL)
- fmt = 0x4;
- else if (state->std & V4L2_STD_SECAM)
- fmt = 0xc;
- }
-
- CX18_DEBUG_INFO_DEV(sd, "changing video std to fmt %i\n", fmt);
-
- /* Follow step 9 of section 3.16 in the cx18_av datasheet.
- Without this PAL may display a vertical ghosting effect.
- This happens for example with the Yuan MPC622. */
- if (fmt >= 4 && fmt < 8) {
- /* Set format to NTSC-M */
- cx18_av_and_or(cx, 0x400, ~0xf, 1);
- /* Turn off LCOMB */
- cx18_av_and_or(cx, 0x47b, ~6, 0);
- }
- cx18_av_and_or(cx, 0x400, ~0x2f, fmt | 0x20);
- cx18_av_and_or(cx, 0x403, ~0x3, pal_m);
- cx18_av_std_setup(cx);
- input_change(cx);
- return 0;
-}
-
-static int cx18_av_s_radio(struct v4l2_subdev *sd)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- state->radio = 1;
- return 0;
-}
-
-static int cx18_av_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- cx18_av_write(cx, 0x414, ctrl->val - 128);
- break;
-
- case V4L2_CID_CONTRAST:
- cx18_av_write(cx, 0x415, ctrl->val << 1);
- break;
-
- case V4L2_CID_SATURATION:
- cx18_av_write(cx, 0x420, ctrl->val << 1);
- cx18_av_write(cx, 0x421, ctrl->val << 1);
- break;
-
- case V4L2_CID_HUE:
- cx18_av_write(cx, 0x422, ctrl->val);
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
- int is_50Hz = !(state->std & V4L2_STD_525_60);
-
- if (fmt->code != V4L2_MBUS_FMT_FIXED)
- return -EINVAL;
-
- fmt->field = V4L2_FIELD_INTERLACED;
- fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
-
- Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4;
- Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4;
-
- Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4;
- Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4;
-
- /*
- * This adjustment reflects the excess of vactive, set in
- * cx18_av_std_setup(), above standard values:
- *
- * 480 + 1 for 60 Hz systems
- * 576 + 3 for 50 Hz systems
- */
- Vlines = fmt->height + (is_50Hz ? 3 : 1);
-
- /*
- * Invalid height and width scaling requests are:
- * 1. width less than 1/16 of the source width
- * 2. width greater than the source width
- * 3. height less than 1/8 of the source height
- * 4. height greater than the source height
- */
- if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
- (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
- CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n",
- fmt->width, fmt->height);
- return -ERANGE;
- }
-
- HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20);
- VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
- VSC &= 0x1fff;
-
- if (fmt->width >= 385)
- filter = 0;
- else if (fmt->width > 192)
- filter = 1;
- else if (fmt->width > 96)
- filter = 2;
- else
- filter = 3;
-
- CX18_DEBUG_INFO_DEV(sd,
- "decoder set size %dx%d -> scale %ux%u\n",
- fmt->width, fmt->height, HSC, VSC);
-
- /* HSCALE=HSC */
- cx18_av_write(cx, 0x418, HSC & 0xff);
- cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff);
- cx18_av_write(cx, 0x41a, HSC >> 16);
- /* VSCALE=VSC */
- cx18_av_write(cx, 0x41c, VSC & 0xff);
- cx18_av_write(cx, 0x41d, VSC >> 8);
- /* VS_INTRLACE=1 VFILT=filter */
- cx18_av_write(cx, 0x41e, 0x8 | filter);
- return 0;
-}
-
-static int cx18_av_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- CX18_DEBUG_INFO_DEV(sd, "%s output\n", enable ? "enable" : "disable");
- if (enable) {
- cx18_av_write(cx, 0x115, 0x8c);
- cx18_av_write(cx, 0x116, 0x07);
- } else {
- cx18_av_write(cx, 0x115, 0x00);
- cx18_av_write(cx, 0x116, 0x00);
- }
- return 0;
-}
-
-static void log_video_status(struct cx18 *cx)
-{
- static const char *const fmt_strs[] = {
- "0x0",
- "NTSC-M", "NTSC-J", "NTSC-4.43",
- "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
- "0x9", "0xA", "0xB",
- "SECAM",
- "0xD", "0xE", "0xF"
- };
-
- struct cx18_av_state *state = &cx->av_state;
- struct v4l2_subdev *sd = &state->sd;
- u8 vidfmt_sel = cx18_av_read(cx, 0x400) & 0xf;
- u8 gen_stat1 = cx18_av_read(cx, 0x40d);
- u8 gen_stat2 = cx18_av_read(cx, 0x40e);
- int vid_input = state->vid_input;
-
- CX18_INFO_DEV(sd, "Video signal: %spresent\n",
- (gen_stat2 & 0x20) ? "" : "not ");
- CX18_INFO_DEV(sd, "Detected format: %s\n",
- fmt_strs[gen_stat1 & 0xf]);
-
- CX18_INFO_DEV(sd, "Specified standard: %s\n",
- vidfmt_sel ? fmt_strs[vidfmt_sel]
- : "automatic detection");
-
- if (vid_input >= CX18_AV_COMPOSITE1 &&
- vid_input <= CX18_AV_COMPOSITE8) {
- CX18_INFO_DEV(sd, "Specified video input: Composite %d\n",
- vid_input - CX18_AV_COMPOSITE1 + 1);
- } else {
- CX18_INFO_DEV(sd, "Specified video input: "
- "S-Video (Luma In%d, Chroma In%d)\n",
- (vid_input & 0xf0) >> 4,
- (vid_input & 0xf00) >> 8);
- }
-
- CX18_INFO_DEV(sd, "Specified audioclock freq: %d Hz\n",
- state->audclk_freq);
-}
-
-static void log_audio_status(struct cx18 *cx)
-{
- struct cx18_av_state *state = &cx->av_state;
- struct v4l2_subdev *sd = &state->sd;
- u8 download_ctl = cx18_av_read(cx, 0x803);
- u8 mod_det_stat0 = cx18_av_read(cx, 0x804);
- u8 mod_det_stat1 = cx18_av_read(cx, 0x805);
- u8 audio_config = cx18_av_read(cx, 0x808);
- u8 pref_mode = cx18_av_read(cx, 0x809);
- u8 afc0 = cx18_av_read(cx, 0x80b);
- u8 mute_ctl = cx18_av_read(cx, 0x8d3);
- int aud_input = state->aud_input;
- char *p;
-
- switch (mod_det_stat0) {
- case 0x00: p = "mono"; break;
- case 0x01: p = "stereo"; break;
- case 0x02: p = "dual"; break;
- case 0x04: p = "tri"; break;
- case 0x10: p = "mono with SAP"; break;
- case 0x11: p = "stereo with SAP"; break;
- case 0x12: p = "dual with SAP"; break;
- case 0x14: p = "tri with SAP"; break;
- case 0xfe: p = "forced mode"; break;
- default: p = "not defined"; break;
- }
- CX18_INFO_DEV(sd, "Detected audio mode: %s\n", p);
-
- switch (mod_det_stat1) {
- case 0x00: p = "not defined"; break;
- case 0x01: p = "EIAJ"; break;
- case 0x02: p = "A2-M"; break;
- case 0x03: p = "A2-BG"; break;
- case 0x04: p = "A2-DK1"; break;
- case 0x05: p = "A2-DK2"; break;
- case 0x06: p = "A2-DK3"; break;
- case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
- case 0x08: p = "AM-L"; break;
- case 0x09: p = "NICAM-BG"; break;
- case 0x0a: p = "NICAM-DK"; break;
- case 0x0b: p = "NICAM-I"; break;
- case 0x0c: p = "NICAM-L"; break;
- case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
- case 0x0e: p = "IF FM Radio"; break;
- case 0x0f: p = "BTSC"; break;
- case 0x10: p = "detected chrominance"; break;
- case 0xfd: p = "unknown audio standard"; break;
- case 0xfe: p = "forced audio standard"; break;
- case 0xff: p = "no detected audio standard"; break;
- default: p = "not defined"; break;
- }
- CX18_INFO_DEV(sd, "Detected audio standard: %s\n", p);
- CX18_INFO_DEV(sd, "Audio muted: %s\n",
- (mute_ctl & 0x2) ? "yes" : "no");
- CX18_INFO_DEV(sd, "Audio microcontroller: %s\n",
- (download_ctl & 0x10) ? "running" : "stopped");
-
- switch (audio_config >> 4) {
- case 0x00: p = "undefined"; break;
- case 0x01: p = "BTSC"; break;
- case 0x02: p = "EIAJ"; break;
- case 0x03: p = "A2-M"; break;
- case 0x04: p = "A2-BG"; break;
- case 0x05: p = "A2-DK1"; break;
- case 0x06: p = "A2-DK2"; break;
- case 0x07: p = "A2-DK3"; break;
- case 0x08: p = "A1 (6.0 MHz FM Mono)"; break;
- case 0x09: p = "AM-L"; break;
- case 0x0a: p = "NICAM-BG"; break;
- case 0x0b: p = "NICAM-DK"; break;
- case 0x0c: p = "NICAM-I"; break;
- case 0x0d: p = "NICAM-L"; break;
- case 0x0e: p = "FM radio"; break;
- case 0x0f: p = "automatic detection"; break;
- default: p = "undefined"; break;
- }
- CX18_INFO_DEV(sd, "Configured audio standard: %s\n", p);
-
- if ((audio_config >> 4) < 0xF) {
- switch (audio_config & 0xF) {
- case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
- case 0x01: p = "MONO2 (LANGUAGE B)"; break;
- case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
- case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
- case 0x04: p = "STEREO"; break;
- case 0x05: p = "DUAL1 (AC)"; break;
- case 0x06: p = "DUAL2 (BC)"; break;
- case 0x07: p = "DUAL3 (AB)"; break;
- default: p = "undefined";
- }
- CX18_INFO_DEV(sd, "Configured audio mode: %s\n", p);
- } else {
- switch (audio_config & 0xF) {
- case 0x00: p = "BG"; break;
- case 0x01: p = "DK1"; break;
- case 0x02: p = "DK2"; break;
- case 0x03: p = "DK3"; break;
- case 0x04: p = "I"; break;
- case 0x05: p = "L"; break;
- case 0x06: p = "BTSC"; break;
- case 0x07: p = "EIAJ"; break;
- case 0x08: p = "A2-M"; break;
- case 0x09: p = "FM Radio (4.5 MHz)"; break;
- case 0x0a: p = "FM Radio (5.5 MHz)"; break;
- case 0x0b: p = "S-Video"; break;
- case 0x0f: p = "automatic standard and mode detection"; break;
- default: p = "undefined"; break;
- }
- CX18_INFO_DEV(sd, "Configured audio system: %s\n", p);
- }
-
- if (aud_input)
- CX18_INFO_DEV(sd, "Specified audio input: Tuner (In%d)\n",
- aud_input);
- else
- CX18_INFO_DEV(sd, "Specified audio input: External\n");
-
- switch (pref_mode & 0xf) {
- case 0: p = "mono/language A"; break;
- case 1: p = "language B"; break;
- case 2: p = "language C"; break;
- case 3: p = "analog fallback"; break;
- case 4: p = "stereo"; break;
- case 5: p = "language AC"; break;
- case 6: p = "language BC"; break;
- case 7: p = "language AB"; break;
- default: p = "undefined"; break;
- }
- CX18_INFO_DEV(sd, "Preferred audio mode: %s\n", p);
-
- if ((audio_config & 0xf) == 0xf) {
- switch ((afc0 >> 3) & 0x1) {
- case 0: p = "system DK"; break;
- case 1: p = "system L"; break;
- }
- CX18_INFO_DEV(sd, "Selected 65 MHz format: %s\n", p);
-
- switch (afc0 & 0x7) {
- case 0: p = "Chroma"; break;
- case 1: p = "BTSC"; break;
- case 2: p = "EIAJ"; break;
- case 3: p = "A2-M"; break;
- case 4: p = "autodetect"; break;
- default: p = "undefined"; break;
- }
- CX18_INFO_DEV(sd, "Selected 45 MHz format: %s\n", p);
- }
-}
-
-static int cx18_av_log_status(struct v4l2_subdev *sd)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- log_video_status(cx);
- log_audio_status(cx);
- return 0;
-}
-
-static inline int cx18_av_dbg_match(const struct v4l2_dbg_match *match)
-{
- return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 1;
-}
-
-static int cx18_av_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
-
- if (cx18_av_dbg_match(&chip->match)) {
- chip->ident = state->id;
- chip->revision = state->rev;
- }
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int cx18_av_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- if (!cx18_av_dbg_match(&reg->match))
- return -EINVAL;
- if ((reg->reg & 0x3) != 0)
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- reg->size = 4;
- reg->val = cx18_av_read4(cx, reg->reg & 0x00000ffc);
- return 0;
-}
-
-static int cx18_av_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- if (!cx18_av_dbg_match(&reg->match))
- return -EINVAL;
- if ((reg->reg & 0x3) != 0)
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- cx18_av_write4(cx, reg->reg & 0x00000ffc, reg->val);
- return 0;
-}
-#endif
-
-static const struct v4l2_ctrl_ops cx18_av_ctrl_ops = {
- .s_ctrl = cx18_av_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
- .g_chip_ident = cx18_av_g_chip_ident,
- .log_status = cx18_av_log_status,
- .load_fw = cx18_av_load_fw,
- .reset = cx18_av_reset,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
- .s_std = cx18_av_s_std,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = cx18_av_g_register,
- .s_register = cx18_av_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_tuner_ops cx18_av_tuner_ops = {
- .s_radio = cx18_av_s_radio,
- .s_frequency = cx18_av_s_frequency,
- .g_tuner = cx18_av_g_tuner,
- .s_tuner = cx18_av_s_tuner,
-};
-
-static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = {
- .s_clock_freq = cx18_av_s_clock_freq,
- .s_routing = cx18_av_s_audio_routing,
-};
-
-static const struct v4l2_subdev_video_ops cx18_av_video_ops = {
- .s_routing = cx18_av_s_video_routing,
- .s_stream = cx18_av_s_stream,
- .s_mbus_fmt = cx18_av_s_mbus_fmt,
-};
-
-static const struct v4l2_subdev_vbi_ops cx18_av_vbi_ops = {
- .decode_vbi_line = cx18_av_decode_vbi_line,
- .g_sliced_fmt = cx18_av_g_sliced_fmt,
- .s_sliced_fmt = cx18_av_s_sliced_fmt,
- .s_raw_fmt = cx18_av_s_raw_fmt,
-};
-
-static const struct v4l2_subdev_ops cx18_av_ops = {
- .core = &cx18_av_general_ops,
- .tuner = &cx18_av_tuner_ops,
- .audio = &cx18_av_audio_ops,
- .video = &cx18_av_video_ops,
- .vbi = &cx18_av_vbi_ops,
-};
-
-int cx18_av_probe(struct cx18 *cx)
-{
- struct cx18_av_state *state = &cx->av_state;
- struct v4l2_subdev *sd;
- int err;
-
- state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
- state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
- ? V4L2_IDENT_CX23418_843 : V4L2_IDENT_UNKNOWN;
-
- state->vid_input = CX18_AV_COMPOSITE7;
- state->aud_input = CX18_AV_AUDIO8;
- state->audclk_freq = 48000;
- state->audmode = V4L2_TUNER_MODE_LANG1;
- state->slicer_line_delay = 0;
- state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
-
- sd = &state->sd;
- v4l2_subdev_init(sd, &cx18_av_ops);
- v4l2_set_subdevdata(sd, cx);
- snprintf(sd->name, sizeof(sd->name),
- "%s %03x", cx->v4l2_dev.name, (state->rev >> 4));
- sd->grp_id = CX18_HW_418_AV;
- v4l2_ctrl_handler_init(&state->hdl, 9);
- v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 127, 1, 64);
- v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
- V4L2_CID_SATURATION, 0, 127, 1, 64);
- v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
- V4L2_CID_HUE, -128, 127, 1, 0);
-
- state->volume = v4l2_ctrl_new_std(&state->hdl,
- &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
- 0, 65535, 65535 / 100, 0);
- v4l2_ctrl_new_std(&state->hdl,
- &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE,
- 0, 1, 1, 0);
- v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
- V4L2_CID_AUDIO_BALANCE,
- 0, 65535, 65535 / 100, 32768);
- v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
- V4L2_CID_AUDIO_BASS,
- 0, 65535, 65535 / 100, 32768);
- v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
- V4L2_CID_AUDIO_TREBLE,
- 0, 65535, 65535 / 100, 32768);
- sd->ctrl_handler = &state->hdl;
- if (state->hdl.error) {
- int err = state->hdl.error;
-
- v4l2_ctrl_handler_free(&state->hdl);
- return err;
- }
- err = v4l2_device_register_subdev(&cx->v4l2_dev, sd);
- if (err)
- v4l2_ctrl_handler_free(&state->hdl);
- else
- cx18_av_init(cx);
- return err;
-}
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
deleted file mode 100644
index e9c69d9c9e4..00000000000
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * cx18 ADEC header
- *
- * Derived from cx25840-core.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#ifndef _CX18_AV_CORE_H_
-#define _CX18_AV_CORE_H_
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-
-struct cx18;
-
-enum cx18_av_video_input {
- /* Composite video inputs In1-In8 */
- CX18_AV_COMPOSITE1 = 1,
- CX18_AV_COMPOSITE2,
- CX18_AV_COMPOSITE3,
- CX18_AV_COMPOSITE4,
- CX18_AV_COMPOSITE5,
- CX18_AV_COMPOSITE6,
- CX18_AV_COMPOSITE7,
- CX18_AV_COMPOSITE8,
-
- /* S-Video inputs consist of one luma input (In1-In8) ORed with one
- chroma input (In5-In8) */
- CX18_AV_SVIDEO_LUMA1 = 0x10,
- CX18_AV_SVIDEO_LUMA2 = 0x20,
- CX18_AV_SVIDEO_LUMA3 = 0x30,
- CX18_AV_SVIDEO_LUMA4 = 0x40,
- CX18_AV_SVIDEO_LUMA5 = 0x50,
- CX18_AV_SVIDEO_LUMA6 = 0x60,
- CX18_AV_SVIDEO_LUMA7 = 0x70,
- CX18_AV_SVIDEO_LUMA8 = 0x80,
- CX18_AV_SVIDEO_CHROMA4 = 0x400,
- CX18_AV_SVIDEO_CHROMA5 = 0x500,
- CX18_AV_SVIDEO_CHROMA6 = 0x600,
- CX18_AV_SVIDEO_CHROMA7 = 0x700,
- CX18_AV_SVIDEO_CHROMA8 = 0x800,
-
- /* S-Video aliases for common luma/chroma combinations */
- CX18_AV_SVIDEO1 = 0x510,
- CX18_AV_SVIDEO2 = 0x620,
- CX18_AV_SVIDEO3 = 0x730,
- CX18_AV_SVIDEO4 = 0x840,
-
- /* Component Video inputs consist of one luma input (In1-In8) ORed
- with a red chroma (In4-In6) and blue chroma input (In7-In8) */
- CX18_AV_COMPONENT_LUMA1 = 0x1000,
- CX18_AV_COMPONENT_LUMA2 = 0x2000,
- CX18_AV_COMPONENT_LUMA3 = 0x3000,
- CX18_AV_COMPONENT_LUMA4 = 0x4000,
- CX18_AV_COMPONENT_LUMA5 = 0x5000,
- CX18_AV_COMPONENT_LUMA6 = 0x6000,
- CX18_AV_COMPONENT_LUMA7 = 0x7000,
- CX18_AV_COMPONENT_LUMA8 = 0x8000,
- CX18_AV_COMPONENT_R_CHROMA4 = 0x40000,
- CX18_AV_COMPONENT_R_CHROMA5 = 0x50000,
- CX18_AV_COMPONENT_R_CHROMA6 = 0x60000,
- CX18_AV_COMPONENT_B_CHROMA7 = 0x700000,
- CX18_AV_COMPONENT_B_CHROMA8 = 0x800000,
-
- /* Component Video aliases for common combinations */
- CX18_AV_COMPONENT1 = 0x861000,
-};
-
-enum cx18_av_audio_input {
- /* Audio inputs: serial or In4-In8 */
- CX18_AV_AUDIO_SERIAL1,
- CX18_AV_AUDIO_SERIAL2,
- CX18_AV_AUDIO4 = 4,
- CX18_AV_AUDIO5,
- CX18_AV_AUDIO6,
- CX18_AV_AUDIO7,
- CX18_AV_AUDIO8,
-};
-
-struct cx18_av_state {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- struct v4l2_ctrl *volume;
- int radio;
- v4l2_std_id std;
- enum cx18_av_video_input vid_input;
- enum cx18_av_audio_input aud_input;
- u32 audclk_freq;
- int audmode;
- u32 id;
- u32 rev;
- int is_initialized;
-
- /*
- * The VBI slicer starts operating and counting lines, beginning at
- * slicer line count of 1, at D lines after the deassertion of VRESET.
- * This staring field line, S, is 6 (& 319) or 10 (& 273) for 625 or 525
- * line systems respectively. Sliced ancillary data captured on VBI
- * slicer line M is inserted after the VBI slicer is done with line M,
- * when VBI slicer line count is N = M+1. Thus when the VBI slicer
- * reports a VBI slicer line number with ancillary data, the IDID0 byte
- * indicates VBI slicer line N. The actual field line that the captured
- * data comes from is
- *
- * L = M+(S+D-1) = N-1+(S+D-1) = N + (S+D-2).
- *
- * L is the line in the field, not frame, from which the VBI data came.
- * N is the line reported by the slicer in the ancillary data.
- * D is the slicer_line_delay value programmed into register 0x47f.
- * S is 6 for 625 line systems or 10 for 525 line systems
- * (S+D-2) is the slicer_line_offset used to convert slicer reported
- * line counts to actual field lines.
- */
- int slicer_line_delay;
- int slicer_line_offset;
-};
-
-
-/* Registers */
-#define CXADEC_CHIP_TYPE_TIGER 0x837
-#define CXADEC_CHIP_TYPE_MAKO 0x843
-
-#define CXADEC_HOST_REG1 0x000
-#define CXADEC_HOST_REG2 0x001
-
-#define CXADEC_CHIP_CTRL 0x100
-#define CXADEC_AFE_CTRL 0x104
-#define CXADEC_PLL_CTRL1 0x108
-#define CXADEC_VID_PLL_FRAC 0x10C
-#define CXADEC_AUX_PLL_FRAC 0x110
-#define CXADEC_PIN_CTRL1 0x114
-#define CXADEC_PIN_CTRL2 0x118
-#define CXADEC_PIN_CFG1 0x11C
-#define CXADEC_PIN_CFG2 0x120
-
-#define CXADEC_PIN_CFG3 0x124
-#define CXADEC_I2S_MCLK 0x127
-
-#define CXADEC_AUD_LOCK1 0x128
-#define CXADEC_AUD_LOCK2 0x12C
-#define CXADEC_POWER_CTRL 0x130
-#define CXADEC_AFE_DIAG_CTRL1 0x134
-#define CXADEC_AFE_DIAG_CTRL2 0x138
-#define CXADEC_AFE_DIAG_CTRL3 0x13C
-#define CXADEC_PLL_DIAG_CTRL 0x140
-#define CXADEC_TEST_CTRL1 0x144
-#define CXADEC_TEST_CTRL2 0x148
-#define CXADEC_BIST_STAT 0x14C
-#define CXADEC_DLL1_DIAG_CTRL 0x158
-#define CXADEC_DLL2_DIAG_CTRL 0x15C
-
-/* IR registers */
-#define CXADEC_IR_CTRL_REG 0x200
-#define CXADEC_IR_TXCLK_REG 0x204
-#define CXADEC_IR_RXCLK_REG 0x208
-#define CXADEC_IR_CDUTY_REG 0x20C
-#define CXADEC_IR_STAT_REG 0x210
-#define CXADEC_IR_IRQEN_REG 0x214
-#define CXADEC_IR_FILTER_REG 0x218
-#define CXADEC_IR_FIFO_REG 0x21C
-
-/* Video Registers */
-#define CXADEC_MODE_CTRL 0x400
-#define CXADEC_OUT_CTRL1 0x404
-#define CXADEC_OUT_CTRL2 0x408
-#define CXADEC_GEN_STAT 0x40C
-#define CXADEC_INT_STAT_MASK 0x410
-#define CXADEC_LUMA_CTRL 0x414
-
-#define CXADEC_BRIGHTNESS_CTRL_BYTE 0x414
-#define CXADEC_CONTRAST_CTRL_BYTE 0x415
-#define CXADEC_LUMA_CTRL_BYTE_3 0x416
-
-#define CXADEC_HSCALE_CTRL 0x418
-#define CXADEC_VSCALE_CTRL 0x41C
-
-#define CXADEC_CHROMA_CTRL 0x420
-
-#define CXADEC_USAT_CTRL_BYTE 0x420
-#define CXADEC_VSAT_CTRL_BYTE 0x421
-#define CXADEC_HUE_CTRL_BYTE 0x422
-
-#define CXADEC_VBI_LINE_CTRL1 0x424
-#define CXADEC_VBI_LINE_CTRL2 0x428
-#define CXADEC_VBI_LINE_CTRL3 0x42C
-#define CXADEC_VBI_LINE_CTRL4 0x430
-#define CXADEC_VBI_LINE_CTRL5 0x434
-#define CXADEC_VBI_FC_CFG 0x438
-#define CXADEC_VBI_MISC_CFG1 0x43C
-#define CXADEC_VBI_MISC_CFG2 0x440
-#define CXADEC_VBI_PAY1 0x444
-#define CXADEC_VBI_PAY2 0x448
-#define CXADEC_VBI_CUST1_CFG1 0x44C
-#define CXADEC_VBI_CUST1_CFG2 0x450
-#define CXADEC_VBI_CUST1_CFG3 0x454
-#define CXADEC_VBI_CUST2_CFG1 0x458
-#define CXADEC_VBI_CUST2_CFG2 0x45C
-#define CXADEC_VBI_CUST2_CFG3 0x460
-#define CXADEC_VBI_CUST3_CFG1 0x464
-#define CXADEC_VBI_CUST3_CFG2 0x468
-#define CXADEC_VBI_CUST3_CFG3 0x46C
-#define CXADEC_HORIZ_TIM_CTRL 0x470
-#define CXADEC_VERT_TIM_CTRL 0x474
-#define CXADEC_SRC_COMB_CFG 0x478
-#define CXADEC_CHROMA_VBIOFF_CFG 0x47C
-#define CXADEC_FIELD_COUNT 0x480
-#define CXADEC_MISC_TIM_CTRL 0x484
-#define CXADEC_DFE_CTRL1 0x488
-#define CXADEC_DFE_CTRL2 0x48C
-#define CXADEC_DFE_CTRL3 0x490
-#define CXADEC_PLL_CTRL2 0x494
-#define CXADEC_HTL_CTRL 0x498
-#define CXADEC_COMB_CTRL 0x49C
-#define CXADEC_CRUSH_CTRL 0x4A0
-#define CXADEC_SOFT_RST_CTRL 0x4A4
-#define CXADEC_MV_DT_CTRL2 0x4A8
-#define CXADEC_MV_DT_CTRL3 0x4AC
-#define CXADEC_MISC_DIAG_CTRL 0x4B8
-
-#define CXADEC_DL_CTL 0x800
-#define CXADEC_DL_CTL_ADDRESS_LOW 0x800 /* Byte 1 in DL_CTL */
-#define CXADEC_DL_CTL_ADDRESS_HIGH 0x801 /* Byte 2 in DL_CTL */
-#define CXADEC_DL_CTL_DATA 0x802 /* Byte 3 in DL_CTL */
-#define CXADEC_DL_CTL_CONTROL 0x803 /* Byte 4 in DL_CTL */
-
-#define CXADEC_STD_DET_STATUS 0x804
-
-#define CXADEC_STD_DET_CTL 0x808
-#define CXADEC_STD_DET_CTL_AUD_CTL 0x808 /* Byte 1 in STD_DET_CTL */
-#define CXADEC_STD_DET_CTL_PREF_MODE 0x809 /* Byte 2 in STD_DET_CTL */
-
-#define CXADEC_DW8051_INT 0x80C
-#define CXADEC_GENERAL_CTL 0x810
-#define CXADEC_AAGC_CTL 0x814
-#define CXADEC_IF_SRC_CTL 0x818
-#define CXADEC_ANLOG_DEMOD_CTL 0x81C
-#define CXADEC_ROT_FREQ_CTL 0x820
-#define CXADEC_FM1_CTL 0x824
-#define CXADEC_PDF_CTL 0x828
-#define CXADEC_DFT1_CTL1 0x82C
-#define CXADEC_DFT1_CTL2 0x830
-#define CXADEC_DFT_STATUS 0x834
-#define CXADEC_DFT2_CTL1 0x838
-#define CXADEC_DFT2_CTL2 0x83C
-#define CXADEC_DFT2_STATUS 0x840
-#define CXADEC_DFT3_CTL1 0x844
-#define CXADEC_DFT3_CTL2 0x848
-#define CXADEC_DFT3_STATUS 0x84C
-#define CXADEC_DFT4_CTL1 0x850
-#define CXADEC_DFT4_CTL2 0x854
-#define CXADEC_DFT4_STATUS 0x858
-#define CXADEC_AM_MTS_DET 0x85C
-#define CXADEC_ANALOG_MUX_CTL 0x860
-#define CXADEC_DIG_PLL_CTL1 0x864
-#define CXADEC_DIG_PLL_CTL2 0x868
-#define CXADEC_DIG_PLL_CTL3 0x86C
-#define CXADEC_DIG_PLL_CTL4 0x870
-#define CXADEC_DIG_PLL_CTL5 0x874
-#define CXADEC_DEEMPH_GAIN_CTL 0x878
-#define CXADEC_DEEMPH_COEF1 0x87C
-#define CXADEC_DEEMPH_COEF2 0x880
-#define CXADEC_DBX1_CTL1 0x884
-#define CXADEC_DBX1_CTL2 0x888
-#define CXADEC_DBX1_STATUS 0x88C
-#define CXADEC_DBX2_CTL1 0x890
-#define CXADEC_DBX2_CTL2 0x894
-#define CXADEC_DBX2_STATUS 0x898
-#define CXADEC_AM_FM_DIFF 0x89C
-
-/* NICAM registers go here */
-#define CXADEC_NICAM_STATUS 0x8C8
-#define CXADEC_DEMATRIX_CTL 0x8CC
-
-#define CXADEC_PATH1_CTL1 0x8D0
-#define CXADEC_PATH1_VOL_CTL 0x8D4
-#define CXADEC_PATH1_EQ_CTL 0x8D8
-#define CXADEC_PATH1_SC_CTL 0x8DC
-
-#define CXADEC_PATH2_CTL1 0x8E0
-#define CXADEC_PATH2_VOL_CTL 0x8E4
-#define CXADEC_PATH2_EQ_CTL 0x8E8
-#define CXADEC_PATH2_SC_CTL 0x8EC
-
-#define CXADEC_SRC_CTL 0x8F0
-#define CXADEC_SRC_LF_COEF 0x8F4
-#define CXADEC_SRC1_CTL 0x8F8
-#define CXADEC_SRC2_CTL 0x8FC
-#define CXADEC_SRC3_CTL 0x900
-#define CXADEC_SRC4_CTL 0x904
-#define CXADEC_SRC5_CTL 0x908
-#define CXADEC_SRC6_CTL 0x90C
-
-#define CXADEC_BASEBAND_OUT_SEL 0x910
-#define CXADEC_I2S_IN_CTL 0x914
-#define CXADEC_I2S_OUT_CTL 0x918
-#define CXADEC_AC97_CTL 0x91C
-#define CXADEC_QAM_PDF 0x920
-#define CXADEC_QAM_CONST_DEC 0x924
-#define CXADEC_QAM_ROTATOR_FREQ 0x948
-
-/* Bit definitions / settings used in Mako Audio */
-#define CXADEC_PREF_MODE_MONO_LANGA 0
-#define CXADEC_PREF_MODE_MONO_LANGB 1
-#define CXADEC_PREF_MODE_MONO_LANGC 2
-#define CXADEC_PREF_MODE_FALLBACK 3
-#define CXADEC_PREF_MODE_STEREO 4
-#define CXADEC_PREF_MODE_DUAL_LANG_AC 5
-#define CXADEC_PREF_MODE_DUAL_LANG_BC 6
-#define CXADEC_PREF_MODE_DUAL_LANG_AB 7
-
-
-#define CXADEC_DETECT_STEREO 1
-#define CXADEC_DETECT_DUAL 2
-#define CXADEC_DETECT_TRI 4
-#define CXADEC_DETECT_SAP 0x10
-#define CXADEC_DETECT_NO_SIGNAL 0xFF
-
-#define CXADEC_SELECT_AUDIO_STANDARD_BG 0xF0 /* NICAM BG and A2 BG */
-#define CXADEC_SELECT_AUDIO_STANDARD_DK1 0xF1 /* NICAM DK and A2 DK */
-#define CXADEC_SELECT_AUDIO_STANDARD_DK2 0xF2
-#define CXADEC_SELECT_AUDIO_STANDARD_DK3 0xF3
-#define CXADEC_SELECT_AUDIO_STANDARD_I 0xF4 /* NICAM I and A1 */
-#define CXADEC_SELECT_AUDIO_STANDARD_L 0xF5 /* NICAM L and System L AM */
-#define CXADEC_SELECT_AUDIO_STANDARD_BTSC 0xF6
-#define CXADEC_SELECT_AUDIO_STANDARD_EIAJ 0xF7
-#define CXADEC_SELECT_AUDIO_STANDARD_A2_M 0xF8 /* A2 M */
-#define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */
-#define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */
-
-static inline struct cx18_av_state *to_cx18_av_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct cx18_av_state, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct cx18_av_state, hdl)->sd;
-}
-
-/* ----------------------------------------------------------------------- */
-/* cx18_av-core.c */
-int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
-int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value);
-int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value);
-int cx18_av_write_expect(struct cx18 *cx, u16 addr, u8 value, u8 eval, u8 mask);
-int cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval,
- u32 mask);
-u8 cx18_av_read(struct cx18 *cx, u16 addr);
-u32 cx18_av_read4(struct cx18 *cx, u16 addr);
-int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
-int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
-void cx18_av_std_setup(struct cx18 *cx);
-
-int cx18_av_probe(struct cx18 *cx);
-
-/* ----------------------------------------------------------------------- */
-/* cx18_av-firmware.c */
-int cx18_av_loadfw(struct cx18 *cx);
-
-/* ----------------------------------------------------------------------- */
-/* cx18_av-audio.c */
-int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
-void cx18_av_audio_set_path(struct cx18 *cx);
-extern const struct v4l2_ctrl_ops cx18_av_audio_ctrl_ops;
-
-/* ----------------------------------------------------------------------- */
-/* cx18_av-vbi.c */
-int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
- struct v4l2_decode_vbi_line *vbi);
-int cx18_av_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt);
-int cx18_av_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
-int cx18_av_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
-
-#endif
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
deleted file mode 100644
index 280aa4d2248..00000000000
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * cx18 ADEC firmware functions
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include <linux/firmware.h>
-
-#define CX18_AUDIO_ENABLE 0xc72014
-#define CX18_AI1_MUX_MASK 0x30
-#define CX18_AI1_MUX_I2S1 0x00
-#define CX18_AI1_MUX_I2S2 0x10
-#define CX18_AI1_MUX_843_I2S 0x20
-#define CX18_AI1_MUX_INVALID 0x30
-
-#define FWFILE "v4l-cx23418-dig.fw"
-
-static int cx18_av_verifyfw(struct cx18 *cx, const struct firmware *fw)
-{
- struct v4l2_subdev *sd = &cx->av_state.sd;
- int ret = 0;
- const u8 *data;
- u32 size;
- int addr;
- u32 expected, dl_control;
-
- /* Ensure we put the 8051 in reset and enable firmware upload mode */
- dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
- do {
- dl_control &= 0x00ffffff;
- dl_control |= 0x0f000000;
- cx18_av_write4_noretry(cx, CXADEC_DL_CTL, dl_control);
- dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
- } while ((dl_control & 0xff000000) != 0x0f000000);
-
- /* Read and auto increment until at address 0x0000 */
- while (dl_control & 0x3fff)
- dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
-
- data = fw->data;
- size = fw->size;
- for (addr = 0; addr < size; addr++) {
- dl_control &= 0xffff3fff; /* ignore top 2 bits of address */
- expected = 0x0f000000 | ((u32)data[addr] << 16) | addr;
- if (expected != dl_control) {
- CX18_ERR_DEV(sd, "verification of %s firmware load "
- "failed: expected %#010x got %#010x\n",
- FWFILE, expected, dl_control);
- ret = -EIO;
- break;
- }
- dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
- }
- if (ret == 0)
- CX18_INFO_DEV(sd, "verified load of %s firmware (%d bytes)\n",
- FWFILE, size);
- return ret;
-}
-
-int cx18_av_loadfw(struct cx18 *cx)
-{
- struct v4l2_subdev *sd = &cx->av_state.sd;
- const struct firmware *fw = NULL;
- u32 size;
- u32 u, v;
- const u8 *ptr;
- int i;
- int retries1 = 0;
-
- if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) {
- CX18_ERR_DEV(sd, "unable to open firmware %s\n", FWFILE);
- return -EINVAL;
- }
-
- /* The firmware load often has byte errors, so allow for several
- retries, both at byte level and at the firmware load level. */
- while (retries1 < 5) {
- cx18_av_write4_expect(cx, CXADEC_CHIP_CTRL, 0x00010000,
- 0x00008430, 0xffffffff); /* cx25843 */
- cx18_av_write_expect(cx, CXADEC_STD_DET_CTL, 0xf6, 0xf6, 0xff);
-
- /* Reset the Mako core, Register is alias of CXADEC_CHIP_CTRL */
- cx18_av_write4_expect(cx, 0x8100, 0x00010000,
- 0x00008430, 0xffffffff); /* cx25843 */
-
- /* Put the 8051 in reset and enable firmware upload */
- cx18_av_write4_noretry(cx, CXADEC_DL_CTL, 0x0F000000);
-
- ptr = fw->data;
- size = fw->size;
-
- for (i = 0; i < size; i++) {
- u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16);
- u32 value = 0;
- int retries2;
- int unrec_err = 0;
-
- for (retries2 = 0; retries2 < CX18_MAX_MMIO_WR_RETRIES;
- retries2++) {
- cx18_av_write4_noretry(cx, CXADEC_DL_CTL,
- dl_control);
- udelay(10);
- value = cx18_av_read4(cx, CXADEC_DL_CTL);
- if (value == dl_control)
- break;
- /* Check if we can correct the byte by changing
- the address. We can only write the lower
- address byte of the address. */
- if ((value & 0x3F00) != (dl_control & 0x3F00)) {
- unrec_err = 1;
- break;
- }
- }
- if (unrec_err || retries2 >= CX18_MAX_MMIO_WR_RETRIES)
- break;
- }
- if (i == size)
- break;
- retries1++;
- }
- if (retries1 >= 5) {
- CX18_ERR_DEV(sd, "unable to load firmware %s\n", FWFILE);
- release_firmware(fw);
- return -EIO;
- }
-
- cx18_av_write4_expect(cx, CXADEC_DL_CTL,
- 0x03000000 | fw->size, 0x03000000, 0x13000000);
-
- CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
-
- if (cx18_av_verifyfw(cx, fw) == 0)
- cx18_av_write4_expect(cx, CXADEC_DL_CTL,
- 0x13000000 | fw->size, 0x13000000, 0x13000000);
-
- /* Output to the 416 */
- cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x78000);
-
- /* Audio input control 1 set to Sony mode */
- /* Audio output input 2 is 0 for slave operation input */
- /* 0xC4000914[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
- /* 0xC4000914[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
- after WS transition for first bit of audio word. */
- cx18_av_write4(cx, CXADEC_I2S_IN_CTL, 0x000000A0);
-
- /* Audio output control 1 is set to Sony mode */
- /* Audio output control 2 is set to 1 for master mode */
- /* 0xC4000918[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
- /* 0xC4000918[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
- after WS transition for first bit of audio word. */
- /* 0xC4000918[8]: 0 = slave operation, 1 = master (SCK_OUT and WS_OUT
- are generated) */
- cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0);
-
- /* set alt I2s master clock to /0x16 and enable alt divider i2s
- passthrough */
- cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5600B687);
-
- cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, 0x000000F6, 0x000000F6,
- 0x3F00FFFF);
- /* CxDevWrReg(CXADEC_STD_DET_CTL, 0x000000FF); */
-
- /* Set bit 0 in register 0x9CC to signify that this is MiniMe. */
- /* Register 0x09CC is defined by the Merlin firmware, and doesn't
- have a name in the spec. */
- cx18_av_write4(cx, 0x09CC, 1);
-
- v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
- /* If bit 11 is 1, clear bit 10 */
- if (v & 0x800)
- cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE,
- 0, 0x400);
-
- /* Toggle the AI1 MUX */
- v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
- u = v & CX18_AI1_MUX_MASK;
- v &= ~CX18_AI1_MUX_MASK;
- if (u == CX18_AI1_MUX_843_I2S || u == CX18_AI1_MUX_INVALID) {
- /* Switch to I2S1 */
- v |= CX18_AI1_MUX_I2S1;
- cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
- v, CX18_AI1_MUX_MASK);
- /* Switch back to the A/V decoder core I2S output */
- v = (v & ~CX18_AI1_MUX_MASK) | CX18_AI1_MUX_843_I2S;
- } else {
- /* Switch to the A/V decoder core I2S output */
- v |= CX18_AI1_MUX_843_I2S;
- cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
- v, CX18_AI1_MUX_MASK);
- /* Switch back to I2S1 or I2S2 */
- v = (v & ~CX18_AI1_MUX_MASK) | u;
- }
- cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
- v, CX18_AI1_MUX_MASK);
-
- /* Enable WW auto audio standard detection */
- v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
- v |= 0xFF; /* Auto by default */
- v |= 0x400; /* Stereo by default */
- v |= 0x14000000;
- cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF);
-
- release_firmware(fw);
- return 0;
-}
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
deleted file mode 100644
index baa36fbcd4d..00000000000
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * cx18 ADEC VBI functions
- *
- * Derived from cx25840-vbi.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-
-#include "cx18-driver.h"
-
-/*
- * For sliced VBI output, we set up to use VIP-1.1, 8-bit mode,
- * NN counts 1 byte Dwords, an IDID with the VBI line # in it.
- * Thus, according to the VIP-2 Spec, our VBI ancillary data lines
- * (should!) look like:
- * 4 byte EAV code: 0xff 0x00 0x00 0xRP
- * unknown number of possible idle bytes
- * 3 byte Anc data preamble: 0x00 0xff 0xff
- * 1 byte data identifier: ne010iii (parity bits, 010, DID bits)
- * 1 byte secondary data id: nessssss (parity bits, SDID bits)
- * 1 byte data word count: necccccc (parity bits, NN Dword count)
- * 2 byte Internal DID: VBI-line-# 0x80
- * NN data bytes
- * 1 byte checksum
- * Fill bytes needed to fil out to 4*NN bytes of payload
- *
- * The RP codes for EAVs when in VIP-1.1 mode, not in raw mode, &
- * in the vertical blanking interval are:
- * 0xb0 (Task 0 VerticalBlank HorizontalBlank 0 0 0 0)
- * 0xf0 (Task EvenField VerticalBlank HorizontalBlank 0 0 0 0)
- *
- * Since the V bit is only allowed to toggle in the EAV RP code, just
- * before the first active region line and for active lines, they are:
- * 0x90 (Task 0 0 HorizontalBlank 0 0 0 0)
- * 0xd0 (Task EvenField 0 HorizontalBlank 0 0 0 0)
- *
- * The user application DID bytes we care about are:
- * 0x91 (1 0 010 0 !ActiveLine AncDataPresent)
- * 0x55 (0 1 010 2ndField !ActiveLine AncDataPresent)
- *
- */
-static const u8 sliced_vbi_did[2] = { 0x91, 0x55 };
-
-struct vbi_anc_data {
- /* u8 eav[4]; */
- /* u8 idle[]; Variable number of idle bytes */
- u8 preamble[3];
- u8 did;
- u8 sdid;
- u8 data_count;
- u8 idid[2];
- u8 payload[1]; /* data_count of payload */
- /* u8 checksum; */
- /* u8 fill[]; Variable number of fill bytes */
-};
-
-static int odd_parity(u8 c)
-{
- c ^= (c >> 4);
- c ^= (c >> 2);
- c ^= (c >> 1);
-
- return c & 1;
-}
-
-static int decode_vps(u8 *dst, u8 *p)
-{
- static const u8 biphase_tbl[] = {
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
- 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
- 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
- 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
- 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
- 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
- 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
- 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
- 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
- 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
- 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
- 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
- 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
- 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
- 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
- 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
- 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
- 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
- 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
- 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
- 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
- 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- };
-
- u8 c, err = 0;
- int i;
-
- for (i = 0; i < 2 * 13; i += 2) {
- err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
- c = (biphase_tbl[p[i + 1]] & 0xf) |
- ((biphase_tbl[p[i]] & 0xf) << 4);
- dst[i / 2] = c;
- }
-
- return err & 0xf0;
-}
-
-int cx18_av_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- struct cx18_av_state *state = &cx->av_state;
- static const u16 lcr2vbi[] = {
- 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
- 0, V4L2_SLICED_WSS_625, 0, /* 4 */
- V4L2_SLICED_CAPTION_525, /* 6 */
- 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
- 0, 0, 0, 0
- };
- int is_pal = !(state->std & V4L2_STD_525_60);
- int i;
-
- memset(svbi, 0, sizeof(*svbi));
- /* we're done if raw VBI is active */
- if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
- return 0;
-
- if (is_pal) {
- for (i = 7; i <= 23; i++) {
- u8 v = cx18_av_read(cx, 0x424 + i - 7);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |= svbi->service_lines[0][i] |
- svbi->service_lines[1][i];
- }
- } else {
- for (i = 10; i <= 21; i++) {
- u8 v = cx18_av_read(cx, 0x424 + i - 10);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |= svbi->service_lines[0][i] |
- svbi->service_lines[1][i];
- }
- }
- return 0;
-}
-
-int cx18_av_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- struct cx18_av_state *state = &cx->av_state;
-
- /* Setup standard */
- cx18_av_std_setup(cx);
-
- /* VBI Offset */
- cx18_av_write(cx, 0x47f, state->slicer_line_delay);
- cx18_av_write(cx, 0x404, 0x2e);
- return 0;
-}
-
-int cx18_av_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- struct cx18_av_state *state = &cx->av_state;
- int is_pal = !(state->std & V4L2_STD_525_60);
- int i, x;
- u8 lcr[24];
-
- for (x = 0; x <= 23; x++)
- lcr[x] = 0x00;
-
- /* Setup standard */
- cx18_av_std_setup(cx);
-
- /* Sliced VBI */
- cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
- cx18_av_write(cx, 0x406, 0x13);
- cx18_av_write(cx, 0x47f, state->slicer_line_delay);
-
- /* Force impossible lines to 0 */
- if (is_pal) {
- for (i = 0; i <= 6; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- } else {
- for (i = 0; i <= 9; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
-
- for (i = 22; i <= 23; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- }
-
- /* Build register values for requested service lines */
- for (i = 7; i <= 23; i++) {
- for (x = 0; x <= 1; x++) {
- switch (svbi->service_lines[1-x][i]) {
- case V4L2_SLICED_TELETEXT_B:
- lcr[i] |= 1 << (4 * x);
- break;
- case V4L2_SLICED_WSS_625:
- lcr[i] |= 4 << (4 * x);
- break;
- case V4L2_SLICED_CAPTION_525:
- lcr[i] |= 6 << (4 * x);
- break;
- case V4L2_SLICED_VPS:
- lcr[i] |= 9 << (4 * x);
- break;
- }
- }
- }
-
- if (is_pal) {
- for (x = 1, i = 0x424; i <= 0x434; i++, x++)
- cx18_av_write(cx, i, lcr[6 + x]);
- } else {
- for (x = 1, i = 0x424; i <= 0x430; i++, x++)
- cx18_av_write(cx, i, lcr[9 + x]);
- for (i = 0x431; i <= 0x434; i++)
- cx18_av_write(cx, i, 0);
- }
-
- cx18_av_write(cx, 0x43c, 0x16);
- /* Should match vblank set in cx18_av_std_setup() */
- cx18_av_write(cx, 0x474, is_pal ? 38 : 26);
- return 0;
-}
-
-int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
- struct v4l2_decode_vbi_line *vbi)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- struct cx18_av_state *state = &cx->av_state;
- struct vbi_anc_data *anc = (struct vbi_anc_data *)vbi->p;
- u8 *p;
- int did, sdid, l, err = 0;
-
- /*
- * Check for the ancillary data header for sliced VBI
- */
- if (anc->preamble[0] ||
- anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
- (anc->did != sliced_vbi_did[0] &&
- anc->did != sliced_vbi_did[1])) {
- vbi->line = vbi->type = 0;
- return 0;
- }
-
- did = anc->did;
- sdid = anc->sdid & 0xf;
- l = anc->idid[0] & 0x3f;
- l += state->slicer_line_offset;
- p = anc->payload;
-
- /* Decode the SDID set by the slicer */
- switch (sdid) {
- case 1:
- sdid = V4L2_SLICED_TELETEXT_B;
- break;
- case 4:
- sdid = V4L2_SLICED_WSS_625;
- break;
- case 6:
- sdid = V4L2_SLICED_CAPTION_525;
- err = !odd_parity(p[0]) || !odd_parity(p[1]);
- break;
- case 9:
- sdid = V4L2_SLICED_VPS;
- if (decode_vps(p, p) != 0)
- err = 1;
- break;
- default:
- sdid = 0;
- err = 1;
- break;
- }
-
- vbi->type = err ? 0 : sdid;
- vbi->line = err ? 0 : l;
- vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
- vbi->p = p;
- return 0;
-}
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
deleted file mode 100644
index c07c849b1aa..00000000000
--- a/drivers/media/video/cx18/cx18-cards.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/*
- * cx18 functions to query card hardware
- *
- * Derived from ivtv-cards.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-cards.h"
-#include "cx18-av-core.h"
-#include "cx18-i2c.h"
-#include <media/cs5345.h>
-
-#define V4L2_STD_PAL_SECAM (V4L2_STD_PAL|V4L2_STD_SECAM)
-
-/********************** card configuration *******************************/
-
-/* usual i2c tuner addresses to probe */
-static struct cx18_card_tuner_i2c cx18_i2c_std = {
- .radio = { I2C_CLIENT_END },
- .demod = { 0x43, I2C_CLIENT_END },
- .tv = { 0x61, 0x60, I2C_CLIENT_END },
-};
-
-/*
- * usual i2c tuner addresses to probe with additional demod address for
- * an NXP TDA8295 at 0x42 (N.B. it can possibly be at 0x4b or 0x4c too).
- */
-static struct cx18_card_tuner_i2c cx18_i2c_nxp = {
- .radio = { I2C_CLIENT_END },
- .demod = { 0x42, 0x43, I2C_CLIENT_END },
- .tv = { 0x61, 0x60, I2C_CLIENT_END },
-};
-
-/* Please add new PCI IDs to: http://pci-ids.ucw.cz/
- This keeps the PCI ID database up to date. Note that the entries
- must be added under vendor 0x4444 (Conexant) as subsystem IDs.
- New vendor IDs should still be added to the vendor ID list. */
-
-/* Hauppauge HVR-1600 cards */
-
-/* Note: for Hauppauge cards the tveeprom information is used instead
- of PCI IDs */
-static const struct cx18_card cx18_card_hvr1600_esmt = {
- .type = CX18_CARD_HVR_1600_ESMT,
- .name = "Hauppauge HVR-1600",
- .comment = "Simultaneous Digital and Analog TV capture supported\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_CS5345,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
- CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
- CX18_HW_Z8F0811_IR_HAUP,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
- { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
- { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
- { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
- { CX18_CARD_INPUT_LINE_IN1,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
- { CX18_CARD_INPUT_LINE_IN2,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
- },
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
- .ddr = {
- /* ESMT M13S128324A-5B memory */
- .chip_config = 0x003,
- .refresh = 0x30c,
- .timing1 = 0x44220e82,
- .timing2 = 0x08,
- .tune_lane = 0,
- .initial_emrs = 0,
- },
- .gpio_init.initial_value = 0x3001,
- .gpio_init.direction = 0x3001,
- .gpio_i2c_slave_reset = {
- .active_lo_mask = 0x3001,
- .msecs_asserted = 10,
- .msecs_recovery = 40,
- .ir_reset_mask = 0x0001,
- },
- .i2c = &cx18_i2c_std,
-};
-
-static const struct cx18_card cx18_card_hvr1600_s5h1411 = {
- .type = CX18_CARD_HVR_1600_S5H1411,
- .name = "Hauppauge HVR-1600",
- .comment = "Simultaneous Digital and Analog TV capture supported\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_CS5345,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
- CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
- CX18_HW_Z8F0811_IR_HAUP,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
- { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
- { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
- { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
- { CX18_CARD_INPUT_LINE_IN1,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
- { CX18_CARD_INPUT_LINE_IN2,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
- },
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
- .ddr = {
- /* ESMT M13S128324A-5B memory */
- .chip_config = 0x003,
- .refresh = 0x30c,
- .timing1 = 0x44220e82,
- .timing2 = 0x08,
- .tune_lane = 0,
- .initial_emrs = 0,
- },
- .gpio_init.initial_value = 0x3801,
- .gpio_init.direction = 0x3801,
- .gpio_i2c_slave_reset = {
- .active_lo_mask = 0x3801,
- .msecs_asserted = 10,
- .msecs_recovery = 40,
- .ir_reset_mask = 0x0001,
- },
- .i2c = &cx18_i2c_nxp,
-};
-
-static const struct cx18_card cx18_card_hvr1600_samsung = {
- .type = CX18_CARD_HVR_1600_SAMSUNG,
- .name = "Hauppauge HVR-1600 (Preproduction)",
- .comment = "Simultaneous Digital and Analog TV capture supported\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_CS5345,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
- CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
- CX18_HW_Z8F0811_IR_HAUP,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
- { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
- { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
- { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
- { CX18_CARD_INPUT_LINE_IN1,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
- { CX18_CARD_INPUT_LINE_IN2,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
- },
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
- .ddr = {
- /* Samsung K4D263238G-VC33 memory */
- .chip_config = 0x003,
- .refresh = 0x30c,
- .timing1 = 0x23230b73,
- .timing2 = 0x08,
- .tune_lane = 0,
- .initial_emrs = 2,
- },
- .gpio_init.initial_value = 0x3001,
- .gpio_init.direction = 0x3001,
- .gpio_i2c_slave_reset = {
- .active_lo_mask = 0x3001,
- .msecs_asserted = 10,
- .msecs_recovery = 40,
- .ir_reset_mask = 0x0001,
- },
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Compro VideoMate H900: note that this card is analog only! */
-
-static const struct cx18_card_pci_info cx18_pci_h900[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_COMPRO, 0xe100 },
- { 0, 0, 0 }
-};
-
-static const struct cx18_card cx18_card_h900 = {
- .type = CX18_CARD_COMPRO_H900,
- .name = "Compro VideoMate H900",
- .comment = "Analog TV capture supported\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
- { CX18_CARD_INPUT_SVIDEO1, 1,
- CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1,
- CX18_AV_AUDIO_SERIAL1, 0 },
- },
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO_SERIAL1, 0 },
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .ddr = {
- /* EtronTech EM6A9160TS-5G memory */
- .chip_config = 0x50003,
- .refresh = 0x753,
- .timing1 = 0x24330e84,
- .timing2 = 0x1f,
- .tune_lane = 0,
- .initial_emrs = 0,
- },
- .xceive_pin = 15,
- .pci_list = cx18_pci_h900,
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Yuan MPC718: not working at the moment! */
-
-static const struct cx18_card_pci_info cx18_pci_mpc718[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_YUAN, 0x0718 },
- { 0, 0, 0 }
-};
-
-static const struct cx18_card cx18_card_mpc718 = {
- .type = CX18_CARD_YUAN_MPC718,
- .name = "Yuan MPC718 MiniPCI DVB-T/Analog",
- .comment = "Experimenters needed for device to work well.\n"
- "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_GPIO_MUX,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
- CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
- { CX18_CARD_INPUT_SVIDEO1, 1,
- CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
- { CX18_CARD_INPUT_SVIDEO2, 2,
- CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
- { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
- { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
- },
- .tuners = {
- /* XC3028 tuner */
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- /* FIXME - the FM radio is just a guess and driver doesn't use SIF */
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
- .ddr = {
- /* Hynix HY5DU283222B DDR RAM */
- .chip_config = 0x303,
- .refresh = 0x3bd,
- .timing1 = 0x36320966,
- .timing2 = 0x1f,
- .tune_lane = 0,
- .initial_emrs = 2,
- },
- .gpio_init.initial_value = 0x1,
- .gpio_init.direction = 0x3,
- /* FIXME - these GPIO's are just guesses */
- .gpio_audio_input = { .mask = 0x3,
- .tuner = 0x1,
- .linein = 0x3,
- .radio = 0x1 },
- .xceive_pin = 0,
- .pci_list = cx18_pci_mpc718,
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* GoTView PCI */
-
-static const struct cx18_card_pci_info cx18_pci_gotview_dvd3[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_GOTVIEW, 0x3343 },
- { 0, 0, 0 }
-};
-
-static const struct cx18_card cx18_card_gotview_dvd3 = {
- .type = CX18_CARD_GOTVIEW_PCI_DVD3,
- .name = "GoTView PCI DVD3 Hybrid",
- .comment = "Experimenters needed for device to work well.\n"
- "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_GPIO_MUX,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
- CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
- { CX18_CARD_INPUT_SVIDEO1, 1,
- CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
- { CX18_CARD_INPUT_SVIDEO2, 2,
- CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
- { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
- { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
- },
- .tuners = {
- /* XC3028 tuner */
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- /* FIXME - the FM radio is just a guess and driver doesn't use SIF */
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
- .ddr = {
- /* Hynix HY5DU283222B DDR RAM */
- .chip_config = 0x303,
- .refresh = 0x3bd,
- .timing1 = 0x36320966,
- .timing2 = 0x1f,
- .tune_lane = 0,
- .initial_emrs = 2,
- },
- .gpio_init.initial_value = 0x1,
- .gpio_init.direction = 0x3,
-
- .gpio_audio_input = { .mask = 0x3,
- .tuner = 0x1,
- .linein = 0x2,
- .radio = 0x1 },
- .xceive_pin = 0,
- .pci_list = cx18_pci_gotview_dvd3,
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Conexant Raptor PAL/SECAM: note that this card is analog only! */
-
-static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_CONEXANT, 0x0009 },
- { 0, 0, 0 }
-};
-
-static const struct cx18_card cx18_card_cnxt_raptor_pal = {
- .type = CX18_CARD_CNXT_RAPTOR_PAL,
- .name = "Conexant Raptor PAL/SECAM",
- .comment = "Analog TV capture supported\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_GPIO_MUX,
- .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
- { CX18_CARD_INPUT_SVIDEO1, 1,
- CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
- { CX18_CARD_INPUT_SVIDEO2, 2,
- CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
- { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
- { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
- },
- .tuners = {
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
- },
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL1, 2 },
- .ddr = {
- /* MT 46V16M16 memory */
- .chip_config = 0x50306,
- .refresh = 0x753,
- .timing1 = 0x33220953,
- .timing2 = 0x09,
- .tune_lane = 0,
- .initial_emrs = 0,
- },
- .gpio_init.initial_value = 0x1002,
- .gpio_init.direction = 0xf002,
- .gpio_audio_input = { .mask = 0xf002,
- .tuner = 0x1002, /* LED D1 Tuner AF */
- .linein = 0x2000, /* LED D2 Line In 1 */
- .radio = 0x4002 }, /* LED D3 Tuner AF */
- .pci_list = cx18_pci_cnxt_raptor_pal,
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Toshiba Qosmio laptop internal DVB-T/Analog Hybrid Tuner */
-
-static const struct cx18_card_pci_info cx18_pci_toshiba_qosmio_dvbt[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_TOSHIBA, 0x0110 },
- { 0, 0, 0 }
-};
-
-static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
- .type = CX18_CARD_TOSHIBA_QOSMIO_DVBT,
- .name = "Toshiba Qosmio DVB-T/Analog",
- .comment = "Experimenters and photos needed for device to work well.\n"
- "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE6 },
- { CX18_CARD_INPUT_SVIDEO1, 1,
- CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
- },
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .ddr = {
- .chip_config = 0x202,
- .refresh = 0x3bb,
- .timing1 = 0x33320a63,
- .timing2 = 0x0a,
- .tune_lane = 0,
- .initial_emrs = 0x42,
- },
- .xceive_pin = 15,
- .pci_list = cx18_pci_toshiba_qosmio_dvbt,
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Leadtek WinFast PVR2100 */
-
-static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */
- { 0, 0, 0 }
-};
-
-static const struct cx18_card cx18_card_leadtek_pvr2100 = {
- .type = CX18_CARD_LEADTEK_PVR2100,
- .name = "Leadtek WinFast PVR2100",
- .comment = "Experimenters and photos needed for device to work well.\n"
- "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_GPIO_MUX,
- .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
- CX18_HW_GPIO_RESET_CTRL,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
- { CX18_CARD_INPUT_SVIDEO1, 1,
- CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 },
- { CX18_CARD_INPUT_COMPONENT1, 1, CX18_AV_COMPONENT1 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
- },
- .tuners = {
- /* XC2028 tuner */
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
- .ddr = {
- /* Pointer to proper DDR config values provided by Terry Wu */
- .chip_config = 0x303,
- .refresh = 0x3bb,
- .timing1 = 0x24220e83,
- .timing2 = 0x1f,
- .tune_lane = 0,
- .initial_emrs = 0x2,
- },
- .gpio_init.initial_value = 0x6,
- .gpio_init.direction = 0x7,
- .gpio_audio_input = { .mask = 0x7,
- .tuner = 0x6, .linein = 0x2, .radio = 0x2 },
- .xceive_pin = 1,
- .pci_list = cx18_pci_leadtek_pvr2100,
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Leadtek WinFast DVR3100 H */
-
-static const struct cx18_card_pci_info cx18_pci_leadtek_dvr3100h[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */
- { 0, 0, 0 }
-};
-
-static const struct cx18_card cx18_card_leadtek_dvr3100h = {
- .type = CX18_CARD_LEADTEK_DVR3100H,
- .name = "Leadtek WinFast DVR3100 H",
- .comment = "Simultaneous DVB-T and Analog capture supported,\n"
- "\texcept when capturing Analog from the antenna input.\n",
- .v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_418_AV,
- .hw_muxer = CX18_HW_GPIO_MUX,
- .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
- CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
- .video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
- { CX18_CARD_INPUT_SVIDEO1, 1,
- CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 },
- { CX18_CARD_INPUT_COMPONENT1, 1, CX18_AV_COMPONENT1 },
- },
- .audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
- },
- .tuners = {
- /* XC3028 tuner */
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
- .ddr = {
- /* Pointer to proper DDR config values provided by Terry Wu */
- .chip_config = 0x303,
- .refresh = 0x3bb,
- .timing1 = 0x24220e83,
- .timing2 = 0x1f,
- .tune_lane = 0,
- .initial_emrs = 0x2,
- },
- .gpio_init.initial_value = 0x6,
- .gpio_init.direction = 0x7,
- .gpio_audio_input = { .mask = 0x7,
- .tuner = 0x6, .linein = 0x2, .radio = 0x2 },
- .xceive_pin = 1,
- .pci_list = cx18_pci_leadtek_dvr3100h,
- .i2c = &cx18_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-static const struct cx18_card *cx18_card_list[] = {
- &cx18_card_hvr1600_esmt,
- &cx18_card_hvr1600_samsung,
- &cx18_card_h900,
- &cx18_card_mpc718,
- &cx18_card_cnxt_raptor_pal,
- &cx18_card_toshiba_qosmio_dvbt,
- &cx18_card_leadtek_pvr2100,
- &cx18_card_leadtek_dvr3100h,
- &cx18_card_gotview_dvd3,
- &cx18_card_hvr1600_s5h1411
-};
-
-const struct cx18_card *cx18_get_card(u16 index)
-{
- if (index >= ARRAY_SIZE(cx18_card_list))
- return NULL;
- return cx18_card_list[index];
-}
-
-int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input)
-{
- const struct cx18_card_video_input *card_input =
- cx->card->video_inputs + index;
- static const char * const input_strs[] = {
- "Tuner 1",
- "S-Video 1",
- "S-Video 2",
- "Composite 1",
- "Composite 2",
- "Component 1"
- };
-
- if (index >= cx->nof_inputs)
- return -EINVAL;
- input->index = index;
- strlcpy(input->name, input_strs[card_input->video_type - 1],
- sizeof(input->name));
- input->type = (card_input->video_type == CX18_CARD_INPUT_VID_TUNER ?
- V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA);
- input->audioset = (1 << cx->nof_audio_inputs) - 1;
- input->std = (input->type == V4L2_INPUT_TYPE_TUNER) ?
- cx->tuner_std : V4L2_STD_ALL;
- return 0;
-}
-
-int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *audio)
-{
- const struct cx18_card_audio_input *aud_input =
- cx->card->audio_inputs + index;
- static const char * const input_strs[] = {
- "Tuner 1",
- "Line In 1",
- "Line In 2"
- };
-
- memset(audio, 0, sizeof(*audio));
- if (index >= cx->nof_audio_inputs)
- return -EINVAL;
- strlcpy(audio->name, input_strs[aud_input->audio_type - 1],
- sizeof(audio->name));
- audio->index = index;
- audio->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
deleted file mode 100644
index add7391ecab..00000000000
--- a/drivers/media/video/cx18/cx18-cards.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * cx18 functions to query card hardware
- *
- * Derived from ivtv-cards.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* hardware flags */
-#define CX18_HW_TUNER (1 << 0)
-#define CX18_HW_TVEEPROM (1 << 1)
-#define CX18_HW_CS5345 (1 << 2)
-#define CX18_HW_DVB (1 << 3)
-#define CX18_HW_418_AV (1 << 4)
-#define CX18_HW_GPIO_MUX (1 << 5)
-#define CX18_HW_GPIO_RESET_CTRL (1 << 6)
-#define CX18_HW_Z8F0811_IR_TX_HAUP (1 << 7)
-#define CX18_HW_Z8F0811_IR_RX_HAUP (1 << 8)
-#define CX18_HW_Z8F0811_IR_HAUP (CX18_HW_Z8F0811_IR_RX_HAUP | \
- CX18_HW_Z8F0811_IR_TX_HAUP)
-
-#define CX18_HW_IR_ANY (CX18_HW_Z8F0811_IR_RX_HAUP | \
- CX18_HW_Z8F0811_IR_TX_HAUP)
-
-/* video inputs */
-#define CX18_CARD_INPUT_VID_TUNER 1
-#define CX18_CARD_INPUT_SVIDEO1 2
-#define CX18_CARD_INPUT_SVIDEO2 3
-#define CX18_CARD_INPUT_COMPOSITE1 4
-#define CX18_CARD_INPUT_COMPOSITE2 5
-#define CX18_CARD_INPUT_COMPONENT1 6
-
-/* audio inputs */
-#define CX18_CARD_INPUT_AUD_TUNER 1
-#define CX18_CARD_INPUT_LINE_IN1 2
-#define CX18_CARD_INPUT_LINE_IN2 3
-
-#define CX18_CARD_MAX_VIDEO_INPUTS 6
-#define CX18_CARD_MAX_AUDIO_INPUTS 3
-#define CX18_CARD_MAX_TUNERS 2
-
-/* V4L2 capability aliases */
-#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
- V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | \
- V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)
-
-struct cx18_card_video_input {
- u8 video_type; /* video input type */
- u8 audio_index; /* index in cx18_card_audio_input array */
- u32 video_input; /* hardware video input */
-};
-
-struct cx18_card_audio_input {
- u8 audio_type; /* audio input type */
- u32 audio_input; /* hardware audio input */
- u16 muxer_input; /* hardware muxer input for boards with a
- multiplexer chip */
-};
-
-struct cx18_card_pci_info {
- u16 device;
- u16 subsystem_vendor;
- u16 subsystem_device;
-};
-
-/* GPIO definitions */
-
-/* The mask is the set of bits used by the operation */
-
-struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
- u32 direction; /* DIR setting. Leave to 0 if no init is needed */
- u32 initial_value;
-};
-
-struct cx18_gpio_i2c_slave_reset {
- u32 active_lo_mask; /* GPIO outputs that reset i2c chips when low */
- u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */
- int msecs_asserted; /* time period reset must remain asserted */
- int msecs_recovery; /* time after deassert for chips to be ready */
- u32 ir_reset_mask; /* GPIO to reset the Zilog Z8F0811 IR contoller */
-};
-
-struct cx18_gpio_audio_input { /* select tuner/line in input */
- u32 mask; /* leave to 0 if not supported */
- u32 tuner;
- u32 linein;
- u32 radio;
-};
-
-struct cx18_card_tuner {
- v4l2_std_id std; /* standard for which the tuner is suitable */
- int tuner; /* tuner ID (from tuner.h) */
-};
-
-struct cx18_card_tuner_i2c {
- unsigned short radio[2];/* radio tuner i2c address to probe */
- unsigned short demod[3];/* demodulator i2c address to probe */
- unsigned short tv[4]; /* tv tuner i2c addresses to probe */
-};
-
-struct cx18_ddr { /* DDR config data */
- u32 chip_config;
- u32 refresh;
- u32 timing1;
- u32 timing2;
- u32 tune_lane;
- u32 initial_emrs;
-};
-
-/* for card information/parameters */
-struct cx18_card {
- int type;
- char *name;
- char *comment;
- u32 v4l2_capabilities;
- u32 hw_audio_ctrl; /* hardware used for the V4L2 controls (only
- 1 dev allowed currently) */
- u32 hw_muxer; /* hardware used to multiplex audio input */
- u32 hw_all; /* all hardware used by the board */
- struct cx18_card_video_input video_inputs[CX18_CARD_MAX_VIDEO_INPUTS];
- struct cx18_card_audio_input audio_inputs[CX18_CARD_MAX_AUDIO_INPUTS];
- struct cx18_card_audio_input radio_input;
-
- /* GPIO card-specific settings */
- u8 xceive_pin; /* XCeive tuner GPIO reset pin */
- struct cx18_gpio_init gpio_init;
- struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset;
- struct cx18_gpio_audio_input gpio_audio_input;
-
- struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
- struct cx18_card_tuner_i2c *i2c;
-
- struct cx18_ddr ddr;
-
- /* list of device and subsystem vendor/devices that
- correspond to this card type. */
- const struct cx18_card_pci_info *pci_list;
-};
-
-int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input);
-int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *input);
-const struct cx18_card *cx18_get_card(u16 index);
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
deleted file mode 100644
index 282a3d29fda..00000000000
--- a/drivers/media/video/cx18/cx18-controls.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * cx18 ioctl control functions
- *
- * Derived from ivtv-controls.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-#include <linux/kernel.h>
-#include <linux/slab.h>
-
-#include "cx18-driver.h"
-#include "cx18-cards.h"
-#include "cx18-ioctl.h"
-#include "cx18-audio.h"
-#include "cx18-mailbox.h"
-#include "cx18-controls.h"
-
-static int cx18_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt)
-{
- struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
- int type = cxhdl->stream_type->val;
-
- if (atomic_read(&cx->ana_capturing) > 0)
- return -EBUSY;
-
- if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV ||
- !(type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS ||
- type == V4L2_MPEG_STREAM_TYPE_MPEG2_DVD ||
- type == V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD)) {
- /* Only IVTV fmt VBI insertion & only MPEG-2 PS type streams */
- cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE;
- CX18_DEBUG_INFO("disabled insertion of sliced VBI data into "
- "the MPEG stream\n");
- return 0;
- }
-
- /* Allocate sliced VBI buffers if needed. */
- if (cx->vbi.sliced_mpeg_data[0] == NULL) {
- int i;
-
- for (i = 0; i < CX18_VBI_FRAMES; i++) {
- cx->vbi.sliced_mpeg_data[i] =
- kmalloc(CX18_SLICED_MPEG_DATA_BUFSZ, GFP_KERNEL);
- if (cx->vbi.sliced_mpeg_data[i] == NULL) {
- while (--i >= 0) {
- kfree(cx->vbi.sliced_mpeg_data[i]);
- cx->vbi.sliced_mpeg_data[i] = NULL;
- }
- cx->vbi.insert_mpeg =
- V4L2_MPEG_STREAM_VBI_FMT_NONE;
- CX18_WARN("Unable to allocate buffers for "
- "sliced VBI data insertion\n");
- return -ENOMEM;
- }
- }
- }
-
- cx->vbi.insert_mpeg = fmt;
- CX18_DEBUG_INFO("enabled insertion of sliced VBI data into the MPEG PS,"
- "when sliced VBI is enabled\n");
-
- /*
- * If our current settings have no lines set for capture, store a valid,
- * default set of service lines to capture, in our current settings.
- */
- if (cx18_get_service_set(cx->vbi.sliced_in) == 0) {
- if (cx->is_60hz)
- cx->vbi.sliced_in->service_set =
- V4L2_SLICED_CAPTION_525;
- else
- cx->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
- cx18_expand_service_set(cx->vbi.sliced_in, cx->is_50hz);
- }
- return 0;
-}
-
-static int cx18_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val)
-{
- struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
- int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
- struct v4l2_mbus_framefmt fmt;
-
- /* fix videodecoder resolution */
- fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1);
- fmt.height = cxhdl->height;
- fmt.code = V4L2_MBUS_FMT_FIXED;
- v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &fmt);
- return 0;
-}
-
-static int cx18_s_audio_sampling_freq(struct cx2341x_handler *cxhdl, u32 idx)
-{
- static const u32 freqs[3] = { 44100, 48000, 32000 };
- struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
-
- /* The audio clock of the digitizer must match the codec sample
- rate otherwise you get some very strange effects. */
- if (idx < ARRAY_SIZE(freqs))
- cx18_call_all(cx, audio, s_clock_freq, freqs[idx]);
- return 0;
-}
-
-static int cx18_s_audio_mode(struct cx2341x_handler *cxhdl, u32 val)
-{
- struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
-
- cx->dualwatch_stereo_mode = val;
- return 0;
-}
-
-struct cx2341x_handler_ops cx18_cxhdl_ops = {
- .s_audio_mode = cx18_s_audio_mode,
- .s_audio_sampling_freq = cx18_s_audio_sampling_freq,
- .s_video_encoding = cx18_s_video_encoding,
- .s_stream_vbi_fmt = cx18_s_stream_vbi_fmt,
-};
diff --git a/drivers/media/video/cx18/cx18-controls.h b/drivers/media/video/cx18/cx18-controls.h
deleted file mode 100644
index cb5dfc7b205..00000000000
--- a/drivers/media/video/cx18/cx18-controls.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * cx18 ioctl control functions
- *
- * Derived from ivtv-controls.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-extern struct cx2341x_handler_ops cx18_cxhdl_ops;
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
deleted file mode 100644
index 75c89090792..00000000000
--- a/drivers/media/video/cx18/cx18-driver.c
+++ /dev/null
@@ -1,1359 +0,0 @@
-/*
- * cx18 driver initialization and card probing
- *
- * Derived from ivtv-driver.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-version.h"
-#include "cx18-cards.h"
-#include "cx18-i2c.h"
-#include "cx18-irq.h"
-#include "cx18-gpio.h"
-#include "cx18-firmware.h"
-#include "cx18-queue.h"
-#include "cx18-streams.h"
-#include "cx18-av-core.h"
-#include "cx18-scb.h"
-#include "cx18-mailbox.h"
-#include "cx18-ioctl.h"
-#include "cx18-controls.h"
-#include "tuner-xc2028.h"
-#include <linux/dma-mapping.h>
-#include <media/tveeprom.h>
-
-/* If you have already X v4l cards, then set this to X. This way
- the device numbers stay matched. Example: you have a WinTV card
- without radio and a Compro H900 with. Normally this would give a
- video1 device together with a radio0 device for the Compro. By
- setting this to 1 you ensure that radio0 is now also radio1. */
-int cx18_first_minor;
-
-/* Callback for registering extensions */
-int (*cx18_ext_init)(struct cx18 *);
-EXPORT_SYMBOL(cx18_ext_init);
-
-/* add your revision and whatnot here */
-static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
- {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, cx18_pci_tbl);
-
-static atomic_t cx18_instance = ATOMIC_INIT(0);
-
-/* Parameter declarations */
-static int cardtype[CX18_MAX_CARDS];
-static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1 };
-static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1 };
-static unsigned cardtype_c = 1;
-static unsigned tuner_c = 1;
-static unsigned radio_c = 1;
-static char pal[] = "--";
-static char secam[] = "--";
-static char ntsc[] = "-";
-
-/* Buffers */
-static int enc_ts_buffers = CX18_DEFAULT_ENC_TS_BUFFERS;
-static int enc_mpg_buffers = CX18_DEFAULT_ENC_MPG_BUFFERS;
-static int enc_idx_buffers = CX18_DEFAULT_ENC_IDX_BUFFERS;
-static int enc_yuv_buffers = CX18_DEFAULT_ENC_YUV_BUFFERS;
-static int enc_vbi_buffers = CX18_DEFAULT_ENC_VBI_BUFFERS;
-static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS;
-
-static int enc_ts_bufsize = CX18_DEFAULT_ENC_TS_BUFSIZE;
-static int enc_mpg_bufsize = CX18_DEFAULT_ENC_MPG_BUFSIZE;
-static int enc_idx_bufsize = CX18_DEFAULT_ENC_IDX_BUFSIZE;
-static int enc_yuv_bufsize = CX18_DEFAULT_ENC_YUV_BUFSIZE;
-static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE;
-
-static int enc_ts_bufs = -1;
-static int enc_mpg_bufs = -1;
-static int enc_idx_bufs = CX18_MAX_FW_MDLS_PER_STREAM;
-static int enc_yuv_bufs = -1;
-static int enc_vbi_bufs = -1;
-static int enc_pcm_bufs = -1;
-
-
-static int cx18_pci_latency = 1;
-
-static int mmio_ndelay;
-static int retry_mmio = 1;
-
-int cx18_debug;
-
-module_param_array(tuner, int, &tuner_c, 0644);
-module_param_array(radio, int, &radio_c, 0644);
-module_param_array(cardtype, int, &cardtype_c, 0644);
-module_param_string(pal, pal, sizeof(pal), 0644);
-module_param_string(secam, secam, sizeof(secam), 0644);
-module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
-module_param_named(debug, cx18_debug, int, 0644);
-module_param(mmio_ndelay, int, 0644);
-module_param(retry_mmio, int, 0644);
-module_param(cx18_pci_latency, int, 0644);
-module_param(cx18_first_minor, int, 0644);
-
-module_param(enc_ts_buffers, int, 0644);
-module_param(enc_mpg_buffers, int, 0644);
-module_param(enc_idx_buffers, int, 0644);
-module_param(enc_yuv_buffers, int, 0644);
-module_param(enc_vbi_buffers, int, 0644);
-module_param(enc_pcm_buffers, int, 0644);
-
-module_param(enc_ts_bufsize, int, 0644);
-module_param(enc_mpg_bufsize, int, 0644);
-module_param(enc_idx_bufsize, int, 0644);
-module_param(enc_yuv_bufsize, int, 0644);
-module_param(enc_pcm_bufsize, int, 0644);
-
-module_param(enc_ts_bufs, int, 0644);
-module_param(enc_mpg_bufs, int, 0644);
-module_param(enc_idx_bufs, int, 0644);
-module_param(enc_yuv_bufs, int, 0644);
-module_param(enc_vbi_bufs, int, 0644);
-module_param(enc_pcm_bufs, int, 0644);
-
-MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
- "\t\t\tsee tuner.h for values");
-MODULE_PARM_DESC(radio,
- "Enable or disable the radio. Use only if autodetection\n"
- "\t\t\tfails. 0 = disable, 1 = enable");
-MODULE_PARM_DESC(cardtype,
- "Only use this option if your card is not detected properly.\n"
- "\t\tSpecify card type:\n"
- "\t\t\t 1 = Hauppauge HVR 1600 (ESMT memory)\n"
- "\t\t\t 2 = Hauppauge HVR 1600 (Samsung memory)\n"
- "\t\t\t 3 = Compro VideoMate H900\n"
- "\t\t\t 4 = Yuan MPC718\n"
- "\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
- "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
- "\t\t\t 7 = Leadtek WinFast PVR2100\n"
- "\t\t\t 8 = Leadtek WinFast DVR3100 H\n"
- "\t\t\t 9 = GoTView PCI DVD3 Hybrid\n"
- "\t\t\t 10 = Hauppauge HVR 1600 (S5H1411)\n"
- "\t\t\t 0 = Autodetect (default)\n"
- "\t\t\t-1 = Ignore this card\n\t\t");
-MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
-MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC");
-MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K");
-MODULE_PARM_DESC(debug,
- "Debug level (bitmask). Default: 0\n"
- "\t\t\t 1/0x0001: warning\n"
- "\t\t\t 2/0x0002: info\n"
- "\t\t\t 4/0x0004: mailbox\n"
- "\t\t\t 8/0x0008: dma\n"
- "\t\t\t 16/0x0010: ioctl\n"
- "\t\t\t 32/0x0020: file\n"
- "\t\t\t 64/0x0040: i2c\n"
- "\t\t\t128/0x0080: irq\n"
- "\t\t\t256/0x0100: high volume\n");
-MODULE_PARM_DESC(cx18_pci_latency,
- "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
- "\t\t\tDefault: Yes");
-MODULE_PARM_DESC(retry_mmio,
- "(Deprecated) MMIO writes are now always checked and retried\n"
- "\t\t\tEffectively: 1 [Yes]");
-MODULE_PARM_DESC(mmio_ndelay,
- "(Deprecated) MMIO accesses are now never purposely delayed\n"
- "\t\t\tEffectively: 0 ns");
-MODULE_PARM_DESC(enc_ts_buffers,
- "Encoder TS buffer memory (MB). (enc_ts_bufs can override)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFFERS));
-MODULE_PARM_DESC(enc_ts_bufsize,
- "Size of an encoder TS buffer (kB)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFSIZE));
-MODULE_PARM_DESC(enc_ts_bufs,
- "Number of encoder TS buffers\n"
- "\t\t\tDefault is computed from other enc_ts_* parameters");
-MODULE_PARM_DESC(enc_mpg_buffers,
- "Encoder MPG buffer memory (MB). (enc_mpg_bufs can override)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
-MODULE_PARM_DESC(enc_mpg_bufsize,
- "Size of an encoder MPG buffer (kB)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFSIZE));
-MODULE_PARM_DESC(enc_mpg_bufs,
- "Number of encoder MPG buffers\n"
- "\t\t\tDefault is computed from other enc_mpg_* parameters");
-MODULE_PARM_DESC(enc_idx_buffers,
- "(Deprecated) Encoder IDX buffer memory (MB)\n"
- "\t\t\tIgnored, except 0 disables IDX buffer allocations\n"
- "\t\t\tDefault: 1 [Enabled]");
-MODULE_PARM_DESC(enc_idx_bufsize,
- "Size of an encoder IDX buffer (kB)\n"
- "\t\t\tAllowed values are multiples of 1.5 kB rounded up\n"
- "\t\t\t(multiples of size required for 64 index entries)\n"
- "\t\t\tDefault: 2");
-MODULE_PARM_DESC(enc_idx_bufs,
- "Number of encoder IDX buffers\n"
- "\t\t\tDefault: " __stringify(CX18_MAX_FW_MDLS_PER_STREAM));
-MODULE_PARM_DESC(enc_yuv_buffers,
- "Encoder YUV buffer memory (MB). (enc_yuv_bufs can override)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
-MODULE_PARM_DESC(enc_yuv_bufsize,
- "Size of an encoder YUV buffer (kB)\n"
- "\t\t\tAllowed values are multiples of 33.75 kB rounded up\n"
- "\t\t\t(multiples of size required for 32 screen lines)\n"
- "\t\t\tDefault: 102");
-MODULE_PARM_DESC(enc_yuv_bufs,
- "Number of encoder YUV buffers\n"
- "\t\t\tDefault is computed from other enc_yuv_* parameters");
-MODULE_PARM_DESC(enc_vbi_buffers,
- "Encoder VBI buffer memory (MB). (enc_vbi_bufs can override)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS));
-MODULE_PARM_DESC(enc_vbi_bufs,
- "Number of encoder VBI buffers\n"
- "\t\t\tDefault is computed from enc_vbi_buffers");
-MODULE_PARM_DESC(enc_pcm_buffers,
- "Encoder PCM buffer memory (MB). (enc_pcm_bufs can override)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
-MODULE_PARM_DESC(enc_pcm_bufsize,
- "Size of an encoder PCM buffer (kB)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFSIZE));
-MODULE_PARM_DESC(enc_pcm_bufs,
- "Number of encoder PCM buffers\n"
- "\t\t\tDefault is computed from other enc_pcm_* parameters");
-
-MODULE_PARM_DESC(cx18_first_minor,
- "Set device node number assigned to first card");
-
-MODULE_AUTHOR("Hans Verkuil");
-MODULE_DESCRIPTION("CX23418 driver");
-MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder");
-MODULE_LICENSE("GPL");
-
-MODULE_VERSION(CX18_VERSION);
-
-#if defined(CONFIG_MODULES) && defined(MODULE)
-static void request_module_async(struct work_struct *work)
-{
- struct cx18 *dev = container_of(work, struct cx18, request_module_wk);
-
- /* Make sure cx18-alsa module is loaded */
- request_module("cx18-alsa");
-
- /* Initialize cx18-alsa for this instance of the cx18 device */
- if (cx18_ext_init != NULL)
- cx18_ext_init(dev);
-}
-
-static void request_modules(struct cx18 *dev)
-{
- INIT_WORK(&dev->request_module_wk, request_module_async);
- schedule_work(&dev->request_module_wk);
-}
-
-static void flush_request_modules(struct cx18 *dev)
-{
- flush_work(&dev->request_module_wk);
-}
-#else
-#define request_modules(dev)
-#define flush_request_modules(dev)
-#endif /* CONFIG_MODULES */
-
-/* Generic utility functions */
-int cx18_msleep_timeout(unsigned int msecs, int intr)
-{
- long int timeout = msecs_to_jiffies(msecs);
- int sig;
-
- do {
- set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
- timeout = schedule_timeout(timeout);
- sig = intr ? signal_pending(current) : 0;
- } while (!sig && timeout);
- return sig;
-}
-
-/* Release ioremapped memory */
-static void cx18_iounmap(struct cx18 *cx)
-{
- if (cx == NULL)
- return;
-
- /* Release io memory */
- if (cx->enc_mem != NULL) {
- CX18_DEBUG_INFO("releasing enc_mem\n");
- iounmap(cx->enc_mem);
- cx->enc_mem = NULL;
- }
-}
-
-static void cx18_eeprom_dump(struct cx18 *cx, unsigned char *eedata, int len)
-{
- int i;
-
- CX18_INFO("eeprom dump:\n");
- for (i = 0; i < len; i++) {
- if (0 == (i % 16))
- CX18_INFO("eeprom %02x:", i);
- printk(KERN_CONT " %02x", eedata[i]);
- if (15 == (i % 16))
- printk(KERN_CONT "\n");
- }
-}
-
-/* Hauppauge card? get values from tveeprom */
-void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
-{
- struct i2c_client c;
- u8 eedata[256];
-
- memset(&c, 0, sizeof(c));
- strlcpy(c.name, "cx18 tveeprom tmp", sizeof(c.name));
- c.adapter = &cx->i2c_adap[0];
- c.addr = 0xA0 >> 1;
-
- memset(tv, 0, sizeof(*tv));
- if (tveeprom_read(&c, eedata, sizeof(eedata)))
- return;
-
- switch (cx->card->type) {
- case CX18_CARD_HVR_1600_ESMT:
- case CX18_CARD_HVR_1600_SAMSUNG:
- case CX18_CARD_HVR_1600_S5H1411:
- tveeprom_hauppauge_analog(&c, tv, eedata);
- break;
- case CX18_CARD_YUAN_MPC718:
- case CX18_CARD_GOTVIEW_PCI_DVD3:
- tv->model = 0x718;
- cx18_eeprom_dump(cx, eedata, sizeof(eedata));
- CX18_INFO("eeprom PCI ID: %02x%02x:%02x%02x\n",
- eedata[2], eedata[1], eedata[4], eedata[3]);
- break;
- default:
- tv->model = 0xffffffff;
- cx18_eeprom_dump(cx, eedata, sizeof(eedata));
- break;
- }
-}
-
-static void cx18_process_eeprom(struct cx18 *cx)
-{
- struct tveeprom tv;
-
- cx18_read_eeprom(cx, &tv);
-
- /* Many thanks to Steven Toth from Hauppauge for providing the
- model numbers */
- /* Note: the Samsung memory models cannot be reliably determined
- from the model number. Use the cardtype module option if you
- have one of these preproduction models. */
- switch (tv.model) {
- case 74301: /* Retail models */
- case 74321:
- case 74351: /* OEM models */
- case 74361:
- /* Digital side is s5h1411/tda18271 */
- cx->card = cx18_get_card(CX18_CARD_HVR_1600_S5H1411);
- break;
- case 74021: /* Retail models */
- case 74031:
- case 74041:
- case 74141:
- case 74541: /* OEM models */
- case 74551:
- case 74591:
- case 74651:
- case 74691:
- case 74751:
- case 74891:
- /* Digital side is s5h1409/mxl5005s */
- cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
- break;
- case 0x718:
- return;
- case 0xffffffff:
- CX18_INFO("Unknown EEPROM encoding\n");
- return;
- case 0:
- CX18_ERR("Invalid EEPROM\n");
- return;
- default:
- CX18_ERR("Unknown model %d, defaulting to original HVR-1600 "
- "(cardtype=1)\n", tv.model);
- cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
- break;
- }
-
- cx->v4l2_cap = cx->card->v4l2_capabilities;
- cx->card_name = cx->card->name;
- cx->card_i2c = cx->card->i2c;
-
- CX18_INFO("Autodetected %s\n", cx->card_name);
-
- if (tv.tuner_type == TUNER_ABSENT)
- CX18_ERR("tveeprom cannot autodetect tuner!\n");
-
- if (cx->options.tuner == -1)
- cx->options.tuner = tv.tuner_type;
- if (cx->options.radio == -1)
- cx->options.radio = (tv.has_radio != 0);
-
- if (cx->std != 0)
- /* user specified tuner standard */
- return;
-
- /* autodetect tuner standard */
-#define TVEEPROM_TUNER_FORMAT_ALL (V4L2_STD_B | V4L2_STD_GH | \
- V4L2_STD_MN | \
- V4L2_STD_PAL_I | \
- V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC | \
- V4L2_STD_DK)
- if ((tv.tuner_formats & TVEEPROM_TUNER_FORMAT_ALL)
- == TVEEPROM_TUNER_FORMAT_ALL) {
- CX18_DEBUG_INFO("Worldwide tuner detected\n");
- cx->std = V4L2_STD_ALL;
- } else if (tv.tuner_formats & V4L2_STD_PAL) {
- CX18_DEBUG_INFO("PAL tuner detected\n");
- cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
- } else if (tv.tuner_formats & V4L2_STD_NTSC) {
- CX18_DEBUG_INFO("NTSC tuner detected\n");
- cx->std |= V4L2_STD_NTSC_M;
- } else if (tv.tuner_formats & V4L2_STD_SECAM) {
- CX18_DEBUG_INFO("SECAM tuner detected\n");
- cx->std |= V4L2_STD_SECAM_L;
- } else {
- CX18_INFO("No tuner detected, default to NTSC-M\n");
- cx->std |= V4L2_STD_NTSC_M;
- }
-}
-
-static v4l2_std_id cx18_parse_std(struct cx18 *cx)
-{
- switch (pal[0]) {
- case '6':
- return V4L2_STD_PAL_60;
- case 'b':
- case 'B':
- case 'g':
- case 'G':
- return V4L2_STD_PAL_BG;
- case 'h':
- case 'H':
- return V4L2_STD_PAL_H;
- case 'n':
- case 'N':
- if (pal[1] == 'c' || pal[1] == 'C')
- return V4L2_STD_PAL_Nc;
- return V4L2_STD_PAL_N;
- case 'i':
- case 'I':
- return V4L2_STD_PAL_I;
- case 'd':
- case 'D':
- case 'k':
- case 'K':
- return V4L2_STD_PAL_DK;
- case 'M':
- case 'm':
- return V4L2_STD_PAL_M;
- case '-':
- break;
- default:
- CX18_WARN("pal= argument not recognised\n");
- return 0;
- }
-
- switch (secam[0]) {
- case 'b':
- case 'B':
- case 'g':
- case 'G':
- case 'h':
- case 'H':
- return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
- case 'd':
- case 'D':
- case 'k':
- case 'K':
- return V4L2_STD_SECAM_DK;
- case 'l':
- case 'L':
- if (secam[1] == 'C' || secam[1] == 'c')
- return V4L2_STD_SECAM_LC;
- return V4L2_STD_SECAM_L;
- case '-':
- break;
- default:
- CX18_WARN("secam= argument not recognised\n");
- return 0;
- }
-
- switch (ntsc[0]) {
- case 'm':
- case 'M':
- return V4L2_STD_NTSC_M;
- case 'j':
- case 'J':
- return V4L2_STD_NTSC_M_JP;
- case 'k':
- case 'K':
- return V4L2_STD_NTSC_M_KR;
- case '-':
- break;
- default:
- CX18_WARN("ntsc= argument not recognised\n");
- return 0;
- }
-
- /* no match found */
- return 0;
-}
-
-static void cx18_process_options(struct cx18 *cx)
-{
- int i, j;
-
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers;
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_buffers;
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers;
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers;
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control only */
-
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufs;
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufs;
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufs;
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufs;
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_bufs;
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufs;
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control, no data */
-
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufsize;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_active_samples * 36;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */
-
- /* Ensure stream_buffers & stream_buf_size are valid */
- for (i = 0; i < CX18_MAX_STREAMS; i++) {
- if (cx->stream_buffers[i] == 0 || /* User said 0 buffers */
- cx->options.megabytes[i] <= 0 || /* User said 0 MB total */
- cx->stream_buf_size[i] <= 0) { /* User said buf size 0 */
- cx->options.megabytes[i] = 0;
- cx->stream_buffers[i] = 0;
- cx->stream_buf_size[i] = 0;
- continue;
- }
- /*
- * YUV is a special case where the stream_buf_size needs to be
- * an integral multiple of 33.75 kB (storage for 32 screens
- * lines to maintain alignment in case of lost buffers).
- *
- * IDX is a special case where the stream_buf_size should be
- * an integral multiple of 1.5 kB (storage for 64 index entries
- * to maintain alignment in case of lost buffers).
- *
- */
- if (i == CX18_ENC_STREAM_TYPE_YUV) {
- cx->stream_buf_size[i] *= 1024;
- cx->stream_buf_size[i] -=
- (cx->stream_buf_size[i] % CX18_UNIT_ENC_YUV_BUFSIZE);
-
- if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE)
- cx->stream_buf_size[i] =
- CX18_UNIT_ENC_YUV_BUFSIZE;
- } else if (i == CX18_ENC_STREAM_TYPE_IDX) {
- cx->stream_buf_size[i] *= 1024;
- cx->stream_buf_size[i] -=
- (cx->stream_buf_size[i] % CX18_UNIT_ENC_IDX_BUFSIZE);
-
- if (cx->stream_buf_size[i] < CX18_UNIT_ENC_IDX_BUFSIZE)
- cx->stream_buf_size[i] =
- CX18_UNIT_ENC_IDX_BUFSIZE;
- }
- /*
- * YUV and IDX are special cases where the stream_buf_size is
- * now in bytes.
- * VBI is a special case where the stream_buf_size is fixed
- * and already in bytes
- */
- if (i == CX18_ENC_STREAM_TYPE_VBI ||
- i == CX18_ENC_STREAM_TYPE_YUV ||
- i == CX18_ENC_STREAM_TYPE_IDX) {
- if (cx->stream_buffers[i] < 0) {
- cx->stream_buffers[i] =
- cx->options.megabytes[i] * 1024 * 1024
- / cx->stream_buf_size[i];
- } else {
- /* N.B. This might round down to 0 */
- cx->options.megabytes[i] =
- cx->stream_buffers[i]
- * cx->stream_buf_size[i]/(1024 * 1024);
- }
- } else {
- /* All other streams have stream_buf_size in kB here */
- if (cx->stream_buffers[i] < 0) {
- cx->stream_buffers[i] =
- cx->options.megabytes[i] * 1024
- / cx->stream_buf_size[i];
- } else {
- /* N.B. This might round down to 0 */
- cx->options.megabytes[i] =
- cx->stream_buffers[i]
- * cx->stream_buf_size[i] / 1024;
- }
- /* convert from kB to bytes */
- cx->stream_buf_size[i] *= 1024;
- }
- CX18_DEBUG_INFO("Stream type %d options: %d MB, %d buffers, "
- "%d bytes\n", i, cx->options.megabytes[i],
- cx->stream_buffers[i], cx->stream_buf_size[i]);
- }
-
- cx->options.cardtype = cardtype[cx->instance];
- cx->options.tuner = tuner[cx->instance];
- cx->options.radio = radio[cx->instance];
-
- cx->std = cx18_parse_std(cx);
- if (cx->options.cardtype == -1) {
- CX18_INFO("Ignore card\n");
- return;
- }
- cx->card = cx18_get_card(cx->options.cardtype - 1);
- if (cx->card)
- CX18_INFO("User specified %s card\n", cx->card->name);
- else if (cx->options.cardtype != 0)
- CX18_ERR("Unknown user specified type, trying to autodetect card\n");
- if (cx->card == NULL) {
- if (cx->pci_dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
- cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
- CX18_INFO("Autodetected Hauppauge card\n");
- }
- }
- if (cx->card == NULL) {
- for (i = 0; (cx->card = cx18_get_card(i)); i++) {
- if (cx->card->pci_list == NULL)
- continue;
- for (j = 0; cx->card->pci_list[j].device; j++) {
- if (cx->pci_dev->device !=
- cx->card->pci_list[j].device)
- continue;
- if (cx->pci_dev->subsystem_vendor !=
- cx->card->pci_list[j].subsystem_vendor)
- continue;
- if (cx->pci_dev->subsystem_device !=
- cx->card->pci_list[j].subsystem_device)
- continue;
- CX18_INFO("Autodetected %s card\n", cx->card->name);
- goto done;
- }
- }
- }
-done:
-
- if (cx->card == NULL) {
- cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
- CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
- cx->pci_dev->vendor, cx->pci_dev->device);
- CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n",
- cx->pci_dev->subsystem_vendor,
- cx->pci_dev->subsystem_device);
- CX18_ERR("Defaulting to %s card\n", cx->card->name);
- CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
- CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
- CX18_ERR("Prefix your subject line with [UNKNOWN CX18 CARD].\n");
- }
- cx->v4l2_cap = cx->card->v4l2_capabilities;
- cx->card_name = cx->card->name;
- cx->card_i2c = cx->card->i2c;
-}
-
-static int __devinit cx18_create_in_workq(struct cx18 *cx)
-{
- snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in",
- cx->v4l2_dev.name);
- cx->in_work_queue = alloc_ordered_workqueue(cx->in_workq_name, 0);
- if (cx->in_work_queue == NULL) {
- CX18_ERR("Unable to create incoming mailbox handler thread\n");
- return -ENOMEM;
- }
- return 0;
-}
-
-static void __devinit cx18_init_in_work_orders(struct cx18 *cx)
-{
- int i;
- for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
- cx->in_work_order[i].cx = cx;
- cx->in_work_order[i].str = cx->epu_debug_str;
- INIT_WORK(&cx->in_work_order[i].work, cx18_in_work_handler);
- }
-}
-
-/* Precondition: the cx18 structure has been memset to 0. Only
- the dev and instance fields have been filled in.
- No assumptions on the card type may be made here (see cx18_init_struct2
- for that).
- */
-static int __devinit cx18_init_struct1(struct cx18 *cx)
-{
- int ret;
-
- cx->base_addr = pci_resource_start(cx->pci_dev, 0);
-
- mutex_init(&cx->serialize_lock);
- mutex_init(&cx->gpio_lock);
- mutex_init(&cx->epu2apu_mb_lock);
- mutex_init(&cx->epu2cpu_mb_lock);
-
- ret = cx18_create_in_workq(cx);
- if (ret)
- return ret;
-
- cx18_init_in_work_orders(cx);
-
- /* start counting open_id at 1 */
- cx->open_id = 1;
-
- /* Initial settings */
- cx->cxhdl.port = CX2341X_PORT_MEMORY;
- cx->cxhdl.capabilities = CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_SLICED_VBI;
- cx->cxhdl.ops = &cx18_cxhdl_ops;
- cx->cxhdl.func = cx18_api_func;
- cx->cxhdl.priv = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
- ret = cx2341x_handler_init(&cx->cxhdl, 50);
- if (ret)
- return ret;
- cx->v4l2_dev.ctrl_handler = &cx->cxhdl.hdl;
-
- cx->temporal_strength = cx->cxhdl.video_temporal_filter->cur.val;
- cx->spatial_strength = cx->cxhdl.video_spatial_filter->cur.val;
- cx->filter_mode = cx->cxhdl.video_spatial_filter_mode->cur.val |
- (cx->cxhdl.video_temporal_filter_mode->cur.val << 1) |
- (cx->cxhdl.video_median_filter_type->cur.val << 2);
-
- init_waitqueue_head(&cx->cap_w);
- init_waitqueue_head(&cx->mb_apu_waitq);
- init_waitqueue_head(&cx->mb_cpu_waitq);
- init_waitqueue_head(&cx->dma_waitq);
-
- /* VBI */
- cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
- cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
-
- /* IVTV style VBI insertion into MPEG streams */
- INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_buf.list);
- INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.list);
- INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.buf_list);
- list_add(&cx->vbi.sliced_mpeg_buf.list,
- &cx->vbi.sliced_mpeg_mdl.buf_list);
- return 0;
-}
-
-/* Second initialization part. Here the card type has been
- autodetected. */
-static void __devinit cx18_init_struct2(struct cx18 *cx)
-{
- int i;
-
- for (i = 0; i < CX18_CARD_MAX_VIDEO_INPUTS; i++)
- if (cx->card->video_inputs[i].video_type == 0)
- break;
- cx->nof_inputs = i;
- for (i = 0; i < CX18_CARD_MAX_AUDIO_INPUTS; i++)
- if (cx->card->audio_inputs[i].audio_type == 0)
- break;
- cx->nof_audio_inputs = i;
-
- /* Find tuner input */
- for (i = 0; i < cx->nof_inputs; i++) {
- if (cx->card->video_inputs[i].video_type ==
- CX18_CARD_INPUT_VID_TUNER)
- break;
- }
- if (i == cx->nof_inputs)
- i = 0;
- cx->active_input = i;
- cx->audio_input = cx->card->video_inputs[i].audio_index;
-}
-
-static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
-{
- u16 cmd;
- unsigned char pci_latency;
-
- CX18_DEBUG_INFO("Enabling pci device\n");
-
- if (pci_enable_device(pci_dev)) {
- CX18_ERR("Can't enable device %d!\n", cx->instance);
- return -EIO;
- }
- if (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32))) {
- CX18_ERR("No suitable DMA available, card %d\n", cx->instance);
- return -EIO;
- }
- if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) {
- CX18_ERR("Cannot request encoder memory region, card %d\n",
- cx->instance);
- return -EIO;
- }
-
- /* Enable bus mastering and memory mapped IO for the CX23418 */
- pci_read_config_word(pci_dev, PCI_COMMAND, &cmd);
- cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
- pci_write_config_word(pci_dev, PCI_COMMAND, cmd);
-
- cx->card_rev = pci_dev->revision;
- pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
-
- if (pci_latency < 64 && cx18_pci_latency) {
- CX18_INFO("Unreasonably low latency timer, "
- "setting to 64 (was %d)\n", pci_latency);
- pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, 64);
- pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
- }
-
- CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, "
- "irq: %d, latency: %d, memory: 0x%llx\n",
- cx->pci_dev->device, cx->card_rev, pci_dev->bus->number,
- PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn),
- cx->pci_dev->irq, pci_latency, (u64)cx->base_addr);
-
- return 0;
-}
-
-static void cx18_init_subdevs(struct cx18 *cx)
-{
- u32 hw = cx->card->hw_all;
- u32 device;
- int i;
-
- for (i = 0, device = 1; i < 32; i++, device <<= 1) {
-
- if (!(device & hw))
- continue;
-
- switch (device) {
- case CX18_HW_DVB:
- case CX18_HW_TVEEPROM:
- /* These subordinate devices do not use probing */
- cx->hw_flags |= device;
- break;
- case CX18_HW_418_AV:
- /* The A/V decoder gets probed earlier to set PLLs */
- /* Just note that the card uses it (i.e. has analog) */
- cx->hw_flags |= device;
- break;
- case CX18_HW_GPIO_RESET_CTRL:
- /*
- * The Reset Controller gets probed and added to
- * hw_flags earlier for i2c adapter/bus initialization
- */
- break;
- case CX18_HW_GPIO_MUX:
- if (cx18_gpio_register(cx, device) == 0)
- cx->hw_flags |= device;
- break;
- default:
- if (cx18_i2c_register(cx, i) == 0)
- cx->hw_flags |= device;
- break;
- }
- }
-
- if (cx->hw_flags & CX18_HW_418_AV)
- cx->sd_av = cx18_find_hw(cx, CX18_HW_418_AV);
-
- if (cx->card->hw_muxer != 0)
- cx->sd_extmux = cx18_find_hw(cx, cx->card->hw_muxer);
-}
-
-static int __devinit cx18_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
-{
- int retval = 0;
- int i;
- u32 devtype;
- struct cx18 *cx;
-
- /* FIXME - module parameter arrays constrain max instances */
- i = atomic_inc_return(&cx18_instance) - 1;
- if (i >= CX18_MAX_CARDS) {
- printk(KERN_ERR "cx18: cannot manage card %d, driver has a "
- "limit of 0 - %d\n", i, CX18_MAX_CARDS - 1);
- return -ENOMEM;
- }
-
- cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
- if (cx == NULL) {
- printk(KERN_ERR "cx18: cannot manage card %d, out of memory\n",
- i);
- return -ENOMEM;
- }
- cx->pci_dev = pci_dev;
- cx->instance = i;
-
- retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev);
- if (retval) {
- printk(KERN_ERR "cx18: v4l2_device_register of card %d failed"
- "\n", cx->instance);
- kfree(cx);
- return retval;
- }
- snprintf(cx->v4l2_dev.name, sizeof(cx->v4l2_dev.name), "cx18-%d",
- cx->instance);
- CX18_INFO("Initializing card %d\n", cx->instance);
-
- cx18_process_options(cx);
- if (cx->options.cardtype == -1) {
- retval = -ENODEV;
- goto err;
- }
-
- retval = cx18_init_struct1(cx);
- if (retval)
- goto err;
-
- CX18_DEBUG_INFO("base addr: 0x%llx\n", (u64)cx->base_addr);
-
- /* PCI Device Setup */
- retval = cx18_setup_pci(cx, pci_dev, pci_id);
- if (retval != 0)
- goto free_workqueues;
-
- /* map io memory */
- CX18_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n",
- (u64)cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE);
- cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET,
- CX18_MEM_SIZE);
- if (!cx->enc_mem) {
- CX18_ERR("ioremap failed. Can't get a window into CX23418 "
- "memory and register space\n");
- CX18_ERR("Each capture card with a CX23418 needs 64 MB of "
- "vmalloc address space for the window\n");
- CX18_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
- CX18_ERR("Use the vmalloc= kernel command line option to set "
- "VmallocTotal to a larger value\n");
- retval = -ENOMEM;
- goto free_mem;
- }
- cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET;
- devtype = cx18_read_reg(cx, 0xC72028);
- switch (devtype & 0xff000000) {
- case 0xff000000:
- CX18_INFO("cx23418 revision %08x (A)\n", devtype);
- break;
- case 0x01000000:
- CX18_INFO("cx23418 revision %08x (B)\n", devtype);
- break;
- default:
- CX18_INFO("cx23418 revision %08x (Unknown)\n", devtype);
- break;
- }
-
- cx18_init_power(cx, 1);
- cx18_init_memory(cx);
-
- cx->scb = (struct cx18_scb __iomem *)(cx->enc_mem + SCB_OFFSET);
- cx18_init_scb(cx);
-
- cx18_gpio_init(cx);
-
- /* Initialize integrated A/V decoder early to set PLLs, just in case */
- retval = cx18_av_probe(cx);
- if (retval) {
- CX18_ERR("Could not register A/V decoder subdevice\n");
- goto free_map;
- }
-
- /* Initialize GPIO Reset Controller to do chip resets during i2c init */
- if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) {
- if (cx18_gpio_register(cx, CX18_HW_GPIO_RESET_CTRL) != 0)
- CX18_WARN("Could not register GPIO reset controller"
- "subdevice; proceeding anyway.\n");
- else
- cx->hw_flags |= CX18_HW_GPIO_RESET_CTRL;
- }
-
- /* active i2c */
- CX18_DEBUG_INFO("activating i2c...\n");
- retval = init_cx18_i2c(cx);
- if (retval) {
- CX18_ERR("Could not initialize i2c\n");
- goto free_map;
- }
-
- if (cx->card->hw_all & CX18_HW_TVEEPROM) {
- /* Based on the model number the cardtype may be changed.
- The PCI IDs are not always reliable. */
- const struct cx18_card *orig_card = cx->card;
- cx18_process_eeprom(cx);
-
- if (cx->card != orig_card) {
- /* Changed the cardtype; re-reset the I2C chips */
- cx18_gpio_init(cx);
- cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
- core, reset, (u32) CX18_GPIO_RESET_I2C);
- }
- }
- if (cx->card->comment)
- CX18_INFO("%s", cx->card->comment);
- if (cx->card->v4l2_capabilities == 0) {
- retval = -ENODEV;
- goto free_i2c;
- }
- cx18_init_memory(cx);
- cx18_init_scb(cx);
-
- /* Register IRQ */
- retval = request_irq(cx->pci_dev->irq, cx18_irq_handler,
- IRQF_SHARED | IRQF_DISABLED,
- cx->v4l2_dev.name, (void *)cx);
- if (retval) {
- CX18_ERR("Failed to register irq %d\n", retval);
- goto free_i2c;
- }
-
- if (cx->std == 0)
- cx->std = V4L2_STD_NTSC_M;
-
- if (cx->options.tuner == -1) {
- for (i = 0; i < CX18_CARD_MAX_TUNERS; i++) {
- if ((cx->std & cx->card->tuners[i].std) == 0)
- continue;
- cx->options.tuner = cx->card->tuners[i].tuner;
- break;
- }
- }
- /* if no tuner was found, then pick the first tuner in the card list */
- if (cx->options.tuner == -1 && cx->card->tuners[0].std) {
- cx->std = cx->card->tuners[0].std;
- if (cx->std & V4L2_STD_PAL)
- cx->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
- else if (cx->std & V4L2_STD_NTSC)
- cx->std = V4L2_STD_NTSC_M;
- else if (cx->std & V4L2_STD_SECAM)
- cx->std = V4L2_STD_SECAM_L;
- cx->options.tuner = cx->card->tuners[0].tuner;
- }
- if (cx->options.radio == -1)
- cx->options.radio = (cx->card->radio_input.audio_type != 0);
-
- /* The card is now fully identified, continue with card-specific
- initialization. */
- cx18_init_struct2(cx);
-
- cx18_init_subdevs(cx);
-
- if (cx->std & V4L2_STD_525_60)
- cx->is_60hz = 1;
- else
- cx->is_50hz = 1;
-
- cx2341x_handler_set_50hz(&cx->cxhdl, !cx->is_60hz);
-
- if (cx->options.radio > 0)
- cx->v4l2_cap |= V4L2_CAP_RADIO;
-
- if (cx->options.tuner > -1) {
- struct tuner_setup setup;
-
- setup.addr = ADDR_UNSET;
- setup.type = cx->options.tuner;
- setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
- if (cx->options.radio > 0)
- setup.mode_mask |= T_RADIO;
- setup.tuner_callback = (setup.type == TUNER_XC2028) ?
- cx18_reset_tuner_gpio : NULL;
- cx18_call_all(cx, tuner, s_type_addr, &setup);
- if (setup.type == TUNER_XC2028) {
- static struct xc2028_ctrl ctrl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64,
- };
- struct v4l2_priv_tun_config cfg = {
- .tuner = cx->options.tuner,
- .priv = &ctrl,
- };
- cx18_call_all(cx, tuner, s_config, &cfg);
- }
- }
-
- /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
- are not. */
- cx->tuner_std = cx->std;
- if (cx->std == V4L2_STD_ALL)
- cx->std = V4L2_STD_NTSC_M;
-
- retval = cx18_streams_setup(cx);
- if (retval) {
- CX18_ERR("Error %d setting up streams\n", retval);
- goto free_irq;
- }
- retval = cx18_streams_register(cx);
- if (retval) {
- CX18_ERR("Error %d registering devices\n", retval);
- goto free_streams;
- }
-
- CX18_INFO("Initialized card: %s\n", cx->card_name);
-
- /* Load cx18 submodules (cx18-alsa) */
- request_modules(cx);
- return 0;
-
-free_streams:
- cx18_streams_cleanup(cx, 1);
-free_irq:
- free_irq(cx->pci_dev->irq, (void *)cx);
-free_i2c:
- exit_cx18_i2c(cx);
-free_map:
- cx18_iounmap(cx);
-free_mem:
- release_mem_region(cx->base_addr, CX18_MEM_SIZE);
-free_workqueues:
- destroy_workqueue(cx->in_work_queue);
-err:
- if (retval == 0)
- retval = -ENODEV;
- CX18_ERR("Error %d on initialization\n", retval);
-
- v4l2_device_unregister(&cx->v4l2_dev);
- kfree(cx);
- return retval;
-}
-
-int cx18_init_on_first_open(struct cx18 *cx)
-{
- int video_input;
- int fw_retry_count = 3;
- struct v4l2_frequency vf;
- struct cx18_open_id fh;
- v4l2_std_id std;
-
- fh.cx = cx;
-
- if (test_bit(CX18_F_I_FAILED, &cx->i_flags))
- return -ENXIO;
-
- if (test_and_set_bit(CX18_F_I_INITED, &cx->i_flags))
- return 0;
-
- while (--fw_retry_count > 0) {
- /* load firmware */
- if (cx18_firmware_init(cx) == 0)
- break;
- if (fw_retry_count > 1)
- CX18_WARN("Retry loading firmware\n");
- }
-
- if (fw_retry_count == 0) {
- set_bit(CX18_F_I_FAILED, &cx->i_flags);
- return -ENXIO;
- }
- set_bit(CX18_F_I_LOADED_FW, &cx->i_flags);
-
- /*
- * Init the firmware twice to work around a silicon bug
- * with the digital TS.
- *
- * The second firmware load requires us to normalize the APU state,
- * or the audio for the first analog capture will be badly incorrect.
- *
- * I can't seem to call APU_RESETAI and have it succeed without the
- * APU capturing audio, so we start and stop it here to do the reset
- */
-
- /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
- cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
- cx18_vapi(cx, CX18_APU_RESETAI, 0);
- cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
-
- fw_retry_count = 3;
- while (--fw_retry_count > 0) {
- /* load firmware */
- if (cx18_firmware_init(cx) == 0)
- break;
- if (fw_retry_count > 1)
- CX18_WARN("Retry loading firmware\n");
- }
-
- if (fw_retry_count == 0) {
- set_bit(CX18_F_I_FAILED, &cx->i_flags);
- return -ENXIO;
- }
-
- /*
- * The second firmware load requires us to normalize the APU state,
- * or the audio for the first analog capture will be badly incorrect.
- *
- * I can't seem to call APU_RESETAI and have it succeed without the
- * APU capturing audio, so we start and stop it here to do the reset
- */
-
- /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
- cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
- cx18_vapi(cx, CX18_APU_RESETAI, 0);
- cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
-
- /* Init the A/V decoder, if it hasn't been already */
- v4l2_subdev_call(cx->sd_av, core, load_fw);
-
- vf.tuner = 0;
- vf.type = V4L2_TUNER_ANALOG_TV;
- vf.frequency = 6400; /* the tuner 'baseline' frequency */
-
- /* Set initial frequency. For PAL/SECAM broadcasts no
- 'default' channel exists AFAIK. */
- if (cx->std == V4L2_STD_NTSC_M_JP)
- vf.frequency = 1460; /* ch. 1 91250*16/1000 */
- else if (cx->std & V4L2_STD_NTSC_M)
- vf.frequency = 1076; /* ch. 4 67250*16/1000 */
-
- video_input = cx->active_input;
- cx->active_input++; /* Force update of input */
- cx18_s_input(NULL, &fh, video_input);
-
- /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
- in one place. */
- cx->std++; /* Force full standard initialization */
- std = (cx->tuner_std == V4L2_STD_ALL) ? V4L2_STD_NTSC_M : cx->tuner_std;
- cx18_s_std(NULL, &fh, &std);
- cx18_s_frequency(NULL, &fh, &vf);
- return 0;
-}
-
-static void cx18_cancel_in_work_orders(struct cx18 *cx)
-{
- int i;
- for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++)
- cancel_work_sync(&cx->in_work_order[i].work);
-}
-
-static void cx18_cancel_out_work_orders(struct cx18 *cx)
-{
- int i;
- for (i = 0; i < CX18_MAX_STREAMS; i++)
- if (&cx->streams[i].video_dev != NULL)
- cancel_work_sync(&cx->streams[i].out_work_order);
-}
-
-static void cx18_remove(struct pci_dev *pci_dev)
-{
- struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
- struct cx18 *cx = to_cx18(v4l2_dev);
- int i;
-
- CX18_DEBUG_INFO("Removing Card\n");
-
- flush_request_modules(cx);
-
- /* Stop all captures */
- CX18_DEBUG_INFO("Stopping all streams\n");
- if (atomic_read(&cx->tot_capturing) > 0)
- cx18_stop_all_captures(cx);
-
- /* Stop interrupts that cause incoming work to be queued */
- cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
-
- /* Incoming work can cause outgoing work, so clean up incoming first */
- cx18_cancel_in_work_orders(cx);
- cx18_cancel_out_work_orders(cx);
-
- /* Stop ack interrupts that may have been needed for work to finish */
- cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
-
- cx18_halt_firmware(cx);
-
- destroy_workqueue(cx->in_work_queue);
-
- cx18_streams_cleanup(cx, 1);
-
- exit_cx18_i2c(cx);
-
- free_irq(cx->pci_dev->irq, (void *)cx);
-
- cx18_iounmap(cx);
-
- release_mem_region(cx->base_addr, CX18_MEM_SIZE);
-
- pci_disable_device(cx->pci_dev);
-
- if (cx->vbi.sliced_mpeg_data[0] != NULL)
- for (i = 0; i < CX18_VBI_FRAMES; i++)
- kfree(cx->vbi.sliced_mpeg_data[i]);
-
- v4l2_ctrl_handler_free(&cx->av_state.hdl);
-
- CX18_INFO("Removed %s\n", cx->card_name);
-
- v4l2_device_unregister(v4l2_dev);
- kfree(cx);
-}
-
-
-/* define a pci_driver for card detection */
-static struct pci_driver cx18_pci_driver = {
- .name = "cx18",
- .id_table = cx18_pci_tbl,
- .probe = cx18_probe,
- .remove = cx18_remove,
-};
-
-static int __init module_start(void)
-{
- printk(KERN_INFO "cx18: Start initialization, version %s\n",
- CX18_VERSION);
-
- /* Validate parameters */
- if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
- printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n",
- CX18_MAX_CARDS - 1);
- return -1;
- }
-
- if (cx18_debug < 0 || cx18_debug > 511) {
- cx18_debug = 0;
- printk(KERN_INFO "cx18: Debug value must be >= 0 and <= 511!\n");
- }
-
- if (pci_register_driver(&cx18_pci_driver)) {
- printk(KERN_ERR "cx18: Error detecting PCI card\n");
- return -ENODEV;
- }
- printk(KERN_INFO "cx18: End initialization\n");
- return 0;
-}
-
-static void __exit module_cleanup(void)
-{
- pci_unregister_driver(&cx18_pci_driver);
-}
-
-module_init(module_start);
-module_exit(module_cleanup);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
deleted file mode 100644
index 2767c64df0c..00000000000
--- a/drivers/media/video/cx18/cx18-driver.h
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * cx18 driver internal defines and structures
- *
- * Derived from ivtv-driver.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#ifndef CX18_DRIVER_H
-#define CX18_DRIVER_H
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/list.h>
-#include <linux/unistd.h>
-#include <linux/pagemap.h>
-#include <linux/workqueue.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <asm/byteorder.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-fh.h>
-#include <media/tuner.h>
-#include <media/ir-kbd-i2c.h>
-#include "cx18-mailbox.h"
-#include "cx18-av-core.h"
-#include "cx23418.h"
-
-/* DVB */
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
-
-/* Videobuf / YUV support */
-#include <media/videobuf-core.h>
-#include <media/videobuf-vmalloc.h>
-
-#ifndef CONFIG_PCI
-# error "This driver requires kernel PCI support."
-#endif
-
-#define CX18_MEM_OFFSET 0x00000000
-#define CX18_MEM_SIZE 0x04000000
-#define CX18_REG_OFFSET 0x02000000
-
-/* Maximum cx18 driver instances. */
-#define CX18_MAX_CARDS 32
-
-/* Supported cards */
-#define CX18_CARD_HVR_1600_ESMT 0 /* Hauppauge HVR 1600 (ESMT memory) */
-#define CX18_CARD_HVR_1600_SAMSUNG 1 /* Hauppauge HVR 1600 (Samsung memory) */
-#define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */
-#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
-#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */
-#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
-#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */
-#define CX18_CARD_LEADTEK_DVR3100H 7 /* Leadtek WinFast DVR3100 H */
-#define CX18_CARD_GOTVIEW_PCI_DVD3 8 /* GoTView PCI DVD3 Hybrid */
-#define CX18_CARD_HVR_1600_S5H1411 9 /* Hauppauge HVR 1600 s5h1411/tda18271*/
-#define CX18_CARD_LAST 9
-
-#define CX18_ENC_STREAM_TYPE_MPG 0
-#define CX18_ENC_STREAM_TYPE_TS 1
-#define CX18_ENC_STREAM_TYPE_YUV 2
-#define CX18_ENC_STREAM_TYPE_VBI 3
-#define CX18_ENC_STREAM_TYPE_PCM 4
-#define CX18_ENC_STREAM_TYPE_IDX 5
-#define CX18_ENC_STREAM_TYPE_RAD 6
-#define CX18_MAX_STREAMS 7
-
-/* system vendor and device IDs */
-#define PCI_VENDOR_ID_CX 0x14f1
-#define PCI_DEVICE_ID_CX23418 0x5b7a
-
-/* subsystem vendor ID */
-#define CX18_PCI_ID_HAUPPAUGE 0x0070
-#define CX18_PCI_ID_COMPRO 0x185b
-#define CX18_PCI_ID_YUAN 0x12ab
-#define CX18_PCI_ID_CONEXANT 0x14f1
-#define CX18_PCI_ID_TOSHIBA 0x1179
-#define CX18_PCI_ID_LEADTEK 0x107D
-#define CX18_PCI_ID_GOTVIEW 0x5854
-
-/* ======================================================================== */
-/* ========================== START USER SETTABLE DMA VARIABLES =========== */
-/* ======================================================================== */
-
-/* DMA Buffers, Default size in MB allocated */
-#define CX18_DEFAULT_ENC_TS_BUFFERS 1
-#define CX18_DEFAULT_ENC_MPG_BUFFERS 2
-#define CX18_DEFAULT_ENC_IDX_BUFFERS 1
-#define CX18_DEFAULT_ENC_YUV_BUFFERS 2
-#define CX18_DEFAULT_ENC_VBI_BUFFERS 1
-#define CX18_DEFAULT_ENC_PCM_BUFFERS 1
-
-/* Maximum firmware DMA buffers per stream */
-#define CX18_MAX_FW_MDLS_PER_STREAM 63
-
-/* YUV buffer sizes in bytes to ensure integer # of frames per buffer */
-#define CX18_UNIT_ENC_YUV_BUFSIZE (720 * 32 * 3 / 2) /* bytes */
-#define CX18_625_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 576/32)
-#define CX18_525_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 480/32)
-
-/* IDX buffer size should be a multiple of the index entry size from the chip */
-struct cx18_enc_idx_entry {
- __le32 length;
- __le32 offset_low;
- __le32 offset_high;
- __le32 flags;
- __le32 pts_low;
- __le32 pts_high;
-} __attribute__ ((packed));
-#define CX18_UNIT_ENC_IDX_BUFSIZE \
- (sizeof(struct cx18_enc_idx_entry) * V4L2_ENC_IDX_ENTRIES)
-
-/* DMA buffer, default size in kB allocated */
-#define CX18_DEFAULT_ENC_TS_BUFSIZE 32
-#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32
-#define CX18_DEFAULT_ENC_IDX_BUFSIZE (CX18_UNIT_ENC_IDX_BUFSIZE * 1 / 1024 + 1)
-#define CX18_DEFAULT_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1)
-#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4
-
-/* i2c stuff */
-#define I2C_CLIENTS_MAX 16
-
-/* debugging */
-
-/* Flag to turn on high volume debugging */
-#define CX18_DBGFLG_WARN (1 << 0)
-#define CX18_DBGFLG_INFO (1 << 1)
-#define CX18_DBGFLG_API (1 << 2)
-#define CX18_DBGFLG_DMA (1 << 3)
-#define CX18_DBGFLG_IOCTL (1 << 4)
-#define CX18_DBGFLG_FILE (1 << 5)
-#define CX18_DBGFLG_I2C (1 << 6)
-#define CX18_DBGFLG_IRQ (1 << 7)
-/* Flag to turn on high volume debugging */
-#define CX18_DBGFLG_HIGHVOL (1 << 8)
-
-/* NOTE: extra space before comma in 'fmt , ## args' is required for
- gcc-2.95, otherwise it won't compile. */
-#define CX18_DEBUG(x, type, fmt, args...) \
- do { \
- if ((x) & cx18_debug) \
- v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
- } while (0)
-#define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args)
-#define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args)
-#define CX18_DEBUG_API(fmt, args...) CX18_DEBUG(CX18_DBGFLG_API, "api", fmt , ## args)
-#define CX18_DEBUG_DMA(fmt, args...) CX18_DEBUG(CX18_DBGFLG_DMA, "dma", fmt , ## args)
-#define CX18_DEBUG_IOCTL(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args)
-#define CX18_DEBUG_FILE(fmt, args...) CX18_DEBUG(CX18_DBGFLG_FILE, "file", fmt , ## args)
-#define CX18_DEBUG_I2C(fmt, args...) CX18_DEBUG(CX18_DBGFLG_I2C, "i2c", fmt , ## args)
-#define CX18_DEBUG_IRQ(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
-
-#define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \
- do { \
- if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
- v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
- } while (0)
-#define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args)
-#define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args)
-#define CX18_DEBUG_HI_API(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_API, "api", fmt , ## args)
-#define CX18_DEBUG_HI_DMA(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_DMA, "dma", fmt , ## args)
-#define CX18_DEBUG_HI_IOCTL(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args)
-#define CX18_DEBUG_HI_FILE(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_FILE, "file", fmt , ## args)
-#define CX18_DEBUG_HI_I2C(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_I2C, "i2c", fmt , ## args)
-#define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
-
-/* Standard kernel messages */
-#define CX18_ERR(fmt, args...) v4l2_err(&cx->v4l2_dev, fmt , ## args)
-#define CX18_WARN(fmt, args...) v4l2_warn(&cx->v4l2_dev, fmt , ## args)
-#define CX18_INFO(fmt, args...) v4l2_info(&cx->v4l2_dev, fmt , ## args)
-
-/* Messages for internal subdevs to use */
-#define CX18_DEBUG_DEV(x, dev, type, fmt, args...) \
- do { \
- if ((x) & cx18_debug) \
- v4l2_info(dev, " " type ": " fmt , ## args); \
- } while (0)
-#define CX18_DEBUG_WARN_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args)
-#define CX18_DEBUG_INFO_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args)
-#define CX18_DEBUG_API_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args)
-#define CX18_DEBUG_DMA_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args)
-#define CX18_DEBUG_IOCTL_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args)
-#define CX18_DEBUG_FILE_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args)
-#define CX18_DEBUG_I2C_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args)
-#define CX18_DEBUG_IRQ_DEV(dev, fmt, args...) \
- CX18_DEBUG_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args)
-
-#define CX18_DEBUG_HIGH_VOL_DEV(x, dev, type, fmt, args...) \
- do { \
- if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
- v4l2_info(dev, " " type ": " fmt , ## args); \
- } while (0)
-#define CX18_DEBUG_HI_WARN_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args)
-#define CX18_DEBUG_HI_INFO_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args)
-#define CX18_DEBUG_HI_API_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args)
-#define CX18_DEBUG_HI_DMA_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args)
-#define CX18_DEBUG_HI_IOCTL_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args)
-#define CX18_DEBUG_HI_FILE_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args)
-#define CX18_DEBUG_HI_I2C_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args)
-#define CX18_DEBUG_HI_IRQ_DEV(dev, fmt, args...) \
- CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args)
-
-#define CX18_ERR_DEV(dev, fmt, args...) v4l2_err(dev, fmt , ## args)
-#define CX18_WARN_DEV(dev, fmt, args...) v4l2_warn(dev, fmt , ## args)
-#define CX18_INFO_DEV(dev, fmt, args...) v4l2_info(dev, fmt , ## args)
-
-extern int cx18_debug;
-
-struct cx18_options {
- int megabytes[CX18_MAX_STREAMS]; /* Size in megabytes of each stream */
- int cardtype; /* force card type on load */
- int tuner; /* set tuner on load */
- int radio; /* enable/disable radio */
-};
-
-/* per-mdl bit flags */
-#define CX18_F_M_NEED_SWAP 0 /* mdl buffer data must be endianess swapped */
-
-/* per-stream, s_flags */
-#define CX18_F_S_CLAIMED 3 /* this stream is claimed */
-#define CX18_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */
-#define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
-#define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */
-#define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */
-#define CX18_F_S_STOPPING 9 /* telling the fw to stop capturing */
-
-/* per-cx18, i_flags */
-#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */
-#define CX18_F_I_EOS 4 /* End of encoder stream */
-#define CX18_F_I_RADIO_USER 5 /* radio tuner is selected */
-#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */
-#define CX18_F_I_INITED 21 /* set after first open */
-#define CX18_F_I_FAILED 22 /* set if first open failed */
-
-/* These are the VBI types as they appear in the embedded VBI private packets. */
-#define CX18_SLICED_TYPE_TELETEXT_B (1)
-#define CX18_SLICED_TYPE_CAPTION_525 (4)
-#define CX18_SLICED_TYPE_WSS_625 (5)
-#define CX18_SLICED_TYPE_VPS (7)
-
-/**
- * list_entry_is_past_end - check if a previous loop cursor is off list end
- * @pos: the type * previously used as a loop cursor.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- *
- * Check if the entry's list_head is the head of the list, thus it's not a
- * real entry but was the loop cursor that walked past the end
- */
-#define list_entry_is_past_end(pos, head, member) \
- (&pos->member == (head))
-
-struct cx18_buffer {
- struct list_head list;
- dma_addr_t dma_handle;
- char *buf;
-
- u32 bytesused;
- u32 readpos;
-};
-
-struct cx18_mdl {
- struct list_head list;
- u32 id; /* index into cx->scb->cpu_mdl[] of 1st cx18_mdl_ent */
-
- unsigned int skipped;
- unsigned long m_flags;
-
- struct list_head buf_list;
- struct cx18_buffer *curr_buf; /* current buffer in list for reading */
-
- u32 bytesused;
- u32 readpos;
-};
-
-struct cx18_queue {
- struct list_head list;
- atomic_t depth;
- u32 bytesused;
- spinlock_t lock;
-};
-
-struct cx18_stream; /* forward reference */
-
-struct cx18_dvb {
- struct cx18_stream *stream;
- struct dmx_frontend hw_frontend;
- struct dmx_frontend mem_frontend;
- struct dmxdev dmxdev;
- struct dvb_adapter dvb_adapter;
- struct dvb_demux demux;
- struct dvb_frontend *fe;
- struct dvb_net dvbnet;
- int enabled;
- int feeding;
- struct mutex feedlock;
-};
-
-struct cx18; /* forward reference */
-struct cx18_scb; /* forward reference */
-
-
-#define CX18_MAX_MDL_ACKS 2
-#define CX18_MAX_IN_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7)
-/* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */
-
-#define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1
-#define CX18_F_EWO_MB_STALE_WHILE_PROC 0x2
-#define CX18_F_EWO_MB_STALE \
- (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC)
-
-struct cx18_in_work_order {
- struct work_struct work;
- atomic_t pending;
- struct cx18 *cx;
- unsigned long flags;
- int rpu;
- struct cx18_mailbox mb;
- struct cx18_mdl_ack mdl_ack[CX18_MAX_MDL_ACKS];
- char *str;
-};
-
-#define CX18_INVALID_TASK_HANDLE 0xffffffff
-
-struct cx18_stream {
- /* These first five fields are always set, even if the stream
- is not actually created. */
- struct video_device *video_dev; /* NULL when stream not created */
- struct cx18_dvb *dvb; /* DVB / Digital Transport */
- struct cx18 *cx; /* for ease of use */
- const char *name; /* name of the stream */
- int type; /* stream type */
- u32 handle; /* task handle */
- unsigned int mdl_base_idx;
-
- u32 id;
- unsigned long s_flags; /* status flags, see above */
- int dma; /* can be PCI_DMA_TODEVICE,
- PCI_DMA_FROMDEVICE or
- PCI_DMA_NONE */
- wait_queue_head_t waitq;
-
- /* Buffers */
- struct list_head buf_pool; /* buffers not attached to an MDL */
- u32 buffers; /* total buffers owned by this stream */
- u32 buf_size; /* size in bytes of a single buffer */
-
- /* MDL sizes - all stream MDLs are the same size */
- u32 bufs_per_mdl;
- u32 mdl_size; /* total bytes in all buffers in a mdl */
-
- /* MDL Queues */
- struct cx18_queue q_free; /* free - in rotation, not committed */
- struct cx18_queue q_busy; /* busy - in use by firmware */
- struct cx18_queue q_full; /* full - data for user apps */
- struct cx18_queue q_idle; /* idle - not in rotation */
-
- struct work_struct out_work_order;
-
- /* Videobuf for YUV video */
- u32 pixelformat;
- u32 vb_bytes_per_frame;
- struct list_head vb_capture; /* video capture queue */
- spinlock_t vb_lock;
- struct timer_list vb_timeout;
-
- struct videobuf_queue vbuf_q;
- spinlock_t vbuf_q_lock; /* Protect vbuf_q */
- enum v4l2_buf_type vb_type;
-};
-
-struct cx18_videobuf_buffer {
- /* Common video buffer sub-system struct */
- struct videobuf_buffer vb;
- v4l2_std_id tvnorm; /* selected tv norm */
- u32 bytes_used;
-};
-
-struct cx18_open_id {
- struct v4l2_fh fh;
- u32 open_id;
- int type;
- struct cx18 *cx;
-};
-
-static inline struct cx18_open_id *fh2id(struct v4l2_fh *fh)
-{
- return container_of(fh, struct cx18_open_id, fh);
-}
-
-static inline struct cx18_open_id *file2id(struct file *file)
-{
- return fh2id(file->private_data);
-}
-
-/* forward declaration of struct defined in cx18-cards.h */
-struct cx18_card;
-
-/*
- * A note about "sliced" VBI data as implemented in this driver:
- *
- * Currently we collect the sliced VBI in the form of Ancillary Data
- * packets, inserted by the AV core decoder/digitizer/slicer in the
- * horizontal blanking region of the VBI lines, in "raw" mode as far as
- * the Encoder is concerned. We don't ever tell the Encoder itself
- * to provide sliced VBI. (AV Core: sliced mode - Encoder: raw mode)
- *
- * We then process the ancillary data ourselves to send the sliced data
- * to the user application directly or build up MPEG-2 private stream 1
- * packets to splice into (only!) MPEG-2 PS streams for the user app.
- *
- * (That's how ivtv essentially does it.)
- *
- * The Encoder should be able to extract certain sliced VBI data for
- * us and provide it in a separate stream or splice it into any type of
- * MPEG PS or TS stream, but this isn't implemented yet.
- */
-
-/*
- * Number of "raw" VBI samples per horizontal line we tell the Encoder to
- * grab from the decoder/digitizer/slicer output for raw or sliced VBI.
- * It depends on the pixel clock and the horiz rate:
- *
- * (1/Fh)*(2*Fp) = Samples/line
- * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
- *
- * Sliced VBI data is sent as ancillary data during horizontal blanking
- * Raw VBI is sent as active video samples during vertcal blanking
- *
- * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
- * length of 720 pixels @ 4:2:2 sampling. Thus...
- *
- * For systems that use a 15.734 kHz horizontal rate, such as
- * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
- *
- * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
- * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
- *
- * For systems that use a 15.625 kHz horizontal rate, such as
- * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
- *
- * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
- * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
- */
-static const u32 vbi_active_samples = 1444; /* 4 byte SAV + 720 Y + 720 U/V */
-static const u32 vbi_hblank_samples_60Hz = 272; /* 4 byte EAV + 268 anc/fill */
-static const u32 vbi_hblank_samples_50Hz = 284; /* 4 byte EAV + 280 anc/fill */
-
-#define CX18_VBI_FRAMES 32
-
-struct vbi_info {
- /* Current state of v4l2 VBI settings for this device */
- struct v4l2_format in;
- struct v4l2_sliced_vbi_format *sliced_in; /* pointer to in.fmt.sliced */
- u32 count; /* Count of VBI data lines: 60 Hz: 12 or 50 Hz: 18 */
- u32 start[2]; /* First VBI data line per field: 10 & 273 or 6 & 318 */
-
- u32 frame; /* Count of VBI buffers/frames received from Encoder */
-
- /*
- * Vars for creation and insertion of MPEG Private Stream 1 packets
- * of sliced VBI data into an MPEG PS
- */
-
- /* Boolean: create and insert Private Stream 1 packets into the PS */
- int insert_mpeg;
-
- /*
- * Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
- * Used in cx18-vbi.c only for collecting sliced data, and as a source
- * during conversion of sliced VBI data into MPEG Priv Stream 1 packets.
- * We don't need to save state here, but the array may have been a bit
- * too big (2304 bytes) to alloc from the stack.
- */
- struct v4l2_sliced_vbi_data sliced_data[36];
-
- /*
- * A ring buffer of driver-generated MPEG-2 PS
- * Program Pack/Private Stream 1 packets for sliced VBI data insertion
- * into the MPEG PS stream.
- *
- * In each sliced_mpeg_data[] buffer is:
- * 16 byte MPEG-2 PS Program Pack Header
- * 16 byte MPEG-2 Private Stream 1 PES Header
- * 4 byte magic number: "itv0" or "ITV0"
- * 4 byte first field line mask, if "itv0"
- * 4 byte second field line mask, if "itv0"
- * 36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data
- *
- * Each line in the payload is
- * 1 byte line header derived from the SDID (WSS, CC, VPS, etc.)
- * 42 bytes of line data
- *
- * That's a maximum 1552 bytes of payload in the Private Stream 1 packet
- * which is the payload size a PVR-350 (CX23415) MPEG decoder will
- * accept for VBI data. So, including the headers, it's a maximum 1584
- * bytes total.
- */
-#define CX18_SLICED_MPEG_DATA_MAXSZ 1584
- /* copy_vbi_buf() needs 8 temp bytes on the end for the worst case */
-#define CX18_SLICED_MPEG_DATA_BUFSZ (CX18_SLICED_MPEG_DATA_MAXSZ+8)
- u8 *sliced_mpeg_data[CX18_VBI_FRAMES];
- u32 sliced_mpeg_size[CX18_VBI_FRAMES];
-
- /* Count of Program Pack/Program Stream 1 packets inserted into PS */
- u32 inserted_frame;
-
- /*
- * A dummy driver stream transfer mdl & buffer with a copy of the next
- * sliced_mpeg_data[] buffer for output to userland apps.
- * Only used in cx18-fileops.c, but its state needs to persist at times.
- */
- struct cx18_mdl sliced_mpeg_mdl;
- struct cx18_buffer sliced_mpeg_buf;
-};
-
-/* Per cx23418, per I2C bus private algo callback data */
-struct cx18_i2c_algo_callback_data {
- struct cx18 *cx;
- int bus_index; /* 0 or 1 for the cx23418's 1st or 2nd I2C bus */
-};
-
-#define CX18_MAX_MMIO_WR_RETRIES 10
-
-/* Struct to hold info about cx18 cards */
-struct cx18 {
- int instance;
- struct pci_dev *pci_dev;
- struct v4l2_device v4l2_dev;
- struct v4l2_subdev *sd_av; /* A/V decoder/digitizer sub-device */
- struct v4l2_subdev *sd_extmux; /* External multiplexer sub-dev */
-
- const struct cx18_card *card; /* card information */
- const char *card_name; /* full name of the card */
- const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
- u8 is_50hz;
- u8 is_60hz;
- u8 nof_inputs; /* number of video inputs */
- u8 nof_audio_inputs; /* number of audio inputs */
- u32 v4l2_cap; /* V4L2 capabilities of card */
- u32 hw_flags; /* Hardware description of the board */
- unsigned int free_mdl_idx;
- struct cx18_scb __iomem *scb; /* pointer to SCB */
- struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/
- struct mutex epu2cpu_mb_lock; /* protect driver to chip mailbox in SCB*/
-
- struct cx18_av_state av_state;
-
- /* codec settings */
- struct cx2341x_handler cxhdl;
- u32 filter_mode;
- u32 temporal_strength;
- u32 spatial_strength;
-
- /* dualwatch */
- unsigned long dualwatch_jiffies;
- u32 dualwatch_stereo_mode;
-
- struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
- struct cx18_options options; /* User options */
- int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */
- int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
- struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
- struct snd_cx18_card *alsa; /* ALSA interface for PCM capture stream */
- void (*pcm_announce_callback)(struct snd_cx18_card *card, u8 *pcm_data,
- size_t num_bytes);
-
- unsigned long i_flags; /* global cx18 flags */
- atomic_t ana_capturing; /* count number of active analog capture streams */
- atomic_t tot_capturing; /* total count number of active capture streams */
- int search_pack_header;
-
- int open_id; /* incremented each time an open occurs, used as
- unique ID. Starts at 1, so 0 can be used as
- uninitialized value in the stream->id. */
-
- resource_size_t base_addr;
-
- u8 card_rev;
- void __iomem *enc_mem, *reg_mem;
-
- struct vbi_info vbi;
-
- u64 mpg_data_received;
- u64 vbi_data_inserted;
-
- wait_queue_head_t mb_apu_waitq;
- wait_queue_head_t mb_cpu_waitq;
- wait_queue_head_t cap_w;
- /* when the current DMA is finished this queue is woken up */
- wait_queue_head_t dma_waitq;
-
- u32 sw1_irq_mask;
- u32 sw2_irq_mask;
- u32 hw2_irq_mask;
-
- struct workqueue_struct *in_work_queue;
- char in_workq_name[11]; /* "cx18-NN-in" */
- struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS];
- char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */
-
- /* i2c */
- struct i2c_adapter i2c_adap[2];
- struct i2c_algo_bit_data i2c_algo[2];
- struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
-
- struct IR_i2c_init_data ir_i2c_init_data;
-
- /* gpio */
- u32 gpio_dir;
- u32 gpio_val;
- struct mutex gpio_lock;
- struct v4l2_subdev sd_gpiomux;
- struct v4l2_subdev sd_resetctrl;
-
- /* v4l2 and User settings */
-
- /* codec settings */
- u32 audio_input;
- u32 active_input;
- v4l2_std_id std;
- v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
-
- /* Used for cx18-alsa module loading */
- struct work_struct request_module_wk;
-};
-
-static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct cx18, v4l2_dev);
-}
-
-/* cx18 extensions to be loaded */
-extern int (*cx18_ext_init)(struct cx18 *);
-
-/* Globals */
-extern int cx18_first_minor;
-
-/*==============Prototypes==================*/
-
-/* Return non-zero if a signal is pending */
-int cx18_msleep_timeout(unsigned int msecs, int intr);
-
-/* Read Hauppauge eeprom */
-struct tveeprom; /* forward reference */
-void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
-
-/* First-open initialization: load firmware, etc. */
-int cx18_init_on_first_open(struct cx18 *cx);
-
-/* Test if the current VBI mode is raw (1) or sliced (0) */
-static inline int cx18_raw_vbi(const struct cx18 *cx)
-{
- return cx->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE;
-}
-
-/* Call the specified callback for all subdevs with a grp_id bit matching the
- * mask in hw (if 0, then match them all). Ignore any errors. */
-#define cx18_call_hw(cx, hw, o, f, args...) \
- do { \
- struct v4l2_subdev *__sd; \
- __v4l2_device_call_subdevs_p(&(cx)->v4l2_dev, __sd, \
- !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \
- } while (0)
-
-#define cx18_call_all(cx, o, f, args...) cx18_call_hw(cx, 0, o, f , ##args)
-
-/* Call the specified callback for all subdevs with a grp_id bit matching the
- * mask in hw (if 0, then match them all). If the callback returns an error
- * other than 0 or -ENOIOCTLCMD, then return with that error code. */
-#define cx18_call_hw_err(cx, hw, o, f, args...) \
-({ \
- struct v4l2_subdev *__sd; \
- __v4l2_device_call_subdevs_until_err_p(&(cx)->v4l2_dev, \
- __sd, !(hw) || (__sd->grp_id & (hw)), o, f, \
- ##args); \
-})
-
-#define cx18_call_all_err(cx, o, f, args...) \
- cx18_call_hw_err(cx, 0, o, f , ##args)
-
-#endif /* CX18_DRIVER_H */
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
deleted file mode 100644
index f41922bd402..00000000000
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- * cx18 functions for DVB support
- *
- * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx18-version.h"
-#include "cx18-dvb.h"
-#include "cx18-io.h"
-#include "cx18-queue.h"
-#include "cx18-streams.h"
-#include "cx18-cards.h"
-#include "cx18-gpio.h"
-#include "s5h1409.h"
-#include "mxl5005s.h"
-#include "s5h1411.h"
-#include "tda18271.h"
-#include "zl10353.h"
-
-#include <linux/firmware.h>
-#include "mt352.h"
-#include "mt352_priv.h"
-#include "tuner-xc2028.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
-#define CX18_CLOCK_ENABLE2 0xc71024
-#define CX18_DMUX_CLK_MASK 0x0080
-
-/*
- * CX18_CARD_HVR_1600_ESMT
- * CX18_CARD_HVR_1600_SAMSUNG
- */
-
-static struct mxl5005s_config hauppauge_hvr1600_tuner = {
- .i2c_address = 0xC6 >> 1,
- .if_freq = IF_FREQ_5380000HZ,
- .xtal_freq = CRYSTAL_FREQ_16000000HZ,
- .agc_mode = MXL_SINGLE_AGC,
- .tracking_filter = MXL_TF_C_H,
- .rssi_enable = MXL_RSSI_ENABLE,
- .cap_select = MXL_CAP_SEL_ENABLE,
- .div_out = MXL_DIV_OUT_4,
- .clock_out = MXL_CLOCK_OUT_DISABLE,
- .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
- .top = MXL5005S_TOP_25P2,
- .mod_mode = MXL_DIGITAL_MODE,
- .if_mode = MXL_ZERO_IF,
- .qam_gain = 0x02,
- .AgcMasterByte = 0x00,
-};
-
-static struct s5h1409_config hauppauge_hvr1600_config = {
- .demod_address = 0x32 >> 1,
- .output_mode = S5H1409_SERIAL_OUTPUT,
- .gpio = S5H1409_GPIO_ON,
- .qam_if = 44000,
- .inversion = S5H1409_INVERSION_OFF,
- .status_mode = S5H1409_DEMODLOCKING,
- .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
- .hvr1600_opt = S5H1409_HVR1600_OPTIMIZE
-};
-
-/*
- * CX18_CARD_HVR_1600_S5H1411
- */
-static struct s5h1411_config hcw_s5h1411_config = {
- .output_mode = S5H1411_SERIAL_OUTPUT,
- .gpio = S5H1411_GPIO_OFF,
- .vsb_if = S5H1411_IF_44000,
- .qam_if = S5H1411_IF_4000,
- .inversion = S5H1411_INVERSION_ON,
- .status_mode = S5H1411_DEMODLOCKING,
- .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static struct tda18271_std_map hauppauge_tda18271_std_map = {
- .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3,
- .if_lvl = 6, .rfagc_top = 0x37 },
- .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
- .if_lvl = 6, .rfagc_top = 0x37 },
-};
-
-static struct tda18271_config hauppauge_tda18271_config = {
- .std_map = &hauppauge_tda18271_std_map,
- .gate = TDA18271_GATE_DIGITAL,
- .output_opt = TDA18271_OUTPUT_LT_OFF,
-};
-
-/*
- * CX18_CARD_LEADTEK_DVR3100H
- */
-/* Information/confirmation of proper config values provided by Terry Wu */
-static struct zl10353_config leadtek_dvr3100h_demod = {
- .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
- .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
- .parallel_ts = 1, /* Not a serial TS */
- .no_tuner = 1, /* XC3028 is not behind the gate */
- .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
-};
-
-/*
- * CX18_CARD_YUAN_MPC718
- */
-/*
- * Due to
- *
- * 1. an absence of information on how to prgram the MT352
- * 2. the Linux mt352 module pushing MT352 initialzation off onto us here
- *
- * We have to use an init sequence that *you* must extract from the Windows
- * driver (yuanrap.sys) and which we load as a firmware.
- *
- * If someone can provide me with a Zarlink MT352 (Intel CE6352?) Design Manual
- * with chip programming details, then I can remove this annoyance.
- */
-static int yuan_mpc718_mt352_reqfw(struct cx18_stream *stream,
- const struct firmware **fw)
-{
- struct cx18 *cx = stream->cx;
- const char *fn = "dvb-cx18-mpc718-mt352.fw";
- int ret;
-
- ret = request_firmware(fw, fn, &cx->pci_dev->dev);
- if (ret)
- CX18_ERR("Unable to open firmware file %s\n", fn);
- else {
- size_t sz = (*fw)->size;
- if (sz < 2 || sz > 64 || (sz % 2) != 0) {
- CX18_ERR("Firmware %s has a bad size: %lu bytes\n",
- fn, (unsigned long) sz);
- ret = -EILSEQ;
- release_firmware(*fw);
- *fw = NULL;
- }
- }
-
- if (ret) {
- CX18_ERR("The MPC718 board variant with the MT352 DVB-T"
- "demodualtor will not work without it\n");
- CX18_ERR("Run 'linux/Documentation/dvb/get_dvb_firmware "
- "mpc718' if you need the firmware\n");
- }
- return ret;
-}
-
-static int yuan_mpc718_mt352_init(struct dvb_frontend *fe)
-{
- struct cx18_dvb *dvb = container_of(fe->dvb,
- struct cx18_dvb, dvb_adapter);
- struct cx18_stream *stream = dvb->stream;
- const struct firmware *fw = NULL;
- int ret;
- int i;
- u8 buf[3];
-
- ret = yuan_mpc718_mt352_reqfw(stream, &fw);
- if (ret)
- return ret;
-
- /* Loop through all the register-value pairs in the firmware file */
- for (i = 0; i < fw->size; i += 2) {
- buf[0] = fw->data[i];
- /* Intercept a few registers we want to set ourselves */
- switch (buf[0]) {
- case TRL_NOMINAL_RATE_0:
- /* Set our custom OFDM bandwidth in the case below */
- break;
- case TRL_NOMINAL_RATE_1:
- /* 6 MHz: 64/7 * 6/8 / 20.48 * 2^16 = 0x55b6.db6 */
- /* 7 MHz: 64/7 * 7/8 / 20.48 * 2^16 = 0x6400 */
- /* 8 MHz: 64/7 * 8/8 / 20.48 * 2^16 = 0x7249.249 */
- buf[1] = 0x72;
- buf[2] = 0x49;
- mt352_write(fe, buf, 3);
- break;
- case INPUT_FREQ_0:
- /* Set our custom IF in the case below */
- break;
- case INPUT_FREQ_1:
- /* 4.56 MHz IF: (20.48 - 4.56)/20.48 * 2^14 = 0x31c0 */
- buf[1] = 0x31;
- buf[2] = 0xc0;
- mt352_write(fe, buf, 3);
- break;
- default:
- /* Pass through the register-value pair from the fw */
- buf[1] = fw->data[i+1];
- mt352_write(fe, buf, 2);
- break;
- }
- }
-
- buf[0] = (u8) TUNER_GO;
- buf[1] = 0x01; /* Go */
- mt352_write(fe, buf, 2);
- release_firmware(fw);
- return 0;
-}
-
-static struct mt352_config yuan_mpc718_mt352_demod = {
- .demod_address = 0x1e >> 1,
- .adc_clock = 20480, /* 20.480 MHz */
- .if2 = 4560, /* 4.560 MHz */
- .no_tuner = 1, /* XC3028 is not behind the gate */
- .demod_init = yuan_mpc718_mt352_init,
-};
-
-static struct zl10353_config yuan_mpc718_zl10353_demod = {
- .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
- .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
- .parallel_ts = 1, /* Not a serial TS */
- .no_tuner = 1, /* XC3028 is not behind the gate */
- .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
-};
-
-static struct zl10353_config gotview_dvd3_zl10353_demod = {
- .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
- .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
- .parallel_ts = 1, /* Not a serial TS */
- .no_tuner = 1, /* XC3028 is not behind the gate */
- .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
-};
-
-static int dvb_register(struct cx18_stream *stream);
-
-/* Kernel DVB framework calls this when the feed needs to start.
- * The CX18 framework should enable the transport DMA handling
- * and queue processing.
- */
-static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct cx18_stream *stream = (struct cx18_stream *) demux->priv;
- struct cx18 *cx;
- int ret;
- u32 v;
-
- if (!stream)
- return -EINVAL;
-
- cx = stream->cx;
- CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n",
- feed->pid, feed->index);
-
- mutex_lock(&cx->serialize_lock);
- ret = cx18_init_on_first_open(cx);
- mutex_unlock(&cx->serialize_lock);
- if (ret) {
- CX18_ERR("Failed to initialize firmware starting DVB feed\n");
- return ret;
- }
- ret = -EINVAL;
-
- switch (cx->card->type) {
- case CX18_CARD_HVR_1600_ESMT:
- case CX18_CARD_HVR_1600_SAMSUNG:
- case CX18_CARD_HVR_1600_S5H1411:
- v = cx18_read_reg(cx, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
- v |= 0x00400000; /* Serial Mode */
- v |= 0x00002000; /* Data Length - Byte */
- v |= 0x00010000; /* Error - Polarity */
- v |= 0x00020000; /* Error - Passthru */
- v |= 0x000c0000; /* Error - Ignore */
- cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
- break;
-
- case CX18_CARD_LEADTEK_DVR3100H:
- case CX18_CARD_YUAN_MPC718:
- case CX18_CARD_GOTVIEW_PCI_DVD3:
- default:
- /* Assumption - Parallel transport - Signalling
- * undefined or default.
- */
- break;
- }
-
- if (!demux->dmx.frontend)
- return -EINVAL;
-
- mutex_lock(&stream->dvb->feedlock);
- if (stream->dvb->feeding++ == 0) {
- CX18_DEBUG_INFO("Starting Transport DMA\n");
- mutex_lock(&cx->serialize_lock);
- set_bit(CX18_F_S_STREAMING, &stream->s_flags);
- ret = cx18_start_v4l2_encode_stream(stream);
- if (ret < 0) {
- CX18_DEBUG_INFO("Failed to start Transport DMA\n");
- stream->dvb->feeding--;
- if (stream->dvb->feeding == 0)
- clear_bit(CX18_F_S_STREAMING, &stream->s_flags);
- }
- mutex_unlock(&cx->serialize_lock);
- } else
- ret = 0;
- mutex_unlock(&stream->dvb->feedlock);
-
- return ret;
-}
-
-/* Kernel DVB framework calls this when the feed needs to stop. */
-static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct cx18_stream *stream = (struct cx18_stream *)demux->priv;
- struct cx18 *cx;
- int ret = -EINVAL;
-
- if (stream) {
- cx = stream->cx;
- CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
- feed->pid, feed->index);
-
- mutex_lock(&stream->dvb->feedlock);
- if (--stream->dvb->feeding == 0) {
- CX18_DEBUG_INFO("Stopping Transport DMA\n");
- mutex_lock(&cx->serialize_lock);
- ret = cx18_stop_v4l2_encode_stream(stream, 0);
- mutex_unlock(&cx->serialize_lock);
- } else
- ret = 0;
- mutex_unlock(&stream->dvb->feedlock);
- }
-
- return ret;
-}
-
-int cx18_dvb_register(struct cx18_stream *stream)
-{
- struct cx18 *cx = stream->cx;
- struct cx18_dvb *dvb = stream->dvb;
- struct dvb_adapter *dvb_adapter;
- struct dvb_demux *dvbdemux;
- struct dmx_demux *dmx;
- int ret;
-
- if (!dvb)
- return -EINVAL;
-
- dvb->enabled = 0;
- dvb->stream = stream;
-
- ret = dvb_register_adapter(&dvb->dvb_adapter,
- CX18_DRIVER_NAME,
- THIS_MODULE, &cx->pci_dev->dev, adapter_nr);
- if (ret < 0)
- goto err_out;
-
- dvb_adapter = &dvb->dvb_adapter;
-
- dvbdemux = &dvb->demux;
-
- dvbdemux->priv = (void *)stream;
-
- dvbdemux->filternum = 256;
- dvbdemux->feednum = 256;
- dvbdemux->start_feed = cx18_dvb_start_feed;
- dvbdemux->stop_feed = cx18_dvb_stop_feed;
- dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
- DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
- ret = dvb_dmx_init(dvbdemux);
- if (ret < 0)
- goto err_dvb_unregister_adapter;
-
- dmx = &dvbdemux->dmx;
-
- dvb->hw_frontend.source = DMX_FRONTEND_0;
- dvb->mem_frontend.source = DMX_MEMORY_FE;
- dvb->dmxdev.filternum = 256;
- dvb->dmxdev.demux = dmx;
-
- ret = dvb_dmxdev_init(&dvb->dmxdev, dvb_adapter);
- if (ret < 0)
- goto err_dvb_dmx_release;
-
- ret = dmx->add_frontend(dmx, &dvb->hw_frontend);
- if (ret < 0)
- goto err_dvb_dmxdev_release;
-
- ret = dmx->add_frontend(dmx, &dvb->mem_frontend);
- if (ret < 0)
- goto err_remove_hw_frontend;
-
- ret = dmx->connect_frontend(dmx, &dvb->hw_frontend);
- if (ret < 0)
- goto err_remove_mem_frontend;
-
- ret = dvb_register(stream);
- if (ret < 0)
- goto err_disconnect_frontend;
-
- dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
-
- CX18_INFO("DVB Frontend registered\n");
- CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n",
- stream->dvb->dvb_adapter.num, stream->name,
- stream->buffers, stream->buf_size/1024,
- (stream->buf_size * 100 / 1024) % 100);
-
- mutex_init(&dvb->feedlock);
- dvb->enabled = 1;
- return ret;
-
-err_disconnect_frontend:
- dmx->disconnect_frontend(dmx);
-err_remove_mem_frontend:
- dmx->remove_frontend(dmx, &dvb->mem_frontend);
-err_remove_hw_frontend:
- dmx->remove_frontend(dmx, &dvb->hw_frontend);
-err_dvb_dmxdev_release:
- dvb_dmxdev_release(&dvb->dmxdev);
-err_dvb_dmx_release:
- dvb_dmx_release(dvbdemux);
-err_dvb_unregister_adapter:
- dvb_unregister_adapter(dvb_adapter);
-err_out:
- return ret;
-}
-
-void cx18_dvb_unregister(struct cx18_stream *stream)
-{
- struct cx18 *cx = stream->cx;
- struct cx18_dvb *dvb = stream->dvb;
- struct dvb_adapter *dvb_adapter;
- struct dvb_demux *dvbdemux;
- struct dmx_demux *dmx;
-
- CX18_INFO("unregister DVB\n");
-
- if (dvb == NULL || !dvb->enabled)
- return;
-
- dvb_adapter = &dvb->dvb_adapter;
- dvbdemux = &dvb->demux;
- dmx = &dvbdemux->dmx;
-
- dmx->close(dmx);
- dvb_net_release(&dvb->dvbnet);
- dmx->remove_frontend(dmx, &dvb->mem_frontend);
- dmx->remove_frontend(dmx, &dvb->hw_frontend);
- dvb_dmxdev_release(&dvb->dmxdev);
- dvb_dmx_release(dvbdemux);
- dvb_unregister_frontend(dvb->fe);
- dvb_frontend_detach(dvb->fe);
- dvb_unregister_adapter(dvb_adapter);
-}
-
-/* All the DVB attach calls go here, this function get's modified
- * for each new card. cx18_dvb_start_feed() will also need changes.
- */
-static int dvb_register(struct cx18_stream *stream)
-{
- struct cx18_dvb *dvb = stream->dvb;
- struct cx18 *cx = stream->cx;
- int ret = 0;
-
- switch (cx->card->type) {
- case CX18_CARD_HVR_1600_ESMT:
- case CX18_CARD_HVR_1600_SAMSUNG:
- dvb->fe = dvb_attach(s5h1409_attach,
- &hauppauge_hvr1600_config,
- &cx->i2c_adap[0]);
- if (dvb->fe != NULL) {
- dvb_attach(mxl5005s_attach, dvb->fe,
- &cx->i2c_adap[0],
- &hauppauge_hvr1600_tuner);
- ret = 0;
- }
- break;
- case CX18_CARD_HVR_1600_S5H1411:
- dvb->fe = dvb_attach(s5h1411_attach,
- &hcw_s5h1411_config,
- &cx->i2c_adap[0]);
- if (dvb->fe != NULL)
- dvb_attach(tda18271_attach, dvb->fe,
- 0x60, &cx->i2c_adap[0],
- &hauppauge_tda18271_config);
- break;
- case CX18_CARD_LEADTEK_DVR3100H:
- dvb->fe = dvb_attach(zl10353_attach,
- &leadtek_dvr3100h_demod,
- &cx->i2c_adap[1]);
- if (dvb->fe != NULL) {
- struct dvb_frontend *fe;
- struct xc2028_config cfg = {
- .i2c_adap = &cx->i2c_adap[1],
- .i2c_addr = 0xc2 >> 1,
- .ctrl = NULL,
- };
- static struct xc2028_ctrl ctrl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64,
- .demod = XC3028_FE_ZARLINK456,
- .type = XC2028_AUTO,
- };
-
- fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
- if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
- fe->ops.tuner_ops.set_config(fe, &ctrl);
- }
- break;
- case CX18_CARD_YUAN_MPC718:
- /*
- * TODO
- * Apparently, these cards also could instead have a
- * DiBcom demod supported by one of the db7000 drivers
- */
- dvb->fe = dvb_attach(mt352_attach,
- &yuan_mpc718_mt352_demod,
- &cx->i2c_adap[1]);
- if (dvb->fe == NULL)
- dvb->fe = dvb_attach(zl10353_attach,
- &yuan_mpc718_zl10353_demod,
- &cx->i2c_adap[1]);
- if (dvb->fe != NULL) {
- struct dvb_frontend *fe;
- struct xc2028_config cfg = {
- .i2c_adap = &cx->i2c_adap[1],
- .i2c_addr = 0xc2 >> 1,
- .ctrl = NULL,
- };
- static struct xc2028_ctrl ctrl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64,
- .demod = XC3028_FE_ZARLINK456,
- .type = XC2028_AUTO,
- };
-
- fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
- if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
- fe->ops.tuner_ops.set_config(fe, &ctrl);
- }
- break;
- case CX18_CARD_GOTVIEW_PCI_DVD3:
- dvb->fe = dvb_attach(zl10353_attach,
- &gotview_dvd3_zl10353_demod,
- &cx->i2c_adap[1]);
- if (dvb->fe != NULL) {
- struct dvb_frontend *fe;
- struct xc2028_config cfg = {
- .i2c_adap = &cx->i2c_adap[1],
- .i2c_addr = 0xc2 >> 1,
- .ctrl = NULL,
- };
- static struct xc2028_ctrl ctrl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64,
- .demod = XC3028_FE_ZARLINK456,
- .type = XC2028_AUTO,
- };
-
- fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
- if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
- fe->ops.tuner_ops.set_config(fe, &ctrl);
- }
- break;
- default:
- /* No Digital Tv Support */
- break;
- }
-
- if (dvb->fe == NULL) {
- CX18_ERR("frontend initialization failed\n");
- return -1;
- }
-
- dvb->fe->callback = cx18_reset_tuner_gpio;
-
- ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe);
- if (ret < 0) {
- if (dvb->fe->ops.release)
- dvb->fe->ops.release(dvb->fe);
- return ret;
- }
-
- /*
- * The firmware seems to enable the TS DMUX clock
- * under various circumstances. However, since we know we
- * might use it, let's just turn it on ourselves here.
- */
- cx18_write_reg_expect(cx,
- (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK,
- CX18_CLOCK_ENABLE2,
- CX18_DMUX_CLK_MASK,
- (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK);
-
- return ret;
-}
diff --git a/drivers/media/video/cx18/cx18-dvb.h b/drivers/media/video/cx18/cx18-dvb.h
deleted file mode 100644
index bf8d8f6f545..00000000000
--- a/drivers/media/video/cx18/cx18-dvb.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * cx18 functions for DVB support
- *
- * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx18-driver.h"
-
-int cx18_dvb_register(struct cx18_stream *stream);
-void cx18_dvb_unregister(struct cx18_stream *stream);
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
deleted file mode 100644
index 4bfd865a410..00000000000
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * cx18 file operation functions
- *
- * Derived from ivtv-fileops.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-fileops.h"
-#include "cx18-i2c.h"
-#include "cx18-queue.h"
-#include "cx18-vbi.h"
-#include "cx18-audio.h"
-#include "cx18-mailbox.h"
-#include "cx18-scb.h"
-#include "cx18-streams.h"
-#include "cx18-controls.h"
-#include "cx18-ioctl.h"
-#include "cx18-cards.h"
-
-/* This function tries to claim the stream for a specific file descriptor.
- If no one else is using this stream then the stream is claimed and
- associated VBI and IDX streams are also automatically claimed.
- Possible error returns: -EBUSY if someone else has claimed
- the stream or 0 on success. */
-int cx18_claim_stream(struct cx18_open_id *id, int type)
-{
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[type];
- struct cx18_stream *s_assoc;
-
- /* Nothing should ever try to directly claim the IDX stream */
- if (type == CX18_ENC_STREAM_TYPE_IDX) {
- CX18_WARN("MPEG Index stream cannot be claimed "
- "directly, but something tried.\n");
- return -EINVAL;
- }
-
- if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
- /* someone already claimed this stream */
- if (s->id == id->open_id) {
- /* yes, this file descriptor did. So that's OK. */
- return 0;
- }
- if (s->id == -1 && type == CX18_ENC_STREAM_TYPE_VBI) {
- /* VBI is handled already internally, now also assign
- the file descriptor to this stream for external
- reading of the stream. */
- s->id = id->open_id;
- CX18_DEBUG_INFO("Start Read VBI\n");
- return 0;
- }
- /* someone else is using this stream already */
- CX18_DEBUG_INFO("Stream %d is busy\n", type);
- return -EBUSY;
- }
- s->id = id->open_id;
-
- /*
- * CX18_ENC_STREAM_TYPE_MPG needs to claim:
- * CX18_ENC_STREAM_TYPE_VBI, if VBI insertion is on for sliced VBI, or
- * CX18_ENC_STREAM_TYPE_IDX, if VBI insertion is off for sliced VBI
- * (We don't yet fix up MPEG Index entries for our inserted packets).
- *
- * For all other streams we're done.
- */
- if (type != CX18_ENC_STREAM_TYPE_MPG)
- return 0;
-
- s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
- if (cx->vbi.insert_mpeg && !cx18_raw_vbi(cx))
- s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
- else if (!cx18_stream_enabled(s_assoc))
- return 0;
-
- set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
-
- /* mark that it is used internally */
- set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
- return 0;
-}
-EXPORT_SYMBOL(cx18_claim_stream);
-
-/* This function releases a previously claimed stream. It will take into
- account associated VBI streams. */
-void cx18_release_stream(struct cx18_stream *s)
-{
- struct cx18 *cx = s->cx;
- struct cx18_stream *s_assoc;
-
- s->id = -1;
- if (s->type == CX18_ENC_STREAM_TYPE_IDX) {
- /*
- * The IDX stream is only used internally, and can
- * only be indirectly unclaimed by unclaiming the MPG stream.
- */
- return;
- }
-
- if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
- test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) {
- /* this stream is still in use internally */
- return;
- }
- if (!test_and_clear_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
- CX18_DEBUG_WARN("Release stream %s not in use!\n", s->name);
- return;
- }
-
- cx18_flush_queues(s);
-
- /*
- * CX18_ENC_STREAM_TYPE_MPG needs to release the
- * CX18_ENC_STREAM_TYPE_VBI and/or CX18_ENC_STREAM_TYPE_IDX streams.
- *
- * For all other streams we're done.
- */
- if (s->type != CX18_ENC_STREAM_TYPE_MPG)
- return;
-
- /* Unclaim the associated MPEG Index stream */
- s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
- if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
- clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
- cx18_flush_queues(s_assoc);
- }
-
- /* Unclaim the associated VBI stream */
- s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
- if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
- if (s_assoc->id == -1) {
- /*
- * The VBI stream is not still claimed by a file
- * descriptor, so completely unclaim it.
- */
- clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
- cx18_flush_queues(s_assoc);
- }
- }
-}
-EXPORT_SYMBOL(cx18_release_stream);
-
-static void cx18_dualwatch(struct cx18 *cx)
-{
- struct v4l2_tuner vt;
- u32 new_stereo_mode;
- const u32 dual = 0x0200;
-
- new_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
- memset(&vt, 0, sizeof(vt));
- cx18_call_all(cx, tuner, g_tuner, &vt);
- if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
- (vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
- new_stereo_mode = dual;
-
- if (new_stereo_mode == cx->dualwatch_stereo_mode)
- return;
-
- CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",
- cx->dualwatch_stereo_mode, new_stereo_mode);
- if (v4l2_ctrl_s_ctrl(cx->cxhdl.audio_mode, new_stereo_mode))
- CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
-}
-
-
-static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
- int *err)
-{
- struct cx18 *cx = s->cx;
- struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
- struct cx18_mdl *mdl;
- DEFINE_WAIT(wait);
-
- *err = 0;
- while (1) {
- if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
- /* Process pending program updates and VBI data */
- if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
- cx->dualwatch_jiffies = jiffies;
- cx18_dualwatch(cx);
- }
- if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
- !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
- while ((mdl = cx18_dequeue(s_vbi,
- &s_vbi->q_full))) {
- /* byteswap and process VBI data */
- cx18_process_vbi_data(cx, mdl,
- s_vbi->type);
- cx18_stream_put_mdl_fw(s_vbi, mdl);
- }
- }
- mdl = &cx->vbi.sliced_mpeg_mdl;
- if (mdl->readpos != mdl->bytesused)
- return mdl;
- }
-
- /* do we have new data? */
- mdl = cx18_dequeue(s, &s->q_full);
- if (mdl) {
- if (!test_and_clear_bit(CX18_F_M_NEED_SWAP,
- &mdl->m_flags))
- return mdl;
- if (s->type == CX18_ENC_STREAM_TYPE_MPG)
- /* byteswap MPG data */
- cx18_mdl_swap(mdl);
- else {
- /* byteswap and process VBI data */
- cx18_process_vbi_data(cx, mdl, s->type);
- }
- return mdl;
- }
-
- /* return if end of stream */
- if (!test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
- CX18_DEBUG_INFO("EOS %s\n", s->name);
- return NULL;
- }
-
- /* return if file was opened with O_NONBLOCK */
- if (non_block) {
- *err = -EAGAIN;
- return NULL;
- }
-
- /* wait for more data to arrive */
- prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
- /* New buffers might have become available before we were added
- to the waitqueue */
- if (!atomic_read(&s->q_full.depth))
- schedule();
- finish_wait(&s->waitq, &wait);
- if (signal_pending(current)) {
- /* return if a signal was received */
- CX18_DEBUG_INFO("User stopped %s\n", s->name);
- *err = -EINTR;
- return NULL;
- }
- }
-}
-
-static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx)
-{
- struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl;
- struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf;
- int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
-
- buf->buf = cx->vbi.sliced_mpeg_data[idx];
- buf->bytesused = cx->vbi.sliced_mpeg_size[idx];
- buf->readpos = 0;
-
- mdl->curr_buf = NULL;
- mdl->bytesused = cx->vbi.sliced_mpeg_size[idx];
- mdl->readpos = 0;
-}
-
-static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
- struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop)
-{
- struct cx18 *cx = s->cx;
- size_t len = buf->bytesused - buf->readpos;
-
- *stop = false;
- if (len > ucount)
- len = ucount;
- if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
- !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
- /*
- * Try to find a good splice point in the PS, just before
- * an MPEG-2 Program Pack start code, and provide only
- * up to that point to the user, so it's easy to insert VBI data
- * the next time around.
- *
- * This will not work for an MPEG-2 TS and has only been
- * verified by analysis to work for an MPEG-2 PS. Helen Buus
- * pointed out this works for the CX23416 MPEG-2 DVD compatible
- * stream, and research indicates both the MPEG 2 SVCD and DVD
- * stream types use an MPEG-2 PS container.
- */
- /*
- * An MPEG-2 Program Stream (PS) is a series of
- * MPEG-2 Program Packs terminated by an
- * MPEG Program End Code after the last Program Pack.
- * A Program Pack may hold a PS System Header packet and any
- * number of Program Elementary Stream (PES) Packets
- */
- const char *start = buf->buf + buf->readpos;
- const char *p = start + 1;
- const u8 *q;
- u8 ch = cx->search_pack_header ? 0xba : 0xe0;
- int stuffing, i;
-
- while (start + len > p) {
- /* Scan for a 0 to find a potential MPEG-2 start code */
- q = memchr(p, 0, start + len - p);
- if (q == NULL)
- break;
- p = q + 1;
- /*
- * Keep looking if not a
- * MPEG-2 Pack header start code: 0x00 0x00 0x01 0xba
- * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0
- */
- if ((char *)q + 15 >= buf->buf + buf->bytesused ||
- q[1] != 0 || q[2] != 1 || q[3] != ch)
- continue;
-
- /* If expecting the primary video PES */
- if (!cx->search_pack_header) {
- /* Continue if it couldn't be a PES packet */
- if ((q[6] & 0xc0) != 0x80)
- continue;
- /* Check if a PTS or PTS & DTS follow */
- if (((q[7] & 0xc0) == 0x80 && /* PTS only */
- (q[9] & 0xf0) == 0x20) || /* PTS only */
- ((q[7] & 0xc0) == 0xc0 && /* PTS & DTS */
- (q[9] & 0xf0) == 0x30)) { /* DTS follows */
- /* Assume we found the video PES hdr */
- ch = 0xba; /* next want a Program Pack*/
- cx->search_pack_header = 1;
- p = q + 9; /* Skip this video PES hdr */
- }
- continue;
- }
-
- /* We may have found a Program Pack start code */
-
- /* Get the count of stuffing bytes & verify them */
- stuffing = q[13] & 7;
- /* all stuffing bytes must be 0xff */
- for (i = 0; i < stuffing; i++)
- if (q[14 + i] != 0xff)
- break;
- if (i == stuffing && /* right number of stuffing bytes*/
- (q[4] & 0xc4) == 0x44 && /* marker check */
- (q[12] & 3) == 3 && /* marker check */
- q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */
- q[15 + stuffing] == 0 &&
- q[16 + stuffing] == 1) {
- /* We declare we actually found a Program Pack*/
- cx->search_pack_header = 0; /* expect vid PES */
- len = (char *)q - start;
- cx18_setup_sliced_vbi_mdl(cx);
- *stop = true;
- break;
- }
- }
- }
- if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {
- CX18_DEBUG_WARN("copy %zd bytes to user failed for %s\n",
- len, s->name);
- return -EFAULT;
- }
- buf->readpos += len;
- if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
- buf != &cx->vbi.sliced_mpeg_buf)
- cx->mpg_data_received += len;
- return len;
-}
-
-static size_t cx18_copy_mdl_to_user(struct cx18_stream *s,
- struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
-{
- size_t tot_written = 0;
- int rc;
- bool stop = false;
-
- if (mdl->curr_buf == NULL)
- mdl->curr_buf = list_first_entry(&mdl->buf_list,
- struct cx18_buffer, list);
-
- if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
- /*
- * For some reason we've exhausted the buffers, but the MDL
- * object still said some data was unread.
- * Fix that and bail out.
- */
- mdl->readpos = mdl->bytesused;
- return 0;
- }
-
- list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
-
- if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
- continue;
-
- rc = cx18_copy_buf_to_user(s, mdl->curr_buf, ubuf + tot_written,
- ucount - tot_written, &stop);
- if (rc < 0)
- return rc;
- mdl->readpos += rc;
- tot_written += rc;
-
- if (stop || /* Forced stopping point for VBI insertion */
- tot_written >= ucount || /* Reader request statisfied */
- mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
- mdl->readpos >= mdl->bytesused) /* MDL buffers drained */
- break;
- }
- return tot_written;
-}
-
-static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
- size_t tot_count, int non_block)
-{
- struct cx18 *cx = s->cx;
- size_t tot_written = 0;
- int single_frame = 0;
-
- if (atomic_read(&cx->ana_capturing) == 0 && s->id == -1) {
- /* shouldn't happen */
- CX18_DEBUG_WARN("Stream %s not initialized before read\n",
- s->name);
- return -EIO;
- }
-
- /* Each VBI buffer is one frame, the v4l2 API says that for VBI the
- frames should arrive one-by-one, so make sure we never output more
- than one VBI frame at a time */
- if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx))
- single_frame = 1;
-
- for (;;) {
- struct cx18_mdl *mdl;
- int rc;
-
- mdl = cx18_get_mdl(s, non_block, &rc);
- /* if there is no data available... */
- if (mdl == NULL) {
- /* if we got data, then return that regardless */
- if (tot_written)
- break;
- /* EOS condition */
- if (rc == 0) {
- clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
- clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
- cx18_release_stream(s);
- }
- /* set errno */
- return rc;
- }
-
- rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written,
- tot_count - tot_written);
-
- if (mdl != &cx->vbi.sliced_mpeg_mdl) {
- if (mdl->readpos == mdl->bytesused)
- cx18_stream_put_mdl_fw(s, mdl);
- else
- cx18_push(s, mdl, &s->q_full);
- } else if (mdl->readpos == mdl->bytesused) {
- int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
-
- cx->vbi.sliced_mpeg_size[idx] = 0;
- cx->vbi.inserted_frame++;
- cx->vbi_data_inserted += mdl->bytesused;
- }
- if (rc < 0)
- return rc;
- tot_written += rc;
-
- if (tot_written == tot_count || single_frame)
- break;
- }
- return tot_written;
-}
-
-static ssize_t cx18_read_pos(struct cx18_stream *s, char __user *ubuf,
- size_t count, loff_t *pos, int non_block)
-{
- ssize_t rc = count ? cx18_read(s, ubuf, count, non_block) : 0;
- struct cx18 *cx = s->cx;
-
- CX18_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);
- if (rc > 0)
- pos += rc;
- return rc;
-}
-
-int cx18_start_capture(struct cx18_open_id *id)
-{
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
- struct cx18_stream *s_vbi;
- struct cx18_stream *s_idx;
-
- if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
- /* you cannot read from these stream types. */
- return -EPERM;
- }
-
- /* Try to claim this stream. */
- if (cx18_claim_stream(id, s->type))
- return -EBUSY;
-
- /* If capture is already in progress, then we also have to
- do nothing extra. */
- if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
- test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
- set_bit(CX18_F_S_APPL_IO, &s->s_flags);
- return 0;
- }
-
- /* Start associated VBI or IDX stream capture if required */
- s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
- s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
- if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
- /*
- * The VBI and IDX streams should have been claimed
- * automatically, if for internal use, when the MPG stream was
- * claimed. We only need to start these streams capturing.
- */
- if (test_bit(CX18_F_S_INTERNAL_USE, &s_idx->s_flags) &&
- !test_and_set_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
- if (cx18_start_v4l2_encode_stream(s_idx)) {
- CX18_DEBUG_WARN("IDX capture start failed\n");
- clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
- goto start_failed;
- }
- CX18_DEBUG_INFO("IDX capture started\n");
- }
- if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
- !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
- if (cx18_start_v4l2_encode_stream(s_vbi)) {
- CX18_DEBUG_WARN("VBI capture start failed\n");
- clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
- goto start_failed;
- }
- CX18_DEBUG_INFO("VBI insertion started\n");
- }
- }
-
- /* Tell the card to start capturing */
- if (!cx18_start_v4l2_encode_stream(s)) {
- /* We're done */
- set_bit(CX18_F_S_APPL_IO, &s->s_flags);
- /* Resume a possibly paused encoder */
- if (test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
- cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, s->handle);
- return 0;
- }
-
-start_failed:
- CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
-
- /*
- * The associated VBI and IDX streams for internal use are released
- * automatically when the MPG stream is released. We only need to stop
- * the associated stream.
- */
- if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
- /* Stop the IDX stream which is always for internal use */
- if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
- cx18_stop_v4l2_encode_stream(s_idx, 0);
- clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
- }
- /* Stop the VBI stream, if only running for internal use */
- if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
- !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
- cx18_stop_v4l2_encode_stream(s_vbi, 0);
- clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
- }
- }
- clear_bit(CX18_F_S_STREAMING, &s->s_flags);
- cx18_release_stream(s); /* Also releases associated streams */
- return -EIO;
-}
-
-ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
- loff_t *pos)
-{
- struct cx18_open_id *id = file2id(filp);
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
- int rc;
-
- CX18_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
-
- mutex_lock(&cx->serialize_lock);
- rc = cx18_start_capture(id);
- mutex_unlock(&cx->serialize_lock);
- if (rc)
- return rc;
-
- if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
- return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0,
- filp->f_flags & O_NONBLOCK);
- }
-
- return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
-}
-
-unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
-{
- struct cx18_open_id *id = file2id(filp);
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
- int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
-
- /* Start a capture if there is none */
- if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
- int rc;
-
- mutex_lock(&cx->serialize_lock);
- rc = cx18_start_capture(id);
- mutex_unlock(&cx->serialize_lock);
- if (rc) {
- CX18_DEBUG_INFO("Could not start capture for %s (%d)\n",
- s->name, rc);
- return POLLERR;
- }
- CX18_DEBUG_FILE("Encoder poll started capture\n");
- }
-
- if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
- int videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait);
- if (eof && videobuf_poll == POLLERR)
- return POLLHUP;
- else
- return videobuf_poll;
- }
-
- /* add stream's waitq to the poll list */
- CX18_DEBUG_HI_FILE("Encoder poll\n");
- poll_wait(filp, &s->waitq, wait);
-
- if (atomic_read(&s->q_full.depth))
- return POLLIN | POLLRDNORM;
- if (eof)
- return POLLHUP;
- return 0;
-}
-
-int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct cx18_open_id *id = file->private_data;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
- int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
-
- if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
-
- /* Start a capture if there is none */
- if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
- int rc;
-
- mutex_lock(&cx->serialize_lock);
- rc = cx18_start_capture(id);
- mutex_unlock(&cx->serialize_lock);
- if (rc) {
- CX18_DEBUG_INFO(
- "Could not start capture for %s (%d)\n",
- s->name, rc);
- return -EINVAL;
- }
- CX18_DEBUG_FILE("Encoder mmap started capture\n");
- }
-
- return videobuf_mmap_mapper(&s->vbuf_q, vma);
- }
-
- return -EINVAL;
-}
-
-void cx18_vb_timeout(unsigned long data)
-{
- struct cx18_stream *s = (struct cx18_stream *)data;
- struct cx18_videobuf_buffer *buf;
- unsigned long flags;
-
- /* Return all of the buffers in error state, so the vbi/vid inode
- * can return from blocking.
- */
- spin_lock_irqsave(&s->vb_lock, flags);
- while (!list_empty(&s->vb_capture)) {
- buf = list_entry(s->vb_capture.next,
- struct cx18_videobuf_buffer, vb.queue);
- list_del(&buf->vb.queue);
- buf->vb.state = VIDEOBUF_ERROR;
- wake_up(&buf->vb.done);
- }
- spin_unlock_irqrestore(&s->vb_lock, flags);
-}
-
-void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
-{
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
- struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
- struct cx18_stream *s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
-
- CX18_DEBUG_IOCTL("close() of %s\n", s->name);
-
- /* 'Unclaim' this stream */
-
- /* Stop capturing */
- if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
- CX18_DEBUG_INFO("close stopping capture\n");
- if (id->type == CX18_ENC_STREAM_TYPE_MPG) {
- /* Stop internal use associated VBI and IDX streams */
- if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
- !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
- CX18_DEBUG_INFO("close stopping embedded VBI "
- "capture\n");
- cx18_stop_v4l2_encode_stream(s_vbi, 0);
- }
- if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
- CX18_DEBUG_INFO("close stopping IDX capture\n");
- cx18_stop_v4l2_encode_stream(s_idx, 0);
- }
- }
- if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
- test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
- /* Also used internally, don't stop capturing */
- s->id = -1;
- else
- cx18_stop_v4l2_encode_stream(s, gop_end);
- }
- if (!gop_end) {
- clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
- clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
- cx18_release_stream(s);
- }
-}
-
-int cx18_v4l2_close(struct file *filp)
-{
- struct v4l2_fh *fh = filp->private_data;
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- CX18_DEBUG_IOCTL("close() of %s\n", s->name);
-
- mutex_lock(&cx->serialize_lock);
- /* Stop radio */
- if (id->type == CX18_ENC_STREAM_TYPE_RAD &&
- v4l2_fh_is_singular_file(filp)) {
- /* Closing radio device, return to TV mode */
- cx18_mute(cx);
- /* Mark that the radio is no longer in use */
- clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
- /* Switch tuner to TV */
- cx18_call_all(cx, core, s_std, cx->std);
- /* Select correct audio input (i.e. TV tuner or Line in) */
- cx18_audio_set_io(cx);
- if (atomic_read(&cx->ana_capturing) > 0) {
- /* Undo video mute */
- cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
- (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute) |
- (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8)));
- }
- /* Done! Unmute and continue. */
- cx18_unmute(cx);
- }
-
- v4l2_fh_del(fh);
- v4l2_fh_exit(fh);
-
- /* 'Unclaim' this stream */
- if (s->id == id->open_id)
- cx18_stop_capture(id, 0);
- kfree(id);
- mutex_unlock(&cx->serialize_lock);
- return 0;
-}
-
-static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
-{
- struct cx18 *cx = s->cx;
- struct cx18_open_id *item;
-
- CX18_DEBUG_FILE("open %s\n", s->name);
-
- /* Allocate memory */
- item = kzalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
- if (NULL == item) {
- CX18_DEBUG_WARN("nomem on v4l2 open\n");
- return -ENOMEM;
- }
- v4l2_fh_init(&item->fh, s->video_dev);
-
- item->cx = cx;
- item->type = s->type;
-
- item->open_id = cx->open_id++;
- filp->private_data = &item->fh;
- v4l2_fh_add(&item->fh);
-
- if (item->type == CX18_ENC_STREAM_TYPE_RAD &&
- v4l2_fh_is_singular_file(filp)) {
- if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
- if (atomic_read(&cx->ana_capturing) > 0) {
- /* switching to radio while capture is
- in progress is not polite */
- v4l2_fh_del(&item->fh);
- v4l2_fh_exit(&item->fh);
- kfree(item);
- return -EBUSY;
- }
- }
-
- /* Mark that the radio is being used. */
- set_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
- /* We have the radio */
- cx18_mute(cx);
- /* Switch tuner to radio */
- cx18_call_all(cx, tuner, s_radio);
- /* Select the correct audio input (i.e. radio tuner) */
- cx18_audio_set_io(cx);
- /* Done! Unmute and continue. */
- cx18_unmute(cx);
- }
- return 0;
-}
-
-int cx18_v4l2_open(struct file *filp)
-{
- int res;
- struct video_device *video_dev = video_devdata(filp);
- struct cx18_stream *s = video_get_drvdata(video_dev);
- struct cx18 *cx = s->cx;
-
- mutex_lock(&cx->serialize_lock);
- if (cx18_init_on_first_open(cx)) {
- CX18_ERR("Failed to initialize on %s\n",
- video_device_node_name(video_dev));
- mutex_unlock(&cx->serialize_lock);
- return -ENXIO;
- }
- res = cx18_serialized_open(s, filp);
- mutex_unlock(&cx->serialize_lock);
- return res;
-}
-
-void cx18_mute(struct cx18 *cx)
-{
- u32 h;
- if (atomic_read(&cx->ana_capturing)) {
- h = cx18_find_handle(cx);
- if (h != CX18_INVALID_TASK_HANDLE)
- cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 1);
- else
- CX18_ERR("Can't find valid task handle for mute\n");
- }
- CX18_DEBUG_INFO("Mute\n");
-}
-
-void cx18_unmute(struct cx18 *cx)
-{
- u32 h;
- if (atomic_read(&cx->ana_capturing)) {
- h = cx18_find_handle(cx);
- if (h != CX18_INVALID_TASK_HANDLE) {
- cx18_msleep_timeout(100, 0);
- cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, h, 12);
- cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 0);
- } else
- CX18_ERR("Can't find valid task handle for unmute\n");
- }
- CX18_DEBUG_INFO("Unmute\n");
-}
diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h
deleted file mode 100644
index b9e5110ad04..00000000000
--- a/drivers/media/video/cx18/cx18-fileops.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * cx18 file operation functions
- *
- * Derived from ivtv-fileops.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-/* Testing/Debugging */
-int cx18_v4l2_open(struct file *filp);
-ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
- loff_t *pos);
-ssize_t cx18_v4l2_write(struct file *filp, const char __user *buf, size_t count,
- loff_t *pos);
-int cx18_v4l2_close(struct file *filp);
-unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait);
-int cx18_start_capture(struct cx18_open_id *id);
-void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
-void cx18_mute(struct cx18 *cx);
-void cx18_unmute(struct cx18 *cx);
-int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma);
-void cx18_vb_timeout(unsigned long data);
-
-/* Shared with cx18-alsa module */
-int cx18_claim_stream(struct cx18_open_id *id, int type);
-void cx18_release_stream(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c
deleted file mode 100644
index b85c292a849..00000000000
--- a/drivers/media/video/cx18/cx18-firmware.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * cx18 firmware functions
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-scb.h"
-#include "cx18-irq.h"
-#include "cx18-firmware.h"
-#include "cx18-cards.h"
-#include <linux/firmware.h>
-
-#define CX18_PROC_SOFT_RESET 0xc70010
-#define CX18_DDR_SOFT_RESET 0xc70014
-#define CX18_CLOCK_SELECT1 0xc71000
-#define CX18_CLOCK_SELECT2 0xc71004
-#define CX18_HALF_CLOCK_SELECT1 0xc71008
-#define CX18_HALF_CLOCK_SELECT2 0xc7100C
-#define CX18_CLOCK_POLARITY1 0xc71010
-#define CX18_CLOCK_POLARITY2 0xc71014
-#define CX18_ADD_DELAY_ENABLE1 0xc71018
-#define CX18_ADD_DELAY_ENABLE2 0xc7101C
-#define CX18_CLOCK_ENABLE1 0xc71020
-#define CX18_CLOCK_ENABLE2 0xc71024
-
-#define CX18_REG_BUS_TIMEOUT_EN 0xc72024
-
-#define CX18_FAST_CLOCK_PLL_INT 0xc78000
-#define CX18_FAST_CLOCK_PLL_FRAC 0xc78004
-#define CX18_FAST_CLOCK_PLL_POST 0xc78008
-#define CX18_FAST_CLOCK_PLL_PRESCALE 0xc7800C
-#define CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH 0xc78010
-
-#define CX18_SLOW_CLOCK_PLL_INT 0xc78014
-#define CX18_SLOW_CLOCK_PLL_FRAC 0xc78018
-#define CX18_SLOW_CLOCK_PLL_POST 0xc7801C
-#define CX18_MPEG_CLOCK_PLL_INT 0xc78040
-#define CX18_MPEG_CLOCK_PLL_FRAC 0xc78044
-#define CX18_MPEG_CLOCK_PLL_POST 0xc78048
-#define CX18_PLL_POWER_DOWN 0xc78088
-#define CX18_SW1_INT_STATUS 0xc73104
-#define CX18_SW1_INT_ENABLE_PCI 0xc7311C
-#define CX18_SW2_INT_SET 0xc73140
-#define CX18_SW2_INT_STATUS 0xc73144
-#define CX18_ADEC_CONTROL 0xc78120
-
-#define CX18_DDR_REQUEST_ENABLE 0xc80000
-#define CX18_DDR_CHIP_CONFIG 0xc80004
-#define CX18_DDR_REFRESH 0xc80008
-#define CX18_DDR_TIMING1 0xc8000C
-#define CX18_DDR_TIMING2 0xc80010
-#define CX18_DDR_POWER_REG 0xc8001C
-
-#define CX18_DDR_TUNE_LANE 0xc80048
-#define CX18_DDR_INITIAL_EMRS 0xc80054
-#define CX18_DDR_MB_PER_ROW_7 0xc8009C
-#define CX18_DDR_BASE_63_ADDR 0xc804FC
-
-#define CX18_WMB_CLIENT02 0xc90108
-#define CX18_WMB_CLIENT05 0xc90114
-#define CX18_WMB_CLIENT06 0xc90118
-#define CX18_WMB_CLIENT07 0xc9011C
-#define CX18_WMB_CLIENT08 0xc90120
-#define CX18_WMB_CLIENT09 0xc90124
-#define CX18_WMB_CLIENT10 0xc90128
-#define CX18_WMB_CLIENT11 0xc9012C
-#define CX18_WMB_CLIENT12 0xc90130
-#define CX18_WMB_CLIENT13 0xc90134
-#define CX18_WMB_CLIENT14 0xc90138
-
-#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
-
-#define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */
-#define APU_ROM_SYNC2 0x72646548 /* "rdeH" */
-
-struct cx18_apu_rom_seghdr {
- u32 sync1;
- u32 sync2;
- u32 addr;
- u32 size;
-};
-
-static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
-{
- const struct firmware *fw = NULL;
- int i, j;
- unsigned size;
- u32 __iomem *dst = (u32 __iomem *)mem;
- const u32 *src;
-
- if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
- CX18_ERR("Unable to open firmware %s\n", fn);
- CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
- return -ENOMEM;
- }
-
- src = (const u32 *)fw->data;
-
- for (i = 0; i < fw->size; i += 4096) {
- cx18_setup_page(cx, i);
- for (j = i; j < fw->size && j < i + 4096; j += 4) {
- /* no need for endianness conversion on the ppc */
- cx18_raw_writel(cx, *src, dst);
- if (cx18_raw_readl(cx, dst) != *src) {
- CX18_ERR("Mismatch at offset %x\n", i);
- release_firmware(fw);
- cx18_setup_page(cx, 0);
- return -EIO;
- }
- dst++;
- src++;
- }
- }
- if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
- CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
- size = fw->size;
- release_firmware(fw);
- cx18_setup_page(cx, SCB_OFFSET);
- return size;
-}
-
-static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
- u32 *entry_addr)
-{
- const struct firmware *fw = NULL;
- int i, j;
- unsigned size;
- const u32 *src;
- struct cx18_apu_rom_seghdr seghdr;
- const u8 *vers;
- u32 offset = 0;
- u32 apu_version = 0;
- int sz;
-
- if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
- CX18_ERR("unable to open firmware %s\n", fn);
- CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
- cx18_setup_page(cx, 0);
- return -ENOMEM;
- }
-
- *entry_addr = 0;
- src = (const u32 *)fw->data;
- vers = fw->data + sizeof(seghdr);
- sz = fw->size;
-
- apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
- while (offset + sizeof(seghdr) < fw->size) {
- const u32 *shptr = src + offset / 4;
-
- seghdr.sync1 = le32_to_cpu(shptr[0]);
- seghdr.sync2 = le32_to_cpu(shptr[1]);
- seghdr.addr = le32_to_cpu(shptr[2]);
- seghdr.size = le32_to_cpu(shptr[3]);
-
- offset += sizeof(seghdr);
- if (seghdr.sync1 != APU_ROM_SYNC1 ||
- seghdr.sync2 != APU_ROM_SYNC2) {
- offset += seghdr.size;
- continue;
- }
- CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr,
- seghdr.addr + seghdr.size - 1);
- if (*entry_addr == 0)
- *entry_addr = seghdr.addr;
- if (offset + seghdr.size > sz)
- break;
- for (i = 0; i < seghdr.size; i += 4096) {
- cx18_setup_page(cx, seghdr.addr + i);
- for (j = i; j < seghdr.size && j < i + 4096; j += 4) {
- /* no need for endianness conversion on the ppc */
- cx18_raw_writel(cx, src[(offset + j) / 4],
- dst + seghdr.addr + j);
- if (cx18_raw_readl(cx, dst + seghdr.addr + j)
- != src[(offset + j) / 4]) {
- CX18_ERR("Mismatch at offset %x\n",
- offset + j);
- release_firmware(fw);
- cx18_setup_page(cx, 0);
- return -EIO;
- }
- }
- }
- offset += seghdr.size;
- }
- if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
- CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
- fn, apu_version, fw->size);
- size = fw->size;
- release_firmware(fw);
- cx18_setup_page(cx, 0);
- return size;
-}
-
-void cx18_halt_firmware(struct cx18 *cx)
-{
- CX18_DEBUG_INFO("Preparing for firmware halt.\n");
- cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
- 0x0000000F, 0x000F000F);
- cx18_write_reg_expect(cx, 0x00020002, CX18_ADEC_CONTROL,
- 0x00000002, 0x00020002);
-}
-
-void cx18_init_power(struct cx18 *cx, int lowpwr)
-{
- /* power-down Spare and AOM PLLs */
- /* power-up fast, slow and mpeg PLLs */
- cx18_write_reg(cx, 0x00000008, CX18_PLL_POWER_DOWN);
-
- /* ADEC out of sleep */
- cx18_write_reg_expect(cx, 0x00020000, CX18_ADEC_CONTROL,
- 0x00000000, 0x00020002);
-
- /*
- * The PLL parameters are based on the external crystal frequency that
- * would ideally be:
- *
- * NTSC Color subcarrier freq * 8 =
- * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
- *
- * The accidents of history and rationale that explain from where this
- * combination of magic numbers originate can be found in:
- *
- * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in
- * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80
- *
- * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the
- * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83
- *
- * As Mike Bradley has rightly pointed out, it's not the exact crystal
- * frequency that matters, only that all parts of the driver and
- * firmware are using the same value (close to the ideal value).
- *
- * Since I have a strong suspicion that, if the firmware ever assumes a
- * crystal value at all, it will assume 28.636360 MHz, the crystal
- * freq used in calculations in this driver will be:
- *
- * xtal_freq = 28.636360 MHz
- *
- * an error of less than 0.13 ppm which is way, way better than any off
- * the shelf crystal will have for accuracy anyway.
- *
- * Below I aim to run the PLLs' VCOs near 400 MHz to minimze errors.
- *
- * Many thanks to Jeff Campbell and Mike Bradley for their extensive
- * investigation, experimentation, testing, and suggested solutions of
- * of audio/video sync problems with SVideo and CVBS captures.
- */
-
- /* the fast clock is at 200/245 MHz */
- /* 1 * xtal_freq * 0x0d.f7df9b8 / 2 = 200 MHz: 400 MHz pre post-divide*/
- /* 1 * xtal_freq * 0x11.1c71eb8 / 2 = 245 MHz: 490 MHz pre post-divide*/
- cx18_write_reg(cx, lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT);
- cx18_write_reg(cx, lowpwr ? 0x1EFBF37 : 0x038E3D7,
- CX18_FAST_CLOCK_PLL_FRAC);
-
- cx18_write_reg(cx, 2, CX18_FAST_CLOCK_PLL_POST);
- cx18_write_reg(cx, 1, CX18_FAST_CLOCK_PLL_PRESCALE);
- cx18_write_reg(cx, 4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH);
-
- /* set slow clock to 125/120 MHz */
- /* xtal_freq * 0x0d.1861a20 / 3 = 125 MHz: 375 MHz before post-divide */
- /* xtal_freq * 0x0c.92493f8 / 3 = 120 MHz: 360 MHz before post-divide */
- cx18_write_reg(cx, lowpwr ? 0xD : 0xC, CX18_SLOW_CLOCK_PLL_INT);
- cx18_write_reg(cx, lowpwr ? 0x30C344 : 0x124927F,
- CX18_SLOW_CLOCK_PLL_FRAC);
- cx18_write_reg(cx, 3, CX18_SLOW_CLOCK_PLL_POST);
-
- /* mpeg clock pll 54MHz */
- /* xtal_freq * 0xf.15f17f0 / 8 = 54 MHz: 432 MHz before post-divide */
- cx18_write_reg(cx, 0xF, CX18_MPEG_CLOCK_PLL_INT);
- cx18_write_reg(cx, 0x2BE2FE, CX18_MPEG_CLOCK_PLL_FRAC);
- cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST);
-
- /* Defaults */
- /* APU = SC or SC/2 = 125/62.5 */
- /* EPU = SC = 125 */
- /* DDR = FC = 180 */
- /* ENC = SC = 125 */
- /* AI1 = SC = 125 */
- /* VIM2 = disabled */
- /* PCI = FC/2 = 90 */
- /* AI2 = disabled */
- /* DEMUX = disabled */
- /* AO = SC/2 = 62.5 */
- /* SER = 54MHz */
- /* VFC = disabled */
- /* USB = disabled */
-
- if (lowpwr) {
- cx18_write_reg_expect(cx, 0xFFFF0020, CX18_CLOCK_SELECT1,
- 0x00000020, 0xFFFFFFFF);
- cx18_write_reg_expect(cx, 0xFFFF0004, CX18_CLOCK_SELECT2,
- 0x00000004, 0xFFFFFFFF);
- } else {
- /* This doesn't explicitly set every clock select */
- cx18_write_reg_expect(cx, 0x00060004, CX18_CLOCK_SELECT1,
- 0x00000004, 0x00060006);
- cx18_write_reg_expect(cx, 0x00060006, CX18_CLOCK_SELECT2,
- 0x00000006, 0x00060006);
- }
-
- cx18_write_reg_expect(cx, 0xFFFF0002, CX18_HALF_CLOCK_SELECT1,
- 0x00000002, 0xFFFFFFFF);
- cx18_write_reg_expect(cx, 0xFFFF0104, CX18_HALF_CLOCK_SELECT2,
- 0x00000104, 0xFFFFFFFF);
- cx18_write_reg_expect(cx, 0xFFFF9026, CX18_CLOCK_ENABLE1,
- 0x00009026, 0xFFFFFFFF);
- cx18_write_reg_expect(cx, 0xFFFF3105, CX18_CLOCK_ENABLE2,
- 0x00003105, 0xFFFFFFFF);
-}
-
-void cx18_init_memory(struct cx18 *cx)
-{
- cx18_msleep_timeout(10, 0);
- cx18_write_reg_expect(cx, 0x00010000, CX18_DDR_SOFT_RESET,
- 0x00000000, 0x00010001);
- cx18_msleep_timeout(10, 0);
-
- cx18_write_reg(cx, cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG);
-
- cx18_msleep_timeout(10, 0);
-
- cx18_write_reg(cx, cx->card->ddr.refresh, CX18_DDR_REFRESH);
- cx18_write_reg(cx, cx->card->ddr.timing1, CX18_DDR_TIMING1);
- cx18_write_reg(cx, cx->card->ddr.timing2, CX18_DDR_TIMING2);
-
- cx18_msleep_timeout(10, 0);
-
- /* Initialize DQS pad time */
- cx18_write_reg(cx, cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE);
- cx18_write_reg(cx, cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS);
-
- cx18_msleep_timeout(10, 0);
-
- cx18_write_reg_expect(cx, 0x00020000, CX18_DDR_SOFT_RESET,
- 0x00000000, 0x00020002);
- cx18_msleep_timeout(10, 0);
-
- /* use power-down mode when idle */
- cx18_write_reg(cx, 0x00000010, CX18_DDR_POWER_REG);
-
- cx18_write_reg_expect(cx, 0x00010001, CX18_REG_BUS_TIMEOUT_EN,
- 0x00000001, 0x00010001);
-
- cx18_write_reg(cx, 0x48, CX18_DDR_MB_PER_ROW_7);
- cx18_write_reg(cx, 0xE0000, CX18_DDR_BASE_63_ADDR);
-
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT02); /* AO */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT09); /* AI2 */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT05); /* VIM1 */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT06); /* AI1 */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT07); /* 3D comb */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT10); /* ME */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT12); /* ENC */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT13); /* PK */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT11); /* RC */
- cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT14); /* AVO */
-}
-
-int cx18_firmware_init(struct cx18 *cx)
-{
- u32 fw_entry_addr;
- int sz, retries;
- u32 api_args[MAX_MB_ARGUMENTS];
-
- /* Allow chip to control CLKRUN */
- cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK);
-
- /* Stop the firmware */
- cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
- 0x0000000F, 0x000F000F);
-
- cx18_msleep_timeout(1, 0);
-
- /* If the CPU is still running */
- if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) == 0) {
- CX18_ERR("%s: couldn't stop CPU to load firmware\n", __func__);
- return -EIO;
- }
-
- cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
- cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
-
- sz = load_cpu_fw_direct("v4l-cx23418-cpu.fw", cx->enc_mem, cx);
- if (sz <= 0)
- return sz;
-
- /* The SCB & IPC area *must* be correct before starting the firmwares */
- cx18_init_scb(cx);
-
- fw_entry_addr = 0;
- sz = load_apu_fw_direct("v4l-cx23418-apu.fw", cx->enc_mem, cx,
- &fw_entry_addr);
- if (sz <= 0)
- return sz;
-
- /* Start the CPU. The CPU will take care of the APU for us. */
- cx18_write_reg_expect(cx, 0x00080000, CX18_PROC_SOFT_RESET,
- 0x00000000, 0x00080008);
-
- /* Wait up to 500 ms for the APU to come out of reset */
- for (retries = 0;
- retries < 50 && (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1;
- retries++)
- cx18_msleep_timeout(10, 0);
-
- cx18_msleep_timeout(200, 0);
-
- if (retries == 50 &&
- (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1) {
- CX18_ERR("Could not start the CPU\n");
- return -EIO;
- }
-
- /*
- * The CPU had once before set up to receive an interrupt for it's
- * outgoing IRQ_CPU_TO_EPU_ACK to us. If it ever does this, we get an
- * interrupt when it sends us an ack, but by the time we process it,
- * that flag in the SW2 status register has been cleared by the CPU
- * firmware. We'll prevent that not so useful condition from happening
- * by clearing the CPU's interrupt enables for Ack IRQ's we want to
- * process.
- */
- cx18_sw2_irq_disable_cpu(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
-
- /* Try a benign command to see if the CPU is alive and well */
- sz = cx18_vapi_result(cx, api_args, CX18_CPU_DEBUG_PEEK32, 1, 0);
- if (sz < 0)
- return sz;
-
- /* initialize GPIO */
- cx18_write_reg_expect(cx, 0x14001400, 0xc78110, 0x00001400, 0x14001400);
- return 0;
-}
diff --git a/drivers/media/video/cx18/cx18-firmware.h b/drivers/media/video/cx18/cx18-firmware.h
deleted file mode 100644
index 38d4c05e849..00000000000
--- a/drivers/media/video/cx18/cx18-firmware.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * cx18 firmware functions
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-int cx18_firmware_init(struct cx18 *cx);
-void cx18_halt_firmware(struct cx18 *cx);
-void cx18_init_memory(struct cx18 *cx);
-void cx18_init_power(struct cx18 *cx, int lowpwr);
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
deleted file mode 100644
index 5374aeb0cd2..00000000000
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * cx18 gpio functions
- *
- * Derived from ivtv-gpio.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-cards.h"
-#include "cx18-gpio.h"
-#include "tuner-xc2028.h"
-
-/********************* GPIO stuffs *********************/
-
-/* GPIO registers */
-#define CX18_REG_GPIO_IN 0xc72010
-#define CX18_REG_GPIO_OUT1 0xc78100
-#define CX18_REG_GPIO_DIR1 0xc78108
-#define CX18_REG_GPIO_OUT2 0xc78104
-#define CX18_REG_GPIO_DIR2 0xc7810c
-
-/*
- * HVR-1600 GPIO pins, courtesy of Hauppauge:
- *
- * gpio0: zilog ir process reset pin
- * gpio1: zilog programming pin (you should never use this)
- * gpio12: cx24227 reset pin
- * gpio13: cs5345 reset pin
-*/
-
-/*
- * File scope utility functions
- */
-static void gpio_write(struct cx18 *cx)
-{
- u32 dir_lo = cx->gpio_dir & 0xffff;
- u32 val_lo = cx->gpio_val & 0xffff;
- u32 dir_hi = cx->gpio_dir >> 16;
- u32 val_hi = cx->gpio_val >> 16;
-
- cx18_write_reg_expect(cx, dir_lo << 16,
- CX18_REG_GPIO_DIR1, ~dir_lo, dir_lo);
- cx18_write_reg_expect(cx, (dir_lo << 16) | val_lo,
- CX18_REG_GPIO_OUT1, val_lo, dir_lo);
- cx18_write_reg_expect(cx, dir_hi << 16,
- CX18_REG_GPIO_DIR2, ~dir_hi, dir_hi);
- cx18_write_reg_expect(cx, (dir_hi << 16) | val_hi,
- CX18_REG_GPIO_OUT2, val_hi, dir_hi);
-}
-
-static void gpio_update(struct cx18 *cx, u32 mask, u32 data)
-{
- if (mask == 0)
- return;
-
- mutex_lock(&cx->gpio_lock);
- cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
- gpio_write(cx);
- mutex_unlock(&cx->gpio_lock);
-}
-
-static void gpio_reset_seq(struct cx18 *cx, u32 active_lo, u32 active_hi,
- unsigned int assert_msecs,
- unsigned int recovery_msecs)
-{
- u32 mask;
-
- mask = active_lo | active_hi;
- if (mask == 0)
- return;
-
- /*
- * Assuming that active_hi and active_lo are a subsets of the bits in
- * gpio_dir. Also assumes that active_lo and active_hi don't overlap
- * in any bit position
- */
-
- /* Assert */
- gpio_update(cx, mask, ~active_lo);
- schedule_timeout_uninterruptible(msecs_to_jiffies(assert_msecs));
-
- /* Deassert */
- gpio_update(cx, mask, ~active_hi);
- schedule_timeout_uninterruptible(msecs_to_jiffies(recovery_msecs));
-}
-
-/*
- * GPIO Multiplexer - logical device
- */
-static int gpiomux_log_status(struct v4l2_subdev *sd)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- mutex_lock(&cx->gpio_lock);
- CX18_INFO_DEV(sd, "GPIO: direction 0x%08x, value 0x%08x\n",
- cx->gpio_dir, cx->gpio_val);
- mutex_unlock(&cx->gpio_lock);
- return 0;
-}
-
-static int gpiomux_s_radio(struct v4l2_subdev *sd)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- /*
- * FIXME - work out the cx->active/audio_input mess - this is
- * intended to handle the switch to radio mode and set the
- * audio routing, but we need to update the state in cx
- */
- gpio_update(cx, cx->card->gpio_audio_input.mask,
- cx->card->gpio_audio_input.radio);
- return 0;
-}
-
-static int gpiomux_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- u32 data;
-
- switch (cx->card->audio_inputs[cx->audio_input].muxer_input) {
- case 1:
- data = cx->card->gpio_audio_input.linein;
- break;
- case 0:
- data = cx->card->gpio_audio_input.tuner;
- break;
- default:
- /*
- * FIXME - work out the cx->active/audio_input mess - this is
- * intended to handle the switch from radio mode and set the
- * audio routing, but we need to update the state in cx
- */
- data = cx->card->gpio_audio_input.tuner;
- break;
- }
- gpio_update(cx, cx->card->gpio_audio_input.mask, data);
- return 0;
-}
-
-static int gpiomux_s_audio_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- u32 data;
-
- switch (input) {
- case 0:
- data = cx->card->gpio_audio_input.tuner;
- break;
- case 1:
- data = cx->card->gpio_audio_input.linein;
- break;
- case 2:
- data = cx->card->gpio_audio_input.radio;
- break;
- default:
- return -EINVAL;
- }
- gpio_update(cx, cx->card->gpio_audio_input.mask, data);
- return 0;
-}
-
-static const struct v4l2_subdev_core_ops gpiomux_core_ops = {
- .log_status = gpiomux_log_status,
- .s_std = gpiomux_s_std,
-};
-
-static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = {
- .s_radio = gpiomux_s_radio,
-};
-
-static const struct v4l2_subdev_audio_ops gpiomux_audio_ops = {
- .s_routing = gpiomux_s_audio_routing,
-};
-
-static const struct v4l2_subdev_ops gpiomux_ops = {
- .core = &gpiomux_core_ops,
- .tuner = &gpiomux_tuner_ops,
- .audio = &gpiomux_audio_ops,
-};
-
-/*
- * GPIO Reset Controller - logical device
- */
-static int resetctrl_log_status(struct v4l2_subdev *sd)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
-
- mutex_lock(&cx->gpio_lock);
- CX18_INFO_DEV(sd, "GPIO: direction 0x%08x, value 0x%08x\n",
- cx->gpio_dir, cx->gpio_val);
- mutex_unlock(&cx->gpio_lock);
- return 0;
-}
-
-static int resetctrl_reset(struct v4l2_subdev *sd, u32 val)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- const struct cx18_gpio_i2c_slave_reset *p;
-
- p = &cx->card->gpio_i2c_slave_reset;
- switch (val) {
- case CX18_GPIO_RESET_I2C:
- gpio_reset_seq(cx, p->active_lo_mask, p->active_hi_mask,
- p->msecs_asserted, p->msecs_recovery);
- break;
- case CX18_GPIO_RESET_Z8F0811:
- /*
- * Assert timing for the Z8F0811 on HVR-1600 boards:
- * 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to
- * initiate
- * 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock
- * cycles (6,601,085 nanoseconds ~= 7 milliseconds)
- * 3. DBG pin must be high before chip exits reset for normal
- * operation. DBG is open drain and hopefully pulled high
- * since we don't normally drive it (GPIO 1?) for the
- * HVR-1600
- * 4. Z8F0811 won't exit reset until RESET is deasserted
- * 5. Zilog comes out of reset, loads reset vector address and
- * executes from there. Required recovery delay unknown.
- */
- gpio_reset_seq(cx, p->ir_reset_mask, 0,
- p->msecs_asserted, p->msecs_recovery);
- break;
- case CX18_GPIO_RESET_XC2028:
- if (cx->card->tuners[0].tuner == TUNER_XC2028)
- gpio_reset_seq(cx, (1 << cx->card->xceive_pin), 0,
- 1, 1);
- break;
- }
- return 0;
-}
-
-static const struct v4l2_subdev_core_ops resetctrl_core_ops = {
- .log_status = resetctrl_log_status,
- .reset = resetctrl_reset,
-};
-
-static const struct v4l2_subdev_ops resetctrl_ops = {
- .core = &resetctrl_core_ops,
-};
-
-/*
- * External entry points
- */
-void cx18_gpio_init(struct cx18 *cx)
-{
- mutex_lock(&cx->gpio_lock);
- cx->gpio_dir = cx->card->gpio_init.direction;
- cx->gpio_val = cx->card->gpio_init.initial_value;
-
- if (cx->card->tuners[0].tuner == TUNER_XC2028) {
- cx->gpio_dir |= 1 << cx->card->xceive_pin;
- cx->gpio_val |= 1 << cx->card->xceive_pin;
- }
-
- if (cx->gpio_dir == 0) {
- mutex_unlock(&cx->gpio_lock);
- return;
- }
-
- CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
- cx18_read_reg(cx, CX18_REG_GPIO_DIR1),
- cx18_read_reg(cx, CX18_REG_GPIO_DIR2),
- cx18_read_reg(cx, CX18_REG_GPIO_OUT1),
- cx18_read_reg(cx, CX18_REG_GPIO_OUT2));
-
- gpio_write(cx);
- mutex_unlock(&cx->gpio_lock);
-}
-
-int cx18_gpio_register(struct cx18 *cx, u32 hw)
-{
- struct v4l2_subdev *sd;
- const struct v4l2_subdev_ops *ops;
- char *str;
-
- switch (hw) {
- case CX18_HW_GPIO_MUX:
- sd = &cx->sd_gpiomux;
- ops = &gpiomux_ops;
- str = "gpio-mux";
- break;
- case CX18_HW_GPIO_RESET_CTRL:
- sd = &cx->sd_resetctrl;
- ops = &resetctrl_ops;
- str = "gpio-reset-ctrl";
- break;
- default:
- return -EINVAL;
- }
-
- v4l2_subdev_init(sd, ops);
- v4l2_set_subdevdata(sd, cx);
- snprintf(sd->name, sizeof(sd->name), "%s %s", cx->v4l2_dev.name, str);
- sd->grp_id = hw;
- return v4l2_device_register_subdev(&cx->v4l2_dev, sd);
-}
-
-void cx18_reset_ir_gpio(void *data)
-{
- struct cx18 *cx = to_cx18((struct v4l2_device *)data);
-
- if (cx->card->gpio_i2c_slave_reset.ir_reset_mask == 0)
- return;
-
- CX18_DEBUG_INFO("Resetting IR microcontroller\n");
-
- v4l2_subdev_call(&cx->sd_resetctrl,
- core, reset, CX18_GPIO_RESET_Z8F0811);
-}
-EXPORT_SYMBOL(cx18_reset_ir_gpio);
-/* This symbol is exported for use by lirc_pvr150 for the IR-blaster */
-
-/* Xceive tuner reset function */
-int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value)
-{
- struct i2c_algo_bit_data *algo = dev;
- struct cx18_i2c_algo_callback_data *cb_data = algo->data;
- struct cx18 *cx = cb_data->cx;
-
- if (cmd != XC2028_TUNER_RESET ||
- cx->card->tuners[0].tuner != TUNER_XC2028)
- return 0;
-
- CX18_DEBUG_INFO("Resetting XCeive tuner\n");
- return v4l2_subdev_call(&cx->sd_resetctrl,
- core, reset, CX18_GPIO_RESET_XC2028);
-}
diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h
deleted file mode 100644
index 4aea2ef88e8..00000000000
--- a/drivers/media/video/cx18/cx18-gpio.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * cx18 gpio functions
- *
- * Derived from ivtv-gpio.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-void cx18_gpio_init(struct cx18 *cx);
-int cx18_gpio_register(struct cx18 *cx, u32 hw);
-
-enum cx18_gpio_reset_type {
- CX18_GPIO_RESET_I2C = 0,
- CX18_GPIO_RESET_Z8F0811 = 1,
- CX18_GPIO_RESET_XC2028 = 2,
-};
-
-void cx18_reset_ir_gpio(void *data);
-int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value);
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
deleted file mode 100644
index 51609d5c88c..00000000000
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * cx18 I2C functions
- *
- * Derived from ivtv-i2c.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-cards.h"
-#include "cx18-gpio.h"
-#include "cx18-i2c.h"
-#include "cx18-irq.h"
-
-#define CX18_REG_I2C_1_WR 0xf15000
-#define CX18_REG_I2C_1_RD 0xf15008
-#define CX18_REG_I2C_2_WR 0xf25100
-#define CX18_REG_I2C_2_RD 0xf25108
-
-#define SETSCL_BIT 0x0001
-#define SETSDL_BIT 0x0002
-#define GETSCL_BIT 0x0004
-#define GETSDL_BIT 0x0008
-
-#define CX18_CS5345_I2C_ADDR 0x4c
-#define CX18_Z8F0811_IR_TX_I2C_ADDR 0x70
-#define CX18_Z8F0811_IR_RX_I2C_ADDR 0x71
-
-/* This array should match the CX18_HW_ defines */
-static const u8 hw_addrs[] = {
- 0, /* CX18_HW_TUNER */
- 0, /* CX18_HW_TVEEPROM */
- CX18_CS5345_I2C_ADDR, /* CX18_HW_CS5345 */
- 0, /* CX18_HW_DVB */
- 0, /* CX18_HW_418_AV */
- 0, /* CX18_HW_GPIO_MUX */
- 0, /* CX18_HW_GPIO_RESET_CTRL */
- CX18_Z8F0811_IR_TX_I2C_ADDR, /* CX18_HW_Z8F0811_IR_TX_HAUP */
- CX18_Z8F0811_IR_RX_I2C_ADDR, /* CX18_HW_Z8F0811_IR_RX_HAUP */
-};
-
-/* This array should match the CX18_HW_ defines */
-/* This might well become a card-specific array */
-static const u8 hw_bus[] = {
- 1, /* CX18_HW_TUNER */
- 0, /* CX18_HW_TVEEPROM */
- 0, /* CX18_HW_CS5345 */
- 0, /* CX18_HW_DVB */
- 0, /* CX18_HW_418_AV */
- 0, /* CX18_HW_GPIO_MUX */
- 0, /* CX18_HW_GPIO_RESET_CTRL */
- 0, /* CX18_HW_Z8F0811_IR_TX_HAUP */
- 0, /* CX18_HW_Z8F0811_IR_RX_HAUP */
-};
-
-/* This array should match the CX18_HW_ defines */
-static const char * const hw_devicenames[] = {
- "tuner",
- "tveeprom",
- "cs5345",
- "cx23418_DTV",
- "cx23418_AV",
- "gpio_mux",
- "gpio_reset_ctrl",
- "ir_tx_z8f0811_haup",
- "ir_rx_z8f0811_haup",
-};
-
-static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
- const char *type, u8 addr)
-{
- struct i2c_board_info info;
- struct IR_i2c_init_data *init_data = &cx->ir_i2c_init_data;
- unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, type, I2C_NAME_SIZE);
-
- /* Our default information for ir-kbd-i2c.c to use */
- switch (hw) {
- case CX18_HW_Z8F0811_IR_RX_HAUP:
- init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
- init_data->type = RC_TYPE_RC5;
- init_data->name = cx->card_name;
- info.platform_data = init_data;
- break;
- }
-
- return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
- -1 : 0;
-}
-
-int cx18_i2c_register(struct cx18 *cx, unsigned idx)
-{
- struct v4l2_subdev *sd;
- int bus = hw_bus[idx];
- struct i2c_adapter *adap = &cx->i2c_adap[bus];
- const char *type = hw_devicenames[idx];
- u32 hw = 1 << idx;
-
- if (idx >= ARRAY_SIZE(hw_addrs))
- return -1;
-
- if (hw == CX18_HW_TUNER) {
- /* special tuner group handling */
- sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
- adap, type, 0, cx->card_i2c->radio);
- if (sd != NULL)
- sd->grp_id = hw;
- sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
- adap, type, 0, cx->card_i2c->demod);
- if (sd != NULL)
- sd->grp_id = hw;
- sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
- adap, type, 0, cx->card_i2c->tv);
- if (sd != NULL)
- sd->grp_id = hw;
- return sd != NULL ? 0 : -1;
- }
-
- if (hw & CX18_HW_IR_ANY)
- return cx18_i2c_new_ir(cx, adap, hw, type, hw_addrs[idx]);
-
- /* Is it not an I2C device or one we do not wish to register? */
- if (!hw_addrs[idx])
- return -1;
-
- /* It's an I2C device other than an analog tuner or IR chip */
- sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, type, hw_addrs[idx],
- NULL);
- if (sd != NULL)
- sd->grp_id = hw;
- return sd != NULL ? 0 : -1;
-}
-
-/* Find the first member of the subdev group id in hw */
-struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw)
-{
- struct v4l2_subdev *result = NULL;
- struct v4l2_subdev *sd;
-
- spin_lock(&cx->v4l2_dev.lock);
- v4l2_device_for_each_subdev(sd, &cx->v4l2_dev) {
- if (sd->grp_id == hw) {
- result = sd;
- break;
- }
- }
- spin_unlock(&cx->v4l2_dev.lock);
- return result;
-}
-
-static void cx18_setscl(void *data, int state)
-{
- struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
- int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
- u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
- u32 r = cx18_read_reg(cx, addr);
-
- if (state)
- cx18_write_reg(cx, r | SETSCL_BIT, addr);
- else
- cx18_write_reg(cx, r & ~SETSCL_BIT, addr);
-}
-
-static void cx18_setsda(void *data, int state)
-{
- struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
- int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
- u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
- u32 r = cx18_read_reg(cx, addr);
-
- if (state)
- cx18_write_reg(cx, r | SETSDL_BIT, addr);
- else
- cx18_write_reg(cx, r & ~SETSDL_BIT, addr);
-}
-
-static int cx18_getscl(void *data)
-{
- struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
- int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
- u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
-
- return cx18_read_reg(cx, addr) & GETSCL_BIT;
-}
-
-static int cx18_getsda(void *data)
-{
- struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
- int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
- u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
-
- return cx18_read_reg(cx, addr) & GETSDL_BIT;
-}
-
-/* template for i2c-bit-algo */
-static struct i2c_adapter cx18_i2c_adap_template = {
- .name = "cx18 i2c driver",
- .algo = NULL, /* set by i2c-algo-bit */
- .algo_data = NULL, /* filled from template */
- .owner = THIS_MODULE,
-};
-
-#define CX18_SCL_PERIOD (10) /* usecs. 10 usec is period for a 100 KHz clock */
-#define CX18_ALGO_BIT_TIMEOUT (2) /* seconds */
-
-static struct i2c_algo_bit_data cx18_i2c_algo_template = {
- .setsda = cx18_setsda,
- .setscl = cx18_setscl,
- .getsda = cx18_getsda,
- .getscl = cx18_getscl,
- .udelay = CX18_SCL_PERIOD/2, /* 1/2 clock period in usec*/
- .timeout = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */
-};
-
-/* init + register i2c adapter */
-int init_cx18_i2c(struct cx18 *cx)
-{
- int i, err;
- CX18_DEBUG_I2C("i2c init\n");
-
- for (i = 0; i < 2; i++) {
- /* Setup algorithm for adapter */
- memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template,
- sizeof(struct i2c_algo_bit_data));
- cx->i2c_algo_cb_data[i].cx = cx;
- cx->i2c_algo_cb_data[i].bus_index = i;
- cx->i2c_algo[i].data = &cx->i2c_algo_cb_data[i];
-
- /* Setup adapter */
- memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
- sizeof(struct i2c_adapter));
- cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
- sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name),
- " #%d-%d", cx->instance, i);
- i2c_set_adapdata(&cx->i2c_adap[i], &cx->v4l2_dev);
- cx->i2c_adap[i].dev.parent = &cx->pci_dev->dev;
- }
-
- if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) {
- /* Reset/Unreset I2C hardware block */
- /* Clock select 220MHz */
- cx18_write_reg_expect(cx, 0x10000000, 0xc71004,
- 0x00000000, 0x10001000);
- /* Clock Enable */
- cx18_write_reg_expect(cx, 0x10001000, 0xc71024,
- 0x00001000, 0x10001000);
- }
- /* courtesy of Steven Toth <stoth@hauppauge.com> */
- cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
- mdelay(10);
- cx18_write_reg_expect(cx, 0x00c000c0, 0xc7001c, 0x000000c0, 0x00c000c0);
- mdelay(10);
- cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
- mdelay(10);
-
- /* Set to edge-triggered intrs. */
- cx18_write_reg(cx, 0x00c00000, 0xc730c8);
- /* Clear any stale intrs */
- cx18_write_reg_expect(cx, HW2_I2C1_INT|HW2_I2C2_INT, HW2_INT_CLR_STATUS,
- ~(HW2_I2C1_INT|HW2_I2C2_INT), HW2_I2C1_INT|HW2_I2C2_INT);
-
- /* Hw I2C1 Clock Freq ~100kHz */
- cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR);
- cx18_setscl(&cx->i2c_algo_cb_data[0], 1);
- cx18_setsda(&cx->i2c_algo_cb_data[0], 1);
-
- /* Hw I2C2 Clock Freq ~100kHz */
- cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR);
- cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
- cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
-
- cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
- core, reset, (u32) CX18_GPIO_RESET_I2C);
-
- err = i2c_bit_add_bus(&cx->i2c_adap[0]);
- if (err)
- goto err;
- err = i2c_bit_add_bus(&cx->i2c_adap[1]);
- if (err)
- goto err_del_bus_0;
- return 0;
-
- err_del_bus_0:
- i2c_del_adapter(&cx->i2c_adap[0]);
- err:
- return err;
-}
-
-void exit_cx18_i2c(struct cx18 *cx)
-{
- int i;
- CX18_DEBUG_I2C("i2c exit\n");
- cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_1_WR) | 4,
- CX18_REG_I2C_1_WR);
- cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_2_WR) | 4,
- CX18_REG_I2C_2_WR);
-
- for (i = 0; i < 2; i++) {
- i2c_del_adapter(&cx->i2c_adap[i]);
- }
-}
-
-/*
- Hauppauge HVR1600 should have:
- 32 cx24227
- 98 unknown
- a0 eeprom
- c2 tuner
- e? zilog ir
- */
diff --git a/drivers/media/video/cx18/cx18-i2c.h b/drivers/media/video/cx18/cx18-i2c.h
deleted file mode 100644
index 1180fdc8d98..00000000000
--- a/drivers/media/video/cx18/cx18-i2c.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * cx18 I2C functions
- *
- * Derived from ivtv-i2c.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-int cx18_i2c_register(struct cx18 *cx, unsigned idx);
-struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw);
-
-/* init + register i2c adapter */
-int init_cx18_i2c(struct cx18 *cx);
-void exit_cx18_i2c(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/video/cx18/cx18-io.c
deleted file mode 100644
index 49b9dbd0624..00000000000
--- a/drivers/media/video/cx18/cx18-io.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * cx18 driver PCI memory mapped IO access routines
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-irq.h"
-
-void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count)
-{
- u8 __iomem *dst = addr;
- u16 val2 = val | (val << 8);
- u32 val4 = val2 | (val2 << 16);
-
- /* Align writes on the CX23418's addresses */
- if ((count > 0) && ((unsigned long)dst & 1)) {
- cx18_writeb(cx, (u8) val, dst);
- count--;
- dst++;
- }
- if ((count > 1) && ((unsigned long)dst & 2)) {
- cx18_writew(cx, val2, dst);
- count -= 2;
- dst += 2;
- }
- while (count > 3) {
- cx18_writel(cx, val4, dst);
- count -= 4;
- dst += 4;
- }
- if (count > 1) {
- cx18_writew(cx, val2, dst);
- count -= 2;
- dst += 2;
- }
- if (count > 0)
- cx18_writeb(cx, (u8) val, dst);
-}
-
-void cx18_sw1_irq_enable(struct cx18 *cx, u32 val)
-{
- cx18_write_reg_expect(cx, val, SW1_INT_STATUS, ~val, val);
- cx->sw1_irq_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | val;
- cx18_write_reg(cx, cx->sw1_irq_mask, SW1_INT_ENABLE_PCI);
-}
-
-void cx18_sw1_irq_disable(struct cx18 *cx, u32 val)
-{
- cx->sw1_irq_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) & ~val;
- cx18_write_reg(cx, cx->sw1_irq_mask, SW1_INT_ENABLE_PCI);
-}
-
-void cx18_sw2_irq_enable(struct cx18 *cx, u32 val)
-{
- cx18_write_reg_expect(cx, val, SW2_INT_STATUS, ~val, val);
- cx->sw2_irq_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) | val;
- cx18_write_reg(cx, cx->sw2_irq_mask, SW2_INT_ENABLE_PCI);
-}
-
-void cx18_sw2_irq_disable(struct cx18 *cx, u32 val)
-{
- cx->sw2_irq_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) & ~val;
- cx18_write_reg(cx, cx->sw2_irq_mask, SW2_INT_ENABLE_PCI);
-}
-
-void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val)
-{
- u32 r;
- r = cx18_read_reg(cx, SW2_INT_ENABLE_CPU);
- cx18_write_reg(cx, r & ~val, SW2_INT_ENABLE_CPU);
-}
-
-void cx18_setup_page(struct cx18 *cx, u32 addr)
-{
- u32 val;
- val = cx18_read_reg(cx, 0xD000F8);
- val = (val & ~0x1f00) | ((addr >> 17) & 0x1f00);
- cx18_write_reg(cx, val, 0xD000F8);
-}
diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/video/cx18/cx18-io.h
deleted file mode 100644
index 18974d886cf..00000000000
--- a/drivers/media/video/cx18/cx18-io.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * cx18 driver PCI memory mapped IO access routines
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#ifndef CX18_IO_H
-#define CX18_IO_H
-
-#include "cx18-driver.h"
-
-/*
- * Readback and retry of MMIO access for reliability:
- * The concept was suggested by Steve Toth <stoth@linuxtv.org>.
- * The implmentation is the fault of Andy Walls <awalls@md.metrocast.net>.
- *
- * *write* functions are implied to retry the mmio unless suffixed with _noretry
- * *read* functions never retry the mmio (it never helps to do so)
- */
-
-/* Non byteswapping memory mapped IO */
-static inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr)
-{
- return __raw_readl(addr);
-}
-
-static inline
-void cx18_raw_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
-{
- __raw_writel(val, addr);
-}
-
-static inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr)
-{
- int i;
- for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
- cx18_raw_writel_noretry(cx, val, addr);
- if (val == cx18_raw_readl(cx, addr))
- break;
- }
-}
-
-/* Normal memory mapped IO */
-static inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr)
-{
- return readl(addr);
-}
-
-static inline
-void cx18_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
-{
- writel(val, addr);
-}
-
-static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
-{
- int i;
- for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
- cx18_writel_noretry(cx, val, addr);
- if (val == cx18_readl(cx, addr))
- break;
- }
-}
-
-static inline
-void cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
- u32 eval, u32 mask)
-{
- int i;
- u32 r;
- eval &= mask;
- for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
- cx18_writel_noretry(cx, val, addr);
- r = cx18_readl(cx, addr);
- if (r == 0xffffffff && eval != 0xffffffff)
- continue;
- if (eval == (r & mask))
- break;
- }
-}
-
-static inline u16 cx18_readw(struct cx18 *cx, const void __iomem *addr)
-{
- return readw(addr);
-}
-
-static inline
-void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr)
-{
- writew(val, addr);
-}
-
-static inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr)
-{
- int i;
- for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
- cx18_writew_noretry(cx, val, addr);
- if (val == cx18_readw(cx, addr))
- break;
- }
-}
-
-static inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr)
-{
- return readb(addr);
-}
-
-static inline
-void cx18_writeb_noretry(struct cx18 *cx, u8 val, void __iomem *addr)
-{
- writeb(val, addr);
-}
-
-static inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr)
-{
- int i;
- for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
- cx18_writeb_noretry(cx, val, addr);
- if (val == cx18_readb(cx, addr))
- break;
- }
-}
-
-static inline
-void cx18_memcpy_fromio(struct cx18 *cx, void *to,
- const void __iomem *from, unsigned int len)
-{
- memcpy_fromio(to, from, len);
-}
-
-void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count);
-
-
-/* Access "register" region of CX23418 memory mapped I/O */
-static inline void cx18_write_reg_noretry(struct cx18 *cx, u32 val, u32 reg)
-{
- cx18_writel_noretry(cx, val, cx->reg_mem + reg);
-}
-
-static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg)
-{
- cx18_writel(cx, val, cx->reg_mem + reg);
-}
-
-static inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg,
- u32 eval, u32 mask)
-{
- cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask);
-}
-
-static inline u32 cx18_read_reg(struct cx18 *cx, u32 reg)
-{
- return cx18_readl(cx, cx->reg_mem + reg);
-}
-
-
-/* Access "encoder memory" region of CX23418 memory mapped I/O */
-static inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr)
-{
- cx18_writel(cx, val, cx->enc_mem + addr);
-}
-
-static inline u32 cx18_read_enc(struct cx18 *cx, u32 addr)
-{
- return cx18_readl(cx, cx->enc_mem + addr);
-}
-
-void cx18_sw1_irq_enable(struct cx18 *cx, u32 val);
-void cx18_sw1_irq_disable(struct cx18 *cx, u32 val);
-void cx18_sw2_irq_enable(struct cx18 *cx, u32 val);
-void cx18_sw2_irq_disable(struct cx18 *cx, u32 val);
-void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val);
-void cx18_setup_page(struct cx18 *cx, u32 addr);
-
-#endif /* CX18_IO_H */
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
deleted file mode 100644
index e9912db3b49..00000000000
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ /dev/null
@@ -1,1194 +0,0 @@
-/*
- * cx18 ioctl system call
- *
- * Derived from ivtv-ioctl.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-version.h"
-#include "cx18-mailbox.h"
-#include "cx18-i2c.h"
-#include "cx18-queue.h"
-#include "cx18-fileops.h"
-#include "cx18-vbi.h"
-#include "cx18-audio.h"
-#include "cx18-video.h"
-#include "cx18-streams.h"
-#include "cx18-ioctl.h"
-#include "cx18-gpio.h"
-#include "cx18-controls.h"
-#include "cx18-cards.h"
-#include "cx18-av-core.h"
-#include <media/tveeprom.h>
-#include <media/v4l2-chip-ident.h>
-
-u16 cx18_service2vbi(int type)
-{
- switch (type) {
- case V4L2_SLICED_TELETEXT_B:
- return CX18_SLICED_TYPE_TELETEXT_B;
- case V4L2_SLICED_CAPTION_525:
- return CX18_SLICED_TYPE_CAPTION_525;
- case V4L2_SLICED_WSS_625:
- return CX18_SLICED_TYPE_WSS_625;
- case V4L2_SLICED_VPS:
- return CX18_SLICED_TYPE_VPS;
- default:
- return 0;
- }
-}
-
-/* Check if VBI services are allowed on the (field, line) for the video std */
-static int valid_service_line(int field, int line, int is_pal)
-{
- return (is_pal && line >= 6 &&
- ((field == 0 && line <= 23) || (field == 1 && line <= 22))) ||
- (!is_pal && line >= 10 && line < 22);
-}
-
-/*
- * For a (field, line, std) and inbound potential set of services for that line,
- * return the first valid service of those passed in the incoming set for that
- * line in priority order:
- * CC, VPS, or WSS over TELETEXT for well known lines
- * TELETEXT, before VPS, before CC, before WSS, for other lines
- */
-static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
-{
- u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
- int i;
-
- set = set & valid_set;
- if (set == 0 || !valid_service_line(field, line, is_pal))
- return 0;
- if (!is_pal) {
- if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
- return V4L2_SLICED_CAPTION_525;
- } else {
- if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
- return V4L2_SLICED_VPS;
- if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
- return V4L2_SLICED_WSS_625;
- if (line == 23)
- return 0;
- }
- for (i = 0; i < 32; i++) {
- if ((1 << i) & set)
- return 1 << i;
- }
- return 0;
-}
-
-/*
- * Expand the service_set of *fmt into valid service_lines for the std,
- * and clear the passed in fmt->service_set
- */
-void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
-{
- u16 set = fmt->service_set;
- int f, l;
-
- fmt->service_set = 0;
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++)
- fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
- }
-}
-
-/*
- * Sanitize the service_lines in *fmt per the video std, and return 1
- * if any service_line is left as valid after santization
- */
-static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
-{
- int f, l;
- u16 set = 0;
-
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
- set |= fmt->service_lines[f][l];
- }
- }
- return set != 0;
-}
-
-/* Compute the service_set from the assumed valid service_lines of *fmt */
-u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
-{
- int f, l;
- u16 set = 0;
-
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++)
- set |= fmt->service_lines[f][l];
- }
- return set;
-}
-
-static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
- struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-
- pixfmt->width = cx->cxhdl.width;
- pixfmt->height = cx->cxhdl.height;
- pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
- pixfmt->field = V4L2_FIELD_INTERLACED;
- pixfmt->priv = 0;
- if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
- pixfmt->pixelformat = s->pixelformat;
- pixfmt->sizeimage = s->vb_bytes_per_frame;
- pixfmt->bytesperline = 720;
- } else {
- pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
- pixfmt->sizeimage = 128 * 1024;
- pixfmt->bytesperline = 0;
- }
- return 0;
-}
-
-static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
-
- vbifmt->sampling_rate = 27000000;
- vbifmt->offset = 248; /* FIXME - slightly wrong for both 50 & 60 Hz */
- vbifmt->samples_per_line = vbi_active_samples - 4;
- vbifmt->sample_format = V4L2_PIX_FMT_GREY;
- vbifmt->start[0] = cx->vbi.start[0];
- vbifmt->start[1] = cx->vbi.start[1];
- vbifmt->count[0] = vbifmt->count[1] = cx->vbi.count;
- vbifmt->flags = 0;
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
- return 0;
-}
-
-static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
-
- /* sane, V4L2 spec compliant, defaults */
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
- vbifmt->service_set = 0;
-
- /*
- * Fetch the configured service_lines and total service_set from the
- * digitizer/slicer. Note, cx18_av_vbi() wipes the passed in
- * fmt->fmt.sliced under valid calling conditions
- */
- if (v4l2_subdev_call(cx->sd_av, vbi, g_sliced_fmt, &fmt->fmt.sliced))
- return -EINVAL;
-
- /* Ensure V4L2 spec compliant output */
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- vbifmt->service_set = cx18_get_service_set(vbifmt);
- return 0;
-}
-
-static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
- int w = fmt->fmt.pix.width;
- int h = fmt->fmt.pix.height;
- int min_h = 2;
-
- w = min(w, 720);
- w = max(w, 2);
- if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
- /* YUV height must be a multiple of 32 */
- h &= ~0x1f;
- min_h = 32;
- }
- h = min(h, cx->is_50hz ? 576 : 480);
- h = max(h, min_h);
-
- fmt->fmt.pix.width = w;
- fmt->fmt.pix.height = h;
- return 0;
-}
-
-static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- return cx18_g_fmt_vbi_cap(file, fh, fmt);
-}
-
-static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
-
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
-
- /* If given a service set, expand it validly & clear passed in set */
- if (vbifmt->service_set)
- cx18_expand_service_set(vbifmt, cx->is_50hz);
- /* Sanitize the service_lines, and compute the new set if any valid */
- if (check_service_set(vbifmt, cx->is_50hz))
- vbifmt->service_set = cx18_get_service_set(vbifmt);
- return 0;
-}
-
-static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
- struct v4l2_mbus_framefmt mbus_fmt;
- struct cx18_stream *s = &cx->streams[id->type];
- int ret;
- int w, h;
-
- ret = cx18_try_fmt_vid_cap(file, fh, fmt);
- if (ret)
- return ret;
- w = fmt->fmt.pix.width;
- h = fmt->fmt.pix.height;
-
- if (cx->cxhdl.width == w && cx->cxhdl.height == h &&
- s->pixelformat == fmt->fmt.pix.pixelformat)
- return 0;
-
- if (atomic_read(&cx->ana_capturing) > 0)
- return -EBUSY;
-
- s->pixelformat = fmt->fmt.pix.pixelformat;
- /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
- UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
- if (s->pixelformat == V4L2_PIX_FMT_HM12)
- s->vb_bytes_per_frame = h * 720 * 3 / 2;
- else
- s->vb_bytes_per_frame = h * 720 * 2;
-
- mbus_fmt.width = cx->cxhdl.width = w;
- mbus_fmt.height = cx->cxhdl.height = h;
- mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
- v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt);
- return cx18_g_fmt_vid_cap(file, fh, fmt);
-}
-
-static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
- int ret;
-
- /*
- * Changing the Encoder's Raw VBI parameters won't have any effect
- * if any analog capture is ongoing
- */
- if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
- return -EBUSY;
-
- /*
- * Set the digitizer registers for raw active VBI.
- * Note cx18_av_vbi_wipes out a lot of the passed in fmt under valid
- * calling conditions
- */
- ret = v4l2_subdev_call(cx->sd_av, vbi, s_raw_fmt, &fmt->fmt.vbi);
- if (ret)
- return ret;
-
- /* Store our new v4l2 (non-)sliced VBI state */
- cx->vbi.sliced_in->service_set = 0;
- cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
-
- return cx18_g_fmt_vbi_cap(file, fh, fmt);
-}
-
-static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
- struct v4l2_format *fmt)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
- int ret;
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
-
- cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
-
- /*
- * Changing the Encoder's Raw VBI parameters won't have any effect
- * if any analog capture is ongoing
- */
- if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
- return -EBUSY;
-
- /*
- * Set the service_lines requested in the digitizer/slicer registers.
- * Note, cx18_av_vbi() wipes some "impossible" service lines in the
- * passed in fmt->fmt.sliced under valid calling conditions
- */
- ret = v4l2_subdev_call(cx->sd_av, vbi, s_sliced_fmt, &fmt->fmt.sliced);
- if (ret)
- return ret;
- /* Store our current v4l2 sliced VBI settings */
- cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
- memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
- return 0;
-}
-
-static int cx18_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- int err = 0;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- switch (chip->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- switch (chip->match.addr) {
- case 0:
- chip->ident = V4L2_IDENT_CX23418;
- chip->revision = cx18_read_reg(cx, 0xC72028);
- break;
- case 1:
- /*
- * The A/V decoder is always present, but in the rare
- * case that the card doesn't have analog, we don't
- * use it. We find it w/o using the cx->sd_av pointer
- */
- cx18_call_hw(cx, CX18_HW_418_AV,
- core, g_chip_ident, chip);
- break;
- default:
- /*
- * Could return ident = V4L2_IDENT_UNKNOWN if we had
- * other host chips at higher addresses, but we don't
- */
- err = -EINVAL; /* per V4L2 spec */
- break;
- }
- break;
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
- cx18_call_all(cx, core, g_chip_ident, chip);
- break;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- /*
- * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
- * to look if a chip is at the address with no driver. That's a
- * dangerous thing to do with EEPROMs anyway.
- */
- cx18_call_all(cx, core, g_chip_ident, chip);
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
-{
- struct v4l2_dbg_register *regs = arg;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
- return -EINVAL;
-
- regs->size = 4;
- if (cmd == VIDIOC_DBG_S_REGISTER)
- cx18_write_enc(cx, regs->val, regs->reg);
- else
- regs->val = cx18_read_enc(cx, regs->reg);
- return 0;
-}
-
-static int cx18_g_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- if (v4l2_chip_match_host(&reg->match))
- return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg);
- /* FIXME - errors shouldn't be ignored */
- cx18_call_all(cx, core, g_register, reg);
- return 0;
-}
-
-static int cx18_s_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- if (v4l2_chip_match_host(&reg->match))
- return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg);
- /* FIXME - errors shouldn't be ignored */
- cx18_call_all(cx, core, s_register, reg);
- return 0;
-}
-#endif
-
-static int cx18_querycap(struct file *file, void *fh,
- struct v4l2_capability *vcap)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
-
- strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
- strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
- snprintf(vcap->bus_info, sizeof(vcap->bus_info),
- "PCI:%s", pci_name(cx->pci_dev));
- vcap->capabilities = cx->v4l2_cap; /* capabilities */
- if (id->type == CX18_ENC_STREAM_TYPE_YUV)
- vcap->capabilities |= V4L2_CAP_STREAMING;
- return 0;
-}
-
-static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- return cx18_get_audio_input(cx, vin->index, vin);
-}
-
-static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- vin->index = cx->audio_input;
- return cx18_get_audio_input(cx, vin->index, vin);
-}
-
-static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- if (vout->index >= cx->nof_audio_inputs)
- return -EINVAL;
- cx->audio_input = vout->index;
- cx18_audio_set_io(cx);
- return 0;
-}
-
-static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- /* set it to defaults from our table */
- return cx18_get_input(cx, vin->index, vin);
-}
-
-static int cx18_cropcap(struct file *file, void *fh,
- struct v4l2_cropcap *cropcap)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- cropcap->bounds.top = cropcap->bounds.left = 0;
- cropcap->bounds.width = 720;
- cropcap->bounds.height = cx->is_50hz ? 576 : 480;
- cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10;
- cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11;
- cropcap->defrect = cropcap->bounds;
- return 0;
-}
-
-static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n");
- return -EINVAL;
-}
-
-static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n");
- return -EINVAL;
-}
-
-static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_fmtdesc *fmt)
-{
- static const struct v4l2_fmtdesc formats[] = {
- { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
- "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 }
- },
- { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
- "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 }
- },
- { 2, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
- "UYVY 4:2:2", V4L2_PIX_FMT_UYVY, { 0, 0, 0, 0 }
- },
- };
-
- if (fmt->index > ARRAY_SIZE(formats) - 1)
- return -EINVAL;
- *fmt = formats[fmt->index];
- return 0;
-}
-
-static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- *i = cx->active_input;
- return 0;
-}
-
-int cx18_s_input(struct file *file, void *fh, unsigned int inp)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
-
- if (inp >= cx->nof_inputs)
- return -EINVAL;
-
- if (inp == cx->active_input) {
- CX18_DEBUG_INFO("Input unchanged\n");
- return 0;
- }
-
- CX18_DEBUG_INFO("Changing input from %d to %d\n",
- cx->active_input, inp);
-
- cx->active_input = inp;
- /* Set the audio input to whatever is appropriate for the input type. */
- cx->audio_input = cx->card->video_inputs[inp].audio_index;
-
- /* prevent others from messing with the streams until
- we're finished changing inputs. */
- cx18_mute(cx);
- cx18_video_set_io(cx);
- cx18_audio_set_io(cx);
- cx18_unmute(cx);
- return 0;
-}
-
-static int cx18_g_frequency(struct file *file, void *fh,
- struct v4l2_frequency *vf)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- if (vf->tuner != 0)
- return -EINVAL;
-
- cx18_call_all(cx, tuner, g_frequency, vf);
- return 0;
-}
-
-int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
-
- if (vf->tuner != 0)
- return -EINVAL;
-
- cx18_mute(cx);
- CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
- cx18_call_all(cx, tuner, s_frequency, vf);
- cx18_unmute(cx);
- return 0;
-}
-
-static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- *std = cx->std;
- return 0;
-}
-
-int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
-
- if ((*std & V4L2_STD_ALL) == 0)
- return -EINVAL;
-
- if (*std == cx->std)
- return 0;
-
- if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
- atomic_read(&cx->ana_capturing) > 0) {
- /* Switching standard would turn off the radio or mess
- with already running streams, prevent that by
- returning EBUSY. */
- return -EBUSY;
- }
-
- cx->std = *std;
- cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
- cx->is_50hz = !cx->is_60hz;
- cx2341x_handler_set_50hz(&cx->cxhdl, cx->is_50hz);
- cx->cxhdl.width = 720;
- cx->cxhdl.height = cx->is_50hz ? 576 : 480;
- cx->vbi.count = cx->is_50hz ? 18 : 12;
- cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
- cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
- CX18_DEBUG_INFO("Switching standard to %llx.\n",
- (unsigned long long) cx->std);
-
- /* Tuner */
- cx18_call_all(cx, core, s_std, cx->std);
- return 0;
-}
-
-static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
-
- if (vt->index != 0)
- return -EINVAL;
-
- cx18_call_all(cx, tuner, s_tuner, vt);
- return 0;
-}
-
-static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- if (vt->index != 0)
- return -EINVAL;
-
- cx18_call_all(cx, tuner, g_tuner, vt);
-
- if (vt->type == V4L2_TUNER_RADIO)
- strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
- else
- strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
- return 0;
-}
-
-static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
- struct v4l2_sliced_vbi_cap *cap)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
- int f, l;
-
- if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
- return -EINVAL;
-
- cap->service_set = 0;
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- if (valid_service_line(f, l, cx->is_50hz)) {
- /*
- * We can find all v4l2 supported vbi services
- * for the standard, on a valid line for the std
- */
- cap->service_lines[f][l] = set;
- cap->service_set |= set;
- } else
- cap->service_lines[f][l] = 0;
- }
- }
- for (f = 0; f < 3; f++)
- cap->reserved[f] = 0;
- return 0;
-}
-
-static int _cx18_process_idx_data(struct cx18_buffer *buf,
- struct v4l2_enc_idx *idx)
-{
- int consumed, remaining;
- struct v4l2_enc_idx_entry *e_idx;
- struct cx18_enc_idx_entry *e_buf;
-
- /* Frame type lookup: 1=I, 2=P, 4=B */
- const int mapping[8] = {
- -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P,
- -1, V4L2_ENC_IDX_FRAME_B, -1, -1, -1
- };
-
- /*
- * Assumption here is that a buf holds an integral number of
- * struct cx18_enc_idx_entry objects and is properly aligned.
- * This is enforced by the module options on IDX buffer sizes.
- */
- remaining = buf->bytesused - buf->readpos;
- consumed = 0;
- e_idx = &idx->entry[idx->entries];
- e_buf = (struct cx18_enc_idx_entry *) &buf->buf[buf->readpos];
-
- while (remaining >= sizeof(struct cx18_enc_idx_entry) &&
- idx->entries < V4L2_ENC_IDX_ENTRIES) {
-
- e_idx->offset = (((u64) le32_to_cpu(e_buf->offset_high)) << 32)
- | le32_to_cpu(e_buf->offset_low);
-
- e_idx->pts = (((u64) (le32_to_cpu(e_buf->pts_high) & 1)) << 32)
- | le32_to_cpu(e_buf->pts_low);
-
- e_idx->length = le32_to_cpu(e_buf->length);
-
- e_idx->flags = mapping[le32_to_cpu(e_buf->flags) & 0x7];
-
- e_idx->reserved[0] = 0;
- e_idx->reserved[1] = 0;
-
- idx->entries++;
- e_idx = &idx->entry[idx->entries];
- e_buf++;
-
- remaining -= sizeof(struct cx18_enc_idx_entry);
- consumed += sizeof(struct cx18_enc_idx_entry);
- }
-
- /* Swallow any partial entries at the end, if there are any */
- if (remaining > 0 && remaining < sizeof(struct cx18_enc_idx_entry))
- consumed += remaining;
-
- buf->readpos += consumed;
- return consumed;
-}
-
-static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl,
- struct v4l2_enc_idx *idx)
-{
- if (s->type != CX18_ENC_STREAM_TYPE_IDX)
- return -EINVAL;
-
- if (mdl->curr_buf == NULL)
- mdl->curr_buf = list_first_entry(&mdl->buf_list,
- struct cx18_buffer, list);
-
- if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
- /*
- * For some reason we've exhausted the buffers, but the MDL
- * object still said some data was unread.
- * Fix that and bail out.
- */
- mdl->readpos = mdl->bytesused;
- return 0;
- }
-
- list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
-
- /* Skip any empty buffers in the MDL */
- if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
- continue;
-
- mdl->readpos += _cx18_process_idx_data(mdl->curr_buf, idx);
-
- /* exit when MDL drained or request satisfied */
- if (idx->entries >= V4L2_ENC_IDX_ENTRIES ||
- mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
- mdl->readpos >= mdl->bytesused)
- break;
- }
- return 0;
-}
-
-static int cx18_g_enc_index(struct file *file, void *fh,
- struct v4l2_enc_idx *idx)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
- s32 tmp;
- struct cx18_mdl *mdl;
-
- if (!cx18_stream_enabled(s)) /* Module options inhibited IDX stream */
- return -EINVAL;
-
- /* Compute the best case number of entries we can buffer */
- tmp = s->buffers -
- s->bufs_per_mdl * CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN;
- if (tmp <= 0)
- tmp = 1;
- tmp = tmp * s->buf_size / sizeof(struct cx18_enc_idx_entry);
-
- /* Fill out the header of the return structure */
- idx->entries = 0;
- idx->entries_cap = tmp;
- memset(idx->reserved, 0, sizeof(idx->reserved));
-
- /* Pull IDX MDLs and buffers from q_full and populate the entries */
- do {
- mdl = cx18_dequeue(s, &s->q_full);
- if (mdl == NULL) /* No more IDX data right now */
- break;
-
- /* Extract the Index entry data from the MDL and buffers */
- cx18_process_idx_data(s, mdl, idx);
- if (mdl->readpos < mdl->bytesused) {
- /* We finished with data remaining, push the MDL back */
- cx18_push(s, mdl, &s->q_full);
- break;
- }
-
- /* We drained this MDL, schedule it to go to the firmware */
- cx18_enqueue(s, mdl, &s->q_free);
-
- } while (idx->entries < V4L2_ENC_IDX_ENTRIES);
-
- /* Tell the work handler to send free IDX MDLs to the firmware */
- cx18_stream_load_fw_queue(s);
- return 0;
-}
-
-static struct videobuf_queue *cx18_vb_queue(struct cx18_open_id *id)
-{
- struct videobuf_queue *q = NULL;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- switch (s->vb_type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- q = &s->vbuf_q;
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- break;
- default:
- break;
- }
- return q;
-}
-
-static int cx18_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct cx18_open_id *id = file->private_data;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- /* Start the hardware only if we're the video device */
- if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
-
- if (id->type != CX18_ENC_STREAM_TYPE_YUV)
- return -EINVAL;
-
- /* Establish a buffer timeout */
- mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
-
- return videobuf_streamon(cx18_vb_queue(id));
-}
-
-static int cx18_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct cx18_open_id *id = file->private_data;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- /* Start the hardware only if we're the video device */
- if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
-
- if (id->type != CX18_ENC_STREAM_TYPE_YUV)
- return -EINVAL;
-
- return videobuf_streamoff(cx18_vb_queue(id));
-}
-
-static int cx18_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *rb)
-{
- struct cx18_open_id *id = file->private_data;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
-
- return videobuf_reqbufs(cx18_vb_queue(id), rb);
-}
-
-static int cx18_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct cx18_open_id *id = file->private_data;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
-
- return videobuf_querybuf(cx18_vb_queue(id), b);
-}
-
-static int cx18_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct cx18_open_id *id = file->private_data;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
-
- return videobuf_qbuf(cx18_vb_queue(id), b);
-}
-
-static int cx18_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct cx18_open_id *id = file->private_data;
- struct cx18 *cx = id->cx;
- struct cx18_stream *s = &cx->streams[id->type];
-
- if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
-
- return videobuf_dqbuf(cx18_vb_queue(id), b, file->f_flags & O_NONBLOCK);
-}
-
-static int cx18_encoder_cmd(struct file *file, void *fh,
- struct v4l2_encoder_cmd *enc)
-{
- struct cx18_open_id *id = fh2id(fh);
- struct cx18 *cx = id->cx;
- u32 h;
-
- switch (enc->cmd) {
- case V4L2_ENC_CMD_START:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
- enc->flags = 0;
- return cx18_start_capture(id);
-
- case V4L2_ENC_CMD_STOP:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
- enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
- cx18_stop_capture(id,
- enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
- break;
-
- case V4L2_ENC_CMD_PAUSE:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
- enc->flags = 0;
- if (!atomic_read(&cx->ana_capturing))
- return -EPERM;
- if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
- return 0;
- h = cx18_find_handle(cx);
- if (h == CX18_INVALID_TASK_HANDLE) {
- CX18_ERR("Can't find valid task handle for "
- "V4L2_ENC_CMD_PAUSE\n");
- return -EBADFD;
- }
- cx18_mute(cx);
- cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h);
- break;
-
- case V4L2_ENC_CMD_RESUME:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
- enc->flags = 0;
- if (!atomic_read(&cx->ana_capturing))
- return -EPERM;
- if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
- return 0;
- h = cx18_find_handle(cx);
- if (h == CX18_INVALID_TASK_HANDLE) {
- CX18_ERR("Can't find valid task handle for "
- "V4L2_ENC_CMD_RESUME\n");
- return -EBADFD;
- }
- cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h);
- cx18_unmute(cx);
- break;
-
- default:
- CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
- return -EINVAL;
- }
- return 0;
-}
-
-static int cx18_try_encoder_cmd(struct file *file, void *fh,
- struct v4l2_encoder_cmd *enc)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- switch (enc->cmd) {
- case V4L2_ENC_CMD_START:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
- enc->flags = 0;
- break;
-
- case V4L2_ENC_CMD_STOP:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
- enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
- break;
-
- case V4L2_ENC_CMD_PAUSE:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
- enc->flags = 0;
- break;
-
- case V4L2_ENC_CMD_RESUME:
- CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
- enc->flags = 0;
- break;
-
- default:
- CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
- return -EINVAL;
- }
- return 0;
-}
-
-static int cx18_log_status(struct file *file, void *fh)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- struct v4l2_input vidin;
- struct v4l2_audio audin;
- int i;
-
- CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name);
- if (cx->hw_flags & CX18_HW_TVEEPROM) {
- struct tveeprom tv;
-
- cx18_read_eeprom(cx, &tv);
- }
- cx18_call_all(cx, core, log_status);
- cx18_get_input(cx, cx->active_input, &vidin);
- cx18_get_audio_input(cx, cx->audio_input, &audin);
- CX18_INFO("Video Input: %s\n", vidin.name);
- CX18_INFO("Audio Input: %s\n", audin.name);
- mutex_lock(&cx->gpio_lock);
- CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n",
- cx->gpio_dir, cx->gpio_val);
- mutex_unlock(&cx->gpio_lock);
- CX18_INFO("Tuner: %s\n",
- test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV");
- v4l2_ctrl_handler_log_status(&cx->cxhdl.hdl, cx->v4l2_dev.name);
- CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
- for (i = 0; i < CX18_MAX_STREAMS; i++) {
- struct cx18_stream *s = &cx->streams[i];
-
- if (s->video_dev == NULL || s->buffers == 0)
- continue;
- CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
- s->name, s->s_flags,
- atomic_read(&s->q_full.depth) * s->bufs_per_mdl * 100
- / s->buffers,
- (s->buffers * s->buf_size) / 1024, s->buffers);
- }
- CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
- (long long)cx->mpg_data_received,
- (long long)cx->vbi_data_inserted);
- return 0;
-}
-
-static long cx18_default(struct file *file, void *fh, bool valid_prio,
- int cmd, void *arg)
-{
- struct cx18 *cx = fh2id(fh)->cx;
-
- switch (cmd) {
- case VIDIOC_INT_RESET: {
- u32 val = *(u32 *)arg;
-
- if ((val == 0) || (val & 0x01))
- cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, core, reset,
- (u32) CX18_GPIO_RESET_Z8F0811);
- break;
- }
-
- default:
- return -ENOTTY;
- }
- return 0;
-}
-
-static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
- .vidioc_querycap = cx18_querycap,
- .vidioc_s_audio = cx18_s_audio,
- .vidioc_g_audio = cx18_g_audio,
- .vidioc_enumaudio = cx18_enumaudio,
- .vidioc_enum_input = cx18_enum_input,
- .vidioc_cropcap = cx18_cropcap,
- .vidioc_s_crop = cx18_s_crop,
- .vidioc_g_crop = cx18_g_crop,
- .vidioc_g_input = cx18_g_input,
- .vidioc_s_input = cx18_s_input,
- .vidioc_g_frequency = cx18_g_frequency,
- .vidioc_s_frequency = cx18_s_frequency,
- .vidioc_s_tuner = cx18_s_tuner,
- .vidioc_g_tuner = cx18_g_tuner,
- .vidioc_g_enc_index = cx18_g_enc_index,
- .vidioc_g_std = cx18_g_std,
- .vidioc_s_std = cx18_s_std,
- .vidioc_log_status = cx18_log_status,
- .vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap,
- .vidioc_encoder_cmd = cx18_encoder_cmd,
- .vidioc_try_encoder_cmd = cx18_try_encoder_cmd,
- .vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap,
- .vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap,
- .vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap,
- .vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap,
- .vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap,
- .vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap,
- .vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap,
- .vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap,
- .vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap,
- .vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap,
- .vidioc_g_chip_ident = cx18_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx18_g_register,
- .vidioc_s_register = cx18_s_register,
-#endif
- .vidioc_default = cx18_default,
- .vidioc_streamon = cx18_streamon,
- .vidioc_streamoff = cx18_streamoff,
- .vidioc_reqbufs = cx18_reqbufs,
- .vidioc_querybuf = cx18_querybuf,
- .vidioc_qbuf = cx18_qbuf,
- .vidioc_dqbuf = cx18_dqbuf,
-};
-
-void cx18_set_funcs(struct video_device *vdev)
-{
- vdev->ioctl_ops = &cx18_ioctl_ops;
-}
diff --git a/drivers/media/video/cx18/cx18-ioctl.h b/drivers/media/video/cx18/cx18-ioctl.h
deleted file mode 100644
index 2f9dd591ee0..00000000000
--- a/drivers/media/video/cx18/cx18-ioctl.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * cx18 ioctl system call
- *
- * Derived from ivtv-ioctl.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-u16 cx18_service2vbi(int type);
-void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
-u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt);
-void cx18_set_funcs(struct video_device *vdev);
-int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std);
-int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
-int cx18_s_input(struct file *file, void *fh, unsigned int inp);
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c
deleted file mode 100644
index 80edfe93a3d..00000000000
--- a/drivers/media/video/cx18/cx18-irq.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * cx18 interrupt handling
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-irq.h"
-#include "cx18-mailbox.h"
-#include "cx18-scb.h"
-
-static void xpu_ack(struct cx18 *cx, u32 sw2)
-{
- if (sw2 & IRQ_CPU_TO_EPU_ACK)
- wake_up(&cx->mb_cpu_waitq);
- if (sw2 & IRQ_APU_TO_EPU_ACK)
- wake_up(&cx->mb_apu_waitq);
-}
-
-static void epu_cmd(struct cx18 *cx, u32 sw1)
-{
- if (sw1 & IRQ_CPU_TO_EPU)
- cx18_api_epu_cmd_irq(cx, CPU);
- if (sw1 & IRQ_APU_TO_EPU)
- cx18_api_epu_cmd_irq(cx, APU);
-}
-
-irqreturn_t cx18_irq_handler(int irq, void *dev_id)
-{
- struct cx18 *cx = (struct cx18 *)dev_id;
- u32 sw1, sw2, hw2;
-
- sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & cx->sw1_irq_mask;
- sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & cx->sw2_irq_mask;
- hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & cx->hw2_irq_mask;
-
- if (sw1)
- cx18_write_reg_expect(cx, sw1, SW1_INT_STATUS, ~sw1, sw1);
- if (sw2)
- cx18_write_reg_expect(cx, sw2, SW2_INT_STATUS, ~sw2, sw2);
- if (hw2)
- cx18_write_reg_expect(cx, hw2, HW2_INT_CLR_STATUS, ~hw2, hw2);
-
- if (sw1 || sw2 || hw2)
- CX18_DEBUG_HI_IRQ("received interrupts "
- "SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2);
-
- /*
- * SW1 responses have to happen first. The sending XPU times out the
- * incoming mailboxes on us rather rapidly.
- */
- if (sw1)
- epu_cmd(cx, sw1);
-
- /* To do: interrupt-based I2C handling
- if (hw2 & (HW2_I2C1_INT|HW2_I2C2_INT)) {
- }
- */
-
- if (sw2)
- xpu_ack(cx, sw2);
-
- return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE;
-}
diff --git a/drivers/media/video/cx18/cx18-irq.h b/drivers/media/video/cx18/cx18-irq.h
deleted file mode 100644
index 30e7eaf8cb5..00000000000
--- a/drivers/media/video/cx18/cx18-irq.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * cx18 interrupt handling
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#define HW2_I2C1_INT (1 << 22)
-#define HW2_I2C2_INT (1 << 23)
-#define HW2_INT_CLR_STATUS 0xc730c4
-#define HW2_INT_MASK5_PCI 0xc730e4
-#define SW1_INT_SET 0xc73100
-#define SW1_INT_STATUS 0xc73104
-#define SW1_INT_ENABLE_PCI 0xc7311c
-#define SW2_INT_SET 0xc73140
-#define SW2_INT_STATUS 0xc73144
-#define SW2_INT_ENABLE_CPU 0xc73158
-#define SW2_INT_ENABLE_PCI 0xc7315c
-
-irqreturn_t cx18_irq_handler(int irq, void *dev_id);
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
deleted file mode 100644
index eabf00c6351..00000000000
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ /dev/null
@@ -1,870 +0,0 @@
-/*
- * cx18 mailbox functions
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include <stdarg.h>
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-scb.h"
-#include "cx18-irq.h"
-#include "cx18-mailbox.h"
-#include "cx18-queue.h"
-#include "cx18-streams.h"
-#include "cx18-alsa-pcm.h" /* FIXME make configurable */
-
-static const char *rpu_str[] = { "APU", "CPU", "EPU", "HPU" };
-
-#define API_FAST (1 << 2) /* Short timeout */
-#define API_SLOW (1 << 3) /* Additional 300ms timeout */
-
-struct cx18_api_info {
- u32 cmd;
- u8 flags; /* Flags, see above */
- u8 rpu; /* Processing unit */
- const char *name; /* The name of the command */
-};
-
-#define API_ENTRY(rpu, x, f) { (x), (f), (rpu), #x }
-
-static const struct cx18_api_info api_info[] = {
- /* MPEG encoder API */
- API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0),
- API_ENTRY(CPU, CX18_EPU_DEBUG, 0),
- API_ENTRY(CPU, CX18_CREATE_TASK, 0),
- API_ENTRY(CPU, CX18_DESTROY_TASK, 0),
- API_ENTRY(CPU, CX18_CPU_CAPTURE_START, API_SLOW),
- API_ENTRY(CPU, CX18_CPU_CAPTURE_STOP, API_SLOW),
- API_ENTRY(CPU, CX18_CPU_CAPTURE_PAUSE, 0),
- API_ENTRY(CPU, CX18_CPU_CAPTURE_RESUME, 0),
- API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_VIDEO_IN, 0),
- API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RATE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RESOLUTION, 0),
- API_ENTRY(CPU, CX18_CPU_SET_FILTER_PARAM, 0),
- API_ENTRY(CPU, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_MEDIAN_CORING, 0),
- API_ENTRY(CPU, CX18_CPU_SET_INDEXTABLE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PARAMETERS, 0),
- API_ENTRY(CPU, CX18_CPU_SET_VIDEO_MUTE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_AUDIO_MUTE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_MISC_PARAMETERS, 0),
- API_ENTRY(CPU, CX18_CPU_SET_RAW_VBI_PARAM, API_SLOW),
- API_ENTRY(CPU, CX18_CPU_SET_CAPTURE_LINE_NO, 0),
- API_ENTRY(CPU, CX18_CPU_SET_COPYRIGHT, 0),
- API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PID, 0),
- API_ENTRY(CPU, CX18_CPU_SET_VIDEO_PID, 0),
- API_ENTRY(CPU, CX18_CPU_SET_VER_CROP_LINE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_GOP_STRUCTURE, 0),
- API_ENTRY(CPU, CX18_CPU_SET_SCENE_CHANGE_DETECTION, 0),
- API_ENTRY(CPU, CX18_CPU_SET_ASPECT_RATIO, 0),
- API_ENTRY(CPU, CX18_CPU_SET_SKIP_INPUT_FRAME, 0),
- API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0),
- API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0),
- API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0),
- API_ENTRY(CPU, CX18_CPU_SET_VFC_PARAM, 0),
- API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0),
- API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
- API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW),
- API_ENTRY(APU, CX18_APU_START, 0),
- API_ENTRY(APU, CX18_APU_STOP, 0),
- API_ENTRY(APU, CX18_APU_RESETAI, 0),
- API_ENTRY(CPU, CX18_CPU_DEBUG_PEEK32, 0),
- API_ENTRY(0, 0, 0),
-};
-
-static const struct cx18_api_info *find_api_info(u32 cmd)
-{
- int i;
-
- for (i = 0; api_info[i].cmd; i++)
- if (api_info[i].cmd == cmd)
- return &api_info[i];
- return NULL;
-}
-
-/* Call with buf of n*11+1 bytes */
-static char *u32arr2hex(u32 data[], int n, char *buf)
-{
- char *p;
- int i;
-
- for (i = 0, p = buf; i < n; i++, p += 11) {
- /* kernel snprintf() appends '\0' always */
- snprintf(p, 12, " %#010x", data[i]);
- }
- *p = '\0';
- return buf;
-}
-
-static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
-{
- char argstr[MAX_MB_ARGUMENTS*11+1];
-
- if (!(cx18_debug & CX18_DBGFLG_API))
- return;
-
- CX18_DEBUG_API("%s: req %#010x ack %#010x cmd %#010x err %#010x args%s"
- "\n", name, mb->request, mb->ack, mb->cmd, mb->error,
- u32arr2hex(mb->args, MAX_MB_ARGUMENTS, argstr));
-}
-
-
-/*
- * Functions that run in a work_queue work handling context
- */
-
-static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
-{
- struct cx18_buffer *buf;
-
- if (s->dvb == NULL || !s->dvb->enabled || mdl->bytesused == 0)
- return;
-
- /* We ignore mdl and buf readpos accounting here - it doesn't matter */
-
- /* The likely case */
- if (list_is_singular(&mdl->buf_list)) {
- buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
- list);
- if (buf->bytesused)
- dvb_dmx_swfilter(&s->dvb->demux,
- buf->buf, buf->bytesused);
- return;
- }
-
- list_for_each_entry(buf, &mdl->buf_list, list) {
- if (buf->bytesused == 0)
- break;
- dvb_dmx_swfilter(&s->dvb->demux, buf->buf, buf->bytesused);
- }
-}
-
-static void cx18_mdl_send_to_videobuf(struct cx18_stream *s,
- struct cx18_mdl *mdl)
-{
- struct cx18_videobuf_buffer *vb_buf;
- struct cx18_buffer *buf;
- u8 *p;
- u32 offset = 0;
- int dispatch = 0;
-
- if (mdl->bytesused == 0)
- return;
-
- /* Acquire a videobuf buffer, clone to and and release it */
- spin_lock(&s->vb_lock);
- if (list_empty(&s->vb_capture))
- goto out;
-
- vb_buf = list_first_entry(&s->vb_capture, struct cx18_videobuf_buffer,
- vb.queue);
-
- p = videobuf_to_vmalloc(&vb_buf->vb);
- if (!p)
- goto out;
-
- offset = vb_buf->bytes_used;
- list_for_each_entry(buf, &mdl->buf_list, list) {
- if (buf->bytesused == 0)
- break;
-
- if ((offset + buf->bytesused) <= vb_buf->vb.bsize) {
- memcpy(p + offset, buf->buf, buf->bytesused);
- offset += buf->bytesused;
- vb_buf->bytes_used += buf->bytesused;
- }
- }
-
- /* If we've filled the buffer as per the callers res then dispatch it */
- if (vb_buf->bytes_used >= s->vb_bytes_per_frame) {
- dispatch = 1;
- vb_buf->bytes_used = 0;
- }
-
- if (dispatch) {
- vb_buf->vb.ts = ktime_to_timeval(ktime_get());
- list_del(&vb_buf->vb.queue);
- vb_buf->vb.state = VIDEOBUF_DONE;
- wake_up(&vb_buf->vb.done);
- }
-
- mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
-
-out:
- spin_unlock(&s->vb_lock);
-}
-
-static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s,
- struct cx18_mdl *mdl)
-{
- struct cx18_buffer *buf;
-
- if (mdl->bytesused == 0)
- return;
-
- /* We ignore mdl and buf readpos accounting here - it doesn't matter */
-
- /* The likely case */
- if (list_is_singular(&mdl->buf_list)) {
- buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
- list);
- if (buf->bytesused)
- cx->pcm_announce_callback(cx->alsa, buf->buf,
- buf->bytesused);
- return;
- }
-
- list_for_each_entry(buf, &mdl->buf_list, list) {
- if (buf->bytesused == 0)
- break;
- cx->pcm_announce_callback(cx->alsa, buf->buf, buf->bytesused);
- }
-}
-
-static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- u32 handle, mdl_ack_count, id;
- struct cx18_mailbox *mb;
- struct cx18_mdl_ack *mdl_ack;
- struct cx18_stream *s;
- struct cx18_mdl *mdl;
- int i;
-
- mb = &order->mb;
- handle = mb->args[0];
- s = cx18_handle_to_stream(cx, handle);
-
- if (s == NULL) {
- CX18_WARN("Got DMA done notification for unknown/inactive"
- " handle %d, %s mailbox seq no %d\n", handle,
- (order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) ?
- "stale" : "good", mb->request);
- return;
- }
-
- mdl_ack_count = mb->args[2];
- mdl_ack = order->mdl_ack;
- for (i = 0; i < mdl_ack_count; i++, mdl_ack++) {
- id = mdl_ack->id;
- /*
- * Simple integrity check for processing a stale (and possibly
- * inconsistent mailbox): make sure the MDL id is in the
- * valid range for the stream.
- *
- * We go through the trouble of dealing with stale mailboxes
- * because most of the time, the mailbox data is still valid and
- * unchanged (and in practice the firmware ping-pongs the
- * two mdl_ack buffers so mdl_acks are not stale).
- *
- * There are occasions when we get a half changed mailbox,
- * which this check catches for a handle & id mismatch. If the
- * handle and id do correspond, the worst case is that we
- * completely lost the old MDL, but pick up the new MDL
- * early (but the new mdl_ack is guaranteed to be good in this
- * case as the firmware wouldn't point us to a new mdl_ack until
- * it's filled in).
- *
- * cx18_queue_get_mdl() will detect the lost MDLs
- * and send them back to q_free for fw rotation eventually.
- */
- if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) &&
- !(id >= s->mdl_base_idx &&
- id < (s->mdl_base_idx + s->buffers))) {
- CX18_WARN("Fell behind! Ignoring stale mailbox with "
- " inconsistent data. Lost MDL for mailbox "
- "seq no %d\n", mb->request);
- break;
- }
- mdl = cx18_queue_get_mdl(s, id, mdl_ack->data_used);
-
- CX18_DEBUG_HI_DMA("DMA DONE for %s (MDL %d)\n", s->name, id);
- if (mdl == NULL) {
- CX18_WARN("Could not find MDL %d for stream %s\n",
- id, s->name);
- continue;
- }
-
- CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
- s->name, mdl->bytesused);
-
- if (s->type == CX18_ENC_STREAM_TYPE_TS) {
- cx18_mdl_send_to_dvb(s, mdl);
- cx18_enqueue(s, mdl, &s->q_free);
- } else if (s->type == CX18_ENC_STREAM_TYPE_PCM) {
- /* Pass the data to cx18-alsa */
- if (cx->pcm_announce_callback != NULL) {
- cx18_mdl_send_to_alsa(cx, s, mdl);
- cx18_enqueue(s, mdl, &s->q_free);
- } else {
- cx18_enqueue(s, mdl, &s->q_full);
- }
- } else if (s->type == CX18_ENC_STREAM_TYPE_YUV) {
- cx18_mdl_send_to_videobuf(s, mdl);
- cx18_enqueue(s, mdl, &s->q_free);
- } else {
- cx18_enqueue(s, mdl, &s->q_full);
- if (s->type == CX18_ENC_STREAM_TYPE_IDX)
- cx18_stream_rotate_idx_mdls(cx);
- }
- }
- /* Put as many MDLs as possible back into fw use */
- cx18_stream_load_fw_queue(s);
-
- wake_up(&cx->dma_waitq);
- if (s->id != -1)
- wake_up(&s->waitq);
-}
-
-static void epu_debug(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- char *p;
- char *str = order->str;
-
- CX18_DEBUG_INFO("%x %s\n", order->mb.args[0], str);
- p = strchr(str, '.');
- if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags) && p && p > str)
- CX18_INFO("FW version: %s\n", p - 1);
-}
-
-static void epu_cmd(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- switch (order->rpu) {
- case CPU:
- {
- switch (order->mb.cmd) {
- case CX18_EPU_DMA_DONE:
- epu_dma_done(cx, order);
- break;
- case CX18_EPU_DEBUG:
- epu_debug(cx, order);
- break;
- default:
- CX18_WARN("Unknown CPU to EPU mailbox command %#0x\n",
- order->mb.cmd);
- break;
- }
- break;
- }
- case APU:
- CX18_WARN("Unknown APU to EPU mailbox command %#0x\n",
- order->mb.cmd);
- break;
- default:
- break;
- }
-}
-
-static
-void free_in_work_order(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- atomic_set(&order->pending, 0);
-}
-
-void cx18_in_work_handler(struct work_struct *work)
-{
- struct cx18_in_work_order *order =
- container_of(work, struct cx18_in_work_order, work);
- struct cx18 *cx = order->cx;
- epu_cmd(cx, order);
- free_in_work_order(cx, order);
-}
-
-
-/*
- * Functions that run in an interrupt handling context
- */
-
-static void mb_ack_irq(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- struct cx18_mailbox __iomem *ack_mb;
- u32 ack_irq, req;
-
- switch (order->rpu) {
- case APU:
- ack_irq = IRQ_EPU_TO_APU_ACK;
- ack_mb = &cx->scb->apu2epu_mb;
- break;
- case CPU:
- ack_irq = IRQ_EPU_TO_CPU_ACK;
- ack_mb = &cx->scb->cpu2epu_mb;
- break;
- default:
- CX18_WARN("Unhandled RPU (%d) for command %x ack\n",
- order->rpu, order->mb.cmd);
- return;
- }
-
- req = order->mb.request;
- /* Don't ack if the RPU has gotten impatient and timed us out */
- if (req != cx18_readl(cx, &ack_mb->request) ||
- req == cx18_readl(cx, &ack_mb->ack)) {
- CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our "
- "incoming %s to EPU mailbox (sequence no. %u) "
- "while processing\n",
- rpu_str[order->rpu], rpu_str[order->rpu], req);
- order->flags |= CX18_F_EWO_MB_STALE_WHILE_PROC;
- return;
- }
- cx18_writel(cx, req, &ack_mb->ack);
- cx18_write_reg_expect(cx, ack_irq, SW2_INT_SET, ack_irq, ack_irq);
- return;
-}
-
-static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- u32 handle, mdl_ack_offset, mdl_ack_count;
- struct cx18_mailbox *mb;
- int i;
-
- mb = &order->mb;
- handle = mb->args[0];
- mdl_ack_offset = mb->args[1];
- mdl_ack_count = mb->args[2];
-
- if (handle == CX18_INVALID_TASK_HANDLE ||
- mdl_ack_count == 0 || mdl_ack_count > CX18_MAX_MDL_ACKS) {
- if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
- mb_ack_irq(cx, order);
- return -1;
- }
-
- for (i = 0; i < sizeof(struct cx18_mdl_ack) * mdl_ack_count; i += sizeof(u32))
- ((u32 *)order->mdl_ack)[i / sizeof(u32)] =
- cx18_readl(cx, cx->enc_mem + mdl_ack_offset + i);
-
- if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
- mb_ack_irq(cx, order);
- return 1;
-}
-
-static
-int epu_debug_irq(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- u32 str_offset;
- char *str = order->str;
-
- str[0] = '\0';
- str_offset = order->mb.args[1];
- if (str_offset) {
- cx18_setup_page(cx, str_offset);
- cx18_memcpy_fromio(cx, str, cx->enc_mem + str_offset, 252);
- str[252] = '\0';
- cx18_setup_page(cx, SCB_OFFSET);
- }
-
- if ((order->flags & CX18_F_EWO_MB_STALE) == 0)
- mb_ack_irq(cx, order);
-
- return str_offset ? 1 : 0;
-}
-
-static inline
-int epu_cmd_irq(struct cx18 *cx, struct cx18_in_work_order *order)
-{
- int ret = -1;
-
- switch (order->rpu) {
- case CPU:
- {
- switch (order->mb.cmd) {
- case CX18_EPU_DMA_DONE:
- ret = epu_dma_done_irq(cx, order);
- break;
- case CX18_EPU_DEBUG:
- ret = epu_debug_irq(cx, order);
- break;
- default:
- CX18_WARN("Unknown CPU to EPU mailbox command %#0x\n",
- order->mb.cmd);
- break;
- }
- break;
- }
- case APU:
- CX18_WARN("Unknown APU to EPU mailbox command %#0x\n",
- order->mb.cmd);
- break;
- default:
- break;
- }
- return ret;
-}
-
-static inline
-struct cx18_in_work_order *alloc_in_work_order_irq(struct cx18 *cx)
-{
- int i;
- struct cx18_in_work_order *order = NULL;
-
- for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
- /*
- * We only need "pending" atomic to inspect its contents,
- * and need not do a check and set because:
- * 1. Any work handler thread only clears "pending" and only
- * on one, particular work order at a time, per handler thread.
- * 2. "pending" is only set here, and we're serialized because
- * we're called in an IRQ handler context.
- */
- if (atomic_read(&cx->in_work_order[i].pending) == 0) {
- order = &cx->in_work_order[i];
- atomic_set(&order->pending, 1);
- break;
- }
- }
- return order;
-}
-
-void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
-{
- struct cx18_mailbox __iomem *mb;
- struct cx18_mailbox *order_mb;
- struct cx18_in_work_order *order;
- int submit;
- int i;
-
- switch (rpu) {
- case CPU:
- mb = &cx->scb->cpu2epu_mb;
- break;
- case APU:
- mb = &cx->scb->apu2epu_mb;
- break;
- default:
- return;
- }
-
- order = alloc_in_work_order_irq(cx);
- if (order == NULL) {
- CX18_WARN("Unable to find blank work order form to schedule "
- "incoming mailbox command processing\n");
- return;
- }
-
- order->flags = 0;
- order->rpu = rpu;
- order_mb = &order->mb;
-
- /* mb->cmd and mb->args[0] through mb->args[2] */
- for (i = 0; i < 4; i++)
- (&order_mb->cmd)[i] = cx18_readl(cx, &mb->cmd + i);
-
- /* mb->request and mb->ack. N.B. we want to read mb->ack last */
- for (i = 0; i < 2; i++)
- (&order_mb->request)[i] = cx18_readl(cx, &mb->request + i);
-
- if (order_mb->request == order_mb->ack) {
- CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our "
- "incoming %s to EPU mailbox (sequence no. %u)"
- "\n",
- rpu_str[rpu], rpu_str[rpu], order_mb->request);
- if (cx18_debug & CX18_DBGFLG_WARN)
- dump_mb(cx, order_mb, "incoming");
- order->flags = CX18_F_EWO_MB_STALE_UPON_RECEIPT;
- }
-
- /*
- * Individual EPU command processing is responsible for ack-ing
- * a non-stale mailbox as soon as possible
- */
- submit = epu_cmd_irq(cx, order);
- if (submit > 0) {
- queue_work(cx->in_work_queue, &order->work);
- }
-}
-
-
-/*
- * Functions called from a non-interrupt, non work_queue context
- */
-
-static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
-{
- const struct cx18_api_info *info = find_api_info(cmd);
- u32 irq, req, ack, err;
- struct cx18_mailbox __iomem *mb;
- wait_queue_head_t *waitq;
- struct mutex *mb_lock;
- unsigned long int t0, timeout, ret;
- int i;
- char argstr[MAX_MB_ARGUMENTS*11+1];
- DEFINE_WAIT(w);
-
- if (info == NULL) {
- CX18_WARN("unknown cmd %x\n", cmd);
- return -EINVAL;
- }
-
- if (cx18_debug & CX18_DBGFLG_API) { /* only call u32arr2hex if needed */
- if (cmd == CX18_CPU_DE_SET_MDL) {
- if (cx18_debug & CX18_DBGFLG_HIGHVOL)
- CX18_DEBUG_HI_API("%s\tcmd %#010x args%s\n",
- info->name, cmd,
- u32arr2hex(data, args, argstr));
- } else
- CX18_DEBUG_API("%s\tcmd %#010x args%s\n",
- info->name, cmd,
- u32arr2hex(data, args, argstr));
- }
-
- switch (info->rpu) {
- case APU:
- waitq = &cx->mb_apu_waitq;
- mb_lock = &cx->epu2apu_mb_lock;
- irq = IRQ_EPU_TO_APU;
- mb = &cx->scb->epu2apu_mb;
- break;
- case CPU:
- waitq = &cx->mb_cpu_waitq;
- mb_lock = &cx->epu2cpu_mb_lock;
- irq = IRQ_EPU_TO_CPU;
- mb = &cx->scb->epu2cpu_mb;
- break;
- default:
- CX18_WARN("Unknown RPU (%d) for API call\n", info->rpu);
- return -EINVAL;
- }
-
- mutex_lock(mb_lock);
- /*
- * Wait for an in-use mailbox to complete
- *
- * If the XPU is responding with Ack's, the mailbox shouldn't be in
- * a busy state, since we serialize access to it on our end.
- *
- * If the wait for ack after sending a previous command was interrupted
- * by a signal, we may get here and find a busy mailbox. After waiting,
- * mark it "not busy" from our end, if the XPU hasn't ack'ed it still.
- */
- req = cx18_readl(cx, &mb->request);
- timeout = msecs_to_jiffies(10);
- ret = wait_event_timeout(*waitq,
- (ack = cx18_readl(cx, &mb->ack)) == req,
- timeout);
- if (req != ack) {
- /* waited long enough, make the mbox "not busy" from our end */
- cx18_writel(cx, req, &mb->ack);
- CX18_ERR("mbox was found stuck busy when setting up for %s; "
- "clearing busy and trying to proceed\n", info->name);
- } else if (ret != timeout)
- CX18_DEBUG_API("waited %u msecs for busy mbox to be acked\n",
- jiffies_to_msecs(timeout-ret));
-
- /* Build the outgoing mailbox */
- req = ((req & 0xfffffffe) == 0xfffffffe) ? 1 : req + 1;
-
- cx18_writel(cx, cmd, &mb->cmd);
- for (i = 0; i < args; i++)
- cx18_writel(cx, data[i], &mb->args[i]);
- cx18_writel(cx, 0, &mb->error);
- cx18_writel(cx, req, &mb->request);
- cx18_writel(cx, req - 1, &mb->ack); /* ensure ack & req are distinct */
-
- /*
- * Notify the XPU and wait for it to send an Ack back
- */
- timeout = msecs_to_jiffies((info->flags & API_FAST) ? 10 : 20);
-
- CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n",
- irq, info->name);
-
- /* So we don't miss the wakeup, prepare to wait before notifying fw */
- prepare_to_wait(waitq, &w, TASK_UNINTERRUPTIBLE);
- cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq);
-
- t0 = jiffies;
- ack = cx18_readl(cx, &mb->ack);
- if (ack != req) {
- schedule_timeout(timeout);
- ret = jiffies - t0;
- ack = cx18_readl(cx, &mb->ack);
- } else {
- ret = jiffies - t0;
- }
-
- finish_wait(waitq, &w);
-
- if (req != ack) {
- mutex_unlock(mb_lock);
- if (ret >= timeout) {
- /* Timed out */
- CX18_DEBUG_WARN("sending %s timed out waiting %d msecs "
- "for RPU acknowledgement\n",
- info->name, jiffies_to_msecs(ret));
- } else {
- CX18_DEBUG_WARN("woken up before mailbox ack was ready "
- "after submitting %s to RPU. only "
- "waited %d msecs on req %u but awakened"
- " with unmatched ack %u\n",
- info->name,
- jiffies_to_msecs(ret),
- req, ack);
- }
- return -EINVAL;
- }
-
- if (ret >= timeout)
- CX18_DEBUG_WARN("failed to be awakened upon RPU acknowledgment "
- "sending %s; timed out waiting %d msecs\n",
- info->name, jiffies_to_msecs(ret));
- else
- CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n",
- jiffies_to_msecs(ret), info->name);
-
- /* Collect data returned by the XPU */
- for (i = 0; i < MAX_MB_ARGUMENTS; i++)
- data[i] = cx18_readl(cx, &mb->args[i]);
- err = cx18_readl(cx, &mb->error);
- mutex_unlock(mb_lock);
-
- /*
- * Wait for XPU to perform extra actions for the caller in some cases.
- * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all MDLs
- * back in a burst shortly thereafter
- */
- if (info->flags & API_SLOW)
- cx18_msleep_timeout(300, 0);
-
- if (err)
- CX18_DEBUG_API("mailbox error %08x for command %s\n", err,
- info->name);
- return err ? -EIO : 0;
-}
-
-int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[])
-{
- return cx18_api_call(cx, cmd, args, data);
-}
-
-static int cx18_set_filter_param(struct cx18_stream *s)
-{
- struct cx18 *cx = s->cx;
- u32 mode;
- int ret;
-
- mode = (cx->filter_mode & 1) ? 2 : (cx->spatial_strength ? 1 : 0);
- ret = cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
- s->handle, 1, mode, cx->spatial_strength);
- mode = (cx->filter_mode & 2) ? 2 : (cx->temporal_strength ? 1 : 0);
- ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
- s->handle, 0, mode, cx->temporal_strength);
- ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
- s->handle, 2, cx->filter_mode >> 2, 0);
- return ret;
-}
-
-int cx18_api_func(void *priv, u32 cmd, int in, int out,
- u32 data[CX2341X_MBOX_MAX_DATA])
-{
- struct cx18_stream *s = priv;
- struct cx18 *cx = s->cx;
-
- switch (cmd) {
- case CX2341X_ENC_SET_OUTPUT_PORT:
- return 0;
- case CX2341X_ENC_SET_FRAME_RATE:
- return cx18_vapi(cx, CX18_CPU_SET_VIDEO_IN, 6,
- s->handle, 0, 0, 0, 0, data[0]);
- case CX2341X_ENC_SET_FRAME_SIZE:
- return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RESOLUTION, 3,
- s->handle, data[1], data[0]);
- case CX2341X_ENC_SET_STREAM_TYPE:
- return cx18_vapi(cx, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 2,
- s->handle, data[0]);
- case CX2341X_ENC_SET_ASPECT_RATIO:
- return cx18_vapi(cx, CX18_CPU_SET_ASPECT_RATIO, 2,
- s->handle, data[0]);
-
- case CX2341X_ENC_SET_GOP_PROPERTIES:
- return cx18_vapi(cx, CX18_CPU_SET_GOP_STRUCTURE, 3,
- s->handle, data[0], data[1]);
- case CX2341X_ENC_SET_GOP_CLOSURE:
- return 0;
- case CX2341X_ENC_SET_AUDIO_PROPERTIES:
- return cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2,
- s->handle, data[0]);
- case CX2341X_ENC_MUTE_AUDIO:
- return cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2,
- s->handle, data[0]);
- case CX2341X_ENC_SET_BIT_RATE:
- return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RATE, 5,
- s->handle, data[0], data[1], data[2], data[3]);
- case CX2341X_ENC_MUTE_VIDEO:
- return cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
- s->handle, data[0]);
- case CX2341X_ENC_SET_FRAME_DROP_RATE:
- return cx18_vapi(cx, CX18_CPU_SET_SKIP_INPUT_FRAME, 2,
- s->handle, data[0]);
- case CX2341X_ENC_MISC:
- return cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 4,
- s->handle, data[0], data[1], data[2]);
- case CX2341X_ENC_SET_DNR_FILTER_MODE:
- cx->filter_mode = (data[0] & 3) | (data[1] << 2);
- return cx18_set_filter_param(s);
- case CX2341X_ENC_SET_DNR_FILTER_PROPS:
- cx->spatial_strength = data[0];
- cx->temporal_strength = data[1];
- return cx18_set_filter_param(s);
- case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE:
- return cx18_vapi(cx, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 3,
- s->handle, data[0], data[1]);
- case CX2341X_ENC_SET_CORING_LEVELS:
- return cx18_vapi(cx, CX18_CPU_SET_MEDIAN_CORING, 5,
- s->handle, data[0], data[1], data[2], data[3]);
- }
- CX18_WARN("Unknown cmd %x\n", cmd);
- return 0;
-}
-
-int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS],
- u32 cmd, int args, ...)
-{
- va_list ap;
- int i;
-
- va_start(ap, args);
- for (i = 0; i < args; i++)
- data[i] = va_arg(ap, u32);
- va_end(ap);
- return cx18_api(cx, cmd, args, data);
-}
-
-int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...)
-{
- u32 data[MAX_MB_ARGUMENTS];
- va_list ap;
- int i;
-
- if (cx == NULL) {
- CX18_ERR("cx == NULL (cmd=%x)\n", cmd);
- return 0;
- }
- if (args > MAX_MB_ARGUMENTS) {
- CX18_ERR("args too big (cmd=%x)\n", cmd);
- args = MAX_MB_ARGUMENTS;
- }
- va_start(ap, args);
- for (i = 0; i < args; i++)
- data[i] = va_arg(ap, u32);
- va_end(ap);
- return cx18_api(cx, cmd, args, data);
-}
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
deleted file mode 100644
index b63fdfaac49..00000000000
--- a/drivers/media/video/cx18/cx18-mailbox.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * cx18 mailbox functions
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#ifndef _CX18_MAILBOX_H_
-#define _CX18_MAILBOX_H_
-
-/* mailbox max args */
-#define MAX_MB_ARGUMENTS 6
-/* compatibility, should be same as the define in cx2341x.h */
-#define CX2341X_MBOX_MAX_DATA 16
-
-#define MB_RESERVED_HANDLE_0 0
-#define MB_RESERVED_HANDLE_1 0xFFFFFFFF
-
-#define APU 0
-#define CPU 1
-#define EPU 2
-#define HPU 3
-
-struct cx18;
-
-/*
- * This structure is used by CPU to provide completed MDL & buffers information.
- * Its structure is dictated by the layout of the SCB, required by the
- * firmware, but its definition needs to be here, instead of in cx18-scb.h,
- * for mailbox work order scheduling
- */
-struct cx18_mdl_ack {
- u32 id; /* ID of a completed MDL */
- u32 data_used; /* Total data filled in the MDL with 'id' */
-};
-
-/* The cx18_mailbox struct is the mailbox structure which is used for passing
- messages between processors */
-struct cx18_mailbox {
- /* The sender sets a handle in 'request' after he fills the command. The
- 'request' should be different than 'ack'. The sender, also, generates
- an interrupt on XPU2YPU_irq where XPU is the sender and YPU is the
- receiver. */
- u32 request;
- /* The receiver detects a new command when 'req' is different than 'ack'.
- He sets 'ack' to the same value as 'req' to clear the command. He, also,
- generates an interrupt on YPU2XPU_irq where XPU is the sender and YPU
- is the receiver. */
- u32 ack;
- u32 reserved[6];
- /* 'cmd' identifies the command. The list of these commands are in
- cx23418.h */
- u32 cmd;
- /* Each command can have up to 6 arguments */
- u32 args[MAX_MB_ARGUMENTS];
- /* The return code can be one of the codes in the file cx23418.h. If the
- command is completed successfully, the error will be ERR_SYS_SUCCESS.
- If it is pending, the code is ERR_SYS_PENDING. If it failed, the error
- code would indicate the task from which the error originated and will
- be one of the errors in cx23418.h. In that case, the following
- applies ((error & 0xff) != 0).
- If the command is pending, the return will be passed in a MB from the
- receiver to the sender. 'req' will be returned in args[0] */
- u32 error;
-};
-
-struct cx18_stream;
-
-int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]);
-int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS], u32 cmd,
- int args, ...);
-int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...);
-int cx18_api_func(void *priv, u32 cmd, int in, int out,
- u32 data[CX2341X_MBOX_MAX_DATA]);
-
-void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu);
-
-void cx18_in_work_handler(struct work_struct *work);
-
-#endif
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
deleted file mode 100644
index 8884537bd62..00000000000
--- a/drivers/media/video/cx18/cx18-queue.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * cx18 buffer queues
- *
- * Derived from ivtv-queue.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-queue.h"
-#include "cx18-streams.h"
-#include "cx18-scb.h"
-#include "cx18-io.h"
-
-void cx18_buf_swap(struct cx18_buffer *buf)
-{
- int i;
-
- for (i = 0; i < buf->bytesused; i += 4)
- swab32s((u32 *)(buf->buf + i));
-}
-
-void _cx18_mdl_swap(struct cx18_mdl *mdl)
-{
- struct cx18_buffer *buf;
-
- list_for_each_entry(buf, &mdl->buf_list, list) {
- if (buf->bytesused == 0)
- break;
- cx18_buf_swap(buf);
- }
-}
-
-void cx18_queue_init(struct cx18_queue *q)
-{
- INIT_LIST_HEAD(&q->list);
- atomic_set(&q->depth, 0);
- q->bytesused = 0;
-}
-
-struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
- struct cx18_queue *q, int to_front)
-{
- /* clear the mdl if it is not to be enqueued to the full queue */
- if (q != &s->q_full) {
- mdl->bytesused = 0;
- mdl->readpos = 0;
- mdl->m_flags = 0;
- mdl->skipped = 0;
- mdl->curr_buf = NULL;
- }
-
- /* q_busy is restricted to a max buffer count imposed by firmware */
- if (q == &s->q_busy &&
- atomic_read(&q->depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
- q = &s->q_free;
-
- spin_lock(&q->lock);
-
- if (to_front)
- list_add(&mdl->list, &q->list); /* LIFO */
- else
- list_add_tail(&mdl->list, &q->list); /* FIFO */
- q->bytesused += mdl->bytesused - mdl->readpos;
- atomic_inc(&q->depth);
-
- spin_unlock(&q->lock);
- return q;
-}
-
-struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
-{
- struct cx18_mdl *mdl = NULL;
-
- spin_lock(&q->lock);
- if (!list_empty(&q->list)) {
- mdl = list_first_entry(&q->list, struct cx18_mdl, list);
- list_del_init(&mdl->list);
- q->bytesused -= mdl->bytesused - mdl->readpos;
- mdl->skipped = 0;
- atomic_dec(&q->depth);
- }
- spin_unlock(&q->lock);
- return mdl;
-}
-
-static void _cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
- struct cx18_mdl *mdl)
-{
- struct cx18_buffer *buf;
- u32 buf_size = s->buf_size;
- u32 bytesused = mdl->bytesused;
-
- list_for_each_entry(buf, &mdl->buf_list, list) {
- buf->readpos = 0;
- if (bytesused >= buf_size) {
- buf->bytesused = buf_size;
- bytesused -= buf_size;
- } else {
- buf->bytesused = bytesused;
- bytesused = 0;
- }
- cx18_buf_sync_for_cpu(s, buf);
- }
-}
-
-static inline void cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
- struct cx18_mdl *mdl)
-{
- struct cx18_buffer *buf;
-
- if (list_is_singular(&mdl->buf_list)) {
- buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
- list);
- buf->bytesused = mdl->bytesused;
- buf->readpos = 0;
- cx18_buf_sync_for_cpu(s, buf);
- } else {
- _cx18_mdl_update_bufs_for_cpu(s, mdl);
- }
-}
-
-struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
- u32 bytesused)
-{
- struct cx18 *cx = s->cx;
- struct cx18_mdl *mdl;
- struct cx18_mdl *tmp;
- struct cx18_mdl *ret = NULL;
- LIST_HEAD(sweep_up);
-
- /*
- * We don't have to acquire multiple q locks here, because we are
- * serialized by the single threaded work handler.
- * MDLs from the firmware will thus remain in order as
- * they are moved from q_busy to q_full or to the dvb ring buffer.
- */
- spin_lock(&s->q_busy.lock);
- list_for_each_entry_safe(mdl, tmp, &s->q_busy.list, list) {
- /*
- * We should find what the firmware told us is done,
- * right at the front of the queue. If we don't, we likely have
- * missed an mdl done message from the firmware.
- * Once we skip an mdl repeatedly, relative to the size of
- * q_busy, we have high confidence we've missed it.
- */
- if (mdl->id != id) {
- mdl->skipped++;
- if (mdl->skipped >= atomic_read(&s->q_busy.depth)-1) {
- /* mdl must have fallen out of rotation */
- CX18_WARN("Skipped %s, MDL %d, %d "
- "times - it must have dropped out of "
- "rotation\n", s->name, mdl->id,
- mdl->skipped);
- /* Sweep it up to put it back into rotation */
- list_move_tail(&mdl->list, &sweep_up);
- atomic_dec(&s->q_busy.depth);
- }
- continue;
- }
- /*
- * We pull the desired mdl off of the queue here. Something
- * will have to put it back on a queue later.
- */
- list_del_init(&mdl->list);
- atomic_dec(&s->q_busy.depth);
- ret = mdl;
- break;
- }
- spin_unlock(&s->q_busy.lock);
-
- /*
- * We found the mdl for which we were looking. Get it ready for
- * the caller to put on q_full or in the dvb ring buffer.
- */
- if (ret != NULL) {
- ret->bytesused = bytesused;
- ret->skipped = 0;
- /* 0'ed readpos, m_flags & curr_buf when mdl went on q_busy */
- cx18_mdl_update_bufs_for_cpu(s, ret);
- if (s->type != CX18_ENC_STREAM_TYPE_TS)
- set_bit(CX18_F_M_NEED_SWAP, &ret->m_flags);
- }
-
- /* Put any mdls the firmware is ignoring back into normal rotation */
- list_for_each_entry_safe(mdl, tmp, &sweep_up, list) {
- list_del_init(&mdl->list);
- cx18_enqueue(s, mdl, &s->q_free);
- }
- return ret;
-}
-
-/* Move all mdls of a queue, while flushing the mdl */
-static void cx18_queue_flush(struct cx18_stream *s,
- struct cx18_queue *q_src, struct cx18_queue *q_dst)
-{
- struct cx18_mdl *mdl;
-
- /* It only makes sense to flush to q_free or q_idle */
- if (q_src == q_dst || q_dst == &s->q_full || q_dst == &s->q_busy)
- return;
-
- spin_lock(&q_src->lock);
- spin_lock(&q_dst->lock);
- while (!list_empty(&q_src->list)) {
- mdl = list_first_entry(&q_src->list, struct cx18_mdl, list);
- list_move_tail(&mdl->list, &q_dst->list);
- mdl->bytesused = 0;
- mdl->readpos = 0;
- mdl->m_flags = 0;
- mdl->skipped = 0;
- mdl->curr_buf = NULL;
- atomic_inc(&q_dst->depth);
- }
- cx18_queue_init(q_src);
- spin_unlock(&q_src->lock);
- spin_unlock(&q_dst->lock);
-}
-
-void cx18_flush_queues(struct cx18_stream *s)
-{
- cx18_queue_flush(s, &s->q_busy, &s->q_free);
- cx18_queue_flush(s, &s->q_full, &s->q_free);
-}
-
-/*
- * Note, s->buf_pool is not protected by a lock,
- * the stream better not have *anything* going on when calling this
- */
-void cx18_unload_queues(struct cx18_stream *s)
-{
- struct cx18_queue *q_idle = &s->q_idle;
- struct cx18_mdl *mdl;
- struct cx18_buffer *buf;
-
- /* Move all MDLS to q_idle */
- cx18_queue_flush(s, &s->q_busy, q_idle);
- cx18_queue_flush(s, &s->q_full, q_idle);
- cx18_queue_flush(s, &s->q_free, q_idle);
-
- /* Reset MDL id's and move all buffers back to the stream's buf_pool */
- spin_lock(&q_idle->lock);
- list_for_each_entry(mdl, &q_idle->list, list) {
- while (!list_empty(&mdl->buf_list)) {
- buf = list_first_entry(&mdl->buf_list,
- struct cx18_buffer, list);
- list_move_tail(&buf->list, &s->buf_pool);
- buf->bytesused = 0;
- buf->readpos = 0;
- }
- mdl->id = s->mdl_base_idx; /* reset id to a "safe" value */
- /* all other mdl fields were cleared by cx18_queue_flush() */
- }
- spin_unlock(&q_idle->lock);
-}
-
-/*
- * Note, s->buf_pool is not protected by a lock,
- * the stream better not have *anything* going on when calling this
- */
-void cx18_load_queues(struct cx18_stream *s)
-{
- struct cx18 *cx = s->cx;
- struct cx18_mdl *mdl;
- struct cx18_buffer *buf;
- int mdl_id;
- int i;
- u32 partial_buf_size;
-
- /*
- * Attach buffers to MDLs, give the MDLs ids, and add MDLs to q_free
- * Excess MDLs are left on q_idle
- * Excess buffers are left in buf_pool and/or on an MDL in q_idle
- */
- mdl_id = s->mdl_base_idx;
- for (mdl = cx18_dequeue(s, &s->q_idle), i = s->bufs_per_mdl;
- mdl != NULL && i == s->bufs_per_mdl;
- mdl = cx18_dequeue(s, &s->q_idle)) {
-
- mdl->id = mdl_id;
-
- for (i = 0; i < s->bufs_per_mdl; i++) {
- if (list_empty(&s->buf_pool))
- break;
-
- buf = list_first_entry(&s->buf_pool, struct cx18_buffer,
- list);
- list_move_tail(&buf->list, &mdl->buf_list);
-
- /* update the firmware's MDL array with this buffer */
- cx18_writel(cx, buf->dma_handle,
- &cx->scb->cpu_mdl[mdl_id + i].paddr);
- cx18_writel(cx, s->buf_size,
- &cx->scb->cpu_mdl[mdl_id + i].length);
- }
-
- if (i == s->bufs_per_mdl) {
- /*
- * The encoder doesn't honor s->mdl_size. So in the
- * case of a non-integral number of buffers to meet
- * mdl_size, we lie about the size of the last buffer
- * in the MDL to get the encoder to really only send
- * us mdl_size bytes per MDL transfer.
- */
- partial_buf_size = s->mdl_size % s->buf_size;
- if (partial_buf_size) {
- cx18_writel(cx, partial_buf_size,
- &cx->scb->cpu_mdl[mdl_id + i - 1].length);
- }
- cx18_enqueue(s, mdl, &s->q_free);
- } else {
- /* Not enough buffers for this MDL; we won't use it */
- cx18_push(s, mdl, &s->q_idle);
- }
- mdl_id += i;
- }
-}
-
-void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl)
-{
- int dma = s->dma;
- u32 buf_size = s->buf_size;
- struct pci_dev *pci_dev = s->cx->pci_dev;
- struct cx18_buffer *buf;
-
- list_for_each_entry(buf, &mdl->buf_list, list)
- pci_dma_sync_single_for_device(pci_dev, buf->dma_handle,
- buf_size, dma);
-}
-
-int cx18_stream_alloc(struct cx18_stream *s)
-{
- struct cx18 *cx = s->cx;
- int i;
-
- if (s->buffers == 0)
- return 0;
-
- CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers "
- "(%d.%02d kB total)\n",
- s->name, s->buffers, s->buf_size,
- s->buffers * s->buf_size / 1024,
- (s->buffers * s->buf_size * 100 / 1024) % 100);
-
- if (((char __iomem *)&cx->scb->cpu_mdl[cx->free_mdl_idx + s->buffers] -
- (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) {
- unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE -
- ((char __iomem *)cx->scb->cpu_mdl));
-
- CX18_ERR("Too many buffers, cannot fit in SCB area\n");
- CX18_ERR("Max buffers = %zd\n",
- bufsz / sizeof(struct cx18_mdl_ent));
- return -ENOMEM;
- }
-
- s->mdl_base_idx = cx->free_mdl_idx;
-
- /* allocate stream buffers and MDLs */
- for (i = 0; i < s->buffers; i++) {
- struct cx18_mdl *mdl;
- struct cx18_buffer *buf;
-
- /* 1 MDL per buffer to handle the worst & also default case */
- mdl = kzalloc(sizeof(struct cx18_mdl), GFP_KERNEL|__GFP_NOWARN);
- if (mdl == NULL)
- break;
-
- buf = kzalloc(sizeof(struct cx18_buffer),
- GFP_KERNEL|__GFP_NOWARN);
- if (buf == NULL) {
- kfree(mdl);
- break;
- }
-
- buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
- if (buf->buf == NULL) {
- kfree(mdl);
- kfree(buf);
- break;
- }
-
- INIT_LIST_HEAD(&mdl->list);
- INIT_LIST_HEAD(&mdl->buf_list);
- mdl->id = s->mdl_base_idx; /* a somewhat safe value */
- cx18_enqueue(s, mdl, &s->q_idle);
-
- INIT_LIST_HEAD(&buf->list);
- buf->dma_handle = pci_map_single(s->cx->pci_dev,
- buf->buf, s->buf_size, s->dma);
- cx18_buf_sync_for_cpu(s, buf);
- list_add_tail(&buf->list, &s->buf_pool);
- }
- if (i == s->buffers) {
- cx->free_mdl_idx += s->buffers;
- return 0;
- }
- CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name);
- cx18_stream_free(s);
- return -ENOMEM;
-}
-
-void cx18_stream_free(struct cx18_stream *s)
-{
- struct cx18_mdl *mdl;
- struct cx18_buffer *buf;
- struct cx18 *cx = s->cx;
-
- CX18_DEBUG_INFO("Deallocating buffers for %s stream\n", s->name);
-
- /* move all buffers to buf_pool and all MDLs to q_idle */
- cx18_unload_queues(s);
-
- /* empty q_idle */
- while ((mdl = cx18_dequeue(s, &s->q_idle)))
- kfree(mdl);
-
- /* empty buf_pool */
- while (!list_empty(&s->buf_pool)) {
- buf = list_first_entry(&s->buf_pool, struct cx18_buffer, list);
- list_del_init(&buf->list);
-
- pci_unmap_single(s->cx->pci_dev, buf->dma_handle,
- s->buf_size, s->dma);
- kfree(buf->buf);
- kfree(buf);
- }
-}
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
deleted file mode 100644
index 4201ddc1609..00000000000
--- a/drivers/media/video/cx18/cx18-queue.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * cx18 buffer queues
- *
- * Derived from ivtv-queue.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#define CX18_DMA_UNMAPPED ((u32) -1)
-
-/* cx18_buffer utility functions */
-
-static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s,
- struct cx18_buffer *buf)
-{
- pci_dma_sync_single_for_cpu(s->cx->pci_dev, buf->dma_handle,
- s->buf_size, s->dma);
-}
-
-static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
- struct cx18_buffer *buf)
-{
- pci_dma_sync_single_for_device(s->cx->pci_dev, buf->dma_handle,
- s->buf_size, s->dma);
-}
-
-void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl);
-
-static inline void cx18_mdl_sync_for_device(struct cx18_stream *s,
- struct cx18_mdl *mdl)
-{
- if (list_is_singular(&mdl->buf_list))
- cx18_buf_sync_for_device(s, list_first_entry(&mdl->buf_list,
- struct cx18_buffer,
- list));
- else
- _cx18_mdl_sync_for_device(s, mdl);
-}
-
-void cx18_buf_swap(struct cx18_buffer *buf);
-void _cx18_mdl_swap(struct cx18_mdl *mdl);
-
-static inline void cx18_mdl_swap(struct cx18_mdl *mdl)
-{
- if (list_is_singular(&mdl->buf_list))
- cx18_buf_swap(list_first_entry(&mdl->buf_list,
- struct cx18_buffer, list));
- else
- _cx18_mdl_swap(mdl);
-}
-
-/* cx18_queue utility functions */
-struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
- struct cx18_queue *q, int to_front);
-
-static inline
-struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
- struct cx18_queue *q)
-{
- return _cx18_enqueue(s, mdl, q, 0); /* FIFO */
-}
-
-static inline
-struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_mdl *mdl,
- struct cx18_queue *q)
-{
- return _cx18_enqueue(s, mdl, q, 1); /* LIFO */
-}
-
-void cx18_queue_init(struct cx18_queue *q);
-struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
-struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
- u32 bytesused);
-void cx18_flush_queues(struct cx18_stream *s);
-
-/* queue MDL reconfiguration helpers */
-void cx18_unload_queues(struct cx18_stream *s);
-void cx18_load_queues(struct cx18_stream *s);
-
-/* cx18_stream utility functions */
-int cx18_stream_alloc(struct cx18_stream *s);
-void cx18_stream_free(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-scb.c b/drivers/media/video/cx18/cx18-scb.c
deleted file mode 100644
index 85cc59637e5..00000000000
--- a/drivers/media/video/cx18/cx18-scb.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * cx18 System Control Block initialization
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-scb.h"
-
-void cx18_init_scb(struct cx18 *cx)
-{
- cx18_setup_page(cx, SCB_OFFSET);
- cx18_memset_io(cx, cx->scb, 0, 0x10000);
-
- cx18_writel(cx, IRQ_APU_TO_CPU, &cx->scb->apu2cpu_irq);
- cx18_writel(cx, IRQ_CPU_TO_APU_ACK, &cx->scb->cpu2apu_irq_ack);
- cx18_writel(cx, IRQ_HPU_TO_CPU, &cx->scb->hpu2cpu_irq);
- cx18_writel(cx, IRQ_CPU_TO_HPU_ACK, &cx->scb->cpu2hpu_irq_ack);
- cx18_writel(cx, IRQ_PPU_TO_CPU, &cx->scb->ppu2cpu_irq);
- cx18_writel(cx, IRQ_CPU_TO_PPU_ACK, &cx->scb->cpu2ppu_irq_ack);
- cx18_writel(cx, IRQ_EPU_TO_CPU, &cx->scb->epu2cpu_irq);
- cx18_writel(cx, IRQ_CPU_TO_EPU_ACK, &cx->scb->cpu2epu_irq_ack);
-
- cx18_writel(cx, IRQ_CPU_TO_APU, &cx->scb->cpu2apu_irq);
- cx18_writel(cx, IRQ_APU_TO_CPU_ACK, &cx->scb->apu2cpu_irq_ack);
- cx18_writel(cx, IRQ_HPU_TO_APU, &cx->scb->hpu2apu_irq);
- cx18_writel(cx, IRQ_APU_TO_HPU_ACK, &cx->scb->apu2hpu_irq_ack);
- cx18_writel(cx, IRQ_PPU_TO_APU, &cx->scb->ppu2apu_irq);
- cx18_writel(cx, IRQ_APU_TO_PPU_ACK, &cx->scb->apu2ppu_irq_ack);
- cx18_writel(cx, IRQ_EPU_TO_APU, &cx->scb->epu2apu_irq);
- cx18_writel(cx, IRQ_APU_TO_EPU_ACK, &cx->scb->apu2epu_irq_ack);
-
- cx18_writel(cx, IRQ_CPU_TO_HPU, &cx->scb->cpu2hpu_irq);
- cx18_writel(cx, IRQ_HPU_TO_CPU_ACK, &cx->scb->hpu2cpu_irq_ack);
- cx18_writel(cx, IRQ_APU_TO_HPU, &cx->scb->apu2hpu_irq);
- cx18_writel(cx, IRQ_HPU_TO_APU_ACK, &cx->scb->hpu2apu_irq_ack);
- cx18_writel(cx, IRQ_PPU_TO_HPU, &cx->scb->ppu2hpu_irq);
- cx18_writel(cx, IRQ_HPU_TO_PPU_ACK, &cx->scb->hpu2ppu_irq_ack);
- cx18_writel(cx, IRQ_EPU_TO_HPU, &cx->scb->epu2hpu_irq);
- cx18_writel(cx, IRQ_HPU_TO_EPU_ACK, &cx->scb->hpu2epu_irq_ack);
-
- cx18_writel(cx, IRQ_CPU_TO_PPU, &cx->scb->cpu2ppu_irq);
- cx18_writel(cx, IRQ_PPU_TO_CPU_ACK, &cx->scb->ppu2cpu_irq_ack);
- cx18_writel(cx, IRQ_APU_TO_PPU, &cx->scb->apu2ppu_irq);
- cx18_writel(cx, IRQ_PPU_TO_APU_ACK, &cx->scb->ppu2apu_irq_ack);
- cx18_writel(cx, IRQ_HPU_TO_PPU, &cx->scb->hpu2ppu_irq);
- cx18_writel(cx, IRQ_PPU_TO_HPU_ACK, &cx->scb->ppu2hpu_irq_ack);
- cx18_writel(cx, IRQ_EPU_TO_PPU, &cx->scb->epu2ppu_irq);
- cx18_writel(cx, IRQ_PPU_TO_EPU_ACK, &cx->scb->ppu2epu_irq_ack);
-
- cx18_writel(cx, IRQ_CPU_TO_EPU, &cx->scb->cpu2epu_irq);
- cx18_writel(cx, IRQ_EPU_TO_CPU_ACK, &cx->scb->epu2cpu_irq_ack);
- cx18_writel(cx, IRQ_APU_TO_EPU, &cx->scb->apu2epu_irq);
- cx18_writel(cx, IRQ_EPU_TO_APU_ACK, &cx->scb->epu2apu_irq_ack);
- cx18_writel(cx, IRQ_HPU_TO_EPU, &cx->scb->hpu2epu_irq);
- cx18_writel(cx, IRQ_EPU_TO_HPU_ACK, &cx->scb->epu2hpu_irq_ack);
- cx18_writel(cx, IRQ_PPU_TO_EPU, &cx->scb->ppu2epu_irq);
- cx18_writel(cx, IRQ_EPU_TO_PPU_ACK, &cx->scb->epu2ppu_irq_ack);
-
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2cpu_mb),
- &cx->scb->apu2cpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2cpu_mb),
- &cx->scb->hpu2cpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2cpu_mb),
- &cx->scb->ppu2cpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2cpu_mb),
- &cx->scb->epu2cpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2apu_mb),
- &cx->scb->cpu2apu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2apu_mb),
- &cx->scb->hpu2apu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2apu_mb),
- &cx->scb->ppu2apu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2apu_mb),
- &cx->scb->epu2apu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2hpu_mb),
- &cx->scb->cpu2hpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2hpu_mb),
- &cx->scb->apu2hpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2hpu_mb),
- &cx->scb->ppu2hpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2hpu_mb),
- &cx->scb->epu2hpu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2ppu_mb),
- &cx->scb->cpu2ppu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2ppu_mb),
- &cx->scb->apu2ppu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2ppu_mb),
- &cx->scb->hpu2ppu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2ppu_mb),
- &cx->scb->epu2ppu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2epu_mb),
- &cx->scb->cpu2epu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2epu_mb),
- &cx->scb->apu2epu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2epu_mb),
- &cx->scb->hpu2epu_mb_offset);
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2epu_mb),
- &cx->scb->ppu2epu_mb_offset);
-
- cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu_state),
- &cx->scb->ipc_offset);
-
- cx18_writel(cx, 1, &cx->scb->epu_state);
-}
diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h
deleted file mode 100644
index 08877652e32..00000000000
--- a/drivers/media/video/cx18/cx18-scb.h
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * cx18 System Control Block initialization
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#ifndef CX18_SCB_H
-#define CX18_SCB_H
-
-#include "cx18-mailbox.h"
-
-/* NOTE: All ACK interrupts are in the SW2 register. All non-ACK interrupts
- are in the SW1 register. */
-
-#define IRQ_APU_TO_CPU 0x00000001
-#define IRQ_CPU_TO_APU_ACK 0x00000001
-#define IRQ_HPU_TO_CPU 0x00000002
-#define IRQ_CPU_TO_HPU_ACK 0x00000002
-#define IRQ_PPU_TO_CPU 0x00000004
-#define IRQ_CPU_TO_PPU_ACK 0x00000004
-#define IRQ_EPU_TO_CPU 0x00000008
-#define IRQ_CPU_TO_EPU_ACK 0x00000008
-
-#define IRQ_CPU_TO_APU 0x00000010
-#define IRQ_APU_TO_CPU_ACK 0x00000010
-#define IRQ_HPU_TO_APU 0x00000020
-#define IRQ_APU_TO_HPU_ACK 0x00000020
-#define IRQ_PPU_TO_APU 0x00000040
-#define IRQ_APU_TO_PPU_ACK 0x00000040
-#define IRQ_EPU_TO_APU 0x00000080
-#define IRQ_APU_TO_EPU_ACK 0x00000080
-
-#define IRQ_CPU_TO_HPU 0x00000100
-#define IRQ_HPU_TO_CPU_ACK 0x00000100
-#define IRQ_APU_TO_HPU 0x00000200
-#define IRQ_HPU_TO_APU_ACK 0x00000200
-#define IRQ_PPU_TO_HPU 0x00000400
-#define IRQ_HPU_TO_PPU_ACK 0x00000400
-#define IRQ_EPU_TO_HPU 0x00000800
-#define IRQ_HPU_TO_EPU_ACK 0x00000800
-
-#define IRQ_CPU_TO_PPU 0x00001000
-#define IRQ_PPU_TO_CPU_ACK 0x00001000
-#define IRQ_APU_TO_PPU 0x00002000
-#define IRQ_PPU_TO_APU_ACK 0x00002000
-#define IRQ_HPU_TO_PPU 0x00004000
-#define IRQ_PPU_TO_HPU_ACK 0x00004000
-#define IRQ_EPU_TO_PPU 0x00008000
-#define IRQ_PPU_TO_EPU_ACK 0x00008000
-
-#define IRQ_CPU_TO_EPU 0x00010000
-#define IRQ_EPU_TO_CPU_ACK 0x00010000
-#define IRQ_APU_TO_EPU 0x00020000
-#define IRQ_EPU_TO_APU_ACK 0x00020000
-#define IRQ_HPU_TO_EPU 0x00040000
-#define IRQ_EPU_TO_HPU_ACK 0x00040000
-#define IRQ_PPU_TO_EPU 0x00080000
-#define IRQ_EPU_TO_PPU_ACK 0x00080000
-
-#define SCB_OFFSET 0xDC0000
-
-/* If Firmware uses fixed memory map, it shall not allocate the area
- between SCB_OFFSET and SCB_OFFSET+SCB_RESERVED_SIZE-1 inclusive */
-#define SCB_RESERVED_SIZE 0x10000
-
-
-/* This structure is used by EPU to provide memory descriptors in its memory */
-struct cx18_mdl_ent {
- u32 paddr; /* Physical address of a buffer segment */
- u32 length; /* Length of the buffer segment */
-};
-
-struct cx18_scb {
- /* These fields form the System Control Block which is used at boot time
- for localizing the IPC data as well as the code positions for all
- processors. The offsets are from the start of this struct. */
-
- /* Offset where to find the Inter-Processor Communication data */
- u32 ipc_offset;
- u32 reserved01[7];
- /* Offset where to find the start of the CPU code */
- u32 cpu_code_offset;
- u32 reserved02[3];
- /* Offset where to find the start of the APU code */
- u32 apu_code_offset;
- u32 reserved03[3];
- /* Offset where to find the start of the HPU code */
- u32 hpu_code_offset;
- u32 reserved04[3];
- /* Offset where to find the start of the PPU code */
- u32 ppu_code_offset;
- u32 reserved05[3];
-
- /* These fields form Inter-Processor Communication data which is used
- by all processors to locate the information needed for communicating
- with other processors */
-
- /* Fields for CPU: */
-
- /* bit 0: 1/0 processor ready/not ready. Set other bits to 0. */
- u32 cpu_state;
- u32 reserved1[7];
- /* Offset to the mailbox used for sending commands from APU to CPU */
- u32 apu2cpu_mb_offset;
- /* Value to write to register SW1 register set (0xC7003100) after the
- command is ready */
- u32 apu2cpu_irq;
- /* Value to write to register SW2 register set (0xC7003140) after the
- command is cleared */
- u32 cpu2apu_irq_ack;
- u32 reserved2[13];
-
- u32 hpu2cpu_mb_offset;
- u32 hpu2cpu_irq;
- u32 cpu2hpu_irq_ack;
- u32 reserved3[13];
-
- u32 ppu2cpu_mb_offset;
- u32 ppu2cpu_irq;
- u32 cpu2ppu_irq_ack;
- u32 reserved4[13];
-
- u32 epu2cpu_mb_offset;
- u32 epu2cpu_irq;
- u32 cpu2epu_irq_ack;
- u32 reserved5[13];
- u32 reserved6[8];
-
- /* Fields for APU: */
-
- u32 apu_state;
- u32 reserved11[7];
- u32 cpu2apu_mb_offset;
- u32 cpu2apu_irq;
- u32 apu2cpu_irq_ack;
- u32 reserved12[13];
-
- u32 hpu2apu_mb_offset;
- u32 hpu2apu_irq;
- u32 apu2hpu_irq_ack;
- u32 reserved13[13];
-
- u32 ppu2apu_mb_offset;
- u32 ppu2apu_irq;
- u32 apu2ppu_irq_ack;
- u32 reserved14[13];
-
- u32 epu2apu_mb_offset;
- u32 epu2apu_irq;
- u32 apu2epu_irq_ack;
- u32 reserved15[13];
- u32 reserved16[8];
-
- /* Fields for HPU: */
-
- u32 hpu_state;
- u32 reserved21[7];
- u32 cpu2hpu_mb_offset;
- u32 cpu2hpu_irq;
- u32 hpu2cpu_irq_ack;
- u32 reserved22[13];
-
- u32 apu2hpu_mb_offset;
- u32 apu2hpu_irq;
- u32 hpu2apu_irq_ack;
- u32 reserved23[13];
-
- u32 ppu2hpu_mb_offset;
- u32 ppu2hpu_irq;
- u32 hpu2ppu_irq_ack;
- u32 reserved24[13];
-
- u32 epu2hpu_mb_offset;
- u32 epu2hpu_irq;
- u32 hpu2epu_irq_ack;
- u32 reserved25[13];
- u32 reserved26[8];
-
- /* Fields for PPU: */
-
- u32 ppu_state;
- u32 reserved31[7];
- u32 cpu2ppu_mb_offset;
- u32 cpu2ppu_irq;
- u32 ppu2cpu_irq_ack;
- u32 reserved32[13];
-
- u32 apu2ppu_mb_offset;
- u32 apu2ppu_irq;
- u32 ppu2apu_irq_ack;
- u32 reserved33[13];
-
- u32 hpu2ppu_mb_offset;
- u32 hpu2ppu_irq;
- u32 ppu2hpu_irq_ack;
- u32 reserved34[13];
-
- u32 epu2ppu_mb_offset;
- u32 epu2ppu_irq;
- u32 ppu2epu_irq_ack;
- u32 reserved35[13];
- u32 reserved36[8];
-
- /* Fields for EPU: */
-
- u32 epu_state;
- u32 reserved41[7];
- u32 cpu2epu_mb_offset;
- u32 cpu2epu_irq;
- u32 epu2cpu_irq_ack;
- u32 reserved42[13];
-
- u32 apu2epu_mb_offset;
- u32 apu2epu_irq;
- u32 epu2apu_irq_ack;
- u32 reserved43[13];
-
- u32 hpu2epu_mb_offset;
- u32 hpu2epu_irq;
- u32 epu2hpu_irq_ack;
- u32 reserved44[13];
-
- u32 ppu2epu_mb_offset;
- u32 ppu2epu_irq;
- u32 epu2ppu_irq_ack;
- u32 reserved45[13];
- u32 reserved46[8];
-
- u32 semaphores[8]; /* Semaphores */
-
- u32 reserved50[32]; /* Reserved for future use */
-
- struct cx18_mailbox apu2cpu_mb;
- struct cx18_mailbox hpu2cpu_mb;
- struct cx18_mailbox ppu2cpu_mb;
- struct cx18_mailbox epu2cpu_mb;
-
- struct cx18_mailbox cpu2apu_mb;
- struct cx18_mailbox hpu2apu_mb;
- struct cx18_mailbox ppu2apu_mb;
- struct cx18_mailbox epu2apu_mb;
-
- struct cx18_mailbox cpu2hpu_mb;
- struct cx18_mailbox apu2hpu_mb;
- struct cx18_mailbox ppu2hpu_mb;
- struct cx18_mailbox epu2hpu_mb;
-
- struct cx18_mailbox cpu2ppu_mb;
- struct cx18_mailbox apu2ppu_mb;
- struct cx18_mailbox hpu2ppu_mb;
- struct cx18_mailbox epu2ppu_mb;
-
- struct cx18_mailbox cpu2epu_mb;
- struct cx18_mailbox apu2epu_mb;
- struct cx18_mailbox hpu2epu_mb;
- struct cx18_mailbox ppu2epu_mb;
-
- struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][CX18_MAX_MDL_ACKS];
- struct cx18_mdl_ent cpu_mdl[1];
-};
-
-void cx18_init_scb(struct cx18 *cx);
-
-#endif
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
deleted file mode 100644
index 9d598ab8861..00000000000
--- a/drivers/media/video/cx18/cx18-streams.c
+++ /dev/null
@@ -1,1060 +0,0 @@
-/*
- * cx18 init/start/stop/exit stream functions
- *
- * Derived from ivtv-streams.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-io.h"
-#include "cx18-fileops.h"
-#include "cx18-mailbox.h"
-#include "cx18-i2c.h"
-#include "cx18-queue.h"
-#include "cx18-ioctl.h"
-#include "cx18-streams.h"
-#include "cx18-cards.h"
-#include "cx18-scb.h"
-#include "cx18-dvb.h"
-
-#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
-
-static struct v4l2_file_operations cx18_v4l2_enc_fops = {
- .owner = THIS_MODULE,
- .read = cx18_v4l2_read,
- .open = cx18_v4l2_open,
- .unlocked_ioctl = video_ioctl2,
- .release = cx18_v4l2_close,
- .poll = cx18_v4l2_enc_poll,
- .mmap = cx18_v4l2_mmap,
-};
-
-/* offset from 0 to register ts v4l2 minors on */
-#define CX18_V4L2_ENC_TS_OFFSET 16
-/* offset from 0 to register pcm v4l2 minors on */
-#define CX18_V4L2_ENC_PCM_OFFSET 24
-/* offset from 0 to register yuv v4l2 minors on */
-#define CX18_V4L2_ENC_YUV_OFFSET 32
-
-static struct {
- const char *name;
- int vfl_type;
- int num_offset;
- int dma;
- enum v4l2_buf_type buf_type;
-} cx18_stream_info[] = {
- { /* CX18_ENC_STREAM_TYPE_MPG */
- "encoder MPEG",
- VFL_TYPE_GRABBER, 0,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- },
- { /* CX18_ENC_STREAM_TYPE_TS */
- "TS",
- VFL_TYPE_GRABBER, -1,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- },
- { /* CX18_ENC_STREAM_TYPE_YUV */
- "encoder YUV",
- VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- },
- { /* CX18_ENC_STREAM_TYPE_VBI */
- "encoder VBI",
- VFL_TYPE_VBI, 0,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VBI_CAPTURE,
- },
- { /* CX18_ENC_STREAM_TYPE_PCM */
- "encoder PCM audio",
- VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_PRIVATE,
- },
- { /* CX18_ENC_STREAM_TYPE_IDX */
- "encoder IDX",
- VFL_TYPE_GRABBER, -1,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- },
- { /* CX18_ENC_STREAM_TYPE_RAD */
- "encoder radio",
- VFL_TYPE_RADIO, 0,
- PCI_DMA_NONE, V4L2_BUF_TYPE_PRIVATE,
- },
-};
-
-
-void cx18_dma_free(struct videobuf_queue *q,
- struct cx18_stream *s, struct cx18_videobuf_buffer *buf)
-{
- videobuf_waiton(q, &buf->vb, 0, 0);
- videobuf_vmalloc_free(&buf->vb);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int cx18_prepare_buffer(struct videobuf_queue *q,
- struct cx18_stream *s,
- struct cx18_videobuf_buffer *buf,
- u32 pixelformat,
- unsigned int width, unsigned int height,
- enum v4l2_field field)
-{
- struct cx18 *cx = s->cx;
- int rc = 0;
-
- /* check settings */
- buf->bytes_used = 0;
-
- if ((width < 48) || (height < 32))
- return -EINVAL;
-
- buf->vb.size = (width * height * 2);
- if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
- return -EINVAL;
-
- /* alloc + fill struct (if changed) */
- if (buf->vb.width != width || buf->vb.height != height ||
- buf->vb.field != field || s->pixelformat != pixelformat ||
- buf->tvnorm != cx->std) {
-
- buf->vb.width = width;
- buf->vb.height = height;
- buf->vb.field = field;
- buf->tvnorm = cx->std;
- s->pixelformat = pixelformat;
-
- /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
- UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
- if (s->pixelformat == V4L2_PIX_FMT_HM12)
- s->vb_bytes_per_frame = height * 720 * 3 / 2;
- else
- s->vb_bytes_per_frame = height * 720 * 2;
- cx18_dma_free(q, s, buf);
- }
-
- if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
- return -EINVAL;
-
- if (buf->vb.field == 0)
- buf->vb.field = V4L2_FIELD_INTERLACED;
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- buf->vb.width = width;
- buf->vb.height = height;
- buf->vb.field = field;
- buf->tvnorm = cx->std;
- s->pixelformat = pixelformat;
-
- /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
- UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
- if (s->pixelformat == V4L2_PIX_FMT_HM12)
- s->vb_bytes_per_frame = height * 720 * 3 / 2;
- else
- s->vb_bytes_per_frame = height * 720 * 2;
- rc = videobuf_iolock(q, &buf->vb, NULL);
- if (rc != 0)
- goto fail;
- }
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
-fail:
- cx18_dma_free(q, s, buf);
- return rc;
-
-}
-
-/* VB_MIN_BUFSIZE is lcm(1440 * 480, 1440 * 576)
- 1440 is a single line of 4:2:2 YUV at 720 luma samples wide
-*/
-#define VB_MIN_BUFFERS 32
-#define VB_MIN_BUFSIZE 4147200
-
-static int buffer_setup(struct videobuf_queue *q,
- unsigned int *count, unsigned int *size)
-{
- struct cx18_stream *s = q->priv_data;
- struct cx18 *cx = s->cx;
-
- *size = 2 * cx->cxhdl.width * cx->cxhdl.height;
- if (*count == 0)
- *count = VB_MIN_BUFFERS;
-
- while (*size * *count > VB_MIN_BUFFERS * VB_MIN_BUFSIZE)
- (*count)--;
-
- q->field = V4L2_FIELD_INTERLACED;
- q->last = V4L2_FIELD_INTERLACED;
-
- return 0;
-}
-
-static int buffer_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct cx18_videobuf_buffer *buf =
- container_of(vb, struct cx18_videobuf_buffer, vb);
- struct cx18_stream *s = q->priv_data;
- struct cx18 *cx = s->cx;
-
- return cx18_prepare_buffer(q, s, buf, s->pixelformat,
- cx->cxhdl.width, cx->cxhdl.height, field);
-}
-
-static void buffer_release(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- struct cx18_videobuf_buffer *buf =
- container_of(vb, struct cx18_videobuf_buffer, vb);
- struct cx18_stream *s = q->priv_data;
-
- cx18_dma_free(q, s, buf);
-}
-
-static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct cx18_videobuf_buffer *buf =
- container_of(vb, struct cx18_videobuf_buffer, vb);
- struct cx18_stream *s = q->priv_data;
-
- buf->vb.state = VIDEOBUF_QUEUED;
-
- list_add_tail(&buf->vb.queue, &s->vb_capture);
-}
-
-static struct videobuf_queue_ops cx18_videobuf_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-static void cx18_stream_init(struct cx18 *cx, int type)
-{
- struct cx18_stream *s = &cx->streams[type];
- struct video_device *video_dev = s->video_dev;
-
- /* we need to keep video_dev, so restore it afterwards */
- memset(s, 0, sizeof(*s));
- s->video_dev = video_dev;
-
- /* initialize cx18_stream fields */
- s->dvb = NULL;
- s->cx = cx;
- s->type = type;
- s->name = cx18_stream_info[type].name;
- s->handle = CX18_INVALID_TASK_HANDLE;
-
- s->dma = cx18_stream_info[type].dma;
- s->buffers = cx->stream_buffers[type];
- s->buf_size = cx->stream_buf_size[type];
- INIT_LIST_HEAD(&s->buf_pool);
- s->bufs_per_mdl = 1;
- s->mdl_size = s->buf_size * s->bufs_per_mdl;
-
- init_waitqueue_head(&s->waitq);
- s->id = -1;
- spin_lock_init(&s->q_free.lock);
- cx18_queue_init(&s->q_free);
- spin_lock_init(&s->q_busy.lock);
- cx18_queue_init(&s->q_busy);
- spin_lock_init(&s->q_full.lock);
- cx18_queue_init(&s->q_full);
- spin_lock_init(&s->q_idle.lock);
- cx18_queue_init(&s->q_idle);
-
- INIT_WORK(&s->out_work_order, cx18_out_work_handler);
-
- INIT_LIST_HEAD(&s->vb_capture);
- s->vb_timeout.function = cx18_vb_timeout;
- s->vb_timeout.data = (unsigned long)s;
- init_timer(&s->vb_timeout);
- spin_lock_init(&s->vb_lock);
- if (type == CX18_ENC_STREAM_TYPE_YUV) {
- spin_lock_init(&s->vbuf_q_lock);
-
- s->vb_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- videobuf_queue_vmalloc_init(&s->vbuf_q, &cx18_videobuf_qops,
- &cx->pci_dev->dev, &s->vbuf_q_lock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx18_videobuf_buffer),
- s, &cx->serialize_lock);
-
- /* Assume the previous pixel default */
- s->pixelformat = V4L2_PIX_FMT_HM12;
- s->vb_bytes_per_frame = cx->cxhdl.height * 720 * 3 / 2;
- }
-}
-
-static int cx18_prep_dev(struct cx18 *cx, int type)
-{
- struct cx18_stream *s = &cx->streams[type];
- u32 cap = cx->v4l2_cap;
- int num_offset = cx18_stream_info[type].num_offset;
- int num = cx->instance + cx18_first_minor + num_offset;
-
- /*
- * These five fields are always initialized.
- * For analog capture related streams, if video_dev == NULL then the
- * stream is not in use.
- * For the TS stream, if dvb == NULL then the stream is not in use.
- * In those cases no other fields but these four can be used.
- */
- s->video_dev = NULL;
- s->dvb = NULL;
- s->cx = cx;
- s->type = type;
- s->name = cx18_stream_info[type].name;
-
- /* Check whether the radio is supported */
- if (type == CX18_ENC_STREAM_TYPE_RAD && !(cap & V4L2_CAP_RADIO))
- return 0;
-
- /* Check whether VBI is supported */
- if (type == CX18_ENC_STREAM_TYPE_VBI &&
- !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)))
- return 0;
-
- /* User explicitly selected 0 buffers for these streams, so don't
- create them. */
- if (cx18_stream_info[type].dma != PCI_DMA_NONE &&
- cx->stream_buffers[type] == 0) {
- CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name);
- return 0;
- }
-
- cx18_stream_init(cx, type);
-
- /* Allocate the cx18_dvb struct only for the TS on cards with DTV */
- if (type == CX18_ENC_STREAM_TYPE_TS) {
- if (cx->card->hw_all & CX18_HW_DVB) {
- s->dvb = kzalloc(sizeof(struct cx18_dvb), GFP_KERNEL);
- if (s->dvb == NULL) {
- CX18_ERR("Couldn't allocate cx18_dvb structure"
- " for %s\n", s->name);
- return -ENOMEM;
- }
- } else {
- /* Don't need buffers for the TS, if there is no DVB */
- s->buffers = 0;
- }
- }
-
- if (num_offset == -1)
- return 0;
-
- /* allocate and initialize the v4l2 video device structure */
- s->video_dev = video_device_alloc();
- if (s->video_dev == NULL) {
- CX18_ERR("Couldn't allocate v4l2 video_device for %s\n",
- s->name);
- return -ENOMEM;
- }
-
- snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s",
- cx->v4l2_dev.name, s->name);
-
- s->video_dev->num = num;
- s->video_dev->v4l2_dev = &cx->v4l2_dev;
- s->video_dev->fops = &cx18_v4l2_enc_fops;
- s->video_dev->release = video_device_release;
- s->video_dev->tvnorms = V4L2_STD_ALL;
- s->video_dev->lock = &cx->serialize_lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags);
- cx18_set_funcs(s->video_dev);
- return 0;
-}
-
-/* Initialize v4l2 variables and register v4l2 devices */
-int cx18_streams_setup(struct cx18 *cx)
-{
- int type, ret;
-
- /* Setup V4L2 Devices */
- for (type = 0; type < CX18_MAX_STREAMS; type++) {
- /* Prepare device */
- ret = cx18_prep_dev(cx, type);
- if (ret < 0)
- break;
-
- /* Allocate Stream */
- ret = cx18_stream_alloc(&cx->streams[type]);
- if (ret < 0)
- break;
- }
- if (type == CX18_MAX_STREAMS)
- return 0;
-
- /* One or more streams could not be initialized. Clean 'em all up. */
- cx18_streams_cleanup(cx, 0);
- return ret;
-}
-
-static int cx18_reg_dev(struct cx18 *cx, int type)
-{
- struct cx18_stream *s = &cx->streams[type];
- int vfl_type = cx18_stream_info[type].vfl_type;
- const char *name;
- int num, ret;
-
- if (type == CX18_ENC_STREAM_TYPE_TS && s->dvb != NULL) {
- ret = cx18_dvb_register(s);
- if (ret < 0) {
- CX18_ERR("DVB failed to register\n");
- return ret;
- }
- }
-
- if (s->video_dev == NULL)
- return 0;
-
- num = s->video_dev->num;
- /* card number + user defined offset + device offset */
- if (type != CX18_ENC_STREAM_TYPE_MPG) {
- struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
-
- if (s_mpg->video_dev)
- num = s_mpg->video_dev->num
- + cx18_stream_info[type].num_offset;
- }
- video_set_drvdata(s->video_dev, s);
-
- /* Register device. First try the desired minor, then any free one. */
- ret = video_register_device_no_warn(s->video_dev, vfl_type, num);
- if (ret < 0) {
- CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
- s->name, num);
- video_device_release(s->video_dev);
- s->video_dev = NULL;
- return ret;
- }
-
- name = video_device_node_name(s->video_dev);
-
- switch (vfl_type) {
- case VFL_TYPE_GRABBER:
- CX18_INFO("Registered device %s for %s (%d x %d.%02d kB)\n",
- name, s->name, cx->stream_buffers[type],
- cx->stream_buf_size[type] / 1024,
- (cx->stream_buf_size[type] * 100 / 1024) % 100);
- break;
-
- case VFL_TYPE_RADIO:
- CX18_INFO("Registered device %s for %s\n", name, s->name);
- break;
-
- case VFL_TYPE_VBI:
- if (cx->stream_buffers[type])
- CX18_INFO("Registered device %s for %s "
- "(%d x %d bytes)\n",
- name, s->name, cx->stream_buffers[type],
- cx->stream_buf_size[type]);
- else
- CX18_INFO("Registered device %s for %s\n",
- name, s->name);
- break;
- }
-
- return 0;
-}
-
-/* Register v4l2 devices */
-int cx18_streams_register(struct cx18 *cx)
-{
- int type;
- int err;
- int ret = 0;
-
- /* Register V4L2 devices */
- for (type = 0; type < CX18_MAX_STREAMS; type++) {
- err = cx18_reg_dev(cx, type);
- if (err && ret == 0)
- ret = err;
- }
-
- if (ret == 0)
- return 0;
-
- /* One or more streams could not be initialized. Clean 'em all up. */
- cx18_streams_cleanup(cx, 1);
- return ret;
-}
-
-/* Unregister v4l2 devices */
-void cx18_streams_cleanup(struct cx18 *cx, int unregister)
-{
- struct video_device *vdev;
- int type;
-
- /* Teardown all streams */
- for (type = 0; type < CX18_MAX_STREAMS; type++) {
-
- /* The TS has a cx18_dvb structure, not a video_device */
- if (type == CX18_ENC_STREAM_TYPE_TS) {
- if (cx->streams[type].dvb != NULL) {
- if (unregister)
- cx18_dvb_unregister(&cx->streams[type]);
- kfree(cx->streams[type].dvb);
- cx->streams[type].dvb = NULL;
- cx18_stream_free(&cx->streams[type]);
- }
- continue;
- }
-
- /* No struct video_device, but can have buffers allocated */
- if (type == CX18_ENC_STREAM_TYPE_IDX) {
- /* If the module params didn't inhibit IDX ... */
- if (cx->stream_buffers[type] != 0) {
- cx->stream_buffers[type] = 0;
- /*
- * Before calling cx18_stream_free(),
- * check if the IDX stream was actually set up.
- * Needed, since the cx18_probe() error path
- * exits through here as well as normal clean up
- */
- if (cx->streams[type].buffers != 0)
- cx18_stream_free(&cx->streams[type]);
- }
- continue;
- }
-
- /* If struct video_device exists, can have buffers allocated */
- vdev = cx->streams[type].video_dev;
-
- cx->streams[type].video_dev = NULL;
- if (vdev == NULL)
- continue;
-
- if (type == CX18_ENC_STREAM_TYPE_YUV)
- videobuf_mmap_free(&cx->streams[type].vbuf_q);
-
- cx18_stream_free(&cx->streams[type]);
-
- /* Unregister or release device */
- if (unregister)
- video_unregister_device(vdev);
- else
- video_device_release(vdev);
- }
-}
-
-static void cx18_vbi_setup(struct cx18_stream *s)
-{
- struct cx18 *cx = s->cx;
- int raw = cx18_raw_vbi(cx);
- u32 data[CX2341X_MBOX_MAX_DATA];
- int lines;
-
- if (cx->is_60hz) {
- cx->vbi.count = 12;
- cx->vbi.start[0] = 10;
- cx->vbi.start[1] = 273;
- } else { /* PAL/SECAM */
- cx->vbi.count = 18;
- cx->vbi.start[0] = 6;
- cx->vbi.start[1] = 318;
- }
-
- /* setup VBI registers */
- if (raw)
- v4l2_subdev_call(cx->sd_av, vbi, s_raw_fmt, &cx->vbi.in.fmt.vbi);
- else
- v4l2_subdev_call(cx->sd_av, vbi, s_sliced_fmt, &cx->vbi.in.fmt.sliced);
-
- /*
- * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw
- * VBI when the first analog capture channel starts, as once it starts
- * (e.g. MPEG), we can't effect any change in the Encoder Raw VBI setup
- * (i.e. for the VBI capture channels). We also send it for each
- * analog capture channel anyway just to make sure we get the proper
- * behavior
- */
- if (raw) {
- lines = cx->vbi.count * 2;
- } else {
- /*
- * For 525/60 systems, according to the VIP 2 & BT.656 std:
- * The EAV RP code's Field bit toggles on line 4, a few lines
- * after the Vertcal Blank bit has already toggled.
- * Tell the encoder to capture 21-4+1=18 lines per field,
- * since we want lines 10 through 21.
- *
- * For 625/50 systems, according to the VIP 2 & BT.656 std:
- * The EAV RP code's Field bit toggles on line 1, a few lines
- * after the Vertcal Blank bit has already toggled.
- * (We've actually set the digitizer so that the Field bit
- * toggles on line 2.) Tell the encoder to capture 23-2+1=22
- * lines per field, since we want lines 6 through 23.
- */
- lines = cx->is_60hz ? (21 - 4 + 1) * 2 : (23 - 2 + 1) * 2;
- }
-
- data[0] = s->handle;
- /* Lines per field */
- data[1] = (lines / 2) | ((lines / 2) << 16);
- /* bytes per line */
- data[2] = (raw ? vbi_active_samples
- : (cx->is_60hz ? vbi_hblank_samples_60Hz
- : vbi_hblank_samples_50Hz));
- /* Every X number of frames a VBI interrupt arrives
- (frames as in 25 or 30 fps) */
- data[3] = 1;
- /*
- * Set the SAV/EAV RP codes to look for as start/stop points
- * when in VIP-1.1 mode
- */
- if (raw) {
- /*
- * Start codes for beginning of "active" line in vertical blank
- * 0x20 ( VerticalBlank )
- * 0x60 ( EvenField VerticalBlank )
- */
- data[4] = 0x20602060;
- /*
- * End codes for end of "active" raw lines and regular lines
- * 0x30 ( VerticalBlank HorizontalBlank)
- * 0x70 ( EvenField VerticalBlank HorizontalBlank)
- * 0x90 (Task HorizontalBlank)
- * 0xd0 (Task EvenField HorizontalBlank)
- */
- data[5] = 0x307090d0;
- } else {
- /*
- * End codes for active video, we want data in the hblank region
- * 0xb0 (Task 0 VerticalBlank HorizontalBlank)
- * 0xf0 (Task EvenField VerticalBlank HorizontalBlank)
- *
- * Since the V bit is only allowed to toggle in the EAV RP code,
- * just before the first active region line, these two
- * are problematic:
- * 0x90 (Task HorizontalBlank)
- * 0xd0 (Task EvenField HorizontalBlank)
- *
- * We have set the digitzer such that we don't have to worry
- * about these problem codes.
- */
- data[4] = 0xB0F0B0F0;
- /*
- * Start codes for beginning of active line in vertical blank
- * 0xa0 (Task VerticalBlank )
- * 0xe0 (Task EvenField VerticalBlank )
- */
- data[5] = 0xA0E0A0E0;
- }
-
- CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n",
- data[0], data[1], data[2], data[3], data[4], data[5]);
-
- cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
-}
-
-void cx18_stream_rotate_idx_mdls(struct cx18 *cx)
-{
- struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
- struct cx18_mdl *mdl;
-
- if (!cx18_stream_enabled(s))
- return;
-
- /* Return if the firmware is not running low on MDLs */
- if ((atomic_read(&s->q_free.depth) + atomic_read(&s->q_busy.depth)) >=
- CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN)
- return;
-
- /* Return if there are no MDLs to rotate back to the firmware */
- if (atomic_read(&s->q_full.depth) < 2)
- return;
-
- /*
- * Take the oldest IDX MDL still holding data, and discard its index
- * entries by scheduling the MDL to go back to the firmware
- */
- mdl = cx18_dequeue(s, &s->q_full);
- if (mdl != NULL)
- cx18_enqueue(s, mdl, &s->q_free);
-}
-
-static
-struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
- struct cx18_mdl *mdl)
-{
- struct cx18 *cx = s->cx;
- struct cx18_queue *q;
-
- /* Don't give it to the firmware, if we're not running a capture */
- if (s->handle == CX18_INVALID_TASK_HANDLE ||
- test_bit(CX18_F_S_STOPPING, &s->s_flags) ||
- !test_bit(CX18_F_S_STREAMING, &s->s_flags))
- return cx18_enqueue(s, mdl, &s->q_free);
-
- q = cx18_enqueue(s, mdl, &s->q_busy);
- if (q != &s->q_busy)
- return q; /* The firmware has the max MDLs it can handle */
-
- cx18_mdl_sync_for_device(s, mdl);
- cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
- (void __iomem *) &cx->scb->cpu_mdl[mdl->id] - cx->enc_mem,
- s->bufs_per_mdl, mdl->id, s->mdl_size);
- return q;
-}
-
-static
-void _cx18_stream_load_fw_queue(struct cx18_stream *s)
-{
- struct cx18_queue *q;
- struct cx18_mdl *mdl;
-
- if (atomic_read(&s->q_free.depth) == 0 ||
- atomic_read(&s->q_busy.depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
- return;
-
- /* Move from q_free to q_busy notifying the firmware, until the limit */
- do {
- mdl = cx18_dequeue(s, &s->q_free);
- if (mdl == NULL)
- break;
- q = _cx18_stream_put_mdl_fw(s, mdl);
- } while (atomic_read(&s->q_busy.depth) < CX18_MAX_FW_MDLS_PER_STREAM
- && q == &s->q_busy);
-}
-
-void cx18_out_work_handler(struct work_struct *work)
-{
- struct cx18_stream *s =
- container_of(work, struct cx18_stream, out_work_order);
-
- _cx18_stream_load_fw_queue(s);
-}
-
-static void cx18_stream_configure_mdls(struct cx18_stream *s)
-{
- cx18_unload_queues(s);
-
- switch (s->type) {
- case CX18_ENC_STREAM_TYPE_YUV:
- /*
- * Height should be a multiple of 32 lines.
- * Set the MDL size to the exact size needed for one frame.
- * Use enough buffers per MDL to cover the MDL size
- */
- if (s->pixelformat == V4L2_PIX_FMT_HM12)
- s->mdl_size = 720 * s->cx->cxhdl.height * 3 / 2;
- else
- s->mdl_size = 720 * s->cx->cxhdl.height * 2;
- s->bufs_per_mdl = s->mdl_size / s->buf_size;
- if (s->mdl_size % s->buf_size)
- s->bufs_per_mdl++;
- break;
- case CX18_ENC_STREAM_TYPE_VBI:
- s->bufs_per_mdl = 1;
- if (cx18_raw_vbi(s->cx)) {
- s->mdl_size = (s->cx->is_60hz ? 12 : 18)
- * 2 * vbi_active_samples;
- } else {
- /*
- * See comment in cx18_vbi_setup() below about the
- * extra lines we capture in sliced VBI mode due to
- * the lines on which EAV RP codes toggle.
- */
- s->mdl_size = s->cx->is_60hz
- ? (21 - 4 + 1) * 2 * vbi_hblank_samples_60Hz
- : (23 - 2 + 1) * 2 * vbi_hblank_samples_50Hz;
- }
- break;
- default:
- s->bufs_per_mdl = 1;
- s->mdl_size = s->buf_size * s->bufs_per_mdl;
- break;
- }
-
- cx18_load_queues(s);
-}
-
-int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
-{
- u32 data[MAX_MB_ARGUMENTS];
- struct cx18 *cx = s->cx;
- int captype = 0;
- struct cx18_stream *s_idx;
-
- if (!cx18_stream_enabled(s))
- return -EINVAL;
-
- CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
-
- switch (s->type) {
- case CX18_ENC_STREAM_TYPE_MPG:
- captype = CAPTURE_CHANNEL_TYPE_MPEG;
- cx->mpg_data_received = cx->vbi_data_inserted = 0;
- cx->dualwatch_jiffies = jiffies;
- cx->dualwatch_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
- cx->search_pack_header = 0;
- break;
-
- case CX18_ENC_STREAM_TYPE_IDX:
- captype = CAPTURE_CHANNEL_TYPE_INDEX;
- break;
- case CX18_ENC_STREAM_TYPE_TS:
- captype = CAPTURE_CHANNEL_TYPE_TS;
- break;
- case CX18_ENC_STREAM_TYPE_YUV:
- captype = CAPTURE_CHANNEL_TYPE_YUV;
- break;
- case CX18_ENC_STREAM_TYPE_PCM:
- captype = CAPTURE_CHANNEL_TYPE_PCM;
- break;
- case CX18_ENC_STREAM_TYPE_VBI:
-#ifdef CX18_ENCODER_PARSES_SLICED
- captype = cx18_raw_vbi(cx) ?
- CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI;
-#else
- /*
- * Currently we set things up so that Sliced VBI from the
- * digitizer is handled as Raw VBI by the encoder
- */
- captype = CAPTURE_CHANNEL_TYPE_VBI;
-#endif
- cx->vbi.frame = 0;
- cx->vbi.inserted_frame = 0;
- memset(cx->vbi.sliced_mpeg_size,
- 0, sizeof(cx->vbi.sliced_mpeg_size));
- break;
- default:
- return -EINVAL;
- }
-
- /* Clear Streamoff flags in case left from last capture */
- clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
-
- cx18_vapi_result(cx, data, CX18_CREATE_TASK, 1, CPU_CMD_MASK_CAPTURE);
- s->handle = data[0];
- cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);
-
- /*
- * For everything but CAPTURE_CHANNEL_TYPE_TS, play it safe and
- * set up all the parameters, as it is not obvious which parameters the
- * firmware shares across capture channel types and which it does not.
- *
- * Some of the cx18_vapi() calls below apply to only certain capture
- * channel types. We're hoping there's no harm in calling most of them
- * anyway, as long as the values are all consistent. Setting some
- * shared parameters will have no effect once an analog capture channel
- * has started streaming.
- */
- if (captype != CAPTURE_CHANNEL_TYPE_TS) {
- cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
- cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
- cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0);
- cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1);
-
- /*
- * Audio related reset according to
- * Documentation/video4linux/cx2341x/fw-encoder-api.txt
- */
- if (atomic_read(&cx->ana_capturing) == 0)
- cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2,
- s->handle, 12);
-
- /*
- * Number of lines for Field 1 & Field 2 according to
- * Documentation/video4linux/cx2341x/fw-encoder-api.txt
- * Field 1 is 312 for 625 line systems in BT.656
- * Field 2 is 313 for 625 line systems in BT.656
- */
- cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3,
- s->handle, 312, 313);
-
- if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE)
- cx18_vbi_setup(s);
-
- /*
- * Select to receive I, P, and B frame index entries, if the
- * index stream is enabled. Otherwise disable index entry
- * generation.
- */
- s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
- cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 2,
- s->handle, cx18_stream_enabled(s_idx) ? 7 : 0);
-
- /* Call out to the common CX2341x API setup for user controls */
- cx->cxhdl.priv = s;
- cx2341x_handler_setup(&cx->cxhdl);
-
- /*
- * When starting a capture and we're set for radio,
- * ensure the video is muted, despite the user control.
- */
- if (!cx->cxhdl.video_mute &&
- test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
- cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
- (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8) | 1);
-
- /* Enable the Video Format Converter for UYVY 4:2:2 support,
- * rather than the default HM12 Macroblovk 4:2:0 support.
- */
- if (captype == CAPTURE_CHANNEL_TYPE_YUV) {
- if (s->pixelformat == V4L2_PIX_FMT_UYVY)
- cx18_vapi(cx, CX18_CPU_SET_VFC_PARAM, 2,
- s->handle, 1);
- else
- /* If in doubt, default to HM12 */
- cx18_vapi(cx, CX18_CPU_SET_VFC_PARAM, 2,
- s->handle, 0);
- }
- }
-
- if (atomic_read(&cx->tot_capturing) == 0) {
- cx2341x_handler_set_busy(&cx->cxhdl, 1);
- clear_bit(CX18_F_I_EOS, &cx->i_flags);
- cx18_write_reg(cx, 7, CX18_DSP0_INTERRUPT_MASK);
- }
-
- cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle,
- (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem,
- (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);
-
- /* Init all the cpu_mdls for this stream */
- cx18_stream_configure_mdls(s);
- _cx18_stream_load_fw_queue(s);
-
- /* begin_capture */
- if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) {
- CX18_DEBUG_WARN("Error starting capture!\n");
- /* Ensure we're really not capturing before releasing MDLs */
- set_bit(CX18_F_S_STOPPING, &s->s_flags);
- if (s->type == CX18_ENC_STREAM_TYPE_MPG)
- cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1);
- else
- cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);
- clear_bit(CX18_F_S_STREAMING, &s->s_flags);
- /* FIXME - CX18_F_S_STREAMOFF as well? */
- cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
- cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
- s->handle = CX18_INVALID_TASK_HANDLE;
- clear_bit(CX18_F_S_STOPPING, &s->s_flags);
- if (atomic_read(&cx->tot_capturing) == 0) {
- set_bit(CX18_F_I_EOS, &cx->i_flags);
- cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
- }
- return -EINVAL;
- }
-
- /* you're live! sit back and await interrupts :) */
- if (captype != CAPTURE_CHANNEL_TYPE_TS)
- atomic_inc(&cx->ana_capturing);
- atomic_inc(&cx->tot_capturing);
- return 0;
-}
-EXPORT_SYMBOL(cx18_start_v4l2_encode_stream);
-
-void cx18_stop_all_captures(struct cx18 *cx)
-{
- int i;
-
- for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
- struct cx18_stream *s = &cx->streams[i];
-
- if (!cx18_stream_enabled(s))
- continue;
- if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
- cx18_stop_v4l2_encode_stream(s, 0);
- }
-}
-
-int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
-{
- struct cx18 *cx = s->cx;
-
- if (!cx18_stream_enabled(s))
- return -EINVAL;
-
- /* This function assumes that you are allowed to stop the capture
- and that we are actually capturing */
-
- CX18_DEBUG_INFO("Stop Capture\n");
-
- if (atomic_read(&cx->tot_capturing) == 0)
- return 0;
-
- set_bit(CX18_F_S_STOPPING, &s->s_flags);
- if (s->type == CX18_ENC_STREAM_TYPE_MPG)
- cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end);
- else
- cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);
-
- if (s->type == CX18_ENC_STREAM_TYPE_MPG && gop_end) {
- CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n");
- }
-
- if (s->type != CX18_ENC_STREAM_TYPE_TS)
- atomic_dec(&cx->ana_capturing);
- atomic_dec(&cx->tot_capturing);
-
- /* Clear capture and no-read bits */
- clear_bit(CX18_F_S_STREAMING, &s->s_flags);
-
- /* Tell the CX23418 it can't use our buffers anymore */
- cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
-
- cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
- s->handle = CX18_INVALID_TASK_HANDLE;
- clear_bit(CX18_F_S_STOPPING, &s->s_flags);
-
- if (atomic_read(&cx->tot_capturing) > 0)
- return 0;
-
- cx2341x_handler_set_busy(&cx->cxhdl, 0);
- cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
- wake_up(&s->waitq);
-
- return 0;
-}
-EXPORT_SYMBOL(cx18_stop_v4l2_encode_stream);
-
-u32 cx18_find_handle(struct cx18 *cx)
-{
- int i;
-
- /* find first available handle to be used for global settings */
- for (i = 0; i < CX18_MAX_STREAMS; i++) {
- struct cx18_stream *s = &cx->streams[i];
-
- if (s->video_dev && (s->handle != CX18_INVALID_TASK_HANDLE))
- return s->handle;
- }
- return CX18_INVALID_TASK_HANDLE;
-}
-
-struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle)
-{
- int i;
- struct cx18_stream *s;
-
- if (handle == CX18_INVALID_TASK_HANDLE)
- return NULL;
-
- for (i = 0; i < CX18_MAX_STREAMS; i++) {
- s = &cx->streams[i];
- if (s->handle != handle)
- continue;
- if (cx18_stream_enabled(s))
- return s;
- }
- return NULL;
-}
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
deleted file mode 100644
index 713b0e61536..00000000000
--- a/drivers/media/video/cx18/cx18-streams.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * cx18 init/start/stop/exit stream functions
- *
- * Derived from ivtv-streams.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-u32 cx18_find_handle(struct cx18 *cx);
-struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle);
-int cx18_streams_setup(struct cx18 *cx);
-int cx18_streams_register(struct cx18 *cx);
-void cx18_streams_cleanup(struct cx18 *cx, int unregister);
-
-#define CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN (3)
-void cx18_stream_rotate_idx_mdls(struct cx18 *cx);
-
-static inline bool cx18_stream_enabled(struct cx18_stream *s)
-{
- return s->video_dev ||
- (s->dvb && s->dvb->enabled) ||
- (s->type == CX18_ENC_STREAM_TYPE_IDX &&
- s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0);
-}
-
-/* Related to submission of mdls to firmware */
-static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
-{
- schedule_work(&s->out_work_order);
-}
-
-static inline void cx18_stream_put_mdl_fw(struct cx18_stream *s,
- struct cx18_mdl *mdl)
-{
- /* Put mdl on q_free; the out work handler will move mdl(s) to q_busy */
- cx18_enqueue(s, mdl, &s->q_free);
- cx18_stream_load_fw_queue(s);
-}
-
-void cx18_out_work_handler(struct work_struct *work);
-
-/* Capture related */
-int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
-int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end);
-
-void cx18_stop_all_captures(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
deleted file mode 100644
index 6d3121ff45a..00000000000
--- a/drivers/media/video/cx18/cx18-vbi.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * cx18 Vertical Blank Interval support functions
- *
- * Derived from ivtv-vbi.c
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-vbi.h"
-#include "cx18-ioctl.h"
-#include "cx18-queue.h"
-
-/*
- * Raster Reference/Protection (RP) bytes, used in Start/End Active
- * Video codes emitted from the digitzer in VIP 1.x mode, that flag the start
- * of VBI sample or VBI ancillary data regions in the digitial ratser line.
- *
- * Task FieldEven VerticalBlank HorizontalBlank 0 0 0 0
- */
-static const u8 raw_vbi_sav_rp[2] = { 0x20, 0x60 }; /* __V_, _FV_ */
-static const u8 sliced_vbi_eav_rp[2] = { 0xb0, 0xf0 }; /* T_VH, TFVH */
-
-static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
-{
- int line = 0;
- int i;
- u32 linemask[2] = { 0, 0 };
- unsigned short size;
- static const u8 mpeg_hdr_data[] = {
- /* MPEG-2 Program Pack */
- 0x00, 0x00, 0x01, 0xba, /* Prog Pack start code */
- 0x44, 0x00, 0x0c, 0x66, 0x24, 0x01, /* SCR, SCR Ext, markers */
- 0x01, 0xd1, 0xd3, /* Mux Rate, markers */
- 0xfa, 0xff, 0xff, /* Res, Suff cnt, Stuff */
- /* MPEG-2 Private Stream 1 PES Packet */
- 0x00, 0x00, 0x01, 0xbd, /* Priv Stream 1 start */
- 0x00, 0x1a, /* length */
- 0x84, 0x80, 0x07, /* flags, hdr data len */
- 0x21, 0x00, 0x5d, 0x63, 0xa7, /* PTS, markers */
- 0xff, 0xff /* stuffing */
- };
- const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
- int idx = cx->vbi.frame % CX18_VBI_FRAMES;
- u8 *dst = &cx->vbi.sliced_mpeg_data[idx][0];
-
- for (i = 0; i < lines; i++) {
- struct v4l2_sliced_vbi_data *sdata = cx->vbi.sliced_data + i;
- int f, l;
-
- if (sdata->id == 0)
- continue;
-
- l = sdata->line - 6;
- f = sdata->field;
- if (f)
- l += 18;
- if (l < 32)
- linemask[0] |= (1 << l);
- else
- linemask[1] |= (1 << (l - 32));
- dst[sd + 12 + line * 43] = cx18_service2vbi(sdata->id);
- memcpy(dst + sd + 12 + line * 43 + 1, sdata->data, 42);
- line++;
- }
- memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
- if (line == 36) {
- /* All lines are used, so there is no space for the linemask
- (the max size of the VBI data is 36 * 43 + 4 bytes).
- So in this case we use the magic number 'ITV0'. */
- memcpy(dst + sd, "ITV0", 4);
- memcpy(dst + sd + 4, dst + sd + 12, line * 43);
- size = 4 + ((43 * line + 3) & ~3);
- } else {
- memcpy(dst + sd, "itv0", 4);
- cpu_to_le32s(&linemask[0]);
- cpu_to_le32s(&linemask[1]);
- memcpy(dst + sd + 4, &linemask[0], 8);
- size = 12 + ((43 * line + 3) & ~3);
- }
- dst[4+16] = (size + 10) >> 8;
- dst[5+16] = (size + 10) & 0xff;
- dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
- dst[10+16] = (pts_stamp >> 22) & 0xff;
- dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
- dst[12+16] = (pts_stamp >> 7) & 0xff;
- dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
- cx->vbi.sliced_mpeg_size[idx] = sd + size;
-}
-
-/* Compress raw VBI format, removes leading SAV codes and surplus space
- after the frame. Returns new compressed size. */
-/* FIXME - this function ignores the input size. */
-static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size)
-{
- u32 line_size = vbi_active_samples;
- u32 lines = cx->vbi.count * 2;
- u8 *q = buf;
- u8 *p;
- int i;
-
- /* Skip the header */
- buf += hdr_size;
-
- for (i = 0; i < lines; i++) {
- p = buf + i * line_size;
-
- /* Look for SAV code */
- if (p[0] != 0xff || p[1] || p[2] ||
- (p[3] != raw_vbi_sav_rp[0] &&
- p[3] != raw_vbi_sav_rp[1]))
- break;
- if (i == lines - 1) {
- /* last line is hdr_size bytes short - extrapolate it */
- memcpy(q, p + 4, line_size - 4 - hdr_size);
- q += line_size - 4 - hdr_size;
- p += line_size - hdr_size - 1;
- memset(q, (int) *p, hdr_size);
- } else {
- memcpy(q, p + 4, line_size - 4);
- q += line_size - 4;
- }
- }
- return lines * (line_size - 4);
-}
-
-static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size,
- const u32 hdr_size)
-{
- struct v4l2_decode_vbi_line vbi;
- int i;
- u32 line = 0;
- u32 line_size = cx->is_60hz ? vbi_hblank_samples_60Hz
- : vbi_hblank_samples_50Hz;
-
- /* find the first valid line */
- for (i = hdr_size, buf += hdr_size; i < size; i++, buf++) {
- if (buf[0] == 0xff && !buf[1] && !buf[2] &&
- (buf[3] == sliced_vbi_eav_rp[0] ||
- buf[3] == sliced_vbi_eav_rp[1]))
- break;
- }
-
- /*
- * The last line is short by hdr_size bytes, but for the remaining
- * checks against size, we pretend that it is not, by counting the
- * header bytes we knowingly skipped
- */
- size -= (i - hdr_size);
- if (size < line_size)
- return line;
-
- for (i = 0; i < size / line_size; i++) {
- u8 *p = buf + i * line_size;
-
- /* Look for EAV code */
- if (p[0] != 0xff || p[1] || p[2] ||
- (p[3] != sliced_vbi_eav_rp[0] &&
- p[3] != sliced_vbi_eav_rp[1]))
- continue;
- vbi.p = p + 4;
- v4l2_subdev_call(cx->sd_av, vbi, decode_vbi_line, &vbi);
- if (vbi.type) {
- cx->vbi.sliced_data[line].id = vbi.type;
- cx->vbi.sliced_data[line].field = vbi.is_second_field;
- cx->vbi.sliced_data[line].line = vbi.line;
- memcpy(cx->vbi.sliced_data[line].data, vbi.p, 42);
- line++;
- }
- }
- return line;
-}
-
-static void _cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf)
-{
- /*
- * The CX23418 provides a 12 byte header in its raw VBI buffers to us:
- * 0x3fffffff [4 bytes of something] [4 byte presentation time stamp]
- */
- struct vbi_data_hdr {
- __be32 magic;
- __be32 unknown;
- __be32 pts;
- } *hdr = (struct vbi_data_hdr *) buf->buf;
-
- u8 *p = (u8 *) buf->buf;
- u32 size = buf->bytesused;
- u32 pts;
- int lines;
-
- /*
- * The CX23418 sends us data that is 32 bit little-endian swapped,
- * but we want the raw VBI bytes in the order they were in the raster
- * line. This has a side effect of making the header big endian
- */
- cx18_buf_swap(buf);
-
- /* Raw VBI data */
- if (cx18_raw_vbi(cx)) {
-
- size = buf->bytesused =
- compress_raw_buf(cx, p, size, sizeof(struct vbi_data_hdr));
-
- /*
- * Hack needed for compatibility with old VBI software.
- * Write the frame # at the last 4 bytes of the frame
- */
- p += size - 4;
- memcpy(p, &cx->vbi.frame, 4);
- cx->vbi.frame++;
- return;
- }
-
- /* Sliced VBI data with data insertion */
-
- pts = (be32_to_cpu(hdr->magic) == 0x3fffffff) ? be32_to_cpu(hdr->pts)
- : 0;
-
- lines = compress_sliced_buf(cx, p, size, sizeof(struct vbi_data_hdr));
-
- /* always return at least one empty line */
- if (lines == 0) {
- cx->vbi.sliced_data[0].id = 0;
- cx->vbi.sliced_data[0].line = 0;
- cx->vbi.sliced_data[0].field = 0;
- lines = 1;
- }
- buf->bytesused = size = lines * sizeof(cx->vbi.sliced_data[0]);
- memcpy(p, &cx->vbi.sliced_data[0], size);
-
- if (cx->vbi.insert_mpeg)
- copy_vbi_data(cx, lines, pts);
- cx->vbi.frame++;
-}
-
-void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
- int streamtype)
-{
- struct cx18_buffer *buf;
- u32 orig_used;
-
- if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
- return;
-
- /*
- * Big assumption here:
- * Every buffer hooked to the MDL's buf_list is a complete VBI frame
- * that ends at the end of the buffer.
- *
- * To assume anything else would make the code in this file
- * more complex, or require extra memcpy()'s to make the
- * buffers satisfy the above assumption. It's just simpler to set
- * up the encoder buffer transfers to make the assumption true.
- */
- list_for_each_entry(buf, &mdl->buf_list, list) {
- orig_used = buf->bytesused;
- if (orig_used == 0)
- break;
- _cx18_process_vbi_data(cx, buf);
- mdl->bytesused -= (orig_used - buf->bytesused);
- }
-}
diff --git a/drivers/media/video/cx18/cx18-vbi.h b/drivers/media/video/cx18/cx18-vbi.h
deleted file mode 100644
index b365cf4b466..00000000000
--- a/drivers/media/video/cx18/cx18-vbi.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * cx18 Vertical Blank Interval support functions
- *
- * Derived from ivtv-vbi.h
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
- int streamtype);
-int cx18_used_line(struct cx18 *cx, int line, int field);
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
deleted file mode 100644
index fed48b6bb67..00000000000
--- a/drivers/media/video/cx18/cx18-version.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * cx18 driver version information
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#ifndef CX18_VERSION_H
-#define CX18_VERSION_H
-
-#define CX18_DRIVER_NAME "cx18"
-#define CX18_VERSION "1.5.1"
-
-#endif
diff --git a/drivers/media/video/cx18/cx18-video.c b/drivers/media/video/cx18/cx18-video.c
deleted file mode 100644
index 6dc84aac8f4..00000000000
--- a/drivers/media/video/cx18/cx18-video.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * cx18 video interface functions
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#include "cx18-driver.h"
-#include "cx18-video.h"
-#include "cx18-cards.h"
-
-void cx18_video_set_io(struct cx18 *cx)
-{
- int inp = cx->active_input;
-
- v4l2_subdev_call(cx->sd_av, video, s_routing,
- cx->card->video_inputs[inp].video_input, 0, 0);
-}
diff --git a/drivers/media/video/cx18/cx18-video.h b/drivers/media/video/cx18/cx18-video.h
deleted file mode 100644
index 529006a06e5..00000000000
--- a/drivers/media/video/cx18/cx18-video.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * cx18 video interface functions
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-void cx18_video_set_io(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
deleted file mode 100644
index 767a8d23e3f..00000000000
--- a/drivers/media/video/cx18/cx23418.h
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- * cx18 header containing common defines.
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- */
-
-#ifndef CX23418_H
-#define CX23418_H
-
-#include <media/cx2341x.h>
-
-#define MGR_CMD_MASK 0x40000000
-/* The MSB of the command code indicates that this is the completion of a
- command */
-#define MGR_CMD_MASK_ACK (MGR_CMD_MASK | 0x80000000)
-
-/* Description: This command creates a new instance of a certain task
- IN[0] - Task ID. This is one of the XPU_CMD_MASK_YYY where XPU is
- the processor on which the task YYY will be created
- OUT[0] - Task handle. This handle is passed along with commands to
- dispatch to the right instance of the task
- ReturnCode - One of the ERR_SYS_... */
-#define CX18_CREATE_TASK (MGR_CMD_MASK | 0x0001)
-
-/* Description: This command destroys an instance of a task
- IN[0] - Task handle. Hanlde of the task to destroy
- ReturnCode - One of the ERR_SYS_... */
-#define CX18_DESTROY_TASK (MGR_CMD_MASK | 0x0002)
-
-/* All commands for CPU have the following mask set */
-#define CPU_CMD_MASK 0x20000000
-#define CPU_CMD_MASK_DEBUG (CPU_CMD_MASK | 0x00000000)
-#define CPU_CMD_MASK_ACK (CPU_CMD_MASK | 0x80000000)
-#define CPU_CMD_MASK_CAPTURE (CPU_CMD_MASK | 0x00020000)
-#define CPU_CMD_MASK_TS (CPU_CMD_MASK | 0x00040000)
-
-#define EPU_CMD_MASK 0x02000000
-#define EPU_CMD_MASK_DEBUG (EPU_CMD_MASK | 0x000000)
-#define EPU_CMD_MASK_DE (EPU_CMD_MASK | 0x040000)
-
-#define APU_CMD_MASK 0x10000000
-#define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000)
-
-#define CX18_APU_ENCODING_METHOD_MPEG (0 << 28)
-#define CX18_APU_ENCODING_METHOD_AC3 (1 << 28)
-
-/* Description: Command APU to start audio
- IN[0] - audio parameters (same as CX18_CPU_SET_AUDIO_PARAMETERS?)
- IN[1] - caller buffer address, or 0
- ReturnCode - ??? */
-#define CX18_APU_START (APU_CMD_MASK | 0x01)
-
-/* Description: Command APU to stop audio
- IN[0] - encoding method to stop
- ReturnCode - ??? */
-#define CX18_APU_STOP (APU_CMD_MASK | 0x02)
-
-/* Description: Command APU to reset the AI
- ReturnCode - ??? */
-#define CX18_APU_RESETAI (APU_CMD_MASK | 0x05)
-
-/* Description: This command indicates that a Memory Descriptor List has been
- filled with the requested channel type
- IN[0] - Task handle. Handle of the task
- IN[1] - Offset of the MDL_ACK from the beginning of the local DDR.
- IN[2] - Number of CNXT_MDL_ACK structures in the array pointed to by IN[1]
- ReturnCode - One of the ERR_DE_... */
-#define CX18_EPU_DMA_DONE (EPU_CMD_MASK_DE | 0x0001)
-
-/* Something interesting happened
- IN[0] - A value to log
- IN[1] - An offset of a string in the MiniMe memory;
- 0/zero/NULL means "I have nothing to say" */
-#define CX18_EPU_DEBUG (EPU_CMD_MASK_DEBUG | 0x0003)
-
-/* Reads memory/registers (32-bit)
- IN[0] - Address
- OUT[1] - Value */
-#define CX18_CPU_DEBUG_PEEK32 (CPU_CMD_MASK_DEBUG | 0x0003)
-
-/* Description: This command starts streaming with the set channel type
- IN[0] - Task handle. Handle of the task to start
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_START (CPU_CMD_MASK_CAPTURE | 0x0002)
-
-/* Description: This command stops streaming with the set channel type
- IN[0] - Task handle. Handle of the task to stop
- IN[1] - 0 = stop at end of GOP, 1 = stop at end of frame (MPEG only)
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_STOP (CPU_CMD_MASK_CAPTURE | 0x0003)
-
-/* Description: This command pauses streaming with the set channel type
- IN[0] - Task handle. Handle of the task to pause
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_PAUSE (CPU_CMD_MASK_CAPTURE | 0x0007)
-
-/* Description: This command resumes streaming with the set channel type
- IN[0] - Task handle. Handle of the task to resume
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_RESUME (CPU_CMD_MASK_CAPTURE | 0x0008)
-
-#define CAPTURE_CHANNEL_TYPE_NONE 0
-#define CAPTURE_CHANNEL_TYPE_MPEG 1
-#define CAPTURE_CHANNEL_TYPE_INDEX 2
-#define CAPTURE_CHANNEL_TYPE_YUV 3
-#define CAPTURE_CHANNEL_TYPE_PCM 4
-#define CAPTURE_CHANNEL_TYPE_VBI 5
-#define CAPTURE_CHANNEL_TYPE_SLICED_VBI 6
-#define CAPTURE_CHANNEL_TYPE_TS 7
-#define CAPTURE_CHANNEL_TYPE_MAX 15
-
-/* Description: This command sets the channel type. This can only be done
- when stopped.
- IN[0] - Task handle. Handle of the task to start
- IN[1] - Channel Type. See Below.
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_CHANNEL_TYPE (CPU_CMD_MASK_CAPTURE + 1)
-
-/* Description: Set stream output type
- IN[0] - task handle. Handle of the task to start
- IN[1] - type
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_STREAM_OUTPUT_TYPE (CPU_CMD_MASK_CAPTURE | 0x0012)
-
-/* Description: Set video input resolution and frame rate
- IN[0] - task handle
- IN[1] - reserved
- IN[2] - reserved
- IN[3] - reserved
- IN[4] - reserved
- IN[5] - frame rate, 0 - 29.97f/s, 1 - 25f/s
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VIDEO_IN (CPU_CMD_MASK_CAPTURE | 0x0004)
-
-/* Description: Set video frame rate
- IN[0] - task handle. Handle of the task to start
- IN[1] - video bit rate mode
- IN[2] - video average rate
- IN[3] - video peak rate
- IN[4] - system mux rate
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VIDEO_RATE (CPU_CMD_MASK_CAPTURE | 0x0005)
-
-/* Description: Set video output resolution
- IN[0] - task handle
- IN[1] - horizontal size
- IN[2] - vertical size
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VIDEO_RESOLUTION (CPU_CMD_MASK_CAPTURE | 0x0006)
-
-/* Description: This command set filter parameters
- IN[0] - Task handle. Handle of the task
- IN[1] - type, 0 - temporal, 1 - spatial, 2 - median
- IN[2] - mode, temporal/spatial: 0 - disable, 1 - static, 2 - dynamic
- median: 0 = disable, 1 = horizontal, 2 = vertical,
- 3 = horizontal/vertical, 4 = diagonal
- IN[3] - strength, temporal 0 - 31, spatial 0 - 15
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_FILTER_PARAM (CPU_CMD_MASK_CAPTURE | 0x0009)
-
-/* Description: This command set spatial filter type
- IN[0] - Task handle.
- IN[1] - luma type: 0 = disable, 1 = 1D horizontal only, 2 = 1D vertical only,
- 3 = 2D H/V separable, 4 = 2D symmetric non-separable
- IN[2] - chroma type: 0 - disable, 1 = 1D horizontal
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_SPATIAL_FILTER_TYPE (CPU_CMD_MASK_CAPTURE | 0x000C)
-
-/* Description: This command set coring levels for median filter
- IN[0] - Task handle.
- IN[1] - luma_high
- IN[2] - luma_low
- IN[3] - chroma_high
- IN[4] - chroma_low
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_MEDIAN_CORING (CPU_CMD_MASK_CAPTURE | 0x000E)
-
-/* Description: This command set the picture type mask for index file
- IN[0] - Task handle (ignored by firmware)
- IN[1] - 0 = disable index file output
- 1 = output I picture
- 2 = P picture
- 4 = B picture
- other = illegal */
-#define CX18_CPU_SET_INDEXTABLE (CPU_CMD_MASK_CAPTURE | 0x0010)
-
-/* Description: Set audio parameters
- IN[0] - task handle. Handle of the task to start
- IN[1] - audio parameter
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_AUDIO_PARAMETERS (CPU_CMD_MASK_CAPTURE | 0x0011)
-
-/* Description: Set video mute
- IN[0] - task handle. Handle of the task to start
- IN[1] - bit31-24: muteYvalue
- bit23-16: muteUvalue
- bit15-8: muteVvalue
- bit0: 1:mute, 0: unmute
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VIDEO_MUTE (CPU_CMD_MASK_CAPTURE | 0x0013)
-
-/* Description: Set audio mute
- IN[0] - task handle. Handle of the task to start
- IN[1] - mute/unmute
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_AUDIO_MUTE (CPU_CMD_MASK_CAPTURE | 0x0014)
-
-/* Description: Set stream output type
- IN[0] - task handle. Handle of the task to start
- IN[1] - subType
- SET_INITIAL_SCR 1
- SET_QUALITY_MODE 2
- SET_VIM_PROTECT_MODE 3
- SET_PTS_CORRECTION 4
- SET_USB_FLUSH_MODE 5
- SET_MERAQPAR_ENABLE 6
- SET_NAV_PACK_INSERTION 7
- SET_SCENE_CHANGE_ENABLE 8
- IN[2] - parameter 1
- IN[3] - parameter 2
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_MISC_PARAMETERS (CPU_CMD_MASK_CAPTURE | 0x0015)
-
-/* Description: Set raw VBI parameters
- IN[0] - Task handle
- IN[1] - No. of input lines per field:
- bit[15:0]: field 1,
- bit[31:16]: field 2
- IN[2] - No. of input bytes per line
- IN[3] - No. of output frames per transfer
- IN[4] - start code
- IN[5] - stop code
- ReturnCode */
-#define CX18_CPU_SET_RAW_VBI_PARAM (CPU_CMD_MASK_CAPTURE | 0x0016)
-
-/* Description: Set capture line No.
- IN[0] - task handle. Handle of the task to start
- IN[1] - height1
- IN[2] - height2
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_CAPTURE_LINE_NO (CPU_CMD_MASK_CAPTURE | 0x0017)
-
-/* Description: Set copyright
- IN[0] - task handle. Handle of the task to start
- IN[1] - copyright
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_COPYRIGHT (CPU_CMD_MASK_CAPTURE | 0x0018)
-
-/* Description: Set audio PID
- IN[0] - task handle. Handle of the task to start
- IN[1] - PID
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_AUDIO_PID (CPU_CMD_MASK_CAPTURE | 0x0019)
-
-/* Description: Set video PID
- IN[0] - task handle. Handle of the task to start
- IN[1] - PID
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VIDEO_PID (CPU_CMD_MASK_CAPTURE | 0x001A)
-
-/* Description: Set Vertical Crop Line
- IN[0] - task handle. Handle of the task to start
- IN[1] - Line
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VER_CROP_LINE (CPU_CMD_MASK_CAPTURE | 0x001B)
-
-/* Description: Set COP structure
- IN[0] - task handle. Handle of the task to start
- IN[1] - M
- IN[2] - N
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_GOP_STRUCTURE (CPU_CMD_MASK_CAPTURE | 0x001C)
-
-/* Description: Set Scene Change Detection
- IN[0] - task handle. Handle of the task to start
- IN[1] - scene change
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_SCENE_CHANGE_DETECTION (CPU_CMD_MASK_CAPTURE | 0x001D)
-
-/* Description: Set Aspect Ratio
- IN[0] - task handle. Handle of the task to start
- IN[1] - AspectRatio
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_ASPECT_RATIO (CPU_CMD_MASK_CAPTURE | 0x001E)
-
-/* Description: Set Skip Input Frame
- IN[0] - task handle. Handle of the task to start
- IN[1] - skip input frames
- ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_SKIP_INPUT_FRAME (CPU_CMD_MASK_CAPTURE | 0x001F)
-
-/* Description: Set sliced VBI parameters -
- Note This API will only apply to MPEG and Sliced VBI Channels
- IN[0] - Task handle
- IN[1] - output type, 0 - CC, 1 - Moji, 2 - Teletext
- IN[2] - start / stop line
- bit[15:0] start line number
- bit[31:16] stop line number
- IN[3] - number of output frames per interrupt
- IN[4] - VBI insertion mode
- bit 0: output user data, 1 - enable
- bit 1: output private stream, 1 - enable
- bit 2: mux option, 0 - in GOP, 1 - in picture
- bit[7:0] private stream ID
- IN[5] - insertion period while mux option is in picture
- ReturnCode - VBI data offset */
-#define CX18_CPU_SET_SLICED_VBI_PARAM (CPU_CMD_MASK_CAPTURE | 0x0020)
-
-/* Description: Set the user data place holder
- IN[0] - type of data (0 for user)
- IN[1] - Stuffing period
- IN[2] - ID data size in word (less than 10)
- IN[3] - Pointer to ID buffer */
-#define CX18_CPU_SET_USERDATA_PLACE_HOLDER (CPU_CMD_MASK_CAPTURE | 0x0021)
-
-
-/* Description:
- In[0] Task Handle
- return parameter:
- Out[0] Reserved
- Out[1] Video PTS bit[32:2] of last output video frame.
- Out[2] Video PTS bit[ 1:0] of last output video frame.
- Out[3] Hardware Video PTS counter bit[31:0],
- these bits get incremented on every 90kHz clock tick.
- Out[4] Hardware Video PTS counter bit32,
- these bits get incremented on every 90kHz clock tick.
- ReturnCode */
-#define CX18_CPU_GET_ENC_PTS (CPU_CMD_MASK_CAPTURE | 0x0022)
-
-/* Description: Set VFC parameters
- IN[0] - task handle
- IN[1] - VFC enable flag, 1 - enable, 0 - disable
-*/
-#define CX18_CPU_SET_VFC_PARAM (CPU_CMD_MASK_CAPTURE | 0x0023)
-
-/* Below is the list of commands related to the data exchange */
-#define CPU_CMD_MASK_DE (CPU_CMD_MASK | 0x040000)
-
-/* Description: This command provides the physical base address of the local
- DDR as viewed by EPU
- IN[0] - Physical offset where EPU has the local DDR mapped
- ReturnCode - One of the ERR_DE_... */
-#define CPU_CMD_DE_SetBase (CPU_CMD_MASK_DE | 0x0001)
-
-/* Description: This command provides the offsets in the device memory where
- the 2 cx18_mdl_ack blocks reside
- IN[0] - Task handle. Handle of the task to start
- IN[1] - Offset of the first cx18_mdl_ack from the beginning of the
- local DDR.
- IN[2] - Offset of the second cx18_mdl_ack from the beginning of the
- local DDR.
- ReturnCode - One of the ERR_DE_... */
-#define CX18_CPU_DE_SET_MDL_ACK (CPU_CMD_MASK_DE | 0x0002)
-
-/* Description: This command provides the offset to a Memory Descriptor List
- IN[0] - Task handle. Handle of the task to start
- IN[1] - Offset of the MDL from the beginning of the local DDR.
- IN[2] - Number of cx18_mdl_ent structures in the array pointed to by IN[1]
- IN[3] - Buffer ID
- IN[4] - Total buffer length
- ReturnCode - One of the ERR_DE_... */
-#define CX18_CPU_DE_SET_MDL (CPU_CMD_MASK_DE | 0x0005)
-
-/* Description: This command requests return of all current Memory
- Descriptor Lists to the driver
- IN[0] - Task handle. Handle of the task to start
- ReturnCode - One of the ERR_DE_... */
-#define CX18_CPU_DE_RELEASE_MDL (CPU_CMD_MASK_DE | 0x0006)
-
-/* Description: This command signals the cpu that the dat buffer has been
- consumed and ready for re-use.
- IN[0] - Task handle. Handle of the task
- IN[1] - Offset of the data block from the beginning of the local DDR.
- IN[2] - Number of bytes in the data block
- ReturnCode - One of the ERR_DE_... */
-/* #define CX18_CPU_DE_RELEASE_BUFFER (CPU_CMD_MASK_DE | 0x0007) */
-
-/* No Error / Success */
-#define CNXT_OK 0x000000
-
-/* Received unknown command */
-#define CXERR_UNK_CMD 0x000001
-
-/* First parameter in the command is invalid */
-#define CXERR_INVALID_PARAM1 0x000002
-
-/* Second parameter in the command is invalid */
-#define CXERR_INVALID_PARAM2 0x000003
-
-/* Device interface is not open/found */
-#define CXERR_DEV_NOT_FOUND 0x000004
-
-/* Requested function is not implemented/available */
-#define CXERR_NOTSUPPORTED 0x000005
-
-/* Invalid pointer is provided */
-#define CXERR_BADPTR 0x000006
-
-/* Unable to allocate memory */
-#define CXERR_NOMEM 0x000007
-
-/* Object/Link not found */
-#define CXERR_LINK 0x000008
-
-/* Device busy, command cannot be executed */
-#define CXERR_BUSY 0x000009
-
-/* File/device/handle is not open. */
-#define CXERR_NOT_OPEN 0x00000A
-
-/* Value is out of range */
-#define CXERR_OUTOFRANGE 0x00000B
-
-/* Buffer overflow */
-#define CXERR_OVERFLOW 0x00000C
-
-/* Version mismatch */
-#define CXERR_BADVER 0x00000D
-
-/* Operation timed out */
-#define CXERR_TIMEOUT 0x00000E
-
-/* Operation aborted */
-#define CXERR_ABORT 0x00000F
-
-/* Specified I2C device not found for read/write */
-#define CXERR_I2CDEV_NOTFOUND 0x000010
-
-/* Error in I2C data xfer (but I2C device is present) */
-#define CXERR_I2CDEV_XFERERR 0x000011
-
-/* Chanel changing component not ready */
-#define CXERR_CHANNELNOTREADY 0x000012
-
-/* PPU (Presensation/Decoder) mail box is corrupted */
-#define CXERR_PPU_MB_CORRUPT 0x000013
-
-/* CPU (Capture/Encoder) mail box is corrupted */
-#define CXERR_CPU_MB_CORRUPT 0x000014
-
-/* APU (Audio) mail box is corrupted */
-#define CXERR_APU_MB_CORRUPT 0x000015
-
-/* Unable to open file for reading */
-#define CXERR_FILE_OPEN_READ 0x000016
-
-/* Unable to open file for writing */
-#define CXERR_FILE_OPEN_WRITE 0x000017
-
-/* Unable to find the I2C section specified */
-#define CXERR_I2C_BADSECTION 0x000018
-
-/* Error in I2C data xfer (but I2C device is present) */
-#define CXERR_I2CDEV_DATALOW 0x000019
-
-/* Error in I2C data xfer (but I2C device is present) */
-#define CXERR_I2CDEV_CLOCKLOW 0x00001A
-
-/* No Interrupt received from HW (for I2C access) */
-#define CXERR_NO_HW_I2C_INTR 0x00001B
-
-/* RPU is not ready to accept commands! */
-#define CXERR_RPU_NOT_READY 0x00001C
-
-/* RPU is not ready to accept commands! */
-#define CXERR_RPU_NO_ACK 0x00001D
-
-/* The are no buffers ready. Try again soon! */
-#define CXERR_NODATA_AGAIN 0x00001E
-
-/* The stream is stopping. Function not allowed now! */
-#define CXERR_STOPPING_STATUS 0x00001F
-
-/* Trying to access hardware when the power is turned OFF */
-#define CXERR_DEVPOWER_OFF 0x000020
-
-#endif /* CX23418_H */
diff --git a/drivers/media/video/cx231xx/Kconfig b/drivers/media/video/cx231xx/Kconfig
deleted file mode 100644
index 446f692aabb..00000000000
--- a/drivers/media/video/cx231xx/Kconfig
+++ /dev/null
@@ -1,51 +0,0 @@
-config VIDEO_CX231XX
- tristate "Conexant cx231xx USB video capture support"
- depends on VIDEO_DEV && I2C
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- depends on RC_CORE
- select VIDEOBUF_VMALLOC
- select VIDEO_CX25840
- select VIDEO_CX2341X
-
- ---help---
- This is a video4linux driver for Conexant 231xx USB based TV cards.
-
- To compile this driver as a module, choose M here: the
- module will be called cx231xx
-
-config VIDEO_CX231XX_RC
- bool "Conexant cx231xx Remote Controller additional support"
- depends on RC_CORE
- depends on VIDEO_CX231XX
- default y
- ---help---
- cx231xx hardware has a builtin RX/TX support. However, a few
- designs opted to not use it, but, instead, some other hardware.
- This module enables the usage of those other hardware, like the
- ones used with ISDB-T boards.
-
- On most cases, all you need for IR is mceusb module.
-
-config VIDEO_CX231XX_ALSA
- tristate "Conexant Cx231xx ALSA audio module"
- depends on VIDEO_CX231XX && SND
- select SND_PCM
-
- ---help---
- This is an ALSA driver for Cx231xx USB based TV cards.
-
- To compile this driver as a module, choose M here: the
- module will be called cx231xx-alsa
-
-config VIDEO_CX231XX_DVB
- tristate "DVB/ATSC Support for Cx231xx based TV cards"
- depends on VIDEO_CX231XX && DVB_CORE && DVB_CAPTURE_DRIVERS
- select VIDEOBUF_DVB
- select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
- select DVB_MB86A20S if !DVB_FE_CUSTOMISE
-
- ---help---
- This adds support for DVB cards based on the
- Conexant cx231xx chips.
diff --git a/drivers/media/video/cx231xx/Makefile b/drivers/media/video/cx231xx/Makefile
deleted file mode 100644
index b3348975c7c..00000000000
--- a/drivers/media/video/cx231xx/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-cx231xx-y += cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o
-cx231xx-y += cx231xx-avcore.o cx231xx-417.o cx231xx-pcb-cfg.o cx231xx-vbi.o
-cx231xx-$(CONFIG_VIDEO_CX231XX_RC) += cx231xx-input.o
-
-cx231xx-alsa-objs := cx231xx-audio.o
-
-obj-$(CONFIG_VIDEO_CX231XX) += cx231xx.o
-obj-$(CONFIG_VIDEO_CX231XX_ALSA) += cx231xx-alsa.o
-obj-$(CONFIG_VIDEO_CX231XX_DVB) += cx231xx-dvb.o
-
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
-ccflags-y += -Idrivers/media/dvb/dvb-usb
-
diff --git a/drivers/media/video/cx231xx/cx231xx-417.c b/drivers/media/video/cx231xx/cx231xx-417.c
deleted file mode 100644
index ce2f62238a1..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-417.c
+++ /dev/null
@@ -1,2195 +0,0 @@
-/*
- *
- * Support for a cx23417 mpeg encoder via cx231xx host port.
- *
- * (c) 2004 Jelle Foks <jelle@foks.us>
- * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
- * (c) 2008 Steven Toth <stoth@linuxtv.org>
- * - CX23885/7/8 support
- *
- * Includes parts from the ivtv driver( http://ivtv.sourceforge.net/),
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/vmalloc.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/cx2341x.h>
-#include <linux/usb.h>
-
-#include "cx231xx.h"
-/*#include "cx23885-ioctl.h"*/
-
-#define CX231xx_FIRM_IMAGE_SIZE 376836
-#define CX231xx_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw"
-
-/* for polaris ITVC */
-#define ITVC_WRITE_DIR 0x03FDFC00
-#define ITVC_READ_DIR 0x0001FC00
-
-#define MCI_MEMORY_DATA_BYTE0 0x00
-#define MCI_MEMORY_DATA_BYTE1 0x08
-#define MCI_MEMORY_DATA_BYTE2 0x10
-#define MCI_MEMORY_DATA_BYTE3 0x18
-
-#define MCI_MEMORY_ADDRESS_BYTE2 0x20
-#define MCI_MEMORY_ADDRESS_BYTE1 0x28
-#define MCI_MEMORY_ADDRESS_BYTE0 0x30
-
-#define MCI_REGISTER_DATA_BYTE0 0x40
-#define MCI_REGISTER_DATA_BYTE1 0x48
-#define MCI_REGISTER_DATA_BYTE2 0x50
-#define MCI_REGISTER_DATA_BYTE3 0x58
-
-#define MCI_REGISTER_ADDRESS_BYTE0 0x60
-#define MCI_REGISTER_ADDRESS_BYTE1 0x68
-
-#define MCI_REGISTER_MODE 0x70
-
-/* Read and write modes for polaris ITVC */
-#define MCI_MODE_REGISTER_READ 0x000
-#define MCI_MODE_REGISTER_WRITE 0x100
-#define MCI_MODE_MEMORY_READ 0x000
-#define MCI_MODE_MEMORY_WRITE 0x4000
-
-static unsigned int mpegbufs = 8;
-module_param(mpegbufs, int, 0644);
-MODULE_PARM_DESC(mpegbufs, "number of mpeg buffers, range 2-32");
-static unsigned int mpeglines = 128;
-module_param(mpeglines, int, 0644);
-MODULE_PARM_DESC(mpeglines, "number of lines in an MPEG buffer, range 2-32");
-static unsigned int mpeglinesize = 512;
-module_param(mpeglinesize, int, 0644);
-MODULE_PARM_DESC(mpeglinesize,
- "number of bytes in each line of an MPEG buffer, range 512-1024");
-
-static unsigned int v4l_debug = 1;
-module_param(v4l_debug, int, 0644);
-MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages");
-struct cx231xx_dmaqueue *dma_qq;
-#define dprintk(level, fmt, arg...)\
- do { if (v4l_debug >= level) \
- printk(KERN_INFO "%s: " fmt, \
- (dev) ? dev->name : "cx231xx[?]", ## arg); \
- } while (0)
-
-static struct cx231xx_tvnorm cx231xx_tvnorms[] = {
- {
- .name = "NTSC-M",
- .id = V4L2_STD_NTSC_M,
- }, {
- .name = "NTSC-JP",
- .id = V4L2_STD_NTSC_M_JP,
- }, {
- .name = "PAL-BG",
- .id = V4L2_STD_PAL_BG,
- }, {
- .name = "PAL-DK",
- .id = V4L2_STD_PAL_DK,
- }, {
- .name = "PAL-I",
- .id = V4L2_STD_PAL_I,
- }, {
- .name = "PAL-M",
- .id = V4L2_STD_PAL_M,
- }, {
- .name = "PAL-N",
- .id = V4L2_STD_PAL_N,
- }, {
- .name = "PAL-Nc",
- .id = V4L2_STD_PAL_Nc,
- }, {
- .name = "PAL-60",
- .id = V4L2_STD_PAL_60,
- }, {
- .name = "SECAM-L",
- .id = V4L2_STD_SECAM_L,
- }, {
- .name = "SECAM-DK",
- .id = V4L2_STD_SECAM_DK,
- }
-};
-
-/* ------------------------------------------------------------------ */
-enum cx231xx_capture_type {
- CX231xx_MPEG_CAPTURE,
- CX231xx_RAW_CAPTURE,
- CX231xx_RAW_PASSTHRU_CAPTURE
-};
-enum cx231xx_capture_bits {
- CX231xx_RAW_BITS_NONE = 0x00,
- CX231xx_RAW_BITS_YUV_CAPTURE = 0x01,
- CX231xx_RAW_BITS_PCM_CAPTURE = 0x02,
- CX231xx_RAW_BITS_VBI_CAPTURE = 0x04,
- CX231xx_RAW_BITS_PASSTHRU_CAPTURE = 0x08,
- CX231xx_RAW_BITS_TO_HOST_CAPTURE = 0x10
-};
-enum cx231xx_capture_end {
- CX231xx_END_AT_GOP, /* stop at the end of gop, generate irq */
- CX231xx_END_NOW, /* stop immediately, no irq */
-};
-enum cx231xx_framerate {
- CX231xx_FRAMERATE_NTSC_30, /* NTSC: 30fps */
- CX231xx_FRAMERATE_PAL_25 /* PAL: 25fps */
-};
-enum cx231xx_stream_port {
- CX231xx_OUTPUT_PORT_MEMORY,
- CX231xx_OUTPUT_PORT_STREAMING,
- CX231xx_OUTPUT_PORT_SERIAL
-};
-enum cx231xx_data_xfer_status {
- CX231xx_MORE_BUFFERS_FOLLOW,
- CX231xx_LAST_BUFFER,
-};
-enum cx231xx_picture_mask {
- CX231xx_PICTURE_MASK_NONE,
- CX231xx_PICTURE_MASK_I_FRAMES,
- CX231xx_PICTURE_MASK_I_P_FRAMES = 0x3,
- CX231xx_PICTURE_MASK_ALL_FRAMES = 0x7,
-};
-enum cx231xx_vbi_mode_bits {
- CX231xx_VBI_BITS_SLICED,
- CX231xx_VBI_BITS_RAW,
-};
-enum cx231xx_vbi_insertion_bits {
- CX231xx_VBI_BITS_INSERT_IN_XTENSION_USR_DATA,
- CX231xx_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1,
- CX231xx_VBI_BITS_SEPARATE_STREAM = 0x2 << 1,
- CX231xx_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1,
- CX231xx_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1,
-};
-enum cx231xx_dma_unit {
- CX231xx_DMA_BYTES,
- CX231xx_DMA_FRAMES,
-};
-enum cx231xx_dma_transfer_status_bits {
- CX231xx_DMA_TRANSFER_BITS_DONE = 0x01,
- CX231xx_DMA_TRANSFER_BITS_ERROR = 0x04,
- CX231xx_DMA_TRANSFER_BITS_LL_ERROR = 0x10,
-};
-enum cx231xx_pause {
- CX231xx_PAUSE_ENCODING,
- CX231xx_RESUME_ENCODING,
-};
-enum cx231xx_copyright {
- CX231xx_COPYRIGHT_OFF,
- CX231xx_COPYRIGHT_ON,
-};
-enum cx231xx_notification_type {
- CX231xx_NOTIFICATION_REFRESH,
-};
-enum cx231xx_notification_status {
- CX231xx_NOTIFICATION_OFF,
- CX231xx_NOTIFICATION_ON,
-};
-enum cx231xx_notification_mailbox {
- CX231xx_NOTIFICATION_NO_MAILBOX = -1,
-};
-enum cx231xx_field1_lines {
- CX231xx_FIELD1_SAA7114 = 0x00EF, /* 239 */
- CX231xx_FIELD1_SAA7115 = 0x00F0, /* 240 */
- CX231xx_FIELD1_MICRONAS = 0x0105, /* 261 */
-};
-enum cx231xx_field2_lines {
- CX231xx_FIELD2_SAA7114 = 0x00EF, /* 239 */
- CX231xx_FIELD2_SAA7115 = 0x00F0, /* 240 */
- CX231xx_FIELD2_MICRONAS = 0x0106, /* 262 */
-};
-enum cx231xx_custom_data_type {
- CX231xx_CUSTOM_EXTENSION_USR_DATA,
- CX231xx_CUSTOM_PRIVATE_PACKET,
-};
-enum cx231xx_mute {
- CX231xx_UNMUTE,
- CX231xx_MUTE,
-};
-enum cx231xx_mute_video_mask {
- CX231xx_MUTE_VIDEO_V_MASK = 0x0000FF00,
- CX231xx_MUTE_VIDEO_U_MASK = 0x00FF0000,
- CX231xx_MUTE_VIDEO_Y_MASK = 0xFF000000,
-};
-enum cx231xx_mute_video_shift {
- CX231xx_MUTE_VIDEO_V_SHIFT = 8,
- CX231xx_MUTE_VIDEO_U_SHIFT = 16,
- CX231xx_MUTE_VIDEO_Y_SHIFT = 24,
-};
-
-/* defines below are from ivtv-driver.h */
-#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
-
-/* Firmware API commands */
-#define IVTV_API_STD_TIMEOUT 500
-
-/* Registers */
-/* IVTV_REG_OFFSET */
-#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8)
-#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC)
-#define IVTV_REG_SPU (0x9050)
-#define IVTV_REG_HW_BLOCKS (0x9054)
-#define IVTV_REG_VPU (0x9058)
-#define IVTV_REG_APU (0xA064)
-
-/*
- * Bit definitions for MC417_RWD and MC417_OEN registers
- *
- * bits 31-16
- *+-----------+
- *| Reserved |
- *|+-----------+
- *| bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8
- *|+-------+-------+-------+-------+-------+-------+-------+-------+
- *|| MIWR# | MIRD# | MICS# |MIRDY# |MIADDR3|MIADDR2|MIADDR1|MIADDR0|
- *|+-------+-------+-------+-------+-------+-------+-------+-------+
- *| bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
- *|+-------+-------+-------+-------+-------+-------+-------+-------+
- *||MIDATA7|MIDATA6|MIDATA5|MIDATA4|MIDATA3|MIDATA2|MIDATA1|MIDATA0|
- *|+-------+-------+-------+-------+-------+-------+-------+-------+
- */
-#define MC417_MIWR 0x8000
-#define MC417_MIRD 0x4000
-#define MC417_MICS 0x2000
-#define MC417_MIRDY 0x1000
-#define MC417_MIADDR 0x0F00
-#define MC417_MIDATA 0x00FF
-
-
-/* Bit definitions for MC417_CTL register ****
- *bits 31-6 bits 5-4 bit 3 bits 2-1 Bit 0
- *+--------+-------------+--------+--------------+------------+
- *|Reserved|MC417_SPD_CTL|Reserved|MC417_GPIO_SEL|UART_GPIO_EN|
- *+--------+-------------+--------+--------------+------------+
- */
-#define MC417_SPD_CTL(x) (((x) << 4) & 0x00000030)
-#define MC417_GPIO_SEL(x) (((x) << 1) & 0x00000006)
-#define MC417_UART_GPIO_EN 0x00000001
-
-/* Values for speed control */
-#define MC417_SPD_CTL_SLOW 0x1
-#define MC417_SPD_CTL_MEDIUM 0x0
-#define MC417_SPD_CTL_FAST 0x3 /* b'1x, but we use b'11 */
-
-/* Values for GPIO select */
-#define MC417_GPIO_SEL_GPIO3 0x3
-#define MC417_GPIO_SEL_GPIO2 0x2
-#define MC417_GPIO_SEL_GPIO1 0x1
-#define MC417_GPIO_SEL_GPIO0 0x0
-
-
-#define CX23417_GPIO_MASK 0xFC0003FF
-static int setITVCReg(struct cx231xx *dev, u32 gpio_direction, u32 value)
-{
- int status = 0;
- u32 _gpio_direction = 0;
-
- _gpio_direction = _gpio_direction & CX23417_GPIO_MASK;
- _gpio_direction = _gpio_direction|gpio_direction;
- status = cx231xx_send_gpio_cmd(dev, _gpio_direction,
- (u8 *)&value, 4, 0, 0);
- return status;
-}
-static int getITVCReg(struct cx231xx *dev, u32 gpio_direction, u32 *pValue)
-{
- int status = 0;
- u32 _gpio_direction = 0;
-
- _gpio_direction = _gpio_direction & CX23417_GPIO_MASK;
- _gpio_direction = _gpio_direction|gpio_direction;
-
- status = cx231xx_send_gpio_cmd(dev, _gpio_direction,
- (u8 *)pValue, 4, 0, 1);
- return status;
-}
-
-static int waitForMciComplete(struct cx231xx *dev)
-{
- u32 gpio;
- u32 gpio_driection = 0;
- u8 count = 0;
- getITVCReg(dev, gpio_driection, &gpio);
-
- while (!(gpio&0x020000)) {
- msleep(10);
-
- getITVCReg(dev, gpio_driection, &gpio);
-
- if (count++ > 100) {
- dprintk(3, "ERROR: Timeout - gpio=%x\n", gpio);
- return -1;
- }
- }
- return 0;
-}
-
-static int mc417_register_write(struct cx231xx *dev, u16 address, u32 value)
-{
- u32 temp;
- int status = 0;
-
- temp = 0x82|MCI_REGISTER_DATA_BYTE0|((value&0x000000FF)<<8);
- temp = temp<<10;
- status = setITVCReg(dev, ITVC_WRITE_DIR, temp);
- if (status < 0)
- return status;
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*write data byte 1;*/
- temp = 0x82|MCI_REGISTER_DATA_BYTE1|(value&0x0000FF00);
- temp = temp<<10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*write data byte 2;*/
- temp = 0x82|MCI_REGISTER_DATA_BYTE2|((value&0x00FF0000)>>8);
- temp = temp<<10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*write data byte 3;*/
- temp = 0x82|MCI_REGISTER_DATA_BYTE3|((value&0xFF000000)>>16);
- temp = temp<<10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*write address byte 0;*/
- temp = 0x82|MCI_REGISTER_ADDRESS_BYTE0|((address&0x000000FF)<<8);
- temp = temp<<10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*write address byte 1;*/
- temp = 0x82|MCI_REGISTER_ADDRESS_BYTE1|(address&0x0000FF00);
- temp = temp<<10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*Write that the mode is write.*/
- temp = 0x82 | MCI_REGISTER_MODE | MCI_MODE_REGISTER_WRITE;
- temp = temp<<10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- return waitForMciComplete(dev);
-}
-
-static int mc417_register_read(struct cx231xx *dev, u16 address, u32 *value)
-{
- /*write address byte 0;*/
- u32 temp;
- u32 return_value = 0;
- int ret = 0;
-
- temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE0 | ((address & 0x00FF) << 8);
- temp = temp << 10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp | ((0x05) << 10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*write address byte 1;*/
- temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE1 | (address & 0xFF00);
- temp = temp << 10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp | ((0x05) << 10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*write that the mode is read;*/
- temp = 0x82 | MCI_REGISTER_MODE | MCI_MODE_REGISTER_READ;
- temp = temp << 10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp | ((0x05) << 10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*wait for the MIRDY line to be asserted ,
- signalling that the read is done;*/
- ret = waitForMciComplete(dev);
-
- /*switch the DATA- GPIO to input mode;*/
-
- /*Read data byte 0;*/
- temp = (0x82 | MCI_REGISTER_DATA_BYTE0) << 10;
- setITVCReg(dev, ITVC_READ_DIR, temp);
- temp = ((0x81 | MCI_REGISTER_DATA_BYTE0) << 10);
- setITVCReg(dev, ITVC_READ_DIR, temp);
- getITVCReg(dev, ITVC_READ_DIR, &temp);
- return_value |= ((temp & 0x03FC0000) >> 18);
- setITVCReg(dev, ITVC_READ_DIR, (0x87 << 10));
-
- /* Read data byte 1;*/
- temp = (0x82 | MCI_REGISTER_DATA_BYTE1) << 10;
- setITVCReg(dev, ITVC_READ_DIR, temp);
- temp = ((0x81 | MCI_REGISTER_DATA_BYTE1) << 10);
- setITVCReg(dev, ITVC_READ_DIR, temp);
- getITVCReg(dev, ITVC_READ_DIR, &temp);
-
- return_value |= ((temp & 0x03FC0000) >> 10);
- setITVCReg(dev, ITVC_READ_DIR, (0x87 << 10));
-
- /*Read data byte 2;*/
- temp = (0x82 | MCI_REGISTER_DATA_BYTE2) << 10;
- setITVCReg(dev, ITVC_READ_DIR, temp);
- temp = ((0x81 | MCI_REGISTER_DATA_BYTE2) << 10);
- setITVCReg(dev, ITVC_READ_DIR, temp);
- getITVCReg(dev, ITVC_READ_DIR, &temp);
- return_value |= ((temp & 0x03FC0000) >> 2);
- setITVCReg(dev, ITVC_READ_DIR, (0x87 << 10));
-
- /*Read data byte 3;*/
- temp = (0x82 | MCI_REGISTER_DATA_BYTE3) << 10;
- setITVCReg(dev, ITVC_READ_DIR, temp);
- temp = ((0x81 | MCI_REGISTER_DATA_BYTE3) << 10);
- setITVCReg(dev, ITVC_READ_DIR, temp);
- getITVCReg(dev, ITVC_READ_DIR, &temp);
- return_value |= ((temp & 0x03FC0000) << 6);
- setITVCReg(dev, ITVC_READ_DIR, (0x87 << 10));
-
- *value = return_value;
-
-
- return ret;
-}
-
-static int mc417_memory_write(struct cx231xx *dev, u32 address, u32 value)
-{
- /*write data byte 0;*/
-
- u32 temp;
- int ret = 0;
-
- temp = 0x82 | MCI_MEMORY_DATA_BYTE0|((value & 0x000000FF) << 8);
- temp = temp << 10;
- ret = setITVCReg(dev, ITVC_WRITE_DIR, temp);
- if (ret < 0)
- return ret;
- temp = temp | ((0x05) << 10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*write data byte 1;*/
- temp = 0x82 | MCI_MEMORY_DATA_BYTE1 | (value & 0x0000FF00);
- temp = temp << 10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp | ((0x05) << 10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*write data byte 2;*/
- temp = 0x82|MCI_MEMORY_DATA_BYTE2|((value&0x00FF0000)>>8);
- temp = temp<<10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*write data byte 3;*/
- temp = 0x82|MCI_MEMORY_DATA_BYTE3|((value&0xFF000000)>>16);
- temp = temp<<10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /* write address byte 2;*/
- temp = 0x82|MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_WRITE |
- ((address & 0x003F0000)>>8);
- temp = temp<<10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /* write address byte 1;*/
- temp = 0x82|MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00);
- temp = temp<<10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /* write address byte 0;*/
- temp = 0x82|MCI_MEMORY_ADDRESS_BYTE0|((address & 0x00FF)<<8);
- temp = temp<<10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*wait for MIRDY line;*/
- waitForMciComplete(dev);
-
- return 0;
-}
-
-static int mc417_memory_read(struct cx231xx *dev, u32 address, u32 *value)
-{
- u32 temp = 0;
- u32 return_value = 0;
- int ret = 0;
-
- /*write address byte 2;*/
- temp = 0x82|MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_READ |
- ((address & 0x003F0000)>>8);
- temp = temp<<10;
- ret = setITVCReg(dev, ITVC_WRITE_DIR, temp);
- if (ret < 0)
- return ret;
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*write address byte 1*/
- temp = 0x82|MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00);
- temp = temp<<10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*write address byte 0*/
- temp = 0x82|MCI_MEMORY_ADDRESS_BYTE0 | ((address & 0x00FF)<<8);
- temp = temp<<10;
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
- temp = temp|((0x05)<<10);
- setITVCReg(dev, ITVC_WRITE_DIR, temp);
-
- /*Wait for MIRDY line*/
- ret = waitForMciComplete(dev);
-
-
- /*Read data byte 3;*/
- temp = (0x82|MCI_MEMORY_DATA_BYTE3)<<10;
- setITVCReg(dev, ITVC_READ_DIR, temp);
- temp = ((0x81|MCI_MEMORY_DATA_BYTE3)<<10);
- setITVCReg(dev, ITVC_READ_DIR, temp);
- getITVCReg(dev, ITVC_READ_DIR, &temp);
- return_value |= ((temp&0x03FC0000)<<6);
- setITVCReg(dev, ITVC_READ_DIR, (0x87<<10));
-
- /*Read data byte 2;*/
- temp = (0x82|MCI_MEMORY_DATA_BYTE2)<<10;
- setITVCReg(dev, ITVC_READ_DIR, temp);
- temp = ((0x81|MCI_MEMORY_DATA_BYTE2)<<10);
- setITVCReg(dev, ITVC_READ_DIR, temp);
- getITVCReg(dev, ITVC_READ_DIR, &temp);
- return_value |= ((temp&0x03FC0000)>>2);
- setITVCReg(dev, ITVC_READ_DIR, (0x87<<10));
-
- /* Read data byte 1;*/
- temp = (0x82|MCI_MEMORY_DATA_BYTE1)<<10;
- setITVCReg(dev, ITVC_READ_DIR, temp);
- temp = ((0x81|MCI_MEMORY_DATA_BYTE1)<<10);
- setITVCReg(dev, ITVC_READ_DIR, temp);
- getITVCReg(dev, ITVC_READ_DIR, &temp);
- return_value |= ((temp&0x03FC0000)>>10);
- setITVCReg(dev, ITVC_READ_DIR, (0x87<<10));
-
- /*Read data byte 0;*/
- temp = (0x82|MCI_MEMORY_DATA_BYTE0)<<10;
- setITVCReg(dev, ITVC_READ_DIR, temp);
- temp = ((0x81|MCI_MEMORY_DATA_BYTE0)<<10);
- setITVCReg(dev, ITVC_READ_DIR, temp);
- getITVCReg(dev, ITVC_READ_DIR, &temp);
- return_value |= ((temp&0x03FC0000)>>18);
- setITVCReg(dev, ITVC_READ_DIR, (0x87<<10));
-
- *value = return_value;
- return ret;
-}
-
-/* ------------------------------------------------------------------ */
-
-/* MPEG encoder API */
-static char *cmd_to_str(int cmd)
-{
- switch (cmd) {
- case CX2341X_ENC_PING_FW:
- return "PING_FW";
- case CX2341X_ENC_START_CAPTURE:
- return "START_CAPTURE";
- case CX2341X_ENC_STOP_CAPTURE:
- return "STOP_CAPTURE";
- case CX2341X_ENC_SET_AUDIO_ID:
- return "SET_AUDIO_ID";
- case CX2341X_ENC_SET_VIDEO_ID:
- return "SET_VIDEO_ID";
- case CX2341X_ENC_SET_PCR_ID:
- return "SET_PCR_PID";
- case CX2341X_ENC_SET_FRAME_RATE:
- return "SET_FRAME_RATE";
- case CX2341X_ENC_SET_FRAME_SIZE:
- return "SET_FRAME_SIZE";
- case CX2341X_ENC_SET_BIT_RATE:
- return "SET_BIT_RATE";
- case CX2341X_ENC_SET_GOP_PROPERTIES:
- return "SET_GOP_PROPERTIES";
- case CX2341X_ENC_SET_ASPECT_RATIO:
- return "SET_ASPECT_RATIO";
- case CX2341X_ENC_SET_DNR_FILTER_MODE:
- return "SET_DNR_FILTER_PROPS";
- case CX2341X_ENC_SET_DNR_FILTER_PROPS:
- return "SET_DNR_FILTER_PROPS";
- case CX2341X_ENC_SET_CORING_LEVELS:
- return "SET_CORING_LEVELS";
- case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE:
- return "SET_SPATIAL_FILTER_TYPE";
- case CX2341X_ENC_SET_VBI_LINE:
- return "SET_VBI_LINE";
- case CX2341X_ENC_SET_STREAM_TYPE:
- return "SET_STREAM_TYPE";
- case CX2341X_ENC_SET_OUTPUT_PORT:
- return "SET_OUTPUT_PORT";
- case CX2341X_ENC_SET_AUDIO_PROPERTIES:
- return "SET_AUDIO_PROPERTIES";
- case CX2341X_ENC_HALT_FW:
- return "HALT_FW";
- case CX2341X_ENC_GET_VERSION:
- return "GET_VERSION";
- case CX2341X_ENC_SET_GOP_CLOSURE:
- return "SET_GOP_CLOSURE";
- case CX2341X_ENC_GET_SEQ_END:
- return "GET_SEQ_END";
- case CX2341X_ENC_SET_PGM_INDEX_INFO:
- return "SET_PGM_INDEX_INFO";
- case CX2341X_ENC_SET_VBI_CONFIG:
- return "SET_VBI_CONFIG";
- case CX2341X_ENC_SET_DMA_BLOCK_SIZE:
- return "SET_DMA_BLOCK_SIZE";
- case CX2341X_ENC_GET_PREV_DMA_INFO_MB_10:
- return "GET_PREV_DMA_INFO_MB_10";
- case CX2341X_ENC_GET_PREV_DMA_INFO_MB_9:
- return "GET_PREV_DMA_INFO_MB_9";
- case CX2341X_ENC_SCHED_DMA_TO_HOST:
- return "SCHED_DMA_TO_HOST";
- case CX2341X_ENC_INITIALIZE_INPUT:
- return "INITIALIZE_INPUT";
- case CX2341X_ENC_SET_FRAME_DROP_RATE:
- return "SET_FRAME_DROP_RATE";
- case CX2341X_ENC_PAUSE_ENCODER:
- return "PAUSE_ENCODER";
- case CX2341X_ENC_REFRESH_INPUT:
- return "REFRESH_INPUT";
- case CX2341X_ENC_SET_COPYRIGHT:
- return "SET_COPYRIGHT";
- case CX2341X_ENC_SET_EVENT_NOTIFICATION:
- return "SET_EVENT_NOTIFICATION";
- case CX2341X_ENC_SET_NUM_VSYNC_LINES:
- return "SET_NUM_VSYNC_LINES";
- case CX2341X_ENC_SET_PLACEHOLDER:
- return "SET_PLACEHOLDER";
- case CX2341X_ENC_MUTE_VIDEO:
- return "MUTE_VIDEO";
- case CX2341X_ENC_MUTE_AUDIO:
- return "MUTE_AUDIO";
- case CX2341X_ENC_MISC:
- return "MISC";
- default:
- return "UNKNOWN";
- }
-}
-
-static int cx231xx_mbox_func(void *priv,
- u32 command,
- int in,
- int out,
- u32 data[CX2341X_MBOX_MAX_DATA])
-{
- struct cx231xx *dev = priv;
- unsigned long timeout;
- u32 value, flag, retval = 0;
- int i;
-
- dprintk(3, "%s: command(0x%X) = %s\n", __func__, command,
- cmd_to_str(command));
-
- /* this may not be 100% safe if we can't read any memory location
- without side effects */
- mc417_memory_read(dev, dev->cx23417_mailbox - 4, &value);
- if (value != 0x12345678) {
- dprintk(3,
- "Firmware and/or mailbox pointer not initialized "
- "or corrupted, signature = 0x%x, cmd = %s\n", value,
- cmd_to_str(command));
- return -1;
- }
-
- /* This read looks at 32 bits, but flag is only 8 bits.
- * Seems we also bail if CMD or TIMEOUT bytes are set???
- */
- mc417_memory_read(dev, dev->cx23417_mailbox, &flag);
- if (flag) {
- dprintk(3, "ERROR: Mailbox appears to be in use "
- "(%x), cmd = %s\n", flag, cmd_to_str(command));
- return -1;
- }
-
- flag |= 1; /* tell 'em we're working on it */
- mc417_memory_write(dev, dev->cx23417_mailbox, flag);
-
- /* write command + args + fill remaining with zeros */
- /* command code */
- mc417_memory_write(dev, dev->cx23417_mailbox + 1, command);
- mc417_memory_write(dev, dev->cx23417_mailbox + 3,
- IVTV_API_STD_TIMEOUT); /* timeout */
- for (i = 0; i < in; i++) {
- mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, data[i]);
- dprintk(3, "API Input %d = %d\n", i, data[i]);
- }
- for (; i < CX2341X_MBOX_MAX_DATA; i++)
- mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, 0);
-
- flag |= 3; /* tell 'em we're done writing */
- mc417_memory_write(dev, dev->cx23417_mailbox, flag);
-
- /* wait for firmware to handle the API command */
- timeout = jiffies + msecs_to_jiffies(10);
- for (;;) {
- mc417_memory_read(dev, dev->cx23417_mailbox, &flag);
- if (0 != (flag & 4))
- break;
- if (time_after(jiffies, timeout)) {
- dprintk(3, "ERROR: API Mailbox timeout\n");
- return -1;
- }
- udelay(10);
- }
-
- /* read output values */
- for (i = 0; i < out; i++) {
- mc417_memory_read(dev, dev->cx23417_mailbox + 4 + i, data + i);
- dprintk(3, "API Output %d = %d\n", i, data[i]);
- }
-
- mc417_memory_read(dev, dev->cx23417_mailbox + 2, &retval);
- dprintk(3, "API result = %d\n", retval);
-
- flag = 0;
- mc417_memory_write(dev, dev->cx23417_mailbox, flag);
-
- return retval;
-}
-
-/* We don't need to call the API often, so using just one
- * mailbox will probably suffice
- */
-static int cx231xx_api_cmd(struct cx231xx *dev,
- u32 command,
- u32 inputcnt,
- u32 outputcnt,
- ...)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- va_list vargs;
- int i, err;
-
- dprintk(3, "%s() cmds = 0x%08x\n", __func__, command);
-
- va_start(vargs, outputcnt);
- for (i = 0; i < inputcnt; i++)
- data[i] = va_arg(vargs, int);
-
- err = cx231xx_mbox_func(dev, command, inputcnt, outputcnt, data);
- for (i = 0; i < outputcnt; i++) {
- int *vptr = va_arg(vargs, int *);
- *vptr = data[i];
- }
- va_end(vargs);
-
- return err;
-}
-
-static int cx231xx_find_mailbox(struct cx231xx *dev)
-{
- u32 signature[4] = {
- 0x12345678, 0x34567812, 0x56781234, 0x78123456
- };
- int signaturecnt = 0;
- u32 value;
- int i;
- int ret = 0;
-
- dprintk(2, "%s()\n", __func__);
-
- for (i = 0; i < 0x100; i++) {/*CX231xx_FIRM_IMAGE_SIZE*/
- ret = mc417_memory_read(dev, i, &value);
- if (ret < 0)
- return ret;
- if (value == signature[signaturecnt])
- signaturecnt++;
- else
- signaturecnt = 0;
- if (4 == signaturecnt) {
- dprintk(1, "Mailbox signature found at 0x%x\n", i+1);
- return i+1;
- }
- }
- dprintk(3, "Mailbox signature values not found!\n");
- return -1;
-}
-
-static void mciWriteMemoryToGPIO(struct cx231xx *dev, u32 address, u32 value,
- u32 *p_fw_image)
-{
-
- u32 temp = 0;
- int i = 0;
-
- temp = 0x82|MCI_MEMORY_DATA_BYTE0|((value&0x000000FF)<<8);
- temp = temp<<10;
- *p_fw_image = temp;
- p_fw_image++;
- temp = temp|((0x05)<<10);
- *p_fw_image = temp;
- p_fw_image++;
-
- /*write data byte 1;*/
- temp = 0x82|MCI_MEMORY_DATA_BYTE1|(value&0x0000FF00);
- temp = temp<<10;
- *p_fw_image = temp;
- p_fw_image++;
- temp = temp|((0x05)<<10);
- *p_fw_image = temp;
- p_fw_image++;
-
- /*write data byte 2;*/
- temp = 0x82|MCI_MEMORY_DATA_BYTE2|((value&0x00FF0000)>>8);
- temp = temp<<10;
- *p_fw_image = temp;
- p_fw_image++;
- temp = temp|((0x05)<<10);
- *p_fw_image = temp;
- p_fw_image++;
-
- /*write data byte 3;*/
- temp = 0x82|MCI_MEMORY_DATA_BYTE3|((value&0xFF000000)>>16);
- temp = temp<<10;
- *p_fw_image = temp;
- p_fw_image++;
- temp = temp|((0x05)<<10);
- *p_fw_image = temp;
- p_fw_image++;
-
- /* write address byte 2;*/
- temp = 0x82|MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_WRITE |
- ((address & 0x003F0000)>>8);
- temp = temp<<10;
- *p_fw_image = temp;
- p_fw_image++;
- temp = temp|((0x05)<<10);
- *p_fw_image = temp;
- p_fw_image++;
-
- /* write address byte 1;*/
- temp = 0x82|MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00);
- temp = temp<<10;
- *p_fw_image = temp;
- p_fw_image++;
- temp = temp|((0x05)<<10);
- *p_fw_image = temp;
- p_fw_image++;
-
- /* write address byte 0;*/
- temp = 0x82|MCI_MEMORY_ADDRESS_BYTE0|((address & 0x00FF)<<8);
- temp = temp<<10;
- *p_fw_image = temp;
- p_fw_image++;
- temp = temp|((0x05)<<10);
- *p_fw_image = temp;
- p_fw_image++;
-
- for (i = 0; i < 6; i++) {
- *p_fw_image = 0xFFFFFFFF;
- p_fw_image++;
- }
-}
-
-
-static int cx231xx_load_firmware(struct cx231xx *dev)
-{
- static const unsigned char magic[8] = {
- 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa
- };
- const struct firmware *firmware;
- int i, retval = 0;
- u32 value = 0;
- u32 gpio_output = 0;
- /*u32 checksum = 0;*/
- /*u32 *dataptr;*/
- u32 transfer_size = 0;
- u32 fw_data = 0;
- u32 address = 0;
- /*u32 current_fw[800];*/
- u32 *p_current_fw, *p_fw;
- u32 *p_fw_data;
- int frame = 0;
- u16 _buffer_size = 4096;
- u8 *p_buffer;
-
- p_current_fw = vmalloc(1884180 * 4);
- p_fw = p_current_fw;
- if (p_current_fw == NULL) {
- dprintk(2, "FAIL!!!\n");
- return -1;
- }
-
- p_buffer = vmalloc(4096);
- if (p_buffer == NULL) {
- dprintk(2, "FAIL!!!\n");
- return -1;
- }
-
- dprintk(2, "%s()\n", __func__);
-
- /* Save GPIO settings before reset of APU */
- retval |= mc417_memory_read(dev, 0x9020, &gpio_output);
- retval |= mc417_memory_read(dev, 0x900C, &value);
-
- retval = mc417_register_write(dev,
- IVTV_REG_VPU, 0xFFFFFFED);
- retval |= mc417_register_write(dev,
- IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
- retval |= mc417_register_write(dev,
- IVTV_REG_ENC_SDRAM_REFRESH, 0x80000800);
- retval |= mc417_register_write(dev,
- IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
- retval |= mc417_register_write(dev,
- IVTV_REG_APU, 0);
-
- if (retval != 0) {
- printk(KERN_ERR "%s: Error with mc417_register_write\n",
- __func__);
- return -1;
- }
-
- retval = request_firmware(&firmware, CX231xx_FIRM_IMAGE_NAME,
- &dev->udev->dev);
-
- if (retval != 0) {
- printk(KERN_ERR
- "ERROR: Hotplug firmware request failed (%s).\n",
- CX231xx_FIRM_IMAGE_NAME);
- printk(KERN_ERR "Please fix your hotplug setup, the board will "
- "not work without firmware loaded!\n");
- return -1;
- }
-
- if (firmware->size != CX231xx_FIRM_IMAGE_SIZE) {
- printk(KERN_ERR "ERROR: Firmware size mismatch "
- "(have %zd, expected %d)\n",
- firmware->size, CX231xx_FIRM_IMAGE_SIZE);
- release_firmware(firmware);
- return -1;
- }
-
- if (0 != memcmp(firmware->data, magic, 8)) {
- printk(KERN_ERR
- "ERROR: Firmware magic mismatch, wrong file?\n");
- release_firmware(firmware);
- return -1;
- }
-
- initGPIO(dev);
-
- /* transfer to the chip */
- dprintk(2, "Loading firmware to GPIO...\n");
- p_fw_data = (u32 *)firmware->data;
- dprintk(2, "firmware->size=%zd\n", firmware->size);
- for (transfer_size = 0; transfer_size < firmware->size;
- transfer_size += 4) {
- fw_data = *p_fw_data;
-
- mciWriteMemoryToGPIO(dev, address, fw_data, p_current_fw);
- address = address + 1;
- p_current_fw += 20;
- p_fw_data += 1;
- }
-
- /*download the firmware by ep5-out*/
-
- for (frame = 0; frame < (int)(CX231xx_FIRM_IMAGE_SIZE*20/_buffer_size);
- frame++) {
- for (i = 0; i < _buffer_size; i++) {
- *(p_buffer + i) = (u8)(*(p_fw + (frame * 128 * 8 + (i / 4))) & 0x000000FF);
- i++;
- *(p_buffer + i) = (u8)((*(p_fw + (frame * 128 * 8 + (i / 4))) & 0x0000FF00) >> 8);
- i++;
- *(p_buffer + i) = (u8)((*(p_fw + (frame * 128 * 8 + (i / 4))) & 0x00FF0000) >> 16);
- i++;
- *(p_buffer + i) = (u8)((*(p_fw + (frame * 128 * 8 + (i / 4))) & 0xFF000000) >> 24);
- }
- cx231xx_ep5_bulkout(dev, p_buffer, _buffer_size);
- }
-
- p_current_fw = p_fw;
- vfree(p_current_fw);
- p_current_fw = NULL;
- uninitGPIO(dev);
- release_firmware(firmware);
- dprintk(1, "Firmware upload successful.\n");
-
- retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS,
- IVTV_CMD_HW_BLOCKS_RST);
- if (retval < 0) {
- printk(KERN_ERR "%s: Error with mc417_register_write\n",
- __func__);
- return retval;
- }
- /* F/W power up disturbs the GPIOs, restore state */
- retval |= mc417_register_write(dev, 0x9020, gpio_output);
- retval |= mc417_register_write(dev, 0x900C, value);
-
- retval |= mc417_register_read(dev, IVTV_REG_VPU, &value);
- retval |= mc417_register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFE8);
-
- if (retval < 0) {
- printk(KERN_ERR "%s: Error with mc417_register_write\n",
- __func__);
- return retval;
- }
- return 0;
-}
-
-static void cx231xx_417_check_encoder(struct cx231xx *dev)
-{
- u32 status, seq;
-
- status = 0;
- seq = 0;
- cx231xx_api_cmd(dev, CX2341X_ENC_GET_SEQ_END, 0, 2, &status, &seq);
- dprintk(1, "%s() status = %d, seq = %d\n", __func__, status, seq);
-}
-
-static void cx231xx_codec_settings(struct cx231xx *dev)
-{
- dprintk(1, "%s()\n", __func__);
-
- /* assign frame size */
- cx231xx_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
- dev->ts1.height, dev->ts1.width);
-
- dev->mpeg_params.width = dev->ts1.width;
- dev->mpeg_params.height = dev->ts1.height;
-
- cx2341x_update(dev, cx231xx_mbox_func, NULL, &dev->mpeg_params);
-
- cx231xx_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1);
- cx231xx_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1);
-}
-
-static int cx231xx_initialize_codec(struct cx231xx *dev)
-{
- int version;
- int retval;
- u32 i;
- u32 val = 0;
-
- dprintk(1, "%s()\n", __func__);
- cx231xx_disable656(dev);
- retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
- if (retval < 0) {
- dprintk(2, "%s() PING OK\n", __func__);
- retval = cx231xx_load_firmware(dev);
- if (retval < 0) {
- printk(KERN_ERR "%s() f/w load failed\n", __func__);
- return retval;
- }
- retval = cx231xx_find_mailbox(dev);
- if (retval < 0) {
- printk(KERN_ERR "%s() mailbox < 0, error\n",
- __func__);
- return -1;
- }
- dev->cx23417_mailbox = retval;
- retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0);
- if (retval < 0) {
- printk(KERN_ERR
- "ERROR: cx23417 firmware ping failed!\n");
- return -1;
- }
- retval = cx231xx_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1,
- &version);
- if (retval < 0) {
- printk(KERN_ERR "ERROR: cx23417 firmware get encoder :"
- "version failed!\n");
- return -1;
- }
- dprintk(1, "cx23417 firmware version is 0x%08x\n", version);
- msleep(200);
- }
-
- for (i = 0; i < 1; i++) {
- retval = mc417_register_read(dev, 0x20f8, &val);
- dprintk(3, "***before enable656() VIM Capture Lines =%d ***\n",
- val);
- if (retval < 0)
- return retval;
- }
-
- cx231xx_enable656(dev);
- /* stop mpeg capture */
- cx231xx_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE,
- 3, 0, 1, 3, 4);
-
- cx231xx_codec_settings(dev);
- msleep(60);
-
-/* cx231xx_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0,
- CX231xx_FIELD1_SAA7115, CX231xx_FIELD2_SAA7115);
- cx231xx_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0,
- CX231xx_CUSTOM_EXTENSION_USR_DATA, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0);
-*/
-
-#if 0
- /* TODO */
- u32 data[7];
-
- /* Setup to capture VBI */
- data[0] = 0x0001BD00;
- data[1] = 1; /* frames per interrupt */
- data[2] = 4; /* total bufs */
- data[3] = 0x91559155; /* start codes */
- data[4] = 0x206080C0; /* stop codes */
- data[5] = 6; /* lines */
- data[6] = 64; /* BPL */
-
- cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_CONFIG, 7, 0, data[0], data[1],
- data[2], data[3], data[4], data[5], data[6]);
-
- for (i = 2; i <= 24; i++) {
- int valid;
-
- valid = ((i >= 19) && (i <= 21));
- cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, i,
- valid, 0 , 0, 0);
- cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0,
- i | 0x80000000, valid, 0, 0, 0);
- }
-#endif
-/* cx231xx_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, CX231xx_UNMUTE);
- msleep(60);
-*/
- /* initialize the video input */
- retval = cx231xx_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
- if (retval < 0)
- return retval;
- msleep(60);
-
- /* Enable VIP style pixel invalidation so we work with scaled mode */
- mc417_memory_write(dev, 2120, 0x00000080);
-
- /* start capturing to the host interface */
- retval = cx231xx_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0,
- CX231xx_MPEG_CAPTURE, CX231xx_RAW_BITS_NONE);
- if (retval < 0)
- return retval;
- msleep(10);
-
- for (i = 0; i < 1; i++) {
- mc417_register_read(dev, 0x20f8, &val);
- dprintk(3, "***VIM Capture Lines =%d ***\n", val);
- }
-
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int bb_buf_setup(struct videobuf_queue *q,
- unsigned int *count, unsigned int *size)
-{
- struct cx231xx_fh *fh = q->priv_data;
-
- fh->dev->ts1.ts_packet_size = mpeglinesize;
- fh->dev->ts1.ts_packet_count = mpeglines;
-
- *size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count;
- *count = mpegbufs;
-
- return 0;
-}
-static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
-{
- struct cx231xx_fh *fh = vq->priv_data;
- struct cx231xx *dev = fh->dev;
- unsigned long flags = 0;
-
- if (in_interrupt())
- BUG();
-
- spin_lock_irqsave(&dev->video_mode.slock, flags);
- if (dev->USE_ISO) {
- if (dev->video_mode.isoc_ctl.buf == buf)
- dev->video_mode.isoc_ctl.buf = NULL;
- } else {
- if (dev->video_mode.bulk_ctl.buf == buf)
- dev->video_mode.bulk_ctl.buf = NULL;
- }
- spin_unlock_irqrestore(&dev->video_mode.slock, flags);
- videobuf_waiton(vq, &buf->vb, 0, 0);
- videobuf_vmalloc_free(&buf->vb);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static void buffer_copy(struct cx231xx *dev, char *data, int len, struct urb *urb,
- struct cx231xx_dmaqueue *dma_q)
-{
- void *vbuf;
- struct cx231xx_buffer *buf;
- u32 tail_data = 0;
- char *p_data;
-
- if (dma_q->mpeg_buffer_done == 0) {
- if (list_empty(&dma_q->active))
- return;
-
- buf = list_entry(dma_q->active.next,
- struct cx231xx_buffer, vb.queue);
- dev->video_mode.isoc_ctl.buf = buf;
- dma_q->mpeg_buffer_done = 1;
- }
- /* Fill buffer */
- buf = dev->video_mode.isoc_ctl.buf;
- vbuf = videobuf_to_vmalloc(&buf->vb);
-
- if ((dma_q->mpeg_buffer_completed+len) <
- mpeglines*mpeglinesize) {
- if (dma_q->add_ps_package_head ==
- CX231XX_NEED_ADD_PS_PACKAGE_HEAD) {
- memcpy(vbuf+dma_q->mpeg_buffer_completed,
- dma_q->ps_head, 3);
- dma_q->mpeg_buffer_completed =
- dma_q->mpeg_buffer_completed + 3;
- dma_q->add_ps_package_head =
- CX231XX_NONEED_PS_PACKAGE_HEAD;
- }
- memcpy(vbuf+dma_q->mpeg_buffer_completed, data, len);
- dma_q->mpeg_buffer_completed =
- dma_q->mpeg_buffer_completed + len;
- } else {
- dma_q->mpeg_buffer_done = 0;
-
- tail_data =
- mpeglines*mpeglinesize - dma_q->mpeg_buffer_completed;
- memcpy(vbuf+dma_q->mpeg_buffer_completed,
- data, tail_data);
-
- buf->vb.state = VIDEOBUF_DONE;
- buf->vb.field_count++;
- do_gettimeofday(&buf->vb.ts);
- list_del(&buf->vb.queue);
- wake_up(&buf->vb.done);
- dma_q->mpeg_buffer_completed = 0;
-
- if (len - tail_data > 0) {
- p_data = data + tail_data;
- dma_q->left_data_count = len - tail_data;
- memcpy(dma_q->p_left_data,
- p_data, len - tail_data);
- }
-
- }
-
- return;
-}
-
-static void buffer_filled(char *data, int len, struct urb *urb,
- struct cx231xx_dmaqueue *dma_q)
-{
- void *vbuf;
- struct cx231xx_buffer *buf;
-
- if (list_empty(&dma_q->active))
- return;
-
-
- buf = list_entry(dma_q->active.next,
- struct cx231xx_buffer, vb.queue);
-
-
- /* Fill buffer */
- vbuf = videobuf_to_vmalloc(&buf->vb);
- memcpy(vbuf, data, len);
- buf->vb.state = VIDEOBUF_DONE;
- buf->vb.field_count++;
- do_gettimeofday(&buf->vb.ts);
- list_del(&buf->vb.queue);
- wake_up(&buf->vb.done);
-
- return;
-}
-static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
-{
- struct cx231xx_dmaqueue *dma_q = urb->context;
- unsigned char *p_buffer;
- u32 buffer_size = 0;
- u32 i = 0;
-
- for (i = 0; i < urb->number_of_packets; i++) {
- if (dma_q->left_data_count > 0) {
- buffer_copy(dev, dma_q->p_left_data,
- dma_q->left_data_count, urb, dma_q);
- dma_q->mpeg_buffer_completed = dma_q->left_data_count;
- dma_q->left_data_count = 0;
- }
-
- p_buffer = urb->transfer_buffer +
- urb->iso_frame_desc[i].offset;
- buffer_size = urb->iso_frame_desc[i].actual_length;
-
- if (buffer_size > 0)
- buffer_copy(dev, p_buffer, buffer_size, urb, dma_q);
- }
-
- return 0;
-}
-static inline int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb)
-{
-
- /*char *outp;*/
- /*struct cx231xx_buffer *buf;*/
- struct cx231xx_dmaqueue *dma_q = urb->context;
- unsigned char *p_buffer, *buffer;
- u32 buffer_size = 0;
-
- p_buffer = urb->transfer_buffer;
- buffer_size = urb->actual_length;
-
- buffer = kmalloc(buffer_size, GFP_ATOMIC);
-
- memcpy(buffer, dma_q->ps_head, 3);
- memcpy(buffer+3, p_buffer, buffer_size-3);
- memcpy(dma_q->ps_head, p_buffer+buffer_size-3, 3);
-
- p_buffer = buffer;
- buffer_filled(p_buffer, buffer_size, urb, dma_q);
-
- kfree(buffer);
- return 0;
-}
-
-static int bb_buf_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb, enum v4l2_field field)
-{
- struct cx231xx_fh *fh = q->priv_data;
- struct cx231xx_buffer *buf =
- container_of(vb, struct cx231xx_buffer, vb);
- struct cx231xx *dev = fh->dev;
- int rc = 0, urb_init = 0;
- int size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count;
-
- dma_qq = &dev->video_mode.vidq;
-
- if (0 != buf->vb.baddr && buf->vb.bsize < size)
- return -EINVAL;
- buf->vb.width = fh->dev->ts1.ts_packet_size;
- buf->vb.height = fh->dev->ts1.ts_packet_count;
- buf->vb.size = size;
- buf->vb.field = field;
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- rc = videobuf_iolock(q, &buf->vb, NULL);
- if (rc < 0)
- goto fail;
- }
-
- if (dev->USE_ISO) {
- if (!dev->video_mode.isoc_ctl.num_bufs)
- urb_init = 1;
- } else {
- if (!dev->video_mode.bulk_ctl.num_bufs)
- urb_init = 1;
- }
- /*cx231xx_info("urb_init=%d dev->video_mode.max_pkt_size=%d\n",
- urb_init, dev->video_mode.max_pkt_size);*/
- dev->mode_tv = 1;
-
- if (urb_init) {
- rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
- rc = cx231xx_unmute_audio(dev);
- if (dev->USE_ISO) {
- cx231xx_set_alt_setting(dev, INDEX_TS1, 4);
- rc = cx231xx_init_isoc(dev, mpeglines,
- mpegbufs,
- dev->ts1_mode.max_pkt_size,
- cx231xx_isoc_copy);
- } else {
- cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
- rc = cx231xx_init_bulk(dev, mpeglines,
- mpegbufs,
- dev->ts1_mode.max_pkt_size,
- cx231xx_bulk_copy);
- }
- if (rc < 0)
- goto fail;
- }
-
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
-fail:
- free_buffer(q, buf);
- return rc;
-}
-
-static void bb_buf_queue(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- struct cx231xx_fh *fh = q->priv_data;
-
- struct cx231xx_buffer *buf =
- container_of(vb, struct cx231xx_buffer, vb);
- struct cx231xx *dev = fh->dev;
- struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq;
-
- buf->vb.state = VIDEOBUF_QUEUED;
- list_add_tail(&buf->vb.queue, &vidq->active);
-
-}
-
-static void bb_buf_release(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- struct cx231xx_buffer *buf =
- container_of(vb, struct cx231xx_buffer, vb);
- /*struct cx231xx_fh *fh = q->priv_data;*/
- /*struct cx231xx *dev = (struct cx231xx *)fh->dev;*/
-
- free_buffer(q, buf);
-}
-
-static struct videobuf_queue_ops cx231xx_qops = {
- .buf_setup = bb_buf_setup,
- .buf_prepare = bb_buf_prepare,
- .buf_queue = bb_buf_queue,
- .buf_release = bb_buf_release,
-};
-
-/* ------------------------------------------------------------------ */
-
-static const u32 *ctrl_classes[] = {
- cx2341x_mpeg_ctrls,
- NULL
-};
-
-static int cx231xx_queryctrl(struct cx231xx *dev,
- struct v4l2_queryctrl *qctrl)
-{
- qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
- if (qctrl->id == 0)
- return -EINVAL;
-
- /* MPEG V4L2 controls */
- if (cx2341x_ctrl_query(&dev->mpeg_params, qctrl))
- qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
-
- return 0;
-}
-
-static int cx231xx_querymenu(struct cx231xx *dev,
- struct v4l2_querymenu *qmenu)
-{
- struct v4l2_queryctrl qctrl;
-
- qctrl.id = qmenu->id;
- cx231xx_queryctrl(dev, &qctrl);
- return v4l2_ctrl_query_menu(qmenu, &qctrl,
- cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id));
-}
-
-static int vidioc_g_std(struct file *file, void *fh0, v4l2_std_id *norm)
-{
- struct cx231xx_fh *fh = file->private_data;
- struct cx231xx *dev = fh->dev;
-
- *norm = dev->encodernorm.id;
- return 0;
-}
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
-{
- struct cx231xx_fh *fh = file->private_data;
- struct cx231xx *dev = fh->dev;
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(cx231xx_tvnorms); i++)
- if (*id & cx231xx_tvnorms[i].id)
- break;
- if (i == ARRAY_SIZE(cx231xx_tvnorms))
- return -EINVAL;
- dev->encodernorm = cx231xx_tvnorms[i];
-
- if (dev->encodernorm.id & 0xb000) {
- dprintk(3, "encodernorm set to NTSC\n");
- dev->norm = V4L2_STD_NTSC;
- dev->ts1.height = 480;
- dev->mpeg_params.is_50hz = 0;
- } else {
- dprintk(3, "encodernorm set to PAL\n");
- dev->norm = V4L2_STD_PAL_B;
- dev->ts1.height = 576;
- dev->mpeg_params.is_50hz = 1;
- }
- call_all(dev, core, s_std, dev->norm);
- /* do mode control overrides */
- cx231xx_do_mode_ctrl_overrides(dev);
-
- dprintk(3, "exit vidioc_s_std() i=0x%x\n", i);
- return 0;
-}
-static int vidioc_g_audio(struct file *file, void *fh,
- struct v4l2_audio *a)
-{
- struct v4l2_audio *vin = a;
-
- int ret = -EINVAL;
- if (vin->index > 0)
- return ret;
- strncpy(vin->name, "VideoGrabber Audio", 14);
- vin->capability = V4L2_AUDCAP_STEREO;
-return 0;
-}
-static int vidioc_enumaudio(struct file *file, void *fh,
- struct v4l2_audio *a)
-{
- struct v4l2_audio *vin = a;
-
- int ret = -EINVAL;
-
- if (vin->index > 0)
- return ret;
- strncpy(vin->name, "VideoGrabber Audio", 14);
- vin->capability = V4L2_AUDCAP_STEREO;
-
-
-return 0;
-}
-static const char *iname[] = {
- [CX231XX_VMUX_COMPOSITE1] = "Composite1",
- [CX231XX_VMUX_SVIDEO] = "S-Video",
- [CX231XX_VMUX_TELEVISION] = "Television",
- [CX231XX_VMUX_CABLE] = "Cable TV",
- [CX231XX_VMUX_DVB] = "DVB",
- [CX231XX_VMUX_DEBUG] = "for debug only",
-};
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct cx231xx_fh *fh = file->private_data;
- struct cx231xx *dev = fh->dev;
- struct cx231xx_input *input;
- int n;
- dprintk(3, "enter vidioc_enum_input()i->index=%d\n", i->index);
-
- if (i->index >= 4)
- return -EINVAL;
-
-
- input = &cx231xx_boards[dev->model].input[i->index];
-
- if (input->type == 0)
- return -EINVAL;
-
- /* FIXME
- * strcpy(i->name, input->name); */
-
- n = i->index;
- strcpy(i->name, iname[INPUT(n)->type]);
-
- if (input->type == CX231XX_VMUX_TELEVISION ||
- input->type == CX231XX_VMUX_CABLE)
- i->type = V4L2_INPUT_TYPE_TUNER;
- else
- i->type = V4L2_INPUT_TYPE_CAMERA;
-
-
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- struct cx231xx_fh *fh = file->private_data;
- struct cx231xx *dev = fh->dev;
-
- dprintk(3, "enter vidioc_s_input() i=%d\n", i);
-
- mutex_lock(&dev->lock);
-
- video_mux(dev, i);
-
- mutex_unlock(&dev->lock);
-
- if (i >= 4)
- return -EINVAL;
- dev->input = i;
- dprintk(3, "exit vidioc_s_input()\n");
- return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
-
-
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx231xx_fh *fh = file->private_data;
- struct cx231xx *dev = fh->dev;
- dprintk(3, "enter vidioc_s_ctrl()\n");
- /* Update the A/V core */
- call_all(dev, core, s_ctrl, ctl);
- dprintk(3, "exit vidioc_s_ctrl()\n");
- return 0;
-}
-static struct v4l2_capability pvr_capability = {
- .driver = "cx231xx",
- .card = "VideoGrabber",
- .bus_info = "usb",
- .version = 1,
- .capabilities = (V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
- V4L2_CAP_STREAMING | V4L2_CAP_READWRITE),
-};
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
-
-
-
- memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability));
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
-
- if (f->index != 0)
- return -EINVAL;
-
- strlcpy(f->description, "MPEG", sizeof(f->description));
- f->pixelformat = V4L2_PIX_FMT_MPEG;
-
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx231xx_fh *fh = file->private_data;
- struct cx231xx *dev = fh->dev;
- dprintk(3, "enter vidioc_g_fmt_vid_cap()\n");
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
- f->fmt.pix.colorspace = 0;
- f->fmt.pix.width = dev->ts1.width;
- f->fmt.pix.height = dev->ts1.height;
- f->fmt.pix.field = fh->vidq.field;
- dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
- dev->ts1.width, dev->ts1.height, fh->vidq.field);
- dprintk(3, "exit vidioc_g_fmt_vid_cap()\n");
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx231xx_fh *fh = file->private_data;
- struct cx231xx *dev = fh->dev;
- dprintk(3, "enter vidioc_try_fmt_vid_cap()\n");
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
- f->fmt.pix.colorspace = 0;
- dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
- dev->ts1.width, dev->ts1.height, fh->vidq.field);
- dprintk(3, "exit vidioc_try_fmt_vid_cap()\n");
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
-
- return 0;
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct cx231xx_fh *fh = file->private_data;
-
- return videobuf_reqbufs(&fh->vidq, p);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct cx231xx_fh *fh = file->private_data;
-
- return videobuf_querybuf(&fh->vidq, p);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct cx231xx_fh *fh = file->private_data;
-
- return videobuf_qbuf(&fh->vidq, p);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct cx231xx_fh *fh = priv;
-
- return videobuf_dqbuf(&fh->vidq, b, file->f_flags & O_NONBLOCK);
-}
-
-
-static int vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type i)
-{
- struct cx231xx_fh *fh = file->private_data;
-
- struct cx231xx *dev = fh->dev;
- dprintk(3, "enter vidioc_streamon()\n");
- cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
- cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
- if (dev->USE_ISO)
- cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS,
- CX231XX_NUM_BUFS,
- dev->video_mode.max_pkt_size,
- cx231xx_isoc_copy);
- else {
- cx231xx_init_bulk(dev, 320,
- 5,
- dev->ts1_mode.max_pkt_size,
- cx231xx_bulk_copy);
- }
- dprintk(3, "exit vidioc_streamon()\n");
- return videobuf_streamon(&fh->vidq);
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx231xx_fh *fh = file->private_data;
-
- return videobuf_streamoff(&fh->vidq);
-}
-
-static int vidioc_g_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *f)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- dprintk(3, "enter vidioc_g_ext_ctrls()\n");
- if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
- dprintk(3, "exit vidioc_g_ext_ctrls()\n");
- return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, VIDIOC_G_EXT_CTRLS);
-}
-
-static int vidioc_s_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *f)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- struct cx2341x_mpeg_params p;
- int err;
- dprintk(3, "enter vidioc_s_ext_ctrls()\n");
- if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
-
- p = dev->mpeg_params;
- err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS);
- if (err == 0) {
- err = cx2341x_update(dev, cx231xx_mbox_func,
- &dev->mpeg_params, &p);
- dev->mpeg_params = p;
- }
-
- return err;
-
-
-return 0;
-}
-
-static int vidioc_try_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *f)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- struct cx2341x_mpeg_params p;
- int err;
- dprintk(3, "enter vidioc_try_ext_ctrls()\n");
- if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
-
- p = dev->mpeg_params;
- err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS);
- dprintk(3, "exit vidioc_try_ext_ctrls() err=%d\n", err);
- return err;
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- char name[32 + 2];
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- dprintk(3,
- "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- call_all(dev, core, log_status);
- cx2341x_log_status(&dev->mpeg_params, name);
- dprintk(3,
- "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_querymenu(struct file *file, void *priv,
- struct v4l2_querymenu *a)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- dprintk(3, "enter vidioc_querymenu()\n");
- dprintk(3, "exit vidioc_querymenu()\n");
- return cx231xx_querymenu(dev, a);
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *c)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- dprintk(3, "enter vidioc_queryctrl()\n");
- dprintk(3, "exit vidioc_queryctrl()\n");
- return cx231xx_queryctrl(dev, c);
-}
-
-static int mpeg_open(struct file *file)
-{
- int minor = video_devdata(file)->minor;
- struct cx231xx *h, *dev = NULL;
- /*struct list_head *list;*/
- struct cx231xx_fh *fh;
- /*u32 value = 0;*/
-
- dprintk(2, "%s()\n", __func__);
-
- list_for_each_entry(h, &cx231xx_devlist, devlist) {
- if (h->v4l_device->minor == minor)
- dev = h;
- }
-
- if (dev == NULL)
- return -ENODEV;
-
- mutex_lock(&dev->lock);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh) {
- mutex_unlock(&dev->lock);
- return -ENOMEM;
- }
-
- file->private_data = fh;
- fh->dev = dev;
-
-
- videobuf_queue_vmalloc_init(&fh->vidq, &cx231xx_qops,
- NULL, &dev->video_mode.slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED,
- sizeof(struct cx231xx_buffer), fh, NULL);
-/*
- videobuf_queue_sg_init(&fh->vidq, &cx231xx_qops,
- &dev->udev->dev, &dev->ts1.slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx231xx_buffer),
- fh, NULL);
-*/
-
-
- cx231xx_set_alt_setting(dev, INDEX_VANC, 1);
- cx231xx_set_gpio_value(dev, 2, 0);
-
- cx231xx_initialize_codec(dev);
-
- mutex_unlock(&dev->lock);
- cx231xx_start_TS1(dev);
-
- return 0;
-}
-
-static int mpeg_release(struct file *file)
-{
- struct cx231xx_fh *fh = file->private_data;
- struct cx231xx *dev = fh->dev;
-
- dprintk(3, "mpeg_release()! dev=0x%p\n", dev);
-
- if (!dev) {
- dprintk(3, "abort!!!\n");
- return 0;
- }
-
- mutex_lock(&dev->lock);
-
- cx231xx_stop_TS1(dev);
-
- /* do this before setting alternate! */
- if (dev->USE_ISO)
- cx231xx_uninit_isoc(dev);
- else
- cx231xx_uninit_bulk(dev);
- cx231xx_set_mode(dev, CX231XX_SUSPEND);
-
- cx231xx_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
- CX231xx_END_NOW, CX231xx_MPEG_CAPTURE,
- CX231xx_RAW_BITS_NONE);
-
- /* FIXME: Review this crap */
- /* Shut device down on last close */
- if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
- if (atomic_dec_return(&dev->v4l_reader_count) == 0) {
- /* stop mpeg capture */
-
- msleep(500);
- cx231xx_417_check_encoder(dev);
-
- }
- }
-
- if (fh->vidq.streaming)
- videobuf_streamoff(&fh->vidq);
- if (fh->vidq.reading)
- videobuf_read_stop(&fh->vidq);
-
- videobuf_mmap_free(&fh->vidq);
- file->private_data = NULL;
- kfree(fh);
- mutex_unlock(&dev->lock);
- return 0;
-}
-
-static ssize_t mpeg_read(struct file *file, char __user *data,
- size_t count, loff_t *ppos)
-{
- struct cx231xx_fh *fh = file->private_data;
- struct cx231xx *dev = fh->dev;
-
-
- /* Deal w/ A/V decoder * and mpeg encoder sync issues. */
- /* Start mpeg encoder on first read. */
- if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
- if (atomic_inc_return(&dev->v4l_reader_count) == 1) {
- if (cx231xx_initialize_codec(dev) < 0)
- return -EINVAL;
- }
- }
-
- return videobuf_read_stream(&fh->vidq, data, count, ppos, 0,
- file->f_flags & O_NONBLOCK);
-}
-
-static unsigned int mpeg_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx231xx_fh *fh = file->private_data;
- /*struct cx231xx *dev = fh->dev;*/
-
- /*dprintk(2, "%s\n", __func__);*/
-
- return videobuf_poll_stream(file, &fh->vidq, wait);
-}
-
-static int mpeg_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct cx231xx_fh *fh = file->private_data;
- struct cx231xx *dev = fh->dev;
-
- dprintk(2, "%s()\n", __func__);
-
- return videobuf_mmap_mapper(&fh->vidq, vma);
-}
-
-static struct v4l2_file_operations mpeg_fops = {
- .owner = THIS_MODULE,
- .open = mpeg_open,
- .release = mpeg_release,
- .read = mpeg_read,
- .poll = mpeg_poll,
- .mmap = mpeg_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
- .vidioc_s_std = vidioc_s_std,
- .vidioc_g_std = vidioc_g_std,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_enumaudio = vidioc_enumaudio,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
- .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
- .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_querymenu = vidioc_querymenu,
- .vidioc_queryctrl = vidioc_queryctrl,
-/* .vidioc_g_chip_ident = cx231xx_g_chip_ident,*/
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-/* .vidioc_g_register = cx231xx_g_register,*/
-/* .vidioc_s_register = cx231xx_s_register,*/
-#endif
-};
-
-static struct video_device cx231xx_mpeg_template = {
- .name = "cx231xx",
- .fops = &mpeg_fops,
- .ioctl_ops = &mpeg_ioctl_ops,
- .minor = -1,
- .tvnorms = CX231xx_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
-
-void cx231xx_417_unregister(struct cx231xx *dev)
-{
- dprintk(1, "%s()\n", __func__);
- dprintk(3, "%s()\n", __func__);
-
- if (dev->v4l_device) {
- if (-1 != dev->v4l_device->minor)
- video_unregister_device(dev->v4l_device);
- else
- video_device_release(dev->v4l_device);
- dev->v4l_device = NULL;
- }
-}
-
-static struct video_device *cx231xx_video_dev_alloc(
- struct cx231xx *dev,
- struct usb_device *usbdev,
- struct video_device *template,
- char *type)
-{
- struct video_device *vfd;
-
- dprintk(1, "%s()\n", __func__);
- vfd = video_device_alloc();
- if (NULL == vfd)
- return NULL;
- *vfd = *template;
- vfd->minor = -1;
- snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
- type, cx231xx_boards[dev->model].name);
-
- vfd->v4l2_dev = &dev->v4l2_dev;
- vfd->release = video_device_release;
-
- return vfd;
-
-}
-
-int cx231xx_417_register(struct cx231xx *dev)
-{
- /* FIXME: Port1 hardcoded here */
- int err = -ENODEV;
- struct cx231xx_tsport *tsport = &dev->ts1;
-
- dprintk(1, "%s()\n", __func__);
-
- /* Set default TV standard */
- dev->encodernorm = cx231xx_tvnorms[0];
-
- if (dev->encodernorm.id & V4L2_STD_525_60)
- tsport->height = 480;
- else
- tsport->height = 576;
-
- tsport->width = 720;
- cx2341x_fill_defaults(&dev->mpeg_params);
- dev->norm = V4L2_STD_NTSC;
-
- dev->mpeg_params.port = CX2341X_PORT_SERIAL;
-
- /* Allocate and initialize V4L video device */
- dev->v4l_device = cx231xx_video_dev_alloc(dev,
- dev->udev, &cx231xx_mpeg_template, "mpeg");
- err = video_register_device(dev->v4l_device,
- VFL_TYPE_GRABBER, -1);
- if (err < 0) {
- dprintk(3, "%s: can't register mpeg device\n", dev->name);
- return err;
- }
-
- dprintk(3, "%s: registered device video%d [mpeg]\n",
- dev->name, dev->v4l_device->num);
-
- return 0;
-}
diff --git a/drivers/media/video/cx231xx/cx231xx-audio.c b/drivers/media/video/cx231xx/cx231xx-audio.c
deleted file mode 100644
index b4c99c7270c..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-audio.c
+++ /dev/null
@@ -1,780 +0,0 @@
-/*
- * Conexant Cx231xx audio extension
- *
- * Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
- * Based on em28xx driver
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/usb.h>
-#include <linux/init.h>
-#include <linux/sound.h>
-#include <linux/spinlock.h>
-#include <linux/soundcard.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/proc_fs.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/info.h>
-#include <sound/initval.h>
-#include <sound/control.h>
-#include <media/v4l2-common.h>
-#include "cx231xx.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "activates debug info");
-
-#define dprintk(fmt, arg...) do { \
- if (debug) \
- printk(KERN_INFO "cx231xx-audio %s: " fmt, \
- __func__, ##arg); \
- } while (0)
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-
-static int cx231xx_isoc_audio_deinit(struct cx231xx *dev)
-{
- int i;
-
- dprintk("Stopping isoc\n");
-
- for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
- if (dev->adev.urb[i]) {
- if (!irqs_disabled())
- usb_kill_urb(dev->adev.urb[i]);
- else
- usb_unlink_urb(dev->adev.urb[i]);
-
- usb_free_urb(dev->adev.urb[i]);
- dev->adev.urb[i] = NULL;
-
- kfree(dev->adev.transfer_buffer[i]);
- dev->adev.transfer_buffer[i] = NULL;
- }
- }
-
- return 0;
-}
-
-static int cx231xx_bulk_audio_deinit(struct cx231xx *dev)
-{
- int i;
-
- dprintk("Stopping bulk\n");
-
- for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
- if (dev->adev.urb[i]) {
- if (!irqs_disabled())
- usb_kill_urb(dev->adev.urb[i]);
- else
- usb_unlink_urb(dev->adev.urb[i]);
-
- usb_free_urb(dev->adev.urb[i]);
- dev->adev.urb[i] = NULL;
-
- kfree(dev->adev.transfer_buffer[i]);
- dev->adev.transfer_buffer[i] = NULL;
- }
- }
-
- return 0;
-}
-
-static void cx231xx_audio_isocirq(struct urb *urb)
-{
- struct cx231xx *dev = urb->context;
- int i;
- unsigned int oldptr;
- int period_elapsed = 0;
- int status;
- unsigned char *cp;
- unsigned int stride;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
-
- if (dev->state & DEV_DISCONNECTED)
- return;
-
- switch (urb->status) {
- case 0: /* success */
- case -ETIMEDOUT: /* NAK */
- break;
- case -ECONNRESET: /* kill */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- default: /* error */
- dprintk("urb completition error %d.\n", urb->status);
- break;
- }
-
- if (atomic_read(&dev->stream_started) == 0)
- return;
-
- if (dev->adev.capture_pcm_substream) {
- substream = dev->adev.capture_pcm_substream;
- runtime = substream->runtime;
- stride = runtime->frame_bits >> 3;
-
- for (i = 0; i < urb->number_of_packets; i++) {
- int length = urb->iso_frame_desc[i].actual_length /
- stride;
- cp = (unsigned char *)urb->transfer_buffer +
- urb->iso_frame_desc[i].offset;
-
- if (!length)
- continue;
-
- oldptr = dev->adev.hwptr_done_capture;
- if (oldptr + length >= runtime->buffer_size) {
- unsigned int cnt;
-
- cnt = runtime->buffer_size - oldptr;
- memcpy(runtime->dma_area + oldptr * stride, cp,
- cnt * stride);
- memcpy(runtime->dma_area, cp + cnt * stride,
- length * stride - cnt * stride);
- } else {
- memcpy(runtime->dma_area + oldptr * stride, cp,
- length * stride);
- }
-
- snd_pcm_stream_lock(substream);
-
- dev->adev.hwptr_done_capture += length;
- if (dev->adev.hwptr_done_capture >=
- runtime->buffer_size)
- dev->adev.hwptr_done_capture -=
- runtime->buffer_size;
-
- dev->adev.capture_transfer_done += length;
- if (dev->adev.capture_transfer_done >=
- runtime->period_size) {
- dev->adev.capture_transfer_done -=
- runtime->period_size;
- period_elapsed = 1;
- }
- snd_pcm_stream_unlock(substream);
- }
- if (period_elapsed)
- snd_pcm_period_elapsed(substream);
- }
- urb->status = 0;
-
- status = usb_submit_urb(urb, GFP_ATOMIC);
- if (status < 0) {
- cx231xx_errdev("resubmit of audio urb failed (error=%i)\n",
- status);
- }
- return;
-}
-
-static void cx231xx_audio_bulkirq(struct urb *urb)
-{
- struct cx231xx *dev = urb->context;
- unsigned int oldptr;
- int period_elapsed = 0;
- int status;
- unsigned char *cp;
- unsigned int stride;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
-
- if (dev->state & DEV_DISCONNECTED)
- return;
-
- switch (urb->status) {
- case 0: /* success */
- case -ETIMEDOUT: /* NAK */
- break;
- case -ECONNRESET: /* kill */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- default: /* error */
- dprintk("urb completition error %d.\n", urb->status);
- break;
- }
-
- if (atomic_read(&dev->stream_started) == 0)
- return;
-
- if (dev->adev.capture_pcm_substream) {
- substream = dev->adev.capture_pcm_substream;
- runtime = substream->runtime;
- stride = runtime->frame_bits >> 3;
-
- if (1) {
- int length = urb->actual_length /
- stride;
- cp = (unsigned char *)urb->transfer_buffer;
-
- oldptr = dev->adev.hwptr_done_capture;
- if (oldptr + length >= runtime->buffer_size) {
- unsigned int cnt;
-
- cnt = runtime->buffer_size - oldptr;
- memcpy(runtime->dma_area + oldptr * stride, cp,
- cnt * stride);
- memcpy(runtime->dma_area, cp + cnt * stride,
- length * stride - cnt * stride);
- } else {
- memcpy(runtime->dma_area + oldptr * stride, cp,
- length * stride);
- }
-
- snd_pcm_stream_lock(substream);
-
- dev->adev.hwptr_done_capture += length;
- if (dev->adev.hwptr_done_capture >=
- runtime->buffer_size)
- dev->adev.hwptr_done_capture -=
- runtime->buffer_size;
-
- dev->adev.capture_transfer_done += length;
- if (dev->adev.capture_transfer_done >=
- runtime->period_size) {
- dev->adev.capture_transfer_done -=
- runtime->period_size;
- period_elapsed = 1;
- }
- snd_pcm_stream_unlock(substream);
- }
- if (period_elapsed)
- snd_pcm_period_elapsed(substream);
- }
- urb->status = 0;
-
- status = usb_submit_urb(urb, GFP_ATOMIC);
- if (status < 0) {
- cx231xx_errdev("resubmit of audio urb failed (error=%i)\n",
- status);
- }
- return;
-}
-
-static int cx231xx_init_audio_isoc(struct cx231xx *dev)
-{
- int i, errCode;
- int sb_size;
-
- cx231xx_info("%s: Starting ISO AUDIO transfers\n", __func__);
-
- if (dev->state & DEV_DISCONNECTED)
- return -ENODEV;
-
- sb_size = CX231XX_ISO_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size;
-
- for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
- struct urb *urb;
- int j, k;
-
- dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC);
- if (!dev->adev.transfer_buffer[i])
- return -ENOMEM;
-
- memset(dev->adev.transfer_buffer[i], 0x80, sb_size);
- urb = usb_alloc_urb(CX231XX_ISO_NUM_AUDIO_PACKETS, GFP_ATOMIC);
- if (!urb) {
- cx231xx_errdev("usb_alloc_urb failed!\n");
- for (j = 0; j < i; j++) {
- usb_free_urb(dev->adev.urb[j]);
- kfree(dev->adev.transfer_buffer[j]);
- }
- return -ENOMEM;
- }
-
- urb->dev = dev->udev;
- urb->context = dev;
- urb->pipe = usb_rcvisocpipe(dev->udev,
- dev->adev.end_point_addr);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = dev->adev.transfer_buffer[i];
- urb->interval = 1;
- urb->complete = cx231xx_audio_isocirq;
- urb->number_of_packets = CX231XX_ISO_NUM_AUDIO_PACKETS;
- urb->transfer_buffer_length = sb_size;
-
- for (j = k = 0; j < CX231XX_ISO_NUM_AUDIO_PACKETS;
- j++, k += dev->adev.max_pkt_size) {
- urb->iso_frame_desc[j].offset = k;
- urb->iso_frame_desc[j].length = dev->adev.max_pkt_size;
- }
- dev->adev.urb[i] = urb;
- }
-
- for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
- errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
- if (errCode < 0) {
- cx231xx_isoc_audio_deinit(dev);
- return errCode;
- }
- }
-
- return errCode;
-}
-
-static int cx231xx_init_audio_bulk(struct cx231xx *dev)
-{
- int i, errCode;
- int sb_size;
-
- cx231xx_info("%s: Starting BULK AUDIO transfers\n", __func__);
-
- if (dev->state & DEV_DISCONNECTED)
- return -ENODEV;
-
- sb_size = CX231XX_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size;
-
- for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
- struct urb *urb;
- int j;
-
- dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC);
- if (!dev->adev.transfer_buffer[i])
- return -ENOMEM;
-
- memset(dev->adev.transfer_buffer[i], 0x80, sb_size);
- urb = usb_alloc_urb(CX231XX_NUM_AUDIO_PACKETS, GFP_ATOMIC);
- if (!urb) {
- cx231xx_errdev("usb_alloc_urb failed!\n");
- for (j = 0; j < i; j++) {
- usb_free_urb(dev->adev.urb[j]);
- kfree(dev->adev.transfer_buffer[j]);
- }
- return -ENOMEM;
- }
-
- urb->dev = dev->udev;
- urb->context = dev;
- urb->pipe = usb_rcvbulkpipe(dev->udev,
- dev->adev.end_point_addr);
- urb->transfer_flags = 0;
- urb->transfer_buffer = dev->adev.transfer_buffer[i];
- urb->complete = cx231xx_audio_bulkirq;
- urb->transfer_buffer_length = sb_size;
-
- dev->adev.urb[i] = urb;
-
- }
-
- for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
- errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
- if (errCode < 0) {
- cx231xx_bulk_audio_deinit(dev);
- return errCode;
- }
- }
-
- return errCode;
-}
-
-static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
- size_t size)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
-
- dprintk("Allocating vbuffer\n");
- if (runtime->dma_area) {
- if (runtime->dma_bytes > size)
- return 0;
-
- vfree(runtime->dma_area);
- }
- runtime->dma_area = vmalloc(size);
- if (!runtime->dma_area)
- return -ENOMEM;
-
- runtime->dma_bytes = size;
-
- return 0;
-}
-
-static struct snd_pcm_hardware snd_cx231xx_hw_capture = {
- .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID,
-
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
-
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT,
-
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */
- .period_bytes_min = 64, /* 12544/2, */
- .period_bytes_max = 12544,
- .periods_min = 2,
- .periods_max = 98, /* 12544, */
-};
-
-static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream)
-{
- struct cx231xx *dev = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int ret = 0;
-
- dprintk("opening device and trying to acquire exclusive lock\n");
-
- if (!dev) {
- cx231xx_errdev("BUG: cx231xx can't find device struct."
- " Can't proceed with open\n");
- return -ENODEV;
- }
-
- if (dev->state & DEV_DISCONNECTED) {
- cx231xx_errdev("Can't open. the device was removed.\n");
- return -ENODEV;
- }
-
- /* Sets volume, mute, etc */
- dev->mute = 0;
-
- /* set alternate setting for audio interface */
- /* 1 - 48000 samples per sec */
- mutex_lock(&dev->lock);
- if (dev->USE_ISO)
- ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 1);
- else
- ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0);
- mutex_unlock(&dev->lock);
- if (ret < 0) {
- cx231xx_errdev("failed to set alternate setting !\n");
-
- return ret;
- }
-
- runtime->hw = snd_cx231xx_hw_capture;
-
- mutex_lock(&dev->lock);
- /* inform hardware to start streaming */
- ret = cx231xx_capture_start(dev, 1, Audio);
-
- dev->adev.users++;
- mutex_unlock(&dev->lock);
-
- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- dev->adev.capture_pcm_substream = substream;
- runtime->private_data = dev;
-
- return 0;
-}
-
-static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream)
-{
- int ret;
- struct cx231xx *dev = snd_pcm_substream_chip(substream);
-
- dprintk("closing device\n");
-
- /* inform hardware to stop streaming */
- mutex_lock(&dev->lock);
- ret = cx231xx_capture_start(dev, 0, Audio);
-
- /* set alternate setting for audio interface */
- /* 1 - 48000 samples per sec */
- ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0);
- if (ret < 0) {
- cx231xx_errdev("failed to set alternate setting !\n");
-
- mutex_unlock(&dev->lock);
- return ret;
- }
-
- dev->mute = 1;
- dev->adev.users--;
- mutex_unlock(&dev->lock);
-
- if (dev->adev.users == 0 && dev->adev.shutdown == 1) {
- dprintk("audio users: %d\n", dev->adev.users);
- dprintk("disabling audio stream!\n");
- dev->adev.shutdown = 0;
- dprintk("released lock\n");
- if (atomic_read(&dev->stream_started) > 0) {
- atomic_set(&dev->stream_started, 0);
- schedule_work(&dev->wq_trigger);
- }
- }
- return 0;
-}
-
-static int snd_cx231xx_hw_capture_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- int ret;
-
- dprintk("Setting capture parameters\n");
-
- ret = snd_pcm_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(hw_params));
-#if 0
- /* TODO: set up cx231xx audio chip to deliver the correct audio format,
- current default is 48000hz multiplexed => 96000hz mono
- which shouldn't matter since analogue TV only supports mono */
- unsigned int channels, rate, format;
-
- format = params_format(hw_params);
- rate = params_rate(hw_params);
- channels = params_channels(hw_params);
-#endif
-
- return ret;
-}
-
-static int snd_cx231xx_hw_capture_free(struct snd_pcm_substream *substream)
-{
- struct cx231xx *dev = snd_pcm_substream_chip(substream);
-
- dprintk("Stop capture, if needed\n");
-
- if (atomic_read(&dev->stream_started) > 0) {
- atomic_set(&dev->stream_started, 0);
- schedule_work(&dev->wq_trigger);
- }
-
- return 0;
-}
-
-static int snd_cx231xx_prepare(struct snd_pcm_substream *substream)
-{
- struct cx231xx *dev = snd_pcm_substream_chip(substream);
-
- dev->adev.hwptr_done_capture = 0;
- dev->adev.capture_transfer_done = 0;
-
- return 0;
-}
-
-static void audio_trigger(struct work_struct *work)
-{
- struct cx231xx *dev = container_of(work, struct cx231xx, wq_trigger);
-
- if (atomic_read(&dev->stream_started)) {
- dprintk("starting capture");
- if (is_fw_load(dev) == 0)
- cx25840_call(dev, core, load_fw);
- if (dev->USE_ISO)
- cx231xx_init_audio_isoc(dev);
- else
- cx231xx_init_audio_bulk(dev);
- } else {
- dprintk("stopping capture");
- cx231xx_isoc_audio_deinit(dev);
- }
-}
-
-static int snd_cx231xx_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct cx231xx *dev = snd_pcm_substream_chip(substream);
- int retval = 0;
-
- if (dev->state & DEV_DISCONNECTED)
- return -ENODEV;
-
- spin_lock(&dev->adev.slock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- atomic_set(&dev->stream_started, 1);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- atomic_set(&dev->stream_started, 0);
- break;
- default:
- retval = -EINVAL;
- break;
- }
- spin_unlock(&dev->adev.slock);
-
- schedule_work(&dev->wq_trigger);
-
- return retval;
-}
-
-static snd_pcm_uframes_t snd_cx231xx_capture_pointer(struct snd_pcm_substream
- *substream)
-{
- struct cx231xx *dev;
- unsigned long flags;
- snd_pcm_uframes_t hwptr_done;
-
- dev = snd_pcm_substream_chip(substream);
-
- spin_lock_irqsave(&dev->adev.slock, flags);
- hwptr_done = dev->adev.hwptr_done_capture;
- spin_unlock_irqrestore(&dev->adev.slock, flags);
-
- return hwptr_done;
-}
-
-static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
- unsigned long offset)
-{
- void *pageptr = subs->runtime->dma_area + offset;
-
- return vmalloc_to_page(pageptr);
-}
-
-static struct snd_pcm_ops snd_cx231xx_pcm_capture = {
- .open = snd_cx231xx_capture_open,
- .close = snd_cx231xx_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cx231xx_hw_capture_params,
- .hw_free = snd_cx231xx_hw_capture_free,
- .prepare = snd_cx231xx_prepare,
- .trigger = snd_cx231xx_capture_trigger,
- .pointer = snd_cx231xx_capture_pointer,
- .page = snd_pcm_get_vmalloc_page,
-};
-
-static int cx231xx_audio_init(struct cx231xx *dev)
-{
- struct cx231xx_audio *adev = &dev->adev;
- struct snd_pcm *pcm;
- struct snd_card *card;
- static int devnr;
- int err;
- struct usb_interface *uif;
- int i, isoc_pipe = 0;
-
- if (dev->has_alsa_audio != 1) {
- /* This device does not support the extension (in this case
- the device is expecting the snd-usb-audio module or
- doesn't have analog audio support at all) */
- return 0;
- }
-
- cx231xx_info("cx231xx-audio.c: probing for cx231xx "
- "non standard usbaudio\n");
-
- err = snd_card_create(index[devnr], "Cx231xx Audio", THIS_MODULE,
- 0, &card);
- if (err < 0)
- return err;
-
- spin_lock_init(&adev->slock);
- err = snd_pcm_new(card, "Cx231xx Audio", 0, 0, 1, &pcm);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_cx231xx_pcm_capture);
- pcm->info_flags = 0;
- pcm->private_data = dev;
- strcpy(pcm->name, "Conexant cx231xx Capture");
- snd_card_set_dev(card, &dev->udev->dev);
- strcpy(card->driver, "Cx231xx-Audio");
- strcpy(card->shortname, "Cx231xx Audio");
- strcpy(card->longname, "Conexant cx231xx Audio");
-
- INIT_WORK(&dev->wq_trigger, audio_trigger);
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- adev->sndcard = card;
- adev->udev = dev->udev;
-
- /* compute alternate max packet sizes for Audio */
- uif =
- dev->udev->actconfig->interface[dev->current_pcb_config.
- hs_config_info[0].interface_info.
- audio_index + 1];
-
- adev->end_point_addr =
- le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
- bEndpointAddress);
-
- adev->num_alt = uif->num_altsetting;
- cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
- adev->end_point_addr, adev->num_alt);
- adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL);
-
- if (adev->alt_max_pkt_size == NULL) {
- cx231xx_errdev("out of memory!\n");
- return -ENOMEM;
- }
-
- for (i = 0; i < adev->num_alt; i++) {
- u16 tmp =
- le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.
- wMaxPacketSize);
- adev->alt_max_pkt_size[i] =
- (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
- cx231xx_info("Alternate setting %i, max size= %i\n", i,
- adev->alt_max_pkt_size[i]);
- }
-
- return 0;
-}
-
-static int cx231xx_audio_fini(struct cx231xx *dev)
-{
- if (dev == NULL)
- return 0;
-
- if (dev->has_alsa_audio != 1) {
- /* This device does not support the extension (in this case
- the device is expecting the snd-usb-audio module or
- doesn't have analog audio support at all) */
- return 0;
- }
-
- if (dev->adev.sndcard) {
- snd_card_free(dev->adev.sndcard);
- kfree(dev->adev.alt_max_pkt_size);
- dev->adev.sndcard = NULL;
- }
-
- return 0;
-}
-
-static struct cx231xx_ops audio_ops = {
- .id = CX231XX_AUDIO,
- .name = "Cx231xx Audio Extension",
- .init = cx231xx_audio_init,
- .fini = cx231xx_audio_fini,
-};
-
-static int __init cx231xx_alsa_register(void)
-{
- return cx231xx_register_extension(&audio_ops);
-}
-
-static void __exit cx231xx_alsa_unregister(void)
-{
- cx231xx_unregister_extension(&audio_ops);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>");
-MODULE_DESCRIPTION("Cx231xx Audio driver");
-
-module_init(cx231xx_alsa_register);
-module_exit(cx231xx_alsa_unregister);
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
deleted file mode 100644
index 447148eff95..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ /dev/null
@@ -1,3087 +0,0 @@
-/*
- cx231xx_avcore.c - driver for Conexant Cx23100/101/102
- USB video capture devices
-
- Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
-
- This program contains the specific code to control the avdecoder chip and
- other related usb control functions for cx231xx based chipset.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/bitmap.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <linux/mm.h>
-#include <linux/mutex.h>
-#include <media/tuner.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
-
-#include "cx231xx.h"
-#include "cx231xx-dif.h"
-
-#define TUNER_MODE_FM_RADIO 0
-/******************************************************************************
- -: BLOCK ARRANGEMENT :-
- I2S block ----------------------|
- [I2S audio] |
- |
- Analog Front End --> Direct IF -|-> Cx25840 --> Audio
- [video & audio] | [Audio]
- |
- |-> Cx25840 --> Video
- [Video]
-
-*******************************************************************************/
-/******************************************************************************
- * VERVE REGISTER *
- * *
- ******************************************************************************/
-static int verve_write_byte(struct cx231xx *dev, u8 saddr, u8 data)
-{
- return cx231xx_write_i2c_data(dev, VERVE_I2C_ADDRESS,
- saddr, 1, data, 1);
-}
-
-static int verve_read_byte(struct cx231xx *dev, u8 saddr, u8 *data)
-{
- int status;
- u32 temp = 0;
-
- status = cx231xx_read_i2c_data(dev, VERVE_I2C_ADDRESS,
- saddr, 1, &temp, 1);
- *data = (u8) temp;
- return status;
-}
-void initGPIO(struct cx231xx *dev)
-{
- u32 _gpio_direction = 0;
- u32 value = 0;
- u8 val = 0;
-
- _gpio_direction = _gpio_direction & 0xFC0003FF;
- _gpio_direction = _gpio_direction | 0x03FDFC00;
- cx231xx_send_gpio_cmd(dev, _gpio_direction, (u8 *)&value, 4, 0, 0);
-
- verve_read_byte(dev, 0x07, &val);
- cx231xx_info(" verve_read_byte address0x07=0x%x\n", val);
- verve_write_byte(dev, 0x07, 0xF4);
- verve_read_byte(dev, 0x07, &val);
- cx231xx_info(" verve_read_byte address0x07=0x%x\n", val);
-
- cx231xx_capture_start(dev, 1, Vbi);
-
- cx231xx_mode_register(dev, EP_MODE_SET, 0x0500FE00);
- cx231xx_mode_register(dev, GBULK_BIT_EN, 0xFFFDFFFF);
-
-}
-void uninitGPIO(struct cx231xx *dev)
-{
- u8 value[4] = { 0, 0, 0, 0 };
-
- cx231xx_capture_start(dev, 0, Vbi);
- verve_write_byte(dev, 0x07, 0x14);
- cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- 0x68, value, 4);
-}
-
-/******************************************************************************
- * A F E - B L O C K C O N T R O L functions *
- * [ANALOG FRONT END] *
- ******************************************************************************/
-static int afe_write_byte(struct cx231xx *dev, u16 saddr, u8 data)
-{
- return cx231xx_write_i2c_data(dev, AFE_DEVICE_ADDRESS,
- saddr, 2, data, 1);
-}
-
-static int afe_read_byte(struct cx231xx *dev, u16 saddr, u8 *data)
-{
- int status;
- u32 temp = 0;
-
- status = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
- saddr, 2, &temp, 1);
- *data = (u8) temp;
- return status;
-}
-
-int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count)
-{
- int status = 0;
- u8 temp = 0;
- u8 afe_power_status = 0;
- int i = 0;
-
- /* super block initialize */
- temp = (u8) (ref_count & 0xff);
- status = afe_write_byte(dev, SUP_BLK_TUNE2, temp);
- if (status < 0)
- return status;
-
- status = afe_read_byte(dev, SUP_BLK_TUNE2, &afe_power_status);
- if (status < 0)
- return status;
-
- temp = (u8) ((ref_count & 0x300) >> 8);
- temp |= 0x40;
- status = afe_write_byte(dev, SUP_BLK_TUNE1, temp);
- if (status < 0)
- return status;
-
- status = afe_write_byte(dev, SUP_BLK_PLL2, 0x0f);
- if (status < 0)
- return status;
-
- /* enable pll */
- while (afe_power_status != 0x18) {
- status = afe_write_byte(dev, SUP_BLK_PWRDN, 0x18);
- if (status < 0) {
- cx231xx_info(
- ": Init Super Block failed in send cmd\n");
- break;
- }
-
- status = afe_read_byte(dev, SUP_BLK_PWRDN, &afe_power_status);
- afe_power_status &= 0xff;
- if (status < 0) {
- cx231xx_info(
- ": Init Super Block failed in receive cmd\n");
- break;
- }
- i++;
- if (i == 10) {
- cx231xx_info(
- ": Init Super Block force break in loop !!!!\n");
- status = -1;
- break;
- }
- }
-
- if (status < 0)
- return status;
-
- /* start tuning filter */
- status = afe_write_byte(dev, SUP_BLK_TUNE3, 0x40);
- if (status < 0)
- return status;
-
- msleep(5);
-
- /* exit tuning */
- status = afe_write_byte(dev, SUP_BLK_TUNE3, 0x00);
-
- return status;
-}
-
-int cx231xx_afe_init_channels(struct cx231xx *dev)
-{
- int status = 0;
-
- /* power up all 3 channels, clear pd_buffer */
- status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1, 0x00);
- status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2, 0x00);
- status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, 0x00);
-
- /* Enable quantizer calibration */
- status = afe_write_byte(dev, ADC_COM_QUANT, 0x02);
-
- /* channel initialize, force modulator (fb) reset */
- status = afe_write_byte(dev, ADC_FB_FRCRST_CH1, 0x17);
- status = afe_write_byte(dev, ADC_FB_FRCRST_CH2, 0x17);
- status = afe_write_byte(dev, ADC_FB_FRCRST_CH3, 0x17);
-
- /* start quantilizer calibration */
- status = afe_write_byte(dev, ADC_CAL_ATEST_CH1, 0x10);
- status = afe_write_byte(dev, ADC_CAL_ATEST_CH2, 0x10);
- status = afe_write_byte(dev, ADC_CAL_ATEST_CH3, 0x10);
- msleep(5);
-
- /* exit modulator (fb) reset */
- status = afe_write_byte(dev, ADC_FB_FRCRST_CH1, 0x07);
- status = afe_write_byte(dev, ADC_FB_FRCRST_CH2, 0x07);
- status = afe_write_byte(dev, ADC_FB_FRCRST_CH3, 0x07);
-
- /* enable the pre_clamp in each channel for single-ended input */
- status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH1, 0xf0);
- status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH2, 0xf0);
- status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH3, 0xf0);
-
- /* use diode instead of resistor, so set term_en to 0, res_en to 0 */
- status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
- ADC_QGAIN_RES_TRM_CH1, 3, 7, 0x00);
- status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
- ADC_QGAIN_RES_TRM_CH2, 3, 7, 0x00);
- status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
- ADC_QGAIN_RES_TRM_CH3, 3, 7, 0x00);
-
- /* dynamic element matching off */
- status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH1, 0x03);
- status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH2, 0x03);
- status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH3, 0x03);
-
- return status;
-}
-
-int cx231xx_afe_setup_AFE_for_baseband(struct cx231xx *dev)
-{
- u8 c_value = 0;
- int status = 0;
-
- status = afe_read_byte(dev, ADC_PWRDN_CLAMP_CH2, &c_value);
- c_value &= (~(0x50));
- status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2, c_value);
-
- return status;
-}
-
-/*
- The Analog Front End in Cx231xx has 3 channels. These
- channels are used to share between different inputs
- like tuner, s-video and composite inputs.
-
- channel 1 ----- pin 1 to pin4(in reg is 1-4)
- channel 2 ----- pin 5 to pin8(in reg is 5-8)
- channel 3 ----- pin 9 to pin 12(in reg is 9-11)
-*/
-int cx231xx_afe_set_input_mux(struct cx231xx *dev, u32 input_mux)
-{
- u8 ch1_setting = (u8) input_mux;
- u8 ch2_setting = (u8) (input_mux >> 8);
- u8 ch3_setting = (u8) (input_mux >> 16);
- int status = 0;
- u8 value = 0;
-
- if (ch1_setting != 0) {
- status = afe_read_byte(dev, ADC_INPUT_CH1, &value);
- value &= ~INPUT_SEL_MASK;
- value |= (ch1_setting - 1) << 4;
- value &= 0xff;
- status = afe_write_byte(dev, ADC_INPUT_CH1, value);
- }
-
- if (ch2_setting != 0) {
- status = afe_read_byte(dev, ADC_INPUT_CH2, &value);
- value &= ~INPUT_SEL_MASK;
- value |= (ch2_setting - 1) << 4;
- value &= 0xff;
- status = afe_write_byte(dev, ADC_INPUT_CH2, value);
- }
-
- /* For ch3_setting, the value to put in the register is
- 7 less than the input number */
- if (ch3_setting != 0) {
- status = afe_read_byte(dev, ADC_INPUT_CH3, &value);
- value &= ~INPUT_SEL_MASK;
- value |= (ch3_setting - 1) << 4;
- value &= 0xff;
- status = afe_write_byte(dev, ADC_INPUT_CH3, value);
- }
-
- return status;
-}
-
-int cx231xx_afe_set_mode(struct cx231xx *dev, enum AFE_MODE mode)
-{
- int status = 0;
-
- /*
- * FIXME: We need to implement the AFE code for LOW IF and for HI IF.
- * Currently, only baseband works.
- */
-
- switch (mode) {
- case AFE_MODE_LOW_IF:
- cx231xx_Setup_AFE_for_LowIF(dev);
- break;
- case AFE_MODE_BASEBAND:
- status = cx231xx_afe_setup_AFE_for_baseband(dev);
- break;
- case AFE_MODE_EU_HI_IF:
- /* SetupAFEforEuHiIF(); */
- break;
- case AFE_MODE_US_HI_IF:
- /* SetupAFEforUsHiIF(); */
- break;
- case AFE_MODE_JAPAN_HI_IF:
- /* SetupAFEforJapanHiIF(); */
- break;
- }
-
- if ((mode != dev->afe_mode) &&
- (dev->video_input == CX231XX_VMUX_TELEVISION))
- status = cx231xx_afe_adjust_ref_count(dev,
- CX231XX_VMUX_TELEVISION);
-
- dev->afe_mode = mode;
-
- return status;
-}
-
-int cx231xx_afe_update_power_control(struct cx231xx *dev,
- enum AV_MODE avmode)
-{
- u8 afe_power_status = 0;
- int status = 0;
-
- switch (dev->model) {
- case CX231XX_BOARD_CNXT_CARRAERA:
- case CX231XX_BOARD_CNXT_RDE_250:
- case CX231XX_BOARD_CNXT_SHELBY:
- case CX231XX_BOARD_CNXT_RDU_250:
- case CX231XX_BOARD_CNXT_RDE_253S:
- case CX231XX_BOARD_CNXT_RDU_253S:
- case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
- case CX231XX_BOARD_HAUPPAUGE_EXETER:
- case CX231XX_BOARD_HAUPPAUGE_USBLIVE2:
- case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
- case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL:
- case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC:
- if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
- while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
- FLD_PWRDN_ENABLE_PLL)) {
- status = afe_write_byte(dev, SUP_BLK_PWRDN,
- FLD_PWRDN_TUNING_BIAS |
- FLD_PWRDN_ENABLE_PLL);
- status |= afe_read_byte(dev, SUP_BLK_PWRDN,
- &afe_power_status);
- if (status < 0)
- break;
- }
-
- status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
- 0x00);
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
- 0x00);
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
- 0x00);
- } else if (avmode == POLARIS_AVMODE_DIGITAL) {
- status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
- 0x70);
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
- 0x70);
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
- 0x70);
-
- status |= afe_read_byte(dev, SUP_BLK_PWRDN,
- &afe_power_status);
- afe_power_status |= FLD_PWRDN_PD_BANDGAP |
- FLD_PWRDN_PD_BIAS |
- FLD_PWRDN_PD_TUNECK;
- status |= afe_write_byte(dev, SUP_BLK_PWRDN,
- afe_power_status);
- } else if (avmode == POLARIS_AVMODE_ENXTERNAL_AV) {
- while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
- FLD_PWRDN_ENABLE_PLL)) {
- status = afe_write_byte(dev, SUP_BLK_PWRDN,
- FLD_PWRDN_TUNING_BIAS |
- FLD_PWRDN_ENABLE_PLL);
- status |= afe_read_byte(dev, SUP_BLK_PWRDN,
- &afe_power_status);
- if (status < 0)
- break;
- }
-
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
- 0x00);
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
- 0x00);
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
- 0x00);
- } else {
- cx231xx_info("Invalid AV mode input\n");
- status = -1;
- }
- break;
- default:
- if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
- while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
- FLD_PWRDN_ENABLE_PLL)) {
- status = afe_write_byte(dev, SUP_BLK_PWRDN,
- FLD_PWRDN_TUNING_BIAS |
- FLD_PWRDN_ENABLE_PLL);
- status |= afe_read_byte(dev, SUP_BLK_PWRDN,
- &afe_power_status);
- if (status < 0)
- break;
- }
-
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
- 0x40);
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
- 0x40);
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
- 0x00);
- } else if (avmode == POLARIS_AVMODE_DIGITAL) {
- status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
- 0x70);
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
- 0x70);
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
- 0x70);
-
- status |= afe_read_byte(dev, SUP_BLK_PWRDN,
- &afe_power_status);
- afe_power_status |= FLD_PWRDN_PD_BANDGAP |
- FLD_PWRDN_PD_BIAS |
- FLD_PWRDN_PD_TUNECK;
- status |= afe_write_byte(dev, SUP_BLK_PWRDN,
- afe_power_status);
- } else if (avmode == POLARIS_AVMODE_ENXTERNAL_AV) {
- while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
- FLD_PWRDN_ENABLE_PLL)) {
- status = afe_write_byte(dev, SUP_BLK_PWRDN,
- FLD_PWRDN_TUNING_BIAS |
- FLD_PWRDN_ENABLE_PLL);
- status |= afe_read_byte(dev, SUP_BLK_PWRDN,
- &afe_power_status);
- if (status < 0)
- break;
- }
-
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
- 0x00);
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
- 0x00);
- status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
- 0x40);
- } else {
- cx231xx_info("Invalid AV mode input\n");
- status = -1;
- }
- } /* switch */
-
- return status;
-}
-
-int cx231xx_afe_adjust_ref_count(struct cx231xx *dev, u32 video_input)
-{
- u8 input_mode = 0;
- u8 ntf_mode = 0;
- int status = 0;
-
- dev->video_input = video_input;
-
- if (video_input == CX231XX_VMUX_TELEVISION) {
- status = afe_read_byte(dev, ADC_INPUT_CH3, &input_mode);
- status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH3,
- &ntf_mode);
- } else {
- status = afe_read_byte(dev, ADC_INPUT_CH1, &input_mode);
- status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH1,
- &ntf_mode);
- }
-
- input_mode = (ntf_mode & 0x3) | ((input_mode & 0x6) << 1);
-
- switch (input_mode) {
- case SINGLE_ENDED:
- dev->afe_ref_count = 0x23C;
- break;
- case LOW_IF:
- dev->afe_ref_count = 0x24C;
- break;
- case EU_IF:
- dev->afe_ref_count = 0x258;
- break;
- case US_IF:
- dev->afe_ref_count = 0x260;
- break;
- default:
- break;
- }
-
- status = cx231xx_afe_init_super_block(dev, dev->afe_ref_count);
-
- return status;
-}
-
-/******************************************************************************
- * V I D E O / A U D I O D E C O D E R C O N T R O L functions *
- ******************************************************************************/
-static int vid_blk_write_byte(struct cx231xx *dev, u16 saddr, u8 data)
-{
- return cx231xx_write_i2c_data(dev, VID_BLK_I2C_ADDRESS,
- saddr, 2, data, 1);
-}
-
-static int vid_blk_read_byte(struct cx231xx *dev, u16 saddr, u8 *data)
-{
- int status;
- u32 temp = 0;
-
- status = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
- saddr, 2, &temp, 1);
- *data = (u8) temp;
- return status;
-}
-
-static int vid_blk_write_word(struct cx231xx *dev, u16 saddr, u32 data)
-{
- return cx231xx_write_i2c_data(dev, VID_BLK_I2C_ADDRESS,
- saddr, 2, data, 4);
-}
-
-static int vid_blk_read_word(struct cx231xx *dev, u16 saddr, u32 *data)
-{
- return cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
- saddr, 2, data, 4);
-}
-int cx231xx_check_fw(struct cx231xx *dev)
-{
- u8 temp = 0;
- int status = 0;
- status = vid_blk_read_byte(dev, DL_CTL_ADDRESS_LOW, &temp);
- if (status < 0)
- return status;
- else
- return temp;
-
-}
-
-int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input)
-{
- int status = 0;
-
- switch (INPUT(input)->type) {
- case CX231XX_VMUX_COMPOSITE1:
- case CX231XX_VMUX_SVIDEO:
- if ((dev->current_pcb_config.type == USB_BUS_POWER) &&
- (dev->power_mode != POLARIS_AVMODE_ENXTERNAL_AV)) {
- /* External AV */
- status = cx231xx_set_power_mode(dev,
- POLARIS_AVMODE_ENXTERNAL_AV);
- if (status < 0) {
- cx231xx_errdev("%s: set_power_mode : Failed to"
- " set Power - errCode [%d]!\n",
- __func__, status);
- return status;
- }
- }
- status = cx231xx_set_decoder_video_input(dev,
- INPUT(input)->type,
- INPUT(input)->vmux);
- break;
- case CX231XX_VMUX_TELEVISION:
- case CX231XX_VMUX_CABLE:
- if ((dev->current_pcb_config.type == USB_BUS_POWER) &&
- (dev->power_mode != POLARIS_AVMODE_ANALOGT_TV)) {
- /* Tuner */
- status = cx231xx_set_power_mode(dev,
- POLARIS_AVMODE_ANALOGT_TV);
- if (status < 0) {
- cx231xx_errdev("%s: set_power_mode:Failed"
- " to set Power - errCode [%d]!\n",
- __func__, status);
- return status;
- }
- }
- if (dev->tuner_type == TUNER_NXP_TDA18271)
- status = cx231xx_set_decoder_video_input(dev,
- CX231XX_VMUX_TELEVISION,
- INPUT(input)->vmux);
- else
- status = cx231xx_set_decoder_video_input(dev,
- CX231XX_VMUX_COMPOSITE1,
- INPUT(input)->vmux);
-
- break;
- default:
- cx231xx_errdev("%s: set_power_mode : Unknown Input %d !\n",
- __func__, INPUT(input)->type);
- break;
- }
-
- /* save the selection */
- dev->video_input = input;
-
- return status;
-}
-
-int cx231xx_set_decoder_video_input(struct cx231xx *dev,
- u8 pin_type, u8 input)
-{
- int status = 0;
- u32 value = 0;
-
- if (pin_type != dev->video_input) {
- status = cx231xx_afe_adjust_ref_count(dev, pin_type);
- if (status < 0) {
- cx231xx_errdev("%s: adjust_ref_count :Failed to set"
- "AFE input mux - errCode [%d]!\n",
- __func__, status);
- return status;
- }
- }
-
- /* call afe block to set video inputs */
- status = cx231xx_afe_set_input_mux(dev, input);
- if (status < 0) {
- cx231xx_errdev("%s: set_input_mux :Failed to set"
- " AFE input mux - errCode [%d]!\n",
- __func__, status);
- return status;
- }
-
- switch (pin_type) {
- case CX231XX_VMUX_COMPOSITE1:
- status = vid_blk_read_word(dev, AFE_CTRL, &value);
- value |= (0 << 13) | (1 << 4);
- value &= ~(1 << 5);
-
- /* set [24:23] [22:15] to 0 */
- value &= (~(0x1ff8000));
- /* set FUNC_MODE[24:23] = 2 IF_MOD[22:15] = 0 */
- value |= 0x1000000;
- status = vid_blk_write_word(dev, AFE_CTRL, value);
-
- status = vid_blk_read_word(dev, OUT_CTRL1, &value);
- value |= (1 << 7);
- status = vid_blk_write_word(dev, OUT_CTRL1, value);
-
- /* Set output mode */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- OUT_CTRL1,
- FLD_OUT_MODE,
- dev->board.output_mode);
-
- /* Tell DIF object to go to baseband mode */
- status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
- if (status < 0) {
- cx231xx_errdev("%s: cx231xx_dif set to By pass"
- " mode- errCode [%d]!\n",
- __func__, status);
- return status;
- }
-
- /* Read the DFE_CTRL1 register */
- status = vid_blk_read_word(dev, DFE_CTRL1, &value);
-
- /* enable the VBI_GATE_EN */
- value |= FLD_VBI_GATE_EN;
-
- /* Enable the auto-VGA enable */
- value |= FLD_VGA_AUTO_EN;
-
- /* Write it back */
- status = vid_blk_write_word(dev, DFE_CTRL1, value);
-
- /* Disable auto config of registers */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- MODE_CTRL, FLD_ACFG_DIS,
- cx231xx_set_field(FLD_ACFG_DIS, 1));
-
- /* Set CVBS input mode */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- MODE_CTRL, FLD_INPUT_MODE,
- cx231xx_set_field(FLD_INPUT_MODE, INPUT_MODE_CVBS_0));
- break;
- case CX231XX_VMUX_SVIDEO:
- /* Disable the use of DIF */
-
- status = vid_blk_read_word(dev, AFE_CTRL, &value);
-
- /* set [24:23] [22:15] to 0 */
- value &= (~(0x1ff8000));
- /* set FUNC_MODE[24:23] = 2
- IF_MOD[22:15] = 0 DCR_BYP_CH2[4:4] = 1; */
- value |= 0x1000010;
- status = vid_blk_write_word(dev, AFE_CTRL, value);
-
- /* Tell DIF object to go to baseband mode */
- status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
- if (status < 0) {
- cx231xx_errdev("%s: cx231xx_dif set to By pass"
- " mode- errCode [%d]!\n",
- __func__, status);
- return status;
- }
-
- /* Read the DFE_CTRL1 register */
- status = vid_blk_read_word(dev, DFE_CTRL1, &value);
-
- /* enable the VBI_GATE_EN */
- value |= FLD_VBI_GATE_EN;
-
- /* Enable the auto-VGA enable */
- value |= FLD_VGA_AUTO_EN;
-
- /* Write it back */
- status = vid_blk_write_word(dev, DFE_CTRL1, value);
-
- /* Disable auto config of registers */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- MODE_CTRL, FLD_ACFG_DIS,
- cx231xx_set_field(FLD_ACFG_DIS, 1));
-
- /* Set YC input mode */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- MODE_CTRL,
- FLD_INPUT_MODE,
- cx231xx_set_field(FLD_INPUT_MODE, INPUT_MODE_YC_1));
-
- /* Chroma to ADC2 */
- status = vid_blk_read_word(dev, AFE_CTRL, &value);
- value |= FLD_CHROMA_IN_SEL; /* set the chroma in select */
-
- /* Clear VGA_SEL_CH2 and VGA_SEL_CH3 (bits 7 and 8)
- This sets them to use video
- rather than audio. Only one of the two will be in use. */
- value &= ~(FLD_VGA_SEL_CH2 | FLD_VGA_SEL_CH3);
-
- status = vid_blk_write_word(dev, AFE_CTRL, value);
-
- status = cx231xx_afe_set_mode(dev, AFE_MODE_BASEBAND);
- break;
- case CX231XX_VMUX_TELEVISION:
- case CX231XX_VMUX_CABLE:
- default:
- /* TODO: Test if this is also needed for xc2028/xc3028 */
- if (dev->board.tuner_type == TUNER_XC5000) {
- /* Disable the use of DIF */
-
- status = vid_blk_read_word(dev, AFE_CTRL, &value);
- value |= (0 << 13) | (1 << 4);
- value &= ~(1 << 5);
-
- /* set [24:23] [22:15] to 0 */
- value &= (~(0x1FF8000));
- /* set FUNC_MODE[24:23] = 2 IF_MOD[22:15] = 0 */
- value |= 0x1000000;
- status = vid_blk_write_word(dev, AFE_CTRL, value);
-
- status = vid_blk_read_word(dev, OUT_CTRL1, &value);
- value |= (1 << 7);
- status = vid_blk_write_word(dev, OUT_CTRL1, value);
-
- /* Set output mode */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- OUT_CTRL1, FLD_OUT_MODE,
- dev->board.output_mode);
-
- /* Tell DIF object to go to baseband mode */
- status = cx231xx_dif_set_standard(dev,
- DIF_USE_BASEBAND);
- if (status < 0) {
- cx231xx_errdev("%s: cx231xx_dif set to By pass"
- " mode- errCode [%d]!\n",
- __func__, status);
- return status;
- }
-
- /* Read the DFE_CTRL1 register */
- status = vid_blk_read_word(dev, DFE_CTRL1, &value);
-
- /* enable the VBI_GATE_EN */
- value |= FLD_VBI_GATE_EN;
-
- /* Enable the auto-VGA enable */
- value |= FLD_VGA_AUTO_EN;
-
- /* Write it back */
- status = vid_blk_write_word(dev, DFE_CTRL1, value);
-
- /* Disable auto config of registers */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- MODE_CTRL, FLD_ACFG_DIS,
- cx231xx_set_field(FLD_ACFG_DIS, 1));
-
- /* Set CVBS input mode */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- MODE_CTRL, FLD_INPUT_MODE,
- cx231xx_set_field(FLD_INPUT_MODE,
- INPUT_MODE_CVBS_0));
- } else {
- /* Enable the DIF for the tuner */
-
- /* Reinitialize the DIF */
- status = cx231xx_dif_set_standard(dev, dev->norm);
- if (status < 0) {
- cx231xx_errdev("%s: cx231xx_dif set to By pass"
- " mode- errCode [%d]!\n",
- __func__, status);
- return status;
- }
-
- /* Make sure bypass is cleared */
- status = vid_blk_read_word(dev, DIF_MISC_CTRL, &value);
-
- /* Clear the bypass bit */
- value &= ~FLD_DIF_DIF_BYPASS;
-
- /* Enable the use of the DIF block */
- status = vid_blk_write_word(dev, DIF_MISC_CTRL, value);
-
- /* Read the DFE_CTRL1 register */
- status = vid_blk_read_word(dev, DFE_CTRL1, &value);
-
- /* Disable the VBI_GATE_EN */
- value &= ~FLD_VBI_GATE_EN;
-
- /* Enable the auto-VGA enable, AGC, and
- set the skip count to 2 */
- value |= FLD_VGA_AUTO_EN | FLD_AGC_AUTO_EN | 0x00200000;
-
- /* Write it back */
- status = vid_blk_write_word(dev, DFE_CTRL1, value);
-
- /* Wait until AGC locks up */
- msleep(1);
-
- /* Disable the auto-VGA enable AGC */
- value &= ~(FLD_VGA_AUTO_EN);
-
- /* Write it back */
- status = vid_blk_write_word(dev, DFE_CTRL1, value);
-
- /* Enable Polaris B0 AGC output */
- status = vid_blk_read_word(dev, PIN_CTRL, &value);
- value |= (FLD_OEF_AGC_RF) |
- (FLD_OEF_AGC_IFVGA) |
- (FLD_OEF_AGC_IF);
- status = vid_blk_write_word(dev, PIN_CTRL, value);
-
- /* Set output mode */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- OUT_CTRL1, FLD_OUT_MODE,
- dev->board.output_mode);
-
- /* Disable auto config of registers */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- MODE_CTRL, FLD_ACFG_DIS,
- cx231xx_set_field(FLD_ACFG_DIS, 1));
-
- /* Set CVBS input mode */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- MODE_CTRL, FLD_INPUT_MODE,
- cx231xx_set_field(FLD_INPUT_MODE,
- INPUT_MODE_CVBS_0));
-
- /* Set some bits in AFE_CTRL so that channel 2 or 3
- * is ready to receive audio */
- /* Clear clamp for channels 2 and 3 (bit 16-17) */
- /* Clear droop comp (bit 19-20) */
- /* Set VGA_SEL (for audio control) (bit 7-8) */
- status = vid_blk_read_word(dev, AFE_CTRL, &value);
-
- /*Set Func mode:01-DIF 10-baseband 11-YUV*/
- value &= (~(FLD_FUNC_MODE));
- value |= 0x800000;
-
- value |= FLD_VGA_SEL_CH3 | FLD_VGA_SEL_CH2;
-
- status = vid_blk_write_word(dev, AFE_CTRL, value);
-
- if (dev->tuner_type == TUNER_NXP_TDA18271) {
- status = vid_blk_read_word(dev, PIN_CTRL,
- &value);
- status = vid_blk_write_word(dev, PIN_CTRL,
- (value & 0xFFFFFFEF));
- }
-
- break;
-
- }
- break;
- }
-
- /* Set raw VBI mode */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- OUT_CTRL1, FLD_VBIHACTRAW_EN,
- cx231xx_set_field(FLD_VBIHACTRAW_EN, 1));
-
- status = vid_blk_read_word(dev, OUT_CTRL1, &value);
- if (value & 0x02) {
- value |= (1 << 19);
- status = vid_blk_write_word(dev, OUT_CTRL1, value);
- }
-
- return status;
-}
-
-void cx231xx_enable656(struct cx231xx *dev)
-{
- u8 temp = 0;
- /*enable TS1 data[0:7] as output to export 656*/
-
- vid_blk_write_byte(dev, TS1_PIN_CTL0, 0xFF);
-
- /*enable TS1 clock as output to export 656*/
-
- vid_blk_read_byte(dev, TS1_PIN_CTL1, &temp);
- temp = temp|0x04;
-
- vid_blk_write_byte(dev, TS1_PIN_CTL1, temp);
-}
-EXPORT_SYMBOL_GPL(cx231xx_enable656);
-
-void cx231xx_disable656(struct cx231xx *dev)
-{
- u8 temp = 0;
-
- vid_blk_write_byte(dev, TS1_PIN_CTL0, 0x00);
-
- vid_blk_read_byte(dev, TS1_PIN_CTL1, &temp);
- temp = temp&0xFB;
-
- vid_blk_write_byte(dev, TS1_PIN_CTL1, temp);
-}
-EXPORT_SYMBOL_GPL(cx231xx_disable656);
-
-/*
- * Handle any video-mode specific overrides that are different
- * on a per video standards basis after touching the MODE_CTRL
- * register which resets many values for autodetect
- */
-int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev)
-{
- int status = 0;
-
- cx231xx_info("do_mode_ctrl_overrides : 0x%x\n",
- (unsigned int)dev->norm);
-
- /* Change the DFE_CTRL3 bp_percent to fix flagging */
- status = vid_blk_write_word(dev, DFE_CTRL3, 0xCD3F0280);
-
- if (dev->norm & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) {
- cx231xx_info("do_mode_ctrl_overrides NTSC\n");
-
- /* Move the close caption lines out of active video,
- adjust the active video start point */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- VERT_TIM_CTRL,
- FLD_VBLANK_CNT, 0x18);
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- VERT_TIM_CTRL,
- FLD_VACTIVE_CNT,
- 0x1E7000);
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- VERT_TIM_CTRL,
- FLD_V656BLANK_CNT,
- 0x1C000000);
-
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- HORIZ_TIM_CTRL,
- FLD_HBLANK_CNT,
- cx231xx_set_field
- (FLD_HBLANK_CNT, 0x79));
-
- } else if (dev->norm & V4L2_STD_SECAM) {
- cx231xx_info("do_mode_ctrl_overrides SECAM\n");
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- VERT_TIM_CTRL,
- FLD_VBLANK_CNT, 0x20);
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- VERT_TIM_CTRL,
- FLD_VACTIVE_CNT,
- cx231xx_set_field
- (FLD_VACTIVE_CNT,
- 0x244));
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- VERT_TIM_CTRL,
- FLD_V656BLANK_CNT,
- cx231xx_set_field
- (FLD_V656BLANK_CNT,
- 0x24));
- /* Adjust the active video horizontal start point */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- HORIZ_TIM_CTRL,
- FLD_HBLANK_CNT,
- cx231xx_set_field
- (FLD_HBLANK_CNT, 0x85));
- } else {
- cx231xx_info("do_mode_ctrl_overrides PAL\n");
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- VERT_TIM_CTRL,
- FLD_VBLANK_CNT, 0x20);
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- VERT_TIM_CTRL,
- FLD_VACTIVE_CNT,
- cx231xx_set_field
- (FLD_VACTIVE_CNT,
- 0x244));
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- VERT_TIM_CTRL,
- FLD_V656BLANK_CNT,
- cx231xx_set_field
- (FLD_V656BLANK_CNT,
- 0x24));
- /* Adjust the active video horizontal start point */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- HORIZ_TIM_CTRL,
- FLD_HBLANK_CNT,
- cx231xx_set_field
- (FLD_HBLANK_CNT, 0x85));
-
- }
-
- return status;
-}
-
-int cx231xx_unmute_audio(struct cx231xx *dev)
-{
- return vid_blk_write_byte(dev, PATH1_VOL_CTL, 0x24);
-}
-EXPORT_SYMBOL_GPL(cx231xx_unmute_audio);
-
-int stopAudioFirmware(struct cx231xx *dev)
-{
- return vid_blk_write_byte(dev, DL_CTL_CONTROL, 0x03);
-}
-
-int restartAudioFirmware(struct cx231xx *dev)
-{
- return vid_blk_write_byte(dev, DL_CTL_CONTROL, 0x13);
-}
-
-int cx231xx_set_audio_input(struct cx231xx *dev, u8 input)
-{
- int status = 0;
- enum AUDIO_INPUT ainput = AUDIO_INPUT_LINE;
-
- switch (INPUT(input)->amux) {
- case CX231XX_AMUX_VIDEO:
- ainput = AUDIO_INPUT_TUNER_TV;
- break;
- case CX231XX_AMUX_LINE_IN:
- status = cx231xx_i2s_blk_set_audio_input(dev, input);
- ainput = AUDIO_INPUT_LINE;
- break;
- default:
- break;
- }
-
- status = cx231xx_set_audio_decoder_input(dev, ainput);
-
- return status;
-}
-
-int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
- enum AUDIO_INPUT audio_input)
-{
- u32 dwval;
- int status;
- u8 gen_ctrl;
- u32 value = 0;
-
- /* Put it in soft reset */
- status = vid_blk_read_byte(dev, GENERAL_CTL, &gen_ctrl);
- gen_ctrl |= 1;
- status = vid_blk_write_byte(dev, GENERAL_CTL, gen_ctrl);
-
- switch (audio_input) {
- case AUDIO_INPUT_LINE:
- /* setup AUD_IO control from Merlin paralle output */
- value = cx231xx_set_field(FLD_AUD_CHAN1_SRC,
- AUD_CHAN_SRC_PARALLEL);
- status = vid_blk_write_word(dev, AUD_IO_CTRL, value);
-
- /* setup input to Merlin, SRC2 connect to AC97
- bypass upsample-by-2, slave mode, sony mode, left justify
- adr 091c, dat 01000000 */
- status = vid_blk_read_word(dev, AC97_CTL, &dwval);
-
- status = vid_blk_write_word(dev, AC97_CTL,
- (dwval | FLD_AC97_UP2X_BYPASS));
-
- /* select the parallel1 and SRC3 */
- status = vid_blk_write_word(dev, BAND_OUT_SEL,
- cx231xx_set_field(FLD_SRC3_IN_SEL, 0x0) |
- cx231xx_set_field(FLD_SRC3_CLK_SEL, 0x0) |
- cx231xx_set_field(FLD_PARALLEL1_SRC_SEL, 0x0));
-
- /* unmute all, AC97 in, independence mode
- adr 08d0, data 0x00063073 */
- status = vid_blk_write_word(dev, DL_CTL, 0x3000001);
- status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063073);
-
- /* set AVC maximum threshold, adr 08d4, dat ffff0024 */
- status = vid_blk_read_word(dev, PATH1_VOL_CTL, &dwval);
- status = vid_blk_write_word(dev, PATH1_VOL_CTL,
- (dwval | FLD_PATH1_AVC_THRESHOLD));
-
- /* set SC maximum threshold, adr 08ec, dat ffffb3a3 */
- status = vid_blk_read_word(dev, PATH1_SC_CTL, &dwval);
- status = vid_blk_write_word(dev, PATH1_SC_CTL,
- (dwval | FLD_PATH1_SC_THRESHOLD));
- break;
-
- case AUDIO_INPUT_TUNER_TV:
- default:
- status = stopAudioFirmware(dev);
- /* Setup SRC sources and clocks */
- status = vid_blk_write_word(dev, BAND_OUT_SEL,
- cx231xx_set_field(FLD_SRC6_IN_SEL, 0x00) |
- cx231xx_set_field(FLD_SRC6_CLK_SEL, 0x01) |
- cx231xx_set_field(FLD_SRC5_IN_SEL, 0x00) |
- cx231xx_set_field(FLD_SRC5_CLK_SEL, 0x02) |
- cx231xx_set_field(FLD_SRC4_IN_SEL, 0x02) |
- cx231xx_set_field(FLD_SRC4_CLK_SEL, 0x03) |
- cx231xx_set_field(FLD_SRC3_IN_SEL, 0x00) |
- cx231xx_set_field(FLD_SRC3_CLK_SEL, 0x00) |
- cx231xx_set_field(FLD_BASEBAND_BYPASS_CTL, 0x00) |
- cx231xx_set_field(FLD_AC97_SRC_SEL, 0x03) |
- cx231xx_set_field(FLD_I2S_SRC_SEL, 0x00) |
- cx231xx_set_field(FLD_PARALLEL2_SRC_SEL, 0x02) |
- cx231xx_set_field(FLD_PARALLEL1_SRC_SEL, 0x01));
-
- /* Setup the AUD_IO control */
- status = vid_blk_write_word(dev, AUD_IO_CTRL,
- cx231xx_set_field(FLD_I2S_PORT_DIR, 0x00) |
- cx231xx_set_field(FLD_I2S_OUT_SRC, 0x00) |
- cx231xx_set_field(FLD_AUD_CHAN3_SRC, 0x00) |
- cx231xx_set_field(FLD_AUD_CHAN2_SRC, 0x00) |
- cx231xx_set_field(FLD_AUD_CHAN1_SRC, 0x03));
-
- status = vid_blk_write_word(dev, PATH1_CTL1, 0x1F063870);
-
- /* setAudioStandard(_audio_standard); */
- status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063870);
-
- status = restartAudioFirmware(dev);
-
- switch (dev->board.tuner_type) {
- case TUNER_XC5000:
- /* SIF passthrough at 28.6363 MHz sample rate */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- CHIP_CTRL,
- FLD_SIF_EN,
- cx231xx_set_field(FLD_SIF_EN, 1));
- break;
- case TUNER_NXP_TDA18271:
- /* Normal mode: SIF passthrough at 14.32 MHz */
- status = cx231xx_read_modify_write_i2c_dword(dev,
- VID_BLK_I2C_ADDRESS,
- CHIP_CTRL,
- FLD_SIF_EN,
- cx231xx_set_field(FLD_SIF_EN, 0));
- break;
- default:
- /* This is just a casual suggestion to people adding
- new boards in case they use a tuner type we don't
- currently know about */
- printk(KERN_INFO "Unknown tuner type configuring SIF");
- break;
- }
- break;
-
- case AUDIO_INPUT_TUNER_FM:
- /* use SIF for FM radio
- setupFM();
- setAudioStandard(_audio_standard);
- */
- break;
-
- case AUDIO_INPUT_MUTE:
- status = vid_blk_write_word(dev, PATH1_CTL1, 0x1F011012);
- break;
- }
-
- /* Take it out of soft reset */
- status = vid_blk_read_byte(dev, GENERAL_CTL, &gen_ctrl);
- gen_ctrl &= ~1;
- status = vid_blk_write_byte(dev, GENERAL_CTL, gen_ctrl);
-
- return status;
-}
-
-/******************************************************************************
- * C H I P Specific C O N T R O L functions *
- ******************************************************************************/
-int cx231xx_init_ctrl_pin_status(struct cx231xx *dev)
-{
- u32 value;
- int status = 0;
-
- status = vid_blk_read_word(dev, PIN_CTRL, &value);
- value |= (~dev->board.ctl_pin_status_mask);
- status = vid_blk_write_word(dev, PIN_CTRL, value);
-
- return status;
-}
-
-int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev,
- u8 analog_or_digital)
-{
- int status = 0;
-
- /* first set the direction to output */
- status = cx231xx_set_gpio_direction(dev,
- dev->board.
- agc_analog_digital_select_gpio, 1);
-
- /* 0 - demod ; 1 - Analog mode */
- status = cx231xx_set_gpio_value(dev,
- dev->board.agc_analog_digital_select_gpio,
- analog_or_digital);
-
- return status;
-}
-
-int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3)
-{
- u8 value[4] = { 0, 0, 0, 0 };
- int status = 0;
- bool current_is_port_3;
-
- if (dev->board.dont_use_port_3)
- is_port_3 = false;
- status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
- PWR_CTL_EN, value, 4);
- if (status < 0)
- return status;
-
- current_is_port_3 = value[0] & I2C_DEMOD_EN ? true : false;
-
- /* Just return, if already using the right port */
- if (current_is_port_3 == is_port_3)
- return 0;
-
- if (is_port_3)
- value[0] |= I2C_DEMOD_EN;
- else
- value[0] &= ~I2C_DEMOD_EN;
-
- cx231xx_info("Changing the i2c master port to %d\n",
- is_port_3 ? 3 : 1);
-
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
-
- return status;
-
-}
-EXPORT_SYMBOL_GPL(cx231xx_enable_i2c_port_3);
-
-void update_HH_register_after_set_DIF(struct cx231xx *dev)
-{
-/*
- u8 status = 0;
- u32 value = 0;
-
- vid_blk_write_word(dev, PIN_CTRL, 0xA0FFF82F);
- vid_blk_write_word(dev, DIF_MISC_CTRL, 0x0A203F11);
- vid_blk_write_word(dev, DIF_SRC_PHASE_INC, 0x1BEFBF06);
-
- status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value);
- vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390);
- status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value);
-*/
-}
-
-void cx231xx_dump_HH_reg(struct cx231xx *dev)
-{
- u32 value = 0;
- u16 i = 0;
-
- value = 0x45005390;
- vid_blk_write_word(dev, 0x104, value);
-
- for (i = 0x100; i < 0x140; i++) {
- vid_blk_read_word(dev, i, &value);
- cx231xx_info("reg0x%x=0x%x\n", i, value);
- i = i+3;
- }
-
- for (i = 0x300; i < 0x400; i++) {
- vid_blk_read_word(dev, i, &value);
- cx231xx_info("reg0x%x=0x%x\n", i, value);
- i = i+3;
- }
-
- for (i = 0x400; i < 0x440; i++) {
- vid_blk_read_word(dev, i, &value);
- cx231xx_info("reg0x%x=0x%x\n", i, value);
- i = i+3;
- }
-
- vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value);
- cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value);
- vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390);
- vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value);
- cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value);
-}
-
-void cx231xx_dump_SC_reg(struct cx231xx *dev)
-{
- u8 value[4] = { 0, 0, 0, 0 };
- cx231xx_info("cx231xx_dump_SC_reg!\n");
-
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", BOARD_CFG_STAT, value[0],
- value[1], value[2], value[3]);
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS_MODE_REG,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS_MODE_REG, value[0],
- value[1], value[2], value[3]);
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_CFG_REG,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_CFG_REG, value[0],
- value[1], value[2], value[3]);
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_LENGTH_REG,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_LENGTH_REG, value[0],
- value[1], value[2], value[3]);
-
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_CFG_REG,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_CFG_REG, value[0],
- value[1], value[2], value[3]);
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_LENGTH_REG,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_LENGTH_REG, value[0],
- value[1], value[2], value[3]);
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", EP_MODE_SET, value[0],
- value[1], value[2], value[3]);
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN1,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN1, value[0],
- value[1], value[2], value[3]);
-
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN2,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN2, value[0],
- value[1], value[2], value[3]);
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN3,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN3, value[0],
- value[1], value[2], value[3]);
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK0,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK0, value[0],
- value[1], value[2], value[3]);
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK1,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK1, value[0],
- value[1], value[2], value[3]);
-
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK2,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK2, value[0],
- value[1], value[2], value[3]);
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_GAIN,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_GAIN, value[0],
- value[1], value[2], value[3]);
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_CAR_REG,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_CAR_REG, value[0],
- value[1], value[2], value[3]);
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG1,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG1, value[0],
- value[1], value[2], value[3]);
-
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG2,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG2, value[0],
- value[1], value[2], value[3]);
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN,
- value, 4);
- cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, value[0],
- value[1], value[2], value[3]);
-
-
-}
-
-void cx231xx_Setup_AFE_for_LowIF(struct cx231xx *dev)
-
-{
- u8 value = 0;
-
- afe_read_byte(dev, ADC_STATUS2_CH3, &value);
- value = (value & 0xFE)|0x01;
- afe_write_byte(dev, ADC_STATUS2_CH3, value);
-
- afe_read_byte(dev, ADC_STATUS2_CH3, &value);
- value = (value & 0xFE)|0x00;
- afe_write_byte(dev, ADC_STATUS2_CH3, value);
-
-
-/*
- config colibri to lo-if mode
-
- FIXME: ntf_mode = 2'b00 by default. But set 0x1 would reduce
- the diff IF input by half,
-
- for low-if agc defect
-*/
-
- afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH3, &value);
- value = (value & 0xFC)|0x00;
- afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH3, value);
-
- afe_read_byte(dev, ADC_INPUT_CH3, &value);
- value = (value & 0xF9)|0x02;
- afe_write_byte(dev, ADC_INPUT_CH3, value);
-
- afe_read_byte(dev, ADC_FB_FRCRST_CH3, &value);
- value = (value & 0xFB)|0x04;
- afe_write_byte(dev, ADC_FB_FRCRST_CH3, value);
-
- afe_read_byte(dev, ADC_DCSERVO_DEM_CH3, &value);
- value = (value & 0xFC)|0x03;
- afe_write_byte(dev, ADC_DCSERVO_DEM_CH3, value);
-
- afe_read_byte(dev, ADC_CTRL_DAC1_CH3, &value);
- value = (value & 0xFB)|0x04;
- afe_write_byte(dev, ADC_CTRL_DAC1_CH3, value);
-
- afe_read_byte(dev, ADC_CTRL_DAC23_CH3, &value);
- value = (value & 0xF8)|0x06;
- afe_write_byte(dev, ADC_CTRL_DAC23_CH3, value);
-
- afe_read_byte(dev, ADC_CTRL_DAC23_CH3, &value);
- value = (value & 0x8F)|0x40;
- afe_write_byte(dev, ADC_CTRL_DAC23_CH3, value);
-
- afe_read_byte(dev, ADC_PWRDN_CLAMP_CH3, &value);
- value = (value & 0xDF)|0x20;
- afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, value);
-}
-
-void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq,
- u8 spectral_invert, u32 mode)
-{
- u32 colibri_carrier_offset = 0;
- u32 func_mode = 0x01; /* Device has a DIF if this function is called */
- u32 standard = 0;
- u8 value[4] = { 0, 0, 0, 0 };
-
- cx231xx_info("Enter cx231xx_set_Colibri_For_LowIF()\n");
- value[0] = (u8) 0x6F;
- value[1] = (u8) 0x6F;
- value[2] = (u8) 0x6F;
- value[3] = (u8) 0x6F;
- cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
-
- /*Set colibri for low IF*/
- cx231xx_afe_set_mode(dev, AFE_MODE_LOW_IF);
-
- /* Set C2HH for low IF operation.*/
- standard = dev->norm;
- cx231xx_dif_configure_C2HH_for_low_IF(dev, dev->active_mode,
- func_mode, standard);
-
- /* Get colibri offsets.*/
- colibri_carrier_offset = cx231xx_Get_Colibri_CarrierOffset(mode,
- standard);
-
- cx231xx_info("colibri_carrier_offset=%d, standard=0x%x\n",
- colibri_carrier_offset, standard);
-
- /* Set the band Pass filter for DIF*/
- cx231xx_set_DIF_bandpass(dev, (if_freq+colibri_carrier_offset),
- spectral_invert, mode);
-}
-
-u32 cx231xx_Get_Colibri_CarrierOffset(u32 mode, u32 standerd)
-{
- u32 colibri_carrier_offset = 0;
-
- if (mode == TUNER_MODE_FM_RADIO) {
- colibri_carrier_offset = 1100000;
- } else if (standerd & (V4L2_STD_MN | V4L2_STD_NTSC_M_JP)) {
- colibri_carrier_offset = 4832000; /*4.83MHz */
- } else if (standerd & (V4L2_STD_PAL_B | V4L2_STD_PAL_G)) {
- colibri_carrier_offset = 2700000; /*2.70MHz */
- } else if (standerd & (V4L2_STD_PAL_D | V4L2_STD_PAL_I
- | V4L2_STD_SECAM)) {
- colibri_carrier_offset = 2100000; /*2.10MHz */
- }
-
- return colibri_carrier_offset;
-}
-
-void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq,
- u8 spectral_invert, u32 mode)
-{
- unsigned long pll_freq_word;
- u32 dif_misc_ctrl_value = 0;
- u64 pll_freq_u64 = 0;
- u32 i = 0;
-
- cx231xx_info("if_freq=%d;spectral_invert=0x%x;mode=0x%x\n",
- if_freq, spectral_invert, mode);
-
-
- if (mode == TUNER_MODE_FM_RADIO) {
- pll_freq_word = 0x905A1CAC;
- vid_blk_write_word(dev, DIF_PLL_FREQ_WORD, pll_freq_word);
-
- } else /*KSPROPERTY_TUNER_MODE_TV*/{
- /* Calculate the PLL frequency word based on the adjusted if_freq*/
- pll_freq_word = if_freq;
- pll_freq_u64 = (u64)pll_freq_word << 28L;
- do_div(pll_freq_u64, 50000000);
- pll_freq_word = (u32)pll_freq_u64;
- /*pll_freq_word = 0x3463497;*/
- vid_blk_write_word(dev, DIF_PLL_FREQ_WORD, pll_freq_word);
-
- if (spectral_invert) {
- if_freq -= 400000;
- /* Enable Spectral Invert*/
- vid_blk_read_word(dev, DIF_MISC_CTRL,
- &dif_misc_ctrl_value);
- dif_misc_ctrl_value = dif_misc_ctrl_value | 0x00200000;
- vid_blk_write_word(dev, DIF_MISC_CTRL,
- dif_misc_ctrl_value);
- } else {
- if_freq += 400000;
- /* Disable Spectral Invert*/
- vid_blk_read_word(dev, DIF_MISC_CTRL,
- &dif_misc_ctrl_value);
- dif_misc_ctrl_value = dif_misc_ctrl_value & 0xFFDFFFFF;
- vid_blk_write_word(dev, DIF_MISC_CTRL,
- dif_misc_ctrl_value);
- }
-
- if_freq = (if_freq/100000)*100000;
-
- if (if_freq < 3000000)
- if_freq = 3000000;
-
- if (if_freq > 16000000)
- if_freq = 16000000;
- }
-
- cx231xx_info("Enter IF=%zd\n",
- ARRAY_SIZE(Dif_set_array));
- for (i = 0; i < ARRAY_SIZE(Dif_set_array); i++) {
- if (Dif_set_array[i].if_freq == if_freq) {
- vid_blk_write_word(dev,
- Dif_set_array[i].register_address, Dif_set_array[i].value);
- }
- }
-}
-
-/******************************************************************************
- * D I F - B L O C K C O N T R O L functions *
- ******************************************************************************/
-int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode,
- u32 function_mode, u32 standard)
-{
- int status = 0;
-
-
- if (mode == V4L2_TUNER_RADIO) {
- /* C2HH */
- /* lo if big signal */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
- /* FUNC_MODE = DIF */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 23, 24, function_mode);
- /* IF_MODE */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xFF);
- /* no inv */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
- } else if (standard != DIF_USE_BASEBAND) {
- if (standard & V4L2_STD_MN) {
- /* lo if big signal */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
- /* FUNC_MODE = DIF */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
- function_mode);
- /* IF_MODE */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xb);
- /* no inv */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
- /* 0x124, AUD_CHAN1_SRC = 0x3 */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AUD_IO_CTRL, 0, 31, 0x00000003);
- } else if ((standard == V4L2_STD_PAL_I) |
- (standard & V4L2_STD_PAL_D) |
- (standard & V4L2_STD_SECAM)) {
- /* C2HH setup */
- /* lo if big signal */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
- /* FUNC_MODE = DIF */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
- function_mode);
- /* IF_MODE */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xF);
- /* no inv */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
- } else {
- /* default PAL BG */
- /* C2HH setup */
- /* lo if big signal */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
- /* FUNC_MODE = DIF */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
- function_mode);
- /* IF_MODE */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xE);
- /* no inv */
- status = cx231xx_reg_mask_write(dev,
- VID_BLK_I2C_ADDRESS, 32,
- AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
- }
- }
-
- return status;
-}
-
-int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard)
-{
- int status = 0;
- u32 dif_misc_ctrl_value = 0;
- u32 func_mode = 0;
-
- cx231xx_info("%s: setStandard to %x\n", __func__, standard);
-
- status = vid_blk_read_word(dev, DIF_MISC_CTRL, &dif_misc_ctrl_value);
- if (standard != DIF_USE_BASEBAND)
- dev->norm = standard;
-
- switch (dev->model) {
- case CX231XX_BOARD_CNXT_CARRAERA:
- case CX231XX_BOARD_CNXT_RDE_250:
- case CX231XX_BOARD_CNXT_SHELBY:
- case CX231XX_BOARD_CNXT_RDU_250:
- case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
- case CX231XX_BOARD_HAUPPAUGE_EXETER:
- func_mode = 0x03;
- break;
- case CX231XX_BOARD_CNXT_RDE_253S:
- case CX231XX_BOARD_CNXT_RDU_253S:
- case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL:
- case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC:
- func_mode = 0x01;
- break;
- default:
- func_mode = 0x01;
- }
-
- status = cx231xx_dif_configure_C2HH_for_low_IF(dev, dev->active_mode,
- func_mode, standard);
-
- if (standard == DIF_USE_BASEBAND) { /* base band */
- /* There is a different SRC_PHASE_INC value
- for baseband vs. DIF */
- status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC, 0xDF7DF83);
- status = vid_blk_read_word(dev, DIF_MISC_CTRL,
- &dif_misc_ctrl_value);
- dif_misc_ctrl_value |= FLD_DIF_DIF_BYPASS;
- status = vid_blk_write_word(dev, DIF_MISC_CTRL,
- dif_misc_ctrl_value);
- } else if (standard & V4L2_STD_PAL_D) {
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL3, 0, 31, 0x00008800);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_IF_REF, 0, 31, 0x444C1380);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_IF_INT_CURRENT, 0, 31,
- 0x26001700);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_RF_CURRENT, 0, 31,
- 0x00002660);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_VIDEO_AGC_CTRL, 0, 31,
- 0x72500800);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_VID_AUD_OVERRIDE, 0, 31,
- 0x27000100);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AV_SEP_CTRL, 0, 31, 0x3F3934EA);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_COMP_FLT_CTRL, 0, 31,
- 0x00000000);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_SRC_PHASE_INC, 0, 31,
- 0x1befbf06);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_SRC_GAIN_CONTROL, 0, 31,
- 0x000035e8);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_RPT_VARIANCE, 0, 31, 0x00000000);
- /* Save the Spec Inversion value */
- dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
- dif_misc_ctrl_value |= 0x3a023F11;
- } else if (standard & V4L2_STD_PAL_I) {
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL3, 0, 31, 0x00008800);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_IF_REF, 0, 31, 0x444C1380);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_IF_INT_CURRENT, 0, 31,
- 0x26001700);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_RF_CURRENT, 0, 31,
- 0x00002660);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_VIDEO_AGC_CTRL, 0, 31,
- 0x72500800);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_VID_AUD_OVERRIDE, 0, 31,
- 0x27000100);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AV_SEP_CTRL, 0, 31, 0x5F39A934);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_COMP_FLT_CTRL, 0, 31,
- 0x00000000);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_SRC_PHASE_INC, 0, 31,
- 0x1befbf06);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_SRC_GAIN_CONTROL, 0, 31,
- 0x000035e8);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_RPT_VARIANCE, 0, 31, 0x00000000);
- /* Save the Spec Inversion value */
- dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
- dif_misc_ctrl_value |= 0x3a033F11;
- } else if (standard & V4L2_STD_PAL_M) {
- /* improved Low Frequency Phase Noise */
- status = vid_blk_write_word(dev, DIF_PLL_CTRL, 0xFF01FF0C);
- status = vid_blk_write_word(dev, DIF_PLL_CTRL1, 0xbd038c85);
- status = vid_blk_write_word(dev, DIF_PLL_CTRL2, 0x1db4640a);
- status = vid_blk_write_word(dev, DIF_PLL_CTRL3, 0x00008800);
- status = vid_blk_write_word(dev, DIF_AGC_IF_REF, 0x444C1380);
- status = vid_blk_write_word(dev, DIF_AGC_IF_INT_CURRENT,
- 0x26001700);
- status = vid_blk_write_word(dev, DIF_AGC_RF_CURRENT,
- 0x00002660);
- status = vid_blk_write_word(dev, DIF_VIDEO_AGC_CTRL,
- 0x72500800);
- status = vid_blk_write_word(dev, DIF_VID_AUD_OVERRIDE,
- 0x27000100);
- status = vid_blk_write_word(dev, DIF_AV_SEP_CTRL, 0x012c405d);
- status = vid_blk_write_word(dev, DIF_COMP_FLT_CTRL,
- 0x009f50c1);
- status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC,
- 0x1befbf06);
- status = vid_blk_write_word(dev, DIF_SRC_GAIN_CONTROL,
- 0x000035e8);
- status = vid_blk_write_word(dev, DIF_SOFT_RST_CTRL_REVB,
- 0x00000000);
- /* Save the Spec Inversion value */
- dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
- dif_misc_ctrl_value |= 0x3A0A3F10;
- } else if (standard & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) {
- /* improved Low Frequency Phase Noise */
- status = vid_blk_write_word(dev, DIF_PLL_CTRL, 0xFF01FF0C);
- status = vid_blk_write_word(dev, DIF_PLL_CTRL1, 0xbd038c85);
- status = vid_blk_write_word(dev, DIF_PLL_CTRL2, 0x1db4640a);
- status = vid_blk_write_word(dev, DIF_PLL_CTRL3, 0x00008800);
- status = vid_blk_write_word(dev, DIF_AGC_IF_REF, 0x444C1380);
- status = vid_blk_write_word(dev, DIF_AGC_IF_INT_CURRENT,
- 0x26001700);
- status = vid_blk_write_word(dev, DIF_AGC_RF_CURRENT,
- 0x00002660);
- status = vid_blk_write_word(dev, DIF_VIDEO_AGC_CTRL,
- 0x72500800);
- status = vid_blk_write_word(dev, DIF_VID_AUD_OVERRIDE,
- 0x27000100);
- status = vid_blk_write_word(dev, DIF_AV_SEP_CTRL,
- 0x012c405d);
- status = vid_blk_write_word(dev, DIF_COMP_FLT_CTRL,
- 0x009f50c1);
- status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC,
- 0x1befbf06);
- status = vid_blk_write_word(dev, DIF_SRC_GAIN_CONTROL,
- 0x000035e8);
- status = vid_blk_write_word(dev, DIF_SOFT_RST_CTRL_REVB,
- 0x00000000);
- /* Save the Spec Inversion value */
- dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
- dif_misc_ctrl_value = 0x3A093F10;
- } else if (standard &
- (V4L2_STD_SECAM_B | V4L2_STD_SECAM_D | V4L2_STD_SECAM_G |
- V4L2_STD_SECAM_K | V4L2_STD_SECAM_K1)) {
-
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL3, 0, 31, 0x00008800);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_IF_REF, 0, 31, 0x888C0380);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_IF, 0, 31, 0xe0262600);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_INT, 0, 31, 0xc2171700);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_RF, 0, 31, 0xc2262600);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_IF_INT_CURRENT, 0, 31,
- 0x26001700);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_RF_CURRENT, 0, 31,
- 0x00002660);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_VID_AUD_OVERRIDE, 0, 31,
- 0x27000100);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AV_SEP_CTRL, 0, 31, 0x3F3530ec);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_COMP_FLT_CTRL, 0, 31,
- 0x00000000);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_SRC_PHASE_INC, 0, 31,
- 0x1befbf06);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_SRC_GAIN_CONTROL, 0, 31,
- 0x000035e8);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_RPT_VARIANCE, 0, 31, 0x00000000);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_VIDEO_AGC_CTRL, 0, 31,
- 0xf4000000);
-
- /* Save the Spec Inversion value */
- dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
- dif_misc_ctrl_value |= 0x3a023F11;
- } else if (standard & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) {
- /* Is it SECAM_L1? */
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL3, 0, 31, 0x00008800);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_IF_REF, 0, 31, 0x888C0380);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_IF, 0, 31, 0xe0262600);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_INT, 0, 31, 0xc2171700);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_RF, 0, 31, 0xc2262600);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_IF_INT_CURRENT, 0, 31,
- 0x26001700);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_RF_CURRENT, 0, 31,
- 0x00002660);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_VID_AUD_OVERRIDE, 0, 31,
- 0x27000100);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AV_SEP_CTRL, 0, 31, 0x3F3530ec);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_COMP_FLT_CTRL, 0, 31,
- 0x00000000);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_SRC_PHASE_INC, 0, 31,
- 0x1befbf06);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_SRC_GAIN_CONTROL, 0, 31,
- 0x000035e8);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_RPT_VARIANCE, 0, 31, 0x00000000);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_VIDEO_AGC_CTRL, 0, 31,
- 0xf2560000);
-
- /* Save the Spec Inversion value */
- dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
- dif_misc_ctrl_value |= 0x3a023F11;
-
- } else if (standard & V4L2_STD_NTSC_M) {
- /* V4L2_STD_NTSC_M (75 IRE Setup) Or
- V4L2_STD_NTSC_M_JP (Japan, 0 IRE Setup) */
-
- /* For NTSC the centre frequency of video coming out of
- sidewinder is around 7.1MHz or 3.6MHz depending on the
- spectral inversion. so for a non spectrally inverted channel
- the pll freq word is 0x03420c49
- */
-
- status = vid_blk_write_word(dev, DIF_PLL_CTRL, 0x6503BC0C);
- status = vid_blk_write_word(dev, DIF_PLL_CTRL1, 0xBD038C85);
- status = vid_blk_write_word(dev, DIF_PLL_CTRL2, 0x1DB4640A);
- status = vid_blk_write_word(dev, DIF_PLL_CTRL3, 0x00008800);
- status = vid_blk_write_word(dev, DIF_AGC_IF_REF, 0x444C0380);
- status = vid_blk_write_word(dev, DIF_AGC_IF_INT_CURRENT,
- 0x26001700);
- status = vid_blk_write_word(dev, DIF_AGC_RF_CURRENT,
- 0x00002660);
- status = vid_blk_write_word(dev, DIF_VIDEO_AGC_CTRL,
- 0x04000800);
- status = vid_blk_write_word(dev, DIF_VID_AUD_OVERRIDE,
- 0x27000100);
- status = vid_blk_write_word(dev, DIF_AV_SEP_CTRL, 0x01296e1f);
-
- status = vid_blk_write_word(dev, DIF_COMP_FLT_CTRL,
- 0x009f50c1);
- status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC,
- 0x1befbf06);
- status = vid_blk_write_word(dev, DIF_SRC_GAIN_CONTROL,
- 0x000035e8);
-
- status = vid_blk_write_word(dev, DIF_AGC_CTRL_IF, 0xC2262600);
- status = vid_blk_write_word(dev, DIF_AGC_CTRL_INT,
- 0xC2262600);
- status = vid_blk_write_word(dev, DIF_AGC_CTRL_RF, 0xC2262600);
-
- /* Save the Spec Inversion value */
- dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
- dif_misc_ctrl_value |= 0x3a003F10;
- } else {
- /* default PAL BG */
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_PLL_CTRL3, 0, 31, 0x00008800);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_IF_REF, 0, 31, 0x444C1380);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_IF_INT_CURRENT, 0, 31,
- 0x26001700);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AGC_RF_CURRENT, 0, 31,
- 0x00002660);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_VIDEO_AGC_CTRL, 0, 31,
- 0x72500800);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_VID_AUD_OVERRIDE, 0, 31,
- 0x27000100);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_AV_SEP_CTRL, 0, 31, 0x3F3530EC);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_COMP_FLT_CTRL, 0, 31,
- 0x00A653A8);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_SRC_PHASE_INC, 0, 31,
- 0x1befbf06);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_SRC_GAIN_CONTROL, 0, 31,
- 0x000035e8);
- status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
- DIF_RPT_VARIANCE, 0, 31, 0x00000000);
- /* Save the Spec Inversion value */
- dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
- dif_misc_ctrl_value |= 0x3a013F11;
- }
-
- /* The AGC values should be the same for all standards,
- AUD_SRC_SEL[19] should always be disabled */
- dif_misc_ctrl_value &= ~FLD_DIF_AUD_SRC_SEL;
-
- /* It is still possible to get Set Standard calls even when we
- are in FM mode.
- This is done to override the value for FM. */
- if (dev->active_mode == V4L2_TUNER_RADIO)
- dif_misc_ctrl_value = 0x7a080000;
-
- /* Write the calculated value for misc ontrol register */
- status = vid_blk_write_word(dev, DIF_MISC_CTRL, dif_misc_ctrl_value);
-
- return status;
-}
-
-int cx231xx_tuner_pre_channel_change(struct cx231xx *dev)
-{
- int status = 0;
- u32 dwval;
-
- /* Set the RF and IF k_agc values to 3 */
- status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval);
- dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
- dwval |= 0x33000000;
-
- status = vid_blk_write_word(dev, DIF_AGC_IF_REF, dwval);
-
- return status;
-}
-
-int cx231xx_tuner_post_channel_change(struct cx231xx *dev)
-{
- int status = 0;
- u32 dwval;
- cx231xx_info("cx231xx_tuner_post_channel_change dev->tuner_type =0%d\n",
- dev->tuner_type);
- /* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for
- * SECAM L/B/D standards */
- status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval);
- dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
-
- if (dev->norm & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_B |
- V4L2_STD_SECAM_D)) {
- if (dev->tuner_type == TUNER_NXP_TDA18271) {
- dwval &= ~FLD_DIF_IF_REF;
- dwval |= 0x88000300;
- } else
- dwval |= 0x88000000;
- } else {
- if (dev->tuner_type == TUNER_NXP_TDA18271) {
- dwval &= ~FLD_DIF_IF_REF;
- dwval |= 0xCC000300;
- } else
- dwval |= 0x44000000;
- }
-
- status = vid_blk_write_word(dev, DIF_AGC_IF_REF, dwval);
-
- return status;
-}
-
-/******************************************************************************
- * I 2 S - B L O C K C O N T R O L functions *
- ******************************************************************************/
-int cx231xx_i2s_blk_initialize(struct cx231xx *dev)
-{
- int status = 0;
- u32 value;
-
- status = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
- CH_PWR_CTRL1, 1, &value, 1);
- /* enables clock to delta-sigma and decimation filter */
- value |= 0x80;
- status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
- CH_PWR_CTRL1, 1, value, 1);
- /* power up all channel */
- status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
- CH_PWR_CTRL2, 1, 0x00, 1);
-
- return status;
-}
-
-int cx231xx_i2s_blk_update_power_control(struct cx231xx *dev,
- enum AV_MODE avmode)
-{
- int status = 0;
- u32 value = 0;
-
- if (avmode != POLARIS_AVMODE_ENXTERNAL_AV) {
- status = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
- CH_PWR_CTRL2, 1, &value, 1);
- value |= 0xfe;
- status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
- CH_PWR_CTRL2, 1, value, 1);
- } else {
- status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
- CH_PWR_CTRL2, 1, 0x00, 1);
- }
-
- return status;
-}
-
-/* set i2s_blk for audio input types */
-int cx231xx_i2s_blk_set_audio_input(struct cx231xx *dev, u8 audio_input)
-{
- int status = 0;
-
- switch (audio_input) {
- case CX231XX_AMUX_LINE_IN:
- status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
- CH_PWR_CTRL2, 1, 0x00, 1);
- status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
- CH_PWR_CTRL1, 1, 0x80, 1);
- break;
- case CX231XX_AMUX_VIDEO:
- default:
- break;
- }
-
- dev->ctl_ainput = audio_input;
-
- return status;
-}
-
-/******************************************************************************
- * P O W E R C O N T R O L functions *
- ******************************************************************************/
-int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode)
-{
- u8 value[4] = { 0, 0, 0, 0 };
- u32 tmp = 0;
- int status = 0;
-
- if (dev->power_mode != mode)
- dev->power_mode = mode;
- else {
- cx231xx_info(" setPowerMode::mode = %d, No Change req.\n",
- mode);
- return 0;
- }
-
- status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value,
- 4);
- if (status < 0)
- return status;
-
- tmp = *((u32 *) value);
-
- switch (mode) {
- case POLARIS_AVMODE_ENXTERNAL_AV:
-
- tmp &= (~PWR_MODE_MASK);
-
- tmp |= PWR_AV_EN;
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(PWR_SLEEP_INTERVAL);
-
- tmp |= PWR_ISO_EN;
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status =
- cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, PWR_CTL_EN,
- value, 4);
- msleep(PWR_SLEEP_INTERVAL);
-
- tmp |= POLARIS_AVMODE_ENXTERNAL_AV;
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
-
- /* reset state of xceive tuner */
- dev->xc_fw_load_done = 0;
- break;
-
- case POLARIS_AVMODE_ANALOGT_TV:
-
- tmp |= PWR_DEMOD_EN;
- tmp |= (I2C_DEMOD_EN);
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(PWR_SLEEP_INTERVAL);
-
- if (!(tmp & PWR_TUNER_EN)) {
- tmp |= (PWR_TUNER_EN);
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(PWR_SLEEP_INTERVAL);
- }
-
- if (!(tmp & PWR_AV_EN)) {
- tmp |= PWR_AV_EN;
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(PWR_SLEEP_INTERVAL);
- }
- if (!(tmp & PWR_ISO_EN)) {
- tmp |= PWR_ISO_EN;
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(PWR_SLEEP_INTERVAL);
- }
-
- if (!(tmp & POLARIS_AVMODE_ANALOGT_TV)) {
- tmp |= POLARIS_AVMODE_ANALOGT_TV;
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(PWR_SLEEP_INTERVAL);
- }
-
- if (dev->board.tuner_type != TUNER_ABSENT) {
- /* Enable tuner */
- cx231xx_enable_i2c_port_3(dev, true);
-
- /* reset the Tuner */
- if (dev->board.tuner_gpio)
- cx231xx_gpio_set(dev, dev->board.tuner_gpio);
-
- if (dev->cx231xx_reset_analog_tuner)
- dev->cx231xx_reset_analog_tuner(dev);
- }
-
- break;
-
- case POLARIS_AVMODE_DIGITAL:
- if (!(tmp & PWR_TUNER_EN)) {
- tmp |= (PWR_TUNER_EN);
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(PWR_SLEEP_INTERVAL);
- }
- if (!(tmp & PWR_AV_EN)) {
- tmp |= PWR_AV_EN;
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(PWR_SLEEP_INTERVAL);
- }
- if (!(tmp & PWR_ISO_EN)) {
- tmp |= PWR_ISO_EN;
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(PWR_SLEEP_INTERVAL);
- }
-
- tmp &= (~PWR_AV_MODE);
- tmp |= POLARIS_AVMODE_DIGITAL | I2C_DEMOD_EN;
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(PWR_SLEEP_INTERVAL);
-
- if (!(tmp & PWR_DEMOD_EN)) {
- tmp |= PWR_DEMOD_EN;
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(PWR_SLEEP_INTERVAL);
- }
-
- if (dev->board.tuner_type != TUNER_ABSENT) {
- /*
- * Enable tuner
- * Hauppauge Exeter seems to need to do something different!
- */
- if (dev->model == CX231XX_BOARD_HAUPPAUGE_EXETER)
- cx231xx_enable_i2c_port_3(dev, false);
- else
- cx231xx_enable_i2c_port_3(dev, true);
-
- /* reset the Tuner */
- if (dev->board.tuner_gpio)
- cx231xx_gpio_set(dev, dev->board.tuner_gpio);
-
- if (dev->cx231xx_reset_analog_tuner)
- dev->cx231xx_reset_analog_tuner(dev);
- }
- break;
-
- default:
- break;
- }
-
- msleep(PWR_SLEEP_INTERVAL);
-
- /* For power saving, only enable Pwr_resetout_n
- when digital TV is selected. */
- if (mode == POLARIS_AVMODE_DIGITAL) {
- tmp |= PWR_RESETOUT_EN;
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(PWR_SLEEP_INTERVAL);
- }
-
- /* update power control for afe */
- status = cx231xx_afe_update_power_control(dev, mode);
-
- /* update power control for i2s_blk */
- status = cx231xx_i2s_blk_update_power_control(dev, mode);
-
- status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value,
- 4);
-
- return status;
-}
-
-int cx231xx_power_suspend(struct cx231xx *dev)
-{
- u8 value[4] = { 0, 0, 0, 0 };
- u32 tmp = 0;
- int status = 0;
-
- status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN,
- value, 4);
- if (status > 0)
- return status;
-
- tmp = *((u32 *) value);
- tmp &= (~PWR_MODE_MASK);
-
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, PWR_CTL_EN,
- value, 4);
-
- return status;
-}
-
-/******************************************************************************
- * S T R E A M C O N T R O L functions *
- ******************************************************************************/
-int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask)
-{
- u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
- u32 tmp = 0;
- int status = 0;
-
- cx231xx_info("cx231xx_start_stream():: ep_mask = %x\n", ep_mask);
- status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET,
- value, 4);
- if (status < 0)
- return status;
-
- tmp = *((u32 *) value);
- tmp |= ep_mask;
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
-
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, EP_MODE_SET,
- value, 4);
-
- return status;
-}
-
-int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask)
-{
- u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
- u32 tmp = 0;
- int status = 0;
-
- cx231xx_info("cx231xx_stop_stream():: ep_mask = %x\n", ep_mask);
- status =
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4);
- if (status < 0)
- return status;
-
- tmp = *((u32 *) value);
- tmp &= (~ep_mask);
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
-
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, EP_MODE_SET,
- value, 4);
-
- return status;
-}
-
-int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)
-{
- int status = 0;
- u32 value = 0;
- u8 val[4] = { 0, 0, 0, 0 };
-
- if (dev->udev->speed == USB_SPEED_HIGH) {
- switch (media_type) {
- case Audio:
- cx231xx_info("%s: Audio enter HANC\n", __func__);
- status =
- cx231xx_mode_register(dev, TS_MODE_REG, 0x9300);
- break;
-
- case Vbi:
- cx231xx_info("%s: set vanc registers\n", __func__);
- status = cx231xx_mode_register(dev, TS_MODE_REG, 0x300);
- break;
-
- case Sliced_cc:
- cx231xx_info("%s: set hanc registers\n", __func__);
- status =
- cx231xx_mode_register(dev, TS_MODE_REG, 0x1300);
- break;
-
- case Raw_Video:
- cx231xx_info("%s: set video registers\n", __func__);
- status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100);
- break;
-
- case TS1_serial_mode:
- cx231xx_info("%s: set ts1 registers", __func__);
-
- if (dev->board.has_417) {
- cx231xx_info(" MPEG\n");
- value &= 0xFFFFFFFC;
- value |= 0x3;
-
- status = cx231xx_mode_register(dev, TS_MODE_REG, value);
-
- val[0] = 0x04;
- val[1] = 0xA3;
- val[2] = 0x3B;
- val[3] = 0x00;
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- TS1_CFG_REG, val, 4);
-
- val[0] = 0x00;
- val[1] = 0x08;
- val[2] = 0x00;
- val[3] = 0x08;
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- TS1_LENGTH_REG, val, 4);
-
- } else {
- cx231xx_info(" BDA\n");
- status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101);
- status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x010);
- }
- break;
-
- case TS1_parallel_mode:
- cx231xx_info("%s: set ts1 parallel mode registers\n",
- __func__);
- status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100);
- status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400);
- break;
- }
- } else {
- status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101);
- }
-
- return status;
-}
-
-int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type)
-{
- int rc = -1;
- u32 ep_mask = -1;
- struct pcb_config *pcb_config;
-
- /* get EP for media type */
- pcb_config = (struct pcb_config *)&dev->current_pcb_config;
-
- if (pcb_config->config_num) {
- switch (media_type) {
- case Raw_Video:
- ep_mask = ENABLE_EP4; /* ep4 [00:1000] */
- break;
- case Audio:
- ep_mask = ENABLE_EP3; /* ep3 [00:0100] */
- break;
- case Vbi:
- ep_mask = ENABLE_EP5; /* ep5 [01:0000] */
- break;
- case Sliced_cc:
- ep_mask = ENABLE_EP6; /* ep6 [10:0000] */
- break;
- case TS1_serial_mode:
- case TS1_parallel_mode:
- ep_mask = ENABLE_EP1; /* ep1 [00:0001] */
- break;
- case TS2:
- ep_mask = ENABLE_EP2; /* ep2 [00:0010] */
- break;
- }
- }
-
- if (start) {
- rc = cx231xx_initialize_stream_xfer(dev, media_type);
-
- if (rc < 0)
- return rc;
-
- /* enable video capture */
- if (ep_mask > 0)
- rc = cx231xx_start_stream(dev, ep_mask);
- } else {
- /* disable video capture */
- if (ep_mask > 0)
- rc = cx231xx_stop_stream(dev, ep_mask);
- }
-
- if (dev->mode == CX231XX_ANALOG_MODE)
- ;/* do any in Analog mode */
- else
- ;/* do any in digital mode */
-
- return rc;
-}
-EXPORT_SYMBOL_GPL(cx231xx_capture_start);
-
-/*****************************************************************************
-* G P I O B I T control functions *
-******************************************************************************/
-int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val)
-{
- int status = 0;
-
- status = cx231xx_send_gpio_cmd(dev, gpio_bit, gpio_val, 4, 0, 0);
-
- return status;
-}
-
-int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val)
-{
- int status = 0;
-
- status = cx231xx_send_gpio_cmd(dev, gpio_bit, gpio_val, 4, 0, 1);
-
- return status;
-}
-
-/*
-* cx231xx_set_gpio_direction
-* Sets the direction of the GPIO pin to input or output
-*
-* Parameters :
-* pin_number : The GPIO Pin number to program the direction for
-* from 0 to 31
-* pin_value : The Direction of the GPIO Pin under reference.
-* 0 = Input direction
-* 1 = Output direction
-*/
-int cx231xx_set_gpio_direction(struct cx231xx *dev,
- int pin_number, int pin_value)
-{
- int status = 0;
- u32 value = 0;
-
- /* Check for valid pin_number - if 32 , bail out */
- if (pin_number >= 32)
- return -EINVAL;
-
- /* input */
- if (pin_value == 0)
- value = dev->gpio_dir & (~(1 << pin_number)); /* clear */
- else
- value = dev->gpio_dir | (1 << pin_number);
-
- status = cx231xx_set_gpio_bit(dev, value, (u8 *) &dev->gpio_val);
-
- /* cache the value for future */
- dev->gpio_dir = value;
-
- return status;
-}
-
-/*
-* cx231xx_set_gpio_value
-* Sets the value of the GPIO pin to Logic high or low. The Pin under
-* reference should ALREADY BE SET IN OUTPUT MODE !!!!!!!!!
-*
-* Parameters :
-* pin_number : The GPIO Pin number to program the direction for
-* pin_value : The value of the GPIO Pin under reference.
-* 0 = set it to 0
-* 1 = set it to 1
-*/
-int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value)
-{
- int status = 0;
- u32 value = 0;
-
- /* Check for valid pin_number - if 0xFF , bail out */
- if (pin_number >= 32)
- return -EINVAL;
-
- /* first do a sanity check - if the Pin is not output, make it output */
- if ((dev->gpio_dir & (1 << pin_number)) == 0x00) {
- /* It was in input mode */
- value = dev->gpio_dir | (1 << pin_number);
- dev->gpio_dir = value;
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
- (u8 *) &dev->gpio_val);
- value = 0;
- }
-
- if (pin_value == 0)
- value = dev->gpio_val & (~(1 << pin_number));
- else
- value = dev->gpio_val | (1 << pin_number);
-
- /* store the value */
- dev->gpio_val = value;
-
- /* toggle bit0 of GP_IO */
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
-
- return status;
-}
-
-/*****************************************************************************
-* G P I O I2C related functions *
-******************************************************************************/
-int cx231xx_gpio_i2c_start(struct cx231xx *dev)
-{
- int status = 0;
-
- /* set SCL to output 1 ; set SDA to output 1 */
- dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
- dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
- dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
- dev->gpio_val |= 1 << dev->board.tuner_sda_gpio;
-
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
- if (status < 0)
- return -EINVAL;
-
- /* set SCL to output 1; set SDA to output 0 */
- dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
- dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
-
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
- if (status < 0)
- return -EINVAL;
-
- /* set SCL to output 0; set SDA to output 0 */
- dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
- dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
-
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
- if (status < 0)
- return -EINVAL;
-
- return status;
-}
-
-int cx231xx_gpio_i2c_end(struct cx231xx *dev)
-{
- int status = 0;
-
- /* set SCL to output 0; set SDA to output 0 */
- dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
- dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
-
- dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
- dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
-
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
- if (status < 0)
- return -EINVAL;
-
- /* set SCL to output 1; set SDA to output 0 */
- dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
- dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
-
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
- if (status < 0)
- return -EINVAL;
-
- /* set SCL to input ,release SCL cable control
- set SDA to input ,release SDA cable control */
- dev->gpio_dir &= ~(1 << dev->board.tuner_scl_gpio);
- dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
-
- status =
- cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
- if (status < 0)
- return -EINVAL;
-
- return status;
-}
-
-int cx231xx_gpio_i2c_write_byte(struct cx231xx *dev, u8 data)
-{
- int status = 0;
- u8 i;
-
- /* set SCL to output ; set SDA to output */
- dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
- dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
-
- for (i = 0; i < 8; i++) {
- if (((data << i) & 0x80) == 0) {
- /* set SCL to output 0; set SDA to output 0 */
- dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
- dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
- (u8 *)&dev->gpio_val);
-
- /* set SCL to output 1; set SDA to output 0 */
- dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
- (u8 *)&dev->gpio_val);
-
- /* set SCL to output 0; set SDA to output 0 */
- dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
- (u8 *)&dev->gpio_val);
- } else {
- /* set SCL to output 0; set SDA to output 1 */
- dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
- dev->gpio_val |= 1 << dev->board.tuner_sda_gpio;
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
- (u8 *)&dev->gpio_val);
-
- /* set SCL to output 1; set SDA to output 1 */
- dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
- (u8 *)&dev->gpio_val);
-
- /* set SCL to output 0; set SDA to output 1 */
- dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
- (u8 *)&dev->gpio_val);
- }
- }
- return status;
-}
-
-int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 *buf)
-{
- u8 value = 0;
- int status = 0;
- u32 gpio_logic_value = 0;
- u8 i;
-
- /* read byte */
- for (i = 0; i < 8; i++) { /* send write I2c addr */
-
- /* set SCL to output 0; set SDA to input */
- dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
- (u8 *)&dev->gpio_val);
-
- /* set SCL to output 1; set SDA to input */
- dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
- (u8 *)&dev->gpio_val);
-
- /* get SDA data bit */
- gpio_logic_value = dev->gpio_val;
- status = cx231xx_get_gpio_bit(dev, dev->gpio_dir,
- (u8 *)&dev->gpio_val);
- if ((dev->gpio_val & (1 << dev->board.tuner_sda_gpio)) != 0)
- value |= (1 << (8 - i - 1));
-
- dev->gpio_val = gpio_logic_value;
- }
-
- /* set SCL to output 0,finish the read latest SCL signal.
- !!!set SDA to input, never to modify SDA direction at
- the same times */
- dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
-
- /* store the value */
- *buf = value & 0xff;
-
- return status;
-}
-
-int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev)
-{
- int status = 0;
- u32 gpio_logic_value = 0;
- int nCnt = 10;
- int nInit = nCnt;
-
- /* clock stretch; set SCL to input; set SDA to input;
- get SCL value till SCL = 1 */
- dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
- dev->gpio_dir &= ~(1 << dev->board.tuner_scl_gpio);
-
- gpio_logic_value = dev->gpio_val;
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
-
- do {
- msleep(2);
- status = cx231xx_get_gpio_bit(dev, dev->gpio_dir,
- (u8 *)&dev->gpio_val);
- nCnt--;
- } while (((dev->gpio_val &
- (1 << dev->board.tuner_scl_gpio)) == 0) &&
- (nCnt > 0));
-
- if (nCnt == 0)
- cx231xx_info("No ACK after %d msec -GPIO I2C failed!",
- nInit * 10);
-
- /*
- * readAck
- * through clock stretch, slave has given a SCL signal,
- * so the SDA data can be directly read.
- */
- status = cx231xx_get_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
-
- if ((dev->gpio_val & 1 << dev->board.tuner_sda_gpio) == 0) {
- dev->gpio_val = gpio_logic_value;
- dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
- status = 0;
- } else {
- dev->gpio_val = gpio_logic_value;
- dev->gpio_val |= (1 << dev->board.tuner_sda_gpio);
- }
-
- /* read SDA end, set the SCL to output 0, after this operation,
- SDA direction can be changed. */
- dev->gpio_val = gpio_logic_value;
- dev->gpio_dir |= (1 << dev->board.tuner_scl_gpio);
- dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
-
- return status;
-}
-
-int cx231xx_gpio_i2c_write_ack(struct cx231xx *dev)
-{
- int status = 0;
-
- /* set SDA to ouput */
- dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
-
- /* set SCL = 0 (output); set SDA = 0 (output) */
- dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
- dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
-
- /* set SCL = 1 (output); set SDA = 0 (output) */
- dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
-
- /* set SCL = 0 (output); set SDA = 0 (output) */
- dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
-
- /* set SDA to input,and then the slave will read data from SDA. */
- dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
-
- return status;
-}
-
-int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev)
-{
- int status = 0;
-
- /* set scl to output ; set sda to input */
- dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
- dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
-
- /* set scl to output 0; set sda to input */
- dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
-
- /* set scl to output 1; set sda to input */
- dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
- status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
-
- return status;
-}
-
-/*****************************************************************************
-* G P I O I2C related functions *
-******************************************************************************/
-/* cx231xx_gpio_i2c_read
- * Function to read data from gpio based I2C interface
- */
-int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len)
-{
- int status = 0;
- int i = 0;
-
- /* get the lock */
- mutex_lock(&dev->gpio_i2c_lock);
-
- /* start */
- status = cx231xx_gpio_i2c_start(dev);
-
- /* write dev_addr */
- status = cx231xx_gpio_i2c_write_byte(dev, (dev_addr << 1) + 1);
-
- /* readAck */
- status = cx231xx_gpio_i2c_read_ack(dev);
-
- /* read data */
- for (i = 0; i < len; i++) {
- /* read data */
- buf[i] = 0;
- status = cx231xx_gpio_i2c_read_byte(dev, &buf[i]);
-
- if ((i + 1) != len) {
- /* only do write ack if we more length */
- status = cx231xx_gpio_i2c_write_ack(dev);
- }
- }
-
- /* write NAK - inform reads are complete */
- status = cx231xx_gpio_i2c_write_nak(dev);
-
- /* write end */
- status = cx231xx_gpio_i2c_end(dev);
-
- /* release the lock */
- mutex_unlock(&dev->gpio_i2c_lock);
-
- return status;
-}
-
-/* cx231xx_gpio_i2c_write
- * Function to write data to gpio based I2C interface
- */
-int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len)
-{
- int i = 0;
-
- /* get the lock */
- mutex_lock(&dev->gpio_i2c_lock);
-
- /* start */
- cx231xx_gpio_i2c_start(dev);
-
- /* write dev_addr */
- cx231xx_gpio_i2c_write_byte(dev, dev_addr << 1);
-
- /* read Ack */
- cx231xx_gpio_i2c_read_ack(dev);
-
- for (i = 0; i < len; i++) {
- /* Write data */
- cx231xx_gpio_i2c_write_byte(dev, buf[i]);
-
- /* read Ack */
- cx231xx_gpio_i2c_read_ack(dev);
- }
-
- /* write End */
- cx231xx_gpio_i2c_end(dev);
-
- /* release the lock */
- mutex_unlock(&dev->gpio_i2c_lock);
-
- return 0;
-}
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
deleted file mode 100644
index b84ebc54d91..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ /dev/null
@@ -1,1370 +0,0 @@
-/*
- cx231xx-cards.c - driver for Conexant Cx23100/101/102
- USB video capture devices
-
- Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
- Based on em28xx driver
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/usb.h>
-#include <media/tuner.h>
-#include <media/tveeprom.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-
-#include <media/cx25840.h>
-#include "dvb-usb-ids.h"
-#include "xc5000.h"
-#include "tda18271.h"
-
-#include "cx231xx.h"
-
-static int tuner = -1;
-module_param(tuner, int, 0444);
-MODULE_PARM_DESC(tuner, "tuner type");
-
-static int transfer_mode = 1;
-module_param(transfer_mode, int, 0444);
-MODULE_PARM_DESC(transfer_mode, "transfer mode (1-ISO or 0-BULK)");
-
-static unsigned int disable_ir;
-module_param(disable_ir, int, 0444);
-MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
-
-/* Bitmask marking allocated devices from 0 to CX231XX_MAXBOARDS */
-static unsigned long cx231xx_devused;
-
-/*
- * Reset sequences for analog/digital modes
- */
-
-static struct cx231xx_reg_seq RDE250_XCV_TUNER[] = {
- {0x03, 0x01, 10},
- {0x03, 0x00, 30},
- {0x03, 0x01, 10},
- {-1, -1, -1},
-};
-
-/*
- * Board definitions
- */
-struct cx231xx_board cx231xx_boards[] = {
- [CX231XX_BOARD_UNKNOWN] = {
- .name = "Unknown CX231xx video grabber",
- .tuner_type = TUNER_ABSENT,
- .input = {{
- .type = CX231XX_VMUX_TELEVISION,
- .vmux = CX231XX_VIN_3_1,
- .amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_COMPOSITE1,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_SVIDEO,
- .vmux = CX231XX_VIN_1_1 |
- (CX231XX_VIN_1_2 << 8) |
- CX25840_SVIDEO_ON,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }
- },
- },
- [CX231XX_BOARD_CNXT_CARRAERA] = {
- .name = "Conexant Hybrid TV - CARRAERA",
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0x61,
- .tuner_gpio = RDE250_XCV_TUNER,
- .tuner_sif_gpio = 0x05,
- .tuner_scl_gpio = 0x1a,
- .tuner_sda_gpio = 0x1b,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .demod_xfer_mode = 0,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x0c,
- .gpio_pin_status_mask = 0x4001000,
- .tuner_i2c_master = 1,
- .demod_i2c_master = 2,
- .has_dvb = 1,
- .demod_addr = 0x02,
- .norm = V4L2_STD_PAL,
-
- .input = {{
- .type = CX231XX_VMUX_TELEVISION,
- .vmux = CX231XX_VIN_3_1,
- .amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_COMPOSITE1,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_SVIDEO,
- .vmux = CX231XX_VIN_1_1 |
- (CX231XX_VIN_1_2 << 8) |
- CX25840_SVIDEO_ON,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }
- },
- },
- [CX231XX_BOARD_CNXT_SHELBY] = {
- .name = "Conexant Hybrid TV - SHELBY",
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0x61,
- .tuner_gpio = RDE250_XCV_TUNER,
- .tuner_sif_gpio = 0x05,
- .tuner_scl_gpio = 0x1a,
- .tuner_sda_gpio = 0x1b,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .demod_xfer_mode = 0,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x0c,
- .gpio_pin_status_mask = 0x4001000,
- .tuner_i2c_master = 1,
- .demod_i2c_master = 2,
- .has_dvb = 1,
- .demod_addr = 0x32,
- .norm = V4L2_STD_NTSC,
-
- .input = {{
- .type = CX231XX_VMUX_TELEVISION,
- .vmux = CX231XX_VIN_3_1,
- .amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_COMPOSITE1,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_SVIDEO,
- .vmux = CX231XX_VIN_1_1 |
- (CX231XX_VIN_1_2 << 8) |
- CX25840_SVIDEO_ON,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }
- },
- },
- [CX231XX_BOARD_CNXT_RDE_253S] = {
- .name = "Conexant Hybrid TV - RDE253S",
- .tuner_type = TUNER_NXP_TDA18271,
- .tuner_addr = 0x60,
- .tuner_gpio = RDE250_XCV_TUNER,
- .tuner_sif_gpio = 0x05,
- .tuner_scl_gpio = 0x1a,
- .tuner_sda_gpio = 0x1b,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .demod_xfer_mode = 0,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x1c,
- .gpio_pin_status_mask = 0x4001000,
- .tuner_i2c_master = 1,
- .demod_i2c_master = 2,
- .has_dvb = 1,
- .demod_addr = 0x02,
- .norm = V4L2_STD_PAL,
-
- .input = {{
- .type = CX231XX_VMUX_TELEVISION,
- .vmux = CX231XX_VIN_3_1,
- .amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_COMPOSITE1,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_SVIDEO,
- .vmux = CX231XX_VIN_1_1 |
- (CX231XX_VIN_1_2 << 8) |
- CX25840_SVIDEO_ON,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }
- },
- },
-
- [CX231XX_BOARD_CNXT_RDU_253S] = {
- .name = "Conexant Hybrid TV - RDU253S",
- .tuner_type = TUNER_NXP_TDA18271,
- .tuner_addr = 0x60,
- .tuner_gpio = RDE250_XCV_TUNER,
- .tuner_sif_gpio = 0x05,
- .tuner_scl_gpio = 0x1a,
- .tuner_sda_gpio = 0x1b,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .demod_xfer_mode = 0,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x1c,
- .gpio_pin_status_mask = 0x4001000,
- .tuner_i2c_master = 1,
- .demod_i2c_master = 2,
- .has_dvb = 1,
- .demod_addr = 0x02,
- .norm = V4L2_STD_PAL,
-
- .input = {{
- .type = CX231XX_VMUX_TELEVISION,
- .vmux = CX231XX_VIN_3_1,
- .amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_COMPOSITE1,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_SVIDEO,
- .vmux = CX231XX_VIN_1_1 |
- (CX231XX_VIN_1_2 << 8) |
- CX25840_SVIDEO_ON,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }
- },
- },
- [CX231XX_BOARD_CNXT_VIDEO_GRABBER] = {
- .name = "Conexant VIDEO GRABBER",
- .tuner_type = TUNER_ABSENT,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x1c,
- .gpio_pin_status_mask = 0x4001000,
- .norm = V4L2_STD_PAL,
- .no_alt_vanc = 1,
- .external_av = 1,
- .has_417 = 1,
-
- .input = {{
- .type = CX231XX_VMUX_COMPOSITE1,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_SVIDEO,
- .vmux = CX231XX_VIN_1_1 |
- (CX231XX_VIN_1_2 << 8) |
- CX25840_SVIDEO_ON,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }
- },
- },
- [CX231XX_BOARD_CNXT_RDE_250] = {
- .name = "Conexant Hybrid TV - rde 250",
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0x61,
- .tuner_gpio = RDE250_XCV_TUNER,
- .tuner_sif_gpio = 0x05,
- .tuner_scl_gpio = 0x1a,
- .tuner_sda_gpio = 0x1b,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .demod_xfer_mode = 0,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x0c,
- .gpio_pin_status_mask = 0x4001000,
- .tuner_i2c_master = 1,
- .demod_i2c_master = 2,
- .has_dvb = 1,
- .demod_addr = 0x02,
- .norm = V4L2_STD_PAL,
-
- .input = {{
- .type = CX231XX_VMUX_TELEVISION,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
- }
- },
- },
- [CX231XX_BOARD_CNXT_RDU_250] = {
- .name = "Conexant Hybrid TV - RDU 250",
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0x61,
- .tuner_gpio = RDE250_XCV_TUNER,
- .tuner_sif_gpio = 0x05,
- .tuner_scl_gpio = 0x1a,
- .tuner_sda_gpio = 0x1b,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .demod_xfer_mode = 0,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x0c,
- .gpio_pin_status_mask = 0x4001000,
- .tuner_i2c_master = 1,
- .demod_i2c_master = 2,
- .has_dvb = 1,
- .demod_addr = 0x32,
- .norm = V4L2_STD_NTSC,
-
- .input = {{
- .type = CX231XX_VMUX_TELEVISION,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
- }
- },
- },
- [CX231XX_BOARD_HAUPPAUGE_EXETER] = {
- .name = "Hauppauge EXETER",
- .tuner_type = TUNER_NXP_TDA18271,
- .tuner_addr = 0x60,
- .tuner_gpio = RDE250_XCV_TUNER,
- .tuner_sif_gpio = 0x05,
- .tuner_scl_gpio = 0x1a,
- .tuner_sda_gpio = 0x1b,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .demod_xfer_mode = 0,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x0c,
- .gpio_pin_status_mask = 0x4001000,
- .tuner_i2c_master = 1,
- .demod_i2c_master = 2,
- .has_dvb = 1,
- .demod_addr = 0x0e,
- .norm = V4L2_STD_NTSC,
-
- .input = {{
- .type = CX231XX_VMUX_TELEVISION,
- .vmux = CX231XX_VIN_3_1,
- .amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_COMPOSITE1,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_SVIDEO,
- .vmux = CX231XX_VIN_1_1 |
- (CX231XX_VIN_1_2 << 8) |
- CX25840_SVIDEO_ON,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- } },
- },
- [CX231XX_BOARD_HAUPPAUGE_USBLIVE2] = {
- .name = "Hauppauge USB Live 2",
- .tuner_type = TUNER_ABSENT,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .demod_xfer_mode = 0,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x0c,
- .gpio_pin_status_mask = 0x4001000,
- .norm = V4L2_STD_NTSC,
- .no_alt_vanc = 1,
- .external_av = 1,
- .dont_use_port_3 = 1,
- .input = {{
- .type = CX231XX_VMUX_COMPOSITE1,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_SVIDEO,
- .vmux = CX231XX_VIN_1_1 |
- (CX231XX_VIN_1_2 << 8) |
- CX25840_SVIDEO_ON,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- } },
- },
- [CX231XX_BOARD_KWORLD_UB430_USB_HYBRID] = {
- .name = "Kworld UB430 USB Hybrid",
- .tuner_type = TUNER_NXP_TDA18271,
- .tuner_addr = 0x60,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .demod_xfer_mode = 0,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x11, /* According with PV cxPolaris.inf file */
- .tuner_sif_gpio = -1,
- .tuner_scl_gpio = -1,
- .tuner_sda_gpio = -1,
- .gpio_pin_status_mask = 0x4001000,
- .tuner_i2c_master = 2,
- .demod_i2c_master = 1,
- .ir_i2c_master = 2,
- .has_dvb = 1,
- .demod_addr = 0x10,
- .norm = V4L2_STD_PAL_M,
- .input = {{
- .type = CX231XX_VMUX_TELEVISION,
- .vmux = CX231XX_VIN_3_1,
- .amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_COMPOSITE1,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_SVIDEO,
- .vmux = CX231XX_VIN_1_1 |
- (CX231XX_VIN_1_2 << 8) |
- CX25840_SVIDEO_ON,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- } },
- },
- [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = {
- .name = "Pixelview PlayTV USB Hybrid",
- .tuner_type = TUNER_NXP_TDA18271,
- .tuner_addr = 0x60,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .demod_xfer_mode = 0,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x00, /* According with PV cxPolaris.inf file */
- .tuner_sif_gpio = -1,
- .tuner_scl_gpio = -1,
- .tuner_sda_gpio = -1,
- .gpio_pin_status_mask = 0x4001000,
- .tuner_i2c_master = 2,
- .demod_i2c_master = 1,
- .ir_i2c_master = 2,
- .rc_map_name = RC_MAP_PIXELVIEW_002T,
- .has_dvb = 1,
- .demod_addr = 0x10,
- .norm = V4L2_STD_PAL_M,
- .input = {{
- .type = CX231XX_VMUX_TELEVISION,
- .vmux = CX231XX_VIN_3_1,
- .amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_COMPOSITE1,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_SVIDEO,
- .vmux = CX231XX_VIN_1_1 |
- (CX231XX_VIN_1_2 << 8) |
- CX25840_SVIDEO_ON,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- } },
- },
- [CX231XX_BOARD_PV_XCAPTURE_USB] = {
- .name = "Pixelview Xcapture USB",
- .tuner_type = TUNER_ABSENT,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .demod_xfer_mode = 0,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x0c,
- .gpio_pin_status_mask = 0x4001000,
- .norm = V4L2_STD_NTSC,
- .no_alt_vanc = 1,
- .external_av = 1,
- .dont_use_port_3 = 1,
-
- .input = {{
- .type = CX231XX_VMUX_COMPOSITE1,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_SVIDEO,
- .vmux = CX231XX_VIN_1_1 |
- (CX231XX_VIN_1_2 << 8) |
- CX25840_SVIDEO_ON,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }
- },
- },
-
- [CX231XX_BOARD_ICONBIT_U100] = {
- .name = "Iconbit Analog Stick U100 FM",
- .tuner_type = TUNER_ABSENT,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .demod_xfer_mode = 0,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x1C,
- .gpio_pin_status_mask = 0x4001000,
-
- .input = {{
- .type = CX231XX_VMUX_COMPOSITE1,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_SVIDEO,
- .vmux = CX231XX_VIN_1_1 |
- (CX231XX_VIN_1_2 << 8) |
- CX25840_SVIDEO_ON,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- } },
- },
- [CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL] = {
- .name = "Hauppauge WinTV USB2 FM (PAL)",
- .tuner_type = TUNER_NXP_TDA18271,
- .tuner_addr = 0x60,
- .tuner_gpio = RDE250_XCV_TUNER,
- .tuner_sif_gpio = 0x05,
- .tuner_scl_gpio = 0x1a,
- .tuner_sda_gpio = 0x1b,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x0c,
- .gpio_pin_status_mask = 0x4001000,
- .tuner_i2c_master = 1,
- .norm = V4L2_STD_PAL,
-
- .input = {{
- .type = CX231XX_VMUX_TELEVISION,
- .vmux = CX231XX_VIN_3_1,
- .amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_COMPOSITE1,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_SVIDEO,
- .vmux = CX231XX_VIN_1_1 |
- (CX231XX_VIN_1_2 << 8) |
- CX25840_SVIDEO_ON,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- } },
- },
- [CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC] = {
- .name = "Hauppauge WinTV USB2 FM (NTSC)",
- .tuner_type = TUNER_NXP_TDA18271,
- .tuner_addr = 0x60,
- .tuner_gpio = RDE250_XCV_TUNER,
- .tuner_sif_gpio = 0x05,
- .tuner_scl_gpio = 0x1a,
- .tuner_sda_gpio = 0x1b,
- .decoder = CX231XX_AVDECODER,
- .output_mode = OUT_MODE_VIP11,
- .ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x0c,
- .gpio_pin_status_mask = 0x4001000,
- .tuner_i2c_master = 1,
- .norm = V4L2_STD_NTSC,
-
- .input = {{
- .type = CX231XX_VMUX_TELEVISION,
- .vmux = CX231XX_VIN_3_1,
- .amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_COMPOSITE1,
- .vmux = CX231XX_VIN_2_1,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- }, {
- .type = CX231XX_VMUX_SVIDEO,
- .vmux = CX231XX_VIN_1_1 |
- (CX231XX_VIN_1_2 << 8) |
- CX25840_SVIDEO_ON,
- .amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
- } },
- },
-};
-const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
-
-/* table of devices that work with this driver */
-struct usb_device_id cx231xx_id_table[] = {
- {USB_DEVICE(0x0572, 0x5A3C),
- .driver_info = CX231XX_BOARD_UNKNOWN},
- {USB_DEVICE(0x0572, 0x58A2),
- .driver_info = CX231XX_BOARD_CNXT_CARRAERA},
- {USB_DEVICE(0x0572, 0x58A1),
- .driver_info = CX231XX_BOARD_CNXT_SHELBY},
- {USB_DEVICE(0x0572, 0x58A4),
- .driver_info = CX231XX_BOARD_CNXT_RDE_253S},
- {USB_DEVICE(0x0572, 0x58A5),
- .driver_info = CX231XX_BOARD_CNXT_RDU_253S},
- {USB_DEVICE(0x0572, 0x58A6),
- .driver_info = CX231XX_BOARD_CNXT_VIDEO_GRABBER},
- {USB_DEVICE(0x0572, 0x589E),
- .driver_info = CX231XX_BOARD_CNXT_RDE_250},
- {USB_DEVICE(0x0572, 0x58A0),
- .driver_info = CX231XX_BOARD_CNXT_RDU_250},
- {USB_DEVICE(0x2040, 0xb110),
- .driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL},
- {USB_DEVICE(0x2040, 0xb111),
- .driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC},
- {USB_DEVICE(0x2040, 0xb120),
- .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER},
- {USB_DEVICE(0x2040, 0xb140),
- .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER},
- {USB_DEVICE(0x2040, 0xc200),
- .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2},
- {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001),
- .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID},
- {USB_DEVICE(USB_VID_PIXELVIEW, 0x5014),
- .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB},
- {USB_DEVICE(0x1b80, 0xe424),
- .driver_info = CX231XX_BOARD_KWORLD_UB430_USB_HYBRID},
- {USB_DEVICE(0x1f4d, 0x0237),
- .driver_info = CX231XX_BOARD_ICONBIT_U100},
- {},
-};
-
-MODULE_DEVICE_TABLE(usb, cx231xx_id_table);
-
-/* cx231xx_tuner_callback
- * will be used to reset XC5000 tuner using GPIO pin
- */
-
-int cx231xx_tuner_callback(void *ptr, int component, int command, int arg)
-{
- int rc = 0;
- struct cx231xx *dev = ptr;
-
- if (dev->tuner_type == TUNER_XC5000) {
- if (command == XC5000_TUNER_RESET) {
- cx231xx_info
- ("Tuner CB: RESET: cmd %d : tuner type %d \n",
- command, dev->tuner_type);
- cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
- 1);
- msleep(10);
- cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
- 0);
- msleep(330);
- cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
- 1);
- msleep(10);
- }
- } else if (dev->tuner_type == TUNER_NXP_TDA18271) {
- switch (command) {
- case TDA18271_CALLBACK_CMD_AGC_ENABLE:
- if (dev->model == CX231XX_BOARD_PV_PLAYTV_USB_HYBRID)
- rc = cx231xx_set_agc_analog_digital_mux_select(dev, arg);
- break;
- default:
- rc = -EINVAL;
- break;
- }
- }
- return rc;
-}
-EXPORT_SYMBOL_GPL(cx231xx_tuner_callback);
-
-void cx231xx_reset_out(struct cx231xx *dev)
-{
- cx231xx_set_gpio_value(dev, CX23417_RESET, 1);
- msleep(200);
- cx231xx_set_gpio_value(dev, CX23417_RESET, 0);
- msleep(200);
- cx231xx_set_gpio_value(dev, CX23417_RESET, 1);
-}
-void cx231xx_enable_OSC(struct cx231xx *dev)
-{
- cx231xx_set_gpio_value(dev, CX23417_OSC_EN, 1);
-}
-void cx231xx_sleep_s5h1432(struct cx231xx *dev)
-{
- cx231xx_set_gpio_value(dev, SLEEP_S5H1432, 0);
-}
-
-static inline void cx231xx_set_model(struct cx231xx *dev)
-{
- memcpy(&dev->board, &cx231xx_boards[dev->model], sizeof(dev->board));
-}
-
-/* Since cx231xx_pre_card_setup() requires a proper dev->model,
- * this won't work for boards with generic PCI IDs
- */
-void cx231xx_pre_card_setup(struct cx231xx *dev)
-{
-
- cx231xx_set_model(dev);
-
- cx231xx_info("Identified as %s (card=%d)\n",
- dev->board.name, dev->model);
-
- /* set the direction for GPIO pins */
- if (dev->board.tuner_gpio) {
- cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1);
- cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1);
- }
- if (dev->board.tuner_sif_gpio >= 0)
- cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1);
-
- /* request some modules if any required */
-
- /* set the mode to Analog mode initially */
- cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
-
- /* Unlock device */
- /* cx231xx_set_mode(dev, CX231XX_SUSPEND); */
-
-}
-
-static void cx231xx_config_tuner(struct cx231xx *dev)
-{
- struct tuner_setup tun_setup;
- struct v4l2_frequency f;
-
- if (dev->tuner_type == TUNER_ABSENT)
- return;
-
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.type = dev->tuner_type;
- tun_setup.addr = dev->tuner_addr;
- tun_setup.tuner_callback = cx231xx_tuner_callback;
-
- tuner_call(dev, tuner, s_type_addr, &tun_setup);
-
-#if 0
- if (tun_setup.type == TUNER_XC5000) {
- static struct xc2028_ctrl ctrl = {
- .fname = XC5000_DEFAULT_FIRMWARE,
- .max_len = 64,
- .demod = 0;
- };
- struct v4l2_priv_tun_config cfg = {
- .tuner = dev->tuner_type,
- .priv = &ctrl,
- };
- tuner_call(dev, tuner, s_config, &cfg);
- }
-#endif
- /* configure tuner */
- f.tuner = 0;
- f.type = V4L2_TUNER_ANALOG_TV;
- f.frequency = 9076; /* just a magic number */
- dev->ctl_freq = f.frequency;
- call_all(dev, tuner, s_frequency, &f);
-
-}
-
-void cx231xx_card_setup(struct cx231xx *dev)
-{
-
- cx231xx_set_model(dev);
-
- dev->tuner_type = cx231xx_boards[dev->model].tuner_type;
- if (cx231xx_boards[dev->model].tuner_addr)
- dev->tuner_addr = cx231xx_boards[dev->model].tuner_addr;
-
- /* request some modules */
- if (dev->board.decoder == CX231XX_AVDECODER) {
- dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_bus[0].i2c_adap,
- "cx25840", 0x88 >> 1, NULL);
- if (dev->sd_cx25840 == NULL)
- cx231xx_info("cx25840 subdev registration failure\n");
- cx25840_call(dev, core, load_fw);
-
- }
-
- /* Initialize the tuner */
- if (dev->board.tuner_type != TUNER_ABSENT) {
- dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
- "tuner",
- dev->tuner_addr, NULL);
- if (dev->sd_tuner == NULL)
- cx231xx_info("tuner subdev registration failure\n");
- else
- cx231xx_config_tuner(dev);
- }
-}
-
-/*
- * cx231xx_config()
- * inits registers with sane defaults
- */
-int cx231xx_config(struct cx231xx *dev)
-{
- /* TBD need to add cx231xx specific code */
- dev->mute = 1; /* maybe not the right place... */
- dev->volume = 0x1f;
-
- return 0;
-}
-
-/*
- * cx231xx_config_i2c()
- * configure i2c attached devices
- */
-void cx231xx_config_i2c(struct cx231xx *dev)
-{
- /* u32 input = INPUT(dev->video_input)->vmux; */
-
- call_all(dev, video, s_stream, 1);
-}
-
-/*
- * cx231xx_realease_resources()
- * unregisters the v4l2,i2c and usb devices
- * called when the device gets disconected or at module unload
-*/
-void cx231xx_release_resources(struct cx231xx *dev)
-{
- cx231xx_release_analog_resources(dev);
-
- cx231xx_remove_from_devlist(dev);
-
- cx231xx_ir_exit(dev);
-
- /* Release I2C buses */
- cx231xx_dev_uninit(dev);
-
- /* delete v4l2 device */
- v4l2_device_unregister(&dev->v4l2_dev);
-
- usb_put_dev(dev->udev);
-
- /* Mark device as unused */
- clear_bit(dev->devno, &cx231xx_devused);
-
- kfree(dev->video_mode.alt_max_pkt_size);
- kfree(dev->vbi_mode.alt_max_pkt_size);
- kfree(dev->sliced_cc_mode.alt_max_pkt_size);
- kfree(dev->ts1_mode.alt_max_pkt_size);
- kfree(dev);
-}
-
-/*
- * cx231xx_init_dev()
- * allocates and inits the device structs, registers i2c bus and v4l device
- */
-static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev,
- int minor)
-{
- int retval = -ENOMEM;
- int errCode;
- unsigned int maxh, maxw;
-
- dev->udev = udev;
- mutex_init(&dev->lock);
- mutex_init(&dev->ctrl_urb_lock);
- mutex_init(&dev->gpio_i2c_lock);
- mutex_init(&dev->i2c_lock);
-
- spin_lock_init(&dev->video_mode.slock);
- spin_lock_init(&dev->vbi_mode.slock);
- spin_lock_init(&dev->sliced_cc_mode.slock);
-
- init_waitqueue_head(&dev->open);
- init_waitqueue_head(&dev->wait_frame);
- init_waitqueue_head(&dev->wait_stream);
-
- dev->cx231xx_read_ctrl_reg = cx231xx_read_ctrl_reg;
- dev->cx231xx_write_ctrl_reg = cx231xx_write_ctrl_reg;
- dev->cx231xx_send_usb_command = cx231xx_send_usb_command;
- dev->cx231xx_gpio_i2c_read = cx231xx_gpio_i2c_read;
- dev->cx231xx_gpio_i2c_write = cx231xx_gpio_i2c_write;
-
- /* Query cx231xx to find what pcb config it is related to */
- initialize_cx231xx(dev);
-
- /*To workaround error number=-71 on EP0 for VideoGrabber,
- need set alt here.*/
- if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER ||
- dev->model == CX231XX_BOARD_HAUPPAUGE_USBLIVE2) {
- cx231xx_set_alt_setting(dev, INDEX_VIDEO, 3);
- cx231xx_set_alt_setting(dev, INDEX_VANC, 1);
- }
- /* Cx231xx pre card setup */
- cx231xx_pre_card_setup(dev);
-
- errCode = cx231xx_config(dev);
- if (errCode) {
- cx231xx_errdev("error configuring device\n");
- return -ENOMEM;
- }
-
- /* set default norm */
- dev->norm = dev->board.norm;
-
- /* register i2c bus */
- errCode = cx231xx_dev_init(dev);
- if (errCode < 0) {
- cx231xx_dev_uninit(dev);
- cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n",
- __func__, errCode);
- return errCode;
- }
-
- /* Do board specific init */
- cx231xx_card_setup(dev);
-
- /* configure the device */
- cx231xx_config_i2c(dev);
-
- maxw = norm_maxw(dev);
- maxh = norm_maxh(dev);
-
- /* set default image size */
- dev->width = maxw;
- dev->height = maxh;
- dev->interlaced = 0;
- dev->video_input = 0;
-
- errCode = cx231xx_config(dev);
- if (errCode < 0) {
- cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n",
- __func__, errCode);
- return errCode;
- }
-
- /* init video dma queues */
- INIT_LIST_HEAD(&dev->video_mode.vidq.active);
- INIT_LIST_HEAD(&dev->video_mode.vidq.queued);
-
- /* init vbi dma queues */
- INIT_LIST_HEAD(&dev->vbi_mode.vidq.active);
- INIT_LIST_HEAD(&dev->vbi_mode.vidq.queued);
-
- /* Reset other chips required if they are tied up with GPIO pins */
- cx231xx_add_into_devlist(dev);
-
- if (dev->board.has_417) {
- printk(KERN_INFO "attach 417 %d\n", dev->model);
- if (cx231xx_417_register(dev) < 0) {
- printk(KERN_ERR
- "%s() Failed to register 417 on VID_B\n",
- __func__);
- }
- }
-
- retval = cx231xx_register_analog_devices(dev);
- if (retval < 0) {
- cx231xx_release_resources(dev);
- return retval;
- }
-
- cx231xx_ir_init(dev);
-
- cx231xx_init_extension(dev);
-
- return 0;
-}
-
-#if defined(CONFIG_MODULES) && defined(MODULE)
-static void request_module_async(struct work_struct *work)
-{
- struct cx231xx *dev = container_of(work,
- struct cx231xx, request_module_wk);
-
- if (dev->has_alsa_audio)
- request_module("cx231xx-alsa");
-
- if (dev->board.has_dvb)
- request_module("cx231xx-dvb");
-
-}
-
-static void request_modules(struct cx231xx *dev)
-{
- INIT_WORK(&dev->request_module_wk, request_module_async);
- schedule_work(&dev->request_module_wk);
-}
-
-static void flush_request_modules(struct cx231xx *dev)
-{
- flush_work(&dev->request_module_wk);
-}
-#else
-#define request_modules(dev)
-#define flush_request_modules(dev)
-#endif /* CONFIG_MODULES */
-
-/*
- * cx231xx_usb_probe()
- * checks for supported devices
- */
-static int cx231xx_usb_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- struct usb_device *udev;
- struct usb_interface *uif;
- struct cx231xx *dev = NULL;
- int retval = -ENODEV;
- int nr = 0, ifnum;
- int i, isoc_pipe = 0;
- char *speed;
- struct usb_interface_assoc_descriptor *assoc_desc;
-
- udev = usb_get_dev(interface_to_usbdev(interface));
- ifnum = interface->altsetting[0].desc.bInterfaceNumber;
-
- /*
- * Interface number 0 - IR interface (handled by mceusb driver)
- * Interface number 1 - AV interface (handled by this driver)
- */
- if (ifnum != 1)
- return -ENODEV;
-
- /* Check to see next free device and mark as used */
- do {
- nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS);
- if (nr >= CX231XX_MAXBOARDS) {
- /* No free device slots */
- cx231xx_err(DRIVER_NAME ": Supports only %i devices.\n",
- CX231XX_MAXBOARDS);
- return -ENOMEM;
- }
- } while (test_and_set_bit(nr, &cx231xx_devused));
-
- /* allocate memory for our device state and initialize it */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL) {
- cx231xx_err(DRIVER_NAME ": out of memory!\n");
- clear_bit(nr, &cx231xx_devused);
- return -ENOMEM;
- }
-
- snprintf(dev->name, 29, "cx231xx #%d", nr);
- dev->devno = nr;
- dev->model = id->driver_info;
- dev->video_mode.alt = -1;
-
- dev->interface_count++;
- /* reset gpio dir and value */
- dev->gpio_dir = 0;
- dev->gpio_val = 0;
- dev->xc_fw_load_done = 0;
- dev->has_alsa_audio = 1;
- dev->power_mode = -1;
- atomic_set(&dev->devlist_count, 0);
-
- /* 0 - vbi ; 1 -sliced cc mode */
- dev->vbi_or_sliced_cc_mode = 0;
-
- /* get maximum no.of IAD interfaces */
- assoc_desc = udev->actconfig->intf_assoc[0];
- dev->max_iad_interface_count = assoc_desc->bInterfaceCount;
-
- /* init CIR module TBD */
-
- /*mode_tv: digital=1 or analog=0*/
- dev->mode_tv = 0;
-
- dev->USE_ISO = transfer_mode;
-
- switch (udev->speed) {
- case USB_SPEED_LOW:
- speed = "1.5";
- break;
- case USB_SPEED_UNKNOWN:
- case USB_SPEED_FULL:
- speed = "12";
- break;
- case USB_SPEED_HIGH:
- speed = "480";
- break;
- default:
- speed = "unknown";
- }
-
- cx231xx_info("New device %s %s @ %s Mbps "
- "(%04x:%04x) with %d interfaces\n",
- udev->manufacturer ? udev->manufacturer : "",
- udev->product ? udev->product : "",
- speed,
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct),
- dev->max_iad_interface_count);
-
- /* increment interface count */
- dev->interface_count++;
-
- /* get device number */
- nr = dev->devno;
-
- assoc_desc = udev->actconfig->intf_assoc[0];
- if (assoc_desc->bFirstInterface != ifnum) {
- cx231xx_err(DRIVER_NAME ": Not found "
- "matching IAD interface\n");
- clear_bit(dev->devno, &cx231xx_devused);
- kfree(dev);
- dev = NULL;
- return -ENODEV;
- }
-
- cx231xx_info("registering interface %d\n", ifnum);
-
- /* save our data pointer in this interface device */
- usb_set_intfdata(interface, dev);
-
- /*
- * AV device initialization - only done at the last interface
- */
-
- /* Create v4l2 device */
- retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
- if (retval) {
- cx231xx_errdev("v4l2_device_register failed\n");
- clear_bit(dev->devno, &cx231xx_devused);
- kfree(dev);
- dev = NULL;
- return -EIO;
- }
- /* allocate device struct */
- retval = cx231xx_init_dev(dev, udev, nr);
- if (retval) {
- clear_bit(dev->devno, &cx231xx_devused);
- v4l2_device_unregister(&dev->v4l2_dev);
- kfree(dev);
- dev = NULL;
- usb_set_intfdata(interface, NULL);
-
- return retval;
- }
-
- /* compute alternate max packet sizes for video */
- uif = udev->actconfig->interface[dev->current_pcb_config.
- hs_config_info[0].interface_info.video_index + 1];
-
- dev->video_mode.end_point_addr = le16_to_cpu(uif->altsetting[0].
- endpoint[isoc_pipe].desc.bEndpointAddress);
-
- dev->video_mode.num_alt = uif->num_altsetting;
- cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
- dev->video_mode.end_point_addr,
- dev->video_mode.num_alt);
- dev->video_mode.alt_max_pkt_size =
- kmalloc(32 * dev->video_mode.num_alt, GFP_KERNEL);
-
- if (dev->video_mode.alt_max_pkt_size == NULL) {
- cx231xx_errdev("out of memory!\n");
- clear_bit(dev->devno, &cx231xx_devused);
- v4l2_device_unregister(&dev->v4l2_dev);
- kfree(dev);
- dev = NULL;
- return -ENOMEM;
- }
-
- for (i = 0; i < dev->video_mode.num_alt; i++) {
- u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
- desc.wMaxPacketSize);
- dev->video_mode.alt_max_pkt_size[i] =
- (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
- cx231xx_info("Alternate setting %i, max size= %i\n", i,
- dev->video_mode.alt_max_pkt_size[i]);
- }
-
- /* compute alternate max packet sizes for vbi */
- uif = udev->actconfig->interface[dev->current_pcb_config.
- hs_config_info[0].interface_info.
- vanc_index + 1];
-
- dev->vbi_mode.end_point_addr =
- le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
- bEndpointAddress);
-
- dev->vbi_mode.num_alt = uif->num_altsetting;
- cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
- dev->vbi_mode.end_point_addr,
- dev->vbi_mode.num_alt);
- dev->vbi_mode.alt_max_pkt_size =
- kmalloc(32 * dev->vbi_mode.num_alt, GFP_KERNEL);
-
- if (dev->vbi_mode.alt_max_pkt_size == NULL) {
- cx231xx_errdev("out of memory!\n");
- clear_bit(dev->devno, &cx231xx_devused);
- v4l2_device_unregister(&dev->v4l2_dev);
- kfree(dev);
- dev = NULL;
- return -ENOMEM;
- }
-
- for (i = 0; i < dev->vbi_mode.num_alt; i++) {
- u16 tmp =
- le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
- desc.wMaxPacketSize);
- dev->vbi_mode.alt_max_pkt_size[i] =
- (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
- cx231xx_info("Alternate setting %i, max size= %i\n", i,
- dev->vbi_mode.alt_max_pkt_size[i]);
- }
-
- /* compute alternate max packet sizes for sliced CC */
- uif = udev->actconfig->interface[dev->current_pcb_config.
- hs_config_info[0].interface_info.
- hanc_index + 1];
-
- dev->sliced_cc_mode.end_point_addr =
- le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
- bEndpointAddress);
-
- dev->sliced_cc_mode.num_alt = uif->num_altsetting;
- cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
- dev->sliced_cc_mode.end_point_addr,
- dev->sliced_cc_mode.num_alt);
- dev->sliced_cc_mode.alt_max_pkt_size =
- kmalloc(32 * dev->sliced_cc_mode.num_alt, GFP_KERNEL);
-
- if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) {
- cx231xx_errdev("out of memory!\n");
- clear_bit(dev->devno, &cx231xx_devused);
- v4l2_device_unregister(&dev->v4l2_dev);
- kfree(dev);
- dev = NULL;
- return -ENOMEM;
- }
-
- for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) {
- u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
- desc.wMaxPacketSize);
- dev->sliced_cc_mode.alt_max_pkt_size[i] =
- (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
- cx231xx_info("Alternate setting %i, max size= %i\n", i,
- dev->sliced_cc_mode.alt_max_pkt_size[i]);
- }
-
- if (dev->current_pcb_config.ts1_source != 0xff) {
- /* compute alternate max packet sizes for TS1 */
- uif = udev->actconfig->interface[dev->current_pcb_config.
- hs_config_info[0].
- interface_info.
- ts1_index + 1];
-
- dev->ts1_mode.end_point_addr =
- le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].
- desc.bEndpointAddress);
-
- dev->ts1_mode.num_alt = uif->num_altsetting;
- cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
- dev->ts1_mode.end_point_addr,
- dev->ts1_mode.num_alt);
- dev->ts1_mode.alt_max_pkt_size =
- kmalloc(32 * dev->ts1_mode.num_alt, GFP_KERNEL);
-
- if (dev->ts1_mode.alt_max_pkt_size == NULL) {
- cx231xx_errdev("out of memory!\n");
- clear_bit(dev->devno, &cx231xx_devused);
- v4l2_device_unregister(&dev->v4l2_dev);
- kfree(dev);
- dev = NULL;
- return -ENOMEM;
- }
-
- for (i = 0; i < dev->ts1_mode.num_alt; i++) {
- u16 tmp = le16_to_cpu(uif->altsetting[i].
- endpoint[isoc_pipe].desc.
- wMaxPacketSize);
- dev->ts1_mode.alt_max_pkt_size[i] =
- (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
- cx231xx_info("Alternate setting %i, max size= %i\n", i,
- dev->ts1_mode.alt_max_pkt_size[i]);
- }
- }
-
- if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) {
- cx231xx_enable_OSC(dev);
- cx231xx_reset_out(dev);
- cx231xx_set_alt_setting(dev, INDEX_VIDEO, 3);
- }
-
- if (dev->model == CX231XX_BOARD_CNXT_RDE_253S)
- cx231xx_sleep_s5h1432(dev);
-
- /* load other modules required */
- request_modules(dev);
-
- return 0;
-}
-
-/*
- * cx231xx_usb_disconnect()
- * called when the device gets diconencted
- * video device will be unregistered on v4l2_close in case it is still open
- */
-static void cx231xx_usb_disconnect(struct usb_interface *interface)
-{
- struct cx231xx *dev;
-
- dev = usb_get_intfdata(interface);
- usb_set_intfdata(interface, NULL);
-
- if (!dev)
- return;
-
- if (!dev->udev)
- return;
-
- dev->state |= DEV_DISCONNECTED;
-
- flush_request_modules(dev);
-
- /* wait until all current v4l2 io is finished then deallocate
- resources */
- mutex_lock(&dev->lock);
-
- wake_up_interruptible_all(&dev->open);
-
- if (dev->users) {
- cx231xx_warn
- ("device %s is open! Deregistration and memory "
- "deallocation are deferred on close.\n",
- video_device_node_name(dev->vdev));
-
- /* Even having users, it is safe to remove the RC i2c driver */
- cx231xx_ir_exit(dev);
-
- if (dev->USE_ISO)
- cx231xx_uninit_isoc(dev);
- else
- cx231xx_uninit_bulk(dev);
- wake_up_interruptible(&dev->wait_frame);
- wake_up_interruptible(&dev->wait_stream);
- } else {
- }
-
- cx231xx_close_extension(dev);
-
- mutex_unlock(&dev->lock);
-
- if (!dev->users)
- cx231xx_release_resources(dev);
-}
-
-static struct usb_driver cx231xx_usb_driver = {
- .name = "cx231xx",
- .probe = cx231xx_usb_probe,
- .disconnect = cx231xx_usb_disconnect,
- .id_table = cx231xx_id_table,
-};
-
-module_usb_driver(cx231xx_usb_driver);
diff --git a/drivers/media/video/cx231xx/cx231xx-conf-reg.h b/drivers/media/video/cx231xx/cx231xx-conf-reg.h
deleted file mode 100644
index 25593f212ab..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-conf-reg.h
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- cx231xx_conf-reg.h - driver for Conexant Cx23100/101/102 USB
- video capture devices
-
- Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _POLARIS_REG_H_
-#define _POLARIS_REG_H_
-
-#define BOARD_CFG_STAT 0x0
-#define TS_MODE_REG 0x4
-#define TS1_CFG_REG 0x8
-#define TS1_LENGTH_REG 0xc
-#define TS2_CFG_REG 0x10
-#define TS2_LENGTH_REG 0x14
-#define EP_MODE_SET 0x18
-#define CIR_PWR_PTN1 0x1c
-#define CIR_PWR_PTN2 0x20
-#define CIR_PWR_PTN3 0x24
-#define CIR_PWR_MASK0 0x28
-#define CIR_PWR_MASK1 0x2c
-#define CIR_PWR_MASK2 0x30
-#define CIR_GAIN 0x34
-#define CIR_CAR_REG 0x38
-#define CIR_OT_CFG1 0x40
-#define CIR_OT_CFG2 0x44
-#define GBULK_BIT_EN 0x68
-#define PWR_CTL_EN 0x74
-
-/* Polaris Endpoints capture mask for register EP_MODE_SET */
-#define ENABLE_EP1 0x01 /* Bit[0]=1 */
-#define ENABLE_EP2 0x02 /* Bit[1]=1 */
-#define ENABLE_EP3 0x04 /* Bit[2]=1 */
-#define ENABLE_EP4 0x08 /* Bit[3]=1 */
-#define ENABLE_EP5 0x10 /* Bit[4]=1 */
-#define ENABLE_EP6 0x20 /* Bit[5]=1 */
-
-/* Bit definition for register PWR_CTL_EN */
-#define PWR_MODE_MASK 0x17f
-#define PWR_AV_EN 0x08 /* bit3 */
-#define PWR_ISO_EN 0x40 /* bit6 */
-#define PWR_AV_MODE 0x30 /* bit4,5 */
-#define PWR_TUNER_EN 0x04 /* bit2 */
-#define PWR_DEMOD_EN 0x02 /* bit1 */
-#define I2C_DEMOD_EN 0x01 /* bit0 */
-#define PWR_RESETOUT_EN 0x100 /* bit8 */
-
-enum AV_MODE{
- POLARIS_AVMODE_DEFAULT = 0,
- POLARIS_AVMODE_DIGITAL = 0x10,
- POLARIS_AVMODE_ANALOGT_TV = 0x20,
- POLARIS_AVMODE_ENXTERNAL_AV = 0x30,
-
-};
-
-/* Colibri Registers */
-
-#define SINGLE_ENDED 0x0
-#define LOW_IF 0x4
-#define EU_IF 0x9
-#define US_IF 0xa
-
-#define SUP_BLK_TUNE1 0x00
-#define SUP_BLK_TUNE2 0x01
-#define SUP_BLK_TUNE3 0x02
-#define SUP_BLK_XTAL 0x03
-#define SUP_BLK_PLL1 0x04
-#define SUP_BLK_PLL2 0x05
-#define SUP_BLK_PLL3 0x06
-#define SUP_BLK_REF 0x07
-#define SUP_BLK_PWRDN 0x08
-#define SUP_BLK_TESTPAD 0x09
-#define ADC_COM_INT5_STAB_REF 0x0a
-#define ADC_COM_QUANT 0x0b
-#define ADC_COM_BIAS1 0x0c
-#define ADC_COM_BIAS2 0x0d
-#define ADC_COM_BIAS3 0x0e
-#define TESTBUS_CTRL 0x12
-
-#define FLD_PWRDN_TUNING_BIAS 0x10
-#define FLD_PWRDN_ENABLE_PLL 0x08
-#define FLD_PWRDN_PD_BANDGAP 0x04
-#define FLD_PWRDN_PD_BIAS 0x02
-#define FLD_PWRDN_PD_TUNECK 0x01
-
-
-#define ADC_STATUS_CH1 0x20
-#define ADC_STATUS_CH2 0x40
-#define ADC_STATUS_CH3 0x60
-
-#define ADC_STATUS2_CH1 0x21
-#define ADC_STATUS2_CH2 0x41
-#define ADC_STATUS2_CH3 0x61
-
-#define ADC_CAL_ATEST_CH1 0x22
-#define ADC_CAL_ATEST_CH2 0x42
-#define ADC_CAL_ATEST_CH3 0x62
-
-#define ADC_PWRDN_CLAMP_CH1 0x23
-#define ADC_PWRDN_CLAMP_CH2 0x43
-#define ADC_PWRDN_CLAMP_CH3 0x63
-
-#define ADC_CTRL_DAC23_CH1 0x24
-#define ADC_CTRL_DAC23_CH2 0x44
-#define ADC_CTRL_DAC23_CH3 0x64
-
-#define ADC_CTRL_DAC1_CH1 0x25
-#define ADC_CTRL_DAC1_CH2 0x45
-#define ADC_CTRL_DAC1_CH3 0x65
-
-#define ADC_DCSERVO_DEM_CH1 0x26
-#define ADC_DCSERVO_DEM_CH2 0x46
-#define ADC_DCSERVO_DEM_CH3 0x66
-
-#define ADC_FB_FRCRST_CH1 0x27
-#define ADC_FB_FRCRST_CH2 0x47
-#define ADC_FB_FRCRST_CH3 0x67
-
-#define ADC_INPUT_CH1 0x28
-#define ADC_INPUT_CH2 0x48
-#define ADC_INPUT_CH3 0x68
-#define INPUT_SEL_MASK 0x30 /* [5:4] in_sel */
-
-#define ADC_NTF_PRECLMP_EN_CH1 0x29
-#define ADC_NTF_PRECLMP_EN_CH2 0x49
-#define ADC_NTF_PRECLMP_EN_CH3 0x69
-
-#define ADC_QGAIN_RES_TRM_CH1 0x2a
-#define ADC_QGAIN_RES_TRM_CH2 0x4a
-#define ADC_QGAIN_RES_TRM_CH3 0x6a
-
-#define ADC_SOC_PRECLMP_TERM_CH1 0x2b
-#define ADC_SOC_PRECLMP_TERM_CH2 0x4b
-#define ADC_SOC_PRECLMP_TERM_CH3 0x6b
-
-#define TESTBUS_CTRL_CH1 0x32
-#define TESTBUS_CTRL_CH2 0x52
-#define TESTBUS_CTRL_CH3 0x72
-
-/******************************************************************************
- * DIF registers *
- ******************************************************************************/
-#define DIRECT_IF_REVB_BASE 0x00300
-
-/*****************************************************************************/
-#define DIF_PLL_FREQ_WORD (DIRECT_IF_REVB_BASE + 0x00000000)
-/*****************************************************************************/
-#define FLD_DIF_PLL_LOCK 0x80000000
-/* Reserved [30:29] */
-#define FLD_DIF_PLL_FREE_RUN 0x10000000
-#define FLD_DIF_PLL_FREQ 0x0fffffff
-
-/*****************************************************************************/
-#define DIF_PLL_CTRL (DIRECT_IF_REVB_BASE + 0x00000004)
-/*****************************************************************************/
-#define FLD_DIF_KD_PD 0xff000000
-/* Reserved [23:20] */
-#define FLD_DIF_KDS_PD 0x000f0000
-#define FLD_DIF_KI_PD 0x0000ff00
-/* Reserved [7:4] */
-#define FLD_DIF_KIS_PD 0x0000000f
-
-/*****************************************************************************/
-#define DIF_PLL_CTRL1 (DIRECT_IF_REVB_BASE + 0x00000008)
-/*****************************************************************************/
-#define FLD_DIF_KD_FD 0xff000000
-/* Reserved [23:20] */
-#define FLD_DIF_KDS_FD 0x000f0000
-#define FLD_DIF_KI_FD 0x0000ff00
-#define FLD_DIF_SIG_PROP_SZ 0x000000f0
-#define FLD_DIF_KIS_FD 0x0000000f
-
-/*****************************************************************************/
-#define DIF_PLL_CTRL2 (DIRECT_IF_REVB_BASE + 0x0000000c)
-/*****************************************************************************/
-#define FLD_DIF_PLL_AGC_REF 0xfff00000
-#define FLD_DIF_PLL_AGC_KI 0x000f0000
-/* Reserved [15] */
-#define FLD_DIF_FREQ_LIMIT 0x00007000
-#define FLD_DIF_K_FD 0x00000f00
-#define FLD_DIF_DOWNSMPL_FD 0x000000ff
-
-/*****************************************************************************/
-#define DIF_PLL_CTRL3 (DIRECT_IF_REVB_BASE + 0x00000010)
-/*****************************************************************************/
-/* Reserved [31:16] */
-#define FLD_DIF_PLL_AGC_EN 0x00008000
-/* Reserved [14:12] */
-#define FLD_DIF_PLL_MAN_GAIN 0x00000fff
-
-/*****************************************************************************/
-#define DIF_AGC_IF_REF (DIRECT_IF_REVB_BASE + 0x00000014)
-/*****************************************************************************/
-#define FLD_DIF_K_AGC_RF 0xf0000000
-#define FLD_DIF_K_AGC_IF 0x0f000000
-#define FLD_DIF_K_AGC_INT 0x00f00000
-/* Reserved [19:12] */
-#define FLD_DIF_IF_REF 0x00000fff
-
-/*****************************************************************************/
-#define DIF_AGC_CTRL_IF (DIRECT_IF_REVB_BASE + 0x00000018)
-/*****************************************************************************/
-#define FLD_DIF_IF_MAX 0xff000000
-#define FLD_DIF_IF_MIN 0x00ff0000
-#define FLD_DIF_IF_AGC 0x0000ffff
-
-/*****************************************************************************/
-#define DIF_AGC_CTRL_INT (DIRECT_IF_REVB_BASE + 0x0000001c)
-/*****************************************************************************/
-#define FLD_DIF_INT_MAX 0xff000000
-#define FLD_DIF_INT_MIN 0x00ff0000
-#define FLD_DIF_INT_AGC 0x0000ffff
-
-/*****************************************************************************/
-#define DIF_AGC_CTRL_RF (DIRECT_IF_REVB_BASE + 0x00000020)
-/*****************************************************************************/
-#define FLD_DIF_RF_MAX 0xff000000
-#define FLD_DIF_RF_MIN 0x00ff0000
-#define FLD_DIF_RF_AGC 0x0000ffff
-
-/*****************************************************************************/
-#define DIF_AGC_IF_INT_CURRENT (DIRECT_IF_REVB_BASE + 0x00000024)
-/*****************************************************************************/
-#define FLD_DIF_IF_AGC_IN 0xffff0000
-#define FLD_DIF_INT_AGC_IN 0x0000ffff
-
-/*****************************************************************************/
-#define DIF_AGC_RF_CURRENT (DIRECT_IF_REVB_BASE + 0x00000028)
-/*****************************************************************************/
-/* Reserved [31:16] */
-#define FLD_DIF_RF_AGC_IN 0x0000ffff
-
-/*****************************************************************************/
-#define DIF_VIDEO_AGC_CTRL (DIRECT_IF_REVB_BASE + 0x0000002c)
-/*****************************************************************************/
-#define FLD_DIF_AFD 0xc0000000
-#define FLD_DIF_K_VID_AGC 0x30000000
-#define FLD_DIF_LINE_LENGTH 0x0fff0000
-#define FLD_DIF_AGC_GAIN 0x0000ffff
-
-/*****************************************************************************/
-#define DIF_VID_AUD_OVERRIDE (DIRECT_IF_REVB_BASE + 0x00000030)
-/*****************************************************************************/
-#define FLD_DIF_AUDIO_AGC_OVERRIDE 0x80000000
-/* Reserved [30:30] */
-#define FLD_DIF_AUDIO_MAN_GAIN 0x3f000000
-/* Reserved [23:17] */
-#define FLD_DIF_VID_AGC_OVERRIDE 0x00010000
-#define FLD_DIF_VID_MAN_GAIN 0x0000ffff
-
-/*****************************************************************************/
-#define DIF_AV_SEP_CTRL (DIRECT_IF_REVB_BASE + 0x00000034)
-/*****************************************************************************/
-#define FLD_DIF_LPF_FREQ 0xc0000000
-#define FLD_DIF_AV_PHASE_INC 0x3f000000
-#define FLD_DIF_AUDIO_FREQ 0x00ffffff
-
-/*****************************************************************************/
-#define DIF_COMP_FLT_CTRL (DIRECT_IF_REVB_BASE + 0x00000038)
-/*****************************************************************************/
-/* Reserved [31:24] */
-#define FLD_DIF_IIR23_R2 0x00ff0000
-#define FLD_DIF_IIR23_R1 0x0000ff00
-#define FLD_DIF_IIR1_R1 0x000000ff
-
-/*****************************************************************************/
-#define DIF_MISC_CTRL (DIRECT_IF_REVB_BASE + 0x0000003c)
-/*****************************************************************************/
-#define FLD_DIF_DIF_BYPASS 0x80000000
-#define FLD_DIF_FM_NYQ_GAIN 0x40000000
-#define FLD_DIF_RF_AGC_ENA 0x20000000
-#define FLD_DIF_INT_AGC_ENA 0x10000000
-#define FLD_DIF_IF_AGC_ENA 0x08000000
-#define FLD_DIF_FORCE_RF_IF_LOCK 0x04000000
-#define FLD_DIF_VIDEO_AGC_ENA 0x02000000
-#define FLD_DIF_RF_AGC_INV 0x01000000
-#define FLD_DIF_INT_AGC_INV 0x00800000
-#define FLD_DIF_IF_AGC_INV 0x00400000
-#define FLD_DIF_SPEC_INV 0x00200000
-#define FLD_DIF_AUD_FULL_BW 0x00100000
-#define FLD_DIF_AUD_SRC_SEL 0x00080000
-/* Reserved [18] */
-#define FLD_DIF_IF_FREQ 0x00030000
-/* Reserved [15:14] */
-#define FLD_DIF_TIP_OFFSET 0x00003f00
-/* Reserved [7:5] */
-#define FLD_DIF_DITHER_ENA 0x00000010
-/* Reserved [3:1] */
-#define FLD_DIF_RF_IF_LOCK 0x00000001
-
-/*****************************************************************************/
-#define DIF_SRC_PHASE_INC (DIRECT_IF_REVB_BASE + 0x00000040)
-/*****************************************************************************/
-/* Reserved [31:29] */
-#define FLD_DIF_PHASE_INC 0x1fffffff
-
-/*****************************************************************************/
-#define DIF_SRC_GAIN_CONTROL (DIRECT_IF_REVB_BASE + 0x00000044)
-/*****************************************************************************/
-/* Reserved [31:16] */
-#define FLD_DIF_SRC_KI 0x0000ff00
-#define FLD_DIF_SRC_KD 0x000000ff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF01 (DIRECT_IF_REVB_BASE + 0x00000048)
-/*****************************************************************************/
-/* Reserved [31:19] */
-#define FLD_DIF_BPF_COEFF_0 0x00070000
-/* Reserved [15:4] */
-#define FLD_DIF_BPF_COEFF_1 0x0000000f
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF23 (DIRECT_IF_REVB_BASE + 0x0000004c)
-/*****************************************************************************/
-/* Reserved [31:22] */
-#define FLD_DIF_BPF_COEFF_2 0x003f0000
-/* Reserved [15:7] */
-#define FLD_DIF_BPF_COEFF_3 0x0000007f
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF45 (DIRECT_IF_REVB_BASE + 0x00000050)
-/*****************************************************************************/
-/* Reserved [31:24] */
-#define FLD_DIF_BPF_COEFF_4 0x00ff0000
-/* Reserved [15:8] */
-#define FLD_DIF_BPF_COEFF_5 0x000000ff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF67 (DIRECT_IF_REVB_BASE + 0x00000054)
-/*****************************************************************************/
-/* Reserved [31:25] */
-#define FLD_DIF_BPF_COEFF_6 0x01ff0000
-/* Reserved [15:9] */
-#define FLD_DIF_BPF_COEFF_7 0x000001ff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF89 (DIRECT_IF_REVB_BASE + 0x00000058)
-/*****************************************************************************/
-/* Reserved [31:26] */
-#define FLD_DIF_BPF_COEFF_8 0x03ff0000
-/* Reserved [15:10] */
-#define FLD_DIF_BPF_COEFF_9 0x000003ff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF1011 (DIRECT_IF_REVB_BASE + 0x0000005c)
-/*****************************************************************************/
-/* Reserved [31:27] */
-#define FLD_DIF_BPF_COEFF_10 0x07ff0000
-/* Reserved [15:11] */
-#define FLD_DIF_BPF_COEFF_11 0x000007ff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF1213 (DIRECT_IF_REVB_BASE + 0x00000060)
-/*****************************************************************************/
-/* Reserved [31:27] */
-#define FLD_DIF_BPF_COEFF_12 0x07ff0000
-/* Reserved [15:12] */
-#define FLD_DIF_BPF_COEFF_13 0x00000fff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF1415 (DIRECT_IF_REVB_BASE + 0x00000064)
-/*****************************************************************************/
-/* Reserved [31:28] */
-#define FLD_DIF_BPF_COEFF_14 0x0fff0000
-/* Reserved [15:12] */
-#define FLD_DIF_BPF_COEFF_15 0x00000fff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF1617 (DIRECT_IF_REVB_BASE + 0x00000068)
-/*****************************************************************************/
-/* Reserved [31:29] */
-#define FLD_DIF_BPF_COEFF_16 0x1fff0000
-/* Reserved [15:13] */
-#define FLD_DIF_BPF_COEFF_17 0x00001fff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF1819 (DIRECT_IF_REVB_BASE + 0x0000006c)
-/*****************************************************************************/
-/* Reserved [31:29] */
-#define FLD_DIF_BPF_COEFF_18 0x1fff0000
-/* Reserved [15:13] */
-#define FLD_DIF_BPF_COEFF_19 0x00001fff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF2021 (DIRECT_IF_REVB_BASE + 0x00000070)
-/*****************************************************************************/
-/* Reserved [31:29] */
-#define FLD_DIF_BPF_COEFF_20 0x1fff0000
-/* Reserved [15:14] */
-#define FLD_DIF_BPF_COEFF_21 0x00003fff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF2223 (DIRECT_IF_REVB_BASE + 0x00000074)
-/*****************************************************************************/
-/* Reserved [31:30] */
-#define FLD_DIF_BPF_COEFF_22 0x3fff0000
-/* Reserved [15:14] */
-#define FLD_DIF_BPF_COEFF_23 0x00003fff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF2425 (DIRECT_IF_REVB_BASE + 0x00000078)
-/*****************************************************************************/
-/* Reserved [31:30] */
-#define FLD_DIF_BPF_COEFF_24 0x3fff0000
-/* Reserved [15:14] */
-#define FLD_DIF_BPF_COEFF_25 0x00003fff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF2627 (DIRECT_IF_REVB_BASE + 0x0000007c)
-/*****************************************************************************/
-/* Reserved [31:30] */
-#define FLD_DIF_BPF_COEFF_26 0x3fff0000
-/* Reserved [15:14] */
-#define FLD_DIF_BPF_COEFF_27 0x00003fff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF2829 (DIRECT_IF_REVB_BASE + 0x00000080)
-/*****************************************************************************/
-/* Reserved [31:30] */
-#define FLD_DIF_BPF_COEFF_28 0x3fff0000
-/* Reserved [15:14] */
-#define FLD_DIF_BPF_COEFF_29 0x00003fff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF3031 (DIRECT_IF_REVB_BASE + 0x00000084)
-/*****************************************************************************/
-/* Reserved [31:30] */
-#define FLD_DIF_BPF_COEFF_30 0x3fff0000
-/* Reserved [15:14] */
-#define FLD_DIF_BPF_COEFF_31 0x00003fff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF3233 (DIRECT_IF_REVB_BASE + 0x00000088)
-/*****************************************************************************/
-/* Reserved [31:30] */
-#define FLD_DIF_BPF_COEFF_32 0x3fff0000
-/* Reserved [15:14] */
-#define FLD_DIF_BPF_COEFF_33 0x00003fff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF3435 (DIRECT_IF_REVB_BASE + 0x0000008c)
-/*****************************************************************************/
-/* Reserved [31:30] */
-#define FLD_DIF_BPF_COEFF_34 0x3fff0000
-/* Reserved [15:14] */
-#define FLD_DIF_BPF_COEFF_35 0x00003fff
-
-/*****************************************************************************/
-#define DIF_BPF_COEFF36 (DIRECT_IF_REVB_BASE + 0x00000090)
-/*****************************************************************************/
-/* Reserved [31:30] */
-#define FLD_DIF_BPF_COEFF_36 0x3fff0000
-/* Reserved [15:0] */
-
-/*****************************************************************************/
-#define DIF_RPT_VARIANCE (DIRECT_IF_REVB_BASE + 0x00000094)
-/*****************************************************************************/
-/* Reserved [31:20] */
-#define FLD_DIF_RPT_VARIANCE 0x000fffff
-
-/*****************************************************************************/
-#define DIF_SOFT_RST_CTRL_REVB (DIRECT_IF_REVB_BASE + 0x00000098)
-/*****************************************************************************/
-/* Reserved [31:8] */
-#define FLD_DIF_DIF_SOFT_RST 0x00000080
-#define FLD_DIF_DIF_REG_RST_MSK 0x00000040
-#define FLD_DIF_AGC_RST_MSK 0x00000020
-#define FLD_DIF_CMP_RST_MSK 0x00000010
-#define FLD_DIF_AVS_RST_MSK 0x00000008
-#define FLD_DIF_NYQ_RST_MSK 0x00000004
-#define FLD_DIF_DIF_SRC_RST_MSK 0x00000002
-#define FLD_DIF_PLL_RST_MSK 0x00000001
-
-/*****************************************************************************/
-#define DIF_PLL_FREQ_ERR (DIRECT_IF_REVB_BASE + 0x0000009c)
-/*****************************************************************************/
-/* Reserved [31:25] */
-#define FLD_DIF_CTL_IP 0x01ffffff
-
-#endif
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c
deleted file mode 100644
index 05358d48613..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-core.c
+++ /dev/null
@@ -1,1736 +0,0 @@
-/*
- cx231xx-core.c - driver for Conexant Cx23100/101/102
- USB video capture devices
-
- Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
- Based on em28xx driver
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/vmalloc.h>
-#include <media/v4l2-common.h>
-#include <media/tuner.h>
-
-#include "cx231xx.h"
-#include "cx231xx-reg.h"
-
-/* #define ENABLE_DEBUG_ISOC_FRAMES */
-
-static unsigned int core_debug;
-module_param(core_debug, int, 0644);
-MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
-
-#define cx231xx_coredbg(fmt, arg...) do {\
- if (core_debug) \
- printk(KERN_INFO "%s %s :"fmt, \
- dev->name, __func__ , ##arg); } while (0)
-
-static unsigned int reg_debug;
-module_param(reg_debug, int, 0644);
-MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]");
-
-static int alt = CX231XX_PINOUT;
-module_param(alt, int, 0644);
-MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
-
-#define cx231xx_isocdbg(fmt, arg...) do {\
- if (core_debug) \
- printk(KERN_INFO "%s %s :"fmt, \
- dev->name, __func__ , ##arg); } while (0)
-
-/*****************************************************************
-* Device control list functions *
-******************************************************************/
-
-LIST_HEAD(cx231xx_devlist);
-static DEFINE_MUTEX(cx231xx_devlist_mutex);
-
-/*
- * cx231xx_realease_resources()
- * unregisters the v4l2,i2c and usb devices
- * called when the device gets disconected or at module unload
-*/
-void cx231xx_remove_from_devlist(struct cx231xx *dev)
-{
- if (dev == NULL)
- return;
- if (dev->udev == NULL)
- return;
-
- if (atomic_read(&dev->devlist_count) > 0) {
- mutex_lock(&cx231xx_devlist_mutex);
- list_del(&dev->devlist);
- atomic_dec(&dev->devlist_count);
- mutex_unlock(&cx231xx_devlist_mutex);
- }
-};
-
-void cx231xx_add_into_devlist(struct cx231xx *dev)
-{
- mutex_lock(&cx231xx_devlist_mutex);
- list_add_tail(&dev->devlist, &cx231xx_devlist);
- atomic_inc(&dev->devlist_count);
- mutex_unlock(&cx231xx_devlist_mutex);
-};
-
-static LIST_HEAD(cx231xx_extension_devlist);
-
-int cx231xx_register_extension(struct cx231xx_ops *ops)
-{
- struct cx231xx *dev = NULL;
-
- mutex_lock(&cx231xx_devlist_mutex);
- list_add_tail(&ops->next, &cx231xx_extension_devlist);
- list_for_each_entry(dev, &cx231xx_devlist, devlist)
- ops->init(dev);
-
- printk(KERN_INFO DRIVER_NAME ": %s initialized\n", ops->name);
- mutex_unlock(&cx231xx_devlist_mutex);
- return 0;
-}
-EXPORT_SYMBOL(cx231xx_register_extension);
-
-void cx231xx_unregister_extension(struct cx231xx_ops *ops)
-{
- struct cx231xx *dev = NULL;
-
- mutex_lock(&cx231xx_devlist_mutex);
- list_for_each_entry(dev, &cx231xx_devlist, devlist)
- ops->fini(dev);
-
-
- printk(KERN_INFO DRIVER_NAME ": %s removed\n", ops->name);
- list_del(&ops->next);
- mutex_unlock(&cx231xx_devlist_mutex);
-}
-EXPORT_SYMBOL(cx231xx_unregister_extension);
-
-void cx231xx_init_extension(struct cx231xx *dev)
-{
- struct cx231xx_ops *ops = NULL;
-
- mutex_lock(&cx231xx_devlist_mutex);
- if (!list_empty(&cx231xx_extension_devlist)) {
- list_for_each_entry(ops, &cx231xx_extension_devlist, next) {
- if (ops->init)
- ops->init(dev);
- }
- }
- mutex_unlock(&cx231xx_devlist_mutex);
-}
-
-void cx231xx_close_extension(struct cx231xx *dev)
-{
- struct cx231xx_ops *ops = NULL;
-
- mutex_lock(&cx231xx_devlist_mutex);
- if (!list_empty(&cx231xx_extension_devlist)) {
- list_for_each_entry(ops, &cx231xx_extension_devlist, next) {
- if (ops->fini)
- ops->fini(dev);
- }
- }
- mutex_unlock(&cx231xx_devlist_mutex);
-}
-
-/****************************************************************
-* U S B related functions *
-*****************************************************************/
-int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus,
- struct cx231xx_i2c_xfer_data *req_data)
-{
- int status = 0;
- struct cx231xx *dev = i2c_bus->dev;
- struct VENDOR_REQUEST_IN ven_req;
-
- u8 saddr_len = 0;
- u8 _i2c_period = 0;
- u8 _i2c_nostop = 0;
- u8 _i2c_reserve = 0;
-
- if (dev->state & DEV_DISCONNECTED)
- return -ENODEV;
-
- /* Get the I2C period, nostop and reserve parameters */
- _i2c_period = i2c_bus->i2c_period;
- _i2c_nostop = i2c_bus->i2c_nostop;
- _i2c_reserve = i2c_bus->i2c_reserve;
-
- saddr_len = req_data->saddr_len;
-
- /* Set wValue */
- if (saddr_len == 1) /* need check saddr_len == 0 */
- ven_req.wValue =
- req_data->
- dev_addr << 9 | _i2c_period << 4 | saddr_len << 2 |
- _i2c_nostop << 1 | I2C_SYNC | _i2c_reserve << 6;
- else
- ven_req.wValue =
- req_data->
- dev_addr << 9 | _i2c_period << 4 | saddr_len << 2 |
- _i2c_nostop << 1 | I2C_SYNC | _i2c_reserve << 6;
-
- /* set channel number */
- if (req_data->direction & I2C_M_RD) {
- /* channel number, for read,spec required channel_num +4 */
- ven_req.bRequest = i2c_bus->nr + 4;
- } else
- ven_req.bRequest = i2c_bus->nr; /* channel number, */
-
- /* set index value */
- switch (saddr_len) {
- case 0:
- ven_req.wIndex = 0; /* need check */
- break;
- case 1:
- ven_req.wIndex = (req_data->saddr_dat & 0xff);
- break;
- case 2:
- ven_req.wIndex = req_data->saddr_dat;
- break;
- }
-
- /* set wLength value */
- ven_req.wLength = req_data->buf_size;
-
- /* set bData value */
- ven_req.bData = 0;
-
- /* set the direction */
- if (req_data->direction) {
- ven_req.direction = USB_DIR_IN;
- memset(req_data->p_buffer, 0x00, ven_req.wLength);
- } else
- ven_req.direction = USB_DIR_OUT;
-
- /* set the buffer for read / write */
- ven_req.pBuff = req_data->p_buffer;
-
-
- /* call common vendor command request */
- status = cx231xx_send_vendor_cmd(dev, &ven_req);
- if (status < 0) {
- cx231xx_info
- ("UsbInterface::sendCommand, failed with status -%d\n",
- status);
- }
-
- return status;
-}
-EXPORT_SYMBOL_GPL(cx231xx_send_usb_command);
-
-/*
- * Sends/Receives URB control messages, assuring to use a kalloced buffer
- * for all operations (dev->urb_buf), to avoid using stacked buffers, as
- * they aren't safe for usage with USB, due to DMA restrictions.
- * Also implements the debug code for control URB's.
- */
-static int __usb_control_msg(struct cx231xx *dev, unsigned int pipe,
- __u8 request, __u8 requesttype, __u16 value, __u16 index,
- void *data, __u16 size, int timeout)
-{
- int rc, i;
-
- if (reg_debug) {
- printk(KERN_DEBUG "%s: (pipe 0x%08x): "
- "%s: %02x %02x %02x %02x %02x %02x %02x %02x ",
- dev->name,
- pipe,
- (requesttype & USB_DIR_IN) ? "IN" : "OUT",
- requesttype,
- request,
- value & 0xff, value >> 8,
- index & 0xff, index >> 8,
- size & 0xff, size >> 8);
- if (!(requesttype & USB_DIR_IN)) {
- printk(KERN_CONT ">>>");
- for (i = 0; i < size; i++)
- printk(KERN_CONT " %02x",
- ((unsigned char *)data)[i]);
- }
- }
-
- /* Do the real call to usb_control_msg */
- mutex_lock(&dev->ctrl_urb_lock);
- if (!(requesttype & USB_DIR_IN) && size)
- memcpy(dev->urb_buf, data, size);
- rc = usb_control_msg(dev->udev, pipe, request, requesttype, value,
- index, dev->urb_buf, size, timeout);
- if ((requesttype & USB_DIR_IN) && size)
- memcpy(data, dev->urb_buf, size);
- mutex_unlock(&dev->ctrl_urb_lock);
-
- if (reg_debug) {
- if (unlikely(rc < 0)) {
- printk(KERN_CONT "FAILED!\n");
- return rc;
- }
-
- if ((requesttype & USB_DIR_IN)) {
- printk(KERN_CONT "<<<");
- for (i = 0; i < size; i++)
- printk(KERN_CONT " %02x",
- ((unsigned char *)data)[i]);
- }
- printk(KERN_CONT "\n");
- }
-
- return rc;
-}
-
-
-/*
- * cx231xx_read_ctrl_reg()
- * reads data from the usb device specifying bRequest and wValue
- */
-int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg,
- char *buf, int len)
-{
- u8 val = 0;
- int ret;
- int pipe = usb_rcvctrlpipe(dev->udev, 0);
-
- if (dev->state & DEV_DISCONNECTED)
- return -ENODEV;
-
- if (len > URB_MAX_CTRL_SIZE)
- return -EINVAL;
-
- switch (len) {
- case 1:
- val = ENABLE_ONE_BYTE;
- break;
- case 2:
- val = ENABLE_TWE_BYTE;
- break;
- case 3:
- val = ENABLE_THREE_BYTE;
- break;
- case 4:
- val = ENABLE_FOUR_BYTE;
- break;
- default:
- val = 0xFF; /* invalid option */
- }
-
- if (val == 0xFF)
- return -EINVAL;
-
- ret = __usb_control_msg(dev, pipe, req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- val, reg, buf, len, HZ);
- return ret;
-}
-
-int cx231xx_send_vendor_cmd(struct cx231xx *dev,
- struct VENDOR_REQUEST_IN *ven_req)
-{
- int ret;
- int pipe = 0;
- int unsend_size = 0;
- u8 *pdata;
-
- if (dev->state & DEV_DISCONNECTED)
- return -ENODEV;
-
- if ((ven_req->wLength > URB_MAX_CTRL_SIZE))
- return -EINVAL;
-
- if (ven_req->direction)
- pipe = usb_rcvctrlpipe(dev->udev, 0);
- else
- pipe = usb_sndctrlpipe(dev->udev, 0);
-
- /*
- * If the cx23102 read more than 4 bytes with i2c bus,
- * need chop to 4 byte per request
- */
- if ((ven_req->wLength > 4) && ((ven_req->bRequest == 0x4) ||
- (ven_req->bRequest == 0x5) ||
- (ven_req->bRequest == 0x6))) {
- unsend_size = 0;
- pdata = ven_req->pBuff;
-
-
- unsend_size = ven_req->wLength;
-
- /* the first package */
- ven_req->wValue = ven_req->wValue & 0xFFFB;
- ven_req->wValue = (ven_req->wValue & 0xFFBD) | 0x2;
- ret = __usb_control_msg(dev, pipe, ven_req->bRequest,
- ven_req->direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- ven_req->wValue, ven_req->wIndex, pdata,
- 0x0004, HZ);
- unsend_size = unsend_size - 4;
-
- /* the middle package */
- ven_req->wValue = (ven_req->wValue & 0xFFBD) | 0x42;
- while (unsend_size - 4 > 0) {
- pdata = pdata + 4;
- ret = __usb_control_msg(dev, pipe,
- ven_req->bRequest,
- ven_req->direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- ven_req->wValue, ven_req->wIndex, pdata,
- 0x0004, HZ);
- unsend_size = unsend_size - 4;
- }
-
- /* the last package */
- ven_req->wValue = (ven_req->wValue & 0xFFBD) | 0x40;
- pdata = pdata + 4;
- ret = __usb_control_msg(dev, pipe, ven_req->bRequest,
- ven_req->direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- ven_req->wValue, ven_req->wIndex, pdata,
- unsend_size, HZ);
- } else {
- ret = __usb_control_msg(dev, pipe, ven_req->bRequest,
- ven_req->direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- ven_req->wValue, ven_req->wIndex,
- ven_req->pBuff, ven_req->wLength, HZ);
- }
-
- return ret;
-}
-
-/*
- * cx231xx_write_ctrl_reg()
- * sends data to the usb device, specifying bRequest
- */
-int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, char *buf,
- int len)
-{
- u8 val = 0;
- int ret;
- int pipe = usb_sndctrlpipe(dev->udev, 0);
-
- if (dev->state & DEV_DISCONNECTED)
- return -ENODEV;
-
- if ((len < 1) || (len > URB_MAX_CTRL_SIZE))
- return -EINVAL;
-
- switch (len) {
- case 1:
- val = ENABLE_ONE_BYTE;
- break;
- case 2:
- val = ENABLE_TWE_BYTE;
- break;
- case 3:
- val = ENABLE_THREE_BYTE;
- break;
- case 4:
- val = ENABLE_FOUR_BYTE;
- break;
- default:
- val = 0xFF; /* invalid option */
- }
-
- if (val == 0xFF)
- return -EINVAL;
-
- if (reg_debug) {
- int byte;
-
- cx231xx_isocdbg("(pipe 0x%08x): "
- "OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>",
- pipe,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- req, 0, val, reg & 0xff,
- reg >> 8, len & 0xff, len >> 8);
-
- for (byte = 0; byte < len; byte++)
- cx231xx_isocdbg(" %02x", (unsigned char)buf[byte]);
- cx231xx_isocdbg("\n");
- }
-
- ret = __usb_control_msg(dev, pipe, req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- val, reg, buf, len, HZ);
-
- return ret;
-}
-
-/****************************************************************
-* USB Alternate Setting functions *
-*****************************************************************/
-
-int cx231xx_set_video_alternate(struct cx231xx *dev)
-{
- int errCode, prev_alt = dev->video_mode.alt;
- unsigned int min_pkt_size = dev->width * 2 + 4;
- u32 usb_interface_index = 0;
-
- /* When image size is bigger than a certain value,
- the frame size should be increased, otherwise, only
- green screen will be received.
- */
- if (dev->width * 2 * dev->height > 720 * 240 * 2)
- min_pkt_size *= 2;
-
- if (dev->width > 360) {
- /* resolutions: 720,704,640 */
- dev->video_mode.alt = 3;
- } else if (dev->width > 180) {
- /* resolutions: 360,352,320,240 */
- dev->video_mode.alt = 2;
- } else if (dev->width > 0) {
- /* resolutions: 180,176,160,128,88 */
- dev->video_mode.alt = 1;
- } else {
- /* Change to alt0 BULK to release USB bandwidth */
- dev->video_mode.alt = 0;
- }
-
- if (dev->USE_ISO == 0)
- dev->video_mode.alt = 0;
-
- cx231xx_coredbg("dev->video_mode.alt= %d\n", dev->video_mode.alt);
-
- /* Get the correct video interface Index */
- usb_interface_index =
- dev->current_pcb_config.hs_config_info[0].interface_info.
- video_index + 1;
-
- if (dev->video_mode.alt != prev_alt) {
- cx231xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
- min_pkt_size, dev->video_mode.alt);
-
- if (dev->video_mode.alt_max_pkt_size != NULL)
- dev->video_mode.max_pkt_size =
- dev->video_mode.alt_max_pkt_size[dev->video_mode.alt];
- cx231xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n",
- dev->video_mode.alt,
- dev->video_mode.max_pkt_size);
- errCode =
- usb_set_interface(dev->udev, usb_interface_index,
- dev->video_mode.alt);
- if (errCode < 0) {
- cx231xx_errdev
- ("cannot change alt number to %d (error=%i)\n",
- dev->video_mode.alt, errCode);
- return errCode;
- }
- }
- return 0;
-}
-
-int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt)
-{
- int status = 0;
- u32 usb_interface_index = 0;
- u32 max_pkt_size = 0;
-
- switch (index) {
- case INDEX_TS1:
- usb_interface_index =
- dev->current_pcb_config.hs_config_info[0].interface_info.
- ts1_index + 1;
- dev->ts1_mode.alt = alt;
- if (dev->ts1_mode.alt_max_pkt_size != NULL)
- max_pkt_size = dev->ts1_mode.max_pkt_size =
- dev->ts1_mode.alt_max_pkt_size[dev->ts1_mode.alt];
- break;
- case INDEX_TS2:
- usb_interface_index =
- dev->current_pcb_config.hs_config_info[0].interface_info.
- ts2_index + 1;
- break;
- case INDEX_AUDIO:
- usb_interface_index =
- dev->current_pcb_config.hs_config_info[0].interface_info.
- audio_index + 1;
- dev->adev.alt = alt;
- if (dev->adev.alt_max_pkt_size != NULL)
- max_pkt_size = dev->adev.max_pkt_size =
- dev->adev.alt_max_pkt_size[dev->adev.alt];
- break;
- case INDEX_VIDEO:
- usb_interface_index =
- dev->current_pcb_config.hs_config_info[0].interface_info.
- video_index + 1;
- dev->video_mode.alt = alt;
- if (dev->video_mode.alt_max_pkt_size != NULL)
- max_pkt_size = dev->video_mode.max_pkt_size =
- dev->video_mode.alt_max_pkt_size[dev->video_mode.
- alt];
- break;
- case INDEX_VANC:
- if (dev->board.no_alt_vanc)
- return 0;
- usb_interface_index =
- dev->current_pcb_config.hs_config_info[0].interface_info.
- vanc_index + 1;
- dev->vbi_mode.alt = alt;
- if (dev->vbi_mode.alt_max_pkt_size != NULL)
- max_pkt_size = dev->vbi_mode.max_pkt_size =
- dev->vbi_mode.alt_max_pkt_size[dev->vbi_mode.alt];
- break;
- case INDEX_HANC:
- usb_interface_index =
- dev->current_pcb_config.hs_config_info[0].interface_info.
- hanc_index + 1;
- dev->sliced_cc_mode.alt = alt;
- if (dev->sliced_cc_mode.alt_max_pkt_size != NULL)
- max_pkt_size = dev->sliced_cc_mode.max_pkt_size =
- dev->sliced_cc_mode.alt_max_pkt_size[dev->
- sliced_cc_mode.
- alt];
- break;
- default:
- break;
- }
-
- if (alt > 0 && max_pkt_size == 0) {
- cx231xx_errdev
- ("can't change interface %d alt no. to %d: Max. Pkt size = 0\n",
- usb_interface_index, alt);
- /*To workaround error number=-71 on EP0 for videograbber,
- need add following codes.*/
- if (dev->board.no_alt_vanc)
- return -1;
- }
-
- cx231xx_coredbg("setting alternate %d with wMaxPacketSize=%u,"
- "Interface = %d\n", alt, max_pkt_size,
- usb_interface_index);
-
- if (usb_interface_index > 0) {
- status = usb_set_interface(dev->udev, usb_interface_index, alt);
- if (status < 0) {
- cx231xx_errdev
- ("can't change interface %d alt no. to %d (err=%i)\n",
- usb_interface_index, alt, status);
- return status;
- }
- }
-
- return status;
-}
-EXPORT_SYMBOL_GPL(cx231xx_set_alt_setting);
-
-int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio)
-{
- int rc = 0;
-
- if (!gpio)
- return rc;
-
- /* Send GPIO reset sequences specified at board entry */
- while (gpio->sleep >= 0) {
- rc = cx231xx_set_gpio_value(dev, gpio->bit, gpio->val);
- if (rc < 0)
- return rc;
-
- if (gpio->sleep > 0)
- msleep(gpio->sleep);
-
- gpio++;
- }
- return rc;
-}
-
-int cx231xx_demod_reset(struct cx231xx *dev)
-{
-
- u8 status = 0;
- u8 value[4] = { 0, 0, 0, 0 };
-
- status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN,
- value, 4);
-
- cx231xx_coredbg("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN,
- value[0], value[1], value[2], value[3]);
-
- cx231xx_coredbg("Enter cx231xx_demod_reset()\n");
-
- value[1] = (u8) 0x3;
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(10);
-
- value[1] = (u8) 0x0;
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(10);
-
- value[1] = (u8) 0x3;
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- msleep(10);
-
-
-
- status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN,
- value, 4);
-
- cx231xx_coredbg("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN,
- value[0], value[1], value[2], value[3]);
-
- return status;
-}
-EXPORT_SYMBOL_GPL(cx231xx_demod_reset);
-int is_fw_load(struct cx231xx *dev)
-{
- return cx231xx_check_fw(dev);
-}
-EXPORT_SYMBOL_GPL(is_fw_load);
-
-int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
-{
- int errCode = 0;
-
- if (dev->mode == set_mode)
- return 0;
-
- if (set_mode == CX231XX_SUSPEND) {
- /* Set the chip in power saving mode */
- dev->mode = set_mode;
- }
-
- /* Resource is locked */
- if (dev->mode != CX231XX_SUSPEND)
- return -EINVAL;
-
- dev->mode = set_mode;
-
- if (dev->mode == CX231XX_DIGITAL_MODE)/* Set Digital power mode */ {
- /* set AGC mode to Digital */
- switch (dev->model) {
- case CX231XX_BOARD_CNXT_CARRAERA:
- case CX231XX_BOARD_CNXT_RDE_250:
- case CX231XX_BOARD_CNXT_SHELBY:
- case CX231XX_BOARD_CNXT_RDU_250:
- errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0);
- break;
- case CX231XX_BOARD_CNXT_RDE_253S:
- case CX231XX_BOARD_CNXT_RDU_253S:
- errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1);
- break;
- case CX231XX_BOARD_HAUPPAUGE_EXETER:
- errCode = cx231xx_set_power_mode(dev,
- POLARIS_AVMODE_DIGITAL);
- break;
- default:
- break;
- }
- } else/* Set Analog Power mode */ {
- /* set AGC mode to Analog */
- switch (dev->model) {
- case CX231XX_BOARD_CNXT_CARRAERA:
- case CX231XX_BOARD_CNXT_RDE_250:
- case CX231XX_BOARD_CNXT_SHELBY:
- case CX231XX_BOARD_CNXT_RDU_250:
- errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1);
- break;
- case CX231XX_BOARD_CNXT_RDE_253S:
- case CX231XX_BOARD_CNXT_RDU_253S:
- case CX231XX_BOARD_HAUPPAUGE_EXETER:
- case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
- case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL:
- case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC:
- errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0);
- break;
- default:
- break;
- }
- }
-
- return errCode ? -EINVAL : 0;
-}
-EXPORT_SYMBOL_GPL(cx231xx_set_mode);
-
-int cx231xx_ep5_bulkout(struct cx231xx *dev, u8 *firmware, u16 size)
-{
- int errCode = 0;
- int actlen, ret = -ENOMEM;
- u32 *buffer;
-
- buffer = kzalloc(4096, GFP_KERNEL);
- if (buffer == NULL) {
- cx231xx_info("out of mem\n");
- return -ENOMEM;
- }
- memcpy(&buffer[0], firmware, 4096);
-
- ret = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 5),
- buffer, 4096, &actlen, 2000);
-
- if (ret)
- cx231xx_info("bulk message failed: %d (%d/%d)", ret,
- size, actlen);
- else {
- errCode = actlen != size ? -1 : 0;
- }
- kfree(buffer);
- return errCode;
-}
-
-/*****************************************************************
-* URB Streaming functions *
-******************************************************************/
-
-/*
- * IRQ callback, called by URB callback
- */
-static void cx231xx_isoc_irq_callback(struct urb *urb)
-{
- struct cx231xx_dmaqueue *dma_q = urb->context;
- struct cx231xx_video_mode *vmode =
- container_of(dma_q, struct cx231xx_video_mode, vidq);
- struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode);
- int i;
-
- switch (urb->status) {
- case 0: /* success */
- case -ETIMEDOUT: /* NAK */
- break;
- case -ECONNRESET: /* kill */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- default: /* error */
- cx231xx_isocdbg("urb completition error %d.\n", urb->status);
- break;
- }
-
- /* Copy data from URB */
- spin_lock(&dev->video_mode.slock);
- dev->video_mode.isoc_ctl.isoc_copy(dev, urb);
- spin_unlock(&dev->video_mode.slock);
-
- /* Reset urb buffers */
- for (i = 0; i < urb->number_of_packets; i++) {
- urb->iso_frame_desc[i].status = 0;
- urb->iso_frame_desc[i].actual_length = 0;
- }
-
- urb->status = usb_submit_urb(urb, GFP_ATOMIC);
- if (urb->status) {
- cx231xx_isocdbg("urb resubmit failed (error=%i)\n",
- urb->status);
- }
-}
-/*****************************************************************
-* URB Streaming functions *
-******************************************************************/
-
-/*
- * IRQ callback, called by URB callback
- */
-static void cx231xx_bulk_irq_callback(struct urb *urb)
-{
- struct cx231xx_dmaqueue *dma_q = urb->context;
- struct cx231xx_video_mode *vmode =
- container_of(dma_q, struct cx231xx_video_mode, vidq);
- struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode);
-
- switch (urb->status) {
- case 0: /* success */
- case -ETIMEDOUT: /* NAK */
- break;
- case -ECONNRESET: /* kill */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- default: /* error */
- cx231xx_isocdbg("urb completition error %d.\n", urb->status);
- break;
- }
-
- /* Copy data from URB */
- spin_lock(&dev->video_mode.slock);
- dev->video_mode.bulk_ctl.bulk_copy(dev, urb);
- spin_unlock(&dev->video_mode.slock);
-
- /* Reset urb buffers */
- urb->status = usb_submit_urb(urb, GFP_ATOMIC);
- if (urb->status) {
- cx231xx_isocdbg("urb resubmit failed (error=%i)\n",
- urb->status);
- }
-}
-/*
- * Stop and Deallocate URBs
- */
-void cx231xx_uninit_isoc(struct cx231xx *dev)
-{
- struct cx231xx_dmaqueue *dma_q = &dev->video_mode.vidq;
- struct urb *urb;
- int i;
-
- cx231xx_isocdbg("cx231xx: called cx231xx_uninit_isoc\n");
-
- dev->video_mode.isoc_ctl.nfields = -1;
- for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) {
- urb = dev->video_mode.isoc_ctl.urb[i];
- if (urb) {
- if (!irqs_disabled())
- usb_kill_urb(urb);
- else
- usb_unlink_urb(urb);
-
- if (dev->video_mode.isoc_ctl.transfer_buffer[i]) {
- usb_free_coherent(dev->udev,
- urb->transfer_buffer_length,
- dev->video_mode.isoc_ctl.
- transfer_buffer[i],
- urb->transfer_dma);
- }
- usb_free_urb(urb);
- dev->video_mode.isoc_ctl.urb[i] = NULL;
- }
- dev->video_mode.isoc_ctl.transfer_buffer[i] = NULL;
- }
-
- kfree(dev->video_mode.isoc_ctl.urb);
- kfree(dev->video_mode.isoc_ctl.transfer_buffer);
- kfree(dma_q->p_left_data);
-
- dev->video_mode.isoc_ctl.urb = NULL;
- dev->video_mode.isoc_ctl.transfer_buffer = NULL;
- dev->video_mode.isoc_ctl.num_bufs = 0;
- dma_q->p_left_data = NULL;
-
- if (dev->mode_tv == 0)
- cx231xx_capture_start(dev, 0, Raw_Video);
- else
- cx231xx_capture_start(dev, 0, TS1_serial_mode);
-
-
-}
-EXPORT_SYMBOL_GPL(cx231xx_uninit_isoc);
-
-/*
- * Stop and Deallocate URBs
- */
-void cx231xx_uninit_bulk(struct cx231xx *dev)
-{
- struct urb *urb;
- int i;
-
- cx231xx_isocdbg("cx231xx: called cx231xx_uninit_bulk\n");
-
- dev->video_mode.bulk_ctl.nfields = -1;
- for (i = 0; i < dev->video_mode.bulk_ctl.num_bufs; i++) {
- urb = dev->video_mode.bulk_ctl.urb[i];
- if (urb) {
- if (!irqs_disabled())
- usb_kill_urb(urb);
- else
- usb_unlink_urb(urb);
-
- if (dev->video_mode.bulk_ctl.transfer_buffer[i]) {
- usb_free_coherent(dev->udev,
- urb->transfer_buffer_length,
- dev->video_mode.isoc_ctl.
- transfer_buffer[i],
- urb->transfer_dma);
- }
- usb_free_urb(urb);
- dev->video_mode.bulk_ctl.urb[i] = NULL;
- }
- dev->video_mode.bulk_ctl.transfer_buffer[i] = NULL;
- }
-
- kfree(dev->video_mode.bulk_ctl.urb);
- kfree(dev->video_mode.bulk_ctl.transfer_buffer);
-
- dev->video_mode.bulk_ctl.urb = NULL;
- dev->video_mode.bulk_ctl.transfer_buffer = NULL;
- dev->video_mode.bulk_ctl.num_bufs = 0;
-
- if (dev->mode_tv == 0)
- cx231xx_capture_start(dev, 0, Raw_Video);
- else
- cx231xx_capture_start(dev, 0, TS1_serial_mode);
-
-
-}
-EXPORT_SYMBOL_GPL(cx231xx_uninit_bulk);
-
-/*
- * Allocate URBs and start IRQ
- */
-int cx231xx_init_isoc(struct cx231xx *dev, int max_packets,
- int num_bufs, int max_pkt_size,
- int (*isoc_copy) (struct cx231xx *dev, struct urb *urb))
-{
- struct cx231xx_dmaqueue *dma_q = &dev->video_mode.vidq;
- int i;
- int sb_size, pipe;
- struct urb *urb;
- int j, k;
- int rc;
-
- /* De-allocates all pending stuff */
- cx231xx_uninit_isoc(dev);
-
- dma_q->p_left_data = kzalloc(4096, GFP_KERNEL);
- if (dma_q->p_left_data == NULL) {
- cx231xx_info("out of mem\n");
- return -ENOMEM;
- }
-
-
-
- dev->video_mode.isoc_ctl.isoc_copy = isoc_copy;
- dev->video_mode.isoc_ctl.num_bufs = num_bufs;
- dma_q->pos = 0;
- dma_q->is_partial_line = 0;
- dma_q->last_sav = 0;
- dma_q->current_field = -1;
- dma_q->field1_done = 0;
- dma_q->lines_per_field = dev->height / 2;
- dma_q->bytes_left_in_line = dev->width << 1;
- dma_q->lines_completed = 0;
- dma_q->mpeg_buffer_done = 0;
- dma_q->left_data_count = 0;
- dma_q->mpeg_buffer_completed = 0;
- dma_q->add_ps_package_head = CX231XX_NEED_ADD_PS_PACKAGE_HEAD;
- dma_q->ps_head[0] = 0x00;
- dma_q->ps_head[1] = 0x00;
- dma_q->ps_head[2] = 0x01;
- dma_q->ps_head[3] = 0xBA;
- for (i = 0; i < 8; i++)
- dma_q->partial_buf[i] = 0;
-
- dev->video_mode.isoc_ctl.urb =
- kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
- if (!dev->video_mode.isoc_ctl.urb) {
- cx231xx_errdev("cannot alloc memory for usb buffers\n");
- return -ENOMEM;
- }
-
- dev->video_mode.isoc_ctl.transfer_buffer =
- kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
- if (!dev->video_mode.isoc_ctl.transfer_buffer) {
- cx231xx_errdev("cannot allocate memory for usbtransfer\n");
- kfree(dev->video_mode.isoc_ctl.urb);
- return -ENOMEM;
- }
-
- dev->video_mode.isoc_ctl.max_pkt_size = max_pkt_size;
- dev->video_mode.isoc_ctl.buf = NULL;
-
- sb_size = max_packets * dev->video_mode.isoc_ctl.max_pkt_size;
-
- if (dev->mode_tv == 1)
- dev->video_mode.end_point_addr = 0x81;
- else
- dev->video_mode.end_point_addr = 0x84;
-
-
- /* allocate urbs and transfer buffers */
- for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) {
- urb = usb_alloc_urb(max_packets, GFP_KERNEL);
- if (!urb) {
- cx231xx_err("cannot alloc isoc_ctl.urb %i\n", i);
- cx231xx_uninit_isoc(dev);
- return -ENOMEM;
- }
- dev->video_mode.isoc_ctl.urb[i] = urb;
-
- dev->video_mode.isoc_ctl.transfer_buffer[i] =
- usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL,
- &urb->transfer_dma);
- if (!dev->video_mode.isoc_ctl.transfer_buffer[i]) {
- cx231xx_err("unable to allocate %i bytes for transfer"
- " buffer %i%s\n",
- sb_size, i,
- in_interrupt() ? " while in int" : "");
- cx231xx_uninit_isoc(dev);
- return -ENOMEM;
- }
- memset(dev->video_mode.isoc_ctl.transfer_buffer[i], 0, sb_size);
-
- pipe =
- usb_rcvisocpipe(dev->udev, dev->video_mode.end_point_addr);
-
- usb_fill_int_urb(urb, dev->udev, pipe,
- dev->video_mode.isoc_ctl.transfer_buffer[i],
- sb_size, cx231xx_isoc_irq_callback, dma_q, 1);
-
- urb->number_of_packets = max_packets;
- urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
-
- k = 0;
- for (j = 0; j < max_packets; j++) {
- urb->iso_frame_desc[j].offset = k;
- urb->iso_frame_desc[j].length =
- dev->video_mode.isoc_ctl.max_pkt_size;
- k += dev->video_mode.isoc_ctl.max_pkt_size;
- }
- }
-
- init_waitqueue_head(&dma_q->wq);
-
- /* submit urbs and enables IRQ */
- for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) {
- rc = usb_submit_urb(dev->video_mode.isoc_ctl.urb[i],
- GFP_ATOMIC);
- if (rc) {
- cx231xx_err("submit of urb %i failed (error=%i)\n", i,
- rc);
- cx231xx_uninit_isoc(dev);
- return rc;
- }
- }
-
- if (dev->mode_tv == 0)
- cx231xx_capture_start(dev, 1, Raw_Video);
- else
- cx231xx_capture_start(dev, 1, TS1_serial_mode);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cx231xx_init_isoc);
-
-/*
- * Allocate URBs and start IRQ
- */
-int cx231xx_init_bulk(struct cx231xx *dev, int max_packets,
- int num_bufs, int max_pkt_size,
- int (*bulk_copy) (struct cx231xx *dev, struct urb *urb))
-{
- struct cx231xx_dmaqueue *dma_q = &dev->video_mode.vidq;
- int i;
- int sb_size, pipe;
- struct urb *urb;
- int rc;
-
- dev->video_input = dev->video_input > 2 ? 2 : dev->video_input;
-
- cx231xx_coredbg("Setting Video mux to %d\n", dev->video_input);
-
- video_mux(dev, dev->video_input);
-
- /* De-allocates all pending stuff */
- cx231xx_uninit_bulk(dev);
-
- dev->video_mode.bulk_ctl.bulk_copy = bulk_copy;
- dev->video_mode.bulk_ctl.num_bufs = num_bufs;
- dma_q->pos = 0;
- dma_q->is_partial_line = 0;
- dma_q->last_sav = 0;
- dma_q->current_field = -1;
- dma_q->field1_done = 0;
- dma_q->lines_per_field = dev->height / 2;
- dma_q->bytes_left_in_line = dev->width << 1;
- dma_q->lines_completed = 0;
- dma_q->mpeg_buffer_done = 0;
- dma_q->left_data_count = 0;
- dma_q->mpeg_buffer_completed = 0;
- dma_q->ps_head[0] = 0x00;
- dma_q->ps_head[1] = 0x00;
- dma_q->ps_head[2] = 0x01;
- dma_q->ps_head[3] = 0xBA;
- for (i = 0; i < 8; i++)
- dma_q->partial_buf[i] = 0;
-
- dev->video_mode.bulk_ctl.urb =
- kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
- if (!dev->video_mode.bulk_ctl.urb) {
- cx231xx_errdev("cannot alloc memory for usb buffers\n");
- return -ENOMEM;
- }
-
- dev->video_mode.bulk_ctl.transfer_buffer =
- kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
- if (!dev->video_mode.bulk_ctl.transfer_buffer) {
- cx231xx_errdev("cannot allocate memory for usbtransfer\n");
- kfree(dev->video_mode.bulk_ctl.urb);
- return -ENOMEM;
- }
-
- dev->video_mode.bulk_ctl.max_pkt_size = max_pkt_size;
- dev->video_mode.bulk_ctl.buf = NULL;
-
- sb_size = max_packets * dev->video_mode.bulk_ctl.max_pkt_size;
-
- if (dev->mode_tv == 1)
- dev->video_mode.end_point_addr = 0x81;
- else
- dev->video_mode.end_point_addr = 0x84;
-
-
- /* allocate urbs and transfer buffers */
- for (i = 0; i < dev->video_mode.bulk_ctl.num_bufs; i++) {
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- cx231xx_err("cannot alloc bulk_ctl.urb %i\n", i);
- cx231xx_uninit_bulk(dev);
- return -ENOMEM;
- }
- dev->video_mode.bulk_ctl.urb[i] = urb;
- urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
-
- dev->video_mode.bulk_ctl.transfer_buffer[i] =
- usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL,
- &urb->transfer_dma);
- if (!dev->video_mode.bulk_ctl.transfer_buffer[i]) {
- cx231xx_err("unable to allocate %i bytes for transfer"
- " buffer %i%s\n",
- sb_size, i,
- in_interrupt() ? " while in int" : "");
- cx231xx_uninit_bulk(dev);
- return -ENOMEM;
- }
- memset(dev->video_mode.bulk_ctl.transfer_buffer[i], 0, sb_size);
-
- pipe = usb_rcvbulkpipe(dev->udev,
- dev->video_mode.end_point_addr);
- usb_fill_bulk_urb(urb, dev->udev, pipe,
- dev->video_mode.bulk_ctl.transfer_buffer[i],
- sb_size, cx231xx_bulk_irq_callback, dma_q);
- }
-
- init_waitqueue_head(&dma_q->wq);
-
- /* submit urbs and enables IRQ */
- for (i = 0; i < dev->video_mode.bulk_ctl.num_bufs; i++) {
- rc = usb_submit_urb(dev->video_mode.bulk_ctl.urb[i],
- GFP_ATOMIC);
- if (rc) {
- cx231xx_err("submit of urb %i failed (error=%i)\n", i,
- rc);
- cx231xx_uninit_bulk(dev);
- return rc;
- }
- }
-
- if (dev->mode_tv == 0)
- cx231xx_capture_start(dev, 1, Raw_Video);
- else
- cx231xx_capture_start(dev, 1, TS1_serial_mode);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cx231xx_init_bulk);
-void cx231xx_stop_TS1(struct cx231xx *dev)
-{
- u8 val[4] = { 0, 0, 0, 0 };
-
- val[0] = 0x00;
- val[1] = 0x03;
- val[2] = 0x00;
- val[3] = 0x00;
- cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- TS_MODE_REG, val, 4);
-
- val[0] = 0x00;
- val[1] = 0x70;
- val[2] = 0x04;
- val[3] = 0x00;
- cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- TS1_CFG_REG, val, 4);
-}
-/* EXPORT_SYMBOL_GPL(cx231xx_stop_TS1); */
-void cx231xx_start_TS1(struct cx231xx *dev)
-{
- u8 val[4] = { 0, 0, 0, 0 };
-
- val[0] = 0x03;
- val[1] = 0x03;
- val[2] = 0x00;
- val[3] = 0x00;
- cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- TS_MODE_REG, val, 4);
-
- val[0] = 0x04;
- val[1] = 0xA3;
- val[2] = 0x3B;
- val[3] = 0x00;
- cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- TS1_CFG_REG, val, 4);
-}
-/* EXPORT_SYMBOL_GPL(cx231xx_start_TS1); */
-/*****************************************************************
-* Device Init/UnInit functions *
-******************************************************************/
-int cx231xx_dev_init(struct cx231xx *dev)
-{
- int errCode = 0;
-
- /* Initialize I2C bus */
-
- /* External Master 1 Bus */
- dev->i2c_bus[0].nr = 0;
- dev->i2c_bus[0].dev = dev;
- dev->i2c_bus[0].i2c_period = I2C_SPEED_100K; /* 100 KHz */
- dev->i2c_bus[0].i2c_nostop = 0;
- dev->i2c_bus[0].i2c_reserve = 0;
-
- /* External Master 2 Bus */
- dev->i2c_bus[1].nr = 1;
- dev->i2c_bus[1].dev = dev;
- dev->i2c_bus[1].i2c_period = I2C_SPEED_100K; /* 100 KHz */
- dev->i2c_bus[1].i2c_nostop = 0;
- dev->i2c_bus[1].i2c_reserve = 0;
-
- /* Internal Master 3 Bus */
- dev->i2c_bus[2].nr = 2;
- dev->i2c_bus[2].dev = dev;
- dev->i2c_bus[2].i2c_period = I2C_SPEED_100K; /* 100kHz */
- dev->i2c_bus[2].i2c_nostop = 0;
- dev->i2c_bus[2].i2c_reserve = 0;
-
- /* register I2C buses */
- cx231xx_i2c_register(&dev->i2c_bus[0]);
- cx231xx_i2c_register(&dev->i2c_bus[1]);
- cx231xx_i2c_register(&dev->i2c_bus[2]);
-
- /* init hardware */
- /* Note : with out calling set power mode function,
- afe can not be set up correctly */
- if (dev->board.external_av) {
- errCode = cx231xx_set_power_mode(dev,
- POLARIS_AVMODE_ENXTERNAL_AV);
- if (errCode < 0) {
- cx231xx_errdev
- ("%s: Failed to set Power - errCode [%d]!\n",
- __func__, errCode);
- return errCode;
- }
- } else {
- errCode = cx231xx_set_power_mode(dev,
- POLARIS_AVMODE_ANALOGT_TV);
- if (errCode < 0) {
- cx231xx_errdev
- ("%s: Failed to set Power - errCode [%d]!\n",
- __func__, errCode);
- return errCode;
- }
- }
-
- /* reset the Tuner, if it is a Xceive tuner */
- if ((dev->board.tuner_type == TUNER_XC5000) ||
- (dev->board.tuner_type == TUNER_XC2028))
- cx231xx_gpio_set(dev, dev->board.tuner_gpio);
-
- /* initialize Colibri block */
- errCode = cx231xx_afe_init_super_block(dev, 0x23c);
- if (errCode < 0) {
- cx231xx_errdev
- ("%s: cx231xx_afe init super block - errCode [%d]!\n",
- __func__, errCode);
- return errCode;
- }
- errCode = cx231xx_afe_init_channels(dev);
- if (errCode < 0) {
- cx231xx_errdev
- ("%s: cx231xx_afe init channels - errCode [%d]!\n",
- __func__, errCode);
- return errCode;
- }
-
- /* Set DIF in By pass mode */
- errCode = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
- if (errCode < 0) {
- cx231xx_errdev
- ("%s: cx231xx_dif set to By pass mode - errCode [%d]!\n",
- __func__, errCode);
- return errCode;
- }
-
- /* I2S block related functions */
- errCode = cx231xx_i2s_blk_initialize(dev);
- if (errCode < 0) {
- cx231xx_errdev
- ("%s: cx231xx_i2s block initialize - errCode [%d]!\n",
- __func__, errCode);
- return errCode;
- }
-
- /* init control pins */
- errCode = cx231xx_init_ctrl_pin_status(dev);
- if (errCode < 0) {
- cx231xx_errdev("%s: cx231xx_init ctrl pins - errCode [%d]!\n",
- __func__, errCode);
- return errCode;
- }
-
- /* set AGC mode to Analog */
- switch (dev->model) {
- case CX231XX_BOARD_CNXT_CARRAERA:
- case CX231XX_BOARD_CNXT_RDE_250:
- case CX231XX_BOARD_CNXT_SHELBY:
- case CX231XX_BOARD_CNXT_RDU_250:
- errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1);
- break;
- case CX231XX_BOARD_CNXT_RDE_253S:
- case CX231XX_BOARD_CNXT_RDU_253S:
- case CX231XX_BOARD_HAUPPAUGE_EXETER:
- case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
- case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL:
- case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC:
- errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0);
- break;
- default:
- break;
- }
- if (errCode < 0) {
- cx231xx_errdev
- ("%s: cx231xx_AGC mode to Analog - errCode [%d]!\n",
- __func__, errCode);
- return errCode;
- }
-
- /* set all alternate settings to zero initially */
- cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0);
- cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
- cx231xx_set_alt_setting(dev, INDEX_HANC, 0);
- if (dev->board.has_dvb)
- cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
-
- /* set the I2C master port to 3 on channel 1 */
- errCode = cx231xx_enable_i2c_port_3(dev, true);
-
- return errCode;
-}
-EXPORT_SYMBOL_GPL(cx231xx_dev_init);
-
-void cx231xx_dev_uninit(struct cx231xx *dev)
-{
- /* Un Initialize I2C bus */
- cx231xx_i2c_unregister(&dev->i2c_bus[2]);
- cx231xx_i2c_unregister(&dev->i2c_bus[1]);
- cx231xx_i2c_unregister(&dev->i2c_bus[0]);
-}
-EXPORT_SYMBOL_GPL(cx231xx_dev_uninit);
-
-/*****************************************************************
-* G P I O related functions *
-******************************************************************/
-int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val,
- u8 len, u8 request, u8 direction)
-{
- int status = 0;
- struct VENDOR_REQUEST_IN ven_req;
-
- /* Set wValue */
- ven_req.wValue = (u16) (gpio_bit >> 16 & 0xffff);
-
- /* set request */
- if (!request) {
- if (direction)
- ven_req.bRequest = VRT_GET_GPIO; /* 0x8 gpio */
- else
- ven_req.bRequest = VRT_SET_GPIO; /* 0x9 gpio */
- } else {
- if (direction)
- ven_req.bRequest = VRT_GET_GPIE; /* 0xa gpie */
- else
- ven_req.bRequest = VRT_SET_GPIE; /* 0xb gpie */
- }
-
- /* set index value */
- ven_req.wIndex = (u16) (gpio_bit & 0xffff);
-
- /* set wLength value */
- ven_req.wLength = len;
-
- /* set bData value */
- ven_req.bData = 0;
-
- /* set the buffer for read / write */
- ven_req.pBuff = gpio_val;
-
- /* set the direction */
- if (direction) {
- ven_req.direction = USB_DIR_IN;
- memset(ven_req.pBuff, 0x00, ven_req.wLength);
- } else
- ven_req.direction = USB_DIR_OUT;
-
-
- /* call common vendor command request */
- status = cx231xx_send_vendor_cmd(dev, &ven_req);
- if (status < 0) {
- cx231xx_info
- ("UsbInterface::sendCommand, failed with status -%d\n",
- status);
- }
-
- return status;
-}
-EXPORT_SYMBOL_GPL(cx231xx_send_gpio_cmd);
-
-/*****************************************************************
- * C O N T R O L - Register R E A D / W R I T E functions *
- *****************************************************************/
-int cx231xx_mode_register(struct cx231xx *dev, u16 address, u32 mode)
-{
- u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
- u32 tmp = 0;
- int status = 0;
-
- status =
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, address, value, 4);
- if (status < 0)
- return status;
-
- tmp = *((u32 *) value);
- tmp |= mode;
-
- value[0] = (u8) tmp;
- value[1] = (u8) (tmp >> 8);
- value[2] = (u8) (tmp >> 16);
- value[3] = (u8) (tmp >> 24);
-
- status =
- cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, address, value, 4);
-
- return status;
-}
-
-/*****************************************************************
- * I 2 C Internal C O N T R O L functions *
- *****************************************************************/
-int cx231xx_read_i2c_master(struct cx231xx *dev, u8 dev_addr, u16 saddr,
- u8 saddr_len, u32 *data, u8 data_len, int master)
-{
- int status = 0;
- struct cx231xx_i2c_xfer_data req_data;
- u8 value[64] = "0";
-
- if (saddr_len == 0)
- saddr = 0;
- else if (saddr_len == 1)
- saddr &= 0xff;
-
- /* prepare xfer_data struct */
- req_data.dev_addr = dev_addr >> 1;
- req_data.direction = I2C_M_RD;
- req_data.saddr_len = saddr_len;
- req_data.saddr_dat = saddr;
- req_data.buf_size = data_len;
- req_data.p_buffer = (u8 *) value;
-
- /* usb send command */
- if (master == 0)
- status = dev->cx231xx_send_usb_command(&dev->i2c_bus[0],
- &req_data);
- else if (master == 1)
- status = dev->cx231xx_send_usb_command(&dev->i2c_bus[1],
- &req_data);
- else if (master == 2)
- status = dev->cx231xx_send_usb_command(&dev->i2c_bus[2],
- &req_data);
-
- if (status >= 0) {
- /* Copy the data read back to main buffer */
- if (data_len == 1)
- *data = value[0];
- else if (data_len == 4)
- *data =
- value[0] | value[1] << 8 | value[2] << 16 | value[3]
- << 24;
- else if (data_len > 4)
- *data = value[saddr];
- }
-
- return status;
-}
-
-int cx231xx_write_i2c_master(struct cx231xx *dev, u8 dev_addr, u16 saddr,
- u8 saddr_len, u32 data, u8 data_len, int master)
-{
- int status = 0;
- u8 value[4] = { 0, 0, 0, 0 };
- struct cx231xx_i2c_xfer_data req_data;
-
- value[0] = (u8) data;
- value[1] = (u8) (data >> 8);
- value[2] = (u8) (data >> 16);
- value[3] = (u8) (data >> 24);
-
- if (saddr_len == 0)
- saddr = 0;
- else if (saddr_len == 1)
- saddr &= 0xff;
-
- /* prepare xfer_data struct */
- req_data.dev_addr = dev_addr >> 1;
- req_data.direction = 0;
- req_data.saddr_len = saddr_len;
- req_data.saddr_dat = saddr;
- req_data.buf_size = data_len;
- req_data.p_buffer = value;
-
- /* usb send command */
- if (master == 0)
- status = dev->cx231xx_send_usb_command(&dev->i2c_bus[0],
- &req_data);
- else if (master == 1)
- status = dev->cx231xx_send_usb_command(&dev->i2c_bus[1],
- &req_data);
- else if (master == 2)
- status = dev->cx231xx_send_usb_command(&dev->i2c_bus[2],
- &req_data);
-
- return status;
-}
-
-int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr,
- u8 saddr_len, u32 *data, u8 data_len)
-{
- int status = 0;
- struct cx231xx_i2c_xfer_data req_data;
- u8 value[4] = { 0, 0, 0, 0 };
-
- if (saddr_len == 0)
- saddr = 0;
- else if (saddr_len == 1)
- saddr &= 0xff;
-
- /* prepare xfer_data struct */
- req_data.dev_addr = dev_addr >> 1;
- req_data.direction = I2C_M_RD;
- req_data.saddr_len = saddr_len;
- req_data.saddr_dat = saddr;
- req_data.buf_size = data_len;
- req_data.p_buffer = (u8 *) value;
-
- /* usb send command */
- status = dev->cx231xx_send_usb_command(&dev->i2c_bus[0], &req_data);
-
- if (status >= 0) {
- /* Copy the data read back to main buffer */
- if (data_len == 1)
- *data = value[0];
- else
- *data =
- value[0] | value[1] << 8 | value[2] << 16 | value[3]
- << 24;
- }
-
- return status;
-}
-
-int cx231xx_write_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr,
- u8 saddr_len, u32 data, u8 data_len)
-{
- int status = 0;
- u8 value[4] = { 0, 0, 0, 0 };
- struct cx231xx_i2c_xfer_data req_data;
-
- value[0] = (u8) data;
- value[1] = (u8) (data >> 8);
- value[2] = (u8) (data >> 16);
- value[3] = (u8) (data >> 24);
-
- if (saddr_len == 0)
- saddr = 0;
- else if (saddr_len == 1)
- saddr &= 0xff;
-
- /* prepare xfer_data struct */
- req_data.dev_addr = dev_addr >> 1;
- req_data.direction = 0;
- req_data.saddr_len = saddr_len;
- req_data.saddr_dat = saddr;
- req_data.buf_size = data_len;
- req_data.p_buffer = value;
-
- /* usb send command */
- status = dev->cx231xx_send_usb_command(&dev->i2c_bus[0], &req_data);
-
- return status;
-}
-
-int cx231xx_reg_mask_write(struct cx231xx *dev, u8 dev_addr, u8 size,
- u16 register_address, u8 bit_start, u8 bit_end,
- u32 value)
-{
- int status = 0;
- u32 tmp;
- u32 mask = 0;
- int i;
-
- if (bit_start > (size - 1) || bit_end > (size - 1))
- return -1;
-
- if (size == 8) {
- status =
- cx231xx_read_i2c_data(dev, dev_addr, register_address, 2,
- &tmp, 1);
- } else {
- status =
- cx231xx_read_i2c_data(dev, dev_addr, register_address, 2,
- &tmp, 4);
- }
-
- if (status < 0)
- return status;
-
- mask = 1 << bit_end;
- for (i = bit_end; i > bit_start && i > 0; i--)
- mask = mask + (1 << (i - 1));
-
- value <<= bit_start;
-
- if (size == 8) {
- tmp &= ~mask;
- tmp |= value;
- tmp &= 0xff;
- status =
- cx231xx_write_i2c_data(dev, dev_addr, register_address, 2,
- tmp, 1);
- } else {
- tmp &= ~mask;
- tmp |= value;
- status =
- cx231xx_write_i2c_data(dev, dev_addr, register_address, 2,
- tmp, 4);
- }
-
- return status;
-}
-
-int cx231xx_read_modify_write_i2c_dword(struct cx231xx *dev, u8 dev_addr,
- u16 saddr, u32 mask, u32 value)
-{
- u32 temp;
- int status = 0;
-
- status = cx231xx_read_i2c_data(dev, dev_addr, saddr, 2, &temp, 4);
-
- if (status < 0)
- return status;
-
- temp &= ~mask;
- temp |= value;
-
- status = cx231xx_write_i2c_data(dev, dev_addr, saddr, 2, temp, 4);
-
- return status;
-}
-
-u32 cx231xx_set_field(u32 field_mask, u32 data)
-{
- u32 temp;
-
- for (temp = field_mask; (temp & 1) == 0; temp >>= 1)
- data <<= 1;
-
- return data;
-}
diff --git a/drivers/media/video/cx231xx/cx231xx-dif.h b/drivers/media/video/cx231xx/cx231xx-dif.h
deleted file mode 100644
index 2b63c2f6d3b..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-dif.h
+++ /dev/null
@@ -1,3178 +0,0 @@
-/*
- * cx231xx-dif.h - driver for Conexant Cx23100/101/102 USB video capture devices
- *
- * Copyright {C} 2009 <Bill.Liu@conexant.com>
- *
- * This program is free software, you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program, if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _CX231XX_DIF_H
-#define _CX231XX_DIF_H
-
-#include "cx231xx-reg.h"
-
-struct dif_settings{
- u32 if_freq;
- u32 register_address;
- u32 value;
-};
-
-static struct dif_settings Dif_set_array[] = {
-
-/*case 3000000:*/
-/* BEGIN - DIF BPF register values from 30_quant.dat*/
-{3000000, DIF_BPF_COEFF01, 0x00000002},
-{3000000, DIF_BPF_COEFF23, 0x00080012},
-{3000000, DIF_BPF_COEFF45, 0x001e0024},
-{3000000, DIF_BPF_COEFF67, 0x001bfff8},
-{3000000, DIF_BPF_COEFF89, 0xffb4ff50},
-{3000000, DIF_BPF_COEFF1011, 0xfed8fe68},
-{3000000, DIF_BPF_COEFF1213, 0xfe24fe34},
-{3000000, DIF_BPF_COEFF1415, 0xfebaffc7},
-{3000000, DIF_BPF_COEFF1617, 0x014d031f},
-{3000000, DIF_BPF_COEFF1819, 0x04f0065d},
-{3000000, DIF_BPF_COEFF2021, 0x07010688},
-{3000000, DIF_BPF_COEFF2223, 0x04c901d6},
-{3000000, DIF_BPF_COEFF2425, 0xfe00f9d3},
-{3000000, DIF_BPF_COEFF2627, 0xf600f342},
-{3000000, DIF_BPF_COEFF2829, 0xf235f337},
-{3000000, DIF_BPF_COEFF3031, 0xf64efb22},
-{3000000, DIF_BPF_COEFF3233, 0x0105070f},
-{3000000, DIF_BPF_COEFF3435, 0x0c460fce},
-{3000000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 30_quant.dat*/
-
-
-/*case 3100000:*/
-/* BEGIN - DIF BPF register values from 31_quant.dat*/
-{3100000, DIF_BPF_COEFF01, 0x00000001},
-{3100000, DIF_BPF_COEFF23, 0x00070012},
-{3100000, DIF_BPF_COEFF45, 0x00220032},
-{3100000, DIF_BPF_COEFF67, 0x00370026},
-{3100000, DIF_BPF_COEFF89, 0xfff0ff91},
-{3100000, DIF_BPF_COEFF1011, 0xff0efe7c},
-{3100000, DIF_BPF_COEFF1213, 0xfe01fdcc},
-{3100000, DIF_BPF_COEFF1415, 0xfe0afedb},
-{3100000, DIF_BPF_COEFF1617, 0x00440224},
-{3100000, DIF_BPF_COEFF1819, 0x0434060c},
-{3100000, DIF_BPF_COEFF2021, 0x0738074e},
-{3100000, DIF_BPF_COEFF2223, 0x06090361},
-{3100000, DIF_BPF_COEFF2425, 0xff99fb39},
-{3100000, DIF_BPF_COEFF2627, 0xf6fef3b6},
-{3100000, DIF_BPF_COEFF2829, 0xf21af2a5},
-{3100000, DIF_BPF_COEFF3031, 0xf573fa33},
-{3100000, DIF_BPF_COEFF3233, 0x0034067d},
-{3100000, DIF_BPF_COEFF3435, 0x0bfb0fb9},
-{3100000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 31_quant.dat*/
-
-
-/*case 3200000:*/
-/* BEGIN - DIF BPF register values from 32_quant.dat*/
-{3200000, DIF_BPF_COEFF01, 0x00000000},
-{3200000, DIF_BPF_COEFF23, 0x0004000e},
-{3200000, DIF_BPF_COEFF45, 0x00200038},
-{3200000, DIF_BPF_COEFF67, 0x004c004f},
-{3200000, DIF_BPF_COEFF89, 0x002fffdf},
-{3200000, DIF_BPF_COEFF1011, 0xff5cfeb6},
-{3200000, DIF_BPF_COEFF1213, 0xfe0dfd92},
-{3200000, DIF_BPF_COEFF1415, 0xfd7ffe03},
-{3200000, DIF_BPF_COEFF1617, 0xff36010a},
-{3200000, DIF_BPF_COEFF1819, 0x03410575},
-{3200000, DIF_BPF_COEFF2021, 0x072607d2},
-{3200000, DIF_BPF_COEFF2223, 0x071804d5},
-{3200000, DIF_BPF_COEFF2425, 0x0134fcb7},
-{3200000, DIF_BPF_COEFF2627, 0xf81ff451},
-{3200000, DIF_BPF_COEFF2829, 0xf223f22e},
-{3200000, DIF_BPF_COEFF3031, 0xf4a7f94b},
-{3200000, DIF_BPF_COEFF3233, 0xff6405e8},
-{3200000, DIF_BPF_COEFF3435, 0x0bae0fa4},
-{3200000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 32_quant.dat*/
-
-
-/*case 3300000:*/
-/* BEGIN - DIF BPF register values from 33_quant.dat*/
-{3300000, DIF_BPF_COEFF01, 0x0000ffff},
-{3300000, DIF_BPF_COEFF23, 0x00000008},
-{3300000, DIF_BPF_COEFF45, 0x001a0036},
-{3300000, DIF_BPF_COEFF67, 0x0056006d},
-{3300000, DIF_BPF_COEFF89, 0x00670030},
-{3300000, DIF_BPF_COEFF1011, 0xffbdff10},
-{3300000, DIF_BPF_COEFF1213, 0xfe46fd8d},
-{3300000, DIF_BPF_COEFF1415, 0xfd25fd4f},
-{3300000, DIF_BPF_COEFF1617, 0xfe35ffe0},
-{3300000, DIF_BPF_COEFF1819, 0x0224049f},
-{3300000, DIF_BPF_COEFF2021, 0x06c9080e},
-{3300000, DIF_BPF_COEFF2223, 0x07ef0627},
-{3300000, DIF_BPF_COEFF2425, 0x02c9fe45},
-{3300000, DIF_BPF_COEFF2627, 0xf961f513},
-{3300000, DIF_BPF_COEFF2829, 0xf250f1d2},
-{3300000, DIF_BPF_COEFF3031, 0xf3ecf869},
-{3300000, DIF_BPF_COEFF3233, 0xfe930552},
-{3300000, DIF_BPF_COEFF3435, 0x0b5f0f8f},
-{3300000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 33_quant.dat*/
-
-
-/*case 3400000:*/
-/* BEGIN - DIF BPF register values from 34_quant.dat*/
-{3400000, DIF_BPF_COEFF01, 0xfffffffe},
-{3400000, DIF_BPF_COEFF23, 0xfffd0001},
-{3400000, DIF_BPF_COEFF45, 0x000f002c},
-{3400000, DIF_BPF_COEFF67, 0x0054007d},
-{3400000, DIF_BPF_COEFF89, 0x0093007c},
-{3400000, DIF_BPF_COEFF1011, 0x0024ff82},
-{3400000, DIF_BPF_COEFF1213, 0xfea6fdbb},
-{3400000, DIF_BPF_COEFF1415, 0xfd03fcca},
-{3400000, DIF_BPF_COEFF1617, 0xfd51feb9},
-{3400000, DIF_BPF_COEFF1819, 0x00eb0392},
-{3400000, DIF_BPF_COEFF2021, 0x06270802},
-{3400000, DIF_BPF_COEFF2223, 0x08880750},
-{3400000, DIF_BPF_COEFF2425, 0x044dffdb},
-{3400000, DIF_BPF_COEFF2627, 0xfabdf5f8},
-{3400000, DIF_BPF_COEFF2829, 0xf2a0f193},
-{3400000, DIF_BPF_COEFF3031, 0xf342f78f},
-{3400000, DIF_BPF_COEFF3233, 0xfdc404b9},
-{3400000, DIF_BPF_COEFF3435, 0x0b0e0f78},
-{3400000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 34_quant.dat*/
-
-
-/*case 3500000:*/
-/* BEGIN - DIF BPF register values from 35_quant.dat*/
-{3500000, DIF_BPF_COEFF01, 0xfffffffd},
-{3500000, DIF_BPF_COEFF23, 0xfffafff9},
-{3500000, DIF_BPF_COEFF45, 0x0002001b},
-{3500000, DIF_BPF_COEFF67, 0x0046007d},
-{3500000, DIF_BPF_COEFF89, 0x00ad00ba},
-{3500000, DIF_BPF_COEFF1011, 0x00870000},
-{3500000, DIF_BPF_COEFF1213, 0xff26fe1a},
-{3500000, DIF_BPF_COEFF1415, 0xfd1bfc7e},
-{3500000, DIF_BPF_COEFF1617, 0xfc99fda4},
-{3500000, DIF_BPF_COEFF1819, 0xffa5025c},
-{3500000, DIF_BPF_COEFF2021, 0x054507ad},
-{3500000, DIF_BPF_COEFF2223, 0x08dd0847},
-{3500000, DIF_BPF_COEFF2425, 0x05b80172},
-{3500000, DIF_BPF_COEFF2627, 0xfc2ef6ff},
-{3500000, DIF_BPF_COEFF2829, 0xf313f170},
-{3500000, DIF_BPF_COEFF3031, 0xf2abf6bd},
-{3500000, DIF_BPF_COEFF3233, 0xfcf6041f},
-{3500000, DIF_BPF_COEFF3435, 0x0abc0f61},
-{3500000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 35_quant.dat*/
-
-
-/*case 3600000:*/
-/* BEGIN - DIF BPF register values from 36_quant.dat*/
-{3600000, DIF_BPF_COEFF01, 0xfffffffd},
-{3600000, DIF_BPF_COEFF23, 0xfff8fff3},
-{3600000, DIF_BPF_COEFF45, 0xfff50006},
-{3600000, DIF_BPF_COEFF67, 0x002f006c},
-{3600000, DIF_BPF_COEFF89, 0x00b200e3},
-{3600000, DIF_BPF_COEFF1011, 0x00dc007e},
-{3600000, DIF_BPF_COEFF1213, 0xffb9fea0},
-{3600000, DIF_BPF_COEFF1415, 0xfd6bfc71},
-{3600000, DIF_BPF_COEFF1617, 0xfc17fcb1},
-{3600000, DIF_BPF_COEFF1819, 0xfe65010b},
-{3600000, DIF_BPF_COEFF2021, 0x042d0713},
-{3600000, DIF_BPF_COEFF2223, 0x08ec0906},
-{3600000, DIF_BPF_COEFF2425, 0x07020302},
-{3600000, DIF_BPF_COEFF2627, 0xfdaff823},
-{3600000, DIF_BPF_COEFF2829, 0xf3a7f16a},
-{3600000, DIF_BPF_COEFF3031, 0xf228f5f5},
-{3600000, DIF_BPF_COEFF3233, 0xfc2a0384},
-{3600000, DIF_BPF_COEFF3435, 0x0a670f4a},
-{3600000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 36_quant.dat*/
-
-
-/*case 3700000:*/
-/* BEGIN - DIF BPF register values from 37_quant.dat*/
-{3700000, DIF_BPF_COEFF01, 0x0000fffd},
-{3700000, DIF_BPF_COEFF23, 0xfff7ffef},
-{3700000, DIF_BPF_COEFF45, 0xffe9fff1},
-{3700000, DIF_BPF_COEFF67, 0x0010004d},
-{3700000, DIF_BPF_COEFF89, 0x00a100f2},
-{3700000, DIF_BPF_COEFF1011, 0x011a00f0},
-{3700000, DIF_BPF_COEFF1213, 0x0053ff44},
-{3700000, DIF_BPF_COEFF1415, 0xfdedfca2},
-{3700000, DIF_BPF_COEFF1617, 0xfbd3fbef},
-{3700000, DIF_BPF_COEFF1819, 0xfd39ffae},
-{3700000, DIF_BPF_COEFF2021, 0x02ea0638},
-{3700000, DIF_BPF_COEFF2223, 0x08b50987},
-{3700000, DIF_BPF_COEFF2425, 0x08230483},
-{3700000, DIF_BPF_COEFF2627, 0xff39f960},
-{3700000, DIF_BPF_COEFF2829, 0xf45bf180},
-{3700000, DIF_BPF_COEFF3031, 0xf1b8f537},
-{3700000, DIF_BPF_COEFF3233, 0xfb6102e7},
-{3700000, DIF_BPF_COEFF3435, 0x0a110f32},
-{3700000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 37_quant.dat*/
-
-
-/*case 3800000:*/
-/* BEGIN - DIF BPF register values from 38_quant.dat*/
-{3800000, DIF_BPF_COEFF01, 0x0000fffe},
-{3800000, DIF_BPF_COEFF23, 0xfff9ffee},
-{3800000, DIF_BPF_COEFF45, 0xffe1ffdd},
-{3800000, DIF_BPF_COEFF67, 0xfff00024},
-{3800000, DIF_BPF_COEFF89, 0x007c00e5},
-{3800000, DIF_BPF_COEFF1011, 0x013a014a},
-{3800000, DIF_BPF_COEFF1213, 0x00e6fff8},
-{3800000, DIF_BPF_COEFF1415, 0xfe98fd0f},
-{3800000, DIF_BPF_COEFF1617, 0xfbd3fb67},
-{3800000, DIF_BPF_COEFF1819, 0xfc32fe54},
-{3800000, DIF_BPF_COEFF2021, 0x01880525},
-{3800000, DIF_BPF_COEFF2223, 0x083909c7},
-{3800000, DIF_BPF_COEFF2425, 0x091505ee},
-{3800000, DIF_BPF_COEFF2627, 0x00c7fab3},
-{3800000, DIF_BPF_COEFF2829, 0xf52df1b4},
-{3800000, DIF_BPF_COEFF3031, 0xf15df484},
-{3800000, DIF_BPF_COEFF3233, 0xfa9b0249},
-{3800000, DIF_BPF_COEFF3435, 0x09ba0f19},
-{3800000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 38_quant.dat*/
-
-
-/*case 3900000:*/
-/* BEGIN - DIF BPF register values from 39_quant.dat*/
-{3900000, DIF_BPF_COEFF01, 0x00000000},
-{3900000, DIF_BPF_COEFF23, 0xfffbfff0},
-{3900000, DIF_BPF_COEFF45, 0xffdeffcf},
-{3900000, DIF_BPF_COEFF67, 0xffd1fff6},
-{3900000, DIF_BPF_COEFF89, 0x004800be},
-{3900000, DIF_BPF_COEFF1011, 0x01390184},
-{3900000, DIF_BPF_COEFF1213, 0x016300ac},
-{3900000, DIF_BPF_COEFF1415, 0xff5efdb1},
-{3900000, DIF_BPF_COEFF1617, 0xfc17fb23},
-{3900000, DIF_BPF_COEFF1819, 0xfb5cfd0d},
-{3900000, DIF_BPF_COEFF2021, 0x001703e4},
-{3900000, DIF_BPF_COEFF2223, 0x077b09c4},
-{3900000, DIF_BPF_COEFF2425, 0x09d2073c},
-{3900000, DIF_BPF_COEFF2627, 0x0251fc18},
-{3900000, DIF_BPF_COEFF2829, 0xf61cf203},
-{3900000, DIF_BPF_COEFF3031, 0xf118f3dc},
-{3900000, DIF_BPF_COEFF3233, 0xf9d801aa},
-{3900000, DIF_BPF_COEFF3435, 0x09600eff},
-{3900000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 39_quant.dat*/
-
-
-/*case 4000000:*/
-/* BEGIN - DIF BPF register values from 40_quant.dat*/
-{4000000, DIF_BPF_COEFF01, 0x00000001},
-{4000000, DIF_BPF_COEFF23, 0xfffefff4},
-{4000000, DIF_BPF_COEFF45, 0xffe1ffc8},
-{4000000, DIF_BPF_COEFF67, 0xffbaffca},
-{4000000, DIF_BPF_COEFF89, 0x000b0082},
-{4000000, DIF_BPF_COEFF1011, 0x01170198},
-{4000000, DIF_BPF_COEFF1213, 0x01c10152},
-{4000000, DIF_BPF_COEFF1415, 0x0030fe7b},
-{4000000, DIF_BPF_COEFF1617, 0xfc99fb24},
-{4000000, DIF_BPF_COEFF1819, 0xfac3fbe9},
-{4000000, DIF_BPF_COEFF2021, 0xfea5027f},
-{4000000, DIF_BPF_COEFF2223, 0x0683097f},
-{4000000, DIF_BPF_COEFF2425, 0x0a560867},
-{4000000, DIF_BPF_COEFF2627, 0x03d2fd89},
-{4000000, DIF_BPF_COEFF2829, 0xf723f26f},
-{4000000, DIF_BPF_COEFF3031, 0xf0e8f341},
-{4000000, DIF_BPF_COEFF3233, 0xf919010a},
-{4000000, DIF_BPF_COEFF3435, 0x09060ee5},
-{4000000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 40_quant.dat*/
-
-
-/*case 4100000:*/
-/* BEGIN - DIF BPF register values from 41_quant.dat*/
-{4100000, DIF_BPF_COEFF01, 0x00010002},
-{4100000, DIF_BPF_COEFF23, 0x0002fffb},
-{4100000, DIF_BPF_COEFF45, 0xffe8ffca},
-{4100000, DIF_BPF_COEFF67, 0xffacffa4},
-{4100000, DIF_BPF_COEFF89, 0xffcd0036},
-{4100000, DIF_BPF_COEFF1011, 0x00d70184},
-{4100000, DIF_BPF_COEFF1213, 0x01f601dc},
-{4100000, DIF_BPF_COEFF1415, 0x00ffff60},
-{4100000, DIF_BPF_COEFF1617, 0xfd51fb6d},
-{4100000, DIF_BPF_COEFF1819, 0xfa6efaf5},
-{4100000, DIF_BPF_COEFF2021, 0xfd410103},
-{4100000, DIF_BPF_COEFF2223, 0x055708f9},
-{4100000, DIF_BPF_COEFF2425, 0x0a9e0969},
-{4100000, DIF_BPF_COEFF2627, 0x0543ff02},
-{4100000, DIF_BPF_COEFF2829, 0xf842f2f5},
-{4100000, DIF_BPF_COEFF3031, 0xf0cef2b2},
-{4100000, DIF_BPF_COEFF3233, 0xf85e006b},
-{4100000, DIF_BPF_COEFF3435, 0x08aa0ecb},
-{4100000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 41_quant.dat*/
-
-
-/*case 4200000:*/
-/* BEGIN - DIF BPF register values from 42_quant.dat*/
-{4200000, DIF_BPF_COEFF01, 0x00010003},
-{4200000, DIF_BPF_COEFF23, 0x00050003},
-{4200000, DIF_BPF_COEFF45, 0xfff3ffd3},
-{4200000, DIF_BPF_COEFF67, 0xffaaff8b},
-{4200000, DIF_BPF_COEFF89, 0xff95ffe5},
-{4200000, DIF_BPF_COEFF1011, 0x0080014a},
-{4200000, DIF_BPF_COEFF1213, 0x01fe023f},
-{4200000, DIF_BPF_COEFF1415, 0x01ba0050},
-{4200000, DIF_BPF_COEFF1617, 0xfe35fbf8},
-{4200000, DIF_BPF_COEFF1819, 0xfa62fa3b},
-{4200000, DIF_BPF_COEFF2021, 0xfbf9ff7e},
-{4200000, DIF_BPF_COEFF2223, 0x04010836},
-{4200000, DIF_BPF_COEFF2425, 0x0aa90a3d},
-{4200000, DIF_BPF_COEFF2627, 0x069f007f},
-{4200000, DIF_BPF_COEFF2829, 0xf975f395},
-{4200000, DIF_BPF_COEFF3031, 0xf0cbf231},
-{4200000, DIF_BPF_COEFF3233, 0xf7a9ffcb},
-{4200000, DIF_BPF_COEFF3435, 0x084c0eaf},
-{4200000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 42_quant.dat*/
-
-
-/*case 4300000:*/
-/* BEGIN - DIF BPF register values from 43_quant.dat*/
-{4300000, DIF_BPF_COEFF01, 0x00010003},
-{4300000, DIF_BPF_COEFF23, 0x0008000a},
-{4300000, DIF_BPF_COEFF45, 0x0000ffe4},
-{4300000, DIF_BPF_COEFF67, 0xffb4ff81},
-{4300000, DIF_BPF_COEFF89, 0xff6aff96},
-{4300000, DIF_BPF_COEFF1011, 0x001c00f0},
-{4300000, DIF_BPF_COEFF1213, 0x01d70271},
-{4300000, DIF_BPF_COEFF1415, 0x0254013b},
-{4300000, DIF_BPF_COEFF1617, 0xff36fcbd},
-{4300000, DIF_BPF_COEFF1819, 0xfa9ff9c5},
-{4300000, DIF_BPF_COEFF2021, 0xfadbfdfe},
-{4300000, DIF_BPF_COEFF2223, 0x028c073b},
-{4300000, DIF_BPF_COEFF2425, 0x0a750adf},
-{4300000, DIF_BPF_COEFF2627, 0x07e101fa},
-{4300000, DIF_BPF_COEFF2829, 0xfab8f44e},
-{4300000, DIF_BPF_COEFF3031, 0xf0ddf1be},
-{4300000, DIF_BPF_COEFF3233, 0xf6f9ff2b},
-{4300000, DIF_BPF_COEFF3435, 0x07ed0e94},
-{4300000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 43_quant.dat*/
-
-
-/*case 4400000:*/
-/* BEGIN - DIF BPF register values from 44_quant.dat*/
-{4400000, DIF_BPF_COEFF01, 0x00000003},
-{4400000, DIF_BPF_COEFF23, 0x0009000f},
-{4400000, DIF_BPF_COEFF45, 0x000efff8},
-{4400000, DIF_BPF_COEFF67, 0xffc9ff87},
-{4400000, DIF_BPF_COEFF89, 0xff52ff54},
-{4400000, DIF_BPF_COEFF1011, 0xffb5007e},
-{4400000, DIF_BPF_COEFF1213, 0x01860270},
-{4400000, DIF_BPF_COEFF1415, 0x02c00210},
-{4400000, DIF_BPF_COEFF1617, 0x0044fdb2},
-{4400000, DIF_BPF_COEFF1819, 0xfb22f997},
-{4400000, DIF_BPF_COEFF2021, 0xf9f2fc90},
-{4400000, DIF_BPF_COEFF2223, 0x0102060f},
-{4400000, DIF_BPF_COEFF2425, 0x0a050b4c},
-{4400000, DIF_BPF_COEFF2627, 0x0902036e},
-{4400000, DIF_BPF_COEFF2829, 0xfc0af51e},
-{4400000, DIF_BPF_COEFF3031, 0xf106f15a},
-{4400000, DIF_BPF_COEFF3233, 0xf64efe8b},
-{4400000, DIF_BPF_COEFF3435, 0x078d0e77},
-{4400000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 44_quant.dat*/
-
-
-/*case 4500000:*/
-/* BEGIN - DIF BPF register values from 45_quant.dat*/
-{4500000, DIF_BPF_COEFF01, 0x00000002},
-{4500000, DIF_BPF_COEFF23, 0x00080012},
-{4500000, DIF_BPF_COEFF45, 0x0019000e},
-{4500000, DIF_BPF_COEFF67, 0xffe5ff9e},
-{4500000, DIF_BPF_COEFF89, 0xff4fff25},
-{4500000, DIF_BPF_COEFF1011, 0xff560000},
-{4500000, DIF_BPF_COEFF1213, 0x0112023b},
-{4500000, DIF_BPF_COEFF1415, 0x02f702c0},
-{4500000, DIF_BPF_COEFF1617, 0x014dfec8},
-{4500000, DIF_BPF_COEFF1819, 0xfbe5f9b3},
-{4500000, DIF_BPF_COEFF2021, 0xf947fb41},
-{4500000, DIF_BPF_COEFF2223, 0xff7004b9},
-{4500000, DIF_BPF_COEFF2425, 0x095a0b81},
-{4500000, DIF_BPF_COEFF2627, 0x0a0004d8},
-{4500000, DIF_BPF_COEFF2829, 0xfd65f603},
-{4500000, DIF_BPF_COEFF3031, 0xf144f104},
-{4500000, DIF_BPF_COEFF3233, 0xf5aafdec},
-{4500000, DIF_BPF_COEFF3435, 0x072b0e5a},
-{4500000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 45_quant.dat*/
-
-
-/*case 4600000:*/
-/* BEGIN - DIF BPF register values from 46_quant.dat*/
-{4600000, DIF_BPF_COEFF01, 0x00000001},
-{4600000, DIF_BPF_COEFF23, 0x00060012},
-{4600000, DIF_BPF_COEFF45, 0x00200022},
-{4600000, DIF_BPF_COEFF67, 0x0005ffc1},
-{4600000, DIF_BPF_COEFF89, 0xff61ff10},
-{4600000, DIF_BPF_COEFF1011, 0xff09ff82},
-{4600000, DIF_BPF_COEFF1213, 0x008601d7},
-{4600000, DIF_BPF_COEFF1415, 0x02f50340},
-{4600000, DIF_BPF_COEFF1617, 0x0241fff0},
-{4600000, DIF_BPF_COEFF1819, 0xfcddfa19},
-{4600000, DIF_BPF_COEFF2021, 0xf8e2fa1e},
-{4600000, DIF_BPF_COEFF2223, 0xfde30343},
-{4600000, DIF_BPF_COEFF2425, 0x08790b7f},
-{4600000, DIF_BPF_COEFF2627, 0x0ad50631},
-{4600000, DIF_BPF_COEFF2829, 0xfec7f6fc},
-{4600000, DIF_BPF_COEFF3031, 0xf198f0bd},
-{4600000, DIF_BPF_COEFF3233, 0xf50dfd4e},
-{4600000, DIF_BPF_COEFF3435, 0x06c90e3d},
-{4600000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 46_quant.dat*/
-
-
-/*case 4700000:*/
-/* BEGIN - DIF BPF register values from 47_quant.dat*/
-{4700000, DIF_BPF_COEFF01, 0x0000ffff},
-{4700000, DIF_BPF_COEFF23, 0x0003000f},
-{4700000, DIF_BPF_COEFF45, 0x00220030},
-{4700000, DIF_BPF_COEFF67, 0x0025ffed},
-{4700000, DIF_BPF_COEFF89, 0xff87ff15},
-{4700000, DIF_BPF_COEFF1011, 0xfed6ff10},
-{4700000, DIF_BPF_COEFF1213, 0xffed014c},
-{4700000, DIF_BPF_COEFF1415, 0x02b90386},
-{4700000, DIF_BPF_COEFF1617, 0x03110119},
-{4700000, DIF_BPF_COEFF1819, 0xfdfefac4},
-{4700000, DIF_BPF_COEFF2021, 0xf8c6f92f},
-{4700000, DIF_BPF_COEFF2223, 0xfc6701b7},
-{4700000, DIF_BPF_COEFF2425, 0x07670b44},
-{4700000, DIF_BPF_COEFF2627, 0x0b7e0776},
-{4700000, DIF_BPF_COEFF2829, 0x002df807},
-{4700000, DIF_BPF_COEFF3031, 0xf200f086},
-{4700000, DIF_BPF_COEFF3233, 0xf477fcb1},
-{4700000, DIF_BPF_COEFF3435, 0x06650e1e},
-{4700000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 47_quant.dat*/
-
-
-/*case 4800000:*/
-/* BEGIN - DIF BPF register values from 48_quant.dat*/
-{4800000, DIF_BPF_COEFF01, 0xfffffffe},
-{4800000, DIF_BPF_COEFF23, 0xffff0009},
-{4800000, DIF_BPF_COEFF45, 0x001e0038},
-{4800000, DIF_BPF_COEFF67, 0x003f001b},
-{4800000, DIF_BPF_COEFF89, 0xffbcff36},
-{4800000, DIF_BPF_COEFF1011, 0xfec2feb6},
-{4800000, DIF_BPF_COEFF1213, 0xff5600a5},
-{4800000, DIF_BPF_COEFF1415, 0x0248038d},
-{4800000, DIF_BPF_COEFF1617, 0x03b00232},
-{4800000, DIF_BPF_COEFF1819, 0xff39fbab},
-{4800000, DIF_BPF_COEFF2021, 0xf8f4f87f},
-{4800000, DIF_BPF_COEFF2223, 0xfb060020},
-{4800000, DIF_BPF_COEFF2425, 0x062a0ad2},
-{4800000, DIF_BPF_COEFF2627, 0x0bf908a3},
-{4800000, DIF_BPF_COEFF2829, 0x0192f922},
-{4800000, DIF_BPF_COEFF3031, 0xf27df05e},
-{4800000, DIF_BPF_COEFF3233, 0xf3e8fc14},
-{4800000, DIF_BPF_COEFF3435, 0x06000e00},
-{4800000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 48_quant.dat*/
-
-
-/*case 4900000:*/
-/* BEGIN - DIF BPF register values from 49_quant.dat*/
-{4900000, DIF_BPF_COEFF01, 0xfffffffd},
-{4900000, DIF_BPF_COEFF23, 0xfffc0002},
-{4900000, DIF_BPF_COEFF45, 0x00160037},
-{4900000, DIF_BPF_COEFF67, 0x00510046},
-{4900000, DIF_BPF_COEFF89, 0xfff9ff6d},
-{4900000, DIF_BPF_COEFF1011, 0xfed0fe7c},
-{4900000, DIF_BPF_COEFF1213, 0xfecefff0},
-{4900000, DIF_BPF_COEFF1415, 0x01aa0356},
-{4900000, DIF_BPF_COEFF1617, 0x0413032b},
-{4900000, DIF_BPF_COEFF1819, 0x007ffcc5},
-{4900000, DIF_BPF_COEFF2021, 0xf96cf812},
-{4900000, DIF_BPF_COEFF2223, 0xf9cefe87},
-{4900000, DIF_BPF_COEFF2425, 0x04c90a2c},
-{4900000, DIF_BPF_COEFF2627, 0x0c4309b4},
-{4900000, DIF_BPF_COEFF2829, 0x02f3fa4a},
-{4900000, DIF_BPF_COEFF3031, 0xf30ef046},
-{4900000, DIF_BPF_COEFF3233, 0xf361fb7a},
-{4900000, DIF_BPF_COEFF3435, 0x059b0de0},
-{4900000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 49_quant.dat*/
-
-
-/*case 5000000:*/
-/* BEGIN - DIF BPF register values from 50_quant.dat*/
-{5000000, DIF_BPF_COEFF01, 0xfffffffd},
-{5000000, DIF_BPF_COEFF23, 0xfff9fffa},
-{5000000, DIF_BPF_COEFF45, 0x000a002d},
-{5000000, DIF_BPF_COEFF67, 0x00570067},
-{5000000, DIF_BPF_COEFF89, 0x0037ffb5},
-{5000000, DIF_BPF_COEFF1011, 0xfefffe68},
-{5000000, DIF_BPF_COEFF1213, 0xfe62ff3d},
-{5000000, DIF_BPF_COEFF1415, 0x00ec02e3},
-{5000000, DIF_BPF_COEFF1617, 0x043503f6},
-{5000000, DIF_BPF_COEFF1819, 0x01befe05},
-{5000000, DIF_BPF_COEFF2021, 0xfa27f7ee},
-{5000000, DIF_BPF_COEFF2223, 0xf8c6fcf8},
-{5000000, DIF_BPF_COEFF2425, 0x034c0954},
-{5000000, DIF_BPF_COEFF2627, 0x0c5c0aa4},
-{5000000, DIF_BPF_COEFF2829, 0x044cfb7e},
-{5000000, DIF_BPF_COEFF3031, 0xf3b1f03f},
-{5000000, DIF_BPF_COEFF3233, 0xf2e2fae1},
-{5000000, DIF_BPF_COEFF3435, 0x05340dc0},
-{5000000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 50_quant.dat*/
-
-
-/*case 5100000:*/
-/* BEGIN - DIF BPF register values from 51_quant.dat*/
-{5100000, DIF_BPF_COEFF01, 0x0000fffd},
-{5100000, DIF_BPF_COEFF23, 0xfff8fff4},
-{5100000, DIF_BPF_COEFF45, 0xfffd001e},
-{5100000, DIF_BPF_COEFF67, 0x0051007b},
-{5100000, DIF_BPF_COEFF89, 0x006e0006},
-{5100000, DIF_BPF_COEFF1011, 0xff48fe7c},
-{5100000, DIF_BPF_COEFF1213, 0xfe1bfe9a},
-{5100000, DIF_BPF_COEFF1415, 0x001d023e},
-{5100000, DIF_BPF_COEFF1617, 0x04130488},
-{5100000, DIF_BPF_COEFF1819, 0x02e6ff5b},
-{5100000, DIF_BPF_COEFF2021, 0xfb1ef812},
-{5100000, DIF_BPF_COEFF2223, 0xf7f7fb7f},
-{5100000, DIF_BPF_COEFF2425, 0x01bc084e},
-{5100000, DIF_BPF_COEFF2627, 0x0c430b72},
-{5100000, DIF_BPF_COEFF2829, 0x059afcba},
-{5100000, DIF_BPF_COEFF3031, 0xf467f046},
-{5100000, DIF_BPF_COEFF3233, 0xf26cfa4a},
-{5100000, DIF_BPF_COEFF3435, 0x04cd0da0},
-{5100000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 51_quant.dat*/
-
-
-/*case 5200000:*/
-/* BEGIN - DIF BPF register values from 52_quant.dat*/
-{5200000, DIF_BPF_COEFF01, 0x0000fffe},
-{5200000, DIF_BPF_COEFF23, 0xfff8ffef},
-{5200000, DIF_BPF_COEFF45, 0xfff00009},
-{5200000, DIF_BPF_COEFF67, 0x003f007f},
-{5200000, DIF_BPF_COEFF89, 0x00980056},
-{5200000, DIF_BPF_COEFF1011, 0xffa5feb6},
-{5200000, DIF_BPF_COEFF1213, 0xfe00fe15},
-{5200000, DIF_BPF_COEFF1415, 0xff4b0170},
-{5200000, DIF_BPF_COEFF1617, 0x03b004d7},
-{5200000, DIF_BPF_COEFF1819, 0x03e800b9},
-{5200000, DIF_BPF_COEFF2021, 0xfc48f87f},
-{5200000, DIF_BPF_COEFF2223, 0xf768fa23},
-{5200000, DIF_BPF_COEFF2425, 0x0022071f},
-{5200000, DIF_BPF_COEFF2627, 0x0bf90c1b},
-{5200000, DIF_BPF_COEFF2829, 0x06dafdfd},
-{5200000, DIF_BPF_COEFF3031, 0xf52df05e},
-{5200000, DIF_BPF_COEFF3233, 0xf1fef9b5},
-{5200000, DIF_BPF_COEFF3435, 0x04640d7f},
-{5200000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 52_quant.dat*/
-
-
-/*case 5300000:*/
-/* BEGIN - DIF BPF register values from 53_quant.dat*/
-{5300000, DIF_BPF_COEFF01, 0x0000ffff},
-{5300000, DIF_BPF_COEFF23, 0xfff9ffee},
-{5300000, DIF_BPF_COEFF45, 0xffe6fff3},
-{5300000, DIF_BPF_COEFF67, 0x00250072},
-{5300000, DIF_BPF_COEFF89, 0x00af009c},
-{5300000, DIF_BPF_COEFF1011, 0x000cff10},
-{5300000, DIF_BPF_COEFF1213, 0xfe13fdb8},
-{5300000, DIF_BPF_COEFF1415, 0xfe870089},
-{5300000, DIF_BPF_COEFF1617, 0x031104e1},
-{5300000, DIF_BPF_COEFF1819, 0x04b8020f},
-{5300000, DIF_BPF_COEFF2021, 0xfd98f92f},
-{5300000, DIF_BPF_COEFF2223, 0xf71df8f0},
-{5300000, DIF_BPF_COEFF2425, 0xfe8805ce},
-{5300000, DIF_BPF_COEFF2627, 0x0b7e0c9c},
-{5300000, DIF_BPF_COEFF2829, 0x0808ff44},
-{5300000, DIF_BPF_COEFF3031, 0xf603f086},
-{5300000, DIF_BPF_COEFF3233, 0xf19af922},
-{5300000, DIF_BPF_COEFF3435, 0x03fb0d5e},
-{5300000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 53_quant.dat*/
-
-
-/*case 5400000:*/
-/* BEGIN - DIF BPF register values from 54_quant.dat*/
-{5400000, DIF_BPF_COEFF01, 0x00000001},
-{5400000, DIF_BPF_COEFF23, 0xfffcffef},
-{5400000, DIF_BPF_COEFF45, 0xffe0ffe0},
-{5400000, DIF_BPF_COEFF67, 0x00050056},
-{5400000, DIF_BPF_COEFF89, 0x00b000d1},
-{5400000, DIF_BPF_COEFF1011, 0x0071ff82},
-{5400000, DIF_BPF_COEFF1213, 0xfe53fd8c},
-{5400000, DIF_BPF_COEFF1415, 0xfddfff99},
-{5400000, DIF_BPF_COEFF1617, 0x024104a3},
-{5400000, DIF_BPF_COEFF1819, 0x054a034d},
-{5400000, DIF_BPF_COEFF2021, 0xff01fa1e},
-{5400000, DIF_BPF_COEFF2223, 0xf717f7ed},
-{5400000, DIF_BPF_COEFF2425, 0xfcf50461},
-{5400000, DIF_BPF_COEFF2627, 0x0ad50cf4},
-{5400000, DIF_BPF_COEFF2829, 0x0921008d},
-{5400000, DIF_BPF_COEFF3031, 0xf6e7f0bd},
-{5400000, DIF_BPF_COEFF3233, 0xf13ff891},
-{5400000, DIF_BPF_COEFF3435, 0x03920d3b},
-{5400000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 54_quant.dat*/
-
-
-/*case 5500000:*/
-/* BEGIN - DIF BPF register values from 55_quant.dat*/
-{5500000, DIF_BPF_COEFF01, 0x00010002},
-{5500000, DIF_BPF_COEFF23, 0xfffffff3},
-{5500000, DIF_BPF_COEFF45, 0xffdeffd1},
-{5500000, DIF_BPF_COEFF67, 0xffe5002f},
-{5500000, DIF_BPF_COEFF89, 0x009c00ed},
-{5500000, DIF_BPF_COEFF1011, 0x00cb0000},
-{5500000, DIF_BPF_COEFF1213, 0xfebafd94},
-{5500000, DIF_BPF_COEFF1415, 0xfd61feb0},
-{5500000, DIF_BPF_COEFF1617, 0x014d0422},
-{5500000, DIF_BPF_COEFF1819, 0x05970464},
-{5500000, DIF_BPF_COEFF2021, 0x0074fb41},
-{5500000, DIF_BPF_COEFF2223, 0xf759f721},
-{5500000, DIF_BPF_COEFF2425, 0xfb7502de},
-{5500000, DIF_BPF_COEFF2627, 0x0a000d21},
-{5500000, DIF_BPF_COEFF2829, 0x0a2201d4},
-{5500000, DIF_BPF_COEFF3031, 0xf7d9f104},
-{5500000, DIF_BPF_COEFF3233, 0xf0edf804},
-{5500000, DIF_BPF_COEFF3435, 0x03280d19},
-{5500000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 55_quant.dat*/
-
-
-/*case 5600000:*/
-/* BEGIN - DIF BPF register values from 56_quant.dat*/
-{5600000, DIF_BPF_COEFF01, 0x00010003},
-{5600000, DIF_BPF_COEFF23, 0x0003fffa},
-{5600000, DIF_BPF_COEFF45, 0xffe3ffc9},
-{5600000, DIF_BPF_COEFF67, 0xffc90002},
-{5600000, DIF_BPF_COEFF89, 0x007500ef},
-{5600000, DIF_BPF_COEFF1011, 0x010e007e},
-{5600000, DIF_BPF_COEFF1213, 0xff3dfdcf},
-{5600000, DIF_BPF_COEFF1415, 0xfd16fddd},
-{5600000, DIF_BPF_COEFF1617, 0x00440365},
-{5600000, DIF_BPF_COEFF1819, 0x059b0548},
-{5600000, DIF_BPF_COEFF2021, 0x01e3fc90},
-{5600000, DIF_BPF_COEFF2223, 0xf7dff691},
-{5600000, DIF_BPF_COEFF2425, 0xfa0f014d},
-{5600000, DIF_BPF_COEFF2627, 0x09020d23},
-{5600000, DIF_BPF_COEFF2829, 0x0b0a0318},
-{5600000, DIF_BPF_COEFF3031, 0xf8d7f15a},
-{5600000, DIF_BPF_COEFF3233, 0xf0a5f779},
-{5600000, DIF_BPF_COEFF3435, 0x02bd0cf6},
-{5600000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 56_quant.dat*/
-
-
-/*case 5700000:*/
-/* BEGIN - DIF BPF register values from 57_quant.dat*/
-{5700000, DIF_BPF_COEFF01, 0x00010003},
-{5700000, DIF_BPF_COEFF23, 0x00060001},
-{5700000, DIF_BPF_COEFF45, 0xffecffc9},
-{5700000, DIF_BPF_COEFF67, 0xffb4ffd4},
-{5700000, DIF_BPF_COEFF89, 0x004000d5},
-{5700000, DIF_BPF_COEFF1011, 0x013600f0},
-{5700000, DIF_BPF_COEFF1213, 0xffd3fe39},
-{5700000, DIF_BPF_COEFF1415, 0xfd04fd31},
-{5700000, DIF_BPF_COEFF1617, 0xff360277},
-{5700000, DIF_BPF_COEFF1819, 0x055605ef},
-{5700000, DIF_BPF_COEFF2021, 0x033efdfe},
-{5700000, DIF_BPF_COEFF2223, 0xf8a5f642},
-{5700000, DIF_BPF_COEFF2425, 0xf8cbffb6},
-{5700000, DIF_BPF_COEFF2627, 0x07e10cfb},
-{5700000, DIF_BPF_COEFF2829, 0x0bd50456},
-{5700000, DIF_BPF_COEFF3031, 0xf9dff1be},
-{5700000, DIF_BPF_COEFF3233, 0xf067f6f2},
-{5700000, DIF_BPF_COEFF3435, 0x02520cd2},
-{5700000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 57_quant.dat*/
-
-
-/*case 5800000:*/
-/* BEGIN - DIF BPF register values from 58_quant.dat*/
-{5800000, DIF_BPF_COEFF01, 0x00000003},
-{5800000, DIF_BPF_COEFF23, 0x00080009},
-{5800000, DIF_BPF_COEFF45, 0xfff8ffd2},
-{5800000, DIF_BPF_COEFF67, 0xffaaffac},
-{5800000, DIF_BPF_COEFF89, 0x000200a3},
-{5800000, DIF_BPF_COEFF1011, 0x013c014a},
-{5800000, DIF_BPF_COEFF1213, 0x006dfec9},
-{5800000, DIF_BPF_COEFF1415, 0xfd2bfcb7},
-{5800000, DIF_BPF_COEFF1617, 0xfe350165},
-{5800000, DIF_BPF_COEFF1819, 0x04cb0651},
-{5800000, DIF_BPF_COEFF2021, 0x0477ff7e},
-{5800000, DIF_BPF_COEFF2223, 0xf9a5f635},
-{5800000, DIF_BPF_COEFF2425, 0xf7b1fe20},
-{5800000, DIF_BPF_COEFF2627, 0x069f0ca8},
-{5800000, DIF_BPF_COEFF2829, 0x0c81058b},
-{5800000, DIF_BPF_COEFF3031, 0xfaf0f231},
-{5800000, DIF_BPF_COEFF3233, 0xf033f66d},
-{5800000, DIF_BPF_COEFF3435, 0x01e60cae},
-{5800000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 58_quant.dat*/
-
-
-/*case 5900000:*/
-/* BEGIN - DIF BPF register values from 59_quant.dat*/
-{5900000, DIF_BPF_COEFF01, 0x00000002},
-{5900000, DIF_BPF_COEFF23, 0x0009000e},
-{5900000, DIF_BPF_COEFF45, 0x0005ffe1},
-{5900000, DIF_BPF_COEFF67, 0xffacff90},
-{5900000, DIF_BPF_COEFF89, 0xffc5005f},
-{5900000, DIF_BPF_COEFF1011, 0x01210184},
-{5900000, DIF_BPF_COEFF1213, 0x00fcff72},
-{5900000, DIF_BPF_COEFF1415, 0xfd8afc77},
-{5900000, DIF_BPF_COEFF1617, 0xfd51003f},
-{5900000, DIF_BPF_COEFF1819, 0x04020669},
-{5900000, DIF_BPF_COEFF2021, 0x05830103},
-{5900000, DIF_BPF_COEFF2223, 0xfad7f66b},
-{5900000, DIF_BPF_COEFF2425, 0xf6c8fc93},
-{5900000, DIF_BPF_COEFF2627, 0x05430c2b},
-{5900000, DIF_BPF_COEFF2829, 0x0d0d06b5},
-{5900000, DIF_BPF_COEFF3031, 0xfc08f2b2},
-{5900000, DIF_BPF_COEFF3233, 0xf00af5ec},
-{5900000, DIF_BPF_COEFF3435, 0x017b0c89},
-{5900000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 59_quant.dat*/
-
-
-/*case 6000000:*/
-/* BEGIN - DIF BPF register values from 60_quant.dat*/
-{6000000, DIF_BPF_COEFF01, 0x00000001},
-{6000000, DIF_BPF_COEFF23, 0x00070012},
-{6000000, DIF_BPF_COEFF45, 0x0012fff5},
-{6000000, DIF_BPF_COEFF67, 0xffbaff82},
-{6000000, DIF_BPF_COEFF89, 0xff8e000f},
-{6000000, DIF_BPF_COEFF1011, 0x00e80198},
-{6000000, DIF_BPF_COEFF1213, 0x01750028},
-{6000000, DIF_BPF_COEFF1415, 0xfe18fc75},
-{6000000, DIF_BPF_COEFF1617, 0xfc99ff15},
-{6000000, DIF_BPF_COEFF1819, 0x03050636},
-{6000000, DIF_BPF_COEFF2021, 0x0656027f},
-{6000000, DIF_BPF_COEFF2223, 0xfc32f6e2},
-{6000000, DIF_BPF_COEFF2425, 0xf614fb17},
-{6000000, DIF_BPF_COEFF2627, 0x03d20b87},
-{6000000, DIF_BPF_COEFF2829, 0x0d7707d2},
-{6000000, DIF_BPF_COEFF3031, 0xfd26f341},
-{6000000, DIF_BPF_COEFF3233, 0xefeaf56f},
-{6000000, DIF_BPF_COEFF3435, 0x010f0c64},
-{6000000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 60_quant.dat*/
-
-
-/*case 6100000:*/
-/* BEGIN - DIF BPF register values from 61_quant.dat*/
-{6100000, DIF_BPF_COEFF01, 0xffff0000},
-{6100000, DIF_BPF_COEFF23, 0x00050012},
-{6100000, DIF_BPF_COEFF45, 0x001c000b},
-{6100000, DIF_BPF_COEFF67, 0xffd1ff84},
-{6100000, DIF_BPF_COEFF89, 0xff66ffbe},
-{6100000, DIF_BPF_COEFF1011, 0x00960184},
-{6100000, DIF_BPF_COEFF1213, 0x01cd00da},
-{6100000, DIF_BPF_COEFF1415, 0xfeccfcb2},
-{6100000, DIF_BPF_COEFF1617, 0xfc17fdf9},
-{6100000, DIF_BPF_COEFF1819, 0x01e005bc},
-{6100000, DIF_BPF_COEFF2021, 0x06e703e4},
-{6100000, DIF_BPF_COEFF2223, 0xfdabf798},
-{6100000, DIF_BPF_COEFF2425, 0xf599f9b3},
-{6100000, DIF_BPF_COEFF2627, 0x02510abd},
-{6100000, DIF_BPF_COEFF2829, 0x0dbf08df},
-{6100000, DIF_BPF_COEFF3031, 0xfe48f3dc},
-{6100000, DIF_BPF_COEFF3233, 0xefd5f4f6},
-{6100000, DIF_BPF_COEFF3435, 0x00a20c3e},
-{6100000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 61_quant.dat*/
-
-
-/*case 6200000:*/
-/* BEGIN - DIF BPF register values from 62_quant.dat*/
-{6200000, DIF_BPF_COEFF01, 0xfffffffe},
-{6200000, DIF_BPF_COEFF23, 0x0002000f},
-{6200000, DIF_BPF_COEFF45, 0x0021001f},
-{6200000, DIF_BPF_COEFF67, 0xfff0ff97},
-{6200000, DIF_BPF_COEFF89, 0xff50ff74},
-{6200000, DIF_BPF_COEFF1011, 0x0034014a},
-{6200000, DIF_BPF_COEFF1213, 0x01fa0179},
-{6200000, DIF_BPF_COEFF1415, 0xff97fd2a},
-{6200000, DIF_BPF_COEFF1617, 0xfbd3fcfa},
-{6200000, DIF_BPF_COEFF1819, 0x00a304fe},
-{6200000, DIF_BPF_COEFF2021, 0x07310525},
-{6200000, DIF_BPF_COEFF2223, 0xff37f886},
-{6200000, DIF_BPF_COEFF2425, 0xf55cf86e},
-{6200000, DIF_BPF_COEFF2627, 0x00c709d0},
-{6200000, DIF_BPF_COEFF2829, 0x0de209db},
-{6200000, DIF_BPF_COEFF3031, 0xff6df484},
-{6200000, DIF_BPF_COEFF3233, 0xefcbf481},
-{6200000, DIF_BPF_COEFF3435, 0x00360c18},
-{6200000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 62_quant.dat*/
-
-
-/*case 6300000:*/
-/* BEGIN - DIF BPF register values from 63_quant.dat*/
-{6300000, DIF_BPF_COEFF01, 0xfffffffd},
-{6300000, DIF_BPF_COEFF23, 0xfffe000a},
-{6300000, DIF_BPF_COEFF45, 0x0021002f},
-{6300000, DIF_BPF_COEFF67, 0x0010ffb8},
-{6300000, DIF_BPF_COEFF89, 0xff50ff3b},
-{6300000, DIF_BPF_COEFF1011, 0xffcc00f0},
-{6300000, DIF_BPF_COEFF1213, 0x01fa01fa},
-{6300000, DIF_BPF_COEFF1415, 0x0069fdd4},
-{6300000, DIF_BPF_COEFF1617, 0xfbd3fc26},
-{6300000, DIF_BPF_COEFF1819, 0xff5d0407},
-{6300000, DIF_BPF_COEFF2021, 0x07310638},
-{6300000, DIF_BPF_COEFF2223, 0x00c9f9a8},
-{6300000, DIF_BPF_COEFF2425, 0xf55cf74e},
-{6300000, DIF_BPF_COEFF2627, 0xff3908c3},
-{6300000, DIF_BPF_COEFF2829, 0x0de20ac3},
-{6300000, DIF_BPF_COEFF3031, 0x0093f537},
-{6300000, DIF_BPF_COEFF3233, 0xefcbf410},
-{6300000, DIF_BPF_COEFF3435, 0xffca0bf2},
-{6300000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 63_quant.dat*/
-
-
-/*case 6400000:*/
-/* BEGIN - DIF BPF register values from 64_quant.dat*/
-{6400000, DIF_BPF_COEFF01, 0xfffffffd},
-{6400000, DIF_BPF_COEFF23, 0xfffb0003},
-{6400000, DIF_BPF_COEFF45, 0x001c0037},
-{6400000, DIF_BPF_COEFF67, 0x002fffe2},
-{6400000, DIF_BPF_COEFF89, 0xff66ff17},
-{6400000, DIF_BPF_COEFF1011, 0xff6a007e},
-{6400000, DIF_BPF_COEFF1213, 0x01cd0251},
-{6400000, DIF_BPF_COEFF1415, 0x0134fea5},
-{6400000, DIF_BPF_COEFF1617, 0xfc17fb8b},
-{6400000, DIF_BPF_COEFF1819, 0xfe2002e0},
-{6400000, DIF_BPF_COEFF2021, 0x06e70713},
-{6400000, DIF_BPF_COEFF2223, 0x0255faf5},
-{6400000, DIF_BPF_COEFF2425, 0xf599f658},
-{6400000, DIF_BPF_COEFF2627, 0xfdaf0799},
-{6400000, DIF_BPF_COEFF2829, 0x0dbf0b96},
-{6400000, DIF_BPF_COEFF3031, 0x01b8f5f5},
-{6400000, DIF_BPF_COEFF3233, 0xefd5f3a3},
-{6400000, DIF_BPF_COEFF3435, 0xff5e0bca},
-{6400000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 64_quant.dat*/
-
-
-/*case 6500000:*/
-/* BEGIN - DIF BPF register values from 65_quant.dat*/
-{6500000, DIF_BPF_COEFF01, 0x0000fffd},
-{6500000, DIF_BPF_COEFF23, 0xfff9fffb},
-{6500000, DIF_BPF_COEFF45, 0x00120037},
-{6500000, DIF_BPF_COEFF67, 0x00460010},
-{6500000, DIF_BPF_COEFF89, 0xff8eff0f},
-{6500000, DIF_BPF_COEFF1011, 0xff180000},
-{6500000, DIF_BPF_COEFF1213, 0x01750276},
-{6500000, DIF_BPF_COEFF1415, 0x01e8ff8d},
-{6500000, DIF_BPF_COEFF1617, 0xfc99fb31},
-{6500000, DIF_BPF_COEFF1819, 0xfcfb0198},
-{6500000, DIF_BPF_COEFF2021, 0x065607ad},
-{6500000, DIF_BPF_COEFF2223, 0x03cefc64},
-{6500000, DIF_BPF_COEFF2425, 0xf614f592},
-{6500000, DIF_BPF_COEFF2627, 0xfc2e0656},
-{6500000, DIF_BPF_COEFF2829, 0x0d770c52},
-{6500000, DIF_BPF_COEFF3031, 0x02daf6bd},
-{6500000, DIF_BPF_COEFF3233, 0xefeaf33b},
-{6500000, DIF_BPF_COEFF3435, 0xfef10ba3},
-{6500000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 65_quant.dat*/
-
-
-/*case 6600000:*/
-/* BEGIN - DIF BPF register values from 66_quant.dat*/
-{6600000, DIF_BPF_COEFF01, 0x0000fffe},
-{6600000, DIF_BPF_COEFF23, 0xfff7fff5},
-{6600000, DIF_BPF_COEFF45, 0x0005002f},
-{6600000, DIF_BPF_COEFF67, 0x0054003c},
-{6600000, DIF_BPF_COEFF89, 0xffc5ff22},
-{6600000, DIF_BPF_COEFF1011, 0xfedfff82},
-{6600000, DIF_BPF_COEFF1213, 0x00fc0267},
-{6600000, DIF_BPF_COEFF1415, 0x0276007e},
-{6600000, DIF_BPF_COEFF1617, 0xfd51fb1c},
-{6600000, DIF_BPF_COEFF1819, 0xfbfe003e},
-{6600000, DIF_BPF_COEFF2021, 0x05830802},
-{6600000, DIF_BPF_COEFF2223, 0x0529fdec},
-{6600000, DIF_BPF_COEFF2425, 0xf6c8f4fe},
-{6600000, DIF_BPF_COEFF2627, 0xfabd04ff},
-{6600000, DIF_BPF_COEFF2829, 0x0d0d0cf6},
-{6600000, DIF_BPF_COEFF3031, 0x03f8f78f},
-{6600000, DIF_BPF_COEFF3233, 0xf00af2d7},
-{6600000, DIF_BPF_COEFF3435, 0xfe850b7b},
-{6600000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 66_quant.dat*/
-
-
-/*case 6700000:*/
-/* BEGIN - DIF BPF register values from 67_quant.dat*/
-{6700000, DIF_BPF_COEFF01, 0x0000ffff},
-{6700000, DIF_BPF_COEFF23, 0xfff8fff0},
-{6700000, DIF_BPF_COEFF45, 0xfff80020},
-{6700000, DIF_BPF_COEFF67, 0x00560060},
-{6700000, DIF_BPF_COEFF89, 0x0002ff4e},
-{6700000, DIF_BPF_COEFF1011, 0xfec4ff10},
-{6700000, DIF_BPF_COEFF1213, 0x006d0225},
-{6700000, DIF_BPF_COEFF1415, 0x02d50166},
-{6700000, DIF_BPF_COEFF1617, 0xfe35fb4e},
-{6700000, DIF_BPF_COEFF1819, 0xfb35fee1},
-{6700000, DIF_BPF_COEFF2021, 0x0477080e},
-{6700000, DIF_BPF_COEFF2223, 0x065bff82},
-{6700000, DIF_BPF_COEFF2425, 0xf7b1f4a0},
-{6700000, DIF_BPF_COEFF2627, 0xf9610397},
-{6700000, DIF_BPF_COEFF2829, 0x0c810d80},
-{6700000, DIF_BPF_COEFF3031, 0x0510f869},
-{6700000, DIF_BPF_COEFF3233, 0xf033f278},
-{6700000, DIF_BPF_COEFF3435, 0xfe1a0b52},
-{6700000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 67_quant.dat*/
-
-
-/*case 6800000:*/
-/* BEGIN - DIF BPF register values from 68_quant.dat*/
-{6800000, DIF_BPF_COEFF01, 0x00010000},
-{6800000, DIF_BPF_COEFF23, 0xfffaffee},
-{6800000, DIF_BPF_COEFF45, 0xffec000c},
-{6800000, DIF_BPF_COEFF67, 0x004c0078},
-{6800000, DIF_BPF_COEFF89, 0x0040ff8e},
-{6800000, DIF_BPF_COEFF1011, 0xfecafeb6},
-{6800000, DIF_BPF_COEFF1213, 0xffd301b6},
-{6800000, DIF_BPF_COEFF1415, 0x02fc0235},
-{6800000, DIF_BPF_COEFF1617, 0xff36fbc5},
-{6800000, DIF_BPF_COEFF1819, 0xfaaafd90},
-{6800000, DIF_BPF_COEFF2021, 0x033e07d2},
-{6800000, DIF_BPF_COEFF2223, 0x075b011b},
-{6800000, DIF_BPF_COEFF2425, 0xf8cbf47a},
-{6800000, DIF_BPF_COEFF2627, 0xf81f0224},
-{6800000, DIF_BPF_COEFF2829, 0x0bd50def},
-{6800000, DIF_BPF_COEFF3031, 0x0621f94b},
-{6800000, DIF_BPF_COEFF3233, 0xf067f21e},
-{6800000, DIF_BPF_COEFF3435, 0xfdae0b29},
-{6800000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 68_quant.dat*/
-
-
-/*case 6900000:*/
-/* BEGIN - DIF BPF register values from 69_quant.dat*/
-{6900000, DIF_BPF_COEFF01, 0x00010001},
-{6900000, DIF_BPF_COEFF23, 0xfffdffef},
-{6900000, DIF_BPF_COEFF45, 0xffe3fff6},
-{6900000, DIF_BPF_COEFF67, 0x0037007f},
-{6900000, DIF_BPF_COEFF89, 0x0075ffdc},
-{6900000, DIF_BPF_COEFF1011, 0xfef2fe7c},
-{6900000, DIF_BPF_COEFF1213, 0xff3d0122},
-{6900000, DIF_BPF_COEFF1415, 0x02ea02dd},
-{6900000, DIF_BPF_COEFF1617, 0x0044fc79},
-{6900000, DIF_BPF_COEFF1819, 0xfa65fc5d},
-{6900000, DIF_BPF_COEFF2021, 0x01e3074e},
-{6900000, DIF_BPF_COEFF2223, 0x082102ad},
-{6900000, DIF_BPF_COEFF2425, 0xfa0ff48c},
-{6900000, DIF_BPF_COEFF2627, 0xf6fe00a9},
-{6900000, DIF_BPF_COEFF2829, 0x0b0a0e43},
-{6900000, DIF_BPF_COEFF3031, 0x0729fa33},
-{6900000, DIF_BPF_COEFF3233, 0xf0a5f1c9},
-{6900000, DIF_BPF_COEFF3435, 0xfd430b00},
-{6900000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 69_quant.dat*/
-
-
-/*case 7000000:*/
-/* BEGIN - DIF BPF register values from 70_quant.dat*/
-{7000000, DIF_BPF_COEFF01, 0x00010002},
-{7000000, DIF_BPF_COEFF23, 0x0001fff3},
-{7000000, DIF_BPF_COEFF45, 0xffdeffe2},
-{7000000, DIF_BPF_COEFF67, 0x001b0076},
-{7000000, DIF_BPF_COEFF89, 0x009c002d},
-{7000000, DIF_BPF_COEFF1011, 0xff35fe68},
-{7000000, DIF_BPF_COEFF1213, 0xfeba0076},
-{7000000, DIF_BPF_COEFF1415, 0x029f0352},
-{7000000, DIF_BPF_COEFF1617, 0x014dfd60},
-{7000000, DIF_BPF_COEFF1819, 0xfa69fb53},
-{7000000, DIF_BPF_COEFF2021, 0x00740688},
-{7000000, DIF_BPF_COEFF2223, 0x08a7042d},
-{7000000, DIF_BPF_COEFF2425, 0xfb75f4d6},
-{7000000, DIF_BPF_COEFF2627, 0xf600ff2d},
-{7000000, DIF_BPF_COEFF2829, 0x0a220e7a},
-{7000000, DIF_BPF_COEFF3031, 0x0827fb22},
-{7000000, DIF_BPF_COEFF3233, 0xf0edf17a},
-{7000000, DIF_BPF_COEFF3435, 0xfcd80ad6},
-{7000000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 70_quant.dat*/
-
-
-/*case 7100000:*/
-/* BEGIN - DIF BPF register values from 71_quant.dat*/
-{7100000, DIF_BPF_COEFF01, 0x00000003},
-{7100000, DIF_BPF_COEFF23, 0x0004fff9},
-{7100000, DIF_BPF_COEFF45, 0xffe0ffd2},
-{7100000, DIF_BPF_COEFF67, 0xfffb005e},
-{7100000, DIF_BPF_COEFF89, 0x00b0007a},
-{7100000, DIF_BPF_COEFF1011, 0xff8ffe7c},
-{7100000, DIF_BPF_COEFF1213, 0xfe53ffc1},
-{7100000, DIF_BPF_COEFF1415, 0x0221038c},
-{7100000, DIF_BPF_COEFF1617, 0x0241fe6e},
-{7100000, DIF_BPF_COEFF1819, 0xfab6fa80},
-{7100000, DIF_BPF_COEFF2021, 0xff010587},
-{7100000, DIF_BPF_COEFF2223, 0x08e90590},
-{7100000, DIF_BPF_COEFF2425, 0xfcf5f556},
-{7100000, DIF_BPF_COEFF2627, 0xf52bfdb3},
-{7100000, DIF_BPF_COEFF2829, 0x09210e95},
-{7100000, DIF_BPF_COEFF3031, 0x0919fc15},
-{7100000, DIF_BPF_COEFF3233, 0xf13ff12f},
-{7100000, DIF_BPF_COEFF3435, 0xfc6e0aab},
-{7100000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 71_quant.dat*/
-
-
-/*case 7200000:*/
-/* BEGIN - DIF BPF register values from 72_quant.dat*/
-{7200000, DIF_BPF_COEFF01, 0x00000003},
-{7200000, DIF_BPF_COEFF23, 0x00070000},
-{7200000, DIF_BPF_COEFF45, 0xffe6ffc9},
-{7200000, DIF_BPF_COEFF67, 0xffdb0039},
-{7200000, DIF_BPF_COEFF89, 0x00af00b8},
-{7200000, DIF_BPF_COEFF1011, 0xfff4feb6},
-{7200000, DIF_BPF_COEFF1213, 0xfe13ff10},
-{7200000, DIF_BPF_COEFF1415, 0x01790388},
-{7200000, DIF_BPF_COEFF1617, 0x0311ff92},
-{7200000, DIF_BPF_COEFF1819, 0xfb48f9ed},
-{7200000, DIF_BPF_COEFF2021, 0xfd980453},
-{7200000, DIF_BPF_COEFF2223, 0x08e306cd},
-{7200000, DIF_BPF_COEFF2425, 0xfe88f60a},
-{7200000, DIF_BPF_COEFF2627, 0xf482fc40},
-{7200000, DIF_BPF_COEFF2829, 0x08080e93},
-{7200000, DIF_BPF_COEFF3031, 0x09fdfd0c},
-{7200000, DIF_BPF_COEFF3233, 0xf19af0ea},
-{7200000, DIF_BPF_COEFF3435, 0xfc050a81},
-{7200000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 72_quant.dat*/
-
-
-/*case 7300000:*/
-/* BEGIN - DIF BPF register values from 73_quant.dat*/
-{7300000, DIF_BPF_COEFF01, 0x00000002},
-{7300000, DIF_BPF_COEFF23, 0x00080008},
-{7300000, DIF_BPF_COEFF45, 0xfff0ffc9},
-{7300000, DIF_BPF_COEFF67, 0xffc1000d},
-{7300000, DIF_BPF_COEFF89, 0x009800e2},
-{7300000, DIF_BPF_COEFF1011, 0x005bff10},
-{7300000, DIF_BPF_COEFF1213, 0xfe00fe74},
-{7300000, DIF_BPF_COEFF1415, 0x00b50345},
-{7300000, DIF_BPF_COEFF1617, 0x03b000bc},
-{7300000, DIF_BPF_COEFF1819, 0xfc18f9a1},
-{7300000, DIF_BPF_COEFF2021, 0xfc4802f9},
-{7300000, DIF_BPF_COEFF2223, 0x089807dc},
-{7300000, DIF_BPF_COEFF2425, 0x0022f6f0},
-{7300000, DIF_BPF_COEFF2627, 0xf407fada},
-{7300000, DIF_BPF_COEFF2829, 0x06da0e74},
-{7300000, DIF_BPF_COEFF3031, 0x0ad3fe06},
-{7300000, DIF_BPF_COEFF3233, 0xf1fef0ab},
-{7300000, DIF_BPF_COEFF3435, 0xfb9c0a55},
-{7300000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 73_quant.dat*/
-
-
-/*case 7400000:*/
-/* BEGIN - DIF BPF register values from 74_quant.dat*/
-{7400000, DIF_BPF_COEFF01, 0x00000001},
-{7400000, DIF_BPF_COEFF23, 0x0008000e},
-{7400000, DIF_BPF_COEFF45, 0xfffdffd0},
-{7400000, DIF_BPF_COEFF67, 0xffafffdf},
-{7400000, DIF_BPF_COEFF89, 0x006e00f2},
-{7400000, DIF_BPF_COEFF1011, 0x00b8ff82},
-{7400000, DIF_BPF_COEFF1213, 0xfe1bfdf8},
-{7400000, DIF_BPF_COEFF1415, 0xffe302c8},
-{7400000, DIF_BPF_COEFF1617, 0x041301dc},
-{7400000, DIF_BPF_COEFF1819, 0xfd1af99e},
-{7400000, DIF_BPF_COEFF2021, 0xfb1e0183},
-{7400000, DIF_BPF_COEFF2223, 0x080908b5},
-{7400000, DIF_BPF_COEFF2425, 0x01bcf801},
-{7400000, DIF_BPF_COEFF2627, 0xf3bdf985},
-{7400000, DIF_BPF_COEFF2829, 0x059a0e38},
-{7400000, DIF_BPF_COEFF3031, 0x0b99ff03},
-{7400000, DIF_BPF_COEFF3233, 0xf26cf071},
-{7400000, DIF_BPF_COEFF3435, 0xfb330a2a},
-{7400000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 74_quant.dat*/
-
-
-/*case 7500000:*/
-/* BEGIN - DIF BPF register values from 75_quant.dat*/
-{7500000, DIF_BPF_COEFF01, 0xffff0000},
-{7500000, DIF_BPF_COEFF23, 0x00070011},
-{7500000, DIF_BPF_COEFF45, 0x000affdf},
-{7500000, DIF_BPF_COEFF67, 0xffa9ffb5},
-{7500000, DIF_BPF_COEFF89, 0x003700e6},
-{7500000, DIF_BPF_COEFF1011, 0x01010000},
-{7500000, DIF_BPF_COEFF1213, 0xfe62fda8},
-{7500000, DIF_BPF_COEFF1415, 0xff140219},
-{7500000, DIF_BPF_COEFF1617, 0x043502e1},
-{7500000, DIF_BPF_COEFF1819, 0xfe42f9e6},
-{7500000, DIF_BPF_COEFF2021, 0xfa270000},
-{7500000, DIF_BPF_COEFF2223, 0x073a0953},
-{7500000, DIF_BPF_COEFF2425, 0x034cf939},
-{7500000, DIF_BPF_COEFF2627, 0xf3a4f845},
-{7500000, DIF_BPF_COEFF2829, 0x044c0de1},
-{7500000, DIF_BPF_COEFF3031, 0x0c4f0000},
-{7500000, DIF_BPF_COEFF3233, 0xf2e2f03c},
-{7500000, DIF_BPF_COEFF3435, 0xfacc09fe},
-{7500000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 75_quant.dat*/
-
-
-/*case 7600000:*/
-/* BEGIN - DIF BPF register values from 76_quant.dat*/
-{7600000, DIF_BPF_COEFF01, 0xffffffff},
-{7600000, DIF_BPF_COEFF23, 0x00040012},
-{7600000, DIF_BPF_COEFF45, 0x0016fff3},
-{7600000, DIF_BPF_COEFF67, 0xffafff95},
-{7600000, DIF_BPF_COEFF89, 0xfff900c0},
-{7600000, DIF_BPF_COEFF1011, 0x0130007e},
-{7600000, DIF_BPF_COEFF1213, 0xfecefd89},
-{7600000, DIF_BPF_COEFF1415, 0xfe560146},
-{7600000, DIF_BPF_COEFF1617, 0x041303bc},
-{7600000, DIF_BPF_COEFF1819, 0xff81fa76},
-{7600000, DIF_BPF_COEFF2021, 0xf96cfe7d},
-{7600000, DIF_BPF_COEFF2223, 0x063209b1},
-{7600000, DIF_BPF_COEFF2425, 0x04c9fa93},
-{7600000, DIF_BPF_COEFF2627, 0xf3bdf71e},
-{7600000, DIF_BPF_COEFF2829, 0x02f30d6e},
-{7600000, DIF_BPF_COEFF3031, 0x0cf200fd},
-{7600000, DIF_BPF_COEFF3233, 0xf361f00e},
-{7600000, DIF_BPF_COEFF3435, 0xfa6509d1},
-{7600000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 76_quant.dat*/
-
-
-/*case 7700000:*/
-/* BEGIN - DIF BPF register values from 77_quant.dat*/
-{7700000, DIF_BPF_COEFF01, 0xfffffffe},
-{7700000, DIF_BPF_COEFF23, 0x00010010},
-{7700000, DIF_BPF_COEFF45, 0x001e0008},
-{7700000, DIF_BPF_COEFF67, 0xffc1ff84},
-{7700000, DIF_BPF_COEFF89, 0xffbc0084},
-{7700000, DIF_BPF_COEFF1011, 0x013e00f0},
-{7700000, DIF_BPF_COEFF1213, 0xff56fd9f},
-{7700000, DIF_BPF_COEFF1415, 0xfdb8005c},
-{7700000, DIF_BPF_COEFF1617, 0x03b00460},
-{7700000, DIF_BPF_COEFF1819, 0x00c7fb45},
-{7700000, DIF_BPF_COEFF2021, 0xf8f4fd07},
-{7700000, DIF_BPF_COEFF2223, 0x04fa09ce},
-{7700000, DIF_BPF_COEFF2425, 0x062afc07},
-{7700000, DIF_BPF_COEFF2627, 0xf407f614},
-{7700000, DIF_BPF_COEFF2829, 0x01920ce0},
-{7700000, DIF_BPF_COEFF3031, 0x0d8301fa},
-{7700000, DIF_BPF_COEFF3233, 0xf3e8efe5},
-{7700000, DIF_BPF_COEFF3435, 0xfa0009a4},
-{7700000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 77_quant.dat*/
-
-
-/*case 7800000:*/
-/* BEGIN - DIF BPF register values from 78_quant.dat*/
-{7800000, DIF_BPF_COEFF01, 0x0000fffd},
-{7800000, DIF_BPF_COEFF23, 0xfffd000b},
-{7800000, DIF_BPF_COEFF45, 0x0022001d},
-{7800000, DIF_BPF_COEFF67, 0xffdbff82},
-{7800000, DIF_BPF_COEFF89, 0xff870039},
-{7800000, DIF_BPF_COEFF1011, 0x012a014a},
-{7800000, DIF_BPF_COEFF1213, 0xffedfde7},
-{7800000, DIF_BPF_COEFF1415, 0xfd47ff6b},
-{7800000, DIF_BPF_COEFF1617, 0x031104c6},
-{7800000, DIF_BPF_COEFF1819, 0x0202fc4c},
-{7800000, DIF_BPF_COEFF2021, 0xf8c6fbad},
-{7800000, DIF_BPF_COEFF2223, 0x039909a7},
-{7800000, DIF_BPF_COEFF2425, 0x0767fd8e},
-{7800000, DIF_BPF_COEFF2627, 0xf482f52b},
-{7800000, DIF_BPF_COEFF2829, 0x002d0c39},
-{7800000, DIF_BPF_COEFF3031, 0x0e0002f4},
-{7800000, DIF_BPF_COEFF3233, 0xf477efc2},
-{7800000, DIF_BPF_COEFF3435, 0xf99b0977},
-{7800000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 78_quant.dat*/
-
-
-/*case 7900000:*/
-/* BEGIN - DIF BPF register values from 79_quant.dat*/
-{7900000, DIF_BPF_COEFF01, 0x0000fffd},
-{7900000, DIF_BPF_COEFF23, 0xfffa0004},
-{7900000, DIF_BPF_COEFF45, 0x0020002d},
-{7900000, DIF_BPF_COEFF67, 0xfffbff91},
-{7900000, DIF_BPF_COEFF89, 0xff61ffe8},
-{7900000, DIF_BPF_COEFF1011, 0x00f70184},
-{7900000, DIF_BPF_COEFF1213, 0x0086fe5c},
-{7900000, DIF_BPF_COEFF1415, 0xfd0bfe85},
-{7900000, DIF_BPF_COEFF1617, 0x024104e5},
-{7900000, DIF_BPF_COEFF1819, 0x0323fd7d},
-{7900000, DIF_BPF_COEFF2021, 0xf8e2fa79},
-{7900000, DIF_BPF_COEFF2223, 0x021d093f},
-{7900000, DIF_BPF_COEFF2425, 0x0879ff22},
-{7900000, DIF_BPF_COEFF2627, 0xf52bf465},
-{7900000, DIF_BPF_COEFF2829, 0xfec70b79},
-{7900000, DIF_BPF_COEFF3031, 0x0e6803eb},
-{7900000, DIF_BPF_COEFF3233, 0xf50defa5},
-{7900000, DIF_BPF_COEFF3435, 0xf937094a},
-{7900000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 79_quant.dat*/
-
-
-/*case 8000000:*/
-/* BEGIN - DIF BPF register values from 80_quant.dat*/
-{8000000, DIF_BPF_COEFF01, 0x0000fffe},
-{8000000, DIF_BPF_COEFF23, 0xfff8fffd},
-{8000000, DIF_BPF_COEFF45, 0x00190036},
-{8000000, DIF_BPF_COEFF67, 0x001bffaf},
-{8000000, DIF_BPF_COEFF89, 0xff4fff99},
-{8000000, DIF_BPF_COEFF1011, 0x00aa0198},
-{8000000, DIF_BPF_COEFF1213, 0x0112fef3},
-{8000000, DIF_BPF_COEFF1415, 0xfd09fdb9},
-{8000000, DIF_BPF_COEFF1617, 0x014d04be},
-{8000000, DIF_BPF_COEFF1819, 0x041bfecc},
-{8000000, DIF_BPF_COEFF2021, 0xf947f978},
-{8000000, DIF_BPF_COEFF2223, 0x00900897},
-{8000000, DIF_BPF_COEFF2425, 0x095a00b9},
-{8000000, DIF_BPF_COEFF2627, 0xf600f3c5},
-{8000000, DIF_BPF_COEFF2829, 0xfd650aa3},
-{8000000, DIF_BPF_COEFF3031, 0x0ebc04de},
-{8000000, DIF_BPF_COEFF3233, 0xf5aaef8e},
-{8000000, DIF_BPF_COEFF3435, 0xf8d5091c},
-{8000000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 80_quant.dat*/
-
-
-/*case 8100000:*/
-/* BEGIN - DIF BPF register values from 81_quant.dat*/
-{8100000, DIF_BPF_COEFF01, 0x0000ffff},
-{8100000, DIF_BPF_COEFF23, 0xfff7fff6},
-{8100000, DIF_BPF_COEFF45, 0x000e0038},
-{8100000, DIF_BPF_COEFF67, 0x0037ffd7},
-{8100000, DIF_BPF_COEFF89, 0xff52ff56},
-{8100000, DIF_BPF_COEFF1011, 0x004b0184},
-{8100000, DIF_BPF_COEFF1213, 0x0186ffa1},
-{8100000, DIF_BPF_COEFF1415, 0xfd40fd16},
-{8100000, DIF_BPF_COEFF1617, 0x00440452},
-{8100000, DIF_BPF_COEFF1819, 0x04de0029},
-{8100000, DIF_BPF_COEFF2021, 0xf9f2f8b2},
-{8100000, DIF_BPF_COEFF2223, 0xfefe07b5},
-{8100000, DIF_BPF_COEFF2425, 0x0a05024d},
-{8100000, DIF_BPF_COEFF2627, 0xf6fef34d},
-{8100000, DIF_BPF_COEFF2829, 0xfc0a09b8},
-{8100000, DIF_BPF_COEFF3031, 0x0efa05cd},
-{8100000, DIF_BPF_COEFF3233, 0xf64eef7d},
-{8100000, DIF_BPF_COEFF3435, 0xf87308ed},
-{8100000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 81_quant.dat*/
-
-
-/*case 8200000:*/
-/* BEGIN - DIF BPF register values from 82_quant.dat*/
-{8200000, DIF_BPF_COEFF01, 0x00010000},
-{8200000, DIF_BPF_COEFF23, 0xfff8fff0},
-{8200000, DIF_BPF_COEFF45, 0x00000031},
-{8200000, DIF_BPF_COEFF67, 0x004c0005},
-{8200000, DIF_BPF_COEFF89, 0xff6aff27},
-{8200000, DIF_BPF_COEFF1011, 0xffe4014a},
-{8200000, DIF_BPF_COEFF1213, 0x01d70057},
-{8200000, DIF_BPF_COEFF1415, 0xfdacfca6},
-{8200000, DIF_BPF_COEFF1617, 0xff3603a7},
-{8200000, DIF_BPF_COEFF1819, 0x05610184},
-{8200000, DIF_BPF_COEFF2021, 0xfadbf82e},
-{8200000, DIF_BPF_COEFF2223, 0xfd74069f},
-{8200000, DIF_BPF_COEFF2425, 0x0a7503d6},
-{8200000, DIF_BPF_COEFF2627, 0xf81ff2ff},
-{8200000, DIF_BPF_COEFF2829, 0xfab808b9},
-{8200000, DIF_BPF_COEFF3031, 0x0f2306b5},
-{8200000, DIF_BPF_COEFF3233, 0xf6f9ef72},
-{8200000, DIF_BPF_COEFF3435, 0xf81308bf},
-{8200000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 82_quant.dat*/
-
-
-/*case 8300000:*/
-/* BEGIN - DIF BPF register values from 83_quant.dat*/
-{8300000, DIF_BPF_COEFF01, 0x00010001},
-{8300000, DIF_BPF_COEFF23, 0xfffbffee},
-{8300000, DIF_BPF_COEFF45, 0xfff30022},
-{8300000, DIF_BPF_COEFF67, 0x00560032},
-{8300000, DIF_BPF_COEFF89, 0xff95ff10},
-{8300000, DIF_BPF_COEFF1011, 0xff8000f0},
-{8300000, DIF_BPF_COEFF1213, 0x01fe0106},
-{8300000, DIF_BPF_COEFF1415, 0xfe46fc71},
-{8300000, DIF_BPF_COEFF1617, 0xfe3502c7},
-{8300000, DIF_BPF_COEFF1819, 0x059e02ce},
-{8300000, DIF_BPF_COEFF2021, 0xfbf9f7f2},
-{8300000, DIF_BPF_COEFF2223, 0xfbff055b},
-{8300000, DIF_BPF_COEFF2425, 0x0aa9054c},
-{8300000, DIF_BPF_COEFF2627, 0xf961f2db},
-{8300000, DIF_BPF_COEFF2829, 0xf97507aa},
-{8300000, DIF_BPF_COEFF3031, 0x0f350797},
-{8300000, DIF_BPF_COEFF3233, 0xf7a9ef6d},
-{8300000, DIF_BPF_COEFF3435, 0xf7b40890},
-{8300000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 83_quant.dat*/
-
-
-/*case 8400000:*/
-/* BEGIN - DIF BPF register values from 84_quant.dat*/
-{8400000, DIF_BPF_COEFF01, 0x00010002},
-{8400000, DIF_BPF_COEFF23, 0xfffeffee},
-{8400000, DIF_BPF_COEFF45, 0xffe8000f},
-{8400000, DIF_BPF_COEFF67, 0x00540058},
-{8400000, DIF_BPF_COEFF89, 0xffcdff14},
-{8400000, DIF_BPF_COEFF1011, 0xff29007e},
-{8400000, DIF_BPF_COEFF1213, 0x01f6019e},
-{8400000, DIF_BPF_COEFF1415, 0xff01fc7c},
-{8400000, DIF_BPF_COEFF1617, 0xfd5101bf},
-{8400000, DIF_BPF_COEFF1819, 0x059203f6},
-{8400000, DIF_BPF_COEFF2021, 0xfd41f7fe},
-{8400000, DIF_BPF_COEFF2223, 0xfaa903f3},
-{8400000, DIF_BPF_COEFF2425, 0x0a9e06a9},
-{8400000, DIF_BPF_COEFF2627, 0xfabdf2e2},
-{8400000, DIF_BPF_COEFF2829, 0xf842068b},
-{8400000, DIF_BPF_COEFF3031, 0x0f320871},
-{8400000, DIF_BPF_COEFF3233, 0xf85eef6e},
-{8400000, DIF_BPF_COEFF3435, 0xf7560860},
-{8400000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 84_quant.dat*/
-
-
-/*case 8500000:*/
-/* BEGIN - DIF BPF register values from 85_quant.dat*/
-{8500000, DIF_BPF_COEFF01, 0x00000003},
-{8500000, DIF_BPF_COEFF23, 0x0002fff2},
-{8500000, DIF_BPF_COEFF45, 0xffe1fff9},
-{8500000, DIF_BPF_COEFF67, 0x00460073},
-{8500000, DIF_BPF_COEFF89, 0x000bff34},
-{8500000, DIF_BPF_COEFF1011, 0xfee90000},
-{8500000, DIF_BPF_COEFF1213, 0x01c10215},
-{8500000, DIF_BPF_COEFF1415, 0xffd0fcc5},
-{8500000, DIF_BPF_COEFF1617, 0xfc99009d},
-{8500000, DIF_BPF_COEFF1819, 0x053d04f1},
-{8500000, DIF_BPF_COEFF2021, 0xfea5f853},
-{8500000, DIF_BPF_COEFF2223, 0xf97d0270},
-{8500000, DIF_BPF_COEFF2425, 0x0a5607e4},
-{8500000, DIF_BPF_COEFF2627, 0xfc2ef314},
-{8500000, DIF_BPF_COEFF2829, 0xf723055f},
-{8500000, DIF_BPF_COEFF3031, 0x0f180943},
-{8500000, DIF_BPF_COEFF3233, 0xf919ef75},
-{8500000, DIF_BPF_COEFF3435, 0xf6fa0830},
-{8500000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 85_quant.dat*/
-
-
-/*case 8600000:*/
-/* BEGIN - DIF BPF register values from 86_quant.dat*/
-{8600000, DIF_BPF_COEFF01, 0x00000003},
-{8600000, DIF_BPF_COEFF23, 0x0005fff8},
-{8600000, DIF_BPF_COEFF45, 0xffdeffe4},
-{8600000, DIF_BPF_COEFF67, 0x002f007f},
-{8600000, DIF_BPF_COEFF89, 0x0048ff6b},
-{8600000, DIF_BPF_COEFF1011, 0xfec7ff82},
-{8600000, DIF_BPF_COEFF1213, 0x0163025f},
-{8600000, DIF_BPF_COEFF1415, 0x00a2fd47},
-{8600000, DIF_BPF_COEFF1617, 0xfc17ff73},
-{8600000, DIF_BPF_COEFF1819, 0x04a405b2},
-{8600000, DIF_BPF_COEFF2021, 0x0017f8ed},
-{8600000, DIF_BPF_COEFF2223, 0xf88500dc},
-{8600000, DIF_BPF_COEFF2425, 0x09d208f9},
-{8600000, DIF_BPF_COEFF2627, 0xfdaff370},
-{8600000, DIF_BPF_COEFF2829, 0xf61c0429},
-{8600000, DIF_BPF_COEFF3031, 0x0ee80a0b},
-{8600000, DIF_BPF_COEFF3233, 0xf9d8ef82},
-{8600000, DIF_BPF_COEFF3435, 0xf6a00800},
-{8600000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 86_quant.dat*/
-
-
-/*case 8700000:*/
-/* BEGIN - DIF BPF register values from 87_quant.dat*/
-{8700000, DIF_BPF_COEFF01, 0x00000003},
-{8700000, DIF_BPF_COEFF23, 0x0007ffff},
-{8700000, DIF_BPF_COEFF45, 0xffe1ffd4},
-{8700000, DIF_BPF_COEFF67, 0x0010007a},
-{8700000, DIF_BPF_COEFF89, 0x007cffb2},
-{8700000, DIF_BPF_COEFF1011, 0xfec6ff10},
-{8700000, DIF_BPF_COEFF1213, 0x00e60277},
-{8700000, DIF_BPF_COEFF1415, 0x0168fdf9},
-{8700000, DIF_BPF_COEFF1617, 0xfbd3fe50},
-{8700000, DIF_BPF_COEFF1819, 0x03ce0631},
-{8700000, DIF_BPF_COEFF2021, 0x0188f9c8},
-{8700000, DIF_BPF_COEFF2223, 0xf7c7ff43},
-{8700000, DIF_BPF_COEFF2425, 0x091509e3},
-{8700000, DIF_BPF_COEFF2627, 0xff39f3f6},
-{8700000, DIF_BPF_COEFF2829, 0xf52d02ea},
-{8700000, DIF_BPF_COEFF3031, 0x0ea30ac9},
-{8700000, DIF_BPF_COEFF3233, 0xfa9bef95},
-{8700000, DIF_BPF_COEFF3435, 0xf64607d0},
-{8700000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 87_quant.dat*/
-
-
-/*case 8800000:*/
-/* BEGIN - DIF BPF register values from 88_quant.dat*/
-{8800000, DIF_BPF_COEFF01, 0x00000002},
-{8800000, DIF_BPF_COEFF23, 0x00090007},
-{8800000, DIF_BPF_COEFF45, 0xffe9ffca},
-{8800000, DIF_BPF_COEFF67, 0xfff00065},
-{8800000, DIF_BPF_COEFF89, 0x00a10003},
-{8800000, DIF_BPF_COEFF1011, 0xfee6feb6},
-{8800000, DIF_BPF_COEFF1213, 0x0053025b},
-{8800000, DIF_BPF_COEFF1415, 0x0213fed0},
-{8800000, DIF_BPF_COEFF1617, 0xfbd3fd46},
-{8800000, DIF_BPF_COEFF1819, 0x02c70668},
-{8800000, DIF_BPF_COEFF2021, 0x02eafadb},
-{8800000, DIF_BPF_COEFF2223, 0xf74bfdae},
-{8800000, DIF_BPF_COEFF2425, 0x08230a9c},
-{8800000, DIF_BPF_COEFF2627, 0x00c7f4a3},
-{8800000, DIF_BPF_COEFF2829, 0xf45b01a6},
-{8800000, DIF_BPF_COEFF3031, 0x0e480b7c},
-{8800000, DIF_BPF_COEFF3233, 0xfb61efae},
-{8800000, DIF_BPF_COEFF3435, 0xf5ef079f},
-{8800000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 88_quant.dat*/
-
-
-/*case 8900000:*/
-/* BEGIN - DIF BPF register values from 89_quant.dat*/
-{8900000, DIF_BPF_COEFF01, 0xffff0000},
-{8900000, DIF_BPF_COEFF23, 0x0008000d},
-{8900000, DIF_BPF_COEFF45, 0xfff5ffc8},
-{8900000, DIF_BPF_COEFF67, 0xffd10043},
-{8900000, DIF_BPF_COEFF89, 0x00b20053},
-{8900000, DIF_BPF_COEFF1011, 0xff24fe7c},
-{8900000, DIF_BPF_COEFF1213, 0xffb9020c},
-{8900000, DIF_BPF_COEFF1415, 0x0295ffbb},
-{8900000, DIF_BPF_COEFF1617, 0xfc17fc64},
-{8900000, DIF_BPF_COEFF1819, 0x019b0654},
-{8900000, DIF_BPF_COEFF2021, 0x042dfc1c},
-{8900000, DIF_BPF_COEFF2223, 0xf714fc2a},
-{8900000, DIF_BPF_COEFF2425, 0x07020b21},
-{8900000, DIF_BPF_COEFF2627, 0x0251f575},
-{8900000, DIF_BPF_COEFF2829, 0xf3a7005e},
-{8900000, DIF_BPF_COEFF3031, 0x0dd80c24},
-{8900000, DIF_BPF_COEFF3233, 0xfc2aefcd},
-{8900000, DIF_BPF_COEFF3435, 0xf599076e},
-{8900000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 89_quant.dat*/
-
-
-/*case 9000000:*/
-/* BEGIN - DIF BPF register values from 90_quant.dat*/
-{9000000, DIF_BPF_COEFF01, 0xffffffff},
-{9000000, DIF_BPF_COEFF23, 0x00060011},
-{9000000, DIF_BPF_COEFF45, 0x0002ffcf},
-{9000000, DIF_BPF_COEFF67, 0xffba0018},
-{9000000, DIF_BPF_COEFF89, 0x00ad009a},
-{9000000, DIF_BPF_COEFF1011, 0xff79fe68},
-{9000000, DIF_BPF_COEFF1213, 0xff260192},
-{9000000, DIF_BPF_COEFF1415, 0x02e500ab},
-{9000000, DIF_BPF_COEFF1617, 0xfc99fbb6},
-{9000000, DIF_BPF_COEFF1819, 0x005b05f7},
-{9000000, DIF_BPF_COEFF2021, 0x0545fd81},
-{9000000, DIF_BPF_COEFF2223, 0xf723fabf},
-{9000000, DIF_BPF_COEFF2425, 0x05b80b70},
-{9000000, DIF_BPF_COEFF2627, 0x03d2f669},
-{9000000, DIF_BPF_COEFF2829, 0xf313ff15},
-{9000000, DIF_BPF_COEFF3031, 0x0d550cbf},
-{9000000, DIF_BPF_COEFF3233, 0xfcf6eff2},
-{9000000, DIF_BPF_COEFF3435, 0xf544073d},
-{9000000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 90_quant.dat*/
-
-
-/*case 9100000:*/
-/* BEGIN - DIF BPF register values from 91_quant.dat*/
-{9100000, DIF_BPF_COEFF01, 0xfffffffe},
-{9100000, DIF_BPF_COEFF23, 0x00030012},
-{9100000, DIF_BPF_COEFF45, 0x000fffdd},
-{9100000, DIF_BPF_COEFF67, 0xffacffea},
-{9100000, DIF_BPF_COEFF89, 0x009300cf},
-{9100000, DIF_BPF_COEFF1011, 0xffdcfe7c},
-{9100000, DIF_BPF_COEFF1213, 0xfea600f7},
-{9100000, DIF_BPF_COEFF1415, 0x02fd0190},
-{9100000, DIF_BPF_COEFF1617, 0xfd51fb46},
-{9100000, DIF_BPF_COEFF1819, 0xff150554},
-{9100000, DIF_BPF_COEFF2021, 0x0627fefd},
-{9100000, DIF_BPF_COEFF2223, 0xf778f978},
-{9100000, DIF_BPF_COEFF2425, 0x044d0b87},
-{9100000, DIF_BPF_COEFF2627, 0x0543f77d},
-{9100000, DIF_BPF_COEFF2829, 0xf2a0fdcf},
-{9100000, DIF_BPF_COEFF3031, 0x0cbe0d4e},
-{9100000, DIF_BPF_COEFF3233, 0xfdc4f01d},
-{9100000, DIF_BPF_COEFF3435, 0xf4f2070b},
-{9100000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 91_quant.dat*/
-
-
-/*case 9200000:*/
-/* BEGIN - DIF BPF register values from 92_quant.dat*/
-{9200000, DIF_BPF_COEFF01, 0x0000fffd},
-{9200000, DIF_BPF_COEFF23, 0x00000010},
-{9200000, DIF_BPF_COEFF45, 0x001afff0},
-{9200000, DIF_BPF_COEFF67, 0xffaaffbf},
-{9200000, DIF_BPF_COEFF89, 0x006700ed},
-{9200000, DIF_BPF_COEFF1011, 0x0043feb6},
-{9200000, DIF_BPF_COEFF1213, 0xfe460047},
-{9200000, DIF_BPF_COEFF1415, 0x02db0258},
-{9200000, DIF_BPF_COEFF1617, 0xfe35fb1b},
-{9200000, DIF_BPF_COEFF1819, 0xfddc0473},
-{9200000, DIF_BPF_COEFF2021, 0x06c90082},
-{9200000, DIF_BPF_COEFF2223, 0xf811f85e},
-{9200000, DIF_BPF_COEFF2425, 0x02c90b66},
-{9200000, DIF_BPF_COEFF2627, 0x069ff8ad},
-{9200000, DIF_BPF_COEFF2829, 0xf250fc8d},
-{9200000, DIF_BPF_COEFF3031, 0x0c140dcf},
-{9200000, DIF_BPF_COEFF3233, 0xfe93f04d},
-{9200000, DIF_BPF_COEFF3435, 0xf4a106d9},
-{9200000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 92_quant.dat*/
-
-
-/*case 9300000:*/
-/* BEGIN - DIF BPF register values from 93_quant.dat*/
-{9300000, DIF_BPF_COEFF01, 0x0000fffd},
-{9300000, DIF_BPF_COEFF23, 0xfffc000c},
-{9300000, DIF_BPF_COEFF45, 0x00200006},
-{9300000, DIF_BPF_COEFF67, 0xffb4ff9c},
-{9300000, DIF_BPF_COEFF89, 0x002f00ef},
-{9300000, DIF_BPF_COEFF1011, 0x00a4ff10},
-{9300000, DIF_BPF_COEFF1213, 0xfe0dff92},
-{9300000, DIF_BPF_COEFF1415, 0x028102f7},
-{9300000, DIF_BPF_COEFF1617, 0xff36fb37},
-{9300000, DIF_BPF_COEFF1819, 0xfcbf035e},
-{9300000, DIF_BPF_COEFF2021, 0x07260202},
-{9300000, DIF_BPF_COEFF2223, 0xf8e8f778},
-{9300000, DIF_BPF_COEFF2425, 0x01340b0d},
-{9300000, DIF_BPF_COEFF2627, 0x07e1f9f4},
-{9300000, DIF_BPF_COEFF2829, 0xf223fb51},
-{9300000, DIF_BPF_COEFF3031, 0x0b590e42},
-{9300000, DIF_BPF_COEFF3233, 0xff64f083},
-{9300000, DIF_BPF_COEFF3435, 0xf45206a7},
-{9300000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 93_quant.dat*/
-
-
-/*case 9400000:*/
-/* BEGIN - DIF BPF register values from 94_quant.dat*/
-{9400000, DIF_BPF_COEFF01, 0x0000fffd},
-{9400000, DIF_BPF_COEFF23, 0xfff90005},
-{9400000, DIF_BPF_COEFF45, 0x0022001a},
-{9400000, DIF_BPF_COEFF67, 0xffc9ff86},
-{9400000, DIF_BPF_COEFF89, 0xfff000d7},
-{9400000, DIF_BPF_COEFF1011, 0x00f2ff82},
-{9400000, DIF_BPF_COEFF1213, 0xfe01fee5},
-{9400000, DIF_BPF_COEFF1415, 0x01f60362},
-{9400000, DIF_BPF_COEFF1617, 0x0044fb99},
-{9400000, DIF_BPF_COEFF1819, 0xfbcc0222},
-{9400000, DIF_BPF_COEFF2021, 0x07380370},
-{9400000, DIF_BPF_COEFF2223, 0xf9f7f6cc},
-{9400000, DIF_BPF_COEFF2425, 0xff990a7e},
-{9400000, DIF_BPF_COEFF2627, 0x0902fb50},
-{9400000, DIF_BPF_COEFF2829, 0xf21afa1f},
-{9400000, DIF_BPF_COEFF3031, 0x0a8d0ea6},
-{9400000, DIF_BPF_COEFF3233, 0x0034f0bf},
-{9400000, DIF_BPF_COEFF3435, 0xf4050675},
-{9400000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 94_quant.dat*/
-
-
-/*case 9500000:*/
-/* BEGIN - DIF BPF register values from 95_quant.dat*/
-{9500000, DIF_BPF_COEFF01, 0x0000fffe},
-{9500000, DIF_BPF_COEFF23, 0xfff8fffe},
-{9500000, DIF_BPF_COEFF45, 0x001e002b},
-{9500000, DIF_BPF_COEFF67, 0xffe5ff81},
-{9500000, DIF_BPF_COEFF89, 0xffb400a5},
-{9500000, DIF_BPF_COEFF1011, 0x01280000},
-{9500000, DIF_BPF_COEFF1213, 0xfe24fe50},
-{9500000, DIF_BPF_COEFF1415, 0x01460390},
-{9500000, DIF_BPF_COEFF1617, 0x014dfc3a},
-{9500000, DIF_BPF_COEFF1819, 0xfb1000ce},
-{9500000, DIF_BPF_COEFF2021, 0x070104bf},
-{9500000, DIF_BPF_COEFF2223, 0xfb37f65f},
-{9500000, DIF_BPF_COEFF2425, 0xfe0009bc},
-{9500000, DIF_BPF_COEFF2627, 0x0a00fcbb},
-{9500000, DIF_BPF_COEFF2829, 0xf235f8f8},
-{9500000, DIF_BPF_COEFF3031, 0x09b20efc},
-{9500000, DIF_BPF_COEFF3233, 0x0105f101},
-{9500000, DIF_BPF_COEFF3435, 0xf3ba0642},
-{9500000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 95_quant.dat*/
-
-
-/*case 9600000:*/
-/* BEGIN - DIF BPF register values from 96_quant.dat*/
-{9600000, DIF_BPF_COEFF01, 0x0001ffff},
-{9600000, DIF_BPF_COEFF23, 0xfff8fff7},
-{9600000, DIF_BPF_COEFF45, 0x00150036},
-{9600000, DIF_BPF_COEFF67, 0x0005ff8c},
-{9600000, DIF_BPF_COEFF89, 0xff810061},
-{9600000, DIF_BPF_COEFF1011, 0x013d007e},
-{9600000, DIF_BPF_COEFF1213, 0xfe71fddf},
-{9600000, DIF_BPF_COEFF1415, 0x007c0380},
-{9600000, DIF_BPF_COEFF1617, 0x0241fd13},
-{9600000, DIF_BPF_COEFF1819, 0xfa94ff70},
-{9600000, DIF_BPF_COEFF2021, 0x068005e2},
-{9600000, DIF_BPF_COEFF2223, 0xfc9bf633},
-{9600000, DIF_BPF_COEFF2425, 0xfc7308ca},
-{9600000, DIF_BPF_COEFF2627, 0x0ad5fe30},
-{9600000, DIF_BPF_COEFF2829, 0xf274f7e0},
-{9600000, DIF_BPF_COEFF3031, 0x08c90f43},
-{9600000, DIF_BPF_COEFF3233, 0x01d4f147},
-{9600000, DIF_BPF_COEFF3435, 0xf371060f},
-{9600000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 96_quant.dat*/
-
-
-/*case 9700000:*/
-/* BEGIN - DIF BPF register values from 97_quant.dat*/
-{9700000, DIF_BPF_COEFF01, 0x00010001},
-{9700000, DIF_BPF_COEFF23, 0xfff9fff1},
-{9700000, DIF_BPF_COEFF45, 0x00090038},
-{9700000, DIF_BPF_COEFF67, 0x0025ffa7},
-{9700000, DIF_BPF_COEFF89, 0xff5e0012},
-{9700000, DIF_BPF_COEFF1011, 0x013200f0},
-{9700000, DIF_BPF_COEFF1213, 0xfee3fd9b},
-{9700000, DIF_BPF_COEFF1415, 0xffaa0331},
-{9700000, DIF_BPF_COEFF1617, 0x0311fe15},
-{9700000, DIF_BPF_COEFF1819, 0xfa60fe18},
-{9700000, DIF_BPF_COEFF2021, 0x05bd06d1},
-{9700000, DIF_BPF_COEFF2223, 0xfe1bf64a},
-{9700000, DIF_BPF_COEFF2425, 0xfafa07ae},
-{9700000, DIF_BPF_COEFF2627, 0x0b7effab},
-{9700000, DIF_BPF_COEFF2829, 0xf2d5f6d7},
-{9700000, DIF_BPF_COEFF3031, 0x07d30f7a},
-{9700000, DIF_BPF_COEFF3233, 0x02a3f194},
-{9700000, DIF_BPF_COEFF3435, 0xf32905dc},
-{9700000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 97_quant.dat*/
-
-
-/*case 9800000:*/
-/* BEGIN - DIF BPF register values from 98_quant.dat*/
-{9800000, DIF_BPF_COEFF01, 0x00010002},
-{9800000, DIF_BPF_COEFF23, 0xfffcffee},
-{9800000, DIF_BPF_COEFF45, 0xfffb0032},
-{9800000, DIF_BPF_COEFF67, 0x003fffcd},
-{9800000, DIF_BPF_COEFF89, 0xff4effc1},
-{9800000, DIF_BPF_COEFF1011, 0x0106014a},
-{9800000, DIF_BPF_COEFF1213, 0xff6efd8a},
-{9800000, DIF_BPF_COEFF1415, 0xfedd02aa},
-{9800000, DIF_BPF_COEFF1617, 0x03b0ff34},
-{9800000, DIF_BPF_COEFF1819, 0xfa74fcd7},
-{9800000, DIF_BPF_COEFF2021, 0x04bf0781},
-{9800000, DIF_BPF_COEFF2223, 0xffaaf6a3},
-{9800000, DIF_BPF_COEFF2425, 0xf99e066b},
-{9800000, DIF_BPF_COEFF2627, 0x0bf90128},
-{9800000, DIF_BPF_COEFF2829, 0xf359f5e1},
-{9800000, DIF_BPF_COEFF3031, 0x06d20fa2},
-{9800000, DIF_BPF_COEFF3233, 0x0370f1e5},
-{9800000, DIF_BPF_COEFF3435, 0xf2e405a8},
-{9800000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 98_quant.dat*/
-
-
-/*case 9900000:*/
-/* BEGIN - DIF BPF register values from 99_quant.dat*/
-{9900000, DIF_BPF_COEFF01, 0x00000003},
-{9900000, DIF_BPF_COEFF23, 0xffffffee},
-{9900000, DIF_BPF_COEFF45, 0xffef0024},
-{9900000, DIF_BPF_COEFF67, 0x0051fffa},
-{9900000, DIF_BPF_COEFF89, 0xff54ff77},
-{9900000, DIF_BPF_COEFF1011, 0x00be0184},
-{9900000, DIF_BPF_COEFF1213, 0x0006fdad},
-{9900000, DIF_BPF_COEFF1415, 0xfe2701f3},
-{9900000, DIF_BPF_COEFF1617, 0x0413005e},
-{9900000, DIF_BPF_COEFF1819, 0xfad1fbba},
-{9900000, DIF_BPF_COEFF2021, 0x039007ee},
-{9900000, DIF_BPF_COEFF2223, 0x013bf73d},
-{9900000, DIF_BPF_COEFF2425, 0xf868050a},
-{9900000, DIF_BPF_COEFF2627, 0x0c4302a1},
-{9900000, DIF_BPF_COEFF2829, 0xf3fdf4fe},
-{9900000, DIF_BPF_COEFF3031, 0x05c70fba},
-{9900000, DIF_BPF_COEFF3233, 0x043bf23c},
-{9900000, DIF_BPF_COEFF3435, 0xf2a10575},
-{9900000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 99_quant.dat*/
-
-
-/*case 10000000:*/
-/* BEGIN - DIF BPF register values from 100_quant.dat*/
-{10000000, DIF_BPF_COEFF01, 0x00000003},
-{10000000, DIF_BPF_COEFF23, 0x0003fff1},
-{10000000, DIF_BPF_COEFF45, 0xffe50011},
-{10000000, DIF_BPF_COEFF67, 0x00570027},
-{10000000, DIF_BPF_COEFF89, 0xff70ff3c},
-{10000000, DIF_BPF_COEFF1011, 0x00620198},
-{10000000, DIF_BPF_COEFF1213, 0x009efe01},
-{10000000, DIF_BPF_COEFF1415, 0xfd95011a},
-{10000000, DIF_BPF_COEFF1617, 0x04350183},
-{10000000, DIF_BPF_COEFF1819, 0xfb71fad0},
-{10000000, DIF_BPF_COEFF2021, 0x023c0812},
-{10000000, DIF_BPF_COEFF2223, 0x02c3f811},
-{10000000, DIF_BPF_COEFF2425, 0xf75e0390},
-{10000000, DIF_BPF_COEFF2627, 0x0c5c0411},
-{10000000, DIF_BPF_COEFF2829, 0xf4c1f432},
-{10000000, DIF_BPF_COEFF3031, 0x04b30fc1},
-{10000000, DIF_BPF_COEFF3233, 0x0503f297},
-{10000000, DIF_BPF_COEFF3435, 0xf2610541},
-{10000000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 100_quant.dat*/
-
-
-/*case 10100000:*/
-/* BEGIN - DIF BPF register values from 101_quant.dat*/
-{10100000, DIF_BPF_COEFF01, 0x00000003},
-{10100000, DIF_BPF_COEFF23, 0x0006fff7},
-{10100000, DIF_BPF_COEFF45, 0xffdffffc},
-{10100000, DIF_BPF_COEFF67, 0x00510050},
-{10100000, DIF_BPF_COEFF89, 0xff9dff18},
-{10100000, DIF_BPF_COEFF1011, 0xfffc0184},
-{10100000, DIF_BPF_COEFF1213, 0x0128fe80},
-{10100000, DIF_BPF_COEFF1415, 0xfd32002e},
-{10100000, DIF_BPF_COEFF1617, 0x04130292},
-{10100000, DIF_BPF_COEFF1819, 0xfc4dfa21},
-{10100000, DIF_BPF_COEFF2021, 0x00d107ee},
-{10100000, DIF_BPF_COEFF2223, 0x0435f91c},
-{10100000, DIF_BPF_COEFF2425, 0xf6850205},
-{10100000, DIF_BPF_COEFF2627, 0x0c430573},
-{10100000, DIF_BPF_COEFF2829, 0xf5a1f37d},
-{10100000, DIF_BPF_COEFF3031, 0x03990fba},
-{10100000, DIF_BPF_COEFF3233, 0x05c7f2f8},
-{10100000, DIF_BPF_COEFF3435, 0xf222050d},
-{10100000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 101_quant.dat*/
-
-
-/*case 10200000:*/
-/* BEGIN - DIF BPF register values from 102_quant.dat*/
-{10200000, DIF_BPF_COEFF01, 0x00000002},
-{10200000, DIF_BPF_COEFF23, 0x0008fffe},
-{10200000, DIF_BPF_COEFF45, 0xffdfffe7},
-{10200000, DIF_BPF_COEFF67, 0x003f006e},
-{10200000, DIF_BPF_COEFF89, 0xffd6ff0f},
-{10200000, DIF_BPF_COEFF1011, 0xff96014a},
-{10200000, DIF_BPF_COEFF1213, 0x0197ff1f},
-{10200000, DIF_BPF_COEFF1415, 0xfd05ff3e},
-{10200000, DIF_BPF_COEFF1617, 0x03b0037c},
-{10200000, DIF_BPF_COEFF1819, 0xfd59f9b7},
-{10200000, DIF_BPF_COEFF2021, 0xff5d0781},
-{10200000, DIF_BPF_COEFF2223, 0x0585fa56},
-{10200000, DIF_BPF_COEFF2425, 0xf5e4006f},
-{10200000, DIF_BPF_COEFF2627, 0x0bf906c4},
-{10200000, DIF_BPF_COEFF2829, 0xf69df2e0},
-{10200000, DIF_BPF_COEFF3031, 0x02790fa2},
-{10200000, DIF_BPF_COEFF3233, 0x0688f35d},
-{10200000, DIF_BPF_COEFF3435, 0xf1e604d8},
-{10200000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 102_quant.dat*/
-
-
-/*case 10300000:*/
-/* BEGIN - DIF BPF register values from 103_quant.dat*/
-{10300000, DIF_BPF_COEFF01, 0xffff0001},
-{10300000, DIF_BPF_COEFF23, 0x00090005},
-{10300000, DIF_BPF_COEFF45, 0xffe4ffd6},
-{10300000, DIF_BPF_COEFF67, 0x0025007e},
-{10300000, DIF_BPF_COEFF89, 0x0014ff20},
-{10300000, DIF_BPF_COEFF1011, 0xff3c00f0},
-{10300000, DIF_BPF_COEFF1213, 0x01e1ffd0},
-{10300000, DIF_BPF_COEFF1415, 0xfd12fe5c},
-{10300000, DIF_BPF_COEFF1617, 0x03110433},
-{10300000, DIF_BPF_COEFF1819, 0xfe88f996},
-{10300000, DIF_BPF_COEFF2021, 0xfdf106d1},
-{10300000, DIF_BPF_COEFF2223, 0x06aafbb7},
-{10300000, DIF_BPF_COEFF2425, 0xf57efed8},
-{10300000, DIF_BPF_COEFF2627, 0x0b7e07ff},
-{10300000, DIF_BPF_COEFF2829, 0xf7b0f25e},
-{10300000, DIF_BPF_COEFF3031, 0x01560f7a},
-{10300000, DIF_BPF_COEFF3233, 0x0745f3c7},
-{10300000, DIF_BPF_COEFF3435, 0xf1ac04a4},
-{10300000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 103_quant.dat*/
-
-
-/*case 10400000:*/
-/* BEGIN - DIF BPF register values from 104_quant.dat*/
-{10400000, DIF_BPF_COEFF01, 0xffffffff},
-{10400000, DIF_BPF_COEFF23, 0x0008000c},
-{10400000, DIF_BPF_COEFF45, 0xffedffcb},
-{10400000, DIF_BPF_COEFF67, 0x0005007d},
-{10400000, DIF_BPF_COEFF89, 0x0050ff4c},
-{10400000, DIF_BPF_COEFF1011, 0xfef6007e},
-{10400000, DIF_BPF_COEFF1213, 0x01ff0086},
-{10400000, DIF_BPF_COEFF1415, 0xfd58fd97},
-{10400000, DIF_BPF_COEFF1617, 0x024104ad},
-{10400000, DIF_BPF_COEFF1819, 0xffcaf9c0},
-{10400000, DIF_BPF_COEFF2021, 0xfc9905e2},
-{10400000, DIF_BPF_COEFF2223, 0x079afd35},
-{10400000, DIF_BPF_COEFF2425, 0xf555fd46},
-{10400000, DIF_BPF_COEFF2627, 0x0ad50920},
-{10400000, DIF_BPF_COEFF2829, 0xf8d9f1f6},
-{10400000, DIF_BPF_COEFF3031, 0x00310f43},
-{10400000, DIF_BPF_COEFF3233, 0x07fdf435},
-{10400000, DIF_BPF_COEFF3435, 0xf174046f},
-{10400000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 104_quant.dat*/
-
-
-/*case 10500000:*/
-/* BEGIN - DIF BPF register values from 105_quant.dat*/
-{10500000, DIF_BPF_COEFF01, 0xfffffffe},
-{10500000, DIF_BPF_COEFF23, 0x00050011},
-{10500000, DIF_BPF_COEFF45, 0xfffaffc8},
-{10500000, DIF_BPF_COEFF67, 0xffe5006b},
-{10500000, DIF_BPF_COEFF89, 0x0082ff8c},
-{10500000, DIF_BPF_COEFF1011, 0xfecc0000},
-{10500000, DIF_BPF_COEFF1213, 0x01f00130},
-{10500000, DIF_BPF_COEFF1415, 0xfdd2fcfc},
-{10500000, DIF_BPF_COEFF1617, 0x014d04e3},
-{10500000, DIF_BPF_COEFF1819, 0x010efa32},
-{10500000, DIF_BPF_COEFF2021, 0xfb6404bf},
-{10500000, DIF_BPF_COEFF2223, 0x084efec5},
-{10500000, DIF_BPF_COEFF2425, 0xf569fbc2},
-{10500000, DIF_BPF_COEFF2627, 0x0a000a23},
-{10500000, DIF_BPF_COEFF2829, 0xfa15f1ab},
-{10500000, DIF_BPF_COEFF3031, 0xff0b0efc},
-{10500000, DIF_BPF_COEFF3233, 0x08b0f4a7},
-{10500000, DIF_BPF_COEFF3435, 0xf13f043a},
-{10500000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 105_quant.dat*/
-
-
-/*case 10600000:*/
-/* BEGIN - DIF BPF register values from 106_quant.dat*/
-{10600000, DIF_BPF_COEFF01, 0x0000fffd},
-{10600000, DIF_BPF_COEFF23, 0x00020012},
-{10600000, DIF_BPF_COEFF45, 0x0007ffcd},
-{10600000, DIF_BPF_COEFF67, 0xffc9004c},
-{10600000, DIF_BPF_COEFF89, 0x00a4ffd9},
-{10600000, DIF_BPF_COEFF1011, 0xfec3ff82},
-{10600000, DIF_BPF_COEFF1213, 0x01b401c1},
-{10600000, DIF_BPF_COEFF1415, 0xfe76fc97},
-{10600000, DIF_BPF_COEFF1617, 0x004404d2},
-{10600000, DIF_BPF_COEFF1819, 0x0245fae8},
-{10600000, DIF_BPF_COEFF2021, 0xfa5f0370},
-{10600000, DIF_BPF_COEFF2223, 0x08c1005f},
-{10600000, DIF_BPF_COEFF2425, 0xf5bcfa52},
-{10600000, DIF_BPF_COEFF2627, 0x09020b04},
-{10600000, DIF_BPF_COEFF2829, 0xfb60f17b},
-{10600000, DIF_BPF_COEFF3031, 0xfde70ea6},
-{10600000, DIF_BPF_COEFF3233, 0x095df51e},
-{10600000, DIF_BPF_COEFF3435, 0xf10c0405},
-{10600000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 106_quant.dat*/
-
-
-/*case 10700000:*/
-/* BEGIN - DIF BPF register values from 107_quant.dat*/
-{10700000, DIF_BPF_COEFF01, 0x0000fffd},
-{10700000, DIF_BPF_COEFF23, 0xffff0011},
-{10700000, DIF_BPF_COEFF45, 0x0014ffdb},
-{10700000, DIF_BPF_COEFF67, 0xffb40023},
-{10700000, DIF_BPF_COEFF89, 0x00b2002a},
-{10700000, DIF_BPF_COEFF1011, 0xfedbff10},
-{10700000, DIF_BPF_COEFF1213, 0x0150022d},
-{10700000, DIF_BPF_COEFF1415, 0xff38fc6f},
-{10700000, DIF_BPF_COEFF1617, 0xff36047b},
-{10700000, DIF_BPF_COEFF1819, 0x035efbda},
-{10700000, DIF_BPF_COEFF2021, 0xf9940202},
-{10700000, DIF_BPF_COEFF2223, 0x08ee01f5},
-{10700000, DIF_BPF_COEFF2425, 0xf649f8fe},
-{10700000, DIF_BPF_COEFF2627, 0x07e10bc2},
-{10700000, DIF_BPF_COEFF2829, 0xfcb6f169},
-{10700000, DIF_BPF_COEFF3031, 0xfcc60e42},
-{10700000, DIF_BPF_COEFF3233, 0x0a04f599},
-{10700000, DIF_BPF_COEFF3435, 0xf0db03d0},
-{10700000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 107_quant.dat*/
-
-
-/*case 10800000:*/
-/* BEGIN - DIF BPF register values from 108_quant.dat*/
-{10800000, DIF_BPF_COEFF01, 0x0000fffd},
-{10800000, DIF_BPF_COEFF23, 0xfffb000d},
-{10800000, DIF_BPF_COEFF45, 0x001dffed},
-{10800000, DIF_BPF_COEFF67, 0xffaafff5},
-{10800000, DIF_BPF_COEFF89, 0x00aa0077},
-{10800000, DIF_BPF_COEFF1011, 0xff13feb6},
-{10800000, DIF_BPF_COEFF1213, 0x00ce026b},
-{10800000, DIF_BPF_COEFF1415, 0x000afc85},
-{10800000, DIF_BPF_COEFF1617, 0xfe3503e3},
-{10800000, DIF_BPF_COEFF1819, 0x044cfcfb},
-{10800000, DIF_BPF_COEFF2021, 0xf90c0082},
-{10800000, DIF_BPF_COEFF2223, 0x08d5037f},
-{10800000, DIF_BPF_COEFF2425, 0xf710f7cc},
-{10800000, DIF_BPF_COEFF2627, 0x069f0c59},
-{10800000, DIF_BPF_COEFF2829, 0xfe16f173},
-{10800000, DIF_BPF_COEFF3031, 0xfbaa0dcf},
-{10800000, DIF_BPF_COEFF3233, 0x0aa5f617},
-{10800000, DIF_BPF_COEFF3435, 0xf0ad039b},
-{10800000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 108_quant.dat*/
-
-
-/*case 10900000:*/
-/* BEGIN - DIF BPF register values from 109_quant.dat*/
-{10900000, DIF_BPF_COEFF01, 0x0000fffe},
-{10900000, DIF_BPF_COEFF23, 0xfff90006},
-{10900000, DIF_BPF_COEFF45, 0x00210003},
-{10900000, DIF_BPF_COEFF67, 0xffacffc8},
-{10900000, DIF_BPF_COEFF89, 0x008e00b6},
-{10900000, DIF_BPF_COEFF1011, 0xff63fe7c},
-{10900000, DIF_BPF_COEFF1213, 0x003a0275},
-{10900000, DIF_BPF_COEFF1415, 0x00dafcda},
-{10900000, DIF_BPF_COEFF1617, 0xfd510313},
-{10900000, DIF_BPF_COEFF1819, 0x0501fe40},
-{10900000, DIF_BPF_COEFF2021, 0xf8cbfefd},
-{10900000, DIF_BPF_COEFF2223, 0x087604f0},
-{10900000, DIF_BPF_COEFF2425, 0xf80af6c2},
-{10900000, DIF_BPF_COEFF2627, 0x05430cc8},
-{10900000, DIF_BPF_COEFF2829, 0xff7af19a},
-{10900000, DIF_BPF_COEFF3031, 0xfa940d4e},
-{10900000, DIF_BPF_COEFF3233, 0x0b3ff699},
-{10900000, DIF_BPF_COEFF3435, 0xf0810365},
-{10900000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 109_quant.dat*/
-
-
-/*case 11000000:*/
-/* BEGIN - DIF BPF register values from 110_quant.dat*/
-{11000000, DIF_BPF_COEFF01, 0x0001ffff},
-{11000000, DIF_BPF_COEFF23, 0xfff8ffff},
-{11000000, DIF_BPF_COEFF45, 0x00210018},
-{11000000, DIF_BPF_COEFF67, 0xffbaffa3},
-{11000000, DIF_BPF_COEFF89, 0x006000e1},
-{11000000, DIF_BPF_COEFF1011, 0xffc4fe68},
-{11000000, DIF_BPF_COEFF1213, 0xffa0024b},
-{11000000, DIF_BPF_COEFF1415, 0x019afd66},
-{11000000, DIF_BPF_COEFF1617, 0xfc990216},
-{11000000, DIF_BPF_COEFF1819, 0x0575ff99},
-{11000000, DIF_BPF_COEFF2021, 0xf8d4fd81},
-{11000000, DIF_BPF_COEFF2223, 0x07d40640},
-{11000000, DIF_BPF_COEFF2425, 0xf932f5e6},
-{11000000, DIF_BPF_COEFF2627, 0x03d20d0d},
-{11000000, DIF_BPF_COEFF2829, 0x00dff1de},
-{11000000, DIF_BPF_COEFF3031, 0xf9860cbf},
-{11000000, DIF_BPF_COEFF3233, 0x0bd1f71e},
-{11000000, DIF_BPF_COEFF3435, 0xf058032f},
-{11000000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 110_quant.dat*/
-
-
-/*case 11100000:*/
-/* BEGIN - DIF BPF register values from 111_quant.dat*/
-{11100000, DIF_BPF_COEFF01, 0x00010000},
-{11100000, DIF_BPF_COEFF23, 0xfff8fff8},
-{11100000, DIF_BPF_COEFF45, 0x001b0029},
-{11100000, DIF_BPF_COEFF67, 0xffd1ff8a},
-{11100000, DIF_BPF_COEFF89, 0x002600f2},
-{11100000, DIF_BPF_COEFF1011, 0x002cfe7c},
-{11100000, DIF_BPF_COEFF1213, 0xff0f01f0},
-{11100000, DIF_BPF_COEFF1415, 0x023bfe20},
-{11100000, DIF_BPF_COEFF1617, 0xfc1700fa},
-{11100000, DIF_BPF_COEFF1819, 0x05a200f7},
-{11100000, DIF_BPF_COEFF2021, 0xf927fc1c},
-{11100000, DIF_BPF_COEFF2223, 0x06f40765},
-{11100000, DIF_BPF_COEFF2425, 0xfa82f53b},
-{11100000, DIF_BPF_COEFF2627, 0x02510d27},
-{11100000, DIF_BPF_COEFF2829, 0x0243f23d},
-{11100000, DIF_BPF_COEFF3031, 0xf8810c24},
-{11100000, DIF_BPF_COEFF3233, 0x0c5cf7a7},
-{11100000, DIF_BPF_COEFF3435, 0xf03102fa},
-{11100000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 111_quant.dat*/
-
-
-/*case 11200000:*/
-/* BEGIN - DIF BPF register values from 112_quant.dat*/
-{11200000, DIF_BPF_COEFF01, 0x00010002},
-{11200000, DIF_BPF_COEFF23, 0xfffafff2},
-{11200000, DIF_BPF_COEFF45, 0x00110035},
-{11200000, DIF_BPF_COEFF67, 0xfff0ff81},
-{11200000, DIF_BPF_COEFF89, 0xffe700e7},
-{11200000, DIF_BPF_COEFF1011, 0x008ffeb6},
-{11200000, DIF_BPF_COEFF1213, 0xfe94016d},
-{11200000, DIF_BPF_COEFF1415, 0x02b0fefb},
-{11200000, DIF_BPF_COEFF1617, 0xfbd3ffd1},
-{11200000, DIF_BPF_COEFF1819, 0x05850249},
-{11200000, DIF_BPF_COEFF2021, 0xf9c1fadb},
-{11200000, DIF_BPF_COEFF2223, 0x05de0858},
-{11200000, DIF_BPF_COEFF2425, 0xfbf2f4c4},
-{11200000, DIF_BPF_COEFF2627, 0x00c70d17},
-{11200000, DIF_BPF_COEFF2829, 0x03a0f2b8},
-{11200000, DIF_BPF_COEFF3031, 0xf7870b7c},
-{11200000, DIF_BPF_COEFF3233, 0x0cdff833},
-{11200000, DIF_BPF_COEFF3435, 0xf00d02c4},
-{11200000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 112_quant.dat*/
-
-
-/*case 11300000:*/
-/* BEGIN - DIF BPF register values from 113_quant.dat*/
-{11300000, DIF_BPF_COEFF01, 0x00000003},
-{11300000, DIF_BPF_COEFF23, 0xfffdffee},
-{11300000, DIF_BPF_COEFF45, 0x00040038},
-{11300000, DIF_BPF_COEFF67, 0x0010ff88},
-{11300000, DIF_BPF_COEFF89, 0xffac00c2},
-{11300000, DIF_BPF_COEFF1011, 0x00e2ff10},
-{11300000, DIF_BPF_COEFF1213, 0xfe3900cb},
-{11300000, DIF_BPF_COEFF1415, 0x02f1ffe9},
-{11300000, DIF_BPF_COEFF1617, 0xfbd3feaa},
-{11300000, DIF_BPF_COEFF1819, 0x05210381},
-{11300000, DIF_BPF_COEFF2021, 0xfa9cf9c8},
-{11300000, DIF_BPF_COEFF2223, 0x04990912},
-{11300000, DIF_BPF_COEFF2425, 0xfd7af484},
-{11300000, DIF_BPF_COEFF2627, 0xff390cdb},
-{11300000, DIF_BPF_COEFF2829, 0x04f4f34d},
-{11300000, DIF_BPF_COEFF3031, 0xf69a0ac9},
-{11300000, DIF_BPF_COEFF3233, 0x0d5af8c1},
-{11300000, DIF_BPF_COEFF3435, 0xefec028e},
-{11300000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 113_quant.dat*/
-
-
-/*case 11400000:*/
-/* BEGIN - DIF BPF register values from 114_quant.dat*/
-{11400000, DIF_BPF_COEFF01, 0x00000003},
-{11400000, DIF_BPF_COEFF23, 0x0000ffee},
-{11400000, DIF_BPF_COEFF45, 0xfff60033},
-{11400000, DIF_BPF_COEFF67, 0x002fff9f},
-{11400000, DIF_BPF_COEFF89, 0xff7b0087},
-{11400000, DIF_BPF_COEFF1011, 0x011eff82},
-{11400000, DIF_BPF_COEFF1213, 0xfe080018},
-{11400000, DIF_BPF_COEFF1415, 0x02f900d8},
-{11400000, DIF_BPF_COEFF1617, 0xfc17fd96},
-{11400000, DIF_BPF_COEFF1819, 0x04790490},
-{11400000, DIF_BPF_COEFF2021, 0xfbadf8ed},
-{11400000, DIF_BPF_COEFF2223, 0x032f098e},
-{11400000, DIF_BPF_COEFF2425, 0xff10f47d},
-{11400000, DIF_BPF_COEFF2627, 0xfdaf0c75},
-{11400000, DIF_BPF_COEFF2829, 0x063cf3fc},
-{11400000, DIF_BPF_COEFF3031, 0xf5ba0a0b},
-{11400000, DIF_BPF_COEFF3233, 0x0dccf952},
-{11400000, DIF_BPF_COEFF3435, 0xefcd0258},
-{11400000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 114_quant.dat*/
-
-
-/*case 11500000:*/
-/* BEGIN - DIF BPF register values from 115_quant.dat*/
-{11500000, DIF_BPF_COEFF01, 0x00000003},
-{11500000, DIF_BPF_COEFF23, 0x0004fff1},
-{11500000, DIF_BPF_COEFF45, 0xffea0026},
-{11500000, DIF_BPF_COEFF67, 0x0046ffc3},
-{11500000, DIF_BPF_COEFF89, 0xff5a003c},
-{11500000, DIF_BPF_COEFF1011, 0x013b0000},
-{11500000, DIF_BPF_COEFF1213, 0xfe04ff63},
-{11500000, DIF_BPF_COEFF1415, 0x02c801b8},
-{11500000, DIF_BPF_COEFF1617, 0xfc99fca6},
-{11500000, DIF_BPF_COEFF1819, 0x0397056a},
-{11500000, DIF_BPF_COEFF2021, 0xfcecf853},
-{11500000, DIF_BPF_COEFF2223, 0x01ad09c9},
-{11500000, DIF_BPF_COEFF2425, 0x00acf4ad},
-{11500000, DIF_BPF_COEFF2627, 0xfc2e0be7},
-{11500000, DIF_BPF_COEFF2829, 0x0773f4c2},
-{11500000, DIF_BPF_COEFF3031, 0xf4e90943},
-{11500000, DIF_BPF_COEFF3233, 0x0e35f9e6},
-{11500000, DIF_BPF_COEFF3435, 0xefb10221},
-{11500000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 115_quant.dat*/
-
-
-/*case 11600000:*/
-/* BEGIN - DIF BPF register values from 116_quant.dat*/
-{11600000, DIF_BPF_COEFF01, 0x00000002},
-{11600000, DIF_BPF_COEFF23, 0x0007fff6},
-{11600000, DIF_BPF_COEFF45, 0xffe20014},
-{11600000, DIF_BPF_COEFF67, 0x0054ffee},
-{11600000, DIF_BPF_COEFF89, 0xff4effeb},
-{11600000, DIF_BPF_COEFF1011, 0x0137007e},
-{11600000, DIF_BPF_COEFF1213, 0xfe2efebb},
-{11600000, DIF_BPF_COEFF1415, 0x0260027a},
-{11600000, DIF_BPF_COEFF1617, 0xfd51fbe6},
-{11600000, DIF_BPF_COEFF1819, 0x02870605},
-{11600000, DIF_BPF_COEFF2021, 0xfe4af7fe},
-{11600000, DIF_BPF_COEFF2223, 0x001d09c1},
-{11600000, DIF_BPF_COEFF2425, 0x0243f515},
-{11600000, DIF_BPF_COEFF2627, 0xfabd0b32},
-{11600000, DIF_BPF_COEFF2829, 0x0897f59e},
-{11600000, DIF_BPF_COEFF3031, 0xf4280871},
-{11600000, DIF_BPF_COEFF3233, 0x0e95fa7c},
-{11600000, DIF_BPF_COEFF3435, 0xef9701eb},
-{11600000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 116_quant.dat*/
-
-
-/*case 11700000:*/
-/* BEGIN - DIF BPF register values from 117_quant.dat*/
-{11700000, DIF_BPF_COEFF01, 0xffff0001},
-{11700000, DIF_BPF_COEFF23, 0x0008fffd},
-{11700000, DIF_BPF_COEFF45, 0xffdeffff},
-{11700000, DIF_BPF_COEFF67, 0x0056001d},
-{11700000, DIF_BPF_COEFF89, 0xff57ff9c},
-{11700000, DIF_BPF_COEFF1011, 0x011300f0},
-{11700000, DIF_BPF_COEFF1213, 0xfe82fe2e},
-{11700000, DIF_BPF_COEFF1415, 0x01ca0310},
-{11700000, DIF_BPF_COEFF1617, 0xfe35fb62},
-{11700000, DIF_BPF_COEFF1819, 0x0155065a},
-{11700000, DIF_BPF_COEFF2021, 0xffbaf7f2},
-{11700000, DIF_BPF_COEFF2223, 0xfe8c0977},
-{11700000, DIF_BPF_COEFF2425, 0x03cef5b2},
-{11700000, DIF_BPF_COEFF2627, 0xf9610a58},
-{11700000, DIF_BPF_COEFF2829, 0x09a5f68f},
-{11700000, DIF_BPF_COEFF3031, 0xf3790797},
-{11700000, DIF_BPF_COEFF3233, 0x0eebfb14},
-{11700000, DIF_BPF_COEFF3435, 0xef8001b5},
-{11700000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 117_quant.dat*/
-
-
-/*case 11800000:*/
-/* BEGIN - DIF BPF register values from 118_quant.dat*/
-{11800000, DIF_BPF_COEFF01, 0xffff0000},
-{11800000, DIF_BPF_COEFF23, 0x00080004},
-{11800000, DIF_BPF_COEFF45, 0xffe0ffe9},
-{11800000, DIF_BPF_COEFF67, 0x004c0047},
-{11800000, DIF_BPF_COEFF89, 0xff75ff58},
-{11800000, DIF_BPF_COEFF1011, 0x00d1014a},
-{11800000, DIF_BPF_COEFF1213, 0xfef9fdc8},
-{11800000, DIF_BPF_COEFF1415, 0x0111036f},
-{11800000, DIF_BPF_COEFF1617, 0xff36fb21},
-{11800000, DIF_BPF_COEFF1819, 0x00120665},
-{11800000, DIF_BPF_COEFF2021, 0x012df82e},
-{11800000, DIF_BPF_COEFF2223, 0xfd0708ec},
-{11800000, DIF_BPF_COEFF2425, 0x0542f682},
-{11800000, DIF_BPF_COEFF2627, 0xf81f095c},
-{11800000, DIF_BPF_COEFF2829, 0x0a9af792},
-{11800000, DIF_BPF_COEFF3031, 0xf2db06b5},
-{11800000, DIF_BPF_COEFF3233, 0x0f38fbad},
-{11800000, DIF_BPF_COEFF3435, 0xef6c017e},
-{11800000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 118_quant.dat*/
-
-
-/*case 11900000:*/
-/* BEGIN - DIF BPF register values from 119_quant.dat*/
-{11900000, DIF_BPF_COEFF01, 0xffffffff},
-{11900000, DIF_BPF_COEFF23, 0x0007000b},
-{11900000, DIF_BPF_COEFF45, 0xffe7ffd8},
-{11900000, DIF_BPF_COEFF67, 0x00370068},
-{11900000, DIF_BPF_COEFF89, 0xffa4ff28},
-{11900000, DIF_BPF_COEFF1011, 0x00790184},
-{11900000, DIF_BPF_COEFF1213, 0xff87fd91},
-{11900000, DIF_BPF_COEFF1415, 0x00430392},
-{11900000, DIF_BPF_COEFF1617, 0x0044fb26},
-{11900000, DIF_BPF_COEFF1819, 0xfece0626},
-{11900000, DIF_BPF_COEFF2021, 0x0294f8b2},
-{11900000, DIF_BPF_COEFF2223, 0xfb990825},
-{11900000, DIF_BPF_COEFF2425, 0x0698f77f},
-{11900000, DIF_BPF_COEFF2627, 0xf6fe0842},
-{11900000, DIF_BPF_COEFF2829, 0x0b73f8a7},
-{11900000, DIF_BPF_COEFF3031, 0xf25105cd},
-{11900000, DIF_BPF_COEFF3233, 0x0f7bfc48},
-{11900000, DIF_BPF_COEFF3435, 0xef5a0148},
-{11900000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 119_quant.dat*/
-
-
-/*case 12000000:*/
-/* BEGIN - DIF BPF register values from 120_quant.dat*/
-{12000000, DIF_BPF_COEFF01, 0x0000fffe},
-{12000000, DIF_BPF_COEFF23, 0x00050010},
-{12000000, DIF_BPF_COEFF45, 0xfff2ffcc},
-{12000000, DIF_BPF_COEFF67, 0x001b007b},
-{12000000, DIF_BPF_COEFF89, 0xffdfff10},
-{12000000, DIF_BPF_COEFF1011, 0x00140198},
-{12000000, DIF_BPF_COEFF1213, 0x0020fd8e},
-{12000000, DIF_BPF_COEFF1415, 0xff710375},
-{12000000, DIF_BPF_COEFF1617, 0x014dfb73},
-{12000000, DIF_BPF_COEFF1819, 0xfd9a059f},
-{12000000, DIF_BPF_COEFF2021, 0x03e0f978},
-{12000000, DIF_BPF_COEFF2223, 0xfa4e0726},
-{12000000, DIF_BPF_COEFF2425, 0x07c8f8a7},
-{12000000, DIF_BPF_COEFF2627, 0xf600070c},
-{12000000, DIF_BPF_COEFF2829, 0x0c2ff9c9},
-{12000000, DIF_BPF_COEFF3031, 0xf1db04de},
-{12000000, DIF_BPF_COEFF3233, 0x0fb4fce5},
-{12000000, DIF_BPF_COEFF3435, 0xef4b0111},
-{12000000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 120_quant.dat*/
-
-
-/*case 12100000:*/
-/* BEGIN - DIF BPF register values from 121_quant.dat*/
-{12100000, DIF_BPF_COEFF01, 0x0000fffd},
-{12100000, DIF_BPF_COEFF23, 0x00010012},
-{12100000, DIF_BPF_COEFF45, 0xffffffc8},
-{12100000, DIF_BPF_COEFF67, 0xfffb007e},
-{12100000, DIF_BPF_COEFF89, 0x001dff14},
-{12100000, DIF_BPF_COEFF1011, 0xffad0184},
-{12100000, DIF_BPF_COEFF1213, 0x00b7fdbe},
-{12100000, DIF_BPF_COEFF1415, 0xfea9031b},
-{12100000, DIF_BPF_COEFF1617, 0x0241fc01},
-{12100000, DIF_BPF_COEFF1819, 0xfc8504d6},
-{12100000, DIF_BPF_COEFF2021, 0x0504fa79},
-{12100000, DIF_BPF_COEFF2223, 0xf93005f6},
-{12100000, DIF_BPF_COEFF2425, 0x08caf9f2},
-{12100000, DIF_BPF_COEFF2627, 0xf52b05c0},
-{12100000, DIF_BPF_COEFF2829, 0x0ccbfaf9},
-{12100000, DIF_BPF_COEFF3031, 0xf17903eb},
-{12100000, DIF_BPF_COEFF3233, 0x0fe3fd83},
-{12100000, DIF_BPF_COEFF3435, 0xef3f00db},
-{12100000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 121_quant.dat*/
-
-
-/*case 12200000:*/
-/* BEGIN - DIF BPF register values from 122_quant.dat*/
-{12200000, DIF_BPF_COEFF01, 0x0000fffd},
-{12200000, DIF_BPF_COEFF23, 0xfffe0011},
-{12200000, DIF_BPF_COEFF45, 0x000cffcc},
-{12200000, DIF_BPF_COEFF67, 0xffdb0071},
-{12200000, DIF_BPF_COEFF89, 0x0058ff32},
-{12200000, DIF_BPF_COEFF1011, 0xff4f014a},
-{12200000, DIF_BPF_COEFF1213, 0x013cfe1f},
-{12200000, DIF_BPF_COEFF1415, 0xfdfb028a},
-{12200000, DIF_BPF_COEFF1617, 0x0311fcc9},
-{12200000, DIF_BPF_COEFF1819, 0xfb9d03d6},
-{12200000, DIF_BPF_COEFF2021, 0x05f4fbad},
-{12200000, DIF_BPF_COEFF2223, 0xf848049d},
-{12200000, DIF_BPF_COEFF2425, 0x0999fb5b},
-{12200000, DIF_BPF_COEFF2627, 0xf4820461},
-{12200000, DIF_BPF_COEFF2829, 0x0d46fc32},
-{12200000, DIF_BPF_COEFF3031, 0xf12d02f4},
-{12200000, DIF_BPF_COEFF3233, 0x1007fe21},
-{12200000, DIF_BPF_COEFF3435, 0xef3600a4},
-{12200000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 122_quant.dat*/
-
-
-/*case 12300000:*/
-/* BEGIN - DIF BPF register values from 123_quant.dat*/
-{12300000, DIF_BPF_COEFF01, 0x0000fffe},
-{12300000, DIF_BPF_COEFF23, 0xfffa000e},
-{12300000, DIF_BPF_COEFF45, 0x0017ffd9},
-{12300000, DIF_BPF_COEFF67, 0xffc10055},
-{12300000, DIF_BPF_COEFF89, 0x0088ff68},
-{12300000, DIF_BPF_COEFF1011, 0xff0400f0},
-{12300000, DIF_BPF_COEFF1213, 0x01a6fea7},
-{12300000, DIF_BPF_COEFF1415, 0xfd7501cc},
-{12300000, DIF_BPF_COEFF1617, 0x03b0fdc0},
-{12300000, DIF_BPF_COEFF1819, 0xfaef02a8},
-{12300000, DIF_BPF_COEFF2021, 0x06a7fd07},
-{12300000, DIF_BPF_COEFF2223, 0xf79d0326},
-{12300000, DIF_BPF_COEFF2425, 0x0a31fcda},
-{12300000, DIF_BPF_COEFF2627, 0xf40702f3},
-{12300000, DIF_BPF_COEFF2829, 0x0d9ffd72},
-{12300000, DIF_BPF_COEFF3031, 0xf0f601fa},
-{12300000, DIF_BPF_COEFF3233, 0x1021fec0},
-{12300000, DIF_BPF_COEFF3435, 0xef2f006d},
-{12300000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 123_quant.dat*/
-
-
-/*case 12400000:*/
-/* BEGIN - DIF BPF register values from 124_quant.dat*/
-{12400000, DIF_BPF_COEFF01, 0x0001ffff},
-{12400000, DIF_BPF_COEFF23, 0xfff80007},
-{12400000, DIF_BPF_COEFF45, 0x001fffeb},
-{12400000, DIF_BPF_COEFF67, 0xffaf002d},
-{12400000, DIF_BPF_COEFF89, 0x00a8ffb0},
-{12400000, DIF_BPF_COEFF1011, 0xfed3007e},
-{12400000, DIF_BPF_COEFF1213, 0x01e9ff4c},
-{12400000, DIF_BPF_COEFF1415, 0xfd2000ee},
-{12400000, DIF_BPF_COEFF1617, 0x0413fed8},
-{12400000, DIF_BPF_COEFF1819, 0xfa82015c},
-{12400000, DIF_BPF_COEFF2021, 0x0715fe7d},
-{12400000, DIF_BPF_COEFF2223, 0xf7340198},
-{12400000, DIF_BPF_COEFF2425, 0x0a8dfe69},
-{12400000, DIF_BPF_COEFF2627, 0xf3bd017c},
-{12400000, DIF_BPF_COEFF2829, 0x0dd5feb8},
-{12400000, DIF_BPF_COEFF3031, 0xf0d500fd},
-{12400000, DIF_BPF_COEFF3233, 0x1031ff60},
-{12400000, DIF_BPF_COEFF3435, 0xef2b0037},
-{12400000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 124_quant.dat*/
-
-
-/*case 12500000:*/
-/* BEGIN - DIF BPF register values from 125_quant.dat*/
-{12500000, DIF_BPF_COEFF01, 0x00010000},
-{12500000, DIF_BPF_COEFF23, 0xfff70000},
-{12500000, DIF_BPF_COEFF45, 0x00220000},
-{12500000, DIF_BPF_COEFF67, 0xffa90000},
-{12500000, DIF_BPF_COEFF89, 0x00b30000},
-{12500000, DIF_BPF_COEFF1011, 0xfec20000},
-{12500000, DIF_BPF_COEFF1213, 0x02000000},
-{12500000, DIF_BPF_COEFF1415, 0xfd030000},
-{12500000, DIF_BPF_COEFF1617, 0x04350000},
-{12500000, DIF_BPF_COEFF1819, 0xfa5e0000},
-{12500000, DIF_BPF_COEFF2021, 0x073b0000},
-{12500000, DIF_BPF_COEFF2223, 0xf7110000},
-{12500000, DIF_BPF_COEFF2425, 0x0aac0000},
-{12500000, DIF_BPF_COEFF2627, 0xf3a40000},
-{12500000, DIF_BPF_COEFF2829, 0x0de70000},
-{12500000, DIF_BPF_COEFF3031, 0xf0c90000},
-{12500000, DIF_BPF_COEFF3233, 0x10360000},
-{12500000, DIF_BPF_COEFF3435, 0xef290000},
-{12500000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 125_quant.dat*/
-
-
-/*case 12600000:*/
-/* BEGIN - DIF BPF register values from 126_quant.dat*/
-{12600000, DIF_BPF_COEFF01, 0x00010001},
-{12600000, DIF_BPF_COEFF23, 0xfff8fff9},
-{12600000, DIF_BPF_COEFF45, 0x001f0015},
-{12600000, DIF_BPF_COEFF67, 0xffafffd3},
-{12600000, DIF_BPF_COEFF89, 0x00a80050},
-{12600000, DIF_BPF_COEFF1011, 0xfed3ff82},
-{12600000, DIF_BPF_COEFF1213, 0x01e900b4},
-{12600000, DIF_BPF_COEFF1415, 0xfd20ff12},
-{12600000, DIF_BPF_COEFF1617, 0x04130128},
-{12600000, DIF_BPF_COEFF1819, 0xfa82fea4},
-{12600000, DIF_BPF_COEFF2021, 0x07150183},
-{12600000, DIF_BPF_COEFF2223, 0xf734fe68},
-{12600000, DIF_BPF_COEFF2425, 0x0a8d0197},
-{12600000, DIF_BPF_COEFF2627, 0xf3bdfe84},
-{12600000, DIF_BPF_COEFF2829, 0x0dd50148},
-{12600000, DIF_BPF_COEFF3031, 0xf0d5ff03},
-{12600000, DIF_BPF_COEFF3233, 0x103100a0},
-{12600000, DIF_BPF_COEFF3435, 0xef2bffc9},
-{12600000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 126_quant.dat*/
-
-
-/*case 12700000:*/
-/* BEGIN - DIF BPF register values from 127_quant.dat*/
-{12700000, DIF_BPF_COEFF01, 0x00000002},
-{12700000, DIF_BPF_COEFF23, 0xfffafff2},
-{12700000, DIF_BPF_COEFF45, 0x00170027},
-{12700000, DIF_BPF_COEFF67, 0xffc1ffab},
-{12700000, DIF_BPF_COEFF89, 0x00880098},
-{12700000, DIF_BPF_COEFF1011, 0xff04ff10},
-{12700000, DIF_BPF_COEFF1213, 0x01a60159},
-{12700000, DIF_BPF_COEFF1415, 0xfd75fe34},
-{12700000, DIF_BPF_COEFF1617, 0x03b00240},
-{12700000, DIF_BPF_COEFF1819, 0xfaeffd58},
-{12700000, DIF_BPF_COEFF2021, 0x06a702f9},
-{12700000, DIF_BPF_COEFF2223, 0xf79dfcda},
-{12700000, DIF_BPF_COEFF2425, 0x0a310326},
-{12700000, DIF_BPF_COEFF2627, 0xf407fd0d},
-{12700000, DIF_BPF_COEFF2829, 0x0d9f028e},
-{12700000, DIF_BPF_COEFF3031, 0xf0f6fe06},
-{12700000, DIF_BPF_COEFF3233, 0x10210140},
-{12700000, DIF_BPF_COEFF3435, 0xef2fff93},
-{12700000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 127_quant.dat*/
-
-
-/*case 12800000:*/
-/* BEGIN - DIF BPF register values from 128_quant.dat*/
-{12800000, DIF_BPF_COEFF01, 0x00000003},
-{12800000, DIF_BPF_COEFF23, 0xfffeffef},
-{12800000, DIF_BPF_COEFF45, 0x000c0034},
-{12800000, DIF_BPF_COEFF67, 0xffdbff8f},
-{12800000, DIF_BPF_COEFF89, 0x005800ce},
-{12800000, DIF_BPF_COEFF1011, 0xff4ffeb6},
-{12800000, DIF_BPF_COEFF1213, 0x013c01e1},
-{12800000, DIF_BPF_COEFF1415, 0xfdfbfd76},
-{12800000, DIF_BPF_COEFF1617, 0x03110337},
-{12800000, DIF_BPF_COEFF1819, 0xfb9dfc2a},
-{12800000, DIF_BPF_COEFF2021, 0x05f40453},
-{12800000, DIF_BPF_COEFF2223, 0xf848fb63},
-{12800000, DIF_BPF_COEFF2425, 0x099904a5},
-{12800000, DIF_BPF_COEFF2627, 0xf482fb9f},
-{12800000, DIF_BPF_COEFF2829, 0x0d4603ce},
-{12800000, DIF_BPF_COEFF3031, 0xf12dfd0c},
-{12800000, DIF_BPF_COEFF3233, 0x100701df},
-{12800000, DIF_BPF_COEFF3435, 0xef36ff5c},
-{12800000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 128_quant.dat*/
-
-
-/*case 12900000:*/
-/* BEGIN - DIF BPF register values from 129_quant.dat*/
-{12900000, DIF_BPF_COEFF01, 0x00000003},
-{12900000, DIF_BPF_COEFF23, 0x0001ffee},
-{12900000, DIF_BPF_COEFF45, 0xffff0038},
-{12900000, DIF_BPF_COEFF67, 0xfffbff82},
-{12900000, DIF_BPF_COEFF89, 0x001d00ec},
-{12900000, DIF_BPF_COEFF1011, 0xffadfe7c},
-{12900000, DIF_BPF_COEFF1213, 0x00b70242},
-{12900000, DIF_BPF_COEFF1415, 0xfea9fce5},
-{12900000, DIF_BPF_COEFF1617, 0x024103ff},
-{12900000, DIF_BPF_COEFF1819, 0xfc85fb2a},
-{12900000, DIF_BPF_COEFF2021, 0x05040587},
-{12900000, DIF_BPF_COEFF2223, 0xf930fa0a},
-{12900000, DIF_BPF_COEFF2425, 0x08ca060e},
-{12900000, DIF_BPF_COEFF2627, 0xf52bfa40},
-{12900000, DIF_BPF_COEFF2829, 0x0ccb0507},
-{12900000, DIF_BPF_COEFF3031, 0xf179fc15},
-{12900000, DIF_BPF_COEFF3233, 0x0fe3027d},
-{12900000, DIF_BPF_COEFF3435, 0xef3fff25},
-{12900000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 129_quant.dat*/
-
-
-/*case 113000000:*/
-/* BEGIN - DIF BPF register values from 130_quant.dat*/
-{13000000, DIF_BPF_COEFF01, 0x00000002},
-{13000000, DIF_BPF_COEFF23, 0x0005fff0},
-{13000000, DIF_BPF_COEFF45, 0xfff20034},
-{13000000, DIF_BPF_COEFF67, 0x001bff85},
-{13000000, DIF_BPF_COEFF89, 0xffdf00f0},
-{13000000, DIF_BPF_COEFF1011, 0x0014fe68},
-{13000000, DIF_BPF_COEFF1213, 0x00200272},
-{13000000, DIF_BPF_COEFF1415, 0xff71fc8b},
-{13000000, DIF_BPF_COEFF1617, 0x014d048d},
-{13000000, DIF_BPF_COEFF1819, 0xfd9afa61},
-{13000000, DIF_BPF_COEFF2021, 0x03e00688},
-{13000000, DIF_BPF_COEFF2223, 0xfa4ef8da},
-{13000000, DIF_BPF_COEFF2425, 0x07c80759},
-{13000000, DIF_BPF_COEFF2627, 0xf600f8f4},
-{13000000, DIF_BPF_COEFF2829, 0x0c2f0637},
-{13000000, DIF_BPF_COEFF3031, 0xf1dbfb22},
-{13000000, DIF_BPF_COEFF3233, 0x0fb4031b},
-{13000000, DIF_BPF_COEFF3435, 0xef4bfeef},
-{13000000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 130_quant.dat*/
-
-
-/*case 13100000:*/
-/* BEGIN - DIF BPF register values from 131_quant.dat*/
-{13100000, DIF_BPF_COEFF01, 0xffff0001},
-{13100000, DIF_BPF_COEFF23, 0x0007fff5},
-{13100000, DIF_BPF_COEFF45, 0xffe70028},
-{13100000, DIF_BPF_COEFF67, 0x0037ff98},
-{13100000, DIF_BPF_COEFF89, 0xffa400d8},
-{13100000, DIF_BPF_COEFF1011, 0x0079fe7c},
-{13100000, DIF_BPF_COEFF1213, 0xff87026f},
-{13100000, DIF_BPF_COEFF1415, 0x0043fc6e},
-{13100000, DIF_BPF_COEFF1617, 0x004404da},
-{13100000, DIF_BPF_COEFF1819, 0xfecef9da},
-{13100000, DIF_BPF_COEFF2021, 0x0294074e},
-{13100000, DIF_BPF_COEFF2223, 0xfb99f7db},
-{13100000, DIF_BPF_COEFF2425, 0x06980881},
-{13100000, DIF_BPF_COEFF2627, 0xf6fef7be},
-{13100000, DIF_BPF_COEFF2829, 0x0b730759},
-{13100000, DIF_BPF_COEFF3031, 0xf251fa33},
-{13100000, DIF_BPF_COEFF3233, 0x0f7b03b8},
-{13100000, DIF_BPF_COEFF3435, 0xef5afeb8},
-{13100000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 131_quant.dat*/
-
-
-/*case 13200000:*/
-/* BEGIN - DIF BPF register values from 132_quant.dat*/
-{13200000, DIF_BPF_COEFF01, 0xffff0000},
-{13200000, DIF_BPF_COEFF23, 0x0008fffc},
-{13200000, DIF_BPF_COEFF45, 0xffe00017},
-{13200000, DIF_BPF_COEFF67, 0x004cffb9},
-{13200000, DIF_BPF_COEFF89, 0xff7500a8},
-{13200000, DIF_BPF_COEFF1011, 0x00d1feb6},
-{13200000, DIF_BPF_COEFF1213, 0xfef90238},
-{13200000, DIF_BPF_COEFF1415, 0x0111fc91},
-{13200000, DIF_BPF_COEFF1617, 0xff3604df},
-{13200000, DIF_BPF_COEFF1819, 0x0012f99b},
-{13200000, DIF_BPF_COEFF2021, 0x012d07d2},
-{13200000, DIF_BPF_COEFF2223, 0xfd07f714},
-{13200000, DIF_BPF_COEFF2425, 0x0542097e},
-{13200000, DIF_BPF_COEFF2627, 0xf81ff6a4},
-{13200000, DIF_BPF_COEFF2829, 0x0a9a086e},
-{13200000, DIF_BPF_COEFF3031, 0xf2dbf94b},
-{13200000, DIF_BPF_COEFF3233, 0x0f380453},
-{13200000, DIF_BPF_COEFF3435, 0xef6cfe82},
-{13200000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 132_quant.dat*/
-
-
-/*case 13300000:*/
-/* BEGIN - DIF BPF register values from 133_quant.dat*/
-{13300000, DIF_BPF_COEFF01, 0xffffffff},
-{13300000, DIF_BPF_COEFF23, 0x00080003},
-{13300000, DIF_BPF_COEFF45, 0xffde0001},
-{13300000, DIF_BPF_COEFF67, 0x0056ffe3},
-{13300000, DIF_BPF_COEFF89, 0xff570064},
-{13300000, DIF_BPF_COEFF1011, 0x0113ff10},
-{13300000, DIF_BPF_COEFF1213, 0xfe8201d2},
-{13300000, DIF_BPF_COEFF1415, 0x01cafcf0},
-{13300000, DIF_BPF_COEFF1617, 0xfe35049e},
-{13300000, DIF_BPF_COEFF1819, 0x0155f9a6},
-{13300000, DIF_BPF_COEFF2021, 0xffba080e},
-{13300000, DIF_BPF_COEFF2223, 0xfe8cf689},
-{13300000, DIF_BPF_COEFF2425, 0x03ce0a4e},
-{13300000, DIF_BPF_COEFF2627, 0xf961f5a8},
-{13300000, DIF_BPF_COEFF2829, 0x09a50971},
-{13300000, DIF_BPF_COEFF3031, 0xf379f869},
-{13300000, DIF_BPF_COEFF3233, 0x0eeb04ec},
-{13300000, DIF_BPF_COEFF3435, 0xef80fe4b},
-{13300000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 133_quant.dat*/
-
-
-/*case 13400000:*/
-/* BEGIN - DIF BPF register values from 134_quant.dat*/
-{13400000, DIF_BPF_COEFF01, 0x0000fffe},
-{13400000, DIF_BPF_COEFF23, 0x0007000a},
-{13400000, DIF_BPF_COEFF45, 0xffe2ffec},
-{13400000, DIF_BPF_COEFF67, 0x00540012},
-{13400000, DIF_BPF_COEFF89, 0xff4e0015},
-{13400000, DIF_BPF_COEFF1011, 0x0137ff82},
-{13400000, DIF_BPF_COEFF1213, 0xfe2e0145},
-{13400000, DIF_BPF_COEFF1415, 0x0260fd86},
-{13400000, DIF_BPF_COEFF1617, 0xfd51041a},
-{13400000, DIF_BPF_COEFF1819, 0x0287f9fb},
-{13400000, DIF_BPF_COEFF2021, 0xfe4a0802},
-{13400000, DIF_BPF_COEFF2223, 0x001df63f},
-{13400000, DIF_BPF_COEFF2425, 0x02430aeb},
-{13400000, DIF_BPF_COEFF2627, 0xfabdf4ce},
-{13400000, DIF_BPF_COEFF2829, 0x08970a62},
-{13400000, DIF_BPF_COEFF3031, 0xf428f78f},
-{13400000, DIF_BPF_COEFF3233, 0x0e950584},
-{13400000, DIF_BPF_COEFF3435, 0xef97fe15},
-{13400000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 134_quant.dat*/
-
-
-/*case 13500000:*/
-/* BEGIN - DIF BPF register values from 135_quant.dat*/
-{13500000, DIF_BPF_COEFF01, 0x0000fffd},
-{13500000, DIF_BPF_COEFF23, 0x0004000f},
-{13500000, DIF_BPF_COEFF45, 0xffeaffda},
-{13500000, DIF_BPF_COEFF67, 0x0046003d},
-{13500000, DIF_BPF_COEFF89, 0xff5affc4},
-{13500000, DIF_BPF_COEFF1011, 0x013b0000},
-{13500000, DIF_BPF_COEFF1213, 0xfe04009d},
-{13500000, DIF_BPF_COEFF1415, 0x02c8fe48},
-{13500000, DIF_BPF_COEFF1617, 0xfc99035a},
-{13500000, DIF_BPF_COEFF1819, 0x0397fa96},
-{13500000, DIF_BPF_COEFF2021, 0xfcec07ad},
-{13500000, DIF_BPF_COEFF2223, 0x01adf637},
-{13500000, DIF_BPF_COEFF2425, 0x00ac0b53},
-{13500000, DIF_BPF_COEFF2627, 0xfc2ef419},
-{13500000, DIF_BPF_COEFF2829, 0x07730b3e},
-{13500000, DIF_BPF_COEFF3031, 0xf4e9f6bd},
-{13500000, DIF_BPF_COEFF3233, 0x0e35061a},
-{13500000, DIF_BPF_COEFF3435, 0xefb1fddf},
-{13500000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 135_quant.dat*/
-
-
-/*case 13600000:*/
-/* BEGIN - DIF BPF register values from 136_quant.dat*/
-{13600000, DIF_BPF_COEFF01, 0x0000fffd},
-{13600000, DIF_BPF_COEFF23, 0x00000012},
-{13600000, DIF_BPF_COEFF45, 0xfff6ffcd},
-{13600000, DIF_BPF_COEFF67, 0x002f0061},
-{13600000, DIF_BPF_COEFF89, 0xff7bff79},
-{13600000, DIF_BPF_COEFF1011, 0x011e007e},
-{13600000, DIF_BPF_COEFF1213, 0xfe08ffe8},
-{13600000, DIF_BPF_COEFF1415, 0x02f9ff28},
-{13600000, DIF_BPF_COEFF1617, 0xfc17026a},
-{13600000, DIF_BPF_COEFF1819, 0x0479fb70},
-{13600000, DIF_BPF_COEFF2021, 0xfbad0713},
-{13600000, DIF_BPF_COEFF2223, 0x032ff672},
-{13600000, DIF_BPF_COEFF2425, 0xff100b83},
-{13600000, DIF_BPF_COEFF2627, 0xfdaff38b},
-{13600000, DIF_BPF_COEFF2829, 0x063c0c04},
-{13600000, DIF_BPF_COEFF3031, 0xf5baf5f5},
-{13600000, DIF_BPF_COEFF3233, 0x0dcc06ae},
-{13600000, DIF_BPF_COEFF3435, 0xefcdfda8},
-{13600000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 136_quant.dat*/
-
-
-/*case 13700000:*/
-/* BEGIN - DIF BPF register values from 137_quant.dat*/
-{13700000, DIF_BPF_COEFF01, 0x0000fffd},
-{13700000, DIF_BPF_COEFF23, 0xfffd0012},
-{13700000, DIF_BPF_COEFF45, 0x0004ffc8},
-{13700000, DIF_BPF_COEFF67, 0x00100078},
-{13700000, DIF_BPF_COEFF89, 0xffacff3e},
-{13700000, DIF_BPF_COEFF1011, 0x00e200f0},
-{13700000, DIF_BPF_COEFF1213, 0xfe39ff35},
-{13700000, DIF_BPF_COEFF1415, 0x02f10017},
-{13700000, DIF_BPF_COEFF1617, 0xfbd30156},
-{13700000, DIF_BPF_COEFF1819, 0x0521fc7f},
-{13700000, DIF_BPF_COEFF2021, 0xfa9c0638},
-{13700000, DIF_BPF_COEFF2223, 0x0499f6ee},
-{13700000, DIF_BPF_COEFF2425, 0xfd7a0b7c},
-{13700000, DIF_BPF_COEFF2627, 0xff39f325},
-{13700000, DIF_BPF_COEFF2829, 0x04f40cb3},
-{13700000, DIF_BPF_COEFF3031, 0xf69af537},
-{13700000, DIF_BPF_COEFF3233, 0x0d5a073f},
-{13700000, DIF_BPF_COEFF3435, 0xefecfd72},
-{13700000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 137_quant.dat*/
-
-
-/*case 13800000:*/
-/* BEGIN - DIF BPF register values from 138_quant.dat*/
-{13800000, DIF_BPF_COEFF01, 0x0001fffe},
-{13800000, DIF_BPF_COEFF23, 0xfffa000e},
-{13800000, DIF_BPF_COEFF45, 0x0011ffcb},
-{13800000, DIF_BPF_COEFF67, 0xfff0007f},
-{13800000, DIF_BPF_COEFF89, 0xffe7ff19},
-{13800000, DIF_BPF_COEFF1011, 0x008f014a},
-{13800000, DIF_BPF_COEFF1213, 0xfe94fe93},
-{13800000, DIF_BPF_COEFF1415, 0x02b00105},
-{13800000, DIF_BPF_COEFF1617, 0xfbd3002f},
-{13800000, DIF_BPF_COEFF1819, 0x0585fdb7},
-{13800000, DIF_BPF_COEFF2021, 0xf9c10525},
-{13800000, DIF_BPF_COEFF2223, 0x05def7a8},
-{13800000, DIF_BPF_COEFF2425, 0xfbf20b3c},
-{13800000, DIF_BPF_COEFF2627, 0x00c7f2e9},
-{13800000, DIF_BPF_COEFF2829, 0x03a00d48},
-{13800000, DIF_BPF_COEFF3031, 0xf787f484},
-{13800000, DIF_BPF_COEFF3233, 0x0cdf07cd},
-{13800000, DIF_BPF_COEFF3435, 0xf00dfd3c},
-{13800000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 138_quant.dat*/
-
-
-/*case 13900000:*/
-/* BEGIN - DIF BPF register values from 139_quant.dat*/
-{13900000, DIF_BPF_COEFF01, 0x00010000},
-{13900000, DIF_BPF_COEFF23, 0xfff80008},
-{13900000, DIF_BPF_COEFF45, 0x001bffd7},
-{13900000, DIF_BPF_COEFF67, 0xffd10076},
-{13900000, DIF_BPF_COEFF89, 0x0026ff0e},
-{13900000, DIF_BPF_COEFF1011, 0x002c0184},
-{13900000, DIF_BPF_COEFF1213, 0xff0ffe10},
-{13900000, DIF_BPF_COEFF1415, 0x023b01e0},
-{13900000, DIF_BPF_COEFF1617, 0xfc17ff06},
-{13900000, DIF_BPF_COEFF1819, 0x05a2ff09},
-{13900000, DIF_BPF_COEFF2021, 0xf92703e4},
-{13900000, DIF_BPF_COEFF2223, 0x06f4f89b},
-{13900000, DIF_BPF_COEFF2425, 0xfa820ac5},
-{13900000, DIF_BPF_COEFF2627, 0x0251f2d9},
-{13900000, DIF_BPF_COEFF2829, 0x02430dc3},
-{13900000, DIF_BPF_COEFF3031, 0xf881f3dc},
-{13900000, DIF_BPF_COEFF3233, 0x0c5c0859},
-{13900000, DIF_BPF_COEFF3435, 0xf031fd06},
-{13900000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 139_quant.dat*/
-
-
-/*case 14000000:*/
-/* BEGIN - DIF BPF register values from 140_quant.dat*/
-{14000000, DIF_BPF_COEFF01, 0x00010001},
-{14000000, DIF_BPF_COEFF23, 0xfff80001},
-{14000000, DIF_BPF_COEFF45, 0x0021ffe8},
-{14000000, DIF_BPF_COEFF67, 0xffba005d},
-{14000000, DIF_BPF_COEFF89, 0x0060ff1f},
-{14000000, DIF_BPF_COEFF1011, 0xffc40198},
-{14000000, DIF_BPF_COEFF1213, 0xffa0fdb5},
-{14000000, DIF_BPF_COEFF1415, 0x019a029a},
-{14000000, DIF_BPF_COEFF1617, 0xfc99fdea},
-{14000000, DIF_BPF_COEFF1819, 0x05750067},
-{14000000, DIF_BPF_COEFF2021, 0xf8d4027f},
-{14000000, DIF_BPF_COEFF2223, 0x07d4f9c0},
-{14000000, DIF_BPF_COEFF2425, 0xf9320a1a},
-{14000000, DIF_BPF_COEFF2627, 0x03d2f2f3},
-{14000000, DIF_BPF_COEFF2829, 0x00df0e22},
-{14000000, DIF_BPF_COEFF3031, 0xf986f341},
-{14000000, DIF_BPF_COEFF3233, 0x0bd108e2},
-{14000000, DIF_BPF_COEFF3435, 0xf058fcd1},
-{14000000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 140_quant.dat*/
-
-
-/*case 14100000:*/
-/* BEGIN - DIF BPF register values from 141_quant.dat*/
-{14100000, DIF_BPF_COEFF01, 0x00000002},
-{14100000, DIF_BPF_COEFF23, 0xfff9fffa},
-{14100000, DIF_BPF_COEFF45, 0x0021fffd},
-{14100000, DIF_BPF_COEFF67, 0xffac0038},
-{14100000, DIF_BPF_COEFF89, 0x008eff4a},
-{14100000, DIF_BPF_COEFF1011, 0xff630184},
-{14100000, DIF_BPF_COEFF1213, 0x003afd8b},
-{14100000, DIF_BPF_COEFF1415, 0x00da0326},
-{14100000, DIF_BPF_COEFF1617, 0xfd51fced},
-{14100000, DIF_BPF_COEFF1819, 0x050101c0},
-{14100000, DIF_BPF_COEFF2021, 0xf8cb0103},
-{14100000, DIF_BPF_COEFF2223, 0x0876fb10},
-{14100000, DIF_BPF_COEFF2425, 0xf80a093e},
-{14100000, DIF_BPF_COEFF2627, 0x0543f338},
-{14100000, DIF_BPF_COEFF2829, 0xff7a0e66},
-{14100000, DIF_BPF_COEFF3031, 0xfa94f2b2},
-{14100000, DIF_BPF_COEFF3233, 0x0b3f0967},
-{14100000, DIF_BPF_COEFF3435, 0xf081fc9b},
-{14100000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 141_quant.dat*/
-
-
-/*case 14200000:*/
-/* BEGIN - DIF BPF register values from 142_quant.dat*/
-{14200000, DIF_BPF_COEFF01, 0x00000003},
-{14200000, DIF_BPF_COEFF23, 0xfffbfff3},
-{14200000, DIF_BPF_COEFF45, 0x001d0013},
-{14200000, DIF_BPF_COEFF67, 0xffaa000b},
-{14200000, DIF_BPF_COEFF89, 0x00aaff89},
-{14200000, DIF_BPF_COEFF1011, 0xff13014a},
-{14200000, DIF_BPF_COEFF1213, 0x00cefd95},
-{14200000, DIF_BPF_COEFF1415, 0x000a037b},
-{14200000, DIF_BPF_COEFF1617, 0xfe35fc1d},
-{14200000, DIF_BPF_COEFF1819, 0x044c0305},
-{14200000, DIF_BPF_COEFF2021, 0xf90cff7e},
-{14200000, DIF_BPF_COEFF2223, 0x08d5fc81},
-{14200000, DIF_BPF_COEFF2425, 0xf7100834},
-{14200000, DIF_BPF_COEFF2627, 0x069ff3a7},
-{14200000, DIF_BPF_COEFF2829, 0xfe160e8d},
-{14200000, DIF_BPF_COEFF3031, 0xfbaaf231},
-{14200000, DIF_BPF_COEFF3233, 0x0aa509e9},
-{14200000, DIF_BPF_COEFF3435, 0xf0adfc65},
-{14200000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 142_quant.dat*/
-
-
-/*case 14300000:*/
-/* BEGIN - DIF BPF register values from 143_quant.dat*/
-{14300000, DIF_BPF_COEFF01, 0x00000003},
-{14300000, DIF_BPF_COEFF23, 0xffffffef},
-{14300000, DIF_BPF_COEFF45, 0x00140025},
-{14300000, DIF_BPF_COEFF67, 0xffb4ffdd},
-{14300000, DIF_BPF_COEFF89, 0x00b2ffd6},
-{14300000, DIF_BPF_COEFF1011, 0xfedb00f0},
-{14300000, DIF_BPF_COEFF1213, 0x0150fdd3},
-{14300000, DIF_BPF_COEFF1415, 0xff380391},
-{14300000, DIF_BPF_COEFF1617, 0xff36fb85},
-{14300000, DIF_BPF_COEFF1819, 0x035e0426},
-{14300000, DIF_BPF_COEFF2021, 0xf994fdfe},
-{14300000, DIF_BPF_COEFF2223, 0x08eefe0b},
-{14300000, DIF_BPF_COEFF2425, 0xf6490702},
-{14300000, DIF_BPF_COEFF2627, 0x07e1f43e},
-{14300000, DIF_BPF_COEFF2829, 0xfcb60e97},
-{14300000, DIF_BPF_COEFF3031, 0xfcc6f1be},
-{14300000, DIF_BPF_COEFF3233, 0x0a040a67},
-{14300000, DIF_BPF_COEFF3435, 0xf0dbfc30},
-{14300000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 143_quant.dat*/
-
-
-/*case 14400000:*/
-/* BEGIN - DIF BPF register values from 144_quant.dat*/
-{14400000, DIF_BPF_COEFF01, 0x00000003},
-{14400000, DIF_BPF_COEFF23, 0x0002ffee},
-{14400000, DIF_BPF_COEFF45, 0x00070033},
-{14400000, DIF_BPF_COEFF67, 0xffc9ffb4},
-{14400000, DIF_BPF_COEFF89, 0x00a40027},
-{14400000, DIF_BPF_COEFF1011, 0xfec3007e},
-{14400000, DIF_BPF_COEFF1213, 0x01b4fe3f},
-{14400000, DIF_BPF_COEFF1415, 0xfe760369},
-{14400000, DIF_BPF_COEFF1617, 0x0044fb2e},
-{14400000, DIF_BPF_COEFF1819, 0x02450518},
-{14400000, DIF_BPF_COEFF2021, 0xfa5ffc90},
-{14400000, DIF_BPF_COEFF2223, 0x08c1ffa1},
-{14400000, DIF_BPF_COEFF2425, 0xf5bc05ae},
-{14400000, DIF_BPF_COEFF2627, 0x0902f4fc},
-{14400000, DIF_BPF_COEFF2829, 0xfb600e85},
-{14400000, DIF_BPF_COEFF3031, 0xfde7f15a},
-{14400000, DIF_BPF_COEFF3233, 0x095d0ae2},
-{14400000, DIF_BPF_COEFF3435, 0xf10cfbfb},
-{14400000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 144_quant.dat*/
-
-
-/*case 14500000:*/
-/* BEGIN - DIF BPF register values from 145_quant.dat*/
-{14500000, DIF_BPF_COEFF01, 0xffff0002},
-{14500000, DIF_BPF_COEFF23, 0x0005ffef},
-{14500000, DIF_BPF_COEFF45, 0xfffa0038},
-{14500000, DIF_BPF_COEFF67, 0xffe5ff95},
-{14500000, DIF_BPF_COEFF89, 0x00820074},
-{14500000, DIF_BPF_COEFF1011, 0xfecc0000},
-{14500000, DIF_BPF_COEFF1213, 0x01f0fed0},
-{14500000, DIF_BPF_COEFF1415, 0xfdd20304},
-{14500000, DIF_BPF_COEFF1617, 0x014dfb1d},
-{14500000, DIF_BPF_COEFF1819, 0x010e05ce},
-{14500000, DIF_BPF_COEFF2021, 0xfb64fb41},
-{14500000, DIF_BPF_COEFF2223, 0x084e013b},
-{14500000, DIF_BPF_COEFF2425, 0xf569043e},
-{14500000, DIF_BPF_COEFF2627, 0x0a00f5dd},
-{14500000, DIF_BPF_COEFF2829, 0xfa150e55},
-{14500000, DIF_BPF_COEFF3031, 0xff0bf104},
-{14500000, DIF_BPF_COEFF3233, 0x08b00b59},
-{14500000, DIF_BPF_COEFF3435, 0xf13ffbc6},
-{14500000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 145_quant.dat*/
-
-
-/*case 14600000:*/
-/* BEGIN - DIF BPF register values from 146_quant.dat*/
-{14600000, DIF_BPF_COEFF01, 0xffff0001},
-{14600000, DIF_BPF_COEFF23, 0x0008fff4},
-{14600000, DIF_BPF_COEFF45, 0xffed0035},
-{14600000, DIF_BPF_COEFF67, 0x0005ff83},
-{14600000, DIF_BPF_COEFF89, 0x005000b4},
-{14600000, DIF_BPF_COEFF1011, 0xfef6ff82},
-{14600000, DIF_BPF_COEFF1213, 0x01ffff7a},
-{14600000, DIF_BPF_COEFF1415, 0xfd580269},
-{14600000, DIF_BPF_COEFF1617, 0x0241fb53},
-{14600000, DIF_BPF_COEFF1819, 0xffca0640},
-{14600000, DIF_BPF_COEFF2021, 0xfc99fa1e},
-{14600000, DIF_BPF_COEFF2223, 0x079a02cb},
-{14600000, DIF_BPF_COEFF2425, 0xf55502ba},
-{14600000, DIF_BPF_COEFF2627, 0x0ad5f6e0},
-{14600000, DIF_BPF_COEFF2829, 0xf8d90e0a},
-{14600000, DIF_BPF_COEFF3031, 0x0031f0bd},
-{14600000, DIF_BPF_COEFF3233, 0x07fd0bcb},
-{14600000, DIF_BPF_COEFF3435, 0xf174fb91},
-{14600000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 146_quant.dat*/
-
-
-/*case 14700000:*/
-/* BEGIN - DIF BPF register values from 147_quant.dat*/
-{14700000, DIF_BPF_COEFF01, 0xffffffff},
-{14700000, DIF_BPF_COEFF23, 0x0009fffb},
-{14700000, DIF_BPF_COEFF45, 0xffe4002a},
-{14700000, DIF_BPF_COEFF67, 0x0025ff82},
-{14700000, DIF_BPF_COEFF89, 0x001400e0},
-{14700000, DIF_BPF_COEFF1011, 0xff3cff10},
-{14700000, DIF_BPF_COEFF1213, 0x01e10030},
-{14700000, DIF_BPF_COEFF1415, 0xfd1201a4},
-{14700000, DIF_BPF_COEFF1617, 0x0311fbcd},
-{14700000, DIF_BPF_COEFF1819, 0xfe88066a},
-{14700000, DIF_BPF_COEFF2021, 0xfdf1f92f},
-{14700000, DIF_BPF_COEFF2223, 0x06aa0449},
-{14700000, DIF_BPF_COEFF2425, 0xf57e0128},
-{14700000, DIF_BPF_COEFF2627, 0x0b7ef801},
-{14700000, DIF_BPF_COEFF2829, 0xf7b00da2},
-{14700000, DIF_BPF_COEFF3031, 0x0156f086},
-{14700000, DIF_BPF_COEFF3233, 0x07450c39},
-{14700000, DIF_BPF_COEFF3435, 0xf1acfb5c},
-{14700000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 147_quant.dat*/
-
-
-/*case 14800000:*/
-/* BEGIN - DIF BPF register values from 148_quant.dat*/
-{14800000, DIF_BPF_COEFF01, 0x0000fffe},
-{14800000, DIF_BPF_COEFF23, 0x00080002},
-{14800000, DIF_BPF_COEFF45, 0xffdf0019},
-{14800000, DIF_BPF_COEFF67, 0x003fff92},
-{14800000, DIF_BPF_COEFF89, 0xffd600f1},
-{14800000, DIF_BPF_COEFF1011, 0xff96feb6},
-{14800000, DIF_BPF_COEFF1213, 0x019700e1},
-{14800000, DIF_BPF_COEFF1415, 0xfd0500c2},
-{14800000, DIF_BPF_COEFF1617, 0x03b0fc84},
-{14800000, DIF_BPF_COEFF1819, 0xfd590649},
-{14800000, DIF_BPF_COEFF2021, 0xff5df87f},
-{14800000, DIF_BPF_COEFF2223, 0x058505aa},
-{14800000, DIF_BPF_COEFF2425, 0xf5e4ff91},
-{14800000, DIF_BPF_COEFF2627, 0x0bf9f93c},
-{14800000, DIF_BPF_COEFF2829, 0xf69d0d20},
-{14800000, DIF_BPF_COEFF3031, 0x0279f05e},
-{14800000, DIF_BPF_COEFF3233, 0x06880ca3},
-{14800000, DIF_BPF_COEFF3435, 0xf1e6fb28},
-{14800000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 148_quant.dat*/
-
-
-/*case 14900000:*/
-/* BEGIN - DIF BPF register values from 149_quant.dat*/
-{14900000, DIF_BPF_COEFF01, 0x0000fffd},
-{14900000, DIF_BPF_COEFF23, 0x00060009},
-{14900000, DIF_BPF_COEFF45, 0xffdf0004},
-{14900000, DIF_BPF_COEFF67, 0x0051ffb0},
-{14900000, DIF_BPF_COEFF89, 0xff9d00e8},
-{14900000, DIF_BPF_COEFF1011, 0xfffcfe7c},
-{14900000, DIF_BPF_COEFF1213, 0x01280180},
-{14900000, DIF_BPF_COEFF1415, 0xfd32ffd2},
-{14900000, DIF_BPF_COEFF1617, 0x0413fd6e},
-{14900000, DIF_BPF_COEFF1819, 0xfc4d05df},
-{14900000, DIF_BPF_COEFF2021, 0x00d1f812},
-{14900000, DIF_BPF_COEFF2223, 0x043506e4},
-{14900000, DIF_BPF_COEFF2425, 0xf685fdfb},
-{14900000, DIF_BPF_COEFF2627, 0x0c43fa8d},
-{14900000, DIF_BPF_COEFF2829, 0xf5a10c83},
-{14900000, DIF_BPF_COEFF3031, 0x0399f046},
-{14900000, DIF_BPF_COEFF3233, 0x05c70d08},
-{14900000, DIF_BPF_COEFF3435, 0xf222faf3},
-{14900000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 149_quant.dat*/
-
-
-/*case 15000000:*/
-/* BEGIN - DIF BPF register values from 150_quant.dat*/
-{15000000, DIF_BPF_COEFF01, 0x0000fffd},
-{15000000, DIF_BPF_COEFF23, 0x0003000f},
-{15000000, DIF_BPF_COEFF45, 0xffe5ffef},
-{15000000, DIF_BPF_COEFF67, 0x0057ffd9},
-{15000000, DIF_BPF_COEFF89, 0xff7000c4},
-{15000000, DIF_BPF_COEFF1011, 0x0062fe68},
-{15000000, DIF_BPF_COEFF1213, 0x009e01ff},
-{15000000, DIF_BPF_COEFF1415, 0xfd95fee6},
-{15000000, DIF_BPF_COEFF1617, 0x0435fe7d},
-{15000000, DIF_BPF_COEFF1819, 0xfb710530},
-{15000000, DIF_BPF_COEFF2021, 0x023cf7ee},
-{15000000, DIF_BPF_COEFF2223, 0x02c307ef},
-{15000000, DIF_BPF_COEFF2425, 0xf75efc70},
-{15000000, DIF_BPF_COEFF2627, 0x0c5cfbef},
-{15000000, DIF_BPF_COEFF2829, 0xf4c10bce},
-{15000000, DIF_BPF_COEFF3031, 0x04b3f03f},
-{15000000, DIF_BPF_COEFF3233, 0x05030d69},
-{15000000, DIF_BPF_COEFF3435, 0xf261fabf},
-{15000000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 150_quant.dat*/
-
-
-/*case 15100000:*/
-/* BEGIN - DIF BPF register values from 151_quant.dat*/
-{15100000, DIF_BPF_COEFF01, 0x0000fffd},
-{15100000, DIF_BPF_COEFF23, 0xffff0012},
-{15100000, DIF_BPF_COEFF45, 0xffefffdc},
-{15100000, DIF_BPF_COEFF67, 0x00510006},
-{15100000, DIF_BPF_COEFF89, 0xff540089},
-{15100000, DIF_BPF_COEFF1011, 0x00befe7c},
-{15100000, DIF_BPF_COEFF1213, 0x00060253},
-{15100000, DIF_BPF_COEFF1415, 0xfe27fe0d},
-{15100000, DIF_BPF_COEFF1617, 0x0413ffa2},
-{15100000, DIF_BPF_COEFF1819, 0xfad10446},
-{15100000, DIF_BPF_COEFF2021, 0x0390f812},
-{15100000, DIF_BPF_COEFF2223, 0x013b08c3},
-{15100000, DIF_BPF_COEFF2425, 0xf868faf6},
-{15100000, DIF_BPF_COEFF2627, 0x0c43fd5f},
-{15100000, DIF_BPF_COEFF2829, 0xf3fd0b02},
-{15100000, DIF_BPF_COEFF3031, 0x05c7f046},
-{15100000, DIF_BPF_COEFF3233, 0x043b0dc4},
-{15100000, DIF_BPF_COEFF3435, 0xf2a1fa8b},
-{15100000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 151_quant.dat*/
-
-
-/*case 15200000:*/
-/* BEGIN - DIF BPF register values from 152_quant.dat*/
-{15200000, DIF_BPF_COEFF01, 0x0001fffe},
-{15200000, DIF_BPF_COEFF23, 0xfffc0012},
-{15200000, DIF_BPF_COEFF45, 0xfffbffce},
-{15200000, DIF_BPF_COEFF67, 0x003f0033},
-{15200000, DIF_BPF_COEFF89, 0xff4e003f},
-{15200000, DIF_BPF_COEFF1011, 0x0106feb6},
-{15200000, DIF_BPF_COEFF1213, 0xff6e0276},
-{15200000, DIF_BPF_COEFF1415, 0xfeddfd56},
-{15200000, DIF_BPF_COEFF1617, 0x03b000cc},
-{15200000, DIF_BPF_COEFF1819, 0xfa740329},
-{15200000, DIF_BPF_COEFF2021, 0x04bff87f},
-{15200000, DIF_BPF_COEFF2223, 0xffaa095d},
-{15200000, DIF_BPF_COEFF2425, 0xf99ef995},
-{15200000, DIF_BPF_COEFF2627, 0x0bf9fed8},
-{15200000, DIF_BPF_COEFF2829, 0xf3590a1f},
-{15200000, DIF_BPF_COEFF3031, 0x06d2f05e},
-{15200000, DIF_BPF_COEFF3233, 0x03700e1b},
-{15200000, DIF_BPF_COEFF3435, 0xf2e4fa58},
-{15200000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 152_quant.dat*/
-
-
-/*case 115300000:*/
-/* BEGIN - DIF BPF register values from 153_quant.dat*/
-{15300000, DIF_BPF_COEFF01, 0x0001ffff},
-{15300000, DIF_BPF_COEFF23, 0xfff9000f},
-{15300000, DIF_BPF_COEFF45, 0x0009ffc8},
-{15300000, DIF_BPF_COEFF67, 0x00250059},
-{15300000, DIF_BPF_COEFF89, 0xff5effee},
-{15300000, DIF_BPF_COEFF1011, 0x0132ff10},
-{15300000, DIF_BPF_COEFF1213, 0xfee30265},
-{15300000, DIF_BPF_COEFF1415, 0xffaafccf},
-{15300000, DIF_BPF_COEFF1617, 0x031101eb},
-{15300000, DIF_BPF_COEFF1819, 0xfa6001e8},
-{15300000, DIF_BPF_COEFF2021, 0x05bdf92f},
-{15300000, DIF_BPF_COEFF2223, 0xfe1b09b6},
-{15300000, DIF_BPF_COEFF2425, 0xfafaf852},
-{15300000, DIF_BPF_COEFF2627, 0x0b7e0055},
-{15300000, DIF_BPF_COEFF2829, 0xf2d50929},
-{15300000, DIF_BPF_COEFF3031, 0x07d3f086},
-{15300000, DIF_BPF_COEFF3233, 0x02a30e6c},
-{15300000, DIF_BPF_COEFF3435, 0xf329fa24},
-{15300000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 153_quant.dat*/
-
-
-/*case 115400000:*/
-/* BEGIN - DIF BPF register values from 154_quant.dat*/
-{15400000, DIF_BPF_COEFF01, 0x00010001},
-{15400000, DIF_BPF_COEFF23, 0xfff80009},
-{15400000, DIF_BPF_COEFF45, 0x0015ffca},
-{15400000, DIF_BPF_COEFF67, 0x00050074},
-{15400000, DIF_BPF_COEFF89, 0xff81ff9f},
-{15400000, DIF_BPF_COEFF1011, 0x013dff82},
-{15400000, DIF_BPF_COEFF1213, 0xfe710221},
-{15400000, DIF_BPF_COEFF1415, 0x007cfc80},
-{15400000, DIF_BPF_COEFF1617, 0x024102ed},
-{15400000, DIF_BPF_COEFF1819, 0xfa940090},
-{15400000, DIF_BPF_COEFF2021, 0x0680fa1e},
-{15400000, DIF_BPF_COEFF2223, 0xfc9b09cd},
-{15400000, DIF_BPF_COEFF2425, 0xfc73f736},
-{15400000, DIF_BPF_COEFF2627, 0x0ad501d0},
-{15400000, DIF_BPF_COEFF2829, 0xf2740820},
-{15400000, DIF_BPF_COEFF3031, 0x08c9f0bd},
-{15400000, DIF_BPF_COEFF3233, 0x01d40eb9},
-{15400000, DIF_BPF_COEFF3435, 0xf371f9f1},
-{15400000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 154_quant.dat*/
-
-
-/*case 115500000:*/
-/* BEGIN - DIF BPF register values from 155_quant.dat*/
-{15500000, DIF_BPF_COEFF01, 0x00000002},
-{15500000, DIF_BPF_COEFF23, 0xfff80002},
-{15500000, DIF_BPF_COEFF45, 0x001effd5},
-{15500000, DIF_BPF_COEFF67, 0xffe5007f},
-{15500000, DIF_BPF_COEFF89, 0xffb4ff5b},
-{15500000, DIF_BPF_COEFF1011, 0x01280000},
-{15500000, DIF_BPF_COEFF1213, 0xfe2401b0},
-{15500000, DIF_BPF_COEFF1415, 0x0146fc70},
-{15500000, DIF_BPF_COEFF1617, 0x014d03c6},
-{15500000, DIF_BPF_COEFF1819, 0xfb10ff32},
-{15500000, DIF_BPF_COEFF2021, 0x0701fb41},
-{15500000, DIF_BPF_COEFF2223, 0xfb3709a1},
-{15500000, DIF_BPF_COEFF2425, 0xfe00f644},
-{15500000, DIF_BPF_COEFF2627, 0x0a000345},
-{15500000, DIF_BPF_COEFF2829, 0xf2350708},
-{15500000, DIF_BPF_COEFF3031, 0x09b2f104},
-{15500000, DIF_BPF_COEFF3233, 0x01050eff},
-{15500000, DIF_BPF_COEFF3435, 0xf3baf9be},
-{15500000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 155_quant.dat*/
-
-
-/*case 115600000:*/
-/* BEGIN - DIF BPF register values from 156_quant.dat*/
-{15600000, DIF_BPF_COEFF01, 0x00000003},
-{15600000, DIF_BPF_COEFF23, 0xfff9fffb},
-{15600000, DIF_BPF_COEFF45, 0x0022ffe6},
-{15600000, DIF_BPF_COEFF67, 0xffc9007a},
-{15600000, DIF_BPF_COEFF89, 0xfff0ff29},
-{15600000, DIF_BPF_COEFF1011, 0x00f2007e},
-{15600000, DIF_BPF_COEFF1213, 0xfe01011b},
-{15600000, DIF_BPF_COEFF1415, 0x01f6fc9e},
-{15600000, DIF_BPF_COEFF1617, 0x00440467},
-{15600000, DIF_BPF_COEFF1819, 0xfbccfdde},
-{15600000, DIF_BPF_COEFF2021, 0x0738fc90},
-{15600000, DIF_BPF_COEFF2223, 0xf9f70934},
-{15600000, DIF_BPF_COEFF2425, 0xff99f582},
-{15600000, DIF_BPF_COEFF2627, 0x090204b0},
-{15600000, DIF_BPF_COEFF2829, 0xf21a05e1},
-{15600000, DIF_BPF_COEFF3031, 0x0a8df15a},
-{15600000, DIF_BPF_COEFF3233, 0x00340f41},
-{15600000, DIF_BPF_COEFF3435, 0xf405f98b},
-{15600000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 156_quant.dat*/
-
-
-/*case 115700000:*/
-/* BEGIN - DIF BPF register values from 157_quant.dat*/
-{15700000, DIF_BPF_COEFF01, 0x00000003},
-{15700000, DIF_BPF_COEFF23, 0xfffcfff4},
-{15700000, DIF_BPF_COEFF45, 0x0020fffa},
-{15700000, DIF_BPF_COEFF67, 0xffb40064},
-{15700000, DIF_BPF_COEFF89, 0x002fff11},
-{15700000, DIF_BPF_COEFF1011, 0x00a400f0},
-{15700000, DIF_BPF_COEFF1213, 0xfe0d006e},
-{15700000, DIF_BPF_COEFF1415, 0x0281fd09},
-{15700000, DIF_BPF_COEFF1617, 0xff3604c9},
-{15700000, DIF_BPF_COEFF1819, 0xfcbffca2},
-{15700000, DIF_BPF_COEFF2021, 0x0726fdfe},
-{15700000, DIF_BPF_COEFF2223, 0xf8e80888},
-{15700000, DIF_BPF_COEFF2425, 0x0134f4f3},
-{15700000, DIF_BPF_COEFF2627, 0x07e1060c},
-{15700000, DIF_BPF_COEFF2829, 0xf22304af},
-{15700000, DIF_BPF_COEFF3031, 0x0b59f1be},
-{15700000, DIF_BPF_COEFF3233, 0xff640f7d},
-{15700000, DIF_BPF_COEFF3435, 0xf452f959},
-{15700000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 157_quant.dat*/
-
-
-/*case 115800000:*/
-/* BEGIN - DIF BPF register values from 158_quant.dat*/
-{15800000, DIF_BPF_COEFF01, 0x00000003},
-{15800000, DIF_BPF_COEFF23, 0x0000fff0},
-{15800000, DIF_BPF_COEFF45, 0x001a0010},
-{15800000, DIF_BPF_COEFF67, 0xffaa0041},
-{15800000, DIF_BPF_COEFF89, 0x0067ff13},
-{15800000, DIF_BPF_COEFF1011, 0x0043014a},
-{15800000, DIF_BPF_COEFF1213, 0xfe46ffb9},
-{15800000, DIF_BPF_COEFF1415, 0x02dbfda8},
-{15800000, DIF_BPF_COEFF1617, 0xfe3504e5},
-{15800000, DIF_BPF_COEFF1819, 0xfddcfb8d},
-{15800000, DIF_BPF_COEFF2021, 0x06c9ff7e},
-{15800000, DIF_BPF_COEFF2223, 0xf81107a2},
-{15800000, DIF_BPF_COEFF2425, 0x02c9f49a},
-{15800000, DIF_BPF_COEFF2627, 0x069f0753},
-{15800000, DIF_BPF_COEFF2829, 0xf2500373},
-{15800000, DIF_BPF_COEFF3031, 0x0c14f231},
-{15800000, DIF_BPF_COEFF3233, 0xfe930fb3},
-{15800000, DIF_BPF_COEFF3435, 0xf4a1f927},
-{15800000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 158_quant.dat*/
-
-
-/*case 115900000:*/
-/* BEGIN - DIF BPF register values from 159_quant.dat*/
-{15900000, DIF_BPF_COEFF01, 0xffff0002},
-{15900000, DIF_BPF_COEFF23, 0x0003ffee},
-{15900000, DIF_BPF_COEFF45, 0x000f0023},
-{15900000, DIF_BPF_COEFF67, 0xffac0016},
-{15900000, DIF_BPF_COEFF89, 0x0093ff31},
-{15900000, DIF_BPF_COEFF1011, 0xffdc0184},
-{15900000, DIF_BPF_COEFF1213, 0xfea6ff09},
-{15900000, DIF_BPF_COEFF1415, 0x02fdfe70},
-{15900000, DIF_BPF_COEFF1617, 0xfd5104ba},
-{15900000, DIF_BPF_COEFF1819, 0xff15faac},
-{15900000, DIF_BPF_COEFF2021, 0x06270103},
-{15900000, DIF_BPF_COEFF2223, 0xf7780688},
-{15900000, DIF_BPF_COEFF2425, 0x044df479},
-{15900000, DIF_BPF_COEFF2627, 0x05430883},
-{15900000, DIF_BPF_COEFF2829, 0xf2a00231},
-{15900000, DIF_BPF_COEFF3031, 0x0cbef2b2},
-{15900000, DIF_BPF_COEFF3233, 0xfdc40fe3},
-{15900000, DIF_BPF_COEFF3435, 0xf4f2f8f5},
-{15900000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 159_quant.dat*/
-
-
-/*case 116000000:*/
-/* BEGIN - DIF BPF register values from 160_quant.dat*/
-{16000000, DIF_BPF_COEFF01, 0xffff0001},
-{16000000, DIF_BPF_COEFF23, 0x0006ffef},
-{16000000, DIF_BPF_COEFF45, 0x00020031},
-{16000000, DIF_BPF_COEFF67, 0xffbaffe8},
-{16000000, DIF_BPF_COEFF89, 0x00adff66},
-{16000000, DIF_BPF_COEFF1011, 0xff790198},
-{16000000, DIF_BPF_COEFF1213, 0xff26fe6e},
-{16000000, DIF_BPF_COEFF1415, 0x02e5ff55},
-{16000000, DIF_BPF_COEFF1617, 0xfc99044a},
-{16000000, DIF_BPF_COEFF1819, 0x005bfa09},
-{16000000, DIF_BPF_COEFF2021, 0x0545027f},
-{16000000, DIF_BPF_COEFF2223, 0xf7230541},
-{16000000, DIF_BPF_COEFF2425, 0x05b8f490},
-{16000000, DIF_BPF_COEFF2627, 0x03d20997},
-{16000000, DIF_BPF_COEFF2829, 0xf31300eb},
-{16000000, DIF_BPF_COEFF3031, 0x0d55f341},
-{16000000, DIF_BPF_COEFF3233, 0xfcf6100e},
-{16000000, DIF_BPF_COEFF3435, 0xf544f8c3},
-{16000000, DIF_BPF_COEFF36, 0x110d0000},
-/* END - DIF BPF register values from 160_quant.dat*/
-};
-
-#endif
diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c
deleted file mode 100644
index 7c4e360ba9b..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-dvb.c
+++ /dev/null
@@ -1,796 +0,0 @@
-/*
- DVB device driver for cx231xx
-
- Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
- Based on em28xx driver
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-
-#include "cx231xx.h"
-#include <media/v4l2-common.h>
-#include <media/videobuf-vmalloc.h>
-
-#include "xc5000.h"
-#include "s5h1432.h"
-#include "tda18271.h"
-#include "s5h1411.h"
-#include "lgdt3305.h"
-#include "mb86a20s.h"
-
-MODULE_DESCRIPTION("driver for cx231xx based DVB cards");
-MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>");
-MODULE_LICENSE("GPL");
-
-static unsigned int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debug messages [dvb]");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define dprintk(level, fmt, arg...) do { \
-if (debug >= level) \
- printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \
-} while (0)
-
-#define CX231XX_DVB_NUM_BUFS 5
-#define CX231XX_DVB_MAX_PACKETSIZE 564
-#define CX231XX_DVB_MAX_PACKETS 64
-
-struct cx231xx_dvb {
- struct dvb_frontend *frontend;
-
- /* feed count management */
- struct mutex lock;
- int nfeeds;
-
- /* general boilerplate stuff */
- struct dvb_adapter adapter;
- struct dvb_demux demux;
- struct dmxdev dmxdev;
- struct dmx_frontend fe_hw;
- struct dmx_frontend fe_mem;
- struct dvb_net net;
-};
-
-static struct s5h1432_config dvico_s5h1432_config = {
- .output_mode = S5H1432_SERIAL_OUTPUT,
- .gpio = S5H1432_GPIO_ON,
- .qam_if = S5H1432_IF_4000,
- .vsb_if = S5H1432_IF_4000,
- .inversion = S5H1432_INVERSION_OFF,
- .status_mode = S5H1432_DEMODLOCKING,
- .mpeg_timing = S5H1432_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static struct tda18271_std_map cnxt_rde253s_tda18271_std_map = {
- .dvbt_6 = { .if_freq = 4000, .agc_mode = 3, .std = 4,
- .if_lvl = 1, .rfagc_top = 0x37, },
- .dvbt_7 = { .if_freq = 4000, .agc_mode = 3, .std = 5,
- .if_lvl = 1, .rfagc_top = 0x37, },
- .dvbt_8 = { .if_freq = 4000, .agc_mode = 3, .std = 6,
- .if_lvl = 1, .rfagc_top = 0x37, },
-};
-
-static struct tda18271_std_map mb86a20s_tda18271_config = {
- .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
- .if_lvl = 7, .rfagc_top = 0x37, },
-};
-
-static struct tda18271_config cnxt_rde253s_tunerconfig = {
- .std_map = &cnxt_rde253s_tda18271_std_map,
- .gate = TDA18271_GATE_ANALOG,
-};
-
-static struct s5h1411_config tda18271_s5h1411_config = {
- .output_mode = S5H1411_SERIAL_OUTPUT,
- .gpio = S5H1411_GPIO_OFF,
- .vsb_if = S5H1411_IF_3250,
- .qam_if = S5H1411_IF_4000,
- .inversion = S5H1411_INVERSION_ON,
- .status_mode = S5H1411_DEMODLOCKING,
- .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-static struct s5h1411_config xc5000_s5h1411_config = {
- .output_mode = S5H1411_SERIAL_OUTPUT,
- .gpio = S5H1411_GPIO_OFF,
- .vsb_if = S5H1411_IF_3250,
- .qam_if = S5H1411_IF_3250,
- .inversion = S5H1411_INVERSION_OFF,
- .status_mode = S5H1411_DEMODLOCKING,
- .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static struct lgdt3305_config hcw_lgdt3305_config = {
- .i2c_addr = 0x0e,
- .mpeg_mode = LGDT3305_MPEG_SERIAL,
- .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
- .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
- .deny_i2c_rptr = 1,
- .spectral_inversion = 1,
- .qam_if_khz = 4000,
- .vsb_if_khz = 3250,
-};
-
-static struct tda18271_std_map hauppauge_tda18271_std_map = {
- .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4,
- .if_lvl = 1, .rfagc_top = 0x58, },
- .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5,
- .if_lvl = 1, .rfagc_top = 0x58, },
-};
-
-static struct tda18271_config hcw_tda18271_config = {
- .std_map = &hauppauge_tda18271_std_map,
- .gate = TDA18271_GATE_DIGITAL,
-};
-
-static const struct mb86a20s_config pv_mb86a20s_config = {
- .demod_address = 0x10,
- .is_serial = true,
-};
-
-static struct tda18271_config pv_tda18271_config = {
- .std_map = &mb86a20s_tda18271_config,
- .gate = TDA18271_GATE_DIGITAL,
- .small_i2c = TDA18271_03_BYTE_CHUNK_INIT,
-};
-
-static inline void print_err_status(struct cx231xx *dev, int packet, int status)
-{
- char *errmsg = "Unknown";
-
- switch (status) {
- case -ENOENT:
- errmsg = "unlinked synchronuously";
- break;
- case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
- break;
- case -ENOSR:
- errmsg = "Buffer error (overrun)";
- break;
- case -EPIPE:
- errmsg = "Stalled (device not responding)";
- break;
- case -EOVERFLOW:
- errmsg = "Babble (bad cable?)";
- break;
- case -EPROTO:
- errmsg = "Bit-stuff error (bad cable?)";
- break;
- case -EILSEQ:
- errmsg = "CRC/Timeout (could be anything)";
- break;
- case -ETIME:
- errmsg = "Device does not respond";
- break;
- }
- if (packet < 0) {
- dprintk(1, "URB status %d [%s].\n", status, errmsg);
- } else {
- dprintk(1, "URB packet %d, status %d [%s].\n",
- packet, status, errmsg);
- }
-}
-
-static inline int dvb_isoc_copy(struct cx231xx *dev, struct urb *urb)
-{
- int i;
-
- if (!dev)
- return 0;
-
- if (dev->state & DEV_DISCONNECTED)
- return 0;
-
- if (urb->status < 0) {
- print_err_status(dev, -1, urb->status);
- if (urb->status == -ENOENT)
- return 0;
- }
-
- for (i = 0; i < urb->number_of_packets; i++) {
- int status = urb->iso_frame_desc[i].status;
-
- if (status < 0) {
- print_err_status(dev, i, status);
- if (urb->iso_frame_desc[i].status != -EPROTO)
- continue;
- }
-
- dvb_dmx_swfilter(&dev->dvb->demux,
- urb->transfer_buffer +
- urb->iso_frame_desc[i].offset,
- urb->iso_frame_desc[i].actual_length);
- }
-
- return 0;
-}
-
-static inline int dvb_bulk_copy(struct cx231xx *dev, struct urb *urb)
-{
- if (!dev)
- return 0;
-
- if (dev->state & DEV_DISCONNECTED)
- return 0;
-
- if (urb->status < 0) {
- print_err_status(dev, -1, urb->status);
- if (urb->status == -ENOENT)
- return 0;
- }
-
- /* Feed the transport payload into the kernel demux */
- dvb_dmx_swfilter(&dev->dvb->demux,
- urb->transfer_buffer, urb->actual_length);
-
- return 0;
-}
-
-static int start_streaming(struct cx231xx_dvb *dvb)
-{
- int rc;
- struct cx231xx *dev = dvb->adapter.priv;
-
- if (dev->USE_ISO) {
- cx231xx_info("DVB transfer mode is ISO.\n");
- mutex_lock(&dev->i2c_lock);
- cx231xx_enable_i2c_port_3(dev, false);
- cx231xx_set_alt_setting(dev, INDEX_TS1, 4);
- cx231xx_enable_i2c_port_3(dev, true);
- mutex_unlock(&dev->i2c_lock);
- rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
- if (rc < 0)
- return rc;
- dev->mode_tv = 1;
- return cx231xx_init_isoc(dev, CX231XX_DVB_MAX_PACKETS,
- CX231XX_DVB_NUM_BUFS,
- dev->ts1_mode.max_pkt_size,
- dvb_isoc_copy);
- } else {
- cx231xx_info("DVB transfer mode is BULK.\n");
- cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
- rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
- if (rc < 0)
- return rc;
- dev->mode_tv = 1;
- return cx231xx_init_bulk(dev, CX231XX_DVB_MAX_PACKETS,
- CX231XX_DVB_NUM_BUFS,
- dev->ts1_mode.max_pkt_size,
- dvb_bulk_copy);
- }
-
-}
-
-static int stop_streaming(struct cx231xx_dvb *dvb)
-{
- struct cx231xx *dev = dvb->adapter.priv;
-
- if (dev->USE_ISO)
- cx231xx_uninit_isoc(dev);
- else
- cx231xx_uninit_bulk(dev);
-
- cx231xx_set_mode(dev, CX231XX_SUSPEND);
-
- return 0;
-}
-
-static int start_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct cx231xx_dvb *dvb = demux->priv;
- int rc, ret;
-
- if (!demux->dmx.frontend)
- return -EINVAL;
-
- mutex_lock(&dvb->lock);
- dvb->nfeeds++;
- rc = dvb->nfeeds;
-
- if (dvb->nfeeds == 1) {
- ret = start_streaming(dvb);
- if (ret < 0)
- rc = ret;
- }
-
- mutex_unlock(&dvb->lock);
- return rc;
-}
-
-static int stop_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct cx231xx_dvb *dvb = demux->priv;
- int err = 0;
-
- mutex_lock(&dvb->lock);
- dvb->nfeeds--;
-
- if (0 == dvb->nfeeds)
- err = stop_streaming(dvb);
-
- mutex_unlock(&dvb->lock);
- return err;
-}
-
-/* ------------------------------------------------------------------ */
-static int cx231xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
-{
- struct cx231xx *dev = fe->dvb->priv;
-
- if (acquire)
- return cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
- else
- return cx231xx_set_mode(dev, CX231XX_SUSPEND);
-}
-
-/* ------------------------------------------------------------------ */
-
-static struct xc5000_config cnxt_rde250_tunerconfig = {
- .i2c_address = 0x61,
- .if_khz = 4000,
-};
-static struct xc5000_config cnxt_rdu250_tunerconfig = {
- .i2c_address = 0x61,
- .if_khz = 3250,
-};
-
-/* ------------------------------------------------------------------ */
-#if 0
-static int attach_xc5000(u8 addr, struct cx231xx *dev)
-{
-
- struct dvb_frontend *fe;
- struct xc5000_config cfg;
-
- memset(&cfg, 0, sizeof(cfg));
- cfg.i2c_adap = &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap;
- cfg.i2c_addr = addr;
-
- if (!dev->dvb->frontend) {
- printk(KERN_ERR "%s/2: dvb frontend not attached. "
- "Can't attach xc5000\n", dev->name);
- return -EINVAL;
- }
-
- fe = dvb_attach(xc5000_attach, dev->dvb->frontend, &cfg);
- if (!fe) {
- printk(KERN_ERR "%s/2: xc5000 attach failed\n", dev->name);
- dvb_frontend_detach(dev->dvb->frontend);
- dev->dvb->frontend = NULL;
- return -EINVAL;
- }
-
- printk(KERN_INFO "%s/2: xc5000 attached\n", dev->name);
-
- return 0;
-}
-#endif
-
-int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq)
-{
- int status = 0;
-
- if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) {
-
- struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops;
-
- if (dops->set_analog_params != NULL) {
- struct analog_parameters params;
-
- params.frequency = freq;
- params.std = dev->norm;
- params.mode = 0; /* 0- Air; 1 - cable */
- /*params.audmode = ; */
-
- /* Set the analog parameters to set the frequency */
- dops->set_analog_params(dev->dvb->frontend, &params);
- }
-
- }
-
- return status;
-}
-
-int cx231xx_reset_analog_tuner(struct cx231xx *dev)
-{
- int status = 0;
-
- if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) {
-
- struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops;
-
- if (dops->init != NULL && !dev->xc_fw_load_done) {
-
- cx231xx_info("Reloading firmware for XC5000\n");
- status = dops->init(dev->dvb->frontend);
- if (status == 0) {
- dev->xc_fw_load_done = 1;
- cx231xx_info
- ("XC5000 firmware download completed\n");
- } else {
- dev->xc_fw_load_done = 0;
- cx231xx_info
- ("XC5000 firmware download failed !!!\n");
- }
- }
-
- }
-
- return status;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int register_dvb(struct cx231xx_dvb *dvb,
- struct module *module,
- struct cx231xx *dev, struct device *device)
-{
- int result;
-
- mutex_init(&dvb->lock);
-
- /* register adapter */
- result = dvb_register_adapter(&dvb->adapter, dev->name, module, device,
- adapter_nr);
- if (result < 0) {
- printk(KERN_WARNING
- "%s: dvb_register_adapter failed (errno = %d)\n",
- dev->name, result);
- goto fail_adapter;
- }
-
- /* Ensure all frontends negotiate bus access */
- dvb->frontend->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl;
-
- dvb->adapter.priv = dev;
-
- /* register frontend */
- result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
- if (result < 0) {
- printk(KERN_WARNING
- "%s: dvb_register_frontend failed (errno = %d)\n",
- dev->name, result);
- goto fail_frontend;
- }
-
- /* register demux stuff */
- dvb->demux.dmx.capabilities =
- DMX_TS_FILTERING | DMX_SECTION_FILTERING |
- DMX_MEMORY_BASED_FILTERING;
- dvb->demux.priv = dvb;
- dvb->demux.filternum = 256;
- dvb->demux.feednum = 256;
- dvb->demux.start_feed = start_feed;
- dvb->demux.stop_feed = stop_feed;
-
- result = dvb_dmx_init(&dvb->demux);
- if (result < 0) {
- printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n",
- dev->name, result);
- goto fail_dmx;
- }
-
- dvb->dmxdev.filternum = 256;
- dvb->dmxdev.demux = &dvb->demux.dmx;
- dvb->dmxdev.capabilities = 0;
- result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
- if (result < 0) {
- printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
- dev->name, result);
- goto fail_dmxdev;
- }
-
- dvb->fe_hw.source = DMX_FRONTEND_0;
- result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- if (result < 0) {
- printk(KERN_WARNING
- "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
- dev->name, result);
- goto fail_fe_hw;
- }
-
- dvb->fe_mem.source = DMX_MEMORY_FE;
- result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
- if (result < 0) {
- printk(KERN_WARNING
- "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
- dev->name, result);
- goto fail_fe_mem;
- }
-
- result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- if (result < 0) {
- printk(KERN_WARNING
- "%s: connect_frontend failed (errno = %d)\n", dev->name,
- result);
- goto fail_fe_conn;
- }
-
- /* register network adapter */
- dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
- return 0;
-
-fail_fe_conn:
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
-fail_fe_mem:
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
-fail_fe_hw:
- dvb_dmxdev_release(&dvb->dmxdev);
-fail_dmxdev:
- dvb_dmx_release(&dvb->demux);
-fail_dmx:
- dvb_unregister_frontend(dvb->frontend);
-fail_frontend:
- dvb_frontend_detach(dvb->frontend);
- dvb_unregister_adapter(&dvb->adapter);
-fail_adapter:
- return result;
-}
-
-static void unregister_dvb(struct cx231xx_dvb *dvb)
-{
- dvb_net_release(&dvb->net);
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- dvb_dmxdev_release(&dvb->dmxdev);
- dvb_dmx_release(&dvb->demux);
- dvb_unregister_frontend(dvb->frontend);
- dvb_frontend_detach(dvb->frontend);
- dvb_unregister_adapter(&dvb->adapter);
-}
-
-static int dvb_init(struct cx231xx *dev)
-{
- int result = 0;
- struct cx231xx_dvb *dvb;
-
- if (!dev->board.has_dvb) {
- /* This device does not support the extension */
- return 0;
- }
-
- dvb = kzalloc(sizeof(struct cx231xx_dvb), GFP_KERNEL);
-
- if (dvb == NULL) {
- printk(KERN_INFO "cx231xx_dvb: memory allocation failed\n");
- return -ENOMEM;
- }
- dev->dvb = dvb;
- dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq;
- dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner;
-
- mutex_lock(&dev->lock);
- cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
- cx231xx_demod_reset(dev);
- /* init frontend */
- switch (dev->model) {
- case CX231XX_BOARD_CNXT_CARRAERA:
- case CX231XX_BOARD_CNXT_RDE_250:
-
- dev->dvb->frontend = dvb_attach(s5h1432_attach,
- &dvico_s5h1432_config,
- &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
-
- if (dev->dvb->frontend == NULL) {
- printk(DRIVER_NAME
- ": Failed to attach s5h1432 front end\n");
- result = -EINVAL;
- goto out_free;
- }
-
- /* define general-purpose callback pointer */
- dvb->frontend->callback = cx231xx_tuner_callback;
-
- if (!dvb_attach(xc5000_attach, dev->dvb->frontend,
- &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
- &cnxt_rde250_tunerconfig)) {
- result = -EINVAL;
- goto out_free;
- }
-
- break;
- case CX231XX_BOARD_CNXT_SHELBY:
- case CX231XX_BOARD_CNXT_RDU_250:
-
- dev->dvb->frontend = dvb_attach(s5h1411_attach,
- &xc5000_s5h1411_config,
- &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
-
- if (dev->dvb->frontend == NULL) {
- printk(DRIVER_NAME
- ": Failed to attach s5h1411 front end\n");
- result = -EINVAL;
- goto out_free;
- }
-
- /* define general-purpose callback pointer */
- dvb->frontend->callback = cx231xx_tuner_callback;
-
- if (!dvb_attach(xc5000_attach, dev->dvb->frontend,
- &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
- &cnxt_rdu250_tunerconfig)) {
- result = -EINVAL;
- goto out_free;
- }
- break;
- case CX231XX_BOARD_CNXT_RDE_253S:
-
- dev->dvb->frontend = dvb_attach(s5h1432_attach,
- &dvico_s5h1432_config,
- &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
-
- if (dev->dvb->frontend == NULL) {
- printk(DRIVER_NAME
- ": Failed to attach s5h1432 front end\n");
- result = -EINVAL;
- goto out_free;
- }
-
- /* define general-purpose callback pointer */
- dvb->frontend->callback = cx231xx_tuner_callback;
-
- if (!dvb_attach(tda18271_attach, dev->dvb->frontend,
- 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
- &cnxt_rde253s_tunerconfig)) {
- result = -EINVAL;
- goto out_free;
- }
- break;
- case CX231XX_BOARD_CNXT_RDU_253S:
-
- dev->dvb->frontend = dvb_attach(s5h1411_attach,
- &tda18271_s5h1411_config,
- &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
-
- if (dev->dvb->frontend == NULL) {
- printk(DRIVER_NAME
- ": Failed to attach s5h1411 front end\n");
- result = -EINVAL;
- goto out_free;
- }
-
- /* define general-purpose callback pointer */
- dvb->frontend->callback = cx231xx_tuner_callback;
-
- if (!dvb_attach(tda18271_attach, dev->dvb->frontend,
- 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
- &cnxt_rde253s_tunerconfig)) {
- result = -EINVAL;
- goto out_free;
- }
- break;
- case CX231XX_BOARD_HAUPPAUGE_EXETER:
-
- printk(KERN_INFO "%s: looking for tuner / demod on i2c bus: %d\n",
- __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap));
-
- dev->dvb->frontend = dvb_attach(lgdt3305_attach,
- &hcw_lgdt3305_config,
- &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap);
-
- if (dev->dvb->frontend == NULL) {
- printk(DRIVER_NAME
- ": Failed to attach LG3305 front end\n");
- result = -EINVAL;
- goto out_free;
- }
-
- /* define general-purpose callback pointer */
- dvb->frontend->callback = cx231xx_tuner_callback;
-
- dvb_attach(tda18271_attach, dev->dvb->frontend,
- 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
- &hcw_tda18271_config);
- break;
-
- case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
- case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID:
-
- printk(KERN_INFO "%s: looking for demod on i2c bus: %d\n",
- __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap));
-
- dev->dvb->frontend = dvb_attach(mb86a20s_attach,
- &pv_mb86a20s_config,
- &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
-
- if (dev->dvb->frontend == NULL) {
- printk(DRIVER_NAME
- ": Failed to attach mb86a20s demod\n");
- result = -EINVAL;
- goto out_free;
- }
-
- /* define general-purpose callback pointer */
- dvb->frontend->callback = cx231xx_tuner_callback;
-
- dvb_attach(tda18271_attach, dev->dvb->frontend,
- 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
- &pv_tda18271_config);
- break;
-
- default:
- printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
- " isn't supported yet\n", dev->name);
- break;
- }
- if (NULL == dvb->frontend) {
- printk(KERN_ERR
- "%s/2: frontend initialization failed\n", dev->name);
- result = -EINVAL;
- goto out_free;
- }
-
- /* register everything */
- result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);
-
- if (result < 0)
- goto out_free;
-
-
- printk(KERN_INFO "Successfully loaded cx231xx-dvb\n");
-
-ret:
- cx231xx_set_mode(dev, CX231XX_SUSPEND);
- mutex_unlock(&dev->lock);
- return result;
-
-out_free:
- kfree(dvb);
- dev->dvb = NULL;
- goto ret;
-}
-
-static int dvb_fini(struct cx231xx *dev)
-{
- if (!dev->board.has_dvb) {
- /* This device does not support the extension */
- return 0;
- }
-
- if (dev->dvb) {
- unregister_dvb(dev->dvb);
- dev->dvb = NULL;
- }
-
- return 0;
-}
-
-static struct cx231xx_ops dvb_ops = {
- .id = CX231XX_DVB,
- .name = "Cx231xx dvb Extension",
- .init = dvb_init,
- .fini = dvb_fini,
-};
-
-static int __init cx231xx_dvb_register(void)
-{
- return cx231xx_register_extension(&dvb_ops);
-}
-
-static void __exit cx231xx_dvb_unregister(void)
-{
- cx231xx_unregister_extension(&dvb_ops);
-}
-
-module_init(cx231xx_dvb_register);
-module_exit(cx231xx_dvb_unregister);
diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/video/cx231xx/cx231xx-i2c.c
deleted file mode 100644
index 781feed406f..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-i2c.c
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- cx231xx-i2c.c - driver for Conexant Cx23100/101/102 USB video capture devices
-
- Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
- Based on em28xx driver
- Based on Cx23885 driver
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <media/v4l2-common.h>
-#include <media/tuner.h>
-
-#include "cx231xx.h"
-
-/* ----------------------------------------------------------- */
-
-static unsigned int i2c_scan;
-module_param(i2c_scan, int, 0444);
-MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
-
-static unsigned int i2c_debug;
-module_param(i2c_debug, int, 0644);
-MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
-
-#define dprintk1(lvl, fmt, args...) \
-do { \
- if (i2c_debug >= lvl) { \
- printk(fmt, ##args); \
- } \
-} while (0)
-
-#define dprintk2(lvl, fmt, args...) \
-do { \
- if (i2c_debug >= lvl) { \
- printk(KERN_DEBUG "%s at %s: " fmt, \
- dev->name, __func__ , ##args); \
- } \
-} while (0)
-
-static inline bool is_tuner(struct cx231xx *dev, struct cx231xx_i2c *bus,
- const struct i2c_msg *msg, int tuner_type)
-{
- if (bus->nr != dev->board.tuner_i2c_master)
- return false;
-
- if (msg->addr != dev->board.tuner_addr)
- return false;
-
- if (dev->tuner_type != tuner_type)
- return false;
-
- return true;
-}
-
-/*
- * cx231xx_i2c_send_bytes()
- */
-int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap,
- const struct i2c_msg *msg)
-{
- struct cx231xx_i2c *bus = i2c_adap->algo_data;
- struct cx231xx *dev = bus->dev;
- struct cx231xx_i2c_xfer_data req_data;
- int status = 0;
- u16 size = 0;
- u8 loop = 0;
- u8 saddr_len = 1;
- u8 *buf_ptr = NULL;
- u16 saddr = 0;
- u8 need_gpio = 0;
-
- if (is_tuner(dev, bus, msg, TUNER_XC5000)) {
- size = msg->len;
-
- if (size == 2) { /* register write sub addr */
- /* Just writing sub address will cause problem
- * to XC5000. So ignore the request */
- return 0;
- } else if (size == 4) { /* register write with sub addr */
- if (msg->len >= 2)
- saddr = msg->buf[0] << 8 | msg->buf[1];
- else if (msg->len == 1)
- saddr = msg->buf[0];
-
- switch (saddr) {
- case 0x0000: /* start tuner calibration mode */
- need_gpio = 1;
- /* FW Loading is done */
- dev->xc_fw_load_done = 1;
- break;
- case 0x000D: /* Set signal source */
- case 0x0001: /* Set TV standard - Video */
- case 0x0002: /* Set TV standard - Audio */
- case 0x0003: /* Set RF Frequency */
- need_gpio = 1;
- break;
- default:
- if (dev->xc_fw_load_done)
- need_gpio = 1;
- break;
- }
-
- if (need_gpio) {
- dprintk1(1,
- "GPIO WRITE: addr 0x%x, len %d, saddr 0x%x\n",
- msg->addr, msg->len, saddr);
-
- return dev->cx231xx_gpio_i2c_write(dev,
- msg->addr,
- msg->buf,
- msg->len);
- }
- }
-
- /* special case for Xc5000 tuner case */
- saddr_len = 1;
-
- /* adjust the length to correct length */
- size -= saddr_len;
- buf_ptr = (u8 *) (msg->buf + 1);
-
- do {
- /* prepare xfer_data struct */
- req_data.dev_addr = msg->addr;
- req_data.direction = msg->flags;
- req_data.saddr_len = saddr_len;
- req_data.saddr_dat = msg->buf[0];
- req_data.buf_size = size > 16 ? 16 : size;
- req_data.p_buffer = (u8 *) (buf_ptr + loop * 16);
-
- bus->i2c_nostop = (size > 16) ? 1 : 0;
- bus->i2c_reserve = (loop == 0) ? 0 : 1;
-
- /* usb send command */
- status = dev->cx231xx_send_usb_command(bus, &req_data);
- loop++;
-
- if (size >= 16)
- size -= 16;
- else
- size = 0;
-
- } while (size > 0);
-
- bus->i2c_nostop = 0;
- bus->i2c_reserve = 0;
-
- } else { /* regular case */
-
- /* prepare xfer_data struct */
- req_data.dev_addr = msg->addr;
- req_data.direction = msg->flags;
- req_data.saddr_len = 0;
- req_data.saddr_dat = 0;
- req_data.buf_size = msg->len;
- req_data.p_buffer = msg->buf;
-
- /* usb send command */
- status = dev->cx231xx_send_usb_command(bus, &req_data);
- }
-
- return status < 0 ? status : 0;
-}
-
-/*
- * cx231xx_i2c_recv_bytes()
- * read a byte from the i2c device
- */
-static int cx231xx_i2c_recv_bytes(struct i2c_adapter *i2c_adap,
- const struct i2c_msg *msg)
-{
- struct cx231xx_i2c *bus = i2c_adap->algo_data;
- struct cx231xx *dev = bus->dev;
- struct cx231xx_i2c_xfer_data req_data;
- int status = 0;
- u16 saddr = 0;
- u8 need_gpio = 0;
-
- if (is_tuner(dev, bus, msg, TUNER_XC5000)) {
- if (msg->len == 2)
- saddr = msg->buf[0] << 8 | msg->buf[1];
- else if (msg->len == 1)
- saddr = msg->buf[0];
-
- if (dev->xc_fw_load_done) {
-
- switch (saddr) {
- case 0x0009: /* BUSY check */
- dprintk1(1,
- "GPIO R E A D: Special case BUSY check \n");
- /*Try read BUSY register, just set it to zero*/
- msg->buf[0] = 0;
- if (msg->len == 2)
- msg->buf[1] = 0;
- return 0;
- case 0x0004: /* read Lock status */
- need_gpio = 1;
- break;
-
- }
-
- if (need_gpio) {
- /* this is a special case to handle Xceive tuner
- clock stretch issue with gpio based I2C */
-
- dprintk1(1,
- "GPIO R E A D: addr 0x%x, len %d, saddr 0x%x\n",
- msg->addr, msg->len,
- msg->buf[0] << 8 | msg->buf[1]);
-
- status =
- dev->cx231xx_gpio_i2c_write(dev, msg->addr,
- msg->buf,
- msg->len);
- status =
- dev->cx231xx_gpio_i2c_read(dev, msg->addr,
- msg->buf,
- msg->len);
- return status;
- }
- }
-
- /* prepare xfer_data struct */
- req_data.dev_addr = msg->addr;
- req_data.direction = msg->flags;
- req_data.saddr_len = msg->len;
- req_data.saddr_dat = msg->buf[0] << 8 | msg->buf[1];
- req_data.buf_size = msg->len;
- req_data.p_buffer = msg->buf;
-
- /* usb send command */
- status = dev->cx231xx_send_usb_command(bus, &req_data);
-
- } else {
-
- /* prepare xfer_data struct */
- req_data.dev_addr = msg->addr;
- req_data.direction = msg->flags;
- req_data.saddr_len = 0;
- req_data.saddr_dat = 0;
- req_data.buf_size = msg->len;
- req_data.p_buffer = msg->buf;
-
- /* usb send command */
- status = dev->cx231xx_send_usb_command(bus, &req_data);
- }
-
- return status < 0 ? status : 0;
-}
-
-/*
- * cx231xx_i2c_recv_bytes_with_saddr()
- * read a byte from the i2c device
- */
-static int cx231xx_i2c_recv_bytes_with_saddr(struct i2c_adapter *i2c_adap,
- const struct i2c_msg *msg1,
- const struct i2c_msg *msg2)
-{
- struct cx231xx_i2c *bus = i2c_adap->algo_data;
- struct cx231xx *dev = bus->dev;
- struct cx231xx_i2c_xfer_data req_data;
- int status = 0;
- u16 saddr = 0;
- u8 need_gpio = 0;
-
- if (msg1->len == 2)
- saddr = msg1->buf[0] << 8 | msg1->buf[1];
- else if (msg1->len == 1)
- saddr = msg1->buf[0];
-
- if (is_tuner(dev, bus, msg2, TUNER_XC5000)) {
- if ((msg2->len < 16)) {
-
- dprintk1(1,
- "i2c_read: addr 0x%x, len %d, saddr 0x%x, len %d\n",
- msg2->addr, msg2->len, saddr, msg1->len);
-
- switch (saddr) {
- case 0x0008: /* read FW load status */
- need_gpio = 1;
- break;
- case 0x0004: /* read Lock status */
- need_gpio = 1;
- break;
- }
-
- if (need_gpio) {
- status =
- dev->cx231xx_gpio_i2c_write(dev, msg1->addr,
- msg1->buf,
- msg1->len);
- status =
- dev->cx231xx_gpio_i2c_read(dev, msg2->addr,
- msg2->buf,
- msg2->len);
- return status;
- }
- }
- }
-
- /* prepare xfer_data struct */
- req_data.dev_addr = msg2->addr;
- req_data.direction = msg2->flags;
- req_data.saddr_len = msg1->len;
- req_data.saddr_dat = saddr;
- req_data.buf_size = msg2->len;
- req_data.p_buffer = msg2->buf;
-
- /* usb send command */
- status = dev->cx231xx_send_usb_command(bus, &req_data);
-
- return status < 0 ? status : 0;
-}
-
-/*
- * cx231xx_i2c_check_for_device()
- * check if there is a i2c_device at the supplied address
- */
-static int cx231xx_i2c_check_for_device(struct i2c_adapter *i2c_adap,
- const struct i2c_msg *msg)
-{
- struct cx231xx_i2c *bus = i2c_adap->algo_data;
- struct cx231xx *dev = bus->dev;
- struct cx231xx_i2c_xfer_data req_data;
- int status = 0;
-
- /* prepare xfer_data struct */
- req_data.dev_addr = msg->addr;
- req_data.direction = msg->flags;
- req_data.saddr_len = 0;
- req_data.saddr_dat = 0;
- req_data.buf_size = 0;
- req_data.p_buffer = NULL;
-
- /* usb send command */
- status = dev->cx231xx_send_usb_command(bus, &req_data);
-
- return status < 0 ? status : 0;
-}
-
-/*
- * cx231xx_i2c_xfer()
- * the main i2c transfer function
- */
-static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg msgs[], int num)
-{
- struct cx231xx_i2c *bus = i2c_adap->algo_data;
- struct cx231xx *dev = bus->dev;
- int addr, rc, i, byte;
-
- if (num <= 0)
- return 0;
- mutex_lock(&dev->i2c_lock);
- for (i = 0; i < num; i++) {
-
- addr = msgs[i].addr >> 1;
-
- dprintk2(2, "%s %s addr=%x len=%d:",
- (msgs[i].flags & I2C_M_RD) ? "read" : "write",
- i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
- if (!msgs[i].len) {
- /* no len: check only for device presence */
- rc = cx231xx_i2c_check_for_device(i2c_adap, &msgs[i]);
- if (rc < 0) {
- dprintk2(2, " no device\n");
- mutex_unlock(&dev->i2c_lock);
- return rc;
- }
-
- } else if (msgs[i].flags & I2C_M_RD) {
- /* read bytes */
- rc = cx231xx_i2c_recv_bytes(i2c_adap, &msgs[i]);
- if (i2c_debug >= 2) {
- for (byte = 0; byte < msgs[i].len; byte++)
- printk(" %02x", msgs[i].buf[byte]);
- }
- } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
- msgs[i].addr == msgs[i + 1].addr
- && (msgs[i].len <= 2) && (bus->nr < 3)) {
- /* read bytes */
- rc = cx231xx_i2c_recv_bytes_with_saddr(i2c_adap,
- &msgs[i],
- &msgs[i + 1]);
- if (i2c_debug >= 2) {
- for (byte = 0; byte < msgs[i].len; byte++)
- printk(" %02x", msgs[i].buf[byte]);
- }
- i++;
- } else {
- /* write bytes */
- if (i2c_debug >= 2) {
- for (byte = 0; byte < msgs[i].len; byte++)
- printk(" %02x", msgs[i].buf[byte]);
- }
- rc = cx231xx_i2c_send_bytes(i2c_adap, &msgs[i]);
- }
- if (rc < 0)
- goto err;
- if (i2c_debug >= 2)
- printk("\n");
- }
- mutex_unlock(&dev->i2c_lock);
- return num;
-err:
- dprintk2(2, " ERROR: %i\n", rc);
- mutex_unlock(&dev->i2c_lock);
- return rc;
-}
-
-/* ----------------------------------------------------------- */
-
-/*
- * functionality()
- */
-static u32 functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm cx231xx_algo = {
- .master_xfer = cx231xx_i2c_xfer,
- .functionality = functionality,
-};
-
-static struct i2c_adapter cx231xx_adap_template = {
- .owner = THIS_MODULE,
- .name = "cx231xx",
- .algo = &cx231xx_algo,
-};
-
-static struct i2c_client cx231xx_client_template = {
- .name = "cx231xx internal",
-};
-
-/* ----------------------------------------------------------- */
-
-/*
- * i2c_devs
- * incomplete list of known devices
- */
-static char *i2c_devs[128] = {
- [0x60 >> 1] = "colibri",
- [0x88 >> 1] = "hammerhead",
- [0x8e >> 1] = "CIR",
- [0x32 >> 1] = "GeminiIII",
- [0x02 >> 1] = "Aquarius",
- [0xa0 >> 1] = "eeprom",
- [0xc0 >> 1] = "tuner",
- [0xc2 >> 1] = "tuner",
-};
-
-/*
- * cx231xx_do_i2c_scan()
- * check i2c address range for devices
- */
-void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c)
-{
- unsigned char buf;
- int i, rc;
-
- cx231xx_info(": Checking for I2C devices ..\n");
- for (i = 0; i < 128; i++) {
- c->addr = i;
- rc = i2c_master_recv(c, &buf, 0);
- if (rc < 0)
- continue;
- cx231xx_info("%s: i2c scan: found device @ 0x%x [%s]\n",
- dev->name, i << 1,
- i2c_devs[i] ? i2c_devs[i] : "???");
- }
- cx231xx_info(": Completed Checking for I2C devices.\n");
-}
-
-/*
- * cx231xx_i2c_register()
- * register i2c bus
- */
-int cx231xx_i2c_register(struct cx231xx_i2c *bus)
-{
- struct cx231xx *dev = bus->dev;
-
- BUG_ON(!dev->cx231xx_send_usb_command);
-
- bus->i2c_adap = cx231xx_adap_template;
- bus->i2c_client = cx231xx_client_template;
- bus->i2c_adap.dev.parent = &dev->udev->dev;
-
- strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name));
-
- bus->i2c_adap.algo_data = bus;
- i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
- i2c_add_adapter(&bus->i2c_adap);
-
- bus->i2c_client.adapter = &bus->i2c_adap;
-
- if (0 == bus->i2c_rc) {
- if (i2c_scan)
- cx231xx_do_i2c_scan(dev, &bus->i2c_client);
- } else
- cx231xx_warn("%s: i2c bus %d register FAILED\n",
- dev->name, bus->nr);
-
- return bus->i2c_rc;
-}
-
-/*
- * cx231xx_i2c_unregister()
- * unregister i2c_bus
- */
-int cx231xx_i2c_unregister(struct cx231xx_i2c *bus)
-{
- i2c_del_adapter(&bus->i2c_adap);
- return 0;
-}
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
deleted file mode 100644
index 96176e9db5a..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-input.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * cx231xx IR glue driver
- *
- * Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * Polaris (cx231xx) has its support for IR's with a design close to MCE.
- * however, a few designs are using an external I2C chip for IR, instead
- * of using the one provided by the chip.
- * This driver provides support for those extra devices
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
-
-#include "cx231xx.h"
-#include <linux/usb.h>
-#include <linux/slab.h>
-
-#define MODULE_NAME "cx231xx-input"
-
-static int get_key_isdbt(struct IR_i2c *ir, u32 *ir_key,
- u32 *ir_raw)
-{
- int rc;
- u8 cmd, scancode;
-
- dev_dbg(&ir->rc->input_dev->dev, "%s\n", __func__);
-
- /* poll IR chip */
- rc = i2c_master_recv(ir->c, &cmd, 1);
- if (rc < 0)
- return rc;
- if (rc != 1)
- return -EIO;
-
- /* it seems that 0xFE indicates that a button is still hold
- down, while 0xff indicates that no button is hold
- down. 0xfe sequences are sometimes interrupted by 0xFF */
-
- if (cmd == 0xff)
- return 0;
-
- scancode =
- ((cmd & 0x01) ? 0x80 : 0) |
- ((cmd & 0x02) ? 0x40 : 0) |
- ((cmd & 0x04) ? 0x20 : 0) |
- ((cmd & 0x08) ? 0x10 : 0) |
- ((cmd & 0x10) ? 0x08 : 0) |
- ((cmd & 0x20) ? 0x04 : 0) |
- ((cmd & 0x40) ? 0x02 : 0) |
- ((cmd & 0x80) ? 0x01 : 0);
-
- dev_dbg(&ir->rc->input_dev->dev, "cmd %02x, scan = %02x\n",
- cmd, scancode);
-
- *ir_key = scancode;
- *ir_raw = scancode;
- return 1;
-}
-
-int cx231xx_ir_init(struct cx231xx *dev)
-{
- struct i2c_board_info info;
- u8 ir_i2c_bus;
-
- dev_dbg(&dev->udev->dev, "%s\n", __func__);
-
- /* Only initialize if a rc keycode map is defined */
- if (!cx231xx_boards[dev->model].rc_map_name)
- return -ENODEV;
-
- request_module("ir-kbd-i2c");
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- memset(&dev->init_data, 0, sizeof(dev->init_data));
- dev->init_data.rc_dev = rc_allocate_device();
- if (!dev->init_data.rc_dev)
- return -ENOMEM;
-
- dev->init_data.name = cx231xx_boards[dev->model].name;
-
- strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
- info.platform_data = &dev->init_data;
-
- /*
- * Board-dependent values
- *
- * For now, there's just one type of hardware design using
- * an i2c device.
- */
- dev->init_data.get_key = get_key_isdbt;
- dev->init_data.ir_codes = cx231xx_boards[dev->model].rc_map_name;
- /* The i2c micro-controller only outputs the cmd part of NEC protocol */
- dev->init_data.rc_dev->scanmask = 0xff;
- dev->init_data.rc_dev->driver_name = "cx231xx";
- dev->init_data.type = RC_TYPE_NEC;
- info.addr = 0x30;
-
- /* Load and bind ir-kbd-i2c */
- ir_i2c_bus = cx231xx_boards[dev->model].ir_i2c_master;
- dev_dbg(&dev->udev->dev, "Trying to bind ir at bus %d, addr 0x%02x\n",
- ir_i2c_bus, info.addr);
- dev->ir_i2c_client = i2c_new_device(&dev->i2c_bus[ir_i2c_bus].i2c_adap, &info);
-
- return 0;
-}
-
-void cx231xx_ir_exit(struct cx231xx *dev)
-{
- if (dev->ir_i2c_client)
- i2c_unregister_device(dev->ir_i2c_client);
- dev->ir_i2c_client = NULL;
-}
diff --git a/drivers/media/video/cx231xx/cx231xx-pcb-cfg.c b/drivers/media/video/cx231xx/cx231xx-pcb-cfg.c
deleted file mode 100644
index 7473c33e823..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-pcb-cfg.c
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- cx231xx-pcb-config.c - driver for Conexant
- Cx23100/101/102 USB video capture devices
-
- Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx231xx.h"
-#include "cx231xx-conf-reg.h"
-
-static unsigned int pcb_debug;
-module_param(pcb_debug, int, 0644);
-MODULE_PARM_DESC(pcb_debug, "enable pcb config debug messages [video]");
-
-/******************************************************************************/
-
-struct pcb_config cx231xx_Scenario[] = {
- {
- INDEX_SELFPOWER_DIGITAL_ONLY, /* index */
- USB_SELF_POWER, /* power_type */
- 0, /* speed , not decide yet */
- MOD_DIGITAL, /* mode */
- SOURCE_TS_BDA, /* ts1_source, digital tv only */
- NOT_SUPPORTED, /* ts2_source */
- NOT_SUPPORTED, /* analog source */
-
- 0, /* digital_index */
- 0, /* analog index */
- 0, /* dif_index */
- 0, /* external_index */
-
- 1, /* only one configuration */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- 1, /* ts1 index */
- NOT_SUPPORTED, /* TS2 index */
- NOT_SUPPORTED, /* AUDIO */
- NOT_SUPPORTED, /* VIDEO */
- NOT_SUPPORTED, /* VANC */
- NOT_SUPPORTED, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- ,
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- ,
- /* full-speed config */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- 1, /* ts1 index */
- NOT_SUPPORTED, /* TS2 index */
- NOT_SUPPORTED, /* AUDIO */
- NOT_SUPPORTED, /* VIDEO */
- NOT_SUPPORTED, /* VANC */
- NOT_SUPPORTED, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- }
- ,
-
- {
- INDEX_SELFPOWER_DUAL_DIGITAL, /* index */
- USB_SELF_POWER, /* power_type */
- 0, /* speed , not decide yet */
- MOD_DIGITAL, /* mode */
- SOURCE_TS_BDA, /* ts1_source, digital tv only */
- 0, /* ts2_source,need update from register */
- NOT_SUPPORTED, /* analog source */
- 0, /* digital_index */
- 0, /* analog index */
- 0, /* dif_index */
- 0, /* external_index */
-
- 1, /* only one configuration */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- 1, /* ts1 index */
- 2, /* TS2 index */
- NOT_SUPPORTED, /* AUDIO */
- NOT_SUPPORTED, /* VIDEO */
- NOT_SUPPORTED, /* VANC */
- NOT_SUPPORTED, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- ,
- /* full-speed */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- 1, /* ts1 index */
- 2, /* TS2 index */
- NOT_SUPPORTED, /* AUDIO */
- NOT_SUPPORTED, /* VIDEO */
- NOT_SUPPORTED, /* VANC */
- NOT_SUPPORTED, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- }
- ,
-
- {
- INDEX_SELFPOWER_ANALOG_ONLY, /* index */
- USB_SELF_POWER, /* power_type */
- 0, /* speed , not decide yet */
- MOD_ANALOG | MOD_DIF | MOD_EXTERNAL, /* mode ,analog tv only */
- NOT_SUPPORTED, /* ts1_source, NOT SUPPORT */
- NOT_SUPPORTED, /* ts2_source,NOT SUPPORT */
- 0, /* analog source, need update */
-
- 0, /* digital_index */
- 0, /* analog index */
- 0, /* dif_index */
- 0, /* external_index */
-
- 1, /* only one configuration */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- NOT_SUPPORTED, /* ts1 index */
- NOT_SUPPORTED, /* TS2 index */
- 1, /* AUDIO */
- 2, /* VIDEO */
- 3, /* VANC */
- 4, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- ,
- /* full-speed */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- NOT_SUPPORTED, /* ts1 index */
- NOT_SUPPORTED, /* TS2 index */
- 1, /* AUDIO */
- 2, /* VIDEO */
- NOT_SUPPORTED, /* VANC */
- NOT_SUPPORTED, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- }
- ,
-
- {
- INDEX_SELFPOWER_DUAL, /* index */
- USB_SELF_POWER, /* power_type */
- 0, /* speed , not decide yet */
- /* mode ,analog tv and digital path */
- MOD_ANALOG | MOD_DIF | MOD_DIGITAL | MOD_EXTERNAL,
- 0, /* ts1_source,will update in register */
- NOT_SUPPORTED, /* ts2_source,NOT SUPPORT */
- 0, /* analog source need update */
- 0, /* digital_index */
- 0, /* analog index */
- 0, /* dif_index */
- 0, /* external_index */
- 1, /* only one configuration */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- 1, /* ts1 index */
- NOT_SUPPORTED, /* TS2 index */
- 2, /* AUDIO */
- 3, /* VIDEO */
- 4, /* VANC */
- 5, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- ,
- /* full-speed */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- 1, /* ts1 index */
- NOT_SUPPORTED, /* TS2 index */
- 2, /* AUDIO */
- 3, /* VIDEO */
- NOT_SUPPORTED, /* VANC */
- NOT_SUPPORTED, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- }
- ,
-
- {
- INDEX_SELFPOWER_TRIPLE, /* index */
- USB_SELF_POWER, /* power_type */
- 0, /* speed , not decide yet */
- /* mode ,analog tv and digital path */
- MOD_ANALOG | MOD_DIF | MOD_DIGITAL | MOD_EXTERNAL,
- 0, /* ts1_source, update in register */
- 0, /* ts2_source,update in register */
- 0, /* analog source, need update */
-
- 0, /* digital_index */
- 0, /* analog index */
- 0, /* dif_index */
- 0, /* external_index */
- 1, /* only one configuration */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- 1, /* ts1 index */
- 2, /* TS2 index */
- 3, /* AUDIO */
- 4, /* VIDEO */
- 5, /* VANC */
- 6, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- ,
- /* full-speed */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- 1, /* ts1 index */
- 2, /* TS2 index */
- 3, /* AUDIO */
- 4, /* VIDEO */
- NOT_SUPPORTED, /* VANC */
- NOT_SUPPORTED, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- }
- ,
-
- {
- INDEX_SELFPOWER_COMPRESSOR, /* index */
- USB_SELF_POWER, /* power_type */
- 0, /* speed , not decide yet */
- /* mode ,analog tv AND DIGITAL path */
- MOD_ANALOG | MOD_DIF | MOD_DIGITAL | MOD_EXTERNAL,
- NOT_SUPPORTED, /* ts1_source, disable */
- SOURCE_TS_BDA, /* ts2_source */
- 0, /* analog source,need update */
- 0, /* digital_index */
- 0, /* analog index */
- 0, /* dif_index */
- 0, /* external_index */
- 1, /* only one configuration */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- NOT_SUPPORTED, /* ts1 index */
- 1, /* TS2 index */
- 2, /* AUDIO */
- 3, /* VIDEO */
- 4, /* VANC */
- 5, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- ,
- /* full-speed */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- NOT_SUPPORTED, /* ts1 index */
- 1, /* TS2 index */
- 2, /* AUDIO */
- 3, /* VIDEO */
- NOT_SUPPORTED, /* VANC */
- NOT_SUPPORTED, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- }
- ,
-
- {
- INDEX_BUSPOWER_DIGITAL_ONLY, /* index */
- USB_BUS_POWER, /* power_type */
- 0, /* speed , not decide yet */
- MOD_DIGITAL, /* mode ,analog tv AND DIGITAL path */
- SOURCE_TS_BDA, /* ts1_source, disable */
- NOT_SUPPORTED, /* ts2_source */
- NOT_SUPPORTED, /* analog source */
-
- 0, /* digital_index */
- 0, /* analog index */
- 0, /* dif_index */
- 0, /* external_index */
-
- 1, /* only one configuration */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index = 2 */
- 1, /* ts1 index */
- NOT_SUPPORTED, /* TS2 index */
- NOT_SUPPORTED, /* AUDIO */
- NOT_SUPPORTED, /* VIDEO */
- NOT_SUPPORTED, /* VANC */
- NOT_SUPPORTED, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- ,
- /* full-speed */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index = 2 */
- 1, /* ts1 index */
- NOT_SUPPORTED, /* TS2 index */
- NOT_SUPPORTED, /* AUDIO */
- NOT_SUPPORTED, /* VIDEO */
- NOT_SUPPORTED, /* VANC */
- NOT_SUPPORTED, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- }
- ,
- {
- INDEX_BUSPOWER_ANALOG_ONLY, /* index */
- USB_BUS_POWER, /* power_type */
- 0, /* speed , not decide yet */
- MOD_ANALOG, /* mode ,analog tv AND DIGITAL path */
- NOT_SUPPORTED, /* ts1_source, disable */
- NOT_SUPPORTED, /* ts2_source */
- SOURCE_ANALOG, /* analog source--analog */
- 0, /* digital_index */
- 0, /* analog index */
- 0, /* dif_index */
- 0, /* external_index */
- 1, /* only one configuration */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- NOT_SUPPORTED, /* ts1 index */
- NOT_SUPPORTED, /* TS2 index */
- 1, /* AUDIO */
- 2, /* VIDEO */
- 3, /* VANC */
- 4, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- ,
- { /* full-speed */
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- NOT_SUPPORTED, /* ts1 index */
- NOT_SUPPORTED, /* TS2 index */
- 1, /* AUDIO */
- 2, /* VIDEO */
- NOT_SUPPORTED, /* VANC */
- NOT_SUPPORTED, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- }
- ,
- {
- INDEX_BUSPOWER_DIF_ONLY, /* index */
- USB_BUS_POWER, /* power_type */
- 0, /* speed , not decide yet */
- /* mode ,analog tv AND DIGITAL path */
- MOD_DIF | MOD_ANALOG | MOD_DIGITAL | MOD_EXTERNAL,
- SOURCE_TS_BDA, /* ts1_source, disable */
- NOT_SUPPORTED, /* ts2_source */
- SOURCE_DIF | SOURCE_ANALOG | SOURCE_EXTERNAL, /* analog source, dif */
- 0, /* digital_index */
- 0, /* analog index */
- 0, /* dif_index */
- 0, /* external_index */
- 1, /* only one configuration */
- {
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- 1, /* ts1 index */
- NOT_SUPPORTED, /* TS2 index */
- 2, /* AUDIO */
- 3, /* VIDEO */
- 4, /* VANC */
- 5, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- ,
- { /* full speed */
- {
- 0, /* config index */
- {
- 0, /* interrupt ep index */
- 1, /* ts1 index */
- NOT_SUPPORTED, /* TS2 index */
- 2, /* AUDIO */
- 3, /* VIDEO */
- NOT_SUPPORTED, /* VANC */
- NOT_SUPPORTED, /* HANC */
- NOT_SUPPORTED /* ir_index */
- }
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- ,
- {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
- NOT_SUPPORTED}
- }
- }
- }
- ,
-
-};
-
-/*****************************************************************/
-
-u32 initialize_cx231xx(struct cx231xx *dev)
-{
- u32 config_info = 0;
- struct pcb_config *p_pcb_info;
- u8 usb_speed = 1; /* from register,1--HS, 0--FS */
- u8 data[4] = { 0, 0, 0, 0 };
- u32 ts1_source = 0;
- u32 ts2_source = 0;
- u32 analog_source = 0;
- u8 _current_scenario_idx = 0xff;
-
- ts1_source = SOURCE_TS_BDA;
- ts2_source = SOURCE_TS_BDA;
-
- /* read board config register to find out which
- pcb config it is related to */
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, data, 4);
-
- config_info = *((u32 *) data);
- usb_speed = (u8) (config_info & 0x1);
-
- /* Verify this device belongs to Bus power or Self power device */
- if (config_info & BUS_POWER) { /* bus-power */
- switch (config_info & BUSPOWER_MASK) {
- case TS1_PORT | BUS_POWER:
- cx231xx_Scenario[INDEX_BUSPOWER_DIGITAL_ONLY].speed =
- usb_speed;
- p_pcb_info =
- &cx231xx_Scenario[INDEX_BUSPOWER_DIGITAL_ONLY];
- _current_scenario_idx = INDEX_BUSPOWER_DIGITAL_ONLY;
- break;
- case AVDEC_ENABLE | BUS_POWER:
- cx231xx_Scenario[INDEX_BUSPOWER_ANALOG_ONLY].speed =
- usb_speed;
- p_pcb_info =
- &cx231xx_Scenario[INDEX_BUSPOWER_ANALOG_ONLY];
- _current_scenario_idx = INDEX_BUSPOWER_ANALOG_ONLY;
- break;
- case AVDEC_ENABLE | BUS_POWER | TS1_PORT:
- cx231xx_Scenario[INDEX_BUSPOWER_DIF_ONLY].speed =
- usb_speed;
- p_pcb_info = &cx231xx_Scenario[INDEX_BUSPOWER_DIF_ONLY];
- _current_scenario_idx = INDEX_BUSPOWER_DIF_ONLY;
- break;
- default:
- cx231xx_info("bad config in buspower!!!!\n");
- cx231xx_info("config_info=%x\n",
- (config_info & BUSPOWER_MASK));
- return 1;
- }
- } else { /* self-power */
-
- switch (config_info & SELFPOWER_MASK) {
- case TS1_PORT | SELF_POWER:
- cx231xx_Scenario[INDEX_SELFPOWER_DIGITAL_ONLY].speed =
- usb_speed;
- p_pcb_info =
- &cx231xx_Scenario[INDEX_SELFPOWER_DIGITAL_ONLY];
- _current_scenario_idx = INDEX_SELFPOWER_DIGITAL_ONLY;
- break;
- case TS1_TS2_PORT | SELF_POWER:
- cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL].speed =
- usb_speed;
- cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL].
- ts2_source = ts2_source;
- p_pcb_info =
- &cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL];
- _current_scenario_idx = INDEX_SELFPOWER_DUAL_DIGITAL;
- break;
- case AVDEC_ENABLE | SELF_POWER:
- cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY].speed =
- usb_speed;
- cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY].
- analog_source = analog_source;
- p_pcb_info =
- &cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY];
- _current_scenario_idx = INDEX_SELFPOWER_ANALOG_ONLY;
- break;
- case AVDEC_ENABLE | TS1_PORT | SELF_POWER:
- cx231xx_Scenario[INDEX_SELFPOWER_DUAL].speed =
- usb_speed;
- cx231xx_Scenario[INDEX_SELFPOWER_DUAL].ts1_source =
- ts1_source;
- cx231xx_Scenario[INDEX_SELFPOWER_DUAL].analog_source =
- analog_source;
- p_pcb_info = &cx231xx_Scenario[INDEX_SELFPOWER_DUAL];
- _current_scenario_idx = INDEX_SELFPOWER_DUAL;
- break;
- case AVDEC_ENABLE | TS1_TS2_PORT | SELF_POWER:
- cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].speed =
- usb_speed;
- cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].ts1_source =
- ts1_source;
- cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].ts2_source =
- ts2_source;
- cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].analog_source =
- analog_source;
- p_pcb_info = &cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE];
- _current_scenario_idx = INDEX_SELFPOWER_TRIPLE;
- break;
- case AVDEC_ENABLE | TS1VIP_TS2_PORT | SELF_POWER:
- cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR].speed =
- usb_speed;
- cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR].
- analog_source = analog_source;
- p_pcb_info =
- &cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR];
- _current_scenario_idx = INDEX_SELFPOWER_COMPRESSOR;
- break;
- default:
- cx231xx_info("bad senario!!!!!\n");
- cx231xx_info("config_info=%x\n",
- (config_info & SELFPOWER_MASK));
- return 1;
- }
- }
-
- dev->current_scenario_idx = _current_scenario_idx;
-
- memcpy(&dev->current_pcb_config, p_pcb_info,
- sizeof(struct pcb_config));
-
- if (pcb_debug) {
- cx231xx_info("SC(0x00) register = 0x%x\n", config_info);
- cx231xx_info("scenario %d\n",
- (dev->current_pcb_config.index) + 1);
- cx231xx_info("type=%x\n", dev->current_pcb_config.type);
- cx231xx_info("mode=%x\n", dev->current_pcb_config.mode);
- cx231xx_info("speed=%x\n", dev->current_pcb_config.speed);
- cx231xx_info("ts1_source=%x\n",
- dev->current_pcb_config.ts1_source);
- cx231xx_info("ts2_source=%x\n",
- dev->current_pcb_config.ts2_source);
- cx231xx_info("analog_source=%x\n",
- dev->current_pcb_config.analog_source);
- }
-
- return 0;
-}
diff --git a/drivers/media/video/cx231xx/cx231xx-pcb-cfg.h b/drivers/media/video/cx231xx/cx231xx-pcb-cfg.h
deleted file mode 100644
index f5e46e89f3a..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-pcb-cfg.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- cx231xx-pcb-cfg.h - driver for Conexant
- Cx23100/101/102 USB video capture devices
-
- Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _PCB_CONFIG_H_
-#define _PCB_CONFIG_H_
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-/***************************************************************************
- * Class Information *
-***************************************************************************/
-#define CLASS_DEFAULT 0xFF
-
-enum VENDOR_REQUEST_TYPE {
- /* Set/Get I2C */
- VRT_SET_I2C0 = 0x0,
- VRT_SET_I2C1 = 0x1,
- VRT_SET_I2C2 = 0x2,
- VRT_GET_I2C0 = 0x4,
- VRT_GET_I2C1 = 0x5,
- VRT_GET_I2C2 = 0x6,
-
- /* Set/Get GPIO */
- VRT_SET_GPIO = 0x8,
- VRT_GET_GPIO = 0x9,
-
- /* Set/Get GPIE */
- VRT_SET_GPIE = 0xA,
- VRT_GET_GPIE = 0xB,
-
- /* Set/Get Register Control/Status */
- VRT_SET_REGISTER = 0xC,
- VRT_GET_REGISTER = 0xD,
-
- /* Get Extended Compat ID Descriptor */
- VRT_GET_EXTCID_DESC = 0xFF,
-};
-
-enum BYTE_ENABLE_MASK {
- ENABLE_ONE_BYTE = 0x1,
- ENABLE_TWE_BYTE = 0x3,
- ENABLE_THREE_BYTE = 0x7,
- ENABLE_FOUR_BYTE = 0xF,
-};
-
-#define SPEED_MASK 0x1
-enum USB_SPEED{
- FULL_SPEED = 0x0, /* 0: full speed */
- HIGH_SPEED = 0x1 /* 1: high speed */
-};
-
-enum _true_false{
- FALSE = 0,
- TRUE = 1
-};
-
-#define TS_MASK 0x6
-enum TS_PORT{
- NO_TS_PORT = 0x0, /* 2'b00: Neither port used. PCB not a Hybrid,
- only offers Analog TV or Video */
- TS1_PORT = 0x4, /* 2'b10: TS1 Input (Hybrid mode :
- Digital or External Analog/Compressed source) */
- TS1_TS2_PORT = 0x6, /* 2'b11: TS1 & TS2 Inputs
- (Dual inputs from Digital and/or
- External Analog/Compressed sources) */
- TS1_EXT_CLOCK = 0x6, /* 2'b11: TS1 & TS2 as selector
- to external clock */
- TS1VIP_TS2_PORT = 0x2 /* 2'b01: TS1 used as 656/VIP Output,
- TS2 Input (from Compressor) */
-};
-
-#define EAVP_MASK 0x8
-enum EAV_PRESENT{
- NO_EXTERNAL_AV = 0x0, /* 0: No External A/V inputs
- (no need for i2s blcok),
- Analog Tuner must be present */
- EXTERNAL_AV = 0x8 /* 1: External A/V inputs
- present (requires i2s blk) */
-};
-
-#define ATM_MASK 0x30
-enum AT_MODE{
- DIF_TUNER = 0x30, /* 2'b11: IF Tuner (requires use of DIF) */
- BASEBAND_SOUND = 0x20, /* 2'b10: Baseband Composite &
- Sound-IF Signals present */
- NO_TUNER = 0x10 /* 2'b0x: No Analog Tuner present */
-};
-
-#define PWR_SEL_MASK 0x40
-enum POWE_TYPE{
- SELF_POWER = 0x0, /* 0: self power */
- BUS_POWER = 0x40 /* 1: bus power */
-};
-
-enum USB_POWE_TYPE{
- USB_SELF_POWER = 0,
- USB_BUS_POWER
-};
-
-#define BO_0_MASK 0x80
-enum AVDEC_STATUS{
- AVDEC_DISABLE = 0x0, /* 0: A/V Decoder Disabled */
- AVDEC_ENABLE = 0x80 /* 1: A/V Decoder Enabled */
-};
-
-#define BO_1_MASK 0x100
-
-#define BUSPOWER_MASK 0xC4 /* for Polaris spec 0.8 */
-#define SELFPOWER_MASK 0x86
-
-/***************************************************************************/
-#define NOT_DECIDE_YET 0xFE
-#define NOT_SUPPORTED 0xFF
-
-/***************************************************************************
- * for mod field use *
-***************************************************************************/
-#define MOD_DIGITAL 0x1
-#define MOD_ANALOG 0x2
-#define MOD_DIF 0x4
-#define MOD_EXTERNAL 0x8
-#define CAP_ALL_MOD 0x0f
-
-/***************************************************************************
- * source define *
-***************************************************************************/
-#define SOURCE_DIGITAL 0x1
-#define SOURCE_ANALOG 0x2
-#define SOURCE_DIF 0x4
-#define SOURCE_EXTERNAL 0x8
-#define SOURCE_TS_BDA 0x10
-#define SOURCE_TS_ENCODE 0x20
-#define SOURCE_TS_EXTERNAL 0x40
-
-/***************************************************************************
- * interface information define *
-***************************************************************************/
-struct INTERFACE_INFO {
- u8 interrupt_index;
- u8 ts1_index;
- u8 ts2_index;
- u8 audio_index;
- u8 video_index;
- u8 vanc_index; /* VBI */
- u8 hanc_index; /* Sliced CC */
- u8 ir_index;
-};
-
-enum INDEX_INTERFACE_INFO{
- INDEX_INTERRUPT = 0x0,
- INDEX_TS1,
- INDEX_TS2,
- INDEX_AUDIO,
- INDEX_VIDEO,
- INDEX_VANC,
- INDEX_HANC,
- INDEX_IR,
-};
-
-/***************************************************************************
- * configuration information define *
-***************************************************************************/
-struct CONFIG_INFO {
- u8 config_index;
- struct INTERFACE_INFO interface_info;
-};
-
-struct pcb_config {
- u8 index;
- u8 type; /* bus power or self power,
- self power--0, bus_power--1 */
- u8 speed; /* usb speed, 2.0--1, 1.1--0 */
- u8 mode; /* digital , anlog, dif or external A/V */
- u32 ts1_source; /* three source -- BDA,External,encode */
- u32 ts2_source;
- u32 analog_source;
- u8 digital_index; /* bus-power used */
- u8 analog_index; /* bus-power used */
- u8 dif_index; /* bus-power used */
- u8 external_index; /* bus-power used */
- u8 config_num; /* current config num, 0,1,2,
- for self-power, always 0 */
- struct CONFIG_INFO hs_config_info[3];
- struct CONFIG_INFO fs_config_info[3];
-};
-
-enum INDEX_PCB_CONFIG{
- INDEX_SELFPOWER_DIGITAL_ONLY = 0x0,
- INDEX_SELFPOWER_DUAL_DIGITAL,
- INDEX_SELFPOWER_ANALOG_ONLY,
- INDEX_SELFPOWER_DUAL,
- INDEX_SELFPOWER_TRIPLE,
- INDEX_SELFPOWER_COMPRESSOR,
- INDEX_BUSPOWER_DIGITAL_ONLY,
- INDEX_BUSPOWER_ANALOG_ONLY,
- INDEX_BUSPOWER_DIF_ONLY,
- INDEX_BUSPOWER_EXTERNAL_ONLY,
- INDEX_BUSPOWER_EXTERNAL_ANALOG,
- INDEX_BUSPOWER_EXTERNAL_DIF,
- INDEX_BUSPOWER_EXTERNAL_DIGITAL,
- INDEX_BUSPOWER_DIGITAL_ANALOG,
- INDEX_BUSPOWER_DIGITAL_DIF,
- INDEX_BUSPOWER_DIGITAL_ANALOG_EXTERNAL,
- INDEX_BUSPOWER_DIGITAL_DIF_EXTERNAL,
-};
-
-/***************************************************************************/
-struct cx231xx;
-
-u32 initialize_cx231xx(struct cx231xx *p_dev);
-
-#endif
diff --git a/drivers/media/video/cx231xx/cx231xx-reg.h b/drivers/media/video/cx231xx/cx231xx-reg.h
deleted file mode 100644
index 750c5d37d56..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-reg.h
+++ /dev/null
@@ -1,1564 +0,0 @@
-/*
- cx231xx-reg.h - driver for Conexant Cx23100/101/102
- USB video capture devices
-
- Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _CX231XX_REG_H
-#define _CX231XX_REG_H
-
-/*****************************************************************************
- * VBI codes *
-*****************************************************************************/
-
-#define SAV_ACTIVE_VIDEO_FIELD1 0x80
-#define EAV_ACTIVE_VIDEO_FIELD1 0x90
-
-#define SAV_ACTIVE_VIDEO_FIELD2 0xc0
-#define EAV_ACTIVE_VIDEO_FIELD2 0xd0
-
-#define SAV_VBLANK_FIELD1 0xa0
-#define EAV_VBLANK_FIELD1 0xb0
-
-#define SAV_VBLANK_FIELD2 0xe0
-#define EAV_VBLANK_FIELD2 0xf0
-
-#define SAV_VBI_FIELD1 0x20
-#define EAV_VBI_FIELD1 0x30
-
-#define SAV_VBI_FIELD2 0x60
-#define EAV_VBI_FIELD2 0x70
-
-/*****************************************************************************/
-/* Audio ADC Registers */
-#define CH_PWR_CTRL1 0x0000000e
-#define CH_PWR_CTRL2 0x0000000f
-/*****************************************************************************/
-
-#define HOST_REG1 0x000
-#define FLD_FORCE_CHIP_SEL 0x80
-#define FLD_AUTO_INC_DIS 0x20
-#define FLD_PREFETCH_EN 0x10
-/* Reserved [2:3] */
-#define FLD_DIGITAL_PWR_DN 0x02
-#define FLD_SLEEP 0x01
-
-/*****************************************************************************/
-#define HOST_REG2 0x001
-
-/*****************************************************************************/
-#define HOST_REG3 0x002
-
-/*****************************************************************************/
-/* added for polaris */
-#define GPIO_PIN_CTL0 0x3
-#define GPIO_PIN_CTL1 0x4
-#define GPIO_PIN_CTL2 0x5
-#define GPIO_PIN_CTL3 0x6
-#define TS1_PIN_CTL0 0x7
-#define TS1_PIN_CTL1 0x8
-/*****************************************************************************/
-
-#define FLD_CLK_IN_EN 0x80
-#define FLD_XTAL_CTRL 0x70
-#define FLD_BB_CLK_MODE 0x0C
-#define FLD_REF_DIV_PLL 0x02
-#define FLD_REF_SEL_PLL1 0x01
-
-/*****************************************************************************/
-#define CHIP_CTRL 0x100
-/* Reserved [27] */
-/* Reserved [31:21] */
-#define FLD_CHIP_ACFG_DIS 0x00100000
-/* Reserved [19] */
-#define FLD_DUAL_MODE_ADC2 0x00040000
-#define FLD_SIF_EN 0x00020000
-#define FLD_SOFT_RST 0x00010000
-#define FLD_DEVICE_ID 0x0000ffff
-
-/*****************************************************************************/
-#define AFE_CTRL 0x104
-#define AFE_CTRL_C2HH_SRC_CTRL 0x104
-#define FLD_DIF_OUT_SEL 0xc0000000
-#define FLD_AUX_PLL_CLK_ALT_SEL 0x3c000000
-#define FLD_UV_ORDER_MODE 0x02000000
-#define FLD_FUNC_MODE 0x01800000
-#define FLD_ROT1_PHASE_CTL 0x007f8000
-#define FLD_AUD_IN_SEL 0x00004000
-#define FLD_LUMA_IN_SEL 0x00002000
-#define FLD_CHROMA_IN_SEL 0x00001000
-/* reserve [11:10] */
-#define FLD_INV_SPEC_DIS 0x00000200
-#define FLD_VGA_SEL_CH3 0x00000100
-#define FLD_VGA_SEL_CH2 0x00000080
-#define FLD_VGA_SEL_CH1 0x00000040
-#define FLD_DCR_BYP_CH1 0x00000020
-#define FLD_DCR_BYP_CH2 0x00000010
-#define FLD_DCR_BYP_CH3 0x00000008
-#define FLD_EN_12DB_CH3 0x00000004
-#define FLD_EN_12DB_CH2 0x00000002
-#define FLD_EN_12DB_CH1 0x00000001
-
-/* redefine in Cx231xx */
-/*****************************************************************************/
-#define DC_CTRL1 0x108
-/* reserve [31:30] */
-#define FLD_CLAMP_LVL_CH1 0x3fff8000
-#define FLD_CLAMP_LVL_CH2 0x00007fff
-/*****************************************************************************/
-
-/*****************************************************************************/
-#define DC_CTRL2 0x10c
-/* reserve [31:28] */
-#define FLD_CLAMP_LVL_CH3 0x00fffe00
-#define FLD_CLAMP_WIND_LENTH 0x000001e0
-#define FLD_C2HH_SAT_MIN 0x0000001e
-#define FLD_FLT_BYP_SEL 0x00000001
-/*****************************************************************************/
-
-/*****************************************************************************/
-#define DC_CTRL3 0x110
-/* reserve [31:16] */
-#define FLD_ERR_GAIN_CTL 0x00070000
-#define FLD_LPF_MIN 0x0000ffff
-/*****************************************************************************/
-
-/*****************************************************************************/
-#define DC_CTRL4 0x114
-/* reserve [31:31] */
-#define FLD_INTG_CH1 0x7fffffff
-/*****************************************************************************/
-
-/*****************************************************************************/
-#define DC_CTRL5 0x118
-/* reserve [31:31] */
-#define FLD_INTG_CH2 0x7fffffff
-/*****************************************************************************/
-
-/*****************************************************************************/
-#define DC_CTRL6 0x11c
-/* reserve [31:31] */
-#define FLD_INTG_CH3 0x7fffffff
-/*****************************************************************************/
-
-/*****************************************************************************/
-#define PIN_CTRL 0x120
-#define FLD_OEF_AGC_RF 0x00000001
-#define FLD_OEF_AGC_IFVGA 0x00000002
-#define FLD_OEF_AGC_IF 0x00000004
-#define FLD_REG_BO_PUD 0x80000000
-#define FLD_IR_IRQ_STAT 0x40000000
-#define FLD_AUD_IRQ_STAT 0x20000000
-#define FLD_VID_IRQ_STAT 0x10000000
-/* Reserved [27:26] */
-#define FLD_IRQ_N_OUT_EN 0x02000000
-#define FLD_IRQ_N_POLAR 0x01000000
-/* Reserved [23:6] */
-#define FLD_OE_AUX_PLL_CLK 0x00000020
-#define FLD_OE_I2S_BCLK 0x00000010
-#define FLD_OE_I2S_WCLK 0x00000008
-#define FLD_OE_AGC_IF 0x00000004
-#define FLD_OE_AGC_IFVGA 0x00000002
-#define FLD_OE_AGC_RF 0x00000001
-
-/*****************************************************************************/
-#define AUD_IO_CTRL 0x124
-/* Reserved [31:8] */
-#define FLD_I2S_PORT_DIR 0x00000080
-#define FLD_I2S_OUT_SRC 0x00000040
-#define FLD_AUD_CHAN3_SRC 0x00000030
-#define FLD_AUD_CHAN2_SRC 0x0000000c
-#define FLD_AUD_CHAN1_SRC 0x00000003
-
-/*****************************************************************************/
-#define AUD_LOCK1 0x128
-#define FLD_AUD_LOCK_KI_SHIFT 0xc0000000
-#define FLD_AUD_LOCK_KD_SHIFT 0x30000000
-/* Reserved [27:25] */
-#define FLD_EN_AV_LOCK 0x01000000
-#define FLD_VID_COUNT 0x00ffffff
-
-/*****************************************************************************/
-#define AUD_LOCK2 0x12c
-#define FLD_AUD_LOCK_KI_MULT 0xf0000000
-#define FLD_AUD_LOCK_KD_MULT 0x0F000000
-/* Reserved [23:22] */
-#define FLD_AUD_LOCK_FREQ_SHIFT 0x00300000
-#define FLD_AUD_COUNT 0x000fffff
-
-/*****************************************************************************/
-#define AFE_DIAG_CTRL1 0x134
-/* Reserved [31:16] */
-#define FLD_CUV_DLY_LENGTH 0x0000ff00
-#define FLD_YC_DLY_LENGTH 0x000000ff
-
-/*****************************************************************************/
-/* Poalris redefine */
-#define AFE_DIAG_CTRL3 0x138
-/* Reserved [31:26] */
-#define FLD_AUD_DUAL_FLAG_POL 0x02000000
-#define FLD_VID_DUAL_FLAG_POL 0x01000000
-/* Reserved [23:23] */
-#define FLD_COL_CLAMP_DIS_CH1 0x00400000
-#define FLD_COL_CLAMP_DIS_CH2 0x00200000
-#define FLD_COL_CLAMP_DIS_CH3 0x00100000
-
-#define TEST_CTRL1 0x144
-/* Reserved [31:29] */
-#define FLD_LBIST_EN 0x10000000
-/* Reserved [27:10] */
-#define FLD_FI_BIST_INTR_R 0x0000200
-#define FLD_FI_BIST_INTR_L 0x0000100
-#define FLD_BIST_FAIL_AUD_PLL 0x0000080
-#define FLD_BIST_INTR_AUD_PLL 0x0000040
-#define FLD_BIST_FAIL_VID_PLL 0x0000020
-#define FLD_BIST_INTR_VID_PLL 0x0000010
-/* Reserved [3:1] */
-#define FLD_CIR_TEST_DIS 0x00000001
-
-/*****************************************************************************/
-#define TEST_CTRL2 0x148
-#define FLD_TSXCLK_POL_CTL 0x80000000
-#define FLD_ISO_CTL_SEL 0x40000000
-#define FLD_ISO_CTL_EN 0x20000000
-#define FLD_BIST_DEBUGZ 0x10000000
-#define FLD_AUD_BIST_TEST_H 0x0f000000
-/* Reserved [23:22] */
-#define FLD_FLTRN_BIST_TEST_H 0x00020000
-#define FLD_VID_BIST_TEST_H 0x00010000
-/* Reserved [19:17] */
-#define FLD_BIST_TEST_H 0x00010000
-/* Reserved [15:13] */
-#define FLD_TAB_EN 0x00001000
-/* Reserved [11:0] */
-
-/*****************************************************************************/
-#define BIST_STAT 0x14c
-#define FLD_AUD_BIST_FAIL_H 0xfff00000
-#define FLD_FLTRN_BIST_FAIL_H 0x00180000
-#define FLD_VID_BIST_FAIL_H 0x00070000
-#define FLD_AUD_BIST_TST_DONE 0x0000fff0
-#define FLD_FLTRN_BIST_TST_DONE 0x00000008
-#define FLD_VID_BIST_TST_DONE 0x00000007
-
-/*****************************************************************************/
-/* DirectIF registers definition have been moved to DIF_reg.h */
-/*****************************************************************************/
-#define MODE_CTRL 0x400
-#define FLD_AFD_PAL60_DIS 0x20000000
-#define FLD_AFD_FORCE_SECAM 0x10000000
-#define FLD_AFD_FORCE_PALNC 0x08000000
-#define FLD_AFD_FORCE_PAL 0x04000000
-#define FLD_AFD_PALM_SEL 0x03000000
-#define FLD_CKILL_MODE 0x00300000
-#define FLD_COMB_NOTCH_MODE 0x00c00000 /* bit[19:18] */
-#define FLD_CLR_LOCK_STAT 0x00020000
-#define FLD_FAST_LOCK_MD 0x00010000
-#define FLD_WCEN 0x00008000
-#define FLD_CAGCEN 0x00004000
-#define FLD_CKILLEN 0x00002000
-#define FLD_AUTO_SC_LOCK 0x00001000
-#define FLD_MAN_SC_FAST_LOCK 0x00000800
-#define FLD_INPUT_MODE 0x00000600
-#define FLD_AFD_ACQUIRE 0x00000100
-#define FLD_AFD_NTSC_SEL 0x00000080
-#define FLD_AFD_PAL_SEL 0x00000040
-#define FLD_ACFG_DIS 0x00000020
-#define FLD_SQ_PIXEL 0x00000010
-#define FLD_VID_FMT_SEL 0x0000000f
-
-/*****************************************************************************/
-#define OUT_CTRL1 0x404
-#define FLD_POLAR 0x7f000000
-/* Reserved [23] */
-#define FLD_RND_MODE 0x00600000
-#define FLD_VIPCLAMP_EN 0x00100000
-#define FLD_VIPBLANK_EN 0x00080000
-#define FLD_VIP_OPT_AL 0x00040000
-#define FLD_IDID0_SOURCE 0x00020000
-#define FLD_DCMODE 0x00010000
-#define FLD_CLK_GATING 0x0000c000
-#define FLD_CLK_INVERT 0x00002000
-#define FLD_HSFMT 0x00001000
-#define FLD_VALIDFMT 0x00000800
-#define FLD_ACTFMT 0x00000400
-#define FLD_SWAPRAW 0x00000200
-#define FLD_CLAMPRAW_EN 0x00000100
-#define FLD_BLUE_FIELD_EN 0x00000080
-#define FLD_BLUE_FIELD_ACT 0x00000040
-#define FLD_TASKBIT_VAL 0x00000020
-#define FLD_ANC_DATA_EN 0x00000010
-#define FLD_VBIHACTRAW_EN 0x00000008
-#define FLD_MODE10B 0x00000004
-#define FLD_OUT_MODE 0x00000003
-
-/*****************************************************************************/
-#define OUT_CTRL2 0x408
-#define FLD_AUD_GRP 0xc0000000
-#define FLD_SAMPLE_RATE 0x30000000
-#define FLD_AUD_ANC_EN 0x08000000
-#define FLD_EN_C 0x04000000
-#define FLD_EN_B 0x02000000
-#define FLD_EN_A 0x01000000
-/* Reserved [23:20] */
-#define FLD_IDID1_LSB 0x000c0000
-#define FLD_IDID0_LSB 0x00030000
-#define FLD_IDID1_MSB 0x0000ff00
-#define FLD_IDID0_MSB 0x000000ff
-
-/*****************************************************************************/
-#define GEN_STAT 0x40c
-#define FLD_VCR_DETECT 0x00800000
-#define FLD_SPECIAL_PLAY_N 0x00400000
-#define FLD_VPRES 0x00200000
-#define FLD_AGC_LOCK 0x00100000
-#define FLD_CSC_LOCK 0x00080000
-#define FLD_VLOCK 0x00040000
-#define FLD_SRC_LOCK 0x00020000
-#define FLD_HLOCK 0x00010000
-#define FLD_VSYNC_N 0x00008000
-#define FLD_SRC_FIFO_UFLOW 0x00004000
-#define FLD_SRC_FIFO_OFLOW 0x00002000
-#define FLD_FIELD 0x00001000
-#define FLD_AFD_FMT_STAT 0x00000f00
-#define FLD_MV_TYPE2_PAIR 0x00000080
-#define FLD_MV_T3CS 0x00000040
-#define FLD_MV_CS 0x00000020
-#define FLD_MV_PSP 0x00000010
-/* Reserved [3] */
-#define FLD_MV_CDAT 0x00000003
-
-/*****************************************************************************/
-#define INT_STAT_MASK 0x410
-#define FLD_COMB_3D_FIFO_MSK 0x80000000
-#define FLD_WSS_DAT_AVAIL_MSK 0x40000000
-#define FLD_GS2_DAT_AVAIL_MSK 0x20000000
-#define FLD_GS1_DAT_AVAIL_MSK 0x10000000
-#define FLD_CC_DAT_AVAIL_MSK 0x08000000
-#define FLD_VPRES_CHANGE_MSK 0x04000000
-#define FLD_MV_CHANGE_MSK 0x02000000
-#define FLD_END_VBI_EVEN_MSK 0x01000000
-#define FLD_END_VBI_ODD_MSK 0x00800000
-#define FLD_FMT_CHANGE_MSK 0x00400000
-#define FLD_VSYNC_TRAIL_MSK 0x00200000
-#define FLD_HLOCK_CHANGE_MSK 0x00100000
-#define FLD_VLOCK_CHANGE_MSK 0x00080000
-#define FLD_CSC_LOCK_CHANGE_MSK 0x00040000
-#define FLD_SRC_FIFO_UFLOW_MSK 0x00020000
-#define FLD_SRC_FIFO_OFLOW_MSK 0x00010000
-#define FLD_COMB_3D_FIFO_STAT 0x00008000
-#define FLD_WSS_DAT_AVAIL_STAT 0x00004000
-#define FLD_GS2_DAT_AVAIL_STAT 0x00002000
-#define FLD_GS1_DAT_AVAIL_STAT 0x00001000
-#define FLD_CC_DAT_AVAIL_STAT 0x00000800
-#define FLD_VPRES_CHANGE_STAT 0x00000400
-#define FLD_MV_CHANGE_STAT 0x00000200
-#define FLD_END_VBI_EVEN_STAT 0x00000100
-#define FLD_END_VBI_ODD_STAT 0x00000080
-#define FLD_FMT_CHANGE_STAT 0x00000040
-#define FLD_VSYNC_TRAIL_STAT 0x00000020
-#define FLD_HLOCK_CHANGE_STAT 0x00000010
-#define FLD_VLOCK_CHANGE_STAT 0x00000008
-#define FLD_CSC_LOCK_CHANGE_STAT 0x00000004
-#define FLD_SRC_FIFO_UFLOW_STAT 0x00000002
-#define FLD_SRC_FIFO_OFLOW_STAT 0x00000001
-
-/*****************************************************************************/
-#define LUMA_CTRL 0x414
-#define BRIGHTNESS_CTRL_BYTE 0x414
-#define CONTRAST_CTRL_BYTE 0x415
-#define LUMA_CTRL_BYTE_3 0x416
-#define FLD_LUMA_CORE_SEL 0x00c00000
-#define FLD_RANGE 0x00300000
-/* Reserved [19] */
-#define FLD_PEAK_EN 0x00040000
-#define FLD_PEAK_SEL 0x00030000
-#define FLD_CNTRST 0x0000ff00
-#define FLD_BRITE 0x000000ff
-
-/*****************************************************************************/
-#define HSCALE_CTRL 0x418
-#define FLD_HFILT 0x03000000
-#define FLD_HSCALE 0x00ffffff
-
-/*****************************************************************************/
-#define VSCALE_CTRL 0x41c
-#define FLD_LINE_AVG_DIS 0x01000000
-/* Reserved [23:20] */
-#define FLD_VS_INTRLACE 0x00080000
-#define FLD_VFILT 0x00070000
-/* Reserved [15:13] */
-#define FLD_VSCALE 0x00001fff
-
-/*****************************************************************************/
-#define CHROMA_CTRL 0x420
-#define USAT_CTRL_BYTE 0x420
-#define VSAT_CTRL_BYTE 0x421
-#define HUE_CTRL_BYTE 0x422
-#define FLD_C_LPF_EN 0x20000000
-#define FLD_CHR_DELAY 0x1c000000
-#define FLD_C_CORE_SEL 0x03000000
-#define FLD_HUE 0x00ff0000
-#define FLD_VSAT 0x0000ff00
-#define FLD_USAT 0x000000ff
-
-/*****************************************************************************/
-#define VBI_LINE_CTRL1 0x424
-#define FLD_VBI_MD_LINE4 0xff000000
-#define FLD_VBI_MD_LINE3 0x00ff0000
-#define FLD_VBI_MD_LINE2 0x0000ff00
-#define FLD_VBI_MD_LINE1 0x000000ff
-
-/*****************************************************************************/
-#define VBI_LINE_CTRL2 0x428
-#define FLD_VBI_MD_LINE8 0xff000000
-#define FLD_VBI_MD_LINE7 0x00ff0000
-#define FLD_VBI_MD_LINE6 0x0000ff00
-#define FLD_VBI_MD_LINE5 0x000000ff
-
-/*****************************************************************************/
-#define VBI_LINE_CTRL3 0x42c
-#define FLD_VBI_MD_LINE12 0xff000000
-#define FLD_VBI_MD_LINE11 0x00ff0000
-#define FLD_VBI_MD_LINE10 0x0000ff00
-#define FLD_VBI_MD_LINE9 0x000000ff
-
-/*****************************************************************************/
-#define VBI_LINE_CTRL4 0x430
-#define FLD_VBI_MD_LINE16 0xff000000
-#define FLD_VBI_MD_LINE15 0x00ff0000
-#define FLD_VBI_MD_LINE14 0x0000ff00
-#define FLD_VBI_MD_LINE13 0x000000ff
-
-/*****************************************************************************/
-#define VBI_LINE_CTRL5 0x434
-#define FLD_VBI_MD_LINE17 0x000000ff
-
-/*****************************************************************************/
-#define VBI_FC_CFG 0x438
-#define FLD_FC_ALT2 0xff000000
-#define FLD_FC_ALT1 0x00ff0000
-#define FLD_FC_ALT2_TYPE 0x0000f000
-#define FLD_FC_ALT1_TYPE 0x00000f00
-/* Reserved [7:1] */
-#define FLD_FC_SEARCH_MODE 0x00000001
-
-/*****************************************************************************/
-#define VBI_MISC_CFG1 0x43c
-#define FLD_TTX_PKTADRU 0xfff00000
-#define FLD_TTX_PKTADRL 0x000fff00
-/* Reserved [7:6] */
-#define FLD_MOJI_PACK_DIS 0x00000020
-#define FLD_VPS_DEC_DIS 0x00000010
-#define FLD_CRI_MARG_SCALE 0x0000000c
-#define FLD_EDGE_RESYNC_EN 0x00000002
-#define FLD_ADAPT_SLICE_DIS 0x00000001
-
-/*****************************************************************************/
-#define VBI_MISC_CFG2 0x440
-#define FLD_HAMMING_TYPE 0x0f000000
-/* Reserved [23:20] */
-#define FLD_WSS_FIFO_RST 0x00080000
-#define FLD_GS2_FIFO_RST 0x00040000
-#define FLD_GS1_FIFO_RST 0x00020000
-#define FLD_CC_FIFO_RST 0x00010000
-/* Reserved [15:12] */
-#define FLD_VBI3_SDID 0x00000f00
-#define FLD_VBI2_SDID 0x000000f0
-#define FLD_VBI1_SDID 0x0000000f
-
-/*****************************************************************************/
-#define VBI_PAY1 0x444
-#define FLD_GS1_FIFO_DAT 0xFF000000
-#define FLD_GS1_STAT 0x00FF0000
-#define FLD_CC_FIFO_DAT 0x0000FF00
-#define FLD_CC_STAT 0x000000FF
-
-/*****************************************************************************/
-#define VBI_PAY2 0x448
-#define FLD_WSS_FIFO_DAT 0xff000000
-#define FLD_WSS_STAT 0x00ff0000
-#define FLD_GS2_FIFO_DAT 0x0000ff00
-#define FLD_GS2_STAT 0x000000ff
-
-/*****************************************************************************/
-#define VBI_CUST1_CFG1 0x44c
-/* Reserved [31] */
-#define FLD_VBI1_CRIWIN 0x7f000000
-#define FLD_VBI1_SLICE_DIST 0x00f00000
-#define FLD_VBI1_BITINC 0x000fff00
-#define FLD_VBI1_HDELAY 0x000000ff
-
-/*****************************************************************************/
-#define VBI_CUST1_CFG2 0x450
-#define FLD_VBI1_FC_LENGTH 0x1f000000
-#define FLD_VBI1_FRAME_CODE 0x00ffffff
-
-/*****************************************************************************/
-#define VBI_CUST1_CFG3 0x454
-#define FLD_VBI1_HAM_EN 0x80000000
-#define FLD_VBI1_FIFO_MODE 0x70000000
-#define FLD_VBI1_FORMAT_TYPE 0x0f000000
-#define FLD_VBI1_PAYLD_LENGTH 0x00ff0000
-#define FLD_VBI1_CRI_LENGTH 0x0000f000
-#define FLD_VBI1_CRI_MARGIN 0x00000f00
-#define FLD_VBI1_CRI_TIME 0x000000ff
-
-/*****************************************************************************/
-#define VBI_CUST2_CFG1 0x458
-/* Reserved [31] */
-#define FLD_VBI2_CRIWIN 0x7f000000
-#define FLD_VBI2_SLICE_DIST 0x00f00000
-#define FLD_VBI2_BITINC 0x000fff00
-#define FLD_VBI2_HDELAY 0x000000ff
-
-/*****************************************************************************/
-#define VBI_CUST2_CFG2 0x45c
-#define FLD_VBI2_FC_LENGTH 0x1f000000
-#define FLD_VBI2_FRAME_CODE 0x00ffffff
-
-/*****************************************************************************/
-#define VBI_CUST2_CFG3 0x460
-#define FLD_VBI2_HAM_EN 0x80000000
-#define FLD_VBI2_FIFO_MODE 0x70000000
-#define FLD_VBI2_FORMAT_TYPE 0x0f000000
-#define FLD_VBI2_PAYLD_LENGTH 0x00ff0000
-#define FLD_VBI2_CRI_LENGTH 0x0000f000
-#define FLD_VBI2_CRI_MARGIN 0x00000f00
-#define FLD_VBI2_CRI_TIME 0x000000ff
-
-/*****************************************************************************/
-#define VBI_CUST3_CFG1 0x464
-/* Reserved [31] */
-#define FLD_VBI3_CRIWIN 0x7f000000
-#define FLD_VBI3_SLICE_DIST 0x00f00000
-#define FLD_VBI3_BITINC 0x000fff00
-#define FLD_VBI3_HDELAY 0x000000ff
-
-/*****************************************************************************/
-#define VBI_CUST3_CFG2 0x468
-#define FLD_VBI3_FC_LENGTH 0x1f000000
-#define FLD_VBI3_FRAME_CODE 0x00ffffff
-
-/*****************************************************************************/
-#define VBI_CUST3_CFG3 0x46c
-#define FLD_VBI3_HAM_EN 0x80000000
-#define FLD_VBI3_FIFO_MODE 0x70000000
-#define FLD_VBI3_FORMAT_TYPE 0x0f000000
-#define FLD_VBI3_PAYLD_LENGTH 0x00ff0000
-#define FLD_VBI3_CRI_LENGTH 0x0000f000
-#define FLD_VBI3_CRI_MARGIN 0x00000f00
-#define FLD_VBI3_CRI_TIME 0x000000ff
-
-/*****************************************************************************/
-#define HORIZ_TIM_CTRL 0x470
-#define FLD_BGDEL_CNT 0xff000000
-/* Reserved [23:22] */
-#define FLD_HACTIVE_CNT 0x003ff000
-/* Reserved [11:10] */
-#define FLD_HBLANK_CNT 0x000003ff
-
-/*****************************************************************************/
-#define VERT_TIM_CTRL 0x474
-#define FLD_V656BLANK_CNT 0xff000000
-/* Reserved [23:22] */
-#define FLD_VACTIVE_CNT 0x003ff000
-/* Reserved [11:10] */
-#define FLD_VBLANK_CNT 0x000003ff
-
-/*****************************************************************************/
-#define SRC_COMB_CFG 0x478
-#define FLD_CCOMB_2LN_CHECK 0x80000000
-#define FLD_CCOMB_3LN_EN 0x40000000
-#define FLD_CCOMB_2LN_EN 0x20000000
-#define FLD_CCOMB_3D_EN 0x10000000
-/* Reserved [27] */
-#define FLD_LCOMB_3LN_EN 0x04000000
-#define FLD_LCOMB_2LN_EN 0x02000000
-#define FLD_LCOMB_3D_EN 0x01000000
-#define FLD_LUMA_LPF_SEL 0x00c00000
-#define FLD_UV_LPF_SEL 0x00300000
-#define FLD_BLEND_SLOPE 0x000f0000
-#define FLD_CCOMB_REDUCE_EN 0x00008000
-/* Reserved [14:10] */
-#define FLD_SRC_DECIM_RATIO 0x000003ff
-
-/*****************************************************************************/
-#define CHROMA_VBIOFF_CFG 0x47c
-#define FLD_VBI_VOFFSET 0x1f000000
-/* Reserved [23:20] */
-#define FLD_SC_STEP 0x000fffff
-
-/*****************************************************************************/
-#define FIELD_COUNT 0x480
-#define FLD_FIELD_COUNT_FLD 0x000003ff
-
-/*****************************************************************************/
-#define MISC_TIM_CTRL 0x484
-#define FLD_DEBOUNCE_COUNT 0xc0000000
-#define FLD_VT_LINE_CNT_HYST 0x30000000
-/* Reserved [27] */
-#define FLD_AFD_STAT 0x07ff0000
-#define FLD_VPRES_VERT_EN 0x00008000
-/* Reserved [14:12] */
-#define FLD_HR32 0x00000800
-#define FLD_TDALGN 0x00000400
-#define FLD_TDFIELD 0x00000200
-/* Reserved [8:6] */
-#define FLD_TEMPDEC 0x0000003f
-
-/*****************************************************************************/
-#define DFE_CTRL1 0x488
-#define FLD_CLAMP_AUTO_EN 0x80000000
-#define FLD_AGC_AUTO_EN 0x40000000
-#define FLD_VGA_CRUSH_EN 0x20000000
-#define FLD_VGA_AUTO_EN 0x10000000
-#define FLD_VBI_GATE_EN 0x08000000
-#define FLD_CLAMP_LEVEL 0x07000000
-/* Reserved [23:22] */
-#define FLD_CLAMP_SKIP_CNT 0x00300000
-#define FLD_AGC_GAIN 0x000fff00
-/* Reserved [7:6] */
-#define FLD_VGA_GAIN 0x0000003f
-
-/*****************************************************************************/
-#define DFE_CTRL2 0x48c
-#define FLD_VGA_ACQUIRE_RANGE 0x00ff0000
-#define FLD_VGA_TRACK_RANGE 0x0000ff00
-#define FLD_VGA_SYNC 0x000000ff
-
-/*****************************************************************************/
-#define DFE_CTRL3 0x490
-#define FLD_BP_PERCENT 0xff000000
-#define FLD_DFT_THRESHOLD 0x00ff0000
-/* Reserved [15:12] */
-#define FLD_SYNC_WIDTH_SEL 0x00000600
-#define FLD_BP_LOOP_GAIN 0x00000300
-#define FLD_SYNC_LOOP_GAIN 0x000000c0
-/* Reserved [5:4] */
-#define FLD_AGC_LOOP_GAIN 0x0000000c
-#define FLD_DCC_LOOP_GAIN 0x00000003
-
-/*****************************************************************************/
-#define PLL_CTRL 0x494
-#define FLD_PLL_KD 0xff000000
-#define FLD_PLL_KI 0x00ff0000
-#define FLD_PLL_MAX_OFFSET 0x0000ffff
-
-/*****************************************************************************/
-#define HTL_CTRL 0x498
-/* Reserved [31:24] */
-#define FLD_AUTO_LOCK_SPD 0x00080000
-#define FLD_MAN_FAST_LOCK 0x00040000
-#define FLD_HTL_15K_EN 0x00020000
-#define FLD_HTL_500K_EN 0x00010000
-#define FLD_HTL_KD 0x0000ff00
-#define FLD_HTL_KI 0x000000ff
-
-/*****************************************************************************/
-#define COMB_CTRL 0x49c
-#define FLD_COMB_PHASE_LIMIT 0xff000000
-#define FLD_CCOMB_ERR_LIMIT 0x00ff0000
-#define FLD_LUMA_THRESHOLD 0x0000ff00
-#define FLD_LCOMB_ERR_LIMIT 0x000000ff
-
-/*****************************************************************************/
-#define CRUSH_CTRL 0x4a0
-#define FLD_WTW_EN 0x00400000
-#define FLD_CRUSH_FREQ 0x00200000
-#define FLD_MAJ_SEL_EN 0x00100000
-#define FLD_MAJ_SEL 0x000c0000
-/* Reserved [17:15] */
-#define FLD_SYNC_TIP_REDUCE 0x00007e00
-/* Reserved [8:6] */
-#define FLD_SYNC_TIP_INC 0x0000003f
-
-/*****************************************************************************/
-#define SOFT_RST_CTRL 0x4a4
-#define FLD_VD_SOFT_RST 0x00008000
-/* Reserved [14:12] */
-#define FLD_REG_RST_MSK 0x00000800
-#define FLD_VOF_RST_MSK 0x00000400
-#define FLD_MVDET_RST_MSK 0x00000200
-#define FLD_VBI_RST_MSK 0x00000100
-#define FLD_SCALE_RST_MSK 0x00000080
-#define FLD_CHROMA_RST_MSK 0x00000040
-#define FLD_LUMA_RST_MSK 0x00000020
-#define FLD_VTG_RST_MSK 0x00000010
-#define FLD_YCSEP_RST_MSK 0x00000008
-#define FLD_SRC_RST_MSK 0x00000004
-#define FLD_DFE_RST_MSK 0x00000002
-/* Reserved [0] */
-
-/*****************************************************************************/
-#define MV_DT_CTRL1 0x4a8
-/* Reserved [31:29] */
-#define FLD_PSP_STOP_LINE 0x1f000000
-/* Reserved [23:21] */
-#define FLD_PSP_STRT_LINE 0x001f0000
-/* Reserved [15] */
-#define FLD_PSP_LLIMW 0x00007f00
-/* Reserved [7] */
-#define FLD_PSP_ULIMW 0x0000007f
-
-/*****************************************************************************/
-#define MV_DT_CTRL2 0x4aC
-#define FLD_CS_STOPWIN 0xff000000
-#define FLD_CS_STRTWIN 0x00ff0000
-#define FLD_CS_WIDTH 0x0000ff00
-#define FLD_PSP_SPEC_VAL 0x000000ff
-
-/*****************************************************************************/
-#define MV_DT_CTRL3 0x4B0
-#define FLD_AUTO_RATE_DIS 0x80000000
-#define FLD_HLOCK_DIS 0x40000000
-#define FLD_SEL_FIELD_CNT 0x20000000
-#define FLD_CS_TYPE2_SEL 0x10000000
-#define FLD_CS_LINE_THRSH_SEL 0x08000000
-#define FLD_CS_ATHRESH_SEL 0x04000000
-#define FLD_PSP_SPEC_SEL 0x02000000
-#define FLD_PSP_LINES_SEL 0x01000000
-#define FLD_FIELD_CNT 0x00f00000
-#define FLD_CS_TYPE2_CNT 0x000fc000
-#define FLD_CS_LINE_CNT 0x00003f00
-#define FLD_CS_ATHRESH_LEV 0x000000ff
-
-/*****************************************************************************/
-#define CHIP_VERSION 0x4b4
-/* Cx231xx redefine */
-#define VERSION 0x4b4
-#define FLD_REV_ID 0x000000ff
-
-/*****************************************************************************/
-#define MISC_DIAG_CTRL 0x4b8
-/* Reserved [31:24] */
-#define FLD_SC_CONVERGE_THRESH 0x00ff0000
-#define FLD_CCOMB_ERR_LIMIT_3D 0x0000ff00
-#define FLD_LCOMB_ERR_LIMIT_3D 0x000000ff
-
-/*****************************************************************************/
-#define VBI_PASS_CTRL 0x4bc
-#define FLD_VBI_PASS_MD 0x00200000
-#define FLD_VBI_SETUP_DIS 0x00100000
-#define FLD_PASS_LINE_CTRL 0x000fffff
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define VCR_DET_CTRL 0x4c0
-#define FLD_EN_FIELD_PHASE_DET 0x80000000
-#define FLD_EN_HEAD_SW_DET 0x40000000
-#define FLD_FIELD_PHASE_LENGTH 0x01ff0000
-/* Reserved [29:25] */
-#define FLD_FIELD_PHASE_DELAY 0x0000ff00
-#define FLD_FIELD_PHASE_LIMIT 0x000000f0
-#define FLD_HEAD_SW_DET_LIMIT 0x0000000f
-
-/*****************************************************************************/
-#define DL_CTL 0x800
-#define DL_CTL_ADDRESS_LOW 0x800 /* Byte 1 in DL_CTL */
-#define DL_CTL_ADDRESS_HIGH 0x801 /* Byte 2 in DL_CTL */
-#define DL_CTL_DATA 0x802 /* Byte 3 in DL_CTL */
-#define DL_CTL_CONTROL 0x803 /* Byte 4 in DL_CTL */
-/* Reserved [31:5] */
-#define FLD_START_8051 0x10000000
-#define FLD_DL_ENABLE 0x08000000
-#define FLD_DL_AUTO_INC 0x04000000
-#define FLD_DL_MAP 0x03000000
-
-/*****************************************************************************/
-#define STD_DET_STATUS 0x804
-#define FLD_SPARE_STATUS1 0xff000000
-#define FLD_SPARE_STATUS0 0x00ff0000
-#define FLD_MOD_DET_STATUS1 0x0000ff00
-#define FLD_MOD_DET_STATUS0 0x000000ff
-
-/*****************************************************************************/
-#define AUD_BUILD_NUM 0x806
-#define AUD_VER_NUM 0x807
-#define STD_DET_CTL 0x808
-#define STD_DET_CTL_AUD_CTL 0x808 /* Byte 1 in STD_DET_CTL */
-#define STD_DET_CTL_PREF_MODE 0x809 /* Byte 2 in STD_DET_CTL */
-#define FLD_SPARE_CTL0 0xff000000
-#define FLD_DIS_DBX 0x00800000
-#define FLD_DIS_BTSC 0x00400000
-#define FLD_DIS_NICAM_A2 0x00200000
-#define FLD_VIDEO_PRESENT 0x00100000
-#define FLD_DW8051_VIDEO_FORMAT 0x000f0000
-#define FLD_PREF_DEC_MODE 0x0000ff00
-#define FLD_AUD_CONFIG 0x000000ff
-
-/*****************************************************************************/
-#define DW8051_INT 0x80c
-#define FLD_VIDEO_PRESENT_CHANGE 0x80000000
-#define FLD_VIDEO_CHANGE 0x40000000
-#define FLD_RDS_READY 0x20000000
-#define FLD_AC97_INT 0x10000000
-#define FLD_NICAM_BIT_ERROR_TOO_HIGH 0x08000000
-#define FLD_NICAM_LOCK 0x04000000
-#define FLD_NICAM_UNLOCK 0x02000000
-#define FLD_DFT4_TH_CMP 0x01000000
-/* Reserved [23:22] */
-#define FLD_LOCK_IND_INT 0x00200000
-#define FLD_DFT3_TH_CMP 0x00100000
-#define FLD_DFT2_TH_CMP 0x00080000
-#define FLD_DFT1_TH_CMP 0x00040000
-#define FLD_FM2_DFT_TH_CMP 0x00020000
-#define FLD_FM1_DFT_TH_CMP 0x00010000
-#define FLD_VIDEO_PRESENT_EN 0x00008000
-#define FLD_VIDEO_CHANGE_EN 0x00004000
-#define FLD_RDS_READY_EN 0x00002000
-#define FLD_AC97_INT_EN 0x00001000
-#define FLD_NICAM_BIT_ERROR_TOO_HIGH_EN 0x00000800
-#define FLD_NICAM_LOCK_EN 0x00000400
-#define FLD_NICAM_UNLOCK_EN 0x00000200
-#define FLD_DFT4_TH_CMP_EN 0x00000100
-/* Reserved [7] */
-#define FLD_DW8051_INT6_CTL1 0x00000040
-#define FLD_DW8051_INT5_CTL1 0x00000020
-#define FLD_DW8051_INT4_CTL1 0x00000010
-#define FLD_DW8051_INT3_CTL1 0x00000008
-#define FLD_DW8051_INT2_CTL1 0x00000004
-#define FLD_DW8051_INT1_CTL1 0x00000002
-#define FLD_DW8051_INT0_CTL1 0x00000001
-
-/*****************************************************************************/
-#define GENERAL_CTL 0x810
-#define FLD_RDS_INT 0x80000000
-#define FLD_NBER_INT 0x40000000
-#define FLD_NLL_INT 0x20000000
-#define FLD_IFL_INT 0x10000000
-#define FLD_FDL_INT 0x08000000
-#define FLD_AFC_INT 0x04000000
-#define FLD_AMC_INT 0x02000000
-#define FLD_AC97_INT_CTL 0x01000000
-#define FLD_RDS_INT_DIS 0x00800000
-#define FLD_NBER_INT_DIS 0x00400000
-#define FLD_NLL_INT_DIS 0x00200000
-#define FLD_IFL_INT_DIS 0x00100000
-#define FLD_FDL_INT_DIS 0x00080000
-#define FLD_FC_INT_DIS 0x00040000
-#define FLD_AMC_INT_DIS 0x00020000
-#define FLD_AC97_INT_DIS 0x00010000
-#define FLD_REV_NUM 0x0000ff00
-/* Reserved [7:5] */
-#define FLD_DBX_SOFT_RESET_REG 0x00000010
-#define FLD_AD_SOFT_RESET_REG 0x00000008
-#define FLD_SRC_SOFT_RESET_REG 0x00000004
-#define FLD_CDMOD_SOFT_RESET 0x00000002
-#define FLD_8051_SOFT_RESET 0x00000001
-
-/*****************************************************************************/
-#define AAGC_CTL 0x814
-#define FLD_AFE_12DB_EN 0x80000000
-#define FLD_AAGC_DEFAULT_EN 0x40000000
-#define FLD_AAGC_DEFAULT 0x3f000000
-/* Reserved [23] */
-#define FLD_AAGC_GAIN 0x00600000
-#define FLD_AAGC_TH 0x001f0000
-/* Reserved [15:14] */
-#define FLD_AAGC_HYST2 0x00003f00
-/* Reserved [7:6] */
-#define FLD_AAGC_HYST1 0x0000003f
-
-/*****************************************************************************/
-#define IF_SRC_CTL 0x818
-#define FLD_DBX_BYPASS 0x80000000
-/* Reserved [30:25] */
-#define FLD_IF_SRC_MODE 0x01000000
-/* Reserved [23:18] */
-#define FLD_IF_SRC_PHASE_INC 0x0001ffff
-
-/*****************************************************************************/
-#define ANALOG_DEMOD_CTL 0x81c
-#define FLD_ROT1_PHACC_PROG 0xffff0000
-/* Reserved [15] */
-#define FLD_FM1_DELAY_FIX 0x00007000
-#define FLD_PDF4_SHIFT 0x00000c00
-#define FLD_PDF3_SHIFT 0x00000300
-#define FLD_PDF2_SHIFT 0x000000c0
-#define FLD_PDF1_SHIFT 0x00000030
-#define FLD_FMBYPASS_MODE2 0x00000008
-#define FLD_FMBYPASS_MODE1 0x00000004
-#define FLD_NICAM_MODE 0x00000002
-#define FLD_BTSC_FMRADIO_MODE 0x00000001
-
-/*****************************************************************************/
-#define ROT_FREQ_CTL 0x820
-#define FLD_ROT3_PHACC_PROG 0xffff0000
-#define FLD_ROT2_PHACC_PROG 0x0000ffff
-
-/*****************************************************************************/
-#define FM_CTL 0x824
-#define FLD_FM2_DC_FB_SHIFT 0xf0000000
-#define FLD_FM2_DC_INT_SHIFT 0x0f000000
-#define FLD_FM2_AFC_RESET 0x00800000
-#define FLD_FM2_DC_PASS_IN 0x00400000
-#define FLD_FM2_DAGC_SHIFT 0x00380000
-#define FLD_FM2_CORDIC_SHIFT 0x00070000
-#define FLD_FM1_DC_FB_SHIFT 0x0000f000
-#define FLD_FM1_DC_INT_SHIFT 0x00000f00
-#define FLD_FM1_AFC_RESET 0x00000080
-#define FLD_FM1_DC_PASS_IN 0x00000040
-#define FLD_FM1_DAGC_SHIFT 0x00000038
-#define FLD_FM1_CORDIC_SHIFT 0x00000007
-
-/*****************************************************************************/
-#define LPF_PDF_CTL 0x828
-/* Reserved [31:30] */
-#define FLD_LPF32_SHIFT1 0x30000000
-#define FLD_LPF32_SHIFT2 0x0c000000
-#define FLD_LPF160_SHIFTA 0x03000000
-#define FLD_LPF160_SHIFTB 0x00c00000
-#define FLD_LPF160_SHIFTC 0x00300000
-#define FLD_LPF32_COEF_SEL2 0x000c0000
-#define FLD_LPF32_COEF_SEL1 0x00030000
-#define FLD_LPF160_COEF_SELC 0x0000c000
-#define FLD_LPF160_COEF_SELB 0x00003000
-#define FLD_LPF160_COEF_SELA 0x00000c00
-#define FLD_LPF160_IN_EN_REG 0x00000300
-#define FLD_PDF4_PDF_SEL 0x000000c0
-#define FLD_PDF3_PDF_SEL 0x00000030
-#define FLD_PDF2_PDF_SEL 0x0000000c
-#define FLD_PDF1_PDF_SEL 0x00000003
-
-/*****************************************************************************/
-#define DFT1_CTL1 0x82c
-#define FLD_DFT1_DWELL 0xffff0000
-#define FLD_DFT1_FREQ 0x0000ffff
-
-/*****************************************************************************/
-#define DFT1_CTL2 0x830
-#define FLD_DFT1_THRESHOLD 0xffffff00
-#define FLD_DFT1_CMP_CTL 0x00000080
-#define FLD_DFT1_AVG 0x00000070
-/* Reserved [3:1] */
-#define FLD_DFT1_START 0x00000001
-
-/*****************************************************************************/
-#define DFT1_STATUS 0x834
-#define FLD_DFT1_DONE 0x80000000
-#define FLD_DFT1_TH_CMP_STAT 0x40000000
-#define FLD_DFT1_RESULT 0x3fffffff
-
-/*****************************************************************************/
-#define DFT2_CTL1 0x838
-#define FLD_DFT2_DWELL 0xffff0000
-#define FLD_DFT2_FREQ 0x0000ffff
-
-/*****************************************************************************/
-#define DFT2_CTL2 0x83C
-#define FLD_DFT2_THRESHOLD 0xffffff00
-#define FLD_DFT2_CMP_CTL 0x00000080
-#define FLD_DFT2_AVG 0x00000070
-/* Reserved [3:1] */
-#define FLD_DFT2_START 0x00000001
-
-/*****************************************************************************/
-#define DFT2_STATUS 0x840
-#define FLD_DFT2_DONE 0x80000000
-#define FLD_DFT2_TH_CMP_STAT 0x40000000
-#define FLD_DFT2_RESULT 0x3fffffff
-
-/*****************************************************************************/
-#define DFT3_CTL1 0x844
-#define FLD_DFT3_DWELL 0xffff0000
-#define FLD_DFT3_FREQ 0x0000ffff
-
-/*****************************************************************************/
-#define DFT3_CTL2 0x848
-#define FLD_DFT3_THRESHOLD 0xffffff00
-#define FLD_DFT3_CMP_CTL 0x00000080
-#define FLD_DFT3_AVG 0x00000070
-/* Reserved [3:1] */
-#define FLD_DFT3_START 0x00000001
-
-/*****************************************************************************/
-#define DFT3_STATUS 0x84c
-#define FLD_DFT3_DONE 0x80000000
-#define FLD_DFT3_TH_CMP_STAT 0x40000000
-#define FLD_DFT3_RESULT 0x3fffffff
-
-/*****************************************************************************/
-#define DFT4_CTL1 0x850
-#define FLD_DFT4_DWELL 0xffff0000
-#define FLD_DFT4_FREQ 0x0000ffff
-
-/*****************************************************************************/
-#define DFT4_CTL2 0x854
-#define FLD_DFT4_THRESHOLD 0xffffff00
-#define FLD_DFT4_CMP_CTL 0x00000080
-#define FLD_DFT4_AVG 0x00000070
-/* Reserved [3:1] */
-#define FLD_DFT4_START 0x00000001
-
-/*****************************************************************************/
-#define DFT4_STATUS 0x858
-#define FLD_DFT4_DONE 0x80000000
-#define FLD_DFT4_TH_CMP_STAT 0x40000000
-#define FLD_DFT4_RESULT 0x3fffffff
-
-/*****************************************************************************/
-#define AM_MTS_DET 0x85c
-#define FLD_AM_MTS_MODE 0x80000000
-/* Reserved [30:26] */
-#define FLD_AM_SUB 0x02000000
-#define FLD_AM_GAIN_EN 0x01000000
-/* Reserved [23:16] */
-#define FLD_AMMTS_GAIN_SCALE 0x0000e000
-#define FLD_MTS_PDF_SHIFT 0x00001800
-#define FLD_AM_REG_GAIN 0x00000700
-#define FLD_AGC_REF 0x000000ff
-
-/*****************************************************************************/
-#define ANALOG_MUX_CTL 0x860
-/* Reserved [31:29] */
-#define FLD_MUX21_SEL 0x10000000
-#define FLD_MUX20_SEL 0x08000000
-#define FLD_MUX19_SEL 0x04000000
-#define FLD_MUX18_SEL 0x02000000
-#define FLD_MUX17_SEL 0x01000000
-#define FLD_MUX16_SEL 0x00800000
-#define FLD_MUX15_SEL 0x00400000
-#define FLD_MUX14_SEL 0x00300000
-#define FLD_MUX13_SEL 0x000C0000
-#define FLD_MUX12_SEL 0x00020000
-#define FLD_MUX11_SEL 0x00018000
-#define FLD_MUX10_SEL 0x00004000
-#define FLD_MUX9_SEL 0x00002000
-#define FLD_MUX8_SEL 0x00001000
-#define FLD_MUX7_SEL 0x00000800
-#define FLD_MUX6_SEL 0x00000600
-#define FLD_MUX5_SEL 0x00000100
-#define FLD_MUX4_SEL 0x000000c0
-#define FLD_MUX3_SEL 0x00000030
-#define FLD_MUX2_SEL 0x0000000c
-#define FLD_MUX1_SEL 0x00000003
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define DPLL_CTRL1 0x864
-#define DIG_PLL_CTL1 0x864
-
-#define FLD_PLL_STATUS 0x07000000
-#define FLD_BANDWIDTH_SELECT 0x00030000
-#define FLD_PLL_SHIFT_REG 0x00007000
-#define FLD_PHASE_SHIFT 0x000007ff
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define DPLL_CTRL2 0x868
-#define DIG_PLL_CTL2 0x868
-#define FLD_PLL_UNLOCK_THR 0xff000000
-#define FLD_PLL_LOCK_THR 0x00ff0000
-/* Reserved [15:8] */
-#define FLD_AM_PDF_SEL2 0x000000c0
-#define FLD_AM_PDF_SEL1 0x00000030
-#define FLD_DPLL_FSM_CTRL 0x0000000c
-/* Reserved [1] */
-#define FLD_PLL_PILOT_DET 0x00000001
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define DPLL_CTRL3 0x86c
-#define DIG_PLL_CTL3 0x86c
-#define FLD_DISABLE_LOOP 0x01000000
-#define FLD_A1_DS1_SEL 0x000c0000
-#define FLD_A1_DS2_SEL 0x00030000
-#define FLD_A1_KI 0x0000ff00
-#define FLD_A1_KD 0x000000ff
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define DPLL_CTRL4 0x870
-#define DIG_PLL_CTL4 0x870
-#define FLD_A2_DS1_SEL 0x000c0000
-#define FLD_A2_DS2_SEL 0x00030000
-#define FLD_A2_KI 0x0000ff00
-#define FLD_A2_KD 0x000000ff
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define DPLL_CTRL5 0x874
-#define DIG_PLL_CTL5 0x874
-#define FLD_TRK_DS1_SEL 0x000c0000
-#define FLD_TRK_DS2_SEL 0x00030000
-#define FLD_TRK_KI 0x0000ff00
-#define FLD_TRK_KD 0x000000ff
-
-/*****************************************************************************/
-#define DEEMPH_GAIN_CTL 0x878
-#define FLD_DEEMPH2_GAIN 0xFFFF0000
-#define FLD_DEEMPH1_GAIN 0x0000FFFF
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define DEEMPH_COEFF1 0x87c
-#define DEEMPH_COEF1 0x87c
-#define FLD_DEEMPH_B0 0xffff0000
-#define FLD_DEEMPH_A0 0x0000ffff
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define DEEMPH_COEFF2 0x880
-#define DEEMPH_COEF2 0x880
-#define FLD_DEEMPH_B1 0xFFFF0000
-#define FLD_DEEMPH_A1 0x0000FFFF
-
-/*****************************************************************************/
-#define DBX1_CTL1 0x884
-#define FLD_DBX1_WBE_GAIN 0xffff0000
-#define FLD_DBX1_IN_GAIN 0x0000ffff
-
-/*****************************************************************************/
-#define DBX1_CTL2 0x888
-#define FLD_DBX1_SE_BYPASS 0xffff0000
-#define FLD_DBX1_SE_GAIN 0x0000ffff
-
-/*****************************************************************************/
-#define DBX1_RMS_SE 0x88C
-#define FLD_DBX1_RMS_WBE 0xffff0000
-#define FLD_DBX1_RMS_SE_FLD 0x0000ffff
-
-/*****************************************************************************/
-#define DBX2_CTL1 0x890
-#define FLD_DBX2_WBE_GAIN 0xffff0000
-#define FLD_DBX2_IN_GAIN 0x0000ffff
-
-/*****************************************************************************/
-#define DBX2_CTL2 0x894
-#define FLD_DBX2_SE_BYPASS 0xffff0000
-#define FLD_DBX2_SE_GAIN 0x0000ffff
-
-/*****************************************************************************/
-#define DBX2_RMS_SE 0x898
-#define FLD_DBX2_RMS_WBE 0xffff0000
-#define FLD_DBX2_RMS_SE_FLD 0x0000ffff
-
-/*****************************************************************************/
-#define AM_FM_DIFF 0x89c
-/* Reserved [31] */
-#define FLD_FM_DIFF_OUT 0x7fff0000
-/* Reserved [15] */
-#define FLD_AM_DIFF_OUT 0x00007fff
-
-/*****************************************************************************/
-#define NICAM_FAW 0x8a0
-#define FLD_FAWDETWINEND 0xFc000000
-#define FLD_FAWDETWINSTR 0x03ff0000
-/* Reserved [15:12] */
-#define FLD_FAWDETTHRSHLD3 0x00000f00
-#define FLD_FAWDETTHRSHLD2 0x000000f0
-#define FLD_FAWDETTHRSHLD1 0x0000000f
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define DEEMPH_GAIN 0x8a4
-#define NICAM_DEEMPHGAIN 0x8a4
-/* Reserved [31:18] */
-#define FLD_DEEMPHGAIN 0x0003ffff
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define DEEMPH_NUMER1 0x8a8
-#define NICAM_DEEMPHNUMER1 0x8a8
-/* Reserved [31:18] */
-#define FLD_DEEMPHNUMER1 0x0003ffff
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define DEEMPH_NUMER2 0x8ac
-#define NICAM_DEEMPHNUMER2 0x8ac
-/* Reserved [31:18] */
-#define FLD_DEEMPHNUMER2 0x0003ffff
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define DEEMPH_DENOM1 0x8b0
-#define NICAM_DEEMPHDENOM1 0x8b0
-/* Reserved [31:18] */
-#define FLD_DEEMPHDENOM1 0x0003ffff
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define DEEMPH_DENOM2 0x8b4
-#define NICAM_DEEMPHDENOM2 0x8b4
-/* Reserved [31:18] */
-#define FLD_DEEMPHDENOM2 0x0003ffff
-
-/*****************************************************************************/
-#define NICAM_ERRLOG_CTL1 0x8B8
-/* Reserved [31:28] */
-#define FLD_ERRINTRPTTHSHLD1 0x0fff0000
-/* Reserved [15:12] */
-#define FLD_ERRLOGPERIOD 0x00000fff
-
-/*****************************************************************************/
-#define NICAM_ERRLOG_CTL2 0x8bc
-/* Reserved [31:28] */
-#define FLD_ERRINTRPTTHSHLD3 0x0fff0000
-/* Reserved [15:12] */
-#define FLD_ERRINTRPTTHSHLD2 0x00000fff
-
-/*****************************************************************************/
-#define NICAM_ERRLOG_STS1 0x8c0
-/* Reserved [31:28] */
-#define FLD_ERRLOG2 0x0fff0000
-/* Reserved [15:12] */
-#define FLD_ERRLOG1 0x00000fff
-
-/*****************************************************************************/
-#define NICAM_ERRLOG_STS2 0x8c4
-/* Reserved [31:12] */
-#define FLD_ERRLOG3 0x00000fff
-
-/*****************************************************************************/
-#define NICAM_STATUS 0x8c8
-/* Reserved [31:20] */
-#define FLD_NICAM_CIB 0x000c0000
-#define FLD_NICAM_LOCK_STAT 0x00020000
-#define FLD_NICAM_MUTE 0x00010000
-#define FLD_NICAMADDIT_DATA 0x0000ffe0
-#define FLD_NICAMCNTRL 0x0000001f
-
-/*****************************************************************************/
-#define DEMATRIX_CTL 0x8cc
-#define FLD_AC97_IN_SHIFT 0xf0000000
-#define FLD_I2S_IN_SHIFT 0x0f000000
-#define FLD_DEMATRIX_SEL_CTL 0x00ff0000
-/* Reserved [15:11] */
-#define FLD_DMTRX_BYPASS 0x00000400
-#define FLD_DEMATRIX_MODE 0x00000300
-/* Reserved [7:6] */
-#define FLD_PH_DBX_SEL 0x00000020
-#define FLD_PH_CH_SEL 0x00000010
-#define FLD_PHASE_FIX 0x0000000f
-
-/*****************************************************************************/
-#define PATH1_CTL1 0x8d0
-/* Reserved [31:29] */
-#define FLD_PATH1_MUTE_CTL 0x1f000000
-/* Reserved [23:22] */
-#define FLD_PATH1_AVC_CG 0x00300000
-#define FLD_PATH1_AVC_RT 0x000f0000
-#define FLD_PATH1_AVC_AT 0x0000f000
-#define FLD_PATH1_AVC_STEREO 0x00000800
-#define FLD_PATH1_AVC_CR 0x00000700
-#define FLD_PATH1_AVC_RMS_CON 0x000000f0
-#define FLD_PATH1_SEL_CTL 0x0000000f
-
-/*****************************************************************************/
-#define PATH1_VOL_CTL 0x8d4
-#define FLD_PATH1_AVC_THRESHOLD 0x7fff0000
-#define FLD_PATH1_BAL_LEFT 0x00008000
-#define FLD_PATH1_BAL_LEVEL 0x00007f00
-#define FLD_PATH1_VOLUME 0x000000ff
-
-/*****************************************************************************/
-#define PATH1_EQ_CTL 0x8d8
-/* Reserved [31:30] */
-#define FLD_PATH1_EQ_TREBLE_VOL 0x3f000000
-/* Reserved [23:22] */
-#define FLD_PATH1_EQ_MID_VOL 0x003f0000
-/* Reserved [15:14] */
-#define FLD_PATH1_EQ_BASS_VOL 0x00003f00
-/* Reserved [7:1] */
-#define FLD_PATH1_EQ_BAND_SEL 0x00000001
-
-/*****************************************************************************/
-#define PATH1_SC_CTL 0x8dc
-#define FLD_PATH1_SC_THRESHOLD 0x7fff0000
-#define FLD_PATH1_SC_RT 0x0000f000
-#define FLD_PATH1_SC_AT 0x00000f00
-#define FLD_PATH1_SC_STEREO 0x00000080
-#define FLD_PATH1_SC_CR 0x00000070
-#define FLD_PATH1_SC_RMS_CON 0x0000000f
-
-/*****************************************************************************/
-#define PATH2_CTL1 0x8e0
-/* Reserved [31:26] */
-#define FLD_PATH2_MUTE_CTL 0x03000000
-/* Reserved [23:22] */
-#define FLD_PATH2_AVC_CG 0x00300000
-#define FLD_PATH2_AVC_RT 0x000f0000
-#define FLD_PATH2_AVC_AT 0x0000f000
-#define FLD_PATH2_AVC_STEREO 0x00000800
-#define FLD_PATH2_AVC_CR 0x00000700
-#define FLD_PATH2_AVC_RMS_CON 0x000000f0
-#define FLD_PATH2_SEL_CTL 0x0000000f
-
-/*****************************************************************************/
-#define PATH2_VOL_CTL 0x8e4
-#define FLD_PATH2_AVC_THRESHOLD 0xffff0000
-#define FLD_PATH2_BAL_LEFT 0x00008000
-#define FLD_PATH2_BAL_LEVEL 0x00007f00
-#define FLD_PATH2_VOLUME 0x000000ff
-
-/*****************************************************************************/
-#define PATH2_EQ_CTL 0x8e8
-/* Reserved [31:30] */
-#define FLD_PATH2_EQ_TREBLE_VOL 0x3f000000
-/* Reserved [23:22] */
-#define FLD_PATH2_EQ_MID_VOL 0x003f0000
-/* Reserved [15:14] */
-#define FLD_PATH2_EQ_BASS_VOL 0x00003f00
-/* Reserved [7:1] */
-#define FLD_PATH2_EQ_BAND_SEL 0x00000001
-
-/*****************************************************************************/
-#define PATH2_SC_CTL 0x8eC
-#define FLD_PATH2_SC_THRESHOLD 0xffff0000
-#define FLD_PATH2_SC_RT 0x0000f000
-#define FLD_PATH2_SC_AT 0x00000f00
-#define FLD_PATH2_SC_STEREO 0x00000080
-#define FLD_PATH2_SC_CR 0x00000070
-#define FLD_PATH2_SC_RMS_CON 0x0000000f
-
-/*****************************************************************************/
-#define SRC_CTL 0x8f0
-#define FLD_SRC_STATUS 0xffffff00
-#define FLD_FIFO_LF_EN 0x000000fc
-#define FLD_BYPASS_LI 0x00000002
-#define FLD_BYPASS_PF 0x00000001
-
-/*****************************************************************************/
-#define SRC_LF_COEF 0x8f4
-#define FLD_LOOP_FILTER_COEF2 0xffff0000
-#define FLD_LOOP_FILTER_COEF1 0x0000ffff
-
-/*****************************************************************************/
-#define SRC1_CTL 0x8f8
-/* Reserved [31:28] */
-#define FLD_SRC1_FIFO_RD_TH 0x0f000000
-/* Reserved [23:18] */
-#define FLD_SRC1_PHASE_INC 0x0003ffff
-
-/*****************************************************************************/
-#define SRC2_CTL 0x8fc
-/* Reserved [31:28] */
-#define FLD_SRC2_FIFO_RD_TH 0x0f000000
-/* Reserved [23:18] */
-#define FLD_SRC2_PHASE_INC 0x0003ffff
-
-/*****************************************************************************/
-#define SRC3_CTL 0x900
-/* Reserved [31:28] */
-#define FLD_SRC3_FIFO_RD_TH 0x0f000000
-/* Reserved [23:18] */
-#define FLD_SRC3_PHASE_INC 0x0003ffff
-
-/*****************************************************************************/
-#define SRC4_CTL 0x904
-/* Reserved [31:28] */
-#define FLD_SRC4_FIFO_RD_TH 0x0f000000
-/* Reserved [23:18] */
-#define FLD_SRC4_PHASE_INC 0x0003ffff
-
-/*****************************************************************************/
-#define SRC5_CTL 0x908
-/* Reserved [31:28] */
-#define FLD_SRC5_FIFO_RD_TH 0x0f000000
-/* Reserved [23:18] */
-#define FLD_SRC5_PHASE_INC 0x0003ffff
-
-/*****************************************************************************/
-#define SRC6_CTL 0x90c
-/* Reserved [31:28] */
-#define FLD_SRC6_FIFO_RD_TH 0x0f000000
-/* Reserved [23:18] */
-#define FLD_SRC6_PHASE_INC 0x0003ffff
-
-/*****************************************************************************/
-#define BAND_OUT_SEL 0x910
-#define FLD_SRC6_IN_SEL 0xc0000000
-#define FLD_SRC6_CLK_SEL 0x30000000
-#define FLD_SRC5_IN_SEL 0x0c000000
-#define FLD_SRC5_CLK_SEL 0x03000000
-#define FLD_SRC4_IN_SEL 0x00c00000
-#define FLD_SRC4_CLK_SEL 0x00300000
-#define FLD_SRC3_IN_SEL 0x000c0000
-#define FLD_SRC3_CLK_SEL 0x00030000
-#define FLD_BASEBAND_BYPASS_CTL 0x0000ff00
-#define FLD_AC97_SRC_SEL 0x000000c0
-#define FLD_I2S_SRC_SEL 0x00000030
-#define FLD_PARALLEL2_SRC_SEL 0x0000000c
-#define FLD_PARALLEL1_SRC_SEL 0x00000003
-
-/*****************************************************************************/
-#define I2S_IN_CTL 0x914
-/* Reserved [31:11] */
-#define FLD_I2S_UP2X_BW20K 0x00000400
-#define FLD_I2S_UP2X_BYPASS 0x00000200
-#define FLD_I2S_IN_MASTER_MODE 0x00000100
-#define FLD_I2S_IN_SONY_MODE 0x00000080
-#define FLD_I2S_IN_RIGHT_JUST 0x00000040
-#define FLD_I2S_IN_WS_SEL 0x00000020
-#define FLD_I2S_IN_BCN_DEL 0x0000001f
-
-/*****************************************************************************/
-#define I2S_OUT_CTL 0x918
-/* Reserved [31:17] */
-#define FLD_I2S_OUT_SOFT_RESET_EN 0x00010000
-/* Reserved [15:9] */
-#define FLD_I2S_OUT_MASTER_MODE 0x00000100
-#define FLD_I2S_OUT_SONY_MODE 0x00000080
-#define FLD_I2S_OUT_RIGHT_JUST 0x00000040
-#define FLD_I2S_OUT_WS_SEL 0x00000020
-#define FLD_I2S_OUT_BCN_DEL 0x0000001f
-
-/*****************************************************************************/
-#define AC97_CTL 0x91c
-/* Reserved [31:26] */
-#define FLD_AC97_UP2X_BW20K 0x02000000
-#define FLD_AC97_UP2X_BYPASS 0x01000000
-/* Reserved [23:17] */
-#define FLD_AC97_RST_ACL 0x00010000
-/* Reserved [15:9] */
-#define FLD_AC97_WAKE_UP_SYNC 0x00000100
-/* Reserved [7:1] */
-#define FLD_AC97_SHUTDOWN 0x00000001
-
-/* Cx231xx redefine */
-#define QPSK_IAGC_CTL1 0x94c
-#define QPSK_IAGC_CTL2 0x950
-#define QPSK_FEPR_FREQ 0x954
-#define QPSK_BTL_CTL1 0x958
-#define QPSK_BTL_CTL2 0x95c
-#define QPSK_CTL_CTL1 0x960
-#define QPSK_CTL_CTL2 0x964
-#define QPSK_MF_FAGC_CTL 0x968
-#define QPSK_EQ_CTL 0x96c
-#define QPSK_LOCK_CTL 0x970
-
-/*****************************************************************************/
-#define FM1_DFT_CTL 0x9a8
-#define FLD_FM1_DFT_THRESHOLD 0xffff0000
-/* Reserved [15:8] */
-#define FLD_FM1_DFT_CMP_CTL 0x00000080
-#define FLD_FM1_DFT_AVG 0x00000070
-/* Reserved [3:1] */
-#define FLD_FM1_DFT_START 0x00000001
-
-/*****************************************************************************/
-#define FM1_DFT_STATUS 0x9ac
-#define FLD_FM1_DFT_DONE 0x80000000
-/* Reserved [30:19] */
-#define FLD_FM_DFT_TH_CMP 0x00040000
-#define FLD_FM1_DFT 0x0003ffff
-
-/*****************************************************************************/
-#define FM2_DFT_CTL 0x9b0
-#define FLD_FM2_DFT_THRESHOLD 0xffff0000
-/* Reserved [15:8] */
-#define FLD_FM2_DFT_CMP_CTL 0x00000080
-#define FLD_FM2_DFT_AVG 0x00000070
-/* Reserved [3:1] */
-#define FLD_FM2_DFT_START 0x00000001
-
-/*****************************************************************************/
-#define FM2_DFT_STATUS 0x9b4
-#define FLD_FM2_DFT_DONE 0x80000000
-/* Reserved [30:19] */
-#define FLD_FM2_DFT_TH_CMP_STAT 0x00040000
-#define FLD_FM2_DFT 0x0003ffff
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define AAGC_STATUS_REG 0x9b8
-#define AAGC_STATUS 0x9b8
-/* Reserved [31:27] */
-#define FLD_FM2_DAGC_OUT 0x07000000
-/* Reserved [23:19] */
-#define FLD_FM1_DAGC_OUT 0x00070000
-/* Reserved [15:6] */
-#define FLD_AFE_VGA_OUT 0x0000003f
-
-/*****************************************************************************/
-#define MTS_GAIN_STATUS 0x9bc
-/* Reserved [31:14] */
-#define FLD_MTS_GAIN 0x00003fff
-
-#define RDS_OUT 0x9c0
-#define FLD_RDS_Q 0xffff0000
-#define FLD_RDS_I 0x0000ffff
-
-/*****************************************************************************/
-#define AUTOCONFIG_REG 0x9c4
-/* Reserved [31:4] */
-#define FLD_AUTOCONFIG_MODE 0x0000000f
-
-#define FM_AFC 0x9c8
-#define FLD_FM2_AFC 0xffff0000
-#define FLD_FM1_AFC 0x0000ffff
-
-/*****************************************************************************/
-/* Cx231xx redefine */
-#define NEW_SPARE 0x9cc
-#define NEW_SPARE_REG 0x9cc
-
-/*****************************************************************************/
-#define DBX_ADJ 0x9d0
-/* Reserved [31:28] */
-#define FLD_DBX2_ADJ 0x0fff0000
-/* Reserved [15:12] */
-#define FLD_DBX1_ADJ 0x00000fff
-
-#define VID_FMT_AUTO 0
-#define VID_FMT_NTSC_M 1
-#define VID_FMT_NTSC_J 2
-#define VID_FMT_NTSC_443 3
-#define VID_FMT_PAL_BDGHI 4
-#define VID_FMT_PAL_M 5
-#define VID_FMT_PAL_N 6
-#define VID_FMT_PAL_NC 7
-#define VID_FMT_PAL_60 8
-#define VID_FMT_SECAM 12
-#define VID_FMT_SECAM_60 13
-
-#define INPUT_MODE_CVBS_0 0 /* INPUT_MODE_VALUE(0) */
-#define INPUT_MODE_YC_1 1 /* INPUT_MODE_VALUE(1) */
-#define INPUT_MODE_YC2_2 2 /* INPUT_MODE_VALUE(2) */
-#define INPUT_MODE_YUV_3 3 /* INPUT_MODE_VALUE(3) */
-
-#define LUMA_LPF_LOW_BANDPASS 0 /* 0.6Mhz LPF BW */
-#define LUMA_LPF_MEDIUM_BANDPASS 1 /* 1.0Mhz LPF BW */
-#define LUMA_LPF_HIGH_BANDPASS 2 /* 1.5Mhz LPF BW */
-
-#define UV_LPF_LOW_BANDPASS 0 /* 0.6Mhz LPF BW */
-#define UV_LPF_MEDIUM_BANDPASS 1 /* 1.0Mhz LPF BW */
-#define UV_LPF_HIGH_BANDPASS 2 /* 1.5Mhz LPF BW */
-
-#define TWO_TAP_FILT 0
-#define THREE_TAP_FILT 1
-#define FOUR_TAP_FILT 2
-#define FIVE_TAP_FILT 3
-
-#define AUD_CHAN_SRC_PARALLEL 0
-#define AUD_CHAN_SRC_I2S_INPUT 1
-#define AUD_CHAN_SRC_FLATIRON 2
-#define AUD_CHAN_SRC_PARALLEL3 3
-
-#define OUT_MODE_601 0
-#define OUT_MODE_656 1
-#define OUT_MODE_VIP11 2
-#define OUT_MODE_VIP20 3
-
-#define PHASE_INC_49MHZ 0x0df22
-#define PHASE_INC_56MHZ 0x0fa5b
-#define PHASE_INC_28MHZ 0x010000
-
-#endif
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/video/cx231xx/cx231xx-vbi.c
deleted file mode 100644
index ac7db52f404..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-vbi.c
+++ /dev/null
@@ -1,710 +0,0 @@
-/*
- cx231xx_vbi.c - driver for Conexant Cx23100/101/102 USB video capture devices
-
- Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
- Based on cx88 driver
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/bitmap.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <linux/mm.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/msp3400.h>
-#include <media/tuner.h>
-
-#include "cx231xx.h"
-#include "cx231xx-vbi.h"
-
-static inline void print_err_status(struct cx231xx *dev, int packet, int status)
-{
- char *errmsg = "Unknown";
-
- switch (status) {
- case -ENOENT:
- errmsg = "unlinked synchronuously";
- break;
- case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
- break;
- case -ENOSR:
- errmsg = "Buffer error (overrun)";
- break;
- case -EPIPE:
- errmsg = "Stalled (device not responding)";
- break;
- case -EOVERFLOW:
- errmsg = "Babble (bad cable?)";
- break;
- case -EPROTO:
- errmsg = "Bit-stuff error (bad cable?)";
- break;
- case -EILSEQ:
- errmsg = "CRC/Timeout (could be anything)";
- break;
- case -ETIME:
- errmsg = "Device does not respond";
- break;
- }
- if (packet < 0) {
- cx231xx_err(DRIVER_NAME "URB status %d [%s].\n", status,
- errmsg);
- } else {
- cx231xx_err(DRIVER_NAME "URB packet %d, status %d [%s].\n",
- packet, status, errmsg);
- }
-}
-
-/*
- * Controls the isoc copy of each urb packet
- */
-static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb)
-{
- struct cx231xx_dmaqueue *dma_q = urb->context;
- int rc = 1;
- unsigned char *p_buffer;
- u32 bytes_parsed = 0, buffer_size = 0;
- u8 sav_eav = 0;
-
- if (!dev)
- return 0;
-
- if (dev->state & DEV_DISCONNECTED)
- return 0;
-
- if (urb->status < 0) {
- print_err_status(dev, -1, urb->status);
- if (urb->status == -ENOENT)
- return 0;
- }
-
- /* get buffer pointer and length */
- p_buffer = urb->transfer_buffer;
- buffer_size = urb->actual_length;
-
- if (buffer_size > 0) {
- bytes_parsed = 0;
-
- if (dma_q->is_partial_line) {
- /* Handle the case where we were working on a partial
- line */
- sav_eav = dma_q->last_sav;
- } else {
- /* Check for a SAV/EAV overlapping the
- buffer boundary */
-
- sav_eav = cx231xx_find_boundary_SAV_EAV(p_buffer,
- dma_q->partial_buf,
- &bytes_parsed);
- }
-
- sav_eav &= 0xF0;
- /* Get the first line if we have some portion of an SAV/EAV from
- the last buffer or a partial line */
- if (sav_eav) {
- bytes_parsed += cx231xx_get_vbi_line(dev, dma_q,
- sav_eav, /* SAV/EAV */
- p_buffer + bytes_parsed, /* p_buffer */
- buffer_size - bytes_parsed); /* buffer size */
- }
-
- /* Now parse data that is completely in this buffer */
- dma_q->is_partial_line = 0;
-
- while (bytes_parsed < buffer_size) {
- u32 bytes_used = 0;
-
- sav_eav = cx231xx_find_next_SAV_EAV(
- p_buffer + bytes_parsed, /* p_buffer */
- buffer_size - bytes_parsed, /* buffer size */
- &bytes_used); /* bytes used to get SAV/EAV */
-
- bytes_parsed += bytes_used;
-
- sav_eav &= 0xF0;
- if (sav_eav && (bytes_parsed < buffer_size)) {
- bytes_parsed += cx231xx_get_vbi_line(dev,
- dma_q, sav_eav, /* SAV/EAV */
- p_buffer+bytes_parsed, /* p_buffer */
- buffer_size-bytes_parsed);/*buf size*/
- }
- }
-
- /* Save the last four bytes of the buffer so we can
- check the buffer boundary condition next time */
- memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);
- bytes_parsed = 0;
- }
-
- return rc;
-}
-
-/* ------------------------------------------------------------------
- Vbi buf operations
- ------------------------------------------------------------------*/
-
-static int
-vbi_buffer_setup(struct videobuf_queue *vq, unsigned int *count,
- unsigned int *size)
-{
- struct cx231xx_fh *fh = vq->priv_data;
- struct cx231xx *dev = fh->dev;
- u32 height = 0;
-
- height = ((dev->norm & V4L2_STD_625_50) ?
- PAL_VBI_LINES : NTSC_VBI_LINES);
-
- *size = (dev->width * height * 2 * 2);
- if (0 == *count)
- *count = CX231XX_DEF_VBI_BUF;
-
- if (*count < CX231XX_MIN_BUF)
- *count = CX231XX_MIN_BUF;
-
- return 0;
-}
-
-/* This is called *without* dev->slock held; please keep it that way */
-static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
-{
- struct cx231xx_fh *fh = vq->priv_data;
- struct cx231xx *dev = fh->dev;
- unsigned long flags = 0;
- if (in_interrupt())
- BUG();
-
- /* We used to wait for the buffer to finish here, but this didn't work
- because, as we were keeping the state as VIDEOBUF_QUEUED,
- videobuf_queue_cancel marked it as finished for us.
- (Also, it could wedge forever if the hardware was misconfigured.)
-
- This should be safe; by the time we get here, the buffer isn't
- queued anymore. If we ever start marking the buffers as
- VIDEOBUF_ACTIVE, it won't be, though.
- */
- spin_lock_irqsave(&dev->vbi_mode.slock, flags);
- if (dev->vbi_mode.bulk_ctl.buf == buf)
- dev->vbi_mode.bulk_ctl.buf = NULL;
- spin_unlock_irqrestore(&dev->vbi_mode.slock, flags);
-
- videobuf_vmalloc_free(&buf->vb);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int
-vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct cx231xx_fh *fh = vq->priv_data;
- struct cx231xx_buffer *buf =
- container_of(vb, struct cx231xx_buffer, vb);
- struct cx231xx *dev = fh->dev;
- int rc = 0, urb_init = 0;
- u32 height = 0;
-
- height = ((dev->norm & V4L2_STD_625_50) ?
- PAL_VBI_LINES : NTSC_VBI_LINES);
- buf->vb.size = ((dev->width << 1) * height * 2);
-
- if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
- return -EINVAL;
-
- buf->vb.width = dev->width;
- buf->vb.height = height;
- buf->vb.field = field;
- buf->vb.field = V4L2_FIELD_SEQ_TB;
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- rc = videobuf_iolock(vq, &buf->vb, NULL);
- if (rc < 0)
- goto fail;
- }
-
- if (!dev->vbi_mode.bulk_ctl.num_bufs)
- urb_init = 1;
-
- if (urb_init) {
- rc = cx231xx_init_vbi_isoc(dev, CX231XX_NUM_VBI_PACKETS,
- CX231XX_NUM_VBI_BUFS,
- dev->vbi_mode.alt_max_pkt_size[0],
- cx231xx_isoc_vbi_copy);
- if (rc < 0)
- goto fail;
- }
-
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
-fail:
- free_buffer(vq, buf);
- return rc;
-}
-
-static void
-vbi_buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx231xx_buffer *buf =
- container_of(vb, struct cx231xx_buffer, vb);
- struct cx231xx_fh *fh = vq->priv_data;
- struct cx231xx *dev = fh->dev;
- struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq;
-
- buf->vb.state = VIDEOBUF_QUEUED;
- list_add_tail(&buf->vb.queue, &vidq->active);
-
-}
-
-static void vbi_buffer_release(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct cx231xx_buffer *buf =
- container_of(vb, struct cx231xx_buffer, vb);
-
-
- free_buffer(vq, buf);
-}
-
-struct videobuf_queue_ops cx231xx_vbi_qops = {
- .buf_setup = vbi_buffer_setup,
- .buf_prepare = vbi_buffer_prepare,
- .buf_queue = vbi_buffer_queue,
- .buf_release = vbi_buffer_release,
-};
-
-/* ------------------------------------------------------------------
- URB control
- ------------------------------------------------------------------*/
-
-/*
- * IRQ callback, called by URB callback
- */
-static void cx231xx_irq_vbi_callback(struct urb *urb)
-{
- struct cx231xx_dmaqueue *dma_q = urb->context;
- struct cx231xx_video_mode *vmode =
- container_of(dma_q, struct cx231xx_video_mode, vidq);
- struct cx231xx *dev = container_of(vmode, struct cx231xx, vbi_mode);
-
- switch (urb->status) {
- case 0: /* success */
- case -ETIMEDOUT: /* NAK */
- break;
- case -ECONNRESET: /* kill */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- default: /* error */
- cx231xx_err(DRIVER_NAME "urb completition error %d.\n",
- urb->status);
- break;
- }
-
- /* Copy data from URB */
- spin_lock(&dev->vbi_mode.slock);
- dev->vbi_mode.bulk_ctl.bulk_copy(dev, urb);
- spin_unlock(&dev->vbi_mode.slock);
-
- /* Reset status */
- urb->status = 0;
-
- urb->status = usb_submit_urb(urb, GFP_ATOMIC);
- if (urb->status) {
- cx231xx_err(DRIVER_NAME "urb resubmit failed (error=%i)\n",
- urb->status);
- }
-}
-
-/*
- * Stop and Deallocate URBs
- */
-void cx231xx_uninit_vbi_isoc(struct cx231xx *dev)
-{
- struct urb *urb;
- int i;
-
- cx231xx_info(DRIVER_NAME "cx231xx: called cx231xx_uninit_vbi_isoc\n");
-
- dev->vbi_mode.bulk_ctl.nfields = -1;
- for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) {
- urb = dev->vbi_mode.bulk_ctl.urb[i];
- if (urb) {
- if (!irqs_disabled())
- usb_kill_urb(urb);
- else
- usb_unlink_urb(urb);
-
- if (dev->vbi_mode.bulk_ctl.transfer_buffer[i]) {
-
- kfree(dev->vbi_mode.bulk_ctl.
- transfer_buffer[i]);
- dev->vbi_mode.bulk_ctl.transfer_buffer[i] =
- NULL;
- }
- usb_free_urb(urb);
- dev->vbi_mode.bulk_ctl.urb[i] = NULL;
- }
- dev->vbi_mode.bulk_ctl.transfer_buffer[i] = NULL;
- }
-
- kfree(dev->vbi_mode.bulk_ctl.urb);
- kfree(dev->vbi_mode.bulk_ctl.transfer_buffer);
-
- dev->vbi_mode.bulk_ctl.urb = NULL;
- dev->vbi_mode.bulk_ctl.transfer_buffer = NULL;
- dev->vbi_mode.bulk_ctl.num_bufs = 0;
-
- cx231xx_capture_start(dev, 0, Vbi);
-}
-EXPORT_SYMBOL_GPL(cx231xx_uninit_vbi_isoc);
-
-/*
- * Allocate URBs and start IRQ
- */
-int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets,
- int num_bufs, int max_pkt_size,
- int (*bulk_copy) (struct cx231xx *dev,
- struct urb *urb))
-{
- struct cx231xx_dmaqueue *dma_q = &dev->vbi_mode.vidq;
- int i;
- int sb_size, pipe;
- struct urb *urb;
- int rc;
-
- cx231xx_info(DRIVER_NAME "cx231xx: called cx231xx_prepare_isoc\n");
-
- /* De-allocates all pending stuff */
- cx231xx_uninit_vbi_isoc(dev);
-
- /* clear if any halt */
- usb_clear_halt(dev->udev,
- usb_rcvbulkpipe(dev->udev,
- dev->vbi_mode.end_point_addr));
-
- dev->vbi_mode.bulk_ctl.bulk_copy = bulk_copy;
- dev->vbi_mode.bulk_ctl.num_bufs = num_bufs;
- dma_q->pos = 0;
- dma_q->is_partial_line = 0;
- dma_q->last_sav = 0;
- dma_q->current_field = -1;
- dma_q->bytes_left_in_line = dev->width << 1;
- dma_q->lines_per_field = ((dev->norm & V4L2_STD_625_50) ?
- PAL_VBI_LINES : NTSC_VBI_LINES);
- dma_q->lines_completed = 0;
- for (i = 0; i < 8; i++)
- dma_q->partial_buf[i] = 0;
-
- dev->vbi_mode.bulk_ctl.urb = kzalloc(sizeof(void *) * num_bufs,
- GFP_KERNEL);
- if (!dev->vbi_mode.bulk_ctl.urb) {
- cx231xx_errdev("cannot alloc memory for usb buffers\n");
- return -ENOMEM;
- }
-
- dev->vbi_mode.bulk_ctl.transfer_buffer =
- kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
- if (!dev->vbi_mode.bulk_ctl.transfer_buffer) {
- cx231xx_errdev("cannot allocate memory for usbtransfer\n");
- kfree(dev->vbi_mode.bulk_ctl.urb);
- return -ENOMEM;
- }
-
- dev->vbi_mode.bulk_ctl.max_pkt_size = max_pkt_size;
- dev->vbi_mode.bulk_ctl.buf = NULL;
-
- sb_size = max_packets * dev->vbi_mode.bulk_ctl.max_pkt_size;
-
- /* allocate urbs and transfer buffers */
- for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) {
-
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- cx231xx_err(DRIVER_NAME
- ": cannot alloc bulk_ctl.urb %i\n", i);
- cx231xx_uninit_vbi_isoc(dev);
- return -ENOMEM;
- }
- dev->vbi_mode.bulk_ctl.urb[i] = urb;
- urb->transfer_flags = 0;
-
- dev->vbi_mode.bulk_ctl.transfer_buffer[i] =
- kzalloc(sb_size, GFP_KERNEL);
- if (!dev->vbi_mode.bulk_ctl.transfer_buffer[i]) {
- cx231xx_err(DRIVER_NAME
- ": unable to allocate %i bytes for transfer"
- " buffer %i%s\n", sb_size, i,
- in_interrupt() ? " while in int" : "");
- cx231xx_uninit_vbi_isoc(dev);
- return -ENOMEM;
- }
-
- pipe = usb_rcvbulkpipe(dev->udev, dev->vbi_mode.end_point_addr);
- usb_fill_bulk_urb(urb, dev->udev, pipe,
- dev->vbi_mode.bulk_ctl.transfer_buffer[i],
- sb_size, cx231xx_irq_vbi_callback, dma_q);
- }
-
- init_waitqueue_head(&dma_q->wq);
-
- /* submit urbs and enables IRQ */
- for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) {
- rc = usb_submit_urb(dev->vbi_mode.bulk_ctl.urb[i], GFP_ATOMIC);
- if (rc) {
- cx231xx_err(DRIVER_NAME
- ": submit of urb %i failed (error=%i)\n", i,
- rc);
- cx231xx_uninit_vbi_isoc(dev);
- return rc;
- }
- }
-
- cx231xx_capture_start(dev, 1, Vbi);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cx231xx_init_vbi_isoc);
-
-u32 cx231xx_get_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
- u8 sav_eav, u8 *p_buffer, u32 buffer_size)
-{
- u32 bytes_copied = 0;
- int current_field = -1;
-
- switch (sav_eav) {
-
- case SAV_VBI_FIELD1:
- current_field = 1;
- break;
-
- case SAV_VBI_FIELD2:
- current_field = 2;
- break;
- default:
- break;
- }
-
- if (current_field < 0)
- return bytes_copied;
-
- dma_q->last_sav = sav_eav;
-
- bytes_copied =
- cx231xx_copy_vbi_line(dev, dma_q, p_buffer, buffer_size,
- current_field);
-
- return bytes_copied;
-}
-
-/*
- * Announces that a buffer were filled and request the next
- */
-static inline void vbi_buffer_filled(struct cx231xx *dev,
- struct cx231xx_dmaqueue *dma_q,
- struct cx231xx_buffer *buf)
-{
- /* Advice that buffer was filled */
- /* cx231xx_info(DRIVER_NAME "[%p/%d] wakeup\n", buf, buf->vb.i); */
-
- buf->vb.state = VIDEOBUF_DONE;
- buf->vb.field_count++;
- do_gettimeofday(&buf->vb.ts);
-
- dev->vbi_mode.bulk_ctl.buf = NULL;
-
- list_del(&buf->vb.queue);
- wake_up(&buf->vb.done);
-}
-
-u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
- u8 *p_line, u32 length, int field_number)
-{
- u32 bytes_to_copy;
- struct cx231xx_buffer *buf;
- u32 _line_size = dev->width * 2;
-
- if (dma_q->current_field == -1) {
- /* Just starting up */
- cx231xx_reset_vbi_buffer(dev, dma_q);
- }
-
- if (dma_q->current_field != field_number)
- dma_q->lines_completed = 0;
-
- /* get the buffer pointer */
- buf = dev->vbi_mode.bulk_ctl.buf;
-
- /* Remember the field number for next time */
- dma_q->current_field = field_number;
-
- bytes_to_copy = dma_q->bytes_left_in_line;
- if (bytes_to_copy > length)
- bytes_to_copy = length;
-
- if (dma_q->lines_completed >= dma_q->lines_per_field) {
- dma_q->bytes_left_in_line -= bytes_to_copy;
- dma_q->is_partial_line =
- (dma_q->bytes_left_in_line == 0) ? 0 : 1;
- return 0;
- }
-
- dma_q->is_partial_line = 1;
-
- /* If we don't have a buffer, just return the number of bytes we would
- have copied if we had a buffer. */
- if (!buf) {
- dma_q->bytes_left_in_line -= bytes_to_copy;
- dma_q->is_partial_line =
- (dma_q->bytes_left_in_line == 0) ? 0 : 1;
- return bytes_to_copy;
- }
-
- /* copy the data to video buffer */
- cx231xx_do_vbi_copy(dev, dma_q, p_line, bytes_to_copy);
-
- dma_q->pos += bytes_to_copy;
- dma_q->bytes_left_in_line -= bytes_to_copy;
-
- if (dma_q->bytes_left_in_line == 0) {
-
- dma_q->bytes_left_in_line = _line_size;
- dma_q->lines_completed++;
- dma_q->is_partial_line = 0;
-
- if (cx231xx_is_vbi_buffer_done(dev, dma_q) && buf) {
-
- vbi_buffer_filled(dev, dma_q, buf);
-
- dma_q->pos = 0;
- dma_q->lines_completed = 0;
- cx231xx_reset_vbi_buffer(dev, dma_q);
- }
- }
-
- return bytes_to_copy;
-}
-
-/*
- * video-buf generic routine to get the next available buffer
- */
-static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q,
- struct cx231xx_buffer **buf)
-{
- struct cx231xx_video_mode *vmode =
- container_of(dma_q, struct cx231xx_video_mode, vidq);
- struct cx231xx *dev = container_of(vmode, struct cx231xx, vbi_mode);
- char *outp;
-
- if (list_empty(&dma_q->active)) {
- cx231xx_err(DRIVER_NAME ": No active queue to serve\n");
- dev->vbi_mode.bulk_ctl.buf = NULL;
- *buf = NULL;
- return;
- }
-
- /* Get the next buffer */
- *buf = list_entry(dma_q->active.next, struct cx231xx_buffer, vb.queue);
-
- /* Cleans up buffer - Useful for testing for frame/URB loss */
- outp = videobuf_to_vmalloc(&(*buf)->vb);
- memset(outp, 0, (*buf)->vb.size);
-
- dev->vbi_mode.bulk_ctl.buf = *buf;
-
- return;
-}
-
-void cx231xx_reset_vbi_buffer(struct cx231xx *dev,
- struct cx231xx_dmaqueue *dma_q)
-{
- struct cx231xx_buffer *buf;
-
- buf = dev->vbi_mode.bulk_ctl.buf;
-
- if (buf == NULL) {
- /* first try to get the buffer */
- get_next_vbi_buf(dma_q, &buf);
-
- dma_q->pos = 0;
- dma_q->current_field = -1;
- }
-
- dma_q->bytes_left_in_line = dev->width << 1;
- dma_q->lines_completed = 0;
-}
-
-int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
- u8 *p_buffer, u32 bytes_to_copy)
-{
- u8 *p_out_buffer = NULL;
- u32 current_line_bytes_copied = 0;
- struct cx231xx_buffer *buf;
- u32 _line_size = dev->width << 1;
- void *startwrite;
- int offset, lencopy;
-
- buf = dev->vbi_mode.bulk_ctl.buf;
-
- if (buf == NULL)
- return -EINVAL;
-
- p_out_buffer = videobuf_to_vmalloc(&buf->vb);
-
- if (dma_q->bytes_left_in_line != _line_size) {
- current_line_bytes_copied =
- _line_size - dma_q->bytes_left_in_line;
- }
-
- offset = (dma_q->lines_completed * _line_size) +
- current_line_bytes_copied;
-
- if (dma_q->current_field == 2) {
- /* Populate the second half of the frame */
- offset += (dev->width * 2 * dma_q->lines_per_field);
- }
-
- /* prepare destination address */
- startwrite = p_out_buffer + offset;
-
- lencopy = dma_q->bytes_left_in_line > bytes_to_copy ?
- bytes_to_copy : dma_q->bytes_left_in_line;
-
- memcpy(startwrite, p_buffer, lencopy);
-
- return 0;
-}
-
-u8 cx231xx_is_vbi_buffer_done(struct cx231xx *dev,
- struct cx231xx_dmaqueue *dma_q)
-{
- u32 height = 0;
-
- height = ((dev->norm & V4L2_STD_625_50) ?
- PAL_VBI_LINES : NTSC_VBI_LINES);
- if (dma_q->lines_completed == height && dma_q->current_field == 2)
- return 1;
- else
- return 0;
-}
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.h b/drivers/media/video/cx231xx/cx231xx-vbi.h
deleted file mode 100644
index 16c7d20a22a..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-vbi.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- cx231xx_vbi.h - driver for Conexant Cx23100/101/102 USB video capture devices
-
- Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
- Based on cx88 driver
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _CX231XX_VBI_H
-#define _CX231XX_VBI_H
-
-extern struct videobuf_queue_ops cx231xx_vbi_qops;
-
-#define NTSC_VBI_START_LINE 10 /* line 10 - 21 */
-#define NTSC_VBI_END_LINE 21
-#define NTSC_VBI_LINES (NTSC_VBI_END_LINE-NTSC_VBI_START_LINE+1)
-
-#define PAL_VBI_START_LINE 6
-#define PAL_VBI_END_LINE 23
-#define PAL_VBI_LINES (PAL_VBI_END_LINE-PAL_VBI_START_LINE+1)
-
-#define VBI_STRIDE 1440
-#define VBI_SAMPLES_PER_LINE 1440
-
-#define CX231XX_NUM_VBI_PACKETS 4
-#define CX231XX_NUM_VBI_BUFS 5
-
-/* stream functions */
-int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets,
- int num_bufs, int max_pkt_size,
- int (*bulk_copy) (struct cx231xx *dev,
- struct urb *urb));
-
-void cx231xx_uninit_vbi_isoc(struct cx231xx *dev);
-
-/* vbi data copy functions */
-u32 cx231xx_get_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
- u8 sav_eav, u8 *p_buffer, u32 buffer_size);
-
-u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
- u8 *p_line, u32 length, int field_number);
-
-void cx231xx_reset_vbi_buffer(struct cx231xx *dev,
- struct cx231xx_dmaqueue *dma_q);
-
-int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
- u8 *p_buffer, u32 bytes_to_copy);
-
-u8 cx231xx_is_vbi_buffer_done(struct cx231xx *dev,
- struct cx231xx_dmaqueue *dma_q);
-
-#endif
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
deleted file mode 100644
index 523aa49d6b8..00000000000
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ /dev/null
@@ -1,2645 +0,0 @@
-/*
- cx231xx-video.c - driver for Conexant Cx23100/101/102
- USB video capture devices
-
- Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
- Based on em28xx driver
- Based on cx23885 driver
- Based on cx88 driver
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/bitmap.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <linux/mm.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/msp3400.h>
-#include <media/tuner.h>
-
-#include "dvb_frontend.h"
-
-#include "cx231xx.h"
-#include "cx231xx-vbi.h"
-
-#define CX231XX_VERSION "0.0.2"
-
-#define DRIVER_AUTHOR "Srinivasa Deevi <srinivasa.deevi@conexant.com>"
-#define DRIVER_DESC "Conexant cx231xx based USB video device driver"
-
-#define cx231xx_videodbg(fmt, arg...) do {\
- if (video_debug) \
- printk(KERN_INFO "%s %s :"fmt, \
- dev->name, __func__ , ##arg); } while (0)
-
-static unsigned int isoc_debug;
-module_param(isoc_debug, int, 0644);
-MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
-
-#define cx231xx_isocdbg(fmt, arg...) \
-do {\
- if (isoc_debug) { \
- printk(KERN_INFO "%s %s :"fmt, \
- dev->name, __func__ , ##arg); \
- } \
- } while (0)
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_VERSION(CX231XX_VERSION);
-
-static unsigned int card[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
-static unsigned int video_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
-static unsigned int vbi_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
-static unsigned int radio_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
-
-module_param_array(card, int, NULL, 0444);
-module_param_array(video_nr, int, NULL, 0444);
-module_param_array(vbi_nr, int, NULL, 0444);
-module_param_array(radio_nr, int, NULL, 0444);
-
-MODULE_PARM_DESC(card, "card type");
-MODULE_PARM_DESC(video_nr, "video device numbers");
-MODULE_PARM_DESC(vbi_nr, "vbi device numbers");
-MODULE_PARM_DESC(radio_nr, "radio device numbers");
-
-static unsigned int video_debug;
-module_param(video_debug, int, 0644);
-MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
-
-/* supported video standards */
-static struct cx231xx_fmt format[] = {
- {
- .name = "16bpp YUY2, 4:2:2, packed",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = 16,
- .reg = 0,
- },
-};
-
-/* supported controls */
-/* Common to all boards */
-
-/* ------------------------------------------------------------------- */
-
-static const struct v4l2_queryctrl no_ctl = {
- .name = "42",
- .flags = V4L2_CTRL_FLAG_DISABLED,
-};
-
-static struct cx231xx_ctrl cx231xx_ctls[] = {
- /* --- video --- */
- {
- .v = {
- .id = V4L2_CID_BRIGHTNESS,
- .name = "Brightness",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0x7f,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
- .off = 128,
- .reg = LUMA_CTRL,
- .mask = 0x00ff,
- .shift = 0,
- }, {
- .v = {
- .id = V4L2_CID_CONTRAST,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0x3f,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
- .off = 0,
- .reg = LUMA_CTRL,
- .mask = 0xff00,
- .shift = 8,
- }, {
- .v = {
- .id = V4L2_CID_HUE,
- .name = "Hue",
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0x7f,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
- .off = 128,
- .reg = CHROMA_CTRL,
- .mask = 0xff0000,
- .shift = 16,
- }, {
- /* strictly, this only describes only U saturation.
- * V saturation is handled specially through code.
- */
- .v = {
- .id = V4L2_CID_SATURATION,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0x7f,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
- .off = 0,
- .reg = CHROMA_CTRL,
- .mask = 0x00ff,
- .shift = 0,
- }, {
- /* --- audio --- */
- .v = {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },
- .reg = PATH1_CTL1,
- .mask = (0x1f << 24),
- .shift = 24,
- }, {
- .v = {
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 0x3f,
- .step = 1,
- .default_value = 0x3f,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
- .reg = PATH1_VOL_CTL,
- .mask = 0xff,
- .shift = 0,
- }
-};
-static const int CX231XX_CTLS = ARRAY_SIZE(cx231xx_ctls);
-
-static const u32 cx231xx_user_ctrls[] = {
- V4L2_CID_USER_CLASS,
- V4L2_CID_BRIGHTNESS,
- V4L2_CID_CONTRAST,
- V4L2_CID_SATURATION,
- V4L2_CID_HUE,
- V4L2_CID_AUDIO_VOLUME,
-#if 0
- V4L2_CID_AUDIO_BALANCE,
-#endif
- V4L2_CID_AUDIO_MUTE,
- 0
-};
-
-static const u32 *ctrl_classes[] = {
- cx231xx_user_ctrls,
- NULL
-};
-
-/* ------------------------------------------------------------------
- Video buffer and parser functions
- ------------------------------------------------------------------*/
-
-/*
- * Announces that a buffer were filled and request the next
- */
-static inline void buffer_filled(struct cx231xx *dev,
- struct cx231xx_dmaqueue *dma_q,
- struct cx231xx_buffer *buf)
-{
- /* Advice that buffer was filled */
- cx231xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
- buf->vb.state = VIDEOBUF_DONE;
- buf->vb.field_count++;
- do_gettimeofday(&buf->vb.ts);
-
- if (dev->USE_ISO)
- dev->video_mode.isoc_ctl.buf = NULL;
- else
- dev->video_mode.bulk_ctl.buf = NULL;
-
- list_del(&buf->vb.queue);
- wake_up(&buf->vb.done);
-}
-
-static inline void print_err_status(struct cx231xx *dev, int packet, int status)
-{
- char *errmsg = "Unknown";
-
- switch (status) {
- case -ENOENT:
- errmsg = "unlinked synchronuously";
- break;
- case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
- break;
- case -ENOSR:
- errmsg = "Buffer error (overrun)";
- break;
- case -EPIPE:
- errmsg = "Stalled (device not responding)";
- break;
- case -EOVERFLOW:
- errmsg = "Babble (bad cable?)";
- break;
- case -EPROTO:
- errmsg = "Bit-stuff error (bad cable?)";
- break;
- case -EILSEQ:
- errmsg = "CRC/Timeout (could be anything)";
- break;
- case -ETIME:
- errmsg = "Device does not respond";
- break;
- }
- if (packet < 0) {
- cx231xx_isocdbg("URB status %d [%s].\n", status, errmsg);
- } else {
- cx231xx_isocdbg("URB packet %d, status %d [%s].\n",
- packet, status, errmsg);
- }
-}
-
-/*
- * video-buf generic routine to get the next available buffer
- */
-static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q,
- struct cx231xx_buffer **buf)
-{
- struct cx231xx_video_mode *vmode =
- container_of(dma_q, struct cx231xx_video_mode, vidq);
- struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode);
-
- char *outp;
-
- if (list_empty(&dma_q->active)) {
- cx231xx_isocdbg("No active queue to serve\n");
- if (dev->USE_ISO)
- dev->video_mode.isoc_ctl.buf = NULL;
- else
- dev->video_mode.bulk_ctl.buf = NULL;
- *buf = NULL;
- return;
- }
-
- /* Get the next buffer */
- *buf = list_entry(dma_q->active.next, struct cx231xx_buffer, vb.queue);
-
- /* Cleans up buffer - Useful for testing for frame/URB loss */
- outp = videobuf_to_vmalloc(&(*buf)->vb);
- memset(outp, 0, (*buf)->vb.size);
-
- if (dev->USE_ISO)
- dev->video_mode.isoc_ctl.buf = *buf;
- else
- dev->video_mode.bulk_ctl.buf = *buf;
-
- return;
-}
-
-/*
- * Controls the isoc copy of each urb packet
- */
-static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
-{
- struct cx231xx_dmaqueue *dma_q = urb->context;
- int i, rc = 1;
- unsigned char *p_buffer;
- u32 bytes_parsed = 0, buffer_size = 0;
- u8 sav_eav = 0;
-
- if (!dev)
- return 0;
-
- if (dev->state & DEV_DISCONNECTED)
- return 0;
-
- if (urb->status < 0) {
- print_err_status(dev, -1, urb->status);
- if (urb->status == -ENOENT)
- return 0;
- }
-
- for (i = 0; i < urb->number_of_packets; i++) {
- int status = urb->iso_frame_desc[i].status;
-
- if (status < 0) {
- print_err_status(dev, i, status);
- if (urb->iso_frame_desc[i].status != -EPROTO)
- continue;
- }
-
- if (urb->iso_frame_desc[i].actual_length <= 0) {
- /* cx231xx_isocdbg("packet %d is empty",i); - spammy */
- continue;
- }
- if (urb->iso_frame_desc[i].actual_length >
- dev->video_mode.max_pkt_size) {
- cx231xx_isocdbg("packet bigger than packet size");
- continue;
- }
-
- /* get buffer pointer and length */
- p_buffer = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
- buffer_size = urb->iso_frame_desc[i].actual_length;
- bytes_parsed = 0;
-
- if (dma_q->is_partial_line) {
- /* Handle the case of a partial line */
- sav_eav = dma_q->last_sav;
- } else {
- /* Check for a SAV/EAV overlapping
- the buffer boundary */
- sav_eav =
- cx231xx_find_boundary_SAV_EAV(p_buffer,
- dma_q->partial_buf,
- &bytes_parsed);
- }
-
- sav_eav &= 0xF0;
- /* Get the first line if we have some portion of an SAV/EAV from
- the last buffer or a partial line */
- if (sav_eav) {
- bytes_parsed += cx231xx_get_video_line(dev, dma_q,
- sav_eav, /* SAV/EAV */
- p_buffer + bytes_parsed, /* p_buffer */
- buffer_size - bytes_parsed);/* buf size */
- }
-
- /* Now parse data that is completely in this buffer */
- /* dma_q->is_partial_line = 0; */
-
- while (bytes_parsed < buffer_size) {
- u32 bytes_used = 0;
-
- sav_eav = cx231xx_find_next_SAV_EAV(
- p_buffer + bytes_parsed, /* p_buffer */
- buffer_size - bytes_parsed, /* buf size */
- &bytes_used);/* bytes used to get SAV/EAV */
-
- bytes_parsed += bytes_used;
-
- sav_eav &= 0xF0;
- if (sav_eav && (bytes_parsed < buffer_size)) {
- bytes_parsed += cx231xx_get_video_line(dev,
- dma_q, sav_eav, /* SAV/EAV */
- p_buffer + bytes_parsed,/* p_buffer */
- buffer_size - bytes_parsed);/*buf size*/
- }
- }
-
- /* Save the last four bytes of the buffer so we can check the
- buffer boundary condition next time */
- memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);
- bytes_parsed = 0;
-
- }
- return rc;
-}
-
-static inline int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb)
-{
- struct cx231xx_dmaqueue *dma_q = urb->context;
- int rc = 1;
- unsigned char *p_buffer;
- u32 bytes_parsed = 0, buffer_size = 0;
- u8 sav_eav = 0;
-
- if (!dev)
- return 0;
-
- if (dev->state & DEV_DISCONNECTED)
- return 0;
-
- if (urb->status < 0) {
- print_err_status(dev, -1, urb->status);
- if (urb->status == -ENOENT)
- return 0;
- }
-
- if (1) {
-
- /* get buffer pointer and length */
- p_buffer = urb->transfer_buffer;
- buffer_size = urb->actual_length;
- bytes_parsed = 0;
-
- if (dma_q->is_partial_line) {
- /* Handle the case of a partial line */
- sav_eav = dma_q->last_sav;
- } else {
- /* Check for a SAV/EAV overlapping
- the buffer boundary */
- sav_eav =
- cx231xx_find_boundary_SAV_EAV(p_buffer,
- dma_q->partial_buf,
- &bytes_parsed);
- }
-
- sav_eav &= 0xF0;
- /* Get the first line if we have some portion of an SAV/EAV from
- the last buffer or a partial line */
- if (sav_eav) {
- bytes_parsed += cx231xx_get_video_line(dev, dma_q,
- sav_eav, /* SAV/EAV */
- p_buffer + bytes_parsed, /* p_buffer */
- buffer_size - bytes_parsed);/* buf size */
- }
-
- /* Now parse data that is completely in this buffer */
- /* dma_q->is_partial_line = 0; */
-
- while (bytes_parsed < buffer_size) {
- u32 bytes_used = 0;
-
- sav_eav = cx231xx_find_next_SAV_EAV(
- p_buffer + bytes_parsed, /* p_buffer */
- buffer_size - bytes_parsed, /* buf size */
- &bytes_used);/* bytes used to get SAV/EAV */
-
- bytes_parsed += bytes_used;
-
- sav_eav &= 0xF0;
- if (sav_eav && (bytes_parsed < buffer_size)) {
- bytes_parsed += cx231xx_get_video_line(dev,
- dma_q, sav_eav, /* SAV/EAV */
- p_buffer + bytes_parsed,/* p_buffer */
- buffer_size - bytes_parsed);/*buf size*/
- }
- }
-
- /* Save the last four bytes of the buffer so we can check the
- buffer boundary condition next time */
- memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);
- bytes_parsed = 0;
-
- }
- return rc;
-}
-
-
-u8 cx231xx_find_boundary_SAV_EAV(u8 *p_buffer, u8 *partial_buf,
- u32 *p_bytes_used)
-{
- u32 bytes_used;
- u8 boundary_bytes[8];
- u8 sav_eav = 0;
-
- *p_bytes_used = 0;
-
- /* Create an array of the last 4 bytes of the last buffer and the first
- 4 bytes of the current buffer. */
-
- memcpy(boundary_bytes, partial_buf, 4);
- memcpy(boundary_bytes + 4, p_buffer, 4);
-
- /* Check for the SAV/EAV in the boundary buffer */
- sav_eav = cx231xx_find_next_SAV_EAV((u8 *)&boundary_bytes, 8,
- &bytes_used);
-
- if (sav_eav) {
- /* found a boundary SAV/EAV. Updates the bytes used to reflect
- only those used in the new buffer */
- *p_bytes_used = bytes_used - 4;
- }
-
- return sav_eav;
-}
-
-u8 cx231xx_find_next_SAV_EAV(u8 *p_buffer, u32 buffer_size, u32 *p_bytes_used)
-{
- u32 i;
- u8 sav_eav = 0;
-
- /*
- * Don't search if the buffer size is less than 4. It causes a page
- * fault since buffer_size - 4 evaluates to a large number in that
- * case.
- */
- if (buffer_size < 4) {
- *p_bytes_used = buffer_size;
- return 0;
- }
-
- for (i = 0; i < (buffer_size - 3); i++) {
-
- if ((p_buffer[i] == 0xFF) &&
- (p_buffer[i + 1] == 0x00) && (p_buffer[i + 2] == 0x00)) {
-
- *p_bytes_used = i + 4;
- sav_eav = p_buffer[i + 3];
- return sav_eav;
- }
- }
-
- *p_bytes_used = buffer_size;
- return 0;
-}
-
-u32 cx231xx_get_video_line(struct cx231xx *dev,
- struct cx231xx_dmaqueue *dma_q, u8 sav_eav,
- u8 *p_buffer, u32 buffer_size)
-{
- u32 bytes_copied = 0;
- int current_field = -1;
-
- switch (sav_eav) {
- case SAV_ACTIVE_VIDEO_FIELD1:
- /* looking for skipped line which occurred in PAL 720x480 mode.
- In this case, there will be no active data contained
- between the SAV and EAV */
- if ((buffer_size > 3) && (p_buffer[0] == 0xFF) &&
- (p_buffer[1] == 0x00) && (p_buffer[2] == 0x00) &&
- ((p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD1) ||
- (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD2) ||
- (p_buffer[3] == EAV_VBLANK_FIELD1) ||
- (p_buffer[3] == EAV_VBLANK_FIELD2)))
- return bytes_copied;
- current_field = 1;
- break;
-
- case SAV_ACTIVE_VIDEO_FIELD2:
- /* looking for skipped line which occurred in PAL 720x480 mode.
- In this case, there will be no active data contained between
- the SAV and EAV */
- if ((buffer_size > 3) && (p_buffer[0] == 0xFF) &&
- (p_buffer[1] == 0x00) && (p_buffer[2] == 0x00) &&
- ((p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD1) ||
- (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD2) ||
- (p_buffer[3] == EAV_VBLANK_FIELD1) ||
- (p_buffer[3] == EAV_VBLANK_FIELD2)))
- return bytes_copied;
- current_field = 2;
- break;
- }
-
- dma_q->last_sav = sav_eav;
-
- bytes_copied = cx231xx_copy_video_line(dev, dma_q, p_buffer,
- buffer_size, current_field);
-
- return bytes_copied;
-}
-
-u32 cx231xx_copy_video_line(struct cx231xx *dev,
- struct cx231xx_dmaqueue *dma_q, u8 *p_line,
- u32 length, int field_number)
-{
- u32 bytes_to_copy;
- struct cx231xx_buffer *buf;
- u32 _line_size = dev->width * 2;
-
- if (dma_q->current_field != field_number)
- cx231xx_reset_video_buffer(dev, dma_q);
-
- /* get the buffer pointer */
- if (dev->USE_ISO)
- buf = dev->video_mode.isoc_ctl.buf;
- else
- buf = dev->video_mode.bulk_ctl.buf;
-
- /* Remember the field number for next time */
- dma_q->current_field = field_number;
-
- bytes_to_copy = dma_q->bytes_left_in_line;
- if (bytes_to_copy > length)
- bytes_to_copy = length;
-
- if (dma_q->lines_completed >= dma_q->lines_per_field) {
- dma_q->bytes_left_in_line -= bytes_to_copy;
- dma_q->is_partial_line = (dma_q->bytes_left_in_line == 0) ?
- 0 : 1;
- return 0;
- }
-
- dma_q->is_partial_line = 1;
-
- /* If we don't have a buffer, just return the number of bytes we would
- have copied if we had a buffer. */
- if (!buf) {
- dma_q->bytes_left_in_line -= bytes_to_copy;
- dma_q->is_partial_line = (dma_q->bytes_left_in_line == 0)
- ? 0 : 1;
- return bytes_to_copy;
- }
-
- /* copy the data to video buffer */
- cx231xx_do_copy(dev, dma_q, p_line, bytes_to_copy);
-
- dma_q->pos += bytes_to_copy;
- dma_q->bytes_left_in_line -= bytes_to_copy;
-
- if (dma_q->bytes_left_in_line == 0) {
- dma_q->bytes_left_in_line = _line_size;
- dma_q->lines_completed++;
- dma_q->is_partial_line = 0;
-
- if (cx231xx_is_buffer_done(dev, dma_q) && buf) {
- buffer_filled(dev, dma_q, buf);
-
- dma_q->pos = 0;
- buf = NULL;
- dma_q->lines_completed = 0;
- }
- }
-
- return bytes_to_copy;
-}
-
-void cx231xx_reset_video_buffer(struct cx231xx *dev,
- struct cx231xx_dmaqueue *dma_q)
-{
- struct cx231xx_buffer *buf;
-
- /* handle the switch from field 1 to field 2 */
- if (dma_q->current_field == 1) {
- if (dma_q->lines_completed >= dma_q->lines_per_field)
- dma_q->field1_done = 1;
- else
- dma_q->field1_done = 0;
- }
-
- if (dev->USE_ISO)
- buf = dev->video_mode.isoc_ctl.buf;
- else
- buf = dev->video_mode.bulk_ctl.buf;
-
- if (buf == NULL) {
- /* first try to get the buffer */
- get_next_buf(dma_q, &buf);
-
- dma_q->pos = 0;
- dma_q->field1_done = 0;
- dma_q->current_field = -1;
- }
-
- /* reset the counters */
- dma_q->bytes_left_in_line = dev->width << 1;
- dma_q->lines_completed = 0;
-}
-
-int cx231xx_do_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
- u8 *p_buffer, u32 bytes_to_copy)
-{
- u8 *p_out_buffer = NULL;
- u32 current_line_bytes_copied = 0;
- struct cx231xx_buffer *buf;
- u32 _line_size = dev->width << 1;
- void *startwrite;
- int offset, lencopy;
-
- if (dev->USE_ISO)
- buf = dev->video_mode.isoc_ctl.buf;
- else
- buf = dev->video_mode.bulk_ctl.buf;
-
- if (buf == NULL)
- return -1;
-
- p_out_buffer = videobuf_to_vmalloc(&buf->vb);
-
- current_line_bytes_copied = _line_size - dma_q->bytes_left_in_line;
-
- /* Offset field 2 one line from the top of the buffer */
- offset = (dma_q->current_field == 1) ? 0 : _line_size;
-
- /* Offset for field 2 */
- startwrite = p_out_buffer + offset;
-
- /* lines already completed in the current field */
- startwrite += (dma_q->lines_completed * _line_size * 2);
-
- /* bytes already completed in the current line */
- startwrite += current_line_bytes_copied;
-
- lencopy = dma_q->bytes_left_in_line > bytes_to_copy ?
- bytes_to_copy : dma_q->bytes_left_in_line;
-
- if ((u8 *)(startwrite + lencopy) > (u8 *)(p_out_buffer + buf->vb.size))
- return 0;
-
- /* The below copies the UYVY data straight into video buffer */
- cx231xx_swab((u16 *) p_buffer, (u16 *) startwrite, (u16) lencopy);
-
- return 0;
-}
-
-void cx231xx_swab(u16 *from, u16 *to, u16 len)
-{
- u16 i;
-
- if (len <= 0)
- return;
-
- for (i = 0; i < len / 2; i++)
- to[i] = (from[i] << 8) | (from[i] >> 8);
-}
-
-u8 cx231xx_is_buffer_done(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q)
-{
- u8 buffer_complete = 0;
-
- /* Dual field stream */
- buffer_complete = ((dma_q->current_field == 2) &&
- (dma_q->lines_completed >= dma_q->lines_per_field) &&
- dma_q->field1_done);
-
- return buffer_complete;
-}
-
-/* ------------------------------------------------------------------
- Videobuf operations
- ------------------------------------------------------------------*/
-
-static int
-buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
-{
- struct cx231xx_fh *fh = vq->priv_data;
- struct cx231xx *dev = fh->dev;
-
- *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7)>>3;
- if (0 == *count)
- *count = CX231XX_DEF_BUF;
-
- if (*count < CX231XX_MIN_BUF)
- *count = CX231XX_MIN_BUF;
-
- return 0;
-}
-
-/* This is called *without* dev->slock held; please keep it that way */
-static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
-{
- struct cx231xx_fh *fh = vq->priv_data;
- struct cx231xx *dev = fh->dev;
- unsigned long flags = 0;
-
- if (in_interrupt())
- BUG();
-
- /* We used to wait for the buffer to finish here, but this didn't work
- because, as we were keeping the state as VIDEOBUF_QUEUED,
- videobuf_queue_cancel marked it as finished for us.
- (Also, it could wedge forever if the hardware was misconfigured.)
-
- This should be safe; by the time we get here, the buffer isn't
- queued anymore. If we ever start marking the buffers as
- VIDEOBUF_ACTIVE, it won't be, though.
- */
- spin_lock_irqsave(&dev->video_mode.slock, flags);
- if (dev->USE_ISO) {
- if (dev->video_mode.isoc_ctl.buf == buf)
- dev->video_mode.isoc_ctl.buf = NULL;
- } else {
- if (dev->video_mode.bulk_ctl.buf == buf)
- dev->video_mode.bulk_ctl.buf = NULL;
- }
- spin_unlock_irqrestore(&dev->video_mode.slock, flags);
-
- videobuf_vmalloc_free(&buf->vb);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int
-buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct cx231xx_fh *fh = vq->priv_data;
- struct cx231xx_buffer *buf =
- container_of(vb, struct cx231xx_buffer, vb);
- struct cx231xx *dev = fh->dev;
- int rc = 0, urb_init = 0;
-
- /* The only currently supported format is 16 bits/pixel */
- buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth
- + 7) >> 3;
- if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
- return -EINVAL;
-
- buf->vb.width = dev->width;
- buf->vb.height = dev->height;
- buf->vb.field = field;
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- rc = videobuf_iolock(vq, &buf->vb, NULL);
- if (rc < 0)
- goto fail;
- }
-
- if (dev->USE_ISO) {
- if (!dev->video_mode.isoc_ctl.num_bufs)
- urb_init = 1;
- } else {
- if (!dev->video_mode.bulk_ctl.num_bufs)
- urb_init = 1;
- }
- /*cx231xx_info("urb_init=%d dev->video_mode.max_pkt_size=%d\n",
- urb_init, dev->video_mode.max_pkt_size);*/
- if (urb_init) {
- dev->mode_tv = 0;
- if (dev->USE_ISO)
- rc = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS,
- CX231XX_NUM_BUFS,
- dev->video_mode.max_pkt_size,
- cx231xx_isoc_copy);
- else
- rc = cx231xx_init_bulk(dev, CX231XX_NUM_PACKETS,
- CX231XX_NUM_BUFS,
- dev->video_mode.max_pkt_size,
- cx231xx_bulk_copy);
- if (rc < 0)
- goto fail;
- }
-
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
-fail:
- free_buffer(vq, buf);
- return rc;
-}
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx231xx_buffer *buf =
- container_of(vb, struct cx231xx_buffer, vb);
- struct cx231xx_fh *fh = vq->priv_data;
- struct cx231xx *dev = fh->dev;
- struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq;
-
- buf->vb.state = VIDEOBUF_QUEUED;
- list_add_tail(&buf->vb.queue, &vidq->active);
-
-}
-
-static void buffer_release(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct cx231xx_buffer *buf =
- container_of(vb, struct cx231xx_buffer, vb);
- struct cx231xx_fh *fh = vq->priv_data;
- struct cx231xx *dev = (struct cx231xx *)fh->dev;
-
- cx231xx_isocdbg("cx231xx: called buffer_release\n");
-
- free_buffer(vq, buf);
-}
-
-static struct videobuf_queue_ops cx231xx_video_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-/********************* v4l2 interface **************************************/
-
-void video_mux(struct cx231xx *dev, int index)
-{
- dev->video_input = index;
- dev->ctl_ainput = INPUT(index)->amux;
-
- cx231xx_set_video_input_mux(dev, index);
-
- cx25840_call(dev, video, s_routing, INPUT(index)->vmux, 0, 0);
-
- cx231xx_set_audio_input(dev, dev->ctl_ainput);
-
- cx231xx_info("video_mux : %d\n", index);
-
- /* do mode control overrides if required */
- cx231xx_do_mode_ctrl_overrides(dev);
-}
-
-/* Usage lock check functions */
-static int res_get(struct cx231xx_fh *fh)
-{
- struct cx231xx *dev = fh->dev;
- int rc = 0;
-
- /* This instance already has stream_on */
- if (fh->stream_on)
- return rc;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- if (dev->stream_on)
- return -EBUSY;
- dev->stream_on = 1;
- } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- if (dev->vbi_stream_on)
- return -EBUSY;
- dev->vbi_stream_on = 1;
- } else
- return -EINVAL;
-
- fh->stream_on = 1;
-
- return rc;
-}
-
-static int res_check(struct cx231xx_fh *fh)
-{
- return fh->stream_on;
-}
-
-static void res_free(struct cx231xx_fh *fh)
-{
- struct cx231xx *dev = fh->dev;
-
- fh->stream_on = 0;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- dev->stream_on = 0;
- if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
- dev->vbi_stream_on = 0;
-}
-
-static int check_dev(struct cx231xx *dev)
-{
- if (dev->state & DEV_DISCONNECTED) {
- cx231xx_errdev("v4l2 ioctl: device not present\n");
- return -ENODEV;
- }
- return 0;
-}
-
-/* ------------------------------------------------------------------
- IOCTL vidioc handling
- ------------------------------------------------------------------*/
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
-
- f->fmt.pix.width = dev->width;
- f->fmt.pix.height = dev->height;
- f->fmt.pix.pixelformat = dev->format->fourcc;
- f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;
- f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-
- f->fmt.pix.field = V4L2_FIELD_INTERLACED;
-
- return 0;
-}
-
-static struct cx231xx_fmt *format_by_fourcc(unsigned int fourcc)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(format); i++)
- if (format[i].fourcc == fourcc)
- return &format[i];
-
- return NULL;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- unsigned int width = f->fmt.pix.width;
- unsigned int height = f->fmt.pix.height;
- unsigned int maxw = norm_maxw(dev);
- unsigned int maxh = norm_maxh(dev);
- struct cx231xx_fmt *fmt;
-
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- if (!fmt) {
- cx231xx_videodbg("Fourcc format (%08x) invalid.\n",
- f->fmt.pix.pixelformat);
- return -EINVAL;
- }
-
- /* width must even because of the YUYV format
- height must be even because of interlacing */
- v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0);
-
- f->fmt.pix.width = width;
- f->fmt.pix.height = height;
- f->fmt.pix.pixelformat = fmt->fourcc;
- f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3;
- f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- f->fmt.pix.field = V4L2_FIELD_INTERLACED;
-
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
- struct cx231xx_fmt *fmt;
- struct v4l2_mbus_framefmt mbus_fmt;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- vidioc_try_fmt_vid_cap(file, priv, f);
-
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- if (!fmt)
- return -EINVAL;
-
- if (videobuf_queue_is_busy(&fh->vb_vidq)) {
- cx231xx_errdev("%s queue busy\n", __func__);
- return -EBUSY;
- }
-
- if (dev->stream_on && !fh->stream_on) {
- cx231xx_errdev("%s device in use by another fh\n", __func__);
- return -EBUSY;
- }
-
- /* set new image size */
- dev->width = f->fmt.pix.width;
- dev->height = f->fmt.pix.height;
- dev->format = fmt;
-
- v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
- call_all(dev, video, s_mbus_fmt, &mbus_fmt);
- v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
-
- return rc;
-}
-
-static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
-
- *id = dev->norm;
- return 0;
-}
-
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- struct v4l2_mbus_framefmt mbus_fmt;
- struct v4l2_format f;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- cx231xx_info("vidioc_s_std : 0x%x\n", (unsigned int)*norm);
-
- dev->norm = *norm;
-
- /* Adjusts width/height, if needed */
- f.fmt.pix.width = dev->width;
- f.fmt.pix.height = dev->height;
- vidioc_try_fmt_vid_cap(file, priv, &f);
-
- call_all(dev, core, s_std, dev->norm);
-
- /* We need to reset basic properties in the decoder related to
- resolution (since a standard change effects things like the number
- of lines in VACT, etc) */
- v4l2_fill_mbus_format(&mbus_fmt, &f.fmt.pix, V4L2_MBUS_FMT_FIXED);
- call_all(dev, video, s_mbus_fmt, &mbus_fmt);
- v4l2_fill_pix_format(&f.fmt.pix, &mbus_fmt);
-
- /* set new image size */
- dev->width = f.fmt.pix.width;
- dev->height = f.fmt.pix.height;
-
- /* do mode control overrides */
- cx231xx_do_mode_ctrl_overrides(dev);
-
- return 0;
-}
-
-static const char *iname[] = {
- [CX231XX_VMUX_COMPOSITE1] = "Composite1",
- [CX231XX_VMUX_SVIDEO] = "S-Video",
- [CX231XX_VMUX_TELEVISION] = "Television",
- [CX231XX_VMUX_CABLE] = "Cable TV",
- [CX231XX_VMUX_DVB] = "DVB",
- [CX231XX_VMUX_DEBUG] = "for debug only",
-};
-
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- u32 gen_stat;
- unsigned int ret, n;
-
- n = i->index;
- if (n >= MAX_CX231XX_INPUT)
- return -EINVAL;
- if (0 == INPUT(n)->type)
- return -EINVAL;
-
- i->index = n;
- i->type = V4L2_INPUT_TYPE_CAMERA;
-
- strcpy(i->name, iname[INPUT(n)->type]);
-
- if ((CX231XX_VMUX_TELEVISION == INPUT(n)->type) ||
- (CX231XX_VMUX_CABLE == INPUT(n)->type))
- i->type = V4L2_INPUT_TYPE_TUNER;
-
- i->std = dev->vdev->tvnorms;
-
- /* If they are asking about the active input, read signal status */
- if (n == dev->video_input) {
- ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
- GEN_STAT, 2, &gen_stat, 4);
- if (ret > 0) {
- if ((gen_stat & FLD_VPRES) == 0x00)
- i->status |= V4L2_IN_ST_NO_SIGNAL;
- if ((gen_stat & FLD_HLOCK) == 0x00)
- i->status |= V4L2_IN_ST_NO_H_LOCK;
- }
- }
-
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
-
- *i = dev->video_input;
-
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- dev->mode_tv = 0;
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (i >= MAX_CX231XX_INPUT)
- return -EINVAL;
- if (0 == INPUT(i)->type)
- return -EINVAL;
-
- video_mux(dev, i);
-
- if (INPUT(i)->type == CX231XX_VMUX_TELEVISION ||
- INPUT(i)->type == CX231XX_VMUX_CABLE) {
- /* There's a tuner, so reset the standard and put it on the
- last known frequency (since it was probably powered down
- until now */
- call_all(dev, core, s_std, dev->norm);
- }
-
- return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
-
- switch (a->index) {
- case CX231XX_AMUX_VIDEO:
- strcpy(a->name, "Television");
- break;
- case CX231XX_AMUX_LINE_IN:
- strcpy(a->name, "Line In");
- break;
- default:
- return -EINVAL;
- }
-
- a->index = dev->ctl_ainput;
- a->capability = V4L2_AUDCAP_STEREO;
-
- return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int status = 0;
-
- /* Doesn't allow manual routing */
- if (a->index != dev->ctl_ainput)
- return -EINVAL;
-
- dev->ctl_ainput = INPUT(a->index)->amux;
- status = cx231xx_set_audio_input(dev, dev->ctl_ainput);
-
- return status;
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qc)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int id = qc->id;
- int i;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- qc->id = v4l2_ctrl_next(ctrl_classes, qc->id);
- if (unlikely(qc->id == 0))
- return -EINVAL;
-
- memset(qc, 0, sizeof(*qc));
-
- qc->id = id;
-
- if (qc->id < V4L2_CID_BASE || qc->id >= V4L2_CID_LASTP1)
- return -EINVAL;
-
- for (i = 0; i < CX231XX_CTLS; i++)
- if (cx231xx_ctls[i].v.id == qc->id)
- break;
-
- if (i == CX231XX_CTLS) {
- *qc = no_ctl;
- return 0;
- }
- *qc = cx231xx_ctls[i].v;
-
- call_all(dev, core, queryctrl, qc);
-
- if (qc->type)
- return 0;
- else
- return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- call_all(dev, core, g_ctrl, ctrl);
- return rc;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- call_all(dev, core, s_ctrl, ctrl);
- return rc;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (0 != t->index)
- return -EINVAL;
-
- strcpy(t->name, "Tuner");
-
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM;
- t->rangehigh = 0xffffffffUL;
- t->signal = 0xffff; /* LOCKED */
-
- return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (0 != t->index)
- return -EINVAL;
-#if 0
- call_all(dev, tuner, s_tuner, t);
-#endif
- return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
-
- f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- f->frequency = dev->ctl_freq;
-
- call_all(dev, tuner, g_frequency, f);
-
- return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
- u32 if_frequency = 5400000;
-
- cx231xx_info("Enter vidioc_s_frequency()f->frequency=%d;f->type=%d\n",
- f->frequency, f->type);
- /*cx231xx_info("f->type: 1-radio 2-analogTV 3-digitalTV\n");*/
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (0 != f->tuner)
- return -EINVAL;
-
- if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV))
- return -EINVAL;
- if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO))
- return -EINVAL;
-
- /* set pre channel change settings in DIF first */
- rc = cx231xx_tuner_pre_channel_change(dev);
-
- dev->ctl_freq = f->frequency;
- call_all(dev, tuner, s_frequency, f);
-
- /* set post channel change settings in DIF first */
- rc = cx231xx_tuner_post_channel_change(dev);
-
- if (dev->tuner_type == TUNER_NXP_TDA18271) {
- if (dev->norm & (V4L2_STD_MN | V4L2_STD_NTSC_443))
- if_frequency = 5400000; /*5.4MHz */
- else if (dev->norm & V4L2_STD_B)
- if_frequency = 6000000; /*6.0MHz */
- else if (dev->norm & (V4L2_STD_PAL_DK | V4L2_STD_SECAM_DK))
- if_frequency = 6900000; /*6.9MHz */
- else if (dev->norm & V4L2_STD_GH)
- if_frequency = 7100000; /*7.1MHz */
- else if (dev->norm & V4L2_STD_PAL_I)
- if_frequency = 7250000; /*7.25MHz */
- else if (dev->norm & V4L2_STD_SECAM_L)
- if_frequency = 6900000; /*6.9MHz */
- else if (dev->norm & V4L2_STD_SECAM_LC)
- if_frequency = 1250000; /*1.25MHz */
-
- cx231xx_info("if_frequency is set to %d\n", if_frequency);
- cx231xx_set_Colibri_For_LowIF(dev, if_frequency, 1, 1);
-
- update_HH_register_after_set_DIF(dev);
- }
-
- cx231xx_info("Set New FREQUENCY to %d\n", f->frequency);
-
- return rc;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-
-/*
- -R, --list-registers=type=<host/i2cdrv/i2caddr>,
- chip=<chip>[,min=<addr>,max=<addr>]
- dump registers from <min> to <max> [VIDIOC_DBG_G_REGISTER]
- -r, --set-register=type=<host/i2cdrv/i2caddr>,
- chip=<chip>,reg=<addr>,val=<val>
- set the register [VIDIOC_DBG_S_REGISTER]
-
- if type == host, then <chip> is the hosts chip ID (default 0)
- if type == i2cdrv (default), then <chip> is the I2C driver name or ID
- if type == i2caddr, then <chip> is the 7-bit I2C address
-*/
-
-static int vidioc_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int ret = 0;
- u8 value[4] = { 0, 0, 0, 0 };
- u32 data = 0;
-
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- switch (reg->match.addr) {
- case 0: /* Cx231xx - internal registers */
- ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
- (u16)reg->reg, value, 4);
- reg->val = value[0] | value[1] << 8 |
- value[2] << 16 | value[3] << 24;
- break;
- case 1: /* AFE - read byte */
- ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
- (u16)reg->reg, 2, &data, 1);
- reg->val = le32_to_cpu(data & 0xff);
- break;
- case 14: /* AFE - read dword */
- ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
- (u16)reg->reg, 2, &data, 4);
- reg->val = le32_to_cpu(data);
- break;
- case 2: /* Video Block - read byte */
- ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2, &data, 1);
- reg->val = le32_to_cpu(data & 0xff);
- break;
- case 24: /* Video Block - read dword */
- ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2, &data, 4);
- reg->val = le32_to_cpu(data);
- break;
- case 3: /* I2S block - read byte */
- ret = cx231xx_read_i2c_data(dev,
- I2S_BLK_DEVICE_ADDRESS,
- (u16)reg->reg, 1,
- &data, 1);
- reg->val = le32_to_cpu(data & 0xff);
- break;
- case 34: /* I2S Block - read dword */
- ret =
- cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
- (u16)reg->reg, 1, &data, 4);
- reg->val = le32_to_cpu(data);
- break;
- }
- return ret < 0 ? ret : 0;
-
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- call_all(dev, core, g_register, reg);
- return 0;
- case V4L2_CHIP_MATCH_I2C_ADDR:/*for register debug*/
- switch (reg->match.addr) {
- case 0: /* Cx231xx - internal registers */
- ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
- (u16)reg->reg, value, 4);
- reg->val = value[0] | value[1] << 8 |
- value[2] << 16 | value[3] << 24;
-
- break;
- case 0x600:/* AFE - read byte */
- ret = cx231xx_read_i2c_master(dev, AFE_DEVICE_ADDRESS,
- (u16)reg->reg, 2,
- &data, 1 , 0);
- reg->val = le32_to_cpu(data & 0xff);
- break;
-
- case 0x880:/* Video Block - read byte */
- if (reg->reg < 0x0b) {
- ret = cx231xx_read_i2c_master(dev,
- VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2,
- &data, 1 , 0);
- reg->val = le32_to_cpu(data & 0xff);
- } else {
- ret = cx231xx_read_i2c_master(dev,
- VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2,
- &data, 4 , 0);
- reg->val = le32_to_cpu(data);
- }
- break;
- case 0x980:
- ret = cx231xx_read_i2c_master(dev,
- I2S_BLK_DEVICE_ADDRESS,
- (u16)reg->reg, 1,
- &data, 1 , 0);
- reg->val = le32_to_cpu(data & 0xff);
- break;
- case 0x400:
- ret =
- cx231xx_read_i2c_master(dev, 0x40,
- (u16)reg->reg, 1,
- &data, 1 , 0);
- reg->val = le32_to_cpu(data & 0xff);
- break;
- case 0xc01:
- ret =
- cx231xx_read_i2c_master(dev, 0xc0,
- (u16)reg->reg, 2,
- &data, 38, 1);
- reg->val = le32_to_cpu(data);
- break;
- case 0x022:
- ret =
- cx231xx_read_i2c_master(dev, 0x02,
- (u16)reg->reg, 1,
- &data, 1, 2);
- reg->val = le32_to_cpu(data & 0xff);
- break;
- case 0x322:
- ret = cx231xx_read_i2c_master(dev,
- 0x32,
- (u16)reg->reg, 1,
- &data, 4 , 2);
- reg->val = le32_to_cpu(data);
- break;
- case 0x342:
- ret = cx231xx_read_i2c_master(dev,
- 0x34,
- (u16)reg->reg, 1,
- &data, 4 , 2);
- reg->val = le32_to_cpu(data);
- break;
-
- default:
- cx231xx_info("no match device address!!\n");
- break;
- }
- return ret < 0 ? ret : 0;
- /*return -EINVAL;*/
- default:
- if (!v4l2_chip_match_host(&reg->match))
- return -EINVAL;
- }
-
- call_all(dev, core, g_register, reg);
-
- return ret;
-}
-
-static int vidioc_s_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int ret = 0;
- __le64 buf;
- u32 value;
- u8 data[4] = { 0, 0, 0, 0 };
-
- buf = cpu_to_le64(reg->val);
-
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- {
- value = (u32) buf & 0xffffffff;
-
- switch (reg->match.addr) {
- case 0: /* cx231xx internal registers */
- data[0] = (u8) value;
- data[1] = (u8) (value >> 8);
- data[2] = (u8) (value >> 16);
- data[3] = (u8) (value >> 24);
- ret = cx231xx_write_ctrl_reg(dev,
- VRT_SET_REGISTER,
- (u16)reg->reg, data,
- 4);
- break;
- case 1: /* AFE - read byte */
- ret = cx231xx_write_i2c_data(dev,
- AFE_DEVICE_ADDRESS,
- (u16)reg->reg, 2,
- value, 1);
- break;
- case 14: /* AFE - read dword */
- ret = cx231xx_write_i2c_data(dev,
- AFE_DEVICE_ADDRESS,
- (u16)reg->reg, 2,
- value, 4);
- break;
- case 2: /* Video Block - read byte */
- ret =
- cx231xx_write_i2c_data(dev,
- VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2,
- value, 1);
- break;
- case 24: /* Video Block - read dword */
- ret =
- cx231xx_write_i2c_data(dev,
- VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2,
- value, 4);
- break;
- case 3: /* I2S block - read byte */
- ret =
- cx231xx_write_i2c_data(dev,
- I2S_BLK_DEVICE_ADDRESS,
- (u16)reg->reg, 1,
- value, 1);
- break;
- case 34: /* I2S block - read dword */
- ret =
- cx231xx_write_i2c_data(dev,
- I2S_BLK_DEVICE_ADDRESS,
- (u16)reg->reg, 1,
- value, 4);
- break;
- }
- }
- return ret < 0 ? ret : 0;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- {
- value = (u32) buf & 0xffffffff;
-
- switch (reg->match.addr) {
- case 0:/*cx231xx internal registers*/
- data[0] = (u8) value;
- data[1] = (u8) (value >> 8);
- data[2] = (u8) (value >> 16);
- data[3] = (u8) (value >> 24);
- ret = cx231xx_write_ctrl_reg(dev,
- VRT_SET_REGISTER,
- (u16)reg->reg, data,
- 4);
- break;
- case 0x600:/* AFE - read byte */
- ret = cx231xx_write_i2c_master(dev,
- AFE_DEVICE_ADDRESS,
- (u16)reg->reg, 2,
- value, 1 , 0);
- break;
-
- case 0x880:/* Video Block - read byte */
- if (reg->reg < 0x0b)
- cx231xx_write_i2c_master(dev,
- VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2,
- value, 1, 0);
- else
- cx231xx_write_i2c_master(dev,
- VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2,
- value, 4, 0);
- break;
- case 0x980:
- ret =
- cx231xx_write_i2c_master(dev,
- I2S_BLK_DEVICE_ADDRESS,
- (u16)reg->reg, 1,
- value, 1, 0);
- break;
- case 0x400:
- ret =
- cx231xx_write_i2c_master(dev,
- 0x40,
- (u16)reg->reg, 1,
- value, 1, 0);
- break;
- case 0xc01:
- ret =
- cx231xx_write_i2c_master(dev,
- 0xc0,
- (u16)reg->reg, 1,
- value, 1, 1);
- break;
-
- case 0x022:
- ret =
- cx231xx_write_i2c_master(dev,
- 0x02,
- (u16)reg->reg, 1,
- value, 1, 2);
- case 0x322:
- ret =
- cx231xx_write_i2c_master(dev,
- 0x32,
- (u16)reg->reg, 1,
- value, 4, 2);
- break;
-
- case 0x342:
- ret =
- cx231xx_write_i2c_master(dev,
- 0x34,
- (u16)reg->reg, 1,
- value, 4, 2);
- break;
- default:
- cx231xx_info("no match device address, "
- "the value is %x\n", reg->match.addr);
- break;
-
- }
-
- }
- default:
- break;
- }
-
- call_all(dev, core, s_register, reg);
-
- return ret;
-}
-#endif
-
-static int vidioc_cropcap(struct file *file, void *priv,
- struct v4l2_cropcap *cc)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
-
- if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- cc->bounds.left = 0;
- cc->bounds.top = 0;
- cc->bounds.width = dev->width;
- cc->bounds.height = dev->height;
- cc->defrect = cc->bounds;
- cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */
- cc->pixelaspect.denominator = 59;
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- rc = res_get(fh);
-
- if (likely(rc >= 0))
- rc = videobuf_streamon(&fh->vb_vidq);
-
- call_all(dev, video, s_stream, 1);
-
- return rc;
-}
-
-static int vidioc_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
- if (type != fh->type)
- return -EINVAL;
-
- cx25840_call(dev, video, s_stream, 0);
-
- videobuf_streamoff(&fh->vb_vidq);
- res_free(fh);
-
- return 0;
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
-
- strlcpy(cap->driver, "cx231xx", sizeof(cap->driver));
- strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card));
- usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
-
- cap->capabilities = V4L2_CAP_VBI_CAPTURE |
-#if 0
- V4L2_CAP_SLICED_VBI_CAPTURE |
-#endif
- V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_AUDIO |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING;
-
- if (dev->tuner_type != TUNER_ABSENT)
- cap->capabilities |= V4L2_CAP_TUNER;
-
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (unlikely(f->index >= ARRAY_SIZE(format)))
- return -EINVAL;
-
- strlcpy(f->description, format[f->index].name, sizeof(f->description));
- f->pixelformat = format[f->index].fourcc;
-
- return 0;
-}
-
-/* Sliced VBI ioctls */
-static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- f->fmt.sliced.service_set = 0;
-
- call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced);
-
- if (f->fmt.sliced.service_set == 0)
- rc = -EINVAL;
-
- return rc;
-}
-
-static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced);
-
- if (f->fmt.sliced.service_set == 0)
- return -EINVAL;
-
- return 0;
-}
-
-/* RAW VBI ioctls */
-
-static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- f->fmt.vbi.sampling_rate = 6750000 * 4;
- f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
- f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
- f->fmt.vbi.offset = 0;
- f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ?
- PAL_VBI_START_LINE : NTSC_VBI_START_LINE;
- f->fmt.vbi.count[0] = (dev->norm & V4L2_STD_625_50) ?
- PAL_VBI_LINES : NTSC_VBI_LINES;
- f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ?
- PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263;
- f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
-
- return 0;
-
-}
-
-static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
-
- if (dev->vbi_stream_on && !fh->stream_on) {
- cx231xx_errdev("%s device in use by another fh\n", __func__);
- return -EBUSY;
- }
-
- f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
- f->fmt.vbi.sampling_rate = 6750000 * 4;
- f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
- f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
- f->fmt.vbi.offset = 0;
- f->fmt.vbi.flags = 0;
- f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ?
- PAL_VBI_START_LINE : NTSC_VBI_START_LINE;
- f->fmt.vbi.count[0] = (dev->norm & V4L2_STD_625_50) ?
- PAL_VBI_LINES : NTSC_VBI_LINES;
- f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ?
- PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263;
- f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
-
- return 0;
-
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *rb)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- return videobuf_reqbufs(&fh->vb_vidq, rb);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- return videobuf_querybuf(&fh->vb_vidq, b);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- return videobuf_qbuf(&fh->vb_vidq, b);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct cx231xx_fh *fh = priv;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
-}
-
-/* ----------------------------------------------------------- */
-/* RADIO ESPECIFIC IOCTLS */
-/* ----------------------------------------------------------- */
-
-static int radio_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;
-
- strlcpy(cap->driver, "cx231xx", sizeof(cap->driver));
- strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card));
- usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
-
- cap->capabilities = V4L2_CAP_TUNER;
- return 0;
-}
-
-static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
-{
- struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;
-
- if (unlikely(t->index > 0))
- return -EINVAL;
-
- strcpy(t->name, "Radio");
- t->type = V4L2_TUNER_RADIO;
-
- call_all(dev, tuner, s_tuner, t);
-
- return 0;
-}
-
-static int radio_enum_input(struct file *file, void *priv, struct v4l2_input *i)
-{
- if (i->index != 0)
- return -EINVAL;
- strcpy(i->name, "Radio");
- i->type = V4L2_INPUT_TYPE_TUNER;
-
- return 0;
-}
-
-static int radio_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- if (unlikely(a->index))
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- return 0;
-}
-
-static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
-{
- struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;
-
- if (0 != t->index)
- return -EINVAL;
-
- call_all(dev, tuner, s_tuner, t);
-
- return 0;
-}
-
-static int radio_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
-{
- return 0;
-}
-
-static int radio_s_input(struct file *file, void *fh, unsigned int i)
-{
- return 0;
-}
-
-static int radio_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *c)
-{
- int i;
-
- if (c->id < V4L2_CID_BASE || c->id >= V4L2_CID_LASTP1)
- return -EINVAL;
- if (c->id == V4L2_CID_AUDIO_MUTE) {
- for (i = 0; i < CX231XX_CTLS; i++) {
- if (cx231xx_ctls[i].v.id == c->id)
- break;
- }
- if (i == CX231XX_CTLS)
- return -EINVAL;
- *c = cx231xx_ctls[i].v;
- } else
- *c = no_ctl;
- return 0;
-}
-
-/*
- * cx231xx_v4l2_open()
- * inits the device and starts isoc transfer
- */
-static int cx231xx_v4l2_open(struct file *filp)
-{
- int errCode = 0, radio = 0;
- struct video_device *vdev = video_devdata(filp);
- struct cx231xx *dev = video_drvdata(filp);
- struct cx231xx_fh *fh;
- enum v4l2_buf_type fh_type = 0;
-
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- case VFL_TYPE_VBI:
- fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- case VFL_TYPE_RADIO:
- radio = 1;
- break;
- }
-
- cx231xx_videodbg("open dev=%s type=%s users=%d\n",
- video_device_node_name(vdev), v4l2_type_names[fh_type],
- dev->users);
-
-#if 0
- errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
- if (errCode < 0) {
- cx231xx_errdev
- ("Device locked on digital mode. Can't open analog\n");
- return -EBUSY;
- }
-#endif
-
- fh = kzalloc(sizeof(struct cx231xx_fh), GFP_KERNEL);
- if (!fh) {
- cx231xx_errdev("cx231xx-video.c: Out of memory?!\n");
- return -ENOMEM;
- }
- fh->dev = dev;
- fh->radio = radio;
- fh->type = fh_type;
- filp->private_data = fh;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
- dev->width = norm_maxw(dev);
- dev->height = norm_maxh(dev);
-
- /* Power up in Analog TV mode */
- if (dev->board.external_av)
- cx231xx_set_power_mode(dev,
- POLARIS_AVMODE_ENXTERNAL_AV);
- else
- cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV);
-
-#if 0
- cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
-#endif
-
- /* set video alternate setting */
- cx231xx_set_video_alternate(dev);
-
- /* Needed, since GPIO might have disabled power of
- some i2c device */
- cx231xx_config_i2c(dev);
-
- /* device needs to be initialized before isoc transfer */
- dev->video_input = dev->video_input > 2 ? 2 : dev->video_input;
-
- }
- if (fh->radio) {
- cx231xx_videodbg("video_open: setting radio device\n");
-
- /* cx231xx_start_radio(dev); */
-
- call_all(dev, tuner, s_radio);
- }
-
- dev->users++;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_video_qops,
- NULL, &dev->video_mode.slock,
- fh->type, V4L2_FIELD_INTERLACED,
- sizeof(struct cx231xx_buffer),
- fh, &dev->lock);
- if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- /* Set the required alternate setting VBI interface works in
- Bulk mode only */
- cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
-
- videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops,
- NULL, &dev->vbi_mode.slock,
- fh->type, V4L2_FIELD_SEQ_TB,
- sizeof(struct cx231xx_buffer),
- fh, &dev->lock);
- }
-
- return errCode;
-}
-
-/*
- * cx231xx_realease_resources()
- * unregisters the v4l2,i2c and usb devices
- * called when the device gets disconected or at module unload
-*/
-void cx231xx_release_analog_resources(struct cx231xx *dev)
-{
-
- /*FIXME: I2C IR should be disconnected */
-
- if (dev->radio_dev) {
- if (video_is_registered(dev->radio_dev))
- video_unregister_device(dev->radio_dev);
- else
- video_device_release(dev->radio_dev);
- dev->radio_dev = NULL;
- }
- if (dev->vbi_dev) {
- cx231xx_info("V4L2 device %s deregistered\n",
- video_device_node_name(dev->vbi_dev));
- if (video_is_registered(dev->vbi_dev))
- video_unregister_device(dev->vbi_dev);
- else
- video_device_release(dev->vbi_dev);
- dev->vbi_dev = NULL;
- }
- if (dev->vdev) {
- cx231xx_info("V4L2 device %s deregistered\n",
- video_device_node_name(dev->vdev));
-
- if (dev->board.has_417)
- cx231xx_417_unregister(dev);
-
- if (video_is_registered(dev->vdev))
- video_unregister_device(dev->vdev);
- else
- video_device_release(dev->vdev);
- dev->vdev = NULL;
- }
-}
-
-/*
- * cx231xx_v4l2_close()
- * stops streaming and deallocates all resources allocated by the v4l2
- * calls and ioctls
- */
-static int cx231xx_v4l2_close(struct file *filp)
-{
- struct cx231xx_fh *fh = filp->private_data;
- struct cx231xx *dev = fh->dev;
-
- cx231xx_videodbg("users=%d\n", dev->users);
-
- cx231xx_videodbg("users=%d\n", dev->users);
- if (res_check(fh))
- res_free(fh);
-
- /*
- * To workaround error number=-71 on EP0 for VideoGrabber,
- * need exclude following.
- * FIXME: It is probably safe to remove most of these, as we're
- * now avoiding the alternate setting for INDEX_VANC
- */
- if (!dev->board.no_alt_vanc)
- if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- videobuf_stop(&fh->vb_vidq);
- videobuf_mmap_free(&fh->vb_vidq);
-
- /* the device is already disconnect,
- free the remaining resources */
- if (dev->state & DEV_DISCONNECTED) {
- if (atomic_read(&dev->devlist_count) > 0) {
- cx231xx_release_resources(dev);
- fh->dev = NULL;
- return 0;
- }
- return 0;
- }
-
- /* do this before setting alternate! */
- cx231xx_uninit_vbi_isoc(dev);
-
- /* set alternate 0 */
- if (!dev->vbi_or_sliced_cc_mode)
- cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
- else
- cx231xx_set_alt_setting(dev, INDEX_HANC, 0);
-
- kfree(fh);
- dev->users--;
- wake_up_interruptible_nr(&dev->open, 1);
- return 0;
- }
-
- dev->users--;
- if (!dev->users) {
- videobuf_stop(&fh->vb_vidq);
- videobuf_mmap_free(&fh->vb_vidq);
-
- /* the device is already disconnect,
- free the remaining resources */
- if (dev->state & DEV_DISCONNECTED) {
- cx231xx_release_resources(dev);
- fh->dev = NULL;
- return 0;
- }
-
- /* Save some power by putting tuner to sleep */
- call_all(dev, core, s_power, 0);
-
- /* do this before setting alternate! */
- if (dev->USE_ISO)
- cx231xx_uninit_isoc(dev);
- else
- cx231xx_uninit_bulk(dev);
- cx231xx_set_mode(dev, CX231XX_SUSPEND);
-
- /* set alternate 0 */
- cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0);
- }
- kfree(fh);
- wake_up_interruptible_nr(&dev->open, 1);
- return 0;
-}
-
-/*
- * cx231xx_v4l2_read()
- * will allocate buffers when called for the first time
- */
-static ssize_t
-cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
- loff_t *pos)
-{
- struct cx231xx_fh *fh = filp->private_data;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if ((fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
- (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)) {
- rc = res_get(fh);
-
- if (unlikely(rc < 0))
- return rc;
-
- return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
- filp->f_flags & O_NONBLOCK);
- }
- return 0;
-}
-
-/*
- * cx231xx_v4l2_poll()
- * will allocate buffers when called for the first time
- */
-static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table *wait)
-{
- struct cx231xx_fh *fh = filp->private_data;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- rc = res_get(fh);
-
- if (unlikely(rc < 0))
- return POLLERR;
-
- if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == fh->type) ||
- (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type))
- return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
- else
- return POLLERR;
-}
-
-/*
- * cx231xx_v4l2_mmap()
- */
-static int cx231xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- struct cx231xx_fh *fh = filp->private_data;
- struct cx231xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- rc = res_get(fh);
-
- if (unlikely(rc < 0))
- return rc;
-
- rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
-
- cx231xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",
- (unsigned long)vma->vm_start,
- (unsigned long)vma->vm_end -
- (unsigned long)vma->vm_start, rc);
-
- return rc;
-}
-
-static const struct v4l2_file_operations cx231xx_v4l_fops = {
- .owner = THIS_MODULE,
- .open = cx231xx_v4l2_open,
- .release = cx231xx_v4l2_close,
- .read = cx231xx_v4l2_read,
- .poll = cx231xx_v4l2_poll,
- .mmap = cx231xx_v4l2_mmap,
- .unlocked_ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
- .vidioc_try_fmt_vbi_cap = vidioc_try_fmt_vbi_cap,
- .vidioc_s_fmt_vbi_cap = vidioc_try_fmt_vbi_cap,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_cropcap = vidioc_cropcap,
- .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
- .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_g_std = vidioc_g_std,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vidioc_g_register,
- .vidioc_s_register = vidioc_s_register,
-#endif
-};
-
-static struct video_device cx231xx_vbi_template;
-
-static const struct video_device cx231xx_video_template = {
- .fops = &cx231xx_v4l_fops,
- .release = video_device_release,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = V4L2_STD_ALL,
- .current_norm = V4L2_STD_PAL,
-};
-
-static const struct v4l2_file_operations radio_fops = {
- .owner = THIS_MODULE,
- .open = cx231xx_v4l2_open,
- .release = cx231xx_v4l2_close,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops radio_ioctl_ops = {
- .vidioc_querycap = radio_querycap,
- .vidioc_g_tuner = radio_g_tuner,
- .vidioc_enum_input = radio_enum_input,
- .vidioc_g_audio = radio_g_audio,
- .vidioc_s_tuner = radio_s_tuner,
- .vidioc_s_audio = radio_s_audio,
- .vidioc_s_input = radio_s_input,
- .vidioc_queryctrl = radio_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vidioc_g_register,
- .vidioc_s_register = vidioc_s_register,
-#endif
-};
-
-static struct video_device cx231xx_radio_template = {
- .name = "cx231xx-radio",
- .fops = &radio_fops,
- .ioctl_ops = &radio_ioctl_ops,
-};
-
-/******************************** usb interface ******************************/
-
-static struct video_device *cx231xx_vdev_init(struct cx231xx *dev,
- const struct video_device
- *template, const char *type_name)
-{
- struct video_device *vfd;
-
- vfd = video_device_alloc();
- if (NULL == vfd)
- return NULL;
-
- *vfd = *template;
- vfd->v4l2_dev = &dev->v4l2_dev;
- vfd->release = video_device_release;
- vfd->debug = video_debug;
- vfd->lock = &dev->lock;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
-
- snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
-
- video_set_drvdata(vfd, dev);
- return vfd;
-}
-
-int cx231xx_register_analog_devices(struct cx231xx *dev)
-{
- int ret;
-
- cx231xx_info("%s: v4l2 driver version %s\n",
- dev->name, CX231XX_VERSION);
-
- /* set default norm */
- /*dev->norm = cx231xx_video_template.current_norm; */
- dev->width = norm_maxw(dev);
- dev->height = norm_maxh(dev);
- dev->interlaced = 0;
-
- /* Analog specific initialization */
- dev->format = &format[0];
-
- /* Set the initial input */
- video_mux(dev, dev->video_input);
-
- /* Audio defaults */
- dev->mute = 1;
- dev->volume = 0x1f;
-
- /* enable vbi capturing */
- /* write code here... */
-
- /* allocate and fill video video_device struct */
- dev->vdev = cx231xx_vdev_init(dev, &cx231xx_video_template, "video");
- if (!dev->vdev) {
- cx231xx_errdev("cannot allocate video_device.\n");
- return -ENODEV;
- }
-
- /* register v4l2 video video_device */
- ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
- video_nr[dev->devno]);
- if (ret) {
- cx231xx_errdev("unable to register video device (error=%i).\n",
- ret);
- return ret;
- }
-
- cx231xx_info("%s/0: registered device %s [v4l2]\n",
- dev->name, video_device_node_name(dev->vdev));
-
- /* Initialize VBI template */
- memcpy(&cx231xx_vbi_template, &cx231xx_video_template,
- sizeof(cx231xx_vbi_template));
- strcpy(cx231xx_vbi_template.name, "cx231xx-vbi");
-
- /* Allocate and fill vbi video_device struct */
- dev->vbi_dev = cx231xx_vdev_init(dev, &cx231xx_vbi_template, "vbi");
-
- /* register v4l2 vbi video_device */
- ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
- vbi_nr[dev->devno]);
- if (ret < 0) {
- cx231xx_errdev("unable to register vbi device\n");
- return ret;
- }
-
- cx231xx_info("%s/0: registered device %s\n",
- dev->name, video_device_node_name(dev->vbi_dev));
-
- if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) {
- dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template,
- "radio");
- if (!dev->radio_dev) {
- cx231xx_errdev("cannot allocate video_device.\n");
- return -ENODEV;
- }
- ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
- radio_nr[dev->devno]);
- if (ret < 0) {
- cx231xx_errdev("can't register radio device\n");
- return ret;
- }
- cx231xx_info("Registered radio device as %s\n",
- video_device_node_name(dev->radio_dev));
- }
-
- cx231xx_info("V4L2 device registered as %s and %s\n",
- video_device_node_name(dev->vdev),
- video_device_node_name(dev->vbi_dev));
-
- return 0;
-}
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
deleted file mode 100644
index a89d020de94..00000000000
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ /dev/null
@@ -1,1012 +0,0 @@
-/*
- cx231xx.h - driver for Conexant Cx23100/101/102 USB video capture devices
-
- Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
- Based on em28xx driver
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _CX231XX_H
-#define _CX231XX_H
-
-#include <linux/videodev2.h>
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#include <linux/i2c.h>
-#include <linux/workqueue.h>
-#include <linux/mutex.h>
-
-#include <media/cx2341x.h>
-
-#include <media/videobuf-vmalloc.h>
-#include <media/v4l2-device.h>
-#include <media/rc-core.h>
-#include <media/ir-kbd-i2c.h>
-#include <media/videobuf-dvb.h>
-
-#include "cx231xx-reg.h"
-#include "cx231xx-pcb-cfg.h"
-#include "cx231xx-conf-reg.h"
-
-#define DRIVER_NAME "cx231xx"
-#define PWR_SLEEP_INTERVAL 10
-
-/* I2C addresses for control block in Cx231xx */
-#define AFE_DEVICE_ADDRESS 0x60
-#define I2S_BLK_DEVICE_ADDRESS 0x98
-#define VID_BLK_I2C_ADDRESS 0x88
-#define VERVE_I2C_ADDRESS 0x40
-#define DIF_USE_BASEBAND 0xFFFFFFFF
-
-/* Boards supported by driver */
-#define CX231XX_BOARD_UNKNOWN 0
-#define CX231XX_BOARD_CNXT_CARRAERA 1
-#define CX231XX_BOARD_CNXT_SHELBY 2
-#define CX231XX_BOARD_CNXT_RDE_253S 3
-#define CX231XX_BOARD_CNXT_RDU_253S 4
-#define CX231XX_BOARD_CNXT_VIDEO_GRABBER 5
-#define CX231XX_BOARD_CNXT_RDE_250 6
-#define CX231XX_BOARD_CNXT_RDU_250 7
-#define CX231XX_BOARD_HAUPPAUGE_EXETER 8
-#define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9
-#define CX231XX_BOARD_PV_PLAYTV_USB_HYBRID 10
-#define CX231XX_BOARD_PV_XCAPTURE_USB 11
-#define CX231XX_BOARD_KWORLD_UB430_USB_HYBRID 12
-#define CX231XX_BOARD_ICONBIT_U100 13
-#define CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL 14
-#define CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC 15
-
-/* Limits minimum and default number of buffers */
-#define CX231XX_MIN_BUF 4
-#define CX231XX_DEF_BUF 12
-#define CX231XX_DEF_VBI_BUF 6
-
-#define VBI_LINE_COUNT 17
-#define VBI_LINE_LENGTH 1440
-
-/*Limits the max URB message size */
-#define URB_MAX_CTRL_SIZE 80
-
-/* Params for validated field */
-#define CX231XX_BOARD_NOT_VALIDATED 1
-#define CX231XX_BOARD_VALIDATED 0
-
-/* maximum number of cx231xx boards */
-#define CX231XX_MAXBOARDS 8
-
-/* maximum number of frames that can be queued */
-#define CX231XX_NUM_FRAMES 5
-
-/* number of buffers for isoc transfers */
-#define CX231XX_NUM_BUFS 8
-
-/* number of packets for each buffer
- windows requests only 40 packets .. so we better do the same
- this is what I found out for all alternate numbers there!
- */
-#define CX231XX_NUM_PACKETS 40
-
-/* default alternate; 0 means choose the best */
-#define CX231XX_PINOUT 0
-
-#define CX231XX_INTERLACED_DEFAULT 1
-
-/* time to wait when stopping the isoc transfer */
-#define CX231XX_URB_TIMEOUT \
- msecs_to_jiffies(CX231XX_NUM_BUFS * CX231XX_NUM_PACKETS)
-
-#define CX231xx_NORMS (\
- V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443 | \
- V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \
- V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | \
- V4L2_STD_PAL_60 | V4L2_STD_SECAM_L | V4L2_STD_SECAM_DK)
-
-#define SLEEP_S5H1432 30
-#define CX23417_OSC_EN 8
-#define CX23417_RESET 9
-
-struct cx23417_fmt {
- char *name;
- u32 fourcc; /* v4l2 format id */
- int depth;
- int flags;
- u32 cxformat;
-};
-enum cx231xx_mode {
- CX231XX_SUSPEND,
- CX231XX_ANALOG_MODE,
- CX231XX_DIGITAL_MODE,
-};
-
-enum cx231xx_std_mode {
- CX231XX_TV_AIR = 0,
- CX231XX_TV_CABLE
-};
-
-enum cx231xx_stream_state {
- STREAM_OFF,
- STREAM_INTERRUPT,
- STREAM_ON,
-};
-
-struct cx231xx;
-
-struct cx231xx_isoc_ctl {
- /* max packet size of isoc transaction */
- int max_pkt_size;
-
- /* number of allocated urbs */
- int num_bufs;
-
- /* urb for isoc transfers */
- struct urb **urb;
-
- /* transfer buffers for isoc transfer */
- char **transfer_buffer;
-
- /* Last buffer command and region */
- u8 cmd;
- int pos, size, pktsize;
-
- /* Last field: ODD or EVEN? */
- int field;
-
- /* Stores incomplete commands */
- u32 tmp_buf;
- int tmp_buf_len;
-
- /* Stores already requested buffers */
- struct cx231xx_buffer *buf;
-
- /* Stores the number of received fields */
- int nfields;
-
- /* isoc urb callback */
- int (*isoc_copy) (struct cx231xx *dev, struct urb *urb);
-};
-
-struct cx231xx_bulk_ctl {
- /* max packet size of bulk transaction */
- int max_pkt_size;
-
- /* number of allocated urbs */
- int num_bufs;
-
- /* urb for bulk transfers */
- struct urb **urb;
-
- /* transfer buffers for bulk transfer */
- char **transfer_buffer;
-
- /* Last buffer command and region */
- u8 cmd;
- int pos, size, pktsize;
-
- /* Last field: ODD or EVEN? */
- int field;
-
- /* Stores incomplete commands */
- u32 tmp_buf;
- int tmp_buf_len;
-
- /* Stores already requested buffers */
- struct cx231xx_buffer *buf;
-
- /* Stores the number of received fields */
- int nfields;
-
- /* bulk urb callback */
- int (*bulk_copy) (struct cx231xx *dev, struct urb *urb);
-};
-
-struct cx231xx_fmt {
- char *name;
- u32 fourcc; /* v4l2 format id */
- int depth;
- int reg;
-};
-
-/* buffer for one video frame */
-struct cx231xx_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
-
- struct list_head frame;
- int top_field;
- int receiving;
-};
-
-enum ps_package_head {
- CX231XX_NEED_ADD_PS_PACKAGE_HEAD = 0,
- CX231XX_NONEED_PS_PACKAGE_HEAD
-};
-
-struct cx231xx_dmaqueue {
- struct list_head active;
- struct list_head queued;
-
- wait_queue_head_t wq;
-
- /* Counters to control buffer fill */
- int pos;
- u8 is_partial_line;
- u8 partial_buf[8];
- u8 last_sav;
- int current_field;
- u32 bytes_left_in_line;
- u32 lines_completed;
- u8 field1_done;
- u32 lines_per_field;
-
- /*Mpeg2 control buffer*/
- u8 *p_left_data;
- u32 left_data_count;
- u8 mpeg_buffer_done;
- u32 mpeg_buffer_completed;
- enum ps_package_head add_ps_package_head;
- char ps_head[10];
-};
-
-/* inputs */
-
-#define MAX_CX231XX_INPUT 4
-
-enum cx231xx_itype {
- CX231XX_VMUX_COMPOSITE1 = 1,
- CX231XX_VMUX_SVIDEO,
- CX231XX_VMUX_TELEVISION,
- CX231XX_VMUX_CABLE,
- CX231XX_RADIO,
- CX231XX_VMUX_DVB,
- CX231XX_VMUX_DEBUG
-};
-
-enum cx231xx_v_input {
- CX231XX_VIN_1_1 = 0x1,
- CX231XX_VIN_2_1,
- CX231XX_VIN_3_1,
- CX231XX_VIN_4_1,
- CX231XX_VIN_1_2 = 0x01,
- CX231XX_VIN_2_2,
- CX231XX_VIN_3_2,
- CX231XX_VIN_1_3 = 0x1,
- CX231XX_VIN_2_3,
- CX231XX_VIN_3_3,
-};
-
-/* cx231xx has two audio inputs: tuner and line in */
-enum cx231xx_amux {
- /* This is the only entry for cx231xx tuner input */
- CX231XX_AMUX_VIDEO, /* cx231xx tuner */
- CX231XX_AMUX_LINE_IN, /* Line In */
-};
-
-struct cx231xx_reg_seq {
- unsigned char bit;
- unsigned char val;
- int sleep;
-};
-
-struct cx231xx_input {
- enum cx231xx_itype type;
- unsigned int vmux;
- enum cx231xx_amux amux;
- struct cx231xx_reg_seq *gpio;
-};
-
-#define INPUT(nr) (&cx231xx_boards[dev->model].input[nr])
-
-enum cx231xx_decoder {
- CX231XX_NODECODER,
- CX231XX_AVDECODER
-};
-
-enum CX231XX_I2C_MASTER_PORT {
- I2C_0 = 0,
- I2C_1 = 1,
- I2C_2 = 2,
- I2C_3 = 3
-};
-
-struct cx231xx_board {
- char *name;
- int vchannels;
- int tuner_type;
- int tuner_addr;
- v4l2_std_id norm; /* tv norm */
-
- /* demod related */
- int demod_addr;
- u8 demod_xfer_mode; /* 0 - Serial; 1 - parallel */
-
- /* GPIO Pins */
- struct cx231xx_reg_seq *dvb_gpio;
- struct cx231xx_reg_seq *suspend_gpio;
- struct cx231xx_reg_seq *tuner_gpio;
- /* Negative means don't use it */
- s8 tuner_sif_gpio;
- s8 tuner_scl_gpio;
- s8 tuner_sda_gpio;
-
- /* PIN ctrl */
- u32 ctl_pin_status_mask;
- u8 agc_analog_digital_select_gpio;
- u32 gpio_pin_status_mask;
-
- /* i2c masters */
- u8 tuner_i2c_master;
- u8 demod_i2c_master;
- u8 ir_i2c_master;
-
- /* for devices with I2C chips for IR */
- char *rc_map_name;
-
- unsigned int max_range_640_480:1;
- unsigned int has_dvb:1;
- unsigned int has_417:1;
- unsigned int valid:1;
- unsigned int no_alt_vanc:1;
- unsigned int external_av:1;
- unsigned int dont_use_port_3:1;
-
- unsigned char xclk, i2c_speed;
-
- enum cx231xx_decoder decoder;
- int output_mode;
-
- struct cx231xx_input input[MAX_CX231XX_INPUT];
- struct cx231xx_input radio;
- struct rc_map *ir_codes;
-};
-
-/* device states */
-enum cx231xx_dev_state {
- DEV_INITIALIZED = 0x01,
- DEV_DISCONNECTED = 0x02,
-};
-
-enum AFE_MODE {
- AFE_MODE_LOW_IF,
- AFE_MODE_BASEBAND,
- AFE_MODE_EU_HI_IF,
- AFE_MODE_US_HI_IF,
- AFE_MODE_JAPAN_HI_IF
-};
-
-enum AUDIO_INPUT {
- AUDIO_INPUT_MUTE,
- AUDIO_INPUT_LINE,
- AUDIO_INPUT_TUNER_TV,
- AUDIO_INPUT_SPDIF,
- AUDIO_INPUT_TUNER_FM
-};
-
-#define CX231XX_AUDIO_BUFS 5
-#define CX231XX_NUM_AUDIO_PACKETS 16
-#define CX231XX_ISO_NUM_AUDIO_PACKETS 64
-
-/* cx231xx extensions */
-#define CX231XX_AUDIO 0x10
-#define CX231XX_DVB 0x20
-
-struct cx231xx_audio {
- char name[50];
- char *transfer_buffer[CX231XX_AUDIO_BUFS];
- struct urb *urb[CX231XX_AUDIO_BUFS];
- struct usb_device *udev;
- unsigned int capture_transfer_done;
- struct snd_pcm_substream *capture_pcm_substream;
-
- unsigned int hwptr_done_capture;
- struct snd_card *sndcard;
-
- int users, shutdown;
- /* locks */
- spinlock_t slock;
-
- int alt; /* alternate */
- int max_pkt_size; /* max packet size of isoc transaction */
- int num_alt; /* Number of alternative settings */
- unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
- u16 end_point_addr;
-};
-
-struct cx231xx;
-
-struct cx231xx_fh {
- struct cx231xx *dev;
- unsigned int stream_on:1; /* Locks streams */
- int radio;
-
- struct videobuf_queue vb_vidq;
-
- enum v4l2_buf_type type;
-
-
-
-/*following is copyed from cx23885.h*/
- u32 resources;
-
- /* video overlay */
- struct v4l2_window win;
- struct v4l2_clip *clips;
- unsigned int nclips;
-
- /* video capture */
- struct cx23417_fmt *fmt;
- unsigned int width, height;
-
- /* vbi capture */
- struct videobuf_queue vidq;
- struct videobuf_queue vbiq;
-
- /* MPEG Encoder specifics ONLY */
-
- atomic_t v4l_reading;
-};
-
-/*****************************************************************/
-/* set/get i2c */
-/* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */
-#define I2C_SPEED_1M 0x0
-#define I2C_SPEED_400K 0x1
-#define I2C_SPEED_100K 0x2
-#define I2C_SPEED_5M 0x3
-
-/* 0-- STOP transaction */
-#define I2C_STOP 0x0
-/* 1-- do not transmit STOP at end of transaction */
-#define I2C_NOSTOP 0x1
-/* 1--allow slave to insert clock wait states */
-#define I2C_SYNC 0x1
-
-struct cx231xx_i2c {
- struct cx231xx *dev;
-
- int nr;
-
- /* i2c i/o */
- struct i2c_adapter i2c_adap;
- struct i2c_client i2c_client;
- u32 i2c_rc;
-
- /* different settings for each bus */
- u8 i2c_period;
- u8 i2c_nostop;
- u8 i2c_reserve;
-};
-
-struct cx231xx_i2c_xfer_data {
- u8 dev_addr;
- u8 direction; /* 1 - IN, 0 - OUT */
- u8 saddr_len; /* sub address len */
- u16 saddr_dat; /* sub addr data */
- u8 buf_size; /* buffer size */
- u8 *p_buffer; /* pointer to the buffer */
-};
-
-struct VENDOR_REQUEST_IN {
- u8 bRequest;
- u16 wValue;
- u16 wIndex;
- u16 wLength;
- u8 direction;
- u8 bData;
- u8 *pBuff;
-};
-
-struct cx231xx_tvnorm {
- char *name;
- v4l2_std_id id;
- u32 cxiformat;
- u32 cxoformat;
-};
-
-struct cx231xx_ctrl {
- struct v4l2_queryctrl v;
- u32 off;
- u32 reg;
- u32 mask;
- u32 shift;
-};
-
-enum TRANSFER_TYPE {
- Raw_Video = 0,
- Audio,
- Vbi, /* VANC */
- Sliced_cc, /* HANC */
- TS1_serial_mode,
- TS2,
- TS1_parallel_mode
-} ;
-
-struct cx231xx_video_mode {
- /* Isoc control struct */
- struct cx231xx_dmaqueue vidq;
- struct cx231xx_isoc_ctl isoc_ctl;
- struct cx231xx_bulk_ctl bulk_ctl;
- /* locks */
- spinlock_t slock;
-
- /* usb transfer */
- int alt; /* alternate */
- int max_pkt_size; /* max packet size of isoc transaction */
- int num_alt; /* Number of alternative settings */
- unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
- u16 end_point_addr;
-};
-/*
-struct cx23885_dmaqueue {
- struct list_head active;
- struct list_head queued;
- struct timer_list timeout;
- struct btcx_riscmem stopper;
- u32 count;
-};
-*/
-struct cx231xx_tsport {
- struct cx231xx *dev;
-
- int nr;
- int sram_chno;
-
- struct videobuf_dvb_frontends frontends;
-
- /* dma queues */
-
- u32 ts_packet_size;
- u32 ts_packet_count;
-
- int width;
- int height;
-
- /* locks */
- spinlock_t slock;
-
- /* registers */
- u32 reg_gpcnt;
- u32 reg_gpcnt_ctl;
- u32 reg_dma_ctl;
- u32 reg_lngth;
- u32 reg_hw_sop_ctrl;
- u32 reg_gen_ctrl;
- u32 reg_bd_pkt_status;
- u32 reg_sop_status;
- u32 reg_fifo_ovfl_stat;
- u32 reg_vld_misc;
- u32 reg_ts_clk_en;
- u32 reg_ts_int_msk;
- u32 reg_ts_int_stat;
- u32 reg_src_sel;
-
- /* Default register vals */
- int pci_irqmask;
- u32 dma_ctl_val;
- u32 ts_int_msk_val;
- u32 gen_ctrl_val;
- u32 ts_clk_en_val;
- u32 src_sel_val;
- u32 vld_misc_val;
- u32 hw_sop_ctrl_val;
-
- /* Allow a single tsport to have multiple frontends */
- u32 num_frontends;
- void *port_priv;
-};
-
-/* main device struct */
-struct cx231xx {
- /* generic device properties */
- char name[30]; /* name (including minor) of the device */
- int model; /* index in the device_data struct */
- int devno; /* marks the number of this device */
-
- struct cx231xx_board board;
-
- /* For I2C IR support */
- struct IR_i2c_init_data init_data;
- struct i2c_client *ir_i2c_client;
-
- unsigned int stream_on:1; /* Locks streams */
- unsigned int vbi_stream_on:1; /* Locks streams for VBI */
- unsigned int has_audio_class:1;
- unsigned int has_alsa_audio:1;
-
- struct cx231xx_fmt *format;
-
- struct v4l2_device v4l2_dev;
- struct v4l2_subdev *sd_cx25840;
- struct v4l2_subdev *sd_tuner;
-
- struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */
- atomic_t stream_started; /* stream should be running if true */
-
- struct list_head devlist;
-
- int tuner_type; /* type of the tuner */
- int tuner_addr; /* tuner address */
-
- /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */
- struct cx231xx_i2c i2c_bus[3];
- unsigned int xc_fw_load_done:1;
- /* locks */
- struct mutex gpio_i2c_lock;
- struct mutex i2c_lock;
-
- /* video for linux */
- int users; /* user count for exclusive use */
- struct video_device *vdev; /* video for linux device struct */
- v4l2_std_id norm; /* selected tv norm */
- int ctl_freq; /* selected frequency */
- unsigned int ctl_ainput; /* selected audio input */
- int mute;
- int volume;
-
- /* frame properties */
- int width; /* current frame width */
- int height; /* current frame height */
- int interlaced; /* 1=interlace fileds, 0=just top fileds */
-
- struct cx231xx_audio adev;
-
- /* states */
- enum cx231xx_dev_state state;
-
- struct work_struct request_module_wk;
-
- /* locks */
- struct mutex lock;
- struct mutex ctrl_urb_lock; /* protects urb_buf */
- struct list_head inqueue, outqueue;
- wait_queue_head_t open, wait_frame, wait_stream;
- struct video_device *vbi_dev;
- struct video_device *radio_dev;
-
- unsigned char eedata[256];
-
- struct cx231xx_video_mode video_mode;
- struct cx231xx_video_mode vbi_mode;
- struct cx231xx_video_mode sliced_cc_mode;
- struct cx231xx_video_mode ts1_mode;
-
- atomic_t devlist_count;
-
- struct usb_device *udev; /* the usb device */
- char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */
-
- /* helper funcs that call usb_control_msg */
- int (*cx231xx_read_ctrl_reg) (struct cx231xx *dev, u8 req, u16 reg,
- char *buf, int len);
- int (*cx231xx_write_ctrl_reg) (struct cx231xx *dev, u8 req, u16 reg,
- char *buf, int len);
- int (*cx231xx_send_usb_command) (struct cx231xx_i2c *i2c_bus,
- struct cx231xx_i2c_xfer_data *req_data);
- int (*cx231xx_gpio_i2c_read) (struct cx231xx *dev, u8 dev_addr,
- u8 *buf, u8 len);
- int (*cx231xx_gpio_i2c_write) (struct cx231xx *dev, u8 dev_addr,
- u8 *buf, u8 len);
-
- int (*cx231xx_set_analog_freq) (struct cx231xx *dev, u32 freq);
- int (*cx231xx_reset_analog_tuner) (struct cx231xx *dev);
-
- enum cx231xx_mode mode;
-
- struct cx231xx_dvb *dvb;
-
- /* Cx231xx supported PCB config's */
- struct pcb_config current_pcb_config;
- u8 current_scenario_idx;
- u8 interface_count;
- u8 max_iad_interface_count;
-
- /* GPIO related register direction and values */
- u32 gpio_dir;
- u32 gpio_val;
-
- /* Power Modes */
- int power_mode;
-
- /* afe parameters */
- enum AFE_MODE afe_mode;
- u32 afe_ref_count;
-
- /* video related parameters */
- u32 video_input;
- u32 active_mode;
- u8 vbi_or_sliced_cc_mode; /* 0 - vbi ; 1 - sliced cc mode */
- enum cx231xx_std_mode std_mode; /* 0 - Air; 1 - cable */
-
- /*mode: digital=1 or analog=0*/
- u8 mode_tv;
-
- u8 USE_ISO;
- struct cx231xx_tvnorm encodernorm;
- struct cx231xx_tsport ts1, ts2;
- struct cx2341x_mpeg_params mpeg_params;
- struct video_device *v4l_device;
- atomic_t v4l_reader_count;
- u32 freq;
- unsigned int input;
- u32 cx23417_mailbox;
- u32 __iomem *lmmio;
- u8 __iomem *bmmio;
-};
-
-extern struct list_head cx231xx_devlist;
-
-#define cx25840_call(cx231xx, o, f, args...) \
- v4l2_subdev_call(cx231xx->sd_cx25840, o, f, ##args)
-#define tuner_call(cx231xx, o, f, args...) \
- v4l2_subdev_call(cx231xx->sd_tuner, o, f, ##args)
-#define call_all(dev, o, f, args...) \
- v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
-
-struct cx231xx_ops {
- struct list_head next;
- char *name;
- int id;
- int (*init) (struct cx231xx *);
- int (*fini) (struct cx231xx *);
-};
-
-/* call back functions in dvb module */
-int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq);
-int cx231xx_reset_analog_tuner(struct cx231xx *dev);
-
-/* Provided by cx231xx-i2c.c */
-void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c);
-int cx231xx_i2c_register(struct cx231xx_i2c *bus);
-int cx231xx_i2c_unregister(struct cx231xx_i2c *bus);
-
-/* Internal block control functions */
-int cx231xx_read_i2c_master(struct cx231xx *dev, u8 dev_addr, u16 saddr,
- u8 saddr_len, u32 *data, u8 data_len, int master);
-int cx231xx_write_i2c_master(struct cx231xx *dev, u8 dev_addr, u16 saddr,
- u8 saddr_len, u32 data, u8 data_len, int master);
-int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr,
- u16 saddr, u8 saddr_len, u32 *data, u8 data_len);
-int cx231xx_write_i2c_data(struct cx231xx *dev, u8 dev_addr,
- u16 saddr, u8 saddr_len, u32 data, u8 data_len);
-int cx231xx_reg_mask_write(struct cx231xx *dev, u8 dev_addr, u8 size,
- u16 register_address, u8 bit_start, u8 bit_end,
- u32 value);
-int cx231xx_read_modify_write_i2c_dword(struct cx231xx *dev, u8 dev_addr,
- u16 saddr, u32 mask, u32 value);
-u32 cx231xx_set_field(u32 field_mask, u32 data);
-
-/*verve r/w*/
-void initGPIO(struct cx231xx *dev);
-void uninitGPIO(struct cx231xx *dev);
-/* afe related functions */
-int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count);
-int cx231xx_afe_init_channels(struct cx231xx *dev);
-int cx231xx_afe_setup_AFE_for_baseband(struct cx231xx *dev);
-int cx231xx_afe_set_input_mux(struct cx231xx *dev, u32 input_mux);
-int cx231xx_afe_set_mode(struct cx231xx *dev, enum AFE_MODE mode);
-int cx231xx_afe_update_power_control(struct cx231xx *dev,
- enum AV_MODE avmode);
-int cx231xx_afe_adjust_ref_count(struct cx231xx *dev, u32 video_input);
-
-/* i2s block related functions */
-int cx231xx_i2s_blk_initialize(struct cx231xx *dev);
-int cx231xx_i2s_blk_update_power_control(struct cx231xx *dev,
- enum AV_MODE avmode);
-int cx231xx_i2s_blk_set_audio_input(struct cx231xx *dev, u8 audio_input);
-
-/* DIF related functions */
-int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode,
- u32 function_mode, u32 standard);
-void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq,
- u8 spectral_invert, u32 mode);
-u32 cx231xx_Get_Colibri_CarrierOffset(u32 mode, u32 standerd);
-void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq,
- u8 spectral_invert, u32 mode);
-void cx231xx_Setup_AFE_for_LowIF(struct cx231xx *dev);
-void reset_s5h1432_demod(struct cx231xx *dev);
-void cx231xx_dump_HH_reg(struct cx231xx *dev);
-void update_HH_register_after_set_DIF(struct cx231xx *dev);
-void cx231xx_dump_SC_reg(struct cx231xx *dev);
-
-
-
-int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard);
-int cx231xx_tuner_pre_channel_change(struct cx231xx *dev);
-int cx231xx_tuner_post_channel_change(struct cx231xx *dev);
-
-/* video parser functions */
-u8 cx231xx_find_next_SAV_EAV(u8 *p_buffer, u32 buffer_size,
- u32 *p_bytes_used);
-u8 cx231xx_find_boundary_SAV_EAV(u8 *p_buffer, u8 *partial_buf,
- u32 *p_bytes_used);
-int cx231xx_do_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
- u8 *p_buffer, u32 bytes_to_copy);
-void cx231xx_reset_video_buffer(struct cx231xx *dev,
- struct cx231xx_dmaqueue *dma_q);
-u8 cx231xx_is_buffer_done(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q);
-u32 cx231xx_copy_video_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
- u8 *p_line, u32 length, int field_number);
-u32 cx231xx_get_video_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
- u8 sav_eav, u8 *p_buffer, u32 buffer_size);
-void cx231xx_swab(u16 *from, u16 *to, u16 len);
-
-/* Provided by cx231xx-core.c */
-
-u32 cx231xx_request_buffers(struct cx231xx *dev, u32 count);
-void cx231xx_queue_unusedframes(struct cx231xx *dev);
-void cx231xx_release_buffers(struct cx231xx *dev);
-
-/* read from control pipe */
-int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg,
- char *buf, int len);
-
-/* write to control pipe */
-int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg,
- char *buf, int len);
-int cx231xx_mode_register(struct cx231xx *dev, u16 address, u32 mode);
-
-int cx231xx_send_vendor_cmd(struct cx231xx *dev,
- struct VENDOR_REQUEST_IN *ven_req);
-int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus,
- struct cx231xx_i2c_xfer_data *req_data);
-
-/* Gpio related functions */
-int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val,
- u8 len, u8 request, u8 direction);
-int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val);
-int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val);
-int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value);
-int cx231xx_set_gpio_direction(struct cx231xx *dev, int pin_number,
- int pin_value);
-
-int cx231xx_gpio_i2c_start(struct cx231xx *dev);
-int cx231xx_gpio_i2c_end(struct cx231xx *dev);
-int cx231xx_gpio_i2c_write_byte(struct cx231xx *dev, u8 data);
-int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 *buf);
-int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev);
-int cx231xx_gpio_i2c_write_ack(struct cx231xx *dev);
-int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev);
-
-int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len);
-int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len);
-
-/* audio related functions */
-int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
- enum AUDIO_INPUT audio_input);
-
-int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type);
-int cx231xx_set_video_alternate(struct cx231xx *dev);
-int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt);
-int is_fw_load(struct cx231xx *dev);
-int cx231xx_check_fw(struct cx231xx *dev);
-int cx231xx_init_isoc(struct cx231xx *dev, int max_packets,
- int num_bufs, int max_pkt_size,
- int (*isoc_copy) (struct cx231xx *dev,
- struct urb *urb));
-int cx231xx_init_bulk(struct cx231xx *dev, int max_packets,
- int num_bufs, int max_pkt_size,
- int (*bulk_copy) (struct cx231xx *dev,
- struct urb *urb));
-void cx231xx_stop_TS1(struct cx231xx *dev);
-void cx231xx_start_TS1(struct cx231xx *dev);
-void cx231xx_uninit_isoc(struct cx231xx *dev);
-void cx231xx_uninit_bulk(struct cx231xx *dev);
-int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode);
-int cx231xx_unmute_audio(struct cx231xx *dev);
-int cx231xx_ep5_bulkout(struct cx231xx *dev, u8 *firmware, u16 size);
-void cx231xx_disable656(struct cx231xx *dev);
-void cx231xx_enable656(struct cx231xx *dev);
-int cx231xx_demod_reset(struct cx231xx *dev);
-int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio);
-
-/* Device list functions */
-void cx231xx_release_resources(struct cx231xx *dev);
-void cx231xx_release_analog_resources(struct cx231xx *dev);
-int cx231xx_register_analog_devices(struct cx231xx *dev);
-void cx231xx_remove_from_devlist(struct cx231xx *dev);
-void cx231xx_add_into_devlist(struct cx231xx *dev);
-void cx231xx_init_extension(struct cx231xx *dev);
-void cx231xx_close_extension(struct cx231xx *dev);
-
-/* hardware init functions */
-int cx231xx_dev_init(struct cx231xx *dev);
-void cx231xx_dev_uninit(struct cx231xx *dev);
-void cx231xx_config_i2c(struct cx231xx *dev);
-int cx231xx_config(struct cx231xx *dev);
-
-/* Stream control functions */
-int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask);
-int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask);
-
-int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type);
-
-/* Power control functions */
-int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode);
-int cx231xx_power_suspend(struct cx231xx *dev);
-
-/* chip specific control functions */
-int cx231xx_init_ctrl_pin_status(struct cx231xx *dev);
-int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev,
- u8 analog_or_digital);
-int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3);
-
-/* video audio decoder related functions */
-void video_mux(struct cx231xx *dev, int index);
-int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input);
-int cx231xx_set_decoder_video_input(struct cx231xx *dev, u8 pin_type, u8 input);
-int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev);
-int cx231xx_set_audio_input(struct cx231xx *dev, u8 input);
-
-/* Provided by cx231xx-video.c */
-int cx231xx_register_extension(struct cx231xx_ops *dev);
-void cx231xx_unregister_extension(struct cx231xx_ops *dev);
-void cx231xx_init_extension(struct cx231xx *dev);
-void cx231xx_close_extension(struct cx231xx *dev);
-
-/* Provided by cx231xx-cards.c */
-extern void cx231xx_pre_card_setup(struct cx231xx *dev);
-extern void cx231xx_card_setup(struct cx231xx *dev);
-extern struct cx231xx_board cx231xx_boards[];
-extern struct usb_device_id cx231xx_id_table[];
-extern const unsigned int cx231xx_bcount;
-int cx231xx_tuner_callback(void *ptr, int component, int command, int arg);
-
-/* cx23885-417.c */
-extern int cx231xx_417_register(struct cx231xx *dev);
-extern void cx231xx_417_unregister(struct cx231xx *dev);
-
-/* cx23885-input.c */
-
-#if defined(CONFIG_VIDEO_CX231XX_RC)
-int cx231xx_ir_init(struct cx231xx *dev);
-void cx231xx_ir_exit(struct cx231xx *dev);
-#else
-#define cx231xx_ir_init(dev) (0)
-#define cx231xx_ir_exit(dev) (0)
-#endif
-
-
-/* printk macros */
-
-#define cx231xx_err(fmt, arg...) do {\
- printk(KERN_ERR fmt , ##arg); } while (0)
-
-#define cx231xx_errdev(fmt, arg...) do {\
- printk(KERN_ERR "%s: "fmt,\
- dev->name , ##arg); } while (0)
-
-#define cx231xx_info(fmt, arg...) do {\
- printk(KERN_INFO "%s: "fmt,\
- dev->name , ##arg); } while (0)
-#define cx231xx_warn(fmt, arg...) do {\
- printk(KERN_WARNING "%s: "fmt,\
- dev->name , ##arg); } while (0)
-
-static inline unsigned int norm_maxw(struct cx231xx *dev)
-{
- if (dev->board.max_range_640_480)
- return 640;
- else
- return 720;
-}
-
-static inline unsigned int norm_maxh(struct cx231xx *dev)
-{
- if (dev->board.max_range_640_480)
- return 480;
- else
- return (dev->norm & V4L2_STD_625_50) ? 576 : 480;
-}
-#endif
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
deleted file mode 100644
index 103ef6bad2e..00000000000
--- a/drivers/media/video/cx2341x.c
+++ /dev/null
@@ -1,1726 +0,0 @@
-/*
- * cx2341x - generic code for cx23415/6/8 based devices
- *
- * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-
-#include <media/tuner.h>
-#include <media/cx2341x.h>
-#include <media/v4l2-common.h>
-
-MODULE_DESCRIPTION("cx23415/6/8 driver");
-MODULE_AUTHOR("Hans Verkuil");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-/********************** COMMON CODE *********************/
-
-/* definitions for audio properties bits 29-28 */
-#define CX2341X_AUDIO_ENCODING_METHOD_MPEG 0
-#define CX2341X_AUDIO_ENCODING_METHOD_AC3 1
-#define CX2341X_AUDIO_ENCODING_METHOD_LPCM 2
-
-static const char *cx2341x_get_name(u32 id)
-{
- switch (id) {
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
- return "Spatial Filter Mode";
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
- return "Spatial Filter";
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
- return "Spatial Luma Filter Type";
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
- return "Spatial Chroma Filter Type";
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
- return "Temporal Filter Mode";
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
- return "Temporal Filter";
- case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
- return "Median Filter Type";
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
- return "Median Luma Filter Maximum";
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
- return "Median Luma Filter Minimum";
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
- return "Median Chroma Filter Maximum";
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
- return "Median Chroma Filter Minimum";
- case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
- return "Insert Navigation Packets";
- }
- return NULL;
-}
-
-static const char **cx2341x_get_menu(u32 id)
-{
- static const char *cx2341x_video_spatial_filter_mode_menu[] = {
- "Manual",
- "Auto",
- NULL
- };
-
- static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
- "Off",
- "1D Horizontal",
- "1D Vertical",
- "2D H/V Separable",
- "2D Symmetric non-separable",
- NULL
- };
-
- static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
- "Off",
- "1D Horizontal",
- NULL
- };
-
- static const char *cx2341x_video_temporal_filter_mode_menu[] = {
- "Manual",
- "Auto",
- NULL
- };
-
- static const char *cx2341x_video_median_filter_type_menu[] = {
- "Off",
- "Horizontal",
- "Vertical",
- "Horizontal/Vertical",
- "Diagonal",
- NULL
- };
-
- switch (id) {
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
- return cx2341x_video_spatial_filter_mode_menu;
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
- return cx2341x_video_luma_spatial_filter_type_menu;
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
- return cx2341x_video_chroma_spatial_filter_type_menu;
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
- return cx2341x_video_temporal_filter_mode_menu;
- case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
- return cx2341x_video_median_filter_type_menu;
- }
- return NULL;
-}
-
-static void cx2341x_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
- s32 *min, s32 *max, s32 *step, s32 *def, u32 *flags)
-{
- *name = cx2341x_get_name(id);
- *flags = 0;
-
- switch (id) {
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
- *type = V4L2_CTRL_TYPE_MENU;
- *min = 0;
- *step = 0;
- break;
- case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
- *type = V4L2_CTRL_TYPE_BOOLEAN;
- *min = 0;
- *max = *step = 1;
- break;
- default:
- *type = V4L2_CTRL_TYPE_INTEGER;
- break;
- }
- switch (id) {
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
- *flags |= V4L2_CTRL_FLAG_UPDATE;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
- *flags |= V4L2_CTRL_FLAG_SLIDER;
- break;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- *flags |= V4L2_CTRL_FLAG_READ_ONLY;
- break;
- }
-}
-
-
-/********************** OLD CODE *********************/
-
-/* Must be sorted from low to high control ID! */
-const u32 cx2341x_mpeg_ctrls[] = {
- V4L2_CID_MPEG_CLASS,
- V4L2_CID_MPEG_STREAM_TYPE,
- V4L2_CID_MPEG_STREAM_VBI_FMT,
- V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
- V4L2_CID_MPEG_AUDIO_ENCODING,
- V4L2_CID_MPEG_AUDIO_L2_BITRATE,
- V4L2_CID_MPEG_AUDIO_MODE,
- V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
- V4L2_CID_MPEG_AUDIO_EMPHASIS,
- V4L2_CID_MPEG_AUDIO_CRC,
- V4L2_CID_MPEG_AUDIO_MUTE,
- V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
- V4L2_CID_MPEG_VIDEO_ENCODING,
- V4L2_CID_MPEG_VIDEO_ASPECT,
- V4L2_CID_MPEG_VIDEO_B_FRAMES,
- V4L2_CID_MPEG_VIDEO_GOP_SIZE,
- V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
- V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
- V4L2_CID_MPEG_VIDEO_BITRATE,
- V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
- V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
- V4L2_CID_MPEG_VIDEO_MUTE,
- V4L2_CID_MPEG_VIDEO_MUTE_YUV,
- V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
- V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
- V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
- V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
- V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
- V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
- V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
- V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
- V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
- V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
- V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
- V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS,
- 0
-};
-EXPORT_SYMBOL(cx2341x_mpeg_ctrls);
-
-static const struct cx2341x_mpeg_params default_params = {
- /* misc */
- .capabilities = 0,
- .port = CX2341X_PORT_MEMORY,
- .width = 720,
- .height = 480,
- .is_50hz = 0,
-
- /* stream */
- .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
- .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
- .stream_insert_nav_packets = 0,
-
- /* audio */
- .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
- .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
- .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
- .audio_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_224K,
- .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
- .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
- .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
- .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
- .audio_mute = 0,
-
- /* video */
- .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
- .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
- .video_b_frames = 2,
- .video_gop_size = 12,
- .video_gop_closure = 1,
- .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
- .video_bitrate = 6000000,
- .video_bitrate_peak = 8000000,
- .video_temporal_decimation = 0,
- .video_mute = 0,
- .video_mute_yuv = 0x008080, /* YCbCr value for black */
-
- /* encoding filters */
- .video_spatial_filter_mode =
- V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
- .video_spatial_filter = 0,
- .video_luma_spatial_filter_type =
- V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
- .video_chroma_spatial_filter_type =
- V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
- .video_temporal_filter_mode =
- V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
- .video_temporal_filter = 8,
- .video_median_filter_type =
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
- .video_luma_median_filter_top = 255,
- .video_luma_median_filter_bottom = 0,
- .video_chroma_median_filter_top = 255,
- .video_chroma_median_filter_bottom = 0,
-};
-/* Map the control ID to the correct field in the cx2341x_mpeg_params
- struct. Return -EINVAL if the ID is unknown, else return 0. */
-static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params *params,
- struct v4l2_ext_control *ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- ctrl->value = params->audio_sampling_freq;
- break;
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- ctrl->value = params->audio_encoding;
- break;
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- ctrl->value = params->audio_l2_bitrate;
- break;
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- ctrl->value = params->audio_ac3_bitrate;
- break;
- case V4L2_CID_MPEG_AUDIO_MODE:
- ctrl->value = params->audio_mode;
- break;
- case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
- ctrl->value = params->audio_mode_extension;
- break;
- case V4L2_CID_MPEG_AUDIO_EMPHASIS:
- ctrl->value = params->audio_emphasis;
- break;
- case V4L2_CID_MPEG_AUDIO_CRC:
- ctrl->value = params->audio_crc;
- break;
- case V4L2_CID_MPEG_AUDIO_MUTE:
- ctrl->value = params->audio_mute;
- break;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- ctrl->value = params->video_encoding;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- ctrl->value = params->video_aspect;
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- ctrl->value = params->video_b_frames;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- ctrl->value = params->video_gop_size;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
- ctrl->value = params->video_gop_closure;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- ctrl->value = params->video_bitrate_mode;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- ctrl->value = params->video_bitrate;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- ctrl->value = params->video_bitrate_peak;
- break;
- case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
- ctrl->value = params->video_temporal_decimation;
- break;
- case V4L2_CID_MPEG_VIDEO_MUTE:
- ctrl->value = params->video_mute;
- break;
- case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
- ctrl->value = params->video_mute_yuv;
- break;
- case V4L2_CID_MPEG_STREAM_TYPE:
- ctrl->value = params->stream_type;
- break;
- case V4L2_CID_MPEG_STREAM_VBI_FMT:
- ctrl->value = params->stream_vbi_fmt;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
- ctrl->value = params->video_spatial_filter_mode;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
- ctrl->value = params->video_spatial_filter;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
- ctrl->value = params->video_luma_spatial_filter_type;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
- ctrl->value = params->video_chroma_spatial_filter_type;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
- ctrl->value = params->video_temporal_filter_mode;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
- ctrl->value = params->video_temporal_filter;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
- ctrl->value = params->video_median_filter_type;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
- ctrl->value = params->video_luma_median_filter_top;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
- ctrl->value = params->video_luma_median_filter_bottom;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
- ctrl->value = params->video_chroma_median_filter_top;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
- ctrl->value = params->video_chroma_median_filter_bottom;
- break;
- case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
- ctrl->value = params->stream_insert_nav_packets;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/* Map the control ID to the correct field in the cx2341x_mpeg_params
- struct. Return -EINVAL if the ID is unknown, else return 0. */
-static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
- struct v4l2_ext_control *ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- if (busy)
- return -EBUSY;
- params->audio_sampling_freq = ctrl->value;
- break;
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- if (busy)
- return -EBUSY;
- if (params->capabilities & CX2341X_CAP_HAS_AC3)
- if (ctrl->value != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
- ctrl->value != V4L2_MPEG_AUDIO_ENCODING_AC3)
- return -ERANGE;
- params->audio_encoding = ctrl->value;
- break;
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- if (busy)
- return -EBUSY;
- params->audio_l2_bitrate = ctrl->value;
- break;
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- if (busy)
- return -EBUSY;
- if (!(params->capabilities & CX2341X_CAP_HAS_AC3))
- return -EINVAL;
- params->audio_ac3_bitrate = ctrl->value;
- break;
- case V4L2_CID_MPEG_AUDIO_MODE:
- params->audio_mode = ctrl->value;
- break;
- case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
- params->audio_mode_extension = ctrl->value;
- break;
- case V4L2_CID_MPEG_AUDIO_EMPHASIS:
- params->audio_emphasis = ctrl->value;
- break;
- case V4L2_CID_MPEG_AUDIO_CRC:
- params->audio_crc = ctrl->value;
- break;
- case V4L2_CID_MPEG_AUDIO_MUTE:
- params->audio_mute = ctrl->value;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- params->video_aspect = ctrl->value;
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
- int b = ctrl->value + 1;
- int gop = params->video_gop_size;
- params->video_b_frames = ctrl->value;
- params->video_gop_size = b * ((gop + b - 1) / b);
- /* Max GOP size = 34 */
- while (params->video_gop_size > 34)
- params->video_gop_size -= b;
- break;
- }
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE: {
- int b = params->video_b_frames + 1;
- int gop = ctrl->value;
- params->video_gop_size = b * ((gop + b - 1) / b);
- /* Max GOP size = 34 */
- while (params->video_gop_size > 34)
- params->video_gop_size -= b;
- ctrl->value = params->video_gop_size;
- break;
- }
- case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
- params->video_gop_closure = ctrl->value;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- if (busy)
- return -EBUSY;
- /* MPEG-1 only allows CBR */
- if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&
- ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
- return -EINVAL;
- params->video_bitrate_mode = ctrl->value;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- if (busy)
- return -EBUSY;
- params->video_bitrate = ctrl->value;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- if (busy)
- return -EBUSY;
- params->video_bitrate_peak = ctrl->value;
- break;
- case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
- params->video_temporal_decimation = ctrl->value;
- break;
- case V4L2_CID_MPEG_VIDEO_MUTE:
- params->video_mute = (ctrl->value != 0);
- break;
- case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
- params->video_mute_yuv = ctrl->value;
- break;
- case V4L2_CID_MPEG_STREAM_TYPE:
- if (busy)
- return -EBUSY;
- params->stream_type = ctrl->value;
- params->video_encoding =
- (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
- params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
- V4L2_MPEG_VIDEO_ENCODING_MPEG_1 :
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
- if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
- /* MPEG-1 implies CBR */
- params->video_bitrate_mode =
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
- break;
- case V4L2_CID_MPEG_STREAM_VBI_FMT:
- params->stream_vbi_fmt = ctrl->value;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
- params->video_spatial_filter_mode = ctrl->value;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
- params->video_spatial_filter = ctrl->value;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
- params->video_luma_spatial_filter_type = ctrl->value;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
- params->video_chroma_spatial_filter_type = ctrl->value;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
- params->video_temporal_filter_mode = ctrl->value;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
- params->video_temporal_filter = ctrl->value;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
- params->video_median_filter_type = ctrl->value;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
- params->video_luma_median_filter_top = ctrl->value;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
- params->video_luma_median_filter_bottom = ctrl->value;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
- params->video_chroma_median_filter_top = ctrl->value;
- break;
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
- params->video_chroma_median_filter_bottom = ctrl->value;
- break;
- case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
- params->stream_insert_nav_packets = ctrl->value;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl,
- s32 min, s32 max, s32 step, s32 def)
-{
- const char *name;
-
- switch (qctrl->id) {
- /* MPEG controls */
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
- case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
- case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
- cx2341x_ctrl_fill(qctrl->id, &name, &qctrl->type,
- &min, &max, &step, &def, &qctrl->flags);
- qctrl->minimum = min;
- qctrl->maximum = max;
- qctrl->step = step;
- qctrl->default_value = def;
- qctrl->reserved[0] = qctrl->reserved[1] = 0;
- strlcpy(qctrl->name, name, sizeof(qctrl->name));
- return 0;
-
- default:
- return v4l2_ctrl_query_fill(qctrl, min, max, step, def);
- }
-}
-
-int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
- struct v4l2_queryctrl *qctrl)
-{
- int err;
-
- switch (qctrl->id) {
- case V4L2_CID_MPEG_CLASS:
- return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
- case V4L2_CID_MPEG_STREAM_TYPE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
- V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1,
- V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
-
- case V4L2_CID_MPEG_STREAM_VBI_FMT:
- if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_STREAM_VBI_FMT_NONE,
- V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1,
- V4L2_MPEG_STREAM_VBI_FMT_NONE);
- return cx2341x_ctrl_query_fill(qctrl,
- V4L2_MPEG_STREAM_VBI_FMT_NONE,
- V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
- default_params.stream_vbi_fmt);
-
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
-
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- if (params->capabilities & CX2341X_CAP_HAS_AC3) {
- /*
- * The state of L2 & AC3 bitrate controls can change
- * when this control changes, but v4l2_ctrl_query_fill()
- * already sets V4L2_CTRL_FLAG_UPDATE for
- * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here.
- */
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
- V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
- default_params.audio_encoding);
- }
-
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
- default_params.audio_encoding);
-
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- err = v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_L2_BITRATE_192K,
- V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
- default_params.audio_l2_bitrate);
- if (err)
- return err;
- if (params->capabilities & CX2341X_CAP_HAS_AC3 &&
- params->audio_encoding != V4L2_MPEG_AUDIO_ENCODING_LAYER_2)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return 0;
-
- case V4L2_CID_MPEG_AUDIO_MODE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_MODE_STEREO,
- V4L2_MPEG_AUDIO_MODE_MONO, 1,
- V4L2_MPEG_AUDIO_MODE_STEREO);
-
- case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
- err = v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1,
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
- if (err == 0 &&
- params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return err;
-
- case V4L2_CID_MPEG_AUDIO_EMPHASIS:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_EMPHASIS_NONE,
- V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1,
- V4L2_MPEG_AUDIO_EMPHASIS_NONE);
-
- case V4L2_CID_MPEG_AUDIO_CRC:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_CRC_NONE,
- V4L2_MPEG_AUDIO_CRC_CRC16, 1,
- V4L2_MPEG_AUDIO_CRC_NONE);
-
- case V4L2_CID_MPEG_AUDIO_MUTE:
- return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
-
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- err = v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_AC3_BITRATE_48K,
- V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 1,
- default_params.audio_ac3_bitrate);
- if (err)
- return err;
- if (params->capabilities & CX2341X_CAP_HAS_AC3) {
- if (params->audio_encoding !=
- V4L2_MPEG_AUDIO_ENCODING_AC3)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- } else
- qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
- return 0;
-
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- /* this setting is read-only for the cx2341x since the
- V4L2_CID_MPEG_STREAM_TYPE really determines the
- MPEG-1/2 setting */
- err = v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
- if (err == 0)
- qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
- return err;
-
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_ASPECT_1x1,
- V4L2_MPEG_VIDEO_ASPECT_221x100, 1,
- V4L2_MPEG_VIDEO_ASPECT_4x3);
-
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2);
-
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
- params->is_50hz ? 12 : 15);
-
- case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
- return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
-
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- err = v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
- if (err == 0 &&
- params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return err;
-
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
-
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
- if (err == 0 &&
- params->video_bitrate_mode ==
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return err;
-
- case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
- return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
-
- case V4L2_CID_MPEG_VIDEO_MUTE:
- return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
-
- case V4L2_CID_MPEG_VIDEO_MUTE_YUV: /* Init YUV (really YCbCr) to black */
- return v4l2_ctrl_query_fill(qctrl, 0, 0xffffff, 1, 0x008080);
-
- /* CX23415/6 specific */
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
- return cx2341x_ctrl_query_fill(qctrl,
- V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
- V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
- default_params.video_spatial_filter_mode);
-
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
- cx2341x_ctrl_query_fill(qctrl, 0, 15, 1,
- default_params.video_spatial_filter);
- qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
- if (params->video_spatial_filter_mode ==
- V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return 0;
-
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
- cx2341x_ctrl_query_fill(qctrl,
- V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
- V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE,
- 1,
- default_params.video_luma_spatial_filter_type);
- if (params->video_spatial_filter_mode ==
- V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return 0;
-
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
- cx2341x_ctrl_query_fill(qctrl,
- V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
- V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
- 1,
- default_params.video_chroma_spatial_filter_type);
- if (params->video_spatial_filter_mode ==
- V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return 0;
-
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
- return cx2341x_ctrl_query_fill(qctrl,
- V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
- V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
- default_params.video_temporal_filter_mode);
-
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
- cx2341x_ctrl_query_fill(qctrl, 0, 31, 1,
- default_params.video_temporal_filter);
- qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
- if (params->video_temporal_filter_mode ==
- V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return 0;
-
- case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
- return cx2341x_ctrl_query_fill(qctrl,
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
- default_params.video_median_filter_type);
-
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
- cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
- default_params.video_luma_median_filter_top);
- qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
- if (params->video_median_filter_type ==
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return 0;
-
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
- cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
- default_params.video_luma_median_filter_bottom);
- qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
- if (params->video_median_filter_type ==
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return 0;
-
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
- cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
- default_params.video_chroma_median_filter_top);
- qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
- if (params->video_median_filter_type ==
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return 0;
-
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
- cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
- default_params.video_chroma_median_filter_bottom);
- qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
- if (params->video_median_filter_type ==
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return 0;
-
- case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
- return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1,
- default_params.stream_insert_nav_packets);
-
- default:
- return -EINVAL;
-
- }
-}
-EXPORT_SYMBOL(cx2341x_ctrl_query);
-
-const char * const *cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
-{
- static const char * const mpeg_stream_type_without_ts[] = {
- "MPEG-2 Program Stream",
- "",
- "MPEG-1 System Stream",
- "MPEG-2 DVD-compatible Stream",
- "MPEG-1 VCD-compatible Stream",
- "MPEG-2 SVCD-compatible Stream",
- NULL
- };
-
- static const char *mpeg_stream_type_with_ts[] = {
- "MPEG-2 Program Stream",
- "MPEG-2 Transport Stream",
- "MPEG-1 System Stream",
- "MPEG-2 DVD-compatible Stream",
- "MPEG-1 VCD-compatible Stream",
- "MPEG-2 SVCD-compatible Stream",
- NULL
- };
-
- static const char *mpeg_audio_encoding_l2_ac3[] = {
- "",
- "MPEG-1/2 Layer II",
- "",
- "",
- "AC-3",
- NULL
- };
-
- switch (id) {
- case V4L2_CID_MPEG_STREAM_TYPE:
- return (p->capabilities & CX2341X_CAP_HAS_TS) ?
- mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- return (p->capabilities & CX2341X_CAP_HAS_AC3) ?
- mpeg_audio_encoding_l2_ac3 : v4l2_ctrl_get_menu(id);
- case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
- case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
- return NULL;
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
- case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
- return cx2341x_get_menu(id);
- default:
- return v4l2_ctrl_get_menu(id);
- }
-}
-EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
-
-static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
-{
- params->audio_properties =
- (params->audio_sampling_freq << 0) |
- (params->audio_mode << 8) |
- (params->audio_mode_extension << 10) |
- (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
- ? 3 : params->audio_emphasis) << 12) |
- (params->audio_crc << 14);
-
- if ((params->capabilities & CX2341X_CAP_HAS_AC3) &&
- params->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) {
- params->audio_properties |=
- /* Not sure if this MPEG Layer II setting is required */
- ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
- (params->audio_ac3_bitrate << 4) |
- (CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
- } else {
- /* Assuming MPEG Layer II */
- params->audio_properties |=
- ((3 - params->audio_encoding) << 2) |
- ((1 + params->audio_l2_bitrate) << 4);
- }
-}
-
-int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
- struct v4l2_ext_controls *ctrls, unsigned int cmd)
-{
- int err = 0;
- int i;
-
- if (cmd == VIDIOC_G_EXT_CTRLS) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = cx2341x_get_ctrl(params, ctrl);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
- }
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
- struct v4l2_queryctrl qctrl;
- const char * const *menu_items = NULL;
-
- qctrl.id = ctrl->id;
- err = cx2341x_ctrl_query(params, &qctrl);
- if (err)
- break;
- if (qctrl.type == V4L2_CTRL_TYPE_MENU)
- menu_items = cx2341x_ctrl_get_menu(params, qctrl.id);
- err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
- if (err)
- break;
- err = cx2341x_set_ctrl(params, busy, ctrl);
- if (err)
- break;
- }
- if (err == 0 &&
- params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
- params->video_bitrate_peak < params->video_bitrate) {
- err = -ERANGE;
- ctrls->error_idx = ctrls->count;
- }
- if (err)
- ctrls->error_idx = i;
- else
- cx2341x_calc_audio_properties(params);
- return err;
-}
-EXPORT_SYMBOL(cx2341x_ext_ctrls);
-
-void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
-{
- *p = default_params;
- cx2341x_calc_audio_properties(p);
-}
-EXPORT_SYMBOL(cx2341x_fill_defaults);
-
-static int cx2341x_api(void *priv, cx2341x_mbox_func func,
- u32 cmd, int args, ...)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- va_list vargs;
- int i;
-
- va_start(vargs, args);
-
- for (i = 0; i < args; i++)
- data[i] = va_arg(vargs, int);
- va_end(vargs);
- return func(priv, cmd, args, 0, data);
-}
-
-#define NEQ(field) (old->field != new->field)
-
-int cx2341x_update(void *priv, cx2341x_mbox_func func,
- const struct cx2341x_mpeg_params *old,
- const struct cx2341x_mpeg_params *new)
-{
- static int mpeg_stream_type[] = {
- 0, /* MPEG-2 PS */
- 1, /* MPEG-2 TS */
- 2, /* MPEG-1 SS */
- 14, /* DVD */
- 11, /* VCD */
- 12, /* SVCD */
- };
-
- int err = 0;
- int force = (old == NULL);
- u16 temporal = new->video_temporal_filter;
-
- cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
-
- if (force || NEQ(is_50hz)) {
- err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1,
- new->is_50hz);
- if (err) return err;
- }
-
- if (force || NEQ(width) || NEQ(height) || NEQ(video_encoding)) {
- u16 w = new->width;
- u16 h = new->height;
-
- if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
- w /= 2;
- h /= 2;
- }
- err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2,
- h, w);
- if (err) return err;
- }
- if (force || NEQ(stream_type)) {
- err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1,
- mpeg_stream_type[new->stream_type]);
- if (err) return err;
- }
- if (force || NEQ(video_aspect)) {
- err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1,
- 1 + new->video_aspect);
- if (err) return err;
- }
- if (force || NEQ(video_b_frames) || NEQ(video_gop_size)) {
- err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
- new->video_gop_size, new->video_b_frames + 1);
- if (err) return err;
- }
- if (force || NEQ(video_gop_closure)) {
- err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1,
- new->video_gop_closure);
- if (err) return err;
- }
- if (force || NEQ(audio_properties)) {
- err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES,
- 1, new->audio_properties);
- if (err) return err;
- }
- if (force || NEQ(audio_mute)) {
- err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1,
- new->audio_mute);
- if (err) return err;
- }
- if (force || NEQ(video_bitrate_mode) || NEQ(video_bitrate) ||
- NEQ(video_bitrate_peak)) {
- err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
- new->video_bitrate_mode, new->video_bitrate,
- new->video_bitrate_peak / 400, 0, 0);
- if (err) return err;
- }
- if (force || NEQ(video_spatial_filter_mode) ||
- NEQ(video_temporal_filter_mode) ||
- NEQ(video_median_filter_type)) {
- err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE,
- 2, new->video_spatial_filter_mode |
- (new->video_temporal_filter_mode << 1),
- new->video_median_filter_type);
- if (err) return err;
- }
- if (force || NEQ(video_luma_median_filter_bottom) ||
- NEQ(video_luma_median_filter_top) ||
- NEQ(video_chroma_median_filter_bottom) ||
- NEQ(video_chroma_median_filter_top)) {
- err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
- new->video_luma_median_filter_bottom,
- new->video_luma_median_filter_top,
- new->video_chroma_median_filter_bottom,
- new->video_chroma_median_filter_top);
- if (err) return err;
- }
- if (force || NEQ(video_luma_spatial_filter_type) ||
- NEQ(video_chroma_spatial_filter_type)) {
- err = cx2341x_api(priv, func,
- CX2341X_ENC_SET_SPATIAL_FILTER_TYPE,
- 2, new->video_luma_spatial_filter_type,
- new->video_chroma_spatial_filter_type);
- if (err) return err;
- }
- if (force || NEQ(video_spatial_filter) ||
- old->video_temporal_filter != temporal) {
- err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS,
- 2, new->video_spatial_filter, temporal);
- if (err) return err;
- }
- if (force || NEQ(video_temporal_decimation)) {
- err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE,
- 1, new->video_temporal_decimation);
- if (err) return err;
- }
- if (force || NEQ(video_mute) ||
- (new->video_mute && NEQ(video_mute_yuv))) {
- err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1,
- new->video_mute | (new->video_mute_yuv << 8));
- if (err) return err;
- }
- if (force || NEQ(stream_insert_nav_packets)) {
- err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2,
- 7, new->stream_insert_nav_packets);
- if (err) return err;
- }
- return 0;
-}
-EXPORT_SYMBOL(cx2341x_update);
-
-static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params *p, u32 id)
-{
- const char * const *menu = cx2341x_ctrl_get_menu(p, id);
- struct v4l2_ext_control ctrl;
-
- if (menu == NULL)
- goto invalid;
- ctrl.id = id;
- if (cx2341x_get_ctrl(p, &ctrl))
- goto invalid;
- while (ctrl.value-- && *menu) menu++;
- if (*menu == NULL)
- goto invalid;
- return *menu;
-
-invalid:
- return "<invalid>";
-}
-
-void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
-{
- int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
-
- /* Stream */
- printk(KERN_INFO "%s: Stream: %s",
- prefix,
- cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
- if (p->stream_insert_nav_packets)
- printk(" (with navigation packets)");
- printk("\n");
- printk(KERN_INFO "%s: VBI Format: %s\n",
- prefix,
- cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
-
- /* Video */
- printk(KERN_INFO "%s: Video: %dx%d, %d fps%s\n",
- prefix,
- p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
- p->is_50hz ? 25 : 30,
- (p->video_mute) ? " (muted)" : "");
- printk(KERN_INFO "%s: Video: %s, %s, %s, %d",
- prefix,
- cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
- cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
- cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
- p->video_bitrate);
- if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
- printk(", Peak %d", p->video_bitrate_peak);
- printk("\n");
- printk(KERN_INFO
- "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n",
- prefix,
- p->video_gop_size, p->video_b_frames,
- p->video_gop_closure ? "" : "No ");
- if (p->video_temporal_decimation)
- printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
- prefix, p->video_temporal_decimation);
-
- /* Audio */
- printk(KERN_INFO "%s: Audio: %s, %s, %s, %s%s",
- prefix,
- cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
- cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
- cx2341x_menu_item(p,
- p->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3
- ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE
- : V4L2_CID_MPEG_AUDIO_L2_BITRATE),
- cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
- p->audio_mute ? " (muted)" : "");
- if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
- printk(", %s", cx2341x_menu_item(p,
- V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
- printk(", %s, %s\n",
- cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
- cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
-
- /* Encoding filters */
- printk(KERN_INFO "%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
- prefix,
- cx2341x_menu_item(p,
- V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
- cx2341x_menu_item(p,
- V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
- cx2341x_menu_item(p,
- V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
- p->video_spatial_filter);
-
- printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
- prefix,
- cx2341x_menu_item(p,
- V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
- p->video_temporal_filter);
- printk(KERN_INFO
- "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
- prefix,
- cx2341x_menu_item(p,
- V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
- p->video_luma_median_filter_bottom,
- p->video_luma_median_filter_top,
- p->video_chroma_median_filter_bottom,
- p->video_chroma_median_filter_top);
-}
-EXPORT_SYMBOL(cx2341x_log_status);
-
-
-
-/********************** NEW CODE *********************/
-
-static inline struct cx2341x_handler *to_cxhdl(struct v4l2_ctrl *ctrl)
-{
- return container_of(ctrl->handler, struct cx2341x_handler, hdl);
-}
-
-static int cx2341x_hdl_api(struct cx2341x_handler *hdl,
- u32 cmd, int args, ...)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- va_list vargs;
- int i;
-
- va_start(vargs, args);
-
- for (i = 0; i < args; i++)
- data[i] = va_arg(vargs, int);
- va_end(vargs);
- return hdl->func(hdl->priv, cmd, args, 0, data);
-}
-
-/* ctrl->handler->lock is held, so it is safe to access cur.val */
-static inline int cx2341x_neq(struct v4l2_ctrl *ctrl)
-{
- return ctrl && ctrl->val != ctrl->cur.val;
-}
-
-static int cx2341x_try_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct cx2341x_handler *hdl = to_cxhdl(ctrl);
- s32 val = ctrl->val;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
- /* video gop cluster */
- int b = val + 1;
- int gop = hdl->video_gop_size->val;
-
- gop = b * ((gop + b - 1) / b);
-
- /* Max GOP size = 34 */
- while (gop > 34)
- gop -= b;
- hdl->video_gop_size->val = gop;
- break;
- }
-
- case V4L2_CID_MPEG_STREAM_TYPE:
- /* stream type cluster */
- hdl->video_encoding->val =
- (hdl->stream_type->val == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
- hdl->stream_type->val == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
- V4L2_MPEG_VIDEO_ENCODING_MPEG_1 :
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
- if (hdl->video_encoding->val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
- /* MPEG-1 implies CBR */
- hdl->video_bitrate_mode->val =
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
- /* peak bitrate shall be >= normal bitrate */
- if (hdl->video_bitrate_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
- hdl->video_bitrate_peak->val < hdl->video_bitrate->val)
- hdl->video_bitrate_peak->val = hdl->video_bitrate->val;
- break;
- }
- return 0;
-}
-
-static int cx2341x_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- static const int mpeg_stream_type[] = {
- 0, /* MPEG-2 PS */
- 1, /* MPEG-2 TS */
- 2, /* MPEG-1 SS */
- 14, /* DVD */
- 11, /* VCD */
- 12, /* SVCD */
- };
- struct cx2341x_handler *hdl = to_cxhdl(ctrl);
- s32 val = ctrl->val;
- u32 props;
- int err;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_STREAM_VBI_FMT:
- if (hdl->ops && hdl->ops->s_stream_vbi_fmt)
- return hdl->ops->s_stream_vbi_fmt(hdl, val);
- return 0;
-
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- return cx2341x_hdl_api(hdl,
- CX2341X_ENC_SET_ASPECT_RATIO, 1, val + 1);
-
- case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
- return cx2341x_hdl_api(hdl, CX2341X_ENC_SET_GOP_CLOSURE, 1, val);
-
- case V4L2_CID_MPEG_AUDIO_MUTE:
- return cx2341x_hdl_api(hdl, CX2341X_ENC_MUTE_AUDIO, 1, val);
-
- case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
- return cx2341x_hdl_api(hdl,
- CX2341X_ENC_SET_FRAME_DROP_RATE, 1, val);
-
- case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
- return cx2341x_hdl_api(hdl, CX2341X_ENC_MISC, 2, 7, val);
-
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- /* audio properties cluster */
- props = (hdl->audio_sampling_freq->val << 0) |
- (hdl->audio_mode->val << 8) |
- (hdl->audio_mode_extension->val << 10) |
- (hdl->audio_crc->val << 14);
- if (hdl->audio_emphasis->val == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
- props |= 3 << 12;
- else
- props |= hdl->audio_emphasis->val << 12;
-
- if (hdl->audio_encoding->val == V4L2_MPEG_AUDIO_ENCODING_AC3) {
- props |=
-#if 1
- /* Not sure if this MPEG Layer II setting is required */
- ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
-#endif
- (hdl->audio_ac3_bitrate->val << 4) |
- (CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
- } else {
- /* Assuming MPEG Layer II */
- props |=
- ((3 - hdl->audio_encoding->val) << 2) |
- ((1 + hdl->audio_l2_bitrate->val) << 4);
- }
- err = cx2341x_hdl_api(hdl,
- CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, props);
- if (err)
- return err;
-
- hdl->audio_properties = props;
- if (hdl->audio_ac3_bitrate) {
- int is_ac3 = hdl->audio_encoding->val ==
- V4L2_MPEG_AUDIO_ENCODING_AC3;
-
- v4l2_ctrl_activate(hdl->audio_ac3_bitrate, is_ac3);
- v4l2_ctrl_activate(hdl->audio_l2_bitrate, !is_ac3);
- }
- v4l2_ctrl_activate(hdl->audio_mode_extension,
- hdl->audio_mode->val == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO);
- if (cx2341x_neq(hdl->audio_sampling_freq) &&
- hdl->ops && hdl->ops->s_audio_sampling_freq)
- return hdl->ops->s_audio_sampling_freq(hdl, hdl->audio_sampling_freq->val);
- if (cx2341x_neq(hdl->audio_mode) &&
- hdl->ops && hdl->ops->s_audio_mode)
- return hdl->ops->s_audio_mode(hdl, hdl->audio_mode->val);
- return 0;
-
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- /* video gop cluster */
- return cx2341x_hdl_api(hdl, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
- hdl->video_gop_size->val,
- hdl->video_b_frames->val + 1);
-
- case V4L2_CID_MPEG_STREAM_TYPE:
- /* stream type cluster */
- err = cx2341x_hdl_api(hdl,
- CX2341X_ENC_SET_STREAM_TYPE, 1, mpeg_stream_type[val]);
- if (err)
- return err;
-
- err = cx2341x_hdl_api(hdl, CX2341X_ENC_SET_BIT_RATE, 5,
- hdl->video_bitrate_mode->val,
- hdl->video_bitrate->val,
- hdl->video_bitrate_peak->val / 400, 0, 0);
- if (err)
- return err;
-
- v4l2_ctrl_activate(hdl->video_bitrate_mode,
- hdl->video_encoding->val != V4L2_MPEG_VIDEO_ENCODING_MPEG_1);
- v4l2_ctrl_activate(hdl->video_bitrate_peak,
- hdl->video_bitrate_mode->val != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
- if (cx2341x_neq(hdl->video_encoding) &&
- hdl->ops && hdl->ops->s_video_encoding)
- return hdl->ops->s_video_encoding(hdl, hdl->video_encoding->val);
- return 0;
-
- case V4L2_CID_MPEG_VIDEO_MUTE:
- /* video mute cluster */
- return cx2341x_hdl_api(hdl, CX2341X_ENC_MUTE_VIDEO, 1,
- hdl->video_mute->val |
- (hdl->video_mute_yuv->val << 8));
-
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: {
- int active_filter;
-
- /* video filter mode */
- err = cx2341x_hdl_api(hdl, CX2341X_ENC_SET_DNR_FILTER_MODE, 2,
- hdl->video_spatial_filter_mode->val |
- (hdl->video_temporal_filter_mode->val << 1),
- hdl->video_median_filter_type->val);
- if (err)
- return err;
-
- active_filter = hdl->video_spatial_filter_mode->val !=
- V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO;
- v4l2_ctrl_activate(hdl->video_spatial_filter, active_filter);
- v4l2_ctrl_activate(hdl->video_luma_spatial_filter_type, active_filter);
- v4l2_ctrl_activate(hdl->video_chroma_spatial_filter_type, active_filter);
- active_filter = hdl->video_temporal_filter_mode->val !=
- V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO;
- v4l2_ctrl_activate(hdl->video_temporal_filter, active_filter);
- active_filter = hdl->video_median_filter_type->val !=
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF;
- v4l2_ctrl_activate(hdl->video_luma_median_filter_bottom, active_filter);
- v4l2_ctrl_activate(hdl->video_luma_median_filter_top, active_filter);
- v4l2_ctrl_activate(hdl->video_chroma_median_filter_bottom, active_filter);
- v4l2_ctrl_activate(hdl->video_chroma_median_filter_top, active_filter);
- return 0;
- }
-
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
- /* video filter type cluster */
- return cx2341x_hdl_api(hdl,
- CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 2,
- hdl->video_luma_spatial_filter_type->val,
- hdl->video_chroma_spatial_filter_type->val);
-
- case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
- /* video filter cluster */
- return cx2341x_hdl_api(hdl, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2,
- hdl->video_spatial_filter->val,
- hdl->video_temporal_filter->val);
-
- case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
- /* video median cluster */
- return cx2341x_hdl_api(hdl, CX2341X_ENC_SET_CORING_LEVELS, 4,
- hdl->video_luma_median_filter_bottom->val,
- hdl->video_luma_median_filter_top->val,
- hdl->video_chroma_median_filter_bottom->val,
- hdl->video_chroma_median_filter_top->val);
- }
- return -EINVAL;
-}
-
-static const struct v4l2_ctrl_ops cx2341x_ops = {
- .try_ctrl = cx2341x_try_ctrl,
- .s_ctrl = cx2341x_s_ctrl,
-};
-
-static struct v4l2_ctrl *cx2341x_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
- u32 id, s32 min, s32 max, s32 step, s32 def)
-{
- struct v4l2_ctrl_config cfg;
-
- cx2341x_ctrl_fill(id, &cfg.name, &cfg.type, &min, &max, &step, &def, &cfg.flags);
- cfg.ops = &cx2341x_ops;
- cfg.id = id;
- cfg.min = min;
- cfg.max = max;
- cfg.def = def;
- if (cfg.type == V4L2_CTRL_TYPE_MENU) {
- cfg.step = 0;
- cfg.menu_skip_mask = step;
- cfg.qmenu = cx2341x_get_menu(id);
- } else {
- cfg.step = step;
- cfg.menu_skip_mask = 0;
- }
- return v4l2_ctrl_new_custom(hdl, &cfg, NULL);
-}
-
-static struct v4l2_ctrl *cx2341x_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
- u32 id, s32 min, s32 max, s32 step, s32 def)
-{
- return v4l2_ctrl_new_std(hdl, &cx2341x_ops, id, min, max, step, def);
-}
-
-static struct v4l2_ctrl *cx2341x_ctrl_new_menu(struct v4l2_ctrl_handler *hdl,
- u32 id, s32 max, s32 mask, s32 def)
-{
- return v4l2_ctrl_new_std_menu(hdl, &cx2341x_ops, id, max, mask, def);
-}
-
-int cx2341x_handler_init(struct cx2341x_handler *cxhdl,
- unsigned nr_of_controls_hint)
-{
- struct v4l2_ctrl_handler *hdl = &cxhdl->hdl;
- u32 caps = cxhdl->capabilities;
- int has_sliced_vbi = caps & CX2341X_CAP_HAS_SLICED_VBI;
- int has_ac3 = caps & CX2341X_CAP_HAS_AC3;
- int has_ts = caps & CX2341X_CAP_HAS_TS;
-
- cxhdl->width = 720;
- cxhdl->height = 480;
-
- v4l2_ctrl_handler_init(hdl, nr_of_controls_hint);
-
- /* Add controls in ascending control ID order for fastest
- insertion time. */
- cxhdl->stream_type = cx2341x_ctrl_new_menu(hdl,
- V4L2_CID_MPEG_STREAM_TYPE,
- V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, has_ts ? 0 : 2,
- V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
- cxhdl->stream_vbi_fmt = cx2341x_ctrl_new_menu(hdl,
- V4L2_CID_MPEG_STREAM_VBI_FMT,
- V4L2_MPEG_STREAM_VBI_FMT_IVTV, has_sliced_vbi ? 0 : 2,
- V4L2_MPEG_STREAM_VBI_FMT_NONE);
- cxhdl->audio_sampling_freq = cx2341x_ctrl_new_menu(hdl,
- V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 0,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
- cxhdl->audio_encoding = cx2341x_ctrl_new_menu(hdl,
- V4L2_CID_MPEG_AUDIO_ENCODING,
- V4L2_MPEG_AUDIO_ENCODING_AC3, has_ac3 ? ~0x12 : ~0x2,
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
- cxhdl->audio_l2_bitrate = cx2341x_ctrl_new_menu(hdl,
- V4L2_CID_MPEG_AUDIO_L2_BITRATE,
- V4L2_MPEG_AUDIO_L2_BITRATE_384K, 0x1ff,
- V4L2_MPEG_AUDIO_L2_BITRATE_224K);
- cxhdl->audio_mode = cx2341x_ctrl_new_menu(hdl,
- V4L2_CID_MPEG_AUDIO_MODE,
- V4L2_MPEG_AUDIO_MODE_MONO, 0,
- V4L2_MPEG_AUDIO_MODE_STEREO);
- cxhdl->audio_mode_extension = cx2341x_ctrl_new_menu(hdl,
- V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 0,
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
- cxhdl->audio_emphasis = cx2341x_ctrl_new_menu(hdl,
- V4L2_CID_MPEG_AUDIO_EMPHASIS,
- V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 0,
- V4L2_MPEG_AUDIO_EMPHASIS_NONE);
- cxhdl->audio_crc = cx2341x_ctrl_new_menu(hdl,
- V4L2_CID_MPEG_AUDIO_CRC,
- V4L2_MPEG_AUDIO_CRC_CRC16, 0,
- V4L2_MPEG_AUDIO_CRC_NONE);
-
- cx2341x_ctrl_new_std(hdl, V4L2_CID_MPEG_AUDIO_MUTE, 0, 1, 1, 0);
- if (has_ac3)
- cxhdl->audio_ac3_bitrate = cx2341x_ctrl_new_menu(hdl,
- V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
- V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 0x03,
- V4L2_MPEG_AUDIO_AC3_BITRATE_224K);
- cxhdl->video_encoding = cx2341x_ctrl_new_menu(hdl,
- V4L2_CID_MPEG_VIDEO_ENCODING,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 0,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
- cx2341x_ctrl_new_menu(hdl,
- V4L2_CID_MPEG_VIDEO_ASPECT,
- V4L2_MPEG_VIDEO_ASPECT_221x100, 0,
- V4L2_MPEG_VIDEO_ASPECT_4x3);
- cxhdl->video_b_frames = cx2341x_ctrl_new_std(hdl,
- V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 33, 1, 2);
- cxhdl->video_gop_size = cx2341x_ctrl_new_std(hdl,
- V4L2_CID_MPEG_VIDEO_GOP_SIZE,
- 1, 34, 1, cxhdl->is_50hz ? 12 : 15);
- cx2341x_ctrl_new_std(hdl, V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 1);
- cxhdl->video_bitrate_mode = cx2341x_ctrl_new_menu(hdl,
- V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
- cxhdl->video_bitrate = cx2341x_ctrl_new_std(hdl,
- V4L2_CID_MPEG_VIDEO_BITRATE,
- 0, 27000000, 1, 6000000);
- cxhdl->video_bitrate_peak = cx2341x_ctrl_new_std(hdl,
- V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
- 0, 27000000, 1, 8000000);
- cx2341x_ctrl_new_std(hdl,
- V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION, 0, 255, 1, 0);
- cxhdl->video_mute = cx2341x_ctrl_new_std(hdl,
- V4L2_CID_MPEG_VIDEO_MUTE, 0, 1, 1, 0);
- cxhdl->video_mute_yuv = cx2341x_ctrl_new_std(hdl,
- V4L2_CID_MPEG_VIDEO_MUTE_YUV, 0, 0xffffff, 1, 0x008080);
-
- /* CX23415/6 specific */
- cxhdl->video_spatial_filter_mode = cx2341x_ctrl_new_custom(hdl,
- V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
- V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
- V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 0,
- V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL);
- cxhdl->video_spatial_filter = cx2341x_ctrl_new_custom(hdl,
- V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
- 0, 15, 1, 0);
- cxhdl->video_luma_spatial_filter_type = cx2341x_ctrl_new_custom(hdl,
- V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
- V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
- V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE,
- 0,
- V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR);
- cxhdl->video_chroma_spatial_filter_type = cx2341x_ctrl_new_custom(hdl,
- V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
- V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
- V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
- 0,
- V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR);
- cxhdl->video_temporal_filter_mode = cx2341x_ctrl_new_custom(hdl,
- V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
- V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
- V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO,
- 0,
- V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL);
- cxhdl->video_temporal_filter = cx2341x_ctrl_new_custom(hdl,
- V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
- 0, 31, 1, 8);
- cxhdl->video_median_filter_type = cx2341x_ctrl_new_custom(hdl,
- V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG,
- 0,
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF);
- cxhdl->video_luma_median_filter_bottom = cx2341x_ctrl_new_custom(hdl,
- V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
- 0, 255, 1, 0);
- cxhdl->video_luma_median_filter_top = cx2341x_ctrl_new_custom(hdl,
- V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
- 0, 255, 1, 255);
- cxhdl->video_chroma_median_filter_bottom = cx2341x_ctrl_new_custom(hdl,
- V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
- 0, 255, 1, 0);
- cxhdl->video_chroma_median_filter_top = cx2341x_ctrl_new_custom(hdl,
- V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
- 0, 255, 1, 255);
- cx2341x_ctrl_new_custom(hdl, V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS,
- 0, 1, 1, 0);
-
- if (hdl->error) {
- int err = hdl->error;
-
- v4l2_ctrl_handler_free(hdl);
- return err;
- }
-
- v4l2_ctrl_cluster(8, &cxhdl->audio_sampling_freq);
- v4l2_ctrl_cluster(2, &cxhdl->video_b_frames);
- v4l2_ctrl_cluster(5, &cxhdl->stream_type);
- v4l2_ctrl_cluster(2, &cxhdl->video_mute);
- v4l2_ctrl_cluster(3, &cxhdl->video_spatial_filter_mode);
- v4l2_ctrl_cluster(2, &cxhdl->video_luma_spatial_filter_type);
- v4l2_ctrl_cluster(2, &cxhdl->video_spatial_filter);
- v4l2_ctrl_cluster(4, &cxhdl->video_luma_median_filter_top);
-
- return 0;
-}
-EXPORT_SYMBOL(cx2341x_handler_init);
-
-void cx2341x_handler_set_50hz(struct cx2341x_handler *cxhdl, int is_50hz)
-{
- cxhdl->is_50hz = is_50hz;
- cxhdl->video_gop_size->default_value = cxhdl->is_50hz ? 12 : 15;
-}
-EXPORT_SYMBOL(cx2341x_handler_set_50hz);
-
-int cx2341x_handler_setup(struct cx2341x_handler *cxhdl)
-{
- int h = cxhdl->height;
- int w = cxhdl->width;
- int err;
-
- err = cx2341x_hdl_api(cxhdl, CX2341X_ENC_SET_OUTPUT_PORT, 2, cxhdl->port, 0);
- if (err)
- return err;
- err = cx2341x_hdl_api(cxhdl, CX2341X_ENC_SET_FRAME_RATE, 1, cxhdl->is_50hz);
- if (err)
- return err;
-
- if (v4l2_ctrl_g_ctrl(cxhdl->video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
- w /= 2;
- h /= 2;
- }
- err = cx2341x_hdl_api(cxhdl, CX2341X_ENC_SET_FRAME_SIZE, 2, h, w);
- if (err)
- return err;
- return v4l2_ctrl_handler_setup(&cxhdl->hdl);
-}
-EXPORT_SYMBOL(cx2341x_handler_setup);
-
-void cx2341x_handler_set_busy(struct cx2341x_handler *cxhdl, int busy)
-{
- v4l2_ctrl_grab(cxhdl->audio_sampling_freq, busy);
- v4l2_ctrl_grab(cxhdl->audio_encoding, busy);
- v4l2_ctrl_grab(cxhdl->audio_l2_bitrate, busy);
- v4l2_ctrl_grab(cxhdl->audio_ac3_bitrate, busy);
- v4l2_ctrl_grab(cxhdl->stream_vbi_fmt, busy);
- v4l2_ctrl_grab(cxhdl->stream_type, busy);
- v4l2_ctrl_grab(cxhdl->video_bitrate_mode, busy);
- v4l2_ctrl_grab(cxhdl->video_bitrate, busy);
- v4l2_ctrl_grab(cxhdl->video_bitrate_peak, busy);
-}
-EXPORT_SYMBOL(cx2341x_handler_set_busy);
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
deleted file mode 100644
index b391e9bda87..00000000000
--- a/drivers/media/video/cx23885/Kconfig
+++ /dev/null
@@ -1,46 +0,0 @@
-config VIDEO_CX23885
- tristate "Conexant cx23885 (2388x successor) support"
- depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT && SND
- select SND_PCM
- select I2C_ALGOBIT
- select VIDEO_BTCX
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- depends on RC_CORE
- select VIDEOBUF_DVB
- select VIDEOBUF_DMA_SG
- select VIDEO_CX25840
- select VIDEO_CX2341X
- select DVB_DIB7000P if !DVB_FE_CUSTOMISE
- select DVB_S5H1409 if !DVB_FE_CUSTOMISE
- select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select DVB_LGDT330X if !DVB_FE_CUSTOMISE
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select DVB_TDA10048 if !DVB_FE_CUSTOMISE
- select DVB_LNBP21 if !DVB_FE_CUSTOMISE
- select DVB_STV6110 if !DVB_FE_CUSTOMISE
- select DVB_CX24116 if !DVB_FE_CUSTOMISE
- select DVB_STV0900 if !DVB_FE_CUSTOMISE
- select DVB_DS3000 if !DVB_FE_CUSTOMISE
- select DVB_STV0367 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
- ---help---
- This is a video4linux driver for Conexant 23885 based
- TV cards.
-
- To compile this driver as a module, choose M here: the
- module will be called cx23885
-
-config MEDIA_ALTERA_CI
- tristate "Altera FPGA based CI module"
- depends on VIDEO_CX23885 && DVB_CORE
- select ALTERA_STAPL
- ---help---
- An Altera FPGA CI module for NetUP Dual DVB-T/C RF CI card.
-
- To compile this driver as a module, choose M here: the
- module will be called altera-ci
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
deleted file mode 100644
index f81f2796a0f..00000000000
--- a/drivers/media/video/cx23885/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \
- cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \
- cx23885-ioctl.o cx23885-ir.o cx23885-av.o cx23885-input.o \
- cx23888-ir.o netup-init.o cimax2.o netup-eeprom.o \
- cx23885-f300.o cx23885-alsa.o
-
-obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
-obj-$(CONFIG_MEDIA_ALTERA_CI) += altera-ci.o
-
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
-
-ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/cx23885/altera-ci.c b/drivers/media/video/cx23885/altera-ci.c
deleted file mode 100644
index 1fa8927f0d3..00000000000
--- a/drivers/media/video/cx23885/altera-ci.c
+++ /dev/null
@@ -1,837 +0,0 @@
-/*
- * altera-ci.c
- *
- * CI driver in conjunction with NetUp Dual DVB-T/C RF CI card
- *
- * Copyright (C) 2010,2011 NetUP Inc.
- * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * currently cx23885 GPIO's used.
- * GPIO-0 ~INT in
- * GPIO-1 TMS out
- * GPIO-2 ~reset chips out
- * GPIO-3 to GPIO-10 data/addr for CA in/out
- * GPIO-11 ~CS out
- * GPIO-12 AD_RG out
- * GPIO-13 ~WR out
- * GPIO-14 ~RD out
- * GPIO-15 ~RDY in
- * GPIO-16 TCK out
- * GPIO-17 TDO in
- * GPIO-18 TDI out
- */
-/*
- * Bit definitions for MC417_RWD and MC417_OEN registers
- * bits 31-16
- * +-----------+
- * | Reserved |
- * +-----------+
- * bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | TDI | TDO | TCK | RDY# | #RD | #WR | AD_RG | #CS |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | DATA7| DATA6| DATA5| DATA4| DATA3| DATA2| DATA1| DATA0|
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- */
-#include <media/videobuf-dma-sg.h>
-#include <media/videobuf-dvb.h>
-#include "altera-ci.h"
-#include "dvb_ca_en50221.h"
-
-/* FPGA regs */
-#define NETUP_CI_INT_CTRL 0x00
-#define NETUP_CI_BUSCTRL2 0x01
-#define NETUP_CI_ADDR0 0x04
-#define NETUP_CI_ADDR1 0x05
-#define NETUP_CI_DATA 0x06
-#define NETUP_CI_BUSCTRL 0x07
-#define NETUP_CI_PID_ADDR0 0x08
-#define NETUP_CI_PID_ADDR1 0x09
-#define NETUP_CI_PID_DATA 0x0a
-#define NETUP_CI_TSA_DIV 0x0c
-#define NETUP_CI_TSB_DIV 0x0d
-#define NETUP_CI_REVISION 0x0f
-
-/* const for ci op */
-#define NETUP_CI_FLG_CTL 1
-#define NETUP_CI_FLG_RD 1
-#define NETUP_CI_FLG_AD 1
-
-static unsigned int ci_dbg;
-module_param(ci_dbg, int, 0644);
-MODULE_PARM_DESC(ci_dbg, "Enable CI debugging");
-
-static unsigned int pid_dbg;
-module_param(pid_dbg, int, 0644);
-MODULE_PARM_DESC(pid_dbg, "Enable PID filtering debugging");
-
-MODULE_DESCRIPTION("altera FPGA CI module");
-MODULE_AUTHOR("Igor M. Liplianin <liplianin@netup.ru>");
-MODULE_LICENSE("GPL");
-
-#define ci_dbg_print(args...) \
- do { \
- if (ci_dbg) \
- printk(KERN_DEBUG args); \
- } while (0)
-
-#define pid_dbg_print(args...) \
- do { \
- if (pid_dbg) \
- printk(KERN_DEBUG args); \
- } while (0)
-
-struct altera_ci_state;
-struct netup_hw_pid_filter;
-
-struct fpga_internal {
- void *dev;
- struct mutex fpga_mutex;/* two CI's on the same fpga */
- struct netup_hw_pid_filter *pid_filt[2];
- struct altera_ci_state *state[2];
- struct work_struct work;
- int (*fpga_rw) (void *dev, int flag, int data, int rw);
- int cis_used;
- int filts_used;
- int strt_wrk;
-};
-
-/* stores all private variables for communication with CI */
-struct altera_ci_state {
- struct fpga_internal *internal;
- struct dvb_ca_en50221 ca;
- int status;
- int nr;
-};
-
-/* stores all private variables for hardware pid filtering */
-struct netup_hw_pid_filter {
- struct fpga_internal *internal;
- struct dvb_demux *demux;
- /* save old functions */
- int (*start_feed)(struct dvb_demux_feed *feed);
- int (*stop_feed)(struct dvb_demux_feed *feed);
-
- int status;
- int nr;
-};
-
-/* internal params node */
-struct fpga_inode {
- /* pointer for internal params, one for each pair of CI's */
- struct fpga_internal *internal;
- struct fpga_inode *next_inode;
-};
-
-/* first internal params */
-static struct fpga_inode *fpga_first_inode;
-
-/* find chip by dev */
-static struct fpga_inode *find_inode(void *dev)
-{
- struct fpga_inode *temp_chip = fpga_first_inode;
-
- if (temp_chip == NULL)
- return temp_chip;
-
- /*
- Search for the last fpga CI chip or
- find it by dev */
- while ((temp_chip != NULL) &&
- (temp_chip->internal->dev != dev))
- temp_chip = temp_chip->next_inode;
-
- return temp_chip;
-}
-/* check demux */
-static struct fpga_internal *check_filter(struct fpga_internal *temp_int,
- void *demux_dev, int filt_nr)
-{
- if (temp_int == NULL)
- return NULL;
-
- if ((temp_int->pid_filt[filt_nr]) == NULL)
- return NULL;
-
- if (temp_int->pid_filt[filt_nr]->demux == demux_dev)
- return temp_int;
-
- return NULL;
-}
-
-/* find chip by demux */
-static struct fpga_inode *find_dinode(void *demux_dev)
-{
- struct fpga_inode *temp_chip = fpga_first_inode;
- struct fpga_internal *temp_int;
-
- /*
- * Search of the last fpga CI chip or
- * find it by demux
- */
- while (temp_chip != NULL) {
- if (temp_chip->internal != NULL) {
- temp_int = temp_chip->internal;
- if (check_filter(temp_int, demux_dev, 0))
- break;
- if (check_filter(temp_int, demux_dev, 1))
- break;
- }
-
- temp_chip = temp_chip->next_inode;
- }
-
- return temp_chip;
-}
-
-/* deallocating chip */
-static void remove_inode(struct fpga_internal *internal)
-{
- struct fpga_inode *prev_node = fpga_first_inode;
- struct fpga_inode *del_node = find_inode(internal->dev);
-
- if (del_node != NULL) {
- if (del_node == fpga_first_inode) {
- fpga_first_inode = del_node->next_inode;
- } else {
- while (prev_node->next_inode != del_node)
- prev_node = prev_node->next_inode;
-
- if (del_node->next_inode == NULL)
- prev_node->next_inode = NULL;
- else
- prev_node->next_inode =
- prev_node->next_inode->next_inode;
- }
-
- kfree(del_node);
- }
-}
-
-/* allocating new chip */
-static struct fpga_inode *append_internal(struct fpga_internal *internal)
-{
- struct fpga_inode *new_node = fpga_first_inode;
-
- if (new_node == NULL) {
- new_node = kmalloc(sizeof(struct fpga_inode), GFP_KERNEL);
- fpga_first_inode = new_node;
- } else {
- while (new_node->next_inode != NULL)
- new_node = new_node->next_inode;
-
- new_node->next_inode =
- kmalloc(sizeof(struct fpga_inode), GFP_KERNEL);
- if (new_node->next_inode != NULL)
- new_node = new_node->next_inode;
- else
- new_node = NULL;
- }
-
- if (new_node != NULL) {
- new_node->internal = internal;
- new_node->next_inode = NULL;
- }
-
- return new_node;
-}
-
-static int netup_fpga_op_rw(struct fpga_internal *inter, int addr,
- u8 val, u8 read)
-{
- inter->fpga_rw(inter->dev, NETUP_CI_FLG_AD, addr, 0);
- return inter->fpga_rw(inter->dev, 0, val, read);
-}
-
-/* flag - mem/io, read - read/write */
-int altera_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
- u8 flag, u8 read, int addr, u8 val)
-{
-
- struct altera_ci_state *state = en50221->data;
- struct fpga_internal *inter = state->internal;
-
- u8 store;
- int mem = 0;
-
- if (0 != slot)
- return -EINVAL;
-
- mutex_lock(&inter->fpga_mutex);
-
- netup_fpga_op_rw(inter, NETUP_CI_ADDR0, ((addr << 1) & 0xfe), 0);
- netup_fpga_op_rw(inter, NETUP_CI_ADDR1, ((addr >> 7) & 0x7f), 0);
- store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
-
- store &= 0x0f;
- store |= ((state->nr << 7) | (flag << 6));
-
- netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, store, 0);
- mem = netup_fpga_op_rw(inter, NETUP_CI_DATA, val, read);
-
- mutex_unlock(&inter->fpga_mutex);
-
- ci_dbg_print("%s: %s: addr=[0x%02x], %s=%x\n", __func__,
- (read) ? "read" : "write", addr,
- (flag == NETUP_CI_FLG_CTL) ? "ctl" : "mem",
- (read) ? mem : val);
-
- return mem;
-}
-
-int altera_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
- int slot, int addr)
-{
- return altera_ci_op_cam(en50221, slot, 0, NETUP_CI_FLG_RD, addr, 0);
-}
-
-int altera_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
- int slot, int addr, u8 data)
-{
- return altera_ci_op_cam(en50221, slot, 0, 0, addr, data);
-}
-
-int altera_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
-{
- return altera_ci_op_cam(en50221, slot, NETUP_CI_FLG_CTL,
- NETUP_CI_FLG_RD, addr, 0);
-}
-
-int altera_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot,
- u8 addr, u8 data)
-{
- return altera_ci_op_cam(en50221, slot, NETUP_CI_FLG_CTL, 0, addr, data);
-}
-
-int altera_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
-{
- struct altera_ci_state *state = en50221->data;
- struct fpga_internal *inter = state->internal;
- /* reasonable timeout for CI reset is 10 seconds */
- unsigned long t_out = jiffies + msecs_to_jiffies(9999);
- int ret;
-
- ci_dbg_print("%s\n", __func__);
-
- if (0 != slot)
- return -EINVAL;
-
- mutex_lock(&inter->fpga_mutex);
-
- ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
- netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL,
- (ret & 0xcf) | (1 << (5 - state->nr)), 0);
-
- mutex_unlock(&inter->fpga_mutex);
-
- for (;;) {
- mdelay(50);
-
- mutex_lock(&inter->fpga_mutex);
-
- ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL,
- 0, NETUP_CI_FLG_RD);
- mutex_unlock(&inter->fpga_mutex);
-
- if ((ret & (1 << (5 - state->nr))) == 0)
- break;
- if (time_after(jiffies, t_out))
- break;
- }
-
-
- ci_dbg_print("%s: %d msecs\n", __func__,
- jiffies_to_msecs(jiffies + msecs_to_jiffies(9999) - t_out));
-
- return 0;
-}
-
-int altera_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
-{
- /* not implemented */
- return 0;
-}
-
-int altera_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot)
-{
- struct altera_ci_state *state = en50221->data;
- struct fpga_internal *inter = state->internal;
- int ret;
-
- ci_dbg_print("%s\n", __func__);
-
- if (0 != slot)
- return -EINVAL;
-
- mutex_lock(&inter->fpga_mutex);
-
- ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
- netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL,
- (ret & 0x0f) | (1 << (3 - state->nr)), 0);
-
- mutex_unlock(&inter->fpga_mutex);
-
- return 0;
-}
-
-/* work handler */
-static void netup_read_ci_status(struct work_struct *work)
-{
- struct fpga_internal *inter =
- container_of(work, struct fpga_internal, work);
- int ret;
-
- ci_dbg_print("%s\n", __func__);
-
- mutex_lock(&inter->fpga_mutex);
- /* ack' irq */
- ret = netup_fpga_op_rw(inter, NETUP_CI_INT_CTRL, 0, NETUP_CI_FLG_RD);
- ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
-
- mutex_unlock(&inter->fpga_mutex);
-
- if (inter->state[1] != NULL) {
- inter->state[1]->status =
- ((ret & 1) == 0 ?
- DVB_CA_EN50221_POLL_CAM_PRESENT |
- DVB_CA_EN50221_POLL_CAM_READY : 0);
- ci_dbg_print("%s: setting CI[1] status = 0x%x\n",
- __func__, inter->state[1]->status);
- };
-
- if (inter->state[0] != NULL) {
- inter->state[0]->status =
- ((ret & 2) == 0 ?
- DVB_CA_EN50221_POLL_CAM_PRESENT |
- DVB_CA_EN50221_POLL_CAM_READY : 0);
- ci_dbg_print("%s: setting CI[0] status = 0x%x\n",
- __func__, inter->state[0]->status);
- };
-}
-
-/* CI irq handler */
-int altera_ci_irq(void *dev)
-{
- struct fpga_inode *temp_int = NULL;
- struct fpga_internal *inter = NULL;
-
- ci_dbg_print("%s\n", __func__);
-
- if (dev != NULL) {
- temp_int = find_inode(dev);
- if (temp_int != NULL) {
- inter = temp_int->internal;
- schedule_work(&inter->work);
- }
- }
-
- return 1;
-}
-EXPORT_SYMBOL(altera_ci_irq);
-
-int altera_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot,
- int open)
-{
- struct altera_ci_state *state = en50221->data;
-
- if (0 != slot)
- return -EINVAL;
-
- return state->status;
-}
-
-void altera_hw_filt_release(void *main_dev, int filt_nr)
-{
- struct fpga_inode *temp_int = find_inode(main_dev);
- struct netup_hw_pid_filter *pid_filt = NULL;
-
- ci_dbg_print("%s\n", __func__);
-
- if (temp_int != NULL) {
- pid_filt = temp_int->internal->pid_filt[filt_nr - 1];
- /* stored old feed controls */
- pid_filt->demux->start_feed = pid_filt->start_feed;
- pid_filt->demux->stop_feed = pid_filt->stop_feed;
-
- if (((--(temp_int->internal->filts_used)) <= 0) &&
- ((temp_int->internal->cis_used) <= 0)) {
-
- ci_dbg_print("%s: Actually removing\n", __func__);
-
- remove_inode(temp_int->internal);
- kfree(pid_filt->internal);
- }
-
- kfree(pid_filt);
-
- }
-
-}
-EXPORT_SYMBOL(altera_hw_filt_release);
-
-void altera_ci_release(void *dev, int ci_nr)
-{
- struct fpga_inode *temp_int = find_inode(dev);
- struct altera_ci_state *state = NULL;
-
- ci_dbg_print("%s\n", __func__);
-
- if (temp_int != NULL) {
- state = temp_int->internal->state[ci_nr - 1];
- altera_hw_filt_release(dev, ci_nr);
-
-
- if (((temp_int->internal->filts_used) <= 0) &&
- ((--(temp_int->internal->cis_used)) <= 0)) {
-
- ci_dbg_print("%s: Actually removing\n", __func__);
-
- remove_inode(temp_int->internal);
- kfree(state->internal);
- }
-
- if (state != NULL) {
- if (state->ca.data != NULL)
- dvb_ca_en50221_release(&state->ca);
-
- kfree(state);
- }
- }
-
-}
-EXPORT_SYMBOL(altera_ci_release);
-
-static void altera_pid_control(struct netup_hw_pid_filter *pid_filt,
- u16 pid, int onoff)
-{
- struct fpga_internal *inter = pid_filt->internal;
- u8 store = 0;
-
- /* pid 0-0x1f always enabled, don't touch them */
- if ((pid == 0x2000) || (pid < 0x20))
- return;
-
- mutex_lock(&inter->fpga_mutex);
-
- netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR0, (pid >> 3) & 0xff, 0);
- netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR1,
- ((pid >> 11) & 0x03) | (pid_filt->nr << 2), 0);
-
- store = netup_fpga_op_rw(inter, NETUP_CI_PID_DATA, 0, NETUP_CI_FLG_RD);
-
- if (onoff)/* 0 - on, 1 - off */
- store |= (1 << (pid & 7));
- else
- store &= ~(1 << (pid & 7));
-
- netup_fpga_op_rw(inter, NETUP_CI_PID_DATA, store, 0);
-
- mutex_unlock(&inter->fpga_mutex);
-
- pid_dbg_print("%s: (%d) set pid: %5d 0x%04x '%s'\n", __func__,
- pid_filt->nr, pid, pid, onoff ? "off" : "on");
-}
-
-static void altera_toggle_fullts_streaming(struct netup_hw_pid_filter *pid_filt,
- int filt_nr, int onoff)
-{
- struct fpga_internal *inter = pid_filt->internal;
- u8 store = 0;
- int i;
-
- pid_dbg_print("%s: pid_filt->nr[%d] now %s\n", __func__, pid_filt->nr,
- onoff ? "off" : "on");
-
- if (onoff)/* 0 - on, 1 - off */
- store = 0xff;/* ignore pid */
- else
- store = 0;/* enable pid */
-
- mutex_lock(&inter->fpga_mutex);
-
- for (i = 0; i < 1024; i++) {
- netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR0, i & 0xff, 0);
-
- netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR1,
- ((i >> 8) & 0x03) | (pid_filt->nr << 2), 0);
- /* pid 0-0x1f always enabled */
- netup_fpga_op_rw(inter, NETUP_CI_PID_DATA,
- (i > 3 ? store : 0), 0);
- }
-
- mutex_unlock(&inter->fpga_mutex);
-}
-
-int altera_pid_feed_control(void *demux_dev, int filt_nr,
- struct dvb_demux_feed *feed, int onoff)
-{
- struct fpga_inode *temp_int = find_dinode(demux_dev);
- struct fpga_internal *inter = temp_int->internal;
- struct netup_hw_pid_filter *pid_filt = inter->pid_filt[filt_nr - 1];
-
- altera_pid_control(pid_filt, feed->pid, onoff ? 0 : 1);
- /* call old feed proc's */
- if (onoff)
- pid_filt->start_feed(feed);
- else
- pid_filt->stop_feed(feed);
-
- if (feed->pid == 0x2000)
- altera_toggle_fullts_streaming(pid_filt, filt_nr,
- onoff ? 0 : 1);
-
- return 0;
-}
-EXPORT_SYMBOL(altera_pid_feed_control);
-
-int altera_ci_start_feed(struct dvb_demux_feed *feed, int num)
-{
- altera_pid_feed_control(feed->demux, num, feed, 1);
-
- return 0;
-}
-
-int altera_ci_stop_feed(struct dvb_demux_feed *feed, int num)
-{
- altera_pid_feed_control(feed->demux, num, feed, 0);
-
- return 0;
-}
-
-int altera_ci_start_feed_1(struct dvb_demux_feed *feed)
-{
- return altera_ci_start_feed(feed, 1);
-}
-
-int altera_ci_stop_feed_1(struct dvb_demux_feed *feed)
-{
- return altera_ci_stop_feed(feed, 1);
-}
-
-int altera_ci_start_feed_2(struct dvb_demux_feed *feed)
-{
- return altera_ci_start_feed(feed, 2);
-}
-
-int altera_ci_stop_feed_2(struct dvb_demux_feed *feed)
-{
- return altera_ci_stop_feed(feed, 2);
-}
-
-int altera_hw_filt_init(struct altera_ci_config *config, int hw_filt_nr)
-{
- struct netup_hw_pid_filter *pid_filt = NULL;
- struct fpga_inode *temp_int = find_inode(config->dev);
- struct fpga_internal *inter = NULL;
- int ret = 0;
-
- pid_filt = kzalloc(sizeof(struct netup_hw_pid_filter), GFP_KERNEL);
-
- ci_dbg_print("%s\n", __func__);
-
- if (!pid_filt) {
- ret = -ENOMEM;
- goto err;
- }
-
- if (temp_int != NULL) {
- inter = temp_int->internal;
- (inter->filts_used)++;
- ci_dbg_print("%s: Find Internal Structure!\n", __func__);
- } else {
- inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL);
- if (!inter) {
- ret = -ENOMEM;
- goto err;
- }
-
- temp_int = append_internal(inter);
- inter->filts_used = 1;
- inter->dev = config->dev;
- inter->fpga_rw = config->fpga_rw;
- mutex_init(&inter->fpga_mutex);
- inter->strt_wrk = 1;
- ci_dbg_print("%s: Create New Internal Structure!\n", __func__);
- }
-
- ci_dbg_print("%s: setting hw pid filter = %p for ci = %d\n", __func__,
- pid_filt, hw_filt_nr - 1);
- inter->pid_filt[hw_filt_nr - 1] = pid_filt;
- pid_filt->demux = config->demux;
- pid_filt->internal = inter;
- pid_filt->nr = hw_filt_nr - 1;
- /* store old feed controls */
- pid_filt->start_feed = config->demux->start_feed;
- pid_filt->stop_feed = config->demux->stop_feed;
- /* replace with new feed controls */
- if (hw_filt_nr == 1) {
- pid_filt->demux->start_feed = altera_ci_start_feed_1;
- pid_filt->demux->stop_feed = altera_ci_stop_feed_1;
- } else if (hw_filt_nr == 2) {
- pid_filt->demux->start_feed = altera_ci_start_feed_2;
- pid_filt->demux->stop_feed = altera_ci_stop_feed_2;
- }
-
- altera_toggle_fullts_streaming(pid_filt, 0, 1);
-
- return 0;
-err:
- ci_dbg_print("%s: Can't init hardware filter: Error %d\n",
- __func__, ret);
-
- kfree(pid_filt);
-
- return ret;
-}
-EXPORT_SYMBOL(altera_hw_filt_init);
-
-int altera_ci_init(struct altera_ci_config *config, int ci_nr)
-{
- struct altera_ci_state *state;
- struct fpga_inode *temp_int = find_inode(config->dev);
- struct fpga_internal *inter = NULL;
- int ret = 0;
- u8 store = 0;
-
- state = kzalloc(sizeof(struct altera_ci_state), GFP_KERNEL);
-
- ci_dbg_print("%s\n", __func__);
-
- if (!state) {
- ret = -ENOMEM;
- goto err;
- }
-
- if (temp_int != NULL) {
- inter = temp_int->internal;
- (inter->cis_used)++;
- ci_dbg_print("%s: Find Internal Structure!\n", __func__);
- } else {
- inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL);
- if (!inter) {
- ret = -ENOMEM;
- goto err;
- }
-
- temp_int = append_internal(inter);
- inter->cis_used = 1;
- inter->dev = config->dev;
- inter->fpga_rw = config->fpga_rw;
- mutex_init(&inter->fpga_mutex);
- inter->strt_wrk = 1;
- ci_dbg_print("%s: Create New Internal Structure!\n", __func__);
- }
-
- ci_dbg_print("%s: setting state = %p for ci = %d\n", __func__,
- state, ci_nr - 1);
- inter->state[ci_nr - 1] = state;
- state->internal = inter;
- state->nr = ci_nr - 1;
-
- state->ca.owner = THIS_MODULE;
- state->ca.read_attribute_mem = altera_ci_read_attribute_mem;
- state->ca.write_attribute_mem = altera_ci_write_attribute_mem;
- state->ca.read_cam_control = altera_ci_read_cam_ctl;
- state->ca.write_cam_control = altera_ci_write_cam_ctl;
- state->ca.slot_reset = altera_ci_slot_reset;
- state->ca.slot_shutdown = altera_ci_slot_shutdown;
- state->ca.slot_ts_enable = altera_ci_slot_ts_ctl;
- state->ca.poll_slot_status = altera_poll_ci_slot_status;
- state->ca.data = state;
-
- ret = dvb_ca_en50221_init(config->adapter,
- &state->ca,
- /* flags */ 0,
- /* n_slots */ 1);
- if (0 != ret)
- goto err;
-
- altera_hw_filt_init(config, ci_nr);
-
- if (inter->strt_wrk) {
- INIT_WORK(&inter->work, netup_read_ci_status);
- inter->strt_wrk = 0;
- }
-
- ci_dbg_print("%s: CI initialized!\n", __func__);
-
- mutex_lock(&inter->fpga_mutex);
-
- /* Enable div */
- netup_fpga_op_rw(inter, NETUP_CI_TSA_DIV, 0x0, 0);
- netup_fpga_op_rw(inter, NETUP_CI_TSB_DIV, 0x0, 0);
-
- /* enable TS out */
- store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, 0, NETUP_CI_FLG_RD);
- store |= (3 << 4);
- netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0);
-
- ret = netup_fpga_op_rw(inter, NETUP_CI_REVISION, 0, NETUP_CI_FLG_RD);
- /* enable irq */
- netup_fpga_op_rw(inter, NETUP_CI_INT_CTRL, 0x44, 0);
-
- mutex_unlock(&inter->fpga_mutex);
-
- ci_dbg_print("%s: NetUP CI Revision = 0x%x\n", __func__, ret);
-
- schedule_work(&inter->work);
-
- return 0;
-err:
- ci_dbg_print("%s: Cannot initialize CI: Error %d.\n", __func__, ret);
-
- kfree(state);
-
- return ret;
-}
-EXPORT_SYMBOL(altera_ci_init);
-
-int altera_ci_tuner_reset(void *dev, int ci_nr)
-{
- struct fpga_inode *temp_int = find_inode(dev);
- struct fpga_internal *inter = NULL;
- u8 store;
-
- ci_dbg_print("%s\n", __func__);
-
- if (temp_int == NULL)
- return -1;
-
- if (temp_int->internal == NULL)
- return -1;
-
- inter = temp_int->internal;
-
- mutex_lock(&inter->fpga_mutex);
-
- store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, 0, NETUP_CI_FLG_RD);
- store &= ~(4 << (2 - ci_nr));
- netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0);
- msleep(100);
- store |= (4 << (2 - ci_nr));
- netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0);
-
- mutex_unlock(&inter->fpga_mutex);
-
- return 0;
-}
-EXPORT_SYMBOL(altera_ci_tuner_reset);
diff --git a/drivers/media/video/cx23885/altera-ci.h b/drivers/media/video/cx23885/altera-ci.h
deleted file mode 100644
index 70e4fd69ad9..00000000000
--- a/drivers/media/video/cx23885/altera-ci.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * altera-ci.c
- *
- * CI driver in conjunction with NetUp Dual DVB-T/C RF CI card
- *
- * Copyright (C) 2010 NetUP Inc.
- * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#ifndef __ALTERA_CI_H
-#define __ALTERA_CI_H
-
-#define ALT_DATA 0x000000ff
-#define ALT_TDI 0x00008000
-#define ALT_TDO 0x00004000
-#define ALT_TCK 0x00002000
-#define ALT_RDY 0x00001000
-#define ALT_RD 0x00000800
-#define ALT_WR 0x00000400
-#define ALT_AD_RG 0x00000200
-#define ALT_CS 0x00000100
-
-struct altera_ci_config {
- void *dev;/* main dev, for example cx23885_dev */
- void *adapter;/* for CI to connect to */
- struct dvb_demux *demux;/* for hardware PID filter to connect to */
- int (*fpga_rw) (void *dev, int ad_rg, int val, int rw);
-};
-
-#if defined(CONFIG_MEDIA_ALTERA_CI) || (defined(CONFIG_MEDIA_ALTERA_CI_MODULE) \
- && defined(MODULE))
-
-extern int altera_ci_init(struct altera_ci_config *config, int ci_nr);
-extern void altera_ci_release(void *dev, int ci_nr);
-extern int altera_ci_irq(void *dev);
-extern int altera_ci_tuner_reset(void *dev, int ci_nr);
-
-#else
-
-static inline int altera_ci_init(struct altera_ci_config *config, int ci_nr)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return 0;
-}
-
-static inline void altera_ci_release(void *dev, int ci_nr)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
-
-static inline int altera_ci_irq(void *dev)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return 0;
-}
-
-static inline int altera_ci_tuner_reset(void *dev, int ci_nr)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return 0;
-}
-
-#endif
-#if 0
-static inline int altera_hw_filt_init(struct altera_ci_config *config,
- int hw_filt_nr)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return 0;
-}
-
-static inline void altera_hw_filt_release(void *dev, int filt_nr)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
-
-static inline int altera_pid_feed_control(void *dev, int filt_nr,
- struct dvb_demux_feed *dvbdmxfeed, int onoff)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return 0;
-}
-
-#endif /* CONFIG_MEDIA_ALTERA_CI */
-
-#endif /* __ALTERA_CI_H */
diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c
deleted file mode 100644
index c9f15d6dec4..00000000000
--- a/drivers/media/video/cx23885/cimax2.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * cimax2.c
- *
- * CIMax2(R) SP2 driver in conjunction with NetUp Dual DVB-S2 CI card
- *
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
- * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx23885.h"
-#include "dvb_ca_en50221.h"
-/**** Bit definitions for MC417_RWD and MC417_OEN registers ***
- bits 31-16
-+-----------+
-| Reserved |
-+-----------+
- bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8
-+-------+-------+-------+-------+-------+-------+-------+-------+
-| WR# | RD# | | ACK# | ADHI | ADLO | CS1# | CS0# |
-+-------+-------+-------+-------+-------+-------+-------+-------+
- bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
-+-------+-------+-------+-------+-------+-------+-------+-------+
-| DATA7| DATA6| DATA5| DATA4| DATA3| DATA2| DATA1| DATA0|
-+-------+-------+-------+-------+-------+-------+-------+-------+
-***/
-/* MC417 */
-#define NETUP_DATA 0x000000ff
-#define NETUP_WR 0x00008000
-#define NETUP_RD 0x00004000
-#define NETUP_ACK 0x00001000
-#define NETUP_ADHI 0x00000800
-#define NETUP_ADLO 0x00000400
-#define NETUP_CS1 0x00000200
-#define NETUP_CS0 0x00000100
-#define NETUP_EN_ALL 0x00001000
-#define NETUP_CTRL_OFF (NETUP_CS1 | NETUP_CS0 | NETUP_WR | NETUP_RD)
-#define NETUP_CI_CTL 0x04
-#define NETUP_CI_RD 1
-
-#define NETUP_IRQ_DETAM 0x1
-#define NETUP_IRQ_IRQAM 0x4
-
-static unsigned int ci_dbg;
-module_param(ci_dbg, int, 0644);
-MODULE_PARM_DESC(ci_dbg, "Enable CI debugging");
-
-static unsigned int ci_irq_enable;
-module_param(ci_irq_enable, int, 0644);
-MODULE_PARM_DESC(ci_irq_enable, "Enable IRQ from CAM");
-
-#define ci_dbg_print(args...) \
- do { \
- if (ci_dbg) \
- printk(KERN_DEBUG args); \
- } while (0)
-
-#define ci_irq_flags() (ci_irq_enable ? NETUP_IRQ_IRQAM : 0)
-
-/* stores all private variables for communication with CI */
-struct netup_ci_state {
- struct dvb_ca_en50221 ca;
- struct mutex ca_mutex;
- struct i2c_adapter *i2c_adap;
- u8 ci_i2c_addr;
- int status;
- struct work_struct work;
- void *priv;
- u8 current_irq_mode;
- int current_ci_flag;
- unsigned long next_status_checked_time;
-};
-
-
-int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
- u8 *buf, int len)
-{
- int ret;
- struct i2c_msg msg[] = {
- {
- .addr = addr,
- .flags = 0,
- .buf = &reg,
- .len = 1
- }, {
- .addr = addr,
- .flags = I2C_M_RD,
- .buf = buf,
- .len = len
- }
- };
-
- ret = i2c_transfer(i2c_adap, msg, 2);
-
- if (ret != 2) {
- ci_dbg_print("%s: i2c read error, Reg = 0x%02x, Status = %d\n",
- __func__, reg, ret);
-
- return -1;
- }
-
- ci_dbg_print("%s: i2c read Addr=0x%04x, Reg = 0x%02x, data = %02x\n",
- __func__, addr, reg, buf[0]);
-
- return 0;
-}
-
-int netup_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
- u8 *buf, int len)
-{
- int ret;
- u8 buffer[len + 1];
-
- struct i2c_msg msg = {
- .addr = addr,
- .flags = 0,
- .buf = &buffer[0],
- .len = len + 1
- };
-
- buffer[0] = reg;
- memcpy(&buffer[1], buf, len);
-
- ret = i2c_transfer(i2c_adap, &msg, 1);
-
- if (ret != 1) {
- ci_dbg_print("%s: i2c write error, Reg=[0x%02x], Status=%d\n",
- __func__, reg, ret);
- return -1;
- }
-
- return 0;
-}
-
-int netup_ci_get_mem(struct cx23885_dev *dev)
-{
- int mem;
- unsigned long timeout = jiffies + msecs_to_jiffies(1);
-
- for (;;) {
- mem = cx_read(MC417_RWD);
- if ((mem & NETUP_ACK) == 0)
- break;
- if (time_after(jiffies, timeout))
- break;
- udelay(1);
- }
-
- cx_set(MC417_RWD, NETUP_CTRL_OFF);
-
- return mem & 0xff;
-}
-
-int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
- u8 flag, u8 read, int addr, u8 data)
-{
- struct netup_ci_state *state = en50221->data;
- struct cx23885_tsport *port = state->priv;
- struct cx23885_dev *dev = port->dev;
-
- u8 store;
- int mem;
- int ret;
-
- if (0 != slot)
- return -EINVAL;
-
- if (state->current_ci_flag != flag) {
- ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0, &store, 1);
- if (ret != 0)
- return ret;
-
- store &= ~0x0c;
- store |= flag;
-
- ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0, &store, 1);
- if (ret != 0)
- return ret;
- };
- state->current_ci_flag = flag;
-
- mutex_lock(&dev->gpio_lock);
-
- /* write addr */
- cx_write(MC417_OEN, NETUP_EN_ALL);
- cx_write(MC417_RWD, NETUP_CTRL_OFF |
- NETUP_ADLO | (0xff & addr));
- cx_clear(MC417_RWD, NETUP_ADLO);
- cx_write(MC417_RWD, NETUP_CTRL_OFF |
- NETUP_ADHI | (0xff & (addr >> 8)));
- cx_clear(MC417_RWD, NETUP_ADHI);
-
- if (read) { /* data in */
- cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA);
- } else /* data out */
- cx_write(MC417_RWD, NETUP_CTRL_OFF | data);
-
- /* choose chip */
- cx_clear(MC417_RWD,
- (state->ci_i2c_addr == 0x40) ? NETUP_CS0 : NETUP_CS1);
- /* read/write */
- cx_clear(MC417_RWD, (read) ? NETUP_RD : NETUP_WR);
- mem = netup_ci_get_mem(dev);
-
- mutex_unlock(&dev->gpio_lock);
-
- if (!read)
- if (mem < 0)
- return -EREMOTEIO;
-
- ci_dbg_print("%s: %s: chipaddr=[0x%x] addr=[0x%02x], %s=%x\n", __func__,
- (read) ? "read" : "write", state->ci_i2c_addr, addr,
- (flag == NETUP_CI_CTL) ? "ctl" : "mem",
- (read) ? mem : data);
-
- if (read)
- return mem;
-
- return 0;
-}
-
-int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
- int slot, int addr)
-{
- return netup_ci_op_cam(en50221, slot, 0, NETUP_CI_RD, addr, 0);
-}
-
-int netup_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
- int slot, int addr, u8 data)
-{
- return netup_ci_op_cam(en50221, slot, 0, 0, addr, data);
-}
-
-int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
-{
- return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL,
- NETUP_CI_RD, addr, 0);
-}
-
-int netup_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot,
- u8 addr, u8 data)
-{
- return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL, 0, addr, data);
-}
-
-int netup_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
-{
- struct netup_ci_state *state = en50221->data;
- u8 buf = 0x80;
- int ret;
-
- if (0 != slot)
- return -EINVAL;
-
- udelay(500);
- ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0, &buf, 1);
-
- if (ret != 0)
- return ret;
-
- udelay(500);
-
- buf = 0x00;
- ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0, &buf, 1);
-
- msleep(1000);
- dvb_ca_en50221_camready_irq(&state->ca, 0);
-
- return 0;
-
-}
-
-int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
-{
- /* not implemented */
- return 0;
-}
-
-int netup_ci_set_irq(struct dvb_ca_en50221 *en50221, u8 irq_mode)
-{
- struct netup_ci_state *state = en50221->data;
- int ret;
-
- if (irq_mode == state->current_irq_mode)
- return 0;
-
- ci_dbg_print("%s: chipaddr=[0x%x] setting ci IRQ to [0x%x] \n",
- __func__, state->ci_i2c_addr, irq_mode);
- ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0x1b, &irq_mode, 1);
-
- if (ret != 0)
- return ret;
-
- state->current_irq_mode = irq_mode;
-
- return 0;
-}
-
-int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot)
-{
- struct netup_ci_state *state = en50221->data;
- u8 buf;
-
- if (0 != slot)
- return -EINVAL;
-
- netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0, &buf, 1);
- buf |= 0x60;
-
- return netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0, &buf, 1);
-}
-
-/* work handler */
-static void netup_read_ci_status(struct work_struct *work)
-{
- struct netup_ci_state *state =
- container_of(work, struct netup_ci_state, work);
- u8 buf[33];
- int ret;
-
- /* CAM module IRQ processing. fast operation */
- dvb_ca_en50221_frda_irq(&state->ca, 0);
-
- /* CAM module INSERT/REMOVE processing. slow operation because of i2c
- * transfers */
- if (time_after(jiffies, state->next_status_checked_time)
- || !state->status) {
- ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0, &buf[0], 33);
-
- state->next_status_checked_time = jiffies
- + msecs_to_jiffies(1000);
-
- if (ret != 0)
- return;
-
- ci_dbg_print("%s: Slot Status Addr=[0x%04x], "
- "Reg=[0x%02x], data=%02x, "
- "TS config = %02x\n", __func__,
- state->ci_i2c_addr, 0, buf[0],
- buf[0]);
-
-
- if (buf[0] & 1)
- state->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
- DVB_CA_EN50221_POLL_CAM_READY;
- else
- state->status = 0;
- }
-}
-
-/* CI irq handler */
-int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status)
-{
- struct cx23885_tsport *port = NULL;
- struct netup_ci_state *state = NULL;
-
- ci_dbg_print("%s:\n", __func__);
-
- if (0 == (pci_status & (PCI_MSK_GPIO0 | PCI_MSK_GPIO1)))
- return 0;
-
- if (pci_status & PCI_MSK_GPIO0) {
- port = &dev->ts1;
- state = port->port_priv;
- schedule_work(&state->work);
- ci_dbg_print("%s: Wakeup CI0\n", __func__);
- }
-
- if (pci_status & PCI_MSK_GPIO1) {
- port = &dev->ts2;
- state = port->port_priv;
- schedule_work(&state->work);
- ci_dbg_print("%s: Wakeup CI1\n", __func__);
- }
-
- return 1;
-}
-
-int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open)
-{
- struct netup_ci_state *state = en50221->data;
-
- if (0 != slot)
- return -EINVAL;
-
- netup_ci_set_irq(en50221, open ? (NETUP_IRQ_DETAM | ci_irq_flags())
- : NETUP_IRQ_DETAM);
-
- return state->status;
-}
-
-int netup_ci_init(struct cx23885_tsport *port)
-{
- struct netup_ci_state *state;
- u8 cimax_init[34] = {
- 0x00, /* module A control*/
- 0x00, /* auto select mask high A */
- 0x00, /* auto select mask low A */
- 0x00, /* auto select pattern high A */
- 0x00, /* auto select pattern low A */
- 0x44, /* memory access time A */
- 0x00, /* invert input A */
- 0x00, /* RFU */
- 0x00, /* RFU */
- 0x00, /* module B control*/
- 0x00, /* auto select mask high B */
- 0x00, /* auto select mask low B */
- 0x00, /* auto select pattern high B */
- 0x00, /* auto select pattern low B */
- 0x44, /* memory access time B */
- 0x00, /* invert input B */
- 0x00, /* RFU */
- 0x00, /* RFU */
- 0x00, /* auto select mask high Ext */
- 0x00, /* auto select mask low Ext */
- 0x00, /* auto select pattern high Ext */
- 0x00, /* auto select pattern low Ext */
- 0x00, /* RFU */
- 0x02, /* destination - module A */
- 0x01, /* power on (use it like store place) */
- 0x00, /* RFU */
- 0x00, /* int status read only */
- ci_irq_flags() | NETUP_IRQ_DETAM, /* DETAM, IRQAM unmasked */
- 0x05, /* EXTINT=active-high, INT=push-pull */
- 0x00, /* USCG1 */
- 0x04, /* ack active low */
- 0x00, /* LOCK = 0 */
- 0x33, /* serial mode, rising in, rising out, MSB first*/
- 0x31, /* synchronization */
- };
- int ret;
-
- ci_dbg_print("%s\n", __func__);
- state = kzalloc(sizeof(struct netup_ci_state), GFP_KERNEL);
- if (!state) {
- ci_dbg_print("%s: Unable create CI structure!\n", __func__);
- ret = -ENOMEM;
- goto err;
- }
-
- port->port_priv = state;
-
- switch (port->nr) {
- case 1:
- state->ci_i2c_addr = 0x40;
- break;
- case 2:
- state->ci_i2c_addr = 0x41;
- break;
- }
-
- state->i2c_adap = &port->dev->i2c_bus[0].i2c_adap;
- state->ca.owner = THIS_MODULE;
- state->ca.read_attribute_mem = netup_ci_read_attribute_mem;
- state->ca.write_attribute_mem = netup_ci_write_attribute_mem;
- state->ca.read_cam_control = netup_ci_read_cam_ctl;
- state->ca.write_cam_control = netup_ci_write_cam_ctl;
- state->ca.slot_reset = netup_ci_slot_reset;
- state->ca.slot_shutdown = netup_ci_slot_shutdown;
- state->ca.slot_ts_enable = netup_ci_slot_ts_ctl;
- state->ca.poll_slot_status = netup_poll_ci_slot_status;
- state->ca.data = state;
- state->priv = port;
- state->current_irq_mode = ci_irq_flags() | NETUP_IRQ_DETAM;
-
- ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0, &cimax_init[0], 34);
- /* lock registers */
- ret |= netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0x1f, &cimax_init[0x18], 1);
- /* power on slots */
- ret |= netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0x18, &cimax_init[0x18], 1);
-
- if (0 != ret)
- goto err;
-
- ret = dvb_ca_en50221_init(&port->frontends.adapter,
- &state->ca,
- /* flags */ 0,
- /* n_slots */ 1);
- if (0 != ret)
- goto err;
-
- INIT_WORK(&state->work, netup_read_ci_status);
- schedule_work(&state->work);
-
- ci_dbg_print("%s: CI initialized!\n", __func__);
-
- return 0;
-err:
- ci_dbg_print("%s: Cannot initialize CI: Error %d.\n", __func__, ret);
- kfree(state);
- return ret;
-}
-
-void netup_ci_exit(struct cx23885_tsport *port)
-{
- struct netup_ci_state *state;
-
- if (NULL == port)
- return;
-
- state = (struct netup_ci_state *)port->port_priv;
- if (NULL == state)
- return;
-
- if (NULL == state->ca.data)
- return;
-
- dvb_ca_en50221_release(&state->ca);
- kfree(state);
-}
diff --git a/drivers/media/video/cx23885/cimax2.h b/drivers/media/video/cx23885/cimax2.h
deleted file mode 100644
index 518744a4c8a..00000000000
--- a/drivers/media/video/cx23885/cimax2.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * cimax2.h
- *
- * CIMax(R) SP2 driver in conjunction with NetUp Dual DVB-S2 CI card
- *
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
- * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef CIMAX2_H
-#define CIMAX2_H
-#include "dvb_ca_en50221.h"
-
-extern int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
- int slot, int addr);
-extern int netup_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
- int slot, int addr, u8 data);
-extern int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221,
- int slot, u8 addr);
-extern int netup_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221,
- int slot, u8 addr, u8 data);
-extern int netup_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot);
-extern int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot);
-extern int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot);
-extern int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status);
-extern int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221,
- int slot, int open);
-extern int netup_ci_init(struct cx23885_tsport *port);
-extern void netup_ci_exit(struct cx23885_tsport *port);
-
-#endif
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
deleted file mode 100644
index f5c79e53e5a..00000000000
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ /dev/null
@@ -1,1788 +0,0 @@
-/*
- *
- * Support for a cx23417 mpeg encoder via cx23885 host port.
- *
- * (c) 2004 Jelle Foks <jelle@foks.us>
- * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
- * (c) 2008 Steven Toth <stoth@linuxtv.org>
- * - CX23885/7/8 support
- *
- * Includes parts from the ivtv driver <http://sourceforge.net/projects/ivtv/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/cx2341x.h>
-
-#include "cx23885.h"
-#include "cx23885-ioctl.h"
-
-#define CX23885_FIRM_IMAGE_SIZE 376836
-#define CX23885_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw"
-
-static unsigned int mpegbufs = 32;
-module_param(mpegbufs, int, 0644);
-MODULE_PARM_DESC(mpegbufs, "number of mpeg buffers, range 2-32");
-static unsigned int mpeglines = 32;
-module_param(mpeglines, int, 0644);
-MODULE_PARM_DESC(mpeglines, "number of lines in an MPEG buffer, range 2-32");
-static unsigned int mpeglinesize = 512;
-module_param(mpeglinesize, int, 0644);
-MODULE_PARM_DESC(mpeglinesize,
- "number of bytes in each line of an MPEG buffer, range 512-1024");
-
-static unsigned int v4l_debug;
-module_param(v4l_debug, int, 0644);
-MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages");
-
-#define dprintk(level, fmt, arg...)\
- do { if (v4l_debug >= level) \
- printk(KERN_DEBUG "%s: " fmt, \
- (dev) ? dev->name : "cx23885[?]", ## arg); \
- } while (0)
-
-static struct cx23885_tvnorm cx23885_tvnorms[] = {
- {
- .name = "NTSC-M",
- .id = V4L2_STD_NTSC_M,
- }, {
- .name = "NTSC-JP",
- .id = V4L2_STD_NTSC_M_JP,
- }, {
- .name = "PAL-BG",
- .id = V4L2_STD_PAL_BG,
- }, {
- .name = "PAL-DK",
- .id = V4L2_STD_PAL_DK,
- }, {
- .name = "PAL-I",
- .id = V4L2_STD_PAL_I,
- }, {
- .name = "PAL-M",
- .id = V4L2_STD_PAL_M,
- }, {
- .name = "PAL-N",
- .id = V4L2_STD_PAL_N,
- }, {
- .name = "PAL-Nc",
- .id = V4L2_STD_PAL_Nc,
- }, {
- .name = "PAL-60",
- .id = V4L2_STD_PAL_60,
- }, {
- .name = "SECAM-L",
- .id = V4L2_STD_SECAM_L,
- }, {
- .name = "SECAM-DK",
- .id = V4L2_STD_SECAM_DK,
- }
-};
-
-/* ------------------------------------------------------------------ */
-enum cx23885_capture_type {
- CX23885_MPEG_CAPTURE,
- CX23885_RAW_CAPTURE,
- CX23885_RAW_PASSTHRU_CAPTURE
-};
-enum cx23885_capture_bits {
- CX23885_RAW_BITS_NONE = 0x00,
- CX23885_RAW_BITS_YUV_CAPTURE = 0x01,
- CX23885_RAW_BITS_PCM_CAPTURE = 0x02,
- CX23885_RAW_BITS_VBI_CAPTURE = 0x04,
- CX23885_RAW_BITS_PASSTHRU_CAPTURE = 0x08,
- CX23885_RAW_BITS_TO_HOST_CAPTURE = 0x10
-};
-enum cx23885_capture_end {
- CX23885_END_AT_GOP, /* stop at the end of gop, generate irq */
- CX23885_END_NOW, /* stop immediately, no irq */
-};
-enum cx23885_framerate {
- CX23885_FRAMERATE_NTSC_30, /* NTSC: 30fps */
- CX23885_FRAMERATE_PAL_25 /* PAL: 25fps */
-};
-enum cx23885_stream_port {
- CX23885_OUTPUT_PORT_MEMORY,
- CX23885_OUTPUT_PORT_STREAMING,
- CX23885_OUTPUT_PORT_SERIAL
-};
-enum cx23885_data_xfer_status {
- CX23885_MORE_BUFFERS_FOLLOW,
- CX23885_LAST_BUFFER,
-};
-enum cx23885_picture_mask {
- CX23885_PICTURE_MASK_NONE,
- CX23885_PICTURE_MASK_I_FRAMES,
- CX23885_PICTURE_MASK_I_P_FRAMES = 0x3,
- CX23885_PICTURE_MASK_ALL_FRAMES = 0x7,
-};
-enum cx23885_vbi_mode_bits {
- CX23885_VBI_BITS_SLICED,
- CX23885_VBI_BITS_RAW,
-};
-enum cx23885_vbi_insertion_bits {
- CX23885_VBI_BITS_INSERT_IN_XTENSION_USR_DATA,
- CX23885_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1,
- CX23885_VBI_BITS_SEPARATE_STREAM = 0x2 << 1,
- CX23885_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1,
- CX23885_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1,
-};
-enum cx23885_dma_unit {
- CX23885_DMA_BYTES,
- CX23885_DMA_FRAMES,
-};
-enum cx23885_dma_transfer_status_bits {
- CX23885_DMA_TRANSFER_BITS_DONE = 0x01,
- CX23885_DMA_TRANSFER_BITS_ERROR = 0x04,
- CX23885_DMA_TRANSFER_BITS_LL_ERROR = 0x10,
-};
-enum cx23885_pause {
- CX23885_PAUSE_ENCODING,
- CX23885_RESUME_ENCODING,
-};
-enum cx23885_copyright {
- CX23885_COPYRIGHT_OFF,
- CX23885_COPYRIGHT_ON,
-};
-enum cx23885_notification_type {
- CX23885_NOTIFICATION_REFRESH,
-};
-enum cx23885_notification_status {
- CX23885_NOTIFICATION_OFF,
- CX23885_NOTIFICATION_ON,
-};
-enum cx23885_notification_mailbox {
- CX23885_NOTIFICATION_NO_MAILBOX = -1,
-};
-enum cx23885_field1_lines {
- CX23885_FIELD1_SAA7114 = 0x00EF, /* 239 */
- CX23885_FIELD1_SAA7115 = 0x00F0, /* 240 */
- CX23885_FIELD1_MICRONAS = 0x0105, /* 261 */
-};
-enum cx23885_field2_lines {
- CX23885_FIELD2_SAA7114 = 0x00EF, /* 239 */
- CX23885_FIELD2_SAA7115 = 0x00F0, /* 240 */
- CX23885_FIELD2_MICRONAS = 0x0106, /* 262 */
-};
-enum cx23885_custom_data_type {
- CX23885_CUSTOM_EXTENSION_USR_DATA,
- CX23885_CUSTOM_PRIVATE_PACKET,
-};
-enum cx23885_mute {
- CX23885_UNMUTE,
- CX23885_MUTE,
-};
-enum cx23885_mute_video_mask {
- CX23885_MUTE_VIDEO_V_MASK = 0x0000FF00,
- CX23885_MUTE_VIDEO_U_MASK = 0x00FF0000,
- CX23885_MUTE_VIDEO_Y_MASK = 0xFF000000,
-};
-enum cx23885_mute_video_shift {
- CX23885_MUTE_VIDEO_V_SHIFT = 8,
- CX23885_MUTE_VIDEO_U_SHIFT = 16,
- CX23885_MUTE_VIDEO_Y_SHIFT = 24,
-};
-
-/* defines below are from ivtv-driver.h */
-#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
-
-/* Firmware API commands */
-#define IVTV_API_STD_TIMEOUT 500
-
-/* Registers */
-/* IVTV_REG_OFFSET */
-#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8)
-#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC)
-#define IVTV_REG_SPU (0x9050)
-#define IVTV_REG_HW_BLOCKS (0x9054)
-#define IVTV_REG_VPU (0x9058)
-#define IVTV_REG_APU (0xA064)
-
-/**** Bit definitions for MC417_RWD and MC417_OEN registers ***
- bits 31-16
-+-----------+
-| Reserved |
-+-----------+
- bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8
-+-------+-------+-------+-------+-------+-------+-------+-------+
-| MIWR# | MIRD# | MICS# |MIRDY# |MIADDR3|MIADDR2|MIADDR1|MIADDR0|
-+-------+-------+-------+-------+-------+-------+-------+-------+
- bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
-+-------+-------+-------+-------+-------+-------+-------+-------+
-|MIDATA7|MIDATA6|MIDATA5|MIDATA4|MIDATA3|MIDATA2|MIDATA1|MIDATA0|
-+-------+-------+-------+-------+-------+-------+-------+-------+
-***/
-#define MC417_MIWR 0x8000
-#define MC417_MIRD 0x4000
-#define MC417_MICS 0x2000
-#define MC417_MIRDY 0x1000
-#define MC417_MIADDR 0x0F00
-#define MC417_MIDATA 0x00FF
-
-/* MIADDR* nibble definitions */
-#define MCI_MEMORY_DATA_BYTE0 0x000
-#define MCI_MEMORY_DATA_BYTE1 0x100
-#define MCI_MEMORY_DATA_BYTE2 0x200
-#define MCI_MEMORY_DATA_BYTE3 0x300
-#define MCI_MEMORY_ADDRESS_BYTE2 0x400
-#define MCI_MEMORY_ADDRESS_BYTE1 0x500
-#define MCI_MEMORY_ADDRESS_BYTE0 0x600
-#define MCI_REGISTER_DATA_BYTE0 0x800
-#define MCI_REGISTER_DATA_BYTE1 0x900
-#define MCI_REGISTER_DATA_BYTE2 0xA00
-#define MCI_REGISTER_DATA_BYTE3 0xB00
-#define MCI_REGISTER_ADDRESS_BYTE0 0xC00
-#define MCI_REGISTER_ADDRESS_BYTE1 0xD00
-#define MCI_REGISTER_MODE 0xE00
-
-/* Read and write modes */
-#define MCI_MODE_REGISTER_READ 0
-#define MCI_MODE_REGISTER_WRITE 1
-#define MCI_MODE_MEMORY_READ 0
-#define MCI_MODE_MEMORY_WRITE 0x40
-
-/*** Bit definitions for MC417_CTL register ****
- bits 31-6 bits 5-4 bit 3 bits 2-1 Bit 0
-+--------+-------------+--------+--------------+------------+
-|Reserved|MC417_SPD_CTL|Reserved|MC417_GPIO_SEL|UART_GPIO_EN|
-+--------+-------------+--------+--------------+------------+
-***/
-#define MC417_SPD_CTL(x) (((x) << 4) & 0x00000030)
-#define MC417_GPIO_SEL(x) (((x) << 1) & 0x00000006)
-#define MC417_UART_GPIO_EN 0x00000001
-
-/* Values for speed control */
-#define MC417_SPD_CTL_SLOW 0x1
-#define MC417_SPD_CTL_MEDIUM 0x0
-#define MC417_SPD_CTL_FAST 0x3 /* b'1x, but we use b'11 */
-
-/* Values for GPIO select */
-#define MC417_GPIO_SEL_GPIO3 0x3
-#define MC417_GPIO_SEL_GPIO2 0x2
-#define MC417_GPIO_SEL_GPIO1 0x1
-#define MC417_GPIO_SEL_GPIO0 0x0
-
-void cx23885_mc417_init(struct cx23885_dev *dev)
-{
- u32 regval;
-
- dprintk(2, "%s()\n", __func__);
-
- /* Configure MC417_CTL register to defaults. */
- regval = MC417_SPD_CTL(MC417_SPD_CTL_FAST) |
- MC417_GPIO_SEL(MC417_GPIO_SEL_GPIO3) |
- MC417_UART_GPIO_EN;
- cx_write(MC417_CTL, regval);
-
- /* Configure MC417_OEN to defaults. */
- regval = MC417_MIRDY;
- cx_write(MC417_OEN, regval);
-
- /* Configure MC417_RWD to defaults. */
- regval = MC417_MIWR | MC417_MIRD | MC417_MICS;
- cx_write(MC417_RWD, regval);
-}
-
-static int mc417_wait_ready(struct cx23885_dev *dev)
-{
- u32 mi_ready;
- unsigned long timeout = jiffies + msecs_to_jiffies(1);
-
- for (;;) {
- mi_ready = cx_read(MC417_RWD) & MC417_MIRDY;
- if (mi_ready != 0)
- return 0;
- if (time_after(jiffies, timeout))
- return -1;
- udelay(1);
- }
-}
-
-int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value)
-{
- u32 regval;
-
- /* Enable MC417 GPIO outputs except for MC417_MIRDY,
- * which is an input.
- */
- cx_write(MC417_OEN, MC417_MIRDY);
-
- /* Write data byte 0 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0 |
- (value & 0x000000FF);
- cx_write(MC417_RWD, regval);
-
- /* Transition CS/WR to effect write transaction across bus. */
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Write data byte 1 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1 |
- ((value >> 8) & 0x000000FF);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Write data byte 2 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2 |
- ((value >> 16) & 0x000000FF);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Write data byte 3 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3 |
- ((value >> 24) & 0x000000FF);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Write address byte 0 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE0 |
- (address & 0xFF);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Write address byte 1 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE1 |
- ((address >> 8) & 0xFF);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Indicate that this is a write. */
- regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_MODE |
- MCI_MODE_REGISTER_WRITE;
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Wait for the trans to complete (MC417_MIRDY asserted). */
- return mc417_wait_ready(dev);
-}
-
-int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value)
-{
- int retval;
- u32 regval;
- u32 tempval;
- u32 dataval;
-
- /* Enable MC417 GPIO outputs except for MC417_MIRDY,
- * which is an input.
- */
- cx_write(MC417_OEN, MC417_MIRDY);
-
- /* Write address byte 0 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE0 |
- ((address & 0x00FF));
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Write address byte 1 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE1 |
- ((address >> 8) & 0xFF);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Indicate that this is a register read. */
- regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_MODE |
- MCI_MODE_REGISTER_READ;
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Wait for the trans to complete (MC417_MIRDY asserted). */
- retval = mc417_wait_ready(dev);
-
- /* switch the DAT0-7 GPIO[10:3] to input mode */
- cx_write(MC417_OEN, MC417_MIRDY | MC417_MIDATA);
-
- /* Read data byte 0 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0;
- cx_write(MC417_RWD, regval);
-
- /* Transition RD to effect read transaction across bus.
- * Transtion 0x5000 -> 0x9000 correct (RD/RDY -> WR/RDY)?
- * Should it be 0x9000 -> 0xF000 (also why is RDY being set, its
- * input only...)
- */
- regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0;
- cx_write(MC417_RWD, regval);
-
- /* Collect byte */
- tempval = cx_read(MC417_RWD);
- dataval = tempval & 0x000000FF;
-
- /* Bring CS and RD high. */
- regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
- cx_write(MC417_RWD, regval);
-
- /* Read data byte 1 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1;
- cx_write(MC417_RWD, regval);
- regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1;
- cx_write(MC417_RWD, regval);
- tempval = cx_read(MC417_RWD);
- dataval |= ((tempval & 0x000000FF) << 8);
- regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
- cx_write(MC417_RWD, regval);
-
- /* Read data byte 2 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2;
- cx_write(MC417_RWD, regval);
- regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2;
- cx_write(MC417_RWD, regval);
- tempval = cx_read(MC417_RWD);
- dataval |= ((tempval & 0x000000FF) << 16);
- regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
- cx_write(MC417_RWD, regval);
-
- /* Read data byte 3 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3;
- cx_write(MC417_RWD, regval);
- regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3;
- cx_write(MC417_RWD, regval);
- tempval = cx_read(MC417_RWD);
- dataval |= ((tempval & 0x000000FF) << 24);
- regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
- cx_write(MC417_RWD, regval);
-
- *value = dataval;
-
- return retval;
-}
-
-int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value)
-{
- u32 regval;
-
- /* Enable MC417 GPIO outputs except for MC417_MIRDY,
- * which is an input.
- */
- cx_write(MC417_OEN, MC417_MIRDY);
-
- /* Write data byte 0 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0 |
- (value & 0x000000FF);
- cx_write(MC417_RWD, regval);
-
- /* Transition CS/WR to effect write transaction across bus. */
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Write data byte 1 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1 |
- ((value >> 8) & 0x000000FF);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Write data byte 2 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2 |
- ((value >> 16) & 0x000000FF);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Write data byte 3 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3 |
- ((value >> 24) & 0x000000FF);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Write address byte 2 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE2 |
- MCI_MODE_MEMORY_WRITE | ((address >> 16) & 0x3F);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Write address byte 1 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE1 |
- ((address >> 8) & 0xFF);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Write address byte 0 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE0 |
- (address & 0xFF);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Wait for the trans to complete (MC417_MIRDY asserted). */
- return mc417_wait_ready(dev);
-}
-
-int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value)
-{
- int retval;
- u32 regval;
- u32 tempval;
- u32 dataval;
-
- /* Enable MC417 GPIO outputs except for MC417_MIRDY,
- * which is an input.
- */
- cx_write(MC417_OEN, MC417_MIRDY);
-
- /* Write address byte 2 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE2 |
- MCI_MODE_MEMORY_READ | ((address >> 16) & 0x3F);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Write address byte 1 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE1 |
- ((address >> 8) & 0xFF);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Write address byte 0 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE0 |
- (address & 0xFF);
- cx_write(MC417_RWD, regval);
- regval |= MC417_MICS | MC417_MIWR;
- cx_write(MC417_RWD, regval);
-
- /* Wait for the trans to complete (MC417_MIRDY asserted). */
- retval = mc417_wait_ready(dev);
-
- /* switch the DAT0-7 GPIO[10:3] to input mode */
- cx_write(MC417_OEN, MC417_MIRDY | MC417_MIDATA);
-
- /* Read data byte 3 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3;
- cx_write(MC417_RWD, regval);
-
- /* Transition RD to effect read transaction across bus. */
- regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3;
- cx_write(MC417_RWD, regval);
-
- /* Collect byte */
- tempval = cx_read(MC417_RWD);
- dataval = ((tempval & 0x000000FF) << 24);
-
- /* Bring CS and RD high. */
- regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
- cx_write(MC417_RWD, regval);
-
- /* Read data byte 2 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2;
- cx_write(MC417_RWD, regval);
- regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2;
- cx_write(MC417_RWD, regval);
- tempval = cx_read(MC417_RWD);
- dataval |= ((tempval & 0x000000FF) << 16);
- regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
- cx_write(MC417_RWD, regval);
-
- /* Read data byte 1 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1;
- cx_write(MC417_RWD, regval);
- regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1;
- cx_write(MC417_RWD, regval);
- tempval = cx_read(MC417_RWD);
- dataval |= ((tempval & 0x000000FF) << 8);
- regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
- cx_write(MC417_RWD, regval);
-
- /* Read data byte 0 */
- regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0;
- cx_write(MC417_RWD, regval);
- regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0;
- cx_write(MC417_RWD, regval);
- tempval = cx_read(MC417_RWD);
- dataval |= (tempval & 0x000000FF);
- regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
- cx_write(MC417_RWD, regval);
-
- *value = dataval;
-
- return retval;
-}
-
-void mc417_gpio_set(struct cx23885_dev *dev, u32 mask)
-{
- u32 val;
-
- /* Set the gpio value */
- mc417_register_read(dev, 0x900C, &val);
- val |= (mask & 0x000ffff);
- mc417_register_write(dev, 0x900C, val);
-}
-
-void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask)
-{
- u32 val;
-
- /* Clear the gpio value */
- mc417_register_read(dev, 0x900C, &val);
- val &= ~(mask & 0x0000ffff);
- mc417_register_write(dev, 0x900C, val);
-}
-
-void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
-{
- u32 val;
-
- /* Enable GPIO direction bits */
- mc417_register_read(dev, 0x9020, &val);
- if (asoutput)
- val |= (mask & 0x0000ffff);
- else
- val &= ~(mask & 0x0000ffff);
-
- mc417_register_write(dev, 0x9020, val);
-}
-/* ------------------------------------------------------------------ */
-
-/* MPEG encoder API */
-static char *cmd_to_str(int cmd)
-{
- switch (cmd) {
- case CX2341X_ENC_PING_FW:
- return "PING_FW";
- case CX2341X_ENC_START_CAPTURE:
- return "START_CAPTURE";
- case CX2341X_ENC_STOP_CAPTURE:
- return "STOP_CAPTURE";
- case CX2341X_ENC_SET_AUDIO_ID:
- return "SET_AUDIO_ID";
- case CX2341X_ENC_SET_VIDEO_ID:
- return "SET_VIDEO_ID";
- case CX2341X_ENC_SET_PCR_ID:
- return "SET_PCR_ID";
- case CX2341X_ENC_SET_FRAME_RATE:
- return "SET_FRAME_RATE";
- case CX2341X_ENC_SET_FRAME_SIZE:
- return "SET_FRAME_SIZE";
- case CX2341X_ENC_SET_BIT_RATE:
- return "SET_BIT_RATE";
- case CX2341X_ENC_SET_GOP_PROPERTIES:
- return "SET_GOP_PROPERTIES";
- case CX2341X_ENC_SET_ASPECT_RATIO:
- return "SET_ASPECT_RATIO";
- case CX2341X_ENC_SET_DNR_FILTER_MODE:
- return "SET_DNR_FILTER_MODE";
- case CX2341X_ENC_SET_DNR_FILTER_PROPS:
- return "SET_DNR_FILTER_PROPS";
- case CX2341X_ENC_SET_CORING_LEVELS:
- return "SET_CORING_LEVELS";
- case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE:
- return "SET_SPATIAL_FILTER_TYPE";
- case CX2341X_ENC_SET_VBI_LINE:
- return "SET_VBI_LINE";
- case CX2341X_ENC_SET_STREAM_TYPE:
- return "SET_STREAM_TYPE";
- case CX2341X_ENC_SET_OUTPUT_PORT:
- return "SET_OUTPUT_PORT";
- case CX2341X_ENC_SET_AUDIO_PROPERTIES:
- return "SET_AUDIO_PROPERTIES";
- case CX2341X_ENC_HALT_FW:
- return "HALT_FW";
- case CX2341X_ENC_GET_VERSION:
- return "GET_VERSION";
- case CX2341X_ENC_SET_GOP_CLOSURE:
- return "SET_GOP_CLOSURE";
- case CX2341X_ENC_GET_SEQ_END:
- return "GET_SEQ_END";
- case CX2341X_ENC_SET_PGM_INDEX_INFO:
- return "SET_PGM_INDEX_INFO";
- case CX2341X_ENC_SET_VBI_CONFIG:
- return "SET_VBI_CONFIG";
- case CX2341X_ENC_SET_DMA_BLOCK_SIZE:
- return "SET_DMA_BLOCK_SIZE";
- case CX2341X_ENC_GET_PREV_DMA_INFO_MB_10:
- return "GET_PREV_DMA_INFO_MB_10";
- case CX2341X_ENC_GET_PREV_DMA_INFO_MB_9:
- return "GET_PREV_DMA_INFO_MB_9";
- case CX2341X_ENC_SCHED_DMA_TO_HOST:
- return "SCHED_DMA_TO_HOST";
- case CX2341X_ENC_INITIALIZE_INPUT:
- return "INITIALIZE_INPUT";
- case CX2341X_ENC_SET_FRAME_DROP_RATE:
- return "SET_FRAME_DROP_RATE";
- case CX2341X_ENC_PAUSE_ENCODER:
- return "PAUSE_ENCODER";
- case CX2341X_ENC_REFRESH_INPUT:
- return "REFRESH_INPUT";
- case CX2341X_ENC_SET_COPYRIGHT:
- return "SET_COPYRIGHT";
- case CX2341X_ENC_SET_EVENT_NOTIFICATION:
- return "SET_EVENT_NOTIFICATION";
- case CX2341X_ENC_SET_NUM_VSYNC_LINES:
- return "SET_NUM_VSYNC_LINES";
- case CX2341X_ENC_SET_PLACEHOLDER:
- return "SET_PLACEHOLDER";
- case CX2341X_ENC_MUTE_VIDEO:
- return "MUTE_VIDEO";
- case CX2341X_ENC_MUTE_AUDIO:
- return "MUTE_AUDIO";
- case CX2341X_ENC_MISC:
- return "MISC";
- default:
- return "UNKNOWN";
- }
-}
-
-static int cx23885_mbox_func(void *priv,
- u32 command,
- int in,
- int out,
- u32 data[CX2341X_MBOX_MAX_DATA])
-{
- struct cx23885_dev *dev = priv;
- unsigned long timeout;
- u32 value, flag, retval = 0;
- int i;
-
- dprintk(3, "%s: command(0x%X) = %s\n", __func__, command,
- cmd_to_str(command));
-
- /* this may not be 100% safe if we can't read any memory location
- without side effects */
- mc417_memory_read(dev, dev->cx23417_mailbox - 4, &value);
- if (value != 0x12345678) {
- printk(KERN_ERR
- "Firmware and/or mailbox pointer not initialized "
- "or corrupted, signature = 0x%x, cmd = %s\n", value,
- cmd_to_str(command));
- return -1;
- }
-
- /* This read looks at 32 bits, but flag is only 8 bits.
- * Seems we also bail if CMD or TIMEOUT bytes are set???
- */
- mc417_memory_read(dev, dev->cx23417_mailbox, &flag);
- if (flag) {
- printk(KERN_ERR "ERROR: Mailbox appears to be in use "
- "(%x), cmd = %s\n", flag, cmd_to_str(command));
- return -1;
- }
-
- flag |= 1; /* tell 'em we're working on it */
- mc417_memory_write(dev, dev->cx23417_mailbox, flag);
-
- /* write command + args + fill remaining with zeros */
- /* command code */
- mc417_memory_write(dev, dev->cx23417_mailbox + 1, command);
- mc417_memory_write(dev, dev->cx23417_mailbox + 3,
- IVTV_API_STD_TIMEOUT); /* timeout */
- for (i = 0; i < in; i++) {
- mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, data[i]);
- dprintk(3, "API Input %d = %d\n", i, data[i]);
- }
- for (; i < CX2341X_MBOX_MAX_DATA; i++)
- mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, 0);
-
- flag |= 3; /* tell 'em we're done writing */
- mc417_memory_write(dev, dev->cx23417_mailbox, flag);
-
- /* wait for firmware to handle the API command */
- timeout = jiffies + msecs_to_jiffies(10);
- for (;;) {
- mc417_memory_read(dev, dev->cx23417_mailbox, &flag);
- if (0 != (flag & 4))
- break;
- if (time_after(jiffies, timeout)) {
- printk(KERN_ERR "ERROR: API Mailbox timeout\n");
- return -1;
- }
- udelay(10);
- }
-
- /* read output values */
- for (i = 0; i < out; i++) {
- mc417_memory_read(dev, dev->cx23417_mailbox + 4 + i, data + i);
- dprintk(3, "API Output %d = %d\n", i, data[i]);
- }
-
- mc417_memory_read(dev, dev->cx23417_mailbox + 2, &retval);
- dprintk(3, "API result = %d\n", retval);
-
- flag = 0;
- mc417_memory_write(dev, dev->cx23417_mailbox, flag);
-
- return retval;
-}
-
-/* We don't need to call the API often, so using just one
- * mailbox will probably suffice
- */
-static int cx23885_api_cmd(struct cx23885_dev *dev,
- u32 command,
- u32 inputcnt,
- u32 outputcnt,
- ...)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- va_list vargs;
- int i, err;
-
- dprintk(3, "%s() cmds = 0x%08x\n", __func__, command);
-
- va_start(vargs, outputcnt);
- for (i = 0; i < inputcnt; i++)
- data[i] = va_arg(vargs, int);
-
- err = cx23885_mbox_func(dev, command, inputcnt, outputcnt, data);
- for (i = 0; i < outputcnt; i++) {
- int *vptr = va_arg(vargs, int *);
- *vptr = data[i];
- }
- va_end(vargs);
-
- return err;
-}
-
-static int cx23885_find_mailbox(struct cx23885_dev *dev)
-{
- u32 signature[4] = {
- 0x12345678, 0x34567812, 0x56781234, 0x78123456
- };
- int signaturecnt = 0;
- u32 value;
- int i;
-
- dprintk(2, "%s()\n", __func__);
-
- for (i = 0; i < CX23885_FIRM_IMAGE_SIZE; i++) {
- mc417_memory_read(dev, i, &value);
- if (value == signature[signaturecnt])
- signaturecnt++;
- else
- signaturecnt = 0;
- if (4 == signaturecnt) {
- dprintk(1, "Mailbox signature found at 0x%x\n", i+1);
- return i+1;
- }
- }
- printk(KERN_ERR "Mailbox signature values not found!\n");
- return -1;
-}
-
-static int cx23885_load_firmware(struct cx23885_dev *dev)
-{
- static const unsigned char magic[8] = {
- 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa
- };
- const struct firmware *firmware;
- int i, retval = 0;
- u32 value = 0;
- u32 gpio_output = 0;
- u32 gpio_value;
- u32 checksum = 0;
- u32 *dataptr;
-
- dprintk(2, "%s()\n", __func__);
-
- /* Save GPIO settings before reset of APU */
- retval |= mc417_memory_read(dev, 0x9020, &gpio_output);
- retval |= mc417_memory_read(dev, 0x900C, &gpio_value);
-
- retval = mc417_register_write(dev,
- IVTV_REG_VPU, 0xFFFFFFED);
- retval |= mc417_register_write(dev,
- IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
- retval |= mc417_register_write(dev,
- IVTV_REG_ENC_SDRAM_REFRESH, 0x80000800);
- retval |= mc417_register_write(dev,
- IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
- retval |= mc417_register_write(dev,
- IVTV_REG_APU, 0);
-
- if (retval != 0) {
- printk(KERN_ERR "%s: Error with mc417_register_write\n",
- __func__);
- return -1;
- }
-
- retval = request_firmware(&firmware, CX23885_FIRM_IMAGE_NAME,
- &dev->pci->dev);
-
- if (retval != 0) {
- printk(KERN_ERR
- "ERROR: Hotplug firmware request failed (%s).\n",
- CX23885_FIRM_IMAGE_NAME);
- printk(KERN_ERR "Please fix your hotplug setup, the board will "
- "not work without firmware loaded!\n");
- return -1;
- }
-
- if (firmware->size != CX23885_FIRM_IMAGE_SIZE) {
- printk(KERN_ERR "ERROR: Firmware size mismatch "
- "(have %zd, expected %d)\n",
- firmware->size, CX23885_FIRM_IMAGE_SIZE);
- release_firmware(firmware);
- return -1;
- }
-
- if (0 != memcmp(firmware->data, magic, 8)) {
- printk(KERN_ERR
- "ERROR: Firmware magic mismatch, wrong file?\n");
- release_firmware(firmware);
- return -1;
- }
-
- /* transfer to the chip */
- dprintk(2, "Loading firmware ...\n");
- dataptr = (u32 *)firmware->data;
- for (i = 0; i < (firmware->size >> 2); i++) {
- value = *dataptr;
- checksum += ~value;
- if (mc417_memory_write(dev, i, value) != 0) {
- printk(KERN_ERR "ERROR: Loading firmware failed!\n");
- release_firmware(firmware);
- return -1;
- }
- dataptr++;
- }
-
- /* read back to verify with the checksum */
- dprintk(1, "Verifying firmware ...\n");
- for (i--; i >= 0; i--) {
- if (mc417_memory_read(dev, i, &value) != 0) {
- printk(KERN_ERR "ERROR: Reading firmware failed!\n");
- release_firmware(firmware);
- return -1;
- }
- checksum -= ~value;
- }
- if (checksum) {
- printk(KERN_ERR
- "ERROR: Firmware load failed (checksum mismatch).\n");
- release_firmware(firmware);
- return -1;
- }
- release_firmware(firmware);
- dprintk(1, "Firmware upload successful.\n");
-
- retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS,
- IVTV_CMD_HW_BLOCKS_RST);
-
- /* F/W power up disturbs the GPIOs, restore state */
- retval |= mc417_register_write(dev, 0x9020, gpio_output);
- retval |= mc417_register_write(dev, 0x900C, gpio_value);
-
- retval |= mc417_register_read(dev, IVTV_REG_VPU, &value);
- retval |= mc417_register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFE8);
-
- /* Hardcoded GPIO's here */
- retval |= mc417_register_write(dev, 0x9020, 0x4000);
- retval |= mc417_register_write(dev, 0x900C, 0x4000);
-
- mc417_register_read(dev, 0x9020, &gpio_output);
- mc417_register_read(dev, 0x900C, &gpio_value);
-
- if (retval < 0)
- printk(KERN_ERR "%s: Error with mc417_register_write\n",
- __func__);
- return 0;
-}
-
-void cx23885_417_check_encoder(struct cx23885_dev *dev)
-{
- u32 status, seq;
-
- status = seq = 0;
- cx23885_api_cmd(dev, CX2341X_ENC_GET_SEQ_END, 0, 2, &status, &seq);
- dprintk(1, "%s() status = %d, seq = %d\n", __func__, status, seq);
-}
-
-static void cx23885_codec_settings(struct cx23885_dev *dev)
-{
- dprintk(1, "%s()\n", __func__);
-
- /* Dynamically change the height based on video standard */
- if (dev->encodernorm.id & V4L2_STD_525_60)
- dev->ts1.height = 480;
- else
- dev->ts1.height = 576;
-
- /* assign frame size */
- cx23885_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
- dev->ts1.height, dev->ts1.width);
-
- dev->mpeg_params.width = dev->ts1.width;
- dev->mpeg_params.height = dev->ts1.height;
- dev->mpeg_params.is_50hz =
- (dev->encodernorm.id & V4L2_STD_625_50) != 0;
-
- cx2341x_update(dev, cx23885_mbox_func, NULL, &dev->mpeg_params);
-
- cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1);
- cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1);
-}
-
-static int cx23885_initialize_codec(struct cx23885_dev *dev, int startencoder)
-{
- int version;
- int retval;
- u32 i, data[7];
-
- dprintk(1, "%s()\n", __func__);
-
- retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
- if (retval < 0) {
- dprintk(2, "%s() PING OK\n", __func__);
- retval = cx23885_load_firmware(dev);
- if (retval < 0) {
- printk(KERN_ERR "%s() f/w load failed\n", __func__);
- return retval;
- }
- retval = cx23885_find_mailbox(dev);
- if (retval < 0) {
- printk(KERN_ERR "%s() mailbox < 0, error\n",
- __func__);
- return -1;
- }
- dev->cx23417_mailbox = retval;
- retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0);
- if (retval < 0) {
- printk(KERN_ERR
- "ERROR: cx23417 firmware ping failed!\n");
- return -1;
- }
- retval = cx23885_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1,
- &version);
- if (retval < 0) {
- printk(KERN_ERR "ERROR: cx23417 firmware get encoder :"
- "version failed!\n");
- return -1;
- }
- dprintk(1, "cx23417 firmware version is 0x%08x\n", version);
- msleep(200);
- }
-
- cx23885_codec_settings(dev);
- msleep(60);
-
- cx23885_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0,
- CX23885_FIELD1_SAA7115, CX23885_FIELD2_SAA7115);
- cx23885_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0,
- CX23885_CUSTOM_EXTENSION_USR_DATA, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0);
-
- /* Setup to capture VBI */
- data[0] = 0x0001BD00;
- data[1] = 1; /* frames per interrupt */
- data[2] = 4; /* total bufs */
- data[3] = 0x91559155; /* start codes */
- data[4] = 0x206080C0; /* stop codes */
- data[5] = 6; /* lines */
- data[6] = 64; /* BPL */
-
- cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_CONFIG, 7, 0, data[0], data[1],
- data[2], data[3], data[4], data[5], data[6]);
-
- for (i = 2; i <= 24; i++) {
- int valid;
-
- valid = ((i >= 19) && (i <= 21));
- cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, i,
- valid, 0 , 0, 0);
- cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0,
- i | 0x80000000, valid, 0, 0, 0);
- }
-
- cx23885_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, CX23885_UNMUTE);
- msleep(60);
-
- /* initialize the video input */
- cx23885_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
- msleep(60);
-
- /* Enable VIP style pixel invalidation so we work with scaled mode */
- mc417_memory_write(dev, 2120, 0x00000080);
-
- /* start capturing to the host interface */
- if (startencoder) {
- cx23885_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0,
- CX23885_MPEG_CAPTURE, CX23885_RAW_BITS_NONE);
- msleep(10);
- }
-
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int bb_buf_setup(struct videobuf_queue *q,
- unsigned int *count, unsigned int *size)
-{
- struct cx23885_fh *fh = q->priv_data;
-
- fh->dev->ts1.ts_packet_size = mpeglinesize;
- fh->dev->ts1.ts_packet_count = mpeglines;
-
- *size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count;
- *count = mpegbufs;
-
- return 0;
-}
-
-static int bb_buf_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb, enum v4l2_field field)
-{
- struct cx23885_fh *fh = q->priv_data;
- return cx23885_buf_prepare(q, &fh->dev->ts1,
- (struct cx23885_buffer *)vb,
- field);
-}
-
-static void bb_buf_queue(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- struct cx23885_fh *fh = q->priv_data;
- cx23885_buf_queue(&fh->dev->ts1, (struct cx23885_buffer *)vb);
-}
-
-static void bb_buf_release(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
-}
-
-static struct videobuf_queue_ops cx23885_qops = {
- .buf_setup = bb_buf_setup,
- .buf_prepare = bb_buf_prepare,
- .buf_queue = bb_buf_queue,
- .buf_release = bb_buf_release,
-};
-
-/* ------------------------------------------------------------------ */
-
-static const u32 *ctrl_classes[] = {
- cx2341x_mpeg_ctrls,
- NULL
-};
-
-static int cx23885_queryctrl(struct cx23885_dev *dev,
- struct v4l2_queryctrl *qctrl)
-{
- qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
- if (qctrl->id == 0)
- return -EINVAL;
-
- /* MPEG V4L2 controls */
- if (cx2341x_ctrl_query(&dev->mpeg_params, qctrl))
- qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
-
- return 0;
-}
-
-static int cx23885_querymenu(struct cx23885_dev *dev,
- struct v4l2_querymenu *qmenu)
-{
- struct v4l2_queryctrl qctrl;
-
- qctrl.id = qmenu->id;
- cx23885_queryctrl(dev, &qctrl);
- return v4l2_ctrl_query_menu(qmenu, &qctrl,
- cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id));
-}
-
-static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
-
- call_all(dev, core, g_std, id);
-
- return 0;
-}
-
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++)
- if (*id & cx23885_tvnorms[i].id)
- break;
- if (i == ARRAY_SIZE(cx23885_tvnorms))
- return -EINVAL;
- dev->encodernorm = cx23885_tvnorms[i];
-
- /* Have the drier core notify the subdevices */
- mutex_lock(&dev->lock);
- cx23885_set_tvnorm(dev, *id);
- mutex_unlock(&dev->lock);
-
- return 0;
-}
-
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
- dprintk(1, "%s()\n", __func__);
- return cx23885_enum_input(dev, i);
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- return cx23885_get_input(file, priv, i);
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- return cx23885_set_input(file, priv, i);
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
-
- if (UNSET == dev->tuner_type)
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
- strcpy(t->name, "Television");
- call_all(dev, tuner, g_tuner, t);
-
- dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
-
- return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
-
- if (UNSET == dev->tuner_type)
- return -EINVAL;
-
- /* Update the A/V core */
- call_all(dev, tuner, s_tuner, t);
-
- return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
-
- if (UNSET == dev->tuner_type)
- return -EINVAL;
- f->type = V4L2_TUNER_ANALOG_TV;
- f->frequency = dev->freq;
-
- call_all(dev, tuner, g_frequency, f);
-
- return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- return cx23885_set_frequency(file, priv, f);
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
- return cx23885_get_control(dev, ctl);
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
- return cx23885_set_control(dev, ctl);
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
- struct cx23885_tsport *tsport = &dev->ts1;
-
- strlcpy(cap->driver, dev->name, sizeof(cap->driver));
- strlcpy(cap->card, cx23885_boards[tsport->dev->board].name,
- sizeof(cap->card));
- sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
- cap->capabilities =
- V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING |
- 0;
- if (UNSET != dev->tuner_type)
- cap->capabilities |= V4L2_CAP_TUNER;
-
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (f->index != 0)
- return -EINVAL;
-
- strlcpy(f->description, "MPEG", sizeof(f->description));
- f->pixelformat = V4L2_PIX_FMT_MPEG;
-
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
- f->fmt.pix.colorspace = 0;
- f->fmt.pix.width = dev->ts1.width;
- f->fmt.pix.height = dev->ts1.height;
- f->fmt.pix.field = fh->mpegq.field;
- dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
- dev->ts1.width, dev->ts1.height, fh->mpegq.field);
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
- f->fmt.pix.colorspace = 0;
- dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
- dev->ts1.width, dev->ts1.height, fh->mpegq.field);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
- f->fmt.pix.colorspace = 0;
- dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
- f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
- return 0;
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct cx23885_fh *fh = file->private_data;
-
- return videobuf_reqbufs(&fh->mpegq, p);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct cx23885_fh *fh = file->private_data;
-
- return videobuf_querybuf(&fh->mpegq, p);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct cx23885_fh *fh = file->private_data;
-
- return videobuf_qbuf(&fh->mpegq, p);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct cx23885_fh *fh = priv;
-
- return videobuf_dqbuf(&fh->mpegq, b, file->f_flags & O_NONBLOCK);
-}
-
-
-static int vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type i)
-{
- struct cx23885_fh *fh = file->private_data;
-
- return videobuf_streamon(&fh->mpegq);
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx23885_fh *fh = file->private_data;
-
- return videobuf_streamoff(&fh->mpegq);
-}
-
-static int vidioc_g_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *f)
-{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
-
- if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
- return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, VIDIOC_G_EXT_CTRLS);
-}
-
-static int vidioc_s_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *f)
-{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
- struct cx2341x_mpeg_params p;
- int err;
-
- if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
-
- p = dev->mpeg_params;
- err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS);
-
- if (err == 0) {
- err = cx2341x_update(dev, cx23885_mbox_func,
- &dev->mpeg_params, &p);
- dev->mpeg_params = p;
- }
- return err;
-}
-
-static int vidioc_try_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *f)
-{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
- struct cx2341x_mpeg_params p;
- int err;
-
- if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
-
- p = dev->mpeg_params;
- err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS);
- return err;
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
- char name[32 + 2];
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO
- "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- call_all(dev, core, log_status);
- cx2341x_log_status(&dev->mpeg_params, name);
- printk(KERN_INFO
- "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_querymenu(struct file *file, void *priv,
- struct v4l2_querymenu *a)
-{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
-
- return cx23885_querymenu(dev, a);
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *c)
-{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
-
- return cx23885_queryctrl(dev, c);
-}
-
-static int mpeg_open(struct file *file)
-{
- struct cx23885_dev *dev = video_drvdata(file);
- struct cx23885_fh *fh;
-
- dprintk(2, "%s()\n", __func__);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (!fh)
- return -ENOMEM;
-
- file->private_data = fh;
- fh->dev = dev;
-
- videobuf_queue_sg_init(&fh->mpegq, &cx23885_qops,
- &dev->pci->dev, &dev->ts1.slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx23885_buffer),
- fh, NULL);
- return 0;
-}
-
-static int mpeg_release(struct file *file)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
-
- dprintk(2, "%s()\n", __func__);
-
- /* FIXME: Review this crap */
- /* Shut device down on last close */
- if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
- if (atomic_dec_return(&dev->v4l_reader_count) == 0) {
- /* stop mpeg capture */
- cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
- CX23885_END_NOW, CX23885_MPEG_CAPTURE,
- CX23885_RAW_BITS_NONE);
-
- msleep(500);
- cx23885_417_check_encoder(dev);
-
- cx23885_cancel_buffers(&fh->dev->ts1);
- }
- }
-
- if (fh->mpegq.streaming)
- videobuf_streamoff(&fh->mpegq);
- if (fh->mpegq.reading)
- videobuf_read_stop(&fh->mpegq);
-
- videobuf_mmap_free(&fh->mpegq);
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-static ssize_t mpeg_read(struct file *file, char __user *data,
- size_t count, loff_t *ppos)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
-
- dprintk(2, "%s()\n", __func__);
-
- /* Deal w/ A/V decoder * and mpeg encoder sync issues. */
- /* Start mpeg encoder on first read. */
- if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
- if (atomic_inc_return(&dev->v4l_reader_count) == 1) {
- if (cx23885_initialize_codec(dev, 1) < 0)
- return -EINVAL;
- }
- }
-
- return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0,
- file->f_flags & O_NONBLOCK);
-}
-
-static unsigned int mpeg_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
-
- dprintk(2, "%s\n", __func__);
-
- return videobuf_poll_stream(file, &fh->mpegq, wait);
-}
-
-static int mpeg_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
-
- dprintk(2, "%s()\n", __func__);
-
- return videobuf_mmap_mapper(&fh->mpegq, vma);
-}
-
-static struct v4l2_file_operations mpeg_fops = {
- .owner = THIS_MODULE,
- .open = mpeg_open,
- .release = mpeg_release,
- .read = mpeg_read,
- .poll = mpeg_poll,
- .mmap = mpeg_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
- .vidioc_querystd = vidioc_g_std,
- .vidioc_g_std = vidioc_g_std,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
- .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
- .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_querymenu = vidioc_querymenu,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_chip_ident = cx23885_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx23885_g_register,
- .vidioc_s_register = cx23885_s_register,
-#endif
-};
-
-static struct video_device cx23885_mpeg_template = {
- .name = "cx23885",
- .fops = &mpeg_fops,
- .ioctl_ops = &mpeg_ioctl_ops,
- .tvnorms = CX23885_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
-
-void cx23885_417_unregister(struct cx23885_dev *dev)
-{
- dprintk(1, "%s()\n", __func__);
-
- if (dev->v4l_device) {
- if (video_is_registered(dev->v4l_device))
- video_unregister_device(dev->v4l_device);
- else
- video_device_release(dev->v4l_device);
- dev->v4l_device = NULL;
- }
-}
-
-static struct video_device *cx23885_video_dev_alloc(
- struct cx23885_tsport *tsport,
- struct pci_dev *pci,
- struct video_device *template,
- char *type)
-{
- struct video_device *vfd;
- struct cx23885_dev *dev = tsport->dev;
-
- dprintk(1, "%s()\n", __func__);
-
- vfd = video_device_alloc();
- if (NULL == vfd)
- return NULL;
- *vfd = *template;
- snprintf(vfd->name, sizeof(vfd->name), "%s (%s)",
- cx23885_boards[tsport->dev->board].name, type);
- vfd->parent = &pci->dev;
- vfd->release = video_device_release;
- return vfd;
-}
-
-int cx23885_417_register(struct cx23885_dev *dev)
-{
- /* FIXME: Port1 hardcoded here */
- int err = -ENODEV;
- struct cx23885_tsport *tsport = &dev->ts1;
-
- dprintk(1, "%s()\n", __func__);
-
- if (cx23885_boards[dev->board].portb != CX23885_MPEG_ENCODER)
- return err;
-
- /* Set default TV standard */
- dev->encodernorm = cx23885_tvnorms[0];
-
- if (dev->encodernorm.id & V4L2_STD_525_60)
- tsport->height = 480;
- else
- tsport->height = 576;
-
- tsport->width = 720;
- cx2341x_fill_defaults(&dev->mpeg_params);
-
- dev->mpeg_params.port = CX2341X_PORT_SERIAL;
-
- /* Allocate and initialize V4L video device */
- dev->v4l_device = cx23885_video_dev_alloc(tsport,
- dev->pci, &cx23885_mpeg_template, "mpeg");
- video_set_drvdata(dev->v4l_device, dev);
- err = video_register_device(dev->v4l_device,
- VFL_TYPE_GRABBER, -1);
- if (err < 0) {
- printk(KERN_INFO "%s: can't register mpeg device\n", dev->name);
- return err;
- }
-
- printk(KERN_INFO "%s: registered device %s [mpeg]\n",
- dev->name, video_device_node_name(dev->v4l_device));
-
- /* ST: Configure the encoder paramaters, but don't begin
- * encoding, this resolves an issue where the first time the
- * encoder is started video can be choppy.
- */
- cx23885_initialize_codec(dev, 0);
-
- return 0;
-}
diff --git a/drivers/media/video/cx23885/cx23885-alsa.c b/drivers/media/video/cx23885/cx23885-alsa.c
deleted file mode 100644
index 795169237e7..00000000000
--- a/drivers/media/video/cx23885/cx23885-alsa.c
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- *
- * Support for CX23885 analog audio capture
- *
- * (c) 2008 Mijhail Moreyra <mijhail.moreyra@gmail.com>
- * Adapted from cx88-alsa.c
- * (c) 2009 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/vmalloc.h>
-#include <linux/dma-mapping.h>
-#include <linux/pci.h>
-
-#include <asm/delay.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/control.h>
-#include <sound/initval.h>
-
-#include <sound/tlv.h>
-
-
-#include "cx23885.h"
-#include "cx23885-reg.h"
-
-#define AUDIO_SRAM_CHANNEL SRAM_CH07
-
-#define dprintk(level, fmt, arg...) if (audio_debug >= level) \
- printk(KERN_INFO "%s: " fmt, chip->dev->name , ## arg)
-
-#define dprintk_core(level, fmt, arg...) if (audio_debug >= level) \
- printk(KERN_DEBUG "%s: " fmt, chip->dev->name , ## arg)
-
-/****************************************************************************
- Module global static vars
- ****************************************************************************/
-
-static unsigned int disable_analog_audio;
-module_param(disable_analog_audio, int, 0644);
-MODULE_PARM_DESC(disable_analog_audio, "disable analog audio ALSA driver");
-
-static unsigned int audio_debug;
-module_param(audio_debug, int, 0644);
-MODULE_PARM_DESC(audio_debug, "enable debug messages [analog audio]");
-
-/****************************************************************************
- Board specific funtions
- ****************************************************************************/
-
-/* Constants taken from cx88-reg.h */
-#define AUD_INT_DN_RISCI1 (1 << 0)
-#define AUD_INT_UP_RISCI1 (1 << 1)
-#define AUD_INT_RDS_DN_RISCI1 (1 << 2)
-#define AUD_INT_DN_RISCI2 (1 << 4) /* yes, 3 is skipped */
-#define AUD_INT_UP_RISCI2 (1 << 5)
-#define AUD_INT_RDS_DN_RISCI2 (1 << 6)
-#define AUD_INT_DN_SYNC (1 << 12)
-#define AUD_INT_UP_SYNC (1 << 13)
-#define AUD_INT_RDS_DN_SYNC (1 << 14)
-#define AUD_INT_OPC_ERR (1 << 16)
-#define AUD_INT_BER_IRQ (1 << 20)
-#define AUD_INT_MCHG_IRQ (1 << 21)
-#define GP_COUNT_CONTROL_RESET 0x3
-
-/*
- * BOARD Specific: Sets audio DMA
- */
-
-static int cx23885_start_audio_dma(struct cx23885_audio_dev *chip)
-{
- struct cx23885_audio_buffer *buf = chip->buf;
- struct cx23885_dev *dev = chip->dev;
- struct sram_channel *audio_ch =
- &dev->sram_channels[AUDIO_SRAM_CHANNEL];
-
- dprintk(1, "%s()\n", __func__);
-
- /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */
- cx_clear(AUD_INT_DMA_CTL, 0x11);
-
- /* setup fifo + format - out channel */
- cx23885_sram_channel_setup(chip->dev, audio_ch, buf->bpl,
- buf->risc.dma);
-
- /* sets bpl size */
- cx_write(AUD_INT_A_LNGTH, buf->bpl);
-
- /* This is required to get good audio (1 seems to be ok) */
- cx_write(AUD_INT_A_MODE, 1);
-
- /* reset counter */
- cx_write(AUD_INT_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET);
- atomic_set(&chip->count, 0);
-
- dprintk(1, "Start audio DMA, %d B/line, %d lines/FIFO, %d periods, %d "
- "byte buffer\n", buf->bpl, cx_read(audio_ch->cmds_start+12)>>1,
- chip->num_periods, buf->bpl * chip->num_periods);
-
- /* Enables corresponding bits at AUD_INT_STAT */
- cx_write(AUDIO_INT_INT_MSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC |
- AUD_INT_DN_RISCI1);
-
- /* Clean any pending interrupt bits already set */
- cx_write(AUDIO_INT_INT_STAT, ~0);
-
- /* enable audio irqs */
- cx_set(PCI_INT_MSK, chip->dev->pci_irqmask | PCI_MSK_AUD_INT);
-
- /* start dma */
- cx_set(DEV_CNTRL2, (1<<5)); /* Enables Risc Processor */
- cx_set(AUD_INT_DMA_CTL, 0x11); /* audio downstream FIFO and
- RISC enable */
- if (audio_debug)
- cx23885_sram_channel_dump(chip->dev, audio_ch);
-
- return 0;
-}
-
-/*
- * BOARD Specific: Resets audio DMA
- */
-static int cx23885_stop_audio_dma(struct cx23885_audio_dev *chip)
-{
- struct cx23885_dev *dev = chip->dev;
- dprintk(1, "Stopping audio DMA\n");
-
- /* stop dma */
- cx_clear(AUD_INT_DMA_CTL, 0x11);
-
- /* disable irqs */
- cx_clear(PCI_INT_MSK, PCI_MSK_AUD_INT);
- cx_clear(AUDIO_INT_INT_MSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC |
- AUD_INT_DN_RISCI1);
-
- if (audio_debug)
- cx23885_sram_channel_dump(chip->dev,
- &dev->sram_channels[AUDIO_SRAM_CHANNEL]);
-
- return 0;
-}
-
-/*
- * BOARD Specific: Handles audio IRQ
- */
-int cx23885_audio_irq(struct cx23885_dev *dev, u32 status, u32 mask)
-{
- struct cx23885_audio_dev *chip = dev->audio_dev;
-
- if (0 == (status & mask))
- return 0;
-
- cx_write(AUDIO_INT_INT_STAT, status);
-
- /* risc op code error */
- if (status & AUD_INT_OPC_ERR) {
- printk(KERN_WARNING "%s/1: Audio risc op code error\n",
- dev->name);
- cx_clear(AUD_INT_DMA_CTL, 0x11);
- cx23885_sram_channel_dump(dev,
- &dev->sram_channels[AUDIO_SRAM_CHANNEL]);
- }
- if (status & AUD_INT_DN_SYNC) {
- dprintk(1, "Downstream sync error\n");
- cx_write(AUD_INT_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET);
- return 1;
- }
- /* risc1 downstream */
- if (status & AUD_INT_DN_RISCI1) {
- atomic_set(&chip->count, cx_read(AUD_INT_A_GPCNT));
- snd_pcm_period_elapsed(chip->substream);
- }
- /* FIXME: Any other status should deserve a special handling? */
-
- return 1;
-}
-
-static int dsp_buffer_free(struct cx23885_audio_dev *chip)
-{
- BUG_ON(!chip->dma_size);
-
- dprintk(2, "Freeing buffer\n");
- videobuf_dma_unmap(&chip->pci->dev, chip->dma_risc);
- videobuf_dma_free(chip->dma_risc);
- btcx_riscmem_free(chip->pci, &chip->buf->risc);
- kfree(chip->buf);
-
- chip->dma_risc = NULL;
- chip->dma_size = 0;
-
- return 0;
-}
-
-/****************************************************************************
- ALSA PCM Interface
- ****************************************************************************/
-
-/*
- * Digital hardware definition
- */
-#define DEFAULT_FIFO_SIZE 4096
-
-static struct snd_pcm_hardware snd_cx23885_digital_hw = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
-
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- /* Analog audio output will be full of clicks and pops if there
- are not exactly four lines in the SRAM FIFO buffer. */
- .period_bytes_min = DEFAULT_FIFO_SIZE/4,
- .period_bytes_max = DEFAULT_FIFO_SIZE/4,
- .periods_min = 1,
- .periods_max = 1024,
- .buffer_bytes_max = (1024*1024),
-};
-
-/*
- * audio pcm capture open callback
- */
-static int snd_cx23885_pcm_open(struct snd_pcm_substream *substream)
-{
- struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- if (!chip) {
- printk(KERN_ERR "BUG: cx23885 can't find device struct."
- " Can't proceed with open\n");
- return -ENODEV;
- }
-
- err = snd_pcm_hw_constraint_pow2(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0)
- goto _error;
-
- chip->substream = substream;
-
- runtime->hw = snd_cx23885_digital_hw;
-
- if (chip->dev->sram_channels[AUDIO_SRAM_CHANNEL].fifo_size !=
- DEFAULT_FIFO_SIZE) {
- unsigned int bpl = chip->dev->
- sram_channels[AUDIO_SRAM_CHANNEL].fifo_size / 4;
- bpl &= ~7; /* must be multiple of 8 */
- runtime->hw.period_bytes_min = bpl;
- runtime->hw.period_bytes_max = bpl;
- }
-
- return 0;
-_error:
- dprintk(1, "Error opening PCM!\n");
- return err;
-}
-
-/*
- * audio close callback
- */
-static int snd_cx23885_close(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-/*
- * hw_params callback
- */
-static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream);
- struct videobuf_dmabuf *dma;
-
- struct cx23885_audio_buffer *buf;
- int ret;
-
- if (substream->runtime->dma_area) {
- dsp_buffer_free(chip);
- substream->runtime->dma_area = NULL;
- }
-
- chip->period_size = params_period_bytes(hw_params);
- chip->num_periods = params_periods(hw_params);
- chip->dma_size = chip->period_size * params_periods(hw_params);
-
- BUG_ON(!chip->dma_size);
- BUG_ON(chip->num_periods & (chip->num_periods-1));
-
- buf = kzalloc(sizeof(*buf), GFP_KERNEL);
- if (NULL == buf)
- return -ENOMEM;
-
- buf->bpl = chip->period_size;
-
- dma = &buf->dma;
- videobuf_dma_init(dma);
- ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
- (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT));
- if (ret < 0)
- goto error;
-
- ret = videobuf_dma_map(&chip->pci->dev, dma);
- if (ret < 0)
- goto error;
-
- ret = cx23885_risc_databuffer(chip->pci, &buf->risc, dma->sglist,
- chip->period_size, chip->num_periods, 1);
- if (ret < 0)
- goto error;
-
- /* Loop back to start of program */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP|RISC_IRQ1|RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- chip->buf = buf;
- chip->dma_risc = dma;
-
- substream->runtime->dma_area = chip->dma_risc->vaddr;
- substream->runtime->dma_bytes = chip->dma_size;
- substream->runtime->dma_addr = 0;
-
- return 0;
-
-error:
- kfree(buf);
- return ret;
-}
-
-/*
- * hw free callback
- */
-static int snd_cx23885_hw_free(struct snd_pcm_substream *substream)
-{
-
- struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream);
-
- if (substream->runtime->dma_area) {
- dsp_buffer_free(chip);
- substream->runtime->dma_area = NULL;
- }
-
- return 0;
-}
-
-/*
- * prepare callback
- */
-static int snd_cx23885_prepare(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-/*
- * trigger callback
- */
-static int snd_cx23885_card_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream);
- int err;
-
- /* Local interrupts are already disabled by ALSA */
- spin_lock(&chip->lock);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- err = cx23885_start_audio_dma(chip);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- err = cx23885_stop_audio_dma(chip);
- break;
- default:
- err = -EINVAL;
- break;
- }
-
- spin_unlock(&chip->lock);
-
- return err;
-}
-
-/*
- * pointer callback
- */
-static snd_pcm_uframes_t snd_cx23885_pointer(
- struct snd_pcm_substream *substream)
-{
- struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- u16 count;
-
- count = atomic_read(&chip->count);
-
- return runtime->period_size * (count & (runtime->periods-1));
-}
-
-/*
- * page callback (needed for mmap)
- */
-static struct page *snd_cx23885_page(struct snd_pcm_substream *substream,
- unsigned long offset)
-{
- void *pageptr = substream->runtime->dma_area + offset;
- return vmalloc_to_page(pageptr);
-}
-
-/*
- * operators
- */
-static struct snd_pcm_ops snd_cx23885_pcm_ops = {
- .open = snd_cx23885_pcm_open,
- .close = snd_cx23885_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cx23885_hw_params,
- .hw_free = snd_cx23885_hw_free,
- .prepare = snd_cx23885_prepare,
- .trigger = snd_cx23885_card_trigger,
- .pointer = snd_cx23885_pointer,
- .page = snd_cx23885_page,
-};
-
-/*
- * create a PCM device
- */
-static int snd_cx23885_pcm(struct cx23885_audio_dev *chip, int device,
- char *name)
-{
- int err;
- struct snd_pcm *pcm;
-
- err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
- if (err < 0)
- return err;
- pcm->private_data = chip;
- strcpy(pcm->name, name);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx23885_pcm_ops);
-
- return 0;
-}
-
-/****************************************************************************
- Basic Flow for Sound Devices
- ****************************************************************************/
-
-/*
- * Alsa Constructor - Component probe
- */
-
-struct cx23885_audio_dev *cx23885_audio_register(struct cx23885_dev *dev)
-{
- struct snd_card *card;
- struct cx23885_audio_dev *chip;
- int err;
-
- if (disable_analog_audio)
- return NULL;
-
- if (dev->sram_channels[AUDIO_SRAM_CHANNEL].cmds_start == 0) {
- printk(KERN_WARNING "%s(): Missing SRAM channel configuration "
- "for analog TV Audio\n", __func__);
- return NULL;
- }
-
- err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
- THIS_MODULE, sizeof(struct cx23885_audio_dev), &card);
- if (err < 0)
- goto error;
-
- chip = (struct cx23885_audio_dev *) card->private_data;
- chip->dev = dev;
- chip->pci = dev->pci;
- chip->card = card;
- spin_lock_init(&chip->lock);
-
- snd_card_set_dev(card, &dev->pci->dev);
-
- err = snd_cx23885_pcm(chip, 0, "CX23885 Digital");
- if (err < 0)
- goto error;
-
- strcpy(card->driver, "CX23885");
- sprintf(card->shortname, "Conexant CX23885");
- sprintf(card->longname, "%s at %s", card->shortname, dev->name);
-
- err = snd_card_register(card);
- if (err < 0)
- goto error;
-
- dprintk(0, "registered ALSA audio device\n");
-
- return chip;
-
-error:
- snd_card_free(card);
- printk(KERN_ERR "%s(): Failed to register analog "
- "audio adapter\n", __func__);
-
- return NULL;
-}
-
-/*
- * ALSA destructor
- */
-void cx23885_audio_unregister(struct cx23885_dev *dev)
-{
- struct cx23885_audio_dev *chip = dev->audio_dev;
-
- snd_card_free(chip->card);
-}
diff --git a/drivers/media/video/cx23885/cx23885-av.c b/drivers/media/video/cx23885/cx23885-av.c
deleted file mode 100644
index 134ebddd860..00000000000
--- a/drivers/media/video/cx23885/cx23885-av.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Driver for the Conexant CX23885/7/8 PCIe bridge
- *
- * AV device support routines - non-input, non-vl42_subdev routines
- *
- * Copyright (C) 2010 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include "cx23885.h"
-
-void cx23885_av_work_handler(struct work_struct *work)
-{
- struct cx23885_dev *dev =
- container_of(work, struct cx23885_dev, cx25840_work);
- bool handled;
-
- v4l2_subdev_call(dev->sd_cx25840, core, interrupt_service_routine,
- PCI_MSK_AV_CORE, &handled);
- cx23885_irq_enable(dev, PCI_MSK_AV_CORE);
-}
diff --git a/drivers/media/video/cx23885/cx23885-av.h b/drivers/media/video/cx23885/cx23885-av.h
deleted file mode 100644
index d2915c3e53a..00000000000
--- a/drivers/media/video/cx23885/cx23885-av.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Driver for the Conexant CX23885/7/8 PCIe bridge
- *
- * AV device support routines - non-input, non-vl42_subdev routines
- *
- * Copyright (C) 2010 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#ifndef _CX23885_AV_H_
-#define _CX23885_AV_H_
-void cx23885_av_work_handler(struct work_struct *work);
-#endif
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
deleted file mode 100644
index 080e11157e5..00000000000
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ /dev/null
@@ -1,1680 +0,0 @@
-/*
- * Driver for the Conexant CX23885 PCIe bridge
- *
- * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <media/cx25840.h>
-#include <linux/firmware.h>
-#include <misc/altera.h>
-
-#include "cx23885.h"
-#include "tuner-xc2028.h"
-#include "netup-eeprom.h"
-#include "netup-init.h"
-#include "altera-ci.h"
-#include "xc4000.h"
-#include "xc5000.h"
-#include "cx23888-ir.h"
-
-static unsigned int netup_card_rev = 1;
-module_param(netup_card_rev, int, 0644);
-MODULE_PARM_DESC(netup_card_rev,
- "NetUP Dual DVB-T/C CI card revision");
-static unsigned int enable_885_ir;
-module_param(enable_885_ir, int, 0644);
-MODULE_PARM_DESC(enable_885_ir,
- "Enable integrated IR controller for supported\n"
- "\t\t CX2388[57] boards that are wired for it:\n"
- "\t\t\tHVR-1250 (reported safe)\n"
- "\t\t\tTeVii S470 (reported unsafe)\n"
- "\t\t This can cause an interrupt storm with some cards.\n"
- "\t\t Default: 0 [Disabled]");
-
-/* ------------------------------------------------------------------ */
-/* board config info */
-
-struct cx23885_board cx23885_boards[] = {
- [CX23885_BOARD_UNKNOWN] = {
- .name = "UNKNOWN/GENERIC",
- /* Ensure safe default for unknown boards */
- .clk_freq = 0,
- .input = {{
- .type = CX23885_VMUX_COMPOSITE1,
- .vmux = 0,
- }, {
- .type = CX23885_VMUX_COMPOSITE2,
- .vmux = 1,
- }, {
- .type = CX23885_VMUX_COMPOSITE3,
- .vmux = 2,
- }, {
- .type = CX23885_VMUX_COMPOSITE4,
- .vmux = 3,
- } },
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1800lp] = {
- .name = "Hauppauge WinTV-HVR1800lp",
- .portc = CX23885_MPEG_DVB,
- .input = {{
- .type = CX23885_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0xff00,
- }, {
- .type = CX23885_VMUX_DEBUG,
- .vmux = 0,
- .gpio0 = 0xff01,
- }, {
- .type = CX23885_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0xff02,
- }, {
- .type = CX23885_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0xff02,
- } },
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1800] = {
- .name = "Hauppauge WinTV-HVR1800",
- .porta = CX23885_ANALOG_VIDEO,
- .portb = CX23885_MPEG_ENCODER,
- .portc = CX23885_MPEG_DVB,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .tuner_addr = 0x42, /* 0x84 >> 1 */
- .tuner_bus = 1,
- .input = {{
- .type = CX23885_VMUX_TELEVISION,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN5_CH2 |
- CX25840_VIN2_CH1,
- .amux = CX25840_AUDIO8,
- .gpio0 = 0,
- }, {
- .type = CX23885_VMUX_COMPOSITE1,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN4_CH2 |
- CX25840_VIN6_CH1,
- .amux = CX25840_AUDIO7,
- .gpio0 = 0,
- }, {
- .type = CX23885_VMUX_SVIDEO,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN4_CH2 |
- CX25840_VIN8_CH1 |
- CX25840_SVIDEO_ON,
- .amux = CX25840_AUDIO7,
- .gpio0 = 0,
- } },
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1250] = {
- .name = "Hauppauge WinTV-HVR1250",
- .porta = CX23885_ANALOG_VIDEO,
- .portc = CX23885_MPEG_DVB,
-#ifdef MT2131_NO_ANALOG_SUPPORT_YET
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .tuner_addr = 0x42, /* 0x84 >> 1 */
- .tuner_bus = 1,
-#endif
- .force_bff = 1,
- .input = {{
-#ifdef MT2131_NO_ANALOG_SUPPORT_YET
- .type = CX23885_VMUX_TELEVISION,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN5_CH2 |
- CX25840_VIN2_CH1,
- .amux = CX25840_AUDIO8,
- .gpio0 = 0xff00,
- }, {
-#endif
- .type = CX23885_VMUX_COMPOSITE1,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN4_CH2 |
- CX25840_VIN6_CH1,
- .amux = CX25840_AUDIO7,
- .gpio0 = 0xff02,
- }, {
- .type = CX23885_VMUX_SVIDEO,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN4_CH2 |
- CX25840_VIN8_CH1 |
- CX25840_SVIDEO_ON,
- .amux = CX25840_AUDIO7,
- .gpio0 = 0xff02,
- } },
- },
- [CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP] = {
- .name = "DViCO FusionHDTV5 Express",
- .portb = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1500Q] = {
- .name = "Hauppauge WinTV-HVR1500Q",
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1500] = {
- .name = "Hauppauge WinTV-HVR1500",
- .porta = CX23885_ANALOG_VIDEO,
- .portc = CX23885_MPEG_DVB,
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0x61, /* 0xc2 >> 1 */
- .input = {{
- .type = CX23885_VMUX_TELEVISION,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN5_CH2 |
- CX25840_VIN2_CH1,
- .gpio0 = 0,
- }, {
- .type = CX23885_VMUX_COMPOSITE1,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN4_CH2 |
- CX25840_VIN6_CH1,
- .gpio0 = 0,
- }, {
- .type = CX23885_VMUX_SVIDEO,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN4_CH2 |
- CX25840_VIN8_CH1 |
- CX25840_SVIDEO_ON,
- .gpio0 = 0,
- } },
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1200] = {
- .name = "Hauppauge WinTV-HVR1200",
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1700] = {
- .name = "Hauppauge WinTV-HVR1700",
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1400] = {
- .name = "Hauppauge WinTV-HVR1400",
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP] = {
- .name = "DViCO FusionHDTV7 Dual Express",
- .portb = CX23885_MPEG_DVB,
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP] = {
- .name = "DViCO FusionHDTV DVB-T Dual Express",
- .portb = CX23885_MPEG_DVB,
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H] = {
- .name = "Leadtek Winfast PxDVR3200 H",
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000] = {
- .name = "Leadtek Winfast PxDVR3200 H XC4000",
- .porta = CX23885_ANALOG_VIDEO,
- .portc = CX23885_MPEG_DVB,
- .tuner_type = TUNER_XC4000,
- .tuner_addr = 0x61,
- .radio_type = UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX23885_VMUX_TELEVISION,
- .vmux = CX25840_VIN2_CH1 |
- CX25840_VIN5_CH2 |
- CX25840_NONE0_CH3,
- }, {
- .type = CX23885_VMUX_COMPOSITE1,
- .vmux = CX25840_COMPOSITE1,
- }, {
- .type = CX23885_VMUX_SVIDEO,
- .vmux = CX25840_SVIDEO_LUMA3 |
- CX25840_SVIDEO_CHROMA4,
- }, {
- .type = CX23885_VMUX_COMPONENT,
- .vmux = CX25840_VIN7_CH1 |
- CX25840_VIN6_CH2 |
- CX25840_VIN8_CH3 |
- CX25840_COMPONENT_ON,
- } },
- },
- [CX23885_BOARD_COMPRO_VIDEOMATE_E650F] = {
- .name = "Compro VideoMate E650F",
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_TBS_6920] = {
- .name = "TurboSight TBS 6920",
- .portb = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_TEVII_S470] = {
- .name = "TeVii S470",
- .portb = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_DVBWORLD_2005] = {
- .name = "DVBWorld DVB-S2 2005",
- .portb = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_NETUP_DUAL_DVBS2_CI] = {
- .ci_type = 1,
- .name = "NetUP Dual DVB-S2 CI",
- .portb = CX23885_MPEG_DVB,
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1270] = {
- .name = "Hauppauge WinTV-HVR1270",
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1275] = {
- .name = "Hauppauge WinTV-HVR1275",
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1255] = {
- .name = "Hauppauge WinTV-HVR1255",
- .porta = CX23885_ANALOG_VIDEO,
- .portc = CX23885_MPEG_DVB,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = 0x42, /* 0x84 >> 1 */
- .force_bff = 1,
- .input = {{
- .type = CX23885_VMUX_TELEVISION,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN5_CH2 |
- CX25840_VIN2_CH1 |
- CX25840_DIF_ON,
- .amux = CX25840_AUDIO8,
- }, {
- .type = CX23885_VMUX_COMPOSITE1,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN4_CH2 |
- CX25840_VIN6_CH1,
- .amux = CX25840_AUDIO7,
- }, {
- .type = CX23885_VMUX_SVIDEO,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN4_CH2 |
- CX25840_VIN8_CH1 |
- CX25840_SVIDEO_ON,
- .amux = CX25840_AUDIO7,
- } },
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1255_22111] = {
- .name = "Hauppauge WinTV-HVR1255",
- .porta = CX23885_ANALOG_VIDEO,
- .portc = CX23885_MPEG_DVB,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = 0x42, /* 0x84 >> 1 */
- .force_bff = 1,
- .input = {{
- .type = CX23885_VMUX_TELEVISION,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN5_CH2 |
- CX25840_VIN2_CH1 |
- CX25840_DIF_ON,
- .amux = CX25840_AUDIO8,
- }, {
- .type = CX23885_VMUX_SVIDEO,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN4_CH2 |
- CX25840_VIN8_CH1 |
- CX25840_SVIDEO_ON,
- .amux = CX25840_AUDIO7,
- } },
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1210] = {
- .name = "Hauppauge WinTV-HVR1210",
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_MYGICA_X8506] = {
- .name = "Mygica X8506 DMB-TH",
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0x61,
- .tuner_bus = 1,
- .porta = CX23885_ANALOG_VIDEO,
- .portb = CX23885_MPEG_DVB,
- .input = {
- {
- .type = CX23885_VMUX_TELEVISION,
- .vmux = CX25840_COMPOSITE2,
- },
- {
- .type = CX23885_VMUX_COMPOSITE1,
- .vmux = CX25840_COMPOSITE8,
- },
- {
- .type = CX23885_VMUX_SVIDEO,
- .vmux = CX25840_SVIDEO_LUMA3 |
- CX25840_SVIDEO_CHROMA4,
- },
- {
- .type = CX23885_VMUX_COMPONENT,
- .vmux = CX25840_COMPONENT_ON |
- CX25840_VIN1_CH1 |
- CX25840_VIN6_CH2 |
- CX25840_VIN7_CH3,
- },
- },
- },
- [CX23885_BOARD_MAGICPRO_PROHDTVE2] = {
- .name = "Magic-Pro ProHDTV Extreme 2",
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0x61,
- .tuner_bus = 1,
- .porta = CX23885_ANALOG_VIDEO,
- .portb = CX23885_MPEG_DVB,
- .input = {
- {
- .type = CX23885_VMUX_TELEVISION,
- .vmux = CX25840_COMPOSITE2,
- },
- {
- .type = CX23885_VMUX_COMPOSITE1,
- .vmux = CX25840_COMPOSITE8,
- },
- {
- .type = CX23885_VMUX_SVIDEO,
- .vmux = CX25840_SVIDEO_LUMA3 |
- CX25840_SVIDEO_CHROMA4,
- },
- {
- .type = CX23885_VMUX_COMPONENT,
- .vmux = CX25840_COMPONENT_ON |
- CX25840_VIN1_CH1 |
- CX25840_VIN6_CH2 |
- CX25840_VIN7_CH3,
- },
- },
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1850] = {
- .name = "Hauppauge WinTV-HVR1850",
- .porta = CX23885_ANALOG_VIDEO,
- .portb = CX23885_MPEG_ENCODER,
- .portc = CX23885_MPEG_DVB,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = 0x42, /* 0x84 >> 1 */
- .force_bff = 1,
- .input = {{
- .type = CX23885_VMUX_TELEVISION,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN5_CH2 |
- CX25840_VIN2_CH1 |
- CX25840_DIF_ON,
- .amux = CX25840_AUDIO8,
- }, {
- .type = CX23885_VMUX_COMPOSITE1,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN4_CH2 |
- CX25840_VIN6_CH1,
- .amux = CX25840_AUDIO7,
- }, {
- .type = CX23885_VMUX_SVIDEO,
- .vmux = CX25840_VIN7_CH3 |
- CX25840_VIN4_CH2 |
- CX25840_VIN8_CH1 |
- CX25840_SVIDEO_ON,
- .amux = CX25840_AUDIO7,
- } },
- },
- [CX23885_BOARD_COMPRO_VIDEOMATE_E800] = {
- .name = "Compro VideoMate E800",
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_HAUPPAUGE_HVR1290] = {
- .name = "Hauppauge WinTV-HVR1290",
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_MYGICA_X8558PRO] = {
- .name = "Mygica X8558 PRO DMB-TH",
- .portb = CX23885_MPEG_DVB,
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_LEADTEK_WINFAST_PXTV1200] = {
- .name = "LEADTEK WinFast PxTV1200",
- .porta = CX23885_ANALOG_VIDEO,
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0x61,
- .tuner_bus = 1,
- .input = {{
- .type = CX23885_VMUX_TELEVISION,
- .vmux = CX25840_VIN2_CH1 |
- CX25840_VIN5_CH2 |
- CX25840_NONE0_CH3,
- }, {
- .type = CX23885_VMUX_COMPOSITE1,
- .vmux = CX25840_COMPOSITE1,
- }, {
- .type = CX23885_VMUX_SVIDEO,
- .vmux = CX25840_SVIDEO_LUMA3 |
- CX25840_SVIDEO_CHROMA4,
- }, {
- .type = CX23885_VMUX_COMPONENT,
- .vmux = CX25840_VIN7_CH1 |
- CX25840_VIN6_CH2 |
- CX25840_VIN8_CH3 |
- CX25840_COMPONENT_ON,
- } },
- },
- [CX23885_BOARD_GOTVIEW_X5_3D_HYBRID] = {
- .name = "GoTView X5 3D Hybrid",
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0x64,
- .tuner_bus = 1,
- .porta = CX23885_ANALOG_VIDEO,
- .portb = CX23885_MPEG_DVB,
- .input = {{
- .type = CX23885_VMUX_TELEVISION,
- .vmux = CX25840_VIN2_CH1 |
- CX25840_VIN5_CH2,
- .gpio0 = 0x02,
- }, {
- .type = CX23885_VMUX_COMPOSITE1,
- .vmux = CX23885_VMUX_COMPOSITE1,
- }, {
- .type = CX23885_VMUX_SVIDEO,
- .vmux = CX25840_SVIDEO_LUMA3 |
- CX25840_SVIDEO_CHROMA4,
- } },
- },
- [CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF] = {
- .ci_type = 2,
- .name = "NetUP Dual DVB-T/C-CI RF",
- .porta = CX23885_ANALOG_VIDEO,
- .portb = CX23885_MPEG_DVB,
- .portc = CX23885_MPEG_DVB,
- .num_fds_portb = 2,
- .num_fds_portc = 2,
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0x64,
- .input = { {
- .type = CX23885_VMUX_TELEVISION,
- .vmux = CX25840_COMPOSITE1,
- } },
- },
- [CX23885_BOARD_MPX885] = {
- .name = "MPX-885",
- .porta = CX23885_ANALOG_VIDEO,
- .input = {{
- .type = CX23885_VMUX_COMPOSITE1,
- .vmux = CX25840_COMPOSITE1,
- .amux = CX25840_AUDIO6,
- .gpio0 = 0,
- }, {
- .type = CX23885_VMUX_COMPOSITE2,
- .vmux = CX25840_COMPOSITE2,
- .amux = CX25840_AUDIO6,
- .gpio0 = 0,
- }, {
- .type = CX23885_VMUX_COMPOSITE3,
- .vmux = CX25840_COMPOSITE3,
- .amux = CX25840_AUDIO7,
- .gpio0 = 0,
- }, {
- .type = CX23885_VMUX_COMPOSITE4,
- .vmux = CX25840_COMPOSITE4,
- .amux = CX25840_AUDIO7,
- .gpio0 = 0,
- } },
- },
- [CX23885_BOARD_MYGICA_X8507] = {
- .name = "Mygica X8507",
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0x61,
- .tuner_bus = 1,
- .porta = CX23885_ANALOG_VIDEO,
- .input = {
- {
- .type = CX23885_VMUX_TELEVISION,
- .vmux = CX25840_COMPOSITE2,
- .amux = CX25840_AUDIO8,
- },
- {
- .type = CX23885_VMUX_COMPOSITE1,
- .vmux = CX25840_COMPOSITE8,
- },
- {
- .type = CX23885_VMUX_SVIDEO,
- .vmux = CX25840_SVIDEO_LUMA3 |
- CX25840_SVIDEO_CHROMA4,
- },
- {
- .type = CX23885_VMUX_COMPONENT,
- .vmux = CX25840_COMPONENT_ON |
- CX25840_VIN1_CH1 |
- CX25840_VIN6_CH2 |
- CX25840_VIN7_CH3,
- },
- },
- },
- [CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL] = {
- .name = "TerraTec Cinergy T PCIe Dual",
- .portb = CX23885_MPEG_DVB,
- .portc = CX23885_MPEG_DVB,
- },
- [CX23885_BOARD_TEVII_S471] = {
- .name = "TeVii S471",
- .portb = CX23885_MPEG_DVB,
- }
-};
-const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
-
-/* ------------------------------------------------------------------ */
-/* PCI subsystem IDs */
-
-struct cx23885_subid cx23885_subids[] = {
- {
- .subvendor = 0x0070,
- .subdevice = 0x3400,
- .card = CX23885_BOARD_UNKNOWN,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x7600,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1800lp,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x7800,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1800,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x7801,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1800,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x7809,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1800,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x7911,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1250,
- }, {
- .subvendor = 0x18ac,
- .subdevice = 0xd500,
- .card = CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x7790,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x7797,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x7710,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1500,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x7717,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1500,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x71d1,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1200,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x71d3,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1200,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x8101,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1700,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x8010,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1400,
- }, {
- .subvendor = 0x18ac,
- .subdevice = 0xd618,
- .card = CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP,
- }, {
- .subvendor = 0x18ac,
- .subdevice = 0xdb78,
- .card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP,
- }, {
- .subvendor = 0x107d,
- .subdevice = 0x6681,
- .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H,
- }, {
- .subvendor = 0x107d,
- .subdevice = 0x6f39,
- .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000,
- }, {
- .subvendor = 0x185b,
- .subdevice = 0xe800,
- .card = CX23885_BOARD_COMPRO_VIDEOMATE_E650F,
- }, {
- .subvendor = 0x6920,
- .subdevice = 0x8888,
- .card = CX23885_BOARD_TBS_6920,
- }, {
- .subvendor = 0xd470,
- .subdevice = 0x9022,
- .card = CX23885_BOARD_TEVII_S470,
- }, {
- .subvendor = 0x0001,
- .subdevice = 0x2005,
- .card = CX23885_BOARD_DVBWORLD_2005,
- }, {
- .subvendor = 0x1b55,
- .subdevice = 0x2a2c,
- .card = CX23885_BOARD_NETUP_DUAL_DVBS2_CI,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x2211,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1270,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x2215,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1275,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x221d,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1275,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x2251,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1255,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x2259,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1255_22111,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x2291,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x2295,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x2299,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x229d,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x22f0,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x22f1,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1255,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x22f2,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1275,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x22f3,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x22f4,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x22f5,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */
- }, {
- .subvendor = 0x14f1,
- .subdevice = 0x8651,
- .card = CX23885_BOARD_MYGICA_X8506,
- }, {
- .subvendor = 0x14f1,
- .subdevice = 0x8657,
- .card = CX23885_BOARD_MAGICPRO_PROHDTVE2,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x8541,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1850,
- }, {
- .subvendor = 0x1858,
- .subdevice = 0xe800,
- .card = CX23885_BOARD_COMPRO_VIDEOMATE_E800,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x8551,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1290,
- }, {
- .subvendor = 0x14f1,
- .subdevice = 0x8578,
- .card = CX23885_BOARD_MYGICA_X8558PRO,
- }, {
- .subvendor = 0x107d,
- .subdevice = 0x6f22,
- .card = CX23885_BOARD_LEADTEK_WINFAST_PXTV1200,
- }, {
- .subvendor = 0x5654,
- .subdevice = 0x2390,
- .card = CX23885_BOARD_GOTVIEW_X5_3D_HYBRID,
- }, {
- .subvendor = 0x1b55,
- .subdevice = 0xe2e4,
- .card = CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF,
- }, {
- .subvendor = 0x14f1,
- .subdevice = 0x8502,
- .card = CX23885_BOARD_MYGICA_X8507,
- }, {
- .subvendor = 0x153b,
- .subdevice = 0x117e,
- .card = CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL,
- }, {
- .subvendor = 0xd471,
- .subdevice = 0x9022,
- .card = CX23885_BOARD_TEVII_S471,
- },
-};
-const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
-
-void cx23885_card_list(struct cx23885_dev *dev)
-{
- int i;
-
- if (0 == dev->pci->subsystem_vendor &&
- 0 == dev->pci->subsystem_device) {
- printk(KERN_INFO
- "%s: Board has no valid PCIe Subsystem ID and can't\n"
- "%s: be autodetected. Pass card=<n> insmod option\n"
- "%s: to workaround that. Redirect complaints to the\n"
- "%s: vendor of the TV card. Best regards,\n"
- "%s: -- tux\n",
- dev->name, dev->name, dev->name, dev->name, dev->name);
- } else {
- printk(KERN_INFO
- "%s: Your board isn't known (yet) to the driver.\n"
- "%s: Try to pick one of the existing card configs via\n"
- "%s: card=<n> insmod option. Updating to the latest\n"
- "%s: version might help as well.\n",
- dev->name, dev->name, dev->name, dev->name);
- }
- printk(KERN_INFO "%s: Here is a list of valid choices for the card=<n> insmod option:\n",
- dev->name);
- for (i = 0; i < cx23885_bcount; i++)
- printk(KERN_INFO "%s: card=%d -> %s\n",
- dev->name, i, cx23885_boards[i].name);
-}
-
-static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
-{
- struct tveeprom tv;
-
- tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
- eeprom_data);
-
- /* Make sure we support the board model */
- switch (tv.model) {
- case 22001:
- /* WinTV-HVR1270 (PCIe, Retail, half height)
- * ATSC/QAM and basic analog, IR Blast */
- case 22009:
- /* WinTV-HVR1210 (PCIe, Retail, half height)
- * DVB-T and basic analog, IR Blast */
- case 22011:
- /* WinTV-HVR1270 (PCIe, Retail, half height)
- * ATSC/QAM and basic analog, IR Recv */
- case 22019:
- /* WinTV-HVR1210 (PCIe, Retail, half height)
- * DVB-T and basic analog, IR Recv */
- case 22021:
- /* WinTV-HVR1275 (PCIe, Retail, half height)
- * ATSC/QAM and basic analog, IR Recv */
- case 22029:
- /* WinTV-HVR1210 (PCIe, Retail, half height)
- * DVB-T and basic analog, IR Recv */
- case 22101:
- /* WinTV-HVR1270 (PCIe, Retail, full height)
- * ATSC/QAM and basic analog, IR Blast */
- case 22109:
- /* WinTV-HVR1210 (PCIe, Retail, full height)
- * DVB-T and basic analog, IR Blast */
- case 22111:
- /* WinTV-HVR1270 (PCIe, Retail, full height)
- * ATSC/QAM and basic analog, IR Recv */
- case 22119:
- /* WinTV-HVR1210 (PCIe, Retail, full height)
- * DVB-T and basic analog, IR Recv */
- case 22121:
- /* WinTV-HVR1275 (PCIe, Retail, full height)
- * ATSC/QAM and basic analog, IR Recv */
- case 22129:
- /* WinTV-HVR1210 (PCIe, Retail, full height)
- * DVB-T and basic analog, IR Recv */
- case 71009:
- /* WinTV-HVR1200 (PCIe, Retail, full height)
- * DVB-T and basic analog */
- case 71359:
- /* WinTV-HVR1200 (PCIe, OEM, half height)
- * DVB-T and basic analog */
- case 71439:
- /* WinTV-HVR1200 (PCIe, OEM, half height)
- * DVB-T and basic analog */
- case 71449:
- /* WinTV-HVR1200 (PCIe, OEM, full height)
- * DVB-T and basic analog */
- case 71939:
- /* WinTV-HVR1200 (PCIe, OEM, half height)
- * DVB-T and basic analog */
- case 71949:
- /* WinTV-HVR1200 (PCIe, OEM, full height)
- * DVB-T and basic analog */
- case 71959:
- /* WinTV-HVR1200 (PCIe, OEM, full height)
- * DVB-T and basic analog */
- case 71979:
- /* WinTV-HVR1200 (PCIe, OEM, half height)
- * DVB-T and basic analog */
- case 71999:
- /* WinTV-HVR1200 (PCIe, OEM, full height)
- * DVB-T and basic analog */
- case 76601:
- /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual
- channel ATSC and MPEG2 HW Encoder */
- case 77001:
- /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC
- and Basic analog */
- case 77011:
- /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC
- and Basic analog */
- case 77041:
- /* WinTV-HVR1500Q (Express Card, OEM, No IR, ATSC/QAM
- and Basic analog */
- case 77051:
- /* WinTV-HVR1500Q (Express Card, Retail, No IR, ATSC/QAM
- and Basic analog */
- case 78011:
- /* WinTV-HVR1800 (PCIe, Retail, 3.5mm in, IR, No FM,
- Dual channel ATSC and MPEG2 HW Encoder */
- case 78501:
- /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM,
- Dual channel ATSC and MPEG2 HW Encoder */
- case 78521:
- /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM,
- Dual channel ATSC and MPEG2 HW Encoder */
- case 78531:
- /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, No FM,
- Dual channel ATSC and MPEG2 HW Encoder */
- case 78631:
- /* WinTV-HVR1800 (PCIe, OEM, No IR, No FM,
- Dual channel ATSC and MPEG2 HW Encoder */
- case 79001:
- /* WinTV-HVR1250 (PCIe, Retail, IR, full height,
- ATSC and Basic analog */
- case 79101:
- /* WinTV-HVR1250 (PCIe, Retail, IR, half height,
- ATSC and Basic analog */
- case 79501:
- /* WinTV-HVR1250 (PCIe, No IR, half height,
- ATSC [at least] and Basic analog) */
- case 79561:
- /* WinTV-HVR1250 (PCIe, OEM, No IR, half height,
- ATSC and Basic analog */
- case 79571:
- /* WinTV-HVR1250 (PCIe, OEM, No IR, full height,
- ATSC and Basic analog */
- case 79671:
- /* WinTV-HVR1250 (PCIe, OEM, No IR, half height,
- ATSC and Basic analog */
- case 80019:
- /* WinTV-HVR1400 (Express Card, Retail, IR,
- * DVB-T and Basic analog */
- case 81509:
- /* WinTV-HVR1700 (PCIe, OEM, No IR, half height)
- * DVB-T and MPEG2 HW Encoder */
- case 81519:
- /* WinTV-HVR1700 (PCIe, OEM, No IR, full height)
- * DVB-T and MPEG2 HW Encoder */
- break;
- case 85021:
- /* WinTV-HVR1850 (PCIe, Retail, 3.5mm in, IR, FM,
- Dual channel ATSC and MPEG2 HW Encoder */
- break;
- case 85721:
- /* WinTV-HVR1290 (PCIe, OEM, RCA in, IR,
- Dual channel ATSC and Basic analog */
- break;
- default:
- printk(KERN_WARNING "%s: warning: "
- "unknown hauppauge model #%d\n",
- dev->name, tv.model);
- break;
- }
-
- printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n",
- dev->name, tv.model);
-}
-
-int cx23885_tuner_callback(void *priv, int component, int command, int arg)
-{
- struct cx23885_tsport *port = priv;
- struct cx23885_dev *dev = port->dev;
- u32 bitmask = 0;
-
- if ((command == XC2028_RESET_CLK) || (command == XC2028_I2C_FLUSH))
- return 0;
-
- if (command != 0) {
- printk(KERN_ERR "%s(): Unknown command 0x%x.\n",
- __func__, command);
- return -EINVAL;
- }
-
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1400:
- case CX23885_BOARD_HAUPPAUGE_HVR1500:
- case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
- case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
- case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
- case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
- case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
- case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
- /* Tuner Reset Command */
- bitmask = 0x04;
- break;
- case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
- case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
- /* Two identical tuners on two different i2c buses,
- * we need to reset the correct gpio. */
- if (port->nr == 1)
- bitmask = 0x01;
- else if (port->nr == 2)
- bitmask = 0x04;
- break;
- case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID:
- /* Tuner Reset Command */
- bitmask = 0x02;
- break;
- case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
- altera_ci_tuner_reset(dev, port->nr);
- break;
- }
-
- if (bitmask) {
- /* Drive the tuner into reset and back out */
- cx_clear(GP0_IO, bitmask);
- mdelay(200);
- cx_set(GP0_IO, bitmask);
- }
-
- return 0;
-}
-
-void cx23885_gpio_setup(struct cx23885_dev *dev)
-{
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1250:
- /* GPIO-0 cx24227 demodulator reset */
- cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1500:
- /* GPIO-0 cx24227 demodulator */
- /* GPIO-2 xc3028 tuner */
-
- /* Put the parts into reset */
- cx_set(GP0_IO, 0x00050000);
- cx_clear(GP0_IO, 0x00000005);
- msleep(5);
-
- /* Bring the parts out of reset */
- cx_set(GP0_IO, 0x00050005);
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
- /* GPIO-0 cx24227 demodulator reset */
- /* GPIO-2 xc5000 tuner reset */
- cx_set(GP0_IO, 0x00050005); /* Bring the part out of reset */
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1800:
- /* GPIO-0 656_CLK */
- /* GPIO-1 656_D0 */
- /* GPIO-2 8295A Reset */
- /* GPIO-3-10 cx23417 data0-7 */
- /* GPIO-11-14 cx23417 addr0-3 */
- /* GPIO-15-18 cx23417 READY, CS, RD, WR */
- /* GPIO-19 IR_RX */
-
- /* CX23417 GPIO's */
- /* EIO15 Zilog Reset */
- /* EIO14 S5H1409/CX24227 Reset */
- mc417_gpio_enable(dev, GPIO_15 | GPIO_14, 1);
-
- /* Put the demod into reset and protect the eeprom */
- mc417_gpio_clear(dev, GPIO_15 | GPIO_14);
- mdelay(100);
-
- /* Bring the demod and blaster out of reset */
- mc417_gpio_set(dev, GPIO_15 | GPIO_14);
- mdelay(100);
-
- /* Force the TDA8295A into reset and back */
- cx23885_gpio_enable(dev, GPIO_2, 1);
- cx23885_gpio_set(dev, GPIO_2);
- mdelay(20);
- cx23885_gpio_clear(dev, GPIO_2);
- mdelay(20);
- cx23885_gpio_set(dev, GPIO_2);
- mdelay(20);
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1200:
- /* GPIO-0 tda10048 demodulator reset */
- /* GPIO-2 tda18271 tuner reset */
-
- /* Put the parts into reset and back */
- cx_set(GP0_IO, 0x00050000);
- mdelay(20);
- cx_clear(GP0_IO, 0x00000005);
- mdelay(20);
- cx_set(GP0_IO, 0x00050005);
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1700:
- /* GPIO-0 TDA10048 demodulator reset */
- /* GPIO-2 TDA8295A Reset */
- /* GPIO-3-10 cx23417 data0-7 */
- /* GPIO-11-14 cx23417 addr0-3 */
- /* GPIO-15-18 cx23417 READY, CS, RD, WR */
-
- /* The following GPIO's are on the interna AVCore (cx25840) */
- /* GPIO-19 IR_RX */
- /* GPIO-20 IR_TX 416/DVBT Select */
- /* GPIO-21 IIS DAT */
- /* GPIO-22 IIS WCLK */
- /* GPIO-23 IIS BCLK */
-
- /* Put the parts into reset and back */
- cx_set(GP0_IO, 0x00050000);
- mdelay(20);
- cx_clear(GP0_IO, 0x00000005);
- mdelay(20);
- cx_set(GP0_IO, 0x00050005);
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1400:
- /* GPIO-0 Dibcom7000p demodulator reset */
- /* GPIO-2 xc3028L tuner reset */
- /* GPIO-13 LED */
-
- /* Put the parts into reset and back */
- cx_set(GP0_IO, 0x00050000);
- mdelay(20);
- cx_clear(GP0_IO, 0x00000005);
- mdelay(20);
- cx_set(GP0_IO, 0x00050005);
- break;
- case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
- /* GPIO-0 xc5000 tuner reset i2c bus 0 */
- /* GPIO-1 s5h1409 demod reset i2c bus 0 */
- /* GPIO-2 xc5000 tuner reset i2c bus 1 */
- /* GPIO-3 s5h1409 demod reset i2c bus 0 */
-
- /* Put the parts into reset and back */
- cx_set(GP0_IO, 0x000f0000);
- mdelay(20);
- cx_clear(GP0_IO, 0x0000000f);
- mdelay(20);
- cx_set(GP0_IO, 0x000f000f);
- break;
- case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
- /* GPIO-0 portb xc3028 reset */
- /* GPIO-1 portb zl10353 reset */
- /* GPIO-2 portc xc3028 reset */
- /* GPIO-3 portc zl10353 reset */
-
- /* Put the parts into reset and back */
- cx_set(GP0_IO, 0x000f0000);
- mdelay(20);
- cx_clear(GP0_IO, 0x0000000f);
- mdelay(20);
- cx_set(GP0_IO, 0x000f000f);
- break;
- case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
- case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
- case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
- case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
- case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
- /* GPIO-2 xc3028 tuner reset */
-
- /* The following GPIO's are on the internal AVCore (cx25840) */
- /* GPIO-? zl10353 demod reset */
-
- /* Put the parts into reset and back */
- cx_set(GP0_IO, 0x00040000);
- mdelay(20);
- cx_clear(GP0_IO, 0x00000004);
- mdelay(20);
- cx_set(GP0_IO, 0x00040004);
- break;
- case CX23885_BOARD_TBS_6920:
- cx_write(MC417_CTL, 0x00000036);
- cx_write(MC417_OEN, 0x00001000);
- cx_set(MC417_RWD, 0x00000002);
- mdelay(200);
- cx_clear(MC417_RWD, 0x00000800);
- mdelay(200);
- cx_set(MC417_RWD, 0x00000800);
- mdelay(200);
- break;
- case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
- /* GPIO-0 INTA from CiMax1
- GPIO-1 INTB from CiMax2
- GPIO-2 reset chips
- GPIO-3 to GPIO-10 data/addr for CA
- GPIO-11 ~CS0 to CiMax1
- GPIO-12 ~CS1 to CiMax2
- GPIO-13 ADL0 load LSB addr
- GPIO-14 ADL1 load MSB addr
- GPIO-15 ~RDY from CiMax
- GPIO-17 ~RD to CiMax
- GPIO-18 ~WR to CiMax
- */
- cx_set(GP0_IO, 0x00040000); /* GPIO as out */
- /* GPIO1 and GPIO2 as INTA and INTB from CiMaxes, reset low */
- cx_clear(GP0_IO, 0x00030004);
- mdelay(100);/* reset delay */
- cx_set(GP0_IO, 0x00040004); /* GPIO as out, reset high */
- cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */
- /* GPIO-15 IN as ~ACK, rest as OUT */
- cx_write(MC417_OEN, 0x00001000);
- /* ~RD, ~WR high; ADL0, ADL1 low; ~CS0, ~CS1 high */
- cx_write(MC417_RWD, 0x0000c300);
- /* enable irq */
- cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1270:
- case CX23885_BOARD_HAUPPAUGE_HVR1275:
- case CX23885_BOARD_HAUPPAUGE_HVR1255:
- case CX23885_BOARD_HAUPPAUGE_HVR1255_22111:
- case CX23885_BOARD_HAUPPAUGE_HVR1210:
- /* GPIO-5 RF Control: 0 = RF1 Terrestrial, 1 = RF2 Cable */
- /* GPIO-6 I2C Gate which can isolate the demod from the bus */
- /* GPIO-9 Demod reset */
-
- /* Put the parts into reset and back */
- cx23885_gpio_enable(dev, GPIO_9 | GPIO_6 | GPIO_5, 1);
- cx23885_gpio_set(dev, GPIO_9 | GPIO_6 | GPIO_5);
- cx23885_gpio_clear(dev, GPIO_9);
- mdelay(20);
- cx23885_gpio_set(dev, GPIO_9);
- break;
- case CX23885_BOARD_MYGICA_X8506:
- case CX23885_BOARD_MAGICPRO_PROHDTVE2:
- case CX23885_BOARD_MYGICA_X8507:
- /* GPIO-0 (0)Analog / (1)Digital TV */
- /* GPIO-1 reset XC5000 */
- /* GPIO-2 reset LGS8GL5 / LGS8G75 */
- cx23885_gpio_enable(dev, GPIO_0 | GPIO_1 | GPIO_2, 1);
- cx23885_gpio_clear(dev, GPIO_1 | GPIO_2);
- mdelay(100);
- cx23885_gpio_set(dev, GPIO_0 | GPIO_1 | GPIO_2);
- mdelay(100);
- break;
- case CX23885_BOARD_MYGICA_X8558PRO:
- /* GPIO-0 reset first ATBM8830 */
- /* GPIO-1 reset second ATBM8830 */
- cx23885_gpio_enable(dev, GPIO_0 | GPIO_1, 1);
- cx23885_gpio_clear(dev, GPIO_0 | GPIO_1);
- mdelay(100);
- cx23885_gpio_set(dev, GPIO_0 | GPIO_1);
- mdelay(100);
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- case CX23885_BOARD_HAUPPAUGE_HVR1290:
- /* GPIO-0 656_CLK */
- /* GPIO-1 656_D0 */
- /* GPIO-2 Wake# */
- /* GPIO-3-10 cx23417 data0-7 */
- /* GPIO-11-14 cx23417 addr0-3 */
- /* GPIO-15-18 cx23417 READY, CS, RD, WR */
- /* GPIO-19 IR_RX */
- /* GPIO-20 C_IR_TX */
- /* GPIO-21 I2S DAT */
- /* GPIO-22 I2S WCLK */
- /* GPIO-23 I2S BCLK */
- /* ALT GPIO: EXP GPIO LATCH */
-
- /* CX23417 GPIO's */
- /* GPIO-14 S5H1411/CX24228 Reset */
- /* GPIO-13 EEPROM write protect */
- mc417_gpio_enable(dev, GPIO_14 | GPIO_13, 1);
-
- /* Put the demod into reset and protect the eeprom */
- mc417_gpio_clear(dev, GPIO_14 | GPIO_13);
- mdelay(100);
-
- /* Bring the demod out of reset */
- mc417_gpio_set(dev, GPIO_14);
- mdelay(100);
-
- /* CX24228 GPIO */
- /* Connected to IF / Mux */
- break;
- case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID:
- cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */
- break;
- case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
- /* GPIO-0 ~INT in
- GPIO-1 TMS out
- GPIO-2 ~reset chips out
- GPIO-3 to GPIO-10 data/addr for CA in/out
- GPIO-11 ~CS out
- GPIO-12 ADDR out
- GPIO-13 ~WR out
- GPIO-14 ~RD out
- GPIO-15 ~RDY in
- GPIO-16 TCK out
- GPIO-17 TDO in
- GPIO-18 TDI out
- */
- cx_set(GP0_IO, 0x00060000); /* GPIO-1,2 as out */
- /* GPIO-0 as INT, reset & TMS low */
- cx_clear(GP0_IO, 0x00010006);
- mdelay(100);/* reset delay */
- cx_set(GP0_IO, 0x00000004); /* reset high */
- cx_write(MC417_CTL, 0x00000037);/* enable GPIO-3..18 pins */
- /* GPIO-17 is TDO in, GPIO-15 is ~RDY in, rest is out */
- cx_write(MC417_OEN, 0x00005000);
- /* ~RD, ~WR high; ADDR low; ~CS high */
- cx_write(MC417_RWD, 0x00000d00);
- /* enable irq */
- cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/
- break;
- }
-}
-
-int cx23885_ir_init(struct cx23885_dev *dev)
-{
- static struct v4l2_subdev_io_pin_config ir_rxtx_pin_cfg[] = {
- {
- .flags = V4L2_SUBDEV_IO_PIN_INPUT,
- .pin = CX23885_PIN_IR_RX_GPIO19,
- .function = CX23885_PAD_IR_RX,
- .value = 0,
- .strength = CX25840_PIN_DRIVE_MEDIUM,
- }, {
- .flags = V4L2_SUBDEV_IO_PIN_OUTPUT,
- .pin = CX23885_PIN_IR_TX_GPIO20,
- .function = CX23885_PAD_IR_TX,
- .value = 0,
- .strength = CX25840_PIN_DRIVE_MEDIUM,
- }
- };
- const size_t ir_rxtx_pin_cfg_count = ARRAY_SIZE(ir_rxtx_pin_cfg);
-
- static struct v4l2_subdev_io_pin_config ir_rx_pin_cfg[] = {
- {
- .flags = V4L2_SUBDEV_IO_PIN_INPUT,
- .pin = CX23885_PIN_IR_RX_GPIO19,
- .function = CX23885_PAD_IR_RX,
- .value = 0,
- .strength = CX25840_PIN_DRIVE_MEDIUM,
- }
- };
- const size_t ir_rx_pin_cfg_count = ARRAY_SIZE(ir_rx_pin_cfg);
-
- struct v4l2_subdev_ir_parameters params;
- int ret = 0;
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1500:
- case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
- case CX23885_BOARD_HAUPPAUGE_HVR1800:
- case CX23885_BOARD_HAUPPAUGE_HVR1200:
- case CX23885_BOARD_HAUPPAUGE_HVR1400:
- case CX23885_BOARD_HAUPPAUGE_HVR1275:
- case CX23885_BOARD_HAUPPAUGE_HVR1255:
- case CX23885_BOARD_HAUPPAUGE_HVR1255_22111:
- case CX23885_BOARD_HAUPPAUGE_HVR1210:
- /* FIXME: Implement me */
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1270:
- ret = cx23888_ir_probe(dev);
- if (ret)
- break;
- dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_888_IR);
- v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config,
- ir_rx_pin_cfg_count, ir_rx_pin_cfg);
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- case CX23885_BOARD_HAUPPAUGE_HVR1290:
- ret = cx23888_ir_probe(dev);
- if (ret)
- break;
- dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_888_IR);
- v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config,
- ir_rxtx_pin_cfg_count, ir_rxtx_pin_cfg);
- /*
- * For these boards we need to invert the Tx output via the
- * IR controller to have the LED off while idle
- */
- v4l2_subdev_call(dev->sd_ir, ir, tx_g_parameters, &params);
- params.enable = false;
- params.shutdown = false;
- params.invert_level = true;
- v4l2_subdev_call(dev->sd_ir, ir, tx_s_parameters, &params);
- params.shutdown = true;
- v4l2_subdev_call(dev->sd_ir, ir, tx_s_parameters, &params);
- break;
- case CX23885_BOARD_TEVII_S470:
- if (!enable_885_ir)
- break;
- dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE);
- if (dev->sd_ir == NULL) {
- ret = -ENODEV;
- break;
- }
- v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config,
- ir_rx_pin_cfg_count, ir_rx_pin_cfg);
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1250:
- if (!enable_885_ir)
- break;
- dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE);
- if (dev->sd_ir == NULL) {
- ret = -ENODEV;
- break;
- }
- v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config,
- ir_rxtx_pin_cfg_count, ir_rxtx_pin_cfg);
- break;
- case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
- request_module("ir-kbd-i2c");
- break;
- }
-
- return ret;
-}
-
-void cx23885_ir_fini(struct cx23885_dev *dev)
-{
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1270:
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- case CX23885_BOARD_HAUPPAUGE_HVR1290:
- cx23885_irq_remove(dev, PCI_MSK_IR);
- cx23888_ir_remove(dev);
- dev->sd_ir = NULL;
- break;
- case CX23885_BOARD_TEVII_S470:
- case CX23885_BOARD_HAUPPAUGE_HVR1250:
- cx23885_irq_remove(dev, PCI_MSK_AV_CORE);
- /* sd_ir is a duplicate pointer to the AV Core, just clear it */
- dev->sd_ir = NULL;
- break;
- }
-}
-
-int netup_jtag_io(void *device, int tms, int tdi, int read_tdo)
-{
- int data;
- int tdo = 0;
- struct cx23885_dev *dev = (struct cx23885_dev *)device;
- /*TMS*/
- data = ((cx_read(GP0_IO)) & (~0x00000002));
- data |= (tms ? 0x00020002 : 0x00020000);
- cx_write(GP0_IO, data);
-
- /*TDI*/
- data = ((cx_read(MC417_RWD)) & (~0x0000a000));
- data |= (tdi ? 0x00008000 : 0);
- cx_write(MC417_RWD, data);
- if (read_tdo)
- tdo = (data & 0x00004000) ? 1 : 0; /*TDO*/
-
- cx_write(MC417_RWD, data | 0x00002000);
- udelay(1);
- /*TCK*/
- cx_write(MC417_RWD, data);
-
- return tdo;
-}
-
-void cx23885_ir_pci_int_enable(struct cx23885_dev *dev)
-{
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1270:
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- case CX23885_BOARD_HAUPPAUGE_HVR1290:
- if (dev->sd_ir)
- cx23885_irq_add_enable(dev, PCI_MSK_IR);
- break;
- case CX23885_BOARD_TEVII_S470:
- case CX23885_BOARD_HAUPPAUGE_HVR1250:
- if (dev->sd_ir)
- cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE);
- break;
- }
-}
-
-void cx23885_card_setup(struct cx23885_dev *dev)
-{
- struct cx23885_tsport *ts1 = &dev->ts1;
- struct cx23885_tsport *ts2 = &dev->ts2;
-
- static u8 eeprom[256];
-
- if (dev->i2c_bus[0].i2c_rc == 0) {
- dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
- tveeprom_read(&dev->i2c_bus[0].i2c_client,
- eeprom, sizeof(eeprom));
- }
-
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1250:
- if (dev->i2c_bus[0].i2c_rc == 0) {
- if (eeprom[0x80] != 0x84)
- hauppauge_eeprom(dev, eeprom+0xc0);
- else
- hauppauge_eeprom(dev, eeprom+0x80);
- }
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1500:
- case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
- case CX23885_BOARD_HAUPPAUGE_HVR1400:
- if (dev->i2c_bus[0].i2c_rc == 0)
- hauppauge_eeprom(dev, eeprom+0x80);
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1800:
- case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
- case CX23885_BOARD_HAUPPAUGE_HVR1200:
- case CX23885_BOARD_HAUPPAUGE_HVR1700:
- case CX23885_BOARD_HAUPPAUGE_HVR1270:
- case CX23885_BOARD_HAUPPAUGE_HVR1275:
- case CX23885_BOARD_HAUPPAUGE_HVR1255:
- case CX23885_BOARD_HAUPPAUGE_HVR1255_22111:
- case CX23885_BOARD_HAUPPAUGE_HVR1210:
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- case CX23885_BOARD_HAUPPAUGE_HVR1290:
- if (dev->i2c_bus[0].i2c_rc == 0)
- hauppauge_eeprom(dev, eeprom+0xc0);
- break;
- }
-
- switch (dev->board) {
- case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
- case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
- ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
- ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
- ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
- /* break omitted intentionally */
- case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP:
- ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
- ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
- ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- case CX23885_BOARD_HAUPPAUGE_HVR1800:
- /* Defaults for VID B - Analog encoder */
- /* DREQ_POL, SMODE, PUNC_CLK, MCLK_POL Serial bus + punc clk */
- ts1->gen_ctrl_val = 0x10e;
- ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
- ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
-
- /* APB_TSVALERR_POL (active low)*/
- ts1->vld_misc_val = 0x2000;
- ts1->hw_sop_ctrl_val = (0x47 << 16 | 188 << 4 | 0xc);
- cx_write(0x130184, 0xc);
-
- /* Defaults for VID C */
- ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
- ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
- ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
- break;
- case CX23885_BOARD_TBS_6920:
- ts1->gen_ctrl_val = 0x4; /* Parallel */
- ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
- ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
- break;
- case CX23885_BOARD_TEVII_S470:
- case CX23885_BOARD_TEVII_S471:
- case CX23885_BOARD_DVBWORLD_2005:
- ts1->gen_ctrl_val = 0x5; /* Parallel */
- ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
- ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
- break;
- case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
- case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
- case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
- ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
- ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
- ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
- ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
- ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
- ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
- break;
- case CX23885_BOARD_MYGICA_X8506:
- case CX23885_BOARD_MAGICPRO_PROHDTVE2:
- ts1->gen_ctrl_val = 0x5; /* Parallel */
- ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
- ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
- break;
- case CX23885_BOARD_MYGICA_X8558PRO:
- ts1->gen_ctrl_val = 0x5; /* Parallel */
- ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
- ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
- ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
- ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
- ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1250:
- case CX23885_BOARD_HAUPPAUGE_HVR1500:
- case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
- case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
- case CX23885_BOARD_HAUPPAUGE_HVR1200:
- case CX23885_BOARD_HAUPPAUGE_HVR1700:
- case CX23885_BOARD_HAUPPAUGE_HVR1400:
- case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
- case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
- case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
- case CX23885_BOARD_HAUPPAUGE_HVR1270:
- case CX23885_BOARD_HAUPPAUGE_HVR1275:
- case CX23885_BOARD_HAUPPAUGE_HVR1255:
- case CX23885_BOARD_HAUPPAUGE_HVR1255_22111:
- case CX23885_BOARD_HAUPPAUGE_HVR1210:
- case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
- case CX23885_BOARD_HAUPPAUGE_HVR1290:
- case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID:
- default:
- ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
- ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
- ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
- }
-
- /* Certain boards support analog, or require the avcore to be
- * loaded, ensure this happens.
- */
- switch (dev->board) {
- case CX23885_BOARD_TEVII_S470:
- /* Currently only enabled for the integrated IR controller */
- if (!enable_885_ir)
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1250:
- case CX23885_BOARD_HAUPPAUGE_HVR1800:
- case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
- case CX23885_BOARD_HAUPPAUGE_HVR1700:
- case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
- case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
- case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
- case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
- case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
- case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
- case CX23885_BOARD_HAUPPAUGE_HVR1255:
- case CX23885_BOARD_HAUPPAUGE_HVR1255_22111:
- case CX23885_BOARD_HAUPPAUGE_HVR1270:
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- case CX23885_BOARD_MYGICA_X8506:
- case CX23885_BOARD_MAGICPRO_PROHDTVE2:
- case CX23885_BOARD_HAUPPAUGE_HVR1290:
- case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
- case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID:
- case CX23885_BOARD_HAUPPAUGE_HVR1500:
- case CX23885_BOARD_MPX885:
- case CX23885_BOARD_MYGICA_X8507:
- case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
- dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_bus[2].i2c_adap,
- "cx25840", 0x88 >> 1, NULL);
- if (dev->sd_cx25840) {
- dev->sd_cx25840->grp_id = CX23885_HW_AV_CORE;
- v4l2_subdev_call(dev->sd_cx25840, core, load_fw);
- }
- break;
- }
-
- /* AUX-PLL 27MHz CLK */
- switch (dev->board) {
- case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
- netup_initialize(dev);
- break;
- case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: {
- int ret;
- const struct firmware *fw;
- const char *filename = "dvb-netup-altera-01.fw";
- char *action = "configure";
- static struct netup_card_info cinfo;
- struct altera_config netup_config = {
- .dev = dev,
- .action = action,
- .jtag_io = netup_jtag_io,
- };
-
- netup_initialize(dev);
-
- netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo);
- if (netup_card_rev)
- cinfo.rev = netup_card_rev;
-
- switch (cinfo.rev) {
- case 0x4:
- filename = "dvb-netup-altera-04.fw";
- break;
- default:
- filename = "dvb-netup-altera-01.fw";
- break;
- }
- printk(KERN_INFO "NetUP card rev=0x%x fw_filename=%s\n",
- cinfo.rev, filename);
-
- ret = request_firmware(&fw, filename, &dev->pci->dev);
- if (ret != 0)
- printk(KERN_ERR "did not find the firmware file. (%s) "
- "Please see linux/Documentation/dvb/ for more details "
- "on firmware-problems.", filename);
- else
- altera_init(&netup_config, fw);
-
- release_firmware(fw);
- break;
- }
- }
-}
-
-/* ------------------------------------------------------------------ */
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
deleted file mode 100644
index 697728f0943..00000000000
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ /dev/null
@@ -1,2234 +0,0 @@
-/*
- * Driver for the Conexant CX23885 PCIe bridge
- *
- * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kmod.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <asm/div64.h>
-#include <linux/firmware.h>
-
-#include "cx23885.h"
-#include "cimax2.h"
-#include "altera-ci.h"
-#include "cx23888-ir.h"
-#include "cx23885-ir.h"
-#include "cx23885-av.h"
-#include "cx23885-input.h"
-
-MODULE_DESCRIPTION("Driver for cx23885 based TV cards");
-MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(CX23885_VERSION);
-
-static unsigned int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debug messages");
-
-static unsigned int card[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET };
-module_param_array(card, int, NULL, 0444);
-MODULE_PARM_DESC(card, "card type");
-
-#define dprintk(level, fmt, arg...)\
- do { if (debug >= level)\
- printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\
- } while (0)
-
-static unsigned int cx23885_devcount;
-
-#define NO_SYNC_LINE (-1U)
-
-/* FIXME, these allocations will change when
- * analog arrives. The be reviewed.
- * CX23887 Assumptions
- * 1 line = 16 bytes of CDT
- * cmds size = 80
- * cdt size = 16 * linesize
- * iqsize = 64
- * maxlines = 6
- *
- * Address Space:
- * 0x00000000 0x00008fff FIFO clusters
- * 0x00010000 0x000104af Channel Management Data Structures
- * 0x000104b0 0x000104ff Free
- * 0x00010500 0x000108bf 15 channels * iqsize
- * 0x000108c0 0x000108ff Free
- * 0x00010900 0x00010e9f IQ's + Cluster Descriptor Tables
- * 15 channels * (iqsize + (maxlines * linesize))
- * 0x00010ea0 0x00010xxx Free
- */
-
-static struct sram_channel cx23885_sram_channels[] = {
- [SRAM_CH01] = {
- .name = "VID A",
- .cmds_start = 0x10000,
- .ctrl_start = 0x10380,
- .cdt = 0x104c0,
- .fifo_start = 0x40,
- .fifo_size = 0x2800,
- .ptr1_reg = DMA1_PTR1,
- .ptr2_reg = DMA1_PTR2,
- .cnt1_reg = DMA1_CNT1,
- .cnt2_reg = DMA1_CNT2,
- },
- [SRAM_CH02] = {
- .name = "ch2",
- .cmds_start = 0x0,
- .ctrl_start = 0x0,
- .cdt = 0x0,
- .fifo_start = 0x0,
- .fifo_size = 0x0,
- .ptr1_reg = DMA2_PTR1,
- .ptr2_reg = DMA2_PTR2,
- .cnt1_reg = DMA2_CNT1,
- .cnt2_reg = DMA2_CNT2,
- },
- [SRAM_CH03] = {
- .name = "TS1 B",
- .cmds_start = 0x100A0,
- .ctrl_start = 0x10400,
- .cdt = 0x10580,
- .fifo_start = 0x5000,
- .fifo_size = 0x1000,
- .ptr1_reg = DMA3_PTR1,
- .ptr2_reg = DMA3_PTR2,
- .cnt1_reg = DMA3_CNT1,
- .cnt2_reg = DMA3_CNT2,
- },
- [SRAM_CH04] = {
- .name = "ch4",
- .cmds_start = 0x0,
- .ctrl_start = 0x0,
- .cdt = 0x0,
- .fifo_start = 0x0,
- .fifo_size = 0x0,
- .ptr1_reg = DMA4_PTR1,
- .ptr2_reg = DMA4_PTR2,
- .cnt1_reg = DMA4_CNT1,
- .cnt2_reg = DMA4_CNT2,
- },
- [SRAM_CH05] = {
- .name = "ch5",
- .cmds_start = 0x0,
- .ctrl_start = 0x0,
- .cdt = 0x0,
- .fifo_start = 0x0,
- .fifo_size = 0x0,
- .ptr1_reg = DMA5_PTR1,
- .ptr2_reg = DMA5_PTR2,
- .cnt1_reg = DMA5_CNT1,
- .cnt2_reg = DMA5_CNT2,
- },
- [SRAM_CH06] = {
- .name = "TS2 C",
- .cmds_start = 0x10140,
- .ctrl_start = 0x10440,
- .cdt = 0x105e0,
- .fifo_start = 0x6000,
- .fifo_size = 0x1000,
- .ptr1_reg = DMA5_PTR1,
- .ptr2_reg = DMA5_PTR2,
- .cnt1_reg = DMA5_CNT1,
- .cnt2_reg = DMA5_CNT2,
- },
- [SRAM_CH07] = {
- .name = "TV Audio",
- .cmds_start = 0x10190,
- .ctrl_start = 0x10480,
- .cdt = 0x10a00,
- .fifo_start = 0x7000,
- .fifo_size = 0x1000,
- .ptr1_reg = DMA6_PTR1,
- .ptr2_reg = DMA6_PTR2,
- .cnt1_reg = DMA6_CNT1,
- .cnt2_reg = DMA6_CNT2,
- },
- [SRAM_CH08] = {
- .name = "ch8",
- .cmds_start = 0x0,
- .ctrl_start = 0x0,
- .cdt = 0x0,
- .fifo_start = 0x0,
- .fifo_size = 0x0,
- .ptr1_reg = DMA7_PTR1,
- .ptr2_reg = DMA7_PTR2,
- .cnt1_reg = DMA7_CNT1,
- .cnt2_reg = DMA7_CNT2,
- },
- [SRAM_CH09] = {
- .name = "ch9",
- .cmds_start = 0x0,
- .ctrl_start = 0x0,
- .cdt = 0x0,
- .fifo_start = 0x0,
- .fifo_size = 0x0,
- .ptr1_reg = DMA8_PTR1,
- .ptr2_reg = DMA8_PTR2,
- .cnt1_reg = DMA8_CNT1,
- .cnt2_reg = DMA8_CNT2,
- },
-};
-
-static struct sram_channel cx23887_sram_channels[] = {
- [SRAM_CH01] = {
- .name = "VID A",
- .cmds_start = 0x10000,
- .ctrl_start = 0x105b0,
- .cdt = 0x107b0,
- .fifo_start = 0x40,
- .fifo_size = 0x2800,
- .ptr1_reg = DMA1_PTR1,
- .ptr2_reg = DMA1_PTR2,
- .cnt1_reg = DMA1_CNT1,
- .cnt2_reg = DMA1_CNT2,
- },
- [SRAM_CH02] = {
- .name = "VID A (VBI)",
- .cmds_start = 0x10050,
- .ctrl_start = 0x105F0,
- .cdt = 0x10810,
- .fifo_start = 0x3000,
- .fifo_size = 0x1000,
- .ptr1_reg = DMA2_PTR1,
- .ptr2_reg = DMA2_PTR2,
- .cnt1_reg = DMA2_CNT1,
- .cnt2_reg = DMA2_CNT2,
- },
- [SRAM_CH03] = {
- .name = "TS1 B",
- .cmds_start = 0x100A0,
- .ctrl_start = 0x10630,
- .cdt = 0x10870,
- .fifo_start = 0x5000,
- .fifo_size = 0x1000,
- .ptr1_reg = DMA3_PTR1,
- .ptr2_reg = DMA3_PTR2,
- .cnt1_reg = DMA3_CNT1,
- .cnt2_reg = DMA3_CNT2,
- },
- [SRAM_CH04] = {
- .name = "ch4",
- .cmds_start = 0x0,
- .ctrl_start = 0x0,
- .cdt = 0x0,
- .fifo_start = 0x0,
- .fifo_size = 0x0,
- .ptr1_reg = DMA4_PTR1,
- .ptr2_reg = DMA4_PTR2,
- .cnt1_reg = DMA4_CNT1,
- .cnt2_reg = DMA4_CNT2,
- },
- [SRAM_CH05] = {
- .name = "ch5",
- .cmds_start = 0x0,
- .ctrl_start = 0x0,
- .cdt = 0x0,
- .fifo_start = 0x0,
- .fifo_size = 0x0,
- .ptr1_reg = DMA5_PTR1,
- .ptr2_reg = DMA5_PTR2,
- .cnt1_reg = DMA5_CNT1,
- .cnt2_reg = DMA5_CNT2,
- },
- [SRAM_CH06] = {
- .name = "TS2 C",
- .cmds_start = 0x10140,
- .ctrl_start = 0x10670,
- .cdt = 0x108d0,
- .fifo_start = 0x6000,
- .fifo_size = 0x1000,
- .ptr1_reg = DMA5_PTR1,
- .ptr2_reg = DMA5_PTR2,
- .cnt1_reg = DMA5_CNT1,
- .cnt2_reg = DMA5_CNT2,
- },
- [SRAM_CH07] = {
- .name = "TV Audio",
- .cmds_start = 0x10190,
- .ctrl_start = 0x106B0,
- .cdt = 0x10930,
- .fifo_start = 0x7000,
- .fifo_size = 0x1000,
- .ptr1_reg = DMA6_PTR1,
- .ptr2_reg = DMA6_PTR2,
- .cnt1_reg = DMA6_CNT1,
- .cnt2_reg = DMA6_CNT2,
- },
- [SRAM_CH08] = {
- .name = "ch8",
- .cmds_start = 0x0,
- .ctrl_start = 0x0,
- .cdt = 0x0,
- .fifo_start = 0x0,
- .fifo_size = 0x0,
- .ptr1_reg = DMA7_PTR1,
- .ptr2_reg = DMA7_PTR2,
- .cnt1_reg = DMA7_CNT1,
- .cnt2_reg = DMA7_CNT2,
- },
- [SRAM_CH09] = {
- .name = "ch9",
- .cmds_start = 0x0,
- .ctrl_start = 0x0,
- .cdt = 0x0,
- .fifo_start = 0x0,
- .fifo_size = 0x0,
- .ptr1_reg = DMA8_PTR1,
- .ptr2_reg = DMA8_PTR2,
- .cnt1_reg = DMA8_CNT1,
- .cnt2_reg = DMA8_CNT2,
- },
-};
-
-void cx23885_irq_add(struct cx23885_dev *dev, u32 mask)
-{
- unsigned long flags;
- spin_lock_irqsave(&dev->pci_irqmask_lock, flags);
-
- dev->pci_irqmask |= mask;
-
- spin_unlock_irqrestore(&dev->pci_irqmask_lock, flags);
-}
-
-void cx23885_irq_add_enable(struct cx23885_dev *dev, u32 mask)
-{
- unsigned long flags;
- spin_lock_irqsave(&dev->pci_irqmask_lock, flags);
-
- dev->pci_irqmask |= mask;
- cx_set(PCI_INT_MSK, mask);
-
- spin_unlock_irqrestore(&dev->pci_irqmask_lock, flags);
-}
-
-void cx23885_irq_enable(struct cx23885_dev *dev, u32 mask)
-{
- u32 v;
- unsigned long flags;
- spin_lock_irqsave(&dev->pci_irqmask_lock, flags);
-
- v = mask & dev->pci_irqmask;
- if (v)
- cx_set(PCI_INT_MSK, v);
-
- spin_unlock_irqrestore(&dev->pci_irqmask_lock, flags);
-}
-
-static inline void cx23885_irq_enable_all(struct cx23885_dev *dev)
-{
- cx23885_irq_enable(dev, 0xffffffff);
-}
-
-void cx23885_irq_disable(struct cx23885_dev *dev, u32 mask)
-{
- unsigned long flags;
- spin_lock_irqsave(&dev->pci_irqmask_lock, flags);
-
- cx_clear(PCI_INT_MSK, mask);
-
- spin_unlock_irqrestore(&dev->pci_irqmask_lock, flags);
-}
-
-static inline void cx23885_irq_disable_all(struct cx23885_dev *dev)
-{
- cx23885_irq_disable(dev, 0xffffffff);
-}
-
-void cx23885_irq_remove(struct cx23885_dev *dev, u32 mask)
-{
- unsigned long flags;
- spin_lock_irqsave(&dev->pci_irqmask_lock, flags);
-
- dev->pci_irqmask &= ~mask;
- cx_clear(PCI_INT_MSK, mask);
-
- spin_unlock_irqrestore(&dev->pci_irqmask_lock, flags);
-}
-
-static u32 cx23885_irq_get_mask(struct cx23885_dev *dev)
-{
- u32 v;
- unsigned long flags;
- spin_lock_irqsave(&dev->pci_irqmask_lock, flags);
-
- v = cx_read(PCI_INT_MSK);
-
- spin_unlock_irqrestore(&dev->pci_irqmask_lock, flags);
- return v;
-}
-
-static int cx23885_risc_decode(u32 risc)
-{
- static char *instr[16] = {
- [RISC_SYNC >> 28] = "sync",
- [RISC_WRITE >> 28] = "write",
- [RISC_WRITEC >> 28] = "writec",
- [RISC_READ >> 28] = "read",
- [RISC_READC >> 28] = "readc",
- [RISC_JUMP >> 28] = "jump",
- [RISC_SKIP >> 28] = "skip",
- [RISC_WRITERM >> 28] = "writerm",
- [RISC_WRITECM >> 28] = "writecm",
- [RISC_WRITECR >> 28] = "writecr",
- };
- static int incr[16] = {
- [RISC_WRITE >> 28] = 3,
- [RISC_JUMP >> 28] = 3,
- [RISC_SKIP >> 28] = 1,
- [RISC_SYNC >> 28] = 1,
- [RISC_WRITERM >> 28] = 3,
- [RISC_WRITECM >> 28] = 3,
- [RISC_WRITECR >> 28] = 4,
- };
- static char *bits[] = {
- "12", "13", "14", "resync",
- "cnt0", "cnt1", "18", "19",
- "20", "21", "22", "23",
- "irq1", "irq2", "eol", "sol",
- };
- int i;
-
- printk("0x%08x [ %s", risc,
- instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
- for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--)
- if (risc & (1 << (i + 12)))
- printk(" %s", bits[i]);
- printk(" count=%d ]\n", risc & 0xfff);
- return incr[risc >> 28] ? incr[risc >> 28] : 1;
-}
-
-void cx23885_wakeup(struct cx23885_tsport *port,
- struct cx23885_dmaqueue *q, u32 count)
-{
- struct cx23885_dev *dev = port->dev;
- struct cx23885_buffer *buf;
- int bc;
-
- for (bc = 0;; bc++) {
- if (list_empty(&q->active))
- break;
- buf = list_entry(q->active.next,
- struct cx23885_buffer, vb.queue);
-
- /* count comes from the hw and is is 16bit wide --
- * this trick handles wrap-arounds correctly for
- * up to 32767 buffers in flight... */
- if ((s16) (count - buf->count) < 0)
- break;
-
- do_gettimeofday(&buf->vb.ts);
- dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i,
- count, buf->count);
- buf->vb.state = VIDEOBUF_DONE;
- list_del(&buf->vb.queue);
- wake_up(&buf->vb.done);
- }
- if (list_empty(&q->active))
- del_timer(&q->timeout);
- else
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- if (bc != 1)
- printk(KERN_WARNING "%s: %d buffers handled (should be 1)\n",
- __func__, bc);
-}
-
-int cx23885_sram_channel_setup(struct cx23885_dev *dev,
- struct sram_channel *ch,
- unsigned int bpl, u32 risc)
-{
- unsigned int i, lines;
- u32 cdt;
-
- if (ch->cmds_start == 0) {
- dprintk(1, "%s() Erasing channel [%s]\n", __func__,
- ch->name);
- cx_write(ch->ptr1_reg, 0);
- cx_write(ch->ptr2_reg, 0);
- cx_write(ch->cnt2_reg, 0);
- cx_write(ch->cnt1_reg, 0);
- return 0;
- } else {
- dprintk(1, "%s() Configuring channel [%s]\n", __func__,
- ch->name);
- }
-
- bpl = (bpl + 7) & ~7; /* alignment */
- cdt = ch->cdt;
- lines = ch->fifo_size / bpl;
- if (lines > 6)
- lines = 6;
- BUG_ON(lines < 2);
-
- cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- cx_write(8 + 4, 8);
- cx_write(8 + 8, 0);
-
- /* write CDT */
- for (i = 0; i < lines; i++) {
- dprintk(2, "%s() 0x%08x <- 0x%08x\n", __func__, cdt + 16*i,
- ch->fifo_start + bpl*i);
- cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
- cx_write(cdt + 16*i + 4, 0);
- cx_write(cdt + 16*i + 8, 0);
- cx_write(cdt + 16*i + 12, 0);
- }
-
- /* write CMDS */
- if (ch->jumponly)
- cx_write(ch->cmds_start + 0, 8);
- else
- cx_write(ch->cmds_start + 0, risc);
- cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
- cx_write(ch->cmds_start + 8, cdt);
- cx_write(ch->cmds_start + 12, (lines*16) >> 3);
- cx_write(ch->cmds_start + 16, ch->ctrl_start);
- if (ch->jumponly)
- cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
- else
- cx_write(ch->cmds_start + 20, 64 >> 2);
- for (i = 24; i < 80; i += 4)
- cx_write(ch->cmds_start + i, 0);
-
- /* fill registers */
- cx_write(ch->ptr1_reg, ch->fifo_start);
- cx_write(ch->ptr2_reg, cdt);
- cx_write(ch->cnt2_reg, (lines*16) >> 3);
- cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
-
- dprintk(2, "[bridge %d] sram setup %s: bpl=%d lines=%d\n",
- dev->bridge,
- ch->name,
- bpl,
- lines);
-
- return 0;
-}
-
-void cx23885_sram_channel_dump(struct cx23885_dev *dev,
- struct sram_channel *ch)
-{
- static char *name[] = {
- "init risc lo",
- "init risc hi",
- "cdt base",
- "cdt size",
- "iq base",
- "iq size",
- "risc pc lo",
- "risc pc hi",
- "iq wr ptr",
- "iq rd ptr",
- "cdt current",
- "pci target lo",
- "pci target hi",
- "line / byte",
- };
- u32 risc;
- unsigned int i, j, n;
-
- printk(KERN_WARNING "%s: %s - dma channel status dump\n",
- dev->name, ch->name);
- for (i = 0; i < ARRAY_SIZE(name); i++)
- printk(KERN_WARNING "%s: cmds: %-15s: 0x%08x\n",
- dev->name, name[i],
- cx_read(ch->cmds_start + 4*i));
-
- for (i = 0; i < 4; i++) {
- risc = cx_read(ch->cmds_start + 4 * (i + 14));
- printk(KERN_WARNING "%s: risc%d: ", dev->name, i);
- cx23885_risc_decode(risc);
- }
- for (i = 0; i < (64 >> 2); i += n) {
- risc = cx_read(ch->ctrl_start + 4 * i);
- /* No consideration for bits 63-32 */
-
- printk(KERN_WARNING "%s: (0x%08x) iq %x: ", dev->name,
- ch->ctrl_start + 4 * i, i);
- n = cx23885_risc_decode(risc);
- for (j = 1; j < n; j++) {
- risc = cx_read(ch->ctrl_start + 4 * (i + j));
- printk(KERN_WARNING "%s: iq %x: 0x%08x [ arg #%d ]\n",
- dev->name, i+j, risc, j);
- }
- }
-
- printk(KERN_WARNING "%s: fifo: 0x%08x -> 0x%x\n",
- dev->name, ch->fifo_start, ch->fifo_start+ch->fifo_size);
- printk(KERN_WARNING "%s: ctrl: 0x%08x -> 0x%x\n",
- dev->name, ch->ctrl_start, ch->ctrl_start + 6*16);
- printk(KERN_WARNING "%s: ptr1_reg: 0x%08x\n",
- dev->name, cx_read(ch->ptr1_reg));
- printk(KERN_WARNING "%s: ptr2_reg: 0x%08x\n",
- dev->name, cx_read(ch->ptr2_reg));
- printk(KERN_WARNING "%s: cnt1_reg: 0x%08x\n",
- dev->name, cx_read(ch->cnt1_reg));
- printk(KERN_WARNING "%s: cnt2_reg: 0x%08x\n",
- dev->name, cx_read(ch->cnt2_reg));
-}
-
-static void cx23885_risc_disasm(struct cx23885_tsport *port,
- struct btcx_riscmem *risc)
-{
- struct cx23885_dev *dev = port->dev;
- unsigned int i, j, n;
-
- printk(KERN_INFO "%s: risc disasm: %p [dma=0x%08lx]\n",
- dev->name, risc->cpu, (unsigned long)risc->dma);
- for (i = 0; i < (risc->size >> 2); i += n) {
- printk(KERN_INFO "%s: %04d: ", dev->name, i);
- n = cx23885_risc_decode(le32_to_cpu(risc->cpu[i]));
- for (j = 1; j < n; j++)
- printk(KERN_INFO "%s: %04d: 0x%08x [ arg #%d ]\n",
- dev->name, i + j, risc->cpu[i + j], j);
- if (risc->cpu[i] == cpu_to_le32(RISC_JUMP))
- break;
- }
-}
-
-static void cx23885_shutdown(struct cx23885_dev *dev)
-{
- /* disable RISC controller */
- cx_write(DEV_CNTRL2, 0);
-
- /* Disable all IR activity */
- cx_write(IR_CNTRL_REG, 0);
-
- /* Disable Video A/B activity */
- cx_write(VID_A_DMA_CTL, 0);
- cx_write(VID_B_DMA_CTL, 0);
- cx_write(VID_C_DMA_CTL, 0);
-
- /* Disable Audio activity */
- cx_write(AUD_INT_DMA_CTL, 0);
- cx_write(AUD_EXT_DMA_CTL, 0);
-
- /* Disable Serial port */
- cx_write(UART_CTL, 0);
-
- /* Disable Interrupts */
- cx23885_irq_disable_all(dev);
- cx_write(VID_A_INT_MSK, 0);
- cx_write(VID_B_INT_MSK, 0);
- cx_write(VID_C_INT_MSK, 0);
- cx_write(AUDIO_INT_INT_MSK, 0);
- cx_write(AUDIO_EXT_INT_MSK, 0);
-
-}
-
-static void cx23885_reset(struct cx23885_dev *dev)
-{
- dprintk(1, "%s()\n", __func__);
-
- cx23885_shutdown(dev);
-
- cx_write(PCI_INT_STAT, 0xffffffff);
- cx_write(VID_A_INT_STAT, 0xffffffff);
- cx_write(VID_B_INT_STAT, 0xffffffff);
- cx_write(VID_C_INT_STAT, 0xffffffff);
- cx_write(AUDIO_INT_INT_STAT, 0xffffffff);
- cx_write(AUDIO_EXT_INT_STAT, 0xffffffff);
- cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
- cx_write(PAD_CTRL, 0x00500300);
-
- mdelay(100);
-
- cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01],
- 720*4, 0);
- cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02], 128, 0);
- cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH03],
- 188*4, 0);
- cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH04], 128, 0);
- cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH05], 128, 0);
- cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH06],
- 188*4, 0);
- cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH07], 128, 0);
- cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH08], 128, 0);
- cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH09], 128, 0);
-
- cx23885_gpio_setup(dev);
-}
-
-
-static int cx23885_pci_quirks(struct cx23885_dev *dev)
-{
- dprintk(1, "%s()\n", __func__);
-
- /* The cx23885 bridge has a weird bug which causes NMI to be asserted
- * when DMA begins if RDR_TLCTL0 bit4 is not cleared. It does not
- * occur on the cx23887 bridge.
- */
- if (dev->bridge == CX23885_BRIDGE_885)
- cx_clear(RDR_TLCTL0, 1 << 4);
-
- return 0;
-}
-
-static int get_resources(struct cx23885_dev *dev)
-{
- if (request_mem_region(pci_resource_start(dev->pci, 0),
- pci_resource_len(dev->pci, 0),
- dev->name))
- return 0;
-
- printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
- dev->name, (unsigned long long)pci_resource_start(dev->pci, 0));
-
- return -EBUSY;
-}
-
-static void cx23885_timeout(unsigned long data);
-int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
- u32 reg, u32 mask, u32 value);
-
-static int cx23885_init_tsport(struct cx23885_dev *dev,
- struct cx23885_tsport *port, int portno)
-{
- dprintk(1, "%s(portno=%d)\n", __func__, portno);
-
- /* Transport bus init dma queue - Common settings */
- port->dma_ctl_val = 0x11; /* Enable RISC controller and Fifo */
- port->ts_int_msk_val = 0x1111; /* TS port bits for RISC */
- port->vld_misc_val = 0x0;
- port->hw_sop_ctrl_val = (0x47 << 16 | 188 << 4);
-
- spin_lock_init(&port->slock);
- port->dev = dev;
- port->nr = portno;
-
- INIT_LIST_HEAD(&port->mpegq.active);
- INIT_LIST_HEAD(&port->mpegq.queued);
- port->mpegq.timeout.function = cx23885_timeout;
- port->mpegq.timeout.data = (unsigned long)port;
- init_timer(&port->mpegq.timeout);
-
- mutex_init(&port->frontends.lock);
- INIT_LIST_HEAD(&port->frontends.felist);
- port->frontends.active_fe_id = 0;
-
- /* This should be hardcoded allow a single frontend
- * attachment to this tsport, keeping the -dvb.c
- * code clean and safe.
- */
- if (!port->num_frontends)
- port->num_frontends = 1;
-
- switch (portno) {
- case 1:
- port->reg_gpcnt = VID_B_GPCNT;
- port->reg_gpcnt_ctl = VID_B_GPCNT_CTL;
- port->reg_dma_ctl = VID_B_DMA_CTL;
- port->reg_lngth = VID_B_LNGTH;
- port->reg_hw_sop_ctrl = VID_B_HW_SOP_CTL;
- port->reg_gen_ctrl = VID_B_GEN_CTL;
- port->reg_bd_pkt_status = VID_B_BD_PKT_STATUS;
- port->reg_sop_status = VID_B_SOP_STATUS;
- port->reg_fifo_ovfl_stat = VID_B_FIFO_OVFL_STAT;
- port->reg_vld_misc = VID_B_VLD_MISC;
- port->reg_ts_clk_en = VID_B_TS_CLK_EN;
- port->reg_src_sel = VID_B_SRC_SEL;
- port->reg_ts_int_msk = VID_B_INT_MSK;
- port->reg_ts_int_stat = VID_B_INT_STAT;
- port->sram_chno = SRAM_CH03; /* VID_B */
- port->pci_irqmask = 0x02; /* VID_B bit1 */
- break;
- case 2:
- port->reg_gpcnt = VID_C_GPCNT;
- port->reg_gpcnt_ctl = VID_C_GPCNT_CTL;
- port->reg_dma_ctl = VID_C_DMA_CTL;
- port->reg_lngth = VID_C_LNGTH;
- port->reg_hw_sop_ctrl = VID_C_HW_SOP_CTL;
- port->reg_gen_ctrl = VID_C_GEN_CTL;
- port->reg_bd_pkt_status = VID_C_BD_PKT_STATUS;
- port->reg_sop_status = VID_C_SOP_STATUS;
- port->reg_fifo_ovfl_stat = VID_C_FIFO_OVFL_STAT;
- port->reg_vld_misc = VID_C_VLD_MISC;
- port->reg_ts_clk_en = VID_C_TS_CLK_EN;
- port->reg_src_sel = 0;
- port->reg_ts_int_msk = VID_C_INT_MSK;
- port->reg_ts_int_stat = VID_C_INT_STAT;
- port->sram_chno = SRAM_CH06; /* VID_C */
- port->pci_irqmask = 0x04; /* VID_C bit2 */
- break;
- default:
- BUG();
- }
-
- cx23885_risc_stopper(dev->pci, &port->mpegq.stopper,
- port->reg_dma_ctl, port->dma_ctl_val, 0x00);
-
- return 0;
-}
-
-static void cx23885_dev_checkrevision(struct cx23885_dev *dev)
-{
- switch (cx_read(RDR_CFG2) & 0xff) {
- case 0x00:
- /* cx23885 */
- dev->hwrevision = 0xa0;
- break;
- case 0x01:
- /* CX23885-12Z */
- dev->hwrevision = 0xa1;
- break;
- case 0x02:
- /* CX23885-13Z/14Z */
- dev->hwrevision = 0xb0;
- break;
- case 0x03:
- if (dev->pci->device == 0x8880) {
- /* CX23888-21Z/22Z */
- dev->hwrevision = 0xc0;
- } else {
- /* CX23885-14Z */
- dev->hwrevision = 0xa4;
- }
- break;
- case 0x04:
- if (dev->pci->device == 0x8880) {
- /* CX23888-31Z */
- dev->hwrevision = 0xd0;
- } else {
- /* CX23885-15Z, CX23888-31Z */
- dev->hwrevision = 0xa5;
- }
- break;
- case 0x0e:
- /* CX23887-15Z */
- dev->hwrevision = 0xc0;
- break;
- case 0x0f:
- /* CX23887-14Z */
- dev->hwrevision = 0xb1;
- break;
- default:
- printk(KERN_ERR "%s() New hardware revision found 0x%x\n",
- __func__, dev->hwrevision);
- }
- if (dev->hwrevision)
- printk(KERN_INFO "%s() Hardware revision = 0x%02x\n",
- __func__, dev->hwrevision);
- else
- printk(KERN_ERR "%s() Hardware revision unknown 0x%x\n",
- __func__, dev->hwrevision);
-}
-
-/* Find the first v4l2_subdev member of the group id in hw */
-struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw)
-{
- struct v4l2_subdev *result = NULL;
- struct v4l2_subdev *sd;
-
- spin_lock(&dev->v4l2_dev.lock);
- v4l2_device_for_each_subdev(sd, &dev->v4l2_dev) {
- if (sd->grp_id == hw) {
- result = sd;
- break;
- }
- }
- spin_unlock(&dev->v4l2_dev.lock);
- return result;
-}
-
-static int cx23885_dev_setup(struct cx23885_dev *dev)
-{
- int i;
-
- spin_lock_init(&dev->pci_irqmask_lock);
-
- mutex_init(&dev->lock);
- mutex_init(&dev->gpio_lock);
-
- atomic_inc(&dev->refcount);
-
- dev->nr = cx23885_devcount++;
- sprintf(dev->name, "cx23885[%d]", dev->nr);
-
- /* Configure the internal memory */
- if (dev->pci->device == 0x8880) {
- /* Could be 887 or 888, assume a default */
- dev->bridge = CX23885_BRIDGE_887;
- /* Apply a sensible clock frequency for the PCIe bridge */
- dev->clk_freq = 25000000;
- dev->sram_channels = cx23887_sram_channels;
- } else
- if (dev->pci->device == 0x8852) {
- dev->bridge = CX23885_BRIDGE_885;
- /* Apply a sensible clock frequency for the PCIe bridge */
- dev->clk_freq = 28000000;
- dev->sram_channels = cx23885_sram_channels;
- } else
- BUG();
-
- dprintk(1, "%s() Memory configured for PCIe bridge type %d\n",
- __func__, dev->bridge);
-
- /* board config */
- dev->board = UNSET;
- if (card[dev->nr] < cx23885_bcount)
- dev->board = card[dev->nr];
- for (i = 0; UNSET == dev->board && i < cx23885_idcount; i++)
- if (dev->pci->subsystem_vendor == cx23885_subids[i].subvendor &&
- dev->pci->subsystem_device == cx23885_subids[i].subdevice)
- dev->board = cx23885_subids[i].card;
- if (UNSET == dev->board) {
- dev->board = CX23885_BOARD_UNKNOWN;
- cx23885_card_list(dev);
- }
-
- /* If the user specific a clk freq override, apply it */
- if (cx23885_boards[dev->board].clk_freq > 0)
- dev->clk_freq = cx23885_boards[dev->board].clk_freq;
-
- dev->pci_bus = dev->pci->bus->number;
- dev->pci_slot = PCI_SLOT(dev->pci->devfn);
- cx23885_irq_add(dev, 0x001f00);
-
- /* External Master 1 Bus */
- dev->i2c_bus[0].nr = 0;
- dev->i2c_bus[0].dev = dev;
- dev->i2c_bus[0].reg_stat = I2C1_STAT;
- dev->i2c_bus[0].reg_ctrl = I2C1_CTRL;
- dev->i2c_bus[0].reg_addr = I2C1_ADDR;
- dev->i2c_bus[0].reg_rdata = I2C1_RDATA;
- dev->i2c_bus[0].reg_wdata = I2C1_WDATA;
- dev->i2c_bus[0].i2c_period = (0x9d << 24); /* 100kHz */
-
- /* External Master 2 Bus */
- dev->i2c_bus[1].nr = 1;
- dev->i2c_bus[1].dev = dev;
- dev->i2c_bus[1].reg_stat = I2C2_STAT;
- dev->i2c_bus[1].reg_ctrl = I2C2_CTRL;
- dev->i2c_bus[1].reg_addr = I2C2_ADDR;
- dev->i2c_bus[1].reg_rdata = I2C2_RDATA;
- dev->i2c_bus[1].reg_wdata = I2C2_WDATA;
- dev->i2c_bus[1].i2c_period = (0x9d << 24); /* 100kHz */
-
- /* Internal Master 3 Bus */
- dev->i2c_bus[2].nr = 2;
- dev->i2c_bus[2].dev = dev;
- dev->i2c_bus[2].reg_stat = I2C3_STAT;
- dev->i2c_bus[2].reg_ctrl = I2C3_CTRL;
- dev->i2c_bus[2].reg_addr = I2C3_ADDR;
- dev->i2c_bus[2].reg_rdata = I2C3_RDATA;
- dev->i2c_bus[2].reg_wdata = I2C3_WDATA;
- dev->i2c_bus[2].i2c_period = (0x07 << 24); /* 1.95MHz */
-
- if ((cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) ||
- (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER))
- cx23885_init_tsport(dev, &dev->ts1, 1);
-
- if ((cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) ||
- (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER))
- cx23885_init_tsport(dev, &dev->ts2, 2);
-
- if (get_resources(dev) < 0) {
- printk(KERN_ERR "CORE %s No more PCIe resources for "
- "subsystem: %04x:%04x\n",
- dev->name, dev->pci->subsystem_vendor,
- dev->pci->subsystem_device);
-
- cx23885_devcount--;
- return -ENODEV;
- }
-
- /* PCIe stuff */
- dev->lmmio = ioremap(pci_resource_start(dev->pci, 0),
- pci_resource_len(dev->pci, 0));
-
- dev->bmmio = (u8 __iomem *)dev->lmmio;
-
- printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
- dev->name, dev->pci->subsystem_vendor,
- dev->pci->subsystem_device, cx23885_boards[dev->board].name,
- dev->board, card[dev->nr] == dev->board ?
- "insmod option" : "autodetected");
-
- cx23885_pci_quirks(dev);
-
- /* Assume some sensible defaults */
- dev->tuner_type = cx23885_boards[dev->board].tuner_type;
- dev->tuner_addr = cx23885_boards[dev->board].tuner_addr;
- dev->tuner_bus = cx23885_boards[dev->board].tuner_bus;
- dev->radio_type = cx23885_boards[dev->board].radio_type;
- dev->radio_addr = cx23885_boards[dev->board].radio_addr;
-
- dprintk(1, "%s() tuner_type = 0x%x tuner_addr = 0x%x tuner_bus = %d\n",
- __func__, dev->tuner_type, dev->tuner_addr, dev->tuner_bus);
- dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n",
- __func__, dev->radio_type, dev->radio_addr);
-
- /* The cx23417 encoder has GPIO's that need to be initialised
- * before DVB, so that demodulators and tuners are out of
- * reset before DVB uses them.
- */
- if ((cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) ||
- (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER))
- cx23885_mc417_init(dev);
-
- /* init hardware */
- cx23885_reset(dev);
-
- cx23885_i2c_register(&dev->i2c_bus[0]);
- cx23885_i2c_register(&dev->i2c_bus[1]);
- cx23885_i2c_register(&dev->i2c_bus[2]);
- cx23885_card_setup(dev);
- call_all(dev, core, s_power, 0);
- cx23885_ir_init(dev);
-
- if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
- if (cx23885_video_register(dev) < 0) {
- printk(KERN_ERR "%s() Failed to register analog "
- "video adapters on VID_A\n", __func__);
- }
- }
-
- if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) {
- if (cx23885_boards[dev->board].num_fds_portb)
- dev->ts1.num_frontends =
- cx23885_boards[dev->board].num_fds_portb;
- if (cx23885_dvb_register(&dev->ts1) < 0) {
- printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n",
- __func__);
- }
- } else
- if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) {
- if (cx23885_417_register(dev) < 0) {
- printk(KERN_ERR
- "%s() Failed to register 417 on VID_B\n",
- __func__);
- }
- }
-
- if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) {
- if (cx23885_boards[dev->board].num_fds_portc)
- dev->ts2.num_frontends =
- cx23885_boards[dev->board].num_fds_portc;
- if (cx23885_dvb_register(&dev->ts2) < 0) {
- printk(KERN_ERR
- "%s() Failed to register dvb on VID_C\n",
- __func__);
- }
- } else
- if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER) {
- if (cx23885_417_register(dev) < 0) {
- printk(KERN_ERR
- "%s() Failed to register 417 on VID_C\n",
- __func__);
- }
- }
-
- cx23885_dev_checkrevision(dev);
-
- /* disable MSI for NetUP cards, otherwise CI is not working */
- if (cx23885_boards[dev->board].ci_type > 0)
- cx_clear(RDR_RDRCTL1, 1 << 8);
-
- switch (dev->board) {
- case CX23885_BOARD_TEVII_S470:
- case CX23885_BOARD_TEVII_S471:
- cx_clear(RDR_RDRCTL1, 1 << 8);
- break;
- }
-
- return 0;
-}
-
-static void cx23885_dev_unregister(struct cx23885_dev *dev)
-{
- release_mem_region(pci_resource_start(dev->pci, 0),
- pci_resource_len(dev->pci, 0));
-
- if (!atomic_dec_and_test(&dev->refcount))
- return;
-
- if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO)
- cx23885_video_unregister(dev);
-
- if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
- cx23885_dvb_unregister(&dev->ts1);
-
- if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER)
- cx23885_417_unregister(dev);
-
- if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB)
- cx23885_dvb_unregister(&dev->ts2);
-
- if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER)
- cx23885_417_unregister(dev);
-
- cx23885_i2c_unregister(&dev->i2c_bus[2]);
- cx23885_i2c_unregister(&dev->i2c_bus[1]);
- cx23885_i2c_unregister(&dev->i2c_bus[0]);
-
- iounmap(dev->lmmio);
-}
-
-static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
- unsigned int offset, u32 sync_line,
- unsigned int bpl, unsigned int padding,
- unsigned int lines, unsigned int lpi)
-{
- struct scatterlist *sg;
- unsigned int line, todo, sol;
-
- /* sync instruction */
- if (sync_line != NO_SYNC_LINE)
- *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
-
- /* scan lines */
- sg = sglist;
- for (line = 0; line < lines; line++) {
- while (offset && offset >= sg_dma_len(sg)) {
- offset -= sg_dma_len(sg);
- sg++;
- }
-
- if (lpi && line > 0 && !(line % lpi))
- sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
- else
- sol = RISC_SOL;
-
- if (bpl <= sg_dma_len(sg)-offset) {
- /* fits into current chunk */
- *(rp++) = cpu_to_le32(RISC_WRITE|sol|RISC_EOL|bpl);
- *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset);
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
- offset += bpl;
- } else {
- /* scanline needs to be split */
- todo = bpl;
- *(rp++) = cpu_to_le32(RISC_WRITE|sol|
- (sg_dma_len(sg)-offset));
- *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset);
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
- todo -= (sg_dma_len(sg)-offset);
- offset = 0;
- sg++;
- while (todo > sg_dma_len(sg)) {
- *(rp++) = cpu_to_le32(RISC_WRITE|
- sg_dma_len(sg));
- *(rp++) = cpu_to_le32(sg_dma_address(sg));
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
- todo -= sg_dma_len(sg);
- sg++;
- }
- *(rp++) = cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
- *(rp++) = cpu_to_le32(sg_dma_address(sg));
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
- offset += todo;
- }
- offset += padding;
- }
-
- return rp;
-}
-
-int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
- struct scatterlist *sglist, unsigned int top_offset,
- unsigned int bottom_offset, unsigned int bpl,
- unsigned int padding, unsigned int lines)
-{
- u32 instructions, fields;
- __le32 *rp;
- int rc;
-
- fields = 0;
- if (UNSET != top_offset)
- fields++;
- if (UNSET != bottom_offset)
- fields++;
-
- /* estimate risc mem: worst case is one write per page border +
- one write per scan line + syncs + jump (all 2 dwords). Padding
- can cause next bpl to start close to a page border. First DMA
- region may be smaller than PAGE_SIZE */
- /* write and jump need and extra dword */
- instructions = fields * (1 + ((bpl + padding) * lines)
- / PAGE_SIZE + lines);
- instructions += 2;
- rc = btcx_riscmem_alloc(pci, risc, instructions*12);
- if (rc < 0)
- return rc;
-
- /* write risc instructions */
- rp = risc->cpu;
- if (UNSET != top_offset)
- rp = cx23885_risc_field(rp, sglist, top_offset, 0,
- bpl, padding, lines, 0);
- if (UNSET != bottom_offset)
- rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
- bpl, padding, lines, 0);
-
- /* save pointer to jmp instruction address */
- risc->jmp = rp;
- BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
- return 0;
-}
-
-int cx23885_risc_databuffer(struct pci_dev *pci,
- struct btcx_riscmem *risc,
- struct scatterlist *sglist,
- unsigned int bpl,
- unsigned int lines, unsigned int lpi)
-{
- u32 instructions;
- __le32 *rp;
- int rc;
-
- /* estimate risc mem: worst case is one write per page border +
- one write per scan line + syncs + jump (all 2 dwords). Here
- there is no padding and no sync. First DMA region may be smaller
- than PAGE_SIZE */
- /* Jump and write need an extra dword */
- instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
- instructions += 1;
-
- rc = btcx_riscmem_alloc(pci, risc, instructions*12);
- if (rc < 0)
- return rc;
-
- /* write risc instructions */
- rp = risc->cpu;
- rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE,
- bpl, 0, lines, lpi);
-
- /* save pointer to jmp instruction address */
- risc->jmp = rp;
- BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
- return 0;
-}
-
-int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
- struct scatterlist *sglist, unsigned int top_offset,
- unsigned int bottom_offset, unsigned int bpl,
- unsigned int padding, unsigned int lines)
-{
- u32 instructions, fields;
- __le32 *rp;
- int rc;
-
- fields = 0;
- if (UNSET != top_offset)
- fields++;
- if (UNSET != bottom_offset)
- fields++;
-
- /* estimate risc mem: worst case is one write per page border +
- one write per scan line + syncs + jump (all 2 dwords). Padding
- can cause next bpl to start close to a page border. First DMA
- region may be smaller than PAGE_SIZE */
- /* write and jump need and extra dword */
- instructions = fields * (1 + ((bpl + padding) * lines)
- / PAGE_SIZE + lines);
- instructions += 2;
- rc = btcx_riscmem_alloc(pci, risc, instructions*12);
- if (rc < 0)
- return rc;
- /* write risc instructions */
- rp = risc->cpu;
-
- /* Sync to line 6, so US CC line 21 will appear in line '12'
- * in the userland vbi payload */
- if (UNSET != top_offset)
- rp = cx23885_risc_field(rp, sglist, top_offset, 6,
- bpl, padding, lines, 0);
-
- if (UNSET != bottom_offset)
- rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x207,
- bpl, padding, lines, 0);
-
-
-
- /* save pointer to jmp instruction address */
- risc->jmp = rp;
- BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
- return 0;
-}
-
-
-int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
- u32 reg, u32 mask, u32 value)
-{
- __le32 *rp;
- int rc;
-
- rc = btcx_riscmem_alloc(pci, risc, 4*16);
- if (rc < 0)
- return rc;
-
- /* write risc instructions */
- rp = risc->cpu;
- *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2);
- *(rp++) = cpu_to_le32(reg);
- *(rp++) = cpu_to_le32(value);
- *(rp++) = cpu_to_le32(mask);
- *(rp++) = cpu_to_le32(RISC_JUMP);
- *(rp++) = cpu_to_le32(risc->dma);
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
- return 0;
-}
-
-void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf)
-{
- struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
-
- BUG_ON(in_interrupt());
- videobuf_waiton(q, &buf->vb, 0, 0);
- videobuf_dma_unmap(q->dev, dma);
- videobuf_dma_free(dma);
- btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static void cx23885_tsport_reg_dump(struct cx23885_tsport *port)
-{
- struct cx23885_dev *dev = port->dev;
-
- dprintk(1, "%s() Register Dump\n", __func__);
- dprintk(1, "%s() DEV_CNTRL2 0x%08X\n", __func__,
- cx_read(DEV_CNTRL2));
- dprintk(1, "%s() PCI_INT_MSK 0x%08X\n", __func__,
- cx23885_irq_get_mask(dev));
- dprintk(1, "%s() AUD_INT_INT_MSK 0x%08X\n", __func__,
- cx_read(AUDIO_INT_INT_MSK));
- dprintk(1, "%s() AUD_INT_DMA_CTL 0x%08X\n", __func__,
- cx_read(AUD_INT_DMA_CTL));
- dprintk(1, "%s() AUD_EXT_INT_MSK 0x%08X\n", __func__,
- cx_read(AUDIO_EXT_INT_MSK));
- dprintk(1, "%s() AUD_EXT_DMA_CTL 0x%08X\n", __func__,
- cx_read(AUD_EXT_DMA_CTL));
- dprintk(1, "%s() PAD_CTRL 0x%08X\n", __func__,
- cx_read(PAD_CTRL));
- dprintk(1, "%s() ALT_PIN_OUT_SEL 0x%08X\n", __func__,
- cx_read(ALT_PIN_OUT_SEL));
- dprintk(1, "%s() GPIO2 0x%08X\n", __func__,
- cx_read(GPIO2));
- dprintk(1, "%s() gpcnt(0x%08X) 0x%08X\n", __func__,
- port->reg_gpcnt, cx_read(port->reg_gpcnt));
- dprintk(1, "%s() gpcnt_ctl(0x%08X) 0x%08x\n", __func__,
- port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl));
- dprintk(1, "%s() dma_ctl(0x%08X) 0x%08x\n", __func__,
- port->reg_dma_ctl, cx_read(port->reg_dma_ctl));
- if (port->reg_src_sel)
- dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __func__,
- port->reg_src_sel, cx_read(port->reg_src_sel));
- dprintk(1, "%s() lngth(0x%08X) 0x%08x\n", __func__,
- port->reg_lngth, cx_read(port->reg_lngth));
- dprintk(1, "%s() hw_sop_ctrl(0x%08X) 0x%08x\n", __func__,
- port->reg_hw_sop_ctrl, cx_read(port->reg_hw_sop_ctrl));
- dprintk(1, "%s() gen_ctrl(0x%08X) 0x%08x\n", __func__,
- port->reg_gen_ctrl, cx_read(port->reg_gen_ctrl));
- dprintk(1, "%s() bd_pkt_status(0x%08X) 0x%08x\n", __func__,
- port->reg_bd_pkt_status, cx_read(port->reg_bd_pkt_status));
- dprintk(1, "%s() sop_status(0x%08X) 0x%08x\n", __func__,
- port->reg_sop_status, cx_read(port->reg_sop_status));
- dprintk(1, "%s() fifo_ovfl_stat(0x%08X) 0x%08x\n", __func__,
- port->reg_fifo_ovfl_stat, cx_read(port->reg_fifo_ovfl_stat));
- dprintk(1, "%s() vld_misc(0x%08X) 0x%08x\n", __func__,
- port->reg_vld_misc, cx_read(port->reg_vld_misc));
- dprintk(1, "%s() ts_clk_en(0x%08X) 0x%08x\n", __func__,
- port->reg_ts_clk_en, cx_read(port->reg_ts_clk_en));
- dprintk(1, "%s() ts_int_msk(0x%08X) 0x%08x\n", __func__,
- port->reg_ts_int_msk, cx_read(port->reg_ts_int_msk));
-}
-
-static int cx23885_start_dma(struct cx23885_tsport *port,
- struct cx23885_dmaqueue *q,
- struct cx23885_buffer *buf)
-{
- struct cx23885_dev *dev = port->dev;
- u32 reg;
-
- dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__,
- buf->vb.width, buf->vb.height, buf->vb.field);
-
- /* Stop the fifo and risc engine for this port */
- cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
-
- /* setup fifo + format */
- cx23885_sram_channel_setup(dev,
- &dev->sram_channels[port->sram_chno],
- port->ts_packet_size, buf->risc.dma);
- if (debug > 5) {
- cx23885_sram_channel_dump(dev,
- &dev->sram_channels[port->sram_chno]);
- cx23885_risc_disasm(port, &buf->risc);
- }
-
- /* write TS length to chip */
- cx_write(port->reg_lngth, buf->vb.width);
-
- if ((!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) &&
- (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB))) {
- printk("%s() Unsupported .portb/c (0x%08x)/(0x%08x)\n",
- __func__,
- cx23885_boards[dev->board].portb,
- cx23885_boards[dev->board].portc);
- return -EINVAL;
- }
-
- if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER)
- cx23885_av_clk(dev, 0);
-
- udelay(100);
-
- /* If the port supports SRC SELECT, configure it */
- if (port->reg_src_sel)
- cx_write(port->reg_src_sel, port->src_sel_val);
-
- cx_write(port->reg_hw_sop_ctrl, port->hw_sop_ctrl_val);
- cx_write(port->reg_ts_clk_en, port->ts_clk_en_val);
- cx_write(port->reg_vld_misc, port->vld_misc_val);
- cx_write(port->reg_gen_ctrl, port->gen_ctrl_val);
- udelay(100);
-
- /* NOTE: this is 2 (reserved) for portb, does it matter? */
- /* reset counter to zero */
- cx_write(port->reg_gpcnt_ctl, 3);
- q->count = 1;
-
- /* Set VIDB pins to input */
- if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) {
- reg = cx_read(PAD_CTRL);
- reg &= ~0x3; /* Clear TS1_OE & TS1_SOP_OE */
- cx_write(PAD_CTRL, reg);
- }
-
- /* Set VIDC pins to input */
- if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) {
- reg = cx_read(PAD_CTRL);
- reg &= ~0x4; /* Clear TS2_SOP_OE */
- cx_write(PAD_CTRL, reg);
- }
-
- if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) {
-
- reg = cx_read(PAD_CTRL);
- reg = reg & ~0x1; /* Clear TS1_OE */
-
- /* FIXME, bit 2 writing here is questionable */
- /* set TS1_SOP_OE and TS1_OE_HI */
- reg = reg | 0xa;
- cx_write(PAD_CTRL, reg);
-
- /* FIXME and these two registers should be documented. */
- cx_write(CLK_DELAY, cx_read(CLK_DELAY) | 0x80000011);
- cx_write(ALT_PIN_OUT_SEL, 0x10100045);
- }
-
- switch (dev->bridge) {
- case CX23885_BRIDGE_885:
- case CX23885_BRIDGE_887:
- case CX23885_BRIDGE_888:
- /* enable irqs */
- dprintk(1, "%s() enabling TS int's and DMA\n", __func__);
- cx_set(port->reg_ts_int_msk, port->ts_int_msk_val);
- cx_set(port->reg_dma_ctl, port->dma_ctl_val);
- cx23885_irq_add(dev, port->pci_irqmask);
- cx23885_irq_enable_all(dev);
- break;
- default:
- BUG();
- }
-
- cx_set(DEV_CNTRL2, (1<<5)); /* Enable RISC controller */
-
- if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER)
- cx23885_av_clk(dev, 1);
-
- if (debug > 4)
- cx23885_tsport_reg_dump(port);
-
- return 0;
-}
-
-static int cx23885_stop_dma(struct cx23885_tsport *port)
-{
- struct cx23885_dev *dev = port->dev;
- u32 reg;
-
- dprintk(1, "%s()\n", __func__);
-
- /* Stop interrupts and DMA */
- cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val);
- cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
-
- if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) {
-
- reg = cx_read(PAD_CTRL);
-
- /* Set TS1_OE */
- reg = reg | 0x1;
-
- /* clear TS1_SOP_OE and TS1_OE_HI */
- reg = reg & ~0xa;
- cx_write(PAD_CTRL, reg);
- cx_write(port->reg_src_sel, 0);
- cx_write(port->reg_gen_ctrl, 8);
-
- }
-
- if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER)
- cx23885_av_clk(dev, 0);
-
- return 0;
-}
-
-int cx23885_restart_queue(struct cx23885_tsport *port,
- struct cx23885_dmaqueue *q)
-{
- struct cx23885_dev *dev = port->dev;
- struct cx23885_buffer *buf;
-
- dprintk(5, "%s()\n", __func__);
- if (list_empty(&q->active)) {
- struct cx23885_buffer *prev;
- prev = NULL;
-
- dprintk(5, "%s() queue is empty\n", __func__);
-
- for (;;) {
- if (list_empty(&q->queued))
- return 0;
- buf = list_entry(q->queued.next, struct cx23885_buffer,
- vb.queue);
- if (NULL == prev) {
- list_del(&buf->vb.queue);
- list_add_tail(&buf->vb.queue, &q->active);
- cx23885_start_dma(port, q, buf);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- dprintk(5, "[%p/%d] restart_queue - f/active\n",
- buf, buf->vb.i);
-
- } else if (prev->vb.width == buf->vb.width &&
- prev->vb.height == buf->vb.height &&
- prev->fmt == buf->fmt) {
- list_del(&buf->vb.queue);
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(5, "[%p/%d] restart_queue - m/active\n",
- buf, buf->vb.i);
- } else {
- return 0;
- }
- prev = buf;
- }
- return 0;
- }
-
- buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue);
- dprintk(2, "restart_queue [%p/%d]: restart dma\n",
- buf, buf->vb.i);
- cx23885_start_dma(port, q, buf);
- list_for_each_entry(buf, &q->active, vb.queue)
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port,
- struct cx23885_buffer *buf, enum v4l2_field field)
-{
- struct cx23885_dev *dev = port->dev;
- int size = port->ts_packet_size * port->ts_packet_count;
- int rc;
-
- dprintk(1, "%s: %p\n", __func__, buf);
- if (0 != buf->vb.baddr && buf->vb.bsize < size)
- return -EINVAL;
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- buf->vb.width = port->ts_packet_size;
- buf->vb.height = port->ts_packet_count;
- buf->vb.size = size;
- buf->vb.field = field /*V4L2_FIELD_TOP*/;
-
- rc = videobuf_iolock(q, &buf->vb, NULL);
- if (0 != rc)
- goto fail;
- cx23885_risc_databuffer(dev->pci, &buf->risc,
- videobuf_to_dma(&buf->vb)->sglist,
- buf->vb.width, buf->vb.height, 0);
- }
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
- fail:
- cx23885_free_buffer(q, buf);
- return rc;
-}
-
-void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf)
-{
- struct cx23885_buffer *prev;
- struct cx23885_dev *dev = port->dev;
- struct cx23885_dmaqueue *cx88q = &port->mpegq;
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- if (list_empty(&cx88q->active)) {
- dprintk(1, "queue is empty - first active\n");
- list_add_tail(&buf->vb.queue, &cx88q->active);
- cx23885_start_dma(port, cx88q, buf);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = cx88q->count++;
- mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT);
- dprintk(1, "[%p/%d] %s - first active\n",
- buf, buf->vb.i, __func__);
- } else {
- dprintk(1, "queue is not empty - append to active\n");
- prev = list_entry(cx88q->active.prev, struct cx23885_buffer,
- vb.queue);
- list_add_tail(&buf->vb.queue, &cx88q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = cx88q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */
- dprintk(1, "[%p/%d] %s - append to active\n",
- buf, buf->vb.i, __func__);
- }
-}
-
-/* ----------------------------------------------------------- */
-
-static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,
- int restart)
-{
- struct cx23885_dev *dev = port->dev;
- struct cx23885_dmaqueue *q = &port->mpegq;
- struct cx23885_buffer *buf;
- unsigned long flags;
-
- spin_lock_irqsave(&port->slock, flags);
- while (!list_empty(&q->active)) {
- buf = list_entry(q->active.next, struct cx23885_buffer,
- vb.queue);
- list_del(&buf->vb.queue);
- buf->vb.state = VIDEOBUF_ERROR;
- wake_up(&buf->vb.done);
- dprintk(1, "[%p/%d] %s - dma=0x%08lx\n",
- buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
- }
- if (restart) {
- dprintk(1, "restarting queue\n");
- cx23885_restart_queue(port, q);
- }
- spin_unlock_irqrestore(&port->slock, flags);
-}
-
-void cx23885_cancel_buffers(struct cx23885_tsport *port)
-{
- struct cx23885_dev *dev = port->dev;
- struct cx23885_dmaqueue *q = &port->mpegq;
-
- dprintk(1, "%s()\n", __func__);
- del_timer_sync(&q->timeout);
- cx23885_stop_dma(port);
- do_cancel_buffers(port, "cancel", 0);
-}
-
-static void cx23885_timeout(unsigned long data)
-{
- struct cx23885_tsport *port = (struct cx23885_tsport *)data;
- struct cx23885_dev *dev = port->dev;
-
- dprintk(1, "%s()\n", __func__);
-
- if (debug > 5)
- cx23885_sram_channel_dump(dev,
- &dev->sram_channels[port->sram_chno]);
-
- cx23885_stop_dma(port);
- do_cancel_buffers(port, "timeout", 1);
-}
-
-int cx23885_irq_417(struct cx23885_dev *dev, u32 status)
-{
- /* FIXME: port1 assumption here. */
- struct cx23885_tsport *port = &dev->ts1;
- int count = 0;
- int handled = 0;
-
- if (status == 0)
- return handled;
-
- count = cx_read(port->reg_gpcnt);
- dprintk(7, "status: 0x%08x mask: 0x%08x count: 0x%x\n",
- status, cx_read(port->reg_ts_int_msk), count);
-
- if ((status & VID_B_MSK_BAD_PKT) ||
- (status & VID_B_MSK_OPC_ERR) ||
- (status & VID_B_MSK_VBI_OPC_ERR) ||
- (status & VID_B_MSK_SYNC) ||
- (status & VID_B_MSK_VBI_SYNC) ||
- (status & VID_B_MSK_OF) ||
- (status & VID_B_MSK_VBI_OF)) {
- printk(KERN_ERR "%s: V4L mpeg risc op code error, status "
- "= 0x%x\n", dev->name, status);
- if (status & VID_B_MSK_BAD_PKT)
- dprintk(1, " VID_B_MSK_BAD_PKT\n");
- if (status & VID_B_MSK_OPC_ERR)
- dprintk(1, " VID_B_MSK_OPC_ERR\n");
- if (status & VID_B_MSK_VBI_OPC_ERR)
- dprintk(1, " VID_B_MSK_VBI_OPC_ERR\n");
- if (status & VID_B_MSK_SYNC)
- dprintk(1, " VID_B_MSK_SYNC\n");
- if (status & VID_B_MSK_VBI_SYNC)
- dprintk(1, " VID_B_MSK_VBI_SYNC\n");
- if (status & VID_B_MSK_OF)
- dprintk(1, " VID_B_MSK_OF\n");
- if (status & VID_B_MSK_VBI_OF)
- dprintk(1, " VID_B_MSK_VBI_OF\n");
-
- cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
- cx23885_sram_channel_dump(dev,
- &dev->sram_channels[port->sram_chno]);
- cx23885_417_check_encoder(dev);
- } else if (status & VID_B_MSK_RISCI1) {
- dprintk(7, " VID_B_MSK_RISCI1\n");
- spin_lock(&port->slock);
- cx23885_wakeup(port, &port->mpegq, count);
- spin_unlock(&port->slock);
- } else if (status & VID_B_MSK_RISCI2) {
- dprintk(7, " VID_B_MSK_RISCI2\n");
- spin_lock(&port->slock);
- cx23885_restart_queue(port, &port->mpegq);
- spin_unlock(&port->slock);
- }
- if (status) {
- cx_write(port->reg_ts_int_stat, status);
- handled = 1;
- }
-
- return handled;
-}
-
-static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status)
-{
- struct cx23885_dev *dev = port->dev;
- int handled = 0;
- u32 count;
-
- if ((status & VID_BC_MSK_OPC_ERR) ||
- (status & VID_BC_MSK_BAD_PKT) ||
- (status & VID_BC_MSK_SYNC) ||
- (status & VID_BC_MSK_OF)) {
-
- if (status & VID_BC_MSK_OPC_ERR)
- dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n",
- VID_BC_MSK_OPC_ERR);
-
- if (status & VID_BC_MSK_BAD_PKT)
- dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n",
- VID_BC_MSK_BAD_PKT);
-
- if (status & VID_BC_MSK_SYNC)
- dprintk(7, " (VID_BC_MSK_SYNC 0x%08x)\n",
- VID_BC_MSK_SYNC);
-
- if (status & VID_BC_MSK_OF)
- dprintk(7, " (VID_BC_MSK_OF 0x%08x)\n",
- VID_BC_MSK_OF);
-
- printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name);
-
- cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
- cx23885_sram_channel_dump(dev,
- &dev->sram_channels[port->sram_chno]);
-
- } else if (status & VID_BC_MSK_RISCI1) {
-
- dprintk(7, " (RISCI1 0x%08x)\n", VID_BC_MSK_RISCI1);
-
- spin_lock(&port->slock);
- count = cx_read(port->reg_gpcnt);
- cx23885_wakeup(port, &port->mpegq, count);
- spin_unlock(&port->slock);
-
- } else if (status & VID_BC_MSK_RISCI2) {
-
- dprintk(7, " (RISCI2 0x%08x)\n", VID_BC_MSK_RISCI2);
-
- spin_lock(&port->slock);
- cx23885_restart_queue(port, &port->mpegq);
- spin_unlock(&port->slock);
-
- }
- if (status) {
- cx_write(port->reg_ts_int_stat, status);
- handled = 1;
- }
-
- return handled;
-}
-
-static irqreturn_t cx23885_irq(int irq, void *dev_id)
-{
- struct cx23885_dev *dev = dev_id;
- struct cx23885_tsport *ts1 = &dev->ts1;
- struct cx23885_tsport *ts2 = &dev->ts2;
- u32 pci_status, pci_mask;
- u32 vida_status, vida_mask;
- u32 audint_status, audint_mask;
- u32 ts1_status, ts1_mask;
- u32 ts2_status, ts2_mask;
- int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0;
- int audint_count = 0;
- bool subdev_handled;
-
- pci_status = cx_read(PCI_INT_STAT);
- pci_mask = cx23885_irq_get_mask(dev);
- vida_status = cx_read(VID_A_INT_STAT);
- vida_mask = cx_read(VID_A_INT_MSK);
- audint_status = cx_read(AUDIO_INT_INT_STAT);
- audint_mask = cx_read(AUDIO_INT_INT_MSK);
- ts1_status = cx_read(VID_B_INT_STAT);
- ts1_mask = cx_read(VID_B_INT_MSK);
- ts2_status = cx_read(VID_C_INT_STAT);
- ts2_mask = cx_read(VID_C_INT_MSK);
-
- if ((pci_status == 0) && (ts2_status == 0) && (ts1_status == 0))
- goto out;
-
- vida_count = cx_read(VID_A_GPCNT);
- audint_count = cx_read(AUD_INT_A_GPCNT);
- ts1_count = cx_read(ts1->reg_gpcnt);
- ts2_count = cx_read(ts2->reg_gpcnt);
- dprintk(7, "pci_status: 0x%08x pci_mask: 0x%08x\n",
- pci_status, pci_mask);
- dprintk(7, "vida_status: 0x%08x vida_mask: 0x%08x count: 0x%x\n",
- vida_status, vida_mask, vida_count);
- dprintk(7, "audint_status: 0x%08x audint_mask: 0x%08x count: 0x%x\n",
- audint_status, audint_mask, audint_count);
- dprintk(7, "ts1_status: 0x%08x ts1_mask: 0x%08x count: 0x%x\n",
- ts1_status, ts1_mask, ts1_count);
- dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n",
- ts2_status, ts2_mask, ts2_count);
-
- if (pci_status & (PCI_MSK_RISC_RD | PCI_MSK_RISC_WR |
- PCI_MSK_AL_RD | PCI_MSK_AL_WR | PCI_MSK_APB_DMA |
- PCI_MSK_VID_C | PCI_MSK_VID_B | PCI_MSK_VID_A |
- PCI_MSK_AUD_INT | PCI_MSK_AUD_EXT |
- PCI_MSK_GPIO0 | PCI_MSK_GPIO1 |
- PCI_MSK_AV_CORE | PCI_MSK_IR)) {
-
- if (pci_status & PCI_MSK_RISC_RD)
- dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n",
- PCI_MSK_RISC_RD);
-
- if (pci_status & PCI_MSK_RISC_WR)
- dprintk(7, " (PCI_MSK_RISC_WR 0x%08x)\n",
- PCI_MSK_RISC_WR);
-
- if (pci_status & PCI_MSK_AL_RD)
- dprintk(7, " (PCI_MSK_AL_RD 0x%08x)\n",
- PCI_MSK_AL_RD);
-
- if (pci_status & PCI_MSK_AL_WR)
- dprintk(7, " (PCI_MSK_AL_WR 0x%08x)\n",
- PCI_MSK_AL_WR);
-
- if (pci_status & PCI_MSK_APB_DMA)
- dprintk(7, " (PCI_MSK_APB_DMA 0x%08x)\n",
- PCI_MSK_APB_DMA);
-
- if (pci_status & PCI_MSK_VID_C)
- dprintk(7, " (PCI_MSK_VID_C 0x%08x)\n",
- PCI_MSK_VID_C);
-
- if (pci_status & PCI_MSK_VID_B)
- dprintk(7, " (PCI_MSK_VID_B 0x%08x)\n",
- PCI_MSK_VID_B);
-
- if (pci_status & PCI_MSK_VID_A)
- dprintk(7, " (PCI_MSK_VID_A 0x%08x)\n",
- PCI_MSK_VID_A);
-
- if (pci_status & PCI_MSK_AUD_INT)
- dprintk(7, " (PCI_MSK_AUD_INT 0x%08x)\n",
- PCI_MSK_AUD_INT);
-
- if (pci_status & PCI_MSK_AUD_EXT)
- dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n",
- PCI_MSK_AUD_EXT);
-
- if (pci_status & PCI_MSK_GPIO0)
- dprintk(7, " (PCI_MSK_GPIO0 0x%08x)\n",
- PCI_MSK_GPIO0);
-
- if (pci_status & PCI_MSK_GPIO1)
- dprintk(7, " (PCI_MSK_GPIO1 0x%08x)\n",
- PCI_MSK_GPIO1);
-
- if (pci_status & PCI_MSK_AV_CORE)
- dprintk(7, " (PCI_MSK_AV_CORE 0x%08x)\n",
- PCI_MSK_AV_CORE);
-
- if (pci_status & PCI_MSK_IR)
- dprintk(7, " (PCI_MSK_IR 0x%08x)\n",
- PCI_MSK_IR);
- }
-
- if (cx23885_boards[dev->board].ci_type == 1 &&
- (pci_status & (PCI_MSK_GPIO1 | PCI_MSK_GPIO0)))
- handled += netup_ci_slot_status(dev, pci_status);
-
- if (cx23885_boards[dev->board].ci_type == 2 &&
- (pci_status & PCI_MSK_GPIO0))
- handled += altera_ci_irq(dev);
-
- if (ts1_status) {
- if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
- handled += cx23885_irq_ts(ts1, ts1_status);
- else
- if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER)
- handled += cx23885_irq_417(dev, ts1_status);
- }
-
- if (ts2_status) {
- if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB)
- handled += cx23885_irq_ts(ts2, ts2_status);
- else
- if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER)
- handled += cx23885_irq_417(dev, ts2_status);
- }
-
- if (vida_status)
- handled += cx23885_video_irq(dev, vida_status);
-
- if (audint_status)
- handled += cx23885_audio_irq(dev, audint_status, audint_mask);
-
- if (pci_status & PCI_MSK_IR) {
- subdev_handled = false;
- v4l2_subdev_call(dev->sd_ir, core, interrupt_service_routine,
- pci_status, &subdev_handled);
- if (subdev_handled)
- handled++;
- }
-
- if ((pci_status & pci_mask) & PCI_MSK_AV_CORE) {
- cx23885_irq_disable(dev, PCI_MSK_AV_CORE);
- if (!schedule_work(&dev->cx25840_work))
- printk(KERN_ERR "%s: failed to set up deferred work for"
- " AV Core/IR interrupt. Interrupt is disabled"
- " and won't be re-enabled\n", dev->name);
- handled++;
- }
-
- if (handled)
- cx_write(PCI_INT_STAT, pci_status);
-out:
- return IRQ_RETVAL(handled);
-}
-
-static void cx23885_v4l2_dev_notify(struct v4l2_subdev *sd,
- unsigned int notification, void *arg)
-{
- struct cx23885_dev *dev;
-
- if (sd == NULL)
- return;
-
- dev = to_cx23885(sd->v4l2_dev);
-
- switch (notification) {
- case V4L2_SUBDEV_IR_RX_NOTIFY: /* Possibly called in an IRQ context */
- if (sd == dev->sd_ir)
- cx23885_ir_rx_v4l2_dev_notify(sd, *(u32 *)arg);
- break;
- case V4L2_SUBDEV_IR_TX_NOTIFY: /* Possibly called in an IRQ context */
- if (sd == dev->sd_ir)
- cx23885_ir_tx_v4l2_dev_notify(sd, *(u32 *)arg);
- break;
- }
-}
-
-static void cx23885_v4l2_dev_notify_init(struct cx23885_dev *dev)
-{
- INIT_WORK(&dev->cx25840_work, cx23885_av_work_handler);
- INIT_WORK(&dev->ir_rx_work, cx23885_ir_rx_work_handler);
- INIT_WORK(&dev->ir_tx_work, cx23885_ir_tx_work_handler);
- dev->v4l2_dev.notify = cx23885_v4l2_dev_notify;
-}
-
-static inline int encoder_on_portb(struct cx23885_dev *dev)
-{
- return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER;
-}
-
-static inline int encoder_on_portc(struct cx23885_dev *dev)
-{
- return cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER;
-}
-
-/* Mask represents 32 different GPIOs, GPIO's are split into multiple
- * registers depending on the board configuration (and whether the
- * 417 encoder (wi it's own GPIO's) are present. Each GPIO bit will
- * be pushed into the correct hardware register, regardless of the
- * physical location. Certain registers are shared so we sanity check
- * and report errors if we think we're tampering with a GPIo that might
- * be assigned to the encoder (and used for the host bus).
- *
- * GPIO 2 thru 0 - On the cx23885 bridge
- * GPIO 18 thru 3 - On the cx23417 host bus interface
- * GPIO 23 thru 19 - On the cx25840 a/v core
- */
-void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask)
-{
- if (mask & 0x7)
- cx_set(GP0_IO, mask & 0x7);
-
- if (mask & 0x0007fff8) {
- if (encoder_on_portb(dev) || encoder_on_portc(dev))
- printk(KERN_ERR
- "%s: Setting GPIO on encoder ports\n",
- dev->name);
- cx_set(MC417_RWD, (mask & 0x0007fff8) >> 3);
- }
-
- /* TODO: 23-19 */
- if (mask & 0x00f80000)
- printk(KERN_INFO "%s: Unsupported\n", dev->name);
-}
-
-void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask)
-{
- if (mask & 0x00000007)
- cx_clear(GP0_IO, mask & 0x7);
-
- if (mask & 0x0007fff8) {
- if (encoder_on_portb(dev) || encoder_on_portc(dev))
- printk(KERN_ERR
- "%s: Clearing GPIO moving on encoder ports\n",
- dev->name);
- cx_clear(MC417_RWD, (mask & 0x7fff8) >> 3);
- }
-
- /* TODO: 23-19 */
- if (mask & 0x00f80000)
- printk(KERN_INFO "%s: Unsupported\n", dev->name);
-}
-
-u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask)
-{
- if (mask & 0x00000007)
- return (cx_read(GP0_IO) >> 8) & mask & 0x7;
-
- if (mask & 0x0007fff8) {
- if (encoder_on_portb(dev) || encoder_on_portc(dev))
- printk(KERN_ERR
- "%s: Reading GPIO moving on encoder ports\n",
- dev->name);
- return (cx_read(MC417_RWD) & ((mask & 0x7fff8) >> 3)) << 3;
- }
-
- /* TODO: 23-19 */
- if (mask & 0x00f80000)
- printk(KERN_INFO "%s: Unsupported\n", dev->name);
-
- return 0;
-}
-
-void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
-{
- if ((mask & 0x00000007) && asoutput)
- cx_set(GP0_IO, (mask & 0x7) << 16);
- else if ((mask & 0x00000007) && !asoutput)
- cx_clear(GP0_IO, (mask & 0x7) << 16);
-
- if (mask & 0x0007fff8) {
- if (encoder_on_portb(dev) || encoder_on_portc(dev))
- printk(KERN_ERR
- "%s: Enabling GPIO on encoder ports\n",
- dev->name);
- }
-
- /* MC417_OEN is active low for output, write 1 for an input */
- if ((mask & 0x0007fff8) && asoutput)
- cx_clear(MC417_OEN, (mask & 0x7fff8) >> 3);
-
- else if ((mask & 0x0007fff8) && !asoutput)
- cx_set(MC417_OEN, (mask & 0x7fff8) >> 3);
-
- /* TODO: 23-19 */
-}
-
-static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
-{
- struct cx23885_dev *dev;
- int err;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (NULL == dev)
- return -ENOMEM;
-
- err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
- if (err < 0)
- goto fail_free;
-
- /* Prepare to handle notifications from subdevices */
- cx23885_v4l2_dev_notify_init(dev);
-
- /* pci init */
- dev->pci = pci_dev;
- if (pci_enable_device(pci_dev)) {
- err = -EIO;
- goto fail_unreg;
- }
-
- if (cx23885_dev_setup(dev) < 0) {
- err = -EINVAL;
- goto fail_unreg;
- }
-
- /* print pci info */
- dev->pci_rev = pci_dev->revision;
- pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
- printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
- "latency: %d, mmio: 0x%llx\n", dev->name,
- pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
- dev->pci_lat,
- (unsigned long long)pci_resource_start(pci_dev, 0));
-
- pci_set_master(pci_dev);
- if (!pci_dma_supported(pci_dev, 0xffffffff)) {
- printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
- err = -EIO;
- goto fail_irq;
- }
-
- err = request_irq(pci_dev->irq, cx23885_irq,
- IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
- if (err < 0) {
- printk(KERN_ERR "%s: can't get IRQ %d\n",
- dev->name, pci_dev->irq);
- goto fail_irq;
- }
-
- switch (dev->board) {
- case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
- cx23885_irq_add_enable(dev, PCI_MSK_GPIO1 | PCI_MSK_GPIO0);
- break;
- case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
- cx23885_irq_add_enable(dev, PCI_MSK_GPIO0);
- break;
- }
-
- /*
- * The CX2388[58] IR controller can start firing interrupts when
- * enabled, so these have to take place after the cx23885_irq() handler
- * is hooked up by the call to request_irq() above.
- */
- cx23885_ir_pci_int_enable(dev);
- cx23885_input_init(dev);
-
- return 0;
-
-fail_irq:
- cx23885_dev_unregister(dev);
-fail_unreg:
- v4l2_device_unregister(&dev->v4l2_dev);
-fail_free:
- kfree(dev);
- return err;
-}
-
-static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
-{
- struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
- struct cx23885_dev *dev = to_cx23885(v4l2_dev);
-
- cx23885_input_fini(dev);
- cx23885_ir_fini(dev);
-
- cx23885_shutdown(dev);
-
- pci_disable_device(pci_dev);
-
- /* unregister stuff */
- free_irq(pci_dev->irq, dev);
-
- cx23885_dev_unregister(dev);
- v4l2_device_unregister(v4l2_dev);
- kfree(dev);
-}
-
-static struct pci_device_id cx23885_pci_tbl[] = {
- {
- /* CX23885 */
- .vendor = 0x14f1,
- .device = 0x8852,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- }, {
- /* CX23887 Rev 2 */
- .vendor = 0x14f1,
- .device = 0x8880,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- }, {
- /* --- end of list --- */
- }
-};
-MODULE_DEVICE_TABLE(pci, cx23885_pci_tbl);
-
-static struct pci_driver cx23885_pci_driver = {
- .name = "cx23885",
- .id_table = cx23885_pci_tbl,
- .probe = cx23885_initdev,
- .remove = __devexit_p(cx23885_finidev),
- /* TODO */
- .suspend = NULL,
- .resume = NULL,
-};
-
-static int __init cx23885_init(void)
-{
- printk(KERN_INFO "cx23885 driver version %s loaded\n",
- CX23885_VERSION);
- return pci_register_driver(&cx23885_pci_driver);
-}
-
-static void __exit cx23885_fini(void)
-{
- pci_unregister_driver(&cx23885_pci_driver);
-}
-
-module_init(cx23885_init);
-module_exit(cx23885_fini);
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
deleted file mode 100644
index cd542684ba0..00000000000
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ /dev/null
@@ -1,1357 +0,0 @@
-/*
- * Driver for the Conexant CX23885 PCIe bridge
- *
- * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/fs.h>
-#include <linux/kthread.h>
-#include <linux/file.h>
-#include <linux/suspend.h>
-
-#include "cx23885.h"
-#include <media/v4l2-common.h>
-
-#include "dvb_ca_en50221.h"
-#include "s5h1409.h"
-#include "s5h1411.h"
-#include "mt2131.h"
-#include "tda8290.h"
-#include "tda18271.h"
-#include "lgdt330x.h"
-#include "xc4000.h"
-#include "xc5000.h"
-#include "max2165.h"
-#include "tda10048.h"
-#include "tuner-xc2028.h"
-#include "tuner-simple.h"
-#include "dib7000p.h"
-#include "dibx000_common.h"
-#include "zl10353.h"
-#include "stv0900.h"
-#include "stv0900_reg.h"
-#include "stv6110.h"
-#include "lnbh24.h"
-#include "cx24116.h"
-#include "cimax2.h"
-#include "lgs8gxx.h"
-#include "netup-eeprom.h"
-#include "netup-init.h"
-#include "lgdt3305.h"
-#include "atbm8830.h"
-#include "ds3000.h"
-#include "cx23885-f300.h"
-#include "altera-ci.h"
-#include "stv0367.h"
-#include "drxk.h"
-#include "mt2063.h"
-
-static unsigned int debug;
-
-#define dprintk(level, fmt, arg...)\
- do { if (debug >= level)\
- printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
- } while (0)
-
-/* ------------------------------------------------------------------ */
-
-static unsigned int alt_tuner;
-module_param(alt_tuner, int, 0644);
-MODULE_PARM_DESC(alt_tuner, "Enable alternate tuner configuration");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-/* ------------------------------------------------------------------ */
-
-static int dvb_buf_setup(struct videobuf_queue *q,
- unsigned int *count, unsigned int *size)
-{
- struct cx23885_tsport *port = q->priv_data;
-
- port->ts_packet_size = 188 * 4;
- port->ts_packet_count = 32;
-
- *size = port->ts_packet_size * port->ts_packet_count;
- *count = 32;
- return 0;
-}
-
-static int dvb_buf_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb, enum v4l2_field field)
-{
- struct cx23885_tsport *port = q->priv_data;
- return cx23885_buf_prepare(q, port, (struct cx23885_buffer *)vb, field);
-}
-
-static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct cx23885_tsport *port = q->priv_data;
- cx23885_buf_queue(port, (struct cx23885_buffer *)vb);
-}
-
-static void dvb_buf_release(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
-}
-
-static int cx23885_dvb_set_frontend(struct dvb_frontend *fe);
-
-static void cx23885_dvb_gate_ctrl(struct cx23885_tsport *port, int open)
-{
- struct videobuf_dvb_frontends *f;
- struct videobuf_dvb_frontend *fe;
-
- f = &port->frontends;
-
- if (f->gate <= 1) /* undefined or fe0 */
- fe = videobuf_dvb_get_frontend(f, 1);
- else
- fe = videobuf_dvb_get_frontend(f, f->gate);
-
- if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
- fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
-
- /*
- * FIXME: Improve this path to avoid calling the
- * cx23885_dvb_set_frontend() every time it passes here.
- */
- cx23885_dvb_set_frontend(fe->dvb.frontend);
-}
-
-static struct videobuf_queue_ops dvb_qops = {
- .buf_setup = dvb_buf_setup,
- .buf_prepare = dvb_buf_prepare,
- .buf_queue = dvb_buf_queue,
- .buf_release = dvb_buf_release,
-};
-
-static struct s5h1409_config hauppauge_generic_config = {
- .demod_address = 0x32 >> 1,
- .output_mode = S5H1409_SERIAL_OUTPUT,
- .gpio = S5H1409_GPIO_ON,
- .qam_if = 44000,
- .inversion = S5H1409_INVERSION_OFF,
- .status_mode = S5H1409_DEMODLOCKING,
- .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static struct tda10048_config hauppauge_hvr1200_config = {
- .demod_address = 0x10 >> 1,
- .output_mode = TDA10048_SERIAL_OUTPUT,
- .fwbulkwritelen = TDA10048_BULKWRITE_200,
- .inversion = TDA10048_INVERSION_ON,
- .dtv6_if_freq_khz = TDA10048_IF_3300,
- .dtv7_if_freq_khz = TDA10048_IF_3800,
- .dtv8_if_freq_khz = TDA10048_IF_4300,
- .clk_freq_khz = TDA10048_CLK_16000,
-};
-
-static struct tda10048_config hauppauge_hvr1210_config = {
- .demod_address = 0x10 >> 1,
- .output_mode = TDA10048_SERIAL_OUTPUT,
- .fwbulkwritelen = TDA10048_BULKWRITE_200,
- .inversion = TDA10048_INVERSION_ON,
- .dtv6_if_freq_khz = TDA10048_IF_3300,
- .dtv7_if_freq_khz = TDA10048_IF_3500,
- .dtv8_if_freq_khz = TDA10048_IF_4000,
- .clk_freq_khz = TDA10048_CLK_16000,
-};
-
-static struct s5h1409_config hauppauge_ezqam_config = {
- .demod_address = 0x32 >> 1,
- .output_mode = S5H1409_SERIAL_OUTPUT,
- .gpio = S5H1409_GPIO_OFF,
- .qam_if = 4000,
- .inversion = S5H1409_INVERSION_ON,
- .status_mode = S5H1409_DEMODLOCKING,
- .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static struct s5h1409_config hauppauge_hvr1800lp_config = {
- .demod_address = 0x32 >> 1,
- .output_mode = S5H1409_SERIAL_OUTPUT,
- .gpio = S5H1409_GPIO_OFF,
- .qam_if = 44000,
- .inversion = S5H1409_INVERSION_OFF,
- .status_mode = S5H1409_DEMODLOCKING,
- .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static struct s5h1409_config hauppauge_hvr1500_config = {
- .demod_address = 0x32 >> 1,
- .output_mode = S5H1409_SERIAL_OUTPUT,
- .gpio = S5H1409_GPIO_OFF,
- .inversion = S5H1409_INVERSION_OFF,
- .status_mode = S5H1409_DEMODLOCKING,
- .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static struct mt2131_config hauppauge_generic_tunerconfig = {
- 0x61
-};
-
-static struct lgdt330x_config fusionhdtv_5_express = {
- .demod_address = 0x0e,
- .demod_chip = LGDT3303,
- .serial_mpeg = 0x40,
-};
-
-static struct s5h1409_config hauppauge_hvr1500q_config = {
- .demod_address = 0x32 >> 1,
- .output_mode = S5H1409_SERIAL_OUTPUT,
- .gpio = S5H1409_GPIO_ON,
- .qam_if = 44000,
- .inversion = S5H1409_INVERSION_OFF,
- .status_mode = S5H1409_DEMODLOCKING,
- .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static struct s5h1409_config dvico_s5h1409_config = {
- .demod_address = 0x32 >> 1,
- .output_mode = S5H1409_SERIAL_OUTPUT,
- .gpio = S5H1409_GPIO_ON,
- .qam_if = 44000,
- .inversion = S5H1409_INVERSION_OFF,
- .status_mode = S5H1409_DEMODLOCKING,
- .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static struct s5h1411_config dvico_s5h1411_config = {
- .output_mode = S5H1411_SERIAL_OUTPUT,
- .gpio = S5H1411_GPIO_ON,
- .qam_if = S5H1411_IF_44000,
- .vsb_if = S5H1411_IF_44000,
- .inversion = S5H1411_INVERSION_OFF,
- .status_mode = S5H1411_DEMODLOCKING,
- .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static struct s5h1411_config hcw_s5h1411_config = {
- .output_mode = S5H1411_SERIAL_OUTPUT,
- .gpio = S5H1411_GPIO_OFF,
- .vsb_if = S5H1411_IF_44000,
- .qam_if = S5H1411_IF_4000,
- .inversion = S5H1411_INVERSION_ON,
- .status_mode = S5H1411_DEMODLOCKING,
- .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static struct xc5000_config hauppauge_hvr1500q_tunerconfig = {
- .i2c_address = 0x61,
- .if_khz = 5380,
-};
-
-static struct xc5000_config dvico_xc5000_tunerconfig = {
- .i2c_address = 0x64,
- .if_khz = 5380,
-};
-
-static struct tda829x_config tda829x_no_probe = {
- .probe_tuner = TDA829X_DONT_PROBE,
-};
-
-static struct tda18271_std_map hauppauge_tda18271_std_map = {
- .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3,
- .if_lvl = 6, .rfagc_top = 0x37 },
- .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
- .if_lvl = 6, .rfagc_top = 0x37 },
-};
-
-static struct tda18271_std_map hauppauge_hvr1200_tda18271_std_map = {
- .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
- .if_lvl = 1, .rfagc_top = 0x37, },
- .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5,
- .if_lvl = 1, .rfagc_top = 0x37, },
- .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6,
- .if_lvl = 1, .rfagc_top = 0x37, },
-};
-
-static struct tda18271_config hauppauge_tda18271_config = {
- .std_map = &hauppauge_tda18271_std_map,
- .gate = TDA18271_GATE_ANALOG,
- .output_opt = TDA18271_OUTPUT_LT_OFF,
-};
-
-static struct tda18271_config hauppauge_hvr1200_tuner_config = {
- .std_map = &hauppauge_hvr1200_tda18271_std_map,
- .gate = TDA18271_GATE_ANALOG,
- .output_opt = TDA18271_OUTPUT_LT_OFF,
-};
-
-static struct tda18271_config hauppauge_hvr1210_tuner_config = {
- .gate = TDA18271_GATE_DIGITAL,
- .output_opt = TDA18271_OUTPUT_LT_OFF,
-};
-
-static struct tda18271_std_map hauppauge_hvr127x_std_map = {
- .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4,
- .if_lvl = 1, .rfagc_top = 0x58 },
- .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5,
- .if_lvl = 1, .rfagc_top = 0x58 },
-};
-
-static struct tda18271_config hauppauge_hvr127x_config = {
- .std_map = &hauppauge_hvr127x_std_map,
- .output_opt = TDA18271_OUTPUT_LT_OFF,
-};
-
-static struct lgdt3305_config hauppauge_lgdt3305_config = {
- .i2c_addr = 0x0e,
- .mpeg_mode = LGDT3305_MPEG_SERIAL,
- .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
- .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
- .deny_i2c_rptr = 1,
- .spectral_inversion = 1,
- .qam_if_khz = 4000,
- .vsb_if_khz = 3250,
-};
-
-static struct dibx000_agc_config xc3028_agc_config = {
- BAND_VHF | BAND_UHF, /* band_caps */
-
- /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
- * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
- * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0,
- * P_agc_nb_est=2, P_agc_write=0
- */
- (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
- (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */
-
- 712, /* inv_gain */
- 21, /* time_stabiliz */
-
- 0, /* alpha_level */
- 118, /* thlock */
-
- 0, /* wbd_inv */
- 2867, /* wbd_ref */
- 0, /* wbd_sel */
- 2, /* wbd_alpha */
-
- 0, /* agc1_max */
- 0, /* agc1_min */
- 39718, /* agc2_max */
- 9930, /* agc2_min */
- 0, /* agc1_pt1 */
- 0, /* agc1_pt2 */
- 0, /* agc1_pt3 */
- 0, /* agc1_slope1 */
- 0, /* agc1_slope2 */
- 0, /* agc2_pt1 */
- 128, /* agc2_pt2 */
- 29, /* agc2_slope1 */
- 29, /* agc2_slope2 */
-
- 17, /* alpha_mant */
- 27, /* alpha_exp */
- 23, /* beta_mant */
- 51, /* beta_exp */
-
- 1, /* perform_agc_softsplit */
-};
-
-/* PLL Configuration for COFDM BW_MHz = 8.000000
- * With external clock = 30.000000 */
-static struct dibx000_bandwidth_config xc3028_bw_config = {
- 60000, /* internal */
- 30000, /* sampling */
- 1, /* pll_cfg: prediv */
- 8, /* pll_cfg: ratio */
- 3, /* pll_cfg: range */
- 1, /* pll_cfg: reset */
- 0, /* pll_cfg: bypass */
- 0, /* misc: refdiv */
- 0, /* misc: bypclk_div */
- 1, /* misc: IO_CLK_en_core */
- 1, /* misc: ADClkSrc */
- 0, /* misc: modulo */
- (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
- (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
- 20452225, /* timf */
- 30000000 /* xtal_hz */
-};
-
-static struct dib7000p_config hauppauge_hvr1400_dib7000_config = {
- .output_mpeg2_in_188_bytes = 1,
- .hostbus_diversity = 1,
- .tuner_is_baseband = 0,
- .update_lna = NULL,
-
- .agc_config_count = 1,
- .agc = &xc3028_agc_config,
- .bw = &xc3028_bw_config,
-
- .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
- .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
- .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
-
- .pwm_freq_div = 0,
- .agc_control = NULL,
- .spur_protect = 0,
-
- .output_mode = OUTMODE_MPEG2_SERIAL,
-};
-
-static struct zl10353_config dvico_fusionhdtv_xc3028 = {
- .demod_address = 0x0f,
- .if2 = 45600,
- .no_tuner = 1,
- .disable_i2c_gate_ctrl = 1,
-};
-
-static struct stv0900_reg stv0900_ts_regs[] = {
- { R0900_TSGENERAL, 0x00 },
- { R0900_P1_TSSPEED, 0x40 },
- { R0900_P2_TSSPEED, 0x40 },
- { R0900_P1_TSCFGM, 0xc0 },
- { R0900_P2_TSCFGM, 0xc0 },
- { R0900_P1_TSCFGH, 0xe0 },
- { R0900_P2_TSCFGH, 0xe0 },
- { R0900_P1_TSCFGL, 0x20 },
- { R0900_P2_TSCFGL, 0x20 },
- { 0xffff, 0xff }, /* terminate */
-};
-
-static struct stv0900_config netup_stv0900_config = {
- .demod_address = 0x68,
- .demod_mode = 1, /* dual */
- .xtal = 8000000,
- .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
- .diseqc_mode = 2,/* 2/3 PWM */
- .ts_config_regs = stv0900_ts_regs,
- .tun1_maddress = 0,/* 0x60 */
- .tun2_maddress = 3,/* 0x63 */
- .tun1_adc = 1,/* 1 Vpp */
- .tun2_adc = 1,/* 1 Vpp */
-};
-
-static struct stv6110_config netup_stv6110_tunerconfig_a = {
- .i2c_address = 0x60,
- .mclk = 16000000,
- .clk_div = 1,
- .gain = 8, /* +16 dB - maximum gain */
-};
-
-static struct stv6110_config netup_stv6110_tunerconfig_b = {
- .i2c_address = 0x63,
- .mclk = 16000000,
- .clk_div = 1,
- .gain = 8, /* +16 dB - maximum gain */
-};
-
-static struct cx24116_config tbs_cx24116_config = {
- .demod_address = 0x55,
-};
-
-static struct ds3000_config tevii_ds3000_config = {
- .demod_address = 0x68,
-};
-
-static struct cx24116_config dvbworld_cx24116_config = {
- .demod_address = 0x05,
-};
-
-static struct lgs8gxx_config mygica_x8506_lgs8gl5_config = {
- .prod = LGS8GXX_PROD_LGS8GL5,
- .demod_address = 0x19,
- .serial_ts = 0,
- .ts_clk_pol = 1,
- .ts_clk_gated = 1,
- .if_clk_freq = 30400, /* 30.4 MHz */
- .if_freq = 5380, /* 5.38 MHz */
- .if_neg_center = 1,
- .ext_adc = 0,
- .adc_signed = 0,
- .if_neg_edge = 0,
-};
-
-static struct xc5000_config mygica_x8506_xc5000_config = {
- .i2c_address = 0x61,
- .if_khz = 5380,
-};
-
-static int cx23885_dvb_set_frontend(struct dvb_frontend *fe)
-{
- struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- struct cx23885_tsport *port = fe->dvb->priv;
- struct cx23885_dev *dev = port->dev;
-
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1275:
- switch (p->modulation) {
- case VSB_8:
- cx23885_gpio_clear(dev, GPIO_5);
- break;
- case QAM_64:
- case QAM_256:
- default:
- cx23885_gpio_set(dev, GPIO_5);
- break;
- }
- break;
- case CX23885_BOARD_MYGICA_X8506:
- case CX23885_BOARD_MAGICPRO_PROHDTVE2:
- /* Select Digital TV */
- cx23885_gpio_set(dev, GPIO_0);
- break;
- }
- return 0;
-}
-
-static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = {
- .prod = LGS8GXX_PROD_LGS8G75,
- .demod_address = 0x19,
- .serial_ts = 0,
- .ts_clk_pol = 1,
- .ts_clk_gated = 1,
- .if_clk_freq = 30400, /* 30.4 MHz */
- .if_freq = 6500, /* 6.50 MHz */
- .if_neg_center = 1,
- .ext_adc = 0,
- .adc_signed = 1,
- .adc_vpp = 2, /* 1.6 Vpp */
- .if_neg_edge = 1,
-};
-
-static struct xc5000_config magicpro_prohdtve2_xc5000_config = {
- .i2c_address = 0x61,
- .if_khz = 6500,
-};
-
-static struct atbm8830_config mygica_x8558pro_atbm8830_cfg1 = {
- .prod = ATBM8830_PROD_8830,
- .demod_address = 0x44,
- .serial_ts = 0,
- .ts_sampling_edge = 1,
- .ts_clk_gated = 0,
- .osc_clk_freq = 30400, /* in kHz */
- .if_freq = 0, /* zero IF */
- .zif_swap_iq = 1,
- .agc_min = 0x2E,
- .agc_max = 0xFF,
- .agc_hold_loop = 0,
-};
-
-static struct max2165_config mygic_x8558pro_max2165_cfg1 = {
- .i2c_address = 0x60,
- .osc_clk = 20
-};
-
-static struct atbm8830_config mygica_x8558pro_atbm8830_cfg2 = {
- .prod = ATBM8830_PROD_8830,
- .demod_address = 0x44,
- .serial_ts = 1,
- .ts_sampling_edge = 1,
- .ts_clk_gated = 0,
- .osc_clk_freq = 30400, /* in kHz */
- .if_freq = 0, /* zero IF */
- .zif_swap_iq = 1,
- .agc_min = 0x2E,
- .agc_max = 0xFF,
- .agc_hold_loop = 0,
-};
-
-static struct max2165_config mygic_x8558pro_max2165_cfg2 = {
- .i2c_address = 0x60,
- .osc_clk = 20
-};
-static struct stv0367_config netup_stv0367_config[] = {
- {
- .demod_address = 0x1c,
- .xtal = 27000000,
- .if_khz = 4500,
- .if_iq_mode = 0,
- .ts_mode = 1,
- .clk_pol = 0,
- }, {
- .demod_address = 0x1d,
- .xtal = 27000000,
- .if_khz = 4500,
- .if_iq_mode = 0,
- .ts_mode = 1,
- .clk_pol = 0,
- },
-};
-
-static struct xc5000_config netup_xc5000_config[] = {
- {
- .i2c_address = 0x61,
- .if_khz = 4500,
- }, {
- .i2c_address = 0x64,
- .if_khz = 4500,
- },
-};
-
-static struct drxk_config terratec_drxk_config[] = {
- {
- .adr = 0x29,
- .no_i2c_bridge = 1,
- }, {
- .adr = 0x2a,
- .no_i2c_bridge = 1,
- },
-};
-
-static struct mt2063_config terratec_mt2063_config[] = {
- {
- .tuner_address = 0x60,
- }, {
- .tuner_address = 0x67,
- },
-};
-
-int netup_altera_fpga_rw(void *device, int flag, int data, int read)
-{
- struct cx23885_dev *dev = (struct cx23885_dev *)device;
- unsigned long timeout = jiffies + msecs_to_jiffies(1);
- uint32_t mem = 0;
-
- mem = cx_read(MC417_RWD);
- if (read)
- cx_set(MC417_OEN, ALT_DATA);
- else {
- cx_clear(MC417_OEN, ALT_DATA);/* D0-D7 out */
- mem &= ~ALT_DATA;
- mem |= (data & ALT_DATA);
- }
-
- if (flag)
- mem |= ALT_AD_RG;
- else
- mem &= ~ALT_AD_RG;
-
- mem &= ~ALT_CS;
- if (read)
- mem = (mem & ~ALT_RD) | ALT_WR;
- else
- mem = (mem & ~ALT_WR) | ALT_RD;
-
- cx_write(MC417_RWD, mem); /* start RW cycle */
-
- for (;;) {
- mem = cx_read(MC417_RWD);
- if ((mem & ALT_RDY) == 0)
- break;
- if (time_after(jiffies, timeout))
- break;
- udelay(1);
- }
-
- cx_set(MC417_RWD, ALT_RD | ALT_WR | ALT_CS);
- if (read)
- return mem & ALT_DATA;
-
- return 0;
-};
-
-static int dvb_register(struct cx23885_tsport *port)
-{
- struct cx23885_dev *dev = port->dev;
- struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL;
- struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
- int mfe_shared = 0; /* bus not shared by default */
- int ret;
-
- /* Get the first frontend */
- fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
- if (!fe0)
- return -EINVAL;
-
- /* init struct videobuf_dvb */
- fe0->dvb.name = dev->name;
-
- /* multi-frontend gate control is undefined or defaults to fe0 */
- port->frontends.gate = 0;
-
- /* Sets the gate control callback to be used by i2c command calls */
- port->gate_ctrl = cx23885_dvb_gate_ctrl;
-
- /* init frontend */
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1250:
- i2c_bus = &dev->i2c_bus[0];
- fe0->dvb.frontend = dvb_attach(s5h1409_attach,
- &hauppauge_generic_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(mt2131_attach, fe0->dvb.frontend,
- &i2c_bus->i2c_adap,
- &hauppauge_generic_tunerconfig, 0);
- }
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1270:
- case CX23885_BOARD_HAUPPAUGE_HVR1275:
- i2c_bus = &dev->i2c_bus[0];
- fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
- &hauppauge_lgdt3305_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(tda18271_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_bus[1].i2c_adap,
- &hauppauge_hvr127x_config);
- }
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1255:
- case CX23885_BOARD_HAUPPAUGE_HVR1255_22111:
- i2c_bus = &dev->i2c_bus[0];
- fe0->dvb.frontend = dvb_attach(s5h1411_attach,
- &hcw_s5h1411_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(tda18271_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_bus[1].i2c_adap,
- &hauppauge_tda18271_config);
- }
-
- tda18271_attach(&dev->ts1.analog_fe,
- 0x60, &dev->i2c_bus[1].i2c_adap,
- &hauppauge_tda18271_config);
-
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1800:
- i2c_bus = &dev->i2c_bus[0];
- switch (alt_tuner) {
- case 1:
- fe0->dvb.frontend =
- dvb_attach(s5h1409_attach,
- &hauppauge_ezqam_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(tda829x_attach, fe0->dvb.frontend,
- &dev->i2c_bus[1].i2c_adap, 0x42,
- &tda829x_no_probe);
- dvb_attach(tda18271_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_bus[1].i2c_adap,
- &hauppauge_tda18271_config);
- }
- break;
- case 0:
- default:
- fe0->dvb.frontend =
- dvb_attach(s5h1409_attach,
- &hauppauge_generic_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL)
- dvb_attach(mt2131_attach, fe0->dvb.frontend,
- &i2c_bus->i2c_adap,
- &hauppauge_generic_tunerconfig, 0);
- break;
- }
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
- i2c_bus = &dev->i2c_bus[0];
- fe0->dvb.frontend = dvb_attach(s5h1409_attach,
- &hauppauge_hvr1800lp_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(mt2131_attach, fe0->dvb.frontend,
- &i2c_bus->i2c_adap,
- &hauppauge_generic_tunerconfig, 0);
- }
- break;
- case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP:
- i2c_bus = &dev->i2c_bus[0];
- fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
- &fusionhdtv_5_express,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &i2c_bus->i2c_adap, 0x61,
- TUNER_LG_TDVS_H06XF);
- }
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
- i2c_bus = &dev->i2c_bus[1];
- fe0->dvb.frontend = dvb_attach(s5h1409_attach,
- &hauppauge_hvr1500q_config,
- &dev->i2c_bus[0].i2c_adap);
- if (fe0->dvb.frontend != NULL)
- dvb_attach(xc5000_attach, fe0->dvb.frontend,
- &i2c_bus->i2c_adap,
- &hauppauge_hvr1500q_tunerconfig);
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1500:
- i2c_bus = &dev->i2c_bus[1];
- fe0->dvb.frontend = dvb_attach(s5h1409_attach,
- &hauppauge_hvr1500_config,
- &dev->i2c_bus[0].i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- struct dvb_frontend *fe;
- struct xc2028_config cfg = {
- .i2c_adap = &i2c_bus->i2c_adap,
- .i2c_addr = 0x61,
- };
- static struct xc2028_ctrl ctl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64,
- .demod = XC3028_FE_OREN538,
- };
-
- fe = dvb_attach(xc2028_attach,
- fe0->dvb.frontend, &cfg);
- if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
- fe->ops.tuner_ops.set_config(fe, &ctl);
- }
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1200:
- case CX23885_BOARD_HAUPPAUGE_HVR1700:
- i2c_bus = &dev->i2c_bus[0];
- fe0->dvb.frontend = dvb_attach(tda10048_attach,
- &hauppauge_hvr1200_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(tda829x_attach, fe0->dvb.frontend,
- &dev->i2c_bus[1].i2c_adap, 0x42,
- &tda829x_no_probe);
- dvb_attach(tda18271_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_bus[1].i2c_adap,
- &hauppauge_hvr1200_tuner_config);
- }
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1210:
- i2c_bus = &dev->i2c_bus[0];
- fe0->dvb.frontend = dvb_attach(tda10048_attach,
- &hauppauge_hvr1210_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(tda18271_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_bus[1].i2c_adap,
- &hauppauge_hvr1210_tuner_config);
- }
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1400:
- i2c_bus = &dev->i2c_bus[0];
- fe0->dvb.frontend = dvb_attach(dib7000p_attach,
- &i2c_bus->i2c_adap,
- 0x12, &hauppauge_hvr1400_dib7000_config);
- if (fe0->dvb.frontend != NULL) {
- struct dvb_frontend *fe;
- struct xc2028_config cfg = {
- .i2c_adap = &dev->i2c_bus[1].i2c_adap,
- .i2c_addr = 0x64,
- };
- static struct xc2028_ctrl ctl = {
- .fname = XC3028L_DEFAULT_FIRMWARE,
- .max_len = 64,
- .demod = XC3028_FE_DIBCOM52,
- /* This is true for all demods with
- v36 firmware? */
- .type = XC2028_D2633,
- };
-
- fe = dvb_attach(xc2028_attach,
- fe0->dvb.frontend, &cfg);
- if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
- fe->ops.tuner_ops.set_config(fe, &ctl);
- }
- break;
- case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
- i2c_bus = &dev->i2c_bus[port->nr - 1];
-
- fe0->dvb.frontend = dvb_attach(s5h1409_attach,
- &dvico_s5h1409_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend == NULL)
- fe0->dvb.frontend = dvb_attach(s5h1411_attach,
- &dvico_s5h1411_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL)
- dvb_attach(xc5000_attach, fe0->dvb.frontend,
- &i2c_bus->i2c_adap,
- &dvico_xc5000_tunerconfig);
- break;
- case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: {
- i2c_bus = &dev->i2c_bus[port->nr - 1];
-
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &dvico_fusionhdtv_xc3028,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- struct dvb_frontend *fe;
- struct xc2028_config cfg = {
- .i2c_adap = &i2c_bus->i2c_adap,
- .i2c_addr = 0x61,
- };
- static struct xc2028_ctrl ctl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64,
- .demod = XC3028_FE_ZARLINK456,
- };
-
- fe = dvb_attach(xc2028_attach, fe0->dvb.frontend,
- &cfg);
- if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
- fe->ops.tuner_ops.set_config(fe, &ctl);
- }
- break;
- }
- case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
- case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
- case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
- i2c_bus = &dev->i2c_bus[0];
-
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &dvico_fusionhdtv_xc3028,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- struct dvb_frontend *fe;
- struct xc2028_config cfg = {
- .i2c_adap = &dev->i2c_bus[1].i2c_adap,
- .i2c_addr = 0x61,
- };
- static struct xc2028_ctrl ctl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64,
- .demod = XC3028_FE_ZARLINK456,
- };
-
- fe = dvb_attach(xc2028_attach, fe0->dvb.frontend,
- &cfg);
- if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
- fe->ops.tuner_ops.set_config(fe, &ctl);
- }
- break;
- case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
- i2c_bus = &dev->i2c_bus[0];
-
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &dvico_fusionhdtv_xc3028,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- struct dvb_frontend *fe;
- struct xc4000_config cfg = {
- .i2c_address = 0x61,
- .default_pm = 0,
- .dvb_amplitude = 134,
- .set_smoothedcvbs = 1,
- .if_khz = 4560
- };
-
- fe = dvb_attach(xc4000_attach, fe0->dvb.frontend,
- &dev->i2c_bus[1].i2c_adap, &cfg);
- if (!fe) {
- printk(KERN_ERR "%s/2: xc4000 attach failed\n",
- dev->name);
- goto frontend_detach;
- }
- }
- break;
- case CX23885_BOARD_TBS_6920:
- i2c_bus = &dev->i2c_bus[1];
-
- fe0->dvb.frontend = dvb_attach(cx24116_attach,
- &tbs_cx24116_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL)
- fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
-
- break;
- case CX23885_BOARD_TEVII_S470:
- i2c_bus = &dev->i2c_bus[1];
-
- fe0->dvb.frontend = dvb_attach(ds3000_attach,
- &tevii_ds3000_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL)
- fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
-
- break;
- case CX23885_BOARD_DVBWORLD_2005:
- i2c_bus = &dev->i2c_bus[1];
-
- fe0->dvb.frontend = dvb_attach(cx24116_attach,
- &dvbworld_cx24116_config,
- &i2c_bus->i2c_adap);
- break;
- case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
- i2c_bus = &dev->i2c_bus[0];
- switch (port->nr) {
- /* port B */
- case 1:
- fe0->dvb.frontend = dvb_attach(stv0900_attach,
- &netup_stv0900_config,
- &i2c_bus->i2c_adap, 0);
- if (fe0->dvb.frontend != NULL) {
- if (dvb_attach(stv6110_attach,
- fe0->dvb.frontend,
- &netup_stv6110_tunerconfig_a,
- &i2c_bus->i2c_adap)) {
- if (!dvb_attach(lnbh24_attach,
- fe0->dvb.frontend,
- &i2c_bus->i2c_adap,
- LNBH24_PCL | LNBH24_TTX,
- LNBH24_TEN, 0x09))
- printk(KERN_ERR
- "No LNBH24 found!\n");
-
- }
- }
- break;
- /* port C */
- case 2:
- fe0->dvb.frontend = dvb_attach(stv0900_attach,
- &netup_stv0900_config,
- &i2c_bus->i2c_adap, 1);
- if (fe0->dvb.frontend != NULL) {
- if (dvb_attach(stv6110_attach,
- fe0->dvb.frontend,
- &netup_stv6110_tunerconfig_b,
- &i2c_bus->i2c_adap)) {
- if (!dvb_attach(lnbh24_attach,
- fe0->dvb.frontend,
- &i2c_bus->i2c_adap,
- LNBH24_PCL | LNBH24_TTX,
- LNBH24_TEN, 0x0a))
- printk(KERN_ERR
- "No LNBH24 found!\n");
-
- }
- }
- break;
- }
- break;
- case CX23885_BOARD_MYGICA_X8506:
- i2c_bus = &dev->i2c_bus[0];
- i2c_bus2 = &dev->i2c_bus[1];
- fe0->dvb.frontend = dvb_attach(lgs8gxx_attach,
- &mygica_x8506_lgs8gl5_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(xc5000_attach,
- fe0->dvb.frontend,
- &i2c_bus2->i2c_adap,
- &mygica_x8506_xc5000_config);
- }
- break;
- case CX23885_BOARD_MAGICPRO_PROHDTVE2:
- i2c_bus = &dev->i2c_bus[0];
- i2c_bus2 = &dev->i2c_bus[1];
- fe0->dvb.frontend = dvb_attach(lgs8gxx_attach,
- &magicpro_prohdtve2_lgs8g75_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(xc5000_attach,
- fe0->dvb.frontend,
- &i2c_bus2->i2c_adap,
- &magicpro_prohdtve2_xc5000_config);
- }
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- i2c_bus = &dev->i2c_bus[0];
- fe0->dvb.frontend = dvb_attach(s5h1411_attach,
- &hcw_s5h1411_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL)
- dvb_attach(tda18271_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_bus[0].i2c_adap,
- &hauppauge_tda18271_config);
-
- tda18271_attach(&dev->ts1.analog_fe,
- 0x60, &dev->i2c_bus[1].i2c_adap,
- &hauppauge_tda18271_config);
-
- break;
- case CX23885_BOARD_HAUPPAUGE_HVR1290:
- i2c_bus = &dev->i2c_bus[0];
- fe0->dvb.frontend = dvb_attach(s5h1411_attach,
- &hcw_s5h1411_config,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL)
- dvb_attach(tda18271_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_bus[0].i2c_adap,
- &hauppauge_tda18271_config);
- break;
- case CX23885_BOARD_MYGICA_X8558PRO:
- switch (port->nr) {
- /* port B */
- case 1:
- i2c_bus = &dev->i2c_bus[0];
- fe0->dvb.frontend = dvb_attach(atbm8830_attach,
- &mygica_x8558pro_atbm8830_cfg1,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(max2165_attach,
- fe0->dvb.frontend,
- &i2c_bus->i2c_adap,
- &mygic_x8558pro_max2165_cfg1);
- }
- break;
- /* port C */
- case 2:
- i2c_bus = &dev->i2c_bus[1];
- fe0->dvb.frontend = dvb_attach(atbm8830_attach,
- &mygica_x8558pro_atbm8830_cfg2,
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(max2165_attach,
- fe0->dvb.frontend,
- &i2c_bus->i2c_adap,
- &mygic_x8558pro_max2165_cfg2);
- }
- break;
- }
- break;
- case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
- i2c_bus = &dev->i2c_bus[0];
- mfe_shared = 1;/* MFE */
- port->frontends.gate = 0;/* not clear for me yet */
- /* ports B, C */
- /* MFE frontend 1 DVB-T */
- fe0->dvb.frontend = dvb_attach(stv0367ter_attach,
- &netup_stv0367_config[port->nr - 1],
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (NULL == dvb_attach(xc5000_attach,
- fe0->dvb.frontend,
- &i2c_bus->i2c_adap,
- &netup_xc5000_config[port->nr - 1]))
- goto frontend_detach;
- /* load xc5000 firmware */
- fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend);
- }
- /* MFE frontend 2 */
- fe1 = videobuf_dvb_get_frontend(&port->frontends, 2);
- if (fe1 == NULL)
- goto frontend_detach;
- /* DVB-C init */
- fe1->dvb.frontend = dvb_attach(stv0367cab_attach,
- &netup_stv0367_config[port->nr - 1],
- &i2c_bus->i2c_adap);
- if (fe1->dvb.frontend != NULL) {
- fe1->dvb.frontend->id = 1;
- if (NULL == dvb_attach(xc5000_attach,
- fe1->dvb.frontend,
- &i2c_bus->i2c_adap,
- &netup_xc5000_config[port->nr - 1]))
- goto frontend_detach;
- }
- break;
- case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
- i2c_bus = &dev->i2c_bus[0];
- i2c_bus2 = &dev->i2c_bus[1];
-
- switch (port->nr) {
- /* port b */
- case 1:
- fe0->dvb.frontend = dvb_attach(drxk_attach,
- &terratec_drxk_config[0],
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(mt2063_attach,
- fe0->dvb.frontend,
- &terratec_mt2063_config[0],
- &i2c_bus2->i2c_adap))
- goto frontend_detach;
- }
- break;
- /* port c */
- case 2:
- fe0->dvb.frontend = dvb_attach(drxk_attach,
- &terratec_drxk_config[1],
- &i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(mt2063_attach,
- fe0->dvb.frontend,
- &terratec_mt2063_config[1],
- &i2c_bus2->i2c_adap))
- goto frontend_detach;
- }
- break;
- }
- break;
- case CX23885_BOARD_TEVII_S471:
- i2c_bus = &dev->i2c_bus[1];
-
- fe0->dvb.frontend = dvb_attach(ds3000_attach,
- &tevii_ds3000_config,
- &i2c_bus->i2c_adap);
- break;
- default:
- printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
- " isn't supported yet\n",
- dev->name);
- break;
- }
-
- if ((NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend)) {
- printk(KERN_ERR "%s: frontend initialization failed\n",
- dev->name);
- goto frontend_detach;
- }
-
- /* define general-purpose callback pointer */
- fe0->dvb.frontend->callback = cx23885_tuner_callback;
- if (fe1)
- fe1->dvb.frontend->callback = cx23885_tuner_callback;
-#if 0
- /* Ensure all frontends negotiate bus access */
- fe0->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl;
- if (fe1)
- fe1->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl;
-#endif
-
- /* Put the analog decoder in standby to keep it quiet */
- call_all(dev, core, s_power, 0);
-
- if (fe0->dvb.frontend->ops.analog_ops.standby)
- fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
-
- /* register everything */
- ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
- &dev->pci->dev, adapter_nr, mfe_shared,
- NULL);
- if (ret)
- goto frontend_detach;
-
- /* init CI & MAC */
- switch (dev->board) {
- case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: {
- static struct netup_card_info cinfo;
-
- netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo);
- memcpy(port->frontends.adapter.proposed_mac,
- cinfo.port[port->nr - 1].mac, 6);
- printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=%pM\n",
- port->nr, port->frontends.adapter.proposed_mac);
-
- netup_ci_init(port);
- break;
- }
- case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: {
- struct altera_ci_config netup_ci_cfg = {
- .dev = dev,/* magic number to identify*/
- .adapter = &port->frontends.adapter,/* for CI */
- .demux = &fe0->dvb.demux,/* for hw pid filter */
- .fpga_rw = netup_altera_fpga_rw,
- };
-
- altera_ci_init(&netup_ci_cfg, port->nr);
- break;
- }
- case CX23885_BOARD_TEVII_S470: {
- u8 eeprom[256]; /* 24C02 i2c eeprom */
-
- if (port->nr != 1)
- break;
-
- /* Read entire EEPROM */
- dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
- tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom));
- printk(KERN_INFO "TeVii S470 MAC= %pM\n", eeprom + 0xa0);
- memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6);
- break;
- }
- }
-
- return ret;
-
-frontend_detach:
- port->gate_ctrl = NULL;
- videobuf_dvb_dealloc_frontends(&port->frontends);
- return -EINVAL;
-}
-
-int cx23885_dvb_register(struct cx23885_tsport *port)
-{
-
- struct videobuf_dvb_frontend *fe0;
- struct cx23885_dev *dev = port->dev;
- int err, i;
-
- /* Here we need to allocate the correct number of frontends,
- * as reflected in the cards struct. The reality is that currently
- * no cx23885 boards support this - yet. But, if we don't modify this
- * code then the second frontend would never be allocated (later)
- * and fail with error before the attach in dvb_register().
- * Without these changes we risk an OOPS later. The changes here
- * are for safety, and should provide a good foundation for the
- * future addition of any multi-frontend cx23885 based boards.
- */
- printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
- port->num_frontends);
-
- for (i = 1; i <= port->num_frontends; i++) {
- if (videobuf_dvb_alloc_frontend(
- &port->frontends, i) == NULL) {
- printk(KERN_ERR "%s() failed to alloc\n", __func__);
- return -ENOMEM;
- }
-
- fe0 = videobuf_dvb_get_frontend(&port->frontends, i);
- if (!fe0)
- err = -EINVAL;
-
- dprintk(1, "%s\n", __func__);
- dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n",
- dev->board,
- dev->name,
- dev->pci_bus,
- dev->pci_slot);
-
- err = -ENODEV;
-
- /* dvb stuff */
- /* We have to init the queue for each frontend on a port. */
- printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name);
- videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops,
- &dev->pci->dev, &port->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP,
- sizeof(struct cx23885_buffer), port, NULL);
- }
- err = dvb_register(port);
- if (err != 0)
- printk(KERN_ERR "%s() dvb_register failed err = %d\n",
- __func__, err);
-
- return err;
-}
-
-int cx23885_dvb_unregister(struct cx23885_tsport *port)
-{
- struct videobuf_dvb_frontend *fe0;
-
- /* FIXME: in an error condition where the we have
- * an expected number of frontends (attach problem)
- * then this might not clean up correctly, if 1
- * is invalid.
- * This comment only applies to future boards IF they
- * implement MFE support.
- */
- fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
- if (fe0 && fe0->dvb.frontend)
- videobuf_dvb_unregister_bus(&port->frontends);
-
- switch (port->dev->board) {
- case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
- netup_ci_exit(port);
- break;
- case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
- altera_ci_release(port->dev, port->nr);
- break;
- }
-
- port->gate_ctrl = NULL;
-
- return 0;
-}
-
diff --git a/drivers/media/video/cx23885/cx23885-f300.c b/drivers/media/video/cx23885/cx23885-f300.c
deleted file mode 100644
index 93998f22098..00000000000
--- a/drivers/media/video/cx23885/cx23885-f300.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Driver for Silicon Labs C8051F300 microcontroller.
- *
- * It is used for LNB power control in TeVii S470,
- * TBS 6920 PCIe DVB-S2 cards.
- *
- * Microcontroller connected to cx23885 GPIO pins:
- * GPIO0 - data - P0.3 F300
- * GPIO1 - reset - P0.2 F300
- * GPIO2 - clk - P0.1 F300
- * GPIO3 - busy - P0.0 F300
- *
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@me.by>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx23885.h"
-
-#define F300_DATA GPIO_0
-#define F300_RESET GPIO_1
-#define F300_CLK GPIO_2
-#define F300_BUSY GPIO_3
-
-static void f300_set_line(struct cx23885_dev *dev, u32 line, u8 lvl)
-{
- cx23885_gpio_enable(dev, line, 1);
- if (lvl == 1)
- cx23885_gpio_set(dev, line);
- else
- cx23885_gpio_clear(dev, line);
-}
-
-static u8 f300_get_line(struct cx23885_dev *dev, u32 line)
-{
- cx23885_gpio_enable(dev, line, 0);
-
- return cx23885_gpio_get(dev, line);
-}
-
-static void f300_send_byte(struct cx23885_dev *dev, u8 dta)
-{
- u8 i;
-
- for (i = 0; i < 8; i++) {
- f300_set_line(dev, F300_CLK, 0);
- udelay(30);
- f300_set_line(dev, F300_DATA, (dta & 0x80) >> 7);/* msb first */
- udelay(30);
- dta <<= 1;
- f300_set_line(dev, F300_CLK, 1);
- udelay(30);
- }
-}
-
-static u8 f300_get_byte(struct cx23885_dev *dev)
-{
- u8 i, dta = 0;
-
- for (i = 0; i < 8; i++) {
- f300_set_line(dev, F300_CLK, 0);
- udelay(30);
- dta <<= 1;
- f300_set_line(dev, F300_CLK, 1);
- udelay(30);
- dta |= f300_get_line(dev, F300_DATA);/* msb first */
-
- }
-
- return dta;
-}
-
-static u8 f300_xfer(struct dvb_frontend *fe, u8 *buf)
-{
- struct cx23885_tsport *port = fe->dvb->priv;
- struct cx23885_dev *dev = port->dev;
- u8 i, temp, ret = 0;
-
- temp = buf[0];
- for (i = 0; i < buf[0]; i++)
- temp += buf[i + 1];
- temp = (~temp + 1);/* get check sum */
- buf[1 + buf[0]] = temp;
-
- f300_set_line(dev, F300_RESET, 1);
- f300_set_line(dev, F300_CLK, 1);
- udelay(30);
- f300_set_line(dev, F300_DATA, 1);
- msleep(1);
-
- /* question: */
- f300_set_line(dev, F300_RESET, 0);/* begin to send data */
- msleep(1);
-
- f300_send_byte(dev, 0xe0);/* the slave address is 0xe0, write */
- msleep(1);
-
- temp = buf[0];
- temp += 2;
- for (i = 0; i < temp; i++)
- f300_send_byte(dev, buf[i]);
-
- f300_set_line(dev, F300_RESET, 1);/* sent data over */
- f300_set_line(dev, F300_DATA, 1);
-
- /* answer: */
- temp = 0;
- for (i = 0; ((i < 8) & (temp == 0)); i++) {
- msleep(1);
- if (f300_get_line(dev, F300_BUSY) == 0)
- temp = 1;
- }
-
- if (i > 7) {
- printk(KERN_ERR "%s: timeout, the slave no response\n",
- __func__);
- ret = 1; /* timeout, the slave no response */
- } else { /* the slave not busy, prepare for getting data */
- f300_set_line(dev, F300_RESET, 0);/*ready...*/
- msleep(1);
- f300_send_byte(dev, 0xe1);/* 0xe1 is Read */
- msleep(1);
- temp = f300_get_byte(dev);/*get the data length */
- if (temp > 14)
- temp = 14;
-
- for (i = 0; i < (temp + 1); i++)
- f300_get_byte(dev);/* get data to empty buffer */
-
- f300_set_line(dev, F300_RESET, 1);/* received data over */
- f300_set_line(dev, F300_DATA, 1);
- }
-
- return ret;
-}
-
-int f300_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
- u8 buf[16];
-
- buf[0] = 0x05;
- buf[1] = 0x38;/* write port */
- buf[2] = 0x01;/* A port, lnb power */
-
- switch (voltage) {
- case SEC_VOLTAGE_13:
- buf[3] = 0x01;/* power on */
- buf[4] = 0x02;/* B port, H/V */
- buf[5] = 0x00;/*13V v*/
- break;
- case SEC_VOLTAGE_18:
- buf[3] = 0x01;
- buf[4] = 0x02;
- buf[5] = 0x01;/* 18V h*/
- break;
- case SEC_VOLTAGE_OFF:
- buf[3] = 0x00;/* power off */
- buf[4] = 0x00;
- buf[5] = 0x00;
- break;
- }
-
- return f300_xfer(fe, buf);
-}
diff --git a/drivers/media/video/cx23885/cx23885-f300.h b/drivers/media/video/cx23885/cx23885-f300.h
deleted file mode 100644
index e73344c9496..00000000000
--- a/drivers/media/video/cx23885/cx23885-f300.h
+++ /dev/null
@@ -1,2 +0,0 @@
-extern int f300_set_voltage(struct dvb_frontend *fe,
- fe_sec_voltage_t voltage);
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
deleted file mode 100644
index 4887314339c..00000000000
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Driver for the Conexant CX23885 PCIe bridge
- *
- * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-
-#include "cx23885.h"
-
-#include <media/v4l2-common.h>
-
-static unsigned int i2c_debug;
-module_param(i2c_debug, int, 0644);
-MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
-
-static unsigned int i2c_scan;
-module_param(i2c_scan, int, 0444);
-MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
-
-#define dprintk(level, fmt, arg...)\
- do { if (i2c_debug >= level)\
- printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
- } while (0)
-
-#define I2C_WAIT_DELAY 32
-#define I2C_WAIT_RETRY 64
-
-#define I2C_EXTEND (1 << 3)
-#define I2C_NOSTOP (1 << 4)
-
-static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
-{
- struct cx23885_i2c *bus = i2c_adap->algo_data;
- struct cx23885_dev *dev = bus->dev;
- return cx_read(bus->reg_stat) & 0x01;
-}
-
-static inline int i2c_is_busy(struct i2c_adapter *i2c_adap)
-{
- struct cx23885_i2c *bus = i2c_adap->algo_data;
- struct cx23885_dev *dev = bus->dev;
- return cx_read(bus->reg_stat) & 0x02 ? 1 : 0;
-}
-
-static int i2c_wait_done(struct i2c_adapter *i2c_adap)
-{
- int count;
-
- for (count = 0; count < I2C_WAIT_RETRY; count++) {
- if (!i2c_is_busy(i2c_adap))
- break;
- udelay(I2C_WAIT_DELAY);
- }
-
- if (I2C_WAIT_RETRY == count)
- return 0;
-
- return 1;
-}
-
-static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
- const struct i2c_msg *msg, int joined_rlen)
-{
- struct cx23885_i2c *bus = i2c_adap->algo_data;
- struct cx23885_dev *dev = bus->dev;
- u32 wdata, addr, ctrl;
- int retval, cnt;
-
- if (joined_rlen)
- dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__,
- msg->len, joined_rlen);
- else
- dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len);
-
- /* Deal with i2c probe functions with zero payload */
- if (msg->len == 0) {
- cx_write(bus->reg_addr, msg->addr << 25);
- cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2));
- if (!i2c_wait_done(i2c_adap))
- return -EIO;
- if (!i2c_slave_did_ack(i2c_adap))
- return -ENXIO;
-
- dprintk(1, "%s() returns 0\n", __func__);
- return 0;
- }
-
-
- /* dev, reg + first byte */
- addr = (msg->addr << 25) | msg->buf[0];
- wdata = msg->buf[0];
- ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
-
- if (msg->len > 1)
- ctrl |= I2C_NOSTOP | I2C_EXTEND;
- else if (joined_rlen)
- ctrl |= I2C_NOSTOP;
-
- cx_write(bus->reg_addr, addr);
- cx_write(bus->reg_wdata, wdata);
- cx_write(bus->reg_ctrl, ctrl);
-
- if (!i2c_wait_done(i2c_adap))
- goto eio;
- if (i2c_debug) {
- printk(" <W %02x %02x", msg->addr << 1, msg->buf[0]);
- if (!(ctrl & I2C_NOSTOP))
- printk(" >\n");
- }
-
- for (cnt = 1; cnt < msg->len; cnt++) {
- /* following bytes */
- wdata = msg->buf[cnt];
- ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
-
- if (cnt < msg->len - 1)
- ctrl |= I2C_NOSTOP | I2C_EXTEND;
- else if (joined_rlen)
- ctrl |= I2C_NOSTOP;
-
- cx_write(bus->reg_addr, addr);
- cx_write(bus->reg_wdata, wdata);
- cx_write(bus->reg_ctrl, ctrl);
-
- if (!i2c_wait_done(i2c_adap))
- goto eio;
- if (i2c_debug) {
- dprintk(1, " %02x", msg->buf[cnt]);
- if (!(ctrl & I2C_NOSTOP))
- dprintk(1, " >\n");
- }
- }
- return msg->len;
-
- eio:
- retval = -EIO;
- if (i2c_debug)
- printk(KERN_ERR " ERR: %d\n", retval);
- return retval;
-}
-
-static int i2c_readbytes(struct i2c_adapter *i2c_adap,
- const struct i2c_msg *msg, int joined)
-{
- struct cx23885_i2c *bus = i2c_adap->algo_data;
- struct cx23885_dev *dev = bus->dev;
- u32 ctrl, cnt;
- int retval;
-
-
- if (i2c_debug && !joined)
- dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len);
-
- /* Deal with i2c probe functions with zero payload */
- if (msg->len == 0) {
- cx_write(bus->reg_addr, msg->addr << 25);
- cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1);
- if (!i2c_wait_done(i2c_adap))
- return -EIO;
- if (!i2c_slave_did_ack(i2c_adap))
- return -ENXIO;
-
-
- dprintk(1, "%s() returns 0\n", __func__);
- return 0;
- }
-
- if (i2c_debug) {
- if (joined)
- dprintk(1, " R");
- else
- dprintk(1, " <R %02x", (msg->addr << 1) + 1);
- }
-
- for (cnt = 0; cnt < msg->len; cnt++) {
-
- ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1;
-
- if (cnt < msg->len - 1)
- ctrl |= I2C_NOSTOP | I2C_EXTEND;
-
- cx_write(bus->reg_addr, msg->addr << 25);
- cx_write(bus->reg_ctrl, ctrl);
-
- if (!i2c_wait_done(i2c_adap))
- goto eio;
- msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff;
- if (i2c_debug) {
- dprintk(1, " %02x", msg->buf[cnt]);
- if (!(ctrl & I2C_NOSTOP))
- dprintk(1, " >\n");
- }
- }
- return msg->len;
-
- eio:
- retval = -EIO;
- if (i2c_debug)
- printk(KERN_ERR " ERR: %d\n", retval);
- return retval;
-}
-
-static int i2c_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg *msgs, int num)
-{
- struct cx23885_i2c *bus = i2c_adap->algo_data;
- struct cx23885_dev *dev = bus->dev;
- int i, retval = 0;
-
- dprintk(1, "%s(num = %d)\n", __func__, num);
-
- for (i = 0 ; i < num; i++) {
- dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n",
- __func__, num, msgs[i].addr, msgs[i].len);
- if (msgs[i].flags & I2C_M_RD) {
- /* read */
- retval = i2c_readbytes(i2c_adap, &msgs[i], 0);
- } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
- msgs[i].addr == msgs[i + 1].addr) {
- /* write then read from same address */
- retval = i2c_sendbytes(i2c_adap, &msgs[i],
- msgs[i + 1].len);
- if (retval < 0)
- goto err;
- i++;
- retval = i2c_readbytes(i2c_adap, &msgs[i], 1);
- } else {
- /* write */
- retval = i2c_sendbytes(i2c_adap, &msgs[i], 0);
- }
- if (retval < 0)
- goto err;
- }
- return num;
-
- err:
- return retval;
-}
-
-static u32 cx23885_functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm cx23885_i2c_algo_template = {
- .master_xfer = i2c_xfer,
- .functionality = cx23885_functionality,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static struct i2c_adapter cx23885_i2c_adap_template = {
- .name = "cx23885",
- .owner = THIS_MODULE,
- .algo = &cx23885_i2c_algo_template,
-};
-
-static struct i2c_client cx23885_i2c_client_template = {
- .name = "cx23885 internal",
-};
-
-static char *i2c_devs[128] = {
- [0x10 >> 1] = "tda10048",
- [0x12 >> 1] = "dib7000pc",
- [0x1c >> 1] = "lgdt3303",
- [0x86 >> 1] = "tda9887",
- [0x32 >> 1] = "cx24227",
- [0x88 >> 1] = "cx25837",
- [0x84 >> 1] = "tda8295",
- [0x98 >> 1] = "flatiron",
- [0xa0 >> 1] = "eeprom",
- [0xc0 >> 1] = "tuner/mt2131/tda8275",
- [0xc2 >> 1] = "tuner/mt2131/tda8275/xc5000/xc3028",
- [0xc8 >> 1] = "tuner/xc3028L",
-};
-
-static void do_i2c_scan(char *name, struct i2c_client *c)
-{
- unsigned char buf;
- int i, rc;
-
- for (i = 0; i < 128; i++) {
- c->addr = i;
- rc = i2c_master_recv(c, &buf, 0);
- if (rc < 0)
- continue;
- printk(KERN_INFO "%s: i2c scan: found device @ 0x%x [%s]\n",
- name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
- }
-}
-
-/* init + register i2c adapter */
-int cx23885_i2c_register(struct cx23885_i2c *bus)
-{
- struct cx23885_dev *dev = bus->dev;
-
- dprintk(1, "%s(bus = %d)\n", __func__, bus->nr);
-
- bus->i2c_adap = cx23885_i2c_adap_template;
- bus->i2c_client = cx23885_i2c_client_template;
- bus->i2c_adap.dev.parent = &dev->pci->dev;
-
- strlcpy(bus->i2c_adap.name, bus->dev->name,
- sizeof(bus->i2c_adap.name));
-
- bus->i2c_adap.algo_data = bus;
- i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
- i2c_add_adapter(&bus->i2c_adap);
-
- bus->i2c_client.adapter = &bus->i2c_adap;
-
- if (0 == bus->i2c_rc) {
- dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr);
- if (i2c_scan) {
- printk(KERN_INFO "%s: scan bus %d:\n",
- dev->name, bus->nr);
- do_i2c_scan(dev->name, &bus->i2c_client);
- }
- } else
- printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
- dev->name, bus->nr);
-
- /* Instantiate the IR receiver device, if present */
- if (0 == bus->i2c_rc) {
- struct i2c_board_info info;
- const unsigned short addr_list[] = {
- 0x6b, I2C_CLIENT_END
- };
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
- /* Use quick read command for probe, some IR chips don't
- * support writes */
- i2c_new_probed_device(&bus->i2c_adap, &info, addr_list,
- i2c_probe_func_quick_read);
- }
-
- return bus->i2c_rc;
-}
-
-int cx23885_i2c_unregister(struct cx23885_i2c *bus)
-{
- i2c_del_adapter(&bus->i2c_adap);
- return 0;
-}
-
-void cx23885_av_clk(struct cx23885_dev *dev, int enable)
-{
- /* write 0 to bus 2 addr 0x144 via i2x_xfer() */
- char buffer[3];
- struct i2c_msg msg;
- dprintk(1, "%s(enabled = %d)\n", __func__, enable);
-
- /* Register 0x144 */
- buffer[0] = 0x01;
- buffer[1] = 0x44;
- if (enable == 1)
- buffer[2] = 0x05;
- else
- buffer[2] = 0x00;
-
- msg.addr = 0x44;
- msg.flags = I2C_M_TEN;
- msg.len = 3;
- msg.buf = buffer;
-
- i2c_xfer(&dev->i2c_bus[2].i2c_adap, &msg, 1);
-}
-
-/* ----------------------------------------------------------------------- */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
deleted file mode 100644
index bcbf7faf1ba..00000000000
--- a/drivers/media/video/cx23885/cx23885-input.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Driver for the Conexant CX23885/7/8 PCIe bridge
- *
- * Infrared remote control input device
- *
- * Most of this file is
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * However, the cx23885_input_{init,fini} functions contained herein are
- * derived from Linux kernel files linux/media/video/.../...-input.c marked as:
- *
- * Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
- * Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
- * Markus Rechberger <mrechberger@gmail.com>
- * Mauro Carvalho Chehab <mchehab@infradead.org>
- * Sascha Sommer <saschasommer@freenet.de>
- * Copyright (C) 2004, 2005 Chris Pascoe
- * Copyright (C) 2003, 2004 Gerd Knorr
- * Copyright (C) 2003 Pavel Machek
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <linux/slab.h>
-#include <media/rc-core.h>
-#include <media/v4l2-subdev.h>
-
-#include "cx23885.h"
-
-#define MODULE_NAME "cx23885"
-
-static void cx23885_input_process_measurements(struct cx23885_dev *dev,
- bool overrun)
-{
- struct cx23885_kernel_ir *kernel_ir = dev->kernel_ir;
-
- ssize_t num;
- int count, i;
- bool handle = false;
- struct ir_raw_event ir_core_event[64];
-
- do {
- num = 0;
- v4l2_subdev_call(dev->sd_ir, ir, rx_read, (u8 *) ir_core_event,
- sizeof(ir_core_event), &num);
-
- count = num / sizeof(struct ir_raw_event);
-
- for (i = 0; i < count; i++) {
- ir_raw_event_store(kernel_ir->rc,
- &ir_core_event[i]);
- handle = true;
- }
- } while (num != 0);
-
- if (overrun)
- ir_raw_event_reset(kernel_ir->rc);
- else if (handle)
- ir_raw_event_handle(kernel_ir->rc);
-}
-
-void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
-{
- struct v4l2_subdev_ir_parameters params;
- int overrun, data_available;
-
- if (dev->sd_ir == NULL || events == 0)
- return;
-
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1270:
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- case CX23885_BOARD_HAUPPAUGE_HVR1290:
- case CX23885_BOARD_TEVII_S470:
- case CX23885_BOARD_HAUPPAUGE_HVR1250:
- /*
- * The only boards we handle right now. However other boards
- * using the CX2388x integrated IR controller should be similar
- */
- break;
- default:
- return;
- }
-
- overrun = events & (V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN |
- V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN);
-
- data_available = events & (V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED |
- V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ);
-
- if (overrun) {
- /* If there was a FIFO overrun, stop the device */
- v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
- params.enable = false;
- /* Mitigate race with cx23885_input_ir_stop() */
- params.shutdown = atomic_read(&dev->ir_input_stopping);
- v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
- }
-
- if (data_available)
- cx23885_input_process_measurements(dev, overrun);
-
- if (overrun) {
- /* If there was a FIFO overrun, clear & restart the device */
- params.enable = true;
- /* Mitigate race with cx23885_input_ir_stop() */
- params.shutdown = atomic_read(&dev->ir_input_stopping);
- v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
- }
-}
-
-static int cx23885_input_ir_start(struct cx23885_dev *dev)
-{
- struct v4l2_subdev_ir_parameters params;
-
- if (dev->sd_ir == NULL)
- return -ENODEV;
-
- atomic_set(&dev->ir_input_stopping, 0);
-
- v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1270:
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- case CX23885_BOARD_HAUPPAUGE_HVR1290:
- case CX23885_BOARD_HAUPPAUGE_HVR1250:
- /*
- * The IR controller on this board only returns pulse widths.
- * Any other mode setting will fail to set up the device.
- */
- params.mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
- params.enable = true;
- params.interrupt_enable = true;
- params.shutdown = false;
-
- /* Setup for baseband compatible with both RC-5 and RC-6A */
- params.modulation = false;
- /* RC-5: 2,222,222 ns = 1/36 kHz * 32 cycles * 2 marks * 1.25*/
- /* RC-6A: 3,333,333 ns = 1/36 kHz * 16 cycles * 6 marks * 1.25*/
- params.max_pulse_width = 3333333; /* ns */
- /* RC-5: 666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */
- /* RC-6A: 333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */
- params.noise_filter_min_width = 333333; /* ns */
- /*
- * This board has inverted receive sense:
- * mark is received as low logic level;
- * falling edges are detected as rising edges; etc.
- */
- params.invert_level = true;
- break;
- case CX23885_BOARD_TEVII_S470:
- /*
- * The IR controller on this board only returns pulse widths.
- * Any other mode setting will fail to set up the device.
- */
- params.mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
- params.enable = true;
- params.interrupt_enable = true;
- params.shutdown = false;
-
- /* Setup for a standard NEC protocol */
- params.carrier_freq = 37917; /* Hz, 455 kHz/12 for NEC */
- params.carrier_range_lower = 33000; /* Hz */
- params.carrier_range_upper = 43000; /* Hz */
- params.duty_cycle = 33; /* percent, 33 percent for NEC */
-
- /*
- * NEC max pulse width: (64/3)/(455 kHz/12) * 16 nec_units
- * (64/3)/(455 kHz/12) * 16 nec_units * 1.375 = 12378022 ns
- */
- params.max_pulse_width = 12378022; /* ns */
-
- /*
- * NEC noise filter min width: (64/3)/(455 kHz/12) * 1 nec_unit
- * (64/3)/(455 kHz/12) * 1 nec_units * 0.625 = 351648 ns
- */
- params.noise_filter_min_width = 351648; /* ns */
-
- params.modulation = false;
- params.invert_level = true;
- break;
- }
- v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
- return 0;
-}
-
-static int cx23885_input_ir_open(struct rc_dev *rc)
-{
- struct cx23885_kernel_ir *kernel_ir = rc->priv;
-
- if (kernel_ir->cx == NULL)
- return -ENODEV;
-
- return cx23885_input_ir_start(kernel_ir->cx);
-}
-
-static void cx23885_input_ir_stop(struct cx23885_dev *dev)
-{
- struct v4l2_subdev_ir_parameters params;
-
- if (dev->sd_ir == NULL)
- return;
-
- /*
- * Stop the sd_ir subdevice from generating notifications and
- * scheduling work.
- * It is shutdown this way in order to mitigate a race with
- * cx23885_input_rx_work_handler() in the overrun case, which could
- * re-enable the subdevice.
- */
- atomic_set(&dev->ir_input_stopping, 1);
- v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
- while (params.shutdown == false) {
- params.enable = false;
- params.interrupt_enable = false;
- params.shutdown = true;
- v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
- v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
- }
- flush_work(&dev->cx25840_work);
- flush_work(&dev->ir_rx_work);
- flush_work(&dev->ir_tx_work);
-}
-
-static void cx23885_input_ir_close(struct rc_dev *rc)
-{
- struct cx23885_kernel_ir *kernel_ir = rc->priv;
-
- if (kernel_ir->cx != NULL)
- cx23885_input_ir_stop(kernel_ir->cx);
-}
-
-int cx23885_input_init(struct cx23885_dev *dev)
-{
- struct cx23885_kernel_ir *kernel_ir;
- struct rc_dev *rc;
- char *rc_map;
- enum rc_driver_type driver_type;
- unsigned long allowed_protos;
-
- int ret;
-
- /*
- * If the IR device (hardware registers, chip, GPIO lines, etc.) isn't
- * encapsulated in a v4l2_subdev, then I'm not going to deal with it.
- */
- if (dev->sd_ir == NULL)
- return -ENODEV;
-
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1270:
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- case CX23885_BOARD_HAUPPAUGE_HVR1290:
- case CX23885_BOARD_HAUPPAUGE_HVR1250:
- /* Integrated CX2388[58] IR controller */
- driver_type = RC_DRIVER_IR_RAW;
- allowed_protos = RC_TYPE_ALL;
- /* The grey Hauppauge RC-5 remote */
- rc_map = RC_MAP_HAUPPAUGE;
- break;
- case CX23885_BOARD_TEVII_S470:
- /* Integrated CX23885 IR controller */
- driver_type = RC_DRIVER_IR_RAW;
- allowed_protos = RC_TYPE_ALL;
- /* A guess at the remote */
- rc_map = RC_MAP_TEVII_NEC;
- break;
- default:
- return -ENODEV;
- }
-
- /* cx23885 board instance kernel IR state */
- kernel_ir = kzalloc(sizeof(struct cx23885_kernel_ir), GFP_KERNEL);
- if (kernel_ir == NULL)
- return -ENOMEM;
-
- kernel_ir->cx = dev;
- kernel_ir->name = kasprintf(GFP_KERNEL, "cx23885 IR (%s)",
- cx23885_boards[dev->board].name);
- kernel_ir->phys = kasprintf(GFP_KERNEL, "pci-%s/ir0",
- pci_name(dev->pci));
-
- /* input device */
- rc = rc_allocate_device();
- if (!rc) {
- ret = -ENOMEM;
- goto err_out_free;
- }
-
- kernel_ir->rc = rc;
- rc->input_name = kernel_ir->name;
- rc->input_phys = kernel_ir->phys;
- rc->input_id.bustype = BUS_PCI;
- rc->input_id.version = 1;
- if (dev->pci->subsystem_vendor) {
- rc->input_id.vendor = dev->pci->subsystem_vendor;
- rc->input_id.product = dev->pci->subsystem_device;
- } else {
- rc->input_id.vendor = dev->pci->vendor;
- rc->input_id.product = dev->pci->device;
- }
- rc->dev.parent = &dev->pci->dev;
- rc->driver_type = driver_type;
- rc->allowed_protos = allowed_protos;
- rc->priv = kernel_ir;
- rc->open = cx23885_input_ir_open;
- rc->close = cx23885_input_ir_close;
- rc->map_name = rc_map;
- rc->driver_name = MODULE_NAME;
-
- /* Go */
- dev->kernel_ir = kernel_ir;
- ret = rc_register_device(rc);
- if (ret)
- goto err_out_stop;
-
- return 0;
-
-err_out_stop:
- cx23885_input_ir_stop(dev);
- dev->kernel_ir = NULL;
- rc_free_device(rc);
-err_out_free:
- kfree(kernel_ir->phys);
- kfree(kernel_ir->name);
- kfree(kernel_ir);
- return ret;
-}
-
-void cx23885_input_fini(struct cx23885_dev *dev)
-{
- /* Always stop the IR hardware from generating interrupts */
- cx23885_input_ir_stop(dev);
-
- if (dev->kernel_ir == NULL)
- return;
- rc_unregister_device(dev->kernel_ir->rc);
- kfree(dev->kernel_ir->phys);
- kfree(dev->kernel_ir->name);
- kfree(dev->kernel_ir);
- dev->kernel_ir = NULL;
-}
diff --git a/drivers/media/video/cx23885/cx23885-input.h b/drivers/media/video/cx23885/cx23885-input.h
deleted file mode 100644
index 75ef15d3f52..00000000000
--- a/drivers/media/video/cx23885/cx23885-input.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Driver for the Conexant CX23885/7/8 PCIe bridge
- *
- * Infrared remote control input device
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#ifndef _CX23885_INPUT_H_
-#define _CX23885_INPUT_H_
-int cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events);
-
-int cx23885_input_init(struct cx23885_dev *dev);
-void cx23885_input_fini(struct cx23885_dev *dev);
-#endif
diff --git a/drivers/media/video/cx23885/cx23885-ioctl.c b/drivers/media/video/cx23885/cx23885-ioctl.c
deleted file mode 100644
index 44812ca7889..00000000000
--- a/drivers/media/video/cx23885/cx23885-ioctl.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Driver for the Conexant CX23885/7/8 PCIe bridge
- *
- * Various common ioctl() support functions
- *
- * Copyright (c) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx23885.h"
-#include <media/v4l2-chip-ident.h>
-
-int cx23885_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
- int err = 0;
- u8 rev;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- switch (chip->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- switch (chip->match.addr) {
- case 0:
- rev = cx_read(RDR_CFG2) & 0xff;
- switch (dev->pci->device) {
- case 0x8852:
- /* rev 0x04 could be '885 or '888. Pick '888. */
- if (rev == 0x04)
- chip->ident = V4L2_IDENT_CX23888;
- else
- chip->ident = V4L2_IDENT_CX23885;
- break;
- case 0x8880:
- if (rev == 0x0e || rev == 0x0f)
- chip->ident = V4L2_IDENT_CX23887;
- else
- chip->ident = V4L2_IDENT_CX23888;
- break;
- default:
- chip->ident = V4L2_IDENT_UNKNOWN;
- break;
- }
- chip->revision = (dev->pci->device << 16) | (rev << 8) |
- (dev->hwrevision & 0xff);
- break;
- case 1:
- if (dev->v4l_device != NULL) {
- chip->ident = V4L2_IDENT_CX23417;
- chip->revision = 0;
- }
- break;
- case 2:
- /*
- * The integrated IR controller on the CX23888 is
- * host chip 2. It may not be used/initialized or sd_ir
- * may be pointing at the cx25840 subdevice for the
- * IR controller on the CX23885. Thus we find it
- * without using the dev->sd_ir pointer.
- */
- call_hw(dev, CX23885_HW_888_IR, core, g_chip_ident,
- chip);
- break;
- default:
- err = -EINVAL; /* per V4L2 spec */
- break;
- }
- break;
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
- call_all(dev, core, g_chip_ident, chip);
- break;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- /*
- * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
- * to look if a chip is at the address with no driver. That's a
- * dangerous thing to do with EEPROMs anyway.
- */
- call_all(dev, core, g_chip_ident, chip);
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int cx23885_g_host_register(struct cx23885_dev *dev,
- struct v4l2_dbg_register *reg)
-{
- if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
- return -EINVAL;
-
- reg->size = 4;
- reg->val = cx_read(reg->reg);
- return 0;
-}
-
-static int cx23417_g_register(struct cx23885_dev *dev,
- struct v4l2_dbg_register *reg)
-{
- u32 value;
-
- if (dev->v4l_device == NULL)
- return -EINVAL;
-
- if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000)
- return -EINVAL;
-
- if (mc417_register_read(dev, (u16) reg->reg, &value))
- return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */
-
- reg->size = 4;
- reg->val = value;
- return 0;
-}
-
-int cx23885_g_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
- switch (reg->match.addr) {
- case 0:
- return cx23885_g_host_register(dev, reg);
- case 1:
- return cx23417_g_register(dev, reg);
- default:
- break;
- }
- }
-
- /* FIXME - any error returns should not be ignored */
- call_all(dev, core, g_register, reg);
- return 0;
-}
-
-static int cx23885_s_host_register(struct cx23885_dev *dev,
- struct v4l2_dbg_register *reg)
-{
- if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
- return -EINVAL;
-
- reg->size = 4;
- cx_write(reg->reg, reg->val);
- return 0;
-}
-
-static int cx23417_s_register(struct cx23885_dev *dev,
- struct v4l2_dbg_register *reg)
-{
- if (dev->v4l_device == NULL)
- return -EINVAL;
-
- if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000)
- return -EINVAL;
-
- if (mc417_register_write(dev, (u16) reg->reg, (u32) reg->val))
- return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */
-
- reg->size = 4;
- return 0;
-}
-
-int cx23885_s_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
- switch (reg->match.addr) {
- case 0:
- return cx23885_s_host_register(dev, reg);
- case 1:
- return cx23417_s_register(dev, reg);
- default:
- break;
- }
- }
-
- /* FIXME - any error returns should not be ignored */
- call_all(dev, core, s_register, reg);
- return 0;
-}
-#endif
diff --git a/drivers/media/video/cx23885/cx23885-ioctl.h b/drivers/media/video/cx23885/cx23885-ioctl.h
deleted file mode 100644
index 315be0ca5a0..00000000000
--- a/drivers/media/video/cx23885/cx23885-ioctl.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Driver for the Conexant CX23885/7/8 PCIe bridge
- *
- * Various common ioctl() support functions
- *
- * Copyright (c) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _CX23885_IOCTL_H_
-#define _CX23885_IOCTL_H_
-
-int cx23885_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *chip);
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-int cx23885_g_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg);
-
-
-int cx23885_s_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg);
-
-#endif
-#endif
diff --git a/drivers/media/video/cx23885/cx23885-ir.c b/drivers/media/video/cx23885/cx23885-ir.c
deleted file mode 100644
index 7125247dd25..00000000000
--- a/drivers/media/video/cx23885/cx23885-ir.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Driver for the Conexant CX23885/7/8 PCIe bridge
- *
- * Infrared device support routines - non-input, non-vl42_subdev routines
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <media/v4l2-device.h>
-
-#include "cx23885.h"
-#include "cx23885-input.h"
-
-#define CX23885_IR_RX_FIFO_SERVICE_REQ 0
-#define CX23885_IR_RX_END_OF_RX_DETECTED 1
-#define CX23885_IR_RX_HW_FIFO_OVERRUN 2
-#define CX23885_IR_RX_SW_FIFO_OVERRUN 3
-
-#define CX23885_IR_TX_FIFO_SERVICE_REQ 0
-
-
-void cx23885_ir_rx_work_handler(struct work_struct *work)
-{
- struct cx23885_dev *dev =
- container_of(work, struct cx23885_dev, ir_rx_work);
- u32 events = 0;
- unsigned long *notifications = &dev->ir_rx_notifications;
-
- if (test_and_clear_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications))
- events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN;
- if (test_and_clear_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications))
- events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN;
- if (test_and_clear_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications))
- events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED;
- if (test_and_clear_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications))
- events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
-
- if (events == 0)
- return;
-
- if (dev->kernel_ir)
- cx23885_input_rx_work_handler(dev, events);
-}
-
-void cx23885_ir_tx_work_handler(struct work_struct *work)
-{
- struct cx23885_dev *dev =
- container_of(work, struct cx23885_dev, ir_tx_work);
- u32 events = 0;
- unsigned long *notifications = &dev->ir_tx_notifications;
-
- if (test_and_clear_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications))
- events |= V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ;
-
- if (events == 0)
- return;
-
-}
-
-/* Possibly called in an IRQ context */
-void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events)
-{
- struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev);
- unsigned long *notifications = &dev->ir_rx_notifications;
-
- if (events & V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ)
- set_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications);
- if (events & V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED)
- set_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications);
- if (events & V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN)
- set_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications);
- if (events & V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN)
- set_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications);
-
- /*
- * For the integrated AV core, we are already in a workqueue context.
- * For the CX23888 integrated IR, we are in an interrupt context.
- */
- if (sd == dev->sd_cx25840)
- cx23885_ir_rx_work_handler(&dev->ir_rx_work);
- else
- schedule_work(&dev->ir_rx_work);
-}
-
-/* Possibly called in an IRQ context */
-void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events)
-{
- struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev);
- unsigned long *notifications = &dev->ir_tx_notifications;
-
- if (events & V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ)
- set_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications);
-
- /*
- * For the integrated AV core, we are already in a workqueue context.
- * For the CX23888 integrated IR, we are in an interrupt context.
- */
- if (sd == dev->sd_cx25840)
- cx23885_ir_tx_work_handler(&dev->ir_tx_work);
- else
- schedule_work(&dev->ir_tx_work);
-}
diff --git a/drivers/media/video/cx23885/cx23885-ir.h b/drivers/media/video/cx23885/cx23885-ir.h
deleted file mode 100644
index 0c9d8bda9e2..00000000000
--- a/drivers/media/video/cx23885/cx23885-ir.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Driver for the Conexant CX23885/7/8 PCIe bridge
- *
- * Infrared device support routines - non-input, non-vl42_subdev routines
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#ifndef _CX23885_IR_H_
-#define _CX23885_IR_H_
-void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events);
-void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events);
-
-void cx23885_ir_rx_work_handler(struct work_struct *work);
-void cx23885_ir_tx_work_handler(struct work_struct *work);
-#endif
diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h
deleted file mode 100644
index a99936e0cbc..00000000000
--- a/drivers/media/video/cx23885/cx23885-reg.h
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * Driver for the Conexant CX23885 PCIe bridge
- *
- * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _CX23885_REG_H_
-#define _CX23885_REG_H_
-
-/*
-Address Map
-0x00000000 -> 0x00009000 TX SRAM (Fifos)
-0x00010000 -> 0x00013c00 RX SRAM CMDS + CDT
-
-EACH CMDS struct is 0x80 bytes long
-
-DMAx_PTR1 = 0x03040 address of first cluster
-DMAx_PTR2 = 0x10600 address of the CDT
-DMAx_CNT1 = cluster size in (bytes >> 4) -1
-DMAx_CNT2 = total cdt size for all entries >> 3
-
-Cluster Descriptor entry = 4 DWORDS
- DWORD 0 -> ptr to cluster
- DWORD 1 Reserved
- DWORD 2 Reserved
- DWORD 3 Reserved
-
-Channel manager Data Structure entry = 20 DWORD
- 0 IntialProgramCounterLow
- 1 IntialProgramCounterHigh
- 2 ClusterDescriptorTableBase
- 3 ClusterDescriptorTableSize
- 4 InstructionQueueBase
- 5 InstructionQueueSize
-... Reserved
- 19 Reserved
-*/
-
-/* Risc Instructions */
-#define RISC_CNT_INC 0x00010000
-#define RISC_CNT_RESET 0x00030000
-#define RISC_IRQ1 0x01000000
-#define RISC_IRQ2 0x02000000
-#define RISC_EOL 0x04000000
-#define RISC_SOL 0x08000000
-#define RISC_WRITE 0x10000000
-#define RISC_SKIP 0x20000000
-#define RISC_JUMP 0x70000000
-#define RISC_SYNC 0x80000000
-#define RISC_RESYNC 0x80008000
-#define RISC_READ 0x90000000
-#define RISC_WRITERM 0xB0000000
-#define RISC_WRITECM 0xC0000000
-#define RISC_WRITECR 0xD0000000
-#define RISC_WRITEC 0x50000000
-#define RISC_READC 0xA0000000
-
-
-/* Audio and Video Core */
-#define HOST_REG1 0x00000000
-#define HOST_REG2 0x00000001
-#define HOST_REG3 0x00000002
-
-/* Chip Configuration Registers */
-#define CHIP_CTRL 0x00000100
-#define AFE_CTRL 0x00000104
-#define VID_PLL_INT_POST 0x00000108
-#define VID_PLL_FRAC 0x0000010C
-#define AUX_PLL_INT_POST 0x00000110
-#define AUX_PLL_FRAC 0x00000114
-#define SYS_PLL_INT_POST 0x00000118
-#define SYS_PLL_FRAC 0x0000011C
-#define PIN_CTRL 0x00000120
-#define AUD_IO_CTRL 0x00000124
-#define AUD_LOCK1 0x00000128
-#define AUD_LOCK2 0x0000012C
-#define POWER_CTRL 0x00000130
-#define AFE_DIAG_CTRL1 0x00000134
-#define AFE_DIAG_CTRL3 0x0000013C
-#define PLL_DIAG_CTRL 0x00000140
-#define AFE_CLK_OUT_CTRL 0x00000144
-#define DLL1_DIAG_CTRL 0x0000015C
-
-/* GPIO[23:19] Output Enable */
-#define GPIO2_OUT_EN_REG 0x00000160
-/* GPIO[23:19] Data Registers */
-#define GPIO2 0x00000164
-
-#define IFADC_CTRL 0x00000180
-
-/* Infrared Remote Registers */
-#define IR_CNTRL_REG 0x00000200
-#define IR_TXCLK_REG 0x00000204
-#define IR_RXCLK_REG 0x00000208
-#define IR_CDUTY_REG 0x0000020C
-#define IR_STAT_REG 0x00000210
-#define IR_IRQEN_REG 0x00000214
-#define IR_FILTR_REG 0x00000218
-#define IR_FIFO_REG 0x0000023C
-
-/* Video Decoder Registers */
-#define MODE_CTRL 0x00000400
-#define OUT_CTRL1 0x00000404
-#define OUT_CTRL2 0x00000408
-#define GEN_STAT 0x0000040C
-#define INT_STAT_MASK 0x00000410
-#define LUMA_CTRL 0x00000414
-#define HSCALE_CTRL 0x00000418
-#define VSCALE_CTRL 0x0000041C
-#define CHROMA_CTRL 0x00000420
-#define VBI_LINE_CTRL1 0x00000424
-#define VBI_LINE_CTRL2 0x00000428
-#define VBI_LINE_CTRL3 0x0000042C
-#define VBI_LINE_CTRL4 0x00000430
-#define VBI_LINE_CTRL5 0x00000434
-#define VBI_FC_CFG 0x00000438
-#define VBI_MISC_CFG1 0x0000043C
-#define VBI_MISC_CFG2 0x00000440
-#define VBI_PAY1 0x00000444
-#define VBI_PAY2 0x00000448
-#define VBI_CUST1_CFG1 0x0000044C
-#define VBI_CUST1_CFG2 0x00000450
-#define VBI_CUST1_CFG3 0x00000454
-#define VBI_CUST2_CFG1 0x00000458
-#define VBI_CUST2_CFG2 0x0000045C
-#define VBI_CUST2_CFG3 0x00000460
-#define VBI_CUST3_CFG1 0x00000464
-#define VBI_CUST3_CFG2 0x00000468
-#define VBI_CUST3_CFG3 0x0000046C
-#define HORIZ_TIM_CTRL 0x00000470
-#define VERT_TIM_CTRL 0x00000474
-#define SRC_COMB_CFG 0x00000478
-#define CHROMA_VBIOFF_CFG 0x0000047C
-#define FIELD_COUNT 0x00000480
-#define MISC_TIM_CTRL 0x00000484
-#define DFE_CTRL1 0x00000488
-#define DFE_CTRL2 0x0000048C
-#define DFE_CTRL3 0x00000490
-#define PLL_CTRL 0x00000494
-#define HTL_CTRL 0x00000498
-#define COMB_CTRL 0x0000049C
-#define CRUSH_CTRL 0x000004A0
-#define SOFT_RST_CTRL 0x000004A4
-#define CX885_VERSION 0x000004B4
-#define VBI_PASS_CTRL 0x000004BC
-
-/* Audio Decoder Registers */
-/* 8051 Configuration */
-#define DL_CTL 0x00000800
-#define STD_DET_STATUS 0x00000804
-#define STD_DET_CTL 0x00000808
-#define DW8051_INT 0x0000080C
-#define GENERAL_CTL 0x00000810
-#define AAGC_CTL 0x00000814
-#define DEMATRIX_CTL 0x000008CC
-#define PATH1_CTL1 0x000008D0
-#define PATH1_VOL_CTL 0x000008D4
-#define PATH1_EQ_CTL 0x000008D8
-#define PATH1_SC_CTL 0x000008DC
-#define PATH2_CTL1 0x000008E0
-#define PATH2_VOL_CTL 0x000008E4
-#define PATH2_EQ_CTL 0x000008E8
-#define PATH2_SC_CTL 0x000008EC
-
-/* Sample Rate Converter */
-#define SRC_CTL 0x000008F0
-#define SRC_LF_COEF 0x000008F4
-#define SRC1_CTL 0x000008F8
-#define SRC2_CTL 0x000008FC
-#define SRC3_CTL 0x00000900
-#define SRC4_CTL 0x00000904
-#define SRC5_CTL 0x00000908
-#define SRC6_CTL 0x0000090C
-#define BAND_OUT_SEL 0x00000910
-#define I2S_N_CTL 0x00000914
-#define I2S_OUT_CTL 0x00000918
-#define AUTOCONFIG_REG 0x000009C4
-
-/* Audio ADC Registers */
-#define DSM_CTRL1 0x00000000
-#define DSM_CTRL2 0x00000001
-#define CHP_EN_CTRL 0x00000002
-#define CHP_CLK_CTRL1 0x00000004
-#define CHP_CLK_CTRL2 0x00000005
-#define BG_REF_CTRL 0x00000006
-#define SD2_SW_CTRL1 0x00000008
-#define SD2_SW_CTRL2 0x00000009
-#define SD2_BIAS_CTRL 0x0000000A
-#define AMP_BIAS_CTRL 0x0000000C
-#define CH_PWR_CTRL1 0x0000000E
-#define FLD_CH_SEL (1 << 3)
-#define CH_PWR_CTRL2 0x0000000F
-#define DSM_STATUS1 0x00000010
-#define DSM_STATUS2 0x00000011
-#define DIG_CTL1 0x00000012
-#define DIG_CTL2 0x00000013
-#define I2S_TX_CFG 0x0000001A
-
-#define DEV_CNTRL2 0x00040000
-
-#define PCI_MSK_IR (1 << 28)
-#define PCI_MSK_AV_CORE (1 << 27)
-#define PCI_MSK_GPIO1 (1 << 24)
-#define PCI_MSK_GPIO0 (1 << 23)
-#define PCI_MSK_APB_DMA (1 << 12)
-#define PCI_MSK_AL_WR (1 << 11)
-#define PCI_MSK_AL_RD (1 << 10)
-#define PCI_MSK_RISC_WR (1 << 9)
-#define PCI_MSK_RISC_RD (1 << 8)
-#define PCI_MSK_AUD_EXT (1 << 4)
-#define PCI_MSK_AUD_INT (1 << 3)
-#define PCI_MSK_VID_C (1 << 2)
-#define PCI_MSK_VID_B (1 << 1)
-#define PCI_MSK_VID_A 1
-#define PCI_INT_MSK 0x00040010
-
-#define PCI_INT_STAT 0x00040014
-#define PCI_INT_MSTAT 0x00040018
-
-#define VID_A_INT_MSK 0x00040020
-#define VID_A_INT_STAT 0x00040024
-#define VID_A_INT_MSTAT 0x00040028
-#define VID_A_INT_SSTAT 0x0004002C
-
-#define VID_B_INT_MSK 0x00040030
-#define VID_B_MSK_BAD_PKT (1 << 20)
-#define VID_B_MSK_VBI_OPC_ERR (1 << 17)
-#define VID_B_MSK_OPC_ERR (1 << 16)
-#define VID_B_MSK_VBI_SYNC (1 << 13)
-#define VID_B_MSK_SYNC (1 << 12)
-#define VID_B_MSK_VBI_OF (1 << 9)
-#define VID_B_MSK_OF (1 << 8)
-#define VID_B_MSK_VBI_RISCI2 (1 << 5)
-#define VID_B_MSK_RISCI2 (1 << 4)
-#define VID_B_MSK_VBI_RISCI1 (1 << 1)
-#define VID_B_MSK_RISCI1 1
-#define VID_B_INT_STAT 0x00040034
-#define VID_B_INT_MSTAT 0x00040038
-#define VID_B_INT_SSTAT 0x0004003C
-
-#define VID_B_MSK_BAD_PKT (1 << 20)
-#define VID_B_MSK_OPC_ERR (1 << 16)
-#define VID_B_MSK_SYNC (1 << 12)
-#define VID_B_MSK_OF (1 << 8)
-#define VID_B_MSK_RISCI2 (1 << 4)
-#define VID_B_MSK_RISCI1 1
-
-#define VID_C_MSK_BAD_PKT (1 << 20)
-#define VID_C_MSK_OPC_ERR (1 << 16)
-#define VID_C_MSK_SYNC (1 << 12)
-#define VID_C_MSK_OF (1 << 8)
-#define VID_C_MSK_RISCI2 (1 << 4)
-#define VID_C_MSK_RISCI1 1
-
-/* A superset for testing purposes */
-#define VID_BC_MSK_BAD_PKT (1 << 20)
-#define VID_BC_MSK_OPC_ERR (1 << 16)
-#define VID_BC_MSK_SYNC (1 << 12)
-#define VID_BC_MSK_OF (1 << 8)
-#define VID_BC_MSK_VBI_RISCI2 (1 << 5)
-#define VID_BC_MSK_RISCI2 (1 << 4)
-#define VID_BC_MSK_VBI_RISCI1 (1 << 1)
-#define VID_BC_MSK_RISCI1 1
-
-#define VID_C_INT_MSK 0x00040040
-#define VID_C_INT_STAT 0x00040044
-#define VID_C_INT_MSTAT 0x00040048
-#define VID_C_INT_SSTAT 0x0004004C
-
-#define AUDIO_INT_INT_MSK 0x00040050
-#define AUDIO_INT_INT_STAT 0x00040054
-#define AUDIO_INT_INT_MSTAT 0x00040058
-#define AUDIO_INT_INT_SSTAT 0x0004005C
-
-#define AUDIO_EXT_INT_MSK 0x00040060
-#define AUDIO_EXT_INT_STAT 0x00040064
-#define AUDIO_EXT_INT_MSTAT 0x00040068
-#define AUDIO_EXT_INT_SSTAT 0x0004006C
-
-#define RDR_CFG0 0x00050000
-#define RDR_CFG1 0x00050004
-#define RDR_CFG2 0x00050008
-#define RDR_RDRCTL1 0x0005030c
-#define RDR_TLCTL0 0x00050318
-
-/* APB DMAC Current Buffer Pointer */
-#define DMA1_PTR1 0x00100000
-#define DMA2_PTR1 0x00100004
-#define DMA3_PTR1 0x00100008
-#define DMA4_PTR1 0x0010000C
-#define DMA5_PTR1 0x00100010
-#define DMA6_PTR1 0x00100014
-#define DMA7_PTR1 0x00100018
-#define DMA8_PTR1 0x0010001C
-
-/* APB DMAC Current Table Pointer */
-#define DMA1_PTR2 0x00100040
-#define DMA2_PTR2 0x00100044
-#define DMA3_PTR2 0x00100048
-#define DMA4_PTR2 0x0010004C
-#define DMA5_PTR2 0x00100050
-#define DMA6_PTR2 0x00100054
-#define DMA7_PTR2 0x00100058
-#define DMA8_PTR2 0x0010005C
-
-/* APB DMAC Buffer Limit */
-#define DMA1_CNT1 0x00100080
-#define DMA2_CNT1 0x00100084
-#define DMA3_CNT1 0x00100088
-#define DMA4_CNT1 0x0010008C
-#define DMA5_CNT1 0x00100090
-#define DMA6_CNT1 0x00100094
-#define DMA7_CNT1 0x00100098
-#define DMA8_CNT1 0x0010009C
-
-/* APB DMAC Table Size */
-#define DMA1_CNT2 0x001000C0
-#define DMA2_CNT2 0x001000C4
-#define DMA3_CNT2 0x001000C8
-#define DMA4_CNT2 0x001000CC
-#define DMA5_CNT2 0x001000D0
-#define DMA6_CNT2 0x001000D4
-#define DMA7_CNT2 0x001000D8
-#define DMA8_CNT2 0x001000DC
-
-/* Timer Counters */
-#define TM_CNT_LDW 0x00110000
-#define TM_CNT_UW 0x00110004
-#define TM_LMT_LDW 0x00110008
-#define TM_LMT_UW 0x0011000C
-
-/* GPIO */
-#define GP0_IO 0x00110010
-#define GPIO_ISM 0x00110014
-#define SOFT_RESET 0x0011001C
-
-/* GPIO (417 Microsoftcontroller) RW Data */
-#define MC417_RWD 0x00110020
-
-/* GPIO (417 Microsoftcontroller) Output Enable, Low Active */
-#define MC417_OEN 0x00110024
-#define MC417_CTL 0x00110028
-#define ALT_PIN_OUT_SEL 0x0011002C
-#define CLK_DELAY 0x00110048
-#define PAD_CTRL 0x0011004C
-
-/* Video A Interface */
-#define VID_A_GPCNT 0x00130020
-#define VBI_A_GPCNT 0x00130024
-#define VID_A_GPCNT_CTL 0x00130030
-#define VBI_A_GPCNT_CTL 0x00130034
-#define VID_A_DMA_CTL 0x00130040
-#define VID_A_VIP_CTRL 0x00130080
-#define VID_A_PIXEL_FRMT 0x00130084
-#define VID_A_VBI_CTRL 0x00130088
-
-/* Video B Interface */
-#define VID_B_DMA 0x00130100
-#define VBI_B_DMA 0x00130108
-#define VID_B_GPCNT 0x00130120
-#define VBI_B_GPCNT 0x00130124
-#define VID_B_GPCNT_CTL 0x00130134
-#define VBI_B_GPCNT_CTL 0x00130138
-#define VID_B_DMA_CTL 0x00130140
-#define VID_B_SRC_SEL 0x00130144
-#define VID_B_LNGTH 0x00130150
-#define VID_B_HW_SOP_CTL 0x00130154
-#define VID_B_GEN_CTL 0x00130158
-#define VID_B_BD_PKT_STATUS 0x0013015C
-#define VID_B_SOP_STATUS 0x00130160
-#define VID_B_FIFO_OVFL_STAT 0x00130164
-#define VID_B_VLD_MISC 0x00130168
-#define VID_B_TS_CLK_EN 0x0013016C
-#define VID_B_VIP_CTRL 0x00130180
-#define VID_B_PIXEL_FRMT 0x00130184
-
-/* Video C Interface */
-#define VID_C_GPCNT 0x00130220
-#define VID_C_GPCNT_CTL 0x00130230
-#define VBI_C_GPCNT_CTL 0x00130234
-#define VID_C_DMA_CTL 0x00130240
-#define VID_C_LNGTH 0x00130250
-#define VID_C_HW_SOP_CTL 0x00130254
-#define VID_C_GEN_CTL 0x00130258
-#define VID_C_BD_PKT_STATUS 0x0013025C
-#define VID_C_SOP_STATUS 0x00130260
-#define VID_C_FIFO_OVFL_STAT 0x00130264
-#define VID_C_VLD_MISC 0x00130268
-#define VID_C_TS_CLK_EN 0x0013026C
-
-/* Internal Audio Interface */
-#define AUD_INT_A_GPCNT 0x00140020
-#define AUD_INT_B_GPCNT 0x00140024
-#define AUD_INT_A_GPCNT_CTL 0x00140030
-#define AUD_INT_B_GPCNT_CTL 0x00140034
-#define AUD_INT_DMA_CTL 0x00140040
-#define AUD_INT_A_LNGTH 0x00140050
-#define AUD_INT_B_LNGTH 0x00140054
-#define AUD_INT_A_MODE 0x00140058
-#define AUD_INT_B_MODE 0x0014005C
-
-/* External Audio Interface */
-#define AUD_EXT_DMA 0x00140100
-#define AUD_EXT_GPCNT 0x00140120
-#define AUD_EXT_GPCNT_CTL 0x00140130
-#define AUD_EXT_DMA_CTL 0x00140140
-#define AUD_EXT_LNGTH 0x00140150
-#define AUD_EXT_A_MODE 0x00140158
-
-/* I2C Bus 1 */
-#define I2C1_ADDR 0x00180000
-#define I2C1_WDATA 0x00180004
-#define I2C1_CTRL 0x00180008
-#define I2C1_RDATA 0x0018000C
-#define I2C1_STAT 0x00180010
-
-/* I2C Bus 2 */
-#define I2C2_ADDR 0x00190000
-#define I2C2_WDATA 0x00190004
-#define I2C2_CTRL 0x00190008
-#define I2C2_RDATA 0x0019000C
-#define I2C2_STAT 0x00190010
-
-/* I2C Bus 3 */
-#define I2C3_ADDR 0x001A0000
-#define I2C3_WDATA 0x001A0004
-#define I2C3_CTRL 0x001A0008
-#define I2C3_RDATA 0x001A000C
-#define I2C3_STAT 0x001A0010
-
-/* UART */
-#define UART_CTL 0x001B0000
-#define UART_BRD 0x001B0004
-#define UART_ISR 0x001B000C
-#define UART_CNT 0x001B0010
-
-#endif /* _CX23885_REG_H_ */
diff --git a/drivers/media/video/cx23885/cx23885-vbi.c b/drivers/media/video/cx23885/cx23885-vbi.c
deleted file mode 100644
index a1154f035bc..00000000000
--- a/drivers/media/video/cx23885/cx23885-vbi.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Driver for the Conexant CX23885 PCIe bridge
- *
- * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-
-#include "cx23885.h"
-
-static unsigned int vbibufs = 4;
-module_param(vbibufs, int, 0644);
-MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32");
-
-static unsigned int vbi_debug;
-module_param(vbi_debug, int, 0644);
-MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]");
-
-#define dprintk(level, fmt, arg...)\
- do { if (vbi_debug >= level)\
- printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
- } while (0)
-
-/* ------------------------------------------------------------------ */
-
-#define VBI_LINE_LENGTH 1440
-#define NTSC_VBI_START_LINE 10 /* line 10 - 21 */
-#define NTSC_VBI_END_LINE 21
-#define NTSC_VBI_LINES (NTSC_VBI_END_LINE - NTSC_VBI_START_LINE + 1)
-
-
-int cx23885_vbi_fmt(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
-
- if (dev->tvnorm & V4L2_STD_525_60) {
- /* ntsc */
- f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
- f->fmt.vbi.sampling_rate = 27000000;
- f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
- f->fmt.vbi.offset = 0;
- f->fmt.vbi.flags = 0;
- f->fmt.vbi.start[0] = 10;
- f->fmt.vbi.count[0] = 17;
- f->fmt.vbi.start[1] = 263 + 10 + 1;
- f->fmt.vbi.count[1] = 17;
- } else if (dev->tvnorm & V4L2_STD_625_50) {
- /* pal */
- f->fmt.vbi.sampling_rate = 35468950;
- f->fmt.vbi.start[0] = 7 - 1;
- f->fmt.vbi.start[1] = 319 - 1;
- }
-
- return 0;
-}
-
-/* We're given the Video Interrupt status register.
- * The cx23885_video_irq() func has already validated
- * the potential error bits, we just need to
- * deal with vbi payload and return indication if
- * we actually processed any payload.
- */
-int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status)
-{
- u32 count;
- int handled = 0;
-
- if (status & VID_BC_MSK_VBI_RISCI1) {
- dprintk(1, "%s() VID_BC_MSK_VBI_RISCI1\n", __func__);
- spin_lock(&dev->slock);
- count = cx_read(VID_A_GPCNT);
- cx23885_video_wakeup(dev, &dev->vbiq, count);
- spin_unlock(&dev->slock);
- handled++;
- }
-
- if (status & VID_BC_MSK_VBI_RISCI2) {
- dprintk(1, "%s() VID_BC_MSK_VBI_RISCI2\n", __func__);
- dprintk(2, "stopper vbi\n");
- spin_lock(&dev->slock);
- cx23885_restart_vbi_queue(dev, &dev->vbiq);
- spin_unlock(&dev->slock);
- handled++;
- }
-
- return handled;
-}
-
-static int cx23885_start_vbi_dma(struct cx23885_dev *dev,
- struct cx23885_dmaqueue *q,
- struct cx23885_buffer *buf)
-{
- dprintk(1, "%s()\n", __func__);
-
- /* setup fifo + format */
- cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02],
- buf->vb.width, buf->risc.dma);
-
- /* reset counter */
- cx_write(VID_A_GPCNT_CTL, 3);
- cx_write(VID_A_VBI_CTRL, 3);
- cx_write(VBI_A_GPCNT_CTL, 3);
- q->count = 1;
-
- /* enable irq */
- cx23885_irq_add_enable(dev, 0x01);
- cx_set(VID_A_INT_MSK, 0x000022);
-
- /* start dma */
- cx_set(DEV_CNTRL2, (1<<5));
- cx_set(VID_A_DMA_CTL, 0x22); /* FIFO and RISC enable */
-
- return 0;
-}
-
-
-int cx23885_restart_vbi_queue(struct cx23885_dev *dev,
- struct cx23885_dmaqueue *q)
-{
- struct cx23885_buffer *buf;
- struct list_head *item;
-
- if (list_empty(&q->active))
- return 0;
-
- buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue);
- dprintk(2, "restart_queue [%p/%d]: restart dma\n",
- buf, buf->vb.i);
- cx23885_start_vbi_dma(dev, q, buf);
- list_for_each(item, &q->active) {
- buf = list_entry(item, struct cx23885_buffer, vb.queue);
- buf->count = q->count++;
- }
- mod_timer(&q->timeout, jiffies + (BUFFER_TIMEOUT / 30));
- return 0;
-}
-
-void cx23885_vbi_timeout(unsigned long data)
-{
- struct cx23885_dev *dev = (struct cx23885_dev *)data;
- struct cx23885_dmaqueue *q = &dev->vbiq;
- struct cx23885_buffer *buf;
- unsigned long flags;
-
- /* Stop the VBI engine */
- cx_clear(VID_A_DMA_CTL, 0x22);
-
- spin_lock_irqsave(&dev->slock, flags);
- while (!list_empty(&q->active)) {
- buf = list_entry(q->active.next, struct cx23885_buffer,
- vb.queue);
- list_del(&buf->vb.queue);
- buf->vb.state = VIDEOBUF_ERROR;
- wake_up(&buf->vb.done);
- printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", dev->name,
- buf, buf->vb.i, (unsigned long)buf->risc.dma);
- }
- cx23885_restart_vbi_queue(dev, q);
- spin_unlock_irqrestore(&dev->slock, flags);
-}
-
-/* ------------------------------------------------------------------ */
-#define VBI_LINE_LENGTH 1440
-#define VBI_LINE_COUNT 17
-
-static int
-vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
-{
- *size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
- if (0 == *count)
- *count = vbibufs;
- if (*count < 2)
- *count = 2;
- if (*count > 32)
- *count = 32;
- return 0;
-}
-
-static int
-vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct cx23885_fh *fh = q->priv_data;
- struct cx23885_dev *dev = fh->dev;
- struct cx23885_buffer *buf = container_of(vb,
- struct cx23885_buffer, vb);
- struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
- unsigned int size;
- int rc;
-
- size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
- if (0 != buf->vb.baddr && buf->vb.bsize < size)
- return -EINVAL;
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- buf->vb.width = VBI_LINE_LENGTH;
- buf->vb.height = VBI_LINE_COUNT;
- buf->vb.size = size;
- buf->vb.field = V4L2_FIELD_SEQ_TB;
-
- rc = videobuf_iolock(q, &buf->vb, NULL);
- if (0 != rc)
- goto fail;
- cx23885_risc_vbibuffer(dev->pci, &buf->risc,
- dma->sglist,
- 0, buf->vb.width * buf->vb.height,
- buf->vb.width, 0,
- buf->vb.height);
- }
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
- fail:
- cx23885_free_buffer(q, buf);
- return rc;
-}
-
-static void
-vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx23885_buffer *buf =
- container_of(vb, struct cx23885_buffer, vb);
- struct cx23885_buffer *prev;
- struct cx23885_fh *fh = vq->priv_data;
- struct cx23885_dev *dev = fh->dev;
- struct cx23885_dmaqueue *q = &dev->vbiq;
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx23885_start_vbi_dma(dev, q, buf);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + (BUFFER_TIMEOUT / 30));
- dprintk(2, "[%p/%d] vbi_queue - first active\n",
- buf, buf->vb.i);
-
- } else {
- prev = list_entry(q->active.prev, struct cx23885_buffer,
- vb.queue);
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63-32 */
- dprintk(2, "[%p/%d] buffer_queue - append to active\n",
- buf, buf->vb.i);
- }
-}
-
-static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct cx23885_buffer *buf =
- container_of(vb, struct cx23885_buffer, vb);
-
- cx23885_free_buffer(q, buf);
-}
-
-struct videobuf_queue_ops cx23885_vbi_qops = {
- .buf_setup = vbi_setup,
- .buf_prepare = vbi_prepare,
- .buf_queue = vbi_queue,
- .buf_release = vbi_release,
-};
-
-/* ------------------------------------------------------------------ */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
deleted file mode 100644
index 22f8e7fbd66..00000000000
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ /dev/null
@@ -1,1926 +0,0 @@
-/*
- * Driver for the Conexant CX23885 PCIe bridge
- *
- * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kmod.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/kthread.h>
-#include <asm/div64.h>
-
-#include "cx23885.h"
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include "cx23885-ioctl.h"
-#include "tuner-xc2028.h"
-
-#include <media/cx25840.h>
-
-MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
-MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
-MODULE_LICENSE("GPL");
-
-/* ------------------------------------------------------------------ */
-
-static unsigned int video_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET };
-static unsigned int vbi_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET };
-static unsigned int radio_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET };
-
-module_param_array(video_nr, int, NULL, 0444);
-module_param_array(vbi_nr, int, NULL, 0444);
-module_param_array(radio_nr, int, NULL, 0444);
-
-MODULE_PARM_DESC(video_nr, "video device numbers");
-MODULE_PARM_DESC(vbi_nr, "vbi device numbers");
-MODULE_PARM_DESC(radio_nr, "radio device numbers");
-
-static unsigned int video_debug;
-module_param(video_debug, int, 0644);
-MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
-
-static unsigned int irq_debug;
-module_param(irq_debug, int, 0644);
-MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]");
-
-static unsigned int vid_limit = 16;
-module_param(vid_limit, int, 0644);
-MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
-
-#define dprintk(level, fmt, arg...)\
- do { if (video_debug >= level)\
- printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\
- } while (0)
-
-/* ------------------------------------------------------------------- */
-/* static data */
-
-#define FORMAT_FLAGS_PACKED 0x01
-#if 0
-static struct cx23885_fmt formats[] = {
- {
- .name = "8 bpp, gray",
- .fourcc = V4L2_PIX_FMT_GREY,
- .depth = 8,
- .flags = FORMAT_FLAGS_PACKED,
- }, {
- .name = "15 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_RGB555,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- }, {
- .name = "15 bpp RGB, be",
- .fourcc = V4L2_PIX_FMT_RGB555X,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- }, {
- .name = "16 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_RGB565,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- }, {
- .name = "16 bpp RGB, be",
- .fourcc = V4L2_PIX_FMT_RGB565X,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- }, {
- .name = "24 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_BGR24,
- .depth = 24,
- .flags = FORMAT_FLAGS_PACKED,
- }, {
- .name = "32 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_BGR32,
- .depth = 32,
- .flags = FORMAT_FLAGS_PACKED,
- }, {
- .name = "32 bpp RGB, be",
- .fourcc = V4L2_PIX_FMT_RGB32,
- .depth = 32,
- .flags = FORMAT_FLAGS_PACKED,
- }, {
- .name = "4:2:2, packed, YUYV",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- }, {
- .name = "4:2:2, packed, UYVY",
- .fourcc = V4L2_PIX_FMT_UYVY,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- },
-};
-#else
-static struct cx23885_fmt formats[] = {
- {
-#if 0
- .name = "4:2:2, packed, UYVY",
- .fourcc = V4L2_PIX_FMT_UYVY,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- }, {
-#endif
- .name = "4:2:2, packed, YUYV",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- }
-};
-#endif
-
-static struct cx23885_fmt *format_by_fourcc(unsigned int fourcc)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(formats); i++)
- if (formats[i].fourcc == fourcc)
- return formats+i;
-
- printk(KERN_ERR "%s(%c%c%c%c) NOT FOUND\n", __func__,
- (fourcc & 0xff),
- ((fourcc >> 8) & 0xff),
- ((fourcc >> 16) & 0xff),
- ((fourcc >> 24) & 0xff)
- );
- return NULL;
-}
-
-/* ------------------------------------------------------------------- */
-
-static const struct v4l2_queryctrl no_ctl = {
- .name = "42",
- .flags = V4L2_CTRL_FLAG_DISABLED,
-};
-
-static struct cx23885_ctrl cx23885_ctls[] = {
- /* --- video --- */
- {
- .v = {
- .id = V4L2_CID_BRIGHTNESS,
- .name = "Brightness",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0x7f,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
- .off = 128,
- .reg = LUMA_CTRL,
- .mask = 0x00ff,
- .shift = 0,
- }, {
- .v = {
- .id = V4L2_CID_CONTRAST,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 0x7f,
- .step = 1,
- .default_value = 0x3f,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
- .off = 0,
- .reg = LUMA_CTRL,
- .mask = 0xff00,
- .shift = 8,
- }, {
- .v = {
- .id = V4L2_CID_HUE,
- .name = "Hue",
- .minimum = -127,
- .maximum = 128,
- .step = 1,
- .default_value = 0x0,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
- .off = 128,
- .reg = CHROMA_CTRL,
- .mask = 0xff0000,
- .shift = 16,
- }, {
- /* strictly, this only describes only U saturation.
- * V saturation is handled specially through code.
- */
- .v = {
- .id = V4L2_CID_SATURATION,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 0x7f,
- .step = 1,
- .default_value = 0x3f,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
- .off = 0,
- .reg = CHROMA_CTRL,
- .mask = 0x00ff,
- .shift = 0,
- }, {
- /* --- audio --- */
- .v = {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },
- .reg = PATH1_CTL1,
- .mask = (0x1f << 24),
- .shift = 24,
- }, {
- .v = {
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 65535 / 100,
- .default_value = 65535,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
- .reg = PATH1_VOL_CTL,
- .mask = 0xff,
- .shift = 0,
- }
-};
-static const int CX23885_CTLS = ARRAY_SIZE(cx23885_ctls);
-
-/* Must be sorted from low to high control ID! */
-static const u32 cx23885_user_ctrls[] = {
- V4L2_CID_USER_CLASS,
- V4L2_CID_BRIGHTNESS,
- V4L2_CID_CONTRAST,
- V4L2_CID_SATURATION,
- V4L2_CID_HUE,
- V4L2_CID_AUDIO_VOLUME,
- V4L2_CID_AUDIO_MUTE,
- 0
-};
-
-static const u32 *ctrl_classes[] = {
- cx23885_user_ctrls,
- NULL
-};
-
-void cx23885_video_wakeup(struct cx23885_dev *dev,
- struct cx23885_dmaqueue *q, u32 count)
-{
- struct cx23885_buffer *buf;
- int bc;
-
- for (bc = 0;; bc++) {
- if (list_empty(&q->active))
- break;
- buf = list_entry(q->active.next,
- struct cx23885_buffer, vb.queue);
-
- /* count comes from the hw and is is 16bit wide --
- * this trick handles wrap-arounds correctly for
- * up to 32767 buffers in flight... */
- if ((s16) (count - buf->count) < 0)
- break;
-
- do_gettimeofday(&buf->vb.ts);
- dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i,
- count, buf->count);
- buf->vb.state = VIDEOBUF_DONE;
- list_del(&buf->vb.queue);
- wake_up(&buf->vb.done);
- }
- if (list_empty(&q->active))
- del_timer(&q->timeout);
- else
- mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- if (bc != 1)
- printk(KERN_ERR "%s: %d buffers handled (should be 1)\n",
- __func__, bc);
-}
-
-int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
-{
- dprintk(1, "%s(norm = 0x%08x) name: [%s]\n",
- __func__,
- (unsigned int)norm,
- v4l2_norm_to_name(norm));
-
- dev->tvnorm = norm;
-
- call_all(dev, core, s_std, norm);
-
- return 0;
-}
-
-static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev,
- struct pci_dev *pci,
- struct video_device *template,
- char *type)
-{
- struct video_device *vfd;
- dprintk(1, "%s()\n", __func__);
-
- vfd = video_device_alloc();
- if (NULL == vfd)
- return NULL;
- *vfd = *template;
- vfd->v4l2_dev = &dev->v4l2_dev;
- vfd->release = video_device_release;
- snprintf(vfd->name, sizeof(vfd->name), "%s (%s)",
- cx23885_boards[dev->board].name, type);
- video_set_drvdata(vfd, dev);
- return vfd;
-}
-
-static int cx23885_ctrl_query(struct v4l2_queryctrl *qctrl)
-{
- int i;
-
- if (qctrl->id < V4L2_CID_BASE ||
- qctrl->id >= V4L2_CID_LASTP1)
- return -EINVAL;
- for (i = 0; i < CX23885_CTLS; i++)
- if (cx23885_ctls[i].v.id == qctrl->id)
- break;
- if (i == CX23885_CTLS) {
- *qctrl = no_ctl;
- return 0;
- }
- *qctrl = cx23885_ctls[i].v;
- return 0;
-}
-
-/* ------------------------------------------------------------------- */
-/* resource management */
-
-static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh,
- unsigned int bit)
-{
- dprintk(1, "%s()\n", __func__);
- if (fh->resources & bit)
- /* have it already allocated */
- return 1;
-
- /* is it free? */
- mutex_lock(&dev->lock);
- if (dev->resources & bit) {
- /* no, someone else uses it */
- mutex_unlock(&dev->lock);
- return 0;
- }
- /* it's free, grab it */
- fh->resources |= bit;
- dev->resources |= bit;
- dprintk(1, "res: get %d\n", bit);
- mutex_unlock(&dev->lock);
- return 1;
-}
-
-static int res_check(struct cx23885_fh *fh, unsigned int bit)
-{
- return fh->resources & bit;
-}
-
-static int res_locked(struct cx23885_dev *dev, unsigned int bit)
-{
- return dev->resources & bit;
-}
-
-static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh,
- unsigned int bits)
-{
- BUG_ON((fh->resources & bits) != bits);
- dprintk(1, "%s()\n", __func__);
-
- mutex_lock(&dev->lock);
- fh->resources &= ~bits;
- dev->resources &= ~bits;
- dprintk(1, "res: put %d\n", bits);
- mutex_unlock(&dev->lock);
-}
-
-static int cx23885_flatiron_write(struct cx23885_dev *dev, u8 reg, u8 data)
-{
- /* 8 bit registers, 8 bit values */
- u8 buf[] = { reg, data };
-
- struct i2c_msg msg = { .addr = 0x98 >> 1,
- .flags = 0, .buf = buf, .len = 2 };
-
- return i2c_transfer(&dev->i2c_bus[2].i2c_adap, &msg, 1);
-}
-
-static u8 cx23885_flatiron_read(struct cx23885_dev *dev, u8 reg)
-{
- /* 8 bit registers, 8 bit values */
- int ret;
- u8 b0[] = { reg };
- u8 b1[] = { 0 };
-
- struct i2c_msg msg[] = {
- { .addr = 0x98 >> 1, .flags = 0, .buf = b0, .len = 1 },
- { .addr = 0x98 >> 1, .flags = I2C_M_RD, .buf = b1, .len = 1 }
- };
-
- ret = i2c_transfer(&dev->i2c_bus[2].i2c_adap, &msg[0], 2);
- if (ret != 2)
- printk(KERN_ERR "%s() error\n", __func__);
-
- return b1[0];
-}
-
-static void cx23885_flatiron_dump(struct cx23885_dev *dev)
-{
- int i;
- dprintk(1, "Flatiron dump\n");
- for (i = 0; i < 0x24; i++) {
- dprintk(1, "FI[%02x] = %02x\n", i,
- cx23885_flatiron_read(dev, i));
- }
-}
-
-static int cx23885_flatiron_mux(struct cx23885_dev *dev, int input)
-{
- u8 val;
- dprintk(1, "%s(input = %d)\n", __func__, input);
-
- if (input == 1)
- val = cx23885_flatiron_read(dev, CH_PWR_CTRL1) & ~FLD_CH_SEL;
- else if (input == 2)
- val = cx23885_flatiron_read(dev, CH_PWR_CTRL1) | FLD_CH_SEL;
- else
- return -EINVAL;
-
- val |= 0x20; /* Enable clock to delta-sigma and dec filter */
-
- cx23885_flatiron_write(dev, CH_PWR_CTRL1, val);
-
- /* Wake up */
- cx23885_flatiron_write(dev, CH_PWR_CTRL2, 0);
-
- if (video_debug)
- cx23885_flatiron_dump(dev);
-
- return 0;
-}
-
-static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
-{
- dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
- __func__,
- input, INPUT(input)->vmux,
- INPUT(input)->gpio0, INPUT(input)->gpio1,
- INPUT(input)->gpio2, INPUT(input)->gpio3);
- dev->input = input;
-
- if (dev->board == CX23885_BOARD_MYGICA_X8506 ||
- dev->board == CX23885_BOARD_MAGICPRO_PROHDTVE2 ||
- dev->board == CX23885_BOARD_MYGICA_X8507) {
- /* Select Analog TV */
- if (INPUT(input)->type == CX23885_VMUX_TELEVISION)
- cx23885_gpio_clear(dev, GPIO_0);
- }
-
- /* Tell the internal A/V decoder */
- v4l2_subdev_call(dev->sd_cx25840, video, s_routing,
- INPUT(input)->vmux, 0, 0);
-
- if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1800) ||
- (dev->board == CX23885_BOARD_MPX885) ||
- (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1250) ||
- (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) ||
- (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) ||
- (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850)) {
- /* Configure audio routing */
- v4l2_subdev_call(dev->sd_cx25840, audio, s_routing,
- INPUT(input)->amux, 0, 0);
-
- if (INPUT(input)->amux == CX25840_AUDIO7)
- cx23885_flatiron_mux(dev, 1);
- else if (INPUT(input)->amux == CX25840_AUDIO6)
- cx23885_flatiron_mux(dev, 2);
- }
-
- return 0;
-}
-
-static int cx23885_audio_mux(struct cx23885_dev *dev, unsigned int input)
-{
- dprintk(1, "%s(input=%d)\n", __func__, input);
-
- /* The baseband video core of the cx23885 has two audio inputs.
- * LR1 and LR2. In almost every single case so far only HVR1xxx
- * cards we've only ever supported LR1. Time to support LR2,
- * which is available via the optional white breakout header on
- * the board.
- * We'll use a could of existing enums in the card struct to allow
- * devs to specify which baseband input they need, or just default
- * to what we've always used.
- */
- if (INPUT(input)->amux == CX25840_AUDIO7)
- cx23885_flatiron_mux(dev, 1);
- else if (INPUT(input)->amux == CX25840_AUDIO6)
- cx23885_flatiron_mux(dev, 2);
- else {
- /* Not specifically defined, assume the default. */
- cx23885_flatiron_mux(dev, 1);
- }
-
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-static int cx23885_start_video_dma(struct cx23885_dev *dev,
- struct cx23885_dmaqueue *q,
- struct cx23885_buffer *buf)
-{
- dprintk(1, "%s()\n", __func__);
-
- /* Stop the dma/fifo before we tamper with it's risc programs */
- cx_clear(VID_A_DMA_CTL, 0x11);
-
- /* setup fifo + format */
- cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01],
- buf->bpl, buf->risc.dma);
-
- /* reset counter */
- cx_write(VID_A_GPCNT_CTL, 3);
- q->count = 1;
-
- /* enable irq */
- cx23885_irq_add_enable(dev, 0x01);
- cx_set(VID_A_INT_MSK, 0x000011);
-
- /* start dma */
- cx_set(DEV_CNTRL2, (1<<5));
- cx_set(VID_A_DMA_CTL, 0x11); /* FIFO and RISC enable */
-
- return 0;
-}
-
-
-static int cx23885_restart_video_queue(struct cx23885_dev *dev,
- struct cx23885_dmaqueue *q)
-{
- struct cx23885_buffer *buf, *prev;
- struct list_head *item;
- dprintk(1, "%s()\n", __func__);
-
- if (!list_empty(&q->active)) {
- buf = list_entry(q->active.next, struct cx23885_buffer,
- vb.queue);
- dprintk(2, "restart_queue [%p/%d]: restart dma\n",
- buf, buf->vb.i);
- cx23885_start_video_dma(dev, q, buf);
- list_for_each(item, &q->active) {
- buf = list_entry(item, struct cx23885_buffer,
- vb.queue);
- buf->count = q->count++;
- }
- mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- return 0;
- }
-
- prev = NULL;
- for (;;) {
- if (list_empty(&q->queued))
- return 0;
- buf = list_entry(q->queued.next, struct cx23885_buffer,
- vb.queue);
- if (NULL == prev) {
- list_move_tail(&buf->vb.queue, &q->active);
- cx23885_start_video_dma(dev, q, buf);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- dprintk(2, "[%p/%d] restart_queue - first active\n",
- buf, buf->vb.i);
-
- } else if (prev->vb.width == buf->vb.width &&
- prev->vb.height == buf->vb.height &&
- prev->fmt == buf->fmt) {
- list_move_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */
- dprintk(2, "[%p/%d] restart_queue - move to active\n",
- buf, buf->vb.i);
- } else {
- return 0;
- }
- prev = buf;
- }
-}
-
-static int buffer_setup(struct videobuf_queue *q, unsigned int *count,
- unsigned int *size)
-{
- struct cx23885_fh *fh = q->priv_data;
-
- *size = fh->fmt->depth*fh->width*fh->height >> 3;
- if (0 == *count)
- *count = 32;
- if (*size * *count > vid_limit * 1024 * 1024)
- *count = (vid_limit * 1024 * 1024) / *size;
- return 0;
-}
-
-static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct cx23885_fh *fh = q->priv_data;
- struct cx23885_dev *dev = fh->dev;
- struct cx23885_buffer *buf =
- container_of(vb, struct cx23885_buffer, vb);
- int rc, init_buffer = 0;
- u32 line0_offset, line1_offset;
- struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
- int field_tff;
-
- BUG_ON(NULL == fh->fmt);
- if (fh->width < 48 || fh->width > norm_maxw(dev->tvnorm) ||
- fh->height < 32 || fh->height > norm_maxh(dev->tvnorm))
- return -EINVAL;
- buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
- if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
- return -EINVAL;
-
- if (buf->fmt != fh->fmt ||
- buf->vb.width != fh->width ||
- buf->vb.height != fh->height ||
- buf->vb.field != field) {
- buf->fmt = fh->fmt;
- buf->vb.width = fh->width;
- buf->vb.height = fh->height;
- buf->vb.field = field;
- init_buffer = 1;
- }
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- init_buffer = 1;
- rc = videobuf_iolock(q, &buf->vb, NULL);
- if (0 != rc)
- goto fail;
- }
-
- if (init_buffer) {
- buf->bpl = buf->vb.width * buf->fmt->depth >> 3;
- switch (buf->vb.field) {
- case V4L2_FIELD_TOP:
- cx23885_risc_buffer(dev->pci, &buf->risc,
- dma->sglist, 0, UNSET,
- buf->bpl, 0, buf->vb.height);
- break;
- case V4L2_FIELD_BOTTOM:
- cx23885_risc_buffer(dev->pci, &buf->risc,
- dma->sglist, UNSET, 0,
- buf->bpl, 0, buf->vb.height);
- break;
- case V4L2_FIELD_INTERLACED:
- if (dev->tvnorm & V4L2_STD_NTSC)
- /* NTSC or */
- field_tff = 1;
- else
- field_tff = 0;
-
- if (cx23885_boards[dev->board].force_bff)
- /* PAL / SECAM OR 888 in NTSC MODE */
- field_tff = 0;
-
- if (field_tff) {
- /* cx25840 transmits NTSC bottom field first */
- dprintk(1, "%s() Creating TFF/NTSC risc\n",
- __func__);
- line0_offset = buf->bpl;
- line1_offset = 0;
- } else {
- /* All other formats are top field first */
- dprintk(1, "%s() Creating BFF/PAL/SECAM risc\n",
- __func__);
- line0_offset = 0;
- line1_offset = buf->bpl;
- }
- cx23885_risc_buffer(dev->pci, &buf->risc,
- dma->sglist, line0_offset,
- line1_offset,
- buf->bpl, buf->bpl,
- buf->vb.height >> 1);
- break;
- case V4L2_FIELD_SEQ_TB:
- cx23885_risc_buffer(dev->pci, &buf->risc,
- dma->sglist,
- 0, buf->bpl * (buf->vb.height >> 1),
- buf->bpl, 0,
- buf->vb.height >> 1);
- break;
- case V4L2_FIELD_SEQ_BT:
- cx23885_risc_buffer(dev->pci, &buf->risc,
- dma->sglist,
- buf->bpl * (buf->vb.height >> 1), 0,
- buf->bpl, 0,
- buf->vb.height >> 1);
- break;
- default:
- BUG();
- }
- }
- dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
- buf, buf->vb.i,
- fh->width, fh->height, fh->fmt->depth, fh->fmt->name,
- (unsigned long)buf->risc.dma);
-
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
- fail:
- cx23885_free_buffer(q, buf);
- return rc;
-}
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx23885_buffer *buf = container_of(vb,
- struct cx23885_buffer, vb);
- struct cx23885_buffer *prev;
- struct cx23885_fh *fh = vq->priv_data;
- struct cx23885_dev *dev = fh->dev;
- struct cx23885_dmaqueue *q = &dev->vidq;
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n",
- buf, buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx23885_start_video_dma(dev, q, buf);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- dprintk(2, "[%p/%d] buffer_queue - first active\n",
- buf, buf->vb.i);
-
- } else {
- prev = list_entry(q->active.prev, struct cx23885_buffer,
- vb.queue);
- if (prev->vb.width == buf->vb.width &&
- prev->vb.height == buf->vb.height &&
- prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(2, "[%p/%d] buffer_queue - append to active\n",
- buf, buf->vb.i);
-
- } else {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n",
- buf, buf->vb.i);
- }
- }
-}
-
-static void buffer_release(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- struct cx23885_buffer *buf = container_of(vb,
- struct cx23885_buffer, vb);
-
- cx23885_free_buffer(q, buf);
-}
-
-static struct videobuf_queue_ops cx23885_video_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-static struct videobuf_queue *get_queue(struct cx23885_fh *fh)
-{
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- return &fh->vidq;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- return &fh->vbiq;
- default:
- BUG();
- return NULL;
- }
-}
-
-static int get_resource(struct cx23885_fh *fh)
-{
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- return RESOURCE_VIDEO;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- return RESOURCE_VBI;
- default:
- BUG();
- return 0;
- }
-}
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx23885_dev *dev = video_drvdata(file);
- struct cx23885_fh *fh;
- enum v4l2_buf_type type = 0;
- int radio = 0;
-
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- case VFL_TYPE_VBI:
- type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- case VFL_TYPE_RADIO:
- radio = 1;
- break;
- }
-
- dprintk(1, "open dev=%s radio=%d type=%s\n",
- video_device_node_name(vdev), radio, v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- file->private_data = fh;
- fh->dev = dev;
- fh->radio = radio;
- fh->type = type;
- fh->width = 320;
- fh->height = 240;
- fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
-
- videobuf_queue_sg_init(&fh->vidq, &cx23885_video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx23885_buffer),
- fh, NULL);
-
- videobuf_queue_sg_init(&fh->vbiq, &cx23885_vbi_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VBI_CAPTURE,
- V4L2_FIELD_SEQ_TB,
- sizeof(struct cx23885_buffer),
- fh, NULL);
-
-
- dprintk(1, "post videobuf_queue_init()\n");
-
- return 0;
-}
-
-static ssize_t video_read(struct file *file, char __user *data,
- size_t count, loff_t *ppos)
-{
- struct cx23885_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (res_locked(fh->dev, RESOURCE_VIDEO))
- return -EBUSY;
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (!res_get(fh->dev, fh, RESOURCE_VBI))
- return -EBUSY;
- return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1,
- file->f_flags & O_NONBLOCK);
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int video_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_buffer *buf;
- unsigned int rc = POLLERR;
-
- if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
- if (!res_get(fh->dev, fh, RESOURCE_VBI))
- return POLLERR;
- return videobuf_poll_stream(file, &fh->vbiq, wait);
- }
-
- mutex_lock(&fh->vidq.vb_lock);
- if (res_check(fh, RESOURCE_VIDEO)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- goto done;
- buf = list_entry(fh->vidq.stream.next,
- struct cx23885_buffer, vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx23885_buffer *)fh->vidq.read_buf;
- if (NULL == buf)
- goto done;
- }
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE ||
- buf->vb.state == VIDEOBUF_ERROR)
- rc = POLLIN|POLLRDNORM;
- else
- rc = 0;
-done:
- mutex_unlock(&fh->vidq.vb_lock);
- return rc;
-}
-
-static int video_release(struct file *file)
-{
- struct cx23885_fh *fh = file->private_data;
- struct cx23885_dev *dev = fh->dev;
-
- /* turn off overlay */
- if (res_check(fh, RESOURCE_OVERLAY)) {
- /* FIXME */
- res_free(dev, fh, RESOURCE_OVERLAY);
- }
-
- /* stop video capture */
- if (res_check(fh, RESOURCE_VIDEO)) {
- videobuf_queue_cancel(&fh->vidq);
- res_free(dev, fh, RESOURCE_VIDEO);
- }
- if (fh->vidq.read_buf) {
- buffer_release(&fh->vidq, fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- /* stop vbi capture */
- if (res_check(fh, RESOURCE_VBI)) {
- if (fh->vbiq.streaming)
- videobuf_streamoff(&fh->vbiq);
- if (fh->vbiq.reading)
- videobuf_read_stop(&fh->vbiq);
- res_free(dev, fh, RESOURCE_VBI);
- }
-
- videobuf_mmap_free(&fh->vidq);
- videobuf_mmap_free(&fh->vbiq);
-
- file->private_data = NULL;
- kfree(fh);
-
- /* We are not putting the tuner to sleep here on exit, because
- * we want to use the mpeg encoder in another session to capture
- * tuner video. Closing this will result in no video to the encoder.
- */
-
- return 0;
-}
-
-static int video_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct cx23885_fh *fh = file->private_data;
-
- return videobuf_mmap_mapper(get_queue(fh), vma);
-}
-
-/* ------------------------------------------------------------------ */
-/* VIDEO CTRL IOCTLS */
-
-int cx23885_get_control(struct cx23885_dev *dev,
- struct v4l2_control *ctl)
-{
- dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__);
- call_all(dev, core, g_ctrl, ctl);
- return 0;
-}
-
-int cx23885_set_control(struct cx23885_dev *dev,
- struct v4l2_control *ctl)
-{
- dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)\n", __func__);
- call_all(dev, core, s_ctrl, ctl);
-
- return 0;
-}
-
-static void init_controls(struct cx23885_dev *dev)
-{
- struct v4l2_control ctrl;
- int i;
-
- for (i = 0; i < CX23885_CTLS; i++) {
- ctrl.id = cx23885_ctls[i].v.id;
- ctrl.value = cx23885_ctls[i].v.default_value;
-
- cx23885_set_control(dev, &ctrl);
- }
-}
-
-/* ------------------------------------------------------------------ */
-/* VIDEO IOCTLS */
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx23885_fh *fh = priv;
-
- f->fmt.pix.width = fh->width;
- f->fmt.pix.height = fh->height;
- f->fmt.pix.field = fh->vidq.field;
- f->fmt.pix.pixelformat = fh->fmt->fourcc;
- f->fmt.pix.bytesperline =
- (f->fmt.pix.width * fh->fmt->depth) >> 3;
- f->fmt.pix.sizeimage =
- f->fmt.pix.height * f->fmt.pix.bytesperline;
-
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
- struct cx23885_fmt *fmt;
- enum v4l2_field field;
- unsigned int maxw, maxh;
-
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- if (NULL == fmt)
- return -EINVAL;
-
- field = f->fmt.pix.field;
- maxw = norm_maxw(dev->tvnorm);
- maxh = norm_maxh(dev->tvnorm);
-
- if (V4L2_FIELD_ANY == field) {
- field = (f->fmt.pix.height > maxh/2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_BOTTOM;
- }
-
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- break;
- default:
- return -EINVAL;
- }
-
- f->fmt.pix.field = field;
- v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,
- &f->fmt.pix.height, 32, maxh, 0, 0);
- f->fmt.pix.bytesperline =
- (f->fmt.pix.width * fmt->depth) >> 3;
- f->fmt.pix.sizeimage =
- f->fmt.pix.height * f->fmt.pix.bytesperline;
-
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
- struct v4l2_mbus_framefmt mbus_fmt;
- int err;
-
- dprintk(2, "%s()\n", __func__);
- err = vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (0 != err)
- return err;
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->width = f->fmt.pix.width;
- fh->height = f->fmt.pix.height;
- fh->vidq.field = f->fmt.pix.field;
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__,
- fh->width, fh->height, fh->vidq.field);
- v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
- call_all(dev, video, s_mbus_fmt, &mbus_fmt);
- v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
- return 0;
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
- strcpy(cap->driver, "cx23885");
- strlcpy(cap->card, cx23885_boards[dev->board].name,
- sizeof(cap->card));
- sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
- cap->capabilities =
- V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING |
- V4L2_CAP_VBI_CAPTURE;
- if (UNSET != dev->tuner_type)
- cap->capabilities |= V4L2_CAP_TUNER;
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (unlikely(f->index >= ARRAY_SIZE(formats)))
- return -EINVAL;
-
- strlcpy(f->description, formats[f->index].name,
- sizeof(f->description));
- f->pixelformat = formats[f->index].fourcc;
-
- return 0;
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct cx23885_fh *fh = priv;
- return videobuf_reqbufs(get_queue(fh), p);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct cx23885_fh *fh = priv;
- return videobuf_querybuf(get_queue(fh), p);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct cx23885_fh *fh = priv;
- return videobuf_qbuf(get_queue(fh), p);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct cx23885_fh *fh = priv;
- return videobuf_dqbuf(get_queue(fh), p,
- file->f_flags & O_NONBLOCK);
-}
-
-static int vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type i)
-{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
- dprintk(1, "%s()\n", __func__);
-
- if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
- if (unlikely(i != fh->type))
- return -EINVAL;
-
- if (unlikely(!res_get(dev, fh, get_resource(fh))))
- return -EBUSY;
-
- /* Don't start VBI streaming unless vida streaming
- * has already started.
- */
- if ((fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) &&
- ((cx_read(VID_A_DMA_CTL) & 0x11) == 0))
- return -EINVAL;
-
- return videobuf_streamon(get_queue(fh));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
- int err, res;
- dprintk(1, "%s()\n", __func__);
-
- if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- res = get_resource(fh);
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- res_free(dev, fh, res);
- return 0;
-}
-
-static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
- dprintk(1, "%s()\n", __func__);
-
- call_all(dev, core, g_std, id);
-
- return 0;
-}
-
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
- dprintk(1, "%s()\n", __func__);
-
- mutex_lock(&dev->lock);
- cx23885_set_tvnorm(dev, *tvnorms);
- mutex_unlock(&dev->lock);
-
- return 0;
-}
-
-int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
-{
- static const char *iname[] = {
- [CX23885_VMUX_COMPOSITE1] = "Composite1",
- [CX23885_VMUX_COMPOSITE2] = "Composite2",
- [CX23885_VMUX_COMPOSITE3] = "Composite3",
- [CX23885_VMUX_COMPOSITE4] = "Composite4",
- [CX23885_VMUX_SVIDEO] = "S-Video",
- [CX23885_VMUX_COMPONENT] = "Component",
- [CX23885_VMUX_TELEVISION] = "Television",
- [CX23885_VMUX_CABLE] = "Cable TV",
- [CX23885_VMUX_DVB] = "DVB",
- [CX23885_VMUX_DEBUG] = "for debug only",
- };
- unsigned int n;
- dprintk(1, "%s()\n", __func__);
-
- n = i->index;
- if (n >= MAX_CX23885_INPUT)
- return -EINVAL;
-
- if (0 == INPUT(n)->type)
- return -EINVAL;
-
- i->index = n;
- i->type = V4L2_INPUT_TYPE_CAMERA;
- strcpy(i->name, iname[INPUT(n)->type]);
- if ((CX23885_VMUX_TELEVISION == INPUT(n)->type) ||
- (CX23885_VMUX_CABLE == INPUT(n)->type)) {
- i->type = V4L2_INPUT_TYPE_TUNER;
- i->std = CX23885_NORMS;
- }
-
- /* Two selectable audio inputs for non-tv inputs */
- if (INPUT(n)->type != CX23885_VMUX_TELEVISION)
- i->audioset = 0x3;
-
- if (dev->input == n) {
- /* enum'd input matches our configured input.
- * Ask the video decoder to process the call
- * and give it an oppertunity to update the
- * status field.
- */
- call_all(dev, video, g_input_status, &i->status);
- }
-
- return 0;
-}
-
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
- dprintk(1, "%s()\n", __func__);
- return cx23885_enum_input(dev, i);
-}
-
-int cx23885_get_input(struct file *file, void *priv, unsigned int *i)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
- *i = dev->input;
- dprintk(1, "%s() returns %d\n", __func__, *i);
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- return cx23885_get_input(file, priv, i);
-}
-
-int cx23885_set_input(struct file *file, void *priv, unsigned int i)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
- dprintk(1, "%s(%d)\n", __func__, i);
-
- if (i >= MAX_CX23885_INPUT) {
- dprintk(1, "%s() -EINVAL\n", __func__);
- return -EINVAL;
- }
-
- if (INPUT(i)->type == 0)
- return -EINVAL;
-
- mutex_lock(&dev->lock);
- cx23885_video_mux(dev, i);
-
- /* By default establish the default audio input for the card also */
- /* Caller is free to use VIDIOC_S_AUDIO to override afterwards */
- cx23885_audio_mux(dev, i);
- mutex_unlock(&dev->lock);
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- return cx23885_set_input(file, priv, i);
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
-
- printk(KERN_INFO
- "%s/0: ============ START LOG STATUS ============\n",
- dev->name);
- call_all(dev, core, log_status);
- printk(KERN_INFO
- "%s/0: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int cx23885_query_audinput(struct file *file, void *priv,
- struct v4l2_audio *i)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
- static const char *iname[] = {
- [0] = "Baseband L/R 1",
- [1] = "Baseband L/R 2",
- };
- unsigned int n;
- dprintk(1, "%s()\n", __func__);
-
- n = i->index;
- if (n >= 2)
- return -EINVAL;
-
- memset(i, 0, sizeof(*i));
- i->index = n;
- strcpy(i->name, iname[n]);
- i->capability = V4L2_AUDCAP_STEREO;
- i->mode = V4L2_AUDMODE_AVL;
- return 0;
-
-}
-
-static int vidioc_enum_audinput(struct file *file, void *priv,
- struct v4l2_audio *i)
-{
- return cx23885_query_audinput(file, priv, i);
-}
-
-static int vidioc_g_audinput(struct file *file, void *priv,
- struct v4l2_audio *i)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
- i->index = dev->audinput;
- dprintk(1, "%s(input=%d)\n", __func__, i->index);
-
- return cx23885_query_audinput(file, priv, i);
-}
-
-static int vidioc_s_audinput(struct file *file, void *priv,
- struct v4l2_audio *i)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
- if (i->index >= 2)
- return -EINVAL;
-
- dprintk(1, "%s(%d)\n", __func__, i->index);
-
- dev->audinput = i->index;
-
- /* Skip the audio defaults from the cards struct, caller wants
- * directly touch the audio mux hardware. */
- cx23885_flatiron_mux(dev, dev->audinput + 1);
- return 0;
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qctrl)
-{
- qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
- if (unlikely(qctrl->id == 0))
- return -EINVAL;
- return cx23885_ctrl_query(qctrl);
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
- return cx23885_get_control(dev, ctl);
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
- return cx23885_set_control(dev, ctl);
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
- if (unlikely(UNSET == dev->tuner_type))
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
-
- strcpy(t->name, "Television");
-
- call_all(dev, tuner, g_tuner, t);
- return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
- if (UNSET == dev->tuner_type)
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
- /* Update the A/V core */
- call_all(dev, tuner, s_tuner, t);
-
- return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
-
- if (unlikely(UNSET == dev->tuner_type))
- return -EINVAL;
-
- /* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */
- f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- f->frequency = dev->freq;
-
- call_all(dev, tuner, g_frequency, f);
-
- return 0;
-}
-
-static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f)
-{
- struct v4l2_control ctrl;
-
- if (unlikely(UNSET == dev->tuner_type))
- return -EINVAL;
- if (unlikely(f->tuner != 0))
- return -EINVAL;
-
- mutex_lock(&dev->lock);
- dev->freq = f->frequency;
-
- /* I need to mute audio here */
- ctrl.id = V4L2_CID_AUDIO_MUTE;
- ctrl.value = 1;
- cx23885_set_control(dev, &ctrl);
-
- call_all(dev, tuner, s_frequency, f);
-
- /* When changing channels it is required to reset TVAUDIO */
- msleep(100);
-
- /* I need to unmute audio here */
- ctrl.value = 0;
- cx23885_set_control(dev, &ctrl);
-
- mutex_unlock(&dev->lock);
-
- return 0;
-}
-
-static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
- struct v4l2_frequency *f)
-{
- struct v4l2_control ctrl;
- struct videobuf_dvb_frontend *vfe;
- struct dvb_frontend *fe;
-
- struct analog_parameters params = {
- .mode = V4L2_TUNER_ANALOG_TV,
- .audmode = V4L2_TUNER_MODE_STEREO,
- .std = dev->tvnorm,
- .frequency = f->frequency
- };
-
- mutex_lock(&dev->lock);
- dev->freq = f->frequency;
-
- /* I need to mute audio here */
- ctrl.id = V4L2_CID_AUDIO_MUTE;
- ctrl.value = 1;
- cx23885_set_control(dev, &ctrl);
-
- /* If HVR1850 */
- dprintk(1, "%s() frequency=%d tuner=%d std=0x%llx\n", __func__,
- params.frequency, f->tuner, params.std);
-
- vfe = videobuf_dvb_get_frontend(&dev->ts2.frontends, 1);
- if (!vfe) {
- mutex_unlock(&dev->lock);
- return -EINVAL;
- }
-
- fe = vfe->dvb.frontend;
-
- if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) ||
- (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) ||
- (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111))
- fe = &dev->ts1.analog_fe;
-
- if (fe && fe->ops.tuner_ops.set_analog_params) {
- call_all(dev, core, s_std, dev->tvnorm);
- fe->ops.tuner_ops.set_analog_params(fe, &params);
- }
- else
- printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__);
-
- /* When changing channels it is required to reset TVAUDIO */
- msleep(100);
-
- /* I need to unmute audio here */
- ctrl.value = 0;
- cx23885_set_control(dev, &ctrl);
-
- mutex_unlock(&dev->lock);
-
- return 0;
-}
-
-int cx23885_set_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct cx23885_fh *fh = priv;
- struct cx23885_dev *dev = fh->dev;
- int ret;
-
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1255:
- case CX23885_BOARD_HAUPPAUGE_HVR1255_22111:
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- ret = cx23885_set_freq_via_ops(dev, f);
- break;
- default:
- ret = cx23885_set_freq(dev, f);
- }
-
- return ret;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- return cx23885_set_frequency(file, priv, f);
-}
-
-/* ----------------------------------------------------------- */
-
-static void cx23885_vid_timeout(unsigned long data)
-{
- struct cx23885_dev *dev = (struct cx23885_dev *)data;
- struct cx23885_dmaqueue *q = &dev->vidq;
- struct cx23885_buffer *buf;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->slock, flags);
- while (!list_empty(&q->active)) {
- buf = list_entry(q->active.next,
- struct cx23885_buffer, vb.queue);
- list_del(&buf->vb.queue);
- buf->vb.state = VIDEOBUF_ERROR;
- wake_up(&buf->vb.done);
- printk(KERN_ERR "%s: [%p/%d] timeout - dma=0x%08lx\n",
- dev->name, buf, buf->vb.i,
- (unsigned long)buf->risc.dma);
- }
- cx23885_restart_video_queue(dev, q);
- spin_unlock_irqrestore(&dev->slock, flags);
-}
-
-int cx23885_video_irq(struct cx23885_dev *dev, u32 status)
-{
- u32 mask, count;
- int handled = 0;
-
- mask = cx_read(VID_A_INT_MSK);
- if (0 == (status & mask))
- return handled;
-
- cx_write(VID_A_INT_STAT, status);
-
- /* risc op code error, fifo overflow or line sync detection error */
- if ((status & VID_BC_MSK_OPC_ERR) ||
- (status & VID_BC_MSK_SYNC) ||
- (status & VID_BC_MSK_OF)) {
-
- if (status & VID_BC_MSK_OPC_ERR) {
- dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n",
- VID_BC_MSK_OPC_ERR);
- printk(KERN_WARNING "%s: video risc op code error\n",
- dev->name);
- cx23885_sram_channel_dump(dev,
- &dev->sram_channels[SRAM_CH01]);
- }
-
- if (status & VID_BC_MSK_SYNC)
- dprintk(7, " (VID_BC_MSK_SYNC 0x%08x) "
- "video lines miss-match\n",
- VID_BC_MSK_SYNC);
-
- if (status & VID_BC_MSK_OF)
- dprintk(7, " (VID_BC_MSK_OF 0x%08x) fifo overflow\n",
- VID_BC_MSK_OF);
-
- }
-
- /* Video */
- if (status & VID_BC_MSK_RISCI1) {
- spin_lock(&dev->slock);
- count = cx_read(VID_A_GPCNT);
- cx23885_video_wakeup(dev, &dev->vidq, count);
- spin_unlock(&dev->slock);
- handled++;
- }
- if (status & VID_BC_MSK_RISCI2) {
- dprintk(2, "stopper video\n");
- spin_lock(&dev->slock);
- cx23885_restart_video_queue(dev, &dev->vidq);
- spin_unlock(&dev->slock);
- handled++;
- }
-
- /* Allow the VBI framework to process it's payload */
- handled += cx23885_vbi_irq(dev, status);
-
- return handled;
-}
-
-/* ----------------------------------------------------------- */
-/* exported stuff */
-
-static const struct v4l2_file_operations video_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = video_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_g_fmt_vbi_cap = cx23885_vbi_fmt,
- .vidioc_try_fmt_vbi_cap = cx23885_vbi_fmt,
- .vidioc_s_fmt_vbi_cap = cx23885_vbi_fmt,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_g_std = vidioc_g_std,
- .vidioc_querystd = vidioc_g_std,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_g_chip_ident = cx23885_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx23885_g_register,
- .vidioc_s_register = cx23885_s_register,
-#endif
- .vidioc_enumaudio = vidioc_enum_audinput,
- .vidioc_g_audio = vidioc_g_audinput,
- .vidioc_s_audio = vidioc_s_audinput,
-};
-
-static struct video_device cx23885_vbi_template;
-static struct video_device cx23885_video_template = {
- .name = "cx23885-video",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX23885_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
-
-static const struct v4l2_file_operations radio_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .ioctl = video_ioctl2,
-};
-
-
-void cx23885_video_unregister(struct cx23885_dev *dev)
-{
- dprintk(1, "%s()\n", __func__);
- cx23885_irq_remove(dev, 0x01);
-
- if (dev->vbi_dev) {
- if (video_is_registered(dev->vbi_dev))
- video_unregister_device(dev->vbi_dev);
- else
- video_device_release(dev->vbi_dev);
- dev->vbi_dev = NULL;
- btcx_riscmem_free(dev->pci, &dev->vbiq.stopper);
- }
- if (dev->video_dev) {
- if (video_is_registered(dev->video_dev))
- video_unregister_device(dev->video_dev);
- else
- video_device_release(dev->video_dev);
- dev->video_dev = NULL;
-
- btcx_riscmem_free(dev->pci, &dev->vidq.stopper);
- }
-
- if (dev->audio_dev)
- cx23885_audio_unregister(dev);
-}
-
-int cx23885_video_register(struct cx23885_dev *dev)
-{
- int err;
-
- dprintk(1, "%s()\n", __func__);
- spin_lock_init(&dev->slock);
-
- /* Initialize VBI template */
- memcpy(&cx23885_vbi_template, &cx23885_video_template,
- sizeof(cx23885_vbi_template));
- strcpy(cx23885_vbi_template.name, "cx23885-vbi");
-
- dev->tvnorm = cx23885_video_template.current_norm;
-
- /* init video dma queues */
- INIT_LIST_HEAD(&dev->vidq.active);
- INIT_LIST_HEAD(&dev->vidq.queued);
- dev->vidq.timeout.function = cx23885_vid_timeout;
- dev->vidq.timeout.data = (unsigned long)dev;
- init_timer(&dev->vidq.timeout);
- cx23885_risc_stopper(dev->pci, &dev->vidq.stopper,
- VID_A_DMA_CTL, 0x11, 0x00);
-
- /* init vbi dma queues */
- INIT_LIST_HEAD(&dev->vbiq.active);
- INIT_LIST_HEAD(&dev->vbiq.queued);
- dev->vbiq.timeout.function = cx23885_vbi_timeout;
- dev->vbiq.timeout.data = (unsigned long)dev;
- init_timer(&dev->vbiq.timeout);
- cx23885_risc_stopper(dev->pci, &dev->vbiq.stopper,
- VID_A_DMA_CTL, 0x22, 0x00);
-
- cx23885_irq_add_enable(dev, 0x01);
-
- if ((TUNER_ABSENT != dev->tuner_type) &&
- ((dev->tuner_bus == 0) || (dev->tuner_bus == 1))) {
- struct v4l2_subdev *sd = NULL;
-
- if (dev->tuner_addr)
- sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_bus[dev->tuner_bus].i2c_adap,
- "tuner", dev->tuner_addr, NULL);
- else
- sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_bus[dev->tuner_bus].i2c_adap,
- "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV));
- if (sd) {
- struct tuner_setup tun_setup;
-
- memset(&tun_setup, 0, sizeof(tun_setup));
- tun_setup.mode_mask = T_ANALOG_TV;
- tun_setup.type = dev->tuner_type;
- tun_setup.addr = v4l2_i2c_subdev_addr(sd);
- tun_setup.tuner_callback = cx23885_tuner_callback;
-
- v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
-
- if (dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXTV1200) {
- struct xc2028_ctrl ctrl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64
- };
- struct v4l2_priv_tun_config cfg = {
- .tuner = dev->tuner_type,
- .priv = &ctrl
- };
- v4l2_subdev_call(sd, tuner, s_config, &cfg);
- }
- }
- }
-
- /* register Video device */
- dev->video_dev = cx23885_vdev_init(dev, dev->pci,
- &cx23885_video_template, "video");
- err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER,
- video_nr[dev->nr]);
- if (err < 0) {
- printk(KERN_INFO "%s: can't register video device\n",
- dev->name);
- goto fail_unreg;
- }
- printk(KERN_INFO "%s: registered device %s [v4l2]\n",
- dev->name, video_device_node_name(dev->video_dev));
-
- /* register VBI device */
- dev->vbi_dev = cx23885_vdev_init(dev, dev->pci,
- &cx23885_vbi_template, "vbi");
- err = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
- vbi_nr[dev->nr]);
- if (err < 0) {
- printk(KERN_INFO "%s: can't register vbi device\n",
- dev->name);
- goto fail_unreg;
- }
- printk(KERN_INFO "%s: registered device %s\n",
- dev->name, video_device_node_name(dev->vbi_dev));
-
- /* Register ALSA audio device */
- dev->audio_dev = cx23885_audio_register(dev);
-
- /* initial device configuration */
- mutex_lock(&dev->lock);
- cx23885_set_tvnorm(dev, dev->tvnorm);
- init_controls(dev);
- cx23885_video_mux(dev, 0);
- cx23885_audio_mux(dev, 0);
- mutex_unlock(&dev->lock);
-
- return 0;
-
-fail_unreg:
- cx23885_video_unregister(dev);
- return err;
-}
-
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
deleted file mode 100644
index 5d560c747e0..00000000000
--- a/drivers/media/video/cx23885/cx23885.h
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * Driver for the Conexant CX23885 PCIe bridge
- *
- * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/kdev_t.h>
-#include <linux/slab.h>
-
-#include <media/v4l2-device.h>
-#include <media/tuner.h>
-#include <media/tveeprom.h>
-#include <media/videobuf-dma-sg.h>
-#include <media/videobuf-dvb.h>
-#include <media/rc-core.h>
-
-#include "btcx-risc.h"
-#include "cx23885-reg.h"
-#include "media/cx2341x.h"
-
-#include <linux/mutex.h>
-
-#define CX23885_VERSION "0.0.3"
-
-#define UNSET (-1U)
-
-#define CX23885_MAXBOARDS 8
-
-/* Max number of inputs by card */
-#define MAX_CX23885_INPUT 8
-#define INPUT(nr) (&cx23885_boards[dev->board].input[nr])
-#define RESOURCE_OVERLAY 1
-#define RESOURCE_VIDEO 2
-#define RESOURCE_VBI 4
-
-#define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */
-
-#define CX23885_BOARD_NOAUTO UNSET
-#define CX23885_BOARD_UNKNOWN 0
-#define CX23885_BOARD_HAUPPAUGE_HVR1800lp 1
-#define CX23885_BOARD_HAUPPAUGE_HVR1800 2
-#define CX23885_BOARD_HAUPPAUGE_HVR1250 3
-#define CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP 4
-#define CX23885_BOARD_HAUPPAUGE_HVR1500Q 5
-#define CX23885_BOARD_HAUPPAUGE_HVR1500 6
-#define CX23885_BOARD_HAUPPAUGE_HVR1200 7
-#define CX23885_BOARD_HAUPPAUGE_HVR1700 8
-#define CX23885_BOARD_HAUPPAUGE_HVR1400 9
-#define CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP 10
-#define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP 11
-#define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H 12
-#define CX23885_BOARD_COMPRO_VIDEOMATE_E650F 13
-#define CX23885_BOARD_TBS_6920 14
-#define CX23885_BOARD_TEVII_S470 15
-#define CX23885_BOARD_DVBWORLD_2005 16
-#define CX23885_BOARD_NETUP_DUAL_DVBS2_CI 17
-#define CX23885_BOARD_HAUPPAUGE_HVR1270 18
-#define CX23885_BOARD_HAUPPAUGE_HVR1275 19
-#define CX23885_BOARD_HAUPPAUGE_HVR1255 20
-#define CX23885_BOARD_HAUPPAUGE_HVR1210 21
-#define CX23885_BOARD_MYGICA_X8506 22
-#define CX23885_BOARD_MAGICPRO_PROHDTVE2 23
-#define CX23885_BOARD_HAUPPAUGE_HVR1850 24
-#define CX23885_BOARD_COMPRO_VIDEOMATE_E800 25
-#define CX23885_BOARD_HAUPPAUGE_HVR1290 26
-#define CX23885_BOARD_MYGICA_X8558PRO 27
-#define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28
-#define CX23885_BOARD_GOTVIEW_X5_3D_HYBRID 29
-#define CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF 30
-#define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000 31
-#define CX23885_BOARD_MPX885 32
-#define CX23885_BOARD_MYGICA_X8507 33
-#define CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL 34
-#define CX23885_BOARD_TEVII_S471 35
-#define CX23885_BOARD_HAUPPAUGE_HVR1255_22111 36
-
-#define GPIO_0 0x00000001
-#define GPIO_1 0x00000002
-#define GPIO_2 0x00000004
-#define GPIO_3 0x00000008
-#define GPIO_4 0x00000010
-#define GPIO_5 0x00000020
-#define GPIO_6 0x00000040
-#define GPIO_7 0x00000080
-#define GPIO_8 0x00000100
-#define GPIO_9 0x00000200
-#define GPIO_10 0x00000400
-#define GPIO_11 0x00000800
-#define GPIO_12 0x00001000
-#define GPIO_13 0x00002000
-#define GPIO_14 0x00004000
-#define GPIO_15 0x00008000
-
-/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
-#define CX23885_NORMS (\
- V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443 | \
- V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \
- V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | \
- V4L2_STD_PAL_60 | V4L2_STD_SECAM_L | V4L2_STD_SECAM_DK)
-
-struct cx23885_fmt {
- char *name;
- u32 fourcc; /* v4l2 format id */
- int depth;
- int flags;
- u32 cxformat;
-};
-
-struct cx23885_ctrl {
- struct v4l2_queryctrl v;
- u32 off;
- u32 reg;
- u32 mask;
- u32 shift;
-};
-
-struct cx23885_tvnorm {
- char *name;
- v4l2_std_id id;
- u32 cxiformat;
- u32 cxoformat;
-};
-
-struct cx23885_fh {
- struct cx23885_dev *dev;
- enum v4l2_buf_type type;
- int radio;
- u32 resources;
-
- /* video overlay */
- struct v4l2_window win;
- struct v4l2_clip *clips;
- unsigned int nclips;
-
- /* video capture */
- struct cx23885_fmt *fmt;
- unsigned int width, height;
-
- /* vbi capture */
- struct videobuf_queue vidq;
- struct videobuf_queue vbiq;
-
- /* MPEG Encoder specifics ONLY */
- struct videobuf_queue mpegq;
- atomic_t v4l_reading;
-};
-
-enum cx23885_itype {
- CX23885_VMUX_COMPOSITE1 = 1,
- CX23885_VMUX_COMPOSITE2,
- CX23885_VMUX_COMPOSITE3,
- CX23885_VMUX_COMPOSITE4,
- CX23885_VMUX_SVIDEO,
- CX23885_VMUX_COMPONENT,
- CX23885_VMUX_TELEVISION,
- CX23885_VMUX_CABLE,
- CX23885_VMUX_DVB,
- CX23885_VMUX_DEBUG,
- CX23885_RADIO,
-};
-
-enum cx23885_src_sel_type {
- CX23885_SRC_SEL_EXT_656_VIDEO = 0,
- CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO
-};
-
-/* buffer for one video frame */
-struct cx23885_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
-
- /* cx23885 specific */
- unsigned int bpl;
- struct btcx_riscmem risc;
- struct cx23885_fmt *fmt;
- u32 count;
-};
-
-struct cx23885_input {
- enum cx23885_itype type;
- unsigned int vmux;
- unsigned int amux;
- u32 gpio0, gpio1, gpio2, gpio3;
-};
-
-typedef enum {
- CX23885_MPEG_UNDEFINED = 0,
- CX23885_MPEG_DVB,
- CX23885_ANALOG_VIDEO,
- CX23885_MPEG_ENCODER,
-} port_t;
-
-struct cx23885_board {
- char *name;
- port_t porta, portb, portc;
- int num_fds_portb, num_fds_portc;
- unsigned int tuner_type;
- unsigned int radio_type;
- unsigned char tuner_addr;
- unsigned char radio_addr;
- unsigned int tuner_bus;
-
- /* Vendors can and do run the PCIe bridge at different
- * clock rates, driven physically by crystals on the PCBs.
- * The core has to accommodate this. This allows the user
- * to add new boards with new frequencys. The value is
- * expressed in Hz.
- *
- * The core framework will default this value based on
- * current designs, but it can vary.
- */
- u32 clk_freq;
- struct cx23885_input input[MAX_CX23885_INPUT];
- int ci_type; /* for NetUP */
- /* Force bottom field first during DMA (888 workaround) */
- u32 force_bff;
-};
-
-struct cx23885_subid {
- u16 subvendor;
- u16 subdevice;
- u32 card;
-};
-
-struct cx23885_i2c {
- struct cx23885_dev *dev;
-
- int nr;
-
- /* i2c i/o */
- struct i2c_adapter i2c_adap;
- struct i2c_client i2c_client;
- u32 i2c_rc;
-
- /* 885 registers used for raw addess */
- u32 i2c_period;
- u32 reg_ctrl;
- u32 reg_stat;
- u32 reg_addr;
- u32 reg_rdata;
- u32 reg_wdata;
-};
-
-struct cx23885_dmaqueue {
- struct list_head active;
- struct list_head queued;
- struct timer_list timeout;
- struct btcx_riscmem stopper;
- u32 count;
-};
-
-struct cx23885_tsport {
- struct cx23885_dev *dev;
-
- int nr;
- int sram_chno;
-
- struct videobuf_dvb_frontends frontends;
-
- /* dma queues */
- struct cx23885_dmaqueue mpegq;
- u32 ts_packet_size;
- u32 ts_packet_count;
-
- int width;
- int height;
-
- spinlock_t slock;
-
- /* registers */
- u32 reg_gpcnt;
- u32 reg_gpcnt_ctl;
- u32 reg_dma_ctl;
- u32 reg_lngth;
- u32 reg_hw_sop_ctrl;
- u32 reg_gen_ctrl;
- u32 reg_bd_pkt_status;
- u32 reg_sop_status;
- u32 reg_fifo_ovfl_stat;
- u32 reg_vld_misc;
- u32 reg_ts_clk_en;
- u32 reg_ts_int_msk;
- u32 reg_ts_int_stat;
- u32 reg_src_sel;
-
- /* Default register vals */
- int pci_irqmask;
- u32 dma_ctl_val;
- u32 ts_int_msk_val;
- u32 gen_ctrl_val;
- u32 ts_clk_en_val;
- u32 src_sel_val;
- u32 vld_misc_val;
- u32 hw_sop_ctrl_val;
-
- /* Allow a single tsport to have multiple frontends */
- u32 num_frontends;
- void (*gate_ctrl)(struct cx23885_tsport *port, int open);
- void *port_priv;
-
- /* Workaround for a temp dvb_frontend that the tuner can attached to */
- struct dvb_frontend analog_fe;
-};
-
-struct cx23885_kernel_ir {
- struct cx23885_dev *cx;
- char *name;
- char *phys;
-
- struct rc_dev *rc;
-};
-
-struct cx23885_audio_buffer {
- unsigned int bpl;
- struct btcx_riscmem risc;
- struct videobuf_dmabuf dma;
-};
-
-struct cx23885_audio_dev {
- struct cx23885_dev *dev;
-
- struct pci_dev *pci;
-
- struct snd_card *card;
-
- spinlock_t lock;
-
- atomic_t count;
-
- unsigned int dma_size;
- unsigned int period_size;
- unsigned int num_periods;
-
- struct videobuf_dmabuf *dma_risc;
-
- struct cx23885_audio_buffer *buf;
-
- struct snd_pcm_substream *substream;
-};
-
-struct cx23885_dev {
- atomic_t refcount;
- struct v4l2_device v4l2_dev;
-
- /* pci stuff */
- struct pci_dev *pci;
- unsigned char pci_rev, pci_lat;
- int pci_bus, pci_slot;
- u32 __iomem *lmmio;
- u8 __iomem *bmmio;
- int pci_irqmask;
- spinlock_t pci_irqmask_lock; /* protects mask reg too */
- int hwrevision;
-
- /* This valud is board specific and is used to configure the
- * AV core so we see nice clean and stable video and audio. */
- u32 clk_freq;
-
- /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */
- struct cx23885_i2c i2c_bus[3];
-
- int nr;
- struct mutex lock;
- struct mutex gpio_lock;
-
- /* board details */
- unsigned int board;
- char name[32];
-
- struct cx23885_tsport ts1, ts2;
-
- /* sram configuration */
- struct sram_channel *sram_channels;
-
- enum {
- CX23885_BRIDGE_UNDEFINED = 0,
- CX23885_BRIDGE_885 = 885,
- CX23885_BRIDGE_887 = 887,
- CX23885_BRIDGE_888 = 888,
- } bridge;
-
- /* Analog video */
- u32 resources;
- unsigned int input;
- unsigned int audinput; /* Selectable audio input */
- u32 tvaudio;
- v4l2_std_id tvnorm;
- unsigned int tuner_type;
- unsigned char tuner_addr;
- unsigned int tuner_bus;
- unsigned int radio_type;
- unsigned char radio_addr;
- unsigned int has_radio;
- struct v4l2_subdev *sd_cx25840;
- struct work_struct cx25840_work;
-
- /* Infrared */
- struct v4l2_subdev *sd_ir;
- struct work_struct ir_rx_work;
- unsigned long ir_rx_notifications;
- struct work_struct ir_tx_work;
- unsigned long ir_tx_notifications;
-
- struct cx23885_kernel_ir *kernel_ir;
- atomic_t ir_input_stopping;
-
- /* V4l */
- u32 freq;
- struct video_device *video_dev;
- struct video_device *vbi_dev;
- struct video_device *radio_dev;
-
- struct cx23885_dmaqueue vidq;
- struct cx23885_dmaqueue vbiq;
- spinlock_t slock;
-
- /* MPEG Encoder ONLY settings */
- u32 cx23417_mailbox;
- struct cx2341x_mpeg_params mpeg_params;
- struct video_device *v4l_device;
- atomic_t v4l_reader_count;
- struct cx23885_tvnorm encodernorm;
-
- /* Analog raw audio */
- struct cx23885_audio_dev *audio_dev;
-
-};
-
-static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct cx23885_dev, v4l2_dev);
-}
-
-#define call_all(dev, o, f, args...) \
- v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
-
-#define CX23885_HW_888_IR (1 << 0)
-#define CX23885_HW_AV_CORE (1 << 1)
-
-#define call_hw(dev, grpid, o, f, args...) \
- v4l2_device_call_all(&dev->v4l2_dev, grpid, o, f, ##args)
-
-extern struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw);
-
-#define SRAM_CH01 0 /* Video A */
-#define SRAM_CH02 1 /* VBI A */
-#define SRAM_CH03 2 /* Video B */
-#define SRAM_CH04 3 /* Transport via B */
-#define SRAM_CH05 4 /* VBI B */
-#define SRAM_CH06 5 /* Video C */
-#define SRAM_CH07 6 /* Transport via C */
-#define SRAM_CH08 7 /* Audio Internal A */
-#define SRAM_CH09 8 /* Audio Internal B */
-#define SRAM_CH10 9 /* Audio External */
-#define SRAM_CH11 10 /* COMB_3D_N */
-#define SRAM_CH12 11 /* Comb 3D N1 */
-#define SRAM_CH13 12 /* Comb 3D N2 */
-#define SRAM_CH14 13 /* MOE Vid */
-#define SRAM_CH15 14 /* MOE RSLT */
-
-struct sram_channel {
- char *name;
- u32 cmds_start;
- u32 ctrl_start;
- u32 cdt;
- u32 fifo_start;
- u32 fifo_size;
- u32 ptr1_reg;
- u32 ptr2_reg;
- u32 cnt1_reg;
- u32 cnt2_reg;
- u32 jumponly;
-};
-
-/* ----------------------------------------------------------- */
-
-#define cx_read(reg) readl(dev->lmmio + ((reg)>>2))
-#define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2))
-
-#define cx_andor(reg, mask, value) \
- writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\
- ((value) & (mask)), dev->lmmio+((reg)>>2))
-
-#define cx_set(reg, bit) cx_andor((reg), (bit), (bit))
-#define cx_clear(reg, bit) cx_andor((reg), (bit), 0)
-
-/* ----------------------------------------------------------- */
-/* cx23885-core.c */
-
-extern int cx23885_sram_channel_setup(struct cx23885_dev *dev,
- struct sram_channel *ch,
- unsigned int bpl, u32 risc);
-
-extern void cx23885_sram_channel_dump(struct cx23885_dev *dev,
- struct sram_channel *ch);
-
-extern int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
- u32 reg, u32 mask, u32 value);
-
-extern int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
- struct scatterlist *sglist,
- unsigned int top_offset, unsigned int bottom_offset,
- unsigned int bpl, unsigned int padding, unsigned int lines);
-
-extern int cx23885_risc_vbibuffer(struct pci_dev *pci,
- struct btcx_riscmem *risc, struct scatterlist *sglist,
- unsigned int top_offset, unsigned int bottom_offset,
- unsigned int bpl, unsigned int padding, unsigned int lines);
-
-void cx23885_cancel_buffers(struct cx23885_tsport *port);
-
-extern int cx23885_restart_queue(struct cx23885_tsport *port,
- struct cx23885_dmaqueue *q);
-
-extern void cx23885_wakeup(struct cx23885_tsport *port,
- struct cx23885_dmaqueue *q, u32 count);
-
-extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask);
-extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask);
-extern u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask);
-extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask,
- int asoutput);
-
-extern void cx23885_irq_add_enable(struct cx23885_dev *dev, u32 mask);
-extern void cx23885_irq_enable(struct cx23885_dev *dev, u32 mask);
-extern void cx23885_irq_disable(struct cx23885_dev *dev, u32 mask);
-extern void cx23885_irq_remove(struct cx23885_dev *dev, u32 mask);
-
-/* ----------------------------------------------------------- */
-/* cx23885-cards.c */
-extern struct cx23885_board cx23885_boards[];
-extern const unsigned int cx23885_bcount;
-
-extern struct cx23885_subid cx23885_subids[];
-extern const unsigned int cx23885_idcount;
-
-extern int cx23885_tuner_callback(void *priv, int component,
- int command, int arg);
-extern void cx23885_card_list(struct cx23885_dev *dev);
-extern int cx23885_ir_init(struct cx23885_dev *dev);
-extern void cx23885_ir_pci_int_enable(struct cx23885_dev *dev);
-extern void cx23885_ir_fini(struct cx23885_dev *dev);
-extern void cx23885_gpio_setup(struct cx23885_dev *dev);
-extern void cx23885_card_setup(struct cx23885_dev *dev);
-extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev);
-
-extern int cx23885_dvb_register(struct cx23885_tsport *port);
-extern int cx23885_dvb_unregister(struct cx23885_tsport *port);
-
-extern int cx23885_buf_prepare(struct videobuf_queue *q,
- struct cx23885_tsport *port,
- struct cx23885_buffer *buf,
- enum v4l2_field field);
-extern void cx23885_buf_queue(struct cx23885_tsport *port,
- struct cx23885_buffer *buf);
-extern void cx23885_free_buffer(struct videobuf_queue *q,
- struct cx23885_buffer *buf);
-
-/* ----------------------------------------------------------- */
-/* cx23885-video.c */
-/* Video */
-extern int cx23885_video_register(struct cx23885_dev *dev);
-extern void cx23885_video_unregister(struct cx23885_dev *dev);
-extern int cx23885_video_irq(struct cx23885_dev *dev, u32 status);
-extern void cx23885_video_wakeup(struct cx23885_dev *dev,
- struct cx23885_dmaqueue *q, u32 count);
-int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i);
-int cx23885_set_input(struct file *file, void *priv, unsigned int i);
-int cx23885_get_input(struct file *file, void *priv, unsigned int *i);
-int cx23885_set_frequency(struct file *file, void *priv, struct v4l2_frequency *f);
-int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl);
-int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl);
-int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm);
-
-/* ----------------------------------------------------------- */
-/* cx23885-vbi.c */
-extern int cx23885_vbi_fmt(struct file *file, void *priv,
- struct v4l2_format *f);
-extern void cx23885_vbi_timeout(unsigned long data);
-extern struct videobuf_queue_ops cx23885_vbi_qops;
-extern int cx23885_restart_vbi_queue(struct cx23885_dev *dev,
- struct cx23885_dmaqueue *q);
-extern int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status);
-
-/* cx23885-i2c.c */
-extern int cx23885_i2c_register(struct cx23885_i2c *bus);
-extern int cx23885_i2c_unregister(struct cx23885_i2c *bus);
-extern void cx23885_av_clk(struct cx23885_dev *dev, int enable);
-
-/* ----------------------------------------------------------- */
-/* cx23885-417.c */
-extern int cx23885_417_register(struct cx23885_dev *dev);
-extern void cx23885_417_unregister(struct cx23885_dev *dev);
-extern int cx23885_irq_417(struct cx23885_dev *dev, u32 status);
-extern void cx23885_417_check_encoder(struct cx23885_dev *dev);
-extern void cx23885_mc417_init(struct cx23885_dev *dev);
-extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value);
-extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value);
-extern int mc417_register_read(struct cx23885_dev *dev,
- u16 address, u32 *value);
-extern int mc417_register_write(struct cx23885_dev *dev,
- u16 address, u32 value);
-extern void mc417_gpio_set(struct cx23885_dev *dev, u32 mask);
-extern void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask);
-extern void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput);
-
-/* ----------------------------------------------------------- */
-/* cx23885-alsa.c */
-extern struct cx23885_audio_dev *cx23885_audio_register(
- struct cx23885_dev *dev);
-extern void cx23885_audio_unregister(struct cx23885_dev *dev);
-extern int cx23885_audio_irq(struct cx23885_dev *dev, u32 status, u32 mask);
-extern int cx23885_risc_databuffer(struct pci_dev *pci,
- struct btcx_riscmem *risc,
- struct scatterlist *sglist,
- unsigned int bpl,
- unsigned int lines,
- unsigned int lpi);
-
-/* ----------------------------------------------------------- */
-/* tv norms */
-
-static inline unsigned int norm_maxw(v4l2_std_id norm)
-{
- return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768;
-}
-
-static inline unsigned int norm_maxh(v4l2_std_id norm)
-{
- return (norm & V4L2_STD_625_50) ? 576 : 480;
-}
-
-static inline unsigned int norm_swidth(v4l2_std_id norm)
-{
- return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
-}
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c
deleted file mode 100644
index c2bc39c58f8..00000000000
--- a/drivers/media/video/cx23885/cx23888-ir.c
+++ /dev/null
@@ -1,1271 +0,0 @@
-/*
- * Driver for the Conexant CX23885/7/8 PCIe bridge
- *
- * CX23888 Integrated Consumer Infrared Controller
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <linux/kfifo.h>
-#include <linux/slab.h>
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/rc-core.h>
-
-#include "cx23885.h"
-
-static unsigned int ir_888_debug;
-module_param(ir_888_debug, int, 0644);
-MODULE_PARM_DESC(ir_888_debug, "enable debug messages [CX23888 IR controller]");
-
-#define CX23888_IR_REG_BASE 0x170000
-/*
- * These CX23888 register offsets have a straightforward one to one mapping
- * to the CX23885 register offsets of 0x200 through 0x218
- */
-#define CX23888_IR_CNTRL_REG 0x170000
-#define CNTRL_WIN_3_3 0x00000000
-#define CNTRL_WIN_4_3 0x00000001
-#define CNTRL_WIN_3_4 0x00000002
-#define CNTRL_WIN_4_4 0x00000003
-#define CNTRL_WIN 0x00000003
-#define CNTRL_EDG_NONE 0x00000000
-#define CNTRL_EDG_FALL 0x00000004
-#define CNTRL_EDG_RISE 0x00000008
-#define CNTRL_EDG_BOTH 0x0000000C
-#define CNTRL_EDG 0x0000000C
-#define CNTRL_DMD 0x00000010
-#define CNTRL_MOD 0x00000020
-#define CNTRL_RFE 0x00000040
-#define CNTRL_TFE 0x00000080
-#define CNTRL_RXE 0x00000100
-#define CNTRL_TXE 0x00000200
-#define CNTRL_RIC 0x00000400
-#define CNTRL_TIC 0x00000800
-#define CNTRL_CPL 0x00001000
-#define CNTRL_LBM 0x00002000
-#define CNTRL_R 0x00004000
-/* CX23888 specific control flag */
-#define CNTRL_IVO 0x00008000
-
-#define CX23888_IR_TXCLK_REG 0x170004
-#define TXCLK_TCD 0x0000FFFF
-
-#define CX23888_IR_RXCLK_REG 0x170008
-#define RXCLK_RCD 0x0000FFFF
-
-#define CX23888_IR_CDUTY_REG 0x17000C
-#define CDUTY_CDC 0x0000000F
-
-#define CX23888_IR_STATS_REG 0x170010
-#define STATS_RTO 0x00000001
-#define STATS_ROR 0x00000002
-#define STATS_RBY 0x00000004
-#define STATS_TBY 0x00000008
-#define STATS_RSR 0x00000010
-#define STATS_TSR 0x00000020
-
-#define CX23888_IR_IRQEN_REG 0x170014
-#define IRQEN_RTE 0x00000001
-#define IRQEN_ROE 0x00000002
-#define IRQEN_RSE 0x00000010
-#define IRQEN_TSE 0x00000020
-
-#define CX23888_IR_FILTR_REG 0x170018
-#define FILTR_LPF 0x0000FFFF
-
-/* This register doesn't follow the pattern; it's 0x23C on a CX23885 */
-#define CX23888_IR_FIFO_REG 0x170040
-#define FIFO_RXTX 0x0000FFFF
-#define FIFO_RXTX_LVL 0x00010000
-#define FIFO_RXTX_RTO 0x0001FFFF
-#define FIFO_RX_NDV 0x00020000
-#define FIFO_RX_DEPTH 8
-#define FIFO_TX_DEPTH 8
-
-/* CX23888 unique registers */
-#define CX23888_IR_SEEDP_REG 0x17001C
-#define CX23888_IR_TIMOL_REG 0x170020
-#define CX23888_IR_WAKE0_REG 0x170024
-#define CX23888_IR_WAKE1_REG 0x170028
-#define CX23888_IR_WAKE2_REG 0x17002C
-#define CX23888_IR_MASK0_REG 0x170030
-#define CX23888_IR_MASK1_REG 0x170034
-#define CX23888_IR_MAKS2_REG 0x170038
-#define CX23888_IR_DPIPG_REG 0x17003C
-#define CX23888_IR_LEARN_REG 0x170044
-
-#define CX23888_VIDCLK_FREQ 108000000 /* 108 MHz, BT.656 */
-#define CX23888_IR_REFCLK_FREQ (CX23888_VIDCLK_FREQ / 2)
-
-/*
- * We use this union internally for convenience, but callers to tx_write
- * and rx_read will be expecting records of type struct ir_raw_event.
- * Always ensure the size of this union is dictated by struct ir_raw_event.
- */
-union cx23888_ir_fifo_rec {
- u32 hw_fifo_data;
- struct ir_raw_event ir_core_data;
-};
-
-#define CX23888_IR_RX_KFIFO_SIZE (256 * sizeof(union cx23888_ir_fifo_rec))
-#define CX23888_IR_TX_KFIFO_SIZE (256 * sizeof(union cx23888_ir_fifo_rec))
-
-struct cx23888_ir_state {
- struct v4l2_subdev sd;
- struct cx23885_dev *dev;
- u32 id;
- u32 rev;
-
- struct v4l2_subdev_ir_parameters rx_params;
- struct mutex rx_params_lock;
- atomic_t rxclk_divider;
- atomic_t rx_invert;
-
- struct kfifo rx_kfifo;
- spinlock_t rx_kfifo_lock;
-
- struct v4l2_subdev_ir_parameters tx_params;
- struct mutex tx_params_lock;
- atomic_t txclk_divider;
-};
-
-static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd)
-{
- return v4l2_get_subdevdata(sd);
-}
-
-/*
- * IR register block read and write functions
- */
-static
-inline int cx23888_ir_write4(struct cx23885_dev *dev, u32 addr, u32 value)
-{
- cx_write(addr, value);
- return 0;
-}
-
-static inline u32 cx23888_ir_read4(struct cx23885_dev *dev, u32 addr)
-{
- return cx_read(addr);
-}
-
-static inline int cx23888_ir_and_or4(struct cx23885_dev *dev, u32 addr,
- u32 and_mask, u32 or_value)
-{
- cx_andor(addr, ~and_mask, or_value);
- return 0;
-}
-
-/*
- * Rx and Tx Clock Divider register computations
- *
- * Note the largest clock divider value of 0xffff corresponds to:
- * (0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns
- * which fits in 21 bits, so we'll use unsigned int for time arguments.
- */
-static inline u16 count_to_clock_divider(unsigned int d)
-{
- if (d > RXCLK_RCD + 1)
- d = RXCLK_RCD;
- else if (d < 2)
- d = 1;
- else
- d--;
- return (u16) d;
-}
-
-static inline u16 ns_to_clock_divider(unsigned int ns)
-{
- return count_to_clock_divider(
- DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000));
-}
-
-static inline unsigned int clock_divider_to_ns(unsigned int divider)
-{
- /* Period of the Rx or Tx clock in ns */
- return DIV_ROUND_CLOSEST((divider + 1) * 1000,
- CX23888_IR_REFCLK_FREQ / 1000000);
-}
-
-static inline u16 carrier_freq_to_clock_divider(unsigned int freq)
-{
- return count_to_clock_divider(
- DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * 16));
-}
-
-static inline unsigned int clock_divider_to_carrier_freq(unsigned int divider)
-{
- return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, (divider + 1) * 16);
-}
-
-static inline u16 freq_to_clock_divider(unsigned int freq,
- unsigned int rollovers)
-{
- return count_to_clock_divider(
- DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * rollovers));
-}
-
-static inline unsigned int clock_divider_to_freq(unsigned int divider,
- unsigned int rollovers)
-{
- return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ,
- (divider + 1) * rollovers);
-}
-
-/*
- * Low Pass Filter register calculations
- *
- * Note the largest count value of 0xffff corresponds to:
- * 0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns
- * which fits in 21 bits, so we'll use unsigned int for time arguments.
- */
-static inline u16 count_to_lpf_count(unsigned int d)
-{
- if (d > FILTR_LPF)
- d = FILTR_LPF;
- else if (d < 4)
- d = 0;
- return (u16) d;
-}
-
-static inline u16 ns_to_lpf_count(unsigned int ns)
-{
- return count_to_lpf_count(
- DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000));
-}
-
-static inline unsigned int lpf_count_to_ns(unsigned int count)
-{
- /* Duration of the Low Pass Filter rejection window in ns */
- return DIV_ROUND_CLOSEST(count * 1000,
- CX23888_IR_REFCLK_FREQ / 1000000);
-}
-
-static inline unsigned int lpf_count_to_us(unsigned int count)
-{
- /* Duration of the Low Pass Filter rejection window in us */
- return DIV_ROUND_CLOSEST(count, CX23888_IR_REFCLK_FREQ / 1000000);
-}
-
-/*
- * FIFO register pulse width count compuations
- */
-static u32 clock_divider_to_resolution(u16 divider)
-{
- /*
- * Resolution is the duration of 1 tick of the readable portion of
- * of the pulse width counter as read from the FIFO. The two lsb's are
- * not readable, hence the << 2. This function returns ns.
- */
- return DIV_ROUND_CLOSEST((1 << 2) * ((u32) divider + 1) * 1000,
- CX23888_IR_REFCLK_FREQ / 1000000);
-}
-
-static u64 pulse_width_count_to_ns(u16 count, u16 divider)
-{
- u64 n;
- u32 rem;
-
- /*
- * The 2 lsb's of the pulse width timer count are not readable, hence
- * the (count << 2) | 0x3
- */
- n = (((u64) count << 2) | 0x3) * (divider + 1) * 1000; /* millicycles */
- rem = do_div(n, CX23888_IR_REFCLK_FREQ / 1000000); /* / MHz => ns */
- if (rem >= CX23888_IR_REFCLK_FREQ / 1000000 / 2)
- n++;
- return n;
-}
-
-static unsigned int pulse_width_count_to_us(u16 count, u16 divider)
-{
- u64 n;
- u32 rem;
-
- /*
- * The 2 lsb's of the pulse width timer count are not readable, hence
- * the (count << 2) | 0x3
- */
- n = (((u64) count << 2) | 0x3) * (divider + 1); /* cycles */
- rem = do_div(n, CX23888_IR_REFCLK_FREQ / 1000000); /* / MHz => us */
- if (rem >= CX23888_IR_REFCLK_FREQ / 1000000 / 2)
- n++;
- return (unsigned int) n;
-}
-
-/*
- * Pulse Clocks computations: Combined Pulse Width Count & Rx Clock Counts
- *
- * The total pulse clock count is an 18 bit pulse width timer count as the most
- * significant part and (up to) 16 bit clock divider count as a modulus.
- * When the Rx clock divider ticks down to 0, it increments the 18 bit pulse
- * width timer count's least significant bit.
- */
-static u64 ns_to_pulse_clocks(u32 ns)
-{
- u64 clocks;
- u32 rem;
- clocks = CX23888_IR_REFCLK_FREQ / 1000000 * (u64) ns; /* millicycles */
- rem = do_div(clocks, 1000); /* /1000 = cycles */
- if (rem >= 1000 / 2)
- clocks++;
- return clocks;
-}
-
-static u16 pulse_clocks_to_clock_divider(u64 count)
-{
- do_div(count, (FIFO_RXTX << 2) | 0x3);
-
- /* net result needs to be rounded down and decremented by 1 */
- if (count > RXCLK_RCD + 1)
- count = RXCLK_RCD;
- else if (count < 2)
- count = 1;
- else
- count--;
- return (u16) count;
-}
-
-/*
- * IR Control Register helpers
- */
-enum tx_fifo_watermark {
- TX_FIFO_HALF_EMPTY = 0,
- TX_FIFO_EMPTY = CNTRL_TIC,
-};
-
-enum rx_fifo_watermark {
- RX_FIFO_HALF_FULL = 0,
- RX_FIFO_NOT_EMPTY = CNTRL_RIC,
-};
-
-static inline void control_tx_irq_watermark(struct cx23885_dev *dev,
- enum tx_fifo_watermark level)
-{
- cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_TIC, level);
-}
-
-static inline void control_rx_irq_watermark(struct cx23885_dev *dev,
- enum rx_fifo_watermark level)
-{
- cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_RIC, level);
-}
-
-static inline void control_tx_enable(struct cx23885_dev *dev, bool enable)
-{
- cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~(CNTRL_TXE | CNTRL_TFE),
- enable ? (CNTRL_TXE | CNTRL_TFE) : 0);
-}
-
-static inline void control_rx_enable(struct cx23885_dev *dev, bool enable)
-{
- cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~(CNTRL_RXE | CNTRL_RFE),
- enable ? (CNTRL_RXE | CNTRL_RFE) : 0);
-}
-
-static inline void control_tx_modulation_enable(struct cx23885_dev *dev,
- bool enable)
-{
- cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_MOD,
- enable ? CNTRL_MOD : 0);
-}
-
-static inline void control_rx_demodulation_enable(struct cx23885_dev *dev,
- bool enable)
-{
- cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_DMD,
- enable ? CNTRL_DMD : 0);
-}
-
-static inline void control_rx_s_edge_detection(struct cx23885_dev *dev,
- u32 edge_types)
-{
- cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_EDG_BOTH,
- edge_types & CNTRL_EDG_BOTH);
-}
-
-static void control_rx_s_carrier_window(struct cx23885_dev *dev,
- unsigned int carrier,
- unsigned int *carrier_range_low,
- unsigned int *carrier_range_high)
-{
- u32 v;
- unsigned int c16 = carrier * 16;
-
- if (*carrier_range_low < DIV_ROUND_CLOSEST(c16, 16 + 3)) {
- v = CNTRL_WIN_3_4;
- *carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 4);
- } else {
- v = CNTRL_WIN_3_3;
- *carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 3);
- }
-
- if (*carrier_range_high > DIV_ROUND_CLOSEST(c16, 16 - 3)) {
- v |= CNTRL_WIN_4_3;
- *carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 4);
- } else {
- v |= CNTRL_WIN_3_3;
- *carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 3);
- }
- cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_WIN, v);
-}
-
-static inline void control_tx_polarity_invert(struct cx23885_dev *dev,
- bool invert)
-{
- cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_CPL,
- invert ? CNTRL_CPL : 0);
-}
-
-static inline void control_tx_level_invert(struct cx23885_dev *dev,
- bool invert)
-{
- cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_IVO,
- invert ? CNTRL_IVO : 0);
-}
-
-/*
- * IR Rx & Tx Clock Register helpers
- */
-static unsigned int txclk_tx_s_carrier(struct cx23885_dev *dev,
- unsigned int freq,
- u16 *divider)
-{
- *divider = carrier_freq_to_clock_divider(freq);
- cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider);
- return clock_divider_to_carrier_freq(*divider);
-}
-
-static unsigned int rxclk_rx_s_carrier(struct cx23885_dev *dev,
- unsigned int freq,
- u16 *divider)
-{
- *divider = carrier_freq_to_clock_divider(freq);
- cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider);
- return clock_divider_to_carrier_freq(*divider);
-}
-
-static u32 txclk_tx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns,
- u16 *divider)
-{
- u64 pulse_clocks;
-
- if (ns > IR_MAX_DURATION)
- ns = IR_MAX_DURATION;
- pulse_clocks = ns_to_pulse_clocks(ns);
- *divider = pulse_clocks_to_clock_divider(pulse_clocks);
- cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider);
- return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider);
-}
-
-static u32 rxclk_rx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns,
- u16 *divider)
-{
- u64 pulse_clocks;
-
- if (ns > IR_MAX_DURATION)
- ns = IR_MAX_DURATION;
- pulse_clocks = ns_to_pulse_clocks(ns);
- *divider = pulse_clocks_to_clock_divider(pulse_clocks);
- cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider);
- return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider);
-}
-
-/*
- * IR Tx Carrier Duty Cycle register helpers
- */
-static unsigned int cduty_tx_s_duty_cycle(struct cx23885_dev *dev,
- unsigned int duty_cycle)
-{
- u32 n;
- n = DIV_ROUND_CLOSEST(duty_cycle * 100, 625); /* 16ths of 100% */
- if (n != 0)
- n--;
- if (n > 15)
- n = 15;
- cx23888_ir_write4(dev, CX23888_IR_CDUTY_REG, n);
- return DIV_ROUND_CLOSEST((n + 1) * 100, 16);
-}
-
-/*
- * IR Filter Register helpers
- */
-static u32 filter_rx_s_min_width(struct cx23885_dev *dev, u32 min_width_ns)
-{
- u32 count = ns_to_lpf_count(min_width_ns);
- cx23888_ir_write4(dev, CX23888_IR_FILTR_REG, count);
- return lpf_count_to_ns(count);
-}
-
-/*
- * IR IRQ Enable Register helpers
- */
-static inline void irqenable_rx(struct cx23885_dev *dev, u32 mask)
-{
- mask &= (IRQEN_RTE | IRQEN_ROE | IRQEN_RSE);
- cx23888_ir_and_or4(dev, CX23888_IR_IRQEN_REG,
- ~(IRQEN_RTE | IRQEN_ROE | IRQEN_RSE), mask);
-}
-
-static inline void irqenable_tx(struct cx23885_dev *dev, u32 mask)
-{
- mask &= IRQEN_TSE;
- cx23888_ir_and_or4(dev, CX23888_IR_IRQEN_REG, ~IRQEN_TSE, mask);
-}
-
-/*
- * V4L2 Subdevice IR Ops
- */
-static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
- bool *handled)
-{
- struct cx23888_ir_state *state = to_state(sd);
- struct cx23885_dev *dev = state->dev;
- unsigned long flags;
-
- u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG);
- u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
- u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG);
-
- union cx23888_ir_fifo_rec rx_data[FIFO_RX_DEPTH];
- unsigned int i, j, k;
- u32 events, v;
- int tsr, rsr, rto, ror, tse, rse, rte, roe, kror;
-
- tsr = stats & STATS_TSR; /* Tx FIFO Service Request */
- rsr = stats & STATS_RSR; /* Rx FIFO Service Request */
- rto = stats & STATS_RTO; /* Rx Pulse Width Timer Time Out */
- ror = stats & STATS_ROR; /* Rx FIFO Over Run */
-
- tse = irqen & IRQEN_TSE; /* Tx FIFO Service Request IRQ Enable */
- rse = irqen & IRQEN_RSE; /* Rx FIFO Service Reuqest IRQ Enable */
- rte = irqen & IRQEN_RTE; /* Rx Pulse Width Timer Time Out IRQ Enable */
- roe = irqen & IRQEN_ROE; /* Rx FIFO Over Run IRQ Enable */
-
- *handled = false;
- v4l2_dbg(2, ir_888_debug, sd, "IRQ Status: %s %s %s %s %s %s\n",
- tsr ? "tsr" : " ", rsr ? "rsr" : " ",
- rto ? "rto" : " ", ror ? "ror" : " ",
- stats & STATS_TBY ? "tby" : " ",
- stats & STATS_RBY ? "rby" : " ");
-
- v4l2_dbg(2, ir_888_debug, sd, "IRQ Enables: %s %s %s %s\n",
- tse ? "tse" : " ", rse ? "rse" : " ",
- rte ? "rte" : " ", roe ? "roe" : " ");
-
- /*
- * Transmitter interrupt service
- */
- if (tse && tsr) {
- /*
- * TODO:
- * Check the watermark threshold setting
- * Pull FIFO_TX_DEPTH or FIFO_TX_DEPTH/2 entries from tx_kfifo
- * Push the data to the hardware FIFO.
- * If there was nothing more to send in the tx_kfifo, disable
- * the TSR IRQ and notify the v4l2_device.
- * If there was something in the tx_kfifo, check the tx_kfifo
- * level and notify the v4l2_device, if it is low.
- */
- /* For now, inhibit TSR interrupt until Tx is implemented */
- irqenable_tx(dev, 0);
- events = V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ;
- v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_TX_NOTIFY, &events);
- *handled = true;
- }
-
- /*
- * Receiver interrupt service
- */
- kror = 0;
- if ((rse && rsr) || (rte && rto)) {
- /*
- * Receive data on RSR to clear the STATS_RSR.
- * Receive data on RTO, since we may not have yet hit the RSR
- * watermark when we receive the RTO.
- */
- for (i = 0, v = FIFO_RX_NDV;
- (v & FIFO_RX_NDV) && !kror; i = 0) {
- for (j = 0;
- (v & FIFO_RX_NDV) && j < FIFO_RX_DEPTH; j++) {
- v = cx23888_ir_read4(dev, CX23888_IR_FIFO_REG);
- rx_data[i].hw_fifo_data = v & ~FIFO_RX_NDV;
- i++;
- }
- if (i == 0)
- break;
- j = i * sizeof(union cx23888_ir_fifo_rec);
- k = kfifo_in_locked(&state->rx_kfifo,
- (unsigned char *) rx_data, j,
- &state->rx_kfifo_lock);
- if (k != j)
- kror++; /* rx_kfifo over run */
- }
- *handled = true;
- }
-
- events = 0;
- v = 0;
- if (kror) {
- events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN;
- v4l2_err(sd, "IR receiver software FIFO overrun\n");
- }
- if (roe && ror) {
- /*
- * The RX FIFO Enable (CNTRL_RFE) must be toggled to clear
- * the Rx FIFO Over Run status (STATS_ROR)
- */
- v |= CNTRL_RFE;
- events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN;
- v4l2_err(sd, "IR receiver hardware FIFO overrun\n");
- }
- if (rte && rto) {
- /*
- * The IR Receiver Enable (CNTRL_RXE) must be toggled to clear
- * the Rx Pulse Width Timer Time Out (STATS_RTO)
- */
- v |= CNTRL_RXE;
- events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED;
- }
- if (v) {
- /* Clear STATS_ROR & STATS_RTO as needed by reseting hardware */
- cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl & ~v);
- cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl);
- *handled = true;
- }
-
- spin_lock_irqsave(&state->rx_kfifo_lock, flags);
- if (kfifo_len(&state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2)
- events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
- spin_unlock_irqrestore(&state->rx_kfifo_lock, flags);
-
- if (events)
- v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events);
- return 0;
-}
-
-/* Receiver */
-static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
- ssize_t *num)
-{
- struct cx23888_ir_state *state = to_state(sd);
- bool invert = (bool) atomic_read(&state->rx_invert);
- u16 divider = (u16) atomic_read(&state->rxclk_divider);
-
- unsigned int i, n;
- union cx23888_ir_fifo_rec *p;
- unsigned u, v, w;
-
- n = count / sizeof(union cx23888_ir_fifo_rec)
- * sizeof(union cx23888_ir_fifo_rec);
- if (n == 0) {
- *num = 0;
- return 0;
- }
-
- n = kfifo_out_locked(&state->rx_kfifo, buf, n, &state->rx_kfifo_lock);
-
- n /= sizeof(union cx23888_ir_fifo_rec);
- *num = n * sizeof(union cx23888_ir_fifo_rec);
-
- for (p = (union cx23888_ir_fifo_rec *) buf, i = 0; i < n; p++, i++) {
-
- if ((p->hw_fifo_data & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) {
- /* Assume RTO was because of no IR light input */
- u = 0;
- w = 1;
- } else {
- u = (p->hw_fifo_data & FIFO_RXTX_LVL) ? 1 : 0;
- if (invert)
- u = u ? 0 : 1;
- w = 0;
- }
-
- v = (unsigned) pulse_width_count_to_ns(
- (u16) (p->hw_fifo_data & FIFO_RXTX), divider);
- if (v > IR_MAX_DURATION)
- v = IR_MAX_DURATION;
-
- init_ir_raw_event(&p->ir_core_data);
- p->ir_core_data.pulse = u;
- p->ir_core_data.duration = v;
- p->ir_core_data.timeout = w;
-
- v4l2_dbg(2, ir_888_debug, sd, "rx read: %10u ns %s %s\n",
- v, u ? "mark" : "space", w ? "(timed out)" : "");
- if (w)
- v4l2_dbg(2, ir_888_debug, sd, "rx read: end of rx\n");
- }
- return 0;
-}
-
-static int cx23888_ir_rx_g_parameters(struct v4l2_subdev *sd,
- struct v4l2_subdev_ir_parameters *p)
-{
- struct cx23888_ir_state *state = to_state(sd);
- mutex_lock(&state->rx_params_lock);
- memcpy(p, &state->rx_params, sizeof(struct v4l2_subdev_ir_parameters));
- mutex_unlock(&state->rx_params_lock);
- return 0;
-}
-
-static int cx23888_ir_rx_shutdown(struct v4l2_subdev *sd)
-{
- struct cx23888_ir_state *state = to_state(sd);
- struct cx23885_dev *dev = state->dev;
-
- mutex_lock(&state->rx_params_lock);
-
- /* Disable or slow down all IR Rx circuits and counters */
- irqenable_rx(dev, 0);
- control_rx_enable(dev, false);
- control_rx_demodulation_enable(dev, false);
- control_rx_s_edge_detection(dev, CNTRL_EDG_NONE);
- filter_rx_s_min_width(dev, 0);
- cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, RXCLK_RCD);
-
- state->rx_params.shutdown = true;
-
- mutex_unlock(&state->rx_params_lock);
- return 0;
-}
-
-static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd,
- struct v4l2_subdev_ir_parameters *p)
-{
- struct cx23888_ir_state *state = to_state(sd);
- struct cx23885_dev *dev = state->dev;
- struct v4l2_subdev_ir_parameters *o = &state->rx_params;
- u16 rxclk_divider;
-
- if (p->shutdown)
- return cx23888_ir_rx_shutdown(sd);
-
- if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH)
- return -ENOSYS;
-
- mutex_lock(&state->rx_params_lock);
-
- o->shutdown = p->shutdown;
-
- o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
-
- o->bytes_per_data_element = p->bytes_per_data_element
- = sizeof(union cx23888_ir_fifo_rec);
-
- /* Before we tweak the hardware, we have to disable the receiver */
- irqenable_rx(dev, 0);
- control_rx_enable(dev, false);
-
- control_rx_demodulation_enable(dev, p->modulation);
- o->modulation = p->modulation;
-
- if (p->modulation) {
- p->carrier_freq = rxclk_rx_s_carrier(dev, p->carrier_freq,
- &rxclk_divider);
-
- o->carrier_freq = p->carrier_freq;
-
- o->duty_cycle = p->duty_cycle = 50;
-
- control_rx_s_carrier_window(dev, p->carrier_freq,
- &p->carrier_range_lower,
- &p->carrier_range_upper);
- o->carrier_range_lower = p->carrier_range_lower;
- o->carrier_range_upper = p->carrier_range_upper;
-
- p->max_pulse_width =
- (u32) pulse_width_count_to_ns(FIFO_RXTX, rxclk_divider);
- } else {
- p->max_pulse_width =
- rxclk_rx_s_max_pulse_width(dev, p->max_pulse_width,
- &rxclk_divider);
- }
- o->max_pulse_width = p->max_pulse_width;
- atomic_set(&state->rxclk_divider, rxclk_divider);
-
- p->noise_filter_min_width =
- filter_rx_s_min_width(dev, p->noise_filter_min_width);
- o->noise_filter_min_width = p->noise_filter_min_width;
-
- p->resolution = clock_divider_to_resolution(rxclk_divider);
- o->resolution = p->resolution;
-
- /* FIXME - make this dependent on resolution for better performance */
- control_rx_irq_watermark(dev, RX_FIFO_HALF_FULL);
-
- control_rx_s_edge_detection(dev, CNTRL_EDG_BOTH);
-
- o->invert_level = p->invert_level;
- atomic_set(&state->rx_invert, p->invert_level);
-
- o->interrupt_enable = p->interrupt_enable;
- o->enable = p->enable;
- if (p->enable) {
- unsigned long flags;
-
- spin_lock_irqsave(&state->rx_kfifo_lock, flags);
- kfifo_reset(&state->rx_kfifo);
- /* reset tx_fifo too if there is one... */
- spin_unlock_irqrestore(&state->rx_kfifo_lock, flags);
- if (p->interrupt_enable)
- irqenable_rx(dev, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE);
- control_rx_enable(dev, p->enable);
- }
-
- mutex_unlock(&state->rx_params_lock);
- return 0;
-}
-
-/* Transmitter */
-static int cx23888_ir_tx_write(struct v4l2_subdev *sd, u8 *buf, size_t count,
- ssize_t *num)
-{
- struct cx23888_ir_state *state = to_state(sd);
- struct cx23885_dev *dev = state->dev;
- /* For now enable the Tx FIFO Service interrupt & pretend we did work */
- irqenable_tx(dev, IRQEN_TSE);
- *num = count;
- return 0;
-}
-
-static int cx23888_ir_tx_g_parameters(struct v4l2_subdev *sd,
- struct v4l2_subdev_ir_parameters *p)
-{
- struct cx23888_ir_state *state = to_state(sd);
- mutex_lock(&state->tx_params_lock);
- memcpy(p, &state->tx_params, sizeof(struct v4l2_subdev_ir_parameters));
- mutex_unlock(&state->tx_params_lock);
- return 0;
-}
-
-static int cx23888_ir_tx_shutdown(struct v4l2_subdev *sd)
-{
- struct cx23888_ir_state *state = to_state(sd);
- struct cx23885_dev *dev = state->dev;
-
- mutex_lock(&state->tx_params_lock);
-
- /* Disable or slow down all IR Tx circuits and counters */
- irqenable_tx(dev, 0);
- control_tx_enable(dev, false);
- control_tx_modulation_enable(dev, false);
- cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, TXCLK_TCD);
-
- state->tx_params.shutdown = true;
-
- mutex_unlock(&state->tx_params_lock);
- return 0;
-}
-
-static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd,
- struct v4l2_subdev_ir_parameters *p)
-{
- struct cx23888_ir_state *state = to_state(sd);
- struct cx23885_dev *dev = state->dev;
- struct v4l2_subdev_ir_parameters *o = &state->tx_params;
- u16 txclk_divider;
-
- if (p->shutdown)
- return cx23888_ir_tx_shutdown(sd);
-
- if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH)
- return -ENOSYS;
-
- mutex_lock(&state->tx_params_lock);
-
- o->shutdown = p->shutdown;
-
- o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
-
- o->bytes_per_data_element = p->bytes_per_data_element
- = sizeof(union cx23888_ir_fifo_rec);
-
- /* Before we tweak the hardware, we have to disable the transmitter */
- irqenable_tx(dev, 0);
- control_tx_enable(dev, false);
-
- control_tx_modulation_enable(dev, p->modulation);
- o->modulation = p->modulation;
-
- if (p->modulation) {
- p->carrier_freq = txclk_tx_s_carrier(dev, p->carrier_freq,
- &txclk_divider);
- o->carrier_freq = p->carrier_freq;
-
- p->duty_cycle = cduty_tx_s_duty_cycle(dev, p->duty_cycle);
- o->duty_cycle = p->duty_cycle;
-
- p->max_pulse_width =
- (u32) pulse_width_count_to_ns(FIFO_RXTX, txclk_divider);
- } else {
- p->max_pulse_width =
- txclk_tx_s_max_pulse_width(dev, p->max_pulse_width,
- &txclk_divider);
- }
- o->max_pulse_width = p->max_pulse_width;
- atomic_set(&state->txclk_divider, txclk_divider);
-
- p->resolution = clock_divider_to_resolution(txclk_divider);
- o->resolution = p->resolution;
-
- /* FIXME - make this dependent on resolution for better performance */
- control_tx_irq_watermark(dev, TX_FIFO_HALF_EMPTY);
-
- control_tx_polarity_invert(dev, p->invert_carrier_sense);
- o->invert_carrier_sense = p->invert_carrier_sense;
-
- control_tx_level_invert(dev, p->invert_level);
- o->invert_level = p->invert_level;
-
- o->interrupt_enable = p->interrupt_enable;
- o->enable = p->enable;
- if (p->enable) {
- if (p->interrupt_enable)
- irqenable_tx(dev, IRQEN_TSE);
- control_tx_enable(dev, p->enable);
- }
-
- mutex_unlock(&state->tx_params_lock);
- return 0;
-}
-
-
-/*
- * V4L2 Subdevice Core Ops
- */
-static int cx23888_ir_log_status(struct v4l2_subdev *sd)
-{
- struct cx23888_ir_state *state = to_state(sd);
- struct cx23885_dev *dev = state->dev;
- char *s;
- int i, j;
-
- u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG);
- u32 txclk = cx23888_ir_read4(dev, CX23888_IR_TXCLK_REG) & TXCLK_TCD;
- u32 rxclk = cx23888_ir_read4(dev, CX23888_IR_RXCLK_REG) & RXCLK_RCD;
- u32 cduty = cx23888_ir_read4(dev, CX23888_IR_CDUTY_REG) & CDUTY_CDC;
- u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG);
- u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
- u32 filtr = cx23888_ir_read4(dev, CX23888_IR_FILTR_REG) & FILTR_LPF;
-
- v4l2_info(sd, "IR Receiver:\n");
- v4l2_info(sd, "\tEnabled: %s\n",
- cntrl & CNTRL_RXE ? "yes" : "no");
- v4l2_info(sd, "\tDemodulation from a carrier: %s\n",
- cntrl & CNTRL_DMD ? "enabled" : "disabled");
- v4l2_info(sd, "\tFIFO: %s\n",
- cntrl & CNTRL_RFE ? "enabled" : "disabled");
- switch (cntrl & CNTRL_EDG) {
- case CNTRL_EDG_NONE:
- s = "disabled";
- break;
- case CNTRL_EDG_FALL:
- s = "falling edge";
- break;
- case CNTRL_EDG_RISE:
- s = "rising edge";
- break;
- case CNTRL_EDG_BOTH:
- s = "rising & falling edges";
- break;
- default:
- s = "??? edge";
- break;
- }
- v4l2_info(sd, "\tPulse timers' start/stop trigger: %s\n", s);
- v4l2_info(sd, "\tFIFO data on pulse timer overflow: %s\n",
- cntrl & CNTRL_R ? "not loaded" : "overflow marker");
- v4l2_info(sd, "\tFIFO interrupt watermark: %s\n",
- cntrl & CNTRL_RIC ? "not empty" : "half full or greater");
- v4l2_info(sd, "\tLoopback mode: %s\n",
- cntrl & CNTRL_LBM ? "loopback active" : "normal receive");
- if (cntrl & CNTRL_DMD) {
- v4l2_info(sd, "\tExpected carrier (16 clocks): %u Hz\n",
- clock_divider_to_carrier_freq(rxclk));
- switch (cntrl & CNTRL_WIN) {
- case CNTRL_WIN_3_3:
- i = 3;
- j = 3;
- break;
- case CNTRL_WIN_4_3:
- i = 4;
- j = 3;
- break;
- case CNTRL_WIN_3_4:
- i = 3;
- j = 4;
- break;
- case CNTRL_WIN_4_4:
- i = 4;
- j = 4;
- break;
- default:
- i = 0;
- j = 0;
- break;
- }
- v4l2_info(sd, "\tNext carrier edge window: 16 clocks "
- "-%1d/+%1d, %u to %u Hz\n", i, j,
- clock_divider_to_freq(rxclk, 16 + j),
- clock_divider_to_freq(rxclk, 16 - i));
- }
- v4l2_info(sd, "\tMax measurable pulse width: %u us, %llu ns\n",
- pulse_width_count_to_us(FIFO_RXTX, rxclk),
- pulse_width_count_to_ns(FIFO_RXTX, rxclk));
- v4l2_info(sd, "\tLow pass filter: %s\n",
- filtr ? "enabled" : "disabled");
- if (filtr)
- v4l2_info(sd, "\tMin acceptable pulse width (LPF): %u us, "
- "%u ns\n",
- lpf_count_to_us(filtr),
- lpf_count_to_ns(filtr));
- v4l2_info(sd, "\tPulse width timer timed-out: %s\n",
- stats & STATS_RTO ? "yes" : "no");
- v4l2_info(sd, "\tPulse width timer time-out intr: %s\n",
- irqen & IRQEN_RTE ? "enabled" : "disabled");
- v4l2_info(sd, "\tFIFO overrun: %s\n",
- stats & STATS_ROR ? "yes" : "no");
- v4l2_info(sd, "\tFIFO overrun interrupt: %s\n",
- irqen & IRQEN_ROE ? "enabled" : "disabled");
- v4l2_info(sd, "\tBusy: %s\n",
- stats & STATS_RBY ? "yes" : "no");
- v4l2_info(sd, "\tFIFO service requested: %s\n",
- stats & STATS_RSR ? "yes" : "no");
- v4l2_info(sd, "\tFIFO service request interrupt: %s\n",
- irqen & IRQEN_RSE ? "enabled" : "disabled");
-
- v4l2_info(sd, "IR Transmitter:\n");
- v4l2_info(sd, "\tEnabled: %s\n",
- cntrl & CNTRL_TXE ? "yes" : "no");
- v4l2_info(sd, "\tModulation onto a carrier: %s\n",
- cntrl & CNTRL_MOD ? "enabled" : "disabled");
- v4l2_info(sd, "\tFIFO: %s\n",
- cntrl & CNTRL_TFE ? "enabled" : "disabled");
- v4l2_info(sd, "\tFIFO interrupt watermark: %s\n",
- cntrl & CNTRL_TIC ? "not empty" : "half full or less");
- v4l2_info(sd, "\tOutput pin level inversion %s\n",
- cntrl & CNTRL_IVO ? "yes" : "no");
- v4l2_info(sd, "\tCarrier polarity: %s\n",
- cntrl & CNTRL_CPL ? "space:burst mark:noburst"
- : "space:noburst mark:burst");
- if (cntrl & CNTRL_MOD) {
- v4l2_info(sd, "\tCarrier (16 clocks): %u Hz\n",
- clock_divider_to_carrier_freq(txclk));
- v4l2_info(sd, "\tCarrier duty cycle: %2u/16\n",
- cduty + 1);
- }
- v4l2_info(sd, "\tMax pulse width: %u us, %llu ns\n",
- pulse_width_count_to_us(FIFO_RXTX, txclk),
- pulse_width_count_to_ns(FIFO_RXTX, txclk));
- v4l2_info(sd, "\tBusy: %s\n",
- stats & STATS_TBY ? "yes" : "no");
- v4l2_info(sd, "\tFIFO service requested: %s\n",
- stats & STATS_TSR ? "yes" : "no");
- v4l2_info(sd, "\tFIFO service request interrupt: %s\n",
- irqen & IRQEN_TSE ? "enabled" : "disabled");
-
- return 0;
-}
-
-static inline int cx23888_ir_dbg_match(const struct v4l2_dbg_match *match)
-{
- return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 2;
-}
-
-static int cx23888_ir_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct cx23888_ir_state *state = to_state(sd);
-
- if (cx23888_ir_dbg_match(&chip->match)) {
- chip->ident = state->id;
- chip->revision = state->rev;
- }
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int cx23888_ir_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct cx23888_ir_state *state = to_state(sd);
- u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg;
-
- if (!cx23888_ir_dbg_match(&reg->match))
- return -EINVAL;
- if ((addr & 0x3) != 0)
- return -EINVAL;
- if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG)
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- reg->size = 4;
- reg->val = cx23888_ir_read4(state->dev, addr);
- return 0;
-}
-
-static int cx23888_ir_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct cx23888_ir_state *state = to_state(sd);
- u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg;
-
- if (!cx23888_ir_dbg_match(&reg->match))
- return -EINVAL;
- if ((addr & 0x3) != 0)
- return -EINVAL;
- if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG)
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- cx23888_ir_write4(state->dev, addr, reg->val);
- return 0;
-}
-#endif
-
-static const struct v4l2_subdev_core_ops cx23888_ir_core_ops = {
- .g_chip_ident = cx23888_ir_g_chip_ident,
- .log_status = cx23888_ir_log_status,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = cx23888_ir_g_register,
- .s_register = cx23888_ir_s_register,
-#endif
- .interrupt_service_routine = cx23888_ir_irq_handler,
-};
-
-static const struct v4l2_subdev_ir_ops cx23888_ir_ir_ops = {
- .rx_read = cx23888_ir_rx_read,
- .rx_g_parameters = cx23888_ir_rx_g_parameters,
- .rx_s_parameters = cx23888_ir_rx_s_parameters,
-
- .tx_write = cx23888_ir_tx_write,
- .tx_g_parameters = cx23888_ir_tx_g_parameters,
- .tx_s_parameters = cx23888_ir_tx_s_parameters,
-};
-
-static const struct v4l2_subdev_ops cx23888_ir_controller_ops = {
- .core = &cx23888_ir_core_ops,
- .ir = &cx23888_ir_ir_ops,
-};
-
-static const struct v4l2_subdev_ir_parameters default_rx_params = {
- .bytes_per_data_element = sizeof(union cx23888_ir_fifo_rec),
- .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
-
- .enable = false,
- .interrupt_enable = false,
- .shutdown = true,
-
- .modulation = true,
- .carrier_freq = 36000, /* 36 kHz - RC-5, RC-6, and RC-6A carrier */
-
- /* RC-5: 666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */
- /* RC-6A: 333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */
- .noise_filter_min_width = 333333, /* ns */
- .carrier_range_lower = 35000,
- .carrier_range_upper = 37000,
- .invert_level = false,
-};
-
-static const struct v4l2_subdev_ir_parameters default_tx_params = {
- .bytes_per_data_element = sizeof(union cx23888_ir_fifo_rec),
- .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
-
- .enable = false,
- .interrupt_enable = false,
- .shutdown = true,
-
- .modulation = true,
- .carrier_freq = 36000, /* 36 kHz - RC-5 carrier */
- .duty_cycle = 25, /* 25 % - RC-5 carrier */
- .invert_level = false,
- .invert_carrier_sense = false,
-};
-
-int cx23888_ir_probe(struct cx23885_dev *dev)
-{
- struct cx23888_ir_state *state;
- struct v4l2_subdev *sd;
- struct v4l2_subdev_ir_parameters default_params;
- int ret;
-
- state = kzalloc(sizeof(struct cx23888_ir_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
-
- spin_lock_init(&state->rx_kfifo_lock);
- if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL))
- return -ENOMEM;
-
- state->dev = dev;
- state->id = V4L2_IDENT_CX23888_IR;
- state->rev = 0;
- sd = &state->sd;
-
- v4l2_subdev_init(sd, &cx23888_ir_controller_ops);
- v4l2_set_subdevdata(sd, state);
- /* FIXME - fix the formatting of dev->v4l2_dev.name and use it */
- snprintf(sd->name, sizeof(sd->name), "%s/888-ir", dev->name);
- sd->grp_id = CX23885_HW_888_IR;
-
- ret = v4l2_device_register_subdev(&dev->v4l2_dev, sd);
- if (ret == 0) {
- /*
- * Ensure no interrupts arrive from '888 specific conditions,
- * since we ignore them in this driver to have commonality with
- * similar IR controller cores.
- */
- cx23888_ir_write4(dev, CX23888_IR_IRQEN_REG, 0);
-
- mutex_init(&state->rx_params_lock);
- memcpy(&default_params, &default_rx_params,
- sizeof(struct v4l2_subdev_ir_parameters));
- v4l2_subdev_call(sd, ir, rx_s_parameters, &default_params);
-
- mutex_init(&state->tx_params_lock);
- memcpy(&default_params, &default_tx_params,
- sizeof(struct v4l2_subdev_ir_parameters));
- v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params);
- } else {
- kfifo_free(&state->rx_kfifo);
- }
- return ret;
-}
-
-int cx23888_ir_remove(struct cx23885_dev *dev)
-{
- struct v4l2_subdev *sd;
- struct cx23888_ir_state *state;
-
- sd = cx23885_find_hw(dev, CX23885_HW_888_IR);
- if (sd == NULL)
- return -ENODEV;
-
- cx23888_ir_rx_shutdown(sd);
- cx23888_ir_tx_shutdown(sd);
-
- state = to_state(sd);
- v4l2_device_unregister_subdev(sd);
- kfifo_free(&state->rx_kfifo);
- kfree(state);
- /* Nothing more to free() as state held the actual v4l2_subdev object */
- return 0;
-}
diff --git a/drivers/media/video/cx23885/cx23888-ir.h b/drivers/media/video/cx23885/cx23888-ir.h
deleted file mode 100644
index d2de41caaf1..00000000000
--- a/drivers/media/video/cx23885/cx23888-ir.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Driver for the Conexant CX23885/7/8 PCIe bridge
- *
- * CX23888 Integrated Consumer Infrared Controller
- *
- * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#ifndef _CX23888_IR_H_
-#define _CX23888_IR_H_
-int cx23888_ir_probe(struct cx23885_dev *dev);
-int cx23888_ir_remove(struct cx23885_dev *dev);
-#endif
diff --git a/drivers/media/video/cx23885/netup-eeprom.c b/drivers/media/video/cx23885/netup-eeprom.c
deleted file mode 100644
index 98a48f50068..00000000000
--- a/drivers/media/video/cx23885/netup-eeprom.c
+++ /dev/null
@@ -1,107 +0,0 @@
-
-/*
- * netup-eeprom.c
- *
- * 24LC02 EEPROM driver in conjunction with NetUP Dual DVB-S2 CI card
- *
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#
-#include "cx23885.h"
-#include "netup-eeprom.h"
-
-#define EEPROM_I2C_ADDR 0x50
-
-int netup_eeprom_read(struct i2c_adapter *i2c_adap, u8 addr)
-{
- int ret;
- unsigned char buf[2];
-
- /* Read from EEPROM */
- struct i2c_msg msg[] = {
- {
- .addr = EEPROM_I2C_ADDR,
- .flags = 0,
- .buf = &buf[0],
- .len = 1
- }, {
- .addr = EEPROM_I2C_ADDR,
- .flags = I2C_M_RD,
- .buf = &buf[1],
- .len = 1
- }
-
- };
-
- buf[0] = addr;
- buf[1] = 0x0;
-
- ret = i2c_transfer(i2c_adap, msg, 2);
-
- if (ret != 2) {
- printk(KERN_ERR "eeprom i2c read error, status=%d\n", ret);
- return -1;
- }
-
- return buf[1];
-};
-
-int netup_eeprom_write(struct i2c_adapter *i2c_adap, u8 addr, u8 data)
-{
- int ret;
- unsigned char bufw[2];
-
- /* Write into EEPROM */
- struct i2c_msg msg[] = {
- {
- .addr = EEPROM_I2C_ADDR,
- .flags = 0,
- .buf = &bufw[0],
- .len = 2
- }
- };
-
- bufw[0] = addr;
- bufw[1] = data;
-
- ret = i2c_transfer(i2c_adap, msg, 1);
-
- if (ret != 1) {
- printk(KERN_ERR "eeprom i2c write error, status=%d\n", ret);
- return -1;
- }
-
- mdelay(10); /* prophylactic delay, datasheet write cycle time = 5 ms */
- return 0;
-};
-
-void netup_get_card_info(struct i2c_adapter *i2c_adap,
- struct netup_card_info *cinfo)
-{
- int i, j;
-
- cinfo->rev = netup_eeprom_read(i2c_adap, 63);
-
- for (i = 64, j = 0; i < 70; i++, j++)
- cinfo->port[0].mac[j] = netup_eeprom_read(i2c_adap, i);
-
- for (i = 70, j = 0; i < 76; i++, j++)
- cinfo->port[1].mac[j] = netup_eeprom_read(i2c_adap, i);
-};
diff --git a/drivers/media/video/cx23885/netup-eeprom.h b/drivers/media/video/cx23885/netup-eeprom.h
deleted file mode 100644
index 13926e18feb..00000000000
--- a/drivers/media/video/cx23885/netup-eeprom.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * netup-eeprom.h
- *
- * 24LC02 EEPROM driver in conjunction with NetUP Dual DVB-S2 CI card
- *
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef NETUP_EEPROM_H
-#define NETUP_EEPROM_H
-
-struct netup_port_info {
- u8 mac[6];/* card MAC address */
-};
-
-struct netup_card_info {
- struct netup_port_info port[2];/* ports - 1,2 */
- u8 rev;/* card revision */
-};
-
-extern int netup_eeprom_read(struct i2c_adapter *i2c_adap, u8 addr);
-extern int netup_eeprom_write(struct i2c_adapter *i2c_adap, u8 addr, u8 data);
-extern void netup_get_card_info(struct i2c_adapter *i2c_adap,
- struct netup_card_info *cinfo);
-
-#endif
diff --git a/drivers/media/video/cx23885/netup-init.c b/drivers/media/video/cx23885/netup-init.c
deleted file mode 100644
index f4893e69cd8..00000000000
--- a/drivers/media/video/cx23885/netup-init.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * netup-init.c
- *
- * NetUP Dual DVB-S2 CI driver
- *
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
- * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx23885.h"
-
-static void i2c_av_write(struct i2c_adapter *i2c, u16 reg, u8 val)
-{
- int ret;
- u8 buf[3];
- struct i2c_msg msg = {
- .addr = 0x88 >> 1,
- .flags = 0,
- .buf = buf,
- .len = 3
- };
-
- buf[0] = reg >> 8;
- buf[1] = reg & 0xff;
- buf[2] = val;
-
- ret = i2c_transfer(i2c, &msg, 1);
-
- if (ret != 1)
- printk(KERN_ERR "%s: i2c write error!\n", __func__);
-}
-
-static void i2c_av_write4(struct i2c_adapter *i2c, u16 reg, u32 val)
-{
- int ret;
- u8 buf[6];
- struct i2c_msg msg = {
- .addr = 0x88 >> 1,
- .flags = 0,
- .buf = buf,
- .len = 6
- };
-
- buf[0] = reg >> 8;
- buf[1] = reg & 0xff;
- buf[2] = val & 0xff;
- buf[3] = (val >> 8) & 0xff;
- buf[4] = (val >> 16) & 0xff;
- buf[5] = val >> 24;
-
- ret = i2c_transfer(i2c, &msg, 1);
-
- if (ret != 1)
- printk(KERN_ERR "%s: i2c write error!\n", __func__);
-}
-
-static u8 i2c_av_read(struct i2c_adapter *i2c, u16 reg)
-{
- int ret;
- u8 buf[2];
- struct i2c_msg msg = {
- .addr = 0x88 >> 1,
- .flags = 0,
- .buf = buf,
- .len = 2
- };
-
- buf[0] = reg >> 8;
- buf[1] = reg & 0xff;
-
- ret = i2c_transfer(i2c, &msg, 1);
-
- if (ret != 1)
- printk(KERN_ERR "%s: i2c write error!\n", __func__);
-
- msg.flags = I2C_M_RD;
- msg.len = 1;
-
- ret = i2c_transfer(i2c, &msg, 1);
-
- if (ret != 1)
- printk(KERN_ERR "%s: i2c read error!\n", __func__);
-
- return buf[0];
-}
-
-static void i2c_av_and_or(struct i2c_adapter *i2c, u16 reg, unsigned and_mask,
- u8 or_value)
-{
- i2c_av_write(i2c, reg, (i2c_av_read(i2c, reg) & and_mask) | or_value);
-}
-/* set 27MHz on AUX_CLK */
-void netup_initialize(struct cx23885_dev *dev)
-{
- struct cx23885_i2c *i2c_bus = &dev->i2c_bus[2];
- struct i2c_adapter *i2c = &i2c_bus->i2c_adap;
-
- /* Stop microcontroller */
- i2c_av_and_or(i2c, 0x803, ~0x10, 0x00);
-
- /* Aux PLL frac for 27 MHz */
- i2c_av_write4(i2c, 0x114, 0xea0eb3);
-
- /* Aux PLL int for 27 MHz */
- i2c_av_write4(i2c, 0x110, 0x090319);
-
- /* start microcontroller */
- i2c_av_and_or(i2c, 0x803, ~0x10, 0x10);
-}
diff --git a/drivers/media/video/cx23885/netup-init.h b/drivers/media/video/cx23885/netup-init.h
deleted file mode 100644
index d26ae4b1590..00000000000
--- a/drivers/media/video/cx23885/netup-init.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * netup-init.h
- *
- * NetUP Dual DVB-S2 CI driver
- *
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
- * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-extern void netup_initialize(struct cx23885_dev *dev);
diff --git a/drivers/media/video/cx25821/Kconfig b/drivers/media/video/cx25821/Kconfig
deleted file mode 100644
index 5f6b5421371..00000000000
--- a/drivers/media/video/cx25821/Kconfig
+++ /dev/null
@@ -1,34 +0,0 @@
-config VIDEO_CX25821
- tristate "Conexant cx25821 support"
- depends on DVB_CORE && VIDEO_DEV && PCI && I2C
- select I2C_ALGOBIT
- select VIDEO_BTCX
- select VIDEO_TVEEPROM
- depends on RC_CORE
- select VIDEOBUF_DVB
- select VIDEOBUF_DMA_SG
- select VIDEO_CX25840
- select VIDEO_CX2341X
- ---help---
- This is a video4linux driver for Conexant 25821 based
- TV cards.
-
- To compile this driver as a module, choose M here: the
- module will be called cx25821
-
-config VIDEO_CX25821_ALSA
- tristate "Conexant 25821 DMA audio support"
- depends on VIDEO_CX25821 && SND && EXPERIMENTAL
- select SND_PCM
- ---help---
- This is a video4linux driver for direct (DMA) audio on
- Conexant 25821 based capture cards using ALSA.
-
- It only works with boards with function 01 enabled.
- To check if your board supports, use lspci -n.
- If supported, you should see 14f1:8801 or 14f1:8811
- PCI device.
-
- To compile this driver as a module, choose M here: the
- module will be called cx25821-alsa.
-
diff --git a/drivers/media/video/cx25821/Makefile b/drivers/media/video/cx25821/Makefile
deleted file mode 100644
index aedde18c68f..00000000000
--- a/drivers/media/video/cx25821/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-cx25821-y := cx25821-core.o cx25821-cards.o cx25821-i2c.o \
- cx25821-gpio.o cx25821-medusa-video.o \
- cx25821-video.o cx25821-video-upstream.o \
- cx25821-video-upstream-ch2.o \
- cx25821-audio-upstream.o
-
-obj-$(CONFIG_VIDEO_CX25821) += cx25821.o
-obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o
-
-ccflags-y := -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/video/cx25821/cx25821-alsa.c b/drivers/media/video/cx25821/cx25821-alsa.c
deleted file mode 100644
index 1858a45dd08..00000000000
--- a/drivers/media/video/cx25821/cx25821-alsa.c
+++ /dev/null
@@ -1,784 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on SAA713x ALSA driver and CX88 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/vmalloc.h>
-#include <linux/dma-mapping.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/control.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "cx25821.h"
-#include "cx25821-reg.h"
-
-#define AUDIO_SRAM_CHANNEL SRAM_CH08
-
-#define dprintk(level, fmt, arg...) \
-do { \
- if (debug >= level) \
- pr_info("%s/1: " fmt, chip->dev->name, ##arg); \
-} while (0)
-#define dprintk_core(level, fmt, arg...) \
-do { \
- if (debug >= level) \
- printk(KERN_DEBUG "%s/1: " fmt, chip->dev->name, ##arg); \
-} while (0)
-
-/****************************************************************************
- Data type declarations - Can be moded to a header file later
- ****************************************************************************/
-
-static struct snd_card *snd_cx25821_cards[SNDRV_CARDS];
-static int devno;
-
-struct cx25821_audio_buffer {
- unsigned int bpl;
- struct btcx_riscmem risc;
- struct videobuf_dmabuf dma;
-};
-
-struct cx25821_audio_dev {
- struct cx25821_dev *dev;
- struct cx25821_dmaqueue q;
-
- /* pci i/o */
- struct pci_dev *pci;
-
- /* audio controls */
- int irq;
-
- struct snd_card *card;
-
- unsigned long iobase;
- spinlock_t reg_lock;
- atomic_t count;
-
- unsigned int dma_size;
- unsigned int period_size;
- unsigned int num_periods;
-
- struct videobuf_dmabuf *dma_risc;
-
- struct cx25821_audio_buffer *buf;
-
- struct snd_pcm_substream *substream;
-};
-
-
-/****************************************************************************
- Module global static vars
- ****************************************************************************/
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = { 1, [1 ... (SNDRV_CARDS - 1)] = 1 };
-
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable cx25821 soundcard. default enabled.");
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for cx25821 capture interface(s).");
-
-/****************************************************************************
- Module macros
- ****************************************************************************/
-
-MODULE_DESCRIPTION("ALSA driver module for cx25821 based capture cards");
-MODULE_AUTHOR("Hiep Huynh");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Conexant,25821}"); /* "{{Conexant,23881}," */
-
-static unsigned int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debug messages");
-
-/****************************************************************************
- Module specific funtions
- ****************************************************************************/
-/* Constants taken from cx88-reg.h */
-#define AUD_INT_DN_RISCI1 (1 << 0)
-#define AUD_INT_UP_RISCI1 (1 << 1)
-#define AUD_INT_RDS_DN_RISCI1 (1 << 2)
-#define AUD_INT_DN_RISCI2 (1 << 4) /* yes, 3 is skipped */
-#define AUD_INT_UP_RISCI2 (1 << 5)
-#define AUD_INT_RDS_DN_RISCI2 (1 << 6)
-#define AUD_INT_DN_SYNC (1 << 12)
-#define AUD_INT_UP_SYNC (1 << 13)
-#define AUD_INT_RDS_DN_SYNC (1 << 14)
-#define AUD_INT_OPC_ERR (1 << 16)
-#define AUD_INT_BER_IRQ (1 << 20)
-#define AUD_INT_MCHG_IRQ (1 << 21)
-#define GP_COUNT_CONTROL_RESET 0x3
-
-#define PCI_MSK_AUD_EXT (1 << 4)
-#define PCI_MSK_AUD_INT (1 << 3)
-/*
- * BOARD Specific: Sets audio DMA
- */
-
-static int _cx25821_start_audio_dma(struct cx25821_audio_dev *chip)
-{
- struct cx25821_audio_buffer *buf = chip->buf;
- struct cx25821_dev *dev = chip->dev;
- struct sram_channel *audio_ch =
- &cx25821_sram_channels[AUDIO_SRAM_CHANNEL];
- u32 tmp = 0;
-
- /* enable output on the GPIO 0 for the MCLK ADC (Audio) */
- cx25821_set_gpiopin_direction(chip->dev, 0, 0);
-
- /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */
- cx_clear(AUD_INT_DMA_CTL,
- FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
-
- /* setup fifo + format - out channel */
- cx25821_sram_channel_setup_audio(chip->dev, audio_ch, buf->bpl,
- buf->risc.dma);
-
- /* sets bpl size */
- cx_write(AUD_A_LNGTH, buf->bpl);
-
- /* reset counter */
- /* GP_COUNT_CONTROL_RESET = 0x3 */
- cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET);
- atomic_set(&chip->count, 0);
-
- /* Set the input mode to 16-bit */
- tmp = cx_read(AUD_A_CFG);
- cx_write(AUD_A_CFG, tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE |
- FLD_AUD_CLK_ENABLE);
-
- /*
- pr_info("DEBUG: Start audio DMA, %d B/line, cmds_start(0x%x)= %d lines/FIFO, %d periods, %d byte buffer\n",
- buf->bpl, audio_ch->cmds_start,
- cx_read(audio_ch->cmds_start + 12)>>1,
- chip->num_periods, buf->bpl * chip->num_periods);
- */
-
- /* Enables corresponding bits at AUD_INT_STAT */
- cx_write(AUD_A_INT_MSK, FLD_AUD_DST_RISCI1 | FLD_AUD_DST_OF |
- FLD_AUD_DST_SYNC | FLD_AUD_DST_OPC_ERR);
-
- /* Clean any pending interrupt bits already set */
- cx_write(AUD_A_INT_STAT, ~0);
-
- /* enable audio irqs */
- cx_set(PCI_INT_MSK, chip->dev->pci_irqmask | PCI_MSK_AUD_INT);
-
- /* Turn on audio downstream fifo and risc enable 0x101 */
- tmp = cx_read(AUD_INT_DMA_CTL);
- cx_set(AUD_INT_DMA_CTL, tmp |
- (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN));
-
- mdelay(100);
- return 0;
-}
-
-/*
- * BOARD Specific: Resets audio DMA
- */
-static int _cx25821_stop_audio_dma(struct cx25821_audio_dev *chip)
-{
- struct cx25821_dev *dev = chip->dev;
-
- /* stop dma */
- cx_clear(AUD_INT_DMA_CTL,
- FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
-
- /* disable irqs */
- cx_clear(PCI_INT_MSK, PCI_MSK_AUD_INT);
- cx_clear(AUD_A_INT_MSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC |
- AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1);
-
- return 0;
-}
-
-#define MAX_IRQ_LOOP 50
-
-/*
- * BOARD Specific: IRQ dma bits
- */
-static char *cx25821_aud_irqs[32] = {
- "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */
- NULL, /* reserved */
- "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */
- NULL, /* reserved */
- "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */
- NULL, /* reserved */
- "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */
- NULL, /* reserved */
- "opc_err", "par_err", "rip_err", /* 16-18 */
- "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */
-};
-
-/*
- * BOARD Specific: Threats IRQ audio specific calls
- */
-static void cx25821_aud_irq(struct cx25821_audio_dev *chip, u32 status,
- u32 mask)
-{
- struct cx25821_dev *dev = chip->dev;
-
- if (0 == (status & mask))
- return;
-
- cx_write(AUD_A_INT_STAT, status);
- if (debug > 1 || (status & mask & ~0xff))
- cx25821_print_irqbits(dev->name, "irq aud", cx25821_aud_irqs,
- ARRAY_SIZE(cx25821_aud_irqs), status, mask);
-
- /* risc op code error */
- if (status & AUD_INT_OPC_ERR) {
- pr_warn("WARNING %s/1: Audio risc op code error\n", dev->name);
-
- cx_clear(AUD_INT_DMA_CTL,
- FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
- cx25821_sram_channel_dump_audio(dev,
- &cx25821_sram_channels[AUDIO_SRAM_CHANNEL]);
- }
- if (status & AUD_INT_DN_SYNC) {
- pr_warn("WARNING %s: Downstream sync error!\n", dev->name);
- cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET);
- return;
- }
-
- /* risc1 downstream */
- if (status & AUD_INT_DN_RISCI1) {
- atomic_set(&chip->count, cx_read(AUD_A_GPCNT));
- snd_pcm_period_elapsed(chip->substream);
- }
-}
-
-/*
- * BOARD Specific: Handles IRQ calls
- */
-static irqreturn_t cx25821_irq(int irq, void *dev_id)
-{
- struct cx25821_audio_dev *chip = dev_id;
- struct cx25821_dev *dev = chip->dev;
- u32 status, pci_status;
- u32 audint_status, audint_mask;
- int loop, handled = 0;
-
- audint_status = cx_read(AUD_A_INT_STAT);
- audint_mask = cx_read(AUD_A_INT_MSK);
- status = cx_read(PCI_INT_STAT);
-
- for (loop = 0; loop < 1; loop++) {
- status = cx_read(PCI_INT_STAT);
- if (0 == status) {
- status = cx_read(PCI_INT_STAT);
- audint_status = cx_read(AUD_A_INT_STAT);
- audint_mask = cx_read(AUD_A_INT_MSK);
-
- if (status) {
- handled = 1;
- cx_write(PCI_INT_STAT, status);
-
- cx25821_aud_irq(chip, audint_status,
- audint_mask);
- break;
- } else {
- goto out;
- }
- }
-
- handled = 1;
- cx_write(PCI_INT_STAT, status);
-
- cx25821_aud_irq(chip, audint_status, audint_mask);
- }
-
- pci_status = cx_read(PCI_INT_STAT);
-
- if (handled)
- cx_write(PCI_INT_STAT, pci_status);
-
-out:
- return IRQ_RETVAL(handled);
-}
-
-static int dsp_buffer_free(struct cx25821_audio_dev *chip)
-{
- BUG_ON(!chip->dma_size);
-
- dprintk(2, "Freeing buffer\n");
- videobuf_dma_unmap(&chip->pci->dev, chip->dma_risc);
- videobuf_dma_free(chip->dma_risc);
- btcx_riscmem_free(chip->pci, &chip->buf->risc);
- kfree(chip->buf);
-
- chip->dma_risc = NULL;
- chip->dma_size = 0;
-
- return 0;
-}
-
-/****************************************************************************
- ALSA PCM Interface
- ****************************************************************************/
-
-/*
- * Digital hardware definition
- */
-#define DEFAULT_FIFO_SIZE 384
-static struct snd_pcm_hardware snd_cx25821_digital_hw = {
- .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
-
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- /* Analog audio output will be full of clicks and pops if there
- are not exactly four lines in the SRAM FIFO buffer. */
- .period_bytes_min = DEFAULT_FIFO_SIZE / 3,
- .period_bytes_max = DEFAULT_FIFO_SIZE / 3,
- .periods_min = 1,
- .periods_max = AUDIO_LINE_SIZE,
- /* 128 * 128 = 16384 = 1024 * 16 */
- .buffer_bytes_max = (AUDIO_LINE_SIZE * AUDIO_LINE_SIZE),
-};
-
-/*
- * audio pcm capture open callback
- */
-static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream)
-{
- struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
- unsigned int bpl = 0;
-
- if (!chip) {
- pr_err("DEBUG: cx25821 can't find device struct. Can't proceed with open\n");
- return -ENODEV;
- }
-
- err = snd_pcm_hw_constraint_pow2(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0)
- goto _error;
-
- chip->substream = substream;
-
- runtime->hw = snd_cx25821_digital_hw;
-
- if (cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size !=
- DEFAULT_FIFO_SIZE) {
- /* since there are 3 audio Clusters */
- bpl = cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size / 3;
- bpl &= ~7; /* must be multiple of 8 */
-
- if (bpl > AUDIO_LINE_SIZE)
- bpl = AUDIO_LINE_SIZE;
-
- runtime->hw.period_bytes_min = bpl;
- runtime->hw.period_bytes_max = bpl;
- }
-
- return 0;
-_error:
- dprintk(1, "Error opening PCM!\n");
- return err;
-}
-
-/*
- * audio close callback
- */
-static int snd_cx25821_close(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-/*
- * hw_params callback
- */
-static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream);
- struct videobuf_dmabuf *dma;
-
- struct cx25821_audio_buffer *buf;
- int ret;
-
- if (substream->runtime->dma_area) {
- dsp_buffer_free(chip);
- substream->runtime->dma_area = NULL;
- }
-
- chip->period_size = params_period_bytes(hw_params);
- chip->num_periods = params_periods(hw_params);
- chip->dma_size = chip->period_size * params_periods(hw_params);
-
- BUG_ON(!chip->dma_size);
- BUG_ON(chip->num_periods & (chip->num_periods - 1));
-
- buf = kzalloc(sizeof(*buf), GFP_KERNEL);
- if (NULL == buf)
- return -ENOMEM;
-
- if (chip->period_size > AUDIO_LINE_SIZE)
- chip->period_size = AUDIO_LINE_SIZE;
-
- buf->bpl = chip->period_size;
-
- dma = &buf->dma;
- videobuf_dma_init(dma);
- ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
- (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT));
- if (ret < 0)
- goto error;
-
- ret = videobuf_dma_map(&chip->pci->dev, dma);
- if (ret < 0)
- goto error;
-
- ret = cx25821_risc_databuffer_audio(chip->pci, &buf->risc, dma->sglist,
- chip->period_size, chip->num_periods, 1);
- if (ret < 0) {
- pr_info("DEBUG: ERROR after cx25821_risc_databuffer_audio()\n");
- goto error;
- }
-
- /* Loop back to start of program */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- chip->buf = buf;
- chip->dma_risc = dma;
-
- substream->runtime->dma_area = chip->dma_risc->vaddr;
- substream->runtime->dma_bytes = chip->dma_size;
- substream->runtime->dma_addr = 0;
-
- return 0;
-
-error:
- kfree(buf);
- return ret;
-}
-
-/*
- * hw free callback
- */
-static int snd_cx25821_hw_free(struct snd_pcm_substream *substream)
-{
- struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream);
-
- if (substream->runtime->dma_area) {
- dsp_buffer_free(chip);
- substream->runtime->dma_area = NULL;
- }
-
- return 0;
-}
-
-/*
- * prepare callback
- */
-static int snd_cx25821_prepare(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-/*
- * trigger callback
- */
-static int snd_cx25821_card_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream);
- int err = 0;
-
- /* Local interrupts are already disabled by ALSA */
- spin_lock(&chip->reg_lock);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- err = _cx25821_start_audio_dma(chip);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- err = _cx25821_stop_audio_dma(chip);
- break;
- default:
- err = -EINVAL;
- break;
- }
-
- spin_unlock(&chip->reg_lock);
-
- return err;
-}
-
-/*
- * pointer callback
- */
-static snd_pcm_uframes_t snd_cx25821_pointer(struct snd_pcm_substream
- *substream)
-{
- struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- u16 count;
-
- count = atomic_read(&chip->count);
-
- return runtime->period_size * (count & (runtime->periods - 1));
-}
-
-/*
- * page callback (needed for mmap)
- */
-static struct page *snd_cx25821_page(struct snd_pcm_substream *substream,
- unsigned long offset)
-{
- void *pageptr = substream->runtime->dma_area + offset;
-
- return vmalloc_to_page(pageptr);
-}
-
-/*
- * operators
- */
-static struct snd_pcm_ops snd_cx25821_pcm_ops = {
- .open = snd_cx25821_pcm_open,
- .close = snd_cx25821_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cx25821_hw_params,
- .hw_free = snd_cx25821_hw_free,
- .prepare = snd_cx25821_prepare,
- .trigger = snd_cx25821_card_trigger,
- .pointer = snd_cx25821_pointer,
- .page = snd_cx25821_page,
-};
-
-/*
- * ALSA create a PCM device: Called when initializing the board.
- * Sets up the name and hooks up the callbacks
- */
-static int snd_cx25821_pcm(struct cx25821_audio_dev *chip, int device,
- char *name)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
- if (err < 0) {
- pr_info("ERROR: FAILED snd_pcm_new() in %s\n", __func__);
- return err;
- }
- pcm->private_data = chip;
- pcm->info_flags = 0;
- strcpy(pcm->name, name);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx25821_pcm_ops);
-
- return 0;
-}
-
-/****************************************************************************
- Basic Flow for Sound Devices
- ****************************************************************************/
-
-/*
- * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio
- * Only boards with eeprom and byte 1 at eeprom=1 have it
- */
-
-static DEFINE_PCI_DEVICE_TABLE(cx25821_audio_pci_tbl) = {
- {0x14f1, 0x0920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, cx25821_audio_pci_tbl);
-
-/*
- * Not used in the function snd_cx25821_dev_free so removing
- * from the file.
- */
-/*
-static int snd_cx25821_free(struct cx25821_audio_dev *chip)
-{
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
-
- cx25821_dev_unregister(chip->dev);
- pci_disable_device(chip->pci);
-
- return 0;
-}
-*/
-
-/*
- * Component Destructor
- */
-static void snd_cx25821_dev_free(struct snd_card *card)
-{
- struct cx25821_audio_dev *chip = card->private_data;
-
- /* snd_cx25821_free(chip); */
- snd_card_free(chip->card);
-}
-
-/*
- * Alsa Constructor - Component probe
- */
-static int cx25821_audio_initdev(struct cx25821_dev *dev)
-{
- struct snd_card *card;
- struct cx25821_audio_dev *chip;
- int err;
-
- if (devno >= SNDRV_CARDS) {
- pr_info("DEBUG ERROR: devno >= SNDRV_CARDS %s\n", __func__);
- return -ENODEV;
- }
-
- if (!enable[devno]) {
- ++devno;
- pr_info("DEBUG ERROR: !enable[devno] %s\n", __func__);
- return -ENOENT;
- }
-
- err = snd_card_create(index[devno], id[devno], THIS_MODULE,
- sizeof(struct cx25821_audio_dev), &card);
- if (err < 0) {
- pr_info("DEBUG ERROR: cannot create snd_card_new in %s\n",
- __func__);
- return err;
- }
-
- strcpy(card->driver, "cx25821");
-
- /* Card "creation" */
- card->private_free = snd_cx25821_dev_free;
- chip = card->private_data;
- spin_lock_init(&chip->reg_lock);
-
- chip->dev = dev;
- chip->card = card;
- chip->pci = dev->pci;
- chip->iobase = pci_resource_start(dev->pci, 0);
-
- chip->irq = dev->pci->irq;
-
- err = request_irq(dev->pci->irq, cx25821_irq,
- IRQF_SHARED, chip->dev->name, chip);
-
- if (err < 0) {
- pr_err("ERROR %s: can't get IRQ %d for ALSA\n", chip->dev->name,
- dev->pci->irq);
- goto error;
- }
-
- err = snd_cx25821_pcm(chip, 0, "cx25821 Digital");
- if (err < 0) {
- pr_info("DEBUG ERROR: cannot create snd_cx25821_pcm %s\n",
- __func__);
- goto error;
- }
-
- snd_card_set_dev(card, &chip->pci->dev);
-
- strcpy(card->shortname, "cx25821");
- sprintf(card->longname, "%s at 0x%lx irq %d", chip->dev->name,
- chip->iobase, chip->irq);
- strcpy(card->mixername, "CX25821");
-
- pr_info("%s/%i: ALSA support for cx25821 boards\n", card->driver,
- devno);
-
- err = snd_card_register(card);
- if (err < 0) {
- pr_info("DEBUG ERROR: cannot register sound card %s\n",
- __func__);
- goto error;
- }
-
- snd_cx25821_cards[devno] = card;
-
- devno++;
- return 0;
-
-error:
- snd_card_free(card);
- return err;
-}
-
-/****************************************************************************
- LINUX MODULE INIT
- ****************************************************************************/
-static void cx25821_audio_fini(void)
-{
- snd_card_free(snd_cx25821_cards[0]);
-}
-
-/*
- * Module initializer
- *
- * Loops through present saa7134 cards, and assigns an ALSA device
- * to each one
- *
- */
-static int cx25821_alsa_init(void)
-{
- struct cx25821_dev *dev = NULL;
- struct list_head *list;
-
- mutex_lock(&cx25821_devlist_mutex);
- list_for_each(list, &cx25821_devlist) {
- dev = list_entry(list, struct cx25821_dev, devlist);
- cx25821_audio_initdev(dev);
- }
- mutex_unlock(&cx25821_devlist_mutex);
-
- if (dev == NULL)
- pr_info("ERROR ALSA: no cx25821 cards found\n");
-
- return 0;
-
-}
-
-late_initcall(cx25821_alsa_init);
-module_exit(cx25821_audio_fini);
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/cx25821/cx25821-audio-upstream.c b/drivers/media/video/cx25821/cx25821-audio-upstream.c
deleted file mode 100644
index 8b2a99975c2..00000000000
--- a/drivers/media/video/cx25821/cx25821-audio-upstream.c
+++ /dev/null
@@ -1,778 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "cx25821-video.h"
-#include "cx25821-audio-upstream.h"
-
-#include <linux/fs.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/syscalls.h>
-#include <linux/file.h>
-#include <linux/fcntl.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
-MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
-MODULE_LICENSE("GPL");
-
-static int _intr_msk = FLD_AUD_SRC_RISCI1 | FLD_AUD_SRC_OF |
- FLD_AUD_SRC_SYNC | FLD_AUD_SRC_OPC_ERR;
-
-int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev,
- struct sram_channel *ch,
- unsigned int bpl, u32 risc)
-{
- unsigned int i, lines;
- u32 cdt;
-
- if (ch->cmds_start == 0) {
- cx_write(ch->ptr1_reg, 0);
- cx_write(ch->ptr2_reg, 0);
- cx_write(ch->cnt2_reg, 0);
- cx_write(ch->cnt1_reg, 0);
- return 0;
- }
-
- bpl = (bpl + 7) & ~7; /* alignment */
- cdt = ch->cdt;
- lines = ch->fifo_size / bpl;
-
- if (lines > 3)
- lines = 3;
-
- BUG_ON(lines < 2);
-
- /* write CDT */
- for (i = 0; i < lines; i++) {
- cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
- cx_write(cdt + 16 * i + 4, 0);
- cx_write(cdt + 16 * i + 8, 0);
- cx_write(cdt + 16 * i + 12, 0);
- }
-
- /* write CMDS */
- cx_write(ch->cmds_start + 0, risc);
-
- cx_write(ch->cmds_start + 4, 0);
- cx_write(ch->cmds_start + 8, cdt);
- cx_write(ch->cmds_start + 12, AUDIO_CDT_SIZE_QW);
- cx_write(ch->cmds_start + 16, ch->ctrl_start);
-
- /* IQ size */
- cx_write(ch->cmds_start + 20, AUDIO_IQ_SIZE_DW);
-
- for (i = 24; i < 80; i += 4)
- cx_write(ch->cmds_start + i, 0);
-
- /* fill registers */
- cx_write(ch->ptr1_reg, ch->fifo_start);
- cx_write(ch->ptr2_reg, cdt);
- cx_write(ch->cnt2_reg, AUDIO_CDT_SIZE_QW);
- cx_write(ch->cnt1_reg, AUDIO_CLUSTER_SIZE_QW - 1);
-
- return 0;
-}
-
-static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev,
- __le32 *rp,
- dma_addr_t databuf_phys_addr,
- unsigned int bpl,
- int fifo_enable)
-{
- unsigned int line;
- struct sram_channel *sram_ch =
- dev->channels[dev->_audio_upstream_channel].sram_channels;
- int offset = 0;
-
- /* scan lines */
- for (line = 0; line < LINES_PER_AUDIO_BUFFER; line++) {
- *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
- *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
-
- /* Check if we need to enable the FIFO
- * after the first 3 lines.
- * For the upstream audio channel,
- * the risc engine will enable the FIFO */
- if (fifo_enable && line == 2) {
- *(rp++) = RISC_WRITECR;
- *(rp++) = sram_ch->dma_ctl;
- *(rp++) = sram_ch->fld_aud_fifo_en;
- *(rp++) = 0x00000020;
- }
-
- offset += AUDIO_LINE_SIZE;
- }
-
- return rp;
-}
-
-int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev,
- struct pci_dev *pci,
- unsigned int bpl, unsigned int lines)
-{
- __le32 *rp;
- int fifo_enable = 0;
- int frame = 0, i = 0;
- int frame_size = AUDIO_DATA_BUF_SZ;
- int databuf_offset = 0;
- int risc_flag = RISC_CNT_INC;
- dma_addr_t risc_phys_jump_addr;
-
- /* Virtual address of Risc buffer program */
- rp = dev->_risc_virt_addr;
-
- /* sync instruction */
- *(rp++) = cpu_to_le32(RISC_RESYNC | AUDIO_SYNC_LINE);
-
- for (frame = 0; frame < NUM_AUDIO_FRAMES; frame++) {
- databuf_offset = frame_size * frame;
-
- if (frame == 0) {
- fifo_enable = 1;
- risc_flag = RISC_CNT_RESET;
- } else {
- fifo_enable = 0;
- risc_flag = RISC_CNT_INC;
- }
-
- /* Calculate physical jump address */
- if ((frame + 1) == NUM_AUDIO_FRAMES) {
- risc_phys_jump_addr =
- dev->_risc_phys_start_addr +
- RISC_SYNC_INSTRUCTION_SIZE;
- } else {
- risc_phys_jump_addr =
- dev->_risc_phys_start_addr +
- RISC_SYNC_INSTRUCTION_SIZE +
- AUDIO_RISC_DMA_BUF_SIZE * (frame + 1);
- }
-
- rp = cx25821_risc_field_upstream_audio(dev, rp,
- dev->_audiodata_buf_phys_addr + databuf_offset,
- bpl, fifo_enable);
-
- if (USE_RISC_NOOP_AUDIO) {
- for (i = 0; i < NUM_NO_OPS; i++)
- *(rp++) = cpu_to_le32(RISC_NOOP);
- }
-
- /* Loop to (Nth)FrameRISC or to Start of Risc program &
- * generate IRQ */
- *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
- *(rp++) = cpu_to_le32(risc_phys_jump_addr);
- *(rp++) = cpu_to_le32(0);
-
- /* Recalculate virtual address based on frame index */
- rp = dev->_risc_virt_addr + RISC_SYNC_INSTRUCTION_SIZE / 4 +
- (AUDIO_RISC_DMA_BUF_SIZE * (frame + 1) / 4);
- }
-
- return 0;
-}
-
-void cx25821_free_memory_audio(struct cx25821_dev *dev)
-{
- if (dev->_risc_virt_addr) {
- pci_free_consistent(dev->pci, dev->_audiorisc_size,
- dev->_risc_virt_addr, dev->_risc_phys_addr);
- dev->_risc_virt_addr = NULL;
- }
-
- if (dev->_audiodata_buf_virt_addr) {
- pci_free_consistent(dev->pci, dev->_audiodata_buf_size,
- dev->_audiodata_buf_virt_addr,
- dev->_audiodata_buf_phys_addr);
- dev->_audiodata_buf_virt_addr = NULL;
- }
-}
-
-void cx25821_stop_upstream_audio(struct cx25821_dev *dev)
-{
- struct sram_channel *sram_ch =
- dev->channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B].sram_channels;
- u32 tmp = 0;
-
- if (!dev->_audio_is_running) {
- printk(KERN_DEBUG
- pr_fmt("No audio file is currently running so return!\n"));
- return;
- }
- /* Disable RISC interrupts */
- cx_write(sram_ch->int_msk, 0);
-
- /* Turn OFF risc and fifo enable in AUD_DMA_CNTRL */
- tmp = cx_read(sram_ch->dma_ctl);
- cx_write(sram_ch->dma_ctl,
- tmp & ~(sram_ch->fld_aud_fifo_en | sram_ch->fld_aud_risc_en));
-
- /* Clear data buffer memory */
- if (dev->_audiodata_buf_virt_addr)
- memset(dev->_audiodata_buf_virt_addr, 0,
- dev->_audiodata_buf_size);
-
- dev->_audio_is_running = 0;
- dev->_is_first_audio_frame = 0;
- dev->_audioframe_count = 0;
- dev->_audiofile_status = END_OF_FILE;
-
- kfree(dev->_irq_audio_queues);
- dev->_irq_audio_queues = NULL;
-
- kfree(dev->_audiofilename);
-}
-
-void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev)
-{
- if (dev->_audio_is_running)
- cx25821_stop_upstream_audio(dev);
-
- cx25821_free_memory_audio(dev);
-}
-
-int cx25821_get_audio_data(struct cx25821_dev *dev,
- struct sram_channel *sram_ch)
-{
- struct file *myfile;
- int frame_index_temp = dev->_audioframe_index;
- int i = 0;
- int line_size = AUDIO_LINE_SIZE;
- int frame_size = AUDIO_DATA_BUF_SZ;
- int frame_offset = frame_size * frame_index_temp;
- ssize_t vfs_read_retval = 0;
- char mybuf[line_size];
- loff_t file_offset = dev->_audioframe_count * frame_size;
- loff_t pos;
- mm_segment_t old_fs;
-
- if (dev->_audiofile_status == END_OF_FILE)
- return 0;
-
- myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
-
- if (IS_ERR(myfile)) {
- const int open_errno = -PTR_ERR(myfile);
- pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
- __func__, dev->_audiofilename, open_errno);
- return PTR_ERR(myfile);
- } else {
- if (!(myfile->f_op)) {
- pr_err("%s(): File has no file operations registered!\n",
- __func__);
- filp_close(myfile, NULL);
- return -EIO;
- }
-
- if (!myfile->f_op->read) {
- pr_err("%s(): File has no READ operations registered!\n",
- __func__);
- filp_close(myfile, NULL);
- return -EIO;
- }
-
- pos = myfile->f_pos;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- for (i = 0; i < dev->_audio_lines_count; i++) {
- pos = file_offset;
-
- vfs_read_retval = vfs_read(myfile, mybuf, line_size,
- &pos);
-
- if (vfs_read_retval > 0 && vfs_read_retval == line_size
- && dev->_audiodata_buf_virt_addr != NULL) {
- memcpy((void *)(dev->_audiodata_buf_virt_addr +
- frame_offset / 4), mybuf,
- vfs_read_retval);
- }
-
- file_offset += vfs_read_retval;
- frame_offset += vfs_read_retval;
-
- if (vfs_read_retval < line_size) {
- pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
- __func__);
- break;
- }
- }
-
- if (i > 0)
- dev->_audioframe_count++;
-
- dev->_audiofile_status = (vfs_read_retval == line_size) ?
- IN_PROGRESS : END_OF_FILE;
-
- set_fs(old_fs);
- filp_close(myfile, NULL);
- }
-
- return 0;
-}
-
-static void cx25821_audioups_handler(struct work_struct *work)
-{
- struct cx25821_dev *dev = container_of(work, struct cx25821_dev,
- _audio_work_entry);
-
- if (!dev) {
- pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n",
- __func__);
- return;
- }
-
- cx25821_get_audio_data(dev, dev->channels[dev->_audio_upstream_channel].
- sram_channels);
-}
-
-int cx25821_openfile_audio(struct cx25821_dev *dev,
- struct sram_channel *sram_ch)
-{
- struct file *myfile;
- int i = 0, j = 0;
- int line_size = AUDIO_LINE_SIZE;
- ssize_t vfs_read_retval = 0;
- char mybuf[line_size];
- loff_t pos;
- loff_t offset = (unsigned long)0;
- mm_segment_t old_fs;
-
- myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
-
- if (IS_ERR(myfile)) {
- const int open_errno = -PTR_ERR(myfile);
- pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
- __func__, dev->_audiofilename, open_errno);
- return PTR_ERR(myfile);
- } else {
- if (!(myfile->f_op)) {
- pr_err("%s(): File has no file operations registered!\n",
- __func__);
- filp_close(myfile, NULL);
- return -EIO;
- }
-
- if (!myfile->f_op->read) {
- pr_err("%s(): File has no READ operations registered!\n",
- __func__);
- filp_close(myfile, NULL);
- return -EIO;
- }
-
- pos = myfile->f_pos;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- for (j = 0; j < NUM_AUDIO_FRAMES; j++) {
- for (i = 0; i < dev->_audio_lines_count; i++) {
- pos = offset;
-
- vfs_read_retval = vfs_read(myfile, mybuf,
- line_size, &pos);
-
- if (vfs_read_retval > 0 &&
- vfs_read_retval == line_size &&
- dev->_audiodata_buf_virt_addr != NULL) {
- memcpy((void *)(dev->
- _audiodata_buf_virt_addr
- + offset / 4), mybuf,
- vfs_read_retval);
- }
-
- offset += vfs_read_retval;
-
- if (vfs_read_retval < line_size) {
- pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
- __func__);
- break;
- }
- }
-
- if (i > 0)
- dev->_audioframe_count++;
-
- if (vfs_read_retval < line_size)
- break;
- }
-
- dev->_audiofile_status = (vfs_read_retval == line_size) ?
- IN_PROGRESS : END_OF_FILE;
-
- set_fs(old_fs);
- myfile->f_pos = 0;
- filp_close(myfile, NULL);
- }
-
- return 0;
-}
-
-static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev,
- struct sram_channel *sram_ch,
- int bpl)
-{
- int ret = 0;
- dma_addr_t dma_addr;
- dma_addr_t data_dma_addr;
-
- cx25821_free_memory_audio(dev);
-
- dev->_risc_virt_addr = pci_alloc_consistent(dev->pci,
- dev->audio_upstream_riscbuf_size, &dma_addr);
- dev->_risc_virt_start_addr = dev->_risc_virt_addr;
- dev->_risc_phys_start_addr = dma_addr;
- dev->_risc_phys_addr = dma_addr;
- dev->_audiorisc_size = dev->audio_upstream_riscbuf_size;
-
- if (!dev->_risc_virt_addr) {
- printk(KERN_DEBUG
- pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning\n"));
- return -ENOMEM;
- }
- /* Clear out memory at address */
- memset(dev->_risc_virt_addr, 0, dev->_audiorisc_size);
-
- /* For Audio Data buffer allocation */
- dev->_audiodata_buf_virt_addr = pci_alloc_consistent(dev->pci,
- dev->audio_upstream_databuf_size, &data_dma_addr);
- dev->_audiodata_buf_phys_addr = data_dma_addr;
- dev->_audiodata_buf_size = dev->audio_upstream_databuf_size;
-
- if (!dev->_audiodata_buf_virt_addr) {
- printk(KERN_DEBUG
- pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning\n"));
- return -ENOMEM;
- }
- /* Clear out memory at address */
- memset(dev->_audiodata_buf_virt_addr, 0, dev->_audiodata_buf_size);
-
- ret = cx25821_openfile_audio(dev, sram_ch);
- if (ret < 0)
- return ret;
-
- /* Creating RISC programs */
- ret = cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl,
- dev->_audio_lines_count);
- if (ret < 0) {
- printk(KERN_DEBUG
- pr_fmt("ERROR creating audio upstream RISC programs!\n"));
- goto error;
- }
-
- return 0;
-
-error:
- return ret;
-}
-
-int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
- u32 status)
-{
- int i = 0;
- u32 int_msk_tmp;
- struct sram_channel *channel = dev->channels[chan_num].sram_channels;
- dma_addr_t risc_phys_jump_addr;
- __le32 *rp;
-
- if (status & FLD_AUD_SRC_RISCI1) {
- /* Get interrupt_index of the program that interrupted */
- u32 prog_cnt = cx_read(channel->gpcnt);
-
- /* Since we've identified our IRQ, clear our bits from the
- * interrupt mask and interrupt status registers */
- cx_write(channel->int_msk, 0);
- cx_write(channel->int_stat, cx_read(channel->int_stat));
-
- spin_lock(&dev->slock);
-
- while (prog_cnt != dev->_last_index_irq) {
- /* Update _last_index_irq */
- if (dev->_last_index_irq < (NUMBER_OF_PROGRAMS - 1))
- dev->_last_index_irq++;
- else
- dev->_last_index_irq = 0;
-
- dev->_audioframe_index = dev->_last_index_irq;
-
- queue_work(dev->_irq_audio_queues,
- &dev->_audio_work_entry);
- }
-
- if (dev->_is_first_audio_frame) {
- dev->_is_first_audio_frame = 0;
-
- if (dev->_risc_virt_start_addr != NULL) {
- risc_phys_jump_addr =
- dev->_risc_phys_start_addr +
- RISC_SYNC_INSTRUCTION_SIZE +
- AUDIO_RISC_DMA_BUF_SIZE;
-
- rp = cx25821_risc_field_upstream_audio(dev,
- dev->_risc_virt_start_addr + 1,
- dev->_audiodata_buf_phys_addr,
- AUDIO_LINE_SIZE, FIFO_DISABLE);
-
- if (USE_RISC_NOOP_AUDIO) {
- for (i = 0; i < NUM_NO_OPS; i++) {
- *(rp++) =
- cpu_to_le32(RISC_NOOP);
- }
- }
- /* Jump to 2nd Audio Frame */
- *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 |
- RISC_CNT_RESET);
- *(rp++) = cpu_to_le32(risc_phys_jump_addr);
- *(rp++) = cpu_to_le32(0);
- }
- }
-
- spin_unlock(&dev->slock);
- } else {
- if (status & FLD_AUD_SRC_OF)
- pr_warn("%s(): Audio Received Overflow Error Interrupt!\n",
- __func__);
-
- if (status & FLD_AUD_SRC_SYNC)
- pr_warn("%s(): Audio Received Sync Error Interrupt!\n",
- __func__);
-
- if (status & FLD_AUD_SRC_OPC_ERR)
- pr_warn("%s(): Audio Received OpCode Error Interrupt!\n",
- __func__);
-
- /* Read and write back the interrupt status register to clear
- * our bits */
- cx_write(channel->int_stat, cx_read(channel->int_stat));
- }
-
- if (dev->_audiofile_status == END_OF_FILE) {
- pr_warn("EOF Channel Audio Framecount = %d\n",
- dev->_audioframe_count);
- return -1;
- }
- /* ElSE, set the interrupt mask register, re-enable irq. */
- int_msk_tmp = cx_read(channel->int_msk);
- cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
-
- return 0;
-}
-
-static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id)
-{
- struct cx25821_dev *dev = dev_id;
- u32 audio_status;
- int handled = 0;
- struct sram_channel *sram_ch;
-
- if (!dev)
- return -1;
-
- sram_ch = dev->channels[dev->_audio_upstream_channel].sram_channels;
-
- audio_status = cx_read(sram_ch->int_stat);
-
- /* Only deal with our interrupt */
- if (audio_status) {
- handled = cx25821_audio_upstream_irq(dev,
- dev->_audio_upstream_channel, audio_status);
- }
-
- if (handled < 0)
- cx25821_stop_upstream_audio(dev);
- else
- handled += handled;
-
- return IRQ_RETVAL(handled);
-}
-
-static void cx25821_wait_fifo_enable(struct cx25821_dev *dev,
- struct sram_channel *sram_ch)
-{
- int count = 0;
- u32 tmp;
-
- do {
- /* Wait 10 microsecond before checking to see if the FIFO is
- * turned ON. */
- udelay(10);
-
- tmp = cx_read(sram_ch->dma_ctl);
-
- /* 10 millisecond timeout */
- if (count++ > 1000) {
- pr_err("ERROR: %s() fifo is NOT turned on. Timeout!\n",
- __func__);
- return;
- }
-
- } while (!(tmp & sram_ch->fld_aud_fifo_en));
-
-}
-
-int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev,
- struct sram_channel *sram_ch)
-{
- u32 tmp = 0;
- int err = 0;
-
- /* Set the physical start address of the RISC program in the initial
- * program counter(IPC) member of the CMDS. */
- cx_write(sram_ch->cmds_start + 0, dev->_risc_phys_addr);
- /* Risc IPC High 64 bits 63-32 */
- cx_write(sram_ch->cmds_start + 4, 0);
-
- /* reset counter */
- cx_write(sram_ch->gpcnt_ctl, 3);
-
- /* Set the line length (It looks like we do not need to set the
- * line length) */
- cx_write(sram_ch->aud_length, AUDIO_LINE_SIZE & FLD_AUD_DST_LN_LNGTH);
-
- /* Set the input mode to 16-bit */
- tmp = cx_read(sram_ch->aud_cfg);
- tmp |= FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE |
- FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D |
- FLD_AUD_SONY_MODE;
- cx_write(sram_ch->aud_cfg, tmp);
-
- /* Read and write back the interrupt status register to clear it */
- tmp = cx_read(sram_ch->int_stat);
- cx_write(sram_ch->int_stat, tmp);
-
- /* Clear our bits from the interrupt status register. */
- cx_write(sram_ch->int_stat, _intr_msk);
-
- /* Set the interrupt mask register, enable irq. */
- cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
- tmp = cx_read(sram_ch->int_msk);
- cx_write(sram_ch->int_msk, tmp |= _intr_msk);
-
- err = request_irq(dev->pci->irq, cx25821_upstream_irq_audio,
- IRQF_SHARED, dev->name, dev);
- if (err < 0) {
- pr_err("%s: can't get upstream IRQ %d\n", dev->name,
- dev->pci->irq);
- goto fail_irq;
- }
-
- /* Start the DMA engine */
- tmp = cx_read(sram_ch->dma_ctl);
- cx_set(sram_ch->dma_ctl, tmp | sram_ch->fld_aud_risc_en);
-
- dev->_audio_is_running = 1;
- dev->_is_first_audio_frame = 1;
-
- /* The fifo_en bit turns on by the first Risc program */
- cx25821_wait_fifo_enable(dev, sram_ch);
-
- return 0;
-
-fail_irq:
- cx25821_dev_unregister(dev);
- return err;
-}
-
-int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
-{
- struct sram_channel *sram_ch;
- int retval = 0;
- int err = 0;
- int str_length = 0;
-
- if (dev->_audio_is_running) {
- pr_warn("Audio Channel is still running so return!\n");
- return 0;
- }
-
- dev->_audio_upstream_channel = channel_select;
- sram_ch = dev->channels[channel_select].sram_channels;
-
- /* Work queue */
- INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler);
- dev->_irq_audio_queues =
- create_singlethread_workqueue("cx25821_audioworkqueue");
-
- if (!dev->_irq_audio_queues) {
- printk(KERN_DEBUG
- pr_fmt("ERROR: create_singlethread_workqueue() for Audio FAILED!\n"));
- return -ENOMEM;
- }
-
- dev->_last_index_irq = 0;
- dev->_audio_is_running = 0;
- dev->_audioframe_count = 0;
- dev->_audiofile_status = RESET_STATUS;
- dev->_audio_lines_count = LINES_PER_AUDIO_BUFFER;
- _line_size = AUDIO_LINE_SIZE;
-
- if (dev->input_audiofilename) {
- str_length = strlen(dev->input_audiofilename);
- dev->_audiofilename = kmemdup(dev->input_audiofilename,
- str_length + 1, GFP_KERNEL);
-
- if (!dev->_audiofilename)
- goto error;
-
- /* Default if filename is empty string */
- if (strcmp(dev->input_audiofilename, "") == 0)
- dev->_audiofilename = "/root/audioGOOD.wav";
- } else {
- str_length = strlen(_defaultAudioName);
- dev->_audiofilename = kmemdup(_defaultAudioName,
- str_length + 1, GFP_KERNEL);
-
- if (!dev->_audiofilename)
- goto error;
- }
-
- retval = cx25821_sram_channel_setup_upstream_audio(dev, sram_ch,
- _line_size, 0);
-
- dev->audio_upstream_riscbuf_size =
- AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS +
- RISC_SYNC_INSTRUCTION_SIZE;
- dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS;
-
- /* Allocating buffers and prepare RISC program */
- retval = cx25821_audio_upstream_buffer_prepare(dev, sram_ch,
- _line_size);
- if (retval < 0) {
- pr_err("%s: Failed to set up Audio upstream buffers!\n",
- dev->name);
- goto error;
- }
- /* Start RISC engine */
- cx25821_start_audio_dma_upstream(dev, sram_ch);
-
- return 0;
-
-error:
- cx25821_dev_unregister(dev);
-
- return err;
-}
diff --git a/drivers/media/video/cx25821/cx25821-audio-upstream.h b/drivers/media/video/cx25821/cx25821-audio-upstream.h
deleted file mode 100644
index af2ae7c5815..00000000000
--- a/drivers/media/video/cx25821/cx25821-audio-upstream.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/mutex.h>
-#include <linux/workqueue.h>
-
-#define NUM_AUDIO_PROGS 8
-#define NUM_AUDIO_FRAMES 8
-#define END_OF_FILE 0
-#define IN_PROGRESS 1
-#define RESET_STATUS -1
-#define FIFO_DISABLE 0
-#define FIFO_ENABLE 1
-#define NUM_NO_OPS 4
-
-#define RISC_READ_INSTRUCTION_SIZE 12
-#define RISC_JUMP_INSTRUCTION_SIZE 12
-#define RISC_WRITECR_INSTRUCTION_SIZE 16
-#define RISC_SYNC_INSTRUCTION_SIZE 4
-#define DWORD_SIZE 4
-#define AUDIO_SYNC_LINE 4
-
-#define LINES_PER_AUDIO_BUFFER 15
-#define AUDIO_LINE_SIZE 128
-#define AUDIO_DATA_BUF_SZ (AUDIO_LINE_SIZE * LINES_PER_AUDIO_BUFFER)
-
-#define USE_RISC_NOOP_AUDIO 1
-
-#ifdef USE_RISC_NOOP_AUDIO
-#define AUDIO_RISC_DMA_BUF_SIZE \
- (LINES_PER_AUDIO_BUFFER * RISC_READ_INSTRUCTION_SIZE + \
- RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS * DWORD_SIZE + \
- RISC_JUMP_INSTRUCTION_SIZE)
-#endif
-
-#ifndef USE_RISC_NOOP_AUDIO
-#define AUDIO_RISC_DMA_BUF_SIZE \
- (LINES_PER_AUDIO_BUFFER * RISC_READ_INSTRUCTION_SIZE + \
- RISC_WRITECR_INSTRUCTION_SIZE + RISC_JUMP_INSTRUCTION_SIZE)
-#endif
-
-static int _line_size;
-char *_defaultAudioName = "/root/audioGOOD.wav";
diff --git a/drivers/media/video/cx25821/cx25821-audio.h b/drivers/media/video/cx25821/cx25821-audio.h
deleted file mode 100644
index 1fc2d24f511..00000000000
--- a/drivers/media/video/cx25821/cx25821-audio.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __CX25821_AUDIO_H__
-#define __CX25821_AUDIO_H__
-
-#define USE_RISC_NOOP 1
-#define LINES_PER_BUFFER 15
-#define AUDIO_LINE_SIZE 128
-
-/* Number of buffer programs to use at once. */
-#define NUMBER_OF_PROGRAMS 8
-
-/*
- * Max size of the RISC program for a buffer. - worst case is 2 writes per line
- * Space is also added for the 4 no-op instructions added on the end.
- */
-#ifndef USE_RISC_NOOP
-#define MAX_BUFFER_PROGRAM_SIZE \
- (2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE + \
- RISC_WRITECR_INSTRUCTION_SIZE * 4)
-#endif
-
-/* MAE 12 July 2005 Try to use NOOP RISC instruction instead */
-#ifdef USE_RISC_NOOP
-#define MAX_BUFFER_PROGRAM_SIZE \
- (2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE + \
- RISC_NOOP_INSTRUCTION_SIZE * 4)
-#endif
-
-/* Sizes of various instructions in bytes. Used when adding instructions. */
-#define RISC_WRITE_INSTRUCTION_SIZE 12
-#define RISC_JUMP_INSTRUCTION_SIZE 12
-#define RISC_SKIP_INSTRUCTION_SIZE 4
-#define RISC_SYNC_INSTRUCTION_SIZE 4
-#define RISC_WRITECR_INSTRUCTION_SIZE 16
-#define RISC_NOOP_INSTRUCTION_SIZE 4
-
-#define MAX_AUDIO_DMA_BUFFER_SIZE \
- (MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS + \
- RISC_SYNC_INSTRUCTION_SIZE)
-
-#endif
diff --git a/drivers/media/video/cx25821/cx25821-biffuncs.h b/drivers/media/video/cx25821/cx25821-biffuncs.h
deleted file mode 100644
index 9326a7c729e..00000000000
--- a/drivers/media/video/cx25821/cx25821-biffuncs.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _BITFUNCS_H
-#define _BITFUNCS_H
-
-#define SetBit(Bit) (1 << Bit)
-
-inline u8 getBit(u32 sample, u8 index)
-{
- return (u8) ((sample >> index) & 1);
-}
-
-inline u32 clearBitAtPos(u32 value, u8 bit)
-{
- return value & ~(1 << bit);
-}
-
-inline u32 setBitAtPos(u32 sample, u8 bit)
-{
- sample |= (1 << bit);
- return sample;
-
-}
-
-#endif
diff --git a/drivers/media/video/cx25821/cx25821-cards.c b/drivers/media/video/cx25821/cx25821-cards.c
deleted file mode 100644
index 99988c98809..00000000000
--- a/drivers/media/video/cx25821/cx25821-cards.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <media/cx25840.h>
-
-#include "cx25821.h"
-#include "tuner-xc2028.h"
-
-/* board config info */
-
-struct cx25821_board cx25821_boards[] = {
- [UNKNOWN_BOARD] = {
- .name = "UNKNOWN/GENERIC",
- /* Ensure safe default for unknown boards */
- .clk_freq = 0,
- },
-
- [CX25821_BOARD] = {
- .name = "CX25821",
- .portb = CX25821_RAW,
- .portc = CX25821_264,
- .input[0].type = CX25821_VMUX_COMPOSITE,
- },
-
-};
-
-const unsigned int cx25821_bcount = ARRAY_SIZE(cx25821_boards);
-
-struct cx25821_subid cx25821_subids[] = {
- {
- .subvendor = 0x14f1,
- .subdevice = 0x0920,
- .card = CX25821_BOARD,
- },
-};
-
-void cx25821_card_setup(struct cx25821_dev *dev)
-{
- static u8 eeprom[256];
-
- if (dev->i2c_bus[0].i2c_rc == 0) {
- dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
- tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom,
- sizeof(eeprom));
- }
-}
diff --git a/drivers/media/video/cx25821/cx25821-core.c b/drivers/media/video/cx25821/cx25821-core.c
deleted file mode 100644
index f11f6f07e91..00000000000
--- a/drivers/media/video/cx25821/cx25821-core.c
+++ /dev/null
@@ -1,1502 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include "cx25821.h"
-#include "cx25821-sram.h"
-#include "cx25821-video.h"
-
-MODULE_DESCRIPTION("Driver for Athena cards");
-MODULE_AUTHOR("Shu Lin - Hiep Huynh");
-MODULE_LICENSE("GPL");
-
-static unsigned int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debug messages");
-
-static unsigned int card[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
-module_param_array(card, int, NULL, 0444);
-MODULE_PARM_DESC(card, "card type");
-
-static unsigned int cx25821_devcount;
-
-DEFINE_MUTEX(cx25821_devlist_mutex);
-EXPORT_SYMBOL(cx25821_devlist_mutex);
-LIST_HEAD(cx25821_devlist);
-EXPORT_SYMBOL(cx25821_devlist);
-
-struct sram_channel cx25821_sram_channels[] = {
- [SRAM_CH00] = {
- .i = SRAM_CH00,
- .name = "VID A",
- .cmds_start = VID_A_DOWN_CMDS,
- .ctrl_start = VID_A_IQ,
- .cdt = VID_A_CDT,
- .fifo_start = VID_A_DOWN_CLUSTER_1,
- .fifo_size = (VID_CLUSTER_SIZE << 2),
- .ptr1_reg = DMA1_PTR1,
- .ptr2_reg = DMA1_PTR2,
- .cnt1_reg = DMA1_CNT1,
- .cnt2_reg = DMA1_CNT2,
- .int_msk = VID_A_INT_MSK,
- .int_stat = VID_A_INT_STAT,
- .int_mstat = VID_A_INT_MSTAT,
- .dma_ctl = VID_DST_A_DMA_CTL,
- .gpcnt_ctl = VID_DST_A_GPCNT_CTL,
- .gpcnt = VID_DST_A_GPCNT,
- .vip_ctl = VID_DST_A_VIP_CTL,
- .pix_frmt = VID_DST_A_PIX_FRMT,
- },
-
- [SRAM_CH01] = {
- .i = SRAM_CH01,
- .name = "VID B",
- .cmds_start = VID_B_DOWN_CMDS,
- .ctrl_start = VID_B_IQ,
- .cdt = VID_B_CDT,
- .fifo_start = VID_B_DOWN_CLUSTER_1,
- .fifo_size = (VID_CLUSTER_SIZE << 2),
- .ptr1_reg = DMA2_PTR1,
- .ptr2_reg = DMA2_PTR2,
- .cnt1_reg = DMA2_CNT1,
- .cnt2_reg = DMA2_CNT2,
- .int_msk = VID_B_INT_MSK,
- .int_stat = VID_B_INT_STAT,
- .int_mstat = VID_B_INT_MSTAT,
- .dma_ctl = VID_DST_B_DMA_CTL,
- .gpcnt_ctl = VID_DST_B_GPCNT_CTL,
- .gpcnt = VID_DST_B_GPCNT,
- .vip_ctl = VID_DST_B_VIP_CTL,
- .pix_frmt = VID_DST_B_PIX_FRMT,
- },
-
- [SRAM_CH02] = {
- .i = SRAM_CH02,
- .name = "VID C",
- .cmds_start = VID_C_DOWN_CMDS,
- .ctrl_start = VID_C_IQ,
- .cdt = VID_C_CDT,
- .fifo_start = VID_C_DOWN_CLUSTER_1,
- .fifo_size = (VID_CLUSTER_SIZE << 2),
- .ptr1_reg = DMA3_PTR1,
- .ptr2_reg = DMA3_PTR2,
- .cnt1_reg = DMA3_CNT1,
- .cnt2_reg = DMA3_CNT2,
- .int_msk = VID_C_INT_MSK,
- .int_stat = VID_C_INT_STAT,
- .int_mstat = VID_C_INT_MSTAT,
- .dma_ctl = VID_DST_C_DMA_CTL,
- .gpcnt_ctl = VID_DST_C_GPCNT_CTL,
- .gpcnt = VID_DST_C_GPCNT,
- .vip_ctl = VID_DST_C_VIP_CTL,
- .pix_frmt = VID_DST_C_PIX_FRMT,
- },
-
- [SRAM_CH03] = {
- .i = SRAM_CH03,
- .name = "VID D",
- .cmds_start = VID_D_DOWN_CMDS,
- .ctrl_start = VID_D_IQ,
- .cdt = VID_D_CDT,
- .fifo_start = VID_D_DOWN_CLUSTER_1,
- .fifo_size = (VID_CLUSTER_SIZE << 2),
- .ptr1_reg = DMA4_PTR1,
- .ptr2_reg = DMA4_PTR2,
- .cnt1_reg = DMA4_CNT1,
- .cnt2_reg = DMA4_CNT2,
- .int_msk = VID_D_INT_MSK,
- .int_stat = VID_D_INT_STAT,
- .int_mstat = VID_D_INT_MSTAT,
- .dma_ctl = VID_DST_D_DMA_CTL,
- .gpcnt_ctl = VID_DST_D_GPCNT_CTL,
- .gpcnt = VID_DST_D_GPCNT,
- .vip_ctl = VID_DST_D_VIP_CTL,
- .pix_frmt = VID_DST_D_PIX_FRMT,
- },
-
- [SRAM_CH04] = {
- .i = SRAM_CH04,
- .name = "VID E",
- .cmds_start = VID_E_DOWN_CMDS,
- .ctrl_start = VID_E_IQ,
- .cdt = VID_E_CDT,
- .fifo_start = VID_E_DOWN_CLUSTER_1,
- .fifo_size = (VID_CLUSTER_SIZE << 2),
- .ptr1_reg = DMA5_PTR1,
- .ptr2_reg = DMA5_PTR2,
- .cnt1_reg = DMA5_CNT1,
- .cnt2_reg = DMA5_CNT2,
- .int_msk = VID_E_INT_MSK,
- .int_stat = VID_E_INT_STAT,
- .int_mstat = VID_E_INT_MSTAT,
- .dma_ctl = VID_DST_E_DMA_CTL,
- .gpcnt_ctl = VID_DST_E_GPCNT_CTL,
- .gpcnt = VID_DST_E_GPCNT,
- .vip_ctl = VID_DST_E_VIP_CTL,
- .pix_frmt = VID_DST_E_PIX_FRMT,
- },
-
- [SRAM_CH05] = {
- .i = SRAM_CH05,
- .name = "VID F",
- .cmds_start = VID_F_DOWN_CMDS,
- .ctrl_start = VID_F_IQ,
- .cdt = VID_F_CDT,
- .fifo_start = VID_F_DOWN_CLUSTER_1,
- .fifo_size = (VID_CLUSTER_SIZE << 2),
- .ptr1_reg = DMA6_PTR1,
- .ptr2_reg = DMA6_PTR2,
- .cnt1_reg = DMA6_CNT1,
- .cnt2_reg = DMA6_CNT2,
- .int_msk = VID_F_INT_MSK,
- .int_stat = VID_F_INT_STAT,
- .int_mstat = VID_F_INT_MSTAT,
- .dma_ctl = VID_DST_F_DMA_CTL,
- .gpcnt_ctl = VID_DST_F_GPCNT_CTL,
- .gpcnt = VID_DST_F_GPCNT,
- .vip_ctl = VID_DST_F_VIP_CTL,
- .pix_frmt = VID_DST_F_PIX_FRMT,
- },
-
- [SRAM_CH06] = {
- .i = SRAM_CH06,
- .name = "VID G",
- .cmds_start = VID_G_DOWN_CMDS,
- .ctrl_start = VID_G_IQ,
- .cdt = VID_G_CDT,
- .fifo_start = VID_G_DOWN_CLUSTER_1,
- .fifo_size = (VID_CLUSTER_SIZE << 2),
- .ptr1_reg = DMA7_PTR1,
- .ptr2_reg = DMA7_PTR2,
- .cnt1_reg = DMA7_CNT1,
- .cnt2_reg = DMA7_CNT2,
- .int_msk = VID_G_INT_MSK,
- .int_stat = VID_G_INT_STAT,
- .int_mstat = VID_G_INT_MSTAT,
- .dma_ctl = VID_DST_G_DMA_CTL,
- .gpcnt_ctl = VID_DST_G_GPCNT_CTL,
- .gpcnt = VID_DST_G_GPCNT,
- .vip_ctl = VID_DST_G_VIP_CTL,
- .pix_frmt = VID_DST_G_PIX_FRMT,
- },
-
- [SRAM_CH07] = {
- .i = SRAM_CH07,
- .name = "VID H",
- .cmds_start = VID_H_DOWN_CMDS,
- .ctrl_start = VID_H_IQ,
- .cdt = VID_H_CDT,
- .fifo_start = VID_H_DOWN_CLUSTER_1,
- .fifo_size = (VID_CLUSTER_SIZE << 2),
- .ptr1_reg = DMA8_PTR1,
- .ptr2_reg = DMA8_PTR2,
- .cnt1_reg = DMA8_CNT1,
- .cnt2_reg = DMA8_CNT2,
- .int_msk = VID_H_INT_MSK,
- .int_stat = VID_H_INT_STAT,
- .int_mstat = VID_H_INT_MSTAT,
- .dma_ctl = VID_DST_H_DMA_CTL,
- .gpcnt_ctl = VID_DST_H_GPCNT_CTL,
- .gpcnt = VID_DST_H_GPCNT,
- .vip_ctl = VID_DST_H_VIP_CTL,
- .pix_frmt = VID_DST_H_PIX_FRMT,
- },
-
- [SRAM_CH08] = {
- .name = "audio from",
- .cmds_start = AUD_A_DOWN_CMDS,
- .ctrl_start = AUD_A_IQ,
- .cdt = AUD_A_CDT,
- .fifo_start = AUD_A_DOWN_CLUSTER_1,
- .fifo_size = AUDIO_CLUSTER_SIZE * 3,
- .ptr1_reg = DMA17_PTR1,
- .ptr2_reg = DMA17_PTR2,
- .cnt1_reg = DMA17_CNT1,
- .cnt2_reg = DMA17_CNT2,
- },
-
- [SRAM_CH09] = {
- .i = SRAM_CH09,
- .name = "VID Upstream I",
- .cmds_start = VID_I_UP_CMDS,
- .ctrl_start = VID_I_IQ,
- .cdt = VID_I_CDT,
- .fifo_start = VID_I_UP_CLUSTER_1,
- .fifo_size = (VID_CLUSTER_SIZE << 2),
- .ptr1_reg = DMA15_PTR1,
- .ptr2_reg = DMA15_PTR2,
- .cnt1_reg = DMA15_CNT1,
- .cnt2_reg = DMA15_CNT2,
- .int_msk = VID_I_INT_MSK,
- .int_stat = VID_I_INT_STAT,
- .int_mstat = VID_I_INT_MSTAT,
- .dma_ctl = VID_SRC_I_DMA_CTL,
- .gpcnt_ctl = VID_SRC_I_GPCNT_CTL,
- .gpcnt = VID_SRC_I_GPCNT,
-
- .vid_fmt_ctl = VID_SRC_I_FMT_CTL,
- .vid_active_ctl1 = VID_SRC_I_ACTIVE_CTL1,
- .vid_active_ctl2 = VID_SRC_I_ACTIVE_CTL2,
- .vid_cdt_size = VID_SRC_I_CDT_SZ,
- .irq_bit = 8,
- },
-
- [SRAM_CH10] = {
- .i = SRAM_CH10,
- .name = "VID Upstream J",
- .cmds_start = VID_J_UP_CMDS,
- .ctrl_start = VID_J_IQ,
- .cdt = VID_J_CDT,
- .fifo_start = VID_J_UP_CLUSTER_1,
- .fifo_size = (VID_CLUSTER_SIZE << 2),
- .ptr1_reg = DMA16_PTR1,
- .ptr2_reg = DMA16_PTR2,
- .cnt1_reg = DMA16_CNT1,
- .cnt2_reg = DMA16_CNT2,
- .int_msk = VID_J_INT_MSK,
- .int_stat = VID_J_INT_STAT,
- .int_mstat = VID_J_INT_MSTAT,
- .dma_ctl = VID_SRC_J_DMA_CTL,
- .gpcnt_ctl = VID_SRC_J_GPCNT_CTL,
- .gpcnt = VID_SRC_J_GPCNT,
-
- .vid_fmt_ctl = VID_SRC_J_FMT_CTL,
- .vid_active_ctl1 = VID_SRC_J_ACTIVE_CTL1,
- .vid_active_ctl2 = VID_SRC_J_ACTIVE_CTL2,
- .vid_cdt_size = VID_SRC_J_CDT_SZ,
- .irq_bit = 9,
- },
-
- [SRAM_CH11] = {
- .i = SRAM_CH11,
- .name = "Audio Upstream Channel B",
- .cmds_start = AUD_B_UP_CMDS,
- .ctrl_start = AUD_B_IQ,
- .cdt = AUD_B_CDT,
- .fifo_start = AUD_B_UP_CLUSTER_1,
- .fifo_size = (AUDIO_CLUSTER_SIZE * 3),
- .ptr1_reg = DMA22_PTR1,
- .ptr2_reg = DMA22_PTR2,
- .cnt1_reg = DMA22_CNT1,
- .cnt2_reg = DMA22_CNT2,
- .int_msk = AUD_B_INT_MSK,
- .int_stat = AUD_B_INT_STAT,
- .int_mstat = AUD_B_INT_MSTAT,
- .dma_ctl = AUD_INT_DMA_CTL,
- .gpcnt_ctl = AUD_B_GPCNT_CTL,
- .gpcnt = AUD_B_GPCNT,
- .aud_length = AUD_B_LNGTH,
- .aud_cfg = AUD_B_CFG,
- .fld_aud_fifo_en = FLD_AUD_SRC_B_FIFO_EN,
- .fld_aud_risc_en = FLD_AUD_SRC_B_RISC_EN,
- .irq_bit = 11,
- },
-};
-EXPORT_SYMBOL(cx25821_sram_channels);
-
-struct sram_channel *channel0 = &cx25821_sram_channels[SRAM_CH00];
-struct sram_channel *channel1 = &cx25821_sram_channels[SRAM_CH01];
-struct sram_channel *channel2 = &cx25821_sram_channels[SRAM_CH02];
-struct sram_channel *channel3 = &cx25821_sram_channels[SRAM_CH03];
-struct sram_channel *channel4 = &cx25821_sram_channels[SRAM_CH04];
-struct sram_channel *channel5 = &cx25821_sram_channels[SRAM_CH05];
-struct sram_channel *channel6 = &cx25821_sram_channels[SRAM_CH06];
-struct sram_channel *channel7 = &cx25821_sram_channels[SRAM_CH07];
-struct sram_channel *channel9 = &cx25821_sram_channels[SRAM_CH09];
-struct sram_channel *channel10 = &cx25821_sram_channels[SRAM_CH10];
-struct sram_channel *channel11 = &cx25821_sram_channels[SRAM_CH11];
-
-struct cx25821_dmaqueue mpegq;
-
-static int cx25821_risc_decode(u32 risc)
-{
- static const char * const instr[16] = {
- [RISC_SYNC >> 28] = "sync",
- [RISC_WRITE >> 28] = "write",
- [RISC_WRITEC >> 28] = "writec",
- [RISC_READ >> 28] = "read",
- [RISC_READC >> 28] = "readc",
- [RISC_JUMP >> 28] = "jump",
- [RISC_SKIP >> 28] = "skip",
- [RISC_WRITERM >> 28] = "writerm",
- [RISC_WRITECM >> 28] = "writecm",
- [RISC_WRITECR >> 28] = "writecr",
- };
- static const int incr[16] = {
- [RISC_WRITE >> 28] = 3,
- [RISC_JUMP >> 28] = 3,
- [RISC_SKIP >> 28] = 1,
- [RISC_SYNC >> 28] = 1,
- [RISC_WRITERM >> 28] = 3,
- [RISC_WRITECM >> 28] = 3,
- [RISC_WRITECR >> 28] = 4,
- };
- static const char * const bits[] = {
- "12", "13", "14", "resync",
- "cnt0", "cnt1", "18", "19",
- "20", "21", "22", "23",
- "irq1", "irq2", "eol", "sol",
- };
- int i;
-
- pr_cont("0x%08x [ %s",
- risc, instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
- for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) {
- if (risc & (1 << (i + 12)))
- pr_cont(" %s", bits[i]);
- }
- pr_cont(" count=%d ]\n", risc & 0xfff);
- return incr[risc >> 28] ? incr[risc >> 28] : 1;
-}
-
-static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
-{
- struct cx25821_i2c *bus = i2c_adap->algo_data;
- struct cx25821_dev *dev = bus->dev;
- return cx_read(bus->reg_stat) & 0x01;
-}
-
-static void cx25821_registers_init(struct cx25821_dev *dev)
-{
- u32 tmp;
-
- /* enable RUN_RISC in Pecos */
- cx_write(DEV_CNTRL2, 0x20);
-
- /* Set the master PCI interrupt masks to enable video, audio, MBIF,
- * and GPIO interrupts
- * I2C interrupt masking is handled by the I2C objects themselves. */
- cx_write(PCI_INT_MSK, 0x2001FFFF);
-
- tmp = cx_read(RDR_TLCTL0);
- tmp &= ~FLD_CFG_RCB_CK_EN; /* Clear the RCB_CK_EN bit */
- cx_write(RDR_TLCTL0, tmp);
-
- /* PLL-A setting for the Audio Master Clock */
- cx_write(PLL_A_INT_FRAC, 0x9807A58B);
-
- /* PLL_A_POST = 0x1C, PLL_A_OUT_TO_PIN = 0x1 */
- cx_write(PLL_A_POST_STAT_BIST, 0x8000019C);
-
- /* clear reset bit [31] */
- tmp = cx_read(PLL_A_INT_FRAC);
- cx_write(PLL_A_INT_FRAC, tmp & 0x7FFFFFFF);
-
- /* PLL-B setting for Mobilygen Host Bus Interface */
- cx_write(PLL_B_INT_FRAC, 0x9883A86F);
-
- /* PLL_B_POST = 0xD, PLL_B_OUT_TO_PIN = 0x0 */
- cx_write(PLL_B_POST_STAT_BIST, 0x8000018D);
-
- /* clear reset bit [31] */
- tmp = cx_read(PLL_B_INT_FRAC);
- cx_write(PLL_B_INT_FRAC, tmp & 0x7FFFFFFF);
-
- /* PLL-C setting for video upstream channel */
- cx_write(PLL_C_INT_FRAC, 0x96A0EA3F);
-
- /* PLL_C_POST = 0x3, PLL_C_OUT_TO_PIN = 0x0 */
- cx_write(PLL_C_POST_STAT_BIST, 0x80000103);
-
- /* clear reset bit [31] */
- tmp = cx_read(PLL_C_INT_FRAC);
- cx_write(PLL_C_INT_FRAC, tmp & 0x7FFFFFFF);
-
- /* PLL-D setting for audio upstream channel */
- cx_write(PLL_D_INT_FRAC, 0x98757F5B);
-
- /* PLL_D_POST = 0x13, PLL_D_OUT_TO_PIN = 0x0 */
- cx_write(PLL_D_POST_STAT_BIST, 0x80000113);
-
- /* clear reset bit [31] */
- tmp = cx_read(PLL_D_INT_FRAC);
- cx_write(PLL_D_INT_FRAC, tmp & 0x7FFFFFFF);
-
- /* This selects the PLL C clock source for the video upstream channel
- * I and J */
- tmp = cx_read(VID_CH_CLK_SEL);
- cx_write(VID_CH_CLK_SEL, (tmp & 0x00FFFFFF) | 0x24000000);
-
- /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
- * channel A-C
- * select 656/VIP DST for downstream Channel A - C */
- tmp = cx_read(VID_CH_MODE_SEL);
- /* cx_write( VID_CH_MODE_SEL, tmp | 0x1B0001FF); */
- cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
-
- /* enables 656 port I and J as output */
- tmp = cx_read(CLK_RST);
- /* use external ALT_PLL_REF pin as its reference clock instead */
- tmp |= FLD_USE_ALT_PLL_REF;
- cx_write(CLK_RST, tmp & ~(FLD_VID_I_CLK_NOE | FLD_VID_J_CLK_NOE));
-
- mdelay(100);
-}
-
-int cx25821_sram_channel_setup(struct cx25821_dev *dev,
- struct sram_channel *ch,
- unsigned int bpl, u32 risc)
-{
- unsigned int i, lines;
- u32 cdt;
-
- if (ch->cmds_start == 0) {
- cx_write(ch->ptr1_reg, 0);
- cx_write(ch->ptr2_reg, 0);
- cx_write(ch->cnt2_reg, 0);
- cx_write(ch->cnt1_reg, 0);
- return 0;
- }
-
- bpl = (bpl + 7) & ~7; /* alignment */
- cdt = ch->cdt;
- lines = ch->fifo_size / bpl;
-
- if (lines > 4)
- lines = 4;
-
- BUG_ON(lines < 2);
-
- cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- cx_write(8 + 4, 8);
- cx_write(8 + 8, 0);
-
- /* write CDT */
- for (i = 0; i < lines; i++) {
- cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
- cx_write(cdt + 16 * i + 4, 0);
- cx_write(cdt + 16 * i + 8, 0);
- cx_write(cdt + 16 * i + 12, 0);
- }
-
- /* init the first cdt buffer */
- for (i = 0; i < 128; i++)
- cx_write(ch->fifo_start + 4 * i, i);
-
- /* write CMDS */
- if (ch->jumponly)
- cx_write(ch->cmds_start + 0, 8);
- else
- cx_write(ch->cmds_start + 0, risc);
-
- cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
- cx_write(ch->cmds_start + 8, cdt);
- cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
- cx_write(ch->cmds_start + 16, ch->ctrl_start);
-
- if (ch->jumponly)
- cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
- else
- cx_write(ch->cmds_start + 20, 64 >> 2);
-
- for (i = 24; i < 80; i += 4)
- cx_write(ch->cmds_start + i, 0);
-
- /* fill registers */
- cx_write(ch->ptr1_reg, ch->fifo_start);
- cx_write(ch->ptr2_reg, cdt);
- cx_write(ch->cnt2_reg, (lines * 16) >> 3);
- cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
-
- return 0;
-}
-EXPORT_SYMBOL(cx25821_sram_channel_setup);
-
-int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
- struct sram_channel *ch,
- unsigned int bpl, u32 risc)
-{
- unsigned int i, lines;
- u32 cdt;
-
- if (ch->cmds_start == 0) {
- cx_write(ch->ptr1_reg, 0);
- cx_write(ch->ptr2_reg, 0);
- cx_write(ch->cnt2_reg, 0);
- cx_write(ch->cnt1_reg, 0);
- return 0;
- }
-
- bpl = (bpl + 7) & ~7; /* alignment */
- cdt = ch->cdt;
- lines = ch->fifo_size / bpl;
-
- if (lines > 3)
- lines = 3; /* for AUDIO */
-
- BUG_ON(lines < 2);
-
- cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- cx_write(8 + 4, 8);
- cx_write(8 + 8, 0);
-
- /* write CDT */
- for (i = 0; i < lines; i++) {
- cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
- cx_write(cdt + 16 * i + 4, 0);
- cx_write(cdt + 16 * i + 8, 0);
- cx_write(cdt + 16 * i + 12, 0);
- }
-
- /* write CMDS */
- if (ch->jumponly)
- cx_write(ch->cmds_start + 0, 8);
- else
- cx_write(ch->cmds_start + 0, risc);
-
- cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
- cx_write(ch->cmds_start + 8, cdt);
- cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
- cx_write(ch->cmds_start + 16, ch->ctrl_start);
-
- /* IQ size */
- if (ch->jumponly)
- cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
- else
- cx_write(ch->cmds_start + 20, 64 >> 2);
-
- /* zero out */
- for (i = 24; i < 80; i += 4)
- cx_write(ch->cmds_start + i, 0);
-
- /* fill registers */
- cx_write(ch->ptr1_reg, ch->fifo_start);
- cx_write(ch->ptr2_reg, cdt);
- cx_write(ch->cnt2_reg, (lines * 16) >> 3);
- cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
-
- return 0;
-}
-EXPORT_SYMBOL(cx25821_sram_channel_setup_audio);
-
-void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch)
-{
- static char *name[] = {
- "init risc lo",
- "init risc hi",
- "cdt base",
- "cdt size",
- "iq base",
- "iq size",
- "risc pc lo",
- "risc pc hi",
- "iq wr ptr",
- "iq rd ptr",
- "cdt current",
- "pci target lo",
- "pci target hi",
- "line / byte",
- };
- u32 risc;
- unsigned int i, j, n;
-
- pr_warn("%s: %s - dma channel status dump\n", dev->name, ch->name);
- for (i = 0; i < ARRAY_SIZE(name); i++)
- pr_warn("cmds + 0x%2x: %-15s: 0x%08x\n",
- i * 4, name[i], cx_read(ch->cmds_start + 4 * i));
-
- j = i * 4;
- for (i = 0; i < 4;) {
- risc = cx_read(ch->cmds_start + 4 * (i + 14));
- pr_warn("cmds + 0x%2x: risc%d: ", j + i * 4, i);
- i += cx25821_risc_decode(risc);
- }
-
- for (i = 0; i < (64 >> 2); i += n) {
- risc = cx_read(ch->ctrl_start + 4 * i);
- /* No consideration for bits 63-32 */
-
- pr_warn("ctrl + 0x%2x (0x%08x): iq %x: ",
- i * 4, ch->ctrl_start + 4 * i, i);
- n = cx25821_risc_decode(risc);
- for (j = 1; j < n; j++) {
- risc = cx_read(ch->ctrl_start + 4 * (i + j));
- pr_warn("ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
- 4 * (i + j), i + j, risc, j);
- }
- }
-
- pr_warn(" : fifo: 0x%08x -> 0x%x\n",
- ch->fifo_start, ch->fifo_start + ch->fifo_size);
- pr_warn(" : ctrl: 0x%08x -> 0x%x\n",
- ch->ctrl_start, ch->ctrl_start + 6 * 16);
- pr_warn(" : ptr1_reg: 0x%08x\n",
- cx_read(ch->ptr1_reg));
- pr_warn(" : ptr2_reg: 0x%08x\n",
- cx_read(ch->ptr2_reg));
- pr_warn(" : cnt1_reg: 0x%08x\n",
- cx_read(ch->cnt1_reg));
- pr_warn(" : cnt2_reg: 0x%08x\n",
- cx_read(ch->cnt2_reg));
-}
-EXPORT_SYMBOL(cx25821_sram_channel_dump);
-
-void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
- struct sram_channel *ch)
-{
- static const char * const name[] = {
- "init risc lo",
- "init risc hi",
- "cdt base",
- "cdt size",
- "iq base",
- "iq size",
- "risc pc lo",
- "risc pc hi",
- "iq wr ptr",
- "iq rd ptr",
- "cdt current",
- "pci target lo",
- "pci target hi",
- "line / byte",
- };
-
- u32 risc, value, tmp;
- unsigned int i, j, n;
-
- pr_info("\n%s: %s - dma Audio channel status dump\n",
- dev->name, ch->name);
-
- for (i = 0; i < ARRAY_SIZE(name); i++)
- pr_info("%s: cmds + 0x%2x: %-15s: 0x%08x\n",
- dev->name, i * 4, name[i],
- cx_read(ch->cmds_start + 4 * i));
-
- j = i * 4;
- for (i = 0; i < 4;) {
- risc = cx_read(ch->cmds_start + 4 * (i + 14));
- pr_warn("cmds + 0x%2x: risc%d: ", j + i * 4, i);
- i += cx25821_risc_decode(risc);
- }
-
- for (i = 0; i < (64 >> 2); i += n) {
- risc = cx_read(ch->ctrl_start + 4 * i);
- /* No consideration for bits 63-32 */
-
- pr_warn("ctrl + 0x%2x (0x%08x): iq %x: ",
- i * 4, ch->ctrl_start + 4 * i, i);
- n = cx25821_risc_decode(risc);
-
- for (j = 1; j < n; j++) {
- risc = cx_read(ch->ctrl_start + 4 * (i + j));
- pr_warn("ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
- 4 * (i + j), i + j, risc, j);
- }
- }
-
- pr_warn(" : fifo: 0x%08x -> 0x%x\n",
- ch->fifo_start, ch->fifo_start + ch->fifo_size);
- pr_warn(" : ctrl: 0x%08x -> 0x%x\n",
- ch->ctrl_start, ch->ctrl_start + 6 * 16);
- pr_warn(" : ptr1_reg: 0x%08x\n",
- cx_read(ch->ptr1_reg));
- pr_warn(" : ptr2_reg: 0x%08x\n",
- cx_read(ch->ptr2_reg));
- pr_warn(" : cnt1_reg: 0x%08x\n",
- cx_read(ch->cnt1_reg));
- pr_warn(" : cnt2_reg: 0x%08x\n",
- cx_read(ch->cnt2_reg));
-
- for (i = 0; i < 4; i++) {
- risc = cx_read(ch->cmds_start + 56 + (i * 4));
- pr_warn("instruction %d = 0x%x\n", i, risc);
- }
-
- /* read data from the first cdt buffer */
- risc = cx_read(AUD_A_CDT);
- pr_warn("\nread cdt loc=0x%x\n", risc);
- for (i = 0; i < 8; i++) {
- n = cx_read(risc + i * 4);
- pr_cont("0x%x ", n);
- }
- pr_cont("\n\n");
-
- value = cx_read(CLK_RST);
- CX25821_INFO(" CLK_RST = 0x%x\n\n", value);
-
- value = cx_read(PLL_A_POST_STAT_BIST);
- CX25821_INFO(" PLL_A_POST_STAT_BIST = 0x%x\n\n", value);
- value = cx_read(PLL_A_INT_FRAC);
- CX25821_INFO(" PLL_A_INT_FRAC = 0x%x\n\n", value);
-
- value = cx_read(PLL_B_POST_STAT_BIST);
- CX25821_INFO(" PLL_B_POST_STAT_BIST = 0x%x\n\n", value);
- value = cx_read(PLL_B_INT_FRAC);
- CX25821_INFO(" PLL_B_INT_FRAC = 0x%x\n\n", value);
-
- value = cx_read(PLL_C_POST_STAT_BIST);
- CX25821_INFO(" PLL_C_POST_STAT_BIST = 0x%x\n\n", value);
- value = cx_read(PLL_C_INT_FRAC);
- CX25821_INFO(" PLL_C_INT_FRAC = 0x%x\n\n", value);
-
- value = cx_read(PLL_D_POST_STAT_BIST);
- CX25821_INFO(" PLL_D_POST_STAT_BIST = 0x%x\n\n", value);
- value = cx_read(PLL_D_INT_FRAC);
- CX25821_INFO(" PLL_D_INT_FRAC = 0x%x\n\n", value);
-
- value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
- CX25821_INFO(" AFE_AB_DIAG_CTRL (0x10900090) = 0x%x\n\n", value);
-}
-EXPORT_SYMBOL(cx25821_sram_channel_dump_audio);
-
-static void cx25821_shutdown(struct cx25821_dev *dev)
-{
- int i;
-
- /* disable RISC controller */
- cx_write(DEV_CNTRL2, 0);
-
- /* Disable Video A/B activity */
- for (i = 0; i < VID_CHANNEL_NUM; i++) {
- cx_write(dev->channels[i].sram_channels->dma_ctl, 0);
- cx_write(dev->channels[i].sram_channels->int_msk, 0);
- }
-
- for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
- i <= VID_UPSTREAM_SRAM_CHANNEL_J; i++) {
- cx_write(dev->channels[i].sram_channels->dma_ctl, 0);
- cx_write(dev->channels[i].sram_channels->int_msk, 0);
- }
-
- /* Disable Audio activity */
- cx_write(AUD_INT_DMA_CTL, 0);
-
- /* Disable Serial port */
- cx_write(UART_CTL, 0);
-
- /* Disable Interrupts */
- cx_write(PCI_INT_MSK, 0);
- cx_write(AUD_A_INT_MSK, 0);
-}
-
-void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select,
- u32 format)
-{
- if (channel_select <= 7 && channel_select >= 0) {
- cx_write(dev->channels[channel_select].sram_channels->pix_frmt,
- format);
- dev->channels[channel_select].pixel_formats = format;
- }
-}
-
-static void cx25821_set_vip_mode(struct cx25821_dev *dev,
- struct sram_channel *ch)
-{
- cx_write(ch->pix_frmt, PIXEL_FRMT_422);
- cx_write(ch->vip_ctl, PIXEL_ENGINE_VIP1);
-}
-
-static void cx25821_initialize(struct cx25821_dev *dev)
-{
- int i;
-
- dprintk(1, "%s()\n", __func__);
-
- cx25821_shutdown(dev);
- cx_write(PCI_INT_STAT, 0xffffffff);
-
- for (i = 0; i < VID_CHANNEL_NUM; i++)
- cx_write(dev->channels[i].sram_channels->int_stat, 0xffffffff);
-
- cx_write(AUD_A_INT_STAT, 0xffffffff);
- cx_write(AUD_B_INT_STAT, 0xffffffff);
- cx_write(AUD_C_INT_STAT, 0xffffffff);
- cx_write(AUD_D_INT_STAT, 0xffffffff);
- cx_write(AUD_E_INT_STAT, 0xffffffff);
-
- cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
- cx_write(PAD_CTRL, 0x12); /* for I2C */
- cx25821_registers_init(dev); /* init Pecos registers */
- mdelay(100);
-
- for (i = 0; i < VID_CHANNEL_NUM; i++) {
- cx25821_set_vip_mode(dev, dev->channels[i].sram_channels);
- cx25821_sram_channel_setup(dev, dev->channels[i].sram_channels,
- 1440, 0);
- dev->channels[i].pixel_formats = PIXEL_FRMT_422;
- dev->channels[i].use_cif_resolution = FALSE;
- }
-
- /* Probably only affect Downstream */
- for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
- i <= VID_UPSTREAM_SRAM_CHANNEL_J; i++) {
- cx25821_set_vip_mode(dev, dev->channels[i].sram_channels);
- }
-
- cx25821_sram_channel_setup_audio(dev,
- dev->channels[SRAM_CH08].sram_channels, 128, 0);
-
- cx25821_gpio_init(dev);
-}
-
-static int cx25821_get_resources(struct cx25821_dev *dev)
-{
- if (request_mem_region(pci_resource_start(dev->pci, 0),
- pci_resource_len(dev->pci, 0), dev->name))
- return 0;
-
- pr_err("%s: can't get MMIO memory @ 0x%llx\n",
- dev->name, (unsigned long long)pci_resource_start(dev->pci, 0));
-
- return -EBUSY;
-}
-
-static void cx25821_dev_checkrevision(struct cx25821_dev *dev)
-{
- dev->hwrevision = cx_read(RDR_CFG2) & 0xff;
-
- pr_info("%s(): Hardware revision = 0x%02x\n",
- __func__, dev->hwrevision);
-}
-
-static void cx25821_iounmap(struct cx25821_dev *dev)
-{
- if (dev == NULL)
- return;
-
- /* Releasing IO memory */
- if (dev->lmmio != NULL) {
- CX25821_INFO("Releasing lmmio.\n");
- iounmap(dev->lmmio);
- dev->lmmio = NULL;
- }
-}
-
-static int cx25821_dev_setup(struct cx25821_dev *dev)
-{
- int i;
-
- pr_info("\n***********************************\n");
- pr_info("cx25821 set up\n");
- pr_info("***********************************\n\n");
-
- mutex_init(&dev->lock);
-
- atomic_inc(&dev->refcount);
-
- dev->nr = ++cx25821_devcount;
- sprintf(dev->name, "cx25821[%d]", dev->nr);
-
- mutex_lock(&cx25821_devlist_mutex);
- list_add_tail(&dev->devlist, &cx25821_devlist);
- mutex_unlock(&cx25821_devlist_mutex);
-
- if (dev->pci->device != 0x8210) {
- pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n",
- __func__, dev->pci->device);
- return -1;
- } else {
- pr_info("Athena Hardware device = 0x%02x\n", dev->pci->device);
- }
-
- /* Apply a sensible clock frequency for the PCIe bridge */
- dev->clk_freq = 28000000;
- for (i = 0; i < MAX_VID_CHANNEL_NUM; i++)
- dev->channels[i].sram_channels = &cx25821_sram_channels[i];
-
- if (dev->nr > 1)
- CX25821_INFO("dev->nr > 1!");
-
- /* board config */
- dev->board = 1; /* card[dev->nr]; */
- dev->_max_num_decoders = MAX_DECODERS;
-
- dev->pci_bus = dev->pci->bus->number;
- dev->pci_slot = PCI_SLOT(dev->pci->devfn);
- dev->pci_irqmask = 0x001f00;
-
- /* External Master 1 Bus */
- dev->i2c_bus[0].nr = 0;
- dev->i2c_bus[0].dev = dev;
- dev->i2c_bus[0].reg_stat = I2C1_STAT;
- dev->i2c_bus[0].reg_ctrl = I2C1_CTRL;
- dev->i2c_bus[0].reg_addr = I2C1_ADDR;
- dev->i2c_bus[0].reg_rdata = I2C1_RDATA;
- dev->i2c_bus[0].reg_wdata = I2C1_WDATA;
- dev->i2c_bus[0].i2c_period = (0x07 << 24); /* 1.95MHz */
-
- if (cx25821_get_resources(dev) < 0) {
- pr_err("%s: No more PCIe resources for subsystem: %04x:%04x\n",
- dev->name, dev->pci->subsystem_vendor,
- dev->pci->subsystem_device);
-
- cx25821_devcount--;
- return -EBUSY;
- }
-
- /* PCIe stuff */
- dev->base_io_addr = pci_resource_start(dev->pci, 0);
-
- if (!dev->base_io_addr) {
- CX25821_ERR("No PCI Memory resources, exiting!\n");
- return -ENODEV;
- }
-
- dev->lmmio = ioremap(dev->base_io_addr, pci_resource_len(dev->pci, 0));
-
- if (!dev->lmmio) {
- CX25821_ERR("ioremap failed, maybe increasing __VMALLOC_RESERVE in page.h\n");
- cx25821_iounmap(dev);
- return -ENOMEM;
- }
-
- dev->bmmio = (u8 __iomem *) dev->lmmio;
-
- pr_info("%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
- dev->name, dev->pci->subsystem_vendor,
- dev->pci->subsystem_device, cx25821_boards[dev->board].name,
- dev->board, card[dev->nr] == dev->board ?
- "insmod option" : "autodetected");
-
- /* init hardware */
- cx25821_initialize(dev);
-
- cx25821_i2c_register(&dev->i2c_bus[0]);
-/* cx25821_i2c_register(&dev->i2c_bus[1]);
- * cx25821_i2c_register(&dev->i2c_bus[2]); */
-
- CX25821_INFO("i2c register! bus->i2c_rc = %d\n",
- dev->i2c_bus[0].i2c_rc);
-
- cx25821_card_setup(dev);
-
- if (medusa_video_init(dev) < 0)
- CX25821_ERR("%s(): Failed to initialize medusa!\n", __func__);
-
- cx25821_video_register(dev);
-
- /* register IOCTL device */
- dev->ioctl_dev = cx25821_vdev_init(dev, dev->pci,
- &cx25821_videoioctl_template, "video");
-
- if (video_register_device
- (dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) {
- cx25821_videoioctl_unregister(dev);
- pr_err("%s(): Failed to register video adapter for IOCTL, so unregistering videoioctl device\n",
- __func__);
- }
-
- cx25821_dev_checkrevision(dev);
- CX25821_INFO("setup done!\n");
-
- return 0;
-}
-
-void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev,
- struct upstream_user_struct *up_data)
-{
- dev->_isNTSC = !strcmp(dev->vid_stdname, "NTSC") ? 1 : 0;
-
- dev->tvnorm = !dev->_isNTSC ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
- medusa_set_videostandard(dev);
-
- cx25821_vidupstream_init_ch1(dev, dev->channel_select,
- dev->pixel_format);
-}
-
-void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev,
- struct upstream_user_struct *up_data)
-{
- dev->_isNTSC_ch2 = !strcmp(dev->vid_stdname_ch2, "NTSC") ? 1 : 0;
-
- dev->tvnorm = !dev->_isNTSC_ch2 ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
- medusa_set_videostandard(dev);
-
- cx25821_vidupstream_init_ch2(dev, dev->channel_select_ch2,
- dev->pixel_format_ch2);
-}
-
-void cx25821_start_upstream_audio(struct cx25821_dev *dev,
- struct upstream_user_struct *up_data)
-{
- cx25821_audio_upstream_init(dev, AUDIO_UPSTREAM_SRAM_CHANNEL_B);
-}
-
-void cx25821_dev_unregister(struct cx25821_dev *dev)
-{
- int i;
-
- if (!dev->base_io_addr)
- return;
-
- cx25821_free_mem_upstream_ch1(dev);
- cx25821_free_mem_upstream_ch2(dev);
- cx25821_free_mem_upstream_audio(dev);
-
- release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0));
-
- if (!atomic_dec_and_test(&dev->refcount))
- return;
-
- for (i = 0; i < VID_CHANNEL_NUM; i++)
- cx25821_video_unregister(dev, i);
-
- for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
- i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) {
- cx25821_video_unregister(dev, i);
- }
-
- cx25821_videoioctl_unregister(dev);
-
- cx25821_i2c_unregister(&dev->i2c_bus[0]);
- cx25821_iounmap(dev);
-}
-EXPORT_SYMBOL(cx25821_dev_unregister);
-
-static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist,
- unsigned int offset, u32 sync_line,
- unsigned int bpl, unsigned int padding,
- unsigned int lines)
-{
- struct scatterlist *sg;
- unsigned int line, todo;
-
- /* sync instruction */
- if (sync_line != NO_SYNC_LINE)
- *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
-
- /* scan lines */
- sg = sglist;
- for (line = 0; line < lines; line++) {
- while (offset && offset >= sg_dma_len(sg)) {
- offset -= sg_dma_len(sg);
- sg++;
- }
- if (bpl <= sg_dma_len(sg) - offset) {
- /* fits into current chunk */
- *(rp++) = cpu_to_le32(RISC_WRITE | RISC_SOL | RISC_EOL |
- bpl);
- *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
- offset += bpl;
- } else {
- /* scanline needs to be split */
- todo = bpl;
- *(rp++) = cpu_to_le32(RISC_WRITE | RISC_SOL |
- (sg_dma_len(sg) - offset));
- *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
- todo -= (sg_dma_len(sg) - offset);
- offset = 0;
- sg++;
- while (todo > sg_dma_len(sg)) {
- *(rp++) = cpu_to_le32(RISC_WRITE |
- sg_dma_len(sg));
- *(rp++) = cpu_to_le32(sg_dma_address(sg));
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
- todo -= sg_dma_len(sg);
- sg++;
- }
- *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
- *(rp++) = cpu_to_le32(sg_dma_address(sg));
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
- offset += todo;
- }
-
- offset += padding;
- }
-
- return rp;
-}
-
-int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
- struct scatterlist *sglist, unsigned int top_offset,
- unsigned int bottom_offset, unsigned int bpl,
- unsigned int padding, unsigned int lines)
-{
- u32 instructions;
- u32 fields;
- __le32 *rp;
- int rc;
-
- fields = 0;
- if (UNSET != top_offset)
- fields++;
- if (UNSET != bottom_offset)
- fields++;
-
- /* estimate risc mem: worst case is one write per page border +
- one write per scan line + syncs + jump (all 2 dwords). Padding
- can cause next bpl to start close to a page border. First DMA
- region may be smaller than PAGE_SIZE */
- /* write and jump need and extra dword */
- instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE +
- lines);
- instructions += 2;
- rc = btcx_riscmem_alloc(pci, risc, instructions * 12);
-
- if (rc < 0)
- return rc;
-
- /* write risc instructions */
- rp = risc->cpu;
-
- if (UNSET != top_offset) {
- rp = cx25821_risc_field(rp, sglist, top_offset, 0, bpl, padding,
- lines);
- }
-
- if (UNSET != bottom_offset) {
- rp = cx25821_risc_field(rp, sglist, bottom_offset, 0x200, bpl,
- padding, lines);
- }
-
- /* save pointer to jmp instruction address */
- risc->jmp = rp;
- BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
-
- return 0;
-}
-
-static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist,
- unsigned int offset, u32 sync_line,
- unsigned int bpl, unsigned int padding,
- unsigned int lines, unsigned int lpi)
-{
- struct scatterlist *sg;
- unsigned int line, todo, sol;
-
- /* sync instruction */
- if (sync_line != NO_SYNC_LINE)
- *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
-
- /* scan lines */
- sg = sglist;
- for (line = 0; line < lines; line++) {
- while (offset && offset >= sg_dma_len(sg)) {
- offset -= sg_dma_len(sg);
- sg++;
- }
-
- if (lpi && line > 0 && !(line % lpi))
- sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
- else
- sol = RISC_SOL;
-
- if (bpl <= sg_dma_len(sg) - offset) {
- /* fits into current chunk */
- *(rp++) = cpu_to_le32(RISC_WRITE | sol | RISC_EOL |
- bpl);
- *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
- offset += bpl;
- } else {
- /* scanline needs to be split */
- todo = bpl;
- *(rp++) = cpu_to_le32(RISC_WRITE | sol |
- (sg_dma_len(sg) - offset));
- *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
- todo -= (sg_dma_len(sg) - offset);
- offset = 0;
- sg++;
- while (todo > sg_dma_len(sg)) {
- *(rp++) = cpu_to_le32(RISC_WRITE |
- sg_dma_len(sg));
- *(rp++) = cpu_to_le32(sg_dma_address(sg));
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
- todo -= sg_dma_len(sg);
- sg++;
- }
- *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
- *(rp++) = cpu_to_le32(sg_dma_address(sg));
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
- offset += todo;
- }
- offset += padding;
- }
-
- return rp;
-}
-
-int cx25821_risc_databuffer_audio(struct pci_dev *pci,
- struct btcx_riscmem *risc,
- struct scatterlist *sglist,
- unsigned int bpl,
- unsigned int lines, unsigned int lpi)
-{
- u32 instructions;
- __le32 *rp;
- int rc;
-
- /* estimate risc mem: worst case is one write per page border +
- one write per scan line + syncs + jump (all 2 dwords). Here
- there is no padding and no sync. First DMA region may be smaller
- than PAGE_SIZE */
- /* Jump and write need an extra dword */
- instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
- instructions += 1;
-
- rc = btcx_riscmem_alloc(pci, risc, instructions * 12);
- if (rc < 0)
- return rc;
-
- /* write risc instructions */
- rp = risc->cpu;
- rp = cx25821_risc_field_audio(rp, sglist, 0, NO_SYNC_LINE, bpl, 0,
- lines, lpi);
-
- /* save pointer to jmp instruction address */
- risc->jmp = rp;
- BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
- return 0;
-}
-EXPORT_SYMBOL(cx25821_risc_databuffer_audio);
-
-int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
- u32 reg, u32 mask, u32 value)
-{
- __le32 *rp;
- int rc;
-
- rc = btcx_riscmem_alloc(pci, risc, 4 * 16);
-
- if (rc < 0)
- return rc;
-
- /* write risc instructions */
- rp = risc->cpu;
-
- *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ1);
- *(rp++) = cpu_to_le32(reg);
- *(rp++) = cpu_to_le32(value);
- *(rp++) = cpu_to_le32(mask);
- *(rp++) = cpu_to_le32(RISC_JUMP);
- *(rp++) = cpu_to_le32(risc->dma);
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
- return 0;
-}
-
-void cx25821_free_buffer(struct videobuf_queue *q, struct cx25821_buffer *buf)
-{
- struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
-
- BUG_ON(in_interrupt());
- videobuf_waiton(q, &buf->vb, 0, 0);
- videobuf_dma_unmap(q->dev, dma);
- videobuf_dma_free(dma);
- btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static irqreturn_t cx25821_irq(int irq, void *dev_id)
-{
- struct cx25821_dev *dev = dev_id;
- u32 pci_status;
- u32 vid_status;
- int i, handled = 0;
- u32 mask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
-
- pci_status = cx_read(PCI_INT_STAT);
-
- if (pci_status == 0)
- goto out;
-
- for (i = 0; i < VID_CHANNEL_NUM; i++) {
- if (pci_status & mask[i]) {
- vid_status = cx_read(dev->channels[i].
- sram_channels->int_stat);
-
- if (vid_status)
- handled += cx25821_video_irq(dev, i,
- vid_status);
-
- cx_write(PCI_INT_STAT, mask[i]);
- }
- }
-
-out:
- return IRQ_RETVAL(handled);
-}
-
-void cx25821_print_irqbits(char *name, char *tag, char **strings,
- int len, u32 bits, u32 mask)
-{
- unsigned int i;
-
- printk(KERN_DEBUG pr_fmt("%s: %s [0x%x]"), name, tag, bits);
-
- for (i = 0; i < len; i++) {
- if (!(bits & (1 << i)))
- continue;
- if (strings[i])
- pr_cont(" %s", strings[i]);
- else
- pr_cont(" %d", i);
- if (!(mask & (1 << i)))
- continue;
- pr_cont("*");
- }
- pr_cont("\n");
-}
-EXPORT_SYMBOL(cx25821_print_irqbits);
-
-struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci)
-{
- struct cx25821_dev *dev = pci_get_drvdata(pci);
- return dev;
-}
-EXPORT_SYMBOL(cx25821_dev_get);
-
-static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
-{
- struct cx25821_dev *dev;
- int err = 0;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (NULL == dev)
- return -ENOMEM;
-
- err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
- if (err < 0)
- goto fail_free;
-
- /* pci init */
- dev->pci = pci_dev;
- if (pci_enable_device(pci_dev)) {
- err = -EIO;
-
- pr_info("pci enable failed!\n");
-
- goto fail_unregister_device;
- }
-
- pr_info("Athena pci enable !\n");
-
- err = cx25821_dev_setup(dev);
- if (err) {
- if (err == -EBUSY)
- goto fail_unregister_device;
- else
- goto fail_unregister_pci;
- }
-
- /* print pci info */
- pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
- pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
- pr_info("%s/0: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n",
- dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
- dev->pci_lat, (unsigned long long)dev->base_io_addr);
-
- pci_set_master(pci_dev);
- if (!pci_dma_supported(pci_dev, 0xffffffff)) {
- pr_err("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
- err = -EIO;
- goto fail_irq;
- }
-
- err = request_irq(pci_dev->irq, cx25821_irq,
- IRQF_SHARED, dev->name, dev);
-
- if (err < 0) {
- pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq);
- goto fail_irq;
- }
-
- return 0;
-
-fail_irq:
- pr_info("cx25821_initdev() can't get IRQ !\n");
- cx25821_dev_unregister(dev);
-
-fail_unregister_pci:
- pci_disable_device(pci_dev);
-fail_unregister_device:
- v4l2_device_unregister(&dev->v4l2_dev);
-
-fail_free:
- kfree(dev);
- return err;
-}
-
-static void __devexit cx25821_finidev(struct pci_dev *pci_dev)
-{
- struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
- struct cx25821_dev *dev = get_cx25821(v4l2_dev);
-
- cx25821_shutdown(dev);
- pci_disable_device(pci_dev);
-
- /* unregister stuff */
- if (pci_dev->irq)
- free_irq(pci_dev->irq, dev);
-
- mutex_lock(&cx25821_devlist_mutex);
- list_del(&dev->devlist);
- mutex_unlock(&cx25821_devlist_mutex);
-
- cx25821_dev_unregister(dev);
- v4l2_device_unregister(v4l2_dev);
- kfree(dev);
-}
-
-static DEFINE_PCI_DEVICE_TABLE(cx25821_pci_tbl) = {
- {
- /* CX25821 Athena */
- .vendor = 0x14f1,
- .device = 0x8210,
- .subvendor = 0x14f1,
- .subdevice = 0x0920,
- }, {
- /* CX25821 No Brand */
- .vendor = 0x14f1,
- .device = 0x8210,
- .subvendor = 0x0000,
- .subdevice = 0x0000,
- }, {
- /* --- end of list --- */
- }
-};
-
-MODULE_DEVICE_TABLE(pci, cx25821_pci_tbl);
-
-static struct pci_driver cx25821_pci_driver = {
- .name = "cx25821",
- .id_table = cx25821_pci_tbl,
- .probe = cx25821_initdev,
- .remove = __devexit_p(cx25821_finidev),
- /* TODO */
- .suspend = NULL,
- .resume = NULL,
-};
-
-static int __init cx25821_init(void)
-{
- pr_info("driver version %d.%d.%d loaded\n",
- (CX25821_VERSION_CODE >> 16) & 0xff,
- (CX25821_VERSION_CODE >> 8) & 0xff,
- CX25821_VERSION_CODE & 0xff);
- return pci_register_driver(&cx25821_pci_driver);
-}
-
-static void __exit cx25821_fini(void)
-{
- pci_unregister_driver(&cx25821_pci_driver);
-}
-
-module_init(cx25821_init);
-module_exit(cx25821_fini);
diff --git a/drivers/media/video/cx25821/cx25821-gpio.c b/drivers/media/video/cx25821/cx25821-gpio.c
deleted file mode 100644
index 29e43b03c85..00000000000
--- a/drivers/media/video/cx25821/cx25821-gpio.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx25821.h"
-
-/********************* GPIO stuffs *********************/
-void cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
- int pin_number, int pin_logic_value)
-{
- int bit = pin_number;
- u32 gpio_oe_reg = GPIO_LO_OE;
- u32 gpio_register = 0;
- u32 value = 0;
-
- /* Check for valid pinNumber */
- if (pin_number >= 47)
- return;
-
- if (pin_number > 31) {
- bit = pin_number - 31;
- gpio_oe_reg = GPIO_HI_OE;
- }
- /* Here we will make sure that the GPIOs 0 and 1 are output. keep the
- * rest as is */
- gpio_register = cx_read(gpio_oe_reg);
-
- if (pin_logic_value == 1)
- value = gpio_register | Set_GPIO_Bit(bit);
- else
- value = gpio_register & Clear_GPIO_Bit(bit);
-
- cx_write(gpio_oe_reg, value);
-}
-EXPORT_SYMBOL(cx25821_set_gpiopin_direction);
-
-static void cx25821_set_gpiopin_logicvalue(struct cx25821_dev *dev,
- int pin_number, int pin_logic_value)
-{
- int bit = pin_number;
- u32 gpio_reg = GPIO_LO;
- u32 value = 0;
-
- /* Check for valid pinNumber */
- if (pin_number >= 47)
- return;
-
- /* change to output direction */
- cx25821_set_gpiopin_direction(dev, pin_number, 0);
-
- if (pin_number > 31) {
- bit = pin_number - 31;
- gpio_reg = GPIO_HI;
- }
-
- value = cx_read(gpio_reg);
-
- if (pin_logic_value == 0)
- value &= Clear_GPIO_Bit(bit);
- else
- value |= Set_GPIO_Bit(bit);
-
- cx_write(gpio_reg, value);
-}
-
-void cx25821_gpio_init(struct cx25821_dev *dev)
-{
- if (dev == NULL)
- return;
-
- switch (dev->board) {
- case CX25821_BOARD_CONEXANT_ATHENA10:
- default:
- /* set GPIO 5 to select the path for Medusa/Athena */
- cx25821_set_gpiopin_logicvalue(dev, 5, 1);
- mdelay(20);
- break;
- }
-
-}
diff --git a/drivers/media/video/cx25821/cx25821-i2c.c b/drivers/media/video/cx25821/cx25821-i2c.c
deleted file mode 100644
index 9844549764c..00000000000
--- a/drivers/media/video/cx25821/cx25821-i2c.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "cx25821.h"
-#include <linux/i2c.h>
-
-static unsigned int i2c_debug;
-module_param(i2c_debug, int, 0644);
-MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
-
-static unsigned int i2c_scan;
-module_param(i2c_scan, int, 0444);
-MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
-
-#define dprintk(level, fmt, arg...) \
-do { \
- if (i2c_debug >= level) \
- printk(KERN_DEBUG "%s/0: " fmt, dev->name, ##arg); \
-} while (0)
-
-#define I2C_WAIT_DELAY 32
-#define I2C_WAIT_RETRY 64
-
-#define I2C_EXTEND (1 << 3)
-#define I2C_NOSTOP (1 << 4)
-
-static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
-{
- struct cx25821_i2c *bus = i2c_adap->algo_data;
- struct cx25821_dev *dev = bus->dev;
- return cx_read(bus->reg_stat) & 0x01;
-}
-
-static inline int i2c_is_busy(struct i2c_adapter *i2c_adap)
-{
- struct cx25821_i2c *bus = i2c_adap->algo_data;
- struct cx25821_dev *dev = bus->dev;
- return cx_read(bus->reg_stat) & 0x02 ? 1 : 0;
-}
-
-static int i2c_wait_done(struct i2c_adapter *i2c_adap)
-{
- int count;
-
- for (count = 0; count < I2C_WAIT_RETRY; count++) {
- if (!i2c_is_busy(i2c_adap))
- break;
- udelay(I2C_WAIT_DELAY);
- }
-
- if (I2C_WAIT_RETRY == count)
- return 0;
-
- return 1;
-}
-
-static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
- const struct i2c_msg *msg, int joined_rlen)
-{
- struct cx25821_i2c *bus = i2c_adap->algo_data;
- struct cx25821_dev *dev = bus->dev;
- u32 wdata, addr, ctrl;
- int retval, cnt;
-
- if (joined_rlen)
- dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__,
- msg->len, joined_rlen);
- else
- dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len);
-
- /* Deal with i2c probe functions with zero payload */
- if (msg->len == 0) {
- cx_write(bus->reg_addr, msg->addr << 25);
- cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2));
-
- if (!i2c_wait_done(i2c_adap))
- return -EIO;
-
- if (!i2c_slave_did_ack(i2c_adap))
- return -EIO;
-
- dprintk(1, "%s(): returns 0\n", __func__);
- return 0;
- }
-
- /* dev, reg + first byte */
- addr = (msg->addr << 25) | msg->buf[0];
- wdata = msg->buf[0];
-
- ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
-
- if (msg->len > 1)
- ctrl |= I2C_NOSTOP | I2C_EXTEND;
- else if (joined_rlen)
- ctrl |= I2C_NOSTOP;
-
- cx_write(bus->reg_addr, addr);
- cx_write(bus->reg_wdata, wdata);
- cx_write(bus->reg_ctrl, ctrl);
-
- retval = i2c_wait_done(i2c_adap);
- if (retval < 0)
- goto err;
-
- if (retval == 0)
- goto eio;
-
- if (i2c_debug) {
- if (!(ctrl & I2C_NOSTOP))
- printk(" >\n");
- }
-
- for (cnt = 1; cnt < msg->len; cnt++) {
- /* following bytes */
- wdata = msg->buf[cnt];
- ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
-
- if (cnt < msg->len - 1)
- ctrl |= I2C_NOSTOP | I2C_EXTEND;
- else if (joined_rlen)
- ctrl |= I2C_NOSTOP;
-
- cx_write(bus->reg_addr, addr);
- cx_write(bus->reg_wdata, wdata);
- cx_write(bus->reg_ctrl, ctrl);
-
- retval = i2c_wait_done(i2c_adap);
- if (retval < 0)
- goto err;
-
- if (retval == 0)
- goto eio;
-
- if (i2c_debug) {
- dprintk(1, " %02x", msg->buf[cnt]);
- if (!(ctrl & I2C_NOSTOP))
- dprintk(1, " >\n");
- }
- }
-
- return msg->len;
-
-eio:
- retval = -EIO;
-err:
- if (i2c_debug)
- pr_err(" ERR: %d\n", retval);
- return retval;
-}
-
-static int i2c_readbytes(struct i2c_adapter *i2c_adap,
- const struct i2c_msg *msg, int joined)
-{
- struct cx25821_i2c *bus = i2c_adap->algo_data;
- struct cx25821_dev *dev = bus->dev;
- u32 ctrl, cnt;
- int retval;
-
- if (i2c_debug && !joined)
- dprintk(1, "6-%s(msg->len=%d)\n", __func__, msg->len);
-
- /* Deal with i2c probe functions with zero payload */
- if (msg->len == 0) {
- cx_write(bus->reg_addr, msg->addr << 25);
- cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1);
- if (!i2c_wait_done(i2c_adap))
- return -EIO;
- if (!i2c_slave_did_ack(i2c_adap))
- return -EIO;
-
- dprintk(1, "%s(): returns 0\n", __func__);
- return 0;
- }
-
- if (i2c_debug) {
- if (joined)
- dprintk(1, " R");
- else
- dprintk(1, " <R %02x", (msg->addr << 1) + 1);
- }
-
- for (cnt = 0; cnt < msg->len; cnt++) {
-
- ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1;
-
- if (cnt < msg->len - 1)
- ctrl |= I2C_NOSTOP | I2C_EXTEND;
-
- cx_write(bus->reg_addr, msg->addr << 25);
- cx_write(bus->reg_ctrl, ctrl);
-
- retval = i2c_wait_done(i2c_adap);
- if (retval < 0)
- goto err;
- if (retval == 0)
- goto eio;
- msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff;
-
- if (i2c_debug) {
- dprintk(1, " %02x", msg->buf[cnt]);
- if (!(ctrl & I2C_NOSTOP))
- dprintk(1, " >\n");
- }
- }
-
- return msg->len;
-eio:
- retval = -EIO;
-err:
- if (i2c_debug)
- pr_err(" ERR: %d\n", retval);
- return retval;
-}
-
-static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
-{
- struct cx25821_i2c *bus = i2c_adap->algo_data;
- struct cx25821_dev *dev = bus->dev;
- int i, retval = 0;
-
- dprintk(1, "%s(num = %d)\n", __func__, num);
-
- for (i = 0; i < num; i++) {
- dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n",
- __func__, num, msgs[i].addr, msgs[i].len);
-
- if (msgs[i].flags & I2C_M_RD) {
- /* read */
- retval = i2c_readbytes(i2c_adap, &msgs[i], 0);
- } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
- msgs[i].addr == msgs[i + 1].addr) {
- /* write then read from same address */
- retval = i2c_sendbytes(i2c_adap, &msgs[i],
- msgs[i + 1].len);
-
- if (retval < 0)
- goto err;
- i++;
- retval = i2c_readbytes(i2c_adap, &msgs[i], 1);
- } else {
- /* write */
- retval = i2c_sendbytes(i2c_adap, &msgs[i], 0);
- }
-
- if (retval < 0)
- goto err;
- }
- return num;
-
-err:
- return retval;
-}
-
-
-static u32 cx25821_functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA;
-}
-
-static struct i2c_algorithm cx25821_i2c_algo_template = {
- .master_xfer = i2c_xfer,
- .functionality = cx25821_functionality,
-#ifdef NEED_ALGO_CONTROL
- .algo_control = dummy_algo_control,
-#endif
-};
-
-static struct i2c_adapter cx25821_i2c_adap_template = {
- .name = "cx25821",
- .owner = THIS_MODULE,
- .algo = &cx25821_i2c_algo_template,
-};
-
-static struct i2c_client cx25821_i2c_client_template = {
- .name = "cx25821 internal",
-};
-
-/* init + register i2c adapter */
-int cx25821_i2c_register(struct cx25821_i2c *bus)
-{
- struct cx25821_dev *dev = bus->dev;
-
- dprintk(1, "%s(bus = %d)\n", __func__, bus->nr);
-
- bus->i2c_adap = cx25821_i2c_adap_template;
- bus->i2c_client = cx25821_i2c_client_template;
- bus->i2c_adap.dev.parent = &dev->pci->dev;
-
- strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name));
-
- bus->i2c_adap.algo_data = bus;
- i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
- i2c_add_adapter(&bus->i2c_adap);
-
- bus->i2c_client.adapter = &bus->i2c_adap;
-
- /* set up the I2c */
- bus->i2c_client.addr = (0x88 >> 1);
-
- return bus->i2c_rc;
-}
-
-int cx25821_i2c_unregister(struct cx25821_i2c *bus)
-{
- i2c_del_adapter(&bus->i2c_adap);
- return 0;
-}
-
-void cx25821_av_clk(struct cx25821_dev *dev, int enable)
-{
- /* write 0 to bus 2 addr 0x144 via i2x_xfer() */
- char buffer[3];
- struct i2c_msg msg;
- dprintk(1, "%s(enabled = %d)\n", __func__, enable);
-
- /* Register 0x144 */
- buffer[0] = 0x01;
- buffer[1] = 0x44;
- if (enable == 1)
- buffer[2] = 0x05;
- else
- buffer[2] = 0x00;
-
- msg.addr = 0x44;
- msg.flags = I2C_M_TEN;
- msg.len = 3;
- msg.buf = buffer;
-
- i2c_xfer(&dev->i2c_bus[0].i2c_adap, &msg, 1);
-}
-
-int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value)
-{
- struct i2c_client *client = &bus->i2c_client;
- int v = 0;
- u8 addr[2] = { 0, 0 };
- u8 buf[4] = { 0, 0, 0, 0 };
-
- struct i2c_msg msgs[2] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = 2,
- .buf = addr,
- }, {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = 4,
- .buf = buf,
- }
- };
-
- addr[0] = (reg_addr >> 8);
- addr[1] = (reg_addr & 0xff);
- msgs[0].addr = 0x44;
- msgs[1].addr = 0x44;
-
- i2c_xfer(client->adapter, msgs, 2);
-
- v = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
- *value = v;
-
- return v;
-}
-
-int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value)
-{
- struct i2c_client *client = &bus->i2c_client;
- int retval = 0;
- u8 buf[6] = { 0, 0, 0, 0, 0, 0 };
-
- struct i2c_msg msgs[1] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = 6,
- .buf = buf,
- }
- };
-
- buf[0] = reg_addr >> 8;
- buf[1] = reg_addr & 0xff;
- buf[5] = (value >> 24) & 0xff;
- buf[4] = (value >> 16) & 0xff;
- buf[3] = (value >> 8) & 0xff;
- buf[2] = value & 0xff;
- client->flags = 0;
- msgs[0].addr = 0x44;
-
- retval = i2c_xfer(client->adapter, msgs, 1);
-
- return retval;
-}
diff --git a/drivers/media/video/cx25821/cx25821-medusa-defines.h b/drivers/media/video/cx25821/cx25821-medusa-defines.h
deleted file mode 100644
index 7a9e6470ba2..00000000000
--- a/drivers/media/video/cx25821/cx25821-medusa-defines.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _MEDUSA_DEF_H_
-#define _MEDUSA_DEF_H_
-
-/* Video decoder that we supported */
-#define VDEC_A 0
-#define VDEC_B 1
-#define VDEC_C 2
-#define VDEC_D 3
-#define VDEC_E 4
-#define VDEC_F 5
-#define VDEC_G 6
-#define VDEC_H 7
-
-/* end of display sequence */
-#define END_OF_SEQ 0xF;
-
-/* registry string size */
-#define MAX_REGISTRY_SZ 40;
-
-#endif
diff --git a/drivers/media/video/cx25821/cx25821-medusa-reg.h b/drivers/media/video/cx25821/cx25821-medusa-reg.h
deleted file mode 100644
index c98ac946b27..00000000000
--- a/drivers/media/video/cx25821/cx25821-medusa-reg.h
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __MEDUSA_REGISTERS__
-#define __MEDUSA_REGISTERS__
-
-/* Serial Slave Registers */
-#define HOST_REGISTER1 0x0000
-#define HOST_REGISTER2 0x0001
-
-/* Chip Configuration Registers */
-#define CHIP_CTRL 0x0100
-#define AFE_AB_CTRL 0x0104
-#define AFE_CD_CTRL 0x0108
-#define AFE_EF_CTRL 0x010C
-#define AFE_GH_CTRL 0x0110
-#define DENC_AB_CTRL 0x0114
-#define BYP_AB_CTRL 0x0118
-#define MON_A_CTRL 0x011C
-#define DISP_SEQ_A 0x0120
-#define DISP_SEQ_B 0x0124
-#define DISP_AB_CNT 0x0128
-#define DISP_CD_CNT 0x012C
-#define DISP_EF_CNT 0x0130
-#define DISP_GH_CNT 0x0134
-#define DISP_IJ_CNT 0x0138
-#define PIN_OE_CTRL 0x013C
-#define PIN_SPD_CTRL 0x0140
-#define PIN_SPD_CTRL2 0x0144
-#define IRQ_STAT_CTRL 0x0148
-#define POWER_CTRL_AB 0x014C
-#define POWER_CTRL_CD 0x0150
-#define POWER_CTRL_EF 0x0154
-#define POWER_CTRL_GH 0x0158
-#define TUNE_CTRL 0x015C
-#define BIAS_CTRL 0x0160
-#define AFE_AB_DIAG_CTRL 0x0164
-#define AFE_CD_DIAG_CTRL 0x0168
-#define AFE_EF_DIAG_CTRL 0x016C
-#define AFE_GH_DIAG_CTRL 0x0170
-#define PLL_AB_DIAG_CTRL 0x0174
-#define PLL_CD_DIAG_CTRL 0x0178
-#define PLL_EF_DIAG_CTRL 0x017C
-#define PLL_GH_DIAG_CTRL 0x0180
-#define TEST_CTRL 0x0184
-#define BIST_STAT 0x0188
-#define BIST_STAT2 0x018C
-#define BIST_VID_PLL_AB_STAT 0x0190
-#define BIST_VID_PLL_CD_STAT 0x0194
-#define BIST_VID_PLL_EF_STAT 0x0198
-#define BIST_VID_PLL_GH_STAT 0x019C
-#define DLL_DIAG_CTRL 0x01A0
-#define DEV_CH_ID_CTRL 0x01A4
-#define ABIST_CTRL_STATUS 0x01A8
-#define ABIST_FREQ 0x01AC
-#define ABIST_GOERT_SHIFT 0x01B0
-#define ABIST_COEF12 0x01B4
-#define ABIST_COEF34 0x01B8
-#define ABIST_COEF56 0x01BC
-#define ABIST_COEF7_SNR 0x01C0
-#define ABIST_ADC_CAL 0x01C4
-#define ABIST_BIN1_VGA0 0x01C8
-#define ABIST_BIN2_VGA1 0x01CC
-#define ABIST_BIN3_VGA2 0x01D0
-#define ABIST_BIN4_VGA3 0x01D4
-#define ABIST_BIN5_VGA4 0x01D8
-#define ABIST_BIN6_VGA5 0x01DC
-#define ABIST_BIN7_VGA6 0x0x1E0
-#define ABIST_CLAMP_A 0x0x1E4
-#define ABIST_CLAMP_B 0x0x1E8
-#define ABIST_CLAMP_C 0x01EC
-#define ABIST_CLAMP_D 0x01F0
-#define ABIST_CLAMP_E 0x01F4
-#define ABIST_CLAMP_F 0x01F8
-
-/* Digital Video Encoder A Registers */
-#define DENC_A_REG_1 0x0200
-#define DENC_A_REG_2 0x0204
-#define DENC_A_REG_3 0x0208
-#define DENC_A_REG_4 0x020C
-#define DENC_A_REG_5 0x0210
-#define DENC_A_REG_6 0x0214
-#define DENC_A_REG_7 0x0218
-#define DENC_A_REG_8 0x021C
-
-/* Digital Video Encoder B Registers */
-#define DENC_B_REG_1 0x0300
-#define DENC_B_REG_2 0x0304
-#define DENC_B_REG_3 0x0308
-#define DENC_B_REG_4 0x030C
-#define DENC_B_REG_5 0x0310
-#define DENC_B_REG_6 0x0314
-#define DENC_B_REG_7 0x0318
-#define DENC_B_REG_8 0x031C
-
-/* Video Decoder A Registers */
-#define MODE_CTRL 0x1000
-#define OUT_CTRL1 0x1004
-#define OUT_CTRL_NS 0x1008
-#define GEN_STAT 0x100C
-#define INT_STAT_MASK 0x1010
-#define LUMA_CTRL 0x1014
-#define CHROMA_CTRL 0x1018
-#define CRUSH_CTRL 0x101C
-#define HORIZ_TIM_CTRL 0x1020
-#define VERT_TIM_CTRL 0x1024
-#define MISC_TIM_CTRL 0x1028
-#define FIELD_COUNT 0x102C
-#define HSCALE_CTRL 0x1030
-#define VSCALE_CTRL 0x1034
-#define MAN_VGA_CTRL 0x1038
-#define MAN_AGC_CTRL 0x103C
-#define DFE_CTRL1 0x1040
-#define DFE_CTRL2 0x1044
-#define DFE_CTRL3 0x1048
-#define PLL_CTRL 0x104C
-#define PLL_CTRL_FAST 0x1050
-#define HTL_CTRL 0x1054
-#define SRC_CFG 0x1058
-#define SC_STEP_SIZE 0x105C
-#define SC_CONVERGE_CTRL 0x1060
-#define SC_LOOP_CTRL 0x1064
-#define COMB_2D_HFS_CFG 0x1068
-#define COMB_2D_HFD_CFG 0x106C
-#define COMB_2D_LF_CFG 0x1070
-#define COMB_2D_BLEND 0x1074
-#define COMB_MISC_CTRL 0x1078
-#define COMB_FLAT_THRESH_CTRL 0x107C
-#define COMB_TEST 0x1080
-#define BP_MISC_CTRL 0x1084
-#define VCR_DET_CTRL 0x1088
-#define NOISE_DET_CTRL 0x108C
-#define COMB_FLAT_NOISE_CTRL 0x1090
-#define VERSION 0x11F8
-#define SOFT_RST_CTRL 0x11FC
-
-/* Video Decoder B Registers */
-#define VDEC_B_MODE_CTRL 0x1200
-#define VDEC_B_OUT_CTRL1 0x1204
-#define VDEC_B_OUT_CTRL_NS 0x1208
-#define VDEC_B_GEN_STAT 0x120C
-#define VDEC_B_INT_STAT_MASK 0x1210
-#define VDEC_B_LUMA_CTRL 0x1214
-#define VDEC_B_CHROMA_CTRL 0x1218
-#define VDEC_B_CRUSH_CTRL 0x121C
-#define VDEC_B_HORIZ_TIM_CTRL 0x1220
-#define VDEC_B_VERT_TIM_CTRL 0x1224
-#define VDEC_B_MISC_TIM_CTRL 0x1228
-#define VDEC_B_FIELD_COUNT 0x122C
-#define VDEC_B_HSCALE_CTRL 0x1230
-#define VDEC_B_VSCALE_CTRL 0x1234
-#define VDEC_B_MAN_VGA_CTRL 0x1238
-#define VDEC_B_MAN_AGC_CTRL 0x123C
-#define VDEC_B_DFE_CTRL1 0x1240
-#define VDEC_B_DFE_CTRL2 0x1244
-#define VDEC_B_DFE_CTRL3 0x1248
-#define VDEC_B_PLL_CTRL 0x124C
-#define VDEC_B_PLL_CTRL_FAST 0x1250
-#define VDEC_B_HTL_CTRL 0x1254
-#define VDEC_B_SRC_CFG 0x1258
-#define VDEC_B_SC_STEP_SIZE 0x125C
-#define VDEC_B_SC_CONVERGE_CTRL 0x1260
-#define VDEC_B_SC_LOOP_CTRL 0x1264
-#define VDEC_B_COMB_2D_HFS_CFG 0x1268
-#define VDEC_B_COMB_2D_HFD_CFG 0x126C
-#define VDEC_B_COMB_2D_LF_CFG 0x1270
-#define VDEC_B_COMB_2D_BLEND 0x1274
-#define VDEC_B_COMB_MISC_CTRL 0x1278
-#define VDEC_B_COMB_FLAT_THRESH_CTRL 0x127C
-#define VDEC_B_COMB_TEST 0x1280
-#define VDEC_B_BP_MISC_CTRL 0x1284
-#define VDEC_B_VCR_DET_CTRL 0x1288
-#define VDEC_B_NOISE_DET_CTRL 0x128C
-#define VDEC_B_COMB_FLAT_NOISE_CTRL 0x1290
-#define VDEC_B_VERSION 0x13F8
-#define VDEC_B_SOFT_RST_CTRL 0x13FC
-
-/* Video Decoder C Registers */
-#define VDEC_C_MODE_CTRL 0x1400
-#define VDEC_C_OUT_CTRL1 0x1404
-#define VDEC_C_OUT_CTRL_NS 0x1408
-#define VDEC_C_GEN_STAT 0x140C
-#define VDEC_C_INT_STAT_MASK 0x1410
-#define VDEC_C_LUMA_CTRL 0x1414
-#define VDEC_C_CHROMA_CTRL 0x1418
-#define VDEC_C_CRUSH_CTRL 0x141C
-#define VDEC_C_HORIZ_TIM_CTRL 0x1420
-#define VDEC_C_VERT_TIM_CTRL 0x1424
-#define VDEC_C_MISC_TIM_CTRL 0x1428
-#define VDEC_C_FIELD_COUNT 0x142C
-#define VDEC_C_HSCALE_CTRL 0x1430
-#define VDEC_C_VSCALE_CTRL 0x1434
-#define VDEC_C_MAN_VGA_CTRL 0x1438
-#define VDEC_C_MAN_AGC_CTRL 0x143C
-#define VDEC_C_DFE_CTRL1 0x1440
-#define VDEC_C_DFE_CTRL2 0x1444
-#define VDEC_C_DFE_CTRL3 0x1448
-#define VDEC_C_PLL_CTRL 0x144C
-#define VDEC_C_PLL_CTRL_FAST 0x1450
-#define VDEC_C_HTL_CTRL 0x1454
-#define VDEC_C_SRC_CFG 0x1458
-#define VDEC_C_SC_STEP_SIZE 0x145C
-#define VDEC_C_SC_CONVERGE_CTRL 0x1460
-#define VDEC_C_SC_LOOP_CTRL 0x1464
-#define VDEC_C_COMB_2D_HFS_CFG 0x1468
-#define VDEC_C_COMB_2D_HFD_CFG 0x146C
-#define VDEC_C_COMB_2D_LF_CFG 0x1470
-#define VDEC_C_COMB_2D_BLEND 0x1474
-#define VDEC_C_COMB_MISC_CTRL 0x1478
-#define VDEC_C_COMB_FLAT_THRESH_CTRL 0x147C
-#define VDEC_C_COMB_TEST 0x1480
-#define VDEC_C_BP_MISC_CTRL 0x1484
-#define VDEC_C_VCR_DET_CTRL 0x1488
-#define VDEC_C_NOISE_DET_CTRL 0x148C
-#define VDEC_C_COMB_FLAT_NOISE_CTRL 0x1490
-#define VDEC_C_VERSION 0x15F8
-#define VDEC_C_SOFT_RST_CTRL 0x15FC
-
-/* Video Decoder D Registers */
-#define VDEC_D_MODE_CTRL 0x1600
-#define VDEC_D_OUT_CTRL1 0x1604
-#define VDEC_D_OUT_CTRL_NS 0x1608
-#define VDEC_D_GEN_STAT 0x160C
-#define VDEC_D_INT_STAT_MASK 0x1610
-#define VDEC_D_LUMA_CTRL 0x1614
-#define VDEC_D_CHROMA_CTRL 0x1618
-#define VDEC_D_CRUSH_CTRL 0x161C
-#define VDEC_D_HORIZ_TIM_CTRL 0x1620
-#define VDEC_D_VERT_TIM_CTRL 0x1624
-#define VDEC_D_MISC_TIM_CTRL 0x1628
-#define VDEC_D_FIELD_COUNT 0x162C
-#define VDEC_D_HSCALE_CTRL 0x1630
-#define VDEC_D_VSCALE_CTRL 0x1634
-#define VDEC_D_MAN_VGA_CTRL 0x1638
-#define VDEC_D_MAN_AGC_CTRL 0x163C
-#define VDEC_D_DFE_CTRL1 0x1640
-#define VDEC_D_DFE_CTRL2 0x1644
-#define VDEC_D_DFE_CTRL3 0x1648
-#define VDEC_D_PLL_CTRL 0x164C
-#define VDEC_D_PLL_CTRL_FAST 0x1650
-#define VDEC_D_HTL_CTRL 0x1654
-#define VDEC_D_SRC_CFG 0x1658
-#define VDEC_D_SC_STEP_SIZE 0x165C
-#define VDEC_D_SC_CONVERGE_CTRL 0x1660
-#define VDEC_D_SC_LOOP_CTRL 0x1664
-#define VDEC_D_COMB_2D_HFS_CFG 0x1668
-#define VDEC_D_COMB_2D_HFD_CFG 0x166C
-#define VDEC_D_COMB_2D_LF_CFG 0x1670
-#define VDEC_D_COMB_2D_BLEND 0x1674
-#define VDEC_D_COMB_MISC_CTRL 0x1678
-#define VDEC_D_COMB_FLAT_THRESH_CTRL 0x167C
-#define VDEC_D_COMB_TEST 0x1680
-#define VDEC_D_BP_MISC_CTRL 0x1684
-#define VDEC_D_VCR_DET_CTRL 0x1688
-#define VDEC_D_NOISE_DET_CTRL 0x168C
-#define VDEC_D_COMB_FLAT_NOISE_CTRL 0x1690
-#define VDEC_D_VERSION 0x17F8
-#define VDEC_D_SOFT_RST_CTRL 0x17FC
-
-/* Video Decoder E Registers */
-#define VDEC_E_MODE_CTRL 0x1800
-#define VDEC_E_OUT_CTRL1 0x1804
-#define VDEC_E_OUT_CTRL_NS 0x1808
-#define VDEC_E_GEN_STAT 0x180C
-#define VDEC_E_INT_STAT_MASK 0x1810
-#define VDEC_E_LUMA_CTRL 0x1814
-#define VDEC_E_CHROMA_CTRL 0x1818
-#define VDEC_E_CRUSH_CTRL 0x181C
-#define VDEC_E_HORIZ_TIM_CTRL 0x1820
-#define VDEC_E_VERT_TIM_CTRL 0x1824
-#define VDEC_E_MISC_TIM_CTRL 0x1828
-#define VDEC_E_FIELD_COUNT 0x182C
-#define VDEC_E_HSCALE_CTRL 0x1830
-#define VDEC_E_VSCALE_CTRL 0x1834
-#define VDEC_E_MAN_VGA_CTRL 0x1838
-#define VDEC_E_MAN_AGC_CTRL 0x183C
-#define VDEC_E_DFE_CTRL1 0x1840
-#define VDEC_E_DFE_CTRL2 0x1844
-#define VDEC_E_DFE_CTRL3 0x1848
-#define VDEC_E_PLL_CTRL 0x184C
-#define VDEC_E_PLL_CTRL_FAST 0x1850
-#define VDEC_E_HTL_CTRL 0x1854
-#define VDEC_E_SRC_CFG 0x1858
-#define VDEC_E_SC_STEP_SIZE 0x185C
-#define VDEC_E_SC_CONVERGE_CTRL 0x1860
-#define VDEC_E_SC_LOOP_CTRL 0x1864
-#define VDEC_E_COMB_2D_HFS_CFG 0x1868
-#define VDEC_E_COMB_2D_HFD_CFG 0x186C
-#define VDEC_E_COMB_2D_LF_CFG 0x1870
-#define VDEC_E_COMB_2D_BLEND 0x1874
-#define VDEC_E_COMB_MISC_CTRL 0x1878
-#define VDEC_E_COMB_FLAT_THRESH_CTRL 0x187C
-#define VDEC_E_COMB_TEST 0x1880
-#define VDEC_E_BP_MISC_CTRL 0x1884
-#define VDEC_E_VCR_DET_CTRL 0x1888
-#define VDEC_E_NOISE_DET_CTRL 0x188C
-#define VDEC_E_COMB_FLAT_NOISE_CTRL 0x1890
-#define VDEC_E_VERSION 0x19F8
-#define VDEC_E_SOFT_RST_CTRL 0x19FC
-
-/* Video Decoder F Registers */
-#define VDEC_F_MODE_CTRL 0x1A00
-#define VDEC_F_OUT_CTRL1 0x1A04
-#define VDEC_F_OUT_CTRL_NS 0x1A08
-#define VDEC_F_GEN_STAT 0x1A0C
-#define VDEC_F_INT_STAT_MASK 0x1A10
-#define VDEC_F_LUMA_CTRL 0x1A14
-#define VDEC_F_CHROMA_CTRL 0x1A18
-#define VDEC_F_CRUSH_CTRL 0x1A1C
-#define VDEC_F_HORIZ_TIM_CTRL 0x1A20
-#define VDEC_F_VERT_TIM_CTRL 0x1A24
-#define VDEC_F_MISC_TIM_CTRL 0x1A28
-#define VDEC_F_FIELD_COUNT 0x1A2C
-#define VDEC_F_HSCALE_CTRL 0x1A30
-#define VDEC_F_VSCALE_CTRL 0x1A34
-#define VDEC_F_MAN_VGA_CTRL 0x1A38
-#define VDEC_F_MAN_AGC_CTRL 0x1A3C
-#define VDEC_F_DFE_CTRL1 0x1A40
-#define VDEC_F_DFE_CTRL2 0x1A44
-#define VDEC_F_DFE_CTRL3 0x1A48
-#define VDEC_F_PLL_CTRL 0x1A4C
-#define VDEC_F_PLL_CTRL_FAST 0x1A50
-#define VDEC_F_HTL_CTRL 0x1A54
-#define VDEC_F_SRC_CFG 0x1A58
-#define VDEC_F_SC_STEP_SIZE 0x1A5C
-#define VDEC_F_SC_CONVERGE_CTRL 0x1A60
-#define VDEC_F_SC_LOOP_CTRL 0x1A64
-#define VDEC_F_COMB_2D_HFS_CFG 0x1A68
-#define VDEC_F_COMB_2D_HFD_CFG 0x1A6C
-#define VDEC_F_COMB_2D_LF_CFG 0x1A70
-#define VDEC_F_COMB_2D_BLEND 0x1A74
-#define VDEC_F_COMB_MISC_CTRL 0x1A78
-#define VDEC_F_COMB_FLAT_THRESH_CTRL 0x1A7C
-#define VDEC_F_COMB_TEST 0x1A80
-#define VDEC_F_BP_MISC_CTRL 0x1A84
-#define VDEC_F_VCR_DET_CTRL 0x1A88
-#define VDEC_F_NOISE_DET_CTRL 0x1A8C
-#define VDEC_F_COMB_FLAT_NOISE_CTRL 0x1A90
-#define VDEC_F_VERSION 0x1BF8
-#define VDEC_F_SOFT_RST_CTRL 0x1BFC
-
-/* Video Decoder G Registers */
-#define VDEC_G_MODE_CTRL 0x1C00
-#define VDEC_G_OUT_CTRL1 0x1C04
-#define VDEC_G_OUT_CTRL_NS 0x1C08
-#define VDEC_G_GEN_STAT 0x1C0C
-#define VDEC_G_INT_STAT_MASK 0x1C10
-#define VDEC_G_LUMA_CTRL 0x1C14
-#define VDEC_G_CHROMA_CTRL 0x1C18
-#define VDEC_G_CRUSH_CTRL 0x1C1C
-#define VDEC_G_HORIZ_TIM_CTRL 0x1C20
-#define VDEC_G_VERT_TIM_CTRL 0x1C24
-#define VDEC_G_MISC_TIM_CTRL 0x1C28
-#define VDEC_G_FIELD_COUNT 0x1C2C
-#define VDEC_G_HSCALE_CTRL 0x1C30
-#define VDEC_G_VSCALE_CTRL 0x1C34
-#define VDEC_G_MAN_VGA_CTRL 0x1C38
-#define VDEC_G_MAN_AGC_CTRL 0x1C3C
-#define VDEC_G_DFE_CTRL1 0x1C40
-#define VDEC_G_DFE_CTRL2 0x1C44
-#define VDEC_G_DFE_CTRL3 0x1C48
-#define VDEC_G_PLL_CTRL 0x1C4C
-#define VDEC_G_PLL_CTRL_FAST 0x1C50
-#define VDEC_G_HTL_CTRL 0x1C54
-#define VDEC_G_SRC_CFG 0x1C58
-#define VDEC_G_SC_STEP_SIZE 0x1C5C
-#define VDEC_G_SC_CONVERGE_CTRL 0x1C60
-#define VDEC_G_SC_LOOP_CTRL 0x1C64
-#define VDEC_G_COMB_2D_HFS_CFG 0x1C68
-#define VDEC_G_COMB_2D_HFD_CFG 0x1C6C
-#define VDEC_G_COMB_2D_LF_CFG 0x1C70
-#define VDEC_G_COMB_2D_BLEND 0x1C74
-#define VDEC_G_COMB_MISC_CTRL 0x1C78
-#define VDEC_G_COMB_FLAT_THRESH_CTRL 0x1C7C
-#define VDEC_G_COMB_TEST 0x1C80
-#define VDEC_G_BP_MISC_CTRL 0x1C84
-#define VDEC_G_VCR_DET_CTRL 0x1C88
-#define VDEC_G_NOISE_DET_CTRL 0x1C8C
-#define VDEC_G_COMB_FLAT_NOISE_CTRL 0x1C90
-#define VDEC_G_VERSION 0x1DF8
-#define VDEC_G_SOFT_RST_CTRL 0x1DFC
-
-/* Video Decoder H Registers */
-#define VDEC_H_MODE_CTRL 0x1E00
-#define VDEC_H_OUT_CTRL1 0x1E04
-#define VDEC_H_OUT_CTRL_NS 0x1E08
-#define VDEC_H_GEN_STAT 0x1E0C
-#define VDEC_H_INT_STAT_MASK 0x1E1E
-#define VDEC_H_LUMA_CTRL 0x1E14
-#define VDEC_H_CHROMA_CTRL 0x1E18
-#define VDEC_H_CRUSH_CTRL 0x1E1C
-#define VDEC_H_HORIZ_TIM_CTRL 0x1E20
-#define VDEC_H_VERT_TIM_CTRL 0x1E24
-#define VDEC_H_MISC_TIM_CTRL 0x1E28
-#define VDEC_H_FIELD_COUNT 0x1E2C
-#define VDEC_H_HSCALE_CTRL 0x1E30
-#define VDEC_H_VSCALE_CTRL 0x1E34
-#define VDEC_H_MAN_VGA_CTRL 0x1E38
-#define VDEC_H_MAN_AGC_CTRL 0x1E3C
-#define VDEC_H_DFE_CTRL1 0x1E40
-#define VDEC_H_DFE_CTRL2 0x1E44
-#define VDEC_H_DFE_CTRL3 0x1E48
-#define VDEC_H_PLL_CTRL 0x1E4C
-#define VDEC_H_PLL_CTRL_FAST 0x1E50
-#define VDEC_H_HTL_CTRL 0x1E54
-#define VDEC_H_SRC_CFG 0x1E58
-#define VDEC_H_SC_STEP_SIZE 0x1E5C
-#define VDEC_H_SC_CONVERGE_CTRL 0x1E60
-#define VDEC_H_SC_LOOP_CTRL 0x1E64
-#define VDEC_H_COMB_2D_HFS_CFG 0x1E68
-#define VDEC_H_COMB_2D_HFD_CFG 0x1E6C
-#define VDEC_H_COMB_2D_LF_CFG 0x1E70
-#define VDEC_H_COMB_2D_BLEND 0x1E74
-#define VDEC_H_COMB_MISC_CTRL 0x1E78
-#define VDEC_H_COMB_FLAT_THRESH_CTRL 0x1E7C
-#define VDEC_H_COMB_TEST 0x1E80
-#define VDEC_H_BP_MISC_CTRL 0x1E84
-#define VDEC_H_VCR_DET_CTRL 0x1E88
-#define VDEC_H_NOISE_DET_CTRL 0x1E8C
-#define VDEC_H_COMB_FLAT_NOISE_CTRL 0x1E90
-#define VDEC_H_VERSION 0x1FF8
-#define VDEC_H_SOFT_RST_CTRL 0x1FFC
-
-/*****************************************************************************/
-/* LUMA_CTRL register fields */
-#define VDEC_A_BRITE_CTRL 0x1014
-#define VDEC_A_CNTRST_CTRL 0x1015
-#define VDEC_A_PEAK_SEL 0x1016
-
-/*****************************************************************************/
-/* CHROMA_CTRL register fields */
-#define VDEC_A_USAT_CTRL 0x1018
-#define VDEC_A_VSAT_CTRL 0x1019
-#define VDEC_A_HUE_CTRL 0x101A
-
-#endif
diff --git a/drivers/media/video/cx25821/cx25821-medusa-video.c b/drivers/media/video/cx25821/cx25821-medusa-video.c
deleted file mode 100644
index 6a92e5c70c2..00000000000
--- a/drivers/media/video/cx25821/cx25821-medusa-video.c
+++ /dev/null
@@ -1,787 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "cx25821.h"
-#include "cx25821-medusa-video.h"
-#include "cx25821-biffuncs.h"
-
-/*
- * medusa_enable_bluefield_output()
- *
- * Enable the generation of blue filed output if no video
- *
- */
-static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel,
- int enable)
-{
- u32 value = 0;
- u32 tmp = 0;
- int out_ctrl = OUT_CTRL1;
- int out_ctrl_ns = OUT_CTRL_NS;
-
- switch (channel) {
- default:
- case VDEC_A:
- break;
- case VDEC_B:
- out_ctrl = VDEC_B_OUT_CTRL1;
- out_ctrl_ns = VDEC_B_OUT_CTRL_NS;
- break;
- case VDEC_C:
- out_ctrl = VDEC_C_OUT_CTRL1;
- out_ctrl_ns = VDEC_C_OUT_CTRL_NS;
- break;
- case VDEC_D:
- out_ctrl = VDEC_D_OUT_CTRL1;
- out_ctrl_ns = VDEC_D_OUT_CTRL_NS;
- break;
- case VDEC_E:
- out_ctrl = VDEC_E_OUT_CTRL1;
- out_ctrl_ns = VDEC_E_OUT_CTRL_NS;
- return;
- case VDEC_F:
- out_ctrl = VDEC_F_OUT_CTRL1;
- out_ctrl_ns = VDEC_F_OUT_CTRL_NS;
- return;
- case VDEC_G:
- out_ctrl = VDEC_G_OUT_CTRL1;
- out_ctrl_ns = VDEC_G_OUT_CTRL_NS;
- return;
- case VDEC_H:
- out_ctrl = VDEC_H_OUT_CTRL1;
- out_ctrl_ns = VDEC_H_OUT_CTRL_NS;
- return;
- }
-
- value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp);
- value &= 0xFFFFFF7F; /* clear BLUE_FIELD_EN */
- if (enable)
- value |= 0x00000080; /* set BLUE_FIELD_EN */
- cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value);
-
- value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp);
- value &= 0xFFFFFF7F;
- if (enable)
- value |= 0x00000080; /* set BLUE_FIELD_EN */
- cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value);
-}
-
-static int medusa_initialize_ntsc(struct cx25821_dev *dev)
-{
- int ret_val = 0;
- int i = 0;
- u32 value = 0;
- u32 tmp = 0;
-
- mutex_lock(&dev->lock);
-
- for (i = 0; i < MAX_DECODERS; i++) {
- /* set video format NTSC-M */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- MODE_CTRL + (0x200 * i), &tmp);
- value &= 0xFFFFFFF0;
- /* enable the fast locking mode bit[16] */
- value |= 0x10001;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- MODE_CTRL + (0x200 * i), value);
-
- /* resolution NTSC 720x480 */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- HORIZ_TIM_CTRL + (0x200 * i), &tmp);
- value &= 0x00C00C00;
- value |= 0x612D0074;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- HORIZ_TIM_CTRL + (0x200 * i), value);
-
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- VERT_TIM_CTRL + (0x200 * i), &tmp);
- value &= 0x00C00C00;
- value |= 0x1C1E001A; /* vblank_cnt + 2 to get camera ID */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- VERT_TIM_CTRL + (0x200 * i), value);
-
- /* chroma subcarrier step size */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- SC_STEP_SIZE + (0x200 * i), 0x43E00000);
-
- /* enable VIP optional active */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- OUT_CTRL_NS + (0x200 * i), &tmp);
- value &= 0xFFFBFFFF;
- value |= 0x00040000;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- OUT_CTRL_NS + (0x200 * i), value);
-
- /* enable VIP optional active (VIP_OPT_AL) for direct output. */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- OUT_CTRL1 + (0x200 * i), &tmp);
- value &= 0xFFFBFFFF;
- value |= 0x00040000;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- OUT_CTRL1 + (0x200 * i), value);
-
- /*
- * clear VPRES_VERT_EN bit, fixes the chroma run away problem
- * when the input switching rate < 16 fields
- */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- MISC_TIM_CTRL + (0x200 * i), &tmp);
- /* disable special play detection */
- value = setBitAtPos(value, 14);
- value = clearBitAtPos(value, 15);
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- MISC_TIM_CTRL + (0x200 * i), value);
-
- /* set vbi_gate_en to 0 */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- DFE_CTRL1 + (0x200 * i), &tmp);
- value = clearBitAtPos(value, 29);
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DFE_CTRL1 + (0x200 * i), value);
-
- /* Enable the generation of blue field output if no video */
- medusa_enable_bluefield_output(dev, i, 1);
- }
-
- for (i = 0; i < MAX_ENCODERS; i++) {
- /* NTSC hclock */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- DENC_A_REG_1 + (0x100 * i), &tmp);
- value &= 0xF000FC00;
- value |= 0x06B402D0;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DENC_A_REG_1 + (0x100 * i), value);
-
- /* burst begin and burst end */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- DENC_A_REG_2 + (0x100 * i), &tmp);
- value &= 0xFF000000;
- value |= 0x007E9054;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DENC_A_REG_2 + (0x100 * i), value);
-
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- DENC_A_REG_3 + (0x100 * i), &tmp);
- value &= 0xFC00FE00;
- value |= 0x00EC00F0;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DENC_A_REG_3 + (0x100 * i), value);
-
- /* set NTSC vblank, no phase alternation, 7.5 IRE pedestal */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- DENC_A_REG_4 + (0x100 * i), &tmp);
- value &= 0x00FCFFFF;
- value |= 0x13020000;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DENC_A_REG_4 + (0x100 * i), value);
-
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- DENC_A_REG_5 + (0x100 * i), &tmp);
- value &= 0xFFFF0000;
- value |= 0x0000E575;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DENC_A_REG_5 + (0x100 * i), value);
-
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DENC_A_REG_6 + (0x100 * i), 0x009A89C1);
-
- /* Subcarrier Increment */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DENC_A_REG_7 + (0x100 * i), 0x21F07C1F);
- }
-
- /* set picture resolutions */
- /* 0 - 720 */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0);
- /* 0 - 480 */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0);
-
- /* set Bypass input format to NTSC 525 lines */
- value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
- value |= 0x00080200;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
-
- mutex_unlock(&dev->lock);
-
- return ret_val;
-}
-
-static int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
-{
- int ret_val = -1;
- u32 value = 0, tmp = 0;
-
- /* Setup for 2D threshold */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- COMB_2D_HFS_CFG + (0x200 * dec), 0x20002861);
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- COMB_2D_HFD_CFG + (0x200 * dec), 0x20002861);
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- COMB_2D_LF_CFG + (0x200 * dec), 0x200A1023);
-
- /* Setup flat chroma and luma thresholds */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp);
- value &= 0x06230000;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- COMB_FLAT_THRESH_CTRL + (0x200 * dec), value);
-
- /* set comb 2D blend */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- COMB_2D_BLEND + (0x200 * dec), 0x210F0F0F);
-
- /* COMB MISC CONTROL */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- COMB_MISC_CTRL + (0x200 * dec), 0x41120A7F);
-
- return ret_val;
-}
-
-static int medusa_initialize_pal(struct cx25821_dev *dev)
-{
- int ret_val = 0;
- int i = 0;
- u32 value = 0;
- u32 tmp = 0;
-
- mutex_lock(&dev->lock);
-
- for (i = 0; i < MAX_DECODERS; i++) {
- /* set video format PAL-BDGHI */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- MODE_CTRL + (0x200 * i), &tmp);
- value &= 0xFFFFFFF0;
- /* enable the fast locking mode bit[16] */
- value |= 0x10004;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- MODE_CTRL + (0x200 * i), value);
-
- /* resolution PAL 720x576 */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- HORIZ_TIM_CTRL + (0x200 * i), &tmp);
- value &= 0x00C00C00;
- value |= 0x632D007D;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- HORIZ_TIM_CTRL + (0x200 * i), value);
-
- /* vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24 */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- VERT_TIM_CTRL + (0x200 * i), &tmp);
- value &= 0x00C00C00;
- value |= 0x28240026; /* vblank_cnt + 2 to get camera ID */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- VERT_TIM_CTRL + (0x200 * i), value);
-
- /* chroma subcarrier step size */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- SC_STEP_SIZE + (0x200 * i), 0x5411E2D0);
-
- /* enable VIP optional active */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- OUT_CTRL_NS + (0x200 * i), &tmp);
- value &= 0xFFFBFFFF;
- value |= 0x00040000;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- OUT_CTRL_NS + (0x200 * i), value);
-
- /* enable VIP optional active (VIP_OPT_AL) for direct output. */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- OUT_CTRL1 + (0x200 * i), &tmp);
- value &= 0xFFFBFFFF;
- value |= 0x00040000;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- OUT_CTRL1 + (0x200 * i), value);
-
- /*
- * clear VPRES_VERT_EN bit, fixes the chroma run away problem
- * when the input switching rate < 16 fields
- */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- MISC_TIM_CTRL + (0x200 * i), &tmp);
- /* disable special play detection */
- value = setBitAtPos(value, 14);
- value = clearBitAtPos(value, 15);
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- MISC_TIM_CTRL + (0x200 * i), value);
-
- /* set vbi_gate_en to 0 */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- DFE_CTRL1 + (0x200 * i), &tmp);
- value = clearBitAtPos(value, 29);
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DFE_CTRL1 + (0x200 * i), value);
-
- medusa_PALCombInit(dev, i);
-
- /* Enable the generation of blue field output if no video */
- medusa_enable_bluefield_output(dev, i, 1);
- }
-
- for (i = 0; i < MAX_ENCODERS; i++) {
- /* PAL hclock */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- DENC_A_REG_1 + (0x100 * i), &tmp);
- value &= 0xF000FC00;
- value |= 0x06C002D0;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DENC_A_REG_1 + (0x100 * i), value);
-
- /* burst begin and burst end */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- DENC_A_REG_2 + (0x100 * i), &tmp);
- value &= 0xFF000000;
- value |= 0x007E9754;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DENC_A_REG_2 + (0x100 * i), value);
-
- /* hblank and vactive */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- DENC_A_REG_3 + (0x100 * i), &tmp);
- value &= 0xFC00FE00;
- value |= 0x00FC0120;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DENC_A_REG_3 + (0x100 * i), value);
-
- /* set PAL vblank, phase alternation, 0 IRE pedestal */
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- DENC_A_REG_4 + (0x100 * i), &tmp);
- value &= 0x00FCFFFF;
- value |= 0x14010000;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DENC_A_REG_4 + (0x100 * i), value);
-
- value = cx25821_i2c_read(&dev->i2c_bus[0],
- DENC_A_REG_5 + (0x100 * i), &tmp);
- value &= 0xFFFF0000;
- value |= 0x0000F078;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DENC_A_REG_5 + (0x100 * i), value);
-
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DENC_A_REG_6 + (0x100 * i), 0x00A493CF);
-
- /* Subcarrier Increment */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
- DENC_A_REG_7 + (0x100 * i), 0x2A098ACB);
- }
-
- /* set picture resolutions */
- /* 0 - 720 */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0);
- /* 0 - 576 */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0);
-
- /* set Bypass input format to PAL 625 lines */
- value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
- value &= 0xFFF7FDFF;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
-
- mutex_unlock(&dev->lock);
-
- return ret_val;
-}
-
-int medusa_set_videostandard(struct cx25821_dev *dev)
-{
- int status = STATUS_SUCCESS;
- u32 value = 0, tmp = 0;
-
- if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
- status = medusa_initialize_pal(dev);
- else
- status = medusa_initialize_ntsc(dev);
-
- /* Enable DENC_A output */
- value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp);
- value = setBitAtPos(value, 4);
- status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value);
-
- /* Enable DENC_B output */
- value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp);
- value = setBitAtPos(value, 4);
- status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value);
-
- return status;
-}
-
-void medusa_set_resolution(struct cx25821_dev *dev, int width,
- int decoder_select)
-{
- int decoder = 0;
- int decoder_count = 0;
- u32 hscale = 0x0;
- u32 vscale = 0x0;
- const int MAX_WIDTH = 720;
-
- mutex_lock(&dev->lock);
-
- /* validate the width */
- if (width > MAX_WIDTH) {
- pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n",
- __func__, width, MAX_WIDTH);
- width = MAX_WIDTH;
- }
-
- if (decoder_select <= 7 && decoder_select >= 0) {
- decoder = decoder_select;
- decoder_count = decoder_select + 1;
- } else {
- decoder = 0;
- decoder_count = _num_decoders;
- }
-
- switch (width) {
- case 320:
- hscale = 0x13E34B;
- vscale = 0x0;
- break;
-
- case 352:
- hscale = 0x10A273;
- vscale = 0x0;
- break;
-
- case 176:
- hscale = 0x3115B2;
- vscale = 0x1E00;
- break;
-
- case 160:
- hscale = 0x378D84;
- vscale = 0x1E00;
- break;
-
- default: /* 720 */
- hscale = 0x0;
- vscale = 0x0;
- break;
- }
-
- for (; decoder < decoder_count; decoder++) {
- /* write scaling values for each decoder */
- cx25821_i2c_write(&dev->i2c_bus[0],
- HSCALE_CTRL + (0x200 * decoder), hscale);
- cx25821_i2c_write(&dev->i2c_bus[0],
- VSCALE_CTRL + (0x200 * decoder), vscale);
- }
-
- mutex_unlock(&dev->lock);
-}
-
-static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
- int duration)
-{
- u32 fld_cnt = 0;
- u32 tmp = 0;
- u32 disp_cnt_reg = DISP_AB_CNT;
-
- mutex_lock(&dev->lock);
-
- /* no support */
- if (decoder < VDEC_A || decoder > VDEC_H) {
- mutex_unlock(&dev->lock);
- return;
- }
-
- switch (decoder) {
- default:
- break;
- case VDEC_C:
- case VDEC_D:
- disp_cnt_reg = DISP_CD_CNT;
- break;
- case VDEC_E:
- case VDEC_F:
- disp_cnt_reg = DISP_EF_CNT;
- break;
- case VDEC_G:
- case VDEC_H:
- disp_cnt_reg = DISP_GH_CNT;
- break;
- }
-
- _display_field_cnt[decoder] = duration;
-
- /* update hardware */
- fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp);
-
- if (!(decoder % 2)) { /* EVEN decoder */
- fld_cnt &= 0xFFFF0000;
- fld_cnt |= duration;
- } else {
- fld_cnt &= 0x0000FFFF;
- fld_cnt |= ((u32) duration) << 16;
- }
-
- cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt);
-
- mutex_unlock(&dev->lock);
-}
-
-/* Map to Medusa register setting */
-static int mapM(int srcMin, int srcMax, int srcVal, int dstMin, int dstMax,
- int *dstVal)
-{
- int numerator;
- int denominator;
- int quotient;
-
- if ((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax))
- return -1;
- /*
- * This is the overall expression used:
- * *dstVal =
- * (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin;
- * but we need to account for rounding so below we use the modulus
- * operator to find the remainder and increment if necessary.
- */
- numerator = (srcVal - srcMin) * (dstMax - dstMin);
- denominator = srcMax - srcMin;
- quotient = numerator / denominator;
-
- if (2 * (numerator % denominator) >= denominator)
- quotient++;
-
- *dstVal = quotient + dstMin;
-
- return 0;
-}
-
-static unsigned long convert_to_twos(long numeric, unsigned long bits_len)
-{
- unsigned char temp;
-
- if (numeric >= 0)
- return numeric;
- else {
- temp = ~(abs(numeric) & 0xFF);
- temp += 1;
- return temp;
- }
-}
-
-int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)
-{
- int ret_val = 0;
- int value = 0;
- u32 val = 0, tmp = 0;
-
- mutex_lock(&dev->lock);
- if ((brightness > VIDEO_PROCAMP_MAX) ||
- (brightness < VIDEO_PROCAMP_MIN)) {
- mutex_unlock(&dev->lock);
- return -1;
- }
- ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness,
- SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
- value = convert_to_twos(value, 8);
- val = cx25821_i2c_read(&dev->i2c_bus[0],
- VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp);
- val &= 0xFFFFFF00;
- ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
- VDEC_A_BRITE_CTRL + (0x200 * decoder), val | value);
- mutex_unlock(&dev->lock);
- return ret_val;
-}
-
-int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)
-{
- int ret_val = 0;
- int value = 0;
- u32 val = 0, tmp = 0;
-
- mutex_lock(&dev->lock);
-
- if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) {
- mutex_unlock(&dev->lock);
- return -1;
- }
-
- ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast,
- UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
- val = cx25821_i2c_read(&dev->i2c_bus[0],
- VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp);
- val &= 0xFFFFFF00;
- ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
- VDEC_A_CNTRST_CTRL + (0x200 * decoder), val | value);
-
- mutex_unlock(&dev->lock);
- return ret_val;
-}
-
-int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)
-{
- int ret_val = 0;
- int value = 0;
- u32 val = 0, tmp = 0;
-
- mutex_lock(&dev->lock);
-
- if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) {
- mutex_unlock(&dev->lock);
- return -1;
- }
-
- ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue,
- SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
-
- value = convert_to_twos(value, 8);
- val = cx25821_i2c_read(&dev->i2c_bus[0],
- VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp);
- val &= 0xFFFFFF00;
-
- ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
- VDEC_A_HUE_CTRL + (0x200 * decoder), val | value);
-
- mutex_unlock(&dev->lock);
- return ret_val;
-}
-
-int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
-{
- int ret_val = 0;
- int value = 0;
- u32 val = 0, tmp = 0;
-
- mutex_lock(&dev->lock);
-
- if ((saturation > VIDEO_PROCAMP_MAX) ||
- (saturation < VIDEO_PROCAMP_MIN)) {
- mutex_unlock(&dev->lock);
- return -1;
- }
-
- ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation,
- UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
-
- val = cx25821_i2c_read(&dev->i2c_bus[0],
- VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp);
- val &= 0xFFFFFF00;
- ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
- VDEC_A_USAT_CTRL + (0x200 * decoder), val | value);
-
- val = cx25821_i2c_read(&dev->i2c_bus[0],
- VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp);
- val &= 0xFFFFFF00;
- ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
- VDEC_A_VSAT_CTRL + (0x200 * decoder), val | value);
-
- mutex_unlock(&dev->lock);
- return ret_val;
-}
-
-/* Program the display sequence and monitor output. */
-
-int medusa_video_init(struct cx25821_dev *dev)
-{
- u32 value = 0, tmp = 0;
- int ret_val = 0;
- int i = 0;
-
- mutex_lock(&dev->lock);
-
- _num_decoders = dev->_max_num_decoders;
-
- /* disable Auto source selection on all video decoders */
- value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
- value &= 0xFFFFF0FF;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
-
- if (ret_val < 0)
- goto error;
-
- /* Turn off Master source switch enable */
- value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
- value &= 0xFFFFFFDF;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
-
- if (ret_val < 0)
- goto error;
-
- mutex_unlock(&dev->lock);
-
- for (i = 0; i < _num_decoders; i++)
- medusa_set_decoderduration(dev, i, _display_field_cnt[i]);
-
- mutex_lock(&dev->lock);
-
- /* Select monitor as DENC A input, power up the DAC */
- value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);
- value &= 0xFF70FF70;
- value |= 0x00090008; /* set en_active */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value);
-
- if (ret_val < 0)
- goto error;
-
- /* enable input is VIP/656 */
- value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
- value |= 0x00040100; /* enable VIP */
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
-
- if (ret_val < 0)
- goto error;
-
- /* select AFE clock to output mode */
- value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
- value &= 0x83FFFFFF;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL,
- value | 0x10000000);
-
- if (ret_val < 0)
- goto error;
-
- /* Turn on all of the data out and control output pins. */
- value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp);
- value &= 0xFEF0FE00;
- if (_num_decoders == MAX_DECODERS) {
- /*
- * Note: The octal board does not support control pins(bit16-19)
- * These bits are ignored in the octal board.
- *
- * disable VDEC A-C port, default to Mobilygen Interface
- */
- value |= 0x010001F8;
- } else {
- /* disable VDEC A-C port, default to Mobilygen Interface */
- value |= 0x010F0108;
- }
-
- value |= 7;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value);
-
- if (ret_val < 0)
- goto error;
-
-
- mutex_unlock(&dev->lock);
-
- ret_val = medusa_set_videostandard(dev);
-
- return ret_val;
-
-error:
- mutex_unlock(&dev->lock);
- return ret_val;
-}
diff --git a/drivers/media/video/cx25821/cx25821-medusa-video.h b/drivers/media/video/cx25821/cx25821-medusa-video.h
deleted file mode 100644
index 6175e096185..00000000000
--- a/drivers/media/video/cx25821/cx25821-medusa-video.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _MEDUSA_VIDEO_H
-#define _MEDUSA_VIDEO_H
-
-#include "cx25821-medusa-defines.h"
-
-/* Color control constants */
-#define VIDEO_PROCAMP_MIN 0
-#define VIDEO_PROCAMP_MAX 10000
-#define UNSIGNED_BYTE_MIN 0
-#define UNSIGNED_BYTE_MAX 0xFF
-#define SIGNED_BYTE_MIN -128
-#define SIGNED_BYTE_MAX 127
-
-/* Default video color settings */
-#define SHARPNESS_DEFAULT 50
-#define SATURATION_DEFAULT 5000
-#define BRIGHTNESS_DEFAULT 6200
-#define CONTRAST_DEFAULT 5000
-#define HUE_DEFAULT 5000
-
-unsigned short _num_decoders;
-unsigned short _num_cameras;
-
-unsigned int _video_standard;
-int _display_field_cnt[MAX_DECODERS];
-
-#endif
diff --git a/drivers/media/video/cx25821/cx25821-reg.h b/drivers/media/video/cx25821/cx25821-reg.h
deleted file mode 100644
index a3fc25a4dc0..00000000000
--- a/drivers/media/video/cx25821/cx25821-reg.h
+++ /dev/null
@@ -1,1592 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __CX25821_REGISTERS__
-#define __CX25821_REGISTERS__
-
-/* Risc Instructions */
-#define RISC_CNT_INC 0x00010000
-#define RISC_CNT_RESET 0x00030000
-#define RISC_IRQ1 0x01000000
-#define RISC_IRQ2 0x02000000
-#define RISC_EOL 0x04000000
-#define RISC_SOL 0x08000000
-#define RISC_WRITE 0x10000000
-#define RISC_SKIP 0x20000000
-#define RISC_JUMP 0x70000000
-#define RISC_SYNC 0x80000000
-#define RISC_RESYNC 0x80008000
-#define RISC_READ 0x90000000
-#define RISC_WRITERM 0xB0000000
-#define RISC_WRITECM 0xC0000000
-#define RISC_WRITECR 0xD0000000
-#define RISC_WRITEC 0x50000000
-#define RISC_READC 0xA0000000
-
-#define RISC_SYNC_ODD 0x00000000
-#define RISC_SYNC_EVEN 0x00000200
-#define RISC_SYNC_ODD_VBI 0x00000006
-#define RISC_SYNC_EVEN_VBI 0x00000207
-#define RISC_NOOP 0xF0000000
-
-/*****************************************************************************
-* ASB SRAM
- *****************************************************************************/
-#define TX_SRAM 0x000000 /* Transmit SRAM */
-
-/*****************************************************************************/
-#define RX_RAM 0x010000 /* Receive SRAM */
-
-/*****************************************************************************
-* Application Layer (AL)
- *****************************************************************************/
-#define DEV_CNTRL2 0x040000 /* Device control */
-#define FLD_RUN_RISC 0x00000020
-
-/* ***************************************************************************** */
-#define PCI_INT_MSK 0x040010 /* PCI interrupt mask */
-#define PCI_INT_STAT 0x040014 /* PCI interrupt status */
-#define PCI_INT_MSTAT 0x040018 /* PCI interrupt masked status */
-#define FLD_HAMMERHEAD_INT (1 << 27)
-#define FLD_UART_INT (1 << 26)
-#define FLD_IRQN_INT (1 << 25)
-#define FLD_TM_INT (1 << 28)
-#define FLD_I2C_3_RACK (1 << 27)
-#define FLD_I2C_3_INT (1 << 26)
-#define FLD_I2C_2_RACK (1 << 25)
-#define FLD_I2C_2_INT (1 << 24)
-#define FLD_I2C_1_RACK (1 << 23)
-#define FLD_I2C_1_INT (1 << 22)
-
-#define FLD_APB_DMA_BERR_INT (1 << 21)
-#define FLD_AL_WR_BERR_INT (1 << 20)
-#define FLD_AL_RD_BERR_INT (1 << 19)
-#define FLD_RISC_WR_BERR_INT (1 << 18)
-#define FLD_RISC_RD_BERR_INT (1 << 17)
-
-#define FLD_VID_I_INT (1 << 8)
-#define FLD_VID_H_INT (1 << 7)
-#define FLD_VID_G_INT (1 << 6)
-#define FLD_VID_F_INT (1 << 5)
-#define FLD_VID_E_INT (1 << 4)
-#define FLD_VID_D_INT (1 << 3)
-#define FLD_VID_C_INT (1 << 2)
-#define FLD_VID_B_INT (1 << 1)
-#define FLD_VID_A_INT (1 << 0)
-
-/* ***************************************************************************** */
-#define VID_A_INT_MSK 0x040020 /* Video A interrupt mask */
-#define VID_A_INT_STAT 0x040024 /* Video A interrupt status */
-#define VID_A_INT_MSTAT 0x040028 /* Video A interrupt masked status */
-#define VID_A_INT_SSTAT 0x04002C /* Video A interrupt set status */
-
-/* ***************************************************************************** */
-#define VID_B_INT_MSK 0x040030 /* Video B interrupt mask */
-#define VID_B_INT_STAT 0x040034 /* Video B interrupt status */
-#define VID_B_INT_MSTAT 0x040038 /* Video B interrupt masked status */
-#define VID_B_INT_SSTAT 0x04003C /* Video B interrupt set status */
-
-/* ***************************************************************************** */
-#define VID_C_INT_MSK 0x040040 /* Video C interrupt mask */
-#define VID_C_INT_STAT 0x040044 /* Video C interrupt status */
-#define VID_C_INT_MSTAT 0x040048 /* Video C interrupt masked status */
-#define VID_C_INT_SSTAT 0x04004C /* Video C interrupt set status */
-
-/* ***************************************************************************** */
-#define VID_D_INT_MSK 0x040050 /* Video D interrupt mask */
-#define VID_D_INT_STAT 0x040054 /* Video D interrupt status */
-#define VID_D_INT_MSTAT 0x040058 /* Video D interrupt masked status */
-#define VID_D_INT_SSTAT 0x04005C /* Video D interrupt set status */
-
-/* ***************************************************************************** */
-#define VID_E_INT_MSK 0x040060 /* Video E interrupt mask */
-#define VID_E_INT_STAT 0x040064 /* Video E interrupt status */
-#define VID_E_INT_MSTAT 0x040068 /* Video E interrupt masked status */
-#define VID_E_INT_SSTAT 0x04006C /* Video E interrupt set status */
-
-/* ***************************************************************************** */
-#define VID_F_INT_MSK 0x040070 /* Video F interrupt mask */
-#define VID_F_INT_STAT 0x040074 /* Video F interrupt status */
-#define VID_F_INT_MSTAT 0x040078 /* Video F interrupt masked status */
-#define VID_F_INT_SSTAT 0x04007C /* Video F interrupt set status */
-
-/* ***************************************************************************** */
-#define VID_G_INT_MSK 0x040080 /* Video G interrupt mask */
-#define VID_G_INT_STAT 0x040084 /* Video G interrupt status */
-#define VID_G_INT_MSTAT 0x040088 /* Video G interrupt masked status */
-#define VID_G_INT_SSTAT 0x04008C /* Video G interrupt set status */
-
-/* ***************************************************************************** */
-#define VID_H_INT_MSK 0x040090 /* Video H interrupt mask */
-#define VID_H_INT_STAT 0x040094 /* Video H interrupt status */
-#define VID_H_INT_MSTAT 0x040098 /* Video H interrupt masked status */
-#define VID_H_INT_SSTAT 0x04009C /* Video H interrupt set status */
-
-/* ***************************************************************************** */
-#define VID_I_INT_MSK 0x0400A0 /* Video I interrupt mask */
-#define VID_I_INT_STAT 0x0400A4 /* Video I interrupt status */
-#define VID_I_INT_MSTAT 0x0400A8 /* Video I interrupt masked status */
-#define VID_I_INT_SSTAT 0x0400AC /* Video I interrupt set status */
-
-/* ***************************************************************************** */
-#define VID_J_INT_MSK 0x0400B0 /* Video J interrupt mask */
-#define VID_J_INT_STAT 0x0400B4 /* Video J interrupt status */
-#define VID_J_INT_MSTAT 0x0400B8 /* Video J interrupt masked status */
-#define VID_J_INT_SSTAT 0x0400BC /* Video J interrupt set status */
-
-#define FLD_VID_SRC_OPC_ERR 0x00020000
-#define FLD_VID_DST_OPC_ERR 0x00010000
-#define FLD_VID_SRC_SYNC 0x00002000
-#define FLD_VID_DST_SYNC 0x00001000
-#define FLD_VID_SRC_UF 0x00000200
-#define FLD_VID_DST_OF 0x00000100
-#define FLD_VID_SRC_RISC2 0x00000020
-#define FLD_VID_DST_RISC2 0x00000010
-#define FLD_VID_SRC_RISC1 0x00000002
-#define FLD_VID_DST_RISC1 0x00000001
-#define FLD_VID_SRC_ERRORS (FLD_VID_SRC_OPC_ERR | FLD_VID_SRC_SYNC | FLD_VID_SRC_UF)
-#define FLD_VID_DST_ERRORS (FLD_VID_DST_OPC_ERR | FLD_VID_DST_SYNC | FLD_VID_DST_OF)
-
-/* ***************************************************************************** */
-#define AUD_A_INT_MSK 0x0400C0 /* Audio Int interrupt mask */
-#define AUD_A_INT_STAT 0x0400C4 /* Audio Int interrupt status */
-#define AUD_A_INT_MSTAT 0x0400C8 /* Audio Int interrupt masked status */
-#define AUD_A_INT_SSTAT 0x0400CC /* Audio Int interrupt set status */
-
-/* ***************************************************************************** */
-#define AUD_B_INT_MSK 0x0400D0 /* Audio Int interrupt mask */
-#define AUD_B_INT_STAT 0x0400D4 /* Audio Int interrupt status */
-#define AUD_B_INT_MSTAT 0x0400D8 /* Audio Int interrupt masked status */
-#define AUD_B_INT_SSTAT 0x0400DC /* Audio Int interrupt set status */
-
-/* ***************************************************************************** */
-#define AUD_C_INT_MSK 0x0400E0 /* Audio Int interrupt mask */
-#define AUD_C_INT_STAT 0x0400E4 /* Audio Int interrupt status */
-#define AUD_C_INT_MSTAT 0x0400E8 /* Audio Int interrupt masked status */
-#define AUD_C_INT_SSTAT 0x0400EC /* Audio Int interrupt set status */
-
-/* ***************************************************************************** */
-#define AUD_D_INT_MSK 0x0400F0 /* Audio Int interrupt mask */
-#define AUD_D_INT_STAT 0x0400F4 /* Audio Int interrupt status */
-#define AUD_D_INT_MSTAT 0x0400F8 /* Audio Int interrupt masked status */
-#define AUD_D_INT_SSTAT 0x0400FC /* Audio Int interrupt set status */
-
-/* ***************************************************************************** */
-#define AUD_E_INT_MSK 0x040100 /* Audio Int interrupt mask */
-#define AUD_E_INT_STAT 0x040104 /* Audio Int interrupt status */
-#define AUD_E_INT_MSTAT 0x040108 /* Audio Int interrupt masked status */
-#define AUD_E_INT_SSTAT 0x04010C /* Audio Int interrupt set status */
-
-#define FLD_AUD_SRC_OPC_ERR 0x00020000
-#define FLD_AUD_DST_OPC_ERR 0x00010000
-#define FLD_AUD_SRC_SYNC 0x00002000
-#define FLD_AUD_DST_SYNC 0x00001000
-#define FLD_AUD_SRC_OF 0x00000200
-#define FLD_AUD_DST_OF 0x00000100
-#define FLD_AUD_SRC_RISCI2 0x00000020
-#define FLD_AUD_DST_RISCI2 0x00000010
-#define FLD_AUD_SRC_RISCI1 0x00000002
-#define FLD_AUD_DST_RISCI1 0x00000001
-
-/* ***************************************************************************** */
-#define MBIF_A_INT_MSK 0x040110 /* MBIF Int interrupt mask */
-#define MBIF_A_INT_STAT 0x040114 /* MBIF Int interrupt status */
-#define MBIF_A_INT_MSTAT 0x040118 /* MBIF Int interrupt masked status */
-#define MBIF_A_INT_SSTAT 0x04011C /* MBIF Int interrupt set status */
-
-/* ***************************************************************************** */
-#define MBIF_B_INT_MSK 0x040120 /* MBIF Int interrupt mask */
-#define MBIF_B_INT_STAT 0x040124 /* MBIF Int interrupt status */
-#define MBIF_B_INT_MSTAT 0x040128 /* MBIF Int interrupt masked status */
-#define MBIF_B_INT_SSTAT 0x04012C /* MBIF Int interrupt set status */
-
-#define FLD_MBIF_DST_OPC_ERR 0x00010000
-#define FLD_MBIF_DST_SYNC 0x00001000
-#define FLD_MBIF_DST_OF 0x00000100
-#define FLD_MBIF_DST_RISCI2 0x00000010
-#define FLD_MBIF_DST_RISCI1 0x00000001
-
-/* ***************************************************************************** */
-#define AUD_EXT_INT_MSK 0x040060 /* Audio Ext interrupt mask */
-#define AUD_EXT_INT_STAT 0x040064 /* Audio Ext interrupt status */
-#define AUD_EXT_INT_MSTAT 0x040068 /* Audio Ext interrupt masked status */
-#define AUD_EXT_INT_SSTAT 0x04006C /* Audio Ext interrupt set status */
-#define FLD_AUD_EXT_OPC_ERR 0x00010000
-#define FLD_AUD_EXT_SYNC 0x00001000
-#define FLD_AUD_EXT_OF 0x00000100
-#define FLD_AUD_EXT_RISCI2 0x00000010
-#define FLD_AUD_EXT_RISCI1 0x00000001
-
-/* ***************************************************************************** */
-#define GPIO_LO 0x110010 /* Lower of GPIO pins [31:0] */
-#define GPIO_HI 0x110014 /* Upper WORD of GPIO pins [47:31] */
-
-#define GPIO_LO_OE 0x110018 /* Lower of GPIO output enable [31:0] */
-#define GPIO_HI_OE 0x11001C /* Upper word of GPIO output enable [47:32] */
-
-#define GPIO_LO_INT_MSK 0x11003C /* GPIO interrupt mask */
-#define GPIO_LO_INT_STAT 0x110044 /* GPIO interrupt status */
-#define GPIO_LO_INT_MSTAT 0x11004C /* GPIO interrupt masked status */
-#define GPIO_LO_ISM_SNS 0x110054 /* GPIO interrupt sensitivity */
-#define GPIO_LO_ISM_POL 0x11005C /* GPIO interrupt polarity */
-
-#define GPIO_HI_INT_MSK 0x110040 /* GPIO interrupt mask */
-#define GPIO_HI_INT_STAT 0x110048 /* GPIO interrupt status */
-#define GPIO_HI_INT_MSTAT 0x110050 /* GPIO interrupt masked status */
-#define GPIO_HI_ISM_SNS 0x110058 /* GPIO interrupt sensitivity */
-#define GPIO_HI_ISM_POL 0x110060 /* GPIO interrupt polarity */
-
-#define FLD_GPIO43_INT (1 << 11)
-#define FLD_GPIO42_INT (1 << 10)
-#define FLD_GPIO41_INT (1 << 9)
-#define FLD_GPIO40_INT (1 << 8)
-
-#define FLD_GPIO9_INT (1 << 9)
-#define FLD_GPIO8_INT (1 << 8)
-#define FLD_GPIO7_INT (1 << 7)
-#define FLD_GPIO6_INT (1 << 6)
-#define FLD_GPIO5_INT (1 << 5)
-#define FLD_GPIO4_INT (1 << 4)
-#define FLD_GPIO3_INT (1 << 3)
-#define FLD_GPIO2_INT (1 << 2)
-#define FLD_GPIO1_INT (1 << 1)
-#define FLD_GPIO0_INT (1 << 0)
-
-/* ***************************************************************************** */
-#define TC_REQ 0x040090 /* Rider PCI Express traFFic class request */
-
-/* ***************************************************************************** */
-#define TC_REQ_SET 0x040094 /* Rider PCI Express traFFic class request set */
-
-/* ***************************************************************************** */
-/* Rider */
-/* ***************************************************************************** */
-
-/* PCI Compatible Header */
-/* ***************************************************************************** */
-#define RDR_CFG0 0x050000
-#define RDR_VENDOR_DEVICE_ID_CFG 0x050000
-
-/* ***************************************************************************** */
-#define RDR_CFG1 0x050004
-
-/* ***************************************************************************** */
-#define RDR_CFG2 0x050008
-
-/* ***************************************************************************** */
-#define RDR_CFG3 0x05000C
-
-/* ***************************************************************************** */
-#define RDR_CFG4 0x050010
-
-/* ***************************************************************************** */
-#define RDR_CFG5 0x050014
-
-/* ***************************************************************************** */
-#define RDR_CFG6 0x050018
-
-/* ***************************************************************************** */
-#define RDR_CFG7 0x05001C
-
-/* ***************************************************************************** */
-#define RDR_CFG8 0x050020
-
-/* ***************************************************************************** */
-#define RDR_CFG9 0x050024
-
-/* ***************************************************************************** */
-#define RDR_CFGA 0x050028
-
-/* ***************************************************************************** */
-#define RDR_CFGB 0x05002C
-#define RDR_SUSSYSTEM_ID_CFG 0x05002C
-
-/* ***************************************************************************** */
-#define RDR_CFGC 0x050030
-
-/* ***************************************************************************** */
-#define RDR_CFGD 0x050034
-
-/* ***************************************************************************** */
-#define RDR_CFGE 0x050038
-
-/* ***************************************************************************** */
-#define RDR_CFGF 0x05003C
-
-/* ***************************************************************************** */
-/* PCI-Express Capabilities */
-/* ***************************************************************************** */
-#define RDR_PECAP 0x050040
-
-/* ***************************************************************************** */
-#define RDR_PEDEVCAP 0x050044
-
-/* ***************************************************************************** */
-#define RDR_PEDEVSC 0x050048
-
-/* ***************************************************************************** */
-#define RDR_PELINKCAP 0x05004C
-
-/* ***************************************************************************** */
-#define RDR_PELINKSC 0x050050
-
-/* ***************************************************************************** */
-#define RDR_PMICAP 0x050080
-
-/* ***************************************************************************** */
-#define RDR_PMCSR 0x050084
-
-/* ***************************************************************************** */
-#define RDR_VPDCAP 0x050090
-
-/* ***************************************************************************** */
-#define RDR_VPDDATA 0x050094
-
-/* ***************************************************************************** */
-#define RDR_MSICAP 0x0500A0
-
-/* ***************************************************************************** */
-#define RDR_MSIARL 0x0500A4
-
-/* ***************************************************************************** */
-#define RDR_MSIARU 0x0500A8
-
-/* ***************************************************************************** */
-#define RDR_MSIDATA 0x0500AC
-
-/* ***************************************************************************** */
-/* PCI Express Extended Capabilities */
-/* ***************************************************************************** */
-#define RDR_AERXCAP 0x050100
-
-/* ***************************************************************************** */
-#define RDR_AERUESTA 0x050104
-
-/* ***************************************************************************** */
-#define RDR_AERUEMSK 0x050108
-
-/* ***************************************************************************** */
-#define RDR_AERUESEV 0x05010C
-
-/* ***************************************************************************** */
-#define RDR_AERCESTA 0x050110
-
-/* ***************************************************************************** */
-#define RDR_AERCEMSK 0x050114
-
-/* ***************************************************************************** */
-#define RDR_AERCC 0x050118
-
-/* ***************************************************************************** */
-#define RDR_AERHL0 0x05011C
-
-/* ***************************************************************************** */
-#define RDR_AERHL1 0x050120
-
-/* ***************************************************************************** */
-#define RDR_AERHL2 0x050124
-
-/* ***************************************************************************** */
-#define RDR_AERHL3 0x050128
-
-/* ***************************************************************************** */
-#define RDR_VCXCAP 0x050200
-
-/* ***************************************************************************** */
-#define RDR_VCCAP1 0x050204
-
-/* ***************************************************************************** */
-#define RDR_VCCAP2 0x050208
-
-/* ***************************************************************************** */
-#define RDR_VCSC 0x05020C
-
-/* ***************************************************************************** */
-#define RDR_VCR0_CAP 0x050210
-
-/* ***************************************************************************** */
-#define RDR_VCR0_CTRL 0x050214
-
-/* ***************************************************************************** */
-#define RDR_VCR0_STAT 0x050218
-
-/* ***************************************************************************** */
-#define RDR_VCR1_CAP 0x05021C
-
-/* ***************************************************************************** */
-#define RDR_VCR1_CTRL 0x050220
-
-/* ***************************************************************************** */
-#define RDR_VCR1_STAT 0x050224
-
-/* ***************************************************************************** */
-#define RDR_VCR2_CAP 0x050228
-
-/* ***************************************************************************** */
-#define RDR_VCR2_CTRL 0x05022C
-
-/* ***************************************************************************** */
-#define RDR_VCR2_STAT 0x050230
-
-/* ***************************************************************************** */
-#define RDR_VCR3_CAP 0x050234
-
-/* ***************************************************************************** */
-#define RDR_VCR3_CTRL 0x050238
-
-/* ***************************************************************************** */
-#define RDR_VCR3_STAT 0x05023C
-
-/* ***************************************************************************** */
-#define RDR_VCARB0 0x050240
-
-/* ***************************************************************************** */
-#define RDR_VCARB1 0x050244
-
-/* ***************************************************************************** */
-#define RDR_VCARB2 0x050248
-
-/* ***************************************************************************** */
-#define RDR_VCARB3 0x05024C
-
-/* ***************************************************************************** */
-#define RDR_VCARB4 0x050250
-
-/* ***************************************************************************** */
-#define RDR_VCARB5 0x050254
-
-/* ***************************************************************************** */
-#define RDR_VCARB6 0x050258
-
-/* ***************************************************************************** */
-#define RDR_VCARB7 0x05025C
-
-/* ***************************************************************************** */
-#define RDR_RDRSTAT0 0x050300
-
-/* ***************************************************************************** */
-#define RDR_RDRSTAT1 0x050304
-
-/* ***************************************************************************** */
-#define RDR_RDRCTL0 0x050308
-
-/* ***************************************************************************** */
-#define RDR_RDRCTL1 0x05030C
-
-/* ***************************************************************************** */
-/* Transaction Layer Registers */
-/* ***************************************************************************** */
-#define RDR_TLSTAT0 0x050310
-
-/* ***************************************************************************** */
-#define RDR_TLSTAT1 0x050314
-
-/* ***************************************************************************** */
-#define RDR_TLCTL0 0x050318
-#define FLD_CFG_UR_CPL_MODE 0x00000040
-#define FLD_CFG_CORR_ERR_QUITE 0x00000020
-#define FLD_CFG_RCB_CK_EN 0x00000010
-#define FLD_CFG_BNDRY_CK_EN 0x00000008
-#define FLD_CFG_BYTE_EN_CK_EN 0x00000004
-#define FLD_CFG_RELAX_ORDER_MSK 0x00000002
-#define FLD_CFG_TAG_ORDER_EN 0x00000001
-
-/* ***************************************************************************** */
-#define RDR_TLCTL1 0x05031C
-
-/* ***************************************************************************** */
-#define RDR_REQRCAL 0x050320
-
-/* ***************************************************************************** */
-#define RDR_REQRCAU 0x050324
-
-/* ***************************************************************************** */
-#define RDR_REQEPA 0x050328
-
-/* ***************************************************************************** */
-#define RDR_REQCTRL 0x05032C
-
-/* ***************************************************************************** */
-#define RDR_REQSTAT 0x050330
-
-/* ***************************************************************************** */
-#define RDR_TL_TEST 0x050334
-
-/* ***************************************************************************** */
-#define RDR_VCR01_CTL 0x050348
-
-/* ***************************************************************************** */
-#define RDR_VCR23_CTL 0x05034C
-
-/* ***************************************************************************** */
-#define RDR_RX_VCR0_FC 0x050350
-
-/* ***************************************************************************** */
-#define RDR_RX_VCR1_FC 0x050354
-
-/* ***************************************************************************** */
-#define RDR_RX_VCR2_FC 0x050358
-
-/* ***************************************************************************** */
-#define RDR_RX_VCR3_FC 0x05035C
-
-/* ***************************************************************************** */
-/* Data Link Layer Registers */
-/* ***************************************************************************** */
-#define RDR_DLLSTAT 0x050360
-
-/* ***************************************************************************** */
-#define RDR_DLLCTRL 0x050364
-
-/* ***************************************************************************** */
-#define RDR_REPLAYTO 0x050368
-
-/* ***************************************************************************** */
-#define RDR_ACKLATTO 0x05036C
-
-/* ***************************************************************************** */
-/* MAC Layer Registers */
-/* ***************************************************************************** */
-#define RDR_MACSTAT0 0x050380
-
-/* ***************************************************************************** */
-#define RDR_MACSTAT1 0x050384
-
-/* ***************************************************************************** */
-#define RDR_MACCTRL0 0x050388
-
-/* ***************************************************************************** */
-#define RDR_MACCTRL1 0x05038C
-
-/* ***************************************************************************** */
-#define RDR_MACCTRL2 0x050390
-
-/* ***************************************************************************** */
-#define RDR_MAC_LB_DATA 0x050394
-
-/* ***************************************************************************** */
-#define RDR_L0S_EXIT_LAT 0x050398
-
-/* ***************************************************************************** */
-/* DMAC */
-/* ***************************************************************************** */
-#define DMA1_PTR1 0x100000 /* DMA Current Ptr : Ch#1 */
-
-/* ***************************************************************************** */
-#define DMA2_PTR1 0x100004 /* DMA Current Ptr : Ch#2 */
-
-/* ***************************************************************************** */
-#define DMA3_PTR1 0x100008 /* DMA Current Ptr : Ch#3 */
-
-/* ***************************************************************************** */
-#define DMA4_PTR1 0x10000C /* DMA Current Ptr : Ch#4 */
-
-/* ***************************************************************************** */
-#define DMA5_PTR1 0x100010 /* DMA Current Ptr : Ch#5 */
-
-/* ***************************************************************************** */
-#define DMA6_PTR1 0x100014 /* DMA Current Ptr : Ch#6 */
-
-/* ***************************************************************************** */
-#define DMA7_PTR1 0x100018 /* DMA Current Ptr : Ch#7 */
-
-/* ***************************************************************************** */
-#define DMA8_PTR1 0x10001C /* DMA Current Ptr : Ch#8 */
-
-/* ***************************************************************************** */
-#define DMA9_PTR1 0x100020 /* DMA Current Ptr : Ch#9 */
-
-/* ***************************************************************************** */
-#define DMA10_PTR1 0x100024 /* DMA Current Ptr : Ch#10 */
-
-/* ***************************************************************************** */
-#define DMA11_PTR1 0x100028 /* DMA Current Ptr : Ch#11 */
-
-/* ***************************************************************************** */
-#define DMA12_PTR1 0x10002C /* DMA Current Ptr : Ch#12 */
-
-/* ***************************************************************************** */
-#define DMA13_PTR1 0x100030 /* DMA Current Ptr : Ch#13 */
-
-/* ***************************************************************************** */
-#define DMA14_PTR1 0x100034 /* DMA Current Ptr : Ch#14 */
-
-/* ***************************************************************************** */
-#define DMA15_PTR1 0x100038 /* DMA Current Ptr : Ch#15 */
-
-/* ***************************************************************************** */
-#define DMA16_PTR1 0x10003C /* DMA Current Ptr : Ch#16 */
-
-/* ***************************************************************************** */
-#define DMA17_PTR1 0x100040 /* DMA Current Ptr : Ch#17 */
-
-/* ***************************************************************************** */
-#define DMA18_PTR1 0x100044 /* DMA Current Ptr : Ch#18 */
-
-/* ***************************************************************************** */
-#define DMA19_PTR1 0x100048 /* DMA Current Ptr : Ch#19 */
-
-/* ***************************************************************************** */
-#define DMA20_PTR1 0x10004C /* DMA Current Ptr : Ch#20 */
-
-/* ***************************************************************************** */
-#define DMA21_PTR1 0x100050 /* DMA Current Ptr : Ch#21 */
-
-/* ***************************************************************************** */
-#define DMA22_PTR1 0x100054 /* DMA Current Ptr : Ch#22 */
-
-/* ***************************************************************************** */
-#define DMA23_PTR1 0x100058 /* DMA Current Ptr : Ch#23 */
-
-/* ***************************************************************************** */
-#define DMA24_PTR1 0x10005C /* DMA Current Ptr : Ch#24 */
-
-/* ***************************************************************************** */
-#define DMA25_PTR1 0x100060 /* DMA Current Ptr : Ch#25 */
-
-/* ***************************************************************************** */
-#define DMA26_PTR1 0x100064 /* DMA Current Ptr : Ch#26 */
-
-/* ***************************************************************************** */
-#define DMA1_PTR2 0x100080 /* DMA Tab Ptr : Ch#1 */
-
-/* ***************************************************************************** */
-#define DMA2_PTR2 0x100084 /* DMA Tab Ptr : Ch#2 */
-
-/* ***************************************************************************** */
-#define DMA3_PTR2 0x100088 /* DMA Tab Ptr : Ch#3 */
-
-/* ***************************************************************************** */
-#define DMA4_PTR2 0x10008C /* DMA Tab Ptr : Ch#4 */
-
-/* ***************************************************************************** */
-#define DMA5_PTR2 0x100090 /* DMA Tab Ptr : Ch#5 */
-
-/* ***************************************************************************** */
-#define DMA6_PTR2 0x100094 /* DMA Tab Ptr : Ch#6 */
-
-/* ***************************************************************************** */
-#define DMA7_PTR2 0x100098 /* DMA Tab Ptr : Ch#7 */
-
-/* ***************************************************************************** */
-#define DMA8_PTR2 0x10009C /* DMA Tab Ptr : Ch#8 */
-
-/* ***************************************************************************** */
-#define DMA9_PTR2 0x1000A0 /* DMA Tab Ptr : Ch#9 */
-
-/* ***************************************************************************** */
-#define DMA10_PTR2 0x1000A4 /* DMA Tab Ptr : Ch#10 */
-
-/* ***************************************************************************** */
-#define DMA11_PTR2 0x1000A8 /* DMA Tab Ptr : Ch#11 */
-
-/* ***************************************************************************** */
-#define DMA12_PTR2 0x1000AC /* DMA Tab Ptr : Ch#12 */
-
-/* ***************************************************************************** */
-#define DMA13_PTR2 0x1000B0 /* DMA Tab Ptr : Ch#13 */
-
-/* ***************************************************************************** */
-#define DMA14_PTR2 0x1000B4 /* DMA Tab Ptr : Ch#14 */
-
-/* ***************************************************************************** */
-#define DMA15_PTR2 0x1000B8 /* DMA Tab Ptr : Ch#15 */
-
-/* ***************************************************************************** */
-#define DMA16_PTR2 0x1000BC /* DMA Tab Ptr : Ch#16 */
-
-/* ***************************************************************************** */
-#define DMA17_PTR2 0x1000C0 /* DMA Tab Ptr : Ch#17 */
-
-/* ***************************************************************************** */
-#define DMA18_PTR2 0x1000C4 /* DMA Tab Ptr : Ch#18 */
-
-/* ***************************************************************************** */
-#define DMA19_PTR2 0x1000C8 /* DMA Tab Ptr : Ch#19 */
-
-/* ***************************************************************************** */
-#define DMA20_PTR2 0x1000CC /* DMA Tab Ptr : Ch#20 */
-
-/* ***************************************************************************** */
-#define DMA21_PTR2 0x1000D0 /* DMA Tab Ptr : Ch#21 */
-
-/* ***************************************************************************** */
-#define DMA22_PTR2 0x1000D4 /* DMA Tab Ptr : Ch#22 */
-
-/* ***************************************************************************** */
-#define DMA23_PTR2 0x1000D8 /* DMA Tab Ptr : Ch#23 */
-
-/* ***************************************************************************** */
-#define DMA24_PTR2 0x1000DC /* DMA Tab Ptr : Ch#24 */
-
-/* ***************************************************************************** */
-#define DMA25_PTR2 0x1000E0 /* DMA Tab Ptr : Ch#25 */
-
-/* ***************************************************************************** */
-#define DMA26_PTR2 0x1000E4 /* DMA Tab Ptr : Ch#26 */
-
-/* ***************************************************************************** */
-#define DMA1_CNT1 0x100100 /* DMA BuFFer Size : Ch#1 */
-
-/* ***************************************************************************** */
-#define DMA2_CNT1 0x100104 /* DMA BuFFer Size : Ch#2 */
-
-/* ***************************************************************************** */
-#define DMA3_CNT1 0x100108 /* DMA BuFFer Size : Ch#3 */
-
-/* ***************************************************************************** */
-#define DMA4_CNT1 0x10010C /* DMA BuFFer Size : Ch#4 */
-
-/* ***************************************************************************** */
-#define DMA5_CNT1 0x100110 /* DMA BuFFer Size : Ch#5 */
-
-/* ***************************************************************************** */
-#define DMA6_CNT1 0x100114 /* DMA BuFFer Size : Ch#6 */
-
-/* ***************************************************************************** */
-#define DMA7_CNT1 0x100118 /* DMA BuFFer Size : Ch#7 */
-
-/* ***************************************************************************** */
-#define DMA8_CNT1 0x10011C /* DMA BuFFer Size : Ch#8 */
-
-/* ***************************************************************************** */
-#define DMA9_CNT1 0x100120 /* DMA BuFFer Size : Ch#9 */
-
-/* ***************************************************************************** */
-#define DMA10_CNT1 0x100124 /* DMA BuFFer Size : Ch#10 */
-
-/* ***************************************************************************** */
-#define DMA11_CNT1 0x100128 /* DMA BuFFer Size : Ch#11 */
-
-/* ***************************************************************************** */
-#define DMA12_CNT1 0x10012C /* DMA BuFFer Size : Ch#12 */
-
-/* ***************************************************************************** */
-#define DMA13_CNT1 0x100130 /* DMA BuFFer Size : Ch#13 */
-
-/* ***************************************************************************** */
-#define DMA14_CNT1 0x100134 /* DMA BuFFer Size : Ch#14 */
-
-/* ***************************************************************************** */
-#define DMA15_CNT1 0x100138 /* DMA BuFFer Size : Ch#15 */
-
-/* ***************************************************************************** */
-#define DMA16_CNT1 0x10013C /* DMA BuFFer Size : Ch#16 */
-
-/* ***************************************************************************** */
-#define DMA17_CNT1 0x100140 /* DMA BuFFer Size : Ch#17 */
-
-/* ***************************************************************************** */
-#define DMA18_CNT1 0x100144 /* DMA BuFFer Size : Ch#18 */
-
-/* ***************************************************************************** */
-#define DMA19_CNT1 0x100148 /* DMA BuFFer Size : Ch#19 */
-
-/* ***************************************************************************** */
-#define DMA20_CNT1 0x10014C /* DMA BuFFer Size : Ch#20 */
-
-/* ***************************************************************************** */
-#define DMA21_CNT1 0x100150 /* DMA BuFFer Size : Ch#21 */
-
-/* ***************************************************************************** */
-#define DMA22_CNT1 0x100154 /* DMA BuFFer Size : Ch#22 */
-
-/* ***************************************************************************** */
-#define DMA23_CNT1 0x100158 /* DMA BuFFer Size : Ch#23 */
-
-/* ***************************************************************************** */
-#define DMA24_CNT1 0x10015C /* DMA BuFFer Size : Ch#24 */
-
-/* ***************************************************************************** */
-#define DMA25_CNT1 0x100160 /* DMA BuFFer Size : Ch#25 */
-
-/* ***************************************************************************** */
-#define DMA26_CNT1 0x100164 /* DMA BuFFer Size : Ch#26 */
-
-/* ***************************************************************************** */
-#define DMA1_CNT2 0x100180 /* DMA Table Size : Ch#1 */
-
-/* ***************************************************************************** */
-#define DMA2_CNT2 0x100184 /* DMA Table Size : Ch#2 */
-
-/* ***************************************************************************** */
-#define DMA3_CNT2 0x100188 /* DMA Table Size : Ch#3 */
-
-/* ***************************************************************************** */
-#define DMA4_CNT2 0x10018C /* DMA Table Size : Ch#4 */
-
-/* ***************************************************************************** */
-#define DMA5_CNT2 0x100190 /* DMA Table Size : Ch#5 */
-
-/* ***************************************************************************** */
-#define DMA6_CNT2 0x100194 /* DMA Table Size : Ch#6 */
-
-/* ***************************************************************************** */
-#define DMA7_CNT2 0x100198 /* DMA Table Size : Ch#7 */
-
-/* ***************************************************************************** */
-#define DMA8_CNT2 0x10019C /* DMA Table Size : Ch#8 */
-
-/* ***************************************************************************** */
-#define DMA9_CNT2 0x1001A0 /* DMA Table Size : Ch#9 */
-
-/* ***************************************************************************** */
-#define DMA10_CNT2 0x1001A4 /* DMA Table Size : Ch#10 */
-
-/* ***************************************************************************** */
-#define DMA11_CNT2 0x1001A8 /* DMA Table Size : Ch#11 */
-
-/* ***************************************************************************** */
-#define DMA12_CNT2 0x1001AC /* DMA Table Size : Ch#12 */
-
-/* ***************************************************************************** */
-#define DMA13_CNT2 0x1001B0 /* DMA Table Size : Ch#13 */
-
-/* ***************************************************************************** */
-#define DMA14_CNT2 0x1001B4 /* DMA Table Size : Ch#14 */
-
-/* ***************************************************************************** */
-#define DMA15_CNT2 0x1001B8 /* DMA Table Size : Ch#15 */
-
-/* ***************************************************************************** */
-#define DMA16_CNT2 0x1001BC /* DMA Table Size : Ch#16 */
-
-/* ***************************************************************************** */
-#define DMA17_CNT2 0x1001C0 /* DMA Table Size : Ch#17 */
-
-/* ***************************************************************************** */
-#define DMA18_CNT2 0x1001C4 /* DMA Table Size : Ch#18 */
-
-/* ***************************************************************************** */
-#define DMA19_CNT2 0x1001C8 /* DMA Table Size : Ch#19 */
-
-/* ***************************************************************************** */
-#define DMA20_CNT2 0x1001CC /* DMA Table Size : Ch#20 */
-
-/* ***************************************************************************** */
-#define DMA21_CNT2 0x1001D0 /* DMA Table Size : Ch#21 */
-
-/* ***************************************************************************** */
-#define DMA22_CNT2 0x1001D4 /* DMA Table Size : Ch#22 */
-
-/* ***************************************************************************** */
-#define DMA23_CNT2 0x1001D8 /* DMA Table Size : Ch#23 */
-
-/* ***************************************************************************** */
-#define DMA24_CNT2 0x1001DC /* DMA Table Size : Ch#24 */
-
-/* ***************************************************************************** */
-#define DMA25_CNT2 0x1001E0 /* DMA Table Size : Ch#25 */
-
-/* ***************************************************************************** */
-#define DMA26_CNT2 0x1001E4 /* DMA Table Size : Ch#26 */
-
-/* ***************************************************************************** */
- /* ITG */
-/* ***************************************************************************** */
-#define TM_CNT_LDW 0x110000 /* Timer : Counter low */
-
-/* ***************************************************************************** */
-#define TM_CNT_UW 0x110004 /* Timer : Counter high word */
-
-/* ***************************************************************************** */
-#define TM_LMT_LDW 0x110008 /* Timer : Limit low */
-
-/* ***************************************************************************** */
-#define TM_LMT_UW 0x11000C /* Timer : Limit high word */
-
-/* ***************************************************************************** */
-#define GP0_IO 0x110010 /* GPIO output enables data I/O */
-#define FLD_GP_OE 0x00FF0000 /* GPIO: GP_OE output enable */
-#define FLD_GP_IN 0x0000FF00 /* GPIO: GP_IN status */
-#define FLD_GP_OUT 0x000000FF /* GPIO: GP_OUT control */
-
-/* ***************************************************************************** */
-#define GPIO_ISM 0x110014 /* GPIO interrupt sensitivity mode */
-#define FLD_GP_ISM_SNS 0x00000070
-#define FLD_GP_ISM_POL 0x00000007
-
-/* ***************************************************************************** */
-#define SOFT_RESET 0x11001C /* Output system reset reg */
-#define FLD_PECOS_SOFT_RESET 0x00000001
-
-/* ***************************************************************************** */
-#define MC416_RWD 0x110020 /* MC416 GPIO[18:3] pin */
-#define MC416_OEN 0x110024 /* Output enable of GPIO[18:3] */
-#define MC416_CTL 0x110028
-
-/* ***************************************************************************** */
-#define ALT_PIN_OUT_SEL 0x11002C /* Alternate GPIO output select */
-
-#define FLD_ALT_GPIO_OUT_SEL 0xF0000000
-/* 0 Disabled <-- default */
-/* 1 GPIO[0] */
-/* 2 GPIO[10] */
-/* 3 VIP_656_DATA_VAL */
-/* 4 VIP_656_DATA[0] */
-/* 5 VIP_656_CLK */
-/* 6 VIP_656_DATA_EXT[1] */
-/* 7 VIP_656_DATA_EXT[0] */
-/* 8 ATT_IF */
-
-#define FLD_AUX_PLL_CLK_ALT_SEL 0x0F000000
-/* 0 AUX_PLL_CLK<-- default */
-/* 1 GPIO[2] */
-/* 2 GPIO[10] */
-/* 3 VIP_656_DATA_VAL */
-/* 4 VIP_656_DATA[0] */
-/* 5 VIP_656_CLK */
-/* 6 VIP_656_DATA_EXT[1] */
-/* 7 VIP_656_DATA_EXT[0] */
-
-#define FLD_IR_TX_ALT_SEL 0x00F00000
-/* 0 IR_TX <-- default */
-/* 1 GPIO[1] */
-/* 2 GPIO[10] */
-/* 3 VIP_656_DATA_VAL */
-/* 4 VIP_656_DATA[0] */
-/* 5 VIP_656_CLK */
-/* 6 VIP_656_DATA_EXT[1] */
-/* 7 VIP_656_DATA_EXT[0] */
-
-#define FLD_IR_RX_ALT_SEL 0x000F0000
-/* 0 IR_RX <-- default */
-/* 1 GPIO[0] */
-/* 2 GPIO[10] */
-/* 3 VIP_656_DATA_VAL */
-/* 4 VIP_656_DATA[0] */
-/* 5 VIP_656_CLK */
-/* 6 VIP_656_DATA_EXT[1] */
-/* 7 VIP_656_DATA_EXT[0] */
-
-#define FLD_GPIO10_ALT_SEL 0x0000F000
-/* 0 GPIO[10] <-- default */
-/* 1 GPIO[0] */
-/* 2 GPIO[10] */
-/* 3 VIP_656_DATA_VAL */
-/* 4 VIP_656_DATA[0] */
-/* 5 VIP_656_CLK */
-/* 6 VIP_656_DATA_EXT[1] */
-/* 7 VIP_656_DATA_EXT[0] */
-
-#define FLD_GPIO2_ALT_SEL 0x00000F00
-/* 0 GPIO[2] <-- default */
-/* 1 GPIO[1] */
-/* 2 GPIO[10] */
-/* 3 VIP_656_DATA_VAL */
-/* 4 VIP_656_DATA[0] */
-/* 5 VIP_656_CLK */
-/* 6 VIP_656_DATA_EXT[1] */
-/* 7 VIP_656_DATA_EXT[0] */
-
-#define FLD_GPIO1_ALT_SEL 0x000000F0
-/* 0 GPIO[1] <-- default */
-/* 1 GPIO[0] */
-/* 2 GPIO[10] */
-/* 3 VIP_656_DATA_VAL */
-/* 4 VIP_656_DATA[0] */
-/* 5 VIP_656_CLK */
-/* 6 VIP_656_DATA_EXT[1] */
-/* 7 VIP_656_DATA_EXT[0] */
-
-#define FLD_GPIO0_ALT_SEL 0x0000000F
-/* 0 GPIO[0] <-- default */
-/* 1 GPIO[1] */
-/* 2 GPIO[10] */
-/* 3 VIP_656_DATA_VAL */
-/* 4 VIP_656_DATA[0] */
-/* 5 VIP_656_CLK */
-/* 6 VIP_656_DATA_EXT[1] */
-/* 7 VIP_656_DATA_EXT[0] */
-
-#define ALT_PIN_IN_SEL 0x110030 /* Alternate GPIO input select */
-
-#define FLD_GPIO10_ALT_IN_SEL 0x0000F000
-/* 0 GPIO[10] <-- default */
-/* 1 IR_RX */
-/* 2 IR_TX */
-/* 3 AUX_PLL_CLK */
-/* 4 IF_ATT_SEL */
-/* 5 GPIO[0] */
-/* 6 GPIO[1] */
-/* 7 GPIO[2] */
-
-#define FLD_GPIO2_ALT_IN_SEL 0x00000F00
-/* 0 GPIO[2] <-- default */
-/* 1 IR_RX */
-/* 2 IR_TX */
-/* 3 AUX_PLL_CLK */
-/* 4 IF_ATT_SEL */
-
-#define FLD_GPIO1_ALT_IN_SEL 0x000000F0
-/* 0 GPIO[1] <-- default */
-/* 1 IR_RX */
-/* 2 IR_TX */
-/* 3 AUX_PLL_CLK */
-/* 4 IF_ATT_SEL */
-
-#define FLD_GPIO0_ALT_IN_SEL 0x0000000F
-/* 0 GPIO[0] <-- default */
-/* 1 IR_RX */
-/* 2 IR_TX */
-/* 3 AUX_PLL_CLK */
-/* 4 IF_ATT_SEL */
-
-/* ***************************************************************************** */
-#define TEST_BUS_CTL1 0x110040 /* Test bus control register #1 */
-
-/* ***************************************************************************** */
-#define TEST_BUS_CTL2 0x110044 /* Test bus control register #2 */
-
-/* ***************************************************************************** */
-#define CLK_DELAY 0x110048 /* Clock delay */
-#define FLD_MOE_CLK_DIS 0x80000000 /* Disable MoE clock */
-
-/* ***************************************************************************** */
-#define PAD_CTRL 0x110068 /* Pad drive strength control */
-
-/* ***************************************************************************** */
-#define MBIST_CTRL 0x110050 /* SRAM memory built-in self test control */
-
-/* ***************************************************************************** */
-#define MBIST_STAT 0x110054 /* SRAM memory built-in self test status */
-
-/* ***************************************************************************** */
-/* PLL registers */
-/* ***************************************************************************** */
-#define PLL_A_INT_FRAC 0x110088
-#define PLL_A_POST_STAT_BIST 0x11008C
-#define PLL_B_INT_FRAC 0x110090
-#define PLL_B_POST_STAT_BIST 0x110094
-#define PLL_C_INT_FRAC 0x110098
-#define PLL_C_POST_STAT_BIST 0x11009C
-#define PLL_D_INT_FRAC 0x1100A0
-#define PLL_D_POST_STAT_BIST 0x1100A4
-
-#define CLK_RST 0x11002C
-#define FLD_VID_I_CLK_NOE 0x00001000
-#define FLD_VID_J_CLK_NOE 0x00002000
-#define FLD_USE_ALT_PLL_REF 0x00004000
-
-#define VID_CH_MODE_SEL 0x110078
-#define VID_CH_CLK_SEL 0x11007C
-
-/* ***************************************************************************** */
-#define VBI_A_DMA 0x130008 /* VBI A DMA data port */
-
-/* ***************************************************************************** */
-#define VID_A_VIP_CTL 0x130080 /* Video A VIP format control */
-#define FLD_VIP_MODE 0x00000001
-
-/* ***************************************************************************** */
-#define VID_A_PIXEL_FRMT 0x130084 /* Video A pixel format */
-#define FLD_VID_A_GAMMA_DIS 0x00000008
-#define FLD_VID_A_FORMAT 0x00000007
-#define FLD_VID_A_GAMMA_FACTOR 0x00000010
-
-/* ***************************************************************************** */
-#define VID_A_VBI_CTL 0x130088 /* Video A VBI miscellaneous control */
-#define FLD_VID_A_VIP_EXT 0x00000003
-
-/* ***************************************************************************** */
-#define VID_B_DMA 0x130100 /* Video B DMA data port */
-
-/* ***************************************************************************** */
-#define VBI_B_DMA 0x130108 /* VBI B DMA data port */
-
-/* ***************************************************************************** */
-#define VID_B_SRC_SEL 0x130144 /* Video B source select */
-#define FLD_VID_B_SRC_SEL 0x00000000
-
-/* ***************************************************************************** */
-#define VID_B_LNGTH 0x130150 /* Video B line length */
-#define FLD_VID_B_LN_LNGTH 0x00000FFF
-
-/* ***************************************************************************** */
-#define VID_B_VIP_CTL 0x130180 /* Video B VIP format control */
-
-/* ***************************************************************************** */
-#define VID_B_PIXEL_FRMT 0x130184 /* Video B pixel format */
-#define FLD_VID_B_GAMMA_DIS 0x00000008
-#define FLD_VID_B_FORMAT 0x00000007
-#define FLD_VID_B_GAMMA_FACTOR 0x00000010
-
-/* ***************************************************************************** */
-#define VID_C_DMA 0x130200 /* Video C DMA data port */
-
-/* ***************************************************************************** */
-#define VID_C_LNGTH 0x130250 /* Video C line length */
-#define FLD_VID_C_LN_LNGTH 0x00000FFF
-
-/* ***************************************************************************** */
-/* Video Destination Channels */
-/* ***************************************************************************** */
-
-#define VID_DST_A_GPCNT 0x130020 /* Video A general purpose counter */
-#define VID_DST_B_GPCNT 0x130120 /* Video B general purpose counter */
-#define VID_DST_C_GPCNT 0x130220 /* Video C general purpose counter */
-#define VID_DST_D_GPCNT 0x130320 /* Video D general purpose counter */
-#define VID_DST_E_GPCNT 0x130420 /* Video E general purpose counter */
-#define VID_DST_F_GPCNT 0x130520 /* Video F general purpose counter */
-#define VID_DST_G_GPCNT 0x130620 /* Video G general purpose counter */
-#define VID_DST_H_GPCNT 0x130720 /* Video H general purpose counter */
-
-/* ***************************************************************************** */
-
-#define VID_DST_A_GPCNT_CTL 0x130030 /* Video A general purpose control */
-#define VID_DST_B_GPCNT_CTL 0x130130 /* Video B general purpose control */
-#define VID_DST_C_GPCNT_CTL 0x130230 /* Video C general purpose control */
-#define VID_DST_D_GPCNT_CTL 0x130330 /* Video D general purpose control */
-#define VID_DST_E_GPCNT_CTL 0x130430 /* Video E general purpose control */
-#define VID_DST_F_GPCNT_CTL 0x130530 /* Video F general purpose control */
-#define VID_DST_G_GPCNT_CTL 0x130630 /* Video G general purpose control */
-#define VID_DST_H_GPCNT_CTL 0x130730 /* Video H general purpose control */
-
-/* ***************************************************************************** */
-
-#define VID_DST_A_DMA_CTL 0x130040 /* Video A DMA control */
-#define VID_DST_B_DMA_CTL 0x130140 /* Video B DMA control */
-#define VID_DST_C_DMA_CTL 0x130240 /* Video C DMA control */
-#define VID_DST_D_DMA_CTL 0x130340 /* Video D DMA control */
-#define VID_DST_E_DMA_CTL 0x130440 /* Video E DMA control */
-#define VID_DST_F_DMA_CTL 0x130540 /* Video F DMA control */
-#define VID_DST_G_DMA_CTL 0x130640 /* Video G DMA control */
-#define VID_DST_H_DMA_CTL 0x130740 /* Video H DMA control */
-
-#define FLD_VID_RISC_EN 0x00000010
-#define FLD_VID_FIFO_EN 0x00000001
-
-/* ***************************************************************************** */
-
-#define VID_DST_A_VIP_CTL 0x130080 /* Video A VIP control */
-#define VID_DST_B_VIP_CTL 0x130180 /* Video B VIP control */
-#define VID_DST_C_VIP_CTL 0x130280 /* Video C VIP control */
-#define VID_DST_D_VIP_CTL 0x130380 /* Video D VIP control */
-#define VID_DST_E_VIP_CTL 0x130480 /* Video E VIP control */
-#define VID_DST_F_VIP_CTL 0x130580 /* Video F VIP control */
-#define VID_DST_G_VIP_CTL 0x130680 /* Video G VIP control */
-#define VID_DST_H_VIP_CTL 0x130780 /* Video H VIP control */
-
-/* ***************************************************************************** */
-
-#define VID_DST_A_PIX_FRMT 0x130084 /* Video A Pixel format */
-#define VID_DST_B_PIX_FRMT 0x130184 /* Video B Pixel format */
-#define VID_DST_C_PIX_FRMT 0x130284 /* Video C Pixel format */
-#define VID_DST_D_PIX_FRMT 0x130384 /* Video D Pixel format */
-#define VID_DST_E_PIX_FRMT 0x130484 /* Video E Pixel format */
-#define VID_DST_F_PIX_FRMT 0x130584 /* Video F Pixel format */
-#define VID_DST_G_PIX_FRMT 0x130684 /* Video G Pixel format */
-#define VID_DST_H_PIX_FRMT 0x130784 /* Video H Pixel format */
-
-/* ***************************************************************************** */
-/* Video Source Channels */
-/* ***************************************************************************** */
-
-#define VID_SRC_A_GPCNT_CTL 0x130804 /* Video A general purpose control */
-#define VID_SRC_B_GPCNT_CTL 0x130904 /* Video B general purpose control */
-#define VID_SRC_C_GPCNT_CTL 0x130A04 /* Video C general purpose control */
-#define VID_SRC_D_GPCNT_CTL 0x130B04 /* Video D general purpose control */
-#define VID_SRC_E_GPCNT_CTL 0x130C04 /* Video E general purpose control */
-#define VID_SRC_F_GPCNT_CTL 0x130D04 /* Video F general purpose control */
-#define VID_SRC_I_GPCNT_CTL 0x130E04 /* Video I general purpose control */
-#define VID_SRC_J_GPCNT_CTL 0x130F04 /* Video J general purpose control */
-
-/* ***************************************************************************** */
-
-#define VID_SRC_A_GPCNT 0x130808 /* Video A general purpose counter */
-#define VID_SRC_B_GPCNT 0x130908 /* Video B general purpose counter */
-#define VID_SRC_C_GPCNT 0x130A08 /* Video C general purpose counter */
-#define VID_SRC_D_GPCNT 0x130B08 /* Video D general purpose counter */
-#define VID_SRC_E_GPCNT 0x130C08 /* Video E general purpose counter */
-#define VID_SRC_F_GPCNT 0x130D08 /* Video F general purpose counter */
-#define VID_SRC_I_GPCNT 0x130E08 /* Video I general purpose counter */
-#define VID_SRC_J_GPCNT 0x130F08 /* Video J general purpose counter */
-
-/* ***************************************************************************** */
-
-#define VID_SRC_A_DMA_CTL 0x13080C /* Video A DMA control */
-#define VID_SRC_B_DMA_CTL 0x13090C /* Video B DMA control */
-#define VID_SRC_C_DMA_CTL 0x130A0C /* Video C DMA control */
-#define VID_SRC_D_DMA_CTL 0x130B0C /* Video D DMA control */
-#define VID_SRC_E_DMA_CTL 0x130C0C /* Video E DMA control */
-#define VID_SRC_F_DMA_CTL 0x130D0C /* Video F DMA control */
-#define VID_SRC_I_DMA_CTL 0x130E0C /* Video I DMA control */
-#define VID_SRC_J_DMA_CTL 0x130F0C /* Video J DMA control */
-
-#define FLD_APB_RISC_EN 0x00000010
-#define FLD_APB_FIFO_EN 0x00000001
-
-/* ***************************************************************************** */
-
-#define VID_SRC_A_FMT_CTL 0x130810 /* Video A format control */
-#define VID_SRC_B_FMT_CTL 0x130910 /* Video B format control */
-#define VID_SRC_C_FMT_CTL 0x130A10 /* Video C format control */
-#define VID_SRC_D_FMT_CTL 0x130B10 /* Video D format control */
-#define VID_SRC_E_FMT_CTL 0x130C10 /* Video E format control */
-#define VID_SRC_F_FMT_CTL 0x130D10 /* Video F format control */
-#define VID_SRC_I_FMT_CTL 0x130E10 /* Video I format control */
-#define VID_SRC_J_FMT_CTL 0x130F10 /* Video J format control */
-
-/* ***************************************************************************** */
-
-#define VID_SRC_A_ACTIVE_CTL1 0x130814 /* Video A active control 1 */
-#define VID_SRC_B_ACTIVE_CTL1 0x130914 /* Video B active control 1 */
-#define VID_SRC_C_ACTIVE_CTL1 0x130A14 /* Video C active control 1 */
-#define VID_SRC_D_ACTIVE_CTL1 0x130B14 /* Video D active control 1 */
-#define VID_SRC_E_ACTIVE_CTL1 0x130C14 /* Video E active control 1 */
-#define VID_SRC_F_ACTIVE_CTL1 0x130D14 /* Video F active control 1 */
-#define VID_SRC_I_ACTIVE_CTL1 0x130E14 /* Video I active control 1 */
-#define VID_SRC_J_ACTIVE_CTL1 0x130F14 /* Video J active control 1 */
-
-/* ***************************************************************************** */
-
-#define VID_SRC_A_ACTIVE_CTL2 0x130818 /* Video A active control 2 */
-#define VID_SRC_B_ACTIVE_CTL2 0x130918 /* Video B active control 2 */
-#define VID_SRC_C_ACTIVE_CTL2 0x130A18 /* Video C active control 2 */
-#define VID_SRC_D_ACTIVE_CTL2 0x130B18 /* Video D active control 2 */
-#define VID_SRC_E_ACTIVE_CTL2 0x130C18 /* Video E active control 2 */
-#define VID_SRC_F_ACTIVE_CTL2 0x130D18 /* Video F active control 2 */
-#define VID_SRC_I_ACTIVE_CTL2 0x130E18 /* Video I active control 2 */
-#define VID_SRC_J_ACTIVE_CTL2 0x130F18 /* Video J active control 2 */
-
-/* ***************************************************************************** */
-
-#define VID_SRC_A_CDT_SZ 0x13081C /* Video A CDT size */
-#define VID_SRC_B_CDT_SZ 0x13091C /* Video B CDT size */
-#define VID_SRC_C_CDT_SZ 0x130A1C /* Video C CDT size */
-#define VID_SRC_D_CDT_SZ 0x130B1C /* Video D CDT size */
-#define VID_SRC_E_CDT_SZ 0x130C1C /* Video E CDT size */
-#define VID_SRC_F_CDT_SZ 0x130D1C /* Video F CDT size */
-#define VID_SRC_I_CDT_SZ 0x130E1C /* Video I CDT size */
-#define VID_SRC_J_CDT_SZ 0x130F1C /* Video J CDT size */
-
-/* ***************************************************************************** */
-/* Audio I/F */
-/* ***************************************************************************** */
-#define AUD_DST_A_DMA 0x140000 /* Audio Int A DMA data port */
-#define AUD_SRC_A_DMA 0x140008 /* Audio Int A DMA data port */
-
-#define AUD_A_GPCNT 0x140010 /* Audio Int A gp counter */
-#define FLD_AUD_A_GP_CNT 0x0000FFFF
-
-#define AUD_A_GPCNT_CTL 0x140014 /* Audio Int A gp control */
-
-#define AUD_A_LNGTH 0x140018 /* Audio Int A line length */
-
-#define AUD_A_CFG 0x14001C /* Audio Int A configuration */
-
-/* ***************************************************************************** */
-#define AUD_DST_B_DMA 0x140100 /* Audio Int B DMA data port */
-#define AUD_SRC_B_DMA 0x140108 /* Audio Int B DMA data port */
-
-#define AUD_B_GPCNT 0x140110 /* Audio Int B gp counter */
-#define FLD_AUD_B_GP_CNT 0x0000FFFF
-
-#define AUD_B_GPCNT_CTL 0x140114 /* Audio Int B gp control */
-
-#define AUD_B_LNGTH 0x140118 /* Audio Int B line length */
-
-#define AUD_B_CFG 0x14011C /* Audio Int B configuration */
-
-/* ***************************************************************************** */
-#define AUD_DST_C_DMA 0x140200 /* Audio Int C DMA data port */
-#define AUD_SRC_C_DMA 0x140208 /* Audio Int C DMA data port */
-
-#define AUD_C_GPCNT 0x140210 /* Audio Int C gp counter */
-#define FLD_AUD_C_GP_CNT 0x0000FFFF
-
-#define AUD_C_GPCNT_CTL 0x140214 /* Audio Int C gp control */
-
-#define AUD_C_LNGTH 0x140218 /* Audio Int C line length */
-
-#define AUD_C_CFG 0x14021C /* Audio Int C configuration */
-
-/* ***************************************************************************** */
-#define AUD_DST_D_DMA 0x140300 /* Audio Int D DMA data port */
-#define AUD_SRC_D_DMA 0x140308 /* Audio Int D DMA data port */
-
-#define AUD_D_GPCNT 0x140310 /* Audio Int D gp counter */
-#define FLD_AUD_D_GP_CNT 0x0000FFFF
-
-#define AUD_D_GPCNT_CTL 0x140314 /* Audio Int D gp control */
-
-#define AUD_D_LNGTH 0x140318 /* Audio Int D line length */
-
-#define AUD_D_CFG 0x14031C /* Audio Int D configuration */
-
-/* ***************************************************************************** */
-#define AUD_SRC_E_DMA 0x140400 /* Audio Int E DMA data port */
-
-#define AUD_E_GPCNT 0x140410 /* Audio Int E gp counter */
-#define FLD_AUD_E_GP_CNT 0x0000FFFF
-
-#define AUD_E_GPCNT_CTL 0x140414 /* Audio Int E gp control */
-
-#define AUD_E_CFG 0x14041C /* Audio Int E configuration */
-
-/* ***************************************************************************** */
-
-#define FLD_AUD_DST_LN_LNGTH 0x00000FFF
-
-#define FLD_AUD_DST_PK_MODE 0x00004000
-
-#define FLD_AUD_CLK_ENABLE 0x00000200
-
-#define FLD_AUD_MASTER_MODE 0x00000002
-
-#define FLD_AUD_SONY_MODE 0x00000001
-
-#define FLD_AUD_CLK_SELECT_PLL_D 0x00001800
-
-#define FLD_AUD_DST_ENABLE 0x00020000
-
-#define FLD_AUD_SRC_ENABLE 0x00010000
-
-/* ***************************************************************************** */
-#define AUD_INT_DMA_CTL 0x140500 /* Audio Int DMA control */
-
-#define FLD_AUD_SRC_E_RISC_EN 0x00008000
-#define FLD_AUD_SRC_C_RISC_EN 0x00004000
-#define FLD_AUD_SRC_B_RISC_EN 0x00002000
-#define FLD_AUD_SRC_A_RISC_EN 0x00001000
-
-#define FLD_AUD_DST_D_RISC_EN 0x00000800
-#define FLD_AUD_DST_C_RISC_EN 0x00000400
-#define FLD_AUD_DST_B_RISC_EN 0x00000200
-#define FLD_AUD_DST_A_RISC_EN 0x00000100
-
-#define FLD_AUD_SRC_E_FIFO_EN 0x00000080
-#define FLD_AUD_SRC_C_FIFO_EN 0x00000040
-#define FLD_AUD_SRC_B_FIFO_EN 0x00000020
-#define FLD_AUD_SRC_A_FIFO_EN 0x00000010
-
-#define FLD_AUD_DST_D_FIFO_EN 0x00000008
-#define FLD_AUD_DST_C_FIFO_EN 0x00000004
-#define FLD_AUD_DST_B_FIFO_EN 0x00000002
-#define FLD_AUD_DST_A_FIFO_EN 0x00000001
-
-/* ***************************************************************************** */
-/* */
-/* Mobilygen Interface Registers */
-/* */
-/* ***************************************************************************** */
-/* Mobilygen Interface A */
-/* ***************************************************************************** */
-#define MB_IF_A_DMA 0x150000 /* MBIF A DMA data port */
-#define MB_IF_A_GPCN 0x150008 /* MBIF A GP counter */
-#define MB_IF_A_GPCN_CTRL 0x15000C
-#define MB_IF_A_DMA_CTRL 0x150010
-#define MB_IF_A_LENGTH 0x150014
-#define MB_IF_A_HDMA_XFER_SZ 0x150018
-#define MB_IF_A_HCMD 0x15001C
-#define MB_IF_A_HCONFIG 0x150020
-#define MB_IF_A_DATA_STRUCT_0 0x150024
-#define MB_IF_A_DATA_STRUCT_1 0x150028
-#define MB_IF_A_DATA_STRUCT_2 0x15002C
-#define MB_IF_A_DATA_STRUCT_3 0x150030
-#define MB_IF_A_DATA_STRUCT_4 0x150034
-#define MB_IF_A_DATA_STRUCT_5 0x150038
-#define MB_IF_A_DATA_STRUCT_6 0x15003C
-#define MB_IF_A_DATA_STRUCT_7 0x150040
-#define MB_IF_A_DATA_STRUCT_8 0x150044
-#define MB_IF_A_DATA_STRUCT_9 0x150048
-#define MB_IF_A_DATA_STRUCT_A 0x15004C
-#define MB_IF_A_DATA_STRUCT_B 0x150050
-#define MB_IF_A_DATA_STRUCT_C 0x150054
-#define MB_IF_A_DATA_STRUCT_D 0x150058
-#define MB_IF_A_DATA_STRUCT_E 0x15005C
-#define MB_IF_A_DATA_STRUCT_F 0x150060
-/* ***************************************************************************** */
-/* Mobilygen Interface B */
-/* ***************************************************************************** */
-#define MB_IF_B_DMA 0x160000 /* MBIF A DMA data port */
-#define MB_IF_B_GPCN 0x160008 /* MBIF A GP counter */
-#define MB_IF_B_GPCN_CTRL 0x16000C
-#define MB_IF_B_DMA_CTRL 0x160010
-#define MB_IF_B_LENGTH 0x160014
-#define MB_IF_B_HDMA_XFER_SZ 0x160018
-#define MB_IF_B_HCMD 0x16001C
-#define MB_IF_B_HCONFIG 0x160020
-#define MB_IF_B_DATA_STRUCT_0 0x160024
-#define MB_IF_B_DATA_STRUCT_1 0x160028
-#define MB_IF_B_DATA_STRUCT_2 0x16002C
-#define MB_IF_B_DATA_STRUCT_3 0x160030
-#define MB_IF_B_DATA_STRUCT_4 0x160034
-#define MB_IF_B_DATA_STRUCT_5 0x160038
-#define MB_IF_B_DATA_STRUCT_6 0x16003C
-#define MB_IF_B_DATA_STRUCT_7 0x160040
-#define MB_IF_B_DATA_STRUCT_8 0x160044
-#define MB_IF_B_DATA_STRUCT_9 0x160048
-#define MB_IF_B_DATA_STRUCT_A 0x16004C
-#define MB_IF_B_DATA_STRUCT_B 0x160050
-#define MB_IF_B_DATA_STRUCT_C 0x160054
-#define MB_IF_B_DATA_STRUCT_D 0x160058
-#define MB_IF_B_DATA_STRUCT_E 0x16005C
-#define MB_IF_B_DATA_STRUCT_F 0x160060
-
-/* MB_DMA_CTRL */
-#define FLD_MB_IF_RISC_EN 0x00000010
-#define FLD_MB_IF_FIFO_EN 0x00000001
-
-/* MB_LENGTH */
-#define FLD_MB_IF_LN_LNGTH 0x00000FFF
-
-/* MB_HCMD register */
-#define FLD_MB_HCMD_H_GO 0x80000000
-#define FLD_MB_HCMD_H_BUSY 0x40000000
-#define FLD_MB_HCMD_H_DMA_HOLD 0x10000000
-#define FLD_MB_HCMD_H_DMA_BUSY 0x08000000
-#define FLD_MB_HCMD_H_DMA_TYPE 0x04000000
-#define FLD_MB_HCMD_H_DMA_XACT 0x02000000
-#define FLD_MB_HCMD_H_RW_N 0x01000000
-#define FLD_MB_HCMD_H_ADDR 0x00FF0000
-#define FLD_MB_HCMD_H_DATA 0x0000FFFF
-
-/* ***************************************************************************** */
-/* I2C #1 */
-/* ***************************************************************************** */
-#define I2C1_ADDR 0x180000 /* I2C #1 address */
-#define FLD_I2C_DADDR 0xfe000000 /* RW [31:25] I2C Device Address */
- /* RO [24] reserved */
-/* ***************************************************************************** */
-#define FLD_I2C_SADDR 0x00FFFFFF /* RW [23:0] I2C Sub-address */
-
-/* ***************************************************************************** */
-#define I2C1_WDATA 0x180004 /* I2C #1 write data */
-#define FLD_I2C_WDATA 0xFFFFFFFF /* RW [31:0] */
-
-/* ***************************************************************************** */
-#define I2C1_CTRL 0x180008 /* I2C #1 control */
-#define FLD_I2C_PERIOD 0xFF000000 /* RW [31:24] */
-#define FLD_I2C_SCL_IN 0x00200000 /* RW [21] */
-#define FLD_I2C_SDA_IN 0x00100000 /* RW [20] */
- /* RO [19:18] reserved */
-#define FLD_I2C_SCL_OUT 0x00020000 /* RW [17] */
-#define FLD_I2C_SDA_OUT 0x00010000 /* RW [16] */
- /* RO [15] reserved */
-#define FLD_I2C_DATA_LEN 0x00007000 /* RW [14:12] */
-#define FLD_I2C_SADDR_INC 0x00000800 /* RW [11] */
- /* RO [10:9] reserved */
-#define FLD_I2C_SADDR_LEN 0x00000300 /* RW [9:8] */
- /* RO [7:6] reserved */
-#define FLD_I2C_SOFT 0x00000020 /* RW [5] */
-#define FLD_I2C_NOSTOP 0x00000010 /* RW [4] */
-#define FLD_I2C_EXTEND 0x00000008 /* RW [3] */
-#define FLD_I2C_SYNC 0x00000004 /* RW [2] */
-#define FLD_I2C_READ_SA 0x00000002 /* RW [1] */
-#define FLD_I2C_READ_WRN 0x00000001 /* RW [0] */
-
-/* ***************************************************************************** */
-#define I2C1_RDATA 0x18000C /* I2C #1 read data */
-#define FLD_I2C_RDATA 0xFFFFFFFF /* RO [31:0] */
-
-/* ***************************************************************************** */
-#define I2C1_STAT 0x180010 /* I2C #1 status */
-#define FLD_I2C_XFER_IN_PROG 0x00000002 /* RO [1] */
-#define FLD_I2C_RACK 0x00000001 /* RO [0] */
-
-/* ***************************************************************************** */
-/* I2C #2 */
-/* ***************************************************************************** */
-#define I2C2_ADDR 0x190000 /* I2C #2 address */
-
-/* ***************************************************************************** */
-#define I2C2_WDATA 0x190004 /* I2C #2 write data */
-
-/* ***************************************************************************** */
-#define I2C2_CTRL 0x190008 /* I2C #2 control */
-
-/* ***************************************************************************** */
-#define I2C2_RDATA 0x19000C /* I2C #2 read data */
-
-/* ***************************************************************************** */
-#define I2C2_STAT 0x190010 /* I2C #2 status */
-
-/* ***************************************************************************** */
-/* I2C #3 */
-/* ***************************************************************************** */
-#define I2C3_ADDR 0x1A0000 /* I2C #3 address */
-
-/* ***************************************************************************** */
-#define I2C3_WDATA 0x1A0004 /* I2C #3 write data */
-
-/* ***************************************************************************** */
-#define I2C3_CTRL 0x1A0008 /* I2C #3 control */
-
-/* ***************************************************************************** */
-#define I2C3_RDATA 0x1A000C /* I2C #3 read data */
-
-/* ***************************************************************************** */
-#define I2C3_STAT 0x1A0010 /* I2C #3 status */
-
-/* ***************************************************************************** */
-/* UART */
-/* ***************************************************************************** */
-#define UART_CTL 0x1B0000 /* UART Control Register */
-#define FLD_LOOP_BACK_EN (1 << 7) /* RW field - default 0 */
-#define FLD_RX_TRG_SZ (3 << 2) /* RW field - default 0 */
-#define FLD_RX_EN (1 << 1) /* RW field - default 0 */
-#define FLD_TX_EN (1 << 0) /* RW field - default 0 */
-
-/* ***************************************************************************** */
-#define UART_BRD 0x1B0004 /* UART Baud Rate Divisor */
-#define FLD_BRD 0x0000FFFF /* RW field - default 0x197 */
-
-/* ***************************************************************************** */
-#define UART_DBUF 0x1B0008 /* UART Tx/Rx Data BuFFer */
-#define FLD_DB 0xFFFFFFFF /* RW field - default 0 */
-
-/* ***************************************************************************** */
-#define UART_ISR 0x1B000C /* UART Interrupt Status */
-#define FLD_RXD_TIMEOUT_EN (1 << 7) /* RW field - default 0 */
-#define FLD_FRM_ERR_EN (1 << 6) /* RW field - default 0 */
-#define FLD_RXD_RDY_EN (1 << 5) /* RW field - default 0 */
-#define FLD_TXD_EMPTY_EN (1 << 4) /* RW field - default 0 */
-#define FLD_RXD_OVERFLOW (1 << 3) /* RW field - default 0 */
-#define FLD_FRM_ERR (1 << 2) /* RW field - default 0 */
-#define FLD_RXD_RDY (1 << 1) /* RW field - default 0 */
-#define FLD_TXD_EMPTY (1 << 0) /* RW field - default 0 */
-
-/* ***************************************************************************** */
-#define UART_CNT 0x1B0010 /* UART Tx/Rx FIFO Byte Count */
-#define FLD_TXD_CNT (0x1F << 8) /* RW field - default 0 */
-#define FLD_RXD_CNT (0x1F << 0) /* RW field - default 0 */
-
-/* ***************************************************************************** */
-/* Motion Detection */
-#define MD_CH0_GRID_BLOCK_YCNT 0x170014
-#define MD_CH1_GRID_BLOCK_YCNT 0x170094
-#define MD_CH2_GRID_BLOCK_YCNT 0x170114
-#define MD_CH3_GRID_BLOCK_YCNT 0x170194
-#define MD_CH4_GRID_BLOCK_YCNT 0x170214
-#define MD_CH5_GRID_BLOCK_YCNT 0x170294
-#define MD_CH6_GRID_BLOCK_YCNT 0x170314
-#define MD_CH7_GRID_BLOCK_YCNT 0x170394
-
-#define PIXEL_FRMT_422 4
-#define PIXEL_FRMT_411 5
-#define PIXEL_FRMT_Y8 6
-
-#define PIXEL_ENGINE_VIP1 0
-#define PIXEL_ENGINE_VIP2 1
-
-#endif /* Athena_REGISTERS */
diff --git a/drivers/media/video/cx25821/cx25821-sram.h b/drivers/media/video/cx25821/cx25821-sram.h
deleted file mode 100644
index 5f05d153bc4..00000000000
--- a/drivers/media/video/cx25821/cx25821-sram.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ATHENA_SRAM_H__
-#define __ATHENA_SRAM_H__
-
-/* #define RX_SRAM_START_SIZE = 0; // Start of reserved SRAM */
-#define VID_CMDS_SIZE 80 /* Video CMDS size in bytes */
-#define AUDIO_CMDS_SIZE 80 /* AUDIO CMDS size in bytes */
-#define MBIF_CMDS_SIZE 80 /* MBIF CMDS size in bytes */
-
-/* #define RX_SRAM_POOL_START_SIZE = 0; // Start of useable RX SRAM for buffers */
-#define VID_IQ_SIZE 64 /* VID instruction queue size in bytes */
-#define MBIF_IQ_SIZE 64
-#define AUDIO_IQ_SIZE 64 /* AUD instruction queue size in bytes */
-
-#define VID_CDT_SIZE 64 /* VID cluster descriptor table size in bytes */
-#define MBIF_CDT_SIZE 64 /* MBIF/HBI cluster descriptor table size in bytes */
-#define AUDIO_CDT_SIZE 48 /* AUD cluster descriptor table size in bytes */
-
-/* #define RX_SRAM_POOL_FREE_SIZE = 16; // Start of available RX SRAM */
-/* #define RX_SRAM_END_SIZE = 0; // End of RX SRAM */
-
-/* #define TX_SRAM_POOL_START_SIZE = 0; // Start of transmit pool SRAM */
-/* #define MSI_DATA_SIZE = 64; // Reserved (MSI Data, RISC working stora */
-
-#define VID_CLUSTER_SIZE 1440 /* VID cluster data line */
-#define AUDIO_CLUSTER_SIZE 128 /* AUDIO cluster data line */
-#define MBIF_CLUSTER_SIZE 1440 /* MBIF/HBI cluster data line */
-
-/* #define TX_SRAM_POOL_FREE_SIZE = 704; // Start of available TX SRAM */
-/* #define TX_SRAM_END_SIZE = 0; // End of TX SRAM */
-
-/* Receive SRAM */
-#define RX_SRAM_START 0x10000
-#define VID_A_DOWN_CMDS 0x10000
-#define VID_B_DOWN_CMDS 0x10050
-#define VID_C_DOWN_CMDS 0x100A0
-#define VID_D_DOWN_CMDS 0x100F0
-#define VID_E_DOWN_CMDS 0x10140
-#define VID_F_DOWN_CMDS 0x10190
-#define VID_G_DOWN_CMDS 0x101E0
-#define VID_H_DOWN_CMDS 0x10230
-#define VID_A_UP_CMDS 0x10280
-#define VID_B_UP_CMDS 0x102D0
-#define VID_C_UP_CMDS 0x10320
-#define VID_D_UP_CMDS 0x10370
-#define VID_E_UP_CMDS 0x103C0
-#define VID_F_UP_CMDS 0x10410
-#define VID_I_UP_CMDS 0x10460
-#define VID_J_UP_CMDS 0x104B0
-#define AUD_A_DOWN_CMDS 0x10500
-#define AUD_B_DOWN_CMDS 0x10550
-#define AUD_C_DOWN_CMDS 0x105A0
-#define AUD_D_DOWN_CMDS 0x105F0
-#define AUD_A_UP_CMDS 0x10640
-#define AUD_B_UP_CMDS 0x10690
-#define AUD_C_UP_CMDS 0x106E0
-#define AUD_E_UP_CMDS 0x10730
-#define MBIF_A_DOWN_CMDS 0x10780
-#define MBIF_B_DOWN_CMDS 0x107D0
-#define DMA_SCRATCH_PAD 0x10820 /* Scratch pad area from 0x10820 to 0x10B40 */
-
-/* #define RX_SRAM_POOL_START = 0x105B0; */
-
-#define VID_A_IQ 0x11000
-#define VID_B_IQ 0x11040
-#define VID_C_IQ 0x11080
-#define VID_D_IQ 0x110C0
-#define VID_E_IQ 0x11100
-#define VID_F_IQ 0x11140
-#define VID_G_IQ 0x11180
-#define VID_H_IQ 0x111C0
-#define VID_I_IQ 0x11200
-#define VID_J_IQ 0x11240
-#define AUD_A_IQ 0x11280
-#define AUD_B_IQ 0x112C0
-#define AUD_C_IQ 0x11300
-#define AUD_D_IQ 0x11340
-#define AUD_E_IQ 0x11380
-#define MBIF_A_IQ 0x11000
-#define MBIF_B_IQ 0x110C0
-
-#define VID_A_CDT 0x10C00
-#define VID_B_CDT 0x10C40
-#define VID_C_CDT 0x10C80
-#define VID_D_CDT 0x10CC0
-#define VID_E_CDT 0x10D00
-#define VID_F_CDT 0x10D40
-#define VID_G_CDT 0x10D80
-#define VID_H_CDT 0x10DC0
-#define VID_I_CDT 0x10E00
-#define VID_J_CDT 0x10E40
-#define AUD_A_CDT 0x10E80
-#define AUD_B_CDT 0x10EB0
-#define AUD_C_CDT 0x10EE0
-#define AUD_D_CDT 0x10F10
-#define AUD_E_CDT 0x10F40
-#define MBIF_A_CDT 0x10C00
-#define MBIF_B_CDT 0x10CC0
-
-/* Cluster Buffer for RX */
-#define VID_A_UP_CLUSTER_1 0x11400
-#define VID_A_UP_CLUSTER_2 0x119A0
-#define VID_A_UP_CLUSTER_3 0x11F40
-#define VID_A_UP_CLUSTER_4 0x124E0
-
-#define VID_B_UP_CLUSTER_1 0x12A80
-#define VID_B_UP_CLUSTER_2 0x13020
-#define VID_B_UP_CLUSTER_3 0x135C0
-#define VID_B_UP_CLUSTER_4 0x13B60
-
-#define VID_C_UP_CLUSTER_1 0x14100
-#define VID_C_UP_CLUSTER_2 0x146A0
-#define VID_C_UP_CLUSTER_3 0x14C40
-#define VID_C_UP_CLUSTER_4 0x151E0
-
-#define VID_D_UP_CLUSTER_1 0x15780
-#define VID_D_UP_CLUSTER_2 0x15D20
-#define VID_D_UP_CLUSTER_3 0x162C0
-#define VID_D_UP_CLUSTER_4 0x16860
-
-#define VID_E_UP_CLUSTER_1 0x16E00
-#define VID_E_UP_CLUSTER_2 0x173A0
-#define VID_E_UP_CLUSTER_3 0x17940
-#define VID_E_UP_CLUSTER_4 0x17EE0
-
-#define VID_F_UP_CLUSTER_1 0x18480
-#define VID_F_UP_CLUSTER_2 0x18A20
-#define VID_F_UP_CLUSTER_3 0x18FC0
-#define VID_F_UP_CLUSTER_4 0x19560
-
-#define VID_I_UP_CLUSTER_1 0x19B00
-#define VID_I_UP_CLUSTER_2 0x1A0A0
-#define VID_I_UP_CLUSTER_3 0x1A640
-#define VID_I_UP_CLUSTER_4 0x1ABE0
-
-#define VID_J_UP_CLUSTER_1 0x1B180
-#define VID_J_UP_CLUSTER_2 0x1B720
-#define VID_J_UP_CLUSTER_3 0x1BCC0
-#define VID_J_UP_CLUSTER_4 0x1C260
-
-#define AUD_A_UP_CLUSTER_1 0x1C800
-#define AUD_A_UP_CLUSTER_2 0x1C880
-#define AUD_A_UP_CLUSTER_3 0x1C900
-
-#define AUD_B_UP_CLUSTER_1 0x1C980
-#define AUD_B_UP_CLUSTER_2 0x1CA00
-#define AUD_B_UP_CLUSTER_3 0x1CA80
-
-#define AUD_C_UP_CLUSTER_1 0x1CB00
-#define AUD_C_UP_CLUSTER_2 0x1CB80
-#define AUD_C_UP_CLUSTER_3 0x1CC00
-
-#define AUD_E_UP_CLUSTER_1 0x1CC80
-#define AUD_E_UP_CLUSTER_2 0x1CD00
-#define AUD_E_UP_CLUSTER_3 0x1CD80
-
-#define RX_SRAM_POOL_FREE 0x1CE00
-#define RX_SRAM_END 0x1D000
-
-/* Free Receive SRAM 144 Bytes */
-
-/* Transmit SRAM */
-#define TX_SRAM_POOL_START 0x00000
-
-#define VID_A_DOWN_CLUSTER_1 0x00040
-#define VID_A_DOWN_CLUSTER_2 0x005E0
-#define VID_A_DOWN_CLUSTER_3 0x00B80
-#define VID_A_DOWN_CLUSTER_4 0x01120
-
-#define VID_B_DOWN_CLUSTER_1 0x016C0
-#define VID_B_DOWN_CLUSTER_2 0x01C60
-#define VID_B_DOWN_CLUSTER_3 0x02200
-#define VID_B_DOWN_CLUSTER_4 0x027A0
-
-#define VID_C_DOWN_CLUSTER_1 0x02D40
-#define VID_C_DOWN_CLUSTER_2 0x032E0
-#define VID_C_DOWN_CLUSTER_3 0x03880
-#define VID_C_DOWN_CLUSTER_4 0x03E20
-
-#define VID_D_DOWN_CLUSTER_1 0x043C0
-#define VID_D_DOWN_CLUSTER_2 0x04960
-#define VID_D_DOWN_CLUSTER_3 0x04F00
-#define VID_D_DOWN_CLUSTER_4 0x054A0
-
-#define VID_E_DOWN_CLUSTER_1 0x05a40
-#define VID_E_DOWN_CLUSTER_2 0x05FE0
-#define VID_E_DOWN_CLUSTER_3 0x06580
-#define VID_E_DOWN_CLUSTER_4 0x06B20
-
-#define VID_F_DOWN_CLUSTER_1 0x070C0
-#define VID_F_DOWN_CLUSTER_2 0x07660
-#define VID_F_DOWN_CLUSTER_3 0x07C00
-#define VID_F_DOWN_CLUSTER_4 0x081A0
-
-#define VID_G_DOWN_CLUSTER_1 0x08740
-#define VID_G_DOWN_CLUSTER_2 0x08CE0
-#define VID_G_DOWN_CLUSTER_3 0x09280
-#define VID_G_DOWN_CLUSTER_4 0x09820
-
-#define VID_H_DOWN_CLUSTER_1 0x09DC0
-#define VID_H_DOWN_CLUSTER_2 0x0A360
-#define VID_H_DOWN_CLUSTER_3 0x0A900
-#define VID_H_DOWN_CLUSTER_4 0x0AEA0
-
-#define AUD_A_DOWN_CLUSTER_1 0x0B500
-#define AUD_A_DOWN_CLUSTER_2 0x0B580
-#define AUD_A_DOWN_CLUSTER_3 0x0B600
-
-#define AUD_B_DOWN_CLUSTER_1 0x0B680
-#define AUD_B_DOWN_CLUSTER_2 0x0B700
-#define AUD_B_DOWN_CLUSTER_3 0x0B780
-
-#define AUD_C_DOWN_CLUSTER_1 0x0B800
-#define AUD_C_DOWN_CLUSTER_2 0x0B880
-#define AUD_C_DOWN_CLUSTER_3 0x0B900
-
-#define AUD_D_DOWN_CLUSTER_1 0x0B980
-#define AUD_D_DOWN_CLUSTER_2 0x0BA00
-#define AUD_D_DOWN_CLUSTER_3 0x0BA80
-
-#define TX_SRAM_POOL_FREE 0x0BB00
-#define TX_SRAM_END 0x0C000
-
-#define BYTES_TO_DWORDS(bcount) ((bcount) >> 2)
-#define BYTES_TO_QWORDS(bcount) ((bcount) >> 3)
-#define BYTES_TO_OWORDS(bcount) ((bcount) >> 4)
-
-#define VID_IQ_SIZE_DW BYTES_TO_DWORDS(VID_IQ_SIZE)
-#define VID_CDT_SIZE_QW BYTES_TO_QWORDS(VID_CDT_SIZE)
-#define VID_CLUSTER_SIZE_OW BYTES_TO_OWORDS(VID_CLUSTER_SIZE)
-
-#define AUDIO_IQ_SIZE_DW BYTES_TO_DWORDS(AUDIO_IQ_SIZE)
-#define AUDIO_CDT_SIZE_QW BYTES_TO_QWORDS(AUDIO_CDT_SIZE)
-#define AUDIO_CLUSTER_SIZE_QW BYTES_TO_QWORDS(AUDIO_CLUSTER_SIZE)
-
-#define MBIF_IQ_SIZE_DW BYTES_TO_DWORDS(MBIF_IQ_SIZE)
-#define MBIF_CDT_SIZE_QW BYTES_TO_QWORDS(MBIF_CDT_SIZE)
-#define MBIF_CLUSTER_SIZE_OW BYTES_TO_OWORDS(MBIF_CLUSTER_SIZE)
-
-#endif
diff --git a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c
deleted file mode 100644
index c8c94fbf5d8..00000000000
--- a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c
+++ /dev/null
@@ -1,802 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "cx25821-video.h"
-#include "cx25821-video-upstream-ch2.h"
-
-#include <linux/fs.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/syscalls.h>
-#include <linux/file.h>
-#include <linux/fcntl.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
-MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
-MODULE_LICENSE("GPL");
-
-static int _intr_msk = FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC |
- FLD_VID_SRC_OPC_ERR;
-
-static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev,
- __le32 *rp, unsigned int offset,
- unsigned int bpl, u32 sync_line,
- unsigned int lines,
- int fifo_enable, int field_type)
-{
- unsigned int line, i;
- int dist_betwn_starts = bpl * 2;
-
- *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
-
- if (USE_RISC_NOOP_VIDEO) {
- for (i = 0; i < NUM_NO_OPS; i++)
- *(rp++) = cpu_to_le32(RISC_NOOP);
- }
-
- /* scan lines */
- for (line = 0; line < lines; line++) {
- *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
- *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr_ch2 + offset);
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
-
- if ((lines <= NTSC_FIELD_HEIGHT) ||
- (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) {
- offset += dist_betwn_starts;
- }
- }
-
- return rp;
-}
-
-static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev,
- __le32 *rp,
- dma_addr_t databuf_phys_addr,
- unsigned int offset,
- u32 sync_line, unsigned int bpl,
- unsigned int lines,
- int fifo_enable, int field_type)
-{
- unsigned int line, i;
- struct sram_channel *sram_ch =
- dev->channels[dev->_channel2_upstream_select].sram_channels;
- int dist_betwn_starts = bpl * 2;
-
- /* sync instruction */
- if (sync_line != NO_SYNC_LINE)
- *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
-
- if (USE_RISC_NOOP_VIDEO) {
- for (i = 0; i < NUM_NO_OPS; i++)
- *(rp++) = cpu_to_le32(RISC_NOOP);
- }
-
- /* scan lines */
- for (line = 0; line < lines; line++) {
- *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
- *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
-
- if ((lines <= NTSC_FIELD_HEIGHT) ||
- (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) {
- offset += dist_betwn_starts;
- }
-
- /*
- check if we need to enable the FIFO after the first 4 lines
- For the upstream video channel, the risc engine will enable
- the FIFO.
- */
- if (fifo_enable && line == 3) {
- *(rp++) = RISC_WRITECR;
- *(rp++) = sram_ch->dma_ctl;
- *(rp++) = FLD_VID_FIFO_EN;
- *(rp++) = 0x00000001;
- }
- }
-
- return rp;
-}
-
-int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev,
- struct pci_dev *pci,
- unsigned int top_offset, unsigned int bpl,
- unsigned int lines)
-{
- __le32 *rp;
- int fifo_enable = 0;
- int singlefield_lines = lines >> 1; /*get line count for single field */
- int odd_num_lines = singlefield_lines;
- int frame = 0;
- int frame_size = 0;
- int databuf_offset = 0;
- int risc_program_size = 0;
- int risc_flag = RISC_CNT_RESET;
- unsigned int bottom_offset = bpl;
- dma_addr_t risc_phys_jump_addr;
-
- if (dev->_isNTSC_ch2) {
- odd_num_lines = singlefield_lines + 1;
- risc_program_size = FRAME1_VID_PROG_SIZE;
- if (bpl == Y411_LINE_SZ)
- frame_size = FRAME_SIZE_NTSC_Y411;
- else
- frame_size = FRAME_SIZE_NTSC_Y422;
- } else {
- risc_program_size = PAL_VID_PROG_SIZE;
- if (bpl == Y411_LINE_SZ)
- frame_size = FRAME_SIZE_PAL_Y411;
- else
- frame_size = FRAME_SIZE_PAL_Y422;
- }
-
- /* Virtual address of Risc buffer program */
- rp = dev->_dma_virt_addr_ch2;
-
- for (frame = 0; frame < NUM_FRAMES; frame++) {
- databuf_offset = frame_size * frame;
-
- if (UNSET != top_offset) {
- fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
- rp = cx25821_risc_field_upstream_ch2(dev, rp,
- dev->_data_buf_phys_addr_ch2 + databuf_offset,
- top_offset, 0, bpl, odd_num_lines, fifo_enable,
- ODD_FIELD);
- }
-
- fifo_enable = FIFO_DISABLE;
-
- /* Even field */
- rp = cx25821_risc_field_upstream_ch2(dev, rp,
- dev->_data_buf_phys_addr_ch2 + databuf_offset,
- bottom_offset, 0x200, bpl, singlefield_lines,
- fifo_enable, EVEN_FIELD);
-
- if (frame == 0) {
- risc_flag = RISC_CNT_RESET;
- risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2 +
- risc_program_size;
- } else {
- risc_flag = RISC_CNT_INC;
- risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2;
- }
-
- /*
- * Loop to 2ndFrameRISC or to Start of
- * Risc program & generate IRQ
- */
- *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
- *(rp++) = cpu_to_le32(risc_phys_jump_addr);
- *(rp++) = cpu_to_le32(0);
- }
-
- return 0;
-}
-
-void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev)
-{
- struct sram_channel *sram_ch =
- dev->channels[VID_UPSTREAM_SRAM_CHANNEL_J].sram_channels;
- u32 tmp = 0;
-
- if (!dev->_is_running_ch2) {
- pr_info("No video file is currently running so return!\n");
- return;
- }
- /* Disable RISC interrupts */
- tmp = cx_read(sram_ch->int_msk);
- cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
-
- /* Turn OFF risc and fifo */
- tmp = cx_read(sram_ch->dma_ctl);
- cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
-
- /* Clear data buffer memory */
- if (dev->_data_buf_virt_addr_ch2)
- memset(dev->_data_buf_virt_addr_ch2, 0,
- dev->_data_buf_size_ch2);
-
- dev->_is_running_ch2 = 0;
- dev->_is_first_frame_ch2 = 0;
- dev->_frame_count_ch2 = 0;
- dev->_file_status_ch2 = END_OF_FILE;
-
- kfree(dev->_irq_queues_ch2);
- dev->_irq_queues_ch2 = NULL;
-
- kfree(dev->_filename_ch2);
-
- tmp = cx_read(VID_CH_MODE_SEL);
- cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
-}
-
-void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev)
-{
- if (dev->_is_running_ch2)
- cx25821_stop_upstream_video_ch2(dev);
-
- if (dev->_dma_virt_addr_ch2) {
- pci_free_consistent(dev->pci, dev->_risc_size_ch2,
- dev->_dma_virt_addr_ch2,
- dev->_dma_phys_addr_ch2);
- dev->_dma_virt_addr_ch2 = NULL;
- }
-
- if (dev->_data_buf_virt_addr_ch2) {
- pci_free_consistent(dev->pci, dev->_data_buf_size_ch2,
- dev->_data_buf_virt_addr_ch2,
- dev->_data_buf_phys_addr_ch2);
- dev->_data_buf_virt_addr_ch2 = NULL;
- }
-}
-
-int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
-{
- struct file *myfile;
- int frame_index_temp = dev->_frame_index_ch2;
- int i = 0;
- int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ?
- Y411_LINE_SZ : Y422_LINE_SZ;
- int frame_size = 0;
- int frame_offset = 0;
- ssize_t vfs_read_retval = 0;
- char mybuf[line_size];
- loff_t file_offset;
- loff_t pos;
- mm_segment_t old_fs;
-
- if (dev->_file_status_ch2 == END_OF_FILE)
- return 0;
-
- if (dev->_isNTSC_ch2) {
- frame_size = (line_size == Y411_LINE_SZ) ?
- FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;
- } else {
- frame_size = (line_size == Y411_LINE_SZ) ?
- FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
- }
-
- frame_offset = (frame_index_temp > 0) ? frame_size : 0;
- file_offset = dev->_frame_count_ch2 * frame_size;
-
- myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0);
- if (IS_ERR(myfile)) {
- const int open_errno = -PTR_ERR(myfile);
- pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
- __func__, dev->_filename_ch2, open_errno);
- return PTR_ERR(myfile);
- } else {
- if (!(myfile->f_op)) {
- pr_err("%s(): File has no file operations registered!\n",
- __func__);
- filp_close(myfile, NULL);
- return -EIO;
- }
-
- if (!myfile->f_op->read) {
- pr_err("%s(): File has no READ operations registered!\n",
- __func__);
- filp_close(myfile, NULL);
- return -EIO;
- }
-
- pos = myfile->f_pos;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- for (i = 0; i < dev->_lines_count_ch2; i++) {
- pos = file_offset;
-
- vfs_read_retval = vfs_read(myfile, mybuf, line_size,
- &pos);
-
- if (vfs_read_retval > 0 && vfs_read_retval == line_size
- && dev->_data_buf_virt_addr_ch2 != NULL) {
- memcpy((void *)(dev->_data_buf_virt_addr_ch2 +
- frame_offset / 4), mybuf,
- vfs_read_retval);
- }
-
- file_offset += vfs_read_retval;
- frame_offset += vfs_read_retval;
-
- if (vfs_read_retval < line_size) {
- pr_info("Done: exit %s() since no more bytes to read from Video file\n",
- __func__);
- break;
- }
- }
-
- if (i > 0)
- dev->_frame_count_ch2++;
-
- dev->_file_status_ch2 = (vfs_read_retval == line_size) ?
- IN_PROGRESS : END_OF_FILE;
-
- set_fs(old_fs);
- filp_close(myfile, NULL);
- }
-
- return 0;
-}
-
-static void cx25821_vidups_handler_ch2(struct work_struct *work)
-{
- struct cx25821_dev *dev = container_of(work, struct cx25821_dev,
- _irq_work_entry_ch2);
-
- if (!dev) {
- pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n",
- __func__);
- return;
- }
-
- cx25821_get_frame_ch2(dev, dev->channels[dev->
- _channel2_upstream_select].sram_channels);
-}
-
-int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
-{
- struct file *myfile;
- int i = 0, j = 0;
- int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ?
- Y411_LINE_SZ : Y422_LINE_SZ;
- ssize_t vfs_read_retval = 0;
- char mybuf[line_size];
- loff_t pos;
- loff_t offset = (unsigned long)0;
- mm_segment_t old_fs;
-
- myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0);
-
- if (IS_ERR(myfile)) {
- const int open_errno = -PTR_ERR(myfile);
- pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
- __func__, dev->_filename_ch2, open_errno);
- return PTR_ERR(myfile);
- } else {
- if (!(myfile->f_op)) {
- pr_err("%s(): File has no file operations registered!\n",
- __func__);
- filp_close(myfile, NULL);
- return -EIO;
- }
-
- if (!myfile->f_op->read) {
- pr_err("%s(): File has no READ operations registered! Returning\n",
- __func__);
- filp_close(myfile, NULL);
- return -EIO;
- }
-
- pos = myfile->f_pos;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- for (j = 0; j < NUM_FRAMES; j++) {
- for (i = 0; i < dev->_lines_count_ch2; i++) {
- pos = offset;
-
- vfs_read_retval = vfs_read(myfile, mybuf,
- line_size, &pos);
-
- if (vfs_read_retval > 0 &&
- vfs_read_retval == line_size &&
- dev->_data_buf_virt_addr_ch2 != NULL) {
- memcpy((void *)(dev->
- _data_buf_virt_addr_ch2
- + offset / 4), mybuf,
- vfs_read_retval);
- }
-
- offset += vfs_read_retval;
-
- if (vfs_read_retval < line_size) {
- pr_info("Done: exit %s() since no more bytes to read from Video file\n",
- __func__);
- break;
- }
- }
-
- if (i > 0)
- dev->_frame_count_ch2++;
-
- if (vfs_read_retval < line_size)
- break;
- }
-
- dev->_file_status_ch2 = (vfs_read_retval == line_size) ?
- IN_PROGRESS : END_OF_FILE;
-
- set_fs(old_fs);
- myfile->f_pos = 0;
- filp_close(myfile, NULL);
- }
-
- return 0;
-}
-
-static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
- struct sram_channel *sram_ch,
- int bpl)
-{
- int ret = 0;
- dma_addr_t dma_addr;
- dma_addr_t data_dma_addr;
-
- if (dev->_dma_virt_addr_ch2 != NULL) {
- pci_free_consistent(dev->pci, dev->upstream_riscbuf_size_ch2,
- dev->_dma_virt_addr_ch2,
- dev->_dma_phys_addr_ch2);
- }
-
- dev->_dma_virt_addr_ch2 = pci_alloc_consistent(dev->pci,
- dev->upstream_riscbuf_size_ch2, &dma_addr);
- dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2;
- dev->_dma_phys_start_addr_ch2 = dma_addr;
- dev->_dma_phys_addr_ch2 = dma_addr;
- dev->_risc_size_ch2 = dev->upstream_riscbuf_size_ch2;
-
- if (!dev->_dma_virt_addr_ch2) {
- pr_err("FAILED to allocate memory for Risc buffer! Returning\n");
- return -ENOMEM;
- }
-
- /* Iniitize at this address until n bytes to 0 */
- memset(dev->_dma_virt_addr_ch2, 0, dev->_risc_size_ch2);
-
- if (dev->_data_buf_virt_addr_ch2 != NULL) {
- pci_free_consistent(dev->pci, dev->upstream_databuf_size_ch2,
- dev->_data_buf_virt_addr_ch2,
- dev->_data_buf_phys_addr_ch2);
- }
- /* For Video Data buffer allocation */
- dev->_data_buf_virt_addr_ch2 = pci_alloc_consistent(dev->pci,
- dev->upstream_databuf_size_ch2, &data_dma_addr);
- dev->_data_buf_phys_addr_ch2 = data_dma_addr;
- dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2;
-
- if (!dev->_data_buf_virt_addr_ch2) {
- pr_err("FAILED to allocate memory for data buffer! Returning\n");
- return -ENOMEM;
- }
-
- /* Initialize at this address until n bytes to 0 */
- memset(dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2);
-
- ret = cx25821_openfile_ch2(dev, sram_ch);
- if (ret < 0)
- return ret;
-
- /* Creating RISC programs */
- ret = cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl,
- dev->_lines_count_ch2);
- if (ret < 0) {
- pr_info("Failed creating Video Upstream Risc programs!\n");
- goto error;
- }
-
- return 0;
-
-error:
- return ret;
-}
-
-int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num,
- u32 status)
-{
- u32 int_msk_tmp;
- struct sram_channel *channel = dev->channels[chan_num].sram_channels;
- int singlefield_lines = NTSC_FIELD_HEIGHT;
- int line_size_in_bytes = Y422_LINE_SZ;
- int odd_risc_prog_size = 0;
- dma_addr_t risc_phys_jump_addr;
- __le32 *rp;
-
- if (status & FLD_VID_SRC_RISC1) {
- /* We should only process one program per call */
- u32 prog_cnt = cx_read(channel->gpcnt);
-
- /*
- * Since we've identified our IRQ, clear our bits from the
- * interrupt mask and interrupt status registers
- */
- int_msk_tmp = cx_read(channel->int_msk);
- cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
- cx_write(channel->int_stat, _intr_msk);
-
- spin_lock(&dev->slock);
-
- dev->_frame_index_ch2 = prog_cnt;
-
- queue_work(dev->_irq_queues_ch2, &dev->_irq_work_entry_ch2);
-
- if (dev->_is_first_frame_ch2) {
- dev->_is_first_frame_ch2 = 0;
-
- if (dev->_isNTSC_ch2) {
- singlefield_lines += 1;
- odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
- } else {
- singlefield_lines = PAL_FIELD_HEIGHT;
- odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
- }
-
- if (dev->_dma_virt_start_addr_ch2 != NULL) {
- if (dev->_pixel_format_ch2 == PIXEL_FRMT_411)
- line_size_in_bytes = Y411_LINE_SZ;
- else
- line_size_in_bytes = Y422_LINE_SZ;
- risc_phys_jump_addr =
- dev->_dma_phys_start_addr_ch2 +
- odd_risc_prog_size;
-
- rp = cx25821_update_riscprogram_ch2(dev,
- dev->_dma_virt_start_addr_ch2,
- TOP_OFFSET, line_size_in_bytes,
- 0x0, singlefield_lines,
- FIFO_DISABLE, ODD_FIELD);
-
- /* Jump to Even Risc program of 1st Frame */
- *(rp++) = cpu_to_le32(RISC_JUMP);
- *(rp++) = cpu_to_le32(risc_phys_jump_addr);
- *(rp++) = cpu_to_le32(0);
- }
- }
-
- spin_unlock(&dev->slock);
- }
-
- if (dev->_file_status_ch2 == END_OF_FILE) {
- pr_info("EOF Channel 2 Framecount = %d\n",
- dev->_frame_count_ch2);
- return -1;
- }
- /* ElSE, set the interrupt mask register, re-enable irq. */
- int_msk_tmp = cx_read(channel->int_msk);
- cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
-
- return 0;
-}
-
-static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id)
-{
- struct cx25821_dev *dev = dev_id;
- u32 vid_status;
- int handled = 0;
- int channel_num = 0;
- struct sram_channel *sram_ch;
-
- if (!dev)
- return -1;
-
- channel_num = VID_UPSTREAM_SRAM_CHANNEL_J;
- sram_ch = dev->channels[channel_num].sram_channels;
-
- vid_status = cx_read(sram_ch->int_stat);
-
- /* Only deal with our interrupt */
- if (vid_status)
- handled = cx25821_video_upstream_irq_ch2(dev, channel_num,
- vid_status);
-
- if (handled < 0)
- cx25821_stop_upstream_video_ch2(dev);
- else
- handled += handled;
-
- return IRQ_RETVAL(handled);
-}
-
-static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev,
- struct sram_channel *ch, int pix_format)
-{
- int width = WIDTH_D1;
- int height = dev->_lines_count_ch2;
- int num_lines, odd_num_lines;
- u32 value;
- int vip_mode = PIXEL_ENGINE_VIP1;
-
- value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);
- value &= 0xFFFFFFEF;
- value |= dev->_isNTSC_ch2 ? 0 : 0x10;
- cx_write(ch->vid_fmt_ctl, value);
-
- /*
- * set number of active pixels in each line. Default is 720
- * pixels in both NTSC and PAL format
- */
- cx_write(ch->vid_active_ctl1, width);
-
- num_lines = (height / 2) & 0x3FF;
- odd_num_lines = num_lines;
-
- if (dev->_isNTSC_ch2)
- odd_num_lines += 1;
-
- value = (num_lines << 16) | odd_num_lines;
-
- /* set number of active lines in field 0 (top) and field 1 (bottom) */
- cx_write(ch->vid_active_ctl2, value);
-
- cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
-}
-
-int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev,
- struct sram_channel *sram_ch)
-{
- u32 tmp = 0;
- int err = 0;
-
- /*
- * 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface
- * for channel A-C
- */
- tmp = cx_read(VID_CH_MODE_SEL);
- cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
-
- /*
- * Set the physical start address of the RISC program in the initial
- * program counter(IPC) member of the cmds.
- */
- cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr_ch2);
- cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
-
- /* reset counter */
- cx_write(sram_ch->gpcnt_ctl, 3);
-
- /* Clear our bits from the interrupt status register. */
- cx_write(sram_ch->int_stat, _intr_msk);
-
- /* Set the interrupt mask register, enable irq. */
- cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
- tmp = cx_read(sram_ch->int_msk);
- cx_write(sram_ch->int_msk, tmp |= _intr_msk);
-
- err = request_irq(dev->pci->irq, cx25821_upstream_irq_ch2,
- IRQF_SHARED, dev->name, dev);
- if (err < 0) {
- pr_err("%s: can't get upstream IRQ %d\n",
- dev->name, dev->pci->irq);
- goto fail_irq;
- }
- /* Start the DMA engine */
- tmp = cx_read(sram_ch->dma_ctl);
- cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);
-
- dev->_is_running_ch2 = 1;
- dev->_is_first_frame_ch2 = 1;
-
- return 0;
-
-fail_irq:
- cx25821_dev_unregister(dev);
- return err;
-}
-
-int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
- int pixel_format)
-{
- struct sram_channel *sram_ch;
- u32 tmp;
- int retval = 0;
- int err = 0;
- int data_frame_size = 0;
- int risc_buffer_size = 0;
- int str_length = 0;
-
- if (dev->_is_running_ch2) {
- pr_info("Video Channel is still running so return!\n");
- return 0;
- }
-
- dev->_channel2_upstream_select = channel_select;
- sram_ch = dev->channels[channel_select].sram_channels;
-
- INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2);
- dev->_irq_queues_ch2 =
- create_singlethread_workqueue("cx25821_workqueue2");
-
- if (!dev->_irq_queues_ch2) {
- pr_err("create_singlethread_workqueue() for Video FAILED!\n");
- return -ENOMEM;
- }
- /*
- * 656/VIP SRC Upstream Channel I & J and 7 -
- * Host Bus Interface for channel A-C
- */
- tmp = cx_read(VID_CH_MODE_SEL);
- cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
-
- dev->_is_running_ch2 = 0;
- dev->_frame_count_ch2 = 0;
- dev->_file_status_ch2 = RESET_STATUS;
- dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576;
- dev->_pixel_format_ch2 = pixel_format;
- dev->_line_size_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_422) ?
- (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
- data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
- risc_buffer_size = dev->_isNTSC_ch2 ?
- NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
-
- if (dev->input_filename_ch2) {
- str_length = strlen(dev->input_filename_ch2);
- dev->_filename_ch2 = kmemdup(dev->input_filename_ch2,
- str_length + 1, GFP_KERNEL);
-
- if (!dev->_filename_ch2)
- goto error;
- } else {
- str_length = strlen(dev->_defaultname_ch2);
- dev->_filename_ch2 = kmemdup(dev->_defaultname_ch2,
- str_length + 1, GFP_KERNEL);
-
- if (!dev->_filename_ch2)
- goto error;
- }
-
- /* Default if filename is empty string */
- if (strcmp(dev->input_filename_ch2, "") == 0) {
- if (dev->_isNTSC_ch2) {
- dev->_filename_ch2 = (dev->_pixel_format_ch2 ==
- PIXEL_FRMT_411) ? "/root/vid411.yuv" :
- "/root/vidtest.yuv";
- } else {
- dev->_filename_ch2 = (dev->_pixel_format_ch2 ==
- PIXEL_FRMT_411) ? "/root/pal411.yuv" :
- "/root/pal422.yuv";
- }
- }
-
- retval = cx25821_sram_channel_setup_upstream(dev, sram_ch,
- dev->_line_size_ch2, 0);
-
- /* setup fifo + format */
- cx25821_set_pixelengine_ch2(dev, sram_ch, dev->_pixel_format_ch2);
-
- dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2;
- dev->upstream_databuf_size_ch2 = data_frame_size * 2;
-
- /* Allocating buffers and prepare RISC program */
- retval = cx25821_upstream_buffer_prepare_ch2(dev, sram_ch,
- dev->_line_size_ch2);
- if (retval < 0) {
- pr_err("%s: Failed to set up Video upstream buffers!\n",
- dev->name);
- goto error;
- }
-
- cx25821_start_video_dma_upstream_ch2(dev, sram_ch);
-
- return 0;
-
-error:
- cx25821_dev_unregister(dev);
-
- return err;
-}
diff --git a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.h b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.h
deleted file mode 100644
index d42dab59b66..00000000000
--- a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/mutex.h>
-#include <linux/workqueue.h>
-
-#define OPEN_FILE_1 0
-#define NUM_PROGS 8
-#define NUM_FRAMES 2
-#define ODD_FIELD 0
-#define EVEN_FIELD 1
-#define TOP_OFFSET 0
-#define FIFO_DISABLE 0
-#define FIFO_ENABLE 1
-#define TEST_FRAMES 5
-#define END_OF_FILE 0
-#define IN_PROGRESS 1
-#define RESET_STATUS -1
-#define NUM_NO_OPS 5
-
-/* PAL and NTSC line sizes and number of lines. */
-#define WIDTH_D1 720
-#define NTSC_LINES_PER_FRAME 480
-#define PAL_LINES_PER_FRAME 576
-#define PAL_LINE_SZ 1440
-#define Y422_LINE_SZ 1440
-#define Y411_LINE_SZ 1080
-#define NTSC_FIELD_HEIGHT 240
-#define NTSC_ODD_FLD_LINES 241
-#define PAL_FIELD_HEIGHT 288
-
-#define FRAME_SIZE_NTSC_Y422 (NTSC_LINES_PER_FRAME * Y422_LINE_SZ)
-#define FRAME_SIZE_NTSC_Y411 (NTSC_LINES_PER_FRAME * Y411_LINE_SZ)
-#define FRAME_SIZE_PAL_Y422 (PAL_LINES_PER_FRAME * Y422_LINE_SZ)
-#define FRAME_SIZE_PAL_Y411 (PAL_LINES_PER_FRAME * Y411_LINE_SZ)
-
-#define NTSC_DATA_BUF_SZ (Y422_LINE_SZ * NTSC_LINES_PER_FRAME)
-#define PAL_DATA_BUF_SZ (Y422_LINE_SZ * PAL_LINES_PER_FRAME)
-
-#define RISC_WRITECR_INSTRUCTION_SIZE 16
-#define RISC_SYNC_INSTRUCTION_SIZE 4
-#define JUMP_INSTRUCTION_SIZE 12
-#define MAXSIZE_NO_OPS 36
-#define DWORD_SIZE 4
-
-#define USE_RISC_NOOP_VIDEO 1
-
-#ifdef USE_RISC_NOOP_VIDEO
-#define PAL_US_VID_PROG_SIZE \
- (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \
- RISC_WRITECR_INSTRUCTION_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
- NUM_NO_OPS * DWORD_SIZE)
-
-#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
-
-#define PAL_VID_PROG_SIZE \
- ((PAL_FIELD_HEIGHT * 2) * 3 * DWORD_SIZE + \
- 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
- JUMP_INSTRUCTION_SIZE + 2 * NUM_NO_OPS * DWORD_SIZE)
-
-#define ODD_FLD_PAL_PROG_SIZE \
- (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \
- RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
- NUM_NO_OPS * DWORD_SIZE)
-
-#define NTSC_US_VID_PROG_SIZE \
- ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + \
- RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + \
- NUM_NO_OPS * DWORD_SIZE)
-
-#define NTSC_RISC_BUF_SIZE \
- (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE))
-
-#define FRAME1_VID_PROG_SIZE \
- ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * \
- 3 * DWORD_SIZE + 2 * RISC_SYNC_INSTRUCTION_SIZE + \
- RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + \
- 2 * NUM_NO_OPS * DWORD_SIZE)
-
-#define ODD_FLD_NTSC_PROG_SIZE \
- (NTSC_ODD_FLD_LINES * 3 * DWORD_SIZE + \
- RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
- NUM_NO_OPS * DWORD_SIZE)
-#endif
-
-#ifndef USE_RISC_NOOP_VIDEO
-#define PAL_US_VID_PROG_SIZE \
- ((PAL_FIELD_HEIGHT + 1) * 3 * DWORD_SIZE + \
- RISC_WRITECR_INSTRUCTION_SIZE)
-
-#define PAL_RISC_BUF_SIZE \
- (2 * (RISC_SYNC_INSTRUCTION_SIZE + PAL_US_VID_PROG_SIZE))
-
-#define PAL_VID_PROG_SIZE \
- ((PAL_FIELD_HEIGHT * 2) * 3 * DWORD_SIZE + \
- 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
- JUMP_INSTRUCTION_SIZE)
-
-#define ODD_FLD_PAL_PROG_SIZE \
- (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \
- RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE)
-
-#define ODD_FLD_NTSC_PROG_SIZE \
- (NTSC_ODD_FLD_LINES * 3 * DWORD_SIZE + \
- RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE)
-
-#define NTSC_US_VID_PROG_SIZE \
- ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + \
- RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
-
-#define NTSC_RISC_BUF_SIZE \
- (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE))
-
-#define FRAME1_VID_PROG_SIZE \
- ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * \
- 3 * DWORD_SIZE + 2 * RISC_SYNC_INSTRUCTION_SIZE + \
- RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
-
-#endif
diff --git a/drivers/media/video/cx25821/cx25821-video-upstream.c b/drivers/media/video/cx25821/cx25821-video-upstream.c
deleted file mode 100644
index 52c13e0b649..00000000000
--- a/drivers/media/video/cx25821/cx25821-video-upstream.c
+++ /dev/null
@@ -1,856 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "cx25821-video.h"
-#include "cx25821-video-upstream.h"
-
-#include <linux/fs.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/syscalls.h>
-#include <linux/file.h>
-#include <linux/fcntl.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
-MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
-MODULE_LICENSE("GPL");
-
-static int _intr_msk = FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC |
- FLD_VID_SRC_OPC_ERR;
-
-int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
- struct sram_channel *ch,
- unsigned int bpl, u32 risc)
-{
- unsigned int i, lines;
- u32 cdt;
-
- if (ch->cmds_start == 0) {
- cx_write(ch->ptr1_reg, 0);
- cx_write(ch->ptr2_reg, 0);
- cx_write(ch->cnt2_reg, 0);
- cx_write(ch->cnt1_reg, 0);
- return 0;
- }
-
- bpl = (bpl + 7) & ~7; /* alignment */
- cdt = ch->cdt;
- lines = ch->fifo_size / bpl;
-
- if (lines > 4)
- lines = 4;
-
- BUG_ON(lines < 2);
-
- /* write CDT */
- for (i = 0; i < lines; i++) {
- cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
- cx_write(cdt + 16 * i + 4, 0);
- cx_write(cdt + 16 * i + 8, 0);
- cx_write(cdt + 16 * i + 12, 0);
- }
-
- /* write CMDS */
- cx_write(ch->cmds_start + 0, risc);
-
- cx_write(ch->cmds_start + 4, 0);
- cx_write(ch->cmds_start + 8, cdt);
- cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
- cx_write(ch->cmds_start + 16, ch->ctrl_start);
-
- cx_write(ch->cmds_start + 20, VID_IQ_SIZE_DW);
-
- for (i = 24; i < 80; i += 4)
- cx_write(ch->cmds_start + i, 0);
-
- /* fill registers */
- cx_write(ch->ptr1_reg, ch->fifo_start);
- cx_write(ch->ptr2_reg, cdt);
- cx_write(ch->cnt2_reg, (lines * 16) >> 3);
- cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
-
- return 0;
-}
-
-static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev,
- __le32 *rp, unsigned int offset,
- unsigned int bpl, u32 sync_line,
- unsigned int lines, int fifo_enable,
- int field_type)
-{
- unsigned int line, i;
- int dist_betwn_starts = bpl * 2;
-
- *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
-
- if (USE_RISC_NOOP_VIDEO) {
- for (i = 0; i < NUM_NO_OPS; i++)
- *(rp++) = cpu_to_le32(RISC_NOOP);
- }
-
- /* scan lines */
- for (line = 0; line < lines; line++) {
- *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
- *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr + offset);
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
-
- if ((lines <= NTSC_FIELD_HEIGHT)
- || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) {
- offset += dist_betwn_starts;
- }
- }
-
- return rp;
-}
-
-static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp,
- dma_addr_t databuf_phys_addr,
- unsigned int offset, u32 sync_line,
- unsigned int bpl, unsigned int lines,
- int fifo_enable, int field_type)
-{
- unsigned int line, i;
- struct sram_channel *sram_ch =
- dev->channels[dev->_channel_upstream_select].sram_channels;
- int dist_betwn_starts = bpl * 2;
-
- /* sync instruction */
- if (sync_line != NO_SYNC_LINE)
- *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
-
- if (USE_RISC_NOOP_VIDEO) {
- for (i = 0; i < NUM_NO_OPS; i++)
- *(rp++) = cpu_to_le32(RISC_NOOP);
- }
-
- /* scan lines */
- for (line = 0; line < lines; line++) {
- *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
- *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
- *(rp++) = cpu_to_le32(0); /* bits 63-32 */
-
- if ((lines <= NTSC_FIELD_HEIGHT)
- || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC))
- /* to skip the other field line */
- offset += dist_betwn_starts;
-
- /* check if we need to enable the FIFO after the first 4 lines
- * For the upstream video channel, the risc engine will enable
- * the FIFO. */
- if (fifo_enable && line == 3) {
- *(rp++) = RISC_WRITECR;
- *(rp++) = sram_ch->dma_ctl;
- *(rp++) = FLD_VID_FIFO_EN;
- *(rp++) = 0x00000001;
- }
- }
-
- return rp;
-}
-
-int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,
- struct pci_dev *pci,
- unsigned int top_offset,
- unsigned int bpl, unsigned int lines)
-{
- __le32 *rp;
- int fifo_enable = 0;
- /* get line count for single field */
- int singlefield_lines = lines >> 1;
- int odd_num_lines = singlefield_lines;
- int frame = 0;
- int frame_size = 0;
- int databuf_offset = 0;
- int risc_program_size = 0;
- int risc_flag = RISC_CNT_RESET;
- unsigned int bottom_offset = bpl;
- dma_addr_t risc_phys_jump_addr;
-
- if (dev->_isNTSC) {
- odd_num_lines = singlefield_lines + 1;
- risc_program_size = FRAME1_VID_PROG_SIZE;
- frame_size = (bpl == Y411_LINE_SZ) ?
- FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;
- } else {
- risc_program_size = PAL_VID_PROG_SIZE;
- frame_size = (bpl == Y411_LINE_SZ) ?
- FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
- }
-
- /* Virtual address of Risc buffer program */
- rp = dev->_dma_virt_addr;
-
- for (frame = 0; frame < NUM_FRAMES; frame++) {
- databuf_offset = frame_size * frame;
-
- if (UNSET != top_offset) {
- fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
- rp = cx25821_risc_field_upstream(dev, rp,
- dev->_data_buf_phys_addr +
- databuf_offset, top_offset, 0, bpl,
- odd_num_lines, fifo_enable, ODD_FIELD);
- }
-
- fifo_enable = FIFO_DISABLE;
-
- /* Even Field */
- rp = cx25821_risc_field_upstream(dev, rp,
- dev->_data_buf_phys_addr +
- databuf_offset, bottom_offset,
- 0x200, bpl, singlefield_lines,
- fifo_enable, EVEN_FIELD);
-
- if (frame == 0) {
- risc_flag = RISC_CNT_RESET;
- risc_phys_jump_addr = dev->_dma_phys_start_addr +
- risc_program_size;
- } else {
- risc_phys_jump_addr = dev->_dma_phys_start_addr;
- risc_flag = RISC_CNT_INC;
- }
-
- /* Loop to 2ndFrameRISC or to Start of Risc
- * program & generate IRQ
- */
- *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
- *(rp++) = cpu_to_le32(risc_phys_jump_addr);
- *(rp++) = cpu_to_le32(0);
- }
-
- return 0;
-}
-
-void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)
-{
- struct sram_channel *sram_ch =
- dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels;
- u32 tmp = 0;
-
- if (!dev->_is_running) {
- pr_info("No video file is currently running so return!\n");
- return;
- }
- /* Disable RISC interrupts */
- tmp = cx_read(sram_ch->int_msk);
- cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
-
- /* Turn OFF risc and fifo enable */
- tmp = cx_read(sram_ch->dma_ctl);
- cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
-
- /* Clear data buffer memory */
- if (dev->_data_buf_virt_addr)
- memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);
-
- dev->_is_running = 0;
- dev->_is_first_frame = 0;
- dev->_frame_count = 0;
- dev->_file_status = END_OF_FILE;
-
- kfree(dev->_irq_queues);
- dev->_irq_queues = NULL;
-
- kfree(dev->_filename);
-
- tmp = cx_read(VID_CH_MODE_SEL);
- cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
-}
-
-void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev)
-{
- if (dev->_is_running)
- cx25821_stop_upstream_video_ch1(dev);
-
- if (dev->_dma_virt_addr) {
- pci_free_consistent(dev->pci, dev->_risc_size,
- dev->_dma_virt_addr, dev->_dma_phys_addr);
- dev->_dma_virt_addr = NULL;
- }
-
- if (dev->_data_buf_virt_addr) {
- pci_free_consistent(dev->pci, dev->_data_buf_size,
- dev->_data_buf_virt_addr,
- dev->_data_buf_phys_addr);
- dev->_data_buf_virt_addr = NULL;
- }
-}
-
-int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
-{
- struct file *myfile;
- int frame_index_temp = dev->_frame_index;
- int i = 0;
- int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ?
- Y411_LINE_SZ : Y422_LINE_SZ;
- int frame_size = 0;
- int frame_offset = 0;
- ssize_t vfs_read_retval = 0;
- char mybuf[line_size];
- loff_t file_offset;
- loff_t pos;
- mm_segment_t old_fs;
-
- if (dev->_file_status == END_OF_FILE)
- return 0;
-
- if (dev->_isNTSC)
- frame_size = (line_size == Y411_LINE_SZ) ?
- FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;
- else
- frame_size = (line_size == Y411_LINE_SZ) ?
- FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
-
- frame_offset = (frame_index_temp > 0) ? frame_size : 0;
- file_offset = dev->_frame_count * frame_size;
-
- myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0);
-
- if (IS_ERR(myfile)) {
- const int open_errno = -PTR_ERR(myfile);
- pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
- __func__, dev->_filename, open_errno);
- return PTR_ERR(myfile);
- } else {
- if (!(myfile->f_op)) {
- pr_err("%s(): File has no file operations registered!\n",
- __func__);
- filp_close(myfile, NULL);
- return -EIO;
- }
-
- if (!myfile->f_op->read) {
- pr_err("%s(): File has no READ operations registered!\n",
- __func__);
- filp_close(myfile, NULL);
- return -EIO;
- }
-
- pos = myfile->f_pos;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- for (i = 0; i < dev->_lines_count; i++) {
- pos = file_offset;
-
- vfs_read_retval = vfs_read(myfile, mybuf, line_size,
- &pos);
-
- if (vfs_read_retval > 0 && vfs_read_retval == line_size
- && dev->_data_buf_virt_addr != NULL) {
- memcpy((void *)(dev->_data_buf_virt_addr +
- frame_offset / 4), mybuf,
- vfs_read_retval);
- }
-
- file_offset += vfs_read_retval;
- frame_offset += vfs_read_retval;
-
- if (vfs_read_retval < line_size) {
- pr_info("Done: exit %s() since no more bytes to read from Video file\n",
- __func__);
- break;
- }
- }
-
- if (i > 0)
- dev->_frame_count++;
-
- dev->_file_status = (vfs_read_retval == line_size) ?
- IN_PROGRESS : END_OF_FILE;
-
- set_fs(old_fs);
- filp_close(myfile, NULL);
- }
-
- return 0;
-}
-
-static void cx25821_vidups_handler(struct work_struct *work)
-{
- struct cx25821_dev *dev = container_of(work, struct cx25821_dev,
- _irq_work_entry);
-
- if (!dev) {
- pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n",
- __func__);
- return;
- }
-
- cx25821_get_frame(dev, dev->channels[dev->_channel_upstream_select].
- sram_channels);
-}
-
-int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
-{
- struct file *myfile;
- int i = 0, j = 0;
- int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ?
- Y411_LINE_SZ : Y422_LINE_SZ;
- ssize_t vfs_read_retval = 0;
- char mybuf[line_size];
- loff_t pos;
- loff_t offset = (unsigned long)0;
- mm_segment_t old_fs;
-
- myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0);
-
- if (IS_ERR(myfile)) {
- const int open_errno = -PTR_ERR(myfile);
- pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
- __func__, dev->_filename, open_errno);
- return PTR_ERR(myfile);
- } else {
- if (!(myfile->f_op)) {
- pr_err("%s(): File has no file operations registered!\n",
- __func__);
- filp_close(myfile, NULL);
- return -EIO;
- }
-
- if (!myfile->f_op->read) {
- pr_err("%s(): File has no READ operations registered! Returning\n",
- __func__);
- filp_close(myfile, NULL);
- return -EIO;
- }
-
- pos = myfile->f_pos;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- for (j = 0; j < NUM_FRAMES; j++) {
- for (i = 0; i < dev->_lines_count; i++) {
- pos = offset;
-
- vfs_read_retval = vfs_read(myfile, mybuf,
- line_size, &pos);
-
- if (vfs_read_retval > 0
- && vfs_read_retval == line_size
- && dev->_data_buf_virt_addr != NULL) {
- memcpy((void *)(dev->
- _data_buf_virt_addr +
- offset / 4), mybuf,
- vfs_read_retval);
- }
-
- offset += vfs_read_retval;
-
- if (vfs_read_retval < line_size) {
- pr_info("Done: exit %s() since no more bytes to read from Video file\n",
- __func__);
- break;
- }
- }
-
- if (i > 0)
- dev->_frame_count++;
-
- if (vfs_read_retval < line_size)
- break;
- }
-
- dev->_file_status = (vfs_read_retval == line_size) ?
- IN_PROGRESS : END_OF_FILE;
-
- set_fs(old_fs);
- myfile->f_pos = 0;
- filp_close(myfile, NULL);
- }
-
- return 0;
-}
-
-int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
- struct sram_channel *sram_ch, int bpl)
-{
- int ret = 0;
- dma_addr_t dma_addr;
- dma_addr_t data_dma_addr;
-
- if (dev->_dma_virt_addr != NULL)
- pci_free_consistent(dev->pci, dev->upstream_riscbuf_size,
- dev->_dma_virt_addr, dev->_dma_phys_addr);
-
- dev->_dma_virt_addr = pci_alloc_consistent(dev->pci,
- dev->upstream_riscbuf_size, &dma_addr);
- dev->_dma_virt_start_addr = dev->_dma_virt_addr;
- dev->_dma_phys_start_addr = dma_addr;
- dev->_dma_phys_addr = dma_addr;
- dev->_risc_size = dev->upstream_riscbuf_size;
-
- if (!dev->_dma_virt_addr) {
- pr_err("FAILED to allocate memory for Risc buffer! Returning\n");
- return -ENOMEM;
- }
-
- /* Clear memory at address */
- memset(dev->_dma_virt_addr, 0, dev->_risc_size);
-
- if (dev->_data_buf_virt_addr != NULL)
- pci_free_consistent(dev->pci, dev->upstream_databuf_size,
- dev->_data_buf_virt_addr,
- dev->_data_buf_phys_addr);
- /* For Video Data buffer allocation */
- dev->_data_buf_virt_addr = pci_alloc_consistent(dev->pci,
- dev->upstream_databuf_size, &data_dma_addr);
- dev->_data_buf_phys_addr = data_dma_addr;
- dev->_data_buf_size = dev->upstream_databuf_size;
-
- if (!dev->_data_buf_virt_addr) {
- pr_err("FAILED to allocate memory for data buffer! Returning\n");
- return -ENOMEM;
- }
-
- /* Clear memory at address */
- memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);
-
- ret = cx25821_openfile(dev, sram_ch);
- if (ret < 0)
- return ret;
-
- /* Create RISC programs */
- ret = cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl,
- dev->_lines_count);
- if (ret < 0) {
- pr_info("Failed creating Video Upstream Risc programs!\n");
- goto error;
- }
-
- return 0;
-
-error:
- return ret;
-}
-
-int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
- u32 status)
-{
- u32 int_msk_tmp;
- struct sram_channel *channel = dev->channels[chan_num].sram_channels;
- int singlefield_lines = NTSC_FIELD_HEIGHT;
- int line_size_in_bytes = Y422_LINE_SZ;
- int odd_risc_prog_size = 0;
- dma_addr_t risc_phys_jump_addr;
- __le32 *rp;
-
- if (status & FLD_VID_SRC_RISC1) {
- /* We should only process one program per call */
- u32 prog_cnt = cx_read(channel->gpcnt);
-
- /* Since we've identified our IRQ, clear our bits from the
- * interrupt mask and interrupt status registers */
- int_msk_tmp = cx_read(channel->int_msk);
- cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
- cx_write(channel->int_stat, _intr_msk);
-
- spin_lock(&dev->slock);
-
- dev->_frame_index = prog_cnt;
-
- queue_work(dev->_irq_queues, &dev->_irq_work_entry);
-
- if (dev->_is_first_frame) {
- dev->_is_first_frame = 0;
-
- if (dev->_isNTSC) {
- singlefield_lines += 1;
- odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
- } else {
- singlefield_lines = PAL_FIELD_HEIGHT;
- odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
- }
-
- if (dev->_dma_virt_start_addr != NULL) {
- line_size_in_bytes =
- (dev->_pixel_format ==
- PIXEL_FRMT_411) ? Y411_LINE_SZ :
- Y422_LINE_SZ;
- risc_phys_jump_addr =
- dev->_dma_phys_start_addr +
- odd_risc_prog_size;
-
- rp = cx25821_update_riscprogram(dev,
- dev->_dma_virt_start_addr, TOP_OFFSET,
- line_size_in_bytes, 0x0,
- singlefield_lines, FIFO_DISABLE,
- ODD_FIELD);
-
- /* Jump to Even Risc program of 1st Frame */
- *(rp++) = cpu_to_le32(RISC_JUMP);
- *(rp++) = cpu_to_le32(risc_phys_jump_addr);
- *(rp++) = cpu_to_le32(0);
- }
- }
-
- spin_unlock(&dev->slock);
- } else {
- if (status & FLD_VID_SRC_UF)
- pr_err("%s(): Video Received Underflow Error Interrupt!\n",
- __func__);
-
- if (status & FLD_VID_SRC_SYNC)
- pr_err("%s(): Video Received Sync Error Interrupt!\n",
- __func__);
-
- if (status & FLD_VID_SRC_OPC_ERR)
- pr_err("%s(): Video Received OpCode Error Interrupt!\n",
- __func__);
- }
-
- if (dev->_file_status == END_OF_FILE) {
- pr_err("EOF Channel 1 Framecount = %d\n", dev->_frame_count);
- return -1;
- }
- /* ElSE, set the interrupt mask register, re-enable irq. */
- int_msk_tmp = cx_read(channel->int_msk);
- cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
-
- return 0;
-}
-
-static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)
-{
- struct cx25821_dev *dev = dev_id;
- u32 vid_status;
- int handled = 0;
- int channel_num = 0;
- struct sram_channel *sram_ch;
-
- if (!dev)
- return -1;
-
- channel_num = VID_UPSTREAM_SRAM_CHANNEL_I;
-
- sram_ch = dev->channels[channel_num].sram_channels;
-
- vid_status = cx_read(sram_ch->int_stat);
-
- /* Only deal with our interrupt */
- if (vid_status)
- handled = cx25821_video_upstream_irq(dev, channel_num,
- vid_status);
-
- if (handled < 0)
- cx25821_stop_upstream_video_ch1(dev);
- else
- handled += handled;
-
- return IRQ_RETVAL(handled);
-}
-
-void cx25821_set_pixelengine(struct cx25821_dev *dev, struct sram_channel *ch,
- int pix_format)
-{
- int width = WIDTH_D1;
- int height = dev->_lines_count;
- int num_lines, odd_num_lines;
- u32 value;
- int vip_mode = OUTPUT_FRMT_656;
-
- value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);
- value &= 0xFFFFFFEF;
- value |= dev->_isNTSC ? 0 : 0x10;
- cx_write(ch->vid_fmt_ctl, value);
-
- /* set number of active pixels in each line.
- * Default is 720 pixels in both NTSC and PAL format */
- cx_write(ch->vid_active_ctl1, width);
-
- num_lines = (height / 2) & 0x3FF;
- odd_num_lines = num_lines;
-
- if (dev->_isNTSC)
- odd_num_lines += 1;
-
- value = (num_lines << 16) | odd_num_lines;
-
- /* set number of active lines in field 0 (top) and field 1 (bottom) */
- cx_write(ch->vid_active_ctl2, value);
-
- cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
-}
-
-int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
- struct sram_channel *sram_ch)
-{
- u32 tmp = 0;
- int err = 0;
-
- /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
- * channel A-C
- */
- tmp = cx_read(VID_CH_MODE_SEL);
- cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
-
- /* Set the physical start address of the RISC program in the initial
- * program counter(IPC) member of the cmds.
- */
- cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr);
- /* Risc IPC High 64 bits 63-32 */
- cx_write(sram_ch->cmds_start + 4, 0);
-
- /* reset counter */
- cx_write(sram_ch->gpcnt_ctl, 3);
-
- /* Clear our bits from the interrupt status register. */
- cx_write(sram_ch->int_stat, _intr_msk);
-
- /* Set the interrupt mask register, enable irq. */
- cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
- tmp = cx_read(sram_ch->int_msk);
- cx_write(sram_ch->int_msk, tmp |= _intr_msk);
-
- err = request_irq(dev->pci->irq, cx25821_upstream_irq,
- IRQF_SHARED, dev->name, dev);
- if (err < 0) {
- pr_err("%s: can't get upstream IRQ %d\n",
- dev->name, dev->pci->irq);
- goto fail_irq;
- }
-
- /* Start the DMA engine */
- tmp = cx_read(sram_ch->dma_ctl);
- cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);
-
- dev->_is_running = 1;
- dev->_is_first_frame = 1;
-
- return 0;
-
-fail_irq:
- cx25821_dev_unregister(dev);
- return err;
-}
-
-int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
- int pixel_format)
-{
- struct sram_channel *sram_ch;
- u32 tmp;
- int retval = 0;
- int err = 0;
- int data_frame_size = 0;
- int risc_buffer_size = 0;
- int str_length = 0;
-
- if (dev->_is_running) {
- pr_info("Video Channel is still running so return!\n");
- return 0;
- }
-
- dev->_channel_upstream_select = channel_select;
- sram_ch = dev->channels[channel_select].sram_channels;
-
- INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler);
- dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue");
-
- if (!dev->_irq_queues) {
- pr_err("create_singlethread_workqueue() for Video FAILED!\n");
- return -ENOMEM;
- }
- /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
- * channel A-C
- */
- tmp = cx_read(VID_CH_MODE_SEL);
- cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
-
- dev->_is_running = 0;
- dev->_frame_count = 0;
- dev->_file_status = RESET_STATUS;
- dev->_lines_count = dev->_isNTSC ? 480 : 576;
- dev->_pixel_format = pixel_format;
- dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ?
- (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
- data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
- risc_buffer_size = dev->_isNTSC ?
- NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
-
- if (dev->input_filename) {
- str_length = strlen(dev->input_filename);
- dev->_filename = kmemdup(dev->input_filename, str_length + 1,
- GFP_KERNEL);
-
- if (!dev->_filename)
- goto error;
- } else {
- str_length = strlen(dev->_defaultname);
- dev->_filename = kmemdup(dev->_defaultname, str_length + 1,
- GFP_KERNEL);
-
- if (!dev->_filename)
- goto error;
- }
-
- /* Default if filename is empty string */
- if (strcmp(dev->input_filename, "") == 0) {
- if (dev->_isNTSC) {
- dev->_filename =
- (dev->_pixel_format == PIXEL_FRMT_411) ?
- "/root/vid411.yuv" : "/root/vidtest.yuv";
- } else {
- dev->_filename =
- (dev->_pixel_format == PIXEL_FRMT_411) ?
- "/root/pal411.yuv" : "/root/pal422.yuv";
- }
- }
-
- dev->_is_running = 0;
- dev->_frame_count = 0;
- dev->_file_status = RESET_STATUS;
- dev->_lines_count = dev->_isNTSC ? 480 : 576;
- dev->_pixel_format = pixel_format;
- dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ?
- (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
-
- retval = cx25821_sram_channel_setup_upstream(dev, sram_ch,
- dev->_line_size, 0);
-
- /* setup fifo + format */
- cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format);
-
- dev->upstream_riscbuf_size = risc_buffer_size * 2;
- dev->upstream_databuf_size = data_frame_size * 2;
-
- /* Allocating buffers and prepare RISC program */
- retval = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size);
- if (retval < 0) {
- pr_err("%s: Failed to set up Video upstream buffers!\n",
- dev->name);
- goto error;
- }
-
- cx25821_start_video_dma_upstream(dev, sram_ch);
-
- return 0;
-
-error:
- cx25821_dev_unregister(dev);
-
- return err;
-}
diff --git a/drivers/media/video/cx25821/cx25821-video-upstream.h b/drivers/media/video/cx25821/cx25821-video-upstream.h
deleted file mode 100644
index 268ec8aa6a6..00000000000
--- a/drivers/media/video/cx25821/cx25821-video-upstream.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/mutex.h>
-#include <linux/workqueue.h>
-
-#define OUTPUT_FRMT_656 0
-#define OPEN_FILE_1 0
-#define NUM_PROGS 8
-#define NUM_FRAMES 2
-#define ODD_FIELD 0
-#define EVEN_FIELD 1
-#define TOP_OFFSET 0
-#define FIFO_DISABLE 0
-#define FIFO_ENABLE 1
-#define TEST_FRAMES 5
-#define END_OF_FILE 0
-#define IN_PROGRESS 1
-#define RESET_STATUS -1
-#define NUM_NO_OPS 5
-
-/* PAL and NTSC line sizes and number of lines. */
-#define WIDTH_D1 720
-#define NTSC_LINES_PER_FRAME 480
-#define PAL_LINES_PER_FRAME 576
-#define PAL_LINE_SZ 1440
-#define Y422_LINE_SZ 1440
-#define Y411_LINE_SZ 1080
-#define NTSC_FIELD_HEIGHT 240
-#define NTSC_ODD_FLD_LINES 241
-#define PAL_FIELD_HEIGHT 288
-
-#define FRAME_SIZE_NTSC_Y422 (NTSC_LINES_PER_FRAME * Y422_LINE_SZ)
-#define FRAME_SIZE_NTSC_Y411 (NTSC_LINES_PER_FRAME * Y411_LINE_SZ)
-#define FRAME_SIZE_PAL_Y422 (PAL_LINES_PER_FRAME * Y422_LINE_SZ)
-#define FRAME_SIZE_PAL_Y411 (PAL_LINES_PER_FRAME * Y411_LINE_SZ)
-
-#define NTSC_DATA_BUF_SZ (Y422_LINE_SZ * NTSC_LINES_PER_FRAME)
-#define PAL_DATA_BUF_SZ (Y422_LINE_SZ * PAL_LINES_PER_FRAME)
-
-#define RISC_WRITECR_INSTRUCTION_SIZE 16
-#define RISC_SYNC_INSTRUCTION_SIZE 4
-#define JUMP_INSTRUCTION_SIZE 12
-#define MAXSIZE_NO_OPS 36
-#define DWORD_SIZE 4
-
-#define USE_RISC_NOOP_VIDEO 1
-
-#ifdef USE_RISC_NOOP_VIDEO
-#define PAL_US_VID_PROG_SIZE \
- (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \
- RISC_WRITECR_INSTRUCTION_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
- NUM_NO_OPS * DWORD_SIZE)
-
-#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
-
-#define PAL_VID_PROG_SIZE \
- ((PAL_FIELD_HEIGHT * 2) * 3 * DWORD_SIZE + \
- 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
- JUMP_INSTRUCTION_SIZE + 2 * NUM_NO_OPS * DWORD_SIZE)
-
-#define ODD_FLD_PAL_PROG_SIZE \
- (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \
- RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
- NUM_NO_OPS * DWORD_SIZE)
-
-#define ODD_FLD_NTSC_PROG_SIZE \
- (NTSC_ODD_FLD_LINES * 3 * DWORD_SIZE + \
- RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
- NUM_NO_OPS * DWORD_SIZE)
-
-#define NTSC_US_VID_PROG_SIZE \
- ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + \
- RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + \
- NUM_NO_OPS * DWORD_SIZE)
-
-#define NTSC_RISC_BUF_SIZE \
- (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE))
-
-#define FRAME1_VID_PROG_SIZE \
- ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + \
- 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
- JUMP_INSTRUCTION_SIZE + 2 * NUM_NO_OPS * DWORD_SIZE)
-
-#endif
-
-#ifndef USE_RISC_NOOP_VIDEO
-#define PAL_US_VID_PROG_SIZE \
- (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \
- RISC_WRITECR_INSTRUCTION_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
- JUMP_INSTRUCTION_SIZE)
-
-#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
-
-#define PAL_VID_PROG_SIZE \
- ((PAL_FIELD_HEIGHT * 2) * 3 * DWORD_SIZE + \
- 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
- JUMP_INSTRUCTION_SIZE)
-
-#define ODD_FLD_PAL_PROG_SIZE \
- (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \
- RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE)
-
-#define ODD_FLD_NTSC_PROG_SIZE \
- (NTSC_ODD_FLD_LINES * 3 * DWORD_SIZE + \
- RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE)
-
-#define NTSC_US_VID_PROG_SIZE \
- ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + \
- RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
-
-#define NTSC_RISC_BUF_SIZE \
- (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE))
-
-#define FRAME1_VID_PROG_SIZE \
- ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + \
- 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
- JUMP_INSTRUCTION_SIZE)
-
-#endif
diff --git a/drivers/media/video/cx25821/cx25821-video.c b/drivers/media/video/cx25821/cx25821-video.c
deleted file mode 100644
index b38d4379cc3..00000000000
--- a/drivers/media/video/cx25821/cx25821-video.c
+++ /dev/null
@@ -1,1990 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- * Parts adapted/taken from Eduardo Moscoso Rubino
- * Copyright (C) 2009 Eduardo Moscoso Rubino <moscoso@TopoLogica.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "cx25821-video.h"
-
-MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
-MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
-MODULE_LICENSE("GPL");
-
-static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
-static unsigned int radio_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
-
-module_param_array(video_nr, int, NULL, 0444);
-module_param_array(radio_nr, int, NULL, 0444);
-
-MODULE_PARM_DESC(video_nr, "video device numbers");
-MODULE_PARM_DESC(radio_nr, "radio device numbers");
-
-static unsigned int video_debug = VIDEO_DEBUG;
-module_param(video_debug, int, 0644);
-MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
-
-static unsigned int irq_debug;
-module_param(irq_debug, int, 0644);
-MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]");
-
-unsigned int vid_limit = 16;
-module_param(vid_limit, int, 0644);
-MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
-
-static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num);
-
-static const struct v4l2_file_operations video_fops;
-static const struct v4l2_ioctl_ops video_ioctl_ops;
-
-#define FORMAT_FLAGS_PACKED 0x01
-
-struct cx25821_fmt formats[] = {
- {
- .name = "8 bpp, gray",
- .fourcc = V4L2_PIX_FMT_GREY,
- .depth = 8,
- .flags = FORMAT_FLAGS_PACKED,
- }, {
- .name = "4:1:1, packed, Y41P",
- .fourcc = V4L2_PIX_FMT_Y41P,
- .depth = 12,
- .flags = FORMAT_FLAGS_PACKED,
- }, {
- .name = "4:2:2, packed, YUYV",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- }, {
- .name = "4:2:2, packed, UYVY",
- .fourcc = V4L2_PIX_FMT_UYVY,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- }, {
- .name = "4:2:0, YUV",
- .fourcc = V4L2_PIX_FMT_YUV420,
- .depth = 12,
- .flags = FORMAT_FLAGS_PACKED,
- },
-};
-
-int cx25821_get_format_size(void)
-{
- return ARRAY_SIZE(formats);
-}
-
-struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc)
-{
- unsigned int i;
-
- if (fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P)
- return formats + 1;
-
- for (i = 0; i < ARRAY_SIZE(formats); i++)
- if (formats[i].fourcc == fourcc)
- return formats + i;
-
- pr_err("%s(0x%08x) NOT FOUND\n", __func__, fourcc);
- return NULL;
-}
-
-void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,
- u32 count)
-{
- struct cx25821_buffer *buf;
- int bc;
-
- for (bc = 0;; bc++) {
- if (list_empty(&q->active)) {
- dprintk(1, "bc=%d (=0: active empty)\n", bc);
- break;
- }
-
- buf = list_entry(q->active.next, struct cx25821_buffer,
- vb.queue);
-
- /* count comes from the hw and it is 16bit wide --
- * this trick handles wrap-arounds correctly for
- * up to 32767 buffers in flight... */
- if ((s16) (count - buf->count) < 0)
- break;
-
- do_gettimeofday(&buf->vb.ts);
- buf->vb.state = VIDEOBUF_DONE;
- list_del(&buf->vb.queue);
- wake_up(&buf->vb.done);
- }
-
- if (list_empty(&q->active))
- del_timer(&q->timeout);
- else
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- if (bc != 1)
- pr_err("%s: %d buffers handled (should be 1)\n", __func__, bc);
-}
-
-#ifdef TUNER_FLAG
-int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
-{
- dprintk(1, "%s(norm = 0x%08x) name: [%s]\n",
- __func__, (unsigned int)norm, v4l2_norm_to_name(norm));
-
- dev->tvnorm = norm;
-
- /* Tell the internal A/V decoder */
- cx25821_call_all(dev, core, s_std, norm);
-
- return 0;
-}
-#endif
-
-struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
- struct pci_dev *pci,
- struct video_device *template,
- char *type)
-{
- struct video_device *vfd;
- dprintk(1, "%s()\n", __func__);
-
- vfd = video_device_alloc();
- if (NULL == vfd)
- return NULL;
- *vfd = *template;
- vfd->v4l2_dev = &dev->v4l2_dev;
- vfd->release = video_device_release;
- snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type,
- cx25821_boards[dev->board].name);
- video_set_drvdata(vfd, dev);
- return vfd;
-}
-
-/*
-static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
-{
- int i;
-
- if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
- return -EINVAL;
- for (i = 0; i < CX25821_CTLS; i++)
- if (cx25821_ctls[i].v.id == qctrl->id)
- break;
- if (i == CX25821_CTLS) {
- *qctrl = no_ctl;
- return 0;
- }
- *qctrl = cx25821_ctls[i].v;
- return 0;
-}
-*/
-
-/* resource management */
-int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh,
- unsigned int bit)
-{
- dprintk(1, "%s()\n", __func__);
- if (fh->resources & bit)
- /* have it already allocated */
- return 1;
-
- /* is it free? */
- mutex_lock(&dev->lock);
- if (dev->channels[fh->channel_id].resources & bit) {
- /* no, someone else uses it */
- mutex_unlock(&dev->lock);
- return 0;
- }
- /* it's free, grab it */
- fh->resources |= bit;
- dev->channels[fh->channel_id].resources |= bit;
- dprintk(1, "res: get %d\n", bit);
- mutex_unlock(&dev->lock);
- return 1;
-}
-
-int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit)
-{
- return fh->resources & bit;
-}
-
-int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit)
-{
- return fh->dev->channels[fh->channel_id].resources & bit;
-}
-
-void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh,
- unsigned int bits)
-{
- BUG_ON((fh->resources & bits) != bits);
- dprintk(1, "%s()\n", __func__);
-
- mutex_lock(&dev->lock);
- fh->resources &= ~bits;
- dev->channels[fh->channel_id].resources &= ~bits;
- dprintk(1, "res: put %d\n", bits);
- mutex_unlock(&dev->lock);
-}
-
-int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
-{
- struct v4l2_routing route;
- memset(&route, 0, sizeof(route));
-
- dprintk(1, "%s(): video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
- __func__, input, INPUT(input)->vmux, INPUT(input)->gpio0,
- INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3);
- dev->input = input;
-
- route.input = INPUT(input)->vmux;
-
- /* Tell the internal A/V decoder */
- cx25821_call_all(dev, video, s_routing, INPUT(input)->vmux, 0, 0);
-
- return 0;
-}
-
-int cx25821_start_video_dma(struct cx25821_dev *dev,
- struct cx25821_dmaqueue *q,
- struct cx25821_buffer *buf,
- struct sram_channel *channel)
-{
- int tmp = 0;
-
- /* setup fifo + format */
- cx25821_sram_channel_setup(dev, channel, buf->bpl, buf->risc.dma);
-
- /* reset counter */
- cx_write(channel->gpcnt_ctl, 3);
- q->count = 1;
-
- /* enable irq */
- cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << channel->i));
- cx_set(channel->int_msk, 0x11);
-
- /* start dma */
- cx_write(channel->dma_ctl, 0x11); /* FIFO and RISC enable */
-
- /* make sure upstream setting if any is reversed */
- tmp = cx_read(VID_CH_MODE_SEL);
- cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
-
- return 0;
-}
-
-int cx25821_restart_video_queue(struct cx25821_dev *dev,
- struct cx25821_dmaqueue *q,
- struct sram_channel *channel)
-{
- struct cx25821_buffer *buf, *prev;
- struct list_head *item;
-
- if (!list_empty(&q->active)) {
- buf = list_entry(q->active.next, struct cx25821_buffer,
- vb.queue);
-
- cx25821_start_video_dma(dev, q, buf, channel);
-
- list_for_each(item, &q->active) {
- buf = list_entry(item, struct cx25821_buffer, vb.queue);
- buf->count = q->count++;
- }
-
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- return 0;
- }
-
- prev = NULL;
- for (;;) {
- if (list_empty(&q->queued))
- return 0;
-
- buf = list_entry(q->queued.next, struct cx25821_buffer,
- vb.queue);
-
- if (NULL == prev) {
- list_move_tail(&buf->vb.queue, &q->active);
- cx25821_start_video_dma(dev, q, buf, channel);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- } else if (prev->vb.width == buf->vb.width &&
- prev->vb.height == buf->vb.height &&
- prev->fmt == buf->fmt) {
- list_move_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */
- } else {
- return 0;
- }
- prev = buf;
- }
-}
-
-void cx25821_vid_timeout(unsigned long data)
-{
- struct cx25821_data *timeout_data = (struct cx25821_data *)data;
- struct cx25821_dev *dev = timeout_data->dev;
- struct sram_channel *channel = timeout_data->channel;
- struct cx25821_dmaqueue *q = &dev->channels[channel->i].vidq;
- struct cx25821_buffer *buf;
- unsigned long flags;
-
- /* cx25821_sram_channel_dump(dev, channel); */
- cx_clear(channel->dma_ctl, 0x11);
-
- spin_lock_irqsave(&dev->slock, flags);
- while (!list_empty(&q->active)) {
- buf = list_entry(q->active.next, struct cx25821_buffer,
- vb.queue);
- list_del(&buf->vb.queue);
-
- buf->vb.state = VIDEOBUF_ERROR;
- wake_up(&buf->vb.done);
- }
-
- cx25821_restart_video_queue(dev, q, channel);
- spin_unlock_irqrestore(&dev->slock, flags);
-}
-
-int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
-{
- u32 count = 0;
- int handled = 0;
- u32 mask;
- struct sram_channel *channel = dev->channels[chan_num].sram_channels;
-
- mask = cx_read(channel->int_msk);
- if (0 == (status & mask))
- return handled;
-
- cx_write(channel->int_stat, status);
-
- /* risc op code error */
- if (status & (1 << 16)) {
- pr_warn("%s, %s: video risc op code error\n",
- dev->name, channel->name);
- cx_clear(channel->dma_ctl, 0x11);
- cx25821_sram_channel_dump(dev, channel);
- }
-
- /* risc1 y */
- if (status & FLD_VID_DST_RISC1) {
- spin_lock(&dev->slock);
- count = cx_read(channel->gpcnt);
- cx25821_video_wakeup(dev, &dev->channels[channel->i].vidq,
- count);
- spin_unlock(&dev->slock);
- handled++;
- }
-
- /* risc2 y */
- if (status & 0x10) {
- dprintk(2, "stopper video\n");
- spin_lock(&dev->slock);
- cx25821_restart_video_queue(dev,
- &dev->channels[channel->i].vidq, channel);
- spin_unlock(&dev->slock);
- handled++;
- }
- return handled;
-}
-
-void cx25821_videoioctl_unregister(struct cx25821_dev *dev)
-{
- if (dev->ioctl_dev) {
- if (video_is_registered(dev->ioctl_dev))
- video_unregister_device(dev->ioctl_dev);
- else
- video_device_release(dev->ioctl_dev);
-
- dev->ioctl_dev = NULL;
- }
-}
-
-void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
-{
- cx_clear(PCI_INT_MSK, 1);
-
- if (dev->channels[chan_num].video_dev) {
- if (video_is_registered(dev->channels[chan_num].video_dev))
- video_unregister_device(
- dev->channels[chan_num].video_dev);
- else
- video_device_release(
- dev->channels[chan_num].video_dev);
-
- dev->channels[chan_num].video_dev = NULL;
-
- btcx_riscmem_free(dev->pci,
- &dev->channels[chan_num].vidq.stopper);
-
- pr_warn("device %d released!\n", chan_num);
- }
-
-}
-
-int cx25821_video_register(struct cx25821_dev *dev)
-{
- int err;
- int i;
-
- struct video_device cx25821_video_device = {
- .name = "cx25821-video",
- .fops = &video_fops,
- .minor = -1,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX25821_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
- };
-
- spin_lock_init(&dev->slock);
-
- for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; ++i) {
- cx25821_init_controls(dev, i);
-
- cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper,
- dev->channels[i].sram_channels->dma_ctl, 0x11, 0);
-
- dev->channels[i].sram_channels = &cx25821_sram_channels[i];
- dev->channels[i].video_dev = NULL;
- dev->channels[i].resources = 0;
-
- cx_write(dev->channels[i].sram_channels->int_stat, 0xffffffff);
-
- INIT_LIST_HEAD(&dev->channels[i].vidq.active);
- INIT_LIST_HEAD(&dev->channels[i].vidq.queued);
-
- dev->channels[i].timeout_data.dev = dev;
- dev->channels[i].timeout_data.channel =
- &cx25821_sram_channels[i];
- dev->channels[i].vidq.timeout.function = cx25821_vid_timeout;
- dev->channels[i].vidq.timeout.data =
- (unsigned long)&dev->channels[i].timeout_data;
- init_timer(&dev->channels[i].vidq.timeout);
-
- /* register v4l devices */
- dev->channels[i].video_dev = cx25821_vdev_init(dev, dev->pci,
- &cx25821_video_device, "video");
-
- err = video_register_device(dev->channels[i].video_dev,
- VFL_TYPE_GRABBER, video_nr[dev->nr]);
-
- if (err < 0)
- goto fail_unreg;
-
- }
-
- /* set PCI interrupt */
- cx_set(PCI_INT_MSK, 0xff);
-
- /* initial device configuration */
- mutex_lock(&dev->lock);
-#ifdef TUNER_FLAG
- dev->tvnorm = cx25821_video_device.current_norm;
- cx25821_set_tvnorm(dev, dev->tvnorm);
-#endif
- mutex_unlock(&dev->lock);
-
- return 0;
-
-fail_unreg:
- cx25821_video_unregister(dev, i);
- return err;
-}
-
-int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count,
- unsigned int *size)
-{
- struct cx25821_fh *fh = q->priv_data;
-
- *size = fh->fmt->depth * fh->width * fh->height >> 3;
-
- if (0 == *count)
- *count = 32;
-
- if (*size * *count > vid_limit * 1024 * 1024)
- *count = (vid_limit * 1024 * 1024) / *size;
-
- return 0;
-}
-
-int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct cx25821_fh *fh = q->priv_data;
- struct cx25821_dev *dev = fh->dev;
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
- int rc, init_buffer = 0;
- u32 line0_offset;
- struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
- int bpl_local = LINE_SIZE_D1;
- int channel_opened = fh->channel_id;
-
- BUG_ON(NULL == fh->fmt);
- if (fh->width < 48 || fh->width > 720 ||
- fh->height < 32 || fh->height > 576)
- return -EINVAL;
-
- buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
-
- if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
- return -EINVAL;
-
- if (buf->fmt != fh->fmt ||
- buf->vb.width != fh->width ||
- buf->vb.height != fh->height || buf->vb.field != field) {
- buf->fmt = fh->fmt;
- buf->vb.width = fh->width;
- buf->vb.height = fh->height;
- buf->vb.field = field;
- init_buffer = 1;
- }
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- init_buffer = 1;
- rc = videobuf_iolock(q, &buf->vb, NULL);
- if (0 != rc) {
- printk(KERN_DEBUG pr_fmt("videobuf_iolock failed!\n"));
- goto fail;
- }
- }
-
- dprintk(1, "init_buffer=%d\n", init_buffer);
-
- if (init_buffer) {
-
- channel_opened = dev->channel_opened;
- if (channel_opened < 0 || channel_opened > 7)
- channel_opened = 7;
-
- if (dev->channels[channel_opened].pixel_formats ==
- PIXEL_FRMT_411)
- buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3;
- else
- buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width);
-
- if (dev->channels[channel_opened].pixel_formats ==
- PIXEL_FRMT_411) {
- bpl_local = buf->bpl;
- } else {
- bpl_local = buf->bpl; /* Default */
-
- if (channel_opened >= 0 && channel_opened <= 7) {
- if (dev->channels[channel_opened]
- .use_cif_resolution) {
- if (dev->tvnorm & V4L2_STD_PAL_BG ||
- dev->tvnorm & V4L2_STD_PAL_DK)
- bpl_local = 352 << 1;
- else
- bpl_local = dev->channels[
- channel_opened].
- cif_width << 1;
- }
- }
- }
-
- switch (buf->vb.field) {
- case V4L2_FIELD_TOP:
- cx25821_risc_buffer(dev->pci, &buf->risc,
- dma->sglist, 0, UNSET,
- buf->bpl, 0, buf->vb.height);
- break;
- case V4L2_FIELD_BOTTOM:
- cx25821_risc_buffer(dev->pci, &buf->risc,
- dma->sglist, UNSET, 0,
- buf->bpl, 0, buf->vb.height);
- break;
- case V4L2_FIELD_INTERLACED:
- /* All other formats are top field first */
- line0_offset = 0;
- dprintk(1, "top field first\n");
-
- cx25821_risc_buffer(dev->pci, &buf->risc,
- dma->sglist, line0_offset,
- bpl_local, bpl_local, bpl_local,
- buf->vb.height >> 1);
- break;
- case V4L2_FIELD_SEQ_TB:
- cx25821_risc_buffer(dev->pci, &buf->risc,
- dma->sglist,
- 0, buf->bpl * (buf->vb.height >> 1),
- buf->bpl, 0, buf->vb.height >> 1);
- break;
- case V4L2_FIELD_SEQ_BT:
- cx25821_risc_buffer(dev->pci, &buf->risc,
- dma->sglist,
- buf->bpl * (buf->vb.height >> 1), 0,
- buf->bpl, 0, buf->vb.height >> 1);
- break;
- default:
- BUG();
- }
- }
-
- dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
- buf, buf->vb.i, fh->width, fh->height, fh->fmt->depth,
- fh->fmt->name, (unsigned long)buf->risc.dma);
-
- buf->vb.state = VIDEOBUF_PREPARED;
-
- return 0;
-
-fail:
- cx25821_free_buffer(q, buf);
- return rc;
-}
-
-void cx25821_buffer_release(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
-
- cx25821_free_buffer(q, buf);
-}
-
-struct videobuf_queue *get_queue(struct cx25821_fh *fh)
-{
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- return &fh->vidq;
- default:
- BUG();
- return NULL;
- }
-}
-
-int cx25821_get_resource(struct cx25821_fh *fh, int resource)
-{
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- return resource;
- default:
- BUG();
- return 0;
- }
-}
-
-int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct cx25821_fh *fh = file->private_data;
-
- return videobuf_mmap_mapper(get_queue(fh), vma);
-}
-
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
- struct cx25821_buffer *prev;
- struct cx25821_fh *fh = vq->priv_data;
- struct cx25821_dev *dev = fh->dev;
- struct cx25821_dmaqueue *q = &dev->channels[fh->channel_id].vidq;
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
- buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx25821_start_video_dma(dev, q, buf,
- dev->channels[fh->channel_id].sram_channels);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
- buf, buf->vb.i, buf->count, q->count);
- } else {
- prev = list_entry(q->active.prev, struct cx25821_buffer,
- vb.queue);
- if (prev->vb.width == buf->vb.width
- && prev->vb.height == buf->vb.height
- && prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
- buf, buf->vb.i, buf->count);
-
- } else {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
- buf->vb.i);
- }
- }
-
- if (list_empty(&q->active))
- dprintk(2, "active queue empty!\n");
-}
-
-static struct videobuf_queue_ops cx25821_video_qops = {
- .buf_setup = cx25821_buffer_setup,
- .buf_prepare = cx25821_buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = cx25821_buffer_release,
-};
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx25821_dev *h, *dev = video_drvdata(file);
- struct cx25821_fh *fh;
- struct list_head *list;
- int minor = video_devdata(file)->minor;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- u32 pix_format;
- int ch_id = 0;
- int i;
-
- dprintk(1, "open dev=%s type=%s\n", video_device_node_name(vdev),
- v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- mutex_lock(&cx25821_devlist_mutex);
-
- list_for_each(list, &cx25821_devlist)
- {
- h = list_entry(list, struct cx25821_dev, devlist);
-
- for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) {
- if (h->channels[i].video_dev &&
- h->channels[i].video_dev->minor == minor) {
- dev = h;
- ch_id = i;
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- }
- }
- }
-
- if (NULL == dev) {
- mutex_unlock(&cx25821_devlist_mutex);
- kfree(fh);
- return -ENODEV;
- }
-
- file->private_data = fh;
- fh->dev = dev;
- fh->type = type;
- fh->width = 720;
- fh->channel_id = ch_id;
-
- if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
- fh->height = 576;
- else
- fh->height = 480;
-
- dev->channel_opened = fh->channel_id;
- if (dev->channels[ch_id].pixel_formats == PIXEL_FRMT_411)
- pix_format = V4L2_PIX_FMT_Y41P;
- else
- pix_format = V4L2_PIX_FMT_YUYV;
- fh->fmt = cx25821_format_by_fourcc(pix_format);
-
- v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio);
-
- videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops, &dev->pci->dev,
- &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer),
- fh, NULL);
-
- dprintk(1, "post videobuf_queue_init()\n");
- mutex_unlock(&cx25821_devlist_mutex);
-
- return 0;
-}
-
-static ssize_t video_read(struct file *file, char __user * data, size_t count,
- loff_t *ppos)
-{
- struct cx25821_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (cx25821_res_locked(fh, RESOURCE_VIDEO0))
- return -EBUSY;
-
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
-
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int video_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_buffer *buf;
-
- if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- return POLLERR;
- buf = list_entry(fh->vidq.stream.next,
- struct cx25821_buffer, vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx25821_buffer *)fh->vidq.read_buf;
- if (NULL == buf)
- return POLLERR;
- }
-
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
- if (buf->vb.state == VIDEOBUF_DONE) {
- struct cx25821_dev *dev = fh->dev;
-
- if (dev && dev->channels[fh->channel_id]
- .use_cif_resolution) {
- u8 cam_id = *((char *)buf->vb.baddr + 3);
- memcpy((char *)buf->vb.baddr,
- (char *)buf->vb.baddr + (fh->width * 2),
- (fh->width * 2));
- *((char *)buf->vb.baddr + 3) = cam_id;
- }
- }
-
- return POLLIN | POLLRDNORM;
- }
-
- return 0;
-}
-
-static int video_release(struct file *file)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
-
- /* stop the risc engine and fifo */
- cx_write(channel0->dma_ctl, 0); /* FIFO and RISC disable */
-
- /* stop video capture */
- if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
- videobuf_queue_cancel(&fh->vidq);
- cx25821_res_free(dev, fh, RESOURCE_VIDEO0);
- }
-
- if (fh->vidq.read_buf) {
- cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- videobuf_mmap_free(&fh->vidq);
-
- v4l2_prio_close(&dev->channels[fh->channel_id].prio, fh->prio);
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
-
- if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
- return -EINVAL;
-
- if (unlikely(i != fh->type))
- return -EINVAL;
-
- if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh,
- RESOURCE_VIDEO0))))
- return -EBUSY;
-
- return videobuf_streamon(get_queue(fh));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
- int err, res;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- res = cx25821_get_resource(fh, RESOURCE_VIDEO0);
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- cx25821_res_free(dev, fh, res);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- struct v4l2_mbus_framefmt mbus_fmt;
- int err;
- int pix_format = PIXEL_FRMT_422;
-
- if (fh) {
- err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
- fh->prio);
- if (0 != err)
- return err;
- }
-
- dprintk(2, "%s()\n", __func__);
- err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (0 != err)
- return err;
-
- fh->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
- fh->vidq.field = f->fmt.pix.field;
-
- /* check if width and height is valid based on set standard */
- if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm))
- fh->width = f->fmt.pix.width;
-
- if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm))
- fh->height = f->fmt.pix.height;
-
- if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
- pix_format = PIXEL_FRMT_411;
- else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
- pix_format = PIXEL_FRMT_422;
- else
- return -EINVAL;
-
- cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);
-
- /* check if cif resolution */
- if (fh->width == 320 || fh->width == 352)
- dev->channels[fh->channel_id].use_cif_resolution = 1;
- else
- dev->channels[fh->channel_id].use_cif_resolution = 0;
-
- dev->channels[fh->channel_id].cif_width = fh->width;
- medusa_set_resolution(dev, fh->width, SRAM_CH00);
-
- dprintk(2, "%s(): width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
- v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
- cx25821_call_all(dev, video, s_mbus_fmt, &mbus_fmt);
-
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- int ret_val = 0;
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
-
- ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
-
- p->sequence = dev->channels[fh->channel_id].vidq.count;
-
- return ret_val;
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- struct cx25821_fh *fh = priv;
- char name[32 + 2];
-
- struct sram_channel *sram_ch = dev->channels[fh->channel_id]
- .sram_channels;
- u32 tmp = 0;
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- pr_info("%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- cx25821_call_all(dev, core, log_status);
- tmp = cx_read(sram_ch->dma_ctl);
- pr_info("Video input 0 is %s\n",
- (tmp & 0x11) ? "streaming" : "stopped");
- pr_info("%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
- fh->prio);
- if (0 != err)
- return err;
- }
-
- return cx25821_set_control(dev, ctl, fh->channel_id);
-}
-
-/* VIDEO IOCTLS */
-int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fh *fh = priv;
-
- f->fmt.pix.width = fh->width;
- f->fmt.pix.height = fh->height;
- f->fmt.pix.field = fh->vidq.field;
- f->fmt.pix.pixelformat = fh->fmt->fourcc;
- f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3;
- f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
-
- return 0;
-}
-
-int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fmt *fmt;
- enum v4l2_field field;
- unsigned int maxw, maxh;
-
- fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
- if (NULL == fmt)
- return -EINVAL;
-
- field = f->fmt.pix.field;
- maxw = 720;
- maxh = 576;
-
- if (V4L2_FIELD_ANY == field) {
- if (f->fmt.pix.height > maxh / 2)
- field = V4L2_FIELD_INTERLACED;
- else
- field = V4L2_FIELD_TOP;
- }
-
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- break;
- default:
- return -EINVAL;
- }
-
- f->fmt.pix.field = field;
- if (f->fmt.pix.height < 32)
- f->fmt.pix.height = 32;
- if (f->fmt.pix.height > maxh)
- f->fmt.pix.height = maxh;
- if (f->fmt.pix.width < 48)
- f->fmt.pix.width = 48;
- if (f->fmt.pix.width > maxw)
- f->fmt.pix.width = maxw;
- f->fmt.pix.width &= ~0x03;
- f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
- f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
-
- return 0;
-}
-
-int cx25821_vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
-
- strcpy(cap->driver, "cx25821");
- strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
- sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
- cap->version = CX25821_VERSION_CODE;
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING;
- if (UNSET != dev->tuner_type)
- cap->capabilities |= V4L2_CAP_TUNER;
- return 0;
-}
-
-int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (unlikely(f->index >= ARRAY_SIZE(formats)))
- return -EINVAL;
-
- strlcpy(f->description, formats[f->index].name, sizeof(f->description));
- f->pixelformat = formats[f->index].fourcc;
-
- return 0;
-}
-
-int cx25821_vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct cx25821_fh *fh = priv;
- return videobuf_reqbufs(get_queue(fh), p);
-}
-
-int cx25821_vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct cx25821_fh *fh = priv;
- return videobuf_querybuf(get_queue(fh), p);
-}
-
-int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct cx25821_fh *fh = priv;
- return videobuf_qbuf(get_queue(fh), p);
-}
-
-int cx25821_vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
- struct cx25821_fh *fh = f;
-
- *p = v4l2_prio_max(&dev->channels[fh->channel_id].prio);
-
- return 0;
-}
-
-int cx25821_vidioc_s_priority(struct file *file, void *f,
- enum v4l2_priority prio)
-{
- struct cx25821_fh *fh = f;
- struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
-
- return v4l2_prio_change(&dev->channels[fh->channel_id].prio, &fh->prio,
- prio);
-}
-
-#ifdef TUNER_FLAG
-int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- dprintk(1, "%s()\n", __func__);
-
- if (fh) {
- err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
- fh->prio);
- if (0 != err)
- return err;
- }
-
- if (dev->tvnorm == *tvnorms)
- return 0;
-
- mutex_lock(&dev->lock);
- cx25821_set_tvnorm(dev, *tvnorms);
- mutex_unlock(&dev->lock);
-
- medusa_set_videostandard(dev);
-
- return 0;
-}
-#endif
-
-int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i)
-{
- static const char * const iname[] = {
- [CX25821_VMUX_COMPOSITE] = "Composite",
- [CX25821_VMUX_SVIDEO] = "S-Video",
- [CX25821_VMUX_DEBUG] = "for debug only",
- };
- unsigned int n;
- dprintk(1, "%s()\n", __func__);
-
- n = i->index;
- if (n >= 2)
- return -EINVAL;
-
- if (0 == INPUT(n)->type)
- return -EINVAL;
-
- i->type = V4L2_INPUT_TYPE_CAMERA;
- strcpy(i->name, iname[INPUT(n)->type]);
-
- i->std = CX25821_NORMS;
- return 0;
-}
-
-int cx25821_vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- dprintk(1, "%s()\n", __func__);
- return cx25821_enum_input(dev, i);
-}
-
-int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
-
- *i = dev->input;
- dprintk(1, "%s(): returns %d\n", __func__, *i);
- return 0;
-}
-
-int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- dprintk(1, "%s(%d)\n", __func__, i);
-
- if (fh) {
- err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
- fh->prio);
- if (0 != err)
- return err;
- }
-
- if (i >= CX25821_NR_INPUT) {
- dprintk(1, "%s(): -EINVAL\n", __func__);
- return -EINVAL;
- }
-
- mutex_lock(&dev->lock);
- cx25821_video_mux(dev, i);
- mutex_unlock(&dev->lock);
- return 0;
-}
-
-#ifdef TUNER_FLAG
-int cx25821_vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
-
- f->frequency = dev->freq;
-
- cx25821_call_all(dev, tuner, g_frequency, f);
-
- return 0;
-}
-
-int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f)
-{
- mutex_lock(&dev->lock);
- dev->freq = f->frequency;
-
- cx25821_call_all(dev, tuner, s_frequency, f);
-
- /* When changing channels it is required to reset TVAUDIO */
- msleep(10);
-
- mutex_unlock(&dev->lock);
-
- return 0;
-}
-
-int cx25821_vidioc_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev;
- int err;
-
- if (fh) {
- dev = fh->dev;
- err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
- fh->prio);
- if (0 != err)
- return err;
- } else {
- pr_err("Invalid fh pointer!\n");
- return -EINVAL;
- }
-
- return cx25821_set_freq(dev, f);
-}
-#endif
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-int cx25821_vidioc_g_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
-
- if (!v4l2_chip_match_host(&reg->match))
- return -EINVAL;
-
- cx25821_call_all(dev, core, g_register, reg);
-
- return 0;
-}
-
-int cx25821_vidioc_s_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
-
- if (!v4l2_chip_match_host(&reg->match))
- return -EINVAL;
-
- cx25821_call_all(dev, core, s_register, reg);
-
- return 0;
-}
-
-#endif
-
-#ifdef TUNER_FLAG
-int cx25821_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
-
- if (unlikely(UNSET == dev->tuner_type))
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
-
- strcpy(t->name, "Television");
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM;
- t->rangehigh = 0xffffffffUL;
-
- t->signal = 0xffff; /* LOCKED */
- return 0;
-}
-
-int cx25821_vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- struct cx25821_fh *fh = priv;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
- fh->prio);
- if (0 != err)
- return err;
- }
-
- dprintk(1, "%s()\n", __func__);
- if (UNSET == dev->tuner_type)
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
-
- return 0;
-}
-
-#endif
-/*****************************************************************************/
-static const struct v4l2_queryctrl no_ctl = {
- .name = "42",
- .flags = V4L2_CTRL_FLAG_DISABLED,
-};
-
-static struct v4l2_queryctrl cx25821_ctls[] = {
- /* --- video --- */
- {
- .id = V4L2_CID_BRIGHTNESS,
- .name = "Brightness",
- .minimum = 0,
- .maximum = 10000,
- .step = 1,
- .default_value = 6200,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }, {
- .id = V4L2_CID_CONTRAST,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 10000,
- .step = 1,
- .default_value = 5000,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }, {
- .id = V4L2_CID_SATURATION,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 10000,
- .step = 1,
- .default_value = 5000,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }, {
- .id = V4L2_CID_HUE,
- .name = "Hue",
- .minimum = 0,
- .maximum = 10000,
- .step = 1,
- .default_value = 5000,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
-static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls);
-
-static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
-{
- int i;
-
- if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
- return -EINVAL;
- for (i = 0; i < CX25821_CTLS; i++)
- if (cx25821_ctls[i].id == qctrl->id)
- break;
- if (i == CX25821_CTLS) {
- *qctrl = no_ctl;
- return 0;
- }
- *qctrl = cx25821_ctls[i];
- return 0;
-}
-
-int cx25821_vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qctrl)
-{
- return cx25821_ctrl_query(qctrl);
-}
-
-/* ------------------------------------------------------------------ */
-/* VIDEO CTRL IOCTLS */
-
-static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
-{
- unsigned int i;
-
- for (i = 0; i < CX25821_CTLS; i++)
- if (cx25821_ctls[i].id == id)
- return cx25821_ctls + i;
- return NULL;
-}
-
-int cx25821_vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- struct cx25821_fh *fh = priv;
-
- const struct v4l2_queryctrl *ctrl;
-
- ctrl = ctrl_by_id(ctl->id);
-
- if (NULL == ctrl)
- return -EINVAL;
- switch (ctl->id) {
- case V4L2_CID_BRIGHTNESS:
- ctl->value = dev->channels[fh->channel_id].ctl_bright;
- break;
- case V4L2_CID_HUE:
- ctl->value = dev->channels[fh->channel_id].ctl_hue;
- break;
- case V4L2_CID_CONTRAST:
- ctl->value = dev->channels[fh->channel_id].ctl_contrast;
- break;
- case V4L2_CID_SATURATION:
- ctl->value = dev->channels[fh->channel_id].ctl_saturation;
- break;
- }
- return 0;
-}
-
-int cx25821_set_control(struct cx25821_dev *dev,
- struct v4l2_control *ctl, int chan_num)
-{
- int err;
- const struct v4l2_queryctrl *ctrl;
-
- err = -EINVAL;
-
- ctrl = ctrl_by_id(ctl->id);
-
- if (NULL == ctrl)
- return err;
-
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_BOOLEAN:
- case V4L2_CTRL_TYPE_MENU:
- case V4L2_CTRL_TYPE_INTEGER:
- if (ctl->value < ctrl->minimum)
- ctl->value = ctrl->minimum;
- if (ctl->value > ctrl->maximum)
- ctl->value = ctrl->maximum;
- break;
- default:
- /* nothing */ ;
- }
-
- switch (ctl->id) {
- case V4L2_CID_BRIGHTNESS:
- dev->channels[chan_num].ctl_bright = ctl->value;
- medusa_set_brightness(dev, ctl->value, chan_num);
- break;
- case V4L2_CID_HUE:
- dev->channels[chan_num].ctl_hue = ctl->value;
- medusa_set_hue(dev, ctl->value, chan_num);
- break;
- case V4L2_CID_CONTRAST:
- dev->channels[chan_num].ctl_contrast = ctl->value;
- medusa_set_contrast(dev, ctl->value, chan_num);
- break;
- case V4L2_CID_SATURATION:
- dev->channels[chan_num].ctl_saturation = ctl->value;
- medusa_set_saturation(dev, ctl->value, chan_num);
- break;
- }
-
- err = 0;
-
- return err;
-}
-
-static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num)
-{
- struct v4l2_control ctrl;
- int i;
- for (i = 0; i < CX25821_CTLS; i++) {
- ctrl.id = cx25821_ctls[i].id;
- ctrl.value = cx25821_ctls[i].default_value;
-
- cx25821_set_control(dev, &ctrl, chan_num);
- }
-}
-
-int cx25821_vidioc_cropcap(struct file *file, void *priv,
- struct v4l2_cropcap *cropcap)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
-
- if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- cropcap->bounds.top = 0;
- cropcap->bounds.left = 0;
- cropcap->bounds.width = 720;
- cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480;
- cropcap->pixelaspect.numerator =
- dev->tvnorm == V4L2_STD_PAL_BG ? 59 : 10;
- cropcap->pixelaspect.denominator =
- dev->tvnorm == V4L2_STD_PAL_BG ? 54 : 11;
- cropcap->defrect = cropcap->bounds;
- return 0;
-}
-
-int cx25821_vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- struct cx25821_fh *fh = priv;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
- fh->prio);
- if (0 != err)
- return err;
- }
- /* cx25821_vidioc_s_crop not supported */
- return -EINVAL;
-}
-
-int cx25821_vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
-{
- /* cx25821_vidioc_g_crop not supported */
- return -EINVAL;
-}
-
-int cx25821_vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm)
-{
- /* medusa does not support video standard sensing of current input */
- *norm = CX25821_NORMS;
-
- return 0;
-}
-
-int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm)
-{
- if (tvnorm == V4L2_STD_PAL_BG) {
- if (width == 352 || width == 720)
- return 1;
- else
- return 0;
- }
-
- if (tvnorm == V4L2_STD_NTSC_M) {
- if (width == 320 || width == 352 || width == 720)
- return 1;
- else
- return 0;
- }
- return 0;
-}
-
-int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm)
-{
- if (tvnorm == V4L2_STD_PAL_BG) {
- if (height == 576 || height == 288)
- return 1;
- else
- return 0;
- }
-
- if (tvnorm == V4L2_STD_NTSC_M) {
- if (height == 480 || height == 240)
- return 1;
- else
- return 0;
- }
-
- return 0;
-}
-
-static long video_ioctl_upstream9(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
- int command = 0;
- struct upstream_user_struct *data_from_user;
-
- data_from_user = (struct upstream_user_struct *)arg;
-
- if (!data_from_user) {
- pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
- return 0;
- }
-
- command = data_from_user->command;
-
- if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO)
- return 0;
-
- dev->input_filename = data_from_user->input_filename;
- dev->input_audiofilename = data_from_user->input_filename;
- dev->vid_stdname = data_from_user->vid_stdname;
- dev->pixel_format = data_from_user->pixel_format;
- dev->channel_select = data_from_user->channel_select;
- dev->command = data_from_user->command;
-
- switch (command) {
- case UPSTREAM_START_VIDEO:
- cx25821_start_upstream_video_ch1(dev, data_from_user);
- break;
-
- case UPSTREAM_STOP_VIDEO:
- cx25821_stop_upstream_video_ch1(dev);
- break;
- }
-
- return 0;
-}
-
-static long video_ioctl_upstream10(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
- int command = 0;
- struct upstream_user_struct *data_from_user;
-
- data_from_user = (struct upstream_user_struct *)arg;
-
- if (!data_from_user) {
- pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
- return 0;
- }
-
- command = data_from_user->command;
-
- if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO)
- return 0;
-
- dev->input_filename_ch2 = data_from_user->input_filename;
- dev->input_audiofilename = data_from_user->input_filename;
- dev->vid_stdname_ch2 = data_from_user->vid_stdname;
- dev->pixel_format_ch2 = data_from_user->pixel_format;
- dev->channel_select_ch2 = data_from_user->channel_select;
- dev->command_ch2 = data_from_user->command;
-
- switch (command) {
- case UPSTREAM_START_VIDEO:
- cx25821_start_upstream_video_ch2(dev, data_from_user);
- break;
-
- case UPSTREAM_STOP_VIDEO:
- cx25821_stop_upstream_video_ch2(dev);
- break;
- }
-
- return 0;
-}
-
-static long video_ioctl_upstream11(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
- int command = 0;
- struct upstream_user_struct *data_from_user;
-
- data_from_user = (struct upstream_user_struct *)arg;
-
- if (!data_from_user) {
- pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
- return 0;
- }
-
- command = data_from_user->command;
-
- if (command != UPSTREAM_START_AUDIO && command != UPSTREAM_STOP_AUDIO)
- return 0;
-
- dev->input_filename = data_from_user->input_filename;
- dev->input_audiofilename = data_from_user->input_filename;
- dev->vid_stdname = data_from_user->vid_stdname;
- dev->pixel_format = data_from_user->pixel_format;
- dev->channel_select = data_from_user->channel_select;
- dev->command = data_from_user->command;
-
- switch (command) {
- case UPSTREAM_START_AUDIO:
- cx25821_start_upstream_audio(dev, data_from_user);
- break;
-
- case UPSTREAM_STOP_AUDIO:
- cx25821_stop_upstream_audio(dev);
- break;
- }
-
- return 0;
-}
-
-static long video_ioctl_set(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
- struct downstream_user_struct *data_from_user;
- int command;
- int width = 720;
- int selected_channel = 0;
- int pix_format = 0;
- int i = 0;
- int cif_enable = 0;
- int cif_width = 0;
-
- data_from_user = (struct downstream_user_struct *)arg;
-
- if (!data_from_user) {
- pr_err("%s(): User data is INVALID. Returning\n", __func__);
- return 0;
- }
-
- command = data_from_user->command;
-
- if (command != SET_VIDEO_STD && command != SET_PIXEL_FORMAT
- && command != ENABLE_CIF_RESOLUTION && command != REG_READ
- && command != REG_WRITE && command != MEDUSA_READ
- && command != MEDUSA_WRITE) {
- return 0;
- }
-
- switch (command) {
- case SET_VIDEO_STD:
- if (!strcmp(data_from_user->vid_stdname, "PAL"))
- dev->tvnorm = V4L2_STD_PAL_BG;
- else
- dev->tvnorm = V4L2_STD_NTSC_M;
- medusa_set_videostandard(dev);
- break;
-
- case SET_PIXEL_FORMAT:
- selected_channel = data_from_user->decoder_select;
- pix_format = data_from_user->pixel_format;
-
- if (!(selected_channel <= 7 && selected_channel >= 0)) {
- selected_channel -= 4;
- selected_channel = selected_channel % 8;
- }
-
- if (selected_channel >= 0)
- cx25821_set_pixel_format(dev, selected_channel,
- pix_format);
-
- break;
-
- case ENABLE_CIF_RESOLUTION:
- selected_channel = data_from_user->decoder_select;
- cif_enable = data_from_user->cif_resolution_enable;
- cif_width = data_from_user->cif_width;
-
- if (cif_enable) {
- if (dev->tvnorm & V4L2_STD_PAL_BG
- || dev->tvnorm & V4L2_STD_PAL_DK) {
- width = 352;
- } else {
- width = cif_width;
- if (cif_width != 320 && cif_width != 352)
- width = 320;
- }
- }
-
- if (!(selected_channel <= 7 && selected_channel >= 0)) {
- selected_channel -= 4;
- selected_channel = selected_channel % 8;
- }
-
- if (selected_channel <= 7 && selected_channel >= 0) {
- dev->channels[selected_channel].use_cif_resolution =
- cif_enable;
- dev->channels[selected_channel].cif_width = width;
- } else {
- for (i = 0; i < VID_CHANNEL_NUM; i++) {
- dev->channels[i].use_cif_resolution =
- cif_enable;
- dev->channels[i].cif_width = width;
- }
- }
-
- medusa_set_resolution(dev, width, selected_channel);
- break;
- case REG_READ:
- data_from_user->reg_data = cx_read(data_from_user->reg_address);
- break;
- case REG_WRITE:
- cx_write(data_from_user->reg_address, data_from_user->reg_data);
- break;
- case MEDUSA_READ:
- cx25821_i2c_read(&dev->i2c_bus[0],
- (u16) data_from_user->reg_address,
- &data_from_user->reg_data);
- break;
- case MEDUSA_WRITE:
- cx25821_i2c_write(&dev->i2c_bus[0],
- (u16) data_from_user->reg_address,
- data_from_user->reg_data);
- break;
- }
-
- return 0;
-}
-
-static long cx25821_video_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- int ret = 0;
-
- struct cx25821_fh *fh = file->private_data;
-
- /* check to see if it's the video upstream */
- if (fh->channel_id == SRAM_CH09) {
- ret = video_ioctl_upstream9(file, cmd, arg);
- return ret;
- } else if (fh->channel_id == SRAM_CH10) {
- ret = video_ioctl_upstream10(file, cmd, arg);
- return ret;
- } else if (fh->channel_id == SRAM_CH11) {
- ret = video_ioctl_upstream11(file, cmd, arg);
- ret = video_ioctl_set(file, cmd, arg);
- return ret;
- }
-
- return video_ioctl2(file, cmd, arg);
-}
-
-/* exported stuff */
-static const struct v4l2_file_operations video_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = cx25821_video_mmap,
- .ioctl = cx25821_video_ioctl,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = cx25821_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = cx25821_vidioc_reqbufs,
- .vidioc_querybuf = cx25821_vidioc_querybuf,
- .vidioc_qbuf = cx25821_vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-#ifdef TUNER_FLAG
- .vidioc_s_std = cx25821_vidioc_s_std,
- .vidioc_querystd = cx25821_vidioc_querystd,
-#endif
- .vidioc_cropcap = cx25821_vidioc_cropcap,
- .vidioc_s_crop = cx25821_vidioc_s_crop,
- .vidioc_g_crop = cx25821_vidioc_g_crop,
- .vidioc_enum_input = cx25821_vidioc_enum_input,
- .vidioc_g_input = cx25821_vidioc_g_input,
- .vidioc_s_input = cx25821_vidioc_s_input,
- .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_queryctrl = cx25821_vidioc_queryctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_g_priority = cx25821_vidioc_g_priority,
- .vidioc_s_priority = cx25821_vidioc_s_priority,
-#ifdef TUNER_FLAG
- .vidioc_g_tuner = cx25821_vidioc_g_tuner,
- .vidioc_s_tuner = cx25821_vidioc_s_tuner,
- .vidioc_g_frequency = cx25821_vidioc_g_frequency,
- .vidioc_s_frequency = cx25821_vidioc_s_frequency,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx25821_vidioc_g_register,
- .vidioc_s_register = cx25821_vidioc_s_register,
-#endif
-};
-
-struct video_device cx25821_videoioctl_template = {
- .name = "cx25821-videoioctl",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX25821_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
diff --git a/drivers/media/video/cx25821/cx25821-video.h b/drivers/media/video/cx25821/cx25821-video.h
deleted file mode 100644
index 9652a5e35ba..00000000000
--- a/drivers/media/video/cx25821/cx25821-video.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef CX25821_VIDEO_H_
-#define CX25821_VIDEO_H_
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kmod.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/kthread.h>
-#include <asm/div64.h>
-
-#include "cx25821.h"
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-
-#define TUNER_FLAG
-
-#define VIDEO_DEBUG 0
-
-#define dprintk(level, fmt, arg...) \
-do { \
- if (VIDEO_DEBUG >= level) \
- printk(KERN_DEBUG "%s/0: " fmt, dev->name, ##arg); \
-} while (0)
-
-/* For IOCTL to identify running upstream */
-#define UPSTREAM_START_VIDEO 700
-#define UPSTREAM_STOP_VIDEO 701
-#define UPSTREAM_START_AUDIO 702
-#define UPSTREAM_STOP_AUDIO 703
-#define UPSTREAM_DUMP_REGISTERS 702
-#define SET_VIDEO_STD 800
-#define SET_PIXEL_FORMAT 1000
-#define ENABLE_CIF_RESOLUTION 1001
-
-#define REG_READ 900
-#define REG_WRITE 901
-#define MEDUSA_READ 910
-#define MEDUSA_WRITE 911
-
-extern struct sram_channel *channel0;
-extern struct sram_channel *channel1;
-extern struct sram_channel *channel2;
-extern struct sram_channel *channel3;
-extern struct sram_channel *channel4;
-extern struct sram_channel *channel5;
-extern struct sram_channel *channel6;
-extern struct sram_channel *channel7;
-extern struct sram_channel *channel9;
-extern struct sram_channel *channel10;
-extern struct sram_channel *channel11;
-extern struct video_device cx25821_videoioctl_template;
-/* extern const u32 *ctrl_classes[]; */
-
-extern unsigned int vid_limit;
-
-#define FORMAT_FLAGS_PACKED 0x01
-extern struct cx25821_fmt formats[];
-extern struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc);
-extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
-
-extern void cx25821_video_wakeup(struct cx25821_dev *dev,
- struct cx25821_dmaqueue *q, u32 count);
-
-#ifdef TUNER_FLAG
-extern int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm);
-#endif
-
-extern int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh,
- unsigned int bit);
-extern int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit);
-extern int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit);
-extern void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh,
- unsigned int bits);
-extern int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input);
-extern int cx25821_start_video_dma(struct cx25821_dev *dev,
- struct cx25821_dmaqueue *q,
- struct cx25821_buffer *buf,
- struct sram_channel *channel);
-
-extern int cx25821_set_scale(struct cx25821_dev *dev, unsigned int width,
- unsigned int height, enum v4l2_field field);
-extern int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status);
-extern void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num);
-extern int cx25821_video_register(struct cx25821_dev *dev);
-extern int cx25821_get_format_size(void);
-
-extern int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count,
- unsigned int *size);
-extern int cx25821_buffer_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb,
- enum v4l2_field field);
-extern void cx25821_buffer_release(struct videobuf_queue *q,
- struct videobuf_buffer *vb);
-extern struct videobuf_queue *get_queue(struct cx25821_fh *fh);
-extern int cx25821_get_resource(struct cx25821_fh *fh, int resource);
-extern int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma);
-extern int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f);
-extern int cx25821_vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap);
-extern int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f);
-extern int cx25821_vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p);
-extern int cx25821_vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *p);
-extern int cx25821_vidioc_qbuf(struct file *file, void *priv,
- struct v4l2_buffer *p);
-extern int cx25821_vidioc_s_std(struct file *file, void *priv,
- v4l2_std_id *tvnorms);
-extern int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i);
-extern int cx25821_vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *i);
-extern int cx25821_vidioc_g_input(struct file *file, void *priv,
- unsigned int *i);
-extern int cx25821_vidioc_s_input(struct file *file, void *priv,
- unsigned int i);
-extern int cx25821_vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl);
-extern int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f);
-extern int cx25821_vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f);
-extern int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f);
-extern int cx25821_vidioc_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f);
-extern int cx25821_vidioc_g_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg);
-extern int cx25821_vidioc_s_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg);
-extern int cx25821_vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t);
-extern int cx25821_vidioc_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t);
-
-extern int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm);
-extern int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm);
-
-extern int cx25821_vidioc_g_priority(struct file *file, void *f,
- enum v4l2_priority *p);
-extern int cx25821_vidioc_s_priority(struct file *file, void *f,
- enum v4l2_priority prio);
-
-extern int cx25821_vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qctrl);
-extern int cx25821_set_control(struct cx25821_dev *dev,
- struct v4l2_control *ctrl, int chan_num);
-
-extern int cx25821_vidioc_cropcap(struct file *file, void *fh,
- struct v4l2_cropcap *cropcap);
-extern int cx25821_vidioc_s_crop(struct file *file, void *priv,
- struct v4l2_crop *crop);
-extern int cx25821_vidioc_g_crop(struct file *file, void *priv,
- struct v4l2_crop *crop);
-
-extern int cx25821_vidioc_querystd(struct file *file, void *priv,
- v4l2_std_id *norm);
-#endif
diff --git a/drivers/media/video/cx25821/cx25821.h b/drivers/media/video/cx25821/cx25821.h
deleted file mode 100644
index 8a9c0c86941..00000000000
--- a/drivers/media/video/cx25821/cx25821.h
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef CX25821_H_
-#define CX25821_H_
-
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/kdev_t.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/tuner.h>
-#include <media/tveeprom.h>
-#include <media/videobuf-dma-sg.h>
-#include <media/videobuf-dvb.h>
-
-#include "btcx-risc.h"
-#include "cx25821-reg.h"
-#include "cx25821-medusa-reg.h"
-#include "cx25821-sram.h"
-#include "cx25821-audio.h"
-#include "media/cx2341x.h"
-
-#include <linux/version.h>
-#include <linux/mutex.h>
-
-#define CX25821_VERSION_CODE KERNEL_VERSION(0, 0, 106)
-
-#define UNSET (-1U)
-#define NO_SYNC_LINE (-1U)
-
-#define CX25821_MAXBOARDS 2
-
-#define TRUE 1
-#define FALSE 0
-#define LINE_SIZE_D1 1440
-
-/* Number of decoders and encoders */
-#define MAX_DECODERS 8
-#define MAX_ENCODERS 2
-#define QUAD_DECODERS 4
-#define MAX_CAMERAS 16
-
-/* Max number of inputs by card */
-#define MAX_CX25821_INPUT 8
-#define INPUT(nr) (&cx25821_boards[dev->board].input[nr])
-#define RESOURCE_VIDEO0 1
-#define RESOURCE_VIDEO1 2
-#define RESOURCE_VIDEO2 4
-#define RESOURCE_VIDEO3 8
-#define RESOURCE_VIDEO4 16
-#define RESOURCE_VIDEO5 32
-#define RESOURCE_VIDEO6 64
-#define RESOURCE_VIDEO7 128
-#define RESOURCE_VIDEO8 256
-#define RESOURCE_VIDEO9 512
-#define RESOURCE_VIDEO10 1024
-#define RESOURCE_VIDEO11 2048
-#define RESOURCE_VIDEO_IOCTL 4096
-
-#define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */
-
-#define UNKNOWN_BOARD 0
-#define CX25821_BOARD 1
-
-/* Currently supported by the driver */
-#define CX25821_NORMS (\
- V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_M_KR | \
- V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \
- V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_H | \
- V4L2_STD_PAL_Nc)
-
-#define CX25821_BOARD_CONEXANT_ATHENA10 1
-#define MAX_VID_CHANNEL_NUM 12
-#define VID_CHANNEL_NUM 8
-#define CX25821_NR_INPUT 2
-
-struct cx25821_fmt {
- char *name;
- u32 fourcc; /* v4l2 format id */
- int depth;
- int flags;
- u32 cxformat;
-};
-
-struct cx25821_ctrl {
- struct v4l2_queryctrl v;
- u32 off;
- u32 reg;
- u32 mask;
- u32 shift;
-};
-
-struct cx25821_tvnorm {
- char *name;
- v4l2_std_id id;
- u32 cxiformat;
- u32 cxoformat;
-};
-
-struct cx25821_fh {
- struct cx25821_dev *dev;
- enum v4l2_buf_type type;
- int radio;
- u32 resources;
-
- enum v4l2_priority prio;
-
- /* video overlay */
- struct v4l2_window win;
- struct v4l2_clip *clips;
- unsigned int nclips;
-
- /* video capture */
- struct cx25821_fmt *fmt;
- unsigned int width, height;
- int channel_id;
-
- /* vbi capture */
- struct videobuf_queue vidq;
- struct videobuf_queue vbiq;
-
- /* H264 Encoder specifics ONLY */
- struct videobuf_queue mpegq;
- atomic_t v4l_reading;
-};
-
-enum cx25821_itype {
- CX25821_VMUX_COMPOSITE = 1,
- CX25821_VMUX_SVIDEO,
- CX25821_VMUX_DEBUG,
- CX25821_RADIO,
-};
-
-enum cx25821_src_sel_type {
- CX25821_SRC_SEL_EXT_656_VIDEO = 0,
- CX25821_SRC_SEL_PARALLEL_MPEG_VIDEO
-};
-
-/* buffer for one video frame */
-struct cx25821_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
-
- /* cx25821 specific */
- unsigned int bpl;
- struct btcx_riscmem risc;
- struct cx25821_fmt *fmt;
- u32 count;
-};
-
-struct cx25821_input {
- enum cx25821_itype type;
- unsigned int vmux;
- u32 gpio0, gpio1, gpio2, gpio3;
-};
-
-enum port {
- CX25821_UNDEFINED = 0,
- CX25821_RAW,
- CX25821_264
-};
-
-struct cx25821_board {
- const char *name;
- enum port porta;
- enum port portb;
- enum port portc;
- unsigned int tuner_type;
- unsigned int radio_type;
- unsigned char tuner_addr;
- unsigned char radio_addr;
-
- u32 clk_freq;
- struct cx25821_input input[CX25821_NR_INPUT];
-};
-
-struct cx25821_subid {
- u16 subvendor;
- u16 subdevice;
- u32 card;
-};
-
-struct cx25821_i2c {
- struct cx25821_dev *dev;
-
- int nr;
-
- /* i2c i/o */
- struct i2c_adapter i2c_adap;
- struct i2c_client i2c_client;
- u32 i2c_rc;
-
- /* cx25821 registers used for raw addess */
- u32 i2c_period;
- u32 reg_ctrl;
- u32 reg_stat;
- u32 reg_addr;
- u32 reg_rdata;
- u32 reg_wdata;
-};
-
-struct cx25821_dmaqueue {
- struct list_head active;
- struct list_head queued;
- struct timer_list timeout;
- struct btcx_riscmem stopper;
- u32 count;
-};
-
-struct cx25821_data {
- struct cx25821_dev *dev;
- struct sram_channel *channel;
-};
-
-struct cx25821_channel {
- struct v4l2_prio_state prio;
-
- int ctl_bright;
- int ctl_contrast;
- int ctl_hue;
- int ctl_saturation;
- struct cx25821_data timeout_data;
-
- struct video_device *video_dev;
- struct cx25821_dmaqueue vidq;
-
- struct sram_channel *sram_channels;
-
- struct mutex lock;
- int resources;
-
- int pixel_formats;
- int use_cif_resolution;
- int cif_width;
-};
-
-struct cx25821_dev {
- struct list_head devlist;
- atomic_t refcount;
- struct v4l2_device v4l2_dev;
-
- /* pci stuff */
- struct pci_dev *pci;
- unsigned char pci_rev, pci_lat;
- int pci_bus, pci_slot;
- u32 base_io_addr;
- u32 __iomem *lmmio;
- u8 __iomem *bmmio;
- int pci_irqmask;
- int hwrevision;
-
- u32 clk_freq;
-
- /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */
- struct cx25821_i2c i2c_bus[3];
-
- int nr;
- struct mutex lock;
-
- struct cx25821_channel channels[MAX_VID_CHANNEL_NUM];
-
- /* board details */
- unsigned int board;
- char name[32];
-
- /* Analog video */
- u32 resources;
- unsigned int input;
- u32 tvaudio;
- v4l2_std_id tvnorm;
- unsigned int tuner_type;
- unsigned char tuner_addr;
- unsigned int radio_type;
- unsigned char radio_addr;
- unsigned int has_radio;
- unsigned int videc_type;
- unsigned char videc_addr;
- unsigned short _max_num_decoders;
-
- /* Analog Audio Upstream */
- int _audio_is_running;
- int _audiopixel_format;
- int _is_first_audio_frame;
- int _audiofile_status;
- int _audio_lines_count;
- int _audioframe_count;
- int _audio_upstream_channel;
- int _last_index_irq; /* The last interrupt index processed. */
-
- __le32 *_risc_audio_jmp_addr;
- __le32 *_risc_virt_start_addr;
- __le32 *_risc_virt_addr;
- dma_addr_t _risc_phys_addr;
- dma_addr_t _risc_phys_start_addr;
-
- unsigned int _audiorisc_size;
- unsigned int _audiodata_buf_size;
- __le32 *_audiodata_buf_virt_addr;
- dma_addr_t _audiodata_buf_phys_addr;
- char *_audiofilename;
-
- /* V4l */
- u32 freq;
- struct video_device *vbi_dev;
- struct video_device *radio_dev;
- struct video_device *ioctl_dev;
-
- spinlock_t slock;
-
- /* Video Upstream */
- int _line_size;
- int _prog_cnt;
- int _pixel_format;
- int _is_first_frame;
- int _is_running;
- int _file_status;
- int _lines_count;
- int _frame_count;
- int _channel_upstream_select;
- unsigned int _risc_size;
-
- __le32 *_dma_virt_start_addr;
- __le32 *_dma_virt_addr;
- dma_addr_t _dma_phys_addr;
- dma_addr_t _dma_phys_start_addr;
-
- unsigned int _data_buf_size;
- __le32 *_data_buf_virt_addr;
- dma_addr_t _data_buf_phys_addr;
- char *_filename;
- char *_defaultname;
-
- int _line_size_ch2;
- int _prog_cnt_ch2;
- int _pixel_format_ch2;
- int _is_first_frame_ch2;
- int _is_running_ch2;
- int _file_status_ch2;
- int _lines_count_ch2;
- int _frame_count_ch2;
- int _channel2_upstream_select;
- unsigned int _risc_size_ch2;
-
- __le32 *_dma_virt_start_addr_ch2;
- __le32 *_dma_virt_addr_ch2;
- dma_addr_t _dma_phys_addr_ch2;
- dma_addr_t _dma_phys_start_addr_ch2;
-
- unsigned int _data_buf_size_ch2;
- __le32 *_data_buf_virt_addr_ch2;
- dma_addr_t _data_buf_phys_addr_ch2;
- char *_filename_ch2;
- char *_defaultname_ch2;
-
- /* MPEG Encoder ONLY settings */
- u32 cx23417_mailbox;
- struct cx2341x_mpeg_params mpeg_params;
- struct video_device *v4l_device;
- atomic_t v4l_reader_count;
- struct cx25821_tvnorm encodernorm;
-
- u32 upstream_riscbuf_size;
- u32 upstream_databuf_size;
- u32 upstream_riscbuf_size_ch2;
- u32 upstream_databuf_size_ch2;
- u32 audio_upstream_riscbuf_size;
- u32 audio_upstream_databuf_size;
- int _isNTSC;
- int _frame_index;
- int _audioframe_index;
- struct workqueue_struct *_irq_queues;
- struct work_struct _irq_work_entry;
- struct workqueue_struct *_irq_queues_ch2;
- struct work_struct _irq_work_entry_ch2;
- struct workqueue_struct *_irq_audio_queues;
- struct work_struct _audio_work_entry;
- char *input_filename;
- char *input_filename_ch2;
- int _frame_index_ch2;
- int _isNTSC_ch2;
- char *vid_stdname_ch2;
- int pixel_format_ch2;
- int channel_select_ch2;
- int command_ch2;
- char *input_audiofilename;
- char *vid_stdname;
- int pixel_format;
- int channel_select;
- int command;
- int channel_opened;
-};
-
-struct upstream_user_struct {
- char *input_filename;
- char *vid_stdname;
- int pixel_format;
- int channel_select;
- int command;
-};
-
-struct downstream_user_struct {
- char *vid_stdname;
- int pixel_format;
- int cif_resolution_enable;
- int cif_width;
- int decoder_select;
- int command;
- int reg_address;
- int reg_data;
-};
-
-extern struct upstream_user_struct *up_data;
-
-static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct cx25821_dev, v4l2_dev);
-}
-
-#define cx25821_call_all(dev, o, f, args...) \
- v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
-
-extern struct list_head cx25821_devlist;
-extern struct mutex cx25821_devlist_mutex;
-
-extern struct cx25821_board cx25821_boards[];
-extern struct cx25821_subid cx25821_subids[];
-
-#define SRAM_CH00 0 /* Video A */
-#define SRAM_CH01 1 /* Video B */
-#define SRAM_CH02 2 /* Video C */
-#define SRAM_CH03 3 /* Video D */
-#define SRAM_CH04 4 /* Video E */
-#define SRAM_CH05 5 /* Video F */
-#define SRAM_CH06 6 /* Video G */
-#define SRAM_CH07 7 /* Video H */
-
-#define SRAM_CH08 8 /* Audio A */
-#define SRAM_CH09 9 /* Video Upstream I */
-#define SRAM_CH10 10 /* Video Upstream J */
-#define SRAM_CH11 11 /* Audio Upstream AUD_CHANNEL_B */
-
-#define VID_UPSTREAM_SRAM_CHANNEL_I SRAM_CH09
-#define VID_UPSTREAM_SRAM_CHANNEL_J SRAM_CH10
-#define AUDIO_UPSTREAM_SRAM_CHANNEL_B SRAM_CH11
-#define VIDEO_IOCTL_CH 11
-
-struct sram_channel {
- char *name;
- u32 i;
- u32 cmds_start;
- u32 ctrl_start;
- u32 cdt;
- u32 fifo_start;
- u32 fifo_size;
- u32 ptr1_reg;
- u32 ptr2_reg;
- u32 cnt1_reg;
- u32 cnt2_reg;
- u32 int_msk;
- u32 int_stat;
- u32 int_mstat;
- u32 dma_ctl;
- u32 gpcnt_ctl;
- u32 gpcnt;
- u32 aud_length;
- u32 aud_cfg;
- u32 fld_aud_fifo_en;
- u32 fld_aud_risc_en;
-
- /* For Upstream Video */
- u32 vid_fmt_ctl;
- u32 vid_active_ctl1;
- u32 vid_active_ctl2;
- u32 vid_cdt_size;
-
- u32 vip_ctl;
- u32 pix_frmt;
- u32 jumponly;
- u32 irq_bit;
-};
-extern struct sram_channel cx25821_sram_channels[];
-
-#define STATUS_SUCCESS 0
-#define STATUS_UNSUCCESSFUL -1
-
-#define cx_read(reg) readl(dev->lmmio + ((reg)>>2))
-#define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2))
-
-#define cx_andor(reg, mask, value) \
- writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\
- ((value) & (mask)), dev->lmmio+((reg)>>2))
-
-#define cx_set(reg, bit) cx_andor((reg), (bit), (bit))
-#define cx_clear(reg, bit) cx_andor((reg), (bit), 0)
-
-#define Set_GPIO_Bit(Bit) (1 << Bit)
-#define Clear_GPIO_Bit(Bit) (~(1 << Bit))
-
-#define CX25821_ERR(fmt, args...) \
- pr_err("(%d): " fmt, dev->board, ##args)
-#define CX25821_WARN(fmt, args...) \
- pr_warn("(%d): " fmt, dev->board, ##args)
-#define CX25821_INFO(fmt, args...) \
- pr_info("(%d): " fmt, dev->board, ##args)
-
-extern int cx25821_i2c_register(struct cx25821_i2c *bus);
-extern void cx25821_card_setup(struct cx25821_dev *dev);
-extern int cx25821_ir_init(struct cx25821_dev *dev);
-extern int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value);
-extern int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value);
-extern int cx25821_i2c_unregister(struct cx25821_i2c *bus);
-extern void cx25821_gpio_init(struct cx25821_dev *dev);
-extern void cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
- int pin_number, int pin_logic_value);
-
-extern int medusa_video_init(struct cx25821_dev *dev);
-extern int medusa_set_videostandard(struct cx25821_dev *dev);
-extern void medusa_set_resolution(struct cx25821_dev *dev, int width,
- int decoder_select);
-extern int medusa_set_brightness(struct cx25821_dev *dev, int brightness,
- int decoder);
-extern int medusa_set_contrast(struct cx25821_dev *dev, int contrast,
- int decoder);
-extern int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder);
-extern int medusa_set_saturation(struct cx25821_dev *dev, int saturation,
- int decoder);
-
-extern int cx25821_sram_channel_setup(struct cx25821_dev *dev,
- struct sram_channel *ch, unsigned int bpl,
- u32 risc);
-
-extern int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
- struct scatterlist *sglist,
- unsigned int top_offset,
- unsigned int bottom_offset,
- unsigned int bpl,
- unsigned int padding, unsigned int lines);
-extern int cx25821_risc_databuffer_audio(struct pci_dev *pci,
- struct btcx_riscmem *risc,
- struct scatterlist *sglist,
- unsigned int bpl,
- unsigned int lines, unsigned int lpi);
-extern void cx25821_free_buffer(struct videobuf_queue *q,
- struct cx25821_buffer *buf);
-extern int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
- u32 reg, u32 mask, u32 value);
-extern void cx25821_sram_channel_dump(struct cx25821_dev *dev,
- struct sram_channel *ch);
-extern void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
- struct sram_channel *ch);
-
-extern struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci);
-extern void cx25821_print_irqbits(char *name, char *tag, char **strings,
- int len, u32 bits, u32 mask);
-extern void cx25821_dev_unregister(struct cx25821_dev *dev);
-extern int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
- struct sram_channel *ch,
- unsigned int bpl, u32 risc);
-
-extern int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev,
- int channel_select, int pixel_format);
-extern int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev,
- int channel_select, int pixel_format);
-extern int cx25821_audio_upstream_init(struct cx25821_dev *dev,
- int channel_select);
-extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev);
-extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev);
-extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev);
-extern void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev,
- struct upstream_user_struct
- *up_data);
-extern void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev,
- struct upstream_user_struct
- *up_data);
-extern void cx25821_start_upstream_audio(struct cx25821_dev *dev,
- struct upstream_user_struct *up_data);
-extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev);
-extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev);
-extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev);
-extern int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
- struct sram_channel *ch,
- unsigned int bpl, u32 risc);
-extern void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel,
- u32 format);
-extern void cx25821_videoioctl_unregister(struct cx25821_dev *dev);
-extern struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
- struct pci_dev *pci,
- struct video_device *template,
- char *type);
-#endif
diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/video/cx25840/Kconfig
deleted file mode 100644
index 451133ad41f..00000000000
--- a/drivers/media/video/cx25840/Kconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-config VIDEO_CX25840
- tristate "Conexant CX2584x audio/video decoders"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Conexant CX2584x audio/video decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called cx25840
diff --git a/drivers/media/video/cx25840/Makefile b/drivers/media/video/cx25840/Makefile
deleted file mode 100644
index dc40dde2e0c..00000000000
--- a/drivers/media/video/cx25840/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-cx25840-objs := cx25840-core.o cx25840-audio.o cx25840-firmware.o \
- cx25840-vbi.o cx25840-ir.o
-
-obj-$(CONFIG_VIDEO_CX25840) += cx25840.o
-
-ccflags-y += -Idrivers/media/video
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
deleted file mode 100644
index 34b96c7cfd6..00000000000
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/* cx25840 audio functions
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-
-#include <linux/videodev2.h>
-#include <linux/i2c.h>
-#include <media/v4l2-common.h>
-#include <media/cx25840.h>
-
-#include "cx25840-core.h"
-
-/*
- * Note: The PLL and SRC parameters are based on a reference frequency that
- * would ideally be:
- *
- * NTSC Color subcarrier freq * 8 = 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
- *
- * However, it's not the exact reference frequency that matters, only that the
- * firmware and modules that comprise the driver for a particular board all
- * use the same value (close to the ideal value).
- *
- * Comments below will note which reference frequency is assumed for various
- * parameters. They will usually be one of
- *
- * ref_freq = 28.636360 MHz
- * or
- * ref_freq = 28.636363 MHz
- */
-
-static int cx25840_set_audclk_freq(struct i2c_client *client, u32 freq)
-{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
-
- if (state->aud_input != CX25840_AUDIO_SERIAL) {
- switch (freq) {
- case 32000:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x06, AUX PLL Post Divider = 0x10
- */
- cx25840_write4(client, 0x108, 0x1006040f);
-
- /*
- * VID_PLL Fraction (register 0x10c) = 0x2be2fe
- * 28636360 * 0xf.15f17f0/4 = 108 MHz
- * 432 MHz pre-postdivide
- */
-
- /*
- * AUX_PLL Fraction = 0x1bb39ee
- * 28636363 * 0x6.dd9cf70/0x10 = 32000 * 384
- * 196.6 MHz pre-postdivide
- * FIXME < 200 MHz is out of specified valid range
- * FIXME 28636363 ref_freq doesn't match VID PLL ref
- */
- cx25840_write4(client, 0x110, 0x01bb39ee);
-
- /*
- * SA_MCLK_SEL = 1
- * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
- */
- cx25840_write(client, 0x127, 0x50);
-
- if (is_cx2583x(state))
- break;
-
- /* src3/4/6_ctl */
- /* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */
- cx25840_write4(client, 0x900, 0x0801f77f);
- cx25840_write4(client, 0x904, 0x0801f77f);
- cx25840_write4(client, 0x90c, 0x0801f77f);
- break;
-
- case 44100:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x10
- */
- cx25840_write4(client, 0x108, 0x1009040f);
-
- /*
- * VID_PLL Fraction (register 0x10c) = 0x2be2fe
- * 28636360 * 0xf.15f17f0/4 = 108 MHz
- * 432 MHz pre-postdivide
- */
-
- /*
- * AUX_PLL Fraction = 0x0ec6bd6
- * 28636363 * 0x9.7635eb0/0x10 = 44100 * 384
- * 271 MHz pre-postdivide
- * FIXME 28636363 ref_freq doesn't match VID PLL ref
- */
- cx25840_write4(client, 0x110, 0x00ec6bd6);
-
- /*
- * SA_MCLK_SEL = 1
- * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
- */
- cx25840_write(client, 0x127, 0x50);
-
- if (is_cx2583x(state))
- break;
-
- /* src3/4/6_ctl */
- /* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */
- cx25840_write4(client, 0x900, 0x08016d59);
- cx25840_write4(client, 0x904, 0x08016d59);
- cx25840_write4(client, 0x90c, 0x08016d59);
- break;
-
- case 48000:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x10
- */
- cx25840_write4(client, 0x108, 0x100a040f);
-
- /*
- * VID_PLL Fraction (register 0x10c) = 0x2be2fe
- * 28636360 * 0xf.15f17f0/4 = 108 MHz
- * 432 MHz pre-postdivide
- */
-
- /*
- * AUX_PLL Fraction = 0x098d6e5
- * 28636363 * 0xa.4c6b728/0x10 = 48000 * 384
- * 295 MHz pre-postdivide
- * FIXME 28636363 ref_freq doesn't match VID PLL ref
- */
- cx25840_write4(client, 0x110, 0x0098d6e5);
-
- /*
- * SA_MCLK_SEL = 1
- * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
- */
- cx25840_write(client, 0x127, 0x50);
-
- if (is_cx2583x(state))
- break;
-
- /* src3/4/6_ctl */
- /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
- cx25840_write4(client, 0x900, 0x08014faa);
- cx25840_write4(client, 0x904, 0x08014faa);
- cx25840_write4(client, 0x90c, 0x08014faa);
- break;
- }
- } else {
- switch (freq) {
- case 32000:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x08, AUX PLL Post Divider = 0x1e
- */
- cx25840_write4(client, 0x108, 0x1e08040f);
-
- /*
- * VID_PLL Fraction (register 0x10c) = 0x2be2fe
- * 28636360 * 0xf.15f17f0/4 = 108 MHz
- * 432 MHz pre-postdivide
- */
-
- /*
- * AUX_PLL Fraction = 0x12a0869
- * 28636363 * 0x8.9504348/0x1e = 32000 * 256
- * 246 MHz pre-postdivide
- * FIXME 28636363 ref_freq doesn't match VID PLL ref
- */
- cx25840_write4(client, 0x110, 0x012a0869);
-
- /*
- * SA_MCLK_SEL = 1
- * SA_MCLK_DIV = 0x14 = 256/384 * AUX_PLL post dvivider
- */
- cx25840_write(client, 0x127, 0x54);
-
- if (is_cx2583x(state))
- break;
-
- /* src1_ctl */
- /* 0x1.0000 = 32000/32000 */
- cx25840_write4(client, 0x8f8, 0x08010000);
-
- /* src3/4/6_ctl */
- /* 0x2.0000 = 2 * (32000/32000) */
- cx25840_write4(client, 0x900, 0x08020000);
- cx25840_write4(client, 0x904, 0x08020000);
- cx25840_write4(client, 0x90c, 0x08020000);
- break;
-
- case 44100:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x18
- */
- cx25840_write4(client, 0x108, 0x1809040f);
-
- /*
- * VID_PLL Fraction (register 0x10c) = 0x2be2fe
- * 28636360 * 0xf.15f17f0/4 = 108 MHz
- * 432 MHz pre-postdivide
- */
-
- /*
- * AUX_PLL Fraction = 0x0ec6bd6
- * 28636363 * 0x9.7635eb0/0x18 = 44100 * 256
- * 271 MHz pre-postdivide
- * FIXME 28636363 ref_freq doesn't match VID PLL ref
- */
- cx25840_write4(client, 0x110, 0x00ec6bd6);
-
- /*
- * SA_MCLK_SEL = 1
- * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider
- */
- cx25840_write(client, 0x127, 0x50);
-
- if (is_cx2583x(state))
- break;
-
- /* src1_ctl */
- /* 0x1.60cd = 44100/32000 */
- cx25840_write4(client, 0x8f8, 0x080160cd);
-
- /* src3/4/6_ctl */
- /* 0x1.7385 = 2 * (32000/44100) */
- cx25840_write4(client, 0x900, 0x08017385);
- cx25840_write4(client, 0x904, 0x08017385);
- cx25840_write4(client, 0x90c, 0x08017385);
- break;
-
- case 48000:
- /*
- * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
- * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x18
- */
- cx25840_write4(client, 0x108, 0x180a040f);
-
- /*
- * VID_PLL Fraction (register 0x10c) = 0x2be2fe
- * 28636360 * 0xf.15f17f0/4 = 108 MHz
- * 432 MHz pre-postdivide
- */
-
- /*
- * AUX_PLL Fraction = 0x098d6e5
- * 28636363 * 0xa.4c6b728/0x18 = 48000 * 256
- * 295 MHz pre-postdivide
- * FIXME 28636363 ref_freq doesn't match VID PLL ref
- */
- cx25840_write4(client, 0x110, 0x0098d6e5);
-
- /*
- * SA_MCLK_SEL = 1
- * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider
- */
- cx25840_write(client, 0x127, 0x50);
-
- if (is_cx2583x(state))
- break;
-
- /* src1_ctl */
- /* 0x1.8000 = 48000/32000 */
- cx25840_write4(client, 0x8f8, 0x08018000);
-
- /* src3/4/6_ctl */
- /* 0x1.5555 = 2 * (32000/48000) */
- cx25840_write4(client, 0x900, 0x08015555);
- cx25840_write4(client, 0x904, 0x08015555);
- cx25840_write4(client, 0x90c, 0x08015555);
- break;
- }
- }
-
- state->audclk_freq = freq;
-
- return 0;
-}
-
-static inline int cx25836_set_audclk_freq(struct i2c_client *client, u32 freq)
-{
- return cx25840_set_audclk_freq(client, freq);
-}
-
-static int cx23885_set_audclk_freq(struct i2c_client *client, u32 freq)
-{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
-
- if (state->aud_input != CX25840_AUDIO_SERIAL) {
- switch (freq) {
- case 32000:
- case 44100:
- case 48000:
- /* We don't have register values
- * so avoid destroying registers. */
- /* FIXME return -EINVAL; */
- break;
- }
- } else {
- switch (freq) {
- case 32000:
- case 44100:
- /* We don't have register values
- * so avoid destroying registers. */
- /* FIXME return -EINVAL; */
- break;
-
- case 48000:
- /* src1_ctl */
- /* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */
- cx25840_write4(client, 0x8f8, 0x0801867c);
-
- /* src3/4/6_ctl */
- /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
- cx25840_write4(client, 0x900, 0x08014faa);
- cx25840_write4(client, 0x904, 0x08014faa);
- cx25840_write4(client, 0x90c, 0x08014faa);
- break;
- }
- }
-
- state->audclk_freq = freq;
-
- return 0;
-}
-
-static int cx231xx_set_audclk_freq(struct i2c_client *client, u32 freq)
-{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
-
- if (state->aud_input != CX25840_AUDIO_SERIAL) {
- switch (freq) {
- case 32000:
- /* src3/4/6_ctl */
- /* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */
- cx25840_write4(client, 0x900, 0x0801f77f);
- cx25840_write4(client, 0x904, 0x0801f77f);
- cx25840_write4(client, 0x90c, 0x0801f77f);
- break;
-
- case 44100:
- /* src3/4/6_ctl */
- /* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */
- cx25840_write4(client, 0x900, 0x08016d59);
- cx25840_write4(client, 0x904, 0x08016d59);
- cx25840_write4(client, 0x90c, 0x08016d59);
- break;
-
- case 48000:
- /* src3/4/6_ctl */
- /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
- cx25840_write4(client, 0x900, 0x08014faa);
- cx25840_write4(client, 0x904, 0x08014faa);
- cx25840_write4(client, 0x90c, 0x08014faa);
- break;
- }
- } else {
- switch (freq) {
- /* FIXME These cases make different assumptions about audclk */
- case 32000:
- /* src1_ctl */
- /* 0x1.0000 = 32000/32000 */
- cx25840_write4(client, 0x8f8, 0x08010000);
-
- /* src3/4/6_ctl */
- /* 0x2.0000 = 2 * (32000/32000) */
- cx25840_write4(client, 0x900, 0x08020000);
- cx25840_write4(client, 0x904, 0x08020000);
- cx25840_write4(client, 0x90c, 0x08020000);
- break;
-
- case 44100:
- /* src1_ctl */
- /* 0x1.60cd = 44100/32000 */
- cx25840_write4(client, 0x8f8, 0x080160cd);
-
- /* src3/4/6_ctl */
- /* 0x1.7385 = 2 * (32000/44100) */
- cx25840_write4(client, 0x900, 0x08017385);
- cx25840_write4(client, 0x904, 0x08017385);
- cx25840_write4(client, 0x90c, 0x08017385);
- break;
-
- case 48000:
- /* src1_ctl */
- /* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */
- cx25840_write4(client, 0x8f8, 0x0801867c);
-
- /* src3/4/6_ctl */
- /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
- cx25840_write4(client, 0x900, 0x08014faa);
- cx25840_write4(client, 0x904, 0x08014faa);
- cx25840_write4(client, 0x90c, 0x08014faa);
- break;
- }
- }
-
- state->audclk_freq = freq;
-
- return 0;
-}
-
-static int set_audclk_freq(struct i2c_client *client, u32 freq)
-{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
-
- if (freq != 32000 && freq != 44100 && freq != 48000)
- return -EINVAL;
-
- if (is_cx231xx(state))
- return cx231xx_set_audclk_freq(client, freq);
-
- if (is_cx2388x(state))
- return cx23885_set_audclk_freq(client, freq);
-
- if (is_cx2583x(state))
- return cx25836_set_audclk_freq(client, freq);
-
- return cx25840_set_audclk_freq(client, freq);
-}
-
-void cx25840_audio_set_path(struct i2c_client *client)
-{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
-
- if (!is_cx2583x(state)) {
- /* assert soft reset */
- cx25840_and_or(client, 0x810, ~0x1, 0x01);
-
- /* stop microcontroller */
- cx25840_and_or(client, 0x803, ~0x10, 0);
-
- /* Mute everything to prevent the PFFT! */
- cx25840_write(client, 0x8d3, 0x1f);
-
- if (state->aud_input == CX25840_AUDIO_SERIAL) {
- /* Set Path1 to Serial Audio Input */
- cx25840_write4(client, 0x8d0, 0x01011012);
-
- /* The microcontroller should not be started for the
- * non-tuner inputs: autodetection is specific for
- * TV audio. */
- } else {
- /* Set Path1 to Analog Demod Main Channel */
- cx25840_write4(client, 0x8d0, 0x1f063870);
- }
- }
-
- set_audclk_freq(client, state->audclk_freq);
-
- if (!is_cx2583x(state)) {
- if (state->aud_input != CX25840_AUDIO_SERIAL) {
- /* When the microcontroller detects the
- * audio format, it will unmute the lines */
- cx25840_and_or(client, 0x803, ~0x10, 0x10);
- }
-
- /* deassert soft reset */
- cx25840_and_or(client, 0x810, ~0x1, 0x00);
-
- /* Ensure the controller is running when we exit */
- if (is_cx2388x(state) || is_cx231xx(state))
- cx25840_and_or(client, 0x803, ~0x10, 0x10);
- }
-}
-
-static void set_volume(struct i2c_client *client, int volume)
-{
- int vol;
-
- /* Convert the volume to msp3400 values (0-127) */
- vol = volume >> 9;
-
- /* now scale it up to cx25840 values
- * -114dB to -96dB maps to 0
- * this should be 19, but in my testing that was 4dB too loud */
- if (vol <= 23) {
- vol = 0;
- } else {
- vol -= 23;
- }
-
- /* PATH1_VOLUME */
- cx25840_write(client, 0x8d4, 228 - (vol * 2));
-}
-
-static void set_balance(struct i2c_client *client, int balance)
-{
- int bal = balance >> 8;
- if (bal > 0x80) {
- /* PATH1_BAL_LEFT */
- cx25840_and_or(client, 0x8d5, 0x7f, 0x80);
- /* PATH1_BAL_LEVEL */
- cx25840_and_or(client, 0x8d5, ~0x7f, bal & 0x7f);
- } else {
- /* PATH1_BAL_LEFT */
- cx25840_and_or(client, 0x8d5, 0x7f, 0x00);
- /* PATH1_BAL_LEVEL */
- cx25840_and_or(client, 0x8d5, ~0x7f, 0x80 - bal);
- }
-}
-
-int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct cx25840_state *state = to_state(sd);
- int retval;
-
- if (!is_cx2583x(state))
- cx25840_and_or(client, 0x810, ~0x1, 1);
- if (state->aud_input != CX25840_AUDIO_SERIAL) {
- cx25840_and_or(client, 0x803, ~0x10, 0);
- cx25840_write(client, 0x8d3, 0x1f);
- }
- retval = set_audclk_freq(client, freq);
- if (state->aud_input != CX25840_AUDIO_SERIAL)
- cx25840_and_or(client, 0x803, ~0x10, 0x10);
- if (!is_cx2583x(state))
- cx25840_and_or(client, 0x810, ~0x1, 0);
- return retval;
-}
-
-static int cx25840_audio_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- if (state->mute->val)
- set_volume(client, 0);
- else
- set_volume(client, state->volume->val);
- break;
- case V4L2_CID_AUDIO_BASS:
- /* PATH1_EQ_BASS_VOL */
- cx25840_and_or(client, 0x8d9, ~0x3f,
- 48 - (ctrl->val * 48 / 0xffff));
- break;
- case V4L2_CID_AUDIO_TREBLE:
- /* PATH1_EQ_TREBLE_VOL */
- cx25840_and_or(client, 0x8db, ~0x3f,
- 48 - (ctrl->val * 48 / 0xffff));
- break;
- case V4L2_CID_AUDIO_BALANCE:
- set_balance(client, ctrl->val);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-const struct v4l2_ctrl_ops cx25840_audio_ctrl_ops = {
- .s_ctrl = cx25840_audio_s_ctrl,
-};
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
deleted file mode 100644
index d8eac3e30a7..00000000000
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ /dev/null
@@ -1,5340 +0,0 @@
-/* cx25840 - Conexant CX25840 audio/video decoder driver
- *
- * Copyright (C) 2004 Ulf Eklund
- *
- * Based on the saa7115 driver and on the first version of Chris Kennedy's
- * cx25840 driver.
- *
- * Changes by Tyler Trafford <tatrafford@comcast.net>
- * - cleanup/rewrite for V4L2 API (2005)
- *
- * VBI support by Hans Verkuil <hverkuil@xs4all.nl>.
- *
- * NTSC sliced VBI support by Christopher Neufeld <television@cneufeld.ca>
- * with additional fixes by Hans Verkuil <hverkuil@xs4all.nl>.
- *
- * CX23885 support by Steven Toth <stoth@linuxtv.org>.
- *
- * CX2388[578] IRQ handling, IO Pin mux configuration and other small fixes are
- * Copyright (C) 2010 Andy Walls <awalls@md.metrocast.net>
- *
- * CX23888 DIF support for the HVR1850
- * Copyright (C) 2011 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/math64.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/cx25840.h>
-
-#include "cx25840-core.h"
-
-MODULE_DESCRIPTION("Conexant CX25840 audio/video decoder driver");
-MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford");
-MODULE_LICENSE("GPL");
-
-#define CX25840_VID_INT_STAT_REG 0x410
-#define CX25840_VID_INT_STAT_BITS 0x0000ffff
-#define CX25840_VID_INT_MASK_BITS 0xffff0000
-#define CX25840_VID_INT_MASK_SHFT 16
-#define CX25840_VID_INT_MASK_REG 0x412
-
-#define CX23885_AUD_MC_INT_MASK_REG 0x80c
-#define CX23885_AUD_MC_INT_STAT_BITS 0xffff0000
-#define CX23885_AUD_MC_INT_CTRL_BITS 0x0000ffff
-#define CX23885_AUD_MC_INT_STAT_SHFT 16
-
-#define CX25840_AUD_INT_CTRL_REG 0x812
-#define CX25840_AUD_INT_STAT_REG 0x813
-
-#define CX23885_PIN_CTRL_IRQ_REG 0x123
-#define CX23885_PIN_CTRL_IRQ_IR_STAT 0x40
-#define CX23885_PIN_CTRL_IRQ_AUD_STAT 0x20
-#define CX23885_PIN_CTRL_IRQ_VID_STAT 0x10
-
-#define CX25840_IR_STATS_REG 0x210
-#define CX25840_IR_IRQEN_REG 0x214
-
-static int cx25840_debug;
-
-module_param_named(debug,cx25840_debug, int, 0644);
-
-MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]");
-
-
-/* ----------------------------------------------------------------------- */
-static void cx23888_std_setup(struct i2c_client *client);
-
-int cx25840_write(struct i2c_client *client, u16 addr, u8 value)
-{
- u8 buffer[3];
- buffer[0] = addr >> 8;
- buffer[1] = addr & 0xff;
- buffer[2] = value;
- return i2c_master_send(client, buffer, 3);
-}
-
-int cx25840_write4(struct i2c_client *client, u16 addr, u32 value)
-{
- u8 buffer[6];
- buffer[0] = addr >> 8;
- buffer[1] = addr & 0xff;
- buffer[2] = value & 0xff;
- buffer[3] = (value >> 8) & 0xff;
- buffer[4] = (value >> 16) & 0xff;
- buffer[5] = value >> 24;
- return i2c_master_send(client, buffer, 6);
-}
-
-u8 cx25840_read(struct i2c_client * client, u16 addr)
-{
- struct i2c_msg msgs[2];
- u8 tx_buf[2], rx_buf[1];
-
- /* Write register address */
- tx_buf[0] = addr >> 8;
- tx_buf[1] = addr & 0xff;
- msgs[0].addr = client->addr;
- msgs[0].flags = 0;
- msgs[0].len = 2;
- msgs[0].buf = (char *) tx_buf;
-
- /* Read data from register */
- msgs[1].addr = client->addr;
- msgs[1].flags = I2C_M_RD;
- msgs[1].len = 1;
- msgs[1].buf = (char *) rx_buf;
-
- if (i2c_transfer(client->adapter, msgs, 2) < 2)
- return 0;
-
- return rx_buf[0];
-}
-
-u32 cx25840_read4(struct i2c_client * client, u16 addr)
-{
- struct i2c_msg msgs[2];
- u8 tx_buf[2], rx_buf[4];
-
- /* Write register address */
- tx_buf[0] = addr >> 8;
- tx_buf[1] = addr & 0xff;
- msgs[0].addr = client->addr;
- msgs[0].flags = 0;
- msgs[0].len = 2;
- msgs[0].buf = (char *) tx_buf;
-
- /* Read data from registers */
- msgs[1].addr = client->addr;
- msgs[1].flags = I2C_M_RD;
- msgs[1].len = 4;
- msgs[1].buf = (char *) rx_buf;
-
- if (i2c_transfer(client->adapter, msgs, 2) < 2)
- return 0;
-
- return (rx_buf[3] << 24) | (rx_buf[2] << 16) | (rx_buf[1] << 8) |
- rx_buf[0];
-}
-
-int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned and_mask,
- u8 or_value)
-{
- return cx25840_write(client, addr,
- (cx25840_read(client, addr) & and_mask) |
- or_value);
-}
-
-int cx25840_and_or4(struct i2c_client *client, u16 addr, u32 and_mask,
- u32 or_value)
-{
- return cx25840_write4(client, addr,
- (cx25840_read4(client, addr) & and_mask) |
- or_value);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
- enum cx25840_audio_input aud_input);
-
-/* ----------------------------------------------------------------------- */
-
-static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
- struct v4l2_subdev_io_pin_config *p)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int i;
- u32 pin_ctrl;
- u8 gpio_oe, gpio_data, strength;
-
- pin_ctrl = cx25840_read4(client, 0x120);
- gpio_oe = cx25840_read(client, 0x160);
- gpio_data = cx25840_read(client, 0x164);
-
- for (i = 0; i < n; i++) {
- strength = p[i].strength;
- if (strength > CX25840_PIN_DRIVE_FAST)
- strength = CX25840_PIN_DRIVE_FAST;
-
- switch (p[i].pin) {
- case CX23885_PIN_IRQ_N_GPIO16:
- if (p[i].function != CX23885_PAD_IRQ_N) {
- /* GPIO16 */
- pin_ctrl &= ~(0x1 << 25);
- } else {
- /* IRQ_N */
- if (p[i].flags &
- (V4L2_SUBDEV_IO_PIN_DISABLE |
- V4L2_SUBDEV_IO_PIN_INPUT)) {
- pin_ctrl &= ~(0x1 << 25);
- } else {
- pin_ctrl |= (0x1 << 25);
- }
- if (p[i].flags &
- V4L2_SUBDEV_IO_PIN_ACTIVE_LOW) {
- pin_ctrl &= ~(0x1 << 24);
- } else {
- pin_ctrl |= (0x1 << 24);
- }
- }
- break;
- case CX23885_PIN_IR_RX_GPIO19:
- if (p[i].function != CX23885_PAD_GPIO19) {
- /* IR_RX */
- gpio_oe |= (0x1 << 0);
- pin_ctrl &= ~(0x3 << 18);
- pin_ctrl |= (strength << 18);
- } else {
- /* GPIO19 */
- gpio_oe &= ~(0x1 << 0);
- if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
- gpio_data &= ~(0x1 << 0);
- gpio_data |= ((p[i].value & 0x1) << 0);
- }
- pin_ctrl &= ~(0x3 << 12);
- pin_ctrl |= (strength << 12);
- }
- break;
- case CX23885_PIN_IR_TX_GPIO20:
- if (p[i].function != CX23885_PAD_GPIO20) {
- /* IR_TX */
- gpio_oe |= (0x1 << 1);
- if (p[i].flags & V4L2_SUBDEV_IO_PIN_DISABLE)
- pin_ctrl &= ~(0x1 << 10);
- else
- pin_ctrl |= (0x1 << 10);
- pin_ctrl &= ~(0x3 << 18);
- pin_ctrl |= (strength << 18);
- } else {
- /* GPIO20 */
- gpio_oe &= ~(0x1 << 1);
- if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
- gpio_data &= ~(0x1 << 1);
- gpio_data |= ((p[i].value & 0x1) << 1);
- }
- pin_ctrl &= ~(0x3 << 12);
- pin_ctrl |= (strength << 12);
- }
- break;
- case CX23885_PIN_I2S_SDAT_GPIO21:
- if (p[i].function != CX23885_PAD_GPIO21) {
- /* I2S_SDAT */
- /* TODO: Input or Output config */
- gpio_oe |= (0x1 << 2);
- pin_ctrl &= ~(0x3 << 22);
- pin_ctrl |= (strength << 22);
- } else {
- /* GPIO21 */
- gpio_oe &= ~(0x1 << 2);
- if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
- gpio_data &= ~(0x1 << 2);
- gpio_data |= ((p[i].value & 0x1) << 2);
- }
- pin_ctrl &= ~(0x3 << 12);
- pin_ctrl |= (strength << 12);
- }
- break;
- case CX23885_PIN_I2S_WCLK_GPIO22:
- if (p[i].function != CX23885_PAD_GPIO22) {
- /* I2S_WCLK */
- /* TODO: Input or Output config */
- gpio_oe |= (0x1 << 3);
- pin_ctrl &= ~(0x3 << 22);
- pin_ctrl |= (strength << 22);
- } else {
- /* GPIO22 */
- gpio_oe &= ~(0x1 << 3);
- if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
- gpio_data &= ~(0x1 << 3);
- gpio_data |= ((p[i].value & 0x1) << 3);
- }
- pin_ctrl &= ~(0x3 << 12);
- pin_ctrl |= (strength << 12);
- }
- break;
- case CX23885_PIN_I2S_BCLK_GPIO23:
- if (p[i].function != CX23885_PAD_GPIO23) {
- /* I2S_BCLK */
- /* TODO: Input or Output config */
- gpio_oe |= (0x1 << 4);
- pin_ctrl &= ~(0x3 << 22);
- pin_ctrl |= (strength << 22);
- } else {
- /* GPIO23 */
- gpio_oe &= ~(0x1 << 4);
- if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
- gpio_data &= ~(0x1 << 4);
- gpio_data |= ((p[i].value & 0x1) << 4);
- }
- pin_ctrl &= ~(0x3 << 12);
- pin_ctrl |= (strength << 12);
- }
- break;
- }
- }
-
- cx25840_write(client, 0x164, gpio_data);
- cx25840_write(client, 0x160, gpio_oe);
- cx25840_write4(client, 0x120, pin_ctrl);
- return 0;
-}
-
-static int common_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
- struct v4l2_subdev_io_pin_config *pincfg)
-{
- struct cx25840_state *state = to_state(sd);
-
- if (is_cx2388x(state))
- return cx23885_s_io_pin_config(sd, n, pincfg);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static void init_dll1(struct i2c_client *client)
-{
- /* This is the Hauppauge sequence used to
- * initialize the Delay Lock Loop 1 (ADC DLL). */
- cx25840_write(client, 0x159, 0x23);
- cx25840_write(client, 0x15a, 0x87);
- cx25840_write(client, 0x15b, 0x06);
- udelay(10);
- cx25840_write(client, 0x159, 0xe1);
- udelay(10);
- cx25840_write(client, 0x15a, 0x86);
- cx25840_write(client, 0x159, 0xe0);
- cx25840_write(client, 0x159, 0xe1);
- cx25840_write(client, 0x15b, 0x10);
-}
-
-static void init_dll2(struct i2c_client *client)
-{
- /* This is the Hauppauge sequence used to
- * initialize the Delay Lock Loop 2 (ADC DLL). */
- cx25840_write(client, 0x15d, 0xe3);
- cx25840_write(client, 0x15e, 0x86);
- cx25840_write(client, 0x15f, 0x06);
- udelay(10);
- cx25840_write(client, 0x15d, 0xe1);
- cx25840_write(client, 0x15d, 0xe0);
- cx25840_write(client, 0x15d, 0xe1);
-}
-
-static void cx25836_initialize(struct i2c_client *client)
-{
- /* reset configuration is described on page 3-77 of the CX25836 datasheet */
- /* 2. */
- cx25840_and_or(client, 0x000, ~0x01, 0x01);
- cx25840_and_or(client, 0x000, ~0x01, 0x00);
- /* 3a. */
- cx25840_and_or(client, 0x15a, ~0x70, 0x00);
- /* 3b. */
- cx25840_and_or(client, 0x15b, ~0x1e, 0x06);
- /* 3c. */
- cx25840_and_or(client, 0x159, ~0x02, 0x02);
- /* 3d. */
- udelay(10);
- /* 3e. */
- cx25840_and_or(client, 0x159, ~0x02, 0x00);
- /* 3f. */
- cx25840_and_or(client, 0x159, ~0xc0, 0xc0);
- /* 3g. */
- cx25840_and_or(client, 0x159, ~0x01, 0x00);
- cx25840_and_or(client, 0x159, ~0x01, 0x01);
- /* 3h. */
- cx25840_and_or(client, 0x15b, ~0x1e, 0x10);
-}
-
-static void cx25840_work_handler(struct work_struct *work)
-{
- struct cx25840_state *state = container_of(work, struct cx25840_state, fw_work);
- cx25840_loadfw(state->c);
- wake_up(&state->fw_wait);
-}
-
-static void cx25840_initialize(struct i2c_client *client)
-{
- DEFINE_WAIT(wait);
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- struct workqueue_struct *q;
-
- /* datasheet startup in numbered steps, refer to page 3-77 */
- /* 2. */
- cx25840_and_or(client, 0x803, ~0x10, 0x00);
- /* The default of this register should be 4, but I get 0 instead.
- * Set this register to 4 manually. */
- cx25840_write(client, 0x000, 0x04);
- /* 3. */
- init_dll1(client);
- init_dll2(client);
- cx25840_write(client, 0x136, 0x0a);
- /* 4. */
- cx25840_write(client, 0x13c, 0x01);
- cx25840_write(client, 0x13c, 0x00);
- /* 5. */
- /* Do the firmware load in a work handler to prevent.
- Otherwise the kernel is blocked waiting for the
- bit-banging i2c interface to finish uploading the
- firmware. */
- INIT_WORK(&state->fw_work, cx25840_work_handler);
- init_waitqueue_head(&state->fw_wait);
- q = create_singlethread_workqueue("cx25840_fw");
- prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
- queue_work(q, &state->fw_work);
- schedule();
- finish_wait(&state->fw_wait, &wait);
- destroy_workqueue(q);
-
- /* 6. */
- cx25840_write(client, 0x115, 0x8c);
- cx25840_write(client, 0x116, 0x07);
- cx25840_write(client, 0x118, 0x02);
- /* 7. */
- cx25840_write(client, 0x4a5, 0x80);
- cx25840_write(client, 0x4a5, 0x00);
- cx25840_write(client, 0x402, 0x00);
- /* 8. */
- cx25840_and_or(client, 0x401, ~0x18, 0);
- cx25840_and_or(client, 0x4a2, ~0x10, 0x10);
- /* steps 8c and 8d are done in change_input() */
- /* 10. */
- cx25840_write(client, 0x8d3, 0x1f);
- cx25840_write(client, 0x8e3, 0x03);
-
- cx25840_std_setup(client);
-
- /* trial and error says these are needed to get audio */
- cx25840_write(client, 0x914, 0xa0);
- cx25840_write(client, 0x918, 0xa0);
- cx25840_write(client, 0x919, 0x01);
-
- /* stereo preferred */
- cx25840_write(client, 0x809, 0x04);
- /* AC97 shift */
- cx25840_write(client, 0x8cf, 0x0f);
-
- /* (re)set input */
- set_input(client, state->vid_input, state->aud_input);
-
- /* start microcontroller */
- cx25840_and_or(client, 0x803, ~0x10, 0x10);
-}
-
-static void cx23885_initialize(struct i2c_client *client)
-{
- DEFINE_WAIT(wait);
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- struct workqueue_struct *q;
-
- /*
- * Come out of digital power down
- * The CX23888, at least, needs this, otherwise registers aside from
- * 0x0-0x2 can't be read or written.
- */
- cx25840_write(client, 0x000, 0);
-
- /* Internal Reset */
- cx25840_and_or(client, 0x102, ~0x01, 0x01);
- cx25840_and_or(client, 0x102, ~0x01, 0x00);
-
- /* Stop microcontroller */
- cx25840_and_or(client, 0x803, ~0x10, 0x00);
-
- /* DIF in reset? */
- cx25840_write(client, 0x398, 0);
-
- /*
- * Trust the default xtal, no division
- * '885: 28.636363... MHz
- * '887: 25.000000 MHz
- * '888: 50.000000 MHz
- */
- cx25840_write(client, 0x2, 0x76);
-
- /* Power up all the PLL's and DLL */
- cx25840_write(client, 0x1, 0x40);
-
- /* Sys PLL */
- switch (state->id) {
- case V4L2_IDENT_CX23888_AV:
- /*
- * 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz
- * 572.73 MHz before post divide
- */
- /* HVR1850 or 50MHz xtal */
- cx25840_write(client, 0x2, 0x71);
- cx25840_write4(client, 0x11c, 0x01d1744c);
- cx25840_write4(client, 0x118, 0x00000416);
- cx25840_write4(client, 0x404, 0x0010253e);
- cx25840_write4(client, 0x42c, 0x42600000);
- cx25840_write4(client, 0x44c, 0x161f1000);
- break;
- case V4L2_IDENT_CX23887_AV:
- /*
- * 25.0 MHz * (0x16 + 0x1d1744c/0x2000000)/4 = 5 * 28.636363 MHz
- * 572.73 MHz before post divide
- */
- cx25840_write4(client, 0x11c, 0x01d1744c);
- cx25840_write4(client, 0x118, 0x00000416);
- break;
- case V4L2_IDENT_CX23885_AV:
- default:
- /*
- * 28.636363 MHz * (0x14 + 0x0/0x2000000)/4 = 5 * 28.636363 MHz
- * 572.73 MHz before post divide
- */
- cx25840_write4(client, 0x11c, 0x00000000);
- cx25840_write4(client, 0x118, 0x00000414);
- break;
- }
-
- /* Disable DIF bypass */
- cx25840_write4(client, 0x33c, 0x00000001);
-
- /* DIF Src phase inc */
- cx25840_write4(client, 0x340, 0x0df7df83);
-
- /*
- * Vid PLL
- * Setup for a BT.656 pixel clock of 13.5 Mpixels/second
- *
- * 28.636363 MHz * (0xf + 0x02be2c9/0x2000000)/4 = 8 * 13.5 MHz
- * 432.0 MHz before post divide
- */
-
- /* HVR1850 */
- switch (state->id) {
- case V4L2_IDENT_CX23888_AV:
- /* 888/HVR1250 specific */
- cx25840_write4(client, 0x10c, 0x13333333);
- cx25840_write4(client, 0x108, 0x00000515);
- break;
- default:
- cx25840_write4(client, 0x10c, 0x002be2c9);
- cx25840_write4(client, 0x108, 0x0000040f);
- }
-
- /* Luma */
- cx25840_write4(client, 0x414, 0x00107d12);
-
- /* Chroma */
- cx25840_write4(client, 0x420, 0x3d008282);
-
- /*
- * Aux PLL
- * Initial setup for audio sample clock:
- * 48 ksps, 16 bits/sample, x160 multiplier = 122.88 MHz
- * Initial I2S output/master clock(?):
- * 48 ksps, 16 bits/sample, x16 multiplier = 12.288 MHz
- */
- switch (state->id) {
- case V4L2_IDENT_CX23888_AV:
- /*
- * 50.0 MHz * (0x7 + 0x0bedfa4/0x2000000)/3 = 122.88 MHz
- * 368.64 MHz before post divide
- * 122.88 MHz / 0xa = 12.288 MHz
- */
- /* HVR1850 or 50MHz xtal */
- cx25840_write4(client, 0x114, 0x017dbf48);
- cx25840_write4(client, 0x110, 0x000a030e);
- break;
- case V4L2_IDENT_CX23887_AV:
- /*
- * 25.0 MHz * (0xe + 0x17dbf48/0x2000000)/3 = 122.88 MHz
- * 368.64 MHz before post divide
- * 122.88 MHz / 0xa = 12.288 MHz
- */
- cx25840_write4(client, 0x114, 0x017dbf48);
- cx25840_write4(client, 0x110, 0x000a030e);
- break;
- case V4L2_IDENT_CX23885_AV:
- default:
- /*
- * 28.636363 MHz * (0xc + 0x1bf0c9e/0x2000000)/3 = 122.88 MHz
- * 368.64 MHz before post divide
- * 122.88 MHz / 0xa = 12.288 MHz
- */
- cx25840_write4(client, 0x114, 0x01bf0c9e);
- cx25840_write4(client, 0x110, 0x000a030c);
- break;
- };
-
- /* ADC2 input select */
- cx25840_write(client, 0x102, 0x10);
-
- /* VIN1 & VIN5 */
- cx25840_write(client, 0x103, 0x11);
-
- /* Enable format auto detect */
- cx25840_write(client, 0x400, 0);
- /* Fast subchroma lock */
- /* White crush, Chroma AGC & Chroma Killer enabled */
- cx25840_write(client, 0x401, 0xe8);
-
- /* Select AFE clock pad output source */
- cx25840_write(client, 0x144, 0x05);
-
- /* Drive GPIO2 direction and values for HVR1700
- * where an onboard mux selects the output of demodulator
- * vs the 417. Failure to set this results in no DTV.
- * It's safe to set this across all Hauppauge boards
- * currently, regardless of the board type.
- */
- cx25840_write(client, 0x160, 0x1d);
- cx25840_write(client, 0x164, 0x00);
-
- /* Do the firmware load in a work handler to prevent.
- Otherwise the kernel is blocked waiting for the
- bit-banging i2c interface to finish uploading the
- firmware. */
- INIT_WORK(&state->fw_work, cx25840_work_handler);
- init_waitqueue_head(&state->fw_wait);
- q = create_singlethread_workqueue("cx25840_fw");
- prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
- queue_work(q, &state->fw_work);
- schedule();
- finish_wait(&state->fw_wait, &wait);
- destroy_workqueue(q);
-
- /* Call the cx23888 specific std setup func, we no longer rely on
- * the generic cx24840 func.
- */
- if (is_cx23888(state))
- cx23888_std_setup(client);
- else
- cx25840_std_setup(client);
-
- /* (re)set input */
- set_input(client, state->vid_input, state->aud_input);
-
- /* start microcontroller */
- cx25840_and_or(client, 0x803, ~0x10, 0x10);
-
- /* Disable and clear video interrupts - we don't use them */
- cx25840_write4(client, CX25840_VID_INT_STAT_REG, 0xffffffff);
-
- /* Disable and clear audio interrupts - we don't use them */
- cx25840_write(client, CX25840_AUD_INT_CTRL_REG, 0xff);
- cx25840_write(client, CX25840_AUD_INT_STAT_REG, 0xff);
-
- /* CC raw enable */
- /* - VIP 1.1 control codes - 10bit, blue field enable.
- * - enable raw data during vertical blanking.
- * - enable ancillary Data insertion for 656 or VIP.
- */
- cx25840_write4(client, 0x404, 0x0010253e);
-
- /* CC on - Undocumented Register */
- cx25840_write(client, 0x42f, 0x66);
-
- /* HVR-1250 / HVR1850 DIF related */
- /* Power everything up */
- cx25840_write4(client, 0x130, 0x0);
-
- /* Undocumented */
- cx25840_write4(client, 0x478, 0x6628021F);
-
- /* AFE_CLK_OUT_CTRL - Select the clock output source as output */
- cx25840_write4(client, 0x144, 0x5);
-
- /* I2C_OUT_CTL - I2S output configuration as
- * Master, Sony, Left justified, left sample on WS=1
- */
- cx25840_write4(client, 0x918, 0x1a0);
-
- /* AFE_DIAG_CTRL1 */
- cx25840_write4(client, 0x134, 0x000a1800);
-
- /* AFE_DIAG_CTRL3 - Inverted Polarity for Audio and Video */
- cx25840_write4(client, 0x13c, 0x00310000);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static void cx231xx_initialize(struct i2c_client *client)
-{
- DEFINE_WAIT(wait);
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- struct workqueue_struct *q;
-
- /* Internal Reset */
- cx25840_and_or(client, 0x102, ~0x01, 0x01);
- cx25840_and_or(client, 0x102, ~0x01, 0x00);
-
- /* Stop microcontroller */
- cx25840_and_or(client, 0x803, ~0x10, 0x00);
-
- /* DIF in reset? */
- cx25840_write(client, 0x398, 0);
-
- /* Trust the default xtal, no division */
- /* This changes for the cx23888 products */
- cx25840_write(client, 0x2, 0x76);
-
- /* Bring down the regulator for AUX clk */
- cx25840_write(client, 0x1, 0x40);
-
- /* Disable DIF bypass */
- cx25840_write4(client, 0x33c, 0x00000001);
-
- /* DIF Src phase inc */
- cx25840_write4(client, 0x340, 0x0df7df83);
-
- /* Luma */
- cx25840_write4(client, 0x414, 0x00107d12);
-
- /* Chroma */
- cx25840_write4(client, 0x420, 0x3d008282);
-
- /* ADC2 input select */
- cx25840_write(client, 0x102, 0x10);
-
- /* VIN1 & VIN5 */
- cx25840_write(client, 0x103, 0x11);
-
- /* Enable format auto detect */
- cx25840_write(client, 0x400, 0);
- /* Fast subchroma lock */
- /* White crush, Chroma AGC & Chroma Killer enabled */
- cx25840_write(client, 0x401, 0xe8);
-
- /* Do the firmware load in a work handler to prevent.
- Otherwise the kernel is blocked waiting for the
- bit-banging i2c interface to finish uploading the
- firmware. */
- INIT_WORK(&state->fw_work, cx25840_work_handler);
- init_waitqueue_head(&state->fw_wait);
- q = create_singlethread_workqueue("cx25840_fw");
- prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
- queue_work(q, &state->fw_work);
- schedule();
- finish_wait(&state->fw_wait, &wait);
- destroy_workqueue(q);
-
- cx25840_std_setup(client);
-
- /* (re)set input */
- set_input(client, state->vid_input, state->aud_input);
-
- /* start microcontroller */
- cx25840_and_or(client, 0x803, ~0x10, 0x10);
-
- /* CC raw enable */
- cx25840_write(client, 0x404, 0x0b);
-
- /* CC on */
- cx25840_write(client, 0x42f, 0x66);
- cx25840_write4(client, 0x474, 0x1e1e601a);
-}
-
-/* ----------------------------------------------------------------------- */
-
-void cx25840_std_setup(struct i2c_client *client)
-{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- v4l2_std_id std = state->std;
- int hblank, hactive, burst, vblank, vactive, sc;
- int vblank656, src_decimation;
- int luma_lpf, uv_lpf, comb;
- u32 pll_int, pll_frac, pll_post;
-
- /* datasheet startup, step 8d */
- if (std & ~V4L2_STD_NTSC)
- cx25840_write(client, 0x49f, 0x11);
- else
- cx25840_write(client, 0x49f, 0x14);
-
- if (std & V4L2_STD_625_50) {
- hblank = 132;
- hactive = 720;
- burst = 93;
- vblank = 36;
- vactive = 580;
- vblank656 = 40;
- src_decimation = 0x21f;
- luma_lpf = 2;
-
- if (std & V4L2_STD_SECAM) {
- uv_lpf = 0;
- comb = 0;
- sc = 0x0a425f;
- } else if (std == V4L2_STD_PAL_Nc) {
- uv_lpf = 1;
- comb = 0x20;
- sc = 556453;
- } else {
- uv_lpf = 1;
- comb = 0x20;
- sc = 688739;
- }
- } else {
- hactive = 720;
- hblank = 122;
- vactive = 487;
- luma_lpf = 1;
- uv_lpf = 1;
-
- src_decimation = 0x21f;
- if (std == V4L2_STD_PAL_60) {
- vblank = 26;
- vblank656 = 26;
- burst = 0x5b;
- luma_lpf = 2;
- comb = 0x20;
- sc = 688739;
- } else if (std == V4L2_STD_PAL_M) {
- vblank = 20;
- vblank656 = 24;
- burst = 0x61;
- comb = 0x20;
- sc = 555452;
- } else {
- vblank = 26;
- vblank656 = 26;
- burst = 0x5b;
- comb = 0x66;
- sc = 556063;
- }
- }
-
- /* DEBUG: Displays configured PLL frequency */
- if (!is_cx231xx(state)) {
- pll_int = cx25840_read(client, 0x108);
- pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;
- pll_post = cx25840_read(client, 0x109);
- v4l_dbg(1, cx25840_debug, client,
- "PLL regs = int: %u, frac: %u, post: %u\n",
- pll_int, pll_frac, pll_post);
-
- if (pll_post) {
- int fin, fsc;
- int pll = (28636363L * ((((u64)pll_int) << 25L) + pll_frac)) >> 25L;
-
- pll /= pll_post;
- v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n",
- pll / 1000000, pll % 1000000);
- v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n",
- pll / 8000000, (pll / 8) % 1000000);
-
- fin = ((u64)src_decimation * pll) >> 12;
- v4l_dbg(1, cx25840_debug, client,
- "ADC Sampling freq = %d.%06d MHz\n",
- fin / 1000000, fin % 1000000);
-
- fsc = (((u64)sc) * pll) >> 24L;
- v4l_dbg(1, cx25840_debug, client,
- "Chroma sub-carrier freq = %d.%06d MHz\n",
- fsc / 1000000, fsc % 1000000);
-
- v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, "
- "vblank %i, vactive %i, vblank656 %i, src_dec %i, "
- "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, "
- "sc 0x%06x\n",
- hblank, hactive, vblank, vactive, vblank656,
- src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
- }
- }
-
- /* Sets horizontal blanking delay and active lines */
- cx25840_write(client, 0x470, hblank);
- cx25840_write(client, 0x471,
- 0xff & (((hblank >> 8) & 0x3) | (hactive << 4)));
- cx25840_write(client, 0x472, hactive >> 4);
-
- /* Sets burst gate delay */
- cx25840_write(client, 0x473, burst);
-
- /* Sets vertical blanking delay and active duration */
- cx25840_write(client, 0x474, vblank);
- cx25840_write(client, 0x475,
- 0xff & (((vblank >> 8) & 0x3) | (vactive << 4)));
- cx25840_write(client, 0x476, vactive >> 4);
- cx25840_write(client, 0x477, vblank656);
-
- /* Sets src decimation rate */
- cx25840_write(client, 0x478, 0xff & src_decimation);
- cx25840_write(client, 0x479, 0xff & (src_decimation >> 8));
-
- /* Sets Luma and UV Low pass filters */
- cx25840_write(client, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));
-
- /* Enables comb filters */
- cx25840_write(client, 0x47b, comb);
-
- /* Sets SC Step*/
- cx25840_write(client, 0x47c, sc);
- cx25840_write(client, 0x47d, 0xff & sc >> 8);
- cx25840_write(client, 0x47e, 0xff & sc >> 16);
-
- /* Sets VBI parameters */
- if (std & V4L2_STD_625_50) {
- cx25840_write(client, 0x47f, 0x01);
- state->vbi_line_offset = 5;
- } else {
- cx25840_write(client, 0x47f, 0x00);
- state->vbi_line_offset = 8;
- }
-}
-
-/* ----------------------------------------------------------------------- */
-
-static void input_change(struct i2c_client *client)
-{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- v4l2_std_id std = state->std;
-
- /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */
- if (std & V4L2_STD_SECAM) {
- cx25840_write(client, 0x402, 0);
- }
- else {
- cx25840_write(client, 0x402, 0x04);
- cx25840_write(client, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
- }
- cx25840_and_or(client, 0x401, ~0x60, 0);
- cx25840_and_or(client, 0x401, ~0x60, 0x60);
-
- /* Don't write into audio registers on cx2583x chips */
- if (is_cx2583x(state))
- return;
-
- cx25840_and_or(client, 0x810, ~0x01, 1);
-
- if (state->radio) {
- cx25840_write(client, 0x808, 0xf9);
- cx25840_write(client, 0x80b, 0x00);
- }
- else if (std & V4L2_STD_525_60) {
- /* Certain Hauppauge PVR150 models have a hardware bug
- that causes audio to drop out. For these models the
- audio standard must be set explicitly.
- To be precise: it affects cards with tuner models
- 85, 99 and 112 (model numbers from tveeprom). */
- int hw_fix = state->pvr150_workaround;
-
- if (std == V4L2_STD_NTSC_M_JP) {
- /* Japan uses EIAJ audio standard */
- cx25840_write(client, 0x808, hw_fix ? 0x2f : 0xf7);
- } else if (std == V4L2_STD_NTSC_M_KR) {
- /* South Korea uses A2 audio standard */
- cx25840_write(client, 0x808, hw_fix ? 0x3f : 0xf8);
- } else {
- /* Others use the BTSC audio standard */
- cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6);
- }
- cx25840_write(client, 0x80b, 0x00);
- } else if (std & V4L2_STD_PAL) {
- /* Autodetect audio standard and audio system */
- cx25840_write(client, 0x808, 0xff);
- /* Since system PAL-L is pretty much non-existent and
- not used by any public broadcast network, force
- 6.5 MHz carrier to be interpreted as System DK,
- this avoids DK audio detection instability */
- cx25840_write(client, 0x80b, 0x00);
- } else if (std & V4L2_STD_SECAM) {
- /* Autodetect audio standard and audio system */
- cx25840_write(client, 0x808, 0xff);
- /* If only one of SECAM-DK / SECAM-L is required, then force
- 6.5MHz carrier, else autodetect it */
- if ((std & V4L2_STD_SECAM_DK) &&
- !(std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {
- /* 6.5 MHz carrier to be interpreted as System DK */
- cx25840_write(client, 0x80b, 0x00);
- } else if (!(std & V4L2_STD_SECAM_DK) &&
- (std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {
- /* 6.5 MHz carrier to be interpreted as System L */
- cx25840_write(client, 0x80b, 0x08);
- } else {
- /* 6.5 MHz carrier to be autodetected */
- cx25840_write(client, 0x80b, 0x10);
- }
- }
-
- cx25840_and_or(client, 0x810, ~0x01, 0);
-}
-
-static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
- enum cx25840_audio_input aud_input)
-{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&
- vid_input <= CX25840_COMPOSITE8);
- u8 is_component = (vid_input & CX25840_COMPONENT_ON) ==
- CX25840_COMPONENT_ON;
- u8 is_dif = (vid_input & CX25840_DIF_ON) ==
- CX25840_DIF_ON;
- u8 is_svideo = (vid_input & CX25840_SVIDEO_ON) ==
- CX25840_SVIDEO_ON;
- int luma = vid_input & 0xf0;
- int chroma = vid_input & 0xf00;
- u8 reg;
- u32 val;
-
- v4l_dbg(1, cx25840_debug, client,
- "decoder set video input %d, audio input %d\n",
- vid_input, aud_input);
-
- if (vid_input >= CX25840_VIN1_CH1) {
- v4l_dbg(1, cx25840_debug, client, "vid_input 0x%x\n",
- vid_input);
- reg = vid_input & 0xff;
- is_composite = !is_component &&
- ((vid_input & CX25840_SVIDEO_ON) != CX25840_SVIDEO_ON);
-
- v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n",
- reg, is_composite);
- } else if (is_composite) {
- reg = 0xf0 + (vid_input - CX25840_COMPOSITE1);
- } else {
- if ((vid_input & ~0xff0) ||
- luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 ||
- chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
- v4l_err(client, "0x%04x is not a valid video input!\n",
- vid_input);
- return -EINVAL;
- }
- reg = 0xf0 + ((luma - CX25840_SVIDEO_LUMA1) >> 4);
- if (chroma >= CX25840_SVIDEO_CHROMA7) {
- reg &= 0x3f;
- reg |= (chroma - CX25840_SVIDEO_CHROMA7) >> 2;
- } else {
- reg &= 0xcf;
- reg |= (chroma - CX25840_SVIDEO_CHROMA4) >> 4;
- }
- }
-
- /* The caller has previously prepared the correct routing
- * configuration in reg (for the cx23885) so we have no
- * need to attempt to flip bits for earlier av decoders.
- */
- if (!is_cx2388x(state) && !is_cx231xx(state)) {
- switch (aud_input) {
- case CX25840_AUDIO_SERIAL:
- /* do nothing, use serial audio input */
- break;
- case CX25840_AUDIO4: reg &= ~0x30; break;
- case CX25840_AUDIO5: reg &= ~0x30; reg |= 0x10; break;
- case CX25840_AUDIO6: reg &= ~0x30; reg |= 0x20; break;
- case CX25840_AUDIO7: reg &= ~0xc0; break;
- case CX25840_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
-
- default:
- v4l_err(client, "0x%04x is not a valid audio input!\n",
- aud_input);
- return -EINVAL;
- }
- }
-
- cx25840_write(client, 0x103, reg);
-
- /* Set INPUT_MODE to Composite, S-Video or Component */
- if (is_component)
- cx25840_and_or(client, 0x401, ~0x6, 0x6);
- else
- cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
-
- if (is_cx2388x(state)) {
-
- /* Enable or disable the DIF for tuner use */
- if (is_dif) {
- cx25840_and_or(client, 0x102, ~0x80, 0x80);
-
- /* Set of defaults for NTSC and PAL */
- cx25840_write4(client, 0x31c, 0xc2262600);
- cx25840_write4(client, 0x320, 0xc2262600);
-
- /* 18271 IF - Nobody else yet uses a different
- * tuner with the DIF, so these are reasonable
- * assumptions (HVR1250 and HVR1850 specific).
- */
- cx25840_write4(client, 0x318, 0xda262600);
- cx25840_write4(client, 0x33c, 0x2a24c800);
- cx25840_write4(client, 0x104, 0x0704dd00);
- } else {
- cx25840_write4(client, 0x300, 0x015c28f5);
-
- cx25840_and_or(client, 0x102, ~0x80, 0);
- cx25840_write4(client, 0x340, 0xdf7df83);
- cx25840_write4(client, 0x104, 0x0704dd80);
- cx25840_write4(client, 0x314, 0x22400600);
- cx25840_write4(client, 0x318, 0x40002600);
- cx25840_write4(client, 0x324, 0x40002600);
- cx25840_write4(client, 0x32c, 0x0250e620);
- cx25840_write4(client, 0x39c, 0x01FF0B00);
-
- cx25840_write4(client, 0x410, 0xffff0dbf);
- cx25840_write4(client, 0x414, 0x00137d03);
-
- /* on the 887, 0x418 is HSCALE_CTRL, on the 888 it is
- CHROMA_CTRL */
- if (is_cx23888(state))
- cx25840_write4(client, 0x418, 0x01008080);
- else
- cx25840_write4(client, 0x418, 0x01000000);
-
- cx25840_write4(client, 0x41c, 0x00000000);
-
- /* on the 887, 0x420 is CHROMA_CTRL, on the 888 it is
- CRUSH_CTRL */
- if (is_cx23888(state))
- cx25840_write4(client, 0x420, 0x001c3e0f);
- else
- cx25840_write4(client, 0x420, 0x001c8282);
-
- cx25840_write4(client, 0x42c, 0x42600000);
- cx25840_write4(client, 0x430, 0x0000039b);
- cx25840_write4(client, 0x438, 0x00000000);
-
- cx25840_write4(client, 0x440, 0xF8E3E824);
- cx25840_write4(client, 0x444, 0x401040dc);
- cx25840_write4(client, 0x448, 0xcd3f02a0);
- cx25840_write4(client, 0x44c, 0x161f1000);
- cx25840_write4(client, 0x450, 0x00000802);
-
- cx25840_write4(client, 0x91c, 0x01000000);
- cx25840_write4(client, 0x8e0, 0x03063870);
- cx25840_write4(client, 0x8d4, 0x7FFF0024);
- cx25840_write4(client, 0x8d0, 0x00063073);
-
- cx25840_write4(client, 0x8c8, 0x00010000);
- cx25840_write4(client, 0x8cc, 0x00080023);
-
- /* DIF BYPASS */
- cx25840_write4(client, 0x33c, 0x2a04c800);
- }
-
- /* Reset the DIF */
- cx25840_write4(client, 0x398, 0);
- }
-
- if (!is_cx2388x(state) && !is_cx231xx(state)) {
- /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
- cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
- /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */
- if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
- cx25840_and_or(client, 0x102, ~0x4, 4);
- else
- cx25840_and_or(client, 0x102, ~0x4, 0);
- } else {
- /* Set DUAL_MODE_ADC2 to 1 if component*/
- cx25840_and_or(client, 0x102, ~0x4, is_component ? 0x4 : 0x0);
- if (is_composite) {
- /* ADC2 input select channel 2 */
- cx25840_and_or(client, 0x102, ~0x2, 0);
- } else if (!is_component) {
- /* S-Video */
- if (chroma >= CX25840_SVIDEO_CHROMA7) {
- /* ADC2 input select channel 3 */
- cx25840_and_or(client, 0x102, ~0x2, 2);
- } else {
- /* ADC2 input select channel 2 */
- cx25840_and_or(client, 0x102, ~0x2, 0);
- }
- }
-
- /* cx23885 / SVIDEO */
- if (is_cx2388x(state) && is_svideo) {
-#define AFE_CTRL (0x104)
-#define MODE_CTRL (0x400)
- cx25840_and_or(client, 0x102, ~0x2, 0x2);
-
- val = cx25840_read4(client, MODE_CTRL);
- val &= 0xFFFFF9FF;
-
- /* YC */
- val |= 0x00000200;
- val &= ~0x2000;
- cx25840_write4(client, MODE_CTRL, val);
-
- val = cx25840_read4(client, AFE_CTRL);
-
- /* Chroma in select */
- val |= 0x00001000;
- val &= 0xfffffe7f;
- /* Clear VGA_SEL_CH2 and VGA_SEL_CH3 (bits 7 and 8).
- * This sets them to use video rather than audio.
- * Only one of the two will be in use.
- */
- cx25840_write4(client, AFE_CTRL, val);
- } else
- cx25840_and_or(client, 0x102, ~0x2, 0);
- }
-
- state->vid_input = vid_input;
- state->aud_input = aud_input;
- cx25840_audio_set_path(client);
- input_change(client);
-
- if (is_cx2388x(state)) {
- /* Audio channel 1 src : Parallel 1 */
- cx25840_write(client, 0x124, 0x03);
-
- /* Select AFE clock pad output source */
- cx25840_write(client, 0x144, 0x05);
-
- /* I2S_IN_CTL: I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1 */
- cx25840_write(client, 0x914, 0xa0);
-
- /* I2S_OUT_CTL:
- * I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1
- * I2S_OUT_MASTER_MODE = Master
- */
- cx25840_write(client, 0x918, 0xa0);
- cx25840_write(client, 0x919, 0x01);
- } else if (is_cx231xx(state)) {
- /* Audio channel 1 src : Parallel 1 */
- cx25840_write(client, 0x124, 0x03);
-
- /* I2S_IN_CTL: I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1 */
- cx25840_write(client, 0x914, 0xa0);
-
- /* I2S_OUT_CTL:
- * I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1
- * I2S_OUT_MASTER_MODE = Master
- */
- cx25840_write(client, 0x918, 0xa0);
- cx25840_write(client, 0x919, 0x01);
- }
-
- if (is_cx2388x(state) && ((aud_input == CX25840_AUDIO7) ||
- (aud_input == CX25840_AUDIO6))) {
- /* Configure audio from LR1 or LR2 input */
- cx25840_write4(client, 0x910, 0);
- cx25840_write4(client, 0x8d0, 0x63073);
- } else
- if (is_cx2388x(state) && (aud_input == CX25840_AUDIO8)) {
- /* Configure audio from tuner/sif input */
- cx25840_write4(client, 0x910, 0x12b000c9);
- cx25840_write4(client, 0x8d0, 0x1f063870);
- }
-
- if (is_cx23888(state)) {
- /* HVR1850 */
- /* AUD_IO_CTRL - I2S Input, Parallel1*/
- /* - Channel 1 src - Parallel1 (Merlin out) */
- /* - Channel 2 src - Parallel2 (Merlin out) */
- /* - Channel 3 src - Parallel3 (Merlin AC97 out) */
- /* - I2S source and dir - Merlin, output */
- cx25840_write4(client, 0x124, 0x100);
-
- if (!is_dif) {
- /* Stop microcontroller if we don't need it
- * to avoid audio popping on svideo/composite use.
- */
- cx25840_and_or(client, 0x803, ~0x10, 0x00);
- }
- }
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int set_v4lstd(struct i2c_client *client)
-{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- u8 fmt = 0; /* zero is autodetect */
- u8 pal_m = 0;
-
- /* First tests should be against specific std */
- if (state->std == V4L2_STD_NTSC_M_JP) {
- fmt = 0x2;
- } else if (state->std == V4L2_STD_NTSC_443) {
- fmt = 0x3;
- } else if (state->std == V4L2_STD_PAL_M) {
- pal_m = 1;
- fmt = 0x5;
- } else if (state->std == V4L2_STD_PAL_N) {
- fmt = 0x6;
- } else if (state->std == V4L2_STD_PAL_Nc) {
- fmt = 0x7;
- } else if (state->std == V4L2_STD_PAL_60) {
- fmt = 0x8;
- } else {
- /* Then, test against generic ones */
- if (state->std & V4L2_STD_NTSC)
- fmt = 0x1;
- else if (state->std & V4L2_STD_PAL)
- fmt = 0x4;
- else if (state->std & V4L2_STD_SECAM)
- fmt = 0xc;
- }
-
- v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt);
-
- /* Follow step 9 of section 3.16 in the cx25840 datasheet.
- Without this PAL may display a vertical ghosting effect.
- This happens for example with the Yuan MPC622. */
- if (fmt >= 4 && fmt < 8) {
- /* Set format to NTSC-M */
- cx25840_and_or(client, 0x400, ~0xf, 1);
- /* Turn off LCOMB */
- cx25840_and_or(client, 0x47b, ~6, 0);
- }
- cx25840_and_or(client, 0x400, ~0xf, fmt);
- cx25840_and_or(client, 0x403, ~0x3, pal_m);
- if (is_cx23888(state))
- cx23888_std_setup(client);
- else
- cx25840_std_setup(client);
- if (!is_cx2583x(state))
- input_change(client);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int cx25840_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- cx25840_write(client, 0x414, ctrl->val - 128);
- break;
-
- case V4L2_CID_CONTRAST:
- cx25840_write(client, 0x415, ctrl->val << 1);
- break;
-
- case V4L2_CID_SATURATION:
- if (is_cx23888(state)) {
- cx25840_write(client, 0x418, ctrl->val << 1);
- cx25840_write(client, 0x419, ctrl->val << 1);
- } else {
- cx25840_write(client, 0x420, ctrl->val << 1);
- cx25840_write(client, 0x421, ctrl->val << 1);
- }
- break;
-
- case V4L2_CID_HUE:
- if (is_cx23888(state))
- cx25840_write(client, 0x41a, ctrl->val);
- else
- cx25840_write(client, 0x422, ctrl->val);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int cx25840_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
- int is_50Hz = !(state->std & V4L2_STD_525_60);
-
- if (fmt->code != V4L2_MBUS_FMT_FIXED)
- return -EINVAL;
-
- fmt->field = V4L2_FIELD_INTERLACED;
- fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
-
- if (is_cx23888(state)) {
- Vsrc = (cx25840_read(client, 0x42a) & 0x3f) << 4;
- Vsrc |= (cx25840_read(client, 0x429) & 0xf0) >> 4;
- } else {
- Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4;
- Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4;
- }
-
- if (is_cx23888(state)) {
- Hsrc = (cx25840_read(client, 0x426) & 0x3f) << 4;
- Hsrc |= (cx25840_read(client, 0x425) & 0xf0) >> 4;
- } else {
- Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
- Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
- }
-
- Vlines = fmt->height + (is_50Hz ? 4 : 7);
-
- if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
- (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
- v4l_err(client, "%dx%d is not a valid size!\n",
- fmt->width, fmt->height);
- return -ERANGE;
- }
-
- HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20);
- VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
- VSC &= 0x1fff;
-
- if (fmt->width >= 385)
- filter = 0;
- else if (fmt->width > 192)
- filter = 1;
- else if (fmt->width > 96)
- filter = 2;
- else
- filter = 3;
-
- v4l_dbg(1, cx25840_debug, client, "decoder set size %dx%d -> scale %ux%u\n",
- fmt->width, fmt->height, HSC, VSC);
-
- /* HSCALE=HSC */
- cx25840_write(client, 0x418, HSC & 0xff);
- cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
- cx25840_write(client, 0x41a, HSC >> 16);
- /* VSCALE=VSC */
- cx25840_write(client, 0x41c, VSC & 0xff);
- cx25840_write(client, 0x41d, VSC >> 8);
- /* VS_INTRLACE=1 VFILT=filter */
- cx25840_write(client, 0x41e, 0x8 | filter);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static void log_video_status(struct i2c_client *client)
-{
- static const char *const fmt_strs[] = {
- "0x0",
- "NTSC-M", "NTSC-J", "NTSC-4.43",
- "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
- "0x9", "0xA", "0xB",
- "SECAM",
- "0xD", "0xE", "0xF"
- };
-
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf;
- u8 gen_stat1 = cx25840_read(client, 0x40d);
- u8 gen_stat2 = cx25840_read(client, 0x40e);
- int vid_input = state->vid_input;
-
- v4l_info(client, "Video signal: %spresent\n",
- (gen_stat2 & 0x20) ? "" : "not ");
- v4l_info(client, "Detected format: %s\n",
- fmt_strs[gen_stat1 & 0xf]);
-
- v4l_info(client, "Specified standard: %s\n",
- vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
-
- if (vid_input >= CX25840_COMPOSITE1 &&
- vid_input <= CX25840_COMPOSITE8) {
- v4l_info(client, "Specified video input: Composite %d\n",
- vid_input - CX25840_COMPOSITE1 + 1);
- } else {
- v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
- (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
- }
-
- v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static void log_audio_status(struct i2c_client *client)
-{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- u8 download_ctl = cx25840_read(client, 0x803);
- u8 mod_det_stat0 = cx25840_read(client, 0x804);
- u8 mod_det_stat1 = cx25840_read(client, 0x805);
- u8 audio_config = cx25840_read(client, 0x808);
- u8 pref_mode = cx25840_read(client, 0x809);
- u8 afc0 = cx25840_read(client, 0x80b);
- u8 mute_ctl = cx25840_read(client, 0x8d3);
- int aud_input = state->aud_input;
- char *p;
-
- switch (mod_det_stat0) {
- case 0x00: p = "mono"; break;
- case 0x01: p = "stereo"; break;
- case 0x02: p = "dual"; break;
- case 0x04: p = "tri"; break;
- case 0x10: p = "mono with SAP"; break;
- case 0x11: p = "stereo with SAP"; break;
- case 0x12: p = "dual with SAP"; break;
- case 0x14: p = "tri with SAP"; break;
- case 0xfe: p = "forced mode"; break;
- default: p = "not defined";
- }
- v4l_info(client, "Detected audio mode: %s\n", p);
-
- switch (mod_det_stat1) {
- case 0x00: p = "not defined"; break;
- case 0x01: p = "EIAJ"; break;
- case 0x02: p = "A2-M"; break;
- case 0x03: p = "A2-BG"; break;
- case 0x04: p = "A2-DK1"; break;
- case 0x05: p = "A2-DK2"; break;
- case 0x06: p = "A2-DK3"; break;
- case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
- case 0x08: p = "AM-L"; break;
- case 0x09: p = "NICAM-BG"; break;
- case 0x0a: p = "NICAM-DK"; break;
- case 0x0b: p = "NICAM-I"; break;
- case 0x0c: p = "NICAM-L"; break;
- case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
- case 0x0e: p = "IF FM Radio"; break;
- case 0x0f: p = "BTSC"; break;
- case 0x10: p = "high-deviation FM"; break;
- case 0x11: p = "very high-deviation FM"; break;
- case 0xfd: p = "unknown audio standard"; break;
- case 0xfe: p = "forced audio standard"; break;
- case 0xff: p = "no detected audio standard"; break;
- default: p = "not defined";
- }
- v4l_info(client, "Detected audio standard: %s\n", p);
- v4l_info(client, "Audio microcontroller: %s\n",
- (download_ctl & 0x10) ?
- ((mute_ctl & 0x2) ? "detecting" : "running") : "stopped");
-
- switch (audio_config >> 4) {
- case 0x00: p = "undefined"; break;
- case 0x01: p = "BTSC"; break;
- case 0x02: p = "EIAJ"; break;
- case 0x03: p = "A2-M"; break;
- case 0x04: p = "A2-BG"; break;
- case 0x05: p = "A2-DK1"; break;
- case 0x06: p = "A2-DK2"; break;
- case 0x07: p = "A2-DK3"; break;
- case 0x08: p = "A1 (6.0 MHz FM Mono)"; break;
- case 0x09: p = "AM-L"; break;
- case 0x0a: p = "NICAM-BG"; break;
- case 0x0b: p = "NICAM-DK"; break;
- case 0x0c: p = "NICAM-I"; break;
- case 0x0d: p = "NICAM-L"; break;
- case 0x0e: p = "FM radio"; break;
- case 0x0f: p = "automatic detection"; break;
- default: p = "undefined";
- }
- v4l_info(client, "Configured audio standard: %s\n", p);
-
- if ((audio_config >> 4) < 0xF) {
- switch (audio_config & 0xF) {
- case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
- case 0x01: p = "MONO2 (LANGUAGE B)"; break;
- case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
- case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
- case 0x04: p = "STEREO"; break;
- case 0x05: p = "DUAL1 (AB)"; break;
- case 0x06: p = "DUAL2 (AC) (FM)"; break;
- case 0x07: p = "DUAL3 (BC) (FM)"; break;
- case 0x08: p = "DUAL4 (AC) (AM)"; break;
- case 0x09: p = "DUAL5 (BC) (AM)"; break;
- case 0x0a: p = "SAP"; break;
- default: p = "undefined";
- }
- v4l_info(client, "Configured audio mode: %s\n", p);
- } else {
- switch (audio_config & 0xF) {
- case 0x00: p = "BG"; break;
- case 0x01: p = "DK1"; break;
- case 0x02: p = "DK2"; break;
- case 0x03: p = "DK3"; break;
- case 0x04: p = "I"; break;
- case 0x05: p = "L"; break;
- case 0x06: p = "BTSC"; break;
- case 0x07: p = "EIAJ"; break;
- case 0x08: p = "A2-M"; break;
- case 0x09: p = "FM Radio"; break;
- case 0x0f: p = "automatic standard and mode detection"; break;
- default: p = "undefined";
- }
- v4l_info(client, "Configured audio system: %s\n", p);
- }
-
- if (aud_input) {
- v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input);
- } else {
- v4l_info(client, "Specified audio input: External\n");
- }
-
- switch (pref_mode & 0xf) {
- case 0: p = "mono/language A"; break;
- case 1: p = "language B"; break;
- case 2: p = "language C"; break;
- case 3: p = "analog fallback"; break;
- case 4: p = "stereo"; break;
- case 5: p = "language AC"; break;
- case 6: p = "language BC"; break;
- case 7: p = "language AB"; break;
- default: p = "undefined";
- }
- v4l_info(client, "Preferred audio mode: %s\n", p);
-
- if ((audio_config & 0xf) == 0xf) {
- switch ((afc0 >> 3) & 0x3) {
- case 0: p = "system DK"; break;
- case 1: p = "system L"; break;
- case 2: p = "autodetect"; break;
- default: p = "undefined";
- }
- v4l_info(client, "Selected 65 MHz format: %s\n", p);
-
- switch (afc0 & 0x7) {
- case 0: p = "chroma"; break;
- case 1: p = "BTSC"; break;
- case 2: p = "EIAJ"; break;
- case 3: p = "A2-M"; break;
- case 4: p = "autodetect"; break;
- default: p = "undefined";
- }
- v4l_info(client, "Selected 45 MHz format: %s\n", p);
- }
-}
-
-/* ----------------------------------------------------------------------- */
-
-/* This load_fw operation must be called to load the driver's firmware.
- Without this the audio standard detection will fail and you will
- only get mono.
-
- Since loading the firmware is often problematic when the driver is
- compiled into the kernel I recommend postponing calling this function
- until the first open of the video device. Another reason for
- postponing it is that loading this firmware takes a long time (seconds)
- due to the slow i2c bus speed. So it will speed up the boot process if
- you can avoid loading the fw as long as the video device isn't used. */
-static int cx25840_load_fw(struct v4l2_subdev *sd)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!state->is_initialized) {
- /* initialize and load firmware */
- state->is_initialized = 1;
- if (is_cx2583x(state))
- cx25836_initialize(client);
- else if (is_cx2388x(state))
- cx23885_initialize(client);
- else if (is_cx231xx(state))
- cx231xx_initialize(client);
- else
- cx25840_initialize(client);
- }
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int cx25840_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- reg->size = 1;
- reg->val = cx25840_read(client, reg->reg & 0x0fff);
- return 0;
-}
-
-static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
- return 0;
-}
-#endif
-
-static int cx25840_s_audio_stream(struct v4l2_subdev *sd, int enable)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 v;
-
- if (is_cx2583x(state) || is_cx2388x(state) || is_cx231xx(state))
- return 0;
-
- v4l_dbg(1, cx25840_debug, client, "%s audio output\n",
- enable ? "enable" : "disable");
-
- if (enable) {
- v = cx25840_read(client, 0x115) | 0x80;
- cx25840_write(client, 0x115, v);
- v = cx25840_read(client, 0x116) | 0x03;
- cx25840_write(client, 0x116, v);
- } else {
- v = cx25840_read(client, 0x115) & ~(0x80);
- cx25840_write(client, 0x115, v);
- v = cx25840_read(client, 0x116) & ~(0x03);
- cx25840_write(client, 0x116, v);
- }
- return 0;
-}
-
-static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 v;
-
- v4l_dbg(1, cx25840_debug, client, "%s video output\n",
- enable ? "enable" : "disable");
- if (enable) {
- if (is_cx2388x(state) || is_cx231xx(state)) {
- v = cx25840_read(client, 0x421) | 0x0b;
- cx25840_write(client, 0x421, v);
- } else {
- v = cx25840_read(client, 0x115) | 0x0c;
- cx25840_write(client, 0x115, v);
- v = cx25840_read(client, 0x116) | 0x04;
- cx25840_write(client, 0x116, v);
- }
- } else {
- if (is_cx2388x(state) || is_cx231xx(state)) {
- v = cx25840_read(client, 0x421) & ~(0x0b);
- cx25840_write(client, 0x421, v);
- } else {
- v = cx25840_read(client, 0x115) & ~(0x0c);
- cx25840_write(client, 0x115, v);
- v = cx25840_read(client, 0x116) & ~(0x04);
- cx25840_write(client, 0x116, v);
- }
- }
- return 0;
-}
-
-/* Query the current detected video format */
-static int cx25840_g_std(struct v4l2_subdev *sd, v4l2_std_id *std)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- v4l2_std_id stds[] = {
- /* 0000 */ V4L2_STD_UNKNOWN,
-
- /* 0001 */ V4L2_STD_NTSC_M,
- /* 0010 */ V4L2_STD_NTSC_M_JP,
- /* 0011 */ V4L2_STD_NTSC_443,
- /* 0100 */ V4L2_STD_PAL,
- /* 0101 */ V4L2_STD_PAL_M,
- /* 0110 */ V4L2_STD_PAL_N,
- /* 0111 */ V4L2_STD_PAL_Nc,
- /* 1000 */ V4L2_STD_PAL_60,
-
- /* 1001 */ V4L2_STD_UNKNOWN,
- /* 1010 */ V4L2_STD_UNKNOWN,
- /* 1001 */ V4L2_STD_UNKNOWN,
- /* 1010 */ V4L2_STD_UNKNOWN,
- /* 1011 */ V4L2_STD_UNKNOWN,
- /* 1110 */ V4L2_STD_UNKNOWN,
- /* 1111 */ V4L2_STD_UNKNOWN
- };
-
- u32 fmt = (cx25840_read4(client, 0x40c) >> 8) & 0xf;
- *std = stds[ fmt ];
-
- v4l_dbg(1, cx25840_debug, client, "g_std fmt = %x, v4l2_std_id = 0x%x\n",
- fmt, (unsigned int)stds[ fmt ]);
-
- return 0;
-}
-
-static int cx25840_g_input_status(struct v4l2_subdev *sd, u32 *status)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- /* A limited function that checks for signal status and returns
- * the state.
- */
-
- /* Check for status of Horizontal lock (SRC lock isn't reliable) */
- if ((cx25840_read4(client, 0x40c) & 0x00010000) == 0)
- *status |= V4L2_IN_ST_NO_SIGNAL;
-
- return 0;
-}
-
-static int cx25840_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (state->radio == 0 && state->std == std)
- return 0;
- state->radio = 0;
- state->std = std;
- return set_v4lstd(client);
-}
-
-static int cx25840_s_radio(struct v4l2_subdev *sd)
-{
- struct cx25840_state *state = to_state(sd);
-
- state->radio = 1;
- return 0;
-}
-
-static int cx25840_s_video_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (is_cx23888(state))
- cx23888_std_setup(client);
-
- return set_input(client, input, state->aud_input);
-}
-
-static int cx25840_s_audio_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (is_cx23888(state))
- cx23888_std_setup(client);
- return set_input(client, state->vid_input, input);
-}
-
-static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- input_change(client);
- return 0;
-}
-
-static int cx25840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 vpres = cx25840_read(client, 0x40e) & 0x20;
- u8 mode;
- int val = 0;
-
- if (state->radio)
- return 0;
-
- vt->signal = vpres ? 0xffff : 0x0;
- if (is_cx2583x(state))
- return 0;
-
- vt->capability |=
- V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
- V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
-
- mode = cx25840_read(client, 0x804);
-
- /* get rxsubchans and audmode */
- if ((mode & 0xf) == 1)
- val |= V4L2_TUNER_SUB_STEREO;
- else
- val |= V4L2_TUNER_SUB_MONO;
-
- if (mode == 2 || mode == 4)
- val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
-
- if (mode & 0x10)
- val |= V4L2_TUNER_SUB_SAP;
-
- vt->rxsubchans = val;
- vt->audmode = state->audmode;
- return 0;
-}
-
-static int cx25840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (state->radio || is_cx2583x(state))
- return 0;
-
- switch (vt->audmode) {
- case V4L2_TUNER_MODE_MONO:
- /* mono -> mono
- stereo -> mono
- bilingual -> lang1 */
- cx25840_and_or(client, 0x809, ~0xf, 0x00);
- break;
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang1 */
- cx25840_and_or(client, 0x809, ~0xf, 0x04);
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang1/lang2 */
- cx25840_and_or(client, 0x809, ~0xf, 0x07);
- break;
- case V4L2_TUNER_MODE_LANG2:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang2 */
- cx25840_and_or(client, 0x809, ~0xf, 0x01);
- break;
- default:
- return -EINVAL;
- }
- state->audmode = vt->audmode;
- return 0;
-}
-
-static int cx25840_reset(struct v4l2_subdev *sd, u32 val)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (is_cx2583x(state))
- cx25836_initialize(client);
- else if (is_cx2388x(state))
- cx23885_initialize(client);
- else if (is_cx231xx(state))
- cx231xx_initialize(client);
- else
- cx25840_initialize(client);
- return 0;
-}
-
-static int cx25840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
-}
-
-static int cx25840_log_status(struct v4l2_subdev *sd)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- log_video_status(client);
- if (!is_cx2583x(state))
- log_audio_status(client);
- cx25840_ir_log_status(sd);
- v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
- return 0;
-}
-
-static int cx23885_irq_handler(struct v4l2_subdev *sd, u32 status,
- bool *handled)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *c = v4l2_get_subdevdata(sd);
- u8 irq_stat, aud_stat, aud_en, ir_stat, ir_en;
- u32 vid_stat, aud_mc_stat;
- bool block_handled;
- int ret = 0;
-
- irq_stat = cx25840_read(c, CX23885_PIN_CTRL_IRQ_REG);
- v4l_dbg(2, cx25840_debug, c, "AV Core IRQ status (entry): %s %s %s\n",
- irq_stat & CX23885_PIN_CTRL_IRQ_IR_STAT ? "ir" : " ",
- irq_stat & CX23885_PIN_CTRL_IRQ_AUD_STAT ? "aud" : " ",
- irq_stat & CX23885_PIN_CTRL_IRQ_VID_STAT ? "vid" : " ");
-
- if ((is_cx23885(state) || is_cx23887(state))) {
- ir_stat = cx25840_read(c, CX25840_IR_STATS_REG);
- ir_en = cx25840_read(c, CX25840_IR_IRQEN_REG);
- v4l_dbg(2, cx25840_debug, c,
- "AV Core ir IRQ status: %#04x disables: %#04x\n",
- ir_stat, ir_en);
- if (irq_stat & CX23885_PIN_CTRL_IRQ_IR_STAT) {
- block_handled = false;
- ret = cx25840_ir_irq_handler(sd,
- status, &block_handled);
- if (block_handled)
- *handled = true;
- }
- }
-
- aud_stat = cx25840_read(c, CX25840_AUD_INT_STAT_REG);
- aud_en = cx25840_read(c, CX25840_AUD_INT_CTRL_REG);
- v4l_dbg(2, cx25840_debug, c,
- "AV Core audio IRQ status: %#04x disables: %#04x\n",
- aud_stat, aud_en);
- aud_mc_stat = cx25840_read4(c, CX23885_AUD_MC_INT_MASK_REG);
- v4l_dbg(2, cx25840_debug, c,
- "AV Core audio MC IRQ status: %#06x enables: %#06x\n",
- aud_mc_stat >> CX23885_AUD_MC_INT_STAT_SHFT,
- aud_mc_stat & CX23885_AUD_MC_INT_CTRL_BITS);
- if (irq_stat & CX23885_PIN_CTRL_IRQ_AUD_STAT) {
- if (aud_stat) {
- cx25840_write(c, CX25840_AUD_INT_STAT_REG, aud_stat);
- *handled = true;
- }
- }
-
- vid_stat = cx25840_read4(c, CX25840_VID_INT_STAT_REG);
- v4l_dbg(2, cx25840_debug, c,
- "AV Core video IRQ status: %#06x disables: %#06x\n",
- vid_stat & CX25840_VID_INT_STAT_BITS,
- vid_stat >> CX25840_VID_INT_MASK_SHFT);
- if (irq_stat & CX23885_PIN_CTRL_IRQ_VID_STAT) {
- if (vid_stat & CX25840_VID_INT_STAT_BITS) {
- cx25840_write4(c, CX25840_VID_INT_STAT_REG, vid_stat);
- *handled = true;
- }
- }
-
- irq_stat = cx25840_read(c, CX23885_PIN_CTRL_IRQ_REG);
- v4l_dbg(2, cx25840_debug, c, "AV Core IRQ status (exit): %s %s %s\n",
- irq_stat & CX23885_PIN_CTRL_IRQ_IR_STAT ? "ir" : " ",
- irq_stat & CX23885_PIN_CTRL_IRQ_AUD_STAT ? "aud" : " ",
- irq_stat & CX23885_PIN_CTRL_IRQ_VID_STAT ? "vid" : " ");
-
- return ret;
-}
-
-static int cx25840_irq_handler(struct v4l2_subdev *sd, u32 status,
- bool *handled)
-{
- struct cx25840_state *state = to_state(sd);
-
- *handled = false;
-
- /* Only support the CX2388[578] AV Core for now */
- if (is_cx2388x(state))
- return cx23885_irq_handler(sd, status, handled);
-
- return -ENODEV;
-}
-
-/* ----------------------------------------------------------------------- */
-
-#define DIF_PLL_FREQ_WORD (0x300)
-#define DIF_BPF_COEFF01 (0x348)
-#define DIF_BPF_COEFF23 (0x34c)
-#define DIF_BPF_COEFF45 (0x350)
-#define DIF_BPF_COEFF67 (0x354)
-#define DIF_BPF_COEFF89 (0x358)
-#define DIF_BPF_COEFF1011 (0x35c)
-#define DIF_BPF_COEFF1213 (0x360)
-#define DIF_BPF_COEFF1415 (0x364)
-#define DIF_BPF_COEFF1617 (0x368)
-#define DIF_BPF_COEFF1819 (0x36c)
-#define DIF_BPF_COEFF2021 (0x370)
-#define DIF_BPF_COEFF2223 (0x374)
-#define DIF_BPF_COEFF2425 (0x378)
-#define DIF_BPF_COEFF2627 (0x37c)
-#define DIF_BPF_COEFF2829 (0x380)
-#define DIF_BPF_COEFF3031 (0x384)
-#define DIF_BPF_COEFF3233 (0x388)
-#define DIF_BPF_COEFF3435 (0x38c)
-#define DIF_BPF_COEFF36 (0x390)
-
-void cx23885_dif_setup(struct i2c_client *client, u32 ifHz)
-{
- u64 pll_freq;
- u32 pll_freq_word;
-
- v4l_dbg(1, cx25840_debug, client, "%s(%d)\n", __func__, ifHz);
-
- /* Assuming TV */
- /* Calculate the PLL frequency word based on the adjusted ifHz */
- pll_freq = div_u64((u64)ifHz * 268435456, 50000000);
- pll_freq_word = (u32)pll_freq;
-
- cx25840_write4(client, DIF_PLL_FREQ_WORD, pll_freq_word);
-
- /* Round down to the nearest 100KHz */
- ifHz = (ifHz / 100000) * 100000;
-
- if (ifHz < 3000000)
- ifHz = 3000000;
-
- if (ifHz > 16000000)
- ifHz = 16000000;
-
- v4l_dbg(1, cx25840_debug, client, "%s(%d) again\n", __func__, ifHz);
-
- switch (ifHz) {
- case 3000000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00080012);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001e0024);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x001bfff8);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffb4ff50);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfed8fe68);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe24fe34);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfebaffc7);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x014d031f);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x04f0065d);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x07010688);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x04c901d6);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfe00f9d3);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf600f342);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf235f337);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf64efb22);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0105070f);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x0c460fce);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 3100000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00070012);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00220032);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00370026);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xfff0ff91);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff0efe7c);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe01fdcc);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe0afedb);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x00440224);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0434060c);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0738074e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x06090361);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xff99fb39);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf6fef3b6);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf21af2a5);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf573fa33);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0034067d);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x0bfb0fb9);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 3200000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000000);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0004000e);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00200038);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x004c004f);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x002fffdf);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff5cfeb6);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe0dfd92);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd7ffe03);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xff36010a);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x03410575);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x072607d2);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x071804d5);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0134fcb7);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf81ff451);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf223f22e);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf4a7f94b);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xff6405e8);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x0bae0fa4);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 3300000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000ffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00000008);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001a0036);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0056006d);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00670030);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xffbdff10);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe46fd8d);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd25fd4f);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe35ffe0);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0224049f);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x06c9080e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x07ef0627);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x02c9fe45);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf961f513);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf250f1d2);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf3ecf869);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfe930552);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x0b5f0f8f);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 3400000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffd0001);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x000f002c);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0054007d);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0093007c);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0024ff82);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfea6fdbb);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd03fcca);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51feb9);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x00eb0392);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x06270802);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x08880750);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x044dffdb);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfabdf5f8);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2a0f193);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf342f78f);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfdc404b9);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x0b0e0f78);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 3500000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffafff9);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0002001b);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0046007d);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00ad00ba);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00870000);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xff26fe1a);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd1bfc7e);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99fda4);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xffa5025c);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x054507ad);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x08dd0847);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x05b80172);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfc2ef6ff);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf313f170);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf2abf6bd);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfcf6041f);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x0abc0f61);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 3600000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fff3);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfff50006);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x002f006c);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00b200e3);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00dc007e);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xffb9fea0);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd6bfc71);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17fcb1);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfe65010b);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x042d0713);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x08ec0906);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x07020302);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfdaff823);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf3a7f16a);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf228f5f5);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfc2a0384);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x0a670f4a);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 3700000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff7ffef);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe9fff1);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0010004d);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00a100f2);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x011a00f0);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x0053ff44);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfdedfca2);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3fbef);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfd39ffae);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x02ea0638);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x08b50987);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x08230483);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xff39f960);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf45bf180);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf1b8f537);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfb6102e7);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x0a110f32);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 3800000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9ffee);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe1ffdd);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xfff00024);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x007c00e5);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x013a014a);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x00e6fff8);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe98fd0f);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3fb67);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfc32fe54);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x01880525);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x083909c7);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x091505ee);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x00c7fab3);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf52df1b4);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf15df484);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfa9b0249);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x09ba0f19);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 3900000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000000);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffbfff0);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffdeffcf);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffd1fff6);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x004800be);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x01390184);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x016300ac);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xff5efdb1);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17fb23);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb5cfd0d);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x001703e4);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x077b09c4);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x09d2073c);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0251fc18);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf61cf203);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf118f3dc);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf9d801aa);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x09600eff);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 4000000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffefff4);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe1ffc8);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffbaffca);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x000b0082);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x01170198);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01c10152);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0030fe7b);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99fb24);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfac3fbe9);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfea5027f);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x0683097f);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a560867);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x03d2fd89);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf723f26f);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0e8f341);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf919010a);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x09060ee5);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 4100000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0002fffb);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe8ffca);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffacffa4);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffcd0036);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00d70184);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01f601dc);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x00ffff60);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51fb6d);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa6efaf5);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfd410103);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x055708f9);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a9e0969);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0543ff02);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf842f2f5);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0cef2b2);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf85e006b);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x08aa0ecb);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 4200000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00050003);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfff3ffd3);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffaaff8b);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff95ffe5);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0080014a);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01fe023f);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x01ba0050);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe35fbf8);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa62fa3b);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfbf9ff7e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x04010836);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0aa90a3d);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x069f007f);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf975f395);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0cbf231);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf7a9ffcb);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x084c0eaf);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 4300000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0008000a);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0000ffe4);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffb4ff81);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff6aff96);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x001c00f0);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01d70271);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0254013b);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xff36fcbd);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa9ff9c5);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfadbfdfe);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x028c073b);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a750adf);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x07e101fa);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfab8f44e);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0ddf1be);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf6f9ff2b);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x07ed0e94);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 4400000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0009000f);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x000efff8);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffc9ff87);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff52ff54);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xffb5007e);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01860270);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02c00210);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0044fdb2);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb22f997);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf9f2fc90);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x0102060f);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a050b4c);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0902036e);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfc0af51e);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf106f15a);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf64efe8b);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x078d0e77);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 4500000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00080012);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0019000e);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffe5ff9e);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff4fff25);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff560000);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x0112023b);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02f702c0);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x014dfec8);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfbe5f9b3);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf947fb41);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xff7004b9);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x095a0b81);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0a0004d8);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfd65f603);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf144f104);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf5aafdec);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x072b0e5a);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 4600000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00060012);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00200022);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0005ffc1);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff61ff10);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff09ff82);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x008601d7);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02f50340);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0241fff0);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfcddfa19);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8e2fa1e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfde30343);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x08790b7f);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0ad50631);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfec7f6fc);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf198f0bd);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf50dfd4e);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x06c90e3d);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 4700000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000ffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0003000f);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00220030);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0025ffed);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff87ff15);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfed6ff10);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xffed014c);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02b90386);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x03110119);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfdfefac4);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8c6f92f);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfc6701b7);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x07670b44);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0b7e0776);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x002df807);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf200f086);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf477fcb1);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x06650e1e);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 4800000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xffff0009);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001e0038);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x003f001b);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffbcff36);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfec2feb6);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xff5600a5);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0248038d);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b00232);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xff39fbab);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8f4f87f);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfb060020);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x062a0ad2);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0bf908a3);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0192f922);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf27df05e);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf3e8fc14);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x06000e00);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 4900000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffc0002);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00160037);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00510046);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xfff9ff6d);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfed0fe7c);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfecefff0);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x01aa0356);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0413032b);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x007ffcc5);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf96cf812);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf9cefe87);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x04c90a2c);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c4309b4);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x02f3fa4a);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf30ef046);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf361fb7a);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x059b0de0);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 5000000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9fffa);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x000a002d);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00570067);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0037ffb5);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfefffe68);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe62ff3d);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x00ec02e3);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x043503f6);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x01befe05);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfa27f7ee);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf8c6fcf8);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x034c0954);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c5c0aa4);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x044cfb7e);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf3b1f03f);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf2e2fae1);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x05340dc0);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 5100000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fff4);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfffd001e);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0051007b);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x006e0006);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff48fe7c);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe1bfe9a);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x001d023e);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x04130488);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x02e6ff5b);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfb1ef812);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf7f7fb7f);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x01bc084e);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c430b72);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x059afcba);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf467f046);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf26cfa4a);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x04cd0da0);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 5200000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8ffef);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfff00009);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x003f007f);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00980056);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xffa5feb6);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe00fe15);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xff4b0170);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b004d7);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x03e800b9);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfc48f87f);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf768fa23);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0022071f);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0bf90c1b);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x06dafdfd);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf52df05e);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf1fef9b5);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x04640d7f);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 5300000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000ffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9ffee);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe6fff3);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00250072);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00af009c);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x000cff10);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe13fdb8);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe870089);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x031104e1);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x04b8020f);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfd98f92f);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf71df8f0);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfe8805ce);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0b7e0c9c);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0808ff44);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf603f086);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf19af922);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x03fb0d5e);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 5400000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffcffef);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe0ffe0);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00050056);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00b000d1);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0071ff82);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe53fd8c);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfddfff99);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x024104a3);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x054a034d);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xff01fa1e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf717f7ed);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfcf50461);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0ad50cf4);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0921008d);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf6e7f0bd);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf13ff891);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x03920d3b);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 5500000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffffff3);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffdeffd1);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffe5002f);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x009c00ed);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00cb0000);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfebafd94);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd61feb0);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x014d0422);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x05970464);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0074fb41);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf759f721);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfb7502de);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0a000d21);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0a2201d4);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf7d9f104);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf0edf804);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x03280d19);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 5600000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0003fffa);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe3ffc9);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffc90002);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x007500ef);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x010e007e);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xff3dfdcf);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd16fddd);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x00440365);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x059b0548);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x01e3fc90);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf7dff691);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfa0f014d);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x09020d23);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0b0a0318);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf8d7f15a);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf0a5f779);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x02bd0cf6);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 5700000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00060001);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffecffc9);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffb4ffd4);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x004000d5);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x013600f0);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xffd3fe39);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd04fd31);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xff360277);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x055605ef);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x033efdfe);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf8a5f642);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf8cbffb6);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x07e10cfb);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0bd50456);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf9dff1be);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf067f6f2);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x02520cd2);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 5800000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00080009);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfff8ffd2);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffaaffac);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x000200a3);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x013c014a);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x006dfec9);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd2bfcb7);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe350165);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x04cb0651);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0477ff7e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf9a5f635);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf7b1fe20);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x069f0ca8);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0c81058b);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xfaf0f231);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf033f66d);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x01e60cae);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 5900000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0009000e);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0005ffe1);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffacff90);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffc5005f);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x01210184);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x00fcff72);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd8afc77);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51003f);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x04020669);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x05830103);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfad7f66b);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf6c8fc93);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x05430c2b);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d0d06b5);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xfc08f2b2);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf00af5ec);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x017b0c89);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 6000000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00070012);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0012fff5);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffbaff82);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff8e000f);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00e80198);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01750028);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe18fc75);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99ff15);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x03050636);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0656027f);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfc32f6e2);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf614fb17);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x03d20b87);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d7707d2);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xfd26f341);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xefeaf56f);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x010f0c64);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 6100000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0000);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00050012);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001c000b);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffd1ff84);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff66ffbe);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00960184);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01cd00da);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfeccfcb2);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17fdf9);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x01e005bc);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x06e703e4);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfdabf798);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf599f9b3);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x02510abd);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0dbf08df);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xfe48f3dc);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xefd5f4f6);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x00a20c3e);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 6200000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0002000f);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0021001f);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xfff0ff97);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff50ff74);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0034014a);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01fa0179);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xff97fd2a);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3fcfa);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x00a304fe);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x07310525);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xff37f886);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf55cf86e);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x00c709d0);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0de209db);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xff6df484);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xefcbf481);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0x00360c18);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 6300000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffe000a);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0021002f);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0010ffb8);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff50ff3b);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xffcc00f0);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01fa01fa);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0069fdd4);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3fc26);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xff5d0407);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x07310638);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x00c9f9a8);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf55cf74e);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xff3908c3);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0de20ac3);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0093f537);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xefcbf410);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xffca0bf2);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 6400000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffb0003);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001c0037);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x002fffe2);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff66ff17);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff6a007e);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01cd0251);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0134fea5);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17fb8b);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfe2002e0);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x06e70713);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x0255faf5);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf599f658);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfdaf0799);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0dbf0b96);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x01b8f5f5);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xefd5f3a3);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xff5e0bca);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 6500000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9fffb);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00120037);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00460010);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff8eff0f);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff180000);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01750276);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x01e8ff8d);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99fb31);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfcfb0198);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x065607ad);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x03cefc64);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf614f592);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfc2e0656);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d770c52);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x02daf6bd);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xefeaf33b);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xfef10ba3);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 6600000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff7fff5);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0005002f);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0054003c);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffc5ff22);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfedfff82);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x00fc0267);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0276007e);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51fb1c);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfbfe003e);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x05830802);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x0529fdec);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf6c8f4fe);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfabd04ff);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d0d0cf6);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x03f8f78f);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf00af2d7);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xfe850b7b);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 6700000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000ffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fff0);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfff80020);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00560060);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0002ff4e);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfec4ff10);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x006d0225);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02d50166);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe35fb4e);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb35fee1);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0477080e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x065bff82);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf7b1f4a0);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf9610397);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0c810d80);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0510f869);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf033f278);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xfe1a0b52);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 6800000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010000);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffaffee);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffec000c);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x004c0078);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0040ff8e);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfecafeb6);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xffd301b6);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02fc0235);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xff36fbc5);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfaaafd90);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x033e07d2);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x075b011b);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf8cbf47a);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf81f0224);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0bd50def);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0621f94b);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf067f21e);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xfdae0b29);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 6900000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffdffef);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe3fff6);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0037007f);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0075ffdc);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfef2fe7c);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xff3d0122);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02ea02dd);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0044fc79);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa65fc5d);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x01e3074e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x082102ad);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfa0ff48c);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf6fe00a9);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0b0a0e43);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0729fa33);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf0a5f1c9);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xfd430b00);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 7000000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0001fff3);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffdeffe2);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x001b0076);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x009c002d);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff35fe68);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfeba0076);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x029f0352);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x014dfd60);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa69fb53);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x00740688);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x08a7042d);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfb75f4d6);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf600ff2d);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0a220e7a);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0827fb22);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf0edf17a);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xfcd80ad6);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 7100000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0004fff9);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe0ffd2);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xfffb005e);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00b0007a);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff8ffe7c);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe53ffc1);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0221038c);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0241fe6e);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfab6fa80);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xff010587);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x08e90590);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfcf5f556);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf52bfdb3);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x09210e95);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0919fc15);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf13ff12f);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xfc6e0aab);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 7200000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00070000);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe6ffc9);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffdb0039);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00af00b8);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfff4feb6);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe13ff10);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x01790388);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0311ff92);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb48f9ed);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfd980453);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x08e306cd);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfe88f60a);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf482fc40);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x08080e93);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x09fdfd0c);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf19af0ea);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xfc050a81);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 7300000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00080008);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfff0ffc9);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffc1000d);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x009800e2);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x005bff10);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe00fe74);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x00b50345);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b000bc);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfc18f9a1);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfc4802f9);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x089807dc);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0022f6f0);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf407fada);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x06da0e74);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0ad3fe06);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf1fef0ab);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xfb9c0a55);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 7400000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0008000e);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfffdffd0);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffafffdf);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x006e00f2);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00b8ff82);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe1bfdf8);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xffe302c8);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x041301dc);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfd1af99e);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfb1e0183);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x080908b5);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x01bcf801);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf3bdf985);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x059a0e38);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0b99ff03);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf26cf071);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xfb330a2a);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 7500000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0000);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00070011);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x000affdf);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffa9ffb5);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x003700e6);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x01010000);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe62fda8);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xff140219);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x043502e1);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfe42f9e6);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfa270000);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x073a0953);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x034cf939);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf3a4f845);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x044c0de1);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0c4f0000);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf2e2f03c);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xfacc09fe);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 7600000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffffffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00040012);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0016fff3);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffafff95);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xfff900c0);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0130007e);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfecefd89);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe560146);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x041303bc);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xff81fa76);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf96cfe7d);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x063209b1);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x04c9fa93);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf3bdf71e);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x02f30d6e);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0cf200fd);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf361f00e);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xfa6509d1);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 7700000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00010010);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001e0008);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffc1ff84);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffbc0084);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x013e00f0);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xff56fd9f);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfdb8005c);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b00460);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x00c7fb45);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8f4fd07);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x04fa09ce);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x062afc07);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf407f614);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x01920ce0);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0d8301fa);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf3e8efe5);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xfa0009a4);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 7800000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffd000b);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0022001d);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffdbff82);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff870039);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x012a014a);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xffedfde7);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd47ff6b);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x031104c6);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0202fc4c);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8c6fbad);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x039909a7);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0767fd8e);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf482f52b);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x002d0c39);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0e0002f4);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf477efc2);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf99b0977);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 7900000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffa0004);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0020002d);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xfffbff91);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff61ffe8);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00f70184);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x0086fe5c);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd0bfe85);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x024104e5);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0323fd7d);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8e2fa79);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x021d093f);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0879ff22);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf52bf465);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfec70b79);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0e6803eb);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf50defa5);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf937094a);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 8000000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fffd);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00190036);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x001bffaf);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff4fff99);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00aa0198);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x0112fef3);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd09fdb9);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x014d04be);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x041bfecc);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf947f978);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x00900897);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x095a00b9);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf600f3c5);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfd650aa3);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0ebc04de);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf5aaef8e);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf8d5091c);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 8100000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000ffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff7fff6);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x000e0038);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0037ffd7);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff52ff56);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x004b0184);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x0186ffa1);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd40fd16);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x00440452);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x04de0029);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf9f2f8b2);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfefe07b5);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a05024d);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf6fef34d);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfc0a09b8);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0efa05cd);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf64eef7d);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf87308ed);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 8200000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010000);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fff0);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00000031);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x004c0005);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff6aff27);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xffe4014a);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01d70057);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfdacfca6);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xff3603a7);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x05610184);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfadbf82e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfd74069f);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a7503d6);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf81ff2ff);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfab808b9);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0f2306b5);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf6f9ef72);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf81308bf);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 8300000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffbffee);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfff30022);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00560032);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff95ff10);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff8000f0);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01fe0106);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe46fc71);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe3502c7);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x059e02ce);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfbf9f7f2);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfbff055b);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0aa9054c);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf961f2db);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf97507aa);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0f350797);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf7a9ef6d);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf7b40890);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 8400000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffeffee);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe8000f);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00540058);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffcdff14);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff29007e);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01f6019e);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xff01fc7c);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd5101bf);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x059203f6);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfd41f7fe);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfaa903f3);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a9e06a9);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfabdf2e2);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf842068b);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0f320871);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf85eef6e);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf7560860);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 8500000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0002fff2);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe1fff9);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00460073);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x000bff34);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfee90000);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01c10215);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xffd0fcc5);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99009d);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x053d04f1);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfea5f853);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf97d0270);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a5607e4);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfc2ef314);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf723055f);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0f180943);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf919ef75);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf6fa0830);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 8600000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0005fff8);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffdeffe4);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x002f007f);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0048ff6b);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfec7ff82);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x0163025f);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x00a2fd47);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17ff73);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x04a405b2);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0017f8ed);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf88500dc);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x09d208f9);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfdaff370);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf61c0429);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0ee80a0b);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xf9d8ef82);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf6a00800);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 8700000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0007ffff);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe1ffd4);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0010007a);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x007cffb2);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfec6ff10);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x00e60277);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0168fdf9);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3fe50);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x03ce0631);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0188f9c8);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf7c7ff43);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x091509e3);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xff39f3f6);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf52d02ea);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0ea30ac9);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfa9bef95);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf64607d0);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 8800000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00090007);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe9ffca);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xfff00065);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00a10003);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfee6feb6);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x0053025b);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0213fed0);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3fd46);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x02c70668);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x02eafadb);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf74bfdae);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x08230a9c);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x00c7f4a3);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf45b01a6);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0e480b7c);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfb61efae);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf5ef079f);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 8900000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0000);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0008000d);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfff5ffc8);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffd10043);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00b20053);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff24fe7c);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xffb9020c);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0295ffbb);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17fc64);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x019b0654);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x042dfc1c);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf714fc2a);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x07020b21);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0251f575);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf3a7005e);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0dd80c24);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfc2aefcd);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf599076e);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 9000000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffffffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00060011);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0002ffcf);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffba0018);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00ad009a);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff79fe68);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xff260192);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02e500ab);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99fbb6);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x005b05f7);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0545fd81);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf723fabf);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x05b80b70);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x03d2f669);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf313ff15);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0d550cbf);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfcf6eff2);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf544073d);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 9100000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00030012);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x000fffdd);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffacffea);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x009300cf);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xffdcfe7c);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfea600f7);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02fd0190);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51fb46);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xff150554);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0627fefd);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf778f978);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x044d0b87);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0543f77d);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2a0fdcf);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0cbe0d4e);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfdc4f01d);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf4f2070b);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 9200000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00000010);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001afff0);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffaaffbf);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x006700ed);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0043feb6);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe460047);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02db0258);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe35fb1b);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfddc0473);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x06c90082);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf811f85e);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x02c90b66);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x069ff8ad);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf250fc8d);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0c140dcf);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfe93f04d);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf4a106d9);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 9300000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffc000c);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00200006);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffb4ff9c);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x002f00ef);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00a4ff10);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe0dff92);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x028102f7);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xff36fb37);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfcbf035e);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x07260202);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf8e8f778);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x01340b0d);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x07e1f9f4);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf223fb51);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0b590e42);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xff64f083);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf45206a7);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 9400000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff90005);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0022001a);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffc9ff86);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xfff000d7);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00f2ff82);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe01fee5);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x01f60362);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0044fb99);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfbcc0222);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x07380370);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf9f7f6cc);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xff990a7e);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0902fb50);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf21afa1f);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0a8d0ea6);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0034f0bf);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf4050675);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 9500000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fffe);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001e002b);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffe5ff81);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffb400a5);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x01280000);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe24fe50);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x01460390);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x014dfc3a);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb1000ce);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x070104bf);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfb37f65f);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfe0009bc);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0a00fcbb);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf235f8f8);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x09b20efc);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0105f101);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf3ba0642);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 9600000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0001ffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fff7);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00150036);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0005ff8c);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff810061);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x013d007e);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe71fddf);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x007c0380);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0241fd13);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa94ff70);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x068005e2);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfc9bf633);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfc7308ca);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0ad5fe30);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf274f7e0);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x08c90f43);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x01d4f147);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf371060f);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 9700000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9fff1);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00090038);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0025ffa7);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff5e0012);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x013200f0);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfee3fd9b);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xffaa0331);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0311fe15);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa60fe18);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x05bd06d1);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfe1bf64a);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfafa07ae);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0b7effab);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2d5f6d7);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x07d30f7a);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x02a3f194);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf32905dc);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 9800000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffcffee);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfffb0032);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x003fffcd);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff4effc1);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0106014a);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xff6efd8a);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfedd02aa);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b0ff34);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa74fcd7);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x04bf0781);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xffaaf6a3);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf99e066b);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0bf90128);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf359f5e1);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x06d20fa2);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0370f1e5);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf2e405a8);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 9900000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xffffffee);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffef0024);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0051fffa);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff54ff77);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00be0184);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x0006fdad);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe2701f3);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0413005e);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfad1fbba);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x039007ee);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x013bf73d);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf868050a);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c4302a1);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf3fdf4fe);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x05c70fba);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x043bf23c);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf2a10575);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 10000000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0003fff1);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe50011);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00570027);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff70ff3c);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00620198);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x009efe01);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd95011a);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x04350183);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb71fad0);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x023c0812);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x02c3f811);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf75e0390);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c5c0411);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf4c1f432);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x04b30fc1);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0503f297);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf2610541);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 10100000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0006fff7);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffdffffc);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00510050);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff9dff18);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfffc0184);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x0128fe80);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd32002e);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x04130292);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfc4dfa21);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x00d107ee);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x0435f91c);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf6850205);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c430573);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf5a1f37d);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x03990fba);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x05c7f2f8);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf222050d);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 10200000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0008fffe);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffdfffe7);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x003f006e);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffd6ff0f);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff96014a);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x0197ff1f);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd05ff3e);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b0037c);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfd59f9b7);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xff5d0781);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x0585fa56);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf5e4006f);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0bf906c4);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf69df2e0);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x02790fa2);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0688f35d);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf1e604d8);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 10300000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00090005);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe4ffd6);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0025007e);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0014ff20);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff3c00f0);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01e1ffd0);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd12fe5c);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x03110433);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfe88f996);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfdf106d1);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x06aafbb7);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf57efed8);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0b7e07ff);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf7b0f25e);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x01560f7a);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0745f3c7);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf1ac04a4);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 10400000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffffffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0008000c);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffedffcb);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0005007d);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0050ff4c);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfef6007e);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01ff0086);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd58fd97);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x024104ad);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xffcaf9c0);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfc9905e2);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x079afd35);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf555fd46);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0ad50920);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf8d9f1f6);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x00310f43);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x07fdf435);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf174046f);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 10500000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00050011);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfffaffc8);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffe5006b);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0082ff8c);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfecc0000);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01f00130);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfdd2fcfc);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x014d04e3);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x010efa32);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfb6404bf);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x084efec5);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf569fbc2);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0a000a23);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfa15f1ab);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xff0b0efc);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x08b0f4a7);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf13f043a);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 10600000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00020012);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0007ffcd);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffc9004c);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00a4ffd9);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfec3ff82);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01b401c1);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe76fc97);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x004404d2);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0245fae8);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfa5f0370);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x08c1005f);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf5bcfa52);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x09020b04);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfb60f17b);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xfde70ea6);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x095df51e);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf10c0405);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 10700000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xffff0011);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0014ffdb);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffb40023);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00b2002a);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfedbff10);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x0150022d);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xff38fc6f);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xff36047b);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x035efbda);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf9940202);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x08ee01f5);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf649f8fe);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x07e10bc2);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfcb6f169);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xfcc60e42);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0a04f599);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf0db03d0);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 10800000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffb000d);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001dffed);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffaafff5);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00aa0077);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff13feb6);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x00ce026b);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x000afc85);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe3503e3);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x044cfcfb);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf90c0082);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x08d5037f);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf710f7cc);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x069f0c59);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfe16f173);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xfbaa0dcf);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0aa5f617);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf0ad039b);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 10900000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff90006);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00210003);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffacffc8);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x008e00b6);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff63fe7c);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x003a0275);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x00dafcda);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd510313);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0501fe40);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8cbfefd);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x087604f0);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf80af6c2);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x05430cc8);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xff7af19a);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xfa940d4e);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0b3ff699);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf0810365);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 11000000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0001ffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8ffff);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00210018);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffbaffa3);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x006000e1);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xffc4fe68);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xffa0024b);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x019afd66);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc990216);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0575ff99);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8d4fd81);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x07d40640);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf932f5e6);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x03d20d0d);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x00dff1de);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf9860cbf);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0bd1f71e);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf058032f);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 11100000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010000);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fff8);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001b0029);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffd1ff8a);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x002600f2);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x002cfe7c);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xff0f01f0);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x023bfe20);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc1700fa);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x05a200f7);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf927fc1c);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x06f40765);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfa82f53b);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x02510d27);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0243f23d);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf8810c24);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0c5cf7a7);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf03102fa);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 11200000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffafff2);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00110035);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xfff0ff81);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffe700e7);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x008ffeb6);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe94016d);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02b0fefb);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3ffd1);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x05850249);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf9c1fadb);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x05de0858);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfbf2f4c4);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x00c70d17);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x03a0f2b8);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf7870b7c);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0cdff833);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf00d02c4);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 11300000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffdffee);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00040038);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0010ff88);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffac00c2);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00e2ff10);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe3900cb);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02f1ffe9);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3feaa);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x05210381);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfa9cf9c8);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x04990912);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfd7af484);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xff390cdb);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x04f4f34d);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf69a0ac9);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0d5af8c1);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xefec028e);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 11400000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0000ffee);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfff60033);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x002fff9f);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff7b0087);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x011eff82);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe080018);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02f900d8);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17fd96);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x04790490);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfbadf8ed);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x032f098e);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xff10f47d);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfdaf0c75);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x063cf3fc);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf5ba0a0b);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0dccf952);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xefcd0258);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 11500000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0004fff1);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffea0026);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0046ffc3);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff5a003c);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x013b0000);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe04ff63);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02c801b8);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99fca6);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0397056a);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfcecf853);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x01ad09c9);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x00acf4ad);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfc2e0be7);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0773f4c2);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf4e90943);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0e35f9e6);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xefb10221);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 11600000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0007fff6);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe20014);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0054ffee);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff4effeb);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0137007e);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe2efebb);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0260027a);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51fbe6);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x02870605);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfe4af7fe);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x001d09c1);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0243f515);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfabd0b32);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0897f59e);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf4280871);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0e95fa7c);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef9701eb);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 11700000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0008fffd);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffdeffff);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0056001d);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff57ff9c);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x011300f0);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe82fe2e);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x01ca0310);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe35fb62);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0155065a);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xffbaf7f2);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfe8c0977);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x03cef5b2);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf9610a58);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x09a5f68f);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf3790797);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0eebfb14);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef8001b5);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 11800000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0000);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00080004);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe0ffe9);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x004c0047);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff75ff58);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00d1014a);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfef9fdc8);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0111036f);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xff36fb21);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x00120665);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x012df82e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfd0708ec);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0542f682);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf81f095c);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0a9af792);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf2db06b5);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0f38fbad);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef6c017e);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 11900000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffffffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0007000b);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe7ffd8);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00370068);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffa4ff28);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00790184);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xff87fd91);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x00430392);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0044fb26);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfece0626);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0294f8b2);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfb990825);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0698f77f);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf6fe0842);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0b73f8a7);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf25105cd);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0f7bfc48);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef5a0148);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 12000000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00050010);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfff2ffcc);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x001b007b);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffdfff10);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00140198);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x0020fd8e);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xff710375);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x014dfb73);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfd9a059f);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x03e0f978);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfa4e0726);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x07c8f8a7);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf600070c);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0c2ff9c9);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf1db04de);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0fb4fce5);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef4b0111);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 12100000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00010012);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffffffc8);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xfffb007e);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x001dff14);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xffad0184);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x00b7fdbe);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfea9031b);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0241fc01);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfc8504d6);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0504fa79);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf93005f6);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x08caf9f2);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf52b05c0);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0ccbfaf9);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf17903eb);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0fe3fd83);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef3f00db);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 12200000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffe0011);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x000cffcc);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffdb0071);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0058ff32);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff4f014a);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x013cfe1f);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfdfb028a);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0311fcc9);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb9d03d6);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x05f4fbad);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf848049d);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0999fb5b);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf4820461);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d46fc32);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf12d02f4);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x1007fe21);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef3600a4);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 12300000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffa000e);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0017ffd9);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffc10055);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0088ff68);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff0400f0);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01a6fea7);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd7501cc);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b0fdc0);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfaef02a8);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x06a7fd07);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf79d0326);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a31fcda);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf40702f3);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d9ffd72);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0f601fa);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x1021fec0);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef2f006d);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 12400000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0001ffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff80007);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001fffeb);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffaf002d);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00a8ffb0);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfed3007e);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01e9ff4c);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd2000ee);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0413fed8);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa82015c);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0715fe7d);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf7340198);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a8dfe69);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf3bd017c);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0dd5feb8);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0d500fd);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x1031ff60);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef2b0037);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 12500000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010000);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff70000);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00220000);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffa90000);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00b30000);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfec20000);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x02000000);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd030000);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x04350000);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa5e0000);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x073b0000);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf7110000);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0aac0000);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf3a40000);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0de70000);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0c90000);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x10360000);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef290000);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 12600000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fff9);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001f0015);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffafffd3);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00a80050);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfed3ff82);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01e900b4);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd20ff12);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x04130128);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa82fea4);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x07150183);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf734fe68);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a8d0197);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf3bdfe84);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0dd50148);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0d5ff03);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x103100a0);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef2bffc9);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 12700000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffafff2);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00170027);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffc1ffab);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00880098);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff04ff10);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01a60159);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd75fe34);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b00240);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfaeffd58);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x06a702f9);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf79dfcda);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a310326);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf407fd0d);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d9f028e);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0f6fe06);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x10210140);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef2fff93);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 12800000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffeffef);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x000c0034);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffdbff8f);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x005800ce);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff4ffeb6);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x013c01e1);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfdfbfd76);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x03110337);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb9dfc2a);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x05f40453);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf848fb63);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x099904a5);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf482fb9f);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d4603ce);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf12dfd0c);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x100701df);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef36ff5c);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 12900000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0001ffee);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffff0038);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xfffbff82);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x001d00ec);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xffadfe7c);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x00b70242);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfea9fce5);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x024103ff);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfc85fb2a);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x05040587);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf930fa0a);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x08ca060e);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf52bfa40);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0ccb0507);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf179fc15);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0fe3027d);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef3fff25);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 13000000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0005fff0);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfff20034);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x001bff85);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffdf00f0);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0014fe68);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x00200272);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xff71fc8b);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x014d048d);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfd9afa61);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x03e00688);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfa4ef8da);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x07c80759);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf600f8f4);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0c2f0637);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf1dbfb22);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0fb4031b);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef4bfeef);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 13100000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0007fff5);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe70028);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0037ff98);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffa400d8);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0079fe7c);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xff87026f);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0043fc6e);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x004404da);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfecef9da);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0294074e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfb99f7db);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x06980881);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf6fef7be);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0b730759);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf251fa33);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0f7b03b8);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef5afeb8);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 13200000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0000);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0008fffc);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe00017);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x004cffb9);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff7500a8);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00d1feb6);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfef90238);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0111fc91);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xff3604df);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0012f99b);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x012d07d2);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfd07f714);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0542097e);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf81ff6a4);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x0a9a086e);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf2dbf94b);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0f380453);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef6cfe82);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 13300000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffffffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00080003);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffde0001);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0056ffe3);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff570064);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0113ff10);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe8201d2);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x01cafcf0);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe35049e);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0155f9a6);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xffba080e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfe8cf689);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x03ce0a4e);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xf961f5a8);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x09a50971);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf379f869);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0eeb04ec);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef80fe4b);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 13400000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0007000a);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe2ffec);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00540012);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff4e0015);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0137ff82);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe2e0145);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0260fd86);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51041a);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0287f9fb);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfe4a0802);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x001df63f);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x02430aeb);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfabdf4ce);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x08970a62);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf428f78f);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0e950584);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xef97fe15);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 13500000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0004000f);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffeaffda);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0046003d);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff5affc4);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x013b0000);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe04009d);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02c8fe48);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99035a);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0397fa96);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfcec07ad);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x01adf637);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x00ac0b53);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfc2ef419);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x07730b3e);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf4e9f6bd);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0e35061a);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xefb1fddf);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 13600000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00000012);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfff6ffcd);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x002f0061);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff7bff79);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x011e007e);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe08ffe8);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02f9ff28);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17026a);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0479fb70);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfbad0713);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x032ff672);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xff100b83);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xfdaff38b);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x063c0c04);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf5baf5f5);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0dcc06ae);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xefcdfda8);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 13700000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffd0012);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0004ffc8);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00100078);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffacff3e);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00e200f0);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe39ff35);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02f10017);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd30156);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0521fc7f);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfa9c0638);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x0499f6ee);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfd7a0b7c);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0xff39f325);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x04f40cb3);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf69af537);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0d5a073f);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xefecfd72);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 13800000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0001fffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffa000e);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0011ffcb);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xfff0007f);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffe7ff19);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x008f014a);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe94fe93);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02b00105);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3002f);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x0585fdb7);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf9c10525);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x05def7a8);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfbf20b3c);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x00c7f2e9);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x03a00d48);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf787f484);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0cdf07cd);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf00dfd3c);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 13900000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010000);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff80008);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001bffd7);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffd10076);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0026ff0e);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x002c0184);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xff0ffe10);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x023b01e0);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17ff06);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x05a2ff09);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf92703e4);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x06f4f89b);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfa820ac5);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0251f2d9);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x02430dc3);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf881f3dc);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0c5c0859);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf031fd06);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 14000000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff80001);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0021ffe8);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffba005d);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0060ff1f);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xffc40198);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xffa0fdb5);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x019a029a);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99fdea);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x05750067);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8d4027f);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x07d4f9c0);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf9320a1a);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x03d2f2f3);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0x00df0e22);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xf986f341);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0bd108e2);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf058fcd1);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 14100000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9fffa);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0021fffd);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffac0038);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x008eff4a);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff630184);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x003afd8b);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x00da0326);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51fced);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x050101c0);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8cb0103);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x0876fb10);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf80a093e);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0543f338);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xff7a0e66);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xfa94f2b2);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0b3f0967);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf081fc9b);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 14200000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffbfff3);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001d0013);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffaa000b);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00aaff89);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff13014a);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x00cefd95);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x000a037b);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe35fc1d);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x044c0305);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf90cff7e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x08d5fc81);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf7100834);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x069ff3a7);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfe160e8d);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xfbaaf231);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0aa509e9);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf0adfc65);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 14300000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xffffffef);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00140025);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffb4ffdd);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00b2ffd6);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfedb00f0);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x0150fdd3);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xff380391);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xff36fb85);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x035e0426);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xf994fdfe);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x08eefe0b);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf6490702);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x07e1f43e);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfcb60e97);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xfcc6f1be);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x0a040a67);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf0dbfc30);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 14400000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0002ffee);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00070033);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffc9ffb4);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00a40027);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfec3007e);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01b4fe3f);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe760369);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0044fb2e);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x02450518);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfa5ffc90);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x08c1ffa1);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf5bc05ae);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0902f4fc);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfb600e85);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xfde7f15a);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x095d0ae2);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf10cfbfb);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 14500000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0005ffef);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfffa0038);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffe5ff95);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00820074);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfecc0000);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01f0fed0);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfdd20304);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x014dfb1d);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x010e05ce);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfb64fb41);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x084e013b);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf569043e);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0a00f5dd);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xfa150e55);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0xff0bf104);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x08b00b59);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf13ffbc6);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 14600000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0008fff4);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffed0035);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0005ff83);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x005000b4);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfef6ff82);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01ffff7a);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd580269);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0241fb53);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xffca0640);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfc99fa1e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x079a02cb);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf55502ba);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0ad5f6e0);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf8d90e0a);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0031f0bd);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x07fd0bcb);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf174fb91);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 14700000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffffffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0009fffb);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe4002a);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0025ff82);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x001400e0);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff3cff10);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01e10030);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd1201a4);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0311fbcd);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfe88066a);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xfdf1f92f);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x06aa0449);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf57e0128);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0b7ef801);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf7b00da2);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0156f086);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x07450c39);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf1acfb5c);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 14800000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00080002);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffdf0019);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x003fff92);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffd600f1);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff96feb6);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x019700e1);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd0500c2);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b0fc84);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfd590649);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0xff5df87f);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x058505aa);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf5e4ff91);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0bf9f93c);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf69d0d20);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0279f05e);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x06880ca3);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf1e6fb28);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 14900000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x00060009);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffdf0004);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0051ffb0);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff9d00e8);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xfffcfe7c);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x01280180);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd32ffd2);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0413fd6e);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfc4d05df);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x00d1f812);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x043506e4);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf685fdfb);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c43fa8d);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf5a10c83);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0399f046);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x05c70d08);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf222faf3);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 15000000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0003000f);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffe5ffef);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x0057ffd9);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff7000c4);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0062fe68);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x009e01ff);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd95fee6);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0435fe7d);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb710530);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x023cf7ee);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x02c307ef);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf75efc70);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c5cfbef);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf4c10bce);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x04b3f03f);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x05030d69);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf261fabf);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 15100000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xffff0012);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xffefffdc);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00510006);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff540089);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00befe7c);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0x00060253);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe27fe0d);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x0413ffa2);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfad10446);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0390f812);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0x013b08c3);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf868faf6);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c43fd5f);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf3fd0b02);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x05c7f046);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x043b0dc4);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf2a1fa8b);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 15200000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0001fffe);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffc0012);
- cx25840_write4(client, DIF_BPF_COEFF45, 0xfffbffce);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x003f0033);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff4e003f);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0106feb6);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xff6e0276);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xfeddfd56);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b000cc);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa740329);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x04bff87f);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xffaa095d);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xf99ef995);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0bf9fed8);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf3590a1f);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x06d2f05e);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x03700e1b);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf2e4fa58);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 15300000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x0001ffff);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9000f);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0009ffc8);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00250059);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff5effee);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0132ff10);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfee30265);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0xffaafccf);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x031101eb);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa6001e8);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x05bdf92f);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfe1b09b6);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfafaf852);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0b7e0055);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2d50929);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x07d3f086);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x02a30e6c);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf329fa24);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 15400000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00010001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff80009);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0015ffca);
- cx25840_write4(client, DIF_BPF_COEFF67, 0x00050074);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xff81ff9f);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x013dff82);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe710221);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x007cfc80);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x024102ed);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa940090);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0680fa1e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfc9b09cd);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfc73f736);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0ad501d0);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2740820);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x08c9f0bd);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x01d40eb9);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf371f9f1);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 15500000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff80002);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001effd5);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffe5007f);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xffb4ff5b);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x01280000);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe2401b0);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0146fc70);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x014d03c6);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb10ff32);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0701fb41);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xfb3709a1);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xfe00f644);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x0a000345);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2350708);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x09b2f104);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x01050eff);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf3baf9be);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 15600000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9fffb);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0022ffe6);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffc9007a);
- cx25840_write4(client, DIF_BPF_COEFF89, 0xfff0ff29);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00f2007e);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe01011b);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x01f6fc9e);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0x00440467);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfbccfdde);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0738fc90);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf9f70934);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0xff99f582);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x090204b0);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf21a05e1);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0a8df15a);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0x00340f41);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf405f98b);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 15700000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0xfffcfff4);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x0020fffa);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffb40064);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x002fff11);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x00a400f0);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe0d006e);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x0281fd09);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xff3604c9);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfcbffca2);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0726fdfe);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf8e80888);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x0134f4f3);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x07e1060c);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf22304af);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0b59f1be);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xff640f7d);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf452f959);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 15800000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0000fff0);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x001a0010);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffaa0041);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0067ff13);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0x0043014a);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe46ffb9);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02dbfda8);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe3504e5);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xfddcfb8d);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x06c9ff7e);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf81107a2);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x02c9f49a);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x069f0753);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2500373);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0c14f231);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfe930fb3);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf4a1f927);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 15900000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0002);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0003ffee);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x000f0023);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffac0016);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x0093ff31);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xffdc0184);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xfea6ff09);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02fdfe70);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd5104ba);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0xff15faac);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x06270103);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf7780688);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x044df479);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x05430883);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2a00231);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0cbef2b2);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfdc40fe3);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf4f2f8f5);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
-
- case 16000000:
- cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0001);
- cx25840_write4(client, DIF_BPF_COEFF23, 0x0006ffef);
- cx25840_write4(client, DIF_BPF_COEFF45, 0x00020031);
- cx25840_write4(client, DIF_BPF_COEFF67, 0xffbaffe8);
- cx25840_write4(client, DIF_BPF_COEFF89, 0x00adff66);
- cx25840_write4(client, DIF_BPF_COEFF1011, 0xff790198);
- cx25840_write4(client, DIF_BPF_COEFF1213, 0xff26fe6e);
- cx25840_write4(client, DIF_BPF_COEFF1415, 0x02e5ff55);
- cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99044a);
- cx25840_write4(client, DIF_BPF_COEFF1819, 0x005bfa09);
- cx25840_write4(client, DIF_BPF_COEFF2021, 0x0545027f);
- cx25840_write4(client, DIF_BPF_COEFF2223, 0xf7230541);
- cx25840_write4(client, DIF_BPF_COEFF2425, 0x05b8f490);
- cx25840_write4(client, DIF_BPF_COEFF2627, 0x03d20997);
- cx25840_write4(client, DIF_BPF_COEFF2829, 0xf31300eb);
- cx25840_write4(client, DIF_BPF_COEFF3031, 0x0d55f341);
- cx25840_write4(client, DIF_BPF_COEFF3233, 0xfcf6100e);
- cx25840_write4(client, DIF_BPF_COEFF3435, 0xf544f8c3);
- cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000);
- break;
- }
-}
-
-static void cx23888_std_setup(struct i2c_client *client)
-{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- v4l2_std_id std = state->std;
- u32 ifHz;
-
- cx25840_write4(client, 0x478, 0x6628021F);
- cx25840_write4(client, 0x400, 0x0);
- cx25840_write4(client, 0x4b4, 0x20524030);
- cx25840_write4(client, 0x47c, 0x010a8263);
-
- if (std & V4L2_STD_NTSC) {
- v4l_dbg(1, cx25840_debug, client, "%s() Selecting NTSC",
- __func__);
-
- /* Horiz / vert timing */
- cx25840_write4(client, 0x428, 0x1e1e601a);
- cx25840_write4(client, 0x424, 0x5b2d007a);
-
- /* DIF NTSC */
- cx25840_write4(client, 0x304, 0x6503bc0c);
- cx25840_write4(client, 0x308, 0xbd038c85);
- cx25840_write4(client, 0x30c, 0x1db4640a);
- cx25840_write4(client, 0x310, 0x00008800);
- cx25840_write4(client, 0x314, 0x44400400);
- cx25840_write4(client, 0x32c, 0x0c800800);
- cx25840_write4(client, 0x330, 0x27000100);
- cx25840_write4(client, 0x334, 0x1f296e1f);
- cx25840_write4(client, 0x338, 0x009f50c1);
- cx25840_write4(client, 0x340, 0x1befbf06);
- cx25840_write4(client, 0x344, 0x000035e8);
-
- /* DIF I/F */
- ifHz = 5400000;
-
- } else {
- v4l_dbg(1, cx25840_debug, client, "%s() Selecting PAL-BG",
- __func__);
-
- /* Horiz / vert timing */
- cx25840_write4(client, 0x428, 0x28244024);
- cx25840_write4(client, 0x424, 0x5d2d0084);
-
- /* DIF */
- cx25840_write4(client, 0x304, 0x6503bc0c);
- cx25840_write4(client, 0x308, 0xbd038c85);
- cx25840_write4(client, 0x30c, 0x1db4640a);
- cx25840_write4(client, 0x310, 0x00008800);
- cx25840_write4(client, 0x314, 0x44400600);
- cx25840_write4(client, 0x32c, 0x0c800800);
- cx25840_write4(client, 0x330, 0x27000100);
- cx25840_write4(client, 0x334, 0x213530ec);
- cx25840_write4(client, 0x338, 0x00a65ba8);
- cx25840_write4(client, 0x340, 0x1befbf06);
- cx25840_write4(client, 0x344, 0x000035e8);
-
- /* DIF I/F */
- ifHz = 6000000;
- }
-
- cx23885_dif_setup(client, ifHz);
-
- /* Explicitly ensure the inputs are reconfigured after
- * a standard change.
- */
- set_input(client, state->vid_input, state->aud_input);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_ctrl_ops cx25840_ctrl_ops = {
- .s_ctrl = cx25840_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops cx25840_core_ops = {
- .log_status = cx25840_log_status,
- .g_chip_ident = cx25840_g_chip_ident,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
- .s_std = cx25840_s_std,
- .g_std = cx25840_g_std,
- .reset = cx25840_reset,
- .load_fw = cx25840_load_fw,
- .s_io_pin_config = common_s_io_pin_config,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = cx25840_g_register,
- .s_register = cx25840_s_register,
-#endif
- .interrupt_service_routine = cx25840_irq_handler,
-};
-
-static const struct v4l2_subdev_tuner_ops cx25840_tuner_ops = {
- .s_frequency = cx25840_s_frequency,
- .s_radio = cx25840_s_radio,
- .g_tuner = cx25840_g_tuner,
- .s_tuner = cx25840_s_tuner,
-};
-
-static const struct v4l2_subdev_audio_ops cx25840_audio_ops = {
- .s_clock_freq = cx25840_s_clock_freq,
- .s_routing = cx25840_s_audio_routing,
- .s_stream = cx25840_s_audio_stream,
-};
-
-static const struct v4l2_subdev_video_ops cx25840_video_ops = {
- .s_routing = cx25840_s_video_routing,
- .s_mbus_fmt = cx25840_s_mbus_fmt,
- .s_stream = cx25840_s_stream,
- .g_input_status = cx25840_g_input_status,
-};
-
-static const struct v4l2_subdev_vbi_ops cx25840_vbi_ops = {
- .decode_vbi_line = cx25840_decode_vbi_line,
- .s_raw_fmt = cx25840_s_raw_fmt,
- .s_sliced_fmt = cx25840_s_sliced_fmt,
- .g_sliced_fmt = cx25840_g_sliced_fmt,
-};
-
-static const struct v4l2_subdev_ops cx25840_ops = {
- .core = &cx25840_core_ops,
- .tuner = &cx25840_tuner_ops,
- .audio = &cx25840_audio_ops,
- .video = &cx25840_video_ops,
- .vbi = &cx25840_vbi_ops,
- .ir = &cx25840_ir_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static u32 get_cx2388x_ident(struct i2c_client *client)
-{
- u32 ret;
-
- /* Come out of digital power down */
- cx25840_write(client, 0x000, 0);
-
- /* Detecting whether the part is cx23885/7/8 is more
- * difficult than it needs to be. No ID register. Instead we
- * probe certain registers indicated in the datasheets to look
- * for specific defaults that differ between the silicon designs. */
-
- /* It's either 885/7 if the IR Tx Clk Divider register exists */
- if (cx25840_read4(client, 0x204) & 0xffff) {
- /* CX23885 returns bogus repetitive byte values for the DIF,
- * which doesn't exist for it. (Ex. 8a8a8a8a or 31313131) */
- ret = cx25840_read4(client, 0x300);
- if (((ret & 0xffff0000) >> 16) == (ret & 0xffff)) {
- /* No DIF */
- ret = V4L2_IDENT_CX23885_AV;
- } else {
- /* CX23887 has a broken DIF, but the registers
- * appear valid (but unused), good enough to detect. */
- ret = V4L2_IDENT_CX23887_AV;
- }
- } else if (cx25840_read4(client, 0x300) & 0x0fffffff) {
- /* DIF PLL Freq Word reg exists; chip must be a CX23888 */
- ret = V4L2_IDENT_CX23888_AV;
- } else {
- v4l_err(client, "Unable to detect h/w, assuming cx23887\n");
- ret = V4L2_IDENT_CX23887_AV;
- }
-
- /* Back into digital power down */
- cx25840_write(client, 0x000, 2);
- return ret;
-}
-
-static int cx25840_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct cx25840_state *state;
- struct v4l2_subdev *sd;
- int default_volume;
- u32 id = V4L2_IDENT_NONE;
- u16 device_id;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- v4l_dbg(1, cx25840_debug, client, "detecting cx25840 client on address 0x%x\n", client->addr << 1);
-
- device_id = cx25840_read(client, 0x101) << 8;
- device_id |= cx25840_read(client, 0x100);
- v4l_dbg(1, cx25840_debug, client, "device_id = 0x%04x\n", device_id);
-
- /* The high byte of the device ID should be
- * 0x83 for the cx2583x and 0x84 for the cx2584x */
- if ((device_id & 0xff00) == 0x8300) {
- id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
- } else if ((device_id & 0xff00) == 0x8400) {
- id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
- } else if (device_id == 0x0000) {
- id = get_cx2388x_ident(client);
- } else if ((device_id & 0xfff0) == 0x5A30) {
- /* The CX23100 (0x5A3C = 23100) doesn't have an A/V decoder */
- id = V4L2_IDENT_CX2310X_AV;
- } else if ((device_id & 0xff) == (device_id >> 8)) {
- v4l_err(client,
- "likely a confused/unresponsive cx2388[578] A/V decoder"
- " found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
- v4l_err(client, "A method to reset it from the cx25840 driver"
- " software is not known at this time\n");
- return -ENODEV;
- } else {
- v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
- return -ENODEV;
- }
-
- state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
-
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &cx25840_ops);
-
- switch (id) {
- case V4L2_IDENT_CX23885_AV:
- v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
- break;
- case V4L2_IDENT_CX23887_AV:
- v4l_info(client, "cx23887 A/V decoder found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
- break;
- case V4L2_IDENT_CX23888_AV:
- v4l_info(client, "cx23888 A/V decoder found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
- break;
- case V4L2_IDENT_CX2310X_AV:
- v4l_info(client, "cx%d A/V decoder found @ 0x%x (%s)\n",
- device_id, client->addr << 1, client->adapter->name);
- break;
- case V4L2_IDENT_CX25840:
- case V4L2_IDENT_CX25841:
- case V4L2_IDENT_CX25842:
- case V4L2_IDENT_CX25843:
- /* Note: revision '(device_id & 0x0f) == 2' was never built. The
- marking skips from 0x1 == 22 to 0x3 == 23. */
- v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
- (device_id & 0xfff0) >> 4,
- (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1
- : (device_id & 0x0f),
- client->addr << 1, client->adapter->name);
- break;
- case V4L2_IDENT_CX25836:
- case V4L2_IDENT_CX25837:
- default:
- v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n",
- (device_id & 0xfff0) >> 4, device_id & 0x0f,
- client->addr << 1, client->adapter->name);
- break;
- }
-
- state->c = client;
- state->vid_input = CX25840_COMPOSITE7;
- state->aud_input = CX25840_AUDIO8;
- state->audclk_freq = 48000;
- state->audmode = V4L2_TUNER_MODE_LANG1;
- state->vbi_line_offset = 8;
- state->id = id;
- state->rev = device_id;
- v4l2_ctrl_handler_init(&state->hdl, 9);
- v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 127, 1, 64);
- v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
- V4L2_CID_SATURATION, 0, 127, 1, 64);
- v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
- V4L2_CID_HUE, -128, 127, 1, 0);
- if (!is_cx2583x(state)) {
- default_volume = cx25840_read(client, 0x8d4);
- /*
- * Enforce the legacy PVR-350/MSP3400 to PVR-150/CX25843 volume
- * scale mapping limits to avoid -ERANGE errors when
- * initializing the volume control
- */
- if (default_volume > 228) {
- /* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */
- default_volume = 228;
- cx25840_write(client, 0x8d4, 228);
- }
- else if (default_volume < 20) {
- /* Top out at + 8 dB, v4l2 vol range 0xfe00-0xffff */
- default_volume = 20;
- cx25840_write(client, 0x8d4, 20);
- }
- default_volume = (((228 - default_volume) >> 1) + 23) << 9;
-
- state->volume = v4l2_ctrl_new_std(&state->hdl,
- &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
- 0, 65535, 65535 / 100, default_volume);
- state->mute = v4l2_ctrl_new_std(&state->hdl,
- &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE,
- 0, 1, 1, 0);
- v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops,
- V4L2_CID_AUDIO_BALANCE,
- 0, 65535, 65535 / 100, 32768);
- v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops,
- V4L2_CID_AUDIO_BASS,
- 0, 65535, 65535 / 100, 32768);
- v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops,
- V4L2_CID_AUDIO_TREBLE,
- 0, 65535, 65535 / 100, 32768);
- }
- sd->ctrl_handler = &state->hdl;
- if (state->hdl.error) {
- int err = state->hdl.error;
-
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return err;
- }
- if (!is_cx2583x(state))
- v4l2_ctrl_cluster(2, &state->volume);
- v4l2_ctrl_handler_setup(&state->hdl);
-
- if (client->dev.platform_data) {
- struct cx25840_platform_data *pdata = client->dev.platform_data;
-
- state->pvr150_workaround = pdata->pvr150_workaround;
- }
-
- cx25840_ir_probe(sd);
- return 0;
-}
-
-static int cx25840_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct cx25840_state *state = to_state(sd);
-
- cx25840_ir_remove(sd);
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return 0;
-}
-
-static const struct i2c_device_id cx25840_id[] = {
- { "cx25840", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, cx25840_id);
-
-static struct i2c_driver cx25840_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "cx25840",
- },
- .probe = cx25840_probe,
- .remove = cx25840_remove,
- .id_table = cx25840_id,
-};
-
-module_i2c_driver(cx25840_driver);
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
deleted file mode 100644
index bd4ada28b49..00000000000
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* cx25840 internal API header
- *
- * Copyright (C) 2003-2004 Chris Kennedy
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef _CX25840_CORE_H_
-#define _CX25840_CORE_H_
-
-
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-#include <linux/i2c.h>
-
-struct cx25840_ir_state;
-
-struct cx25840_state {
- struct i2c_client *c;
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- struct {
- /* volume cluster */
- struct v4l2_ctrl *volume;
- struct v4l2_ctrl *mute;
- };
- int pvr150_workaround;
- int radio;
- v4l2_std_id std;
- enum cx25840_video_input vid_input;
- enum cx25840_audio_input aud_input;
- u32 audclk_freq;
- int audmode;
- int vbi_line_offset;
- u32 id;
- u32 rev;
- int is_initialized;
- wait_queue_head_t fw_wait; /* wake up when the fw load is finished */
- struct work_struct fw_work; /* work entry for fw load */
- struct cx25840_ir_state *ir_state;
-};
-
-static inline struct cx25840_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct cx25840_state, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct cx25840_state, hdl)->sd;
-}
-
-static inline bool is_cx2583x(struct cx25840_state *state)
-{
- return state->id == V4L2_IDENT_CX25836 ||
- state->id == V4L2_IDENT_CX25837;
-}
-
-static inline bool is_cx231xx(struct cx25840_state *state)
-{
- return state->id == V4L2_IDENT_CX2310X_AV;
-}
-
-static inline bool is_cx2388x(struct cx25840_state *state)
-{
- return state->id == V4L2_IDENT_CX23885_AV ||
- state->id == V4L2_IDENT_CX23887_AV ||
- state->id == V4L2_IDENT_CX23888_AV;
-}
-
-static inline bool is_cx23885(struct cx25840_state *state)
-{
- return state->id == V4L2_IDENT_CX23885_AV;
-}
-
-static inline bool is_cx23887(struct cx25840_state *state)
-{
- return state->id == V4L2_IDENT_CX23887_AV;
-}
-
-static inline bool is_cx23888(struct cx25840_state *state)
-{
- return state->id == V4L2_IDENT_CX23888_AV;
-}
-
-/* ----------------------------------------------------------------------- */
-/* cx25850-core.c */
-int cx25840_write(struct i2c_client *client, u16 addr, u8 value);
-int cx25840_write4(struct i2c_client *client, u16 addr, u32 value);
-u8 cx25840_read(struct i2c_client *client, u16 addr);
-u32 cx25840_read4(struct i2c_client *client, u16 addr);
-int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value);
-int cx25840_and_or4(struct i2c_client *client, u16 addr, u32 and_mask,
- u32 or_value);
-void cx25840_std_setup(struct i2c_client *client);
-
-/* ----------------------------------------------------------------------- */
-/* cx25850-firmware.c */
-int cx25840_loadfw(struct i2c_client *client);
-
-/* ----------------------------------------------------------------------- */
-/* cx25850-audio.c */
-void cx25840_audio_set_path(struct i2c_client *client);
-int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
-
-extern const struct v4l2_ctrl_ops cx25840_audio_ctrl_ops;
-
-/* ----------------------------------------------------------------------- */
-/* cx25850-vbi.c */
-int cx25840_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt);
-int cx25840_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
-int cx25840_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
-int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi);
-
-/* ----------------------------------------------------------------------- */
-/* cx25850-ir.c */
-extern const struct v4l2_subdev_ir_ops cx25840_ir_ops;
-int cx25840_ir_log_status(struct v4l2_subdev *sd);
-int cx25840_ir_irq_handler(struct v4l2_subdev *sd, u32 status, bool *handled);
-int cx25840_ir_probe(struct v4l2_subdev *sd);
-int cx25840_ir_remove(struct v4l2_subdev *sd);
-
-#endif
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
deleted file mode 100644
index 8150200511d..00000000000
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/* cx25840 firmware functions
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/firmware.h>
-#include <media/v4l2-common.h>
-#include <media/cx25840.h>
-
-#include "cx25840-core.h"
-
-/*
- * Mike Isely <isely@pobox.com> - The FWSEND parameter controls the
- * size of the firmware chunks sent down the I2C bus to the chip.
- * Previously this had been set to 1024 but unfortunately some I2C
- * implementations can't transfer data in such big gulps.
- * Specifically, the pvrusb2 driver has a hard limit of around 60
- * bytes, due to the encapsulation there of I2C traffic into USB
- * messages. So we have to significantly reduce this parameter.
- */
-#define FWSEND 48
-
-#define FWDEV(x) &((x)->dev)
-
-static char *firmware = "";
-
-module_param(firmware, charp, 0444);
-
-MODULE_PARM_DESC(firmware, "Firmware image to load");
-
-static void start_fw_load(struct i2c_client *client)
-{
- /* DL_ADDR_LB=0 DL_ADDR_HB=0 */
- cx25840_write(client, 0x800, 0x00);
- cx25840_write(client, 0x801, 0x00);
- // DL_MAP=3 DL_AUTO_INC=0 DL_ENABLE=1
- cx25840_write(client, 0x803, 0x0b);
- /* AUTO_INC_DIS=1 */
- cx25840_write(client, 0x000, 0x20);
-}
-
-static void end_fw_load(struct i2c_client *client)
-{
- /* AUTO_INC_DIS=0 */
- cx25840_write(client, 0x000, 0x00);
- /* DL_ENABLE=0 */
- cx25840_write(client, 0x803, 0x03);
-}
-
-static const char *get_fw_name(struct i2c_client *client)
-{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
-
- if (firmware[0])
- return firmware;
- if (is_cx2388x(state))
- return "v4l-cx23885-avcore-01.fw";
- if (is_cx231xx(state))
- return "v4l-cx231xx-avcore-01.fw";
- return "v4l-cx25840.fw";
-}
-
-static int check_fw_load(struct i2c_client *client, int size)
-{
- /* DL_ADDR_HB DL_ADDR_LB */
- int s = cx25840_read(client, 0x801) << 8;
- s |= cx25840_read(client, 0x800);
-
- if (size != s) {
- v4l_err(client, "firmware %s load failed\n",
- get_fw_name(client));
- return -EINVAL;
- }
-
- v4l_info(client, "loaded %s firmware (%d bytes)\n",
- get_fw_name(client), size);
- return 0;
-}
-
-static int fw_write(struct i2c_client *client, const u8 *data, int size)
-{
- if (i2c_master_send(client, data, size) < size) {
- v4l_err(client, "firmware load i2c failure\n");
- return -ENOSYS;
- }
-
- return 0;
-}
-
-int cx25840_loadfw(struct i2c_client *client)
-{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- const struct firmware *fw = NULL;
- u8 buffer[FWSEND];
- const u8 *ptr;
- const char *fwname = get_fw_name(client);
- int size, retval;
- int MAX_BUF_SIZE = FWSEND;
- u32 gpio_oe = 0, gpio_da = 0;
-
- if (is_cx2388x(state)) {
- /* Preserve the GPIO OE and output bits */
- gpio_oe = cx25840_read(client, 0x160);
- gpio_da = cx25840_read(client, 0x164);
- }
-
- if (is_cx231xx(state) && MAX_BUF_SIZE > 16) {
- v4l_err(client, " Firmware download size changed to 16 bytes max length\n");
- MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */
- }
-
- if (request_firmware(&fw, fwname, FWDEV(client)) != 0) {
- v4l_err(client, "unable to open firmware %s\n", fwname);
- return -EINVAL;
- }
-
- start_fw_load(client);
-
- buffer[0] = 0x08;
- buffer[1] = 0x02;
-
- size = fw->size;
- ptr = fw->data;
- while (size > 0) {
- int len = min(MAX_BUF_SIZE - 2, size);
-
- memcpy(buffer + 2, ptr, len);
-
- retval = fw_write(client, buffer, len + 2);
-
- if (retval < 0) {
- release_firmware(fw);
- return retval;
- }
-
- size -= len;
- ptr += len;
- }
-
- end_fw_load(client);
-
- size = fw->size;
- release_firmware(fw);
-
- if (is_cx2388x(state)) {
- /* Restore GPIO configuration after f/w load */
- cx25840_write(client, 0x160, gpio_oe);
- cx25840_write(client, 0x164, gpio_da);
- }
-
- return check_fw_load(client, size);
-}
diff --git a/drivers/media/video/cx25840/cx25840-ir.c b/drivers/media/video/cx25840/cx25840-ir.c
deleted file mode 100644
index 38ce76ed192..00000000000
--- a/drivers/media/video/cx25840/cx25840-ir.c
+++ /dev/null
@@ -1,1281 +0,0 @@
-/*
- * Driver for the Conexant CX2584x Audio/Video decoder chip and related cores
- *
- * Integrated Consumer Infrared Controller
- *
- * Copyright (C) 2010 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <linux/slab.h>
-#include <linux/kfifo.h>
-#include <linux/module.h>
-#include <media/cx25840.h>
-#include <media/rc-core.h>
-
-#include "cx25840-core.h"
-
-static unsigned int ir_debug;
-module_param(ir_debug, int, 0644);
-MODULE_PARM_DESC(ir_debug, "enable integrated IR debug messages");
-
-#define CX25840_IR_REG_BASE 0x200
-
-#define CX25840_IR_CNTRL_REG 0x200
-#define CNTRL_WIN_3_3 0x00000000
-#define CNTRL_WIN_4_3 0x00000001
-#define CNTRL_WIN_3_4 0x00000002
-#define CNTRL_WIN_4_4 0x00000003
-#define CNTRL_WIN 0x00000003
-#define CNTRL_EDG_NONE 0x00000000
-#define CNTRL_EDG_FALL 0x00000004
-#define CNTRL_EDG_RISE 0x00000008
-#define CNTRL_EDG_BOTH 0x0000000C
-#define CNTRL_EDG 0x0000000C
-#define CNTRL_DMD 0x00000010
-#define CNTRL_MOD 0x00000020
-#define CNTRL_RFE 0x00000040
-#define CNTRL_TFE 0x00000080
-#define CNTRL_RXE 0x00000100
-#define CNTRL_TXE 0x00000200
-#define CNTRL_RIC 0x00000400
-#define CNTRL_TIC 0x00000800
-#define CNTRL_CPL 0x00001000
-#define CNTRL_LBM 0x00002000
-#define CNTRL_R 0x00004000
-
-#define CX25840_IR_TXCLK_REG 0x204
-#define TXCLK_TCD 0x0000FFFF
-
-#define CX25840_IR_RXCLK_REG 0x208
-#define RXCLK_RCD 0x0000FFFF
-
-#define CX25840_IR_CDUTY_REG 0x20C
-#define CDUTY_CDC 0x0000000F
-
-#define CX25840_IR_STATS_REG 0x210
-#define STATS_RTO 0x00000001
-#define STATS_ROR 0x00000002
-#define STATS_RBY 0x00000004
-#define STATS_TBY 0x00000008
-#define STATS_RSR 0x00000010
-#define STATS_TSR 0x00000020
-
-#define CX25840_IR_IRQEN_REG 0x214
-#define IRQEN_RTE 0x00000001
-#define IRQEN_ROE 0x00000002
-#define IRQEN_RSE 0x00000010
-#define IRQEN_TSE 0x00000020
-#define IRQEN_MSK 0x00000033
-
-#define CX25840_IR_FILTR_REG 0x218
-#define FILTR_LPF 0x0000FFFF
-
-#define CX25840_IR_FIFO_REG 0x23C
-#define FIFO_RXTX 0x0000FFFF
-#define FIFO_RXTX_LVL 0x00010000
-#define FIFO_RXTX_RTO 0x0001FFFF
-#define FIFO_RX_NDV 0x00020000
-#define FIFO_RX_DEPTH 8
-#define FIFO_TX_DEPTH 8
-
-#define CX25840_VIDCLK_FREQ 108000000 /* 108 MHz, BT.656 */
-#define CX25840_IR_REFCLK_FREQ (CX25840_VIDCLK_FREQ / 2)
-
-/*
- * We use this union internally for convenience, but callers to tx_write
- * and rx_read will be expecting records of type struct ir_raw_event.
- * Always ensure the size of this union is dictated by struct ir_raw_event.
- */
-union cx25840_ir_fifo_rec {
- u32 hw_fifo_data;
- struct ir_raw_event ir_core_data;
-};
-
-#define CX25840_IR_RX_KFIFO_SIZE (256 * sizeof(union cx25840_ir_fifo_rec))
-#define CX25840_IR_TX_KFIFO_SIZE (256 * sizeof(union cx25840_ir_fifo_rec))
-
-struct cx25840_ir_state {
- struct i2c_client *c;
-
- struct v4l2_subdev_ir_parameters rx_params;
- struct mutex rx_params_lock; /* protects Rx parameter settings cache */
- atomic_t rxclk_divider;
- atomic_t rx_invert;
-
- struct kfifo rx_kfifo;
- spinlock_t rx_kfifo_lock; /* protect Rx data kfifo */
-
- struct v4l2_subdev_ir_parameters tx_params;
- struct mutex tx_params_lock; /* protects Tx parameter settings cache */
- atomic_t txclk_divider;
-};
-
-static inline struct cx25840_ir_state *to_ir_state(struct v4l2_subdev *sd)
-{
- struct cx25840_state *state = to_state(sd);
- return state ? state->ir_state : NULL;
-}
-
-
-/*
- * Rx and Tx Clock Divider register computations
- *
- * Note the largest clock divider value of 0xffff corresponds to:
- * (0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns
- * which fits in 21 bits, so we'll use unsigned int for time arguments.
- */
-static inline u16 count_to_clock_divider(unsigned int d)
-{
- if (d > RXCLK_RCD + 1)
- d = RXCLK_RCD;
- else if (d < 2)
- d = 1;
- else
- d--;
- return (u16) d;
-}
-
-static inline u16 ns_to_clock_divider(unsigned int ns)
-{
- return count_to_clock_divider(
- DIV_ROUND_CLOSEST(CX25840_IR_REFCLK_FREQ / 1000000 * ns, 1000));
-}
-
-static inline unsigned int clock_divider_to_ns(unsigned int divider)
-{
- /* Period of the Rx or Tx clock in ns */
- return DIV_ROUND_CLOSEST((divider + 1) * 1000,
- CX25840_IR_REFCLK_FREQ / 1000000);
-}
-
-static inline u16 carrier_freq_to_clock_divider(unsigned int freq)
-{
- return count_to_clock_divider(
- DIV_ROUND_CLOSEST(CX25840_IR_REFCLK_FREQ, freq * 16));
-}
-
-static inline unsigned int clock_divider_to_carrier_freq(unsigned int divider)
-{
- return DIV_ROUND_CLOSEST(CX25840_IR_REFCLK_FREQ, (divider + 1) * 16);
-}
-
-static inline u16 freq_to_clock_divider(unsigned int freq,
- unsigned int rollovers)
-{
- return count_to_clock_divider(
- DIV_ROUND_CLOSEST(CX25840_IR_REFCLK_FREQ, freq * rollovers));
-}
-
-static inline unsigned int clock_divider_to_freq(unsigned int divider,
- unsigned int rollovers)
-{
- return DIV_ROUND_CLOSEST(CX25840_IR_REFCLK_FREQ,
- (divider + 1) * rollovers);
-}
-
-/*
- * Low Pass Filter register calculations
- *
- * Note the largest count value of 0xffff corresponds to:
- * 0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns
- * which fits in 21 bits, so we'll use unsigned int for time arguments.
- */
-static inline u16 count_to_lpf_count(unsigned int d)
-{
- if (d > FILTR_LPF)
- d = FILTR_LPF;
- else if (d < 4)
- d = 0;
- return (u16) d;
-}
-
-static inline u16 ns_to_lpf_count(unsigned int ns)
-{
- return count_to_lpf_count(
- DIV_ROUND_CLOSEST(CX25840_IR_REFCLK_FREQ / 1000000 * ns, 1000));
-}
-
-static inline unsigned int lpf_count_to_ns(unsigned int count)
-{
- /* Duration of the Low Pass Filter rejection window in ns */
- return DIV_ROUND_CLOSEST(count * 1000,
- CX25840_IR_REFCLK_FREQ / 1000000);
-}
-
-static inline unsigned int lpf_count_to_us(unsigned int count)
-{
- /* Duration of the Low Pass Filter rejection window in us */
- return DIV_ROUND_CLOSEST(count, CX25840_IR_REFCLK_FREQ / 1000000);
-}
-
-/*
- * FIFO register pulse width count compuations
- */
-static u32 clock_divider_to_resolution(u16 divider)
-{
- /*
- * Resolution is the duration of 1 tick of the readable portion of
- * of the pulse width counter as read from the FIFO. The two lsb's are
- * not readable, hence the << 2. This function returns ns.
- */
- return DIV_ROUND_CLOSEST((1 << 2) * ((u32) divider + 1) * 1000,
- CX25840_IR_REFCLK_FREQ / 1000000);
-}
-
-static u64 pulse_width_count_to_ns(u16 count, u16 divider)
-{
- u64 n;
- u32 rem;
-
- /*
- * The 2 lsb's of the pulse width timer count are not readable, hence
- * the (count << 2) | 0x3
- */
- n = (((u64) count << 2) | 0x3) * (divider + 1) * 1000; /* millicycles */
- rem = do_div(n, CX25840_IR_REFCLK_FREQ / 1000000); /* / MHz => ns */
- if (rem >= CX25840_IR_REFCLK_FREQ / 1000000 / 2)
- n++;
- return n;
-}
-
-#if 0
-/* Keep as we will need this for Transmit functionality */
-static u16 ns_to_pulse_width_count(u32 ns, u16 divider)
-{
- u64 n;
- u32 d;
- u32 rem;
-
- /*
- * The 2 lsb's of the pulse width timer count are not accessible, hence
- * the (1 << 2)
- */
- n = ((u64) ns) * CX25840_IR_REFCLK_FREQ / 1000000; /* millicycles */
- d = (1 << 2) * ((u32) divider + 1) * 1000; /* millicycles/count */
- rem = do_div(n, d);
- if (rem >= d / 2)
- n++;
-
- if (n > FIFO_RXTX)
- n = FIFO_RXTX;
- else if (n == 0)
- n = 1;
- return (u16) n;
-}
-
-#endif
-static unsigned int pulse_width_count_to_us(u16 count, u16 divider)
-{
- u64 n;
- u32 rem;
-
- /*
- * The 2 lsb's of the pulse width timer count are not readable, hence
- * the (count << 2) | 0x3
- */
- n = (((u64) count << 2) | 0x3) * (divider + 1); /* cycles */
- rem = do_div(n, CX25840_IR_REFCLK_FREQ / 1000000); /* / MHz => us */
- if (rem >= CX25840_IR_REFCLK_FREQ / 1000000 / 2)
- n++;
- return (unsigned int) n;
-}
-
-/*
- * Pulse Clocks computations: Combined Pulse Width Count & Rx Clock Counts
- *
- * The total pulse clock count is an 18 bit pulse width timer count as the most
- * significant part and (up to) 16 bit clock divider count as a modulus.
- * When the Rx clock divider ticks down to 0, it increments the 18 bit pulse
- * width timer count's least significant bit.
- */
-static u64 ns_to_pulse_clocks(u32 ns)
-{
- u64 clocks;
- u32 rem;
- clocks = CX25840_IR_REFCLK_FREQ / 1000000 * (u64) ns; /* millicycles */
- rem = do_div(clocks, 1000); /* /1000 = cycles */
- if (rem >= 1000 / 2)
- clocks++;
- return clocks;
-}
-
-static u16 pulse_clocks_to_clock_divider(u64 count)
-{
- do_div(count, (FIFO_RXTX << 2) | 0x3);
-
- /* net result needs to be rounded down and decremented by 1 */
- if (count > RXCLK_RCD + 1)
- count = RXCLK_RCD;
- else if (count < 2)
- count = 1;
- else
- count--;
- return (u16) count;
-}
-
-/*
- * IR Control Register helpers
- */
-enum tx_fifo_watermark {
- TX_FIFO_HALF_EMPTY = 0,
- TX_FIFO_EMPTY = CNTRL_TIC,
-};
-
-enum rx_fifo_watermark {
- RX_FIFO_HALF_FULL = 0,
- RX_FIFO_NOT_EMPTY = CNTRL_RIC,
-};
-
-static inline void control_tx_irq_watermark(struct i2c_client *c,
- enum tx_fifo_watermark level)
-{
- cx25840_and_or4(c, CX25840_IR_CNTRL_REG, ~CNTRL_TIC, level);
-}
-
-static inline void control_rx_irq_watermark(struct i2c_client *c,
- enum rx_fifo_watermark level)
-{
- cx25840_and_or4(c, CX25840_IR_CNTRL_REG, ~CNTRL_RIC, level);
-}
-
-static inline void control_tx_enable(struct i2c_client *c, bool enable)
-{
- cx25840_and_or4(c, CX25840_IR_CNTRL_REG, ~(CNTRL_TXE | CNTRL_TFE),
- enable ? (CNTRL_TXE | CNTRL_TFE) : 0);
-}
-
-static inline void control_rx_enable(struct i2c_client *c, bool enable)
-{
- cx25840_and_or4(c, CX25840_IR_CNTRL_REG, ~(CNTRL_RXE | CNTRL_RFE),
- enable ? (CNTRL_RXE | CNTRL_RFE) : 0);
-}
-
-static inline void control_tx_modulation_enable(struct i2c_client *c,
- bool enable)
-{
- cx25840_and_or4(c, CX25840_IR_CNTRL_REG, ~CNTRL_MOD,
- enable ? CNTRL_MOD : 0);
-}
-
-static inline void control_rx_demodulation_enable(struct i2c_client *c,
- bool enable)
-{
- cx25840_and_or4(c, CX25840_IR_CNTRL_REG, ~CNTRL_DMD,
- enable ? CNTRL_DMD : 0);
-}
-
-static inline void control_rx_s_edge_detection(struct i2c_client *c,
- u32 edge_types)
-{
- cx25840_and_or4(c, CX25840_IR_CNTRL_REG, ~CNTRL_EDG_BOTH,
- edge_types & CNTRL_EDG_BOTH);
-}
-
-static void control_rx_s_carrier_window(struct i2c_client *c,
- unsigned int carrier,
- unsigned int *carrier_range_low,
- unsigned int *carrier_range_high)
-{
- u32 v;
- unsigned int c16 = carrier * 16;
-
- if (*carrier_range_low < DIV_ROUND_CLOSEST(c16, 16 + 3)) {
- v = CNTRL_WIN_3_4;
- *carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 4);
- } else {
- v = CNTRL_WIN_3_3;
- *carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 3);
- }
-
- if (*carrier_range_high > DIV_ROUND_CLOSEST(c16, 16 - 3)) {
- v |= CNTRL_WIN_4_3;
- *carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 4);
- } else {
- v |= CNTRL_WIN_3_3;
- *carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 3);
- }
- cx25840_and_or4(c, CX25840_IR_CNTRL_REG, ~CNTRL_WIN, v);
-}
-
-static inline void control_tx_polarity_invert(struct i2c_client *c,
- bool invert)
-{
- cx25840_and_or4(c, CX25840_IR_CNTRL_REG, ~CNTRL_CPL,
- invert ? CNTRL_CPL : 0);
-}
-
-/*
- * IR Rx & Tx Clock Register helpers
- */
-static unsigned int txclk_tx_s_carrier(struct i2c_client *c,
- unsigned int freq,
- u16 *divider)
-{
- *divider = carrier_freq_to_clock_divider(freq);
- cx25840_write4(c, CX25840_IR_TXCLK_REG, *divider);
- return clock_divider_to_carrier_freq(*divider);
-}
-
-static unsigned int rxclk_rx_s_carrier(struct i2c_client *c,
- unsigned int freq,
- u16 *divider)
-{
- *divider = carrier_freq_to_clock_divider(freq);
- cx25840_write4(c, CX25840_IR_RXCLK_REG, *divider);
- return clock_divider_to_carrier_freq(*divider);
-}
-
-static u32 txclk_tx_s_max_pulse_width(struct i2c_client *c, u32 ns,
- u16 *divider)
-{
- u64 pulse_clocks;
-
- if (ns > IR_MAX_DURATION)
- ns = IR_MAX_DURATION;
- pulse_clocks = ns_to_pulse_clocks(ns);
- *divider = pulse_clocks_to_clock_divider(pulse_clocks);
- cx25840_write4(c, CX25840_IR_TXCLK_REG, *divider);
- return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider);
-}
-
-static u32 rxclk_rx_s_max_pulse_width(struct i2c_client *c, u32 ns,
- u16 *divider)
-{
- u64 pulse_clocks;
-
- if (ns > IR_MAX_DURATION)
- ns = IR_MAX_DURATION;
- pulse_clocks = ns_to_pulse_clocks(ns);
- *divider = pulse_clocks_to_clock_divider(pulse_clocks);
- cx25840_write4(c, CX25840_IR_RXCLK_REG, *divider);
- return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider);
-}
-
-/*
- * IR Tx Carrier Duty Cycle register helpers
- */
-static unsigned int cduty_tx_s_duty_cycle(struct i2c_client *c,
- unsigned int duty_cycle)
-{
- u32 n;
- n = DIV_ROUND_CLOSEST(duty_cycle * 100, 625); /* 16ths of 100% */
- if (n != 0)
- n--;
- if (n > 15)
- n = 15;
- cx25840_write4(c, CX25840_IR_CDUTY_REG, n);
- return DIV_ROUND_CLOSEST((n + 1) * 100, 16);
-}
-
-/*
- * IR Filter Register helpers
- */
-static u32 filter_rx_s_min_width(struct i2c_client *c, u32 min_width_ns)
-{
- u32 count = ns_to_lpf_count(min_width_ns);
- cx25840_write4(c, CX25840_IR_FILTR_REG, count);
- return lpf_count_to_ns(count);
-}
-
-/*
- * IR IRQ Enable Register helpers
- */
-static inline void irqenable_rx(struct v4l2_subdev *sd, u32 mask)
-{
- struct cx25840_state *state = to_state(sd);
-
- if (is_cx23885(state) || is_cx23887(state))
- mask ^= IRQEN_MSK;
- mask &= (IRQEN_RTE | IRQEN_ROE | IRQEN_RSE);
- cx25840_and_or4(state->c, CX25840_IR_IRQEN_REG,
- ~(IRQEN_RTE | IRQEN_ROE | IRQEN_RSE), mask);
-}
-
-static inline void irqenable_tx(struct v4l2_subdev *sd, u32 mask)
-{
- struct cx25840_state *state = to_state(sd);
-
- if (is_cx23885(state) || is_cx23887(state))
- mask ^= IRQEN_MSK;
- mask &= IRQEN_TSE;
- cx25840_and_or4(state->c, CX25840_IR_IRQEN_REG, ~IRQEN_TSE, mask);
-}
-
-/*
- * V4L2 Subdevice IR Ops
- */
-int cx25840_ir_irq_handler(struct v4l2_subdev *sd, u32 status, bool *handled)
-{
- struct cx25840_state *state = to_state(sd);
- struct cx25840_ir_state *ir_state = to_ir_state(sd);
- struct i2c_client *c = NULL;
- unsigned long flags;
-
- union cx25840_ir_fifo_rec rx_data[FIFO_RX_DEPTH];
- unsigned int i, j, k;
- u32 events, v;
- int tsr, rsr, rto, ror, tse, rse, rte, roe, kror;
- u32 cntrl, irqen, stats;
-
- *handled = false;
- if (ir_state == NULL)
- return -ENODEV;
-
- c = ir_state->c;
-
- /* Only support the IR controller for the CX2388[57] AV Core for now */
- if (!(is_cx23885(state) || is_cx23887(state)))
- return -ENODEV;
-
- cntrl = cx25840_read4(c, CX25840_IR_CNTRL_REG);
- irqen = cx25840_read4(c, CX25840_IR_IRQEN_REG);
- if (is_cx23885(state) || is_cx23887(state))
- irqen ^= IRQEN_MSK;
- stats = cx25840_read4(c, CX25840_IR_STATS_REG);
-
- tsr = stats & STATS_TSR; /* Tx FIFO Service Request */
- rsr = stats & STATS_RSR; /* Rx FIFO Service Request */
- rto = stats & STATS_RTO; /* Rx Pulse Width Timer Time Out */
- ror = stats & STATS_ROR; /* Rx FIFO Over Run */
-
- tse = irqen & IRQEN_TSE; /* Tx FIFO Service Request IRQ Enable */
- rse = irqen & IRQEN_RSE; /* Rx FIFO Service Reuqest IRQ Enable */
- rte = irqen & IRQEN_RTE; /* Rx Pulse Width Timer Time Out IRQ Enable */
- roe = irqen & IRQEN_ROE; /* Rx FIFO Over Run IRQ Enable */
-
- v4l2_dbg(2, ir_debug, sd, "IR IRQ Status: %s %s %s %s %s %s\n",
- tsr ? "tsr" : " ", rsr ? "rsr" : " ",
- rto ? "rto" : " ", ror ? "ror" : " ",
- stats & STATS_TBY ? "tby" : " ",
- stats & STATS_RBY ? "rby" : " ");
-
- v4l2_dbg(2, ir_debug, sd, "IR IRQ Enables: %s %s %s %s\n",
- tse ? "tse" : " ", rse ? "rse" : " ",
- rte ? "rte" : " ", roe ? "roe" : " ");
-
- /*
- * Transmitter interrupt service
- */
- if (tse && tsr) {
- /*
- * TODO:
- * Check the watermark threshold setting
- * Pull FIFO_TX_DEPTH or FIFO_TX_DEPTH/2 entries from tx_kfifo
- * Push the data to the hardware FIFO.
- * If there was nothing more to send in the tx_kfifo, disable
- * the TSR IRQ and notify the v4l2_device.
- * If there was something in the tx_kfifo, check the tx_kfifo
- * level and notify the v4l2_device, if it is low.
- */
- /* For now, inhibit TSR interrupt until Tx is implemented */
- irqenable_tx(sd, 0);
- events = V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ;
- v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_TX_NOTIFY, &events);
- *handled = true;
- }
-
- /*
- * Receiver interrupt service
- */
- kror = 0;
- if ((rse && rsr) || (rte && rto)) {
- /*
- * Receive data on RSR to clear the STATS_RSR.
- * Receive data on RTO, since we may not have yet hit the RSR
- * watermark when we receive the RTO.
- */
- for (i = 0, v = FIFO_RX_NDV;
- (v & FIFO_RX_NDV) && !kror; i = 0) {
- for (j = 0;
- (v & FIFO_RX_NDV) && j < FIFO_RX_DEPTH; j++) {
- v = cx25840_read4(c, CX25840_IR_FIFO_REG);
- rx_data[i].hw_fifo_data = v & ~FIFO_RX_NDV;
- i++;
- }
- if (i == 0)
- break;
- j = i * sizeof(union cx25840_ir_fifo_rec);
- k = kfifo_in_locked(&ir_state->rx_kfifo,
- (unsigned char *) rx_data, j,
- &ir_state->rx_kfifo_lock);
- if (k != j)
- kror++; /* rx_kfifo over run */
- }
- *handled = true;
- }
-
- events = 0;
- v = 0;
- if (kror) {
- events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN;
- v4l2_err(sd, "IR receiver software FIFO overrun\n");
- }
- if (roe && ror) {
- /*
- * The RX FIFO Enable (CNTRL_RFE) must be toggled to clear
- * the Rx FIFO Over Run status (STATS_ROR)
- */
- v |= CNTRL_RFE;
- events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN;
- v4l2_err(sd, "IR receiver hardware FIFO overrun\n");
- }
- if (rte && rto) {
- /*
- * The IR Receiver Enable (CNTRL_RXE) must be toggled to clear
- * the Rx Pulse Width Timer Time Out (STATS_RTO)
- */
- v |= CNTRL_RXE;
- events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED;
- }
- if (v) {
- /* Clear STATS_ROR & STATS_RTO as needed by reseting hardware */
- cx25840_write4(c, CX25840_IR_CNTRL_REG, cntrl & ~v);
- cx25840_write4(c, CX25840_IR_CNTRL_REG, cntrl);
- *handled = true;
- }
- spin_lock_irqsave(&ir_state->rx_kfifo_lock, flags);
- if (kfifo_len(&ir_state->rx_kfifo) >= CX25840_IR_RX_KFIFO_SIZE / 2)
- events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
- spin_unlock_irqrestore(&ir_state->rx_kfifo_lock, flags);
-
- if (events)
- v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events);
- return 0;
-}
-
-/* Receiver */
-static int cx25840_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
- ssize_t *num)
-{
- struct cx25840_ir_state *ir_state = to_ir_state(sd);
- bool invert;
- u16 divider;
- unsigned int i, n;
- union cx25840_ir_fifo_rec *p;
- unsigned u, v, w;
-
- if (ir_state == NULL)
- return -ENODEV;
-
- invert = (bool) atomic_read(&ir_state->rx_invert);
- divider = (u16) atomic_read(&ir_state->rxclk_divider);
-
- n = count / sizeof(union cx25840_ir_fifo_rec)
- * sizeof(union cx25840_ir_fifo_rec);
- if (n == 0) {
- *num = 0;
- return 0;
- }
-
- n = kfifo_out_locked(&ir_state->rx_kfifo, buf, n,
- &ir_state->rx_kfifo_lock);
-
- n /= sizeof(union cx25840_ir_fifo_rec);
- *num = n * sizeof(union cx25840_ir_fifo_rec);
-
- for (p = (union cx25840_ir_fifo_rec *) buf, i = 0; i < n; p++, i++) {
-
- if ((p->hw_fifo_data & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) {
- /* Assume RTO was because of no IR light input */
- u = 0;
- w = 1;
- } else {
- u = (p->hw_fifo_data & FIFO_RXTX_LVL) ? 1 : 0;
- if (invert)
- u = u ? 0 : 1;
- w = 0;
- }
-
- v = (unsigned) pulse_width_count_to_ns(
- (u16) (p->hw_fifo_data & FIFO_RXTX), divider);
- if (v > IR_MAX_DURATION)
- v = IR_MAX_DURATION;
-
- init_ir_raw_event(&p->ir_core_data);
- p->ir_core_data.pulse = u;
- p->ir_core_data.duration = v;
- p->ir_core_data.timeout = w;
-
- v4l2_dbg(2, ir_debug, sd, "rx read: %10u ns %s %s\n",
- v, u ? "mark" : "space", w ? "(timed out)" : "");
- if (w)
- v4l2_dbg(2, ir_debug, sd, "rx read: end of rx\n");
- }
- return 0;
-}
-
-static int cx25840_ir_rx_g_parameters(struct v4l2_subdev *sd,
- struct v4l2_subdev_ir_parameters *p)
-{
- struct cx25840_ir_state *ir_state = to_ir_state(sd);
-
- if (ir_state == NULL)
- return -ENODEV;
-
- mutex_lock(&ir_state->rx_params_lock);
- memcpy(p, &ir_state->rx_params,
- sizeof(struct v4l2_subdev_ir_parameters));
- mutex_unlock(&ir_state->rx_params_lock);
- return 0;
-}
-
-static int cx25840_ir_rx_shutdown(struct v4l2_subdev *sd)
-{
- struct cx25840_ir_state *ir_state = to_ir_state(sd);
- struct i2c_client *c;
-
- if (ir_state == NULL)
- return -ENODEV;
-
- c = ir_state->c;
- mutex_lock(&ir_state->rx_params_lock);
-
- /* Disable or slow down all IR Rx circuits and counters */
- irqenable_rx(sd, 0);
- control_rx_enable(c, false);
- control_rx_demodulation_enable(c, false);
- control_rx_s_edge_detection(c, CNTRL_EDG_NONE);
- filter_rx_s_min_width(c, 0);
- cx25840_write4(c, CX25840_IR_RXCLK_REG, RXCLK_RCD);
-
- ir_state->rx_params.shutdown = true;
-
- mutex_unlock(&ir_state->rx_params_lock);
- return 0;
-}
-
-static int cx25840_ir_rx_s_parameters(struct v4l2_subdev *sd,
- struct v4l2_subdev_ir_parameters *p)
-{
- struct cx25840_ir_state *ir_state = to_ir_state(sd);
- struct i2c_client *c;
- struct v4l2_subdev_ir_parameters *o;
- u16 rxclk_divider;
-
- if (ir_state == NULL)
- return -ENODEV;
-
- if (p->shutdown)
- return cx25840_ir_rx_shutdown(sd);
-
- if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH)
- return -ENOSYS;
-
- c = ir_state->c;
- o = &ir_state->rx_params;
-
- mutex_lock(&ir_state->rx_params_lock);
-
- o->shutdown = p->shutdown;
-
- p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
- o->mode = p->mode;
-
- p->bytes_per_data_element = sizeof(union cx25840_ir_fifo_rec);
- o->bytes_per_data_element = p->bytes_per_data_element;
-
- /* Before we tweak the hardware, we have to disable the receiver */
- irqenable_rx(sd, 0);
- control_rx_enable(c, false);
-
- control_rx_demodulation_enable(c, p->modulation);
- o->modulation = p->modulation;
-
- if (p->modulation) {
- p->carrier_freq = rxclk_rx_s_carrier(c, p->carrier_freq,
- &rxclk_divider);
-
- o->carrier_freq = p->carrier_freq;
-
- p->duty_cycle = 50;
- o->duty_cycle = p->duty_cycle;
-
- control_rx_s_carrier_window(c, p->carrier_freq,
- &p->carrier_range_lower,
- &p->carrier_range_upper);
- o->carrier_range_lower = p->carrier_range_lower;
- o->carrier_range_upper = p->carrier_range_upper;
-
- p->max_pulse_width =
- (u32) pulse_width_count_to_ns(FIFO_RXTX, rxclk_divider);
- } else {
- p->max_pulse_width =
- rxclk_rx_s_max_pulse_width(c, p->max_pulse_width,
- &rxclk_divider);
- }
- o->max_pulse_width = p->max_pulse_width;
- atomic_set(&ir_state->rxclk_divider, rxclk_divider);
-
- p->noise_filter_min_width =
- filter_rx_s_min_width(c, p->noise_filter_min_width);
- o->noise_filter_min_width = p->noise_filter_min_width;
-
- p->resolution = clock_divider_to_resolution(rxclk_divider);
- o->resolution = p->resolution;
-
- /* FIXME - make this dependent on resolution for better performance */
- control_rx_irq_watermark(c, RX_FIFO_HALF_FULL);
-
- control_rx_s_edge_detection(c, CNTRL_EDG_BOTH);
-
- o->invert_level = p->invert_level;
- atomic_set(&ir_state->rx_invert, p->invert_level);
-
- o->interrupt_enable = p->interrupt_enable;
- o->enable = p->enable;
- if (p->enable) {
- unsigned long flags;
-
- spin_lock_irqsave(&ir_state->rx_kfifo_lock, flags);
- kfifo_reset(&ir_state->rx_kfifo);
- spin_unlock_irqrestore(&ir_state->rx_kfifo_lock, flags);
- if (p->interrupt_enable)
- irqenable_rx(sd, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE);
- control_rx_enable(c, p->enable);
- }
-
- mutex_unlock(&ir_state->rx_params_lock);
- return 0;
-}
-
-/* Transmitter */
-static int cx25840_ir_tx_write(struct v4l2_subdev *sd, u8 *buf, size_t count,
- ssize_t *num)
-{
- struct cx25840_ir_state *ir_state = to_ir_state(sd);
-
- if (ir_state == NULL)
- return -ENODEV;
-
-#if 0
- /*
- * FIXME - the code below is an incomplete and untested sketch of what
- * may need to be done. The critical part is to get 4 (or 8) pulses
- * from the tx_kfifo, or converted from ns to the proper units from the
- * input, and push them off to the hardware Tx FIFO right away, if the
- * HW TX fifo needs service. The rest can be pushed to the tx_kfifo in
- * a less critical timeframe. Also watch out for overruning the
- * tx_kfifo - don't let it happen and let the caller know not all his
- * pulses were written.
- */
- u32 *ns_pulse = (u32 *) buf;
- unsigned int n;
- u32 fifo_pulse[FIFO_TX_DEPTH];
- u32 mark;
-
- /* Compute how much we can fit in the tx kfifo */
- n = CX25840_IR_TX_KFIFO_SIZE - kfifo_len(ir_state->tx_kfifo);
- n = min(n, (unsigned int) count);
- n /= sizeof(u32);
-
- /* FIXME - turn on Tx Fifo service interrupt
- * check hardware fifo level, and other stuff
- */
- for (i = 0; i < n; ) {
- for (j = 0; j < FIFO_TX_DEPTH / 2 && i < n; j++) {
- mark = ns_pulse[i] & LEVEL_MASK;
- fifo_pulse[j] = ns_to_pulse_width_count(
- ns_pulse[i] &
- ~LEVEL_MASK,
- ir_state->txclk_divider);
- if (mark)
- fifo_pulse[j] &= FIFO_RXTX_LVL;
- i++;
- }
- kfifo_put(ir_state->tx_kfifo, (u8 *) fifo_pulse,
- j * sizeof(u32));
- }
- *num = n * sizeof(u32);
-#else
- /* For now enable the Tx FIFO Service interrupt & pretend we did work */
- irqenable_tx(sd, IRQEN_TSE);
- *num = count;
-#endif
- return 0;
-}
-
-static int cx25840_ir_tx_g_parameters(struct v4l2_subdev *sd,
- struct v4l2_subdev_ir_parameters *p)
-{
- struct cx25840_ir_state *ir_state = to_ir_state(sd);
-
- if (ir_state == NULL)
- return -ENODEV;
-
- mutex_lock(&ir_state->tx_params_lock);
- memcpy(p, &ir_state->tx_params,
- sizeof(struct v4l2_subdev_ir_parameters));
- mutex_unlock(&ir_state->tx_params_lock);
- return 0;
-}
-
-static int cx25840_ir_tx_shutdown(struct v4l2_subdev *sd)
-{
- struct cx25840_ir_state *ir_state = to_ir_state(sd);
- struct i2c_client *c;
-
- if (ir_state == NULL)
- return -ENODEV;
-
- c = ir_state->c;
- mutex_lock(&ir_state->tx_params_lock);
-
- /* Disable or slow down all IR Tx circuits and counters */
- irqenable_tx(sd, 0);
- control_tx_enable(c, false);
- control_tx_modulation_enable(c, false);
- cx25840_write4(c, CX25840_IR_TXCLK_REG, TXCLK_TCD);
-
- ir_state->tx_params.shutdown = true;
-
- mutex_unlock(&ir_state->tx_params_lock);
- return 0;
-}
-
-static int cx25840_ir_tx_s_parameters(struct v4l2_subdev *sd,
- struct v4l2_subdev_ir_parameters *p)
-{
- struct cx25840_ir_state *ir_state = to_ir_state(sd);
- struct i2c_client *c;
- struct v4l2_subdev_ir_parameters *o;
- u16 txclk_divider;
-
- if (ir_state == NULL)
- return -ENODEV;
-
- if (p->shutdown)
- return cx25840_ir_tx_shutdown(sd);
-
- if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH)
- return -ENOSYS;
-
- c = ir_state->c;
- o = &ir_state->tx_params;
- mutex_lock(&ir_state->tx_params_lock);
-
- o->shutdown = p->shutdown;
-
- p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
- o->mode = p->mode;
-
- p->bytes_per_data_element = sizeof(union cx25840_ir_fifo_rec);
- o->bytes_per_data_element = p->bytes_per_data_element;
-
- /* Before we tweak the hardware, we have to disable the transmitter */
- irqenable_tx(sd, 0);
- control_tx_enable(c, false);
-
- control_tx_modulation_enable(c, p->modulation);
- o->modulation = p->modulation;
-
- if (p->modulation) {
- p->carrier_freq = txclk_tx_s_carrier(c, p->carrier_freq,
- &txclk_divider);
- o->carrier_freq = p->carrier_freq;
-
- p->duty_cycle = cduty_tx_s_duty_cycle(c, p->duty_cycle);
- o->duty_cycle = p->duty_cycle;
-
- p->max_pulse_width =
- (u32) pulse_width_count_to_ns(FIFO_RXTX, txclk_divider);
- } else {
- p->max_pulse_width =
- txclk_tx_s_max_pulse_width(c, p->max_pulse_width,
- &txclk_divider);
- }
- o->max_pulse_width = p->max_pulse_width;
- atomic_set(&ir_state->txclk_divider, txclk_divider);
-
- p->resolution = clock_divider_to_resolution(txclk_divider);
- o->resolution = p->resolution;
-
- /* FIXME - make this dependent on resolution for better performance */
- control_tx_irq_watermark(c, TX_FIFO_HALF_EMPTY);
-
- control_tx_polarity_invert(c, p->invert_carrier_sense);
- o->invert_carrier_sense = p->invert_carrier_sense;
-
- /*
- * FIXME: we don't have hardware help for IO pin level inversion
- * here like we have on the CX23888.
- * Act on this with some mix of logical inversion of data levels,
- * carrier polarity, and carrier duty cycle.
- */
- o->invert_level = p->invert_level;
-
- o->interrupt_enable = p->interrupt_enable;
- o->enable = p->enable;
- if (p->enable) {
- /* reset tx_fifo here */
- if (p->interrupt_enable)
- irqenable_tx(sd, IRQEN_TSE);
- control_tx_enable(c, p->enable);
- }
-
- mutex_unlock(&ir_state->tx_params_lock);
- return 0;
-}
-
-
-/*
- * V4L2 Subdevice Core Ops support
- */
-int cx25840_ir_log_status(struct v4l2_subdev *sd)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *c = state->c;
- char *s;
- int i, j;
- u32 cntrl, txclk, rxclk, cduty, stats, irqen, filtr;
-
- /* The CX23888 chip doesn't have an IR controller on the A/V core */
- if (is_cx23888(state))
- return 0;
-
- cntrl = cx25840_read4(c, CX25840_IR_CNTRL_REG);
- txclk = cx25840_read4(c, CX25840_IR_TXCLK_REG) & TXCLK_TCD;
- rxclk = cx25840_read4(c, CX25840_IR_RXCLK_REG) & RXCLK_RCD;
- cduty = cx25840_read4(c, CX25840_IR_CDUTY_REG) & CDUTY_CDC;
- stats = cx25840_read4(c, CX25840_IR_STATS_REG);
- irqen = cx25840_read4(c, CX25840_IR_IRQEN_REG);
- if (is_cx23885(state) || is_cx23887(state))
- irqen ^= IRQEN_MSK;
- filtr = cx25840_read4(c, CX25840_IR_FILTR_REG) & FILTR_LPF;
-
- v4l2_info(sd, "IR Receiver:\n");
- v4l2_info(sd, "\tEnabled: %s\n",
- cntrl & CNTRL_RXE ? "yes" : "no");
- v4l2_info(sd, "\tDemodulation from a carrier: %s\n",
- cntrl & CNTRL_DMD ? "enabled" : "disabled");
- v4l2_info(sd, "\tFIFO: %s\n",
- cntrl & CNTRL_RFE ? "enabled" : "disabled");
- switch (cntrl & CNTRL_EDG) {
- case CNTRL_EDG_NONE:
- s = "disabled";
- break;
- case CNTRL_EDG_FALL:
- s = "falling edge";
- break;
- case CNTRL_EDG_RISE:
- s = "rising edge";
- break;
- case CNTRL_EDG_BOTH:
- s = "rising & falling edges";
- break;
- default:
- s = "??? edge";
- break;
- }
- v4l2_info(sd, "\tPulse timers' start/stop trigger: %s\n", s);
- v4l2_info(sd, "\tFIFO data on pulse timer overflow: %s\n",
- cntrl & CNTRL_R ? "not loaded" : "overflow marker");
- v4l2_info(sd, "\tFIFO interrupt watermark: %s\n",
- cntrl & CNTRL_RIC ? "not empty" : "half full or greater");
- v4l2_info(sd, "\tLoopback mode: %s\n",
- cntrl & CNTRL_LBM ? "loopback active" : "normal receive");
- if (cntrl & CNTRL_DMD) {
- v4l2_info(sd, "\tExpected carrier (16 clocks): %u Hz\n",
- clock_divider_to_carrier_freq(rxclk));
- switch (cntrl & CNTRL_WIN) {
- case CNTRL_WIN_3_3:
- i = 3;
- j = 3;
- break;
- case CNTRL_WIN_4_3:
- i = 4;
- j = 3;
- break;
- case CNTRL_WIN_3_4:
- i = 3;
- j = 4;
- break;
- case CNTRL_WIN_4_4:
- i = 4;
- j = 4;
- break;
- default:
- i = 0;
- j = 0;
- break;
- }
- v4l2_info(sd, "\tNext carrier edge window: 16 clocks "
- "-%1d/+%1d, %u to %u Hz\n", i, j,
- clock_divider_to_freq(rxclk, 16 + j),
- clock_divider_to_freq(rxclk, 16 - i));
- }
- v4l2_info(sd, "\tMax measurable pulse width: %u us, %llu ns\n",
- pulse_width_count_to_us(FIFO_RXTX, rxclk),
- pulse_width_count_to_ns(FIFO_RXTX, rxclk));
- v4l2_info(sd, "\tLow pass filter: %s\n",
- filtr ? "enabled" : "disabled");
- if (filtr)
- v4l2_info(sd, "\tMin acceptable pulse width (LPF): %u us, "
- "%u ns\n",
- lpf_count_to_us(filtr),
- lpf_count_to_ns(filtr));
- v4l2_info(sd, "\tPulse width timer timed-out: %s\n",
- stats & STATS_RTO ? "yes" : "no");
- v4l2_info(sd, "\tPulse width timer time-out intr: %s\n",
- irqen & IRQEN_RTE ? "enabled" : "disabled");
- v4l2_info(sd, "\tFIFO overrun: %s\n",
- stats & STATS_ROR ? "yes" : "no");
- v4l2_info(sd, "\tFIFO overrun interrupt: %s\n",
- irqen & IRQEN_ROE ? "enabled" : "disabled");
- v4l2_info(sd, "\tBusy: %s\n",
- stats & STATS_RBY ? "yes" : "no");
- v4l2_info(sd, "\tFIFO service requested: %s\n",
- stats & STATS_RSR ? "yes" : "no");
- v4l2_info(sd, "\tFIFO service request interrupt: %s\n",
- irqen & IRQEN_RSE ? "enabled" : "disabled");
-
- v4l2_info(sd, "IR Transmitter:\n");
- v4l2_info(sd, "\tEnabled: %s\n",
- cntrl & CNTRL_TXE ? "yes" : "no");
- v4l2_info(sd, "\tModulation onto a carrier: %s\n",
- cntrl & CNTRL_MOD ? "enabled" : "disabled");
- v4l2_info(sd, "\tFIFO: %s\n",
- cntrl & CNTRL_TFE ? "enabled" : "disabled");
- v4l2_info(sd, "\tFIFO interrupt watermark: %s\n",
- cntrl & CNTRL_TIC ? "not empty" : "half full or less");
- v4l2_info(sd, "\tCarrier polarity: %s\n",
- cntrl & CNTRL_CPL ? "space:burst mark:noburst"
- : "space:noburst mark:burst");
- if (cntrl & CNTRL_MOD) {
- v4l2_info(sd, "\tCarrier (16 clocks): %u Hz\n",
- clock_divider_to_carrier_freq(txclk));
- v4l2_info(sd, "\tCarrier duty cycle: %2u/16\n",
- cduty + 1);
- }
- v4l2_info(sd, "\tMax pulse width: %u us, %llu ns\n",
- pulse_width_count_to_us(FIFO_RXTX, txclk),
- pulse_width_count_to_ns(FIFO_RXTX, txclk));
- v4l2_info(sd, "\tBusy: %s\n",
- stats & STATS_TBY ? "yes" : "no");
- v4l2_info(sd, "\tFIFO service requested: %s\n",
- stats & STATS_TSR ? "yes" : "no");
- v4l2_info(sd, "\tFIFO service request interrupt: %s\n",
- irqen & IRQEN_TSE ? "enabled" : "disabled");
-
- return 0;
-}
-
-
-const struct v4l2_subdev_ir_ops cx25840_ir_ops = {
- .rx_read = cx25840_ir_rx_read,
- .rx_g_parameters = cx25840_ir_rx_g_parameters,
- .rx_s_parameters = cx25840_ir_rx_s_parameters,
-
- .tx_write = cx25840_ir_tx_write,
- .tx_g_parameters = cx25840_ir_tx_g_parameters,
- .tx_s_parameters = cx25840_ir_tx_s_parameters,
-};
-
-
-static const struct v4l2_subdev_ir_parameters default_rx_params = {
- .bytes_per_data_element = sizeof(union cx25840_ir_fifo_rec),
- .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
-
- .enable = false,
- .interrupt_enable = false,
- .shutdown = true,
-
- .modulation = true,
- .carrier_freq = 36000, /* 36 kHz - RC-5, and RC-6 carrier */
-
- /* RC-5: 666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */
- /* RC-6: 333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */
- .noise_filter_min_width = 333333, /* ns */
- .carrier_range_lower = 35000,
- .carrier_range_upper = 37000,
- .invert_level = false,
-};
-
-static const struct v4l2_subdev_ir_parameters default_tx_params = {
- .bytes_per_data_element = sizeof(union cx25840_ir_fifo_rec),
- .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
-
- .enable = false,
- .interrupt_enable = false,
- .shutdown = true,
-
- .modulation = true,
- .carrier_freq = 36000, /* 36 kHz - RC-5 carrier */
- .duty_cycle = 25, /* 25 % - RC-5 carrier */
- .invert_level = false,
- .invert_carrier_sense = false,
-};
-
-int cx25840_ir_probe(struct v4l2_subdev *sd)
-{
- struct cx25840_state *state = to_state(sd);
- struct cx25840_ir_state *ir_state;
- struct v4l2_subdev_ir_parameters default_params;
-
- /* Only init the IR controller for the CX2388[57] AV Core for now */
- if (!(is_cx23885(state) || is_cx23887(state)))
- return 0;
-
- ir_state = kzalloc(sizeof(struct cx25840_ir_state), GFP_KERNEL);
- if (ir_state == NULL)
- return -ENOMEM;
-
- spin_lock_init(&ir_state->rx_kfifo_lock);
- if (kfifo_alloc(&ir_state->rx_kfifo,
- CX25840_IR_RX_KFIFO_SIZE, GFP_KERNEL)) {
- kfree(ir_state);
- return -ENOMEM;
- }
-
- ir_state->c = state->c;
- state->ir_state = ir_state;
-
- /* Ensure no interrupts arrive yet */
- if (is_cx23885(state) || is_cx23887(state))
- cx25840_write4(ir_state->c, CX25840_IR_IRQEN_REG, IRQEN_MSK);
- else
- cx25840_write4(ir_state->c, CX25840_IR_IRQEN_REG, 0);
-
- mutex_init(&ir_state->rx_params_lock);
- memcpy(&default_params, &default_rx_params,
- sizeof(struct v4l2_subdev_ir_parameters));
- v4l2_subdev_call(sd, ir, rx_s_parameters, &default_params);
-
- mutex_init(&ir_state->tx_params_lock);
- memcpy(&default_params, &default_tx_params,
- sizeof(struct v4l2_subdev_ir_parameters));
- v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params);
-
- return 0;
-}
-
-int cx25840_ir_remove(struct v4l2_subdev *sd)
-{
- struct cx25840_state *state = to_state(sd);
- struct cx25840_ir_state *ir_state = to_ir_state(sd);
-
- if (ir_state == NULL)
- return -ENODEV;
-
- cx25840_ir_rx_shutdown(sd);
- cx25840_ir_tx_shutdown(sd);
-
- kfifo_free(&ir_state->rx_kfifo);
- kfree(ir_state);
- state->ir_state = NULL;
- return 0;
-}
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c
deleted file mode 100644
index 64a4004f8a9..00000000000
--- a/drivers/media/video/cx25840/cx25840-vbi.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/* cx25840 VBI functions
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-
-#include <linux/videodev2.h>
-#include <linux/i2c.h>
-#include <media/v4l2-common.h>
-#include <media/cx25840.h>
-
-#include "cx25840-core.h"
-
-static int odd_parity(u8 c)
-{
- c ^= (c >> 4);
- c ^= (c >> 2);
- c ^= (c >> 1);
-
- return c & 1;
-}
-
-static int decode_vps(u8 * dst, u8 * p)
-{
- static const u8 biphase_tbl[] = {
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
- 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
- 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
- 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
- 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
- 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
- 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
- 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
- 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
- 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
- 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
- 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
- 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
- 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
- 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
- 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
- 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
- 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
- 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
- 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
- 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
- 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- };
-
- u8 c, err = 0;
- int i;
-
- for (i = 0; i < 2 * 13; i += 2) {
- err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
- c = (biphase_tbl[p[i + 1]] & 0xf) |
- ((biphase_tbl[p[i]] & 0xf) << 4);
- dst[i / 2] = c;
- }
-
- return err & 0xf0;
-}
-
-int cx25840_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct cx25840_state *state = to_state(sd);
- static const u16 lcr2vbi[] = {
- 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
- 0, V4L2_SLICED_WSS_625, 0, /* 4 */
- V4L2_SLICED_CAPTION_525, /* 6 */
- 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
- 0, 0, 0, 0
- };
- int is_pal = !(state->std & V4L2_STD_525_60);
- int i;
-
- memset(svbi, 0, sizeof(*svbi));
- /* we're done if raw VBI is active */
- if ((cx25840_read(client, 0x404) & 0x10) == 0)
- return 0;
-
- if (is_pal) {
- for (i = 7; i <= 23; i++) {
- u8 v = cx25840_read(client, 0x424 + i - 7);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |= svbi->service_lines[0][i] |
- svbi->service_lines[1][i];
- }
- } else {
- for (i = 10; i <= 21; i++) {
- u8 v = cx25840_read(client, 0x424 + i - 10);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |= svbi->service_lines[0][i] |
- svbi->service_lines[1][i];
- }
- }
- return 0;
-}
-
-int cx25840_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct cx25840_state *state = to_state(sd);
- int is_pal = !(state->std & V4L2_STD_525_60);
- int vbi_offset = is_pal ? 1 : 0;
-
- /* Setup standard */
- cx25840_std_setup(client);
-
- /* VBI Offset */
- cx25840_write(client, 0x47f, vbi_offset);
- cx25840_write(client, 0x404, 0x2e);
- return 0;
-}
-
-int cx25840_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct cx25840_state *state = to_state(sd);
- int is_pal = !(state->std & V4L2_STD_525_60);
- int vbi_offset = is_pal ? 1 : 0;
- int i, x;
- u8 lcr[24];
-
- for (x = 0; x <= 23; x++)
- lcr[x] = 0x00;
-
- /* Setup standard */
- cx25840_std_setup(client);
-
- /* Sliced VBI */
- cx25840_write(client, 0x404, 0x32); /* Ancillary data */
- cx25840_write(client, 0x406, 0x13);
- cx25840_write(client, 0x47f, vbi_offset);
-
- if (is_pal) {
- for (i = 0; i <= 6; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- } else {
- for (i = 0; i <= 9; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
-
- for (i = 22; i <= 23; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- }
-
- for (i = 7; i <= 23; i++) {
- for (x = 0; x <= 1; x++) {
- switch (svbi->service_lines[1-x][i]) {
- case V4L2_SLICED_TELETEXT_B:
- lcr[i] |= 1 << (4 * x);
- break;
- case V4L2_SLICED_WSS_625:
- lcr[i] |= 4 << (4 * x);
- break;
- case V4L2_SLICED_CAPTION_525:
- lcr[i] |= 6 << (4 * x);
- break;
- case V4L2_SLICED_VPS:
- lcr[i] |= 9 << (4 * x);
- break;
- }
- }
- }
-
- if (is_pal) {
- for (x = 1, i = 0x424; i <= 0x434; i++, x++)
- cx25840_write(client, i, lcr[6 + x]);
- } else {
- for (x = 1, i = 0x424; i <= 0x430; i++, x++)
- cx25840_write(client, i, lcr[9 + x]);
- for (i = 0x431; i <= 0x434; i++)
- cx25840_write(client, i, 0);
- }
-
- cx25840_write(client, 0x43c, 0x16);
- cx25840_write(client, 0x474, is_pal ? 0x2a : 0x22);
- return 0;
-}
-
-int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
-{
- struct cx25840_state *state = to_state(sd);
- u8 *p = vbi->p;
- int id1, id2, l, err = 0;
-
- if (p[0] || p[1] != 0xff || p[2] != 0xff ||
- (p[3] != 0x55 && p[3] != 0x91)) {
- vbi->line = vbi->type = 0;
- return 0;
- }
-
- p += 4;
- id1 = p[-1];
- id2 = p[0] & 0xf;
- l = p[2] & 0x3f;
- l += state->vbi_line_offset;
- p += 4;
-
- switch (id2) {
- case 1:
- id2 = V4L2_SLICED_TELETEXT_B;
- break;
- case 4:
- id2 = V4L2_SLICED_WSS_625;
- break;
- case 6:
- id2 = V4L2_SLICED_CAPTION_525;
- err = !odd_parity(p[0]) || !odd_parity(p[1]);
- break;
- case 9:
- id2 = V4L2_SLICED_VPS;
- if (decode_vps(p, p) != 0)
- err = 1;
- break;
- default:
- id2 = 0;
- err = 1;
- break;
- }
-
- vbi->type = err ? 0 : id2;
- vbi->line = err ? 0 : l;
- vbi->is_second_field = err ? 0 : (id1 == 0x55);
- vbi->p = p;
- return 0;
-}
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
deleted file mode 100644
index 3598dc087b0..00000000000
--- a/drivers/media/video/cx88/Kconfig
+++ /dev/null
@@ -1,86 +0,0 @@
-config VIDEO_CX88
- tristate "Conexant 2388x (bt878 successor) support"
- depends on VIDEO_DEV && PCI && I2C && RC_CORE
- select I2C_ALGOBIT
- select VIDEO_BTCX
- select VIDEOBUF_DMA_SG
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO
- ---help---
- This is a video4linux driver for Conexant 2388x based
- TV cards.
-
- To compile this driver as a module, choose M here: the
- module will be called cx8800
-
-config VIDEO_CX88_ALSA
- tristate "Conexant 2388x DMA audio support"
- depends on VIDEO_CX88 && SND
- select SND_PCM
- ---help---
- This is a video4linux driver for direct (DMA) audio on
- Conexant 2388x based TV cards using ALSA.
-
- It only works with boards with function 01 enabled.
- To check if your board supports, use lspci -n.
- If supported, you should see 14f1:8801 or 14f1:8811
- PCI device.
-
- To compile this driver as a module, choose M here: the
- module will be called cx88-alsa.
-
-config VIDEO_CX88_BLACKBIRD
- tristate "Blackbird MPEG encoder support (cx2388x + cx23416)"
- depends on VIDEO_CX88
- select VIDEO_CX2341X
- ---help---
- This adds support for MPEG encoder cards based on the
- Blackbird reference design, using the Conexant 2388x
- and 23416 chips.
-
- To compile this driver as a module, choose M here: the
- module will be called cx88-blackbird.
-
-config VIDEO_CX88_DVB
- tristate "DVB/ATSC Support for cx2388x based TV cards"
- depends on VIDEO_CX88 && DVB_CORE
- select VIDEOBUF_DVB
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select DVB_MT352 if !DVB_FE_CUSTOMISE
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select DVB_OR51132 if !DVB_FE_CUSTOMISE
- select DVB_CX22702 if !DVB_FE_CUSTOMISE
- select DVB_LGDT330X if !DVB_FE_CUSTOMISE
- select DVB_NXT200X if !DVB_FE_CUSTOMISE
- select DVB_CX24123 if !DVB_FE_CUSTOMISE
- select DVB_ISL6421 if !DVB_FE_CUSTOMISE
- select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select DVB_CX24116 if !DVB_FE_CUSTOMISE
- select DVB_STV0299 if !DVB_FE_CUSTOMISE
- select DVB_STV0288 if !DVB_FE_CUSTOMISE
- select DVB_STB6000 if !DVB_FE_CUSTOMISE
- select DVB_STV0900 if !DVB_FE_CUSTOMISE
- select DVB_STB6100 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
- ---help---
- This adds support for DVB/ATSC cards based on the
- Conexant 2388x chip.
-
- To compile this driver as a module, choose M here: the
- module will be called cx88-dvb.
-
-config VIDEO_CX88_VP3054
- tristate "VP-3054 Secondary I2C Bus Support"
- default m
- depends on VIDEO_CX88_DVB && DVB_MT352
- ---help---
- This adds DVB-T support for cards based on the
- Conexant 2388x chip and the MT352 demodulator,
- which also require support for the VP-3054
- Secondary I2C bus, such at DNTV Live! DVB-T Pro.
-
-config VIDEO_CX88_MPEG
- tristate
- depends on VIDEO_CX88_DVB || VIDEO_CX88_BLACKBIRD
- default y
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
deleted file mode 100644
index c1a2785ba24..00000000000
--- a/drivers/media/video/cx88/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \
- cx88-dsp.o cx88-input.o
-cx8800-objs := cx88-video.o cx88-vbi.o
-cx8802-objs := cx88-mpeg.o
-
-obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o
-obj-$(CONFIG_VIDEO_CX88_MPEG) += cx8802.o
-obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o
-obj-$(CONFIG_VIDEO_CX88_BLACKBIRD) += cx88-blackbird.o
-obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
-obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o
-
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
deleted file mode 100644
index dfac6e34859..00000000000
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ /dev/null
@@ -1,975 +0,0 @@
-/*
- *
- * Support for audio capture
- * PCI function #1 of the cx2388x.
- *
- * (c) 2007 Trent Piepho <xyzzy@speakeasy.org>
- * (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org>
- * (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
- * Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org>
- * Based on dummy.c by Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/vmalloc.h>
-#include <linux/dma-mapping.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include <asm/delay.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/control.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <media/wm8775.h>
-
-#include "cx88.h"
-#include "cx88-reg.h"
-
-#define dprintk(level,fmt, arg...) if (debug >= level) \
- printk(KERN_INFO "%s/1: " fmt, chip->core->name , ## arg)
-
-#define dprintk_core(level,fmt, arg...) if (debug >= level) \
- printk(KERN_DEBUG "%s/1: " fmt, chip->core->name , ## arg)
-
-/****************************************************************************
- Data type declarations - Can be moded to a header file later
- ****************************************************************************/
-
-struct cx88_audio_buffer {
- unsigned int bpl;
- struct btcx_riscmem risc;
- struct videobuf_dmabuf dma;
-};
-
-struct cx88_audio_dev {
- struct cx88_core *core;
- struct cx88_dmaqueue q;
-
- /* pci i/o */
- struct pci_dev *pci;
-
- /* audio controls */
- int irq;
-
- struct snd_card *card;
-
- spinlock_t reg_lock;
- atomic_t count;
-
- unsigned int dma_size;
- unsigned int period_size;
- unsigned int num_periods;
-
- struct videobuf_dmabuf *dma_risc;
-
- struct cx88_audio_buffer *buf;
-
- struct snd_pcm_substream *substream;
-};
-typedef struct cx88_audio_dev snd_cx88_card_t;
-
-
-
-/****************************************************************************
- Module global static vars
- ****************************************************************************/
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static const char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
-
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled.");
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s).");
-
-
-/****************************************************************************
- Module macros
- ****************************************************************************/
-
-MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards");
-MODULE_AUTHOR("Ricardo Cerqueira");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(CX88_VERSION);
-
-MODULE_SUPPORTED_DEVICE("{{Conexant,23881},"
- "{{Conexant,23882},"
- "{{Conexant,23883}");
-static unsigned int debug;
-module_param(debug,int,0644);
-MODULE_PARM_DESC(debug,"enable debug messages");
-
-/****************************************************************************
- Module specific funtions
- ****************************************************************************/
-
-/*
- * BOARD Specific: Sets audio DMA
- */
-
-static int _cx88_start_audio_dma(snd_cx88_card_t *chip)
-{
- struct cx88_audio_buffer *buf = chip->buf;
- struct cx88_core *core=chip->core;
- const struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25];
-
- /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */
- cx_clear(MO_AUD_DMACNTRL, 0x11);
-
- /* setup fifo + format - out channel */
- cx88_sram_channel_setup(chip->core, audio_ch, buf->bpl, buf->risc.dma);
-
- /* sets bpl size */
- cx_write(MO_AUDD_LNGTH, buf->bpl);
-
- /* reset counter */
- cx_write(MO_AUDD_GPCNTRL, GP_COUNT_CONTROL_RESET);
- atomic_set(&chip->count, 0);
-
- dprintk(1, "Start audio DMA, %d B/line, %d lines/FIFO, %d periods, %d "
- "byte buffer\n", buf->bpl, cx_read(audio_ch->cmds_start + 8)>>1,
- chip->num_periods, buf->bpl * chip->num_periods);
-
- /* Enables corresponding bits at AUD_INT_STAT */
- cx_write(MO_AUD_INTMSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC |
- AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1);
-
- /* Clean any pending interrupt bits already set */
- cx_write(MO_AUD_INTSTAT, ~0);
-
- /* enable audio irqs */
- cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | PCI_INT_AUDINT);
-
- /* start dma */
- cx_set(MO_DEV_CNTRL2, (1<<5)); /* Enables Risc Processor */
- cx_set(MO_AUD_DMACNTRL, 0x11); /* audio downstream FIFO and RISC enable */
-
- if (debug)
- cx88_sram_channel_dump(chip->core, audio_ch);
-
- return 0;
-}
-
-/*
- * BOARD Specific: Resets audio DMA
- */
-static int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
-{
- struct cx88_core *core=chip->core;
- dprintk(1, "Stopping audio DMA\n");
-
- /* stop dma */
- cx_clear(MO_AUD_DMACNTRL, 0x11);
-
- /* disable irqs */
- cx_clear(MO_PCI_INTMSK, PCI_INT_AUDINT);
- cx_clear(MO_AUD_INTMSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC |
- AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1);
-
- if (debug)
- cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]);
-
- return 0;
-}
-
-#define MAX_IRQ_LOOP 50
-
-/*
- * BOARD Specific: IRQ dma bits
- */
-static const char *cx88_aud_irqs[32] = {
- "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */
- NULL, /* reserved */
- "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */
- NULL, /* reserved */
- "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */
- NULL, /* reserved */
- "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */
- NULL, /* reserved */
- "opc_err", "par_err", "rip_err", /* 16-18 */
- "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */
-};
-
-/*
- * BOARD Specific: Threats IRQ audio specific calls
- */
-static void cx8801_aud_irq(snd_cx88_card_t *chip)
-{
- struct cx88_core *core = chip->core;
- u32 status, mask;
-
- status = cx_read(MO_AUD_INTSTAT);
- mask = cx_read(MO_AUD_INTMSK);
- if (0 == (status & mask))
- return;
- cx_write(MO_AUD_INTSTAT, status);
- if (debug > 1 || (status & mask & ~0xff))
- cx88_print_irqbits(core->name, "irq aud",
- cx88_aud_irqs, ARRAY_SIZE(cx88_aud_irqs),
- status, mask);
- /* risc op code error */
- if (status & AUD_INT_OPC_ERR) {
- printk(KERN_WARNING "%s/1: Audio risc op code error\n",core->name);
- cx_clear(MO_AUD_DMACNTRL, 0x11);
- cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH25]);
- }
- if (status & AUD_INT_DN_SYNC) {
- dprintk(1, "Downstream sync error\n");
- cx_write(MO_AUDD_GPCNTRL, GP_COUNT_CONTROL_RESET);
- return;
- }
- /* risc1 downstream */
- if (status & AUD_INT_DN_RISCI1) {
- atomic_set(&chip->count, cx_read(MO_AUDD_GPCNT));
- snd_pcm_period_elapsed(chip->substream);
- }
- /* FIXME: Any other status should deserve a special handling? */
-}
-
-/*
- * BOARD Specific: Handles IRQ calls
- */
-static irqreturn_t cx8801_irq(int irq, void *dev_id)
-{
- snd_cx88_card_t *chip = dev_id;
- struct cx88_core *core = chip->core;
- u32 status;
- int loop, handled = 0;
-
- for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
- status = cx_read(MO_PCI_INTSTAT) &
- (core->pci_irqmask | PCI_INT_AUDINT);
- if (0 == status)
- goto out;
- dprintk(3, "cx8801_irq loop %d/%d, status %x\n",
- loop, MAX_IRQ_LOOP, status);
- handled = 1;
- cx_write(MO_PCI_INTSTAT, status);
-
- if (status & core->pci_irqmask)
- cx88_core_irq(core, status);
- if (status & PCI_INT_AUDINT)
- cx8801_aud_irq(chip);
- }
-
- if (MAX_IRQ_LOOP == loop) {
- printk(KERN_ERR
- "%s/1: IRQ loop detected, disabling interrupts\n",
- core->name);
- cx_clear(MO_PCI_INTMSK, PCI_INT_AUDINT);
- }
-
- out:
- return IRQ_RETVAL(handled);
-}
-
-
-static int dsp_buffer_free(snd_cx88_card_t *chip)
-{
- BUG_ON(!chip->dma_size);
-
- dprintk(2,"Freeing buffer\n");
- videobuf_dma_unmap(&chip->pci->dev, chip->dma_risc);
- videobuf_dma_free(chip->dma_risc);
- btcx_riscmem_free(chip->pci,&chip->buf->risc);
- kfree(chip->buf);
-
- chip->dma_risc = NULL;
- chip->dma_size = 0;
-
- return 0;
-}
-
-/****************************************************************************
- ALSA PCM Interface
- ****************************************************************************/
-
-/*
- * Digital hardware definition
- */
-#define DEFAULT_FIFO_SIZE 4096
-static const struct snd_pcm_hardware snd_cx88_digital_hw = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
-
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- /* Analog audio output will be full of clicks and pops if there
- are not exactly four lines in the SRAM FIFO buffer. */
- .period_bytes_min = DEFAULT_FIFO_SIZE/4,
- .period_bytes_max = DEFAULT_FIFO_SIZE/4,
- .periods_min = 1,
- .periods_max = 1024,
- .buffer_bytes_max = (1024*1024),
-};
-
-/*
- * audio pcm capture open callback
- */
-static int snd_cx88_pcm_open(struct snd_pcm_substream *substream)
-{
- snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- if (!chip) {
- printk(KERN_ERR "BUG: cx88 can't find device struct."
- " Can't proceed with open\n");
- return -ENODEV;
- }
-
- err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0)
- goto _error;
-
- chip->substream = substream;
-
- runtime->hw = snd_cx88_digital_hw;
-
- if (cx88_sram_channels[SRAM_CH25].fifo_size != DEFAULT_FIFO_SIZE) {
- unsigned int bpl = cx88_sram_channels[SRAM_CH25].fifo_size / 4;
- bpl &= ~7; /* must be multiple of 8 */
- runtime->hw.period_bytes_min = bpl;
- runtime->hw.period_bytes_max = bpl;
- }
-
- return 0;
-_error:
- dprintk(1,"Error opening PCM!\n");
- return err;
-}
-
-/*
- * audio close callback
- */
-static int snd_cx88_close(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-/*
- * hw_params callback
- */
-static int snd_cx88_hw_params(struct snd_pcm_substream * substream,
- struct snd_pcm_hw_params * hw_params)
-{
- snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
- struct videobuf_dmabuf *dma;
-
- struct cx88_audio_buffer *buf;
- int ret;
-
- if (substream->runtime->dma_area) {
- dsp_buffer_free(chip);
- substream->runtime->dma_area = NULL;
- }
-
- chip->period_size = params_period_bytes(hw_params);
- chip->num_periods = params_periods(hw_params);
- chip->dma_size = chip->period_size * params_periods(hw_params);
-
- BUG_ON(!chip->dma_size);
- BUG_ON(chip->num_periods & (chip->num_periods-1));
-
- buf = kzalloc(sizeof(*buf), GFP_KERNEL);
- if (NULL == buf)
- return -ENOMEM;
-
- buf->bpl = chip->period_size;
-
- dma = &buf->dma;
- videobuf_dma_init(dma);
- ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
- (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT));
- if (ret < 0)
- goto error;
-
- ret = videobuf_dma_map(&chip->pci->dev, dma);
- if (ret < 0)
- goto error;
-
- ret = cx88_risc_databuffer(chip->pci, &buf->risc, dma->sglist,
- chip->period_size, chip->num_periods, 1);
- if (ret < 0)
- goto error;
-
- /* Loop back to start of program */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP|RISC_IRQ1|RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-
- chip->buf = buf;
- chip->dma_risc = dma;
-
- substream->runtime->dma_area = chip->dma_risc->vaddr;
- substream->runtime->dma_bytes = chip->dma_size;
- substream->runtime->dma_addr = 0;
- return 0;
-
-error:
- kfree(buf);
- return ret;
-}
-
-/*
- * hw free callback
- */
-static int snd_cx88_hw_free(struct snd_pcm_substream * substream)
-{
-
- snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
-
- if (substream->runtime->dma_area) {
- dsp_buffer_free(chip);
- substream->runtime->dma_area = NULL;
- }
-
- return 0;
-}
-
-/*
- * prepare callback
- */
-static int snd_cx88_prepare(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-/*
- * trigger callback
- */
-static int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
- int err;
-
- /* Local interrupts are already disabled by ALSA */
- spin_lock(&chip->reg_lock);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- err=_cx88_start_audio_dma(chip);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- err=_cx88_stop_audio_dma(chip);
- break;
- default:
- err=-EINVAL;
- break;
- }
-
- spin_unlock(&chip->reg_lock);
-
- return err;
-}
-
-/*
- * pointer callback
- */
-static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream)
-{
- snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- u16 count;
-
- count = atomic_read(&chip->count);
-
-// dprintk(2, "%s - count %d (+%u), period %d, frame %lu\n", __func__,
-// count, new, count & (runtime->periods-1),
-// runtime->period_size * (count & (runtime->periods-1)));
- return runtime->period_size * (count & (runtime->periods-1));
-}
-
-/*
- * page callback (needed for mmap)
- */
-static struct page *snd_cx88_page(struct snd_pcm_substream *substream,
- unsigned long offset)
-{
- void *pageptr = substream->runtime->dma_area + offset;
- return vmalloc_to_page(pageptr);
-}
-
-/*
- * operators
- */
-static struct snd_pcm_ops snd_cx88_pcm_ops = {
- .open = snd_cx88_pcm_open,
- .close = snd_cx88_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cx88_hw_params,
- .hw_free = snd_cx88_hw_free,
- .prepare = snd_cx88_prepare,
- .trigger = snd_cx88_card_trigger,
- .pointer = snd_cx88_pointer,
- .page = snd_cx88_page,
-};
-
-/*
- * create a PCM device
- */
-static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, const char *name)
-{
- int err;
- struct snd_pcm *pcm;
-
- err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
- if (err < 0)
- return err;
- pcm->private_data = chip;
- strcpy(pcm->name, name);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx88_pcm_ops);
-
- return 0;
-}
-
-/****************************************************************************
- CONTROL INTERFACE
- ****************************************************************************/
-static int snd_cx88_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *info)
-{
- info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- info->count = 2;
- info->value.integer.min = 0;
- info->value.integer.max = 0x3f;
-
- return 0;
-}
-
-static int snd_cx88_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
- struct cx88_core *core=chip->core;
- int vol = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f),
- bal = cx_read(AUD_BAL_CTL);
-
- value->value.integer.value[(bal & 0x40) ? 0 : 1] = vol;
- vol -= (bal & 0x3f);
- value->value.integer.value[(bal & 0x40) ? 1 : 0] = vol < 0 ? 0 : vol;
-
- return 0;
-}
-
-static void snd_cx88_wm8775_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
- struct cx88_core *core = chip->core;
- int left = value->value.integer.value[0];
- int right = value->value.integer.value[1];
- int v, b;
-
- /* Pass volume & balance onto any WM8775 */
- if (left >= right) {
- v = left << 10;
- b = left ? (0x8000 * right) / left : 0x8000;
- } else {
- v = right << 10;
- b = right ? 0xffff - (0x8000 * left) / right : 0x8000;
- }
- wm8775_s_ctrl(core, V4L2_CID_AUDIO_VOLUME, v);
- wm8775_s_ctrl(core, V4L2_CID_AUDIO_BALANCE, b);
-}
-
-/* OK - TODO: test it */
-static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
- struct cx88_core *core=chip->core;
- int left, right, v, b;
- int changed = 0;
- u32 old;
-
- if (core->board.audio_chip == V4L2_IDENT_WM8775)
- snd_cx88_wm8775_volume_put(kcontrol, value);
-
- left = value->value.integer.value[0] & 0x3f;
- right = value->value.integer.value[1] & 0x3f;
- b = right - left;
- if (b < 0) {
- v = 0x3f - left;
- b = (-b) | 0x40;
- } else {
- v = 0x3f - right;
- }
- /* Do we really know this will always be called with IRQs on? */
- spin_lock_irq(&chip->reg_lock);
- old = cx_read(AUD_VOL_CTL);
- if (v != (old & 0x3f)) {
- cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, (old & ~0x3f) | v);
- changed = 1;
- }
- if ((cx_read(AUD_BAL_CTL) & 0x7f) != b) {
- cx_write(AUD_BAL_CTL, b);
- changed = 1;
- }
- spin_unlock_irq(&chip->reg_lock);
-
- return changed;
-}
-
-static const DECLARE_TLV_DB_SCALE(snd_cx88_db_scale, -6300, 100, 0);
-
-static const struct snd_kcontrol_new snd_cx88_volume = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .name = "Analog-TV Volume",
- .info = snd_cx88_volume_info,
- .get = snd_cx88_volume_get,
- .put = snd_cx88_volume_put,
- .tlv.p = snd_cx88_db_scale,
-};
-
-static int snd_cx88_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
- struct cx88_core *core = chip->core;
- u32 bit = kcontrol->private_value;
-
- value->value.integer.value[0] = !(cx_read(AUD_VOL_CTL) & bit);
- return 0;
-}
-
-static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
- struct cx88_core *core = chip->core;
- u32 bit = kcontrol->private_value;
- int ret = 0;
- u32 vol;
-
- spin_lock_irq(&chip->reg_lock);
- vol = cx_read(AUD_VOL_CTL);
- if (value->value.integer.value[0] != !(vol & bit)) {
- vol ^= bit;
- cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol);
- /* Pass mute onto any WM8775 */
- if ((core->board.audio_chip == V4L2_IDENT_WM8775) &&
- ((1<<6) == bit))
- wm8775_s_ctrl(core, V4L2_CID_AUDIO_MUTE, 0 != (vol & bit));
- ret = 1;
- }
- spin_unlock_irq(&chip->reg_lock);
- return ret;
-}
-
-static const struct snd_kcontrol_new snd_cx88_dac_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Audio-Out Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = snd_cx88_switch_get,
- .put = snd_cx88_switch_put,
- .private_value = (1<<8),
-};
-
-static const struct snd_kcontrol_new snd_cx88_source_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog-TV Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = snd_cx88_switch_get,
- .put = snd_cx88_switch_put,
- .private_value = (1<<6),
-};
-
-static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
- struct cx88_core *core = chip->core;
- s32 val;
-
- val = wm8775_g_ctrl(core, V4L2_CID_AUDIO_LOUDNESS);
- value->value.integer.value[0] = val ? 1 : 0;
- return 0;
-}
-
-static int snd_cx88_alc_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
- struct cx88_core *core = chip->core;
- struct v4l2_control client_ctl;
-
- memset(&client_ctl, 0, sizeof(client_ctl));
- client_ctl.value = 0 != value->value.integer.value[0];
- client_ctl.id = V4L2_CID_AUDIO_LOUDNESS;
- call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
-
- return 0;
-}
-
-static struct snd_kcontrol_new snd_cx88_alc_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line-In ALC Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = snd_cx88_alc_get,
- .put = snd_cx88_alc_put,
-};
-
-/****************************************************************************
- Basic Flow for Sound Devices
- ****************************************************************************/
-
-/*
- * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio
- * Only boards with eeprom and byte 1 at eeprom=1 have it
- */
-
-static const struct pci_device_id const cx88_audio_pci_tbl[] __devinitdata = {
- {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {0, }
-};
-MODULE_DEVICE_TABLE(pci, cx88_audio_pci_tbl);
-
-/*
- * Chip-specific destructor
- */
-
-static int snd_cx88_free(snd_cx88_card_t *chip)
-{
-
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
-
- cx88_core_put(chip->core,chip->pci);
-
- pci_disable_device(chip->pci);
- return 0;
-}
-
-/*
- * Component Destructor
- */
-static void snd_cx88_dev_free(struct snd_card * card)
-{
- snd_cx88_card_t *chip = card->private_data;
-
- snd_cx88_free(chip);
-}
-
-
-/*
- * Alsa Constructor - Component probe
- */
-
-static int devno;
-static int __devinit snd_cx88_create(struct snd_card *card,
- struct pci_dev *pci,
- snd_cx88_card_t **rchip,
- struct cx88_core **core_ptr)
-{
- snd_cx88_card_t *chip;
- struct cx88_core *core;
- int err;
- unsigned char pci_lat;
-
- *rchip = NULL;
-
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
-
- pci_set_master(pci);
-
- chip = card->private_data;
-
- core = cx88_core_get(pci);
- if (NULL == core) {
- err = -EINVAL;
- return err;
- }
-
- if (!pci_dma_supported(pci,DMA_BIT_MASK(32))) {
- dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
- err = -EIO;
- cx88_core_put(core, pci);
- return err;
- }
-
-
- /* pci init */
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- spin_lock_init(&chip->reg_lock);
-
- chip->core = core;
-
- /* get irq */
- err = request_irq(chip->pci->irq, cx8801_irq,
- IRQF_SHARED | IRQF_DISABLED, chip->core->name, chip);
- if (err < 0) {
- dprintk(0, "%s: can't get IRQ %d\n",
- chip->core->name, chip->pci->irq);
- return err;
- }
-
- /* print pci info */
- pci_read_config_byte(pci, PCI_LATENCY_TIMER, &pci_lat);
-
- dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, "
- "latency: %d, mmio: 0x%llx\n", core->name, devno,
- pci_name(pci), pci->revision, pci->irq,
- pci_lat, (unsigned long long)pci_resource_start(pci,0));
-
- chip->irq = pci->irq;
- synchronize_irq(chip->irq);
-
- snd_card_set_dev(card, &pci->dev);
-
- *rchip = chip;
- *core_ptr = core;
-
- return 0;
-}
-
-static int __devinit cx88_audio_initdev(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- struct snd_card *card;
- snd_cx88_card_t *chip;
- struct cx88_core *core = NULL;
- int err;
-
- if (devno >= SNDRV_CARDS)
- return (-ENODEV);
-
- if (!enable[devno]) {
- ++devno;
- return (-ENOENT);
- }
-
- err = snd_card_create(index[devno], id[devno], THIS_MODULE,
- sizeof(snd_cx88_card_t), &card);
- if (err < 0)
- return err;
-
- card->private_free = snd_cx88_dev_free;
-
- err = snd_cx88_create(card, pci, &chip, &core);
- if (err < 0)
- goto error;
-
- err = snd_cx88_pcm(chip, 0, "CX88 Digital");
- if (err < 0)
- goto error;
-
- err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_volume, chip));
- if (err < 0)
- goto error;
- err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_dac_switch, chip));
- if (err < 0)
- goto error;
- err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_source_switch, chip));
- if (err < 0)
- goto error;
-
- /* If there's a wm8775 then add a Line-In ALC switch */
- if (core->board.audio_chip == V4L2_IDENT_WM8775)
- snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch, chip));
-
- strcpy (card->driver, "CX88x");
- sprintf(card->shortname, "Conexant CX%x", pci->device);
- sprintf(card->longname, "%s at %#llx",
- card->shortname,(unsigned long long)pci_resource_start(pci, 0));
- strcpy (card->mixername, "CX88");
-
- dprintk (0, "%s/%i: ALSA support for cx2388x boards\n",
- card->driver,devno);
-
- err = snd_card_register(card);
- if (err < 0)
- goto error;
- pci_set_drvdata(pci,card);
-
- devno++;
- return 0;
-
-error:
- snd_card_free(card);
- return err;
-}
-/*
- * ALSA destructor
- */
-static void __devexit cx88_audio_finidev(struct pci_dev *pci)
-{
- struct cx88_audio_dev *card = pci_get_drvdata(pci);
-
- snd_card_free((void *)card);
-
- pci_set_drvdata(pci, NULL);
-
- devno--;
-}
-
-/*
- * PCI driver definition
- */
-
-static struct pci_driver cx88_audio_pci_driver = {
- .name = "cx88_audio",
- .id_table = cx88_audio_pci_tbl,
- .probe = cx88_audio_initdev,
- .remove = __devexit_p(cx88_audio_finidev),
-};
-
-/****************************************************************************
- LINUX MODULE INIT
- ****************************************************************************/
-
-/*
- * module init
- */
-static int __init cx88_audio_init(void)
-{
- printk(KERN_INFO "cx2388x alsa driver version %s loaded\n",
- CX88_VERSION);
- return pci_register_driver(&cx88_audio_pci_driver);
-}
-
-/*
- * module remove
- */
-static void __exit cx88_audio_fini(void)
-{
- pci_unregister_driver(&cx88_audio_pci_driver);
-}
-
-module_init(cx88_audio_init);
-module_exit(cx88_audio_fini);
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
deleted file mode 100644
index 843ffd9e533..00000000000
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ /dev/null
@@ -1,1299 +0,0 @@
-/*
- *
- * Support for a cx23416 mpeg encoder via cx2388x host port.
- * "blackbird" reference design.
- *
- * (c) 2004 Jelle Foks <jelle@foks.us>
- * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
- *
- * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
- * - video_ioctl2 conversion
- *
- * Includes parts from the ivtv driver <http://sourceforge.net/projects/ivtv/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-event.h>
-#include <media/cx2341x.h>
-
-#include "cx88.h"
-
-MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards");
-MODULE_AUTHOR("Jelle Foks <jelle@foks.us>, Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(CX88_VERSION);
-
-static unsigned int mpegbufs = 32;
-module_param(mpegbufs,int,0644);
-MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32");
-
-static unsigned int debug;
-module_param(debug,int,0644);
-MODULE_PARM_DESC(debug,"enable debug messages [blackbird]");
-
-#define dprintk(level,fmt, arg...) if (debug >= level) \
- printk(KERN_DEBUG "%s/2-bb: " fmt, dev->core->name , ## arg)
-
-
-/* ------------------------------------------------------------------ */
-
-#define BLACKBIRD_FIRM_IMAGE_SIZE 376836
-
-/* defines below are from ivtv-driver.h */
-
-#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
-
-/* Firmware API commands */
-#define IVTV_API_STD_TIMEOUT 500
-
-enum blackbird_capture_type {
- BLACKBIRD_MPEG_CAPTURE,
- BLACKBIRD_RAW_CAPTURE,
- BLACKBIRD_RAW_PASSTHRU_CAPTURE
-};
-enum blackbird_capture_bits {
- BLACKBIRD_RAW_BITS_NONE = 0x00,
- BLACKBIRD_RAW_BITS_YUV_CAPTURE = 0x01,
- BLACKBIRD_RAW_BITS_PCM_CAPTURE = 0x02,
- BLACKBIRD_RAW_BITS_VBI_CAPTURE = 0x04,
- BLACKBIRD_RAW_BITS_PASSTHRU_CAPTURE = 0x08,
- BLACKBIRD_RAW_BITS_TO_HOST_CAPTURE = 0x10
-};
-enum blackbird_capture_end {
- BLACKBIRD_END_AT_GOP, /* stop at the end of gop, generate irq */
- BLACKBIRD_END_NOW, /* stop immediately, no irq */
-};
-enum blackbird_framerate {
- BLACKBIRD_FRAMERATE_NTSC_30, /* NTSC: 30fps */
- BLACKBIRD_FRAMERATE_PAL_25 /* PAL: 25fps */
-};
-enum blackbird_stream_port {
- BLACKBIRD_OUTPUT_PORT_MEMORY,
- BLACKBIRD_OUTPUT_PORT_STREAMING,
- BLACKBIRD_OUTPUT_PORT_SERIAL
-};
-enum blackbird_data_xfer_status {
- BLACKBIRD_MORE_BUFFERS_FOLLOW,
- BLACKBIRD_LAST_BUFFER,
-};
-enum blackbird_picture_mask {
- BLACKBIRD_PICTURE_MASK_NONE,
- BLACKBIRD_PICTURE_MASK_I_FRAMES,
- BLACKBIRD_PICTURE_MASK_I_P_FRAMES = 0x3,
- BLACKBIRD_PICTURE_MASK_ALL_FRAMES = 0x7,
-};
-enum blackbird_vbi_mode_bits {
- BLACKBIRD_VBI_BITS_SLICED,
- BLACKBIRD_VBI_BITS_RAW,
-};
-enum blackbird_vbi_insertion_bits {
- BLACKBIRD_VBI_BITS_INSERT_IN_XTENSION_USR_DATA,
- BLACKBIRD_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1,
- BLACKBIRD_VBI_BITS_SEPARATE_STREAM = 0x2 << 1,
- BLACKBIRD_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1,
- BLACKBIRD_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1,
-};
-enum blackbird_dma_unit {
- BLACKBIRD_DMA_BYTES,
- BLACKBIRD_DMA_FRAMES,
-};
-enum blackbird_dma_transfer_status_bits {
- BLACKBIRD_DMA_TRANSFER_BITS_DONE = 0x01,
- BLACKBIRD_DMA_TRANSFER_BITS_ERROR = 0x04,
- BLACKBIRD_DMA_TRANSFER_BITS_LL_ERROR = 0x10,
-};
-enum blackbird_pause {
- BLACKBIRD_PAUSE_ENCODING,
- BLACKBIRD_RESUME_ENCODING,
-};
-enum blackbird_copyright {
- BLACKBIRD_COPYRIGHT_OFF,
- BLACKBIRD_COPYRIGHT_ON,
-};
-enum blackbird_notification_type {
- BLACKBIRD_NOTIFICATION_REFRESH,
-};
-enum blackbird_notification_status {
- BLACKBIRD_NOTIFICATION_OFF,
- BLACKBIRD_NOTIFICATION_ON,
-};
-enum blackbird_notification_mailbox {
- BLACKBIRD_NOTIFICATION_NO_MAILBOX = -1,
-};
-enum blackbird_field1_lines {
- BLACKBIRD_FIELD1_SAA7114 = 0x00EF, /* 239 */
- BLACKBIRD_FIELD1_SAA7115 = 0x00F0, /* 240 */
- BLACKBIRD_FIELD1_MICRONAS = 0x0105, /* 261 */
-};
-enum blackbird_field2_lines {
- BLACKBIRD_FIELD2_SAA7114 = 0x00EF, /* 239 */
- BLACKBIRD_FIELD2_SAA7115 = 0x00F0, /* 240 */
- BLACKBIRD_FIELD2_MICRONAS = 0x0106, /* 262 */
-};
-enum blackbird_custom_data_type {
- BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
- BLACKBIRD_CUSTOM_PRIVATE_PACKET,
-};
-enum blackbird_mute {
- BLACKBIRD_UNMUTE,
- BLACKBIRD_MUTE,
-};
-enum blackbird_mute_video_mask {
- BLACKBIRD_MUTE_VIDEO_V_MASK = 0x0000FF00,
- BLACKBIRD_MUTE_VIDEO_U_MASK = 0x00FF0000,
- BLACKBIRD_MUTE_VIDEO_Y_MASK = 0xFF000000,
-};
-enum blackbird_mute_video_shift {
- BLACKBIRD_MUTE_VIDEO_V_SHIFT = 8,
- BLACKBIRD_MUTE_VIDEO_U_SHIFT = 16,
- BLACKBIRD_MUTE_VIDEO_Y_SHIFT = 24,
-};
-
-/* Registers */
-#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/)
-#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC /*| IVTV_REG_OFFSET*/)
-#define IVTV_REG_SPU (0x9050 /*| IVTV_REG_OFFSET*/)
-#define IVTV_REG_HW_BLOCKS (0x9054 /*| IVTV_REG_OFFSET*/)
-#define IVTV_REG_VPU (0x9058 /*| IVTV_REG_OFFSET*/)
-#define IVTV_REG_APU (0xA064 /*| IVTV_REG_OFFSET*/)
-
-/* ------------------------------------------------------------------ */
-
-static void host_setup(struct cx88_core *core)
-{
- /* toggle reset of the host */
- cx_write(MO_GPHST_SOFT_RST, 1);
- udelay(100);
- cx_write(MO_GPHST_SOFT_RST, 0);
- udelay(100);
-
- /* host port setup */
- cx_write(MO_GPHST_WSC, 0x44444444U);
- cx_write(MO_GPHST_XFR, 0);
- cx_write(MO_GPHST_WDTH, 15);
- cx_write(MO_GPHST_HDSHK, 0);
- cx_write(MO_GPHST_MUX16, 0x44448888U);
- cx_write(MO_GPHST_MODE, 0);
-}
-
-/* ------------------------------------------------------------------ */
-
-#define P1_MDATA0 0x390000
-#define P1_MDATA1 0x390001
-#define P1_MDATA2 0x390002
-#define P1_MDATA3 0x390003
-#define P1_MADDR2 0x390004
-#define P1_MADDR1 0x390005
-#define P1_MADDR0 0x390006
-#define P1_RDATA0 0x390008
-#define P1_RDATA1 0x390009
-#define P1_RDATA2 0x39000A
-#define P1_RDATA3 0x39000B
-#define P1_RADDR0 0x39000C
-#define P1_RADDR1 0x39000D
-#define P1_RRDWR 0x39000E
-
-static int wait_ready_gpio0_bit1(struct cx88_core *core, u32 state)
-{
- unsigned long timeout = jiffies + msecs_to_jiffies(1);
- u32 gpio0,need;
-
- need = state ? 2 : 0;
- for (;;) {
- gpio0 = cx_read(MO_GP0_IO) & 2;
- if (need == gpio0)
- return 0;
- if (time_after(jiffies,timeout))
- return -1;
- udelay(1);
- }
-}
-
-static int memory_write(struct cx88_core *core, u32 address, u32 value)
-{
- /* Warning: address is dword address (4 bytes) */
- cx_writeb(P1_MDATA0, (unsigned int)value);
- cx_writeb(P1_MDATA1, (unsigned int)(value >> 8));
- cx_writeb(P1_MDATA2, (unsigned int)(value >> 16));
- cx_writeb(P1_MDATA3, (unsigned int)(value >> 24));
- cx_writeb(P1_MADDR2, (unsigned int)(address >> 16) | 0x40);
- cx_writeb(P1_MADDR1, (unsigned int)(address >> 8));
- cx_writeb(P1_MADDR0, (unsigned int)address);
- cx_read(P1_MDATA0);
- cx_read(P1_MADDR0);
-
- return wait_ready_gpio0_bit1(core,1);
-}
-
-static int memory_read(struct cx88_core *core, u32 address, u32 *value)
-{
- int retval;
- u32 val;
-
- /* Warning: address is dword address (4 bytes) */
- cx_writeb(P1_MADDR2, (unsigned int)(address >> 16) & ~0xC0);
- cx_writeb(P1_MADDR1, (unsigned int)(address >> 8));
- cx_writeb(P1_MADDR0, (unsigned int)address);
- cx_read(P1_MADDR0);
-
- retval = wait_ready_gpio0_bit1(core,1);
-
- cx_writeb(P1_MDATA3, 0);
- val = (unsigned char)cx_read(P1_MDATA3) << 24;
- cx_writeb(P1_MDATA2, 0);
- val |= (unsigned char)cx_read(P1_MDATA2) << 16;
- cx_writeb(P1_MDATA1, 0);
- val |= (unsigned char)cx_read(P1_MDATA1) << 8;
- cx_writeb(P1_MDATA0, 0);
- val |= (unsigned char)cx_read(P1_MDATA0);
-
- *value = val;
- return retval;
-}
-
-static int register_write(struct cx88_core *core, u32 address, u32 value)
-{
- cx_writeb(P1_RDATA0, (unsigned int)value);
- cx_writeb(P1_RDATA1, (unsigned int)(value >> 8));
- cx_writeb(P1_RDATA2, (unsigned int)(value >> 16));
- cx_writeb(P1_RDATA3, (unsigned int)(value >> 24));
- cx_writeb(P1_RADDR0, (unsigned int)address);
- cx_writeb(P1_RADDR1, (unsigned int)(address >> 8));
- cx_writeb(P1_RRDWR, 1);
- cx_read(P1_RDATA0);
- cx_read(P1_RADDR0);
-
- return wait_ready_gpio0_bit1(core,1);
-}
-
-
-static int register_read(struct cx88_core *core, u32 address, u32 *value)
-{
- int retval;
- u32 val;
-
- cx_writeb(P1_RADDR0, (unsigned int)address);
- cx_writeb(P1_RADDR1, (unsigned int)(address >> 8));
- cx_writeb(P1_RRDWR, 0);
- cx_read(P1_RADDR0);
-
- retval = wait_ready_gpio0_bit1(core,1);
- val = (unsigned char)cx_read(P1_RDATA0);
- val |= (unsigned char)cx_read(P1_RDATA1) << 8;
- val |= (unsigned char)cx_read(P1_RDATA2) << 16;
- val |= (unsigned char)cx_read(P1_RDATA3) << 24;
-
- *value = val;
- return retval;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA])
-{
- struct cx8802_dev *dev = priv;
- unsigned long timeout;
- u32 value, flag, retval;
- int i;
-
- dprintk(1,"%s: 0x%X\n", __func__, command);
-
- /* this may not be 100% safe if we can't read any memory location
- without side effects */
- memory_read(dev->core, dev->mailbox - 4, &value);
- if (value != 0x12345678) {
- dprintk(0, "Firmware and/or mailbox pointer not initialized or corrupted\n");
- return -1;
- }
-
- memory_read(dev->core, dev->mailbox, &flag);
- if (flag) {
- dprintk(0, "ERROR: Mailbox appears to be in use (%x)\n", flag);
- return -1;
- }
-
- flag |= 1; /* tell 'em we're working on it */
- memory_write(dev->core, dev->mailbox, flag);
-
- /* write command + args + fill remaining with zeros */
- memory_write(dev->core, dev->mailbox + 1, command); /* command code */
- memory_write(dev->core, dev->mailbox + 3, IVTV_API_STD_TIMEOUT); /* timeout */
- for (i = 0; i < in; i++) {
- memory_write(dev->core, dev->mailbox + 4 + i, data[i]);
- dprintk(1, "API Input %d = %d\n", i, data[i]);
- }
- for (; i < CX2341X_MBOX_MAX_DATA; i++)
- memory_write(dev->core, dev->mailbox + 4 + i, 0);
-
- flag |= 3; /* tell 'em we're done writing */
- memory_write(dev->core, dev->mailbox, flag);
-
- /* wait for firmware to handle the API command */
- timeout = jiffies + msecs_to_jiffies(10);
- for (;;) {
- memory_read(dev->core, dev->mailbox, &flag);
- if (0 != (flag & 4))
- break;
- if (time_after(jiffies,timeout)) {
- dprintk(0, "ERROR: API Mailbox timeout\n");
- return -1;
- }
- udelay(10);
- }
-
- /* read output values */
- for (i = 0; i < out; i++) {
- memory_read(dev->core, dev->mailbox + 4 + i, data + i);
- dprintk(1, "API Output %d = %d\n", i, data[i]);
- }
-
- memory_read(dev->core, dev->mailbox + 2, &retval);
- dprintk(1, "API result = %d\n",retval);
-
- flag = 0;
- memory_write(dev->core, dev->mailbox, flag);
- return retval;
-}
-/* ------------------------------------------------------------------ */
-
-/* We don't need to call the API often, so using just one mailbox will probably suffice */
-static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command,
- u32 inputcnt, u32 outputcnt, ...)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- va_list vargs;
- int i, err;
-
- va_start(vargs, outputcnt);
-
- for (i = 0; i < inputcnt; i++) {
- data[i] = va_arg(vargs, int);
- }
- err = blackbird_mbox_func(dev, command, inputcnt, outputcnt, data);
- for (i = 0; i < outputcnt; i++) {
- int *vptr = va_arg(vargs, int *);
- *vptr = data[i];
- }
- va_end(vargs);
- return err;
-}
-
-static int blackbird_find_mailbox(struct cx8802_dev *dev)
-{
- u32 signature[4]={0x12345678, 0x34567812, 0x56781234, 0x78123456};
- int signaturecnt=0;
- u32 value;
- int i;
-
- for (i = 0; i < BLACKBIRD_FIRM_IMAGE_SIZE; i++) {
- memory_read(dev->core, i, &value);
- if (value == signature[signaturecnt])
- signaturecnt++;
- else
- signaturecnt = 0;
- if (4 == signaturecnt) {
- dprintk(1, "Mailbox signature found\n");
- return i+1;
- }
- }
- dprintk(0, "Mailbox signature values not found!\n");
- return -1;
-}
-
-static int blackbird_load_firmware(struct cx8802_dev *dev)
-{
- static const unsigned char magic[8] = {
- 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa
- };
- const struct firmware *firmware;
- int i, retval = 0;
- u32 value = 0;
- u32 checksum = 0;
- u32 *dataptr;
-
- retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED);
- retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
- retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640);
- retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
- msleep(1);
- retval |= register_write(dev->core, IVTV_REG_APU, 0);
-
- if (retval < 0)
- dprintk(0, "Error with register_write\n");
-
- retval = request_firmware(&firmware, CX2341X_FIRM_ENC_FILENAME,
- &dev->pci->dev);
-
-
- if (retval != 0) {
- dprintk(0, "ERROR: Hotplug firmware request failed (%s).\n",
- CX2341X_FIRM_ENC_FILENAME);
- dprintk(0, "Please fix your hotplug setup, the board will "
- "not work without firmware loaded!\n");
- return -1;
- }
-
- if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) {
- dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d)\n",
- firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE);
- release_firmware(firmware);
- return -1;
- }
-
- if (0 != memcmp(firmware->data, magic, 8)) {
- dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n");
- release_firmware(firmware);
- return -1;
- }
-
- /* transfer to the chip */
- dprintk(1,"Loading firmware ...\n");
- dataptr = (u32*)firmware->data;
- for (i = 0; i < (firmware->size >> 2); i++) {
- value = le32_to_cpu(*dataptr);
- checksum += ~value;
- memory_write(dev->core, i, value);
- dataptr++;
- }
-
- /* read back to verify with the checksum */
- for (i--; i >= 0; i--) {
- memory_read(dev->core, i, &value);
- checksum -= ~value;
- }
- if (checksum) {
- dprintk(0, "ERROR: Firmware load failed (checksum mismatch).\n");
- release_firmware(firmware);
- return -1;
- }
- release_firmware(firmware);
- dprintk(0, "Firmware upload successful.\n");
-
- retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
- retval |= register_read(dev->core, IVTV_REG_SPU, &value);
- retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE);
- msleep(1);
-
- retval |= register_read(dev->core, IVTV_REG_VPU, &value);
- retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8);
-
- if (retval < 0)
- dprintk(0, "Error with register_write\n");
- return 0;
-}
-
-/**
- Settings used by the windows tv app for PVR2000:
-=================================================================================================================
-Profile | Codec | Resolution | CBR/VBR | Video Qlty | V. Bitrate | Frmrate | Audio Codec | A. Bitrate | A. Mode
------------------------------------------------------------------------------------------------------------------
-MPEG-1 | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 2000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
-MPEG-2 | MPEG2 | 720x576PAL | VBR | 600 :Good | 4000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
-VCD | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 1150 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
-DVD | MPEG2 | 720x576PAL | VBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
-DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
-=================================================================================================================
-*DB: "DirectBurn"
-*/
-
-static void blackbird_codec_settings(struct cx8802_dev *dev)
-{
- /* assign frame size */
- blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
- dev->height, dev->width);
-
- dev->cxhdl.width = dev->width;
- dev->cxhdl.height = dev->height;
- cx2341x_handler_set_50hz(&dev->cxhdl, dev->core->tvnorm & V4L2_STD_625_50);
- cx2341x_handler_setup(&dev->cxhdl);
-}
-
-static int blackbird_initialize_codec(struct cx8802_dev *dev)
-{
- struct cx88_core *core = dev->core;
- int version;
- int retval;
-
- dprintk(1,"Initialize codec\n");
- retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
- if (retval < 0) {
-
- dev->mpeg_active = 0;
-
- /* ping was not successful, reset and upload firmware */
- cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
- cx_write(MO_SRST_IO, 1); /* SYS_RSTO=1 */
- retval = blackbird_load_firmware(dev);
- if (retval < 0)
- return retval;
-
- retval = blackbird_find_mailbox(dev);
- if (retval < 0)
- return -1;
-
- dev->mailbox = retval;
-
- retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
- if (retval < 0) {
- dprintk(0, "ERROR: Firmware ping failed!\n");
- return -1;
- }
-
- retval = blackbird_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, &version);
- if (retval < 0) {
- dprintk(0, "ERROR: Firmware get encoder version failed!\n");
- return -1;
- }
- dprintk(0, "Firmware version is 0x%08x\n", version);
- }
-
- cx_write(MO_PINMUX_IO, 0x88); /* 656-8bit IO and enable MPEG parallel IO */
- cx_clear(MO_INPUT_FORMAT, 0x100); /* chroma subcarrier lock to normal? */
- cx_write(MO_VBOS_CONTROL, 0x84A00); /* no 656 mode, 8-bit pixels, disable VBI */
- cx_clear(MO_OUTPUT_FORMAT, 0x0008); /* Normal Y-limits to let the mpeg encoder sync */
-
- blackbird_codec_settings(dev);
-
- blackbird_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0,
- BLACKBIRD_FIELD1_SAA7115,
- BLACKBIRD_FIELD2_SAA7115
- );
-
- blackbird_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0,
- BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-
- return 0;
-}
-
-static int blackbird_start_codec(struct file *file, void *priv)
-{
- struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
- struct cx88_core *core = dev->core;
- /* start capturing to the host interface */
- u32 reg;
-
- int i;
- int lastchange = -1;
- int lastval = 0;
-
- for (i = 0; (i < 10) && (i < (lastchange + 4)); i++) {
- reg = cx_read(AUD_STATUS);
-
- dprintk(1, "AUD_STATUS:%dL: 0x%x\n", i, reg);
- if ((reg & 0x0F) != lastval) {
- lastval = reg & 0x0F;
- lastchange = i;
- }
- msleep(100);
- }
-
- /* unmute audio source */
- cx_clear(AUD_VOL_CTL, (1 << 6));
-
- blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0, 0);
-
- /* initialize the video input */
- blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
-
- cx2341x_handler_set_busy(&dev->cxhdl, 1);
-
- /* start capturing to the host interface */
- blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0,
- BLACKBIRD_MPEG_CAPTURE,
- BLACKBIRD_RAW_BITS_NONE
- );
-
- dev->mpeg_active = 1;
- return 0;
-}
-
-static int blackbird_stop_codec(struct cx8802_dev *dev)
-{
- blackbird_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
- BLACKBIRD_END_NOW,
- BLACKBIRD_MPEG_CAPTURE,
- BLACKBIRD_RAW_BITS_NONE
- );
-
- cx2341x_handler_set_busy(&dev->cxhdl, 0);
-
- dev->mpeg_active = 0;
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int bb_buf_setup(struct videobuf_queue *q,
- unsigned int *count, unsigned int *size)
-{
- struct cx8802_fh *fh = q->priv_data;
-
- fh->dev->ts_packet_size = 188 * 4; /* was: 512 */
- fh->dev->ts_packet_count = mpegbufs; /* was: 100 */
-
- *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count;
- *count = fh->dev->ts_packet_count;
- return 0;
-}
-
-static int
-bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct cx8802_fh *fh = q->priv_data;
- return cx8802_buf_prepare(q, fh->dev, (struct cx88_buffer*)vb, field);
-}
-
-static void
-bb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct cx8802_fh *fh = q->priv_data;
- cx8802_buf_queue(fh->dev, (struct cx88_buffer*)vb);
-}
-
-static void
-bb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- cx88_free_buffer(q, (struct cx88_buffer*)vb);
-}
-
-static struct videobuf_queue_ops blackbird_qops = {
- .buf_setup = bb_buf_setup,
- .buf_prepare = bb_buf_prepare,
- .buf_queue = bb_buf_queue,
- .buf_release = bb_buf_release,
-};
-
-/* ------------------------------------------------------------------ */
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
- struct cx88_core *core = dev->core;
-
- strcpy(cap->driver, "cx88_blackbird");
- sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
- cx88_querycap(file, core, cap);
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (f->index != 0)
- return -EINVAL;
-
- strlcpy(f->description, "MPEG", sizeof(f->description));
- f->pixelformat = V4L2_PIX_FMT_MPEG;
- f->flags = V4L2_FMT_FLAG_COMPRESSED;
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx8802_fh *fh = priv;
- struct cx8802_dev *dev = fh->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- f->fmt.pix.width = dev->width;
- f->fmt.pix.height = dev->height;
- f->fmt.pix.field = fh->mpegq.field;
- dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
- dev->width, dev->height, fh->mpegq.field );
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap (struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx8802_fh *fh = priv;
- struct cx8802_dev *dev = fh->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
- dev->width, dev->height, fh->mpegq.field );
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap (struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx8802_fh *fh = priv;
- struct cx8802_dev *dev = fh->dev;
- struct cx88_core *core = dev->core;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- dev->width = f->fmt.pix.width;
- dev->height = f->fmt.pix.height;
- fh->mpegq.field = f->fmt.pix.field;
- cx88_set_scale(core, f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
- blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
- f->fmt.pix.height, f->fmt.pix.width);
- dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
- f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field );
- return 0;
-}
-
-static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p)
-{
- struct cx8802_fh *fh = priv;
- return (videobuf_reqbufs(&fh->mpegq, p));
-}
-
-static int vidioc_querybuf (struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct cx8802_fh *fh = priv;
- return (videobuf_querybuf(&fh->mpegq, p));
-}
-
-static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct cx8802_fh *fh = priv;
- return (videobuf_qbuf(&fh->mpegq, p));
-}
-
-static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct cx8802_fh *fh = priv;
- return (videobuf_dqbuf(&fh->mpegq, p,
- file->f_flags & O_NONBLOCK));
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx8802_fh *fh = priv;
- struct cx8802_dev *dev = fh->dev;
-
- if (!dev->mpeg_active)
- blackbird_start_codec(file, fh);
- return videobuf_streamon(&fh->mpegq);
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx8802_fh *fh = priv;
- struct cx8802_dev *dev = fh->dev;
-
- if (dev->mpeg_active)
- blackbird_stop_codec(dev);
- return videobuf_streamoff(&fh->mpegq);
-}
-
-static int vidioc_s_frequency (struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct cx8802_fh *fh = priv;
- struct cx8802_dev *dev = fh->dev;
- struct cx88_core *core = dev->core;
-
- if (unlikely(UNSET == core->board.tuner_type))
- return -EINVAL;
- if (unlikely(f->tuner != 0))
- return -EINVAL;
- if (dev->mpeg_active)
- blackbird_stop_codec(dev);
-
- cx88_set_freq (core,f);
- blackbird_initialize_codec(dev);
- cx88_set_scale(dev->core, dev->width, dev->height,
- fh->mpegq.field);
- return 0;
-}
-
-static int vidioc_log_status (struct file *file, void *priv)
-{
- struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
- struct cx88_core *core = dev->core;
- char name[32 + 2];
-
- snprintf(name, sizeof(name), "%s/2", core->name);
- call_all(core, core, log_status);
- v4l2_ctrl_handler_log_status(&dev->cxhdl.hdl, name);
- return 0;
-}
-
-static int vidioc_enum_input (struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
- return cx88_enum_input (core,i);
-}
-
-static int vidioc_g_frequency (struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct cx8802_fh *fh = priv;
- struct cx88_core *core = fh->dev->core;
-
- if (unlikely(UNSET == core->board.tuner_type))
- return -EINVAL;
- if (unlikely(f->tuner != 0))
- return -EINVAL;
-
- f->frequency = core->freq;
- call_all(core, tuner, g_frequency, f);
-
- return 0;
-}
-
-static int vidioc_g_input (struct file *file, void *priv, unsigned int *i)
-{
- struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
-
- *i = core->input;
- return 0;
-}
-
-static int vidioc_s_input (struct file *file, void *priv, unsigned int i)
-{
- struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
-
- if (i >= 4)
- return -EINVAL;
- if (0 == INPUT(i).type)
- return -EINVAL;
-
- mutex_lock(&core->lock);
- cx88_newstation(core);
- cx88_video_mux(core,i);
- mutex_unlock(&core->lock);
- return 0;
-}
-
-static int vidioc_g_tuner (struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
- u32 reg;
-
- if (unlikely(UNSET == core->board.tuner_type))
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
-
- strcpy(t->name, "Television");
- t->capability = V4L2_TUNER_CAP_NORM;
- t->rangehigh = 0xffffffffUL;
- call_all(core, tuner, g_tuner, t);
-
- cx88_get_stereo(core ,t);
- reg = cx_read(MO_DEVICE_STATUS);
- t->signal = (reg & (1<<5)) ? 0xffff : 0x0000;
- return 0;
-}
-
-static int vidioc_s_tuner (struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
-
- if (UNSET == core->board.tuner_type)
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
-
- cx88_set_stereo(core, t->audmode, 1);
- return 0;
-}
-
-static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm)
-{
- struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
-
- *tvnorm = core->tvnorm;
- return 0;
-}
-
-static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id)
-{
- struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
-
- mutex_lock(&core->lock);
- cx88_set_tvnorm(core,*id);
- mutex_unlock(&core->lock);
- return 0;
-}
-
-/* FIXME: cx88_ioctl_hook not implemented */
-
-static int mpeg_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx8802_dev *dev = video_drvdata(file);
- struct cx8802_fh *fh;
- struct cx8802_driver *drv = NULL;
- int err;
-
- dprintk( 1, "%s\n", __func__);
-
- mutex_lock(&dev->core->lock);
-
- /* Make sure we can acquire the hardware */
- drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
- if (!drv) {
- dprintk(1, "%s: blackbird driver is not loaded\n", __func__);
- mutex_unlock(&dev->core->lock);
- return -ENODEV;
- }
-
- err = drv->request_acquire(drv);
- if (err != 0) {
- dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err);
- mutex_unlock(&dev->core->lock);
- return err;
- }
-
- if (!dev->core->mpeg_users && blackbird_initialize_codec(dev) < 0) {
- drv->request_release(drv);
- mutex_unlock(&dev->core->lock);
- return -EINVAL;
- }
- dprintk(1, "open dev=%s\n", video_device_node_name(vdev));
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh),GFP_KERNEL);
- if (NULL == fh) {
- drv->request_release(drv);
- mutex_unlock(&dev->core->lock);
- return -ENOMEM;
- }
- v4l2_fh_init(&fh->fh, vdev);
- file->private_data = fh;
- fh->dev = dev;
-
- videobuf_queue_sg_init(&fh->mpegq, &blackbird_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx88_buffer),
- fh, NULL);
-
- /* FIXME: locking against other video device */
- cx88_set_scale(dev->core, dev->width, dev->height,
- fh->mpegq.field);
-
- dev->core->mpeg_users++;
- mutex_unlock(&dev->core->lock);
- v4l2_fh_add(&fh->fh);
- return 0;
-}
-
-static int mpeg_release(struct file *file)
-{
- struct cx8802_fh *fh = file->private_data;
- struct cx8802_dev *dev = fh->dev;
- struct cx8802_driver *drv = NULL;
-
- mutex_lock(&dev->core->lock);
-
- if (dev->mpeg_active && dev->core->mpeg_users == 1)
- blackbird_stop_codec(dev);
-
- cx8802_cancel_buffers(fh->dev);
- /* stop mpeg capture */
- videobuf_stop(&fh->mpegq);
-
- videobuf_mmap_free(&fh->mpegq);
-
- v4l2_fh_del(&fh->fh);
- v4l2_fh_exit(&fh->fh);
- file->private_data = NULL;
- kfree(fh);
-
- /* Make sure we release the hardware */
- drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
- WARN_ON(!drv);
- if (drv)
- drv->request_release(drv);
-
- dev->core->mpeg_users--;
-
- mutex_unlock(&dev->core->lock);
-
- return 0;
-}
-
-static ssize_t
-mpeg_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
-{
- struct cx8802_fh *fh = file->private_data;
- struct cx8802_dev *dev = fh->dev;
-
- if (!dev->mpeg_active)
- blackbird_start_codec(file, fh);
-
- return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0,
- file->f_flags & O_NONBLOCK);
-}
-
-static unsigned int
-mpeg_poll(struct file *file, struct poll_table_struct *wait)
-{
- unsigned long req_events = poll_requested_events(wait);
- struct cx8802_fh *fh = file->private_data;
- struct cx8802_dev *dev = fh->dev;
-
- if (!dev->mpeg_active && (req_events & (POLLIN | POLLRDNORM)))
- blackbird_start_codec(file, fh);
-
- return v4l2_ctrl_poll(file, wait) | videobuf_poll_stream(file, &fh->mpegq, wait);
-}
-
-static int
-mpeg_mmap(struct file *file, struct vm_area_struct * vma)
-{
- struct cx8802_fh *fh = file->private_data;
-
- return videobuf_mmap_mapper(&fh->mpegq, vma);
-}
-
-static const struct v4l2_file_operations mpeg_fops =
-{
- .owner = THIS_MODULE,
- .open = mpeg_open,
- .release = mpeg_release,
- .read = mpeg_read,
- .poll = mpeg_poll,
- .mmap = mpeg_mmap,
- .unlocked_ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_std = vidioc_g_std,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static struct video_device cx8802_mpeg_template = {
- .name = "cx8802",
- .fops = &mpeg_fops,
- .ioctl_ops = &mpeg_ioctl_ops,
- .tvnorms = CX88_NORMS,
-};
-
-/* ------------------------------------------------------------------ */
-
-/* The CX8802 MPEG API will call this when we can use the hardware */
-static int cx8802_blackbird_advise_acquire(struct cx8802_driver *drv)
-{
- struct cx88_core *core = drv->core;
- int err = 0;
-
- switch (core->boardnr) {
- case CX88_BOARD_HAUPPAUGE_HVR1300:
- /* By default, core setup will leave the cx22702 out of reset, on the bus.
- * We left the hardware on power up with the cx22702 active.
- * We're being given access to re-arrange the GPIOs.
- * Take the bus off the cx22702 and put the cx23416 on it.
- */
- /* Toggle reset on cx22702 leaving i2c active */
- cx_set(MO_GP0_IO, 0x00000080);
- udelay(1000);
- cx_clear(MO_GP0_IO, 0x00000080);
- udelay(50);
- cx_set(MO_GP0_IO, 0x00000080);
- udelay(1000);
- /* tri-state the cx22702 pins */
- cx_set(MO_GP0_IO, 0x00000004);
- udelay(1000);
- break;
- default:
- err = -ENODEV;
- }
- return err;
-}
-
-/* The CX8802 MPEG API will call this when we need to release the hardware */
-static int cx8802_blackbird_advise_release(struct cx8802_driver *drv)
-{
- struct cx88_core *core = drv->core;
- int err = 0;
-
- switch (core->boardnr) {
- case CX88_BOARD_HAUPPAUGE_HVR1300:
- /* Exit leaving the cx23416 on the bus */
- break;
- default:
- err = -ENODEV;
- }
- return err;
-}
-
-static void blackbird_unregister_video(struct cx8802_dev *dev)
-{
- if (dev->mpeg_dev) {
- if (video_is_registered(dev->mpeg_dev))
- video_unregister_device(dev->mpeg_dev);
- else
- video_device_release(dev->mpeg_dev);
- dev->mpeg_dev = NULL;
- }
-}
-
-static int blackbird_register_video(struct cx8802_dev *dev)
-{
- int err;
-
- dev->mpeg_dev = cx88_vdev_init(dev->core,dev->pci,
- &cx8802_mpeg_template,"mpeg");
- dev->mpeg_dev->ctrl_handler = &dev->cxhdl.hdl;
- video_set_drvdata(dev->mpeg_dev, dev);
- err = video_register_device(dev->mpeg_dev,VFL_TYPE_GRABBER, -1);
- if (err < 0) {
- printk(KERN_INFO "%s/2: can't register mpeg device\n",
- dev->core->name);
- return err;
- }
- printk(KERN_INFO "%s/2: registered device %s [mpeg]\n",
- dev->core->name, video_device_node_name(dev->mpeg_dev));
- return 0;
-}
-
-/* ----------------------------------------------------------- */
-
-static int cx8802_blackbird_probe(struct cx8802_driver *drv)
-{
- struct cx88_core *core = drv->core;
- struct cx8802_dev *dev = core->dvbdev;
- int err;
-
- dprintk( 1, "%s\n", __func__);
- dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
- core->boardnr,
- core->name,
- core->pci_bus,
- core->pci_slot);
-
- err = -ENODEV;
- if (!(core->board.mpeg & CX88_MPEG_BLACKBIRD))
- goto fail_core;
-
- dev->width = 720;
- if (core->tvnorm & V4L2_STD_525_60) {
- dev->height = 480;
- } else {
- dev->height = 576;
- }
- dev->cxhdl.port = CX2341X_PORT_STREAMING;
- dev->cxhdl.width = dev->width;
- dev->cxhdl.height = dev->height;
- dev->cxhdl.func = blackbird_mbox_func;
- dev->cxhdl.priv = dev;
- err = cx2341x_handler_init(&dev->cxhdl, 36);
- if (err)
- goto fail_core;
- v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl);
-
- /* blackbird stuff */
- printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n",
- core->name);
- host_setup(dev->core);
-
- blackbird_initialize_codec(dev);
-
- /* initial device configuration: needed ? */
-// init_controls(core);
- cx88_set_tvnorm(core,core->tvnorm);
- cx88_video_mux(core,0);
- cx2341x_handler_set_50hz(&dev->cxhdl, dev->height == 576);
- cx2341x_handler_setup(&dev->cxhdl);
- blackbird_register_video(dev);
-
- return 0;
-
- fail_core:
- return err;
-}
-
-static int cx8802_blackbird_remove(struct cx8802_driver *drv)
-{
- struct cx88_core *core = drv->core;
- struct cx8802_dev *dev = core->dvbdev;
-
- /* blackbird */
- blackbird_unregister_video(drv->core->dvbdev);
- v4l2_ctrl_handler_free(&dev->cxhdl.hdl);
-
- return 0;
-}
-
-static struct cx8802_driver cx8802_blackbird_driver = {
- .type_id = CX88_MPEG_BLACKBIRD,
- .hw_access = CX8802_DRVCTL_SHARED,
- .probe = cx8802_blackbird_probe,
- .remove = cx8802_blackbird_remove,
- .advise_acquire = cx8802_blackbird_advise_acquire,
- .advise_release = cx8802_blackbird_advise_release,
-};
-
-static int __init blackbird_init(void)
-{
- printk(KERN_INFO "cx2388x blackbird driver version %s loaded\n",
- CX88_VERSION);
- return cx8802_register_driver(&cx8802_blackbird_driver);
-}
-
-static void __exit blackbird_fini(void)
-{
- cx8802_unregister_driver(&cx8802_blackbird_driver);
-}
-
-module_init(blackbird_init);
-module_exit(blackbird_fini);
-
-module_param_named(video_debug,cx8802_mpeg_template.debug, int, 0644);
-MODULE_PARM_DESC(debug,"enable debug messages [video]");
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
deleted file mode 100644
index 4e9d4f72296..00000000000
--- a/drivers/media/video/cx88/cx88-cards.c
+++ /dev/null
@@ -1,3811 +0,0 @@
-/*
- *
- * device driver for Conexant 2388x based TV cards
- * card-specific stuff.
- *
- * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-
-#include "cx88.h"
-#include "tea5767.h"
-#include "xc4000.h"
-
-static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
-static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
-static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
-
-module_param_array(tuner, int, NULL, 0444);
-module_param_array(radio, int, NULL, 0444);
-module_param_array(card, int, NULL, 0444);
-
-MODULE_PARM_DESC(tuner,"tuner type");
-MODULE_PARM_DESC(radio,"radio tuner type");
-MODULE_PARM_DESC(card,"card type");
-
-static unsigned int latency = UNSET;
-module_param(latency,int,0444);
-MODULE_PARM_DESC(latency,"pci latency timer");
-
-static int disable_ir;
-module_param(disable_ir, int, 0444);
-MODULE_PARM_DESC(disable_ir, "Disable IR support");
-
-#define info_printk(core, fmt, arg...) \
- printk(KERN_INFO "%s: " fmt, core->name , ## arg)
-
-#define warn_printk(core, fmt, arg...) \
- printk(KERN_WARNING "%s: " fmt, core->name , ## arg)
-
-#define err_printk(core, fmt, arg...) \
- printk(KERN_ERR "%s: " fmt, core->name , ## arg)
-
-
-/* ------------------------------------------------------------------ */
-/* board config info */
-
-/* If radio_type !=UNSET, radio_addr should be specified
- */
-
-static const struct cx88_board cx88_boards[] = {
- [CX88_BOARD_UNKNOWN] = {
- .name = "UNKNOWN/GENERIC",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 0,
- },{
- .type = CX88_VMUX_COMPOSITE2,
- .vmux = 1,
- },{
- .type = CX88_VMUX_COMPOSITE3,
- .vmux = 2,
- },{
- .type = CX88_VMUX_COMPOSITE4,
- .vmux = 3,
- }},
- },
- [CX88_BOARD_HAUPPAUGE] = {
- .name = "Hauppauge WinTV 34xxx models",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0xff00, // internal decoder
- },{
- .type = CX88_VMUX_DEBUG,
- .vmux = 0,
- .gpio0 = 0xff01, // mono from tuner chip
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0xff02,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0xff02,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0xff01,
- },
- },
- [CX88_BOARD_GDI] = {
- .name = "GDI Black Gold",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- }},
- },
- [CX88_BOARD_PIXELVIEW] = {
- .name = "PixelView",
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0xff00, // internal decoder
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0xff10,
- },
- },
- [CX88_BOARD_ATI_WONDER_PRO] = {
- .name = "ATI TV Wonder Pro",
- .tuner_type = TUNER_PHILIPS_4IN1,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x03ff,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x03fe,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x03fe,
- }},
- },
- [CX88_BOARD_WINFAST2000XP_EXPERT] = {
- .name = "Leadtek Winfast 2000XP Expert",
- .tuner_type = TUNER_PHILIPS_4IN1,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x00F5e700,
- .gpio1 = 0x00003004,
- .gpio2 = 0x00F5e700,
- .gpio3 = 0x02000000,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x00F5c700,
- .gpio1 = 0x00003004,
- .gpio2 = 0x00F5c700,
- .gpio3 = 0x02000000,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x00F5c700,
- .gpio1 = 0x00003004,
- .gpio2 = 0x00F5c700,
- .gpio3 = 0x02000000,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x00F5d700,
- .gpio1 = 0x00003004,
- .gpio2 = 0x00F5d700,
- .gpio3 = 0x02000000,
- },
- },
- [CX88_BOARD_AVERTV_STUDIO_303] = {
- .name = "AverTV Studio 303 (M126)",
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio1 = 0xe09f,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio1 = 0xe05f,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio1 = 0xe05f,
- }},
- .radio = {
- .gpio1 = 0xe0df,
- .type = CX88_RADIO,
- },
- },
- [CX88_BOARD_MSI_TVANYWHERE_MASTER] = {
- // added gpio values thanks to Michal
- // values for PAL from DScaler
- .name = "MSI TV-@nywhere Master",
- .tuner_type = TUNER_MT2032,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER_NTSC,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x000040bf,
- .gpio1 = 0x000080c0,
- .gpio2 = 0x0000ff40,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x000040bf,
- .gpio1 = 0x000080c0,
- .gpio2 = 0x0000ff40,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x000040bf,
- .gpio1 = 0x000080c0,
- .gpio2 = 0x0000ff40,
- }},
- .radio = {
- .type = CX88_RADIO,
- .vmux = 3,
- .gpio0 = 0x000040bf,
- .gpio1 = 0x000080c0,
- .gpio2 = 0x0000ff20,
- },
- },
- [CX88_BOARD_WINFAST_DV2000] = {
- .name = "Leadtek Winfast DV2000",
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0035e700,
- .gpio1 = 0x00003004,
- .gpio2 = 0x0035e700,
- .gpio3 = 0x02000000,
- },{
-
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0035c700,
- .gpio1 = 0x00003004,
- .gpio2 = 0x0035c700,
- .gpio3 = 0x02000000,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0035c700,
- .gpio1 = 0x0035c700,
- .gpio2 = 0x02000000,
- .gpio3 = 0x02000000,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x0035d700,
- .gpio1 = 0x00007004,
- .gpio2 = 0x0035d700,
- .gpio3 = 0x02000000,
- },
- },
- [CX88_BOARD_LEADTEK_PVR2000] = {
- // gpio values for PAL version from regspy by DScaler
- .name = "Leadtek PVR 2000",
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0000bde2,
- .audioroute = 1,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0000bde6,
- .audioroute = 1,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0000bde6,
- .audioroute = 1,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x0000bd62,
- .audioroute = 1,
- },
- .mpeg = CX88_MPEG_BLACKBIRD,
- },
- [CX88_BOARD_IODATA_GVVCP3PCI] = {
- .name = "IODATA GV-VCP3/PCI",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 0,
- },{
- .type = CX88_VMUX_COMPOSITE2,
- .vmux = 1,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- }},
- },
- [CX88_BOARD_PROLINK_PLAYTVPVR] = {
- .name = "Prolink PlayTV PVR",
- .tuner_type = TUNER_PHILIPS_FM1236_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0xbff0,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0xbff3,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0xbff3,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0xbff0,
- },
- },
- [CX88_BOARD_ASUS_PVR_416] = {
- .name = "ASUS PVR-416",
- .tuner_type = TUNER_PHILIPS_FM1236_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0000fde6,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in?
- .audioroute = 1,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x0000fde2,
- },
- .mpeg = CX88_MPEG_BLACKBIRD,
- },
- [CX88_BOARD_MSI_TVANYWHERE] = {
- .name = "MSI TV-@nywhere",
- .tuner_type = TUNER_MT2032,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x00000fbf,
- .gpio2 = 0x0000fc08,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x00000fbf,
- .gpio2 = 0x0000fc68,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x00000fbf,
- .gpio2 = 0x0000fc68,
- }},
- },
- [CX88_BOARD_KWORLD_DVB_T] = {
- .name = "KWorld/VStream XPert DVB-T",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0700,
- .gpio2 = 0x0101,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0700,
- .gpio2 = 0x0101,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
- .name = "DViCO FusionHDTV DVB-T1",
- .tuner_type = TUNER_ABSENT, /* No analog tuner */
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x000027df,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x000027df,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_KWORLD_LTV883] = {
- .name = "KWorld LTV883RF",
- .tuner_type = TUNER_TNF_8831BGFF,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x07f8,
- },{
- .type = CX88_VMUX_DEBUG,
- .vmux = 0,
- .gpio0 = 0x07f9, // mono from tuner chip
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x000007fa,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x000007fa,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x000007f8,
- },
- },
- [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = {
- .name = "DViCO FusionHDTV 3 Gold-Q",
- .tuner_type = TUNER_MICROTUNE_4042FI5,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- /*
- GPIO[0] resets DT3302 DTV receiver
- 0 - reset asserted
- 1 - normal operation
- GPIO[1] mutes analog audio output connector
- 0 - enable selected source
- 1 - mute
- GPIO[2] selects source for analog audio output connector
- 0 - analog audio input connector on tab
- 1 - analog DAC output from CX23881 chip
- GPIO[3] selects RF input connector on tuner module
- 0 - RF connector labeled CABLE
- 1 - RF connector labeled ANT
- GPIO[4] selects high RF for QAM256 mode
- 0 - normal RF
- 1 - high RF
- */
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0f0d,
- },{
- .type = CX88_VMUX_CABLE,
- .vmux = 0,
- .gpio0 = 0x0f05,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0f00,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0f00,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_HAUPPAUGE_DVB_T1] = {
- .name = "Hauppauge Nova-T DVB-T",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_CONEXANT_DVB_T1] = {
- .name = "Conexant DVB-T reference design",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_PROVIDEO_PV259] = {
- .name = "Provideo PV259",
- .tuner_type = TUNER_PHILIPS_FQ1216ME,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .audioroute = 1,
- }},
- .mpeg = CX88_MPEG_BLACKBIRD,
- },
- [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = {
- .name = "DViCO FusionHDTV DVB-T Plus",
- .tuner_type = TUNER_ABSENT, /* No analog tuner */
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x000027df,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x000027df,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_DNTV_LIVE_DVB_T] = {
- .name = "digitalnow DNTV Live! DVB-T",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x00000700,
- .gpio2 = 0x00000101,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x00000700,
- .gpio2 = 0x00000101,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_PCHDTV_HD3000] = {
- .name = "pcHDTV HD3000 HDTV",
- .tuner_type = TUNER_THOMSON_DTT761X,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- /* GPIO[2] = audio source for analog audio out connector
- * 0 = analog audio input connector
- * 1 = CX88 audio DACs
- *
- * GPIO[7] = input to CX88's audio/chroma ADC
- * 0 = FM 10.7 MHz IF
- * 1 = Sound 4.5 MHz IF
- *
- * GPIO[1,5,6] = Oren 51132 pins 27,35,28 respectively
- *
- * GPIO[16] = Remote control input
- */
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x00008484,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x00008400,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x00008400,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x00008404,
- },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_HAUPPAUGE_ROSLYN] = {
- // entry added by Kaustubh D. Bhalerao <bhalerao.1@osu.edu>
- // GPIO values obtained from regspy, courtesy Sean Covel
- .name = "Hauppauge WinTV 28xxx (Roslyn) models",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0xed1a,
- .gpio2 = 0x00ff,
- },{
- .type = CX88_VMUX_DEBUG,
- .vmux = 0,
- .gpio0 = 0xff01,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0xff02,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0xed92,
- .gpio2 = 0x00ff,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0xed96,
- .gpio2 = 0x00ff,
- },
- .mpeg = CX88_MPEG_BLACKBIRD,
- },
- [CX88_BOARD_DIGITALLOGIC_MEC] = {
- .name = "Digital-Logic MICROSPACE Entertainment Center (MEC)",
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x00009d80,
- .audioroute = 1,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x00009d76,
- .audioroute = 1,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x00009d76,
- .audioroute = 1,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x00009d00,
- .audioroute = 1,
- },
- .mpeg = CX88_MPEG_BLACKBIRD,
- },
- [CX88_BOARD_IODATA_GVBCTV7E] = {
- .name = "IODATA GV/BCTV7E",
- .tuner_type = TUNER_PHILIPS_FQ1286,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 1,
- .gpio1 = 0x0000e03f,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 2,
- .gpio1 = 0x0000e07f,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 3,
- .gpio1 = 0x0000e07f,
- }}
- },
- [CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO] = {
- .name = "PixelView PlayTV Ultra Pro (Stereo)",
- /* May be also TUNER_YMEC_TVF_5533MF for NTSC/M or PAL/M */
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- /* Some variants use a tda9874 and so need the tvaudio module. */
- .audio_chip = V4L2_IDENT_TVAUDIO,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0xbf61, /* internal decoder */
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0xbf63,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0xbf63,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0xbf60,
- },
- },
- [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
- .name = "DViCO FusionHDTV 3 Gold-T",
- .tuner_type = TUNER_THOMSON_DTT761X,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x97ed,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x97e9,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x97e9,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_ADSTECH_DVB_T_PCI] = {
- .name = "ADS Tech Instant TV DVB-T PCI",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0700,
- .gpio2 = 0x0101,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0700,
- .gpio2 = 0x0101,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = {
- .name = "TerraTec Cinergy 1400 DVB-T",
- .tuner_type = TUNER_ABSENT,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 2,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD] = {
- .name = "DViCO FusionHDTV 5 Gold",
- .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H062F */
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x87fd,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x87f9,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x87f9,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_AVERMEDIA_ULTRATV_MC_550] = {
- .name = "AverMedia UltraTV Media Center PCI 550",
- .tuner_type = TUNER_PHILIPS_FM1236_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 0,
- .gpio0 = 0x0000cd73,
- .audioroute = 1,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 1,
- .gpio0 = 0x0000cd73,
- .audioroute = 1,
- },{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 3,
- .gpio0 = 0x0000cdb3,
- .audioroute = 1,
- }},
- .radio = {
- .type = CX88_RADIO,
- .vmux = 2,
- .gpio0 = 0x0000cdf3,
- .audioroute = 1,
- },
- .mpeg = CX88_MPEG_BLACKBIRD,
- },
- [CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD] = {
- /* Alexander Wold <awold@bigfoot.com> */
- .name = "Kworld V-Stream Xpert DVD",
- .tuner_type = UNSET,
- .input = {{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x03000000,
- .gpio1 = 0x01000000,
- .gpio2 = 0x02000000,
- .gpio3 = 0x00100000,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x03000000,
- .gpio1 = 0x01000000,
- .gpio2 = 0x02000000,
- .gpio3 = 0x00100000,
- }},
- },
- [CX88_BOARD_ATI_HDTVWONDER] = {
- .name = "ATI HDTV Wonder",
- .tuner_type = TUNER_PHILIPS_TUV1236D,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x00000ff7,
- .gpio1 = 0x000000ff,
- .gpio2 = 0x00000001,
- .gpio3 = 0x00000000,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x00000ffe,
- .gpio1 = 0x000000ff,
- .gpio2 = 0x00000001,
- .gpio3 = 0x00000000,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x00000ffe,
- .gpio1 = 0x000000ff,
- .gpio2 = 0x00000001,
- .gpio3 = 0x00000000,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_WINFAST_DTV1000] = {
- .name = "WinFast DTV1000-T",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_AVERTV_303] = {
- .name = "AVerTV 303 (M126)",
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x00ff,
- .gpio1 = 0xe09f,
- .gpio2 = 0x0010,
- .gpio3 = 0x0000,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x00ff,
- .gpio1 = 0xe05f,
- .gpio2 = 0x0010,
- .gpio3 = 0x0000,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x00ff,
- .gpio1 = 0xe05f,
- .gpio2 = 0x0010,
- .gpio3 = 0x0000,
- }},
- },
- [CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1] = {
- .name = "Hauppauge Nova-S-Plus DVB-S",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .audio_chip = V4L2_IDENT_WM8775,
- .i2sinputcntl = 2,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- /* 2: Line-In */
- .audioroute = 2,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- /* 2: Line-In */
- .audioroute = 2,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- /* 2: Line-In */
- .audioroute = 2,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_HAUPPAUGE_NOVASE2_S1] = {
- .name = "Hauppauge Nova-SE2 DVB-S",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_KWORLD_DVBS_100] = {
- .name = "KWorld DVB-S 100",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .audio_chip = V4L2_IDENT_WM8775,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- /* 2: Line-In */
- .audioroute = 2,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- /* 2: Line-In */
- .audioroute = 2,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- /* 2: Line-In */
- .audioroute = 2,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_HAUPPAUGE_HVR1100] = {
- .name = "Hauppauge WinTV-HVR1100 DVB-T/Hybrid",
- .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- }},
- /* fixme: Add radio support */
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_HAUPPAUGE_HVR1100LP] = {
- .name = "Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)",
- .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- }},
- /* fixme: Add radio support */
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_DNTV_LIVE_DVB_T_PRO] = {
- .name = "digitalnow DNTV Live! DVB-T Pro",
- .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE |
- TDA9887_PORT2_ACTIVE,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0xf80808,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0xf80808,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0xf80808,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0xf80808,
- },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_KWORLD_DVB_T_CX22702] = {
- /* Kworld V-stream Xpert DVB-T with Thomson tuner */
- /* DTT 7579 Conexant CX22702-19 Conexant CX2388x */
- /* Manenti Marco <marco_manenti@colman.it> */
- .name = "KWorld/VStream XPert DVB-T with cx22702",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0700,
- .gpio2 = 0x0101,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0700,
- .gpio2 = 0x0101,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL] = {
- .name = "DViCO FusionHDTV DVB-T Dual Digital",
- .tuner_type = TUNER_ABSENT, /* No analog tuner */
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x000067df,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x000067df,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = {
- .name = "KWorld HardwareMpegTV XPert",
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x3de2,
- .gpio2 = 0x00ff,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x3de6,
- .audioroute = 1,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x3de6,
- .audioroute = 1,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x3de6,
- .gpio2 = 0x00ff,
- },
- .mpeg = CX88_MPEG_BLACKBIRD,
- },
- [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID] = {
- .name = "DViCO FusionHDTV DVB-T Hybrid",
- .tuner_type = TUNER_THOMSON_FE6600,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0000a75f,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0000a75b,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0000a75b,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_PCHDTV_HD5500] = {
- .name = "pcHDTV HD5500 HDTV",
- .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x87fd,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x87f9,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x87f9,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_KWORLD_MCE200_DELUXE] = {
- /* FIXME: tested TV input only, disabled composite,
- svideo and radio until they can be tested also. */
- .name = "Kworld MCE 200 Deluxe",
- .tuner_type = TUNER_TENA_9533_DI,
- .radio_type = UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0000BDE6
- }},
- .mpeg = CX88_MPEG_BLACKBIRD,
- },
- [CX88_BOARD_PIXELVIEW_PLAYTV_P7000] = {
- /* FIXME: SVideo, Composite and FM inputs are untested */
- .name = "PixelView PlayTV P7000",
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE |
- TDA9887_PORT2_ACTIVE,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x5da6,
- }},
- .mpeg = CX88_MPEG_BLACKBIRD,
- },
- [CX88_BOARD_NPGTECH_REALTV_TOP10FM] = {
- .name = "NPG Tech Real TV FM Top 10",
- .tuner_type = TUNER_TNF_5335MF, /* Actually a TNF9535 */
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0788,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x078b,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x078b,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x074a,
- },
- },
- [CX88_BOARD_WINFAST_DTV2000H] = {
- .name = "WinFast DTV2000 H",
- .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x00017304,
- .gpio1 = 0x00008203,
- .gpio2 = 0x00017304,
- .gpio3 = 0x02000000,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0001d701,
- .gpio1 = 0x0000b207,
- .gpio2 = 0x0001d701,
- .gpio3 = 0x02000000,
- }, {
- .type = CX88_VMUX_COMPOSITE2,
- .vmux = 2,
- .gpio0 = 0x0001d503,
- .gpio1 = 0x0000b207,
- .gpio2 = 0x0001d503,
- .gpio3 = 0x02000000,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 3,
- .gpio0 = 0x0001d701,
- .gpio1 = 0x0000b207,
- .gpio2 = 0x0001d701,
- .gpio3 = 0x02000000,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x00015702,
- .gpio1 = 0x0000f207,
- .gpio2 = 0x00015702,
- .gpio3 = 0x02000000,
- },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_WINFAST_DTV2000H_J] = {
- .name = "WinFast DTV2000 H rev. J",
- .tuner_type = TUNER_PHILIPS_FMD1216MEX_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x00017300,
- .gpio1 = 0x00008207,
- .gpio2 = 0x00000000,
- .gpio3 = 0x02000000,
- },{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x00018300,
- .gpio1 = 0x0000f207,
- .gpio2 = 0x00017304,
- .gpio3 = 0x02000000,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x00018301,
- .gpio1 = 0x0000f207,
- .gpio2 = 0x00017304,
- .gpio3 = 0x02000000,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x00018301,
- .gpio1 = 0x0000f207,
- .gpio2 = 0x00017304,
- .gpio3 = 0x02000000,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x00015702,
- .gpio1 = 0x0000f207,
- .gpio2 = 0x00015702,
- .gpio3 = 0x02000000,
- },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_GENIATECH_DVBS] = {
- .name = "Geniatech DVB-S",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_HAUPPAUGE_HVR3000] = {
- .name = "Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T",
- .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .audio_chip = V4L2_IDENT_WM8775,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x84bf,
- /* 1: TV Audio / FM Mono */
- .audioroute = 1,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x84bf,
- /* 2: Line-In */
- .audioroute = 2,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x84bf,
- /* 2: Line-In */
- .audioroute = 2,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x84bf,
- /* 4: FM Stereo (untested) */
- .audioroute = 8,
- },
- .mpeg = CX88_MPEG_DVB,
- .num_frontends = 2,
- },
- [CX88_BOARD_NORWOOD_MICRO] = {
- .name = "Norwood Micro TV Tuner",
- .tuner_type = TUNER_TNF_5335MF,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0709,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x070b,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x070b,
- }},
- },
- [CX88_BOARD_TE_DTV_250_OEM_SWANN] = {
- .name = "Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM",
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x003fffff,
- .gpio1 = 0x00e00000,
- .gpio2 = 0x003fffff,
- .gpio3 = 0x02000000,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x003fffff,
- .gpio1 = 0x00e00000,
- .gpio2 = 0x003fffff,
- .gpio3 = 0x02000000,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x003fffff,
- .gpio1 = 0x00e00000,
- .gpio2 = 0x003fffff,
- .gpio3 = 0x02000000,
- }},
- },
- [CX88_BOARD_HAUPPAUGE_HVR1300] = {
- .name = "Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder",
- .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .audio_chip = V4L2_IDENT_WM8775,
- /*
- * gpio0 as reported by Mike Crash <mike AT mikecrash.com>
- */
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0xef88,
- /* 1: TV Audio / FM Mono */
- .audioroute = 1,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0xef88,
- /* 2: Line-In */
- .audioroute = 2,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0xef88,
- /* 2: Line-In */
- .audioroute = 2,
- }},
- .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD,
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0xef88,
- /* 4: FM Stereo (untested) */
- .audioroute = 8,
- },
- },
- [CX88_BOARD_SAMSUNG_SMT_7020] = {
- .name = "Samsung SMT 7020 DVB-S",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = { {
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_ADSTECH_PTV_390] = {
- .name = "ADS Tech Instant Video PCI",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DEBUG,
- .vmux = 3,
- .gpio0 = 0x04ff,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x07fa,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x07fa,
- }},
- },
- [CX88_BOARD_PINNACLE_PCTV_HD_800i] = {
- .name = "Pinnacle PCTV HD 800i",
- .tuner_type = TUNER_XC5000,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x04fb,
- .gpio1 = 0x10ff,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x04fb,
- .gpio1 = 0x10ef,
- .audioroute = 1,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x04fb,
- .gpio1 = 0x10ef,
- .audioroute = 1,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO] = {
- .name = "DViCO FusionHDTV 5 PCI nano",
- /* xc3008 tuner, digital only for now */
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x000027df, /* Unconfirmed */
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x000027df, /* Unconfirmed */
- .audioroute = 1,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x000027df, /* Unconfirmed */
- .audioroute = 1,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_PINNACLE_HYBRID_PCTV] = {
- .name = "Pinnacle Hybrid PCTV",
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0x61,
- .radio_type = UNSET,
- .radio_addr = ADDR_UNSET,
- .input = { {
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x004ff,
- .gpio1 = 0x010ff,
- .gpio2 = 0x00001,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x004fb,
- .gpio1 = 0x010ef,
- .audioroute = 1,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x004fb,
- .gpio1 = 0x010ef,
- .audioroute = 1,
- } },
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x004ff,
- .gpio1 = 0x010ff,
- .gpio2 = 0x0ff,
- },
- .mpeg = CX88_MPEG_DVB,
- },
- /* Terry Wu <terrywu2009@gmail.com> */
- /* TV Audio : set GPIO 2, 18, 19 value to 0, 1, 0 */
- /* FM Audio : set GPIO 2, 18, 19 value to 0, 0, 0 */
- /* Line-in Audio : set GPIO 2, 18, 19 value to 0, 1, 1 */
- /* Mute Audio : set GPIO 2 value to 1 */
- [CX88_BOARD_WINFAST_TV2000_XP_GLOBAL] = {
- .name = "Leadtek TV2000 XP Global",
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0x61,
- .radio_type = UNSET,
- .radio_addr = ADDR_UNSET,
- .input = { {
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x0000,
- .gpio2 = 0x0C04, /* pin 18 = 1, pin 19 = 0 */
- .gpio3 = 0x0000,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x0000,
- .gpio2 = 0x0C0C, /* pin 18 = 1, pin 19 = 1 */
- .gpio3 = 0x0000,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x0000,
- .gpio2 = 0x0C0C, /* pin 18 = 1, pin 19 = 1 */
- .gpio3 = 0x0000,
- } },
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x0000,
- .gpio2 = 0x0C00, /* pin 18 = 0, pin 19 = 0 */
- .gpio3 = 0x0000,
- },
- },
- [CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36] = {
- .name = "Leadtek TV2000 XP Global (SC4100)",
- .tuner_type = TUNER_XC4000,
- .tuner_addr = 0x61,
- .radio_type = UNSET,
- .radio_addr = ADDR_UNSET,
- .input = { {
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x0000,
- .gpio2 = 0x0C04, /* pin 18 = 1, pin 19 = 0 */
- .gpio3 = 0x0000,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x0000,
- .gpio2 = 0x0C0C, /* pin 18 = 1, pin 19 = 1 */
- .gpio3 = 0x0000,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x0000,
- .gpio2 = 0x0C0C, /* pin 18 = 1, pin 19 = 1 */
- .gpio3 = 0x0000,
- } },
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x0000,
- .gpio2 = 0x0C00, /* pin 18 = 0, pin 19 = 0 */
- .gpio3 = 0x0000,
- },
- },
- [CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43] = {
- .name = "Leadtek TV2000 XP Global (XC4100)",
- .tuner_type = TUNER_XC4000,
- .tuner_addr = 0x61,
- .radio_type = UNSET,
- .radio_addr = ADDR_UNSET,
- .input = { {
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x6040, /* pin 14 = 1, pin 13 = 0 */
- .gpio2 = 0x0000,
- .gpio3 = 0x0000,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x6060, /* pin 14 = 1, pin 13 = 1 */
- .gpio2 = 0x0000,
- .gpio3 = 0x0000,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x6060, /* pin 14 = 1, pin 13 = 1 */
- .gpio2 = 0x0000,
- .gpio3 = 0x0000,
- } },
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x6000, /* pin 14 = 1, pin 13 = 0 */
- .gpio2 = 0x0000,
- .gpio3 = 0x0000,
- },
- },
- [CX88_BOARD_POWERCOLOR_REAL_ANGEL] = {
- .name = "PowerColor RA330", /* Long names may confuse LIRC. */
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0x61,
- .input = { {
- .type = CX88_VMUX_DEBUG,
- .vmux = 3, /* Due to the way the cx88 driver is written, */
- .gpio0 = 0x00ff, /* there is no way to deactivate audio pass- */
- .gpio1 = 0xf39d, /* through without this entry. Furthermore, if */
- .gpio3 = 0x0000, /* the TV mux entry is first, you get audio */
- }, { /* from the tuner on boot for a little while. */
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x00ff,
- .gpio1 = 0xf35d,
- .gpio3 = 0x0000,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x00ff,
- .gpio1 = 0xf37d,
- .gpio3 = 0x0000,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x000ff,
- .gpio1 = 0x0f37d,
- .gpio3 = 0x00000,
- } },
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x000ff,
- .gpio1 = 0x0f35d,
- .gpio3 = 0x00000,
- },
- },
- [CX88_BOARD_GENIATECH_X8000_MT] = {
- /* Also PowerColor Real Angel 330 and Geniatech X800 OEM */
- .name = "Geniatech X8000-MT DVBT",
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0x61,
- .input = { {
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x00000000,
- .gpio1 = 0x00e3e341,
- .gpio2 = 0x00000000,
- .gpio3 = 0x00000000,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x00000000,
- .gpio1 = 0x00e3e361,
- .gpio2 = 0x00000000,
- .gpio3 = 0x00000000,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x00000000,
- .gpio1 = 0x00e3e361,
- .gpio2 = 0x00000000,
- .gpio3 = 0x00000000,
- } },
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x00000000,
- .gpio1 = 0x00e3e341,
- .gpio2 = 0x00000000,
- .gpio3 = 0x00000000,
- },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO] = {
- .name = "DViCO FusionHDTV DVB-T PRO",
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0x61,
- .radio_type = UNSET,
- .radio_addr = ADDR_UNSET,
- .input = { {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x000067df,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x000067df,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD] = {
- .name = "DViCO FusionHDTV 7 Gold",
- .tuner_type = TUNER_XC5000,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x10df,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x16d9,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x16d9,
- }},
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_PROLINK_PV_8000GT] = {
- .name = "Prolink Pixelview MPEG 8000GT",
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0x61,
- .input = { {
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0ff,
- .gpio2 = 0x0cfb,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio2 = 0x0cfb,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio2 = 0x0cfb,
- } },
- .radio = {
- .type = CX88_RADIO,
- .gpio2 = 0x0cfb,
- },
- },
- [CX88_BOARD_PROLINK_PV_GLOBAL_XTREME] = {
- .name = "Prolink Pixelview Global Extreme",
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0x61,
- .input = { {
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x04fb,
- .gpio1 = 0x04080,
- .gpio2 = 0x0cf7,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x04fb,
- .gpio1 = 0x04080,
- .gpio2 = 0x0cfb,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x04fb,
- .gpio1 = 0x04080,
- .gpio2 = 0x0cfb,
- } },
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x04ff,
- .gpio1 = 0x04080,
- .gpio2 = 0x0cf7,
- },
- },
- /* Both radio, analog and ATSC work with this board.
- However, for analog to work, s5h1409 gate should be open,
- otherwise, tuner-xc3028 won't be detected.
- A proper fix require using the newer i2c methods to add
- tuner-xc3028 without doing an i2c probe.
- */
- [CX88_BOARD_KWORLD_ATSC_120] = {
- .name = "Kworld PlusTV HD PCI 120 (ATSC 120)",
- .tuner_type = TUNER_XC2028,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = { {
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x000000ff,
- .gpio1 = 0x0000f35d,
- .gpio2 = 0x00000000,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x000000ff,
- .gpio1 = 0x0000f37e,
- .gpio2 = 0x00000000,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x000000ff,
- .gpio1 = 0x0000f37e,
- .gpio2 = 0x00000000,
- } },
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x000000ff,
- .gpio1 = 0x0000f35d,
- .gpio2 = 0x00000000,
- },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_HAUPPAUGE_HVR4000] = {
- .name = "Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid",
- .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .audio_chip = V4L2_IDENT_WM8775,
- /*
- * GPIO0 (WINTV2000)
- *
- * Analogue SAT DVB-T
- * Antenna 0xc4bf 0xc4bb
- * Composite 0xc4bf 0xc4bb
- * S-Video 0xc4bf 0xc4bb
- * Composite1 0xc4ff 0xc4fb
- * S-Video1 0xc4ff 0xc4fb
- *
- * BIT VALUE FUNCTION GP{x}_IO
- * 0 1 I:?
- * 1 1 I:?
- * 2 1 O:MPEG PORT 0=DVB-T 1=DVB-S
- * 3 1 I:?
- * 4 1 I:?
- * 5 1 I:?
- * 6 0 O:INPUT SELECTOR 0=INTERNAL 1=EXPANSION
- * 7 1 O:DVB-T DEMOD RESET LOW
- *
- * BIT VALUE FUNCTION GP{x}_OE
- * 8 0 I
- * 9 0 I
- * a 1 O
- * b 0 I
- * c 0 I
- * d 0 I
- * e 1 O
- * f 1 O
- *
- * WM8775 ADC
- *
- * 1: TV Audio / FM Mono
- * 2: Line-In
- * 3: Line-In Expansion
- * 4: FM Stereo
- */
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0xc4bf,
- /* 1: TV Audio / FM Mono */
- .audioroute = 1,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0xc4bf,
- /* 2: Line-In */
- .audioroute = 2,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0xc4bf,
- /* 2: Line-In */
- .audioroute = 2,
- } },
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0xc4bf,
- /* 4: FM Stereo */
- .audioroute = 8,
- },
- .mpeg = CX88_MPEG_DVB,
- .num_frontends = 2,
- },
- [CX88_BOARD_HAUPPAUGE_HVR4000LITE] = {
- .name = "Hauppauge WinTV-HVR4000(Lite) DVB-S/S2",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_TEVII_S420] = {
- .name = "TeVii S420 DVB-S",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_TEVII_S460] = {
- .name = "TeVii S460 DVB-S/S2",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_TEVII_S464] = {
- .name = "TeVii S464 DVB-S/S2",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_OMICOM_SS4_PCI] = {
- .name = "Omicom SS4 DVB-S/S2 PCI",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_TBS_8910] = {
- .name = "TBS 8910 DVB-S",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_TBS_8920] = {
- .name = "TBS 8920 DVB-S/S2",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- .gpio0 = 0x8080,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_PROF_6200] = {
- .name = "Prof 6200 DVB-S",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_PROF_7300] = {
- .name = "PROF 7300 DVB-S/S2",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_SATTRADE_ST4200] = {
- .name = "SATTRADE ST4200 DVB-S/S2",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII] = {
- .name = "Terratec Cinergy HT PCI MKII",
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0x61,
- .radio_type = UNSET,
- .radio_addr = ADDR_UNSET,
- .input = { {
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x004ff,
- .gpio1 = 0x010ff,
- .gpio2 = 0x00001,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x004fb,
- .gpio1 = 0x010ef,
- .audioroute = 1,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x004fb,
- .gpio1 = 0x010ef,
- .audioroute = 1,
- } },
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x004ff,
- .gpio1 = 0x010ff,
- .gpio2 = 0x0ff,
- },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_HAUPPAUGE_IRONLY] = {
- .name = "Hauppauge WinTV-IR Only",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- },
- [CX88_BOARD_WINFAST_DTV1800H] = {
- .name = "Leadtek WinFast DTV1800 Hybrid",
- .tuner_type = TUNER_XC2028,
- .radio_type = UNSET,
- .tuner_addr = 0x61,
- .radio_addr = ADDR_UNSET,
- /*
- * GPIO setting
- *
- * 2: mute (0=off,1=on)
- * 12: tuner reset pin
- * 13: audio source (0=tuner audio,1=line in)
- * 14: FM (0=on,1=off ???)
- */
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x6040, /* pin 13 = 0, pin 14 = 1 */
- .gpio2 = 0x0000,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x6060, /* pin 13 = 1, pin 14 = 1 */
- .gpio2 = 0x0000,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x6060, /* pin 13 = 1, pin 14 = 1 */
- .gpio2 = 0x0000,
- } },
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x6000, /* pin 13 = 0, pin 14 = 0 */
- .gpio2 = 0x0000,
- },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_WINFAST_DTV1800H_XC4000] = {
- .name = "Leadtek WinFast DTV1800 H (XC4000)",
- .tuner_type = TUNER_XC4000,
- .radio_type = UNSET,
- .tuner_addr = 0x61,
- .radio_addr = ADDR_UNSET,
- /*
- * GPIO setting
- *
- * 2: mute (0=off,1=on)
- * 12: tuner reset pin
- * 13: audio source (0=tuner audio,1=line in)
- * 14: FM (0=on,1=off ???)
- */
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x6040, /* pin 13 = 0, pin 14 = 1 */
- .gpio2 = 0x0000,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x6060, /* pin 13 = 1, pin 14 = 1 */
- .gpio2 = 0x0000,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x6060, /* pin 13 = 1, pin 14 = 1 */
- .gpio2 = 0x0000,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x0400, /* pin 2 = 0 */
- .gpio1 = 0x6000, /* pin 13 = 0, pin 14 = 0 */
- .gpio2 = 0x0000,
- },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_WINFAST_DTV2000H_PLUS] = {
- .name = "Leadtek WinFast DTV2000 H PLUS",
- .tuner_type = TUNER_XC4000,
- .radio_type = UNSET,
- .tuner_addr = 0x61,
- .radio_addr = ADDR_UNSET,
- /*
- * GPIO
- * 2: 1: mute audio
- * 12: 0: reset XC4000
- * 13: 1: audio input is line in (0: tuner)
- * 14: 0: FM radio
- * 16: 0: RF input is cable
- */
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0403,
- .gpio1 = 0xF0D7,
- .gpio2 = 0x0101,
- .gpio3 = 0x0000,
- }, {
- .type = CX88_VMUX_CABLE,
- .vmux = 0,
- .gpio0 = 0x0403,
- .gpio1 = 0xF0D7,
- .gpio2 = 0x0100,
- .gpio3 = 0x0000,
- }, {
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0403, /* was 0x0407 */
- .gpio1 = 0xF0F7,
- .gpio2 = 0x0101,
- .gpio3 = 0x0000,
- }, {
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0403, /* was 0x0407 */
- .gpio1 = 0xF0F7,
- .gpio2 = 0x0101,
- .gpio3 = 0x0000,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x0403,
- .gpio1 = 0xF097,
- .gpio2 = 0x0100,
- .gpio3 = 0x0000,
- },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_PROF_7301] = {
- .name = "Prof 7301 DVB-S/S2",
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = { {
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
- [CX88_BOARD_TWINHAN_VP1027_DVBS] = {
- .name = "Twinhan VP-1027 DVB-S",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- } },
- .mpeg = CX88_MPEG_DVB,
- },
-};
-
-/* ------------------------------------------------------------------ */
-/* PCI subsystem IDs */
-
-static const struct cx88_subid cx88_subids[] = {
- {
- .subvendor = 0x0070,
- .subdevice = 0x3400,
- .card = CX88_BOARD_HAUPPAUGE,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x3401,
- .card = CX88_BOARD_HAUPPAUGE,
- },{
- .subvendor = 0x14c7,
- .subdevice = 0x0106,
- .card = CX88_BOARD_GDI,
- },{
- .subvendor = 0x14c7,
- .subdevice = 0x0107, /* with mpeg encoder */
- .card = CX88_BOARD_GDI,
- },{
- .subvendor = PCI_VENDOR_ID_ATI,
- .subdevice = 0x00f8,
- .card = CX88_BOARD_ATI_WONDER_PRO,
- }, {
- .subvendor = PCI_VENDOR_ID_ATI,
- .subdevice = 0x00f9,
- .card = CX88_BOARD_ATI_WONDER_PRO,
- }, {
- .subvendor = 0x107d,
- .subdevice = 0x6611,
- .card = CX88_BOARD_WINFAST2000XP_EXPERT,
- },{
- .subvendor = 0x107d,
- .subdevice = 0x6613, /* NTSC */
- .card = CX88_BOARD_WINFAST2000XP_EXPERT,
- },{
- .subvendor = 0x107d,
- .subdevice = 0x6620,
- .card = CX88_BOARD_WINFAST_DV2000,
- },{
- .subvendor = 0x107d,
- .subdevice = 0x663b,
- .card = CX88_BOARD_LEADTEK_PVR2000,
- },{
- .subvendor = 0x107d,
- .subdevice = 0x663c,
- .card = CX88_BOARD_LEADTEK_PVR2000,
- },{
- .subvendor = 0x1461,
- .subdevice = 0x000b,
- .card = CX88_BOARD_AVERTV_STUDIO_303,
- },{
- .subvendor = 0x1462,
- .subdevice = 0x8606,
- .card = CX88_BOARD_MSI_TVANYWHERE_MASTER,
- },{
- .subvendor = 0x10fc,
- .subdevice = 0xd003,
- .card = CX88_BOARD_IODATA_GVVCP3PCI,
- },{
- .subvendor = 0x1043,
- .subdevice = 0x4823, /* with mpeg encoder */
- .card = CX88_BOARD_ASUS_PVR_416,
- },{
- .subvendor = 0x17de,
- .subdevice = 0x08a6,
- .card = CX88_BOARD_KWORLD_DVB_T,
- },{
- .subvendor = 0x18ac,
- .subdevice = 0xd810,
- .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q,
- },{
- .subvendor = 0x18ac,
- .subdevice = 0xd820,
- .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T,
- },{
- .subvendor = 0x18ac,
- .subdevice = 0xdb00,
- .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x9002,
- .card = CX88_BOARD_HAUPPAUGE_DVB_T1,
- },{
- .subvendor = 0x14f1,
- .subdevice = 0x0187,
- .card = CX88_BOARD_CONEXANT_DVB_T1,
- },{
- .subvendor = 0x1540,
- .subdevice = 0x2580,
- .card = CX88_BOARD_PROVIDEO_PV259,
- },{
- .subvendor = 0x18ac,
- .subdevice = 0xdb10,
- .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
- },{
- .subvendor = 0x1554,
- .subdevice = 0x4811,
- .card = CX88_BOARD_PIXELVIEW,
- },{
- .subvendor = 0x7063,
- .subdevice = 0x3000, /* HD-3000 card */
- .card = CX88_BOARD_PCHDTV_HD3000,
- },{
- .subvendor = 0x17de,
- .subdevice = 0xa8a6,
- .card = CX88_BOARD_DNTV_LIVE_DVB_T,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x2801,
- .card = CX88_BOARD_HAUPPAUGE_ROSLYN,
- },{
- .subvendor = 0x14f1,
- .subdevice = 0x0342,
- .card = CX88_BOARD_DIGITALLOGIC_MEC,
- },{
- .subvendor = 0x10fc,
- .subdevice = 0xd035,
- .card = CX88_BOARD_IODATA_GVBCTV7E,
- },{
- .subvendor = 0x1421,
- .subdevice = 0x0334,
- .card = CX88_BOARD_ADSTECH_DVB_T_PCI,
- },{
- .subvendor = 0x153b,
- .subdevice = 0x1166,
- .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1,
- },{
- .subvendor = 0x18ac,
- .subdevice = 0xd500,
- .card = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD,
- },{
- .subvendor = 0x1461,
- .subdevice = 0x8011,
- .card = CX88_BOARD_AVERMEDIA_ULTRATV_MC_550,
- },{
- .subvendor = PCI_VENDOR_ID_ATI,
- .subdevice = 0xa101,
- .card = CX88_BOARD_ATI_HDTVWONDER,
- },{
- .subvendor = 0x107d,
- .subdevice = 0x665f,
- .card = CX88_BOARD_WINFAST_DTV1000,
- },{
- .subvendor = 0x1461,
- .subdevice = 0x000a,
- .card = CX88_BOARD_AVERTV_303,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x9200,
- .card = CX88_BOARD_HAUPPAUGE_NOVASE2_S1,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x9201,
- .card = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x9202,
- .card = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1,
- },{
- .subvendor = 0x17de,
- .subdevice = 0x08b2,
- .card = CX88_BOARD_KWORLD_DVBS_100,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x9400,
- .card = CX88_BOARD_HAUPPAUGE_HVR1100,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x9402,
- .card = CX88_BOARD_HAUPPAUGE_HVR1100,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x9800,
- .card = CX88_BOARD_HAUPPAUGE_HVR1100LP,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x9802,
- .card = CX88_BOARD_HAUPPAUGE_HVR1100LP,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x9001,
- .card = CX88_BOARD_HAUPPAUGE_DVB_T1,
- },{
- .subvendor = 0x1822,
- .subdevice = 0x0025,
- .card = CX88_BOARD_DNTV_LIVE_DVB_T_PRO,
- },{
- .subvendor = 0x17de,
- .subdevice = 0x08a1,
- .card = CX88_BOARD_KWORLD_DVB_T_CX22702,
- },{
- .subvendor = 0x18ac,
- .subdevice = 0xdb50,
- .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
- },{
- .subvendor = 0x18ac,
- .subdevice = 0xdb54,
- .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
- /* Re-branded DViCO: DigitalNow DVB-T Dual */
- },{
- .subvendor = 0x18ac,
- .subdevice = 0xdb11,
- .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
- /* Re-branded DViCO: UltraView DVB-T Plus */
- }, {
- .subvendor = 0x18ac,
- .subdevice = 0xdb30,
- .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO,
- }, {
- .subvendor = 0x17de,
- .subdevice = 0x0840,
- .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT,
- },{
- .subvendor = 0x1421,
- .subdevice = 0x0305,
- .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT,
- },{
- .subvendor = 0x18ac,
- .subdevice = 0xdb40,
- .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID,
- },{
- .subvendor = 0x18ac,
- .subdevice = 0xdb44,
- .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID,
- },{
- .subvendor = 0x7063,
- .subdevice = 0x5500,
- .card = CX88_BOARD_PCHDTV_HD5500,
- },{
- .subvendor = 0x17de,
- .subdevice = 0x0841,
- .card = CX88_BOARD_KWORLD_MCE200_DELUXE,
- },{
- .subvendor = 0x1822,
- .subdevice = 0x0019,
- .card = CX88_BOARD_DNTV_LIVE_DVB_T_PRO,
- },{
- .subvendor = 0x1554,
- .subdevice = 0x4813,
- .card = CX88_BOARD_PIXELVIEW_PLAYTV_P7000,
- },{
- .subvendor = 0x14f1,
- .subdevice = 0x0842,
- .card = CX88_BOARD_NPGTECH_REALTV_TOP10FM,
- },{
- .subvendor = 0x107d,
- .subdevice = 0x665e,
- .card = CX88_BOARD_WINFAST_DTV2000H,
- },{
- .subvendor = 0x107d,
- .subdevice = 0x6f2b,
- .card = CX88_BOARD_WINFAST_DTV2000H_J,
- },{
- .subvendor = 0x18ac,
- .subdevice = 0xd800, /* FusionHDTV 3 Gold (original revision) */
- .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q,
- },{
- .subvendor = 0x14f1,
- .subdevice = 0x0084,
- .card = CX88_BOARD_GENIATECH_DVBS,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x1404,
- .card = CX88_BOARD_HAUPPAUGE_HVR3000,
- }, {
- .subvendor = 0x18ac,
- .subdevice = 0xdc00,
- .card = CX88_BOARD_SAMSUNG_SMT_7020,
- }, {
- .subvendor = 0x18ac,
- .subdevice = 0xdccd,
- .card = CX88_BOARD_SAMSUNG_SMT_7020,
- },{
- .subvendor = 0x1461,
- .subdevice = 0xc111, /* AverMedia M150-D */
- /* This board is known to work with the ASUS PVR416 config */
- .card = CX88_BOARD_ASUS_PVR_416,
- },{
- .subvendor = 0xc180,
- .subdevice = 0xc980,
- .card = CX88_BOARD_TE_DTV_250_OEM_SWANN,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x9600,
- .card = CX88_BOARD_HAUPPAUGE_HVR1300,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x9601,
- .card = CX88_BOARD_HAUPPAUGE_HVR1300,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x9602,
- .card = CX88_BOARD_HAUPPAUGE_HVR1300,
- },{
- .subvendor = 0x107d,
- .subdevice = 0x6632,
- .card = CX88_BOARD_LEADTEK_PVR2000,
- },{
- .subvendor = 0x12ab,
- .subdevice = 0x2300, /* Club3D Zap TV2100 */
- .card = CX88_BOARD_KWORLD_DVB_T_CX22702,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x9000,
- .card = CX88_BOARD_HAUPPAUGE_DVB_T1,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x1400,
- .card = CX88_BOARD_HAUPPAUGE_HVR3000,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x1401,
- .card = CX88_BOARD_HAUPPAUGE_HVR3000,
- },{
- .subvendor = 0x0070,
- .subdevice = 0x1402,
- .card = CX88_BOARD_HAUPPAUGE_HVR3000,
- },{
- .subvendor = 0x1421,
- .subdevice = 0x0341, /* ADS Tech InstantTV DVB-S */
- .card = CX88_BOARD_KWORLD_DVBS_100,
- },{
- .subvendor = 0x1421,
- .subdevice = 0x0390,
- .card = CX88_BOARD_ADSTECH_PTV_390,
- },{
- .subvendor = 0x11bd,
- .subdevice = 0x0051,
- .card = CX88_BOARD_PINNACLE_PCTV_HD_800i,
- }, {
- .subvendor = 0x18ac,
- .subdevice = 0xd530,
- .card = CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO,
- }, {
- .subvendor = 0x12ab,
- .subdevice = 0x1788,
- .card = CX88_BOARD_PINNACLE_HYBRID_PCTV,
- }, {
- .subvendor = 0x14f1,
- .subdevice = 0xea3d,
- .card = CX88_BOARD_POWERCOLOR_REAL_ANGEL,
- }, {
- .subvendor = 0x107d,
- .subdevice = 0x6f18,
- .card = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
- }, {
- .subvendor = 0x14f1,
- .subdevice = 0x8852,
- .card = CX88_BOARD_GENIATECH_X8000_MT,
- }, {
- .subvendor = 0x18ac,
- .subdevice = 0xd610,
- .card = CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD,
- }, {
- .subvendor = 0x1554,
- .subdevice = 0x4935,
- .card = CX88_BOARD_PROLINK_PV_8000GT,
- }, {
- .subvendor = 0x1554,
- .subdevice = 0x4976,
- .card = CX88_BOARD_PROLINK_PV_GLOBAL_XTREME,
- }, {
- .subvendor = 0x17de,
- .subdevice = 0x08c1,
- .card = CX88_BOARD_KWORLD_ATSC_120,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x6900,
- .card = CX88_BOARD_HAUPPAUGE_HVR4000,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x6904,
- .card = CX88_BOARD_HAUPPAUGE_HVR4000,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x6902,
- .card = CX88_BOARD_HAUPPAUGE_HVR4000,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x6905,
- .card = CX88_BOARD_HAUPPAUGE_HVR4000LITE,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x6906,
- .card = CX88_BOARD_HAUPPAUGE_HVR4000LITE,
- }, {
- .subvendor = 0xd420,
- .subdevice = 0x9022,
- .card = CX88_BOARD_TEVII_S420,
- }, {
- .subvendor = 0xd460,
- .subdevice = 0x9022,
- .card = CX88_BOARD_TEVII_S460,
- }, {
- .subvendor = 0xd464,
- .subdevice = 0x9022,
- .card = CX88_BOARD_TEVII_S464,
- }, {
- .subvendor = 0xA044,
- .subdevice = 0x2011,
- .card = CX88_BOARD_OMICOM_SS4_PCI,
- }, {
- .subvendor = 0x8910,
- .subdevice = 0x8888,
- .card = CX88_BOARD_TBS_8910,
- }, {
- .subvendor = 0x8920,
- .subdevice = 0x8888,
- .card = CX88_BOARD_TBS_8920,
- }, {
- .subvendor = 0xb022,
- .subdevice = 0x3022,
- .card = CX88_BOARD_PROF_6200,
- }, {
- .subvendor = 0xB033,
- .subdevice = 0x3033,
- .card = CX88_BOARD_PROF_7300,
- }, {
- .subvendor = 0xb200,
- .subdevice = 0x4200,
- .card = CX88_BOARD_SATTRADE_ST4200,
- }, {
- .subvendor = 0x153b,
- .subdevice = 0x1177,
- .card = CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x9290,
- .card = CX88_BOARD_HAUPPAUGE_IRONLY,
- }, {
- .subvendor = 0x107d,
- .subdevice = 0x6654,
- .card = CX88_BOARD_WINFAST_DTV1800H,
- }, {
- /* WinFast DTV1800 H with XC4000 tuner */
- .subvendor = 0x107d,
- .subdevice = 0x6f38,
- .card = CX88_BOARD_WINFAST_DTV1800H_XC4000,
- }, {
- .subvendor = 0x107d,
- .subdevice = 0x6f42,
- .card = CX88_BOARD_WINFAST_DTV2000H_PLUS,
- }, {
- /* PVR2000 PAL Model [107d:6630] */
- .subvendor = 0x107d,
- .subdevice = 0x6630,
- .card = CX88_BOARD_LEADTEK_PVR2000,
- }, {
- /* PVR2000 PAL Model [107d:6638] */
- .subvendor = 0x107d,
- .subdevice = 0x6638,
- .card = CX88_BOARD_LEADTEK_PVR2000,
- }, {
- /* PVR2000 NTSC Model [107d:6631] */
- .subvendor = 0x107d,
- .subdevice = 0x6631,
- .card = CX88_BOARD_LEADTEK_PVR2000,
- }, {
- /* PVR2000 NTSC Model [107d:6637] */
- .subvendor = 0x107d,
- .subdevice = 0x6637,
- .card = CX88_BOARD_LEADTEK_PVR2000,
- }, {
- /* PVR2000 NTSC Model [107d:663d] */
- .subvendor = 0x107d,
- .subdevice = 0x663d,
- .card = CX88_BOARD_LEADTEK_PVR2000,
- }, {
- /* DV2000 NTSC Model [107d:6621] */
- .subvendor = 0x107d,
- .subdevice = 0x6621,
- .card = CX88_BOARD_WINFAST_DV2000,
- }, {
- /* TV2000 XP Global [107d:6618] */
- .subvendor = 0x107d,
- .subdevice = 0x6618,
- .card = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
- }, {
- /* TV2000 XP Global [107d:6618] */
- .subvendor = 0x107d,
- .subdevice = 0x6619,
- .card = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
- }, {
- /* WinFast TV2000 XP Global with XC4000 tuner */
- .subvendor = 0x107d,
- .subdevice = 0x6f36,
- .card = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36,
- }, {
- /* WinFast TV2000 XP Global with XC4000 tuner and different GPIOs */
- .subvendor = 0x107d,
- .subdevice = 0x6f43,
- .card = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43,
- }, {
- .subvendor = 0xb034,
- .subdevice = 0x3034,
- .card = CX88_BOARD_PROF_7301,
- }, {
- .subvendor = 0x1822,
- .subdevice = 0x0023,
- .card = CX88_BOARD_TWINHAN_VP1027_DVBS,
- },
-};
-
-/* ----------------------------------------------------------------------- */
-/* some leadtek specific stuff */
-
-static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
-{
- if (eeprom_data[4] != 0x7d ||
- eeprom_data[5] != 0x10 ||
- eeprom_data[7] != 0x66) {
- warn_printk(core, "Leadtek eeprom invalid.\n");
- return;
- }
-
- /* Terry Wu <terrywu2009@gmail.com> */
- switch (eeprom_data[6]) {
- case 0x13: /* SSID 6613 for TV2000 XP Expert NTSC Model */
- case 0x21: /* SSID 6621 for DV2000 NTSC Model */
- case 0x31: /* SSID 6631 for PVR2000 NTSC Model */
- case 0x37: /* SSID 6637 for PVR2000 NTSC Model */
- case 0x3d: /* SSID 6637 for PVR2000 NTSC Model */
- core->board.tuner_type = TUNER_PHILIPS_FM1236_MK3;
- break;
- default:
- core->board.tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
- break;
- }
-
- info_printk(core, "Leadtek Winfast 2000XP Expert config: "
- "tuner=%d, eeprom[0]=0x%02x\n",
- core->board.tuner_type, eeprom_data[0]);
-}
-
-static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
-{
- struct tveeprom tv;
-
- tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data);
- core->board.tuner_type = tv.tuner_type;
- core->tuner_formats = tv.tuner_formats;
- core->board.radio.type = tv.has_radio ? CX88_RADIO : 0;
-
- /* Make sure we support the board model */
- switch (tv.model)
- {
- case 14009: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in) */
- case 14019: /* WinTV-HVR3000 (Retail, IR Blaster, b/panel video, 3.5mm audio in) */
- case 14029: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - 880 bridge) */
- case 14109: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - low profile) */
- case 14129: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - 880 bridge - LP) */
- case 14559: /* WinTV-HVR3000 (OEM, no IR, b/panel video, 3.5mm audio in) */
- case 14569: /* WinTV-HVR3000 (OEM, no IR, no back panel video) */
- case 14659: /* WinTV-HVR3000 (OEM, no IR, b/panel video, RCA audio in - Low profile) */
- case 14669: /* WinTV-HVR3000 (OEM, no IR, no b/panel video - Low profile) */
- case 28552: /* WinTV-PVR 'Roslyn' (No IR) */
- case 34519: /* WinTV-PCI-FM */
- case 69009:
- /* WinTV-HVR4000 (DVBS/S2/T, Video and IR, back panel inputs) */
- case 69100: /* WinTV-HVR4000LITE (DVBS/S2, IR) */
- case 69500: /* WinTV-HVR4000LITE (DVBS/S2, No IR) */
- case 69559:
- /* WinTV-HVR4000 (DVBS/S2/T, Video no IR, back panel inputs) */
- case 69569: /* WinTV-HVR4000 (DVBS/S2/T, Video no IR) */
- case 90002: /* Nova-T-PCI (9002) */
- case 92001: /* Nova-S-Plus (Video and IR) */
- case 92002: /* Nova-S-Plus (Video and IR) */
- case 90003: /* Nova-T-PCI (9002 No RF out) */
- case 90500: /* Nova-T-PCI (oem) */
- case 90501: /* Nova-T-PCI (oem/IR) */
- case 92000: /* Nova-SE2 (OEM, No Video or IR) */
- case 92900: /* WinTV-IROnly (No analog or digital Video inputs) */
- case 94009: /* WinTV-HVR1100 (Video and IR Retail) */
- case 94501: /* WinTV-HVR1100 (Video and IR OEM) */
- case 96009: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX) */
- case 96019: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX/TX) */
- case 96559: /* WinTV-HVR1300 (PAL Video, MPEG Video no IR) */
- case 96569: /* WinTV-HVR1300 () */
- case 96659: /* WinTV-HVR1300 () */
- case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
- /* known */
- break;
- case CX88_BOARD_SAMSUNG_SMT_7020:
- cx_set(MO_GP0_IO, 0x008989FF);
- break;
- default:
- warn_printk(core, "warning: unknown hauppauge model #%d\n",
- tv.model);
- break;
- }
-
- info_printk(core, "hauppauge eeprom: model=%d\n", tv.model);
-}
-
-/* ----------------------------------------------------------------------- */
-/* some GDI (was: Modular Technology) specific stuff */
-
-static const struct {
- int id;
- int fm;
- const char *name;
-} gdi_tuner[] = {
- [ 0x01 ] = { .id = TUNER_ABSENT,
- .name = "NTSC_M" },
- [ 0x02 ] = { .id = TUNER_ABSENT,
- .name = "PAL_B" },
- [ 0x03 ] = { .id = TUNER_ABSENT,
- .name = "PAL_I" },
- [ 0x04 ] = { .id = TUNER_ABSENT,
- .name = "PAL_D" },
- [ 0x05 ] = { .id = TUNER_ABSENT,
- .name = "SECAM" },
-
- [ 0x10 ] = { .id = TUNER_ABSENT,
- .fm = 1,
- .name = "TEMIC_4049" },
- [ 0x11 ] = { .id = TUNER_TEMIC_4136FY5,
- .name = "TEMIC_4136" },
- [ 0x12 ] = { .id = TUNER_ABSENT,
- .name = "TEMIC_4146" },
-
- [ 0x20 ] = { .id = TUNER_PHILIPS_FQ1216ME,
- .fm = 1,
- .name = "PHILIPS_FQ1216_MK3" },
- [ 0x21 ] = { .id = TUNER_ABSENT, .fm = 1,
- .name = "PHILIPS_FQ1236_MK3" },
- [ 0x22 ] = { .id = TUNER_ABSENT,
- .name = "PHILIPS_FI1236_MK3" },
- [ 0x23 ] = { .id = TUNER_ABSENT,
- .name = "PHILIPS_FI1216_MK3" },
-};
-
-static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data)
-{
- const char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner))
- ? gdi_tuner[eeprom_data[0x0d]].name : NULL;
-
- info_printk(core, "GDI: tuner=%s\n", name ? name : "unknown");
- if (NULL == name)
- return;
- core->board.tuner_type = gdi_tuner[eeprom_data[0x0d]].id;
- core->board.radio.type = gdi_tuner[eeprom_data[0x0d]].fm ?
- CX88_RADIO : 0;
-}
-
-/* ------------------------------------------------------------------- */
-/* some Divco specific stuff */
-static int cx88_dvico_xc2028_callback(struct cx88_core *core,
- int command, int arg)
-{
- switch (command) {
- case XC2028_TUNER_RESET:
- switch (core->boardnr) {
- case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
- /* GPIO-4 xc3028 tuner */
-
- cx_set(MO_GP0_IO, 0x00001000);
- cx_clear(MO_GP0_IO, 0x00000010);
- msleep(100);
- cx_set(MO_GP0_IO, 0x00000010);
- msleep(100);
- break;
- default:
- cx_write(MO_GP0_IO, 0x101000);
- mdelay(5);
- cx_set(MO_GP0_IO, 0x101010);
- }
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-/* ----------------------------------------------------------------------- */
-/* some Geniatech specific stuff */
-
-static int cx88_xc3028_geniatech_tuner_callback(struct cx88_core *core,
- int command, int mode)
-{
- switch (command) {
- case XC2028_TUNER_RESET:
- switch (INPUT(core->input).type) {
- case CX88_RADIO:
- break;
- case CX88_VMUX_DVB:
- cx_write(MO_GP1_IO, 0x030302);
- mdelay(50);
- break;
- default:
- cx_write(MO_GP1_IO, 0x030301);
- mdelay(50);
- }
- cx_write(MO_GP1_IO, 0x101010);
- mdelay(50);
- cx_write(MO_GP1_IO, 0x101000);
- mdelay(50);
- cx_write(MO_GP1_IO, 0x101010);
- mdelay(50);
- return 0;
- }
- return -EINVAL;
-}
-
-static int cx88_xc3028_winfast1800h_callback(struct cx88_core *core,
- int command, int arg)
-{
- switch (command) {
- case XC2028_TUNER_RESET:
- /* GPIO 12 (xc3028 tuner reset) */
- cx_set(MO_GP1_IO, 0x1010);
- mdelay(50);
- cx_clear(MO_GP1_IO, 0x10);
- mdelay(50);
- cx_set(MO_GP1_IO, 0x10);
- mdelay(50);
- return 0;
- }
- return -EINVAL;
-}
-
-static int cx88_xc4000_winfast2000h_plus_callback(struct cx88_core *core,
- int command, int arg)
-{
- switch (command) {
- case XC4000_TUNER_RESET:
- /* GPIO 12 (xc4000 tuner reset) */
- cx_set(MO_GP1_IO, 0x1010);
- mdelay(50);
- cx_clear(MO_GP1_IO, 0x10);
- mdelay(75);
- cx_set(MO_GP1_IO, 0x10);
- mdelay(75);
- return 0;
- }
- return -EINVAL;
-}
-
-/* ------------------------------------------------------------------- */
-/* some Divco specific stuff */
-static int cx88_pv_8000gt_callback(struct cx88_core *core,
- int command, int arg)
-{
- switch (command) {
- case XC2028_TUNER_RESET:
- cx_write(MO_GP2_IO, 0xcf7);
- mdelay(50);
- cx_write(MO_GP2_IO, 0xef5);
- mdelay(50);
- cx_write(MO_GP2_IO, 0xcf7);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-/* some DViCO specific stuff */
-
-static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core)
-{
- struct i2c_msg msg = { .addr = 0x45, .flags = 0 };
- int i, err;
- static u8 init_bufs[13][5] = {
- { 0x10, 0x00, 0x20, 0x01, 0x03 },
- { 0x10, 0x10, 0x01, 0x00, 0x21 },
- { 0x10, 0x10, 0x10, 0x00, 0xCA },
- { 0x10, 0x10, 0x12, 0x00, 0x08 },
- { 0x10, 0x10, 0x13, 0x00, 0x0A },
- { 0x10, 0x10, 0x16, 0x01, 0xC0 },
- { 0x10, 0x10, 0x22, 0x01, 0x3D },
- { 0x10, 0x10, 0x73, 0x01, 0x2E },
- { 0x10, 0x10, 0x72, 0x00, 0xC5 },
- { 0x10, 0x10, 0x71, 0x01, 0x97 },
- { 0x10, 0x10, 0x70, 0x00, 0x0F },
- { 0x10, 0x10, 0xB0, 0x00, 0x01 },
- { 0x03, 0x0C },
- };
-
- for (i = 0; i < ARRAY_SIZE(init_bufs); i++) {
- msg.buf = init_bufs[i];
- msg.len = (i != 12 ? 5 : 2);
- err = i2c_transfer(&core->i2c_adap, &msg, 1);
- if (err != 1) {
- warn_printk(core, "dvico_fusionhdtv_hybrid_init buf %d "
- "failed (err = %d)!\n", i, err);
- return;
- }
- }
-}
-
-static int cx88_xc2028_tuner_callback(struct cx88_core *core,
- int command, int arg)
-{
- /* Board-specific callbacks */
- switch (core->boardnr) {
- case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
- case CX88_BOARD_GENIATECH_X8000_MT:
- case CX88_BOARD_KWORLD_ATSC_120:
- return cx88_xc3028_geniatech_tuner_callback(core,
- command, arg);
- case CX88_BOARD_PROLINK_PV_8000GT:
- case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
- return cx88_pv_8000gt_callback(core, command, arg);
- case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
- case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
- return cx88_dvico_xc2028_callback(core, command, arg);
- case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
- case CX88_BOARD_WINFAST_DTV1800H:
- return cx88_xc3028_winfast1800h_callback(core, command, arg);
- }
-
- switch (command) {
- case XC2028_TUNER_RESET:
- switch (INPUT(core->input).type) {
- case CX88_RADIO:
- info_printk(core, "setting GPIO to radio!\n");
- cx_write(MO_GP0_IO, 0x4ff);
- mdelay(250);
- cx_write(MO_GP2_IO, 0xff);
- mdelay(250);
- break;
- case CX88_VMUX_DVB: /* Digital TV*/
- default: /* Analog TV */
- info_printk(core, "setting GPIO to TV!\n");
- break;
- }
- cx_write(MO_GP1_IO, 0x101010);
- mdelay(250);
- cx_write(MO_GP1_IO, 0x101000);
- mdelay(250);
- cx_write(MO_GP1_IO, 0x101010);
- mdelay(250);
- return 0;
- }
- return -EINVAL;
-}
-
-static int cx88_xc4000_tuner_callback(struct cx88_core *core,
- int command, int arg)
-{
- /* Board-specific callbacks */
- switch (core->boardnr) {
- case CX88_BOARD_WINFAST_DTV1800H_XC4000:
- case CX88_BOARD_WINFAST_DTV2000H_PLUS:
- case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36:
- case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43:
- return cx88_xc4000_winfast2000h_plus_callback(core,
- command, arg);
- }
- return -EINVAL;
-}
-
-/* ----------------------------------------------------------------------- */
-/* Tuner callback function. Currently only needed for the Pinnacle *
- * PCTV HD 800i with an xc5000 sillicon tuner. This is used for both *
- * analog tuner attach (tuner-core.c) and dvb tuner attach (cx88-dvb.c) */
-
-static int cx88_xc5000_tuner_callback(struct cx88_core *core,
- int command, int arg)
-{
- switch (core->boardnr) {
- case CX88_BOARD_PINNACLE_PCTV_HD_800i:
- if (command == 0) { /* This is the reset command from xc5000 */
-
- /* djh - According to the engineer at PCTV Systems,
- the xc5000 reset pin is supposed to be on GPIO12.
- However, despite three nights of effort, pulling
- that GPIO low didn't reset the xc5000. While
- pulling MO_SRST_IO low does reset the xc5000, this
- also resets in the s5h1409 being reset as well.
- This causes tuning to always fail since the internal
- state of the s5h1409 does not match the driver's
- state. Given that the only two conditions in which
- the driver performs a reset is during firmware load
- and powering down the chip, I am taking out the
- reset. We know that the chip is being reset
- when the cx88 comes online, and not being able to
- do power management for this board is worse than
- not having any tuning at all. */
- return 0;
- } else {
- err_printk(core, "xc5000: unknown tuner "
- "callback command.\n");
- return -EINVAL;
- }
- break;
- case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
- if (command == 0) { /* This is the reset command from xc5000 */
- cx_clear(MO_GP0_IO, 0x00000010);
- msleep(10);
- cx_set(MO_GP0_IO, 0x00000010);
- return 0;
- } else {
- printk(KERN_ERR
- "xc5000: unknown tuner callback command.\n");
- return -EINVAL;
- }
- break;
- }
- return 0; /* Should never be here */
-}
-
-int cx88_tuner_callback(void *priv, int component, int command, int arg)
-{
- struct i2c_algo_bit_data *i2c_algo = priv;
- struct cx88_core *core;
-
- if (!i2c_algo) {
- printk(KERN_ERR "cx88: Error - i2c private data undefined.\n");
- return -EINVAL;
- }
-
- core = i2c_algo->data;
-
- if (!core) {
- printk(KERN_ERR "cx88: Error - device struct undefined.\n");
- return -EINVAL;
- }
-
- if (component != DVB_FRONTEND_COMPONENT_TUNER)
- return -EINVAL;
-
- switch (core->board.tuner_type) {
- case TUNER_XC2028:
- info_printk(core, "Calling XC2028/3028 callback\n");
- return cx88_xc2028_tuner_callback(core, command, arg);
- case TUNER_XC4000:
- info_printk(core, "Calling XC4000 callback\n");
- return cx88_xc4000_tuner_callback(core, command, arg);
- case TUNER_XC5000:
- info_printk(core, "Calling XC5000 callback\n");
- return cx88_xc5000_tuner_callback(core, command, arg);
- }
- err_printk(core, "Error: Calling callback for tuner %d\n",
- core->board.tuner_type);
- return -EINVAL;
-}
-EXPORT_SYMBOL(cx88_tuner_callback);
-
-/* ----------------------------------------------------------------------- */
-
-static void cx88_card_list(struct cx88_core *core, struct pci_dev *pci)
-{
- int i;
-
- if (0 == pci->subsystem_vendor &&
- 0 == pci->subsystem_device) {
- printk(KERN_ERR
- "%s: Your board has no valid PCI Subsystem ID and thus can't\n"
- "%s: be autodetected. Please pass card=<n> insmod option to\n"
- "%s: workaround that. Redirect complaints to the vendor of\n"
- "%s: the TV card. Best regards,\n"
- "%s: -- tux\n",
- core->name,core->name,core->name,core->name,core->name);
- } else {
- printk(KERN_ERR
- "%s: Your board isn't known (yet) to the driver. You can\n"
- "%s: try to pick one of the existing card configs via\n"
- "%s: card=<n> insmod option. Updating to the latest\n"
- "%s: version might help as well.\n",
- core->name,core->name,core->name,core->name);
- }
- err_printk(core, "Here is a list of valid choices for the card=<n> "
- "insmod option:\n");
- for (i = 0; i < ARRAY_SIZE(cx88_boards); i++)
- printk(KERN_ERR "%s: card=%d -> %s\n",
- core->name, i, cx88_boards[i].name);
-}
-
-static void cx88_card_setup_pre_i2c(struct cx88_core *core)
-{
- switch (core->boardnr) {
- case CX88_BOARD_HAUPPAUGE_HVR1300:
- /*
- * Bring the 702 demod up before i2c scanning/attach or devices are hidden
- * We leave here with the 702 on the bus
- *
- * "reset the IR receiver on GPIO[3]"
- * Reported by Mike Crash <mike AT mikecrash.com>
- */
- cx_write(MO_GP0_IO, 0x0000ef88);
- udelay(1000);
- cx_clear(MO_GP0_IO, 0x00000088);
- udelay(50);
- cx_set(MO_GP0_IO, 0x00000088); /* 702 out of reset */
- udelay(1000);
- break;
-
- case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
- case CX88_BOARD_PROLINK_PV_8000GT:
- cx_write(MO_GP2_IO, 0xcf7);
- mdelay(50);
- cx_write(MO_GP2_IO, 0xef5);
- mdelay(50);
- cx_write(MO_GP2_IO, 0xcf7);
- msleep(10);
- break;
-
- case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
- /* Enable the xc5000 tuner */
- cx_set(MO_GP0_IO, 0x00001010);
- break;
-
- case CX88_BOARD_WINFAST_DTV2000H_J:
- case CX88_BOARD_HAUPPAUGE_HVR3000:
- case CX88_BOARD_HAUPPAUGE_HVR4000:
- /* Init GPIO */
- cx_write(MO_GP0_IO, core->board.input[0].gpio0);
- udelay(1000);
- cx_clear(MO_GP0_IO, 0x00000080);
- udelay(50);
- cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */
- udelay(1000);
- break;
-
- case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
- case CX88_BOARD_WINFAST_DTV1800H:
- cx88_xc3028_winfast1800h_callback(core, XC2028_TUNER_RESET, 0);
- break;
-
- case CX88_BOARD_WINFAST_DTV1800H_XC4000:
- case CX88_BOARD_WINFAST_DTV2000H_PLUS:
- case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36:
- case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43:
- cx88_xc4000_winfast2000h_plus_callback(core,
- XC4000_TUNER_RESET, 0);
- break;
-
- case CX88_BOARD_TWINHAN_VP1027_DVBS:
- cx_write(MO_GP0_IO, 0x00003230);
- cx_write(MO_GP0_IO, 0x00003210);
- msleep(1);
- cx_write(MO_GP0_IO, 0x00001230);
- break;
- }
-}
-
-/*
- * Sets board-dependent xc3028 configuration
- */
-void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
-{
- memset(ctl, 0, sizeof(*ctl));
-
- ctl->fname = XC2028_DEFAULT_FIRMWARE;
- ctl->max_len = 64;
-
- switch (core->boardnr) {
- case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
- /* Now works with firmware version 2.7 */
- if (core->i2c_algo.udelay < 16)
- core->i2c_algo.udelay = 16;
- break;
- case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
- case CX88_BOARD_WINFAST_DTV1800H:
- ctl->demod = XC3028_FE_ZARLINK456;
- break;
- case CX88_BOARD_KWORLD_ATSC_120:
- case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
- ctl->demod = XC3028_FE_OREN538;
- break;
- case CX88_BOARD_GENIATECH_X8000_MT:
- /* FIXME: For this board, the xc3028 never recovers after being
- powered down (the reset GPIO probably is not set properly).
- We don't have access to the hardware so we cannot determine
- which GPIO is used for xc3028, so just disable power xc3028
- power management for now */
- ctl->disable_power_mgmt = 1;
- break;
- case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
- case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
- case CX88_BOARD_PROLINK_PV_8000GT:
- /*
- * Those boards uses non-MTS firmware
- */
- break;
- case CX88_BOARD_PINNACLE_HYBRID_PCTV:
- case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
- ctl->demod = XC3028_FE_ZARLINK456;
- ctl->mts = 1;
- break;
- default:
- ctl->demod = XC3028_FE_OREN538;
- ctl->mts = 1;
- }
-}
-EXPORT_SYMBOL_GPL(cx88_setup_xc3028);
-
-static void cx88_card_setup(struct cx88_core *core)
-{
- static u8 eeprom[256];
- struct tuner_setup tun_setup;
- unsigned int mode_mask = T_RADIO | T_ANALOG_TV;
-
- memset(&tun_setup, 0, sizeof(tun_setup));
-
- if (0 == core->i2c_rc) {
- core->i2c_client.addr = 0xa0 >> 1;
- tveeprom_read(&core->i2c_client, eeprom, sizeof(eeprom));
- }
-
- switch (core->boardnr) {
- case CX88_BOARD_HAUPPAUGE:
- case CX88_BOARD_HAUPPAUGE_ROSLYN:
- if (0 == core->i2c_rc)
- hauppauge_eeprom(core, eeprom+8);
- break;
- case CX88_BOARD_GDI:
- if (0 == core->i2c_rc)
- gdi_eeprom(core, eeprom);
- break;
- case CX88_BOARD_LEADTEK_PVR2000:
- case CX88_BOARD_WINFAST_DV2000:
- case CX88_BOARD_WINFAST2000XP_EXPERT:
- if (0 == core->i2c_rc)
- leadtek_eeprom(core, eeprom);
- break;
- case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
- case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
- case CX88_BOARD_HAUPPAUGE_DVB_T1:
- case CX88_BOARD_HAUPPAUGE_HVR1100:
- case CX88_BOARD_HAUPPAUGE_HVR1100LP:
- case CX88_BOARD_HAUPPAUGE_HVR3000:
- case CX88_BOARD_HAUPPAUGE_HVR1300:
- case CX88_BOARD_HAUPPAUGE_HVR4000:
- case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
- case CX88_BOARD_HAUPPAUGE_IRONLY:
- if (0 == core->i2c_rc)
- hauppauge_eeprom(core, eeprom);
- break;
- case CX88_BOARD_KWORLD_DVBS_100:
- cx_write(MO_GP0_IO, 0x000007f8);
- cx_write(MO_GP1_IO, 0x00000001);
- break;
- case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
- /* GPIO0:0 is hooked to demod reset */
- /* GPIO0:4 is hooked to xc3028 reset */
- cx_write(MO_GP0_IO, 0x00111100);
- msleep(1);
- cx_write(MO_GP0_IO, 0x00111111);
- break;
- case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
- /* GPIO0:6 is hooked to FX2 reset pin */
- cx_set(MO_GP0_IO, 0x00004040);
- cx_clear(MO_GP0_IO, 0x00000040);
- msleep(1000);
- cx_set(MO_GP0_IO, 0x00004040);
- /* FALLTHROUGH */
- case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
- case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
- case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
- /* GPIO0:0 is hooked to mt352 reset pin */
- cx_set(MO_GP0_IO, 0x00000101);
- cx_clear(MO_GP0_IO, 0x00000001);
- msleep(1);
- cx_set(MO_GP0_IO, 0x00000101);
- if (0 == core->i2c_rc &&
- core->boardnr == CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID)
- dvico_fusionhdtv_hybrid_init(core);
- break;
- case CX88_BOARD_KWORLD_DVB_T:
- case CX88_BOARD_DNTV_LIVE_DVB_T:
- cx_set(MO_GP0_IO, 0x00000707);
- cx_set(MO_GP2_IO, 0x00000101);
- cx_clear(MO_GP2_IO, 0x00000001);
- msleep(1);
- cx_clear(MO_GP0_IO, 0x00000007);
- cx_set(MO_GP2_IO, 0x00000101);
- break;
- case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
- cx_write(MO_GP0_IO, 0x00080808);
- break;
- case CX88_BOARD_ATI_HDTVWONDER:
- if (0 == core->i2c_rc) {
- /* enable tuner */
- int i;
- static const u8 buffer [][2] = {
- {0x10,0x12},
- {0x13,0x04},
- {0x16,0x00},
- {0x14,0x04},
- {0x17,0x00}
- };
- core->i2c_client.addr = 0x0a;
-
- for (i = 0; i < ARRAY_SIZE(buffer); i++)
- if (2 != i2c_master_send(&core->i2c_client,
- buffer[i],2))
- warn_printk(core, "Unable to enable "
- "tuner(%i).\n", i);
- }
- break;
- case CX88_BOARD_MSI_TVANYWHERE_MASTER:
- {
- struct v4l2_priv_tun_config tea5767_cfg;
- struct tea5767_ctrl ctl;
-
- memset(&ctl, 0, sizeof(ctl));
-
- ctl.high_cut = 1;
- ctl.st_noise = 1;
- ctl.deemph_75 = 1;
- ctl.xtal_freq = TEA5767_HIGH_LO_13MHz;
-
- tea5767_cfg.tuner = TUNER_TEA5767;
- tea5767_cfg.priv = &ctl;
-
- call_all(core, tuner, s_config, &tea5767_cfg);
- break;
- }
- case CX88_BOARD_TEVII_S420:
- case CX88_BOARD_TEVII_S460:
- case CX88_BOARD_TEVII_S464:
- case CX88_BOARD_OMICOM_SS4_PCI:
- case CX88_BOARD_TBS_8910:
- case CX88_BOARD_TBS_8920:
- case CX88_BOARD_PROF_6200:
- case CX88_BOARD_PROF_7300:
- case CX88_BOARD_PROF_7301:
- case CX88_BOARD_SATTRADE_ST4200:
- cx_write(MO_GP0_IO, 0x8000);
- msleep(100);
- cx_write(MO_SRST_IO, 0);
- msleep(10);
- cx_write(MO_GP0_IO, 0x8080);
- msleep(100);
- cx_write(MO_SRST_IO, 1);
- msleep(100);
- break;
- } /*end switch() */
-
-
- /* Setup tuners */
- if ((core->board.radio_type != UNSET)) {
- tun_setup.mode_mask = T_RADIO;
- tun_setup.type = core->board.radio_type;
- tun_setup.addr = core->board.radio_addr;
- tun_setup.tuner_callback = cx88_tuner_callback;
- call_all(core, tuner, s_type_addr, &tun_setup);
- mode_mask &= ~T_RADIO;
- }
-
- if (core->board.tuner_type != TUNER_ABSENT) {
- tun_setup.mode_mask = mode_mask;
- tun_setup.type = core->board.tuner_type;
- tun_setup.addr = core->board.tuner_addr;
- tun_setup.tuner_callback = cx88_tuner_callback;
-
- call_all(core, tuner, s_type_addr, &tun_setup);
- }
-
- if (core->board.tda9887_conf) {
- struct v4l2_priv_tun_config tda9887_cfg;
-
- tda9887_cfg.tuner = TUNER_TDA9887;
- tda9887_cfg.priv = &core->board.tda9887_conf;
-
- call_all(core, tuner, s_config, &tda9887_cfg);
- }
-
- if (core->board.tuner_type == TUNER_XC2028) {
- struct v4l2_priv_tun_config xc2028_cfg;
- struct xc2028_ctrl ctl;
-
- /* Fills device-dependent initialization parameters */
- cx88_setup_xc3028(core, &ctl);
-
- /* Sends parameters to xc2028/3028 tuner */
- memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
- xc2028_cfg.tuner = TUNER_XC2028;
- xc2028_cfg.priv = &ctl;
- info_printk(core, "Asking xc2028/3028 to load firmware %s\n",
- ctl.fname);
- call_all(core, tuner, s_config, &xc2028_cfg);
- }
- call_all(core, core, s_power, 0);
-}
-
-/* ------------------------------------------------------------------ */
-
-static int cx88_pci_quirks(const char *name, struct pci_dev *pci)
-{
- unsigned int lat = UNSET;
- u8 ctrl = 0;
- u8 value;
-
- /* check pci quirks */
- if (pci_pci_problems & PCIPCI_TRITON) {
- printk(KERN_INFO "%s: quirk: PCIPCI_TRITON -- set TBFX\n",
- name);
- ctrl |= CX88X_EN_TBFX;
- }
- if (pci_pci_problems & PCIPCI_NATOMA) {
- printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA -- set TBFX\n",
- name);
- ctrl |= CX88X_EN_TBFX;
- }
- if (pci_pci_problems & PCIPCI_VIAETBF) {
- printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF -- set TBFX\n",
- name);
- ctrl |= CX88X_EN_TBFX;
- }
- if (pci_pci_problems & PCIPCI_VSFX) {
- printk(KERN_INFO "%s: quirk: PCIPCI_VSFX -- set VSFX\n",
- name);
- ctrl |= CX88X_EN_VSFX;
- }
-#ifdef PCIPCI_ALIMAGIK
- if (pci_pci_problems & PCIPCI_ALIMAGIK) {
- printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
- name);
- lat = 0x0A;
- }
-#endif
-
- /* check insmod options */
- if (UNSET != latency)
- lat = latency;
-
- /* apply stuff */
- if (ctrl) {
- pci_read_config_byte(pci, CX88X_DEVCTRL, &value);
- value |= ctrl;
- pci_write_config_byte(pci, CX88X_DEVCTRL, value);
- }
- if (UNSET != lat) {
- printk(KERN_INFO "%s: setting pci latency timer to %d\n",
- name, latency);
- pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency);
- }
- return 0;
-}
-
-int cx88_get_resources(const struct cx88_core *core, struct pci_dev *pci)
-{
- if (request_mem_region(pci_resource_start(pci,0),
- pci_resource_len(pci,0),
- core->name))
- return 0;
- printk(KERN_ERR
- "%s/%d: Can't get MMIO memory @ 0x%llx, subsystem: %04x:%04x\n",
- core->name, PCI_FUNC(pci->devfn),
- (unsigned long long)pci_resource_start(pci, 0),
- pci->subsystem_vendor, pci->subsystem_device);
- return -EBUSY;
-}
-
-/* Allocate and initialize the cx88 core struct. One should hold the
- * devlist mutex before calling this. */
-struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
-{
- struct cx88_core *core;
- int i;
-
- core = kzalloc(sizeof(*core), GFP_KERNEL);
- if (core == NULL)
- return NULL;
-
- atomic_inc(&core->refcount);
- core->pci_bus = pci->bus->number;
- core->pci_slot = PCI_SLOT(pci->devfn);
- core->pci_irqmask = PCI_INT_RISC_RD_BERRINT | PCI_INT_RISC_WR_BERRINT |
- PCI_INT_BRDG_BERRINT | PCI_INT_SRC_DMA_BERRINT |
- PCI_INT_DST_DMA_BERRINT | PCI_INT_IPB_DMA_BERRINT;
- mutex_init(&core->lock);
-
- core->nr = nr;
- sprintf(core->name, "cx88[%d]", core->nr);
-
- strcpy(core->v4l2_dev.name, core->name);
- if (v4l2_device_register(NULL, &core->v4l2_dev)) {
- kfree(core);
- return NULL;
- }
-
- if (v4l2_ctrl_handler_init(&core->video_hdl, 13)) {
- v4l2_device_unregister(&core->v4l2_dev);
- kfree(core);
- return NULL;
- }
-
- if (v4l2_ctrl_handler_init(&core->audio_hdl, 13)) {
- v4l2_ctrl_handler_free(&core->video_hdl);
- v4l2_device_unregister(&core->v4l2_dev);
- kfree(core);
- return NULL;
- }
-
- if (0 != cx88_get_resources(core, pci)) {
- v4l2_ctrl_handler_free(&core->video_hdl);
- v4l2_ctrl_handler_free(&core->audio_hdl);
- v4l2_device_unregister(&core->v4l2_dev);
- kfree(core);
- return NULL;
- }
-
- /* PCI stuff */
- cx88_pci_quirks(core->name, pci);
- core->lmmio = ioremap(pci_resource_start(pci, 0),
- pci_resource_len(pci, 0));
- core->bmmio = (u8 __iomem *)core->lmmio;
-
- if (core->lmmio == NULL) {
- release_mem_region(pci_resource_start(pci, 0),
- pci_resource_len(pci, 0));
- v4l2_ctrl_handler_free(&core->video_hdl);
- v4l2_ctrl_handler_free(&core->audio_hdl);
- v4l2_device_unregister(&core->v4l2_dev);
- kfree(core);
- return NULL;
- }
-
- /* board config */
- core->boardnr = UNSET;
- if (card[core->nr] < ARRAY_SIZE(cx88_boards))
- core->boardnr = card[core->nr];
- for (i = 0; UNSET == core->boardnr && i < ARRAY_SIZE(cx88_subids); i++)
- if (pci->subsystem_vendor == cx88_subids[i].subvendor &&
- pci->subsystem_device == cx88_subids[i].subdevice)
- core->boardnr = cx88_subids[i].card;
- if (UNSET == core->boardnr) {
- core->boardnr = CX88_BOARD_UNKNOWN;
- cx88_card_list(core, pci);
- }
-
- memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board));
-
- if (!core->board.num_frontends && (core->board.mpeg & CX88_MPEG_DVB))
- core->board.num_frontends = 1;
-
- info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s], frontend(s): %d\n",
- pci->subsystem_vendor, pci->subsystem_device, core->board.name,
- core->boardnr, card[core->nr] == core->boardnr ?
- "insmod option" : "autodetected",
- core->board.num_frontends);
-
- if (tuner[core->nr] != UNSET)
- core->board.tuner_type = tuner[core->nr];
- if (radio[core->nr] != UNSET)
- core->board.radio_type = radio[core->nr];
-
- info_printk(core, "TV tuner type %d, Radio tuner type %d\n",
- core->board.tuner_type, core->board.radio_type);
-
- /* init hardware */
- cx88_reset(core);
- cx88_card_setup_pre_i2c(core);
- cx88_i2c_init(core, pci);
-
- /* load tuner module, if needed */
- if (TUNER_ABSENT != core->board.tuner_type) {
- /* Ignore 0x6b and 0x6f on cx88 boards.
- * FusionHDTV5 RT Gold has an ir receiver at 0x6b
- * and an RTC at 0x6f which can get corrupted if probed. */
- static const unsigned short tv_addrs[] = {
- 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x6e,
- I2C_CLIENT_END
- };
- int has_demod = (core->board.tda9887_conf & TDA9887_PRESENT);
-
- /* I don't trust the radio_type as is stored in the card
- definitions, so we just probe for it.
- The radio_type is sometimes missing, or set to UNSET but
- later code configures a tea5767.
- */
- v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
- "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
- if (has_demod)
- v4l2_i2c_new_subdev(&core->v4l2_dev,
- &core->i2c_adap, "tuner",
- 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
- if (core->board.tuner_addr == ADDR_UNSET) {
- v4l2_i2c_new_subdev(&core->v4l2_dev,
- &core->i2c_adap, "tuner",
- 0, has_demod ? tv_addrs + 4 : tv_addrs);
- } else {
- v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
- "tuner", core->board.tuner_addr, NULL);
- }
- }
-
- cx88_card_setup(core);
- if (!disable_ir) {
- cx88_i2c_init_ir(core);
- cx88_ir_init(core, pci);
- }
-
- return core;
-}
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
deleted file mode 100644
index e81c735f012..00000000000
--- a/drivers/media/video/cx88/cx88-core.c
+++ /dev/null
@@ -1,1131 +0,0 @@
-/*
- *
- * device driver for Conexant 2388x based TV cards
- * driver core
- *
- * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
- * - Multituner support
- * - video_ioctl2 conversion
- * - PAL/M fixes
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/kmod.h>
-#include <linux/sound.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include <linux/mutex.h>
-
-#include "cx88.h"
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-
-MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
-MODULE_LICENSE("GPL");
-
-/* ------------------------------------------------------------------ */
-
-static unsigned int core_debug;
-module_param(core_debug,int,0644);
-MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
-
-static unsigned int nicam;
-module_param(nicam,int,0644);
-MODULE_PARM_DESC(nicam,"tv audio is nicam");
-
-static unsigned int nocomb;
-module_param(nocomb,int,0644);
-MODULE_PARM_DESC(nocomb,"disable comb filter");
-
-#define dprintk(level,fmt, arg...) if (core_debug >= level) \
- printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
-
-static unsigned int cx88_devcount;
-static LIST_HEAD(cx88_devlist);
-static DEFINE_MUTEX(devlist);
-
-#define NO_SYNC_LINE (-1U)
-
-/* @lpi: lines per IRQ, or 0 to not generate irqs. Note: IRQ to be
- generated _after_ lpi lines are transferred. */
-static __le32* cx88_risc_field(__le32 *rp, struct scatterlist *sglist,
- unsigned int offset, u32 sync_line,
- unsigned int bpl, unsigned int padding,
- unsigned int lines, unsigned int lpi)
-{
- struct scatterlist *sg;
- unsigned int line,todo,sol;
-
- /* sync instruction */
- if (sync_line != NO_SYNC_LINE)
- *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
-
- /* scan lines */
- sg = sglist;
- for (line = 0; line < lines; line++) {
- while (offset && offset >= sg_dma_len(sg)) {
- offset -= sg_dma_len(sg);
- sg++;
- }
- if (lpi && line>0 && !(line % lpi))
- sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
- else
- sol = RISC_SOL;
- if (bpl <= sg_dma_len(sg)-offset) {
- /* fits into current chunk */
- *(rp++)=cpu_to_le32(RISC_WRITE|sol|RISC_EOL|bpl);
- *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
- offset+=bpl;
- } else {
- /* scanline needs to be split */
- todo = bpl;
- *(rp++)=cpu_to_le32(RISC_WRITE|sol|
- (sg_dma_len(sg)-offset));
- *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
- todo -= (sg_dma_len(sg)-offset);
- offset = 0;
- sg++;
- while (todo > sg_dma_len(sg)) {
- *(rp++)=cpu_to_le32(RISC_WRITE|
- sg_dma_len(sg));
- *(rp++)=cpu_to_le32(sg_dma_address(sg));
- todo -= sg_dma_len(sg);
- sg++;
- }
- *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
- *(rp++)=cpu_to_le32(sg_dma_address(sg));
- offset += todo;
- }
- offset += padding;
- }
-
- return rp;
-}
-
-int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
- struct scatterlist *sglist,
- unsigned int top_offset, unsigned int bottom_offset,
- unsigned int bpl, unsigned int padding, unsigned int lines)
-{
- u32 instructions,fields;
- __le32 *rp;
- int rc;
-
- fields = 0;
- if (UNSET != top_offset)
- fields++;
- if (UNSET != bottom_offset)
- fields++;
-
- /* estimate risc mem: worst case is one write per page border +
- one write per scan line + syncs + jump (all 2 dwords). Padding
- can cause next bpl to start close to a page border. First DMA
- region may be smaller than PAGE_SIZE */
- instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
- instructions += 2;
- if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
- return rc;
-
- /* write risc instructions */
- rp = risc->cpu;
- if (UNSET != top_offset)
- rp = cx88_risc_field(rp, sglist, top_offset, 0,
- bpl, padding, lines, 0);
- if (UNSET != bottom_offset)
- rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200,
- bpl, padding, lines, 0);
-
- /* save pointer to jmp instruction address */
- risc->jmp = rp;
- BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
- return 0;
-}
-
-int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
- struct scatterlist *sglist, unsigned int bpl,
- unsigned int lines, unsigned int lpi)
-{
- u32 instructions;
- __le32 *rp;
- int rc;
-
- /* estimate risc mem: worst case is one write per page border +
- one write per scan line + syncs + jump (all 2 dwords). Here
- there is no padding and no sync. First DMA region may be smaller
- than PAGE_SIZE */
- instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
- instructions += 1;
- if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
- return rc;
-
- /* write risc instructions */
- rp = risc->cpu;
- rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines, lpi);
-
- /* save pointer to jmp instruction address */
- risc->jmp = rp;
- BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
- return 0;
-}
-
-int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
- u32 reg, u32 mask, u32 value)
-{
- __le32 *rp;
- int rc;
-
- if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0)
- return rc;
-
- /* write risc instructions */
- rp = risc->cpu;
- *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2 | RISC_IMM);
- *(rp++) = cpu_to_le32(reg);
- *(rp++) = cpu_to_le32(value);
- *(rp++) = cpu_to_le32(mask);
- *(rp++) = cpu_to_le32(RISC_JUMP);
- *(rp++) = cpu_to_le32(risc->dma);
- return 0;
-}
-
-void
-cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
-{
- struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
-
- BUG_ON(in_interrupt());
- videobuf_waiton(q, &buf->vb, 0, 0);
- videobuf_dma_unmap(q->dev, dma);
- videobuf_dma_free(dma);
- btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-/* ------------------------------------------------------------------ */
-/* our SRAM memory layout */
-
-/* we are going to put all thr risc programs into host memory, so we
- * can use the whole SDRAM for the DMA fifos. To simplify things, we
- * use a static memory layout. That surely will waste memory in case
- * we don't use all DMA channels at the same time (which will be the
- * case most of the time). But that still gives us enough FIFO space
- * to be able to deal with insane long pci latencies ...
- *
- * FIFO space allocations:
- * channel 21 (y video) - 10.0k
- * channel 22 (u video) - 2.0k
- * channel 23 (v video) - 2.0k
- * channel 24 (vbi) - 4.0k
- * channels 25+26 (audio) - 4.0k
- * channel 28 (mpeg) - 4.0k
- * channel 27 (audio rds)- 3.0k
- * TOTAL = 29.0k
- *
- * Every channel has 160 bytes control data (64 bytes instruction
- * queue and 6 CDT entries), which is close to 2k total.
- *
- * Address layout:
- * 0x0000 - 0x03ff CMDs / reserved
- * 0x0400 - 0x0bff instruction queues + CDs
- * 0x0c00 - FIFOs
- */
-
-const struct sram_channel const cx88_sram_channels[] = {
- [SRAM_CH21] = {
- .name = "video y / packed",
- .cmds_start = 0x180040,
- .ctrl_start = 0x180400,
- .cdt = 0x180400 + 64,
- .fifo_start = 0x180c00,
- .fifo_size = 0x002800,
- .ptr1_reg = MO_DMA21_PTR1,
- .ptr2_reg = MO_DMA21_PTR2,
- .cnt1_reg = MO_DMA21_CNT1,
- .cnt2_reg = MO_DMA21_CNT2,
- },
- [SRAM_CH22] = {
- .name = "video u",
- .cmds_start = 0x180080,
- .ctrl_start = 0x1804a0,
- .cdt = 0x1804a0 + 64,
- .fifo_start = 0x183400,
- .fifo_size = 0x000800,
- .ptr1_reg = MO_DMA22_PTR1,
- .ptr2_reg = MO_DMA22_PTR2,
- .cnt1_reg = MO_DMA22_CNT1,
- .cnt2_reg = MO_DMA22_CNT2,
- },
- [SRAM_CH23] = {
- .name = "video v",
- .cmds_start = 0x1800c0,
- .ctrl_start = 0x180540,
- .cdt = 0x180540 + 64,
- .fifo_start = 0x183c00,
- .fifo_size = 0x000800,
- .ptr1_reg = MO_DMA23_PTR1,
- .ptr2_reg = MO_DMA23_PTR2,
- .cnt1_reg = MO_DMA23_CNT1,
- .cnt2_reg = MO_DMA23_CNT2,
- },
- [SRAM_CH24] = {
- .name = "vbi",
- .cmds_start = 0x180100,
- .ctrl_start = 0x1805e0,
- .cdt = 0x1805e0 + 64,
- .fifo_start = 0x184400,
- .fifo_size = 0x001000,
- .ptr1_reg = MO_DMA24_PTR1,
- .ptr2_reg = MO_DMA24_PTR2,
- .cnt1_reg = MO_DMA24_CNT1,
- .cnt2_reg = MO_DMA24_CNT2,
- },
- [SRAM_CH25] = {
- .name = "audio from",
- .cmds_start = 0x180140,
- .ctrl_start = 0x180680,
- .cdt = 0x180680 + 64,
- .fifo_start = 0x185400,
- .fifo_size = 0x001000,
- .ptr1_reg = MO_DMA25_PTR1,
- .ptr2_reg = MO_DMA25_PTR2,
- .cnt1_reg = MO_DMA25_CNT1,
- .cnt2_reg = MO_DMA25_CNT2,
- },
- [SRAM_CH26] = {
- .name = "audio to",
- .cmds_start = 0x180180,
- .ctrl_start = 0x180720,
- .cdt = 0x180680 + 64, /* same as audio IN */
- .fifo_start = 0x185400, /* same as audio IN */
- .fifo_size = 0x001000, /* same as audio IN */
- .ptr1_reg = MO_DMA26_PTR1,
- .ptr2_reg = MO_DMA26_PTR2,
- .cnt1_reg = MO_DMA26_CNT1,
- .cnt2_reg = MO_DMA26_CNT2,
- },
- [SRAM_CH28] = {
- .name = "mpeg",
- .cmds_start = 0x180200,
- .ctrl_start = 0x1807C0,
- .cdt = 0x1807C0 + 64,
- .fifo_start = 0x186400,
- .fifo_size = 0x001000,
- .ptr1_reg = MO_DMA28_PTR1,
- .ptr2_reg = MO_DMA28_PTR2,
- .cnt1_reg = MO_DMA28_CNT1,
- .cnt2_reg = MO_DMA28_CNT2,
- },
- [SRAM_CH27] = {
- .name = "audio rds",
- .cmds_start = 0x1801C0,
- .ctrl_start = 0x180860,
- .cdt = 0x180860 + 64,
- .fifo_start = 0x187400,
- .fifo_size = 0x000C00,
- .ptr1_reg = MO_DMA27_PTR1,
- .ptr2_reg = MO_DMA27_PTR2,
- .cnt1_reg = MO_DMA27_CNT1,
- .cnt2_reg = MO_DMA27_CNT2,
- },
-};
-
-int cx88_sram_channel_setup(struct cx88_core *core,
- const struct sram_channel *ch,
- unsigned int bpl, u32 risc)
-{
- unsigned int i,lines;
- u32 cdt;
-
- bpl = (bpl + 7) & ~7; /* alignment */
- cdt = ch->cdt;
- lines = ch->fifo_size / bpl;
- if (lines > 6)
- lines = 6;
- BUG_ON(lines < 2);
-
- /* write CDT */
- for (i = 0; i < lines; i++)
- cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
-
- /* write CMDS */
- cx_write(ch->cmds_start + 0, risc);
- cx_write(ch->cmds_start + 4, cdt);
- cx_write(ch->cmds_start + 8, (lines*16) >> 3);
- cx_write(ch->cmds_start + 12, ch->ctrl_start);
- cx_write(ch->cmds_start + 16, 64 >> 2);
- for (i = 20; i < 64; i += 4)
- cx_write(ch->cmds_start + i, 0);
-
- /* fill registers */
- cx_write(ch->ptr1_reg, ch->fifo_start);
- cx_write(ch->ptr2_reg, cdt);
- cx_write(ch->cnt1_reg, (bpl >> 3) -1);
- cx_write(ch->cnt2_reg, (lines*16) >> 3);
-
- dprintk(2,"sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-/* debug helper code */
-
-static int cx88_risc_decode(u32 risc)
-{
- static const char * const instr[16] = {
- [ RISC_SYNC >> 28 ] = "sync",
- [ RISC_WRITE >> 28 ] = "write",
- [ RISC_WRITEC >> 28 ] = "writec",
- [ RISC_READ >> 28 ] = "read",
- [ RISC_READC >> 28 ] = "readc",
- [ RISC_JUMP >> 28 ] = "jump",
- [ RISC_SKIP >> 28 ] = "skip",
- [ RISC_WRITERM >> 28 ] = "writerm",
- [ RISC_WRITECM >> 28 ] = "writecm",
- [ RISC_WRITECR >> 28 ] = "writecr",
- };
- static int const incr[16] = {
- [ RISC_WRITE >> 28 ] = 2,
- [ RISC_JUMP >> 28 ] = 2,
- [ RISC_WRITERM >> 28 ] = 3,
- [ RISC_WRITECM >> 28 ] = 3,
- [ RISC_WRITECR >> 28 ] = 4,
- };
- static const char * const bits[] = {
- "12", "13", "14", "resync",
- "cnt0", "cnt1", "18", "19",
- "20", "21", "22", "23",
- "irq1", "irq2", "eol", "sol",
- };
- int i;
-
- printk("0x%08x [ %s", risc,
- instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
- for (i = ARRAY_SIZE(bits)-1; i >= 0; i--)
- if (risc & (1 << (i + 12)))
- printk(" %s",bits[i]);
- printk(" count=%d ]\n", risc & 0xfff);
- return incr[risc >> 28] ? incr[risc >> 28] : 1;
-}
-
-
-void cx88_sram_channel_dump(struct cx88_core *core,
- const struct sram_channel *ch)
-{
- static const char * const name[] = {
- "initial risc",
- "cdt base",
- "cdt size",
- "iq base",
- "iq size",
- "risc pc",
- "iq wr ptr",
- "iq rd ptr",
- "cdt current",
- "pci target",
- "line / byte",
- };
- u32 risc;
- unsigned int i,j,n;
-
- printk("%s: %s - dma channel status dump\n",
- core->name,ch->name);
- for (i = 0; i < ARRAY_SIZE(name); i++)
- printk("%s: cmds: %-12s: 0x%08x\n",
- core->name,name[i],
- cx_read(ch->cmds_start + 4*i));
- for (n = 1, i = 0; i < 4; i++) {
- risc = cx_read(ch->cmds_start + 4 * (i+11));
- printk("%s: risc%d: ", core->name, i);
- if (--n)
- printk("0x%08x [ arg #%d ]\n", risc, n);
- else
- n = cx88_risc_decode(risc);
- }
- for (i = 0; i < 16; i += n) {
- risc = cx_read(ch->ctrl_start + 4 * i);
- printk("%s: iq %x: ", core->name, i);
- n = cx88_risc_decode(risc);
- for (j = 1; j < n; j++) {
- risc = cx_read(ch->ctrl_start + 4 * (i+j));
- printk("%s: iq %x: 0x%08x [ arg #%d ]\n",
- core->name, i+j, risc, j);
- }
- }
-
- printk("%s: fifo: 0x%08x -> 0x%x\n",
- core->name, ch->fifo_start, ch->fifo_start+ch->fifo_size);
- printk("%s: ctrl: 0x%08x -> 0x%x\n",
- core->name, ch->ctrl_start, ch->ctrl_start+6*16);
- printk("%s: ptr1_reg: 0x%08x\n",
- core->name,cx_read(ch->ptr1_reg));
- printk("%s: ptr2_reg: 0x%08x\n",
- core->name,cx_read(ch->ptr2_reg));
- printk("%s: cnt1_reg: 0x%08x\n",
- core->name,cx_read(ch->cnt1_reg));
- printk("%s: cnt2_reg: 0x%08x\n",
- core->name,cx_read(ch->cnt2_reg));
-}
-
-static const char *cx88_pci_irqs[32] = {
- "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",
- "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",
- "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
- "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
-};
-
-void cx88_print_irqbits(const char *name, const char *tag, const char *strings[],
- int len, u32 bits, u32 mask)
-{
- unsigned int i;
-
- printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
- for (i = 0; i < len; i++) {
- if (!(bits & (1 << i)))
- continue;
- if (strings[i])
- printk(" %s", strings[i]);
- else
- printk(" %d", i);
- if (!(mask & (1 << i)))
- continue;
- printk("*");
- }
- printk("\n");
-}
-
-/* ------------------------------------------------------------------ */
-
-int cx88_core_irq(struct cx88_core *core, u32 status)
-{
- int handled = 0;
-
- if (status & PCI_INT_IR_SMPINT) {
- cx88_ir_irq(core);
- handled++;
- }
- if (!handled)
- cx88_print_irqbits(core->name, "irq pci",
- cx88_pci_irqs, ARRAY_SIZE(cx88_pci_irqs),
- status, core->pci_irqmask);
- return handled;
-}
-
-void cx88_wakeup(struct cx88_core *core,
- struct cx88_dmaqueue *q, u32 count)
-{
- struct cx88_buffer *buf;
- int bc;
-
- for (bc = 0;; bc++) {
- if (list_empty(&q->active))
- break;
- buf = list_entry(q->active.next,
- struct cx88_buffer, vb.queue);
- /* count comes from the hw and is is 16bit wide --
- * this trick handles wrap-arounds correctly for
- * up to 32767 buffers in flight... */
- if ((s16) (count - buf->count) < 0)
- break;
- do_gettimeofday(&buf->vb.ts);
- dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i,
- count, buf->count);
- buf->vb.state = VIDEOBUF_DONE;
- list_del(&buf->vb.queue);
- wake_up(&buf->vb.done);
- }
- if (list_empty(&q->active)) {
- del_timer(&q->timeout);
- } else {
- mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- }
- if (bc != 1)
- dprintk(2, "%s: %d buffers handled (should be 1)\n",
- __func__, bc);
-}
-
-void cx88_shutdown(struct cx88_core *core)
-{
- /* disable RISC controller + IRQs */
- cx_write(MO_DEV_CNTRL2, 0);
-
- /* stop dma transfers */
- cx_write(MO_VID_DMACNTRL, 0x0);
- cx_write(MO_AUD_DMACNTRL, 0x0);
- cx_write(MO_TS_DMACNTRL, 0x0);
- cx_write(MO_VIP_DMACNTRL, 0x0);
- cx_write(MO_GPHST_DMACNTRL, 0x0);
-
- /* stop interrupts */
- cx_write(MO_PCI_INTMSK, 0x0);
- cx_write(MO_VID_INTMSK, 0x0);
- cx_write(MO_AUD_INTMSK, 0x0);
- cx_write(MO_TS_INTMSK, 0x0);
- cx_write(MO_VIP_INTMSK, 0x0);
- cx_write(MO_GPHST_INTMSK, 0x0);
-
- /* stop capturing */
- cx_write(VID_CAPTURE_CONTROL, 0);
-}
-
-int cx88_reset(struct cx88_core *core)
-{
- dprintk(1,"%s\n",__func__);
- cx88_shutdown(core);
-
- /* clear irq status */
- cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
- cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
- cx_write(MO_INT1_STAT, 0xFFFFFFFF); // Clear RISC int
-
- /* wait a bit */
- msleep(100);
-
- /* init sram */
- cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], 720*4, 0);
- cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0);
- cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0);
- cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0);
- cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
- cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
- cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0);
- cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], 128, 0);
-
- /* misc init ... */
- cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable
- (1 << 12) | // agc gain
- (1 << 11) | // adaptibe agc
- (0 << 10) | // chroma agc
- (0 << 9) | // ckillen
- (7)));
-
- /* setup image format */
- cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
-
- /* setup FIFO Thresholds */
- cx_write(MO_PDMA_STHRSH, 0x0807);
- cx_write(MO_PDMA_DTHRSH, 0x0807);
-
- /* fixes flashing of image */
- cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
- cx_write(MO_AGC_BACK_VBI, 0x00E00555);
-
- cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
- cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
- cx_write(MO_INT1_STAT, 0xFFFFFFFF); // Clear RISC int
-
- /* Reset on-board parts */
- cx_write(MO_SRST_IO, 0);
- msleep(10);
- cx_write(MO_SRST_IO, 1);
-
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static unsigned int inline norm_swidth(v4l2_std_id norm)
-{
- return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
-}
-
-static unsigned int inline norm_hdelay(v4l2_std_id norm)
-{
- return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186;
-}
-
-static unsigned int inline norm_vdelay(v4l2_std_id norm)
-{
- return (norm & V4L2_STD_625_50) ? 0x24 : 0x18;
-}
-
-static unsigned int inline norm_fsc8(v4l2_std_id norm)
-{
- if (norm & V4L2_STD_PAL_M)
- return 28604892; // 3.575611 MHz
-
- if (norm & (V4L2_STD_PAL_Nc))
- return 28656448; // 3.582056 MHz
-
- if (norm & V4L2_STD_NTSC) // All NTSC/M and variants
- return 28636360; // 3.57954545 MHz +/- 10 Hz
-
- /* SECAM have also different sub carrier for chroma,
- but step_db and step_dr, at cx88_set_tvnorm already handles that.
-
- The same FSC applies to PAL/BGDKIH, PAL/60, NTSC/4.43 and PAL/N
- */
-
- return 35468950; // 4.43361875 MHz +/- 5 Hz
-}
-
-static unsigned int inline norm_htotal(v4l2_std_id norm)
-{
-
- unsigned int fsc4=norm_fsc8(norm)/2;
-
- /* returns 4*FSC / vtotal / frames per seconds */
- return (norm & V4L2_STD_625_50) ?
- ((fsc4+312)/625+12)/25 :
- ((fsc4+262)/525*1001+15000)/30000;
-}
-
-static unsigned int inline norm_vbipack(v4l2_std_id norm)
-{
- return (norm & V4L2_STD_625_50) ? 511 : 400;
-}
-
-int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height,
- enum v4l2_field field)
-{
- unsigned int swidth = norm_swidth(core->tvnorm);
- unsigned int sheight = norm_maxh(core->tvnorm);
- u32 value;
-
- dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height,
- V4L2_FIELD_HAS_TOP(field) ? "T" : "",
- V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
- v4l2_norm_to_name(core->tvnorm));
- if (!V4L2_FIELD_HAS_BOTH(field))
- height *= 2;
-
- // recalc H delay and scale registers
- value = (width * norm_hdelay(core->tvnorm)) / swidth;
- value &= 0x3fe;
- cx_write(MO_HDELAY_EVEN, value);
- cx_write(MO_HDELAY_ODD, value);
- dprintk(1,"set_scale: hdelay 0x%04x (width %d)\n", value,swidth);
-
- value = (swidth * 4096 / width) - 4096;
- cx_write(MO_HSCALE_EVEN, value);
- cx_write(MO_HSCALE_ODD, value);
- dprintk(1,"set_scale: hscale 0x%04x\n", value);
-
- cx_write(MO_HACTIVE_EVEN, width);
- cx_write(MO_HACTIVE_ODD, width);
- dprintk(1,"set_scale: hactive 0x%04x\n", width);
-
- // recalc V scale Register (delay is constant)
- cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));
- cx_write(MO_VDELAY_ODD, norm_vdelay(core->tvnorm));
- dprintk(1,"set_scale: vdelay 0x%04x\n", norm_vdelay(core->tvnorm));
-
- value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;
- cx_write(MO_VSCALE_EVEN, value);
- cx_write(MO_VSCALE_ODD, value);
- dprintk(1,"set_scale: vscale 0x%04x\n", value);
-
- cx_write(MO_VACTIVE_EVEN, sheight);
- cx_write(MO_VACTIVE_ODD, sheight);
- dprintk(1,"set_scale: vactive 0x%04x\n", sheight);
-
- // setup filters
- value = 0;
- value |= (1 << 19); // CFILT (default)
- if (core->tvnorm & V4L2_STD_SECAM) {
- value |= (1 << 15);
- value |= (1 << 16);
- }
- if (INPUT(core->input).type == CX88_VMUX_SVIDEO)
- value |= (1 << 13) | (1 << 5);
- if (V4L2_FIELD_INTERLACED == field)
- value |= (1 << 3); // VINT (interlaced vertical scaling)
- if (width < 385)
- value |= (1 << 0); // 3-tap interpolation
- if (width < 193)
- value |= (1 << 1); // 5-tap interpolation
- if (nocomb)
- value |= (3 << 5); // disable comb filter
-
- cx_andor(MO_FILTER_EVEN, 0x7ffc7f, value); /* preserve PEAKEN, PSEL */
- cx_andor(MO_FILTER_ODD, 0x7ffc7f, value);
- dprintk(1,"set_scale: filter 0x%04x\n", value);
-
- return 0;
-}
-
-static const u32 xtal = 28636363;
-
-static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
-{
- static const u32 pre[] = { 0, 0, 0, 3, 2, 1 };
- u64 pll;
- u32 reg;
- int i;
-
- if (prescale < 2)
- prescale = 2;
- if (prescale > 5)
- prescale = 5;
-
- pll = ofreq * 8 * prescale * (u64)(1 << 20);
- do_div(pll,xtal);
- reg = (pll & 0x3ffffff) | (pre[prescale] << 26);
- if (((reg >> 20) & 0x3f) < 14) {
- printk("%s/0: pll out of range\n",core->name);
- return -1;
- }
-
- dprintk(1,"set_pll: MO_PLL_REG 0x%08x [old=0x%08x,freq=%d]\n",
- reg, cx_read(MO_PLL_REG), ofreq);
- cx_write(MO_PLL_REG, reg);
- for (i = 0; i < 100; i++) {
- reg = cx_read(MO_DEVICE_STATUS);
- if (reg & (1<<2)) {
- dprintk(1,"pll locked [pre=%d,ofreq=%d]\n",
- prescale,ofreq);
- return 0;
- }
- dprintk(1,"pll not locked yet, waiting ...\n");
- msleep(10);
- }
- dprintk(1,"pll NOT locked [pre=%d,ofreq=%d]\n",prescale,ofreq);
- return -1;
-}
-
-int cx88_start_audio_dma(struct cx88_core *core)
-{
- /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
- int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4;
-
- int rds_bpl = cx88_sram_channels[SRAM_CH27].fifo_size/AUD_RDS_LINES;
-
- /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
- if (cx_read(MO_AUD_DMACNTRL) & 0x10)
- return 0;
-
- /* setup fifo + format */
- cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
- cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
- cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27],
- rds_bpl, 0);
-
- cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
- cx_write(MO_AUDR_LNGTH, rds_bpl); /* fifo bpl size */
-
- /* enable Up, Down and Audio RDS fifo */
- cx_write(MO_AUD_DMACNTRL, 0x0007);
-
- return 0;
-}
-
-int cx88_stop_audio_dma(struct cx88_core *core)
-{
- /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
- if (cx_read(MO_AUD_DMACNTRL) & 0x10)
- return 0;
-
- /* stop dma */
- cx_write(MO_AUD_DMACNTRL, 0x0000);
-
- return 0;
-}
-
-static int set_tvaudio(struct cx88_core *core)
-{
- v4l2_std_id norm = core->tvnorm;
-
- if (CX88_VMUX_TELEVISION != INPUT(core->input).type &&
- CX88_VMUX_CABLE != INPUT(core->input).type)
- return 0;
-
- if (V4L2_STD_PAL_BG & norm) {
- core->tvaudio = WW_BG;
-
- } else if (V4L2_STD_PAL_DK & norm) {
- core->tvaudio = WW_DK;
-
- } else if (V4L2_STD_PAL_I & norm) {
- core->tvaudio = WW_I;
-
- } else if (V4L2_STD_SECAM_L & norm) {
- core->tvaudio = WW_L;
-
- } else if ((V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H) & norm) {
- core->tvaudio = WW_BG;
-
- } else if (V4L2_STD_SECAM_DK & norm) {
- core->tvaudio = WW_DK;
-
- } else if ((V4L2_STD_NTSC_M & norm) ||
- (V4L2_STD_PAL_M & norm)) {
- core->tvaudio = WW_BTSC;
-
- } else if (V4L2_STD_NTSC_M_JP & norm) {
- core->tvaudio = WW_EIAJ;
-
- } else {
- printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n",
- core->name, v4l2_norm_to_name(core->tvnorm));
- core->tvaudio = WW_NONE;
- return 0;
- }
-
- cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
- cx88_set_tvaudio(core);
- /* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */
-
-/*
- This should be needed only on cx88-alsa. It seems that some cx88 chips have
- bugs and does require DMA enabled for it to work.
- */
- cx88_start_audio_dma(core);
- return 0;
-}
-
-
-
-int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
-{
- u32 fsc8;
- u32 adc_clock;
- u32 vdec_clock;
- u32 step_db,step_dr;
- u64 tmp64;
- u32 bdelay,agcdelay,htotal;
- u32 cxiformat, cxoformat;
-
- core->tvnorm = norm;
- fsc8 = norm_fsc8(norm);
- adc_clock = xtal;
- vdec_clock = fsc8;
- step_db = fsc8;
- step_dr = fsc8;
-
- if (norm & V4L2_STD_NTSC_M_JP) {
- cxiformat = VideoFormatNTSCJapan;
- cxoformat = 0x181f0008;
- } else if (norm & V4L2_STD_NTSC_443) {
- cxiformat = VideoFormatNTSC443;
- cxoformat = 0x181f0008;
- } else if (norm & V4L2_STD_PAL_M) {
- cxiformat = VideoFormatPALM;
- cxoformat = 0x1c1f0008;
- } else if (norm & V4L2_STD_PAL_N) {
- cxiformat = VideoFormatPALN;
- cxoformat = 0x1c1f0008;
- } else if (norm & V4L2_STD_PAL_Nc) {
- cxiformat = VideoFormatPALNC;
- cxoformat = 0x1c1f0008;
- } else if (norm & V4L2_STD_PAL_60) {
- cxiformat = VideoFormatPAL60;
- cxoformat = 0x181f0008;
- } else if (norm & V4L2_STD_NTSC) {
- cxiformat = VideoFormatNTSC;
- cxoformat = 0x181f0008;
- } else if (norm & V4L2_STD_SECAM) {
- step_db = 4250000 * 8;
- step_dr = 4406250 * 8;
-
- cxiformat = VideoFormatSECAM;
- cxoformat = 0x181f0008;
- } else { /* PAL */
- cxiformat = VideoFormatPAL;
- cxoformat = 0x181f0008;
- }
-
- dprintk(1,"set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
- v4l2_norm_to_name(core->tvnorm), fsc8, adc_clock, vdec_clock,
- step_db, step_dr);
- set_pll(core,2,vdec_clock);
-
- dprintk(1,"set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n",
- cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
- /* Chroma AGC must be disabled if SECAM is used, we enable it
- by default on PAL and NTSC */
- cx_andor(MO_INPUT_FORMAT, 0x40f,
- norm & V4L2_STD_SECAM ? cxiformat : cxiformat | 0x400);
-
- // FIXME: as-is from DScaler
- dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
- cxoformat, cx_read(MO_OUTPUT_FORMAT));
- cx_write(MO_OUTPUT_FORMAT, cxoformat);
-
- // MO_SCONV_REG = adc clock / video dec clock * 2^17
- tmp64 = adc_clock * (u64)(1 << 17);
- do_div(tmp64, vdec_clock);
- dprintk(1,"set_tvnorm: MO_SCONV_REG 0x%08x [old=0x%08x]\n",
- (u32)tmp64, cx_read(MO_SCONV_REG));
- cx_write(MO_SCONV_REG, (u32)tmp64);
-
- // MO_SUB_STEP = 8 * fsc / video dec clock * 2^22
- tmp64 = step_db * (u64)(1 << 22);
- do_div(tmp64, vdec_clock);
- dprintk(1,"set_tvnorm: MO_SUB_STEP 0x%08x [old=0x%08x]\n",
- (u32)tmp64, cx_read(MO_SUB_STEP));
- cx_write(MO_SUB_STEP, (u32)tmp64);
-
- // MO_SUB_STEP_DR = 8 * 4406250 / video dec clock * 2^22
- tmp64 = step_dr * (u64)(1 << 22);
- do_div(tmp64, vdec_clock);
- dprintk(1,"set_tvnorm: MO_SUB_STEP_DR 0x%08x [old=0x%08x]\n",
- (u32)tmp64, cx_read(MO_SUB_STEP_DR));
- cx_write(MO_SUB_STEP_DR, (u32)tmp64);
-
- // bdelay + agcdelay
- bdelay = vdec_clock * 65 / 20000000 + 21;
- agcdelay = vdec_clock * 68 / 20000000 + 15;
- dprintk(1,"set_tvnorm: MO_AGC_BURST 0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n",
- (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST), bdelay, agcdelay);
- cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay);
-
- // htotal
- tmp64 = norm_htotal(norm) * (u64)vdec_clock;
- do_div(tmp64, fsc8);
- htotal = (u32)tmp64;
- dprintk(1,"set_tvnorm: MO_HTOTAL 0x%08x [old=0x%08x,htotal=%d]\n",
- htotal, cx_read(MO_HTOTAL), (u32)tmp64);
- cx_andor(MO_HTOTAL, 0x07ff, htotal);
-
- // vbi stuff, set vbi offset to 10 (for 20 Clk*2 pixels), this makes
- // the effective vbi offset ~244 samples, the same as the Bt8x8
- cx_write(MO_VBI_PACKET, (10<<11) | norm_vbipack(norm));
-
- // this is needed as well to set all tvnorm parameter
- cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
-
- // audio
- set_tvaudio(core);
-
- // tell i2c chips
- call_all(core, core, s_std, norm);
-
- /* The chroma_agc control should be inaccessible if the video format is SECAM */
- v4l2_ctrl_grab(core->chroma_agc, cxiformat == VideoFormatSECAM);
-
- // done
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-struct video_device *cx88_vdev_init(struct cx88_core *core,
- struct pci_dev *pci,
- const struct video_device *template_,
- const char *type)
-{
- struct video_device *vfd;
-
- vfd = video_device_alloc();
- if (NULL == vfd)
- return NULL;
- *vfd = *template_;
- vfd->v4l2_dev = &core->v4l2_dev;
- vfd->release = video_device_release;
- snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
- core->name, type, core->board.name);
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
- return vfd;
-}
-
-struct cx88_core* cx88_core_get(struct pci_dev *pci)
-{
- struct cx88_core *core;
-
- mutex_lock(&devlist);
- list_for_each_entry(core, &cx88_devlist, devlist) {
- if (pci->bus->number != core->pci_bus)
- continue;
- if (PCI_SLOT(pci->devfn) != core->pci_slot)
- continue;
-
- if (0 != cx88_get_resources(core, pci)) {
- mutex_unlock(&devlist);
- return NULL;
- }
- atomic_inc(&core->refcount);
- mutex_unlock(&devlist);
- return core;
- }
-
- core = cx88_core_create(pci, cx88_devcount);
- if (NULL != core) {
- cx88_devcount++;
- list_add_tail(&core->devlist, &cx88_devlist);
- }
-
- mutex_unlock(&devlist);
- return core;
-}
-
-void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
-{
- release_mem_region(pci_resource_start(pci,0),
- pci_resource_len(pci,0));
-
- if (!atomic_dec_and_test(&core->refcount))
- return;
-
- mutex_lock(&devlist);
- cx88_ir_fini(core);
- if (0 == core->i2c_rc) {
- if (core->i2c_rtc)
- i2c_unregister_device(core->i2c_rtc);
- i2c_del_adapter(&core->i2c_adap);
- }
- list_del(&core->devlist);
- iounmap(core->lmmio);
- cx88_devcount--;
- mutex_unlock(&devlist);
- v4l2_ctrl_handler_free(&core->video_hdl);
- v4l2_ctrl_handler_free(&core->audio_hdl);
- v4l2_device_unregister(&core->v4l2_dev);
- kfree(core);
-}
-
-/* ------------------------------------------------------------------ */
-
-EXPORT_SYMBOL(cx88_print_irqbits);
-
-EXPORT_SYMBOL(cx88_core_irq);
-EXPORT_SYMBOL(cx88_wakeup);
-EXPORT_SYMBOL(cx88_reset);
-EXPORT_SYMBOL(cx88_shutdown);
-
-EXPORT_SYMBOL(cx88_risc_buffer);
-EXPORT_SYMBOL(cx88_risc_databuffer);
-EXPORT_SYMBOL(cx88_risc_stopper);
-EXPORT_SYMBOL(cx88_free_buffer);
-
-EXPORT_SYMBOL(cx88_sram_channels);
-EXPORT_SYMBOL(cx88_sram_channel_setup);
-EXPORT_SYMBOL(cx88_sram_channel_dump);
-
-EXPORT_SYMBOL(cx88_set_tvnorm);
-EXPORT_SYMBOL(cx88_set_scale);
-
-EXPORT_SYMBOL(cx88_vdev_init);
-EXPORT_SYMBOL(cx88_core_get);
-EXPORT_SYMBOL(cx88_core_put);
-
-EXPORT_SYMBOL(cx88_ir_start);
-EXPORT_SYMBOL(cx88_ir_stop);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
- */
diff --git a/drivers/media/video/cx88/cx88-dsp.c b/drivers/media/video/cx88/cx88-dsp.c
deleted file mode 100644
index a9907265ff6..00000000000
--- a/drivers/media/video/cx88/cx88-dsp.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- *
- * Stereo and SAP detection for cx88
- *
- * Copyright (c) 2009 Marton Balint <cus@fazekas.hu>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/jiffies.h>
-#include <asm/div64.h>
-
-#include "cx88.h"
-#include "cx88-reg.h"
-
-#define INT_PI ((s32)(3.141592653589 * 32768.0))
-
-#define compat_remainder(a, b) \
- ((float)(((s32)((a)*100))%((s32)((b)*100)))/100.0)
-
-#define baseband_freq(carrier, srate, tone) ((s32)( \
- (compat_remainder(carrier + tone, srate)) / srate * 2 * INT_PI))
-
-/* We calculate the baseband frequencies of the carrier and the pilot tones
- * based on the the sampling rate of the audio rds fifo. */
-
-#define FREQ_A2_CARRIER baseband_freq(54687.5, 2689.36, 0.0)
-#define FREQ_A2_DUAL baseband_freq(54687.5, 2689.36, 274.1)
-#define FREQ_A2_STEREO baseband_freq(54687.5, 2689.36, 117.5)
-
-/* The frequencies below are from the reference driver. They probably need
- * further adjustments, because they are not tested at all. You may even need
- * to play a bit with the registers of the chip to select the proper signal
- * for the input of the audio rds fifo, and measure it's sampling rate to
- * calculate the proper baseband frequencies... */
-
-#define FREQ_A2M_CARRIER ((s32)(2.114516 * 32768.0))
-#define FREQ_A2M_DUAL ((s32)(2.754916 * 32768.0))
-#define FREQ_A2M_STEREO ((s32)(2.462326 * 32768.0))
-
-#define FREQ_EIAJ_CARRIER ((s32)(1.963495 * 32768.0)) /* 5pi/8 */
-#define FREQ_EIAJ_DUAL ((s32)(2.562118 * 32768.0))
-#define FREQ_EIAJ_STEREO ((s32)(2.601053 * 32768.0))
-
-#define FREQ_BTSC_DUAL ((s32)(1.963495 * 32768.0)) /* 5pi/8 */
-#define FREQ_BTSC_DUAL_REF ((s32)(1.374446 * 32768.0)) /* 7pi/16 */
-
-#define FREQ_BTSC_SAP ((s32)(2.471532 * 32768.0))
-#define FREQ_BTSC_SAP_REF ((s32)(1.730072 * 32768.0))
-
-/* The spectrum of the signal should be empty between these frequencies. */
-#define FREQ_NOISE_START ((s32)(0.100000 * 32768.0))
-#define FREQ_NOISE_END ((s32)(1.200000 * 32768.0))
-
-static unsigned int dsp_debug;
-module_param(dsp_debug, int, 0644);
-MODULE_PARM_DESC(dsp_debug, "enable audio dsp debug messages");
-
-#define dprintk(level, fmt, arg...) if (dsp_debug >= level) \
- printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
-
-static s32 int_cos(u32 x)
-{
- u32 t2, t4, t6, t8;
- s32 ret;
- u16 period = x / INT_PI;
- if (period % 2)
- return -int_cos(x - INT_PI);
- x = x % INT_PI;
- if (x > INT_PI/2)
- return -int_cos(INT_PI/2 - (x % (INT_PI/2)));
- /* Now x is between 0 and INT_PI/2.
- * To calculate cos(x) we use it's Taylor polinom. */
- t2 = x*x/32768/2;
- t4 = t2*x/32768*x/32768/3/4;
- t6 = t4*x/32768*x/32768/5/6;
- t8 = t6*x/32768*x/32768/7/8;
- ret = 32768-t2+t4-t6+t8;
- return ret;
-}
-
-static u32 int_goertzel(s16 x[], u32 N, u32 freq)
-{
- /* We use the Goertzel algorithm to determine the power of the
- * given frequency in the signal */
- s32 s_prev = 0;
- s32 s_prev2 = 0;
- s32 coeff = 2*int_cos(freq);
- u32 i;
-
- u64 tmp;
- u32 divisor;
-
- for (i = 0; i < N; i++) {
- s32 s = x[i] + ((s64)coeff*s_prev/32768) - s_prev2;
- s_prev2 = s_prev;
- s_prev = s;
- }
-
- tmp = (s64)s_prev2 * s_prev2 + (s64)s_prev * s_prev -
- (s64)coeff * s_prev2 * s_prev / 32768;
-
- /* XXX: N must be low enough so that N*N fits in s32.
- * Else we need two divisions. */
- divisor = N * N;
- do_div(tmp, divisor);
-
- return (u32) tmp;
-}
-
-static u32 freq_magnitude(s16 x[], u32 N, u32 freq)
-{
- u32 sum = int_goertzel(x, N, freq);
- return (u32)int_sqrt(sum);
-}
-
-static u32 noise_magnitude(s16 x[], u32 N, u32 freq_start, u32 freq_end)
-{
- int i;
- u32 sum = 0;
- u32 freq_step;
- int samples = 5;
-
- if (N > 192) {
- /* The last 192 samples are enough for noise detection */
- x += (N-192);
- N = 192;
- }
-
- freq_step = (freq_end - freq_start) / (samples - 1);
-
- for (i = 0; i < samples; i++) {
- sum += int_goertzel(x, N, freq_start);
- freq_start += freq_step;
- }
-
- return (u32)int_sqrt(sum / samples);
-}
-
-static s32 detect_a2_a2m_eiaj(struct cx88_core *core, s16 x[], u32 N)
-{
- s32 carrier, stereo, dual, noise;
- s32 carrier_freq, stereo_freq, dual_freq;
- s32 ret;
-
- switch (core->tvaudio) {
- case WW_BG:
- case WW_DK:
- carrier_freq = FREQ_A2_CARRIER;
- stereo_freq = FREQ_A2_STEREO;
- dual_freq = FREQ_A2_DUAL;
- break;
- case WW_M:
- carrier_freq = FREQ_A2M_CARRIER;
- stereo_freq = FREQ_A2M_STEREO;
- dual_freq = FREQ_A2M_DUAL;
- break;
- case WW_EIAJ:
- carrier_freq = FREQ_EIAJ_CARRIER;
- stereo_freq = FREQ_EIAJ_STEREO;
- dual_freq = FREQ_EIAJ_DUAL;
- break;
- default:
- printk(KERN_WARNING "%s/0: unsupported audio mode %d for %s\n",
- core->name, core->tvaudio, __func__);
- return UNSET;
- }
-
- carrier = freq_magnitude(x, N, carrier_freq);
- stereo = freq_magnitude(x, N, stereo_freq);
- dual = freq_magnitude(x, N, dual_freq);
- noise = noise_magnitude(x, N, FREQ_NOISE_START, FREQ_NOISE_END);
-
- dprintk(1, "detect a2/a2m/eiaj: carrier=%d, stereo=%d, dual=%d, "
- "noise=%d\n", carrier, stereo, dual, noise);
-
- if (stereo > dual)
- ret = V4L2_TUNER_SUB_STEREO;
- else
- ret = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
-
- if (core->tvaudio == WW_EIAJ) {
- /* EIAJ checks may need adjustments */
- if ((carrier > max(stereo, dual)*2) &&
- (carrier < max(stereo, dual)*6) &&
- (carrier > 20 && carrier < 200) &&
- (max(stereo, dual) > min(stereo, dual))) {
- /* For EIAJ the carrier is always present,
- so we probably don't need noise detection */
- return ret;
- }
- } else {
- if ((carrier > max(stereo, dual)*2) &&
- (carrier < max(stereo, dual)*8) &&
- (carrier > 20 && carrier < 200) &&
- (noise < 10) &&
- (max(stereo, dual) > min(stereo, dual)*2)) {
- return ret;
- }
- }
- return V4L2_TUNER_SUB_MONO;
-}
-
-static s32 detect_btsc(struct cx88_core *core, s16 x[], u32 N)
-{
- s32 sap_ref = freq_magnitude(x, N, FREQ_BTSC_SAP_REF);
- s32 sap = freq_magnitude(x, N, FREQ_BTSC_SAP);
- s32 dual_ref = freq_magnitude(x, N, FREQ_BTSC_DUAL_REF);
- s32 dual = freq_magnitude(x, N, FREQ_BTSC_DUAL);
- dprintk(1, "detect btsc: dual_ref=%d, dual=%d, sap_ref=%d, sap=%d"
- "\n", dual_ref, dual, sap_ref, sap);
- /* FIXME: Currently not supported */
- return UNSET;
-}
-
-static s16 *read_rds_samples(struct cx88_core *core, u32 *N)
-{
- const struct sram_channel *srch = &cx88_sram_channels[SRAM_CH27];
- s16 *samples;
-
- unsigned int i;
- unsigned int bpl = srch->fifo_size/AUD_RDS_LINES;
- unsigned int spl = bpl/4;
- unsigned int sample_count = spl*(AUD_RDS_LINES-1);
-
- u32 current_address = cx_read(srch->ptr1_reg);
- u32 offset = (current_address - srch->fifo_start + bpl);
-
- dprintk(1, "read RDS samples: current_address=%08x (offset=%08x), "
- "sample_count=%d, aud_intstat=%08x\n", current_address,
- current_address - srch->fifo_start, sample_count,
- cx_read(MO_AUD_INTSTAT));
-
- samples = kmalloc(sizeof(s16)*sample_count, GFP_KERNEL);
- if (!samples)
- return NULL;
-
- *N = sample_count;
-
- for (i = 0; i < sample_count; i++) {
- offset = offset % (AUD_RDS_LINES*bpl);
- samples[i] = cx_read(srch->fifo_start + offset);
- offset += 4;
- }
-
- if (dsp_debug >= 2) {
- dprintk(2, "RDS samples dump: ");
- for (i = 0; i < sample_count; i++)
- printk("%hd ", samples[i]);
- printk(".\n");
- }
-
- return samples;
-}
-
-s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core)
-{
- s16 *samples;
- u32 N = 0;
- s32 ret = UNSET;
-
- /* If audio RDS fifo is disabled, we can't read the samples */
- if (!(cx_read(MO_AUD_DMACNTRL) & 0x04))
- return ret;
- if (!(cx_read(AUD_CTL) & EN_FMRADIO_EN_RDS))
- return ret;
-
- /* Wait at least 500 ms after an audio standard change */
- if (time_before(jiffies, core->last_change + msecs_to_jiffies(500)))
- return ret;
-
- samples = read_rds_samples(core, &N);
-
- if (!samples)
- return ret;
-
- switch (core->tvaudio) {
- case WW_BG:
- case WW_DK:
- case WW_EIAJ:
- case WW_M:
- ret = detect_a2_a2m_eiaj(core, samples, N);
- break;
- case WW_BTSC:
- ret = detect_btsc(core, samples, N);
- break;
- case WW_NONE:
- case WW_I:
- case WW_L:
- case WW_I2SPT:
- case WW_FM:
- case WW_I2SADC:
- break;
- }
-
- kfree(samples);
-
- if (UNSET != ret)
- dprintk(1, "stereo/sap detection result:%s%s%s\n",
- (ret & V4L2_TUNER_SUB_MONO) ? " mono" : "",
- (ret & V4L2_TUNER_SUB_STEREO) ? " stereo" : "",
- (ret & V4L2_TUNER_SUB_LANG2) ? " dual" : "");
-
- return ret;
-}
-EXPORT_SYMBOL(cx88_dsp_detect_stereo_sap);
-
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
deleted file mode 100644
index 003937cd72f..00000000000
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ /dev/null
@@ -1,1778 +0,0 @@
-/*
- *
- * device driver for Conexant 2388x based TV cards
- * MPEG Transport Stream (DVB) routines
- *
- * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
- * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/fs.h>
-#include <linux/kthread.h>
-#include <linux/file.h>
-#include <linux/suspend.h>
-
-#include "cx88.h"
-#include "dvb-pll.h"
-#include <media/v4l2-common.h>
-
-#include "mt352.h"
-#include "mt352_priv.h"
-#include "cx88-vp3054-i2c.h"
-#include "zl10353.h"
-#include "cx22702.h"
-#include "or51132.h"
-#include "lgdt330x.h"
-#include "s5h1409.h"
-#include "xc4000.h"
-#include "xc5000.h"
-#include "nxt200x.h"
-#include "cx24123.h"
-#include "isl6421.h"
-#include "tuner-simple.h"
-#include "tda9887.h"
-#include "s5h1411.h"
-#include "stv0299.h"
-#include "z0194a.h"
-#include "stv0288.h"
-#include "stb6000.h"
-#include "cx24116.h"
-#include "stv0900.h"
-#include "stb6100.h"
-#include "stb6100_proc.h"
-#include "mb86a16.h"
-#include "ds3000.h"
-
-MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
-MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(CX88_VERSION);
-
-static unsigned int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
-
-static unsigned int dvb_buf_tscnt = 32;
-module_param(dvb_buf_tscnt, int, 0644);
-MODULE_PARM_DESC(dvb_buf_tscnt, "DVB Buffer TS count [dvb]");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define dprintk(level,fmt, arg...) if (debug >= level) \
- printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg)
-
-/* ------------------------------------------------------------------ */
-
-static int dvb_buf_setup(struct videobuf_queue *q,
- unsigned int *count, unsigned int *size)
-{
- struct cx8802_dev *dev = q->priv_data;
-
- dev->ts_packet_size = 188 * 4;
- dev->ts_packet_count = dvb_buf_tscnt;
-
- *size = dev->ts_packet_size * dev->ts_packet_count;
- *count = dvb_buf_tscnt;
- return 0;
-}
-
-static int dvb_buf_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb, enum v4l2_field field)
-{
- struct cx8802_dev *dev = q->priv_data;
- return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
-}
-
-static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct cx8802_dev *dev = q->priv_data;
- cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
-}
-
-static void dvb_buf_release(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- cx88_free_buffer(q, (struct cx88_buffer*)vb);
-}
-
-static const struct videobuf_queue_ops dvb_qops = {
- .buf_setup = dvb_buf_setup,
- .buf_prepare = dvb_buf_prepare,
- .buf_queue = dvb_buf_queue,
- .buf_release = dvb_buf_release,
-};
-
-/* ------------------------------------------------------------------ */
-
-static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
-{
- struct cx8802_dev *dev= fe->dvb->priv;
- struct cx8802_driver *drv = NULL;
- int ret = 0;
- int fe_id;
-
- fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe);
- if (!fe_id) {
- printk(KERN_ERR "%s() No frontend found\n", __func__);
- return -EINVAL;
- }
-
- mutex_lock(&dev->core->lock);
- drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
- if (drv) {
- if (acquire){
- dev->frontends.active_fe_id = fe_id;
- ret = drv->request_acquire(drv);
- } else {
- ret = drv->request_release(drv);
- dev->frontends.active_fe_id = 0;
- }
- }
- mutex_unlock(&dev->core->lock);
-
- return ret;
-}
-
-static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open)
-{
- struct videobuf_dvb_frontends *f;
- struct videobuf_dvb_frontend *fe;
-
- if (!core->dvbdev)
- return;
-
- f = &core->dvbdev->frontends;
-
- if (!f)
- return;
-
- if (f->gate <= 1) /* undefined or fe0 */
- fe = videobuf_dvb_get_frontend(f, 1);
- else
- fe = videobuf_dvb_get_frontend(f, f->gate);
-
- if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
- fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
-}
-
-/* ------------------------------------------------------------------ */
-
-static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
-{
- static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
- static const u8 reset [] = { RESET, 0x80 };
- static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
- static const u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
- static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
- static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
-
- mt352_write(fe, clock_config, sizeof(clock_config));
- udelay(200);
- mt352_write(fe, reset, sizeof(reset));
- mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
-
- mt352_write(fe, agc_cfg, sizeof(agc_cfg));
- mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
- mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
- return 0;
-}
-
-static int dvico_dual_demod_init(struct dvb_frontend *fe)
-{
- static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
- static const u8 reset [] = { RESET, 0x80 };
- static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
- static const u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
- static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
- static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
-
- mt352_write(fe, clock_config, sizeof(clock_config));
- udelay(200);
- mt352_write(fe, reset, sizeof(reset));
- mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
-
- mt352_write(fe, agc_cfg, sizeof(agc_cfg));
- mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
- mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
-
- return 0;
-}
-
-static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
-{
- static const u8 clock_config [] = { 0x89, 0x38, 0x39 };
- static const u8 reset [] = { 0x50, 0x80 };
- static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
- static const u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
- 0x00, 0xFF, 0x00, 0x40, 0x40 };
- static const u8 dntv_extra[] = { 0xB5, 0x7A };
- static const u8 capt_range_cfg[] = { 0x75, 0x32 };
-
- mt352_write(fe, clock_config, sizeof(clock_config));
- udelay(2000);
- mt352_write(fe, reset, sizeof(reset));
- mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
-
- mt352_write(fe, agc_cfg, sizeof(agc_cfg));
- udelay(2000);
- mt352_write(fe, dntv_extra, sizeof(dntv_extra));
- mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
-
- return 0;
-}
-
-static const struct mt352_config dvico_fusionhdtv = {
- .demod_address = 0x0f,
- .demod_init = dvico_fusionhdtv_demod_init,
-};
-
-static const struct mt352_config dntv_live_dvbt_config = {
- .demod_address = 0x0f,
- .demod_init = dntv_live_dvbt_demod_init,
-};
-
-static const struct mt352_config dvico_fusionhdtv_dual = {
- .demod_address = 0x0f,
- .demod_init = dvico_dual_demod_init,
-};
-
-static const struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
- .demod_address = (0x1e >> 1),
- .no_tuner = 1,
- .if2 = 45600,
-};
-
-static struct mb86a16_config twinhan_vp1027 = {
- .demod_address = 0x08,
-};
-
-#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
-static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
-{
- static const u8 clock_config [] = { 0x89, 0x38, 0x38 };
- static const u8 reset [] = { 0x50, 0x80 };
- static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
- static const u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
- 0x00, 0xFF, 0x00, 0x40, 0x40 };
- static const u8 dntv_extra[] = { 0xB5, 0x7A };
- static const u8 capt_range_cfg[] = { 0x75, 0x32 };
-
- mt352_write(fe, clock_config, sizeof(clock_config));
- udelay(2000);
- mt352_write(fe, reset, sizeof(reset));
- mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
-
- mt352_write(fe, agc_cfg, sizeof(agc_cfg));
- udelay(2000);
- mt352_write(fe, dntv_extra, sizeof(dntv_extra));
- mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
-
- return 0;
-}
-
-static const struct mt352_config dntv_live_dvbt_pro_config = {
- .demod_address = 0x0f,
- .no_tuner = 1,
- .demod_init = dntv_live_dvbt_pro_demod_init,
-};
-#endif
-
-static const struct zl10353_config dvico_fusionhdtv_hybrid = {
- .demod_address = 0x0f,
- .no_tuner = 1,
-};
-
-static const struct zl10353_config dvico_fusionhdtv_xc3028 = {
- .demod_address = 0x0f,
- .if2 = 45600,
- .no_tuner = 1,
-};
-
-static const struct mt352_config dvico_fusionhdtv_mt352_xc3028 = {
- .demod_address = 0x0f,
- .if2 = 4560,
- .no_tuner = 1,
- .demod_init = dvico_fusionhdtv_demod_init,
-};
-
-static const struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
- .demod_address = 0x0f,
-};
-
-static const struct cx22702_config connexant_refboard_config = {
- .demod_address = 0x43,
- .output_mode = CX22702_SERIAL_OUTPUT,
-};
-
-static const struct cx22702_config hauppauge_hvr_config = {
- .demod_address = 0x63,
- .output_mode = CX22702_SERIAL_OUTPUT,
-};
-
-static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured)
-{
- struct cx8802_dev *dev= fe->dvb->priv;
- dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
- return 0;
-}
-
-static const struct or51132_config pchdtv_hd3000 = {
- .demod_address = 0x15,
- .set_ts_params = or51132_set_ts_param,
-};
-
-static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
-{
- struct cx8802_dev *dev= fe->dvb->priv;
- struct cx88_core *core = dev->core;
-
- dprintk(1, "%s: index = %d\n", __func__, index);
- if (index == 0)
- cx_clear(MO_GP0_IO, 8);
- else
- cx_set(MO_GP0_IO, 8);
- return 0;
-}
-
-static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
-{
- struct cx8802_dev *dev= fe->dvb->priv;
- if (is_punctured)
- dev->ts_gen_cntrl |= 0x04;
- else
- dev->ts_gen_cntrl &= ~0x04;
- return 0;
-}
-
-static struct lgdt330x_config fusionhdtv_3_gold = {
- .demod_address = 0x0e,
- .demod_chip = LGDT3302,
- .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
- .set_ts_params = lgdt330x_set_ts_param,
-};
-
-static const struct lgdt330x_config fusionhdtv_5_gold = {
- .demod_address = 0x0e,
- .demod_chip = LGDT3303,
- .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
- .set_ts_params = lgdt330x_set_ts_param,
-};
-
-static const struct lgdt330x_config pchdtv_hd5500 = {
- .demod_address = 0x59,
- .demod_chip = LGDT3303,
- .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
- .set_ts_params = lgdt330x_set_ts_param,
-};
-
-static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
-{
- struct cx8802_dev *dev= fe->dvb->priv;
- dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
- return 0;
-}
-
-static const struct nxt200x_config ati_hdtvwonder = {
- .demod_address = 0x0a,
- .set_ts_params = nxt200x_set_ts_param,
-};
-
-static int cx24123_set_ts_param(struct dvb_frontend* fe,
- int is_punctured)
-{
- struct cx8802_dev *dev= fe->dvb->priv;
- dev->ts_gen_cntrl = 0x02;
- return 0;
-}
-
-static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe,
- fe_sec_voltage_t voltage)
-{
- struct cx8802_dev *dev= fe->dvb->priv;
- struct cx88_core *core = dev->core;
-
- if (voltage == SEC_VOLTAGE_OFF)
- cx_write(MO_GP0_IO, 0x000006fb);
- else
- cx_write(MO_GP0_IO, 0x000006f9);
-
- if (core->prev_set_voltage)
- return core->prev_set_voltage(fe, voltage);
- return 0;
-}
-
-static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
- fe_sec_voltage_t voltage)
-{
- struct cx8802_dev *dev= fe->dvb->priv;
- struct cx88_core *core = dev->core;
-
- if (voltage == SEC_VOLTAGE_OFF) {
- dprintk(1,"LNB Voltage OFF\n");
- cx_write(MO_GP0_IO, 0x0000efff);
- }
-
- if (core->prev_set_voltage)
- return core->prev_set_voltage(fe, voltage);
- return 0;
-}
-
-static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
- fe_sec_voltage_t voltage)
-{
- struct cx8802_dev *dev= fe->dvb->priv;
- struct cx88_core *core = dev->core;
-
- cx_set(MO_GP0_IO, 0x6040);
- switch (voltage) {
- case SEC_VOLTAGE_13:
- cx_clear(MO_GP0_IO, 0x20);
- break;
- case SEC_VOLTAGE_18:
- cx_set(MO_GP0_IO, 0x20);
- break;
- case SEC_VOLTAGE_OFF:
- cx_clear(MO_GP0_IO, 0x20);
- break;
- }
-
- if (core->prev_set_voltage)
- return core->prev_set_voltage(fe, voltage);
- return 0;
-}
-
-static int vp1027_set_voltage(struct dvb_frontend *fe,
- fe_sec_voltage_t voltage)
-{
- struct cx8802_dev *dev = fe->dvb->priv;
- struct cx88_core *core = dev->core;
-
- switch (voltage) {
- case SEC_VOLTAGE_13:
- dprintk(1, "LNB SEC Voltage=13\n");
- cx_write(MO_GP0_IO, 0x00001220);
- break;
- case SEC_VOLTAGE_18:
- dprintk(1, "LNB SEC Voltage=18\n");
- cx_write(MO_GP0_IO, 0x00001222);
- break;
- case SEC_VOLTAGE_OFF:
- dprintk(1, "LNB Voltage OFF\n");
- cx_write(MO_GP0_IO, 0x00001230);
- break;
- }
-
- if (core->prev_set_voltage)
- return core->prev_set_voltage(fe, voltage);
- return 0;
-}
-
-static const struct cx24123_config geniatech_dvbs_config = {
- .demod_address = 0x55,
- .set_ts_params = cx24123_set_ts_param,
-};
-
-static const struct cx24123_config hauppauge_novas_config = {
- .demod_address = 0x55,
- .set_ts_params = cx24123_set_ts_param,
-};
-
-static const struct cx24123_config kworld_dvbs_100_config = {
- .demod_address = 0x15,
- .set_ts_params = cx24123_set_ts_param,
- .lnb_polarity = 1,
-};
-
-static const struct s5h1409_config pinnacle_pctv_hd_800i_config = {
- .demod_address = 0x32 >> 1,
- .output_mode = S5H1409_PARALLEL_OUTPUT,
- .gpio = S5H1409_GPIO_ON,
- .qam_if = 44000,
- .inversion = S5H1409_INVERSION_OFF,
- .status_mode = S5H1409_DEMODLOCKING,
- .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
-};
-
-static const struct s5h1409_config dvico_hdtv5_pci_nano_config = {
- .demod_address = 0x32 >> 1,
- .output_mode = S5H1409_SERIAL_OUTPUT,
- .gpio = S5H1409_GPIO_OFF,
- .inversion = S5H1409_INVERSION_OFF,
- .status_mode = S5H1409_DEMODLOCKING,
- .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static const struct s5h1409_config kworld_atsc_120_config = {
- .demod_address = 0x32 >> 1,
- .output_mode = S5H1409_SERIAL_OUTPUT,
- .gpio = S5H1409_GPIO_OFF,
- .inversion = S5H1409_INVERSION_OFF,
- .status_mode = S5H1409_DEMODLOCKING,
- .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
- .i2c_address = 0x64,
- .if_khz = 5380,
-};
-
-static const struct zl10353_config cx88_pinnacle_hybrid_pctv = {
- .demod_address = (0x1e >> 1),
- .no_tuner = 1,
- .if2 = 45600,
-};
-
-static const struct zl10353_config cx88_geniatech_x8000_mt = {
- .demod_address = (0x1e >> 1),
- .no_tuner = 1,
- .disable_i2c_gate_ctrl = 1,
-};
-
-static const struct s5h1411_config dvico_fusionhdtv7_config = {
- .output_mode = S5H1411_SERIAL_OUTPUT,
- .gpio = S5H1411_GPIO_ON,
- .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
- .qam_if = S5H1411_IF_44000,
- .vsb_if = S5H1411_IF_44000,
- .inversion = S5H1411_INVERSION_OFF,
- .status_mode = S5H1411_DEMODLOCKING
-};
-
-static const struct xc5000_config dvico_fusionhdtv7_tuner_config = {
- .i2c_address = 0xc2 >> 1,
- .if_khz = 5380,
-};
-
-static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
-{
- struct dvb_frontend *fe;
- struct videobuf_dvb_frontend *fe0 = NULL;
- struct xc2028_ctrl ctl;
- struct xc2028_config cfg = {
- .i2c_adap = &dev->core->i2c_adap,
- .i2c_addr = addr,
- .ctrl = &ctl,
- };
-
- /* Get the first frontend */
- fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
- if (!fe0)
- return -EINVAL;
-
- if (!fe0->dvb.frontend) {
- printk(KERN_ERR "%s/2: dvb frontend not attached. "
- "Can't attach xc3028\n",
- dev->core->name);
- return -EINVAL;
- }
-
- /*
- * Some xc3028 devices may be hidden by an I2C gate. This is known
- * to happen with some s5h1409-based devices.
- * Now that I2C gate is open, sets up xc3028 configuration
- */
- cx88_setup_xc3028(dev->core, &ctl);
-
- fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
- if (!fe) {
- printk(KERN_ERR "%s/2: xc3028 attach failed\n",
- dev->core->name);
- dvb_frontend_detach(fe0->dvb.frontend);
- dvb_unregister_frontend(fe0->dvb.frontend);
- fe0->dvb.frontend = NULL;
- return -EINVAL;
- }
-
- printk(KERN_INFO "%s/2: xc3028 attached\n",
- dev->core->name);
-
- return 0;
-}
-
-static int attach_xc4000(struct cx8802_dev *dev, struct xc4000_config *cfg)
-{
- struct dvb_frontend *fe;
- struct videobuf_dvb_frontend *fe0 = NULL;
-
- /* Get the first frontend */
- fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
- if (!fe0)
- return -EINVAL;
-
- if (!fe0->dvb.frontend) {
- printk(KERN_ERR "%s/2: dvb frontend not attached. "
- "Can't attach xc4000\n",
- dev->core->name);
- return -EINVAL;
- }
-
- fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, &dev->core->i2c_adap,
- cfg);
- if (!fe) {
- printk(KERN_ERR "%s/2: xc4000 attach failed\n",
- dev->core->name);
- dvb_frontend_detach(fe0->dvb.frontend);
- dvb_unregister_frontend(fe0->dvb.frontend);
- fe0->dvb.frontend = NULL;
- return -EINVAL;
- }
-
- printk(KERN_INFO "%s/2: xc4000 attached\n", dev->core->name);
-
- return 0;
-}
-
-static int cx24116_set_ts_param(struct dvb_frontend *fe,
- int is_punctured)
-{
- struct cx8802_dev *dev = fe->dvb->priv;
- dev->ts_gen_cntrl = 0x2;
-
- return 0;
-}
-
-static int stv0900_set_ts_param(struct dvb_frontend *fe,
- int is_punctured)
-{
- struct cx8802_dev *dev = fe->dvb->priv;
- dev->ts_gen_cntrl = 0;
-
- return 0;
-}
-
-static int cx24116_reset_device(struct dvb_frontend *fe)
-{
- struct cx8802_dev *dev = fe->dvb->priv;
- struct cx88_core *core = dev->core;
-
- /* Reset the part */
- /* Put the cx24116 into reset */
- cx_write(MO_SRST_IO, 0);
- msleep(10);
- /* Take the cx24116 out of reset */
- cx_write(MO_SRST_IO, 1);
- msleep(10);
-
- return 0;
-}
-
-static const struct cx24116_config hauppauge_hvr4000_config = {
- .demod_address = 0x05,
- .set_ts_params = cx24116_set_ts_param,
- .reset_device = cx24116_reset_device,
-};
-
-static const struct cx24116_config tevii_s460_config = {
- .demod_address = 0x55,
- .set_ts_params = cx24116_set_ts_param,
- .reset_device = cx24116_reset_device,
-};
-
-static int ds3000_set_ts_param(struct dvb_frontend *fe,
- int is_punctured)
-{
- struct cx8802_dev *dev = fe->dvb->priv;
- dev->ts_gen_cntrl = 4;
-
- return 0;
-}
-
-static struct ds3000_config tevii_ds3000_config = {
- .demod_address = 0x68,
- .set_ts_params = ds3000_set_ts_param,
-};
-
-static const struct stv0900_config prof_7301_stv0900_config = {
- .demod_address = 0x6a,
-/* demod_mode = 0,*/
- .xtal = 27000000,
- .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
- .diseqc_mode = 2,/* 2/3 PWM */
- .tun1_maddress = 0,/* 0x60 */
- .tun1_adc = 0,/* 2 Vpp */
- .path1_mode = 3,
- .set_ts_params = stv0900_set_ts_param,
-};
-
-static const struct stb6100_config prof_7301_stb6100_config = {
- .tuner_address = 0x60,
- .refclock = 27000000,
-};
-
-static const struct stv0299_config tevii_tuner_sharp_config = {
- .demod_address = 0x68,
- .inittab = sharp_z0194a_inittab,
- .mclk = 88000000UL,
- .invert = 1,
- .skip_reinit = 0,
- .lock_output = 1,
- .volt13_op0_op1 = STV0299_VOLT13_OP1,
- .min_delay_ms = 100,
- .set_symbol_rate = sharp_z0194a_set_symbol_rate,
- .set_ts_params = cx24116_set_ts_param,
-};
-
-static const struct stv0288_config tevii_tuner_earda_config = {
- .demod_address = 0x68,
- .min_delay_ms = 100,
- .set_ts_params = cx24116_set_ts_param,
-};
-
-static int cx8802_alloc_frontends(struct cx8802_dev *dev)
-{
- struct cx88_core *core = dev->core;
- struct videobuf_dvb_frontend *fe = NULL;
- int i;
-
- mutex_init(&dev->frontends.lock);
- INIT_LIST_HEAD(&dev->frontends.felist);
-
- if (!core->board.num_frontends)
- return -ENODEV;
-
- printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
- core->board.num_frontends);
- for (i = 1; i <= core->board.num_frontends; i++) {
- fe = videobuf_dvb_alloc_frontend(&dev->frontends, i);
- if (!fe) {
- printk(KERN_ERR "%s() failed to alloc\n", __func__);
- videobuf_dvb_dealloc_frontends(&dev->frontends);
- return -ENOMEM;
- }
- }
- return 0;
-}
-
-
-
-static const u8 samsung_smt_7020_inittab[] = {
- 0x01, 0x15,
- 0x02, 0x00,
- 0x03, 0x00,
- 0x04, 0x7D,
- 0x05, 0x0F,
- 0x06, 0x02,
- 0x07, 0x00,
- 0x08, 0x60,
-
- 0x0A, 0xC2,
- 0x0B, 0x00,
- 0x0C, 0x01,
- 0x0D, 0x81,
- 0x0E, 0x44,
- 0x0F, 0x09,
- 0x10, 0x3C,
- 0x11, 0x84,
- 0x12, 0xDA,
- 0x13, 0x99,
- 0x14, 0x8D,
- 0x15, 0xCE,
- 0x16, 0xE8,
- 0x17, 0x43,
- 0x18, 0x1C,
- 0x19, 0x1B,
- 0x1A, 0x1D,
-
- 0x1C, 0x12,
- 0x1D, 0x00,
- 0x1E, 0x00,
- 0x1F, 0x00,
- 0x20, 0x00,
- 0x21, 0x00,
- 0x22, 0x00,
- 0x23, 0x00,
-
- 0x28, 0x02,
- 0x29, 0x28,
- 0x2A, 0x14,
- 0x2B, 0x0F,
- 0x2C, 0x09,
- 0x2D, 0x05,
-
- 0x31, 0x1F,
- 0x32, 0x19,
- 0x33, 0xFC,
- 0x34, 0x13,
- 0xff, 0xff,
-};
-
-
-static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe)
-{
- struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- struct cx8802_dev *dev = fe->dvb->priv;
- u8 buf[4];
- u32 div;
- struct i2c_msg msg = {
- .addr = 0x61,
- .flags = 0,
- .buf = buf,
- .len = sizeof(buf) };
-
- div = c->frequency / 125;
-
- buf[0] = (div >> 8) & 0x7f;
- buf[1] = div & 0xff;
- buf[2] = 0x84; /* 0xC4 */
- buf[3] = 0x00;
-
- if (c->frequency < 1500000)
- buf[3] |= 0x10;
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
-
- if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1)
- return -EIO;
-
- return 0;
-}
-
-static int samsung_smt_7020_set_tone(struct dvb_frontend *fe,
- fe_sec_tone_mode_t tone)
-{
- struct cx8802_dev *dev = fe->dvb->priv;
- struct cx88_core *core = dev->core;
-
- cx_set(MO_GP0_IO, 0x0800);
-
- switch (tone) {
- case SEC_TONE_ON:
- cx_set(MO_GP0_IO, 0x08);
- break;
- case SEC_TONE_OFF:
- cx_clear(MO_GP0_IO, 0x08);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
- fe_sec_voltage_t voltage)
-{
- struct cx8802_dev *dev = fe->dvb->priv;
- struct cx88_core *core = dev->core;
-
- u8 data;
- struct i2c_msg msg = {
- .addr = 8,
- .flags = 0,
- .buf = &data,
- .len = sizeof(data) };
-
- cx_set(MO_GP0_IO, 0x8000);
-
- switch (voltage) {
- case SEC_VOLTAGE_OFF:
- break;
- case SEC_VOLTAGE_13:
- data = ISL6421_EN1 | ISL6421_LLC1;
- cx_clear(MO_GP0_IO, 0x80);
- break;
- case SEC_VOLTAGE_18:
- data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1;
- cx_clear(MO_GP0_IO, 0x80);
- break;
- default:
- return -EINVAL;
- };
-
- return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
-}
-
-static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe,
- u32 srate, u32 ratio)
-{
- u8 aclk = 0;
- u8 bclk = 0;
-
- if (srate < 1500000) {
- aclk = 0xb7;
- bclk = 0x47;
- } else if (srate < 3000000) {
- aclk = 0xb7;
- bclk = 0x4b;
- } else if (srate < 7000000) {
- aclk = 0xb7;
- bclk = 0x4f;
- } else if (srate < 14000000) {
- aclk = 0xb7;
- bclk = 0x53;
- } else if (srate < 30000000) {
- aclk = 0xb6;
- bclk = 0x53;
- } else if (srate < 45000000) {
- aclk = 0xb4;
- bclk = 0x51;
- }
-
- stv0299_writereg(fe, 0x13, aclk);
- stv0299_writereg(fe, 0x14, bclk);
- stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
- stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
- stv0299_writereg(fe, 0x21, ratio & 0xf0);
-
- return 0;
-}
-
-
-static const struct stv0299_config samsung_stv0299_config = {
- .demod_address = 0x68,
- .inittab = samsung_smt_7020_inittab,
- .mclk = 88000000UL,
- .invert = 0,
- .skip_reinit = 0,
- .lock_output = STV0299_LOCKOUTPUT_LK,
- .volt13_op0_op1 = STV0299_VOLT13_OP1,
- .min_delay_ms = 100,
- .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate,
-};
-
-static int dvb_register(struct cx8802_dev *dev)
-{
- struct cx88_core *core = dev->core;
- struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
- int mfe_shared = 0; /* bus not shared by default */
- int res = -EINVAL;
-
- if (0 != core->i2c_rc) {
- printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
- goto frontend_detach;
- }
-
- /* Get the first frontend */
- fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
- if (!fe0)
- goto frontend_detach;
-
- /* multi-frontend gate control is undefined or defaults to fe0 */
- dev->frontends.gate = 0;
-
- /* Sets the gate control callback to be used by i2c command calls */
- core->gate_ctrl = cx88_dvb_gate_ctrl;
-
- /* init frontend(s) */
- switch (core->boardnr) {
- case CX88_BOARD_HAUPPAUGE_DVB_T1:
- fe0->dvb.frontend = dvb_attach(cx22702_attach,
- &connexant_refboard_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
- 0x61, &core->i2c_adap,
- DVB_PLL_THOMSON_DTT759X))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
- case CX88_BOARD_CONEXANT_DVB_T1:
- case CX88_BOARD_KWORLD_DVB_T_CX22702:
- case CX88_BOARD_WINFAST_DTV1000:
- fe0->dvb.frontend = dvb_attach(cx22702_attach,
- &connexant_refboard_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
- 0x60, &core->i2c_adap,
- DVB_PLL_THOMSON_DTT7579))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_WINFAST_DTV2000H:
- case CX88_BOARD_HAUPPAUGE_HVR1100:
- case CX88_BOARD_HAUPPAUGE_HVR1100LP:
- case CX88_BOARD_HAUPPAUGE_HVR1300:
- fe0->dvb.frontend = dvb_attach(cx22702_attach,
- &hauppauge_hvr_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &core->i2c_adap, 0x61,
- TUNER_PHILIPS_FMD1216ME_MK3))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_WINFAST_DTV2000H_J:
- fe0->dvb.frontend = dvb_attach(cx22702_attach,
- &hauppauge_hvr_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &core->i2c_adap, 0x61,
- TUNER_PHILIPS_FMD1216MEX_MK3))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_HAUPPAUGE_HVR3000:
- /* MFE frontend 1 */
- mfe_shared = 1;
- dev->frontends.gate = 2;
- /* DVB-S init */
- fe0->dvb.frontend = dvb_attach(cx24123_attach,
- &hauppauge_novas_config,
- &dev->core->i2c_adap);
- if (fe0->dvb.frontend) {
- if (!dvb_attach(isl6421_attach,
- fe0->dvb.frontend,
- &dev->core->i2c_adap,
- 0x08, ISL6421_DCL, 0x00))
- goto frontend_detach;
- }
- /* MFE frontend 2 */
- fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
- if (!fe1)
- goto frontend_detach;
- /* DVB-T init */
- fe1->dvb.frontend = dvb_attach(cx22702_attach,
- &hauppauge_hvr_config,
- &dev->core->i2c_adap);
- if (fe1->dvb.frontend) {
- fe1->dvb.frontend->id = 1;
- if (!dvb_attach(simple_tuner_attach,
- fe1->dvb.frontend,
- &dev->core->i2c_adap,
- 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
- fe0->dvb.frontend = dvb_attach(mt352_attach,
- &dvico_fusionhdtv,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
- 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
- goto frontend_detach;
- break;
- }
- /* ZL10353 replaces MT352 on later cards */
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &dvico_fusionhdtv_plus_v1_1,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
- 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
- /* The tin box says DEE1601, but it seems to be DTT7579
- * compatible, with a slightly different MT352 AGC gain. */
- fe0->dvb.frontend = dvb_attach(mt352_attach,
- &dvico_fusionhdtv_dual,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
- 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
- goto frontend_detach;
- break;
- }
- /* ZL10353 replaces MT352 on later cards */
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &dvico_fusionhdtv_plus_v1_1,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
- 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
- fe0->dvb.frontend = dvb_attach(mt352_attach,
- &dvico_fusionhdtv,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
- 0x61, NULL, DVB_PLL_LG_Z201))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_KWORLD_DVB_T:
- case CX88_BOARD_DNTV_LIVE_DVB_T:
- case CX88_BOARD_ADSTECH_DVB_T_PCI:
- fe0->dvb.frontend = dvb_attach(mt352_attach,
- &dntv_live_dvbt_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
- 0x61, NULL, DVB_PLL_UNKNOWN_1))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
-#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
- /* MT352 is on a secondary I2C bus made from some GPIO lines */
- fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
- &dev->vp3054->adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &core->i2c_adap, 0x61,
- TUNER_PHILIPS_FMD1216ME_MK3))
- goto frontend_detach;
- }
-#else
- printk(KERN_ERR "%s/2: built without vp3054 support\n",
- core->name);
-#endif
- break;
- case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &dvico_fusionhdtv_hybrid,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &core->i2c_adap, 0x61,
- TUNER_THOMSON_FE6600))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &dvico_fusionhdtv_xc3028,
- &core->i2c_adap);
- if (fe0->dvb.frontend == NULL)
- fe0->dvb.frontend = dvb_attach(mt352_attach,
- &dvico_fusionhdtv_mt352_xc3028,
- &core->i2c_adap);
- /*
- * On this board, the demod provides the I2C bus pullup.
- * We must not permit gate_ctrl to be performed, or
- * the xc3028 cannot communicate on the bus.
- */
- if (fe0->dvb.frontend)
- fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
- if (attach_xc3028(0x61, dev) < 0)
- goto frontend_detach;
- break;
- case CX88_BOARD_PCHDTV_HD3000:
- fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &core->i2c_adap, 0x61,
- TUNER_THOMSON_DTT761X))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
- dev->ts_gen_cntrl = 0x08;
-
- /* Do a hardware reset of chip before using it. */
- cx_clear(MO_GP0_IO, 1);
- mdelay(100);
- cx_set(MO_GP0_IO, 1);
- mdelay(200);
-
- /* Select RF connector callback */
- fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
- fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
- &fusionhdtv_3_gold,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &core->i2c_adap, 0x61,
- TUNER_MICROTUNE_4042FI5))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
- dev->ts_gen_cntrl = 0x08;
-
- /* Do a hardware reset of chip before using it. */
- cx_clear(MO_GP0_IO, 1);
- mdelay(100);
- cx_set(MO_GP0_IO, 9);
- mdelay(200);
- fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
- &fusionhdtv_3_gold,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &core->i2c_adap, 0x61,
- TUNER_THOMSON_DTT761X))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
- dev->ts_gen_cntrl = 0x08;
-
- /* Do a hardware reset of chip before using it. */
- cx_clear(MO_GP0_IO, 1);
- mdelay(100);
- cx_set(MO_GP0_IO, 1);
- mdelay(200);
- fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
- &fusionhdtv_5_gold,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &core->i2c_adap, 0x61,
- TUNER_LG_TDVS_H06XF))
- goto frontend_detach;
- if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
- &core->i2c_adap, 0x43))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_PCHDTV_HD5500:
- dev->ts_gen_cntrl = 0x08;
-
- /* Do a hardware reset of chip before using it. */
- cx_clear(MO_GP0_IO, 1);
- mdelay(100);
- cx_set(MO_GP0_IO, 1);
- mdelay(200);
- fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
- &pchdtv_hd5500,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &core->i2c_adap, 0x61,
- TUNER_LG_TDVS_H06XF))
- goto frontend_detach;
- if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
- &core->i2c_adap, 0x43))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_ATI_HDTVWONDER:
- fe0->dvb.frontend = dvb_attach(nxt200x_attach,
- &ati_hdtvwonder,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &core->i2c_adap, 0x61,
- TUNER_PHILIPS_TUV1236D))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
- case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
- fe0->dvb.frontend = dvb_attach(cx24123_attach,
- &hauppauge_novas_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend) {
- if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
- &core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_KWORLD_DVBS_100:
- fe0->dvb.frontend = dvb_attach(cx24123_attach,
- &kworld_dvbs_100_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend) {
- core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
- fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
- }
- break;
- case CX88_BOARD_GENIATECH_DVBS:
- fe0->dvb.frontend = dvb_attach(cx24123_attach,
- &geniatech_dvbs_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend) {
- core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
- fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
- }
- break;
- case CX88_BOARD_PINNACLE_PCTV_HD_800i:
- fe0->dvb.frontend = dvb_attach(s5h1409_attach,
- &pinnacle_pctv_hd_800i_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
- &core->i2c_adap,
- &pinnacle_pctv_hd_800i_tuner_config))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
- fe0->dvb.frontend = dvb_attach(s5h1409_attach,
- &dvico_hdtv5_pci_nano_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- struct dvb_frontend *fe;
- struct xc2028_config cfg = {
- .i2c_adap = &core->i2c_adap,
- .i2c_addr = 0x61,
- };
- static struct xc2028_ctrl ctl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64,
- .scode_table = XC3028_FE_OREN538,
- };
-
- fe = dvb_attach(xc2028_attach,
- fe0->dvb.frontend, &cfg);
- if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
- fe->ops.tuner_ops.set_config(fe, &ctl);
- }
- break;
- case CX88_BOARD_PINNACLE_HYBRID_PCTV:
- case CX88_BOARD_WINFAST_DTV1800H:
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &cx88_pinnacle_hybrid_pctv,
- &core->i2c_adap);
- if (fe0->dvb.frontend) {
- fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
- if (attach_xc3028(0x61, dev) < 0)
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_WINFAST_DTV1800H_XC4000:
- case CX88_BOARD_WINFAST_DTV2000H_PLUS:
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &cx88_pinnacle_hybrid_pctv,
- &core->i2c_adap);
- if (fe0->dvb.frontend) {
- struct xc4000_config cfg = {
- .i2c_address = 0x61,
- .default_pm = 0,
- .dvb_amplitude = 134,
- .set_smoothedcvbs = 1,
- .if_khz = 4560
- };
- fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
- if (attach_xc4000(dev, &cfg) < 0)
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_GENIATECH_X8000_MT:
- dev->ts_gen_cntrl = 0x00;
-
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &cx88_geniatech_x8000_mt,
- &core->i2c_adap);
- if (attach_xc3028(0x61, dev) < 0)
- goto frontend_detach;
- break;
- case CX88_BOARD_KWORLD_ATSC_120:
- fe0->dvb.frontend = dvb_attach(s5h1409_attach,
- &kworld_atsc_120_config,
- &core->i2c_adap);
- if (attach_xc3028(0x61, dev) < 0)
- goto frontend_detach;
- break;
- case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
- fe0->dvb.frontend = dvb_attach(s5h1411_attach,
- &dvico_fusionhdtv7_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
- &core->i2c_adap,
- &dvico_fusionhdtv7_tuner_config))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_HAUPPAUGE_HVR4000:
- /* MFE frontend 1 */
- mfe_shared = 1;
- dev->frontends.gate = 2;
- /* DVB-S/S2 Init */
- fe0->dvb.frontend = dvb_attach(cx24116_attach,
- &hauppauge_hvr4000_config,
- &dev->core->i2c_adap);
- if (fe0->dvb.frontend) {
- if (!dvb_attach(isl6421_attach,
- fe0->dvb.frontend,
- &dev->core->i2c_adap,
- 0x08, ISL6421_DCL, 0x00))
- goto frontend_detach;
- }
- /* MFE frontend 2 */
- fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
- if (!fe1)
- goto frontend_detach;
- /* DVB-T Init */
- fe1->dvb.frontend = dvb_attach(cx22702_attach,
- &hauppauge_hvr_config,
- &dev->core->i2c_adap);
- if (fe1->dvb.frontend) {
- fe1->dvb.frontend->id = 1;
- if (!dvb_attach(simple_tuner_attach,
- fe1->dvb.frontend,
- &dev->core->i2c_adap,
- 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
- fe0->dvb.frontend = dvb_attach(cx24116_attach,
- &hauppauge_hvr4000_config,
- &dev->core->i2c_adap);
- if (fe0->dvb.frontend) {
- if (!dvb_attach(isl6421_attach,
- fe0->dvb.frontend,
- &dev->core->i2c_adap,
- 0x08, ISL6421_DCL, 0x00))
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_PROF_6200:
- case CX88_BOARD_TBS_8910:
- case CX88_BOARD_TEVII_S420:
- fe0->dvb.frontend = dvb_attach(stv0299_attach,
- &tevii_tuner_sharp_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
- &core->i2c_adap, DVB_PLL_OPERA1))
- goto frontend_detach;
- core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
- fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
-
- } else {
- fe0->dvb.frontend = dvb_attach(stv0288_attach,
- &tevii_tuner_earda_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61,
- &core->i2c_adap))
- goto frontend_detach;
- core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
- fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
- }
- }
- break;
- case CX88_BOARD_TEVII_S460:
- fe0->dvb.frontend = dvb_attach(cx24116_attach,
- &tevii_s460_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL)
- fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
- break;
- case CX88_BOARD_TEVII_S464:
- fe0->dvb.frontend = dvb_attach(ds3000_attach,
- &tevii_ds3000_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL)
- fe0->dvb.frontend->ops.set_voltage =
- tevii_dvbs_set_voltage;
- break;
- case CX88_BOARD_OMICOM_SS4_PCI:
- case CX88_BOARD_TBS_8920:
- case CX88_BOARD_PROF_7300:
- case CX88_BOARD_SATTRADE_ST4200:
- fe0->dvb.frontend = dvb_attach(cx24116_attach,
- &hauppauge_hvr4000_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend != NULL)
- fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
- break;
- case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &cx88_terratec_cinergy_ht_pci_mkii_config,
- &core->i2c_adap);
- if (fe0->dvb.frontend) {
- fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
- if (attach_xc3028(0x61, dev) < 0)
- goto frontend_detach;
- }
- break;
- case CX88_BOARD_PROF_7301:{
- struct dvb_tuner_ops *tuner_ops = NULL;
-
- fe0->dvb.frontend = dvb_attach(stv0900_attach,
- &prof_7301_stv0900_config,
- &core->i2c_adap, 0);
- if (fe0->dvb.frontend != NULL) {
- if (!dvb_attach(stb6100_attach, fe0->dvb.frontend,
- &prof_7301_stb6100_config,
- &core->i2c_adap))
- goto frontend_detach;
-
- tuner_ops = &fe0->dvb.frontend->ops.tuner_ops;
- tuner_ops->set_frequency = stb6100_set_freq;
- tuner_ops->get_frequency = stb6100_get_freq;
- tuner_ops->set_bandwidth = stb6100_set_bandw;
- tuner_ops->get_bandwidth = stb6100_get_bandw;
-
- core->prev_set_voltage =
- fe0->dvb.frontend->ops.set_voltage;
- fe0->dvb.frontend->ops.set_voltage =
- tevii_dvbs_set_voltage;
- }
- break;
- }
- case CX88_BOARD_SAMSUNG_SMT_7020:
- dev->ts_gen_cntrl = 0x08;
-
- cx_set(MO_GP0_IO, 0x0101);
-
- cx_clear(MO_GP0_IO, 0x01);
- mdelay(100);
- cx_set(MO_GP0_IO, 0x01);
- mdelay(200);
-
- fe0->dvb.frontend = dvb_attach(stv0299_attach,
- &samsung_stv0299_config,
- &dev->core->i2c_adap);
- if (fe0->dvb.frontend) {
- fe0->dvb.frontend->ops.tuner_ops.set_params =
- samsung_smt_7020_tuner_set_params;
- fe0->dvb.frontend->tuner_priv =
- &dev->core->i2c_adap;
- fe0->dvb.frontend->ops.set_voltage =
- samsung_smt_7020_set_voltage;
- fe0->dvb.frontend->ops.set_tone =
- samsung_smt_7020_set_tone;
- }
-
- break;
- case CX88_BOARD_TWINHAN_VP1027_DVBS:
- dev->ts_gen_cntrl = 0x00;
- fe0->dvb.frontend = dvb_attach(mb86a16_attach,
- &twinhan_vp1027,
- &core->i2c_adap);
- if (fe0->dvb.frontend) {
- core->prev_set_voltage =
- fe0->dvb.frontend->ops.set_voltage;
- fe0->dvb.frontend->ops.set_voltage =
- vp1027_set_voltage;
- }
- break;
-
- default:
- printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
- core->name);
- break;
- }
-
- if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
- printk(KERN_ERR
- "%s/2: frontend initialization failed\n",
- core->name);
- goto frontend_detach;
- }
- /* define general-purpose callback pointer */
- fe0->dvb.frontend->callback = cx88_tuner_callback;
-
- /* Ensure all frontends negotiate bus access */
- fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
- if (fe1)
- fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
-
- /* Put the analog decoder in standby to keep it quiet */
- call_all(core, core, s_power, 0);
-
- /* register everything */
- res = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
- &dev->pci->dev, adapter_nr, mfe_shared, NULL);
- if (res)
- goto frontend_detach;
- return res;
-
-frontend_detach:
- core->gate_ctrl = NULL;
- videobuf_dvb_dealloc_frontends(&dev->frontends);
- return res;
-}
-
-/* ----------------------------------------------------------- */
-
-/* CX8802 MPEG -> mini driver - We have been given the hardware */
-static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
-{
- struct cx88_core *core = drv->core;
- int err = 0;
- dprintk( 1, "%s\n", __func__);
-
- switch (core->boardnr) {
- case CX88_BOARD_HAUPPAUGE_HVR1300:
- /* We arrive here with either the cx23416 or the cx22702
- * on the bus. Take the bus from the cx23416 and enable the
- * cx22702 demod
- */
- /* Toggle reset on cx22702 leaving i2c active */
- cx_set(MO_GP0_IO, 0x00000080);
- udelay(1000);
- cx_clear(MO_GP0_IO, 0x00000080);
- udelay(50);
- cx_set(MO_GP0_IO, 0x00000080);
- udelay(1000);
- /* enable the cx22702 pins */
- cx_clear(MO_GP0_IO, 0x00000004);
- udelay(1000);
- break;
-
- case CX88_BOARD_HAUPPAUGE_HVR3000:
- case CX88_BOARD_HAUPPAUGE_HVR4000:
- /* Toggle reset on cx22702 leaving i2c active */
- cx_set(MO_GP0_IO, 0x00000080);
- udelay(1000);
- cx_clear(MO_GP0_IO, 0x00000080);
- udelay(50);
- cx_set(MO_GP0_IO, 0x00000080);
- udelay(1000);
- switch (core->dvbdev->frontends.active_fe_id) {
- case 1: /* DVB-S/S2 Enabled */
- /* tri-state the cx22702 pins */
- cx_set(MO_GP0_IO, 0x00000004);
- /* Take the cx24116/cx24123 out of reset */
- cx_write(MO_SRST_IO, 1);
- core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
- break;
- case 2: /* DVB-T Enabled */
- /* Put the cx24116/cx24123 into reset */
- cx_write(MO_SRST_IO, 0);
- /* enable the cx22702 pins */
- cx_clear(MO_GP0_IO, 0x00000004);
- core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
- break;
- }
- udelay(1000);
- break;
-
- case CX88_BOARD_WINFAST_DTV2000H_PLUS:
- /* set RF input to AIR for DVB-T (GPIO 16) */
- cx_write(MO_GP2_IO, 0x0101);
- break;
-
- default:
- err = -ENODEV;
- }
- return err;
-}
-
-/* CX8802 MPEG -> mini driver - We no longer have the hardware */
-static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
-{
- struct cx88_core *core = drv->core;
- int err = 0;
- dprintk( 1, "%s\n", __func__);
-
- switch (core->boardnr) {
- case CX88_BOARD_HAUPPAUGE_HVR1300:
- /* Do Nothing, leave the cx22702 on the bus. */
- break;
- case CX88_BOARD_HAUPPAUGE_HVR3000:
- case CX88_BOARD_HAUPPAUGE_HVR4000:
- break;
- default:
- err = -ENODEV;
- }
- return err;
-}
-
-static int cx8802_dvb_probe(struct cx8802_driver *drv)
-{
- struct cx88_core *core = drv->core;
- struct cx8802_dev *dev = drv->core->dvbdev;
- int err;
- struct videobuf_dvb_frontend *fe;
- int i;
-
- dprintk( 1, "%s\n", __func__);
- dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
- core->boardnr,
- core->name,
- core->pci_bus,
- core->pci_slot);
-
- err = -ENODEV;
- if (!(core->board.mpeg & CX88_MPEG_DVB))
- goto fail_core;
-
- /* If vp3054 isn't enabled, a stub will just return 0 */
- err = vp3054_i2c_probe(dev);
- if (0 != err)
- goto fail_core;
-
- /* dvb stuff */
- printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
- dev->ts_gen_cntrl = 0x0c;
-
- err = cx8802_alloc_frontends(dev);
- if (err)
- goto fail_core;
-
- err = -ENODEV;
- for (i = 1; i <= core->board.num_frontends; i++) {
- fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
- if (fe == NULL) {
- printk(KERN_ERR "%s() failed to get frontend(%d)\n",
- __func__, i);
- goto fail_probe;
- }
- videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_TOP,
- sizeof(struct cx88_buffer),
- dev, NULL);
- /* init struct videobuf_dvb */
- fe->dvb.name = dev->core->name;
- }
-
- err = dvb_register(dev);
- if (err)
- /* frontends/adapter de-allocated in dvb_register */
- printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
- core->name, err);
- return err;
-fail_probe:
- videobuf_dvb_dealloc_frontends(&core->dvbdev->frontends);
-fail_core:
- return err;
-}
-
-static int cx8802_dvb_remove(struct cx8802_driver *drv)
-{
- struct cx88_core *core = drv->core;
- struct cx8802_dev *dev = drv->core->dvbdev;
-
- dprintk( 1, "%s\n", __func__);
-
- videobuf_dvb_unregister_bus(&dev->frontends);
-
- vp3054_i2c_remove(dev);
-
- core->gate_ctrl = NULL;
-
- return 0;
-}
-
-static struct cx8802_driver cx8802_dvb_driver = {
- .type_id = CX88_MPEG_DVB,
- .hw_access = CX8802_DRVCTL_SHARED,
- .probe = cx8802_dvb_probe,
- .remove = cx8802_dvb_remove,
- .advise_acquire = cx8802_dvb_advise_acquire,
- .advise_release = cx8802_dvb_advise_release,
-};
-
-static int __init dvb_init(void)
-{
- printk(KERN_INFO "cx88/2: cx2388x dvb driver version %s loaded\n",
- CX88_VERSION);
- return cx8802_register_driver(&cx8802_dvb_driver);
-}
-
-static void __exit dvb_fini(void)
-{
- cx8802_unregister_driver(&cx8802_dvb_driver);
-}
-
-module_init(dvb_init);
-module_exit(dvb_fini);
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
deleted file mode 100644
index de0f1af74e4..00000000000
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ /dev/null
@@ -1,184 +0,0 @@
-
-/*
-
- cx88-i2c.c -- all the i2c code is here
-
- Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
- (c) 2002 Yurij Sysoev <yurij@naturesoft.net>
- (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
-
- (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
- - Multituner support and i2c address binding
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-
-#include "cx88.h"
-#include <media/v4l2-common.h>
-
-static unsigned int i2c_debug;
-module_param(i2c_debug, int, 0644);
-MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]");
-
-static unsigned int i2c_scan;
-module_param(i2c_scan, int, 0444);
-MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
-
-static unsigned int i2c_udelay = 5;
-module_param(i2c_udelay, int, 0644);
-MODULE_PARM_DESC(i2c_udelay,"i2c delay at insmod time, in usecs "
- "(should be 5 or higher). Lower value means higher bus speed.");
-
-#define dprintk(level,fmt, arg...) if (i2c_debug >= level) \
- printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
-
-/* ----------------------------------------------------------------------- */
-
-static void cx8800_bit_setscl(void *data, int state)
-{
- struct cx88_core *core = data;
-
- if (state)
- core->i2c_state |= 0x02;
- else
- core->i2c_state &= ~0x02;
- cx_write(MO_I2C, core->i2c_state);
- cx_read(MO_I2C);
-}
-
-static void cx8800_bit_setsda(void *data, int state)
-{
- struct cx88_core *core = data;
-
- if (state)
- core->i2c_state |= 0x01;
- else
- core->i2c_state &= ~0x01;
- cx_write(MO_I2C, core->i2c_state);
- cx_read(MO_I2C);
-}
-
-static int cx8800_bit_getscl(void *data)
-{
- struct cx88_core *core = data;
- u32 state;
-
- state = cx_read(MO_I2C);
- return state & 0x02 ? 1 : 0;
-}
-
-static int cx8800_bit_getsda(void *data)
-{
- struct cx88_core *core = data;
- u32 state;
-
- state = cx_read(MO_I2C);
- return state & 0x01;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_algo_bit_data cx8800_i2c_algo_template = {
- .setsda = cx8800_bit_setsda,
- .setscl = cx8800_bit_setscl,
- .getsda = cx8800_bit_getsda,
- .getscl = cx8800_bit_getscl,
- .udelay = 16,
- .timeout = 200,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static const char * const i2c_devs[128] = {
- [ 0x1c >> 1 ] = "lgdt330x",
- [ 0x86 >> 1 ] = "tda9887/cx22702",
- [ 0xa0 >> 1 ] = "eeprom",
- [ 0xc0 >> 1 ] = "tuner (analog)",
- [ 0xc2 >> 1 ] = "tuner (analog/dvb)",
- [ 0xc8 >> 1 ] = "xc5000",
-};
-
-static void do_i2c_scan(const char *name, struct i2c_client *c)
-{
- unsigned char buf;
- int i,rc;
-
- for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
- c->addr = i;
- rc = i2c_master_recv(c,&buf,0);
- if (rc < 0)
- continue;
- printk("%s: i2c scan: found device @ 0x%x [%s]\n",
- name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
- }
-}
-
-/* init + register i2c adapter */
-int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
-{
- /* Prevents usage of invalid delay values */
- if (i2c_udelay<5)
- i2c_udelay=5;
-
- memcpy(&core->i2c_algo, &cx8800_i2c_algo_template,
- sizeof(core->i2c_algo));
-
-
- core->i2c_adap.dev.parent = &pci->dev;
- strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name));
- core->i2c_adap.owner = THIS_MODULE;
- core->i2c_algo.udelay = i2c_udelay;
- core->i2c_algo.data = core;
- i2c_set_adapdata(&core->i2c_adap, &core->v4l2_dev);
- core->i2c_adap.algo_data = &core->i2c_algo;
- core->i2c_client.adapter = &core->i2c_adap;
- strlcpy(core->i2c_client.name, "cx88xx internal", I2C_NAME_SIZE);
-
- cx8800_bit_setscl(core,1);
- cx8800_bit_setsda(core,1);
-
- core->i2c_rc = i2c_bit_add_bus(&core->i2c_adap);
- if (0 == core->i2c_rc) {
- static u8 tuner_data[] =
- { 0x0b, 0xdc, 0x86, 0x52 };
- static struct i2c_msg tuner_msg =
- { .flags = 0, .addr = 0xc2 >> 1, .buf = tuner_data, .len = 4 };
-
- dprintk(1, "i2c register ok\n");
- switch( core->boardnr ) {
- case CX88_BOARD_HAUPPAUGE_HVR1300:
- case CX88_BOARD_HAUPPAUGE_HVR3000:
- case CX88_BOARD_HAUPPAUGE_HVR4000:
- printk("%s: i2c init: enabling analog demod on HVR1300/3000/4000 tuner\n",
- core->name);
- i2c_transfer(core->i2c_client.adapter, &tuner_msg, 1);
- break;
- default:
- break;
- }
- if (i2c_scan)
- do_i2c_scan(core->name,&core->i2c_client);
- } else
- printk("%s: i2c register FAILED\n", core->name);
-
- return core->i2c_rc;
-}
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
deleted file mode 100644
index ebf448c48ca..00000000000
--- a/drivers/media/video/cx88/cx88-input.c
+++ /dev/null
@@ -1,635 +0,0 @@
-/*
- *
- * Device driver for GPIO attached remote control interfaces
- * on Conexant 2388x based TV/DVB cards.
- *
- * Copyright (c) 2003 Pavel Machek
- * Copyright (c) 2004 Gerd Knorr
- * Copyright (c) 2004, 2005 Chris Pascoe
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/hrtimer.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#include "cx88.h"
-#include <media/rc-core.h>
-
-#define MODULE_NAME "cx88xx"
-
-/* ---------------------------------------------------------------------- */
-
-struct cx88_IR {
- struct cx88_core *core;
- struct rc_dev *dev;
-
- int users;
-
- char name[32];
- char phys[32];
-
- /* sample from gpio pin 16 */
- u32 sampling;
-
- /* poll external decoder */
- int polling;
- struct hrtimer timer;
- u32 gpio_addr;
- u32 last_gpio;
- u32 mask_keycode;
- u32 mask_keydown;
- u32 mask_keyup;
-};
-
-static unsigned ir_samplerate = 4;
-module_param(ir_samplerate, uint, 0444);
-MODULE_PARM_DESC(ir_samplerate, "IR samplerate in kHz, 1 - 20, default 4");
-
-static int ir_debug;
-module_param(ir_debug, int, 0644); /* debug level [IR] */
-MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
-
-#define ir_dprintk(fmt, arg...) if (ir_debug) \
- printk(KERN_DEBUG "%s IR: " fmt , ir->core->name , ##arg)
-
-#define dprintk(fmt, arg...) if (ir_debug) \
- printk(KERN_DEBUG "cx88 IR: " fmt , ##arg)
-
-/* ---------------------------------------------------------------------- */
-
-static void cx88_ir_handle_key(struct cx88_IR *ir)
-{
- struct cx88_core *core = ir->core;
- u32 gpio, data, auxgpio;
-
- /* read gpio value */
- gpio = cx_read(ir->gpio_addr);
- switch (core->boardnr) {
- case CX88_BOARD_NPGTECH_REALTV_TOP10FM:
- /* This board apparently uses a combination of 2 GPIO
- to represent the keys. Additionally, the second GPIO
- can be used for parity.
-
- Example:
-
- for key "5"
- gpio = 0x758, auxgpio = 0xe5 or 0xf5
- for key "Power"
- gpio = 0x758, auxgpio = 0xed or 0xfd
- */
-
- auxgpio = cx_read(MO_GP1_IO);
- /* Take out the parity part */
- gpio=(gpio & 0x7fd) + (auxgpio & 0xef);
- break;
- case CX88_BOARD_WINFAST_DTV1000:
- case CX88_BOARD_WINFAST_DTV1800H:
- case CX88_BOARD_WINFAST_DTV1800H_XC4000:
- case CX88_BOARD_WINFAST_DTV2000H_PLUS:
- case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
- case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36:
- case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43:
- gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900);
- auxgpio = gpio;
- break;
- default:
- auxgpio = gpio;
- }
- if (ir->polling) {
- if (ir->last_gpio == auxgpio)
- return;
- ir->last_gpio = auxgpio;
- }
-
- /* extract data */
- data = ir_extract_bits(gpio, ir->mask_keycode);
- ir_dprintk("irq gpio=0x%x code=%d | %s%s%s\n",
- gpio, data,
- ir->polling ? "poll" : "irq",
- (gpio & ir->mask_keydown) ? " down" : "",
- (gpio & ir->mask_keyup) ? " up" : "");
-
- if (ir->core->boardnr == CX88_BOARD_NORWOOD_MICRO) {
- u32 gpio_key = cx_read(MO_GP0_IO);
-
- data = (data << 4) | ((gpio_key & 0xf0) >> 4);
-
- rc_keydown(ir->dev, data, 0);
-
- } else if (ir->mask_keydown) {
- /* bit set on keydown */
- if (gpio & ir->mask_keydown)
- rc_keydown_notimeout(ir->dev, data, 0);
- else
- rc_keyup(ir->dev);
-
- } else if (ir->mask_keyup) {
- /* bit cleared on keydown */
- if (0 == (gpio & ir->mask_keyup))
- rc_keydown_notimeout(ir->dev, data, 0);
- else
- rc_keyup(ir->dev);
-
- } else {
- /* can't distinguish keydown/up :-/ */
- rc_keydown_notimeout(ir->dev, data, 0);
- rc_keyup(ir->dev);
- }
-}
-
-static enum hrtimer_restart cx88_ir_work(struct hrtimer *timer)
-{
- unsigned long missed;
- struct cx88_IR *ir = container_of(timer, struct cx88_IR, timer);
-
- cx88_ir_handle_key(ir);
- missed = hrtimer_forward_now(&ir->timer,
- ktime_set(0, ir->polling * 1000000));
- if (missed > 1)
- ir_dprintk("Missed ticks %ld\n", missed - 1);
-
- return HRTIMER_RESTART;
-}
-
-static int __cx88_ir_start(void *priv)
-{
- struct cx88_core *core = priv;
- struct cx88_IR *ir;
-
- if (!core || !core->ir)
- return -EINVAL;
-
- ir = core->ir;
-
- if (ir->polling) {
- hrtimer_init(&ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- ir->timer.function = cx88_ir_work;
- hrtimer_start(&ir->timer,
- ktime_set(0, ir->polling * 1000000),
- HRTIMER_MODE_REL);
- }
- if (ir->sampling) {
- core->pci_irqmask |= PCI_INT_IR_SMPINT;
- cx_write(MO_DDS_IO, 0x33F286 * ir_samplerate); /* samplerate */
- cx_write(MO_DDSCFG_IO, 0x5); /* enable */
- }
- return 0;
-}
-
-static void __cx88_ir_stop(void *priv)
-{
- struct cx88_core *core = priv;
- struct cx88_IR *ir;
-
- if (!core || !core->ir)
- return;
-
- ir = core->ir;
- if (ir->sampling) {
- cx_write(MO_DDSCFG_IO, 0x0);
- core->pci_irqmask &= ~PCI_INT_IR_SMPINT;
- }
-
- if (ir->polling)
- hrtimer_cancel(&ir->timer);
-}
-
-int cx88_ir_start(struct cx88_core *core)
-{
- if (core->ir->users)
- return __cx88_ir_start(core);
-
- return 0;
-}
-
-void cx88_ir_stop(struct cx88_core *core)
-{
- if (core->ir->users)
- __cx88_ir_stop(core);
-}
-
-static int cx88_ir_open(struct rc_dev *rc)
-{
- struct cx88_core *core = rc->priv;
-
- core->ir->users++;
- return __cx88_ir_start(core);
-}
-
-static void cx88_ir_close(struct rc_dev *rc)
-{
- struct cx88_core *core = rc->priv;
-
- core->ir->users--;
- if (!core->ir->users)
- __cx88_ir_stop(core);
-}
-
-/* ---------------------------------------------------------------------- */
-
-int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
-{
- struct cx88_IR *ir;
- struct rc_dev *dev;
- char *ir_codes = NULL;
- u64 rc_type = RC_TYPE_OTHER;
- int err = -ENOMEM;
- u32 hardware_mask = 0; /* For devices with a hardware mask, when
- * used with a full-code IR table
- */
-
- ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- dev = rc_allocate_device();
- if (!ir || !dev)
- goto err_out_free;
-
- ir->dev = dev;
-
- /* detect & configure */
- switch (core->boardnr) {
- case CX88_BOARD_DNTV_LIVE_DVB_T:
- case CX88_BOARD_KWORLD_DVB_T:
- case CX88_BOARD_KWORLD_DVB_T_CX22702:
- ir_codes = RC_MAP_DNTV_LIVE_DVB_T;
- ir->gpio_addr = MO_GP1_IO;
- ir->mask_keycode = 0x1f;
- ir->mask_keyup = 0x60;
- ir->polling = 50; /* ms */
- break;
- case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
- ir_codes = RC_MAP_CINERGY_1400;
- ir->sampling = 0xeb04; /* address */
- break;
- case CX88_BOARD_HAUPPAUGE:
- case CX88_BOARD_HAUPPAUGE_DVB_T1:
- case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
- case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
- case CX88_BOARD_HAUPPAUGE_HVR1100:
- case CX88_BOARD_HAUPPAUGE_HVR3000:
- case CX88_BOARD_HAUPPAUGE_HVR4000:
- case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
- case CX88_BOARD_PCHDTV_HD3000:
- case CX88_BOARD_PCHDTV_HD5500:
- case CX88_BOARD_HAUPPAUGE_IRONLY:
- ir_codes = RC_MAP_HAUPPAUGE;
- ir->sampling = 1;
- break;
- case CX88_BOARD_WINFAST_DTV2000H:
- case CX88_BOARD_WINFAST_DTV2000H_J:
- case CX88_BOARD_WINFAST_DTV1800H:
- case CX88_BOARD_WINFAST_DTV1800H_XC4000:
- case CX88_BOARD_WINFAST_DTV2000H_PLUS:
- ir_codes = RC_MAP_WINFAST;
- ir->gpio_addr = MO_GP0_IO;
- ir->mask_keycode = 0x8f8;
- ir->mask_keyup = 0x100;
- ir->polling = 50; /* ms */
- break;
- case CX88_BOARD_WINFAST2000XP_EXPERT:
- case CX88_BOARD_WINFAST_DTV1000:
- case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
- case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36:
- case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43:
- ir_codes = RC_MAP_WINFAST;
- ir->gpio_addr = MO_GP0_IO;
- ir->mask_keycode = 0x8f8;
- ir->mask_keyup = 0x100;
- ir->polling = 1; /* ms */
- break;
- case CX88_BOARD_IODATA_GVBCTV7E:
- ir_codes = RC_MAP_IODATA_BCTV7E;
- ir->gpio_addr = MO_GP0_IO;
- ir->mask_keycode = 0xfd;
- ir->mask_keydown = 0x02;
- ir->polling = 5; /* ms */
- break;
- case CX88_BOARD_PROLINK_PLAYTVPVR:
- case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO:
- /*
- * It seems that this hardware is paired with NEC extended
- * address 0x866b. So, unfortunately, its usage with other
- * IR's with different address won't work. Still, there are
- * other IR's from the same manufacturer that works, like the
- * 002-T mini RC, provided with newer PV hardware
- */
- ir_codes = RC_MAP_PIXELVIEW_MK12;
- ir->gpio_addr = MO_GP1_IO;
- ir->mask_keyup = 0x80;
- ir->polling = 10; /* ms */
- hardware_mask = 0x3f; /* Hardware returns only 6 bits from command part */
- break;
- case CX88_BOARD_PROLINK_PV_8000GT:
- case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
- ir_codes = RC_MAP_PIXELVIEW_NEW;
- ir->gpio_addr = MO_GP1_IO;
- ir->mask_keycode = 0x3f;
- ir->mask_keyup = 0x80;
- ir->polling = 1; /* ms */
- break;
- case CX88_BOARD_KWORLD_LTV883:
- ir_codes = RC_MAP_PIXELVIEW;
- ir->gpio_addr = MO_GP1_IO;
- ir->mask_keycode = 0x1f;
- ir->mask_keyup = 0x60;
- ir->polling = 1; /* ms */
- break;
- case CX88_BOARD_ADSTECH_DVB_T_PCI:
- ir_codes = RC_MAP_ADSTECH_DVB_T_PCI;
- ir->gpio_addr = MO_GP1_IO;
- ir->mask_keycode = 0xbf;
- ir->mask_keyup = 0x40;
- ir->polling = 50; /* ms */
- break;
- case CX88_BOARD_MSI_TVANYWHERE_MASTER:
- ir_codes = RC_MAP_MSI_TVANYWHERE;
- ir->gpio_addr = MO_GP1_IO;
- ir->mask_keycode = 0x1f;
- ir->mask_keyup = 0x40;
- ir->polling = 1; /* ms */
- break;
- case CX88_BOARD_AVERTV_303:
- case CX88_BOARD_AVERTV_STUDIO_303:
- ir_codes = RC_MAP_AVERTV_303;
- ir->gpio_addr = MO_GP2_IO;
- ir->mask_keycode = 0xfb;
- ir->mask_keydown = 0x02;
- ir->polling = 50; /* ms */
- break;
- case CX88_BOARD_OMICOM_SS4_PCI:
- case CX88_BOARD_SATTRADE_ST4200:
- case CX88_BOARD_TBS_8920:
- case CX88_BOARD_TBS_8910:
- case CX88_BOARD_PROF_7300:
- case CX88_BOARD_PROF_7301:
- case CX88_BOARD_PROF_6200:
- ir_codes = RC_MAP_TBS_NEC;
- ir->sampling = 0xff00; /* address */
- break;
- case CX88_BOARD_TEVII_S464:
- case CX88_BOARD_TEVII_S460:
- case CX88_BOARD_TEVII_S420:
- ir_codes = RC_MAP_TEVII_NEC;
- ir->sampling = 0xff00; /* address */
- break;
- case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
- ir_codes = RC_MAP_DNTV_LIVE_DVBT_PRO;
- ir->sampling = 0xff00; /* address */
- break;
- case CX88_BOARD_NORWOOD_MICRO:
- ir_codes = RC_MAP_NORWOOD;
- ir->gpio_addr = MO_GP1_IO;
- ir->mask_keycode = 0x0e;
- ir->mask_keyup = 0x80;
- ir->polling = 50; /* ms */
- break;
- case CX88_BOARD_NPGTECH_REALTV_TOP10FM:
- ir_codes = RC_MAP_NPGTECH;
- ir->gpio_addr = MO_GP0_IO;
- ir->mask_keycode = 0xfa;
- ir->polling = 50; /* ms */
- break;
- case CX88_BOARD_PINNACLE_PCTV_HD_800i:
- ir_codes = RC_MAP_PINNACLE_PCTV_HD;
- ir->sampling = 1;
- break;
- case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
- ir_codes = RC_MAP_POWERCOLOR_REAL_ANGEL;
- ir->gpio_addr = MO_GP2_IO;
- ir->mask_keycode = 0x7e;
- ir->polling = 100; /* ms */
- break;
- case CX88_BOARD_TWINHAN_VP1027_DVBS:
- ir_codes = RC_MAP_TWINHAN_VP1027_DVBS;
- rc_type = RC_TYPE_NEC;
- ir->sampling = 0xff00; /* address */
- break;
- }
-
- if (!ir_codes) {
- err = -ENODEV;
- goto err_out_free;
- }
-
- /*
- * The usage of mask_keycode were very convenient, due to several
- * reasons. Among others, the scancode tables were using the scancode
- * as the index elements. So, the less bits it was used, the smaller
- * the table were stored. After the input changes, the better is to use
- * the full scancodes, since it allows replacing the IR remote by
- * another one. Unfortunately, there are still some hardware, like
- * Pixelview Ultra Pro, where only part of the scancode is sent via
- * GPIO. So, there's no way to get the full scancode. Due to that,
- * hardware_mask were introduced here: it represents those hardware
- * that has such limits.
- */
- if (hardware_mask && !ir->mask_keycode)
- ir->mask_keycode = hardware_mask;
-
- /* init input device */
- snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
- snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
-
- dev->input_name = ir->name;
- dev->input_phys = ir->phys;
- dev->input_id.bustype = BUS_PCI;
- dev->input_id.version = 1;
- if (pci->subsystem_vendor) {
- dev->input_id.vendor = pci->subsystem_vendor;
- dev->input_id.product = pci->subsystem_device;
- } else {
- dev->input_id.vendor = pci->vendor;
- dev->input_id.product = pci->device;
- }
- dev->dev.parent = &pci->dev;
- dev->map_name = ir_codes;
- dev->driver_name = MODULE_NAME;
- dev->priv = core;
- dev->open = cx88_ir_open;
- dev->close = cx88_ir_close;
- dev->scanmask = hardware_mask;
-
- if (ir->sampling) {
- dev->driver_type = RC_DRIVER_IR_RAW;
- dev->timeout = 10 * 1000 * 1000; /* 10 ms */
- } else {
- dev->driver_type = RC_DRIVER_SCANCODE;
- dev->allowed_protos = rc_type;
- }
-
- ir->core = core;
- core->ir = ir;
-
- /* all done */
- err = rc_register_device(dev);
- if (err)
- goto err_out_free;
-
- return 0;
-
-err_out_free:
- rc_free_device(dev);
- core->ir = NULL;
- kfree(ir);
- return err;
-}
-
-int cx88_ir_fini(struct cx88_core *core)
-{
- struct cx88_IR *ir = core->ir;
-
- /* skip detach on non attached boards */
- if (NULL == ir)
- return 0;
-
- cx88_ir_stop(core);
- rc_unregister_device(ir->dev);
- kfree(ir);
-
- /* done */
- core->ir = NULL;
- return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-void cx88_ir_irq(struct cx88_core *core)
-{
- struct cx88_IR *ir = core->ir;
- u32 samples;
- unsigned todo, bits;
- struct ir_raw_event ev;
-
- if (!ir || !ir->sampling)
- return;
-
- /*
- * Samples are stored in a 32 bit register, oldest sample in
- * the msb. A set bit represents space and an unset bit
- * represents a pulse.
- */
- samples = cx_read(MO_SAMPLE_IO);
-
- if (samples == 0xff && ir->dev->idle)
- return;
-
- init_ir_raw_event(&ev);
- for (todo = 32; todo > 0; todo -= bits) {
- ev.pulse = samples & 0x80000000 ? false : true;
- bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples));
- ev.duration = (bits * (NSEC_PER_SEC / 1000)) / ir_samplerate;
- ir_raw_event_store_with_filter(ir->dev, &ev);
- samples <<= bits;
- }
- ir_raw_event_handle(ir->dev);
-}
-
-static int get_key_pvr2000(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- int flags, code;
-
- /* poll IR chip */
- flags = i2c_smbus_read_byte_data(ir->c, 0x10);
- if (flags < 0) {
- dprintk("read error\n");
- return 0;
- }
- /* key pressed ? */
- if (0 == (flags & 0x80))
- return 0;
-
- /* read actual key code */
- code = i2c_smbus_read_byte_data(ir->c, 0x00);
- if (code < 0) {
- dprintk("read error\n");
- return 0;
- }
-
- dprintk("IR Key/Flags: (0x%02x/0x%02x)\n",
- code & 0xff, flags & 0xff);
-
- *ir_key = code & 0xff;
- *ir_raw = code;
- return 1;
-}
-
-void cx88_i2c_init_ir(struct cx88_core *core)
-{
- struct i2c_board_info info;
- const unsigned short default_addr_list[] = {
- 0x18, 0x6b, 0x71,
- I2C_CLIENT_END
- };
- const unsigned short pvr2000_addr_list[] = {
- 0x18, 0x1a,
- I2C_CLIENT_END
- };
- const unsigned short *addr_list = default_addr_list;
- const unsigned short *addrp;
- /* Instantiate the IR receiver device, if present */
- if (0 != core->i2c_rc)
- return;
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
-
- switch (core->boardnr) {
- case CX88_BOARD_LEADTEK_PVR2000:
- addr_list = pvr2000_addr_list;
- core->init_data.name = "cx88 Leadtek PVR 2000 remote";
- core->init_data.type = RC_TYPE_UNKNOWN;
- core->init_data.get_key = get_key_pvr2000;
- core->init_data.ir_codes = RC_MAP_EMPTY;
- break;
- }
-
- /*
- * We can't call i2c_new_probed_device() because it uses
- * quick writes for probing and at least some RC receiver
- * devices only reply to reads.
- * Also, Hauppauge XVR needs to be specified, as address 0x71
- * conflicts with another remote type used with saa7134
- */
- for (addrp = addr_list; *addrp != I2C_CLIENT_END; addrp++) {
- info.platform_data = NULL;
- memset(&core->init_data, 0, sizeof(core->init_data));
-
- if (*addrp == 0x71) {
- /* Hauppauge XVR */
- core->init_data.name = "cx88 Hauppauge XVR remote";
- core->init_data.ir_codes = RC_MAP_HAUPPAUGE;
- core->init_data.type = RC_TYPE_RC5;
- core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
-
- info.platform_data = &core->init_data;
- }
- if (i2c_smbus_xfer(&core->i2c_adap, *addrp, 0,
- I2C_SMBUS_READ, 0,
- I2C_SMBUS_QUICK, NULL) >= 0) {
- info.addr = *addrp;
- i2c_new_device(&core->i2c_adap, &info);
- break;
- }
- }
-}
-
-/* ---------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Gerd Knorr, Pavel Machek, Chris Pascoe");
-MODULE_DESCRIPTION("input driver for cx88 GPIO-based IR remote controls");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
deleted file mode 100644
index c04fb618e10..00000000000
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ /dev/null
@@ -1,929 +0,0 @@
-/*
- *
- * Support for the mpeg transport stream transfers
- * PCI function #2 of the cx2388x.
- *
- * (c) 2004 Jelle Foks <jelle@foks.us>
- * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
- * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-#include <asm/delay.h>
-
-#include "cx88.h"
-
-/* ------------------------------------------------------------------ */
-
-MODULE_DESCRIPTION("mpeg driver for cx2388x based TV cards");
-MODULE_AUTHOR("Jelle Foks <jelle@foks.us>");
-MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(CX88_VERSION);
-
-static unsigned int debug;
-module_param(debug,int,0644);
-MODULE_PARM_DESC(debug,"enable debug messages [mpeg]");
-
-#define dprintk(level,fmt, arg...) if (debug >= level) \
- printk(KERN_DEBUG "%s/2-mpeg: " fmt, dev->core->name, ## arg)
-
-#define mpeg_dbg(level,fmt, arg...) if (debug >= level) \
- printk(KERN_DEBUG "%s/2-mpeg: " fmt, core->name, ## arg)
-
-#if defined(CONFIG_MODULES) && defined(MODULE)
-static void request_module_async(struct work_struct *work)
-{
- struct cx8802_dev *dev=container_of(work, struct cx8802_dev, request_module_wk);
-
- if (dev->core->board.mpeg & CX88_MPEG_DVB)
- request_module("cx88-dvb");
- if (dev->core->board.mpeg & CX88_MPEG_BLACKBIRD)
- request_module("cx88-blackbird");
-}
-
-static void request_modules(struct cx8802_dev *dev)
-{
- INIT_WORK(&dev->request_module_wk, request_module_async);
- schedule_work(&dev->request_module_wk);
-}
-
-static void flush_request_modules(struct cx8802_dev *dev)
-{
- flush_work(&dev->request_module_wk);
-}
-#else
-#define request_modules(dev)
-#define flush_request_modules(dev)
-#endif /* CONFIG_MODULES */
-
-
-static LIST_HEAD(cx8802_devlist);
-static DEFINE_MUTEX(cx8802_mutex);
-/* ------------------------------------------------------------------ */
-
-static int cx8802_start_dma(struct cx8802_dev *dev,
- struct cx88_dmaqueue *q,
- struct cx88_buffer *buf)
-{
- struct cx88_core *core = dev->core;
-
- dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n",
- buf->vb.width, buf->vb.height, buf->vb.field);
-
- /* setup fifo + format */
- cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
- dev->ts_packet_size, buf->risc.dma);
-
- /* write TS length to chip */
- cx_write(MO_TS_LNGTH, buf->vb.width);
-
- /* FIXME: this needs a review.
- * also: move to cx88-blackbird + cx88-dvb source files? */
-
- dprintk( 1, "core->active_type_id = 0x%08x\n", core->active_type_id);
-
- if ( (core->active_type_id == CX88_MPEG_DVB) &&
- (core->board.mpeg & CX88_MPEG_DVB) ) {
-
- dprintk( 1, "cx8802_start_dma doing .dvb\n");
- /* negedge driven & software reset */
- cx_write(TS_GEN_CNTRL, 0x0040 | dev->ts_gen_cntrl);
- udelay(100);
- cx_write(MO_PINMUX_IO, 0x00);
- cx_write(TS_HW_SOP_CNTRL, 0x47<<16|188<<4|0x01);
- switch (core->boardnr) {
- case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
- case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
- case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
- case CX88_BOARD_PCHDTV_HD5500:
- cx_write(TS_SOP_STAT, 1<<13);
- break;
- case CX88_BOARD_SAMSUNG_SMT_7020:
- cx_write(TS_SOP_STAT, 0x00);
- break;
- case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
- case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
- cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */
- udelay(100);
- break;
- case CX88_BOARD_HAUPPAUGE_HVR1300:
- /* Enable MPEG parallel IO and video signal pins */
- cx_write(MO_PINMUX_IO, 0x88);
- cx_write(TS_SOP_STAT, 0);
- cx_write(TS_VALERR_CNTRL, 0);
- break;
- case CX88_BOARD_PINNACLE_PCTV_HD_800i:
- /* Enable MPEG parallel IO and video signal pins */
- cx_write(MO_PINMUX_IO, 0x88);
- cx_write(TS_HW_SOP_CNTRL, (0x47 << 16) | (188 << 4));
- dev->ts_gen_cntrl = 5;
- cx_write(TS_SOP_STAT, 0);
- cx_write(TS_VALERR_CNTRL, 0);
- udelay(100);
- break;
- default:
- cx_write(TS_SOP_STAT, 0x00);
- break;
- }
- cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
- udelay(100);
- } else if ( (core->active_type_id == CX88_MPEG_BLACKBIRD) &&
- (core->board.mpeg & CX88_MPEG_BLACKBIRD) ) {
- dprintk( 1, "cx8802_start_dma doing .blackbird\n");
- cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */
-
- cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */
- udelay(100);
-
- cx_write(TS_HW_SOP_CNTRL, 0x408); /* mpeg start byte */
- cx_write(TS_VALERR_CNTRL, 0x2000);
-
- cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */
- udelay(100);
- } else {
- printk( "%s() Failed. Unsupported value in .mpeg (0x%08x)\n", __func__,
- core->board.mpeg );
- return -EINVAL;
- }
-
- /* reset counter */
- cx_write(MO_TS_GPCNTRL, GP_COUNT_CONTROL_RESET);
- q->count = 1;
-
- /* enable irqs */
- dprintk( 1, "setting the interrupt mask\n" );
- cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_TSINT);
- cx_set(MO_TS_INTMSK, 0x1f0011);
-
- /* start dma */
- cx_set(MO_DEV_CNTRL2, (1<<5));
- cx_set(MO_TS_DMACNTRL, 0x11);
- return 0;
-}
-
-static int cx8802_stop_dma(struct cx8802_dev *dev)
-{
- struct cx88_core *core = dev->core;
- dprintk( 1, "cx8802_stop_dma\n" );
-
- /* stop dma */
- cx_clear(MO_TS_DMACNTRL, 0x11);
-
- /* disable irqs */
- cx_clear(MO_PCI_INTMSK, PCI_INT_TSINT);
- cx_clear(MO_TS_INTMSK, 0x1f0011);
-
- /* Reset the controller */
- cx_write(TS_GEN_CNTRL, 0xcd);
- return 0;
-}
-
-static int cx8802_restart_queue(struct cx8802_dev *dev,
- struct cx88_dmaqueue *q)
-{
- struct cx88_buffer *buf;
-
- dprintk( 1, "cx8802_restart_queue\n" );
- if (list_empty(&q->active))
- {
- struct cx88_buffer *prev;
- prev = NULL;
-
- dprintk(1, "cx8802_restart_queue: queue is empty\n" );
-
- for (;;) {
- if (list_empty(&q->queued))
- return 0;
- buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
- if (NULL == prev) {
- list_del(&buf->vb.queue);
- list_add_tail(&buf->vb.queue,&q->active);
- cx8802_start_dma(dev, q, buf);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- dprintk(1,"[%p/%d] restart_queue - first active\n",
- buf,buf->vb.i);
-
- } else if (prev->vb.width == buf->vb.width &&
- prev->vb.height == buf->vb.height &&
- prev->fmt == buf->fmt) {
- list_del(&buf->vb.queue);
- list_add_tail(&buf->vb.queue,&q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- dprintk(1,"[%p/%d] restart_queue - move to active\n",
- buf,buf->vb.i);
- } else {
- return 0;
- }
- prev = buf;
- }
- return 0;
- }
-
- buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
- dprintk(2,"restart_queue [%p/%d]: restart dma\n",
- buf, buf->vb.i);
- cx8802_start_dma(dev, q, buf);
- list_for_each_entry(buf, &q->active, vb.queue)
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev,
- struct cx88_buffer *buf, enum v4l2_field field)
-{
- int size = dev->ts_packet_size * dev->ts_packet_count;
- struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
- int rc;
-
- dprintk(1, "%s: %p\n", __func__, buf);
- if (0 != buf->vb.baddr && buf->vb.bsize < size)
- return -EINVAL;
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- buf->vb.width = dev->ts_packet_size;
- buf->vb.height = dev->ts_packet_count;
- buf->vb.size = size;
- buf->vb.field = field /*V4L2_FIELD_TOP*/;
-
- if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
- goto fail;
- cx88_risc_databuffer(dev->pci, &buf->risc,
- dma->sglist,
- buf->vb.width, buf->vb.height, 0);
- }
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
- fail:
- cx88_free_buffer(q,buf);
- return rc;
-}
-
-void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
-{
- struct cx88_buffer *prev;
- struct cx88_dmaqueue *cx88q = &dev->mpegq;
-
- dprintk( 1, "cx8802_buf_queue\n" );
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma);
-
- if (list_empty(&cx88q->active)) {
- dprintk( 1, "queue is empty - first active\n" );
- list_add_tail(&buf->vb.queue,&cx88q->active);
- cx8802_start_dma(dev, cx88q, buf);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = cx88q->count++;
- mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT);
- dprintk(1,"[%p/%d] %s - first active\n",
- buf, buf->vb.i, __func__);
-
- } else {
- dprintk( 1, "queue is not empty - append to active\n" );
- prev = list_entry(cx88q->active.prev, struct cx88_buffer, vb.queue);
- list_add_tail(&buf->vb.queue,&cx88q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = cx88q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- dprintk( 1, "[%p/%d] %s - append to active\n",
- buf, buf->vb.i, __func__);
- }
-}
-
-/* ----------------------------------------------------------- */
-
-static void do_cancel_buffers(struct cx8802_dev *dev, const char *reason, int restart)
-{
- struct cx88_dmaqueue *q = &dev->mpegq;
- struct cx88_buffer *buf;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->slock,flags);
- while (!list_empty(&q->active)) {
- buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
- list_del(&buf->vb.queue);
- buf->vb.state = VIDEOBUF_ERROR;
- wake_up(&buf->vb.done);
- dprintk(1,"[%p/%d] %s - dma=0x%08lx\n",
- buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
- }
- if (restart)
- {
- dprintk(1, "restarting queue\n" );
- cx8802_restart_queue(dev,q);
- }
- spin_unlock_irqrestore(&dev->slock,flags);
-}
-
-void cx8802_cancel_buffers(struct cx8802_dev *dev)
-{
- struct cx88_dmaqueue *q = &dev->mpegq;
-
- dprintk( 1, "cx8802_cancel_buffers" );
- del_timer_sync(&q->timeout);
- cx8802_stop_dma(dev);
- do_cancel_buffers(dev,"cancel",0);
-}
-
-static void cx8802_timeout(unsigned long data)
-{
- struct cx8802_dev *dev = (struct cx8802_dev*)data;
-
- dprintk(1, "%s\n",__func__);
-
- if (debug)
- cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
- cx8802_stop_dma(dev);
- do_cancel_buffers(dev,"timeout",1);
-}
-
-static const char * cx88_mpeg_irqs[32] = {
- "ts_risci1", NULL, NULL, NULL,
- "ts_risci2", NULL, NULL, NULL,
- "ts_oflow", NULL, NULL, NULL,
- "ts_sync", NULL, NULL, NULL,
- "opc_err", "par_err", "rip_err", "pci_abort",
- "ts_err?",
-};
-
-static void cx8802_mpeg_irq(struct cx8802_dev *dev)
-{
- struct cx88_core *core = dev->core;
- u32 status, mask, count;
-
- dprintk( 1, "cx8802_mpeg_irq\n" );
- status = cx_read(MO_TS_INTSTAT);
- mask = cx_read(MO_TS_INTMSK);
- if (0 == (status & mask))
- return;
-
- cx_write(MO_TS_INTSTAT, status);
-
- if (debug || (status & mask & ~0xff))
- cx88_print_irqbits(core->name, "irq mpeg ",
- cx88_mpeg_irqs, ARRAY_SIZE(cx88_mpeg_irqs),
- status, mask);
-
- /* risc op code error */
- if (status & (1 << 16)) {
- printk(KERN_WARNING "%s: mpeg risc op code error\n",core->name);
- cx_clear(MO_TS_DMACNTRL, 0x11);
- cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
- }
-
- /* risc1 y */
- if (status & 0x01) {
- dprintk( 1, "wake up\n" );
- spin_lock(&dev->slock);
- count = cx_read(MO_TS_GPCNT);
- cx88_wakeup(dev->core, &dev->mpegq, count);
- spin_unlock(&dev->slock);
- }
-
- /* risc2 y */
- if (status & 0x10) {
- spin_lock(&dev->slock);
- cx8802_restart_queue(dev,&dev->mpegq);
- spin_unlock(&dev->slock);
- }
-
- /* other general errors */
- if (status & 0x1f0100) {
- dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
- spin_lock(&dev->slock);
- cx8802_stop_dma(dev);
- cx8802_restart_queue(dev,&dev->mpegq);
- spin_unlock(&dev->slock);
- }
-}
-
-#define MAX_IRQ_LOOP 10
-
-static irqreturn_t cx8802_irq(int irq, void *dev_id)
-{
- struct cx8802_dev *dev = dev_id;
- struct cx88_core *core = dev->core;
- u32 status;
- int loop, handled = 0;
-
- for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
- status = cx_read(MO_PCI_INTSTAT) &
- (core->pci_irqmask | PCI_INT_TSINT);
- if (0 == status)
- goto out;
- dprintk( 1, "cx8802_irq\n" );
- dprintk( 1, " loop: %d/%d\n", loop, MAX_IRQ_LOOP );
- dprintk( 1, " status: %d\n", status );
- handled = 1;
- cx_write(MO_PCI_INTSTAT, status);
-
- if (status & core->pci_irqmask)
- cx88_core_irq(core,status);
- if (status & PCI_INT_TSINT)
- cx8802_mpeg_irq(dev);
- };
- if (MAX_IRQ_LOOP == loop) {
- dprintk( 0, "clearing mask\n" );
- printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
- core->name);
- cx_write(MO_PCI_INTMSK,0);
- }
-
- out:
- return IRQ_RETVAL(handled);
-}
-
-static int cx8802_init_common(struct cx8802_dev *dev)
-{
- struct cx88_core *core = dev->core;
- int err;
-
- /* pci init */
- if (pci_enable_device(dev->pci))
- return -EIO;
- pci_set_master(dev->pci);
- if (!pci_dma_supported(dev->pci,DMA_BIT_MASK(32))) {
- printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name);
- return -EIO;
- }
-
- dev->pci_rev = dev->pci->revision;
- pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat);
- printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
- "latency: %d, mmio: 0x%llx\n", dev->core->name,
- pci_name(dev->pci), dev->pci_rev, dev->pci->irq,
- dev->pci_lat,(unsigned long long)pci_resource_start(dev->pci,0));
-
- /* initialize driver struct */
- spin_lock_init(&dev->slock);
-
- /* init dma queue */
- INIT_LIST_HEAD(&dev->mpegq.active);
- INIT_LIST_HEAD(&dev->mpegq.queued);
- dev->mpegq.timeout.function = cx8802_timeout;
- dev->mpegq.timeout.data = (unsigned long)dev;
- init_timer(&dev->mpegq.timeout);
- cx88_risc_stopper(dev->pci,&dev->mpegq.stopper,
- MO_TS_DMACNTRL,0x11,0x00);
-
- /* get irq */
- err = request_irq(dev->pci->irq, cx8802_irq,
- IRQF_SHARED | IRQF_DISABLED, dev->core->name, dev);
- if (err < 0) {
- printk(KERN_ERR "%s: can't get IRQ %d\n",
- dev->core->name, dev->pci->irq);
- return err;
- }
- cx_set(MO_PCI_INTMSK, core->pci_irqmask);
-
- /* everything worked */
- pci_set_drvdata(dev->pci,dev);
- return 0;
-}
-
-static void cx8802_fini_common(struct cx8802_dev *dev)
-{
- dprintk( 2, "cx8802_fini_common\n" );
- cx8802_stop_dma(dev);
- pci_disable_device(dev->pci);
-
- /* unregister stuff */
- free_irq(dev->pci->irq, dev);
- pci_set_drvdata(dev->pci, NULL);
-
- /* free memory */
- btcx_riscmem_free(dev->pci,&dev->mpegq.stopper);
-}
-
-/* ----------------------------------------------------------- */
-
-static int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
-{
- struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
- struct cx88_core *core = dev->core;
-
- /* stop mpeg dma */
- spin_lock(&dev->slock);
- if (!list_empty(&dev->mpegq.active)) {
- dprintk( 2, "suspend\n" );
- printk("%s: suspend mpeg\n", core->name);
- cx8802_stop_dma(dev);
- del_timer(&dev->mpegq.timeout);
- }
- spin_unlock(&dev->slock);
-
- /* FIXME -- shutdown device */
- cx88_shutdown(dev->core);
-
- pci_save_state(pci_dev);
- if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
- pci_disable_device(pci_dev);
- dev->state.disabled = 1;
- }
- return 0;
-}
-
-static int cx8802_resume_common(struct pci_dev *pci_dev)
-{
- struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
- struct cx88_core *core = dev->core;
- int err;
-
- if (dev->state.disabled) {
- err=pci_enable_device(pci_dev);
- if (err) {
- printk(KERN_ERR "%s: can't enable device\n",
- dev->core->name);
- return err;
- }
- dev->state.disabled = 0;
- }
- err=pci_set_power_state(pci_dev, PCI_D0);
- if (err) {
- printk(KERN_ERR "%s: can't enable device\n",
- dev->core->name);
- pci_disable_device(pci_dev);
- dev->state.disabled = 1;
-
- return err;
- }
- pci_restore_state(pci_dev);
-
- /* FIXME: re-initialize hardware */
- cx88_reset(dev->core);
-
- /* restart video+vbi capture */
- spin_lock(&dev->slock);
- if (!list_empty(&dev->mpegq.active)) {
- printk("%s: resume mpeg\n", core->name);
- cx8802_restart_queue(dev,&dev->mpegq);
- }
- spin_unlock(&dev->slock);
-
- return 0;
-}
-
-struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype)
-{
- struct cx8802_driver *d;
-
- list_for_each_entry(d, &dev->drvlist, drvlist)
- if (d->type_id == btype)
- return d;
-
- return NULL;
-}
-
-/* Driver asked for hardware access. */
-static int cx8802_request_acquire(struct cx8802_driver *drv)
-{
- struct cx88_core *core = drv->core;
- unsigned int i;
-
- /* Fail a request for hardware if the device is busy. */
- if (core->active_type_id != CX88_BOARD_NONE &&
- core->active_type_id != drv->type_id)
- return -EBUSY;
-
- if (drv->type_id == CX88_MPEG_DVB) {
- /* When switching to DVB, always set the input to the tuner */
- core->last_analog_input = core->input;
- core->input = 0;
- for (i = 0;
- i < (sizeof(core->board.input) / sizeof(struct cx88_input));
- i++) {
- if (core->board.input[i].type == CX88_VMUX_DVB) {
- core->input = i;
- break;
- }
- }
- }
-
- if (drv->advise_acquire)
- {
- core->active_ref++;
- if (core->active_type_id == CX88_BOARD_NONE) {
- core->active_type_id = drv->type_id;
- drv->advise_acquire(drv);
- }
-
- mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO));
- }
-
- return 0;
-}
-
-/* Driver asked to release hardware. */
-static int cx8802_request_release(struct cx8802_driver *drv)
-{
- struct cx88_core *core = drv->core;
-
- if (drv->advise_release && --core->active_ref == 0)
- {
- if (drv->type_id == CX88_MPEG_DVB) {
- /* If the DVB driver is releasing, reset the input
- state to the last configured analog input */
- core->input = core->last_analog_input;
- }
-
- drv->advise_release(drv);
- core->active_type_id = CX88_BOARD_NONE;
- mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO));
- }
-
- return 0;
-}
-
-static int cx8802_check_driver(struct cx8802_driver *drv)
-{
- if (drv == NULL)
- return -ENODEV;
-
- if ((drv->type_id != CX88_MPEG_DVB) &&
- (drv->type_id != CX88_MPEG_BLACKBIRD))
- return -EINVAL;
-
- if ((drv->hw_access != CX8802_DRVCTL_SHARED) &&
- (drv->hw_access != CX8802_DRVCTL_EXCLUSIVE))
- return -EINVAL;
-
- if ((drv->probe == NULL) ||
- (drv->remove == NULL) ||
- (drv->advise_acquire == NULL) ||
- (drv->advise_release == NULL))
- return -EINVAL;
-
- return 0;
-}
-
-int cx8802_register_driver(struct cx8802_driver *drv)
-{
- struct cx8802_dev *dev;
- struct cx8802_driver *driver;
- int err, i = 0;
-
- printk(KERN_INFO
- "cx88/2: registering cx8802 driver, type: %s access: %s\n",
- drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
- drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
-
- if ((err = cx8802_check_driver(drv)) != 0) {
- printk(KERN_ERR "cx88/2: cx8802_driver is invalid\n");
- return err;
- }
-
- mutex_lock(&cx8802_mutex);
-
- list_for_each_entry(dev, &cx8802_devlist, devlist) {
- printk(KERN_INFO
- "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
- dev->core->name, dev->pci->subsystem_vendor,
- dev->pci->subsystem_device, dev->core->board.name,
- dev->core->boardnr);
-
- /* Bring up a new struct for each driver instance */
- driver = kzalloc(sizeof(*drv),GFP_KERNEL);
- if (driver == NULL) {
- err = -ENOMEM;
- goto out;
- }
-
- /* Snapshot of the driver registration data */
- drv->core = dev->core;
- drv->suspend = cx8802_suspend_common;
- drv->resume = cx8802_resume_common;
- drv->request_acquire = cx8802_request_acquire;
- drv->request_release = cx8802_request_release;
- memcpy(driver, drv, sizeof(*driver));
-
- mutex_lock(&drv->core->lock);
- err = drv->probe(driver);
- if (err == 0) {
- i++;
- list_add_tail(&driver->drvlist, &dev->drvlist);
- } else {
- printk(KERN_ERR
- "%s/2: cx8802 probe failed, err = %d\n",
- dev->core->name, err);
- }
- mutex_unlock(&drv->core->lock);
- }
-
- err = i ? 0 : -ENODEV;
-out:
- mutex_unlock(&cx8802_mutex);
- return err;
-}
-
-int cx8802_unregister_driver(struct cx8802_driver *drv)
-{
- struct cx8802_dev *dev;
- struct cx8802_driver *d, *dtmp;
- int err = 0;
-
- printk(KERN_INFO
- "cx88/2: unregistering cx8802 driver, type: %s access: %s\n",
- drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
- drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
-
- mutex_lock(&cx8802_mutex);
-
- list_for_each_entry(dev, &cx8802_devlist, devlist) {
- printk(KERN_INFO
- "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
- dev->core->name, dev->pci->subsystem_vendor,
- dev->pci->subsystem_device, dev->core->board.name,
- dev->core->boardnr);
-
- mutex_lock(&dev->core->lock);
-
- list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) {
- /* only unregister the correct driver type */
- if (d->type_id != drv->type_id)
- continue;
-
- err = d->remove(d);
- if (err == 0) {
- list_del(&d->drvlist);
- kfree(d);
- } else
- printk(KERN_ERR "%s/2: cx8802 driver remove "
- "failed (%d)\n", dev->core->name, err);
- }
-
- mutex_unlock(&dev->core->lock);
- }
-
- mutex_unlock(&cx8802_mutex);
-
- return err;
-}
-
-/* ----------------------------------------------------------- */
-static int __devinit cx8802_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
-{
- struct cx8802_dev *dev;
- struct cx88_core *core;
- int err;
-
- /* general setup */
- core = cx88_core_get(pci_dev);
- if (NULL == core)
- return -EINVAL;
-
- printk("%s/2: cx2388x 8802 Driver Manager\n", core->name);
-
- err = -ENODEV;
- if (!core->board.mpeg)
- goto fail_core;
-
- err = -ENOMEM;
- dev = kzalloc(sizeof(*dev),GFP_KERNEL);
- if (NULL == dev)
- goto fail_core;
- dev->pci = pci_dev;
- dev->core = core;
-
- /* Maintain a reference so cx88-video can query the 8802 device. */
- core->dvbdev = dev;
-
- err = cx8802_init_common(dev);
- if (err != 0)
- goto fail_free;
-
- INIT_LIST_HEAD(&dev->drvlist);
- mutex_lock(&cx8802_mutex);
- list_add_tail(&dev->devlist,&cx8802_devlist);
- mutex_unlock(&cx8802_mutex);
-
- /* now autoload cx88-dvb or cx88-blackbird */
- request_modules(dev);
- return 0;
-
- fail_free:
- kfree(dev);
- fail_core:
- core->dvbdev = NULL;
- cx88_core_put(core,pci_dev);
- return err;
-}
-
-static void __devexit cx8802_remove(struct pci_dev *pci_dev)
-{
- struct cx8802_dev *dev;
-
- dev = pci_get_drvdata(pci_dev);
-
- dprintk( 1, "%s\n", __func__);
-
- flush_request_modules(dev);
-
- mutex_lock(&dev->core->lock);
-
- if (!list_empty(&dev->drvlist)) {
- struct cx8802_driver *drv, *tmp;
- int err;
-
- printk(KERN_WARNING "%s/2: Trying to remove cx8802 driver "
- "while cx8802 sub-drivers still loaded?!\n",
- dev->core->name);
-
- list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) {
- err = drv->remove(drv);
- if (err == 0) {
- list_del(&drv->drvlist);
- } else
- printk(KERN_ERR "%s/2: cx8802 driver remove "
- "failed (%d)\n", dev->core->name, err);
- kfree(drv);
- }
- }
-
- mutex_unlock(&dev->core->lock);
-
- /* Destroy any 8802 reference. */
- dev->core->dvbdev = NULL;
-
- /* common */
- cx8802_fini_common(dev);
- cx88_core_put(dev->core,dev->pci);
- kfree(dev);
-}
-
-static const struct pci_device_id cx8802_pci_tbl[] = {
- {
- .vendor = 0x14f1,
- .device = 0x8802,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- },{
- /* --- end of list --- */
- }
-};
-MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
-
-static struct pci_driver cx8802_pci_driver = {
- .name = "cx88-mpeg driver manager",
- .id_table = cx8802_pci_tbl,
- .probe = cx8802_probe,
- .remove = __devexit_p(cx8802_remove),
-};
-
-static int __init cx8802_init(void)
-{
- printk(KERN_INFO "cx88/2: cx2388x MPEG-TS Driver Manager version %s loaded\n",
- CX88_VERSION);
- return pci_register_driver(&cx8802_pci_driver);
-}
-
-static void __exit cx8802_fini(void)
-{
- pci_unregister_driver(&cx8802_pci_driver);
-}
-
-module_init(cx8802_init);
-module_exit(cx8802_fini);
-EXPORT_SYMBOL(cx8802_buf_prepare);
-EXPORT_SYMBOL(cx8802_buf_queue);
-EXPORT_SYMBOL(cx8802_cancel_buffers);
-
-EXPORT_SYMBOL(cx8802_register_driver);
-EXPORT_SYMBOL(cx8802_unregister_driver);
-EXPORT_SYMBOL(cx8802_get_driver);
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
- */
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
deleted file mode 100644
index 2ec52d1cdea..00000000000
--- a/drivers/media/video/cx88/cx88-reg.h
+++ /dev/null
@@ -1,836 +0,0 @@
-/*
-
- cx88x-hw.h - CX2388x register offsets
-
- Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- 2001 Michael Eskin
- 2002 Yurij Sysoev <yurij@naturesoft.net>
- 2003 Gerd Knorr <kraxel@bytesex.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _CX88_REG_H_
-#define _CX88_REG_H_
-
-/* ---------------------------------------------------------------------- */
-/* PCI IDs and config space */
-
-#ifndef PCI_VENDOR_ID_CONEXANT
-# define PCI_VENDOR_ID_CONEXANT 0x14F1
-#endif
-#ifndef PCI_DEVICE_ID_CX2300_VID
-# define PCI_DEVICE_ID_CX2300_VID 0x8800
-#endif
-
-#define CX88X_DEVCTRL 0x40
-#define CX88X_EN_TBFX 0x02
-#define CX88X_EN_VSFX 0x04
-
-/* ---------------------------------------------------------------------- */
-/* PCI controller registers */
-
-/* Command and Status Register */
-#define F0_CMD_STAT_MM 0x2f0004
-#define F1_CMD_STAT_MM 0x2f0104
-#define F2_CMD_STAT_MM 0x2f0204
-#define F3_CMD_STAT_MM 0x2f0304
-#define F4_CMD_STAT_MM 0x2f0404
-
-/* Device Control #1 */
-#define F0_DEV_CNTRL1_MM 0x2f0040
-#define F1_DEV_CNTRL1_MM 0x2f0140
-#define F2_DEV_CNTRL1_MM 0x2f0240
-#define F3_DEV_CNTRL1_MM 0x2f0340
-#define F4_DEV_CNTRL1_MM 0x2f0440
-
-/* Device Control #1 */
-#define F0_BAR0_MM 0x2f0010
-#define F1_BAR0_MM 0x2f0110
-#define F2_BAR0_MM 0x2f0210
-#define F3_BAR0_MM 0x2f0310
-#define F4_BAR0_MM 0x2f0410
-
-/* ---------------------------------------------------------------------- */
-/* DMA Controller registers */
-
-#define MO_PDMA_STHRSH 0x200000 // Source threshold
-#define MO_PDMA_STADRS 0x200004 // Source target address
-#define MO_PDMA_SIADRS 0x200008 // Source internal address
-#define MO_PDMA_SCNTRL 0x20000C // Source control
-#define MO_PDMA_DTHRSH 0x200010 // Destination threshold
-#define MO_PDMA_DTADRS 0x200014 // Destination target address
-#define MO_PDMA_DIADRS 0x200018 // Destination internal address
-#define MO_PDMA_DCNTRL 0x20001C // Destination control
-#define MO_LD_SSID 0x200030 // Load subsystem ID
-#define MO_DEV_CNTRL2 0x200034 // Device control
-#define MO_PCI_INTMSK 0x200040 // PCI interrupt mask
-#define MO_PCI_INTSTAT 0x200044 // PCI interrupt status
-#define MO_PCI_INTMSTAT 0x200048 // PCI interrupt masked status
-#define MO_VID_INTMSK 0x200050 // Video interrupt mask
-#define MO_VID_INTSTAT 0x200054 // Video interrupt status
-#define MO_VID_INTMSTAT 0x200058 // Video interrupt masked status
-#define MO_VID_INTSSTAT 0x20005C // Video interrupt set status
-#define MO_AUD_INTMSK 0x200060 // Audio interrupt mask
-#define MO_AUD_INTSTAT 0x200064 // Audio interrupt status
-#define MO_AUD_INTMSTAT 0x200068 // Audio interrupt masked status
-#define MO_AUD_INTSSTAT 0x20006C // Audio interrupt set status
-#define MO_TS_INTMSK 0x200070 // Transport stream interrupt mask
-#define MO_TS_INTSTAT 0x200074 // Transport stream interrupt status
-#define MO_TS_INTMSTAT 0x200078 // Transport stream interrupt mask status
-#define MO_TS_INTSSTAT 0x20007C // Transport stream interrupt set status
-#define MO_VIP_INTMSK 0x200080 // VIP interrupt mask
-#define MO_VIP_INTSTAT 0x200084 // VIP interrupt status
-#define MO_VIP_INTMSTAT 0x200088 // VIP interrupt masked status
-#define MO_VIP_INTSSTAT 0x20008C // VIP interrupt set status
-#define MO_GPHST_INTMSK 0x200090 // Host interrupt mask
-#define MO_GPHST_INTSTAT 0x200094 // Host interrupt status
-#define MO_GPHST_INTMSTAT 0x200098 // Host interrupt masked status
-#define MO_GPHST_INTSSTAT 0x20009C // Host interrupt set status
-
-// DMA Channels 1-6 belong to SPIPE
-#define MO_DMA7_PTR1 0x300018 // {24}RW* DMA Current Ptr : Ch#7
-#define MO_DMA8_PTR1 0x30001C // {24}RW* DMA Current Ptr : Ch#8
-
-// DMA Channels 9-20 belong to SPIPE
-#define MO_DMA21_PTR1 0x300080 // {24}R0* DMA Current Ptr : Ch#21
-#define MO_DMA22_PTR1 0x300084 // {24}R0* DMA Current Ptr : Ch#22
-#define MO_DMA23_PTR1 0x300088 // {24}R0* DMA Current Ptr : Ch#23
-#define MO_DMA24_PTR1 0x30008C // {24}R0* DMA Current Ptr : Ch#24
-#define MO_DMA25_PTR1 0x300090 // {24}R0* DMA Current Ptr : Ch#25
-#define MO_DMA26_PTR1 0x300094 // {24}R0* DMA Current Ptr : Ch#26
-#define MO_DMA27_PTR1 0x300098 // {24}R0* DMA Current Ptr : Ch#27
-#define MO_DMA28_PTR1 0x30009C // {24}R0* DMA Current Ptr : Ch#28
-#define MO_DMA29_PTR1 0x3000A0 // {24}R0* DMA Current Ptr : Ch#29
-#define MO_DMA30_PTR1 0x3000A4 // {24}R0* DMA Current Ptr : Ch#30
-#define MO_DMA31_PTR1 0x3000A8 // {24}R0* DMA Current Ptr : Ch#31
-#define MO_DMA32_PTR1 0x3000AC // {24}R0* DMA Current Ptr : Ch#32
-
-#define MO_DMA21_PTR2 0x3000C0 // {24}RW* DMA Tab Ptr : Ch#21
-#define MO_DMA22_PTR2 0x3000C4 // {24}RW* DMA Tab Ptr : Ch#22
-#define MO_DMA23_PTR2 0x3000C8 // {24}RW* DMA Tab Ptr : Ch#23
-#define MO_DMA24_PTR2 0x3000CC // {24}RW* DMA Tab Ptr : Ch#24
-#define MO_DMA25_PTR2 0x3000D0 // {24}RW* DMA Tab Ptr : Ch#25
-#define MO_DMA26_PTR2 0x3000D4 // {24}RW* DMA Tab Ptr : Ch#26
-#define MO_DMA27_PTR2 0x3000D8 // {24}RW* DMA Tab Ptr : Ch#27
-#define MO_DMA28_PTR2 0x3000DC // {24}RW* DMA Tab Ptr : Ch#28
-#define MO_DMA29_PTR2 0x3000E0 // {24}RW* DMA Tab Ptr : Ch#29
-#define MO_DMA30_PTR2 0x3000E4 // {24}RW* DMA Tab Ptr : Ch#30
-#define MO_DMA31_PTR2 0x3000E8 // {24}RW* DMA Tab Ptr : Ch#31
-#define MO_DMA32_PTR2 0x3000EC // {24}RW* DMA Tab Ptr : Ch#32
-
-#define MO_DMA21_CNT1 0x300100 // {11}RW* DMA Buffer Size : Ch#21
-#define MO_DMA22_CNT1 0x300104 // {11}RW* DMA Buffer Size : Ch#22
-#define MO_DMA23_CNT1 0x300108 // {11}RW* DMA Buffer Size : Ch#23
-#define MO_DMA24_CNT1 0x30010C // {11}RW* DMA Buffer Size : Ch#24
-#define MO_DMA25_CNT1 0x300110 // {11}RW* DMA Buffer Size : Ch#25
-#define MO_DMA26_CNT1 0x300114 // {11}RW* DMA Buffer Size : Ch#26
-#define MO_DMA27_CNT1 0x300118 // {11}RW* DMA Buffer Size : Ch#27
-#define MO_DMA28_CNT1 0x30011C // {11}RW* DMA Buffer Size : Ch#28
-#define MO_DMA29_CNT1 0x300120 // {11}RW* DMA Buffer Size : Ch#29
-#define MO_DMA30_CNT1 0x300124 // {11}RW* DMA Buffer Size : Ch#30
-#define MO_DMA31_CNT1 0x300128 // {11}RW* DMA Buffer Size : Ch#31
-#define MO_DMA32_CNT1 0x30012C // {11}RW* DMA Buffer Size : Ch#32
-
-#define MO_DMA21_CNT2 0x300140 // {11}RW* DMA Table Size : Ch#21
-#define MO_DMA22_CNT2 0x300144 // {11}RW* DMA Table Size : Ch#22
-#define MO_DMA23_CNT2 0x300148 // {11}RW* DMA Table Size : Ch#23
-#define MO_DMA24_CNT2 0x30014C // {11}RW* DMA Table Size : Ch#24
-#define MO_DMA25_CNT2 0x300150 // {11}RW* DMA Table Size : Ch#25
-#define MO_DMA26_CNT2 0x300154 // {11}RW* DMA Table Size : Ch#26
-#define MO_DMA27_CNT2 0x300158 // {11}RW* DMA Table Size : Ch#27
-#define MO_DMA28_CNT2 0x30015C // {11}RW* DMA Table Size : Ch#28
-#define MO_DMA29_CNT2 0x300160 // {11}RW* DMA Table Size : Ch#29
-#define MO_DMA30_CNT2 0x300164 // {11}RW* DMA Table Size : Ch#30
-#define MO_DMA31_CNT2 0x300168 // {11}RW* DMA Table Size : Ch#31
-#define MO_DMA32_CNT2 0x30016C // {11}RW* DMA Table Size : Ch#32
-
-
-/* ---------------------------------------------------------------------- */
-/* Video registers */
-
-#define MO_VIDY_DMA 0x310000 // {64}RWp Video Y
-#define MO_VIDU_DMA 0x310008 // {64}RWp Video U
-#define MO_VIDV_DMA 0x310010 // {64}RWp Video V
-#define MO_VBI_DMA 0x310018 // {64}RWp VBI (Vertical blanking interval)
-
-#define MO_DEVICE_STATUS 0x310100
-#define MO_INPUT_FORMAT 0x310104
-#define MO_AGC_BURST 0x31010c
-#define MO_CONTR_BRIGHT 0x310110
-#define MO_UV_SATURATION 0x310114
-#define MO_HUE 0x310118
-#define MO_HTOTAL 0x310120
-#define MO_HDELAY_EVEN 0x310124
-#define MO_HDELAY_ODD 0x310128
-#define MO_VDELAY_ODD 0x31012c
-#define MO_VDELAY_EVEN 0x310130
-#define MO_HACTIVE_EVEN 0x31013c
-#define MO_HACTIVE_ODD 0x310140
-#define MO_VACTIVE_EVEN 0x310144
-#define MO_VACTIVE_ODD 0x310148
-#define MO_HSCALE_EVEN 0x31014c
-#define MO_HSCALE_ODD 0x310150
-#define MO_VSCALE_EVEN 0x310154
-#define MO_FILTER_EVEN 0x31015c
-#define MO_VSCALE_ODD 0x310158
-#define MO_FILTER_ODD 0x310160
-#define MO_OUTPUT_FORMAT 0x310164
-
-#define MO_PLL_REG 0x310168 // PLL register
-#define MO_PLL_ADJ_CTRL 0x31016c // PLL adjust control register
-#define MO_SCONV_REG 0x310170 // sample rate conversion register
-#define MO_SCONV_FIFO 0x310174 // sample rate conversion fifo
-#define MO_SUB_STEP 0x310178 // subcarrier step size
-#define MO_SUB_STEP_DR 0x31017c // subcarrier step size for DR line
-
-#define MO_CAPTURE_CTRL 0x310180 // capture control
-#define MO_COLOR_CTRL 0x310184
-#define MO_VBI_PACKET 0x310188 // vbi packet size / delay
-#define MO_FIELD_COUNT 0x310190 // field counter
-#define MO_VIP_CONFIG 0x310194
-#define MO_VBOS_CONTROL 0x3101a8
-
-#define MO_AGC_BACK_VBI 0x310200
-#define MO_AGC_SYNC_TIP1 0x310208
-
-#define MO_VIDY_GPCNT 0x31C020 // {16}RO Video Y general purpose counter
-#define MO_VIDU_GPCNT 0x31C024 // {16}RO Video U general purpose counter
-#define MO_VIDV_GPCNT 0x31C028 // {16}RO Video V general purpose counter
-#define MO_VBI_GPCNT 0x31C02C // {16}RO VBI general purpose counter
-#define MO_VIDY_GPCNTRL 0x31C030 // {2}WO Video Y general purpose control
-#define MO_VIDU_GPCNTRL 0x31C034 // {2}WO Video U general purpose control
-#define MO_VIDV_GPCNTRL 0x31C038 // {2}WO Video V general purpose control
-#define MO_VBI_GPCNTRL 0x31C03C // {2}WO VBI general purpose counter
-#define MO_VID_DMACNTRL 0x31C040 // {8}RW Video DMA control
-#define MO_VID_XFR_STAT 0x31C044 // {1}RO Video transfer status
-
-
-/* ---------------------------------------------------------------------- */
-/* audio registers */
-
-#define MO_AUDD_DMA 0x320000 // {64}RWp Audio downstream
-#define MO_AUDU_DMA 0x320008 // {64}RWp Audio upstream
-#define MO_AUDR_DMA 0x320010 // {64}RWp Audio RDS (downstream)
-#define MO_AUDD_GPCNT 0x32C020 // {16}RO Audio down general purpose counter
-#define MO_AUDU_GPCNT 0x32C024 // {16}RO Audio up general purpose counter
-#define MO_AUDR_GPCNT 0x32C028 // {16}RO Audio RDS general purpose counter
-#define MO_AUDD_GPCNTRL 0x32C030 // {2}WO Audio down general purpose control
-#define MO_AUDU_GPCNTRL 0x32C034 // {2}WO Audio up general purpose control
-#define MO_AUDR_GPCNTRL 0x32C038 // {2}WO Audio RDS general purpose control
-#define MO_AUD_DMACNTRL 0x32C040 // {6}RW Audio DMA control
-#define MO_AUD_XFR_STAT 0x32C044 // {1}RO Audio transfer status
-#define MO_AUDD_LNGTH 0x32C048 // {12}RW Audio down line length
-#define MO_AUDR_LNGTH 0x32C04C // {12}RW Audio RDS line length
-
-#define AUD_INIT 0x320100
-#define AUD_INIT_LD 0x320104
-#define AUD_SOFT_RESET 0x320108
-#define AUD_I2SINPUTCNTL 0x320120
-#define AUD_BAUDRATE 0x320124
-#define AUD_I2SOUTPUTCNTL 0x320128
-#define AAGC_HYST 0x320134
-#define AAGC_GAIN 0x320138
-#define AAGC_DEF 0x32013c
-#define AUD_IIR1_0_SEL 0x320150
-#define AUD_IIR1_0_SHIFT 0x320154
-#define AUD_IIR1_1_SEL 0x320158
-#define AUD_IIR1_1_SHIFT 0x32015c
-#define AUD_IIR1_2_SEL 0x320160
-#define AUD_IIR1_2_SHIFT 0x320164
-#define AUD_IIR1_3_SEL 0x320168
-#define AUD_IIR1_3_SHIFT 0x32016c
-#define AUD_IIR1_4_SEL 0x320170
-#define AUD_IIR1_4_SHIFT 0x32017c
-#define AUD_IIR1_5_SEL 0x320180
-#define AUD_IIR1_5_SHIFT 0x320184
-#define AUD_IIR2_0_SEL 0x320190
-#define AUD_IIR2_0_SHIFT 0x320194
-#define AUD_IIR2_1_SEL 0x320198
-#define AUD_IIR2_1_SHIFT 0x32019c
-#define AUD_IIR2_2_SEL 0x3201a0
-#define AUD_IIR2_2_SHIFT 0x3201a4
-#define AUD_IIR2_3_SEL 0x3201a8
-#define AUD_IIR2_3_SHIFT 0x3201ac
-#define AUD_IIR3_0_SEL 0x3201c0
-#define AUD_IIR3_0_SHIFT 0x3201c4
-#define AUD_IIR3_1_SEL 0x3201c8
-#define AUD_IIR3_1_SHIFT 0x3201cc
-#define AUD_IIR3_2_SEL 0x3201d0
-#define AUD_IIR3_2_SHIFT 0x3201d4
-#define AUD_IIR4_0_SEL 0x3201e0
-#define AUD_IIR4_0_SHIFT 0x3201e4
-#define AUD_IIR4_1_SEL 0x3201e8
-#define AUD_IIR4_1_SHIFT 0x3201ec
-#define AUD_IIR4_2_SEL 0x3201f0
-#define AUD_IIR4_2_SHIFT 0x3201f4
-#define AUD_IIR4_0_CA0 0x320200
-#define AUD_IIR4_0_CA1 0x320204
-#define AUD_IIR4_0_CA2 0x320208
-#define AUD_IIR4_0_CB0 0x32020c
-#define AUD_IIR4_0_CB1 0x320210
-#define AUD_IIR4_1_CA0 0x320214
-#define AUD_IIR4_1_CA1 0x320218
-#define AUD_IIR4_1_CA2 0x32021c
-#define AUD_IIR4_1_CB0 0x320220
-#define AUD_IIR4_1_CB1 0x320224
-#define AUD_IIR4_2_CA0 0x320228
-#define AUD_IIR4_2_CA1 0x32022c
-#define AUD_IIR4_2_CA2 0x320230
-#define AUD_IIR4_2_CB0 0x320234
-#define AUD_IIR4_2_CB1 0x320238
-#define AUD_HP_MD_IIR4_1 0x320250
-#define AUD_HP_PROG_IIR4_1 0x320254
-#define AUD_FM_MODE_ENABLE 0x320258
-#define AUD_POLY0_DDS_CONSTANT 0x320270
-#define AUD_DN0_FREQ 0x320274
-#define AUD_DN1_FREQ 0x320278
-#define AUD_DN1_FREQ_SHIFT 0x32027c
-#define AUD_DN1_AFC 0x320280
-#define AUD_DN1_SRC_SEL 0x320284
-#define AUD_DN1_SHFT 0x320288
-#define AUD_DN2_FREQ 0x32028c
-#define AUD_DN2_FREQ_SHIFT 0x320290
-#define AUD_DN2_AFC 0x320294
-#define AUD_DN2_SRC_SEL 0x320298
-#define AUD_DN2_SHFT 0x32029c
-#define AUD_CRDC0_SRC_SEL 0x320300
-#define AUD_CRDC0_SHIFT 0x320304
-#define AUD_CORDIC_SHIFT_0 0x320308
-#define AUD_CRDC1_SRC_SEL 0x32030c
-#define AUD_CRDC1_SHIFT 0x320310
-#define AUD_CORDIC_SHIFT_1 0x320314
-#define AUD_DCOC_0_SRC 0x320320
-#define AUD_DCOC0_SHIFT 0x320324
-#define AUD_DCOC_0_SHIFT_IN0 0x320328
-#define AUD_DCOC_0_SHIFT_IN1 0x32032c
-#define AUD_DCOC_1_SRC 0x320330
-#define AUD_DCOC1_SHIFT 0x320334
-#define AUD_DCOC_1_SHIFT_IN0 0x320338
-#define AUD_DCOC_1_SHIFT_IN1 0x32033c
-#define AUD_DCOC_2_SRC 0x320340
-#define AUD_DCOC2_SHIFT 0x320344
-#define AUD_DCOC_2_SHIFT_IN0 0x320348
-#define AUD_DCOC_2_SHIFT_IN1 0x32034c
-#define AUD_DCOC_PASS_IN 0x320350
-#define AUD_PDET_SRC 0x320370
-#define AUD_PDET_SHIFT 0x320374
-#define AUD_PILOT_BQD_1_K0 0x320380
-#define AUD_PILOT_BQD_1_K1 0x320384
-#define AUD_PILOT_BQD_1_K2 0x320388
-#define AUD_PILOT_BQD_1_K3 0x32038c
-#define AUD_PILOT_BQD_1_K4 0x320390
-#define AUD_PILOT_BQD_2_K0 0x320394
-#define AUD_PILOT_BQD_2_K1 0x320398
-#define AUD_PILOT_BQD_2_K2 0x32039c
-#define AUD_PILOT_BQD_2_K3 0x3203a0
-#define AUD_PILOT_BQD_2_K4 0x3203a4
-#define AUD_THR_FR 0x3203c0
-#define AUD_X_PROG 0x3203c4
-#define AUD_Y_PROG 0x3203c8
-#define AUD_HARMONIC_MULT 0x3203cc
-#define AUD_C1_UP_THR 0x3203d0
-#define AUD_C1_LO_THR 0x3203d4
-#define AUD_C2_UP_THR 0x3203d8
-#define AUD_C2_LO_THR 0x3203dc
-#define AUD_PLL_EN 0x320400
-#define AUD_PLL_SRC 0x320404
-#define AUD_PLL_SHIFT 0x320408
-#define AUD_PLL_IF_SEL 0x32040c
-#define AUD_PLL_IF_SHIFT 0x320410
-#define AUD_BIQUAD_PLL_K0 0x320414
-#define AUD_BIQUAD_PLL_K1 0x320418
-#define AUD_BIQUAD_PLL_K2 0x32041c
-#define AUD_BIQUAD_PLL_K3 0x320420
-#define AUD_BIQUAD_PLL_K4 0x320424
-#define AUD_DEEMPH0_SRC_SEL 0x320440
-#define AUD_DEEMPH0_SHIFT 0x320444
-#define AUD_DEEMPH0_G0 0x320448
-#define AUD_DEEMPH0_A0 0x32044c
-#define AUD_DEEMPH0_B0 0x320450
-#define AUD_DEEMPH0_A1 0x320454
-#define AUD_DEEMPH0_B1 0x320458
-#define AUD_DEEMPH1_SRC_SEL 0x32045c
-#define AUD_DEEMPH1_SHIFT 0x320460
-#define AUD_DEEMPH1_G0 0x320464
-#define AUD_DEEMPH1_A0 0x320468
-#define AUD_DEEMPH1_B0 0x32046c
-#define AUD_DEEMPH1_A1 0x320470
-#define AUD_DEEMPH1_B1 0x320474
-#define AUD_OUT0_SEL 0x320490
-#define AUD_OUT0_SHIFT 0x320494
-#define AUD_OUT1_SEL 0x320498
-#define AUD_OUT1_SHIFT 0x32049c
-#define AUD_RDSI_SEL 0x3204a0
-#define AUD_RDSI_SHIFT 0x3204a4
-#define AUD_RDSQ_SEL 0x3204a8
-#define AUD_RDSQ_SHIFT 0x3204ac
-#define AUD_DBX_IN_GAIN 0x320500
-#define AUD_DBX_WBE_GAIN 0x320504
-#define AUD_DBX_SE_GAIN 0x320508
-#define AUD_DBX_RMS_WBE 0x32050c
-#define AUD_DBX_RMS_SE 0x320510
-#define AUD_DBX_SE_BYPASS 0x320514
-#define AUD_FAWDETCTL 0x320530
-#define AUD_FAWDETWINCTL 0x320534
-#define AUD_DEEMPHGAIN_R 0x320538
-#define AUD_DEEMPHNUMER1_R 0x32053c
-#define AUD_DEEMPHNUMER2_R 0x320540
-#define AUD_DEEMPHDENOM1_R 0x320544
-#define AUD_DEEMPHDENOM2_R 0x320548
-#define AUD_ERRLOGPERIOD_R 0x32054c
-#define AUD_ERRINTRPTTHSHLD1_R 0x320550
-#define AUD_ERRINTRPTTHSHLD2_R 0x320554
-#define AUD_ERRINTRPTTHSHLD3_R 0x320558
-#define AUD_NICAM_STATUS1 0x32055c
-#define AUD_NICAM_STATUS2 0x320560
-#define AUD_ERRLOG1 0x320564
-#define AUD_ERRLOG2 0x320568
-#define AUD_ERRLOG3 0x32056c
-#define AUD_DAC_BYPASS_L 0x320580
-#define AUD_DAC_BYPASS_R 0x320584
-#define AUD_DAC_BYPASS_CTL 0x320588
-#define AUD_CTL 0x32058c
-#define AUD_STATUS 0x320590
-#define AUD_VOL_CTL 0x320594
-#define AUD_BAL_CTL 0x320598
-#define AUD_START_TIMER 0x3205b0
-#define AUD_MODE_CHG_TIMER 0x3205b4
-#define AUD_POLYPH80SCALEFAC 0x3205b8
-#define AUD_DMD_RA_DDS 0x3205bc
-#define AUD_I2S_RA_DDS 0x3205c0
-#define AUD_RATE_THRES_DMD 0x3205d0
-#define AUD_RATE_THRES_I2S 0x3205d4
-#define AUD_RATE_ADJ1 0x3205d8
-#define AUD_RATE_ADJ2 0x3205dc
-#define AUD_RATE_ADJ3 0x3205e0
-#define AUD_RATE_ADJ4 0x3205e4
-#define AUD_RATE_ADJ5 0x3205e8
-#define AUD_APB_IN_RATE_ADJ 0x3205ec
-#define AUD_I2SCNTL 0x3205ec
-#define AUD_PHASE_FIX_CTL 0x3205f0
-#define AUD_PLL_PRESCALE 0x320600
-#define AUD_PLL_DDS 0x320604
-#define AUD_PLL_INT 0x320608
-#define AUD_PLL_FRAC 0x32060c
-#define AUD_PLL_JTAG 0x320620
-#define AUD_PLL_SPMP 0x320624
-#define AUD_AFE_12DB_EN 0x320628
-
-// Audio QAM Register Addresses
-#define AUD_PDF_DDS_CNST_BYTE2 0x320d01
-#define AUD_PDF_DDS_CNST_BYTE1 0x320d02
-#define AUD_PDF_DDS_CNST_BYTE0 0x320d03
-#define AUD_PHACC_FREQ_8MSB 0x320d2a
-#define AUD_PHACC_FREQ_8LSB 0x320d2b
-#define AUD_QAM_MODE 0x320d04
-
-
-/* ---------------------------------------------------------------------- */
-/* transport stream registers */
-
-#define MO_TS_DMA 0x330000 // {64}RWp Transport stream downstream
-#define MO_TS_GPCNT 0x33C020 // {16}RO TS general purpose counter
-#define MO_TS_GPCNTRL 0x33C030 // {2}WO TS general purpose control
-#define MO_TS_DMACNTRL 0x33C040 // {6}RW TS DMA control
-#define MO_TS_XFR_STAT 0x33C044 // {1}RO TS transfer status
-#define MO_TS_LNGTH 0x33C048 // {12}RW TS line length
-
-#define TS_HW_SOP_CNTRL 0x33C04C
-#define TS_GEN_CNTRL 0x33C050
-#define TS_BD_PKT_STAT 0x33C054
-#define TS_SOP_STAT 0x33C058
-#define TS_FIFO_OVFL_STAT 0x33C05C
-#define TS_VALERR_CNTRL 0x33C060
-
-
-/* ---------------------------------------------------------------------- */
-/* VIP registers */
-
-#define MO_VIPD_DMA 0x340000 // {64}RWp VIP downstream
-#define MO_VIPU_DMA 0x340008 // {64}RWp VIP upstream
-#define MO_VIPD_GPCNT 0x34C020 // {16}RO VIP down general purpose counter
-#define MO_VIPU_GPCNT 0x34C024 // {16}RO VIP up general purpose counter
-#define MO_VIPD_GPCNTRL 0x34C030 // {2}WO VIP down general purpose control
-#define MO_VIPU_GPCNTRL 0x34C034 // {2}WO VIP up general purpose control
-#define MO_VIP_DMACNTRL 0x34C040 // {6}RW VIP DMA control
-#define MO_VIP_XFR_STAT 0x34C044 // {1}RO VIP transfer status
-#define MO_VIP_CFG 0x340048 // VIP configuration
-#define MO_VIPU_CNTRL 0x34004C // VIP upstream control #1
-#define MO_VIPD_CNTRL 0x340050 // VIP downstream control #2
-#define MO_VIPD_LNGTH 0x340054 // VIP downstream line length
-#define MO_VIP_BRSTLN 0x340058 // VIP burst length
-#define MO_VIP_INTCNTRL 0x34C05C // VIP Interrupt Control
-#define MO_VIP_XFTERM 0x340060 // VIP transfer terminate
-
-
-/* ---------------------------------------------------------------------- */
-/* misc registers */
-
-#define MO_M2M_DMA 0x350000 // {64}RWp Mem2Mem DMA Bfr
-#define MO_GP0_IO 0x350010 // {32}RW* GPIOoutput enablesdata I/O
-#define MO_GP1_IO 0x350014 // {32}RW* GPIOoutput enablesdata I/O
-#define MO_GP2_IO 0x350018 // {32}RW* GPIOoutput enablesdata I/O
-#define MO_GP3_IO 0x35001C // {32}RW* GPIO Mode/Ctrloutput enables
-#define MO_GPIO 0x350020 // {32}RW* GPIO I2C Ctrldata I/O
-#define MO_GPOE 0x350024 // {32}RW GPIO I2C Ctrloutput enables
-#define MO_GP_ISM 0x350028 // {16}WO GPIO Intr Sens/Pol
-
-#define MO_PLL_B 0x35C008 // {32}RW* PLL Control for ASB bus clks
-#define MO_M2M_CNT 0x35C024 // {32}RW Mem2Mem DMA Cnt
-#define MO_M2M_XSUM 0x35C028 // {32}RO M2M XOR-Checksum
-#define MO_CRC 0x35C02C // {16}RW CRC16 init/result
-#define MO_CRC_D 0x35C030 // {32}WO CRC16 new data in
-#define MO_TM_CNT_LDW 0x35C034 // {32}RO Timer : Counter low dword
-#define MO_TM_CNT_UW 0x35C038 // {16}RO Timer : Counter high word
-#define MO_TM_LMT_LDW 0x35C03C // {32}RW Timer : Limit low dword
-#define MO_TM_LMT_UW 0x35C040 // {32}RW Timer : Limit high word
-#define MO_PINMUX_IO 0x35C044 // {8}RW Pin Mux Control
-#define MO_TSTSEL_IO 0x35C048 // {2}RW Pin Mux Control
-#define MO_AFECFG_IO 0x35C04C // AFE configuration reg
-#define MO_DDS_IO 0x35C050 // DDS Increment reg
-#define MO_DDSCFG_IO 0x35C054 // DDS Configuration reg
-#define MO_SAMPLE_IO 0x35C058 // IRIn sample reg
-#define MO_SRST_IO 0x35C05C // Output system reset reg
-
-#define MO_INT1_MSK 0x35C060 // DMA RISC interrupt mask
-#define MO_INT1_STAT 0x35C064 // DMA RISC interrupt status
-#define MO_INT1_MSTAT 0x35C068 // DMA RISC interrupt masked status
-
-
-/* ---------------------------------------------------------------------- */
-/* i2c bus registers */
-
-#define MO_I2C 0x368000 // I2C data/control
-#define MO_I2C_DIV (0xf<<4)
-#define MO_I2C_SYNC (1<<3)
-#define MO_I2C_W3B (1<<2)
-#define MO_I2C_SCL (1<<1)
-#define MO_I2C_SDA (1<<0)
-
-
-/* ---------------------------------------------------------------------- */
-/* general purpose host registers */
-/* FIXME: tyops? s/0x35/0x38/ ?? */
-
-#define MO_GPHSTD_DMA 0x350000 // {64}RWp Host downstream
-#define MO_GPHSTU_DMA 0x350008 // {64}RWp Host upstream
-#define MO_GPHSTU_CNTRL 0x380048 // Host upstream control #1
-#define MO_GPHSTD_CNTRL 0x38004C // Host downstream control #2
-#define MO_GPHSTD_LNGTH 0x380050 // Host downstream line length
-#define MO_GPHST_WSC 0x380054 // Host wait state control
-#define MO_GPHST_XFR 0x380058 // Host transfer control
-#define MO_GPHST_WDTH 0x38005C // Host interface width
-#define MO_GPHST_HDSHK 0x380060 // Host peripheral handshake
-#define MO_GPHST_MUX16 0x380064 // Host muxed 16-bit transfer parameters
-#define MO_GPHST_MODE 0x380068 // Host mode select
-
-#define MO_GPHSTD_GPCNT 0x35C020 // Host down general purpose counter
-#define MO_GPHSTU_GPCNT 0x35C024 // Host up general purpose counter
-#define MO_GPHSTD_GPCNTRL 0x38C030 // Host down general purpose control
-#define MO_GPHSTU_GPCNTRL 0x38C034 // Host up general purpose control
-#define MO_GPHST_DMACNTRL 0x38C040 // Host DMA control
-#define MO_GPHST_XFR_STAT 0x38C044 // Host transfer status
-#define MO_GPHST_SOFT_RST 0x38C06C // Host software reset
-
-
-/* ---------------------------------------------------------------------- */
-/* RISC instructions */
-
-#define RISC_SYNC 0x80000000
-#define RISC_SYNC_ODD 0x80000000
-#define RISC_SYNC_EVEN 0x80000200
-#define RISC_RESYNC 0x80008000
-#define RISC_RESYNC_ODD 0x80008000
-#define RISC_RESYNC_EVEN 0x80008200
-#define RISC_WRITE 0x10000000
-#define RISC_WRITEC 0x50000000
-#define RISC_READ 0x90000000
-#define RISC_READC 0xA0000000
-#define RISC_JUMP 0x70000000
-#define RISC_SKIP 0x20000000
-#define RISC_WRITERM 0xB0000000
-#define RISC_WRITECM 0xC0000000
-#define RISC_WRITECR 0xD0000000
-#define RISC_IMM 0x00000001
-
-#define RISC_SOL 0x08000000
-#define RISC_EOL 0x04000000
-
-#define RISC_IRQ2 0x02000000
-#define RISC_IRQ1 0x01000000
-
-#define RISC_CNT_NONE 0x00000000
-#define RISC_CNT_INC 0x00010000
-#define RISC_CNT_RSVR 0x00020000
-#define RISC_CNT_RESET 0x00030000
-#define RISC_JMP_SRP 0x01
-
-
-/* ---------------------------------------------------------------------- */
-/* various constants */
-
-// DMA
-/* Interrupt mask/status */
-#define PCI_INT_VIDINT (1 << 0)
-#define PCI_INT_AUDINT (1 << 1)
-#define PCI_INT_TSINT (1 << 2)
-#define PCI_INT_VIPINT (1 << 3)
-#define PCI_INT_HSTINT (1 << 4)
-#define PCI_INT_TM1INT (1 << 5)
-#define PCI_INT_SRCDMAINT (1 << 6)
-#define PCI_INT_DSTDMAINT (1 << 7)
-#define PCI_INT_RISC_RD_BERRINT (1 << 10)
-#define PCI_INT_RISC_WR_BERRINT (1 << 11)
-#define PCI_INT_BRDG_BERRINT (1 << 12)
-#define PCI_INT_SRC_DMA_BERRINT (1 << 13)
-#define PCI_INT_DST_DMA_BERRINT (1 << 14)
-#define PCI_INT_IPB_DMA_BERRINT (1 << 15)
-#define PCI_INT_I2CDONE (1 << 16)
-#define PCI_INT_I2CRACK (1 << 17)
-#define PCI_INT_IR_SMPINT (1 << 18)
-#define PCI_INT_GPIO_INT0 (1 << 19)
-#define PCI_INT_GPIO_INT1 (1 << 20)
-
-#define SEL_BTSC 0x01
-#define SEL_EIAJ 0x02
-#define SEL_A2 0x04
-#define SEL_SAP 0x08
-#define SEL_NICAM 0x10
-#define SEL_FMRADIO 0x20
-
-// AUD_CTL
-#define AUD_INT_DN_RISCI1 (1 << 0)
-#define AUD_INT_UP_RISCI1 (1 << 1)
-#define AUD_INT_RDS_DN_RISCI1 (1 << 2)
-#define AUD_INT_DN_RISCI2 (1 << 4) /* yes, 3 is skipped */
-#define AUD_INT_UP_RISCI2 (1 << 5)
-#define AUD_INT_RDS_DN_RISCI2 (1 << 6)
-#define AUD_INT_DN_SYNC (1 << 12)
-#define AUD_INT_UP_SYNC (1 << 13)
-#define AUD_INT_RDS_DN_SYNC (1 << 14)
-#define AUD_INT_OPC_ERR (1 << 16)
-#define AUD_INT_BER_IRQ (1 << 20)
-#define AUD_INT_MCHG_IRQ (1 << 21)
-
-#define EN_BTSC_FORCE_MONO 0
-#define EN_BTSC_FORCE_STEREO 1
-#define EN_BTSC_FORCE_SAP 2
-#define EN_BTSC_AUTO_STEREO 3
-#define EN_BTSC_AUTO_SAP 4
-
-#define EN_A2_FORCE_MONO1 8
-#define EN_A2_FORCE_MONO2 9
-#define EN_A2_FORCE_STEREO 10
-#define EN_A2_AUTO_MONO2 11
-#define EN_A2_AUTO_STEREO 12
-
-#define EN_EIAJ_FORCE_MONO1 16
-#define EN_EIAJ_FORCE_MONO2 17
-#define EN_EIAJ_FORCE_STEREO 18
-#define EN_EIAJ_AUTO_MONO2 19
-#define EN_EIAJ_AUTO_STEREO 20
-
-#define EN_NICAM_FORCE_MONO1 32
-#define EN_NICAM_FORCE_MONO2 33
-#define EN_NICAM_FORCE_STEREO 34
-#define EN_NICAM_AUTO_MONO2 35
-#define EN_NICAM_AUTO_STEREO 36
-
-#define EN_FMRADIO_FORCE_MONO 24
-#define EN_FMRADIO_FORCE_STEREO 25
-#define EN_FMRADIO_AUTO_STEREO 26
-
-#define EN_NICAM_AUTO_FALLBACK 0x00000040
-#define EN_FMRADIO_EN_RDS 0x00000200
-#define EN_NICAM_TRY_AGAIN_BIT 0x00000400
-#define EN_DAC_ENABLE 0x00001000
-#define EN_I2SOUT_ENABLE 0x00002000
-#define EN_I2SIN_STR2DAC 0x00004000
-#define EN_I2SIN_ENABLE 0x00008000
-
-#define EN_DMTRX_SUMDIFF (0 << 7)
-#define EN_DMTRX_SUMR (1 << 7)
-#define EN_DMTRX_LR (2 << 7)
-#define EN_DMTRX_MONO (3 << 7)
-#define EN_DMTRX_BYPASS (1 << 11)
-
-// Video
-#define VID_CAPTURE_CONTROL 0x310180
-
-#define CX23880_CAP_CTL_CAPTURE_VBI_ODD (1<<3)
-#define CX23880_CAP_CTL_CAPTURE_VBI_EVEN (1<<2)
-#define CX23880_CAP_CTL_CAPTURE_ODD (1<<1)
-#define CX23880_CAP_CTL_CAPTURE_EVEN (1<<0)
-
-#define VideoInputMux0 0x0
-#define VideoInputMux1 0x1
-#define VideoInputMux2 0x2
-#define VideoInputMux3 0x3
-#define VideoInputTuner 0x0
-#define VideoInputComposite 0x1
-#define VideoInputSVideo 0x2
-#define VideoInputOther 0x3
-
-#define Xtal0 0x1
-#define Xtal1 0x2
-#define XtalAuto 0x3
-
-#define VideoFormatAuto 0x0
-#define VideoFormatNTSC 0x1
-#define VideoFormatNTSCJapan 0x2
-#define VideoFormatNTSC443 0x3
-#define VideoFormatPAL 0x4
-#define VideoFormatPALB 0x4
-#define VideoFormatPALD 0x4
-#define VideoFormatPALG 0x4
-#define VideoFormatPALH 0x4
-#define VideoFormatPALI 0x4
-#define VideoFormatPALBDGHI 0x4
-#define VideoFormatPALM 0x5
-#define VideoFormatPALN 0x6
-#define VideoFormatPALNC 0x7
-#define VideoFormatPAL60 0x8
-#define VideoFormatSECAM 0x9
-
-#define VideoFormatAuto27MHz 0x10
-#define VideoFormatNTSC27MHz 0x11
-#define VideoFormatNTSCJapan27MHz 0x12
-#define VideoFormatNTSC44327MHz 0x13
-#define VideoFormatPAL27MHz 0x14
-#define VideoFormatPALB27MHz 0x14
-#define VideoFormatPALD27MHz 0x14
-#define VideoFormatPALG27MHz 0x14
-#define VideoFormatPALH27MHz 0x14
-#define VideoFormatPALI27MHz 0x14
-#define VideoFormatPALBDGHI27MHz 0x14
-#define VideoFormatPALM27MHz 0x15
-#define VideoFormatPALN27MHz 0x16
-#define VideoFormatPALNC27MHz 0x17
-#define VideoFormatPAL6027MHz 0x18
-#define VideoFormatSECAM27MHz 0x19
-
-#define NominalUSECAM 0x87
-#define NominalVSECAM 0x85
-#define NominalUNTSC 0xFE
-#define NominalVNTSC 0xB4
-
-#define NominalContrast 0xD8
-
-#define HFilterAutoFormat 0x0
-#define HFilterCIF 0x1
-#define HFilterQCIF 0x2
-#define HFilterICON 0x3
-
-#define VFilter2TapInterpolate 0
-#define VFilter3TapInterpolate 1
-#define VFilter4TapInterpolate 2
-#define VFilter5TapInterpolate 3
-#define VFilter2TapNoInterpolate 4
-#define VFilter3TapNoInterpolate 5
-#define VFilter4TapNoInterpolate 6
-#define VFilter5TapNoInterpolate 7
-
-#define ColorFormatRGB32 0x0000
-#define ColorFormatRGB24 0x0011
-#define ColorFormatRGB16 0x0022
-#define ColorFormatRGB15 0x0033
-#define ColorFormatYUY2 0x0044
-#define ColorFormatBTYUV 0x0055
-#define ColorFormatY8 0x0066
-#define ColorFormatRGB8 0x0077
-#define ColorFormatPL422 0x0088
-#define ColorFormatPL411 0x0099
-#define ColorFormatYUV12 0x00AA
-#define ColorFormatYUV9 0x00BB
-#define ColorFormatRAW 0x00EE
-#define ColorFormatBSWAP 0x0300
-#define ColorFormatWSWAP 0x0c00
-#define ColorFormatEvenMask 0x050f
-#define ColorFormatOddMask 0x0af0
-#define ColorFormatGamma 0x1000
-
-#define Interlaced 0x1
-#define NonInterlaced 0x0
-
-#define FieldEven 0x1
-#define FieldOdd 0x0
-
-#define TGReadWriteMode 0x0
-#define TGEnableMode 0x1
-
-#define DV_CbAlign 0x0
-#define DV_Y0Align 0x1
-#define DV_CrAlign 0x2
-#define DV_Y1Align 0x3
-
-#define DVF_Analog 0x0
-#define DVF_CCIR656 0x1
-#define DVF_ByteStream 0x2
-#define DVF_ExtVSYNC 0x4
-#define DVF_ExtField 0x5
-
-#define CHANNEL_VID_Y 0x1
-#define CHANNEL_VID_U 0x2
-#define CHANNEL_VID_V 0x3
-#define CHANNEL_VID_VBI 0x4
-#define CHANNEL_AUD_DN 0x5
-#define CHANNEL_AUD_UP 0x6
-#define CHANNEL_AUD_RDS_DN 0x7
-#define CHANNEL_MPEG_DN 0x8
-#define CHANNEL_VIP_DN 0x9
-#define CHANNEL_VIP_UP 0xA
-#define CHANNEL_HOST_DN 0xB
-#define CHANNEL_HOST_UP 0xC
-#define CHANNEL_FIRST 0x1
-#define CHANNEL_LAST 0xC
-
-#define GP_COUNT_CONTROL_NONE 0x0
-#define GP_COUNT_CONTROL_INC 0x1
-#define GP_COUNT_CONTROL_RESERVED 0x2
-#define GP_COUNT_CONTROL_RESET 0x3
-
-#define PLL_PRESCALE_BY_2 2
-#define PLL_PRESCALE_BY_3 3
-#define PLL_PRESCALE_BY_4 4
-#define PLL_PRESCALE_BY_5 5
-
-#define HLNotchFilter4xFsc 0
-#define HLNotchFilterSquare 1
-#define HLNotchFilter135NTSC 2
-#define HLNotchFilter135PAL 3
-
-#define NTSC_8x_SUB_CARRIER 28.63636E6
-#define PAL_8x_SUB_CARRIER 35.46895E6
-
-// Default analog settings
-#define DEFAULT_HUE_NTSC 0x00
-#define DEFAULT_BRIGHTNESS_NTSC 0x00
-#define DEFAULT_CONTRAST_NTSC 0x39
-#define DEFAULT_SAT_U_NTSC 0x7F
-#define DEFAULT_SAT_V_NTSC 0x5A
-
-typedef enum
-{
- SOURCE_TUNER = 0,
- SOURCE_COMPOSITE,
- SOURCE_SVIDEO,
- SOURCE_OTHER1,
- SOURCE_OTHER2,
- SOURCE_COMPVIASVIDEO,
- SOURCE_CCIR656
-} VIDEOSOURCETYPE;
-
-#endif /* _CX88_REG_H_ */
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
deleted file mode 100644
index 770ec05b5e9..00000000000
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ /dev/null
@@ -1,1059 +0,0 @@
-/*
-
- cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver
-
- (c) 2001 Michael Eskin, Tom Zakrajsek [Windows version]
- (c) 2002 Yurij Sysoev <yurij@naturesoft.net>
- (c) 2003 Gerd Knorr <kraxel@bytesex.org>
-
- -----------------------------------------------------------------------
-
- Lot of voodoo here. Even the data sheet doesn't help to
- understand what is going on here, the documentation for the audio
- part of the cx2388x chip is *very* bad.
-
- Some of this comes from party done linux driver sources I got from
- [undocumented].
-
- Some comes from the dscaler sources, one of the dscaler driver guy works
- for Conexant ...
-
- -----------------------------------------------------------------------
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/freezer.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/poll.h>
-#include <linux/signal.h>
-#include <linux/ioport.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kthread.h>
-
-#include "cx88.h"
-
-static unsigned int audio_debug;
-module_param(audio_debug, int, 0644);
-MODULE_PARM_DESC(audio_debug, "enable debug messages [audio]");
-
-static unsigned int always_analog;
-module_param(always_analog,int,0644);
-MODULE_PARM_DESC(always_analog,"force analog audio out");
-
-static unsigned int radio_deemphasis;
-module_param(radio_deemphasis,int,0644);
-MODULE_PARM_DESC(radio_deemphasis, "Radio deemphasis time constant, "
- "0=None, 1=50us (elsewhere), 2=75us (USA)");
-
-#define dprintk(fmt, arg...) if (audio_debug) \
- printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
-
-/* ----------------------------------------------------------- */
-
-static const char * const aud_ctl_names[64] = {
- [EN_BTSC_FORCE_MONO] = "BTSC_FORCE_MONO",
- [EN_BTSC_FORCE_STEREO] = "BTSC_FORCE_STEREO",
- [EN_BTSC_FORCE_SAP] = "BTSC_FORCE_SAP",
- [EN_BTSC_AUTO_STEREO] = "BTSC_AUTO_STEREO",
- [EN_BTSC_AUTO_SAP] = "BTSC_AUTO_SAP",
- [EN_A2_FORCE_MONO1] = "A2_FORCE_MONO1",
- [EN_A2_FORCE_MONO2] = "A2_FORCE_MONO2",
- [EN_A2_FORCE_STEREO] = "A2_FORCE_STEREO",
- [EN_A2_AUTO_MONO2] = "A2_AUTO_MONO2",
- [EN_A2_AUTO_STEREO] = "A2_AUTO_STEREO",
- [EN_EIAJ_FORCE_MONO1] = "EIAJ_FORCE_MONO1",
- [EN_EIAJ_FORCE_MONO2] = "EIAJ_FORCE_MONO2",
- [EN_EIAJ_FORCE_STEREO] = "EIAJ_FORCE_STEREO",
- [EN_EIAJ_AUTO_MONO2] = "EIAJ_AUTO_MONO2",
- [EN_EIAJ_AUTO_STEREO] = "EIAJ_AUTO_STEREO",
- [EN_NICAM_FORCE_MONO1] = "NICAM_FORCE_MONO1",
- [EN_NICAM_FORCE_MONO2] = "NICAM_FORCE_MONO2",
- [EN_NICAM_FORCE_STEREO] = "NICAM_FORCE_STEREO",
- [EN_NICAM_AUTO_MONO2] = "NICAM_AUTO_MONO2",
- [EN_NICAM_AUTO_STEREO] = "NICAM_AUTO_STEREO",
- [EN_FMRADIO_FORCE_MONO] = "FMRADIO_FORCE_MONO",
- [EN_FMRADIO_FORCE_STEREO] = "FMRADIO_FORCE_STEREO",
- [EN_FMRADIO_AUTO_STEREO] = "FMRADIO_AUTO_STEREO",
-};
-
-struct rlist {
- u32 reg;
- u32 val;
-};
-
-static void set_audio_registers(struct cx88_core *core, const struct rlist *l)
-{
- int i;
-
- for (i = 0; l[i].reg; i++) {
- switch (l[i].reg) {
- case AUD_PDF_DDS_CNST_BYTE2:
- case AUD_PDF_DDS_CNST_BYTE1:
- case AUD_PDF_DDS_CNST_BYTE0:
- case AUD_QAM_MODE:
- case AUD_PHACC_FREQ_8MSB:
- case AUD_PHACC_FREQ_8LSB:
- cx_writeb(l[i].reg, l[i].val);
- break;
- default:
- cx_write(l[i].reg, l[i].val);
- break;
- }
- }
-}
-
-static void set_audio_start(struct cx88_core *core, u32 mode)
-{
- /* mute */
- cx_write(AUD_VOL_CTL, (1 << 6));
-
- /* start programming */
- cx_write(AUD_INIT, mode);
- cx_write(AUD_INIT_LD, 0x0001);
- cx_write(AUD_SOFT_RESET, 0x0001);
-}
-
-static void set_audio_finish(struct cx88_core *core, u32 ctl)
-{
- u32 volume;
-
- /* restart dma; This avoids buzz in NICAM and is good in others */
- cx88_stop_audio_dma(core);
- cx_write(AUD_RATE_THRES_DMD, 0x000000C0);
- cx88_start_audio_dma(core);
-
- if (core->board.mpeg & CX88_MPEG_BLACKBIRD) {
- cx_write(AUD_I2SINPUTCNTL, 4);
- cx_write(AUD_BAUDRATE, 1);
- /* 'pass-thru mode': this enables the i2s output to the mpeg encoder */
- cx_set(AUD_CTL, EN_I2SOUT_ENABLE);
- cx_write(AUD_I2SOUTPUTCNTL, 1);
- cx_write(AUD_I2SCNTL, 0);
- /* cx_write(AUD_APB_IN_RATE_ADJ, 0); */
- }
- if ((always_analog) || (!(core->board.mpeg & CX88_MPEG_BLACKBIRD))) {
- ctl |= EN_DAC_ENABLE;
- cx_write(AUD_CTL, ctl);
- }
-
- /* finish programming */
- cx_write(AUD_SOFT_RESET, 0x0000);
-
- /* unmute */
- volume = cx_sread(SHADOW_AUD_VOL_CTL);
- cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume);
-
- core->last_change = jiffies;
-}
-
-/* ----------------------------------------------------------- */
-
-static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap,
- u32 mode)
-{
- static const struct rlist btsc[] = {
- {AUD_AFE_12DB_EN, 0x00000001},
- {AUD_OUT1_SEL, 0x00000013},
- {AUD_OUT1_SHIFT, 0x00000000},
- {AUD_POLY0_DDS_CONSTANT, 0x0012010c},
- {AUD_DMD_RA_DDS, 0x00c3e7aa},
- {AUD_DBX_IN_GAIN, 0x00004734},
- {AUD_DBX_WBE_GAIN, 0x00004640},
- {AUD_DBX_SE_GAIN, 0x00008d31},
- {AUD_DCOC_0_SRC, 0x0000001a},
- {AUD_IIR1_4_SEL, 0x00000021},
- {AUD_DCOC_PASS_IN, 0x00000003},
- {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
- {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
- {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
- {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
- {AUD_DN0_FREQ, 0x0000283b},
- {AUD_DN2_SRC_SEL, 0x00000008},
- {AUD_DN2_FREQ, 0x00003000},
- {AUD_DN2_AFC, 0x00000002},
- {AUD_DN2_SHFT, 0x00000000},
- {AUD_IIR2_2_SEL, 0x00000020},
- {AUD_IIR2_2_SHIFT, 0x00000000},
- {AUD_IIR2_3_SEL, 0x0000001f},
- {AUD_IIR2_3_SHIFT, 0x00000000},
- {AUD_CRDC1_SRC_SEL, 0x000003ce},
- {AUD_CRDC1_SHIFT, 0x00000000},
- {AUD_CORDIC_SHIFT_1, 0x00000007},
- {AUD_DCOC_1_SRC, 0x0000001b},
- {AUD_DCOC1_SHIFT, 0x00000000},
- {AUD_RDSI_SEL, 0x00000008},
- {AUD_RDSQ_SEL, 0x00000008},
- {AUD_RDSI_SHIFT, 0x00000000},
- {AUD_RDSQ_SHIFT, 0x00000000},
- {AUD_POLYPH80SCALEFAC, 0x00000003},
- { /* end of list */ },
- };
- static const struct rlist btsc_sap[] = {
- {AUD_AFE_12DB_EN, 0x00000001},
- {AUD_DBX_IN_GAIN, 0x00007200},
- {AUD_DBX_WBE_GAIN, 0x00006200},
- {AUD_DBX_SE_GAIN, 0x00006200},
- {AUD_IIR1_1_SEL, 0x00000000},
- {AUD_IIR1_3_SEL, 0x00000001},
- {AUD_DN1_SRC_SEL, 0x00000007},
- {AUD_IIR1_4_SHIFT, 0x00000006},
- {AUD_IIR2_1_SHIFT, 0x00000000},
- {AUD_IIR2_2_SHIFT, 0x00000000},
- {AUD_IIR3_0_SHIFT, 0x00000000},
- {AUD_IIR3_1_SHIFT, 0x00000000},
- {AUD_IIR3_0_SEL, 0x0000000d},
- {AUD_IIR3_1_SEL, 0x0000000e},
- {AUD_DEEMPH1_SRC_SEL, 0x00000014},
- {AUD_DEEMPH1_SHIFT, 0x00000000},
- {AUD_DEEMPH1_G0, 0x00004000},
- {AUD_DEEMPH1_A0, 0x00000000},
- {AUD_DEEMPH1_B0, 0x00000000},
- {AUD_DEEMPH1_A1, 0x00000000},
- {AUD_DEEMPH1_B1, 0x00000000},
- {AUD_OUT0_SEL, 0x0000003f},
- {AUD_OUT1_SEL, 0x0000003f},
- {AUD_DN1_AFC, 0x00000002},
- {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
- {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
- {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
- {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
- {AUD_IIR1_0_SEL, 0x0000001d},
- {AUD_IIR1_2_SEL, 0x0000001e},
- {AUD_IIR2_1_SEL, 0x00000002},
- {AUD_IIR2_2_SEL, 0x00000004},
- {AUD_IIR3_2_SEL, 0x0000000f},
- {AUD_DCOC2_SHIFT, 0x00000001},
- {AUD_IIR3_2_SHIFT, 0x00000001},
- {AUD_DEEMPH0_SRC_SEL, 0x00000014},
- {AUD_CORDIC_SHIFT_1, 0x00000006},
- {AUD_POLY0_DDS_CONSTANT, 0x000e4db2},
- {AUD_DMD_RA_DDS, 0x00f696e6},
- {AUD_IIR2_3_SEL, 0x00000025},
- {AUD_IIR1_4_SEL, 0x00000021},
- {AUD_DN1_FREQ, 0x0000c965},
- {AUD_DCOC_PASS_IN, 0x00000003},
- {AUD_DCOC_0_SRC, 0x0000001a},
- {AUD_DCOC_1_SRC, 0x0000001b},
- {AUD_DCOC1_SHIFT, 0x00000000},
- {AUD_RDSI_SEL, 0x00000009},
- {AUD_RDSQ_SEL, 0x00000009},
- {AUD_RDSI_SHIFT, 0x00000000},
- {AUD_RDSQ_SHIFT, 0x00000000},
- {AUD_POLYPH80SCALEFAC, 0x00000003},
- { /* end of list */ },
- };
-
- mode |= EN_FMRADIO_EN_RDS;
-
- if (sap) {
- dprintk("%s SAP (status: unknown)\n", __func__);
- set_audio_start(core, SEL_SAP);
- set_audio_registers(core, btsc_sap);
- set_audio_finish(core, mode);
- } else {
- dprintk("%s (status: known-good)\n", __func__);
- set_audio_start(core, SEL_BTSC);
- set_audio_registers(core, btsc);
- set_audio_finish(core, mode);
- }
-}
-
-static void set_audio_standard_NICAM(struct cx88_core *core, u32 mode)
-{
- static const struct rlist nicam_l[] = {
- {AUD_AFE_12DB_EN, 0x00000001},
- {AUD_RATE_ADJ1, 0x00000060},
- {AUD_RATE_ADJ2, 0x000000F9},
- {AUD_RATE_ADJ3, 0x000001CC},
- {AUD_RATE_ADJ4, 0x000002B3},
- {AUD_RATE_ADJ5, 0x00000726},
- {AUD_DEEMPHDENOM1_R, 0x0000F3D0},
- {AUD_DEEMPHDENOM2_R, 0x00000000},
- {AUD_ERRLOGPERIOD_R, 0x00000064},
- {AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF},
- {AUD_ERRINTRPTTHSHLD2_R, 0x0000001F},
- {AUD_ERRINTRPTTHSHLD3_R, 0x0000000F},
- {AUD_POLYPH80SCALEFAC, 0x00000003},
- {AUD_DMD_RA_DDS, 0x00C00000},
- {AUD_PLL_INT, 0x0000001E},
- {AUD_PLL_DDS, 0x00000000},
- {AUD_PLL_FRAC, 0x0000E542},
- {AUD_START_TIMER, 0x00000000},
- {AUD_DEEMPHNUMER1_R, 0x000353DE},
- {AUD_DEEMPHNUMER2_R, 0x000001B1},
- {AUD_PDF_DDS_CNST_BYTE2, 0x06},
- {AUD_PDF_DDS_CNST_BYTE1, 0x82},
- {AUD_PDF_DDS_CNST_BYTE0, 0x12},
- {AUD_QAM_MODE, 0x05},
- {AUD_PHACC_FREQ_8MSB, 0x34},
- {AUD_PHACC_FREQ_8LSB, 0x4C},
- {AUD_DEEMPHGAIN_R, 0x00006680},
- {AUD_RATE_THRES_DMD, 0x000000C0},
- { /* end of list */ },
- };
-
- static const struct rlist nicam_bgdki_common[] = {
- {AUD_AFE_12DB_EN, 0x00000001},
- {AUD_RATE_ADJ1, 0x00000010},
- {AUD_RATE_ADJ2, 0x00000040},
- {AUD_RATE_ADJ3, 0x00000100},
- {AUD_RATE_ADJ4, 0x00000400},
- {AUD_RATE_ADJ5, 0x00001000},
- {AUD_ERRLOGPERIOD_R, 0x00000fff},
- {AUD_ERRINTRPTTHSHLD1_R, 0x000003ff},
- {AUD_ERRINTRPTTHSHLD2_R, 0x000000ff},
- {AUD_ERRINTRPTTHSHLD3_R, 0x0000003f},
- {AUD_POLYPH80SCALEFAC, 0x00000003},
- {AUD_DEEMPHGAIN_R, 0x000023c2},
- {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
- {AUD_DEEMPHNUMER2_R, 0x0003023e},
- {AUD_DEEMPHDENOM1_R, 0x0000f3d0},
- {AUD_DEEMPHDENOM2_R, 0x00000000},
- {AUD_PDF_DDS_CNST_BYTE2, 0x06},
- {AUD_PDF_DDS_CNST_BYTE1, 0x82},
- {AUD_QAM_MODE, 0x05},
- { /* end of list */ },
- };
-
- static const struct rlist nicam_i[] = {
- {AUD_PDF_DDS_CNST_BYTE0, 0x12},
- {AUD_PHACC_FREQ_8MSB, 0x3a},
- {AUD_PHACC_FREQ_8LSB, 0x93},
- { /* end of list */ },
- };
-
- static const struct rlist nicam_default[] = {
- {AUD_PDF_DDS_CNST_BYTE0, 0x16},
- {AUD_PHACC_FREQ_8MSB, 0x34},
- {AUD_PHACC_FREQ_8LSB, 0x4c},
- { /* end of list */ },
- };
-
- set_audio_start(core,SEL_NICAM);
- switch (core->tvaudio) {
- case WW_L:
- dprintk("%s SECAM-L NICAM (status: devel)\n", __func__);
- set_audio_registers(core, nicam_l);
- break;
- case WW_I:
- dprintk("%s PAL-I NICAM (status: known-good)\n", __func__);
- set_audio_registers(core, nicam_bgdki_common);
- set_audio_registers(core, nicam_i);
- break;
- case WW_NONE:
- case WW_BTSC:
- case WW_BG:
- case WW_DK:
- case WW_EIAJ:
- case WW_I2SPT:
- case WW_FM:
- case WW_I2SADC:
- case WW_M:
- dprintk("%s PAL-BGDK NICAM (status: known-good)\n", __func__);
- set_audio_registers(core, nicam_bgdki_common);
- set_audio_registers(core, nicam_default);
- break;
- };
-
- mode |= EN_DMTRX_LR | EN_DMTRX_BYPASS;
- set_audio_finish(core, mode);
-}
-
-static void set_audio_standard_A2(struct cx88_core *core, u32 mode)
-{
- static const struct rlist a2_bgdk_common[] = {
- {AUD_ERRLOGPERIOD_R, 0x00000064},
- {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
- {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
- {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
- {AUD_PDF_DDS_CNST_BYTE2, 0x06},
- {AUD_PDF_DDS_CNST_BYTE1, 0x82},
- {AUD_PDF_DDS_CNST_BYTE0, 0x12},
- {AUD_QAM_MODE, 0x05},
- {AUD_PHACC_FREQ_8MSB, 0x34},
- {AUD_PHACC_FREQ_8LSB, 0x4c},
- {AUD_RATE_ADJ1, 0x00000100},
- {AUD_RATE_ADJ2, 0x00000200},
- {AUD_RATE_ADJ3, 0x00000300},
- {AUD_RATE_ADJ4, 0x00000400},
- {AUD_RATE_ADJ5, 0x00000500},
- {AUD_THR_FR, 0x00000000},
- {AAGC_HYST, 0x0000001a},
- {AUD_PILOT_BQD_1_K0, 0x0000755b},
- {AUD_PILOT_BQD_1_K1, 0x00551340},
- {AUD_PILOT_BQD_1_K2, 0x006d30be},
- {AUD_PILOT_BQD_1_K3, 0xffd394af},
- {AUD_PILOT_BQD_1_K4, 0x00400000},
- {AUD_PILOT_BQD_2_K0, 0x00040000},
- {AUD_PILOT_BQD_2_K1, 0x002a4841},
- {AUD_PILOT_BQD_2_K2, 0x00400000},
- {AUD_PILOT_BQD_2_K3, 0x00000000},
- {AUD_PILOT_BQD_2_K4, 0x00000000},
- {AUD_MODE_CHG_TIMER, 0x00000040},
- {AUD_AFE_12DB_EN, 0x00000001},
- {AUD_CORDIC_SHIFT_0, 0x00000007},
- {AUD_CORDIC_SHIFT_1, 0x00000007},
- {AUD_DEEMPH0_G0, 0x00000380},
- {AUD_DEEMPH1_G0, 0x00000380},
- {AUD_DCOC_0_SRC, 0x0000001a},
- {AUD_DCOC0_SHIFT, 0x00000000},
- {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
- {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
- {AUD_DCOC_PASS_IN, 0x00000003},
- {AUD_IIR3_0_SEL, 0x00000021},
- {AUD_DN2_AFC, 0x00000002},
- {AUD_DCOC_1_SRC, 0x0000001b},
- {AUD_DCOC1_SHIFT, 0x00000000},
- {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
- {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
- {AUD_IIR3_1_SEL, 0x00000023},
- {AUD_RDSI_SEL, 0x00000017},
- {AUD_RDSI_SHIFT, 0x00000000},
- {AUD_RDSQ_SEL, 0x00000017},
- {AUD_RDSQ_SHIFT, 0x00000000},
- {AUD_PLL_INT, 0x0000001e},
- {AUD_PLL_DDS, 0x00000000},
- {AUD_PLL_FRAC, 0x0000e542},
- {AUD_POLYPH80SCALEFAC, 0x00000001},
- {AUD_START_TIMER, 0x00000000},
- { /* end of list */ },
- };
-
- static const struct rlist a2_bg[] = {
- {AUD_DMD_RA_DDS, 0x002a4f2f},
- {AUD_C1_UP_THR, 0x00007000},
- {AUD_C1_LO_THR, 0x00005400},
- {AUD_C2_UP_THR, 0x00005400},
- {AUD_C2_LO_THR, 0x00003000},
- { /* end of list */ },
- };
-
- static const struct rlist a2_dk[] = {
- {AUD_DMD_RA_DDS, 0x002a4f2f},
- {AUD_C1_UP_THR, 0x00007000},
- {AUD_C1_LO_THR, 0x00005400},
- {AUD_C2_UP_THR, 0x00005400},
- {AUD_C2_LO_THR, 0x00003000},
- {AUD_DN0_FREQ, 0x00003a1c},
- {AUD_DN2_FREQ, 0x0000d2e0},
- { /* end of list */ },
- };
-
- static const struct rlist a1_i[] = {
- {AUD_ERRLOGPERIOD_R, 0x00000064},
- {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
- {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
- {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
- {AUD_PDF_DDS_CNST_BYTE2, 0x06},
- {AUD_PDF_DDS_CNST_BYTE1, 0x82},
- {AUD_PDF_DDS_CNST_BYTE0, 0x12},
- {AUD_QAM_MODE, 0x05},
- {AUD_PHACC_FREQ_8MSB, 0x3a},
- {AUD_PHACC_FREQ_8LSB, 0x93},
- {AUD_DMD_RA_DDS, 0x002a4f2f},
- {AUD_PLL_INT, 0x0000001e},
- {AUD_PLL_DDS, 0x00000004},
- {AUD_PLL_FRAC, 0x0000e542},
- {AUD_RATE_ADJ1, 0x00000100},
- {AUD_RATE_ADJ2, 0x00000200},
- {AUD_RATE_ADJ3, 0x00000300},
- {AUD_RATE_ADJ4, 0x00000400},
- {AUD_RATE_ADJ5, 0x00000500},
- {AUD_THR_FR, 0x00000000},
- {AUD_PILOT_BQD_1_K0, 0x0000755b},
- {AUD_PILOT_BQD_1_K1, 0x00551340},
- {AUD_PILOT_BQD_1_K2, 0x006d30be},
- {AUD_PILOT_BQD_1_K3, 0xffd394af},
- {AUD_PILOT_BQD_1_K4, 0x00400000},
- {AUD_PILOT_BQD_2_K0, 0x00040000},
- {AUD_PILOT_BQD_2_K1, 0x002a4841},
- {AUD_PILOT_BQD_2_K2, 0x00400000},
- {AUD_PILOT_BQD_2_K3, 0x00000000},
- {AUD_PILOT_BQD_2_K4, 0x00000000},
- {AUD_MODE_CHG_TIMER, 0x00000060},
- {AUD_AFE_12DB_EN, 0x00000001},
- {AAGC_HYST, 0x0000000a},
- {AUD_CORDIC_SHIFT_0, 0x00000007},
- {AUD_CORDIC_SHIFT_1, 0x00000007},
- {AUD_C1_UP_THR, 0x00007000},
- {AUD_C1_LO_THR, 0x00005400},
- {AUD_C2_UP_THR, 0x00005400},
- {AUD_C2_LO_THR, 0x00003000},
- {AUD_DCOC_0_SRC, 0x0000001a},
- {AUD_DCOC0_SHIFT, 0x00000000},
- {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
- {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
- {AUD_DCOC_PASS_IN, 0x00000003},
- {AUD_IIR3_0_SEL, 0x00000021},
- {AUD_DN2_AFC, 0x00000002},
- {AUD_DCOC_1_SRC, 0x0000001b},
- {AUD_DCOC1_SHIFT, 0x00000000},
- {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
- {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
- {AUD_IIR3_1_SEL, 0x00000023},
- {AUD_DN0_FREQ, 0x000035a3},
- {AUD_DN2_FREQ, 0x000029c7},
- {AUD_CRDC0_SRC_SEL, 0x00000511},
- {AUD_IIR1_0_SEL, 0x00000001},
- {AUD_IIR1_1_SEL, 0x00000000},
- {AUD_IIR3_2_SEL, 0x00000003},
- {AUD_IIR3_2_SHIFT, 0x00000000},
- {AUD_IIR3_0_SEL, 0x00000002},
- {AUD_IIR2_0_SEL, 0x00000021},
- {AUD_IIR2_0_SHIFT, 0x00000002},
- {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
- {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
- {AUD_POLYPH80SCALEFAC, 0x00000001},
- {AUD_START_TIMER, 0x00000000},
- { /* end of list */ },
- };
-
- static const struct rlist am_l[] = {
- {AUD_ERRLOGPERIOD_R, 0x00000064},
- {AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF},
- {AUD_ERRINTRPTTHSHLD2_R, 0x0000001F},
- {AUD_ERRINTRPTTHSHLD3_R, 0x0000000F},
- {AUD_PDF_DDS_CNST_BYTE2, 0x48},
- {AUD_PDF_DDS_CNST_BYTE1, 0x3D},
- {AUD_QAM_MODE, 0x00},
- {AUD_PDF_DDS_CNST_BYTE0, 0xf5},
- {AUD_PHACC_FREQ_8MSB, 0x3a},
- {AUD_PHACC_FREQ_8LSB, 0x4a},
- {AUD_DEEMPHGAIN_R, 0x00006680},
- {AUD_DEEMPHNUMER1_R, 0x000353DE},
- {AUD_DEEMPHNUMER2_R, 0x000001B1},
- {AUD_DEEMPHDENOM1_R, 0x0000F3D0},
- {AUD_DEEMPHDENOM2_R, 0x00000000},
- {AUD_FM_MODE_ENABLE, 0x00000007},
- {AUD_POLYPH80SCALEFAC, 0x00000003},
- {AUD_AFE_12DB_EN, 0x00000001},
- {AAGC_GAIN, 0x00000000},
- {AAGC_HYST, 0x00000018},
- {AAGC_DEF, 0x00000020},
- {AUD_DN0_FREQ, 0x00000000},
- {AUD_POLY0_DDS_CONSTANT, 0x000E4DB2},
- {AUD_DCOC_0_SRC, 0x00000021},
- {AUD_IIR1_0_SEL, 0x00000000},
- {AUD_IIR1_0_SHIFT, 0x00000007},
- {AUD_IIR1_1_SEL, 0x00000002},
- {AUD_IIR1_1_SHIFT, 0x00000000},
- {AUD_DCOC_1_SRC, 0x00000003},
- {AUD_DCOC1_SHIFT, 0x00000000},
- {AUD_DCOC_PASS_IN, 0x00000000},
- {AUD_IIR1_2_SEL, 0x00000023},
- {AUD_IIR1_2_SHIFT, 0x00000000},
- {AUD_IIR1_3_SEL, 0x00000004},
- {AUD_IIR1_3_SHIFT, 0x00000007},
- {AUD_IIR1_4_SEL, 0x00000005},
- {AUD_IIR1_4_SHIFT, 0x00000007},
- {AUD_IIR3_0_SEL, 0x00000007},
- {AUD_IIR3_0_SHIFT, 0x00000000},
- {AUD_DEEMPH0_SRC_SEL, 0x00000011},
- {AUD_DEEMPH0_SHIFT, 0x00000000},
- {AUD_DEEMPH0_G0, 0x00007000},
- {AUD_DEEMPH0_A0, 0x00000000},
- {AUD_DEEMPH0_B0, 0x00000000},
- {AUD_DEEMPH0_A1, 0x00000000},
- {AUD_DEEMPH0_B1, 0x00000000},
- {AUD_DEEMPH1_SRC_SEL, 0x00000011},
- {AUD_DEEMPH1_SHIFT, 0x00000000},
- {AUD_DEEMPH1_G0, 0x00007000},
- {AUD_DEEMPH1_A0, 0x00000000},
- {AUD_DEEMPH1_B0, 0x00000000},
- {AUD_DEEMPH1_A1, 0x00000000},
- {AUD_DEEMPH1_B1, 0x00000000},
- {AUD_OUT0_SEL, 0x0000003F},
- {AUD_OUT1_SEL, 0x0000003F},
- {AUD_DMD_RA_DDS, 0x00F5C285},
- {AUD_PLL_INT, 0x0000001E},
- {AUD_PLL_DDS, 0x00000000},
- {AUD_PLL_FRAC, 0x0000E542},
- {AUD_RATE_ADJ1, 0x00000100},
- {AUD_RATE_ADJ2, 0x00000200},
- {AUD_RATE_ADJ3, 0x00000300},
- {AUD_RATE_ADJ4, 0x00000400},
- {AUD_RATE_ADJ5, 0x00000500},
- {AUD_RATE_THRES_DMD, 0x000000C0},
- { /* end of list */ },
- };
-
- static const struct rlist a2_deemph50[] = {
- {AUD_DEEMPH0_G0, 0x00000380},
- {AUD_DEEMPH1_G0, 0x00000380},
- {AUD_DEEMPHGAIN_R, 0x000011e1},
- {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
- {AUD_DEEMPHNUMER2_R, 0x0003023c},
- { /* end of list */ },
- };
-
- set_audio_start(core, SEL_A2);
- switch (core->tvaudio) {
- case WW_BG:
- dprintk("%s PAL-BG A1/2 (status: known-good)\n", __func__);
- set_audio_registers(core, a2_bgdk_common);
- set_audio_registers(core, a2_bg);
- set_audio_registers(core, a2_deemph50);
- break;
- case WW_DK:
- dprintk("%s PAL-DK A1/2 (status: known-good)\n", __func__);
- set_audio_registers(core, a2_bgdk_common);
- set_audio_registers(core, a2_dk);
- set_audio_registers(core, a2_deemph50);
- break;
- case WW_I:
- dprintk("%s PAL-I A1 (status: known-good)\n", __func__);
- set_audio_registers(core, a1_i);
- set_audio_registers(core, a2_deemph50);
- break;
- case WW_L:
- dprintk("%s AM-L (status: devel)\n", __func__);
- set_audio_registers(core, am_l);
- break;
- case WW_NONE:
- case WW_BTSC:
- case WW_EIAJ:
- case WW_I2SPT:
- case WW_FM:
- case WW_I2SADC:
- case WW_M:
- dprintk("%s Warning: wrong value\n", __func__);
- return;
- break;
- };
-
- mode |= EN_FMRADIO_EN_RDS | EN_DMTRX_SUMDIFF;
- set_audio_finish(core, mode);
-}
-
-static void set_audio_standard_EIAJ(struct cx88_core *core)
-{
- static const struct rlist eiaj[] = {
- /* TODO: eiaj register settings are not there yet ... */
-
- { /* end of list */ },
- };
- dprintk("%s (status: unknown)\n", __func__);
-
- set_audio_start(core, SEL_EIAJ);
- set_audio_registers(core, eiaj);
- set_audio_finish(core, EN_EIAJ_AUTO_STEREO);
-}
-
-static void set_audio_standard_FM(struct cx88_core *core,
- enum cx88_deemph_type deemph)
-{
- static const struct rlist fm_deemph_50[] = {
- {AUD_DEEMPH0_G0, 0x0C45},
- {AUD_DEEMPH0_A0, 0x6262},
- {AUD_DEEMPH0_B0, 0x1C29},
- {AUD_DEEMPH0_A1, 0x3FC66},
- {AUD_DEEMPH0_B1, 0x399A},
-
- {AUD_DEEMPH1_G0, 0x0D80},
- {AUD_DEEMPH1_A0, 0x6262},
- {AUD_DEEMPH1_B0, 0x1C29},
- {AUD_DEEMPH1_A1, 0x3FC66},
- {AUD_DEEMPH1_B1, 0x399A},
-
- {AUD_POLYPH80SCALEFAC, 0x0003},
- { /* end of list */ },
- };
- static const struct rlist fm_deemph_75[] = {
- {AUD_DEEMPH0_G0, 0x091B},
- {AUD_DEEMPH0_A0, 0x6B68},
- {AUD_DEEMPH0_B0, 0x11EC},
- {AUD_DEEMPH0_A1, 0x3FC66},
- {AUD_DEEMPH0_B1, 0x399A},
-
- {AUD_DEEMPH1_G0, 0x0AA0},
- {AUD_DEEMPH1_A0, 0x6B68},
- {AUD_DEEMPH1_B0, 0x11EC},
- {AUD_DEEMPH1_A1, 0x3FC66},
- {AUD_DEEMPH1_B1, 0x399A},
-
- {AUD_POLYPH80SCALEFAC, 0x0003},
- { /* end of list */ },
- };
-
- /* It is enough to leave default values? */
- /* No, it's not! The deemphasis registers are reset to the 75us
- * values by default. Analyzing the spectrum of the decoded audio
- * reveals that "no deemphasis" is the same as 75 us, while the 50 us
- * setting results in less deemphasis. */
- static const struct rlist fm_no_deemph[] = {
-
- {AUD_POLYPH80SCALEFAC, 0x0003},
- { /* end of list */ },
- };
-
- dprintk("%s (status: unknown)\n", __func__);
- set_audio_start(core, SEL_FMRADIO);
-
- switch (deemph) {
- default:
- case FM_NO_DEEMPH:
- set_audio_registers(core, fm_no_deemph);
- break;
-
- case FM_DEEMPH_50:
- set_audio_registers(core, fm_deemph_50);
- break;
-
- case FM_DEEMPH_75:
- set_audio_registers(core, fm_deemph_75);
- break;
- }
-
- set_audio_finish(core, EN_FMRADIO_AUTO_STEREO);
-}
-
-/* ----------------------------------------------------------- */
-
-static int cx88_detect_nicam(struct cx88_core *core)
-{
- int i, j = 0;
-
- dprintk("start nicam autodetect.\n");
-
- for (i = 0; i < 6; i++) {
- /* if bit1=1 then nicam is detected */
- j += ((cx_read(AUD_NICAM_STATUS2) & 0x02) >> 1);
-
- if (j == 1) {
- dprintk("nicam is detected.\n");
- return 1;
- }
-
- /* wait a little bit for next reading status */
- msleep(10);
- }
-
- dprintk("nicam is not detected.\n");
- return 0;
-}
-
-void cx88_set_tvaudio(struct cx88_core *core)
-{
- switch (core->tvaudio) {
- case WW_BTSC:
- set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);
- break;
- case WW_BG:
- case WW_DK:
- case WW_M:
- case WW_I:
- case WW_L:
- /* prepare all dsp registers */
- set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
-
- /* set nicam mode - otherwise
- AUD_NICAM_STATUS2 contains wrong values */
- set_audio_standard_NICAM(core, EN_NICAM_AUTO_STEREO);
- if (0 == cx88_detect_nicam(core)) {
- /* fall back to fm / am mono */
- set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
- core->audiomode_current = V4L2_TUNER_MODE_MONO;
- core->use_nicam = 0;
- } else {
- core->use_nicam = 1;
- }
- break;
- case WW_EIAJ:
- set_audio_standard_EIAJ(core);
- break;
- case WW_FM:
- set_audio_standard_FM(core, radio_deemphasis);
- break;
- case WW_I2SADC:
- set_audio_start(core, 0x01);
- /*
- * Slave/Philips/Autobaud
- * NB on Nova-S bit1 NPhilipsSony appears to be inverted:
- * 0= Sony, 1=Philips
- */
- cx_write(AUD_I2SINPUTCNTL, core->board.i2sinputcntl);
- /* Switch to "I2S ADC mode" */
- cx_write(AUD_I2SCNTL, 0x1);
- set_audio_finish(core, EN_I2SIN_ENABLE);
- break;
- case WW_NONE:
- case WW_I2SPT:
- printk("%s/0: unknown tv audio mode [%d]\n",
- core->name, core->tvaudio);
- break;
- }
- return;
-}
-
-void cx88_newstation(struct cx88_core *core)
-{
- core->audiomode_manual = UNSET;
- core->last_change = jiffies;
-}
-
-void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
-{
- static const char * const m[] = { "stereo", "dual mono", "mono", "sap" };
- static const char * const p[] = { "no pilot", "pilot c1", "pilot c2", "?" };
- u32 reg, mode, pilot;
-
- reg = cx_read(AUD_STATUS);
- mode = reg & 0x03;
- pilot = (reg >> 2) & 0x03;
-
- if (core->astat != reg)
- dprintk("AUD_STATUS: 0x%x [%s/%s] ctl=%s\n",
- reg, m[mode], p[pilot],
- aud_ctl_names[cx_read(AUD_CTL) & 63]);
- core->astat = reg;
-
- t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
- V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
- t->rxsubchans = UNSET;
- t->audmode = V4L2_TUNER_MODE_MONO;
-
- switch (mode) {
- case 0:
- t->audmode = V4L2_TUNER_MODE_STEREO;
- break;
- case 1:
- t->audmode = V4L2_TUNER_MODE_LANG2;
- break;
- case 2:
- t->audmode = V4L2_TUNER_MODE_MONO;
- break;
- case 3:
- t->audmode = V4L2_TUNER_MODE_SAP;
- break;
- }
-
- switch (core->tvaudio) {
- case WW_BTSC:
- case WW_BG:
- case WW_DK:
- case WW_M:
- case WW_EIAJ:
- if (!core->use_nicam) {
- t->rxsubchans = cx88_dsp_detect_stereo_sap(core);
- break;
- }
- break;
- case WW_NONE:
- case WW_I:
- case WW_L:
- case WW_I2SPT:
- case WW_FM:
- case WW_I2SADC:
- /* nothing */
- break;
- }
-
- /* If software stereo detection is not supported... */
- if (UNSET == t->rxsubchans) {
- t->rxsubchans = V4L2_TUNER_SUB_MONO;
- /* If the hardware itself detected stereo, also return
- stereo as an available subchannel */
- if (V4L2_TUNER_MODE_STEREO == t->audmode)
- t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
- }
- return;
-}
-
-void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
-{
- u32 ctl = UNSET;
- u32 mask = UNSET;
-
- if (manual) {
- core->audiomode_manual = mode;
- } else {
- if (UNSET != core->audiomode_manual)
- return;
- }
- core->audiomode_current = mode;
-
- switch (core->tvaudio) {
- case WW_BTSC:
- switch (mode) {
- case V4L2_TUNER_MODE_MONO:
- set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_MONO);
- break;
- case V4L2_TUNER_MODE_LANG1:
- set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);
- break;
- case V4L2_TUNER_MODE_LANG2:
- set_audio_standard_BTSC(core, 1, EN_BTSC_FORCE_SAP);
- break;
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1_LANG2:
- set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_STEREO);
- break;
- }
- break;
- case WW_BG:
- case WW_DK:
- case WW_M:
- case WW_I:
- case WW_L:
- if (1 == core->use_nicam) {
- switch (mode) {
- case V4L2_TUNER_MODE_MONO:
- case V4L2_TUNER_MODE_LANG1:
- set_audio_standard_NICAM(core,
- EN_NICAM_FORCE_MONO1);
- break;
- case V4L2_TUNER_MODE_LANG2:
- set_audio_standard_NICAM(core,
- EN_NICAM_FORCE_MONO2);
- break;
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1_LANG2:
- set_audio_standard_NICAM(core,
- EN_NICAM_FORCE_STEREO);
- break;
- }
- } else {
- if ((core->tvaudio == WW_I) || (core->tvaudio == WW_L)) {
- /* fall back to fm / am mono */
- set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
- } else {
- /* TODO: Add A2 autodection */
- mask = 0x3f;
- switch (mode) {
- case V4L2_TUNER_MODE_MONO:
- case V4L2_TUNER_MODE_LANG1:
- ctl = EN_A2_FORCE_MONO1;
- break;
- case V4L2_TUNER_MODE_LANG2:
- ctl = EN_A2_FORCE_MONO2;
- break;
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1_LANG2:
- ctl = EN_A2_FORCE_STEREO;
- break;
- }
- }
- }
- break;
- case WW_FM:
- switch (mode) {
- case V4L2_TUNER_MODE_MONO:
- ctl = EN_FMRADIO_FORCE_MONO;
- mask = 0x3f;
- break;
- case V4L2_TUNER_MODE_STEREO:
- ctl = EN_FMRADIO_AUTO_STEREO;
- mask = 0x3f;
- break;
- }
- break;
- case WW_I2SADC:
- case WW_NONE:
- case WW_EIAJ:
- case WW_I2SPT:
- /* DO NOTHING */
- break;
- }
-
- if (UNSET != ctl) {
- dprintk("cx88_set_stereo: mask 0x%x, ctl 0x%x "
- "[status=0x%x,ctl=0x%x,vol=0x%x]\n",
- mask, ctl, cx_read(AUD_STATUS),
- cx_read(AUD_CTL), cx_sread(SHADOW_AUD_VOL_CTL));
- cx_andor(AUD_CTL, mask, ctl);
- }
- return;
-}
-
-int cx88_audio_thread(void *data)
-{
- struct cx88_core *core = data;
- struct v4l2_tuner t;
- u32 mode = 0;
-
- dprintk("cx88: tvaudio thread started\n");
- set_freezable();
- for (;;) {
- msleep_interruptible(1000);
- if (kthread_should_stop())
- break;
- try_to_freeze();
-
- switch (core->tvaudio) {
- case WW_BG:
- case WW_DK:
- case WW_M:
- case WW_I:
- case WW_L:
- if (core->use_nicam)
- goto hw_autodetect;
-
- /* just monitor the audio status for now ... */
- memset(&t, 0, sizeof(t));
- cx88_get_stereo(core, &t);
-
- if (UNSET != core->audiomode_manual)
- /* manually set, don't do anything. */
- continue;
-
- /* monitor signal and set stereo if available */
- if (t.rxsubchans & V4L2_TUNER_SUB_STEREO)
- mode = V4L2_TUNER_MODE_STEREO;
- else
- mode = V4L2_TUNER_MODE_MONO;
- if (mode == core->audiomode_current)
- continue;
- /* automatically switch to best available mode */
- cx88_set_stereo(core, mode, 0);
- break;
- case WW_NONE:
- case WW_BTSC:
- case WW_EIAJ:
- case WW_I2SPT:
- case WW_FM:
- case WW_I2SADC:
-hw_autodetect:
- /* stereo autodetection is supported by hardware so
- we don't need to do it manually. Do nothing. */
- break;
- }
- }
-
- dprintk("cx88: tvaudio thread exiting\n");
- return 0;
-}
-
-/* ----------------------------------------------------------- */
-
-EXPORT_SYMBOL(cx88_set_tvaudio);
-EXPORT_SYMBOL(cx88_newstation);
-EXPORT_SYMBOL(cx88_set_stereo);
-EXPORT_SYMBOL(cx88_get_stereo);
-EXPORT_SYMBOL(cx88_audio_thread);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
- */
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c
deleted file mode 100644
index f8f8389c036..00000000000
--- a/drivers/media/video/cx88/cx88-vbi.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include "cx88.h"
-
-static unsigned int vbibufs = 4;
-module_param(vbibufs,int,0644);
-MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32");
-
-static unsigned int vbi_debug;
-module_param(vbi_debug,int,0644);
-MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]");
-
-#define dprintk(level,fmt, arg...) if (vbi_debug >= level) \
- printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg)
-
-/* ------------------------------------------------------------------ */
-
-int cx8800_vbi_fmt (struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx8800_fh *fh = priv;
- struct cx8800_dev *dev = fh->dev;
-
- f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
- f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
- f->fmt.vbi.offset = 244;
- f->fmt.vbi.count[0] = VBI_LINE_COUNT;
- f->fmt.vbi.count[1] = VBI_LINE_COUNT;
-
- if (dev->core->tvnorm & V4L2_STD_525_60) {
- /* ntsc */
- f->fmt.vbi.sampling_rate = 28636363;
- f->fmt.vbi.start[0] = 10;
- f->fmt.vbi.start[1] = 273;
-
- } else if (dev->core->tvnorm & V4L2_STD_625_50) {
- /* pal */
- f->fmt.vbi.sampling_rate = 35468950;
- f->fmt.vbi.start[0] = 7 -1;
- f->fmt.vbi.start[1] = 319 -1;
- }
- return 0;
-}
-
-static int cx8800_start_vbi_dma(struct cx8800_dev *dev,
- struct cx88_dmaqueue *q,
- struct cx88_buffer *buf)
-{
- struct cx88_core *core = dev->core;
-
- /* setup fifo + format */
- cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH24],
- buf->vb.width, buf->risc.dma);
-
- cx_write(MO_VBOS_CONTROL, ( (1 << 18) | // comb filter delay fixup
- (1 << 15) | // enable vbi capture
- (1 << 11) ));
-
- /* reset counter */
- cx_write(MO_VBI_GPCNTRL, GP_COUNT_CONTROL_RESET);
- q->count = 1;
-
- /* enable irqs */
- cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_VIDINT);
- cx_set(MO_VID_INTMSK, 0x0f0088);
-
- /* enable capture */
- cx_set(VID_CAPTURE_CONTROL,0x18);
-
- /* start dma */
- cx_set(MO_DEV_CNTRL2, (1<<5));
- cx_set(MO_VID_DMACNTRL, 0x88);
-
- return 0;
-}
-
-int cx8800_stop_vbi_dma(struct cx8800_dev *dev)
-{
- struct cx88_core *core = dev->core;
-
- /* stop dma */
- cx_clear(MO_VID_DMACNTRL, 0x88);
-
- /* disable capture */
- cx_clear(VID_CAPTURE_CONTROL,0x18);
-
- /* disable irqs */
- cx_clear(MO_PCI_INTMSK, PCI_INT_VIDINT);
- cx_clear(MO_VID_INTMSK, 0x0f0088);
- return 0;
-}
-
-int cx8800_restart_vbi_queue(struct cx8800_dev *dev,
- struct cx88_dmaqueue *q)
-{
- struct cx88_buffer *buf;
-
- if (list_empty(&q->active))
- return 0;
-
- buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
- dprintk(2,"restart_queue [%p/%d]: restart dma\n",
- buf, buf->vb.i);
- cx8800_start_vbi_dma(dev, q, buf);
- list_for_each_entry(buf, &q->active, vb.queue)
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- return 0;
-}
-
-void cx8800_vbi_timeout(unsigned long data)
-{
- struct cx8800_dev *dev = (struct cx8800_dev*)data;
- struct cx88_core *core = dev->core;
- struct cx88_dmaqueue *q = &dev->vbiq;
- struct cx88_buffer *buf;
- unsigned long flags;
-
- cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH24]);
-
- cx_clear(MO_VID_DMACNTRL, 0x88);
- cx_clear(VID_CAPTURE_CONTROL, 0x18);
-
- spin_lock_irqsave(&dev->slock,flags);
- while (!list_empty(&q->active)) {
- buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
- list_del(&buf->vb.queue);
- buf->vb.state = VIDEOBUF_ERROR;
- wake_up(&buf->vb.done);
- printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", dev->core->name,
- buf, buf->vb.i, (unsigned long)buf->risc.dma);
- }
- cx8800_restart_vbi_queue(dev,q);
- spin_unlock_irqrestore(&dev->slock,flags);
-}
-
-/* ------------------------------------------------------------------ */
-
-static int
-vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
-{
- *size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
- if (0 == *count)
- *count = vbibufs;
- if (*count < 2)
- *count = 2;
- if (*count > 32)
- *count = 32;
- return 0;
-}
-
-static int
-vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct cx8800_fh *fh = q->priv_data;
- struct cx8800_dev *dev = fh->dev;
- struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
- unsigned int size;
- int rc;
-
- size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
- if (0 != buf->vb.baddr && buf->vb.bsize < size)
- return -EINVAL;
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
- buf->vb.width = VBI_LINE_LENGTH;
- buf->vb.height = VBI_LINE_COUNT;
- buf->vb.size = size;
- buf->vb.field = V4L2_FIELD_SEQ_TB;
-
- if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
- goto fail;
- cx88_risc_buffer(dev->pci, &buf->risc,
- dma->sglist,
- 0, buf->vb.width * buf->vb.height,
- buf->vb.width, 0,
- buf->vb.height);
- }
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
- fail:
- cx88_free_buffer(q,buf);
- return rc;
-}
-
-static void
-vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
- struct cx88_buffer *prev;
- struct cx8800_fh *fh = vq->priv_data;
- struct cx8800_dev *dev = fh->dev;
- struct cx88_dmaqueue *q = &dev->vbiq;
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
-
- if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue,&q->active);
- cx8800_start_vbi_dma(dev, q, buf);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- dprintk(2,"[%p/%d] vbi_queue - first active\n",
- buf, buf->vb.i);
-
- } else {
- prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
- list_add_tail(&buf->vb.queue,&q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- dprintk(2,"[%p/%d] buffer_queue - append to active\n",
- buf, buf->vb.i);
- }
-}
-
-static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
-
- cx88_free_buffer(q,buf);
-}
-
-const struct videobuf_queue_ops cx8800_vbi_qops = {
- .buf_setup = vbi_setup,
- .buf_prepare = vbi_prepare,
- .buf_queue = vbi_queue,
- .buf_release = vbi_release,
-};
-
-/* ------------------------------------------------------------------ */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
deleted file mode 100644
index f6fcc7e763a..00000000000
--- a/drivers/media/video/cx88/cx88-video.c
+++ /dev/null
@@ -1,2075 +0,0 @@
-/*
- *
- * device driver for Conexant 2388x based TV cards
- * video4linux video interface
- *
- * (c) 2003-04 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
- * - Multituner support
- * - video_ioctl2 conversion
- * - PAL/M fixes
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kmod.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/kthread.h>
-#include <asm/div64.h>
-
-#include "cx88.h"
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-event.h>
-#include <media/wm8775.h>
-
-MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(CX88_VERSION);
-
-/* ------------------------------------------------------------------ */
-
-static unsigned int video_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
-static unsigned int vbi_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
-static unsigned int radio_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
-
-module_param_array(video_nr, int, NULL, 0444);
-module_param_array(vbi_nr, int, NULL, 0444);
-module_param_array(radio_nr, int, NULL, 0444);
-
-MODULE_PARM_DESC(video_nr,"video device numbers");
-MODULE_PARM_DESC(vbi_nr,"vbi device numbers");
-MODULE_PARM_DESC(radio_nr,"radio device numbers");
-
-static unsigned int video_debug;
-module_param(video_debug,int,0644);
-MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
-
-static unsigned int irq_debug;
-module_param(irq_debug,int,0644);
-MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]");
-
-static unsigned int vid_limit = 16;
-module_param(vid_limit,int,0644);
-MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
-
-#define dprintk(level,fmt, arg...) if (video_debug >= level) \
- printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
-
-/* ------------------------------------------------------------------- */
-/* static data */
-
-static const struct cx8800_fmt formats[] = {
- {
- .name = "8 bpp, gray",
- .fourcc = V4L2_PIX_FMT_GREY,
- .cxformat = ColorFormatY8,
- .depth = 8,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "15 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_RGB555,
- .cxformat = ColorFormatRGB15,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "15 bpp RGB, be",
- .fourcc = V4L2_PIX_FMT_RGB555X,
- .cxformat = ColorFormatRGB15 | ColorFormatBSWAP,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "16 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_RGB565,
- .cxformat = ColorFormatRGB16,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "16 bpp RGB, be",
- .fourcc = V4L2_PIX_FMT_RGB565X,
- .cxformat = ColorFormatRGB16 | ColorFormatBSWAP,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "24 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_BGR24,
- .cxformat = ColorFormatRGB24,
- .depth = 24,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "32 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_BGR32,
- .cxformat = ColorFormatRGB32,
- .depth = 32,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "32 bpp RGB, be",
- .fourcc = V4L2_PIX_FMT_RGB32,
- .cxformat = ColorFormatRGB32 | ColorFormatBSWAP | ColorFormatWSWAP,
- .depth = 32,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "4:2:2, packed, YUYV",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .cxformat = ColorFormatYUY2,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- },{
- .name = "4:2:2, packed, UYVY",
- .fourcc = V4L2_PIX_FMT_UYVY,
- .cxformat = ColorFormatYUY2 | ColorFormatBSWAP,
- .depth = 16,
- .flags = FORMAT_FLAGS_PACKED,
- },
-};
-
-static const struct cx8800_fmt* format_by_fourcc(unsigned int fourcc)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(formats); i++)
- if (formats[i].fourcc == fourcc)
- return formats+i;
- return NULL;
-}
-
-/* ------------------------------------------------------------------- */
-
-struct cx88_ctrl {
- /* control information */
- u32 id;
- s32 minimum;
- s32 maximum;
- u32 step;
- s32 default_value;
-
- /* control register information */
- u32 off;
- u32 reg;
- u32 sreg;
- u32 mask;
- u32 shift;
-};
-
-static const struct cx88_ctrl cx8800_vid_ctls[] = {
- /* --- video --- */
- {
- .id = V4L2_CID_BRIGHTNESS,
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0x7f,
- .off = 128,
- .reg = MO_CONTR_BRIGHT,
- .mask = 0x00ff,
- .shift = 0,
- },{
- .id = V4L2_CID_CONTRAST,
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0x3f,
- .off = 0,
- .reg = MO_CONTR_BRIGHT,
- .mask = 0xff00,
- .shift = 8,
- },{
- .id = V4L2_CID_HUE,
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0x7f,
- .off = 128,
- .reg = MO_HUE,
- .mask = 0x00ff,
- .shift = 0,
- },{
- /* strictly, this only describes only U saturation.
- * V saturation is handled specially through code.
- */
- .id = V4L2_CID_SATURATION,
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0x7f,
- .off = 0,
- .reg = MO_UV_SATURATION,
- .mask = 0x00ff,
- .shift = 0,
- }, {
- .id = V4L2_CID_SHARPNESS,
- .minimum = 0,
- .maximum = 4,
- .step = 1,
- .default_value = 0x0,
- .off = 0,
- /* NOTE: the value is converted and written to both even
- and odd registers in the code */
- .reg = MO_FILTER_ODD,
- .mask = 7 << 7,
- .shift = 7,
- }, {
- .id = V4L2_CID_CHROMA_AGC,
- .minimum = 0,
- .maximum = 1,
- .default_value = 0x1,
- .reg = MO_INPUT_FORMAT,
- .mask = 1 << 10,
- .shift = 10,
- }, {
- .id = V4L2_CID_COLOR_KILLER,
- .minimum = 0,
- .maximum = 1,
- .default_value = 0x1,
- .reg = MO_INPUT_FORMAT,
- .mask = 1 << 9,
- .shift = 9,
- }, {
- .id = V4L2_CID_BAND_STOP_FILTER,
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0x0,
- .off = 0,
- .reg = MO_HTOTAL,
- .mask = 3 << 11,
- .shift = 11,
- }
-};
-
-static const struct cx88_ctrl cx8800_aud_ctls[] = {
- {
- /* --- audio --- */
- .id = V4L2_CID_AUDIO_MUTE,
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .reg = AUD_VOL_CTL,
- .sreg = SHADOW_AUD_VOL_CTL,
- .mask = (1 << 6),
- .shift = 6,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .minimum = 0,
- .maximum = 0x3f,
- .step = 1,
- .default_value = 0x3f,
- .reg = AUD_VOL_CTL,
- .sreg = SHADOW_AUD_VOL_CTL,
- .mask = 0x3f,
- .shift = 0,
- },{
- .id = V4L2_CID_AUDIO_BALANCE,
- .minimum = 0,
- .maximum = 0x7f,
- .step = 1,
- .default_value = 0x40,
- .reg = AUD_BAL_CTL,
- .sreg = SHADOW_AUD_BAL_CTL,
- .mask = 0x7f,
- .shift = 0,
- }
-};
-
-enum {
- CX8800_VID_CTLS = ARRAY_SIZE(cx8800_vid_ctls),
- CX8800_AUD_CTLS = ARRAY_SIZE(cx8800_aud_ctls),
-};
-
-/* ------------------------------------------------------------------- */
-/* resource management */
-
-static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bit)
-{
- struct cx88_core *core = dev->core;
- if (fh->resources & bit)
- /* have it already allocated */
- return 1;
-
- /* is it free? */
- mutex_lock(&core->lock);
- if (dev->resources & bit) {
- /* no, someone else uses it */
- mutex_unlock(&core->lock);
- return 0;
- }
- /* it's free, grab it */
- fh->resources |= bit;
- dev->resources |= bit;
- dprintk(1,"res: get %d\n",bit);
- mutex_unlock(&core->lock);
- return 1;
-}
-
-static
-int res_check(struct cx8800_fh *fh, unsigned int bit)
-{
- return (fh->resources & bit);
-}
-
-static
-int res_locked(struct cx8800_dev *dev, unsigned int bit)
-{
- return (dev->resources & bit);
-}
-
-static
-void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits)
-{
- struct cx88_core *core = dev->core;
- BUG_ON((fh->resources & bits) != bits);
-
- mutex_lock(&core->lock);
- fh->resources &= ~bits;
- dev->resources &= ~bits;
- dprintk(1,"res: put %d\n",bits);
- mutex_unlock(&core->lock);
-}
-
-/* ------------------------------------------------------------------ */
-
-int cx88_video_mux(struct cx88_core *core, unsigned int input)
-{
- /* struct cx88_core *core = dev->core; */
-
- dprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n",
- input, INPUT(input).vmux,
- INPUT(input).gpio0,INPUT(input).gpio1,
- INPUT(input).gpio2,INPUT(input).gpio3);
- core->input = input;
- cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input).vmux << 14);
- cx_write(MO_GP3_IO, INPUT(input).gpio3);
- cx_write(MO_GP0_IO, INPUT(input).gpio0);
- cx_write(MO_GP1_IO, INPUT(input).gpio1);
- cx_write(MO_GP2_IO, INPUT(input).gpio2);
-
- switch (INPUT(input).type) {
- case CX88_VMUX_SVIDEO:
- cx_set(MO_AFECFG_IO, 0x00000001);
- cx_set(MO_INPUT_FORMAT, 0x00010010);
- cx_set(MO_FILTER_EVEN, 0x00002020);
- cx_set(MO_FILTER_ODD, 0x00002020);
- break;
- default:
- cx_clear(MO_AFECFG_IO, 0x00000001);
- cx_clear(MO_INPUT_FORMAT, 0x00010010);
- cx_clear(MO_FILTER_EVEN, 0x00002020);
- cx_clear(MO_FILTER_ODD, 0x00002020);
- break;
- }
-
- /* if there are audioroutes defined, we have an external
- ADC to deal with audio */
- if (INPUT(input).audioroute) {
- /* The wm8775 module has the "2" route hardwired into
- the initialization. Some boards may use different
- routes for different inputs. HVR-1300 surely does */
- if (core->board.audio_chip &&
- core->board.audio_chip == V4L2_IDENT_WM8775) {
- call_all(core, audio, s_routing,
- INPUT(input).audioroute, 0, 0);
- }
- /* cx2388's C-ADC is connected to the tuner only.
- When used with S-Video, that ADC is busy dealing with
- chroma, so an external must be used for baseband audio */
- if (INPUT(input).type != CX88_VMUX_TELEVISION &&
- INPUT(input).type != CX88_VMUX_CABLE) {
- /* "I2S ADC mode" */
- core->tvaudio = WW_I2SADC;
- cx88_set_tvaudio(core);
- } else {
- /* Normal mode */
- cx_write(AUD_I2SCNTL, 0x0);
- cx_clear(AUD_CTL, EN_I2SIN_ENABLE);
- }
- }
-
- return 0;
-}
-EXPORT_SYMBOL(cx88_video_mux);
-
-/* ------------------------------------------------------------------ */
-
-static int start_video_dma(struct cx8800_dev *dev,
- struct cx88_dmaqueue *q,
- struct cx88_buffer *buf)
-{
- struct cx88_core *core = dev->core;
-
- /* setup fifo + format */
- cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21],
- buf->bpl, buf->risc.dma);
- cx88_set_scale(core, buf->vb.width, buf->vb.height, buf->vb.field);
- cx_write(MO_COLOR_CTRL, buf->fmt->cxformat | ColorFormatGamma);
-
- /* reset counter */
- cx_write(MO_VIDY_GPCNTRL,GP_COUNT_CONTROL_RESET);
- q->count = 1;
-
- /* enable irqs */
- cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_VIDINT);
-
- /* Enables corresponding bits at PCI_INT_STAT:
- bits 0 to 4: video, audio, transport stream, VIP, Host
- bit 7: timer
- bits 8 and 9: DMA complete for: SRC, DST
- bits 10 and 11: BERR signal asserted for RISC: RD, WR
- bits 12 to 15: BERR signal asserted for: BRDG, SRC, DST, IPB
- */
- cx_set(MO_VID_INTMSK, 0x0f0011);
-
- /* enable capture */
- cx_set(VID_CAPTURE_CONTROL,0x06);
-
- /* start dma */
- cx_set(MO_DEV_CNTRL2, (1<<5));
- cx_set(MO_VID_DMACNTRL, 0x11); /* Planar Y and packed FIFO and RISC enable */
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int stop_video_dma(struct cx8800_dev *dev)
-{
- struct cx88_core *core = dev->core;
-
- /* stop dma */
- cx_clear(MO_VID_DMACNTRL, 0x11);
-
- /* disable capture */
- cx_clear(VID_CAPTURE_CONTROL,0x06);
-
- /* disable irqs */
- cx_clear(MO_PCI_INTMSK, PCI_INT_VIDINT);
- cx_clear(MO_VID_INTMSK, 0x0f0011);
- return 0;
-}
-#endif
-
-static int restart_video_queue(struct cx8800_dev *dev,
- struct cx88_dmaqueue *q)
-{
- struct cx88_core *core = dev->core;
- struct cx88_buffer *buf, *prev;
-
- if (!list_empty(&q->active)) {
- buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
- dprintk(2,"restart_queue [%p/%d]: restart dma\n",
- buf, buf->vb.i);
- start_video_dma(dev, q, buf);
- list_for_each_entry(buf, &q->active, vb.queue)
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- return 0;
- }
-
- prev = NULL;
- for (;;) {
- if (list_empty(&q->queued))
- return 0;
- buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
- if (NULL == prev) {
- list_move_tail(&buf->vb.queue, &q->active);
- start_video_dma(dev, q, buf);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- dprintk(2,"[%p/%d] restart_queue - first active\n",
- buf,buf->vb.i);
-
- } else if (prev->vb.width == buf->vb.width &&
- prev->vb.height == buf->vb.height &&
- prev->fmt == buf->fmt) {
- list_move_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- dprintk(2,"[%p/%d] restart_queue - move to active\n",
- buf,buf->vb.i);
- } else {
- return 0;
- }
- prev = buf;
- }
-}
-
-/* ------------------------------------------------------------------ */
-
-static int
-buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
-{
- struct cx8800_fh *fh = q->priv_data;
- struct cx8800_dev *dev = fh->dev;
-
- *size = dev->fmt->depth * dev->width * dev->height >> 3;
- if (0 == *count)
- *count = 32;
- if (*size * *count > vid_limit * 1024 * 1024)
- *count = (vid_limit * 1024 * 1024) / *size;
- return 0;
-}
-
-static int
-buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct cx8800_fh *fh = q->priv_data;
- struct cx8800_dev *dev = fh->dev;
- struct cx88_core *core = dev->core;
- struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
- struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
- int rc, init_buffer = 0;
-
- BUG_ON(NULL == dev->fmt);
- if (dev->width < 48 || dev->width > norm_maxw(core->tvnorm) ||
- dev->height < 32 || dev->height > norm_maxh(core->tvnorm))
- return -EINVAL;
- buf->vb.size = (dev->width * dev->height * dev->fmt->depth) >> 3;
- if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
- return -EINVAL;
-
- if (buf->fmt != dev->fmt ||
- buf->vb.width != dev->width ||
- buf->vb.height != dev->height ||
- buf->vb.field != field) {
- buf->fmt = dev->fmt;
- buf->vb.width = dev->width;
- buf->vb.height = dev->height;
- buf->vb.field = field;
- init_buffer = 1;
- }
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- init_buffer = 1;
- if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
- goto fail;
- }
-
- if (init_buffer) {
- buf->bpl = buf->vb.width * buf->fmt->depth >> 3;
- switch (buf->vb.field) {
- case V4L2_FIELD_TOP:
- cx88_risc_buffer(dev->pci, &buf->risc,
- dma->sglist, 0, UNSET,
- buf->bpl, 0, buf->vb.height);
- break;
- case V4L2_FIELD_BOTTOM:
- cx88_risc_buffer(dev->pci, &buf->risc,
- dma->sglist, UNSET, 0,
- buf->bpl, 0, buf->vb.height);
- break;
- case V4L2_FIELD_INTERLACED:
- cx88_risc_buffer(dev->pci, &buf->risc,
- dma->sglist, 0, buf->bpl,
- buf->bpl, buf->bpl,
- buf->vb.height >> 1);
- break;
- case V4L2_FIELD_SEQ_TB:
- cx88_risc_buffer(dev->pci, &buf->risc,
- dma->sglist,
- 0, buf->bpl * (buf->vb.height >> 1),
- buf->bpl, 0,
- buf->vb.height >> 1);
- break;
- case V4L2_FIELD_SEQ_BT:
- cx88_risc_buffer(dev->pci, &buf->risc,
- dma->sglist,
- buf->bpl * (buf->vb.height >> 1), 0,
- buf->bpl, 0,
- buf->vb.height >> 1);
- break;
- default:
- BUG();
- }
- }
- dprintk(2,"[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
- buf, buf->vb.i,
- dev->width, dev->height, dev->fmt->depth, dev->fmt->name,
- (unsigned long)buf->risc.dma);
-
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
- fail:
- cx88_free_buffer(q,buf);
- return rc;
-}
-
-static void
-buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
- struct cx88_buffer *prev;
- struct cx8800_fh *fh = vq->priv_data;
- struct cx8800_dev *dev = fh->dev;
- struct cx88_core *core = dev->core;
- struct cx88_dmaqueue *q = &dev->vidq;
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue,&q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2,"[%p/%d] buffer_queue - append to queued\n",
- buf, buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue,&q->active);
- start_video_dma(dev, q, buf);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- dprintk(2,"[%p/%d] buffer_queue - first active\n",
- buf, buf->vb.i);
-
- } else {
- prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
- if (prev->vb.width == buf->vb.width &&
- prev->vb.height == buf->vb.height &&
- prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue,&q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- dprintk(2,"[%p/%d] buffer_queue - append to active\n",
- buf, buf->vb.i);
-
- } else {
- list_add_tail(&buf->vb.queue,&q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2,"[%p/%d] buffer_queue - first queued\n",
- buf, buf->vb.i);
- }
- }
-}
-
-static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
-
- cx88_free_buffer(q,buf);
-}
-
-static const struct videobuf_queue_ops cx8800_video_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-/* ------------------------------------------------------------------ */
-
-
-/* ------------------------------------------------------------------ */
-
-static struct videobuf_queue *get_queue(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx8800_fh *fh = file->private_data;
-
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- return &fh->vidq;
- case VFL_TYPE_VBI:
- return &fh->vbiq;
- default:
- BUG();
- return NULL;
- }
-}
-
-static int get_resource(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
-
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- return RESOURCE_VIDEO;
- case VFL_TYPE_VBI:
- return RESOURCE_VBI;
- default:
- BUG();
- return 0;
- }
-}
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx8800_dev *dev = video_drvdata(file);
- struct cx88_core *core = dev->core;
- struct cx8800_fh *fh;
- enum v4l2_buf_type type = 0;
- int radio = 0;
-
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- case VFL_TYPE_VBI:
- type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- case VFL_TYPE_RADIO:
- radio = 1;
- break;
- }
-
- dprintk(1, "open dev=%s radio=%d type=%s\n",
- video_device_node_name(vdev), radio, v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh),GFP_KERNEL);
- if (unlikely(!fh))
- return -ENOMEM;
-
- v4l2_fh_init(&fh->fh, vdev);
- file->private_data = fh;
- fh->dev = dev;
-
- mutex_lock(&core->lock);
-
- videobuf_queue_sg_init(&fh->vidq, &cx8800_video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx88_buffer),
- fh, NULL);
- videobuf_queue_sg_init(&fh->vbiq, &cx8800_vbi_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VBI_CAPTURE,
- V4L2_FIELD_SEQ_TB,
- sizeof(struct cx88_buffer),
- fh, NULL);
-
- if (vdev->vfl_type == VFL_TYPE_RADIO) {
- dprintk(1,"video_open: setting radio device\n");
- cx_write(MO_GP3_IO, core->board.radio.gpio3);
- cx_write(MO_GP0_IO, core->board.radio.gpio0);
- cx_write(MO_GP1_IO, core->board.radio.gpio1);
- cx_write(MO_GP2_IO, core->board.radio.gpio2);
- if (core->board.radio.audioroute) {
- if(core->board.audio_chip &&
- core->board.audio_chip == V4L2_IDENT_WM8775) {
- call_all(core, audio, s_routing,
- core->board.radio.audioroute, 0, 0);
- }
- /* "I2S ADC mode" */
- core->tvaudio = WW_I2SADC;
- cx88_set_tvaudio(core);
- } else {
- /* FM Mode */
- core->tvaudio = WW_FM;
- cx88_set_tvaudio(core);
- cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
- }
- call_all(core, tuner, s_radio);
- }
-
- core->users++;
- mutex_unlock(&core->lock);
- v4l2_fh_add(&fh->fh);
-
- return 0;
-}
-
-static ssize_t
-video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx8800_fh *fh = file->private_data;
-
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- if (res_locked(fh->dev,RESOURCE_VIDEO))
- return -EBUSY;
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
- case VFL_TYPE_VBI:
- if (!res_get(fh->dev,fh,RESOURCE_VBI))
- return -EBUSY;
- return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1,
- file->f_flags & O_NONBLOCK);
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int
-video_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx8800_fh *fh = file->private_data;
- struct cx88_buffer *buf;
- unsigned int rc = v4l2_ctrl_poll(file, wait);
-
- if (vdev->vfl_type == VFL_TYPE_VBI) {
- if (!res_get(fh->dev,fh,RESOURCE_VBI))
- return rc | POLLERR;
- return rc | videobuf_poll_stream(file, &fh->vbiq, wait);
- }
- mutex_lock(&fh->vidq.vb_lock);
- if (res_check(fh,RESOURCE_VIDEO)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- goto done;
- buf = list_entry(fh->vidq.stream.next,struct cx88_buffer,vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx88_buffer*)fh->vidq.read_buf;
- if (NULL == buf)
- goto done;
- }
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE ||
- buf->vb.state == VIDEOBUF_ERROR)
- rc |= POLLIN|POLLRDNORM;
-done:
- mutex_unlock(&fh->vidq.vb_lock);
- return rc;
-}
-
-static int video_release(struct file *file)
-{
- struct cx8800_fh *fh = file->private_data;
- struct cx8800_dev *dev = fh->dev;
-
- /* turn off overlay */
- if (res_check(fh, RESOURCE_OVERLAY)) {
- /* FIXME */
- res_free(dev,fh,RESOURCE_OVERLAY);
- }
-
- /* stop video capture */
- if (res_check(fh, RESOURCE_VIDEO)) {
- videobuf_queue_cancel(&fh->vidq);
- res_free(dev,fh,RESOURCE_VIDEO);
- }
- if (fh->vidq.read_buf) {
- buffer_release(&fh->vidq,fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- /* stop vbi capture */
- if (res_check(fh, RESOURCE_VBI)) {
- videobuf_stop(&fh->vbiq);
- res_free(dev,fh,RESOURCE_VBI);
- }
-
- videobuf_mmap_free(&fh->vidq);
- videobuf_mmap_free(&fh->vbiq);
-
- mutex_lock(&dev->core->lock);
- v4l2_fh_del(&fh->fh);
- v4l2_fh_exit(&fh->fh);
- file->private_data = NULL;
- kfree(fh);
-
- dev->core->users--;
- if (!dev->core->users)
- call_all(dev->core, core, s_power, 0);
- mutex_unlock(&dev->core->lock);
-
- return 0;
-}
-
-static int
-video_mmap(struct file *file, struct vm_area_struct * vma)
-{
- return videobuf_mmap_mapper(get_queue(file), vma);
-}
-
-/* ------------------------------------------------------------------ */
-/* VIDEO CTRL IOCTLS */
-
-static int cx8800_s_vid_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct cx88_core *core =
- container_of(ctrl->handler, struct cx88_core, video_hdl);
- const struct cx88_ctrl *cc = ctrl->priv;
- u32 value, mask;
-
- mask = cc->mask;
- switch (ctrl->id) {
- case V4L2_CID_SATURATION:
- /* special v_sat handling */
-
- value = ((ctrl->val - cc->off) << cc->shift) & cc->mask;
-
- if (core->tvnorm & V4L2_STD_SECAM) {
- /* For SECAM, both U and V sat should be equal */
- value = value << 8 | value;
- } else {
- /* Keeps U Saturation proportional to V Sat */
- value = (value * 0x5a) / 0x7f << 8 | value;
- }
- mask = 0xffff;
- break;
- case V4L2_CID_SHARPNESS:
- /* 0b000, 0b100, 0b101, 0b110, or 0b111 */
- value = (ctrl->val < 1 ? 0 : ((ctrl->val + 3) << 7));
- /* needs to be set for both fields */
- cx_andor(MO_FILTER_EVEN, mask, value);
- break;
- case V4L2_CID_CHROMA_AGC:
- value = ((ctrl->val - cc->off) << cc->shift) & cc->mask;
- break;
- default:
- value = ((ctrl->val - cc->off) << cc->shift) & cc->mask;
- break;
- }
- dprintk(1, "set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
- ctrl->id, ctrl->name, ctrl->val, cc->reg, value,
- mask, cc->sreg ? " [shadowed]" : "");
- if (cc->sreg)
- cx_sandor(cc->sreg, cc->reg, mask, value);
- else
- cx_andor(cc->reg, mask, value);
- return 0;
-}
-
-static int cx8800_s_aud_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct cx88_core *core =
- container_of(ctrl->handler, struct cx88_core, audio_hdl);
- const struct cx88_ctrl *cc = ctrl->priv;
- u32 value,mask;
-
- /* Pass changes onto any WM8775 */
- if (core->board.audio_chip == V4L2_IDENT_WM8775) {
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- wm8775_s_ctrl(core, ctrl->id, ctrl->val);
- break;
- case V4L2_CID_AUDIO_VOLUME:
- wm8775_s_ctrl(core, ctrl->id, (ctrl->val) ?
- (0x90 + ctrl->val) << 8 : 0);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- wm8775_s_ctrl(core, ctrl->id, ctrl->val << 9);
- break;
- default:
- break;
- }
- }
-
- mask = cc->mask;
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_BALANCE:
- value = (ctrl->val < 0x40) ? (0x7f - ctrl->val) : (ctrl->val - 0x40);
- break;
- case V4L2_CID_AUDIO_VOLUME:
- value = 0x3f - (ctrl->val & 0x3f);
- break;
- default:
- value = ((ctrl->val - cc->off) << cc->shift) & cc->mask;
- break;
- }
- dprintk(1,"set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
- ctrl->id, ctrl->name, ctrl->val, cc->reg, value,
- mask, cc->sreg ? " [shadowed]" : "");
- if (cc->sreg)
- cx_sandor(cc->sreg, cc->reg, mask, value);
- else
- cx_andor(cc->reg, mask, value);
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-/* VIDEO IOCTLS */
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx8800_fh *fh = priv;
- struct cx8800_dev *dev = fh->dev;
-
- f->fmt.pix.width = dev->width;
- f->fmt.pix.height = dev->height;
- f->fmt.pix.field = fh->vidq.field;
- f->fmt.pix.pixelformat = dev->fmt->fourcc;
- f->fmt.pix.bytesperline =
- (f->fmt.pix.width * dev->fmt->depth) >> 3;
- f->fmt.pix.sizeimage =
- f->fmt.pix.height * f->fmt.pix.bytesperline;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core;
- const struct cx8800_fmt *fmt;
- enum v4l2_field field;
- unsigned int maxw, maxh;
-
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- if (NULL == fmt)
- return -EINVAL;
-
- field = f->fmt.pix.field;
- maxw = norm_maxw(core->tvnorm);
- maxh = norm_maxh(core->tvnorm);
-
- if (V4L2_FIELD_ANY == field) {
- field = (f->fmt.pix.height > maxh/2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_BOTTOM;
- }
-
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- break;
- default:
- return -EINVAL;
- }
-
- f->fmt.pix.field = field;
- v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,
- &f->fmt.pix.height, 32, maxh, 0, 0);
- f->fmt.pix.bytesperline =
- (f->fmt.pix.width * fmt->depth) >> 3;
- f->fmt.pix.sizeimage =
- f->fmt.pix.height * f->fmt.pix.bytesperline;
-
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx8800_fh *fh = priv;
- struct cx8800_dev *dev = fh->dev;
- int err = vidioc_try_fmt_vid_cap (file,priv,f);
-
- if (0 != err)
- return err;
- dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- dev->width = f->fmt.pix.width;
- dev->height = f->fmt.pix.height;
- fh->vidq.field = f->fmt.pix.field;
- return 0;
-}
-
-void cx88_querycap(struct file *file, struct cx88_core *core,
- struct v4l2_capability *cap)
-{
- struct video_device *vdev = video_devdata(file);
-
- strlcpy(cap->card, core->board.name, sizeof(cap->card));
- cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
- if (UNSET != core->board.tuner_type)
- cap->device_caps |= V4L2_CAP_TUNER;
- switch (vdev->vfl_type) {
- case VFL_TYPE_RADIO:
- cap->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER;
- break;
- case VFL_TYPE_GRABBER:
- cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE;
- break;
- case VFL_TYPE_VBI:
- cap->device_caps |= V4L2_CAP_VBI_CAPTURE;
- break;
- }
- cap->capabilities = cap->device_caps | V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_VBI_CAPTURE | V4L2_CAP_DEVICE_CAPS;
- if (core->board.radio.type == CX88_RADIO)
- cap->capabilities |= V4L2_CAP_RADIO;
-}
-EXPORT_SYMBOL(cx88_querycap);
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct cx8800_dev *dev = ((struct cx8800_fh *)priv)->dev;
- struct cx88_core *core = dev->core;
-
- strcpy(cap->driver, "cx8800");
- sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
- cx88_querycap(file, core, cap);
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (unlikely(f->index >= ARRAY_SIZE(formats)))
- return -EINVAL;
-
- strlcpy(f->description,formats[f->index].name,sizeof(f->description));
- f->pixelformat = formats[f->index].fourcc;
-
- return 0;
-}
-
-static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p)
-{
- return videobuf_reqbufs(get_queue(file), p);
-}
-
-static int vidioc_querybuf (struct file *file, void *priv, struct v4l2_buffer *p)
-{
- return videobuf_querybuf(get_queue(file), p);
-}
-
-static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p)
-{
- return videobuf_qbuf(get_queue(file), p);
-}
-
-static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p)
-{
- return videobuf_dqbuf(get_queue(file), p,
- file->f_flags & O_NONBLOCK);
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx8800_fh *fh = priv;
- struct cx8800_dev *dev = fh->dev;
-
- if ((vdev->vfl_type == VFL_TYPE_GRABBER && i != V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
- (vdev->vfl_type == VFL_TYPE_VBI && i != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
-
- if (unlikely(!res_get(dev, fh, get_resource(file))))
- return -EBUSY;
- return videobuf_streamon(get_queue(file));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx8800_fh *fh = priv;
- struct cx8800_dev *dev = fh->dev;
- int err, res;
-
- if ((vdev->vfl_type == VFL_TYPE_GRABBER && i != V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
- (vdev->vfl_type == VFL_TYPE_VBI && i != V4L2_BUF_TYPE_VBI_CAPTURE))
- return -EINVAL;
-
- res = get_resource(file);
- err = videobuf_streamoff(get_queue(file));
- if (err < 0)
- return err;
- res_free(dev,fh,res);
- return 0;
-}
-
-static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm)
-{
- struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core;
-
- *tvnorm = core->tvnorm;
- return 0;
-}
-
-static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *tvnorms)
-{
- struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core;
-
- mutex_lock(&core->lock);
- cx88_set_tvnorm(core,*tvnorms);
- mutex_unlock(&core->lock);
-
- return 0;
-}
-
-/* only one input in this sample driver */
-int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i)
-{
- static const char * const iname[] = {
- [ CX88_VMUX_COMPOSITE1 ] = "Composite1",
- [ CX88_VMUX_COMPOSITE2 ] = "Composite2",
- [ CX88_VMUX_COMPOSITE3 ] = "Composite3",
- [ CX88_VMUX_COMPOSITE4 ] = "Composite4",
- [ CX88_VMUX_SVIDEO ] = "S-Video",
- [ CX88_VMUX_TELEVISION ] = "Television",
- [ CX88_VMUX_CABLE ] = "Cable TV",
- [ CX88_VMUX_DVB ] = "DVB",
- [ CX88_VMUX_DEBUG ] = "for debug only",
- };
- unsigned int n = i->index;
-
- if (n >= 4)
- return -EINVAL;
- if (0 == INPUT(n).type)
- return -EINVAL;
- i->type = V4L2_INPUT_TYPE_CAMERA;
- strcpy(i->name,iname[INPUT(n).type]);
- if ((CX88_VMUX_TELEVISION == INPUT(n).type) ||
- (CX88_VMUX_CABLE == INPUT(n).type)) {
- i->type = V4L2_INPUT_TYPE_TUNER;
- }
- i->std = CX88_NORMS;
- return 0;
-}
-EXPORT_SYMBOL(cx88_enum_input);
-
-static int vidioc_enum_input (struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core;
- return cx88_enum_input (core,i);
-}
-
-static int vidioc_g_input (struct file *file, void *priv, unsigned int *i)
-{
- struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core;
-
- *i = core->input;
- return 0;
-}
-
-static int vidioc_s_input (struct file *file, void *priv, unsigned int i)
-{
- struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core;
-
- if (i >= 4)
- return -EINVAL;
- if (0 == INPUT(i).type)
- return -EINVAL;
-
- mutex_lock(&core->lock);
- cx88_newstation(core);
- cx88_video_mux(core,i);
- mutex_unlock(&core->lock);
- return 0;
-}
-
-static int vidioc_g_tuner (struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core;
- u32 reg;
-
- if (unlikely(UNSET == core->board.tuner_type))
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
-
- strcpy(t->name, "Television");
- t->capability = V4L2_TUNER_CAP_NORM;
- t->rangehigh = 0xffffffffUL;
- call_all(core, tuner, g_tuner, t);
-
- cx88_get_stereo(core ,t);
- reg = cx_read(MO_DEVICE_STATUS);
- t->signal = (reg & (1<<5)) ? 0xffff : 0x0000;
- return 0;
-}
-
-static int vidioc_s_tuner (struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core;
-
- if (UNSET == core->board.tuner_type)
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
-
- cx88_set_stereo(core, t->audmode, 1);
- return 0;
-}
-
-static int vidioc_g_frequency (struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct cx8800_fh *fh = priv;
- struct cx88_core *core = fh->dev->core;
-
- if (unlikely(UNSET == core->board.tuner_type))
- return -EINVAL;
- if (f->tuner)
- return -EINVAL;
-
- f->frequency = core->freq;
-
- call_all(core, tuner, g_frequency, f);
-
- return 0;
-}
-
-int cx88_set_freq (struct cx88_core *core,
- struct v4l2_frequency *f)
-{
- if (unlikely(UNSET == core->board.tuner_type))
- return -EINVAL;
- if (unlikely(f->tuner != 0))
- return -EINVAL;
-
- mutex_lock(&core->lock);
- cx88_newstation(core);
- call_all(core, tuner, s_frequency, f);
- call_all(core, tuner, g_frequency, f);
- core->freq = f->frequency;
-
- /* When changing channels it is required to reset TVAUDIO */
- msleep (10);
- cx88_set_tvaudio(core);
-
- mutex_unlock(&core->lock);
-
- return 0;
-}
-EXPORT_SYMBOL(cx88_set_freq);
-
-static int vidioc_s_frequency (struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct cx8800_fh *fh = priv;
- struct cx88_core *core = fh->dev->core;
-
- return cx88_set_freq(core, f);
-}
-
-static int vidioc_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- if (!v4l2_chip_match_host(&chip->match))
- return -EINVAL;
- chip->revision = 0;
- chip->ident = V4L2_IDENT_UNKNOWN;
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vidioc_g_register (struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core;
-
- if (!v4l2_chip_match_host(&reg->match))
- return -EINVAL;
- /* cx2388x has a 24-bit register space */
- reg->val = cx_read(reg->reg & 0xffffff);
- reg->size = 4;
- return 0;
-}
-
-static int vidioc_s_register (struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core;
-
- if (!v4l2_chip_match_host(&reg->match))
- return -EINVAL;
- cx_write(reg->reg & 0xffffff, reg->val);
- return 0;
-}
-#endif
-
-/* ----------------------------------------------------------- */
-/* RADIO ESPECIFIC IOCTLS */
-/* ----------------------------------------------------------- */
-
-static int radio_g_tuner (struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core;
-
- if (unlikely(t->index > 0))
- return -EINVAL;
-
- strcpy(t->name, "Radio");
-
- call_all(core, tuner, g_tuner, t);
- return 0;
-}
-
-/* FIXME: Should add a standard for radio */
-
-static int radio_s_tuner (struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core;
-
- if (0 != t->index)
- return -EINVAL;
- if (t->audmode > V4L2_TUNER_MODE_STEREO)
- t->audmode = V4L2_TUNER_MODE_STEREO;
-
- call_all(core, tuner, s_tuner, t);
-
- return 0;
-}
-
-/* ----------------------------------------------------------- */
-
-static void cx8800_vid_timeout(unsigned long data)
-{
- struct cx8800_dev *dev = (struct cx8800_dev*)data;
- struct cx88_core *core = dev->core;
- struct cx88_dmaqueue *q = &dev->vidq;
- struct cx88_buffer *buf;
- unsigned long flags;
-
- cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]);
-
- cx_clear(MO_VID_DMACNTRL, 0x11);
- cx_clear(VID_CAPTURE_CONTROL, 0x06);
-
- spin_lock_irqsave(&dev->slock,flags);
- while (!list_empty(&q->active)) {
- buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
- list_del(&buf->vb.queue);
- buf->vb.state = VIDEOBUF_ERROR;
- wake_up(&buf->vb.done);
- printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", core->name,
- buf, buf->vb.i, (unsigned long)buf->risc.dma);
- }
- restart_video_queue(dev,q);
- spin_unlock_irqrestore(&dev->slock,flags);
-}
-
-static const char *cx88_vid_irqs[32] = {
- "y_risci1", "u_risci1", "v_risci1", "vbi_risc1",
- "y_risci2", "u_risci2", "v_risci2", "vbi_risc2",
- "y_oflow", "u_oflow", "v_oflow", "vbi_oflow",
- "y_sync", "u_sync", "v_sync", "vbi_sync",
- "opc_err", "par_err", "rip_err", "pci_abort",
-};
-
-static void cx8800_vid_irq(struct cx8800_dev *dev)
-{
- struct cx88_core *core = dev->core;
- u32 status, mask, count;
-
- status = cx_read(MO_VID_INTSTAT);
- mask = cx_read(MO_VID_INTMSK);
- if (0 == (status & mask))
- return;
- cx_write(MO_VID_INTSTAT, status);
- if (irq_debug || (status & mask & ~0xff))
- cx88_print_irqbits(core->name, "irq vid",
- cx88_vid_irqs, ARRAY_SIZE(cx88_vid_irqs),
- status, mask);
-
- /* risc op code error */
- if (status & (1 << 16)) {
- printk(KERN_WARNING "%s/0: video risc op code error\n",core->name);
- cx_clear(MO_VID_DMACNTRL, 0x11);
- cx_clear(VID_CAPTURE_CONTROL, 0x06);
- cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]);
- }
-
- /* risc1 y */
- if (status & 0x01) {
- spin_lock(&dev->slock);
- count = cx_read(MO_VIDY_GPCNT);
- cx88_wakeup(core, &dev->vidq, count);
- spin_unlock(&dev->slock);
- }
-
- /* risc1 vbi */
- if (status & 0x08) {
- spin_lock(&dev->slock);
- count = cx_read(MO_VBI_GPCNT);
- cx88_wakeup(core, &dev->vbiq, count);
- spin_unlock(&dev->slock);
- }
-
- /* risc2 y */
- if (status & 0x10) {
- dprintk(2,"stopper video\n");
- spin_lock(&dev->slock);
- restart_video_queue(dev,&dev->vidq);
- spin_unlock(&dev->slock);
- }
-
- /* risc2 vbi */
- if (status & 0x80) {
- dprintk(2,"stopper vbi\n");
- spin_lock(&dev->slock);
- cx8800_restart_vbi_queue(dev,&dev->vbiq);
- spin_unlock(&dev->slock);
- }
-}
-
-static irqreturn_t cx8800_irq(int irq, void *dev_id)
-{
- struct cx8800_dev *dev = dev_id;
- struct cx88_core *core = dev->core;
- u32 status;
- int loop, handled = 0;
-
- for (loop = 0; loop < 10; loop++) {
- status = cx_read(MO_PCI_INTSTAT) &
- (core->pci_irqmask | PCI_INT_VIDINT);
- if (0 == status)
- goto out;
- cx_write(MO_PCI_INTSTAT, status);
- handled = 1;
-
- if (status & core->pci_irqmask)
- cx88_core_irq(core,status);
- if (status & PCI_INT_VIDINT)
- cx8800_vid_irq(dev);
- };
- if (10 == loop) {
- printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
- core->name);
- cx_write(MO_PCI_INTMSK,0);
- }
-
- out:
- return IRQ_RETVAL(handled);
-}
-
-/* ----------------------------------------------------------- */
-/* exported stuff */
-
-static const struct v4l2_file_operations video_fops =
-{
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = video_mmap,
- .unlocked_ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_g_std = vidioc_g_std,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vidioc_g_register,
- .vidioc_s_register = vidioc_s_register,
-#endif
-};
-
-static const struct video_device cx8800_video_template = {
- .name = "cx8800-video",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX88_NORMS,
-};
-
-static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_g_fmt_vbi_cap = cx8800_vbi_fmt,
- .vidioc_try_fmt_vbi_cap = cx8800_vbi_fmt,
- .vidioc_s_fmt_vbi_cap = cx8800_vbi_fmt,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_g_std = vidioc_g_std,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vidioc_g_register,
- .vidioc_s_register = vidioc_s_register,
-#endif
-};
-
-static const struct video_device cx8800_vbi_template = {
- .name = "cx8800-vbi",
- .fops = &video_fops,
- .ioctl_ops = &vbi_ioctl_ops,
- .tvnorms = CX88_NORMS,
-};
-
-static const struct v4l2_file_operations radio_fops =
-{
- .owner = THIS_MODULE,
- .open = video_open,
- .poll = v4l2_ctrl_poll,
- .release = video_release,
- .unlocked_ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops radio_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_g_tuner = radio_g_tuner,
- .vidioc_s_tuner = radio_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vidioc_g_register,
- .vidioc_s_register = vidioc_s_register,
-#endif
-};
-
-static const struct video_device cx8800_radio_template = {
- .name = "cx8800-radio",
- .fops = &radio_fops,
- .ioctl_ops = &radio_ioctl_ops,
-};
-
-static const struct v4l2_ctrl_ops cx8800_ctrl_vid_ops = {
- .s_ctrl = cx8800_s_vid_ctrl,
-};
-
-static const struct v4l2_ctrl_ops cx8800_ctrl_aud_ops = {
- .s_ctrl = cx8800_s_aud_ctrl,
-};
-
-/* ----------------------------------------------------------- */
-
-static void cx8800_unregister_video(struct cx8800_dev *dev)
-{
- if (dev->radio_dev) {
- if (video_is_registered(dev->radio_dev))
- video_unregister_device(dev->radio_dev);
- else
- video_device_release(dev->radio_dev);
- dev->radio_dev = NULL;
- }
- if (dev->vbi_dev) {
- if (video_is_registered(dev->vbi_dev))
- video_unregister_device(dev->vbi_dev);
- else
- video_device_release(dev->vbi_dev);
- dev->vbi_dev = NULL;
- }
- if (dev->video_dev) {
- if (video_is_registered(dev->video_dev))
- video_unregister_device(dev->video_dev);
- else
- video_device_release(dev->video_dev);
- dev->video_dev = NULL;
- }
-}
-
-static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
-{
- struct cx8800_dev *dev;
- struct cx88_core *core;
- int err;
- int i;
-
- dev = kzalloc(sizeof(*dev),GFP_KERNEL);
- if (NULL == dev)
- return -ENOMEM;
-
- /* pci init */
- dev->pci = pci_dev;
- if (pci_enable_device(pci_dev)) {
- err = -EIO;
- goto fail_free;
- }
- core = cx88_core_get(dev->pci);
- if (NULL == core) {
- err = -EINVAL;
- goto fail_free;
- }
- dev->core = core;
-
- /* print pci info */
- dev->pci_rev = pci_dev->revision;
- pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
- printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
- "latency: %d, mmio: 0x%llx\n", core->name,
- pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
- dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0));
-
- pci_set_master(pci_dev);
- if (!pci_dma_supported(pci_dev,DMA_BIT_MASK(32))) {
- printk("%s/0: Oops: no 32bit PCI DMA ???\n",core->name);
- err = -EIO;
- goto fail_core;
- }
-
- /* initialize driver struct */
- spin_lock_init(&dev->slock);
- core->tvnorm = V4L2_STD_NTSC_M;
-
- /* init video dma queues */
- INIT_LIST_HEAD(&dev->vidq.active);
- INIT_LIST_HEAD(&dev->vidq.queued);
- dev->vidq.timeout.function = cx8800_vid_timeout;
- dev->vidq.timeout.data = (unsigned long)dev;
- init_timer(&dev->vidq.timeout);
- cx88_risc_stopper(dev->pci,&dev->vidq.stopper,
- MO_VID_DMACNTRL,0x11,0x00);
-
- /* init vbi dma queues */
- INIT_LIST_HEAD(&dev->vbiq.active);
- INIT_LIST_HEAD(&dev->vbiq.queued);
- dev->vbiq.timeout.function = cx8800_vbi_timeout;
- dev->vbiq.timeout.data = (unsigned long)dev;
- init_timer(&dev->vbiq.timeout);
- cx88_risc_stopper(dev->pci,&dev->vbiq.stopper,
- MO_VID_DMACNTRL,0x88,0x00);
-
- /* get irq */
- err = request_irq(pci_dev->irq, cx8800_irq,
- IRQF_SHARED | IRQF_DISABLED, core->name, dev);
- if (err < 0) {
- printk(KERN_ERR "%s/0: can't get IRQ %d\n",
- core->name,pci_dev->irq);
- goto fail_core;
- }
- cx_set(MO_PCI_INTMSK, core->pci_irqmask);
-
- for (i = 0; i < CX8800_AUD_CTLS; i++) {
- const struct cx88_ctrl *cc = &cx8800_aud_ctls[i];
- struct v4l2_ctrl *vc;
-
- vc = v4l2_ctrl_new_std(&core->audio_hdl, &cx8800_ctrl_aud_ops,
- cc->id, cc->minimum, cc->maximum, cc->step, cc->default_value);
- if (vc == NULL) {
- err = core->audio_hdl.error;
- goto fail_core;
- }
- vc->priv = (void *)cc;
- }
-
- for (i = 0; i < CX8800_VID_CTLS; i++) {
- const struct cx88_ctrl *cc = &cx8800_vid_ctls[i];
- struct v4l2_ctrl *vc;
-
- vc = v4l2_ctrl_new_std(&core->video_hdl, &cx8800_ctrl_vid_ops,
- cc->id, cc->minimum, cc->maximum, cc->step, cc->default_value);
- if (vc == NULL) {
- err = core->video_hdl.error;
- goto fail_core;
- }
- vc->priv = (void *)cc;
- if (vc->id == V4L2_CID_CHROMA_AGC)
- core->chroma_agc = vc;
- }
- v4l2_ctrl_add_handler(&core->video_hdl, &core->audio_hdl);
-
- /* load and configure helper modules */
-
- if (core->board.audio_chip == V4L2_IDENT_WM8775) {
- struct i2c_board_info wm8775_info = {
- .type = "wm8775",
- .addr = 0x36 >> 1,
- .platform_data = &core->wm8775_data,
- };
- struct v4l2_subdev *sd;
-
- if (core->boardnr == CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1)
- core->wm8775_data.is_nova_s = true;
- else
- core->wm8775_data.is_nova_s = false;
-
- sd = v4l2_i2c_new_subdev_board(&core->v4l2_dev, &core->i2c_adap,
- &wm8775_info, NULL);
- if (sd != NULL) {
- core->sd_wm8775 = sd;
- sd->grp_id = WM8775_GID;
- }
- }
-
- if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
- /* This probes for a tda9874 as is used on some
- Pixelview Ultra boards. */
- v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
- "tvaudio", 0, I2C_ADDRS(0xb0 >> 1));
- }
-
- switch (core->boardnr) {
- case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
- case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: {
- static const struct i2c_board_info rtc_info = {
- I2C_BOARD_INFO("isl1208", 0x6f)
- };
-
- request_module("rtc-isl1208");
- core->i2c_rtc = i2c_new_device(&core->i2c_adap, &rtc_info);
- }
- /* break intentionally omitted */
- case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
- request_module("ir-kbd-i2c");
- }
-
- /* Sets device info at pci_dev */
- pci_set_drvdata(pci_dev, dev);
-
- dev->width = 320;
- dev->height = 240;
- dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
-
- /* initial device configuration */
- mutex_lock(&core->lock);
- cx88_set_tvnorm(core, core->tvnorm);
- v4l2_ctrl_handler_setup(&core->video_hdl);
- v4l2_ctrl_handler_setup(&core->audio_hdl);
- cx88_video_mux(core, 0);
-
- /* register v4l devices */
- dev->video_dev = cx88_vdev_init(core,dev->pci,
- &cx8800_video_template,"video");
- video_set_drvdata(dev->video_dev, dev);
- dev->video_dev->ctrl_handler = &core->video_hdl;
- err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
- video_nr[core->nr]);
- if (err < 0) {
- printk(KERN_ERR "%s/0: can't register video device\n",
- core->name);
- goto fail_unreg;
- }
- printk(KERN_INFO "%s/0: registered device %s [v4l2]\n",
- core->name, video_device_node_name(dev->video_dev));
-
- dev->vbi_dev = cx88_vdev_init(core,dev->pci,&cx8800_vbi_template,"vbi");
- video_set_drvdata(dev->vbi_dev, dev);
- err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
- vbi_nr[core->nr]);
- if (err < 0) {
- printk(KERN_ERR "%s/0: can't register vbi device\n",
- core->name);
- goto fail_unreg;
- }
- printk(KERN_INFO "%s/0: registered device %s\n",
- core->name, video_device_node_name(dev->vbi_dev));
-
- if (core->board.radio.type == CX88_RADIO) {
- dev->radio_dev = cx88_vdev_init(core,dev->pci,
- &cx8800_radio_template,"radio");
- video_set_drvdata(dev->radio_dev, dev);
- dev->radio_dev->ctrl_handler = &core->audio_hdl;
- err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
- radio_nr[core->nr]);
- if (err < 0) {
- printk(KERN_ERR "%s/0: can't register radio device\n",
- core->name);
- goto fail_unreg;
- }
- printk(KERN_INFO "%s/0: registered device %s\n",
- core->name, video_device_node_name(dev->radio_dev));
- }
-
- /* start tvaudio thread */
- if (core->board.tuner_type != TUNER_ABSENT) {
- core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio");
- if (IS_ERR(core->kthread)) {
- err = PTR_ERR(core->kthread);
- printk(KERN_ERR "%s/0: failed to create cx88 audio thread, err=%d\n",
- core->name, err);
- }
- }
- mutex_unlock(&core->lock);
-
- return 0;
-
-fail_unreg:
- cx8800_unregister_video(dev);
- free_irq(pci_dev->irq, dev);
- mutex_unlock(&core->lock);
-fail_core:
- cx88_core_put(core,dev->pci);
-fail_free:
- kfree(dev);
- return err;
-}
-
-static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
-{
- struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
- struct cx88_core *core = dev->core;
-
- /* stop thread */
- if (core->kthread) {
- kthread_stop(core->kthread);
- core->kthread = NULL;
- }
-
- if (core->ir)
- cx88_ir_stop(core);
-
- cx88_shutdown(core); /* FIXME */
- pci_disable_device(pci_dev);
-
- /* unregister stuff */
-
- free_irq(pci_dev->irq, dev);
- cx8800_unregister_video(dev);
- pci_set_drvdata(pci_dev, NULL);
-
- /* free memory */
- btcx_riscmem_free(dev->pci,&dev->vidq.stopper);
- cx88_core_put(core,dev->pci);
- kfree(dev);
-}
-
-#ifdef CONFIG_PM
-static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
-{
- struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
- struct cx88_core *core = dev->core;
-
- /* stop video+vbi capture */
- spin_lock(&dev->slock);
- if (!list_empty(&dev->vidq.active)) {
- printk("%s/0: suspend video\n", core->name);
- stop_video_dma(dev);
- del_timer(&dev->vidq.timeout);
- }
- if (!list_empty(&dev->vbiq.active)) {
- printk("%s/0: suspend vbi\n", core->name);
- cx8800_stop_vbi_dma(dev);
- del_timer(&dev->vbiq.timeout);
- }
- spin_unlock(&dev->slock);
-
- if (core->ir)
- cx88_ir_stop(core);
- /* FIXME -- shutdown device */
- cx88_shutdown(core);
-
- pci_save_state(pci_dev);
- if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
- pci_disable_device(pci_dev);
- dev->state.disabled = 1;
- }
- return 0;
-}
-
-static int cx8800_resume(struct pci_dev *pci_dev)
-{
- struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
- struct cx88_core *core = dev->core;
- int err;
-
- if (dev->state.disabled) {
- err=pci_enable_device(pci_dev);
- if (err) {
- printk(KERN_ERR "%s/0: can't enable device\n",
- core->name);
- return err;
- }
-
- dev->state.disabled = 0;
- }
- err= pci_set_power_state(pci_dev, PCI_D0);
- if (err) {
- printk(KERN_ERR "%s/0: can't set power state\n", core->name);
- pci_disable_device(pci_dev);
- dev->state.disabled = 1;
-
- return err;
- }
- pci_restore_state(pci_dev);
-
- /* FIXME: re-initialize hardware */
- cx88_reset(core);
- if (core->ir)
- cx88_ir_start(core);
-
- cx_set(MO_PCI_INTMSK, core->pci_irqmask);
-
- /* restart video+vbi capture */
- spin_lock(&dev->slock);
- if (!list_empty(&dev->vidq.active)) {
- printk("%s/0: resume video\n", core->name);
- restart_video_queue(dev,&dev->vidq);
- }
- if (!list_empty(&dev->vbiq.active)) {
- printk("%s/0: resume vbi\n", core->name);
- cx8800_restart_vbi_queue(dev,&dev->vbiq);
- }
- spin_unlock(&dev->slock);
-
- return 0;
-}
-#endif
-
-/* ----------------------------------------------------------- */
-
-static const struct pci_device_id cx8800_pci_tbl[] = {
- {
- .vendor = 0x14f1,
- .device = 0x8800,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- },{
- /* --- end of list --- */
- }
-};
-MODULE_DEVICE_TABLE(pci, cx8800_pci_tbl);
-
-static struct pci_driver cx8800_pci_driver = {
- .name = "cx8800",
- .id_table = cx8800_pci_tbl,
- .probe = cx8800_initdev,
- .remove = __devexit_p(cx8800_finidev),
-#ifdef CONFIG_PM
- .suspend = cx8800_suspend,
- .resume = cx8800_resume,
-#endif
-};
-
-static int __init cx8800_init(void)
-{
- printk(KERN_INFO "cx88/0: cx2388x v4l2 driver version %s loaded\n",
- CX88_VERSION);
- return pci_register_driver(&cx8800_pci_driver);
-}
-
-static void __exit cx8800_fini(void)
-{
- pci_unregister_driver(&cx8800_pci_driver);
-}
-
-module_init(cx8800_init);
-module_exit(cx8800_fini);
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c
deleted file mode 100644
index d77f8ecab9d..00000000000
--- a/drivers/media/video/cx88/cx88-vp3054-i2c.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
-
- cx88-vp3054-i2c.c -- support for the secondary I2C bus of the
- DNTV Live! DVB-T Pro (VP-3054), wired as:
- GPIO[0] -> SCL, GPIO[1] -> SDA
-
- (c) 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-
-#include "cx88.h"
-#include "cx88-vp3054-i2c.h"
-
-MODULE_DESCRIPTION("driver for cx2388x VP3054 design");
-MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
-MODULE_LICENSE("GPL");
-
-/* ----------------------------------------------------------------------- */
-
-static void vp3054_bit_setscl(void *data, int state)
-{
- struct cx8802_dev *dev = data;
- struct cx88_core *core = dev->core;
- struct vp3054_i2c_state *vp3054_i2c = dev->vp3054;
-
- if (state) {
- vp3054_i2c->state |= 0x0001; /* SCL high */
- vp3054_i2c->state &= ~0x0100; /* external pullup */
- } else {
- vp3054_i2c->state &= ~0x0001; /* SCL low */
- vp3054_i2c->state |= 0x0100; /* drive pin */
- }
- cx_write(MO_GP0_IO, 0x010000 | vp3054_i2c->state);
- cx_read(MO_GP0_IO);
-}
-
-static void vp3054_bit_setsda(void *data, int state)
-{
- struct cx8802_dev *dev = data;
- struct cx88_core *core = dev->core;
- struct vp3054_i2c_state *vp3054_i2c = dev->vp3054;
-
- if (state) {
- vp3054_i2c->state |= 0x0002; /* SDA high */
- vp3054_i2c->state &= ~0x0200; /* tristate pin */
- } else {
- vp3054_i2c->state &= ~0x0002; /* SDA low */
- vp3054_i2c->state |= 0x0200; /* drive pin */
- }
- cx_write(MO_GP0_IO, 0x020000 | vp3054_i2c->state);
- cx_read(MO_GP0_IO);
-}
-
-static int vp3054_bit_getscl(void *data)
-{
- struct cx8802_dev *dev = data;
- struct cx88_core *core = dev->core;
- u32 state;
-
- state = cx_read(MO_GP0_IO);
- return (state & 0x01) ? 1 : 0;
-}
-
-static int vp3054_bit_getsda(void *data)
-{
- struct cx8802_dev *dev = data;
- struct cx88_core *core = dev->core;
- u32 state;
-
- state = cx_read(MO_GP0_IO);
- return (state & 0x02) ? 1 : 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_algo_bit_data vp3054_i2c_algo_template = {
- .setsda = vp3054_bit_setsda,
- .setscl = vp3054_bit_setscl,
- .getsda = vp3054_bit_getsda,
- .getscl = vp3054_bit_getscl,
- .udelay = 16,
- .timeout = 200,
-};
-
-/* ----------------------------------------------------------------------- */
-
-int vp3054_i2c_probe(struct cx8802_dev *dev)
-{
- struct cx88_core *core = dev->core;
- struct vp3054_i2c_state *vp3054_i2c;
- int rc;
-
- if (core->boardnr != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
- return 0;
-
- vp3054_i2c = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL);
- if (vp3054_i2c == NULL)
- return -ENOMEM;
- dev->vp3054 = vp3054_i2c;
-
- memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template,
- sizeof(vp3054_i2c->algo));
-
- vp3054_i2c->adap.dev.parent = &dev->pci->dev;
- strlcpy(vp3054_i2c->adap.name, core->name,
- sizeof(vp3054_i2c->adap.name));
- vp3054_i2c->adap.owner = THIS_MODULE;
- vp3054_i2c->algo.data = dev;
- i2c_set_adapdata(&vp3054_i2c->adap, dev);
- vp3054_i2c->adap.algo_data = &vp3054_i2c->algo;
-
- vp3054_bit_setscl(dev,1);
- vp3054_bit_setsda(dev,1);
-
- rc = i2c_bit_add_bus(&vp3054_i2c->adap);
- if (0 != rc) {
- printk("%s: vp3054_i2c register FAILED\n", core->name);
-
- kfree(dev->vp3054);
- dev->vp3054 = NULL;
- }
-
- return rc;
-}
-
-void vp3054_i2c_remove(struct cx8802_dev *dev)
-{
- struct vp3054_i2c_state *vp3054_i2c = dev->vp3054;
-
- if (vp3054_i2c == NULL ||
- dev->core->boardnr != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
- return;
-
- i2c_del_adapter(&vp3054_i2c->adap);
- kfree(vp3054_i2c);
-}
-
-EXPORT_SYMBOL(vp3054_i2c_probe);
-EXPORT_SYMBOL(vp3054_i2c_remove);
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.h b/drivers/media/video/cx88/cx88-vp3054-i2c.h
deleted file mode 100644
index be99c931dc3..00000000000
--- a/drivers/media/video/cx88/cx88-vp3054-i2c.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-
- cx88-vp3054-i2c.h -- support for the secondary I2C bus of the
- DNTV Live! DVB-T Pro (VP-3054), wired as:
- GPIO[0] -> SCL, GPIO[1] -> SDA
-
- (c) 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-/* ----------------------------------------------------------------------- */
-struct vp3054_i2c_state {
- struct i2c_adapter adap;
- struct i2c_algo_bit_data algo;
- u32 state;
-};
-
-/* ----------------------------------------------------------------------- */
-#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
-int vp3054_i2c_probe(struct cx8802_dev *dev);
-void vp3054_i2c_remove(struct cx8802_dev *dev);
-#else
-static inline int vp3054_i2c_probe(struct cx8802_dev *dev)
-{ return 0; }
-static inline void vp3054_i2c_remove(struct cx8802_dev *dev)
-{ }
-#endif
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
deleted file mode 100644
index 0cae0fd9e16..00000000000
--- a/drivers/media/video/cx88/cx88.h
+++ /dev/null
@@ -1,748 +0,0 @@
-/*
- *
- * v4l2 device driver for cx2388x based TV cards
- *
- * (c) 2003,04 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/videodev2.h>
-#include <linux/kdev_t.h>
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-fh.h>
-#include <media/tuner.h>
-#include <media/tveeprom.h>
-#include <media/videobuf-dma-sg.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/cx2341x.h>
-#include <media/videobuf-dvb.h>
-#include <media/ir-kbd-i2c.h>
-#include <media/wm8775.h>
-
-#include "btcx-risc.h"
-#include "cx88-reg.h"
-#include "tuner-xc2028.h"
-
-#include <linux/mutex.h>
-
-#define CX88_VERSION "0.0.9"
-
-#define UNSET (-1U)
-
-#define CX88_MAXBOARDS 8
-
-/* Max number of inputs by card */
-#define MAX_CX88_INPUT 8
-
-/* ----------------------------------------------------------- */
-/* defines and enums */
-
-/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM/LC */
-#define CX88_NORMS (V4L2_STD_ALL \
- & ~V4L2_STD_PAL_H \
- & ~V4L2_STD_NTSC_M_KR \
- & ~V4L2_STD_SECAM_LC)
-
-#define FORMAT_FLAGS_PACKED 0x01
-#define FORMAT_FLAGS_PLANAR 0x02
-
-#define VBI_LINE_COUNT 17
-#define VBI_LINE_LENGTH 2048
-
-#define AUD_RDS_LINES 4
-
-/* need "shadow" registers for some write-only ones ... */
-#define SHADOW_AUD_VOL_CTL 1
-#define SHADOW_AUD_BAL_CTL 2
-#define SHADOW_MAX 3
-
-/* FM Radio deemphasis type */
-enum cx88_deemph_type {
- FM_NO_DEEMPH = 0,
- FM_DEEMPH_50,
- FM_DEEMPH_75
-};
-
-enum cx88_board_type {
- CX88_BOARD_NONE = 0,
- CX88_MPEG_DVB,
- CX88_MPEG_BLACKBIRD
-};
-
-enum cx8802_board_access {
- CX8802_DRVCTL_SHARED = 1,
- CX8802_DRVCTL_EXCLUSIVE = 2,
-};
-
-/* ----------------------------------------------------------- */
-/* tv norms */
-
-static unsigned int inline norm_maxw(v4l2_std_id norm)
-{
- return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768;
-}
-
-
-static unsigned int inline norm_maxh(v4l2_std_id norm)
-{
- return (norm & V4L2_STD_625_50) ? 576 : 480;
-}
-
-/* ----------------------------------------------------------- */
-/* static data */
-
-struct cx8800_fmt {
- const char *name;
- u32 fourcc; /* v4l2 format id */
- int depth;
- int flags;
- u32 cxformat;
-};
-
-/* ----------------------------------------------------------- */
-/* SRAM memory management data (see cx88-core.c) */
-
-#define SRAM_CH21 0 /* video */
-#define SRAM_CH22 1
-#define SRAM_CH23 2
-#define SRAM_CH24 3 /* vbi */
-#define SRAM_CH25 4 /* audio */
-#define SRAM_CH26 5
-#define SRAM_CH28 6 /* mpeg */
-#define SRAM_CH27 7 /* audio rds */
-/* more */
-
-struct sram_channel {
- const char *name;
- u32 cmds_start;
- u32 ctrl_start;
- u32 cdt;
- u32 fifo_start;
- u32 fifo_size;
- u32 ptr1_reg;
- u32 ptr2_reg;
- u32 cnt1_reg;
- u32 cnt2_reg;
-};
-extern const struct sram_channel const cx88_sram_channels[];
-
-/* ----------------------------------------------------------- */
-/* card configuration */
-
-#define CX88_BOARD_NOAUTO UNSET
-#define CX88_BOARD_UNKNOWN 0
-#define CX88_BOARD_HAUPPAUGE 1
-#define CX88_BOARD_GDI 2
-#define CX88_BOARD_PIXELVIEW 3
-#define CX88_BOARD_ATI_WONDER_PRO 4
-#define CX88_BOARD_WINFAST2000XP_EXPERT 5
-#define CX88_BOARD_AVERTV_STUDIO_303 6
-#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7
-#define CX88_BOARD_WINFAST_DV2000 8
-#define CX88_BOARD_LEADTEK_PVR2000 9
-#define CX88_BOARD_IODATA_GVVCP3PCI 10
-#define CX88_BOARD_PROLINK_PLAYTVPVR 11
-#define CX88_BOARD_ASUS_PVR_416 12
-#define CX88_BOARD_MSI_TVANYWHERE 13
-#define CX88_BOARD_KWORLD_DVB_T 14
-#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1 15
-#define CX88_BOARD_KWORLD_LTV883 16
-#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q 17
-#define CX88_BOARD_HAUPPAUGE_DVB_T1 18
-#define CX88_BOARD_CONEXANT_DVB_T1 19
-#define CX88_BOARD_PROVIDEO_PV259 20
-#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS 21
-#define CX88_BOARD_PCHDTV_HD3000 22
-#define CX88_BOARD_DNTV_LIVE_DVB_T 23
-#define CX88_BOARD_HAUPPAUGE_ROSLYN 24
-#define CX88_BOARD_DIGITALLOGIC_MEC 25
-#define CX88_BOARD_IODATA_GVBCTV7E 26
-#define CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO 27
-#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T 28
-#define CX88_BOARD_ADSTECH_DVB_T_PCI 29
-#define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30
-#define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31
-#define CX88_BOARD_AVERMEDIA_ULTRATV_MC_550 32
-#define CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD 33
-#define CX88_BOARD_ATI_HDTVWONDER 34
-#define CX88_BOARD_WINFAST_DTV1000 35
-#define CX88_BOARD_AVERTV_303 36
-#define CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1 37
-#define CX88_BOARD_HAUPPAUGE_NOVASE2_S1 38
-#define CX88_BOARD_KWORLD_DVBS_100 39
-#define CX88_BOARD_HAUPPAUGE_HVR1100 40
-#define CX88_BOARD_HAUPPAUGE_HVR1100LP 41
-#define CX88_BOARD_DNTV_LIVE_DVB_T_PRO 42
-#define CX88_BOARD_KWORLD_DVB_T_CX22702 43
-#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44
-#define CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT 45
-#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID 46
-#define CX88_BOARD_PCHDTV_HD5500 47
-#define CX88_BOARD_KWORLD_MCE200_DELUXE 48
-#define CX88_BOARD_PIXELVIEW_PLAYTV_P7000 49
-#define CX88_BOARD_NPGTECH_REALTV_TOP10FM 50
-#define CX88_BOARD_WINFAST_DTV2000H 51
-#define CX88_BOARD_GENIATECH_DVBS 52
-#define CX88_BOARD_HAUPPAUGE_HVR3000 53
-#define CX88_BOARD_NORWOOD_MICRO 54
-#define CX88_BOARD_TE_DTV_250_OEM_SWANN 55
-#define CX88_BOARD_HAUPPAUGE_HVR1300 56
-#define CX88_BOARD_ADSTECH_PTV_390 57
-#define CX88_BOARD_PINNACLE_PCTV_HD_800i 58
-#define CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO 59
-#define CX88_BOARD_PINNACLE_HYBRID_PCTV 60
-#define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL 61
-#define CX88_BOARD_POWERCOLOR_REAL_ANGEL 62
-#define CX88_BOARD_GENIATECH_X8000_MT 63
-#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO 64
-#define CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD 65
-#define CX88_BOARD_PROLINK_PV_8000GT 66
-#define CX88_BOARD_KWORLD_ATSC_120 67
-#define CX88_BOARD_HAUPPAUGE_HVR4000 68
-#define CX88_BOARD_HAUPPAUGE_HVR4000LITE 69
-#define CX88_BOARD_TEVII_S460 70
-#define CX88_BOARD_OMICOM_SS4_PCI 71
-#define CX88_BOARD_TBS_8920 72
-#define CX88_BOARD_TEVII_S420 73
-#define CX88_BOARD_PROLINK_PV_GLOBAL_XTREME 74
-#define CX88_BOARD_PROF_7300 75
-#define CX88_BOARD_SATTRADE_ST4200 76
-#define CX88_BOARD_TBS_8910 77
-#define CX88_BOARD_PROF_6200 78
-#define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79
-#define CX88_BOARD_HAUPPAUGE_IRONLY 80
-#define CX88_BOARD_WINFAST_DTV1800H 81
-#define CX88_BOARD_WINFAST_DTV2000H_J 82
-#define CX88_BOARD_PROF_7301 83
-#define CX88_BOARD_SAMSUNG_SMT_7020 84
-#define CX88_BOARD_TWINHAN_VP1027_DVBS 85
-#define CX88_BOARD_TEVII_S464 86
-#define CX88_BOARD_WINFAST_DTV2000H_PLUS 87
-#define CX88_BOARD_WINFAST_DTV1800H_XC4000 88
-#define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36 89
-#define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43 90
-
-enum cx88_itype {
- CX88_VMUX_COMPOSITE1 = 1,
- CX88_VMUX_COMPOSITE2,
- CX88_VMUX_COMPOSITE3,
- CX88_VMUX_COMPOSITE4,
- CX88_VMUX_SVIDEO,
- CX88_VMUX_TELEVISION,
- CX88_VMUX_CABLE,
- CX88_VMUX_DVB,
- CX88_VMUX_DEBUG,
- CX88_RADIO,
-};
-
-struct cx88_input {
- enum cx88_itype type;
- u32 gpio0, gpio1, gpio2, gpio3;
- unsigned int vmux:2;
- unsigned int audioroute:4;
-};
-
-struct cx88_board {
- const char *name;
- unsigned int tuner_type;
- unsigned int radio_type;
- unsigned char tuner_addr;
- unsigned char radio_addr;
- int tda9887_conf;
- struct cx88_input input[MAX_CX88_INPUT];
- struct cx88_input radio;
- enum cx88_board_type mpeg;
- unsigned int audio_chip;
- int num_frontends;
-
- /* Used for I2S devices */
- int i2sinputcntl;
-};
-
-struct cx88_subid {
- u16 subvendor;
- u16 subdevice;
- u32 card;
-};
-
-enum cx88_tvaudio {
- WW_NONE = 1,
- WW_BTSC,
- WW_BG,
- WW_DK,
- WW_I,
- WW_L,
- WW_EIAJ,
- WW_I2SPT,
- WW_FM,
- WW_I2SADC,
- WW_M
-};
-
-#define INPUT(nr) (core->board.input[nr])
-
-/* ----------------------------------------------------------- */
-/* device / file handle status */
-
-#define RESOURCE_OVERLAY 1
-#define RESOURCE_VIDEO 2
-#define RESOURCE_VBI 4
-
-#define BUFFER_TIMEOUT msecs_to_jiffies(2000)
-
-/* buffer for one video frame */
-struct cx88_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
-
- /* cx88 specific */
- unsigned int bpl;
- struct btcx_riscmem risc;
- const struct cx8800_fmt *fmt;
- u32 count;
-};
-
-struct cx88_dmaqueue {
- struct list_head active;
- struct list_head queued;
- struct timer_list timeout;
- struct btcx_riscmem stopper;
- u32 count;
-};
-
-struct cx88_core {
- struct list_head devlist;
- atomic_t refcount;
-
- /* board name */
- int nr;
- char name[32];
-
- /* pci stuff */
- int pci_bus;
- int pci_slot;
- u32 __iomem *lmmio;
- u8 __iomem *bmmio;
- u32 shadow[SHADOW_MAX];
- int pci_irqmask;
-
- /* i2c i/o */
- struct i2c_adapter i2c_adap;
- struct i2c_algo_bit_data i2c_algo;
- struct i2c_client i2c_client;
- u32 i2c_state, i2c_rc;
-
- /* config info -- analog */
- struct v4l2_device v4l2_dev;
- struct v4l2_ctrl_handler video_hdl;
- struct v4l2_ctrl *chroma_agc;
- struct v4l2_ctrl_handler audio_hdl;
- struct v4l2_subdev *sd_wm8775;
- struct i2c_client *i2c_rtc;
- unsigned int boardnr;
- struct cx88_board board;
-
- /* Supported V4L _STD_ tuner formats */
- unsigned int tuner_formats;
-
- /* config info -- dvb */
-#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
- int (*prev_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
-#endif
- void (*gate_ctrl)(struct cx88_core *core, int open);
-
- /* state info */
- struct task_struct *kthread;
- v4l2_std_id tvnorm;
- enum cx88_tvaudio tvaudio;
- u32 audiomode_manual;
- u32 audiomode_current;
- u32 input;
- u32 last_analog_input;
- u32 astat;
- u32 use_nicam;
- unsigned long last_change;
-
- /* IR remote control state */
- struct cx88_IR *ir;
-
- /* I2C remote data */
- struct IR_i2c_init_data init_data;
- struct wm8775_platform_data wm8775_data;
-
- struct mutex lock;
- /* various v4l controls */
- u32 freq;
- int users;
- int mpeg_users;
-
- /* cx88-video needs to access cx8802 for hybrid tuner pll access. */
- struct cx8802_dev *dvbdev;
- enum cx88_board_type active_type_id;
- int active_ref;
- int active_fe_id;
-};
-
-static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct cx88_core, v4l2_dev);
-}
-
-#define call_hw(core, grpid, o, f, args...) \
- do { \
- if (!core->i2c_rc) { \
- if (core->gate_ctrl) \
- core->gate_ctrl(core, 1); \
- v4l2_device_call_all(&core->v4l2_dev, grpid, o, f, ##args); \
- if (core->gate_ctrl) \
- core->gate_ctrl(core, 0); \
- } \
- } while (0)
-
-#define call_all(core, o, f, args...) call_hw(core, 0, o, f, ##args)
-
-#define WM8775_GID (1 << 0)
-
-#define wm8775_s_ctrl(core, id, val) \
- do { \
- struct v4l2_ctrl *ctrl_ = \
- v4l2_ctrl_find(core->sd_wm8775->ctrl_handler, id); \
- if (ctrl_ && !core->i2c_rc) { \
- if (core->gate_ctrl) \
- core->gate_ctrl(core, 1); \
- v4l2_ctrl_s_ctrl(ctrl_, val); \
- if (core->gate_ctrl) \
- core->gate_ctrl(core, 0); \
- } \
- } while (0)
-
-#define wm8775_g_ctrl(core, id) \
- ({ \
- struct v4l2_ctrl *ctrl_ = \
- v4l2_ctrl_find(core->sd_wm8775->ctrl_handler, id); \
- s32 val = 0; \
- if (ctrl_ && !core->i2c_rc) { \
- if (core->gate_ctrl) \
- core->gate_ctrl(core, 1); \
- val = v4l2_ctrl_g_ctrl(ctrl_); \
- if (core->gate_ctrl) \
- core->gate_ctrl(core, 0); \
- } \
- val; \
- })
-
-struct cx8800_dev;
-struct cx8802_dev;
-
-/* ----------------------------------------------------------- */
-/* function 0: video stuff */
-
-struct cx8800_fh {
- struct v4l2_fh fh;
- struct cx8800_dev *dev;
- unsigned int resources;
-
- /* video capture */
- struct videobuf_queue vidq;
-
- /* vbi capture */
- struct videobuf_queue vbiq;
-};
-
-struct cx8800_suspend_state {
- int disabled;
-};
-
-struct cx8800_dev {
- struct cx88_core *core;
- spinlock_t slock;
-
- /* various device info */
- unsigned int resources;
- struct video_device *video_dev;
- struct video_device *vbi_dev;
- struct video_device *radio_dev;
-
- /* pci i/o */
- struct pci_dev *pci;
- unsigned char pci_rev,pci_lat;
-
- const struct cx8800_fmt *fmt;
- unsigned int width, height;
-
- /* capture queues */
- struct cx88_dmaqueue vidq;
- struct cx88_dmaqueue vbiq;
-
- /* various v4l controls */
-
- /* other global state info */
- struct cx8800_suspend_state state;
-};
-
-/* ----------------------------------------------------------- */
-/* function 1: audio/alsa stuff */
-/* =============> moved to cx88-alsa.c <====================== */
-
-
-/* ----------------------------------------------------------- */
-/* function 2: mpeg stuff */
-
-struct cx8802_fh {
- struct v4l2_fh fh;
- struct cx8802_dev *dev;
- struct videobuf_queue mpegq;
-};
-
-struct cx8802_suspend_state {
- int disabled;
-};
-
-struct cx8802_driver {
- struct cx88_core *core;
-
- /* List of drivers attached to device */
- struct list_head drvlist;
-
- /* Type of driver and access required */
- enum cx88_board_type type_id;
- enum cx8802_board_access hw_access;
-
- /* MPEG 8802 internal only */
- int (*suspend)(struct pci_dev *pci_dev, pm_message_t state);
- int (*resume)(struct pci_dev *pci_dev);
-
- /* Callers to the following functions must hold core->lock */
-
- /* MPEG 8802 -> mini driver - Driver probe and configuration */
- int (*probe)(struct cx8802_driver *drv);
- int (*remove)(struct cx8802_driver *drv);
-
- /* MPEG 8802 -> mini driver - Access for hardware control */
- int (*advise_acquire)(struct cx8802_driver *drv);
- int (*advise_release)(struct cx8802_driver *drv);
-
- /* MPEG 8802 <- mini driver - Access for hardware control */
- int (*request_acquire)(struct cx8802_driver *drv);
- int (*request_release)(struct cx8802_driver *drv);
-};
-
-struct cx8802_dev {
- struct cx88_core *core;
- spinlock_t slock;
-
- /* pci i/o */
- struct pci_dev *pci;
- unsigned char pci_rev,pci_lat;
-
- /* dma queues */
- struct cx88_dmaqueue mpegq;
- u32 ts_packet_size;
- u32 ts_packet_count;
-
- /* other global state info */
- struct cx8802_suspend_state state;
-
- /* for blackbird only */
- struct list_head devlist;
-#if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \
- defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE)
- struct video_device *mpeg_dev;
- u32 mailbox;
- int width;
- int height;
- unsigned char mpeg_active; /* nonzero if mpeg encoder is active */
-
- /* mpeg params */
- struct cx2341x_handler cxhdl;
-#endif
-
-#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
- /* for dvb only */
- struct videobuf_dvb_frontends frontends;
-#endif
-
-#if defined(CONFIG_VIDEO_CX88_VP3054) || \
- defined(CONFIG_VIDEO_CX88_VP3054_MODULE)
- /* For VP3045 secondary I2C bus support */
- struct vp3054_i2c_state *vp3054;
-#endif
- /* for switching modulation types */
- unsigned char ts_gen_cntrl;
-
- /* List of attached drivers; must hold core->lock to access */
- struct list_head drvlist;
-
- struct work_struct request_module_wk;
-};
-
-/* ----------------------------------------------------------- */
-
-#define cx_read(reg) readl(core->lmmio + ((reg)>>2))
-#define cx_write(reg,value) writel((value), core->lmmio + ((reg)>>2))
-#define cx_writeb(reg,value) writeb((value), core->bmmio + (reg))
-
-#define cx_andor(reg,mask,value) \
- writel((readl(core->lmmio+((reg)>>2)) & ~(mask)) |\
- ((value) & (mask)), core->lmmio+((reg)>>2))
-#define cx_set(reg,bit) cx_andor((reg),(bit),(bit))
-#define cx_clear(reg,bit) cx_andor((reg),(bit),0)
-
-#define cx_wait(d) { if (need_resched()) schedule(); else udelay(d); }
-
-/* shadow registers */
-#define cx_sread(sreg) (core->shadow[sreg])
-#define cx_swrite(sreg,reg,value) \
- (core->shadow[sreg] = value, \
- writel(core->shadow[sreg], core->lmmio + ((reg)>>2)))
-#define cx_sandor(sreg,reg,mask,value) \
- (core->shadow[sreg] = (core->shadow[sreg] & ~(mask)) | ((value) & (mask)), \
- writel(core->shadow[sreg], core->lmmio + ((reg)>>2)))
-
-/* ----------------------------------------------------------- */
-/* cx88-core.c */
-
-extern void cx88_print_irqbits(const char *name, const char *tag, const char *strings[],
- int len, u32 bits, u32 mask);
-
-extern int cx88_core_irq(struct cx88_core *core, u32 status);
-extern void cx88_wakeup(struct cx88_core *core,
- struct cx88_dmaqueue *q, u32 count);
-extern void cx88_shutdown(struct cx88_core *core);
-extern int cx88_reset(struct cx88_core *core);
-
-extern int
-cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
- struct scatterlist *sglist,
- unsigned int top_offset, unsigned int bottom_offset,
- unsigned int bpl, unsigned int padding, unsigned int lines);
-extern int
-cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
- struct scatterlist *sglist, unsigned int bpl,
- unsigned int lines, unsigned int lpi);
-extern int
-cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
- u32 reg, u32 mask, u32 value);
-extern void
-cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf);
-
-extern void cx88_risc_disasm(struct cx88_core *core,
- struct btcx_riscmem *risc);
-extern int cx88_sram_channel_setup(struct cx88_core *core,
- const struct sram_channel *ch,
- unsigned int bpl, u32 risc);
-extern void cx88_sram_channel_dump(struct cx88_core *core,
- const struct sram_channel *ch);
-
-extern int cx88_set_scale(struct cx88_core *core, unsigned int width,
- unsigned int height, enum v4l2_field field);
-extern int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm);
-
-extern struct video_device *cx88_vdev_init(struct cx88_core *core,
- struct pci_dev *pci,
- const struct video_device *template_,
- const char *type);
-extern struct cx88_core* cx88_core_get(struct pci_dev *pci);
-extern void cx88_core_put(struct cx88_core *core,
- struct pci_dev *pci);
-
-extern int cx88_start_audio_dma(struct cx88_core *core);
-extern int cx88_stop_audio_dma(struct cx88_core *core);
-
-
-/* ----------------------------------------------------------- */
-/* cx88-vbi.c */
-
-/* Can be used as g_vbi_fmt, try_vbi_fmt and s_vbi_fmt */
-int cx8800_vbi_fmt (struct file *file, void *priv,
- struct v4l2_format *f);
-
-/*
-int cx8800_start_vbi_dma(struct cx8800_dev *dev,
- struct cx88_dmaqueue *q,
- struct cx88_buffer *buf);
-*/
-int cx8800_stop_vbi_dma(struct cx8800_dev *dev);
-int cx8800_restart_vbi_queue(struct cx8800_dev *dev,
- struct cx88_dmaqueue *q);
-void cx8800_vbi_timeout(unsigned long data);
-
-extern const struct videobuf_queue_ops cx8800_vbi_qops;
-
-/* ----------------------------------------------------------- */
-/* cx88-i2c.c */
-
-extern int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci);
-
-
-/* ----------------------------------------------------------- */
-/* cx88-cards.c */
-
-extern int cx88_tuner_callback(void *dev, int component, int command, int arg);
-extern int cx88_get_resources(const struct cx88_core *core,
- struct pci_dev *pci);
-extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr);
-extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl);
-
-/* ----------------------------------------------------------- */
-/* cx88-tvaudio.c */
-
-void cx88_set_tvaudio(struct cx88_core *core);
-void cx88_newstation(struct cx88_core *core);
-void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t);
-void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual);
-int cx88_audio_thread(void *data);
-
-int cx8802_register_driver(struct cx8802_driver *drv);
-int cx8802_unregister_driver(struct cx8802_driver *drv);
-
-/* Caller must hold core->lock */
-struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype);
-
-/* ----------------------------------------------------------- */
-/* cx88-dsp.c */
-
-s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core);
-
-/* ----------------------------------------------------------- */
-/* cx88-input.c */
-
-int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci);
-int cx88_ir_fini(struct cx88_core *core);
-void cx88_ir_irq(struct cx88_core *core);
-int cx88_ir_start(struct cx88_core *core);
-void cx88_ir_stop(struct cx88_core *core);
-extern void cx88_i2c_init_ir(struct cx88_core *core);
-
-/* ----------------------------------------------------------- */
-/* cx88-mpeg.c */
-
-int cx8802_buf_prepare(struct videobuf_queue *q,struct cx8802_dev *dev,
- struct cx88_buffer *buf, enum v4l2_field field);
-void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf);
-void cx8802_cancel_buffers(struct cx8802_dev *dev);
-
-/* ----------------------------------------------------------- */
-/* cx88-video.c*/
-int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i);
-int cx88_set_freq (struct cx88_core *core,struct v4l2_frequency *f);
-int cx88_video_mux(struct cx88_core *core, unsigned int input);
-void cx88_querycap(struct file *file, struct cx88_core *core,
- struct v4l2_capability *cap);
diff --git a/drivers/media/video/davinci/Kconfig b/drivers/media/video/davinci/Kconfig
deleted file mode 100644
index 52c5ca68cb3..00000000000
--- a/drivers/media/video/davinci/Kconfig
+++ /dev/null
@@ -1,121 +0,0 @@
-config VIDEO_DAVINCI_VPIF_DISPLAY
- tristate "DM646x/DA850/OMAPL138 EVM Video Display"
- depends on VIDEO_DEV && (MACH_DAVINCI_DM6467_EVM || MACH_DAVINCI_DA850_EVM)
- select VIDEOBUF2_DMA_CONTIG
- select VIDEO_DAVINCI_VPIF
- select VIDEO_ADV7343 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_THS7303 if VIDEO_HELPER_CHIPS_AUTO
- help
- Enables Davinci VPIF module used for display devices.
- This module is common for following DM6467/DA850/OMAPL138
- based display devices.
-
- To compile this driver as a module, choose M here: the
- module will be called vpif_display.
-
-config VIDEO_DAVINCI_VPIF_CAPTURE
- tristate "DM646x/DA850/OMAPL138 EVM Video Capture"
- depends on VIDEO_DEV && (MACH_DAVINCI_DM6467_EVM || MACH_DAVINCI_DA850_EVM)
- select VIDEOBUF2_DMA_CONTIG
- select VIDEO_DAVINCI_VPIF
- help
- Enables Davinci VPIF module used for captur devices.
- This module is common for following DM6467/DA850/OMAPL138
- based capture devices.
-
- To compile this driver as a module, choose M here: the
- module will be called vpif_capture.
-
-config VIDEO_DAVINCI_VPIF
- tristate "DaVinci VPIF Driver"
- depends on VIDEO_DAVINCI_VPIF_DISPLAY || VIDEO_DAVINCI_VPIF_CAPTURE
- help
- Support for DaVinci VPIF Driver.
-
- To compile this driver as a module, choose M here: the
- module will be called vpif.
-
-config VIDEO_VPSS_SYSTEM
- tristate "VPSS System module driver"
- depends on ARCH_DAVINCI
- help
- Support for vpss system module for video driver
-
-config VIDEO_VPFE_CAPTURE
- tristate "VPFE Video Capture Driver"
- depends on VIDEO_V4L2 && (ARCH_DAVINCI || ARCH_OMAP3)
- depends on I2C
- select VIDEOBUF_DMA_CONTIG
- help
- Support for DMx/AMx VPFE based frame grabber. This is the
- common V4L2 module for following DMx/AMx SoCs from Texas
- Instruments:- DM6446, DM365, DM355 & AM3517/05.
-
- To compile this driver as a module, choose M here: the
- module will be called vpfe-capture.
-
-config VIDEO_DM6446_CCDC
- tristate "DM6446 CCDC HW module"
- depends on VIDEO_VPFE_CAPTURE
- select VIDEO_VPSS_SYSTEM
- default y
- help
- Enables DaVinci CCD hw module. DaVinci CCDC hw interfaces
- with decoder modules such as TVP5146 over BT656 or
- sensor module such as MT9T001 over a raw interface. This
- module configures the interface and CCDC/ISIF to do
- video frame capture from slave decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called vpfe.
-
-config VIDEO_DM355_CCDC
- tristate "DM355 CCDC HW module"
- depends on ARCH_DAVINCI_DM355 && VIDEO_VPFE_CAPTURE
- select VIDEO_VPSS_SYSTEM
- default y
- help
- Enables DM355 CCD hw module. DM355 CCDC hw interfaces
- with decoder modules such as TVP5146 over BT656 or
- sensor module such as MT9T001 over a raw interface. This
- module configures the interface and CCDC/ISIF to do
- video frame capture from a slave decoders
-
- To compile this driver as a module, choose M here: the
- module will be called vpfe.
-
-config VIDEO_ISIF
- tristate "ISIF HW module"
- depends on ARCH_DAVINCI_DM365 && VIDEO_VPFE_CAPTURE
- select VIDEO_VPSS_SYSTEM
- default y
- help
- Enables ISIF hw module. This is the hardware module for
- configuring ISIF in VPFE to capture Raw Bayer RGB data from
- a image sensor or YUV data from a YUV source.
-
- To compile this driver as a module, choose M here: the
- module will be called vpfe.
-
-config VIDEO_DM644X_VPBE
- tristate "DM644X VPBE HW module"
- depends on ARCH_DAVINCI_DM644x
- select VIDEO_VPSS_SYSTEM
- select VIDEOBUF_DMA_CONTIG
- help
- Enables VPBE modules used for display on a DM644x
- SoC.
-
- To compile this driver as a module, choose M here: the
- module will be called vpbe.
-
-
-config VIDEO_VPBE_DISPLAY
- tristate "VPBE V4L2 Display driver"
- depends on ARCH_DAVINCI_DM644x
- select VIDEO_DM644X_VPBE
- help
- Enables VPBE V4L2 Display driver on a DM644x device
-
- To compile this driver as a module, choose M here: the
- module will be called vpbe_display.
diff --git a/drivers/media/video/davinci/Makefile b/drivers/media/video/davinci/Makefile
deleted file mode 100644
index 74ed92d0925..00000000000
--- a/drivers/media/video/davinci/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Makefile for the davinci video device drivers.
-#
-
-# VPIF
-obj-$(CONFIG_VIDEO_DAVINCI_VPIF) += vpif.o
-
-#VPIF Display driver
-obj-$(CONFIG_VIDEO_DAVINCI_VPIF_DISPLAY) += vpif_display.o
-#VPIF Capture driver
-obj-$(CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE) += vpif_capture.o
-
-# Capture: DM6446 and DM355
-obj-$(CONFIG_VIDEO_VPSS_SYSTEM) += vpss.o
-obj-$(CONFIG_VIDEO_VPFE_CAPTURE) += vpfe_capture.o
-obj-$(CONFIG_VIDEO_DM6446_CCDC) += dm644x_ccdc.o
-obj-$(CONFIG_VIDEO_DM355_CCDC) += dm355_ccdc.o
-obj-$(CONFIG_VIDEO_ISIF) += isif.o
-obj-$(CONFIG_VIDEO_DM644X_VPBE) += vpbe.o vpbe_osd.o vpbe_venc.o
-obj-$(CONFIG_VIDEO_VPBE_DISPLAY) += vpbe_display.o
diff --git a/drivers/media/video/davinci/ccdc_hw_device.h b/drivers/media/video/davinci/ccdc_hw_device.h
deleted file mode 100644
index 86b9b351896..00000000000
--- a/drivers/media/video/davinci/ccdc_hw_device.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * ccdc device API
- */
-#ifndef _CCDC_HW_DEVICE_H
-#define _CCDC_HW_DEVICE_H
-
-#ifdef __KERNEL__
-#include <linux/videodev2.h>
-#include <linux/device.h>
-#include <media/davinci/vpfe_types.h>
-#include <media/davinci/ccdc_types.h>
-
-/*
- * ccdc hw operations
- */
-struct ccdc_hw_ops {
- /* Pointer to initialize function to initialize ccdc device */
- int (*open) (struct device *dev);
- /* Pointer to deinitialize function */
- int (*close) (struct device *dev);
- /* set ccdc base address */
- void (*set_ccdc_base)(void *base, int size);
- /* Pointer to function to enable or disable ccdc */
- void (*enable) (int en);
- /* reset sbl. only for 6446 */
- void (*reset) (void);
- /* enable output to sdram */
- void (*enable_out_to_sdram) (int en);
- /* Pointer to function to set hw parameters */
- int (*set_hw_if_params) (struct vpfe_hw_if_param *param);
- /* get interface parameters */
- int (*get_hw_if_params) (struct vpfe_hw_if_param *param);
- /*
- * Pointer to function to set parameters. Used
- * for implementing VPFE_S_CCDC_PARAMS
- */
- int (*set_params) (void *params);
- /*
- * Pointer to function to get parameter. Used
- * for implementing VPFE_G_CCDC_PARAMS
- */
- int (*get_params) (void *params);
- /* Pointer to function to configure ccdc */
- int (*configure) (void);
-
- /* Pointer to function to set buffer type */
- int (*set_buftype) (enum ccdc_buftype buf_type);
- /* Pointer to function to get buffer type */
- enum ccdc_buftype (*get_buftype) (void);
- /* Pointer to function to set frame format */
- int (*set_frame_format) (enum ccdc_frmfmt frm_fmt);
- /* Pointer to function to get frame format */
- enum ccdc_frmfmt (*get_frame_format) (void);
- /* enumerate hw pix formats */
- int (*enum_pix)(u32 *hw_pix, int i);
- /* Pointer to function to set buffer type */
- u32 (*get_pixel_format) (void);
- /* Pointer to function to get pixel format. */
- int (*set_pixel_format) (u32 pixfmt);
- /* Pointer to function to set image window */
- int (*set_image_window) (struct v4l2_rect *win);
- /* Pointer to function to set image window */
- void (*get_image_window) (struct v4l2_rect *win);
- /* Pointer to function to get line length */
- unsigned int (*get_line_length) (void);
-
- /* Query CCDC control IDs */
- int (*queryctrl)(struct v4l2_queryctrl *qctrl);
- /* Set CCDC control */
- int (*set_control)(struct v4l2_control *ctrl);
- /* Get CCDC control */
- int (*get_control)(struct v4l2_control *ctrl);
-
- /* Pointer to function to set frame buffer address */
- void (*setfbaddr) (unsigned long addr);
- /* Pointer to function to get field id */
- int (*getfid) (void);
-};
-
-struct ccdc_hw_device {
- /* ccdc device name */
- char name[32];
- /* module owner */
- struct module *owner;
- /* hw ops */
- struct ccdc_hw_ops hw_ops;
-};
-
-/* Used by CCDC module to register & unregister with vpfe capture driver */
-int vpfe_register_ccdc_device(struct ccdc_hw_device *dev);
-void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev);
-
-#endif
-#endif
diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/video/davinci/dm355_ccdc.c
deleted file mode 100644
index 5b68847d401..00000000000
--- a/drivers/media/video/davinci/dm355_ccdc.c
+++ /dev/null
@@ -1,1072 +0,0 @@
-/*
- * Copyright (C) 2005-2009 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * CCDC hardware module for DM355
- * ------------------------------
- *
- * This module is for configuring DM355 CCD controller of VPFE to capture
- * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
- * such as Defect Pixel Correction, Color Space Conversion etc to
- * pre-process the Bayer RGB data, before writing it to SDRAM. This
- * module also allows application to configure individual
- * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL.
- * To do so, application include dm355_ccdc.h and vpfe_capture.h header
- * files. The setparams() API is called by vpfe_capture driver
- * to configure module parameters
- *
- * TODO: 1) Raw bayer parameter settings and bayer capture
- * 2) Split module parameter structure to module specific ioctl structs
- * 3) add support for lense shading correction
- * 4) investigate if enum used for user space type definition
- * to be replaced by #defines or integer
- */
-#include <linux/platform_device.h>
-#include <linux/uaccess.h>
-#include <linux/videodev2.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/module.h>
-
-#include <media/davinci/dm355_ccdc.h>
-#include <media/davinci/vpss.h>
-
-#include "dm355_ccdc_regs.h"
-#include "ccdc_hw_device.h"
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("CCDC Driver for DM355");
-MODULE_AUTHOR("Texas Instruments");
-
-static struct ccdc_oper_config {
- struct device *dev;
- /* CCDC interface type */
- enum vpfe_hw_if_type if_type;
- /* Raw Bayer configuration */
- struct ccdc_params_raw bayer;
- /* YCbCr configuration */
- struct ccdc_params_ycbcr ycbcr;
- /* Master clock */
- struct clk *mclk;
- /* slave clock */
- struct clk *sclk;
- /* ccdc base address */
- void __iomem *base_addr;
-} ccdc_cfg = {
- /* Raw configurations */
- .bayer = {
- .pix_fmt = CCDC_PIXFMT_RAW,
- .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
- .win = CCDC_WIN_VGA,
- .fid_pol = VPFE_PINPOL_POSITIVE,
- .vd_pol = VPFE_PINPOL_POSITIVE,
- .hd_pol = VPFE_PINPOL_POSITIVE,
- .gain = {
- .r_ye = 256,
- .gb_g = 256,
- .gr_cy = 256,
- .b_mg = 256
- },
- .config_params = {
- .datasft = 2,
- .mfilt1 = CCDC_NO_MEDIAN_FILTER1,
- .mfilt2 = CCDC_NO_MEDIAN_FILTER2,
- .alaw = {
- .gama_wd = 2,
- },
- .blk_clamp = {
- .sample_pixel = 1,
- .dc_sub = 25
- },
- .col_pat_field0 = {
- .olop = CCDC_GREEN_BLUE,
- .olep = CCDC_BLUE,
- .elop = CCDC_RED,
- .elep = CCDC_GREEN_RED
- },
- .col_pat_field1 = {
- .olop = CCDC_GREEN_BLUE,
- .olep = CCDC_BLUE,
- .elop = CCDC_RED,
- .elep = CCDC_GREEN_RED
- },
- },
- },
- /* YCbCr configuration */
- .ycbcr = {
- .win = CCDC_WIN_PAL,
- .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
- .frm_fmt = CCDC_FRMFMT_INTERLACED,
- .fid_pol = VPFE_PINPOL_POSITIVE,
- .vd_pol = VPFE_PINPOL_POSITIVE,
- .hd_pol = VPFE_PINPOL_POSITIVE,
- .bt656_enable = 1,
- .pix_order = CCDC_PIXORDER_CBYCRY,
- .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
- },
-};
-
-
-/* Raw Bayer formats */
-static u32 ccdc_raw_bayer_pix_formats[] =
- {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
-
-/* Raw YUV formats */
-static u32 ccdc_raw_yuv_pix_formats[] =
- {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
-
-/* register access routines */
-static inline u32 regr(u32 offset)
-{
- return __raw_readl(ccdc_cfg.base_addr + offset);
-}
-
-static inline void regw(u32 val, u32 offset)
-{
- __raw_writel(val, ccdc_cfg.base_addr + offset);
-}
-
-static void ccdc_enable(int en)
-{
- unsigned int temp;
- temp = regr(SYNCEN);
- temp &= (~CCDC_SYNCEN_VDHDEN_MASK);
- temp |= (en & CCDC_SYNCEN_VDHDEN_MASK);
- regw(temp, SYNCEN);
-}
-
-static void ccdc_enable_output_to_sdram(int en)
-{
- unsigned int temp;
- temp = regr(SYNCEN);
- temp &= (~(CCDC_SYNCEN_WEN_MASK));
- temp |= ((en << CCDC_SYNCEN_WEN_SHIFT) & CCDC_SYNCEN_WEN_MASK);
- regw(temp, SYNCEN);
-}
-
-static void ccdc_config_gain_offset(void)
-{
- /* configure gain */
- regw(ccdc_cfg.bayer.gain.r_ye, RYEGAIN);
- regw(ccdc_cfg.bayer.gain.gr_cy, GRCYGAIN);
- regw(ccdc_cfg.bayer.gain.gb_g, GBGGAIN);
- regw(ccdc_cfg.bayer.gain.b_mg, BMGGAIN);
- /* configure offset */
- regw(ccdc_cfg.bayer.ccdc_offset, OFFSET);
-}
-
-/*
- * ccdc_restore_defaults()
- * This function restore power on defaults in the ccdc registers
- */
-static int ccdc_restore_defaults(void)
-{
- int i;
-
- dev_dbg(ccdc_cfg.dev, "\nstarting ccdc_restore_defaults...");
- /* set all registers to zero */
- for (i = 0; i <= CCDC_REG_LAST; i += 4)
- regw(0, i);
-
- /* now override the values with power on defaults in registers */
- regw(MODESET_DEFAULT, MODESET);
- /* no culling support */
- regw(CULH_DEFAULT, CULH);
- regw(CULV_DEFAULT, CULV);
- /* Set default Gain and Offset */
- ccdc_cfg.bayer.gain.r_ye = GAIN_DEFAULT;
- ccdc_cfg.bayer.gain.gb_g = GAIN_DEFAULT;
- ccdc_cfg.bayer.gain.gr_cy = GAIN_DEFAULT;
- ccdc_cfg.bayer.gain.b_mg = GAIN_DEFAULT;
- ccdc_config_gain_offset();
- regw(OUTCLIP_DEFAULT, OUTCLIP);
- regw(LSCCFG2_DEFAULT, LSCCFG2);
- /* select ccdc input */
- if (vpss_select_ccdc_source(VPSS_CCDCIN)) {
- dev_dbg(ccdc_cfg.dev, "\ncouldn't select ccdc input source");
- return -EFAULT;
- }
- /* select ccdc clock */
- if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) {
- dev_dbg(ccdc_cfg.dev, "\ncouldn't enable ccdc clock");
- return -EFAULT;
- }
- dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_restore_defaults...");
- return 0;
-}
-
-static int ccdc_open(struct device *device)
-{
- return ccdc_restore_defaults();
-}
-
-static int ccdc_close(struct device *device)
-{
- /* disable clock */
- vpss_enable_clock(VPSS_CCDC_CLOCK, 0);
- /* do nothing for now */
- return 0;
-}
-/*
- * ccdc_setwin()
- * This function will configure the window size to
- * be capture in CCDC reg.
- */
-static void ccdc_setwin(struct v4l2_rect *image_win,
- enum ccdc_frmfmt frm_fmt, int ppc)
-{
- int horz_start, horz_nr_pixels;
- int vert_start, vert_nr_lines;
- int mid_img = 0;
-
- dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
-
- /*
- * ppc - per pixel count. indicates how many pixels per cell
- * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
- * raw capture this is 1
- */
- horz_start = image_win->left << (ppc - 1);
- horz_nr_pixels = ((image_win->width) << (ppc - 1)) - 1;
-
- /* Writing the horizontal info into the registers */
- regw(horz_start, SPH);
- regw(horz_nr_pixels, NPH);
- vert_start = image_win->top;
-
- if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
- vert_nr_lines = (image_win->height >> 1) - 1;
- vert_start >>= 1;
- /* Since first line doesn't have any data */
- vert_start += 1;
- /* configure VDINT0 and VDINT1 */
- regw(vert_start, VDINT0);
- } else {
- /* Since first line doesn't have any data */
- vert_start += 1;
- vert_nr_lines = image_win->height - 1;
- /* configure VDINT0 and VDINT1 */
- mid_img = vert_start + (image_win->height / 2);
- regw(vert_start, VDINT0);
- regw(mid_img, VDINT1);
- }
- regw(vert_start & CCDC_START_VER_ONE_MASK, SLV0);
- regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1);
- regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV);
- dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
-}
-
-static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
-{
- if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT ||
- ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) {
- dev_dbg(ccdc_cfg.dev, "Invalid value of data shift\n");
- return -EINVAL;
- }
-
- if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 ||
- ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) {
- dev_dbg(ccdc_cfg.dev, "Invalid value of median filter1\n");
- return -EINVAL;
- }
-
- if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 ||
- ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) {
- dev_dbg(ccdc_cfg.dev, "Invalid value of median filter2\n");
- return -EINVAL;
- }
-
- if ((ccdcparam->med_filt_thres < 0) ||
- (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) {
- dev_dbg(ccdc_cfg.dev,
- "Invalid value of median filter threshold\n");
- return -EINVAL;
- }
-
- if (ccdcparam->data_sz < CCDC_DATA_16BITS ||
- ccdcparam->data_sz > CCDC_DATA_8BITS) {
- dev_dbg(ccdc_cfg.dev, "Invalid value of data size\n");
- return -EINVAL;
- }
-
- if (ccdcparam->alaw.enable) {
- if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 ||
- ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) {
- dev_dbg(ccdc_cfg.dev, "Invalid value of ALAW\n");
- return -EINVAL;
- }
- }
-
- if (ccdcparam->blk_clamp.b_clamp_enable) {
- if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS ||
- ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) {
- dev_dbg(ccdc_cfg.dev,
- "Invalid value of sample pixel\n");
- return -EINVAL;
- }
- if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES ||
- ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) {
- dev_dbg(ccdc_cfg.dev,
- "Invalid value of sample lines\n");
- return -EINVAL;
- }
- }
- return 0;
-}
-
-/* Parameter operations */
-static int ccdc_set_params(void __user *params)
-{
- struct ccdc_config_params_raw ccdc_raw_params;
- int x;
-
- /* only raw module parameters can be set through the IOCTL */
- if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
- return -EINVAL;
-
- x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
- if (x) {
- dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying ccdc"
- "params, %d\n", x);
- return -EFAULT;
- }
-
- if (!validate_ccdc_param(&ccdc_raw_params)) {
- memcpy(&ccdc_cfg.bayer.config_params,
- &ccdc_raw_params,
- sizeof(ccdc_raw_params));
- return 0;
- }
- return -EINVAL;
-}
-
-/* This function will configure CCDC for YCbCr video capture */
-static void ccdc_config_ycbcr(void)
-{
- struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
- u32 temp;
-
- /* first set the CCDC power on defaults values in all registers */
- dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
- ccdc_restore_defaults();
-
- /* configure pixel format & video frame format */
- temp = (((params->pix_fmt & CCDC_INPUT_MODE_MASK) <<
- CCDC_INPUT_MODE_SHIFT) |
- ((params->frm_fmt & CCDC_FRM_FMT_MASK) <<
- CCDC_FRM_FMT_SHIFT));
-
- /* setup BT.656 sync mode */
- if (params->bt656_enable) {
- regw(CCDC_REC656IF_BT656_EN, REC656IF);
- /*
- * configure the FID, VD, HD pin polarity fld,hd pol positive,
- * vd negative, 8-bit pack mode
- */
- temp |= CCDC_VD_POL_NEGATIVE;
- } else { /* y/c external sync mode */
- temp |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
- CCDC_FID_POL_SHIFT) |
- ((params->hd_pol & CCDC_HD_POL_MASK) <<
- CCDC_HD_POL_SHIFT) |
- ((params->vd_pol & CCDC_VD_POL_MASK) <<
- CCDC_VD_POL_SHIFT));
- }
-
- /* pack the data to 8-bit */
- temp |= CCDC_DATA_PACK_ENABLE;
-
- regw(temp, MODESET);
-
- /* configure video window */
- ccdc_setwin(&params->win, params->frm_fmt, 2);
-
- /* configure the order of y cb cr in SD-RAM */
- temp = (params->pix_order << CCDC_Y8POS_SHIFT);
- temp |= CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC;
- regw(temp, CCDCFG);
-
- /*
- * configure the horizontal line offset. This is done by rounding up
- * width to a multiple of 16 pixels and multiply by two to account for
- * y:cb:cr 4:2:2 data
- */
- regw(((params->win.width * 2 + 31) >> 5), HSIZE);
-
- /* configure the memory line offset */
- if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) {
- /* two fields are interleaved in memory */
- regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST);
- }
-
- dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
-}
-
-/*
- * ccdc_config_black_clamp()
- * configure parameters for Optical Black Clamp
- */
-static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
-{
- u32 val;
-
- if (!bclamp->b_clamp_enable) {
- /* configure DCSub */
- regw(bclamp->dc_sub & CCDC_BLK_DC_SUB_MASK, DCSUB);
- regw(0x0000, CLAMP);
- return;
- }
- /* Enable the Black clamping, set sample lines and pixels */
- val = (bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) |
- ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
- CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE;
- regw(val, CLAMP);
-
- /* If Black clamping is enable then make dcsub 0 */
- val = (bclamp->sample_ln & CCDC_NUM_LINE_CALC_MASK)
- << CCDC_NUM_LINE_CALC_SHIFT;
- regw(val, DCSUB);
-}
-
-/*
- * ccdc_config_black_compense()
- * configure parameters for Black Compensation
- */
-static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
-{
- u32 val;
-
- val = (bcomp->b & CCDC_BLK_COMP_MASK) |
- ((bcomp->gb & CCDC_BLK_COMP_MASK) <<
- CCDC_BLK_COMP_GB_COMP_SHIFT);
- regw(val, BLKCMP1);
-
- val = ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
- CCDC_BLK_COMP_GR_COMP_SHIFT) |
- ((bcomp->r & CCDC_BLK_COMP_MASK) <<
- CCDC_BLK_COMP_R_COMP_SHIFT);
- regw(val, BLKCMP0);
-}
-
-/*
- * ccdc_write_dfc_entry()
- * write an entry in the dfc table.
- */
-int ccdc_write_dfc_entry(int index, struct ccdc_vertical_dft *dfc)
-{
-/* TODO This is to be re-visited and adjusted */
-#define DFC_WRITE_WAIT_COUNT 1000
- u32 val, count = DFC_WRITE_WAIT_COUNT;
-
- regw(dfc->dft_corr_vert[index], DFCMEM0);
- regw(dfc->dft_corr_horz[index], DFCMEM1);
- regw(dfc->dft_corr_sub1[index], DFCMEM2);
- regw(dfc->dft_corr_sub2[index], DFCMEM3);
- regw(dfc->dft_corr_sub3[index], DFCMEM4);
- /* set WR bit to write */
- val = regr(DFCMEMCTL) | CCDC_DFCMEMCTL_DFCMWR_MASK;
- regw(val, DFCMEMCTL);
-
- /*
- * Assume, it is very short. If we get an error, we need to
- * adjust this value
- */
- while (regr(DFCMEMCTL) & CCDC_DFCMEMCTL_DFCMWR_MASK)
- count--;
- /*
- * TODO We expect the count to be non-zero to be successful. Adjust
- * the count if write requires more time
- */
-
- if (count) {
- dev_err(ccdc_cfg.dev, "defect table write timeout !!!\n");
- return -1;
- }
- return 0;
-}
-
-/*
- * ccdc_config_vdfc()
- * configure parameters for Vertical Defect Correction
- */
-static int ccdc_config_vdfc(struct ccdc_vertical_dft *dfc)
-{
- u32 val;
- int i;
-
- /* Configure General Defect Correction. The table used is from IPIPE */
- val = dfc->gen_dft_en & CCDC_DFCCTL_GDFCEN_MASK;
-
- /* Configure Vertical Defect Correction if needed */
- if (!dfc->ver_dft_en) {
- /* Enable only General Defect Correction */
- regw(val, DFCCTL);
- return 0;
- }
-
- if (dfc->table_size > CCDC_DFT_TABLE_SIZE)
- return -EINVAL;
-
- val |= CCDC_DFCCTL_VDFC_DISABLE;
- val |= (dfc->dft_corr_ctl.vdfcsl & CCDC_DFCCTL_VDFCSL_MASK) <<
- CCDC_DFCCTL_VDFCSL_SHIFT;
- val |= (dfc->dft_corr_ctl.vdfcuda & CCDC_DFCCTL_VDFCUDA_MASK) <<
- CCDC_DFCCTL_VDFCUDA_SHIFT;
- val |= (dfc->dft_corr_ctl.vdflsft & CCDC_DFCCTL_VDFLSFT_MASK) <<
- CCDC_DFCCTL_VDFLSFT_SHIFT;
- regw(val , DFCCTL);
-
- /* clear address ptr to offset 0 */
- val = CCDC_DFCMEMCTL_DFCMARST_MASK << CCDC_DFCMEMCTL_DFCMARST_SHIFT;
-
- /* write defect table entries */
- for (i = 0; i < dfc->table_size; i++) {
- /* increment address for non zero index */
- if (i != 0)
- val = CCDC_DFCMEMCTL_INC_ADDR;
- regw(val, DFCMEMCTL);
- if (ccdc_write_dfc_entry(i, dfc) < 0)
- return -EFAULT;
- }
-
- /* update saturation level and enable dfc */
- regw(dfc->saturation_ctl & CCDC_VDC_DFCVSAT_MASK, DFCVSAT);
- val = regr(DFCCTL) | (CCDC_DFCCTL_VDFCEN_MASK <<
- CCDC_DFCCTL_VDFCEN_SHIFT);
- regw(val, DFCCTL);
- return 0;
-}
-
-/*
- * ccdc_config_csc()
- * configure parameters for color space conversion
- * Each register CSCM0-7 has two values in S8Q5 format.
- */
-static void ccdc_config_csc(struct ccdc_csc *csc)
-{
- u32 val1, val2;
- int i;
-
- if (!csc->enable)
- return;
-
- /* Enable the CSC sub-module */
- regw(CCDC_CSC_ENABLE, CSCCTL);
-
- /* Converting the co-eff as per the format of the register */
- for (i = 0; i < CCDC_CSC_COEFF_TABLE_SIZE; i++) {
- if ((i % 2) == 0) {
- /* CSCM - LSB */
- val1 = (csc->coeff[i].integer &
- CCDC_CSC_COEF_INTEG_MASK)
- << CCDC_CSC_COEF_INTEG_SHIFT;
- /*
- * convert decimal part to binary. Use 2 decimal
- * precision, user values range from .00 - 0.99
- */
- val1 |= (((csc->coeff[i].decimal &
- CCDC_CSC_COEF_DECIMAL_MASK) *
- CCDC_CSC_DEC_MAX) / 100);
- } else {
-
- /* CSCM - MSB */
- val2 = (csc->coeff[i].integer &
- CCDC_CSC_COEF_INTEG_MASK)
- << CCDC_CSC_COEF_INTEG_SHIFT;
- val2 |= (((csc->coeff[i].decimal &
- CCDC_CSC_COEF_DECIMAL_MASK) *
- CCDC_CSC_DEC_MAX) / 100);
- val2 <<= CCDC_CSCM_MSB_SHIFT;
- val2 |= val1;
- regw(val2, (CSCM0 + ((i - 1) << 1)));
- }
- }
-}
-
-/*
- * ccdc_config_color_patterns()
- * configure parameters for color patterns
- */
-static void ccdc_config_color_patterns(struct ccdc_col_pat *pat0,
- struct ccdc_col_pat *pat1)
-{
- u32 val;
-
- val = (pat0->olop | (pat0->olep << 2) | (pat0->elop << 4) |
- (pat0->elep << 6) | (pat1->olop << 8) | (pat1->olep << 10) |
- (pat1->elop << 12) | (pat1->elep << 14));
- regw(val, COLPTN);
-}
-
-/* This function will configure CCDC for Raw mode image capture */
-static int ccdc_config_raw(void)
-{
- struct ccdc_params_raw *params = &ccdc_cfg.bayer;
- struct ccdc_config_params_raw *config_params =
- &ccdc_cfg.bayer.config_params;
- unsigned int val;
-
- dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
-
- /* restore power on defaults to register */
- ccdc_restore_defaults();
-
- /* CCDCFG register:
- * set CCD Not to swap input since input is RAW data
- * set FID detection function to Latch at V-Sync
- * set WENLOG - ccdc valid area to AND
- * set TRGSEL to WENBIT
- * set EXTRG to DISABLE
- * disable latching function on VSYNC - shadowed registers
- */
- regw(CCDC_YCINSWP_RAW | CCDC_CCDCFG_FIDMD_LATCH_VSYNC |
- CCDC_CCDCFG_WENLOG_AND | CCDC_CCDCFG_TRGSEL_WEN |
- CCDC_CCDCFG_EXTRG_DISABLE | CCDC_LATCH_ON_VSYNC_DISABLE, CCDCFG);
-
- /*
- * Set VDHD direction to input, input type to raw input
- * normal data polarity, do not use external WEN
- */
- val = (CCDC_VDHDOUT_INPUT | CCDC_RAW_IP_MODE | CCDC_DATAPOL_NORMAL |
- CCDC_EXWEN_DISABLE);
-
- /*
- * Configure the vertical sync polarity (MODESET.VDPOL), horizontal
- * sync polarity (MODESET.HDPOL), field id polarity (MODESET.FLDPOL),
- * frame format(progressive or interlace), & pixel format (Input mode)
- */
- val |= (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) |
- ((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) |
- ((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) |
- ((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
- ((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT));
-
- /* set pack for alaw compression */
- if ((config_params->data_sz == CCDC_DATA_8BITS) ||
- config_params->alaw.enable)
- val |= CCDC_DATA_PACK_ENABLE;
-
- /* Configure for LPF */
- if (config_params->lpf_enable)
- val |= (config_params->lpf_enable & CCDC_LPF_MASK) <<
- CCDC_LPF_SHIFT;
-
- /* Configure the data shift */
- val |= (config_params->datasft & CCDC_DATASFT_MASK) <<
- CCDC_DATASFT_SHIFT;
- regw(val , MODESET);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to MODESET...\n", val);
-
- /* Configure the Median Filter threshold */
- regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT);
-
- /* Configure GAMMAWD register. defaur 11-2, and Mosaic cfa pattern */
- val = CCDC_GAMMA_BITS_11_2 << CCDC_GAMMAWD_INPUT_SHIFT |
- CCDC_CFA_MOSAIC;
-
- /* Enable and configure aLaw register if needed */
- if (config_params->alaw.enable) {
- val |= (CCDC_ALAW_ENABLE |
- ((config_params->alaw.gama_wd &
- CCDC_ALAW_GAMA_WD_MASK) <<
- CCDC_GAMMAWD_INPUT_SHIFT));
- }
-
- /* Configure Median filter1 & filter2 */
- val |= ((config_params->mfilt1 << CCDC_MFILT1_SHIFT) |
- (config_params->mfilt2 << CCDC_MFILT2_SHIFT));
-
- regw(val, GAMMAWD);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to GAMMAWD...\n", val);
-
- /* configure video window */
- ccdc_setwin(&params->win, params->frm_fmt, 1);
-
- /* Optical Clamp Averaging */
- ccdc_config_black_clamp(&config_params->blk_clamp);
-
- /* Black level compensation */
- ccdc_config_black_compense(&config_params->blk_comp);
-
- /* Vertical Defect Correction if needed */
- if (ccdc_config_vdfc(&config_params->vertical_dft) < 0)
- return -EFAULT;
-
- /* color space conversion */
- ccdc_config_csc(&config_params->csc);
-
- /* color pattern */
- ccdc_config_color_patterns(&config_params->col_pat_field0,
- &config_params->col_pat_field1);
-
- /* Configure the Gain & offset control */
- ccdc_config_gain_offset();
-
- dev_dbg(ccdc_cfg.dev, "\nWriting %x to COLPTN...\n", val);
-
- /* Configure DATAOFST register */
- val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) <<
- CCDC_DATAOFST_H_SHIFT;
- val |= (config_params->data_offset.vert_offset & CCDC_DATAOFST_MASK) <<
- CCDC_DATAOFST_V_SHIFT;
- regw(val, DATAOFST);
-
- /* configuring HSIZE register */
- val = (params->horz_flip_enable & CCDC_HSIZE_FLIP_MASK) <<
- CCDC_HSIZE_FLIP_SHIFT;
-
- /* If pack 8 is enable then 1 pixel will take 1 byte */
- if ((config_params->data_sz == CCDC_DATA_8BITS) ||
- config_params->alaw.enable) {
- val |= (((params->win.width) + 31) >> 5) &
- CCDC_HSIZE_VAL_MASK;
-
- /* adjust to multiple of 32 */
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
- (((params->win.width) + 31) >> 5) &
- CCDC_HSIZE_VAL_MASK);
- } else {
- /* else one pixel will take 2 byte */
- val |= (((params->win.width * 2) + 31) >> 5) &
- CCDC_HSIZE_VAL_MASK;
-
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
- (((params->win.width * 2) + 31) >> 5) &
- CCDC_HSIZE_VAL_MASK);
- }
- regw(val, HSIZE);
-
- /* Configure SDOFST register */
- if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
- if (params->image_invert_enable) {
- /* For interlace inverse mode */
- regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST);
- dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
- CCDC_SDOFST_INTERLACE_INVERSE);
- } else {
- /* For interlace non inverse mode */
- regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST);
- dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
- CCDC_SDOFST_INTERLACE_NORMAL);
- }
- } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
- if (params->image_invert_enable) {
- /* For progessive inverse mode */
- regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST);
- dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
- CCDC_SDOFST_PROGRESSIVE_INVERSE);
- } else {
- /* For progessive non inverse mode */
- regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST);
- dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
- CCDC_SDOFST_PROGRESSIVE_NORMAL);
- }
- }
- dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
- return 0;
-}
-
-static int ccdc_configure(void)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- return ccdc_config_raw();
- else
- ccdc_config_ycbcr();
- return 0;
-}
-
-static int ccdc_set_buftype(enum ccdc_buftype buf_type)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- ccdc_cfg.bayer.buf_type = buf_type;
- else
- ccdc_cfg.ycbcr.buf_type = buf_type;
- return 0;
-}
-static enum ccdc_buftype ccdc_get_buftype(void)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- return ccdc_cfg.bayer.buf_type;
- return ccdc_cfg.ycbcr.buf_type;
-}
-
-static int ccdc_enum_pix(u32 *pix, int i)
-{
- int ret = -EINVAL;
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
- if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
- *pix = ccdc_raw_bayer_pix_formats[i];
- ret = 0;
- }
- } else {
- if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
- *pix = ccdc_raw_yuv_pix_formats[i];
- ret = 0;
- }
- }
- return ret;
-}
-
-static int ccdc_set_pixel_format(u32 pixfmt)
-{
- struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
-
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
- ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
- if (pixfmt == V4L2_PIX_FMT_SBGGR8)
- alaw->enable = 1;
- else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
- return -EINVAL;
- } else {
- if (pixfmt == V4L2_PIX_FMT_YUYV)
- ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
- else if (pixfmt == V4L2_PIX_FMT_UYVY)
- ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
- else
- return -EINVAL;
- }
- return 0;
-}
-static u32 ccdc_get_pixel_format(void)
-{
- struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
- u32 pixfmt;
-
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- if (alaw->enable)
- pixfmt = V4L2_PIX_FMT_SBGGR8;
- else
- pixfmt = V4L2_PIX_FMT_SBGGR16;
- else {
- if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
- pixfmt = V4L2_PIX_FMT_YUYV;
- else
- pixfmt = V4L2_PIX_FMT_UYVY;
- }
- return pixfmt;
-}
-static int ccdc_set_image_window(struct v4l2_rect *win)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- ccdc_cfg.bayer.win = *win;
- else
- ccdc_cfg.ycbcr.win = *win;
- return 0;
-}
-
-static void ccdc_get_image_window(struct v4l2_rect *win)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- *win = ccdc_cfg.bayer.win;
- else
- *win = ccdc_cfg.ycbcr.win;
-}
-
-static unsigned int ccdc_get_line_length(void)
-{
- struct ccdc_config_params_raw *config_params =
- &ccdc_cfg.bayer.config_params;
- unsigned int len;
-
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
- if ((config_params->alaw.enable) ||
- (config_params->data_sz == CCDC_DATA_8BITS))
- len = ccdc_cfg.bayer.win.width;
- else
- len = ccdc_cfg.bayer.win.width * 2;
- } else
- len = ccdc_cfg.ycbcr.win.width * 2;
- return ALIGN(len, 32);
-}
-
-static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- ccdc_cfg.bayer.frm_fmt = frm_fmt;
- else
- ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
- return 0;
-}
-
-static enum ccdc_frmfmt ccdc_get_frame_format(void)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- return ccdc_cfg.bayer.frm_fmt;
- else
- return ccdc_cfg.ycbcr.frm_fmt;
-}
-
-static int ccdc_getfid(void)
-{
- return (regr(MODESET) >> 15) & 1;
-}
-
-/* misc operations */
-static inline void ccdc_setfbaddr(unsigned long addr)
-{
- regw((addr >> 21) & 0x007f, STADRH);
- regw((addr >> 5) & 0x0ffff, STADRL);
-}
-
-static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
-{
- ccdc_cfg.if_type = params->if_type;
-
- switch (params->if_type) {
- case VPFE_BT656:
- case VPFE_YCBCR_SYNC_16:
- case VPFE_YCBCR_SYNC_8:
- ccdc_cfg.ycbcr.vd_pol = params->vdpol;
- ccdc_cfg.ycbcr.hd_pol = params->hdpol;
- break;
- default:
- /* TODO add support for raw bayer here */
- return -EINVAL;
- }
- return 0;
-}
-
-static struct ccdc_hw_device ccdc_hw_dev = {
- .name = "DM355 CCDC",
- .owner = THIS_MODULE,
- .hw_ops = {
- .open = ccdc_open,
- .close = ccdc_close,
- .enable = ccdc_enable,
- .enable_out_to_sdram = ccdc_enable_output_to_sdram,
- .set_hw_if_params = ccdc_set_hw_if_params,
- .set_params = ccdc_set_params,
- .configure = ccdc_configure,
- .set_buftype = ccdc_set_buftype,
- .get_buftype = ccdc_get_buftype,
- .enum_pix = ccdc_enum_pix,
- .set_pixel_format = ccdc_set_pixel_format,
- .get_pixel_format = ccdc_get_pixel_format,
- .set_frame_format = ccdc_set_frame_format,
- .get_frame_format = ccdc_get_frame_format,
- .set_image_window = ccdc_set_image_window,
- .get_image_window = ccdc_get_image_window,
- .get_line_length = ccdc_get_line_length,
- .setfbaddr = ccdc_setfbaddr,
- .getfid = ccdc_getfid,
- },
-};
-
-static int __init dm355_ccdc_probe(struct platform_device *pdev)
-{
- void (*setup_pinmux)(void);
- struct resource *res;
- int status = 0;
-
- /*
- * first try to register with vpfe. If not correct platform, then we
- * don't have to iomap
- */
- status = vpfe_register_ccdc_device(&ccdc_hw_dev);
- if (status < 0)
- return status;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- status = -ENODEV;
- goto fail_nores;
- }
-
- res = request_mem_region(res->start, resource_size(res), res->name);
- if (!res) {
- status = -EBUSY;
- goto fail_nores;
- }
-
- ccdc_cfg.base_addr = ioremap_nocache(res->start, resource_size(res));
- if (!ccdc_cfg.base_addr) {
- status = -ENOMEM;
- goto fail_nomem;
- }
-
- /* Get and enable Master clock */
- ccdc_cfg.mclk = clk_get(&pdev->dev, "master");
- if (IS_ERR(ccdc_cfg.mclk)) {
- status = PTR_ERR(ccdc_cfg.mclk);
- goto fail_nomap;
- }
- if (clk_enable(ccdc_cfg.mclk)) {
- status = -ENODEV;
- goto fail_mclk;
- }
-
- /* Get and enable Slave clock */
- ccdc_cfg.sclk = clk_get(&pdev->dev, "slave");
- if (IS_ERR(ccdc_cfg.sclk)) {
- status = PTR_ERR(ccdc_cfg.sclk);
- goto fail_mclk;
- }
- if (clk_enable(ccdc_cfg.sclk)) {
- status = -ENODEV;
- goto fail_sclk;
- }
-
- /* Platform data holds setup_pinmux function ptr */
- if (NULL == pdev->dev.platform_data) {
- status = -ENODEV;
- goto fail_sclk;
- }
- setup_pinmux = pdev->dev.platform_data;
- /*
- * setup Mux configuration for ccdc which may be different for
- * different SoCs using this CCDC
- */
- setup_pinmux();
- ccdc_cfg.dev = &pdev->dev;
- printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
- return 0;
-fail_sclk:
- clk_put(ccdc_cfg.sclk);
-fail_mclk:
- clk_put(ccdc_cfg.mclk);
-fail_nomap:
- iounmap(ccdc_cfg.base_addr);
-fail_nomem:
- release_mem_region(res->start, resource_size(res));
-fail_nores:
- vpfe_unregister_ccdc_device(&ccdc_hw_dev);
- return status;
-}
-
-static int dm355_ccdc_remove(struct platform_device *pdev)
-{
- struct resource *res;
-
- clk_put(ccdc_cfg.mclk);
- clk_put(ccdc_cfg.sclk);
- iounmap(ccdc_cfg.base_addr);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res)
- release_mem_region(res->start, resource_size(res));
- vpfe_unregister_ccdc_device(&ccdc_hw_dev);
- return 0;
-}
-
-static struct platform_driver dm355_ccdc_driver = {
- .driver = {
- .name = "dm355_ccdc",
- .owner = THIS_MODULE,
- },
- .remove = __devexit_p(dm355_ccdc_remove),
- .probe = dm355_ccdc_probe,
-};
-
-module_platform_driver(dm355_ccdc_driver);
diff --git a/drivers/media/video/davinci/dm355_ccdc_regs.h b/drivers/media/video/davinci/dm355_ccdc_regs.h
deleted file mode 100644
index d6d2ef0533b..00000000000
--- a/drivers/media/video/davinci/dm355_ccdc_regs.h
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2005-2009 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef _DM355_CCDC_REGS_H
-#define _DM355_CCDC_REGS_H
-
-/**************************************************************************\
-* Register OFFSET Definitions
-\**************************************************************************/
-#define SYNCEN 0x00
-#define MODESET 0x04
-#define HDWIDTH 0x08
-#define VDWIDTH 0x0c
-#define PPLN 0x10
-#define LPFR 0x14
-#define SPH 0x18
-#define NPH 0x1c
-#define SLV0 0x20
-#define SLV1 0x24
-#define NLV 0x28
-#define CULH 0x2c
-#define CULV 0x30
-#define HSIZE 0x34
-#define SDOFST 0x38
-#define STADRH 0x3c
-#define STADRL 0x40
-#define CLAMP 0x44
-#define DCSUB 0x48
-#define COLPTN 0x4c
-#define BLKCMP0 0x50
-#define BLKCMP1 0x54
-#define MEDFILT 0x58
-#define RYEGAIN 0x5c
-#define GRCYGAIN 0x60
-#define GBGGAIN 0x64
-#define BMGGAIN 0x68
-#define OFFSET 0x6c
-#define OUTCLIP 0x70
-#define VDINT0 0x74
-#define VDINT1 0x78
-#define RSV0 0x7c
-#define GAMMAWD 0x80
-#define REC656IF 0x84
-#define CCDCFG 0x88
-#define FMTCFG 0x8c
-#define FMTPLEN 0x90
-#define FMTSPH 0x94
-#define FMTLNH 0x98
-#define FMTSLV 0x9c
-#define FMTLNV 0xa0
-#define FMTRLEN 0xa4
-#define FMTHCNT 0xa8
-#define FMT_ADDR_PTR_B 0xac
-#define FMT_ADDR_PTR(i) (FMT_ADDR_PTR_B + (i * 4))
-#define FMTPGM_VF0 0xcc
-#define FMTPGM_VF1 0xd0
-#define FMTPGM_AP0 0xd4
-#define FMTPGM_AP1 0xd8
-#define FMTPGM_AP2 0xdc
-#define FMTPGM_AP3 0xe0
-#define FMTPGM_AP4 0xe4
-#define FMTPGM_AP5 0xe8
-#define FMTPGM_AP6 0xec
-#define FMTPGM_AP7 0xf0
-#define LSCCFG1 0xf4
-#define LSCCFG2 0xf8
-#define LSCH0 0xfc
-#define LSCV0 0x100
-#define LSCKH 0x104
-#define LSCKV 0x108
-#define LSCMEMCTL 0x10c
-#define LSCMEMD 0x110
-#define LSCMEMQ 0x114
-#define DFCCTL 0x118
-#define DFCVSAT 0x11c
-#define DFCMEMCTL 0x120
-#define DFCMEM0 0x124
-#define DFCMEM1 0x128
-#define DFCMEM2 0x12c
-#define DFCMEM3 0x130
-#define DFCMEM4 0x134
-#define CSCCTL 0x138
-#define CSCM0 0x13c
-#define CSCM1 0x140
-#define CSCM2 0x144
-#define CSCM3 0x148
-#define CSCM4 0x14c
-#define CSCM5 0x150
-#define CSCM6 0x154
-#define CSCM7 0x158
-#define DATAOFST 0x15c
-#define CCDC_REG_LAST DATAOFST
-/**************************************************************
-* Define for various register bit mask and shifts for CCDC
-*
-**************************************************************/
-#define CCDC_RAW_IP_MODE 0
-#define CCDC_VDHDOUT_INPUT 0
-#define CCDC_YCINSWP_RAW (0 << 4)
-#define CCDC_EXWEN_DISABLE 0
-#define CCDC_DATAPOL_NORMAL 0
-#define CCDC_CCDCFG_FIDMD_LATCH_VSYNC 0
-#define CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC (1 << 6)
-#define CCDC_CCDCFG_WENLOG_AND 0
-#define CCDC_CCDCFG_TRGSEL_WEN 0
-#define CCDC_CCDCFG_EXTRG_DISABLE 0
-#define CCDC_CFA_MOSAIC 0
-#define CCDC_Y8POS_SHIFT 11
-
-#define CCDC_VDC_DFCVSAT_MASK 0x3fff
-#define CCDC_DATAOFST_MASK 0x0ff
-#define CCDC_DATAOFST_H_SHIFT 0
-#define CCDC_DATAOFST_V_SHIFT 8
-#define CCDC_GAMMAWD_CFA_MASK 1
-#define CCDC_GAMMAWD_CFA_SHIFT 5
-#define CCDC_GAMMAWD_INPUT_SHIFT 2
-#define CCDC_FID_POL_MASK 1
-#define CCDC_FID_POL_SHIFT 4
-#define CCDC_HD_POL_MASK 1
-#define CCDC_HD_POL_SHIFT 3
-#define CCDC_VD_POL_MASK 1
-#define CCDC_VD_POL_SHIFT 2
-#define CCDC_VD_POL_NEGATIVE (1 << 2)
-#define CCDC_FRM_FMT_MASK 1
-#define CCDC_FRM_FMT_SHIFT 7
-#define CCDC_DATA_SZ_MASK 7
-#define CCDC_DATA_SZ_SHIFT 8
-#define CCDC_VDHDOUT_MASK 1
-#define CCDC_VDHDOUT_SHIFT 0
-#define CCDC_EXWEN_MASK 1
-#define CCDC_EXWEN_SHIFT 5
-#define CCDC_INPUT_MODE_MASK 3
-#define CCDC_INPUT_MODE_SHIFT 12
-#define CCDC_PIX_FMT_MASK 3
-#define CCDC_PIX_FMT_SHIFT 12
-#define CCDC_DATAPOL_MASK 1
-#define CCDC_DATAPOL_SHIFT 6
-#define CCDC_WEN_ENABLE (1 << 1)
-#define CCDC_VDHDEN_ENABLE (1 << 16)
-#define CCDC_LPF_ENABLE (1 << 14)
-#define CCDC_ALAW_ENABLE 1
-#define CCDC_ALAW_GAMA_WD_MASK 7
-#define CCDC_REC656IF_BT656_EN 3
-
-#define CCDC_FMTCFG_FMTMODE_MASK 3
-#define CCDC_FMTCFG_FMTMODE_SHIFT 1
-#define CCDC_FMTCFG_LNUM_MASK 3
-#define CCDC_FMTCFG_LNUM_SHIFT 4
-#define CCDC_FMTCFG_ADDRINC_MASK 7
-#define CCDC_FMTCFG_ADDRINC_SHIFT 8
-
-#define CCDC_CCDCFG_FIDMD_SHIFT 6
-#define CCDC_CCDCFG_WENLOG_SHIFT 8
-#define CCDC_CCDCFG_TRGSEL_SHIFT 9
-#define CCDC_CCDCFG_EXTRG_SHIFT 10
-#define CCDC_CCDCFG_MSBINVI_SHIFT 13
-
-#define CCDC_HSIZE_FLIP_SHIFT 12
-#define CCDC_HSIZE_FLIP_MASK 1
-#define CCDC_HSIZE_VAL_MASK 0xFFF
-#define CCDC_SDOFST_FIELD_INTERLEAVED 0x249
-#define CCDC_SDOFST_INTERLACE_INVERSE 0x4B6D
-#define CCDC_SDOFST_INTERLACE_NORMAL 0x0B6D
-#define CCDC_SDOFST_PROGRESSIVE_INVERSE 0x4000
-#define CCDC_SDOFST_PROGRESSIVE_NORMAL 0
-#define CCDC_START_PX_HOR_MASK 0x7FFF
-#define CCDC_NUM_PX_HOR_MASK 0x7FFF
-#define CCDC_START_VER_ONE_MASK 0x7FFF
-#define CCDC_START_VER_TWO_MASK 0x7FFF
-#define CCDC_NUM_LINES_VER 0x7FFF
-
-#define CCDC_BLK_CLAMP_ENABLE (1 << 15)
-#define CCDC_BLK_SGAIN_MASK 0x1F
-#define CCDC_BLK_ST_PXL_MASK 0x1FFF
-#define CCDC_BLK_SAMPLE_LN_MASK 3
-#define CCDC_BLK_SAMPLE_LN_SHIFT 13
-
-#define CCDC_NUM_LINE_CALC_MASK 3
-#define CCDC_NUM_LINE_CALC_SHIFT 14
-
-#define CCDC_BLK_DC_SUB_MASK 0x3FFF
-#define CCDC_BLK_COMP_MASK 0xFF
-#define CCDC_BLK_COMP_GB_COMP_SHIFT 8
-#define CCDC_BLK_COMP_GR_COMP_SHIFT 0
-#define CCDC_BLK_COMP_R_COMP_SHIFT 8
-#define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15)
-#define CCDC_LATCH_ON_VSYNC_ENABLE (0 << 15)
-#define CCDC_FPC_ENABLE (1 << 15)
-#define CCDC_FPC_FPC_NUM_MASK 0x7FFF
-#define CCDC_DATA_PACK_ENABLE (1 << 11)
-#define CCDC_FMT_HORZ_FMTLNH_MASK 0x1FFF
-#define CCDC_FMT_HORZ_FMTSPH_MASK 0x1FFF
-#define CCDC_FMT_HORZ_FMTSPH_SHIFT 16
-#define CCDC_FMT_VERT_FMTLNV_MASK 0x1FFF
-#define CCDC_FMT_VERT_FMTSLV_MASK 0x1FFF
-#define CCDC_FMT_VERT_FMTSLV_SHIFT 16
-#define CCDC_VP_OUT_VERT_NUM_MASK 0x3FFF
-#define CCDC_VP_OUT_VERT_NUM_SHIFT 17
-#define CCDC_VP_OUT_HORZ_NUM_MASK 0x1FFF
-#define CCDC_VP_OUT_HORZ_NUM_SHIFT 4
-#define CCDC_VP_OUT_HORZ_ST_MASK 0xF
-
-#define CCDC_CSC_COEF_INTEG_MASK 7
-#define CCDC_CSC_COEF_DECIMAL_MASK 0x1f
-#define CCDC_CSC_COEF_INTEG_SHIFT 5
-#define CCDC_CSCM_MSB_SHIFT 8
-#define CCDC_CSC_ENABLE 1
-#define CCDC_CSC_DEC_MAX 32
-
-#define CCDC_MFILT1_SHIFT 10
-#define CCDC_MFILT2_SHIFT 8
-#define CCDC_MED_FILT_THRESH 0x3FFF
-#define CCDC_LPF_MASK 1
-#define CCDC_LPF_SHIFT 14
-#define CCDC_OFFSET_MASK 0x3FF
-#define CCDC_DATASFT_MASK 7
-#define CCDC_DATASFT_SHIFT 8
-
-#define CCDC_DF_ENABLE 1
-
-#define CCDC_FMTPLEN_P0_MASK 0xF
-#define CCDC_FMTPLEN_P1_MASK 0xF
-#define CCDC_FMTPLEN_P2_MASK 7
-#define CCDC_FMTPLEN_P3_MASK 7
-#define CCDC_FMTPLEN_P0_SHIFT 0
-#define CCDC_FMTPLEN_P1_SHIFT 4
-#define CCDC_FMTPLEN_P2_SHIFT 8
-#define CCDC_FMTPLEN_P3_SHIFT 12
-
-#define CCDC_FMTSPH_MASK 0x1FFF
-#define CCDC_FMTLNH_MASK 0x1FFF
-#define CCDC_FMTSLV_MASK 0x1FFF
-#define CCDC_FMTLNV_MASK 0x7FFF
-#define CCDC_FMTRLEN_MASK 0x1FFF
-#define CCDC_FMTHCNT_MASK 0x1FFF
-
-#define CCDC_ADP_INIT_MASK 0x1FFF
-#define CCDC_ADP_LINE_SHIFT 13
-#define CCDC_ADP_LINE_MASK 3
-#define CCDC_FMTPGN_APTR_MASK 7
-
-#define CCDC_DFCCTL_GDFCEN_MASK 1
-#define CCDC_DFCCTL_VDFCEN_MASK 1
-#define CCDC_DFCCTL_VDFC_DISABLE (0 << 4)
-#define CCDC_DFCCTL_VDFCEN_SHIFT 4
-#define CCDC_DFCCTL_VDFCSL_MASK 3
-#define CCDC_DFCCTL_VDFCSL_SHIFT 5
-#define CCDC_DFCCTL_VDFCUDA_MASK 1
-#define CCDC_DFCCTL_VDFCUDA_SHIFT 7
-#define CCDC_DFCCTL_VDFLSFT_MASK 3
-#define CCDC_DFCCTL_VDFLSFT_SHIFT 8
-#define CCDC_DFCMEMCTL_DFCMARST_MASK 1
-#define CCDC_DFCMEMCTL_DFCMARST_SHIFT 2
-#define CCDC_DFCMEMCTL_DFCMWR_MASK 1
-#define CCDC_DFCMEMCTL_DFCMWR_SHIFT 0
-#define CCDC_DFCMEMCTL_INC_ADDR (0 << 2)
-
-#define CCDC_LSCCFG_GFTSF_MASK 7
-#define CCDC_LSCCFG_GFTSF_SHIFT 1
-#define CCDC_LSCCFG_GFTINV_MASK 0xf
-#define CCDC_LSCCFG_GFTINV_SHIFT 4
-#define CCDC_LSC_GFTABLE_SEL_MASK 3
-#define CCDC_LSC_GFTABLE_EPEL_SHIFT 8
-#define CCDC_LSC_GFTABLE_OPEL_SHIFT 10
-#define CCDC_LSC_GFTABLE_EPOL_SHIFT 12
-#define CCDC_LSC_GFTABLE_OPOL_SHIFT 14
-#define CCDC_LSC_GFMODE_MASK 3
-#define CCDC_LSC_GFMODE_SHIFT 4
-#define CCDC_LSC_DISABLE 0
-#define CCDC_LSC_ENABLE 1
-#define CCDC_LSC_TABLE1_SLC 0
-#define CCDC_LSC_TABLE2_SLC 1
-#define CCDC_LSC_TABLE3_SLC 2
-#define CCDC_LSC_MEMADDR_RESET (1 << 2)
-#define CCDC_LSC_MEMADDR_INCR (0 << 2)
-#define CCDC_LSC_FRAC_MASK_T1 0xFF
-#define CCDC_LSC_INT_MASK 3
-#define CCDC_LSC_FRAC_MASK 0x3FFF
-#define CCDC_LSC_CENTRE_MASK 0x3FFF
-#define CCDC_LSC_COEF_MASK 0xff
-#define CCDC_LSC_COEFL_SHIFT 0
-#define CCDC_LSC_COEFU_SHIFT 8
-#define CCDC_GAIN_MASK 0x7FF
-#define CCDC_SYNCEN_VDHDEN_MASK (1 << 0)
-#define CCDC_SYNCEN_WEN_MASK (1 << 1)
-#define CCDC_SYNCEN_WEN_SHIFT 1
-
-/* Power on Defaults in hardware */
-#define MODESET_DEFAULT 0x200
-#define CULH_DEFAULT 0xFFFF
-#define CULV_DEFAULT 0xFF
-#define GAIN_DEFAULT 256
-#define OUTCLIP_DEFAULT 0x3FFF
-#define LSCCFG2_DEFAULT 0xE
-
-#endif
diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c
deleted file mode 100644
index 9303fe553b0..00000000000
--- a/drivers/media/video/davinci/dm644x_ccdc.c
+++ /dev/null
@@ -1,1081 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * CCDC hardware module for DM6446
- * ------------------------------
- *
- * This module is for configuring CCD controller of DM6446 VPFE to capture
- * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
- * such as Defect Pixel Correction, Color Space Conversion etc to
- * pre-process the Raw Bayer RGB data, before writing it to SDRAM. This
- * module also allows application to configure individual
- * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL.
- * To do so, application includes dm644x_ccdc.h and vpfe_capture.h header
- * files. The setparams() API is called by vpfe_capture driver
- * to configure module parameters. This file is named DM644x so that other
- * variants such DM6443 may be supported using the same module.
- *
- * TODO: Test Raw bayer parameter settings and bayer capture
- * Split module parameter structure to module specific ioctl structs
- * investigate if enum used for user space type definition
- * to be replaced by #defines or integer
- */
-#include <linux/platform_device.h>
-#include <linux/uaccess.h>
-#include <linux/videodev2.h>
-#include <linux/gfp.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/module.h>
-
-#include <media/davinci/dm644x_ccdc.h>
-#include <media/davinci/vpss.h>
-
-#include "dm644x_ccdc_regs.h"
-#include "ccdc_hw_device.h"
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("CCDC Driver for DM6446");
-MODULE_AUTHOR("Texas Instruments");
-
-static struct ccdc_oper_config {
- struct device *dev;
- /* CCDC interface type */
- enum vpfe_hw_if_type if_type;
- /* Raw Bayer configuration */
- struct ccdc_params_raw bayer;
- /* YCbCr configuration */
- struct ccdc_params_ycbcr ycbcr;
- /* Master clock */
- struct clk *mclk;
- /* slave clock */
- struct clk *sclk;
- /* ccdc base address */
- void __iomem *base_addr;
-} ccdc_cfg = {
- /* Raw configurations */
- .bayer = {
- .pix_fmt = CCDC_PIXFMT_RAW,
- .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
- .win = CCDC_WIN_VGA,
- .fid_pol = VPFE_PINPOL_POSITIVE,
- .vd_pol = VPFE_PINPOL_POSITIVE,
- .hd_pol = VPFE_PINPOL_POSITIVE,
- .config_params = {
- .data_sz = CCDC_DATA_10BITS,
- },
- },
- .ycbcr = {
- .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
- .frm_fmt = CCDC_FRMFMT_INTERLACED,
- .win = CCDC_WIN_PAL,
- .fid_pol = VPFE_PINPOL_POSITIVE,
- .vd_pol = VPFE_PINPOL_POSITIVE,
- .hd_pol = VPFE_PINPOL_POSITIVE,
- .bt656_enable = 1,
- .pix_order = CCDC_PIXORDER_CBYCRY,
- .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
- },
-};
-
-#define CCDC_MAX_RAW_YUV_FORMATS 2
-
-/* Raw Bayer formats */
-static u32 ccdc_raw_bayer_pix_formats[] =
- {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
-
-/* Raw YUV formats */
-static u32 ccdc_raw_yuv_pix_formats[] =
- {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
-
-/* CCDC Save/Restore context */
-static u32 ccdc_ctx[CCDC_REG_END / sizeof(u32)];
-
-/* register access routines */
-static inline u32 regr(u32 offset)
-{
- return __raw_readl(ccdc_cfg.base_addr + offset);
-}
-
-static inline void regw(u32 val, u32 offset)
-{
- __raw_writel(val, ccdc_cfg.base_addr + offset);
-}
-
-static void ccdc_enable(int flag)
-{
- regw(flag, CCDC_PCR);
-}
-
-static void ccdc_enable_vport(int flag)
-{
- if (flag)
- /* enable video port */
- regw(CCDC_ENABLE_VIDEO_PORT, CCDC_FMTCFG);
- else
- regw(CCDC_DISABLE_VIDEO_PORT, CCDC_FMTCFG);
-}
-
-/*
- * ccdc_setwin()
- * This function will configure the window size
- * to be capture in CCDC reg
- */
-void ccdc_setwin(struct v4l2_rect *image_win,
- enum ccdc_frmfmt frm_fmt,
- int ppc)
-{
- int horz_start, horz_nr_pixels;
- int vert_start, vert_nr_lines;
- int val = 0, mid_img = 0;
-
- dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
- /*
- * ppc - per pixel count. indicates how many pixels per cell
- * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
- * raw capture this is 1
- */
- horz_start = image_win->left << (ppc - 1);
- horz_nr_pixels = (image_win->width << (ppc - 1)) - 1;
- regw((horz_start << CCDC_HORZ_INFO_SPH_SHIFT) | horz_nr_pixels,
- CCDC_HORZ_INFO);
-
- vert_start = image_win->top;
-
- if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
- vert_nr_lines = (image_win->height >> 1) - 1;
- vert_start >>= 1;
- /* Since first line doesn't have any data */
- vert_start += 1;
- /* configure VDINT0 */
- val = (vert_start << CCDC_VDINT_VDINT0_SHIFT);
- regw(val, CCDC_VDINT);
-
- } else {
- /* Since first line doesn't have any data */
- vert_start += 1;
- vert_nr_lines = image_win->height - 1;
- /*
- * configure VDINT0 and VDINT1. VDINT1 will be at half
- * of image height
- */
- mid_img = vert_start + (image_win->height / 2);
- val = (vert_start << CCDC_VDINT_VDINT0_SHIFT) |
- (mid_img & CCDC_VDINT_VDINT1_MASK);
- regw(val, CCDC_VDINT);
-
- }
- regw((vert_start << CCDC_VERT_START_SLV0_SHIFT) | vert_start,
- CCDC_VERT_START);
- regw(vert_nr_lines, CCDC_VERT_LINES);
- dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
-}
-
-static void ccdc_readregs(void)
-{
- unsigned int val = 0;
-
- val = regr(CCDC_ALAW);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to ALAW...\n", val);
- val = regr(CCDC_CLAMP);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to CLAMP...\n", val);
- val = regr(CCDC_DCSUB);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to DCSUB...\n", val);
- val = regr(CCDC_BLKCMP);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to BLKCMP...\n", val);
- val = regr(CCDC_FPC_ADDR);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FPC_ADDR...\n", val);
- val = regr(CCDC_FPC);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FPC...\n", val);
- val = regr(CCDC_FMTCFG);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMTCFG...\n", val);
- val = regr(CCDC_COLPTN);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to COLPTN...\n", val);
- val = regr(CCDC_FMT_HORZ);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMT_HORZ...\n", val);
- val = regr(CCDC_FMT_VERT);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMT_VERT...\n", val);
- val = regr(CCDC_HSIZE_OFF);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to HSIZE_OFF...\n", val);
- val = regr(CCDC_SDOFST);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to SDOFST...\n", val);
- val = regr(CCDC_VP_OUT);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VP_OUT...\n", val);
- val = regr(CCDC_SYN_MODE);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to SYN_MODE...\n", val);
- val = regr(CCDC_HORZ_INFO);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to HORZ_INFO...\n", val);
- val = regr(CCDC_VERT_START);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_START...\n", val);
- val = regr(CCDC_VERT_LINES);
- dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_LINES...\n", val);
-}
-
-static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
-{
- if (ccdcparam->alaw.enable) {
- if ((ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) ||
- (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_15_6) ||
- (ccdcparam->alaw.gama_wd < ccdcparam->data_sz)) {
- dev_dbg(ccdc_cfg.dev, "\nInvalid data line select");
- return -1;
- }
- }
- return 0;
-}
-
-static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
-{
- struct ccdc_config_params_raw *config_params =
- &ccdc_cfg.bayer.config_params;
- unsigned int *fpc_virtaddr = NULL;
- unsigned int *fpc_physaddr = NULL;
-
- memcpy(config_params, raw_params, sizeof(*raw_params));
- /*
- * allocate memory for fault pixel table and copy the user
- * values to the table
- */
- if (!config_params->fault_pxl.enable)
- return 0;
-
- fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
- fpc_virtaddr = (unsigned int *)phys_to_virt(
- (unsigned long)fpc_physaddr);
- /*
- * Allocate memory for FPC table if current
- * FPC table buffer is not big enough to
- * accommodate FPC Number requested
- */
- if (raw_params->fault_pxl.fp_num != config_params->fault_pxl.fp_num) {
- if (fpc_physaddr != NULL) {
- free_pages((unsigned long)fpc_physaddr,
- get_order
- (config_params->fault_pxl.fp_num *
- FP_NUM_BYTES));
- }
-
- /* Allocate memory for FPC table */
- fpc_virtaddr =
- (unsigned int *)__get_free_pages(GFP_KERNEL | GFP_DMA,
- get_order(raw_params->
- fault_pxl.fp_num *
- FP_NUM_BYTES));
-
- if (fpc_virtaddr == NULL) {
- dev_dbg(ccdc_cfg.dev,
- "\nUnable to allocate memory for FPC");
- return -EFAULT;
- }
- fpc_physaddr =
- (unsigned int *)virt_to_phys((void *)fpc_virtaddr);
- }
-
- /* Copy number of fault pixels and FPC table */
- config_params->fault_pxl.fp_num = raw_params->fault_pxl.fp_num;
- if (copy_from_user(fpc_virtaddr,
- (void __user *)raw_params->fault_pxl.fpc_table_addr,
- config_params->fault_pxl.fp_num * FP_NUM_BYTES)) {
- dev_dbg(ccdc_cfg.dev, "\n copy_from_user failed");
- return -EFAULT;
- }
- config_params->fault_pxl.fpc_table_addr = (unsigned int)fpc_physaddr;
- return 0;
-}
-
-static int ccdc_close(struct device *dev)
-{
- struct ccdc_config_params_raw *config_params =
- &ccdc_cfg.bayer.config_params;
- unsigned int *fpc_physaddr = NULL, *fpc_virtaddr = NULL;
-
- fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
-
- if (fpc_physaddr != NULL) {
- fpc_virtaddr = (unsigned int *)
- phys_to_virt((unsigned long)fpc_physaddr);
- free_pages((unsigned long)fpc_virtaddr,
- get_order(config_params->fault_pxl.fp_num *
- FP_NUM_BYTES));
- }
- return 0;
-}
-
-/*
- * ccdc_restore_defaults()
- * This function will write defaults to all CCDC registers
- */
-static void ccdc_restore_defaults(void)
-{
- int i;
-
- /* disable CCDC */
- ccdc_enable(0);
- /* set all registers to default value */
- for (i = 4; i <= 0x94; i += 4)
- regw(0, i);
- regw(CCDC_NO_CULLING, CCDC_CULLING);
- regw(CCDC_GAMMA_BITS_11_2, CCDC_ALAW);
-}
-
-static int ccdc_open(struct device *device)
-{
- ccdc_restore_defaults();
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- ccdc_enable_vport(1);
- return 0;
-}
-
-static void ccdc_sbl_reset(void)
-{
- vpss_clear_wbl_overflow(VPSS_PCR_CCDC_WBL_O);
-}
-
-/* Parameter operations */
-static int ccdc_set_params(void __user *params)
-{
- struct ccdc_config_params_raw ccdc_raw_params;
- int x;
-
- if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
- return -EINVAL;
-
- x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
- if (x) {
- dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying"
- "ccdc params, %d\n", x);
- return -EFAULT;
- }
-
- if (!validate_ccdc_param(&ccdc_raw_params)) {
- if (!ccdc_update_raw_params(&ccdc_raw_params))
- return 0;
- }
- return -EINVAL;
-}
-
-/*
- * ccdc_config_ycbcr()
- * This function will configure CCDC for YCbCr video capture
- */
-void ccdc_config_ycbcr(void)
-{
- struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
- u32 syn_mode;
-
- dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
- /*
- * first restore the CCDC registers to default values
- * This is important since we assume default values to be set in
- * a lot of registers that we didn't touch
- */
- ccdc_restore_defaults();
-
- /*
- * configure pixel format, frame format, configure video frame
- * format, enable output to SDRAM, enable internal timing generator
- * and 8bit pack mode
- */
- syn_mode = (((params->pix_fmt & CCDC_SYN_MODE_INPMOD_MASK) <<
- CCDC_SYN_MODE_INPMOD_SHIFT) |
- ((params->frm_fmt & CCDC_SYN_FLDMODE_MASK) <<
- CCDC_SYN_FLDMODE_SHIFT) | CCDC_VDHDEN_ENABLE |
- CCDC_WEN_ENABLE | CCDC_DATA_PACK_ENABLE);
-
- /* setup BT.656 sync mode */
- if (params->bt656_enable) {
- regw(CCDC_REC656IF_BT656_EN, CCDC_REC656IF);
-
- /*
- * configure the FID, VD, HD pin polarity,
- * fld,hd pol positive, vd negative, 8-bit data
- */
- syn_mode |= CCDC_SYN_MODE_VD_POL_NEGATIVE;
- if (ccdc_cfg.if_type == VPFE_BT656_10BIT)
- syn_mode |= CCDC_SYN_MODE_10BITS;
- else
- syn_mode |= CCDC_SYN_MODE_8BITS;
- } else {
- /* y/c external sync mode */
- syn_mode |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
- CCDC_FID_POL_SHIFT) |
- ((params->hd_pol & CCDC_HD_POL_MASK) <<
- CCDC_HD_POL_SHIFT) |
- ((params->vd_pol & CCDC_VD_POL_MASK) <<
- CCDC_VD_POL_SHIFT));
- }
- regw(syn_mode, CCDC_SYN_MODE);
-
- /* configure video window */
- ccdc_setwin(&params->win, params->frm_fmt, 2);
-
- /*
- * configure the order of y cb cr in SDRAM, and disable latch
- * internal register on vsync
- */
- if (ccdc_cfg.if_type == VPFE_BT656_10BIT)
- regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
- CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_BW656_10BIT,
- CCDC_CCDCFG);
- else
- regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
- CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
-
- /*
- * configure the horizontal line offset. This should be a
- * on 32 byte boundary. So clear LSB 5 bits
- */
- regw(((params->win.width * 2 + 31) & ~0x1f), CCDC_HSIZE_OFF);
-
- /* configure the memory line offset */
- if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
- /* two fields are interleaved in memory */
- regw(CCDC_SDOFST_FIELD_INTERLEAVED, CCDC_SDOFST);
-
- ccdc_sbl_reset();
- dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
-}
-
-static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
-{
- u32 val;
-
- if (!bclamp->enable) {
- /* configure DCSub */
- val = (bclamp->dc_sub) & CCDC_BLK_DC_SUB_MASK;
- regw(val, CCDC_DCSUB);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to DCSUB...\n", val);
- regw(CCDC_CLAMP_DEFAULT_VAL, CCDC_CLAMP);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x0000 to CLAMP...\n");
- return;
- }
- /*
- * Configure gain, Start pixel, No of line to be avg,
- * No of pixel/line to be avg, & Enable the Black clamping
- */
- val = ((bclamp->sgain & CCDC_BLK_SGAIN_MASK) |
- ((bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) <<
- CCDC_BLK_ST_PXL_SHIFT) |
- ((bclamp->sample_ln & CCDC_BLK_SAMPLE_LINE_MASK) <<
- CCDC_BLK_SAMPLE_LINE_SHIFT) |
- ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
- CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE);
- regw(val, CCDC_CLAMP);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to CLAMP...\n", val);
- /* If Black clamping is enable then make dcsub 0 */
- regw(CCDC_DCSUB_DEFAULT_VAL, CCDC_DCSUB);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x00000000 to DCSUB...\n");
-}
-
-static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
-{
- u32 val;
-
- val = ((bcomp->b & CCDC_BLK_COMP_MASK) |
- ((bcomp->gb & CCDC_BLK_COMP_MASK) <<
- CCDC_BLK_COMP_GB_COMP_SHIFT) |
- ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
- CCDC_BLK_COMP_GR_COMP_SHIFT) |
- ((bcomp->r & CCDC_BLK_COMP_MASK) <<
- CCDC_BLK_COMP_R_COMP_SHIFT));
- regw(val, CCDC_BLKCMP);
-}
-
-static void ccdc_config_fpc(struct ccdc_fault_pixel *fpc)
-{
- u32 val;
-
- /* Initially disable FPC */
- val = CCDC_FPC_DISABLE;
- regw(val, CCDC_FPC);
-
- if (!fpc->enable)
- return;
-
- /* Configure Fault pixel if needed */
- regw(fpc->fpc_table_addr, CCDC_FPC_ADDR);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC_ADDR...\n",
- (fpc->fpc_table_addr));
- /* Write the FPC params with FPC disable */
- val = fpc->fp_num & CCDC_FPC_FPC_NUM_MASK;
- regw(val, CCDC_FPC);
-
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC...\n", val);
- /* read the FPC register */
- val = regr(CCDC_FPC) | CCDC_FPC_ENABLE;
- regw(val, CCDC_FPC);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC...\n", val);
-}
-
-/*
- * ccdc_config_raw()
- * This function will configure CCDC for Raw capture mode
- */
-void ccdc_config_raw(void)
-{
- struct ccdc_params_raw *params = &ccdc_cfg.bayer;
- struct ccdc_config_params_raw *config_params =
- &ccdc_cfg.bayer.config_params;
- unsigned int syn_mode = 0;
- unsigned int val;
-
- dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
-
- /* Reset CCDC */
- ccdc_restore_defaults();
-
- /* Disable latching function registers on VSYNC */
- regw(CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
-
- /*
- * Configure the vertical sync polarity(SYN_MODE.VDPOL),
- * horizontal sync polarity (SYN_MODE.HDPOL), frame id polarity
- * (SYN_MODE.FLDPOL), frame format(progressive or interlace),
- * data size(SYNMODE.DATSIZ), &pixel format (Input mode), output
- * SDRAM, enable internal timing generator
- */
- syn_mode =
- (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) |
- ((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) |
- ((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) |
- ((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
- ((config_params->data_sz & CCDC_DATA_SZ_MASK) <<
- CCDC_DATA_SZ_SHIFT) |
- ((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT) |
- CCDC_WEN_ENABLE | CCDC_VDHDEN_ENABLE);
-
- /* Enable and configure aLaw register if needed */
- if (config_params->alaw.enable) {
- val = ((config_params->alaw.gama_wd &
- CCDC_ALAW_GAMA_WD_MASK) | CCDC_ALAW_ENABLE);
- regw(val, CCDC_ALAW);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to ALAW...\n", val);
- }
-
- /* Configure video window */
- ccdc_setwin(&params->win, params->frm_fmt, CCDC_PPC_RAW);
-
- /* Configure Black Clamp */
- ccdc_config_black_clamp(&config_params->blk_clamp);
-
- /* Configure Black level compensation */
- ccdc_config_black_compense(&config_params->blk_comp);
-
- /* Configure Fault Pixel Correction */
- ccdc_config_fpc(&config_params->fault_pxl);
-
- /* If data size is 8 bit then pack the data */
- if ((config_params->data_sz == CCDC_DATA_8BITS) ||
- config_params->alaw.enable)
- syn_mode |= CCDC_DATA_PACK_ENABLE;
-
-#ifdef CONFIG_DM644X_VIDEO_PORT_ENABLE
- /* enable video port */
- val = CCDC_ENABLE_VIDEO_PORT;
-#else
- /* disable video port */
- val = CCDC_DISABLE_VIDEO_PORT;
-#endif
-
- if (config_params->data_sz == CCDC_DATA_8BITS)
- val |= (CCDC_DATA_10BITS & CCDC_FMTCFG_VPIN_MASK)
- << CCDC_FMTCFG_VPIN_SHIFT;
- else
- val |= (config_params->data_sz & CCDC_FMTCFG_VPIN_MASK)
- << CCDC_FMTCFG_VPIN_SHIFT;
- /* Write value in FMTCFG */
- regw(val, CCDC_FMTCFG);
-
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMTCFG...\n", val);
- /* Configure the color pattern according to mt9t001 sensor */
- regw(CCDC_COLPTN_VAL, CCDC_COLPTN);
-
- dev_dbg(ccdc_cfg.dev, "\nWriting 0xBB11BB11 to COLPTN...\n");
- /*
- * Configure Data formatter(Video port) pixel selection
- * (FMT_HORZ, FMT_VERT)
- */
- val = ((params->win.left & CCDC_FMT_HORZ_FMTSPH_MASK) <<
- CCDC_FMT_HORZ_FMTSPH_SHIFT) |
- (params->win.width & CCDC_FMT_HORZ_FMTLNH_MASK);
- regw(val, CCDC_FMT_HORZ);
-
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMT_HORZ...\n", val);
- val = (params->win.top & CCDC_FMT_VERT_FMTSLV_MASK)
- << CCDC_FMT_VERT_FMTSLV_SHIFT;
- if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
- val |= (params->win.height) & CCDC_FMT_VERT_FMTLNV_MASK;
- else
- val |= (params->win.height >> 1) & CCDC_FMT_VERT_FMTLNV_MASK;
-
- dev_dbg(ccdc_cfg.dev, "\nparams->win.height 0x%x ...\n",
- params->win.height);
- regw(val, CCDC_FMT_VERT);
-
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMT_VERT...\n", val);
-
- dev_dbg(ccdc_cfg.dev, "\nbelow regw(val, FMT_VERT)...");
-
- /*
- * Configure Horizontal offset register. If pack 8 is enabled then
- * 1 pixel will take 1 byte
- */
- if ((config_params->data_sz == CCDC_DATA_8BITS) ||
- config_params->alaw.enable)
- regw((params->win.width + CCDC_32BYTE_ALIGN_VAL) &
- CCDC_HSIZE_OFF_MASK, CCDC_HSIZE_OFF);
- else
- /* else one pixel will take 2 byte */
- regw(((params->win.width * CCDC_TWO_BYTES_PER_PIXEL) +
- CCDC_32BYTE_ALIGN_VAL) & CCDC_HSIZE_OFF_MASK,
- CCDC_HSIZE_OFF);
-
- /* Set value for SDOFST */
- if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
- if (params->image_invert_enable) {
- /* For intelace inverse mode */
- regw(CCDC_INTERLACED_IMAGE_INVERT, CCDC_SDOFST);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x4B6D to SDOFST..\n");
- }
-
- else {
- /* For intelace non inverse mode */
- regw(CCDC_INTERLACED_NO_IMAGE_INVERT, CCDC_SDOFST);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x0249 to SDOFST..\n");
- }
- } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
- regw(CCDC_PROGRESSIVE_NO_IMAGE_INVERT, CCDC_SDOFST);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x0000 to SDOFST...\n");
- }
-
- /*
- * Configure video port pixel selection (VPOUT)
- * Here -1 is to make the height value less than FMT_VERT.FMTLNV
- */
- if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
- val = (((params->win.height - 1) & CCDC_VP_OUT_VERT_NUM_MASK))
- << CCDC_VP_OUT_VERT_NUM_SHIFT;
- else
- val =
- ((((params->win.height >> CCDC_INTERLACED_HEIGHT_SHIFT) -
- 1) & CCDC_VP_OUT_VERT_NUM_MASK)) <<
- CCDC_VP_OUT_VERT_NUM_SHIFT;
-
- val |= ((((params->win.width))) & CCDC_VP_OUT_HORZ_NUM_MASK)
- << CCDC_VP_OUT_HORZ_NUM_SHIFT;
- val |= (params->win.left) & CCDC_VP_OUT_HORZ_ST_MASK;
- regw(val, CCDC_VP_OUT);
-
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to VP_OUT...\n", val);
- regw(syn_mode, CCDC_SYN_MODE);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode);
-
- ccdc_sbl_reset();
- dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
- ccdc_readregs();
-}
-
-static int ccdc_configure(void)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- ccdc_config_raw();
- else
- ccdc_config_ycbcr();
- return 0;
-}
-
-static int ccdc_set_buftype(enum ccdc_buftype buf_type)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- ccdc_cfg.bayer.buf_type = buf_type;
- else
- ccdc_cfg.ycbcr.buf_type = buf_type;
- return 0;
-}
-
-static enum ccdc_buftype ccdc_get_buftype(void)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- return ccdc_cfg.bayer.buf_type;
- return ccdc_cfg.ycbcr.buf_type;
-}
-
-static int ccdc_enum_pix(u32 *pix, int i)
-{
- int ret = -EINVAL;
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
- if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
- *pix = ccdc_raw_bayer_pix_formats[i];
- ret = 0;
- }
- } else {
- if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
- *pix = ccdc_raw_yuv_pix_formats[i];
- ret = 0;
- }
- }
- return ret;
-}
-
-static int ccdc_set_pixel_format(u32 pixfmt)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
- ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
- if (pixfmt == V4L2_PIX_FMT_SBGGR8)
- ccdc_cfg.bayer.config_params.alaw.enable = 1;
- else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
- return -EINVAL;
- } else {
- if (pixfmt == V4L2_PIX_FMT_YUYV)
- ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
- else if (pixfmt == V4L2_PIX_FMT_UYVY)
- ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
- else
- return -EINVAL;
- }
- return 0;
-}
-
-static u32 ccdc_get_pixel_format(void)
-{
- struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
- u32 pixfmt;
-
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- if (alaw->enable)
- pixfmt = V4L2_PIX_FMT_SBGGR8;
- else
- pixfmt = V4L2_PIX_FMT_SBGGR16;
- else {
- if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
- pixfmt = V4L2_PIX_FMT_YUYV;
- else
- pixfmt = V4L2_PIX_FMT_UYVY;
- }
- return pixfmt;
-}
-
-static int ccdc_set_image_window(struct v4l2_rect *win)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- ccdc_cfg.bayer.win = *win;
- else
- ccdc_cfg.ycbcr.win = *win;
- return 0;
-}
-
-static void ccdc_get_image_window(struct v4l2_rect *win)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- *win = ccdc_cfg.bayer.win;
- else
- *win = ccdc_cfg.ycbcr.win;
-}
-
-static unsigned int ccdc_get_line_length(void)
-{
- struct ccdc_config_params_raw *config_params =
- &ccdc_cfg.bayer.config_params;
- unsigned int len;
-
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
- if ((config_params->alaw.enable) ||
- (config_params->data_sz == CCDC_DATA_8BITS))
- len = ccdc_cfg.bayer.win.width;
- else
- len = ccdc_cfg.bayer.win.width * 2;
- } else
- len = ccdc_cfg.ycbcr.win.width * 2;
- return ALIGN(len, 32);
-}
-
-static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- ccdc_cfg.bayer.frm_fmt = frm_fmt;
- else
- ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
- return 0;
-}
-
-static enum ccdc_frmfmt ccdc_get_frame_format(void)
-{
- if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
- return ccdc_cfg.bayer.frm_fmt;
- else
- return ccdc_cfg.ycbcr.frm_fmt;
-}
-
-static int ccdc_getfid(void)
-{
- return (regr(CCDC_SYN_MODE) >> 15) & 1;
-}
-
-/* misc operations */
-static inline void ccdc_setfbaddr(unsigned long addr)
-{
- regw(addr & 0xffffffe0, CCDC_SDR_ADDR);
-}
-
-static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
-{
- ccdc_cfg.if_type = params->if_type;
-
- switch (params->if_type) {
- case VPFE_BT656:
- case VPFE_YCBCR_SYNC_16:
- case VPFE_YCBCR_SYNC_8:
- case VPFE_BT656_10BIT:
- ccdc_cfg.ycbcr.vd_pol = params->vdpol;
- ccdc_cfg.ycbcr.hd_pol = params->hdpol;
- break;
- default:
- /* TODO add support for raw bayer here */
- return -EINVAL;
- }
- return 0;
-}
-
-static void ccdc_save_context(void)
-{
- ccdc_ctx[CCDC_PCR >> 2] = regr(CCDC_PCR);
- ccdc_ctx[CCDC_SYN_MODE >> 2] = regr(CCDC_SYN_MODE);
- ccdc_ctx[CCDC_HD_VD_WID >> 2] = regr(CCDC_HD_VD_WID);
- ccdc_ctx[CCDC_PIX_LINES >> 2] = regr(CCDC_PIX_LINES);
- ccdc_ctx[CCDC_HORZ_INFO >> 2] = regr(CCDC_HORZ_INFO);
- ccdc_ctx[CCDC_VERT_START >> 2] = regr(CCDC_VERT_START);
- ccdc_ctx[CCDC_VERT_LINES >> 2] = regr(CCDC_VERT_LINES);
- ccdc_ctx[CCDC_CULLING >> 2] = regr(CCDC_CULLING);
- ccdc_ctx[CCDC_HSIZE_OFF >> 2] = regr(CCDC_HSIZE_OFF);
- ccdc_ctx[CCDC_SDOFST >> 2] = regr(CCDC_SDOFST);
- ccdc_ctx[CCDC_SDR_ADDR >> 2] = regr(CCDC_SDR_ADDR);
- ccdc_ctx[CCDC_CLAMP >> 2] = regr(CCDC_CLAMP);
- ccdc_ctx[CCDC_DCSUB >> 2] = regr(CCDC_DCSUB);
- ccdc_ctx[CCDC_COLPTN >> 2] = regr(CCDC_COLPTN);
- ccdc_ctx[CCDC_BLKCMP >> 2] = regr(CCDC_BLKCMP);
- ccdc_ctx[CCDC_FPC >> 2] = regr(CCDC_FPC);
- ccdc_ctx[CCDC_FPC_ADDR >> 2] = regr(CCDC_FPC_ADDR);
- ccdc_ctx[CCDC_VDINT >> 2] = regr(CCDC_VDINT);
- ccdc_ctx[CCDC_ALAW >> 2] = regr(CCDC_ALAW);
- ccdc_ctx[CCDC_REC656IF >> 2] = regr(CCDC_REC656IF);
- ccdc_ctx[CCDC_CCDCFG >> 2] = regr(CCDC_CCDCFG);
- ccdc_ctx[CCDC_FMTCFG >> 2] = regr(CCDC_FMTCFG);
- ccdc_ctx[CCDC_FMT_HORZ >> 2] = regr(CCDC_FMT_HORZ);
- ccdc_ctx[CCDC_FMT_VERT >> 2] = regr(CCDC_FMT_VERT);
- ccdc_ctx[CCDC_FMT_ADDR0 >> 2] = regr(CCDC_FMT_ADDR0);
- ccdc_ctx[CCDC_FMT_ADDR1 >> 2] = regr(CCDC_FMT_ADDR1);
- ccdc_ctx[CCDC_FMT_ADDR2 >> 2] = regr(CCDC_FMT_ADDR2);
- ccdc_ctx[CCDC_FMT_ADDR3 >> 2] = regr(CCDC_FMT_ADDR3);
- ccdc_ctx[CCDC_FMT_ADDR4 >> 2] = regr(CCDC_FMT_ADDR4);
- ccdc_ctx[CCDC_FMT_ADDR5 >> 2] = regr(CCDC_FMT_ADDR5);
- ccdc_ctx[CCDC_FMT_ADDR6 >> 2] = regr(CCDC_FMT_ADDR6);
- ccdc_ctx[CCDC_FMT_ADDR7 >> 2] = regr(CCDC_FMT_ADDR7);
- ccdc_ctx[CCDC_PRGEVEN_0 >> 2] = regr(CCDC_PRGEVEN_0);
- ccdc_ctx[CCDC_PRGEVEN_1 >> 2] = regr(CCDC_PRGEVEN_1);
- ccdc_ctx[CCDC_PRGODD_0 >> 2] = regr(CCDC_PRGODD_0);
- ccdc_ctx[CCDC_PRGODD_1 >> 2] = regr(CCDC_PRGODD_1);
- ccdc_ctx[CCDC_VP_OUT >> 2] = regr(CCDC_VP_OUT);
-}
-
-static void ccdc_restore_context(void)
-{
- regw(ccdc_ctx[CCDC_SYN_MODE >> 2], CCDC_SYN_MODE);
- regw(ccdc_ctx[CCDC_HD_VD_WID >> 2], CCDC_HD_VD_WID);
- regw(ccdc_ctx[CCDC_PIX_LINES >> 2], CCDC_PIX_LINES);
- regw(ccdc_ctx[CCDC_HORZ_INFO >> 2], CCDC_HORZ_INFO);
- regw(ccdc_ctx[CCDC_VERT_START >> 2], CCDC_VERT_START);
- regw(ccdc_ctx[CCDC_VERT_LINES >> 2], CCDC_VERT_LINES);
- regw(ccdc_ctx[CCDC_CULLING >> 2], CCDC_CULLING);
- regw(ccdc_ctx[CCDC_HSIZE_OFF >> 2], CCDC_HSIZE_OFF);
- regw(ccdc_ctx[CCDC_SDOFST >> 2], CCDC_SDOFST);
- regw(ccdc_ctx[CCDC_SDR_ADDR >> 2], CCDC_SDR_ADDR);
- regw(ccdc_ctx[CCDC_CLAMP >> 2], CCDC_CLAMP);
- regw(ccdc_ctx[CCDC_DCSUB >> 2], CCDC_DCSUB);
- regw(ccdc_ctx[CCDC_COLPTN >> 2], CCDC_COLPTN);
- regw(ccdc_ctx[CCDC_BLKCMP >> 2], CCDC_BLKCMP);
- regw(ccdc_ctx[CCDC_FPC >> 2], CCDC_FPC);
- regw(ccdc_ctx[CCDC_FPC_ADDR >> 2], CCDC_FPC_ADDR);
- regw(ccdc_ctx[CCDC_VDINT >> 2], CCDC_VDINT);
- regw(ccdc_ctx[CCDC_ALAW >> 2], CCDC_ALAW);
- regw(ccdc_ctx[CCDC_REC656IF >> 2], CCDC_REC656IF);
- regw(ccdc_ctx[CCDC_CCDCFG >> 2], CCDC_CCDCFG);
- regw(ccdc_ctx[CCDC_FMTCFG >> 2], CCDC_FMTCFG);
- regw(ccdc_ctx[CCDC_FMT_HORZ >> 2], CCDC_FMT_HORZ);
- regw(ccdc_ctx[CCDC_FMT_VERT >> 2], CCDC_FMT_VERT);
- regw(ccdc_ctx[CCDC_FMT_ADDR0 >> 2], CCDC_FMT_ADDR0);
- regw(ccdc_ctx[CCDC_FMT_ADDR1 >> 2], CCDC_FMT_ADDR1);
- regw(ccdc_ctx[CCDC_FMT_ADDR2 >> 2], CCDC_FMT_ADDR2);
- regw(ccdc_ctx[CCDC_FMT_ADDR3 >> 2], CCDC_FMT_ADDR3);
- regw(ccdc_ctx[CCDC_FMT_ADDR4 >> 2], CCDC_FMT_ADDR4);
- regw(ccdc_ctx[CCDC_FMT_ADDR5 >> 2], CCDC_FMT_ADDR5);
- regw(ccdc_ctx[CCDC_FMT_ADDR6 >> 2], CCDC_FMT_ADDR6);
- regw(ccdc_ctx[CCDC_FMT_ADDR7 >> 2], CCDC_FMT_ADDR7);
- regw(ccdc_ctx[CCDC_PRGEVEN_0 >> 2], CCDC_PRGEVEN_0);
- regw(ccdc_ctx[CCDC_PRGEVEN_1 >> 2], CCDC_PRGEVEN_1);
- regw(ccdc_ctx[CCDC_PRGODD_0 >> 2], CCDC_PRGODD_0);
- regw(ccdc_ctx[CCDC_PRGODD_1 >> 2], CCDC_PRGODD_1);
- regw(ccdc_ctx[CCDC_VP_OUT >> 2], CCDC_VP_OUT);
- regw(ccdc_ctx[CCDC_PCR >> 2], CCDC_PCR);
-}
-static struct ccdc_hw_device ccdc_hw_dev = {
- .name = "DM6446 CCDC",
- .owner = THIS_MODULE,
- .hw_ops = {
- .open = ccdc_open,
- .close = ccdc_close,
- .reset = ccdc_sbl_reset,
- .enable = ccdc_enable,
- .set_hw_if_params = ccdc_set_hw_if_params,
- .set_params = ccdc_set_params,
- .configure = ccdc_configure,
- .set_buftype = ccdc_set_buftype,
- .get_buftype = ccdc_get_buftype,
- .enum_pix = ccdc_enum_pix,
- .set_pixel_format = ccdc_set_pixel_format,
- .get_pixel_format = ccdc_get_pixel_format,
- .set_frame_format = ccdc_set_frame_format,
- .get_frame_format = ccdc_get_frame_format,
- .set_image_window = ccdc_set_image_window,
- .get_image_window = ccdc_get_image_window,
- .get_line_length = ccdc_get_line_length,
- .setfbaddr = ccdc_setfbaddr,
- .getfid = ccdc_getfid,
- },
-};
-
-static int __init dm644x_ccdc_probe(struct platform_device *pdev)
-{
- struct resource *res;
- int status = 0;
-
- /*
- * first try to register with vpfe. If not correct platform, then we
- * don't have to iomap
- */
- status = vpfe_register_ccdc_device(&ccdc_hw_dev);
- if (status < 0)
- return status;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- status = -ENODEV;
- goto fail_nores;
- }
-
- res = request_mem_region(res->start, resource_size(res), res->name);
- if (!res) {
- status = -EBUSY;
- goto fail_nores;
- }
-
- ccdc_cfg.base_addr = ioremap_nocache(res->start, resource_size(res));
- if (!ccdc_cfg.base_addr) {
- status = -ENOMEM;
- goto fail_nomem;
- }
-
- /* Get and enable Master clock */
- ccdc_cfg.mclk = clk_get(&pdev->dev, "master");
- if (IS_ERR(ccdc_cfg.mclk)) {
- status = PTR_ERR(ccdc_cfg.mclk);
- goto fail_nomap;
- }
- if (clk_enable(ccdc_cfg.mclk)) {
- status = -ENODEV;
- goto fail_mclk;
- }
-
- /* Get and enable Slave clock */
- ccdc_cfg.sclk = clk_get(&pdev->dev, "slave");
- if (IS_ERR(ccdc_cfg.sclk)) {
- status = PTR_ERR(ccdc_cfg.sclk);
- goto fail_mclk;
- }
- if (clk_enable(ccdc_cfg.sclk)) {
- status = -ENODEV;
- goto fail_sclk;
- }
- ccdc_cfg.dev = &pdev->dev;
- printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
- return 0;
-fail_sclk:
- clk_put(ccdc_cfg.sclk);
-fail_mclk:
- clk_put(ccdc_cfg.mclk);
-fail_nomap:
- iounmap(ccdc_cfg.base_addr);
-fail_nomem:
- release_mem_region(res->start, resource_size(res));
-fail_nores:
- vpfe_unregister_ccdc_device(&ccdc_hw_dev);
- return status;
-}
-
-static int dm644x_ccdc_remove(struct platform_device *pdev)
-{
- struct resource *res;
-
- clk_put(ccdc_cfg.mclk);
- clk_put(ccdc_cfg.sclk);
- iounmap(ccdc_cfg.base_addr);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res)
- release_mem_region(res->start, resource_size(res));
- vpfe_unregister_ccdc_device(&ccdc_hw_dev);
- return 0;
-}
-
-static int dm644x_ccdc_suspend(struct device *dev)
-{
- /* Save CCDC context */
- ccdc_save_context();
- /* Disable CCDC */
- ccdc_enable(0);
- /* Disable both master and slave clock */
- clk_disable(ccdc_cfg.mclk);
- clk_disable(ccdc_cfg.sclk);
-
- return 0;
-}
-
-static int dm644x_ccdc_resume(struct device *dev)
-{
- /* Enable both master and slave clock */
- clk_enable(ccdc_cfg.mclk);
- clk_enable(ccdc_cfg.sclk);
- /* Restore CCDC context */
- ccdc_restore_context();
-
- return 0;
-}
-
-static const struct dev_pm_ops dm644x_ccdc_pm_ops = {
- .suspend = dm644x_ccdc_suspend,
- .resume = dm644x_ccdc_resume,
-};
-
-static struct platform_driver dm644x_ccdc_driver = {
- .driver = {
- .name = "dm644x_ccdc",
- .owner = THIS_MODULE,
- .pm = &dm644x_ccdc_pm_ops,
- },
- .remove = __devexit_p(dm644x_ccdc_remove),
- .probe = dm644x_ccdc_probe,
-};
-
-module_platform_driver(dm644x_ccdc_driver);
diff --git a/drivers/media/video/davinci/dm644x_ccdc_regs.h b/drivers/media/video/davinci/dm644x_ccdc_regs.h
deleted file mode 100644
index 90370e414e2..00000000000
--- a/drivers/media/video/davinci/dm644x_ccdc_regs.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef _DM644X_CCDC_REGS_H
-#define _DM644X_CCDC_REGS_H
-
-/**************************************************************************\
-* Register OFFSET Definitions
-\**************************************************************************/
-#define CCDC_PID 0x0
-#define CCDC_PCR 0x4
-#define CCDC_SYN_MODE 0x8
-#define CCDC_HD_VD_WID 0xc
-#define CCDC_PIX_LINES 0x10
-#define CCDC_HORZ_INFO 0x14
-#define CCDC_VERT_START 0x18
-#define CCDC_VERT_LINES 0x1c
-#define CCDC_CULLING 0x20
-#define CCDC_HSIZE_OFF 0x24
-#define CCDC_SDOFST 0x28
-#define CCDC_SDR_ADDR 0x2c
-#define CCDC_CLAMP 0x30
-#define CCDC_DCSUB 0x34
-#define CCDC_COLPTN 0x38
-#define CCDC_BLKCMP 0x3c
-#define CCDC_FPC 0x40
-#define CCDC_FPC_ADDR 0x44
-#define CCDC_VDINT 0x48
-#define CCDC_ALAW 0x4c
-#define CCDC_REC656IF 0x50
-#define CCDC_CCDCFG 0x54
-#define CCDC_FMTCFG 0x58
-#define CCDC_FMT_HORZ 0x5c
-#define CCDC_FMT_VERT 0x60
-#define CCDC_FMT_ADDR0 0x64
-#define CCDC_FMT_ADDR1 0x68
-#define CCDC_FMT_ADDR2 0x6c
-#define CCDC_FMT_ADDR3 0x70
-#define CCDC_FMT_ADDR4 0x74
-#define CCDC_FMT_ADDR5 0x78
-#define CCDC_FMT_ADDR6 0x7c
-#define CCDC_FMT_ADDR7 0x80
-#define CCDC_PRGEVEN_0 0x84
-#define CCDC_PRGEVEN_1 0x88
-#define CCDC_PRGODD_0 0x8c
-#define CCDC_PRGODD_1 0x90
-#define CCDC_VP_OUT 0x94
-#define CCDC_REG_END 0x98
-
-/***************************************************************
-* Define for various register bit mask and shifts for CCDC
-****************************************************************/
-#define CCDC_FID_POL_MASK 1
-#define CCDC_FID_POL_SHIFT 4
-#define CCDC_HD_POL_MASK 1
-#define CCDC_HD_POL_SHIFT 3
-#define CCDC_VD_POL_MASK 1
-#define CCDC_VD_POL_SHIFT 2
-#define CCDC_HSIZE_OFF_MASK 0xffffffe0
-#define CCDC_32BYTE_ALIGN_VAL 31
-#define CCDC_FRM_FMT_MASK 0x1
-#define CCDC_FRM_FMT_SHIFT 7
-#define CCDC_DATA_SZ_MASK 7
-#define CCDC_DATA_SZ_SHIFT 8
-#define CCDC_PIX_FMT_MASK 3
-#define CCDC_PIX_FMT_SHIFT 12
-#define CCDC_VP2SDR_DISABLE 0xFFFBFFFF
-#define CCDC_WEN_ENABLE (1 << 17)
-#define CCDC_SDR2RSZ_DISABLE 0xFFF7FFFF
-#define CCDC_VDHDEN_ENABLE (1 << 16)
-#define CCDC_LPF_ENABLE (1 << 14)
-#define CCDC_ALAW_ENABLE (1 << 3)
-#define CCDC_ALAW_GAMA_WD_MASK 7
-#define CCDC_BLK_CLAMP_ENABLE (1 << 31)
-#define CCDC_BLK_SGAIN_MASK 0x1F
-#define CCDC_BLK_ST_PXL_MASK 0x7FFF
-#define CCDC_BLK_ST_PXL_SHIFT 10
-#define CCDC_BLK_SAMPLE_LN_MASK 7
-#define CCDC_BLK_SAMPLE_LN_SHIFT 28
-#define CCDC_BLK_SAMPLE_LINE_MASK 7
-#define CCDC_BLK_SAMPLE_LINE_SHIFT 25
-#define CCDC_BLK_DC_SUB_MASK 0x03FFF
-#define CCDC_BLK_COMP_MASK 0xFF
-#define CCDC_BLK_COMP_GB_COMP_SHIFT 8
-#define CCDC_BLK_COMP_GR_COMP_SHIFT 16
-#define CCDC_BLK_COMP_R_COMP_SHIFT 24
-#define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15)
-#define CCDC_FPC_ENABLE (1 << 15)
-#define CCDC_FPC_DISABLE 0
-#define CCDC_FPC_FPC_NUM_MASK 0x7FFF
-#define CCDC_DATA_PACK_ENABLE (1 << 11)
-#define CCDC_FMTCFG_VPIN_MASK 7
-#define CCDC_FMTCFG_VPIN_SHIFT 12
-#define CCDC_FMT_HORZ_FMTLNH_MASK 0x1FFF
-#define CCDC_FMT_HORZ_FMTSPH_MASK 0x1FFF
-#define CCDC_FMT_HORZ_FMTSPH_SHIFT 16
-#define CCDC_FMT_VERT_FMTLNV_MASK 0x1FFF
-#define CCDC_FMT_VERT_FMTSLV_MASK 0x1FFF
-#define CCDC_FMT_VERT_FMTSLV_SHIFT 16
-#define CCDC_VP_OUT_VERT_NUM_MASK 0x3FFF
-#define CCDC_VP_OUT_VERT_NUM_SHIFT 17
-#define CCDC_VP_OUT_HORZ_NUM_MASK 0x1FFF
-#define CCDC_VP_OUT_HORZ_NUM_SHIFT 4
-#define CCDC_VP_OUT_HORZ_ST_MASK 0xF
-#define CCDC_HORZ_INFO_SPH_SHIFT 16
-#define CCDC_VERT_START_SLV0_SHIFT 16
-#define CCDC_VDINT_VDINT0_SHIFT 16
-#define CCDC_VDINT_VDINT1_MASK 0xFFFF
-#define CCDC_PPC_RAW 1
-#define CCDC_DCSUB_DEFAULT_VAL 0
-#define CCDC_CLAMP_DEFAULT_VAL 0
-#define CCDC_ENABLE_VIDEO_PORT 0x8000
-#define CCDC_DISABLE_VIDEO_PORT 0
-#define CCDC_COLPTN_VAL 0xBB11BB11
-#define CCDC_TWO_BYTES_PER_PIXEL 2
-#define CCDC_INTERLACED_IMAGE_INVERT 0x4B6D
-#define CCDC_INTERLACED_NO_IMAGE_INVERT 0x0249
-#define CCDC_PROGRESSIVE_IMAGE_INVERT 0x4000
-#define CCDC_PROGRESSIVE_NO_IMAGE_INVERT 0
-#define CCDC_INTERLACED_HEIGHT_SHIFT 1
-#define CCDC_SYN_MODE_INPMOD_SHIFT 12
-#define CCDC_SYN_MODE_INPMOD_MASK 3
-#define CCDC_SYN_MODE_8BITS (7 << 8)
-#define CCDC_SYN_MODE_10BITS (6 << 8)
-#define CCDC_SYN_MODE_11BITS (5 << 8)
-#define CCDC_SYN_MODE_12BITS (4 << 8)
-#define CCDC_SYN_MODE_13BITS (3 << 8)
-#define CCDC_SYN_MODE_14BITS (2 << 8)
-#define CCDC_SYN_MODE_15BITS (1 << 8)
-#define CCDC_SYN_MODE_16BITS (0 << 8)
-#define CCDC_SYN_FLDMODE_MASK 1
-#define CCDC_SYN_FLDMODE_SHIFT 7
-#define CCDC_REC656IF_BT656_EN 3
-#define CCDC_SYN_MODE_VD_POL_NEGATIVE (1 << 2)
-#define CCDC_CCDCFG_Y8POS_SHIFT 11
-#define CCDC_CCDCFG_BW656_10BIT (1 << 5)
-#define CCDC_SDOFST_FIELD_INTERLEAVED 0x249
-#define CCDC_NO_CULLING 0xffff00ff
-#endif
diff --git a/drivers/media/video/davinci/isif.c b/drivers/media/video/davinci/isif.c
deleted file mode 100644
index 5278fe7d6d0..00000000000
--- a/drivers/media/video/davinci/isif.c
+++ /dev/null
@@ -1,1162 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Image Sensor Interface (ISIF) driver
- *
- * This driver is for configuring the ISIF IP available on DM365 or any other
- * TI SoCs. This is used for capturing yuv or bayer video or image data
- * from a decoder or sensor. This IP is similar to the CCDC IP on DM355
- * and DM6446, but with enhanced or additional ip blocks. The driver
- * configures the ISIF upon commands from the vpfe bridge driver through
- * ccdc_hw_device interface.
- *
- * TODO: 1) Raw bayer parameter settings and bayer capture
- * 2) Add support for control ioctl
- */
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
-#include <linux/videodev2.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/module.h>
-
-#include <mach/mux.h>
-
-#include <media/davinci/isif.h>
-#include <media/davinci/vpss.h>
-
-#include "isif_regs.h"
-#include "ccdc_hw_device.h"
-
-/* Defaults for module configuration parameters */
-static struct isif_config_params_raw isif_config_defaults = {
- .linearize = {
- .en = 0,
- .corr_shft = ISIF_NO_SHIFT,
- .scale_fact = {1, 0},
- },
- .df_csc = {
- .df_or_csc = 0,
- .csc = {
- .en = 0,
- },
- },
- .dfc = {
- .en = 0,
- },
- .bclamp = {
- .en = 0,
- },
- .gain_offset = {
- .gain = {
- .r_ye = {1, 0},
- .gr_cy = {1, 0},
- .gb_g = {1, 0},
- .b_mg = {1, 0},
- },
- },
- .culling = {
- .hcpat_odd = 0xff,
- .hcpat_even = 0xff,
- .vcpat = 0xff,
- },
- .compress = {
- .alg = ISIF_ALAW,
- },
-};
-
-/* ISIF operation configuration */
-static struct isif_oper_config {
- struct device *dev;
- enum vpfe_hw_if_type if_type;
- struct isif_ycbcr_config ycbcr;
- struct isif_params_raw bayer;
- enum isif_data_pack data_pack;
- /* Master clock */
- struct clk *mclk;
- /* ISIF base address */
- void __iomem *base_addr;
- /* ISIF Linear Table 0 */
- void __iomem *linear_tbl0_addr;
- /* ISIF Linear Table 1 */
- void __iomem *linear_tbl1_addr;
-} isif_cfg = {
- .ycbcr = {
- .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
- .frm_fmt = CCDC_FRMFMT_INTERLACED,
- .win = ISIF_WIN_NTSC,
- .fid_pol = VPFE_PINPOL_POSITIVE,
- .vd_pol = VPFE_PINPOL_POSITIVE,
- .hd_pol = VPFE_PINPOL_POSITIVE,
- .pix_order = CCDC_PIXORDER_CBYCRY,
- .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED,
- },
- .bayer = {
- .pix_fmt = CCDC_PIXFMT_RAW,
- .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
- .win = ISIF_WIN_VGA,
- .fid_pol = VPFE_PINPOL_POSITIVE,
- .vd_pol = VPFE_PINPOL_POSITIVE,
- .hd_pol = VPFE_PINPOL_POSITIVE,
- .gain = {
- .r_ye = {1, 0},
- .gr_cy = {1, 0},
- .gb_g = {1, 0},
- .b_mg = {1, 0},
- },
- .cfa_pat = ISIF_CFA_PAT_MOSAIC,
- .data_msb = ISIF_BIT_MSB_11,
- .config_params = {
- .data_shift = ISIF_NO_SHIFT,
- .col_pat_field0 = {
- .olop = ISIF_GREEN_BLUE,
- .olep = ISIF_BLUE,
- .elop = ISIF_RED,
- .elep = ISIF_GREEN_RED,
- },
- .col_pat_field1 = {
- .olop = ISIF_GREEN_BLUE,
- .olep = ISIF_BLUE,
- .elop = ISIF_RED,
- .elep = ISIF_GREEN_RED,
- },
- .test_pat_gen = 0,
- },
- },
- .data_pack = ISIF_DATA_PACK8,
-};
-
-/* Raw Bayer formats */
-static const u32 isif_raw_bayer_pix_formats[] = {
- V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
-
-/* Raw YUV formats */
-static const u32 isif_raw_yuv_pix_formats[] = {
- V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
-
-/* register access routines */
-static inline u32 regr(u32 offset)
-{
- return __raw_readl(isif_cfg.base_addr + offset);
-}
-
-static inline void regw(u32 val, u32 offset)
-{
- __raw_writel(val, isif_cfg.base_addr + offset);
-}
-
-/* reg_modify() - read, modify and write register */
-static inline u32 reg_modify(u32 mask, u32 val, u32 offset)
-{
- u32 new_val = (regr(offset) & ~mask) | (val & mask);
-
- regw(new_val, offset);
- return new_val;
-}
-
-static inline void regw_lin_tbl(u32 val, u32 offset, int i)
-{
- if (!i)
- __raw_writel(val, isif_cfg.linear_tbl0_addr + offset);
- else
- __raw_writel(val, isif_cfg.linear_tbl1_addr + offset);
-}
-
-static void isif_disable_all_modules(void)
-{
- /* disable BC */
- regw(0, CLAMPCFG);
- /* disable vdfc */
- regw(0, DFCCTL);
- /* disable CSC */
- regw(0, CSCCTL);
- /* disable linearization */
- regw(0, LINCFG0);
- /* disable other modules here as they are supported */
-}
-
-static void isif_enable(int en)
-{
- if (!en) {
- /* Before disable isif, disable all ISIF modules */
- isif_disable_all_modules();
- /*
- * wait for next VD. Assume lowest scan rate is 12 Hz. So
- * 100 msec delay is good enough
- */
- msleep(100);
- }
- reg_modify(ISIF_SYNCEN_VDHDEN_MASK, en, SYNCEN);
-}
-
-static void isif_enable_output_to_sdram(int en)
-{
- reg_modify(ISIF_SYNCEN_WEN_MASK, en << ISIF_SYNCEN_WEN_SHIFT, SYNCEN);
-}
-
-static void isif_config_culling(struct isif_cul *cul)
-{
- u32 val;
-
- /* Horizontal pattern */
- val = (cul->hcpat_even << CULL_PAT_EVEN_LINE_SHIFT) | cul->hcpat_odd;
- regw(val, CULH);
-
- /* vertical pattern */
- regw(cul->vcpat, CULV);
-
- /* LPF */
- reg_modify(ISIF_LPF_MASK << ISIF_LPF_SHIFT,
- cul->en_lpf << ISIF_LPF_SHIFT, MODESET);
-}
-
-static void isif_config_gain_offset(void)
-{
- struct isif_gain_offsets_adj *gain_off_p =
- &isif_cfg.bayer.config_params.gain_offset;
- u32 val;
-
- val = (!!gain_off_p->gain_sdram_en << GAIN_SDRAM_EN_SHIFT) |
- (!!gain_off_p->gain_ipipe_en << GAIN_IPIPE_EN_SHIFT) |
- (!!gain_off_p->gain_h3a_en << GAIN_H3A_EN_SHIFT) |
- (!!gain_off_p->offset_sdram_en << OFST_SDRAM_EN_SHIFT) |
- (!!gain_off_p->offset_ipipe_en << OFST_IPIPE_EN_SHIFT) |
- (!!gain_off_p->offset_h3a_en << OFST_H3A_EN_SHIFT);
-
- reg_modify(GAIN_OFFSET_EN_MASK, val, CGAMMAWD);
-
- val = (gain_off_p->gain.r_ye.integer << GAIN_INTEGER_SHIFT) |
- gain_off_p->gain.r_ye.decimal;
- regw(val, CRGAIN);
-
- val = (gain_off_p->gain.gr_cy.integer << GAIN_INTEGER_SHIFT) |
- gain_off_p->gain.gr_cy.decimal;
- regw(val, CGRGAIN);
-
- val = (gain_off_p->gain.gb_g.integer << GAIN_INTEGER_SHIFT) |
- gain_off_p->gain.gb_g.decimal;
- regw(val, CGBGAIN);
-
- val = (gain_off_p->gain.b_mg.integer << GAIN_INTEGER_SHIFT) |
- gain_off_p->gain.b_mg.decimal;
- regw(val, CBGAIN);
-
- regw(gain_off_p->offset, COFSTA);
-}
-
-static void isif_restore_defaults(void)
-{
- enum vpss_ccdc_source_sel source = VPSS_CCDCIN;
-
- dev_dbg(isif_cfg.dev, "\nstarting isif_restore_defaults...");
- isif_cfg.bayer.config_params = isif_config_defaults;
- /* Enable clock to ISIF, IPIPEIF and BL */
- vpss_enable_clock(VPSS_CCDC_CLOCK, 1);
- vpss_enable_clock(VPSS_IPIPEIF_CLOCK, 1);
- vpss_enable_clock(VPSS_BL_CLOCK, 1);
- /* Set default offset and gain */
- isif_config_gain_offset();
- vpss_select_ccdc_source(source);
- dev_dbg(isif_cfg.dev, "\nEnd of isif_restore_defaults...");
-}
-
-static int isif_open(struct device *device)
-{
- isif_restore_defaults();
- return 0;
-}
-
-/* This function will configure the window size to be capture in ISIF reg */
-static void isif_setwin(struct v4l2_rect *image_win,
- enum ccdc_frmfmt frm_fmt, int ppc)
-{
- int horz_start, horz_nr_pixels;
- int vert_start, vert_nr_lines;
- int mid_img = 0;
-
- dev_dbg(isif_cfg.dev, "\nStarting isif_setwin...");
- /*
- * ppc - per pixel count. indicates how many pixels per cell
- * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
- * raw capture this is 1
- */
- horz_start = image_win->left << (ppc - 1);
- horz_nr_pixels = ((image_win->width) << (ppc - 1)) - 1;
-
- /* Writing the horizontal info into the registers */
- regw(horz_start & START_PX_HOR_MASK, SPH);
- regw(horz_nr_pixels & NUM_PX_HOR_MASK, LNH);
- vert_start = image_win->top;
-
- if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
- vert_nr_lines = (image_win->height >> 1) - 1;
- vert_start >>= 1;
- /* To account for VD since line 0 doesn't have any data */
- vert_start += 1;
- } else {
- /* To account for VD since line 0 doesn't have any data */
- vert_start += 1;
- vert_nr_lines = image_win->height - 1;
- /* configure VDINT0 and VDINT1 */
- mid_img = vert_start + (image_win->height / 2);
- regw(mid_img, VDINT1);
- }
-
- regw(0, VDINT0);
- regw(vert_start & START_VER_ONE_MASK, SLV0);
- regw(vert_start & START_VER_TWO_MASK, SLV1);
- regw(vert_nr_lines & NUM_LINES_VER, LNV);
-}
-
-static void isif_config_bclamp(struct isif_black_clamp *bc)
-{
- u32 val;
-
- /*
- * DC Offset is always added to image data irrespective of bc enable
- * status
- */
- regw(bc->dc_offset, CLDCOFST);
-
- if (bc->en) {
- val = bc->bc_mode_color << ISIF_BC_MODE_COLOR_SHIFT;
-
- /* Enable BC and horizontal clamp caculation paramaters */
- val = val | 1 | (bc->horz.mode << ISIF_HORZ_BC_MODE_SHIFT);
-
- regw(val, CLAMPCFG);
-
- if (bc->horz.mode != ISIF_HORZ_BC_DISABLE) {
- /*
- * Window count for calculation
- * Base window selection
- * pixel limit
- * Horizontal size of window
- * vertical size of the window
- * Horizontal start position of the window
- * Vertical start position of the window
- */
- val = bc->horz.win_count_calc |
- ((!!bc->horz.base_win_sel_calc) <<
- ISIF_HORZ_BC_WIN_SEL_SHIFT) |
- ((!!bc->horz.clamp_pix_limit) <<
- ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
- (bc->horz.win_h_sz_calc <<
- ISIF_HORZ_BC_WIN_H_SIZE_SHIFT) |
- (bc->horz.win_v_sz_calc <<
- ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);
- regw(val, CLHWIN0);
-
- regw(bc->horz.win_start_h_calc, CLHWIN1);
- regw(bc->horz.win_start_v_calc, CLHWIN2);
- }
-
- /* vertical clamp caculation paramaters */
-
- /* Reset clamp value sel for previous line */
- val |=
- (bc->vert.reset_val_sel << ISIF_VERT_BC_RST_VAL_SEL_SHIFT) |
- (bc->vert.line_ave_coef << ISIF_VERT_BC_LINE_AVE_COEF_SHIFT);
- regw(val, CLVWIN0);
-
- /* Optical Black horizontal start position */
- regw(bc->vert.ob_start_h, CLVWIN1);
- /* Optical Black vertical start position */
- regw(bc->vert.ob_start_v, CLVWIN2);
- /* Optical Black vertical size for calculation */
- regw(bc->vert.ob_v_sz_calc, CLVWIN3);
- /* Vertical start position for BC subtraction */
- regw(bc->vert_start_sub, CLSV);
- }
-}
-
-static void isif_config_linearization(struct isif_linearize *linearize)
-{
- u32 val, i;
-
- if (!linearize->en) {
- regw(0, LINCFG0);
- return;
- }
-
- /* shift value for correction & enable linearization (set lsb) */
- val = (linearize->corr_shft << ISIF_LIN_CORRSFT_SHIFT) | 1;
- regw(val, LINCFG0);
-
- /* Scale factor */
- val = ((!!linearize->scale_fact.integer) <<
- ISIF_LIN_SCALE_FACT_INTEG_SHIFT) |
- linearize->scale_fact.decimal;
- regw(val, LINCFG1);
-
- for (i = 0; i < ISIF_LINEAR_TAB_SIZE; i++) {
- if (i % 2)
- regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 1);
- else
- regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 0);
- }
-}
-
-static int isif_config_dfc(struct isif_dfc *vdfc)
-{
- /* initialize retries to loop for max ~ 250 usec */
- u32 val, count, retries = loops_per_jiffy / (4000/HZ);
- int i;
-
- if (!vdfc->en)
- return 0;
-
- /* Correction mode */
- val = (vdfc->corr_mode << ISIF_VDFC_CORR_MOD_SHIFT);
-
- /* Correct whole line or partial */
- if (vdfc->corr_whole_line)
- val |= 1 << ISIF_VDFC_CORR_WHOLE_LN_SHIFT;
-
- /* level shift value */
- val |= vdfc->def_level_shift << ISIF_VDFC_LEVEL_SHFT_SHIFT;
-
- regw(val, DFCCTL);
-
- /* Defect saturation level */
- regw(vdfc->def_sat_level, VDFSATLV);
-
- regw(vdfc->table[0].pos_vert, DFCMEM0);
- regw(vdfc->table[0].pos_horz, DFCMEM1);
- if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
- vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
- regw(vdfc->table[0].level_at_pos, DFCMEM2);
- regw(vdfc->table[0].level_up_pixels, DFCMEM3);
- regw(vdfc->table[0].level_low_pixels, DFCMEM4);
- }
-
- /* set DFCMARST and set DFCMWR */
- val = regr(DFCMEMCTL) | (1 << ISIF_DFCMEMCTL_DFCMARST_SHIFT) | 1;
- regw(val, DFCMEMCTL);
-
- count = retries;
- while (count && (regr(DFCMEMCTL) & 0x1))
- count--;
-
- if (!count) {
- dev_dbg(isif_cfg.dev, "defect table write timeout !!!\n");
- return -1;
- }
-
- for (i = 1; i < vdfc->num_vdefects; i++) {
- regw(vdfc->table[i].pos_vert, DFCMEM0);
- regw(vdfc->table[i].pos_horz, DFCMEM1);
- if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
- vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
- regw(vdfc->table[i].level_at_pos, DFCMEM2);
- regw(vdfc->table[i].level_up_pixels, DFCMEM3);
- regw(vdfc->table[i].level_low_pixels, DFCMEM4);
- }
- val = regr(DFCMEMCTL);
- /* clear DFCMARST and set DFCMWR */
- val &= ~BIT(ISIF_DFCMEMCTL_DFCMARST_SHIFT);
- val |= 1;
- regw(val, DFCMEMCTL);
-
- count = retries;
- while (count && (regr(DFCMEMCTL) & 0x1))
- count--;
-
- if (!count) {
- dev_err(isif_cfg.dev,
- "defect table write timeout !!!\n");
- return -1;
- }
- }
- if (vdfc->num_vdefects < ISIF_VDFC_TABLE_SIZE) {
- /* Extra cycle needed */
- regw(0, DFCMEM0);
- regw(0x1FFF, DFCMEM1);
- regw(1, DFCMEMCTL);
- }
-
- /* enable VDFC */
- reg_modify((1 << ISIF_VDFC_EN_SHIFT), (1 << ISIF_VDFC_EN_SHIFT),
- DFCCTL);
- return 0;
-}
-
-static void isif_config_csc(struct isif_df_csc *df_csc)
-{
- u32 val1 = 0, val2 = 0, i;
-
- if (!df_csc->csc.en) {
- regw(0, CSCCTL);
- return;
- }
- for (i = 0; i < ISIF_CSC_NUM_COEFF; i++) {
- if ((i % 2) == 0) {
- /* CSCM - LSB */
- val1 = (df_csc->csc.coeff[i].integer <<
- ISIF_CSC_COEF_INTEG_SHIFT) |
- df_csc->csc.coeff[i].decimal;
- } else {
-
- /* CSCM - MSB */
- val2 = (df_csc->csc.coeff[i].integer <<
- ISIF_CSC_COEF_INTEG_SHIFT) |
- df_csc->csc.coeff[i].decimal;
- val2 <<= ISIF_CSCM_MSB_SHIFT;
- val2 |= val1;
- regw(val2, (CSCM0 + ((i - 1) << 1)));
- }
- }
-
- /* program the active area */
- regw(df_csc->start_pix, FMTSPH);
- /*
- * one extra pixel as required for CSC. Actually number of
- * pixel - 1 should be configured in this register. So we
- * need to subtract 1 before writing to FMTSPH, but we will
- * not do this since csc requires one extra pixel
- */
- regw(df_csc->num_pixels, FMTLNH);
- regw(df_csc->start_line, FMTSLV);
- /*
- * one extra line as required for CSC. See reason documented for
- * num_pixels
- */
- regw(df_csc->num_lines, FMTLNV);
-
- /* Enable CSC */
- regw(1, CSCCTL);
-}
-
-static int isif_config_raw(void)
-{
- struct isif_params_raw *params = &isif_cfg.bayer;
- struct isif_config_params_raw *module_params =
- &isif_cfg.bayer.config_params;
- struct vpss_pg_frame_size frame_size;
- struct vpss_sync_pol sync;
- u32 val;
-
- dev_dbg(isif_cfg.dev, "\nStarting isif_config_raw..\n");
-
- /*
- * Configure CCDCFG register:-
- * Set CCD Not to swap input since input is RAW data
- * Set FID detection function to Latch at V-Sync
- * Set WENLOG - isif valid area
- * Set TRGSEL
- * Set EXTRG
- * Packed to 8 or 16 bits
- */
-
- val = ISIF_YCINSWP_RAW | ISIF_CCDCFG_FIDMD_LATCH_VSYNC |
- ISIF_CCDCFG_WENLOG_AND | ISIF_CCDCFG_TRGSEL_WEN |
- ISIF_CCDCFG_EXTRG_DISABLE | isif_cfg.data_pack;
-
- dev_dbg(isif_cfg.dev, "Writing 0x%x to ...CCDCFG \n", val);
- regw(val, CCDCFG);
-
- /*
- * Configure the vertical sync polarity(MODESET.VDPOL)
- * Configure the horizontal sync polarity (MODESET.HDPOL)
- * Configure frame id polarity (MODESET.FLDPOL)
- * Configure data polarity
- * Configure External WEN Selection
- * Configure frame format(progressive or interlace)
- * Configure pixel format (Input mode)
- * Configure the data shift
- */
-
- val = ISIF_VDHDOUT_INPUT | (params->vd_pol << ISIF_VD_POL_SHIFT) |
- (params->hd_pol << ISIF_HD_POL_SHIFT) |
- (params->fid_pol << ISIF_FID_POL_SHIFT) |
- (ISIF_DATAPOL_NORMAL << ISIF_DATAPOL_SHIFT) |
- (ISIF_EXWEN_DISABLE << ISIF_EXWEN_SHIFT) |
- (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
- (params->pix_fmt << ISIF_INPUT_SHIFT) |
- (params->config_params.data_shift << ISIF_DATASFT_SHIFT);
-
- regw(val, MODESET);
- dev_dbg(isif_cfg.dev, "Writing 0x%x to MODESET...\n", val);
-
- /*
- * Configure GAMMAWD register
- * CFA pattern setting
- */
- val = params->cfa_pat << ISIF_GAMMAWD_CFA_SHIFT;
-
- /* Gamma msb */
- if (module_params->compress.alg == ISIF_ALAW)
- val |= ISIF_ALAW_ENABLE;
-
- val |= (params->data_msb << ISIF_ALAW_GAMA_WD_SHIFT);
- regw(val, CGAMMAWD);
-
- /* Configure DPCM compression settings */
- if (module_params->compress.alg == ISIF_DPCM) {
- val = BIT(ISIF_DPCM_EN_SHIFT) |
- (module_params->compress.pred <<
- ISIF_DPCM_PREDICTOR_SHIFT);
- }
-
- regw(val, MISC);
-
- /* Configure Gain & Offset */
- isif_config_gain_offset();
-
- /* Configure Color pattern */
- val = (params->config_params.col_pat_field0.olop) |
- (params->config_params.col_pat_field0.olep << 2) |
- (params->config_params.col_pat_field0.elop << 4) |
- (params->config_params.col_pat_field0.elep << 6) |
- (params->config_params.col_pat_field1.olop << 8) |
- (params->config_params.col_pat_field1.olep << 10) |
- (params->config_params.col_pat_field1.elop << 12) |
- (params->config_params.col_pat_field1.elep << 14);
- regw(val, CCOLP);
- dev_dbg(isif_cfg.dev, "Writing %x to CCOLP ...\n", val);
-
- /* Configure HSIZE register */
- val = (!!params->horz_flip_en) << ISIF_HSIZE_FLIP_SHIFT;
-
- /* calculate line offset in 32 bytes based on pack value */
- if (isif_cfg.data_pack == ISIF_PACK_8BIT)
- val |= ((params->win.width + 31) >> 5);
- else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
- val |= (((params->win.width +
- (params->win.width >> 2)) + 31) >> 5);
- else
- val |= (((params->win.width * 2) + 31) >> 5);
- regw(val, HSIZE);
-
- /* Configure SDOFST register */
- if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
- if (params->image_invert_en) {
- /* For interlace inverse mode */
- regw(0x4B6D, SDOFST);
- dev_dbg(isif_cfg.dev, "Writing 0x4B6D to SDOFST...\n");
- } else {
- /* For interlace non inverse mode */
- regw(0x0B6D, SDOFST);
- dev_dbg(isif_cfg.dev, "Writing 0x0B6D to SDOFST...\n");
- }
- } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
- if (params->image_invert_en) {
- /* For progressive inverse mode */
- regw(0x4000, SDOFST);
- dev_dbg(isif_cfg.dev, "Writing 0x4000 to SDOFST...\n");
- } else {
- /* For progressive non inverse mode */
- regw(0x0000, SDOFST);
- dev_dbg(isif_cfg.dev, "Writing 0x0000 to SDOFST...\n");
- }
- }
-
- /* Configure video window */
- isif_setwin(&params->win, params->frm_fmt, 1);
-
- /* Configure Black Clamp */
- isif_config_bclamp(&module_params->bclamp);
-
- /* Configure Vertical Defection Pixel Correction */
- if (isif_config_dfc(&module_params->dfc) < 0)
- return -EFAULT;
-
- if (!module_params->df_csc.df_or_csc)
- /* Configure Color Space Conversion */
- isif_config_csc(&module_params->df_csc);
-
- isif_config_linearization(&module_params->linearize);
-
- /* Configure Culling */
- isif_config_culling(&module_params->culling);
-
- /* Configure horizontal and vertical offsets(DFC,LSC,Gain) */
- regw(module_params->horz_offset, DATAHOFST);
- regw(module_params->vert_offset, DATAVOFST);
-
- /* Setup test pattern if enabled */
- if (params->config_params.test_pat_gen) {
- /* Use the HD/VD pol settings from user */
- sync.ccdpg_hdpol = params->hd_pol;
- sync.ccdpg_vdpol = params->vd_pol;
- dm365_vpss_set_sync_pol(sync);
- frame_size.hlpfr = isif_cfg.bayer.win.width;
- frame_size.pplen = isif_cfg.bayer.win.height;
- dm365_vpss_set_pg_frame_size(frame_size);
- vpss_select_ccdc_source(VPSS_PGLPBK);
- }
-
- dev_dbg(isif_cfg.dev, "\nEnd of isif_config_ycbcr...\n");
- return 0;
-}
-
-static int isif_set_buftype(enum ccdc_buftype buf_type)
-{
- if (isif_cfg.if_type == VPFE_RAW_BAYER)
- isif_cfg.bayer.buf_type = buf_type;
- else
- isif_cfg.ycbcr.buf_type = buf_type;
-
- return 0;
-
-}
-static enum ccdc_buftype isif_get_buftype(void)
-{
- if (isif_cfg.if_type == VPFE_RAW_BAYER)
- return isif_cfg.bayer.buf_type;
-
- return isif_cfg.ycbcr.buf_type;
-}
-
-static int isif_enum_pix(u32 *pix, int i)
-{
- int ret = -EINVAL;
-
- if (isif_cfg.if_type == VPFE_RAW_BAYER) {
- if (i < ARRAY_SIZE(isif_raw_bayer_pix_formats)) {
- *pix = isif_raw_bayer_pix_formats[i];
- ret = 0;
- }
- } else {
- if (i < ARRAY_SIZE(isif_raw_yuv_pix_formats)) {
- *pix = isif_raw_yuv_pix_formats[i];
- ret = 0;
- }
- }
-
- return ret;
-}
-
-static int isif_set_pixel_format(unsigned int pixfmt)
-{
- if (isif_cfg.if_type == VPFE_RAW_BAYER) {
- if (pixfmt == V4L2_PIX_FMT_SBGGR8) {
- if ((isif_cfg.bayer.config_params.compress.alg !=
- ISIF_ALAW) &&
- (isif_cfg.bayer.config_params.compress.alg !=
- ISIF_DPCM)) {
- dev_dbg(isif_cfg.dev,
- "Either configure A-Law or DPCM\n");
- return -EINVAL;
- }
- isif_cfg.data_pack = ISIF_PACK_8BIT;
- } else if (pixfmt == V4L2_PIX_FMT_SBGGR16) {
- isif_cfg.bayer.config_params.compress.alg =
- ISIF_NO_COMPRESSION;
- isif_cfg.data_pack = ISIF_PACK_16BIT;
- } else
- return -EINVAL;
- isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
- } else {
- if (pixfmt == V4L2_PIX_FMT_YUYV)
- isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
- else if (pixfmt == V4L2_PIX_FMT_UYVY)
- isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
- else
- return -EINVAL;
- isif_cfg.data_pack = ISIF_PACK_8BIT;
- }
- return 0;
-}
-
-static u32 isif_get_pixel_format(void)
-{
- u32 pixfmt;
-
- if (isif_cfg.if_type == VPFE_RAW_BAYER)
- if (isif_cfg.bayer.config_params.compress.alg == ISIF_ALAW ||
- isif_cfg.bayer.config_params.compress.alg == ISIF_DPCM)
- pixfmt = V4L2_PIX_FMT_SBGGR8;
- else
- pixfmt = V4L2_PIX_FMT_SBGGR16;
- else {
- if (isif_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
- pixfmt = V4L2_PIX_FMT_YUYV;
- else
- pixfmt = V4L2_PIX_FMT_UYVY;
- }
- return pixfmt;
-}
-
-static int isif_set_image_window(struct v4l2_rect *win)
-{
- if (isif_cfg.if_type == VPFE_RAW_BAYER) {
- isif_cfg.bayer.win.top = win->top;
- isif_cfg.bayer.win.left = win->left;
- isif_cfg.bayer.win.width = win->width;
- isif_cfg.bayer.win.height = win->height;
- } else {
- isif_cfg.ycbcr.win.top = win->top;
- isif_cfg.ycbcr.win.left = win->left;
- isif_cfg.ycbcr.win.width = win->width;
- isif_cfg.ycbcr.win.height = win->height;
- }
- return 0;
-}
-
-static void isif_get_image_window(struct v4l2_rect *win)
-{
- if (isif_cfg.if_type == VPFE_RAW_BAYER)
- *win = isif_cfg.bayer.win;
- else
- *win = isif_cfg.ycbcr.win;
-}
-
-static unsigned int isif_get_line_length(void)
-{
- unsigned int len;
-
- if (isif_cfg.if_type == VPFE_RAW_BAYER) {
- if (isif_cfg.data_pack == ISIF_PACK_8BIT)
- len = ((isif_cfg.bayer.win.width));
- else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
- len = (((isif_cfg.bayer.win.width * 2) +
- (isif_cfg.bayer.win.width >> 2)));
- else
- len = (((isif_cfg.bayer.win.width * 2)));
- } else
- len = (((isif_cfg.ycbcr.win.width * 2)));
- return ALIGN(len, 32);
-}
-
-static int isif_set_frame_format(enum ccdc_frmfmt frm_fmt)
-{
- if (isif_cfg.if_type == VPFE_RAW_BAYER)
- isif_cfg.bayer.frm_fmt = frm_fmt;
- else
- isif_cfg.ycbcr.frm_fmt = frm_fmt;
- return 0;
-}
-static enum ccdc_frmfmt isif_get_frame_format(void)
-{
- if (isif_cfg.if_type == VPFE_RAW_BAYER)
- return isif_cfg.bayer.frm_fmt;
- return isif_cfg.ycbcr.frm_fmt;
-}
-
-static int isif_getfid(void)
-{
- return (regr(MODESET) >> 15) & 0x1;
-}
-
-/* misc operations */
-static void isif_setfbaddr(unsigned long addr)
-{
- regw((addr >> 21) & 0x07ff, CADU);
- regw((addr >> 5) & 0x0ffff, CADL);
-}
-
-static int isif_set_hw_if_params(struct vpfe_hw_if_param *params)
-{
- isif_cfg.if_type = params->if_type;
-
- switch (params->if_type) {
- case VPFE_BT656:
- case VPFE_BT656_10BIT:
- case VPFE_YCBCR_SYNC_8:
- isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
- isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
- break;
- case VPFE_BT1120:
- case VPFE_YCBCR_SYNC_16:
- isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_16BIT;
- isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
- break;
- case VPFE_RAW_BAYER:
- isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
- break;
- default:
- dev_dbg(isif_cfg.dev, "Invalid interface type\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* This function will configure ISIF for YCbCr parameters. */
-static int isif_config_ycbcr(void)
-{
- struct isif_ycbcr_config *params = &isif_cfg.ycbcr;
- struct vpss_pg_frame_size frame_size;
- u32 modeset = 0, ccdcfg = 0;
- struct vpss_sync_pol sync;
-
- dev_dbg(isif_cfg.dev, "\nStarting isif_config_ycbcr...");
-
- /* configure pixel format or input mode */
- modeset = modeset | (params->pix_fmt << ISIF_INPUT_SHIFT) |
- (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
- (params->fid_pol << ISIF_FID_POL_SHIFT) |
- (params->hd_pol << ISIF_HD_POL_SHIFT) |
- (params->vd_pol << ISIF_VD_POL_SHIFT);
-
- /* pack the data to 8-bit ISIFCFG */
- switch (isif_cfg.if_type) {
- case VPFE_BT656:
- if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
- dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
- return -EINVAL;
- }
- modeset |= (VPFE_PINPOL_NEGATIVE << ISIF_VD_POL_SHIFT);
- regw(3, REC656IF);
- ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR;
- break;
- case VPFE_BT656_10BIT:
- if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
- dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
- return -EINVAL;
- }
- /* setup BT.656, embedded sync */
- regw(3, REC656IF);
- /* enable 10 bit mode in ccdcfg */
- ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR |
- ISIF_BW656_ENABLE;
- break;
- case VPFE_BT1120:
- if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
- dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
- return -EINVAL;
- }
- regw(3, REC656IF);
- break;
-
- case VPFE_YCBCR_SYNC_8:
- ccdcfg |= ISIF_DATA_PACK8;
- ccdcfg |= ISIF_YCINSWP_YCBCR;
- if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
- dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
- return -EINVAL;
- }
- break;
- case VPFE_YCBCR_SYNC_16:
- if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
- dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
- return -EINVAL;
- }
- break;
- default:
- /* should never come here */
- dev_dbg(isif_cfg.dev, "Invalid interface type\n");
- return -EINVAL;
- }
-
- regw(modeset, MODESET);
-
- /* Set up pix order */
- ccdcfg |= params->pix_order << ISIF_PIX_ORDER_SHIFT;
-
- regw(ccdcfg, CCDCFG);
-
- /* configure video window */
- if ((isif_cfg.if_type == VPFE_BT1120) ||
- (isif_cfg.if_type == VPFE_YCBCR_SYNC_16))
- isif_setwin(&params->win, params->frm_fmt, 1);
- else
- isif_setwin(&params->win, params->frm_fmt, 2);
-
- /*
- * configure the horizontal line offset
- * this is done by rounding up width to a multiple of 16 pixels
- * and multiply by two to account for y:cb:cr 4:2:2 data
- */
- regw(((((params->win.width * 2) + 31) & 0xffffffe0) >> 5), HSIZE);
-
- /* configure the memory line offset */
- if ((params->frm_fmt == CCDC_FRMFMT_INTERLACED) &&
- (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED))
- /* two fields are interleaved in memory */
- regw(0x00000249, SDOFST);
-
- /* Setup test pattern if enabled */
- if (isif_cfg.bayer.config_params.test_pat_gen) {
- sync.ccdpg_hdpol = params->hd_pol;
- sync.ccdpg_vdpol = params->vd_pol;
- dm365_vpss_set_sync_pol(sync);
- dm365_vpss_set_pg_frame_size(frame_size);
- }
- return 0;
-}
-
-static int isif_configure(void)
-{
- if (isif_cfg.if_type == VPFE_RAW_BAYER)
- return isif_config_raw();
- return isif_config_ycbcr();
-}
-
-static int isif_close(struct device *device)
-{
- /* copy defaults to module params */
- isif_cfg.bayer.config_params = isif_config_defaults;
- return 0;
-}
-
-static struct ccdc_hw_device isif_hw_dev = {
- .name = "ISIF",
- .owner = THIS_MODULE,
- .hw_ops = {
- .open = isif_open,
- .close = isif_close,
- .enable = isif_enable,
- .enable_out_to_sdram = isif_enable_output_to_sdram,
- .set_hw_if_params = isif_set_hw_if_params,
- .configure = isif_configure,
- .set_buftype = isif_set_buftype,
- .get_buftype = isif_get_buftype,
- .enum_pix = isif_enum_pix,
- .set_pixel_format = isif_set_pixel_format,
- .get_pixel_format = isif_get_pixel_format,
- .set_frame_format = isif_set_frame_format,
- .get_frame_format = isif_get_frame_format,
- .set_image_window = isif_set_image_window,
- .get_image_window = isif_get_image_window,
- .get_line_length = isif_get_line_length,
- .setfbaddr = isif_setfbaddr,
- .getfid = isif_getfid,
- },
-};
-
-static int __init isif_probe(struct platform_device *pdev)
-{
- void (*setup_pinmux)(void);
- struct resource *res;
- void *__iomem addr;
- int status = 0, i;
-
- /*
- * first try to register with vpfe. If not correct platform, then we
- * don't have to iomap
- */
- status = vpfe_register_ccdc_device(&isif_hw_dev);
- if (status < 0)
- return status;
-
- /* Get and enable Master clock */
- isif_cfg.mclk = clk_get(&pdev->dev, "master");
- if (IS_ERR(isif_cfg.mclk)) {
- status = PTR_ERR(isif_cfg.mclk);
- goto fail_mclk;
- }
- if (clk_enable(isif_cfg.mclk)) {
- status = -ENODEV;
- goto fail_mclk;
- }
-
- /* Platform data holds setup_pinmux function ptr */
- if (NULL == pdev->dev.platform_data) {
- status = -ENODEV;
- goto fail_mclk;
- }
- setup_pinmux = pdev->dev.platform_data;
- /*
- * setup Mux configuration for ccdc which may be different for
- * different SoCs using this CCDC
- */
- setup_pinmux();
-
- i = 0;
- /* Get the ISIF base address, linearization table0 and table1 addr. */
- while (i < 3) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, i);
- if (!res) {
- status = -ENODEV;
- goto fail_nobase_res;
- }
- res = request_mem_region(res->start, resource_size(res),
- res->name);
- if (!res) {
- status = -EBUSY;
- goto fail_nobase_res;
- }
- addr = ioremap_nocache(res->start, resource_size(res));
- if (!addr) {
- status = -ENOMEM;
- goto fail_base_iomap;
- }
- switch (i) {
- case 0:
- /* ISIF base address */
- isif_cfg.base_addr = addr;
- break;
- case 1:
- /* ISIF linear tbl0 address */
- isif_cfg.linear_tbl0_addr = addr;
- break;
- default:
- /* ISIF linear tbl0 address */
- isif_cfg.linear_tbl1_addr = addr;
- break;
- }
- i++;
- }
- isif_cfg.dev = &pdev->dev;
-
- printk(KERN_NOTICE "%s is registered with vpfe.\n",
- isif_hw_dev.name);
- return 0;
-fail_base_iomap:
- release_mem_region(res->start, resource_size(res));
- i--;
-fail_nobase_res:
- if (isif_cfg.base_addr)
- iounmap(isif_cfg.base_addr);
- if (isif_cfg.linear_tbl0_addr)
- iounmap(isif_cfg.linear_tbl0_addr);
-
- while (i >= 0) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, i);
- release_mem_region(res->start, resource_size(res));
- i--;
- }
-fail_mclk:
- clk_put(isif_cfg.mclk);
- vpfe_unregister_ccdc_device(&isif_hw_dev);
- return status;
-}
-
-static int isif_remove(struct platform_device *pdev)
-{
- struct resource *res;
- int i = 0;
-
- iounmap(isif_cfg.base_addr);
- iounmap(isif_cfg.linear_tbl0_addr);
- iounmap(isif_cfg.linear_tbl1_addr);
- while (i < 3) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, i);
- if (res)
- release_mem_region(res->start, resource_size(res));
- i++;
- }
- vpfe_unregister_ccdc_device(&isif_hw_dev);
- return 0;
-}
-
-static struct platform_driver isif_driver = {
- .driver = {
- .name = "isif",
- .owner = THIS_MODULE,
- },
- .remove = __devexit_p(isif_remove),
- .probe = isif_probe,
-};
-
-module_platform_driver(isif_driver);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/davinci/isif_regs.h b/drivers/media/video/davinci/isif_regs.h
deleted file mode 100644
index aa69a463c12..00000000000
--- a/drivers/media/video/davinci/isif_regs.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef _ISIF_REGS_H
-#define _ISIF_REGS_H
-
-/* ISIF registers relative offsets */
-#define SYNCEN 0x00
-#define MODESET 0x04
-#define HDW 0x08
-#define VDW 0x0c
-#define PPLN 0x10
-#define LPFR 0x14
-#define SPH 0x18
-#define LNH 0x1c
-#define SLV0 0x20
-#define SLV1 0x24
-#define LNV 0x28
-#define CULH 0x2c
-#define CULV 0x30
-#define HSIZE 0x34
-#define SDOFST 0x38
-#define CADU 0x3c
-#define CADL 0x40
-#define LINCFG0 0x44
-#define LINCFG1 0x48
-#define CCOLP 0x4c
-#define CRGAIN 0x50
-#define CGRGAIN 0x54
-#define CGBGAIN 0x58
-#define CBGAIN 0x5c
-#define COFSTA 0x60
-#define FLSHCFG0 0x64
-#define FLSHCFG1 0x68
-#define FLSHCFG2 0x6c
-#define VDINT0 0x70
-#define VDINT1 0x74
-#define VDINT2 0x78
-#define MISC 0x7c
-#define CGAMMAWD 0x80
-#define REC656IF 0x84
-#define CCDCFG 0x88
-/*****************************************************
-* Defect Correction registers
-*****************************************************/
-#define DFCCTL 0x8c
-#define VDFSATLV 0x90
-#define DFCMEMCTL 0x94
-#define DFCMEM0 0x98
-#define DFCMEM1 0x9c
-#define DFCMEM2 0xa0
-#define DFCMEM3 0xa4
-#define DFCMEM4 0xa8
-/****************************************************
-* Black Clamp registers
-****************************************************/
-#define CLAMPCFG 0xac
-#define CLDCOFST 0xb0
-#define CLSV 0xb4
-#define CLHWIN0 0xb8
-#define CLHWIN1 0xbc
-#define CLHWIN2 0xc0
-#define CLVRV 0xc4
-#define CLVWIN0 0xc8
-#define CLVWIN1 0xcc
-#define CLVWIN2 0xd0
-#define CLVWIN3 0xd4
-/****************************************************
-* Lense Shading Correction
-****************************************************/
-#define DATAHOFST 0xd8
-#define DATAVOFST 0xdc
-#define LSCHVAL 0xe0
-#define LSCVVAL 0xe4
-#define TWODLSCCFG 0xe8
-#define TWODLSCOFST 0xec
-#define TWODLSCINI 0xf0
-#define TWODLSCGRBU 0xf4
-#define TWODLSCGRBL 0xf8
-#define TWODLSCGROF 0xfc
-#define TWODLSCORBU 0x100
-#define TWODLSCORBL 0x104
-#define TWODLSCOROF 0x108
-#define TWODLSCIRQEN 0x10c
-#define TWODLSCIRQST 0x110
-/****************************************************
-* Data formatter
-****************************************************/
-#define FMTCFG 0x114
-#define FMTPLEN 0x118
-#define FMTSPH 0x11c
-#define FMTLNH 0x120
-#define FMTSLV 0x124
-#define FMTLNV 0x128
-#define FMTRLEN 0x12c
-#define FMTHCNT 0x130
-#define FMTAPTR_BASE 0x134
-/* Below macro for addresses FMTAPTR0 - FMTAPTR15 */
-#define FMTAPTR(i) (FMTAPTR_BASE + (i * 4))
-#define FMTPGMVF0 0x174
-#define FMTPGMVF1 0x178
-#define FMTPGMAPU0 0x17c
-#define FMTPGMAPU1 0x180
-#define FMTPGMAPS0 0x184
-#define FMTPGMAPS1 0x188
-#define FMTPGMAPS2 0x18c
-#define FMTPGMAPS3 0x190
-#define FMTPGMAPS4 0x194
-#define FMTPGMAPS5 0x198
-#define FMTPGMAPS6 0x19c
-#define FMTPGMAPS7 0x1a0
-/************************************************
-* Color Space Converter
-************************************************/
-#define CSCCTL 0x1a4
-#define CSCM0 0x1a8
-#define CSCM1 0x1ac
-#define CSCM2 0x1b0
-#define CSCM3 0x1b4
-#define CSCM4 0x1b8
-#define CSCM5 0x1bc
-#define CSCM6 0x1c0
-#define CSCM7 0x1c4
-#define OBWIN0 0x1c8
-#define OBWIN1 0x1cc
-#define OBWIN2 0x1d0
-#define OBWIN3 0x1d4
-#define OBVAL0 0x1d8
-#define OBVAL1 0x1dc
-#define OBVAL2 0x1e0
-#define OBVAL3 0x1e4
-#define OBVAL4 0x1e8
-#define OBVAL5 0x1ec
-#define OBVAL6 0x1f0
-#define OBVAL7 0x1f4
-#define CLKCTL 0x1f8
-
-/* Masks & Shifts below */
-#define START_PX_HOR_MASK 0x7FFF
-#define NUM_PX_HOR_MASK 0x7FFF
-#define START_VER_ONE_MASK 0x7FFF
-#define START_VER_TWO_MASK 0x7FFF
-#define NUM_LINES_VER 0x7FFF
-
-/* gain - offset masks */
-#define GAIN_INTEGER_SHIFT 9
-#define OFFSET_MASK 0xFFF
-#define GAIN_SDRAM_EN_SHIFT 12
-#define GAIN_IPIPE_EN_SHIFT 13
-#define GAIN_H3A_EN_SHIFT 14
-#define OFST_SDRAM_EN_SHIFT 8
-#define OFST_IPIPE_EN_SHIFT 9
-#define OFST_H3A_EN_SHIFT 10
-#define GAIN_OFFSET_EN_MASK 0x7700
-
-/* Culling */
-#define CULL_PAT_EVEN_LINE_SHIFT 8
-
-/* CCDCFG register */
-#define ISIF_YCINSWP_RAW (0x00 << 4)
-#define ISIF_YCINSWP_YCBCR (0x01 << 4)
-#define ISIF_CCDCFG_FIDMD_LATCH_VSYNC (0x00 << 6)
-#define ISIF_CCDCFG_WENLOG_AND (0x00 << 8)
-#define ISIF_CCDCFG_TRGSEL_WEN (0x00 << 9)
-#define ISIF_CCDCFG_EXTRG_DISABLE (0x00 << 10)
-#define ISIF_LATCH_ON_VSYNC_DISABLE (0x01 << 15)
-#define ISIF_LATCH_ON_VSYNC_ENABLE (0x00 << 15)
-#define ISIF_DATA_PACK_MASK 3
-#define ISIF_DATA_PACK16 0
-#define ISIF_DATA_PACK12 1
-#define ISIF_DATA_PACK8 2
-#define ISIF_PIX_ORDER_SHIFT 11
-#define ISIF_BW656_ENABLE (0x01 << 5)
-
-/* MODESET registers */
-#define ISIF_VDHDOUT_INPUT (0x00 << 0)
-#define ISIF_INPUT_SHIFT 12
-#define ISIF_RAW_INPUT_MODE 0
-#define ISIF_FID_POL_SHIFT 4
-#define ISIF_HD_POL_SHIFT 3
-#define ISIF_VD_POL_SHIFT 2
-#define ISIF_DATAPOL_NORMAL 0
-#define ISIF_DATAPOL_SHIFT 6
-#define ISIF_EXWEN_DISABLE 0
-#define ISIF_EXWEN_SHIFT 5
-#define ISIF_FRM_FMT_SHIFT 7
-#define ISIF_DATASFT_SHIFT 8
-#define ISIF_LPF_SHIFT 14
-#define ISIF_LPF_MASK 1
-
-/* GAMMAWD registers */
-#define ISIF_ALAW_GAMA_WD_MASK 0xF
-#define ISIF_ALAW_GAMA_WD_SHIFT 1
-#define ISIF_ALAW_ENABLE 1
-#define ISIF_GAMMAWD_CFA_SHIFT 5
-
-/* HSIZE registers */
-#define ISIF_HSIZE_FLIP_MASK 1
-#define ISIF_HSIZE_FLIP_SHIFT 12
-
-/* MISC registers */
-#define ISIF_DPCM_EN_SHIFT 12
-#define ISIF_DPCM_PREDICTOR_SHIFT 13
-
-/* Black clamp related */
-#define ISIF_BC_MODE_COLOR_SHIFT 4
-#define ISIF_HORZ_BC_MODE_SHIFT 1
-#define ISIF_HORZ_BC_WIN_SEL_SHIFT 5
-#define ISIF_HORZ_BC_PIX_LIMIT_SHIFT 6
-#define ISIF_HORZ_BC_WIN_H_SIZE_SHIFT 8
-#define ISIF_HORZ_BC_WIN_V_SIZE_SHIFT 12
-#define ISIF_VERT_BC_RST_VAL_SEL_SHIFT 4
-#define ISIF_VERT_BC_LINE_AVE_COEF_SHIFT 8
-
-/* VDFC registers */
-#define ISIF_VDFC_EN_SHIFT 4
-#define ISIF_VDFC_CORR_MOD_SHIFT 5
-#define ISIF_VDFC_CORR_WHOLE_LN_SHIFT 7
-#define ISIF_VDFC_LEVEL_SHFT_SHIFT 8
-#define ISIF_VDFC_POS_MASK 0x1FFF
-#define ISIF_DFCMEMCTL_DFCMARST_SHIFT 2
-
-/* CSC registers */
-#define ISIF_CSC_COEF_INTEG_MASK 7
-#define ISIF_CSC_COEF_DECIMAL_MASK 0x1f
-#define ISIF_CSC_COEF_INTEG_SHIFT 5
-#define ISIF_CSCM_MSB_SHIFT 8
-#define ISIF_DF_CSC_SPH_MASK 0x1FFF
-#define ISIF_DF_CSC_LNH_MASK 0x1FFF
-#define ISIF_DF_CSC_SLV_MASK 0x1FFF
-#define ISIF_DF_CSC_LNV_MASK 0x1FFF
-#define ISIF_DF_NUMLINES 0x7FFF
-#define ISIF_DF_NUMPIX 0x1FFF
-
-/* Offsets for LSC/DFC/Gain */
-#define ISIF_DATA_H_OFFSET_MASK 0x1FFF
-#define ISIF_DATA_V_OFFSET_MASK 0x1FFF
-
-/* Linearization */
-#define ISIF_LIN_CORRSFT_SHIFT 4
-#define ISIF_LIN_SCALE_FACT_INTEG_SHIFT 10
-
-
-/* Pattern registers */
-#define ISIF_PG_EN (1 << 3)
-#define ISIF_SEL_PG_SRC (3 << 4)
-#define ISIF_PG_VD_POL_SHIFT 0
-#define ISIF_PG_HD_POL_SHIFT 1
-
-/*random other junk*/
-#define ISIF_SYNCEN_VDHDEN_MASK (1 << 0)
-#define ISIF_SYNCEN_WEN_MASK (1 << 1)
-#define ISIF_SYNCEN_WEN_SHIFT 1
-
-#endif
diff --git a/drivers/media/video/davinci/vpbe.c b/drivers/media/video/davinci/vpbe.c
deleted file mode 100644
index c4a82a1a8a9..00000000000
--- a/drivers/media/video/davinci/vpbe.c
+++ /dev/null
@@ -1,886 +0,0 @@
-/*
- * Copyright (C) 2010 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include <media/v4l2-device.h>
-#include <media/davinci/vpbe_types.h>
-#include <media/davinci/vpbe.h>
-#include <media/davinci/vpss.h>
-#include <media/davinci/vpbe_venc.h>
-
-#define VPBE_DEFAULT_OUTPUT "Composite"
-#define VPBE_DEFAULT_MODE "ntsc"
-
-static char *def_output = VPBE_DEFAULT_OUTPUT;
-static char *def_mode = VPBE_DEFAULT_MODE;
-static int debug;
-
-module_param(def_output, charp, S_IRUGO);
-module_param(def_mode, charp, S_IRUGO);
-module_param(debug, int, 0644);
-
-MODULE_PARM_DESC(def_output, "vpbe output name (default:Composite)");
-MODULE_PARM_DESC(def_mode, "vpbe output mode name (default:ntsc");
-MODULE_PARM_DESC(debug, "Debug level 0-1");
-
-MODULE_DESCRIPTION("TI DMXXX VPBE Display controller");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Texas Instruments");
-
-/**
- * vpbe_current_encoder_info - Get config info for current encoder
- * @vpbe_dev - vpbe device ptr
- *
- * Return ptr to current encoder config info
- */
-static struct encoder_config_info*
-vpbe_current_encoder_info(struct vpbe_device *vpbe_dev)
-{
- struct vpbe_config *cfg = vpbe_dev->cfg;
- int index = vpbe_dev->current_sd_index;
-
- return ((index == 0) ? &cfg->venc :
- &cfg->ext_encoders[index-1]);
-}
-
-/**
- * vpbe_find_encoder_sd_index - Given a name find encoder sd index
- *
- * @vpbe_config - ptr to vpbe cfg
- * @output_index - index used by application
- *
- * Return sd index of the encoder
- */
-static int vpbe_find_encoder_sd_index(struct vpbe_config *cfg,
- int index)
-{
- char *encoder_name = cfg->outputs[index].subdev_name;
- int i;
-
- /* Venc is always first */
- if (!strcmp(encoder_name, cfg->venc.module_name))
- return 0;
-
- for (i = 0; i < cfg->num_ext_encoders; i++) {
- if (!strcmp(encoder_name,
- cfg->ext_encoders[i].module_name))
- return i+1;
- }
-
- return -EINVAL;
-}
-
-/**
- * vpbe_g_cropcap - Get crop capabilities of the display
- * @vpbe_dev - vpbe device ptr
- * @cropcap - cropcap is a ptr to struct v4l2_cropcap
- *
- * Update the crop capabilities in crop cap for current
- * mode
- */
-static int vpbe_g_cropcap(struct vpbe_device *vpbe_dev,
- struct v4l2_cropcap *cropcap)
-{
- if (NULL == cropcap)
- return -EINVAL;
- cropcap->bounds.left = 0;
- cropcap->bounds.top = 0;
- cropcap->bounds.width = vpbe_dev->current_timings.xres;
- cropcap->bounds.height = vpbe_dev->current_timings.yres;
- cropcap->defrect = cropcap->bounds;
-
- return 0;
-}
-
-/**
- * vpbe_enum_outputs - enumerate outputs
- * @vpbe_dev - vpbe device ptr
- * @output - ptr to v4l2_output structure
- *
- * Enumerates the outputs available at the vpbe display
- * returns the status, -EINVAL if end of output list
- */
-static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev,
- struct v4l2_output *output)
-{
- struct vpbe_config *cfg = vpbe_dev->cfg;
- int temp_index = output->index;
-
- if (temp_index >= cfg->num_outputs)
- return -EINVAL;
-
- *output = cfg->outputs[temp_index].output;
- output->index = temp_index;
-
- return 0;
-}
-
-static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode,
- int output_index)
-{
- struct vpbe_config *cfg = vpbe_dev->cfg;
- struct vpbe_enc_mode_info var;
- int curr_output = output_index;
- int i;
-
- if (NULL == mode)
- return -EINVAL;
-
- for (i = 0; i < cfg->outputs[curr_output].num_modes; i++) {
- var = cfg->outputs[curr_output].modes[i];
- if (!strcmp(mode, var.name)) {
- vpbe_dev->current_timings = var;
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-static int vpbe_get_current_mode_info(struct vpbe_device *vpbe_dev,
- struct vpbe_enc_mode_info *mode_info)
-{
- if (NULL == mode_info)
- return -EINVAL;
-
- *mode_info = vpbe_dev->current_timings;
-
- return 0;
-}
-
-static int vpbe_get_dv_preset_info(struct vpbe_device *vpbe_dev,
- unsigned int dv_preset)
-{
- struct vpbe_config *cfg = vpbe_dev->cfg;
- struct vpbe_enc_mode_info var;
- int curr_output = vpbe_dev->current_out_index;
- int i;
-
- for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
- var = cfg->outputs[curr_output].modes[i];
- if ((var.timings_type & VPBE_ENC_DV_PRESET) &&
- (var.timings.dv_preset == dv_preset)) {
- vpbe_dev->current_timings = var;
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-/* Get std by std id */
-static int vpbe_get_std_info(struct vpbe_device *vpbe_dev,
- v4l2_std_id std_id)
-{
- struct vpbe_config *cfg = vpbe_dev->cfg;
- struct vpbe_enc_mode_info var;
- int curr_output = vpbe_dev->current_out_index;
- int i;
-
- for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
- var = cfg->outputs[curr_output].modes[i];
- if ((var.timings_type & VPBE_ENC_STD) &&
- (var.timings.std_id & std_id)) {
- vpbe_dev->current_timings = var;
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-static int vpbe_get_std_info_by_name(struct vpbe_device *vpbe_dev,
- char *std_name)
-{
- struct vpbe_config *cfg = vpbe_dev->cfg;
- struct vpbe_enc_mode_info var;
- int curr_output = vpbe_dev->current_out_index;
- int i;
-
- for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
- var = cfg->outputs[curr_output].modes[i];
- if (!strcmp(var.name, std_name)) {
- vpbe_dev->current_timings = var;
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-/**
- * vpbe_set_output - Set output
- * @vpbe_dev - vpbe device ptr
- * @index - index of output
- *
- * Set vpbe output to the output specified by the index
- */
-static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index)
-{
- struct encoder_config_info *curr_enc_info =
- vpbe_current_encoder_info(vpbe_dev);
- struct vpbe_config *cfg = vpbe_dev->cfg;
- struct venc_platform_data *venc_device = vpbe_dev->venc_device;
- enum v4l2_mbus_pixelcode if_params;
- int enc_out_index;
- int sd_index;
- int ret = 0;
-
- if (index >= cfg->num_outputs)
- return -EINVAL;
-
- mutex_lock(&vpbe_dev->lock);
-
- sd_index = vpbe_dev->current_sd_index;
- enc_out_index = cfg->outputs[index].output.index;
- /*
- * Currently we switch the encoder based on output selected
- * by the application. If media controller is implemented later
- * there is will be an API added to setup_link between venc
- * and external encoder. So in that case below comparison always
- * match and encoder will not be switched. But if application
- * chose not to use media controller, then this provides current
- * way of switching encoder at the venc output.
- */
- if (strcmp(curr_enc_info->module_name,
- cfg->outputs[index].subdev_name)) {
- /* Need to switch the encoder at the output */
- sd_index = vpbe_find_encoder_sd_index(cfg, index);
- if (sd_index < 0) {
- ret = -EINVAL;
- goto out;
- }
-
- if_params = cfg->outputs[index].if_params;
- venc_device->setup_if_config(if_params);
- if (ret)
- goto out;
- }
-
- /* Set output at the encoder */
- ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
- s_routing, 0, enc_out_index, 0);
- if (ret)
- goto out;
-
- /*
- * It is assumed that venc or extenal encoder will set a default
- * mode in the sub device. For external encoder or LCD pannel output,
- * we also need to set up the lcd port for the required mode. So setup
- * the lcd port for the default mode that is configured in the board
- * arch/arm/mach-davinci/board-dm355-evm.setup file for the external
- * encoder.
- */
- ret = vpbe_get_mode_info(vpbe_dev,
- cfg->outputs[index].default_mode, index);
- if (!ret) {
- struct osd_state *osd_device = vpbe_dev->osd_device;
-
- osd_device->ops.set_left_margin(osd_device,
- vpbe_dev->current_timings.left_margin);
- osd_device->ops.set_top_margin(osd_device,
- vpbe_dev->current_timings.upper_margin);
- vpbe_dev->current_sd_index = sd_index;
- vpbe_dev->current_out_index = index;
- }
-out:
- mutex_unlock(&vpbe_dev->lock);
- return ret;
-}
-
-static int vpbe_set_default_output(struct vpbe_device *vpbe_dev)
-{
- struct vpbe_config *cfg = vpbe_dev->cfg;
- int ret = 0;
- int i;
-
- for (i = 0; i < cfg->num_outputs; i++) {
- if (!strcmp(def_output,
- cfg->outputs[i].output.name)) {
- ret = vpbe_set_output(vpbe_dev, i);
- if (!ret)
- vpbe_dev->current_out_index = i;
- return ret;
- }
- }
- return ret;
-}
-
-/**
- * vpbe_get_output - Get output
- * @vpbe_dev - vpbe device ptr
- *
- * return current vpbe output to the the index
- */
-static unsigned int vpbe_get_output(struct vpbe_device *vpbe_dev)
-{
- return vpbe_dev->current_out_index;
-}
-
-/**
- * vpbe_s_dv_preset - Set the given preset timings in the encoder
- *
- * Sets the preset if supported by the current encoder. Return the status.
- * 0 - success & -EINVAL on error
- */
-static int vpbe_s_dv_preset(struct vpbe_device *vpbe_dev,
- struct v4l2_dv_preset *dv_preset)
-{
- struct vpbe_config *cfg = vpbe_dev->cfg;
- int out_index = vpbe_dev->current_out_index;
- int sd_index = vpbe_dev->current_sd_index;
- int ret;
-
-
- if (!(cfg->outputs[out_index].output.capabilities &
- V4L2_OUT_CAP_PRESETS))
- return -EINVAL;
-
- ret = vpbe_get_dv_preset_info(vpbe_dev, dv_preset->preset);
-
- if (ret)
- return ret;
-
- mutex_lock(&vpbe_dev->lock);
-
-
- ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
- s_dv_preset, dv_preset);
- if (!ret && (vpbe_dev->amp != NULL)) {
- /* Call amplifier subdevice */
- ret = v4l2_subdev_call(vpbe_dev->amp, video,
- s_dv_preset, dv_preset);
- }
- /* set the lcd controller output for the given mode */
- if (!ret) {
- struct osd_state *osd_device = vpbe_dev->osd_device;
-
- osd_device->ops.set_left_margin(osd_device,
- vpbe_dev->current_timings.left_margin);
- osd_device->ops.set_top_margin(osd_device,
- vpbe_dev->current_timings.upper_margin);
- }
- mutex_unlock(&vpbe_dev->lock);
-
- return ret;
-}
-
-/**
- * vpbe_g_dv_preset - Get the preset in the current encoder
- *
- * Get the preset in the current encoder. Return the status. 0 - success
- * -EINVAL on error
- */
-static int vpbe_g_dv_preset(struct vpbe_device *vpbe_dev,
- struct v4l2_dv_preset *dv_preset)
-{
- if (vpbe_dev->current_timings.timings_type &
- VPBE_ENC_DV_PRESET) {
- dv_preset->preset = vpbe_dev->current_timings.timings.dv_preset;
- return 0;
- }
-
- return -EINVAL;
-}
-
-/**
- * vpbe_enum_dv_presets - Enumerate the dv presets in the current encoder
- *
- * Get the preset in the current encoder. Return the status. 0 - success
- * -EINVAL on error
- */
-static int vpbe_enum_dv_presets(struct vpbe_device *vpbe_dev,
- struct v4l2_dv_enum_preset *preset_info)
-{
- struct vpbe_config *cfg = vpbe_dev->cfg;
- int out_index = vpbe_dev->current_out_index;
- struct vpbe_output *output = &cfg->outputs[out_index];
- int j = 0;
- int i;
-
- if (!(output->output.capabilities & V4L2_OUT_CAP_PRESETS))
- return -EINVAL;
-
- for (i = 0; i < output->num_modes; i++) {
- if (output->modes[i].timings_type == VPBE_ENC_DV_PRESET) {
- if (j == preset_info->index)
- break;
- j++;
- }
- }
-
- if (i == output->num_modes)
- return -EINVAL;
-
- return v4l_fill_dv_preset_info(output->modes[i].timings.dv_preset,
- preset_info);
-}
-
-/**
- * vpbe_s_std - Set the given standard in the encoder
- *
- * Sets the standard if supported by the current encoder. Return the status.
- * 0 - success & -EINVAL on error
- */
-static int vpbe_s_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
-{
- struct vpbe_config *cfg = vpbe_dev->cfg;
- int out_index = vpbe_dev->current_out_index;
- int sd_index = vpbe_dev->current_sd_index;
- int ret;
-
- if (!(cfg->outputs[out_index].output.capabilities &
- V4L2_OUT_CAP_STD))
- return -EINVAL;
-
- ret = vpbe_get_std_info(vpbe_dev, *std_id);
- if (ret)
- return ret;
-
- mutex_lock(&vpbe_dev->lock);
-
- ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
- s_std_output, *std_id);
- /* set the lcd controller output for the given mode */
- if (!ret) {
- struct osd_state *osd_device = vpbe_dev->osd_device;
-
- osd_device->ops.set_left_margin(osd_device,
- vpbe_dev->current_timings.left_margin);
- osd_device->ops.set_top_margin(osd_device,
- vpbe_dev->current_timings.upper_margin);
- }
- mutex_unlock(&vpbe_dev->lock);
-
- return ret;
-}
-
-/**
- * vpbe_g_std - Get the standard in the current encoder
- *
- * Get the standard in the current encoder. Return the status. 0 - success
- * -EINVAL on error
- */
-static int vpbe_g_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
-{
- struct vpbe_enc_mode_info cur_timings = vpbe_dev->current_timings;
-
- if (cur_timings.timings_type & VPBE_ENC_STD) {
- *std_id = cur_timings.timings.std_id;
- return 0;
- }
-
- return -EINVAL;
-}
-
-/**
- * vpbe_set_mode - Set mode in the current encoder using mode info
- *
- * Use the mode string to decide what timings to set in the encoder
- * This is typically useful when fbset command is used to change the current
- * timings by specifying a string to indicate the timings.
- */
-static int vpbe_set_mode(struct vpbe_device *vpbe_dev,
- struct vpbe_enc_mode_info *mode_info)
-{
- struct vpbe_enc_mode_info *preset_mode = NULL;
- struct vpbe_config *cfg = vpbe_dev->cfg;
- struct v4l2_dv_preset dv_preset;
- struct osd_state *osd_device;
- int out_index = vpbe_dev->current_out_index;
- int ret = 0;
- int i;
-
- if ((NULL == mode_info) || (NULL == mode_info->name))
- return -EINVAL;
-
- for (i = 0; i < cfg->outputs[out_index].num_modes; i++) {
- if (!strcmp(mode_info->name,
- cfg->outputs[out_index].modes[i].name)) {
- preset_mode = &cfg->outputs[out_index].modes[i];
- /*
- * it may be one of the 3 timings type. Check and
- * invoke right API
- */
- if (preset_mode->timings_type & VPBE_ENC_STD)
- return vpbe_s_std(vpbe_dev,
- &preset_mode->timings.std_id);
- if (preset_mode->timings_type & VPBE_ENC_DV_PRESET) {
- dv_preset.preset =
- preset_mode->timings.dv_preset;
- return vpbe_s_dv_preset(vpbe_dev, &dv_preset);
- }
- }
- }
-
- /* Only custom timing should reach here */
- if (preset_mode == NULL)
- return -EINVAL;
-
- mutex_lock(&vpbe_dev->lock);
-
- osd_device = vpbe_dev->osd_device;
- vpbe_dev->current_timings = *preset_mode;
- osd_device->ops.set_left_margin(osd_device,
- vpbe_dev->current_timings.left_margin);
- osd_device->ops.set_top_margin(osd_device,
- vpbe_dev->current_timings.upper_margin);
-
- mutex_unlock(&vpbe_dev->lock);
-
- return ret;
-}
-
-static int vpbe_set_default_mode(struct vpbe_device *vpbe_dev)
-{
- int ret;
-
- ret = vpbe_get_std_info_by_name(vpbe_dev, def_mode);
- if (ret)
- return ret;
-
- /* set the default mode in the encoder */
- return vpbe_set_mode(vpbe_dev, &vpbe_dev->current_timings);
-}
-
-static int platform_device_get(struct device *dev, void *data)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct vpbe_device *vpbe_dev = data;
-
- if (strcmp("vpbe-osd", pdev->name) == 0)
- vpbe_dev->osd_device = platform_get_drvdata(pdev);
- if (strcmp("vpbe-venc", pdev->name) == 0)
- vpbe_dev->venc_device = dev_get_platdata(&pdev->dev);
-
- return 0;
-}
-
-/**
- * vpbe_initialize() - Initialize the vpbe display controller
- * @vpbe_dev - vpbe device ptr
- *
- * Master frame buffer device drivers calls this to initialize vpbe
- * display controller. This will then registers v4l2 device and the sub
- * devices and sets a current encoder sub device for display. v4l2 display
- * device driver is the master and frame buffer display device driver is
- * the slave. Frame buffer display driver checks the initialized during
- * probe and exit if not initialized. Returns status.
- */
-static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
-{
- struct encoder_config_info *enc_info;
- struct amp_config_info *amp_info;
- struct v4l2_subdev **enc_subdev;
- struct osd_state *osd_device;
- struct i2c_adapter *i2c_adap;
- int output_index;
- int num_encoders;
- int ret = 0;
- int err;
- int i;
-
- /*
- * v4l2 abd FBDev frame buffer devices will get the vpbe_dev pointer
- * from the platform device by iteration of platform drivers and
- * matching with device name
- */
- if (NULL == vpbe_dev || NULL == dev) {
- printk(KERN_ERR "Null device pointers.\n");
- return -ENODEV;
- }
-
- if (vpbe_dev->initialized)
- return 0;
-
- mutex_lock(&vpbe_dev->lock);
-
- if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
- /* We have dac clock available for platform */
- vpbe_dev->dac_clk = clk_get(vpbe_dev->pdev, "vpss_dac");
- if (IS_ERR(vpbe_dev->dac_clk)) {
- ret = PTR_ERR(vpbe_dev->dac_clk);
- goto vpbe_unlock;
- }
- if (clk_enable(vpbe_dev->dac_clk)) {
- ret = -ENODEV;
- goto vpbe_unlock;
- }
- }
-
- /* first enable vpss clocks */
- vpss_enable_clock(VPSS_VPBE_CLOCK, 1);
-
- /* First register a v4l2 device */
- ret = v4l2_device_register(dev, &vpbe_dev->v4l2_dev);
- if (ret) {
- v4l2_err(dev->driver,
- "Unable to register v4l2 device.\n");
- goto vpbe_fail_clock;
- }
- v4l2_info(&vpbe_dev->v4l2_dev, "vpbe v4l2 device registered\n");
-
- err = bus_for_each_dev(&platform_bus_type, NULL, vpbe_dev,
- platform_device_get);
- if (err < 0)
- return err;
-
- vpbe_dev->venc = venc_sub_dev_init(&vpbe_dev->v4l2_dev,
- vpbe_dev->cfg->venc.module_name);
- /* register venc sub device */
- if (vpbe_dev->venc == NULL) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "vpbe unable to init venc sub device\n");
- ret = -ENODEV;
- goto vpbe_fail_v4l2_device;
- }
- /* initialize osd device */
- osd_device = vpbe_dev->osd_device;
-
- if (NULL != osd_device->ops.initialize) {
- err = osd_device->ops.initialize(osd_device);
- if (err) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "unable to initialize the OSD device");
- err = -ENOMEM;
- goto vpbe_fail_v4l2_device;
- }
- }
-
- /*
- * Register any external encoders that are configured. At index 0 we
- * store venc sd index.
- */
- num_encoders = vpbe_dev->cfg->num_ext_encoders + 1;
- vpbe_dev->encoders = kmalloc(
- sizeof(struct v4l2_subdev *)*num_encoders,
- GFP_KERNEL);
- if (NULL == vpbe_dev->encoders) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "unable to allocate memory for encoders sub devices");
- ret = -ENOMEM;
- goto vpbe_fail_v4l2_device;
- }
-
- i2c_adap = i2c_get_adapter(vpbe_dev->cfg->i2c_adapter_id);
- for (i = 0; i < (vpbe_dev->cfg->num_ext_encoders + 1); i++) {
- if (i == 0) {
- /* venc is at index 0 */
- enc_subdev = &vpbe_dev->encoders[i];
- *enc_subdev = vpbe_dev->venc;
- continue;
- }
- enc_info = &vpbe_dev->cfg->ext_encoders[i];
- if (enc_info->is_i2c) {
- enc_subdev = &vpbe_dev->encoders[i];
- *enc_subdev = v4l2_i2c_new_subdev_board(
- &vpbe_dev->v4l2_dev, i2c_adap,
- &enc_info->board_info, NULL);
- if (*enc_subdev)
- v4l2_info(&vpbe_dev->v4l2_dev,
- "v4l2 sub device %s registered\n",
- enc_info->module_name);
- else {
- v4l2_err(&vpbe_dev->v4l2_dev, "encoder %s"
- " failed to register",
- enc_info->module_name);
- ret = -ENODEV;
- goto vpbe_fail_sd_register;
- }
- } else
- v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders"
- " currently not supported");
- }
- /* Add amplifier subdevice for dm365 */
- if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) &&
- vpbe_dev->cfg->amp != NULL) {
- amp_info = vpbe_dev->cfg->amp;
- if (amp_info->is_i2c) {
- vpbe_dev->amp = v4l2_i2c_new_subdev_board(
- &vpbe_dev->v4l2_dev, i2c_adap,
- &amp_info->board_info, NULL);
- if (!vpbe_dev->amp) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "amplifier %s failed to register",
- amp_info->module_name);
- ret = -ENODEV;
- goto vpbe_fail_amp_register;
- }
- v4l2_info(&vpbe_dev->v4l2_dev,
- "v4l2 sub device %s registered\n",
- amp_info->module_name);
- } else {
- vpbe_dev->amp = NULL;
- v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers"
- " currently not supported");
- }
- } else {
- vpbe_dev->amp = NULL;
- }
-
- /* set the current encoder and output to that of venc by default */
- vpbe_dev->current_sd_index = 0;
- vpbe_dev->current_out_index = 0;
- output_index = 0;
-
- mutex_unlock(&vpbe_dev->lock);
-
- printk(KERN_NOTICE "Setting default output to %s\n", def_output);
- ret = vpbe_set_default_output(vpbe_dev);
- if (ret) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default output %s",
- def_output);
- return ret;
- }
-
- printk(KERN_NOTICE "Setting default mode to %s\n", def_mode);
- ret = vpbe_set_default_mode(vpbe_dev);
- if (ret) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default mode %s",
- def_mode);
- return ret;
- }
- vpbe_dev->initialized = 1;
- /* TBD handling of bootargs for default output and mode */
- return 0;
-
-vpbe_fail_amp_register:
- kfree(vpbe_dev->amp);
-vpbe_fail_sd_register:
- kfree(vpbe_dev->encoders);
-vpbe_fail_v4l2_device:
- v4l2_device_unregister(&vpbe_dev->v4l2_dev);
-vpbe_fail_clock:
- if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0)
- clk_put(vpbe_dev->dac_clk);
-vpbe_unlock:
- mutex_unlock(&vpbe_dev->lock);
- return ret;
-}
-
-/**
- * vpbe_deinitialize() - de-initialize the vpbe display controller
- * @dev - Master and slave device ptr
- *
- * vpbe_master and slave frame buffer devices calls this to de-initialize
- * the display controller. It is called when master and slave device
- * driver modules are removed and no longer requires the display controller.
- */
-static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev)
-{
- v4l2_device_unregister(&vpbe_dev->v4l2_dev);
- if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0)
- clk_put(vpbe_dev->dac_clk);
-
- kfree(vpbe_dev->amp);
- kfree(vpbe_dev->encoders);
- vpbe_dev->initialized = 0;
- /* disable vpss clocks */
- vpss_enable_clock(VPSS_VPBE_CLOCK, 0);
-}
-
-static struct vpbe_device_ops vpbe_dev_ops = {
- .g_cropcap = vpbe_g_cropcap,
- .enum_outputs = vpbe_enum_outputs,
- .set_output = vpbe_set_output,
- .get_output = vpbe_get_output,
- .s_dv_preset = vpbe_s_dv_preset,
- .g_dv_preset = vpbe_g_dv_preset,
- .enum_dv_presets = vpbe_enum_dv_presets,
- .s_std = vpbe_s_std,
- .g_std = vpbe_g_std,
- .initialize = vpbe_initialize,
- .deinitialize = vpbe_deinitialize,
- .get_mode_info = vpbe_get_current_mode_info,
- .set_mode = vpbe_set_mode,
-};
-
-static __devinit int vpbe_probe(struct platform_device *pdev)
-{
- struct vpbe_device *vpbe_dev;
- struct vpbe_config *cfg;
- int ret = -EINVAL;
-
- if (pdev->dev.platform_data == NULL) {
- v4l2_err(pdev->dev.driver, "No platform data\n");
- return -ENODEV;
- }
- cfg = pdev->dev.platform_data;
-
- if (!cfg->module_name[0] ||
- !cfg->osd.module_name[0] ||
- !cfg->venc.module_name[0]) {
- v4l2_err(pdev->dev.driver, "vpbe display module names not"
- " defined\n");
- return ret;
- }
-
- vpbe_dev = kzalloc(sizeof(*vpbe_dev), GFP_KERNEL);
- if (vpbe_dev == NULL) {
- v4l2_err(pdev->dev.driver, "Unable to allocate memory"
- " for vpbe_device\n");
- return -ENOMEM;
- }
- vpbe_dev->cfg = cfg;
- vpbe_dev->ops = vpbe_dev_ops;
- vpbe_dev->pdev = &pdev->dev;
-
- if (cfg->outputs->num_modes > 0)
- vpbe_dev->current_timings = vpbe_dev->cfg->outputs[0].modes[0];
- else {
- kfree(vpbe_dev);
- return -ENODEV;
- }
-
- /* set the driver data in platform device */
- platform_set_drvdata(pdev, vpbe_dev);
- mutex_init(&vpbe_dev->lock);
-
- return 0;
-}
-
-static int vpbe_remove(struct platform_device *device)
-{
- struct vpbe_device *vpbe_dev = platform_get_drvdata(device);
-
- kfree(vpbe_dev);
-
- return 0;
-}
-
-static struct platform_driver vpbe_driver = {
- .driver = {
- .name = "vpbe_controller",
- .owner = THIS_MODULE,
- },
- .probe = vpbe_probe,
- .remove = vpbe_remove,
-};
-
-module_platform_driver(vpbe_driver);
diff --git a/drivers/media/video/davinci/vpbe_display.c b/drivers/media/video/davinci/vpbe_display.c
deleted file mode 100644
index 6fe7034bea7..00000000000
--- a/drivers/media/video/davinci/vpbe_display.c
+++ /dev/null
@@ -1,1830 +0,0 @@
-/*
- * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/string.h>
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/mm.h>
-#include <linux/mutex.h>
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-
-#include <asm/pgtable.h>
-#include <mach/cputype.h>
-
-#include <media/v4l2-dev.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <media/davinci/vpbe_display.h>
-#include <media/davinci/vpbe_types.h>
-#include <media/davinci/vpbe.h>
-#include <media/davinci/vpbe_venc.h>
-#include <media/davinci/vpbe_osd.h>
-#include "vpbe_venc_regs.h"
-
-#define VPBE_DISPLAY_DRIVER "vpbe-v4l2"
-
-static int debug;
-
-#define VPBE_DEFAULT_NUM_BUFS 3
-
-module_param(debug, int, 0644);
-
-static int venc_is_second_field(struct vpbe_display *disp_dev)
-{
- struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
- int ret;
- int val;
-
- ret = v4l2_subdev_call(vpbe_dev->venc,
- core,
- ioctl,
- VENC_GET_FLD,
- &val);
- if (ret < 0) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "Error in getting Field ID 0\n");
- }
- return val;
-}
-
-static void vpbe_isr_even_field(struct vpbe_display *disp_obj,
- struct vpbe_layer *layer)
-{
- struct timespec timevalue;
-
- if (layer->cur_frm == layer->next_frm)
- return;
- ktime_get_ts(&timevalue);
- layer->cur_frm->ts.tv_sec = timevalue.tv_sec;
- layer->cur_frm->ts.tv_usec = timevalue.tv_nsec / NSEC_PER_USEC;
- layer->cur_frm->state = VIDEOBUF_DONE;
- wake_up_interruptible(&layer->cur_frm->done);
- /* Make cur_frm pointing to next_frm */
- layer->cur_frm = layer->next_frm;
-}
-
-static void vpbe_isr_odd_field(struct vpbe_display *disp_obj,
- struct vpbe_layer *layer)
-{
- struct osd_state *osd_device = disp_obj->osd_device;
- unsigned long addr;
-
- spin_lock(&disp_obj->dma_queue_lock);
- if (list_empty(&layer->dma_queue) ||
- (layer->cur_frm != layer->next_frm)) {
- spin_unlock(&disp_obj->dma_queue_lock);
- return;
- }
- /*
- * one field is displayed configure
- * the next frame if it is available
- * otherwise hold on current frame
- * Get next from the buffer queue
- */
- layer->next_frm = list_entry(
- layer->dma_queue.next,
- struct videobuf_buffer,
- queue);
- /* Remove that from the buffer queue */
- list_del(&layer->next_frm->queue);
- spin_unlock(&disp_obj->dma_queue_lock);
- /* Mark state of the frame to active */
- layer->next_frm->state = VIDEOBUF_ACTIVE;
- addr = videobuf_to_dma_contig(layer->next_frm);
- osd_device->ops.start_layer(osd_device,
- layer->layer_info.id,
- addr,
- disp_obj->cbcr_ofst);
-}
-
-/* interrupt service routine */
-static irqreturn_t venc_isr(int irq, void *arg)
-{
- struct vpbe_display *disp_dev = (struct vpbe_display *)arg;
- struct vpbe_layer *layer;
- static unsigned last_event;
- unsigned event = 0;
- int fid;
- int i;
-
- if ((NULL == arg) || (NULL == disp_dev->dev[0]))
- return IRQ_HANDLED;
-
- if (venc_is_second_field(disp_dev))
- event |= VENC_SECOND_FIELD;
- else
- event |= VENC_FIRST_FIELD;
-
- if (event == (last_event & ~VENC_END_OF_FRAME)) {
- /*
- * If the display is non-interlaced, then we need to flag the
- * end-of-frame event at every interrupt regardless of the
- * value of the FIDST bit. We can conclude that the display is
- * non-interlaced if the value of the FIDST bit is unchanged
- * from the previous interrupt.
- */
- event |= VENC_END_OF_FRAME;
- } else if (event == VENC_SECOND_FIELD) {
- /* end-of-frame for interlaced display */
- event |= VENC_END_OF_FRAME;
- }
- last_event = event;
-
- for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
- layer = disp_dev->dev[i];
- /* If streaming is started in this layer */
- if (!layer->started)
- continue;
-
- if (layer->layer_first_int) {
- layer->layer_first_int = 0;
- continue;
- }
- /* Check the field format */
- if ((V4L2_FIELD_NONE == layer->pix_fmt.field) &&
- (event & VENC_END_OF_FRAME)) {
- /* Progressive mode */
-
- vpbe_isr_even_field(disp_dev, layer);
- vpbe_isr_odd_field(disp_dev, layer);
- } else {
- /* Interlaced mode */
-
- layer->field_id ^= 1;
- if (event & VENC_FIRST_FIELD)
- fid = 0;
- else
- fid = 1;
-
- /*
- * If field id does not match with store
- * field id
- */
- if (fid != layer->field_id) {
- /* Make them in sync */
- layer->field_id = fid;
- continue;
- }
- /*
- * device field id and local field id are
- * in sync. If this is even field
- */
- if (0 == fid)
- vpbe_isr_even_field(disp_dev, layer);
- else /* odd field */
- vpbe_isr_odd_field(disp_dev, layer);
- }
- }
-
- return IRQ_HANDLED;
-}
-
-/*
- * vpbe_buffer_prepare()
- * This is the callback function called from videobuf_qbuf() function
- * the buffer is prepared and user space virtual address is converted into
- * physical address
- */
-static int vpbe_buffer_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct vpbe_fh *fh = q->priv_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- unsigned long addr;
- int ret;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "vpbe_buffer_prepare\n");
-
- /* If buffer is not initialized, initialize it */
- if (VIDEOBUF_NEEDS_INIT == vb->state) {
- vb->width = layer->pix_fmt.width;
- vb->height = layer->pix_fmt.height;
- vb->size = layer->pix_fmt.sizeimage;
- vb->field = field;
-
- ret = videobuf_iolock(q, vb, NULL);
- if (ret < 0) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Failed to map \
- user address\n");
- return -EINVAL;
- }
-
- addr = videobuf_to_dma_contig(vb);
-
- if (q->streaming) {
- if (!IS_ALIGNED(addr, 8)) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "buffer_prepare:offset is \
- not aligned to 32 bytes\n");
- return -EINVAL;
- }
- }
- vb->state = VIDEOBUF_PREPARED;
- }
- return 0;
-}
-
-/*
- * vpbe_buffer_setup()
- * This function allocates memory for the buffers
- */
-static int vpbe_buffer_setup(struct videobuf_queue *q,
- unsigned int *count,
- unsigned int *size)
-{
- /* Get the file handle object and layer object */
- struct vpbe_fh *fh = q->priv_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n");
-
- *size = layer->pix_fmt.sizeimage;
-
- /* Store number of buffers allocated in numbuffer member */
- if (*count < VPBE_DEFAULT_NUM_BUFS)
- *count = layer->numbuffers = VPBE_DEFAULT_NUM_BUFS;
-
- return 0;
-}
-
-/*
- * vpbe_buffer_queue()
- * This function adds the buffer to DMA queue
- */
-static void vpbe_buffer_queue(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- /* Get the file handle object and layer object */
- struct vpbe_fh *fh = q->priv_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_display *disp = fh->disp_dev;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- unsigned long flags;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "vpbe_buffer_queue\n");
-
- /* add the buffer to the DMA queue */
- spin_lock_irqsave(&disp->dma_queue_lock, flags);
- list_add_tail(&vb->queue, &layer->dma_queue);
- spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
- /* Change state of the buffer */
- vb->state = VIDEOBUF_QUEUED;
-}
-
-/*
- * vpbe_buffer_release()
- * This function is called from the videobuf layer to free memory allocated to
- * the buffers
- */
-static void vpbe_buffer_release(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- /* Get the file handle object and layer object */
- struct vpbe_fh *fh = q->priv_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "vpbe_buffer_release\n");
-
- if (V4L2_MEMORY_USERPTR != layer->memory)
- videobuf_dma_contig_free(q, vb);
-
- vb->state = VIDEOBUF_NEEDS_INIT;
-}
-
-static struct videobuf_queue_ops video_qops = {
- .buf_setup = vpbe_buffer_setup,
- .buf_prepare = vpbe_buffer_prepare,
- .buf_queue = vpbe_buffer_queue,
- .buf_release = vpbe_buffer_release,
-};
-
-static
-struct vpbe_layer*
-_vpbe_display_get_other_win_layer(struct vpbe_display *disp_dev,
- struct vpbe_layer *layer)
-{
- enum vpbe_display_device_id thiswin, otherwin;
- thiswin = layer->device_id;
-
- otherwin = (thiswin == VPBE_DISPLAY_DEVICE_0) ?
- VPBE_DISPLAY_DEVICE_1 : VPBE_DISPLAY_DEVICE_0;
- return disp_dev->dev[otherwin];
-}
-
-static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev,
- struct vpbe_layer *layer)
-{
- struct osd_layer_config *cfg = &layer->layer_info.config;
- struct osd_state *osd_device = disp_dev->osd_device;
- struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
- unsigned long addr;
- int ret;
-
- addr = videobuf_to_dma_contig(layer->cur_frm);
- /* Set address in the display registers */
- osd_device->ops.start_layer(osd_device,
- layer->layer_info.id,
- addr,
- disp_dev->cbcr_ofst);
-
- ret = osd_device->ops.enable_layer(osd_device,
- layer->layer_info.id, 0);
- if (ret < 0) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "Error in enabling osd window layer 0\n");
- return -1;
- }
-
- /* Enable the window */
- layer->layer_info.enable = 1;
- if (cfg->pixfmt == PIXFMT_NV12) {
- struct vpbe_layer *otherlayer =
- _vpbe_display_get_other_win_layer(disp_dev, layer);
-
- ret = osd_device->ops.enable_layer(osd_device,
- otherlayer->layer_info.id, 1);
- if (ret < 0) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "Error in enabling osd window layer 1\n");
- return -1;
- }
- otherlayer->layer_info.enable = 1;
- }
- return 0;
-}
-
-static void
-vpbe_disp_calculate_scale_factor(struct vpbe_display *disp_dev,
- struct vpbe_layer *layer,
- int expected_xsize, int expected_ysize)
-{
- struct display_layer_info *layer_info = &layer->layer_info;
- struct v4l2_pix_format *pixfmt = &layer->pix_fmt;
- struct osd_layer_config *cfg = &layer->layer_info.config;
- struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
- int calculated_xsize;
- int h_exp = 0;
- int v_exp = 0;
- int h_scale;
- int v_scale;
-
- v4l2_std_id standard_id = vpbe_dev->current_timings.timings.std_id;
-
- /*
- * Application initially set the image format. Current display
- * size is obtained from the vpbe display controller. expected_xsize
- * and expected_ysize are set through S_CROP ioctl. Based on this,
- * driver will calculate the scale factors for vertical and
- * horizontal direction so that the image is displayed scaled
- * and expanded. Application uses expansion to display the image
- * in a square pixel. Otherwise it is displayed using displays
- * pixel aspect ratio.It is expected that application chooses
- * the crop coordinates for cropped or scaled display. if crop
- * size is less than the image size, it is displayed cropped or
- * it is displayed scaled and/or expanded.
- *
- * to begin with, set the crop window same as expected. Later we
- * will override with scaled window size
- */
-
- cfg->xsize = pixfmt->width;
- cfg->ysize = pixfmt->height;
- layer_info->h_zoom = ZOOM_X1; /* no horizontal zoom */
- layer_info->v_zoom = ZOOM_X1; /* no horizontal zoom */
- layer_info->h_exp = H_EXP_OFF; /* no horizontal zoom */
- layer_info->v_exp = V_EXP_OFF; /* no horizontal zoom */
-
- if (pixfmt->width < expected_xsize) {
- h_scale = vpbe_dev->current_timings.xres / pixfmt->width;
- if (h_scale < 2)
- h_scale = 1;
- else if (h_scale >= 4)
- h_scale = 4;
- else
- h_scale = 2;
- cfg->xsize *= h_scale;
- if (cfg->xsize < expected_xsize) {
- if ((standard_id & V4L2_STD_525_60) ||
- (standard_id & V4L2_STD_625_50)) {
- calculated_xsize = (cfg->xsize *
- VPBE_DISPLAY_H_EXP_RATIO_N) /
- VPBE_DISPLAY_H_EXP_RATIO_D;
- if (calculated_xsize <= expected_xsize) {
- h_exp = 1;
- cfg->xsize = calculated_xsize;
- }
- }
- }
- if (h_scale == 2)
- layer_info->h_zoom = ZOOM_X2;
- else if (h_scale == 4)
- layer_info->h_zoom = ZOOM_X4;
- if (h_exp)
- layer_info->h_exp = H_EXP_9_OVER_8;
- } else {
- /* no scaling, only cropping. Set display area to crop area */
- cfg->xsize = expected_xsize;
- }
-
- if (pixfmt->height < expected_ysize) {
- v_scale = expected_ysize / pixfmt->height;
- if (v_scale < 2)
- v_scale = 1;
- else if (v_scale >= 4)
- v_scale = 4;
- else
- v_scale = 2;
- cfg->ysize *= v_scale;
- if (cfg->ysize < expected_ysize) {
- if ((standard_id & V4L2_STD_625_50)) {
- calculated_xsize = (cfg->ysize *
- VPBE_DISPLAY_V_EXP_RATIO_N) /
- VPBE_DISPLAY_V_EXP_RATIO_D;
- if (calculated_xsize <= expected_ysize) {
- v_exp = 1;
- cfg->ysize = calculated_xsize;
- }
- }
- }
- if (v_scale == 2)
- layer_info->v_zoom = ZOOM_X2;
- else if (v_scale == 4)
- layer_info->v_zoom = ZOOM_X4;
- if (v_exp)
- layer_info->h_exp = V_EXP_6_OVER_5;
- } else {
- /* no scaling, only cropping. Set display area to crop area */
- cfg->ysize = expected_ysize;
- }
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "crop display xsize = %d, ysize = %d\n",
- cfg->xsize, cfg->ysize);
-}
-
-static void vpbe_disp_adj_position(struct vpbe_display *disp_dev,
- struct vpbe_layer *layer,
- int top, int left)
-{
- struct osd_layer_config *cfg = &layer->layer_info.config;
- struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
-
- cfg->xpos = min((unsigned int)left,
- vpbe_dev->current_timings.xres - cfg->xsize);
- cfg->ypos = min((unsigned int)top,
- vpbe_dev->current_timings.yres - cfg->ysize);
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "new xpos = %d, ypos = %d\n",
- cfg->xpos, cfg->ypos);
-}
-
-static void vpbe_disp_check_window_params(struct vpbe_display *disp_dev,
- struct v4l2_rect *c)
-{
- struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
-
- if ((c->width == 0) ||
- ((c->width + c->left) > vpbe_dev->current_timings.xres))
- c->width = vpbe_dev->current_timings.xres - c->left;
-
- if ((c->height == 0) || ((c->height + c->top) >
- vpbe_dev->current_timings.yres))
- c->height = vpbe_dev->current_timings.yres - c->top;
-
- /* window height must be even for interlaced display */
- if (vpbe_dev->current_timings.interlaced)
- c->height &= (~0x01);
-
-}
-
-/**
- * vpbe_try_format()
- * If user application provides width and height, and have bytesperline set
- * to zero, driver calculates bytesperline and sizeimage based on hardware
- * limits.
- */
-static int vpbe_try_format(struct vpbe_display *disp_dev,
- struct v4l2_pix_format *pixfmt, int check)
-{
- struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
- int min_height = 1;
- int min_width = 32;
- int max_height;
- int max_width;
- int bpp;
-
- if ((pixfmt->pixelformat != V4L2_PIX_FMT_UYVY) &&
- (pixfmt->pixelformat != V4L2_PIX_FMT_NV12))
- /* choose default as V4L2_PIX_FMT_UYVY */
- pixfmt->pixelformat = V4L2_PIX_FMT_UYVY;
-
- /* Check the field format */
- if ((pixfmt->field != V4L2_FIELD_INTERLACED) &&
- (pixfmt->field != V4L2_FIELD_NONE)) {
- if (vpbe_dev->current_timings.interlaced)
- pixfmt->field = V4L2_FIELD_INTERLACED;
- else
- pixfmt->field = V4L2_FIELD_NONE;
- }
-
- if (pixfmt->field == V4L2_FIELD_INTERLACED)
- min_height = 2;
-
- if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
- bpp = 1;
- else
- bpp = 2;
-
- max_width = vpbe_dev->current_timings.xres;
- max_height = vpbe_dev->current_timings.yres;
-
- min_width /= bpp;
-
- if (!pixfmt->width || (pixfmt->width < min_width) ||
- (pixfmt->width > max_width)) {
- pixfmt->width = vpbe_dev->current_timings.xres;
- }
-
- if (!pixfmt->height || (pixfmt->height < min_height) ||
- (pixfmt->height > max_height)) {
- pixfmt->height = vpbe_dev->current_timings.yres;
- }
-
- if (pixfmt->bytesperline < (pixfmt->width * bpp))
- pixfmt->bytesperline = pixfmt->width * bpp;
-
- /* Make the bytesperline 32 byte aligned */
- pixfmt->bytesperline = ((pixfmt->width * bpp + 31) & ~31);
-
- if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
- pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height +
- (pixfmt->bytesperline * pixfmt->height >> 1);
- else
- pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
-
- return 0;
-}
-
-static int vpbe_display_g_priority(struct file *file, void *priv,
- enum v4l2_priority *p)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_layer *layer = fh->layer;
-
- *p = v4l2_prio_max(&layer->prio);
-
- return 0;
-}
-
-static int vpbe_display_s_priority(struct file *file, void *priv,
- enum v4l2_priority p)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_layer *layer = fh->layer;
- int ret;
-
- ret = v4l2_prio_change(&layer->prio, &fh->prio, p);
-
- return ret;
-}
-
-static int vpbe_display_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
- cap->version = VPBE_DISPLAY_VERSION_CODE;
- cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
- strlcpy(cap->driver, VPBE_DISPLAY_DRIVER, sizeof(cap->driver));
- strlcpy(cap->bus_info, "platform", sizeof(cap->bus_info));
- strlcpy(cap->card, vpbe_dev->cfg->module_name, sizeof(cap->card));
-
- return 0;
-}
-
-static int vpbe_display_s_crop(struct file *file, void *priv,
- struct v4l2_crop *crop)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_display *disp_dev = fh->disp_dev;
- struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
- struct osd_layer_config *cfg = &layer->layer_info.config;
- struct osd_state *osd_device = disp_dev->osd_device;
- struct v4l2_rect *rect = &crop->c;
- int ret;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "VIDIOC_S_CROP, layer id = %d\n", layer->device_id);
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buf type\n");
- return -EINVAL;
- }
-
- if (rect->top < 0)
- rect->top = 0;
- if (rect->left < 0)
- rect->left = 0;
-
- vpbe_disp_check_window_params(disp_dev, rect);
-
- osd_device->ops.get_layer_config(osd_device,
- layer->layer_info.id, cfg);
-
- vpbe_disp_calculate_scale_factor(disp_dev, layer,
- rect->width,
- rect->height);
- vpbe_disp_adj_position(disp_dev, layer, rect->top,
- rect->left);
- ret = osd_device->ops.set_layer_config(osd_device,
- layer->layer_info.id, cfg);
- if (ret < 0) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "Error in set layer config:\n");
- return -EINVAL;
- }
-
- /* apply zooming and h or v expansion */
- osd_device->ops.set_zoom(osd_device,
- layer->layer_info.id,
- layer->layer_info.h_zoom,
- layer->layer_info.v_zoom);
- ret = osd_device->ops.set_vid_expansion(osd_device,
- layer->layer_info.h_exp,
- layer->layer_info.v_exp);
- if (ret < 0) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "Error in set vid expansion:\n");
- return -EINVAL;
- }
-
- if ((layer->layer_info.h_zoom != ZOOM_X1) ||
- (layer->layer_info.v_zoom != ZOOM_X1) ||
- (layer->layer_info.h_exp != H_EXP_OFF) ||
- (layer->layer_info.v_exp != V_EXP_OFF))
- /* Enable expansion filter */
- osd_device->ops.set_interpolation_filter(osd_device, 1);
- else
- osd_device->ops.set_interpolation_filter(osd_device, 0);
-
- return 0;
-}
-
-static int vpbe_display_g_crop(struct file *file, void *priv,
- struct v4l2_crop *crop)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_layer *layer = fh->layer;
- struct osd_layer_config *cfg = &layer->layer_info.config;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- struct osd_state *osd_device = fh->disp_dev->osd_device;
- struct v4l2_rect *rect = &crop->c;
- int ret;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "VIDIOC_G_CROP, layer id = %d\n",
- layer->device_id);
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buf type\n");
- ret = -EINVAL;
- }
- osd_device->ops.get_layer_config(osd_device,
- layer->layer_info.id, cfg);
- rect->top = cfg->ypos;
- rect->left = cfg->xpos;
- rect->width = cfg->xsize;
- rect->height = cfg->ysize;
-
- return 0;
-}
-
-static int vpbe_display_cropcap(struct file *file, void *priv,
- struct v4l2_cropcap *cropcap)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_CROPCAP ioctl\n");
-
- cropcap->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- cropcap->bounds.left = 0;
- cropcap->bounds.top = 0;
- cropcap->bounds.width = vpbe_dev->current_timings.xres;
- cropcap->bounds.height = vpbe_dev->current_timings.yres;
- cropcap->pixelaspect = vpbe_dev->current_timings.aspect;
- cropcap->defrect = cropcap->bounds;
- return 0;
-}
-
-static int vpbe_display_g_fmt(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "VIDIOC_G_FMT, layer id = %d\n",
- layer->device_id);
-
- /* If buffer type is video output */
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
- v4l2_err(&vpbe_dev->v4l2_dev, "invalid type\n");
- return -EINVAL;
- }
- /* Fill in the information about format */
- fmt->fmt.pix = layer->pix_fmt;
-
- return 0;
-}
-
-static int vpbe_display_enum_fmt(struct file *file, void *priv,
- struct v4l2_fmtdesc *fmt)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- unsigned int index = 0;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "VIDIOC_ENUM_FMT, layer id = %d\n",
- layer->device_id);
- if (fmt->index > 1) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Invalid format index\n");
- return -EINVAL;
- }
-
- /* Fill in the information about format */
- index = fmt->index;
- memset(fmt, 0, sizeof(*fmt));
- fmt->index = index;
- fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- if (index == 0) {
- strcpy(fmt->description, "YUV 4:2:2 - UYVY");
- fmt->pixelformat = V4L2_PIX_FMT_UYVY;
- } else {
- strcpy(fmt->description, "Y/CbCr 4:2:0");
- fmt->pixelformat = V4L2_PIX_FMT_NV12;
- }
-
- return 0;
-}
-
-static int vpbe_display_s_fmt(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_display *disp_dev = fh->disp_dev;
- struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
- struct osd_layer_config *cfg = &layer->layer_info.config;
- struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
- struct osd_state *osd_device = disp_dev->osd_device;
- int ret;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "VIDIOC_S_FMT, layer id = %d\n",
- layer->device_id);
-
- /* If streaming is started, return error */
- if (layer->started) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
- return -EBUSY;
- }
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "invalid type\n");
- return -EINVAL;
- }
- /* Check for valid pixel format */
- ret = vpbe_try_format(disp_dev, pixfmt, 1);
- if (ret)
- return ret;
-
- /* YUV420 is requested, check availability of the
- other video window */
-
- layer->pix_fmt = *pixfmt;
-
- /* Get osd layer config */
- osd_device->ops.get_layer_config(osd_device,
- layer->layer_info.id, cfg);
- /* Store the pixel format in the layer object */
- cfg->xsize = pixfmt->width;
- cfg->ysize = pixfmt->height;
- cfg->line_length = pixfmt->bytesperline;
- cfg->ypos = 0;
- cfg->xpos = 0;
- cfg->interlaced = vpbe_dev->current_timings.interlaced;
-
- if (V4L2_PIX_FMT_UYVY == pixfmt->pixelformat)
- cfg->pixfmt = PIXFMT_YCbCrI;
-
- /* Change of the default pixel format for both video windows */
- if (V4L2_PIX_FMT_NV12 == pixfmt->pixelformat) {
- struct vpbe_layer *otherlayer;
- cfg->pixfmt = PIXFMT_NV12;
- otherlayer = _vpbe_display_get_other_win_layer(disp_dev,
- layer);
- otherlayer->layer_info.config.pixfmt = PIXFMT_NV12;
- }
-
- /* Set the layer config in the osd window */
- ret = osd_device->ops.set_layer_config(osd_device,
- layer->layer_info.id, cfg);
- if (ret < 0) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "Error in S_FMT params:\n");
- return -EINVAL;
- }
-
- /* Readback and fill the local copy of current pix format */
- osd_device->ops.get_layer_config(osd_device,
- layer->layer_info.id, cfg);
-
- return 0;
-}
-
-static int vpbe_display_try_fmt(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_display *disp_dev = fh->disp_dev;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_TRY_FMT\n");
-
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
- v4l2_err(&vpbe_dev->v4l2_dev, "invalid type\n");
- return -EINVAL;
- }
-
- /* Check for valid field format */
- return vpbe_try_format(disp_dev, pixfmt, 0);
-
-}
-
-/**
- * vpbe_display_s_std - Set the given standard in the encoder
- *
- * Sets the standard if supported by the current encoder. Return the status.
- * 0 - success & -EINVAL on error
- */
-static int vpbe_display_s_std(struct file *file, void *priv,
- v4l2_std_id *std_id)
-{
- struct vpbe_fh *fh = priv;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- int ret;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_STD\n");
-
- /* If streaming is started, return error */
- if (layer->started) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
- return -EBUSY;
- }
- if (NULL != vpbe_dev->ops.s_std) {
- ret = vpbe_dev->ops.s_std(vpbe_dev, std_id);
- if (ret) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "Failed to set standard for sub devices\n");
- return -EINVAL;
- }
- } else {
- return -EINVAL;
- }
-
- return 0;
-}
-
-/**
- * vpbe_display_g_std - Get the standard in the current encoder
- *
- * Get the standard in the current encoder. Return the status. 0 - success
- * -EINVAL on error
- */
-static int vpbe_display_g_std(struct file *file, void *priv,
- v4l2_std_id *std_id)
-{
- struct vpbe_fh *fh = priv;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_STD\n");
-
- /* Get the standard from the current encoder */
- if (vpbe_dev->current_timings.timings_type & VPBE_ENC_STD) {
- *std_id = vpbe_dev->current_timings.timings.std_id;
- return 0;
- }
-
- return -EINVAL;
-}
-
-/**
- * vpbe_display_enum_output - enumerate outputs
- *
- * Enumerates the outputs available at the vpbe display
- * returns the status, -EINVAL if end of output list
- */
-static int vpbe_display_enum_output(struct file *file, void *priv,
- struct v4l2_output *output)
-{
- struct vpbe_fh *fh = priv;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- int ret;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_OUTPUT\n");
-
- /* Enumerate outputs */
-
- if (NULL == vpbe_dev->ops.enum_outputs)
- return -EINVAL;
-
- ret = vpbe_dev->ops.enum_outputs(vpbe_dev, output);
- if (ret) {
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "Failed to enumerate outputs\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-/**
- * vpbe_display_s_output - Set output to
- * the output specified by the index
- */
-static int vpbe_display_s_output(struct file *file, void *priv,
- unsigned int i)
-{
- struct vpbe_fh *fh = priv;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- int ret;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_OUTPUT\n");
- /* If streaming is started, return error */
- if (layer->started) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
- return -EBUSY;
- }
- if (NULL == vpbe_dev->ops.set_output)
- return -EINVAL;
-
- ret = vpbe_dev->ops.set_output(vpbe_dev, i);
- if (ret) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "Failed to set output for sub devices\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-/**
- * vpbe_display_g_output - Get output from subdevice
- * for a given by the index
- */
-static int vpbe_display_g_output(struct file *file, void *priv,
- unsigned int *i)
-{
- struct vpbe_fh *fh = priv;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_OUTPUT\n");
- /* Get the standard from the current encoder */
- *i = vpbe_dev->current_out_index;
-
- return 0;
-}
-
-/**
- * vpbe_display_enum_dv_presets - Enumerate the dv presets
- *
- * enum the preset in the current encoder. Return the status. 0 - success
- * -EINVAL on error
- */
-static int
-vpbe_display_enum_dv_presets(struct file *file, void *priv,
- struct v4l2_dv_enum_preset *preset)
-{
- struct vpbe_fh *fh = priv;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- int ret;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_PRESETS\n");
-
- /* Enumerate outputs */
- if (NULL == vpbe_dev->ops.enum_dv_presets)
- return -EINVAL;
-
- ret = vpbe_dev->ops.enum_dv_presets(vpbe_dev, preset);
- if (ret) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "Failed to enumerate dv presets info\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-/**
- * vpbe_display_s_dv_preset - Set the dv presets
- *
- * Set the preset in the current encoder. Return the status. 0 - success
- * -EINVAL on error
- */
-static int
-vpbe_display_s_dv_preset(struct file *file, void *priv,
- struct v4l2_dv_preset *preset)
-{
- struct vpbe_fh *fh = priv;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- int ret;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_DV_PRESETS\n");
-
-
- /* If streaming is started, return error */
- if (layer->started) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
- return -EBUSY;
- }
-
- /* Set the given standard in the encoder */
- if (!vpbe_dev->ops.s_dv_preset)
- return -EINVAL;
-
- ret = vpbe_dev->ops.s_dv_preset(vpbe_dev, preset);
- if (ret) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "Failed to set the dv presets info\n");
- return -EINVAL;
- }
- /* set the current norm to zero to be consistent. If STD is used
- * v4l2 layer will set the norm properly on successful s_std call
- */
- layer->video_dev.current_norm = 0;
-
- return 0;
-}
-
-/**
- * vpbe_display_g_dv_preset - Set the dv presets
- *
- * Get the preset in the current encoder. Return the status. 0 - success
- * -EINVAL on error
- */
-static int
-vpbe_display_g_dv_preset(struct file *file, void *priv,
- struct v4l2_dv_preset *dv_preset)
-{
- struct vpbe_fh *fh = priv;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_DV_PRESETS\n");
-
- /* Get the given standard in the encoder */
-
- if (vpbe_dev->current_timings.timings_type &
- VPBE_ENC_DV_PRESET) {
- dv_preset->preset =
- vpbe_dev->current_timings.timings.dv_preset;
- } else {
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vpbe_display_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type buf_type)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- struct osd_state *osd_device = fh->disp_dev->osd_device;
- int ret;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "VIDIOC_STREAMOFF,layer id = %d\n",
- layer->device_id);
-
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf_type) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
- return -EINVAL;
- }
-
- /* If io is allowed for this file handle, return error */
- if (!fh->io_allowed) {
- v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
- return -EACCES;
- }
-
- /* If streaming is not started, return error */
- if (!layer->started) {
- v4l2_err(&vpbe_dev->v4l2_dev, "streaming not started in layer"
- " id = %d\n", layer->device_id);
- return -EINVAL;
- }
-
- osd_device->ops.disable_layer(osd_device,
- layer->layer_info.id);
- layer->started = 0;
- ret = videobuf_streamoff(&layer->buffer_queue);
-
- return ret;
-}
-
-static int vpbe_display_streamon(struct file *file, void *priv,
- enum v4l2_buf_type buf_type)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_display *disp_dev = fh->disp_dev;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- struct osd_state *osd_device = disp_dev->osd_device;
- int ret;
-
- osd_device->ops.disable_layer(osd_device,
- layer->layer_info.id);
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_STREAMON, layerid=%d\n",
- layer->device_id);
-
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf_type) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
- return -EINVAL;
- }
-
- /* If file handle is not allowed IO, return error */
- if (!fh->io_allowed) {
- v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
- return -EACCES;
- }
- /* If Streaming is already started, return error */
- if (layer->started) {
- v4l2_err(&vpbe_dev->v4l2_dev, "layer is already streaming\n");
- return -EBUSY;
- }
-
- /*
- * Call videobuf_streamon to start streaming
- * in videobuf
- */
- ret = videobuf_streamon(&layer->buffer_queue);
- if (ret) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "error in videobuf_streamon\n");
- return ret;
- }
- /* If buffer queue is empty, return error */
- if (list_empty(&layer->dma_queue)) {
- v4l2_err(&vpbe_dev->v4l2_dev, "buffer queue is empty\n");
- goto streamoff;
- }
- /* Get the next frame from the buffer queue */
- layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next,
- struct videobuf_buffer, queue);
- /* Remove buffer from the buffer queue */
- list_del(&layer->cur_frm->queue);
- /* Mark state of the current frame to active */
- layer->cur_frm->state = VIDEOBUF_ACTIVE;
- /* Initialize field_id and started member */
- layer->field_id = 0;
-
- /* Set parameters in OSD and VENC */
- ret = vpbe_set_osd_display_params(disp_dev, layer);
- if (ret < 0)
- goto streamoff;
-
- /*
- * if request format is yuv420 semiplanar, need to
- * enable both video windows
- */
- layer->started = 1;
-
- layer->layer_first_int = 1;
-
- return ret;
-streamoff:
- ret = videobuf_streamoff(&layer->buffer_queue);
- return ret;
-}
-
-static int vpbe_display_dqbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- int ret;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "VIDIOC_DQBUF, layer id = %d\n",
- layer->device_id);
-
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf->type) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
- return -EINVAL;
- }
- /* If this file handle is not allowed to do IO, return error */
- if (!fh->io_allowed) {
- v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
- return -EACCES;
- }
- if (file->f_flags & O_NONBLOCK)
- /* Call videobuf_dqbuf for non blocking mode */
- ret = videobuf_dqbuf(&layer->buffer_queue, buf, 1);
- else
- /* Call videobuf_dqbuf for blocking mode */
- ret = videobuf_dqbuf(&layer->buffer_queue, buf, 0);
-
- return ret;
-}
-
-static int vpbe_display_qbuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "VIDIOC_QBUF, layer id = %d\n",
- layer->device_id);
-
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT != p->type) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
- return -EINVAL;
- }
-
- /* If this file handle is not allowed to do IO, return error */
- if (!fh->io_allowed) {
- v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
- return -EACCES;
- }
-
- return videobuf_qbuf(&layer->buffer_queue, p);
-}
-
-static int vpbe_display_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- int ret;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "VIDIOC_QUERYBUF, layer id = %d\n",
- layer->device_id);
-
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf->type) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
- return -EINVAL;
- }
-
- /* Call videobuf_querybuf to get information */
- ret = videobuf_querybuf(&layer->buffer_queue, buf);
-
- return ret;
-}
-
-static int vpbe_display_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *req_buf)
-{
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- int ret;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_reqbufs\n");
-
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT != req_buf->type) {
- v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
- return -EINVAL;
- }
-
- /* If io users of the layer is not zero, return error */
- if (0 != layer->io_usrs) {
- v4l2_err(&vpbe_dev->v4l2_dev, "not IO user\n");
- return -EBUSY;
- }
- /* Initialize videobuf queue as per the buffer type */
- videobuf_queue_dma_contig_init(&layer->buffer_queue,
- &video_qops,
- vpbe_dev->pdev,
- &layer->irqlock,
- V4L2_BUF_TYPE_VIDEO_OUTPUT,
- layer->pix_fmt.field,
- sizeof(struct videobuf_buffer),
- fh, NULL);
-
- /* Set io allowed member of file handle to TRUE */
- fh->io_allowed = 1;
- /* Increment io usrs member of layer object to 1 */
- layer->io_usrs = 1;
- /* Store type of memory requested in layer object */
- layer->memory = req_buf->memory;
- /* Initialize buffer queue */
- INIT_LIST_HEAD(&layer->dma_queue);
- /* Allocate buffers */
- ret = videobuf_reqbufs(&layer->buffer_queue, req_buf);
-
- return ret;
-}
-
-/*
- * vpbe_display_mmap()
- * It is used to map kernel space buffers into user spaces
- */
-static int vpbe_display_mmap(struct file *filep, struct vm_area_struct *vma)
-{
- /* Get the layer object and file handle object */
- struct vpbe_fh *fh = filep->private_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_mmap\n");
-
- return videobuf_mmap_mapper(&layer->buffer_queue, vma);
-}
-
-/* vpbe_display_poll(): It is used for select/poll system call
- */
-static unsigned int vpbe_display_poll(struct file *filep, poll_table *wait)
-{
- struct vpbe_fh *fh = filep->private_data;
- struct vpbe_layer *layer = fh->layer;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- unsigned int err = 0;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_poll\n");
- if (layer->started)
- err = videobuf_poll_stream(filep, &layer->buffer_queue, wait);
- return err;
-}
-
-/*
- * vpbe_display_open()
- * It creates object of file handle structure and stores it in private_data
- * member of filepointer
- */
-static int vpbe_display_open(struct file *file)
-{
- struct vpbe_fh *fh = NULL;
- struct vpbe_layer *layer = video_drvdata(file);
- struct vpbe_display *disp_dev = layer->disp_dev;
- struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
- struct osd_state *osd_device = disp_dev->osd_device;
- int err;
-
- /* Allocate memory for the file handle object */
- fh = kmalloc(sizeof(struct vpbe_fh), GFP_KERNEL);
- if (fh == NULL) {
- v4l2_err(&vpbe_dev->v4l2_dev,
- "unable to allocate memory for file handle object\n");
- return -ENOMEM;
- }
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "vpbe display open plane = %d\n",
- layer->device_id);
-
- /* store pointer to fh in private_data member of filep */
- file->private_data = fh;
- fh->layer = layer;
- fh->disp_dev = disp_dev;
-
- if (!layer->usrs) {
-
- /* First claim the layer for this device */
- err = osd_device->ops.request_layer(osd_device,
- layer->layer_info.id);
- if (err < 0) {
- /* Couldn't get layer */
- v4l2_err(&vpbe_dev->v4l2_dev,
- "Display Manager failed to allocate layer\n");
- kfree(fh);
- return -EINVAL;
- }
- }
- /* Increment layer usrs counter */
- layer->usrs++;
- /* Set io_allowed member to false */
- fh->io_allowed = 0;
- /* Initialize priority of this instance to default priority */
- fh->prio = V4L2_PRIORITY_UNSET;
- v4l2_prio_open(&layer->prio, &fh->prio);
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
- "vpbe display device opened successfully\n");
- return 0;
-}
-
-/*
- * vpbe_display_release()
- * This function deletes buffer queue, frees the buffers and the davinci
- * display file * handle
- */
-static int vpbe_display_release(struct file *file)
-{
- /* Get the layer object and file handle object */
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_layer *layer = fh->layer;
- struct osd_layer_config *cfg = &layer->layer_info.config;
- struct vpbe_display *disp_dev = fh->disp_dev;
- struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
- struct osd_state *osd_device = disp_dev->osd_device;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_release\n");
-
- /* if this instance is doing IO */
- if (fh->io_allowed) {
- /* Reset io_usrs member of layer object */
- layer->io_usrs = 0;
-
- osd_device->ops.disable_layer(osd_device,
- layer->layer_info.id);
- layer->started = 0;
- /* Free buffers allocated */
- videobuf_queue_cancel(&layer->buffer_queue);
- videobuf_mmap_free(&layer->buffer_queue);
- }
-
- /* Decrement layer usrs counter */
- layer->usrs--;
- /* If this file handle has initialize encoder device, reset it */
- if (!layer->usrs) {
- if (cfg->pixfmt == PIXFMT_NV12) {
- struct vpbe_layer *otherlayer;
- otherlayer =
- _vpbe_display_get_other_win_layer(disp_dev, layer);
- osd_device->ops.disable_layer(osd_device,
- otherlayer->layer_info.id);
- osd_device->ops.release_layer(osd_device,
- otherlayer->layer_info.id);
- }
- osd_device->ops.disable_layer(osd_device,
- layer->layer_info.id);
- osd_device->ops.release_layer(osd_device,
- layer->layer_info.id);
- }
- /* Close the priority */
- v4l2_prio_close(&layer->prio, fh->prio);
- file->private_data = NULL;
-
- /* Free memory allocated to file handle object */
- kfree(fh);
-
- disp_dev->cbcr_ofst = 0;
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vpbe_display_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct v4l2_dbg_match *match = &reg->match;
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
- if (match->type >= 2) {
- v4l2_subdev_call(vpbe_dev->venc,
- core,
- g_register,
- reg);
- }
-
- return 0;
-}
-
-static int vpbe_display_s_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- return 0;
-}
-#endif
-
-/* vpbe capture ioctl operations */
-static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
- .vidioc_querycap = vpbe_display_querycap,
- .vidioc_g_fmt_vid_out = vpbe_display_g_fmt,
- .vidioc_enum_fmt_vid_out = vpbe_display_enum_fmt,
- .vidioc_s_fmt_vid_out = vpbe_display_s_fmt,
- .vidioc_try_fmt_vid_out = vpbe_display_try_fmt,
- .vidioc_reqbufs = vpbe_display_reqbufs,
- .vidioc_querybuf = vpbe_display_querybuf,
- .vidioc_qbuf = vpbe_display_qbuf,
- .vidioc_dqbuf = vpbe_display_dqbuf,
- .vidioc_streamon = vpbe_display_streamon,
- .vidioc_streamoff = vpbe_display_streamoff,
- .vidioc_cropcap = vpbe_display_cropcap,
- .vidioc_g_crop = vpbe_display_g_crop,
- .vidioc_s_crop = vpbe_display_s_crop,
- .vidioc_g_priority = vpbe_display_g_priority,
- .vidioc_s_priority = vpbe_display_s_priority,
- .vidioc_s_std = vpbe_display_s_std,
- .vidioc_g_std = vpbe_display_g_std,
- .vidioc_enum_output = vpbe_display_enum_output,
- .vidioc_s_output = vpbe_display_s_output,
- .vidioc_g_output = vpbe_display_g_output,
- .vidioc_s_dv_preset = vpbe_display_s_dv_preset,
- .vidioc_g_dv_preset = vpbe_display_g_dv_preset,
- .vidioc_enum_dv_presets = vpbe_display_enum_dv_presets,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vpbe_display_g_register,
- .vidioc_s_register = vpbe_display_s_register,
-#endif
-};
-
-static struct v4l2_file_operations vpbe_fops = {
- .owner = THIS_MODULE,
- .open = vpbe_display_open,
- .release = vpbe_display_release,
- .unlocked_ioctl = video_ioctl2,
- .mmap = vpbe_display_mmap,
- .poll = vpbe_display_poll
-};
-
-static int vpbe_device_get(struct device *dev, void *data)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct vpbe_display *vpbe_disp = data;
-
- if (strcmp("vpbe_controller", pdev->name) == 0)
- vpbe_disp->vpbe_dev = platform_get_drvdata(pdev);
-
- if (strcmp("vpbe-osd", pdev->name) == 0)
- vpbe_disp->osd_device = platform_get_drvdata(pdev);
-
- return 0;
-}
-
-static __devinit int init_vpbe_layer(int i, struct vpbe_display *disp_dev,
- struct platform_device *pdev)
-{
- struct vpbe_layer *vpbe_display_layer = NULL;
- struct video_device *vbd = NULL;
-
- /* Allocate memory for four plane display objects */
-
- disp_dev->dev[i] =
- kzalloc(sizeof(struct vpbe_layer), GFP_KERNEL);
-
- /* If memory allocation fails, return error */
- if (!disp_dev->dev[i]) {
- printk(KERN_ERR "ran out of memory\n");
- return -ENOMEM;
- }
- spin_lock_init(&disp_dev->dev[i]->irqlock);
- mutex_init(&disp_dev->dev[i]->opslock);
-
- /* Get the pointer to the layer object */
- vpbe_display_layer = disp_dev->dev[i];
- vbd = &vpbe_display_layer->video_dev;
- /* Initialize field of video device */
- vbd->release = video_device_release_empty;
- vbd->fops = &vpbe_fops;
- vbd->ioctl_ops = &vpbe_ioctl_ops;
- vbd->minor = -1;
- vbd->v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vbd->flags);
- vbd->lock = &vpbe_display_layer->opslock;
-
- if (disp_dev->vpbe_dev->current_timings.timings_type &
- VPBE_ENC_STD) {
- vbd->tvnorms = (V4L2_STD_525_60 | V4L2_STD_625_50);
- vbd->current_norm =
- disp_dev->vpbe_dev->
- current_timings.timings.std_id;
- } else
- vbd->current_norm = 0;
-
- snprintf(vbd->name, sizeof(vbd->name),
- "DaVinci_VPBE Display_DRIVER_V%d.%d.%d",
- (VPBE_DISPLAY_VERSION_CODE >> 16) & 0xff,
- (VPBE_DISPLAY_VERSION_CODE >> 8) & 0xff,
- (VPBE_DISPLAY_VERSION_CODE) & 0xff);
-
- vpbe_display_layer->device_id = i;
-
- vpbe_display_layer->layer_info.id =
- ((i == VPBE_DISPLAY_DEVICE_0) ? WIN_VID0 : WIN_VID1);
-
- /* Initialize prio member of layer object */
- v4l2_prio_init(&vpbe_display_layer->prio);
-
- return 0;
-}
-
-static __devinit int register_device(struct vpbe_layer *vpbe_display_layer,
- struct vpbe_display *disp_dev,
- struct platform_device *pdev) {
- int err;
-
- v4l2_info(&disp_dev->vpbe_dev->v4l2_dev,
- "Trying to register VPBE display device.\n");
- v4l2_info(&disp_dev->vpbe_dev->v4l2_dev,
- "layer=%x,layer->video_dev=%x\n",
- (int)vpbe_display_layer,
- (int)&vpbe_display_layer->video_dev);
-
- err = video_register_device(&vpbe_display_layer->video_dev,
- VFL_TYPE_GRABBER,
- -1);
- if (err)
- return -ENODEV;
-
- vpbe_display_layer->disp_dev = disp_dev;
- /* set the driver data in platform device */
- platform_set_drvdata(pdev, disp_dev);
- video_set_drvdata(&vpbe_display_layer->video_dev,
- vpbe_display_layer);
-
- return 0;
-}
-
-
-
-/*
- * vpbe_display_probe()
- * This function creates device entries by register itself to the V4L2 driver
- * and initializes fields of each layer objects
- */
-static __devinit int vpbe_display_probe(struct platform_device *pdev)
-{
- struct vpbe_layer *vpbe_display_layer;
- struct vpbe_display *disp_dev;
- struct resource *res = NULL;
- int k;
- int i;
- int err;
- int irq;
-
- printk(KERN_DEBUG "vpbe_display_probe\n");
- /* Allocate memory for vpbe_display */
- disp_dev = kzalloc(sizeof(struct vpbe_display), GFP_KERNEL);
- if (!disp_dev) {
- printk(KERN_ERR "ran out of memory\n");
- return -ENOMEM;
- }
-
- spin_lock_init(&disp_dev->dma_queue_lock);
- /*
- * Scan all the platform devices to find the vpbe
- * controller device and get the vpbe_dev object
- */
- err = bus_for_each_dev(&platform_bus_type, NULL, disp_dev,
- vpbe_device_get);
- if (err < 0)
- return err;
- /* Initialize the vpbe display controller */
- if (NULL != disp_dev->vpbe_dev->ops.initialize) {
- err = disp_dev->vpbe_dev->ops.initialize(&pdev->dev,
- disp_dev->vpbe_dev);
- if (err) {
- v4l2_err(&disp_dev->vpbe_dev->v4l2_dev,
- "Error initing vpbe\n");
- err = -ENOMEM;
- goto probe_out;
- }
- }
-
- for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
- if (init_vpbe_layer(i, disp_dev, pdev)) {
- err = -ENODEV;
- goto probe_out;
- }
- }
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- v4l2_err(&disp_dev->vpbe_dev->v4l2_dev,
- "Unable to get VENC interrupt resource\n");
- err = -ENODEV;
- goto probe_out;
- }
-
- irq = res->start;
- if (request_irq(irq, venc_isr, IRQF_DISABLED, VPBE_DISPLAY_DRIVER,
- disp_dev)) {
- v4l2_err(&disp_dev->vpbe_dev->v4l2_dev,
- "Unable to request interrupt\n");
- err = -ENODEV;
- goto probe_out;
- }
-
- for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
- if (register_device(disp_dev->dev[i], disp_dev, pdev)) {
- err = -ENODEV;
- goto probe_out_irq;
- }
- }
-
- printk(KERN_DEBUG "Successfully completed the probing of vpbe v4l2 device\n");
- return 0;
-
-probe_out_irq:
- free_irq(res->start, disp_dev);
-probe_out:
- for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) {
- /* Get the pointer to the layer object */
- vpbe_display_layer = disp_dev->dev[k];
- /* Unregister video device */
- if (vpbe_display_layer) {
- video_unregister_device(
- &vpbe_display_layer->video_dev);
- kfree(disp_dev->dev[k]);
- }
- }
- kfree(disp_dev);
- return err;
-}
-
-/*
- * vpbe_display_remove()
- * It un-register hardware layer from V4L2 driver
- */
-static int vpbe_display_remove(struct platform_device *pdev)
-{
- struct vpbe_layer *vpbe_display_layer;
- struct vpbe_display *disp_dev = platform_get_drvdata(pdev);
- struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
- struct resource *res;
- int i;
-
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_remove\n");
-
- /* unregister irq */
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- free_irq(res->start, disp_dev);
-
- /* deinitialize the vpbe display controller */
- if (NULL != vpbe_dev->ops.deinitialize)
- vpbe_dev->ops.deinitialize(&pdev->dev, vpbe_dev);
- /* un-register device */
- for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
- /* Get the pointer to the layer object */
- vpbe_display_layer = disp_dev->dev[i];
- /* Unregister video device */
- video_unregister_device(&vpbe_display_layer->video_dev);
-
- }
- for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
- kfree(disp_dev->dev[i]);
- disp_dev->dev[i] = NULL;
- }
-
- return 0;
-}
-
-static struct platform_driver vpbe_display_driver = {
- .driver = {
- .name = VPBE_DISPLAY_DRIVER,
- .owner = THIS_MODULE,
- .bus = &platform_bus_type,
- },
- .probe = vpbe_display_probe,
- .remove = __devexit_p(vpbe_display_remove),
-};
-
-module_platform_driver(vpbe_display_driver);
-
-MODULE_DESCRIPTION("TI DM644x/DM355/DM365 VPBE Display controller");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Texas Instruments");
diff --git a/drivers/media/video/davinci/vpbe_osd.c b/drivers/media/video/davinci/vpbe_osd.c
deleted file mode 100644
index bba299dbf39..00000000000
--- a/drivers/media/video/davinci/vpbe_osd.c
+++ /dev/null
@@ -1,1605 +0,0 @@
-/*
- * Copyright (C) 2007-2010 Texas Instruments Inc
- * Copyright (C) 2007 MontaVista Software, Inc.
- *
- * Andy Lowe (alowe@mvista.com), MontaVista Software
- * - Initial version
- * Murali Karicheri (mkaricheri@gmail.com), Texas Instruments Ltd.
- * - ported to sub device interface
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/slab.h>
-
-#include <mach/cputype.h>
-#include <mach/hardware.h>
-
-#include <media/davinci/vpss.h>
-#include <media/v4l2-device.h>
-#include <media/davinci/vpbe_types.h>
-#include <media/davinci/vpbe_osd.h>
-
-#include <linux/io.h>
-#include "vpbe_osd_regs.h"
-
-#define MODULE_NAME VPBE_OSD_SUBDEV_NAME
-
-/* register access routines */
-static inline u32 osd_read(struct osd_state *sd, u32 offset)
-{
- struct osd_state *osd = sd;
-
- return readl(osd->osd_base + offset);
-}
-
-static inline u32 osd_write(struct osd_state *sd, u32 val, u32 offset)
-{
- struct osd_state *osd = sd;
-
- writel(val, osd->osd_base + offset);
-
- return val;
-}
-
-static inline u32 osd_set(struct osd_state *sd, u32 mask, u32 offset)
-{
- struct osd_state *osd = sd;
-
- u32 addr = osd->osd_base + offset;
- u32 val = readl(addr) | mask;
-
- writel(val, addr);
-
- return val;
-}
-
-static inline u32 osd_clear(struct osd_state *sd, u32 mask, u32 offset)
-{
- struct osd_state *osd = sd;
-
- u32 addr = osd->osd_base + offset;
- u32 val = readl(addr) & ~mask;
-
- writel(val, addr);
-
- return val;
-}
-
-static inline u32 osd_modify(struct osd_state *sd, u32 mask, u32 val,
- u32 offset)
-{
- struct osd_state *osd = sd;
-
- u32 addr = osd->osd_base + offset;
- u32 new_val = (readl(addr) & ~mask) | (val & mask);
-
- writel(new_val, addr);
-
- return new_val;
-}
-
-/* define some macros for layer and pixfmt classification */
-#define is_osd_win(layer) (((layer) == WIN_OSD0) || ((layer) == WIN_OSD1))
-#define is_vid_win(layer) (((layer) == WIN_VID0) || ((layer) == WIN_VID1))
-#define is_rgb_pixfmt(pixfmt) \
- (((pixfmt) == PIXFMT_RGB565) || ((pixfmt) == PIXFMT_RGB888))
-#define is_yc_pixfmt(pixfmt) \
- (((pixfmt) == PIXFMT_YCbCrI) || ((pixfmt) == PIXFMT_YCrCbI) || \
- ((pixfmt) == PIXFMT_NV12))
-#define MAX_WIN_SIZE OSD_VIDWIN0XP_V0X
-#define MAX_LINE_LENGTH (OSD_VIDWIN0OFST_V0LO << 5)
-
-/**
- * _osd_dm6446_vid0_pingpong() - field inversion fix for DM6446
- * @sd - ptr to struct osd_state
- * @field_inversion - inversion flag
- * @fb_base_phys - frame buffer address
- * @lconfig - ptr to layer config
- *
- * This routine implements a workaround for the field signal inversion silicon
- * erratum described in Advisory 1.3.8 for the DM6446. The fb_base_phys and
- * lconfig parameters apply to the vid0 window. This routine should be called
- * whenever the vid0 layer configuration or start address is modified, or when
- * the OSD field inversion setting is modified.
- * Returns: 1 if the ping-pong buffers need to be toggled in the vsync isr, or
- * 0 otherwise
- */
-static int _osd_dm6446_vid0_pingpong(struct osd_state *sd,
- int field_inversion,
- unsigned long fb_base_phys,
- const struct osd_layer_config *lconfig)
-{
- struct osd_platform_data *pdata;
-
- pdata = (struct osd_platform_data *)sd->dev->platform_data;
- if (pdata->field_inv_wa_enable) {
-
- if (!field_inversion || !lconfig->interlaced) {
- osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR);
- osd_write(sd, fb_base_phys & ~0x1F, OSD_PPVWIN0ADR);
- osd_modify(sd, OSD_MISCCTL_PPSW | OSD_MISCCTL_PPRV, 0,
- OSD_MISCCTL);
- return 0;
- } else {
- unsigned miscctl = OSD_MISCCTL_PPRV;
-
- osd_write(sd,
- (fb_base_phys & ~0x1F) - lconfig->line_length,
- OSD_VIDWIN0ADR);
- osd_write(sd,
- (fb_base_phys & ~0x1F) + lconfig->line_length,
- OSD_PPVWIN0ADR);
- osd_modify(sd,
- OSD_MISCCTL_PPSW | OSD_MISCCTL_PPRV, miscctl,
- OSD_MISCCTL);
-
- return 1;
- }
- }
-
- return 0;
-}
-
-static void _osd_set_field_inversion(struct osd_state *sd, int enable)
-{
- unsigned fsinv = 0;
-
- if (enable)
- fsinv = OSD_MODE_FSINV;
-
- osd_modify(sd, OSD_MODE_FSINV, fsinv, OSD_MODE);
-}
-
-static void _osd_set_blink_attribute(struct osd_state *sd, int enable,
- enum osd_blink_interval blink)
-{
- u32 osdatrmd = 0;
-
- if (enable) {
- osdatrmd |= OSD_OSDATRMD_BLNK;
- osdatrmd |= blink << OSD_OSDATRMD_BLNKINT_SHIFT;
- }
- /* caller must ensure that OSD1 is configured in attribute mode */
- osd_modify(sd, OSD_OSDATRMD_BLNKINT | OSD_OSDATRMD_BLNK, osdatrmd,
- OSD_OSDATRMD);
-}
-
-static void _osd_set_rom_clut(struct osd_state *sd,
- enum osd_rom_clut rom_clut)
-{
- if (rom_clut == ROM_CLUT0)
- osd_clear(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL);
- else
- osd_set(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL);
-}
-
-static void _osd_set_palette_map(struct osd_state *sd,
- enum osd_win_layer osdwin,
- unsigned char pixel_value,
- unsigned char clut_index,
- enum osd_pix_format pixfmt)
-{
- static const int map_2bpp[] = { 0, 5, 10, 15 };
- static const int map_1bpp[] = { 0, 15 };
- int bmp_offset;
- int bmp_shift;
- int bmp_mask;
- int bmp_reg;
-
- switch (pixfmt) {
- case PIXFMT_1BPP:
- bmp_reg = map_1bpp[pixel_value & 0x1];
- break;
- case PIXFMT_2BPP:
- bmp_reg = map_2bpp[pixel_value & 0x3];
- break;
- case PIXFMT_4BPP:
- bmp_reg = pixel_value & 0xf;
- break;
- default:
- return;
- }
-
- switch (osdwin) {
- case OSDWIN_OSD0:
- bmp_offset = OSD_W0BMP01 + (bmp_reg >> 1) * sizeof(u32);
- break;
- case OSDWIN_OSD1:
- bmp_offset = OSD_W1BMP01 + (bmp_reg >> 1) * sizeof(u32);
- break;
- default:
- return;
- }
-
- if (bmp_reg & 1) {
- bmp_shift = 8;
- bmp_mask = 0xff << 8;
- } else {
- bmp_shift = 0;
- bmp_mask = 0xff;
- }
-
- osd_modify(sd, bmp_mask, clut_index << bmp_shift, bmp_offset);
-}
-
-static void _osd_set_rec601_attenuation(struct osd_state *sd,
- enum osd_win_layer osdwin, int enable)
-{
- switch (osdwin) {
- case OSDWIN_OSD0:
- osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
- enable ? OSD_OSDWIN0MD_ATN0E : 0,
- OSD_OSDWIN0MD);
- if (sd->vpbe_type == VPBE_VERSION_1)
- osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
- enable ? OSD_OSDWIN0MD_ATN0E : 0,
- OSD_OSDWIN0MD);
- else if ((sd->vpbe_type == VPBE_VERSION_3) ||
- (sd->vpbe_type == VPBE_VERSION_2))
- osd_modify(sd, OSD_EXTMODE_ATNOSD0EN,
- enable ? OSD_EXTMODE_ATNOSD0EN : 0,
- OSD_EXTMODE);
- break;
- case OSDWIN_OSD1:
- osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
- enable ? OSD_OSDWIN1MD_ATN1E : 0,
- OSD_OSDWIN1MD);
- if (sd->vpbe_type == VPBE_VERSION_1)
- osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
- enable ? OSD_OSDWIN1MD_ATN1E : 0,
- OSD_OSDWIN1MD);
- else if ((sd->vpbe_type == VPBE_VERSION_3) ||
- (sd->vpbe_type == VPBE_VERSION_2))
- osd_modify(sd, OSD_EXTMODE_ATNOSD1EN,
- enable ? OSD_EXTMODE_ATNOSD1EN : 0,
- OSD_EXTMODE);
- break;
- }
-}
-
-static void _osd_set_blending_factor(struct osd_state *sd,
- enum osd_win_layer osdwin,
- enum osd_blending_factor blend)
-{
- switch (osdwin) {
- case OSDWIN_OSD0:
- osd_modify(sd, OSD_OSDWIN0MD_BLND0,
- blend << OSD_OSDWIN0MD_BLND0_SHIFT, OSD_OSDWIN0MD);
- break;
- case OSDWIN_OSD1:
- osd_modify(sd, OSD_OSDWIN1MD_BLND1,
- blend << OSD_OSDWIN1MD_BLND1_SHIFT, OSD_OSDWIN1MD);
- break;
- }
-}
-
-static void _osd_enable_rgb888_pixblend(struct osd_state *sd,
- enum osd_win_layer osdwin)
-{
-
- osd_modify(sd, OSD_MISCCTL_BLDSEL, 0, OSD_MISCCTL);
- switch (osdwin) {
- case OSDWIN_OSD0:
- osd_modify(sd, OSD_EXTMODE_OSD0BLDCHR,
- OSD_EXTMODE_OSD0BLDCHR, OSD_EXTMODE);
- break;
- case OSDWIN_OSD1:
- osd_modify(sd, OSD_EXTMODE_OSD1BLDCHR,
- OSD_EXTMODE_OSD1BLDCHR, OSD_EXTMODE);
- break;
- }
-}
-
-static void _osd_enable_color_key(struct osd_state *sd,
- enum osd_win_layer osdwin,
- unsigned colorkey,
- enum osd_pix_format pixfmt)
-{
- switch (pixfmt) {
- case PIXFMT_1BPP:
- case PIXFMT_2BPP:
- case PIXFMT_4BPP:
- case PIXFMT_8BPP:
- if (sd->vpbe_type == VPBE_VERSION_3) {
- switch (osdwin) {
- case OSDWIN_OSD0:
- osd_modify(sd, OSD_TRANSPBMPIDX_BMP0,
- colorkey <<
- OSD_TRANSPBMPIDX_BMP0_SHIFT,
- OSD_TRANSPBMPIDX);
- break;
- case OSDWIN_OSD1:
- osd_modify(sd, OSD_TRANSPBMPIDX_BMP1,
- colorkey <<
- OSD_TRANSPBMPIDX_BMP1_SHIFT,
- OSD_TRANSPBMPIDX);
- break;
- }
- }
- break;
- case PIXFMT_RGB565:
- if (sd->vpbe_type == VPBE_VERSION_1)
- osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS,
- OSD_TRANSPVAL);
- else if (sd->vpbe_type == VPBE_VERSION_3)
- osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
- OSD_TRANSPVALL);
- break;
- case PIXFMT_YCbCrI:
- case PIXFMT_YCrCbI:
- if (sd->vpbe_type == VPBE_VERSION_3)
- osd_modify(sd, OSD_TRANSPVALU_Y, colorkey,
- OSD_TRANSPVALU);
- break;
- case PIXFMT_RGB888:
- if (sd->vpbe_type == VPBE_VERSION_3) {
- osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
- OSD_TRANSPVALL);
- osd_modify(sd, OSD_TRANSPVALU_RGBU, colorkey >> 16,
- OSD_TRANSPVALU);
- }
- break;
- default:
- break;
- }
-
- switch (osdwin) {
- case OSDWIN_OSD0:
- osd_set(sd, OSD_OSDWIN0MD_TE0, OSD_OSDWIN0MD);
- break;
- case OSDWIN_OSD1:
- osd_set(sd, OSD_OSDWIN1MD_TE1, OSD_OSDWIN1MD);
- break;
- }
-}
-
-static void _osd_disable_color_key(struct osd_state *sd,
- enum osd_win_layer osdwin)
-{
- switch (osdwin) {
- case OSDWIN_OSD0:
- osd_clear(sd, OSD_OSDWIN0MD_TE0, OSD_OSDWIN0MD);
- break;
- case OSDWIN_OSD1:
- osd_clear(sd, OSD_OSDWIN1MD_TE1, OSD_OSDWIN1MD);
- break;
- }
-}
-
-static void _osd_set_osd_clut(struct osd_state *sd,
- enum osd_win_layer osdwin,
- enum osd_clut clut)
-{
- u32 winmd = 0;
-
- switch (osdwin) {
- case OSDWIN_OSD0:
- if (clut == RAM_CLUT)
- winmd |= OSD_OSDWIN0MD_CLUTS0;
- osd_modify(sd, OSD_OSDWIN0MD_CLUTS0, winmd, OSD_OSDWIN0MD);
- break;
- case OSDWIN_OSD1:
- if (clut == RAM_CLUT)
- winmd |= OSD_OSDWIN1MD_CLUTS1;
- osd_modify(sd, OSD_OSDWIN1MD_CLUTS1, winmd, OSD_OSDWIN1MD);
- break;
- }
-}
-
-static void _osd_set_zoom(struct osd_state *sd, enum osd_layer layer,
- enum osd_zoom_factor h_zoom,
- enum osd_zoom_factor v_zoom)
-{
- u32 winmd = 0;
-
- switch (layer) {
- case WIN_OSD0:
- winmd |= (h_zoom << OSD_OSDWIN0MD_OHZ0_SHIFT);
- winmd |= (v_zoom << OSD_OSDWIN0MD_OVZ0_SHIFT);
- osd_modify(sd, OSD_OSDWIN0MD_OHZ0 | OSD_OSDWIN0MD_OVZ0, winmd,
- OSD_OSDWIN0MD);
- break;
- case WIN_VID0:
- winmd |= (h_zoom << OSD_VIDWINMD_VHZ0_SHIFT);
- winmd |= (v_zoom << OSD_VIDWINMD_VVZ0_SHIFT);
- osd_modify(sd, OSD_VIDWINMD_VHZ0 | OSD_VIDWINMD_VVZ0, winmd,
- OSD_VIDWINMD);
- break;
- case WIN_OSD1:
- winmd |= (h_zoom << OSD_OSDWIN1MD_OHZ1_SHIFT);
- winmd |= (v_zoom << OSD_OSDWIN1MD_OVZ1_SHIFT);
- osd_modify(sd, OSD_OSDWIN1MD_OHZ1 | OSD_OSDWIN1MD_OVZ1, winmd,
- OSD_OSDWIN1MD);
- break;
- case WIN_VID1:
- winmd |= (h_zoom << OSD_VIDWINMD_VHZ1_SHIFT);
- winmd |= (v_zoom << OSD_VIDWINMD_VVZ1_SHIFT);
- osd_modify(sd, OSD_VIDWINMD_VHZ1 | OSD_VIDWINMD_VVZ1, winmd,
- OSD_VIDWINMD);
- break;
- }
-}
-
-static void _osd_disable_layer(struct osd_state *sd, enum osd_layer layer)
-{
- switch (layer) {
- case WIN_OSD0:
- osd_clear(sd, OSD_OSDWIN0MD_OACT0, OSD_OSDWIN0MD);
- break;
- case WIN_VID0:
- osd_clear(sd, OSD_VIDWINMD_ACT0, OSD_VIDWINMD);
- break;
- case WIN_OSD1:
- /* disable attribute mode as well as disabling the window */
- osd_clear(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1,
- OSD_OSDWIN1MD);
- break;
- case WIN_VID1:
- osd_clear(sd, OSD_VIDWINMD_ACT1, OSD_VIDWINMD);
- break;
- }
-}
-
-static void osd_disable_layer(struct osd_state *sd, enum osd_layer layer)
-{
- struct osd_state *osd = sd;
- struct osd_window_state *win = &osd->win[layer];
- unsigned long flags;
-
- spin_lock_irqsave(&osd->lock, flags);
-
- if (!win->is_enabled) {
- spin_unlock_irqrestore(&osd->lock, flags);
- return;
- }
- win->is_enabled = 0;
-
- _osd_disable_layer(sd, layer);
-
- spin_unlock_irqrestore(&osd->lock, flags);
-}
-
-static void _osd_enable_attribute_mode(struct osd_state *sd)
-{
- /* enable attribute mode for OSD1 */
- osd_set(sd, OSD_OSDWIN1MD_OASW, OSD_OSDWIN1MD);
-}
-
-static void _osd_enable_layer(struct osd_state *sd, enum osd_layer layer)
-{
- switch (layer) {
- case WIN_OSD0:
- osd_set(sd, OSD_OSDWIN0MD_OACT0, OSD_OSDWIN0MD);
- break;
- case WIN_VID0:
- osd_set(sd, OSD_VIDWINMD_ACT0, OSD_VIDWINMD);
- break;
- case WIN_OSD1:
- /* enable OSD1 and disable attribute mode */
- osd_modify(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1,
- OSD_OSDWIN1MD_OACT1, OSD_OSDWIN1MD);
- break;
- case WIN_VID1:
- osd_set(sd, OSD_VIDWINMD_ACT1, OSD_VIDWINMD);
- break;
- }
-}
-
-static int osd_enable_layer(struct osd_state *sd, enum osd_layer layer,
- int otherwin)
-{
- struct osd_state *osd = sd;
- struct osd_window_state *win = &osd->win[layer];
- struct osd_layer_config *cfg = &win->lconfig;
- unsigned long flags;
-
- spin_lock_irqsave(&osd->lock, flags);
-
- /*
- * use otherwin flag to know this is the other vid window
- * in YUV420 mode, if is, skip this check
- */
- if (!otherwin && (!win->is_allocated ||
- !win->fb_base_phys ||
- !cfg->line_length ||
- !cfg->xsize ||
- !cfg->ysize)) {
- spin_unlock_irqrestore(&osd->lock, flags);
- return -1;
- }
-
- if (win->is_enabled) {
- spin_unlock_irqrestore(&osd->lock, flags);
- return 0;
- }
- win->is_enabled = 1;
-
- if (cfg->pixfmt != PIXFMT_OSD_ATTR)
- _osd_enable_layer(sd, layer);
- else {
- _osd_enable_attribute_mode(sd);
- _osd_set_blink_attribute(sd, osd->is_blinking, osd->blink);
- }
-
- spin_unlock_irqrestore(&osd->lock, flags);
-
- return 0;
-}
-
-#define OSD_SRC_ADDR_HIGH4 0x7800000
-#define OSD_SRC_ADDR_HIGH7 0x7F0000
-#define OSD_SRCADD_OFSET_SFT 23
-#define OSD_SRCADD_ADD_SFT 16
-#define OSD_WINADL_MASK 0xFFFF
-#define OSD_WINOFST_MASK 0x1000
-#define VPBE_REG_BASE 0x80000000
-
-static void _osd_start_layer(struct osd_state *sd, enum osd_layer layer,
- unsigned long fb_base_phys,
- unsigned long cbcr_ofst)
-{
-
- if (sd->vpbe_type == VPBE_VERSION_1) {
- switch (layer) {
- case WIN_OSD0:
- osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR);
- break;
- case WIN_VID0:
- osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR);
- break;
- case WIN_OSD1:
- osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR);
- break;
- case WIN_VID1:
- osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR);
- break;
- }
- } else if (sd->vpbe_type == VPBE_VERSION_3) {
- unsigned long fb_offset_32 =
- (fb_base_phys - VPBE_REG_BASE) >> 5;
-
- switch (layer) {
- case WIN_OSD0:
- osd_modify(sd, OSD_OSDWINADH_O0AH,
- fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
- OSD_OSDWINADH_O0AH_SHIFT),
- OSD_OSDWINADH);
- osd_write(sd, fb_offset_32 & OSD_OSDWIN0ADL_O0AL,
- OSD_OSDWIN0ADL);
- break;
- case WIN_VID0:
- osd_modify(sd, OSD_VIDWINADH_V0AH,
- fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
- OSD_VIDWINADH_V0AH_SHIFT),
- OSD_VIDWINADH);
- osd_write(sd, fb_offset_32 & OSD_VIDWIN0ADL_V0AL,
- OSD_VIDWIN0ADL);
- break;
- case WIN_OSD1:
- osd_modify(sd, OSD_OSDWINADH_O1AH,
- fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
- OSD_OSDWINADH_O1AH_SHIFT),
- OSD_OSDWINADH);
- osd_write(sd, fb_offset_32 & OSD_OSDWIN1ADL_O1AL,
- OSD_OSDWIN1ADL);
- break;
- case WIN_VID1:
- osd_modify(sd, OSD_VIDWINADH_V1AH,
- fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
- OSD_VIDWINADH_V1AH_SHIFT),
- OSD_VIDWINADH);
- osd_write(sd, fb_offset_32 & OSD_VIDWIN1ADL_V1AL,
- OSD_VIDWIN1ADL);
- break;
- }
- } else if (sd->vpbe_type == VPBE_VERSION_2) {
- struct osd_window_state *win = &sd->win[layer];
- unsigned long fb_offset_32, cbcr_offset_32;
-
- fb_offset_32 = fb_base_phys - VPBE_REG_BASE;
- if (cbcr_ofst)
- cbcr_offset_32 = cbcr_ofst;
- else
- cbcr_offset_32 = win->lconfig.line_length *
- win->lconfig.ysize;
- cbcr_offset_32 += fb_offset_32;
- fb_offset_32 = fb_offset_32 >> 5;
- cbcr_offset_32 = cbcr_offset_32 >> 5;
- /*
- * DM365: start address is 27-bit long address b26 - b23 are
- * in offset register b12 - b9, and * bit 26 has to be '1'
- */
- if (win->lconfig.pixfmt == PIXFMT_NV12) {
- switch (layer) {
- case WIN_VID0:
- case WIN_VID1:
- /* Y is in VID0 */
- osd_modify(sd, OSD_VIDWIN0OFST_V0AH,
- ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
- (OSD_SRCADD_OFSET_SFT -
- OSD_WINOFST_AH_SHIFT)) |
- OSD_WINOFST_MASK, OSD_VIDWIN0OFST);
- osd_modify(sd, OSD_VIDWINADH_V0AH,
- (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
- (OSD_SRCADD_ADD_SFT -
- OSD_VIDWINADH_V0AH_SHIFT),
- OSD_VIDWINADH);
- osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
- OSD_VIDWIN0ADL);
- /* CbCr is in VID1 */
- osd_modify(sd, OSD_VIDWIN1OFST_V1AH,
- ((cbcr_offset_32 &
- OSD_SRC_ADDR_HIGH4) >>
- (OSD_SRCADD_OFSET_SFT -
- OSD_WINOFST_AH_SHIFT)) |
- OSD_WINOFST_MASK, OSD_VIDWIN1OFST);
- osd_modify(sd, OSD_VIDWINADH_V1AH,
- (cbcr_offset_32 &
- OSD_SRC_ADDR_HIGH7) >>
- (OSD_SRCADD_ADD_SFT -
- OSD_VIDWINADH_V1AH_SHIFT),
- OSD_VIDWINADH);
- osd_write(sd, cbcr_offset_32 & OSD_WINADL_MASK,
- OSD_VIDWIN1ADL);
- break;
- default:
- break;
- }
- }
-
- switch (layer) {
- case WIN_OSD0:
- osd_modify(sd, OSD_OSDWIN0OFST_O0AH,
- ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
- (OSD_SRCADD_OFSET_SFT -
- OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK,
- OSD_OSDWIN0OFST);
- osd_modify(sd, OSD_OSDWINADH_O0AH,
- (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
- (OSD_SRCADD_ADD_SFT -
- OSD_OSDWINADH_O0AH_SHIFT), OSD_OSDWINADH);
- osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
- OSD_OSDWIN0ADL);
- break;
- case WIN_VID0:
- if (win->lconfig.pixfmt != PIXFMT_NV12) {
- osd_modify(sd, OSD_VIDWIN0OFST_V0AH,
- ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
- (OSD_SRCADD_OFSET_SFT -
- OSD_WINOFST_AH_SHIFT)) |
- OSD_WINOFST_MASK, OSD_VIDWIN0OFST);
- osd_modify(sd, OSD_VIDWINADH_V0AH,
- (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
- (OSD_SRCADD_ADD_SFT -
- OSD_VIDWINADH_V0AH_SHIFT),
- OSD_VIDWINADH);
- osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
- OSD_VIDWIN0ADL);
- }
- break;
- case WIN_OSD1:
- osd_modify(sd, OSD_OSDWIN1OFST_O1AH,
- ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
- (OSD_SRCADD_OFSET_SFT -
- OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK,
- OSD_OSDWIN1OFST);
- osd_modify(sd, OSD_OSDWINADH_O1AH,
- (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
- (OSD_SRCADD_ADD_SFT -
- OSD_OSDWINADH_O1AH_SHIFT),
- OSD_OSDWINADH);
- osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
- OSD_OSDWIN1ADL);
- break;
- case WIN_VID1:
- if (win->lconfig.pixfmt != PIXFMT_NV12) {
- osd_modify(sd, OSD_VIDWIN1OFST_V1AH,
- ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
- (OSD_SRCADD_OFSET_SFT -
- OSD_WINOFST_AH_SHIFT)) |
- OSD_WINOFST_MASK, OSD_VIDWIN1OFST);
- osd_modify(sd, OSD_VIDWINADH_V1AH,
- (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
- (OSD_SRCADD_ADD_SFT -
- OSD_VIDWINADH_V1AH_SHIFT),
- OSD_VIDWINADH);
- osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
- OSD_VIDWIN1ADL);
- }
- break;
- }
- }
-}
-
-static void osd_start_layer(struct osd_state *sd, enum osd_layer layer,
- unsigned long fb_base_phys,
- unsigned long cbcr_ofst)
-{
- struct osd_state *osd = sd;
- struct osd_window_state *win = &osd->win[layer];
- struct osd_layer_config *cfg = &win->lconfig;
- unsigned long flags;
-
- spin_lock_irqsave(&osd->lock, flags);
-
- win->fb_base_phys = fb_base_phys & ~0x1F;
- _osd_start_layer(sd, layer, fb_base_phys, cbcr_ofst);
-
- if (layer == WIN_VID0) {
- osd->pingpong =
- _osd_dm6446_vid0_pingpong(sd, osd->field_inversion,
- win->fb_base_phys,
- cfg);
- }
-
- spin_unlock_irqrestore(&osd->lock, flags);
-}
-
-static void osd_get_layer_config(struct osd_state *sd, enum osd_layer layer,
- struct osd_layer_config *lconfig)
-{
- struct osd_state *osd = sd;
- struct osd_window_state *win = &osd->win[layer];
- unsigned long flags;
-
- spin_lock_irqsave(&osd->lock, flags);
-
- *lconfig = win->lconfig;
-
- spin_unlock_irqrestore(&osd->lock, flags);
-}
-
-/**
- * try_layer_config() - Try a specific configuration for the layer
- * @sd - ptr to struct osd_state
- * @layer - layer to configure
- * @lconfig - layer configuration to try
- *
- * If the requested lconfig is completely rejected and the value of lconfig on
- * exit is the current lconfig, then try_layer_config() returns 1. Otherwise,
- * try_layer_config() returns 0. A return value of 0 does not necessarily mean
- * that the value of lconfig on exit is identical to the value of lconfig on
- * entry, but merely that it represents a change from the current lconfig.
- */
-static int try_layer_config(struct osd_state *sd, enum osd_layer layer,
- struct osd_layer_config *lconfig)
-{
- struct osd_state *osd = sd;
- struct osd_window_state *win = &osd->win[layer];
- int bad_config = 0;
-
- /* verify that the pixel format is compatible with the layer */
- switch (lconfig->pixfmt) {
- case PIXFMT_1BPP:
- case PIXFMT_2BPP:
- case PIXFMT_4BPP:
- case PIXFMT_8BPP:
- case PIXFMT_RGB565:
- if (osd->vpbe_type == VPBE_VERSION_1)
- bad_config = !is_vid_win(layer);
- break;
- case PIXFMT_YCbCrI:
- case PIXFMT_YCrCbI:
- bad_config = !is_vid_win(layer);
- break;
- case PIXFMT_RGB888:
- if (osd->vpbe_type == VPBE_VERSION_1)
- bad_config = !is_vid_win(layer);
- else if ((osd->vpbe_type == VPBE_VERSION_3) ||
- (osd->vpbe_type == VPBE_VERSION_2))
- bad_config = !is_osd_win(layer);
- break;
- case PIXFMT_NV12:
- if (osd->vpbe_type != VPBE_VERSION_2)
- bad_config = 1;
- else
- bad_config = is_osd_win(layer);
- break;
- case PIXFMT_OSD_ATTR:
- bad_config = (layer != WIN_OSD1);
- break;
- default:
- bad_config = 1;
- break;
- }
- if (bad_config) {
- /*
- * The requested pixel format is incompatible with the layer,
- * so keep the current layer configuration.
- */
- *lconfig = win->lconfig;
- return bad_config;
- }
-
- /* DM6446: */
- /* only one OSD window at a time can use RGB pixel formats */
- if ((osd->vpbe_type == VPBE_VERSION_1) &&
- is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) {
- enum osd_pix_format pixfmt;
- if (layer == WIN_OSD0)
- pixfmt = osd->win[WIN_OSD1].lconfig.pixfmt;
- else
- pixfmt = osd->win[WIN_OSD0].lconfig.pixfmt;
-
- if (is_rgb_pixfmt(pixfmt)) {
- /*
- * The other OSD window is already configured for an
- * RGB, so keep the current layer configuration.
- */
- *lconfig = win->lconfig;
- return 1;
- }
- }
-
- /* DM6446: only one video window at a time can use RGB888 */
- if ((osd->vpbe_type == VPBE_VERSION_1) && is_vid_win(layer) &&
- lconfig->pixfmt == PIXFMT_RGB888) {
- enum osd_pix_format pixfmt;
-
- if (layer == WIN_VID0)
- pixfmt = osd->win[WIN_VID1].lconfig.pixfmt;
- else
- pixfmt = osd->win[WIN_VID0].lconfig.pixfmt;
-
- if (pixfmt == PIXFMT_RGB888) {
- /*
- * The other video window is already configured for
- * RGB888, so keep the current layer configuration.
- */
- *lconfig = win->lconfig;
- return 1;
- }
- }
-
- /* window dimensions must be non-zero */
- if (!lconfig->line_length || !lconfig->xsize || !lconfig->ysize) {
- *lconfig = win->lconfig;
- return 1;
- }
-
- /* round line_length up to a multiple of 32 */
- lconfig->line_length = ((lconfig->line_length + 31) / 32) * 32;
- lconfig->line_length =
- min(lconfig->line_length, (unsigned)MAX_LINE_LENGTH);
- lconfig->xsize = min(lconfig->xsize, (unsigned)MAX_WIN_SIZE);
- lconfig->ysize = min(lconfig->ysize, (unsigned)MAX_WIN_SIZE);
- lconfig->xpos = min(lconfig->xpos, (unsigned)MAX_WIN_SIZE);
- lconfig->ypos = min(lconfig->ypos, (unsigned)MAX_WIN_SIZE);
- lconfig->interlaced = (lconfig->interlaced != 0);
- if (lconfig->interlaced) {
- /* ysize and ypos must be even for interlaced displays */
- lconfig->ysize &= ~1;
- lconfig->ypos &= ~1;
- }
-
- return 0;
-}
-
-static void _osd_disable_vid_rgb888(struct osd_state *sd)
-{
- /*
- * The DM6446 supports RGB888 pixel format in a single video window.
- * This routine disables RGB888 pixel format for both video windows.
- * The caller must ensure that neither video window is currently
- * configured for RGB888 pixel format.
- */
- if (sd->vpbe_type == VPBE_VERSION_1)
- osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL);
-}
-
-static void _osd_enable_vid_rgb888(struct osd_state *sd,
- enum osd_layer layer)
-{
- /*
- * The DM6446 supports RGB888 pixel format in a single video window.
- * This routine enables RGB888 pixel format for the specified video
- * window. The caller must ensure that the other video window is not
- * currently configured for RGB888 pixel format, as this routine will
- * disable RGB888 pixel format for the other window.
- */
- if (sd->vpbe_type == VPBE_VERSION_1) {
- if (layer == WIN_VID0)
- osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
- OSD_MISCCTL_RGBEN, OSD_MISCCTL);
- else if (layer == WIN_VID1)
- osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
- OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
- OSD_MISCCTL);
- }
-}
-
-static void _osd_set_cbcr_order(struct osd_state *sd,
- enum osd_pix_format pixfmt)
-{
- /*
- * The caller must ensure that all windows using YC pixfmt use the same
- * Cb/Cr order.
- */
- if (pixfmt == PIXFMT_YCbCrI)
- osd_clear(sd, OSD_MODE_CS, OSD_MODE);
- else if (pixfmt == PIXFMT_YCrCbI)
- osd_set(sd, OSD_MODE_CS, OSD_MODE);
-}
-
-static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
- const struct osd_layer_config *lconfig)
-{
- u32 winmd = 0, winmd_mask = 0, bmw = 0;
-
- _osd_set_cbcr_order(sd, lconfig->pixfmt);
-
- switch (layer) {
- case WIN_OSD0:
- if (sd->vpbe_type == VPBE_VERSION_1) {
- winmd_mask |= OSD_OSDWIN0MD_RGB0E;
- if (lconfig->pixfmt == PIXFMT_RGB565)
- winmd |= OSD_OSDWIN0MD_RGB0E;
- } else if ((sd->vpbe_type == VPBE_VERSION_3) ||
- (sd->vpbe_type == VPBE_VERSION_2)) {
- winmd_mask |= OSD_OSDWIN0MD_BMP0MD;
- switch (lconfig->pixfmt) {
- case PIXFMT_RGB565:
- winmd |= (1 <<
- OSD_OSDWIN0MD_BMP0MD_SHIFT);
- break;
- case PIXFMT_RGB888:
- winmd |= (2 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
- _osd_enable_rgb888_pixblend(sd, OSDWIN_OSD0);
- break;
- case PIXFMT_YCbCrI:
- case PIXFMT_YCrCbI:
- winmd |= (3 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
- break;
- default:
- break;
- }
- }
-
- winmd_mask |= OSD_OSDWIN0MD_BMW0 | OSD_OSDWIN0MD_OFF0;
-
- switch (lconfig->pixfmt) {
- case PIXFMT_1BPP:
- bmw = 0;
- break;
- case PIXFMT_2BPP:
- bmw = 1;
- break;
- case PIXFMT_4BPP:
- bmw = 2;
- break;
- case PIXFMT_8BPP:
- bmw = 3;
- break;
- default:
- break;
- }
- winmd |= (bmw << OSD_OSDWIN0MD_BMW0_SHIFT);
-
- if (lconfig->interlaced)
- winmd |= OSD_OSDWIN0MD_OFF0;
-
- osd_modify(sd, winmd_mask, winmd, OSD_OSDWIN0MD);
- osd_write(sd, lconfig->line_length >> 5, OSD_OSDWIN0OFST);
- osd_write(sd, lconfig->xpos, OSD_OSDWIN0XP);
- osd_write(sd, lconfig->xsize, OSD_OSDWIN0XL);
- if (lconfig->interlaced) {
- osd_write(sd, lconfig->ypos >> 1, OSD_OSDWIN0YP);
- osd_write(sd, lconfig->ysize >> 1, OSD_OSDWIN0YL);
- } else {
- osd_write(sd, lconfig->ypos, OSD_OSDWIN0YP);
- osd_write(sd, lconfig->ysize, OSD_OSDWIN0YL);
- }
- break;
- case WIN_VID0:
- winmd_mask |= OSD_VIDWINMD_VFF0;
- if (lconfig->interlaced)
- winmd |= OSD_VIDWINMD_VFF0;
-
- osd_modify(sd, winmd_mask, winmd, OSD_VIDWINMD);
- osd_write(sd, lconfig->line_length >> 5, OSD_VIDWIN0OFST);
- osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP);
- osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL);
- /*
- * For YUV420P format the register contents are
- * duplicated in both VID registers
- */
- if ((sd->vpbe_type == VPBE_VERSION_2) &&
- (lconfig->pixfmt == PIXFMT_NV12)) {
- /* other window also */
- if (lconfig->interlaced) {
- winmd_mask |= OSD_VIDWINMD_VFF1;
- winmd |= OSD_VIDWINMD_VFF1;
- osd_modify(sd, winmd_mask, winmd,
- OSD_VIDWINMD);
- }
-
- osd_modify(sd, OSD_MISCCTL_S420D,
- OSD_MISCCTL_S420D, OSD_MISCCTL);
- osd_write(sd, lconfig->line_length >> 5,
- OSD_VIDWIN1OFST);
- osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP);
- osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL);
- /*
- * if NV21 pixfmt and line length not 32B
- * aligned (e.g. NTSC), Need to set window
- * X pixel size to be 32B aligned as well
- */
- if (lconfig->xsize % 32) {
- osd_write(sd,
- ((lconfig->xsize + 31) & ~31),
- OSD_VIDWIN1XL);
- osd_write(sd,
- ((lconfig->xsize + 31) & ~31),
- OSD_VIDWIN0XL);
- }
- } else if ((sd->vpbe_type == VPBE_VERSION_2) &&
- (lconfig->pixfmt != PIXFMT_NV12)) {
- osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D,
- OSD_MISCCTL);
- }
-
- if (lconfig->interlaced) {
- osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN0YP);
- osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN0YL);
- if ((sd->vpbe_type == VPBE_VERSION_2) &&
- lconfig->pixfmt == PIXFMT_NV12) {
- osd_write(sd, lconfig->ypos >> 1,
- OSD_VIDWIN1YP);
- osd_write(sd, lconfig->ysize >> 1,
- OSD_VIDWIN1YL);
- }
- } else {
- osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP);
- osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL);
- if ((sd->vpbe_type == VPBE_VERSION_2) &&
- lconfig->pixfmt == PIXFMT_NV12) {
- osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP);
- osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL);
- }
- }
- break;
- case WIN_OSD1:
- /*
- * The caller must ensure that OSD1 is disabled prior to
- * switching from a normal mode to attribute mode or from
- * attribute mode to a normal mode.
- */
- if (lconfig->pixfmt == PIXFMT_OSD_ATTR) {
- if (sd->vpbe_type == VPBE_VERSION_1) {
- winmd_mask |= OSD_OSDWIN1MD_ATN1E |
- OSD_OSDWIN1MD_RGB1E | OSD_OSDWIN1MD_CLUTS1 |
- OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1;
- } else {
- winmd_mask |= OSD_OSDWIN1MD_BMP1MD |
- OSD_OSDWIN1MD_CLUTS1 | OSD_OSDWIN1MD_BLND1 |
- OSD_OSDWIN1MD_TE1;
- }
- } else {
- if (sd->vpbe_type == VPBE_VERSION_1) {
- winmd_mask |= OSD_OSDWIN1MD_RGB1E;
- if (lconfig->pixfmt == PIXFMT_RGB565)
- winmd |= OSD_OSDWIN1MD_RGB1E;
- } else if ((sd->vpbe_type == VPBE_VERSION_3)
- || (sd->vpbe_type == VPBE_VERSION_2)) {
- winmd_mask |= OSD_OSDWIN1MD_BMP1MD;
- switch (lconfig->pixfmt) {
- case PIXFMT_RGB565:
- winmd |=
- (1 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
- break;
- case PIXFMT_RGB888:
- winmd |=
- (2 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
- _osd_enable_rgb888_pixblend(sd,
- OSDWIN_OSD1);
- break;
- case PIXFMT_YCbCrI:
- case PIXFMT_YCrCbI:
- winmd |=
- (3 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
- break;
- default:
- break;
- }
- }
-
- winmd_mask |= OSD_OSDWIN1MD_BMW1;
- switch (lconfig->pixfmt) {
- case PIXFMT_1BPP:
- bmw = 0;
- break;
- case PIXFMT_2BPP:
- bmw = 1;
- break;
- case PIXFMT_4BPP:
- bmw = 2;
- break;
- case PIXFMT_8BPP:
- bmw = 3;
- break;
- default:
- break;
- }
- winmd |= (bmw << OSD_OSDWIN1MD_BMW1_SHIFT);
- }
-
- winmd_mask |= OSD_OSDWIN1MD_OFF1;
- if (lconfig->interlaced)
- winmd |= OSD_OSDWIN1MD_OFF1;
-
- osd_modify(sd, winmd_mask, winmd, OSD_OSDWIN1MD);
- osd_write(sd, lconfig->line_length >> 5, OSD_OSDWIN1OFST);
- osd_write(sd, lconfig->xpos, OSD_OSDWIN1XP);
- osd_write(sd, lconfig->xsize, OSD_OSDWIN1XL);
- if (lconfig->interlaced) {
- osd_write(sd, lconfig->ypos >> 1, OSD_OSDWIN1YP);
- osd_write(sd, lconfig->ysize >> 1, OSD_OSDWIN1YL);
- } else {
- osd_write(sd, lconfig->ypos, OSD_OSDWIN1YP);
- osd_write(sd, lconfig->ysize, OSD_OSDWIN1YL);
- }
- break;
- case WIN_VID1:
- winmd_mask |= OSD_VIDWINMD_VFF1;
- if (lconfig->interlaced)
- winmd |= OSD_VIDWINMD_VFF1;
-
- osd_modify(sd, winmd_mask, winmd, OSD_VIDWINMD);
- osd_write(sd, lconfig->line_length >> 5, OSD_VIDWIN1OFST);
- osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP);
- osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL);
- /*
- * For YUV420P format the register contents are
- * duplicated in both VID registers
- */
- if (sd->vpbe_type == VPBE_VERSION_2) {
- if (lconfig->pixfmt == PIXFMT_NV12) {
- /* other window also */
- if (lconfig->interlaced) {
- winmd_mask |= OSD_VIDWINMD_VFF0;
- winmd |= OSD_VIDWINMD_VFF0;
- osd_modify(sd, winmd_mask, winmd,
- OSD_VIDWINMD);
- }
- osd_modify(sd, OSD_MISCCTL_S420D,
- OSD_MISCCTL_S420D, OSD_MISCCTL);
- osd_write(sd, lconfig->line_length >> 5,
- OSD_VIDWIN0OFST);
- osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP);
- osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL);
- } else {
- osd_modify(sd, OSD_MISCCTL_S420D,
- ~OSD_MISCCTL_S420D, OSD_MISCCTL);
- }
- }
-
- if (lconfig->interlaced) {
- osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN1YP);
- osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN1YL);
- if ((sd->vpbe_type == VPBE_VERSION_2) &&
- lconfig->pixfmt == PIXFMT_NV12) {
- osd_write(sd, lconfig->ypos >> 1,
- OSD_VIDWIN0YP);
- osd_write(sd, lconfig->ysize >> 1,
- OSD_VIDWIN0YL);
- }
- } else {
- osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP);
- osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL);
- if ((sd->vpbe_type == VPBE_VERSION_2) &&
- lconfig->pixfmt == PIXFMT_NV12) {
- osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP);
- osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL);
- }
- }
- break;
- }
-}
-
-static int osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
- struct osd_layer_config *lconfig)
-{
- struct osd_state *osd = sd;
- struct osd_window_state *win = &osd->win[layer];
- struct osd_layer_config *cfg = &win->lconfig;
- unsigned long flags;
- int reject_config;
-
- spin_lock_irqsave(&osd->lock, flags);
-
- reject_config = try_layer_config(sd, layer, lconfig);
- if (reject_config) {
- spin_unlock_irqrestore(&osd->lock, flags);
- return reject_config;
- }
-
- /* update the current Cb/Cr order */
- if (is_yc_pixfmt(lconfig->pixfmt))
- osd->yc_pixfmt = lconfig->pixfmt;
-
- /*
- * If we are switching OSD1 from normal mode to attribute mode or from
- * attribute mode to normal mode, then we must disable the window.
- */
- if (layer == WIN_OSD1) {
- if (((lconfig->pixfmt == PIXFMT_OSD_ATTR) &&
- (cfg->pixfmt != PIXFMT_OSD_ATTR)) ||
- ((lconfig->pixfmt != PIXFMT_OSD_ATTR) &&
- (cfg->pixfmt == PIXFMT_OSD_ATTR))) {
- win->is_enabled = 0;
- _osd_disable_layer(sd, layer);
- }
- }
-
- _osd_set_layer_config(sd, layer, lconfig);
-
- if (layer == WIN_OSD1) {
- struct osd_osdwin_state *osdwin_state =
- &osd->osdwin[OSDWIN_OSD1];
-
- if ((lconfig->pixfmt != PIXFMT_OSD_ATTR) &&
- (cfg->pixfmt == PIXFMT_OSD_ATTR)) {
- /*
- * We just switched OSD1 from attribute mode to normal
- * mode, so we must initialize the CLUT select, the
- * blend factor, transparency colorkey enable, and
- * attenuation enable (DM6446 only) bits in the
- * OSDWIN1MD register.
- */
- _osd_set_osd_clut(sd, OSDWIN_OSD1,
- osdwin_state->clut);
- _osd_set_blending_factor(sd, OSDWIN_OSD1,
- osdwin_state->blend);
- if (osdwin_state->colorkey_blending) {
- _osd_enable_color_key(sd, OSDWIN_OSD1,
- osdwin_state->
- colorkey,
- lconfig->pixfmt);
- } else
- _osd_disable_color_key(sd, OSDWIN_OSD1);
- _osd_set_rec601_attenuation(sd, OSDWIN_OSD1,
- osdwin_state->
- rec601_attenuation);
- } else if ((lconfig->pixfmt == PIXFMT_OSD_ATTR) &&
- (cfg->pixfmt != PIXFMT_OSD_ATTR)) {
- /*
- * We just switched OSD1 from normal mode to attribute
- * mode, so we must initialize the blink enable and
- * blink interval bits in the OSDATRMD register.
- */
- _osd_set_blink_attribute(sd, osd->is_blinking,
- osd->blink);
- }
- }
-
- /*
- * If we just switched to a 1-, 2-, or 4-bits-per-pixel bitmap format
- * then configure a default palette map.
- */
- if ((lconfig->pixfmt != cfg->pixfmt) &&
- ((lconfig->pixfmt == PIXFMT_1BPP) ||
- (lconfig->pixfmt == PIXFMT_2BPP) ||
- (lconfig->pixfmt == PIXFMT_4BPP))) {
- enum osd_win_layer osdwin =
- ((layer == WIN_OSD0) ? OSDWIN_OSD0 : OSDWIN_OSD1);
- struct osd_osdwin_state *osdwin_state =
- &osd->osdwin[osdwin];
- unsigned char clut_index;
- unsigned char clut_entries = 0;
-
- switch (lconfig->pixfmt) {
- case PIXFMT_1BPP:
- clut_entries = 2;
- break;
- case PIXFMT_2BPP:
- clut_entries = 4;
- break;
- case PIXFMT_4BPP:
- clut_entries = 16;
- break;
- default:
- break;
- }
- /*
- * The default palette map maps the pixel value to the clut
- * index, i.e. pixel value 0 maps to clut entry 0, pixel value
- * 1 maps to clut entry 1, etc.
- */
- for (clut_index = 0; clut_index < 16; clut_index++) {
- osdwin_state->palette_map[clut_index] = clut_index;
- if (clut_index < clut_entries) {
- _osd_set_palette_map(sd, osdwin, clut_index,
- clut_index,
- lconfig->pixfmt);
- }
- }
- }
-
- *cfg = *lconfig;
- /* DM6446: configure the RGB888 enable and window selection */
- if (osd->win[WIN_VID0].lconfig.pixfmt == PIXFMT_RGB888)
- _osd_enable_vid_rgb888(sd, WIN_VID0);
- else if (osd->win[WIN_VID1].lconfig.pixfmt == PIXFMT_RGB888)
- _osd_enable_vid_rgb888(sd, WIN_VID1);
- else
- _osd_disable_vid_rgb888(sd);
-
- if (layer == WIN_VID0) {
- osd->pingpong =
- _osd_dm6446_vid0_pingpong(sd, osd->field_inversion,
- win->fb_base_phys,
- cfg);
- }
-
- spin_unlock_irqrestore(&osd->lock, flags);
-
- return 0;
-}
-
-static void osd_init_layer(struct osd_state *sd, enum osd_layer layer)
-{
- struct osd_state *osd = sd;
- struct osd_window_state *win = &osd->win[layer];
- enum osd_win_layer osdwin;
- struct osd_osdwin_state *osdwin_state;
- struct osd_layer_config *cfg = &win->lconfig;
- unsigned long flags;
-
- spin_lock_irqsave(&osd->lock, flags);
-
- win->is_enabled = 0;
- _osd_disable_layer(sd, layer);
-
- win->h_zoom = ZOOM_X1;
- win->v_zoom = ZOOM_X1;
- _osd_set_zoom(sd, layer, win->h_zoom, win->v_zoom);
-
- win->fb_base_phys = 0;
- _osd_start_layer(sd, layer, win->fb_base_phys, 0);
-
- cfg->line_length = 0;
- cfg->xsize = 0;
- cfg->ysize = 0;
- cfg->xpos = 0;
- cfg->ypos = 0;
- cfg->interlaced = 0;
- switch (layer) {
- case WIN_OSD0:
- case WIN_OSD1:
- osdwin = (layer == WIN_OSD0) ? OSDWIN_OSD0 : OSDWIN_OSD1;
- osdwin_state = &osd->osdwin[osdwin];
- /*
- * Other code relies on the fact that OSD windows default to a
- * bitmap pixel format when they are deallocated, so don't
- * change this default pixel format.
- */
- cfg->pixfmt = PIXFMT_8BPP;
- _osd_set_layer_config(sd, layer, cfg);
- osdwin_state->clut = RAM_CLUT;
- _osd_set_osd_clut(sd, osdwin, osdwin_state->clut);
- osdwin_state->colorkey_blending = 0;
- _osd_disable_color_key(sd, osdwin);
- osdwin_state->blend = OSD_8_VID_0;
- _osd_set_blending_factor(sd, osdwin, osdwin_state->blend);
- osdwin_state->rec601_attenuation = 0;
- _osd_set_rec601_attenuation(sd, osdwin,
- osdwin_state->
- rec601_attenuation);
- if (osdwin == OSDWIN_OSD1) {
- osd->is_blinking = 0;
- osd->blink = BLINK_X1;
- }
- break;
- case WIN_VID0:
- case WIN_VID1:
- cfg->pixfmt = osd->yc_pixfmt;
- _osd_set_layer_config(sd, layer, cfg);
- break;
- }
-
- spin_unlock_irqrestore(&osd->lock, flags);
-}
-
-static void osd_release_layer(struct osd_state *sd, enum osd_layer layer)
-{
- struct osd_state *osd = sd;
- struct osd_window_state *win = &osd->win[layer];
- unsigned long flags;
-
- spin_lock_irqsave(&osd->lock, flags);
-
- if (!win->is_allocated) {
- spin_unlock_irqrestore(&osd->lock, flags);
- return;
- }
-
- spin_unlock_irqrestore(&osd->lock, flags);
- osd_init_layer(sd, layer);
- spin_lock_irqsave(&osd->lock, flags);
-
- win->is_allocated = 0;
-
- spin_unlock_irqrestore(&osd->lock, flags);
-}
-
-static int osd_request_layer(struct osd_state *sd, enum osd_layer layer)
-{
- struct osd_state *osd = sd;
- struct osd_window_state *win = &osd->win[layer];
- unsigned long flags;
-
- spin_lock_irqsave(&osd->lock, flags);
-
- if (win->is_allocated) {
- spin_unlock_irqrestore(&osd->lock, flags);
- return -1;
- }
- win->is_allocated = 1;
-
- spin_unlock_irqrestore(&osd->lock, flags);
-
- return 0;
-}
-
-static void _osd_init(struct osd_state *sd)
-{
- osd_write(sd, 0, OSD_MODE);
- osd_write(sd, 0, OSD_VIDWINMD);
- osd_write(sd, 0, OSD_OSDWIN0MD);
- osd_write(sd, 0, OSD_OSDWIN1MD);
- osd_write(sd, 0, OSD_RECTCUR);
- osd_write(sd, 0, OSD_MISCCTL);
- if (sd->vpbe_type == VPBE_VERSION_3) {
- osd_write(sd, 0, OSD_VBNDRY);
- osd_write(sd, 0, OSD_EXTMODE);
- osd_write(sd, OSD_MISCCTL_DMANG, OSD_MISCCTL);
- }
-}
-
-static void osd_set_left_margin(struct osd_state *sd, u32 val)
-{
- osd_write(sd, val, OSD_BASEPX);
-}
-
-static void osd_set_top_margin(struct osd_state *sd, u32 val)
-{
- osd_write(sd, val, OSD_BASEPY);
-}
-
-static int osd_initialize(struct osd_state *osd)
-{
- if (osd == NULL)
- return -ENODEV;
- _osd_init(osd);
-
- /* set default Cb/Cr order */
- osd->yc_pixfmt = PIXFMT_YCbCrI;
-
- if (osd->vpbe_type == VPBE_VERSION_3) {
- /*
- * ROM CLUT1 on the DM355 is similar (identical?) to ROM CLUT0
- * on the DM6446, so make ROM_CLUT1 the default on the DM355.
- */
- osd->rom_clut = ROM_CLUT1;
- }
-
- _osd_set_field_inversion(osd, osd->field_inversion);
- _osd_set_rom_clut(osd, osd->rom_clut);
-
- osd_init_layer(osd, WIN_OSD0);
- osd_init_layer(osd, WIN_VID0);
- osd_init_layer(osd, WIN_OSD1);
- osd_init_layer(osd, WIN_VID1);
-
- return 0;
-}
-
-static const struct vpbe_osd_ops osd_ops = {
- .initialize = osd_initialize,
- .request_layer = osd_request_layer,
- .release_layer = osd_release_layer,
- .enable_layer = osd_enable_layer,
- .disable_layer = osd_disable_layer,
- .set_layer_config = osd_set_layer_config,
- .get_layer_config = osd_get_layer_config,
- .start_layer = osd_start_layer,
- .set_left_margin = osd_set_left_margin,
- .set_top_margin = osd_set_top_margin,
-};
-
-static int osd_probe(struct platform_device *pdev)
-{
- struct osd_platform_data *pdata;
- struct osd_state *osd;
- struct resource *res;
- int ret = 0;
-
- osd = kzalloc(sizeof(struct osd_state), GFP_KERNEL);
- if (osd == NULL)
- return -ENOMEM;
-
- osd->dev = &pdev->dev;
- pdata = (struct osd_platform_data *)pdev->dev.platform_data;
- osd->vpbe_type = (enum vpbe_version)pdata->vpbe_type;
- if (NULL == pdev->dev.platform_data) {
- dev_err(osd->dev, "No platform data defined for OSD"
- " sub device\n");
- ret = -ENOENT;
- goto free_mem;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(osd->dev, "Unable to get OSD register address map\n");
- ret = -ENODEV;
- goto free_mem;
- }
- osd->osd_base_phys = res->start;
- osd->osd_size = resource_size(res);
- if (!request_mem_region(osd->osd_base_phys, osd->osd_size,
- MODULE_NAME)) {
- dev_err(osd->dev, "Unable to reserve OSD MMIO region\n");
- ret = -ENODEV;
- goto free_mem;
- }
- osd->osd_base = (unsigned long)ioremap_nocache(res->start,
- osd->osd_size);
- if (!osd->osd_base) {
- dev_err(osd->dev, "Unable to map the OSD region\n");
- ret = -ENODEV;
- goto release_mem_region;
- }
- spin_lock_init(&osd->lock);
- osd->ops = osd_ops;
- platform_set_drvdata(pdev, osd);
- dev_notice(osd->dev, "OSD sub device probe success\n");
- return ret;
-
-release_mem_region:
- release_mem_region(osd->osd_base_phys, osd->osd_size);
-free_mem:
- kfree(osd);
- return ret;
-}
-
-static int osd_remove(struct platform_device *pdev)
-{
- struct osd_state *osd = platform_get_drvdata(pdev);
-
- iounmap((void *)osd->osd_base);
- release_mem_region(osd->osd_base_phys, osd->osd_size);
- kfree(osd);
- return 0;
-}
-
-static struct platform_driver osd_driver = {
- .probe = osd_probe,
- .remove = osd_remove,
- .driver = {
- .name = MODULE_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(osd_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("DaVinci OSD Manager Driver");
-MODULE_AUTHOR("Texas Instruments");
diff --git a/drivers/media/video/davinci/vpbe_osd_regs.h b/drivers/media/video/davinci/vpbe_osd_regs.h
deleted file mode 100644
index 584520f3af6..00000000000
--- a/drivers/media/video/davinci/vpbe_osd_regs.h
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright (C) 2006-2010 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef _VPBE_OSD_REGS_H
-#define _VPBE_OSD_REGS_H
-
-/* VPBE Global Registers */
-#define VPBE_PID 0x0
-#define VPBE_PCR 0x4
-
-/* VPSS CLock Registers */
-#define VPSSCLK_PID 0x00
-#define VPSSCLK_CLKCTRL 0x04
-
-/* VPSS Buffer Logic Registers */
-#define VPSSBL_PID 0x00
-#define VPSSBL_PCR 0x04
-#define VPSSBL_BCR 0x08
-#define VPSSBL_INTSTAT 0x0C
-#define VPSSBL_INTSEL 0x10
-#define VPSSBL_EVTSEL 0x14
-#define VPSSBL_MEMCTRL 0x18
-#define VPSSBL_CCDCMUX 0x1C
-
-/* DM365 ISP5 system configuration */
-#define ISP5_PID 0x0
-#define ISP5_PCCR 0x4
-#define ISP5_BCR 0x8
-#define ISP5_INTSTAT 0xC
-#define ISP5_INTSEL1 0x10
-#define ISP5_INTSEL2 0x14
-#define ISP5_INTSEL3 0x18
-#define ISP5_EVTSEL 0x1c
-#define ISP5_CCDCMUX 0x20
-
-/* VPBE On-Screen Display Subsystem Registers (OSD) */
-#define OSD_MODE 0x00
-#define OSD_VIDWINMD 0x04
-#define OSD_OSDWIN0MD 0x08
-#define OSD_OSDWIN1MD 0x0C
-#define OSD_OSDATRMD 0x0C
-#define OSD_RECTCUR 0x10
-#define OSD_VIDWIN0OFST 0x18
-#define OSD_VIDWIN1OFST 0x1C
-#define OSD_OSDWIN0OFST 0x20
-#define OSD_OSDWIN1OFST 0x24
-#define OSD_VIDWINADH 0x28
-#define OSD_VIDWIN0ADL 0x2C
-#define OSD_VIDWIN0ADR 0x2C
-#define OSD_VIDWIN1ADL 0x30
-#define OSD_VIDWIN1ADR 0x30
-#define OSD_OSDWINADH 0x34
-#define OSD_OSDWIN0ADL 0x38
-#define OSD_OSDWIN0ADR 0x38
-#define OSD_OSDWIN1ADL 0x3C
-#define OSD_OSDWIN1ADR 0x3C
-#define OSD_BASEPX 0x40
-#define OSD_BASEPY 0x44
-#define OSD_VIDWIN0XP 0x48
-#define OSD_VIDWIN0YP 0x4C
-#define OSD_VIDWIN0XL 0x50
-#define OSD_VIDWIN0YL 0x54
-#define OSD_VIDWIN1XP 0x58
-#define OSD_VIDWIN1YP 0x5C
-#define OSD_VIDWIN1XL 0x60
-#define OSD_VIDWIN1YL 0x64
-#define OSD_OSDWIN0XP 0x68
-#define OSD_OSDWIN0YP 0x6C
-#define OSD_OSDWIN0XL 0x70
-#define OSD_OSDWIN0YL 0x74
-#define OSD_OSDWIN1XP 0x78
-#define OSD_OSDWIN1YP 0x7C
-#define OSD_OSDWIN1XL 0x80
-#define OSD_OSDWIN1YL 0x84
-#define OSD_CURXP 0x88
-#define OSD_CURYP 0x8C
-#define OSD_CURXL 0x90
-#define OSD_CURYL 0x94
-#define OSD_W0BMP01 0xA0
-#define OSD_W0BMP23 0xA4
-#define OSD_W0BMP45 0xA8
-#define OSD_W0BMP67 0xAC
-#define OSD_W0BMP89 0xB0
-#define OSD_W0BMPAB 0xB4
-#define OSD_W0BMPCD 0xB8
-#define OSD_W0BMPEF 0xBC
-#define OSD_W1BMP01 0xC0
-#define OSD_W1BMP23 0xC4
-#define OSD_W1BMP45 0xC8
-#define OSD_W1BMP67 0xCC
-#define OSD_W1BMP89 0xD0
-#define OSD_W1BMPAB 0xD4
-#define OSD_W1BMPCD 0xD8
-#define OSD_W1BMPEF 0xDC
-#define OSD_VBNDRY 0xE0
-#define OSD_EXTMODE 0xE4
-#define OSD_MISCCTL 0xE8
-#define OSD_CLUTRAMYCB 0xEC
-#define OSD_CLUTRAMCR 0xF0
-#define OSD_TRANSPVAL 0xF4
-#define OSD_TRANSPVALL 0xF4
-#define OSD_TRANSPVALU 0xF8
-#define OSD_TRANSPBMPIDX 0xFC
-#define OSD_PPVWIN0ADR 0xFC
-
-/* bit definitions */
-#define VPBE_PCR_VENC_DIV (1 << 1)
-#define VPBE_PCR_CLK_OFF (1 << 0)
-
-#define VPSSBL_INTSTAT_HSSIINT (1 << 14)
-#define VPSSBL_INTSTAT_CFALDINT (1 << 13)
-#define VPSSBL_INTSTAT_IPIPE_INT5 (1 << 12)
-#define VPSSBL_INTSTAT_IPIPE_INT4 (1 << 11)
-#define VPSSBL_INTSTAT_IPIPE_INT3 (1 << 10)
-#define VPSSBL_INTSTAT_IPIPE_INT2 (1 << 9)
-#define VPSSBL_INTSTAT_IPIPE_INT1 (1 << 8)
-#define VPSSBL_INTSTAT_IPIPE_INT0 (1 << 7)
-#define VPSSBL_INTSTAT_IPIPEIFINT (1 << 6)
-#define VPSSBL_INTSTAT_OSDINT (1 << 5)
-#define VPSSBL_INTSTAT_VENCINT (1 << 4)
-#define VPSSBL_INTSTAT_H3AINT (1 << 3)
-#define VPSSBL_INTSTAT_CCDC_VDINT2 (1 << 2)
-#define VPSSBL_INTSTAT_CCDC_VDINT1 (1 << 1)
-#define VPSSBL_INTSTAT_CCDC_VDINT0 (1 << 0)
-
-/* DM365 ISP5 bit definitions */
-#define ISP5_INTSTAT_VENCINT (1 << 21)
-#define ISP5_INTSTAT_OSDINT (1 << 20)
-
-/* VMOD TVTYP options for HDMD=0 */
-#define SDTV_NTSC 0
-#define SDTV_PAL 1
-/* VMOD TVTYP options for HDMD=1 */
-#define HDTV_525P 0
-#define HDTV_625P 1
-#define HDTV_1080I 2
-#define HDTV_720P 3
-
-#define OSD_MODE_CS (1 << 15)
-#define OSD_MODE_OVRSZ (1 << 14)
-#define OSD_MODE_OHRSZ (1 << 13)
-#define OSD_MODE_EF (1 << 12)
-#define OSD_MODE_VVRSZ (1 << 11)
-#define OSD_MODE_VHRSZ (1 << 10)
-#define OSD_MODE_FSINV (1 << 9)
-#define OSD_MODE_BCLUT (1 << 8)
-#define OSD_MODE_CABG_SHIFT 0
-#define OSD_MODE_CABG (0xff << 0)
-
-#define OSD_VIDWINMD_VFINV (1 << 15)
-#define OSD_VIDWINMD_V1EFC (1 << 14)
-#define OSD_VIDWINMD_VHZ1_SHIFT 12
-#define OSD_VIDWINMD_VHZ1 (3 << 12)
-#define OSD_VIDWINMD_VVZ1_SHIFT 10
-#define OSD_VIDWINMD_VVZ1 (3 << 10)
-#define OSD_VIDWINMD_VFF1 (1 << 9)
-#define OSD_VIDWINMD_ACT1 (1 << 8)
-#define OSD_VIDWINMD_V0EFC (1 << 6)
-#define OSD_VIDWINMD_VHZ0_SHIFT 4
-#define OSD_VIDWINMD_VHZ0 (3 << 4)
-#define OSD_VIDWINMD_VVZ0_SHIFT 2
-#define OSD_VIDWINMD_VVZ0 (3 << 2)
-#define OSD_VIDWINMD_VFF0 (1 << 1)
-#define OSD_VIDWINMD_ACT0 (1 << 0)
-
-#define OSD_OSDWIN0MD_ATN0E (1 << 14)
-#define OSD_OSDWIN0MD_RGB0E (1 << 13)
-#define OSD_OSDWIN0MD_BMP0MD_SHIFT 13
-#define OSD_OSDWIN0MD_BMP0MD (3 << 13)
-#define OSD_OSDWIN0MD_CLUTS0 (1 << 12)
-#define OSD_OSDWIN0MD_OHZ0_SHIFT 10
-#define OSD_OSDWIN0MD_OHZ0 (3 << 10)
-#define OSD_OSDWIN0MD_OVZ0_SHIFT 8
-#define OSD_OSDWIN0MD_OVZ0 (3 << 8)
-#define OSD_OSDWIN0MD_BMW0_SHIFT 6
-#define OSD_OSDWIN0MD_BMW0 (3 << 6)
-#define OSD_OSDWIN0MD_BLND0_SHIFT 3
-#define OSD_OSDWIN0MD_BLND0 (7 << 3)
-#define OSD_OSDWIN0MD_TE0 (1 << 2)
-#define OSD_OSDWIN0MD_OFF0 (1 << 1)
-#define OSD_OSDWIN0MD_OACT0 (1 << 0)
-
-#define OSD_OSDWIN1MD_OASW (1 << 15)
-#define OSD_OSDWIN1MD_ATN1E (1 << 14)
-#define OSD_OSDWIN1MD_RGB1E (1 << 13)
-#define OSD_OSDWIN1MD_BMP1MD_SHIFT 13
-#define OSD_OSDWIN1MD_BMP1MD (3 << 13)
-#define OSD_OSDWIN1MD_CLUTS1 (1 << 12)
-#define OSD_OSDWIN1MD_OHZ1_SHIFT 10
-#define OSD_OSDWIN1MD_OHZ1 (3 << 10)
-#define OSD_OSDWIN1MD_OVZ1_SHIFT 8
-#define OSD_OSDWIN1MD_OVZ1 (3 << 8)
-#define OSD_OSDWIN1MD_BMW1_SHIFT 6
-#define OSD_OSDWIN1MD_BMW1 (3 << 6)
-#define OSD_OSDWIN1MD_BLND1_SHIFT 3
-#define OSD_OSDWIN1MD_BLND1 (7 << 3)
-#define OSD_OSDWIN1MD_TE1 (1 << 2)
-#define OSD_OSDWIN1MD_OFF1 (1 << 1)
-#define OSD_OSDWIN1MD_OACT1 (1 << 0)
-
-#define OSD_OSDATRMD_OASW (1 << 15)
-#define OSD_OSDATRMD_OHZA_SHIFT 10
-#define OSD_OSDATRMD_OHZA (3 << 10)
-#define OSD_OSDATRMD_OVZA_SHIFT 8
-#define OSD_OSDATRMD_OVZA (3 << 8)
-#define OSD_OSDATRMD_BLNKINT_SHIFT 6
-#define OSD_OSDATRMD_BLNKINT (3 << 6)
-#define OSD_OSDATRMD_OFFA (1 << 1)
-#define OSD_OSDATRMD_BLNK (1 << 0)
-
-#define OSD_RECTCUR_RCAD_SHIFT 8
-#define OSD_RECTCUR_RCAD (0xff << 8)
-#define OSD_RECTCUR_CLUTSR (1 << 7)
-#define OSD_RECTCUR_RCHW_SHIFT 4
-#define OSD_RECTCUR_RCHW (7 << 4)
-#define OSD_RECTCUR_RCVW_SHIFT 1
-#define OSD_RECTCUR_RCVW (7 << 1)
-#define OSD_RECTCUR_RCACT (1 << 0)
-
-#define OSD_VIDWIN0OFST_V0LO (0x1ff << 0)
-
-#define OSD_VIDWIN1OFST_V1LO (0x1ff << 0)
-
-#define OSD_OSDWIN0OFST_O0LO (0x1ff << 0)
-
-#define OSD_OSDWIN1OFST_O1LO (0x1ff << 0)
-
-#define OSD_WINOFST_AH_SHIFT 9
-
-#define OSD_VIDWIN0OFST_V0AH (0xf << 9)
-#define OSD_VIDWIN1OFST_V1AH (0xf << 9)
-#define OSD_OSDWIN0OFST_O0AH (0xf << 9)
-#define OSD_OSDWIN1OFST_O1AH (0xf << 9)
-
-#define OSD_VIDWINADH_V1AH_SHIFT 8
-#define OSD_VIDWINADH_V1AH (0x7f << 8)
-#define OSD_VIDWINADH_V0AH_SHIFT 0
-#define OSD_VIDWINADH_V0AH (0x7f << 0)
-
-#define OSD_VIDWIN0ADL_V0AL (0xffff << 0)
-
-#define OSD_VIDWIN1ADL_V1AL (0xffff << 0)
-
-#define OSD_OSDWINADH_O1AH_SHIFT 8
-#define OSD_OSDWINADH_O1AH (0x7f << 8)
-#define OSD_OSDWINADH_O0AH_SHIFT 0
-#define OSD_OSDWINADH_O0AH (0x7f << 0)
-
-#define OSD_OSDWIN0ADL_O0AL (0xffff << 0)
-
-#define OSD_OSDWIN1ADL_O1AL (0xffff << 0)
-
-#define OSD_BASEPX_BPX (0x3ff << 0)
-
-#define OSD_BASEPY_BPY (0x1ff << 0)
-
-#define OSD_VIDWIN0XP_V0X (0x7ff << 0)
-
-#define OSD_VIDWIN0YP_V0Y (0x7ff << 0)
-
-#define OSD_VIDWIN0XL_V0W (0x7ff << 0)
-
-#define OSD_VIDWIN0YL_V0H (0x7ff << 0)
-
-#define OSD_VIDWIN1XP_V1X (0x7ff << 0)
-
-#define OSD_VIDWIN1YP_V1Y (0x7ff << 0)
-
-#define OSD_VIDWIN1XL_V1W (0x7ff << 0)
-
-#define OSD_VIDWIN1YL_V1H (0x7ff << 0)
-
-#define OSD_OSDWIN0XP_W0X (0x7ff << 0)
-
-#define OSD_OSDWIN0YP_W0Y (0x7ff << 0)
-
-#define OSD_OSDWIN0XL_W0W (0x7ff << 0)
-
-#define OSD_OSDWIN0YL_W0H (0x7ff << 0)
-
-#define OSD_OSDWIN1XP_W1X (0x7ff << 0)
-
-#define OSD_OSDWIN1YP_W1Y (0x7ff << 0)
-
-#define OSD_OSDWIN1XL_W1W (0x7ff << 0)
-
-#define OSD_OSDWIN1YL_W1H (0x7ff << 0)
-
-#define OSD_CURXP_RCSX (0x7ff << 0)
-
-#define OSD_CURYP_RCSY (0x7ff << 0)
-
-#define OSD_CURXL_RCSW (0x7ff << 0)
-
-#define OSD_CURYL_RCSH (0x7ff << 0)
-
-#define OSD_EXTMODE_EXPMDSEL (1 << 15)
-#define OSD_EXTMODE_SCRNHEXP_SHIFT 13
-#define OSD_EXTMODE_SCRNHEXP (3 << 13)
-#define OSD_EXTMODE_SCRNVEXP (1 << 12)
-#define OSD_EXTMODE_OSD1BLDCHR (1 << 11)
-#define OSD_EXTMODE_OSD0BLDCHR (1 << 10)
-#define OSD_EXTMODE_ATNOSD1EN (1 << 9)
-#define OSD_EXTMODE_ATNOSD0EN (1 << 8)
-#define OSD_EXTMODE_OSDHRSZ15 (1 << 7)
-#define OSD_EXTMODE_VIDHRSZ15 (1 << 6)
-#define OSD_EXTMODE_ZMFILV1HEN (1 << 5)
-#define OSD_EXTMODE_ZMFILV1VEN (1 << 4)
-#define OSD_EXTMODE_ZMFILV0HEN (1 << 3)
-#define OSD_EXTMODE_ZMFILV0VEN (1 << 2)
-#define OSD_EXTMODE_EXPFILHEN (1 << 1)
-#define OSD_EXTMODE_EXPFILVEN (1 << 0)
-
-#define OSD_MISCCTL_BLDSEL (1 << 15)
-#define OSD_MISCCTL_S420D (1 << 14)
-#define OSD_MISCCTL_BMAPT (1 << 13)
-#define OSD_MISCCTL_DM365M (1 << 12)
-#define OSD_MISCCTL_RGBEN (1 << 7)
-#define OSD_MISCCTL_RGBWIN (1 << 6)
-#define OSD_MISCCTL_DMANG (1 << 6)
-#define OSD_MISCCTL_TMON (1 << 5)
-#define OSD_MISCCTL_RSEL (1 << 4)
-#define OSD_MISCCTL_CPBSY (1 << 3)
-#define OSD_MISCCTL_PPSW (1 << 2)
-#define OSD_MISCCTL_PPRV (1 << 1)
-
-#define OSD_CLUTRAMYCB_Y_SHIFT 8
-#define OSD_CLUTRAMYCB_Y (0xff << 8)
-#define OSD_CLUTRAMYCB_CB_SHIFT 0
-#define OSD_CLUTRAMYCB_CB (0xff << 0)
-
-#define OSD_CLUTRAMCR_CR_SHIFT 8
-#define OSD_CLUTRAMCR_CR (0xff << 8)
-#define OSD_CLUTRAMCR_CADDR_SHIFT 0
-#define OSD_CLUTRAMCR_CADDR (0xff << 0)
-
-#define OSD_TRANSPVAL_RGBTRANS (0xffff << 0)
-
-#define OSD_TRANSPVALL_RGBL (0xffff << 0)
-
-#define OSD_TRANSPVALU_Y_SHIFT 8
-#define OSD_TRANSPVALU_Y (0xff << 8)
-#define OSD_TRANSPVALU_RGBU_SHIFT 0
-#define OSD_TRANSPVALU_RGBU (0xff << 0)
-
-#define OSD_TRANSPBMPIDX_BMP1_SHIFT 8
-#define OSD_TRANSPBMPIDX_BMP1 (0xff << 8)
-#define OSD_TRANSPBMPIDX_BMP0_SHIFT 0
-#define OSD_TRANSPBMPIDX_BMP0 0xff
-
-#endif /* _DAVINCI_VPBE_H_ */
diff --git a/drivers/media/video/davinci/vpbe_venc.c b/drivers/media/video/davinci/vpbe_venc.c
deleted file mode 100644
index 0302669622d..00000000000
--- a/drivers/media/video/davinci/vpbe_venc.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * Copyright (C) 2010 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ctype.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-
-#include <mach/hardware.h>
-#include <mach/mux.h>
-#include <linux/platform_data/i2c-davinci.h>
-
-#include <linux/io.h>
-
-#include <media/davinci/vpbe_types.h>
-#include <media/davinci/vpbe_venc.h>
-#include <media/davinci/vpss.h>
-#include <media/v4l2-device.h>
-
-#include "vpbe_venc_regs.h"
-
-#define MODULE_NAME VPBE_VENC_SUBDEV_NAME
-
-static int debug = 2;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level 0-2");
-
-struct venc_state {
- struct v4l2_subdev sd;
- struct venc_callback *callback;
- struct venc_platform_data *pdata;
- struct device *pdev;
- u32 output;
- v4l2_std_id std;
- spinlock_t lock;
- void __iomem *venc_base;
- void __iomem *vdaccfg_reg;
-};
-
-static inline struct venc_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct venc_state, sd);
-}
-
-static inline u32 venc_read(struct v4l2_subdev *sd, u32 offset)
-{
- struct venc_state *venc = to_state(sd);
-
- return readl(venc->venc_base + offset);
-}
-
-static inline u32 venc_write(struct v4l2_subdev *sd, u32 offset, u32 val)
-{
- struct venc_state *venc = to_state(sd);
-
- writel(val, (venc->venc_base + offset));
-
- return val;
-}
-
-static inline u32 venc_modify(struct v4l2_subdev *sd, u32 offset,
- u32 val, u32 mask)
-{
- u32 new_val = (venc_read(sd, offset) & ~mask) | (val & mask);
-
- venc_write(sd, offset, new_val);
-
- return new_val;
-}
-
-static inline u32 vdaccfg_write(struct v4l2_subdev *sd, u32 val)
-{
- struct venc_state *venc = to_state(sd);
-
- writel(val, venc->vdaccfg_reg);
-
- val = readl(venc->vdaccfg_reg);
-
- return val;
-}
-
-#define VDAC_COMPONENT 0x543
-#define VDAC_S_VIDEO 0x210
-/* This function sets the dac of the VPBE for various outputs
- */
-static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index)
-{
- switch (out_index) {
- case 0:
- v4l2_dbg(debug, 1, sd, "Setting output to Composite\n");
- venc_write(sd, VENC_DACSEL, 0);
- break;
- case 1:
- v4l2_dbg(debug, 1, sd, "Setting output to Component\n");
- venc_write(sd, VENC_DACSEL, VDAC_COMPONENT);
- break;
- case 2:
- v4l2_dbg(debug, 1, sd, "Setting output to S-video\n");
- venc_write(sd, VENC_DACSEL, VDAC_S_VIDEO);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable)
-{
- struct venc_state *venc = to_state(sd);
- struct venc_platform_data *pdata = venc->pdata;
- v4l2_dbg(debug, 2, sd, "venc_enabledigitaloutput\n");
-
- if (benable) {
- venc_write(sd, VENC_VMOD, 0);
- venc_write(sd, VENC_CVBS, 0);
- venc_write(sd, VENC_LCDOUT, 0);
- venc_write(sd, VENC_HSPLS, 0);
- venc_write(sd, VENC_HSTART, 0);
- venc_write(sd, VENC_HVALID, 0);
- venc_write(sd, VENC_HINT, 0);
- venc_write(sd, VENC_VSPLS, 0);
- venc_write(sd, VENC_VSTART, 0);
- venc_write(sd, VENC_VVALID, 0);
- venc_write(sd, VENC_VINT, 0);
- venc_write(sd, VENC_YCCCTL, 0);
- venc_write(sd, VENC_DACSEL, 0);
-
- } else {
- venc_write(sd, VENC_VMOD, 0);
- /* disable VCLK output pin enable */
- venc_write(sd, VENC_VIDCTL, 0x141);
-
- /* Disable output sync pins */
- venc_write(sd, VENC_SYNCCTL, 0);
-
- /* Disable DCLOCK */
- venc_write(sd, VENC_DCLKCTL, 0);
- venc_write(sd, VENC_DRGBX1, 0x0000057C);
-
- /* Disable LCD output control (accepting default polarity) */
- venc_write(sd, VENC_LCDOUT, 0);
- if (pdata->venc_type != VPBE_VERSION_3)
- venc_write(sd, VENC_CMPNT, 0x100);
- venc_write(sd, VENC_HSPLS, 0);
- venc_write(sd, VENC_HINT, 0);
- venc_write(sd, VENC_HSTART, 0);
- venc_write(sd, VENC_HVALID, 0);
-
- venc_write(sd, VENC_VSPLS, 0);
- venc_write(sd, VENC_VINT, 0);
- venc_write(sd, VENC_VSTART, 0);
- venc_write(sd, VENC_VVALID, 0);
-
- venc_write(sd, VENC_HSDLY, 0);
- venc_write(sd, VENC_VSDLY, 0);
-
- venc_write(sd, VENC_YCCCTL, 0);
- venc_write(sd, VENC_VSTARTA, 0);
-
- /* Set OSD clock and OSD Sync Adavance registers */
- venc_write(sd, VENC_OSDCLK0, 1);
- venc_write(sd, VENC_OSDCLK1, 2);
- }
-}
-
-#define VDAC_CONFIG_SD_V3 0x0E21A6B6
-#define VDAC_CONFIG_SD_V2 0x081141CF
-/*
- * setting NTSC mode
- */
-static int venc_set_ntsc(struct v4l2_subdev *sd)
-{
- u32 val;
- struct venc_state *venc = to_state(sd);
- struct venc_platform_data *pdata = venc->pdata;
-
- v4l2_dbg(debug, 2, sd, "venc_set_ntsc\n");
-
- /* Setup clock at VPSS & VENC for SD */
- vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
- if (pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_525_60) < 0)
- return -EINVAL;
-
- venc_enabledigitaloutput(sd, 0);
-
- if (pdata->venc_type == VPBE_VERSION_3) {
- venc_write(sd, VENC_CLKCTL, 0x01);
- venc_write(sd, VENC_VIDCTL, 0);
- val = vdaccfg_write(sd, VDAC_CONFIG_SD_V3);
- } else if (pdata->venc_type == VPBE_VERSION_2) {
- venc_write(sd, VENC_CLKCTL, 0x01);
- venc_write(sd, VENC_VIDCTL, 0);
- vdaccfg_write(sd, VDAC_CONFIG_SD_V2);
- } else {
- /* to set VENC CLK DIV to 1 - final clock is 54 MHz */
- venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
- /* Set REC656 Mode */
- venc_write(sd, VENC_YCCCTL, 0x1);
- venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ);
- venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS);
- }
-
- venc_write(sd, VENC_VMOD, 0);
- venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
- VENC_VMOD_VIE);
- venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
- venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_TVTYP_SHIFT),
- VENC_VMOD_TVTYP);
- venc_write(sd, VENC_DACTST, 0x0);
- venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
-
- return 0;
-}
-
-/*
- * setting PAL mode
- */
-static int venc_set_pal(struct v4l2_subdev *sd)
-{
- struct venc_state *venc = to_state(sd);
- struct venc_platform_data *pdata = venc->pdata;
-
- v4l2_dbg(debug, 2, sd, "venc_set_pal\n");
-
- /* Setup clock at VPSS & VENC for SD */
- vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
- if (venc->pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_625_50) < 0)
- return -EINVAL;
-
- venc_enabledigitaloutput(sd, 0);
-
- if (pdata->venc_type == VPBE_VERSION_3) {
- venc_write(sd, VENC_CLKCTL, 0x1);
- venc_write(sd, VENC_VIDCTL, 0);
- vdaccfg_write(sd, VDAC_CONFIG_SD_V3);
- } else if (pdata->venc_type == VPBE_VERSION_2) {
- venc_write(sd, VENC_CLKCTL, 0x1);
- venc_write(sd, VENC_VIDCTL, 0);
- vdaccfg_write(sd, VDAC_CONFIG_SD_V2);
- } else {
- /* to set VENC CLK DIV to 1 - final clock is 54 MHz */
- venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
- /* Set REC656 Mode */
- venc_write(sd, VENC_YCCCTL, 0x1);
- }
-
- venc_modify(sd, VENC_SYNCCTL, 1 << VENC_SYNCCTL_OVD_SHIFT,
- VENC_SYNCCTL_OVD);
- venc_write(sd, VENC_VMOD, 0);
- venc_modify(sd, VENC_VMOD,
- (1 << VENC_VMOD_VIE_SHIFT),
- VENC_VMOD_VIE);
- venc_modify(sd, VENC_VMOD,
- (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
- venc_modify(sd, VENC_VMOD,
- (1 << VENC_VMOD_TVTYP_SHIFT),
- VENC_VMOD_TVTYP);
- venc_write(sd, VENC_DACTST, 0x0);
- venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
-
- return 0;
-}
-
-#define VDAC_CONFIG_HD_V2 0x081141EF
-/*
- * venc_set_480p59_94
- *
- * This function configures the video encoder to EDTV(525p) component setting.
- */
-static int venc_set_480p59_94(struct v4l2_subdev *sd)
-{
- struct venc_state *venc = to_state(sd);
- struct venc_platform_data *pdata = venc->pdata;
-
- v4l2_dbg(debug, 2, sd, "venc_set_480p59_94\n");
- if ((pdata->venc_type != VPBE_VERSION_1) &&
- (pdata->venc_type != VPBE_VERSION_2))
- return -EINVAL;
-
- /* Setup clock at VPSS & VENC for SD */
- if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_480P59_94) < 0)
- return -EINVAL;
-
- venc_enabledigitaloutput(sd, 0);
-
- if (pdata->venc_type == VPBE_VERSION_2)
- vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
- venc_write(sd, VENC_OSDCLK0, 0);
- venc_write(sd, VENC_OSDCLK1, 1);
-
- if (pdata->venc_type == VPBE_VERSION_1) {
- venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
- VENC_VDPRO_DAFRQ);
- venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
- VENC_VDPRO_DAUPS);
- }
-
- venc_write(sd, VENC_VMOD, 0);
- venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
- VENC_VMOD_VIE);
- venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
- venc_modify(sd, VENC_VMOD, (HDTV_525P << VENC_VMOD_TVTYP_SHIFT),
- VENC_VMOD_TVTYP);
- venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
- VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
-
- venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
-
- return 0;
-}
-
-/*
- * venc_set_625p
- *
- * This function configures the video encoder to HDTV(625p) component setting
- */
-static int venc_set_576p50(struct v4l2_subdev *sd)
-{
- struct venc_state *venc = to_state(sd);
- struct venc_platform_data *pdata = venc->pdata;
-
- v4l2_dbg(debug, 2, sd, "venc_set_576p50\n");
-
- if ((pdata->venc_type != VPBE_VERSION_1) &&
- (pdata->venc_type != VPBE_VERSION_2))
- return -EINVAL;
- /* Setup clock at VPSS & VENC for SD */
- if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_576P50) < 0)
- return -EINVAL;
-
- venc_enabledigitaloutput(sd, 0);
-
- if (pdata->venc_type == VPBE_VERSION_2)
- vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
-
- venc_write(sd, VENC_OSDCLK0, 0);
- venc_write(sd, VENC_OSDCLK1, 1);
-
- if (pdata->venc_type == VPBE_VERSION_1) {
- venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
- VENC_VDPRO_DAFRQ);
- venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
- VENC_VDPRO_DAUPS);
- }
-
- venc_write(sd, VENC_VMOD, 0);
- venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
- VENC_VMOD_VIE);
- venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
- venc_modify(sd, VENC_VMOD, (HDTV_625P << VENC_VMOD_TVTYP_SHIFT),
- VENC_VMOD_TVTYP);
-
- venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
- VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
- venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
-
- return 0;
-}
-
-/*
- * venc_set_720p60_internal - Setup 720p60 in venc for dm365 only
- */
-static int venc_set_720p60_internal(struct v4l2_subdev *sd)
-{
- struct venc_state *venc = to_state(sd);
- struct venc_platform_data *pdata = venc->pdata;
-
- if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_720P60) < 0)
- return -EINVAL;
-
- venc_enabledigitaloutput(sd, 0);
-
- venc_write(sd, VENC_OSDCLK0, 0);
- venc_write(sd, VENC_OSDCLK1, 1);
-
- venc_write(sd, VENC_VMOD, 0);
- /* DM365 component HD mode */
- venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
- VENC_VMOD_VIE);
- venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
- venc_modify(sd, VENC_VMOD, (HDTV_720P << VENC_VMOD_TVTYP_SHIFT),
- VENC_VMOD_TVTYP);
- venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
- venc_write(sd, VENC_XHINTVL, 0);
- return 0;
-}
-
-/*
- * venc_set_1080i30_internal - Setup 1080i30 in venc for dm365 only
- */
-static int venc_set_1080i30_internal(struct v4l2_subdev *sd)
-{
- struct venc_state *venc = to_state(sd);
- struct venc_platform_data *pdata = venc->pdata;
-
- if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_1080P30) < 0)
- return -EINVAL;
-
- venc_enabledigitaloutput(sd, 0);
-
- venc_write(sd, VENC_OSDCLK0, 0);
- venc_write(sd, VENC_OSDCLK1, 1);
-
-
- venc_write(sd, VENC_VMOD, 0);
- /* DM365 component HD mode */
- venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
- VENC_VMOD_VIE);
- venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
- venc_modify(sd, VENC_VMOD, (HDTV_1080I << VENC_VMOD_TVTYP_SHIFT),
- VENC_VMOD_TVTYP);
- venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
- venc_write(sd, VENC_XHINTVL, 0);
- return 0;
-}
-
-static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
- v4l2_dbg(debug, 1, sd, "venc_s_std_output\n");
-
- if (norm & V4L2_STD_525_60)
- return venc_set_ntsc(sd);
- else if (norm & V4L2_STD_625_50)
- return venc_set_pal(sd);
-
- return -EINVAL;
-}
-
-static int venc_s_dv_preset(struct v4l2_subdev *sd,
- struct v4l2_dv_preset *dv_preset)
-{
- struct venc_state *venc = to_state(sd);
- int ret;
-
- v4l2_dbg(debug, 1, sd, "venc_s_dv_preset\n");
-
- if (dv_preset->preset == V4L2_DV_576P50)
- return venc_set_576p50(sd);
- else if (dv_preset->preset == V4L2_DV_480P59_94)
- return venc_set_480p59_94(sd);
- else if ((dv_preset->preset == V4L2_DV_720P60) &&
- (venc->pdata->venc_type == VPBE_VERSION_2)) {
- /* TBD setup internal 720p mode here */
- ret = venc_set_720p60_internal(sd);
- /* for DM365 VPBE, there is DAC inside */
- vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
- return ret;
- } else if ((dv_preset->preset == V4L2_DV_1080I30) &&
- (venc->pdata->venc_type == VPBE_VERSION_2)) {
- /* TBD setup internal 1080i mode here */
- ret = venc_set_1080i30_internal(sd);
- /* for DM365 VPBE, there is DAC inside */
- vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
- return ret;
- }
- return -EINVAL;
-}
-
-static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output,
- u32 config)
-{
- struct venc_state *venc = to_state(sd);
- int ret;
-
- v4l2_dbg(debug, 1, sd, "venc_s_routing\n");
-
- ret = venc_set_dac(sd, output);
- if (!ret)
- venc->output = output;
-
- return ret;
-}
-
-static long venc_ioctl(struct v4l2_subdev *sd,
- unsigned int cmd,
- void *arg)
-{
- u32 val;
-
- switch (cmd) {
- case VENC_GET_FLD:
- val = venc_read(sd, VENC_VSTAT);
- *((int *)arg) = ((val & VENC_VSTAT_FIDST) ==
- VENC_VSTAT_FIDST);
- break;
- default:
- v4l2_err(sd, "Wrong IOCTL cmd\n");
- break;
- }
-
- return 0;
-}
-
-static const struct v4l2_subdev_core_ops venc_core_ops = {
- .ioctl = venc_ioctl,
-};
-
-static const struct v4l2_subdev_video_ops venc_video_ops = {
- .s_routing = venc_s_routing,
- .s_std_output = venc_s_std_output,
- .s_dv_preset = venc_s_dv_preset,
-};
-
-static const struct v4l2_subdev_ops venc_ops = {
- .core = &venc_core_ops,
- .video = &venc_video_ops,
-};
-
-static int venc_initialize(struct v4l2_subdev *sd)
-{
- struct venc_state *venc = to_state(sd);
- int ret;
-
- /* Set default to output to composite and std to NTSC */
- venc->output = 0;
- venc->std = V4L2_STD_525_60;
-
- ret = venc_s_routing(sd, 0, venc->output, 0);
- if (ret < 0) {
- v4l2_err(sd, "Error setting output during init\n");
- return -EINVAL;
- }
-
- ret = venc_s_std_output(sd, venc->std);
- if (ret < 0) {
- v4l2_err(sd, "Error setting std during init\n");
- return -EINVAL;
- }
-
- return ret;
-}
-
-static int venc_device_get(struct device *dev, void *data)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct venc_state **venc = data;
-
- if (strcmp(MODULE_NAME, pdev->name) == 0)
- *venc = platform_get_drvdata(pdev);
-
- return 0;
-}
-
-struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev,
- const char *venc_name)
-{
- struct venc_state *venc;
- int err;
-
- err = bus_for_each_dev(&platform_bus_type, NULL, &venc,
- venc_device_get);
- if (venc == NULL)
- return NULL;
-
- v4l2_subdev_init(&venc->sd, &venc_ops);
-
- strcpy(venc->sd.name, venc_name);
- if (v4l2_device_register_subdev(v4l2_dev, &venc->sd) < 0) {
- v4l2_err(v4l2_dev,
- "vpbe unable to register venc sub device\n");
- return NULL;
- }
- if (venc_initialize(&venc->sd)) {
- v4l2_err(v4l2_dev,
- "vpbe venc initialization failed\n");
- return NULL;
- }
-
- return &venc->sd;
-}
-EXPORT_SYMBOL(venc_sub_dev_init);
-
-static int venc_probe(struct platform_device *pdev)
-{
- struct venc_state *venc;
- struct resource *res;
- int ret;
-
- venc = kzalloc(sizeof(struct venc_state), GFP_KERNEL);
- if (venc == NULL)
- return -ENOMEM;
-
- venc->pdev = &pdev->dev;
- venc->pdata = pdev->dev.platform_data;
- if (NULL == venc->pdata) {
- dev_err(venc->pdev, "Unable to get platform data for"
- " VENC sub device");
- ret = -ENOENT;
- goto free_mem;
- }
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(venc->pdev,
- "Unable to get VENC register address map\n");
- ret = -ENODEV;
- goto free_mem;
- }
-
- if (!request_mem_region(res->start, resource_size(res), "venc")) {
- dev_err(venc->pdev, "Unable to reserve VENC MMIO region\n");
- ret = -ENODEV;
- goto free_mem;
- }
-
- venc->venc_base = ioremap_nocache(res->start, resource_size(res));
- if (!venc->venc_base) {
- dev_err(venc->pdev, "Unable to map VENC IO space\n");
- ret = -ENODEV;
- goto release_venc_mem_region;
- }
-
- if (venc->pdata->venc_type != VPBE_VERSION_1) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!res) {
- dev_err(venc->pdev,
- "Unable to get VDAC_CONFIG address map\n");
- ret = -ENODEV;
- goto unmap_venc_io;
- }
-
- if (!request_mem_region(res->start,
- resource_size(res), "venc")) {
- dev_err(venc->pdev,
- "Unable to reserve VDAC_CONFIG MMIO region\n");
- ret = -ENODEV;
- goto unmap_venc_io;
- }
-
- venc->vdaccfg_reg = ioremap_nocache(res->start,
- resource_size(res));
- if (!venc->vdaccfg_reg) {
- dev_err(venc->pdev,
- "Unable to map VDAC_CONFIG IO space\n");
- ret = -ENODEV;
- goto release_vdaccfg_mem_region;
- }
- }
- spin_lock_init(&venc->lock);
- platform_set_drvdata(pdev, venc);
- dev_notice(venc->pdev, "VENC sub device probe success\n");
- return 0;
-
-release_vdaccfg_mem_region:
- release_mem_region(res->start, resource_size(res));
-unmap_venc_io:
- iounmap(venc->venc_base);
-release_venc_mem_region:
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, resource_size(res));
-free_mem:
- kfree(venc);
- return ret;
-}
-
-static int venc_remove(struct platform_device *pdev)
-{
- struct venc_state *venc = platform_get_drvdata(pdev);
- struct resource *res;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- iounmap((void *)venc->venc_base);
- release_mem_region(res->start, resource_size(res));
- if (venc->pdata->venc_type != VPBE_VERSION_1) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- iounmap((void *)venc->vdaccfg_reg);
- release_mem_region(res->start, resource_size(res));
- }
- kfree(venc);
-
- return 0;
-}
-
-static struct platform_driver venc_driver = {
- .probe = venc_probe,
- .remove = venc_remove,
- .driver = {
- .name = MODULE_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(venc_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("VPBE VENC Driver");
-MODULE_AUTHOR("Texas Instruments");
diff --git a/drivers/media/video/davinci/vpbe_venc_regs.h b/drivers/media/video/davinci/vpbe_venc_regs.h
deleted file mode 100644
index 947cb151077..00000000000
--- a/drivers/media/video/davinci/vpbe_venc_regs.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2006-2010 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2..
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef _VPBE_VENC_REGS_H
-#define _VPBE_VENC_REGS_H
-
-/* VPBE Video Encoder / Digital LCD Subsystem Registers (VENC) */
-#define VENC_VMOD 0x00
-#define VENC_VIDCTL 0x04
-#define VENC_VDPRO 0x08
-#define VENC_SYNCCTL 0x0C
-#define VENC_HSPLS 0x10
-#define VENC_VSPLS 0x14
-#define VENC_HINT 0x18
-#define VENC_HSTART 0x1C
-#define VENC_HVALID 0x20
-#define VENC_VINT 0x24
-#define VENC_VSTART 0x28
-#define VENC_VVALID 0x2C
-#define VENC_HSDLY 0x30
-#define VENC_VSDLY 0x34
-#define VENC_YCCCTL 0x38
-#define VENC_RGBCTL 0x3C
-#define VENC_RGBCLP 0x40
-#define VENC_LINECTL 0x44
-#define VENC_CULLLINE 0x48
-#define VENC_LCDOUT 0x4C
-#define VENC_BRTS 0x50
-#define VENC_BRTW 0x54
-#define VENC_ACCTL 0x58
-#define VENC_PWMP 0x5C
-#define VENC_PWMW 0x60
-#define VENC_DCLKCTL 0x64
-#define VENC_DCLKPTN0 0x68
-#define VENC_DCLKPTN1 0x6C
-#define VENC_DCLKPTN2 0x70
-#define VENC_DCLKPTN3 0x74
-#define VENC_DCLKPTN0A 0x78
-#define VENC_DCLKPTN1A 0x7C
-#define VENC_DCLKPTN2A 0x80
-#define VENC_DCLKPTN3A 0x84
-#define VENC_DCLKHS 0x88
-#define VENC_DCLKHSA 0x8C
-#define VENC_DCLKHR 0x90
-#define VENC_DCLKVS 0x94
-#define VENC_DCLKVR 0x98
-#define VENC_CAPCTL 0x9C
-#define VENC_CAPDO 0xA0
-#define VENC_CAPDE 0xA4
-#define VENC_ATR0 0xA8
-#define VENC_ATR1 0xAC
-#define VENC_ATR2 0xB0
-#define VENC_VSTAT 0xB8
-#define VENC_RAMADR 0xBC
-#define VENC_RAMPORT 0xC0
-#define VENC_DACTST 0xC4
-#define VENC_YCOLVL 0xC8
-#define VENC_SCPROG 0xCC
-#define VENC_CVBS 0xDC
-#define VENC_CMPNT 0xE0
-#define VENC_ETMG0 0xE4
-#define VENC_ETMG1 0xE8
-#define VENC_ETMG2 0xEC
-#define VENC_ETMG3 0xF0
-#define VENC_DACSEL 0xF4
-#define VENC_ARGBX0 0x100
-#define VENC_ARGBX1 0x104
-#define VENC_ARGBX2 0x108
-#define VENC_ARGBX3 0x10C
-#define VENC_ARGBX4 0x110
-#define VENC_DRGBX0 0x114
-#define VENC_DRGBX1 0x118
-#define VENC_DRGBX2 0x11C
-#define VENC_DRGBX3 0x120
-#define VENC_DRGBX4 0x124
-#define VENC_VSTARTA 0x128
-#define VENC_OSDCLK0 0x12C
-#define VENC_OSDCLK1 0x130
-#define VENC_HVLDCL0 0x134
-#define VENC_HVLDCL1 0x138
-#define VENC_OSDHADV 0x13C
-#define VENC_CLKCTL 0x140
-#define VENC_GAMCTL 0x144
-#define VENC_XHINTVL 0x174
-
-/* bit definitions */
-#define VPBE_PCR_VENC_DIV (1 << 1)
-#define VPBE_PCR_CLK_OFF (1 << 0)
-
-#define VENC_VMOD_VDMD_SHIFT 12
-#define VENC_VMOD_VDMD_YCBCR16 0
-#define VENC_VMOD_VDMD_YCBCR8 1
-#define VENC_VMOD_VDMD_RGB666 2
-#define VENC_VMOD_VDMD_RGB8 3
-#define VENC_VMOD_VDMD_EPSON 4
-#define VENC_VMOD_VDMD_CASIO 5
-#define VENC_VMOD_VDMD_UDISPQVGA 6
-#define VENC_VMOD_VDMD_STNLCD 7
-#define VENC_VMOD_VIE_SHIFT 1
-#define VENC_VMOD_VDMD (7 << 12)
-#define VENC_VMOD_ITLCL (1 << 11)
-#define VENC_VMOD_ITLC (1 << 10)
-#define VENC_VMOD_NSIT (1 << 9)
-#define VENC_VMOD_HDMD (1 << 8)
-#define VENC_VMOD_TVTYP_SHIFT 6
-#define VENC_VMOD_TVTYP (3 << 6)
-#define VENC_VMOD_SLAVE (1 << 5)
-#define VENC_VMOD_VMD (1 << 4)
-#define VENC_VMOD_BLNK (1 << 3)
-#define VENC_VMOD_VIE (1 << 1)
-#define VENC_VMOD_VENC (1 << 0)
-
-/* VMOD TVTYP options for HDMD=0 */
-#define SDTV_NTSC 0
-#define SDTV_PAL 1
-/* VMOD TVTYP options for HDMD=1 */
-#define HDTV_525P 0
-#define HDTV_625P 1
-#define HDTV_1080I 2
-#define HDTV_720P 3
-
-#define VENC_VIDCTL_VCLKP (1 << 14)
-#define VENC_VIDCTL_VCLKE_SHIFT 13
-#define VENC_VIDCTL_VCLKE (1 << 13)
-#define VENC_VIDCTL_VCLKZ_SHIFT 12
-#define VENC_VIDCTL_VCLKZ (1 << 12)
-#define VENC_VIDCTL_SYDIR_SHIFT 8
-#define VENC_VIDCTL_SYDIR (1 << 8)
-#define VENC_VIDCTL_DOMD_SHIFT 4
-#define VENC_VIDCTL_DOMD (3 << 4)
-#define VENC_VIDCTL_YCDIR_SHIFT 0
-#define VENC_VIDCTL_YCDIR (1 << 0)
-
-#define VENC_VDPRO_ATYCC_SHIFT 5
-#define VENC_VDPRO_ATYCC (1 << 5)
-#define VENC_VDPRO_ATCOM_SHIFT 4
-#define VENC_VDPRO_ATCOM (1 << 4)
-#define VENC_VDPRO_DAFRQ (1 << 3)
-#define VENC_VDPRO_DAUPS (1 << 2)
-#define VENC_VDPRO_CUPS (1 << 1)
-#define VENC_VDPRO_YUPS (1 << 0)
-
-#define VENC_SYNCCTL_VPL_SHIFT 3
-#define VENC_SYNCCTL_VPL (1 << 3)
-#define VENC_SYNCCTL_HPL_SHIFT 2
-#define VENC_SYNCCTL_HPL (1 << 2)
-#define VENC_SYNCCTL_SYEV_SHIFT 1
-#define VENC_SYNCCTL_SYEV (1 << 1)
-#define VENC_SYNCCTL_SYEH_SHIFT 0
-#define VENC_SYNCCTL_SYEH (1 << 0)
-#define VENC_SYNCCTL_OVD_SHIFT 14
-#define VENC_SYNCCTL_OVD (1 << 14)
-
-#define VENC_DCLKCTL_DCKEC_SHIFT 11
-#define VENC_DCLKCTL_DCKEC (1 << 11)
-#define VENC_DCLKCTL_DCKPW_SHIFT 0
-#define VENC_DCLKCTL_DCKPW (0x3f << 0)
-
-#define VENC_VSTAT_FIDST (1 << 4)
-
-#define VENC_CMPNT_MRGB_SHIFT 14
-#define VENC_CMPNT_MRGB (1 << 14)
-
-#endif /* _VPBE_VENC_REGS_H */
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
deleted file mode 100644
index 49a845fb804..00000000000
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ /dev/null
@@ -1,2079 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Driver name : VPFE Capture driver
- * VPFE Capture driver allows applications to capture and stream video
- * frames on DaVinci SoCs (DM6446, DM355 etc) from a YUV source such as
- * TVP5146 or Raw Bayer RGB image data from an image sensor
- * such as Microns' MT9T001, MT9T031 etc.
- *
- * These SoCs have, in common, a Video Processing Subsystem (VPSS) that
- * consists of a Video Processing Front End (VPFE) for capturing
- * video/raw image data and Video Processing Back End (VPBE) for displaying
- * YUV data through an in-built analog encoder or Digital LCD port. This
- * driver is for capture through VPFE. A typical EVM using these SoCs have
- * following high level configuration.
- *
- *
- * decoder(TVP5146/ YUV/
- * MT9T001) --> Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
- * data input | |
- * V |
- * SDRAM |
- * V
- * Image Processor
- * |
- * V
- * SDRAM
- * The data flow happens from a decoder connected to the VPFE over a
- * YUV embedded (BT.656/BT.1120) or separate sync or raw bayer rgb interface
- * and to the input of VPFE through an optional MUX (if more inputs are
- * to be interfaced on the EVM). The input data is first passed through
- * CCDC (CCD Controller, a.k.a Image Sensor Interface, ISIF). The CCDC
- * does very little or no processing on YUV data and does pre-process Raw
- * Bayer RGB data through modules such as Defect Pixel Correction (DFC)
- * Color Space Conversion (CSC), data gain/offset etc. After this, data
- * can be written to SDRAM or can be connected to the image processing
- * block such as IPIPE (on DM355 only).
- *
- * Features supported
- * - MMAP IO
- * - Capture using TVP5146 over BT.656
- * - support for interfacing decoders using sub device model
- * - Work with DM355 or DM6446 CCDC to do Raw Bayer RGB/YUV
- * data capture to SDRAM.
- * TODO list
- * - Support multiple REQBUF after open
- * - Support for de-allocating buffers through REQBUF
- * - Support for Raw Bayer RGB capture
- * - Support for chaining Image Processor
- * - Support for static allocation of buffers
- * - Support for USERPTR IO
- * - Support for STREAMON before QBUF
- * - Support for control ioctls
- */
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <media/v4l2-common.h>
-#include <linux/io.h>
-#include <media/davinci/vpfe_capture.h>
-#include "ccdc_hw_device.h"
-
-static int debug;
-static u32 numbuffers = 3;
-static u32 bufsize = (720 * 576 * 2);
-
-module_param(numbuffers, uint, S_IRUGO);
-module_param(bufsize, uint, S_IRUGO);
-module_param(debug, int, 0644);
-
-MODULE_PARM_DESC(numbuffers, "buffer count (default:3)");
-MODULE_PARM_DESC(bufsize, "buffer size in bytes (default:720 x 576 x 2)");
-MODULE_PARM_DESC(debug, "Debug level 0-1");
-
-MODULE_DESCRIPTION("VPFE Video for Linux Capture Driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Texas Instruments");
-
-/* standard information */
-struct vpfe_standard {
- v4l2_std_id std_id;
- unsigned int width;
- unsigned int height;
- struct v4l2_fract pixelaspect;
- /* 0 - progressive, 1 - interlaced */
- int frame_format;
-};
-
-/* ccdc configuration */
-struct ccdc_config {
- /* This make sure vpfe is probed and ready to go */
- int vpfe_probed;
- /* name of ccdc device */
- char name[32];
-};
-
-/* data structures */
-static struct vpfe_config_params config_params = {
- .min_numbuffers = 3,
- .numbuffers = 3,
- .min_bufsize = 720 * 480 * 2,
- .device_bufsize = 720 * 576 * 2,
-};
-
-/* ccdc device registered */
-static struct ccdc_hw_device *ccdc_dev;
-/* lock for accessing ccdc information */
-static DEFINE_MUTEX(ccdc_lock);
-/* ccdc configuration */
-static struct ccdc_config *ccdc_cfg;
-
-const struct vpfe_standard vpfe_standards[] = {
- {V4L2_STD_525_60, 720, 480, {11, 10}, 1},
- {V4L2_STD_625_50, 720, 576, {54, 59}, 1},
-};
-
-/* Used when raw Bayer image from ccdc is directly captured to SDRAM */
-static const struct vpfe_pixel_format vpfe_pix_fmts[] = {
- {
- .fmtdesc = {
- .index = 0,
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- .description = "Bayer GrRBGb 8bit A-Law compr.",
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- },
- .bpp = 1,
- },
- {
- .fmtdesc = {
- .index = 1,
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- .description = "Bayer GrRBGb - 16bit",
- .pixelformat = V4L2_PIX_FMT_SBGGR16,
- },
- .bpp = 2,
- },
- {
- .fmtdesc = {
- .index = 2,
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- .description = "Bayer GrRBGb 8bit DPCM compr.",
- .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
- },
- .bpp = 1,
- },
- {
- .fmtdesc = {
- .index = 3,
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- .description = "YCbCr 4:2:2 Interleaved UYVY",
- .pixelformat = V4L2_PIX_FMT_UYVY,
- },
- .bpp = 2,
- },
- {
- .fmtdesc = {
- .index = 4,
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- .description = "YCbCr 4:2:2 Interleaved YUYV",
- .pixelformat = V4L2_PIX_FMT_YUYV,
- },
- .bpp = 2,
- },
- {
- .fmtdesc = {
- .index = 5,
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- .description = "Y/CbCr 4:2:0 - Semi planar",
- .pixelformat = V4L2_PIX_FMT_NV12,
- },
- .bpp = 1,
- },
-};
-
-/*
- * vpfe_lookup_pix_format()
- * lookup an entry in the vpfe pix format table based on pix_format
- */
-static const struct vpfe_pixel_format *vpfe_lookup_pix_format(u32 pix_format)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(vpfe_pix_fmts); i++) {
- if (pix_format == vpfe_pix_fmts[i].fmtdesc.pixelformat)
- return &vpfe_pix_fmts[i];
- }
- return NULL;
-}
-
-/*
- * vpfe_register_ccdc_device. CCDC module calls this to
- * register with vpfe capture
- */
-int vpfe_register_ccdc_device(struct ccdc_hw_device *dev)
-{
- int ret = 0;
- printk(KERN_NOTICE "vpfe_register_ccdc_device: %s\n", dev->name);
-
- BUG_ON(!dev->hw_ops.open);
- BUG_ON(!dev->hw_ops.enable);
- BUG_ON(!dev->hw_ops.set_hw_if_params);
- BUG_ON(!dev->hw_ops.configure);
- BUG_ON(!dev->hw_ops.set_buftype);
- BUG_ON(!dev->hw_ops.get_buftype);
- BUG_ON(!dev->hw_ops.enum_pix);
- BUG_ON(!dev->hw_ops.set_frame_format);
- BUG_ON(!dev->hw_ops.get_frame_format);
- BUG_ON(!dev->hw_ops.get_pixel_format);
- BUG_ON(!dev->hw_ops.set_pixel_format);
- BUG_ON(!dev->hw_ops.set_image_window);
- BUG_ON(!dev->hw_ops.get_image_window);
- BUG_ON(!dev->hw_ops.get_line_length);
- BUG_ON(!dev->hw_ops.getfid);
-
- mutex_lock(&ccdc_lock);
- if (NULL == ccdc_cfg) {
- /*
- * TODO. Will this ever happen? if so, we need to fix it.
- * Proabably we need to add the request to a linked list and
- * walk through it during vpfe probe
- */
- printk(KERN_ERR "vpfe capture not initialized\n");
- ret = -EFAULT;
- goto unlock;
- }
-
- if (strcmp(dev->name, ccdc_cfg->name)) {
- /* ignore this ccdc */
- ret = -EINVAL;
- goto unlock;
- }
-
- if (ccdc_dev) {
- printk(KERN_ERR "ccdc already registered\n");
- ret = -EINVAL;
- goto unlock;
- }
-
- ccdc_dev = dev;
-unlock:
- mutex_unlock(&ccdc_lock);
- return ret;
-}
-EXPORT_SYMBOL(vpfe_register_ccdc_device);
-
-/*
- * vpfe_unregister_ccdc_device. CCDC module calls this to
- * unregister with vpfe capture
- */
-void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev)
-{
- if (NULL == dev) {
- printk(KERN_ERR "invalid ccdc device ptr\n");
- return;
- }
-
- printk(KERN_NOTICE "vpfe_unregister_ccdc_device, dev->name = %s\n",
- dev->name);
-
- if (strcmp(dev->name, ccdc_cfg->name)) {
- /* ignore this ccdc */
- return;
- }
-
- mutex_lock(&ccdc_lock);
- ccdc_dev = NULL;
- mutex_unlock(&ccdc_lock);
- return;
-}
-EXPORT_SYMBOL(vpfe_unregister_ccdc_device);
-
-/*
- * vpfe_get_ccdc_image_format - Get image parameters based on CCDC settings
- */
-static int vpfe_get_ccdc_image_format(struct vpfe_device *vpfe_dev,
- struct v4l2_format *f)
-{
- struct v4l2_rect image_win;
- enum ccdc_buftype buf_type;
- enum ccdc_frmfmt frm_fmt;
-
- memset(f, 0, sizeof(*f));
- f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- ccdc_dev->hw_ops.get_image_window(&image_win);
- f->fmt.pix.width = image_win.width;
- f->fmt.pix.height = image_win.height;
- f->fmt.pix.bytesperline = ccdc_dev->hw_ops.get_line_length();
- f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
- f->fmt.pix.height;
- buf_type = ccdc_dev->hw_ops.get_buftype();
- f->fmt.pix.pixelformat = ccdc_dev->hw_ops.get_pixel_format();
- frm_fmt = ccdc_dev->hw_ops.get_frame_format();
- if (frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
- f->fmt.pix.field = V4L2_FIELD_NONE;
- else if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
- if (buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
- f->fmt.pix.field = V4L2_FIELD_INTERLACED;
- else if (buf_type == CCDC_BUFTYPE_FLD_SEPARATED)
- f->fmt.pix.field = V4L2_FIELD_SEQ_TB;
- else {
- v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf_type\n");
- return -EINVAL;
- }
- } else {
- v4l2_err(&vpfe_dev->v4l2_dev, "Invalid frm_fmt\n");
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * vpfe_config_ccdc_image_format()
- * For a pix format, configure ccdc to setup the capture
- */
-static int vpfe_config_ccdc_image_format(struct vpfe_device *vpfe_dev)
-{
- enum ccdc_frmfmt frm_fmt = CCDC_FRMFMT_INTERLACED;
- int ret = 0;
-
- if (ccdc_dev->hw_ops.set_pixel_format(
- vpfe_dev->fmt.fmt.pix.pixelformat) < 0) {
- v4l2_err(&vpfe_dev->v4l2_dev,
- "couldn't set pix format in ccdc\n");
- return -EINVAL;
- }
- /* configure the image window */
- ccdc_dev->hw_ops.set_image_window(&vpfe_dev->crop);
-
- switch (vpfe_dev->fmt.fmt.pix.field) {
- case V4L2_FIELD_INTERLACED:
- /* do nothing, since it is default */
- ret = ccdc_dev->hw_ops.set_buftype(
- CCDC_BUFTYPE_FLD_INTERLEAVED);
- break;
- case V4L2_FIELD_NONE:
- frm_fmt = CCDC_FRMFMT_PROGRESSIVE;
- /* buffer type only applicable for interlaced scan */
- break;
- case V4L2_FIELD_SEQ_TB:
- ret = ccdc_dev->hw_ops.set_buftype(
- CCDC_BUFTYPE_FLD_SEPARATED);
- break;
- default:
- return -EINVAL;
- }
-
- /* set the frame format */
- if (!ret)
- ret = ccdc_dev->hw_ops.set_frame_format(frm_fmt);
- return ret;
-}
-/*
- * vpfe_config_image_format()
- * For a given standard, this functions sets up the default
- * pix format & crop values in the vpfe device and ccdc. It first
- * starts with defaults based values from the standard table.
- * It then checks if sub device support g_mbus_fmt and then override the
- * values based on that.Sets crop values to match with scan resolution
- * starting at 0,0. It calls vpfe_config_ccdc_image_format() set the
- * values in ccdc
- */
-static int vpfe_config_image_format(struct vpfe_device *vpfe_dev,
- const v4l2_std_id *std_id)
-{
- struct vpfe_subdev_info *sdinfo = vpfe_dev->current_subdev;
- struct v4l2_mbus_framefmt mbus_fmt;
- struct v4l2_pix_format *pix = &vpfe_dev->fmt.fmt.pix;
- int i, ret = 0;
-
- for (i = 0; i < ARRAY_SIZE(vpfe_standards); i++) {
- if (vpfe_standards[i].std_id & *std_id) {
- vpfe_dev->std_info.active_pixels =
- vpfe_standards[i].width;
- vpfe_dev->std_info.active_lines =
- vpfe_standards[i].height;
- vpfe_dev->std_info.frame_format =
- vpfe_standards[i].frame_format;
- vpfe_dev->std_index = i;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(vpfe_standards)) {
- v4l2_err(&vpfe_dev->v4l2_dev, "standard not supported\n");
- return -EINVAL;
- }
-
- vpfe_dev->crop.top = 0;
- vpfe_dev->crop.left = 0;
- vpfe_dev->crop.width = vpfe_dev->std_info.active_pixels;
- vpfe_dev->crop.height = vpfe_dev->std_info.active_lines;
- pix->width = vpfe_dev->crop.width;
- pix->height = vpfe_dev->crop.height;
-
- /* first field and frame format based on standard frame format */
- if (vpfe_dev->std_info.frame_format) {
- pix->field = V4L2_FIELD_INTERLACED;
- /* assume V4L2_PIX_FMT_UYVY as default */
- pix->pixelformat = V4L2_PIX_FMT_UYVY;
- v4l2_fill_mbus_format(&mbus_fmt, pix,
- V4L2_MBUS_FMT_YUYV10_2X10);
- } else {
- pix->field = V4L2_FIELD_NONE;
- /* assume V4L2_PIX_FMT_SBGGR8 */
- pix->pixelformat = V4L2_PIX_FMT_SBGGR8;
- v4l2_fill_mbus_format(&mbus_fmt, pix,
- V4L2_MBUS_FMT_SBGGR8_1X8);
- }
-
- /* if sub device supports g_mbus_fmt, override the defaults */
- ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
- sdinfo->grp_id, video, g_mbus_fmt, &mbus_fmt);
-
- if (ret && ret != -ENOIOCTLCMD) {
- v4l2_err(&vpfe_dev->v4l2_dev,
- "error in getting g_mbus_fmt from sub device\n");
- return ret;
- }
- v4l2_fill_pix_format(pix, &mbus_fmt);
- pix->bytesperline = pix->width * 2;
- pix->sizeimage = pix->bytesperline * pix->height;
-
- /* Sets the values in CCDC */
- ret = vpfe_config_ccdc_image_format(vpfe_dev);
- if (ret)
- return ret;
-
- /* Update the values of sizeimage and bytesperline */
- if (!ret) {
- pix->bytesperline = ccdc_dev->hw_ops.get_line_length();
- pix->sizeimage = pix->bytesperline * pix->height;
- }
- return ret;
-}
-
-static int vpfe_initialize_device(struct vpfe_device *vpfe_dev)
-{
- int ret = 0;
-
- /* set first input of current subdevice as the current input */
- vpfe_dev->current_input = 0;
-
- /* set default standard */
- vpfe_dev->std_index = 0;
-
- /* Configure the default format information */
- ret = vpfe_config_image_format(vpfe_dev,
- &vpfe_standards[vpfe_dev->std_index].std_id);
- if (ret)
- return ret;
-
- /* now open the ccdc device to initialize it */
- mutex_lock(&ccdc_lock);
- if (NULL == ccdc_dev) {
- v4l2_err(&vpfe_dev->v4l2_dev, "ccdc device not registered\n");
- ret = -ENODEV;
- goto unlock;
- }
-
- if (!try_module_get(ccdc_dev->owner)) {
- v4l2_err(&vpfe_dev->v4l2_dev, "Couldn't lock ccdc module\n");
- ret = -ENODEV;
- goto unlock;
- }
- ret = ccdc_dev->hw_ops.open(vpfe_dev->pdev);
- if (!ret)
- vpfe_dev->initialized = 1;
-
- /* Clear all VPFE/CCDC interrupts */
- if (vpfe_dev->cfg->clr_intr)
- vpfe_dev->cfg->clr_intr(-1);
-
-unlock:
- mutex_unlock(&ccdc_lock);
- return ret;
-}
-
-/*
- * vpfe_open : It creates object of file handle structure and
- * stores it in private_data member of filepointer
- */
-static int vpfe_open(struct file *file)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- struct vpfe_fh *fh;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_open\n");
-
- if (!vpfe_dev->cfg->num_subdevs) {
- v4l2_err(&vpfe_dev->v4l2_dev, "No decoder registered\n");
- return -ENODEV;
- }
-
- /* Allocate memory for the file handle object */
- fh = kmalloc(sizeof(struct vpfe_fh), GFP_KERNEL);
- if (NULL == fh) {
- v4l2_err(&vpfe_dev->v4l2_dev,
- "unable to allocate memory for file handle object\n");
- return -ENOMEM;
- }
- /* store pointer to fh in private_data member of file */
- file->private_data = fh;
- fh->vpfe_dev = vpfe_dev;
- mutex_lock(&vpfe_dev->lock);
- /* If decoder is not initialized. initialize it */
- if (!vpfe_dev->initialized) {
- if (vpfe_initialize_device(vpfe_dev)) {
- mutex_unlock(&vpfe_dev->lock);
- return -ENODEV;
- }
- }
- /* Increment device usrs counter */
- vpfe_dev->usrs++;
- /* Set io_allowed member to false */
- fh->io_allowed = 0;
- /* Initialize priority of this instance to default priority */
- fh->prio = V4L2_PRIORITY_UNSET;
- v4l2_prio_open(&vpfe_dev->prio, &fh->prio);
- mutex_unlock(&vpfe_dev->lock);
- return 0;
-}
-
-static void vpfe_schedule_next_buffer(struct vpfe_device *vpfe_dev)
-{
- unsigned long addr;
-
- vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next,
- struct videobuf_buffer, queue);
- list_del(&vpfe_dev->next_frm->queue);
- vpfe_dev->next_frm->state = VIDEOBUF_ACTIVE;
- addr = videobuf_to_dma_contig(vpfe_dev->next_frm);
-
- ccdc_dev->hw_ops.setfbaddr(addr);
-}
-
-static void vpfe_schedule_bottom_field(struct vpfe_device *vpfe_dev)
-{
- unsigned long addr;
-
- addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
- addr += vpfe_dev->field_off;
- ccdc_dev->hw_ops.setfbaddr(addr);
-}
-
-static void vpfe_process_buffer_complete(struct vpfe_device *vpfe_dev)
-{
- struct timeval timevalue;
-
- do_gettimeofday(&timevalue);
- vpfe_dev->cur_frm->ts = timevalue;
- vpfe_dev->cur_frm->state = VIDEOBUF_DONE;
- vpfe_dev->cur_frm->size = vpfe_dev->fmt.fmt.pix.sizeimage;
- wake_up_interruptible(&vpfe_dev->cur_frm->done);
- vpfe_dev->cur_frm = vpfe_dev->next_frm;
-}
-
-/* ISR for VINT0*/
-static irqreturn_t vpfe_isr(int irq, void *dev_id)
-{
- struct vpfe_device *vpfe_dev = dev_id;
- enum v4l2_field field;
- int fid;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nStarting vpfe_isr...\n");
- field = vpfe_dev->fmt.fmt.pix.field;
-
- /* if streaming not started, don't do anything */
- if (!vpfe_dev->started)
- goto clear_intr;
-
- /* only for 6446 this will be applicable */
- if (NULL != ccdc_dev->hw_ops.reset)
- ccdc_dev->hw_ops.reset();
-
- if (field == V4L2_FIELD_NONE) {
- /* handle progressive frame capture */
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "frame format is progressive...\n");
- if (vpfe_dev->cur_frm != vpfe_dev->next_frm)
- vpfe_process_buffer_complete(vpfe_dev);
- goto clear_intr;
- }
-
- /* interlaced or TB capture check which field we are in hardware */
- fid = ccdc_dev->hw_ops.getfid();
-
- /* switch the software maintained field id */
- vpfe_dev->field_id ^= 1;
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "field id = %x:%x.\n",
- fid, vpfe_dev->field_id);
- if (fid == vpfe_dev->field_id) {
- /* we are in-sync here,continue */
- if (fid == 0) {
- /*
- * One frame is just being captured. If the next frame
- * is available, release the current frame and move on
- */
- if (vpfe_dev->cur_frm != vpfe_dev->next_frm)
- vpfe_process_buffer_complete(vpfe_dev);
- /*
- * based on whether the two fields are stored
- * interleavely or separately in memory, reconfigure
- * the CCDC memory address
- */
- if (field == V4L2_FIELD_SEQ_TB) {
- vpfe_schedule_bottom_field(vpfe_dev);
- }
- goto clear_intr;
- }
- /*
- * if one field is just being captured configure
- * the next frame get the next frame from the empty
- * queue if no frame is available hold on to the
- * current buffer
- */
- spin_lock(&vpfe_dev->dma_queue_lock);
- if (!list_empty(&vpfe_dev->dma_queue) &&
- vpfe_dev->cur_frm == vpfe_dev->next_frm)
- vpfe_schedule_next_buffer(vpfe_dev);
- spin_unlock(&vpfe_dev->dma_queue_lock);
- } else if (fid == 0) {
- /*
- * out of sync. Recover from any hardware out-of-sync.
- * May loose one frame
- */
- vpfe_dev->field_id = fid;
- }
-clear_intr:
- if (vpfe_dev->cfg->clr_intr)
- vpfe_dev->cfg->clr_intr(irq);
-
- return IRQ_HANDLED;
-}
-
-/* vdint1_isr - isr handler for VINT1 interrupt */
-static irqreturn_t vdint1_isr(int irq, void *dev_id)
-{
- struct vpfe_device *vpfe_dev = dev_id;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nInside vdint1_isr...\n");
-
- /* if streaming not started, don't do anything */
- if (!vpfe_dev->started) {
- if (vpfe_dev->cfg->clr_intr)
- vpfe_dev->cfg->clr_intr(irq);
- return IRQ_HANDLED;
- }
-
- spin_lock(&vpfe_dev->dma_queue_lock);
- if ((vpfe_dev->fmt.fmt.pix.field == V4L2_FIELD_NONE) &&
- !list_empty(&vpfe_dev->dma_queue) &&
- vpfe_dev->cur_frm == vpfe_dev->next_frm)
- vpfe_schedule_next_buffer(vpfe_dev);
- spin_unlock(&vpfe_dev->dma_queue_lock);
-
- if (vpfe_dev->cfg->clr_intr)
- vpfe_dev->cfg->clr_intr(irq);
-
- return IRQ_HANDLED;
-}
-
-static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
-{
- enum ccdc_frmfmt frame_format;
-
- frame_format = ccdc_dev->hw_ops.get_frame_format();
- if (frame_format == CCDC_FRMFMT_PROGRESSIVE)
- free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
-}
-
-static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
-{
- enum ccdc_frmfmt frame_format;
-
- frame_format = ccdc_dev->hw_ops.get_frame_format();
- if (frame_format == CCDC_FRMFMT_PROGRESSIVE) {
- return request_irq(vpfe_dev->ccdc_irq1, vdint1_isr,
- IRQF_DISABLED, "vpfe_capture1",
- vpfe_dev);
- }
- return 0;
-}
-
-/* vpfe_stop_ccdc_capture: stop streaming in ccdc/isif */
-static void vpfe_stop_ccdc_capture(struct vpfe_device *vpfe_dev)
-{
- vpfe_dev->started = 0;
- ccdc_dev->hw_ops.enable(0);
- if (ccdc_dev->hw_ops.enable_out_to_sdram)
- ccdc_dev->hw_ops.enable_out_to_sdram(0);
-}
-
-/*
- * vpfe_release : This function deletes buffer queue, frees the
- * buffers and the vpfe file handle
- */
-static int vpfe_release(struct file *file)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- struct vpfe_fh *fh = file->private_data;
- struct vpfe_subdev_info *sdinfo;
- int ret;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_release\n");
-
- /* Get the device lock */
- mutex_lock(&vpfe_dev->lock);
- /* if this instance is doing IO */
- if (fh->io_allowed) {
- if (vpfe_dev->started) {
- sdinfo = vpfe_dev->current_subdev;
- ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
- sdinfo->grp_id,
- video, s_stream, 0);
- if (ret && (ret != -ENOIOCTLCMD))
- v4l2_err(&vpfe_dev->v4l2_dev,
- "stream off failed in subdev\n");
- vpfe_stop_ccdc_capture(vpfe_dev);
- vpfe_detach_irq(vpfe_dev);
- videobuf_streamoff(&vpfe_dev->buffer_queue);
- }
- vpfe_dev->io_usrs = 0;
- vpfe_dev->numbuffers = config_params.numbuffers;
- }
-
- /* Decrement device usrs counter */
- vpfe_dev->usrs--;
- /* Close the priority */
- v4l2_prio_close(&vpfe_dev->prio, fh->prio);
- /* If this is the last file handle */
- if (!vpfe_dev->usrs) {
- vpfe_dev->initialized = 0;
- if (ccdc_dev->hw_ops.close)
- ccdc_dev->hw_ops.close(vpfe_dev->pdev);
- module_put(ccdc_dev->owner);
- }
- mutex_unlock(&vpfe_dev->lock);
- file->private_data = NULL;
- /* Free memory allocated to file handle object */
- kfree(fh);
- return 0;
-}
-
-/*
- * vpfe_mmap : It is used to map kernel space buffers
- * into user spaces
- */
-static int vpfe_mmap(struct file *file, struct vm_area_struct *vma)
-{
- /* Get the device object and file handle object */
- struct vpfe_device *vpfe_dev = video_drvdata(file);
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_mmap\n");
-
- return videobuf_mmap_mapper(&vpfe_dev->buffer_queue, vma);
-}
-
-/*
- * vpfe_poll: It is used for select/poll system call
- */
-static unsigned int vpfe_poll(struct file *file, poll_table *wait)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_poll\n");
-
- if (vpfe_dev->started)
- return videobuf_poll_stream(file,
- &vpfe_dev->buffer_queue, wait);
- return 0;
-}
-
-/* vpfe capture driver file operations */
-static const struct v4l2_file_operations vpfe_fops = {
- .owner = THIS_MODULE,
- .open = vpfe_open,
- .release = vpfe_release,
- .unlocked_ioctl = video_ioctl2,
- .mmap = vpfe_mmap,
- .poll = vpfe_poll
-};
-
-/*
- * vpfe_check_format()
- * This function adjust the input pixel format as per hardware
- * capabilities and update the same in pixfmt.
- * Following algorithm used :-
- *
- * If given pixformat is not in the vpfe list of pix formats or not
- * supported by the hardware, current value of pixformat in the device
- * is used
- * If given field is not supported, then current field is used. If field
- * is different from current, then it is matched with that from sub device.
- * Minimum height is 2 lines for interlaced or tb field and 1 line for
- * progressive. Maximum height is clamped to active active lines of scan
- * Minimum width is 32 bytes in memory and width is clamped to active
- * pixels of scan.
- * bytesperline is a multiple of 32.
- */
-static const struct vpfe_pixel_format *
- vpfe_check_format(struct vpfe_device *vpfe_dev,
- struct v4l2_pix_format *pixfmt)
-{
- u32 min_height = 1, min_width = 32, max_width, max_height;
- const struct vpfe_pixel_format *vpfe_pix_fmt;
- u32 pix;
- int temp, found;
-
- vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
- if (NULL == vpfe_pix_fmt) {
- /*
- * use current pixel format in the vpfe device. We
- * will find this pix format in the table
- */
- pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat;
- vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
- }
-
- /* check if hw supports it */
- temp = 0;
- found = 0;
- while (ccdc_dev->hw_ops.enum_pix(&pix, temp) >= 0) {
- if (vpfe_pix_fmt->fmtdesc.pixelformat == pix) {
- found = 1;
- break;
- }
- temp++;
- }
-
- if (!found) {
- /* use current pixel format */
- pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat;
- /*
- * Since this is currently used in the vpfe device, we
- * will find this pix format in the table
- */
- vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
- }
-
- /* check what field format is supported */
- if (pixfmt->field == V4L2_FIELD_ANY) {
- /* if field is any, use current value as default */
- pixfmt->field = vpfe_dev->fmt.fmt.pix.field;
- }
-
- /*
- * if field is not same as current field in the vpfe device
- * try matching the field with the sub device field
- */
- if (vpfe_dev->fmt.fmt.pix.field != pixfmt->field) {
- /*
- * If field value is not in the supported fields, use current
- * field used in the device as default
- */
- switch (pixfmt->field) {
- case V4L2_FIELD_INTERLACED:
- case V4L2_FIELD_SEQ_TB:
- /* if sub device is supporting progressive, use that */
- if (!vpfe_dev->std_info.frame_format)
- pixfmt->field = V4L2_FIELD_NONE;
- break;
- case V4L2_FIELD_NONE:
- if (vpfe_dev->std_info.frame_format)
- pixfmt->field = V4L2_FIELD_INTERLACED;
- break;
-
- default:
- /* use current field as default */
- pixfmt->field = vpfe_dev->fmt.fmt.pix.field;
- break;
- }
- }
-
- /* Now adjust image resolutions supported */
- if (pixfmt->field == V4L2_FIELD_INTERLACED ||
- pixfmt->field == V4L2_FIELD_SEQ_TB)
- min_height = 2;
-
- max_width = vpfe_dev->std_info.active_pixels;
- max_height = vpfe_dev->std_info.active_lines;
- min_width /= vpfe_pix_fmt->bpp;
-
- v4l2_info(&vpfe_dev->v4l2_dev, "width = %d, height = %d, bpp = %d\n",
- pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp);
-
- pixfmt->width = clamp((pixfmt->width), min_width, max_width);
- pixfmt->height = clamp((pixfmt->height), min_height, max_height);
-
- /* If interlaced, adjust height to be a multiple of 2 */
- if (pixfmt->field == V4L2_FIELD_INTERLACED)
- pixfmt->height &= (~1);
- /*
- * recalculate bytesperline and sizeimage since width
- * and height might have changed
- */
- pixfmt->bytesperline = (((pixfmt->width * vpfe_pix_fmt->bpp) + 31)
- & ~31);
- if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
- pixfmt->sizeimage =
- pixfmt->bytesperline * pixfmt->height +
- ((pixfmt->bytesperline * pixfmt->height) >> 1);
- else
- pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
-
- v4l2_info(&vpfe_dev->v4l2_dev, "adjusted width = %d, height ="
- " %d, bpp = %d, bytesperline = %d, sizeimage = %d\n",
- pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp,
- pixfmt->bytesperline, pixfmt->sizeimage);
- return vpfe_pix_fmt;
-}
-
-static int vpfe_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querycap\n");
-
- cap->version = VPFE_CAPTURE_VERSION_CODE;
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
- strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
- strlcpy(cap->bus_info, "VPFE", sizeof(cap->bus_info));
- strlcpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card));
- return 0;
-}
-
-static int vpfe_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- int ret = 0;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_fmt_vid_cap\n");
- /* Fill in the information about format */
- *fmt = vpfe_dev->fmt;
- return ret;
-}
-
-static int vpfe_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *fmt)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- const struct vpfe_pixel_format *pix_fmt;
- int temp_index;
- u32 pix;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt_vid_cap\n");
-
- if (ccdc_dev->hw_ops.enum_pix(&pix, fmt->index) < 0)
- return -EINVAL;
-
- /* Fill in the information about format */
- pix_fmt = vpfe_lookup_pix_format(pix);
- if (NULL != pix_fmt) {
- temp_index = fmt->index;
- *fmt = pix_fmt->fmtdesc;
- fmt->index = temp_index;
- return 0;
- }
- return -EINVAL;
-}
-
-static int vpfe_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- const struct vpfe_pixel_format *pix_fmts;
- int ret = 0;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt_vid_cap\n");
-
- /* If streaming is started, return error */
- if (vpfe_dev->started) {
- v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is started\n");
- return -EBUSY;
- }
-
- /* Check for valid frame format */
- pix_fmts = vpfe_check_format(vpfe_dev, &fmt->fmt.pix);
-
- if (NULL == pix_fmts)
- return -EINVAL;
-
- /* store the pixel format in the device object */
- ret = mutex_lock_interruptible(&vpfe_dev->lock);
- if (ret)
- return ret;
-
- /* First detach any IRQ if currently attached */
- vpfe_detach_irq(vpfe_dev);
- vpfe_dev->fmt = *fmt;
- /* set image capture parameters in the ccdc */
- ret = vpfe_config_ccdc_image_format(vpfe_dev);
- mutex_unlock(&vpfe_dev->lock);
- return ret;
-}
-
-static int vpfe_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- const struct vpfe_pixel_format *pix_fmts;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt_vid_cap\n");
-
- pix_fmts = vpfe_check_format(vpfe_dev, &f->fmt.pix);
- if (NULL == pix_fmts)
- return -EINVAL;
- return 0;
-}
-
-/*
- * vpfe_get_subdev_input_index - Get subdev index and subdev input index for a
- * given app input index
- */
-static int vpfe_get_subdev_input_index(struct vpfe_device *vpfe_dev,
- int *subdev_index,
- int *subdev_input_index,
- int app_input_index)
-{
- struct vpfe_config *cfg = vpfe_dev->cfg;
- struct vpfe_subdev_info *sdinfo;
- int i, j = 0;
-
- for (i = 0; i < cfg->num_subdevs; i++) {
- sdinfo = &cfg->sub_devs[i];
- if (app_input_index < (j + sdinfo->num_inputs)) {
- *subdev_index = i;
- *subdev_input_index = app_input_index - j;
- return 0;
- }
- j += sdinfo->num_inputs;
- }
- return -EINVAL;
-}
-
-/*
- * vpfe_get_app_input - Get app input index for a given subdev input index
- * driver stores the input index of the current sub device and translate it
- * when application request the current input
- */
-static int vpfe_get_app_input_index(struct vpfe_device *vpfe_dev,
- int *app_input_index)
-{
- struct vpfe_config *cfg = vpfe_dev->cfg;
- struct vpfe_subdev_info *sdinfo;
- int i, j = 0;
-
- for (i = 0; i < cfg->num_subdevs; i++) {
- sdinfo = &cfg->sub_devs[i];
- if (!strcmp(sdinfo->name, vpfe_dev->current_subdev->name)) {
- if (vpfe_dev->current_input >= sdinfo->num_inputs)
- return -1;
- *app_input_index = j + vpfe_dev->current_input;
- return 0;
- }
- j += sdinfo->num_inputs;
- }
- return -EINVAL;
-}
-
-static int vpfe_enum_input(struct file *file, void *priv,
- struct v4l2_input *inp)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- struct vpfe_subdev_info *sdinfo;
- int subdev, index ;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_input\n");
-
- if (vpfe_get_subdev_input_index(vpfe_dev,
- &subdev,
- &index,
- inp->index) < 0) {
- v4l2_err(&vpfe_dev->v4l2_dev, "input information not found"
- " for the subdev\n");
- return -EINVAL;
- }
- sdinfo = &vpfe_dev->cfg->sub_devs[subdev];
- memcpy(inp, &sdinfo->inputs[index], sizeof(struct v4l2_input));
- return 0;
-}
-
-static int vpfe_g_input(struct file *file, void *priv, unsigned int *index)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_input\n");
-
- return vpfe_get_app_input_index(vpfe_dev, index);
-}
-
-
-static int vpfe_s_input(struct file *file, void *priv, unsigned int index)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- struct vpfe_subdev_info *sdinfo;
- int subdev_index, inp_index;
- struct vpfe_route *route;
- u32 input = 0, output = 0;
- int ret = -EINVAL;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n");
-
- ret = mutex_lock_interruptible(&vpfe_dev->lock);
- if (ret)
- return ret;
-
- /*
- * If streaming is started return device busy
- * error
- */
- if (vpfe_dev->started) {
- v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is on\n");
- ret = -EBUSY;
- goto unlock_out;
- }
-
- if (vpfe_get_subdev_input_index(vpfe_dev,
- &subdev_index,
- &inp_index,
- index) < 0) {
- v4l2_err(&vpfe_dev->v4l2_dev, "invalid input index\n");
- goto unlock_out;
- }
-
- sdinfo = &vpfe_dev->cfg->sub_devs[subdev_index];
- route = &sdinfo->routes[inp_index];
- if (route && sdinfo->can_route) {
- input = route->input;
- output = route->output;
- }
-
- ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
- video, s_routing, input, output, 0);
-
- if (ret) {
- v4l2_err(&vpfe_dev->v4l2_dev,
- "vpfe_doioctl:error in setting input in decoder\n");
- ret = -EINVAL;
- goto unlock_out;
- }
- vpfe_dev->current_subdev = sdinfo;
- vpfe_dev->current_input = index;
- vpfe_dev->std_index = 0;
-
- /* set the bus/interface parameter for the sub device in ccdc */
- ret = ccdc_dev->hw_ops.set_hw_if_params(&sdinfo->ccdc_if_params);
- if (ret)
- goto unlock_out;
-
- /* set the default image parameters in the device */
- ret = vpfe_config_image_format(vpfe_dev,
- &vpfe_standards[vpfe_dev->std_index].std_id);
-unlock_out:
- mutex_unlock(&vpfe_dev->lock);
- return ret;
-}
-
-static int vpfe_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- struct vpfe_subdev_info *sdinfo;
- int ret = 0;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querystd\n");
-
- ret = mutex_lock_interruptible(&vpfe_dev->lock);
- sdinfo = vpfe_dev->current_subdev;
- if (ret)
- return ret;
- /* Call querystd function of decoder device */
- ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
- video, querystd, std_id);
- mutex_unlock(&vpfe_dev->lock);
- return ret;
-}
-
-static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- struct vpfe_subdev_info *sdinfo;
- int ret = 0;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n");
-
- /* Call decoder driver function to set the standard */
- ret = mutex_lock_interruptible(&vpfe_dev->lock);
- if (ret)
- return ret;
-
- sdinfo = vpfe_dev->current_subdev;
- /* If streaming is started, return device busy error */
- if (vpfe_dev->started) {
- v4l2_err(&vpfe_dev->v4l2_dev, "streaming is started\n");
- ret = -EBUSY;
- goto unlock_out;
- }
-
- ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
- core, s_std, *std_id);
- if (ret < 0) {
- v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n");
- goto unlock_out;
- }
- ret = vpfe_config_image_format(vpfe_dev, std_id);
-
-unlock_out:
- mutex_unlock(&vpfe_dev->lock);
- return ret;
-}
-
-static int vpfe_g_std(struct file *file, void *priv, v4l2_std_id *std_id)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_std\n");
-
- *std_id = vpfe_standards[vpfe_dev->std_index].std_id;
- return 0;
-}
-/*
- * Videobuf operations
- */
-static int vpfe_videobuf_setup(struct videobuf_queue *vq,
- unsigned int *count,
- unsigned int *size)
-{
- struct vpfe_fh *fh = vq->priv_data;
- struct vpfe_device *vpfe_dev = fh->vpfe_dev;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_setup\n");
- *size = vpfe_dev->fmt.fmt.pix.sizeimage;
- if (vpfe_dev->memory == V4L2_MEMORY_MMAP &&
- vpfe_dev->fmt.fmt.pix.sizeimage > config_params.device_bufsize)
- *size = config_params.device_bufsize;
-
- if (*count < config_params.min_numbuffers)
- *count = config_params.min_numbuffers;
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "count=%d, size=%d\n", *count, *size);
- return 0;
-}
-
-static int vpfe_videobuf_prepare(struct videobuf_queue *vq,
- struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct vpfe_fh *fh = vq->priv_data;
- struct vpfe_device *vpfe_dev = fh->vpfe_dev;
- unsigned long addr;
- int ret;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_prepare\n");
-
- /* If buffer is not initialized, initialize it */
- if (VIDEOBUF_NEEDS_INIT == vb->state) {
- vb->width = vpfe_dev->fmt.fmt.pix.width;
- vb->height = vpfe_dev->fmt.fmt.pix.height;
- vb->size = vpfe_dev->fmt.fmt.pix.sizeimage;
- vb->field = field;
-
- ret = videobuf_iolock(vq, vb, NULL);
- if (ret < 0)
- return ret;
-
- addr = videobuf_to_dma_contig(vb);
- /* Make sure user addresses are aligned to 32 bytes */
- if (!ALIGN(addr, 32))
- return -EINVAL;
-
- vb->state = VIDEOBUF_PREPARED;
- }
- return 0;
-}
-
-static void vpfe_videobuf_queue(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- /* Get the file handle object and device object */
- struct vpfe_fh *fh = vq->priv_data;
- struct vpfe_device *vpfe_dev = fh->vpfe_dev;
- unsigned long flags;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_queue\n");
-
- /* add the buffer to the DMA queue */
- spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags);
- list_add_tail(&vb->queue, &vpfe_dev->dma_queue);
- spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags);
-
- /* Change state of the buffer */
- vb->state = VIDEOBUF_QUEUED;
-}
-
-static void vpfe_videobuf_release(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct vpfe_fh *fh = vq->priv_data;
- struct vpfe_device *vpfe_dev = fh->vpfe_dev;
- unsigned long flags;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_videobuf_release\n");
-
- /*
- * We need to flush the buffer from the dma queue since
- * they are de-allocated
- */
- spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags);
- INIT_LIST_HEAD(&vpfe_dev->dma_queue);
- spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags);
- videobuf_dma_contig_free(vq, vb);
- vb->state = VIDEOBUF_NEEDS_INIT;
-}
-
-static struct videobuf_queue_ops vpfe_videobuf_qops = {
- .buf_setup = vpfe_videobuf_setup,
- .buf_prepare = vpfe_videobuf_prepare,
- .buf_queue = vpfe_videobuf_queue,
- .buf_release = vpfe_videobuf_release,
-};
-
-/*
- * vpfe_reqbufs. currently support REQBUF only once opening
- * the device.
- */
-static int vpfe_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *req_buf)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- struct vpfe_fh *fh = file->private_data;
- int ret = 0;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs\n");
-
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != req_buf->type) {
- v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buffer type\n");
- return -EINVAL;
- }
-
- ret = mutex_lock_interruptible(&vpfe_dev->lock);
- if (ret)
- return ret;
-
- if (vpfe_dev->io_usrs != 0) {
- v4l2_err(&vpfe_dev->v4l2_dev, "Only one IO user allowed\n");
- ret = -EBUSY;
- goto unlock_out;
- }
-
- vpfe_dev->memory = req_buf->memory;
- videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue,
- &vpfe_videobuf_qops,
- vpfe_dev->pdev,
- &vpfe_dev->irqlock,
- req_buf->type,
- vpfe_dev->fmt.fmt.pix.field,
- sizeof(struct videobuf_buffer),
- fh, NULL);
-
- fh->io_allowed = 1;
- vpfe_dev->io_usrs = 1;
- INIT_LIST_HEAD(&vpfe_dev->dma_queue);
- ret = videobuf_reqbufs(&vpfe_dev->buffer_queue, req_buf);
-unlock_out:
- mutex_unlock(&vpfe_dev->lock);
- return ret;
-}
-
-static int vpfe_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querybuf\n");
-
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) {
- v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
- return -EINVAL;
- }
-
- if (vpfe_dev->memory != V4L2_MEMORY_MMAP) {
- v4l2_err(&vpfe_dev->v4l2_dev, "Invalid memory\n");
- return -EINVAL;
- }
- /* Call videobuf_querybuf to get information */
- return videobuf_querybuf(&vpfe_dev->buffer_queue, buf);
-}
-
-static int vpfe_qbuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- struct vpfe_fh *fh = file->private_data;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_qbuf\n");
-
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != p->type) {
- v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
- return -EINVAL;
- }
-
- /*
- * If this file handle is not allowed to do IO,
- * return error
- */
- if (!fh->io_allowed) {
- v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
- return -EACCES;
- }
- return videobuf_qbuf(&vpfe_dev->buffer_queue, p);
-}
-
-static int vpfe_dqbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_dqbuf\n");
-
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) {
- v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
- return -EINVAL;
- }
- return videobuf_dqbuf(&vpfe_dev->buffer_queue,
- buf, file->f_flags & O_NONBLOCK);
-}
-
-static int vpfe_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qctrl)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- struct vpfe_subdev_info *sdinfo;
-
- sdinfo = vpfe_dev->current_subdev;
-
- return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
- core, queryctrl, qctrl);
-
-}
-
-static int vpfe_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- struct vpfe_subdev_info *sdinfo;
-
- sdinfo = vpfe_dev->current_subdev;
-
- return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
- core, g_ctrl, ctrl);
-}
-
-static int vpfe_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- struct vpfe_subdev_info *sdinfo;
-
- sdinfo = vpfe_dev->current_subdev;
-
- return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
- core, s_ctrl, ctrl);
-}
-
-/*
- * vpfe_calculate_offsets : This function calculates buffers offset
- * for top and bottom field
- */
-static void vpfe_calculate_offsets(struct vpfe_device *vpfe_dev)
-{
- struct v4l2_rect image_win;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_calculate_offsets\n");
-
- ccdc_dev->hw_ops.get_image_window(&image_win);
- vpfe_dev->field_off = image_win.height * image_win.width;
-}
-
-/* vpfe_start_ccdc_capture: start streaming in ccdc/isif */
-static void vpfe_start_ccdc_capture(struct vpfe_device *vpfe_dev)
-{
- ccdc_dev->hw_ops.enable(1);
- if (ccdc_dev->hw_ops.enable_out_to_sdram)
- ccdc_dev->hw_ops.enable_out_to_sdram(1);
- vpfe_dev->started = 1;
-}
-
-/*
- * vpfe_streamon. Assume the DMA queue is not empty.
- * application is expected to call QBUF before calling
- * this ioctl. If not, driver returns error
- */
-static int vpfe_streamon(struct file *file, void *priv,
- enum v4l2_buf_type buf_type)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- struct vpfe_fh *fh = file->private_data;
- struct vpfe_subdev_info *sdinfo;
- unsigned long addr;
- int ret = 0;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamon\n");
-
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) {
- v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
- return -EINVAL;
- }
-
- /* If file handle is not allowed IO, return error */
- if (!fh->io_allowed) {
- v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
- return -EACCES;
- }
-
- sdinfo = vpfe_dev->current_subdev;
- ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
- video, s_stream, 1);
-
- if (ret && (ret != -ENOIOCTLCMD)) {
- v4l2_err(&vpfe_dev->v4l2_dev, "stream on failed in subdev\n");
- return -EINVAL;
- }
-
- /* If buffer queue is empty, return error */
- if (list_empty(&vpfe_dev->buffer_queue.stream)) {
- v4l2_err(&vpfe_dev->v4l2_dev, "buffer queue is empty\n");
- return -EIO;
- }
-
- /* Call videobuf_streamon to start streaming * in videobuf */
- ret = videobuf_streamon(&vpfe_dev->buffer_queue);
- if (ret)
- return ret;
-
-
- ret = mutex_lock_interruptible(&vpfe_dev->lock);
- if (ret)
- goto streamoff;
- /* Get the next frame from the buffer queue */
- vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next,
- struct videobuf_buffer, queue);
- vpfe_dev->cur_frm = vpfe_dev->next_frm;
- /* Remove buffer from the buffer queue */
- list_del(&vpfe_dev->cur_frm->queue);
- /* Mark state of the current frame to active */
- vpfe_dev->cur_frm->state = VIDEOBUF_ACTIVE;
- /* Initialize field_id and started member */
- vpfe_dev->field_id = 0;
- addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
-
- /* Calculate field offset */
- vpfe_calculate_offsets(vpfe_dev);
-
- if (vpfe_attach_irq(vpfe_dev) < 0) {
- v4l2_err(&vpfe_dev->v4l2_dev,
- "Error in attaching interrupt handle\n");
- ret = -EFAULT;
- goto unlock_out;
- }
- if (ccdc_dev->hw_ops.configure() < 0) {
- v4l2_err(&vpfe_dev->v4l2_dev,
- "Error in configuring ccdc\n");
- ret = -EINVAL;
- goto unlock_out;
- }
- ccdc_dev->hw_ops.setfbaddr((unsigned long)(addr));
- vpfe_start_ccdc_capture(vpfe_dev);
- mutex_unlock(&vpfe_dev->lock);
- return ret;
-unlock_out:
- mutex_unlock(&vpfe_dev->lock);
-streamoff:
- ret = videobuf_streamoff(&vpfe_dev->buffer_queue);
- return ret;
-}
-
-static int vpfe_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type buf_type)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- struct vpfe_fh *fh = file->private_data;
- struct vpfe_subdev_info *sdinfo;
- int ret = 0;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamoff\n");
-
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) {
- v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
- return -EINVAL;
- }
-
- /* If io is allowed for this file handle, return error */
- if (!fh->io_allowed) {
- v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
- return -EACCES;
- }
-
- /* If streaming is not started, return error */
- if (!vpfe_dev->started) {
- v4l2_err(&vpfe_dev->v4l2_dev, "device started\n");
- return -EINVAL;
- }
-
- ret = mutex_lock_interruptible(&vpfe_dev->lock);
- if (ret)
- return ret;
-
- vpfe_stop_ccdc_capture(vpfe_dev);
- vpfe_detach_irq(vpfe_dev);
-
- sdinfo = vpfe_dev->current_subdev;
- ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
- video, s_stream, 0);
-
- if (ret && (ret != -ENOIOCTLCMD))
- v4l2_err(&vpfe_dev->v4l2_dev, "stream off failed in subdev\n");
- ret = videobuf_streamoff(&vpfe_dev->buffer_queue);
- mutex_unlock(&vpfe_dev->lock);
- return ret;
-}
-
-static int vpfe_cropcap(struct file *file, void *priv,
- struct v4l2_cropcap *crop)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n");
-
- if (vpfe_dev->std_index >= ARRAY_SIZE(vpfe_standards))
- return -EINVAL;
-
- memset(crop, 0, sizeof(struct v4l2_cropcap));
- crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- crop->bounds.width = crop->defrect.width =
- vpfe_standards[vpfe_dev->std_index].width;
- crop->bounds.height = crop->defrect.height =
- vpfe_standards[vpfe_dev->std_index].height;
- crop->pixelaspect = vpfe_standards[vpfe_dev->std_index].pixelaspect;
- return 0;
-}
-
-static int vpfe_g_crop(struct file *file, void *priv,
- struct v4l2_crop *crop)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_crop\n");
-
- crop->c = vpfe_dev->crop;
- return 0;
-}
-
-static int vpfe_s_crop(struct file *file, void *priv,
- struct v4l2_crop *crop)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- int ret = 0;
-
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_crop\n");
-
- if (vpfe_dev->started) {
- /* make sure streaming is not started */
- v4l2_err(&vpfe_dev->v4l2_dev,
- "Cannot change crop when streaming is ON\n");
- return -EBUSY;
- }
-
- ret = mutex_lock_interruptible(&vpfe_dev->lock);
- if (ret)
- return ret;
-
- if (crop->c.top < 0 || crop->c.left < 0) {
- v4l2_err(&vpfe_dev->v4l2_dev,
- "doesn't support negative values for top & left\n");
- ret = -EINVAL;
- goto unlock_out;
- }
-
- /* adjust the width to 16 pixel boundary */
- crop->c.width = ((crop->c.width + 15) & ~0xf);
-
- /* make sure parameters are valid */
- if ((crop->c.left + crop->c.width >
- vpfe_dev->std_info.active_pixels) ||
- (crop->c.top + crop->c.height >
- vpfe_dev->std_info.active_lines)) {
- v4l2_err(&vpfe_dev->v4l2_dev, "Error in S_CROP params\n");
- ret = -EINVAL;
- goto unlock_out;
- }
- ccdc_dev->hw_ops.set_image_window(&crop->c);
- vpfe_dev->fmt.fmt.pix.width = crop->c.width;
- vpfe_dev->fmt.fmt.pix.height = crop->c.height;
- vpfe_dev->fmt.fmt.pix.bytesperline =
- ccdc_dev->hw_ops.get_line_length();
- vpfe_dev->fmt.fmt.pix.sizeimage =
- vpfe_dev->fmt.fmt.pix.bytesperline *
- vpfe_dev->fmt.fmt.pix.height;
- vpfe_dev->crop = crop->c;
-unlock_out:
- mutex_unlock(&vpfe_dev->lock);
- return ret;
-}
-
-
-static long vpfe_param_handler(struct file *file, void *priv,
- bool valid_prio, int cmd, void *param)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- int ret = 0;
-
- v4l2_dbg(2, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n");
-
- if (vpfe_dev->started) {
- /* only allowed if streaming is not started */
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "device already started\n");
- return -EBUSY;
- }
-
- ret = mutex_lock_interruptible(&vpfe_dev->lock);
- if (ret)
- return ret;
-
- switch (cmd) {
- case VPFE_CMD_S_CCDC_RAW_PARAMS:
- v4l2_warn(&vpfe_dev->v4l2_dev,
- "VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n");
- if (ccdc_dev->hw_ops.set_params) {
- ret = ccdc_dev->hw_ops.set_params(param);
- if (ret) {
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "Error setting parameters in CCDC\n");
- goto unlock_out;
- }
- if (vpfe_get_ccdc_image_format(vpfe_dev,
- &vpfe_dev->fmt) < 0) {
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "Invalid image format at CCDC\n");
- goto unlock_out;
- }
- } else {
- ret = -EINVAL;
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "VPFE_CMD_S_CCDC_RAW_PARAMS not supported\n");
- }
- break;
- default:
- ret = -ENOTTY;
- }
-unlock_out:
- mutex_unlock(&vpfe_dev->lock);
- return ret;
-}
-
-
-/* vpfe capture ioctl operations */
-static const struct v4l2_ioctl_ops vpfe_ioctl_ops = {
- .vidioc_querycap = vpfe_querycap,
- .vidioc_g_fmt_vid_cap = vpfe_g_fmt_vid_cap,
- .vidioc_enum_fmt_vid_cap = vpfe_enum_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vpfe_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vpfe_try_fmt_vid_cap,
- .vidioc_enum_input = vpfe_enum_input,
- .vidioc_g_input = vpfe_g_input,
- .vidioc_s_input = vpfe_s_input,
- .vidioc_querystd = vpfe_querystd,
- .vidioc_s_std = vpfe_s_std,
- .vidioc_g_std = vpfe_g_std,
- .vidioc_queryctrl = vpfe_queryctrl,
- .vidioc_g_ctrl = vpfe_g_ctrl,
- .vidioc_s_ctrl = vpfe_s_ctrl,
- .vidioc_reqbufs = vpfe_reqbufs,
- .vidioc_querybuf = vpfe_querybuf,
- .vidioc_qbuf = vpfe_qbuf,
- .vidioc_dqbuf = vpfe_dqbuf,
- .vidioc_streamon = vpfe_streamon,
- .vidioc_streamoff = vpfe_streamoff,
- .vidioc_cropcap = vpfe_cropcap,
- .vidioc_g_crop = vpfe_g_crop,
- .vidioc_s_crop = vpfe_s_crop,
- .vidioc_default = vpfe_param_handler,
-};
-
-static struct vpfe_device *vpfe_initialize(void)
-{
- struct vpfe_device *vpfe_dev;
-
- /* Default number of buffers should be 3 */
- if ((numbuffers > 0) &&
- (numbuffers < config_params.min_numbuffers))
- numbuffers = config_params.min_numbuffers;
-
- /*
- * Set buffer size to min buffers size if invalid buffer size is
- * given
- */
- if (bufsize < config_params.min_bufsize)
- bufsize = config_params.min_bufsize;
-
- config_params.numbuffers = numbuffers;
-
- if (numbuffers)
- config_params.device_bufsize = bufsize;
-
- /* Allocate memory for device objects */
- vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL);
-
- return vpfe_dev;
-}
-
-/*
- * vpfe_probe : This function creates device entries by register
- * itself to the V4L2 driver and initializes fields of each
- * device objects
- */
-static __init int vpfe_probe(struct platform_device *pdev)
-{
- struct vpfe_subdev_info *sdinfo;
- struct vpfe_config *vpfe_cfg;
- struct resource *res1;
- struct vpfe_device *vpfe_dev;
- struct i2c_adapter *i2c_adap;
- struct video_device *vfd;
- int ret = -ENOMEM, i, j;
- int num_subdevs = 0;
-
- /* Get the pointer to the device object */
- vpfe_dev = vpfe_initialize();
-
- if (!vpfe_dev) {
- v4l2_err(pdev->dev.driver,
- "Failed to allocate memory for vpfe_dev\n");
- return ret;
- }
-
- vpfe_dev->pdev = &pdev->dev;
-
- if (NULL == pdev->dev.platform_data) {
- v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
- ret = -ENODEV;
- goto probe_free_dev_mem;
- }
-
- vpfe_cfg = pdev->dev.platform_data;
- vpfe_dev->cfg = vpfe_cfg;
- if (NULL == vpfe_cfg->ccdc ||
- NULL == vpfe_cfg->card_name ||
- NULL == vpfe_cfg->sub_devs) {
- v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n");
- ret = -ENOENT;
- goto probe_free_dev_mem;
- }
-
- /* Allocate memory for ccdc configuration */
- ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL);
- if (NULL == ccdc_cfg) {
- v4l2_err(pdev->dev.driver,
- "Memory allocation failed for ccdc_cfg\n");
- goto probe_free_lock;
- }
-
- mutex_lock(&ccdc_lock);
-
- strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32);
- /* Get VINT0 irq resource */
- res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res1) {
- v4l2_err(pdev->dev.driver,
- "Unable to get interrupt for VINT0\n");
- ret = -ENODEV;
- goto probe_free_ccdc_cfg_mem;
- }
- vpfe_dev->ccdc_irq0 = res1->start;
-
- /* Get VINT1 irq resource */
- res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
- if (!res1) {
- v4l2_err(pdev->dev.driver,
- "Unable to get interrupt for VINT1\n");
- ret = -ENODEV;
- goto probe_free_ccdc_cfg_mem;
- }
- vpfe_dev->ccdc_irq1 = res1->start;
-
- ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED,
- "vpfe_capture0", vpfe_dev);
-
- if (0 != ret) {
- v4l2_err(pdev->dev.driver, "Unable to request interrupt\n");
- goto probe_free_ccdc_cfg_mem;
- }
-
- /* Allocate memory for video device */
- vfd = video_device_alloc();
- if (NULL == vfd) {
- ret = -ENOMEM;
- v4l2_err(pdev->dev.driver, "Unable to alloc video device\n");
- goto probe_out_release_irq;
- }
-
- /* Initialize field of video device */
- vfd->release = video_device_release;
- vfd->fops = &vpfe_fops;
- vfd->ioctl_ops = &vpfe_ioctl_ops;
- vfd->tvnorms = 0;
- vfd->current_norm = V4L2_STD_PAL;
- vfd->v4l2_dev = &vpfe_dev->v4l2_dev;
- snprintf(vfd->name, sizeof(vfd->name),
- "%s_V%d.%d.%d",
- CAPTURE_DRV_NAME,
- (VPFE_CAPTURE_VERSION_CODE >> 16) & 0xff,
- (VPFE_CAPTURE_VERSION_CODE >> 8) & 0xff,
- (VPFE_CAPTURE_VERSION_CODE) & 0xff);
- /* Set video_dev to the video device */
- vpfe_dev->video_dev = vfd;
-
- ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev);
- if (ret) {
- v4l2_err(pdev->dev.driver,
- "Unable to register v4l2 device.\n");
- goto probe_out_video_release;
- }
- v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n");
- spin_lock_init(&vpfe_dev->irqlock);
- spin_lock_init(&vpfe_dev->dma_queue_lock);
- mutex_init(&vpfe_dev->lock);
-
- /* Initialize field of the device objects */
- vpfe_dev->numbuffers = config_params.numbuffers;
-
- /* Initialize prio member of device object */
- v4l2_prio_init(&vpfe_dev->prio);
- /* register video device */
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "trying to register vpfe device.\n");
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "video_dev=%x\n", (int)&vpfe_dev->video_dev);
- vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- ret = video_register_device(vpfe_dev->video_dev,
- VFL_TYPE_GRABBER, -1);
-
- if (ret) {
- v4l2_err(pdev->dev.driver,
- "Unable to register video device.\n");
- goto probe_out_v4l2_unregister;
- }
-
- v4l2_info(&vpfe_dev->v4l2_dev, "video device registered\n");
- /* set the driver data in platform device */
- platform_set_drvdata(pdev, vpfe_dev);
- /* set driver private data */
- video_set_drvdata(vpfe_dev->video_dev, vpfe_dev);
- i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id);
- num_subdevs = vpfe_cfg->num_subdevs;
- vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs,
- GFP_KERNEL);
- if (NULL == vpfe_dev->sd) {
- v4l2_err(&vpfe_dev->v4l2_dev,
- "unable to allocate memory for subdevice pointers\n");
- ret = -ENOMEM;
- goto probe_out_video_unregister;
- }
-
- for (i = 0; i < num_subdevs; i++) {
- struct v4l2_input *inps;
-
- sdinfo = &vpfe_cfg->sub_devs[i];
-
- /* Load up the subdevice */
- vpfe_dev->sd[i] =
- v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
- i2c_adap,
- &sdinfo->board_info,
- NULL);
- if (vpfe_dev->sd[i]) {
- v4l2_info(&vpfe_dev->v4l2_dev,
- "v4l2 sub device %s registered\n",
- sdinfo->name);
- vpfe_dev->sd[i]->grp_id = sdinfo->grp_id;
- /* update tvnorms from the sub devices */
- for (j = 0; j < sdinfo->num_inputs; j++) {
- inps = &sdinfo->inputs[j];
- vfd->tvnorms |= inps->std;
- }
- } else {
- v4l2_info(&vpfe_dev->v4l2_dev,
- "v4l2 sub device %s register fails\n",
- sdinfo->name);
- goto probe_sd_out;
- }
- }
-
- /* set first sub device as current one */
- vpfe_dev->current_subdev = &vpfe_cfg->sub_devs[0];
-
- /* We have at least one sub device to work with */
- mutex_unlock(&ccdc_lock);
- return 0;
-
-probe_sd_out:
- kfree(vpfe_dev->sd);
-probe_out_video_unregister:
- video_unregister_device(vpfe_dev->video_dev);
-probe_out_v4l2_unregister:
- v4l2_device_unregister(&vpfe_dev->v4l2_dev);
-probe_out_video_release:
- if (!video_is_registered(vpfe_dev->video_dev))
- video_device_release(vpfe_dev->video_dev);
-probe_out_release_irq:
- free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
-probe_free_ccdc_cfg_mem:
- kfree(ccdc_cfg);
-probe_free_lock:
- mutex_unlock(&ccdc_lock);
-probe_free_dev_mem:
- kfree(vpfe_dev);
- return ret;
-}
-
-/*
- * vpfe_remove : It un-register device from V4L2 driver
- */
-static int __devexit vpfe_remove(struct platform_device *pdev)
-{
- struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
-
- v4l2_info(pdev->dev.driver, "vpfe_remove\n");
-
- free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
- kfree(vpfe_dev->sd);
- v4l2_device_unregister(&vpfe_dev->v4l2_dev);
- video_unregister_device(vpfe_dev->video_dev);
- kfree(vpfe_dev);
- kfree(ccdc_cfg);
- return 0;
-}
-
-static int vpfe_suspend(struct device *dev)
-{
- return 0;
-}
-
-static int vpfe_resume(struct device *dev)
-{
- return 0;
-}
-
-static const struct dev_pm_ops vpfe_dev_pm_ops = {
- .suspend = vpfe_suspend,
- .resume = vpfe_resume,
-};
-
-static struct platform_driver vpfe_driver = {
- .driver = {
- .name = CAPTURE_DRV_NAME,
- .owner = THIS_MODULE,
- .pm = &vpfe_dev_pm_ops,
- },
- .probe = vpfe_probe,
- .remove = __devexit_p(vpfe_remove),
-};
-
-module_platform_driver(vpfe_driver);
diff --git a/drivers/media/video/davinci/vpif.c b/drivers/media/video/davinci/vpif.c
deleted file mode 100644
index b3637aff8fe..00000000000
--- a/drivers/media/video/davinci/vpif.c
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * vpif - Video Port Interface driver
- * VPIF is a receiver and transmitter for video data. It has two channels(0, 1)
- * that receiveing video byte stream and two channels(2, 3) for video output.
- * The hardware supports SDTV, HDTV formats, raw data capture.
- * Currently, the driver supports NTSC and PAL standards.
- *
- * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spinlock.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <mach/hardware.h>
-
-#include "vpif.h"
-
-MODULE_DESCRIPTION("TI DaVinci Video Port Interface driver");
-MODULE_LICENSE("GPL");
-
-#define VPIF_CH0_MAX_MODES (22)
-#define VPIF_CH1_MAX_MODES (02)
-#define VPIF_CH2_MAX_MODES (15)
-#define VPIF_CH3_MAX_MODES (02)
-
-static resource_size_t res_len;
-static struct resource *res;
-spinlock_t vpif_lock;
-
-void __iomem *vpif_base;
-struct clk *vpif_clk;
-
-/**
- * ch_params: video standard configuration parameters for vpif
- * The table must include all presets from supported subdevices.
- */
-const struct vpif_channel_config_params ch_params[] = {
- /* HDTV formats */
- {
- .name = "480p59_94",
- .width = 720,
- .height = 480,
- .frm_fmt = 1,
- .ycmux_mode = 0,
- .eav2sav = 138-8,
- .sav2eav = 720,
- .l1 = 1,
- .l3 = 43,
- .l5 = 523,
- .vsize = 525,
- .capture_format = 0,
- .vbi_supported = 0,
- .hd_sd = 1,
- .dv_preset = V4L2_DV_480P59_94,
- },
- {
- .name = "576p50",
- .width = 720,
- .height = 576,
- .frm_fmt = 1,
- .ycmux_mode = 0,
- .eav2sav = 144-8,
- .sav2eav = 720,
- .l1 = 1,
- .l3 = 45,
- .l5 = 621,
- .vsize = 625,
- .capture_format = 0,
- .vbi_supported = 0,
- .hd_sd = 1,
- .dv_preset = V4L2_DV_576P50,
- },
- {
- .name = "720p50",
- .width = 1280,
- .height = 720,
- .frm_fmt = 1,
- .ycmux_mode = 0,
- .eav2sav = 700-8,
- .sav2eav = 1280,
- .l1 = 1,
- .l3 = 26,
- .l5 = 746,
- .vsize = 750,
- .capture_format = 0,
- .vbi_supported = 0,
- .hd_sd = 1,
- .dv_preset = V4L2_DV_720P50,
- },
- {
- .name = "720p60",
- .width = 1280,
- .height = 720,
- .frm_fmt = 1,
- .ycmux_mode = 0,
- .eav2sav = 370 - 8,
- .sav2eav = 1280,
- .l1 = 1,
- .l3 = 26,
- .l5 = 746,
- .vsize = 750,
- .capture_format = 0,
- .vbi_supported = 0,
- .hd_sd = 1,
- .dv_preset = V4L2_DV_720P60,
- },
- {
- .name = "1080I50",
- .width = 1920,
- .height = 1080,
- .frm_fmt = 0,
- .ycmux_mode = 0,
- .eav2sav = 720 - 8,
- .sav2eav = 1920,
- .l1 = 1,
- .l3 = 21,
- .l5 = 561,
- .l7 = 563,
- .l9 = 584,
- .l11 = 1124,
- .vsize = 1125,
- .capture_format = 0,
- .vbi_supported = 0,
- .hd_sd = 1,
- .dv_preset = V4L2_DV_1080I50,
- },
- {
- .name = "1080I60",
- .width = 1920,
- .height = 1080,
- .frm_fmt = 0,
- .ycmux_mode = 0,
- .eav2sav = 280 - 8,
- .sav2eav = 1920,
- .l1 = 1,
- .l3 = 21,
- .l5 = 561,
- .l7 = 563,
- .l9 = 584,
- .l11 = 1124,
- .vsize = 1125,
- .capture_format = 0,
- .vbi_supported = 0,
- .hd_sd = 1,
- .dv_preset = V4L2_DV_1080I60,
- },
- {
- .name = "1080p60",
- .width = 1920,
- .height = 1080,
- .frm_fmt = 1,
- .ycmux_mode = 0,
- .eav2sav = 280 - 8,
- .sav2eav = 1920,
- .l1 = 1,
- .l3 = 42,
- .l5 = 1122,
- .vsize = 1125,
- .capture_format = 0,
- .vbi_supported = 0,
- .hd_sd = 1,
- .dv_preset = V4L2_DV_1080P60,
- },
-
- /* SDTV formats */
- {
- .name = "NTSC_M",
- .width = 720,
- .height = 480,
- .frm_fmt = 0,
- .ycmux_mode = 1,
- .eav2sav = 268,
- .sav2eav = 1440,
- .l1 = 1,
- .l3 = 23,
- .l5 = 263,
- .l7 = 266,
- .l9 = 286,
- .l11 = 525,
- .vsize = 525,
- .capture_format = 0,
- .vbi_supported = 1,
- .hd_sd = 0,
- .stdid = V4L2_STD_525_60,
- },
- {
- .name = "PAL_BDGHIK",
- .width = 720,
- .height = 576,
- .frm_fmt = 0,
- .ycmux_mode = 1,
- .eav2sav = 280,
- .sav2eav = 1440,
- .l1 = 1,
- .l3 = 23,
- .l5 = 311,
- .l7 = 313,
- .l9 = 336,
- .l11 = 624,
- .vsize = 625,
- .capture_format = 0,
- .vbi_supported = 1,
- .hd_sd = 0,
- .stdid = V4L2_STD_625_50,
- },
-};
-
-const unsigned int vpif_ch_params_count = ARRAY_SIZE(ch_params);
-
-static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val)
-{
- if (val)
- vpif_set_bit(reg, bit);
- else
- vpif_clr_bit(reg, bit);
-}
-
-/* This structure is used to keep track of VPIF size register's offsets */
-struct vpif_registers {
- u32 h_cfg, v_cfg_00, v_cfg_01, v_cfg_02, v_cfg, ch_ctrl;
- u32 line_offset, vanc0_strt, vanc0_size, vanc1_strt;
- u32 vanc1_size, width_mask, len_mask;
- u8 max_modes;
-};
-
-static const struct vpif_registers vpifregs[VPIF_NUM_CHANNELS] = {
- /* Channel0 */
- {
- VPIF_CH0_H_CFG, VPIF_CH0_V_CFG_00, VPIF_CH0_V_CFG_01,
- VPIF_CH0_V_CFG_02, VPIF_CH0_V_CFG_03, VPIF_CH0_CTRL,
- VPIF_CH0_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF,
- VPIF_CH0_MAX_MODES,
- },
- /* Channel1 */
- {
- VPIF_CH1_H_CFG, VPIF_CH1_V_CFG_00, VPIF_CH1_V_CFG_01,
- VPIF_CH1_V_CFG_02, VPIF_CH1_V_CFG_03, VPIF_CH1_CTRL,
- VPIF_CH1_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF,
- VPIF_CH1_MAX_MODES,
- },
- /* Channel2 */
- {
- VPIF_CH2_H_CFG, VPIF_CH2_V_CFG_00, VPIF_CH2_V_CFG_01,
- VPIF_CH2_V_CFG_02, VPIF_CH2_V_CFG_03, VPIF_CH2_CTRL,
- VPIF_CH2_IMG_ADD_OFST, VPIF_CH2_VANC0_STRT, VPIF_CH2_VANC0_SIZE,
- VPIF_CH2_VANC1_STRT, VPIF_CH2_VANC1_SIZE, 0x7FF, 0x7FF,
- VPIF_CH2_MAX_MODES
- },
- /* Channel3 */
- {
- VPIF_CH3_H_CFG, VPIF_CH3_V_CFG_00, VPIF_CH3_V_CFG_01,
- VPIF_CH3_V_CFG_02, VPIF_CH3_V_CFG_03, VPIF_CH3_CTRL,
- VPIF_CH3_IMG_ADD_OFST, VPIF_CH3_VANC0_STRT, VPIF_CH3_VANC0_SIZE,
- VPIF_CH3_VANC1_STRT, VPIF_CH3_VANC1_SIZE, 0x7FF, 0x7FF,
- VPIF_CH3_MAX_MODES
- },
-};
-
-/* vpif_set_mode_info:
- * This function is used to set horizontal and vertical config parameters
- * As per the standard in the channel, configure the values of L1, L3,
- * L5, L7 L9, L11 in VPIF Register , also write width and height
- */
-static void vpif_set_mode_info(const struct vpif_channel_config_params *config,
- u8 channel_id, u8 config_channel_id)
-{
- u32 value;
-
- value = (config->eav2sav & vpifregs[config_channel_id].width_mask);
- value <<= VPIF_CH_LEN_SHIFT;
- value |= (config->sav2eav & vpifregs[config_channel_id].width_mask);
- regw(value, vpifregs[channel_id].h_cfg);
-
- value = (config->l1 & vpifregs[config_channel_id].len_mask);
- value <<= VPIF_CH_LEN_SHIFT;
- value |= (config->l3 & vpifregs[config_channel_id].len_mask);
- regw(value, vpifregs[channel_id].v_cfg_00);
-
- value = (config->l5 & vpifregs[config_channel_id].len_mask);
- value <<= VPIF_CH_LEN_SHIFT;
- value |= (config->l7 & vpifregs[config_channel_id].len_mask);
- regw(value, vpifregs[channel_id].v_cfg_01);
-
- value = (config->l9 & vpifregs[config_channel_id].len_mask);
- value <<= VPIF_CH_LEN_SHIFT;
- value |= (config->l11 & vpifregs[config_channel_id].len_mask);
- regw(value, vpifregs[channel_id].v_cfg_02);
-
- value = (config->vsize & vpifregs[config_channel_id].len_mask);
- regw(value, vpifregs[channel_id].v_cfg);
-}
-
-/* config_vpif_params
- * Function to set the parameters of a channel
- * Mainly modifies the channel ciontrol register
- * It sets frame format, yc mux mode
- */
-static void config_vpif_params(struct vpif_params *vpifparams,
- u8 channel_id, u8 found)
-{
- const struct vpif_channel_config_params *config = &vpifparams->std_info;
- u32 value, ch_nip, reg;
- u8 start, end;
- int i;
-
- start = channel_id;
- end = channel_id + found;
-
- for (i = start; i < end; i++) {
- reg = vpifregs[i].ch_ctrl;
- if (channel_id < 2)
- ch_nip = VPIF_CAPTURE_CH_NIP;
- else
- ch_nip = VPIF_DISPLAY_CH_NIP;
-
- vpif_wr_bit(reg, ch_nip, config->frm_fmt);
- vpif_wr_bit(reg, VPIF_CH_YC_MUX_BIT, config->ycmux_mode);
- vpif_wr_bit(reg, VPIF_CH_INPUT_FIELD_FRAME_BIT,
- vpifparams->video_params.storage_mode);
-
- /* Set raster scanning SDR Format */
- vpif_clr_bit(reg, VPIF_CH_SDR_FMT_BIT);
- vpif_wr_bit(reg, VPIF_CH_DATA_MODE_BIT, config->capture_format);
-
- if (channel_id > 1) /* Set the Pixel enable bit */
- vpif_set_bit(reg, VPIF_DISPLAY_PIX_EN_BIT);
- else if (config->capture_format) {
- /* Set the polarity of various pins */
- vpif_wr_bit(reg, VPIF_CH_FID_POLARITY_BIT,
- vpifparams->iface.fid_pol);
- vpif_wr_bit(reg, VPIF_CH_V_VALID_POLARITY_BIT,
- vpifparams->iface.vd_pol);
- vpif_wr_bit(reg, VPIF_CH_H_VALID_POLARITY_BIT,
- vpifparams->iface.hd_pol);
-
- value = regr(reg);
- /* Set data width */
- value &= ~(0x3u <<
- VPIF_CH_DATA_WIDTH_BIT);
- value |= ((vpifparams->params.data_sz) <<
- VPIF_CH_DATA_WIDTH_BIT);
- regw(value, reg);
- }
-
- /* Write the pitch in the driver */
- regw((vpifparams->video_params.hpitch),
- vpifregs[i].line_offset);
- }
-}
-
-/* vpif_set_video_params
- * This function is used to set video parameters in VPIF register
- */
-int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id)
-{
- const struct vpif_channel_config_params *config = &vpifparams->std_info;
- int found = 1;
-
- vpif_set_mode_info(config, channel_id, channel_id);
- if (!config->ycmux_mode) {
- /* YC are on separate channels (HDTV formats) */
- vpif_set_mode_info(config, channel_id + 1, channel_id);
- found = 2;
- }
-
- config_vpif_params(vpifparams, channel_id, found);
-
- regw(0x80, VPIF_REQ_SIZE);
- regw(0x01, VPIF_EMULATION_CTRL);
-
- return found;
-}
-EXPORT_SYMBOL(vpif_set_video_params);
-
-void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
- u8 channel_id)
-{
- u32 value;
-
- value = 0x3F8 & (vbiparams->hstart0);
- value |= 0x3FFFFFF & ((vbiparams->vstart0) << 16);
- regw(value, vpifregs[channel_id].vanc0_strt);
-
- value = 0x3F8 & (vbiparams->hstart1);
- value |= 0x3FFFFFF & ((vbiparams->vstart1) << 16);
- regw(value, vpifregs[channel_id].vanc1_strt);
-
- value = 0x3F8 & (vbiparams->hsize0);
- value |= 0x3FFFFFF & ((vbiparams->vsize0) << 16);
- regw(value, vpifregs[channel_id].vanc0_size);
-
- value = 0x3F8 & (vbiparams->hsize1);
- value |= 0x3FFFFFF & ((vbiparams->vsize1) << 16);
- regw(value, vpifregs[channel_id].vanc1_size);
-
-}
-EXPORT_SYMBOL(vpif_set_vbi_display_params);
-
-int vpif_channel_getfid(u8 channel_id)
-{
- return (regr(vpifregs[channel_id].ch_ctrl) & VPIF_CH_FID_MASK)
- >> VPIF_CH_FID_SHIFT;
-}
-EXPORT_SYMBOL(vpif_channel_getfid);
-
-static int __init vpif_probe(struct platform_device *pdev)
-{
- int status = 0;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENOENT;
-
- res_len = resource_size(res);
-
- res = request_mem_region(res->start, res_len, res->name);
- if (!res)
- return -EBUSY;
-
- vpif_base = ioremap(res->start, res_len);
- if (!vpif_base) {
- status = -EBUSY;
- goto fail;
- }
-
- vpif_clk = clk_get(&pdev->dev, "vpif");
- if (IS_ERR(vpif_clk)) {
- status = PTR_ERR(vpif_clk);
- goto clk_fail;
- }
- clk_enable(vpif_clk);
-
- spin_lock_init(&vpif_lock);
- dev_info(&pdev->dev, "vpif probe success\n");
- return 0;
-
-clk_fail:
- iounmap(vpif_base);
-fail:
- release_mem_region(res->start, res_len);
- return status;
-}
-
-static int __devexit vpif_remove(struct platform_device *pdev)
-{
- if (vpif_clk) {
- clk_disable(vpif_clk);
- clk_put(vpif_clk);
- }
-
- iounmap(vpif_base);
- release_mem_region(res->start, res_len);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int vpif_suspend(struct device *dev)
-{
- clk_disable(vpif_clk);
- return 0;
-}
-
-static int vpif_resume(struct device *dev)
-{
- clk_enable(vpif_clk);
- return 0;
-}
-
-static const struct dev_pm_ops vpif_pm = {
- .suspend = vpif_suspend,
- .resume = vpif_resume,
-};
-
-#define vpif_pm_ops (&vpif_pm)
-#else
-#define vpif_pm_ops NULL
-#endif
-
-static struct platform_driver vpif_driver = {
- .driver = {
- .name = "vpif",
- .owner = THIS_MODULE,
- .pm = vpif_pm_ops,
- },
- .remove = __devexit_p(vpif_remove),
- .probe = vpif_probe,
-};
-
-static void vpif_exit(void)
-{
- platform_driver_unregister(&vpif_driver);
-}
-
-static int __init vpif_init(void)
-{
- return platform_driver_register(&vpif_driver);
-}
-subsys_initcall(vpif_init);
-module_exit(vpif_exit);
-
diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h
deleted file mode 100644
index c2ce4d97c27..00000000000
--- a/drivers/media/video/davinci/vpif.h
+++ /dev/null
@@ -1,688 +0,0 @@
-/*
- * VPIF header file
- *
- * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef VPIF_H
-#define VPIF_H
-
-#include <linux/io.h>
-#include <linux/videodev2.h>
-#include <media/davinci/vpif_types.h>
-
-/* Maximum channel allowed */
-#define VPIF_NUM_CHANNELS (4)
-#define VPIF_CAPTURE_NUM_CHANNELS (2)
-#define VPIF_DISPLAY_NUM_CHANNELS (2)
-
-/* Macros to read/write registers */
-extern void __iomem *vpif_base;
-extern spinlock_t vpif_lock;
-
-#define regr(reg) readl((reg) + vpif_base)
-#define regw(value, reg) writel(value, (reg + vpif_base))
-
-/* Register Address Offsets */
-#define VPIF_PID (0x0000)
-#define VPIF_CH0_CTRL (0x0004)
-#define VPIF_CH1_CTRL (0x0008)
-#define VPIF_CH2_CTRL (0x000C)
-#define VPIF_CH3_CTRL (0x0010)
-
-#define VPIF_INTEN (0x0020)
-#define VPIF_INTEN_SET (0x0024)
-#define VPIF_INTEN_CLR (0x0028)
-#define VPIF_STATUS (0x002C)
-#define VPIF_STATUS_CLR (0x0030)
-#define VPIF_EMULATION_CTRL (0x0034)
-#define VPIF_REQ_SIZE (0x0038)
-
-#define VPIF_CH0_TOP_STRT_ADD_LUMA (0x0040)
-#define VPIF_CH0_BTM_STRT_ADD_LUMA (0x0044)
-#define VPIF_CH0_TOP_STRT_ADD_CHROMA (0x0048)
-#define VPIF_CH0_BTM_STRT_ADD_CHROMA (0x004c)
-#define VPIF_CH0_TOP_STRT_ADD_HANC (0x0050)
-#define VPIF_CH0_BTM_STRT_ADD_HANC (0x0054)
-#define VPIF_CH0_TOP_STRT_ADD_VANC (0x0058)
-#define VPIF_CH0_BTM_STRT_ADD_VANC (0x005c)
-#define VPIF_CH0_SP_CFG (0x0060)
-#define VPIF_CH0_IMG_ADD_OFST (0x0064)
-#define VPIF_CH0_HANC_ADD_OFST (0x0068)
-#define VPIF_CH0_H_CFG (0x006c)
-#define VPIF_CH0_V_CFG_00 (0x0070)
-#define VPIF_CH0_V_CFG_01 (0x0074)
-#define VPIF_CH0_V_CFG_02 (0x0078)
-#define VPIF_CH0_V_CFG_03 (0x007c)
-
-#define VPIF_CH1_TOP_STRT_ADD_LUMA (0x0080)
-#define VPIF_CH1_BTM_STRT_ADD_LUMA (0x0084)
-#define VPIF_CH1_TOP_STRT_ADD_CHROMA (0x0088)
-#define VPIF_CH1_BTM_STRT_ADD_CHROMA (0x008c)
-#define VPIF_CH1_TOP_STRT_ADD_HANC (0x0090)
-#define VPIF_CH1_BTM_STRT_ADD_HANC (0x0094)
-#define VPIF_CH1_TOP_STRT_ADD_VANC (0x0098)
-#define VPIF_CH1_BTM_STRT_ADD_VANC (0x009c)
-#define VPIF_CH1_SP_CFG (0x00a0)
-#define VPIF_CH1_IMG_ADD_OFST (0x00a4)
-#define VPIF_CH1_HANC_ADD_OFST (0x00a8)
-#define VPIF_CH1_H_CFG (0x00ac)
-#define VPIF_CH1_V_CFG_00 (0x00b0)
-#define VPIF_CH1_V_CFG_01 (0x00b4)
-#define VPIF_CH1_V_CFG_02 (0x00b8)
-#define VPIF_CH1_V_CFG_03 (0x00bc)
-
-#define VPIF_CH2_TOP_STRT_ADD_LUMA (0x00c0)
-#define VPIF_CH2_BTM_STRT_ADD_LUMA (0x00c4)
-#define VPIF_CH2_TOP_STRT_ADD_CHROMA (0x00c8)
-#define VPIF_CH2_BTM_STRT_ADD_CHROMA (0x00cc)
-#define VPIF_CH2_TOP_STRT_ADD_HANC (0x00d0)
-#define VPIF_CH2_BTM_STRT_ADD_HANC (0x00d4)
-#define VPIF_CH2_TOP_STRT_ADD_VANC (0x00d8)
-#define VPIF_CH2_BTM_STRT_ADD_VANC (0x00dc)
-#define VPIF_CH2_SP_CFG (0x00e0)
-#define VPIF_CH2_IMG_ADD_OFST (0x00e4)
-#define VPIF_CH2_HANC_ADD_OFST (0x00e8)
-#define VPIF_CH2_H_CFG (0x00ec)
-#define VPIF_CH2_V_CFG_00 (0x00f0)
-#define VPIF_CH2_V_CFG_01 (0x00f4)
-#define VPIF_CH2_V_CFG_02 (0x00f8)
-#define VPIF_CH2_V_CFG_03 (0x00fc)
-#define VPIF_CH2_HANC0_STRT (0x0100)
-#define VPIF_CH2_HANC0_SIZE (0x0104)
-#define VPIF_CH2_HANC1_STRT (0x0108)
-#define VPIF_CH2_HANC1_SIZE (0x010c)
-#define VPIF_CH2_VANC0_STRT (0x0110)
-#define VPIF_CH2_VANC0_SIZE (0x0114)
-#define VPIF_CH2_VANC1_STRT (0x0118)
-#define VPIF_CH2_VANC1_SIZE (0x011c)
-
-#define VPIF_CH3_TOP_STRT_ADD_LUMA (0x0140)
-#define VPIF_CH3_BTM_STRT_ADD_LUMA (0x0144)
-#define VPIF_CH3_TOP_STRT_ADD_CHROMA (0x0148)
-#define VPIF_CH3_BTM_STRT_ADD_CHROMA (0x014c)
-#define VPIF_CH3_TOP_STRT_ADD_HANC (0x0150)
-#define VPIF_CH3_BTM_STRT_ADD_HANC (0x0154)
-#define VPIF_CH3_TOP_STRT_ADD_VANC (0x0158)
-#define VPIF_CH3_BTM_STRT_ADD_VANC (0x015c)
-#define VPIF_CH3_SP_CFG (0x0160)
-#define VPIF_CH3_IMG_ADD_OFST (0x0164)
-#define VPIF_CH3_HANC_ADD_OFST (0x0168)
-#define VPIF_CH3_H_CFG (0x016c)
-#define VPIF_CH3_V_CFG_00 (0x0170)
-#define VPIF_CH3_V_CFG_01 (0x0174)
-#define VPIF_CH3_V_CFG_02 (0x0178)
-#define VPIF_CH3_V_CFG_03 (0x017c)
-#define VPIF_CH3_HANC0_STRT (0x0180)
-#define VPIF_CH3_HANC0_SIZE (0x0184)
-#define VPIF_CH3_HANC1_STRT (0x0188)
-#define VPIF_CH3_HANC1_SIZE (0x018c)
-#define VPIF_CH3_VANC0_STRT (0x0190)
-#define VPIF_CH3_VANC0_SIZE (0x0194)
-#define VPIF_CH3_VANC1_STRT (0x0198)
-#define VPIF_CH3_VANC1_SIZE (0x019c)
-
-#define VPIF_IODFT_CTRL (0x01c0)
-
-/* Functions for bit Manipulation */
-static inline void vpif_set_bit(u32 reg, u32 bit)
-{
- regw((regr(reg)) | (0x01 << bit), reg);
-}
-
-static inline void vpif_clr_bit(u32 reg, u32 bit)
-{
- regw(((regr(reg)) & ~(0x01 << bit)), reg);
-}
-
-/* Macro for Generating mask */
-#ifdef GENERATE_MASK
-#undef GENERATE_MASK
-#endif
-
-#define GENERATE_MASK(bits, pos) \
- ((((0xFFFFFFFF) << (32 - bits)) >> (32 - bits)) << pos)
-
-/* Bit positions in the channel control registers */
-#define VPIF_CH_DATA_MODE_BIT (2)
-#define VPIF_CH_YC_MUX_BIT (3)
-#define VPIF_CH_SDR_FMT_BIT (4)
-#define VPIF_CH_HANC_EN_BIT (8)
-#define VPIF_CH_VANC_EN_BIT (9)
-
-#define VPIF_CAPTURE_CH_NIP (10)
-#define VPIF_DISPLAY_CH_NIP (11)
-
-#define VPIF_DISPLAY_PIX_EN_BIT (10)
-
-#define VPIF_CH_INPUT_FIELD_FRAME_BIT (12)
-
-#define VPIF_CH_FID_POLARITY_BIT (15)
-#define VPIF_CH_V_VALID_POLARITY_BIT (14)
-#define VPIF_CH_H_VALID_POLARITY_BIT (13)
-#define VPIF_CH_DATA_WIDTH_BIT (28)
-
-#define VPIF_CH_CLK_EDGE_CTRL_BIT (31)
-
-/* Mask various length */
-#define VPIF_CH_EAVSAV_MASK GENERATE_MASK(13, 0)
-#define VPIF_CH_LEN_MASK GENERATE_MASK(12, 0)
-#define VPIF_CH_WIDTH_MASK GENERATE_MASK(13, 0)
-#define VPIF_CH_LEN_SHIFT (16)
-
-/* VPIF masks for registers */
-#define VPIF_REQ_SIZE_MASK (0x1ff)
-
-/* bit posotion of interrupt vpif_ch_intr register */
-#define VPIF_INTEN_FRAME_CH0 (0x00000001)
-#define VPIF_INTEN_FRAME_CH1 (0x00000002)
-#define VPIF_INTEN_FRAME_CH2 (0x00000004)
-#define VPIF_INTEN_FRAME_CH3 (0x00000008)
-
-/* bit position of clock and channel enable in vpif_chn_ctrl register */
-
-#define VPIF_CH0_CLK_EN (0x00000002)
-#define VPIF_CH0_EN (0x00000001)
-#define VPIF_CH1_CLK_EN (0x00000002)
-#define VPIF_CH1_EN (0x00000001)
-#define VPIF_CH2_CLK_EN (0x00000002)
-#define VPIF_CH2_EN (0x00000001)
-#define VPIF_CH3_CLK_EN (0x00000002)
-#define VPIF_CH3_EN (0x00000001)
-#define VPIF_CH_CLK_EN (0x00000002)
-#define VPIF_CH_EN (0x00000001)
-
-#define VPIF_INT_TOP (0x00)
-#define VPIF_INT_BOTTOM (0x01)
-#define VPIF_INT_BOTH (0x02)
-
-#define VPIF_CH0_INT_CTRL_SHIFT (6)
-#define VPIF_CH1_INT_CTRL_SHIFT (6)
-#define VPIF_CH2_INT_CTRL_SHIFT (6)
-#define VPIF_CH3_INT_CTRL_SHIFT (6)
-#define VPIF_CH_INT_CTRL_SHIFT (6)
-
-#define VPIF_CH2_CLIP_ANC_EN 14
-#define VPIF_CH2_CLIP_ACTIVE_EN 13
-
-#define VPIF_CH3_CLIP_ANC_EN 14
-#define VPIF_CH3_CLIP_ACTIVE_EN 13
-
-/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
-#define channel0_intr_assert() (regw((regr(VPIF_CH0_CTRL)|\
- (VPIF_INT_BOTH << VPIF_CH0_INT_CTRL_SHIFT)), VPIF_CH0_CTRL))
-
-/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
-#define channel1_intr_assert() (regw((regr(VPIF_CH1_CTRL)|\
- (VPIF_INT_BOTH << VPIF_CH1_INT_CTRL_SHIFT)), VPIF_CH1_CTRL))
-
-/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
-#define channel2_intr_assert() (regw((regr(VPIF_CH2_CTRL)|\
- (VPIF_INT_BOTH << VPIF_CH2_INT_CTRL_SHIFT)), VPIF_CH2_CTRL))
-
-/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
-#define channel3_intr_assert() (regw((regr(VPIF_CH3_CTRL)|\
- (VPIF_INT_BOTH << VPIF_CH3_INT_CTRL_SHIFT)), VPIF_CH3_CTRL))
-
-#define VPIF_CH_FID_MASK (0x20)
-#define VPIF_CH_FID_SHIFT (5)
-
-#define VPIF_NTSC_VBI_START_FIELD0 (1)
-#define VPIF_NTSC_VBI_START_FIELD1 (263)
-#define VPIF_PAL_VBI_START_FIELD0 (624)
-#define VPIF_PAL_VBI_START_FIELD1 (311)
-
-#define VPIF_NTSC_HBI_START_FIELD0 (1)
-#define VPIF_NTSC_HBI_START_FIELD1 (263)
-#define VPIF_PAL_HBI_START_FIELD0 (624)
-#define VPIF_PAL_HBI_START_FIELD1 (311)
-
-#define VPIF_NTSC_VBI_COUNT_FIELD0 (20)
-#define VPIF_NTSC_VBI_COUNT_FIELD1 (19)
-#define VPIF_PAL_VBI_COUNT_FIELD0 (24)
-#define VPIF_PAL_VBI_COUNT_FIELD1 (25)
-
-#define VPIF_NTSC_HBI_COUNT_FIELD0 (263)
-#define VPIF_NTSC_HBI_COUNT_FIELD1 (262)
-#define VPIF_PAL_HBI_COUNT_FIELD0 (312)
-#define VPIF_PAL_HBI_COUNT_FIELD1 (313)
-
-#define VPIF_NTSC_VBI_SAMPLES_PER_LINE (720)
-#define VPIF_PAL_VBI_SAMPLES_PER_LINE (720)
-#define VPIF_NTSC_HBI_SAMPLES_PER_LINE (268)
-#define VPIF_PAL_HBI_SAMPLES_PER_LINE (280)
-
-#define VPIF_CH_VANC_EN (0x20)
-#define VPIF_DMA_REQ_SIZE (0x080)
-#define VPIF_EMULATION_DISABLE (0x01)
-
-extern u8 irq_vpif_capture_channel[VPIF_NUM_CHANNELS];
-
-/* inline function to enable/disable channel0 */
-static inline void enable_channel0(int enable)
-{
- if (enable)
- regw((regr(VPIF_CH0_CTRL) | (VPIF_CH0_EN)), VPIF_CH0_CTRL);
- else
- regw((regr(VPIF_CH0_CTRL) & (~VPIF_CH0_EN)), VPIF_CH0_CTRL);
-}
-
-/* inline function to enable/disable channel1 */
-static inline void enable_channel1(int enable)
-{
- if (enable)
- regw((regr(VPIF_CH1_CTRL) | (VPIF_CH1_EN)), VPIF_CH1_CTRL);
- else
- regw((regr(VPIF_CH1_CTRL) & (~VPIF_CH1_EN)), VPIF_CH1_CTRL);
-}
-
-/* inline function to enable interrupt for channel0 */
-static inline void channel0_intr_enable(int enable)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&vpif_lock, flags);
-
- if (enable) {
- regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
- regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
-
- regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH0), VPIF_INTEN);
- regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
- VPIF_INTEN_SET);
- } else {
- regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH0)), VPIF_INTEN);
- regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
- VPIF_INTEN_SET);
- }
- spin_unlock_irqrestore(&vpif_lock, flags);
-}
-
-/* inline function to enable interrupt for channel1 */
-static inline void channel1_intr_enable(int enable)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&vpif_lock, flags);
-
- if (enable) {
- regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
- regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
-
- regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH1), VPIF_INTEN);
- regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
- VPIF_INTEN_SET);
- } else {
- regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH1)), VPIF_INTEN);
- regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
- VPIF_INTEN_SET);
- }
- spin_unlock_irqrestore(&vpif_lock, flags);
-}
-
-/* inline function to set buffer addresses in case of Y/C non mux mode */
-static inline void ch0_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
-{
- regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
- regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
- regw(top_strt_chroma, VPIF_CH1_TOP_STRT_ADD_CHROMA);
- regw(btm_strt_chroma, VPIF_CH1_BTM_STRT_ADD_CHROMA);
-}
-
-/* inline function to set buffer addresses in VPIF registers for video data */
-static inline void ch0_set_videobuf_addr(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
-{
- regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
- regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
- regw(top_strt_chroma, VPIF_CH0_TOP_STRT_ADD_CHROMA);
- regw(btm_strt_chroma, VPIF_CH0_BTM_STRT_ADD_CHROMA);
-}
-
-static inline void ch1_set_videobuf_addr(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
-{
-
- regw(top_strt_luma, VPIF_CH1_TOP_STRT_ADD_LUMA);
- regw(btm_strt_luma, VPIF_CH1_BTM_STRT_ADD_LUMA);
- regw(top_strt_chroma, VPIF_CH1_TOP_STRT_ADD_CHROMA);
- regw(btm_strt_chroma, VPIF_CH1_BTM_STRT_ADD_CHROMA);
-}
-
-static inline void ch0_set_vbi_addr(unsigned long top_vbi,
- unsigned long btm_vbi, unsigned long a, unsigned long b)
-{
- regw(top_vbi, VPIF_CH0_TOP_STRT_ADD_VANC);
- regw(btm_vbi, VPIF_CH0_BTM_STRT_ADD_VANC);
-}
-
-static inline void ch0_set_hbi_addr(unsigned long top_vbi,
- unsigned long btm_vbi, unsigned long a, unsigned long b)
-{
- regw(top_vbi, VPIF_CH0_TOP_STRT_ADD_HANC);
- regw(btm_vbi, VPIF_CH0_BTM_STRT_ADD_HANC);
-}
-
-static inline void ch1_set_vbi_addr(unsigned long top_vbi,
- unsigned long btm_vbi, unsigned long a, unsigned long b)
-{
- regw(top_vbi, VPIF_CH1_TOP_STRT_ADD_VANC);
- regw(btm_vbi, VPIF_CH1_BTM_STRT_ADD_VANC);
-}
-
-static inline void ch1_set_hbi_addr(unsigned long top_vbi,
- unsigned long btm_vbi, unsigned long a, unsigned long b)
-{
- regw(top_vbi, VPIF_CH1_TOP_STRT_ADD_HANC);
- regw(btm_vbi, VPIF_CH1_BTM_STRT_ADD_HANC);
-}
-
-/* Inline function to enable raw vbi in the given channel */
-static inline void disable_raw_feature(u8 channel_id, u8 index)
-{
- u32 ctrl_reg;
- if (0 == channel_id)
- ctrl_reg = VPIF_CH0_CTRL;
- else
- ctrl_reg = VPIF_CH1_CTRL;
-
- if (1 == index)
- vpif_clr_bit(ctrl_reg, VPIF_CH_VANC_EN_BIT);
- else
- vpif_clr_bit(ctrl_reg, VPIF_CH_HANC_EN_BIT);
-}
-
-static inline void enable_raw_feature(u8 channel_id, u8 index)
-{
- u32 ctrl_reg;
- if (0 == channel_id)
- ctrl_reg = VPIF_CH0_CTRL;
- else
- ctrl_reg = VPIF_CH1_CTRL;
-
- if (1 == index)
- vpif_set_bit(ctrl_reg, VPIF_CH_VANC_EN_BIT);
- else
- vpif_set_bit(ctrl_reg, VPIF_CH_HANC_EN_BIT);
-}
-
-/* inline function to enable/disable channel2 */
-static inline void enable_channel2(int enable)
-{
- if (enable) {
- regw((regr(VPIF_CH2_CTRL) | (VPIF_CH2_CLK_EN)), VPIF_CH2_CTRL);
- regw((regr(VPIF_CH2_CTRL) | (VPIF_CH2_EN)), VPIF_CH2_CTRL);
- } else {
- regw((regr(VPIF_CH2_CTRL) & (~VPIF_CH2_CLK_EN)), VPIF_CH2_CTRL);
- regw((regr(VPIF_CH2_CTRL) & (~VPIF_CH2_EN)), VPIF_CH2_CTRL);
- }
-}
-
-/* inline function to enable/disable channel3 */
-static inline void enable_channel3(int enable)
-{
- if (enable) {
- regw((regr(VPIF_CH3_CTRL) | (VPIF_CH3_CLK_EN)), VPIF_CH3_CTRL);
- regw((regr(VPIF_CH3_CTRL) | (VPIF_CH3_EN)), VPIF_CH3_CTRL);
- } else {
- regw((regr(VPIF_CH3_CTRL) & (~VPIF_CH3_CLK_EN)), VPIF_CH3_CTRL);
- regw((regr(VPIF_CH3_CTRL) & (~VPIF_CH3_EN)), VPIF_CH3_CTRL);
- }
-}
-
-/* inline function to enable interrupt for channel2 */
-static inline void channel2_intr_enable(int enable)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&vpif_lock, flags);
-
- if (enable) {
- regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
- regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
- regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH2), VPIF_INTEN);
- regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
- VPIF_INTEN_SET);
- } else {
- regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH2)), VPIF_INTEN);
- regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
- VPIF_INTEN_SET);
- }
- spin_unlock_irqrestore(&vpif_lock, flags);
-}
-
-/* inline function to enable interrupt for channel3 */
-static inline void channel3_intr_enable(int enable)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&vpif_lock, flags);
-
- if (enable) {
- regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
- regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
-
- regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH3), VPIF_INTEN);
- regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
- VPIF_INTEN_SET);
- } else {
- regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH3)), VPIF_INTEN);
- regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
- VPIF_INTEN_SET);
- }
- spin_unlock_irqrestore(&vpif_lock, flags);
-}
-
-/* inline function to enable raw vbi data for channel2 */
-static inline void channel2_raw_enable(int enable, u8 index)
-{
- u32 mask;
-
- if (1 == index)
- mask = VPIF_CH_VANC_EN_BIT;
- else
- mask = VPIF_CH_HANC_EN_BIT;
-
- if (enable)
- vpif_set_bit(VPIF_CH2_CTRL, mask);
- else
- vpif_clr_bit(VPIF_CH2_CTRL, mask);
-}
-
-/* inline function to enable raw vbi data for channel3*/
-static inline void channel3_raw_enable(int enable, u8 index)
-{
- u32 mask;
-
- if (1 == index)
- mask = VPIF_CH_VANC_EN_BIT;
- else
- mask = VPIF_CH_HANC_EN_BIT;
-
- if (enable)
- vpif_set_bit(VPIF_CH3_CTRL, mask);
- else
- vpif_clr_bit(VPIF_CH3_CTRL, mask);
-}
-
-/* function to enable clipping (for both active and blanking regions) on ch 2 */
-static inline void channel2_clipping_enable(int enable)
-{
- if (enable) {
- vpif_set_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ANC_EN);
- vpif_set_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ACTIVE_EN);
- } else {
- vpif_clr_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ANC_EN);
- vpif_clr_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ACTIVE_EN);
- }
-}
-
-/* function to enable clipping (for both active and blanking regions) on ch 2 */
-static inline void channel3_clipping_enable(int enable)
-{
- if (enable) {
- vpif_set_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ANC_EN);
- vpif_set_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ACTIVE_EN);
- } else {
- vpif_clr_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ANC_EN);
- vpif_clr_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ACTIVE_EN);
- }
-}
-
-/* inline function to set buffer addresses in case of Y/C non mux mode */
-static inline void ch2_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
-{
- regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
- regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
- regw(top_strt_chroma, VPIF_CH3_TOP_STRT_ADD_CHROMA);
- regw(btm_strt_chroma, VPIF_CH3_BTM_STRT_ADD_CHROMA);
-}
-
-/* inline function to set buffer addresses in VPIF registers for video data */
-static inline void ch2_set_videobuf_addr(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
-{
- regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
- regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
- regw(top_strt_chroma, VPIF_CH2_TOP_STRT_ADD_CHROMA);
- regw(btm_strt_chroma, VPIF_CH2_BTM_STRT_ADD_CHROMA);
-}
-
-static inline void ch3_set_videobuf_addr(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
-{
- regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_LUMA);
- regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_LUMA);
- regw(top_strt_chroma, VPIF_CH3_TOP_STRT_ADD_CHROMA);
- regw(btm_strt_chroma, VPIF_CH3_BTM_STRT_ADD_CHROMA);
-}
-
-/* inline function to set buffer addresses in VPIF registers for vbi data */
-static inline void ch2_set_vbi_addr(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
-{
- regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_VANC);
- regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_VANC);
-}
-
-static inline void ch3_set_vbi_addr(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
-{
- regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_VANC);
- regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_VANC);
-}
-
-static inline int vpif_intr_status(int channel)
-{
- int status = 0;
- int mask;
-
- if (channel < 0 || channel > 3)
- return 0;
-
- mask = 1 << channel;
- status = regr(VPIF_STATUS) & mask;
- regw(status, VPIF_STATUS_CLR);
-
- return status;
-}
-
-#define VPIF_MAX_NAME (30)
-
-/* This structure will store size parameters as per the mode selected by user */
-struct vpif_channel_config_params {
- char name[VPIF_MAX_NAME]; /* Name of the mode */
- u16 width; /* Indicates width of the image */
- u16 height; /* Indicates height of the image */
- u8 frm_fmt; /* Interlaced (0) or progressive (1) */
- u8 ycmux_mode; /* This mode requires one (0) or two (1)
- channels */
- u16 eav2sav; /* length of eav 2 sav */
- u16 sav2eav; /* length of sav 2 eav */
- u16 l1, l3, l5, l7, l9, l11; /* Other parameter configurations */
- u16 vsize; /* Vertical size of the image */
- u8 capture_format; /* Indicates whether capture format
- * is in BT or in CCD/CMOS */
- u8 vbi_supported; /* Indicates whether this mode
- * supports capturing vbi or not */
- u8 hd_sd; /* HDTV (1) or SDTV (0) format */
- v4l2_std_id stdid; /* SDTV format */
- u32 dv_preset; /* HDTV format */
-};
-
-extern const unsigned int vpif_ch_params_count;
-extern const struct vpif_channel_config_params ch_params[];
-
-struct vpif_video_params;
-struct vpif_params;
-struct vpif_vbi_params;
-
-int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id);
-void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
- u8 channel_id);
-int vpif_channel_getfid(u8 channel_id);
-
-enum data_size {
- _8BITS = 0,
- _10BITS,
- _12BITS,
-};
-
-/* Structure for vpif parameters for raw vbi data */
-struct vpif_vbi_params {
- __u32 hstart0; /* Horizontal start of raw vbi data for first field */
- __u32 vstart0; /* Vertical start of raw vbi data for first field */
- __u32 hsize0; /* Horizontal size of raw vbi data for first field */
- __u32 vsize0; /* Vertical size of raw vbi data for first field */
- __u32 hstart1; /* Horizontal start of raw vbi data for second field */
- __u32 vstart1; /* Vertical start of raw vbi data for second field */
- __u32 hsize1; /* Horizontal size of raw vbi data for second field */
- __u32 vsize1; /* Vertical size of raw vbi data for second field */
-};
-
-/* structure for vpif parameters */
-struct vpif_video_params {
- __u8 storage_mode; /* Indicates field or frame mode */
- unsigned long hpitch;
- v4l2_std_id stdid;
-};
-
-struct vpif_params {
- struct vpif_interface iface;
- struct vpif_video_params video_params;
- struct vpif_channel_config_params std_info;
- union param {
- struct vpif_vbi_params vbi_params;
- enum data_size data_sz;
- } params;
-};
-
-#endif /* End of #ifndef VPIF_H */
-
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c
deleted file mode 100644
index 266025e5d81..00000000000
--- a/drivers/media/video/davinci/vpif_capture.c
+++ /dev/null
@@ -1,2444 +0,0 @@
-/*
- * Copyright (C) 2009 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * TODO : add support for VBI & HBI data service
- * add static buffer allocation
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/string.h>
-#include <linux/videodev2.h>
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
-
-#include "vpif_capture.h"
-#include "vpif.h"
-
-MODULE_DESCRIPTION("TI DaVinci VPIF Capture driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(VPIF_CAPTURE_VERSION);
-
-#define vpif_err(fmt, arg...) v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
-#define vpif_dbg(level, debug, fmt, arg...) \
- v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
-
-static int debug = 1;
-static u32 ch0_numbuffers = 3;
-static u32 ch1_numbuffers = 3;
-static u32 ch0_bufsize = 1920 * 1080 * 2;
-static u32 ch1_bufsize = 720 * 576 * 2;
-
-module_param(debug, int, 0644);
-module_param(ch0_numbuffers, uint, S_IRUGO);
-module_param(ch1_numbuffers, uint, S_IRUGO);
-module_param(ch0_bufsize, uint, S_IRUGO);
-module_param(ch1_bufsize, uint, S_IRUGO);
-
-MODULE_PARM_DESC(debug, "Debug level 0-1");
-MODULE_PARM_DESC(ch2_numbuffers, "Channel0 buffer count (default:3)");
-MODULE_PARM_DESC(ch3_numbuffers, "Channel1 buffer count (default:3)");
-MODULE_PARM_DESC(ch2_bufsize, "Channel0 buffer size (default:1920 x 1080 x 2)");
-MODULE_PARM_DESC(ch3_bufsize, "Channel1 buffer size (default:720 x 576 x 2)");
-
-static struct vpif_config_params config_params = {
- .min_numbuffers = 3,
- .numbuffers[0] = 3,
- .numbuffers[1] = 3,
- .min_bufsize[0] = 720 * 480 * 2,
- .min_bufsize[1] = 720 * 480 * 2,
- .channel_bufsize[0] = 1920 * 1080 * 2,
- .channel_bufsize[1] = 720 * 576 * 2,
-};
-
-/* global variables */
-static struct vpif_device vpif_obj = { {NULL} };
-static struct device *vpif_dev;
-static void vpif_calculate_offsets(struct channel_obj *ch);
-static void vpif_config_addr(struct channel_obj *ch, int muxmode);
-
-/**
- * buffer_prepare : callback function for buffer prepare
- * @vb: ptr to vb2_buffer
- *
- * This is the callback function for buffer prepare when vb2_qbuf()
- * function is called. The buffer is prepared and user space virtual address
- * or user address is converted into physical address
- */
-static int vpif_buffer_prepare(struct vb2_buffer *vb)
-{
- /* Get the file handle object and channel object */
- struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_queue *q = vb->vb2_queue;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
- unsigned long addr;
-
- vpif_dbg(2, debug, "vpif_buffer_prepare\n");
-
- common = &ch->common[VPIF_VIDEO_INDEX];
-
- if (vb->state != VB2_BUF_STATE_ACTIVE &&
- vb->state != VB2_BUF_STATE_PREPARED) {
- vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
- if (vb2_plane_vaddr(vb, 0) &&
- vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
- goto exit;
- addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-
- if (q->streaming) {
- if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
- !IS_ALIGNED((addr + common->ybtm_off), 8) ||
- !IS_ALIGNED((addr + common->ctop_off), 8) ||
- !IS_ALIGNED((addr + common->cbtm_off), 8))
- goto exit;
- }
- }
- return 0;
-exit:
- vpif_dbg(1, debug, "buffer_prepare:offset is not aligned to 8 bytes\n");
- return -EINVAL;
-}
-
-/**
- * vpif_buffer_queue_setup : Callback function for buffer setup.
- * @vq: vb2_queue ptr
- * @fmt: v4l2 format
- * @nbuffers: ptr to number of buffers requested by application
- * @nplanes:: contains number of distinct video planes needed to hold a frame
- * @sizes[]: contains the size (in bytes) of each plane.
- * @alloc_ctxs: ptr to allocation context
- *
- * This callback function is called when reqbuf() is called to adjust
- * the buffer count and buffer size
- */
-static int vpif_buffer_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
- unsigned int *nbuffers, unsigned int *nplanes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- /* Get the file handle object and channel object */
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
- unsigned long size;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
-
- vpif_dbg(2, debug, "vpif_buffer_setup\n");
-
- /* If memory type is not mmap, return */
- if (V4L2_MEMORY_MMAP == common->memory) {
- /* Calculate the size of the buffer */
- size = config_params.channel_bufsize[ch->channel_id];
- /*
- * Checking if the buffer size exceeds the available buffer
- * ycmux_mode = 0 means 1 channel mode HD and
- * ycmux_mode = 1 means 2 channels mode SD
- */
- if (ch->vpifparams.std_info.ycmux_mode == 0) {
- if (config_params.video_limit[ch->channel_id])
- while (size * *nbuffers >
- (config_params.video_limit[0]
- + config_params.video_limit[1]))
- (*nbuffers)--;
- } else {
- if (config_params.video_limit[ch->channel_id])
- while (size * *nbuffers >
- config_params.video_limit[ch->channel_id])
- (*nbuffers)--;
- }
-
- } else {
- size = common->fmt.fmt.pix.sizeimage;
- }
-
- if (*nbuffers < config_params.min_numbuffers)
- *nbuffers = config_params.min_numbuffers;
-
- *nplanes = 1;
- sizes[0] = size;
- alloc_ctxs[0] = common->alloc_ctx;
-
- return 0;
-}
-
-/**
- * vpif_buffer_queue : Callback function to add buffer to DMA queue
- * @vb: ptr to vb2_buffer
- */
-static void vpif_buffer_queue(struct vb2_buffer *vb)
-{
- /* Get the file handle object and channel object */
- struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
- struct channel_obj *ch = fh->channel;
- struct vpif_cap_buffer *buf = container_of(vb,
- struct vpif_cap_buffer, vb);
- struct common_obj *common;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
-
- vpif_dbg(2, debug, "vpif_buffer_queue\n");
-
- /* add the buffer to the DMA queue */
- list_add_tail(&buf->list, &common->dma_queue);
-}
-
-/**
- * vpif_buf_cleanup : Callback function to free buffer
- * @vb: ptr to vb2_buffer
- *
- * This function is called from the videobuf2 layer to free memory
- * allocated to the buffers
- */
-static void vpif_buf_cleanup(struct vb2_buffer *vb)
-{
- /* Get the file handle object and channel object */
- struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
- struct vpif_cap_buffer *buf = container_of(vb,
- struct vpif_cap_buffer, vb);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
- unsigned long flags;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
-
- spin_lock_irqsave(&common->irqlock, flags);
- if (vb->state == VB2_BUF_STATE_ACTIVE)
- list_del_init(&buf->list);
- spin_unlock_irqrestore(&common->irqlock, flags);
-
-}
-
-static void vpif_wait_prepare(struct vb2_queue *vq)
-{
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
- mutex_unlock(&common->lock);
-}
-
-static void vpif_wait_finish(struct vb2_queue *vq)
-{
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
- mutex_lock(&common->lock);
-}
-
-static int vpif_buffer_init(struct vb2_buffer *vb)
-{
- struct vpif_cap_buffer *buf = container_of(vb,
- struct vpif_cap_buffer, vb);
-
- INIT_LIST_HEAD(&buf->list);
-
- return 0;
-}
-
-static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] =
- { {1, 1} };
-
-static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
- struct vpif_capture_config *vpif_config_data =
- vpif_dev->platform_data;
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct vpif_params *vpif = &ch->vpifparams;
- unsigned long addr = 0;
- int ret;
-
- /* If buffer queue is empty, return error */
- if (list_empty(&common->dma_queue)) {
- vpif_dbg(1, debug, "buffer queue is empty\n");
- return -EIO;
- }
-
- /* Get the next frame from the buffer queue */
- common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
- struct vpif_cap_buffer, list);
- /* Remove buffer from the buffer queue */
- list_del(&common->cur_frm->list);
- /* Mark state of the current frame to active */
- common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
- /* Initialize field_id and started member */
- ch->field_id = 0;
- common->started = 1;
- addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
-
- /* Calculate the offset for Y and C data in the buffer */
- vpif_calculate_offsets(ch);
-
- if ((vpif->std_info.frm_fmt &&
- ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE) &&
- (common->fmt.fmt.pix.field != V4L2_FIELD_ANY))) ||
- (!vpif->std_info.frm_fmt &&
- (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
- vpif_dbg(1, debug, "conflict in field format and std format\n");
- return -EINVAL;
- }
-
- /* configure 1 or 2 channel mode */
- ret = vpif_config_data->setup_input_channel_mode
- (vpif->std_info.ycmux_mode);
-
- if (ret < 0) {
- vpif_dbg(1, debug, "can't set vpif channel mode\n");
- return ret;
- }
-
- /* Call vpif_set_params function to set the parameters and addresses */
- ret = vpif_set_video_params(vpif, ch->channel_id);
-
- if (ret < 0) {
- vpif_dbg(1, debug, "can't set video params\n");
- return ret;
- }
-
- common->started = ret;
- vpif_config_addr(ch, ret);
-
- common->set_addr(addr + common->ytop_off,
- addr + common->ybtm_off,
- addr + common->ctop_off,
- addr + common->cbtm_off);
-
- /**
- * Set interrupt for both the fields in VPIF Register enable channel in
- * VPIF register
- */
- if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)) {
- channel0_intr_assert();
- channel0_intr_enable(1);
- enable_channel0(1);
- }
- if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
- (common->started == 2)) {
- channel1_intr_assert();
- channel1_intr_enable(1);
- enable_channel1(1);
- }
- channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
-
- return 0;
-}
-
-/* abort streaming and wait for last buffer */
-static int vpif_stop_streaming(struct vb2_queue *vq)
-{
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
-
- if (!vb2_is_streaming(vq))
- return 0;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
-
- /* release all active buffers */
- while (!list_empty(&common->dma_queue)) {
- common->next_frm = list_entry(common->dma_queue.next,
- struct vpif_cap_buffer, list);
- list_del(&common->next_frm->list);
- vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR);
- }
-
- return 0;
-}
-
-static struct vb2_ops video_qops = {
- .queue_setup = vpif_buffer_queue_setup,
- .wait_prepare = vpif_wait_prepare,
- .wait_finish = vpif_wait_finish,
- .buf_init = vpif_buffer_init,
- .buf_prepare = vpif_buffer_prepare,
- .start_streaming = vpif_start_streaming,
- .stop_streaming = vpif_stop_streaming,
- .buf_cleanup = vpif_buf_cleanup,
- .buf_queue = vpif_buffer_queue,
-};
-
-/**
- * vpif_process_buffer_complete: process a completed buffer
- * @common: ptr to common channel object
- *
- * This function time stamp the buffer and mark it as DONE. It also
- * wake up any process waiting on the QUEUE and set the next buffer
- * as current
- */
-static void vpif_process_buffer_complete(struct common_obj *common)
-{
- do_gettimeofday(&common->cur_frm->vb.v4l2_buf.timestamp);
- vb2_buffer_done(&common->cur_frm->vb,
- VB2_BUF_STATE_DONE);
- /* Make curFrm pointing to nextFrm */
- common->cur_frm = common->next_frm;
-}
-
-/**
- * vpif_schedule_next_buffer: set next buffer address for capture
- * @common : ptr to common channel object
- *
- * This function will get next buffer from the dma queue and
- * set the buffer address in the vpif register for capture.
- * the buffer is marked active
- */
-static void vpif_schedule_next_buffer(struct common_obj *common)
-{
- unsigned long addr = 0;
-
- common->next_frm = list_entry(common->dma_queue.next,
- struct vpif_cap_buffer, list);
- /* Remove that buffer from the buffer queue */
- list_del(&common->next_frm->list);
- common->next_frm->vb.state = VB2_BUF_STATE_ACTIVE;
- addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb, 0);
-
- /* Set top and bottom field addresses in VPIF registers */
- common->set_addr(addr + common->ytop_off,
- addr + common->ybtm_off,
- addr + common->ctop_off,
- addr + common->cbtm_off);
-}
-
-/**
- * vpif_channel_isr : ISR handler for vpif capture
- * @irq: irq number
- * @dev_id: dev_id ptr
- *
- * It changes status of the captured buffer, takes next buffer from the queue
- * and sets its address in VPIF registers
- */
-static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
-{
- struct vpif_device *dev = &vpif_obj;
- struct common_obj *common;
- struct channel_obj *ch;
- enum v4l2_field field;
- int channel_id = 0;
- int fid = -1, i;
-
- channel_id = *(int *)(dev_id);
- if (!vpif_intr_status(channel_id))
- return IRQ_NONE;
-
- ch = dev->dev[channel_id];
-
- field = ch->common[VPIF_VIDEO_INDEX].fmt.fmt.pix.field;
-
- for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) {
- common = &ch->common[i];
- /* skip If streaming is not started in this channel */
- if (0 == common->started)
- continue;
-
- /* Check the field format */
- if (1 == ch->vpifparams.std_info.frm_fmt) {
- /* Progressive mode */
- if (list_empty(&common->dma_queue))
- continue;
-
- if (!channel_first_int[i][channel_id])
- vpif_process_buffer_complete(common);
-
- channel_first_int[i][channel_id] = 0;
-
- vpif_schedule_next_buffer(common);
-
-
- channel_first_int[i][channel_id] = 0;
- } else {
- /**
- * Interlaced mode. If it is first interrupt, ignore
- * it
- */
- if (channel_first_int[i][channel_id]) {
- channel_first_int[i][channel_id] = 0;
- continue;
- }
- if (0 == i) {
- ch->field_id ^= 1;
- /* Get field id from VPIF registers */
- fid = vpif_channel_getfid(ch->channel_id);
- if (fid != ch->field_id) {
- /**
- * If field id does not match stored
- * field id, make them in sync
- */
- if (0 == fid)
- ch->field_id = fid;
- return IRQ_HANDLED;
- }
- }
- /* device field id and local field id are in sync */
- if (0 == fid) {
- /* this is even field */
- if (common->cur_frm == common->next_frm)
- continue;
-
- /* mark the current buffer as done */
- vpif_process_buffer_complete(common);
- } else if (1 == fid) {
- /* odd field */
- if (list_empty(&common->dma_queue) ||
- (common->cur_frm != common->next_frm))
- continue;
-
- vpif_schedule_next_buffer(common);
- }
- }
- }
- return IRQ_HANDLED;
-}
-
-/**
- * vpif_update_std_info() - update standard related info
- * @ch: ptr to channel object
- *
- * For a given standard selected by application, update values
- * in the device data structures
- */
-static int vpif_update_std_info(struct channel_obj *ch)
-{
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct vpif_params *vpifparams = &ch->vpifparams;
- const struct vpif_channel_config_params *config;
- struct vpif_channel_config_params *std_info = &vpifparams->std_info;
- struct video_obj *vid_ch = &ch->video;
- int index;
-
- vpif_dbg(2, debug, "vpif_update_std_info\n");
-
- for (index = 0; index < vpif_ch_params_count; index++) {
- config = &ch_params[index];
- if (config->hd_sd == 0) {
- vpif_dbg(2, debug, "SD format\n");
- if (config->stdid & vid_ch->stdid) {
- memcpy(std_info, config, sizeof(*config));
- break;
- }
- } else {
- vpif_dbg(2, debug, "HD format\n");
- if (config->dv_preset == vid_ch->dv_preset) {
- memcpy(std_info, config, sizeof(*config));
- break;
- }
- }
- }
-
- /* standard not found */
- if (index == vpif_ch_params_count)
- return -EINVAL;
-
- common->fmt.fmt.pix.width = std_info->width;
- common->width = std_info->width;
- common->fmt.fmt.pix.height = std_info->height;
- common->height = std_info->height;
- common->fmt.fmt.pix.bytesperline = std_info->width;
- vpifparams->video_params.hpitch = std_info->width;
- vpifparams->video_params.storage_mode = std_info->frm_fmt;
-
- return 0;
-}
-
-/**
- * vpif_calculate_offsets : This function calculates buffers offsets
- * @ch : ptr to channel object
- *
- * This function calculates buffer offsets for Y and C in the top and
- * bottom field
- */
-static void vpif_calculate_offsets(struct channel_obj *ch)
-{
- unsigned int hpitch, vpitch, sizeimage;
- struct video_obj *vid_ch = &(ch->video);
- struct vpif_params *vpifparams = &ch->vpifparams;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- enum v4l2_field field = common->fmt.fmt.pix.field;
-
- vpif_dbg(2, debug, "vpif_calculate_offsets\n");
-
- if (V4L2_FIELD_ANY == field) {
- if (vpifparams->std_info.frm_fmt)
- vid_ch->buf_field = V4L2_FIELD_NONE;
- else
- vid_ch->buf_field = V4L2_FIELD_INTERLACED;
- } else
- vid_ch->buf_field = common->fmt.fmt.pix.field;
-
- sizeimage = common->fmt.fmt.pix.sizeimage;
-
- hpitch = common->fmt.fmt.pix.bytesperline;
- vpitch = sizeimage / (hpitch * 2);
-
- if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
- (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
- /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
- common->ytop_off = 0;
- common->ybtm_off = hpitch;
- common->ctop_off = sizeimage / 2;
- common->cbtm_off = sizeimage / 2 + hpitch;
- } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
- /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
- common->ytop_off = 0;
- common->ybtm_off = sizeimage / 4;
- common->ctop_off = sizeimage / 2;
- common->cbtm_off = common->ctop_off + sizeimage / 4;
- } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
- /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
- common->ybtm_off = 0;
- common->ytop_off = sizeimage / 4;
- common->cbtm_off = sizeimage / 2;
- common->ctop_off = common->cbtm_off + sizeimage / 4;
- }
- if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
- (V4L2_FIELD_INTERLACED == vid_ch->buf_field))
- vpifparams->video_params.storage_mode = 1;
- else
- vpifparams->video_params.storage_mode = 0;
-
- if (1 == vpifparams->std_info.frm_fmt)
- vpifparams->video_params.hpitch =
- common->fmt.fmt.pix.bytesperline;
- else {
- if ((field == V4L2_FIELD_ANY)
- || (field == V4L2_FIELD_INTERLACED))
- vpifparams->video_params.hpitch =
- common->fmt.fmt.pix.bytesperline * 2;
- else
- vpifparams->video_params.hpitch =
- common->fmt.fmt.pix.bytesperline;
- }
-
- ch->vpifparams.video_params.stdid = vpifparams->std_info.stdid;
-}
-
-/**
- * vpif_config_format: configure default frame format in the device
- * ch : ptr to channel object
- */
-static void vpif_config_format(struct channel_obj *ch)
-{
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- vpif_dbg(2, debug, "vpif_config_format\n");
-
- common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
- if (config_params.numbuffers[ch->channel_id] == 0)
- common->memory = V4L2_MEMORY_USERPTR;
- else
- common->memory = V4L2_MEMORY_MMAP;
-
- common->fmt.fmt.pix.sizeimage
- = config_params.channel_bufsize[ch->channel_id];
-
- if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
- common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
- else
- common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
- common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-}
-
-/**
- * vpif_get_default_field() - Get default field type based on interface
- * @vpif_params - ptr to vpif params
- */
-static inline enum v4l2_field vpif_get_default_field(
- struct vpif_interface *iface)
-{
- return (iface->if_type == VPIF_IF_RAW_BAYER) ? V4L2_FIELD_NONE :
- V4L2_FIELD_INTERLACED;
-}
-
-/**
- * vpif_check_format() - check given pixel format for compatibility
- * @ch - channel ptr
- * @pixfmt - Given pixel format
- * @update - update the values as per hardware requirement
- *
- * Check the application pixel format for S_FMT and update the input
- * values as per hardware limits for TRY_FMT. The default pixel and
- * field format is selected based on interface type.
- */
-static int vpif_check_format(struct channel_obj *ch,
- struct v4l2_pix_format *pixfmt,
- int update)
-{
- struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
- struct vpif_params *vpif_params = &ch->vpifparams;
- enum v4l2_field field = pixfmt->field;
- u32 sizeimage, hpitch, vpitch;
- int ret = -EINVAL;
-
- vpif_dbg(2, debug, "vpif_check_format\n");
- /**
- * first check for the pixel format. If if_type is Raw bayer,
- * only V4L2_PIX_FMT_SBGGR8 format is supported. Otherwise only
- * V4L2_PIX_FMT_YUV422P is supported
- */
- if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
- if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) {
- if (!update) {
- vpif_dbg(2, debug, "invalid pix format\n");
- goto exit;
- }
- pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
- }
- } else {
- if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) {
- if (!update) {
- vpif_dbg(2, debug, "invalid pixel format\n");
- goto exit;
- }
- pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
- }
- }
-
- if (!(VPIF_VALID_FIELD(field))) {
- if (!update) {
- vpif_dbg(2, debug, "invalid field format\n");
- goto exit;
- }
- /**
- * By default use FIELD_NONE for RAW Bayer capture
- * and FIELD_INTERLACED for other interfaces
- */
- field = vpif_get_default_field(&vpif_params->iface);
- } else if (field == V4L2_FIELD_ANY)
- /* unsupported field. Use default */
- field = vpif_get_default_field(&vpif_params->iface);
-
- /* validate the hpitch */
- hpitch = pixfmt->bytesperline;
- if (hpitch < vpif_params->std_info.width) {
- if (!update) {
- vpif_dbg(2, debug, "invalid hpitch\n");
- goto exit;
- }
- hpitch = vpif_params->std_info.width;
- }
-
- sizeimage = pixfmt->sizeimage;
-
- vpitch = sizeimage / (hpitch * 2);
-
- /* validate the vpitch */
- if (vpitch < vpif_params->std_info.height) {
- if (!update) {
- vpif_dbg(2, debug, "Invalid vpitch\n");
- goto exit;
- }
- vpitch = vpif_params->std_info.height;
- }
-
- /* Check for 8 byte alignment */
- if (!ALIGN(hpitch, 8)) {
- if (!update) {
- vpif_dbg(2, debug, "invalid pitch alignment\n");
- goto exit;
- }
- /* adjust to next 8 byte boundary */
- hpitch = (((hpitch + 7) / 8) * 8);
- }
- /* if update is set, modify the bytesperline and sizeimage */
- if (update) {
- pixfmt->bytesperline = hpitch;
- pixfmt->sizeimage = hpitch * vpitch * 2;
- }
- /**
- * Image width and height is always based on current standard width and
- * height
- */
- pixfmt->width = common->fmt.fmt.pix.width;
- pixfmt->height = common->fmt.fmt.pix.height;
- return 0;
-exit:
- return ret;
-}
-
-/**
- * vpif_config_addr() - function to configure buffer address in vpif
- * @ch - channel ptr
- * @muxmode - channel mux mode
- */
-static void vpif_config_addr(struct channel_obj *ch, int muxmode)
-{
- struct common_obj *common;
-
- vpif_dbg(2, debug, "vpif_config_addr\n");
-
- common = &(ch->common[VPIF_VIDEO_INDEX]);
-
- if (VPIF_CHANNEL1_VIDEO == ch->channel_id)
- common->set_addr = ch1_set_videobuf_addr;
- else if (2 == muxmode)
- common->set_addr = ch0_set_videobuf_addr_yc_nmux;
- else
- common->set_addr = ch0_set_videobuf_addr;
-}
-
-/**
- * vpif_mmap : It is used to map kernel space buffers into user spaces
- * @filep: file pointer
- * @vma: ptr to vm_area_struct
- */
-static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
-{
- /* Get the channel object and file handle object */
- struct vpif_fh *fh = filep->private_data;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
-
- vpif_dbg(2, debug, "vpif_mmap\n");
-
- return vb2_mmap(&common->buffer_queue, vma);
-}
-
-/**
- * vpif_poll: It is used for select/poll system call
- * @filep: file pointer
- * @wait: poll table to wait
- */
-static unsigned int vpif_poll(struct file *filep, poll_table * wait)
-{
- struct vpif_fh *fh = filep->private_data;
- struct channel_obj *channel = fh->channel;
- struct common_obj *common = &(channel->common[VPIF_VIDEO_INDEX]);
-
- vpif_dbg(2, debug, "vpif_poll\n");
-
- if (common->started)
- return vb2_poll(&common->buffer_queue, filep, wait);
- return 0;
-}
-
-/**
- * vpif_open : vpif open handler
- * @filep: file ptr
- *
- * It creates object of file handle structure and stores it in private_data
- * member of filepointer
- */
-static int vpif_open(struct file *filep)
-{
- struct vpif_capture_config *config = vpif_dev->platform_data;
- struct video_device *vdev = video_devdata(filep);
- struct common_obj *common;
- struct video_obj *vid_ch;
- struct channel_obj *ch;
- struct vpif_fh *fh;
- int i;
-
- vpif_dbg(2, debug, "vpif_open\n");
-
- ch = video_get_drvdata(vdev);
-
- vid_ch = &ch->video;
- common = &ch->common[VPIF_VIDEO_INDEX];
-
- if (NULL == ch->curr_subdev_info) {
- /**
- * search through the sub device to see a registered
- * sub device and make it as current sub device
- */
- for (i = 0; i < config->subdev_count; i++) {
- if (vpif_obj.sd[i]) {
- /* the sub device is registered */
- ch->curr_subdev_info = &config->subdev_info[i];
- /* make first input as the current input */
- vid_ch->input_idx = 0;
- break;
- }
- }
- if (i == config->subdev_count) {
- vpif_err("No sub device registered\n");
- return -ENOENT;
- }
- }
-
- /* Allocate memory for the file handle object */
- fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
- if (NULL == fh) {
- vpif_err("unable to allocate memory for file handle object\n");
- return -ENOMEM;
- }
-
- /* store pointer to fh in private_data member of filep */
- filep->private_data = fh;
- fh->channel = ch;
- fh->initialized = 0;
- /* If decoder is not initialized. initialize it */
- if (!ch->initialized) {
- fh->initialized = 1;
- ch->initialized = 1;
- memset(&(ch->vpifparams), 0, sizeof(struct vpif_params));
- }
- /* Increment channel usrs counter */
- ch->usrs++;
- /* Set io_allowed member to false */
- fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
- /* Initialize priority of this instance to default priority */
- fh->prio = V4L2_PRIORITY_UNSET;
- v4l2_prio_open(&ch->prio, &fh->prio);
- return 0;
-}
-
-/**
- * vpif_release : function to clean up file close
- * @filep: file pointer
- *
- * This function deletes buffer queue, frees the buffers and the vpif file
- * handle
- */
-static int vpif_release(struct file *filep)
-{
- struct vpif_fh *fh = filep->private_data;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
-
- vpif_dbg(2, debug, "vpif_release\n");
-
- common = &ch->common[VPIF_VIDEO_INDEX];
-
- /* if this instance is doing IO */
- if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
- /* Reset io_usrs member of channel object */
- common->io_usrs = 0;
- /* Disable channel as per its device type and channel id */
- if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
- enable_channel0(0);
- channel0_intr_enable(0);
- }
- if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
- (2 == common->started)) {
- enable_channel1(0);
- channel1_intr_enable(0);
- }
- common->started = 0;
- /* Free buffers allocated */
- vb2_queue_release(&common->buffer_queue);
- vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
- }
-
- /* Decrement channel usrs counter */
- ch->usrs--;
-
- /* Close the priority */
- v4l2_prio_close(&ch->prio, fh->prio);
-
- if (fh->initialized)
- ch->initialized = 0;
-
- filep->private_data = NULL;
- kfree(fh);
- return 0;
-}
-
-/**
- * vpif_reqbufs() - request buffer handler
- * @file: file ptr
- * @priv: file handle
- * @reqbuf: request buffer structure ptr
- */
-static int vpif_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbuf)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
- u8 index = 0;
- struct vb2_queue *q;
-
- vpif_dbg(2, debug, "vpif_reqbufs\n");
-
- /**
- * This file handle has not initialized the channel,
- * It is not allowed to do settings
- */
- if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)
- || (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
- if (!fh->initialized) {
- vpif_dbg(1, debug, "Channel Busy\n");
- return -EBUSY;
- }
- }
-
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != reqbuf->type || !vpif_dev)
- return -EINVAL;
-
- index = VPIF_VIDEO_INDEX;
-
- common = &ch->common[index];
-
- if (0 != common->io_usrs)
- return -EBUSY;
-
- /* Initialize videobuf2 queue as per the buffer type */
- common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
- if (!common->alloc_ctx) {
- vpif_err("Failed to get the context\n");
- return -EINVAL;
- }
- q = &common->buffer_queue;
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- q->io_modes = VB2_MMAP | VB2_USERPTR;
- q->drv_priv = fh;
- q->ops = &video_qops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->buf_struct_size = sizeof(struct vpif_cap_buffer);
-
- vb2_queue_init(q);
-
- /* Set io allowed member of file handle to TRUE */
- fh->io_allowed[index] = 1;
- /* Increment io usrs member of channel object to 1 */
- common->io_usrs = 1;
- /* Store type of memory requested in channel object */
- common->memory = reqbuf->memory;
- INIT_LIST_HEAD(&common->dma_queue);
-
- /* Allocate buffers */
- return vb2_reqbufs(&common->buffer_queue, reqbuf);
-}
-
-/**
- * vpif_querybuf() - query buffer handler
- * @file: file ptr
- * @priv: file handle
- * @buf: v4l2 buffer structure ptr
- */
-static int vpif_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- vpif_dbg(2, debug, "vpif_querybuf\n");
-
- if (common->fmt.type != buf->type)
- return -EINVAL;
-
- if (common->memory != V4L2_MEMORY_MMAP) {
- vpif_dbg(1, debug, "Invalid memory\n");
- return -EINVAL;
- }
-
- return vb2_querybuf(&common->buffer_queue, buf);
-}
-
-/**
- * vpif_qbuf() - query buffer handler
- * @file: file ptr
- * @priv: file handle
- * @buf: v4l2 buffer structure ptr
- */
-static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
-
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct v4l2_buffer tbuf = *buf;
-
- vpif_dbg(2, debug, "vpif_qbuf\n");
-
- if (common->fmt.type != tbuf.type) {
- vpif_err("invalid buffer type\n");
- return -EINVAL;
- }
-
- if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
- vpif_err("fh io not allowed\n");
- return -EACCES;
- }
-
- return vb2_qbuf(&common->buffer_queue, buf);
-}
-
-/**
- * vpif_dqbuf() - query buffer handler
- * @file: file ptr
- * @priv: file handle
- * @buf: v4l2 buffer structure ptr
- */
-static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- vpif_dbg(2, debug, "vpif_dqbuf\n");
-
- return vb2_dqbuf(&common->buffer_queue, buf,
- (file->f_flags & O_NONBLOCK));
-}
-
-/**
- * vpif_streamon() - streamon handler
- * @file: file ptr
- * @priv: file handle
- * @buftype: v4l2 buffer type
- */
-static int vpif_streamon(struct file *file, void *priv,
- enum v4l2_buf_type buftype)
-{
-
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
- struct vpif_params *vpif;
- int ret = 0;
-
- vpif_dbg(2, debug, "vpif_streamon\n");
-
- vpif = &ch->vpifparams;
-
- if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- vpif_dbg(1, debug, "buffer type not supported\n");
- return -EINVAL;
- }
-
- /* If file handle is not allowed IO, return error */
- if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
- vpif_dbg(1, debug, "io not allowed\n");
- return -EACCES;
- }
-
- /* If Streaming is already started, return error */
- if (common->started) {
- vpif_dbg(1, debug, "channel->started\n");
- return -EBUSY;
- }
-
- if ((ch->channel_id == VPIF_CHANNEL0_VIDEO &&
- oth_ch->common[VPIF_VIDEO_INDEX].started &&
- vpif->std_info.ycmux_mode == 0) ||
- ((ch->channel_id == VPIF_CHANNEL1_VIDEO) &&
- (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
- vpif_dbg(1, debug, "other channel is being used\n");
- return -EBUSY;
- }
-
- ret = vpif_check_format(ch, &common->fmt.fmt.pix, 0);
- if (ret)
- return ret;
-
- /* Enable streamon on the sub device */
- ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
- s_stream, 1);
-
- if (ret && (ret != -ENOIOCTLCMD)) {
- vpif_dbg(1, debug, "stream on failed in subdev\n");
- return ret;
- }
-
- /* Call vb2_streamon to start streaming in videobuf2 */
- ret = vb2_streamon(&common->buffer_queue, buftype);
- if (ret) {
- vpif_dbg(1, debug, "vb2_streamon\n");
- return ret;
- }
-
- return ret;
-}
-
-/**
- * vpif_streamoff() - streamoff handler
- * @file: file ptr
- * @priv: file handle
- * @buftype: v4l2 buffer type
- */
-static int vpif_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type buftype)
-{
-
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- int ret;
-
- vpif_dbg(2, debug, "vpif_streamoff\n");
-
- if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- vpif_dbg(1, debug, "buffer type not supported\n");
- return -EINVAL;
- }
-
- /* If io is allowed for this file handle, return error */
- if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
- vpif_dbg(1, debug, "io not allowed\n");
- return -EACCES;
- }
-
- /* If streaming is not started, return error */
- if (!common->started) {
- vpif_dbg(1, debug, "channel->started\n");
- return -EINVAL;
- }
-
- /* disable channel */
- if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
- enable_channel0(0);
- channel0_intr_enable(0);
- } else {
- enable_channel1(0);
- channel1_intr_enable(0);
- }
-
- common->started = 0;
-
- ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
- s_stream, 0);
-
- if (ret && (ret != -ENOIOCTLCMD))
- vpif_dbg(1, debug, "stream off failed in subdev\n");
-
- return vb2_streamoff(&common->buffer_queue, buftype);
-}
-
-/**
- * vpif_map_sub_device_to_input() - Maps sub device to input
- * @ch - ptr to channel
- * @config - ptr to capture configuration
- * @input_index - Given input index from application
- * @sub_device_index - index into sd table
- *
- * lookup the sub device information for a given input index.
- * we report all the inputs to application. inputs table also
- * has sub device name for the each input
- */
-static struct vpif_subdev_info *vpif_map_sub_device_to_input(
- struct channel_obj *ch,
- struct vpif_capture_config *vpif_cfg,
- int input_index,
- int *sub_device_index)
-{
- struct vpif_capture_chan_config *chan_cfg;
- struct vpif_subdev_info *subdev_info = NULL;
- const char *subdev_name = NULL;
- int i;
-
- vpif_dbg(2, debug, "vpif_map_sub_device_to_input\n");
-
- chan_cfg = &vpif_cfg->chan_config[ch->channel_id];
-
- /**
- * search through the inputs to find the sub device supporting
- * the input
- */
- for (i = 0; i < chan_cfg->input_count; i++) {
- /* For each sub device, loop through input */
- if (i == input_index) {
- subdev_name = chan_cfg->inputs[i].subdev_name;
- break;
- }
- }
-
- /* if reached maximum. return null */
- if (i == chan_cfg->input_count || (NULL == subdev_name))
- return subdev_info;
-
- /* loop through the sub device list to get the sub device info */
- for (i = 0; i < vpif_cfg->subdev_count; i++) {
- subdev_info = &vpif_cfg->subdev_info[i];
- if (!strcmp(subdev_info->name, subdev_name))
- break;
- }
-
- if (i == vpif_cfg->subdev_count)
- return subdev_info;
-
- /* check if the sub device is registered */
- if (NULL == vpif_obj.sd[i])
- return NULL;
-
- *sub_device_index = i;
- return subdev_info;
-}
-
-/**
- * vpif_querystd() - querystd handler
- * @file: file ptr
- * @priv: file handle
- * @std_id: ptr to std id
- *
- * This function is called to detect standard at the selected input
- */
-static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- int ret = 0;
-
- vpif_dbg(2, debug, "vpif_querystd\n");
-
- /* Call querystd function of decoder device */
- ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
- querystd, std_id);
- if (ret < 0)
- vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
-
- return ret;
-}
-
-/**
- * vpif_g_std() - get STD handler
- * @file: file ptr
- * @priv: file handle
- * @std_id: ptr to std id
- */
-static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- vpif_dbg(2, debug, "vpif_g_std\n");
-
- *std = ch->video.stdid;
- return 0;
-}
-
-/**
- * vpif_s_std() - set STD handler
- * @file: file ptr
- * @priv: file handle
- * @std_id: ptr to std id
- */
-static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- int ret = 0;
-
- vpif_dbg(2, debug, "vpif_s_std\n");
-
- if (common->started) {
- vpif_err("streaming in progress\n");
- return -EBUSY;
- }
-
- if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
- (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
- if (!fh->initialized) {
- vpif_dbg(1, debug, "Channel Busy\n");
- return -EBUSY;
- }
- }
-
- ret = v4l2_prio_check(&ch->prio, fh->prio);
- if (0 != ret)
- return ret;
-
- fh->initialized = 1;
-
- /* Call encoder subdevice function to set the standard */
- ch->video.stdid = *std_id;
- ch->video.dv_preset = V4L2_DV_INVALID;
- memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
-
- /* Get the information about the standard */
- if (vpif_update_std_info(ch)) {
- vpif_err("Error getting the standard info\n");
- return -EINVAL;
- }
-
- /* Configure the default format information */
- vpif_config_format(ch);
-
- /* set standard in the sub device */
- ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
- s_std, *std_id);
- if (ret < 0)
- vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
- return ret;
-}
-
-/**
- * vpif_enum_input() - ENUMINPUT handler
- * @file: file ptr
- * @priv: file handle
- * @input: ptr to input structure
- */
-static int vpif_enum_input(struct file *file, void *priv,
- struct v4l2_input *input)
-{
-
- struct vpif_capture_config *config = vpif_dev->platform_data;
- struct vpif_capture_chan_config *chan_cfg;
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- chan_cfg = &config->chan_config[ch->channel_id];
-
- if (input->index >= chan_cfg->input_count) {
- vpif_dbg(1, debug, "Invalid input index\n");
- return -EINVAL;
- }
-
- memcpy(input, &chan_cfg->inputs[input->index].input,
- sizeof(*input));
- return 0;
-}
-
-/**
- * vpif_g_input() - Get INPUT handler
- * @file: file ptr
- * @priv: file handle
- * @index: ptr to input index
- */
-static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct video_obj *vid_ch = &ch->video;
-
- *index = vid_ch->input_idx;
-
- return 0;
-}
-
-/**
- * vpif_s_input() - Set INPUT handler
- * @file: file ptr
- * @priv: file handle
- * @index: input index
- */
-static int vpif_s_input(struct file *file, void *priv, unsigned int index)
-{
- struct vpif_capture_config *config = vpif_dev->platform_data;
- struct vpif_capture_chan_config *chan_cfg;
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct video_obj *vid_ch = &ch->video;
- struct vpif_subdev_info *subdev_info;
- int ret = 0, sd_index = 0;
- u32 input = 0, output = 0;
-
- chan_cfg = &config->chan_config[ch->channel_id];
-
- if (common->started) {
- vpif_err("Streaming in progress\n");
- return -EBUSY;
- }
-
- if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
- (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
- if (!fh->initialized) {
- vpif_dbg(1, debug, "Channel Busy\n");
- return -EBUSY;
- }
- }
-
- ret = v4l2_prio_check(&ch->prio, fh->prio);
- if (0 != ret)
- return ret;
-
- fh->initialized = 1;
- subdev_info = vpif_map_sub_device_to_input(ch, config, index,
- &sd_index);
- if (NULL == subdev_info) {
- vpif_dbg(1, debug,
- "couldn't lookup sub device for the input index\n");
- return -EINVAL;
- }
-
- /* first setup input path from sub device to vpif */
- if (config->setup_input_path) {
- ret = config->setup_input_path(ch->channel_id,
- subdev_info->name);
- if (ret < 0) {
- vpif_dbg(1, debug, "couldn't setup input path for the"
- " sub device %s, for input index %d\n",
- subdev_info->name, index);
- return ret;
- }
- }
-
- if (subdev_info->can_route) {
- input = subdev_info->input;
- output = subdev_info->output;
- ret = v4l2_subdev_call(vpif_obj.sd[sd_index], video, s_routing,
- input, output, 0);
- if (ret < 0) {
- vpif_dbg(1, debug, "Failed to set input\n");
- return ret;
- }
- }
- vid_ch->input_idx = index;
- ch->curr_subdev_info = subdev_info;
- ch->curr_sd_index = sd_index;
- /* copy interface parameters to vpif */
- ch->vpifparams.iface = subdev_info->vpif_if;
-
- /* update tvnorms from the sub device input info */
- ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std;
- return ret;
-}
-
-/**
- * vpif_enum_fmt_vid_cap() - ENUM_FMT handler
- * @file: file ptr
- * @priv: file handle
- * @index: input index
- */
-static int vpif_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *fmt)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- if (fmt->index != 0) {
- vpif_dbg(1, debug, "Invalid format index\n");
- return -EINVAL;
- }
-
- /* Fill in the information about format */
- if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER) {
- fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- strcpy(fmt->description, "Raw Mode -Bayer Pattern GrRBGb");
- fmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
- } else {
- fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
- fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
- }
- return 0;
-}
-
-/**
- * vpif_try_fmt_vid_cap() - TRY_FMT handler
- * @file: file ptr
- * @priv: file handle
- * @fmt: ptr to v4l2 format structure
- */
-static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-
- return vpif_check_format(ch, pixfmt, 1);
-}
-
-
-/**
- * vpif_g_fmt_vid_cap() - Set INPUT handler
- * @file: file ptr
- * @priv: file handle
- * @fmt: ptr to v4l2 format structure
- */
-static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- /* Check the validity of the buffer type */
- if (common->fmt.type != fmt->type)
- return -EINVAL;
-
- /* Fill in the information about format */
- *fmt = common->fmt;
- return 0;
-}
-
-/**
- * vpif_s_fmt_vid_cap() - Set FMT handler
- * @file: file ptr
- * @priv: file handle
- * @fmt: ptr to v4l2 format structure
- */
-static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct v4l2_pix_format *pixfmt;
- int ret = 0;
-
- vpif_dbg(2, debug, "%s\n", __func__);
-
- /* If streaming is started, return error */
- if (common->started) {
- vpif_dbg(1, debug, "Streaming is started\n");
- return -EBUSY;
- }
-
- if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
- (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
- if (!fh->initialized) {
- vpif_dbg(1, debug, "Channel Busy\n");
- return -EBUSY;
- }
- }
-
- ret = v4l2_prio_check(&ch->prio, fh->prio);
- if (0 != ret)
- return ret;
-
- fh->initialized = 1;
-
- pixfmt = &fmt->fmt.pix;
- /* Check for valid field format */
- ret = vpif_check_format(ch, pixfmt, 0);
-
- if (ret)
- return ret;
- /* store the format in the channel object */
- common->fmt = *fmt;
- return 0;
-}
-
-/**
- * vpif_querycap() - QUERYCAP handler
- * @file: file ptr
- * @priv: file handle
- * @cap: ptr to v4l2_capability structure
- */
-static int vpif_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct vpif_capture_config *config = vpif_dev->platform_data;
-
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
- strlcpy(cap->driver, "vpif capture", sizeof(cap->driver));
- strlcpy(cap->bus_info, "VPIF Platform", sizeof(cap->bus_info));
- strlcpy(cap->card, config->card_name, sizeof(cap->card));
-
- return 0;
-}
-
-/**
- * vpif_g_priority() - get priority handler
- * @file: file ptr
- * @priv: file handle
- * @prio: ptr to v4l2_priority structure
- */
-static int vpif_g_priority(struct file *file, void *priv,
- enum v4l2_priority *prio)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- *prio = v4l2_prio_max(&ch->prio);
-
- return 0;
-}
-
-/**
- * vpif_s_priority() - set priority handler
- * @file: file ptr
- * @priv: file handle
- * @prio: ptr to v4l2_priority structure
- */
-static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- return v4l2_prio_change(&ch->prio, &fh->prio, p);
-}
-
-/**
- * vpif_cropcap() - cropcap handler
- * @file: file ptr
- * @priv: file handle
- * @crop: ptr to v4l2_cropcap structure
- */
-static int vpif_cropcap(struct file *file, void *priv,
- struct v4l2_cropcap *crop)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != crop->type)
- return -EINVAL;
-
- crop->bounds.left = 0;
- crop->bounds.top = 0;
- crop->bounds.height = common->height;
- crop->bounds.width = common->width;
- crop->defrect = crop->bounds;
- return 0;
-}
-
-/**
- * vpif_enum_dv_presets() - ENUM_DV_PRESETS handler
- * @file: file ptr
- * @priv: file handle
- * @preset: input preset
- */
-static int vpif_enum_dv_presets(struct file *file, void *priv,
- struct v4l2_dv_enum_preset *preset)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
- video, enum_dv_presets, preset);
-}
-
-/**
- * vpif_query_dv_presets() - QUERY_DV_PRESET handler
- * @file: file ptr
- * @priv: file handle
- * @preset: input preset
- */
-static int vpif_query_dv_preset(struct file *file, void *priv,
- struct v4l2_dv_preset *preset)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
- video, query_dv_preset, preset);
-}
-/**
- * vpif_s_dv_presets() - S_DV_PRESETS handler
- * @file: file ptr
- * @priv: file handle
- * @preset: input preset
- */
-static int vpif_s_dv_preset(struct file *file, void *priv,
- struct v4l2_dv_preset *preset)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- int ret = 0;
-
- if (common->started) {
- vpif_dbg(1, debug, "streaming in progress\n");
- return -EBUSY;
- }
-
- if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
- (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
- if (!fh->initialized) {
- vpif_dbg(1, debug, "Channel Busy\n");
- return -EBUSY;
- }
- }
-
- ret = v4l2_prio_check(&ch->prio, fh->prio);
- if (ret)
- return ret;
-
- fh->initialized = 1;
-
- /* Call encoder subdevice function to set the standard */
- if (mutex_lock_interruptible(&common->lock))
- return -ERESTARTSYS;
-
- ch->video.dv_preset = preset->preset;
- ch->video.stdid = V4L2_STD_UNKNOWN;
- memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
-
- /* Get the information about the standard */
- if (vpif_update_std_info(ch)) {
- vpif_dbg(1, debug, "Error getting the standard info\n");
- ret = -EINVAL;
- } else {
- /* Configure the default format information */
- vpif_config_format(ch);
-
- ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
- video, s_dv_preset, preset);
- }
-
- mutex_unlock(&common->lock);
-
- return ret;
-}
-/**
- * vpif_g_dv_presets() - G_DV_PRESETS handler
- * @file: file ptr
- * @priv: file handle
- * @preset: input preset
- */
-static int vpif_g_dv_preset(struct file *file, void *priv,
- struct v4l2_dv_preset *preset)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- preset->preset = ch->video.dv_preset;
-
- return 0;
-}
-
-/**
- * vpif_s_dv_timings() - S_DV_TIMINGS handler
- * @file: file ptr
- * @priv: file handle
- * @timings: digital video timings
- */
-static int vpif_s_dv_timings(struct file *file, void *priv,
- struct v4l2_dv_timings *timings)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct vpif_params *vpifparams = &ch->vpifparams;
- struct vpif_channel_config_params *std_info = &vpifparams->std_info;
- struct video_obj *vid_ch = &ch->video;
- struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
- int ret;
-
- if (timings->type != V4L2_DV_BT_656_1120) {
- vpif_dbg(2, debug, "Timing type not defined\n");
- return -EINVAL;
- }
-
- /* Configure subdevice timings, if any */
- ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
- video, s_dv_timings, timings);
- if (ret == -ENOIOCTLCMD) {
- vpif_dbg(2, debug, "Custom DV timings not supported by "
- "subdevice\n");
- return -EINVAL;
- }
- if (ret < 0) {
- vpif_dbg(2, debug, "Error setting custom DV timings\n");
- return ret;
- }
-
- if (!(timings->bt.width && timings->bt.height &&
- (timings->bt.hbackporch ||
- timings->bt.hfrontporch ||
- timings->bt.hsync) &&
- timings->bt.vfrontporch &&
- (timings->bt.vbackporch ||
- timings->bt.vsync))) {
- vpif_dbg(2, debug, "Timings for width, height, "
- "horizontal back porch, horizontal sync, "
- "horizontal front porch, vertical back porch, "
- "vertical sync and vertical back porch "
- "must be defined\n");
- return -EINVAL;
- }
-
- *bt = timings->bt;
-
- /* Configure video port timings */
-
- std_info->eav2sav = bt->hbackporch + bt->hfrontporch +
- bt->hsync - 8;
- std_info->sav2eav = bt->width;
-
- std_info->l1 = 1;
- std_info->l3 = bt->vsync + bt->vbackporch + 1;
-
- if (bt->interlaced) {
- if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
- std_info->vsize = bt->height * 2 +
- bt->vfrontporch + bt->vsync + bt->vbackporch +
- bt->il_vfrontporch + bt->il_vsync +
- bt->il_vbackporch;
- std_info->l5 = std_info->vsize/2 -
- (bt->vfrontporch - 1);
- std_info->l7 = std_info->vsize/2 + 1;
- std_info->l9 = std_info->l7 + bt->il_vsync +
- bt->il_vbackporch + 1;
- std_info->l11 = std_info->vsize -
- (bt->il_vfrontporch - 1);
- } else {
- vpif_dbg(2, debug, "Required timing values for "
- "interlaced BT format missing\n");
- return -EINVAL;
- }
- } else {
- std_info->vsize = bt->height + bt->vfrontporch +
- bt->vsync + bt->vbackporch;
- std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
- }
- strncpy(std_info->name, "Custom timings BT656/1120", VPIF_MAX_NAME);
- std_info->width = bt->width;
- std_info->height = bt->height;
- std_info->frm_fmt = bt->interlaced ? 0 : 1;
- std_info->ycmux_mode = 0;
- std_info->capture_format = 0;
- std_info->vbi_supported = 0;
- std_info->hd_sd = 1;
- std_info->stdid = 0;
- std_info->dv_preset = V4L2_DV_INVALID;
-
- vid_ch->stdid = 0;
- vid_ch->dv_preset = V4L2_DV_INVALID;
- return 0;
-}
-
-/**
- * vpif_g_dv_timings() - G_DV_TIMINGS handler
- * @file: file ptr
- * @priv: file handle
- * @timings: digital video timings
- */
-static int vpif_g_dv_timings(struct file *file, void *priv,
- struct v4l2_dv_timings *timings)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct video_obj *vid_ch = &ch->video;
- struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
-
- timings->bt = *bt;
-
- return 0;
-}
-
-/*
- * vpif_g_chip_ident() - Identify the chip
- * @file: file ptr
- * @priv: file handle
- * @chip: chip identity
- *
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
- chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
- vpif_dbg(2, debug, "match_type is invalid.\n");
- return -EINVAL;
- }
-
- return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
- g_chip_ident, chip);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-/*
- * vpif_dbg_g_register() - Read register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be read
- *
- * Debugging only
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_dbg_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg){
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
- g_register, reg);
-}
-
-/*
- * vpif_dbg_s_register() - Write to register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be modified
- *
- * Debugging only
- * Returns zero or -EINVAL if write operations fails.
- */
-static int vpif_dbg_s_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg){
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
- s_register, reg);
-}
-#endif
-
-/*
- * vpif_log_status() - Status information
- * @file: file ptr
- * @priv: file handle
- *
- * Returns zero.
- */
-static int vpif_log_status(struct file *filep, void *priv)
-{
- /* status for sub devices */
- v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);
-
- return 0;
-}
-
-/* vpif capture ioctl operations */
-static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
- .vidioc_querycap = vpif_querycap,
- .vidioc_g_priority = vpif_g_priority,
- .vidioc_s_priority = vpif_s_priority,
- .vidioc_enum_fmt_vid_cap = vpif_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vpif_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vpif_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vpif_try_fmt_vid_cap,
- .vidioc_enum_input = vpif_enum_input,
- .vidioc_s_input = vpif_s_input,
- .vidioc_g_input = vpif_g_input,
- .vidioc_reqbufs = vpif_reqbufs,
- .vidioc_querybuf = vpif_querybuf,
- .vidioc_querystd = vpif_querystd,
- .vidioc_s_std = vpif_s_std,
- .vidioc_g_std = vpif_g_std,
- .vidioc_qbuf = vpif_qbuf,
- .vidioc_dqbuf = vpif_dqbuf,
- .vidioc_streamon = vpif_streamon,
- .vidioc_streamoff = vpif_streamoff,
- .vidioc_cropcap = vpif_cropcap,
- .vidioc_enum_dv_presets = vpif_enum_dv_presets,
- .vidioc_s_dv_preset = vpif_s_dv_preset,
- .vidioc_g_dv_preset = vpif_g_dv_preset,
- .vidioc_query_dv_preset = vpif_query_dv_preset,
- .vidioc_s_dv_timings = vpif_s_dv_timings,
- .vidioc_g_dv_timings = vpif_g_dv_timings,
- .vidioc_g_chip_ident = vpif_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vpif_dbg_g_register,
- .vidioc_s_register = vpif_dbg_s_register,
-#endif
- .vidioc_log_status = vpif_log_status,
-};
-
-/* vpif file operations */
-static struct v4l2_file_operations vpif_fops = {
- .owner = THIS_MODULE,
- .open = vpif_open,
- .release = vpif_release,
- .unlocked_ioctl = video_ioctl2,
- .mmap = vpif_mmap,
- .poll = vpif_poll
-};
-
-/* vpif video template */
-static struct video_device vpif_video_template = {
- .name = "vpif",
- .fops = &vpif_fops,
- .minor = -1,
- .ioctl_ops = &vpif_ioctl_ops,
-};
-
-/**
- * initialize_vpif() - Initialize vpif data structures
- *
- * Allocate memory for data structures and initialize them
- */
-static int initialize_vpif(void)
-{
- int err = 0, i, j;
- int free_channel_objects_index;
-
- /* Default number of buffers should be 3 */
- if ((ch0_numbuffers > 0) &&
- (ch0_numbuffers < config_params.min_numbuffers))
- ch0_numbuffers = config_params.min_numbuffers;
- if ((ch1_numbuffers > 0) &&
- (ch1_numbuffers < config_params.min_numbuffers))
- ch1_numbuffers = config_params.min_numbuffers;
-
- /* Set buffer size to min buffers size if it is invalid */
- if (ch0_bufsize < config_params.min_bufsize[VPIF_CHANNEL0_VIDEO])
- ch0_bufsize =
- config_params.min_bufsize[VPIF_CHANNEL0_VIDEO];
- if (ch1_bufsize < config_params.min_bufsize[VPIF_CHANNEL1_VIDEO])
- ch1_bufsize =
- config_params.min_bufsize[VPIF_CHANNEL1_VIDEO];
-
- config_params.numbuffers[VPIF_CHANNEL0_VIDEO] = ch0_numbuffers;
- config_params.numbuffers[VPIF_CHANNEL1_VIDEO] = ch1_numbuffers;
- if (ch0_numbuffers) {
- config_params.channel_bufsize[VPIF_CHANNEL0_VIDEO]
- = ch0_bufsize;
- }
- if (ch1_numbuffers) {
- config_params.channel_bufsize[VPIF_CHANNEL1_VIDEO]
- = ch1_bufsize;
- }
-
- /* Allocate memory for six channel objects */
- for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
- vpif_obj.dev[i] =
- kzalloc(sizeof(*vpif_obj.dev[i]), GFP_KERNEL);
- /* If memory allocation fails, return error */
- if (!vpif_obj.dev[i]) {
- free_channel_objects_index = i;
- err = -ENOMEM;
- goto vpif_init_free_channel_objects;
- }
- }
- return 0;
-
-vpif_init_free_channel_objects:
- for (j = 0; j < free_channel_objects_index; j++)
- kfree(vpif_obj.dev[j]);
- return err;
-}
-
-/**
- * vpif_probe : This function probes the vpif capture driver
- * @pdev: platform device pointer
- *
- * This creates device entries by register itself to the V4L2 driver and
- * initializes fields of each channel objects
- */
-static __init int vpif_probe(struct platform_device *pdev)
-{
- struct vpif_subdev_info *subdevdata;
- struct vpif_capture_config *config;
- int i, j, k, m, q, err;
- struct i2c_adapter *i2c_adap;
- struct channel_obj *ch;
- struct common_obj *common;
- struct video_device *vfd;
- struct resource *res;
- int subdev_count;
- size_t size;
-
- vpif_dev = &pdev->dev;
-
- err = initialize_vpif();
- if (err) {
- v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
- return err;
- }
-
- err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
- if (err) {
- v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
- return err;
- }
-
- k = 0;
- while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
- for (i = res->start; i <= res->end; i++) {
- if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
- "VPIF_Capture",
- (void *)(&vpif_obj.dev[k]->channel_id))) {
- err = -EBUSY;
- i--;
- goto vpif_int_err;
- }
- }
- k++;
- }
-
- for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
- /* Get the pointer to the channel object */
- ch = vpif_obj.dev[i];
- /* Allocate memory for video device */
- vfd = video_device_alloc();
- if (NULL == vfd) {
- for (j = 0; j < i; j++) {
- ch = vpif_obj.dev[j];
- video_device_release(ch->video_dev);
- }
- err = -ENOMEM;
- goto vpif_dev_alloc_err;
- }
-
- /* Initialize field of video device */
- *vfd = vpif_video_template;
- vfd->v4l2_dev = &vpif_obj.v4l2_dev;
- vfd->release = video_device_release;
- snprintf(vfd->name, sizeof(vfd->name),
- "VPIF_Capture_DRIVER_V%s",
- VPIF_CAPTURE_VERSION);
- /* Set video_dev to the video device */
- ch->video_dev = vfd;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res) {
- size = resource_size(res);
- /* The resources are divided into two equal memory and when we
- * have HD output we can add them together
- */
- for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
- ch = vpif_obj.dev[j];
- ch->channel_id = j;
- /* only enabled if second resource exists */
- config_params.video_limit[ch->channel_id] = 0;
- if (size)
- config_params.video_limit[ch->channel_id] =
- size/2;
- }
- }
-
- for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
- ch = vpif_obj.dev[j];
- ch->channel_id = j;
- common = &(ch->common[VPIF_VIDEO_INDEX]);
- spin_lock_init(&common->irqlock);
- mutex_init(&common->lock);
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &ch->video_dev->flags);
- ch->video_dev->lock = &common->lock;
- /* Initialize prio member of channel object */
- v4l2_prio_init(&ch->prio);
- err = video_register_device(ch->video_dev,
- VFL_TYPE_GRABBER, (j ? 1 : 0));
- if (err)
- goto probe_out;
-
- video_set_drvdata(ch->video_dev, ch);
-
- }
-
- i2c_adap = i2c_get_adapter(1);
- config = pdev->dev.platform_data;
-
- subdev_count = config->subdev_count;
- vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count,
- GFP_KERNEL);
- if (vpif_obj.sd == NULL) {
- vpif_err("unable to allocate memory for subdevice pointers\n");
- err = -ENOMEM;
- goto probe_out;
- }
-
- for (i = 0; i < subdev_count; i++) {
- subdevdata = &config->subdev_info[i];
- vpif_obj.sd[i] =
- v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
- i2c_adap,
- &subdevdata->board_info,
- NULL);
-
- if (!vpif_obj.sd[i]) {
- vpif_err("Error registering v4l2 subdevice\n");
- goto probe_subdev_out;
- }
- v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n",
- subdevdata->name);
-
- if (vpif_obj.sd[i])
- vpif_obj.sd[i]->grp_id = 1 << i;
- }
-
- v4l2_info(&vpif_obj.v4l2_dev, "VPIF capture driver initialized\n");
- return 0;
-
-probe_subdev_out:
- /* free sub devices memory */
- kfree(vpif_obj.sd);
-
- j = VPIF_CAPTURE_MAX_DEVICES;
-probe_out:
- for (k = 0; k < j; k++) {
- /* Get the pointer to the channel object */
- ch = vpif_obj.dev[k];
- /* Unregister video device */
- video_unregister_device(ch->video_dev);
- }
-
-vpif_dev_alloc_err:
- k = VPIF_CAPTURE_MAX_DEVICES-1;
- res = platform_get_resource(pdev, IORESOURCE_IRQ, k);
- i = res->end;
-
-vpif_int_err:
- for (q = k; q >= 0; q--) {
- for (m = i; m >= (int)res->start; m--)
- free_irq(m, (void *)(&vpif_obj.dev[q]->channel_id));
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, q-1);
- if (res)
- i = res->end;
- }
- v4l2_device_unregister(&vpif_obj.v4l2_dev);
- return err;
-}
-
-/**
- * vpif_remove() - driver remove handler
- * @device: ptr to platform device structure
- *
- * The vidoe device is unregistered
- */
-static int vpif_remove(struct platform_device *device)
-{
- int i;
- struct channel_obj *ch;
-
- v4l2_device_unregister(&vpif_obj.v4l2_dev);
-
- /* un-register device */
- for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
- /* Get the pointer to the channel object */
- ch = vpif_obj.dev[i];
- /* Unregister video device */
- video_unregister_device(ch->video_dev);
- }
- return 0;
-}
-
-#ifdef CONFIG_PM
-/**
- * vpif_suspend: vpif device suspend
- */
-static int vpif_suspend(struct device *dev)
-{
-
- struct common_obj *common;
- struct channel_obj *ch;
- int i;
-
- for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
- /* Get the pointer to the channel object */
- ch = vpif_obj.dev[i];
- common = &ch->common[VPIF_VIDEO_INDEX];
- mutex_lock(&common->lock);
- if (ch->usrs && common->io_usrs) {
- /* Disable channel */
- if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
- enable_channel0(0);
- channel0_intr_enable(0);
- }
- if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
- common->started == 2) {
- enable_channel1(0);
- channel1_intr_enable(0);
- }
- }
- mutex_unlock(&common->lock);
- }
-
- return 0;
-}
-
-/*
- * vpif_resume: vpif device suspend
- */
-static int vpif_resume(struct device *dev)
-{
- struct common_obj *common;
- struct channel_obj *ch;
- int i;
-
- for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
- /* Get the pointer to the channel object */
- ch = vpif_obj.dev[i];
- common = &ch->common[VPIF_VIDEO_INDEX];
- mutex_lock(&common->lock);
- if (ch->usrs && common->io_usrs) {
- /* Disable channel */
- if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
- enable_channel0(1);
- channel0_intr_enable(1);
- }
- if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
- common->started == 2) {
- enable_channel1(1);
- channel1_intr_enable(1);
- }
- }
- mutex_unlock(&common->lock);
- }
-
- return 0;
-}
-
-static const struct dev_pm_ops vpif_dev_pm_ops = {
- .suspend = vpif_suspend,
- .resume = vpif_resume,
-};
-
-#define vpif_pm_ops (&vpif_dev_pm_ops)
-#else
-#define vpif_pm_ops NULL
-#endif
-
-static __refdata struct platform_driver vpif_driver = {
- .driver = {
- .name = "vpif_capture",
- .owner = THIS_MODULE,
- .pm = vpif_pm_ops,
- },
- .probe = vpif_probe,
- .remove = vpif_remove,
-};
-
-/**
- * vpif_init: initialize the vpif driver
- *
- * This function registers device and driver to the kernel, requests irq
- * handler and allocates memory
- * for channel objects
- */
-static __init int vpif_init(void)
-{
- return platform_driver_register(&vpif_driver);
-}
-
-/**
- * vpif_cleanup : This function clean up the vpif capture resources
- *
- * This will un-registers device and driver to the kernel, frees
- * requested irq handler and de-allocates memory allocated for channel
- * objects.
- */
-static void vpif_cleanup(void)
-{
- struct platform_device *pdev;
- struct resource *res;
- int irq_num;
- int i = 0;
-
- pdev = container_of(vpif_dev, struct platform_device, dev);
- while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
- for (irq_num = res->start; irq_num <= res->end; irq_num++)
- free_irq(irq_num,
- (void *)(&vpif_obj.dev[i]->channel_id));
- i++;
- }
-
- platform_driver_unregister(&vpif_driver);
-
- kfree(vpif_obj.sd);
- for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++)
- kfree(vpif_obj.dev[i]);
-}
-
-/* Function for module initialization and cleanup */
-module_init(vpif_init);
-module_exit(vpif_cleanup);
diff --git a/drivers/media/video/davinci/vpif_capture.h b/drivers/media/video/davinci/vpif_capture.h
deleted file mode 100644
index 3511510f43e..00000000000
--- a/drivers/media/video/davinci/vpif_capture.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2009 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef VPIF_CAPTURE_H
-#define VPIF_CAPTURE_H
-
-#ifdef __KERNEL__
-
-/* Header files */
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/videobuf-core.h>
-#include <media/videobuf2-dma-contig.h>
-#include <media/davinci/vpif_types.h>
-
-#include "vpif.h"
-
-/* Macros */
-#define VPIF_CAPTURE_VERSION "0.0.2"
-
-#define VPIF_VALID_FIELD(field) (((V4L2_FIELD_ANY == field) || \
- (V4L2_FIELD_NONE == field)) || \
- (((V4L2_FIELD_INTERLACED == field) || \
- (V4L2_FIELD_SEQ_TB == field)) || \
- (V4L2_FIELD_SEQ_BT == field)))
-
-#define VPIF_CAPTURE_MAX_DEVICES 2
-#define VPIF_VIDEO_INDEX 0
-#define VPIF_NUMBER_OF_OBJECTS 1
-
-/* Enumerated data type to give id to each device per channel */
-enum vpif_channel_id {
- VPIF_CHANNEL0_VIDEO = 0,
- VPIF_CHANNEL1_VIDEO,
-};
-
-struct video_obj {
- enum v4l2_field buf_field;
- /* Currently selected or default standard */
- v4l2_std_id stdid;
- u32 dv_preset;
- struct v4l2_bt_timings bt_timings;
- /* This is to track the last input that is passed to application */
- u32 input_idx;
-};
-
-struct vpif_cap_buffer {
- struct vb2_buffer vb;
- struct list_head list;
-};
-
-struct common_obj {
- /* Pointer pointing to current v4l2_buffer */
- struct vpif_cap_buffer *cur_frm;
- /* Pointer pointing to current v4l2_buffer */
- struct vpif_cap_buffer *next_frm;
- /*
- * This field keeps track of type of buffer exchange mechanism
- * user has selected
- */
- enum v4l2_memory memory;
- /* Used to store pixel format */
- struct v4l2_format fmt;
- /* Buffer queue used in video-buf */
- struct vb2_queue buffer_queue;
- /* allocator-specific contexts for each plane */
- struct vb2_alloc_ctx *alloc_ctx;
- /* Queue of filled frames */
- struct list_head dma_queue;
- /* Used in video-buf */
- spinlock_t irqlock;
- /* lock used to access this structure */
- struct mutex lock;
- /* number of users performing IO */
- u32 io_usrs;
- /* Indicates whether streaming started */
- u8 started;
- /* Function pointer to set the addresses */
- void (*set_addr) (unsigned long, unsigned long, unsigned long,
- unsigned long);
- /* offset where Y top starts from the starting of the buffer */
- u32 ytop_off;
- /* offset where Y bottom starts from the starting of the buffer */
- u32 ybtm_off;
- /* offset where C top starts from the starting of the buffer */
- u32 ctop_off;
- /* offset where C bottom starts from the starting of the buffer */
- u32 cbtm_off;
- /* Indicates width of the image data */
- u32 width;
- /* Indicates height of the image data */
- u32 height;
-};
-
-struct channel_obj {
- /* Identifies video device for this channel */
- struct video_device *video_dev;
- /* Used to keep track of state of the priority */
- struct v4l2_prio_state prio;
- /* number of open instances of the channel */
- int usrs;
- /* Indicates id of the field which is being displayed */
- u32 field_id;
- /* flag to indicate whether decoder is initialized */
- u8 initialized;
- /* Identifies channel */
- enum vpif_channel_id channel_id;
- /* index into sd table */
- int curr_sd_index;
- /* ptr to current sub device information */
- struct vpif_subdev_info *curr_subdev_info;
- /* vpif configuration params */
- struct vpif_params vpifparams;
- /* common object array */
- struct common_obj common[VPIF_NUMBER_OF_OBJECTS];
- /* video object */
- struct video_obj video;
-};
-
-/* File handle structure */
-struct vpif_fh {
- /* pointer to channel object for opened device */
- struct channel_obj *channel;
- /* Indicates whether this file handle is doing IO */
- u8 io_allowed[VPIF_NUMBER_OF_OBJECTS];
- /* Used to keep track priority of this instance */
- enum v4l2_priority prio;
- /* Used to indicate channel is initialize or not */
- u8 initialized;
-};
-
-struct vpif_device {
- struct v4l2_device v4l2_dev;
- struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS];
- struct v4l2_subdev **sd;
-};
-
-struct vpif_config_params {
- u8 min_numbuffers;
- u8 numbuffers[VPIF_CAPTURE_NUM_CHANNELS];
- s8 device_type;
- u32 min_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
- u32 channel_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
- u8 default_device[VPIF_CAPTURE_NUM_CHANNELS];
- u32 video_limit[VPIF_CAPTURE_NUM_CHANNELS];
- u8 max_device_type;
-};
-/* Struct which keeps track of the line numbers for the sliced vbi service */
-struct vpif_service_line {
- u16 service_id;
- u16 service_line[2];
-};
-#endif /* End of __KERNEL__ */
-#endif /* VPIF_CAPTURE_H */
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
deleted file mode 100644
index e129c98921a..00000000000
--- a/drivers/media/video/davinci/vpif_display.c
+++ /dev/null
@@ -1,1998 +0,0 @@
-/*
- * vpif-display - VPIF display driver
- * Display driver for TI DaVinci VPIF
- *
- * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/string.h>
-#include <linux/videodev2.h>
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#include <asm/irq.h>
-#include <asm/page.h>
-
-#include <media/adv7343.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
-
-#include "vpif_display.h"
-#include "vpif.h"
-
-MODULE_DESCRIPTION("TI DaVinci VPIF Display driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(VPIF_DISPLAY_VERSION);
-
-#define VPIF_V4L2_STD (V4L2_STD_525_60 | V4L2_STD_625_50)
-
-#define vpif_err(fmt, arg...) v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
-#define vpif_dbg(level, debug, fmt, arg...) \
- v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
-
-static int debug = 1;
-static u32 ch2_numbuffers = 3;
-static u32 ch3_numbuffers = 3;
-static u32 ch2_bufsize = 1920 * 1080 * 2;
-static u32 ch3_bufsize = 720 * 576 * 2;
-
-module_param(debug, int, 0644);
-module_param(ch2_numbuffers, uint, S_IRUGO);
-module_param(ch3_numbuffers, uint, S_IRUGO);
-module_param(ch2_bufsize, uint, S_IRUGO);
-module_param(ch3_bufsize, uint, S_IRUGO);
-
-MODULE_PARM_DESC(debug, "Debug level 0-1");
-MODULE_PARM_DESC(ch2_numbuffers, "Channel2 buffer count (default:3)");
-MODULE_PARM_DESC(ch3_numbuffers, "Channel3 buffer count (default:3)");
-MODULE_PARM_DESC(ch2_bufsize, "Channel2 buffer size (default:1920 x 1080 x 2)");
-MODULE_PARM_DESC(ch3_bufsize, "Channel3 buffer size (default:720 x 576 x 2)");
-
-static struct vpif_config_params config_params = {
- .min_numbuffers = 3,
- .numbuffers[0] = 3,
- .numbuffers[1] = 3,
- .min_bufsize[0] = 720 * 480 * 2,
- .min_bufsize[1] = 720 * 480 * 2,
- .channel_bufsize[0] = 1920 * 1080 * 2,
- .channel_bufsize[1] = 720 * 576 * 2,
-};
-
-static struct vpif_device vpif_obj = { {NULL} };
-static struct device *vpif_dev;
-static void vpif_calculate_offsets(struct channel_obj *ch);
-static void vpif_config_addr(struct channel_obj *ch, int muxmode);
-
-/*
- * buffer_prepare: This is the callback function called from vb2_qbuf()
- * function the buffer is prepared and user space virtual address is converted
- * into physical address
- */
-static int vpif_buffer_prepare(struct vb2_buffer *vb)
-{
- struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_queue *q = vb->vb2_queue;
- struct common_obj *common;
- unsigned long addr;
-
- common = &fh->channel->common[VPIF_VIDEO_INDEX];
- if (vb->state != VB2_BUF_STATE_ACTIVE &&
- vb->state != VB2_BUF_STATE_PREPARED) {
- vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
- if (vb2_plane_vaddr(vb, 0) &&
- vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
- goto buf_align_exit;
-
- addr = vb2_dma_contig_plane_dma_addr(vb, 0);
- if (q->streaming &&
- (V4L2_BUF_TYPE_SLICED_VBI_OUTPUT != q->type)) {
- if (!ISALIGNED(addr + common->ytop_off) ||
- !ISALIGNED(addr + common->ybtm_off) ||
- !ISALIGNED(addr + common->ctop_off) ||
- !ISALIGNED(addr + common->cbtm_off))
- goto buf_align_exit;
- }
- }
- return 0;
-
-buf_align_exit:
- vpif_err("buffer offset not aligned to 8 bytes\n");
- return -EINVAL;
-}
-
-/*
- * vpif_buffer_queue_setup: This function allocates memory for the buffers
- */
-static int vpif_buffer_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
- unsigned int *nbuffers, unsigned int *nplanes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- unsigned long size;
-
- if (V4L2_MEMORY_MMAP == common->memory) {
- size = config_params.channel_bufsize[ch->channel_id];
- /*
- * Checking if the buffer size exceeds the available buffer
- * ycmux_mode = 0 means 1 channel mode HD and
- * ycmux_mode = 1 means 2 channels mode SD
- */
- if (ch->vpifparams.std_info.ycmux_mode == 0) {
- if (config_params.video_limit[ch->channel_id])
- while (size * *nbuffers >
- (config_params.video_limit[0]
- + config_params.video_limit[1]))
- (*nbuffers)--;
- } else {
- if (config_params.video_limit[ch->channel_id])
- while (size * *nbuffers >
- config_params.video_limit[ch->channel_id])
- (*nbuffers)--;
- }
- } else {
- size = common->fmt.fmt.pix.sizeimage;
- }
-
- if (*nbuffers < config_params.min_numbuffers)
- *nbuffers = config_params.min_numbuffers;
-
- *nplanes = 1;
- sizes[0] = size;
- alloc_ctxs[0] = common->alloc_ctx;
- return 0;
-}
-
-/*
- * vpif_buffer_queue: This function adds the buffer to DMA queue
- */
-static void vpif_buffer_queue(struct vb2_buffer *vb)
-{
- struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
- struct vpif_disp_buffer *buf = container_of(vb,
- struct vpif_disp_buffer, vb);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
-
- /* add the buffer to the DMA queue */
- list_add_tail(&buf->list, &common->dma_queue);
-}
-
-/*
- * vpif_buf_cleanup: This function is called from the videobuf2 layer to
- * free memory allocated to the buffers
- */
-static void vpif_buf_cleanup(struct vb2_buffer *vb)
-{
- struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
- struct vpif_disp_buffer *buf = container_of(vb,
- struct vpif_disp_buffer, vb);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
- unsigned long flags;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
-
- spin_lock_irqsave(&common->irqlock, flags);
- if (vb->state == VB2_BUF_STATE_ACTIVE)
- list_del_init(&buf->list);
- spin_unlock_irqrestore(&common->irqlock, flags);
-}
-
-static void vpif_wait_prepare(struct vb2_queue *vq)
-{
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
- mutex_unlock(&common->lock);
-}
-
-static void vpif_wait_finish(struct vb2_queue *vq)
-{
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
- mutex_lock(&common->lock);
-}
-
-static int vpif_buffer_init(struct vb2_buffer *vb)
-{
- struct vpif_disp_buffer *buf = container_of(vb,
- struct vpif_disp_buffer, vb);
-
- INIT_LIST_HEAD(&buf->list);
-
- return 0;
-}
-
-static u8 channel_first_int[VPIF_NUMOBJECTS][2] = { {1, 1} };
-
-static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
- struct vpif_display_config *vpif_config_data =
- vpif_dev->platform_data;
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct vpif_params *vpif = &ch->vpifparams;
- unsigned long addr = 0;
- int ret;
-
- /* If buffer queue is empty, return error */
- if (list_empty(&common->dma_queue)) {
- vpif_err("buffer queue is empty\n");
- return -EIO;
- }
-
- /* Get the next frame from the buffer queue */
- common->next_frm = common->cur_frm =
- list_entry(common->dma_queue.next,
- struct vpif_disp_buffer, list);
-
- list_del(&common->cur_frm->list);
- /* Mark state of the current frame to active */
- common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
-
- /* Initialize field_id and started member */
- ch->field_id = 0;
- common->started = 1;
- addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
- /* Calculate the offset for Y and C data in the buffer */
- vpif_calculate_offsets(ch);
-
- if ((ch->vpifparams.std_info.frm_fmt &&
- ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE)
- && (common->fmt.fmt.pix.field != V4L2_FIELD_ANY)))
- || (!ch->vpifparams.std_info.frm_fmt
- && (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
- vpif_err("conflict in field format and std format\n");
- return -EINVAL;
- }
-
- /* clock settings */
- ret =
- vpif_config_data->set_clock(ch->vpifparams.std_info.ycmux_mode,
- ch->vpifparams.std_info.hd_sd);
- if (ret < 0) {
- vpif_err("can't set clock\n");
- return ret;
- }
-
- /* set the parameters and addresses */
- ret = vpif_set_video_params(vpif, ch->channel_id + 2);
- if (ret < 0)
- return ret;
-
- common->started = ret;
- vpif_config_addr(ch, ret);
- common->set_addr((addr + common->ytop_off),
- (addr + common->ybtm_off),
- (addr + common->ctop_off),
- (addr + common->cbtm_off));
-
- /* Set interrupt for both the fields in VPIF
- Register enable channel in VPIF register */
- if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
- channel2_intr_assert();
- channel2_intr_enable(1);
- enable_channel2(1);
- if (vpif_config_data->ch2_clip_en)
- channel2_clipping_enable(1);
- }
-
- if ((VPIF_CHANNEL3_VIDEO == ch->channel_id)
- || (common->started == 2)) {
- channel3_intr_assert();
- channel3_intr_enable(1);
- enable_channel3(1);
- if (vpif_config_data->ch3_clip_en)
- channel3_clipping_enable(1);
- }
- channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
-
- return 0;
-}
-
-/* abort streaming and wait for last buffer */
-static int vpif_stop_streaming(struct vb2_queue *vq)
-{
- struct vpif_fh *fh = vb2_get_drv_priv(vq);
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
-
- if (!vb2_is_streaming(vq))
- return 0;
-
- common = &ch->common[VPIF_VIDEO_INDEX];
-
- /* release all active buffers */
- while (!list_empty(&common->dma_queue)) {
- common->next_frm = list_entry(common->dma_queue.next,
- struct vpif_disp_buffer, list);
- list_del(&common->next_frm->list);
- vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR);
- }
-
- return 0;
-}
-
-static struct vb2_ops video_qops = {
- .queue_setup = vpif_buffer_queue_setup,
- .wait_prepare = vpif_wait_prepare,
- .wait_finish = vpif_wait_finish,
- .buf_init = vpif_buffer_init,
- .buf_prepare = vpif_buffer_prepare,
- .start_streaming = vpif_start_streaming,
- .stop_streaming = vpif_stop_streaming,
- .buf_cleanup = vpif_buf_cleanup,
- .buf_queue = vpif_buffer_queue,
-};
-
-static void process_progressive_mode(struct common_obj *common)
-{
- unsigned long addr = 0;
-
- /* Get the next buffer from buffer queue */
- common->next_frm = list_entry(common->dma_queue.next,
- struct vpif_disp_buffer, list);
- /* Remove that buffer from the buffer queue */
- list_del(&common->next_frm->list);
- /* Mark status of the buffer as active */
- common->next_frm->vb.state = VB2_BUF_STATE_ACTIVE;
-
- /* Set top and bottom field addrs in VPIF registers */
- addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb, 0);
- common->set_addr(addr + common->ytop_off,
- addr + common->ybtm_off,
- addr + common->ctop_off,
- addr + common->cbtm_off);
-}
-
-static void process_interlaced_mode(int fid, struct common_obj *common)
-{
- /* device field id and local field id are in sync */
- /* If this is even field */
- if (0 == fid) {
- if (common->cur_frm == common->next_frm)
- return;
-
- /* one frame is displayed If next frame is
- * available, release cur_frm and move on */
- /* Copy frame display time */
- do_gettimeofday(&common->cur_frm->vb.v4l2_buf.timestamp);
- /* Change status of the cur_frm */
- vb2_buffer_done(&common->cur_frm->vb,
- VB2_BUF_STATE_DONE);
- /* Make cur_frm pointing to next_frm */
- common->cur_frm = common->next_frm;
-
- } else if (1 == fid) { /* odd field */
- if (list_empty(&common->dma_queue)
- || (common->cur_frm != common->next_frm)) {
- return;
- }
- /* one field is displayed configure the next
- * frame if it is available else hold on current
- * frame */
- /* Get next from the buffer queue */
- process_progressive_mode(common);
-
- }
-}
-
-/*
- * vpif_channel_isr: It changes status of the displayed buffer, takes next
- * buffer from the queue and sets its address in VPIF registers
- */
-static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
-{
- struct vpif_device *dev = &vpif_obj;
- struct channel_obj *ch;
- struct common_obj *common;
- enum v4l2_field field;
- int fid = -1, i;
- int channel_id = 0;
-
- channel_id = *(int *)(dev_id);
- if (!vpif_intr_status(channel_id + 2))
- return IRQ_NONE;
-
- ch = dev->dev[channel_id];
- field = ch->common[VPIF_VIDEO_INDEX].fmt.fmt.pix.field;
- for (i = 0; i < VPIF_NUMOBJECTS; i++) {
- common = &ch->common[i];
- /* If streaming is started in this channel */
- if (0 == common->started)
- continue;
-
- if (1 == ch->vpifparams.std_info.frm_fmt) {
- if (list_empty(&common->dma_queue))
- continue;
-
- /* Progressive mode */
- if (!channel_first_int[i][channel_id]) {
- /* Mark status of the cur_frm to
- * done and unlock semaphore on it */
- do_gettimeofday(&common->cur_frm->vb.
- v4l2_buf.timestamp);
- vb2_buffer_done(&common->cur_frm->vb,
- VB2_BUF_STATE_DONE);
- /* Make cur_frm pointing to next_frm */
- common->cur_frm = common->next_frm;
- }
-
- channel_first_int[i][channel_id] = 0;
- process_progressive_mode(common);
- } else {
- /* Interlaced mode */
- /* If it is first interrupt, ignore it */
-
- if (channel_first_int[i][channel_id]) {
- channel_first_int[i][channel_id] = 0;
- continue;
- }
-
- if (0 == i) {
- ch->field_id ^= 1;
- /* Get field id from VPIF registers */
- fid = vpif_channel_getfid(ch->channel_id + 2);
- /* If fid does not match with stored field id */
- if (fid != ch->field_id) {
- /* Make them in sync */
- if (0 == fid)
- ch->field_id = fid;
-
- return IRQ_HANDLED;
- }
- }
- process_interlaced_mode(fid, common);
- }
- }
-
- return IRQ_HANDLED;
-}
-
-static int vpif_update_std_info(struct channel_obj *ch)
-{
- struct video_obj *vid_ch = &ch->video;
- struct vpif_params *vpifparams = &ch->vpifparams;
- struct vpif_channel_config_params *std_info = &vpifparams->std_info;
- const struct vpif_channel_config_params *config;
-
- int i;
-
- for (i = 0; i < vpif_ch_params_count; i++) {
- config = &ch_params[i];
- if (config->hd_sd == 0) {
- vpif_dbg(2, debug, "SD format\n");
- if (config->stdid & vid_ch->stdid) {
- memcpy(std_info, config, sizeof(*config));
- break;
- }
- } else {
- vpif_dbg(2, debug, "HD format\n");
- if (config->dv_preset == vid_ch->dv_preset) {
- memcpy(std_info, config, sizeof(*config));
- break;
- }
- }
- }
-
- if (i == vpif_ch_params_count) {
- vpif_dbg(1, debug, "Format not found\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vpif_update_resolution(struct channel_obj *ch)
-{
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct video_obj *vid_ch = &ch->video;
- struct vpif_params *vpifparams = &ch->vpifparams;
- struct vpif_channel_config_params *std_info = &vpifparams->std_info;
-
- if (!vid_ch->stdid && !vid_ch->dv_preset && !vid_ch->bt_timings.height)
- return -EINVAL;
-
- if (vid_ch->stdid || vid_ch->dv_preset) {
- if (vpif_update_std_info(ch))
- return -EINVAL;
- }
-
- common->fmt.fmt.pix.width = std_info->width;
- common->fmt.fmt.pix.height = std_info->height;
- vpif_dbg(1, debug, "Pixel details: Width = %d,Height = %d\n",
- common->fmt.fmt.pix.width, common->fmt.fmt.pix.height);
-
- /* Set height and width paramateres */
- common->height = std_info->height;
- common->width = std_info->width;
-
- return 0;
-}
-
-/*
- * vpif_calculate_offsets: This function calculates buffers offset for Y and C
- * in the top and bottom field
- */
-static void vpif_calculate_offsets(struct channel_obj *ch)
-{
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct vpif_params *vpifparams = &ch->vpifparams;
- enum v4l2_field field = common->fmt.fmt.pix.field;
- struct video_obj *vid_ch = &ch->video;
- unsigned int hpitch, vpitch, sizeimage;
-
- if (V4L2_FIELD_ANY == common->fmt.fmt.pix.field) {
- if (ch->vpifparams.std_info.frm_fmt)
- vid_ch->buf_field = V4L2_FIELD_NONE;
- else
- vid_ch->buf_field = V4L2_FIELD_INTERLACED;
- } else {
- vid_ch->buf_field = common->fmt.fmt.pix.field;
- }
-
- sizeimage = common->fmt.fmt.pix.sizeimage;
-
- hpitch = common->fmt.fmt.pix.bytesperline;
- vpitch = sizeimage / (hpitch * 2);
- if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
- (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
- common->ytop_off = 0;
- common->ybtm_off = hpitch;
- common->ctop_off = sizeimage / 2;
- common->cbtm_off = sizeimage / 2 + hpitch;
- } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
- common->ytop_off = 0;
- common->ybtm_off = sizeimage / 4;
- common->ctop_off = sizeimage / 2;
- common->cbtm_off = common->ctop_off + sizeimage / 4;
- } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
- common->ybtm_off = 0;
- common->ytop_off = sizeimage / 4;
- common->cbtm_off = sizeimage / 2;
- common->ctop_off = common->cbtm_off + sizeimage / 4;
- }
-
- if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
- (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
- vpifparams->video_params.storage_mode = 1;
- } else {
- vpifparams->video_params.storage_mode = 0;
- }
-
- if (ch->vpifparams.std_info.frm_fmt == 1) {
- vpifparams->video_params.hpitch =
- common->fmt.fmt.pix.bytesperline;
- } else {
- if ((field == V4L2_FIELD_ANY) ||
- (field == V4L2_FIELD_INTERLACED))
- vpifparams->video_params.hpitch =
- common->fmt.fmt.pix.bytesperline * 2;
- else
- vpifparams->video_params.hpitch =
- common->fmt.fmt.pix.bytesperline;
- }
-
- ch->vpifparams.video_params.stdid = ch->vpifparams.std_info.stdid;
-}
-
-static void vpif_config_format(struct channel_obj *ch)
-{
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
- if (config_params.numbuffers[ch->channel_id] == 0)
- common->memory = V4L2_MEMORY_USERPTR;
- else
- common->memory = V4L2_MEMORY_MMAP;
-
- common->fmt.fmt.pix.sizeimage =
- config_params.channel_bufsize[ch->channel_id];
- common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
- common->fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-}
-
-static int vpif_check_format(struct channel_obj *ch,
- struct v4l2_pix_format *pixfmt)
-{
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- enum v4l2_field field = pixfmt->field;
- u32 sizeimage, hpitch, vpitch;
-
- if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P)
- goto invalid_fmt_exit;
-
- if (!(VPIF_VALID_FIELD(field)))
- goto invalid_fmt_exit;
-
- if (pixfmt->bytesperline <= 0)
- goto invalid_pitch_exit;
-
- sizeimage = pixfmt->sizeimage;
-
- if (vpif_update_resolution(ch))
- return -EINVAL;
-
- hpitch = pixfmt->bytesperline;
- vpitch = sizeimage / (hpitch * 2);
-
- /* Check for valid value of pitch */
- if ((hpitch < ch->vpifparams.std_info.width) ||
- (vpitch < ch->vpifparams.std_info.height))
- goto invalid_pitch_exit;
-
- /* Check for 8 byte alignment */
- if (!ISALIGNED(hpitch)) {
- vpif_err("invalid pitch alignment\n");
- return -EINVAL;
- }
- pixfmt->width = common->fmt.fmt.pix.width;
- pixfmt->height = common->fmt.fmt.pix.height;
-
- return 0;
-
-invalid_fmt_exit:
- vpif_err("invalid field format\n");
- return -EINVAL;
-
-invalid_pitch_exit:
- vpif_err("invalid pitch\n");
- return -EINVAL;
-}
-
-static void vpif_config_addr(struct channel_obj *ch, int muxmode)
-{
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- if (VPIF_CHANNEL3_VIDEO == ch->channel_id) {
- common->set_addr = ch3_set_videobuf_addr;
- } else {
- if (2 == muxmode)
- common->set_addr = ch2_set_videobuf_addr_yc_nmux;
- else
- common->set_addr = ch2_set_videobuf_addr;
- }
-}
-
-/*
- * vpif_mmap: It is used to map kernel space buffers into user spaces
- */
-static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
-{
- struct vpif_fh *fh = filep->private_data;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
-
- vpif_dbg(2, debug, "vpif_mmap\n");
-
- return vb2_mmap(&common->buffer_queue, vma);
-}
-
-/*
- * vpif_poll: It is used for select/poll system call
- */
-static unsigned int vpif_poll(struct file *filep, poll_table *wait)
-{
- struct vpif_fh *fh = filep->private_data;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- if (common->started)
- return vb2_poll(&common->buffer_queue, filep, wait);
-
- return 0;
-}
-
-/*
- * vpif_open: It creates object of file handle structure and stores it in
- * private_data member of filepointer
- */
-static int vpif_open(struct file *filep)
-{
- struct video_device *vdev = video_devdata(filep);
- struct channel_obj *ch = NULL;
- struct vpif_fh *fh = NULL;
-
- ch = video_get_drvdata(vdev);
- /* Allocate memory for the file handle object */
- fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
- if (fh == NULL) {
- vpif_err("unable to allocate memory for file handle object\n");
- return -ENOMEM;
- }
-
- /* store pointer to fh in private_data member of filep */
- filep->private_data = fh;
- fh->channel = ch;
- fh->initialized = 0;
- if (!ch->initialized) {
- fh->initialized = 1;
- ch->initialized = 1;
- memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
- }
-
- /* Increment channel usrs counter */
- atomic_inc(&ch->usrs);
- /* Set io_allowed[VPIF_VIDEO_INDEX] member to false */
- fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
- /* Initialize priority of this instance to default priority */
- fh->prio = V4L2_PRIORITY_UNSET;
- v4l2_prio_open(&ch->prio, &fh->prio);
-
- return 0;
-}
-
-/*
- * vpif_release: This function deletes buffer queue, frees the buffers and
- * the vpif file handle
- */
-static int vpif_release(struct file *filep)
-{
- struct vpif_fh *fh = filep->private_data;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- /* if this instance is doing IO */
- if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
- /* Reset io_usrs member of channel object */
- common->io_usrs = 0;
- /* Disable channel */
- if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
- enable_channel2(0);
- channel2_intr_enable(0);
- }
- if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
- (2 == common->started)) {
- enable_channel3(0);
- channel3_intr_enable(0);
- }
- common->started = 0;
-
- /* Free buffers allocated */
- vb2_queue_release(&common->buffer_queue);
- vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
-
- common->numbuffers =
- config_params.numbuffers[ch->channel_id];
- }
-
- /* Decrement channel usrs counter */
- atomic_dec(&ch->usrs);
- /* If this file handle has initialize encoder device, reset it */
- if (fh->initialized)
- ch->initialized = 0;
-
- /* Close the priority */
- v4l2_prio_close(&ch->prio, fh->prio);
- filep->private_data = NULL;
- fh->initialized = 0;
- kfree(fh);
-
- return 0;
-}
-
-/* functions implementing ioctls */
-/**
- * vpif_querycap() - QUERYCAP handler
- * @file: file ptr
- * @priv: file handle
- * @cap: ptr to v4l2_capability structure
- */
-static int vpif_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct vpif_display_config *config = vpif_dev->platform_data;
-
- cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
- strlcpy(cap->driver, "vpif display", sizeof(cap->driver));
- strlcpy(cap->bus_info, "Platform", sizeof(cap->bus_info));
- strlcpy(cap->card, config->card_name, sizeof(cap->card));
-
- return 0;
-}
-
-static int vpif_enum_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_fmtdesc *fmt)
-{
- if (fmt->index != 0) {
- vpif_err("Invalid format index\n");
- return -EINVAL;
- }
-
- /* Fill in the information about format */
- fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
- fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
-
- return 0;
-}
-
-static int vpif_g_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- /* Check the validity of the buffer type */
- if (common->fmt.type != fmt->type)
- return -EINVAL;
-
- if (vpif_update_resolution(ch))
- return -EINVAL;
- *fmt = common->fmt;
- return 0;
-}
-
-static int vpif_s_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct vpif_fh *fh = priv;
- struct v4l2_pix_format *pixfmt;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- int ret = 0;
-
- if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
- || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
- if (!fh->initialized) {
- vpif_dbg(1, debug, "Channel Busy\n");
- return -EBUSY;
- }
-
- /* Check for the priority */
- ret = v4l2_prio_check(&ch->prio, fh->prio);
- if (0 != ret)
- return ret;
- fh->initialized = 1;
- }
-
- if (common->started) {
- vpif_dbg(1, debug, "Streaming in progress\n");
- return -EBUSY;
- }
-
- pixfmt = &fmt->fmt.pix;
- /* Check for valid field format */
- ret = vpif_check_format(ch, pixfmt);
- if (ret)
- return ret;
-
- /* store the pix format in the channel object */
- common->fmt.fmt.pix = *pixfmt;
- /* store the format in the channel object */
- common->fmt = *fmt;
- return 0;
-}
-
-static int vpif_try_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
- int ret = 0;
-
- ret = vpif_check_format(ch, pixfmt);
- if (ret) {
- *pixfmt = common->fmt.fmt.pix;
- pixfmt->sizeimage = pixfmt->width * pixfmt->height * 2;
- }
-
- return ret;
-}
-
-static int vpif_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbuf)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common;
- enum v4l2_field field;
- struct vb2_queue *q;
- u8 index = 0;
-
- /* This file handle has not initialized the channel,
- It is not allowed to do settings */
- if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
- || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
- if (!fh->initialized) {
- vpif_err("Channel Busy\n");
- return -EBUSY;
- }
- }
-
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT != reqbuf->type)
- return -EINVAL;
-
- index = VPIF_VIDEO_INDEX;
-
- common = &ch->common[index];
-
- if (common->fmt.type != reqbuf->type || !vpif_dev)
- return -EINVAL;
- if (0 != common->io_usrs)
- return -EBUSY;
-
- if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- if (common->fmt.fmt.pix.field == V4L2_FIELD_ANY)
- field = V4L2_FIELD_INTERLACED;
- else
- field = common->fmt.fmt.pix.field;
- } else {
- field = V4L2_VBI_INTERLACED;
- }
- /* Initialize videobuf2 queue as per the buffer type */
- common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
- if (!common->alloc_ctx) {
- vpif_err("Failed to get the context\n");
- return -EINVAL;
- }
- q = &common->buffer_queue;
- q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- q->io_modes = VB2_MMAP | VB2_USERPTR;
- q->drv_priv = fh;
- q->ops = &video_qops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->buf_struct_size = sizeof(struct vpif_disp_buffer);
-
- vb2_queue_init(q);
-
- /* Set io allowed member of file handle to TRUE */
- fh->io_allowed[index] = 1;
- /* Increment io usrs member of channel object to 1 */
- common->io_usrs = 1;
- /* Store type of memory requested in channel object */
- common->memory = reqbuf->memory;
- INIT_LIST_HEAD(&common->dma_queue);
- /* Allocate buffers */
- return vb2_reqbufs(&common->buffer_queue, reqbuf);
-}
-
-static int vpif_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *tbuf)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- if (common->fmt.type != tbuf->type)
- return -EINVAL;
-
- return vb2_querybuf(&common->buffer_queue, tbuf);
-}
-
-static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct vpif_fh *fh = NULL;
- struct channel_obj *ch = NULL;
- struct common_obj *common = NULL;
-
- if (!buf || !priv)
- return -EINVAL;
-
- fh = priv;
- ch = fh->channel;
- if (!ch)
- return -EINVAL;
-
- common = &(ch->common[VPIF_VIDEO_INDEX]);
- if (common->fmt.type != buf->type)
- return -EINVAL;
-
- if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
- vpif_err("fh->io_allowed\n");
- return -EACCES;
- }
-
- return vb2_qbuf(&common->buffer_queue, buf);
-}
-
-static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- int ret = 0;
-
- if (!(*std_id & VPIF_V4L2_STD))
- return -EINVAL;
-
- if (common->started) {
- vpif_err("streaming in progress\n");
- return -EBUSY;
- }
-
- /* Call encoder subdevice function to set the standard */
- ch->video.stdid = *std_id;
- ch->video.dv_preset = V4L2_DV_INVALID;
- memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
-
- /* Get the information about the standard */
- if (vpif_update_resolution(ch))
- return -EINVAL;
-
- if ((ch->vpifparams.std_info.width *
- ch->vpifparams.std_info.height * 2) >
- config_params.channel_bufsize[ch->channel_id]) {
- vpif_err("invalid std for this size\n");
- return -EINVAL;
- }
-
- common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width;
- /* Configure the default format information */
- vpif_config_format(ch);
-
- ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
- s_std_output, *std_id);
- if (ret < 0) {
- vpif_err("Failed to set output standard\n");
- return ret;
- }
-
- ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, core,
- s_std, *std_id);
- if (ret < 0)
- vpif_err("Failed to set standard for sub devices\n");
- return ret;
-}
-
-static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- *std = ch->video.stdid;
- return 0;
-}
-
-static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- return vb2_dqbuf(&common->buffer_queue, p,
- (file->f_flags & O_NONBLOCK));
-}
-
-static int vpif_streamon(struct file *file, void *priv,
- enum v4l2_buf_type buftype)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
- int ret = 0;
-
- if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- vpif_err("buffer type not supported\n");
- return -EINVAL;
- }
-
- if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
- vpif_err("fh->io_allowed\n");
- return -EACCES;
- }
-
- /* If Streaming is already started, return error */
- if (common->started) {
- vpif_err("channel->started\n");
- return -EBUSY;
- }
-
- if ((ch->channel_id == VPIF_CHANNEL2_VIDEO
- && oth_ch->common[VPIF_VIDEO_INDEX].started &&
- ch->vpifparams.std_info.ycmux_mode == 0)
- || ((ch->channel_id == VPIF_CHANNEL3_VIDEO)
- && (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
- vpif_err("other channel is using\n");
- return -EBUSY;
- }
-
- ret = vpif_check_format(ch, &common->fmt.fmt.pix);
- if (ret < 0)
- return ret;
-
- /* Call vb2_streamon to start streaming in videobuf2 */
- ret = vb2_streamon(&common->buffer_queue, buftype);
- if (ret < 0) {
- vpif_err("vb2_streamon\n");
- return ret;
- }
-
- return ret;
-}
-
-static int vpif_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type buftype)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct vpif_display_config *vpif_config_data =
- vpif_dev->platform_data;
-
- if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- vpif_err("buffer type not supported\n");
- return -EINVAL;
- }
-
- if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
- vpif_err("fh->io_allowed\n");
- return -EACCES;
- }
-
- if (!common->started) {
- vpif_err("channel->started\n");
- return -EINVAL;
- }
-
- if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- /* disable channel */
- if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
- if (vpif_config_data->ch2_clip_en)
- channel2_clipping_enable(0);
- enable_channel2(0);
- channel2_intr_enable(0);
- }
- if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
- (2 == common->started)) {
- if (vpif_config_data->ch3_clip_en)
- channel3_clipping_enable(0);
- enable_channel3(0);
- channel3_intr_enable(0);
- }
- }
-
- common->started = 0;
- return vb2_streamoff(&common->buffer_queue, buftype);
-}
-
-static int vpif_cropcap(struct file *file, void *priv,
- struct v4l2_cropcap *crop)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT != crop->type)
- return -EINVAL;
-
- crop->bounds.left = crop->bounds.top = 0;
- crop->defrect.left = crop->defrect.top = 0;
- crop->defrect.height = crop->bounds.height = common->height;
- crop->defrect.width = crop->bounds.width = common->width;
-
- return 0;
-}
-
-static int vpif_enum_output(struct file *file, void *fh,
- struct v4l2_output *output)
-{
-
- struct vpif_display_config *config = vpif_dev->platform_data;
-
- if (output->index >= config->output_count) {
- vpif_dbg(1, debug, "Invalid output index\n");
- return -EINVAL;
- }
-
- strcpy(output->name, config->output[output->index]);
- output->type = V4L2_OUTPUT_TYPE_ANALOG;
- output->std = VPIF_V4L2_STD;
-
- return 0;
-}
-
-static int vpif_s_output(struct file *file, void *priv, unsigned int i)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct video_obj *vid_ch = &ch->video;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- int ret = 0;
-
- if (common->started) {
- vpif_err("Streaming in progress\n");
- return -EBUSY;
- }
-
- ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
- s_routing, 0, i, 0);
-
- if (ret < 0)
- vpif_err("Failed to set output standard\n");
-
- vid_ch->output_id = i;
- return ret;
-}
-
-static int vpif_g_output(struct file *file, void *priv, unsigned int *i)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct video_obj *vid_ch = &ch->video;
-
- *i = vid_ch->output_id;
-
- return 0;
-}
-
-static int vpif_g_priority(struct file *file, void *priv, enum v4l2_priority *p)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- *p = v4l2_prio_max(&ch->prio);
-
- return 0;
-}
-
-static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- return v4l2_prio_change(&ch->prio, &fh->prio, p);
-}
-
-/**
- * vpif_enum_dv_presets() - ENUM_DV_PRESETS handler
- * @file: file ptr
- * @priv: file handle
- * @preset: input preset
- */
-static int vpif_enum_dv_presets(struct file *file, void *priv,
- struct v4l2_dv_enum_preset *preset)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct video_obj *vid_ch = &ch->video;
-
- return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
- video, enum_dv_presets, preset);
-}
-
-/**
- * vpif_s_dv_presets() - S_DV_PRESETS handler
- * @file: file ptr
- * @priv: file handle
- * @preset: input preset
- */
-static int vpif_s_dv_preset(struct file *file, void *priv,
- struct v4l2_dv_preset *preset)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct video_obj *vid_ch = &ch->video;
- int ret = 0;
-
- if (common->started) {
- vpif_dbg(1, debug, "streaming in progress\n");
- return -EBUSY;
- }
-
- ret = v4l2_prio_check(&ch->prio, fh->prio);
- if (ret != 0)
- return ret;
-
- fh->initialized = 1;
-
- /* Call encoder subdevice function to set the standard */
- if (mutex_lock_interruptible(&common->lock))
- return -ERESTARTSYS;
-
- ch->video.dv_preset = preset->preset;
- ch->video.stdid = V4L2_STD_UNKNOWN;
- memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
-
- /* Get the information about the standard */
- if (vpif_update_resolution(ch)) {
- ret = -EINVAL;
- } else {
- /* Configure the default format information */
- vpif_config_format(ch);
-
- ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
- video, s_dv_preset, preset);
- }
-
- mutex_unlock(&common->lock);
-
- return ret;
-}
-/**
- * vpif_g_dv_presets() - G_DV_PRESETS handler
- * @file: file ptr
- * @priv: file handle
- * @preset: input preset
- */
-static int vpif_g_dv_preset(struct file *file, void *priv,
- struct v4l2_dv_preset *preset)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- preset->preset = ch->video.dv_preset;
-
- return 0;
-}
-/**
- * vpif_s_dv_timings() - S_DV_TIMINGS handler
- * @file: file ptr
- * @priv: file handle
- * @timings: digital video timings
- */
-static int vpif_s_dv_timings(struct file *file, void *priv,
- struct v4l2_dv_timings *timings)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct vpif_params *vpifparams = &ch->vpifparams;
- struct vpif_channel_config_params *std_info = &vpifparams->std_info;
- struct video_obj *vid_ch = &ch->video;
- struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
- int ret;
-
- if (timings->type != V4L2_DV_BT_656_1120) {
- vpif_dbg(2, debug, "Timing type not defined\n");
- return -EINVAL;
- }
-
- /* Configure subdevice timings, if any */
- ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
- video, s_dv_timings, timings);
- if (ret == -ENOIOCTLCMD) {
- vpif_dbg(2, debug, "Custom DV timings not supported by "
- "subdevice\n");
- return -EINVAL;
- }
- if (ret < 0) {
- vpif_dbg(2, debug, "Error setting custom DV timings\n");
- return ret;
- }
-
- if (!(timings->bt.width && timings->bt.height &&
- (timings->bt.hbackporch ||
- timings->bt.hfrontporch ||
- timings->bt.hsync) &&
- timings->bt.vfrontporch &&
- (timings->bt.vbackporch ||
- timings->bt.vsync))) {
- vpif_dbg(2, debug, "Timings for width, height, "
- "horizontal back porch, horizontal sync, "
- "horizontal front porch, vertical back porch, "
- "vertical sync and vertical back porch "
- "must be defined\n");
- return -EINVAL;
- }
-
- *bt = timings->bt;
-
- /* Configure video port timings */
-
- std_info->eav2sav = bt->hbackporch + bt->hfrontporch +
- bt->hsync - 8;
- std_info->sav2eav = bt->width;
-
- std_info->l1 = 1;
- std_info->l3 = bt->vsync + bt->vbackporch + 1;
-
- if (bt->interlaced) {
- if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
- std_info->vsize = bt->height * 2 +
- bt->vfrontporch + bt->vsync + bt->vbackporch +
- bt->il_vfrontporch + bt->il_vsync +
- bt->il_vbackporch;
- std_info->l5 = std_info->vsize/2 -
- (bt->vfrontporch - 1);
- std_info->l7 = std_info->vsize/2 + 1;
- std_info->l9 = std_info->l7 + bt->il_vsync +
- bt->il_vbackporch + 1;
- std_info->l11 = std_info->vsize -
- (bt->il_vfrontporch - 1);
- } else {
- vpif_dbg(2, debug, "Required timing values for "
- "interlaced BT format missing\n");
- return -EINVAL;
- }
- } else {
- std_info->vsize = bt->height + bt->vfrontporch +
- bt->vsync + bt->vbackporch;
- std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
- }
- strncpy(std_info->name, "Custom timings BT656/1120",
- VPIF_MAX_NAME);
- std_info->width = bt->width;
- std_info->height = bt->height;
- std_info->frm_fmt = bt->interlaced ? 0 : 1;
- std_info->ycmux_mode = 0;
- std_info->capture_format = 0;
- std_info->vbi_supported = 0;
- std_info->hd_sd = 1;
- std_info->stdid = 0;
- std_info->dv_preset = V4L2_DV_INVALID;
-
- vid_ch->stdid = 0;
- vid_ch->dv_preset = V4L2_DV_INVALID;
-
- return 0;
-}
-
-/**
- * vpif_g_dv_timings() - G_DV_TIMINGS handler
- * @file: file ptr
- * @priv: file handle
- * @timings: digital video timings
- */
-static int vpif_g_dv_timings(struct file *file, void *priv,
- struct v4l2_dv_timings *timings)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct video_obj *vid_ch = &ch->video;
- struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
-
- timings->bt = *bt;
-
- return 0;
-}
-
-/*
- * vpif_g_chip_ident() - Identify the chip
- * @file: file ptr
- * @priv: file handle
- * @chip: chip identity
- *
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
- chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
- vpif_dbg(2, debug, "match_type is invalid.\n");
- return -EINVAL;
- }
-
- return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
- g_chip_ident, chip);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-/*
- * vpif_dbg_g_register() - Read register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be read
- *
- * Debugging only
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_dbg_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg){
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct video_obj *vid_ch = &ch->video;
-
- return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core,
- g_register, reg);
-}
-
-/*
- * vpif_dbg_s_register() - Write to register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be modified
- *
- * Debugging only
- * Returns zero or -EINVAL if write operations fails.
- */
-static int vpif_dbg_s_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg){
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct video_obj *vid_ch = &ch->video;
-
- return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core,
- s_register, reg);
-}
-#endif
-
-/*
- * vpif_log_status() - Status information
- * @file: file ptr
- * @priv: file handle
- *
- * Returns zero.
- */
-static int vpif_log_status(struct file *filep, void *priv)
-{
- /* status for sub devices */
- v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);
-
- return 0;
-}
-
-/* vpif display ioctl operations */
-static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
- .vidioc_querycap = vpif_querycap,
- .vidioc_g_priority = vpif_g_priority,
- .vidioc_s_priority = vpif_s_priority,
- .vidioc_enum_fmt_vid_out = vpif_enum_fmt_vid_out,
- .vidioc_g_fmt_vid_out = vpif_g_fmt_vid_out,
- .vidioc_s_fmt_vid_out = vpif_s_fmt_vid_out,
- .vidioc_try_fmt_vid_out = vpif_try_fmt_vid_out,
- .vidioc_reqbufs = vpif_reqbufs,
- .vidioc_querybuf = vpif_querybuf,
- .vidioc_qbuf = vpif_qbuf,
- .vidioc_dqbuf = vpif_dqbuf,
- .vidioc_streamon = vpif_streamon,
- .vidioc_streamoff = vpif_streamoff,
- .vidioc_s_std = vpif_s_std,
- .vidioc_g_std = vpif_g_std,
- .vidioc_enum_output = vpif_enum_output,
- .vidioc_s_output = vpif_s_output,
- .vidioc_g_output = vpif_g_output,
- .vidioc_cropcap = vpif_cropcap,
- .vidioc_enum_dv_presets = vpif_enum_dv_presets,
- .vidioc_s_dv_preset = vpif_s_dv_preset,
- .vidioc_g_dv_preset = vpif_g_dv_preset,
- .vidioc_s_dv_timings = vpif_s_dv_timings,
- .vidioc_g_dv_timings = vpif_g_dv_timings,
- .vidioc_g_chip_ident = vpif_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vpif_dbg_g_register,
- .vidioc_s_register = vpif_dbg_s_register,
-#endif
- .vidioc_log_status = vpif_log_status,
-};
-
-static const struct v4l2_file_operations vpif_fops = {
- .owner = THIS_MODULE,
- .open = vpif_open,
- .release = vpif_release,
- .unlocked_ioctl = video_ioctl2,
- .mmap = vpif_mmap,
- .poll = vpif_poll
-};
-
-static struct video_device vpif_video_template = {
- .name = "vpif",
- .fops = &vpif_fops,
- .ioctl_ops = &vpif_ioctl_ops,
- .tvnorms = VPIF_V4L2_STD,
- .current_norm = V4L2_STD_625_50,
-
-};
-
-/*Configure the channels, buffer sizei, request irq */
-static int initialize_vpif(void)
-{
- int free_channel_objects_index;
- int free_buffer_channel_index;
- int free_buffer_index;
- int err = 0, i, j;
-
- /* Default number of buffers should be 3 */
- if ((ch2_numbuffers > 0) &&
- (ch2_numbuffers < config_params.min_numbuffers))
- ch2_numbuffers = config_params.min_numbuffers;
- if ((ch3_numbuffers > 0) &&
- (ch3_numbuffers < config_params.min_numbuffers))
- ch3_numbuffers = config_params.min_numbuffers;
-
- /* Set buffer size to min buffers size if invalid buffer size is
- * given */
- if (ch2_bufsize < config_params.min_bufsize[VPIF_CHANNEL2_VIDEO])
- ch2_bufsize =
- config_params.min_bufsize[VPIF_CHANNEL2_VIDEO];
- if (ch3_bufsize < config_params.min_bufsize[VPIF_CHANNEL3_VIDEO])
- ch3_bufsize =
- config_params.min_bufsize[VPIF_CHANNEL3_VIDEO];
-
- config_params.numbuffers[VPIF_CHANNEL2_VIDEO] = ch2_numbuffers;
-
- if (ch2_numbuffers) {
- config_params.channel_bufsize[VPIF_CHANNEL2_VIDEO] =
- ch2_bufsize;
- }
- config_params.numbuffers[VPIF_CHANNEL3_VIDEO] = ch3_numbuffers;
-
- if (ch3_numbuffers) {
- config_params.channel_bufsize[VPIF_CHANNEL3_VIDEO] =
- ch3_bufsize;
- }
-
- /* Allocate memory for six channel objects */
- for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
- vpif_obj.dev[i] =
- kzalloc(sizeof(struct channel_obj), GFP_KERNEL);
- /* If memory allocation fails, return error */
- if (!vpif_obj.dev[i]) {
- free_channel_objects_index = i;
- err = -ENOMEM;
- goto vpif_init_free_channel_objects;
- }
- }
-
- free_channel_objects_index = VPIF_DISPLAY_MAX_DEVICES;
- free_buffer_channel_index = VPIF_DISPLAY_NUM_CHANNELS;
- free_buffer_index = config_params.numbuffers[i - 1];
-
- return 0;
-
-vpif_init_free_channel_objects:
- for (j = 0; j < free_channel_objects_index; j++)
- kfree(vpif_obj.dev[j]);
- return err;
-}
-
-/*
- * vpif_probe: This function creates device entries by register itself to the
- * V4L2 driver and initializes fields of each channel objects
- */
-static __init int vpif_probe(struct platform_device *pdev)
-{
- struct vpif_subdev_info *subdevdata;
- struct vpif_display_config *config;
- int i, j = 0, k, q, m, err = 0;
- struct i2c_adapter *i2c_adap;
- struct common_obj *common;
- struct channel_obj *ch;
- struct video_device *vfd;
- struct resource *res;
- int subdev_count;
- size_t size;
-
- vpif_dev = &pdev->dev;
- err = initialize_vpif();
-
- if (err) {
- v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
- return err;
- }
-
- err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
- if (err) {
- v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
- return err;
- }
-
- k = 0;
- while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
- for (i = res->start; i <= res->end; i++) {
- if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
- "VPIF_Display",
- (void *)(&vpif_obj.dev[k]->channel_id))) {
- err = -EBUSY;
- goto vpif_int_err;
- }
- }
- k++;
- }
-
- for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
-
- /* Get the pointer to the channel object */
- ch = vpif_obj.dev[i];
-
- /* Allocate memory for video device */
- vfd = video_device_alloc();
- if (vfd == NULL) {
- for (j = 0; j < i; j++) {
- ch = vpif_obj.dev[j];
- video_device_release(ch->video_dev);
- }
- err = -ENOMEM;
- goto vpif_int_err;
- }
-
- /* Initialize field of video device */
- *vfd = vpif_video_template;
- vfd->v4l2_dev = &vpif_obj.v4l2_dev;
- vfd->release = video_device_release;
- snprintf(vfd->name, sizeof(vfd->name),
- "VPIF_Display_DRIVER_V%s",
- VPIF_DISPLAY_VERSION);
-
- /* Set video_dev to the video device */
- ch->video_dev = vfd;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res) {
- size = resource_size(res);
- /* The resources are divided into two equal memory and when
- * we have HD output we can add them together
- */
- for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
- ch = vpif_obj.dev[j];
- ch->channel_id = j;
-
- /* only enabled if second resource exists */
- config_params.video_limit[ch->channel_id] = 0;
- if (size)
- config_params.video_limit[ch->channel_id] =
- size/2;
- }
- }
-
- for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
- ch = vpif_obj.dev[j];
- /* Initialize field of the channel objects */
- atomic_set(&ch->usrs, 0);
- for (k = 0; k < VPIF_NUMOBJECTS; k++) {
- ch->common[k].numbuffers = 0;
- common = &ch->common[k];
- common->io_usrs = 0;
- common->started = 0;
- spin_lock_init(&common->irqlock);
- mutex_init(&common->lock);
- common->numbuffers = 0;
- common->set_addr = NULL;
- common->ytop_off = common->ybtm_off = 0;
- common->ctop_off = common->cbtm_off = 0;
- common->cur_frm = common->next_frm = NULL;
- memset(&common->fmt, 0, sizeof(common->fmt));
- common->numbuffers = config_params.numbuffers[k];
-
- }
- ch->initialized = 0;
- ch->channel_id = j;
- if (j < 2)
- ch->common[VPIF_VIDEO_INDEX].numbuffers =
- config_params.numbuffers[ch->channel_id];
- else
- ch->common[VPIF_VIDEO_INDEX].numbuffers = 0;
-
- memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
-
- /* Initialize prio member of channel object */
- v4l2_prio_init(&ch->prio);
- ch->common[VPIF_VIDEO_INDEX].fmt.type =
- V4L2_BUF_TYPE_VIDEO_OUTPUT;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &ch->video_dev->flags);
- ch->video_dev->lock = &common->lock;
-
- /* register video device */
- vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
- (int)ch, (int)&ch->video_dev);
-
- err = video_register_device(ch->video_dev,
- VFL_TYPE_GRABBER, (j ? 3 : 2));
- if (err < 0)
- goto probe_out;
-
- video_set_drvdata(ch->video_dev, ch);
- }
-
- i2c_adap = i2c_get_adapter(1);
- config = pdev->dev.platform_data;
- subdev_count = config->subdev_count;
- subdevdata = config->subdevinfo;
- vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count,
- GFP_KERNEL);
- if (vpif_obj.sd == NULL) {
- vpif_err("unable to allocate memory for subdevice pointers\n");
- err = -ENOMEM;
- goto probe_out;
- }
-
- for (i = 0; i < subdev_count; i++) {
- vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
- i2c_adap,
- &subdevdata[i].board_info,
- NULL);
- if (!vpif_obj.sd[i]) {
- vpif_err("Error registering v4l2 subdevice\n");
- goto probe_subdev_out;
- }
-
- if (vpif_obj.sd[i])
- vpif_obj.sd[i]->grp_id = 1 << i;
- }
-
- v4l2_info(&vpif_obj.v4l2_dev,
- " VPIF display driver initialized\n");
- return 0;
-
-probe_subdev_out:
- kfree(vpif_obj.sd);
-probe_out:
- for (k = 0; k < j; k++) {
- ch = vpif_obj.dev[k];
- video_unregister_device(ch->video_dev);
- video_device_release(ch->video_dev);
- ch->video_dev = NULL;
- }
-vpif_int_err:
- v4l2_device_unregister(&vpif_obj.v4l2_dev);
- vpif_err("VPIF IRQ request failed\n");
- for (q = k; k >= 0; k--) {
- for (m = i; m >= res->start; m--)
- free_irq(m, (void *)(&vpif_obj.dev[k]->channel_id));
- res = platform_get_resource(pdev, IORESOURCE_IRQ, k-1);
- m = res->end;
- }
-
- return err;
-}
-
-/*
- * vpif_remove: It un-register channels from V4L2 driver
- */
-static int vpif_remove(struct platform_device *device)
-{
- struct channel_obj *ch;
- int i;
-
- v4l2_device_unregister(&vpif_obj.v4l2_dev);
-
- /* un-register device */
- for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
- /* Get the pointer to the channel object */
- ch = vpif_obj.dev[i];
- /* Unregister video device */
- video_unregister_device(ch->video_dev);
-
- ch->video_dev = NULL;
- }
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int vpif_suspend(struct device *dev)
-{
- struct common_obj *common;
- struct channel_obj *ch;
- int i;
-
- for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
- /* Get the pointer to the channel object */
- ch = vpif_obj.dev[i];
- common = &ch->common[VPIF_VIDEO_INDEX];
- mutex_lock(&common->lock);
- if (atomic_read(&ch->usrs) && common->io_usrs) {
- /* Disable channel */
- if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
- enable_channel2(0);
- channel2_intr_enable(0);
- }
- if (ch->channel_id == VPIF_CHANNEL3_VIDEO ||
- common->started == 2) {
- enable_channel3(0);
- channel3_intr_enable(0);
- }
- }
- mutex_unlock(&common->lock);
- }
-
- return 0;
-}
-
-static int vpif_resume(struct device *dev)
-{
-
- struct common_obj *common;
- struct channel_obj *ch;
- int i;
-
- for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
- /* Get the pointer to the channel object */
- ch = vpif_obj.dev[i];
- common = &ch->common[VPIF_VIDEO_INDEX];
- mutex_lock(&common->lock);
- if (atomic_read(&ch->usrs) && common->io_usrs) {
- /* Enable channel */
- if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
- enable_channel2(1);
- channel2_intr_enable(1);
- }
- if (ch->channel_id == VPIF_CHANNEL3_VIDEO ||
- common->started == 2) {
- enable_channel3(1);
- channel3_intr_enable(1);
- }
- }
- mutex_unlock(&common->lock);
- }
-
- return 0;
-}
-
-static const struct dev_pm_ops vpif_pm = {
- .suspend = vpif_suspend,
- .resume = vpif_resume,
-};
-
-#define vpif_pm_ops (&vpif_pm)
-#else
-#define vpif_pm_ops NULL
-#endif
-
-static __refdata struct platform_driver vpif_driver = {
- .driver = {
- .name = "vpif_display",
- .owner = THIS_MODULE,
- .pm = vpif_pm_ops,
- },
- .probe = vpif_probe,
- .remove = vpif_remove,
-};
-
-static __init int vpif_init(void)
-{
- return platform_driver_register(&vpif_driver);
-}
-
-/*
- * vpif_cleanup: This function un-registers device and driver to the kernel,
- * frees requested irq handler and de-allocates memory allocated for channel
- * objects.
- */
-static void vpif_cleanup(void)
-{
- struct platform_device *pdev;
- struct resource *res;
- int irq_num;
- int i = 0;
-
- pdev = container_of(vpif_dev, struct platform_device, dev);
-
- while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
- for (irq_num = res->start; irq_num <= res->end; irq_num++)
- free_irq(irq_num,
- (void *)(&vpif_obj.dev[i]->channel_id));
- i++;
- }
-
- platform_driver_unregister(&vpif_driver);
- kfree(vpif_obj.sd);
- for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++)
- kfree(vpif_obj.dev[i]);
-}
-
-module_init(vpif_init);
-module_exit(vpif_cleanup);
diff --git a/drivers/media/video/davinci/vpif_display.h b/drivers/media/video/davinci/vpif_display.h
deleted file mode 100644
index 8967ffb4405..00000000000
--- a/drivers/media/video/davinci/vpif_display.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * VPIF display header file
- *
- * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef DAVINCIHD_DISPLAY_H
-#define DAVINCIHD_DISPLAY_H
-
-/* Header files */
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/videobuf-core.h>
-#include <media/videobuf2-dma-contig.h>
-#include <media/davinci/vpif_types.h>
-
-#include "vpif.h"
-
-/* Macros */
-#define VPIF_DISPLAY_VERSION "0.0.2"
-
-#define VPIF_VALID_FIELD(field) \
- (((V4L2_FIELD_ANY == field) || (V4L2_FIELD_NONE == field)) || \
- (((V4L2_FIELD_INTERLACED == field) || (V4L2_FIELD_SEQ_TB == field)) || \
- (V4L2_FIELD_SEQ_BT == field)))
-
-#define VPIF_DISPLAY_MAX_DEVICES (2)
-#define VPIF_SLICED_BUF_SIZE (256)
-#define VPIF_SLICED_MAX_SERVICES (3)
-#define VPIF_VIDEO_INDEX (0)
-#define VPIF_VBI_INDEX (1)
-#define VPIF_HBI_INDEX (2)
-
-/* Setting it to 1 as HBI/VBI support yet to be added , else 3*/
-#define VPIF_NUMOBJECTS (1)
-
-/* Macros */
-#define ISALIGNED(a) (0 == ((a) & 7))
-
-/* enumerated data types */
-/* Enumerated data type to give id to each device per channel */
-enum vpif_channel_id {
- VPIF_CHANNEL2_VIDEO = 0, /* Channel2 Video */
- VPIF_CHANNEL3_VIDEO, /* Channel3 Video */
-};
-
-/* structures */
-
-struct video_obj {
- enum v4l2_field buf_field;
- u32 latest_only; /* indicate whether to return
- * most recent displayed frame only */
- v4l2_std_id stdid; /* Currently selected or default
- * standard */
- u32 dv_preset;
- struct v4l2_bt_timings bt_timings;
- u32 output_id; /* Current output id */
-};
-
-struct vbi_obj {
- int num_services;
- struct vpif_vbi_params vbiparams; /* vpif parameters for the raw
- * vbi data */
-};
-
-struct vpif_disp_buffer {
- struct vb2_buffer vb;
- struct list_head list;
-};
-
-struct common_obj {
- /* Buffer specific parameters */
- u8 *fbuffers[VIDEO_MAX_FRAME]; /* List of buffer pointers for
- * storing frames */
- u32 numbuffers; /* number of buffers */
- struct vpif_disp_buffer *cur_frm; /* Pointer pointing to current
- * vb2_buffer */
- struct vpif_disp_buffer *next_frm; /* Pointer pointing to next
- * vb2_buffer */
- enum v4l2_memory memory; /* This field keeps track of
- * type of buffer exchange
- * method user has selected */
- struct v4l2_format fmt; /* Used to store the format */
- struct vb2_queue buffer_queue; /* Buffer queue used in
- * video-buf */
- /* allocator-specific contexts for each plane */
- struct vb2_alloc_ctx *alloc_ctx;
-
- struct list_head dma_queue; /* Queue of filled frames */
- spinlock_t irqlock; /* Used in video-buf */
-
- /* channel specific parameters */
- struct mutex lock; /* lock used to access this
- * structure */
- u32 io_usrs; /* number of users performing
- * IO */
- u8 started; /* Indicates whether streaming
- * started */
- u32 ytop_off; /* offset of Y top from the
- * starting of the buffer */
- u32 ybtm_off; /* offset of Y bottom from the
- * starting of the buffer */
- u32 ctop_off; /* offset of C top from the
- * starting of the buffer */
- u32 cbtm_off; /* offset of C bottom from the
- * starting of the buffer */
- /* Function pointer to set the addresses */
- void (*set_addr) (unsigned long, unsigned long,
- unsigned long, unsigned long);
- u32 height;
- u32 width;
-};
-
-struct channel_obj {
- /* V4l2 specific parameters */
- struct video_device *video_dev; /* Identifies video device for
- * this channel */
- struct v4l2_prio_state prio; /* Used to keep track of state of
- * the priority */
- atomic_t usrs; /* number of open instances of
- * the channel */
- u32 field_id; /* Indicates id of the field
- * which is being displayed */
- u8 initialized; /* flag to indicate whether
- * encoder is initialized */
-
- enum vpif_channel_id channel_id;/* Identifies channel */
- struct vpif_params vpifparams;
- struct common_obj common[VPIF_NUMOBJECTS];
- struct video_obj video;
- struct vbi_obj vbi;
-};
-
-/* File handle structure */
-struct vpif_fh {
- struct channel_obj *channel; /* pointer to channel object for
- * opened device */
- u8 io_allowed[VPIF_NUMOBJECTS]; /* Indicates whether this file handle
- * is doing IO */
- enum v4l2_priority prio; /* Used to keep track priority of
- * this instance */
- u8 initialized; /* Used to keep track of whether this
- * file handle has initialized
- * channel or not */
-};
-
-/* vpif device structure */
-struct vpif_device {
- struct v4l2_device v4l2_dev;
- struct channel_obj *dev[VPIF_DISPLAY_NUM_CHANNELS];
- struct v4l2_subdev **sd;
-
-};
-
-struct vpif_config_params {
- u32 min_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
- u32 channel_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
- u8 numbuffers[VPIF_DISPLAY_NUM_CHANNELS];
- u32 video_limit[VPIF_DISPLAY_NUM_CHANNELS];
- u8 min_numbuffers;
-};
-
-/* Struct which keeps track of the line numbers for the sliced vbi service */
-struct vpif_service_line {
- u16 service_id;
- u16 service_line[2];
- u16 enc_service_id;
- u8 bytestowrite;
-};
-
-#endif /* DAVINCIHD_DISPLAY_H */
diff --git a/drivers/media/video/davinci/vpss.c b/drivers/media/video/davinci/vpss.c
deleted file mode 100644
index 3e5cf27ec2b..00000000000
--- a/drivers/media/video/davinci/vpss.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * Copyright (C) 2009 Texas Instruments.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * common vpss system module platform driver for all video drivers.
- */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spinlock.h>
-#include <linux/compiler.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <media/davinci/vpss.h>
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("VPSS Driver");
-MODULE_AUTHOR("Texas Instruments");
-
-/* DM644x defines */
-#define DM644X_SBL_PCR_VPSS (4)
-
-#define DM355_VPSSBL_INTSEL 0x10
-#define DM355_VPSSBL_EVTSEL 0x14
-/* vpss BL register offsets */
-#define DM355_VPSSBL_CCDCMUX 0x1c
-/* vpss CLK register offsets */
-#define DM355_VPSSCLK_CLKCTRL 0x04
-/* masks and shifts */
-#define VPSS_HSSISEL_SHIFT 4
-/*
- * VDINT0 - vpss_int0, VDINT1 - vpss_int1, H3A - vpss_int4,
- * IPIPE_INT1_SDR - vpss_int5
- */
-#define DM355_VPSSBL_INTSEL_DEFAULT 0xff83ff10
-/* VENCINT - vpss_int8 */
-#define DM355_VPSSBL_EVTSEL_DEFAULT 0x4
-
-#define DM365_ISP5_PCCR 0x04
-#define DM365_ISP5_INTSEL1 0x10
-#define DM365_ISP5_INTSEL2 0x14
-#define DM365_ISP5_INTSEL3 0x18
-#define DM365_ISP5_CCDCMUX 0x20
-#define DM365_ISP5_PG_FRAME_SIZE 0x28
-#define DM365_VPBE_CLK_CTRL 0x00
-/*
- * vpss interrupts. VDINT0 - vpss_int0, VDINT1 - vpss_int1,
- * AF - vpss_int3
- */
-#define DM365_ISP5_INTSEL1_DEFAULT 0x0b1f0100
-/* AEW - vpss_int6, RSZ_INT_DMA - vpss_int5 */
-#define DM365_ISP5_INTSEL2_DEFAULT 0x1f0a0f1f
-/* VENC - vpss_int8 */
-#define DM365_ISP5_INTSEL3_DEFAULT 0x00000015
-
-/* masks and shifts for DM365*/
-#define DM365_CCDC_PG_VD_POL_SHIFT 0
-#define DM365_CCDC_PG_HD_POL_SHIFT 1
-
-#define CCD_SRC_SEL_MASK (BIT_MASK(5) | BIT_MASK(4))
-#define CCD_SRC_SEL_SHIFT 4
-
-/* Different SoC platforms supported by this driver */
-enum vpss_platform_type {
- DM644X,
- DM355,
- DM365,
-};
-
-/*
- * vpss operations. Depends on platform. Not all functions are available
- * on all platforms. The api, first check if a functio is available before
- * invoking it. In the probe, the function ptrs are initialized based on
- * vpss name. vpss name can be "dm355_vpss", "dm644x_vpss" etc.
- */
-struct vpss_hw_ops {
- /* enable clock */
- int (*enable_clock)(enum vpss_clock_sel clock_sel, int en);
- /* select input to ccdc */
- void (*select_ccdc_source)(enum vpss_ccdc_source_sel src_sel);
- /* clear wbl overflow bit */
- int (*clear_wbl_overflow)(enum vpss_wbl_sel wbl_sel);
-};
-
-/* vpss configuration */
-struct vpss_oper_config {
- __iomem void *vpss_regs_base0;
- __iomem void *vpss_regs_base1;
- enum vpss_platform_type platform;
- spinlock_t vpss_lock;
- struct vpss_hw_ops hw_ops;
-};
-
-static struct vpss_oper_config oper_cfg;
-
-/* register access routines */
-static inline u32 bl_regr(u32 offset)
-{
- return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
-}
-
-static inline void bl_regw(u32 val, u32 offset)
-{
- __raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
-}
-
-static inline u32 vpss_regr(u32 offset)
-{
- return __raw_readl(oper_cfg.vpss_regs_base1 + offset);
-}
-
-static inline void vpss_regw(u32 val, u32 offset)
-{
- __raw_writel(val, oper_cfg.vpss_regs_base1 + offset);
-}
-
-/* For DM365 only */
-static inline u32 isp5_read(u32 offset)
-{
- return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
-}
-
-/* For DM365 only */
-static inline void isp5_write(u32 val, u32 offset)
-{
- __raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
-}
-
-static void dm365_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
-{
- u32 temp = isp5_read(DM365_ISP5_CCDCMUX) & ~CCD_SRC_SEL_MASK;
-
- /* if we are using pattern generator, enable it */
- if (src_sel == VPSS_PGLPBK || src_sel == VPSS_CCDCPG)
- temp |= 0x08;
-
- temp |= (src_sel << CCD_SRC_SEL_SHIFT);
- isp5_write(temp, DM365_ISP5_CCDCMUX);
-}
-
-static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
-{
- bl_regw(src_sel << VPSS_HSSISEL_SHIFT, DM355_VPSSBL_CCDCMUX);
-}
-
-int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
-{
- if (!oper_cfg.hw_ops.select_ccdc_source)
- return -EINVAL;
-
- oper_cfg.hw_ops.select_ccdc_source(src_sel);
- return 0;
-}
-EXPORT_SYMBOL(vpss_select_ccdc_source);
-
-static int dm644x_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
-{
- u32 mask = 1, val;
-
- if (wbl_sel < VPSS_PCR_AEW_WBL_0 ||
- wbl_sel > VPSS_PCR_CCDC_WBL_O)
- return -EINVAL;
-
- /* writing a 0 clear the overflow */
- mask = ~(mask << wbl_sel);
- val = bl_regr(DM644X_SBL_PCR_VPSS) & mask;
- bl_regw(val, DM644X_SBL_PCR_VPSS);
- return 0;
-}
-
-int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
-{
- if (!oper_cfg.hw_ops.clear_wbl_overflow)
- return -EINVAL;
-
- return oper_cfg.hw_ops.clear_wbl_overflow(wbl_sel);
-}
-EXPORT_SYMBOL(vpss_clear_wbl_overflow);
-
-/*
- * dm355_enable_clock - Enable VPSS Clock
- * @clock_sel: CLock to be enabled/disabled
- * @en: enable/disable flag
- *
- * This is called to enable or disable a vpss clock
- */
-static int dm355_enable_clock(enum vpss_clock_sel clock_sel, int en)
-{
- unsigned long flags;
- u32 utemp, mask = 0x1, shift = 0;
-
- switch (clock_sel) {
- case VPSS_VPBE_CLOCK:
- /* nothing since lsb */
- break;
- case VPSS_VENC_CLOCK_SEL:
- shift = 2;
- break;
- case VPSS_CFALD_CLOCK:
- shift = 3;
- break;
- case VPSS_H3A_CLOCK:
- shift = 4;
- break;
- case VPSS_IPIPE_CLOCK:
- shift = 5;
- break;
- case VPSS_CCDC_CLOCK:
- shift = 6;
- break;
- default:
- printk(KERN_ERR "dm355_enable_clock:"
- " Invalid selector: %d\n", clock_sel);
- return -EINVAL;
- }
-
- spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
- utemp = vpss_regr(DM355_VPSSCLK_CLKCTRL);
- if (!en)
- utemp &= ~(mask << shift);
- else
- utemp |= (mask << shift);
-
- vpss_regw(utemp, DM355_VPSSCLK_CLKCTRL);
- spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
- return 0;
-}
-
-static int dm365_enable_clock(enum vpss_clock_sel clock_sel, int en)
-{
- unsigned long flags;
- u32 utemp, mask = 0x1, shift = 0, offset = DM365_ISP5_PCCR;
- u32 (*read)(u32 offset) = isp5_read;
- void(*write)(u32 val, u32 offset) = isp5_write;
-
- switch (clock_sel) {
- case VPSS_BL_CLOCK:
- break;
- case VPSS_CCDC_CLOCK:
- shift = 1;
- break;
- case VPSS_H3A_CLOCK:
- shift = 2;
- break;
- case VPSS_RSZ_CLOCK:
- shift = 3;
- break;
- case VPSS_IPIPE_CLOCK:
- shift = 4;
- break;
- case VPSS_IPIPEIF_CLOCK:
- shift = 5;
- break;
- case VPSS_PCLK_INTERNAL:
- shift = 6;
- break;
- case VPSS_PSYNC_CLOCK_SEL:
- shift = 7;
- break;
- case VPSS_VPBE_CLOCK:
- read = vpss_regr;
- write = vpss_regw;
- offset = DM365_VPBE_CLK_CTRL;
- break;
- case VPSS_VENC_CLOCK_SEL:
- shift = 2;
- read = vpss_regr;
- write = vpss_regw;
- offset = DM365_VPBE_CLK_CTRL;
- break;
- case VPSS_LDC_CLOCK:
- shift = 3;
- read = vpss_regr;
- write = vpss_regw;
- offset = DM365_VPBE_CLK_CTRL;
- break;
- case VPSS_FDIF_CLOCK:
- shift = 4;
- read = vpss_regr;
- write = vpss_regw;
- offset = DM365_VPBE_CLK_CTRL;
- break;
- case VPSS_OSD_CLOCK_SEL:
- shift = 6;
- read = vpss_regr;
- write = vpss_regw;
- offset = DM365_VPBE_CLK_CTRL;
- break;
- case VPSS_LDC_CLOCK_SEL:
- shift = 7;
- read = vpss_regr;
- write = vpss_regw;
- offset = DM365_VPBE_CLK_CTRL;
- break;
- default:
- printk(KERN_ERR "dm365_enable_clock: Invalid selector: %d\n",
- clock_sel);
- return -1;
- }
-
- spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
- utemp = read(offset);
- if (!en) {
- mask = ~mask;
- utemp &= (mask << shift);
- } else
- utemp |= (mask << shift);
-
- write(utemp, offset);
- spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
-
- return 0;
-}
-
-int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en)
-{
- if (!oper_cfg.hw_ops.enable_clock)
- return -EINVAL;
-
- return oper_cfg.hw_ops.enable_clock(clock_sel, en);
-}
-EXPORT_SYMBOL(vpss_enable_clock);
-
-void dm365_vpss_set_sync_pol(struct vpss_sync_pol sync)
-{
- int val = 0;
- val = isp5_read(DM365_ISP5_CCDCMUX);
-
- val |= (sync.ccdpg_hdpol << DM365_CCDC_PG_HD_POL_SHIFT);
- val |= (sync.ccdpg_vdpol << DM365_CCDC_PG_VD_POL_SHIFT);
-
- isp5_write(val, DM365_ISP5_CCDCMUX);
-}
-EXPORT_SYMBOL(dm365_vpss_set_sync_pol);
-
-void dm365_vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size)
-{
- int current_reg = ((frame_size.hlpfr >> 1) - 1) << 16;
-
- current_reg |= (frame_size.pplen - 1);
- isp5_write(current_reg, DM365_ISP5_PG_FRAME_SIZE);
-}
-EXPORT_SYMBOL(dm365_vpss_set_pg_frame_size);
-
-static int __init vpss_probe(struct platform_device *pdev)
-{
- struct resource *r1, *r2;
- char *platform_name;
- int status;
-
- if (!pdev->dev.platform_data) {
- dev_err(&pdev->dev, "no platform data\n");
- return -ENOENT;
- }
-
- platform_name = pdev->dev.platform_data;
- if (!strcmp(platform_name, "dm355_vpss"))
- oper_cfg.platform = DM355;
- else if (!strcmp(platform_name, "dm365_vpss"))
- oper_cfg.platform = DM365;
- else if (!strcmp(platform_name, "dm644x_vpss"))
- oper_cfg.platform = DM644X;
- else {
- dev_err(&pdev->dev, "vpss driver not supported on"
- " this platform\n");
- return -ENODEV;
- }
-
- dev_info(&pdev->dev, "%s vpss probed\n", platform_name);
- r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r1)
- return -ENOENT;
-
- r1 = request_mem_region(r1->start, resource_size(r1), r1->name);
- if (!r1)
- return -EBUSY;
-
- oper_cfg.vpss_regs_base0 = ioremap(r1->start, resource_size(r1));
- if (!oper_cfg.vpss_regs_base0) {
- status = -EBUSY;
- goto fail1;
- }
-
- if (oper_cfg.platform == DM355 || oper_cfg.platform == DM365) {
- r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!r2) {
- status = -ENOENT;
- goto fail2;
- }
- r2 = request_mem_region(r2->start, resource_size(r2), r2->name);
- if (!r2) {
- status = -EBUSY;
- goto fail2;
- }
-
- oper_cfg.vpss_regs_base1 = ioremap(r2->start,
- resource_size(r2));
- if (!oper_cfg.vpss_regs_base1) {
- status = -EBUSY;
- goto fail3;
- }
- }
-
- if (oper_cfg.platform == DM355) {
- oper_cfg.hw_ops.enable_clock = dm355_enable_clock;
- oper_cfg.hw_ops.select_ccdc_source = dm355_select_ccdc_source;
- /* Setup vpss interrupts */
- bl_regw(DM355_VPSSBL_INTSEL_DEFAULT, DM355_VPSSBL_INTSEL);
- bl_regw(DM355_VPSSBL_EVTSEL_DEFAULT, DM355_VPSSBL_EVTSEL);
- } else if (oper_cfg.platform == DM365) {
- oper_cfg.hw_ops.enable_clock = dm365_enable_clock;
- oper_cfg.hw_ops.select_ccdc_source = dm365_select_ccdc_source;
- /* Setup vpss interrupts */
- isp5_write(DM365_ISP5_INTSEL1_DEFAULT, DM365_ISP5_INTSEL1);
- isp5_write(DM365_ISP5_INTSEL2_DEFAULT, DM365_ISP5_INTSEL2);
- isp5_write(DM365_ISP5_INTSEL3_DEFAULT, DM365_ISP5_INTSEL3);
- } else
- oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow;
-
- spin_lock_init(&oper_cfg.vpss_lock);
- dev_info(&pdev->dev, "%s vpss probe success\n", platform_name);
- return 0;
-
-fail3:
- release_mem_region(r2->start, resource_size(r2));
-fail2:
- iounmap(oper_cfg.vpss_regs_base0);
-fail1:
- release_mem_region(r1->start, resource_size(r1));
- return status;
-}
-
-static int __devexit vpss_remove(struct platform_device *pdev)
-{
- struct resource *res;
-
- iounmap(oper_cfg.vpss_regs_base0);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, resource_size(res));
- if (oper_cfg.platform == DM355 || oper_cfg.platform == DM365) {
- iounmap(oper_cfg.vpss_regs_base1);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- release_mem_region(res->start, resource_size(res));
- }
- return 0;
-}
-
-static struct platform_driver vpss_driver = {
- .driver = {
- .name = "vpss",
- .owner = THIS_MODULE,
- },
- .remove = __devexit_p(vpss_remove),
- .probe = vpss_probe,
-};
-
-static void vpss_exit(void)
-{
- platform_driver_unregister(&vpss_driver);
-}
-
-static int __init vpss_init(void)
-{
- return platform_driver_register(&vpss_driver);
-}
-subsys_initcall(vpss_init);
-module_exit(vpss_exit);
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
deleted file mode 100644
index 928ef0d0429..00000000000
--- a/drivers/media/video/em28xx/Kconfig
+++ /dev/null
@@ -1,58 +0,0 @@
-config VIDEO_EM28XX
- tristate "Empia EM28xx USB video capture support"
- depends on VIDEO_DEV && I2C
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- select VIDEOBUF_VMALLOC
- select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_MT9V011 if VIDEO_HELPER_CHIPS_AUTO
-
- ---help---
- This is a video4linux driver for Empia 28xx based TV cards.
-
- To compile this driver as a module, choose M here: the
- module will be called em28xx
-
-config VIDEO_EM28XX_ALSA
- depends on VIDEO_EM28XX && SND
- select SND_PCM
- tristate "Empia EM28xx ALSA audio module"
- ---help---
- This is an ALSA driver for some Empia 28xx based TV cards.
-
- This is not required for em2800/em2820/em2821 boards. However,
- newer em28xx devices uses Vendor Class for audio, instead of
- implementing the USB Audio Class. For those chips, this module
- will enable digital audio.
-
- To compile this driver as a module, choose M here: the
- module will be called em28xx-alsa
-
-config VIDEO_EM28XX_DVB
- tristate "DVB/ATSC Support for em28xx based TV cards"
- depends on VIDEO_EM28XX && DVB_CORE
- select DVB_LGDT330X if !DVB_FE_CUSTOMISE
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select DVB_TDA10023 if !DVB_FE_CUSTOMISE
- select DVB_S921 if !DVB_FE_CUSTOMISE
- select DVB_DRXD if !DVB_FE_CUSTOMISE
- select DVB_CXD2820R if !DVB_FE_CUSTOMISE
- select DVB_DRXK if !DVB_FE_CUSTOMISE
- select DVB_TDA18271C2DD if !DVB_FE_CUSTOMISE
- select DVB_TDA10071 if !DVB_FE_CUSTOMISE
- select DVB_A8293 if !DVB_FE_CUSTOMISE
- select VIDEOBUF_DVB
- ---help---
- This adds support for DVB cards based on the
- Empiatech em28xx chips.
-
-config VIDEO_EM28XX_RC
- tristate "EM28XX Remote Controller support"
- depends on RC_CORE
- depends on VIDEO_EM28XX
- depends on !(RC_CORE=m && VIDEO_EM28XX=y)
- default VIDEO_EM28XX
- ---help---
- Enables Remote Controller support on em28xx driver.
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile
deleted file mode 100644
index c8b338d4be0..00000000000
--- a/drivers/media/video/em28xx/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-em28xx-y := em28xx-video.o em28xx-i2c.o em28xx-cards.o
-em28xx-y += em28xx-core.o em28xx-vbi.o
-
-em28xx-alsa-objs := em28xx-audio.o
-em28xx-rc-objs := em28xx-input.o
-
-obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o
-obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o
-obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o
-obj-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-rc.o
-
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
deleted file mode 100644
index 07dc594e79f..00000000000
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ /dev/null
@@ -1,752 +0,0 @@
-/*
- * Empiatech em28x1 audio extension
- *
- * Copyright (C) 2006 Markus Rechberger <mrechberger@gmail.com>
- *
- * Copyright (C) 2007-2011 Mauro Carvalho Chehab <mchehab@redhat.com>
- * - Port to work with the in-kernel driver
- * - Cleanups, fixes, alsa-controls, etc.
- *
- * This driver is based on my previous au600 usb pstn audio driver
- * and inherits all the copyrights
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/usb.h>
-#include <linux/init.h>
-#include <linux/sound.h>
-#include <linux/spinlock.h>
-#include <linux/soundcard.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/proc_fs.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/info.h>
-#include <sound/initval.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/ac97_codec.h>
-#include <media/v4l2-common.h>
-#include "em28xx.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "activates debug info");
-
-#define dprintk(fmt, arg...) do { \
- if (debug) \
- printk(KERN_INFO "em28xx-audio %s: " fmt, \
- __func__, ##arg); \
- } while (0)
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-
-static int em28xx_deinit_isoc_audio(struct em28xx *dev)
-{
- int i;
-
- dprintk("Stopping isoc\n");
- for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
- if (!irqs_disabled())
- usb_kill_urb(dev->adev.urb[i]);
- else
- usb_unlink_urb(dev->adev.urb[i]);
-
- usb_free_urb(dev->adev.urb[i]);
- dev->adev.urb[i] = NULL;
-
- kfree(dev->adev.transfer_buffer[i]);
- dev->adev.transfer_buffer[i] = NULL;
- }
-
- return 0;
-}
-
-static void em28xx_audio_isocirq(struct urb *urb)
-{
- struct em28xx *dev = urb->context;
- int i;
- unsigned int oldptr;
- int period_elapsed = 0;
- int status;
- unsigned char *cp;
- unsigned int stride;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
-
- switch (urb->status) {
- case 0: /* success */
- case -ETIMEDOUT: /* NAK */
- break;
- case -ECONNRESET: /* kill */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- default: /* error */
- dprintk("urb completition error %d.\n", urb->status);
- break;
- }
-
- if (atomic_read(&dev->stream_started) == 0)
- return;
-
- if (dev->adev.capture_pcm_substream) {
- substream = dev->adev.capture_pcm_substream;
- runtime = substream->runtime;
- stride = runtime->frame_bits >> 3;
-
- for (i = 0; i < urb->number_of_packets; i++) {
- int length =
- urb->iso_frame_desc[i].actual_length / stride;
- cp = (unsigned char *)urb->transfer_buffer +
- urb->iso_frame_desc[i].offset;
-
- if (!length)
- continue;
-
- oldptr = dev->adev.hwptr_done_capture;
- if (oldptr + length >= runtime->buffer_size) {
- unsigned int cnt =
- runtime->buffer_size - oldptr;
- memcpy(runtime->dma_area + oldptr * stride, cp,
- cnt * stride);
- memcpy(runtime->dma_area, cp + cnt * stride,
- length * stride - cnt * stride);
- } else {
- memcpy(runtime->dma_area + oldptr * stride, cp,
- length * stride);
- }
-
- snd_pcm_stream_lock(substream);
-
- dev->adev.hwptr_done_capture += length;
- if (dev->adev.hwptr_done_capture >=
- runtime->buffer_size)
- dev->adev.hwptr_done_capture -=
- runtime->buffer_size;
-
- dev->adev.capture_transfer_done += length;
- if (dev->adev.capture_transfer_done >=
- runtime->period_size) {
- dev->adev.capture_transfer_done -=
- runtime->period_size;
- period_elapsed = 1;
- }
-
- snd_pcm_stream_unlock(substream);
- }
- if (period_elapsed)
- snd_pcm_period_elapsed(substream);
- }
- urb->status = 0;
-
- status = usb_submit_urb(urb, GFP_ATOMIC);
- if (status < 0) {
- em28xx_errdev("resubmit of audio urb failed (error=%i)\n",
- status);
- }
- return;
-}
-
-static int em28xx_init_audio_isoc(struct em28xx *dev)
-{
- int i, errCode;
- const int sb_size = EM28XX_NUM_AUDIO_PACKETS *
- EM28XX_AUDIO_MAX_PACKET_SIZE;
-
- dprintk("Starting isoc transfers\n");
-
- for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
- struct urb *urb;
- int j, k;
-
- dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC);
- if (!dev->adev.transfer_buffer[i])
- return -ENOMEM;
-
- memset(dev->adev.transfer_buffer[i], 0x80, sb_size);
- urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC);
- if (!urb) {
- em28xx_errdev("usb_alloc_urb failed!\n");
- for (j = 0; j < i; j++) {
- usb_free_urb(dev->adev.urb[j]);
- kfree(dev->adev.transfer_buffer[j]);
- }
- return -ENOMEM;
- }
-
- urb->dev = dev->udev;
- urb->context = dev;
- urb->pipe = usb_rcvisocpipe(dev->udev, EM28XX_EP_AUDIO);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = dev->adev.transfer_buffer[i];
- urb->interval = 1;
- urb->complete = em28xx_audio_isocirq;
- urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS;
- urb->transfer_buffer_length = sb_size;
-
- for (j = k = 0; j < EM28XX_NUM_AUDIO_PACKETS;
- j++, k += EM28XX_AUDIO_MAX_PACKET_SIZE) {
- urb->iso_frame_desc[j].offset = k;
- urb->iso_frame_desc[j].length =
- EM28XX_AUDIO_MAX_PACKET_SIZE;
- }
- dev->adev.urb[i] = urb;
- }
-
- for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
- errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
- if (errCode) {
- em28xx_errdev("submit of audio urb failed\n");
- em28xx_deinit_isoc_audio(dev);
- atomic_set(&dev->stream_started, 0);
- return errCode;
- }
-
- }
-
- return 0;
-}
-
-static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
- size_t size)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
-
- dprintk("Allocating vbuffer\n");
- if (runtime->dma_area) {
- if (runtime->dma_bytes > size)
- return 0;
-
- vfree(runtime->dma_area);
- }
- runtime->dma_area = vmalloc(size);
- if (!runtime->dma_area)
- return -ENOMEM;
-
- runtime->dma_bytes = size;
-
- return 0;
-}
-
-static struct snd_pcm_hardware snd_em28xx_hw_capture = {
- .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BATCH |
- SNDRV_PCM_INFO_MMAP_VALID,
-
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
-
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT,
-
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */
- .period_bytes_min = 64, /* 12544/2, */
- .period_bytes_max = 12544,
- .periods_min = 2,
- .periods_max = 98, /* 12544, */
-};
-
-static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
-{
- struct em28xx *dev = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int ret = 0;
-
- dprintk("opening device and trying to acquire exclusive lock\n");
-
- if (!dev) {
- em28xx_err("BUG: em28xx can't find device struct."
- " Can't proceed with open\n");
- return -ENODEV;
- }
-
- runtime->hw = snd_em28xx_hw_capture;
- if ((dev->alt == 0 || dev->audio_ifnum) && dev->adev.users == 0) {
- if (dev->audio_ifnum)
- dev->alt = 1;
- else
- dev->alt = 7;
-
- dprintk("changing alternate number on interface %d to %d\n",
- dev->audio_ifnum, dev->alt);
- usb_set_interface(dev->udev, dev->audio_ifnum, dev->alt);
-
- /* Sets volume, mute, etc */
- dev->mute = 0;
- mutex_lock(&dev->lock);
- ret = em28xx_audio_analog_set(dev);
- if (ret < 0)
- goto err;
-
- dev->adev.users++;
- mutex_unlock(&dev->lock);
- }
-
- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- dev->adev.capture_pcm_substream = substream;
- runtime->private_data = dev;
-
- return 0;
-err:
- mutex_unlock(&dev->lock);
-
- em28xx_err("Error while configuring em28xx mixer\n");
- return ret;
-}
-
-static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
-{
- struct em28xx *dev = snd_pcm_substream_chip(substream);
-
- dprintk("closing device\n");
-
- dev->mute = 1;
- mutex_lock(&dev->lock);
- dev->adev.users--;
- if (atomic_read(&dev->stream_started) > 0) {
- atomic_set(&dev->stream_started, 0);
- schedule_work(&dev->wq_trigger);
- }
-
- em28xx_audio_analog_set(dev);
- if (substream->runtime->dma_area) {
- dprintk("freeing\n");
- vfree(substream->runtime->dma_area);
- substream->runtime->dma_area = NULL;
- }
- mutex_unlock(&dev->lock);
-
- return 0;
-}
-
-static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- int ret;
-
- dprintk("Setting capture parameters\n");
-
- ret = snd_pcm_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(hw_params));
- if (ret < 0)
- return ret;
-#if 0
- /* TODO: set up em28xx audio chip to deliver the correct audio format,
- current default is 48000hz multiplexed => 96000hz mono
- which shouldn't matter since analogue TV only supports mono */
- unsigned int channels, rate, format;
-
- format = params_format(hw_params);
- rate = params_rate(hw_params);
- channels = params_channels(hw_params);
-#endif
-
- return 0;
-}
-
-static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream)
-{
- struct em28xx *dev = snd_pcm_substream_chip(substream);
-
- dprintk("Stop capture, if needed\n");
-
- if (atomic_read(&dev->stream_started) > 0) {
- atomic_set(&dev->stream_started, 0);
- schedule_work(&dev->wq_trigger);
- }
-
- return 0;
-}
-
-static int snd_em28xx_prepare(struct snd_pcm_substream *substream)
-{
- struct em28xx *dev = snd_pcm_substream_chip(substream);
-
- dev->adev.hwptr_done_capture = 0;
- dev->adev.capture_transfer_done = 0;
-
- return 0;
-}
-
-static void audio_trigger(struct work_struct *work)
-{
- struct em28xx *dev = container_of(work, struct em28xx, wq_trigger);
-
- if (atomic_read(&dev->stream_started)) {
- dprintk("starting capture");
- em28xx_init_audio_isoc(dev);
- } else {
- dprintk("stopping capture");
- em28xx_deinit_isoc_audio(dev);
- }
-}
-
-static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct em28xx *dev = snd_pcm_substream_chip(substream);
- int retval = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
- case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
- case SNDRV_PCM_TRIGGER_START:
- atomic_set(&dev->stream_started, 1);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
- case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
- case SNDRV_PCM_TRIGGER_STOP:
- atomic_set(&dev->stream_started, 0);
- break;
- default:
- retval = -EINVAL;
- }
- schedule_work(&dev->wq_trigger);
- return retval;
-}
-
-static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
- *substream)
-{
- unsigned long flags;
- struct em28xx *dev;
- snd_pcm_uframes_t hwptr_done;
-
- dev = snd_pcm_substream_chip(substream);
- spin_lock_irqsave(&dev->adev.slock, flags);
- hwptr_done = dev->adev.hwptr_done_capture;
- spin_unlock_irqrestore(&dev->adev.slock, flags);
-
- return hwptr_done;
-}
-
-static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
- unsigned long offset)
-{
- void *pageptr = subs->runtime->dma_area + offset;
-
- return vmalloc_to_page(pageptr);
-}
-
-/*
- * AC97 volume control support
- */
-static int em28xx_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *info)
-{
- info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- info->count = 2;
- info->value.integer.min = 0;
- info->value.integer.max = 0x1f;
-
- return 0;
-}
-
-static int em28xx_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- struct em28xx *dev = snd_kcontrol_chip(kcontrol);
- u16 val = (0x1f - (value->value.integer.value[0] & 0x1f)) |
- (0x1f - (value->value.integer.value[1] & 0x1f)) << 8;
- int rc;
-
- mutex_lock(&dev->lock);
- rc = em28xx_read_ac97(dev, kcontrol->private_value);
- if (rc < 0)
- goto err;
-
- val |= rc & 0x8000; /* Preserve the mute flag */
-
- rc = em28xx_write_ac97(dev, kcontrol->private_value, val);
- if (rc < 0)
- goto err;
-
- dprintk("%sleft vol %d, right vol %d (0x%04x) to ac97 volume control 0x%04x\n",
- (val & 0x8000) ? "muted " : "",
- 0x1f - ((val >> 8) & 0x1f), 0x1f - (val & 0x1f),
- val, (int)kcontrol->private_value);
-
-err:
- mutex_unlock(&dev->lock);
- return rc;
-}
-
-static int em28xx_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- struct em28xx *dev = snd_kcontrol_chip(kcontrol);
- int val;
-
- mutex_lock(&dev->lock);
- val = em28xx_read_ac97(dev, kcontrol->private_value);
- mutex_unlock(&dev->lock);
- if (val < 0)
- return val;
-
- dprintk("%sleft vol %d, right vol %d (0x%04x) from ac97 volume control 0x%04x\n",
- (val & 0x8000) ? "muted " : "",
- 0x1f - ((val >> 8) & 0x1f), 0x1f - (val & 0x1f),
- val, (int)kcontrol->private_value);
-
- value->value.integer.value[0] = 0x1f - (val & 0x1f);
- value->value.integer.value[1] = 0x1f - ((val << 8) & 0x1f);
-
- return 0;
-}
-
-static int em28xx_vol_put_mute(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- struct em28xx *dev = snd_kcontrol_chip(kcontrol);
- u16 val = value->value.integer.value[0];
- int rc;
-
- mutex_lock(&dev->lock);
- rc = em28xx_read_ac97(dev, kcontrol->private_value);
- if (rc < 0)
- goto err;
-
- if (val)
- rc &= 0x1f1f;
- else
- rc |= 0x8000;
-
- rc = em28xx_write_ac97(dev, kcontrol->private_value, rc);
- if (rc < 0)
- goto err;
-
- dprintk("%sleft vol %d, right vol %d (0x%04x) to ac97 volume control 0x%04x\n",
- (val & 0x8000) ? "muted " : "",
- 0x1f - ((val >> 8) & 0x1f), 0x1f - (val & 0x1f),
- val, (int)kcontrol->private_value);
-
-err:
- mutex_unlock(&dev->lock);
- return rc;
-}
-
-static int em28xx_vol_get_mute(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- struct em28xx *dev = snd_kcontrol_chip(kcontrol);
- int val;
-
- mutex_lock(&dev->lock);
- val = em28xx_read_ac97(dev, kcontrol->private_value);
- mutex_unlock(&dev->lock);
- if (val < 0)
- return val;
-
- if (val & 0x8000)
- value->value.integer.value[0] = 0;
- else
- value->value.integer.value[0] = 1;
-
- dprintk("%sleft vol %d, right vol %d (0x%04x) from ac97 volume control 0x%04x\n",
- (val & 0x8000) ? "muted " : "",
- 0x1f - ((val >> 8) & 0x1f), 0x1f - (val & 0x1f),
- val, (int)kcontrol->private_value);
-
- return 0;
-}
-
-static const DECLARE_TLV_DB_SCALE(em28xx_db_scale, -3450, 150, 0);
-
-static int em28xx_cvol_new(struct snd_card *card, struct em28xx *dev,
- char *name, int id)
-{
- int err;
- char ctl_name[44];
- struct snd_kcontrol *kctl;
- struct snd_kcontrol_new tmp;
-
- memset (&tmp, 0, sizeof(tmp));
- tmp.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- tmp.private_value = id,
- tmp.name = ctl_name,
-
- /* Add Mute Control */
- sprintf(ctl_name, "%s Switch", name);
- tmp.get = em28xx_vol_get_mute;
- tmp.put = em28xx_vol_put_mute;
- tmp.info = snd_ctl_boolean_mono_info;
- kctl = snd_ctl_new1(&tmp, dev);
- err = snd_ctl_add(card, kctl);
- if (err < 0)
- return err;
- dprintk("Added control %s for ac97 volume control 0x%04x\n",
- ctl_name, id);
-
- memset (&tmp, 0, sizeof(tmp));
- tmp.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- tmp.private_value = id,
- tmp.name = ctl_name,
-
- /* Add Volume Control */
- sprintf(ctl_name, "%s Volume", name);
- tmp.get = em28xx_vol_get;
- tmp.put = em28xx_vol_put;
- tmp.info = em28xx_vol_info;
- tmp.tlv.p = em28xx_db_scale,
- kctl = snd_ctl_new1(&tmp, dev);
- err = snd_ctl_add(card, kctl);
- if (err < 0)
- return err;
- dprintk("Added control %s for ac97 volume control 0x%04x\n",
- ctl_name, id);
-
- return 0;
-}
-
-/*
- * register/unregister code and data
- */
-static struct snd_pcm_ops snd_em28xx_pcm_capture = {
- .open = snd_em28xx_capture_open,
- .close = snd_em28xx_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_em28xx_hw_capture_params,
- .hw_free = snd_em28xx_hw_capture_free,
- .prepare = snd_em28xx_prepare,
- .trigger = snd_em28xx_capture_trigger,
- .pointer = snd_em28xx_capture_pointer,
- .page = snd_pcm_get_vmalloc_page,
-};
-
-static int em28xx_audio_init(struct em28xx *dev)
-{
- struct em28xx_audio *adev = &dev->adev;
- struct snd_pcm *pcm;
- struct snd_card *card;
- static int devnr;
- int err;
-
- if (!dev->has_alsa_audio || dev->audio_ifnum < 0) {
- /* This device does not support the extension (in this case
- the device is expecting the snd-usb-audio module or
- doesn't have analog audio support at all) */
- return 0;
- }
-
- printk(KERN_INFO "em28xx-audio.c: probing for em28xx Audio Vendor Class\n");
- printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
- "Rechberger\n");
- printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2007-2011 Mauro Carvalho Chehab\n");
-
- err = snd_card_create(index[devnr], "Em28xx Audio", THIS_MODULE, 0,
- &card);
- if (err < 0)
- return err;
-
- spin_lock_init(&adev->slock);
- err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture);
- pcm->info_flags = 0;
- pcm->private_data = dev;
- strcpy(pcm->name, "Empia 28xx Capture");
-
- snd_card_set_dev(card, &dev->udev->dev);
- strcpy(card->driver, "Em28xx-Audio");
- strcpy(card->shortname, "Em28xx Audio");
- strcpy(card->longname, "Empia Em28xx Audio");
-
- INIT_WORK(&dev->wq_trigger, audio_trigger);
-
- if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
- em28xx_cvol_new(card, dev, "Video", AC97_VIDEO);
- em28xx_cvol_new(card, dev, "Line In", AC97_LINE);
- em28xx_cvol_new(card, dev, "Phone", AC97_PHONE);
- em28xx_cvol_new(card, dev, "Microphone", AC97_MIC);
- em28xx_cvol_new(card, dev, "CD", AC97_CD);
- em28xx_cvol_new(card, dev, "AUX", AC97_AUX);
- em28xx_cvol_new(card, dev, "PCM", AC97_PCM);
-
- em28xx_cvol_new(card, dev, "Master", AC97_MASTER);
- em28xx_cvol_new(card, dev, "Line", AC97_HEADPHONE);
- em28xx_cvol_new(card, dev, "Mono", AC97_MASTER_MONO);
- em28xx_cvol_new(card, dev, "LFE", AC97_CENTER_LFE_MASTER);
- em28xx_cvol_new(card, dev, "Surround", AC97_SURROUND_MASTER);
- }
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- adev->sndcard = card;
- adev->udev = dev->udev;
-
- return 0;
-}
-
-static int em28xx_audio_fini(struct em28xx *dev)
-{
- if (dev == NULL)
- return 0;
-
- if (dev->has_alsa_audio != 1) {
- /* This device does not support the extension (in this case
- the device is expecting the snd-usb-audio module or
- doesn't have analog audio support at all) */
- return 0;
- }
-
- if (dev->adev.sndcard) {
- snd_card_free(dev->adev.sndcard);
- dev->adev.sndcard = NULL;
- }
-
- return 0;
-}
-
-static struct em28xx_ops audio_ops = {
- .id = EM28XX_AUDIO,
- .name = "Em28xx Audio Extension",
- .init = em28xx_audio_init,
- .fini = em28xx_audio_fini,
-};
-
-static int __init em28xx_alsa_register(void)
-{
- return em28xx_register_extension(&audio_ops);
-}
-
-static void __exit em28xx_alsa_unregister(void)
-{
- em28xx_unregister_extension(&audio_ops);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Markus Rechberger <mrechberger@gmail.com>");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
-MODULE_DESCRIPTION("Em28xx Audio driver");
-
-module_init(em28xx_alsa_register);
-module_exit(em28xx_alsa_unregister);
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
deleted file mode 100644
index f7831e73f07..00000000000
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ /dev/null
@@ -1,3417 +0,0 @@
-/*
- em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB
- video capture devices
-
- Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
- Markus Rechberger <mrechberger@gmail.com>
- Mauro Carvalho Chehab <mchehab@infradead.org>
- Sascha Sommer <saschasommer@freenet.de>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/usb.h>
-#include <media/tuner.h>
-#include <media/msp3400.h>
-#include <media/saa7115.h>
-#include <media/tvp5150.h>
-#include <media/tvaudio.h>
-#include <media/mt9v011.h>
-#include <media/i2c-addr.h>
-#include <media/tveeprom.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-
-#include "em28xx.h"
-
-#define DRIVER_NAME "em28xx"
-
-static int tuner = -1;
-module_param(tuner, int, 0444);
-MODULE_PARM_DESC(tuner, "tuner type");
-
-static unsigned int disable_ir;
-module_param(disable_ir, int, 0444);
-MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
-
-static unsigned int disable_usb_speed_check;
-module_param(disable_usb_speed_check, int, 0444);
-MODULE_PARM_DESC(disable_usb_speed_check,
- "override min bandwidth requirement of 480M bps");
-
-static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
-module_param_array(card, int, NULL, 0444);
-MODULE_PARM_DESC(card, "card type");
-
-/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS - 1 */
-static unsigned long em28xx_devused;
-
-struct em28xx_hash_table {
- unsigned long hash;
- unsigned int model;
- unsigned int tuner;
-};
-
-static void em28xx_pre_card_setup(struct em28xx *dev);
-
-/*
- * Reset sequences for analog/digital modes
- */
-
-/* Reset for the most [analog] boards */
-static struct em28xx_reg_seq default_analog[] = {
- {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
- { -1, -1, -1, -1},
-};
-
-/* Reset for the most [digital] boards */
-static struct em28xx_reg_seq default_digital[] = {
- {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
- { -1, -1, -1, -1},
-};
-
-/* Board Hauppauge WinTV HVR 900 analog */
-static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
- {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10},
- {0x05, 0xff, 0x10, 10},
- { -1, -1, -1, -1},
-};
-
-/* Board Hauppauge WinTV HVR 900 digital */
-static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
- {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10},
- {EM2880_R04_GPO, 0x04, 0x0f, 10},
- {EM2880_R04_GPO, 0x0c, 0x0f, 10},
- { -1, -1, -1, -1},
-};
-
-/* Board Hauppauge WinTV HVR 900 (R2) digital */
-static struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = {
- {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10},
- {EM2880_R04_GPO, 0x0c, 0x0f, 10},
- { -1, -1, -1, -1},
-};
-
-/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
-static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
- {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10},
- { -1, -1, -1, -1},
-};
-
-/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
-
-/* Board - EM2870 Kworld 355u
- Analog - No input analog */
-
-/* Board - EM2882 Kworld 315U digital */
-static struct em28xx_reg_seq em2882_kworld_315u_digital[] = {
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- {EM28XX_R08_GPIO, 0xfe, 0xff, 10},
- {EM2880_R04_GPO, 0x04, 0xff, 10},
- {EM2880_R04_GPO, 0x0c, 0xff, 10},
- {EM28XX_R08_GPIO, 0x7e, 0xff, 10},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = {
- {EM2880_R04_GPO, 0x08, 0xff, 10},
- {EM2880_R04_GPO, 0x0c, 0xff, 10},
- {EM2880_R04_GPO, 0x08, 0xff, 10},
- {EM2880_R04_GPO, 0x0c, 0xff, 10},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq kworld_330u_analog[] = {
- {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
- {EM2880_R04_GPO, 0x00, 0xff, 10},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq kworld_330u_digital[] = {
- {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
- {EM2880_R04_GPO, 0x08, 0xff, 10},
- { -1, -1, -1, -1},
-};
-
-/* Evga inDtube
- GPIO0 - Enable digital power (s5h1409) - low to enable
- GPIO1 - Enable analog power (tvp5150/emp202) - low to enable
- GPIO4 - xc3028 reset
- GOP3 - s5h1409 reset
- */
-static struct em28xx_reg_seq evga_indtube_analog[] = {
- {EM28XX_R08_GPIO, 0x79, 0xff, 60},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq evga_indtube_digital[] = {
- {EM28XX_R08_GPIO, 0x7a, 0xff, 1},
- {EM2880_R04_GPO, 0x04, 0xff, 10},
- {EM2880_R04_GPO, 0x0c, 0xff, 1},
- { -1, -1, -1, -1},
-};
-
-/*
- * KWorld PlusTV 340U and UB435-Q (ATSC) GPIOs map:
- * EM_GPIO_0 - currently unknown
- * EM_GPIO_1 - LED disable/enable (1 = off, 0 = on)
- * EM_GPIO_2 - currently unknown
- * EM_GPIO_3 - currently unknown
- * EM_GPIO_4 - TDA18271HD/C1 tuner (1 = active, 0 = in reset)
- * EM_GPIO_5 - LGDT3304 ATSC/QAM demod (1 = active, 0 = in reset)
- * EM_GPIO_6 - currently unknown
- * EM_GPIO_7 - currently unknown
- */
-static struct em28xx_reg_seq kworld_a340_digital[] = {
- {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
- { -1, -1, -1, -1},
-};
-
-/* Pinnacle Hybrid Pro eb1a:2881 */
-static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = {
- {EM28XX_R08_GPIO, 0xfd, ~EM_GPIO_4, 10},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = {
- {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
- {EM2880_R04_GPO, 0x04, 0xff, 100},/* zl10353 reset */
- {EM2880_R04_GPO, 0x0c, 0xff, 1},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = {
- {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
- {EM2880_R04_GPO, 0x00, 0xff, 10},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = {
- {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
- {EM2880_R04_GPO, 0x08, 0xff, 10},
- { -1, -1, -1, -1},
-};
-
-/* eb1a:2868 Reddo DVB-C USB TV Box
- GPIO4 - CU1216L NIM
- Other GPIOs seems to be don't care. */
-static struct em28xx_reg_seq reddo_dvb_c_usb_box[] = {
- {EM28XX_R08_GPIO, 0xfe, 0xff, 10},
- {EM28XX_R08_GPIO, 0xde, 0xff, 10},
- {EM28XX_R08_GPIO, 0xfe, 0xff, 10},
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- {EM28XX_R08_GPIO, 0x7f, 0xff, 10},
- {EM28XX_R08_GPIO, 0x6f, 0xff, 10},
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- {-1, -1, -1, -1},
-};
-
-/* Callback for the most boards */
-static struct em28xx_reg_seq default_tuner_gpio[] = {
- {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
- {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10},
- {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
- { -1, -1, -1, -1},
-};
-
-/* Mute/unmute */
-static struct em28xx_reg_seq compro_unmute_tv_gpio[] = {
- {EM28XX_R08_GPIO, 5, 7, 10},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq compro_unmute_svid_gpio[] = {
- {EM28XX_R08_GPIO, 4, 7, 10},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq compro_mute_gpio[] = {
- {EM28XX_R08_GPIO, 6, 7, 10},
- { -1, -1, -1, -1},
-};
-
-/* Terratec AV350 */
-static struct em28xx_reg_seq terratec_av350_mute_gpio[] = {
- {EM28XX_R08_GPIO, 0xff, 0x7f, 10},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq terratec_av350_unmute_gpio[] = {
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq silvercrest_reg_seq[] = {
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- {EM28XX_R08_GPIO, 0x01, 0xf7, 10},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq vc211a_enable[] = {
- {EM28XX_R08_GPIO, 0xff, 0x07, 10},
- {EM28XX_R08_GPIO, 0xff, 0x0f, 10},
- {EM28XX_R08_GPIO, 0xff, 0x0b, 10},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq dikom_dk300_digital[] = {
- {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
- {EM2880_R04_GPO, 0x08, 0xff, 10},
- { -1, -1, -1, -1},
-};
-
-
-/* Reset for the most [digital] boards */
-static struct em28xx_reg_seq leadership_digital[] = {
- {EM2874_R80_GPIO, 0x70, 0xff, 10},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq leadership_reset[] = {
- {EM2874_R80_GPIO, 0xf0, 0xff, 10},
- {EM2874_R80_GPIO, 0xb0, 0xff, 10},
- {EM2874_R80_GPIO, 0xf0, 0xff, 10},
- { -1, -1, -1, -1},
-};
-
-/* 2013:024f PCTV nanoStick T2 290e
- * GPIO_6 - demod reset
- * GPIO_7 - LED
- */
-static struct em28xx_reg_seq pctv_290e[] = {
- {EM2874_R80_GPIO, 0x00, 0xff, 80},
- {EM2874_R80_GPIO, 0x40, 0xff, 80}, /* GPIO_6 = 1 */
- {EM2874_R80_GPIO, 0xc0, 0xff, 80}, /* GPIO_7 = 1 */
- {-1, -1, -1, -1},
-};
-
-#if 0
-static struct em28xx_reg_seq terratec_h5_gpio[] = {
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- {EM2874_R80_GPIO, 0xf6, 0xff, 100},
- {EM2874_R80_GPIO, 0xf2, 0xff, 50},
- {EM2874_R80_GPIO, 0xf6, 0xff, 50},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq terratec_h5_digital[] = {
- {EM2874_R80_GPIO, 0xf6, 0xff, 10},
- {EM2874_R80_GPIO, 0xe6, 0xff, 100},
- {EM2874_R80_GPIO, 0xa6, 0xff, 10},
- { -1, -1, -1, -1},
-};
-#endif
-
-/* 2013:024f PCTV DVB-S2 Stick 460e
- * GPIO_0 - POWER_ON
- * GPIO_1 - BOOST
- * GPIO_2 - VUV_LNB (red LED)
- * GPIO_3 - EXT_12V
- * GPIO_4 - INT_DEM (DEMOD GPIO_0)
- * GPIO_5 - INT_LNB
- * GPIO_6 - RESET_DEM
- * GPIO_7 - LED (green LED)
- */
-static struct em28xx_reg_seq pctv_460e[] = {
- {EM2874_R80_GPIO, 0x01, 0xff, 50},
- {0x0d, 0xff, 0xff, 50},
- {EM2874_R80_GPIO, 0x41, 0xff, 50}, /* GPIO_6=1 */
- {0x0d, 0x42, 0xff, 50},
- {EM2874_R80_GPIO, 0x61, 0xff, 50}, /* GPIO_5=1 */
- { -1, -1, -1, -1},
-};
-
-#if 0
-static struct em28xx_reg_seq hauppauge_930c_gpio[] = {
- {EM2874_R80_GPIO, 0x6f, 0xff, 10},
- {EM2874_R80_GPIO, 0x4f, 0xff, 10}, /* xc5000 reset */
- {EM2874_R80_GPIO, 0x6f, 0xff, 10},
- {EM2874_R80_GPIO, 0x4f, 0xff, 10},
- { -1, -1, -1, -1},
-};
-
-static struct em28xx_reg_seq hauppauge_930c_digital[] = {
- {EM2874_R80_GPIO, 0xf6, 0xff, 10},
- {EM2874_R80_GPIO, 0xe6, 0xff, 100},
- {EM2874_R80_GPIO, 0xa6, 0xff, 10},
- { -1, -1, -1, -1},
-};
-#endif
-
-/* 1b80:e425 MaxMedia UB425-TC
- * GPIO_6 - demod reset, 0=active
- * GPIO_7 - LED, 0=active
- */
-static struct em28xx_reg_seq maxmedia_ub425_tc[] = {
- {EM2874_R80_GPIO, 0x83, 0xff, 100},
- {EM2874_R80_GPIO, 0xc3, 0xff, 100}, /* GPIO_6 = 1 */
- {EM2874_R80_GPIO, 0x43, 0xff, 000}, /* GPIO_7 = 0 */
- {-1, -1, -1, -1},
-};
-
-/* 2304:0242 PCTV QuatroStick (510e)
- * GPIO_2: decoder reset, 0=active
- * GPIO_4: decoder suspend, 0=active
- * GPIO_6: demod reset, 0=active
- * GPIO_7: LED, 1=active
- */
-static struct em28xx_reg_seq pctv_510e[] = {
- {EM2874_R80_GPIO, 0x10, 0xff, 100},
- {EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
- {EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
- { -1, -1, -1, -1},
-};
-
-/* 2013:0251 PCTV QuatroStick nano (520e)
- * GPIO_2: decoder reset, 0=active
- * GPIO_4: decoder suspend, 0=active
- * GPIO_6: demod reset, 0=active
- * GPIO_7: LED, 1=active
- */
-static struct em28xx_reg_seq pctv_520e[] = {
- {EM2874_R80_GPIO, 0x10, 0xff, 100},
- {EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
- {EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
- {EM2874_R80_GPIO, 0xd4, 0xff, 000}, /* GPIO_7 = 1 */
- { -1, -1, -1, -1},
-};
-
-/*
- * Board definitions
- */
-struct em28xx_board em28xx_boards[] = {
- [EM2750_BOARD_UNKNOWN] = {
- .name = "EM2710/EM2750/EM2751 webcam grabber",
- .xclk = EM28XX_XCLK_FREQUENCY_20MHZ,
- .tuner_type = TUNER_ABSENT,
- .is_webcam = 1,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = silvercrest_reg_seq,
- } },
- },
- [EM2800_BOARD_UNKNOWN] = {
- .name = "Unknown EM2800 video grabber",
- .is_em2800 = 1,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .tuner_type = TUNER_ABSENT,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2820_BOARD_UNKNOWN] = {
- .name = "Unknown EM2750/28xx video grabber",
- .tuner_type = TUNER_ABSENT,
- .is_webcam = 1, /* To enable sensor probe */
- },
- [EM2750_BOARD_DLCW_130] = {
- /* Beijing Huaqi Information Digital Technology Co., Ltd */
- .name = "Huaqi DLCW-130",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .xclk = EM28XX_XCLK_FREQUENCY_48MHZ,
- .tuner_type = TUNER_ABSENT,
- .is_webcam = 1,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
- .amux = EM28XX_AMUX_VIDEO,
- } },
- },
- [EM2820_BOARD_KWORLD_PVRTV2800RF] = {
- .name = "Kworld PVR TV 2800 RF",
- .tuner_type = TUNER_TEMIC_PAL,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2820_BOARD_GADMEI_TVR200] = {
- .name = "Gadmei TVR200",
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2820_BOARD_TERRATEC_CINERGY_250] = {
- .name = "Terratec Cinergy 250 USB",
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .has_ir_i2c = 1,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2820_BOARD_PINNACLE_USB_2] = {
- .name = "Pinnacle PCTV USB 2",
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .has_ir_i2c = 1,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_VIDEO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = {
- .name = "Hauppauge WinTV USB 2",
- .tuner_type = TUNER_PHILIPS_FM1236_MK3,
- .tda9887_conf = TDA9887_PRESENT |
- TDA9887_PORT1_ACTIVE |
- TDA9887_PORT2_ACTIVE,
- .decoder = EM28XX_TVP5150,
- .has_msp34xx = 1,
- .has_ir_i2c = 1,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = MSP_INPUT_DEFAULT,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
- MSP_DSP_IN_SCART, MSP_DSP_IN_SCART),
- } },
- },
- [EM2820_BOARD_DLINK_USB_TV] = {
- .name = "D-Link DUB-T210 TV Tuner",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2820_BOARD_HERCULES_SMART_TV_USB2] = {
- .name = "Hercules Smart TV USB 2.0",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = {
- .name = "Pinnacle PCTV USB 2 (Philips FM1216ME)",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_VIDEO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2820_BOARD_GADMEI_UTV310] = {
- .name = "Gadmei UTV310",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_TNF_5335MF,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = {
- .name = "Leadtek Winfast USB II Deluxe",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .has_ir_i2c = 1,
- .tvaudio_addr = 0x58,
- .tda9887_conf = TDA9887_PRESENT |
- TDA9887_PORT2_ACTIVE |
- TDA9887_QSS,
- .decoder = EM28XX_SAA711X,
- .adecoder = EM28XX_TVAUDIO,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE4,
- .amux = EM28XX_AMUX_AUX,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE5,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- .radio = {
- .type = EM28XX_RADIO,
- .amux = EM28XX_AMUX_AUX,
- }
- },
- [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
- .name = "Videology 20K14XUSB USB2.0",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_ABSENT,
- .is_webcam = 1,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
- .amux = EM28XX_AMUX_VIDEO,
- } },
- },
- [EM2820_BOARD_SILVERCREST_WEBCAM] = {
- .name = "Silvercrest Webcam 1.3mpix",
- .tuner_type = TUNER_ABSENT,
- .is_webcam = 1,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = silvercrest_reg_seq,
- } },
- },
- [EM2821_BOARD_SUPERCOMP_USB_2] = {
- .name = "Supercomp USB 2.0 TV",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_PHILIPS_FM1236_MK3,
- .tda9887_conf = TDA9887_PRESENT |
- TDA9887_PORT1_ACTIVE |
- TDA9887_PORT2_ACTIVE,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2821_BOARD_USBGEAR_VD204] = {
- .name = "Usbgear VD204v9",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_ABSENT, /* Capture only device */
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2860_BOARD_NETGMBH_CAM] = {
- /* Beijing Huaqi Information Digital Technology Co., Ltd */
- .name = "NetGMBH Cam",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_ABSENT,
- .is_webcam = 1,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
- .amux = EM28XX_AMUX_VIDEO,
- } },
- },
- [EM2860_BOARD_TYPHOON_DVD_MAKER] = {
- .name = "Typhoon DVD Maker",
- .decoder = EM28XX_SAA711X,
- .tuner_type = TUNER_ABSENT, /* Capture only device */
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2860_BOARD_GADMEI_UTV330] = {
- .name = "Gadmei UTV330",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_TNF_5335MF,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_VIDEO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2861_BOARD_GADMEI_UTV330PLUS] = {
- .name = "Gadmei UTV330+",
- .tuner_type = TUNER_TNF_5335MF,
- .tda9887_conf = TDA9887_PRESENT,
- .ir_codes = RC_MAP_GADMEI_RM008Z,
- .decoder = EM28XX_SAA711X,
- .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_VIDEO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2860_BOARD_TERRATEC_HYBRID_XS] = {
- .name = "Terratec Cinergy A Hybrid XS",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .decoder = EM28XX_TVP5150,
-
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- } },
- },
- [EM2861_BOARD_KWORLD_PVRTV_300U] = {
- .name = "KWorld PVRTV 300U",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2861_BOARD_YAKUMO_MOVIE_MIXER] = {
- .name = "Yakumo MovieMixer",
- .tuner_type = TUNER_ABSENT, /* Capture only device */
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2860_BOARD_TVP5150_REFERENCE_DESIGN] = {
- .name = "EM2860/TVP5150 Reference Design",
- .tuner_type = TUNER_ABSENT, /* Capture only device */
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2861_BOARD_PLEXTOR_PX_TV100U] = {
- .name = "Plextor ConvertX PX-TV100U",
- .tuner_type = TUNER_TNF_5335MF,
- .xclk = EM28XX_XCLK_I2S_MSB_TIMING |
- EM28XX_XCLK_FREQUENCY_12MHZ,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_TVP5150,
- .has_msp34xx = 1,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = pinnacle_hybrid_pro_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = pinnacle_hybrid_pro_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = pinnacle_hybrid_pro_analog,
- } },
- },
-
- /* Those boards with em2870 are DVB Only*/
-
- [EM2870_BOARD_TERRATEC_XS] = {
- .name = "Terratec Cinergy T XS",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- },
- [EM2870_BOARD_TERRATEC_XS_MT2060] = {
- .name = "Terratec Cinergy T XS (MT2060)",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_ABSENT, /* MT2060 */
- },
- [EM2870_BOARD_KWORLD_350U] = {
- .name = "Kworld 350 U DVB-T",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- },
- [EM2870_BOARD_KWORLD_355U] = {
- .name = "Kworld 355 U DVB-T",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_ABSENT,
- .tuner_gpio = default_tuner_gpio,
- .has_dvb = 1,
- .dvb_gpio = default_digital,
- },
- [EM2870_BOARD_PINNACLE_PCTV_DVB] = {
- .name = "Pinnacle PCTV DVB-T",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_ABSENT, /* MT2060 */
- /* djh - I have serious doubts this is right... */
- .xclk = EM28XX_XCLK_IR_RC5_MODE |
- EM28XX_XCLK_FREQUENCY_10MHZ,
- },
- [EM2870_BOARD_COMPRO_VIDEOMATE] = {
- .name = "Compro, VideoMate U3",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_ABSENT, /* MT2060 */
- },
-
- [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = {
- .name = "Terratec Hybrid XS Secam",
- .has_msp34xx = 1,
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .decoder = EM28XX_TVP5150,
- .has_dvb = 1,
- .dvb_gpio = terratec_cinergy_USB_XS_FR_digital,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = terratec_cinergy_USB_XS_FR_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = terratec_cinergy_USB_XS_FR_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = terratec_cinergy_USB_XS_FR_analog,
- } },
- },
- [EM2884_BOARD_TERRATEC_H5] = {
- .name = "Terratec Cinergy H5",
- .has_dvb = 1,
-#if 0
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .tuner_addr = 0x41,
- .dvb_gpio = terratec_h5_digital, /* FIXME: probably wrong */
- .tuner_gpio = terratec_h5_gpio,
-#else
- .tuner_type = TUNER_ABSENT,
-#endif
- .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
- EM28XX_I2C_CLK_WAIT_ENABLE |
- EM28XX_I2C_FREQ_400_KHZ,
- },
- [EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = {
- .name = "Hauppauge WinTV HVR 930C",
- .has_dvb = 1,
-#if 0 /* FIXME: Add analog support */
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0x41,
- .dvb_gpio = hauppauge_930c_digital,
- .tuner_gpio = hauppauge_930c_gpio,
-#else
- .tuner_type = TUNER_ABSENT,
-#endif
- .ir_codes = RC_MAP_HAUPPAUGE,
- .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
- EM28XX_I2C_CLK_WAIT_ENABLE |
- EM28XX_I2C_FREQ_400_KHZ,
- },
- [EM2884_BOARD_CINERGY_HTC_STICK] = {
- .name = "Terratec Cinergy HTC Stick",
- .has_dvb = 1,
- .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS,
- .tuner_type = TUNER_ABSENT,
- .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
- EM28XX_I2C_CLK_WAIT_ENABLE |
- EM28XX_I2C_FREQ_400_KHZ,
- },
- [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = {
- .name = "Hauppauge WinTV HVR 900",
- .tda9887_conf = TDA9887_PRESENT,
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .mts_firmware = 1,
- .has_dvb = 1,
- .dvb_gpio = hauppauge_wintv_hvr_900_digital,
- .ir_codes = RC_MAP_HAUPPAUGE,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- } },
- },
- [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = {
- .name = "Hauppauge WinTV HVR 900 (R2)",
- .tda9887_conf = TDA9887_PRESENT,
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .mts_firmware = 1,
- .has_dvb = 1,
- .dvb_gpio = hauppauge_wintv_hvr_900R2_digital,
- .ir_codes = RC_MAP_HAUPPAUGE,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- } },
- },
- [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850] = {
- .name = "Hauppauge WinTV HVR 850",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .mts_firmware = 1,
- .has_dvb = 1,
- .dvb_gpio = hauppauge_wintv_hvr_900_digital,
- .ir_codes = RC_MAP_HAUPPAUGE,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- } },
- },
- [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
- .name = "Hauppauge WinTV HVR 950",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .mts_firmware = 1,
- .has_dvb = 1,
- .dvb_gpio = hauppauge_wintv_hvr_900_digital,
- .ir_codes = RC_MAP_HAUPPAUGE,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- } },
- },
- [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = {
- .name = "Pinnacle PCTV HD Pro Stick",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .mts_firmware = 1,
- .has_dvb = 1,
- .dvb_gpio = hauppauge_wintv_hvr_900_digital,
- .ir_codes = RC_MAP_PINNACLE_PCTV_HD,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- } },
- },
- [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = {
- .name = "AMD ATI TV Wonder HD 600",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .mts_firmware = 1,
- .has_dvb = 1,
- .dvb_gpio = hauppauge_wintv_hvr_900_digital,
- .ir_codes = RC_MAP_ATI_TV_WONDER_HD_600,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- } },
- },
- [EM2880_BOARD_TERRATEC_HYBRID_XS] = {
- .name = "Terratec Hybrid XS",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .decoder = EM28XX_TVP5150,
- .has_dvb = 1,
- .dvb_gpio = default_digital,
- .ir_codes = RC_MAP_TERRATEC_CINERGY_XS,
- .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = default_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = default_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = default_analog,
- } },
- },
- /* maybe there's a reason behind it why Terratec sells the Hybrid XS
- as Prodigy XS with a different PID, let's keep it separated for now
- maybe we'll need it lateron */
- [EM2880_BOARD_TERRATEC_PRODIGY_XS] = {
- .name = "Terratec Prodigy XS",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- } },
- },
- [EM2820_BOARD_MSI_VOX_USB_2] = {
- .name = "MSI VOX USB 2.0",
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .tda9887_conf = TDA9887_PRESENT |
- TDA9887_PORT1_ACTIVE |
- TDA9887_PORT2_ACTIVE,
- .max_range_640_480 = 1,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE4,
- .amux = EM28XX_AMUX_VIDEO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2800_BOARD_TERRATEC_CINERGY_200] = {
- .name = "Terratec Cinergy 200 USB",
- .is_em2800 = 1,
- .has_ir_i2c = 1,
- .tuner_type = TUNER_LG_TALN,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_VIDEO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2800_BOARD_GRABBEEX_USB2800] = {
- .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
- .is_em2800 = 1,
- .decoder = EM28XX_SAA711X,
- .tuner_type = TUNER_ABSENT, /* capture only board */
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2800_BOARD_VC211A] = {
- .name = "Actionmaster/LinXcel/Digitus VC211A",
- .is_em2800 = 1,
- .tuner_type = TUNER_ABSENT, /* Capture-only board */
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = vc211a_enable,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = vc211a_enable,
- } },
- },
- [EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
- .name = "Leadtek Winfast USB II",
- .is_em2800 = 1,
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_VIDEO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2800_BOARD_KWORLD_USB2800] = {
- .name = "Kworld USB2800",
- .is_em2800 = 1,
- .tuner_type = TUNER_PHILIPS_FCV1236D,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_VIDEO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2820_BOARD_PINNACLE_DVC_90] = {
- .name = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker "
- "/ Kworld DVD Maker 2 / Plextor ConvertX PX-AV100U",
- .tuner_type = TUNER_ABSENT, /* capture only board */
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2800_BOARD_VGEAR_POCKETTV] = {
- .name = "V-Gear PocketTV",
- .is_em2800 = 1,
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_VIDEO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2] = {
- .name = "Pixelview PlayTV Box 4 USB 2.0",
- .tda9887_conf = TDA9887_PRESENT,
- .tuner_type = TUNER_YMEC_TVF_5533MF,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_VIDEO,
- .aout = EM28XX_AOUT_MONO | /* I2S */
- EM28XX_AOUT_MASTER, /* Line out pin */
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2820_BOARD_PROLINK_PLAYTV_USB2] = {
- .name = "SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0",
- .has_snapshot_button = 1,
- .tda9887_conf = TDA9887_PRESENT,
- .tuner_type = TUNER_YMEC_TVF_5533MF,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_VIDEO,
- .aout = EM28XX_AOUT_MONO | /* I2S */
- EM28XX_AOUT_MASTER, /* Line out pin */
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2860_BOARD_SAA711X_REFERENCE_DESIGN] = {
- .name = "EM2860/SAA711X Reference Design",
- .has_snapshot_button = 1,
- .tuner_type = TUNER_ABSENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- } },
- },
-
- [EM2874_BOARD_LEADERSHIP_ISDBT] = {
- .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
- EM28XX_I2C_CLK_WAIT_ENABLE |
- EM28XX_I2C_FREQ_100_KHZ,
- .xclk = EM28XX_XCLK_FREQUENCY_10MHZ,
- .name = "EM2874 Leadership ISDBT",
- .tuner_type = TUNER_ABSENT,
- .tuner_gpio = leadership_reset,
- .dvb_gpio = leadership_digital,
- .has_dvb = 1,
- },
-
- [EM2880_BOARD_MSI_DIGIVOX_AD] = {
- .name = "MSI DigiVox A/D",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = em2880_msi_digivox_ad_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = em2880_msi_digivox_ad_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = em2880_msi_digivox_ad_analog,
- } },
- },
- [EM2880_BOARD_MSI_DIGIVOX_AD_II] = {
- .name = "MSI DigiVox A/D II",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = em2880_msi_digivox_ad_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = em2880_msi_digivox_ad_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = em2880_msi_digivox_ad_analog,
- } },
- },
- [EM2880_BOARD_KWORLD_DVB_305U] = {
- .name = "KWorld DVB-T 305U",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2880_BOARD_KWORLD_DVB_310U] = {
- .name = "KWorld DVB-T 310U",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .has_dvb = 1,
- .dvb_gpio = default_digital,
- .mts_firmware = 1,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = default_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = default_analog,
- }, { /* S-video has not been tested yet */
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = default_analog,
- } },
- },
- [EM2882_BOARD_KWORLD_ATSC_315U] = {
- .name = "KWorld ATSC 315U HDTV TV Box",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_THOMSON_DTT761X,
- .tuner_gpio = em2882_kworld_315u_tuner_gpio,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_SAA711X,
- .has_dvb = 1,
- .dvb_gpio = em2882_kworld_315u_digital,
- .ir_codes = RC_MAP_KWORLD_315U,
- .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
- .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE,
- /* Analog mode - still not ready */
- /*.input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = em2882_kworld_315u_analog,
- .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = em2882_kworld_315u_analog1,
- .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = em2882_kworld_315u_analog1,
- .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
- } }, */
- },
- [EM2880_BOARD_EMPIRE_DUAL_TV] = {
- .name = "Empire dual TV",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .has_dvb = 1,
- .dvb_gpio = default_digital,
- .mts_firmware = 1,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = default_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = default_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = default_analog,
- } },
- },
- [EM2881_BOARD_DNT_DA2_HYBRID] = {
- .name = "DNT DA2 Hybrid",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = default_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = default_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = default_analog,
- } },
- },
- [EM2881_BOARD_PINNACLE_HYBRID_PRO] = {
- .name = "Pinnacle Hybrid Pro",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .decoder = EM28XX_TVP5150,
- .has_dvb = 1,
- .dvb_gpio = pinnacle_hybrid_pro_digital,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = pinnacle_hybrid_pro_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = pinnacle_hybrid_pro_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = pinnacle_hybrid_pro_analog,
- } },
- },
- [EM2882_BOARD_PINNACLE_HYBRID_PRO_330E] = {
- .name = "Pinnacle Hybrid Pro (330e)",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .mts_firmware = 1,
- .has_dvb = 1,
- .dvb_gpio = hauppauge_wintv_hvr_900R2_digital,
- .ir_codes = RC_MAP_PINNACLE_PCTV_HD,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- } },
- },
- [EM2882_BOARD_KWORLD_VS_DVBT] = {
- .name = "Kworld VS-DVB-T 323UR",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .decoder = EM28XX_TVP5150,
- .mts_firmware = 1,
- .has_dvb = 1,
- .dvb_gpio = kworld_330u_digital,
- .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
- .ir_codes = RC_MAP_KWORLD_315U,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2882_BOARD_TERRATEC_HYBRID_XS] = {
- .name = "Terratec Cinnergy Hybrid T USB XS (em2882)",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .mts_firmware = 1,
- .decoder = EM28XX_TVP5150,
- .has_dvb = 1,
- .dvb_gpio = hauppauge_wintv_hvr_900_digital,
- .ir_codes = RC_MAP_TERRATEC_CINERGY_XS,
- .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
- } },
- },
- [EM2882_BOARD_DIKOM_DK300] = {
- .name = "Dikom DK300",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .decoder = EM28XX_TVP5150,
- .mts_firmware = 1,
- .has_dvb = 1,
- .dvb_gpio = dikom_dk300_digital,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = default_analog,
- } },
- },
- [EM2883_BOARD_KWORLD_HYBRID_330U] = {
- .name = "Kworld PlusTV HD Hybrid 330",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .decoder = EM28XX_TVP5150,
- .mts_firmware = 1,
- .has_dvb = 1,
- .dvb_gpio = kworld_330u_digital,
- .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
- .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
- EM28XX_I2C_EEPROM_ON_BOARD |
- EM28XX_I2C_EEPROM_KEY_VALID,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = kworld_330u_analog,
- .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = kworld_330u_analog,
- .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = kworld_330u_analog,
- } },
- },
- [EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
- .name = "Compro VideoMate ForYou/Stereo",
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .tvaudio_addr = 0xb0,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_TVP5150,
- .adecoder = EM28XX_TVAUDIO,
- .mute_gpio = compro_mute_gpio,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = compro_unmute_tv_gpio,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = compro_unmute_svid_gpio,
- } },
- },
- [EM2860_BOARD_KAIOMY_TVNPC_U2] = {
- .name = "Kaiomy TVnPC U2",
- .vchannels = 3,
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0x61,
- .mts_firmware = 1,
- .decoder = EM28XX_TVP5150,
- .tuner_gpio = default_tuner_gpio,
- .ir_codes = RC_MAP_KAIOMY,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
-
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- .radio = {
- .type = EM28XX_RADIO,
- .amux = EM28XX_AMUX_LINE_IN,
- }
- },
- [EM2860_BOARD_EASYCAP] = {
- .name = "Easy Cap Capture DC-60",
- .vchannels = 2,
- .tuner_type = TUNER_ABSENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2820_BOARD_IODATA_GVMVP_SZ] = {
- .name = "IO-DATA GV-MVP/SZ",
- .tuner_type = TUNER_PHILIPS_FM1236_MK3,
- .tuner_gpio = default_tuner_gpio,
- .tda9887_conf = TDA9887_PRESENT,
- .decoder = EM28XX_TVP5150,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- }, { /* Composite has not been tested yet */
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_VIDEO,
- }, { /* S-video has not been tested yet */
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_VIDEO,
- } },
- },
- [EM2860_BOARD_TERRATEC_GRABBY] = {
- .name = "Terratec Grabby",
- .vchannels = 2,
- .tuner_type = TUNER_ABSENT,
- .decoder = EM28XX_SAA711X,
- .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- [EM2860_BOARD_TERRATEC_AV350] = {
- .name = "Terratec AV350",
- .vchannels = 2,
- .tuner_type = TUNER_ABSENT,
- .decoder = EM28XX_TVP5150,
- .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
- .mute_gpio = terratec_av350_mute_gpio,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AUDIO_SRC_LINE,
- .gpio = terratec_av350_unmute_gpio,
-
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AUDIO_SRC_LINE,
- .gpio = terratec_av350_unmute_gpio,
- } },
- },
-
- [EM2860_BOARD_ELGATO_VIDEO_CAPTURE] = {
- .name = "Elgato Video Capture",
- .decoder = EM28XX_SAA711X,
- .tuner_type = TUNER_ABSENT, /* Capture only device */
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
-
- [EM2882_BOARD_EVGA_INDTUBE] = {
- .name = "Evga inDtube",
- .tuner_type = TUNER_XC2028,
- .tuner_gpio = default_tuner_gpio,
- .decoder = EM28XX_TVP5150,
- .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
- .mts_firmware = 1,
- .has_dvb = 1,
- .dvb_gpio = evga_indtube_digital,
- .ir_codes = RC_MAP_EVGA_INDTUBE,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = TVP5150_COMPOSITE0,
- .amux = EM28XX_AMUX_VIDEO,
- .gpio = evga_indtube_analog,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = TVP5150_COMPOSITE1,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = evga_indtube_analog,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = TVP5150_SVIDEO,
- .amux = EM28XX_AMUX_LINE_IN,
- .gpio = evga_indtube_analog,
- } },
- },
- /* eb1a:2868 Empia EM2870 + Philips CU1216L NIM (Philips TDA10023 +
- Infineon TUA6034) */
- [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = {
- .name = "Reddo DVB-C USB TV Box",
- .tuner_type = TUNER_ABSENT,
- .tuner_gpio = reddo_dvb_c_usb_box,
- .has_dvb = 1,
- },
- /* 1b80:a340 - Empia EM2870, NXP TDA18271HD and LG DT3304, sold
- * initially as the KWorld PlusTV 340U, then as the UB435-Q.
- * Early variants have a TDA18271HD/C1, later ones a TDA18271HD/C2 */
- [EM2870_BOARD_KWORLD_A340] = {
- .name = "KWorld PlusTV 340U or UB435-Q (ATSC)",
- .tuner_type = TUNER_ABSENT, /* Digital-only TDA18271HD */
- .has_dvb = 1,
- .dvb_gpio = kworld_a340_digital,
- .tuner_gpio = default_tuner_gpio,
- },
- /* 2013:024f PCTV nanoStick T2 290e.
- * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2 */
- [EM28174_BOARD_PCTV_290E] = {
- .name = "PCTV nanoStick T2 290e",
- .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
- EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ,
- .tuner_type = TUNER_ABSENT,
- .tuner_gpio = pctv_290e,
- .has_dvb = 1,
- .ir_codes = RC_MAP_PINNACLE_PCTV_HD,
- },
- /* 2013:024f PCTV DVB-S2 Stick 460e
- * Empia EM28174, NXP TDA10071, Conexant CX24118A and Allegro A8293 */
- [EM28174_BOARD_PCTV_460E] = {
- .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
- EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ,
- .name = "PCTV DVB-S2 Stick (460e)",
- .tuner_type = TUNER_ABSENT,
- .tuner_gpio = pctv_460e,
- .has_dvb = 1,
- .ir_codes = RC_MAP_PINNACLE_PCTV_HD,
- },
- /* eb1a:5006 Honestech VIDBOX NW03
- * Empia EM2860, Philips SAA7113, Empia EMP202, No Tuner */
- [EM2860_BOARD_HT_VIDBOX_NW03] = {
- .name = "Honestech Vidbox NW03",
- .tuner_type = TUNER_ABSENT,
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3, /* S-VIDEO needs confirming */
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
- /* 1b80:e425 MaxMedia UB425-TC
- * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2 */
- [EM2874_BOARD_MAXMEDIA_UB425_TC] = {
- .name = "MaxMedia UB425-TC",
- .tuner_type = TUNER_ABSENT,
- .tuner_gpio = maxmedia_ub425_tc,
- .has_dvb = 1,
- .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
- EM28XX_I2C_CLK_WAIT_ENABLE |
- EM28XX_I2C_FREQ_400_KHZ,
- },
- /* 2304:0242 PCTV QuatroStick (510e)
- * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 */
- [EM2884_BOARD_PCTV_510E] = {
- .name = "PCTV QuatroStick (510e)",
- .tuner_type = TUNER_ABSENT,
- .tuner_gpio = pctv_510e,
- .has_dvb = 1,
- .ir_codes = RC_MAP_PINNACLE_PCTV_HD,
- .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
- EM28XX_I2C_CLK_WAIT_ENABLE |
- EM28XX_I2C_FREQ_400_KHZ,
- },
- /* 2013:0251 PCTV QuatroStick nano (520e)
- * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 */
- [EM2884_BOARD_PCTV_520E] = {
- .name = "PCTV QuatroStick nano (520e)",
- .tuner_type = TUNER_ABSENT,
- .tuner_gpio = pctv_520e,
- .has_dvb = 1,
- .ir_codes = RC_MAP_PINNACLE_PCTV_HD,
- .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
- EM28XX_I2C_CLK_WAIT_ENABLE |
- EM28XX_I2C_FREQ_400_KHZ,
- },
-};
-const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
-
-/* table of devices that work with this driver */
-struct usb_device_id em28xx_id_table[] = {
- { USB_DEVICE(0xeb1a, 0x2750),
- .driver_info = EM2750_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0x2751),
- .driver_info = EM2750_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0x2800),
- .driver_info = EM2800_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0x2710),
- .driver_info = EM2820_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0x2820),
- .driver_info = EM2820_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0x2821),
- .driver_info = EM2820_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0x2860),
- .driver_info = EM2820_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0x2861),
- .driver_info = EM2820_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0x2862),
- .driver_info = EM2820_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0x2863),
- .driver_info = EM2820_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0x2870),
- .driver_info = EM2820_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0x2881),
- .driver_info = EM2820_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0x2883),
- .driver_info = EM2820_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0x2868),
- .driver_info = EM2820_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0x2875),
- .driver_info = EM2820_BOARD_UNKNOWN },
- { USB_DEVICE(0xeb1a, 0xe300),
- .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
- { USB_DEVICE(0xeb1a, 0xe303),
- .driver_info = EM2860_BOARD_KAIOMY_TVNPC_U2 },
- { USB_DEVICE(0xeb1a, 0xe305),
- .driver_info = EM2880_BOARD_KWORLD_DVB_305U },
- { USB_DEVICE(0xeb1a, 0xe310),
- .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD },
- { USB_DEVICE(0xeb1a, 0xa313),
- .driver_info = EM2882_BOARD_KWORLD_ATSC_315U },
- { USB_DEVICE(0xeb1a, 0xa316),
- .driver_info = EM2883_BOARD_KWORLD_HYBRID_330U },
- { USB_DEVICE(0xeb1a, 0xe320),
- .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II },
- { USB_DEVICE(0xeb1a, 0xe323),
- .driver_info = EM2882_BOARD_KWORLD_VS_DVBT },
- { USB_DEVICE(0xeb1a, 0xe350),
- .driver_info = EM2870_BOARD_KWORLD_350U },
- { USB_DEVICE(0xeb1a, 0xe355),
- .driver_info = EM2870_BOARD_KWORLD_355U },
- { USB_DEVICE(0xeb1a, 0x2801),
- .driver_info = EM2800_BOARD_GRABBEEX_USB2800 },
- { USB_DEVICE(0xeb1a, 0xe357),
- .driver_info = EM2870_BOARD_KWORLD_355U },
- { USB_DEVICE(0xeb1a, 0xe359),
- .driver_info = EM2870_BOARD_KWORLD_355U },
- { USB_DEVICE(0x1b80, 0xe302),
- .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kaiser Baas Video to DVD maker */
- { USB_DEVICE(0x1b80, 0xe304),
- .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kworld DVD Maker 2 */
- { USB_DEVICE(0x0ccd, 0x0036),
- .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
- { USB_DEVICE(0x0ccd, 0x004c),
- .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS_FR },
- { USB_DEVICE(0x0ccd, 0x004f),
- .driver_info = EM2860_BOARD_TERRATEC_HYBRID_XS },
- { USB_DEVICE(0x0ccd, 0x005e),
- .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
- { USB_DEVICE(0x0ccd, 0x0042),
- .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
- { USB_DEVICE(0x0ccd, 0x0043),
- .driver_info = EM2870_BOARD_TERRATEC_XS },
- { USB_DEVICE(0x0ccd, 0x008e), /* Cinergy HTC USB XS Rev. 1 */
- .driver_info = EM2884_BOARD_TERRATEC_H5 },
- { USB_DEVICE(0x0ccd, 0x00ac), /* Cinergy HTC USB XS Rev. 2 */
- .driver_info = EM2884_BOARD_TERRATEC_H5 },
- { USB_DEVICE(0x0ccd, 0x10a2), /* H5 Rev. 1 */
- .driver_info = EM2884_BOARD_TERRATEC_H5 },
- { USB_DEVICE(0x0ccd, 0x10ad), /* H5 Rev. 2 */
- .driver_info = EM2884_BOARD_TERRATEC_H5 },
- { USB_DEVICE(0x0ccd, 0x0084),
- .driver_info = EM2860_BOARD_TERRATEC_AV350 },
- { USB_DEVICE(0x0ccd, 0x0096),
- .driver_info = EM2860_BOARD_TERRATEC_GRABBY },
- { USB_DEVICE(0x0ccd, 0x10AF),
- .driver_info = EM2860_BOARD_TERRATEC_GRABBY },
- { USB_DEVICE(0x0ccd, 0x00b2),
- .driver_info = EM2884_BOARD_CINERGY_HTC_STICK },
- { USB_DEVICE(0x0fd9, 0x0033),
- .driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE},
- { USB_DEVICE(0x185b, 0x2870),
- .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE },
- { USB_DEVICE(0x185b, 0x2041),
- .driver_info = EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU },
- { USB_DEVICE(0x2040, 0x4200),
- .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
- { USB_DEVICE(0x2040, 0x4201),
- .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
- { USB_DEVICE(0x2040, 0x6500),
- .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
- { USB_DEVICE(0x2040, 0x6502),
- .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 },
- { USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */
- .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
- { USB_DEVICE(0x2040, 0x6517), /* HP HVR-950 */
- .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
- { USB_DEVICE(0x2040, 0x651b), /* RP HVR-950 */
- .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
- { USB_DEVICE(0x2040, 0x651f),
- .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 },
- { USB_DEVICE(0x0438, 0xb002),
- .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 },
- { USB_DEVICE(0x2001, 0xf112),
- .driver_info = EM2820_BOARD_DLINK_USB_TV },
- { USB_DEVICE(0x2304, 0x0207),
- .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
- { USB_DEVICE(0x2304, 0x0208),
- .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
- { USB_DEVICE(0x2304, 0x021a),
- .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
- { USB_DEVICE(0x2304, 0x0226),
- .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO_330E },
- { USB_DEVICE(0x2304, 0x0227),
- .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
- { USB_DEVICE(0x0413, 0x6023),
- .driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII },
- { USB_DEVICE(0x093b, 0xa003),
- .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
- { USB_DEVICE(0x093b, 0xa005),
- .driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U },
- { USB_DEVICE(0x04bb, 0x0515),
- .driver_info = EM2820_BOARD_IODATA_GVMVP_SZ },
- { USB_DEVICE(0xeb1a, 0x50a6),
- .driver_info = EM2860_BOARD_GADMEI_UTV330 },
- { USB_DEVICE(0x1b80, 0xa340),
- .driver_info = EM2870_BOARD_KWORLD_A340 },
- { USB_DEVICE(0x2013, 0x024f),
- .driver_info = EM28174_BOARD_PCTV_290E },
- { USB_DEVICE(0x2013, 0x024c),
- .driver_info = EM28174_BOARD_PCTV_460E },
- { USB_DEVICE(0x2040, 0x1605),
- .driver_info = EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C },
- { USB_DEVICE(0xeb1a, 0x5006),
- .driver_info = EM2860_BOARD_HT_VIDBOX_NW03 },
- { USB_DEVICE(0x1b80, 0xe309), /* Sveon STV40 */
- .driver_info = EM2860_BOARD_EASYCAP },
- { USB_DEVICE(0x1b80, 0xe425),
- .driver_info = EM2874_BOARD_MAXMEDIA_UB425_TC },
- { USB_DEVICE(0x2304, 0x0242),
- .driver_info = EM2884_BOARD_PCTV_510E },
- { USB_DEVICE(0x2013, 0x0251),
- .driver_info = EM2884_BOARD_PCTV_520E },
- { },
-};
-MODULE_DEVICE_TABLE(usb, em28xx_id_table);
-
-/*
- * EEPROM hash table for devices with generic USB IDs
- */
-static struct em28xx_hash_table em28xx_eeprom_hash[] = {
- /* P/N: SA 60002070465 Tuner: TVF7533-MF */
- {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
- {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
- {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
- {0x166a0441, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
- {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028},
- {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028},
- {0x63f653bd, EM2870_BOARD_REDDO_DVB_C_USB_BOX, TUNER_ABSENT},
- {0x4e913442, EM2882_BOARD_DIKOM_DK300, TUNER_XC2028},
-};
-
-/* I2C devicelist hash table for devices with generic USB IDs */
-static struct em28xx_hash_table em28xx_i2c_hash[] = {
- {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
- {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
- {0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT},
- {0x77800080, EM2860_BOARD_TVP5150_REFERENCE_DESIGN, TUNER_ABSENT},
- {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
- {0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF},
- {0x6b800080, EM2874_BOARD_LEADERSHIP_ISDBT, TUNER_ABSENT},
-};
-
-/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
-static unsigned short saa711x_addrs[] = {
- 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
- 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
- I2C_CLIENT_END };
-
-static unsigned short tvp5150_addrs[] = {
- 0xb8 >> 1,
- 0xba >> 1,
- I2C_CLIENT_END
-};
-
-static unsigned short msp3400_addrs[] = {
- 0x80 >> 1,
- 0x88 >> 1,
- I2C_CLIENT_END
-};
-
-int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
-{
- int rc = 0;
- struct em28xx *dev = ptr;
-
- if (dev->tuner_type != TUNER_XC2028 && dev->tuner_type != TUNER_XC5000)
- return 0;
-
- if (command != XC2028_TUNER_RESET && command != XC5000_TUNER_RESET)
- return 0;
-
- rc = em28xx_gpio_set(dev, dev->board.tuner_gpio);
-
- return rc;
-}
-EXPORT_SYMBOL_GPL(em28xx_tuner_callback);
-
-static inline void em28xx_set_model(struct em28xx *dev)
-{
- memcpy(&dev->board, &em28xx_boards[dev->model], sizeof(dev->board));
-
- /* Those are the default values for the majority of boards
- Use those values if not specified otherwise at boards entry
- */
- if (!dev->board.xclk)
- dev->board.xclk = EM28XX_XCLK_IR_RC5_MODE |
- EM28XX_XCLK_FREQUENCY_12MHZ;
-
- if (!dev->board.i2c_speed)
- dev->board.i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
- EM28XX_I2C_FREQ_100_KHZ;
-}
-
-
-/* FIXME: Should be replaced by a proper mt9m111 driver */
-static int em28xx_initialize_mt9m111(struct em28xx *dev)
-{
- int i;
- unsigned char regs[][3] = {
- { 0x0d, 0x00, 0x01, }, /* reset and use defaults */
- { 0x0d, 0x00, 0x00, },
- { 0x0a, 0x00, 0x21, },
- { 0x21, 0x04, 0x00, }, /* full readout speed, no row/col skipping */
- };
-
- for (i = 0; i < ARRAY_SIZE(regs); i++)
- i2c_master_send(&dev->i2c_client, &regs[i][0], 3);
-
- return 0;
-}
-
-
-/* FIXME: Should be replaced by a proper mt9m001 driver */
-static int em28xx_initialize_mt9m001(struct em28xx *dev)
-{
- int i;
- unsigned char regs[][3] = {
- { 0x0d, 0x00, 0x01, },
- { 0x0d, 0x00, 0x00, },
- { 0x04, 0x05, 0x00, }, /* hres = 1280 */
- { 0x03, 0x04, 0x00, }, /* vres = 1024 */
- { 0x20, 0x11, 0x00, },
- { 0x06, 0x00, 0x10, },
- { 0x2b, 0x00, 0x24, },
- { 0x2e, 0x00, 0x24, },
- { 0x35, 0x00, 0x24, },
- { 0x2d, 0x00, 0x20, },
- { 0x2c, 0x00, 0x20, },
- { 0x09, 0x0a, 0xd4, },
- { 0x35, 0x00, 0x57, },
- };
-
- for (i = 0; i < ARRAY_SIZE(regs); i++)
- i2c_master_send(&dev->i2c_client, &regs[i][0], 3);
-
- return 0;
-}
-
-/* HINT method: webcam I2C chips
- *
- * This method works for webcams with Micron sensors
- */
-static int em28xx_hint_sensor(struct em28xx *dev)
-{
- int rc;
- char *sensor_name;
- unsigned char cmd;
- __be16 version_be;
- u16 version;
-
- /* Micron sensor detection */
- dev->i2c_client.addr = 0xba >> 1;
- cmd = 0;
- i2c_master_send(&dev->i2c_client, &cmd, 1);
- rc = i2c_master_recv(&dev->i2c_client, (char *)&version_be, 2);
- if (rc != 2)
- return -EINVAL;
-
- version = be16_to_cpu(version_be);
- switch (version) {
- case 0x8232: /* mt9v011 640x480 1.3 Mpix sensor */
- case 0x8243: /* mt9v011 rev B 640x480 1.3 Mpix sensor */
- dev->model = EM2820_BOARD_SILVERCREST_WEBCAM;
- em28xx_set_model(dev);
-
- sensor_name = "mt9v011";
- dev->em28xx_sensor = EM28XX_MT9V011;
- dev->sensor_xres = 640;
- dev->sensor_yres = 480;
- /*
- * FIXME: mt9v011 uses I2S speed as xtal clk - at least with
- * the Silvercrest cam I have here for testing - for higher
- * resolutions, a high clock cause horizontal artifacts, so we
- * need to use a lower xclk frequency.
- * Yet, it would be possible to adjust xclk depending on the
- * desired resolution, since this affects directly the
- * frame rate.
- */
- dev->board.xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ;
- dev->sensor_xtal = 4300000;
-
- /* probably means GRGB 16 bit bayer */
- dev->vinmode = 0x0d;
- dev->vinctl = 0x00;
-
- break;
-
- case 0x143a: /* MT9M111 as found in the ECS G200 */
- dev->model = EM2750_BOARD_UNKNOWN;
- em28xx_set_model(dev);
-
- sensor_name = "mt9m111";
- dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ;
- dev->em28xx_sensor = EM28XX_MT9M111;
- em28xx_initialize_mt9m111(dev);
- dev->sensor_xres = 640;
- dev->sensor_yres = 512;
-
- dev->vinmode = 0x0a;
- dev->vinctl = 0x00;
-
- break;
-
- case 0x8431:
- dev->model = EM2750_BOARD_UNKNOWN;
- em28xx_set_model(dev);
-
- sensor_name = "mt9m001";
- dev->em28xx_sensor = EM28XX_MT9M001;
- em28xx_initialize_mt9m001(dev);
- dev->sensor_xres = 1280;
- dev->sensor_yres = 1024;
-
- /* probably means BGGR 16 bit bayer */
- dev->vinmode = 0x0c;
- dev->vinctl = 0x00;
-
- break;
- default:
- printk("Unknown Micron Sensor 0x%04x\n", version);
- return -EINVAL;
- }
-
- /* Setup webcam defaults */
- em28xx_pre_card_setup(dev);
-
- em28xx_errdev("Sensor is %s, using model %s entry.\n",
- sensor_name, em28xx_boards[dev->model].name);
-
- return 0;
-}
-
-/* Since em28xx_pre_card_setup() requires a proper dev->model,
- * this won't work for boards with generic PCI IDs
- */
-static void em28xx_pre_card_setup(struct em28xx *dev)
-{
- /* Set the initial XCLK and I2C clock values based on the board
- definition */
- em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk & 0x7f);
- if (!dev->board.is_em2800)
- em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed);
- msleep(50);
-
- /* request some modules */
- switch (dev->model) {
- case EM2861_BOARD_PLEXTOR_PX_TV100U:
- /* Sets the msp34xx I2S speed */
- dev->i2s_speed = 2048000;
- break;
- case EM2861_BOARD_KWORLD_PVRTV_300U:
- case EM2880_BOARD_KWORLD_DVB_305U:
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x6d);
- msleep(10);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x7d);
- msleep(10);
- break;
- case EM2870_BOARD_COMPRO_VIDEOMATE:
- /* TODO: someone can do some cleanup here...
- not everything's needed */
- em28xx_write_reg(dev, EM2880_R04_GPO, 0x00);
- msleep(10);
- em28xx_write_reg(dev, EM2880_R04_GPO, 0x01);
- msleep(10);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
- mdelay(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc);
- mdelay(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xdc);
- mdelay(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc);
- mdelay(70);
- break;
- case EM2870_BOARD_TERRATEC_XS_MT2060:
- /* this device needs some gpio writes to get the DVB-T
- demod work */
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
- mdelay(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde);
- mdelay(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
- mdelay(70);
- break;
- case EM2870_BOARD_PINNACLE_PCTV_DVB:
- /* this device needs some gpio writes to get the
- DVB-T demod work */
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
- mdelay(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde);
- mdelay(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
- mdelay(70);
- break;
- case EM2820_BOARD_GADMEI_UTV310:
- case EM2820_BOARD_MSI_VOX_USB_2:
- /* enables audio for that devices */
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
- break;
-
- case EM2882_BOARD_KWORLD_ATSC_315U:
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
- msleep(10);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
- msleep(10);
- em28xx_write_reg(dev, EM2880_R04_GPO, 0x00);
- msleep(10);
- em28xx_write_reg(dev, EM2880_R04_GPO, 0x08);
- msleep(10);
- break;
-
- case EM2860_BOARD_KAIOMY_TVNPC_U2:
- em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1);
- em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
- em28xx_write_regs(dev, 0x0d, "\x42", 1);
- em28xx_write_regs(dev, 0x08, "\xfd", 1);
- msleep(10);
- em28xx_write_regs(dev, 0x08, "\xff", 1);
- msleep(10);
- em28xx_write_regs(dev, 0x08, "\x7f", 1);
- msleep(10);
- em28xx_write_regs(dev, 0x08, "\x6b", 1);
-
- break;
- case EM2860_BOARD_EASYCAP:
- em28xx_write_regs(dev, 0x08, "\xf8", 1);
- break;
-
- case EM2820_BOARD_IODATA_GVMVP_SZ:
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
- msleep(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
- msleep(10);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
- msleep(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
- msleep(70);
- break;
- }
-
- em28xx_gpio_set(dev, dev->board.tuner_gpio);
- em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
-
- /* Unlock device */
- em28xx_set_mode(dev, EM28XX_SUSPEND);
-}
-
-static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
-{
- memset(ctl, 0, sizeof(*ctl));
-
- ctl->fname = XC2028_DEFAULT_FIRMWARE;
- ctl->max_len = 64;
- ctl->mts = em28xx_boards[dev->model].mts_firmware;
-
- switch (dev->model) {
- case EM2880_BOARD_EMPIRE_DUAL_TV:
- case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
- case EM2882_BOARD_TERRATEC_HYBRID_XS:
- ctl->demod = XC3028_FE_ZARLINK456;
- break;
- case EM2880_BOARD_TERRATEC_HYBRID_XS:
- case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
- case EM2881_BOARD_PINNACLE_HYBRID_PRO:
- ctl->demod = XC3028_FE_ZARLINK456;
- break;
- case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
- case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
- ctl->demod = XC3028_FE_DEFAULT;
- break;
- case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
- ctl->demod = XC3028_FE_DEFAULT;
- ctl->fname = XC3028L_DEFAULT_FIRMWARE;
- break;
- case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
- case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
- case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
- /* FIXME: Better to specify the needed IF */
- ctl->demod = XC3028_FE_DEFAULT;
- break;
- case EM2883_BOARD_KWORLD_HYBRID_330U:
- case EM2882_BOARD_DIKOM_DK300:
- case EM2882_BOARD_KWORLD_VS_DVBT:
- ctl->demod = XC3028_FE_CHINA;
- ctl->fname = XC2028_DEFAULT_FIRMWARE;
- break;
- case EM2882_BOARD_EVGA_INDTUBE:
- ctl->demod = XC3028_FE_CHINA;
- ctl->fname = XC3028L_DEFAULT_FIRMWARE;
- break;
- default:
- ctl->demod = XC3028_FE_OREN538;
- }
-}
-
-static void em28xx_tuner_setup(struct em28xx *dev)
-{
- struct tuner_setup tun_setup;
- struct v4l2_frequency f;
-
- if (dev->tuner_type == TUNER_ABSENT)
- return;
-
- memset(&tun_setup, 0, sizeof(tun_setup));
-
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.tuner_callback = em28xx_tuner_callback;
-
- if (dev->board.radio.type) {
- tun_setup.type = dev->board.radio.type;
- tun_setup.addr = dev->board.radio_addr;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
- }
-
- if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) {
- tun_setup.type = dev->tuner_type;
- tun_setup.addr = dev->tuner_addr;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
- }
-
- if (dev->tda9887_conf) {
- struct v4l2_priv_tun_config tda9887_cfg;
-
- tda9887_cfg.tuner = TUNER_TDA9887;
- tda9887_cfg.priv = &dev->tda9887_conf;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &tda9887_cfg);
- }
-
- if (dev->tuner_type == TUNER_XC2028) {
- struct v4l2_priv_tun_config xc2028_cfg;
- struct xc2028_ctrl ctl;
-
- memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
- memset(&ctl, 0, sizeof(ctl));
-
- em28xx_setup_xc3028(dev, &ctl);
-
- xc2028_cfg.tuner = TUNER_XC2028;
- xc2028_cfg.priv = &ctl;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &xc2028_cfg);
- }
-
- /* configure tuner */
- f.tuner = 0;
- f.type = V4L2_TUNER_ANALOG_TV;
- f.frequency = 9076; /* just a magic number */
- dev->ctl_freq = f.frequency;
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
-}
-
-static int em28xx_hint_board(struct em28xx *dev)
-{
- int i;
-
- /* HINT method: EEPROM
- *
- * This method works only for boards with eeprom.
- * Uses a hash of all eeprom bytes. The hash should be
- * unique for a vendor/tuner pair.
- * There are a high chance that tuners for different
- * video standards produce different hashes.
- */
- for (i = 0; i < ARRAY_SIZE(em28xx_eeprom_hash); i++) {
- if (dev->hash == em28xx_eeprom_hash[i].hash) {
- dev->model = em28xx_eeprom_hash[i].model;
- dev->tuner_type = em28xx_eeprom_hash[i].tuner;
-
- em28xx_errdev("Your board has no unique USB ID.\n");
- em28xx_errdev("A hint were successfully done, "
- "based on eeprom hash.\n");
- em28xx_errdev("This method is not 100%% failproof.\n");
- em28xx_errdev("If the board were missdetected, "
- "please email this log to:\n");
- em28xx_errdev("\tV4L Mailing List "
- " <linux-media@vger.kernel.org>\n");
- em28xx_errdev("Board detected as %s\n",
- em28xx_boards[dev->model].name);
-
- return 0;
- }
- }
-
- /* HINT method: I2C attached devices
- *
- * This method works for all boards.
- * Uses a hash of i2c scanned devices.
- * Devices with the same i2c attached chips will
- * be considered equal.
- * This method is less precise than the eeprom one.
- */
-
- /* user did not request i2c scanning => do it now */
- if (!dev->i2c_hash)
- em28xx_do_i2c_scan(dev);
-
- for (i = 0; i < ARRAY_SIZE(em28xx_i2c_hash); i++) {
- if (dev->i2c_hash == em28xx_i2c_hash[i].hash) {
- dev->model = em28xx_i2c_hash[i].model;
- dev->tuner_type = em28xx_i2c_hash[i].tuner;
- em28xx_errdev("Your board has no unique USB ID.\n");
- em28xx_errdev("A hint were successfully done, "
- "based on i2c devicelist hash.\n");
- em28xx_errdev("This method is not 100%% failproof.\n");
- em28xx_errdev("If the board were missdetected, "
- "please email this log to:\n");
- em28xx_errdev("\tV4L Mailing List "
- " <linux-media@vger.kernel.org>\n");
- em28xx_errdev("Board detected as %s\n",
- em28xx_boards[dev->model].name);
-
- return 0;
- }
- }
-
- em28xx_errdev("Your board has no unique USB ID and thus need a "
- "hint to be detected.\n");
- em28xx_errdev("You may try to use card=<n> insmod option to "
- "workaround that.\n");
- em28xx_errdev("Please send an email with this log to:\n");
- em28xx_errdev("\tV4L Mailing List <linux-media@vger.kernel.org>\n");
- em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash);
- em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash);
-
- em28xx_errdev("Here is a list of valid choices for the card=<n>"
- " insmod option:\n");
- for (i = 0; i < em28xx_bcount; i++) {
- em28xx_errdev(" card=%d -> %s\n",
- i, em28xx_boards[i].name);
- }
- return -1;
-}
-
-static void em28xx_card_setup(struct em28xx *dev)
-{
- /*
- * If the device can be a webcam, seek for a sensor.
- * If sensor is not found, then it isn't a webcam.
- */
- if (dev->board.is_webcam) {
- if (em28xx_hint_sensor(dev) < 0)
- dev->board.is_webcam = 0;
- else
- dev->progressive = 1;
- }
-
- if (!dev->board.is_webcam) {
- switch (dev->model) {
- case EM2820_BOARD_UNKNOWN:
- case EM2800_BOARD_UNKNOWN:
- /*
- * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD.
- *
- * This occurs because they share identical USB vendor and
- * product IDs.
- *
- * What we do here is look up the EEPROM hash of the K-WORLD
- * and if it is found then we decide that we do not have
- * a DIGIVOX and reset the device to the K-WORLD instead.
- *
- * This solution is only valid if they do not share eeprom
- * hash identities which has not been determined as yet.
- */
- if (em28xx_hint_board(dev) < 0)
- em28xx_errdev("Board not discovered\n");
- else {
- em28xx_set_model(dev);
- em28xx_pre_card_setup(dev);
- }
- break;
- default:
- em28xx_set_model(dev);
- }
- }
-
- em28xx_info("Identified as %s (card=%d)\n",
- dev->board.name, dev->model);
-
- dev->tuner_type = em28xx_boards[dev->model].tuner_type;
- if (em28xx_boards[dev->model].tuner_addr)
- dev->tuner_addr = em28xx_boards[dev->model].tuner_addr;
-
- if (em28xx_boards[dev->model].tda9887_conf)
- dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf;
-
- /* request some modules */
- switch (dev->model) {
- case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
- case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
- case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
- case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
- case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
- {
- struct tveeprom tv;
-#if defined(CONFIG_MODULES) && defined(MODULE)
- request_module("tveeprom");
-#endif
- /* Call first TVeeprom */
-
- dev->i2c_client.addr = 0xa0 >> 1;
- tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata);
-
- dev->tuner_type = tv.tuner_type;
-
- if (tv.audio_processor == V4L2_IDENT_MSPX4XX) {
- dev->i2s_speed = 2048000;
- dev->board.has_msp34xx = 1;
- }
- break;
- }
- case EM2882_BOARD_KWORLD_ATSC_315U:
- em28xx_write_reg(dev, 0x0d, 0x42);
- msleep(10);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
- msleep(10);
- break;
- case EM2820_BOARD_KWORLD_PVRTV2800RF:
- /* GPIO enables sound on KWORLD PVR TV 2800RF */
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9);
- break;
- case EM2820_BOARD_UNKNOWN:
- case EM2800_BOARD_UNKNOWN:
- /*
- * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD.
- *
- * This occurs because they share identical USB vendor and
- * product IDs.
- *
- * What we do here is look up the EEPROM hash of the K-WORLD
- * and if it is found then we decide that we do not have
- * a DIGIVOX and reset the device to the K-WORLD instead.
- *
- * This solution is only valid if they do not share eeprom
- * hash identities which has not been determined as yet.
- */
- case EM2880_BOARD_MSI_DIGIVOX_AD:
- if (!em28xx_hint_board(dev))
- em28xx_set_model(dev);
-
- /* In cases where we had to use a board hint, the call to
- em28xx_set_mode() in em28xx_pre_card_setup() was a no-op,
- so make the call now so the analog GPIOs are set properly
- before probing the i2c bus. */
- em28xx_gpio_set(dev, dev->board.tuner_gpio);
- em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
- break;
-
-/*
- * The Dikom DK300 is detected as an Kworld VS-DVB-T 323UR.
- *
- * This occurs because they share identical USB vendor and
- * product IDs.
- *
- * What we do here is look up the EEPROM hash of the Dikom
- * and if it is found then we decide that we do not have
- * a Kworld and reset the device to the Dikom instead.
- *
- * This solution is only valid if they do not share eeprom
- * hash identities which has not been determined as yet.
- */
- case EM2882_BOARD_KWORLD_VS_DVBT:
- if (!em28xx_hint_board(dev))
- em28xx_set_model(dev);
-
- /* In cases where we had to use a board hint, the call to
- em28xx_set_mode() in em28xx_pre_card_setup() was a no-op,
- so make the call now so the analog GPIOs are set properly
- before probing the i2c bus. */
- em28xx_gpio_set(dev, dev->board.tuner_gpio);
- em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
- break;
- }
-
- if (dev->board.valid == EM28XX_BOARD_NOT_VALIDATED) {
- em28xx_errdev("\n\n");
- em28xx_errdev("The support for this board weren't "
- "valid yet.\n");
- em28xx_errdev("Please send a report of having this working\n");
- em28xx_errdev("not to V4L mailing list (and/or to other "
- "addresses)\n\n");
- }
-
- /* Allow override tuner type by a module parameter */
- if (tuner >= 0)
- dev->tuner_type = tuner;
-
- /* request some modules */
- if (dev->board.has_msp34xx)
- v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- "msp3400", 0, msp3400_addrs);
-
- if (dev->board.decoder == EM28XX_SAA711X)
- v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- "saa7115_auto", 0, saa711x_addrs);
-
- if (dev->board.decoder == EM28XX_TVP5150)
- v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- "tvp5150", 0, tvp5150_addrs);
-
- if (dev->em28xx_sensor == EM28XX_MT9V011) {
- struct mt9v011_platform_data pdata;
- struct i2c_board_info mt9v011_info = {
- .type = "mt9v011",
- .addr = 0xba >> 1,
- .platform_data = &pdata,
- };
-
- pdata.xtal = dev->sensor_xtal;
- v4l2_i2c_new_subdev_board(&dev->v4l2_dev, &dev->i2c_adap,
- &mt9v011_info, NULL);
- }
-
-
- if (dev->board.adecoder == EM28XX_TVAUDIO)
- v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- "tvaudio", dev->board.tvaudio_addr, NULL);
-
- if (dev->board.tuner_type != TUNER_ABSENT) {
- int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
-
- if (dev->board.radio.type)
- v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- "tuner", dev->board.radio_addr, NULL);
-
- if (has_demod)
- v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, "tuner",
- 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
- if (dev->tuner_addr == 0) {
- enum v4l2_i2c_tuner_type type =
- has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
- struct v4l2_subdev *sd;
-
- sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, "tuner",
- 0, v4l2_i2c_tuner_addrs(type));
-
- if (sd)
- dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
- } else {
- v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- "tuner", dev->tuner_addr, NULL);
- }
- }
-
- em28xx_tuner_setup(dev);
-}
-
-
-#if defined(CONFIG_MODULES) && defined(MODULE)
-static void request_module_async(struct work_struct *work)
-{
- struct em28xx *dev = container_of(work,
- struct em28xx, request_module_wk);
-
- if (dev->has_audio_class)
- request_module("snd-usb-audio");
- else if (dev->has_alsa_audio)
- request_module("em28xx-alsa");
-
- if (dev->board.has_dvb)
- request_module("em28xx-dvb");
- if (dev->board.ir_codes && !disable_ir)
- request_module("em28xx-rc");
-}
-
-static void request_modules(struct em28xx *dev)
-{
- INIT_WORK(&dev->request_module_wk, request_module_async);
- schedule_work(&dev->request_module_wk);
-}
-
-static void flush_request_modules(struct em28xx *dev)
-{
- flush_work(&dev->request_module_wk);
-}
-#else
-#define request_modules(dev)
-#define flush_request_modules(dev)
-#endif /* CONFIG_MODULES */
-
-/*
- * em28xx_release_resources()
- * unregisters the v4l2,i2c and usb devices
- * called when the device gets disconnected or at module unload
-*/
-void em28xx_release_resources(struct em28xx *dev)
-{
- /*FIXME: I2C IR should be disconnected */
-
- em28xx_release_analog_resources(dev);
-
- em28xx_i2c_unregister(dev);
-
- v4l2_device_unregister(&dev->v4l2_dev);
-
- usb_put_dev(dev->udev);
-
- /* Mark device as unused */
- clear_bit(dev->devno, &em28xx_devused);
-};
-
-/*
- * em28xx_init_dev()
- * allocates and inits the device structs, registers i2c bus and v4l device
- */
-static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
- struct usb_interface *interface,
- int minor)
-{
- int retval;
-
- dev->udev = udev;
- mutex_init(&dev->ctrl_urb_lock);
- spin_lock_init(&dev->slock);
-
- dev->em28xx_write_regs = em28xx_write_regs;
- dev->em28xx_read_reg = em28xx_read_reg;
- dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len;
- dev->em28xx_write_regs_req = em28xx_write_regs_req;
- dev->em28xx_read_reg_req = em28xx_read_reg_req;
- dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
-
- em28xx_set_model(dev);
-
- /* Set the default GPO/GPIO for legacy devices */
- dev->reg_gpo_num = EM2880_R04_GPO;
- dev->reg_gpio_num = EM28XX_R08_GPIO;
-
- dev->wait_after_write = 5;
-
- /* Based on the Chip ID, set the device configuration */
- retval = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
- if (retval > 0) {
- dev->chip_id = retval;
-
- switch (dev->chip_id) {
- case CHIP_ID_EM2800:
- em28xx_info("chip ID is em2800\n");
- break;
- case CHIP_ID_EM2710:
- em28xx_info("chip ID is em2710\n");
- break;
- case CHIP_ID_EM2750:
- em28xx_info("chip ID is em2750\n");
- break;
- case CHIP_ID_EM2820:
- em28xx_info("chip ID is em2820 (or em2710)\n");
- break;
- case CHIP_ID_EM2840:
- em28xx_info("chip ID is em2840\n");
- break;
- case CHIP_ID_EM2860:
- em28xx_info("chip ID is em2860\n");
- break;
- case CHIP_ID_EM2870:
- em28xx_info("chip ID is em2870\n");
- dev->wait_after_write = 0;
- break;
- case CHIP_ID_EM2874:
- em28xx_info("chip ID is em2874\n");
- dev->reg_gpio_num = EM2874_R80_GPIO;
- dev->wait_after_write = 0;
- break;
- case CHIP_ID_EM28174:
- em28xx_info("chip ID is em28174\n");
- dev->reg_gpio_num = EM2874_R80_GPIO;
- dev->wait_after_write = 0;
- break;
- case CHIP_ID_EM2883:
- em28xx_info("chip ID is em2882/em2883\n");
- dev->wait_after_write = 0;
- break;
- case CHIP_ID_EM2884:
- em28xx_info("chip ID is em2884\n");
- dev->reg_gpio_num = EM2874_R80_GPIO;
- dev->wait_after_write = 0;
- break;
- default:
- em28xx_info("em28xx chip ID = %d\n", dev->chip_id);
- }
- }
-
- if (dev->is_audio_only) {
- retval = em28xx_audio_setup(dev);
- if (retval)
- return -ENODEV;
- em28xx_init_extension(dev);
-
- return 0;
- }
-
- /* Prepopulate cached GPO register content */
- retval = em28xx_read_reg(dev, dev->reg_gpo_num);
- if (retval >= 0)
- dev->reg_gpo = retval;
-
- em28xx_pre_card_setup(dev);
-
- if (!dev->board.is_em2800) {
- /* Resets I2C speed */
- retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed);
- if (retval < 0) {
- em28xx_errdev("%s: em28xx_write_reg failed!"
- " retval [%d]\n",
- __func__, retval);
- return retval;
- }
- }
-
- retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
- if (retval < 0) {
- em28xx_errdev("Call to v4l2_device_register() failed!\n");
- return retval;
- }
-
- /* register i2c bus */
- retval = em28xx_i2c_register(dev);
- if (retval < 0) {
- em28xx_errdev("%s: em28xx_i2c_register - error [%d]!\n",
- __func__, retval);
- goto unregister_dev;
- }
-
- /*
- * Default format, used for tvp5150 or saa711x output formats
- */
- dev->vinmode = 0x10;
- dev->vinctl = EM28XX_VINCTRL_INTERLACED |
- EM28XX_VINCTRL_CCIR656_ENABLE;
-
- /* Do board specific init and eeprom reading */
- em28xx_card_setup(dev);
-
- /* Configure audio */
- retval = em28xx_audio_setup(dev);
- if (retval < 0) {
- em28xx_errdev("%s: Error while setting audio - error [%d]!\n",
- __func__, retval);
- goto fail;
- }
-
- /* wake i2c devices */
- em28xx_wake_i2c(dev);
-
- /* init video dma queues */
- INIT_LIST_HEAD(&dev->vidq.active);
- INIT_LIST_HEAD(&dev->vbiq.active);
-
- if (dev->board.has_msp34xx) {
- /* Send a reset to other chips via gpio */
- retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
- if (retval < 0) {
- em28xx_errdev("%s: em28xx_write_reg - "
- "msp34xx(1) failed! error [%d]\n",
- __func__, retval);
- goto fail;
- }
- msleep(3);
-
- retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
- if (retval < 0) {
- em28xx_errdev("%s: em28xx_write_reg - "
- "msp34xx(2) failed! error [%d]\n",
- __func__, retval);
- goto fail;
- }
- msleep(3);
- }
-
- retval = em28xx_register_analog_devices(dev);
- if (retval < 0) {
- goto fail;
- }
-
- /* Save some power by putting tuner to sleep */
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
-
- return 0;
-
-fail:
- em28xx_i2c_unregister(dev);
-
-unregister_dev:
- v4l2_device_unregister(&dev->v4l2_dev);
-
- return retval;
-}
-
-/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
-#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
-
-/*
- * em28xx_usb_probe()
- * checks for supported devices
- */
-static int em28xx_usb_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- struct usb_device *udev;
- struct em28xx *dev = NULL;
- int retval;
- bool has_audio = false, has_video = false, has_dvb = false;
- int i, nr;
- const int ifnum = interface->altsetting[0].desc.bInterfaceNumber;
- char *speed;
-
- udev = usb_get_dev(interface_to_usbdev(interface));
-
- /* Check to see next free device and mark as used */
- do {
- nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS);
- if (nr >= EM28XX_MAXBOARDS) {
- /* No free device slots */
- printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
- EM28XX_MAXBOARDS);
- retval = -ENOMEM;
- goto err_no_slot;
- }
- } while (test_and_set_bit(nr, &em28xx_devused));
-
- /* Don't register audio interfaces */
- if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
- em28xx_err(DRIVER_NAME " audio device (%04x:%04x): "
- "interface %i, class %i\n",
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct),
- ifnum,
- interface->altsetting[0].desc.bInterfaceClass);
-
- retval = -ENODEV;
- goto err;
- }
-
- /* allocate memory for our device state and initialize it */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL) {
- em28xx_err(DRIVER_NAME ": out of memory!\n");
- retval = -ENOMEM;
- goto err;
- }
-
- /* compute alternate max packet sizes */
- dev->alt_max_pkt_size = kmalloc(sizeof(dev->alt_max_pkt_size[0]) *
- interface->num_altsetting, GFP_KERNEL);
- if (dev->alt_max_pkt_size == NULL) {
- em28xx_errdev("out of memory!\n");
- kfree(dev);
- retval = -ENOMEM;
- goto err;
- }
-
- /* Get endpoints */
- for (i = 0; i < interface->num_altsetting; i++) {
- int ep;
-
- for (ep = 0; ep < interface->altsetting[i].desc.bNumEndpoints; ep++) {
- const struct usb_endpoint_descriptor *e;
- int sizedescr, size;
-
- e = &interface->altsetting[i].endpoint[ep].desc;
-
- sizedescr = le16_to_cpu(e->wMaxPacketSize);
- size = sizedescr & 0x7ff;
-
- if (udev->speed == USB_SPEED_HIGH)
- size = size * hb_mult(sizedescr);
-
- if (usb_endpoint_xfer_isoc(e) &&
- usb_endpoint_dir_in(e)) {
- switch (e->bEndpointAddress) {
- case EM28XX_EP_AUDIO:
- has_audio = true;
- break;
- case EM28XX_EP_ANALOG:
- has_video = true;
- dev->alt_max_pkt_size[i] = size;
- break;
- case EM28XX_EP_DIGITAL:
- has_dvb = true;
- if (size > dev->dvb_max_pkt_size) {
- dev->dvb_max_pkt_size = size;
- dev->dvb_alt = i;
- }
- break;
- }
- }
- }
- }
-
- if (!(has_audio || has_video || has_dvb)) {
- retval = -ENODEV;
- goto err_free;
- }
-
- switch (udev->speed) {
- case USB_SPEED_LOW:
- speed = "1.5";
- break;
- case USB_SPEED_UNKNOWN:
- case USB_SPEED_FULL:
- speed = "12";
- break;
- case USB_SPEED_HIGH:
- speed = "480";
- break;
- default:
- speed = "unknown";
- }
-
- printk(KERN_INFO DRIVER_NAME
- ": New device %s %s @ %s Mbps "
- "(%04x:%04x, interface %d, class %d)\n",
- udev->manufacturer ? udev->manufacturer : "",
- udev->product ? udev->product : "",
- speed,
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct),
- ifnum,
- interface->altsetting->desc.bInterfaceNumber);
-
- if (has_audio)
- printk(KERN_INFO DRIVER_NAME
- ": Audio Vendor Class interface %i found\n",
- ifnum);
- if (has_video)
- printk(KERN_INFO DRIVER_NAME
- ": Video interface %i found\n",
- ifnum);
- if (has_dvb)
- printk(KERN_INFO DRIVER_NAME
- ": DVB interface %i found\n",
- ifnum);
-
- /*
- * Make sure we have 480 Mbps of bandwidth, otherwise things like
- * video stream wouldn't likely work, since 12 Mbps is generally
- * not enough even for most Digital TV streams.
- */
- if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) {
- printk(DRIVER_NAME ": Device initialization failed.\n");
- printk(DRIVER_NAME ": Device must be connected to a high-speed"
- " USB 2.0 port.\n");
- retval = -ENODEV;
- goto err_free;
- }
-
- snprintf(dev->name, sizeof(dev->name), "em28xx #%d", nr);
- dev->devno = nr;
- dev->model = id->driver_info;
- dev->alt = -1;
- dev->is_audio_only = has_audio && !(has_video || has_dvb);
- dev->has_alsa_audio = has_audio;
- dev->audio_ifnum = ifnum;
-
- /* Checks if audio is provided by some interface */
- for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
- struct usb_interface *uif = udev->config->interface[i];
- if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
- dev->has_audio_class = 1;
- break;
- }
- }
-
- dev->num_alt = interface->num_altsetting;
-
- if ((card[nr] >= 0) && (card[nr] < em28xx_bcount))
- dev->model = card[nr];
-
- /* save our data pointer in this interface device */
- usb_set_intfdata(interface, dev);
-
- /* allocate device struct */
- mutex_init(&dev->lock);
- mutex_lock(&dev->lock);
- retval = em28xx_init_dev(dev, udev, interface, nr);
- if (retval) {
- goto unlock_and_free;
- }
-
- if (has_dvb) {
- /* pre-allocate DVB isoc transfer buffers */
- retval = em28xx_alloc_isoc(dev, EM28XX_DIGITAL_MODE,
- EM28XX_DVB_MAX_PACKETS,
- EM28XX_DVB_NUM_BUFS,
- dev->dvb_max_pkt_size);
- if (retval) {
- goto unlock_and_free;
- }
- }
-
- request_modules(dev);
-
- /* Should be the last thing to do, to avoid newer udev's to
- open the device before fully initializing it
- */
- mutex_unlock(&dev->lock);
-
- /*
- * These extensions can be modules. If the modules are already
- * loaded then we can initialise the device now, otherwise we
- * will initialise it when the modules load instead.
- */
- em28xx_init_extension(dev);
-
- return 0;
-
-unlock_and_free:
- mutex_unlock(&dev->lock);
-
-err_free:
- kfree(dev->alt_max_pkt_size);
- kfree(dev);
-
-err:
- clear_bit(nr, &em28xx_devused);
-
-err_no_slot:
- usb_put_dev(udev);
- return retval;
-}
-
-/*
- * em28xx_usb_disconnect()
- * called when the device gets disconnected
- * video device will be unregistered on v4l2_close in case it is still open
- */
-static void em28xx_usb_disconnect(struct usb_interface *interface)
-{
- struct em28xx *dev;
-
- dev = usb_get_intfdata(interface);
- usb_set_intfdata(interface, NULL);
-
- if (!dev)
- return;
-
- if (dev->is_audio_only) {
- mutex_lock(&dev->lock);
- em28xx_close_extension(dev);
- mutex_unlock(&dev->lock);
- return;
- }
-
- em28xx_info("disconnecting %s\n", dev->vdev->name);
-
- flush_request_modules(dev);
-
- /* wait until all current v4l2 io is finished then deallocate
- resources */
- mutex_lock(&dev->lock);
-
- v4l2_device_disconnect(&dev->v4l2_dev);
-
- if (dev->users) {
- em28xx_warn
- ("device %s is open! Deregistration and memory "
- "deallocation are deferred on close.\n",
- video_device_node_name(dev->vdev));
-
- dev->state |= DEV_MISCONFIGURED;
- em28xx_uninit_isoc(dev, dev->mode);
- dev->state |= DEV_DISCONNECTED;
- } else {
- dev->state |= DEV_DISCONNECTED;
- em28xx_release_resources(dev);
- }
-
- /* free DVB isoc buffers */
- em28xx_uninit_isoc(dev, EM28XX_DIGITAL_MODE);
-
- mutex_unlock(&dev->lock);
-
- em28xx_close_extension(dev);
-
- if (!dev->users) {
- kfree(dev->alt_max_pkt_size);
- kfree(dev);
- }
-}
-
-static struct usb_driver em28xx_usb_driver = {
- .name = "em28xx",
- .probe = em28xx_usb_probe,
- .disconnect = em28xx_usb_disconnect,
- .id_table = em28xx_id_table,
-};
-
-module_usb_driver(em28xx_usb_driver);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
deleted file mode 100644
index de2cb20ad2c..00000000000
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ /dev/null
@@ -1,1264 +0,0 @@
-/*
- em28xx-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
-
- Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
- Markus Rechberger <mrechberger@gmail.com>
- Mauro Carvalho Chehab <mchehab@infradead.org>
- Sascha Sommer <saschasommer@freenet.de>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/vmalloc.h>
-#include <sound/ac97_codec.h>
-#include <media/v4l2-common.h>
-
-#include "em28xx.h"
-
-/* #define ENABLE_DEBUG_ISOC_FRAMES */
-
-static unsigned int core_debug;
-module_param(core_debug, int, 0644);
-MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
-
-#define em28xx_coredbg(fmt, arg...) do {\
- if (core_debug) \
- printk(KERN_INFO "%s %s :"fmt, \
- dev->name, __func__ , ##arg); } while (0)
-
-static unsigned int reg_debug;
-module_param(reg_debug, int, 0644);
-MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]");
-
-#define em28xx_regdbg(fmt, arg...) do {\
- if (reg_debug) \
- printk(KERN_INFO "%s %s :"fmt, \
- dev->name, __func__ , ##arg); } while (0)
-
-static int alt;
-module_param(alt, int, 0644);
-MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
-
-static unsigned int disable_vbi;
-module_param(disable_vbi, int, 0644);
-MODULE_PARM_DESC(disable_vbi, "disable vbi support");
-
-/* FIXME */
-#define em28xx_isocdbg(fmt, arg...) do {\
- if (core_debug) \
- printk(KERN_INFO "%s %s :"fmt, \
- dev->name, __func__ , ##arg); } while (0)
-
-/*
- * em28xx_read_reg_req()
- * reads data from the usb device specifying bRequest
- */
-int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
- char *buf, int len)
-{
- int ret;
- int pipe = usb_rcvctrlpipe(dev->udev, 0);
-
- if (dev->state & DEV_DISCONNECTED)
- return -ENODEV;
-
- if (len > URB_MAX_CTRL_SIZE)
- return -EINVAL;
-
- if (reg_debug) {
- printk(KERN_DEBUG "(pipe 0x%08x): "
- "IN: %02x %02x %02x %02x %02x %02x %02x %02x ",
- pipe,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- req, 0, 0,
- reg & 0xff, reg >> 8,
- len & 0xff, len >> 8);
- }
-
- mutex_lock(&dev->ctrl_urb_lock);
- ret = usb_control_msg(dev->udev, pipe, req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0000, reg, dev->urb_buf, len, HZ);
- if (ret < 0) {
- if (reg_debug)
- printk(" failed!\n");
- mutex_unlock(&dev->ctrl_urb_lock);
- return ret;
- }
-
- if (len)
- memcpy(buf, dev->urb_buf, len);
-
- mutex_unlock(&dev->ctrl_urb_lock);
-
- if (reg_debug) {
- int byte;
-
- printk("<<<");
- for (byte = 0; byte < len; byte++)
- printk(" %02x", (unsigned char)buf[byte]);
- printk("\n");
- }
-
- return ret;
-}
-
-/*
- * em28xx_read_reg_req()
- * reads data from the usb device specifying bRequest
- */
-int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
-{
- int ret;
- u8 val;
-
- ret = em28xx_read_reg_req_len(dev, req, reg, &val, 1);
- if (ret < 0)
- return ret;
-
- return val;
-}
-
-int em28xx_read_reg(struct em28xx *dev, u16 reg)
-{
- return em28xx_read_reg_req(dev, USB_REQ_GET_STATUS, reg);
-}
-EXPORT_SYMBOL_GPL(em28xx_read_reg);
-
-/*
- * em28xx_write_regs_req()
- * sends data to the usb device, specifying bRequest
- */
-int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
- int len)
-{
- int ret;
- int pipe = usb_sndctrlpipe(dev->udev, 0);
-
- if (dev->state & DEV_DISCONNECTED)
- return -ENODEV;
-
- if ((len < 1) || (len > URB_MAX_CTRL_SIZE))
- return -EINVAL;
-
- if (reg_debug) {
- int byte;
-
- printk(KERN_DEBUG "(pipe 0x%08x): "
- "OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>",
- pipe,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- req, 0, 0,
- reg & 0xff, reg >> 8,
- len & 0xff, len >> 8);
-
- for (byte = 0; byte < len; byte++)
- printk(" %02x", (unsigned char)buf[byte]);
- printk("\n");
- }
-
- mutex_lock(&dev->ctrl_urb_lock);
- memcpy(dev->urb_buf, buf, len);
- ret = usb_control_msg(dev->udev, pipe, req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0000, reg, dev->urb_buf, len, HZ);
- mutex_unlock(&dev->ctrl_urb_lock);
-
- if (dev->wait_after_write)
- msleep(dev->wait_after_write);
-
- return ret;
-}
-
-int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
-{
- int rc;
-
- rc = em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);
-
- /* Stores GPO/GPIO values at the cache, if changed
- Only write values should be stored, since input on a GPIO
- register will return the input bits.
- Not sure what happens on reading GPO register.
- */
- if (rc >= 0) {
- if (reg == dev->reg_gpo_num)
- dev->reg_gpo = buf[0];
- else if (reg == dev->reg_gpio_num)
- dev->reg_gpio = buf[0];
- }
-
- return rc;
-}
-EXPORT_SYMBOL_GPL(em28xx_write_regs);
-
-/* Write a single register */
-int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val)
-{
- return em28xx_write_regs(dev, reg, &val, 1);
-}
-EXPORT_SYMBOL_GPL(em28xx_write_reg);
-
-/*
- * em28xx_write_reg_bits()
- * sets only some bits (specified by bitmask) of a register, by first reading
- * the actual value
- */
-int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
- u8 bitmask)
-{
- int oldval;
- u8 newval;
-
- /* Uses cache for gpo/gpio registers */
- if (reg == dev->reg_gpo_num)
- oldval = dev->reg_gpo;
- else if (reg == dev->reg_gpio_num)
- oldval = dev->reg_gpio;
- else
- oldval = em28xx_read_reg(dev, reg);
-
- if (oldval < 0)
- return oldval;
-
- newval = (((u8) oldval) & ~bitmask) | (val & bitmask);
-
- return em28xx_write_regs(dev, reg, &newval, 1);
-}
-EXPORT_SYMBOL_GPL(em28xx_write_reg_bits);
-
-/*
- * em28xx_is_ac97_ready()
- * Checks if ac97 is ready
- */
-static int em28xx_is_ac97_ready(struct em28xx *dev)
-{
- int ret, i;
-
- /* Wait up to 50 ms for AC97 command to complete */
- for (i = 0; i < 10; i++, msleep(5)) {
- ret = em28xx_read_reg(dev, EM28XX_R43_AC97BUSY);
- if (ret < 0)
- return ret;
-
- if (!(ret & 0x01))
- return 0;
- }
-
- em28xx_warn("AC97 command still being executed: not handled properly!\n");
- return -EBUSY;
-}
-
-/*
- * em28xx_read_ac97()
- * write a 16 bit value to the specified AC97 address (LSB first!)
- */
-int em28xx_read_ac97(struct em28xx *dev, u8 reg)
-{
- int ret;
- u8 addr = (reg & 0x7f) | 0x80;
- u16 val;
-
- ret = em28xx_is_ac97_ready(dev);
- if (ret < 0)
- return ret;
-
- ret = em28xx_write_regs(dev, EM28XX_R42_AC97ADDR, &addr, 1);
- if (ret < 0)
- return ret;
-
- ret = dev->em28xx_read_reg_req_len(dev, 0, EM28XX_R40_AC97LSB,
- (u8 *)&val, sizeof(val));
-
- if (ret < 0)
- return ret;
- return le16_to_cpu(val);
-}
-EXPORT_SYMBOL_GPL(em28xx_read_ac97);
-
-/*
- * em28xx_write_ac97()
- * write a 16 bit value to the specified AC97 address (LSB first!)
- */
-int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val)
-{
- int ret;
- u8 addr = reg & 0x7f;
- __le16 value;
-
- value = cpu_to_le16(val);
-
- ret = em28xx_is_ac97_ready(dev);
- if (ret < 0)
- return ret;
-
- ret = em28xx_write_regs(dev, EM28XX_R40_AC97LSB, (u8 *) &value, 2);
- if (ret < 0)
- return ret;
-
- ret = em28xx_write_regs(dev, EM28XX_R42_AC97ADDR, &addr, 1);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(em28xx_write_ac97);
-
-struct em28xx_vol_itable {
- enum em28xx_amux mux;
- u8 reg;
-};
-
-static struct em28xx_vol_itable inputs[] = {
- { EM28XX_AMUX_VIDEO, AC97_VIDEO },
- { EM28XX_AMUX_LINE_IN, AC97_LINE },
- { EM28XX_AMUX_PHONE, AC97_PHONE },
- { EM28XX_AMUX_MIC, AC97_MIC },
- { EM28XX_AMUX_CD, AC97_CD },
- { EM28XX_AMUX_AUX, AC97_AUX },
- { EM28XX_AMUX_PCM_OUT, AC97_PCM },
-};
-
-static int set_ac97_input(struct em28xx *dev)
-{
- int ret, i;
- enum em28xx_amux amux = dev->ctl_ainput;
-
- /* EM28XX_AMUX_VIDEO2 is a special case used to indicate that
- em28xx should point to LINE IN, while AC97 should use VIDEO
- */
- if (amux == EM28XX_AMUX_VIDEO2)
- amux = EM28XX_AMUX_VIDEO;
-
- /* Mute all entres but the one that were selected */
- for (i = 0; i < ARRAY_SIZE(inputs); i++) {
- if (amux == inputs[i].mux)
- ret = em28xx_write_ac97(dev, inputs[i].reg, 0x0808);
- else
- ret = em28xx_write_ac97(dev, inputs[i].reg, 0x8000);
-
- if (ret < 0)
- em28xx_warn("couldn't setup AC97 register %d\n",
- inputs[i].reg);
- }
- return 0;
-}
-
-static int em28xx_set_audio_source(struct em28xx *dev)
-{
- int ret;
- u8 input;
-
- if (dev->board.is_em2800) {
- if (dev->ctl_ainput == EM28XX_AMUX_VIDEO)
- input = EM2800_AUDIO_SRC_TUNER;
- else
- input = EM2800_AUDIO_SRC_LINE;
-
- ret = em28xx_write_regs(dev, EM2800_R08_AUDIOSRC, &input, 1);
- if (ret < 0)
- return ret;
- }
-
- if (dev->board.has_msp34xx)
- input = EM28XX_AUDIO_SRC_TUNER;
- else {
- switch (dev->ctl_ainput) {
- case EM28XX_AMUX_VIDEO:
- input = EM28XX_AUDIO_SRC_TUNER;
- break;
- default:
- input = EM28XX_AUDIO_SRC_LINE;
- break;
- }
- }
-
- if (dev->board.mute_gpio && dev->mute)
- em28xx_gpio_set(dev, dev->board.mute_gpio);
- else
- em28xx_gpio_set(dev, INPUT(dev->ctl_input)->gpio);
-
- ret = em28xx_write_reg_bits(dev, EM28XX_R0E_AUDIOSRC, input, 0xc0);
- if (ret < 0)
- return ret;
- msleep(5);
-
- switch (dev->audio_mode.ac97) {
- case EM28XX_NO_AC97:
- break;
- default:
- ret = set_ac97_input(dev);
- }
-
- return ret;
-}
-
-struct em28xx_vol_otable {
- enum em28xx_aout mux;
- u8 reg;
-};
-
-static const struct em28xx_vol_otable outputs[] = {
- { EM28XX_AOUT_MASTER, AC97_MASTER },
- { EM28XX_AOUT_LINE, AC97_HEADPHONE },
- { EM28XX_AOUT_MONO, AC97_MASTER_MONO },
- { EM28XX_AOUT_LFE, AC97_CENTER_LFE_MASTER },
- { EM28XX_AOUT_SURR, AC97_SURROUND_MASTER },
-};
-
-int em28xx_audio_analog_set(struct em28xx *dev)
-{
- int ret, i;
- u8 xclk;
-
- if (!dev->audio_mode.has_audio)
- return 0;
-
- /* It is assumed that all devices use master volume for output.
- It would be possible to use also line output.
- */
- if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
- /* Mute all outputs */
- for (i = 0; i < ARRAY_SIZE(outputs); i++) {
- ret = em28xx_write_ac97(dev, outputs[i].reg, 0x8000);
- if (ret < 0)
- em28xx_warn("couldn't setup AC97 register %d\n",
- outputs[i].reg);
- }
- }
-
- xclk = dev->board.xclk & 0x7f;
- if (!dev->mute)
- xclk |= EM28XX_XCLK_AUDIO_UNMUTE;
-
- ret = em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk);
- if (ret < 0)
- return ret;
- msleep(10);
-
- /* Selects the proper audio input */
- ret = em28xx_set_audio_source(dev);
-
- /* Sets volume */
- if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
- int vol;
-
- em28xx_write_ac97(dev, AC97_POWERDOWN, 0x4200);
- em28xx_write_ac97(dev, AC97_EXTENDED_STATUS, 0x0031);
- em28xx_write_ac97(dev, AC97_PCM_LR_ADC_RATE, 0xbb80);
-
- /* LSB: left channel - both channels with the same level */
- vol = (0x1f - dev->volume) | ((0x1f - dev->volume) << 8);
-
- /* Mute device, if needed */
- if (dev->mute)
- vol |= 0x8000;
-
- /* Sets volume */
- for (i = 0; i < ARRAY_SIZE(outputs); i++) {
- if (dev->ctl_aoutput & outputs[i].mux)
- ret = em28xx_write_ac97(dev, outputs[i].reg,
- vol);
- if (ret < 0)
- em28xx_warn("couldn't setup AC97 register %d\n",
- outputs[i].reg);
- }
-
- if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) {
- int sel = ac97_return_record_select(dev->ctl_aoutput);
-
- /* Use the same input for both left and right
- channels */
- sel |= (sel << 8);
-
- em28xx_write_ac97(dev, AC97_REC_SEL, sel);
- }
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(em28xx_audio_analog_set);
-
-int em28xx_audio_setup(struct em28xx *dev)
-{
- int vid1, vid2, feat, cfg;
- u32 vid;
-
- if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874
- || dev->chip_id == CHIP_ID_EM28174) {
- /* Digital only device - don't load any alsa module */
- dev->audio_mode.has_audio = false;
- dev->has_audio_class = false;
- dev->has_alsa_audio = false;
- return 0;
- }
-
- dev->audio_mode.has_audio = true;
-
- /* See how this device is configured */
- cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG);
- em28xx_info("Config register raw data: 0x%02x\n", cfg);
- if (cfg < 0) {
- /* Register read error? */
- cfg = EM28XX_CHIPCFG_AC97; /* Be conservative */
- } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == 0x00) {
- /* The device doesn't have vendor audio at all */
- dev->has_alsa_audio = false;
- dev->audio_mode.has_audio = false;
- return 0;
- } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) ==
- EM28XX_CHIPCFG_I2S_3_SAMPRATES) {
- em28xx_info("I2S Audio (3 sample rates)\n");
- dev->audio_mode.i2s_3rates = 1;
- } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) ==
- EM28XX_CHIPCFG_I2S_5_SAMPRATES) {
- em28xx_info("I2S Audio (5 sample rates)\n");
- dev->audio_mode.i2s_5rates = 1;
- }
-
- if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) != EM28XX_CHIPCFG_AC97) {
- /* Skip the code that does AC97 vendor detection */
- dev->audio_mode.ac97 = EM28XX_NO_AC97;
- goto init_audio;
- }
-
- dev->audio_mode.ac97 = EM28XX_AC97_OTHER;
-
- vid1 = em28xx_read_ac97(dev, AC97_VENDOR_ID1);
- if (vid1 < 0) {
- /*
- * Device likely doesn't support AC97
- * Note: (some) em2800 devices without eeprom reports 0x91 on
- * CHIPCFG register, even not having an AC97 chip
- */
- em28xx_warn("AC97 chip type couldn't be determined\n");
- dev->audio_mode.ac97 = EM28XX_NO_AC97;
- dev->has_alsa_audio = false;
- dev->audio_mode.has_audio = false;
- goto init_audio;
- }
-
- vid2 = em28xx_read_ac97(dev, AC97_VENDOR_ID2);
- if (vid2 < 0)
- goto init_audio;
-
- vid = vid1 << 16 | vid2;
-
- dev->audio_mode.ac97_vendor_id = vid;
- em28xx_warn("AC97 vendor ID = 0x%08x\n", vid);
-
- feat = em28xx_read_ac97(dev, AC97_RESET);
- if (feat < 0)
- goto init_audio;
-
- dev->audio_mode.ac97_feat = feat;
- em28xx_warn("AC97 features = 0x%04x\n", feat);
-
- /* Try to identify what audio processor we have */
- if (((vid == 0xffffffff) || (vid == 0x83847650)) && (feat == 0x6a90))
- dev->audio_mode.ac97 = EM28XX_AC97_EM202;
- else if ((vid >> 8) == 0x838476)
- dev->audio_mode.ac97 = EM28XX_AC97_SIGMATEL;
-
-init_audio:
- /* Reports detected AC97 processor */
- switch (dev->audio_mode.ac97) {
- case EM28XX_NO_AC97:
- em28xx_info("No AC97 audio processor\n");
- break;
- case EM28XX_AC97_EM202:
- em28xx_info("Empia 202 AC97 audio processor detected\n");
- break;
- case EM28XX_AC97_SIGMATEL:
- em28xx_info("Sigmatel audio processor detected(stac 97%02x)\n",
- dev->audio_mode.ac97_vendor_id & 0xff);
- break;
- case EM28XX_AC97_OTHER:
- em28xx_warn("Unknown AC97 audio processor detected!\n");
- break;
- default:
- break;
- }
-
- return em28xx_audio_analog_set(dev);
-}
-EXPORT_SYMBOL_GPL(em28xx_audio_setup);
-
-int em28xx_colorlevels_set_default(struct em28xx *dev)
-{
- em28xx_write_reg(dev, EM28XX_R20_YGAIN, 0x10); /* contrast */
- em28xx_write_reg(dev, EM28XX_R21_YOFFSET, 0x00); /* brightness */
- em28xx_write_reg(dev, EM28XX_R22_UVGAIN, 0x10); /* saturation */
- em28xx_write_reg(dev, EM28XX_R23_UOFFSET, 0x00);
- em28xx_write_reg(dev, EM28XX_R24_VOFFSET, 0x00);
- em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, 0x00);
-
- em28xx_write_reg(dev, EM28XX_R14_GAMMA, 0x20);
- em28xx_write_reg(dev, EM28XX_R15_RGAIN, 0x20);
- em28xx_write_reg(dev, EM28XX_R16_GGAIN, 0x20);
- em28xx_write_reg(dev, EM28XX_R17_BGAIN, 0x20);
- em28xx_write_reg(dev, EM28XX_R18_ROFFSET, 0x00);
- em28xx_write_reg(dev, EM28XX_R19_GOFFSET, 0x00);
- return em28xx_write_reg(dev, EM28XX_R1A_BOFFSET, 0x00);
-}
-
-int em28xx_capture_start(struct em28xx *dev, int start)
-{
- int rc;
-
- if (dev->chip_id == CHIP_ID_EM2874 ||
- dev->chip_id == CHIP_ID_EM2884 ||
- dev->chip_id == CHIP_ID_EM28174) {
- /* The Transport Stream Enable Register moved in em2874 */
- if (!start) {
- rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE,
- 0x00,
- EM2874_TS1_CAPTURE_ENABLE);
- return rc;
- }
-
- /* Enable Transport Stream */
- rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE,
- EM2874_TS1_CAPTURE_ENABLE,
- EM2874_TS1_CAPTURE_ENABLE);
- return rc;
- }
-
-
- /* FIXME: which is the best order? */
- /* video registers are sampled by VREF */
- rc = em28xx_write_reg_bits(dev, EM28XX_R0C_USBSUSP,
- start ? 0x10 : 0x00, 0x10);
- if (rc < 0)
- return rc;
-
- if (!start) {
- /* disable video capture */
- rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x27);
- return rc;
- }
-
- if (dev->board.is_webcam)
- rc = em28xx_write_reg(dev, 0x13, 0x0c);
-
- /* enable video capture */
- rc = em28xx_write_reg(dev, 0x48, 0x00);
-
- if (dev->mode == EM28XX_ANALOG_MODE)
- rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67);
- else
- rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37);
-
- msleep(6);
-
- return rc;
-}
-
-int em28xx_vbi_supported(struct em28xx *dev)
-{
- /* Modprobe option to manually disable */
- if (disable_vbi == 1)
- return 0;
-
- if (dev->chip_id == CHIP_ID_EM2860 ||
- dev->chip_id == CHIP_ID_EM2883)
- return 1;
-
- /* Version of em28xx that does not support VBI */
- return 0;
-}
-
-int em28xx_set_outfmt(struct em28xx *dev)
-{
- int ret;
- u8 vinctrl;
-
- ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT,
- dev->format->reg | 0x20, 0xff);
- if (ret < 0)
- return ret;
-
- ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, dev->vinmode);
- if (ret < 0)
- return ret;
-
- vinctrl = dev->vinctl;
- if (em28xx_vbi_supported(dev) == 1) {
- vinctrl |= EM28XX_VINCTRL_VBI_RAW;
- em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00);
- em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, dev->vbi_width/4);
- em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, dev->vbi_height);
- if (dev->norm & V4L2_STD_525_60) {
- /* NTSC */
- em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
- } else if (dev->norm & V4L2_STD_625_50) {
- /* PAL */
- em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x07);
- }
- }
-
- return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl);
-}
-
-static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
- u8 ymin, u8 ymax)
-{
- em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n",
- xmin, ymin, xmax, ymax);
-
- em28xx_write_regs(dev, EM28XX_R28_XMIN, &xmin, 1);
- em28xx_write_regs(dev, EM28XX_R29_XMAX, &xmax, 1);
- em28xx_write_regs(dev, EM28XX_R2A_YMIN, &ymin, 1);
- return em28xx_write_regs(dev, EM28XX_R2B_YMAX, &ymax, 1);
-}
-
-static int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
- u16 width, u16 height)
-{
- u8 cwidth = width;
- u8 cheight = height;
- u8 overflow = (height >> 7 & 0x02) | (width >> 8 & 0x01);
-
- em28xx_coredbg("em28xx Area Set: (%d,%d)\n",
- (width | (overflow & 2) << 7),
- (height | (overflow & 1) << 8));
-
- em28xx_write_regs(dev, EM28XX_R1C_HSTART, &hstart, 1);
- em28xx_write_regs(dev, EM28XX_R1D_VSTART, &vstart, 1);
- em28xx_write_regs(dev, EM28XX_R1E_CWIDTH, &cwidth, 1);
- em28xx_write_regs(dev, EM28XX_R1F_CHEIGHT, &cheight, 1);
- return em28xx_write_regs(dev, EM28XX_R1B_OFLOW, &overflow, 1);
-}
-
-static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
-{
- u8 mode;
- /* the em2800 scaler only supports scaling down to 50% */
-
- if (dev->board.is_em2800) {
- mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
- } else {
- u8 buf[2];
-
- buf[0] = h;
- buf[1] = h >> 8;
- em28xx_write_regs(dev, EM28XX_R30_HSCALELOW, (char *)buf, 2);
-
- buf[0] = v;
- buf[1] = v >> 8;
- em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2);
- /* it seems that both H and V scalers must be active
- to work correctly */
- mode = (h || v) ? 0x30 : 0x00;
- }
- return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30);
-}
-
-/* FIXME: this only function read values from dev */
-int em28xx_resolution_set(struct em28xx *dev)
-{
- int width, height;
- width = norm_maxw(dev);
- height = norm_maxh(dev);
-
- /* Properly setup VBI */
- dev->vbi_width = 720;
- if (dev->norm & V4L2_STD_525_60)
- dev->vbi_height = 12;
- else
- dev->vbi_height = 18;
-
- if (!dev->progressive)
- height >>= norm_maxh(dev);
-
- em28xx_set_outfmt(dev);
-
-
- em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
-
- /* If we don't set the start position to 2 in VBI mode, we end up
- with line 20/21 being YUYV encoded instead of being in 8-bit
- greyscale. The core of the issue is that line 21 (and line 23 for
- PAL WSS) are inside of active video region, and as a result they
- get the pixelformatting associated with that area. So by cropping
- it out, we end up with the same format as the rest of the VBI
- region */
- if (em28xx_vbi_supported(dev) == 1)
- em28xx_capture_area_set(dev, 0, 2, width >> 2, height >> 2);
- else
- em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
-
- return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
-}
-
-int em28xx_set_alternate(struct em28xx *dev)
-{
- int errCode, prev_alt = dev->alt;
- int i;
- unsigned int min_pkt_size = dev->width * 2 + 4;
-
- /*
- * alt = 0 is used only for control messages, so, only values
- * greater than 0 can be used for streaming.
- */
- if (alt && alt < dev->num_alt) {
- em28xx_coredbg("alternate forced to %d\n", dev->alt);
- dev->alt = alt;
- goto set_alt;
- }
-
- /* When image size is bigger than a certain value,
- the frame size should be increased, otherwise, only
- green screen will be received.
- */
- if (dev->width * 2 * dev->height > 720 * 240 * 2)
- min_pkt_size *= 2;
-
- for (i = 0; i < dev->num_alt; i++) {
- /* stop when the selected alt setting offers enough bandwidth */
- if (dev->alt_max_pkt_size[i] >= min_pkt_size) {
- dev->alt = i;
- break;
- /* otherwise make sure that we end up with the maximum bandwidth
- because the min_pkt_size equation might be wrong...
- */
- } else if (dev->alt_max_pkt_size[i] >
- dev->alt_max_pkt_size[dev->alt])
- dev->alt = i;
- }
-
-set_alt:
- if (dev->alt != prev_alt) {
- em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
- min_pkt_size, dev->alt);
- dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];
- em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n",
- dev->alt, dev->max_pkt_size);
- errCode = usb_set_interface(dev->udev, 0, dev->alt);
- if (errCode < 0) {
- em28xx_errdev("cannot change alternate number to %d (error=%i)\n",
- dev->alt, errCode);
- return errCode;
- }
- }
- return 0;
-}
-
-int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio)
-{
- int rc = 0;
-
- if (!gpio)
- return rc;
-
- if (dev->mode != EM28XX_SUSPEND) {
- em28xx_write_reg(dev, 0x48, 0x00);
- if (dev->mode == EM28XX_ANALOG_MODE)
- em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67);
- else
- em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37);
- msleep(6);
- }
-
- /* Send GPIO reset sequences specified at board entry */
- while (gpio->sleep >= 0) {
- if (gpio->reg >= 0) {
- rc = em28xx_write_reg_bits(dev,
- gpio->reg,
- gpio->val,
- gpio->mask);
- if (rc < 0)
- return rc;
- }
- if (gpio->sleep > 0)
- msleep(gpio->sleep);
-
- gpio++;
- }
- return rc;
-}
-EXPORT_SYMBOL_GPL(em28xx_gpio_set);
-
-int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode)
-{
- if (dev->mode == set_mode)
- return 0;
-
- if (set_mode == EM28XX_SUSPEND) {
- dev->mode = set_mode;
-
- /* FIXME: add suspend support for ac97 */
-
- return em28xx_gpio_set(dev, dev->board.suspend_gpio);
- }
-
- dev->mode = set_mode;
-
- if (dev->mode == EM28XX_DIGITAL_MODE)
- return em28xx_gpio_set(dev, dev->board.dvb_gpio);
- else
- return em28xx_gpio_set(dev, INPUT(dev->ctl_input)->gpio);
-}
-EXPORT_SYMBOL_GPL(em28xx_set_mode);
-
-/* ------------------------------------------------------------------
- URB control
- ------------------------------------------------------------------*/
-
-/*
- * IRQ callback, called by URB callback
- */
-static void em28xx_irq_callback(struct urb *urb)
-{
- struct em28xx *dev = urb->context;
- int i;
-
- switch (urb->status) {
- case 0: /* success */
- case -ETIMEDOUT: /* NAK */
- break;
- case -ECONNRESET: /* kill */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- default: /* error */
- em28xx_isocdbg("urb completition error %d.\n", urb->status);
- break;
- }
-
- /* Copy data from URB */
- spin_lock(&dev->slock);
- dev->isoc_ctl.isoc_copy(dev, urb);
- spin_unlock(&dev->slock);
-
- /* Reset urb buffers */
- for (i = 0; i < urb->number_of_packets; i++) {
- urb->iso_frame_desc[i].status = 0;
- urb->iso_frame_desc[i].actual_length = 0;
- }
- urb->status = 0;
-
- urb->status = usb_submit_urb(urb, GFP_ATOMIC);
- if (urb->status) {
- em28xx_isocdbg("urb resubmit failed (error=%i)\n",
- urb->status);
- }
-}
-
-/*
- * Stop and Deallocate URBs
- */
-void em28xx_uninit_isoc(struct em28xx *dev, enum em28xx_mode mode)
-{
- struct urb *urb;
- struct em28xx_usb_isoc_bufs *isoc_bufs;
- int i;
-
- em28xx_isocdbg("em28xx: called em28xx_uninit_isoc in mode %d\n", mode);
-
- if (mode == EM28XX_DIGITAL_MODE)
- isoc_bufs = &dev->isoc_ctl.digital_bufs;
- else
- isoc_bufs = &dev->isoc_ctl.analog_bufs;
-
- for (i = 0; i < isoc_bufs->num_bufs; i++) {
- urb = isoc_bufs->urb[i];
- if (urb) {
- if (!irqs_disabled())
- usb_kill_urb(urb);
- else
- usb_unlink_urb(urb);
-
- if (isoc_bufs->transfer_buffer[i]) {
- usb_free_coherent(dev->udev,
- urb->transfer_buffer_length,
- isoc_bufs->transfer_buffer[i],
- urb->transfer_dma);
- }
- usb_free_urb(urb);
- isoc_bufs->urb[i] = NULL;
- }
- isoc_bufs->transfer_buffer[i] = NULL;
- }
-
- kfree(isoc_bufs->urb);
- kfree(isoc_bufs->transfer_buffer);
-
- isoc_bufs->urb = NULL;
- isoc_bufs->transfer_buffer = NULL;
- isoc_bufs->num_bufs = 0;
-
- em28xx_capture_start(dev, 0);
-}
-EXPORT_SYMBOL_GPL(em28xx_uninit_isoc);
-
-/*
- * Stop URBs
- */
-void em28xx_stop_urbs(struct em28xx *dev)
-{
- int i;
- struct urb *urb;
- struct em28xx_usb_isoc_bufs *isoc_bufs = &dev->isoc_ctl.digital_bufs;
-
- em28xx_isocdbg("em28xx: called em28xx_stop_urbs\n");
-
- for (i = 0; i < isoc_bufs->num_bufs; i++) {
- urb = isoc_bufs->urb[i];
- if (urb) {
- if (!irqs_disabled())
- usb_kill_urb(urb);
- else
- usb_unlink_urb(urb);
- }
- }
-
- em28xx_capture_start(dev, 0);
-}
-EXPORT_SYMBOL_GPL(em28xx_stop_urbs);
-
-/*
- * Allocate URBs
- */
-int em28xx_alloc_isoc(struct em28xx *dev, enum em28xx_mode mode,
- int max_packets, int num_bufs, int max_pkt_size)
-{
- struct em28xx_usb_isoc_bufs *isoc_bufs;
- int i;
- int sb_size, pipe;
- struct urb *urb;
- int j, k;
-
- em28xx_isocdbg("em28xx: called em28xx_alloc_isoc in mode %d\n", mode);
-
- if (mode == EM28XX_DIGITAL_MODE)
- isoc_bufs = &dev->isoc_ctl.digital_bufs;
- else
- isoc_bufs = &dev->isoc_ctl.analog_bufs;
-
- /* De-allocates all pending stuff */
- em28xx_uninit_isoc(dev, mode);
-
- isoc_bufs->num_bufs = num_bufs;
-
- isoc_bufs->urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
- if (!isoc_bufs->urb) {
- em28xx_errdev("cannot alloc memory for usb buffers\n");
- return -ENOMEM;
- }
-
- isoc_bufs->transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
- GFP_KERNEL);
- if (!isoc_bufs->transfer_buffer) {
- em28xx_errdev("cannot allocate memory for usb transfer\n");
- kfree(isoc_bufs->urb);
- return -ENOMEM;
- }
-
- isoc_bufs->max_pkt_size = max_pkt_size;
- isoc_bufs->num_packets = max_packets;
- dev->isoc_ctl.vid_buf = NULL;
- dev->isoc_ctl.vbi_buf = NULL;
-
- sb_size = isoc_bufs->num_packets * isoc_bufs->max_pkt_size;
-
- /* allocate urbs and transfer buffers */
- for (i = 0; i < isoc_bufs->num_bufs; i++) {
- urb = usb_alloc_urb(isoc_bufs->num_packets, GFP_KERNEL);
- if (!urb) {
- em28xx_err("cannot alloc isoc_ctl.urb %i\n", i);
- em28xx_uninit_isoc(dev, mode);
- return -ENOMEM;
- }
- isoc_bufs->urb[i] = urb;
-
- isoc_bufs->transfer_buffer[i] = usb_alloc_coherent(dev->udev,
- sb_size, GFP_KERNEL, &urb->transfer_dma);
- if (!isoc_bufs->transfer_buffer[i]) {
- em28xx_err("unable to allocate %i bytes for transfer"
- " buffer %i%s\n",
- sb_size, i,
- in_interrupt() ? " while in int" : "");
- em28xx_uninit_isoc(dev, mode);
- return -ENOMEM;
- }
- memset(isoc_bufs->transfer_buffer[i], 0, sb_size);
-
- /* FIXME: this is a hack - should be
- 'desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK'
- should also be using 'desc.bInterval'
- */
- pipe = usb_rcvisocpipe(dev->udev,
- mode == EM28XX_ANALOG_MODE ?
- EM28XX_EP_ANALOG : EM28XX_EP_DIGITAL);
-
- usb_fill_int_urb(urb, dev->udev, pipe,
- isoc_bufs->transfer_buffer[i], sb_size,
- em28xx_irq_callback, dev, 1);
-
- urb->number_of_packets = isoc_bufs->num_packets;
- urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
-
- k = 0;
- for (j = 0; j < isoc_bufs->num_packets; j++) {
- urb->iso_frame_desc[j].offset = k;
- urb->iso_frame_desc[j].length =
- isoc_bufs->max_pkt_size;
- k += isoc_bufs->max_pkt_size;
- }
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(em28xx_alloc_isoc);
-
-/*
- * Allocate URBs and start IRQ
- */
-int em28xx_init_isoc(struct em28xx *dev, enum em28xx_mode mode,
- int max_packets, int num_bufs, int max_pkt_size,
- int (*isoc_copy) (struct em28xx *dev, struct urb *urb))
-{
- struct em28xx_dmaqueue *dma_q = &dev->vidq;
- struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq;
- struct em28xx_usb_isoc_bufs *isoc_bufs;
- int i;
- int rc;
- int alloc;
-
- em28xx_isocdbg("em28xx: called em28xx_init_isoc in mode %d\n", mode);
-
- dev->isoc_ctl.isoc_copy = isoc_copy;
-
- if (mode == EM28XX_DIGITAL_MODE) {
- isoc_bufs = &dev->isoc_ctl.digital_bufs;
- /* no need to free/alloc isoc buffers in digital mode */
- alloc = 0;
- } else {
- isoc_bufs = &dev->isoc_ctl.analog_bufs;
- alloc = 1;
- }
-
- if (alloc) {
- rc = em28xx_alloc_isoc(dev, mode, max_packets,
- num_bufs, max_pkt_size);
- if (rc)
- return rc;
- }
-
- init_waitqueue_head(&dma_q->wq);
- init_waitqueue_head(&vbi_dma_q->wq);
-
- em28xx_capture_start(dev, 1);
-
- /* submit urbs and enables IRQ */
- for (i = 0; i < isoc_bufs->num_bufs; i++) {
- rc = usb_submit_urb(isoc_bufs->urb[i], GFP_ATOMIC);
- if (rc) {
- em28xx_err("submit of urb %i failed (error=%i)\n", i,
- rc);
- em28xx_uninit_isoc(dev, mode);
- return rc;
- }
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(em28xx_init_isoc);
-
-/*
- * em28xx_wake_i2c()
- * configure i2c attached devices
- */
-void em28xx_wake_i2c(struct em28xx *dev)
-{
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, 0);
- v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
- INPUT(dev->ctl_input)->vmux, 0, 0);
- v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
-}
-
-/*
- * Device control list
- */
-
-static LIST_HEAD(em28xx_devlist);
-static DEFINE_MUTEX(em28xx_devlist_mutex);
-
-/*
- * Extension interface
- */
-
-static LIST_HEAD(em28xx_extension_devlist);
-
-int em28xx_register_extension(struct em28xx_ops *ops)
-{
- struct em28xx *dev = NULL;
-
- mutex_lock(&em28xx_devlist_mutex);
- list_add_tail(&ops->next, &em28xx_extension_devlist);
- list_for_each_entry(dev, &em28xx_devlist, devlist) {
- ops->init(dev);
- }
- mutex_unlock(&em28xx_devlist_mutex);
- printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name);
- return 0;
-}
-EXPORT_SYMBOL(em28xx_register_extension);
-
-void em28xx_unregister_extension(struct em28xx_ops *ops)
-{
- struct em28xx *dev = NULL;
-
- mutex_lock(&em28xx_devlist_mutex);
- list_for_each_entry(dev, &em28xx_devlist, devlist) {
- ops->fini(dev);
- }
- list_del(&ops->next);
- mutex_unlock(&em28xx_devlist_mutex);
- printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
-}
-EXPORT_SYMBOL(em28xx_unregister_extension);
-
-void em28xx_init_extension(struct em28xx *dev)
-{
- const struct em28xx_ops *ops = NULL;
-
- mutex_lock(&em28xx_devlist_mutex);
- list_add_tail(&dev->devlist, &em28xx_devlist);
- list_for_each_entry(ops, &em28xx_extension_devlist, next) {
- if (ops->init)
- ops->init(dev);
- }
- mutex_unlock(&em28xx_devlist_mutex);
-}
-
-void em28xx_close_extension(struct em28xx *dev)
-{
- const struct em28xx_ops *ops = NULL;
-
- mutex_lock(&em28xx_devlist_mutex);
- list_for_each_entry(ops, &em28xx_extension_devlist, next) {
- if (ops->fini)
- ops->fini(dev);
- }
- list_del(&dev->devlist);
- mutex_unlock(&em28xx_devlist_mutex);
-}
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
deleted file mode 100644
index a16531fa937..00000000000
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ /dev/null
@@ -1,1197 +0,0 @@
-/*
- DVB device driver for em28xx
-
- (c) 2008-2011 Mauro Carvalho Chehab <mchehab@infradead.org>
-
- (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com>
- - Fixes for the driver to properly work with HVR-950
- - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick
- - Fixes for the driver to properly work with AMD ATI TV Wonder HD 600
-
- (c) 2008 Aidan Thornton <makosoft@googlemail.com>
-
- Based on cx88-dvb, saa7134-dvb and videobuf-dvb originally written by:
- (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
- (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License.
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-
-#include "em28xx.h"
-#include <media/v4l2-common.h>
-#include <media/videobuf-vmalloc.h>
-#include <media/tuner.h>
-#include "tuner-simple.h"
-
-#include "lgdt330x.h"
-#include "lgdt3305.h"
-#include "zl10353.h"
-#include "s5h1409.h"
-#include "mt352.h"
-#include "mt352_priv.h" /* FIXME */
-#include "tda1002x.h"
-#include "tda18271.h"
-#include "s921.h"
-#include "drxd.h"
-#include "cxd2820r.h"
-#include "tda18271c2dd.h"
-#include "drxk.h"
-#include "tda10071.h"
-#include "a8293.h"
-#include "qt1010.h"
-
-MODULE_DESCRIPTION("driver for em28xx based DVB cards");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_LICENSE("GPL");
-
-static unsigned int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debug messages [dvb]");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define dprintk(level, fmt, arg...) do { \
-if (debug >= level) \
- printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \
-} while (0)
-
-struct em28xx_dvb {
- struct dvb_frontend *fe[2];
-
- /* feed count management */
- struct mutex lock;
- int nfeeds;
-
- /* general boilerplate stuff */
- struct dvb_adapter adapter;
- struct dvb_demux demux;
- struct dmxdev dmxdev;
- struct dmx_frontend fe_hw;
- struct dmx_frontend fe_mem;
- struct dvb_net net;
-
- /* Due to DRX-K - probably need changes */
- int (*gate_ctrl)(struct dvb_frontend *, int);
- struct semaphore pll_mutex;
- bool dont_attach_fe1;
-};
-
-
-static inline void print_err_status(struct em28xx *dev,
- int packet, int status)
-{
- char *errmsg = "Unknown";
-
- switch (status) {
- case -ENOENT:
- errmsg = "unlinked synchronuously";
- break;
- case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
- break;
- case -ENOSR:
- errmsg = "Buffer error (overrun)";
- break;
- case -EPIPE:
- errmsg = "Stalled (device not responding)";
- break;
- case -EOVERFLOW:
- errmsg = "Babble (bad cable?)";
- break;
- case -EPROTO:
- errmsg = "Bit-stuff error (bad cable?)";
- break;
- case -EILSEQ:
- errmsg = "CRC/Timeout (could be anything)";
- break;
- case -ETIME:
- errmsg = "Device does not respond";
- break;
- }
- if (packet < 0) {
- dprintk(1, "URB status %d [%s].\n", status, errmsg);
- } else {
- dprintk(1, "URB packet %d, status %d [%s].\n",
- packet, status, errmsg);
- }
-}
-
-static inline int em28xx_dvb_isoc_copy(struct em28xx *dev, struct urb *urb)
-{
- int i;
-
- if (!dev)
- return 0;
-
- if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
- return 0;
-
- if (urb->status < 0) {
- print_err_status(dev, -1, urb->status);
- if (urb->status == -ENOENT)
- return 0;
- }
-
- for (i = 0; i < urb->number_of_packets; i++) {
- int status = urb->iso_frame_desc[i].status;
-
- if (status < 0) {
- print_err_status(dev, i, status);
- if (urb->iso_frame_desc[i].status != -EPROTO)
- continue;
- }
-
- dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer +
- urb->iso_frame_desc[i].offset,
- urb->iso_frame_desc[i].actual_length);
- }
-
- return 0;
-}
-
-static int em28xx_start_streaming(struct em28xx_dvb *dvb)
-{
- int rc;
- struct em28xx *dev = dvb->adapter.priv;
- int max_dvb_packet_size;
-
- usb_set_interface(dev->udev, 0, dev->dvb_alt);
- rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
- if (rc < 0)
- return rc;
-
- max_dvb_packet_size = dev->dvb_max_pkt_size;
- if (max_dvb_packet_size < 0)
- return max_dvb_packet_size;
- dprintk(1, "Using %d buffers each with %d x %d bytes\n",
- EM28XX_DVB_NUM_BUFS,
- EM28XX_DVB_MAX_PACKETS,
- max_dvb_packet_size);
-
- return em28xx_init_isoc(dev, EM28XX_DIGITAL_MODE,
- EM28XX_DVB_MAX_PACKETS, EM28XX_DVB_NUM_BUFS,
- max_dvb_packet_size, em28xx_dvb_isoc_copy);
-}
-
-static int em28xx_stop_streaming(struct em28xx_dvb *dvb)
-{
- struct em28xx *dev = dvb->adapter.priv;
-
- em28xx_stop_urbs(dev);
-
- em28xx_set_mode(dev, EM28XX_SUSPEND);
-
- return 0;
-}
-
-static int em28xx_start_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct em28xx_dvb *dvb = demux->priv;
- int rc, ret;
-
- if (!demux->dmx.frontend)
- return -EINVAL;
-
- mutex_lock(&dvb->lock);
- dvb->nfeeds++;
- rc = dvb->nfeeds;
-
- if (dvb->nfeeds == 1) {
- ret = em28xx_start_streaming(dvb);
- if (ret < 0)
- rc = ret;
- }
-
- mutex_unlock(&dvb->lock);
- return rc;
-}
-
-static int em28xx_stop_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct em28xx_dvb *dvb = demux->priv;
- int err = 0;
-
- mutex_lock(&dvb->lock);
- dvb->nfeeds--;
-
- if (0 == dvb->nfeeds)
- err = em28xx_stop_streaming(dvb);
-
- mutex_unlock(&dvb->lock);
- return err;
-}
-
-
-
-/* ------------------------------------------------------------------ */
-static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
-{
- struct em28xx *dev = fe->dvb->priv;
-
- if (acquire)
- return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
- else
- return em28xx_set_mode(dev, EM28XX_SUSPEND);
-}
-
-/* ------------------------------------------------------------------ */
-
-static struct lgdt330x_config em2880_lgdt3303_dev = {
- .demod_address = 0x0e,
- .demod_chip = LGDT3303,
-};
-
-static struct lgdt3305_config em2870_lgdt3304_dev = {
- .i2c_addr = 0x0e,
- .demod_chip = LGDT3304,
- .spectral_inversion = 1,
- .deny_i2c_rptr = 1,
- .mpeg_mode = LGDT3305_MPEG_PARALLEL,
- .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
- .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
- .vsb_if_khz = 3250,
- .qam_if_khz = 4000,
-};
-
-static struct s921_config sharp_isdbt = {
- .demod_address = 0x30 >> 1
-};
-
-static struct zl10353_config em28xx_zl10353_with_xc3028 = {
- .demod_address = (0x1e >> 1),
- .no_tuner = 1,
- .parallel_ts = 1,
- .if2 = 45600,
-};
-
-static struct s5h1409_config em28xx_s5h1409_with_xc3028 = {
- .demod_address = 0x32 >> 1,
- .output_mode = S5H1409_PARALLEL_OUTPUT,
- .gpio = S5H1409_GPIO_OFF,
- .inversion = S5H1409_INVERSION_OFF,
- .status_mode = S5H1409_DEMODLOCKING,
- .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
-};
-
-static struct tda18271_std_map kworld_a340_std_map = {
- .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 0,
- .if_lvl = 1, .rfagc_top = 0x37, },
- .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 1,
- .if_lvl = 1, .rfagc_top = 0x37, },
-};
-
-static struct tda18271_config kworld_a340_config = {
- .std_map = &kworld_a340_std_map,
-};
-
-static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = {
- .demod_address = (0x1e >> 1),
- .no_tuner = 1,
- .disable_i2c_gate_ctrl = 1,
- .parallel_ts = 1,
- .if2 = 45600,
-};
-
-static struct drxd_config em28xx_drxd = {
- .demod_address = 0x70,
- .demod_revision = 0xa2,
- .pll_type = DRXD_PLL_NONE,
- .clock = 12000,
- .insert_rs_byte = 1,
- .IF = 42800000,
- .disable_i2c_gate_ctrl = 1,
-};
-
-static struct drxk_config terratec_h5_drxk = {
- .adr = 0x29,
- .single_master = 1,
- .no_i2c_bridge = 1,
- .microcode_name = "dvb-usb-terratec-h5-drxk.fw",
- .qam_demod_parameter_count = 2,
-};
-
-static struct drxk_config hauppauge_930c_drxk = {
- .adr = 0x29,
- .single_master = 1,
- .no_i2c_bridge = 1,
- .microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw",
- .chunk_size = 56,
- .qam_demod_parameter_count = 2,
-};
-
-struct drxk_config terratec_htc_stick_drxk = {
- .adr = 0x29,
- .single_master = 1,
- .no_i2c_bridge = 1,
- .microcode_name = "dvb-usb-terratec-htc-stick-drxk.fw",
- .chunk_size = 54,
- .qam_demod_parameter_count = 2,
- /* Required for the antenna_gpio to disable LNA. */
- .antenna_dvbt = true,
- /* The windows driver uses the same. This will disable LNA. */
- .antenna_gpio = 0x6,
-};
-
-static struct drxk_config maxmedia_ub425_tc_drxk = {
- .adr = 0x29,
- .single_master = 1,
- .no_i2c_bridge = 1,
-};
-
-static struct drxk_config pctv_520e_drxk = {
- .adr = 0x29,
- .single_master = 1,
- .microcode_name = "dvb-demod-drxk-pctv.fw",
- .qam_demod_parameter_count = 2,
- .chunk_size = 58,
- .antenna_dvbt = true, /* disable LNA */
- .antenna_gpio = (1 << 2), /* disable LNA */
-};
-
-static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
- struct em28xx_dvb *dvb = fe->sec_priv;
- int status;
-
- if (!dvb)
- return -EINVAL;
-
- if (enable) {
- down(&dvb->pll_mutex);
- status = dvb->gate_ctrl(fe, 1);
- } else {
- status = dvb->gate_ctrl(fe, 0);
- up(&dvb->pll_mutex);
- }
- return status;
-}
-
-static void hauppauge_hvr930c_init(struct em28xx *dev)
-{
- int i;
-
- struct em28xx_reg_seq hauppauge_hvr930c_init[] = {
- {EM2874_R80_GPIO, 0xff, 0xff, 0x65},
- {EM2874_R80_GPIO, 0xfb, 0xff, 0x32},
- {EM2874_R80_GPIO, 0xff, 0xff, 0xb8},
- { -1, -1, -1, -1},
- };
- struct em28xx_reg_seq hauppauge_hvr930c_end[] = {
- {EM2874_R80_GPIO, 0xef, 0xff, 0x01},
- {EM2874_R80_GPIO, 0xaf, 0xff, 0x65},
- {EM2874_R80_GPIO, 0xef, 0xff, 0x76},
- {EM2874_R80_GPIO, 0xef, 0xff, 0x01},
- {EM2874_R80_GPIO, 0xcf, 0xff, 0x0b},
- {EM2874_R80_GPIO, 0xef, 0xff, 0x40},
-
- {EM2874_R80_GPIO, 0xcf, 0xff, 0x65},
- {EM2874_R80_GPIO, 0xef, 0xff, 0x65},
- {EM2874_R80_GPIO, 0xcf, 0xff, 0x0b},
- {EM2874_R80_GPIO, 0xef, 0xff, 0x65},
-
- { -1, -1, -1, -1},
- };
-
- struct {
- unsigned char r[4];
- int len;
- } regs[] = {
- {{ 0x06, 0x02, 0x00, 0x31 }, 4},
- {{ 0x01, 0x02 }, 2},
- {{ 0x01, 0x02, 0x00, 0xc6 }, 4},
- {{ 0x01, 0x00 }, 2},
- {{ 0x01, 0x00, 0xff, 0xaf }, 4},
- {{ 0x01, 0x00, 0x03, 0xa0 }, 4},
- {{ 0x01, 0x00 }, 2},
- {{ 0x01, 0x00, 0x73, 0xaf }, 4},
- {{ 0x04, 0x00 }, 2},
- {{ 0x00, 0x04 }, 2},
- {{ 0x00, 0x04, 0x00, 0x0a }, 4},
- {{ 0x04, 0x14 }, 2},
- {{ 0x04, 0x14, 0x00, 0x00 }, 4},
- };
-
- em28xx_gpio_set(dev, hauppauge_hvr930c_init);
- em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
- msleep(10);
- em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44);
- msleep(10);
-
- dev->i2c_client.addr = 0x82 >> 1;
-
- for (i = 0; i < ARRAY_SIZE(regs); i++)
- i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len);
- em28xx_gpio_set(dev, hauppauge_hvr930c_end);
-
- msleep(100);
-
- em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44);
- msleep(30);
-
- em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45);
- msleep(10);
-
-}
-
-static void terratec_h5_init(struct em28xx *dev)
-{
- int i;
- struct em28xx_reg_seq terratec_h5_init[] = {
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- {EM2874_R80_GPIO, 0xf6, 0xff, 100},
- {EM2874_R80_GPIO, 0xf2, 0xff, 50},
- {EM2874_R80_GPIO, 0xf6, 0xff, 100},
- { -1, -1, -1, -1},
- };
- struct em28xx_reg_seq terratec_h5_end[] = {
- {EM2874_R80_GPIO, 0xe6, 0xff, 100},
- {EM2874_R80_GPIO, 0xa6, 0xff, 50},
- {EM2874_R80_GPIO, 0xe6, 0xff, 100},
- { -1, -1, -1, -1},
- };
- struct {
- unsigned char r[4];
- int len;
- } regs[] = {
- {{ 0x06, 0x02, 0x00, 0x31 }, 4},
- {{ 0x01, 0x02 }, 2},
- {{ 0x01, 0x02, 0x00, 0xc6 }, 4},
- {{ 0x01, 0x00 }, 2},
- {{ 0x01, 0x00, 0xff, 0xaf }, 4},
- {{ 0x01, 0x00, 0x03, 0xa0 }, 4},
- {{ 0x01, 0x00 }, 2},
- {{ 0x01, 0x00, 0x73, 0xaf }, 4},
- {{ 0x04, 0x00 }, 2},
- {{ 0x00, 0x04 }, 2},
- {{ 0x00, 0x04, 0x00, 0x0a }, 4},
- {{ 0x04, 0x14 }, 2},
- {{ 0x04, 0x14, 0x00, 0x00 }, 4},
- };
-
- em28xx_gpio_set(dev, terratec_h5_init);
- em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
- msleep(10);
- em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45);
- msleep(10);
-
- dev->i2c_client.addr = 0x82 >> 1;
-
- for (i = 0; i < ARRAY_SIZE(regs); i++)
- i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len);
- em28xx_gpio_set(dev, terratec_h5_end);
-};
-
-static void terratec_htc_stick_init(struct em28xx *dev)
-{
- int i;
-
- /*
- * GPIO configuration:
- * 0xff: unknown (does not affect DVB-T).
- * 0xf6: DRX-K (demodulator).
- * 0xe6: unknown (does not affect DVB-T).
- * 0xb6: unknown (does not affect DVB-T).
- */
- struct em28xx_reg_seq terratec_htc_stick_init[] = {
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- {EM2874_R80_GPIO, 0xf6, 0xff, 100},
- {EM2874_R80_GPIO, 0xe6, 0xff, 50},
- {EM2874_R80_GPIO, 0xf6, 0xff, 100},
- { -1, -1, -1, -1},
- };
- struct em28xx_reg_seq terratec_htc_stick_end[] = {
- {EM2874_R80_GPIO, 0xb6, 0xff, 100},
- {EM2874_R80_GPIO, 0xf6, 0xff, 50},
- { -1, -1, -1, -1},
- };
-
- /* Init the analog decoder? */
- struct {
- unsigned char r[4];
- int len;
- } regs[] = {
- {{ 0x06, 0x02, 0x00, 0x31 }, 4},
- {{ 0x01, 0x02 }, 2},
- {{ 0x01, 0x02, 0x00, 0xc6 }, 4},
- {{ 0x01, 0x00 }, 2},
- {{ 0x01, 0x00, 0xff, 0xaf }, 4},
- };
-
- em28xx_gpio_set(dev, terratec_htc_stick_init);
-
- em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
- msleep(10);
- em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44);
- msleep(10);
-
- dev->i2c_client.addr = 0x82 >> 1;
-
- for (i = 0; i < ARRAY_SIZE(regs); i++)
- i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len);
-
- em28xx_gpio_set(dev, terratec_htc_stick_end);
-};
-
-static void pctv_520e_init(struct em28xx *dev)
-{
- /*
- * Init AVF4910B analog decoder. Looks like I2C traffic to
- * digital demodulator and tuner are routed via AVF4910B.
- */
- int i;
- struct {
- unsigned char r[4];
- int len;
- } regs[] = {
- {{ 0x06, 0x02, 0x00, 0x31 }, 4},
- {{ 0x01, 0x02 }, 2},
- {{ 0x01, 0x02, 0x00, 0xc6 }, 4},
- {{ 0x01, 0x00 }, 2},
- {{ 0x01, 0x00, 0xff, 0xaf }, 4},
- {{ 0x01, 0x00, 0x03, 0xa0 }, 4},
- {{ 0x01, 0x00 }, 2},
- {{ 0x01, 0x00, 0x73, 0xaf }, 4},
- };
-
- dev->i2c_client.addr = 0x82 >> 1; /* 0x41 */
-
- for (i = 0; i < ARRAY_SIZE(regs); i++)
- i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len);
-};
-
-static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe)
-{
- /* Values extracted from a USB trace of the Terratec Windows driver */
- static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x2c };
- static u8 reset[] = { RESET, 0x80 };
- static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 };
- static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0xa0 };
- static u8 input_freq_cfg[] = { INPUT_FREQ_1, 0x31, 0xb8 };
- static u8 rs_err_cfg[] = { RS_ERR_PER_1, 0x00, 0x4d };
- static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
- static u8 trl_nom_cfg[] = { TRL_NOMINAL_RATE_1, 0x64, 0x00 };
- static u8 tps_given_cfg[] = { TPS_GIVEN_1, 0x40, 0x80, 0x50 };
- static u8 tuner_go[] = { TUNER_GO, 0x01};
-
- mt352_write(fe, clock_config, sizeof(clock_config));
- udelay(200);
- mt352_write(fe, reset, sizeof(reset));
- mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
- mt352_write(fe, agc_cfg, sizeof(agc_cfg));
- mt352_write(fe, input_freq_cfg, sizeof(input_freq_cfg));
- mt352_write(fe, rs_err_cfg, sizeof(rs_err_cfg));
- mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
- mt352_write(fe, trl_nom_cfg, sizeof(trl_nom_cfg));
- mt352_write(fe, tps_given_cfg, sizeof(tps_given_cfg));
- mt352_write(fe, tuner_go, sizeof(tuner_go));
- return 0;
-}
-
-static struct mt352_config terratec_xs_mt352_cfg = {
- .demod_address = (0x1e >> 1),
- .no_tuner = 1,
- .if2 = 45600,
- .demod_init = em28xx_mt352_terratec_xs_init,
-};
-
-static struct tda10023_config em28xx_tda10023_config = {
- .demod_address = 0x0c,
- .invert = 1,
-};
-
-static struct cxd2820r_config em28xx_cxd2820r_config = {
- .i2c_address = (0xd8 >> 1),
- .ts_mode = CXD2820R_TS_SERIAL,
-
- /* enable LNA for DVB-T, DVB-T2 and DVB-C */
- .gpio_dvbt[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
- .gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
- .gpio_dvbc[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
-};
-
-static struct tda18271_config em28xx_cxd2820r_tda18271_config = {
- .output_opt = TDA18271_OUTPUT_LT_OFF,
- .gate = TDA18271_GATE_DIGITAL,
-};
-
-static const struct tda10071_config em28xx_tda10071_config = {
- .i2c_address = 0x55, /* (0xaa >> 1) */
- .i2c_wr_max = 64,
- .ts_mode = TDA10071_TS_SERIAL,
- .spec_inv = 0,
- .xtal = 40444000, /* 40.444 MHz */
- .pll_multiplier = 20,
-};
-
-static const struct a8293_config em28xx_a8293_config = {
- .i2c_addr = 0x08, /* (0x10 >> 1) */
-};
-
-static struct zl10353_config em28xx_zl10353_no_i2c_gate_dev = {
- .demod_address = (0x1e >> 1),
- .disable_i2c_gate_ctrl = 1,
- .no_tuner = 1,
- .parallel_ts = 1,
-};
-static struct qt1010_config em28xx_qt1010_config = {
- .i2c_address = 0x62
-
-};
-
-/* ------------------------------------------------------------------ */
-
-static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev)
-{
- struct dvb_frontend *fe;
- struct xc2028_config cfg;
-
- memset(&cfg, 0, sizeof(cfg));
- cfg.i2c_adap = &dev->i2c_adap;
- cfg.i2c_addr = addr;
-
- if (!dev->dvb->fe[0]) {
- em28xx_errdev("/2: dvb frontend not attached. "
- "Can't attach xc3028\n");
- return -EINVAL;
- }
-
- fe = dvb_attach(xc2028_attach, dev->dvb->fe[0], &cfg);
- if (!fe) {
- em28xx_errdev("/2: xc3028 attach failed\n");
- dvb_frontend_detach(dev->dvb->fe[0]);
- dev->dvb->fe[0] = NULL;
- return -EINVAL;
- }
-
- em28xx_info("%s/2: xc3028 attached\n", dev->name);
-
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module,
- struct em28xx *dev, struct device *device)
-{
- int result;
-
- mutex_init(&dvb->lock);
-
- /* register adapter */
- result = dvb_register_adapter(&dvb->adapter, dev->name, module, device,
- adapter_nr);
- if (result < 0) {
- printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n",
- dev->name, result);
- goto fail_adapter;
- }
-
- /* Ensure all frontends negotiate bus access */
- dvb->fe[0]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
- if (dvb->fe[1])
- dvb->fe[1]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
-
- dvb->adapter.priv = dev;
-
- /* register frontend */
- result = dvb_register_frontend(&dvb->adapter, dvb->fe[0]);
- if (result < 0) {
- printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
- dev->name, result);
- goto fail_frontend0;
- }
-
- /* register 2nd frontend */
- if (dvb->fe[1]) {
- result = dvb_register_frontend(&dvb->adapter, dvb->fe[1]);
- if (result < 0) {
- printk(KERN_WARNING "%s: 2nd dvb_register_frontend failed (errno = %d)\n",
- dev->name, result);
- goto fail_frontend1;
- }
- }
-
- /* register demux stuff */
- dvb->demux.dmx.capabilities =
- DMX_TS_FILTERING | DMX_SECTION_FILTERING |
- DMX_MEMORY_BASED_FILTERING;
- dvb->demux.priv = dvb;
- dvb->demux.filternum = 256;
- dvb->demux.feednum = 256;
- dvb->demux.start_feed = em28xx_start_feed;
- dvb->demux.stop_feed = em28xx_stop_feed;
-
- result = dvb_dmx_init(&dvb->demux);
- if (result < 0) {
- printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n",
- dev->name, result);
- goto fail_dmx;
- }
-
- dvb->dmxdev.filternum = 256;
- dvb->dmxdev.demux = &dvb->demux.dmx;
- dvb->dmxdev.capabilities = 0;
- result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
- if (result < 0) {
- printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
- dev->name, result);
- goto fail_dmxdev;
- }
-
- dvb->fe_hw.source = DMX_FRONTEND_0;
- result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- if (result < 0) {
- printk(KERN_WARNING "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
- dev->name, result);
- goto fail_fe_hw;
- }
-
- dvb->fe_mem.source = DMX_MEMORY_FE;
- result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
- if (result < 0) {
- printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
- dev->name, result);
- goto fail_fe_mem;
- }
-
- result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- if (result < 0) {
- printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n",
- dev->name, result);
- goto fail_fe_conn;
- }
-
- /* register network adapter */
- dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
- return 0;
-
-fail_fe_conn:
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
-fail_fe_mem:
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
-fail_fe_hw:
- dvb_dmxdev_release(&dvb->dmxdev);
-fail_dmxdev:
- dvb_dmx_release(&dvb->demux);
-fail_dmx:
- if (dvb->fe[1])
- dvb_unregister_frontend(dvb->fe[1]);
- dvb_unregister_frontend(dvb->fe[0]);
-fail_frontend1:
- if (dvb->fe[1])
- dvb_frontend_detach(dvb->fe[1]);
-fail_frontend0:
- dvb_frontend_detach(dvb->fe[0]);
- dvb_unregister_adapter(&dvb->adapter);
-fail_adapter:
- return result;
-}
-
-static void em28xx_unregister_dvb(struct em28xx_dvb *dvb)
-{
- dvb_net_release(&dvb->net);
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- dvb_dmxdev_release(&dvb->dmxdev);
- dvb_dmx_release(&dvb->demux);
- if (dvb->fe[1])
- dvb_unregister_frontend(dvb->fe[1]);
- dvb_unregister_frontend(dvb->fe[0]);
- if (dvb->fe[1] && !dvb->dont_attach_fe1)
- dvb_frontend_detach(dvb->fe[1]);
- dvb_frontend_detach(dvb->fe[0]);
- dvb_unregister_adapter(&dvb->adapter);
-}
-
-static int em28xx_dvb_init(struct em28xx *dev)
-{
- int result = 0, mfe_shared = 0;
- struct em28xx_dvb *dvb;
-
- if (!dev->board.has_dvb) {
- /* This device does not support the extension */
- printk(KERN_INFO "em28xx_dvb: This device does not support the extension\n");
- return 0;
- }
-
- dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL);
-
- if (dvb == NULL) {
- em28xx_info("em28xx_dvb: memory allocation failed\n");
- return -ENOMEM;
- }
- dev->dvb = dvb;
- dvb->fe[0] = dvb->fe[1] = NULL;
-
- mutex_lock(&dev->lock);
- em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
- /* init frontend */
- switch (dev->model) {
- case EM2874_BOARD_LEADERSHIP_ISDBT:
- dvb->fe[0] = dvb_attach(s921_attach,
- &sharp_isdbt, &dev->i2c_adap);
-
- if (!dvb->fe[0]) {
- result = -EINVAL;
- goto out_free;
- }
-
- break;
- case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
- case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
- case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
- case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
- dvb->fe[0] = dvb_attach(lgdt330x_attach,
- &em2880_lgdt3303_dev,
- &dev->i2c_adap);
- if (em28xx_attach_xc3028(0x61, dev) < 0) {
- result = -EINVAL;
- goto out_free;
- }
- break;
- case EM2880_BOARD_KWORLD_DVB_310U:
- dvb->fe[0] = dvb_attach(zl10353_attach,
- &em28xx_zl10353_with_xc3028,
- &dev->i2c_adap);
- if (em28xx_attach_xc3028(0x61, dev) < 0) {
- result = -EINVAL;
- goto out_free;
- }
- break;
- case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
- case EM2882_BOARD_TERRATEC_HYBRID_XS:
- case EM2880_BOARD_EMPIRE_DUAL_TV:
- dvb->fe[0] = dvb_attach(zl10353_attach,
- &em28xx_zl10353_xc3028_no_i2c_gate,
- &dev->i2c_adap);
- if (em28xx_attach_xc3028(0x61, dev) < 0) {
- result = -EINVAL;
- goto out_free;
- }
- break;
- case EM2880_BOARD_TERRATEC_HYBRID_XS:
- case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
- case EM2881_BOARD_PINNACLE_HYBRID_PRO:
- case EM2882_BOARD_DIKOM_DK300:
- case EM2882_BOARD_KWORLD_VS_DVBT:
- dvb->fe[0] = dvb_attach(zl10353_attach,
- &em28xx_zl10353_xc3028_no_i2c_gate,
- &dev->i2c_adap);
- if (dvb->fe[0] == NULL) {
- /* This board could have either a zl10353 or a mt352.
- If the chip id isn't for zl10353, try mt352 */
- dvb->fe[0] = dvb_attach(mt352_attach,
- &terratec_xs_mt352_cfg,
- &dev->i2c_adap);
- }
-
- if (em28xx_attach_xc3028(0x61, dev) < 0) {
- result = -EINVAL;
- goto out_free;
- }
- break;
- case EM2870_BOARD_KWORLD_355U:
- dvb->fe[0] = dvb_attach(zl10353_attach,
- &em28xx_zl10353_no_i2c_gate_dev,
- &dev->i2c_adap);
- if (dvb->fe[0] != NULL)
- dvb_attach(qt1010_attach, dvb->fe[0],
- &dev->i2c_adap, &em28xx_qt1010_config);
- break;
- case EM2883_BOARD_KWORLD_HYBRID_330U:
- case EM2882_BOARD_EVGA_INDTUBE:
- dvb->fe[0] = dvb_attach(s5h1409_attach,
- &em28xx_s5h1409_with_xc3028,
- &dev->i2c_adap);
- if (em28xx_attach_xc3028(0x61, dev) < 0) {
- result = -EINVAL;
- goto out_free;
- }
- break;
- case EM2882_BOARD_KWORLD_ATSC_315U:
- dvb->fe[0] = dvb_attach(lgdt330x_attach,
- &em2880_lgdt3303_dev,
- &dev->i2c_adap);
- if (dvb->fe[0] != NULL) {
- if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
- &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) {
- result = -EINVAL;
- goto out_free;
- }
- }
- break;
- case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
- case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
- dvb->fe[0] = dvb_attach(drxd_attach, &em28xx_drxd, NULL,
- &dev->i2c_adap, &dev->udev->dev);
- if (em28xx_attach_xc3028(0x61, dev) < 0) {
- result = -EINVAL;
- goto out_free;
- }
- break;
- case EM2870_BOARD_REDDO_DVB_C_USB_BOX:
- /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */
- dvb->fe[0] = dvb_attach(tda10023_attach,
- &em28xx_tda10023_config,
- &dev->i2c_adap, 0x48);
- if (dvb->fe[0]) {
- if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
- &dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) {
- result = -EINVAL;
- goto out_free;
- }
- }
- break;
- case EM2870_BOARD_KWORLD_A340:
- dvb->fe[0] = dvb_attach(lgdt3305_attach,
- &em2870_lgdt3304_dev,
- &dev->i2c_adap);
- if (dvb->fe[0] != NULL)
- dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
- &dev->i2c_adap, &kworld_a340_config);
- break;
- case EM28174_BOARD_PCTV_290E:
- dvb->fe[0] = dvb_attach(cxd2820r_attach,
- &em28xx_cxd2820r_config,
- &dev->i2c_adap);
- if (dvb->fe[0]) {
- /* FE 0 attach tuner */
- if (!dvb_attach(tda18271_attach,
- dvb->fe[0],
- 0x60,
- &dev->i2c_adap,
- &em28xx_cxd2820r_tda18271_config)) {
-
- dvb_frontend_detach(dvb->fe[0]);
- result = -EINVAL;
- goto out_free;
- }
- }
- break;
- case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C:
- {
- struct xc5000_config cfg;
- hauppauge_hvr930c_init(dev);
-
- dvb->fe[0] = dvb_attach(drxk_attach,
- &hauppauge_930c_drxk, &dev->i2c_adap);
- if (!dvb->fe[0]) {
- result = -EINVAL;
- goto out_free;
- }
- /* FIXME: do we need a pll semaphore? */
- dvb->fe[0]->sec_priv = dvb;
- sema_init(&dvb->pll_mutex, 1);
- dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl;
- dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
-
- /* Attach xc5000 */
- memset(&cfg, 0, sizeof(cfg));
- cfg.i2c_address = 0x61;
- cfg.if_khz = 4000;
-
- if (dvb->fe[0]->ops.i2c_gate_ctrl)
- dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1);
- if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap,
- &cfg)) {
- result = -EINVAL;
- goto out_free;
- }
- if (dvb->fe[0]->ops.i2c_gate_ctrl)
- dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0);
-
- break;
- }
- case EM2884_BOARD_TERRATEC_H5:
- terratec_h5_init(dev);
-
- dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap);
- if (!dvb->fe[0]) {
- result = -EINVAL;
- goto out_free;
- }
- /* FIXME: do we need a pll semaphore? */
- dvb->fe[0]->sec_priv = dvb;
- sema_init(&dvb->pll_mutex, 1);
- dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl;
- dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
-
- /* Attach tda18271 to DVB-C frontend */
- if (dvb->fe[0]->ops.i2c_gate_ctrl)
- dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1);
- if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], &dev->i2c_adap, 0x60)) {
- result = -EINVAL;
- goto out_free;
- }
- if (dvb->fe[0]->ops.i2c_gate_ctrl)
- dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0);
-
- break;
- case EM28174_BOARD_PCTV_460E:
- /* attach demod */
- dvb->fe[0] = dvb_attach(tda10071_attach,
- &em28xx_tda10071_config, &dev->i2c_adap);
-
- /* attach SEC */
- if (dvb->fe[0])
- dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap,
- &em28xx_a8293_config);
- break;
- case EM2874_BOARD_MAXMEDIA_UB425_TC:
- /* attach demodulator */
- dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk,
- &dev->i2c_adap);
-
- if (dvb->fe[0]) {
- /* disable I2C-gate */
- dvb->fe[0]->ops.i2c_gate_ctrl = NULL;
-
- /* attach tuner */
- if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0],
- &dev->i2c_adap, 0x60)) {
- dvb_frontend_detach(dvb->fe[0]);
- result = -EINVAL;
- goto out_free;
- }
- }
-
- /* TODO: we need drx-3913k firmware in order to support DVB-T */
- em28xx_info("MaxMedia UB425-TC: only DVB-C supported by that " \
- "driver version\n");
-
- break;
- case EM2884_BOARD_PCTV_510E:
- case EM2884_BOARD_PCTV_520E:
- pctv_520e_init(dev);
-
- /* attach demodulator */
- dvb->fe[0] = dvb_attach(drxk_attach, &pctv_520e_drxk,
- &dev->i2c_adap);
-
- if (dvb->fe[0]) {
- /* attach tuner */
- if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
- &dev->i2c_adap,
- &em28xx_cxd2820r_tda18271_config)) {
- dvb_frontend_detach(dvb->fe[0]);
- result = -EINVAL;
- goto out_free;
- }
- }
- break;
- case EM2884_BOARD_CINERGY_HTC_STICK:
- terratec_htc_stick_init(dev);
-
- /* attach demodulator */
- dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk,
- &dev->i2c_adap);
- if (!dvb->fe[0]) {
- result = -EINVAL;
- goto out_free;
- }
-
- /* Attach the demodulator. */
- if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
- &dev->i2c_adap,
- &em28xx_cxd2820r_tda18271_config)) {
- result = -EINVAL;
- goto out_free;
- }
- break;
- default:
- em28xx_errdev("/2: The frontend of your DVB/ATSC card"
- " isn't supported yet\n");
- break;
- }
- if (NULL == dvb->fe[0]) {
- em28xx_errdev("/2: frontend initialization failed\n");
- result = -EINVAL;
- goto out_free;
- }
- /* define general-purpose callback pointer */
- dvb->fe[0]->callback = em28xx_tuner_callback;
- if (dvb->fe[1])
- dvb->fe[1]->callback = em28xx_tuner_callback;
-
- /* register everything */
- result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);
-
- if (result < 0)
- goto out_free;
-
- /* MFE lock */
- dvb->adapter.mfe_shared = mfe_shared;
-
- em28xx_info("Successfully loaded em28xx-dvb\n");
-ret:
- em28xx_set_mode(dev, EM28XX_SUSPEND);
- mutex_unlock(&dev->lock);
- return result;
-
-out_free:
- kfree(dvb);
- dev->dvb = NULL;
- goto ret;
-}
-
-static inline void prevent_sleep(struct dvb_frontend_ops *ops)
-{
- ops->set_voltage = NULL;
- ops->sleep = NULL;
- ops->tuner_ops.sleep = NULL;
-}
-
-static int em28xx_dvb_fini(struct em28xx *dev)
-{
- if (!dev->board.has_dvb) {
- /* This device does not support the extension */
- return 0;
- }
-
- if (dev->dvb) {
- struct em28xx_dvb *dvb = dev->dvb;
-
- if (dev->state & DEV_DISCONNECTED) {
- /* We cannot tell the device to sleep
- * once it has been unplugged. */
- if (dvb->fe[0])
- prevent_sleep(&dvb->fe[0]->ops);
- if (dvb->fe[1])
- prevent_sleep(&dvb->fe[1]->ops);
- }
-
- em28xx_unregister_dvb(dvb);
- kfree(dvb);
- dev->dvb = NULL;
- }
-
- return 0;
-}
-
-static struct em28xx_ops dvb_ops = {
- .id = EM28XX_DVB,
- .name = "Em28xx dvb Extension",
- .init = em28xx_dvb_init,
- .fini = em28xx_dvb_fini,
-};
-
-static int __init em28xx_dvb_register(void)
-{
- return em28xx_register_extension(&dvb_ops);
-}
-
-static void __exit em28xx_dvb_unregister(void)
-{
- em28xx_unregister_extension(&dvb_ops);
-}
-
-module_init(em28xx_dvb_register);
-module_exit(em28xx_dvb_unregister);
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
deleted file mode 100644
index 1683bd9d51e..00000000000
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
-
- Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
- Markus Rechberger <mrechberger@gmail.com>
- Mauro Carvalho Chehab <mchehab@infradead.org>
- Sascha Sommer <saschasommer@freenet.de>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-
-#include "em28xx.h"
-#include "tuner-xc2028.h"
-#include <media/v4l2-common.h>
-#include <media/tuner.h>
-
-/* ----------------------------------------------------------- */
-
-static unsigned int i2c_scan;
-module_param(i2c_scan, int, 0444);
-MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
-
-static unsigned int i2c_debug;
-module_param(i2c_debug, int, 0644);
-MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
-
-#define dprintk2(lvl, fmt, args...) \
-do { \
- if (i2c_debug >= lvl) { \
- printk(KERN_DEBUG "%s at %s: " fmt, \
- dev->name, __func__ , ##args); \
- } \
-} while (0)
-
-/*
- * em2800_i2c_send_max4()
- * send up to 4 bytes to the i2c device
- */
-static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr,
- char *buf, int len)
-{
- int ret;
- int write_timeout;
- unsigned char b2[6];
- BUG_ON(len < 1 || len > 4);
- b2[5] = 0x80 + len - 1;
- b2[4] = addr;
- b2[3] = buf[0];
- if (len > 1)
- b2[2] = buf[1];
- if (len > 2)
- b2[1] = buf[2];
- if (len > 3)
- b2[0] = buf[3];
-
- ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len);
- if (ret != 2 + len) {
- em28xx_warn("writing to i2c device failed (error=%i)\n", ret);
- return -EIO;
- }
- for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
- write_timeout -= 5) {
- ret = dev->em28xx_read_reg(dev, 0x05);
- if (ret == 0x80 + len - 1)
- return len;
- msleep(5);
- }
- em28xx_warn("i2c write timed out\n");
- return -EIO;
-}
-
-/*
- * em2800_i2c_send_bytes()
- */
-static int em2800_i2c_send_bytes(void *data, unsigned char addr, char *buf,
- short len)
-{
- char *bufPtr = buf;
- int ret;
- int wrcount = 0;
- int count;
- int maxLen = 4;
- struct em28xx *dev = (struct em28xx *)data;
- while (len > 0) {
- count = (len > maxLen) ? maxLen : len;
- ret = em2800_i2c_send_max4(dev, addr, bufPtr, count);
- if (ret > 0) {
- len -= count;
- bufPtr += count;
- wrcount += count;
- } else
- return (ret < 0) ? ret : -EFAULT;
- }
- return wrcount;
-}
-
-/*
- * em2800_i2c_check_for_device()
- * check if there is a i2c_device at the supplied address
- */
-static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
-{
- char msg;
- int ret;
- int write_timeout;
- msg = addr;
- ret = dev->em28xx_write_regs(dev, 0x04, &msg, 1);
- if (ret < 0) {
- em28xx_warn("setting i2c device address failed (error=%i)\n",
- ret);
- return ret;
- }
- msg = 0x84;
- ret = dev->em28xx_write_regs(dev, 0x05, &msg, 1);
- if (ret < 0) {
- em28xx_warn("preparing i2c read failed (error=%i)\n", ret);
- return ret;
- }
- for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
- write_timeout -= 5) {
- unsigned reg = dev->em28xx_read_reg(dev, 0x5);
-
- if (reg == 0x94)
- return -ENODEV;
- else if (reg == 0x84)
- return 0;
- msleep(5);
- }
- return -ENODEV;
-}
-
-/*
- * em2800_i2c_recv_bytes()
- * read from the i2c device
- */
-static int em2800_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,
- char *buf, int len)
-{
- int ret;
- /* check for the device and set i2c read address */
- ret = em2800_i2c_check_for_device(dev, addr);
- if (ret) {
- em28xx_warn
- ("preparing read at i2c address 0x%x failed (error=%i)\n",
- addr, ret);
- return ret;
- }
- ret = dev->em28xx_read_reg_req_len(dev, 0x0, 0x3, buf, len);
- if (ret < 0) {
- em28xx_warn("reading from i2c device at 0x%x failed (error=%i)",
- addr, ret);
- return ret;
- }
- return ret;
-}
-
-/*
- * em28xx_i2c_send_bytes()
- */
-static int em28xx_i2c_send_bytes(void *data, unsigned char addr, char *buf,
- short len, int stop)
-{
- int wrcount = 0;
- struct em28xx *dev = (struct em28xx *)data;
- int write_timeout, ret;
-
- wrcount = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len);
-
- /* Seems to be required after a write */
- for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
- write_timeout -= 5) {
- ret = dev->em28xx_read_reg(dev, 0x05);
- if (!ret)
- break;
- msleep(5);
- }
-
- return wrcount;
-}
-
-/*
- * em28xx_i2c_recv_bytes()
- * read a byte from the i2c device
- */
-static int em28xx_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,
- char *buf, int len)
-{
- int ret;
- ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len);
- if (ret < 0) {
- em28xx_warn("reading i2c device failed (error=%i)\n", ret);
- return ret;
- }
- if (dev->em28xx_read_reg(dev, 0x5) != 0)
- return -ENODEV;
- return ret;
-}
-
-/*
- * em28xx_i2c_check_for_device()
- * check if there is a i2c_device at the supplied address
- */
-static int em28xx_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
-{
- int ret;
-
- ret = dev->em28xx_read_reg_req(dev, 2, addr);
- if (ret < 0) {
- em28xx_warn("reading from i2c device failed (error=%i)\n", ret);
- return ret;
- }
- if (dev->em28xx_read_reg(dev, 0x5) != 0)
- return -ENODEV;
- return 0;
-}
-
-/*
- * em28xx_i2c_xfer()
- * the main i2c transfer function
- */
-static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg msgs[], int num)
-{
- struct em28xx *dev = i2c_adap->algo_data;
- int addr, rc, i, byte;
-
- if (num <= 0)
- return 0;
- for (i = 0; i < num; i++) {
- addr = msgs[i].addr << 1;
- dprintk2(2, "%s %s addr=%x len=%d:",
- (msgs[i].flags & I2C_M_RD) ? "read" : "write",
- i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
- if (!msgs[i].len) { /* no len: check only for device presence */
- if (dev->board.is_em2800)
- rc = em2800_i2c_check_for_device(dev, addr);
- else
- rc = em28xx_i2c_check_for_device(dev, addr);
- if (rc < 0) {
- dprintk2(2, " no device\n");
- return rc;
- }
-
- } else if (msgs[i].flags & I2C_M_RD) {
- /* read bytes */
- if (dev->board.is_em2800)
- rc = em2800_i2c_recv_bytes(dev, addr,
- msgs[i].buf,
- msgs[i].len);
- else
- rc = em28xx_i2c_recv_bytes(dev, addr,
- msgs[i].buf,
- msgs[i].len);
- if (i2c_debug >= 2) {
- for (byte = 0; byte < msgs[i].len; byte++)
- printk(" %02x", msgs[i].buf[byte]);
- }
- } else {
- /* write bytes */
- if (i2c_debug >= 2) {
- for (byte = 0; byte < msgs[i].len; byte++)
- printk(" %02x", msgs[i].buf[byte]);
- }
- if (dev->board.is_em2800)
- rc = em2800_i2c_send_bytes(dev, addr,
- msgs[i].buf,
- msgs[i].len);
- else
- rc = em28xx_i2c_send_bytes(dev, addr,
- msgs[i].buf,
- msgs[i].len,
- i == num - 1);
- }
- if (rc < 0)
- goto err;
- if (i2c_debug >= 2)
- printk("\n");
- }
-
- return num;
-err:
- dprintk2(2, " ERROR: %i\n", rc);
- return rc;
-}
-
-/* based on linux/sunrpc/svcauth.h and linux/hash.h
- * The original hash function returns a different value, if arch is x86_64
- * or i386.
- */
-static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits)
-{
- unsigned long hash = 0;
- unsigned long l = 0;
- int len = 0;
- unsigned char c;
- do {
- if (len == length) {
- c = (char)len;
- len = -1;
- } else
- c = *buf++;
- l = (l << 8) | c;
- len++;
- if ((len & (32 / 8 - 1)) == 0)
- hash = ((hash^l) * 0x9e370001UL);
- } while (len);
-
- return (hash >> (32 - bits)) & 0xffffffffUL;
-}
-
-static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
-{
- unsigned char buf, *p = eedata;
- struct em28xx_eeprom *em_eeprom = (void *)eedata;
- int i, err, size = len, block;
-
- if (dev->chip_id == CHIP_ID_EM2874 ||
- dev->chip_id == CHIP_ID_EM28174 ||
- dev->chip_id == CHIP_ID_EM2884) {
- /* Empia switched to a 16-bit addressable eeprom in newer
- devices. While we could certainly write a routine to read
- the eeprom, there is nothing of use in there that cannot be
- accessed through registers, and there is the risk that we
- could corrupt the eeprom (since a 16-bit read call is
- interpreted as a write call by 8-bit eeproms).
- */
- return 0;
- }
-
- dev->i2c_client.addr = 0xa0 >> 1;
-
- /* Check if board has eeprom */
- err = i2c_master_recv(&dev->i2c_client, &buf, 0);
- if (err < 0) {
- em28xx_errdev("board has no eeprom\n");
- memset(eedata, 0, len);
- return -ENODEV;
- }
-
- buf = 0;
-
- err = i2c_master_send(&dev->i2c_client, &buf, 1);
- if (err != 1) {
- printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
- dev->name, err);
- return err;
- }
- while (size > 0) {
- if (size > 16)
- block = 16;
- else
- block = size;
-
- if (block !=
- (err = i2c_master_recv(&dev->i2c_client, p, block))) {
- printk(KERN_WARNING
- "%s: i2c eeprom read error (err=%d)\n",
- dev->name, err);
- return err;
- }
- size -= block;
- p += block;
- }
- for (i = 0; i < len; i++) {
- if (0 == (i % 16))
- printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);
- printk(" %02x", eedata[i]);
- if (15 == (i % 16))
- printk("\n");
- }
-
- if (em_eeprom->id == 0x9567eb1a)
- dev->hash = em28xx_hash_mem(eedata, len, 32);
-
- printk(KERN_INFO "%s: EEPROM ID= 0x%08x, EEPROM hash = 0x%08lx\n",
- dev->name, em_eeprom->id, dev->hash);
-
- printk(KERN_INFO "%s: EEPROM info:\n", dev->name);
-
- switch (em_eeprom->chip_conf >> 4 & 0x3) {
- case 0:
- printk(KERN_INFO "%s:\tNo audio on board.\n", dev->name);
- break;
- case 1:
- printk(KERN_INFO "%s:\tAC97 audio (5 sample rates)\n",
- dev->name);
- break;
- case 2:
- printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n",
- dev->name);
- break;
- case 3:
- printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n",
- dev->name);
- break;
- }
-
- if (em_eeprom->chip_conf & 1 << 3)
- printk(KERN_INFO "%s:\tUSB Remote wakeup capable\n", dev->name);
-
- if (em_eeprom->chip_conf & 1 << 2)
- printk(KERN_INFO "%s:\tUSB Self power capable\n", dev->name);
-
- switch (em_eeprom->chip_conf & 0x3) {
- case 0:
- printk(KERN_INFO "%s:\t500mA max power\n", dev->name);
- break;
- case 1:
- printk(KERN_INFO "%s:\t400mA max power\n", dev->name);
- break;
- case 2:
- printk(KERN_INFO "%s:\t300mA max power\n", dev->name);
- break;
- case 3:
- printk(KERN_INFO "%s:\t200mA max power\n", dev->name);
- break;
- }
- printk(KERN_INFO "%s:\tTable at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n",
- dev->name,
- em_eeprom->string_idx_table,
- em_eeprom->string1,
- em_eeprom->string2,
- em_eeprom->string3);
-
- return 0;
-}
-
-/* ----------------------------------------------------------- */
-
-/*
- * functionality()
- */
-static u32 functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_SMBUS_EMUL;
-}
-
-static struct i2c_algorithm em28xx_algo = {
- .master_xfer = em28xx_i2c_xfer,
- .functionality = functionality,
-};
-
-static struct i2c_adapter em28xx_adap_template = {
- .owner = THIS_MODULE,
- .name = "em28xx",
- .algo = &em28xx_algo,
-};
-
-static struct i2c_client em28xx_client_template = {
- .name = "em28xx internal",
-};
-
-/* ----------------------------------------------------------- */
-
-/*
- * i2c_devs
- * incomplete list of known devices
- */
-static char *i2c_devs[128] = {
- [0x4a >> 1] = "saa7113h",
- [0x52 >> 1] = "drxk",
- [0x60 >> 1] = "remote IR sensor",
- [0x8e >> 1] = "remote IR sensor",
- [0x86 >> 1] = "tda9887",
- [0x80 >> 1] = "msp34xx",
- [0x88 >> 1] = "msp34xx",
- [0xa0 >> 1] = "eeprom",
- [0xb0 >> 1] = "tda9874",
- [0xb8 >> 1] = "tvp5150a",
- [0xba >> 1] = "webcam sensor or tvp5150a",
- [0xc0 >> 1] = "tuner (analog)",
- [0xc2 >> 1] = "tuner (analog)",
- [0xc4 >> 1] = "tuner (analog)",
- [0xc6 >> 1] = "tuner (analog)",
-};
-
-/*
- * do_i2c_scan()
- * check i2c address range for devices
- */
-void em28xx_do_i2c_scan(struct em28xx *dev)
-{
- u8 i2c_devicelist[128];
- unsigned char buf;
- int i, rc;
-
- memset(i2c_devicelist, 0, ARRAY_SIZE(i2c_devicelist));
-
- for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
- dev->i2c_client.addr = i;
- rc = i2c_master_recv(&dev->i2c_client, &buf, 0);
- if (rc < 0)
- continue;
- i2c_devicelist[i] = i;
- printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n",
- dev->name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
- }
-
- dev->i2c_hash = em28xx_hash_mem(i2c_devicelist,
- ARRAY_SIZE(i2c_devicelist), 32);
-}
-
-/*
- * em28xx_i2c_register()
- * register i2c bus
- */
-int em28xx_i2c_register(struct em28xx *dev)
-{
- int retval;
-
- BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg);
- BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req);
- dev->i2c_adap = em28xx_adap_template;
- dev->i2c_adap.dev.parent = &dev->udev->dev;
- strcpy(dev->i2c_adap.name, dev->name);
- dev->i2c_adap.algo_data = dev;
- i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
-
- retval = i2c_add_adapter(&dev->i2c_adap);
- if (retval < 0) {
- em28xx_errdev("%s: i2c_add_adapter failed! retval [%d]\n",
- __func__, retval);
- return retval;
- }
-
- dev->i2c_client = em28xx_client_template;
- dev->i2c_client.adapter = &dev->i2c_adap;
-
- retval = em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata));
- if ((retval < 0) && (retval != -ENODEV)) {
- em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n",
- __func__, retval);
-
- return retval;
- }
-
- if (i2c_scan)
- em28xx_do_i2c_scan(dev);
-
- return 0;
-}
-
-/*
- * em28xx_i2c_unregister()
- * unregister i2c_bus
- */
-int em28xx_i2c_unregister(struct em28xx *dev)
-{
- i2c_del_adapter(&dev->i2c_adap);
- return 0;
-}
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
deleted file mode 100644
index 97d36b4f19d..00000000000
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
- handle em28xx IR remotes via linux kernel input layer.
-
- Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
- Markus Rechberger <mrechberger@gmail.com>
- Mauro Carvalho Chehab <mchehab@infradead.org>
- Sascha Sommer <saschasommer@freenet.de>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/usb.h>
-#include <linux/slab.h>
-
-#include "em28xx.h"
-
-#define EM28XX_SNAPSHOT_KEY KEY_CAMERA
-#define EM28XX_SBUTTON_QUERY_INTERVAL 500
-#define EM28XX_R0C_USBSUSP_SNAPSHOT 0x20
-
-static unsigned int ir_debug;
-module_param(ir_debug, int, 0644);
-MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
-
-#define MODULE_NAME "em28xx"
-
-#define i2cdprintk(fmt, arg...) \
- if (ir_debug) { \
- printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
- }
-
-#define dprintk(fmt, arg...) \
- if (ir_debug) { \
- printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
- }
-
-/**********************************************************
- Polling structure used by em28xx IR's
- **********************************************************/
-
-struct em28xx_ir_poll_result {
- unsigned int toggle_bit:1;
- unsigned int read_count:7;
- u8 rc_address;
- u8 rc_data[4]; /* 1 byte on em2860/2880, 4 on em2874 */
-};
-
-struct em28xx_IR {
- struct em28xx *dev;
- struct rc_dev *rc;
- char name[32];
- char phys[32];
-
- /* poll external decoder */
- int polling;
- struct delayed_work work;
- unsigned int full_code:1;
- unsigned int last_readcount;
-
- int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
-};
-
-/**********************************************************
- I2C IR based get keycodes - should be used with ir-kbd-i2c
- **********************************************************/
-
-static int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- unsigned char b;
-
- /* poll IR chip */
- if (1 != i2c_master_recv(ir->c, &b, 1)) {
- i2cdprintk("read error\n");
- return -EIO;
- }
-
- /* it seems that 0xFE indicates that a button is still hold
- down, while 0xff indicates that no button is hold
- down. 0xfe sequences are sometimes interrupted by 0xFF */
-
- i2cdprintk("key %02x\n", b);
-
- if (b == 0xff)
- return 0;
-
- if (b == 0xfe)
- /* keep old data */
- return 1;
-
- *ir_key = b;
- *ir_raw = b;
- return 1;
-}
-
-static int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- unsigned char buf[2];
- u16 code;
- int size;
-
- /* poll IR chip */
- size = i2c_master_recv(ir->c, buf, sizeof(buf));
-
- if (size != 2)
- return -EIO;
-
- /* Does eliminate repeated parity code */
- if (buf[1] == 0xff)
- return 0;
-
- ir->old = buf[1];
-
- /*
- * Rearranges bits to the right order.
- * The bit order were determined experimentally by using
- * The original Hauppauge Grey IR and another RC5 that uses addr=0x08
- * The RC5 code has 14 bits, but we've experimentally determined
- * the meaning for only 11 bits.
- * So, the code translation is not complete. Yet, it is enough to
- * work with the provided RC5 IR.
- */
- code =
- ((buf[0] & 0x01) ? 0x0020 : 0) | /* 0010 0000 */
- ((buf[0] & 0x02) ? 0x0010 : 0) | /* 0001 0000 */
- ((buf[0] & 0x04) ? 0x0008 : 0) | /* 0000 1000 */
- ((buf[0] & 0x08) ? 0x0004 : 0) | /* 0000 0100 */
- ((buf[0] & 0x10) ? 0x0002 : 0) | /* 0000 0010 */
- ((buf[0] & 0x20) ? 0x0001 : 0) | /* 0000 0001 */
- ((buf[1] & 0x08) ? 0x1000 : 0) | /* 0001 0000 */
- ((buf[1] & 0x10) ? 0x0800 : 0) | /* 0000 1000 */
- ((buf[1] & 0x20) ? 0x0400 : 0) | /* 0000 0100 */
- ((buf[1] & 0x40) ? 0x0200 : 0) | /* 0000 0010 */
- ((buf[1] & 0x80) ? 0x0100 : 0); /* 0000 0001 */
-
- i2cdprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x%02x)\n",
- code, buf[1], buf[0]);
-
- /* return key */
- *ir_key = code;
- *ir_raw = code;
- return 1;
-}
-
-static int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
- u32 *ir_raw)
-{
- unsigned char buf[3];
-
- /* poll IR chip */
-
- if (3 != i2c_master_recv(ir->c, buf, 3)) {
- i2cdprintk("read error\n");
- return -EIO;
- }
-
- i2cdprintk("key %02x\n", buf[2]&0x3f);
- if (buf[0] != 0x00)
- return 0;
-
- *ir_key = buf[2]&0x3f;
- *ir_raw = buf[2]&0x3f;
-
- return 1;
-}
-
-static int em28xx_get_key_winfast_usbii_deluxe(struct IR_i2c *ir, u32 *ir_key,
- u32 *ir_raw)
-{
- unsigned char subaddr, keydetect, key;
-
- struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0, .buf = &subaddr, .len = 1},
-
- { .addr = ir->c->addr, .flags = I2C_M_RD, .buf = &keydetect, .len = 1} };
-
- subaddr = 0x10;
- if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
- i2cdprintk("read error\n");
- return -EIO;
- }
- if (keydetect == 0x00)
- return 0;
-
- subaddr = 0x00;
- msg[1].buf = &key;
- if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
- i2cdprintk("read error\n");
- return -EIO;
- }
- if (key == 0x00)
- return 0;
-
- *ir_key = key;
- *ir_raw = key;
- return 1;
-}
-
-/**********************************************************
- Poll based get keycode functions
- **********************************************************/
-
-/* This is for the em2860/em2880 */
-static int default_polling_getkey(struct em28xx_IR *ir,
- struct em28xx_ir_poll_result *poll_result)
-{
- struct em28xx *dev = ir->dev;
- int rc;
- u8 msg[3] = { 0, 0, 0 };
-
- /* Read key toggle, brand, and key code
- on registers 0x45, 0x46 and 0x47
- */
- rc = dev->em28xx_read_reg_req_len(dev, 0, EM28XX_R45_IR,
- msg, sizeof(msg));
- if (rc < 0)
- return rc;
-
- /* Infrared toggle (Reg 0x45[7]) */
- poll_result->toggle_bit = (msg[0] >> 7);
-
- /* Infrared read count (Reg 0x45[6:0] */
- poll_result->read_count = (msg[0] & 0x7f);
-
- /* Remote Control Address (Reg 0x46) */
- poll_result->rc_address = msg[1];
-
- /* Remote Control Data (Reg 0x47) */
- poll_result->rc_data[0] = msg[2];
-
- return 0;
-}
-
-static int em2874_polling_getkey(struct em28xx_IR *ir,
- struct em28xx_ir_poll_result *poll_result)
-{
- struct em28xx *dev = ir->dev;
- int rc;
- u8 msg[5] = { 0, 0, 0, 0, 0 };
-
- /* Read key toggle, brand, and key code
- on registers 0x51-55
- */
- rc = dev->em28xx_read_reg_req_len(dev, 0, EM2874_R51_IR,
- msg, sizeof(msg));
- if (rc < 0)
- return rc;
-
- /* Infrared toggle (Reg 0x51[7]) */
- poll_result->toggle_bit = (msg[0] >> 7);
-
- /* Infrared read count (Reg 0x51[6:0] */
- poll_result->read_count = (msg[0] & 0x7f);
-
- /* Remote Control Address (Reg 0x52) */
- poll_result->rc_address = msg[1];
-
- /* Remote Control Data (Reg 0x53-55) */
- poll_result->rc_data[0] = msg[2];
- poll_result->rc_data[1] = msg[3];
- poll_result->rc_data[2] = msg[4];
-
- return 0;
-}
-
-/**********************************************************
- Polling code for em28xx
- **********************************************************/
-
-static void em28xx_ir_handle_key(struct em28xx_IR *ir)
-{
- int result;
- struct em28xx_ir_poll_result poll_result;
-
- /* read the registers containing the IR status */
- result = ir->get_key(ir, &poll_result);
- if (unlikely(result < 0)) {
- dprintk("ir->get_key() failed %d\n", result);
- return;
- }
-
- if (unlikely(poll_result.read_count != ir->last_readcount)) {
- dprintk("%s: toggle: %d, count: %d, key 0x%02x%02x\n", __func__,
- poll_result.toggle_bit, poll_result.read_count,
- poll_result.rc_address, poll_result.rc_data[0]);
- if (ir->full_code)
- rc_keydown(ir->rc,
- poll_result.rc_address << 8 |
- poll_result.rc_data[0],
- poll_result.toggle_bit);
- else
- rc_keydown(ir->rc,
- poll_result.rc_data[0],
- poll_result.toggle_bit);
-
- if (ir->dev->chip_id == CHIP_ID_EM2874 ||
- ir->dev->chip_id == CHIP_ID_EM2884)
- /* The em2874 clears the readcount field every time the
- register is read. The em2860/2880 datasheet says that it
- is supposed to clear the readcount, but it doesn't. So with
- the em2874, we are looking for a non-zero read count as
- opposed to a readcount that is incrementing */
- ir->last_readcount = 0;
- else
- ir->last_readcount = poll_result.read_count;
- }
-}
-
-static void em28xx_ir_work(struct work_struct *work)
-{
- struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work.work);
-
- em28xx_ir_handle_key(ir);
- schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
-}
-
-static int em28xx_ir_start(struct rc_dev *rc)
-{
- struct em28xx_IR *ir = rc->priv;
-
- INIT_DELAYED_WORK(&ir->work, em28xx_ir_work);
- schedule_delayed_work(&ir->work, 0);
-
- return 0;
-}
-
-static void em28xx_ir_stop(struct rc_dev *rc)
-{
- struct em28xx_IR *ir = rc->priv;
-
- cancel_delayed_work_sync(&ir->work);
-}
-
-static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type)
-{
- int rc = 0;
- struct em28xx_IR *ir = rc_dev->priv;
- struct em28xx *dev = ir->dev;
- u8 ir_config = EM2874_IR_RC5;
-
- /* Adjust xclk based o IR table for RC5/NEC tables */
-
- if (rc_type == RC_TYPE_RC5) {
- dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
- ir->full_code = 1;
- } else if (rc_type == RC_TYPE_NEC) {
- dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
- ir_config = EM2874_IR_NEC;
- ir->full_code = 1;
- } else if (rc_type != RC_TYPE_UNKNOWN)
- rc = -EINVAL;
-
- em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
- EM28XX_XCLK_IR_RC5_MODE);
-
- /* Setup the proper handler based on the chip */
- switch (dev->chip_id) {
- case CHIP_ID_EM2860:
- case CHIP_ID_EM2883:
- ir->get_key = default_polling_getkey;
- break;
- case CHIP_ID_EM2884:
- case CHIP_ID_EM2874:
- case CHIP_ID_EM28174:
- ir->get_key = em2874_polling_getkey;
- em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1);
- break;
- default:
- printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n",
- dev->chip_id);
- rc = -EINVAL;
- }
-
- return rc;
-}
-
-static void em28xx_register_i2c_ir(struct em28xx *dev)
-{
- /* Leadtek winfast tv USBII deluxe can find a non working IR-device */
- /* at address 0x18, so if that address is needed for another board in */
- /* the future, please put it after 0x1f. */
- struct i2c_board_info info;
- const unsigned short addr_list[] = {
- 0x1f, 0x30, 0x47, I2C_CLIENT_END
- };
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- memset(&dev->init_data, 0, sizeof(dev->init_data));
- strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
-
- /* detect & configure */
- switch (dev->model) {
- case EM2800_BOARD_TERRATEC_CINERGY_200:
- case EM2820_BOARD_TERRATEC_CINERGY_250:
- dev->init_data.ir_codes = RC_MAP_EM_TERRATEC;
- dev->init_data.get_key = em28xx_get_key_terratec;
- dev->init_data.name = "i2c IR (EM28XX Terratec)";
- break;
- case EM2820_BOARD_PINNACLE_USB_2:
- dev->init_data.ir_codes = RC_MAP_PINNACLE_GREY;
- dev->init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
- dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
- break;
- case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
- dev->init_data.ir_codes = RC_MAP_HAUPPAUGE;
- dev->init_data.get_key = em28xx_get_key_em_haup;
- dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
- break;
- case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
- dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;
- dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe;
- dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)";
- break;
- }
-
- if (dev->init_data.name)
- info.platform_data = &dev->init_data;
- i2c_new_probed_device(&dev->i2c_adap, &info, addr_list, NULL);
-}
-
-/**********************************************************
- Handle Webcam snapshot button
- **********************************************************/
-
-static void em28xx_query_sbutton(struct work_struct *work)
-{
- /* Poll the register and see if the button is depressed */
- struct em28xx *dev =
- container_of(work, struct em28xx, sbutton_query_work.work);
- int ret;
-
- ret = em28xx_read_reg(dev, EM28XX_R0C_USBSUSP);
-
- if (ret & EM28XX_R0C_USBSUSP_SNAPSHOT) {
- u8 cleared;
- /* Button is depressed, clear the register */
- cleared = ((u8) ret) & ~EM28XX_R0C_USBSUSP_SNAPSHOT;
- em28xx_write_regs(dev, EM28XX_R0C_USBSUSP, &cleared, 1);
-
- /* Not emulate the keypress */
- input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY,
- 1);
- /* Now unpress the key */
- input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY,
- 0);
- }
-
- /* Schedule next poll */
- schedule_delayed_work(&dev->sbutton_query_work,
- msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL));
-}
-
-static void em28xx_register_snapshot_button(struct em28xx *dev)
-{
- struct input_dev *input_dev;
- int err;
-
- em28xx_info("Registering snapshot button...\n");
- input_dev = input_allocate_device();
- if (!input_dev) {
- em28xx_errdev("input_allocate_device failed\n");
- return;
- }
-
- usb_make_path(dev->udev, dev->snapshot_button_path,
- sizeof(dev->snapshot_button_path));
- strlcat(dev->snapshot_button_path, "/sbutton",
- sizeof(dev->snapshot_button_path));
- INIT_DELAYED_WORK(&dev->sbutton_query_work, em28xx_query_sbutton);
-
- input_dev->name = "em28xx snapshot button";
- input_dev->phys = dev->snapshot_button_path;
- input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
- set_bit(EM28XX_SNAPSHOT_KEY, input_dev->keybit);
- input_dev->keycodesize = 0;
- input_dev->keycodemax = 0;
- input_dev->id.bustype = BUS_USB;
- input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
- input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
- input_dev->id.version = 1;
- input_dev->dev.parent = &dev->udev->dev;
-
- err = input_register_device(input_dev);
- if (err) {
- em28xx_errdev("input_register_device failed\n");
- input_free_device(input_dev);
- return;
- }
-
- dev->sbutton_input_dev = input_dev;
- schedule_delayed_work(&dev->sbutton_query_work,
- msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL));
- return;
-
-}
-
-static void em28xx_deregister_snapshot_button(struct em28xx *dev)
-{
- if (dev->sbutton_input_dev != NULL) {
- em28xx_info("Deregistering snapshot button\n");
- cancel_delayed_work_sync(&dev->sbutton_query_work);
- input_unregister_device(dev->sbutton_input_dev);
- dev->sbutton_input_dev = NULL;
- }
- return;
-}
-
-static int em28xx_ir_init(struct em28xx *dev)
-{
- struct em28xx_IR *ir;
- struct rc_dev *rc;
- int err = -ENOMEM;
-
- if (dev->board.ir_codes == NULL) {
- /* No remote control support */
- em28xx_warn("Remote control support is not available for "
- "this card.\n");
- return 0;
- }
-
- ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- rc = rc_allocate_device();
- if (!ir || !rc)
- goto err_out_free;
-
- /* record handles to ourself */
- ir->dev = dev;
- dev->ir = ir;
- ir->rc = rc;
-
- /*
- * em2874 supports more protocols. For now, let's just announce
- * the two protocols that were already tested
- */
- rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
- rc->priv = ir;
- rc->change_protocol = em28xx_ir_change_protocol;
- rc->open = em28xx_ir_start;
- rc->close = em28xx_ir_stop;
-
- /* By default, keep protocol field untouched */
- err = em28xx_ir_change_protocol(rc, RC_TYPE_UNKNOWN);
- if (err)
- goto err_out_free;
-
- /* This is how often we ask the chip for IR information */
- ir->polling = 100; /* ms */
-
- /* init input device */
- snprintf(ir->name, sizeof(ir->name), "em28xx IR (%s)",
- dev->name);
-
- usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
- strlcat(ir->phys, "/input0", sizeof(ir->phys));
-
- rc->input_name = ir->name;
- rc->input_phys = ir->phys;
- rc->input_id.bustype = BUS_USB;
- rc->input_id.version = 1;
- rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
- rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
- rc->dev.parent = &dev->udev->dev;
- rc->map_name = dev->board.ir_codes;
- rc->driver_name = MODULE_NAME;
-
- /* all done */
- err = rc_register_device(rc);
- if (err)
- goto err_out_stop;
-
- em28xx_register_i2c_ir(dev);
-
-#if defined(CONFIG_MODULES) && defined(MODULE)
- if (dev->board.has_ir_i2c)
- request_module("ir-kbd-i2c");
-#endif
- if (dev->board.has_snapshot_button)
- em28xx_register_snapshot_button(dev);
-
- return 0;
-
- err_out_stop:
- dev->ir = NULL;
- err_out_free:
- rc_free_device(rc);
- kfree(ir);
- return err;
-}
-
-static int em28xx_ir_fini(struct em28xx *dev)
-{
- struct em28xx_IR *ir = dev->ir;
-
- em28xx_deregister_snapshot_button(dev);
-
- /* skip detach on non attached boards */
- if (!ir)
- return 0;
-
- if (ir->rc)
- rc_unregister_device(ir->rc);
-
- /* done */
- kfree(ir);
- dev->ir = NULL;
- return 0;
-}
-
-static struct em28xx_ops rc_ops = {
- .id = EM28XX_RC,
- .name = "Em28xx Input Extension",
- .init = em28xx_ir_init,
- .fini = em28xx_ir_fini,
-};
-
-static int __init em28xx_rc_register(void)
-{
- return em28xx_register_extension(&rc_ops);
-}
-
-static void __exit em28xx_rc_unregister(void)
-{
- em28xx_unregister_extension(&rc_ops);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
-MODULE_DESCRIPTION("Em28xx Input driver");
-
-module_init(em28xx_rc_register);
-module_exit(em28xx_rc_unregister);
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
deleted file mode 100644
index 6ff368297f6..00000000000
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ /dev/null
@@ -1,226 +0,0 @@
-#define EM_GPIO_0 (1 << 0)
-#define EM_GPIO_1 (1 << 1)
-#define EM_GPIO_2 (1 << 2)
-#define EM_GPIO_3 (1 << 3)
-#define EM_GPIO_4 (1 << 4)
-#define EM_GPIO_5 (1 << 5)
-#define EM_GPIO_6 (1 << 6)
-#define EM_GPIO_7 (1 << 7)
-
-#define EM_GPO_0 (1 << 0)
-#define EM_GPO_1 (1 << 1)
-#define EM_GPO_2 (1 << 2)
-#define EM_GPO_3 (1 << 3)
-
-/* em28xx endpoints */
-#define EM28XX_EP_ANALOG 0x82
-#define EM28XX_EP_AUDIO 0x83
-#define EM28XX_EP_DIGITAL 0x84
-
-/* em2800 registers */
-#define EM2800_R08_AUDIOSRC 0x08
-
-/* em28xx registers */
-
-#define EM28XX_R00_CHIPCFG 0x00
-
-/* em28xx Chip Configuration 0x00 */
-#define EM28XX_CHIPCFG_VENDOR_AUDIO 0x80
-#define EM28XX_CHIPCFG_I2S_VOLUME_CAPABLE 0x40
-#define EM28XX_CHIPCFG_I2S_5_SAMPRATES 0x30
-#define EM28XX_CHIPCFG_I2S_3_SAMPRATES 0x20
-#define EM28XX_CHIPCFG_AC97 0x10
-#define EM28XX_CHIPCFG_AUDIOMASK 0x30
-
-#define EM28XX_R01_CHIPCFG2 0x01
-
-/* em28xx Chip Configuration 2 0x01 */
-#define EM28XX_CHIPCFG2_TS_PRESENT 0x10
-#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_MASK 0x0c /* bits 3-2 */
-#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_1MF 0x00
-#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_2MF 0x04
-#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_4MF 0x08
-#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_8MF 0x0c
-#define EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK 0x03 /* bits 0-1 */
-#define EM28XX_CHIPCFG2_TS_PACKETSIZE_188 0x00
-#define EM28XX_CHIPCFG2_TS_PACKETSIZE_376 0x01
-#define EM28XX_CHIPCFG2_TS_PACKETSIZE_564 0x02
-#define EM28XX_CHIPCFG2_TS_PACKETSIZE_752 0x03
-
-
- /* GPIO/GPO registers */
-#define EM2880_R04_GPO 0x04 /* em2880-em2883 only */
-#define EM28XX_R08_GPIO 0x08 /* em2820 or upper */
-
-#define EM28XX_R06_I2C_CLK 0x06
-
-/* em28xx I2C Clock Register (0x06) */
-#define EM28XX_I2C_CLK_ACK_LAST_READ 0x80
-#define EM28XX_I2C_CLK_WAIT_ENABLE 0x40
-#define EM28XX_I2C_EEPROM_ON_BOARD 0x08
-#define EM28XX_I2C_EEPROM_KEY_VALID 0x04
-#define EM2874_I2C_SECONDARY_BUS_SELECT 0x04 /* em2874 has two i2c busses */
-#define EM28XX_I2C_FREQ_1_5_MHZ 0x03 /* bus frequency (bits [1-0]) */
-#define EM28XX_I2C_FREQ_25_KHZ 0x02
-#define EM28XX_I2C_FREQ_400_KHZ 0x01
-#define EM28XX_I2C_FREQ_100_KHZ 0x00
-
-
-#define EM28XX_R0A_CHIPID 0x0a
-#define EM28XX_R0C_USBSUSP 0x0c /* */
-
-#define EM28XX_R0E_AUDIOSRC 0x0e
-#define EM28XX_R0F_XCLK 0x0f
-
-/* em28xx XCLK Register (0x0f) */
-#define EM28XX_XCLK_AUDIO_UNMUTE 0x80 /* otherwise audio muted */
-#define EM28XX_XCLK_I2S_MSB_TIMING 0x40 /* otherwise standard timing */
-#define EM28XX_XCLK_IR_RC5_MODE 0x20 /* otherwise NEC mode */
-#define EM28XX_XCLK_IR_NEC_CHK_PARITY 0x10
-#define EM28XX_XCLK_FREQUENCY_30MHZ 0x00 /* Freq. select (bits [3-0]) */
-#define EM28XX_XCLK_FREQUENCY_15MHZ 0x01
-#define EM28XX_XCLK_FREQUENCY_10MHZ 0x02
-#define EM28XX_XCLK_FREQUENCY_7_5MHZ 0x03
-#define EM28XX_XCLK_FREQUENCY_6MHZ 0x04
-#define EM28XX_XCLK_FREQUENCY_5MHZ 0x05
-#define EM28XX_XCLK_FREQUENCY_4_3MHZ 0x06
-#define EM28XX_XCLK_FREQUENCY_12MHZ 0x07
-#define EM28XX_XCLK_FREQUENCY_20MHZ 0x08
-#define EM28XX_XCLK_FREQUENCY_20MHZ_2 0x09
-#define EM28XX_XCLK_FREQUENCY_48MHZ 0x0a
-#define EM28XX_XCLK_FREQUENCY_24MHZ 0x0b
-
-#define EM28XX_R10_VINMODE 0x10
-
-#define EM28XX_R11_VINCTRL 0x11
-
-/* em28xx Video Input Control Register 0x11 */
-#define EM28XX_VINCTRL_VBI_SLICED 0x80
-#define EM28XX_VINCTRL_VBI_RAW 0x40
-#define EM28XX_VINCTRL_VOUT_MODE_IN 0x20 /* HREF,VREF,VACT in output */
-#define EM28XX_VINCTRL_CCIR656_ENABLE 0x10
-#define EM28XX_VINCTRL_VBI_16BIT_RAW 0x08 /* otherwise 8-bit raw */
-#define EM28XX_VINCTRL_FID_ON_HREF 0x04
-#define EM28XX_VINCTRL_DUAL_EDGE_STROBE 0x02
-#define EM28XX_VINCTRL_INTERLACED 0x01
-
-#define EM28XX_R12_VINENABLE 0x12 /* */
-
-#define EM28XX_R14_GAMMA 0x14
-#define EM28XX_R15_RGAIN 0x15
-#define EM28XX_R16_GGAIN 0x16
-#define EM28XX_R17_BGAIN 0x17
-#define EM28XX_R18_ROFFSET 0x18
-#define EM28XX_R19_GOFFSET 0x19
-#define EM28XX_R1A_BOFFSET 0x1a
-
-#define EM28XX_R1B_OFLOW 0x1b
-#define EM28XX_R1C_HSTART 0x1c
-#define EM28XX_R1D_VSTART 0x1d
-#define EM28XX_R1E_CWIDTH 0x1e
-#define EM28XX_R1F_CHEIGHT 0x1f
-
-#define EM28XX_R20_YGAIN 0x20
-#define EM28XX_R21_YOFFSET 0x21
-#define EM28XX_R22_UVGAIN 0x22
-#define EM28XX_R23_UOFFSET 0x23
-#define EM28XX_R24_VOFFSET 0x24
-#define EM28XX_R25_SHARPNESS 0x25
-
-#define EM28XX_R26_COMPR 0x26
-#define EM28XX_R27_OUTFMT 0x27
-
-/* em28xx Output Format Register (0x27) */
-#define EM28XX_OUTFMT_RGB_8_RGRG 0x00
-#define EM28XX_OUTFMT_RGB_8_GRGR 0x01
-#define EM28XX_OUTFMT_RGB_8_GBGB 0x02
-#define EM28XX_OUTFMT_RGB_8_BGBG 0x03
-#define EM28XX_OUTFMT_RGB_16_656 0x04
-#define EM28XX_OUTFMT_RGB_8_BAYER 0x08 /* Pattern in Reg 0x10[1-0] */
-#define EM28XX_OUTFMT_YUV211 0x10
-#define EM28XX_OUTFMT_YUV422_Y0UY1V 0x14
-#define EM28XX_OUTFMT_YUV422_Y1UY0V 0x15
-#define EM28XX_OUTFMT_YUV411 0x18
-
-
-#define EM28XX_R28_XMIN 0x28
-#define EM28XX_R29_XMAX 0x29
-#define EM28XX_R2A_YMIN 0x2a
-#define EM28XX_R2B_YMAX 0x2b
-
-#define EM28XX_R30_HSCALELOW 0x30
-#define EM28XX_R31_HSCALEHIGH 0x31
-#define EM28XX_R32_VSCALELOW 0x32
-#define EM28XX_R33_VSCALEHIGH 0x33
-#define EM28XX_R34_VBI_START_H 0x34
-#define EM28XX_R35_VBI_START_V 0x35
-#define EM28XX_R36_VBI_WIDTH 0x36
-#define EM28XX_R37_VBI_HEIGHT 0x37
-
-#define EM28XX_R40_AC97LSB 0x40
-#define EM28XX_R41_AC97MSB 0x41
-#define EM28XX_R42_AC97ADDR 0x42
-#define EM28XX_R43_AC97BUSY 0x43
-
-#define EM28XX_R45_IR 0x45
- /* 0x45 bit 7 - parity bit
- bits 6-0 - count
- 0x46 IR brand
- 0x47 IR data
- */
-
-/* em2874 registers */
-#define EM2874_R50_IR_CONFIG 0x50
-#define EM2874_R51_IR 0x51
-#define EM2874_R5F_TS_ENABLE 0x5f
-#define EM2874_R80_GPIO 0x80
-
-/* em2874 IR config register (0x50) */
-#define EM2874_IR_NEC 0x00
-#define EM2874_IR_RC5 0x04
-#define EM2874_IR_RC6_MODE_0 0x08
-#define EM2874_IR_RC6_MODE_6A 0x0b
-
-/* em2874 Transport Stream Enable Register (0x5f) */
-#define EM2874_TS1_CAPTURE_ENABLE (1 << 0)
-#define EM2874_TS1_FILTER_ENABLE (1 << 1)
-#define EM2874_TS1_NULL_DISCARD (1 << 2)
-#define EM2874_TS2_CAPTURE_ENABLE (1 << 4)
-#define EM2874_TS2_FILTER_ENABLE (1 << 5)
-#define EM2874_TS2_NULL_DISCARD (1 << 6)
-
-/* register settings */
-#define EM2800_AUDIO_SRC_TUNER 0x0d
-#define EM2800_AUDIO_SRC_LINE 0x0c
-#define EM28XX_AUDIO_SRC_TUNER 0xc0
-#define EM28XX_AUDIO_SRC_LINE 0x80
-
-/* FIXME: Need to be populated with the other chip ID's */
-enum em28xx_chip_id {
- CHIP_ID_EM2800 = 7,
- CHIP_ID_EM2710 = 17,
- CHIP_ID_EM2820 = 18, /* Also used by some em2710 */
- CHIP_ID_EM2840 = 20,
- CHIP_ID_EM2750 = 33,
- CHIP_ID_EM2860 = 34,
- CHIP_ID_EM2870 = 35,
- CHIP_ID_EM2883 = 36,
- CHIP_ID_EM2874 = 65,
- CHIP_ID_EM2884 = 68,
- CHIP_ID_EM28174 = 113,
-};
-
-/*
- * Registers used by em202
- */
-
-/* EMP202 vendor registers */
-#define EM202_EXT_MODEM_CTRL 0x3e
-#define EM202_GPIO_CONF 0x4c
-#define EM202_GPIO_POLARITY 0x4e
-#define EM202_GPIO_STICKY 0x50
-#define EM202_GPIO_MASK 0x52
-#define EM202_GPIO_STATUS 0x54
-#define EM202_SPDIF_OUT_SEL 0x6a
-#define EM202_ANTIPOP 0x72
-#define EM202_EAPD_GPIO_ACCESS 0x74
diff --git a/drivers/media/video/em28xx/em28xx-vbi.c b/drivers/media/video/em28xx/em28xx-vbi.c
deleted file mode 100644
index 2b4c9cba2d6..00000000000
--- a/drivers/media/video/em28xx/em28xx-vbi.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- em28xx-vbi.c - VBI driver for em28xx
-
- Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
-
- This work was sponsored by EyeMagnet Limited.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/hardirq.h>
-#include <linux/init.h>
-
-#include "em28xx.h"
-
-static unsigned int vbibufs = 5;
-module_param(vbibufs, int, 0644);
-MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32");
-
-static unsigned int vbi_debug;
-module_param(vbi_debug, int, 0644);
-MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]");
-
-#define dprintk(level, fmt, arg...) if (vbi_debug >= level) \
- printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg)
-
-/* ------------------------------------------------------------------ */
-
-static void
-free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf)
-{
- struct em28xx_fh *fh = vq->priv_data;
- struct em28xx *dev = fh->dev;
- unsigned long flags = 0;
- if (in_interrupt())
- BUG();
-
- /* We used to wait for the buffer to finish here, but this didn't work
- because, as we were keeping the state as VIDEOBUF_QUEUED,
- videobuf_queue_cancel marked it as finished for us.
- (Also, it could wedge forever if the hardware was misconfigured.)
-
- This should be safe; by the time we get here, the buffer isn't
- queued anymore. If we ever start marking the buffers as
- VIDEOBUF_ACTIVE, it won't be, though.
- */
- spin_lock_irqsave(&dev->slock, flags);
- if (dev->isoc_ctl.vbi_buf == buf)
- dev->isoc_ctl.vbi_buf = NULL;
- spin_unlock_irqrestore(&dev->slock, flags);
-
- videobuf_vmalloc_free(&buf->vb);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int
-vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
-{
- struct em28xx_fh *fh = q->priv_data;
- struct em28xx *dev = fh->dev;
-
- *size = dev->vbi_width * dev->vbi_height * 2;
-
- if (0 == *count)
- *count = vbibufs;
- if (*count < 2)
- *count = 2;
- if (*count > 32)
- *count = 32;
- return 0;
-}
-
-static int
-vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct em28xx_fh *fh = q->priv_data;
- struct em28xx *dev = fh->dev;
- struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
- int rc = 0;
-
- buf->vb.size = dev->vbi_width * dev->vbi_height * 2;
-
- if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
- return -EINVAL;
-
- buf->vb.width = dev->vbi_width;
- buf->vb.height = dev->vbi_height;
- buf->vb.field = field;
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- rc = videobuf_iolock(q, &buf->vb, NULL);
- if (rc < 0)
- goto fail;
- }
-
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
-fail:
- free_buffer(q, buf);
- return rc;
-}
-
-static void
-vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct em28xx_buffer *buf = container_of(vb,
- struct em28xx_buffer,
- vb);
- struct em28xx_fh *fh = vq->priv_data;
- struct em28xx *dev = fh->dev;
- struct em28xx_dmaqueue *vbiq = &dev->vbiq;
-
- buf->vb.state = VIDEOBUF_QUEUED;
- list_add_tail(&buf->vb.queue, &vbiq->active);
-}
-
-static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
- free_buffer(q, buf);
-}
-
-struct videobuf_queue_ops em28xx_vbi_qops = {
- .buf_setup = vbi_setup,
- .buf_prepare = vbi_prepare,
- .buf_queue = vbi_queue,
- .buf_release = vbi_release,
-};
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
deleted file mode 100644
index 50f5f4fc214..00000000000
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ /dev/null
@@ -1,2606 +0,0 @@
-/*
- em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB
- video capture devices
-
- Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
- Markus Rechberger <mrechberger@gmail.com>
- Mauro Carvalho Chehab <mchehab@infradead.org>
- Sascha Sommer <saschasommer@freenet.de>
-
- Some parts based on SN9C10x PC Camera Controllers GPL driver made
- by Luca Risolia <luca.risolia@studio.unibo.it>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/bitmap.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <linux/mm.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-
-#include "em28xx.h"
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/msp3400.h>
-#include <media/tuner.h>
-
-#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
- "Markus Rechberger <mrechberger@gmail.com>, " \
- "Mauro Carvalho Chehab <mchehab@infradead.org>, " \
- "Sascha Sommer <saschasommer@freenet.de>"
-
-#define DRIVER_DESC "Empia em28xx based USB video device driver"
-
-#define EM28XX_VERSION "0.1.3"
-
-#define em28xx_videodbg(fmt, arg...) do {\
- if (video_debug) \
- printk(KERN_INFO "%s %s :"fmt, \
- dev->name, __func__ , ##arg); } while (0)
-
-static unsigned int isoc_debug;
-module_param(isoc_debug, int, 0644);
-MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
-
-#define em28xx_isocdbg(fmt, arg...) \
-do {\
- if (isoc_debug) { \
- printk(KERN_INFO "%s %s :"fmt, \
- dev->name, __func__ , ##arg); \
- } \
- } while (0)
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_VERSION(EM28XX_VERSION);
-
-static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
-static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
-static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
-
-module_param_array(video_nr, int, NULL, 0444);
-module_param_array(vbi_nr, int, NULL, 0444);
-module_param_array(radio_nr, int, NULL, 0444);
-MODULE_PARM_DESC(video_nr, "video device numbers");
-MODULE_PARM_DESC(vbi_nr, "vbi device numbers");
-MODULE_PARM_DESC(radio_nr, "radio device numbers");
-
-static unsigned int video_debug;
-module_param(video_debug, int, 0644);
-MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
-
-/* supported video standards */
-static struct em28xx_fmt format[] = {
- {
- .name = "16 bpp YUY2, 4:2:2, packed",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = 16,
- .reg = EM28XX_OUTFMT_YUV422_Y0UY1V,
- }, {
- .name = "16 bpp RGB 565, LE",
- .fourcc = V4L2_PIX_FMT_RGB565,
- .depth = 16,
- .reg = EM28XX_OUTFMT_RGB_16_656,
- }, {
- .name = "8 bpp Bayer BGBG..GRGR",
- .fourcc = V4L2_PIX_FMT_SBGGR8,
- .depth = 8,
- .reg = EM28XX_OUTFMT_RGB_8_BGBG,
- }, {
- .name = "8 bpp Bayer GRGR..BGBG",
- .fourcc = V4L2_PIX_FMT_SGRBG8,
- .depth = 8,
- .reg = EM28XX_OUTFMT_RGB_8_GRGR,
- }, {
- .name = "8 bpp Bayer GBGB..RGRG",
- .fourcc = V4L2_PIX_FMT_SGBRG8,
- .depth = 8,
- .reg = EM28XX_OUTFMT_RGB_8_GBGB,
- }, {
- .name = "12 bpp YUV411",
- .fourcc = V4L2_PIX_FMT_YUV411P,
- .depth = 12,
- .reg = EM28XX_OUTFMT_YUV411,
- },
-};
-
-/* supported controls */
-/* Common to all boards */
-static struct v4l2_queryctrl ac97_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_VOLUME,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Volume",
- .minimum = 0x0,
- .maximum = 0x1f,
- .step = 0x1,
- .default_value = 0x1f,
- .flags = V4L2_CTRL_FLAG_SLIDER,
- }, {
- .id = V4L2_CID_AUDIO_MUTE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1,
- .flags = 0,
- }
-};
-
-/* ------------------------------------------------------------------
- DMA and thread functions
- ------------------------------------------------------------------*/
-
-/*
- * Announces that a buffer were filled and request the next
- */
-static inline void buffer_filled(struct em28xx *dev,
- struct em28xx_dmaqueue *dma_q,
- struct em28xx_buffer *buf)
-{
- /* Advice that buffer was filled */
- em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
- buf->vb.state = VIDEOBUF_DONE;
- buf->vb.field_count++;
- do_gettimeofday(&buf->vb.ts);
-
- dev->isoc_ctl.vid_buf = NULL;
-
- list_del(&buf->vb.queue);
- wake_up(&buf->vb.done);
-}
-
-static inline void vbi_buffer_filled(struct em28xx *dev,
- struct em28xx_dmaqueue *dma_q,
- struct em28xx_buffer *buf)
-{
- /* Advice that buffer was filled */
- em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
-
- buf->vb.state = VIDEOBUF_DONE;
- buf->vb.field_count++;
- do_gettimeofday(&buf->vb.ts);
-
- dev->isoc_ctl.vbi_buf = NULL;
-
- list_del(&buf->vb.queue);
- wake_up(&buf->vb.done);
-}
-
-/*
- * Identify the buffer header type and properly handles
- */
-static void em28xx_copy_video(struct em28xx *dev,
- struct em28xx_dmaqueue *dma_q,
- struct em28xx_buffer *buf,
- unsigned char *p,
- unsigned char *outp, unsigned long len)
-{
- void *fieldstart, *startwrite, *startread;
- int linesdone, currlinedone, offset, lencopy, remain;
- int bytesperline = dev->width << 1;
-
- if (dma_q->pos + len > buf->vb.size)
- len = buf->vb.size - dma_q->pos;
-
- startread = p;
- remain = len;
-
- if (dev->progressive)
- fieldstart = outp;
- else {
- /* Interlaces two half frames */
- if (buf->top_field)
- fieldstart = outp;
- else
- fieldstart = outp + bytesperline;
- }
-
- linesdone = dma_q->pos / bytesperline;
- currlinedone = dma_q->pos % bytesperline;
-
- if (dev->progressive)
- offset = linesdone * bytesperline + currlinedone;
- else
- offset = linesdone * bytesperline * 2 + currlinedone;
-
- startwrite = fieldstart + offset;
- lencopy = bytesperline - currlinedone;
- lencopy = lencopy > remain ? remain : lencopy;
-
- if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
- em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
- ((char *)startwrite + lencopy) -
- ((char *)outp + buf->vb.size));
- remain = (char *)outp + buf->vb.size - (char *)startwrite;
- lencopy = remain;
- }
- if (lencopy <= 0)
- return;
- memcpy(startwrite, startread, lencopy);
-
- remain -= lencopy;
-
- while (remain > 0) {
- startwrite += lencopy + bytesperline;
- startread += lencopy;
- if (bytesperline > remain)
- lencopy = remain;
- else
- lencopy = bytesperline;
-
- if ((char *)startwrite + lencopy > (char *)outp +
- buf->vb.size) {
- em28xx_isocdbg("Overflow of %zi bytes past buffer end"
- "(2)\n",
- ((char *)startwrite + lencopy) -
- ((char *)outp + buf->vb.size));
- lencopy = remain = (char *)outp + buf->vb.size -
- (char *)startwrite;
- }
- if (lencopy <= 0)
- break;
-
- memcpy(startwrite, startread, lencopy);
-
- remain -= lencopy;
- }
-
- dma_q->pos += len;
-}
-
-static void em28xx_copy_vbi(struct em28xx *dev,
- struct em28xx_dmaqueue *dma_q,
- struct em28xx_buffer *buf,
- unsigned char *p,
- unsigned char *outp, unsigned long len)
-{
- void *startwrite, *startread;
- int offset;
- int bytesperline;
-
- if (dev == NULL) {
- em28xx_isocdbg("dev is null\n");
- return;
- }
- bytesperline = dev->vbi_width;
-
- if (dma_q == NULL) {
- em28xx_isocdbg("dma_q is null\n");
- return;
- }
- if (buf == NULL) {
- return;
- }
- if (p == NULL) {
- em28xx_isocdbg("p is null\n");
- return;
- }
- if (outp == NULL) {
- em28xx_isocdbg("outp is null\n");
- return;
- }
-
- if (dma_q->pos + len > buf->vb.size)
- len = buf->vb.size - dma_q->pos;
-
- startread = p;
-
- startwrite = outp + dma_q->pos;
- offset = dma_q->pos;
-
- /* Make sure the bottom field populates the second half of the frame */
- if (buf->top_field == 0) {
- startwrite += bytesperline * dev->vbi_height;
- offset += bytesperline * dev->vbi_height;
- }
-
- memcpy(startwrite, startread, len);
- dma_q->pos += len;
-}
-
-static inline void print_err_status(struct em28xx *dev,
- int packet, int status)
-{
- char *errmsg = "Unknown";
-
- switch (status) {
- case -ENOENT:
- errmsg = "unlinked synchronuously";
- break;
- case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
- break;
- case -ENOSR:
- errmsg = "Buffer error (overrun)";
- break;
- case -EPIPE:
- errmsg = "Stalled (device not responding)";
- break;
- case -EOVERFLOW:
- errmsg = "Babble (bad cable?)";
- break;
- case -EPROTO:
- errmsg = "Bit-stuff error (bad cable?)";
- break;
- case -EILSEQ:
- errmsg = "CRC/Timeout (could be anything)";
- break;
- case -ETIME:
- errmsg = "Device does not respond";
- break;
- }
- if (packet < 0) {
- em28xx_isocdbg("URB status %d [%s].\n", status, errmsg);
- } else {
- em28xx_isocdbg("URB packet %d, status %d [%s].\n",
- packet, status, errmsg);
- }
-}
-
-/*
- * video-buf generic routine to get the next available buffer
- */
-static inline void get_next_buf(struct em28xx_dmaqueue *dma_q,
- struct em28xx_buffer **buf)
-{
- struct em28xx *dev = container_of(dma_q, struct em28xx, vidq);
- char *outp;
-
- if (list_empty(&dma_q->active)) {
- em28xx_isocdbg("No active queue to serve\n");
- dev->isoc_ctl.vid_buf = NULL;
- *buf = NULL;
- return;
- }
-
- /* Get the next buffer */
- *buf = list_entry(dma_q->active.next, struct em28xx_buffer, vb.queue);
-
- /* Cleans up buffer - Useful for testing for frame/URB loss */
- outp = videobuf_to_vmalloc(&(*buf)->vb);
- memset(outp, 0, (*buf)->vb.size);
-
- dev->isoc_ctl.vid_buf = *buf;
-
- return;
-}
-
-/*
- * video-buf generic routine to get the next available VBI buffer
- */
-static inline void vbi_get_next_buf(struct em28xx_dmaqueue *dma_q,
- struct em28xx_buffer **buf)
-{
- struct em28xx *dev = container_of(dma_q, struct em28xx, vbiq);
- char *outp;
-
- if (list_empty(&dma_q->active)) {
- em28xx_isocdbg("No active queue to serve\n");
- dev->isoc_ctl.vbi_buf = NULL;
- *buf = NULL;
- return;
- }
-
- /* Get the next buffer */
- *buf = list_entry(dma_q->active.next, struct em28xx_buffer, vb.queue);
- /* Cleans up buffer - Useful for testing for frame/URB loss */
- outp = videobuf_to_vmalloc(&(*buf)->vb);
- memset(outp, 0x00, (*buf)->vb.size);
-
- dev->isoc_ctl.vbi_buf = *buf;
-
- return;
-}
-
-/*
- * Controls the isoc copy of each urb packet
- */
-static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
-{
- struct em28xx_buffer *buf;
- struct em28xx_dmaqueue *dma_q = &dev->vidq;
- unsigned char *outp = NULL;
- int i, len = 0, rc = 1;
- unsigned char *p;
-
- if (!dev)
- return 0;
-
- if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
- return 0;
-
- if (urb->status < 0) {
- print_err_status(dev, -1, urb->status);
- if (urb->status == -ENOENT)
- return 0;
- }
-
- buf = dev->isoc_ctl.vid_buf;
- if (buf != NULL)
- outp = videobuf_to_vmalloc(&buf->vb);
-
- for (i = 0; i < urb->number_of_packets; i++) {
- int status = urb->iso_frame_desc[i].status;
-
- if (status < 0) {
- print_err_status(dev, i, status);
- if (urb->iso_frame_desc[i].status != -EPROTO)
- continue;
- }
-
- len = urb->iso_frame_desc[i].actual_length - 4;
-
- if (urb->iso_frame_desc[i].actual_length <= 0) {
- /* em28xx_isocdbg("packet %d is empty",i); - spammy */
- continue;
- }
- if (urb->iso_frame_desc[i].actual_length >
- dev->max_pkt_size) {
- em28xx_isocdbg("packet bigger than packet size");
- continue;
- }
-
- p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
-
- /* FIXME: incomplete buffer checks where removed to make
- logic simpler. Impacts of those changes should be evaluated
- */
- if (p[0] == 0x33 && p[1] == 0x95 && p[2] == 0x00) {
- em28xx_isocdbg("VBI HEADER!!!\n");
- /* FIXME: Should add vbi copy */
- continue;
- }
- if (p[0] == 0x22 && p[1] == 0x5a) {
- em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
- len, (p[2] & 1) ? "odd" : "even");
-
- if (dev->progressive || !(p[2] & 1)) {
- if (buf != NULL)
- buffer_filled(dev, dma_q, buf);
- get_next_buf(dma_q, &buf);
- if (buf == NULL)
- outp = NULL;
- else
- outp = videobuf_to_vmalloc(&buf->vb);
- }
-
- if (buf != NULL) {
- if (p[2] & 1)
- buf->top_field = 0;
- else
- buf->top_field = 1;
- }
-
- dma_q->pos = 0;
- }
- if (buf != NULL) {
- if (p[0] != 0x88 && p[0] != 0x22) {
- em28xx_isocdbg("frame is not complete\n");
- len += 4;
- } else {
- p += 4;
- }
- em28xx_copy_video(dev, dma_q, buf, p, outp, len);
- }
- }
- return rc;
-}
-
-/* Version of isoc handler that takes into account a mixture of video and
- VBI data */
-static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
-{
- struct em28xx_buffer *buf, *vbi_buf;
- struct em28xx_dmaqueue *dma_q = &dev->vidq;
- struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq;
- unsigned char *outp = NULL;
- unsigned char *vbioutp = NULL;
- int i, len = 0, rc = 1;
- unsigned char *p;
- int vbi_size;
-
- if (!dev)
- return 0;
-
- if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
- return 0;
-
- if (urb->status < 0) {
- print_err_status(dev, -1, urb->status);
- if (urb->status == -ENOENT)
- return 0;
- }
-
- buf = dev->isoc_ctl.vid_buf;
- if (buf != NULL)
- outp = videobuf_to_vmalloc(&buf->vb);
-
- vbi_buf = dev->isoc_ctl.vbi_buf;
- if (vbi_buf != NULL)
- vbioutp = videobuf_to_vmalloc(&vbi_buf->vb);
-
- for (i = 0; i < urb->number_of_packets; i++) {
- int status = urb->iso_frame_desc[i].status;
-
- if (status < 0) {
- print_err_status(dev, i, status);
- if (urb->iso_frame_desc[i].status != -EPROTO)
- continue;
- }
-
- len = urb->iso_frame_desc[i].actual_length;
- if (urb->iso_frame_desc[i].actual_length <= 0) {
- /* em28xx_isocdbg("packet %d is empty",i); - spammy */
- continue;
- }
- if (urb->iso_frame_desc[i].actual_length >
- dev->max_pkt_size) {
- em28xx_isocdbg("packet bigger than packet size");
- continue;
- }
-
- p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
-
- /* capture type 0 = vbi start
- capture type 1 = video start
- capture type 2 = video in progress */
- if (p[0] == 0x33 && p[1] == 0x95) {
- dev->capture_type = 0;
- dev->vbi_read = 0;
- em28xx_isocdbg("VBI START HEADER!!!\n");
- dev->cur_field = p[2];
- p += 4;
- len -= 4;
- } else if (p[0] == 0x88 && p[1] == 0x88 &&
- p[2] == 0x88 && p[3] == 0x88) {
- /* continuation */
- p += 4;
- len -= 4;
- } else if (p[0] == 0x22 && p[1] == 0x5a) {
- /* start video */
- p += 4;
- len -= 4;
- }
-
- vbi_size = dev->vbi_width * dev->vbi_height;
-
- if (dev->capture_type == 0) {
- if (dev->vbi_read >= vbi_size) {
- /* We've already read all the VBI data, so
- treat the rest as video */
- em28xx_isocdbg("dev->vbi_read > vbi_size\n");
- } else if ((dev->vbi_read + len) < vbi_size) {
- /* This entire frame is VBI data */
- if (dev->vbi_read == 0 &&
- (!(dev->cur_field & 1))) {
- /* Brand new frame */
- if (vbi_buf != NULL)
- vbi_buffer_filled(dev,
- vbi_dma_q,
- vbi_buf);
- vbi_get_next_buf(vbi_dma_q, &vbi_buf);
- if (vbi_buf == NULL)
- vbioutp = NULL;
- else
- vbioutp = videobuf_to_vmalloc(
- &vbi_buf->vb);
- }
-
- if (dev->vbi_read == 0) {
- vbi_dma_q->pos = 0;
- if (vbi_buf != NULL) {
- if (dev->cur_field & 1)
- vbi_buf->top_field = 0;
- else
- vbi_buf->top_field = 1;
- }
- }
-
- dev->vbi_read += len;
- em28xx_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
- vbioutp, len);
- } else {
- /* Some of this frame is VBI data and some is
- video data */
- int vbi_data_len = vbi_size - dev->vbi_read;
- dev->vbi_read += vbi_data_len;
- em28xx_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
- vbioutp, vbi_data_len);
- dev->capture_type = 1;
- p += vbi_data_len;
- len -= vbi_data_len;
- }
- }
-
- if (dev->capture_type == 1) {
- dev->capture_type = 2;
- if (dev->progressive || !(dev->cur_field & 1)) {
- if (buf != NULL)
- buffer_filled(dev, dma_q, buf);
- get_next_buf(dma_q, &buf);
- if (buf == NULL)
- outp = NULL;
- else
- outp = videobuf_to_vmalloc(&buf->vb);
- }
- if (buf != NULL) {
- if (dev->cur_field & 1)
- buf->top_field = 0;
- else
- buf->top_field = 1;
- }
-
- dma_q->pos = 0;
- }
-
- if (buf != NULL && dev->capture_type == 2) {
- if (len >= 4 && p[0] == 0x88 && p[1] == 0x88 &&
- p[2] == 0x88 && p[3] == 0x88) {
- p += 4;
- len -= 4;
- }
- if (len >= 4 && p[0] == 0x22 && p[1] == 0x5a) {
- em28xx_isocdbg("Video frame %d, len=%i, %s\n",
- p[2], len, (p[2] & 1) ?
- "odd" : "even");
- p += 4;
- len -= 4;
- }
-
- if (len > 0)
- em28xx_copy_video(dev, dma_q, buf, p, outp,
- len);
- }
- }
- return rc;
-}
-
-
-/* ------------------------------------------------------------------
- Videobuf operations
- ------------------------------------------------------------------*/
-
-static int
-buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
-{
- struct em28xx_fh *fh = vq->priv_data;
- struct em28xx *dev = fh->dev;
- struct v4l2_frequency f;
-
- *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7)
- >> 3;
-
- if (0 == *count)
- *count = EM28XX_DEF_BUF;
-
- if (*count < EM28XX_MIN_BUF)
- *count = EM28XX_MIN_BUF;
-
- /* Ask tuner to go to analog or radio mode */
- memset(&f, 0, sizeof(f));
- f.frequency = dev->ctl_freq;
- f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
-
- return 0;
-}
-
-/* This is called *without* dev->slock held; please keep it that way */
-static void free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf)
-{
- struct em28xx_fh *fh = vq->priv_data;
- struct em28xx *dev = fh->dev;
- unsigned long flags = 0;
- if (in_interrupt())
- BUG();
-
- /* We used to wait for the buffer to finish here, but this didn't work
- because, as we were keeping the state as VIDEOBUF_QUEUED,
- videobuf_queue_cancel marked it as finished for us.
- (Also, it could wedge forever if the hardware was misconfigured.)
-
- This should be safe; by the time we get here, the buffer isn't
- queued anymore. If we ever start marking the buffers as
- VIDEOBUF_ACTIVE, it won't be, though.
- */
- spin_lock_irqsave(&dev->slock, flags);
- if (dev->isoc_ctl.vid_buf == buf)
- dev->isoc_ctl.vid_buf = NULL;
- spin_unlock_irqrestore(&dev->slock, flags);
-
- videobuf_vmalloc_free(&buf->vb);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int
-buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct em28xx_fh *fh = vq->priv_data;
- struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
- struct em28xx *dev = fh->dev;
- int rc = 0, urb_init = 0;
-
- buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth
- + 7) >> 3;
-
- if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
- return -EINVAL;
-
- buf->vb.width = dev->width;
- buf->vb.height = dev->height;
- buf->vb.field = field;
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- rc = videobuf_iolock(vq, &buf->vb, NULL);
- if (rc < 0)
- goto fail;
- }
-
- if (!dev->isoc_ctl.analog_bufs.num_bufs)
- urb_init = 1;
-
- if (urb_init) {
- if (em28xx_vbi_supported(dev) == 1)
- rc = em28xx_init_isoc(dev, EM28XX_ANALOG_MODE,
- EM28XX_NUM_PACKETS,
- EM28XX_NUM_BUFS,
- dev->max_pkt_size,
- em28xx_isoc_copy_vbi);
- else
- rc = em28xx_init_isoc(dev, EM28XX_ANALOG_MODE,
- EM28XX_NUM_PACKETS,
- EM28XX_NUM_BUFS,
- dev->max_pkt_size,
- em28xx_isoc_copy);
- if (rc < 0)
- goto fail;
- }
-
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
-fail:
- free_buffer(vq, buf);
- return rc;
-}
-
-static void
-buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct em28xx_buffer *buf = container_of(vb,
- struct em28xx_buffer,
- vb);
- struct em28xx_fh *fh = vq->priv_data;
- struct em28xx *dev = fh->dev;
- struct em28xx_dmaqueue *vidq = &dev->vidq;
-
- buf->vb.state = VIDEOBUF_QUEUED;
- list_add_tail(&buf->vb.queue, &vidq->active);
-
-}
-
-static void buffer_release(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct em28xx_buffer *buf = container_of(vb,
- struct em28xx_buffer,
- vb);
- struct em28xx_fh *fh = vq->priv_data;
- struct em28xx *dev = (struct em28xx *)fh->dev;
-
- em28xx_isocdbg("em28xx: called buffer_release\n");
-
- free_buffer(vq, buf);
-}
-
-static struct videobuf_queue_ops em28xx_video_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-/********************* v4l2 interface **************************************/
-
-static void video_mux(struct em28xx *dev, int index)
-{
- dev->ctl_input = index;
- dev->ctl_ainput = INPUT(index)->amux;
- dev->ctl_aoutput = INPUT(index)->aout;
-
- if (!dev->ctl_aoutput)
- dev->ctl_aoutput = EM28XX_AOUT_MASTER;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
- INPUT(index)->vmux, 0, 0);
-
- if (dev->board.has_msp34xx) {
- if (dev->i2s_speed) {
- v4l2_device_call_all(&dev->v4l2_dev, 0, audio,
- s_i2s_clock_freq, dev->i2s_speed);
- }
- /* Note: this is msp3400 specific */
- v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
- dev->ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0);
- }
-
- if (dev->board.adecoder != EM28XX_NOADECODER) {
- v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
- dev->ctl_ainput, dev->ctl_aoutput, 0);
- }
-
- em28xx_audio_analog_set(dev);
-}
-
-/* Usage lock check functions */
-static int res_get(struct em28xx_fh *fh, unsigned int bit)
-{
- struct em28xx *dev = fh->dev;
-
- if (fh->resources & bit)
- /* have it already allocated */
- return 1;
-
- /* is it free? */
- if (dev->resources & bit) {
- /* no, someone else uses it */
- return 0;
- }
- /* it's free, grab it */
- fh->resources |= bit;
- dev->resources |= bit;
- em28xx_videodbg("res: get %d\n", bit);
- return 1;
-}
-
-static int res_check(struct em28xx_fh *fh, unsigned int bit)
-{
- return fh->resources & bit;
-}
-
-static int res_locked(struct em28xx *dev, unsigned int bit)
-{
- return dev->resources & bit;
-}
-
-static void res_free(struct em28xx_fh *fh, unsigned int bits)
-{
- struct em28xx *dev = fh->dev;
-
- BUG_ON((fh->resources & bits) != bits);
-
- fh->resources &= ~bits;
- dev->resources &= ~bits;
- em28xx_videodbg("res: put %d\n", bits);
-}
-
-static int get_ressource(struct em28xx_fh *fh)
-{
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- return EM28XX_RESOURCE_VIDEO;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- return EM28XX_RESOURCE_VBI;
- default:
- BUG();
- return 0;
- }
-}
-
-/*
- * ac97_queryctrl()
- * return the ac97 supported controls
- */
-static int ac97_queryctrl(struct v4l2_queryctrl *qc)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) {
- if (qc->id && qc->id == ac97_qctrl[i].id) {
- memcpy(qc, &(ac97_qctrl[i]), sizeof(*qc));
- return 0;
- }
- }
-
- /* Control is not ac97 related */
- return 1;
-}
-
-/*
- * ac97_get_ctrl()
- * return the current values for ac97 mute and volume
- */
-static int ac97_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value = dev->mute;
- return 0;
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = dev->volume;
- return 0;
- default:
- /* Control is not ac97 related */
- return 1;
- }
-}
-
-/*
- * ac97_set_ctrl()
- * set values for ac97 mute and volume
- */
-static int ac97_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++)
- if (ctrl->id == ac97_qctrl[i].id)
- goto handle;
-
- /* Announce that hasn't handle it */
- return 1;
-
-handle:
- if (ctrl->value < ac97_qctrl[i].minimum ||
- ctrl->value > ac97_qctrl[i].maximum)
- return -ERANGE;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- dev->mute = ctrl->value;
- break;
- case V4L2_CID_AUDIO_VOLUME:
- dev->volume = ctrl->value;
- break;
- }
-
- return em28xx_audio_analog_set(dev);
-}
-
-static int check_dev(struct em28xx *dev)
-{
- if (dev->state & DEV_DISCONNECTED) {
- em28xx_errdev("v4l2 ioctl: device not present\n");
- return -ENODEV;
- }
-
- if (dev->state & DEV_MISCONFIGURED) {
- em28xx_errdev("v4l2 ioctl: device is misconfigured; "
- "close and open it again\n");
- return -EIO;
- }
- return 0;
-}
-
-static void get_scale(struct em28xx *dev,
- unsigned int width, unsigned int height,
- unsigned int *hscale, unsigned int *vscale)
-{
- unsigned int maxw = norm_maxw(dev);
- unsigned int maxh = norm_maxh(dev);
-
- *hscale = (((unsigned long)maxw) << 12) / width - 4096L;
- if (*hscale >= 0x4000)
- *hscale = 0x3fff;
-
- *vscale = (((unsigned long)maxh) << 12) / height - 4096L;
- if (*vscale >= 0x4000)
- *vscale = 0x3fff;
-}
-
-/* ------------------------------------------------------------------
- IOCTL vidioc handling
- ------------------------------------------------------------------*/
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
-
- f->fmt.pix.width = dev->width;
- f->fmt.pix.height = dev->height;
- f->fmt.pix.pixelformat = dev->format->fourcc;
- f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;
- f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-
- /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
- if (dev->progressive)
- f->fmt.pix.field = V4L2_FIELD_NONE;
- else
- f->fmt.pix.field = dev->interlaced ?
- V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
- return 0;
-}
-
-static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(format); i++)
- if (format[i].fourcc == fourcc)
- return &format[i];
-
- return NULL;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- unsigned int width = f->fmt.pix.width;
- unsigned int height = f->fmt.pix.height;
- unsigned int maxw = norm_maxw(dev);
- unsigned int maxh = norm_maxh(dev);
- unsigned int hscale, vscale;
- struct em28xx_fmt *fmt;
-
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- if (!fmt) {
- em28xx_videodbg("Fourcc format (%08x) invalid.\n",
- f->fmt.pix.pixelformat);
- return -EINVAL;
- }
-
- if (dev->board.is_em2800) {
- /* the em2800 can only scale down to 50% */
- height = height > (3 * maxh / 4) ? maxh : maxh / 2;
- width = width > (3 * maxw / 4) ? maxw : maxw / 2;
- /* MaxPacketSize for em2800 is too small to capture at full resolution
- * use half of maxw as the scaler can only scale to 50% */
- if (width == maxw && height == maxh)
- width /= 2;
- } else {
- /* width must even because of the YUYV format
- height must be even because of interlacing */
- v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh,
- 1, 0);
- }
-
- get_scale(dev, width, height, &hscale, &vscale);
-
- width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
- height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
-
- f->fmt.pix.width = width;
- f->fmt.pix.height = height;
- f->fmt.pix.pixelformat = fmt->fourcc;
- f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3;
- f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- if (dev->progressive)
- f->fmt.pix.field = V4L2_FIELD_NONE;
- else
- f->fmt.pix.field = dev->interlaced ?
- V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
-
- return 0;
-}
-
-static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc,
- unsigned width, unsigned height)
-{
- struct em28xx_fmt *fmt;
-
- fmt = format_by_fourcc(fourcc);
- if (!fmt)
- return -EINVAL;
-
- dev->format = fmt;
- dev->width = width;
- dev->height = height;
-
- /* set new image size */
- get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
-
- em28xx_set_alternate(dev);
- em28xx_resolution_set(dev);
-
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (videobuf_queue_is_busy(&fh->vb_vidq)) {
- em28xx_errdev("%s queue busy\n", __func__);
- return -EBUSY;
- }
-
- return em28xx_set_video_format(dev, f->fmt.pix.pixelformat,
- f->fmt.pix.width, f->fmt.pix.height);
-}
-
-static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- *norm = dev->norm;
-
- return 0;
-}
-
-static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, video, querystd, norm);
-
- return 0;
-}
-
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- struct v4l2_format f;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- dev->norm = *norm;
-
- /* Adjusts width/height, if needed */
- f.fmt.pix.width = dev->width;
- f.fmt.pix.height = dev->height;
- vidioc_try_fmt_vid_cap(file, priv, &f);
-
- /* set new image size */
- dev->width = f.fmt.pix.width;
- dev->height = f.fmt.pix.height;
- get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
-
- em28xx_resolution_set(dev);
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
-
- return 0;
-}
-
-static int vidioc_g_parm(struct file *file, void *priv,
- struct v4l2_streamparm *p)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc = 0;
-
- if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (dev->board.is_webcam)
- rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0,
- video, g_parm, p);
- else
- v4l2_video_std_frame_period(dev->norm,
- &p->parm.capture.timeperframe);
-
- return rc;
-}
-
-static int vidioc_s_parm(struct file *file, void *priv,
- struct v4l2_streamparm *p)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
-
- if (!dev->board.is_webcam)
- return -EINVAL;
-
- if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- return v4l2_device_call_until_err(&dev->v4l2_dev, 0, video, s_parm, p);
-}
-
-static const char *iname[] = {
- [EM28XX_VMUX_COMPOSITE1] = "Composite1",
- [EM28XX_VMUX_COMPOSITE2] = "Composite2",
- [EM28XX_VMUX_COMPOSITE3] = "Composite3",
- [EM28XX_VMUX_COMPOSITE4] = "Composite4",
- [EM28XX_VMUX_SVIDEO] = "S-Video",
- [EM28XX_VMUX_TELEVISION] = "Television",
- [EM28XX_VMUX_CABLE] = "Cable TV",
- [EM28XX_VMUX_DVB] = "DVB",
- [EM28XX_VMUX_DEBUG] = "for debug only",
-};
-
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- unsigned int n;
-
- n = i->index;
- if (n >= MAX_EM28XX_INPUT)
- return -EINVAL;
- if (0 == INPUT(n)->type)
- return -EINVAL;
-
- i->index = n;
- i->type = V4L2_INPUT_TYPE_CAMERA;
-
- strcpy(i->name, iname[INPUT(n)->type]);
-
- if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
- (EM28XX_VMUX_CABLE == INPUT(n)->type))
- i->type = V4L2_INPUT_TYPE_TUNER;
-
- i->std = dev->vdev->tvnorms;
-
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
-
- *i = dev->ctl_input;
-
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (i >= MAX_EM28XX_INPUT)
- return -EINVAL;
- if (0 == INPUT(i)->type)
- return -EINVAL;
-
- video_mux(dev, i);
- return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
-
- if (!dev->audio_mode.has_audio)
- return -EINVAL;
-
- switch (a->index) {
- case EM28XX_AMUX_VIDEO:
- strcpy(a->name, "Television");
- break;
- case EM28XX_AMUX_LINE_IN:
- strcpy(a->name, "Line In");
- break;
- case EM28XX_AMUX_VIDEO2:
- strcpy(a->name, "Television alt");
- break;
- case EM28XX_AMUX_PHONE:
- strcpy(a->name, "Phone");
- break;
- case EM28XX_AMUX_MIC:
- strcpy(a->name, "Mic");
- break;
- case EM28XX_AMUX_CD:
- strcpy(a->name, "CD");
- break;
- case EM28XX_AMUX_AUX:
- strcpy(a->name, "Aux");
- break;
- case EM28XX_AMUX_PCM_OUT:
- strcpy(a->name, "PCM");
- break;
- default:
- return -EINVAL;
- }
-
- a->index = dev->ctl_ainput;
- a->capability = V4L2_AUDCAP_STEREO;
-
- return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
-
-
- if (!dev->audio_mode.has_audio)
- return -EINVAL;
-
- if (a->index >= MAX_EM28XX_INPUT)
- return -EINVAL;
- if (0 == INPUT(a->index)->type)
- return -EINVAL;
-
- dev->ctl_ainput = INPUT(a->index)->amux;
- dev->ctl_aoutput = INPUT(a->index)->aout;
-
- if (!dev->ctl_aoutput)
- dev->ctl_aoutput = EM28XX_AOUT_MASTER;
-
- return 0;
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qc)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int id = qc->id;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- memset(qc, 0, sizeof(*qc));
-
- qc->id = id;
-
- /* enumerate AC97 controls */
- if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
- rc = ac97_queryctrl(qc);
- if (!rc)
- return 0;
- }
-
- /* enumerate V4L2 device controls */
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc);
-
- if (qc->type)
- return 0;
- else
- return -EINVAL;
-}
-
-/*
- * FIXME: This is an indirect way to check if a control exists at a
- * subdev. Instead of that hack, maybe the better would be to change all
- * subdevs to return -ENOIOCTLCMD, if an ioctl is not supported.
- */
-static int check_subdev_ctrl(struct em28xx *dev, int id)
-{
- struct v4l2_queryctrl qc;
-
- memset(&qc, 0, sizeof(qc));
- qc.id = id;
-
- /* enumerate V4L2 device controls */
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, &qc);
-
- if (qc.type)
- return 0;
- else
- return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
- rc = 0;
-
- /* Set an AC97 control */
- if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
- rc = ac97_get_ctrl(dev, ctrl);
- else
- rc = 1;
-
- /* It were not an AC97 control. Sends it to the v4l2 dev interface */
- if (rc == 1) {
- if (check_subdev_ctrl(dev, ctrl->id))
- return -EINVAL;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
- rc = 0;
- }
-
- return rc;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- /* Set an AC97 control */
- if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
- rc = ac97_set_ctrl(dev, ctrl);
- else
- rc = 1;
-
- /* It isn't an AC97 control. Sends it to the v4l2 dev interface */
- if (rc == 1) {
- rc = check_subdev_ctrl(dev, ctrl->id);
- if (!rc)
- v4l2_device_call_all(&dev->v4l2_dev, 0,
- core, s_ctrl, ctrl);
- /*
- * In the case of non-AC97 volume controls, we still need
- * to do some setups at em28xx, in order to mute/unmute
- * and to adjust audio volume. However, the value ranges
- * should be checked by the corresponding V4L subdriver.
- */
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- dev->mute = ctrl->value;
- rc = em28xx_audio_analog_set(dev);
- break;
- case V4L2_CID_AUDIO_VOLUME:
- dev->volume = ctrl->value;
- rc = em28xx_audio_analog_set(dev);
- }
- }
- return (rc < 0) ? rc : 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (0 != t->index)
- return -EINVAL;
-
- strcpy(t->name, "Tuner");
- t->type = V4L2_TUNER_ANALOG_TV;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
- return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (0 != t->index)
- return -EINVAL;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
- return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
-
- f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- f->frequency = dev->ctl_freq;
- return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (0 != f->tuner)
- return -EINVAL;
-
- if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV))
- return -EINVAL;
- if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO))
- return -EINVAL;
-
- dev->ctl_freq = f->frequency;
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f);
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int em28xx_reg_len(int reg)
-{
- switch (reg) {
- case EM28XX_R40_AC97LSB:
- case EM28XX_R30_HSCALELOW:
- case EM28XX_R32_VSCALELOW:
- return 2;
- default:
- return 1;
- }
-}
-
-static int vidioc_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
-
- return 0;
-}
-
-
-static int vidioc_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int ret;
-
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_AC97:
- ret = em28xx_read_ac97(dev, reg->reg);
- if (ret < 0)
- return ret;
-
- reg->val = ret;
- reg->size = 1;
- return 0;
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
- return 0;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- /* TODO: is this correct? */
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
- return 0;
- default:
- if (!v4l2_chip_match_host(&reg->match))
- return -EINVAL;
- }
-
- /* Match host */
- reg->size = em28xx_reg_len(reg->reg);
- if (reg->size == 1) {
- ret = em28xx_read_reg(dev, reg->reg);
-
- if (ret < 0)
- return ret;
-
- reg->val = ret;
- } else {
- __le16 val = 0;
- ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
- reg->reg, (char *)&val, 2);
- if (ret < 0)
- return ret;
-
- reg->val = le16_to_cpu(val);
- }
-
- return 0;
-}
-
-static int vidioc_s_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- __le16 buf;
-
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_AC97:
- return em28xx_write_ac97(dev, reg->reg, reg->val);
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
- return 0;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- /* TODO: is this correct? */
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
- return 0;
- default:
- if (!v4l2_chip_match_host(&reg->match))
- return -EINVAL;
- }
-
- /* Match host */
- buf = cpu_to_le16(reg->val);
-
- return em28xx_write_regs(dev, reg->reg, (char *)&buf,
- em28xx_reg_len(reg->reg));
-}
-#endif
-
-
-static int vidioc_cropcap(struct file *file, void *priv,
- struct v4l2_cropcap *cc)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
-
- if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- cc->bounds.left = 0;
- cc->bounds.top = 0;
- cc->bounds.width = dev->width;
- cc->bounds.height = dev->height;
- cc->defrect = cc->bounds;
- cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */
- cc->pixelaspect.denominator = 59;
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc = -EINVAL;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (unlikely(type != fh->type))
- return -EINVAL;
-
- em28xx_videodbg("vidioc_streamon fh=%p t=%d fh->res=%d dev->res=%d\n",
- fh, type, fh->resources, dev->resources);
-
- if (unlikely(!res_get(fh, get_ressource(fh))))
- return -EBUSY;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- rc = videobuf_streamon(&fh->vb_vidq);
- else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
- rc = videobuf_streamon(&fh->vb_vbiq);
-
- return rc;
-}
-
-static int vidioc_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
- fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)
- return -EINVAL;
- if (type != fh->type)
- return -EINVAL;
-
- em28xx_videodbg("vidioc_streamoff fh=%p t=%d fh->res=%d dev->res=%d\n",
- fh, type, fh->resources, dev->resources);
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- if (res_check(fh, EM28XX_RESOURCE_VIDEO)) {
- videobuf_streamoff(&fh->vb_vidq);
- res_free(fh, EM28XX_RESOURCE_VIDEO);
- }
- } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- if (res_check(fh, EM28XX_RESOURCE_VBI)) {
- videobuf_streamoff(&fh->vb_vbiq);
- res_free(fh, EM28XX_RESOURCE_VBI);
- }
- }
-
- return 0;
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
-
- strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
- strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
- usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
-
- cap->capabilities =
- V4L2_CAP_SLICED_VBI_CAPTURE |
- V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
-
- if (dev->vbi_dev)
- cap->capabilities |= V4L2_CAP_VBI_CAPTURE;
-
- if (dev->audio_mode.has_audio)
- cap->capabilities |= V4L2_CAP_AUDIO;
-
- if (dev->tuner_type != TUNER_ABSENT)
- cap->capabilities |= V4L2_CAP_TUNER;
-
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (unlikely(f->index >= ARRAY_SIZE(format)))
- return -EINVAL;
-
- strlcpy(f->description, format[f->index].name, sizeof(f->description));
- f->pixelformat = format[f->index].fourcc;
-
- return 0;
-}
-
-static int vidioc_enum_framesizes(struct file *file, void *priv,
- struct v4l2_frmsizeenum *fsize)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- struct em28xx_fmt *fmt;
- unsigned int maxw = norm_maxw(dev);
- unsigned int maxh = norm_maxh(dev);
-
- fmt = format_by_fourcc(fsize->pixel_format);
- if (!fmt) {
- em28xx_videodbg("Fourcc format (%08x) invalid.\n",
- fsize->pixel_format);
- return -EINVAL;
- }
-
- if (dev->board.is_em2800) {
- if (fsize->index > 1)
- return -EINVAL;
- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fsize->discrete.width = maxw / (1 + fsize->index);
- fsize->discrete.height = maxh / (1 + fsize->index);
- return 0;
- }
-
- if (fsize->index != 0)
- return -EINVAL;
-
- /* Report a continuous range */
- fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
- fsize->stepwise.min_width = 48;
- fsize->stepwise.min_height = 32;
- fsize->stepwise.max_width = maxw;
- fsize->stepwise.max_height = maxh;
- fsize->stepwise.step_width = 1;
- fsize->stepwise.step_height = 1;
- return 0;
-}
-
-/* Sliced VBI ioctls */
-static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- f->fmt.sliced.service_set = 0;
- v4l2_device_call_all(&dev->v4l2_dev, 0, vbi, g_sliced_fmt, &f->fmt.sliced);
-
- if (f->fmt.sliced.service_set == 0)
- rc = -EINVAL;
-
- return rc;
-}
-
-static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, vbi, g_sliced_fmt, &f->fmt.sliced);
-
- if (f->fmt.sliced.service_set == 0)
- return -EINVAL;
-
- return 0;
-}
-
-/* RAW VBI ioctls */
-
-static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
- struct v4l2_format *format)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
-
- format->fmt.vbi.samples_per_line = dev->vbi_width;
- format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
- format->fmt.vbi.offset = 0;
- format->fmt.vbi.flags = 0;
- format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
- format->fmt.vbi.count[0] = dev->vbi_height;
- format->fmt.vbi.count[1] = dev->vbi_height;
-
- /* Varies by video standard (NTSC, PAL, etc.) */
- if (dev->norm & V4L2_STD_525_60) {
- /* NTSC */
- format->fmt.vbi.start[0] = 10;
- format->fmt.vbi.start[1] = 273;
- } else if (dev->norm & V4L2_STD_625_50) {
- /* PAL */
- format->fmt.vbi.start[0] = 6;
- format->fmt.vbi.start[1] = 318;
- }
-
- return 0;
-}
-
-static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
- struct v4l2_format *format)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
-
- format->fmt.vbi.samples_per_line = dev->vbi_width;
- format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
- format->fmt.vbi.offset = 0;
- format->fmt.vbi.flags = 0;
- format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
- format->fmt.vbi.count[0] = dev->vbi_height;
- format->fmt.vbi.count[1] = dev->vbi_height;
-
- /* Varies by video standard (NTSC, PAL, etc.) */
- if (dev->norm & V4L2_STD_525_60) {
- /* NTSC */
- format->fmt.vbi.start[0] = 10;
- format->fmt.vbi.start[1] = 273;
- } else if (dev->norm & V4L2_STD_625_50) {
- /* PAL */
- format->fmt.vbi.start[0] = 6;
- format->fmt.vbi.start[1] = 318;
- }
-
- return 0;
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *rb)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return videobuf_reqbufs(&fh->vb_vidq, rb);
- else
- return videobuf_reqbufs(&fh->vb_vbiq, rb);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return videobuf_querybuf(&fh->vb_vidq, b);
- else {
- /* FIXME: I'm not sure yet whether this is a bug in zvbi or
- the videobuf framework, but we probably shouldn't be
- returning a buffer larger than that which was asked for.
- At a minimum, it causes a crash in zvbi since it does
- a memcpy based on the source buffer length */
- int result = videobuf_querybuf(&fh->vb_vbiq, b);
- b->length = dev->vbi_width * dev->vbi_height * 2;
-
- return result;
- }
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return videobuf_qbuf(&fh->vb_vidq, b);
- else
- return videobuf_qbuf(&fh->vb_vbiq, b);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags &
- O_NONBLOCK);
- else
- return videobuf_dqbuf(&fh->vb_vbiq, b, file->f_flags &
- O_NONBLOCK);
-}
-
-/* ----------------------------------------------------------- */
-/* RADIO ESPECIFIC IOCTLS */
-/* ----------------------------------------------------------- */
-
-static int radio_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
-
- strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
- strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
- usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
-
- cap->capabilities = V4L2_CAP_TUNER;
- return 0;
-}
-
-static int radio_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
-
- if (unlikely(t->index > 0))
- return -EINVAL;
-
- strcpy(t->name, "Radio");
- t->type = V4L2_TUNER_RADIO;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
-
- return 0;
-}
-
-static int radio_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- if (i->index != 0)
- return -EINVAL;
- strcpy(i->name, "Radio");
- i->type = V4L2_INPUT_TYPE_TUNER;
-
- return 0;
-}
-
-static int radio_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- if (unlikely(a->index))
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- return 0;
-}
-
-static int radio_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
-
- if (0 != t->index)
- return -EINVAL;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
-
- return 0;
-}
-
-static int radio_s_audio(struct file *file, void *fh,
- struct v4l2_audio *a)
-{
- return 0;
-}
-
-static int radio_s_input(struct file *file, void *fh, unsigned int i)
-{
- return 0;
-}
-
-static int radio_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qc)
-{
- int i;
-
- if (qc->id < V4L2_CID_BASE ||
- qc->id >= V4L2_CID_LASTP1)
- return -EINVAL;
-
- for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) {
- if (qc->id && qc->id == ac97_qctrl[i].id) {
- memcpy(qc, &(ac97_qctrl[i]), sizeof(*qc));
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-/*
- * em28xx_v4l2_open()
- * inits the device and starts isoc transfer
- */
-static int em28xx_v4l2_open(struct file *filp)
-{
- int errCode = 0, radio = 0;
- struct video_device *vdev = video_devdata(filp);
- struct em28xx *dev = video_drvdata(filp);
- enum v4l2_buf_type fh_type = 0;
- struct em28xx_fh *fh;
- enum v4l2_field field;
-
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- case VFL_TYPE_VBI:
- fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- case VFL_TYPE_RADIO:
- radio = 1;
- break;
- }
-
- em28xx_videodbg("open dev=%s type=%s users=%d\n",
- video_device_node_name(vdev), v4l2_type_names[fh_type],
- dev->users);
-
-
- fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
- if (!fh) {
- em28xx_errdev("em28xx-video.c: Out of memory?!\n");
- return -ENOMEM;
- }
- fh->dev = dev;
- fh->radio = radio;
- fh->type = fh_type;
- filp->private_data = fh;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
- em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
- em28xx_set_alternate(dev);
- em28xx_resolution_set(dev);
-
- /* Needed, since GPIO might have disabled power of
- some i2c device
- */
- em28xx_wake_i2c(dev);
-
- }
- if (fh->radio) {
- em28xx_videodbg("video_open: setting radio device\n");
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
- }
-
- dev->users++;
-
- if (dev->progressive)
- field = V4L2_FIELD_NONE;
- else
- field = V4L2_FIELD_INTERLACED;
-
- videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops,
- NULL, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE, field,
- sizeof(struct em28xx_buffer), fh, &dev->lock);
-
- videobuf_queue_vmalloc_init(&fh->vb_vbiq, &em28xx_vbi_qops,
- NULL, &dev->slock,
- V4L2_BUF_TYPE_VBI_CAPTURE,
- V4L2_FIELD_SEQ_TB,
- sizeof(struct em28xx_buffer), fh, &dev->lock);
-
- return errCode;
-}
-
-/*
- * em28xx_realease_resources()
- * unregisters the v4l2,i2c and usb devices
- * called when the device gets disconected or at module unload
-*/
-void em28xx_release_analog_resources(struct em28xx *dev)
-{
-
- /*FIXME: I2C IR should be disconnected */
-
- if (dev->radio_dev) {
- if (video_is_registered(dev->radio_dev))
- video_unregister_device(dev->radio_dev);
- else
- video_device_release(dev->radio_dev);
- dev->radio_dev = NULL;
- }
- if (dev->vbi_dev) {
- em28xx_info("V4L2 device %s deregistered\n",
- video_device_node_name(dev->vbi_dev));
- if (video_is_registered(dev->vbi_dev))
- video_unregister_device(dev->vbi_dev);
- else
- video_device_release(dev->vbi_dev);
- dev->vbi_dev = NULL;
- }
- if (dev->vdev) {
- em28xx_info("V4L2 device %s deregistered\n",
- video_device_node_name(dev->vdev));
- if (video_is_registered(dev->vdev))
- video_unregister_device(dev->vdev);
- else
- video_device_release(dev->vdev);
- dev->vdev = NULL;
- }
-}
-
-/*
- * em28xx_v4l2_close()
- * stops streaming and deallocates all resources allocated by the v4l2
- * calls and ioctls
- */
-static int em28xx_v4l2_close(struct file *filp)
-{
- struct em28xx_fh *fh = filp->private_data;
- struct em28xx *dev = fh->dev;
- int errCode;
-
- em28xx_videodbg("users=%d\n", dev->users);
-
- if (res_check(fh, EM28XX_RESOURCE_VIDEO)) {
- videobuf_stop(&fh->vb_vidq);
- res_free(fh, EM28XX_RESOURCE_VIDEO);
- }
-
- if (res_check(fh, EM28XX_RESOURCE_VBI)) {
- videobuf_stop(&fh->vb_vbiq);
- res_free(fh, EM28XX_RESOURCE_VBI);
- }
-
- if (dev->users == 1) {
- /* the device is already disconnect,
- free the remaining resources */
- if (dev->state & DEV_DISCONNECTED) {
- em28xx_release_resources(dev);
- kfree(dev->alt_max_pkt_size);
- kfree(dev);
- kfree(fh);
- return 0;
- }
-
- /* Save some power by putting tuner to sleep */
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
-
- /* do this before setting alternate! */
- em28xx_uninit_isoc(dev, EM28XX_ANALOG_MODE);
- em28xx_set_mode(dev, EM28XX_SUSPEND);
-
- /* set alternate 0 */
- dev->alt = 0;
- em28xx_videodbg("setting alternate 0\n");
- errCode = usb_set_interface(dev->udev, 0, 0);
- if (errCode < 0) {
- em28xx_errdev("cannot change alternate number to "
- "0 (error=%i)\n", errCode);
- }
- }
-
- videobuf_mmap_free(&fh->vb_vidq);
- videobuf_mmap_free(&fh->vb_vbiq);
- kfree(fh);
- dev->users--;
- return 0;
-}
-
-/*
- * em28xx_v4l2_read()
- * will allocate buffers when called for the first time
- */
-static ssize_t
-em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
- loff_t *pos)
-{
- struct em28xx_fh *fh = filp->private_data;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- /* FIXME: read() is not prepared to allow changing the video
- resolution while streaming. Seems a bug at em28xx_set_fmt
- */
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- if (res_locked(dev, EM28XX_RESOURCE_VIDEO))
- return -EBUSY;
-
- return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
- filp->f_flags & O_NONBLOCK);
- }
-
-
- if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- if (!res_get(fh, EM28XX_RESOURCE_VBI))
- return -EBUSY;
-
- return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
- filp->f_flags & O_NONBLOCK);
- }
-
- return 0;
-}
-
-/*
- * em28xx_v4l2_poll()
- * will allocate buffers when called for the first time
- */
-static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
-{
- struct em28xx_fh *fh = filp->private_data;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- if (!res_get(fh, EM28XX_RESOURCE_VIDEO))
- return POLLERR;
- return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
- } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- if (!res_get(fh, EM28XX_RESOURCE_VBI))
- return POLLERR;
- return videobuf_poll_stream(filp, &fh->vb_vbiq, wait);
- } else {
- return POLLERR;
- }
-}
-
-/*
- * em28xx_v4l2_mmap()
- */
-static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- struct em28xx_fh *fh = filp->private_data;
- struct em28xx *dev = fh->dev;
- int rc;
-
- rc = check_dev(dev);
- if (rc < 0)
- return rc;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
- else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
- rc = videobuf_mmap_mapper(&fh->vb_vbiq, vma);
-
- em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",
- (unsigned long)vma->vm_start,
- (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
- rc);
-
- return rc;
-}
-
-static const struct v4l2_file_operations em28xx_v4l_fops = {
- .owner = THIS_MODULE,
- .open = em28xx_v4l2_open,
- .release = em28xx_v4l2_close,
- .read = em28xx_v4l2_read,
- .poll = em28xx_v4l2_poll,
- .mmap = em28xx_v4l2_mmap,
- .unlocked_ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
- .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
- .vidioc_enum_framesizes = vidioc_enum_framesizes,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_cropcap = vidioc_cropcap,
- .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
- .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
- .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
-
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_g_std = vidioc_g_std,
- .vidioc_querystd = vidioc_querystd,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_g_parm = vidioc_g_parm,
- .vidioc_s_parm = vidioc_s_parm,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vidioc_g_register,
- .vidioc_s_register = vidioc_s_register,
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
-#endif
-};
-
-static const struct video_device em28xx_video_template = {
- .fops = &em28xx_v4l_fops,
- .release = video_device_release,
- .ioctl_ops = &video_ioctl_ops,
-
- .tvnorms = V4L2_STD_ALL,
- .current_norm = V4L2_STD_PAL,
-};
-
-static const struct v4l2_file_operations radio_fops = {
- .owner = THIS_MODULE,
- .open = em28xx_v4l2_open,
- .release = em28xx_v4l2_close,
- .unlocked_ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops radio_ioctl_ops = {
- .vidioc_querycap = radio_querycap,
- .vidioc_g_tuner = radio_g_tuner,
- .vidioc_enum_input = radio_enum_input,
- .vidioc_g_audio = radio_g_audio,
- .vidioc_s_tuner = radio_s_tuner,
- .vidioc_s_audio = radio_s_audio,
- .vidioc_s_input = radio_s_input,
- .vidioc_queryctrl = radio_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vidioc_g_register,
- .vidioc_s_register = vidioc_s_register,
-#endif
-};
-
-static struct video_device em28xx_radio_template = {
- .name = "em28xx-radio",
- .fops = &radio_fops,
- .ioctl_ops = &radio_ioctl_ops,
-};
-
-/******************************** usb interface ******************************/
-
-
-
-static struct video_device *em28xx_vdev_init(struct em28xx *dev,
- const struct video_device *template,
- const char *type_name)
-{
- struct video_device *vfd;
-
- vfd = video_device_alloc();
- if (NULL == vfd)
- return NULL;
-
- *vfd = *template;
- vfd->v4l2_dev = &dev->v4l2_dev;
- vfd->release = video_device_release;
- vfd->debug = video_debug;
- vfd->lock = &dev->lock;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
-
- snprintf(vfd->name, sizeof(vfd->name), "%s %s",
- dev->name, type_name);
-
- video_set_drvdata(vfd, dev);
- return vfd;
-}
-
-int em28xx_register_analog_devices(struct em28xx *dev)
-{
- u8 val;
- int ret;
- unsigned int maxw;
-
- printk(KERN_INFO "%s: v4l2 driver version %s\n",
- dev->name, EM28XX_VERSION);
-
- /* set default norm */
- dev->norm = em28xx_video_template.current_norm;
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
- dev->interlaced = EM28XX_INTERLACED_DEFAULT;
-
- /* Analog specific initialization */
- dev->format = &format[0];
-
- maxw = norm_maxw(dev);
- /* MaxPacketSize for em2800 is too small to capture at full resolution
- * use half of maxw as the scaler can only scale to 50% */
- if (dev->board.is_em2800)
- maxw /= 2;
-
- em28xx_set_video_format(dev, format[0].fourcc,
- maxw, norm_maxh(dev));
-
- video_mux(dev, 0);
-
- /* Audio defaults */
- dev->mute = 1;
- dev->volume = 0x1f;
-
-/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
- val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
- em28xx_write_reg(dev, EM28XX_R0F_XCLK,
- (EM28XX_XCLK_AUDIO_UNMUTE | val));
-
- em28xx_set_outfmt(dev);
- em28xx_colorlevels_set_default(dev);
- em28xx_compression_disable(dev);
-
- /* allocate and fill video video_device struct */
- dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
- if (!dev->vdev) {
- em28xx_errdev("cannot allocate video_device.\n");
- return -ENODEV;
- }
-
- /* register v4l2 video video_device */
- ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
- video_nr[dev->devno]);
- if (ret) {
- em28xx_errdev("unable to register video device (error=%i).\n",
- ret);
- return ret;
- }
-
- /* Allocate and fill vbi video_device struct */
- if (em28xx_vbi_supported(dev) == 1) {
- dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template,
- "vbi");
-
- /* register v4l2 vbi video_device */
- ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
- vbi_nr[dev->devno]);
- if (ret < 0) {
- em28xx_errdev("unable to register vbi device\n");
- return ret;
- }
- }
-
- if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
- dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
- "radio");
- if (!dev->radio_dev) {
- em28xx_errdev("cannot allocate video_device.\n");
- return -ENODEV;
- }
- ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
- radio_nr[dev->devno]);
- if (ret < 0) {
- em28xx_errdev("can't register radio device\n");
- return ret;
- }
- em28xx_info("Registered radio device as %s\n",
- video_device_node_name(dev->radio_dev));
- }
-
- em28xx_info("V4L2 video device registered as %s\n",
- video_device_node_name(dev->vdev));
-
- if (dev->vbi_dev)
- em28xx_info("V4L2 VBI device registered as %s\n",
- video_device_node_name(dev->vbi_dev));
-
- return 0;
-}
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
deleted file mode 100644
index 8757523e686..00000000000
--- a/drivers/media/video/em28xx/em28xx.h
+++ /dev/null
@@ -1,809 +0,0 @@
-/*
- em28xx.h - driver for Empia EM2800/EM2820/2840 USB video capture devices
-
- Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
- Ludovico Cavedon <cavedon@sssup.it>
- Mauro Carvalho Chehab <mchehab@infradead.org>
-
- Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _EM28XX_H
-#define _EM28XX_H
-
-#include <linux/workqueue.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <linux/videodev2.h>
-
-#include <media/videobuf-vmalloc.h>
-#include <media/v4l2-device.h>
-#include <media/ir-kbd-i2c.h>
-#include <media/rc-core.h>
-#if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE)
-#include <media/videobuf-dvb.h>
-#endif
-#include "tuner-xc2028.h"
-#include "xc5000.h"
-#include "em28xx-reg.h"
-
-/* Boards supported by driver */
-#define EM2800_BOARD_UNKNOWN 0
-#define EM2820_BOARD_UNKNOWN 1
-#define EM2820_BOARD_TERRATEC_CINERGY_250 2
-#define EM2820_BOARD_PINNACLE_USB_2 3
-#define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4
-#define EM2820_BOARD_MSI_VOX_USB_2 5
-#define EM2800_BOARD_TERRATEC_CINERGY_200 6
-#define EM2800_BOARD_LEADTEK_WINFAST_USBII 7
-#define EM2800_BOARD_KWORLD_USB2800 8
-#define EM2820_BOARD_PINNACLE_DVC_90 9
-#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 10
-#define EM2880_BOARD_TERRATEC_HYBRID_XS 11
-#define EM2820_BOARD_KWORLD_PVRTV2800RF 12
-#define EM2880_BOARD_TERRATEC_PRODIGY_XS 13
-#define EM2820_BOARD_PROLINK_PLAYTV_USB2 14
-#define EM2800_BOARD_VGEAR_POCKETTV 15
-#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 16
-#define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17
-#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18
-#define EM2860_BOARD_SAA711X_REFERENCE_DESIGN 19
-#define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20
-#define EM2800_BOARD_GRABBEEX_USB2800 21
-#define EM2750_BOARD_UNKNOWN 22
-#define EM2750_BOARD_DLCW_130 23
-#define EM2820_BOARD_DLINK_USB_TV 24
-#define EM2820_BOARD_GADMEI_UTV310 25
-#define EM2820_BOARD_HERCULES_SMART_TV_USB2 26
-#define EM2820_BOARD_PINNACLE_USB_2_FM1216ME 27
-#define EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE 28
-#define EM2860_BOARD_TVP5150_REFERENCE_DESIGN 29
-#define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30
-#define EM2821_BOARD_USBGEAR_VD204 31
-#define EM2821_BOARD_SUPERCOMP_USB_2 32
-#define EM2860_BOARD_ELGATO_VIDEO_CAPTURE 33
-#define EM2860_BOARD_TERRATEC_HYBRID_XS 34
-#define EM2860_BOARD_TYPHOON_DVD_MAKER 35
-#define EM2860_BOARD_NETGMBH_CAM 36
-#define EM2860_BOARD_GADMEI_UTV330 37
-#define EM2861_BOARD_YAKUMO_MOVIE_MIXER 38
-#define EM2861_BOARD_KWORLD_PVRTV_300U 39
-#define EM2861_BOARD_PLEXTOR_PX_TV100U 40
-#define EM2870_BOARD_KWORLD_350U 41
-#define EM2870_BOARD_KWORLD_355U 42
-#define EM2870_BOARD_TERRATEC_XS 43
-#define EM2870_BOARD_TERRATEC_XS_MT2060 44
-#define EM2870_BOARD_PINNACLE_PCTV_DVB 45
-#define EM2870_BOARD_COMPRO_VIDEOMATE 46
-#define EM2880_BOARD_KWORLD_DVB_305U 47
-#define EM2880_BOARD_KWORLD_DVB_310U 48
-#define EM2880_BOARD_MSI_DIGIVOX_AD 49
-#define EM2880_BOARD_MSI_DIGIVOX_AD_II 50
-#define EM2880_BOARD_TERRATEC_HYBRID_XS_FR 51
-#define EM2881_BOARD_DNT_DA2_HYBRID 52
-#define EM2881_BOARD_PINNACLE_HYBRID_PRO 53
-#define EM2882_BOARD_KWORLD_VS_DVBT 54
-#define EM2882_BOARD_TERRATEC_HYBRID_XS 55
-#define EM2882_BOARD_PINNACLE_HYBRID_PRO_330E 56
-#define EM2883_BOARD_KWORLD_HYBRID_330U 57
-#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58
-#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60
-#define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61
-#define EM2820_BOARD_GADMEI_TVR200 62
-#define EM2860_BOARD_KAIOMY_TVNPC_U2 63
-#define EM2860_BOARD_EASYCAP 64
-#define EM2820_BOARD_IODATA_GVMVP_SZ 65
-#define EM2880_BOARD_EMPIRE_DUAL_TV 66
-#define EM2860_BOARD_TERRATEC_GRABBY 67
-#define EM2860_BOARD_TERRATEC_AV350 68
-#define EM2882_BOARD_KWORLD_ATSC_315U 69
-#define EM2882_BOARD_EVGA_INDTUBE 70
-#define EM2820_BOARD_SILVERCREST_WEBCAM 71
-#define EM2861_BOARD_GADMEI_UTV330PLUS 72
-#define EM2870_BOARD_REDDO_DVB_C_USB_BOX 73
-#define EM2800_BOARD_VC211A 74
-#define EM2882_BOARD_DIKOM_DK300 75
-#define EM2870_BOARD_KWORLD_A340 76
-#define EM2874_BOARD_LEADERSHIP_ISDBT 77
-#define EM28174_BOARD_PCTV_290E 78
-#define EM2884_BOARD_TERRATEC_H5 79
-#define EM28174_BOARD_PCTV_460E 80
-#define EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C 81
-#define EM2884_BOARD_CINERGY_HTC_STICK 82
-#define EM2860_BOARD_HT_VIDBOX_NW03 83
-#define EM2874_BOARD_MAXMEDIA_UB425_TC 84
-#define EM2884_BOARD_PCTV_510E 85
-#define EM2884_BOARD_PCTV_520E 86
-
-/* Limits minimum and default number of buffers */
-#define EM28XX_MIN_BUF 4
-#define EM28XX_DEF_BUF 8
-
-/*Limits the max URB message size */
-#define URB_MAX_CTRL_SIZE 80
-
-/* Params for validated field */
-#define EM28XX_BOARD_NOT_VALIDATED 1
-#define EM28XX_BOARD_VALIDATED 0
-
-/* Params for em28xx_cmd() audio */
-#define EM28XX_START_AUDIO 1
-#define EM28XX_STOP_AUDIO 0
-
-/* maximum number of em28xx boards */
-#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
-
-/* maximum number of frames that can be queued */
-#define EM28XX_NUM_FRAMES 5
-/* number of frames that get used for v4l2_read() */
-#define EM28XX_NUM_READ_FRAMES 2
-
-/* number of buffers for isoc transfers */
-#define EM28XX_NUM_BUFS 5
-#define EM28XX_DVB_NUM_BUFS 5
-
-/* number of packets for each buffer
- windows requests only 64 packets .. so we better do the same
- this is what I found out for all alternate numbers there!
- */
-#define EM28XX_NUM_PACKETS 64
-#define EM28XX_DVB_MAX_PACKETS 64
-
-#define EM28XX_INTERLACED_DEFAULT 1
-
-/*
-#define (use usbview if you want to get the other alternate number infos)
-#define
-#define alternate number 2
-#define Endpoint Address: 82
- Direction: in
- Attribute: 1
- Type: Isoc
- Max Packet Size: 1448
- Interval: 125us
-
- alternate number 7
-
- Endpoint Address: 82
- Direction: in
- Attribute: 1
- Type: Isoc
- Max Packet Size: 3072
- Interval: 125us
-*/
-
-/* time to wait when stopping the isoc transfer */
-#define EM28XX_URB_TIMEOUT \
- msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
-
-/* time in msecs to wait for i2c writes to finish */
-#define EM2800_I2C_WRITE_TIMEOUT 20
-
-enum em28xx_mode {
- EM28XX_SUSPEND,
- EM28XX_ANALOG_MODE,
- EM28XX_DIGITAL_MODE,
-};
-
-
-struct em28xx;
-
-struct em28xx_usb_isoc_bufs {
- /* max packet size of isoc transaction */
- int max_pkt_size;
-
- /* number of packets in each buffer */
- int num_packets;
-
- /* number of allocated urbs */
- int num_bufs;
-
- /* urb for isoc transfers */
- struct urb **urb;
-
- /* transfer buffers for isoc transfer */
- char **transfer_buffer;
-};
-
-struct em28xx_usb_isoc_ctl {
- /* isoc transfer buffers for analog mode */
- struct em28xx_usb_isoc_bufs analog_bufs;
-
- /* isoc transfer buffers for digital mode */
- struct em28xx_usb_isoc_bufs digital_bufs;
-
- /* Stores already requested buffers */
- struct em28xx_buffer *vid_buf;
- struct em28xx_buffer *vbi_buf;
-
- /* isoc urb callback */
- int (*isoc_copy) (struct em28xx *dev, struct urb *urb);
-
-};
-
-/* Struct to enumberate video formats */
-struct em28xx_fmt {
- char *name;
- u32 fourcc; /* v4l2 format id */
- int depth;
- int reg;
-};
-
-/* buffer for one video frame */
-struct em28xx_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
-
- struct list_head frame;
- int top_field;
-};
-
-struct em28xx_dmaqueue {
- struct list_head active;
-
- wait_queue_head_t wq;
-
- /* Counters to control buffer fill */
- int pos;
-};
-
-/* inputs */
-
-#define MAX_EM28XX_INPUT 4
-enum enum28xx_itype {
- EM28XX_VMUX_COMPOSITE1 = 1,
- EM28XX_VMUX_COMPOSITE2,
- EM28XX_VMUX_COMPOSITE3,
- EM28XX_VMUX_COMPOSITE4,
- EM28XX_VMUX_SVIDEO,
- EM28XX_VMUX_TELEVISION,
- EM28XX_VMUX_CABLE,
- EM28XX_VMUX_DVB,
- EM28XX_VMUX_DEBUG,
- EM28XX_RADIO,
-};
-
-enum em28xx_ac97_mode {
- EM28XX_NO_AC97 = 0,
- EM28XX_AC97_EM202,
- EM28XX_AC97_SIGMATEL,
- EM28XX_AC97_OTHER,
-};
-
-struct em28xx_audio_mode {
- enum em28xx_ac97_mode ac97;
-
- u16 ac97_feat;
- u32 ac97_vendor_id;
-
- unsigned int has_audio:1;
-
- unsigned int i2s_3rates:1;
- unsigned int i2s_5rates:1;
-};
-
-/* em28xx has two audio inputs: tuner and line in.
- However, on most devices, an auxiliary AC97 codec device is used.
- The AC97 device may have several different inputs and outputs,
- depending on their model. So, it is possible to use AC97 mixer to
- address more than two different entries.
- */
-enum em28xx_amux {
- /* This is the only entry for em28xx tuner input */
- EM28XX_AMUX_VIDEO, /* em28xx tuner, AC97 mixer Video */
-
- EM28XX_AMUX_LINE_IN, /* AC97 mixer Line In */
-
- /* Some less-common mixer setups */
- EM28XX_AMUX_VIDEO2, /* em28xx Line in, AC97 mixer Video */
- EM28XX_AMUX_PHONE,
- EM28XX_AMUX_MIC,
- EM28XX_AMUX_CD,
- EM28XX_AMUX_AUX,
- EM28XX_AMUX_PCM_OUT,
-};
-
-enum em28xx_aout {
- /* AC97 outputs */
- EM28XX_AOUT_MASTER = 1 << 0,
- EM28XX_AOUT_LINE = 1 << 1,
- EM28XX_AOUT_MONO = 1 << 2,
- EM28XX_AOUT_LFE = 1 << 3,
- EM28XX_AOUT_SURR = 1 << 4,
-
- /* PCM IN Mixer - used by AC97_RECORD_SELECT register */
- EM28XX_AOUT_PCM_IN = 1 << 7,
-
- /* Bits 10-8 are used to indicate the PCM IN record select */
- EM28XX_AOUT_PCM_MIC_PCM = 0 << 8,
- EM28XX_AOUT_PCM_CD = 1 << 8,
- EM28XX_AOUT_PCM_VIDEO = 2 << 8,
- EM28XX_AOUT_PCM_AUX = 3 << 8,
- EM28XX_AOUT_PCM_LINE = 4 << 8,
- EM28XX_AOUT_PCM_STEREO = 5 << 8,
- EM28XX_AOUT_PCM_MONO = 6 << 8,
- EM28XX_AOUT_PCM_PHONE = 7 << 8,
-};
-
-static inline int ac97_return_record_select(int a_out)
-{
- return (a_out & 0x700) >> 8;
-}
-
-struct em28xx_reg_seq {
- int reg;
- unsigned char val, mask;
- int sleep;
-};
-
-struct em28xx_input {
- enum enum28xx_itype type;
- unsigned int vmux;
- enum em28xx_amux amux;
- enum em28xx_aout aout;
- struct em28xx_reg_seq *gpio;
-};
-
-#define INPUT(nr) (&em28xx_boards[dev->model].input[nr])
-
-enum em28xx_decoder {
- EM28XX_NODECODER = 0,
- EM28XX_TVP5150,
- EM28XX_SAA711X,
-};
-
-enum em28xx_sensor {
- EM28XX_NOSENSOR = 0,
- EM28XX_MT9V011,
- EM28XX_MT9M001,
- EM28XX_MT9M111,
-};
-
-enum em28xx_adecoder {
- EM28XX_NOADECODER = 0,
- EM28XX_TVAUDIO,
-};
-
-struct em28xx_board {
- char *name;
- int vchannels;
- int tuner_type;
- int tuner_addr;
-
- /* i2c flags */
- unsigned int tda9887_conf;
-
- /* GPIO sequences */
- struct em28xx_reg_seq *dvb_gpio;
- struct em28xx_reg_seq *suspend_gpio;
- struct em28xx_reg_seq *tuner_gpio;
- struct em28xx_reg_seq *mute_gpio;
-
- unsigned int is_em2800:1;
- unsigned int has_msp34xx:1;
- unsigned int mts_firmware:1;
- unsigned int max_range_640_480:1;
- unsigned int has_dvb:1;
- unsigned int has_snapshot_button:1;
- unsigned int is_webcam:1;
- unsigned int valid:1;
- unsigned int has_ir_i2c:1;
-
- unsigned char xclk, i2c_speed;
- unsigned char radio_addr;
- unsigned short tvaudio_addr;
-
- enum em28xx_decoder decoder;
- enum em28xx_adecoder adecoder;
-
- struct em28xx_input input[MAX_EM28XX_INPUT];
- struct em28xx_input radio;
- char *ir_codes;
-};
-
-struct em28xx_eeprom {
- u32 id; /* 0x9567eb1a */
- u16 vendor_ID;
- u16 product_ID;
-
- u16 chip_conf;
-
- u16 board_conf;
-
- u16 string1, string2, string3;
-
- u8 string_idx_table;
-};
-
-/* device states */
-enum em28xx_dev_state {
- DEV_INITIALIZED = 0x01,
- DEV_DISCONNECTED = 0x02,
- DEV_MISCONFIGURED = 0x04,
-};
-
-#define EM28XX_AUDIO_BUFS 5
-#define EM28XX_NUM_AUDIO_PACKETS 64
-#define EM28XX_AUDIO_MAX_PACKET_SIZE 196 /* static value */
-#define EM28XX_CAPTURE_STREAM_EN 1
-
-/* em28xx extensions */
-#define EM28XX_AUDIO 0x10
-#define EM28XX_DVB 0x20
-#define EM28XX_RC 0x30
-
-/* em28xx resource types (used for res_get/res_lock etc */
-#define EM28XX_RESOURCE_VIDEO 0x01
-#define EM28XX_RESOURCE_VBI 0x02
-
-struct em28xx_audio {
- char name[50];
- char *transfer_buffer[EM28XX_AUDIO_BUFS];
- struct urb *urb[EM28XX_AUDIO_BUFS];
- struct usb_device *udev;
- unsigned int capture_transfer_done;
- struct snd_pcm_substream *capture_pcm_substream;
-
- unsigned int hwptr_done_capture;
- struct snd_card *sndcard;
-
- int users;
- spinlock_t slock;
-};
-
-struct em28xx;
-
-struct em28xx_fh {
- struct em28xx *dev;
- int radio;
- unsigned int resources;
-
- struct videobuf_queue vb_vidq;
- struct videobuf_queue vb_vbiq;
-
- enum v4l2_buf_type type;
-};
-
-/* main device struct */
-struct em28xx {
- /* generic device properties */
- char name[30]; /* name (including minor) of the device */
- int model; /* index in the device_data struct */
- int devno; /* marks the number of this device */
- enum em28xx_chip_id chip_id;
-
- int audio_ifnum;
-
- struct v4l2_device v4l2_dev;
- struct em28xx_board board;
-
- /* Webcam specific fields */
- enum em28xx_sensor em28xx_sensor;
- int sensor_xres, sensor_yres;
- int sensor_xtal;
-
- /* Allows progressive (e. g. non-interlaced) mode */
- int progressive;
-
- /* Vinmode/Vinctl used at the driver */
- int vinmode, vinctl;
-
- unsigned int has_audio_class:1;
- unsigned int has_alsa_audio:1;
- unsigned int is_audio_only:1;
-
- /* Controls audio streaming */
- struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */
- atomic_t stream_started; /* stream should be running if true */
-
- struct em28xx_fmt *format;
-
- struct em28xx_IR *ir;
-
- /* Some older em28xx chips needs a waiting time after writing */
- unsigned int wait_after_write;
-
- struct list_head devlist;
-
- u32 i2s_speed; /* I2S speed for audio digital stream */
-
- struct em28xx_audio_mode audio_mode;
-
- int tuner_type; /* type of the tuner */
- int tuner_addr; /* tuner address */
- int tda9887_conf;
- /* i2c i/o */
- struct i2c_adapter i2c_adap;
- struct i2c_client i2c_client;
- /* video for linux */
- int users; /* user count for exclusive use */
- struct video_device *vdev; /* video for linux device struct */
- v4l2_std_id norm; /* selected tv norm */
- int ctl_freq; /* selected frequency */
- unsigned int ctl_input; /* selected input */
- unsigned int ctl_ainput;/* selected audio input */
- unsigned int ctl_aoutput;/* selected audio output */
- int mute;
- int volume;
- /* frame properties */
- int width; /* current frame width */
- int height; /* current frame height */
- unsigned hscale; /* horizontal scale factor (see datasheet) */
- unsigned vscale; /* vertical scale factor (see datasheet) */
- int interlaced; /* 1=interlace fileds, 0=just top fileds */
- unsigned int video_bytesread; /* Number of bytes read */
-
- unsigned long hash; /* eeprom hash - for boards with generic ID */
- unsigned long i2c_hash; /* i2c devicelist hash -
- for boards with generic ID */
-
- struct em28xx_audio adev;
-
- /* states */
- enum em28xx_dev_state state;
-
- /* vbi related state tracking */
- int capture_type;
- int vbi_read;
- unsigned char cur_field;
- unsigned int vbi_width;
- unsigned int vbi_height; /* lines per field */
-
- struct work_struct request_module_wk;
-
- /* locks */
- struct mutex lock;
- struct mutex ctrl_urb_lock; /* protects urb_buf */
- /* spinlock_t queue_lock; */
- struct list_head inqueue, outqueue;
- struct video_device *vbi_dev;
- struct video_device *radio_dev;
-
- /* resources in use */
- unsigned int resources;
-
- unsigned char eedata[256];
-
- /* Isoc control struct */
- struct em28xx_dmaqueue vidq;
- struct em28xx_dmaqueue vbiq;
- struct em28xx_usb_isoc_ctl isoc_ctl;
- spinlock_t slock;
-
- /* usb transfer */
- struct usb_device *udev; /* the usb device */
- int alt; /* alternate */
- int max_pkt_size; /* max packet size of isoc transaction */
- int num_alt; /* Number of alternative settings */
- unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
- int dvb_alt; /* alternate for DVB */
- unsigned int dvb_max_pkt_size; /* wMaxPacketSize for DVB */
- char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */
-
- /* helper funcs that call usb_control_msg */
- int (*em28xx_write_regs) (struct em28xx *dev, u16 reg,
- char *buf, int len);
- int (*em28xx_read_reg) (struct em28xx *dev, u16 reg);
- int (*em28xx_read_reg_req_len) (struct em28xx *dev, u8 req, u16 reg,
- char *buf, int len);
- int (*em28xx_write_regs_req) (struct em28xx *dev, u8 req, u16 reg,
- char *buf, int len);
- int (*em28xx_read_reg_req) (struct em28xx *dev, u8 req, u16 reg);
-
- enum em28xx_mode mode;
-
- /* register numbers for GPO/GPIO registers */
- u16 reg_gpo_num, reg_gpio_num;
-
- /* Caches GPO and GPIO registers */
- unsigned char reg_gpo, reg_gpio;
-
- /* Snapshot button */
- char snapshot_button_path[30]; /* path of the input dev */
- struct input_dev *sbutton_input_dev;
- struct delayed_work sbutton_query_work;
-
- struct em28xx_dvb *dvb;
-
- /* I2C keyboard data */
- struct IR_i2c_init_data init_data;
-};
-
-struct em28xx_ops {
- struct list_head next;
- char *name;
- int id;
- int (*init)(struct em28xx *);
- int (*fini)(struct em28xx *);
-};
-
-/* Provided by em28xx-i2c.c */
-void em28xx_do_i2c_scan(struct em28xx *dev);
-int em28xx_i2c_register(struct em28xx *dev);
-int em28xx_i2c_unregister(struct em28xx *dev);
-
-/* Provided by em28xx-core.c */
-
-u32 em28xx_request_buffers(struct em28xx *dev, u32 count);
-void em28xx_queue_unusedframes(struct em28xx *dev);
-void em28xx_release_buffers(struct em28xx *dev);
-
-int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
- char *buf, int len);
-int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg);
-int em28xx_read_reg(struct em28xx *dev, u16 reg);
-int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
- int len);
-int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
-int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val);
-int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
- u8 bitmask);
-
-int em28xx_read_ac97(struct em28xx *dev, u8 reg);
-int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val);
-
-int em28xx_audio_analog_set(struct em28xx *dev);
-int em28xx_audio_setup(struct em28xx *dev);
-
-int em28xx_colorlevels_set_default(struct em28xx *dev);
-int em28xx_capture_start(struct em28xx *dev, int start);
-int em28xx_vbi_supported(struct em28xx *dev);
-int em28xx_set_outfmt(struct em28xx *dev);
-int em28xx_resolution_set(struct em28xx *dev);
-int em28xx_set_alternate(struct em28xx *dev);
-int em28xx_alloc_isoc(struct em28xx *dev, enum em28xx_mode mode,
- int max_packets, int num_bufs, int max_pkt_size);
-int em28xx_init_isoc(struct em28xx *dev, enum em28xx_mode mode,
- int max_packets, int num_bufs, int max_pkt_size,
- int (*isoc_copy) (struct em28xx *dev, struct urb *urb));
-void em28xx_uninit_isoc(struct em28xx *dev, enum em28xx_mode mode);
-void em28xx_stop_urbs(struct em28xx *dev);
-int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev);
-int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode);
-int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio);
-void em28xx_wake_i2c(struct em28xx *dev);
-int em28xx_register_extension(struct em28xx_ops *dev);
-void em28xx_unregister_extension(struct em28xx_ops *dev);
-void em28xx_init_extension(struct em28xx *dev);
-void em28xx_close_extension(struct em28xx *dev);
-
-/* Provided by em28xx-video.c */
-int em28xx_register_analog_devices(struct em28xx *dev);
-void em28xx_release_analog_resources(struct em28xx *dev);
-
-/* Provided by em28xx-cards.c */
-extern int em2800_variant_detect(struct usb_device *udev, int model);
-extern struct em28xx_board em28xx_boards[];
-extern struct usb_device_id em28xx_id_table[];
-extern const unsigned int em28xx_bcount;
-int em28xx_tuner_callback(void *ptr, int component, int command, int arg);
-void em28xx_release_resources(struct em28xx *dev);
-
-/* Provided by em28xx-vbi.c */
-extern struct videobuf_queue_ops em28xx_vbi_qops;
-
-/* printk macros */
-
-#define em28xx_err(fmt, arg...) do {\
- printk(KERN_ERR fmt , ##arg); } while (0)
-
-#define em28xx_errdev(fmt, arg...) do {\
- printk(KERN_ERR "%s: "fmt,\
- dev->name , ##arg); } while (0)
-
-#define em28xx_info(fmt, arg...) do {\
- printk(KERN_INFO "%s: "fmt,\
- dev->name , ##arg); } while (0)
-#define em28xx_warn(fmt, arg...) do {\
- printk(KERN_WARNING "%s: "fmt,\
- dev->name , ##arg); } while (0)
-
-static inline int em28xx_compression_disable(struct em28xx *dev)
-{
- /* side effect of disabling scaler and mixer */
- return em28xx_write_reg(dev, EM28XX_R26_COMPR, 0x00);
-}
-
-static inline int em28xx_contrast_get(struct em28xx *dev)
-{
- return em28xx_read_reg(dev, EM28XX_R20_YGAIN) & 0x1f;
-}
-
-static inline int em28xx_brightness_get(struct em28xx *dev)
-{
- return em28xx_read_reg(dev, EM28XX_R21_YOFFSET);
-}
-
-static inline int em28xx_saturation_get(struct em28xx *dev)
-{
- return em28xx_read_reg(dev, EM28XX_R22_UVGAIN) & 0x1f;
-}
-
-static inline int em28xx_u_balance_get(struct em28xx *dev)
-{
- return em28xx_read_reg(dev, EM28XX_R23_UOFFSET);
-}
-
-static inline int em28xx_v_balance_get(struct em28xx *dev)
-{
- return em28xx_read_reg(dev, EM28XX_R24_VOFFSET);
-}
-
-static inline int em28xx_gamma_get(struct em28xx *dev)
-{
- return em28xx_read_reg(dev, EM28XX_R14_GAMMA) & 0x3f;
-}
-
-static inline int em28xx_contrast_set(struct em28xx *dev, s32 val)
-{
- u8 tmp = (u8) val;
- return em28xx_write_regs(dev, EM28XX_R20_YGAIN, &tmp, 1);
-}
-
-static inline int em28xx_brightness_set(struct em28xx *dev, s32 val)
-{
- u8 tmp = (u8) val;
- return em28xx_write_regs(dev, EM28XX_R21_YOFFSET, &tmp, 1);
-}
-
-static inline int em28xx_saturation_set(struct em28xx *dev, s32 val)
-{
- u8 tmp = (u8) val;
- return em28xx_write_regs(dev, EM28XX_R22_UVGAIN, &tmp, 1);
-}
-
-static inline int em28xx_u_balance_set(struct em28xx *dev, s32 val)
-{
- u8 tmp = (u8) val;
- return em28xx_write_regs(dev, EM28XX_R23_UOFFSET, &tmp, 1);
-}
-
-static inline int em28xx_v_balance_set(struct em28xx *dev, s32 val)
-{
- u8 tmp = (u8) val;
- return em28xx_write_regs(dev, EM28XX_R24_VOFFSET, &tmp, 1);
-}
-
-static inline int em28xx_gamma_set(struct em28xx *dev, s32 val)
-{
- u8 tmp = (u8) val;
- return em28xx_write_regs(dev, EM28XX_R14_GAMMA, &tmp, 1);
-}
-
-/*FIXME: maxw should be dependent of alt mode */
-static inline unsigned int norm_maxw(struct em28xx *dev)
-{
- if (dev->board.is_webcam)
- return dev->sensor_xres;
-
- if (dev->board.max_range_640_480)
- return 640;
-
- return 720;
-}
-
-static inline unsigned int norm_maxh(struct em28xx *dev)
-{
- if (dev->board.is_webcam)
- return dev->sensor_yres;
-
- if (dev->board.max_range_640_480)
- return 480;
-
- return (dev->norm & V4L2_STD_625_50) ? 576 : 480;
-}
-#endif
diff --git a/drivers/media/video/fsl-viu.c b/drivers/media/video/fsl-viu.c
deleted file mode 100644
index 777486f7cad..00000000000
--- a/drivers/media/video/fsl-viu.c
+++ /dev/null
@@ -1,1673 +0,0 @@
-/*
- * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * Freescale VIU video driver
- *
- * Authors: Hongjun Chen <hong-jun.chen@freescale.com>
- * Porting to 2.6.35 by DENX Software Engineering,
- * Anatolij Gustschin <agust@denx.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/of_platform.h>
-#include <linux/slab.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf-dma-contig.h>
-
-#define DRV_NAME "fsl_viu"
-#define VIU_VERSION "0.5.1"
-
-#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
-
-#define VIU_VID_MEM_LIMIT 4 /* Video memory limit, in Mb */
-
-/* I2C address of video decoder chip is 0x4A */
-#define VIU_VIDEO_DECODER_ADDR 0x25
-
-/* supported controls */
-static struct v4l2_queryctrl viu_qctrl[] = {
- {
- .id = V4L2_CID_BRIGHTNESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Brightness",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 127,
- .flags = 0,
- }, {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 255,
- .step = 0x1,
- .default_value = 0x10,
- .flags = 0,
- }, {
- .id = V4L2_CID_SATURATION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 255,
- .step = 0x1,
- .default_value = 127,
- .flags = 0,
- }, {
- .id = V4L2_CID_HUE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Hue",
- .minimum = -128,
- .maximum = 127,
- .step = 0x1,
- .default_value = 0,
- .flags = 0,
- }
-};
-
-static int qctl_regs[ARRAY_SIZE(viu_qctrl)];
-
-static int info_level;
-
-#define dprintk(level, fmt, arg...) \
- do { \
- if (level <= info_level) \
- printk(KERN_DEBUG "viu: " fmt , ## arg); \
- } while (0)
-
-/*
- * Basic structures
- */
-struct viu_fmt {
- char name[32];
- u32 fourcc; /* v4l2 format id */
- u32 pixelformat;
- int depth;
-};
-
-static struct viu_fmt formats[] = {
- {
- .name = "RGB-16 (5/B-6/G-5/R)",
- .fourcc = V4L2_PIX_FMT_RGB565,
- .pixelformat = V4L2_PIX_FMT_RGB565,
- .depth = 16,
- }, {
- .name = "RGB-32 (A-R-G-B)",
- .fourcc = V4L2_PIX_FMT_RGB32,
- .pixelformat = V4L2_PIX_FMT_RGB32,
- .depth = 32,
- }
-};
-
-struct viu_dev;
-struct viu_buf;
-
-/* buffer for one video frame */
-struct viu_buf {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
- struct viu_fmt *fmt;
-};
-
-struct viu_dmaqueue {
- struct viu_dev *dev;
- struct list_head active;
- struct list_head queued;
- struct timer_list timeout;
-};
-
-struct viu_status {
- u32 field_irq;
- u32 vsync_irq;
- u32 hsync_irq;
- u32 vstart_irq;
- u32 dma_end_irq;
- u32 error_irq;
-};
-
-struct viu_reg {
- u32 status_cfg;
- u32 luminance;
- u32 chroma_r;
- u32 chroma_g;
- u32 chroma_b;
- u32 field_base_addr;
- u32 dma_inc;
- u32 picture_count;
- u32 req_alarm;
- u32 alpha;
-} __attribute__ ((packed));
-
-struct viu_dev {
- struct v4l2_device v4l2_dev;
- struct mutex lock;
- spinlock_t slock;
- int users;
-
- struct device *dev;
- /* various device info */
- struct video_device *vdev;
- struct viu_dmaqueue vidq;
- enum v4l2_field capfield;
- int field;
- int first;
- int dma_done;
-
- /* Hardware register area */
- struct viu_reg *vr;
-
- /* Interrupt vector */
- int irq;
- struct viu_status irqs;
-
- /* video overlay */
- struct v4l2_framebuffer ovbuf;
- struct viu_fmt *ovfmt;
- unsigned int ovenable;
- enum v4l2_field ovfield;
-
- /* crop */
- struct v4l2_rect crop_current;
-
- /* clock pointer */
- struct clk *clk;
-
- /* decoder */
- struct v4l2_subdev *decoder;
-
- v4l2_std_id std;
-};
-
-struct viu_fh {
- struct viu_dev *dev;
-
- /* video capture */
- struct videobuf_queue vb_vidq;
- spinlock_t vbq_lock; /* spinlock for the videobuf queue */
-
- /* video overlay */
- struct v4l2_window win;
- struct v4l2_clip clips[1];
-
- /* video capture */
- struct viu_fmt *fmt;
- int width, height, sizeimage;
- enum v4l2_buf_type type;
-};
-
-static struct viu_reg reg_val;
-
-/*
- * Macro definitions of VIU registers
- */
-
-/* STATUS_CONFIG register */
-enum status_config {
- SOFT_RST = 1 << 0,
-
- ERR_MASK = 0x0f << 4, /* Error code mask */
- ERR_NO = 0x00, /* No error */
- ERR_DMA_V = 0x01 << 4, /* DMA in vertical active */
- ERR_DMA_VB = 0x02 << 4, /* DMA in vertical blanking */
- ERR_LINE_TOO_LONG = 0x04 << 4, /* Line too long */
- ERR_TOO_MANG_LINES = 0x05 << 4, /* Too many lines in field */
- ERR_LINE_TOO_SHORT = 0x06 << 4, /* Line too short */
- ERR_NOT_ENOUGH_LINE = 0x07 << 4, /* Not enough lines in field */
- ERR_FIFO_OVERFLOW = 0x08 << 4, /* FIFO overflow */
- ERR_FIFO_UNDERFLOW = 0x09 << 4, /* FIFO underflow */
- ERR_1bit_ECC = 0x0a << 4, /* One bit ECC error */
- ERR_MORE_ECC = 0x0b << 4, /* Two/more bits ECC error */
-
- INT_FIELD_EN = 0x01 << 8, /* Enable field interrupt */
- INT_VSYNC_EN = 0x01 << 9, /* Enable vsync interrupt */
- INT_HSYNC_EN = 0x01 << 10, /* Enable hsync interrupt */
- INT_VSTART_EN = 0x01 << 11, /* Enable vstart interrupt */
- INT_DMA_END_EN = 0x01 << 12, /* Enable DMA end interrupt */
- INT_ERROR_EN = 0x01 << 13, /* Enable error interrupt */
- INT_ECC_EN = 0x01 << 14, /* Enable ECC interrupt */
-
- INT_FIELD_STATUS = 0x01 << 16, /* field interrupt status */
- INT_VSYNC_STATUS = 0x01 << 17, /* vsync interrupt status */
- INT_HSYNC_STATUS = 0x01 << 18, /* hsync interrupt status */
- INT_VSTART_STATUS = 0x01 << 19, /* vstart interrupt status */
- INT_DMA_END_STATUS = 0x01 << 20, /* DMA end interrupt status */
- INT_ERROR_STATUS = 0x01 << 21, /* error interrupt status */
-
- DMA_ACT = 0x01 << 27, /* Enable DMA transfer */
- FIELD_NO = 0x01 << 28, /* Field number */
- DITHER_ON = 0x01 << 29, /* Dithering is on */
- ROUND_ON = 0x01 << 30, /* Round is on */
- MODE_32BIT = 0x01 << 31, /* Data in RGBa888,
- * 0 in RGB565
- */
-};
-
-#define norm_maxw() 720
-#define norm_maxh() 576
-
-#define INT_ALL_STATUS (INT_FIELD_STATUS | INT_VSYNC_STATUS | \
- INT_HSYNC_STATUS | INT_VSTART_STATUS | \
- INT_DMA_END_STATUS | INT_ERROR_STATUS)
-
-#define NUM_FORMATS ARRAY_SIZE(formats)
-
-static irqreturn_t viu_intr(int irq, void *dev_id);
-
-struct viu_fmt *format_by_fourcc(int fourcc)
-{
- int i;
-
- for (i = 0; i < NUM_FORMATS; i++) {
- if (formats[i].pixelformat == fourcc)
- return formats + i;
- }
-
- dprintk(0, "unknown pixelformat:'%4.4s'\n", (char *)&fourcc);
- return NULL;
-}
-
-void viu_start_dma(struct viu_dev *dev)
-{
- struct viu_reg *vr = dev->vr;
-
- dev->field = 0;
-
- /* Enable DMA operation */
- out_be32(&vr->status_cfg, SOFT_RST);
- out_be32(&vr->status_cfg, INT_FIELD_EN);
-}
-
-void viu_stop_dma(struct viu_dev *dev)
-{
- struct viu_reg *vr = dev->vr;
- int cnt = 100;
- u32 status_cfg;
-
- out_be32(&vr->status_cfg, 0);
-
- /* Clear pending interrupts */
- status_cfg = in_be32(&vr->status_cfg);
- if (status_cfg & 0x3f0000)
- out_be32(&vr->status_cfg, status_cfg & 0x3f0000);
-
- if (status_cfg & DMA_ACT) {
- do {
- status_cfg = in_be32(&vr->status_cfg);
- if (status_cfg & INT_DMA_END_STATUS)
- break;
- } while (cnt--);
-
- if (cnt < 0) {
- /* timed out, issue soft reset */
- out_be32(&vr->status_cfg, SOFT_RST);
- out_be32(&vr->status_cfg, 0);
- } else {
- /* clear DMA_END and other pending irqs */
- out_be32(&vr->status_cfg, status_cfg & 0x3f0000);
- }
- }
-
- dev->field = 0;
-}
-
-static int restart_video_queue(struct viu_dmaqueue *vidq)
-{
- struct viu_buf *buf, *prev;
-
- dprintk(1, "%s vidq=0x%08lx\n", __func__, (unsigned long)vidq);
- if (!list_empty(&vidq->active)) {
- buf = list_entry(vidq->active.next, struct viu_buf, vb.queue);
- dprintk(2, "restart_queue [%p/%d]: restart dma\n",
- buf, buf->vb.i);
-
- viu_stop_dma(vidq->dev);
-
- /* cancel all outstanding capture requests */
- list_for_each_entry_safe(buf, prev, &vidq->active, vb.queue) {
- list_del(&buf->vb.queue);
- buf->vb.state = VIDEOBUF_ERROR;
- wake_up(&buf->vb.done);
- }
- mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT);
- return 0;
- }
-
- prev = NULL;
- for (;;) {
- if (list_empty(&vidq->queued))
- return 0;
- buf = list_entry(vidq->queued.next, struct viu_buf, vb.queue);
- if (prev == NULL) {
- list_del(&buf->vb.queue);
- list_add_tail(&buf->vb.queue, &vidq->active);
-
- dprintk(1, "Restarting video dma\n");
- viu_stop_dma(vidq->dev);
- viu_start_dma(vidq->dev);
-
- buf->vb.state = VIDEOBUF_ACTIVE;
- mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT);
- dprintk(2, "[%p/%d] restart_queue - first active\n",
- buf, buf->vb.i);
-
- } else if (prev->vb.width == buf->vb.width &&
- prev->vb.height == buf->vb.height &&
- prev->fmt == buf->fmt) {
- list_del(&buf->vb.queue);
- list_add_tail(&buf->vb.queue, &vidq->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- dprintk(2, "[%p/%d] restart_queue - move to active\n",
- buf, buf->vb.i);
- } else {
- return 0;
- }
- prev = buf;
- }
-}
-
-static void viu_vid_timeout(unsigned long data)
-{
- struct viu_dev *dev = (struct viu_dev *)data;
- struct viu_buf *buf;
- struct viu_dmaqueue *vidq = &dev->vidq;
-
- while (!list_empty(&vidq->active)) {
- buf = list_entry(vidq->active.next, struct viu_buf, vb.queue);
- list_del(&buf->vb.queue);
- buf->vb.state = VIDEOBUF_ERROR;
- wake_up(&buf->vb.done);
- dprintk(1, "viu/0: [%p/%d] timeout\n", buf, buf->vb.i);
- }
-
- restart_video_queue(vidq);
-}
-
-/*
- * Videobuf operations
- */
-static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
- unsigned int *size)
-{
- struct viu_fh *fh = vq->priv_data;
-
- *size = fh->width * fh->height * fh->fmt->depth >> 3;
- if (*count == 0)
- *count = 32;
-
- while (*size * *count > VIU_VID_MEM_LIMIT * 1024 * 1024)
- (*count)--;
-
- dprintk(1, "%s, count=%d, size=%d\n", __func__, *count, *size);
- return 0;
-}
-
-static void free_buffer(struct videobuf_queue *vq, struct viu_buf *buf)
-{
- struct videobuf_buffer *vb = &buf->vb;
- void *vaddr = NULL;
-
- BUG_ON(in_interrupt());
-
- videobuf_waiton(vq, &buf->vb, 0, 0);
-
- if (vq->int_ops && vq->int_ops->vaddr)
- vaddr = vq->int_ops->vaddr(vb);
-
- if (vaddr)
- videobuf_dma_contig_free(vq, &buf->vb);
-
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-inline int buffer_activate(struct viu_dev *dev, struct viu_buf *buf)
-{
- struct viu_reg *vr = dev->vr;
- int bpp;
-
- /* setup the DMA base address */
- reg_val.field_base_addr = videobuf_to_dma_contig(&buf->vb);
-
- dprintk(1, "buffer_activate [%p/%d]: dma addr 0x%lx\n",
- buf, buf->vb.i, (unsigned long)reg_val.field_base_addr);
-
- /* interlace is on by default, set horizontal DMA increment */
- reg_val.status_cfg = 0;
- bpp = buf->fmt->depth >> 3;
- switch (bpp) {
- case 2:
- reg_val.status_cfg &= ~MODE_32BIT;
- reg_val.dma_inc = buf->vb.width * 2;
- break;
- case 4:
- reg_val.status_cfg |= MODE_32BIT;
- reg_val.dma_inc = buf->vb.width * 4;
- break;
- default:
- dprintk(0, "doesn't support color depth(%d)\n",
- bpp * 8);
- return -EINVAL;
- }
-
- /* setup picture_count register */
- reg_val.picture_count = (buf->vb.height / 2) << 16 |
- buf->vb.width;
-
- reg_val.status_cfg |= DMA_ACT | INT_DMA_END_EN | INT_FIELD_EN;
-
- buf->vb.state = VIDEOBUF_ACTIVE;
- dev->capfield = buf->vb.field;
-
- /* reset dma increment if needed */
- if (!V4L2_FIELD_HAS_BOTH(buf->vb.field))
- reg_val.dma_inc = 0;
-
- out_be32(&vr->dma_inc, reg_val.dma_inc);
- out_be32(&vr->picture_count, reg_val.picture_count);
- out_be32(&vr->field_base_addr, reg_val.field_base_addr);
- mod_timer(&dev->vidq.timeout, jiffies + BUFFER_TIMEOUT);
- return 0;
-}
-
-static int buffer_prepare(struct videobuf_queue *vq,
- struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct viu_fh *fh = vq->priv_data;
- struct viu_buf *buf = container_of(vb, struct viu_buf, vb);
- int rc;
-
- BUG_ON(fh->fmt == NULL);
-
- if (fh->width < 48 || fh->width > norm_maxw() ||
- fh->height < 32 || fh->height > norm_maxh())
- return -EINVAL;
- buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
- if (buf->vb.baddr != 0 && buf->vb.bsize < buf->vb.size)
- return -EINVAL;
-
- if (buf->fmt != fh->fmt ||
- buf->vb.width != fh->width ||
- buf->vb.height != fh->height ||
- buf->vb.field != field) {
- buf->fmt = fh->fmt;
- buf->vb.width = fh->width;
- buf->vb.height = fh->height;
- buf->vb.field = field;
- }
-
- if (buf->vb.state == VIDEOBUF_NEEDS_INIT) {
- rc = videobuf_iolock(vq, &buf->vb, NULL);
- if (rc != 0)
- goto fail;
-
- buf->vb.width = fh->width;
- buf->vb.height = fh->height;
- buf->vb.field = field;
- buf->fmt = fh->fmt;
- }
-
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
-fail:
- free_buffer(vq, buf);
- return rc;
-}
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct viu_buf *buf = container_of(vb, struct viu_buf, vb);
- struct viu_fh *fh = vq->priv_data;
- struct viu_dev *dev = fh->dev;
- struct viu_dmaqueue *vidq = &dev->vidq;
- struct viu_buf *prev;
-
- if (!list_empty(&vidq->queued)) {
- dprintk(1, "adding vb queue=0x%08lx\n",
- (unsigned long)&buf->vb.queue);
- dprintk(1, "vidq pointer 0x%p, queued 0x%p\n",
- vidq, &vidq->queued);
- dprintk(1, "dev %p, queued: self %p, next %p, head %p\n",
- dev, &vidq->queued, vidq->queued.next,
- vidq->queued.prev);
- list_add_tail(&buf->vb.queue, &vidq->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n",
- buf, buf->vb.i);
- } else if (list_empty(&vidq->active)) {
- dprintk(1, "adding vb active=0x%08lx\n",
- (unsigned long)&buf->vb.queue);
- list_add_tail(&buf->vb.queue, &vidq->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT);
- dprintk(2, "[%p/%d] buffer_queue - first active\n",
- buf, buf->vb.i);
-
- buffer_activate(dev, buf);
- } else {
- dprintk(1, "adding vb queue2=0x%08lx\n",
- (unsigned long)&buf->vb.queue);
- prev = list_entry(vidq->active.prev, struct viu_buf, vb.queue);
- if (prev->vb.width == buf->vb.width &&
- prev->vb.height == buf->vb.height &&
- prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &vidq->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- dprintk(2, "[%p/%d] buffer_queue - append to active\n",
- buf, buf->vb.i);
- } else {
- list_add_tail(&buf->vb.queue, &vidq->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n",
- buf, buf->vb.i);
- }
- }
-}
-
-static void buffer_release(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct viu_buf *buf = container_of(vb, struct viu_buf, vb);
- struct viu_fh *fh = vq->priv_data;
- struct viu_dev *dev = (struct viu_dev *)fh->dev;
-
- viu_stop_dma(dev);
- free_buffer(vq, buf);
-}
-
-static struct videobuf_queue_ops viu_video_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-/*
- * IOCTL vidioc handling
- */
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- strcpy(cap->driver, "viu");
- strcpy(cap->card, "viu");
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_STREAMING |
- V4L2_CAP_VIDEO_OVERLAY |
- V4L2_CAP_READWRITE;
- return 0;
-}
-
-static int vidioc_enum_fmt(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- int index = f->index;
-
- if (f->index > NUM_FORMATS)
- return -EINVAL;
-
- strlcpy(f->description, formats[index].name, sizeof(f->description));
- f->pixelformat = formats[index].fourcc;
- return 0;
-}
-
-static int vidioc_g_fmt_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct viu_fh *fh = priv;
-
- f->fmt.pix.width = fh->width;
- f->fmt.pix.height = fh->height;
- f->fmt.pix.field = fh->vb_vidq.field;
- f->fmt.pix.pixelformat = fh->fmt->pixelformat;
- f->fmt.pix.bytesperline =
- (f->fmt.pix.width * fh->fmt->depth) >> 3;
- f->fmt.pix.sizeimage = fh->sizeimage;
- return 0;
-}
-
-static int vidioc_try_fmt_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct viu_fmt *fmt;
- enum v4l2_field field;
- unsigned int maxw, maxh;
-
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- if (!fmt) {
- dprintk(1, "Fourcc format (0x%08x) invalid.",
- f->fmt.pix.pixelformat);
- return -EINVAL;
- }
-
- field = f->fmt.pix.field;
-
- if (field == V4L2_FIELD_ANY) {
- field = V4L2_FIELD_INTERLACED;
- } else if (field != V4L2_FIELD_INTERLACED) {
- dprintk(1, "Field type invalid.\n");
- return -EINVAL;
- }
-
- maxw = norm_maxw();
- maxh = norm_maxh();
-
- f->fmt.pix.field = field;
- if (f->fmt.pix.height < 32)
- f->fmt.pix.height = 32;
- if (f->fmt.pix.height > maxh)
- f->fmt.pix.height = maxh;
- if (f->fmt.pix.width < 48)
- f->fmt.pix.width = 48;
- if (f->fmt.pix.width > maxw)
- f->fmt.pix.width = maxw;
- f->fmt.pix.width &= ~0x03;
- f->fmt.pix.bytesperline =
- (f->fmt.pix.width * fmt->depth) >> 3;
-
- return 0;
-}
-
-static int vidioc_s_fmt_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct viu_fh *fh = priv;
- int ret;
-
- ret = vidioc_try_fmt_cap(file, fh, f);
- if (ret < 0)
- return ret;
-
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->width = f->fmt.pix.width;
- fh->height = f->fmt.pix.height;
- fh->sizeimage = f->fmt.pix.sizeimage;
- fh->vb_vidq.field = f->fmt.pix.field;
- fh->type = f->type;
- dprintk(1, "set to pixelformat '%4.6s'\n", (char *)&fh->fmt->name);
- return 0;
-}
-
-static int vidioc_g_fmt_overlay(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct viu_fh *fh = priv;
-
- f->fmt.win = fh->win;
- return 0;
-}
-
-static int verify_preview(struct viu_dev *dev, struct v4l2_window *win)
-{
- enum v4l2_field field;
- int maxw, maxh;
-
- if (dev->ovbuf.base == NULL)
- return -EINVAL;
- if (dev->ovfmt == NULL)
- return -EINVAL;
- if (win->w.width < 48 || win->w.height < 32)
- return -EINVAL;
-
- field = win->field;
- maxw = dev->crop_current.width;
- maxh = dev->crop_current.height;
-
- if (field == V4L2_FIELD_ANY) {
- field = (win->w.height > maxh/2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_TOP;
- }
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- break;
- default:
- return -EINVAL;
- }
-
- win->field = field;
- if (win->w.width > maxw)
- win->w.width = maxw;
- if (win->w.height > maxh)
- win->w.height = maxh;
- return 0;
-}
-
-inline void viu_activate_overlay(struct viu_reg *viu_reg)
-{
- struct viu_reg *vr = viu_reg;
-
- out_be32(&vr->field_base_addr, reg_val.field_base_addr);
- out_be32(&vr->dma_inc, reg_val.dma_inc);
- out_be32(&vr->picture_count, reg_val.picture_count);
-}
-
-static int viu_setup_preview(struct viu_dev *dev, struct viu_fh *fh)
-{
- int bpp;
-
- dprintk(1, "%s %dx%d %s\n", __func__,
- fh->win.w.width, fh->win.w.height, dev->ovfmt->name);
-
- reg_val.status_cfg = 0;
-
- /* setup window */
- reg_val.picture_count = (fh->win.w.height / 2) << 16 |
- fh->win.w.width;
-
- /* setup color depth and dma increment */
- bpp = dev->ovfmt->depth / 8;
- switch (bpp) {
- case 2:
- reg_val.status_cfg &= ~MODE_32BIT;
- reg_val.dma_inc = fh->win.w.width * 2;
- break;
- case 4:
- reg_val.status_cfg |= MODE_32BIT;
- reg_val.dma_inc = fh->win.w.width * 4;
- break;
- default:
- dprintk(0, "device doesn't support color depth(%d)\n",
- bpp * 8);
- return -EINVAL;
- }
-
- dev->ovfield = fh->win.field;
- if (!V4L2_FIELD_HAS_BOTH(dev->ovfield))
- reg_val.dma_inc = 0;
-
- reg_val.status_cfg |= DMA_ACT | INT_DMA_END_EN | INT_FIELD_EN;
-
- /* setup the base address of the overlay buffer */
- reg_val.field_base_addr = (u32)dev->ovbuf.base;
-
- return 0;
-}
-
-static int vidioc_s_fmt_overlay(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct viu_fh *fh = priv;
- struct viu_dev *dev = (struct viu_dev *)fh->dev;
- unsigned long flags;
- int err;
-
- err = verify_preview(dev, &f->fmt.win);
- if (err)
- return err;
-
- fh->win = f->fmt.win;
-
- spin_lock_irqsave(&dev->slock, flags);
- viu_setup_preview(dev, fh);
- spin_unlock_irqrestore(&dev->slock, flags);
- return 0;
-}
-
-static int vidioc_try_fmt_overlay(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- return 0;
-}
-
-static int vidioc_overlay(struct file *file, void *priv, unsigned int on)
-{
- struct viu_fh *fh = priv;
- struct viu_dev *dev = (struct viu_dev *)fh->dev;
- unsigned long flags;
-
- if (on) {
- spin_lock_irqsave(&dev->slock, flags);
- viu_activate_overlay(dev->vr);
- dev->ovenable = 1;
-
- /* start dma */
- viu_start_dma(dev);
- spin_unlock_irqrestore(&dev->slock, flags);
- } else {
- viu_stop_dma(dev);
- dev->ovenable = 0;
- }
-
- return 0;
-}
-
-int vidioc_g_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *arg)
-{
- struct viu_fh *fh = priv;
- struct viu_dev *dev = fh->dev;
- struct v4l2_framebuffer *fb = arg;
-
- *fb = dev->ovbuf;
- fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
- return 0;
-}
-
-int vidioc_s_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *arg)
-{
- struct viu_fh *fh = priv;
- struct viu_dev *dev = fh->dev;
- struct v4l2_framebuffer *fb = arg;
- struct viu_fmt *fmt;
-
- if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
- return -EPERM;
-
- /* check args */
- fmt = format_by_fourcc(fb->fmt.pixelformat);
- if (fmt == NULL)
- return -EINVAL;
-
- /* ok, accept it */
- dev->ovbuf = *fb;
- dev->ovfmt = fmt;
- if (dev->ovbuf.fmt.bytesperline == 0) {
- dev->ovbuf.fmt.bytesperline =
- dev->ovbuf.fmt.width * fmt->depth / 8;
- }
- return 0;
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct viu_fh *fh = priv;
-
- return videobuf_reqbufs(&fh->vb_vidq, p);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct viu_fh *fh = priv;
-
- return videobuf_querybuf(&fh->vb_vidq, p);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct viu_fh *fh = priv;
-
- return videobuf_qbuf(&fh->vb_vidq, p);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct viu_fh *fh = priv;
-
- return videobuf_dqbuf(&fh->vb_vidq, p,
- file->f_flags & O_NONBLOCK);
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct viu_fh *fh = priv;
- struct viu_dev *dev = fh->dev;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (fh->type != i)
- return -EINVAL;
-
- if (dev->ovenable)
- dev->ovenable = 0;
-
- viu_start_dma(fh->dev);
-
- return videobuf_streamon(&fh->vb_vidq);
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct viu_fh *fh = priv;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (fh->type != i)
- return -EINVAL;
-
- viu_stop_dma(fh->dev);
-
- return videobuf_streamoff(&fh->vb_vidq);
-}
-
-#define decoder_call(viu, o, f, args...) \
- v4l2_subdev_call(viu->decoder, o, f, ##args)
-
-static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
-{
- struct viu_fh *fh = priv;
-
- decoder_call(fh->dev, video, querystd, std_id);
- return 0;
-}
-
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
-{
- struct viu_fh *fh = priv;
-
- fh->dev->std = *id;
- decoder_call(fh->dev, core, s_std, *id);
- return 0;
-}
-
-static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std_id)
-{
- struct viu_fh *fh = priv;
-
- *std_id = fh->dev->std;
- return 0;
-}
-
-/* only one input in this driver */
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *inp)
-{
- struct viu_fh *fh = priv;
-
- if (inp->index != 0)
- return -EINVAL;
-
- inp->type = V4L2_INPUT_TYPE_CAMERA;
- inp->std = fh->dev->vdev->tvnorms;
- strcpy(inp->name, "Camera");
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- struct viu_fh *fh = priv;
-
- if (i > 1)
- return -EINVAL;
-
- decoder_call(fh->dev, video, s_routing, i, 0, 0);
- return 0;
-}
-
-/* Controls */
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qc)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++) {
- if (qc->id && qc->id == viu_qctrl[i].id) {
- memcpy(qc, &(viu_qctrl[i]), sizeof(*qc));
- return 0;
- }
- }
- return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++) {
- if (ctrl->id == viu_qctrl[i].id) {
- ctrl->value = qctl_regs[i];
- return 0;
- }
- }
- return -EINVAL;
-}
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++) {
- if (ctrl->id == viu_qctrl[i].id) {
- if (ctrl->value < viu_qctrl[i].minimum
- || ctrl->value > viu_qctrl[i].maximum)
- return -ERANGE;
- qctl_regs[i] = ctrl->value;
- return 0;
- }
- }
- return -EINVAL;
-}
-
-inline void viu_activate_next_buf(struct viu_dev *dev,
- struct viu_dmaqueue *viuq)
-{
- struct viu_dmaqueue *vidq = viuq;
- struct viu_buf *buf;
-
- /* launch another DMA operation for an active/queued buffer */
- if (!list_empty(&vidq->active)) {
- buf = list_entry(vidq->active.next, struct viu_buf,
- vb.queue);
- dprintk(1, "start another queued buffer: 0x%p\n", buf);
- buffer_activate(dev, buf);
- } else if (!list_empty(&vidq->queued)) {
- buf = list_entry(vidq->queued.next, struct viu_buf,
- vb.queue);
- list_del(&buf->vb.queue);
-
- dprintk(1, "start another queued buffer: 0x%p\n", buf);
- list_add_tail(&buf->vb.queue, &vidq->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buffer_activate(dev, buf);
- }
-}
-
-inline void viu_default_settings(struct viu_reg *viu_reg)
-{
- struct viu_reg *vr = viu_reg;
-
- out_be32(&vr->luminance, 0x9512A254);
- out_be32(&vr->chroma_r, 0x03310000);
- out_be32(&vr->chroma_g, 0x06600F38);
- out_be32(&vr->chroma_b, 0x00000409);
- out_be32(&vr->alpha, 0x000000ff);
- out_be32(&vr->req_alarm, 0x00000090);
- dprintk(1, "status reg: 0x%08x, field base: 0x%08x\n",
- in_be32(&vr->status_cfg), in_be32(&vr->field_base_addr));
-}
-
-static void viu_overlay_intr(struct viu_dev *dev, u32 status)
-{
- struct viu_reg *vr = dev->vr;
-
- if (status & INT_DMA_END_STATUS)
- dev->dma_done = 1;
-
- if (status & INT_FIELD_STATUS) {
- if (dev->dma_done) {
- u32 addr = reg_val.field_base_addr;
-
- dev->dma_done = 0;
- if (status & FIELD_NO)
- addr += reg_val.dma_inc;
-
- out_be32(&vr->field_base_addr, addr);
- out_be32(&vr->dma_inc, reg_val.dma_inc);
- out_be32(&vr->status_cfg,
- (status & 0xffc0ffff) |
- (status & INT_ALL_STATUS) |
- reg_val.status_cfg);
- } else if (status & INT_VSYNC_STATUS) {
- out_be32(&vr->status_cfg,
- (status & 0xffc0ffff) |
- (status & INT_ALL_STATUS) |
- reg_val.status_cfg);
- }
- }
-}
-
-static void viu_capture_intr(struct viu_dev *dev, u32 status)
-{
- struct viu_dmaqueue *vidq = &dev->vidq;
- struct viu_reg *vr = dev->vr;
- struct viu_buf *buf;
- int field_num;
- int need_two;
- int dma_done = 0;
-
- field_num = status & FIELD_NO;
- need_two = V4L2_FIELD_HAS_BOTH(dev->capfield);
-
- if (status & INT_DMA_END_STATUS) {
- dma_done = 1;
- if (((field_num == 0) && (dev->field == 0)) ||
- (field_num && (dev->field == 1)))
- dev->field++;
- }
-
- if (status & INT_FIELD_STATUS) {
- dprintk(1, "irq: field %d, done %d\n",
- !!field_num, dma_done);
- if (unlikely(dev->first)) {
- if (field_num == 0) {
- dev->first = 0;
- dprintk(1, "activate first buf\n");
- viu_activate_next_buf(dev, vidq);
- } else
- dprintk(1, "wait field 0\n");
- return;
- }
-
- /* setup buffer address for next dma operation */
- if (!list_empty(&vidq->active)) {
- u32 addr = reg_val.field_base_addr;
-
- if (field_num && need_two) {
- addr += reg_val.dma_inc;
- dprintk(1, "field 1, 0x%lx, dev field %d\n",
- (unsigned long)addr, dev->field);
- }
- out_be32(&vr->field_base_addr, addr);
- out_be32(&vr->dma_inc, reg_val.dma_inc);
- out_be32(&vr->status_cfg,
- (status & 0xffc0ffff) |
- (status & INT_ALL_STATUS) |
- reg_val.status_cfg);
- return;
- }
- }
-
- if (dma_done && field_num && (dev->field == 2)) {
- dev->field = 0;
- buf = list_entry(vidq->active.next,
- struct viu_buf, vb.queue);
- dprintk(1, "viu/0: [%p/%d] 0x%lx/0x%lx: dma complete\n",
- buf, buf->vb.i,
- (unsigned long)videobuf_to_dma_contig(&buf->vb),
- (unsigned long)in_be32(&vr->field_base_addr));
-
- if (waitqueue_active(&buf->vb.done)) {
- list_del(&buf->vb.queue);
- do_gettimeofday(&buf->vb.ts);
- buf->vb.state = VIDEOBUF_DONE;
- buf->vb.field_count++;
- wake_up(&buf->vb.done);
- }
- /* activate next dma buffer */
- viu_activate_next_buf(dev, vidq);
- }
-}
-
-static irqreturn_t viu_intr(int irq, void *dev_id)
-{
- struct viu_dev *dev = (struct viu_dev *)dev_id;
- struct viu_reg *vr = dev->vr;
- u32 status;
- u32 error;
-
- status = in_be32(&vr->status_cfg);
-
- if (status & INT_ERROR_STATUS) {
- dev->irqs.error_irq++;
- error = status & ERR_MASK;
- if (error)
- dprintk(1, "Err: error(%d), times:%d!\n",
- error >> 4, dev->irqs.error_irq);
- /* Clear interrupt error bit and error flags */
- out_be32(&vr->status_cfg,
- (status & 0xffc0ffff) | INT_ERROR_STATUS);
- }
-
- if (status & INT_DMA_END_STATUS) {
- dev->irqs.dma_end_irq++;
- dev->dma_done = 1;
- dprintk(2, "VIU DMA end interrupt times: %d\n",
- dev->irqs.dma_end_irq);
- }
-
- if (status & INT_HSYNC_STATUS)
- dev->irqs.hsync_irq++;
-
- if (status & INT_FIELD_STATUS) {
- dev->irqs.field_irq++;
- dprintk(2, "VIU field interrupt times: %d\n",
- dev->irqs.field_irq);
- }
-
- if (status & INT_VSTART_STATUS)
- dev->irqs.vstart_irq++;
-
- if (status & INT_VSYNC_STATUS) {
- dev->irqs.vsync_irq++;
- dprintk(2, "VIU vsync interrupt times: %d\n",
- dev->irqs.vsync_irq);
- }
-
- /* clear all pending irqs */
- status = in_be32(&vr->status_cfg);
- out_be32(&vr->status_cfg,
- (status & 0xffc0ffff) | (status & INT_ALL_STATUS));
-
- if (dev->ovenable) {
- viu_overlay_intr(dev, status);
- return IRQ_HANDLED;
- }
-
- /* Capture mode */
- viu_capture_intr(dev, status);
- return IRQ_HANDLED;
-}
-
-/*
- * File operations for the device
- */
-static int viu_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct viu_dev *dev = video_get_drvdata(vdev);
- struct viu_fh *fh;
- struct viu_reg *vr;
- int minor = vdev->minor;
- u32 status_cfg;
- int i;
-
- dprintk(1, "viu: open (minor=%d)\n", minor);
-
- dev->users++;
- if (dev->users > 1) {
- dev->users--;
- return -EBUSY;
- }
-
- vr = dev->vr;
-
- dprintk(1, "open minor=%d type=%s users=%d\n", minor,
- v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
-
- /* allocate and initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (!fh) {
- dev->users--;
- return -ENOMEM;
- }
-
- file->private_data = fh;
- fh->dev = dev;
-
- fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fh->fmt = format_by_fourcc(V4L2_PIX_FMT_RGB32);
- fh->width = norm_maxw();
- fh->height = norm_maxh();
- dev->crop_current.width = fh->width;
- dev->crop_current.height = fh->height;
-
- /* Put all controls at a sane state */
- for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++)
- qctl_regs[i] = viu_qctrl[i].default_value;
-
- dprintk(1, "Open: fh=0x%08lx, dev=0x%08lx, dev->vidq=0x%08lx\n",
- (unsigned long)fh, (unsigned long)dev,
- (unsigned long)&dev->vidq);
- dprintk(1, "Open: list_empty queued=%d\n",
- list_empty(&dev->vidq.queued));
- dprintk(1, "Open: list_empty active=%d\n",
- list_empty(&dev->vidq.active));
-
- viu_default_settings(vr);
-
- status_cfg = in_be32(&vr->status_cfg);
- out_be32(&vr->status_cfg,
- status_cfg & ~(INT_VSYNC_EN | INT_HSYNC_EN |
- INT_FIELD_EN | INT_VSTART_EN |
- INT_DMA_END_EN | INT_ERROR_EN | INT_ECC_EN));
-
- status_cfg = in_be32(&vr->status_cfg);
- out_be32(&vr->status_cfg, status_cfg | INT_ALL_STATUS);
-
- spin_lock_init(&fh->vbq_lock);
- videobuf_queue_dma_contig_init(&fh->vb_vidq, &viu_video_qops,
- dev->dev, &fh->vbq_lock,
- fh->type, V4L2_FIELD_INTERLACED,
- sizeof(struct viu_buf), fh,
- &fh->dev->lock);
- return 0;
-}
-
-static ssize_t viu_read(struct file *file, char __user *data, size_t count,
- loff_t *ppos)
-{
- struct viu_fh *fh = file->private_data;
- struct viu_dev *dev = fh->dev;
- int ret = 0;
-
- dprintk(2, "%s\n", __func__);
- if (dev->ovenable)
- dev->ovenable = 0;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- viu_start_dma(dev);
- ret = videobuf_read_stream(&fh->vb_vidq, data, count,
- ppos, 0, file->f_flags & O_NONBLOCK);
- return ret;
- }
- return 0;
-}
-
-static unsigned int viu_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct viu_fh *fh = file->private_data;
- struct videobuf_queue *q = &fh->vb_vidq;
-
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
- return POLLERR;
-
- return videobuf_poll_stream(file, q, wait);
-}
-
-static int viu_release(struct file *file)
-{
- struct viu_fh *fh = file->private_data;
- struct viu_dev *dev = fh->dev;
- int minor = video_devdata(file)->minor;
-
- viu_stop_dma(dev);
- videobuf_stop(&fh->vb_vidq);
- videobuf_mmap_free(&fh->vb_vidq);
-
- kfree(fh);
-
- dev->users--;
- dprintk(1, "close (minor=%d, users=%d)\n",
- minor, dev->users);
- return 0;
-}
-
-void viu_reset(struct viu_reg *reg)
-{
- out_be32(&reg->status_cfg, 0);
- out_be32(&reg->luminance, 0x9512a254);
- out_be32(&reg->chroma_r, 0x03310000);
- out_be32(&reg->chroma_g, 0x06600f38);
- out_be32(&reg->chroma_b, 0x00000409);
- out_be32(&reg->field_base_addr, 0);
- out_be32(&reg->dma_inc, 0);
- out_be32(&reg->picture_count, 0x01e002d0);
- out_be32(&reg->req_alarm, 0x00000090);
- out_be32(&reg->alpha, 0x000000ff);
-}
-
-static int viu_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct viu_fh *fh = file->private_data;
- int ret;
-
- dprintk(1, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
-
- ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
-
- dprintk(1, "vma start=0x%08lx, size=%ld, ret=%d\n",
- (unsigned long)vma->vm_start,
- (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
- ret);
-
- return ret;
-}
-
-static struct v4l2_file_operations viu_fops = {
- .owner = THIS_MODULE,
- .open = viu_open,
- .release = viu_release,
- .read = viu_read,
- .poll = viu_poll,
- .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
- .mmap = viu_mmap,
-};
-
-static const struct v4l2_ioctl_ops viu_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_cap,
- .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt,
- .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_overlay,
- .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_overlay,
- .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_overlay,
- .vidioc_overlay = vidioc_overlay,
- .vidioc_g_fbuf = vidioc_g_fbuf,
- .vidioc_s_fbuf = vidioc_s_fbuf,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_g_std = vidioc_g_std,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_querystd = vidioc_querystd,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
-};
-
-static struct video_device viu_template = {
- .name = "FSL viu",
- .fops = &viu_fops,
- .minor = -1,
- .ioctl_ops = &viu_ioctl_ops,
- .release = video_device_release,
-
- .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL,
- .current_norm = V4L2_STD_NTSC_M,
-};
-
-static int __devinit viu_of_probe(struct platform_device *op)
-{
- struct viu_dev *viu_dev;
- struct video_device *vdev;
- struct resource r;
- struct viu_reg __iomem *viu_regs;
- struct i2c_adapter *ad;
- int ret, viu_irq;
-
- ret = of_address_to_resource(op->dev.of_node, 0, &r);
- if (ret) {
- dev_err(&op->dev, "Can't parse device node resource\n");
- return -ENODEV;
- }
-
- viu_irq = irq_of_parse_and_map(op->dev.of_node, 0);
- if (viu_irq == NO_IRQ) {
- dev_err(&op->dev, "Error while mapping the irq\n");
- return -EINVAL;
- }
-
- /* request mem region */
- if (!devm_request_mem_region(&op->dev, r.start,
- sizeof(struct viu_reg), DRV_NAME)) {
- dev_err(&op->dev, "Error while requesting mem region\n");
- ret = -EBUSY;
- goto err;
- }
-
- /* remap registers */
- viu_regs = devm_ioremap(&op->dev, r.start, sizeof(struct viu_reg));
- if (!viu_regs) {
- dev_err(&op->dev, "Can't map register set\n");
- ret = -ENOMEM;
- goto err;
- }
-
- /* Prepare our private structure */
- viu_dev = devm_kzalloc(&op->dev, sizeof(struct viu_dev), GFP_ATOMIC);
- if (!viu_dev) {
- dev_err(&op->dev, "Can't allocate private structure\n");
- ret = -ENOMEM;
- goto err;
- }
-
- viu_dev->vr = viu_regs;
- viu_dev->irq = viu_irq;
- viu_dev->dev = &op->dev;
-
- /* init video dma queues */
- INIT_LIST_HEAD(&viu_dev->vidq.active);
- INIT_LIST_HEAD(&viu_dev->vidq.queued);
-
- snprintf(viu_dev->v4l2_dev.name,
- sizeof(viu_dev->v4l2_dev.name), "%s", "VIU");
- ret = v4l2_device_register(viu_dev->dev, &viu_dev->v4l2_dev);
- if (ret < 0) {
- dev_err(&op->dev, "v4l2_device_register() failed: %d\n", ret);
- goto err;
- }
-
- ad = i2c_get_adapter(0);
- viu_dev->decoder = v4l2_i2c_new_subdev(&viu_dev->v4l2_dev, ad,
- "saa7113", VIU_VIDEO_DECODER_ADDR, NULL);
-
- viu_dev->vidq.timeout.function = viu_vid_timeout;
- viu_dev->vidq.timeout.data = (unsigned long)viu_dev;
- init_timer(&viu_dev->vidq.timeout);
- viu_dev->first = 1;
-
- /* Allocate memory for video device */
- vdev = video_device_alloc();
- if (vdev == NULL) {
- ret = -ENOMEM;
- goto err_vdev;
- }
-
- memcpy(vdev, &viu_template, sizeof(viu_template));
-
- vdev->v4l2_dev = &viu_dev->v4l2_dev;
-
- viu_dev->vdev = vdev;
-
- /* initialize locks */
- mutex_init(&viu_dev->lock);
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &viu_dev->vdev->flags);
- viu_dev->vdev->lock = &viu_dev->lock;
- spin_lock_init(&viu_dev->slock);
-
- video_set_drvdata(viu_dev->vdev, viu_dev);
-
- mutex_lock(&viu_dev->lock);
-
- ret = video_register_device(viu_dev->vdev, VFL_TYPE_GRABBER, -1);
- if (ret < 0) {
- video_device_release(viu_dev->vdev);
- goto err_vdev;
- }
-
- /* enable VIU clock */
- viu_dev->clk = clk_get(&op->dev, "viu_clk");
- if (IS_ERR(viu_dev->clk)) {
- dev_err(&op->dev, "failed to find the clock module!\n");
- ret = -ENODEV;
- goto err_clk;
- } else {
- clk_enable(viu_dev->clk);
- }
-
- /* reset VIU module */
- viu_reset(viu_dev->vr);
-
- /* install interrupt handler */
- if (request_irq(viu_dev->irq, viu_intr, 0, "viu", (void *)viu_dev)) {
- dev_err(&op->dev, "Request VIU IRQ failed.\n");
- ret = -ENODEV;
- goto err_irq;
- }
-
- mutex_unlock(&viu_dev->lock);
-
- dev_info(&op->dev, "Freescale VIU Video Capture Board\n");
- return ret;
-
-err_irq:
- clk_disable(viu_dev->clk);
- clk_put(viu_dev->clk);
-err_clk:
- video_unregister_device(viu_dev->vdev);
-err_vdev:
- mutex_unlock(&viu_dev->lock);
- i2c_put_adapter(ad);
- v4l2_device_unregister(&viu_dev->v4l2_dev);
-err:
- irq_dispose_mapping(viu_irq);
- return ret;
-}
-
-static int __devexit viu_of_remove(struct platform_device *op)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(&op->dev);
- struct viu_dev *dev = container_of(v4l2_dev, struct viu_dev, v4l2_dev);
- struct v4l2_subdev *sdev = list_entry(v4l2_dev->subdevs.next,
- struct v4l2_subdev, list);
- struct i2c_client *client = v4l2_get_subdevdata(sdev);
-
- free_irq(dev->irq, (void *)dev);
- irq_dispose_mapping(dev->irq);
-
- clk_disable(dev->clk);
- clk_put(dev->clk);
-
- video_unregister_device(dev->vdev);
- i2c_put_adapter(client->adapter);
- v4l2_device_unregister(&dev->v4l2_dev);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int viu_suspend(struct platform_device *op, pm_message_t state)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(&op->dev);
- struct viu_dev *dev = container_of(v4l2_dev, struct viu_dev, v4l2_dev);
-
- clk_disable(dev->clk);
- return 0;
-}
-
-static int viu_resume(struct platform_device *op)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(&op->dev);
- struct viu_dev *dev = container_of(v4l2_dev, struct viu_dev, v4l2_dev);
-
- clk_enable(dev->clk);
- return 0;
-}
-#endif
-
-/*
- * Initialization and module stuff
- */
-static struct of_device_id mpc512x_viu_of_match[] = {
- {
- .compatible = "fsl,mpc5121-viu",
- },
- {},
-};
-MODULE_DEVICE_TABLE(of, mpc512x_viu_of_match);
-
-static struct platform_driver viu_of_platform_driver = {
- .probe = viu_of_probe,
- .remove = __devexit_p(viu_of_remove),
-#ifdef CONFIG_PM
- .suspend = viu_suspend,
- .resume = viu_resume,
-#endif
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- .of_match_table = mpc512x_viu_of_match,
- },
-};
-
-module_platform_driver(viu_of_platform_driver);
-
-MODULE_DESCRIPTION("Freescale Video-In(VIU)");
-MODULE_AUTHOR("Hongjun Chen");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(VIU_VERSION);
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
deleted file mode 100644
index dfe268bfa4f..00000000000
--- a/drivers/media/video/gspca/Kconfig
+++ /dev/null
@@ -1,425 +0,0 @@
-menuconfig USB_GSPCA
- tristate "GSPCA based webcams"
- depends on VIDEO_V4L2
- default m
- ---help---
- Say Y here if you want to enable selecting webcams based
- on the GSPCA framework.
-
- See <file:Documentation/video4linux/gspca.txt> for more info.
-
- This driver uses the Video For Linux API. You must say Y or M to
- "Video For Linux" to use this driver.
-
- To compile this driver as modules, choose M here: the
- module will be called gspca_main.
-
-
-if USB_GSPCA && VIDEO_V4L2
-
-source "drivers/media/video/gspca/m5602/Kconfig"
-source "drivers/media/video/gspca/stv06xx/Kconfig"
-source "drivers/media/video/gspca/gl860/Kconfig"
-
-config USB_GSPCA_BENQ
- tristate "Benq USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for the Benq DC E300 camera.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_benq.
-
-config USB_GSPCA_CONEX
- tristate "Conexant Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the Conexant chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_conex.
-
-config USB_GSPCA_CPIA1
- tristate "cpia CPiA (version 1) Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for USB cameras based on the cpia
- CPiA chip. Note that you need atleast version 0.6.4 of libv4l for
- applications to understand the videoformat generated by this driver.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_cpia1.
-
-config USB_GSPCA_ETOMS
- tristate "Etoms USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the Etoms chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_etoms.
-
-config USB_GSPCA_FINEPIX
- tristate "Fujifilm FinePix USB V4L2 driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the FinePix chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_finepix.
-
-config USB_GSPCA_JEILINJ
- tristate "Jeilin JPEG USB V4L2 driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on this Jeilin chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_jeilinj.
-
-config USB_GSPCA_JL2005BCD
- tristate "JL2005B/C/D USB V4L2 driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based the
- JL2005B, JL2005C, or JL2005D chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_jl2005bcd.
-
-config USB_GSPCA_KINECT
- tristate "Kinect sensor device USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for the Microsoft Kinect sensor device.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_kinect.
-
-config USB_GSPCA_KONICA
- tristate "Konica USB Camera V4L2 driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the Konica chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_konica.
-
-config USB_GSPCA_MARS
- tristate "Mars USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the Mars chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_mars.
-
-config USB_GSPCA_MR97310A
- tristate "Mars-Semi MR97310A USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the MR97310A chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_mr97310a.
-
-config USB_GSPCA_NW80X
- tristate "Divio based (NW80x) USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the NW80x chips.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_nw80x.
-
-config USB_GSPCA_OV519
- tristate "OV51x / OVFX2 / W996xCF USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on one of these:
- OV511(+), OV518(+), OV519, OVFX2, W9967CF, W9968CF
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_ov519.
-
-config USB_GSPCA_OV534
- tristate "OV534 OV772x USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the OV534 chip
- and sensor OV772x (e.g. Sony Playstation EYE)
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_ov534.
-
-config USB_GSPCA_OV534_9
- tristate "OV534 OV965x USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the OV534 chip
- and sensor OV965x (e.g. Hercules Dualpix)
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_ov534_9.
-
-config USB_GSPCA_PAC207
- tristate "Pixart PAC207 USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the PAC207 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_pac207.
-
-config USB_GSPCA_PAC7302
- tristate "Pixart PAC7302 USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the PAC7302 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_pac7302.
-
-config USB_GSPCA_PAC7311
- tristate "Pixart PAC7311 USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the PAC7311 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_pac7311.
-
-config USB_GSPCA_SE401
- tristate "SE401 USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the
- Endpoints (formerly known as AOX) se401 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_se401.
-
-config USB_GSPCA_SN9C2028
- tristate "SONIX Dual-Mode USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want streaming support for Sonix SN9C2028 cameras.
- These are supported as stillcams in libgphoto2/camlibs/sonix.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_sn9c2028.
-
-config USB_GSPCA_SN9C20X
- tristate "SN9C20X USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the
- sn9c20x chips (SN9C201 and SN9C202).
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_sn9c20x.
-
-config USB_GSPCA_SONIXB
- tristate "SONIX Bayer USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the Sonix
- chips with Bayer format (SN9C101, SN9C102 and SN9C103).
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_sonixb.
-
-config USB_GSPCA_SONIXJ
- tristate "SONIX JPEG USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the Sonix
- chips with JPEG format (SN9C102P, SN9C105 and >= SN9C110).
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_sonixj
-
-config USB_GSPCA_SPCA500
- tristate "SPCA500 USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the SPCA500 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_spca500.
-
-config USB_GSPCA_SPCA501
- tristate "SPCA501 USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the SPCA501 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_spca501.
-
-config USB_GSPCA_SPCA505
- tristate "SPCA505 USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the SPCA505 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_spca505.
-
-config USB_GSPCA_SPCA506
- tristate "SPCA506 USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the SPCA506 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_spca506.
-
-config USB_GSPCA_SPCA508
- tristate "SPCA508 USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the SPCA508 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_spca508.
-
-config USB_GSPCA_SPCA561
- tristate "SPCA561 USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the SPCA561 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_spca561.
-
-config USB_GSPCA_SPCA1528
- tristate "SPCA1528 USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the SPCA1528 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_spca1528.
-
-config USB_GSPCA_SQ905
- tristate "SQ Technologies SQ905 based USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the SQ905 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_sq905.
-
-config USB_GSPCA_SQ905C
- tristate "SQ Technologies SQ905C based USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the SQ905C chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_sq905c.
-
-config USB_GSPCA_SQ930X
- tristate "SQ Technologies SQ930X based USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the SQ930X chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_sq930x.
-
-config USB_GSPCA_STK014
- tristate "Syntek DV4000 (STK014) USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the STK014 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_stk014.
-
-config USB_GSPCA_STV0680
- tristate "STV0680 USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the STV0680 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_stv0680.
-
-config USB_GSPCA_SUNPLUS
- tristate "SUNPLUS USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the Sunplus
- SPCA504(abc) SPCA533 SPCA536 chips.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_sunplus.
-
-config USB_GSPCA_T613
- tristate "T613 (JPEG Compliance) USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the T613 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_t613.
-
-config USB_GSPCA_TOPRO
- tristate "TOPRO USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the
- TP6800 and TP6810 Topro chips.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_topro.
-
-config USB_GSPCA_TV8532
- tristate "TV8532 USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the TV8531 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_tv8532.
-
-config USB_GSPCA_VC032X
- tristate "VC032X USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the VC032X chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_vc032x.
-
-config USB_GSPCA_VICAM
- tristate "ViCam USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for the 3com homeconnect camera
- (vicam).
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_vicam.
-
-config USB_GSPCA_XIRLINK_CIT
- tristate "Xirlink C-It USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for Xirlink C-It bases cameras.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_xirlink_cit.
-
-config USB_GSPCA_ZC3XX
- tristate "ZC3XX USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the ZC3XX chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_zc3xx.
-
-endif
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
deleted file mode 100644
index c901da0bd65..00000000000
--- a/drivers/media/video/gspca/Makefile
+++ /dev/null
@@ -1,93 +0,0 @@
-obj-$(CONFIG_USB_GSPCA) += gspca_main.o
-obj-$(CONFIG_USB_GSPCA_BENQ) += gspca_benq.o
-obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o
-obj-$(CONFIG_USB_GSPCA_CPIA1) += gspca_cpia1.o
-obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
-obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
-obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o
-obj-$(CONFIG_USB_GSPCA_JL2005BCD) += gspca_jl2005bcd.o
-obj-$(CONFIG_USB_GSPCA_KINECT) += gspca_kinect.o
-obj-$(CONFIG_USB_GSPCA_KONICA) += gspca_konica.o
-obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
-obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
-obj-$(CONFIG_USB_GSPCA_NW80X) += gspca_nw80x.o
-obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
-obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
-obj-$(CONFIG_USB_GSPCA_OV534_9) += gspca_ov534_9.o
-obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
-obj-$(CONFIG_USB_GSPCA_PAC7302) += gspca_pac7302.o
-obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
-obj-$(CONFIG_USB_GSPCA_SE401) += gspca_se401.o
-obj-$(CONFIG_USB_GSPCA_SN9C2028) += gspca_sn9c2028.o
-obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o
-obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
-obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o
-obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o
-obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o
-obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o
-obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o
-obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o
-obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o
-obj-$(CONFIG_USB_GSPCA_SPCA1528) += gspca_spca1528.o
-obj-$(CONFIG_USB_GSPCA_SQ905) += gspca_sq905.o
-obj-$(CONFIG_USB_GSPCA_SQ905C) += gspca_sq905c.o
-obj-$(CONFIG_USB_GSPCA_SQ930X) += gspca_sq930x.o
-obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
-obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o
-obj-$(CONFIG_USB_GSPCA_STV0680) += gspca_stv0680.o
-obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
-obj-$(CONFIG_USB_GSPCA_TOPRO) += gspca_topro.o
-obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
-obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
-obj-$(CONFIG_USB_GSPCA_VICAM) += gspca_vicam.o
-obj-$(CONFIG_USB_GSPCA_XIRLINK_CIT) += gspca_xirlink_cit.o
-obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
-
-gspca_main-objs := gspca.o autogain_functions.o
-gspca_benq-objs := benq.o
-gspca_conex-objs := conex.o
-gspca_cpia1-objs := cpia1.o
-gspca_etoms-objs := etoms.o
-gspca_finepix-objs := finepix.o
-gspca_jeilinj-objs := jeilinj.o
-gspca_jl2005bcd-objs := jl2005bcd.o
-gspca_kinect-objs := kinect.o
-gspca_konica-objs := konica.o
-gspca_mars-objs := mars.o
-gspca_mr97310a-objs := mr97310a.o
-gspca_nw80x-objs := nw80x.o
-gspca_ov519-objs := ov519.o
-gspca_ov534-objs := ov534.o
-gspca_ov534_9-objs := ov534_9.o
-gspca_pac207-objs := pac207.o
-gspca_pac7302-objs := pac7302.o
-gspca_pac7311-objs := pac7311.o
-gspca_se401-objs := se401.o
-gspca_sn9c2028-objs := sn9c2028.o
-gspca_sn9c20x-objs := sn9c20x.o
-gspca_sonixb-objs := sonixb.o
-gspca_sonixj-objs := sonixj.o
-gspca_spca500-objs := spca500.o
-gspca_spca501-objs := spca501.o
-gspca_spca505-objs := spca505.o
-gspca_spca506-objs := spca506.o
-gspca_spca508-objs := spca508.o
-gspca_spca561-objs := spca561.o
-gspca_spca1528-objs := spca1528.o
-gspca_sq905-objs := sq905.o
-gspca_sq905c-objs := sq905c.o
-gspca_sq930x-objs := sq930x.o
-gspca_stk014-objs := stk014.o
-gspca_stv0680-objs := stv0680.o
-gspca_sunplus-objs := sunplus.o
-gspca_t613-objs := t613.o
-gspca_topro-objs := topro.o
-gspca_tv8532-objs := tv8532.o
-gspca_vc032x-objs := vc032x.o
-gspca_vicam-objs := vicam.o
-gspca_xirlink_cit-objs := xirlink_cit.o
-gspca_zc3xx-objs := zc3xx.o
-
-obj-$(CONFIG_USB_M5602) += m5602/
-obj-$(CONFIG_USB_STV06XX) += stv06xx/
-obj-$(CONFIG_USB_GL860) += gl860/
diff --git a/drivers/media/video/gspca/autogain_functions.c b/drivers/media/video/gspca/autogain_functions.c
deleted file mode 100644
index 67db674bb04..00000000000
--- a/drivers/media/video/gspca/autogain_functions.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Functions for auto gain.
- *
- * Copyright (C) 2010-2012 Hans de Goede <hdegoede@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "gspca.h"
-
-/* auto gain and exposure algorithm based on the knee algorithm described here:
- http://ytse.tricolour.net/docs/LowLightOptimization.html
-
- Returns 0 if no changes were made, 1 if the gain and or exposure settings
- where changed. */
-int gspca_expo_autogain(
- struct gspca_dev *gspca_dev,
- int avg_lum,
- int desired_avg_lum,
- int deadzone,
- int gain_knee,
- int exposure_knee)
-{
- s32 gain, orig_gain, exposure, orig_exposure;
- int i, steps, retval = 0;
-
- if (v4l2_ctrl_g_ctrl(gspca_dev->autogain) == 0)
- return 0;
-
- orig_gain = gain = v4l2_ctrl_g_ctrl(gspca_dev->gain);
- orig_exposure = exposure = v4l2_ctrl_g_ctrl(gspca_dev->exposure);
-
- /* If we are of a multiple of deadzone, do multiple steps to reach the
- desired lumination fast (with the risc of a slight overshoot) */
- steps = abs(desired_avg_lum - avg_lum) / deadzone;
-
- PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
- avg_lum, desired_avg_lum, steps);
-
- for (i = 0; i < steps; i++) {
- if (avg_lum > desired_avg_lum) {
- if (gain > gain_knee)
- gain--;
- else if (exposure > exposure_knee)
- exposure--;
- else if (gain > gspca_dev->gain->default_value)
- gain--;
- else if (exposure > gspca_dev->exposure->minimum)
- exposure--;
- else if (gain > gspca_dev->gain->minimum)
- gain--;
- else
- break;
- } else {
- if (gain < gspca_dev->gain->default_value)
- gain++;
- else if (exposure < exposure_knee)
- exposure++;
- else if (gain < gain_knee)
- gain++;
- else if (exposure < gspca_dev->exposure->maximum)
- exposure++;
- else if (gain < gspca_dev->gain->maximum)
- gain++;
- else
- break;
- }
- }
-
- if (gain != orig_gain) {
- v4l2_ctrl_s_ctrl(gspca_dev->gain, gain);
- retval = 1;
- }
- if (exposure != orig_exposure) {
- v4l2_ctrl_s_ctrl(gspca_dev->exposure, exposure);
- retval = 1;
- }
-
- if (retval)
- PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d",
- gain, exposure);
- return retval;
-}
-EXPORT_SYMBOL(gspca_expo_autogain);
-
-/* Autogain + exposure algorithm for cameras with a coarse exposure control
- (usually this means we can only control the clockdiv to change exposure)
- As changing the clockdiv so that the fps drops from 30 to 15 fps for
- example, will lead to a huge exposure change (it effectively doubles),
- this algorithm normally tries to only adjust the gain (between 40 and
- 80 %) and if that does not help, only then changes exposure. This leads
- to a much more stable image then using the knee algorithm which at
- certain points of the knee graph will only try to adjust exposure,
- which leads to oscilating as one exposure step is huge.
-
- Returns 0 if no changes were made, 1 if the gain and or exposure settings
- where changed. */
-int gspca_coarse_grained_expo_autogain(
- struct gspca_dev *gspca_dev,
- int avg_lum,
- int desired_avg_lum,
- int deadzone)
-{
- s32 gain_low, gain_high, gain, orig_gain, exposure, orig_exposure;
- int steps, retval = 0;
-
- if (v4l2_ctrl_g_ctrl(gspca_dev->autogain) == 0)
- return 0;
-
- orig_gain = gain = v4l2_ctrl_g_ctrl(gspca_dev->gain);
- orig_exposure = exposure = v4l2_ctrl_g_ctrl(gspca_dev->exposure);
-
- gain_low = (gspca_dev->gain->maximum - gspca_dev->gain->minimum) /
- 5 * 2 + gspca_dev->gain->minimum;
- gain_high = (gspca_dev->gain->maximum - gspca_dev->gain->minimum) /
- 5 * 4 + gspca_dev->gain->minimum;
-
- /* If we are of a multiple of deadzone, do multiple steps to reach the
- desired lumination fast (with the risc of a slight overshoot) */
- steps = (desired_avg_lum - avg_lum) / deadzone;
-
- PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
- avg_lum, desired_avg_lum, steps);
-
- if ((gain + steps) > gain_high &&
- exposure < gspca_dev->exposure->maximum) {
- gain = gain_high;
- gspca_dev->exp_too_low_cnt++;
- gspca_dev->exp_too_high_cnt = 0;
- } else if ((gain + steps) < gain_low &&
- exposure > gspca_dev->exposure->minimum) {
- gain = gain_low;
- gspca_dev->exp_too_high_cnt++;
- gspca_dev->exp_too_low_cnt = 0;
- } else {
- gain += steps;
- if (gain > gspca_dev->gain->maximum)
- gain = gspca_dev->gain->maximum;
- else if (gain < gspca_dev->gain->minimum)
- gain = gspca_dev->gain->minimum;
- gspca_dev->exp_too_high_cnt = 0;
- gspca_dev->exp_too_low_cnt = 0;
- }
-
- if (gspca_dev->exp_too_high_cnt > 3) {
- exposure--;
- gspca_dev->exp_too_high_cnt = 0;
- } else if (gspca_dev->exp_too_low_cnt > 3) {
- exposure++;
- gspca_dev->exp_too_low_cnt = 0;
- }
-
- if (gain != orig_gain) {
- v4l2_ctrl_s_ctrl(gspca_dev->gain, gain);
- retval = 1;
- }
- if (exposure != orig_exposure) {
- v4l2_ctrl_s_ctrl(gspca_dev->exposure, exposure);
- retval = 1;
- }
-
- if (retval)
- PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d",
- gain, exposure);
- return retval;
-}
-EXPORT_SYMBOL(gspca_coarse_grained_expo_autogain);
diff --git a/drivers/media/video/gspca/autogain_functions.h b/drivers/media/video/gspca/autogain_functions.h
deleted file mode 100644
index d625eafe63e..00000000000
--- a/drivers/media/video/gspca/autogain_functions.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Functions for auto gain.
- *
- * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifdef WANT_REGULAR_AUTOGAIN
-/* auto gain and exposure algorithm based on the knee algorithm described here:
- http://ytse.tricolour.net/docs/LowLightOptimization.html
-
- Returns 0 if no changes were made, 1 if the gain and or exposure settings
- where changed. */
-static inline int auto_gain_n_exposure(
- struct gspca_dev *gspca_dev,
- int avg_lum,
- int desired_avg_lum,
- int deadzone,
- int gain_knee,
- int exposure_knee)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i, steps, gain, orig_gain, exposure, orig_exposure;
- int retval = 0;
-
- orig_gain = gain = sd->ctrls[GAIN].val;
- orig_exposure = exposure = sd->ctrls[EXPOSURE].val;
-
- /* If we are of a multiple of deadzone, do multiple steps to reach the
- desired lumination fast (with the risc of a slight overshoot) */
- steps = abs(desired_avg_lum - avg_lum) / deadzone;
-
- PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
- avg_lum, desired_avg_lum, steps);
-
- for (i = 0; i < steps; i++) {
- if (avg_lum > desired_avg_lum) {
- if (gain > gain_knee)
- gain--;
- else if (exposure > exposure_knee)
- exposure--;
- else if (gain > sd->ctrls[GAIN].def)
- gain--;
- else if (exposure > sd->ctrls[EXPOSURE].min)
- exposure--;
- else if (gain > sd->ctrls[GAIN].min)
- gain--;
- else
- break;
- } else {
- if (gain < sd->ctrls[GAIN].def)
- gain++;
- else if (exposure < exposure_knee)
- exposure++;
- else if (gain < gain_knee)
- gain++;
- else if (exposure < sd->ctrls[EXPOSURE].max)
- exposure++;
- else if (gain < sd->ctrls[GAIN].max)
- gain++;
- else
- break;
- }
- }
-
- if (gain != orig_gain) {
- sd->ctrls[GAIN].val = gain;
- setgain(gspca_dev);
- retval = 1;
- }
- if (exposure != orig_exposure) {
- sd->ctrls[EXPOSURE].val = exposure;
- setexposure(gspca_dev);
- retval = 1;
- }
-
- if (retval)
- PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d",
- gain, exposure);
- return retval;
-}
-#endif
-
-#ifdef WANT_COARSE_EXPO_AUTOGAIN
-/* Autogain + exposure algorithm for cameras with a coarse exposure control
- (usually this means we can only control the clockdiv to change exposure)
- As changing the clockdiv so that the fps drops from 30 to 15 fps for
- example, will lead to a huge exposure change (it effectively doubles),
- this algorithm normally tries to only adjust the gain (between 40 and
- 80 %) and if that does not help, only then changes exposure. This leads
- to a much more stable image then using the knee algorithm which at
- certain points of the knee graph will only try to adjust exposure,
- which leads to oscilating as one exposure step is huge.
-
- Note this assumes that the sd struct for the cam in question has
- exp_too_low_cnt and exp_too_high_cnt int members for use by this function.
-
- Returns 0 if no changes were made, 1 if the gain and or exposure settings
- where changed. */
-static inline int coarse_grained_expo_autogain(
- struct gspca_dev *gspca_dev,
- int avg_lum,
- int desired_avg_lum,
- int deadzone)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int steps, gain, orig_gain, exposure, orig_exposure;
- int gain_low, gain_high;
- int retval = 0;
-
- orig_gain = gain = sd->ctrls[GAIN].val;
- orig_exposure = exposure = sd->ctrls[EXPOSURE].val;
-
- gain_low = (sd->ctrls[GAIN].max - sd->ctrls[GAIN].min) / 5 * 2;
- gain_low += sd->ctrls[GAIN].min;
- gain_high = (sd->ctrls[GAIN].max - sd->ctrls[GAIN].min) / 5 * 4;
- gain_high += sd->ctrls[GAIN].min;
-
- /* If we are of a multiple of deadzone, do multiple steps to reach the
- desired lumination fast (with the risc of a slight overshoot) */
- steps = (desired_avg_lum - avg_lum) / deadzone;
-
- PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
- avg_lum, desired_avg_lum, steps);
-
- if ((gain + steps) > gain_high &&
- exposure < sd->ctrls[EXPOSURE].max) {
- gain = gain_high;
- sd->exp_too_low_cnt++;
- sd->exp_too_high_cnt = 0;
- } else if ((gain + steps) < gain_low &&
- exposure > sd->ctrls[EXPOSURE].min) {
- gain = gain_low;
- sd->exp_too_high_cnt++;
- sd->exp_too_low_cnt = 0;
- } else {
- gain += steps;
- if (gain > sd->ctrls[GAIN].max)
- gain = sd->ctrls[GAIN].max;
- else if (gain < sd->ctrls[GAIN].min)
- gain = sd->ctrls[GAIN].min;
- sd->exp_too_high_cnt = 0;
- sd->exp_too_low_cnt = 0;
- }
-
- if (sd->exp_too_high_cnt > 3) {
- exposure--;
- sd->exp_too_high_cnt = 0;
- } else if (sd->exp_too_low_cnt > 3) {
- exposure++;
- sd->exp_too_low_cnt = 0;
- }
-
- if (gain != orig_gain) {
- sd->ctrls[GAIN].val = gain;
- setgain(gspca_dev);
- retval = 1;
- }
- if (exposure != orig_exposure) {
- sd->ctrls[EXPOSURE].val = exposure;
- setexposure(gspca_dev);
- retval = 1;
- }
-
- if (retval)
- PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d",
- gain, exposure);
- return retval;
-}
-#endif
diff --git a/drivers/media/video/gspca/benq.c b/drivers/media/video/gspca/benq.c
deleted file mode 100644
index 352f32190e6..00000000000
--- a/drivers/media/video/gspca/benq.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Benq DC E300 subdriver
- *
- * Copyright (C) 2009 Jean-Francois Moine (http://moinejf.free.fr)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "benq"
-
-#include "gspca.h"
-
-MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
-MODULE_DESCRIPTION("Benq DC E300 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG},
-};
-
-static void sd_isoc_irq(struct urb *urb);
-
-/* -- write a register -- */
-static void reg_w(struct gspca_dev *gspca_dev,
- u16 value, u16 index)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x02,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value,
- index,
- NULL,
- 0,
- 500);
- if (ret < 0) {
- pr_err("reg_w err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- gspca_dev->cam.cam_mode = vga_mode;
- gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
- gspca_dev->cam.no_urb_create = 1;
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- return 0;
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct urb *urb;
- int i, n;
-
- /* create 4 URBs - 2 on endpoint 0x83 and 2 on 0x082 */
-#if MAX_NURBS < 4
-#error "Not enough URBs in the gspca table"
-#endif
-#define SD_PKT_SZ 64
-#define SD_NPKT 32
- for (n = 0; n < 4; n++) {
- urb = usb_alloc_urb(SD_NPKT, GFP_KERNEL);
- if (!urb) {
- pr_err("usb_alloc_urb failed\n");
- return -ENOMEM;
- }
- gspca_dev->urb[n] = urb;
- urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev,
- SD_PKT_SZ * SD_NPKT,
- GFP_KERNEL,
- &urb->transfer_dma);
-
- if (urb->transfer_buffer == NULL) {
- pr_err("usb_alloc_coherent failed\n");
- return -ENOMEM;
- }
- urb->dev = gspca_dev->dev;
- urb->context = gspca_dev;
- urb->transfer_buffer_length = SD_PKT_SZ * SD_NPKT;
- urb->pipe = usb_rcvisocpipe(gspca_dev->dev,
- n & 1 ? 0x82 : 0x83);
- urb->transfer_flags = URB_ISO_ASAP
- | URB_NO_TRANSFER_DMA_MAP;
- urb->interval = 1;
- urb->complete = sd_isoc_irq;
- urb->number_of_packets = SD_NPKT;
- for (i = 0; i < SD_NPKT; i++) {
- urb->iso_frame_desc[i].length = SD_PKT_SZ;
- urb->iso_frame_desc[i].offset = SD_PKT_SZ * i;
- }
- }
-
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct usb_interface *intf;
-
- reg_w(gspca_dev, 0x003c, 0x0003);
- reg_w(gspca_dev, 0x003c, 0x0004);
- reg_w(gspca_dev, 0x003c, 0x0005);
- reg_w(gspca_dev, 0x003c, 0x0006);
- reg_w(gspca_dev, 0x003c, 0x0007);
-
- intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
- usb_set_interface(gspca_dev->dev, gspca_dev->iface,
- intf->num_altsetting - 1);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- /* unused */
-}
-
-/* reception of an URB */
-static void sd_isoc_irq(struct urb *urb)
-{
- struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
- struct urb *urb0;
- u8 *data;
- int i, st;
-
- PDEBUG(D_PACK, "sd isoc irq");
- if (!gspca_dev->streaming)
- return;
- if (urb->status != 0) {
- if (urb->status == -ESHUTDOWN)
- return; /* disconnection */
-#ifdef CONFIG_PM
- if (gspca_dev->frozen)
- return;
-#endif
- pr_err("urb status: %d\n", urb->status);
- return;
- }
-
- /* if this is a control URN (ep 0x83), wait */
- if (urb == gspca_dev->urb[0] || urb == gspca_dev->urb[2])
- return;
-
- /* scan both received URBs */
- if (urb == gspca_dev->urb[1])
- urb0 = gspca_dev->urb[0];
- else
- urb0 = gspca_dev->urb[2];
- for (i = 0; i < urb->number_of_packets; i++) {
-
- /* check the packet status and length */
- if (urb0->iso_frame_desc[i].actual_length != SD_PKT_SZ
- || urb->iso_frame_desc[i].actual_length != SD_PKT_SZ) {
- PDEBUG(D_ERR, "ISOC bad lengths %d / %d",
- urb0->iso_frame_desc[i].actual_length,
- urb->iso_frame_desc[i].actual_length);
- gspca_dev->last_packet_type = DISCARD_PACKET;
- continue;
- }
- st = urb0->iso_frame_desc[i].status;
- if (st == 0)
- st = urb->iso_frame_desc[i].status;
- if (st) {
- pr_err("ISOC data error: [%d] status=%d\n",
- i, st);
- gspca_dev->last_packet_type = DISCARD_PACKET;
- continue;
- }
-
- /*
- * The images are received in URBs of different endpoints
- * (0x83 and 0x82).
- * Image pieces in URBs of ep 0x83 are continuated in URBs of
- * ep 0x82 of the same index.
- * The packets in the URBs of endpoint 0x83 start with:
- * - 80 ba/bb 00 00 = start of image followed by 'ff d8'
- * - 04 ba/bb oo oo = image piece
- * where 'oo oo' is the image offset
- (not cheked)
- * - (other -> bad frame)
- * The images are JPEG encoded with full header and
- * normal ff escape.
- * The end of image ('ff d9') may occur in any URB.
- * (not cheked)
- */
- data = (u8 *) urb0->transfer_buffer
- + urb0->iso_frame_desc[i].offset;
- if (data[0] == 0x80 && (data[1] & 0xfe) == 0xba) {
-
- /* new image */
- gspca_frame_add(gspca_dev, LAST_PACKET,
- NULL, 0);
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- data + 4, SD_PKT_SZ - 4);
- } else if (data[0] == 0x04 && (data[1] & 0xfe) == 0xba) {
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data + 4, SD_PKT_SZ - 4);
- } else {
- gspca_dev->last_packet_type = DISCARD_PACKET;
- continue;
- }
- data = (u8 *) urb->transfer_buffer
- + urb->iso_frame_desc[i].offset;
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data, SD_PKT_SZ);
- }
-
- /* resubmit the URBs */
- st = usb_submit_urb(urb0, GFP_ATOMIC);
- if (st < 0)
- pr_err("usb_submit_urb(0) ret %d\n", st);
- st = usb_submit_urb(urb, GFP_ATOMIC);
- if (st < 0)
- pr_err("usb_submit_urb() ret %d\n", st);
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x04a5, 0x3035)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
deleted file mode 100644
index c9052f20435..00000000000
--- a/drivers/media/video/gspca/conex.c
+++ /dev/null
@@ -1,966 +0,0 @@
-/*
- * Connexant Cx11646 library
- * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
- *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "conex"
-
-#include "gspca.h"
-#define CONEX_CAM 1 /* special JPEG header */
-#include "jpeg.h"
-
-MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
-MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
-MODULE_LICENSE("GPL");
-
-#define QUALITY 50
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- struct v4l2_ctrl *brightness;
- struct v4l2_ctrl *contrast;
- struct v4l2_ctrl *sat;
-
- u8 jpeg_hdr[JPEG_HDR_SZ];
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 3},
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2},
- {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-
-/* the read bytes are found in gspca_dev->usb_buf */
-static void reg_r(struct gspca_dev *gspca_dev,
- __u16 index,
- __u16 len)
-{
- struct usb_device *dev = gspca_dev->dev;
-
-#ifdef GSPCA_DEBUG
- if (len > USB_BUF_SZ) {
- pr_err("reg_r: buffer overflow\n");
- return;
- }
-#endif
- usb_control_msg(dev,
- usb_rcvctrlpipe(dev, 0),
- 0,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0,
- index, gspca_dev->usb_buf, len,
- 500);
- PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
- index, gspca_dev->usb_buf[0]);
-}
-
-/* the bytes to write are in gspca_dev->usb_buf */
-static void reg_w_val(struct gspca_dev *gspca_dev,
- __u16 index,
- __u8 val)
-{
- struct usb_device *dev = gspca_dev->dev;
-
- gspca_dev->usb_buf[0] = val;
- usb_control_msg(dev,
- usb_sndctrlpipe(dev, 0),
- 0,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0,
- index, gspca_dev->usb_buf, 1, 500);
-}
-
-static void reg_w(struct gspca_dev *gspca_dev,
- __u16 index,
- const __u8 *buffer,
- __u16 len)
-{
- struct usb_device *dev = gspca_dev->dev;
-
-#ifdef GSPCA_DEBUG
- if (len > USB_BUF_SZ) {
- pr_err("reg_w: buffer overflow\n");
- return;
- }
- PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
-#endif
- memcpy(gspca_dev->usb_buf, buffer, len);
- usb_control_msg(dev,
- usb_sndctrlpipe(dev, 0),
- 0,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0,
- index, gspca_dev->usb_buf, len, 500);
-}
-
-static const __u8 cx_sensor_init[][4] = {
- {0x88, 0x11, 0x01, 0x01},
- {0x88, 0x12, 0x70, 0x01},
- {0x88, 0x0f, 0x00, 0x01},
- {0x88, 0x05, 0x01, 0x01},
- {}
-};
-
-static const __u8 cx11646_fw1[][3] = {
- {0x00, 0x02, 0x00},
- {0x01, 0x43, 0x00},
- {0x02, 0xA7, 0x00},
- {0x03, 0x8B, 0x01},
- {0x04, 0xE9, 0x02},
- {0x05, 0x08, 0x04},
- {0x06, 0x08, 0x05},
- {0x07, 0x07, 0x06},
- {0x08, 0xE7, 0x06},
- {0x09, 0xC6, 0x07},
- {0x0A, 0x86, 0x08},
- {0x0B, 0x46, 0x09},
- {0x0C, 0x05, 0x0A},
- {0x0D, 0xA5, 0x0A},
- {0x0E, 0x45, 0x0B},
- {0x0F, 0xE5, 0x0B},
- {0x10, 0x85, 0x0C},
- {0x11, 0x25, 0x0D},
- {0x12, 0xC4, 0x0D},
- {0x13, 0x45, 0x0E},
- {0x14, 0xE4, 0x0E},
- {0x15, 0x64, 0x0F},
- {0x16, 0xE4, 0x0F},
- {0x17, 0x64, 0x10},
- {0x18, 0xE4, 0x10},
- {0x19, 0x64, 0x11},
- {0x1A, 0xE4, 0x11},
- {0x1B, 0x64, 0x12},
- {0x1C, 0xE3, 0x12},
- {0x1D, 0x44, 0x13},
- {0x1E, 0xC3, 0x13},
- {0x1F, 0x24, 0x14},
- {0x20, 0xA3, 0x14},
- {0x21, 0x04, 0x15},
- {0x22, 0x83, 0x15},
- {0x23, 0xE3, 0x15},
- {0x24, 0x43, 0x16},
- {0x25, 0xA4, 0x16},
- {0x26, 0x23, 0x17},
- {0x27, 0x83, 0x17},
- {0x28, 0xE3, 0x17},
- {0x29, 0x43, 0x18},
- {0x2A, 0xA3, 0x18},
- {0x2B, 0x03, 0x19},
- {0x2C, 0x63, 0x19},
- {0x2D, 0xC3, 0x19},
- {0x2E, 0x22, 0x1A},
- {0x2F, 0x63, 0x1A},
- {0x30, 0xC3, 0x1A},
- {0x31, 0x23, 0x1B},
- {0x32, 0x83, 0x1B},
- {0x33, 0xE2, 0x1B},
- {0x34, 0x23, 0x1C},
- {0x35, 0x83, 0x1C},
- {0x36, 0xE2, 0x1C},
- {0x37, 0x23, 0x1D},
- {0x38, 0x83, 0x1D},
- {0x39, 0xE2, 0x1D},
- {0x3A, 0x23, 0x1E},
- {0x3B, 0x82, 0x1E},
- {0x3C, 0xC3, 0x1E},
- {0x3D, 0x22, 0x1F},
- {0x3E, 0x63, 0x1F},
- {0x3F, 0xC1, 0x1F},
- {}
-};
-static void cx11646_fw(struct gspca_dev*gspca_dev)
-{
- int i = 0;
-
- reg_w_val(gspca_dev, 0x006a, 0x02);
- while (cx11646_fw1[i][1]) {
- reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
- i++;
- }
- reg_w_val(gspca_dev, 0x006a, 0x00);
-}
-
-static const __u8 cxsensor[] = {
- 0x88, 0x12, 0x70, 0x01,
- 0x88, 0x0d, 0x02, 0x01,
- 0x88, 0x0f, 0x00, 0x01,
- 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
- 0x88, 0x02, 0x10, 0x01,
- 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
- 0x88, 0x0B, 0x00, 0x01,
- 0x88, 0x0A, 0x0A, 0x01,
- 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
- 0x88, 0x05, 0x01, 0x01,
- 0xA1, 0x18, 0x00, 0x01,
- 0x00
-};
-
-static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
-static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
-static const __u8 reg10[] = { 0xb1, 0xb1 };
-static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
-static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
- /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
-static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
- /* 320{0x04,0x0c,0x05,0x0f}; //320 */
-static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
-static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
-
-static void cx_sensor(struct gspca_dev*gspca_dev)
-{
- int i = 0;
- int length;
- const __u8 *ptsensor = cxsensor;
-
- reg_w(gspca_dev, 0x0020, reg20, 8);
- reg_w(gspca_dev, 0x0028, reg28, 8);
- reg_w(gspca_dev, 0x0010, reg10, 2);
- reg_w_val(gspca_dev, 0x0092, 0x03);
-
- switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
- case 0:
- reg_w(gspca_dev, 0x0071, reg71a, 4);
- break;
- case 1:
- reg_w(gspca_dev, 0x0071, reg71b, 4);
- break;
- default:
-/* case 2: */
- reg_w(gspca_dev, 0x0071, reg71c, 4);
- break;
- case 3:
- reg_w(gspca_dev, 0x0071, reg71d, 4);
- break;
- }
- reg_w(gspca_dev, 0x007b, reg7b, 6);
- reg_w_val(gspca_dev, 0x00f8, 0x00);
- reg_w(gspca_dev, 0x0010, reg10, 2);
- reg_w_val(gspca_dev, 0x0098, 0x41);
- for (i = 0; i < 11; i++) {
- if (i == 3 || i == 5 || i == 8)
- length = 8;
- else
- length = 4;
- reg_w(gspca_dev, 0x00e5, ptsensor, length);
- if (length == 4)
- reg_r(gspca_dev, 0x00e8, 1);
- else
- reg_r(gspca_dev, 0x00e8, length);
- ptsensor += length;
- }
- reg_r(gspca_dev, 0x00e7, 8);
-}
-
-static const __u8 cx_inits_176[] = {
- 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
- 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
- 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
- 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
- 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
- 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-static const __u8 cx_inits_320[] = {
- 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
- 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
- 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
- 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
- 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
- 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-static const __u8 cx_inits_352[] = {
- 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
- 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
- 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
- 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
- 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
- 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
- 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-static const __u8 cx_inits_640[] = {
- 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
- 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
- 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
- 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
- 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
- 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static void cx11646_initsize(struct gspca_dev *gspca_dev)
-{
- const __u8 *cxinit;
- static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
- static const __u8 reg17[] =
- { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
-
- switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
- case 0:
- cxinit = cx_inits_640;
- break;
- case 1:
- cxinit = cx_inits_352;
- break;
- default:
-/* case 2: */
- cxinit = cx_inits_320;
- break;
- case 3:
- cxinit = cx_inits_176;
- break;
- }
- reg_w_val(gspca_dev, 0x009a, 0x01);
- reg_w_val(gspca_dev, 0x0010, 0x10);
- reg_w(gspca_dev, 0x0012, reg12, 5);
- reg_w(gspca_dev, 0x0017, reg17, 8);
- reg_w_val(gspca_dev, 0x00c0, 0x00);
- reg_w_val(gspca_dev, 0x00c1, 0x04);
- reg_w_val(gspca_dev, 0x00c2, 0x04);
-
- reg_w(gspca_dev, 0x0061, cxinit, 8);
- cxinit += 8;
- reg_w(gspca_dev, 0x00ca, cxinit, 8);
- cxinit += 8;
- reg_w(gspca_dev, 0x00d2, cxinit, 8);
- cxinit += 8;
- reg_w(gspca_dev, 0x00da, cxinit, 6);
- cxinit += 8;
- reg_w(gspca_dev, 0x0041, cxinit, 8);
- cxinit += 8;
- reg_w(gspca_dev, 0x0049, cxinit, 8);
- cxinit += 8;
- reg_w(gspca_dev, 0x0051, cxinit, 2);
-
- reg_r(gspca_dev, 0x0010, 1);
-}
-
-static const __u8 cx_jpeg_init[][8] = {
- {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
- {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
- {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
- {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
- {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
- {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
- {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
- {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
- {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
- {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
- {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
- {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
- {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
- {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
- {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
- {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
- {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
- {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
- {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
- {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
- {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
- {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
- {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
- {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
- {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
- {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
- {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
- {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
- {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
- {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
- {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
- {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
- {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
- {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
- {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
- {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
- {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
- {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
- {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
- {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
- {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
- {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
- {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
- {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
- {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
- {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
- {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
- {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
- {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
- {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
- {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
- {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
- {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
- {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
- {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
- {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
- {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
- {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
- {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
- {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
- {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
- {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
- {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
- {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
- {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
- {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
- {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
- {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
- {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
- {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
- {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
- {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
- {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
- {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
- {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
- {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
-};
-
-
-static const __u8 cxjpeg_640[][8] = {
- {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
- {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
- {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
- {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
- {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
- {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
- {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
- {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
- {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
- {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
- {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
- {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
- {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
- {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
- {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
- {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
- {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
- {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
- {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
- {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
- {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
- {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
- {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
- {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
- {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
- {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
- {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
-};
-static const __u8 cxjpeg_352[][8] = {
- {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
- {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
- {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
- {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
- {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
- {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
- {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
- {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
- {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
- {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
- {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
- {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
- {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
- {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
- {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
- {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
- {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
- {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
- {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
- {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
- {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
- {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
- {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
- {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
- {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
- {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
- {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-};
-static const __u8 cxjpeg_320[][8] = {
- {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
- {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
- {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
- {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
- {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
- {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
- {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
- {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
- {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
- {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
- {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
- {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
- {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
- {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
- {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
- {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
- {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
- {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
- {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
- {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
- {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
- {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
- {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
- {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
- {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
- {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
- {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
-};
-static const __u8 cxjpeg_176[][8] = {
- {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
- {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
- {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
- {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
- {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
- {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
- {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
- {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
- {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
- {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
- {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
- {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
- {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
- {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
- {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
- {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
- {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
- {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
- {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
- {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
- {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
- {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
- {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
- {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
- {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
- {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
- {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-};
-/* 640 take with the zcx30x part */
-static const __u8 cxjpeg_qtable[][8] = {
- {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
- {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
- {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
- {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
- {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
- {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
- {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
- {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
- {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
- {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
- {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
- {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
- {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
- {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
- {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
- {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
- {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
- {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
-};
-
-
-static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
-{
- int i;
- int length;
-
- reg_w_val(gspca_dev, 0x00c0, 0x01);
- reg_w_val(gspca_dev, 0x00c3, 0x00);
- reg_w_val(gspca_dev, 0x00c0, 0x00);
- reg_r(gspca_dev, 0x0001, 1);
- length = 8;
- for (i = 0; i < 79; i++) {
- if (i == 78)
- length = 6;
- reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
- }
- reg_r(gspca_dev, 0x0002, 1);
- reg_w_val(gspca_dev, 0x0055, 0x14);
-}
-
-static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
-static const __u8 regE5_8[] =
- { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
-static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
-static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
-static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
-static const __u8 reg51[] = { 0x77, 0x03 };
-#define reg70 0x03
-
-static void cx11646_jpeg(struct gspca_dev*gspca_dev)
-{
- int i;
- int length;
- __u8 Reg55;
- int retry;
-
- reg_w_val(gspca_dev, 0x00c0, 0x01);
- reg_w_val(gspca_dev, 0x00c3, 0x00);
- reg_w_val(gspca_dev, 0x00c0, 0x00);
- reg_r(gspca_dev, 0x0001, 1);
- length = 8;
- switch (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv) {
- case 0:
- for (i = 0; i < 27; i++) {
- if (i == 26)
- length = 2;
- reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
- }
- Reg55 = 0x28;
- break;
- case 1:
- for (i = 0; i < 27; i++) {
- if (i == 26)
- length = 2;
- reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
- }
- Reg55 = 0x16;
- break;
- default:
-/* case 2: */
- for (i = 0; i < 27; i++) {
- if (i == 26)
- length = 2;
- reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
- }
- Reg55 = 0x14;
- break;
- case 3:
- for (i = 0; i < 27; i++) {
- if (i == 26)
- length = 2;
- reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
- }
- Reg55 = 0x0B;
- break;
- }
-
- reg_r(gspca_dev, 0x0002, 1);
- reg_w_val(gspca_dev, 0x0055, Reg55);
- reg_r(gspca_dev, 0x0002, 1);
- reg_w(gspca_dev, 0x0010, reg10, 2);
- reg_w_val(gspca_dev, 0x0054, 0x02);
- reg_w_val(gspca_dev, 0x0054, 0x01);
- reg_w_val(gspca_dev, 0x0000, 0x94);
- reg_w_val(gspca_dev, 0x0053, 0xc0);
- reg_w_val(gspca_dev, 0x00fc, 0xe1);
- reg_w_val(gspca_dev, 0x0000, 0x00);
- /* wait for completion */
- retry = 50;
- do {
- reg_r(gspca_dev, 0x0002, 1);
- /* 0x07 until 0x00 */
- if (gspca_dev->usb_buf[0] == 0x00)
- break;
- reg_w_val(gspca_dev, 0x0053, 0x00);
- } while (--retry);
- if (retry == 0)
- PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
- /* send the qtable now */
- reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
- length = 8;
- for (i = 0; i < 18; i++) {
- if (i == 17)
- length = 2;
- reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
-
- }
- reg_r(gspca_dev, 0x0002, 1); /* 0x00 */
- reg_r(gspca_dev, 0x0053, 1); /* 0x00 */
- reg_w_val(gspca_dev, 0x0054, 0x02);
- reg_w_val(gspca_dev, 0x0054, 0x01);
- reg_w_val(gspca_dev, 0x0000, 0x94);
- reg_w_val(gspca_dev, 0x0053, 0xc0);
-
- reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
- reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
- reg_r(gspca_dev, 0x001f, 1); /* 0x38 */
- reg_w(gspca_dev, 0x0012, reg12, 5);
- reg_w(gspca_dev, 0x00e5, regE5_8, 8);
- reg_r(gspca_dev, 0x00e8, 8);
- reg_w(gspca_dev, 0x00e5, regE5a, 4);
- reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
- reg_w_val(gspca_dev, 0x009a, 0x01);
- reg_w(gspca_dev, 0x00e5, regE5b, 4);
- reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
- reg_w(gspca_dev, 0x00e5, regE5c, 4);
- reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
-
- reg_w(gspca_dev, 0x0051, reg51, 2);
- reg_w(gspca_dev, 0x0010, reg10, 2);
- reg_w_val(gspca_dev, 0x0070, reg70);
-}
-
-static void cx11646_init1(struct gspca_dev *gspca_dev)
-{
- int i = 0;
-
- reg_w_val(gspca_dev, 0x0010, 0x00);
- reg_w_val(gspca_dev, 0x0053, 0x00);
- reg_w_val(gspca_dev, 0x0052, 0x00);
- reg_w_val(gspca_dev, 0x009b, 0x2f);
- reg_w_val(gspca_dev, 0x009c, 0x10);
- reg_r(gspca_dev, 0x0098, 1);
- reg_w_val(gspca_dev, 0x0098, 0x40);
- reg_r(gspca_dev, 0x0099, 1);
- reg_w_val(gspca_dev, 0x0099, 0x07);
- reg_w_val(gspca_dev, 0x0039, 0x40);
- reg_w_val(gspca_dev, 0x003c, 0xff);
- reg_w_val(gspca_dev, 0x003f, 0x1f);
- reg_w_val(gspca_dev, 0x003d, 0x40);
-/* reg_w_val(gspca_dev, 0x003d, 0x60); */
- reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */
-
- while (cx_sensor_init[i][0]) {
- reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
- reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
- if (i == 1) {
- reg_w_val(gspca_dev, 0x00ed, 0x01);
- reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
- }
- i++;
- }
- reg_w_val(gspca_dev, 0x00c3, 0x00);
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct cam *cam;
-
- cam = &gspca_dev->cam;
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- cx11646_init1(gspca_dev);
- cx11646_initsize(gspca_dev);
- cx11646_fw(gspca_dev);
- cx_sensor(gspca_dev);
- cx11646_jpegInit(gspca_dev);
- return 0;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* create the JPEG header */
- jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
- 0x22); /* JPEG 411 */
- jpeg_set_qual(sd->jpeg_hdr, QUALITY);
-
- cx11646_initsize(gspca_dev);
- cx11646_fw(gspca_dev);
- cx_sensor(gspca_dev);
- cx11646_jpeg(gspca_dev);
- return 0;
-}
-
-/* called on streamoff with alt 0 and on disconnect */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- int retry = 50;
-
- if (!gspca_dev->present)
- return;
- reg_w_val(gspca_dev, 0x0000, 0x00);
- reg_r(gspca_dev, 0x0002, 1);
- reg_w_val(gspca_dev, 0x0053, 0x00);
-
- while (retry--) {
-/* reg_r(gspca_dev, 0x0002, 1);*/
- reg_r(gspca_dev, 0x0053, 1);
- if (gspca_dev->usb_buf[0] == 0)
- break;
- }
- reg_w_val(gspca_dev, 0x0000, 0x00);
- reg_r(gspca_dev, 0x0002, 1);
-
- reg_w_val(gspca_dev, 0x0010, 0x00);
- reg_r(gspca_dev, 0x0033, 1);
- reg_w_val(gspca_dev, 0x00fc, 0xe0);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (data[0] == 0xff && data[1] == 0xd8) {
-
- /* start of frame */
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
-
- /* put the JPEG header in the new frame */
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sd->jpeg_hdr, JPEG_HDR_SZ);
- data += 2;
- len -= 2;
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val, s32 sat)
-{
- __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
- __u8 reg51c[2];
-
- regE5cbx[2] = val;
- reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
- reg_r(gspca_dev, 0x00e8, 8);
- reg_w(gspca_dev, 0x00e5, regE5c, 4);
- reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
-
- reg51c[0] = 0x77;
- reg51c[1] = sat;
- reg_w(gspca_dev, 0x0051, reg51c, 2);
- reg_w(gspca_dev, 0x0010, reg10, 2);
- reg_w_val(gspca_dev, 0x0070, reg70);
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, s32 val, s32 sat)
-{
- __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
-/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
- __u8 reg51c[2];
-
- regE5acx[2] = val;
- reg_w(gspca_dev, 0x00e5, regE5acx, 4);
- reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
- reg51c[0] = 0x77;
- reg51c[1] = sat;
- reg_w(gspca_dev, 0x0051, reg51c, 2);
- reg_w(gspca_dev, 0x0010, reg10, 2);
- reg_w_val(gspca_dev, 0x0070, reg70);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val, sd->sat->cur.val);
- break;
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val, sd->sat->cur.val);
- break;
- case V4L2_CID_SATURATION:
- setbrightness(gspca_dev, sd->brightness->cur.val, ctrl->val);
- setcontrast(gspca_dev, sd->contrast->cur.val, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 3);
- sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 0xd4);
- sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0x0a, 0x1f, 1, 0x0c);
- sd->sat = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0, 7, 1, 3);
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x0572, 0x0041)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c
deleted file mode 100644
index 2499a881d9a..00000000000
--- a/drivers/media/video/gspca/cpia1.c
+++ /dev/null
@@ -1,1905 +0,0 @@
-/*
- * cpia CPiA (1) gspca driver
- *
- * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com>
- *
- * This module is adapted from the in kernel v4l1 cpia driver which is :
- *
- * (C) Copyright 1999-2000 Peter Pregler
- * (C) Copyright 1999-2000 Scott J. Bertin
- * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
- * (C) Copyright 2000 STMicroelectronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "cpia1"
-
-#include <linux/input.h>
-#include "gspca.h"
-
-MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
-MODULE_DESCRIPTION("Vision CPiA");
-MODULE_LICENSE("GPL");
-
-/* constant value's */
-#define MAGIC_0 0x19
-#define MAGIC_1 0x68
-#define DATA_IN 0xc0
-#define DATA_OUT 0x40
-#define VIDEOSIZE_QCIF 0 /* 176x144 */
-#define VIDEOSIZE_CIF 1 /* 352x288 */
-#define SUBSAMPLE_420 0
-#define SUBSAMPLE_422 1
-#define YUVORDER_YUYV 0
-#define YUVORDER_UYVY 1
-#define NOT_COMPRESSED 0
-#define COMPRESSED 1
-#define NO_DECIMATION 0
-#define DECIMATION_ENAB 1
-#define EOI 0xff /* End Of Image */
-#define EOL 0xfd /* End Of Line */
-#define FRAME_HEADER_SIZE 64
-
-/* Image grab modes */
-#define CPIA_GRAB_SINGLE 0
-#define CPIA_GRAB_CONTINEOUS 1
-
-/* Compression parameters */
-#define CPIA_COMPRESSION_NONE 0
-#define CPIA_COMPRESSION_AUTO 1
-#define CPIA_COMPRESSION_MANUAL 2
-#define CPIA_COMPRESSION_TARGET_QUALITY 0
-#define CPIA_COMPRESSION_TARGET_FRAMERATE 1
-
-/* Return offsets for GetCameraState */
-#define SYSTEMSTATE 0
-#define GRABSTATE 1
-#define STREAMSTATE 2
-#define FATALERROR 3
-#define CMDERROR 4
-#define DEBUGFLAGS 5
-#define VPSTATUS 6
-#define ERRORCODE 7
-
-/* SystemState */
-#define UNINITIALISED_STATE 0
-#define PASS_THROUGH_STATE 1
-#define LO_POWER_STATE 2
-#define HI_POWER_STATE 3
-#define WARM_BOOT_STATE 4
-
-/* GrabState */
-#define GRAB_IDLE 0
-#define GRAB_ACTIVE 1
-#define GRAB_DONE 2
-
-/* StreamState */
-#define STREAM_NOT_READY 0
-#define STREAM_READY 1
-#define STREAM_OPEN 2
-#define STREAM_PAUSED 3
-#define STREAM_FINISHED 4
-
-/* Fatal Error, CmdError, and DebugFlags */
-#define CPIA_FLAG 1
-#define SYSTEM_FLAG 2
-#define INT_CTRL_FLAG 4
-#define PROCESS_FLAG 8
-#define COM_FLAG 16
-#define VP_CTRL_FLAG 32
-#define CAPTURE_FLAG 64
-#define DEBUG_FLAG 128
-
-/* VPStatus */
-#define VP_STATE_OK 0x00
-
-#define VP_STATE_FAILED_VIDEOINIT 0x01
-#define VP_STATE_FAILED_AECACBINIT 0x02
-#define VP_STATE_AEC_MAX 0x04
-#define VP_STATE_ACB_BMAX 0x08
-
-#define VP_STATE_ACB_RMIN 0x10
-#define VP_STATE_ACB_GMIN 0x20
-#define VP_STATE_ACB_RMAX 0x40
-#define VP_STATE_ACB_GMAX 0x80
-
-/* default (minimum) compensation values */
-#define COMP_RED 220
-#define COMP_GREEN1 214
-#define COMP_GREEN2 COMP_GREEN1
-#define COMP_BLUE 230
-
-/* exposure status */
-#define EXPOSURE_VERY_LIGHT 0
-#define EXPOSURE_LIGHT 1
-#define EXPOSURE_NORMAL 2
-#define EXPOSURE_DARK 3
-#define EXPOSURE_VERY_DARK 4
-
-#define CPIA_MODULE_CPIA (0 << 5)
-#define CPIA_MODULE_SYSTEM (1 << 5)
-#define CPIA_MODULE_VP_CTRL (5 << 5)
-#define CPIA_MODULE_CAPTURE (6 << 5)
-#define CPIA_MODULE_DEBUG (7 << 5)
-
-#define INPUT (DATA_IN << 8)
-#define OUTPUT (DATA_OUT << 8)
-
-#define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
-#define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
-#define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
-#define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
-#define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
-#define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
-#define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
-#define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
-
-#define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
-#define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
-#define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
-#define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
-#define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
-#define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
-#define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
-#define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
-#define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
-#define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
-#define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
-#define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
-#define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
-
-#define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
-#define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
-#define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
-#define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
-#define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
-#define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
-#define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
-#define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
-#define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
-#define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
-#define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
-#define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
-#define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
-#define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
-#define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
-#define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
-#define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
-
-#define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
-#define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
-#define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
-#define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
-#define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
-#define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
-#define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
-#define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
-#define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
-#define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
-#define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
-#define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
-#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
-#define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
-#define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
-
-#define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
-#define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
-#define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
-#define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
-#define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
-#define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
-#define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
-#define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
-
-#define ROUND_UP_EXP_FOR_FLICKER 15
-
-/* Constants for automatic frame rate adjustment */
-#define MAX_EXP 302
-#define MAX_EXP_102 255
-#define LOW_EXP 140
-#define VERY_LOW_EXP 70
-#define TC 94
-#define EXP_ACC_DARK 50
-#define EXP_ACC_LIGHT 90
-#define HIGH_COMP_102 160
-#define MAX_COMP 239
-#define DARK_TIME 3
-#define LIGHT_TIME 3
-
-#define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
- sd->params.version.firmwareRevision == (y))
-
-#define CPIA1_CID_COMP_TARGET (V4L2_CTRL_CLASS_USER + 0x1000)
-#define BRIGHTNESS_DEF 50
-#define CONTRAST_DEF 48
-#define SATURATION_DEF 50
-#define FREQ_DEF V4L2_CID_POWER_LINE_FREQUENCY_50HZ
-#define ILLUMINATORS_1_DEF 0
-#define ILLUMINATORS_2_DEF 0
-#define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
-
-/* Developer's Guide Table 5 p 3-34
- * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
-static u8 flicker_jumps[2][2][4] =
-{ { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
- { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
-};
-
-struct cam_params {
- struct {
- u8 firmwareVersion;
- u8 firmwareRevision;
- u8 vcVersion;
- u8 vcRevision;
- } version;
- struct {
- u16 vendor;
- u16 product;
- u16 deviceRevision;
- } pnpID;
- struct {
- u8 vpVersion;
- u8 vpRevision;
- u16 cameraHeadID;
- } vpVersion;
- struct {
- u8 systemState;
- u8 grabState;
- u8 streamState;
- u8 fatalError;
- u8 cmdError;
- u8 debugFlags;
- u8 vpStatus;
- u8 errorCode;
- } status;
- struct {
- u8 brightness;
- u8 contrast;
- u8 saturation;
- } colourParams;
- struct {
- u8 gainMode;
- u8 expMode;
- u8 compMode;
- u8 centreWeight;
- u8 gain;
- u8 fineExp;
- u8 coarseExpLo;
- u8 coarseExpHi;
- u8 redComp;
- u8 green1Comp;
- u8 green2Comp;
- u8 blueComp;
- } exposure;
- struct {
- u8 balanceMode;
- u8 redGain;
- u8 greenGain;
- u8 blueGain;
- } colourBalance;
- struct {
- u8 divisor;
- u8 baserate;
- } sensorFps;
- struct {
- u8 gain1;
- u8 gain2;
- u8 gain4;
- u8 gain8;
- } apcor;
- struct {
- u8 disabled;
- u8 flickerMode;
- u8 coarseJump;
- u8 allowableOverExposure;
- } flickerControl;
- struct {
- u8 gain1;
- u8 gain2;
- u8 gain4;
- u8 gain8;
- } vlOffset;
- struct {
- u8 mode;
- u8 decimation;
- } compression;
- struct {
- u8 frTargeting;
- u8 targetFR;
- u8 targetQ;
- } compressionTarget;
- struct {
- u8 yThreshold;
- u8 uvThreshold;
- } yuvThreshold;
- struct {
- u8 hysteresis;
- u8 threshMax;
- u8 smallStep;
- u8 largeStep;
- u8 decimationHysteresis;
- u8 frDiffStepThresh;
- u8 qDiffStepThresh;
- u8 decimationThreshMod;
- } compressionParams;
- struct {
- u8 videoSize; /* CIF/QCIF */
- u8 subSample;
- u8 yuvOrder;
- } format;
- struct { /* Intel QX3 specific data */
- u8 qx3_detected; /* a QX3 is present */
- u8 toplight; /* top light lit , R/W */
- u8 bottomlight; /* bottom light lit, R/W */
- u8 button; /* snapshot button pressed (R/O) */
- u8 cradled; /* microscope is in cradle (R/O) */
- } qx3;
- struct {
- u8 colStart; /* skip first 8*colStart pixels */
- u8 colEnd; /* finish at 8*colEnd pixels */
- u8 rowStart; /* skip first 4*rowStart lines */
- u8 rowEnd; /* finish at 4*rowEnd lines */
- } roi;
- u8 ecpTiming;
- u8 streamStartLine;
-};
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- struct cam_params params; /* camera settings */
-
- atomic_t cam_exposure;
- atomic_t fps;
- int exposure_count;
- u8 exposure_status;
- struct v4l2_ctrl *freq;
- u8 mainsFreq; /* 0 = 50hz, 1 = 60hz */
- u8 first_frame;
-};
-
-static const struct v4l2_pix_format mode[] = {
- {160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
- /* The sizeimage is trial and error, as with low framerates
- the camera will pad out usb frames, making the image
- data larger then strictly necessary */
- .bytesperline = 160,
- .sizeimage = 65536,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 3},
- {176, 144, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
- .bytesperline = 172,
- .sizeimage = 65536,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
- {320, 240, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 262144,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {352, 288, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 262144,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-/**********************************************************************
- *
- * General functions
- *
- **********************************************************************/
-
-static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
-{
- u8 requesttype;
- unsigned int pipe;
- int ret, databytes = command[6] | (command[7] << 8);
- /* Sometimes we see spurious EPIPE errors */
- int retries = 3;
-
- if (command[0] == DATA_IN) {
- pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
- requesttype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
- } else if (command[0] == DATA_OUT) {
- pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
- requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
- } else {
- PDEBUG(D_ERR, "Unexpected first byte of command: %x",
- command[0]);
- return -EINVAL;
- }
-
-retry:
- ret = usb_control_msg(gspca_dev->dev, pipe,
- command[1],
- requesttype,
- command[2] | (command[3] << 8),
- command[4] | (command[5] << 8),
- gspca_dev->usb_buf, databytes, 1000);
-
- if (ret < 0)
- pr_err("usb_control_msg %02x, error %d\n", command[1], ret);
-
- if (ret == -EPIPE && retries > 0) {
- retries--;
- goto retry;
- }
-
- return (ret < 0) ? ret : 0;
-}
-
-/* send an arbitrary command to the camera */
-static int do_command(struct gspca_dev *gspca_dev, u16 command,
- u8 a, u8 b, u8 c, u8 d)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret, datasize;
- u8 cmd[8];
-
- switch (command) {
- case CPIA_COMMAND_GetCPIAVersion:
- case CPIA_COMMAND_GetPnPID:
- case CPIA_COMMAND_GetCameraStatus:
- case CPIA_COMMAND_GetVPVersion:
- case CPIA_COMMAND_GetColourParams:
- case CPIA_COMMAND_GetColourBalance:
- case CPIA_COMMAND_GetExposure:
- datasize = 8;
- break;
- case CPIA_COMMAND_ReadMCPorts:
- case CPIA_COMMAND_ReadVCRegs:
- datasize = 4;
- break;
- default:
- datasize = 0;
- break;
- }
-
- cmd[0] = command >> 8;
- cmd[1] = command & 0xff;
- cmd[2] = a;
- cmd[3] = b;
- cmd[4] = c;
- cmd[5] = d;
- cmd[6] = datasize;
- cmd[7] = 0;
-
- ret = cpia_usb_transferCmd(gspca_dev, cmd);
- if (ret)
- return ret;
-
- switch (command) {
- case CPIA_COMMAND_GetCPIAVersion:
- sd->params.version.firmwareVersion = gspca_dev->usb_buf[0];
- sd->params.version.firmwareRevision = gspca_dev->usb_buf[1];
- sd->params.version.vcVersion = gspca_dev->usb_buf[2];
- sd->params.version.vcRevision = gspca_dev->usb_buf[3];
- break;
- case CPIA_COMMAND_GetPnPID:
- sd->params.pnpID.vendor =
- gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
- sd->params.pnpID.product =
- gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
- sd->params.pnpID.deviceRevision =
- gspca_dev->usb_buf[4] | (gspca_dev->usb_buf[5] << 8);
- break;
- case CPIA_COMMAND_GetCameraStatus:
- sd->params.status.systemState = gspca_dev->usb_buf[0];
- sd->params.status.grabState = gspca_dev->usb_buf[1];
- sd->params.status.streamState = gspca_dev->usb_buf[2];
- sd->params.status.fatalError = gspca_dev->usb_buf[3];
- sd->params.status.cmdError = gspca_dev->usb_buf[4];
- sd->params.status.debugFlags = gspca_dev->usb_buf[5];
- sd->params.status.vpStatus = gspca_dev->usb_buf[6];
- sd->params.status.errorCode = gspca_dev->usb_buf[7];
- break;
- case CPIA_COMMAND_GetVPVersion:
- sd->params.vpVersion.vpVersion = gspca_dev->usb_buf[0];
- sd->params.vpVersion.vpRevision = gspca_dev->usb_buf[1];
- sd->params.vpVersion.cameraHeadID =
- gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
- break;
- case CPIA_COMMAND_GetColourParams:
- sd->params.colourParams.brightness = gspca_dev->usb_buf[0];
- sd->params.colourParams.contrast = gspca_dev->usb_buf[1];
- sd->params.colourParams.saturation = gspca_dev->usb_buf[2];
- break;
- case CPIA_COMMAND_GetColourBalance:
- sd->params.colourBalance.redGain = gspca_dev->usb_buf[0];
- sd->params.colourBalance.greenGain = gspca_dev->usb_buf[1];
- sd->params.colourBalance.blueGain = gspca_dev->usb_buf[2];
- break;
- case CPIA_COMMAND_GetExposure:
- sd->params.exposure.gain = gspca_dev->usb_buf[0];
- sd->params.exposure.fineExp = gspca_dev->usb_buf[1];
- sd->params.exposure.coarseExpLo = gspca_dev->usb_buf[2];
- sd->params.exposure.coarseExpHi = gspca_dev->usb_buf[3];
- sd->params.exposure.redComp = gspca_dev->usb_buf[4];
- sd->params.exposure.green1Comp = gspca_dev->usb_buf[5];
- sd->params.exposure.green2Comp = gspca_dev->usb_buf[6];
- sd->params.exposure.blueComp = gspca_dev->usb_buf[7];
- break;
-
- case CPIA_COMMAND_ReadMCPorts:
- /* test button press */
- a = ((gspca_dev->usb_buf[1] & 0x02) == 0);
- if (a != sd->params.qx3.button) {
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, a);
- input_sync(gspca_dev->input_dev);
-#endif
- sd->params.qx3.button = a;
- }
- if (sd->params.qx3.button) {
- /* button pressed - unlock the latch */
- do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
- 3, 0xdf, 0xdf, 0);
- do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
- 3, 0xff, 0xff, 0);
- }
-
- /* test whether microscope is cradled */
- sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0);
- break;
- }
-
- return 0;
-}
-
-/* send a command to the camera with an additional data transaction */
-static int do_command_extended(struct gspca_dev *gspca_dev, u16 command,
- u8 a, u8 b, u8 c, u8 d,
- u8 e, u8 f, u8 g, u8 h,
- u8 i, u8 j, u8 k, u8 l)
-{
- u8 cmd[8];
-
- cmd[0] = command >> 8;
- cmd[1] = command & 0xff;
- cmd[2] = a;
- cmd[3] = b;
- cmd[4] = c;
- cmd[5] = d;
- cmd[6] = 8;
- cmd[7] = 0;
- gspca_dev->usb_buf[0] = e;
- gspca_dev->usb_buf[1] = f;
- gspca_dev->usb_buf[2] = g;
- gspca_dev->usb_buf[3] = h;
- gspca_dev->usb_buf[4] = i;
- gspca_dev->usb_buf[5] = j;
- gspca_dev->usb_buf[6] = k;
- gspca_dev->usb_buf[7] = l;
-
- return cpia_usb_transferCmd(gspca_dev, cmd);
-}
-
-/* find_over_exposure
- * Finds a suitable value of OverExposure for use with SetFlickerCtrl
- * Some calculation is required because this value changes with the brightness
- * set with SetColourParameters
- *
- * Parameters: Brightness - last brightness value set with SetColourParameters
- *
- * Returns: OverExposure value to use with SetFlickerCtrl
- */
-#define FLICKER_MAX_EXPOSURE 250
-#define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
-#define FLICKER_BRIGHTNESS_CONSTANT 59
-static int find_over_exposure(int brightness)
-{
- int MaxAllowableOverExposure, OverExposure;
-
- MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
- FLICKER_BRIGHTNESS_CONSTANT;
-
- if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE)
- OverExposure = MaxAllowableOverExposure;
- else
- OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
-
- return OverExposure;
-}
-#undef FLICKER_MAX_EXPOSURE
-#undef FLICKER_ALLOWABLE_OVER_EXPOSURE
-#undef FLICKER_BRIGHTNESS_CONSTANT
-
-/* initialise cam_data structure */
-static void reset_camera_params(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam_params *params = &sd->params;
-
- /* The following parameter values are the defaults from
- * "Software Developer's Guide for CPiA Cameras". Any changes
- * to the defaults are noted in comments. */
- params->colourParams.brightness = BRIGHTNESS_DEF;
- params->colourParams.contrast = CONTRAST_DEF;
- params->colourParams.saturation = SATURATION_DEF;
- params->exposure.gainMode = 4;
- params->exposure.expMode = 2; /* AEC */
- params->exposure.compMode = 1;
- params->exposure.centreWeight = 1;
- params->exposure.gain = 0;
- params->exposure.fineExp = 0;
- params->exposure.coarseExpLo = 185;
- params->exposure.coarseExpHi = 0;
- params->exposure.redComp = COMP_RED;
- params->exposure.green1Comp = COMP_GREEN1;
- params->exposure.green2Comp = COMP_GREEN2;
- params->exposure.blueComp = COMP_BLUE;
- params->colourBalance.balanceMode = 2; /* ACB */
- params->colourBalance.redGain = 32;
- params->colourBalance.greenGain = 6;
- params->colourBalance.blueGain = 92;
- params->apcor.gain1 = 0x18;
- params->apcor.gain2 = 0x16;
- params->apcor.gain4 = 0x24;
- params->apcor.gain8 = 0x34;
- params->vlOffset.gain1 = 20;
- params->vlOffset.gain2 = 24;
- params->vlOffset.gain4 = 26;
- params->vlOffset.gain8 = 26;
- params->compressionParams.hysteresis = 3;
- params->compressionParams.threshMax = 11;
- params->compressionParams.smallStep = 1;
- params->compressionParams.largeStep = 3;
- params->compressionParams.decimationHysteresis = 2;
- params->compressionParams.frDiffStepThresh = 5;
- params->compressionParams.qDiffStepThresh = 3;
- params->compressionParams.decimationThreshMod = 2;
- /* End of default values from Software Developer's Guide */
-
- /* Set Sensor FPS to 15fps. This seems better than 30fps
- * for indoor lighting. */
- params->sensorFps.divisor = 1;
- params->sensorFps.baserate = 1;
-
- params->flickerControl.flickerMode = 0;
- params->flickerControl.disabled = 1;
- params->flickerControl.coarseJump =
- flicker_jumps[sd->mainsFreq]
- [params->sensorFps.baserate]
- [params->sensorFps.divisor];
- params->flickerControl.allowableOverExposure =
- find_over_exposure(params->colourParams.brightness);
-
- params->yuvThreshold.yThreshold = 6; /* From windows driver */
- params->yuvThreshold.uvThreshold = 6; /* From windows driver */
-
- params->format.subSample = SUBSAMPLE_420;
- params->format.yuvOrder = YUVORDER_YUYV;
-
- params->compression.mode = CPIA_COMPRESSION_AUTO;
- params->compression.decimation = NO_DECIMATION;
-
- params->compressionTarget.frTargeting = COMP_TARGET_DEF;
- params->compressionTarget.targetFR = 15; /* From windows driver */
- params->compressionTarget.targetQ = 5; /* From windows driver */
-
- params->qx3.qx3_detected = 0;
- params->qx3.toplight = 0;
- params->qx3.bottomlight = 0;
- params->qx3.button = 0;
- params->qx3.cradled = 0;
-}
-
-static void printstatus(struct cam_params *params)
-{
- PDEBUG(D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
- params->status.systemState, params->status.grabState,
- params->status.streamState, params->status.fatalError,
- params->status.cmdError, params->status.debugFlags,
- params->status.vpStatus, params->status.errorCode);
-}
-
-static int goto_low_power(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0);
- if (ret)
- return ret;
-
- ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
- if (ret)
- return ret;
-
- if (sd->params.status.systemState != LO_POWER_STATE) {
- if (sd->params.status.systemState != WARM_BOOT_STATE) {
- PDEBUG(D_ERR,
- "unexpected state after lo power cmd: %02x",
- sd->params.status.systemState);
- printstatus(&sd->params);
- }
- return -EIO;
- }
-
- PDEBUG(D_CONF, "camera now in LOW power state");
- return 0;
-}
-
-static int goto_high_power(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0);
- if (ret)
- return ret;
-
- msleep_interruptible(40); /* windows driver does it too */
-
- if (signal_pending(current))
- return -EINTR;
-
- do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
- if (ret)
- return ret;
-
- if (sd->params.status.systemState != HI_POWER_STATE) {
- PDEBUG(D_ERR, "unexpected state after hi power cmd: %02x",
- sd->params.status.systemState);
- printstatus(&sd->params);
- return -EIO;
- }
-
- PDEBUG(D_CONF, "camera now in HIGH power state");
- return 0;
-}
-
-static int get_version_information(struct gspca_dev *gspca_dev)
-{
- int ret;
-
- /* GetCPIAVersion */
- ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
- if (ret)
- return ret;
-
- /* GetPnPID */
- return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
-}
-
-static int save_camera_state(struct gspca_dev *gspca_dev)
-{
- int ret;
-
- ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
- if (ret)
- return ret;
-
- return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
-}
-
-static int command_setformat(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = do_command(gspca_dev, CPIA_COMMAND_SetFormat,
- sd->params.format.videoSize,
- sd->params.format.subSample,
- sd->params.format.yuvOrder, 0);
- if (ret)
- return ret;
-
- return do_command(gspca_dev, CPIA_COMMAND_SetROI,
- sd->params.roi.colStart, sd->params.roi.colEnd,
- sd->params.roi.rowStart, sd->params.roi.rowEnd);
-}
-
-static int command_setcolourparams(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- return do_command(gspca_dev, CPIA_COMMAND_SetColourParams,
- sd->params.colourParams.brightness,
- sd->params.colourParams.contrast,
- sd->params.colourParams.saturation, 0);
-}
-
-static int command_setapcor(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- return do_command(gspca_dev, CPIA_COMMAND_SetApcor,
- sd->params.apcor.gain1,
- sd->params.apcor.gain2,
- sd->params.apcor.gain4,
- sd->params.apcor.gain8);
-}
-
-static int command_setvloffset(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset,
- sd->params.vlOffset.gain1,
- sd->params.vlOffset.gain2,
- sd->params.vlOffset.gain4,
- sd->params.vlOffset.gain8);
-}
-
-static int command_setexposure(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
- sd->params.exposure.gainMode,
- 1,
- sd->params.exposure.compMode,
- sd->params.exposure.centreWeight,
- sd->params.exposure.gain,
- sd->params.exposure.fineExp,
- sd->params.exposure.coarseExpLo,
- sd->params.exposure.coarseExpHi,
- sd->params.exposure.redComp,
- sd->params.exposure.green1Comp,
- sd->params.exposure.green2Comp,
- sd->params.exposure.blueComp);
- if (ret)
- return ret;
-
- if (sd->params.exposure.expMode != 1) {
- ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
- 0,
- sd->params.exposure.expMode,
- 0, 0,
- sd->params.exposure.gain,
- sd->params.exposure.fineExp,
- sd->params.exposure.coarseExpLo,
- sd->params.exposure.coarseExpHi,
- 0, 0, 0, 0);
- }
-
- return ret;
-}
-
-static int command_setcolourbalance(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->params.colourBalance.balanceMode == 1) {
- int ret;
-
- ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
- 1,
- sd->params.colourBalance.redGain,
- sd->params.colourBalance.greenGain,
- sd->params.colourBalance.blueGain);
- if (ret)
- return ret;
-
- return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
- 3, 0, 0, 0);
- }
- if (sd->params.colourBalance.balanceMode == 2) {
- return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
- 2, 0, 0, 0);
- }
- if (sd->params.colourBalance.balanceMode == 3) {
- return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
- 3, 0, 0, 0);
- }
-
- return -EINVAL;
-}
-
-static int command_setcompressiontarget(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- return do_command(gspca_dev, CPIA_COMMAND_SetCompressionTarget,
- sd->params.compressionTarget.frTargeting,
- sd->params.compressionTarget.targetFR,
- sd->params.compressionTarget.targetQ, 0);
-}
-
-static int command_setyuvtresh(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh,
- sd->params.yuvThreshold.yThreshold,
- sd->params.yuvThreshold.uvThreshold, 0, 0);
-}
-
-static int command_setcompressionparams(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- return do_command_extended(gspca_dev,
- CPIA_COMMAND_SetCompressionParams,
- 0, 0, 0, 0,
- sd->params.compressionParams.hysteresis,
- sd->params.compressionParams.threshMax,
- sd->params.compressionParams.smallStep,
- sd->params.compressionParams.largeStep,
- sd->params.compressionParams.decimationHysteresis,
- sd->params.compressionParams.frDiffStepThresh,
- sd->params.compressionParams.qDiffStepThresh,
- sd->params.compressionParams.decimationThreshMod);
-}
-
-static int command_setcompression(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- return do_command(gspca_dev, CPIA_COMMAND_SetCompression,
- sd->params.compression.mode,
- sd->params.compression.decimation, 0, 0);
-}
-
-static int command_setsensorfps(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS,
- sd->params.sensorFps.divisor,
- sd->params.sensorFps.baserate, 0, 0);
-}
-
-static int command_setflickerctrl(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl,
- sd->params.flickerControl.flickerMode,
- sd->params.flickerControl.coarseJump,
- sd->params.flickerControl.allowableOverExposure,
- 0);
-}
-
-static int command_setecptiming(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming,
- sd->params.ecpTiming, 0, 0, 0);
-}
-
-static int command_pause(struct gspca_dev *gspca_dev)
-{
- return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
-}
-
-static int command_resume(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap,
- 0, sd->params.streamStartLine, 0, 0);
-}
-
-static int command_setlights(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret, p1, p2;
-
- p1 = (sd->params.qx3.bottomlight == 0) << 1;
- p2 = (sd->params.qx3.toplight == 0) << 3;
-
- ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
- 0x90, 0x8f, 0x50, 0);
- if (ret)
- return ret;
-
- return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
- p1 | p2 | 0xe0, 0);
-}
-
-static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
-{
- /* Everything in here is from the Windows driver */
-/* define for compgain calculation */
-#if 0
-#define COMPGAIN(base, curexp, newexp) \
- (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
-#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
- (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
- (float)(u8)(basecomp - 128))
-#else
- /* equivalent functions without floating point math */
-#define COMPGAIN(base, curexp, newexp) \
- (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
-#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
- (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
-#endif
-
- struct sd *sd = (struct sd *) gspca_dev;
- int currentexp = sd->params.exposure.coarseExpLo +
- sd->params.exposure.coarseExpHi * 256;
- int ret, startexp;
-
- if (on) {
- int cj = sd->params.flickerControl.coarseJump;
- sd->params.flickerControl.flickerMode = 1;
- sd->params.flickerControl.disabled = 0;
- if (sd->params.exposure.expMode != 2) {
- sd->params.exposure.expMode = 2;
- sd->exposure_status = EXPOSURE_NORMAL;
- }
- currentexp = currentexp << sd->params.exposure.gain;
- sd->params.exposure.gain = 0;
- /* round down current exposure to nearest value */
- startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
- if (startexp < 1)
- startexp = 1;
- startexp = (startexp * cj) - 1;
- if (FIRMWARE_VERSION(1, 2))
- while (startexp > MAX_EXP_102)
- startexp -= cj;
- else
- while (startexp > MAX_EXP)
- startexp -= cj;
- sd->params.exposure.coarseExpLo = startexp & 0xff;
- sd->params.exposure.coarseExpHi = startexp >> 8;
- if (currentexp > startexp) {
- if (currentexp > (2 * startexp))
- currentexp = 2 * startexp;
- sd->params.exposure.redComp =
- COMPGAIN(COMP_RED, currentexp, startexp);
- sd->params.exposure.green1Comp =
- COMPGAIN(COMP_GREEN1, currentexp, startexp);
- sd->params.exposure.green2Comp =
- COMPGAIN(COMP_GREEN2, currentexp, startexp);
- sd->params.exposure.blueComp =
- COMPGAIN(COMP_BLUE, currentexp, startexp);
- } else {
- sd->params.exposure.redComp = COMP_RED;
- sd->params.exposure.green1Comp = COMP_GREEN1;
- sd->params.exposure.green2Comp = COMP_GREEN2;
- sd->params.exposure.blueComp = COMP_BLUE;
- }
- if (FIRMWARE_VERSION(1, 2))
- sd->params.exposure.compMode = 0;
- else
- sd->params.exposure.compMode = 1;
-
- sd->params.apcor.gain1 = 0x18;
- sd->params.apcor.gain2 = 0x18;
- sd->params.apcor.gain4 = 0x16;
- sd->params.apcor.gain8 = 0x14;
- } else {
- sd->params.flickerControl.flickerMode = 0;
- sd->params.flickerControl.disabled = 1;
- /* Average equivalent coarse for each comp channel */
- startexp = EXP_FROM_COMP(COMP_RED,
- sd->params.exposure.redComp, currentexp);
- startexp += EXP_FROM_COMP(COMP_GREEN1,
- sd->params.exposure.green1Comp, currentexp);
- startexp += EXP_FROM_COMP(COMP_GREEN2,
- sd->params.exposure.green2Comp, currentexp);
- startexp += EXP_FROM_COMP(COMP_BLUE,
- sd->params.exposure.blueComp, currentexp);
- startexp = startexp >> 2;
- while (startexp > MAX_EXP && sd->params.exposure.gain <
- sd->params.exposure.gainMode - 1) {
- startexp = startexp >> 1;
- ++sd->params.exposure.gain;
- }
- if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
- startexp = MAX_EXP_102;
- if (startexp > MAX_EXP)
- startexp = MAX_EXP;
- sd->params.exposure.coarseExpLo = startexp & 0xff;
- sd->params.exposure.coarseExpHi = startexp >> 8;
- sd->params.exposure.redComp = COMP_RED;
- sd->params.exposure.green1Comp = COMP_GREEN1;
- sd->params.exposure.green2Comp = COMP_GREEN2;
- sd->params.exposure.blueComp = COMP_BLUE;
- sd->params.exposure.compMode = 1;
- sd->params.apcor.gain1 = 0x18;
- sd->params.apcor.gain2 = 0x16;
- sd->params.apcor.gain4 = 0x24;
- sd->params.apcor.gain8 = 0x34;
- }
- sd->params.vlOffset.gain1 = 20;
- sd->params.vlOffset.gain2 = 24;
- sd->params.vlOffset.gain4 = 26;
- sd->params.vlOffset.gain8 = 26;
-
- if (apply) {
- ret = command_setexposure(gspca_dev);
- if (ret)
- return ret;
-
- ret = command_setapcor(gspca_dev);
- if (ret)
- return ret;
-
- ret = command_setvloffset(gspca_dev);
- if (ret)
- return ret;
-
- ret = command_setflickerctrl(gspca_dev);
- if (ret)
- return ret;
- }
-
- return 0;
-#undef EXP_FROM_COMP
-#undef COMPGAIN
-}
-
-/* monitor the exposure and adjust the sensor frame rate if needed */
-static void monitor_exposure(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 exp_acc, bcomp, cmd[8];
- int ret, light_exp, dark_exp, very_dark_exp;
- int old_exposure, new_exposure, framerate;
- int setfps = 0, setexp = 0, setflicker = 0;
-
- /* get necessary stats and register settings from camera */
- /* do_command can't handle this, so do it ourselves */
- cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
- cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
- cmd[2] = 30;
- cmd[3] = 4;
- cmd[4] = 9;
- cmd[5] = 8;
- cmd[6] = 8;
- cmd[7] = 0;
- ret = cpia_usb_transferCmd(gspca_dev, cmd);
- if (ret) {
- pr_err("ReadVPRegs(30,4,9,8) - failed: %d\n", ret);
- return;
- }
- exp_acc = gspca_dev->usb_buf[0];
- bcomp = gspca_dev->usb_buf[1];
-
- light_exp = sd->params.colourParams.brightness +
- TC - 50 + EXP_ACC_LIGHT;
- if (light_exp > 255)
- light_exp = 255;
- dark_exp = sd->params.colourParams.brightness +
- TC - 50 - EXP_ACC_DARK;
- if (dark_exp < 0)
- dark_exp = 0;
- very_dark_exp = dark_exp / 2;
-
- old_exposure = sd->params.exposure.coarseExpHi * 256 +
- sd->params.exposure.coarseExpLo;
-
- if (!sd->params.flickerControl.disabled) {
- /* Flicker control on */
- int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
- HIGH_COMP_102;
- bcomp += 128; /* decode */
- if (bcomp >= max_comp && exp_acc < dark_exp) {
- /* dark */
- if (exp_acc < very_dark_exp) {
- /* very dark */
- if (sd->exposure_status == EXPOSURE_VERY_DARK)
- ++sd->exposure_count;
- else {
- sd->exposure_status =
- EXPOSURE_VERY_DARK;
- sd->exposure_count = 1;
- }
- } else {
- /* just dark */
- if (sd->exposure_status == EXPOSURE_DARK)
- ++sd->exposure_count;
- else {
- sd->exposure_status = EXPOSURE_DARK;
- sd->exposure_count = 1;
- }
- }
- } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
- /* light */
- if (old_exposure <= VERY_LOW_EXP) {
- /* very light */
- if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
- ++sd->exposure_count;
- else {
- sd->exposure_status =
- EXPOSURE_VERY_LIGHT;
- sd->exposure_count = 1;
- }
- } else {
- /* just light */
- if (sd->exposure_status == EXPOSURE_LIGHT)
- ++sd->exposure_count;
- else {
- sd->exposure_status = EXPOSURE_LIGHT;
- sd->exposure_count = 1;
- }
- }
- } else {
- /* not dark or light */
- sd->exposure_status = EXPOSURE_NORMAL;
- }
- } else {
- /* Flicker control off */
- if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
- /* dark */
- if (exp_acc < very_dark_exp) {
- /* very dark */
- if (sd->exposure_status == EXPOSURE_VERY_DARK)
- ++sd->exposure_count;
- else {
- sd->exposure_status =
- EXPOSURE_VERY_DARK;
- sd->exposure_count = 1;
- }
- } else {
- /* just dark */
- if (sd->exposure_status == EXPOSURE_DARK)
- ++sd->exposure_count;
- else {
- sd->exposure_status = EXPOSURE_DARK;
- sd->exposure_count = 1;
- }
- }
- } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
- /* light */
- if (old_exposure <= VERY_LOW_EXP) {
- /* very light */
- if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
- ++sd->exposure_count;
- else {
- sd->exposure_status =
- EXPOSURE_VERY_LIGHT;
- sd->exposure_count = 1;
- }
- } else {
- /* just light */
- if (sd->exposure_status == EXPOSURE_LIGHT)
- ++sd->exposure_count;
- else {
- sd->exposure_status = EXPOSURE_LIGHT;
- sd->exposure_count = 1;
- }
- }
- } else {
- /* not dark or light */
- sd->exposure_status = EXPOSURE_NORMAL;
- }
- }
-
- framerate = atomic_read(&sd->fps);
- if (framerate > 30 || framerate < 1)
- framerate = 1;
-
- if (!sd->params.flickerControl.disabled) {
- /* Flicker control on */
- if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
- sd->exposure_status == EXPOSURE_DARK) &&
- sd->exposure_count >= DARK_TIME * framerate &&
- sd->params.sensorFps.divisor < 2) {
-
- /* dark for too long */
- ++sd->params.sensorFps.divisor;
- setfps = 1;
-
- sd->params.flickerControl.coarseJump =
- flicker_jumps[sd->mainsFreq]
- [sd->params.sensorFps.baserate]
- [sd->params.sensorFps.divisor];
- setflicker = 1;
-
- new_exposure = sd->params.flickerControl.coarseJump-1;
- while (new_exposure < old_exposure / 2)
- new_exposure +=
- sd->params.flickerControl.coarseJump;
- sd->params.exposure.coarseExpLo = new_exposure & 0xff;
- sd->params.exposure.coarseExpHi = new_exposure >> 8;
- setexp = 1;
- sd->exposure_status = EXPOSURE_NORMAL;
- PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
-
- } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
- sd->exposure_status == EXPOSURE_LIGHT) &&
- sd->exposure_count >= LIGHT_TIME * framerate &&
- sd->params.sensorFps.divisor > 0) {
-
- /* light for too long */
- int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
- MAX_EXP;
- --sd->params.sensorFps.divisor;
- setfps = 1;
-
- sd->params.flickerControl.coarseJump =
- flicker_jumps[sd->mainsFreq]
- [sd->params.sensorFps.baserate]
- [sd->params.sensorFps.divisor];
- setflicker = 1;
-
- new_exposure = sd->params.flickerControl.coarseJump-1;
- while (new_exposure < 2 * old_exposure &&
- new_exposure +
- sd->params.flickerControl.coarseJump < max_exp)
- new_exposure +=
- sd->params.flickerControl.coarseJump;
- sd->params.exposure.coarseExpLo = new_exposure & 0xff;
- sd->params.exposure.coarseExpHi = new_exposure >> 8;
- setexp = 1;
- sd->exposure_status = EXPOSURE_NORMAL;
- PDEBUG(D_CONF, "Automatically increasing sensor_fps");
- }
- } else {
- /* Flicker control off */
- if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
- sd->exposure_status == EXPOSURE_DARK) &&
- sd->exposure_count >= DARK_TIME * framerate &&
- sd->params.sensorFps.divisor < 2) {
-
- /* dark for too long */
- ++sd->params.sensorFps.divisor;
- setfps = 1;
-
- if (sd->params.exposure.gain > 0) {
- --sd->params.exposure.gain;
- setexp = 1;
- }
- sd->exposure_status = EXPOSURE_NORMAL;
- PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
-
- } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
- sd->exposure_status == EXPOSURE_LIGHT) &&
- sd->exposure_count >= LIGHT_TIME * framerate &&
- sd->params.sensorFps.divisor > 0) {
-
- /* light for too long */
- --sd->params.sensorFps.divisor;
- setfps = 1;
-
- if (sd->params.exposure.gain <
- sd->params.exposure.gainMode - 1) {
- ++sd->params.exposure.gain;
- setexp = 1;
- }
- sd->exposure_status = EXPOSURE_NORMAL;
- PDEBUG(D_CONF, "Automatically increasing sensor_fps");
- }
- }
-
- if (setexp)
- command_setexposure(gspca_dev);
-
- if (setfps)
- command_setsensorfps(gspca_dev);
-
- if (setflicker)
- command_setflickerctrl(gspca_dev);
-}
-
-/*-----------------------------------------------------------------*/
-/* if flicker is switched off, this function switches it back on.It checks,
- however, that conditions are suitable before restarting it.
- This should only be called for firmware version 1.2.
-
- It also adjust the colour balance when an exposure step is detected - as
- long as flicker is running
-*/
-static void restart_flicker(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int cam_exposure, old_exp;
-
- if (!FIRMWARE_VERSION(1, 2))
- return;
-
- cam_exposure = atomic_read(&sd->cam_exposure);
-
- if (sd->params.flickerControl.flickerMode == 0 ||
- cam_exposure == 0)
- return;
-
- old_exp = sd->params.exposure.coarseExpLo +
- sd->params.exposure.coarseExpHi*256;
- /*
- see how far away camera exposure is from a valid
- flicker exposure value
- */
- cam_exposure %= sd->params.flickerControl.coarseJump;
- if (!sd->params.flickerControl.disabled &&
- cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
- /* Flicker control auto-disabled */
- sd->params.flickerControl.disabled = 1;
- }
-
- if (sd->params.flickerControl.disabled &&
- old_exp > sd->params.flickerControl.coarseJump +
- ROUND_UP_EXP_FOR_FLICKER) {
- /* exposure is now high enough to switch
- flicker control back on */
- set_flicker(gspca_dev, 1, 1);
- }
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
-
- sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
- reset_camera_params(gspca_dev);
-
- PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
- id->idVendor, id->idProduct);
-
- cam = &gspca_dev->cam;
- cam->cam_mode = mode;
- cam->nmodes = ARRAY_SIZE(mode);
-
- goto_low_power(gspca_dev);
- /* Check the firmware version. */
- sd->params.version.firmwareVersion = 0;
- get_version_information(gspca_dev);
- if (sd->params.version.firmwareVersion != 1) {
- PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)",
- sd->params.version.firmwareVersion);
- return -ENODEV;
- }
-
- /* A bug in firmware 1-02 limits gainMode to 2 */
- if (sd->params.version.firmwareRevision <= 2 &&
- sd->params.exposure.gainMode > 2) {
- sd->params.exposure.gainMode = 2;
- }
-
- /* set QX3 detected flag */
- sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
- sd->params.pnpID.product == 0x0001);
- return 0;
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int priv, ret;
-
- /* Start the camera in low power mode */
- if (goto_low_power(gspca_dev)) {
- if (sd->params.status.systemState != WARM_BOOT_STATE) {
- PDEBUG(D_ERR, "unexpected systemstate: %02x",
- sd->params.status.systemState);
- printstatus(&sd->params);
- return -ENODEV;
- }
-
- /* FIXME: this is just dirty trial and error */
- ret = goto_high_power(gspca_dev);
- if (ret)
- return ret;
-
- ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
- 0, 0, 0, 0);
- if (ret)
- return ret;
-
- ret = goto_low_power(gspca_dev);
- if (ret)
- return ret;
- }
-
- /* procedure described in developer's guide p3-28 */
-
- /* Check the firmware version. */
- sd->params.version.firmwareVersion = 0;
- get_version_information(gspca_dev);
-
- /* The fatal error checking should be done after
- * the camera powers up (developer's guide p 3-38) */
-
- /* Set streamState before transition to high power to avoid bug
- * in firmware 1-02 */
- ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus,
- STREAMSTATE, 0, STREAM_NOT_READY, 0);
- if (ret)
- return ret;
-
- /* GotoHiPower */
- ret = goto_high_power(gspca_dev);
- if (ret)
- return ret;
-
- /* Check the camera status */
- ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
- if (ret)
- return ret;
-
- if (sd->params.status.fatalError) {
- PDEBUG(D_ERR, "fatal_error: %04x, vp_status: %04x",
- sd->params.status.fatalError,
- sd->params.status.vpStatus);
- return -EIO;
- }
-
- /* VPVersion can't be retrieved before the camera is in HiPower,
- * so get it here instead of in get_version_information. */
- ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
- if (ret)
- return ret;
-
- /* Determine video mode settings */
- sd->params.streamStartLine = 120;
-
- priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
- if (priv & 0x01) { /* crop */
- sd->params.roi.colStart = 2;
- sd->params.roi.rowStart = 6;
- } else {
- sd->params.roi.colStart = 0;
- sd->params.roi.rowStart = 0;
- }
-
- if (priv & 0x02) { /* quarter */
- sd->params.format.videoSize = VIDEOSIZE_QCIF;
- sd->params.roi.colStart /= 2;
- sd->params.roi.rowStart /= 2;
- sd->params.streamStartLine /= 2;
- } else
- sd->params.format.videoSize = VIDEOSIZE_CIF;
-
- sd->params.roi.colEnd = sd->params.roi.colStart +
- (gspca_dev->width >> 3);
- sd->params.roi.rowEnd = sd->params.roi.rowStart +
- (gspca_dev->height >> 2);
-
- /* And now set the camera to a known state */
- ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode,
- CPIA_GRAB_CONTINEOUS, 0, 0, 0);
- if (ret)
- return ret;
- /* We start with compression disabled, as we need one uncompressed
- frame to handle later compressed frames */
- ret = do_command(gspca_dev, CPIA_COMMAND_SetCompression,
- CPIA_COMPRESSION_NONE,
- NO_DECIMATION, 0, 0);
- if (ret)
- return ret;
- ret = command_setcompressiontarget(gspca_dev);
- if (ret)
- return ret;
- ret = command_setcolourparams(gspca_dev);
- if (ret)
- return ret;
- ret = command_setformat(gspca_dev);
- if (ret)
- return ret;
- ret = command_setyuvtresh(gspca_dev);
- if (ret)
- return ret;
- ret = command_setecptiming(gspca_dev);
- if (ret)
- return ret;
- ret = command_setcompressionparams(gspca_dev);
- if (ret)
- return ret;
- ret = command_setexposure(gspca_dev);
- if (ret)
- return ret;
- ret = command_setcolourbalance(gspca_dev);
- if (ret)
- return ret;
- ret = command_setsensorfps(gspca_dev);
- if (ret)
- return ret;
- ret = command_setapcor(gspca_dev);
- if (ret)
- return ret;
- ret = command_setflickerctrl(gspca_dev);
- if (ret)
- return ret;
- ret = command_setvloffset(gspca_dev);
- if (ret)
- return ret;
-
- /* Start stream */
- ret = command_resume(gspca_dev);
- if (ret)
- return ret;
-
- /* Wait 6 frames before turning compression on for the sensor to get
- all settings and AEC/ACB to settle */
- sd->first_frame = 6;
- sd->exposure_status = EXPOSURE_NORMAL;
- sd->exposure_count = 0;
- atomic_set(&sd->cam_exposure, 0);
- atomic_set(&sd->fps, 0);
-
- return 0;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- command_pause(gspca_dev);
-
- /* save camera state for later open (developers guide ch 3.5.3) */
- save_camera_state(gspca_dev);
-
- /* GotoLoPower */
- goto_low_power(gspca_dev);
-
- /* Update the camera status */
- do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- /* If the last button state is pressed, release it now! */
- if (sd->params.qx3.button) {
- /* The camera latch will hold the pressed state until we reset
- the latch, so we do not reset sd->params.qx3.button now, to
- avoid a false keypress being reported the next sd_start */
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
- input_sync(gspca_dev->input_dev);
- }
-#endif
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- /* Start / Stop the camera to make sure we are talking to
- a supported camera, and to get some information from it
- to print. */
- ret = sd_start(gspca_dev);
- if (ret)
- return ret;
-
- /* Ensure the QX3 illuminators' states are restored upon resume,
- or disable the illuminator controls, if this isn't a QX3 */
- if (sd->params.qx3.qx3_detected)
- command_setlights(gspca_dev);
-
- sd_stopN(gspca_dev);
-
- PDEBUG(D_PROBE, "CPIA Version: %d.%02d (%d.%d)",
- sd->params.version.firmwareVersion,
- sd->params.version.firmwareRevision,
- sd->params.version.vcVersion,
- sd->params.version.vcRevision);
- PDEBUG(D_PROBE, "CPIA PnP-ID: %04x:%04x:%04x",
- sd->params.pnpID.vendor, sd->params.pnpID.product,
- sd->params.pnpID.deviceRevision);
- PDEBUG(D_PROBE, "VP-Version: %d.%d %04x",
- sd->params.vpVersion.vpVersion,
- sd->params.vpVersion.vpRevision,
- sd->params.vpVersion.cameraHeadID);
-
- return 0;
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data,
- int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* Check for SOF */
- if (len >= 64 &&
- data[0] == MAGIC_0 && data[1] == MAGIC_1 &&
- data[16] == sd->params.format.videoSize &&
- data[17] == sd->params.format.subSample &&
- data[18] == sd->params.format.yuvOrder &&
- data[24] == sd->params.roi.colStart &&
- data[25] == sd->params.roi.colEnd &&
- data[26] == sd->params.roi.rowStart &&
- data[27] == sd->params.roi.rowEnd) {
- u8 *image;
-
- atomic_set(&sd->cam_exposure, data[39] * 2);
- atomic_set(&sd->fps, data[41]);
-
- /* Check for proper EOF for last frame */
- image = gspca_dev->image;
- if (image != NULL &&
- gspca_dev->image_len > 4 &&
- image[gspca_dev->image_len - 4] == 0xff &&
- image[gspca_dev->image_len - 3] == 0xff &&
- image[gspca_dev->image_len - 2] == 0xff &&
- image[gspca_dev->image_len - 1] == 0xff)
- gspca_frame_add(gspca_dev, LAST_PACKET,
- NULL, 0);
-
- gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
- return;
- }
-
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-static void sd_dq_callback(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* Set the normal compression settings once we have captured a
- few uncompressed frames (and AEC has hopefully settled) */
- if (sd->first_frame) {
- sd->first_frame--;
- if (sd->first_frame == 0)
- command_setcompression(gspca_dev);
- }
-
- /* Switch flicker control back on if it got turned off */
- restart_flicker(gspca_dev);
-
- /* If AEC is enabled, monitor the exposure and
- adjust the sensor frame rate if needed */
- if (sd->params.exposure.expMode == 2)
- monitor_exposure(gspca_dev);
-
- /* Update our knowledge of the camera state */
- do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
- do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- sd->params.colourParams.brightness = ctrl->val;
- sd->params.flickerControl.allowableOverExposure =
- find_over_exposure(sd->params.colourParams.brightness);
- gspca_dev->usb_err = command_setcolourparams(gspca_dev);
- if (!gspca_dev->usb_err)
- gspca_dev->usb_err = command_setflickerctrl(gspca_dev);
- break;
- case V4L2_CID_CONTRAST:
- sd->params.colourParams.contrast = ctrl->val;
- gspca_dev->usb_err = command_setcolourparams(gspca_dev);
- break;
- case V4L2_CID_SATURATION:
- sd->params.colourParams.saturation = ctrl->val;
- gspca_dev->usb_err = command_setcolourparams(gspca_dev);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY:
- sd->mainsFreq = ctrl->val == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
- sd->params.flickerControl.coarseJump =
- flicker_jumps[sd->mainsFreq]
- [sd->params.sensorFps.baserate]
- [sd->params.sensorFps.divisor];
-
- gspca_dev->usb_err = set_flicker(gspca_dev,
- ctrl->val != V4L2_CID_POWER_LINE_FREQUENCY_DISABLED,
- gspca_dev->streaming);
- break;
- case V4L2_CID_ILLUMINATORS_1:
- sd->params.qx3.bottomlight = ctrl->val;
- gspca_dev->usb_err = command_setlights(gspca_dev);
- break;
- case V4L2_CID_ILLUMINATORS_2:
- sd->params.qx3.toplight = ctrl->val;
- gspca_dev->usb_err = command_setlights(gspca_dev);
- break;
- case CPIA1_CID_COMP_TARGET:
- sd->params.compressionTarget.frTargeting = ctrl->val;
- gspca_dev->usb_err = command_setcompressiontarget(gspca_dev);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
- static const char * const comp_target_menu[] = {
- "Quality",
- "Framerate",
- NULL
- };
- static const struct v4l2_ctrl_config comp_target = {
- .ops = &sd_ctrl_ops,
- .id = CPIA1_CID_COMP_TARGET,
- .type = V4L2_CTRL_TYPE_MENU,
- .name = "Compression Target",
- .qmenu = comp_target_menu,
- .max = 1,
- .def = COMP_TARGET_DEF,
- };
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 7);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 100, 1, BRIGHTNESS_DEF);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 96, 8, CONTRAST_DEF);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0, 100, 1, SATURATION_DEF);
- sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
- V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
- FREQ_DEF);
- if (sd->params.qx3.qx3_detected) {
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_ILLUMINATORS_1, 0, 1, 1,
- ILLUMINATORS_1_DEF);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_ILLUMINATORS_2, 0, 1, 1,
- ILLUMINATORS_2_DEF);
- }
- v4l2_ctrl_new_custom(hdl, &comp_target, NULL);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .dq_callback = sd_dq_callback,
- .pkt_scan = sd_pkt_scan,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .other_input = 1,
-#endif
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x0553, 0x0002)},
- {USB_DEVICE(0x0813, 0x0001)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
deleted file mode 100644
index 38f68e11c3a..00000000000
--- a/drivers/media/video/gspca/etoms.c
+++ /dev/null
@@ -1,799 +0,0 @@
-/*
- * Etoms Et61x151 GPL Linux driver by Michel Xhaard (09/09/2004)
- *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "etoms"
-
-#include "gspca.h"
-
-MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
-MODULE_DESCRIPTION("Etoms USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- unsigned char autogain;
-
- char sensor;
-#define SENSOR_PAS106 0
-#define SENSOR_TAS5130CXX 1
- signed char ag_cnt;
-#define AG_CNT_START 13
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
-/* {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0}, */
-};
-
-static const struct v4l2_pix_format sif_mode[] = {
- {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-#define ETOMS_ALT_SIZE_1000 12
-
-#define ET_GPIO_DIR_CTRL 0x04 /* Control IO bit[0..5] (0 in 1 out) */
-#define ET_GPIO_OUT 0x05 /* Only IO data */
-#define ET_GPIO_IN 0x06 /* Read Only IO data */
-#define ET_RESET_ALL 0x03
-#define ET_ClCK 0x01
-#define ET_CTRL 0x02 /* enable i2c OutClck Powerdown mode */
-
-#define ET_COMP 0x12 /* Compression register */
-#define ET_MAXQt 0x13
-#define ET_MINQt 0x14
-#define ET_COMP_VAL0 0x02
-#define ET_COMP_VAL1 0x03
-
-#define ET_REG1d 0x1d
-#define ET_REG1e 0x1e
-#define ET_REG1f 0x1f
-#define ET_REG20 0x20
-#define ET_REG21 0x21
-#define ET_REG22 0x22
-#define ET_REG23 0x23
-#define ET_REG24 0x24
-#define ET_REG25 0x25
-/* base registers for luma calculation */
-#define ET_LUMA_CENTER 0x39
-
-#define ET_G_RED 0x4d
-#define ET_G_GREEN1 0x4e
-#define ET_G_BLUE 0x4f
-#define ET_G_GREEN2 0x50
-#define ET_G_GR_H 0x51
-#define ET_G_GB_H 0x52
-
-#define ET_O_RED 0x34
-#define ET_O_GREEN1 0x35
-#define ET_O_BLUE 0x36
-#define ET_O_GREEN2 0x37
-
-#define ET_SYNCHRO 0x68
-#define ET_STARTX 0x69
-#define ET_STARTY 0x6a
-#define ET_WIDTH_LOW 0x6b
-#define ET_HEIGTH_LOW 0x6c
-#define ET_W_H_HEIGTH 0x6d
-
-#define ET_REG6e 0x6e /* OBW */
-#define ET_REG6f 0x6f /* OBW */
-#define ET_REG70 0x70 /* OBW_AWB */
-#define ET_REG71 0x71 /* OBW_AWB */
-#define ET_REG72 0x72 /* OBW_AWB */
-#define ET_REG73 0x73 /* Clkdelay ns */
-#define ET_REG74 0x74 /* test pattern */
-#define ET_REG75 0x75 /* test pattern */
-
-#define ET_I2C_CLK 0x8c
-#define ET_PXL_CLK 0x60
-
-#define ET_I2C_BASE 0x89
-#define ET_I2C_COUNT 0x8a
-#define ET_I2C_PREFETCH 0x8b
-#define ET_I2C_REG 0x88
-#define ET_I2C_DATA7 0x87
-#define ET_I2C_DATA6 0x86
-#define ET_I2C_DATA5 0x85
-#define ET_I2C_DATA4 0x84
-#define ET_I2C_DATA3 0x83
-#define ET_I2C_DATA2 0x82
-#define ET_I2C_DATA1 0x81
-#define ET_I2C_DATA0 0x80
-
-#define PAS106_REG2 0x02 /* pxlClk = systemClk/(reg2) */
-#define PAS106_REG3 0x03 /* line/frame H [11..4] */
-#define PAS106_REG4 0x04 /* line/frame L [3..0] */
-#define PAS106_REG5 0x05 /* exposure time line offset(default 5) */
-#define PAS106_REG6 0x06 /* exposure time pixel offset(default 6) */
-#define PAS106_REG7 0x07 /* signbit Dac (default 0) */
-#define PAS106_REG9 0x09
-#define PAS106_REG0e 0x0e /* global gain [4..0](default 0x0e) */
-#define PAS106_REG13 0x13 /* end i2c write */
-
-static const __u8 GainRGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
-
-static const __u8 I2c2[] = { 0x08, 0x08, 0x08, 0x08, 0x0d };
-
-static const __u8 I2c3[] = { 0x12, 0x05 };
-
-static const __u8 I2c4[] = { 0x41, 0x08 };
-
-/* read 'len' bytes to gspca_dev->usb_buf */
-static void reg_r(struct gspca_dev *gspca_dev,
- __u16 index,
- __u16 len)
-{
- struct usb_device *dev = gspca_dev->dev;
-
-#ifdef GSPCA_DEBUG
- if (len > USB_BUF_SZ) {
- pr_err("reg_r: buffer overflow\n");
- return;
- }
-#endif
- usb_control_msg(dev,
- usb_rcvctrlpipe(dev, 0),
- 0,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- 0,
- index, gspca_dev->usb_buf, len, 500);
- PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
- index, gspca_dev->usb_buf[0]);
-}
-
-static void reg_w_val(struct gspca_dev *gspca_dev,
- __u16 index,
- __u8 val)
-{
- struct usb_device *dev = gspca_dev->dev;
-
- gspca_dev->usb_buf[0] = val;
- usb_control_msg(dev,
- usb_sndctrlpipe(dev, 0),
- 0,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- 0,
- index, gspca_dev->usb_buf, 1, 500);
-}
-
-static void reg_w(struct gspca_dev *gspca_dev,
- __u16 index,
- const __u8 *buffer,
- __u16 len)
-{
- struct usb_device *dev = gspca_dev->dev;
-
-#ifdef GSPCA_DEBUG
- if (len > USB_BUF_SZ) {
- pr_err("reg_w: buffer overflow\n");
- return;
- }
- PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
-#endif
- memcpy(gspca_dev->usb_buf, buffer, len);
- usb_control_msg(dev,
- usb_sndctrlpipe(dev, 0),
- 0,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- 0, index, gspca_dev->usb_buf, len, 500);
-}
-
-static int i2c_w(struct gspca_dev *gspca_dev,
- __u8 reg,
- const __u8 *buffer,
- int len, __u8 mode)
-{
- /* buffer should be [D0..D7] */
- __u8 ptchcount;
-
- /* set the base address */
- reg_w_val(gspca_dev, ET_I2C_BASE, 0x40);
- /* sensor base for the pas106 */
- /* set count and prefetch */
- ptchcount = ((len & 0x07) << 4) | (mode & 0x03);
- reg_w_val(gspca_dev, ET_I2C_COUNT, ptchcount);
- /* set the register base */
- reg_w_val(gspca_dev, ET_I2C_REG, reg);
- while (--len >= 0)
- reg_w_val(gspca_dev, ET_I2C_DATA0 + len, buffer[len]);
- return 0;
-}
-
-static int i2c_r(struct gspca_dev *gspca_dev,
- __u8 reg)
-{
- /* set the base address */
- reg_w_val(gspca_dev, ET_I2C_BASE, 0x40);
- /* sensor base for the pas106 */
- /* set count and prefetch (cnd: 4 bits - mode: 4 bits) */
- reg_w_val(gspca_dev, ET_I2C_COUNT, 0x11);
- reg_w_val(gspca_dev, ET_I2C_REG, reg); /* set the register base */
- reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x02); /* prefetch */
- reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x00);
- reg_r(gspca_dev, ET_I2C_DATA0, 1); /* read one byte */
- return 0;
-}
-
-static int Et_WaitStatus(struct gspca_dev *gspca_dev)
-{
- int retry = 10;
-
- while (retry--) {
- reg_r(gspca_dev, ET_ClCK, 1);
- if (gspca_dev->usb_buf[0] != 0)
- return 1;
- }
- return 0;
-}
-
-static int et_video(struct gspca_dev *gspca_dev,
- int on)
-{
- int ret;
-
- reg_w_val(gspca_dev, ET_GPIO_OUT,
- on ? 0x10 /* startvideo - set Bit5 */
- : 0); /* stopvideo */
- ret = Et_WaitStatus(gspca_dev);
- if (ret != 0)
- PDEBUG(D_ERR, "timeout video on/off");
- return ret;
-}
-
-static void Et_init2(struct gspca_dev *gspca_dev)
-{
- __u8 value;
- static const __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 };
-
- PDEBUG(D_STREAM, "Open Init2 ET");
- reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 0x2f);
- reg_w_val(gspca_dev, ET_GPIO_OUT, 0x10);
- reg_r(gspca_dev, ET_GPIO_IN, 1);
- reg_w_val(gspca_dev, ET_ClCK, 0x14); /* 0x14 // 0x16 enabled pattern */
- reg_w_val(gspca_dev, ET_CTRL, 0x1b);
-
- /* compression et subsampling */
- if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
- value = ET_COMP_VAL1; /* 320 */
- else
- value = ET_COMP_VAL0; /* 640 */
- reg_w_val(gspca_dev, ET_COMP, value);
- reg_w_val(gspca_dev, ET_MAXQt, 0x1f);
- reg_w_val(gspca_dev, ET_MINQt, 0x04);
- /* undocumented registers */
- reg_w_val(gspca_dev, ET_REG1d, 0xff);
- reg_w_val(gspca_dev, ET_REG1e, 0xff);
- reg_w_val(gspca_dev, ET_REG1f, 0xff);
- reg_w_val(gspca_dev, ET_REG20, 0x35);
- reg_w_val(gspca_dev, ET_REG21, 0x01);
- reg_w_val(gspca_dev, ET_REG22, 0x00);
- reg_w_val(gspca_dev, ET_REG23, 0xff);
- reg_w_val(gspca_dev, ET_REG24, 0xff);
- reg_w_val(gspca_dev, ET_REG25, 0x0f);
- /* colors setting */
- reg_w_val(gspca_dev, 0x30, 0x11); /* 0x30 */
- reg_w_val(gspca_dev, 0x31, 0x40);
- reg_w_val(gspca_dev, 0x32, 0x00);
- reg_w_val(gspca_dev, ET_O_RED, 0x00); /* 0x34 */
- reg_w_val(gspca_dev, ET_O_GREEN1, 0x00);
- reg_w_val(gspca_dev, ET_O_BLUE, 0x00);
- reg_w_val(gspca_dev, ET_O_GREEN2, 0x00);
- /*************/
- reg_w_val(gspca_dev, ET_G_RED, 0x80); /* 0x4d */
- reg_w_val(gspca_dev, ET_G_GREEN1, 0x80);
- reg_w_val(gspca_dev, ET_G_BLUE, 0x80);
- reg_w_val(gspca_dev, ET_G_GREEN2, 0x80);
- reg_w_val(gspca_dev, ET_G_GR_H, 0x00);
- reg_w_val(gspca_dev, ET_G_GB_H, 0x00); /* 0x52 */
- /* Window control registers */
- reg_w_val(gspca_dev, 0x61, 0x80); /* use cmc_out */
- reg_w_val(gspca_dev, 0x62, 0x02);
- reg_w_val(gspca_dev, 0x63, 0x03);
- reg_w_val(gspca_dev, 0x64, 0x14);
- reg_w_val(gspca_dev, 0x65, 0x0e);
- reg_w_val(gspca_dev, 0x66, 0x02);
- reg_w_val(gspca_dev, 0x67, 0x02);
-
- /**************************************/
- reg_w_val(gspca_dev, ET_SYNCHRO, 0x8f); /* 0x68 */
- reg_w_val(gspca_dev, ET_STARTX, 0x69); /* 0x6a //0x69 */
- reg_w_val(gspca_dev, ET_STARTY, 0x0d); /* 0x0d //0x0c */
- reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x80);
- reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0xe0);
- reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x60); /* 6d */
- reg_w_val(gspca_dev, ET_REG6e, 0x86);
- reg_w_val(gspca_dev, ET_REG6f, 0x01);
- reg_w_val(gspca_dev, ET_REG70, 0x26);
- reg_w_val(gspca_dev, ET_REG71, 0x7a);
- reg_w_val(gspca_dev, ET_REG72, 0x01);
- /* Clock Pattern registers ***************** */
- reg_w_val(gspca_dev, ET_REG73, 0x00);
- reg_w_val(gspca_dev, ET_REG74, 0x18); /* 0x28 */
- reg_w_val(gspca_dev, ET_REG75, 0x0f); /* 0x01 */
- /**********************************************/
- reg_w_val(gspca_dev, 0x8a, 0x20);
- reg_w_val(gspca_dev, 0x8d, 0x0f);
- reg_w_val(gspca_dev, 0x8e, 0x08);
- /**************************************/
- reg_w_val(gspca_dev, 0x03, 0x08);
- reg_w_val(gspca_dev, ET_PXL_CLK, 0x03);
- reg_w_val(gspca_dev, 0x81, 0xff);
- reg_w_val(gspca_dev, 0x80, 0x00);
- reg_w_val(gspca_dev, 0x81, 0xff);
- reg_w_val(gspca_dev, 0x80, 0x20);
- reg_w_val(gspca_dev, 0x03, 0x01);
- reg_w_val(gspca_dev, 0x03, 0x00);
- reg_w_val(gspca_dev, 0x03, 0x08);
- /********************************************/
-
-/* reg_r(gspca_dev, ET_I2C_BASE, 1);
- always 0x40 as the pas106 ??? */
- /* set the sensor */
- if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
- value = 0x04; /* 320 */
- else /* 640 */
- value = 0x1e; /* 0x17 * setting PixelClock
- * 0x03 mean 24/(3+1) = 6 Mhz
- * 0x05 -> 24/(5+1) = 4 Mhz
- * 0x0b -> 24/(11+1) = 2 Mhz
- * 0x17 -> 24/(23+1) = 1 Mhz
- */
- reg_w_val(gspca_dev, ET_PXL_CLK, value);
- /* now set by fifo the FormatLine setting */
- reg_w(gspca_dev, 0x62, FormLine, 6);
-
- /* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */
- reg_w_val(gspca_dev, 0x81, 0x47); /* 0x47; */
- reg_w_val(gspca_dev, 0x80, 0x40); /* 0x40; */
- /* Pedro change */
- /* Brightness change Brith+ decrease value */
- /* Brigth- increase value */
- /* original value = 0x70; */
- reg_w_val(gspca_dev, 0x81, 0x30); /* 0x20; - set brightness */
- reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
-{
- int i;
-
- for (i = 0; i < 4; i++)
- reg_w_val(gspca_dev, ET_O_RED + i, val);
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
-{
- __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
-
- memset(RGBG, val, sizeof(RGBG) - 2);
- reg_w(gspca_dev, ET_G_RED, RGBG, 6);
-}
-
-static void setcolors(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- __u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d };
- __u8 i2cflags = 0x01;
- /* __u8 green = 0; */
-
- I2cc[3] = val; /* red */
- I2cc[0] = 15 - val; /* blue */
- /* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */
- /* I2cc[1] = I2cc[2] = green; */
- if (sd->sensor == SENSOR_PAS106) {
- i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3);
- i2c_w(gspca_dev, PAS106_REG9, I2cc, sizeof I2cc, 1);
- }
-/* PDEBUG(D_CONF , "Etoms red %d blue %d green %d",
- I2cc[3], I2cc[0], green); */
-}
-
-static s32 getcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_PAS106) {
-/* i2c_r(gspca_dev, PAS106_REG9); * blue */
- i2c_r(gspca_dev, PAS106_REG9 + 3); /* red */
- return gspca_dev->usb_buf[0] & 0x0f;
- }
- return 0;
-}
-
-static void setautogain(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->autogain)
- sd->ag_cnt = AG_CNT_START;
- else
- sd->ag_cnt = -1;
-}
-
-static void Et_init1(struct gspca_dev *gspca_dev)
-{
- __u8 value;
-/* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0x22, 0xac, 0x00, 0x01, 0x00}; */
- __u8 I2c0[] = { 0x0a, 0x12, 0x05, 0x6d, 0xcd, 0x00, 0x01, 0x00 };
- /* try 1/120 0x6d 0xcd 0x40 */
-/* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0xfe, 0xfe, 0xc0, 0x01, 0x00};
- * 1/60000 hmm ?? */
-
- PDEBUG(D_STREAM, "Open Init1 ET");
- reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 7);
- reg_r(gspca_dev, ET_GPIO_IN, 1);
- reg_w_val(gspca_dev, ET_RESET_ALL, 1);
- reg_w_val(gspca_dev, ET_RESET_ALL, 0);
- reg_w_val(gspca_dev, ET_ClCK, 0x10);
- reg_w_val(gspca_dev, ET_CTRL, 0x19);
- /* compression et subsampling */
- if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
- value = ET_COMP_VAL1;
- else
- value = ET_COMP_VAL0;
- PDEBUG(D_STREAM, "Open mode %d Compression %d",
- gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv,
- value);
- reg_w_val(gspca_dev, ET_COMP, value);
- reg_w_val(gspca_dev, ET_MAXQt, 0x1d);
- reg_w_val(gspca_dev, ET_MINQt, 0x02);
- /* undocumented registers */
- reg_w_val(gspca_dev, ET_REG1d, 0xff);
- reg_w_val(gspca_dev, ET_REG1e, 0xff);
- reg_w_val(gspca_dev, ET_REG1f, 0xff);
- reg_w_val(gspca_dev, ET_REG20, 0x35);
- reg_w_val(gspca_dev, ET_REG21, 0x01);
- reg_w_val(gspca_dev, ET_REG22, 0x00);
- reg_w_val(gspca_dev, ET_REG23, 0xf7);
- reg_w_val(gspca_dev, ET_REG24, 0xff);
- reg_w_val(gspca_dev, ET_REG25, 0x07);
- /* colors setting */
- reg_w_val(gspca_dev, ET_G_RED, 0x80);
- reg_w_val(gspca_dev, ET_G_GREEN1, 0x80);
- reg_w_val(gspca_dev, ET_G_BLUE, 0x80);
- reg_w_val(gspca_dev, ET_G_GREEN2, 0x80);
- reg_w_val(gspca_dev, ET_G_GR_H, 0x00);
- reg_w_val(gspca_dev, ET_G_GB_H, 0x00);
- /* Window control registers */
- reg_w_val(gspca_dev, ET_SYNCHRO, 0xf0);
- reg_w_val(gspca_dev, ET_STARTX, 0x56); /* 0x56 */
- reg_w_val(gspca_dev, ET_STARTY, 0x05); /* 0x04 */
- reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x60);
- reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0x20);
- reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x50);
- reg_w_val(gspca_dev, ET_REG6e, 0x86);
- reg_w_val(gspca_dev, ET_REG6f, 0x01);
- reg_w_val(gspca_dev, ET_REG70, 0x86);
- reg_w_val(gspca_dev, ET_REG71, 0x14);
- reg_w_val(gspca_dev, ET_REG72, 0x00);
- /* Clock Pattern registers */
- reg_w_val(gspca_dev, ET_REG73, 0x00);
- reg_w_val(gspca_dev, ET_REG74, 0x00);
- reg_w_val(gspca_dev, ET_REG75, 0x0a);
- reg_w_val(gspca_dev, ET_I2C_CLK, 0x04);
- reg_w_val(gspca_dev, ET_PXL_CLK, 0x01);
- /* set the sensor */
- if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
- I2c0[0] = 0x06;
- i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1);
- i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1);
- value = 0x06;
- i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1);
- i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1);
- /* value = 0x1f; */
- value = 0x04;
- i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1);
- } else {
- I2c0[0] = 0x0a;
-
- i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1);
- i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1);
- value = 0x0a;
- i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1);
- i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1);
- value = 0x04;
- /* value = 0x10; */
- i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1);
- /* bit 2 enable bit 1:2 select 0 1 2 3
- value = 0x07; * curve 0 *
- i2c_w(gspca_dev, PAS106_REG0f, &value, 1, 1);
- */
- }
-
-/* value = 0x01; */
-/* value = 0x22; */
-/* i2c_w(gspca_dev, PAS106_REG5, &value, 1, 1); */
- /* magnetude and sign bit for DAC */
- i2c_w(gspca_dev, PAS106_REG7, I2c4, sizeof I2c4, 1);
- /* now set by fifo the whole colors setting */
- reg_w(gspca_dev, ET_G_RED, GainRGBG, 6);
- setcolors(gspca_dev, getcolors(gspca_dev));
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
-
- cam = &gspca_dev->cam;
- sd->sensor = id->driver_info;
- if (sd->sensor == SENSOR_PAS106) {
- cam->cam_mode = sif_mode;
- cam->nmodes = ARRAY_SIZE(sif_mode);
- } else {
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- }
- sd->ag_cnt = -1;
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_PAS106)
- Et_init1(gspca_dev);
- else
- Et_init2(gspca_dev);
- reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
- et_video(gspca_dev, 0); /* video off */
- return 0;
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_PAS106)
- Et_init1(gspca_dev);
- else
- Et_init2(gspca_dev);
-
- setautogain(gspca_dev);
-
- reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
- et_video(gspca_dev, 1); /* video on */
- return 0;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- et_video(gspca_dev, 0); /* video off */
-}
-
-static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_PAS106) {
- i2c_r(gspca_dev, PAS106_REG0e);
- PDEBUG(D_CONF, "Etoms gain G %d", gspca_dev->usb_buf[0]);
- return gspca_dev->usb_buf[0];
- }
- return 0x1f;
-}
-
-static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_PAS106) {
- __u8 i2cflags = 0x01;
-
- i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3);
- i2c_w(gspca_dev, PAS106_REG0e, &gain, 1, 1);
- }
-}
-
-#define BLIMIT(bright) \
- (u8)((bright > 0x1f) ? 0x1f : ((bright < 4) ? 3 : bright))
-#define LIMIT(color) \
- (u8)((color > 0xff) ? 0xff : ((color < 0) ? 0 : color))
-
-static void do_autogain(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- __u8 luma;
- __u8 luma_mean = 128;
- __u8 luma_delta = 20;
- __u8 spring = 4;
- int Gbright;
- __u8 r, g, b;
-
- if (sd->ag_cnt < 0)
- return;
- if (--sd->ag_cnt >= 0)
- return;
- sd->ag_cnt = AG_CNT_START;
-
- Gbright = Et_getgainG(gspca_dev);
- reg_r(gspca_dev, ET_LUMA_CENTER, 4);
- g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1;
- r = gspca_dev->usb_buf[1];
- b = gspca_dev->usb_buf[2];
- r = ((r << 8) - (r << 4) - (r << 3)) >> 10;
- b = ((b << 7) >> 10);
- g = ((g << 9) + (g << 7) + (g << 5)) >> 10;
- luma = LIMIT(r + g + b);
- PDEBUG(D_FRAM, "Etoms luma G %d", luma);
- if (luma < luma_mean - luma_delta || luma > luma_mean + luma_delta) {
- Gbright += (luma_mean - luma) >> spring;
- Gbright = BLIMIT(Gbright);
- PDEBUG(D_FRAM, "Etoms Gbright %d", Gbright);
- Et_setgainG(gspca_dev, (__u8) Gbright);
- }
-}
-
-#undef BLIMIT
-#undef LIMIT
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- int seqframe;
-
- seqframe = data[0] & 0x3f;
- len = (int) (((data[0] & 0xc0) << 2) | data[1]);
- if (seqframe == 0x3f) {
- PDEBUG(D_FRAM,
- "header packet found datalength %d !!", len);
- PDEBUG(D_FRAM, "G %d R %d G %d B %d",
- data[2], data[3], data[4], data[5]);
- data += 30;
- /* don't change datalength as the chips provided it */
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
- gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
- return;
- }
- if (len) {
- data += 8;
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
- } else { /* Drop Packet */
- gspca_dev->last_packet_type = DISCARD_PACKET;
- }
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- setcolors(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_AUTOGAIN:
- sd->autogain = ctrl->val;
- setautogain(gspca_dev);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 4);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 1, 127, 1, 63);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 127);
- if (sd->sensor == SENSOR_PAS106)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0, 15, 1, 7);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
- .dq_callback = do_autogain,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
-#if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE
- {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
-#endif
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
deleted file mode 100644
index c8f2201cc35..00000000000
--- a/drivers/media/video/gspca/finepix.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Fujifilm Finepix subdriver
- *
- * Copyright (C) 2008 Frank Zago
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "finepix"
-
-#include "gspca.h"
-
-MODULE_AUTHOR("Frank Zago <frank@zago.net>");
-MODULE_DESCRIPTION("Fujifilm FinePix USB V4L2 driver");
-MODULE_LICENSE("GPL");
-
-/* Default timeout, in ms */
-#define FPIX_TIMEOUT 250
-
-/* Maximum transfer size to use. The windows driver reads by chunks of
- * 0x2000 bytes, so do the same. Note: reading more seems to work
- * too. */
-#define FPIX_MAX_TRANSFER 0x2000
-
-/* Structure to hold all of our device specific stuff */
-struct usb_fpix {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- struct work_struct work_struct;
- struct workqueue_struct *work_thread;
-};
-
-/* Delay after which claim the next frame. If the delay is too small,
- * the camera will return old frames. On the 4800Z, 20ms is bad, 25ms
- * will fail every 4 or 5 frames, but 30ms is perfect. On the A210,
- * 30ms is bad while 35ms is perfect. */
-#define NEXT_FRAME_DELAY 35
-
-/* These cameras only support 320x200. */
-static const struct v4l2_pix_format fpix_mode[1] = {
- { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0}
-};
-
-/* send a command to the webcam */
-static int command(struct gspca_dev *gspca_dev,
- int order) /* 0: reset, 1: frame request */
-{
- static u8 order_values[2][12] = {
- {0xc6, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0}, /* reset */
- {0xd3, 0, 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0}, /* fr req */
- };
-
- memcpy(gspca_dev->usb_buf, order_values[order], 12);
- return usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- USB_REQ_GET_STATUS,
- USB_DIR_OUT | USB_TYPE_CLASS |
- USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
- 12, FPIX_TIMEOUT);
-}
-
-/* workqueue */
-static void dostream(struct work_struct *work)
-{
- struct usb_fpix *dev = container_of(work, struct usb_fpix, work_struct);
- struct gspca_dev *gspca_dev = &dev->gspca_dev;
- struct urb *urb = gspca_dev->urb[0];
- u8 *data = urb->transfer_buffer;
- int ret = 0;
- int len;
-
- /* synchronize with the main driver */
- mutex_lock(&gspca_dev->usb_lock);
- mutex_unlock(&gspca_dev->usb_lock);
- PDEBUG(D_STREAM, "dostream started");
-
- /* loop reading a frame */
-again:
- while (gspca_dev->dev && gspca_dev->streaming) {
-#ifdef CONFIG_PM
- if (gspca_dev->frozen)
- break;
-#endif
-
- /* request a frame */
- mutex_lock(&gspca_dev->usb_lock);
- ret = command(gspca_dev, 1);
- mutex_unlock(&gspca_dev->usb_lock);
- if (ret < 0)
- break;
-#ifdef CONFIG_PM
- if (gspca_dev->frozen)
- break;
-#endif
- if (!gspca_dev->dev || !gspca_dev->streaming)
- break;
-
- /* the frame comes in parts */
- for (;;) {
- ret = usb_bulk_msg(gspca_dev->dev,
- urb->pipe,
- data,
- FPIX_MAX_TRANSFER,
- &len, FPIX_TIMEOUT);
- if (ret < 0) {
- /* Most of the time we get a timeout
- * error. Just restart. */
- goto again;
- }
-#ifdef CONFIG_PM
- if (gspca_dev->frozen)
- goto out;
-#endif
- if (!gspca_dev->dev || !gspca_dev->streaming)
- goto out;
- if (len < FPIX_MAX_TRANSFER ||
- (data[len - 2] == 0xff &&
- data[len - 1] == 0xd9)) {
-
- /* If the result is less than what was asked
- * for, then it's the end of the
- * frame. Sometimes the jpeg is not complete,
- * but there's nothing we can do. We also end
- * here if the the jpeg ends right at the end
- * of the frame. */
- gspca_frame_add(gspca_dev, LAST_PACKET,
- data, len);
- break;
- }
-
- /* got a partial image */
- gspca_frame_add(gspca_dev,
- gspca_dev->last_packet_type
- == LAST_PACKET
- ? FIRST_PACKET : INTER_PACKET,
- data, len);
- }
-
- /* We must wait before trying reading the next
- * frame. If we don't, or if the delay is too short,
- * the camera will disconnect. */
- msleep(NEXT_FRAME_DELAY);
- }
-
-out:
- PDEBUG(D_STREAM, "dostream stopped");
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
- struct cam *cam = &gspca_dev->cam;
-
- cam->cam_mode = fpix_mode;
- cam->nmodes = 1;
- cam->bulk = 1;
- cam->bulk_size = FPIX_MAX_TRANSFER;
-
- INIT_WORK(&dev->work_struct, dostream);
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- return 0;
-}
-
-/* start the camera */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
- int ret, len;
-
- /* Init the device */
- ret = command(gspca_dev, 0);
- if (ret < 0) {
- pr_err("init failed %d\n", ret);
- return ret;
- }
-
- /* Read the result of the command. Ignore the result, for it
- * varies with the device. */
- ret = usb_bulk_msg(gspca_dev->dev,
- gspca_dev->urb[0]->pipe,
- gspca_dev->urb[0]->transfer_buffer,
- FPIX_MAX_TRANSFER, &len,
- FPIX_TIMEOUT);
- if (ret < 0) {
- pr_err("usb_bulk_msg failed %d\n", ret);
- return ret;
- }
-
- /* Request a frame, but don't read it */
- ret = command(gspca_dev, 1);
- if (ret < 0) {
- pr_err("frame request failed %d\n", ret);
- return ret;
- }
-
- /* Again, reset bulk in endpoint */
- usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
-
- /* Start the workqueue function to do the streaming */
- dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
- queue_work(dev->work_thread, &dev->work_struct);
-
- return 0;
-}
-
-/* called on streamoff with alt==0 and on disconnect */
-/* the usb_lock is held at entry - restore on exit */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
- /* wait for the work queue to terminate */
- mutex_unlock(&gspca_dev->usb_lock);
- destroy_workqueue(dev->work_thread);
- mutex_lock(&gspca_dev->usb_lock);
- dev->work_thread = NULL;
-}
-
-/* Table of supported USB devices */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x04cb, 0x0104)},
- {USB_DEVICE(0x04cb, 0x0109)},
- {USB_DEVICE(0x04cb, 0x010b)},
- {USB_DEVICE(0x04cb, 0x010f)},
- {USB_DEVICE(0x04cb, 0x0111)},
- {USB_DEVICE(0x04cb, 0x0113)},
- {USB_DEVICE(0x04cb, 0x0115)},
- {USB_DEVICE(0x04cb, 0x0117)},
- {USB_DEVICE(0x04cb, 0x0119)},
- {USB_DEVICE(0x04cb, 0x011b)},
- {USB_DEVICE(0x04cb, 0x011d)},
- {USB_DEVICE(0x04cb, 0x0121)},
- {USB_DEVICE(0x04cb, 0x0123)},
- {USB_DEVICE(0x04cb, 0x0125)},
- {USB_DEVICE(0x04cb, 0x0127)},
- {USB_DEVICE(0x04cb, 0x0129)},
- {USB_DEVICE(0x04cb, 0x012b)},
- {USB_DEVICE(0x04cb, 0x012d)},
- {USB_DEVICE(0x04cb, 0x012f)},
- {USB_DEVICE(0x04cb, 0x0131)},
- {USB_DEVICE(0x04cb, 0x013b)},
- {USB_DEVICE(0x04cb, 0x013d)},
- {USB_DEVICE(0x04cb, 0x013f)},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .start = sd_start,
- .stop0 = sd_stop0,
-};
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id,
- &sd_desc,
- sizeof(struct usb_fpix),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/gl860/Kconfig b/drivers/media/video/gspca/gl860/Kconfig
deleted file mode 100644
index 22772f53ec7..00000000000
--- a/drivers/media/video/gspca/gl860/Kconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-config USB_GL860
- tristate "GL860 USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the GL860 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_gl860.
diff --git a/drivers/media/video/gspca/gl860/Makefile b/drivers/media/video/gspca/gl860/Makefile
deleted file mode 100644
index 773ea342656..00000000000
--- a/drivers/media/video/gspca/gl860/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-obj-$(CONFIG_USB_GL860) += gspca_gl860.o
-
-gspca_gl860-objs := gl860.o \
- gl860-mi1320.o \
- gl860-ov2640.o \
- gl860-ov9655.o \
- gl860-mi2020.o
-
-ccflags-y += -I$(srctree)/drivers/media/video/gspca
-
diff --git a/drivers/media/video/gspca/gl860/gl860-mi1320.c b/drivers/media/video/gspca/gl860/gl860-mi1320.c
deleted file mode 100644
index b57160e0486..00000000000
--- a/drivers/media/video/gspca/gl860/gl860-mi1320.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/* Subdriver for the GL860 chip with the MI1320 sensor
- * Author Olivier LORIN from own logs
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Sensor : MI1320 */
-
-#include "gl860.h"
-
-static struct validx tbl_common[] = {
- {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba51, 0x0066}, {0xba02, 0x00f1},
- {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1},
- {0xffff, 0xffff},
- {0xba00, 0x00f0}, {0xba02, 0x00f1}, {0xbafa, 0x0028}, {0xba02, 0x00f1},
- {0xba00, 0x00f0}, {0xba01, 0x00f1}, {0xbaf0, 0x0006}, {0xba0e, 0x00f1},
- {0xba70, 0x0006}, {0xba0e, 0x00f1},
- {0xffff, 0xffff},
- {0xba74, 0x0006}, {0xba0e, 0x00f1},
- {0xffff, 0xffff},
- {0x0061, 0x0000}, {0x0068, 0x000d},
-};
-
-static struct validx tbl_init_at_startup[] = {
- {0x0000, 0x0000}, {0x0010, 0x0010},
- {35, 0xffff},
- {0x0008, 0x00c0}, {0x0001, 0x00c1}, {0x0001, 0x00c2}, {0x0020, 0x0006},
- {0x006a, 0x000d},
-};
-
-static struct validx tbl_sensor_settings_common[] = {
- {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2}, {0x0040, 0x0000},
- {0x006a, 0x0007}, {0x006a, 0x000d}, {0x0063, 0x0006},
-};
-static struct validx tbl_sensor_settings_1280[] = {
- {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba5a, 0x0066}, {0xba02, 0x00f1},
- {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xba20, 0x0065}, {0xba00, 0x00f1},
-};
-static struct validx tbl_sensor_settings_800[] = {
- {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba5a, 0x0066}, {0xba02, 0x00f1},
- {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xba20, 0x0065}, {0xba00, 0x00f1},
-};
-static struct validx tbl_sensor_settings_640[] = {
- {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1},
- {0xba51, 0x0066}, {0xba02, 0x00f1}, {0xba05, 0x0067}, {0xba05, 0x00f1},
- {0xba20, 0x0065}, {0xba00, 0x00f1},
-};
-static struct validx tbl_post_unset_alt[] = {
- {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1},
- {0x0061, 0x0000}, {0x0068, 0x000d},
-};
-
-static u8 *tbl_1280[] = {
- "\x0d\x80\xf1\x08\x03\x04\xf1\x00" "\x04\x05\xf1\x02\x05\x00\xf1\xf1"
- "\x06\x00\xf1\x0d\x20\x01\xf1\x00" "\x21\x84\xf1\x00\x0d\x00\xf1\x08"
- "\xf0\x00\xf1\x01\x34\x00\xf1\x00" "\x9b\x43\xf1\x00\xa6\x05\xf1\x00"
- "\xa9\x04\xf1\x00\xa1\x05\xf1\x00" "\xa4\x04\xf1\x00\xae\x0a\xf1\x08"
- ,
- "\xf0\x00\xf1\x02\x3a\x05\xf1\xf1" "\x3c\x05\xf1\xf1\x59\x01\xf1\x47"
- "\x5a\x01\xf1\x88\x5c\x0a\xf1\x06" "\x5d\x0e\xf1\x0a\x64\x5e\xf1\x1c"
- "\xd2\x00\xf1\xcf\xcb\x00\xf1\x01"
- ,
- "\xd3\x02\xd4\x28\xd5\x01\xd0\x02" "\xd1\x18\xd2\xc1"
-};
-
-static u8 *tbl_800[] = {
- "\x0d\x80\xf1\x08\x03\x03\xf1\xc0" "\x04\x05\xf1\x02\x05\x00\xf1\xf1"
- "\x06\x00\xf1\x0d\x20\x01\xf1\x00" "\x21\x84\xf1\x00\x0d\x00\xf1\x08"
- "\xf0\x00\xf1\x01\x34\x00\xf1\x00" "\x9b\x43\xf1\x00\xa6\x05\xf1\x00"
- "\xa9\x03\xf1\xc0\xa1\x03\xf1\x20" "\xa4\x02\xf1\x5a\xae\x0a\xf1\x08"
- ,
- "\xf0\x00\xf1\x02\x3a\x05\xf1\xf1" "\x3c\x05\xf1\xf1\x59\x01\xf1\x47"
- "\x5a\x01\xf1\x88\x5c\x0a\xf1\x06" "\x5d\x0e\xf1\x0a\x64\x5e\xf1\x1c"
- "\xd2\x00\xf1\xcf\xcb\x00\xf1\x01"
- ,
- "\xd3\x02\xd4\x18\xd5\x21\xd0\x02" "\xd1\x10\xd2\x59"
-};
-
-static u8 *tbl_640[] = {
- "\x0d\x80\xf1\x08\x03\x04\xf1\x04" "\x04\x05\xf1\x02\x07\x01\xf1\x7c"
- "\x08\x00\xf1\x0e\x21\x80\xf1\x00" "\x0d\x00\xf1\x08\xf0\x00\xf1\x01"
- "\x34\x10\xf1\x10\x3a\x43\xf1\x00" "\xa6\x05\xf1\x02\xa9\x04\xf1\x04"
- "\xa7\x02\xf1\x81\xaa\x01\xf1\xe2" "\xae\x0c\xf1\x09"
- ,
- "\xf0\x00\xf1\x02\x39\x03\xf1\xfc" "\x3b\x04\xf1\x04\x57\x01\xf1\xb6"
- "\x58\x02\xf1\x0d\x5c\x1f\xf1\x19" "\x5d\x24\xf1\x1e\x64\x5e\xf1\x1c"
- "\xd2\x00\xf1\x00\xcb\x00\xf1\x01"
- ,
- "\xd3\x02\xd4\x10\xd5\x81\xd0\x02" "\xd1\x08\xd2\xe1"
-};
-
-static s32 tbl_sat[] = {0x25, 0x1d, 0x15, 0x0d, 0x05, 0x4d, 0x55, 0x5d, 0x2d};
-static s32 tbl_bright[] = {0, 8, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70};
-static s32 tbl_backlight[] = {0x0e, 0x06, 0x02};
-
-static s32 tbl_cntr1[] = {
- 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8, 0xc0, 0xc8, 0xd0, 0xe0, 0xf0};
-static s32 tbl_cntr2[] = {
- 0x70, 0x68, 0x60, 0x58, 0x50, 0x48, 0x40, 0x38, 0x30, 0x20, 0x10};
-
-static u8 dat_wbalNL[] =
- "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x3b\x04\xf1\x2a\x47\x10\xf1\x10"
- "\x9d\x3c\xf1\xae\xaf\x10\xf1\x00" "\xf0\x00\xf1\x02\x2f\x91\xf1\x20"
- "\x9c\x91\xf1\x20\x37\x03\xf1\x00" "\x9d\xc5\xf1\x0f\xf0\x00\xf1\x00";
-
-static u8 dat_wbalLL[] =
- "\xf0\x00\xf1\x01\x05\x00\xf1\x0c" "\x3b\x04\xf1\x2a\x47\x40\xf1\x40"
- "\x9d\x20\xf1\xae\xaf\x10\xf1\x00" "\xf0\x00\xf1\x02\x2f\xd1\xf1\x00"
- "\x9c\xd1\xf1\x00\x37\x03\xf1\x00" "\x9d\xc5\xf1\x3f\xf0\x00\xf1\x00";
-
-static u8 dat_wbalBL[] =
- "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x47\x10\xf1\x30\x9d\x3c\xf1\xae"
- "\xaf\x10\xf1\x00\xf0\x00\xf1\x02" "\x2f\x91\xf1\x20\x9c\x91\xf1\x20"
- "\x37\x03\xf1\x00\x9d\xc5\xf1\x2f" "\xf0\x00\xf1\x00";
-
-static u8 dat_hvflip1[] = {0xf0, 0x00, 0xf1, 0x00};
-
-static u8 dat_common00[] =
- "\x00\x01\x07\x6a\x06\x63\x0d\x6a" "\xc0\x00\x10\x10\xc1\x03\xc2\x42"
- "\xd8\x04\x58\x00\x04\x02";
-static u8 dat_common01[] =
- "\x0d\x00\xf1\x0b\x0d\x00\xf1\x08" "\x35\x00\xf1\x22\x68\x00\xf1\x5d"
- "\xf0\x00\xf1\x01\x06\x70\xf1\x0e" "\xf0\x00\xf1\x02\xdd\x18\xf1\xe0";
-static u8 dat_common02[] =
- "\x05\x01\xf1\x84\x06\x00\xf1\x44" "\x07\x00\xf1\xbe\x08\x00\xf1\x1e"
- "\x20\x01\xf1\x03\x21\x84\xf1\x00" "\x22\x0d\xf1\x0f\x24\x80\xf1\x00"
- "\x34\x18\xf1\x2d\x35\x00\xf1\x22" "\x43\x83\xf1\x83\x59\x00\xf1\xff";
-static u8 dat_common03[] =
- "\xf0\x00\xf1\x02\x39\x06\xf1\x8c" "\x3a\x06\xf1\x8c\x3b\x03\xf1\xda"
- "\x3c\x05\xf1\x30\x57\x01\xf1\x0c" "\x58\x01\xf1\x42\x59\x01\xf1\x0c"
- "\x5a\x01\xf1\x42\x5c\x13\xf1\x0e" "\x5d\x17\xf1\x12\x64\x1e\xf1\x1c";
-static u8 dat_common04[] =
- "\xf0\x00\xf1\x02\x24\x5f\xf1\x20" "\x28\xea\xf1\x02\x5f\x41\xf1\x43";
-static u8 dat_common05[] =
- "\x02\x00\xf1\xee\x03\x29\xf1\x1a" "\x04\x02\xf1\xa4\x09\x00\xf1\x68"
- "\x0a\x00\xf1\x2a\x0b\x00\xf1\x04" "\x0c\x00\xf1\x93\x0d\x00\xf1\x82"
- "\x0e\x00\xf1\x40\x0f\x00\xf1\x5f" "\x10\x00\xf1\x4e\x11\x00\xf1\x5b";
-static u8 dat_common06[] =
- "\x15\x00\xf1\xc9\x16\x00\xf1\x5e" "\x17\x00\xf1\x9d\x18\x00\xf1\x06"
- "\x19\x00\xf1\x89\x1a\x00\xf1\x12" "\x1b\x00\xf1\xa1\x1c\x00\xf1\xe4"
- "\x1d\x00\xf1\x7a\x1e\x00\xf1\x64" "\xf6\x00\xf1\x5f";
-static u8 dat_common07[] =
- "\xf0\x00\xf1\x01\x53\x09\xf1\x03" "\x54\x3d\xf1\x1c\x55\x99\xf1\x72"
- "\x56\xc1\xf1\xb1\x57\xd8\xf1\xce" "\x58\xe0\xf1\x00\xdc\x0a\xf1\x03"
- "\xdd\x45\xf1\x20\xde\xae\xf1\x82" "\xdf\xdc\xf1\xc9\xe0\xf6\xf1\xea"
- "\xe1\xff\xf1\x00";
-static u8 dat_common08[] =
- "\xf0\x00\xf1\x01\x80\x00\xf1\x06" "\x81\xf6\xf1\x08\x82\xfb\xf1\xf7"
- "\x83\x00\xf1\xfe\xb6\x07\xf1\x03" "\xb7\x18\xf1\x0c\x84\xfb\xf1\x06"
- "\x85\xfb\xf1\xf9\x86\x00\xf1\xff" "\xb8\x07\xf1\x04\xb9\x16\xf1\x0a";
-static u8 dat_common09[] =
- "\x87\xfa\xf1\x05\x88\xfc\xf1\xf9" "\x89\x00\xf1\xff\xba\x06\xf1\x03"
- "\xbb\x17\xf1\x09\x8a\xe8\xf1\x14" "\x8b\xf7\xf1\xf0\x8c\xfd\xf1\xfa"
- "\x8d\x00\xf1\x00\xbc\x05\xf1\x01" "\xbd\x0c\xf1\x08\xbe\x00\xf1\x14";
-static u8 dat_common10[] =
- "\x8e\xea\xf1\x13\x8f\xf7\xf1\xf2" "\x90\xfd\xf1\xfa\x91\x00\xf1\x00"
- "\xbf\x05\xf1\x01\xc0\x0a\xf1\x08" "\xc1\x00\xf1\x0c\x92\xed\xf1\x0f"
- "\x93\xf9\xf1\xf4\x94\xfe\xf1\xfb" "\x95\x00\xf1\x00\xc2\x04\xf1\x01"
- "\xc3\x0a\xf1\x07\xc4\x00\xf1\x10";
-static u8 dat_common11[] =
- "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x25\x00\xf1\x55\x34\x10\xf1\x10"
- "\x35\xf0\xf1\x10\x3a\x02\xf1\x03" "\x3b\x04\xf1\x2a\x9b\x43\xf1\x00"
- "\xa4\x03\xf1\xc0\xa7\x02\xf1\x81";
-
-static int mi1320_init_at_startup(struct gspca_dev *gspca_dev);
-static int mi1320_configure_alt(struct gspca_dev *gspca_dev);
-static int mi1320_init_pre_alt(struct gspca_dev *gspca_dev);
-static int mi1320_init_post_alt(struct gspca_dev *gspca_dev);
-static void mi1320_post_unset_alt(struct gspca_dev *gspca_dev);
-static int mi1320_sensor_settings(struct gspca_dev *gspca_dev);
-static int mi1320_camera_settings(struct gspca_dev *gspca_dev);
-/*==========================================================================*/
-
-void mi1320_init_settings(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->vcur.backlight = 0;
- sd->vcur.brightness = 0;
- sd->vcur.sharpness = 6;
- sd->vcur.contrast = 10;
- sd->vcur.gamma = 20;
- sd->vcur.hue = 0;
- sd->vcur.saturation = 6;
- sd->vcur.whitebal = 0;
- sd->vcur.mirror = 0;
- sd->vcur.flip = 0;
- sd->vcur.AC50Hz = 1;
-
- sd->vmax.backlight = 2;
- sd->vmax.brightness = 8;
- sd->vmax.sharpness = 7;
- sd->vmax.contrast = 0; /* 10 but not working with this driver */
- sd->vmax.gamma = 40;
- sd->vmax.hue = 5 + 1;
- sd->vmax.saturation = 8;
- sd->vmax.whitebal = 2;
- sd->vmax.mirror = 1;
- sd->vmax.flip = 1;
- sd->vmax.AC50Hz = 1;
-
- sd->dev_camera_settings = mi1320_camera_settings;
- sd->dev_init_at_startup = mi1320_init_at_startup;
- sd->dev_configure_alt = mi1320_configure_alt;
- sd->dev_init_pre_alt = mi1320_init_pre_alt;
- sd->dev_post_unset_alt = mi1320_post_unset_alt;
-}
-
-/*==========================================================================*/
-
-static void common(struct gspca_dev *gspca_dev)
-{
- s32 n; /* reserved for FETCH functions */
-
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, dat_common00);
- ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, dat_common01);
- n = fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common));
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common02);
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common03);
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, dat_common04);
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common05);
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, dat_common06);
- keep_on_fetching_validx(gspca_dev, tbl_common,
- ARRAY_SIZE(tbl_common), n);
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, dat_common07);
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common08);
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common09);
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, dat_common10);
- keep_on_fetching_validx(gspca_dev, tbl_common,
- ARRAY_SIZE(tbl_common), n);
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, dat_common11);
- keep_on_fetching_validx(gspca_dev, tbl_common,
- ARRAY_SIZE(tbl_common), n);
-}
-
-static int mi1320_init_at_startup(struct gspca_dev *gspca_dev)
-{
- fetch_validx(gspca_dev, tbl_init_at_startup,
- ARRAY_SIZE(tbl_init_at_startup));
-
- common(gspca_dev);
-
-/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
-
- return 0;
-}
-
-static int mi1320_init_pre_alt(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->mirrorMask = 0;
-
- sd->vold.backlight = -1;
- sd->vold.brightness = -1;
- sd->vold.sharpness = -1;
- sd->vold.contrast = -1;
- sd->vold.saturation = -1;
- sd->vold.gamma = -1;
- sd->vold.hue = -1;
- sd->vold.whitebal = -1;
- sd->vold.mirror = -1;
- sd->vold.flip = -1;
- sd->vold.AC50Hz = -1;
-
- common(gspca_dev);
-
- mi1320_sensor_settings(gspca_dev);
-
- mi1320_init_post_alt(gspca_dev);
-
- return 0;
-}
-
-static int mi1320_init_post_alt(struct gspca_dev *gspca_dev)
-{
- mi1320_camera_settings(gspca_dev);
-
- return 0;
-}
-
-static int mi1320_sensor_settings(struct gspca_dev *gspca_dev)
-{
- s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
-
- ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
-
- fetch_validx(gspca_dev, tbl_sensor_settings_common,
- ARRAY_SIZE(tbl_sensor_settings_common));
-
- switch (reso) {
- case IMAGE_1280:
- fetch_validx(gspca_dev, tbl_sensor_settings_1280,
- ARRAY_SIZE(tbl_sensor_settings_1280));
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 64, tbl_1280[0]);
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_1280[1]);
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_1280[2]);
- break;
-
- case IMAGE_800:
- fetch_validx(gspca_dev, tbl_sensor_settings_800,
- ARRAY_SIZE(tbl_sensor_settings_800));
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 64, tbl_800[0]);
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_800[1]);
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_800[2]);
- break;
-
- default:
- fetch_validx(gspca_dev, tbl_sensor_settings_640,
- ARRAY_SIZE(tbl_sensor_settings_640));
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 60, tbl_640[0]);
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_640[1]);
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_640[2]);
- break;
- }
- return 0;
-}
-
-static int mi1320_configure_alt(struct gspca_dev *gspca_dev)
-{
- s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
-
- switch (reso) {
- case IMAGE_640:
- gspca_dev->alt = 3 + 1;
- break;
-
- case IMAGE_800:
- case IMAGE_1280:
- gspca_dev->alt = 1 + 1;
- break;
- }
- return 0;
-}
-
-static int mi1320_camera_settings(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- s32 backlight = sd->vcur.backlight;
- s32 bright = sd->vcur.brightness;
- s32 sharp = sd->vcur.sharpness;
- s32 cntr = sd->vcur.contrast;
- s32 gam = sd->vcur.gamma;
- s32 hue = sd->vcur.hue;
- s32 sat = sd->vcur.saturation;
- s32 wbal = sd->vcur.whitebal;
- s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
- s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0);
- s32 freq = (sd->vcur.AC50Hz > 0);
- s32 i;
-
- if (freq != sd->vold.AC50Hz) {
- sd->vold.AC50Hz = freq;
-
- freq = 2 * (freq == 0);
- ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba02, 0x00f1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x005b, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba01 + freq, 0x00f1, 0, NULL);
- }
-
- if (wbal != sd->vold.whitebal) {
- sd->vold.whitebal = wbal;
- if (wbal < 0 || wbal > sd->vmax.whitebal)
- wbal = 0;
-
- for (i = 0; i < 2; i++) {
- if (wbal == 0) { /* Normal light */
- ctrl_out(gspca_dev, 0x40, 1,
- 0x0010, 0x0010, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1,
- 0x0003, 0x00c1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1,
- 0x0042, 0x00c2, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 3,
- 0xba00, 0x0200, 48, dat_wbalNL);
- }
-
- if (wbal == 1) { /* Low light */
- ctrl_out(gspca_dev, 0x40, 1,
- 0x0010, 0x0010, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1,
- 0x0004, 0x00c1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1,
- 0x0043, 0x00c2, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 3,
- 0xba00, 0x0200, 48, dat_wbalLL);
- }
-
- if (wbal == 2) { /* Back light */
- ctrl_out(gspca_dev, 0x40, 1,
- 0x0010, 0x0010, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1,
- 0x0003, 0x00c1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1,
- 0x0042, 0x00c2, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 3,
- 0xba00, 0x0200, 44, dat_wbalBL);
- }
- }
- }
-
- if (bright != sd->vold.brightness) {
- sd->vold.brightness = bright;
- if (bright < 0 || bright > sd->vmax.brightness)
- bright = 0;
-
- bright = tbl_bright[bright];
- ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba00 + bright, 0x0034, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba00 + bright, 0x00f1, 0, NULL);
- }
-
- if (sat != sd->vold.saturation) {
- sd->vold.saturation = sat;
- if (sat < 0 || sat > sd->vmax.saturation)
- sat = 0;
-
- sat = tbl_sat[sat];
- ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x0025, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba00 + sat, 0x00f1, 0, NULL);
- }
-
- if (sharp != sd->vold.sharpness) {
- sd->vold.sharpness = sharp;
- if (sharp < 0 || sharp > sd->vmax.sharpness)
- sharp = 0;
-
- ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x0005, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba00 + sharp, 0x00f1, 0, NULL);
- }
-
- if (hue != sd->vold.hue) {
- /* 0=normal 1=NB 2="sepia" 3=negative 4=other 5=other2 */
- if (hue < 0 || hue > sd->vmax.hue)
- hue = 0;
- if (hue == sd->vmax.hue)
- sd->swapRB = 1;
- else
- sd->swapRB = 0;
-
- ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba70, 0x00e2, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba00 + hue * (hue < 6), 0x00f1,
- 0, NULL);
- }
-
- if (backlight != sd->vold.backlight) {
- sd->vold.backlight = backlight;
- if (backlight < 0 || backlight > sd->vmax.backlight)
- backlight = 0;
-
- backlight = tbl_backlight[backlight];
- for (i = 0; i < 2; i++) {
- ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba74, 0x0006, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba80 + backlight, 0x00f1,
- 0, NULL);
- }
- }
-
- if (hue != sd->vold.hue) {
- sd->vold.hue = hue;
-
- ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba70, 0x00e2, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba00 + hue * (hue < 6), 0x00f1,
- 0, NULL);
- }
-
- if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
- u8 dat_hvflip2[4] = {0x20, 0x01, 0xf1, 0x00};
- sd->vold.mirror = mirror;
- sd->vold.flip = flip;
-
- dat_hvflip2[3] = flip + 2 * mirror;
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 4, dat_hvflip1);
- ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 4, dat_hvflip2);
- }
-
- if (gam != sd->vold.gamma) {
- sd->vold.gamma = gam;
- if (gam < 0 || gam > sd->vmax.gamma)
- gam = 0;
-
- gam = 2 * gam;
- ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba04 , 0x003b, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba02 + gam, 0x00f1, 0, NULL);
- }
-
- if (cntr != sd->vold.contrast) {
- sd->vold.contrast = cntr;
- if (cntr < 0 || cntr > sd->vmax.contrast)
- cntr = 0;
-
- ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba00 + tbl_cntr1[cntr], 0x0035,
- 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0xba00 + tbl_cntr2[cntr], 0x00f1,
- 0, NULL);
- }
-
- return 0;
-}
-
-static void mi1320_post_unset_alt(struct gspca_dev *gspca_dev)
-{
- ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
-
- fetch_validx(gspca_dev, tbl_post_unset_alt,
- ARRAY_SIZE(tbl_post_unset_alt));
-}
diff --git a/drivers/media/video/gspca/gl860/gl860-mi2020.c b/drivers/media/video/gspca/gl860/gl860-mi2020.c
deleted file mode 100644
index 2edda6b7d65..00000000000
--- a/drivers/media/video/gspca/gl860/gl860-mi2020.c
+++ /dev/null
@@ -1,733 +0,0 @@
-/* Subdriver for the GL860 chip with the MI2020 sensor
- * Author Olivier LORIN, from logs by Iceman/Soro2005 + Fret_saw/Hulkie/Tricid
- * with the help of Kytrix/BUGabundo/Blazercist.
- * Driver achieved thanks to a webcam gift by Kytrix.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Sensor : MI2020 */
-
-#include "gl860.h"
-
-static u8 dat_wbal1[] = {0x8c, 0xa2, 0x0c};
-
-static u8 dat_bright1[] = {0x8c, 0xa2, 0x06};
-static u8 dat_bright3[] = {0x8c, 0xa1, 0x02};
-static u8 dat_bright4[] = {0x90, 0x00, 0x0f};
-static u8 dat_bright5[] = {0x8c, 0xa1, 0x03};
-static u8 dat_bright6[] = {0x90, 0x00, 0x05};
-
-static u8 dat_hvflip1[] = {0x8c, 0x27, 0x19};
-static u8 dat_hvflip3[] = {0x8c, 0x27, 0x3b};
-static u8 dat_hvflip5[] = {0x8c, 0xa1, 0x03};
-static u8 dat_hvflip6[] = {0x90, 0x00, 0x06};
-
-static struct idxdata tbl_middle_hvflip_low[] = {
- {0x33, "\x90\x00\x06"},
- {6, "\xff\xff\xff"},
- {0x33, "\x90\x00\x06"},
- {6, "\xff\xff\xff"},
- {0x33, "\x90\x00\x06"},
- {6, "\xff\xff\xff"},
- {0x33, "\x90\x00\x06"},
- {6, "\xff\xff\xff"},
-};
-
-static struct idxdata tbl_middle_hvflip_big[] = {
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa1\x20"},
- {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"},
- {102, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa1\x20"},
- {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
-};
-
-static struct idxdata tbl_end_hvflip[] = {
- {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
- {6, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
- {6, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
- {6, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
-};
-
-static u8 dat_freq1[] = { 0x8c, 0xa4, 0x04 };
-
-static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 };
-static u8 dat_multi6[] = { 0x90, 0x00, 0x05 };
-
-static struct validx tbl_init_at_startup[] = {
- {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
- {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
- {53, 0xffff},
- {0x0040, 0x0000}, {0x0063, 0x0006},
-};
-
-static struct validx tbl_common_0B[] = {
- {0x0002, 0x0004}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d},
- {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2},
- {0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000},
-};
-
-static struct idxdata tbl_common_3B[] = {
- {0x33, "\x86\x25\x01"}, {0x33, "\x86\x25\x00"},
- {2, "\xff\xff\xff"},
- {0x30, "\x1a\x0a\xcc"}, {0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"},
- {6, "\xff\xff\xff"}, /* 12 */
- {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
- {2, "\xff\xff\xff"}, /* - */
- {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\x22\x23"},
- {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa2\x0f"}, {0x33, "\x90\x00\x0d"},
- {0x33, "\x8c\xa2\x10"}, {0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x11"},
- {0x33, "\x90\x00\x07"}, {0x33, "\xf4\x03\x1d"}, {0x35, "\xa2\x00\xe2"},
- {0x33, "\x8c\xab\x05"}, {0x33, "\x90\x00\x01"}, {0x32, "\x6e\x00\x86"},
- {0x32, "\x70\x0f\xaa"}, {0x32, "\x72\x0f\xe4"}, {0x33, "\x8c\xa3\x4a"},
- {0x33, "\x90\x00\x5a"}, {0x33, "\x8c\xa3\x4b"}, {0x33, "\x90\x00\xa6"},
- {0x33, "\x8c\xa3\x61"}, {0x33, "\x90\x00\xc8"}, {0x33, "\x8c\xa3\x62"},
- {0x33, "\x90\x00\xe1"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
- {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
- {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
- {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
- {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
- {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
- {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
- {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
- {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
- {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
- {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
- {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
- {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
- {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
- {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
- {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
- {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
- {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
- {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
- {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
- {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
- {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
- {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
- {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
- {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
- {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
- {0x33, "\x78\x00\x00"},
- {2, "\xff\xff\xff"},
- {0x35, "\xb8\x1f\x20"}, {0x33, "\x8c\xa2\x06"}, {0x33, "\x90\x00\x10"},
- {0x33, "\x8c\xa2\x07"}, {0x33, "\x90\x00\x08"}, {0x33, "\x8c\xa2\x42"},
- {0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x4a"}, {0x33, "\x90\x00\x8c"},
- {0x35, "\xba\xfa\x08"}, {0x33, "\x8c\xa2\x02"}, {0x33, "\x90\x00\x22"},
- {0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"}, {0x33, "\x8c\xa4\x04"},
- {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"}, {0x33, "\x90\x00\x00"},
- {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa2\x0c"},
- {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"}, {0x33, "\x90\x00\x04"},
- {0x33, "\x8c\xa2\x14"}, {0x33, "\x90\x00\x20"}, {0x33, "\x8c\xa1\x03"},
- {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"}, {0x33, "\x90\x21\x11"},
- {0x33, "\x8c\x27\x1b"}, {0x33, "\x90\x02\x4f"}, {0x33, "\x8c\x27\x25"},
- {0x33, "\x90\x06\x0f"}, {0x33, "\x8c\x27\x39"}, {0x33, "\x90\x21\x11"},
- {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"}, {0x33, "\x8c\x27\x47"},
- {0x33, "\x90\x09\x4c"}, {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x02\x84"},
- {0x33, "\x8c\x27\x05"}, {0x33, "\x90\x01\xe2"}, {0x33, "\x8c\x27\x07"},
- {0x33, "\x90\x06\x40"}, {0x33, "\x8c\x27\x09"}, {0x33, "\x90\x04\xb0"},
- {0x33, "\x8c\x27\x0d"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x0f"},
- {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x11"}, {0x33, "\x90\x04\xbd"},
- {0x33, "\x8c\x27\x13"}, {0x33, "\x90\x06\x4d"}, {0x33, "\x8c\x27\x15"},
- {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"}, {0x33, "\x90\x21\x11"},
- {0x33, "\x8c\x27\x19"}, {0x33, "\x90\x04\x6c"}, {0x33, "\x8c\x27\x1b"},
- {0x33, "\x90\x02\x4f"}, {0x33, "\x8c\x27\x1d"}, {0x33, "\x90\x01\x02"},
- {0x33, "\x8c\x27\x1f"}, {0x33, "\x90\x02\x79"}, {0x33, "\x8c\x27\x21"},
- {0x33, "\x90\x01\x55"}, {0x33, "\x8c\x27\x23"}, {0x33, "\x90\x02\x85"},
- {0x33, "\x8c\x27\x25"}, {0x33, "\x90\x06\x0f"}, {0x33, "\x8c\x27\x27"},
- {0x33, "\x90\x20\x20"}, {0x33, "\x8c\x27\x29"}, {0x33, "\x90\x20\x20"},
- {0x33, "\x8c\x27\x2b"}, {0x33, "\x90\x10\x20"}, {0x33, "\x8c\x27\x2d"},
- {0x33, "\x90\x20\x07"}, {0x33, "\x8c\x27\x2f"}, {0x33, "\x90\x00\x04"},
- {0x33, "\x8c\x27\x31"}, {0x33, "\x90\x00\x04"}, {0x33, "\x8c\x27\x33"},
- {0x33, "\x90\x04\xbb"}, {0x33, "\x8c\x27\x35"}, {0x33, "\x90\x06\x4b"},
- {0x33, "\x8c\x27\x37"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x39"},
- {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x3b"}, {0x33, "\x90\x00\x24"},
- {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"}, {0x33, "\x8c\x27\x41"},
- {0x33, "\x90\x01\x69"}, {0x33, "\x8c\x27\x45"}, {0x33, "\x90\x04\xed"},
- {0x33, "\x8c\x27\x47"}, {0x33, "\x90\x09\x4c"}, {0x33, "\x8c\x27\x51"},
- {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x53"}, {0x33, "\x90\x03\x20"},
- {0x33, "\x8c\x27\x55"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x57"},
- {0x33, "\x90\x02\x58"}, {0x33, "\x8c\x27\x5f"}, {0x33, "\x90\x00\x00"},
- {0x33, "\x8c\x27\x61"}, {0x33, "\x90\x06\x40"}, {0x33, "\x8c\x27\x63"},
- {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x65"}, {0x33, "\x90\x04\xb0"},
- {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa1"}, {0x33, "\x8c\xa4\x08"},
- {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"},
- {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"},
- {0x33, "\x90\x00\x27"}, {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\xa1"},
- {0x33, "\x8c\x24\x13"}, {0x33, "\x90\x00\xc1"}, {0x33, "\x8c\x24\x15"},
- {0x33, "\x90\x00\x6a"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\x80"},
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
- {2, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
- {3, "\xff\xff\xff"},
-};
-
-static struct idxdata tbl_init_post_alt_low1[] = {
- {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\x22\x2e"},
- {0x33, "\x90\x00\x81"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x17"},
- {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x1a"}, {0x33, "\x8c\xa4\x0a"},
- {0x33, "\x90\x00\x1d"}, {0x33, "\x8c\xa4\x0b"}, {0x33, "\x90\x00\x20"},
- {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\x81"}, {0x33, "\x8c\x24\x13"},
- {0x33, "\x90\x00\x9b"},
-};
-
-static struct idxdata tbl_init_post_alt_low2[] = {
- {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x03\x24"}, {0x33, "\x8c\x27\x05"},
- {0x33, "\x90\x02\x58"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
- {2, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
- {2, "\xff\xff\xff"},
-};
-
-static struct idxdata tbl_init_post_alt_low3[] = {
- {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
- {2, "\xff\xff\xff"},
- {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x20"},
- {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x01"},
- {0x33, "\x2e\x01\x00"}, {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"},
- {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x95"}, {0x33, "\x90\x01\x00"},
- {2, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x03"},
- {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
- {2, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"},
- {0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"},
- {2, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
- {2, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
- {2, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
- {2, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
-};
-
-static struct idxdata tbl_init_post_alt_big[] = {
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
- {2, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
- {2, "\xff\xff\xff"},
- {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
- {2, "\xff\xff\xff"},
- {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x03"},
- {0x33, "\x90\x00\x05"},
- {2, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
- {2, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
- {2, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, {0x33, "\x8c\xa1\x20"},
- {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x30"}, {0x33, "\x90\x00\x03"},
- {0x33, "\x8c\xa1\x31"}, {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa1\x32"},
- {0x33, "\x90\x00\x03"}, {0x33, "\x8c\xa1\x34"}, {0x33, "\x90\x00\x03"},
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x02"}, {0x33, "\x2e\x01\x00"},
- {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
- {0x33, "\x8c\x27\x97"}, {0x33, "\x90\x01\x00"},
- {51, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"},
- {0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"},
- {51, "\xff\xff\xff"},
- {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x03"},
- {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
- {51, "\xff\xff\xff"},
-};
-
-static struct idxdata tbl_init_post_alt_3B[] = {
- {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
- {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
- {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
- {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
- {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
- {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
- {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
- {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
- {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
- {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
- {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
- {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
- {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
- {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
- {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
- {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
- {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
- {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
- {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
- {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
- {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
- {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
- {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
- {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
- {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
- {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
-};
-
-static u8 *dat_640 = "\xd0\x02\xd1\x08\xd2\xe1\xd3\x02\xd4\x10\xd5\x81";
-static u8 *dat_800 = "\xd0\x02\xd1\x10\xd2\x57\xd3\x02\xd4\x18\xd5\x21";
-static u8 *dat_1280 = "\xd0\x02\xd1\x20\xd2\x01\xd3\x02\xd4\x28\xd5\x01";
-static u8 *dat_1600 = "\xd0\x02\xd1\x20\xd2\xaf\xd3\x02\xd4\x30\xd5\x41";
-
-static int mi2020_init_at_startup(struct gspca_dev *gspca_dev);
-static int mi2020_configure_alt(struct gspca_dev *gspca_dev);
-static int mi2020_init_pre_alt(struct gspca_dev *gspca_dev);
-static int mi2020_init_post_alt(struct gspca_dev *gspca_dev);
-static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev);
-static int mi2020_camera_settings(struct gspca_dev *gspca_dev);
-/*==========================================================================*/
-
-void mi2020_init_settings(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->vcur.backlight = 0;
- sd->vcur.brightness = 70;
- sd->vcur.sharpness = 20;
- sd->vcur.contrast = 0;
- sd->vcur.gamma = 0;
- sd->vcur.hue = 0;
- sd->vcur.saturation = 60;
- sd->vcur.whitebal = 0; /* 50, not done by hardware */
- sd->vcur.mirror = 0;
- sd->vcur.flip = 0;
- sd->vcur.AC50Hz = 1;
-
- sd->vmax.backlight = 64;
- sd->vmax.brightness = 128;
- sd->vmax.sharpness = 40;
- sd->vmax.contrast = 3;
- sd->vmax.gamma = 2;
- sd->vmax.hue = 0 + 1; /* 200, not done by hardware */
- sd->vmax.saturation = 0; /* 100, not done by hardware */
- sd->vmax.whitebal = 2; /* 100, not done by hardware */
- sd->vmax.mirror = 1;
- sd->vmax.flip = 1;
- sd->vmax.AC50Hz = 1;
-
- sd->dev_camera_settings = mi2020_camera_settings;
- sd->dev_init_at_startup = mi2020_init_at_startup;
- sd->dev_configure_alt = mi2020_configure_alt;
- sd->dev_init_pre_alt = mi2020_init_pre_alt;
- sd->dev_post_unset_alt = mi2020_post_unset_alt;
-}
-
-/*==========================================================================*/
-
-static void common(struct gspca_dev *gspca_dev)
-{
- fetch_validx(gspca_dev, tbl_common_0B, ARRAY_SIZE(tbl_common_0B));
- fetch_idxdata(gspca_dev, tbl_common_3B, ARRAY_SIZE(tbl_common_3B));
- ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
-}
-
-static int mi2020_init_at_startup(struct gspca_dev *gspca_dev)
-{
- u8 c;
-
- ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &c);
- ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &c);
-
- fetch_validx(gspca_dev, tbl_init_at_startup,
- ARRAY_SIZE(tbl_init_at_startup));
-
- ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL);
- ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &c);
-
- common(gspca_dev);
-
- msleep(61);
-/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
-/* msleep(36); */
- ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0000, 0, NULL);
-
- return 0;
-}
-
-static int mi2020_init_pre_alt(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->mirrorMask = 0;
- sd->vold.hue = -1;
-
- /* These controls need to be reset */
- sd->vold.brightness = -1;
- sd->vold.sharpness = -1;
-
- /* If not different from default, they do not need to be set */
- sd->vold.contrast = 0;
- sd->vold.gamma = 0;
- sd->vold.backlight = 0;
-
- mi2020_init_post_alt(gspca_dev);
-
- return 0;
-}
-
-static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
-
- s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
- s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0);
- s32 freq = (sd->vcur.AC50Hz > 0);
- s32 wbal = sd->vcur.whitebal;
-
- u8 dat_freq2[] = {0x90, 0x00, 0x80};
- u8 dat_multi1[] = {0x8c, 0xa7, 0x00};
- u8 dat_multi2[] = {0x90, 0x00, 0x00};
- u8 dat_multi3[] = {0x8c, 0xa7, 0x00};
- u8 dat_multi4[] = {0x90, 0x00, 0x00};
- u8 dat_hvflip2[] = {0x90, 0x04, 0x6c};
- u8 dat_hvflip4[] = {0x90, 0x00, 0x24};
- u8 dat_wbal2[] = {0x90, 0x00, 0x00};
- u8 c;
-
- sd->nbIm = -1;
-
- dat_freq2[2] = freq ? 0xc0 : 0x80;
- dat_multi1[2] = 0x9d;
- dat_multi3[2] = dat_multi1[2] + 1;
- if (wbal == 0) {
- dat_multi4[2] = dat_multi2[2] = 0;
- dat_wbal2[2] = 0x17;
- } else if (wbal == 1) {
- dat_multi4[2] = dat_multi2[2] = 0;
- dat_wbal2[2] = 0x35;
- } else if (wbal == 2) {
- dat_multi4[2] = dat_multi2[2] = 0x20;
- dat_wbal2[2] = 0x17;
- }
- dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror);
- dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror);
-
- msleep(200);
- ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
- msleep(2);
-
- common(gspca_dev);
-
- msleep(142);
- ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0003, 0x00c1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0042, 0x00c2, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
-
- switch (reso) {
- case IMAGE_640:
- case IMAGE_800:
- if (reso != IMAGE_800)
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
- 12, dat_640);
- else
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
- 12, dat_800);
-
- fetch_idxdata(gspca_dev, tbl_init_post_alt_low1,
- ARRAY_SIZE(tbl_init_post_alt_low1));
-
- if (reso == IMAGE_800)
- fetch_idxdata(gspca_dev, tbl_init_post_alt_low2,
- ARRAY_SIZE(tbl_init_post_alt_low2));
-
- fetch_idxdata(gspca_dev, tbl_init_post_alt_low3,
- ARRAY_SIZE(tbl_init_post_alt_low3));
-
- ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
- msleep(120);
- break;
-
- case IMAGE_1280:
- case IMAGE_1600:
- if (reso == IMAGE_1280) {
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
- 12, dat_1280);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, "\x8c\x27\x07");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, "\x90\x05\x04");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, "\x8c\x27\x09");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, "\x90\x04\x02");
- } else {
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
- 12, dat_1600);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, "\x8c\x27\x07");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, "\x90\x06\x40");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, "\x8c\x27\x09");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, "\x90\x04\xb0");
- }
-
- fetch_idxdata(gspca_dev, tbl_init_post_alt_big,
- ARRAY_SIZE(tbl_init_post_alt_big));
-
- ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
- msleep(1850);
- }
-
- ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
- msleep(40);
-
- /* AC power frequency */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
- msleep(33);
- /* light source */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
- msleep(7);
- ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
-
- fetch_idxdata(gspca_dev, tbl_init_post_alt_3B,
- ARRAY_SIZE(tbl_init_post_alt_3B));
-
- /* hvflip */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6);
- msleep(250);
-
- if (reso == IMAGE_640 || reso == IMAGE_800)
- fetch_idxdata(gspca_dev, tbl_middle_hvflip_low,
- ARRAY_SIZE(tbl_middle_hvflip_low));
- else
- fetch_idxdata(gspca_dev, tbl_middle_hvflip_big,
- ARRAY_SIZE(tbl_middle_hvflip_big));
-
- fetch_idxdata(gspca_dev, tbl_end_hvflip,
- ARRAY_SIZE(tbl_end_hvflip));
-
- sd->nbIm = 0;
-
- sd->vold.mirror = mirror;
- sd->vold.flip = flip;
- sd->vold.AC50Hz = freq;
- sd->vold.whitebal = wbal;
-
- mi2020_camera_settings(gspca_dev);
-
- return 0;
-}
-
-static int mi2020_configure_alt(struct gspca_dev *gspca_dev)
-{
- s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
-
- switch (reso) {
- case IMAGE_640:
- gspca_dev->alt = 3 + 1;
- break;
-
- case IMAGE_800:
- case IMAGE_1280:
- case IMAGE_1600:
- gspca_dev->alt = 1 + 1;
- break;
- }
- return 0;
-}
-
-static int mi2020_camera_settings(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
-
- s32 backlight = sd->vcur.backlight;
- s32 bright = sd->vcur.brightness;
- s32 sharp = sd->vcur.sharpness;
- s32 cntr = sd->vcur.contrast;
- s32 gam = sd->vcur.gamma;
- s32 hue = (sd->vcur.hue > 0);
- s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
- s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0);
- s32 freq = (sd->vcur.AC50Hz > 0);
- s32 wbal = sd->vcur.whitebal;
-
- u8 dat_sharp[] = {0x6c, 0x00, 0x08};
- u8 dat_bright2[] = {0x90, 0x00, 0x00};
- u8 dat_freq2[] = {0x90, 0x00, 0x80};
- u8 dat_multi1[] = {0x8c, 0xa7, 0x00};
- u8 dat_multi2[] = {0x90, 0x00, 0x00};
- u8 dat_multi3[] = {0x8c, 0xa7, 0x00};
- u8 dat_multi4[] = {0x90, 0x00, 0x00};
- u8 dat_hvflip2[] = {0x90, 0x04, 0x6c};
- u8 dat_hvflip4[] = {0x90, 0x00, 0x24};
- u8 dat_wbal2[] = {0x90, 0x00, 0x00};
-
- /* Less than 4 images received -> too early to set the settings */
- if (sd->nbIm < 4) {
- sd->waitSet = 1;
- return 0;
- }
- sd->waitSet = 0;
-
- if (freq != sd->vold.AC50Hz) {
- sd->vold.AC50Hz = freq;
-
- dat_freq2[2] = freq ? 0xc0 : 0x80;
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
- msleep(20);
- }
-
- if (wbal != sd->vold.whitebal) {
- sd->vold.whitebal = wbal;
- if (wbal < 0 || wbal > sd->vmax.whitebal)
- wbal = 0;
-
- dat_multi1[2] = 0x9d;
- dat_multi3[2] = dat_multi1[2] + 1;
- if (wbal == 0) {
- dat_multi4[2] = dat_multi2[2] = 0;
- dat_wbal2[2] = 0x17;
- } else if (wbal == 1) {
- dat_multi4[2] = dat_multi2[2] = 0;
- dat_wbal2[2] = 0x35;
- } else if (wbal == 2) {
- dat_multi4[2] = dat_multi2[2] = 0x20;
- dat_wbal2[2] = 0x17;
- }
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
- }
-
- if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
- sd->vold.mirror = mirror;
- sd->vold.flip = flip;
-
- dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror);
- dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror);
-
- fetch_idxdata(gspca_dev, tbl_init_post_alt_3B,
- ARRAY_SIZE(tbl_init_post_alt_3B));
-
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6);
- msleep(40);
-
- if (reso == IMAGE_640 || reso == IMAGE_800)
- fetch_idxdata(gspca_dev, tbl_middle_hvflip_low,
- ARRAY_SIZE(tbl_middle_hvflip_low));
- else
- fetch_idxdata(gspca_dev, tbl_middle_hvflip_big,
- ARRAY_SIZE(tbl_middle_hvflip_big));
-
- fetch_idxdata(gspca_dev, tbl_end_hvflip,
- ARRAY_SIZE(tbl_end_hvflip));
- }
-
- if (bright != sd->vold.brightness) {
- sd->vold.brightness = bright;
- if (bright < 0 || bright > sd->vmax.brightness)
- bright = 0;
-
- dat_bright2[2] = bright;
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright3);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright4);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright6);
- }
-
- if (cntr != sd->vold.contrast || gam != sd->vold.gamma) {
- sd->vold.contrast = cntr;
- if (cntr < 0 || cntr > sd->vmax.contrast)
- cntr = 0;
- sd->vold.gamma = gam;
- if (gam < 0 || gam > sd->vmax.gamma)
- gam = 0;
-
- dat_multi1[2] = 0x6d;
- dat_multi3[2] = dat_multi1[2] + 1;
- if (cntr == 0)
- cntr = 4;
- dat_multi4[2] = dat_multi2[2] = cntr * 0x10 + 2 - gam;
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
- }
-
- if (backlight != sd->vold.backlight) {
- sd->vold.backlight = backlight;
- if (backlight < 0 || backlight > sd->vmax.backlight)
- backlight = 0;
-
- dat_multi1[2] = 0x9d;
- dat_multi3[2] = dat_multi1[2] + 1;
- dat_multi4[2] = dat_multi2[2] = backlight;
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
- }
-
- if (sharp != sd->vold.sharpness) {
- sd->vold.sharpness = sharp;
- if (sharp < 0 || sharp > sd->vmax.sharpness)
- sharp = 0;
-
- dat_sharp[1] = sharp;
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0032, 3, dat_sharp);
- }
-
- if (hue != sd->vold.hue) {
- sd->swapRB = hue;
- sd->vold.hue = hue;
- }
-
- return 0;
-}
-
-static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev)
-{
- ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
- msleep(40);
- ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0000, 0, NULL);
-}
diff --git a/drivers/media/video/gspca/gl860/gl860-ov2640.c b/drivers/media/video/gspca/gl860/gl860-ov2640.c
deleted file mode 100644
index 768cac5cd72..00000000000
--- a/drivers/media/video/gspca/gl860/gl860-ov2640.c
+++ /dev/null
@@ -1,489 +0,0 @@
-/* Subdriver for the GL860 chip with the OV2640 sensor
- * Author Olivier LORIN, from Malmostoso's logs
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Sensor : OV2640 */
-
-#include "gl860.h"
-
-static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01";
-
-static u8 c61[] = {0x61}; /* expected */
-static u8 c51[] = {0x51}; /* expected */
-static u8 c50[] = {0x50}; /* expected */
-static u8 c28[] = {0x28}; /* expected */
-static u8 ca8[] = {0xa8}; /* expected */
-
-static u8 dat_post[] =
- "\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01";
-
-static u8 dat_640[] = "\xd0\x01\xd1\x08\xd2\xe0\xd3\x02\xd4\x10\xd5\x81";
-static u8 dat_800[] = "\xd0\x01\xd1\x10\xd2\x58\xd3\x02\xd4\x18\xd5\x21";
-static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01";
-static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41";
-
-static struct validx tbl_init_at_startup[] = {
- {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
- {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
- {0x0050, 0x0000}, {0x0041, 0x0000}, {0x006a, 0x0007}, {0x0061, 0x0006},
- {0x006a, 0x000d}, {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1},
- {0x0041, 0x00c2}, {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058},
- {0x0041, 0x0000}, {0x0061, 0x0000},
-};
-
-static struct validx tbl_common[] = {
- {0x6000, 0x00ff}, {0x60ff, 0x002c}, {0x60df, 0x002e}, {0x6001, 0x00ff},
- {0x6080, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045}, {0x6000, 0x0010},
- {0x6035, 0x003c}, {0x6000, 0x0011}, {0x6028, 0x0004}, {0x60e5, 0x0013},
- {0x6088, 0x0014}, {0x600c, 0x002c}, {0x6078, 0x0033}, {0x60f7, 0x003b},
- {0x6000, 0x003e}, {0x6011, 0x0043}, {0x6010, 0x0016}, {0x6082, 0x0039},
- {0x6088, 0x0035}, {0x600a, 0x0022}, {0x6040, 0x0037}, {0x6000, 0x0023},
- {0x60a0, 0x0034}, {0x601a, 0x0036}, {0x6002, 0x0006}, {0x60c0, 0x0007},
- {0x60b7, 0x000d}, {0x6001, 0x000e}, {0x6000, 0x004c}, {0x6081, 0x004a},
- {0x6099, 0x0021}, {0x6002, 0x0009}, {0x603e, 0x0024}, {0x6034, 0x0025},
- {0x6081, 0x0026}, {0x6000, 0x0000}, {0x6000, 0x0045}, {0x6000, 0x0010},
- {0x6000, 0x005c}, {0x6000, 0x0063}, {0x6000, 0x007c}, {0x6070, 0x0061},
- {0x6080, 0x0062}, {0x6080, 0x0020}, {0x6030, 0x0028}, {0x6000, 0x006c},
- {0x6000, 0x006e}, {0x6002, 0x0070}, {0x6094, 0x0071}, {0x60c1, 0x0073},
- {0x6034, 0x003d}, {0x6057, 0x005a}, {0x60bb, 0x004f}, {0x609c, 0x0050},
- {0x6080, 0x006d}, {0x6002, 0x0039}, {0x6033, 0x003a}, {0x60f1, 0x003b},
- {0x6031, 0x003c}, {0x6000, 0x00ff}, {0x6014, 0x00e0}, {0x60ff, 0x0076},
- {0x60a0, 0x0033}, {0x6020, 0x0042}, {0x6018, 0x0043}, {0x6000, 0x004c},
- {0x60d0, 0x0087}, {0x600f, 0x0088}, {0x6003, 0x00d7}, {0x6010, 0x00d9},
- {0x6005, 0x00da}, {0x6082, 0x00d3}, {0x60c0, 0x00f9}, {0x6006, 0x0044},
- {0x6007, 0x00d1}, {0x6002, 0x00d2}, {0x6000, 0x00d2}, {0x6011, 0x00d8},
- {0x6008, 0x00c8}, {0x6080, 0x00c9}, {0x6008, 0x007c}, {0x6020, 0x007d},
- {0x6020, 0x007d}, {0x6000, 0x0090}, {0x600e, 0x0091}, {0x601a, 0x0091},
- {0x6031, 0x0091}, {0x605a, 0x0091}, {0x6069, 0x0091}, {0x6075, 0x0091},
- {0x607e, 0x0091}, {0x6088, 0x0091}, {0x608f, 0x0091}, {0x6096, 0x0091},
- {0x60a3, 0x0091}, {0x60af, 0x0091}, {0x60c4, 0x0091}, {0x60d7, 0x0091},
- {0x60e8, 0x0091}, {0x6020, 0x0091}, {0x6000, 0x0092}, {0x6006, 0x0093},
- {0x60e3, 0x0093}, {0x6005, 0x0093}, {0x6005, 0x0093}, {0x6000, 0x0093},
- {0x6004, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093},
- {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093},
- {0x6000, 0x0096}, {0x6008, 0x0097}, {0x6019, 0x0097}, {0x6002, 0x0097},
- {0x600c, 0x0097}, {0x6024, 0x0097}, {0x6030, 0x0097}, {0x6028, 0x0097},
- {0x6026, 0x0097}, {0x6002, 0x0097}, {0x6098, 0x0097}, {0x6080, 0x0097},
- {0x6000, 0x0097}, {0x6000, 0x0097}, {0x60ed, 0x00c3}, {0x609a, 0x00c4},
- {0x6000, 0x00a4}, {0x6011, 0x00c5}, {0x6051, 0x00c6}, {0x6010, 0x00c7},
- {0x6066, 0x00b6}, {0x60a5, 0x00b8}, {0x6064, 0x00b7}, {0x607c, 0x00b9},
- {0x60af, 0x00b3}, {0x6097, 0x00b4}, {0x60ff, 0x00b5}, {0x60c5, 0x00b0},
- {0x6094, 0x00b1}, {0x600f, 0x00b2}, {0x605c, 0x00c4}, {0x6000, 0x00a8},
- {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x601d, 0x0086}, {0x6000, 0x0050},
- {0x6090, 0x0051}, {0x6018, 0x0052}, {0x6000, 0x0053}, {0x6000, 0x0054},
- {0x6088, 0x0055}, {0x6000, 0x0057}, {0x6090, 0x005a}, {0x6018, 0x005b},
- {0x6005, 0x005c}, {0x60ed, 0x00c3}, {0x6000, 0x007f}, {0x6005, 0x00da},
- {0x601f, 0x00e5}, {0x6067, 0x00e1}, {0x6000, 0x00e0}, {0x60ff, 0x00dd},
- {0x6000, 0x0005}, {0x6001, 0x00ff}, {0x6000, 0x0000}, {0x6000, 0x0045},
- {0x6000, 0x0010},
-};
-
-static struct validx tbl_sensor_settings_common1[] = {
- {0x0041, 0x0000}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d},
- {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2},
- {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0041, 0x0000},
- {50, 0xffff},
- {0x0061, 0x0000},
- {0xffff, 0xffff},
- {0x6000, 0x00ff}, {0x6000, 0x007c}, {0x6007, 0x007d},
- {30, 0xffff},
- {0x0040, 0x0000},
-};
-
-static struct validx tbl_sensor_settings_common2[] = {
- {0x6001, 0x00ff}, {0x6038, 0x000c},
- {10, 0xffff},
- {0x6000, 0x0011},
-};
-
-static struct validx tbl_640[] = {
- {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, {0x6067, 0x00e1},
- {0x6004, 0x00da}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
- {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0011}, {0x6011, 0x0017},
- {0x6075, 0x0018}, {0x6001, 0x0019}, {0x6097, 0x001a}, {0x6036, 0x0032},
- {0x60bb, 0x004f}, {0x6057, 0x005a}, {0x609c, 0x0050}, {0x6080, 0x006d},
- {0x6092, 0x0026}, {0x60ff, 0x0020}, {0x6000, 0x0027}, {0x6000, 0x00ff},
- {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c}, {0x603d, 0x0086},
- {0x6089, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052}, {0x6000, 0x0053},
- {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057}, {0x60a0, 0x005a},
- {0x6078, 0x005b}, {0x6000, 0x005c}, {0x6004, 0x00d3}, {0x6000, 0x00e0},
- {0x60ff, 0x00dd}, {0x60a1, 0x005a},
-};
-
-static struct validx tbl_800[] = {
- {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, {0x6067, 0x00e1},
- {0x6004, 0x00da}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
- {0x6001, 0x00ff}, {0x6040, 0x0012}, {0x6000, 0x0011}, {0x6011, 0x0017},
- {0x6043, 0x0018}, {0x6000, 0x0019}, {0x604b, 0x001a}, {0x6009, 0x0032},
- {0x60ca, 0x004f}, {0x60a8, 0x0050}, {0x6000, 0x006d}, {0x6038, 0x003d},
- {0x60c8, 0x0035}, {0x6000, 0x0022}, {0x6092, 0x0026}, {0x60ff, 0x0020},
- {0x6000, 0x0027}, {0x6000, 0x00ff}, {0x6064, 0x00c0}, {0x604b, 0x00c1},
- {0x6000, 0x008c}, {0x601d, 0x0086}, {0x6082, 0x00d3}, {0x6000, 0x00e0},
- {0x60ff, 0x00dd}, {0x6020, 0x008c}, {0x6001, 0x00ff}, {0x6044, 0x0018},
-};
-
-static struct validx tbl_big1[] = {
- {0x0002, 0x00c1}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
- {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045},
- {0x6000, 0x0010}, {0x6000, 0x0011}, {0x6011, 0x0017}, {0x6075, 0x0018},
- {0x6001, 0x0019}, {0x6097, 0x001a}, {0x6036, 0x0032}, {0x60bb, 0x004f},
- {0x609c, 0x0050}, {0x6057, 0x005a}, {0x6080, 0x006d}, {0x6043, 0x000f},
- {0x608f, 0x0003}, {0x6005, 0x007c}, {0x6081, 0x0026}, {0x6000, 0x00ff},
- {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c},
-};
-
-static struct validx tbl_big2[] = {
- {0x603d, 0x0086}, {0x6000, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052},
- {0x6000, 0x0053}, {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057},
- {0x6040, 0x005a}, {0x60f0, 0x005b}, {0x6001, 0x005c}, {0x6082, 0x00d3},
- {0x6000, 0x008e},
-};
-
-static struct validx tbl_big3[] = {
- {0x6004, 0x00da}, {0x6000, 0x00e0}, {0x6067, 0x00e1}, {0x60ff, 0x00dd},
- {0x6001, 0x00ff}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
- {0x6001, 0x00ff}, {0x6000, 0x0011}, {0x6000, 0x00ff}, {0x6010, 0x00c7},
- {0x6000, 0x0092}, {0x6006, 0x0093}, {0x60e3, 0x0093}, {0x6005, 0x0093},
- {0x6005, 0x0093}, {0x60ed, 0x00c3}, {0x6000, 0x00a4}, {0x60d0, 0x0087},
- {0x6003, 0x0096}, {0x600c, 0x0097}, {0x6024, 0x0097}, {0x6030, 0x0097},
- {0x6028, 0x0097}, {0x6026, 0x0097}, {0x6002, 0x0097}, {0x6001, 0x00ff},
- {0x6043, 0x000f}, {0x608f, 0x0003}, {0x6000, 0x002d}, {0x6000, 0x002e},
- {0x600a, 0x0022}, {0x6002, 0x0070}, {0x6008, 0x0014}, {0x6048, 0x0014},
- {0x6000, 0x00ff}, {0x6000, 0x00e0}, {0x60ff, 0x00dd},
-};
-
-static struct validx tbl_post_unset_alt[] = {
- {0x006a, 0x000d}, {0x6001, 0x00ff}, {0x6081, 0x0026}, {0x6000, 0x0000},
- {0x6000, 0x0045}, {0x6000, 0x0010}, {0x6068, 0x000d},
- {50, 0xffff},
- {0x0021, 0x0000},
-};
-
-static int ov2640_init_at_startup(struct gspca_dev *gspca_dev);
-static int ov2640_configure_alt(struct gspca_dev *gspca_dev);
-static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev);
-static int ov2640_init_post_alt(struct gspca_dev *gspca_dev);
-static void ov2640_post_unset_alt(struct gspca_dev *gspca_dev);
-static int ov2640_camera_settings(struct gspca_dev *gspca_dev);
-/*==========================================================================*/
-
-void ov2640_init_settings(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->vcur.backlight = 32;
- sd->vcur.brightness = 0;
- sd->vcur.sharpness = 6;
- sd->vcur.contrast = 0;
- sd->vcur.gamma = 32;
- sd->vcur.hue = 0;
- sd->vcur.saturation = 128;
- sd->vcur.whitebal = 64;
- sd->vcur.mirror = 0;
- sd->vcur.flip = 0;
-
- sd->vmax.backlight = 64;
- sd->vmax.brightness = 255;
- sd->vmax.sharpness = 31;
- sd->vmax.contrast = 255;
- sd->vmax.gamma = 64;
- sd->vmax.hue = 254 + 2;
- sd->vmax.saturation = 255;
- sd->vmax.whitebal = 128;
- sd->vmax.mirror = 1;
- sd->vmax.flip = 1;
- sd->vmax.AC50Hz = 0;
-
- sd->dev_camera_settings = ov2640_camera_settings;
- sd->dev_init_at_startup = ov2640_init_at_startup;
- sd->dev_configure_alt = ov2640_configure_alt;
- sd->dev_init_pre_alt = ov2640_init_pre_alt;
- sd->dev_post_unset_alt = ov2640_post_unset_alt;
-}
-
-/*==========================================================================*/
-
-static void common(struct gspca_dev *gspca_dev)
-{
- fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common));
-}
-
-static int ov2640_init_at_startup(struct gspca_dev *gspca_dev)
-{
- fetch_validx(gspca_dev, tbl_init_at_startup,
- ARRAY_SIZE(tbl_init_at_startup));
-
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_init1);
-
- common(gspca_dev);
-
- ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, c61);
-
- ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL);
-
- ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c51);
-
- ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL);
-/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
-
- return 0;
-}
-
-static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->mirrorMask = 0;
-
- sd->vold.backlight = -1;
- sd->vold.brightness = -1;
- sd->vold.sharpness = -1;
- sd->vold.contrast = -1;
- sd->vold.saturation = -1;
- sd->vold.gamma = -1;
- sd->vold.hue = -1;
- sd->vold.whitebal = -1;
- sd->vold.mirror = -1;
- sd->vold.flip = -1;
-
- ov2640_init_post_alt(gspca_dev);
-
- return 0;
-}
-
-static int ov2640_init_post_alt(struct gspca_dev *gspca_dev)
-{
- s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
- s32 n; /* reserved for FETCH functions */
-
- ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
-
- n = fetch_validx(gspca_dev, tbl_sensor_settings_common1,
- ARRAY_SIZE(tbl_sensor_settings_common1));
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_post);
- common(gspca_dev);
- keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common1,
- ARRAY_SIZE(tbl_sensor_settings_common1), n);
-
- switch (reso) {
- case IMAGE_640:
- n = fetch_validx(gspca_dev, tbl_640, ARRAY_SIZE(tbl_640));
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_640);
- break;
-
- case IMAGE_800:
- n = fetch_validx(gspca_dev, tbl_800, ARRAY_SIZE(tbl_800));
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_800);
- break;
-
- case IMAGE_1600:
- case IMAGE_1280:
- n = fetch_validx(gspca_dev, tbl_big1, ARRAY_SIZE(tbl_big1));
-
- if (reso == IMAGE_1280) {
- n = fetch_validx(gspca_dev, tbl_big2,
- ARRAY_SIZE(tbl_big2));
- } else {
- ctrl_out(gspca_dev, 0x40, 1, 0x601d, 0x0086, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00d7, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6082, 0x00d3, 0, NULL);
- }
-
- n = fetch_validx(gspca_dev, tbl_big3, ARRAY_SIZE(tbl_big3));
-
- if (reso == IMAGE_1280) {
- ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
- 12, dat_1280);
- } else {
- ctrl_out(gspca_dev, 0x40, 1, 0x6020, 0x008c, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6076, 0x0018, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
- 12, dat_1600);
- }
- break;
- }
-
- n = fetch_validx(gspca_dev, tbl_sensor_settings_common2,
- ARRAY_SIZE(tbl_sensor_settings_common2));
-
- ov2640_camera_settings(gspca_dev);
-
- return 0;
-}
-
-static int ov2640_configure_alt(struct gspca_dev *gspca_dev)
-{
- s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
-
- switch (reso) {
- case IMAGE_640:
- gspca_dev->alt = 3 + 1;
- break;
-
- case IMAGE_800:
- case IMAGE_1280:
- case IMAGE_1600:
- gspca_dev->alt = 1 + 1;
- break;
- }
- return 0;
-}
-
-static int ov2640_camera_settings(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- s32 backlight = sd->vcur.backlight;
- s32 bright = sd->vcur.brightness;
- s32 sharp = sd->vcur.sharpness;
- s32 gam = sd->vcur.gamma;
- s32 cntr = sd->vcur.contrast;
- s32 sat = sd->vcur.saturation;
- s32 hue = sd->vcur.hue;
- s32 wbal = sd->vcur.whitebal;
- s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) == 0);
- s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) == 0);
-
- if (backlight != sd->vold.backlight) {
- /* No sd->vold.backlight=backlight; (to be done again later) */
- if (backlight < 0 || backlight > sd->vmax.backlight)
- backlight = 0;
-
- ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff,
- 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight , 0x0024,
- 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025,
- 0, NULL);
- }
-
- if (bright != sd->vold.brightness) {
- sd->vold.brightness = bright;
- if (bright < 0 || bright > sd->vmax.brightness)
- bright = 0;
-
- ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6009 , 0x007c, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6000 + bright, 0x007d, 0, NULL);
- }
-
- if (wbal != sd->vold.whitebal) {
- sd->vold.whitebal = wbal;
- if (wbal < 0 || wbal > sd->vmax.whitebal)
- wbal = 0;
-
- ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6003 , 0x007c, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6000 + wbal, 0x007d, 0, NULL);
- }
-
- if (cntr != sd->vold.contrast) {
- sd->vold.contrast = cntr;
- if (cntr < 0 || cntr > sd->vmax.contrast)
- cntr = 0;
-
- ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6007 , 0x007c, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6000 + cntr, 0x007d, 0, NULL);
- }
-
- if (sat != sd->vold.saturation) {
- sd->vold.saturation = sat;
- if (sat < 0 || sat > sd->vmax.saturation)
- sat = 0;
-
- ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x007c, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6000 + sat, 0x007d, 0, NULL);
- }
-
- if (sharp != sd->vold.sharpness) {
- sd->vold.sharpness = sharp;
- if (sharp < 0 || sharp > sd->vmax.sharpness)
- sharp = 0;
-
- ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x0092, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x60c0 + sharp, 0x0093, 0, NULL);
- }
-
- if (hue != sd->vold.hue) {
- sd->vold.hue = hue;
- if (hue < 0 || hue > sd->vmax.hue)
- hue = 0;
-
- ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6002 , 0x007c, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d,
- 0, NULL);
- if (hue >= 255)
- sd->swapRB = 1;
- else
- sd->swapRB = 0;
- }
-
- if (gam != sd->vold.gamma) {
- sd->vold.gamma = gam;
- if (gam < 0 || gam > sd->vmax.gamma)
- gam = 0;
-
- ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6008 , 0x007c, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL);
- }
-
- if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
- sd->vold.mirror = mirror;
- sd->vold.flip = flip;
-
- mirror = 0x80 * mirror;
- ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL);
- ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28);
- ctrl_out(gspca_dev, 0x40, 1, 0x6028 + mirror, 0x0004, 0, NULL);
-
- flip = 0x50 * flip + mirror;
- ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL);
- ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8);
- ctrl_out(gspca_dev, 0x40, 1, 0x6028 + flip, 0x0004, 0, NULL);
-
- ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
- }
-
- if (backlight != sd->vold.backlight) {
- sd->vold.backlight = backlight;
-
- ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff,
- 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight , 0x0024,
- 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025,
- 0, NULL);
- }
-
- return 0;
-}
-
-static void ov2640_post_unset_alt(struct gspca_dev *gspca_dev)
-{
- ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
- msleep(20);
- fetch_validx(gspca_dev, tbl_post_unset_alt,
- ARRAY_SIZE(tbl_post_unset_alt));
-}
diff --git a/drivers/media/video/gspca/gl860/gl860-ov9655.c b/drivers/media/video/gspca/gl860/gl860-ov9655.c
deleted file mode 100644
index 5ae9619d72a..00000000000
--- a/drivers/media/video/gspca/gl860/gl860-ov9655.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* Subdriver for the GL860 chip with the OV9655 sensor
- * Author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt
- * on dsd's weblog
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Sensor : OV9655 */
-
-#include "gl860.h"
-
-static struct validx tbl_init_at_startup[] = {
- {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
- {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
-
- {0x0040, 0x0000},
-};
-
-static struct validx tbl_commmon[] = {
- {0x0041, 0x0000}, {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d},
- {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2},
- {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0040, 0x0000},
- {0x00f3, 0x0006}, {0x0058, 0x0000}, {0x0048, 0x0000}, {0x0061, 0x0000},
-};
-
-static s32 tbl_length[] = {12, 56, 52, 54, 56, 42, 32, 12};
-
-static u8 *tbl_640[] = {
- "\x00\x40\x07\x6a\x06\xf3\x0d\x6a" "\x10\x10\xc1\x01"
- ,
- "\x12\x80\x00\x00\x01\x98\x02\x80" "\x03\x12\x04\x03\x0b\x57\x0e\x61"
- "\x0f\x42\x11\x01\x12\x60\x13\x00" "\x14\x3a\x16\x24\x17\x14\x18\x00"
- "\x19\x01\x1a\x3d\x1e\x04\x24\x3c" "\x25\x36\x26\x72\x27\x08\x28\x08"
- "\x29\x15\x2a\x00\x2b\x00\x2c\x08"
- ,
- "\x32\xff\x33\x00\x34\x3d\x35\x00" "\x36\xfa\x38\x72\x39\x57\x3a\x00"
- "\x3b\x0c\x3d\x99\x3e\x0c\x3f\xc1" "\x40\xc0\x41\x00\x42\xc0\x43\x0a"
- "\x44\xf0\x45\x46\x46\x62\x47\x2a" "\x48\x3c\x4a\xee\x4b\xe7\x4c\xe7"
- "\x4d\xe7\x4e\xe7"
- ,
- "\x4f\x98\x50\x98\x51\x00\x52\x28" "\x53\x70\x54\x98\x58\x1a\x59\x85"
- "\x5a\xa9\x5b\x64\x5c\x84\x5d\x53" "\x5e\x0e\x5f\xf0\x60\xf0\x61\xf0"
- "\x62\x00\x63\x00\x64\x02\x65\x20" "\x66\x00\x69\x0a\x6b\x5a\x6c\x04"
- "\x6d\x55\x6e\x00\x6f\x9d"
- ,
- "\x70\x15\x71\x78\x72\x00\x73\x00" "\x74\x3a\x75\x35\x76\x01\x77\x02"
- "\x7a\x24\x7b\x04\x7c\x07\x7d\x10" "\x7e\x28\x7f\x36\x80\x44\x81\x52"
- "\x82\x60\x83\x6c\x84\x78\x85\x8c" "\x86\x9e\x87\xbb\x88\xd2\x89\xe5"
- "\x8a\x23\x8c\x8d\x90\x7c\x91\x7b"
- ,
- "\x9d\x02\x9e\x02\x9f\x74\xa0\x73" "\xa1\x40\xa4\x50\xa5\x68\xa6\x70"
- "\xa8\xc1\xa9\xef\xaa\x92\xab\x04" "\xac\x80\xad\x80\xae\x80\xaf\x80"
- "\xb2\xf2\xb3\x20\xb4\x20\xb5\x00" "\xb6\xaf"
- ,
- "\xbb\xae\xbc\x4f\xbd\x4e\xbe\x6a" "\xbf\x68\xc0\xaa\xc1\xc0\xc2\x01"
- "\xc3\x4e\xc6\x85\xc7\x81\xc9\xe0" "\xca\xe8\xcb\xf0\xcc\xd8\xcd\x93"
- ,
- "\xd0\x01\xd1\x08\xd2\xe0\xd3\x01" "\xd4\x10\xd5\x80"
-};
-
-static u8 *tbl_1280[] = {
- "\x00\x40\x07\x6a\x06\xf3\x0d\x6a" "\x10\x10\xc1\x01"
- ,
- "\x12\x80\x00\x00\x01\x98\x02\x80" "\x03\x12\x04\x01\x0b\x57\x0e\x61"
- "\x0f\x42\x11\x00\x12\x00\x13\x00" "\x14\x3a\x16\x24\x17\x1b\x18\xbb"
- "\x19\x01\x1a\x81\x1e\x04\x24\x3c" "\x25\x36\x26\x72\x27\x08\x28\x08"
- "\x29\x15\x2a\x00\x2b\x00\x2c\x08"
- ,
- "\x32\xa4\x33\x00\x34\x3d\x35\x00" "\x36\xf8\x38\x72\x39\x57\x3a\x00"
- "\x3b\x0c\x3d\x99\x3e\x0c\x3f\xc2" "\x40\xc0\x41\x00\x42\xc0\x43\x0a"
- "\x44\xf0\x45\x46\x46\x62\x47\x2a" "\x48\x3c\x4a\xec\x4b\xe8\x4c\xe8"
- "\x4d\xe8\x4e\xe8"
- ,
- "\x4f\x98\x50\x98\x51\x00\x52\x28" "\x53\x70\x54\x98\x58\x1a\x59\x85"
- "\x5a\xa9\x5b\x64\x5c\x84\x5d\x53" "\x5e\x0e\x5f\xf0\x60\xf0\x61\xf0"
- "\x62\x00\x63\x00\x64\x02\x65\x20" "\x66\x00\x69\x02\x6b\x5a\x6c\x04"
- "\x6d\x55\x6e\x00\x6f\x9d"
- ,
- "\x70\x08\x71\x78\x72\x00\x73\x01" "\x74\x3a\x75\x35\x76\x01\x77\x02"
- "\x7a\x24\x7b\x04\x7c\x07\x7d\x10" "\x7e\x28\x7f\x36\x80\x44\x81\x52"
- "\x82\x60\x83\x6c\x84\x78\x85\x8c" "\x86\x9e\x87\xbb\x88\xd2\x89\xe5"
- "\x8a\x23\x8c\x0d\x90\x90\x91\x90"
- ,
- "\x9d\x02\x9e\x02\x9f\x94\xa0\x94" "\xa1\x01\xa4\x50\xa5\x68\xa6\x70"
- "\xa8\xc1\xa9\xef\xaa\x92\xab\x04" "\xac\x80\xad\x80\xae\x80\xaf\x80"
- "\xb2\xf2\xb3\x20\xb4\x20\xb5\x00" "\xb6\xaf"
- ,
- "\xbb\xae\xbc\x38\xbd\x39\xbe\x01" "\xbf\x01\xc0\xe2\xc1\xc0\xc2\x01"
- "\xc3\x4e\xc6\x85\xc7\x81\xc9\xe0" "\xca\xe8\xcb\xf0\xcc\xd8\xcd\x93"
- ,
- "\xd0\x21\xd1\x18\xd2\xe0\xd3\x01" "\xd4\x28\xd5\x00"
-};
-
-static u8 c04[] = {0x04};
-static u8 dat_post1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02";
-static u8 dat_post2[] = "\x10\x10\xc1\x02";
-static u8 dat_post3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04";
-static u8 dat_post4[] = "\x10\x02\xc1\x06";
-static u8 dat_post5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08";
-static u8 dat_post6[] = "\x10\x10\xc1\x05";
-static u8 dat_post7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08";
-static u8 dat_post8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09";
-
-static struct validx tbl_init_post_alt[] = {
- {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x603c, 0x00ff},
- {0x6003, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6001, 0x00ff},
- {0x6000, 0x801e},
- {0xffff, 0xffff},
- {0x6004, 0x001e}, {0x6000, 0x801e},
- {0xffff, 0xffff},
- {0x6004, 0x001e}, {0x6012, 0x0003}, {0x6000, 0x801e},
- {0xffff, 0xffff},
- {0x6004, 0x001e}, {0x6000, 0x801e},
- {0xffff, 0xffff},
- {0x6004, 0x001e}, {0x6012, 0x0003},
- {0xffff, 0xffff},
- {0x6000, 0x801e},
- {0xffff, 0xffff},
- {0x6004, 0x001e}, {0x6000, 0x801e},
- {0xffff, 0xffff},
- {0x6004, 0x001e}, {0x6012, 0x0003}, {0x6000, 0x801e},
- {0xffff, 0xffff},
- {0x6004, 0x001e}, {0x6000, 0x801e},
- {0xffff, 0xffff},
- {0x6004, 0x001e}, {0x6012, 0x0003},
- {0xffff, 0xffff},
- {0x6000, 0x801e},
- {0xffff, 0xffff},
- {0x6004, 0x001e}, {0x6000, 0x801e},
- {0xffff, 0xffff},
- {0x6004, 0x001e}, {0x6012, 0x0003},
-};
-
-static int ov9655_init_at_startup(struct gspca_dev *gspca_dev);
-static int ov9655_configure_alt(struct gspca_dev *gspca_dev);
-static int ov9655_init_pre_alt(struct gspca_dev *gspca_dev);
-static int ov9655_init_post_alt(struct gspca_dev *gspca_dev);
-static void ov9655_post_unset_alt(struct gspca_dev *gspca_dev);
-static int ov9655_camera_settings(struct gspca_dev *gspca_dev);
-/*==========================================================================*/
-
-void ov9655_init_settings(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->vcur.backlight = 0;
- sd->vcur.brightness = 128;
- sd->vcur.sharpness = 0;
- sd->vcur.contrast = 0;
- sd->vcur.gamma = 0;
- sd->vcur.hue = 0;
- sd->vcur.saturation = 0;
- sd->vcur.whitebal = 0;
-
- sd->vmax.backlight = 0;
- sd->vmax.brightness = 255;
- sd->vmax.sharpness = 0;
- sd->vmax.contrast = 0;
- sd->vmax.gamma = 0;
- sd->vmax.hue = 0 + 1;
- sd->vmax.saturation = 0;
- sd->vmax.whitebal = 0;
- sd->vmax.mirror = 0;
- sd->vmax.flip = 0;
- sd->vmax.AC50Hz = 0;
-
- sd->dev_camera_settings = ov9655_camera_settings;
- sd->dev_init_at_startup = ov9655_init_at_startup;
- sd->dev_configure_alt = ov9655_configure_alt;
- sd->dev_init_pre_alt = ov9655_init_pre_alt;
- sd->dev_post_unset_alt = ov9655_post_unset_alt;
-}
-
-/*==========================================================================*/
-
-static int ov9655_init_at_startup(struct gspca_dev *gspca_dev)
-{
- fetch_validx(gspca_dev, tbl_init_at_startup,
- ARRAY_SIZE(tbl_init_at_startup));
- fetch_validx(gspca_dev, tbl_commmon, ARRAY_SIZE(tbl_commmon));
-/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL);*/
-
- return 0;
-}
-
-static int ov9655_init_pre_alt(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->vold.brightness = -1;
- sd->vold.hue = -1;
-
- fetch_validx(gspca_dev, tbl_commmon, ARRAY_SIZE(tbl_commmon));
-
- ov9655_init_post_alt(gspca_dev);
-
- return 0;
-}
-
-static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
-{
- s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
- s32 n; /* reserved for FETCH functions */
- s32 i;
- u8 **tbl;
-
- ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
-
- tbl = (reso == IMAGE_640) ? tbl_640 : tbl_1280;
-
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
- tbl_length[0], tbl[0]);
- for (i = 1; i < 7; i++)
- ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200,
- tbl_length[i], tbl[i]);
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
- tbl_length[7], tbl[7]);
-
- n = fetch_validx(gspca_dev, tbl_init_post_alt,
- ARRAY_SIZE(tbl_init_post_alt));
-
- ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
- keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
- ARRAY_SIZE(tbl_init_post_alt), n);
- ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
- keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
- ARRAY_SIZE(tbl_init_post_alt), n);
- ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
- keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
- ARRAY_SIZE(tbl_init_post_alt), n);
- ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
- keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
- ARRAY_SIZE(tbl_init_post_alt), n);
- ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
- keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
- ARRAY_SIZE(tbl_init_post_alt), n);
-
- ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
- keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
- ARRAY_SIZE(tbl_init_post_alt), n);
- ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
- keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
- ARRAY_SIZE(tbl_init_post_alt), n);
- ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
- keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
- ARRAY_SIZE(tbl_init_post_alt), n);
- ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
- keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
- ARRAY_SIZE(tbl_init_post_alt), n);
- ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
- keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
- ARRAY_SIZE(tbl_init_post_alt), n);
-
- ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
- keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
- ARRAY_SIZE(tbl_init_post_alt), n);
- ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
- keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
- ARRAY_SIZE(tbl_init_post_alt), n);
-
- ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
-
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post2);
- ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post3);
-
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post4);
- ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post5);
-
- ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post6);
- ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post7);
-
- ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post8);
-
- ov9655_camera_settings(gspca_dev);
-
- return 0;
-}
-
-static int ov9655_configure_alt(struct gspca_dev *gspca_dev)
-{
- s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
-
- switch (reso) {
- case IMAGE_640:
- gspca_dev->alt = 1 + 1;
- break;
-
- default:
- gspca_dev->alt = 1 + 1;
- break;
- }
- return 0;
-}
-
-static int ov9655_camera_settings(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- u8 dat_bright[] = "\x04\x00\x10\x7c\xa1\x00\x00\x70";
-
- s32 bright = sd->vcur.brightness;
- s32 hue = sd->vcur.hue;
-
- if (bright != sd->vold.brightness) {
- sd->vold.brightness = bright;
- if (bright < 0 || bright > sd->vmax.brightness)
- bright = 0;
-
- dat_bright[3] = bright;
- ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_bright);
- }
-
- if (hue != sd->vold.hue) {
- sd->vold.hue = hue;
- sd->swapRB = (hue != 0);
- }
-
- return 0;
-}
-
-static void ov9655_post_unset_alt(struct gspca_dev *gspca_dev)
-{
- ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0061, 0x0000, 0, NULL);
-}
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c
deleted file mode 100644
index ced3b71f14e..00000000000
--- a/drivers/media/video/gspca/gl860/gl860.c
+++ /dev/null
@@ -1,725 +0,0 @@
-/* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip
- * Subdriver core
- *
- * 2009/09/24 Olivier Lorin <o.lorin@laposte.net>
- * GSPCA by Jean-Francois Moine <http://moinejf.free.fr>
- * Thanks BUGabundo and Malmostoso for your amazing help!
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "gspca.h"
-#include "gl860.h"
-
-MODULE_AUTHOR("Olivier Lorin <o.lorin@laposte.net>");
-MODULE_DESCRIPTION("Genesys Logic USB PC Camera Driver");
-MODULE_LICENSE("GPL");
-
-/*======================== static function declarations ====================*/
-
-static void (*dev_init_settings)(struct gspca_dev *gspca_dev);
-
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id);
-static int sd_init(struct gspca_dev *gspca_dev);
-static int sd_isoc_init(struct gspca_dev *gspca_dev);
-static int sd_start(struct gspca_dev *gspca_dev);
-static void sd_stop0(struct gspca_dev *gspca_dev);
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, int len);
-static void sd_callback(struct gspca_dev *gspca_dev);
-
-static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
- u16 vendor_id, u16 product_id);
-
-/*============================ driver options ==============================*/
-
-static s32 AC50Hz = 0xff;
-module_param(AC50Hz, int, 0644);
-MODULE_PARM_DESC(AC50Hz, " Does AC power frequency is 50Hz? (0/1)");
-
-static char sensor[7];
-module_param_string(sensor, sensor, sizeof(sensor), 0644);
-MODULE_PARM_DESC(sensor,
- " Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640')");
-
-/*============================ webcam controls =============================*/
-
-/* Functions to get and set a control value */
-#define SD_SETGET(thename) \
-static int sd_set_##thename(struct gspca_dev *gspca_dev, s32 val)\
-{\
- struct sd *sd = (struct sd *) gspca_dev;\
-\
- sd->vcur.thename = val;\
- if (gspca_dev->streaming)\
- sd->waitSet = 1;\
- return 0;\
-} \
-static int sd_get_##thename(struct gspca_dev *gspca_dev, s32 *val)\
-{\
- struct sd *sd = (struct sd *) gspca_dev;\
-\
- *val = sd->vcur.thename;\
- return 0;\
-}
-
-SD_SETGET(mirror)
-SD_SETGET(flip)
-SD_SETGET(AC50Hz)
-SD_SETGET(backlight)
-SD_SETGET(brightness)
-SD_SETGET(gamma)
-SD_SETGET(hue)
-SD_SETGET(saturation)
-SD_SETGET(sharpness)
-SD_SETGET(whitebal)
-SD_SETGET(contrast)
-
-#define GL860_NCTRLS 11
-
-/* control table */
-static struct ctrl sd_ctrls_mi1320[GL860_NCTRLS];
-static struct ctrl sd_ctrls_mi2020[GL860_NCTRLS];
-static struct ctrl sd_ctrls_ov2640[GL860_NCTRLS];
-static struct ctrl sd_ctrls_ov9655[GL860_NCTRLS];
-
-#define SET_MY_CTRL(theid, \
- thetype, thelabel, thename) \
- if (sd->vmax.thename != 0) {\
- sd_ctrls[nCtrls].qctrl.id = theid;\
- sd_ctrls[nCtrls].qctrl.type = thetype;\
- strcpy(sd_ctrls[nCtrls].qctrl.name, thelabel);\
- sd_ctrls[nCtrls].qctrl.minimum = 0;\
- sd_ctrls[nCtrls].qctrl.maximum = sd->vmax.thename;\
- sd_ctrls[nCtrls].qctrl.default_value = sd->vcur.thename;\
- sd_ctrls[nCtrls].qctrl.step = \
- (sd->vmax.thename < 16) ? 1 : sd->vmax.thename/16;\
- sd_ctrls[nCtrls].set = sd_set_##thename;\
- sd_ctrls[nCtrls].get = sd_get_##thename;\
- nCtrls++;\
- }
-
-static int gl860_build_control_table(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct ctrl *sd_ctrls;
- int nCtrls = 0;
-
- if (_MI1320_)
- sd_ctrls = sd_ctrls_mi1320;
- else if (_MI2020_)
- sd_ctrls = sd_ctrls_mi2020;
- else if (_OV2640_)
- sd_ctrls = sd_ctrls_ov2640;
- else if (_OV9655_)
- sd_ctrls = sd_ctrls_ov9655;
- else
- return 0;
-
- memset(sd_ctrls, 0, GL860_NCTRLS * sizeof(struct ctrl));
-
- SET_MY_CTRL(V4L2_CID_BRIGHTNESS,
- V4L2_CTRL_TYPE_INTEGER, "Brightness", brightness)
- SET_MY_CTRL(V4L2_CID_SHARPNESS,
- V4L2_CTRL_TYPE_INTEGER, "Sharpness", sharpness)
- SET_MY_CTRL(V4L2_CID_CONTRAST,
- V4L2_CTRL_TYPE_INTEGER, "Contrast", contrast)
- SET_MY_CTRL(V4L2_CID_GAMMA,
- V4L2_CTRL_TYPE_INTEGER, "Gamma", gamma)
- SET_MY_CTRL(V4L2_CID_HUE,
- V4L2_CTRL_TYPE_INTEGER, "Palette", hue)
- SET_MY_CTRL(V4L2_CID_SATURATION,
- V4L2_CTRL_TYPE_INTEGER, "Saturation", saturation)
- SET_MY_CTRL(V4L2_CID_WHITE_BALANCE_TEMPERATURE,
- V4L2_CTRL_TYPE_INTEGER, "White Bal.", whitebal)
- SET_MY_CTRL(V4L2_CID_BACKLIGHT_COMPENSATION,
- V4L2_CTRL_TYPE_INTEGER, "Backlight" , backlight)
-
- SET_MY_CTRL(V4L2_CID_HFLIP,
- V4L2_CTRL_TYPE_BOOLEAN, "Mirror", mirror)
- SET_MY_CTRL(V4L2_CID_VFLIP,
- V4L2_CTRL_TYPE_BOOLEAN, "Flip", flip)
- SET_MY_CTRL(V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CTRL_TYPE_BOOLEAN, "AC power 50Hz", AC50Hz)
-
- return nCtrls;
-}
-
-/*==================== sud-driver structure initialisation =================*/
-
-static const struct sd_desc sd_desc_mi1320 = {
- .name = MODULE_NAME,
- .ctrls = sd_ctrls_mi1320,
- .nctrls = GL860_NCTRLS,
- .config = sd_config,
- .init = sd_init,
- .isoc_init = sd_isoc_init,
- .start = sd_start,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
- .dq_callback = sd_callback,
-};
-
-static const struct sd_desc sd_desc_mi2020 = {
- .name = MODULE_NAME,
- .ctrls = sd_ctrls_mi2020,
- .nctrls = GL860_NCTRLS,
- .config = sd_config,
- .init = sd_init,
- .isoc_init = sd_isoc_init,
- .start = sd_start,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
- .dq_callback = sd_callback,
-};
-
-static const struct sd_desc sd_desc_ov2640 = {
- .name = MODULE_NAME,
- .ctrls = sd_ctrls_ov2640,
- .nctrls = GL860_NCTRLS,
- .config = sd_config,
- .init = sd_init,
- .isoc_init = sd_isoc_init,
- .start = sd_start,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
- .dq_callback = sd_callback,
-};
-
-static const struct sd_desc sd_desc_ov9655 = {
- .name = MODULE_NAME,
- .ctrls = sd_ctrls_ov9655,
- .nctrls = GL860_NCTRLS,
- .config = sd_config,
- .init = sd_init,
- .isoc_init = sd_isoc_init,
- .start = sd_start,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
- .dq_callback = sd_callback,
-};
-
-/*=========================== sub-driver image sizes =======================*/
-
-static struct v4l2_pix_format mi2020_mode[] = {
- { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- },
- { 800, 598, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 800,
- .sizeimage = 800 * 598,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- },
- {1280, 1024, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 1280,
- .sizeimage = 1280 * 1024,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2
- },
- {1600, 1198, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 1600,
- .sizeimage = 1600 * 1198,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 3
- },
-};
-
-static struct v4l2_pix_format ov2640_mode[] = {
- { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- },
- { 800, 600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 800,
- .sizeimage = 800 * 600,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- },
- {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 1280,
- .sizeimage = 1280 * 960,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2
- },
- {1600, 1200, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 1600,
- .sizeimage = 1600 * 1200,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 3
- },
-};
-
-static struct v4l2_pix_format mi1320_mode[] = {
- { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- },
- { 800, 600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 800,
- .sizeimage = 800 * 600,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- },
- {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 1280,
- .sizeimage = 1280 * 960,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2
- },
-};
-
-static struct v4l2_pix_format ov9655_mode[] = {
- { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- },
- {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 1280,
- .sizeimage = 1280 * 960,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- },
-};
-
-/*========================= sud-driver functions ===========================*/
-
-/* This function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
- u16 vendor_id, product_id;
-
- /* Get USB VendorID and ProductID */
- vendor_id = id->idVendor;
- product_id = id->idProduct;
-
- sd->nbRightUp = 1;
- sd->nbIm = -1;
-
- sd->sensor = 0xff;
- if (strcmp(sensor, "MI1320") == 0)
- sd->sensor = ID_MI1320;
- else if (strcmp(sensor, "OV2640") == 0)
- sd->sensor = ID_OV2640;
- else if (strcmp(sensor, "OV9655") == 0)
- sd->sensor = ID_OV9655;
- else if (strcmp(sensor, "MI2020") == 0)
- sd->sensor = ID_MI2020;
-
- /* Get sensor and set the suitable init/start/../stop functions */
- if (gl860_guess_sensor(gspca_dev, vendor_id, product_id) == -1)
- return -1;
-
- cam = &gspca_dev->cam;
-
- switch (sd->sensor) {
- case ID_MI1320:
- gspca_dev->sd_desc = &sd_desc_mi1320;
- cam->cam_mode = mi1320_mode;
- cam->nmodes = ARRAY_SIZE(mi1320_mode);
- dev_init_settings = mi1320_init_settings;
- break;
-
- case ID_MI2020:
- gspca_dev->sd_desc = &sd_desc_mi2020;
- cam->cam_mode = mi2020_mode;
- cam->nmodes = ARRAY_SIZE(mi2020_mode);
- dev_init_settings = mi2020_init_settings;
- break;
-
- case ID_OV2640:
- gspca_dev->sd_desc = &sd_desc_ov2640;
- cam->cam_mode = ov2640_mode;
- cam->nmodes = ARRAY_SIZE(ov2640_mode);
- dev_init_settings = ov2640_init_settings;
- break;
-
- case ID_OV9655:
- gspca_dev->sd_desc = &sd_desc_ov9655;
- cam->cam_mode = ov9655_mode;
- cam->nmodes = ARRAY_SIZE(ov9655_mode);
- dev_init_settings = ov9655_init_settings;
- break;
- }
-
- dev_init_settings(gspca_dev);
- if (AC50Hz != 0xff)
- ((struct sd *) gspca_dev)->vcur.AC50Hz = AC50Hz;
- gl860_build_control_table(gspca_dev);
-
- return 0;
-}
-
-/* This function is called at probe time after sd_config */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- return sd->dev_init_at_startup(gspca_dev);
-}
-
-/* This function is called before to choose the alt setting */
-static int sd_isoc_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- return sd->dev_configure_alt(gspca_dev);
-}
-
-/* This function is called to start the webcam */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- return sd->dev_init_pre_alt(gspca_dev);
-}
-
-/* This function is called to stop the webcam */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (!sd->gspca_dev.present)
- return;
-
- return sd->dev_post_unset_alt(gspca_dev);
-}
-
-/* This function is called when an image is being received */
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- static s32 nSkipped;
-
- s32 mode = (s32) gspca_dev->curr_mode;
- s32 nToSkip =
- sd->swapRB * (gspca_dev->cam.cam_mode[mode].bytesperline + 1);
-
- /* Test only against 0202h, so endianess does not matter */
- switch (*(s16 *) data) {
- case 0x0202: /* End of frame, start a new one */
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
- nSkipped = 0;
- if (sd->nbIm >= 0 && sd->nbIm < 10)
- sd->nbIm++;
- gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
- break;
-
- default:
- data += 2;
- len -= 2;
- if (nSkipped + len <= nToSkip)
- nSkipped += len;
- else {
- if (nSkipped < nToSkip && nSkipped + len > nToSkip) {
- data += nToSkip - nSkipped;
- len -= nToSkip - nSkipped;
- nSkipped = nToSkip + 1;
- }
- gspca_frame_add(gspca_dev,
- INTER_PACKET, data, len);
- }
- break;
- }
-}
-
-/* This function is called when an image has been read */
-/* This function is used to monitor webcam orientation */
-static void sd_callback(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (!_OV9655_) {
- u8 state;
- u8 upsideDown;
-
- /* Probe sensor orientation */
- ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, (void *)&state);
-
- /* C8/40 means upside-down (looking backwards) */
- /* D8/50 means right-up (looking onwards) */
- upsideDown = (state == 0xc8 || state == 0x40);
-
- if (upsideDown && sd->nbRightUp > -4) {
- if (sd->nbRightUp > 0)
- sd->nbRightUp = 0;
- if (sd->nbRightUp == -3) {
- sd->mirrorMask = 1;
- sd->waitSet = 1;
- }
- sd->nbRightUp--;
- }
- if (!upsideDown && sd->nbRightUp < 4) {
- if (sd->nbRightUp < 0)
- sd->nbRightUp = 0;
- if (sd->nbRightUp == 3) {
- sd->mirrorMask = 0;
- sd->waitSet = 1;
- }
- sd->nbRightUp++;
- }
- }
-
- if (sd->waitSet)
- sd->dev_camera_settings(gspca_dev);
-}
-
-/*=================== USB driver structure initialisation ==================*/
-
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x05e3, 0x0503)},
- {USB_DEVICE(0x05e3, 0xf191)},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id,
- &sd_desc_mi1320, sizeof(struct sd), THIS_MODULE);
-}
-
-static void sd_disconnect(struct usb_interface *intf)
-{
- gspca_disconnect(intf);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = sd_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-/*====================== Init and Exit module functions ====================*/
-
-module_usb_driver(sd_driver);
-
-/*==========================================================================*/
-
-int gl860_RTx(struct gspca_dev *gspca_dev,
- unsigned char pref, u32 req, u16 val, u16 index,
- s32 len, void *pdata)
-{
- struct usb_device *udev = gspca_dev->dev;
- s32 r = 0;
-
- if (pref == 0x40) { /* Send */
- if (len > 0) {
- memcpy(gspca_dev->usb_buf, pdata, len);
- r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- req, pref, val, index,
- gspca_dev->usb_buf,
- len, 400 + 200 * (len > 1));
- } else {
- r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- req, pref, val, index, NULL, len, 400);
- }
- } else { /* Receive */
- if (len > 0) {
- r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- req, pref, val, index,
- gspca_dev->usb_buf,
- len, 400 + 200 * (len > 1));
- memcpy(pdata, gspca_dev->usb_buf, len);
- } else {
- r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- req, pref, val, index, NULL, len, 400);
- }
- }
-
- if (r < 0)
- pr_err("ctrl transfer failed %4d [p%02x r%d v%04x i%04x len%d]\n",
- r, pref, req, val, index, len);
- else if (len > 1 && r < len)
- PDEBUG(D_ERR, "short ctrl transfer %d/%d", r, len);
-
- msleep(1);
-
- return r;
-}
-
-int fetch_validx(struct gspca_dev *gspca_dev, struct validx *tbl, int len)
-{
- int n;
-
- for (n = 0; n < len; n++) {
- if (tbl[n].idx != 0xffff)
- ctrl_out(gspca_dev, 0x40, 1, tbl[n].val,
- tbl[n].idx, 0, NULL);
- else if (tbl[n].val == 0xffff)
- break;
- else
- msleep(tbl[n].val);
- }
- return n;
-}
-
-int keep_on_fetching_validx(struct gspca_dev *gspca_dev, struct validx *tbl,
- int len, int n)
-{
- while (++n < len) {
- if (tbl[n].idx != 0xffff)
- ctrl_out(gspca_dev, 0x40, 1, tbl[n].val, tbl[n].idx,
- 0, NULL);
- else if (tbl[n].val == 0xffff)
- break;
- else
- msleep(tbl[n].val);
- }
- return n;
-}
-
-void fetch_idxdata(struct gspca_dev *gspca_dev, struct idxdata *tbl, int len)
-{
- int n;
-
- for (n = 0; n < len; n++) {
- if (memcmp(tbl[n].data, "\xff\xff\xff", 3) != 0)
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, tbl[n].idx,
- 3, tbl[n].data);
- else
- msleep(tbl[n].idx);
- }
-}
-
-static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
- u16 vendor_id, u16 product_id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 probe, nb26, nb96, nOV, ntry;
-
- if (product_id == 0xf191)
- sd->sensor = ID_MI1320;
-
- if (sd->sensor == 0xff) {
- ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &probe);
- ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &probe);
-
- ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x0000, 0, NULL);
- msleep(3);
- ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
- msleep(3);
- ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x00c0, 0, NULL);
- msleep(3);
- ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x00c1, 0, NULL);
- msleep(3);
- ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x00c2, 0, NULL);
- msleep(3);
- ctrl_out(gspca_dev, 0x40, 1, 0x0020, 0x0006, 0, NULL);
- msleep(3);
- ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
- msleep(56);
-
- PDEBUG(D_PROBE, "probing for sensor MI2020 or OVXXXX");
- nOV = 0;
- for (ntry = 0; ntry < 4; ntry++) {
- ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
- msleep(3);
- ctrl_out(gspca_dev, 0x40, 1, 0x0063, 0x0006, 0, NULL);
- msleep(3);
- ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL);
- msleep(10);
- ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe);
- PDEBUG(D_PROBE, "probe=0x%02x", probe);
- if (probe == 0xff)
- nOV++;
- }
-
- if (nOV) {
- PDEBUG(D_PROBE, "0xff -> OVXXXX");
- PDEBUG(D_PROBE, "probing for sensor OV2640 or OV9655");
-
- nb26 = nb96 = 0;
- for (ntry = 0; ntry < 4; ntry++) {
- ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000,
- 0, NULL);
- msleep(3);
- ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x800a,
- 0, NULL);
- msleep(10);
-
- /* Wait for 26(OV2640) or 96(OV9655) */
- ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x800a,
- 1, &probe);
-
- if (probe == 0x26 || probe == 0x40) {
- PDEBUG(D_PROBE,
- "probe=0x%02x -> OV2640",
- probe);
- sd->sensor = ID_OV2640;
- nb26 += 4;
- break;
- }
- if (probe == 0x96 || probe == 0x55) {
- PDEBUG(D_PROBE,
- "probe=0x%02x -> OV9655",
- probe);
- sd->sensor = ID_OV9655;
- nb96 += 4;
- break;
- }
- PDEBUG(D_PROBE, "probe=0x%02x", probe);
- if (probe == 0x00)
- nb26++;
- if (probe == 0xff)
- nb96++;
- msleep(3);
- }
- if (nb26 < 4 && nb96 < 4)
- return -1;
- } else {
- PDEBUG(D_PROBE, "Not any 0xff -> MI2020");
- sd->sensor = ID_MI2020;
- }
- }
-
- if (_MI1320_) {
- PDEBUG(D_PROBE, "05e3:f191 sensor MI1320 (1.3M)");
- } else if (_MI2020_) {
- PDEBUG(D_PROBE, "05e3:0503 sensor MI2020 (2.0M)");
- } else if (_OV9655_) {
- PDEBUG(D_PROBE, "05e3:0503 sensor OV9655 (1.3M)");
- } else if (_OV2640_) {
- PDEBUG(D_PROBE, "05e3:0503 sensor OV2640 (2.0M)");
- } else {
- PDEBUG(D_PROBE, "***** Unknown sensor *****");
- return -1;
- }
-
- return 0;
-}
diff --git a/drivers/media/video/gspca/gl860/gl860.h b/drivers/media/video/gspca/gl860/gl860.h
deleted file mode 100644
index 0330a0293b9..00000000000
--- a/drivers/media/video/gspca/gl860/gl860.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip
- * Subdriver declarations
- *
- * 2009/10/14 Olivier LORIN <o.lorin@laposte.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef GL860_DEV_H
-#define GL860_DEV_H
-
-#include "gspca.h"
-
-#define MODULE_NAME "gspca_gl860"
-#define DRIVER_VERSION "0.9d10"
-
-#define ctrl_in gl860_RTx
-#define ctrl_out gl860_RTx
-
-#define ID_MI1320 1
-#define ID_OV2640 2
-#define ID_OV9655 4
-#define ID_MI2020 8
-
-#define _MI1320_ (((struct sd *) gspca_dev)->sensor == ID_MI1320)
-#define _MI2020_ (((struct sd *) gspca_dev)->sensor == ID_MI2020)
-#define _OV2640_ (((struct sd *) gspca_dev)->sensor == ID_OV2640)
-#define _OV9655_ (((struct sd *) gspca_dev)->sensor == ID_OV9655)
-
-#define IMAGE_640 0
-#define IMAGE_800 1
-#define IMAGE_1280 2
-#define IMAGE_1600 3
-
-struct sd_gl860 {
- u16 backlight;
- u16 brightness;
- u16 sharpness;
- u16 contrast;
- u16 gamma;
- u16 hue;
- u16 saturation;
- u16 whitebal;
- u8 mirror;
- u8 flip;
- u8 AC50Hz;
-};
-
-/* Specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- struct sd_gl860 vcur;
- struct sd_gl860 vold;
- struct sd_gl860 vmax;
-
- int (*dev_configure_alt) (struct gspca_dev *);
- int (*dev_init_at_startup)(struct gspca_dev *);
- int (*dev_init_pre_alt) (struct gspca_dev *);
- void (*dev_post_unset_alt) (struct gspca_dev *);
- int (*dev_camera_settings)(struct gspca_dev *);
-
- u8 swapRB;
- u8 mirrorMask;
- u8 sensor;
- s32 nbIm;
- s32 nbRightUp;
- u8 waitSet;
-};
-
-struct validx {
- u16 val;
- u16 idx;
-};
-
-struct idxdata {
- u8 idx;
- u8 data[3];
-};
-
-int fetch_validx(struct gspca_dev *gspca_dev, struct validx *tbl, int len);
-int keep_on_fetching_validx(struct gspca_dev *gspca_dev, struct validx *tbl,
- int len, int n);
-void fetch_idxdata(struct gspca_dev *gspca_dev, struct idxdata *tbl, int len);
-
-int gl860_RTx(struct gspca_dev *gspca_dev,
- unsigned char pref, u32 req, u16 val, u16 index,
- s32 len, void *pdata);
-
-void mi1320_init_settings(struct gspca_dev *);
-void ov2640_init_settings(struct gspca_dev *);
-void ov9655_init_settings(struct gspca_dev *);
-void mi2020_init_settings(struct gspca_dev *);
-
-#endif
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
deleted file mode 100644
index d4e8343f5b1..00000000000
--- a/drivers/media/video/gspca/gspca.c
+++ /dev/null
@@ -1,2456 +0,0 @@
-/*
- * Main USB camera driver
- *
- * Copyright (C) 2008-2011 Jean-François Moine <http://moinejf.free.fr>
- *
- * Camera button input handling by Márton Németh
- * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define GSPCA_VERSION "2.14.0"
-
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/vmalloc.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/pagemap.h>
-#include <linux/io.h>
-#include <asm/page.h>
-#include <linux/uaccess.h>
-#include <linux/ktime.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-
-#include "gspca.h"
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
-#include <linux/input.h>
-#include <linux/usb/input.h>
-#endif
-
-/* global values */
-#define DEF_NURBS 3 /* default number of URBs */
-#if DEF_NURBS > MAX_NURBS
-#error "DEF_NURBS too big"
-#endif
-
-MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
-MODULE_DESCRIPTION("GSPCA USB Camera Driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(GSPCA_VERSION);
-
-#ifdef GSPCA_DEBUG
-int gspca_debug = D_ERR | D_PROBE;
-EXPORT_SYMBOL(gspca_debug);
-
-static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h)
-{
- if ((pixfmt >> 24) >= '0' && (pixfmt >> 24) <= 'z') {
- PDEBUG(D_CONF|D_STREAM, "%s %c%c%c%c %dx%d",
- txt,
- pixfmt & 0xff,
- (pixfmt >> 8) & 0xff,
- (pixfmt >> 16) & 0xff,
- pixfmt >> 24,
- w, h);
- } else {
- PDEBUG(D_CONF|D_STREAM, "%s 0x%08x %dx%d",
- txt,
- pixfmt,
- w, h);
- }
-}
-#else
-#define PDEBUG_MODE(txt, pixfmt, w, h)
-#endif
-
-/* specific memory types - !! should be different from V4L2_MEMORY_xxx */
-#define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */
-#define GSPCA_MEMORY_READ 7
-
-#define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)
-
-/*
- * VMA operations.
- */
-static void gspca_vm_open(struct vm_area_struct *vma)
-{
- struct gspca_frame *frame = vma->vm_private_data;
-
- frame->vma_use_count++;
- frame->v4l2_buf.flags |= V4L2_BUF_FLAG_MAPPED;
-}
-
-static void gspca_vm_close(struct vm_area_struct *vma)
-{
- struct gspca_frame *frame = vma->vm_private_data;
-
- if (--frame->vma_use_count <= 0)
- frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_MAPPED;
-}
-
-static const struct vm_operations_struct gspca_vm_ops = {
- .open = gspca_vm_open,
- .close = gspca_vm_close,
-};
-
-/*
- * Input and interrupt endpoint handling functions
- */
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
-static void int_irq(struct urb *urb)
-{
- struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
- int ret;
-
- ret = urb->status;
- switch (ret) {
- case 0:
- if (gspca_dev->sd_desc->int_pkt_scan(gspca_dev,
- urb->transfer_buffer, urb->actual_length) < 0) {
- PDEBUG(D_ERR, "Unknown packet received");
- }
- break;
-
- case -ENOENT:
- case -ECONNRESET:
- case -ENODEV:
- case -ESHUTDOWN:
- /* Stop is requested either by software or hardware is gone,
- * keep the ret value non-zero and don't resubmit later.
- */
- break;
-
- default:
- PDEBUG(D_ERR, "URB error %i, resubmitting", urb->status);
- urb->status = 0;
- ret = 0;
- }
-
- if (ret == 0) {
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0)
- pr_err("Resubmit URB failed with error %i\n", ret);
- }
-}
-
-static int gspca_input_connect(struct gspca_dev *dev)
-{
- struct input_dev *input_dev;
- int err = 0;
-
- dev->input_dev = NULL;
- if (dev->sd_desc->int_pkt_scan || dev->sd_desc->other_input) {
- input_dev = input_allocate_device();
- if (!input_dev)
- return -ENOMEM;
-
- usb_make_path(dev->dev, dev->phys, sizeof(dev->phys));
- strlcat(dev->phys, "/input0", sizeof(dev->phys));
-
- input_dev->name = dev->sd_desc->name;
- input_dev->phys = dev->phys;
-
- usb_to_input_id(dev->dev, &input_dev->id);
-
- input_dev->evbit[0] = BIT_MASK(EV_KEY);
- input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
- input_dev->dev.parent = &dev->dev->dev;
-
- err = input_register_device(input_dev);
- if (err) {
- pr_err("Input device registration failed with error %i\n",
- err);
- input_dev->dev.parent = NULL;
- input_free_device(input_dev);
- } else {
- dev->input_dev = input_dev;
- }
- }
-
- return err;
-}
-
-static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
- struct usb_endpoint_descriptor *ep)
-{
- unsigned int buffer_len;
- int interval;
- struct urb *urb;
- struct usb_device *dev;
- void *buffer = NULL;
- int ret = -EINVAL;
-
- buffer_len = le16_to_cpu(ep->wMaxPacketSize);
- interval = ep->bInterval;
- PDEBUG(D_CONF, "found int in endpoint: 0x%x, "
- "buffer_len=%u, interval=%u",
- ep->bEndpointAddress, buffer_len, interval);
-
- dev = gspca_dev->dev;
-
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- ret = -ENOMEM;
- goto error;
- }
-
- buffer = usb_alloc_coherent(dev, buffer_len,
- GFP_KERNEL, &urb->transfer_dma);
- if (!buffer) {
- ret = -ENOMEM;
- goto error_buffer;
- }
- usb_fill_int_urb(urb, dev,
- usb_rcvintpipe(dev, ep->bEndpointAddress),
- buffer, buffer_len,
- int_irq, (void *)gspca_dev, interval);
- urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- ret = usb_submit_urb(urb, GFP_KERNEL);
- if (ret < 0) {
- PDEBUG(D_ERR, "submit int URB failed with error %i", ret);
- goto error_submit;
- }
- gspca_dev->int_urb = urb;
- return ret;
-
-error_submit:
- usb_free_coherent(dev,
- urb->transfer_buffer_length,
- urb->transfer_buffer,
- urb->transfer_dma);
-error_buffer:
- usb_free_urb(urb);
-error:
- return ret;
-}
-
-static void gspca_input_create_urb(struct gspca_dev *gspca_dev)
-{
- struct usb_interface *intf;
- struct usb_host_interface *intf_desc;
- struct usb_endpoint_descriptor *ep;
- int i;
-
- if (gspca_dev->sd_desc->int_pkt_scan) {
- intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
- intf_desc = intf->cur_altsetting;
- for (i = 0; i < intf_desc->desc.bNumEndpoints; i++) {
- ep = &intf_desc->endpoint[i].desc;
- if (usb_endpoint_dir_in(ep) &&
- usb_endpoint_xfer_int(ep)) {
-
- alloc_and_submit_int_urb(gspca_dev, ep);
- break;
- }
- }
- }
-}
-
-static void gspca_input_destroy_urb(struct gspca_dev *gspca_dev)
-{
- struct urb *urb;
-
- urb = gspca_dev->int_urb;
- if (urb) {
- gspca_dev->int_urb = NULL;
- usb_kill_urb(urb);
- usb_free_coherent(gspca_dev->dev,
- urb->transfer_buffer_length,
- urb->transfer_buffer,
- urb->transfer_dma);
- usb_free_urb(urb);
- }
-}
-#else
-static inline void gspca_input_destroy_urb(struct gspca_dev *gspca_dev)
-{
-}
-
-static inline void gspca_input_create_urb(struct gspca_dev *gspca_dev)
-{
-}
-
-static inline int gspca_input_connect(struct gspca_dev *dev)
-{
- return 0;
-}
-#endif
-
-/*
- * fill a video frame from an URB and resubmit
- */
-static void fill_frame(struct gspca_dev *gspca_dev,
- struct urb *urb)
-{
- u8 *data; /* address of data in the iso message */
- int i, len, st;
- cam_pkt_op pkt_scan;
-
- if (urb->status != 0) {
- if (urb->status == -ESHUTDOWN)
- return; /* disconnection */
-#ifdef CONFIG_PM
- if (gspca_dev->frozen)
- return;
-#endif
- PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
- urb->status = 0;
- goto resubmit;
- }
- pkt_scan = gspca_dev->sd_desc->pkt_scan;
- for (i = 0; i < urb->number_of_packets; i++) {
- len = urb->iso_frame_desc[i].actual_length;
-
- /* check the packet status and length */
- st = urb->iso_frame_desc[i].status;
- if (st) {
- pr_err("ISOC data error: [%d] len=%d, status=%d\n",
- i, len, st);
- gspca_dev->last_packet_type = DISCARD_PACKET;
- continue;
- }
- if (len == 0) {
- if (gspca_dev->empty_packet == 0)
- gspca_dev->empty_packet = 1;
- continue;
- }
-
- /* let the packet be analyzed by the subdriver */
- PDEBUG(D_PACK, "packet [%d] o:%d l:%d",
- i, urb->iso_frame_desc[i].offset, len);
- data = (u8 *) urb->transfer_buffer
- + urb->iso_frame_desc[i].offset;
- pkt_scan(gspca_dev, data, len);
- }
-
-resubmit:
- /* resubmit the URB */
- st = usb_submit_urb(urb, GFP_ATOMIC);
- if (st < 0)
- pr_err("usb_submit_urb() ret %d\n", st);
-}
-
-/*
- * ISOC message interrupt from the USB device
- *
- * Analyse each packet and call the subdriver for copy to the frame buffer.
- */
-static void isoc_irq(struct urb *urb)
-{
- struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
-
- PDEBUG(D_PACK, "isoc irq");
- if (!gspca_dev->streaming)
- return;
- fill_frame(gspca_dev, urb);
-}
-
-/*
- * bulk message interrupt from the USB device
- */
-static void bulk_irq(struct urb *urb)
-{
- struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
- int st;
-
- PDEBUG(D_PACK, "bulk irq");
- if (!gspca_dev->streaming)
- return;
- switch (urb->status) {
- case 0:
- break;
- case -ESHUTDOWN:
- return; /* disconnection */
- default:
-#ifdef CONFIG_PM
- if (gspca_dev->frozen)
- return;
-#endif
- PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
- urb->status = 0;
- goto resubmit;
- }
-
- PDEBUG(D_PACK, "packet l:%d", urb->actual_length);
- gspca_dev->sd_desc->pkt_scan(gspca_dev,
- urb->transfer_buffer,
- urb->actual_length);
-
-resubmit:
- /* resubmit the URB */
- if (gspca_dev->cam.bulk_nurbs != 0) {
- st = usb_submit_urb(urb, GFP_ATOMIC);
- if (st < 0)
- pr_err("usb_submit_urb() ret %d\n", st);
- }
-}
-
-/*
- * add data to the current frame
- *
- * This function is called by the subdrivers at interrupt level.
- *
- * To build a frame, these ones must add
- * - one FIRST_PACKET
- * - 0 or many INTER_PACKETs
- * - one LAST_PACKET
- * DISCARD_PACKET invalidates the whole frame.
- */
-void gspca_frame_add(struct gspca_dev *gspca_dev,
- enum gspca_packet_type packet_type,
- const u8 *data,
- int len)
-{
- struct gspca_frame *frame;
- int i, j;
-
- PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len);
-
- if (packet_type == FIRST_PACKET) {
- i = atomic_read(&gspca_dev->fr_i);
-
- /* if there are no queued buffer, discard the whole frame */
- if (i == atomic_read(&gspca_dev->fr_q)) {
- gspca_dev->last_packet_type = DISCARD_PACKET;
- gspca_dev->sequence++;
- return;
- }
- j = gspca_dev->fr_queue[i];
- frame = &gspca_dev->frame[j];
- frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get());
- frame->v4l2_buf.sequence = gspca_dev->sequence++;
- gspca_dev->image = frame->data;
- gspca_dev->image_len = 0;
- } else {
- switch (gspca_dev->last_packet_type) {
- case DISCARD_PACKET:
- if (packet_type == LAST_PACKET) {
- gspca_dev->last_packet_type = packet_type;
- gspca_dev->image = NULL;
- gspca_dev->image_len = 0;
- }
- return;
- case LAST_PACKET:
- return;
- }
- }
-
- /* append the packet to the frame buffer */
- if (len > 0) {
- if (gspca_dev->image_len + len > gspca_dev->frsz) {
- PDEBUG(D_ERR|D_PACK, "frame overflow %d > %d",
- gspca_dev->image_len + len,
- gspca_dev->frsz);
- packet_type = DISCARD_PACKET;
- } else {
-/* !! image is NULL only when last pkt is LAST or DISCARD
- if (gspca_dev->image == NULL) {
- pr_err("gspca_frame_add() image == NULL\n");
- return;
- }
- */
- memcpy(gspca_dev->image + gspca_dev->image_len,
- data, len);
- gspca_dev->image_len += len;
- }
- }
- gspca_dev->last_packet_type = packet_type;
-
- /* if last packet, invalidate packet concatenation until
- * next first packet, wake up the application and advance
- * in the queue */
- if (packet_type == LAST_PACKET) {
- i = atomic_read(&gspca_dev->fr_i);
- j = gspca_dev->fr_queue[i];
- frame = &gspca_dev->frame[j];
- frame->v4l2_buf.bytesused = gspca_dev->image_len;
- frame->v4l2_buf.flags = (frame->v4l2_buf.flags
- | V4L2_BUF_FLAG_DONE)
- & ~V4L2_BUF_FLAG_QUEUED;
- i = (i + 1) % GSPCA_MAX_FRAMES;
- atomic_set(&gspca_dev->fr_i, i);
- wake_up_interruptible(&gspca_dev->wq); /* event = new frame */
- PDEBUG(D_FRAM, "frame complete len:%d",
- frame->v4l2_buf.bytesused);
- gspca_dev->image = NULL;
- gspca_dev->image_len = 0;
- }
-}
-EXPORT_SYMBOL(gspca_frame_add);
-
-static int frame_alloc(struct gspca_dev *gspca_dev, struct file *file,
- enum v4l2_memory memory, unsigned int count)
-{
- struct gspca_frame *frame;
- unsigned int frsz;
- int i;
-
- i = gspca_dev->curr_mode;
- frsz = gspca_dev->cam.cam_mode[i].sizeimage;
- PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz);
- frsz = PAGE_ALIGN(frsz);
- if (count >= GSPCA_MAX_FRAMES)
- count = GSPCA_MAX_FRAMES - 1;
- gspca_dev->frbuf = vmalloc_32(frsz * count);
- if (!gspca_dev->frbuf) {
- pr_err("frame alloc failed\n");
- return -ENOMEM;
- }
- gspca_dev->capt_file = file;
- gspca_dev->memory = memory;
- gspca_dev->frsz = frsz;
- gspca_dev->nframes = count;
- for (i = 0; i < count; i++) {
- frame = &gspca_dev->frame[i];
- frame->v4l2_buf.index = i;
- frame->v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- frame->v4l2_buf.flags = 0;
- frame->v4l2_buf.field = V4L2_FIELD_NONE;
- frame->v4l2_buf.length = frsz;
- frame->v4l2_buf.memory = memory;
- frame->v4l2_buf.sequence = 0;
- frame->data = gspca_dev->frbuf + i * frsz;
- frame->v4l2_buf.m.offset = i * frsz;
- }
- atomic_set(&gspca_dev->fr_q, 0);
- atomic_set(&gspca_dev->fr_i, 0);
- gspca_dev->fr_o = 0;
- return 0;
-}
-
-static void frame_free(struct gspca_dev *gspca_dev)
-{
- int i;
-
- PDEBUG(D_STREAM, "frame free");
- if (gspca_dev->frbuf != NULL) {
- vfree(gspca_dev->frbuf);
- gspca_dev->frbuf = NULL;
- for (i = 0; i < gspca_dev->nframes; i++)
- gspca_dev->frame[i].data = NULL;
- }
- gspca_dev->nframes = 0;
- gspca_dev->frsz = 0;
- gspca_dev->capt_file = NULL;
- gspca_dev->memory = GSPCA_MEMORY_NO;
-}
-
-static void destroy_urbs(struct gspca_dev *gspca_dev)
-{
- struct urb *urb;
- unsigned int i;
-
- PDEBUG(D_STREAM, "kill transfer");
- for (i = 0; i < MAX_NURBS; i++) {
- urb = gspca_dev->urb[i];
- if (urb == NULL)
- break;
-
- gspca_dev->urb[i] = NULL;
- usb_kill_urb(urb);
- if (urb->transfer_buffer != NULL)
- usb_free_coherent(gspca_dev->dev,
- urb->transfer_buffer_length,
- urb->transfer_buffer,
- urb->transfer_dma);
- usb_free_urb(urb);
- }
-}
-
-static int gspca_set_alt0(struct gspca_dev *gspca_dev)
-{
- int ret;
-
- if (gspca_dev->alt == 0)
- return 0;
- ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);
- if (ret < 0)
- pr_err("set alt 0 err %d\n", ret);
- return ret;
-}
-
-/* Note: both the queue and the usb locks should be held when calling this */
-static void gspca_stream_off(struct gspca_dev *gspca_dev)
-{
- gspca_dev->streaming = 0;
- gspca_dev->usb_err = 0;
- if (gspca_dev->sd_desc->stopN)
- gspca_dev->sd_desc->stopN(gspca_dev);
- destroy_urbs(gspca_dev);
- gspca_input_destroy_urb(gspca_dev);
- gspca_set_alt0(gspca_dev);
- gspca_input_create_urb(gspca_dev);
- if (gspca_dev->sd_desc->stop0)
- gspca_dev->sd_desc->stop0(gspca_dev);
- PDEBUG(D_STREAM, "stream off OK");
-}
-
-/*
- * look for an input transfer endpoint in an alternate setting
- */
-static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
- int xfer)
-{
- struct usb_host_endpoint *ep;
- int i, attr;
-
- for (i = 0; i < alt->desc.bNumEndpoints; i++) {
- ep = &alt->endpoint[i];
- attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
- if (attr == xfer
- && ep->desc.wMaxPacketSize != 0
- && usb_endpoint_dir_in(&ep->desc))
- return ep;
- }
- return NULL;
-}
-
-/* compute the minimum bandwidth for the current transfer */
-static u32 which_bandwidth(struct gspca_dev *gspca_dev)
-{
- u32 bandwidth;
- int i;
-
- /* get the (max) image size */
- i = gspca_dev->curr_mode;
- bandwidth = gspca_dev->cam.cam_mode[i].sizeimage;
-
- /* if the image is compressed, estimate its mean size */
- if (!gspca_dev->cam.needs_full_bandwidth &&
- bandwidth < gspca_dev->cam.cam_mode[i].width *
- gspca_dev->cam.cam_mode[i].height)
- bandwidth = bandwidth * 3 / 8; /* 0.375 */
-
- /* estimate the frame rate */
- if (gspca_dev->sd_desc->get_streamparm) {
- struct v4l2_streamparm parm;
-
- gspca_dev->sd_desc->get_streamparm(gspca_dev, &parm);
- bandwidth *= parm.parm.capture.timeperframe.denominator;
- bandwidth /= parm.parm.capture.timeperframe.numerator;
- } else {
-
- /* don't hope more than 15 fps with USB 1.1 and
- * image resolution >= 640x480 */
- if (gspca_dev->width >= 640
- && gspca_dev->dev->speed == USB_SPEED_FULL)
- bandwidth *= 15; /* 15 fps */
- else
- bandwidth *= 30; /* 30 fps */
- }
-
- PDEBUG(D_STREAM, "min bandwidth: %d", bandwidth);
- return bandwidth;
-}
-
-/* endpoint table */
-#define MAX_ALT 16
-struct ep_tb_s {
- u32 alt;
- u32 bandwidth;
-};
-
-/*
- * build the table of the endpoints
- * and compute the minimum bandwidth for the image transfer
- */
-static int build_isoc_ep_tb(struct gspca_dev *gspca_dev,
- struct usb_interface *intf,
- struct ep_tb_s *ep_tb)
-{
- struct usb_host_endpoint *ep;
- int i, j, nbalt, psize, found;
- u32 bandwidth, last_bw;
-
- nbalt = intf->num_altsetting;
- if (nbalt > MAX_ALT)
- nbalt = MAX_ALT; /* fixme: should warn */
-
- /* build the endpoint table */
- i = 0;
- last_bw = 0;
- for (;;) {
- ep_tb->bandwidth = 2000 * 2000 * 120;
- found = 0;
- for (j = 0; j < nbalt; j++) {
- ep = alt_xfer(&intf->altsetting[j],
- USB_ENDPOINT_XFER_ISOC);
- if (ep == NULL)
- continue;
- if (ep->desc.bInterval == 0) {
- pr_err("alt %d iso endp with 0 interval\n", j);
- continue;
- }
- psize = le16_to_cpu(ep->desc.wMaxPacketSize);
- psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
- bandwidth = psize * 1000;
- if (gspca_dev->dev->speed == USB_SPEED_HIGH
- || gspca_dev->dev->speed == USB_SPEED_SUPER)
- bandwidth *= 8;
- bandwidth /= 1 << (ep->desc.bInterval - 1);
- if (bandwidth <= last_bw)
- continue;
- if (bandwidth < ep_tb->bandwidth) {
- ep_tb->bandwidth = bandwidth;
- ep_tb->alt = j;
- found = 1;
- }
- }
- if (!found)
- break;
- PDEBUG(D_STREAM, "alt %d bandwidth %d",
- ep_tb->alt, ep_tb->bandwidth);
- last_bw = ep_tb->bandwidth;
- i++;
- ep_tb++;
- }
-
- /*
- * If the camera:
- * has a usb audio class interface (a built in usb mic); and
- * is a usb 1 full speed device; and
- * uses the max full speed iso bandwidth; and
- * and has more than 1 alt setting
- * then skip the highest alt setting to spare bandwidth for the mic
- */
- if (gspca_dev->audio &&
- gspca_dev->dev->speed == USB_SPEED_FULL &&
- last_bw >= 1000000 &&
- i > 1) {
- PDEBUG(D_STREAM, "dev has usb audio, skipping highest alt");
- i--;
- ep_tb--;
- }
-
- /* get the requested bandwidth and start at the highest atlsetting */
- bandwidth = which_bandwidth(gspca_dev);
- ep_tb--;
- while (i > 1) {
- ep_tb--;
- if (ep_tb->bandwidth < bandwidth)
- break;
- i--;
- }
- return i;
-}
-
-/*
- * create the URBs for image transfer
- */
-static int create_urbs(struct gspca_dev *gspca_dev,
- struct usb_host_endpoint *ep)
-{
- struct urb *urb;
- int n, nurbs, i, psize, npkt, bsize;
-
- /* calculate the packet size and the number of packets */
- psize = le16_to_cpu(ep->desc.wMaxPacketSize);
-
- if (!gspca_dev->cam.bulk) { /* isoc */
-
- /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
- if (gspca_dev->pkt_size == 0)
- psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
- else
- psize = gspca_dev->pkt_size;
- npkt = gspca_dev->cam.npkt;
- if (npkt == 0)
- npkt = 32; /* default value */
- bsize = psize * npkt;
- PDEBUG(D_STREAM,
- "isoc %d pkts size %d = bsize:%d",
- npkt, psize, bsize);
- nurbs = DEF_NURBS;
- } else { /* bulk */
- npkt = 0;
- bsize = gspca_dev->cam.bulk_size;
- if (bsize == 0)
- bsize = psize;
- PDEBUG(D_STREAM, "bulk bsize:%d", bsize);
- if (gspca_dev->cam.bulk_nurbs != 0)
- nurbs = gspca_dev->cam.bulk_nurbs;
- else
- nurbs = 1;
- }
-
- for (n = 0; n < nurbs; n++) {
- urb = usb_alloc_urb(npkt, GFP_KERNEL);
- if (!urb) {
- pr_err("usb_alloc_urb failed\n");
- return -ENOMEM;
- }
- gspca_dev->urb[n] = urb;
- urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev,
- bsize,
- GFP_KERNEL,
- &urb->transfer_dma);
-
- if (urb->transfer_buffer == NULL) {
- pr_err("usb_alloc_coherent failed\n");
- return -ENOMEM;
- }
- urb->dev = gspca_dev->dev;
- urb->context = gspca_dev;
- urb->transfer_buffer_length = bsize;
- if (npkt != 0) { /* ISOC */
- urb->pipe = usb_rcvisocpipe(gspca_dev->dev,
- ep->desc.bEndpointAddress);
- urb->transfer_flags = URB_ISO_ASAP
- | URB_NO_TRANSFER_DMA_MAP;
- urb->interval = 1 << (ep->desc.bInterval - 1);
- urb->complete = isoc_irq;
- urb->number_of_packets = npkt;
- for (i = 0; i < npkt; i++) {
- urb->iso_frame_desc[i].length = psize;
- urb->iso_frame_desc[i].offset = psize * i;
- }
- } else { /* bulk */
- urb->pipe = usb_rcvbulkpipe(gspca_dev->dev,
- ep->desc.bEndpointAddress);
- urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
- urb->complete = bulk_irq;
- }
- }
- return 0;
-}
-
-/*
- * start the USB transfer
- */
-static int gspca_init_transfer(struct gspca_dev *gspca_dev)
-{
- struct usb_interface *intf;
- struct usb_host_endpoint *ep;
- struct urb *urb;
- struct ep_tb_s ep_tb[MAX_ALT];
- int n, ret, xfer, alt, alt_idx;
-
- /* reset the streaming variables */
- gspca_dev->image = NULL;
- gspca_dev->image_len = 0;
- gspca_dev->last_packet_type = DISCARD_PACKET;
- gspca_dev->sequence = 0;
-
- gspca_dev->usb_err = 0;
-
- /* do the specific subdriver stuff before endpoint selection */
- intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
- gspca_dev->alt = gspca_dev->cam.bulk ? intf->num_altsetting : 0;
- if (gspca_dev->sd_desc->isoc_init) {
- ret = gspca_dev->sd_desc->isoc_init(gspca_dev);
- if (ret < 0)
- return ret;
- }
- xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK
- : USB_ENDPOINT_XFER_ISOC;
-
- /* if bulk or the subdriver forced an altsetting, get the endpoint */
- if (gspca_dev->alt != 0) {
- gspca_dev->alt--; /* (previous version compatibility) */
- ep = alt_xfer(&intf->altsetting[gspca_dev->alt], xfer);
- if (ep == NULL) {
- pr_err("bad altsetting %d\n", gspca_dev->alt);
- return -EIO;
- }
- ep_tb[0].alt = gspca_dev->alt;
- alt_idx = 1;
- } else {
-
- /* else, compute the minimum bandwidth
- * and build the endpoint table */
- alt_idx = build_isoc_ep_tb(gspca_dev, intf, ep_tb);
- if (alt_idx <= 0) {
- pr_err("no transfer endpoint found\n");
- return -EIO;
- }
- }
-
- /* set the highest alternate setting and
- * loop until urb submit succeeds */
- gspca_input_destroy_urb(gspca_dev);
-
- gspca_dev->alt = ep_tb[--alt_idx].alt;
- alt = -1;
- for (;;) {
- if (alt != gspca_dev->alt) {
- alt = gspca_dev->alt;
- if (intf->num_altsetting > 1) {
- ret = usb_set_interface(gspca_dev->dev,
- gspca_dev->iface,
- alt);
- if (ret < 0) {
- if (ret == -ENOSPC)
- goto retry; /*fixme: ugly*/
- pr_err("set alt %d err %d\n", alt, ret);
- goto out;
- }
- }
- }
- if (!gspca_dev->cam.no_urb_create) {
- PDEBUG(D_STREAM, "init transfer alt %d", alt);
- ret = create_urbs(gspca_dev,
- alt_xfer(&intf->altsetting[alt], xfer));
- if (ret < 0) {
- destroy_urbs(gspca_dev);
- goto out;
- }
- }
-
- /* clear the bulk endpoint */
- if (gspca_dev->cam.bulk)
- usb_clear_halt(gspca_dev->dev,
- gspca_dev->urb[0]->pipe);
-
- /* start the cam */
- ret = gspca_dev->sd_desc->start(gspca_dev);
- if (ret < 0) {
- destroy_urbs(gspca_dev);
- goto out;
- }
- gspca_dev->streaming = 1;
- v4l2_ctrl_handler_setup(gspca_dev->vdev.ctrl_handler);
-
- /* some bulk transfers are started by the subdriver */
- if (gspca_dev->cam.bulk && gspca_dev->cam.bulk_nurbs == 0)
- break;
-
- /* submit the URBs */
- for (n = 0; n < MAX_NURBS; n++) {
- urb = gspca_dev->urb[n];
- if (urb == NULL)
- break;
- ret = usb_submit_urb(urb, GFP_KERNEL);
- if (ret < 0)
- break;
- }
- if (ret >= 0)
- break; /* transfer is started */
-
- /* something when wrong
- * stop the webcam and free the transfer resources */
- gspca_stream_off(gspca_dev);
- if (ret != -ENOSPC) {
- pr_err("usb_submit_urb alt %d err %d\n",
- gspca_dev->alt, ret);
- goto out;
- }
-
- /* the bandwidth is not wide enough
- * negotiate or try a lower alternate setting */
-retry:
- PDEBUG(D_ERR|D_STREAM,
- "alt %d - bandwidth not wide enough - trying again",
- alt);
- msleep(20); /* wait for kill complete */
- if (gspca_dev->sd_desc->isoc_nego) {
- ret = gspca_dev->sd_desc->isoc_nego(gspca_dev);
- if (ret < 0)
- goto out;
- } else {
- if (alt_idx <= 0) {
- pr_err("no transfer endpoint found\n");
- ret = -EIO;
- goto out;
- }
- gspca_dev->alt = ep_tb[--alt_idx].alt;
- }
- }
-out:
- gspca_input_create_urb(gspca_dev);
- return ret;
-}
-
-static void gspca_set_default_mode(struct gspca_dev *gspca_dev)
-{
- struct gspca_ctrl *ctrl;
- int i;
-
- i = gspca_dev->cam.nmodes - 1; /* take the highest mode */
- gspca_dev->curr_mode = i;
- gspca_dev->width = gspca_dev->cam.cam_mode[i].width;
- gspca_dev->height = gspca_dev->cam.cam_mode[i].height;
- gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixelformat;
-
- /* set the current control values to their default values
- * which may have changed in sd_init() */
- /* does nothing if ctrl_handler == NULL */
- v4l2_ctrl_handler_setup(gspca_dev->vdev.ctrl_handler);
- ctrl = gspca_dev->cam.ctrls;
- if (ctrl != NULL) {
- for (i = 0;
- i < gspca_dev->sd_desc->nctrls;
- i++, ctrl++)
- ctrl->val = ctrl->def;
- }
-}
-
-static int wxh_to_mode(struct gspca_dev *gspca_dev,
- int width, int height)
-{
- int i;
-
- for (i = gspca_dev->cam.nmodes; --i > 0; ) {
- if (width >= gspca_dev->cam.cam_mode[i].width
- && height >= gspca_dev->cam.cam_mode[i].height)
- break;
- }
- return i;
-}
-
-/*
- * search a mode with the right pixel format
- */
-static int gspca_get_mode(struct gspca_dev *gspca_dev,
- int mode,
- int pixfmt)
-{
- int modeU, modeD;
-
- modeU = modeD = mode;
- while ((modeU < gspca_dev->cam.nmodes) || modeD >= 0) {
- if (--modeD >= 0) {
- if (gspca_dev->cam.cam_mode[modeD].pixelformat
- == pixfmt)
- return modeD;
- }
- if (++modeU < gspca_dev->cam.nmodes) {
- if (gspca_dev->cam.cam_mode[modeU].pixelformat
- == pixfmt)
- return modeU;
- }
- }
- return -EINVAL;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vidioc_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
-
- gspca_dev->usb_err = 0;
- return gspca_dev->sd_desc->get_register(gspca_dev, reg);
-}
-
-static int vidioc_s_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
-
- gspca_dev->usb_err = 0;
- return gspca_dev->sd_desc->set_register(gspca_dev, reg);
-}
-#endif
-
-static int vidioc_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
-
- gspca_dev->usb_err = 0;
- return gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip);
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *fmtdesc)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- int i, j, index;
- __u32 fmt_tb[8];
-
- /* give an index to each format */
- index = 0;
- j = 0;
- for (i = gspca_dev->cam.nmodes; --i >= 0; ) {
- fmt_tb[index] = gspca_dev->cam.cam_mode[i].pixelformat;
- j = 0;
- for (;;) {
- if (fmt_tb[j] == fmt_tb[index])
- break;
- j++;
- }
- if (j == index) {
- if (fmtdesc->index == index)
- break; /* new format */
- index++;
- if (index >= ARRAY_SIZE(fmt_tb))
- return -EINVAL;
- }
- }
- if (i < 0)
- return -EINVAL; /* no more format */
-
- fmtdesc->pixelformat = fmt_tb[index];
- if (gspca_dev->cam.cam_mode[i].sizeimage <
- gspca_dev->cam.cam_mode[i].width *
- gspca_dev->cam.cam_mode[i].height)
- fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
- fmtdesc->description[0] = fmtdesc->pixelformat & 0xff;
- fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff;
- fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff;
- fmtdesc->description[3] = fmtdesc->pixelformat >> 24;
- fmtdesc->description[4] = '\0';
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- int mode;
-
- mode = gspca_dev->curr_mode;
- fmt->fmt.pix = gspca_dev->cam.cam_mode[mode];
- /* some drivers use priv internally, zero it before giving it to
- userspace */
- fmt->fmt.pix.priv = 0;
- return 0;
-}
-
-static int try_fmt_vid_cap(struct gspca_dev *gspca_dev,
- struct v4l2_format *fmt)
-{
- int w, h, mode, mode2;
-
- w = fmt->fmt.pix.width;
- h = fmt->fmt.pix.height;
-
-#ifdef GSPCA_DEBUG
- if (gspca_debug & D_CONF)
- PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h);
-#endif
- /* search the closest mode for width and height */
- mode = wxh_to_mode(gspca_dev, w, h);
-
- /* OK if right palette */
- if (gspca_dev->cam.cam_mode[mode].pixelformat
- != fmt->fmt.pix.pixelformat) {
-
- /* else, search the closest mode with the same pixel format */
- mode2 = gspca_get_mode(gspca_dev, mode,
- fmt->fmt.pix.pixelformat);
- if (mode2 >= 0)
- mode = mode2;
-/* else
- ; * no chance, return this mode */
- }
- fmt->fmt.pix = gspca_dev->cam.cam_mode[mode];
- /* some drivers use priv internally, zero it before giving it to
- userspace */
- fmt->fmt.pix.priv = 0;
- return mode; /* used when s_fmt */
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file,
- void *priv,
- struct v4l2_format *fmt)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- int ret;
-
- ret = try_fmt_vid_cap(gspca_dev, fmt);
- if (ret < 0)
- return ret;
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- int ret;
-
- if (mutex_lock_interruptible(&gspca_dev->queue_lock))
- return -ERESTARTSYS;
-
- ret = try_fmt_vid_cap(gspca_dev, fmt);
- if (ret < 0)
- goto out;
-
- if (gspca_dev->nframes != 0
- && fmt->fmt.pix.sizeimage > gspca_dev->frsz) {
- ret = -EINVAL;
- goto out;
- }
-
- if (ret == gspca_dev->curr_mode) {
- ret = 0;
- goto out; /* same mode */
- }
-
- if (gspca_dev->streaming) {
- ret = -EBUSY;
- goto out;
- }
- gspca_dev->width = fmt->fmt.pix.width;
- gspca_dev->height = fmt->fmt.pix.height;
- gspca_dev->pixfmt = fmt->fmt.pix.pixelformat;
- gspca_dev->curr_mode = ret;
-
- ret = 0;
-out:
- mutex_unlock(&gspca_dev->queue_lock);
- return ret;
-}
-
-static int vidioc_enum_framesizes(struct file *file, void *priv,
- struct v4l2_frmsizeenum *fsize)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- int i;
- __u32 index = 0;
-
- for (i = 0; i < gspca_dev->cam.nmodes; i++) {
- if (fsize->pixel_format !=
- gspca_dev->cam.cam_mode[i].pixelformat)
- continue;
-
- if (fsize->index == index) {
- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fsize->discrete.width =
- gspca_dev->cam.cam_mode[i].width;
- fsize->discrete.height =
- gspca_dev->cam.cam_mode[i].height;
- return 0;
- }
- index++;
- }
-
- return -EINVAL;
-}
-
-static int vidioc_enum_frameintervals(struct file *filp, void *priv,
- struct v4l2_frmivalenum *fival)
-{
- struct gspca_dev *gspca_dev = video_drvdata(filp);
- int mode = wxh_to_mode(gspca_dev, fival->width, fival->height);
- __u32 i;
-
- if (gspca_dev->cam.mode_framerates == NULL ||
- gspca_dev->cam.mode_framerates[mode].nrates == 0)
- return -EINVAL;
-
- if (fival->pixel_format !=
- gspca_dev->cam.cam_mode[mode].pixelformat)
- return -EINVAL;
-
- for (i = 0; i < gspca_dev->cam.mode_framerates[mode].nrates; i++) {
- if (fival->index == i) {
- fival->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fival->discrete.numerator = 1;
- fival->discrete.denominator =
- gspca_dev->cam.mode_framerates[mode].rates[i];
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-static void gspca_release(struct v4l2_device *v4l2_device)
-{
- struct gspca_dev *gspca_dev =
- container_of(v4l2_device, struct gspca_dev, v4l2_dev);
-
- v4l2_ctrl_handler_free(gspca_dev->vdev.ctrl_handler);
- v4l2_device_unregister(&gspca_dev->v4l2_dev);
- kfree(gspca_dev->usb_buf);
- kfree(gspca_dev);
-}
-
-static int dev_open(struct file *file)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
-
- PDEBUG(D_STREAM, "[%s] open", current->comm);
-
- /* protect the subdriver against rmmod */
- if (!try_module_get(gspca_dev->module))
- return -ENODEV;
-
-#ifdef GSPCA_DEBUG
- /* activate the v4l2 debug */
- if (gspca_debug & D_V4L2)
- gspca_dev->vdev.debug |= V4L2_DEBUG_IOCTL
- | V4L2_DEBUG_IOCTL_ARG;
- else
- gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL
- | V4L2_DEBUG_IOCTL_ARG);
-#endif
- return v4l2_fh_open(file);
-}
-
-static int dev_close(struct file *file)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
-
- PDEBUG(D_STREAM, "[%s] close", current->comm);
-
- /* Needed for gspca_stream_off, always lock before queue_lock! */
- if (mutex_lock_interruptible(&gspca_dev->usb_lock))
- return -ERESTARTSYS;
-
- if (mutex_lock_interruptible(&gspca_dev->queue_lock)) {
- mutex_unlock(&gspca_dev->usb_lock);
- return -ERESTARTSYS;
- }
-
- /* if the file did the capture, free the streaming resources */
- if (gspca_dev->capt_file == file) {
- if (gspca_dev->streaming)
- gspca_stream_off(gspca_dev);
- frame_free(gspca_dev);
- }
- module_put(gspca_dev->module);
- mutex_unlock(&gspca_dev->queue_lock);
- mutex_unlock(&gspca_dev->usb_lock);
-
- PDEBUG(D_STREAM, "close done");
-
- return v4l2_fh_release(file);
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
-
- strlcpy((char *) cap->driver, gspca_dev->sd_desc->name,
- sizeof cap->driver);
- if (gspca_dev->dev->product != NULL) {
- strlcpy((char *) cap->card, gspca_dev->dev->product,
- sizeof cap->card);
- } else {
- snprintf((char *) cap->card, sizeof cap->card,
- "USB Camera (%04x:%04x)",
- le16_to_cpu(gspca_dev->dev->descriptor.idVendor),
- le16_to_cpu(gspca_dev->dev->descriptor.idProduct));
- }
- usb_make_path(gspca_dev->dev, (char *) cap->bus_info,
- sizeof(cap->bus_info));
- cap->device_caps = V4L2_CAP_VIDEO_CAPTURE
- | V4L2_CAP_STREAMING
- | V4L2_CAP_READWRITE;
- cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
- return 0;
-}
-
-static int get_ctrl(struct gspca_dev *gspca_dev,
- int id)
-{
- const struct ctrl *ctrls;
- int i;
-
- for (i = 0, ctrls = gspca_dev->sd_desc->ctrls;
- i < gspca_dev->sd_desc->nctrls;
- i++, ctrls++) {
- if (gspca_dev->ctrl_dis & (1 << i))
- continue;
- if (id == ctrls->qctrl.id)
- return i;
- }
- return -1;
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *q_ctrl)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- const struct ctrl *ctrls;
- struct gspca_ctrl *gspca_ctrl;
- int i, idx;
- u32 id;
-
- id = q_ctrl->id;
- if (id & V4L2_CTRL_FLAG_NEXT_CTRL) {
- id &= V4L2_CTRL_ID_MASK;
- id++;
- idx = -1;
- for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
- if (gspca_dev->ctrl_dis & (1 << i))
- continue;
- if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id)
- continue;
- if (idx >= 0
- && gspca_dev->sd_desc->ctrls[i].qctrl.id
- > gspca_dev->sd_desc->ctrls[idx].qctrl.id)
- continue;
- idx = i;
- }
- } else {
- idx = get_ctrl(gspca_dev, id);
- }
- if (idx < 0)
- return -EINVAL;
- ctrls = &gspca_dev->sd_desc->ctrls[idx];
- memcpy(q_ctrl, &ctrls->qctrl, sizeof *q_ctrl);
- if (gspca_dev->cam.ctrls != NULL) {
- gspca_ctrl = &gspca_dev->cam.ctrls[idx];
- q_ctrl->default_value = gspca_ctrl->def;
- q_ctrl->minimum = gspca_ctrl->min;
- q_ctrl->maximum = gspca_ctrl->max;
- }
- if (gspca_dev->ctrl_inac & (1 << idx))
- q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- const struct ctrl *ctrls;
- struct gspca_ctrl *gspca_ctrl;
- int idx;
-
- idx = get_ctrl(gspca_dev, ctrl->id);
- if (idx < 0)
- return -EINVAL;
- if (gspca_dev->ctrl_inac & (1 << idx))
- return -EINVAL;
- ctrls = &gspca_dev->sd_desc->ctrls[idx];
- if (gspca_dev->cam.ctrls != NULL) {
- gspca_ctrl = &gspca_dev->cam.ctrls[idx];
- if (ctrl->value < gspca_ctrl->min
- || ctrl->value > gspca_ctrl->max)
- return -ERANGE;
- } else {
- gspca_ctrl = NULL;
- if (ctrl->value < ctrls->qctrl.minimum
- || ctrl->value > ctrls->qctrl.maximum)
- return -ERANGE;
- }
- PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
- gspca_dev->usb_err = 0;
- if (ctrls->set != NULL)
- return ctrls->set(gspca_dev, ctrl->value);
- if (gspca_ctrl != NULL) {
- gspca_ctrl->val = ctrl->value;
- if (ctrls->set_control != NULL
- && gspca_dev->streaming)
- ctrls->set_control(gspca_dev);
- }
- return gspca_dev->usb_err;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- const struct ctrl *ctrls;
- int idx;
-
- idx = get_ctrl(gspca_dev, ctrl->id);
- if (idx < 0)
- return -EINVAL;
- ctrls = &gspca_dev->sd_desc->ctrls[idx];
-
- gspca_dev->usb_err = 0;
- if (ctrls->get != NULL)
- return ctrls->get(gspca_dev, &ctrl->value);
- if (gspca_dev->cam.ctrls != NULL)
- ctrl->value = gspca_dev->cam.ctrls[idx].val;
- return 0;
-}
-
-static int vidioc_querymenu(struct file *file, void *priv,
- struct v4l2_querymenu *qmenu)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
-
- if (!gspca_dev->sd_desc->querymenu)
- return -ENOTTY;
- return gspca_dev->sd_desc->querymenu(gspca_dev, qmenu);
-}
-
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *input)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
-
- if (input->index != 0)
- return -EINVAL;
- input->type = V4L2_INPUT_TYPE_CAMERA;
- input->status = gspca_dev->cam.input_flags;
- strlcpy(input->name, gspca_dev->sd_desc->name,
- sizeof input->name);
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- if (i > 0)
- return -EINVAL;
- return (0);
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *rb)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- int i, ret = 0, streaming;
-
- i = rb->memory; /* (avoid compilation warning) */
- switch (i) {
- case GSPCA_MEMORY_READ: /* (internal call) */
- case V4L2_MEMORY_MMAP:
- case V4L2_MEMORY_USERPTR:
- break;
- default:
- return -EINVAL;
- }
- if (mutex_lock_interruptible(&gspca_dev->queue_lock))
- return -ERESTARTSYS;
-
- if (gspca_dev->memory != GSPCA_MEMORY_NO
- && gspca_dev->memory != GSPCA_MEMORY_READ
- && gspca_dev->memory != rb->memory) {
- ret = -EBUSY;
- goto out;
- }
-
- /* only one file may do the capture */
- if (gspca_dev->capt_file != NULL
- && gspca_dev->capt_file != file) {
- ret = -EBUSY;
- goto out;
- }
-
- /* if allocated, the buffers must not be mapped */
- for (i = 0; i < gspca_dev->nframes; i++) {
- if (gspca_dev->frame[i].vma_use_count) {
- ret = -EBUSY;
- goto out;
- }
- }
-
- /* stop streaming */
- streaming = gspca_dev->streaming;
- if (streaming) {
- gspca_stream_off(gspca_dev);
-
- /* Don't restart the stream when switching from read
- * to mmap mode */
- if (gspca_dev->memory == GSPCA_MEMORY_READ)
- streaming = 0;
- }
-
- /* free the previous allocated buffers, if any */
- if (gspca_dev->nframes != 0)
- frame_free(gspca_dev);
- if (rb->count == 0) /* unrequest */
- goto out;
- ret = frame_alloc(gspca_dev, file, rb->memory, rb->count);
- if (ret == 0) {
- rb->count = gspca_dev->nframes;
- if (streaming)
- ret = gspca_init_transfer(gspca_dev);
- }
-out:
- mutex_unlock(&gspca_dev->queue_lock);
- PDEBUG(D_STREAM, "reqbufs st:%d c:%d", ret, rb->count);
- return ret;
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *v4l2_buf)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- struct gspca_frame *frame;
-
- if (v4l2_buf->index < 0
- || v4l2_buf->index >= gspca_dev->nframes)
- return -EINVAL;
-
- frame = &gspca_dev->frame[v4l2_buf->index];
- memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type buf_type)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- int ret;
-
- if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (mutex_lock_interruptible(&gspca_dev->queue_lock))
- return -ERESTARTSYS;
-
- /* check the capture file */
- if (gspca_dev->capt_file != file) {
- ret = -EBUSY;
- goto out;
- }
-
- if (gspca_dev->nframes == 0
- || !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) {
- ret = -EINVAL;
- goto out;
- }
- if (!gspca_dev->streaming) {
- ret = gspca_init_transfer(gspca_dev);
- if (ret < 0)
- goto out;
- }
-#ifdef GSPCA_DEBUG
- if (gspca_debug & D_STREAM) {
- PDEBUG_MODE("stream on OK",
- gspca_dev->pixfmt,
- gspca_dev->width,
- gspca_dev->height);
- }
-#endif
- ret = 0;
-out:
- mutex_unlock(&gspca_dev->queue_lock);
- return ret;
-}
-
-static int vidioc_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type buf_type)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- int i, ret;
-
- if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&gspca_dev->queue_lock))
- return -ERESTARTSYS;
-
- if (!gspca_dev->streaming) {
- ret = 0;
- goto out;
- }
-
- /* check the capture file */
- if (gspca_dev->capt_file != file) {
- ret = -EBUSY;
- goto out;
- }
-
- /* stop streaming */
- gspca_stream_off(gspca_dev);
- /* In case another thread is waiting in dqbuf */
- wake_up_interruptible(&gspca_dev->wq);
-
- /* empty the transfer queues */
- for (i = 0; i < gspca_dev->nframes; i++)
- gspca_dev->frame[i].v4l2_buf.flags &= ~BUF_ALL_FLAGS;
- atomic_set(&gspca_dev->fr_q, 0);
- atomic_set(&gspca_dev->fr_i, 0);
- gspca_dev->fr_o = 0;
- ret = 0;
-out:
- mutex_unlock(&gspca_dev->queue_lock);
- return ret;
-}
-
-static int vidioc_g_jpegcomp(struct file *file, void *priv,
- struct v4l2_jpegcompression *jpegcomp)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
-
- gspca_dev->usb_err = 0;
- return gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
-}
-
-static int vidioc_s_jpegcomp(struct file *file, void *priv,
- struct v4l2_jpegcompression *jpegcomp)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
-
- gspca_dev->usb_err = 0;
- return gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
-}
-
-static int vidioc_g_parm(struct file *filp, void *priv,
- struct v4l2_streamparm *parm)
-{
- struct gspca_dev *gspca_dev = video_drvdata(filp);
-
- parm->parm.capture.readbuffers = gspca_dev->nbufread;
-
- if (gspca_dev->sd_desc->get_streamparm) {
- gspca_dev->usb_err = 0;
- gspca_dev->sd_desc->get_streamparm(gspca_dev, parm);
- return gspca_dev->usb_err;
- }
- return 0;
-}
-
-static int vidioc_s_parm(struct file *filp, void *priv,
- struct v4l2_streamparm *parm)
-{
- struct gspca_dev *gspca_dev = video_drvdata(filp);
- int n;
-
- n = parm->parm.capture.readbuffers;
- if (n == 0 || n >= GSPCA_MAX_FRAMES)
- parm->parm.capture.readbuffers = gspca_dev->nbufread;
- else
- gspca_dev->nbufread = n;
-
- if (gspca_dev->sd_desc->set_streamparm) {
- gspca_dev->usb_err = 0;
- gspca_dev->sd_desc->set_streamparm(gspca_dev, parm);
- return gspca_dev->usb_err;
- }
-
- return 0;
-}
-
-static int dev_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- struct gspca_frame *frame;
- struct page *page;
- unsigned long addr, start, size;
- int i, ret;
-
- start = vma->vm_start;
- size = vma->vm_end - vma->vm_start;
- PDEBUG(D_STREAM, "mmap start:%08x size:%d", (int) start, (int) size);
-
- if (mutex_lock_interruptible(&gspca_dev->queue_lock))
- return -ERESTARTSYS;
- if (gspca_dev->capt_file != file) {
- ret = -EINVAL;
- goto out;
- }
-
- frame = NULL;
- for (i = 0; i < gspca_dev->nframes; ++i) {
- if (gspca_dev->frame[i].v4l2_buf.memory != V4L2_MEMORY_MMAP) {
- PDEBUG(D_STREAM, "mmap bad memory type");
- break;
- }
- if ((gspca_dev->frame[i].v4l2_buf.m.offset >> PAGE_SHIFT)
- == vma->vm_pgoff) {
- frame = &gspca_dev->frame[i];
- break;
- }
- }
- if (frame == NULL) {
- PDEBUG(D_STREAM, "mmap no frame buffer found");
- ret = -EINVAL;
- goto out;
- }
- if (size != frame->v4l2_buf.length) {
- PDEBUG(D_STREAM, "mmap bad size");
- ret = -EINVAL;
- goto out;
- }
-
- /*
- * - VM_IO marks the area as being a mmaped region for I/O to a
- * device. It also prevents the region from being core dumped.
- */
- vma->vm_flags |= VM_IO;
-
- addr = (unsigned long) frame->data;
- while (size > 0) {
- page = vmalloc_to_page((void *) addr);
- ret = vm_insert_page(vma, start, page);
- if (ret < 0)
- goto out;
- start += PAGE_SIZE;
- addr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- vma->vm_ops = &gspca_vm_ops;
- vma->vm_private_data = frame;
- gspca_vm_open(vma);
- ret = 0;
-out:
- mutex_unlock(&gspca_dev->queue_lock);
- return ret;
-}
-
-static int frame_ready_nolock(struct gspca_dev *gspca_dev, struct file *file,
- enum v4l2_memory memory)
-{
- if (!gspca_dev->present)
- return -ENODEV;
- if (gspca_dev->capt_file != file || gspca_dev->memory != memory ||
- !gspca_dev->streaming)
- return -EINVAL;
-
- /* check if a frame is ready */
- return gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i);
-}
-
-static int frame_ready(struct gspca_dev *gspca_dev, struct file *file,
- enum v4l2_memory memory)
-{
- int ret;
-
- if (mutex_lock_interruptible(&gspca_dev->queue_lock))
- return -ERESTARTSYS;
- ret = frame_ready_nolock(gspca_dev, file, memory);
- mutex_unlock(&gspca_dev->queue_lock);
- return ret;
-}
-
-/*
- * dequeue a video buffer
- *
- * If nonblock_ing is false, block until a buffer is available.
- */
-static int vidioc_dqbuf(struct file *file, void *priv,
- struct v4l2_buffer *v4l2_buf)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- struct gspca_frame *frame;
- int i, j, ret;
-
- PDEBUG(D_FRAM, "dqbuf");
-
- if (mutex_lock_interruptible(&gspca_dev->queue_lock))
- return -ERESTARTSYS;
-
- for (;;) {
- ret = frame_ready_nolock(gspca_dev, file, v4l2_buf->memory);
- if (ret < 0)
- goto out;
- if (ret > 0)
- break;
-
- mutex_unlock(&gspca_dev->queue_lock);
-
- if (file->f_flags & O_NONBLOCK)
- return -EAGAIN;
-
- /* wait till a frame is ready */
- ret = wait_event_interruptible_timeout(gspca_dev->wq,
- frame_ready(gspca_dev, file, v4l2_buf->memory),
- msecs_to_jiffies(3000));
- if (ret < 0)
- return ret;
- if (ret == 0)
- return -EIO;
-
- if (mutex_lock_interruptible(&gspca_dev->queue_lock))
- return -ERESTARTSYS;
- }
-
- i = gspca_dev->fr_o;
- j = gspca_dev->fr_queue[i];
- frame = &gspca_dev->frame[j];
-
- gspca_dev->fr_o = (i + 1) % GSPCA_MAX_FRAMES;
-
- frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
- memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);
- PDEBUG(D_FRAM, "dqbuf %d", j);
- ret = 0;
-
- if (gspca_dev->memory == V4L2_MEMORY_USERPTR) {
- if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr,
- frame->data,
- frame->v4l2_buf.bytesused)) {
- PDEBUG(D_ERR|D_STREAM,
- "dqbuf cp to user failed");
- ret = -EFAULT;
- }
- }
-out:
- mutex_unlock(&gspca_dev->queue_lock);
-
- if (ret == 0 && gspca_dev->sd_desc->dq_callback) {
- mutex_lock(&gspca_dev->usb_lock);
- gspca_dev->usb_err = 0;
- if (gspca_dev->present)
- gspca_dev->sd_desc->dq_callback(gspca_dev);
- mutex_unlock(&gspca_dev->usb_lock);
- }
-
- return ret;
-}
-
-/*
- * queue a video buffer
- *
- * Attempting to queue a buffer that has already been
- * queued will return -EINVAL.
- */
-static int vidioc_qbuf(struct file *file, void *priv,
- struct v4l2_buffer *v4l2_buf)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- struct gspca_frame *frame;
- int i, index, ret;
-
- PDEBUG(D_FRAM, "qbuf %d", v4l2_buf->index);
-
- if (mutex_lock_interruptible(&gspca_dev->queue_lock))
- return -ERESTARTSYS;
-
- index = v4l2_buf->index;
- if ((unsigned) index >= gspca_dev->nframes) {
- PDEBUG(D_FRAM,
- "qbuf idx %d >= %d", index, gspca_dev->nframes);
- ret = -EINVAL;
- goto out;
- }
- if (v4l2_buf->memory != gspca_dev->memory) {
- PDEBUG(D_FRAM, "qbuf bad memory type");
- ret = -EINVAL;
- goto out;
- }
-
- frame = &gspca_dev->frame[index];
- if (frame->v4l2_buf.flags & BUF_ALL_FLAGS) {
- PDEBUG(D_FRAM, "qbuf bad state");
- ret = -EINVAL;
- goto out;
- }
-
- frame->v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED;
-
- if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) {
- frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr;
- frame->v4l2_buf.length = v4l2_buf->length;
- }
-
- /* put the buffer in the 'queued' queue */
- i = atomic_read(&gspca_dev->fr_q);
- gspca_dev->fr_queue[i] = index;
- atomic_set(&gspca_dev->fr_q, (i + 1) % GSPCA_MAX_FRAMES);
-
- v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED;
- v4l2_buf->flags &= ~V4L2_BUF_FLAG_DONE;
- ret = 0;
-out:
- mutex_unlock(&gspca_dev->queue_lock);
- return ret;
-}
-
-/*
- * allocate the resources for read()
- */
-static int read_alloc(struct gspca_dev *gspca_dev,
- struct file *file)
-{
- struct v4l2_buffer v4l2_buf;
- int i, ret;
-
- PDEBUG(D_STREAM, "read alloc");
-
- if (mutex_lock_interruptible(&gspca_dev->usb_lock))
- return -ERESTARTSYS;
-
- if (gspca_dev->nframes == 0) {
- struct v4l2_requestbuffers rb;
-
- memset(&rb, 0, sizeof rb);
- rb.count = gspca_dev->nbufread;
- rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- rb.memory = GSPCA_MEMORY_READ;
- ret = vidioc_reqbufs(file, gspca_dev, &rb);
- if (ret != 0) {
- PDEBUG(D_STREAM, "read reqbuf err %d", ret);
- goto out;
- }
- memset(&v4l2_buf, 0, sizeof v4l2_buf);
- v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- v4l2_buf.memory = GSPCA_MEMORY_READ;
- for (i = 0; i < gspca_dev->nbufread; i++) {
- v4l2_buf.index = i;
- ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
- if (ret != 0) {
- PDEBUG(D_STREAM, "read qbuf err: %d", ret);
- goto out;
- }
- }
- }
-
- /* start streaming */
- ret = vidioc_streamon(file, gspca_dev, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- if (ret != 0)
- PDEBUG(D_STREAM, "read streamon err %d", ret);
-out:
- mutex_unlock(&gspca_dev->usb_lock);
- return ret;
-}
-
-static unsigned int dev_poll(struct file *file, poll_table *wait)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- unsigned long req_events = poll_requested_events(wait);
- int ret = 0;
-
- PDEBUG(D_FRAM, "poll");
-
- if (req_events & POLLPRI)
- ret |= v4l2_ctrl_poll(file, wait);
-
- if (req_events & (POLLIN | POLLRDNORM)) {
- /* if reqbufs is not done, the user would use read() */
- if (gspca_dev->memory == GSPCA_MEMORY_NO) {
- if (read_alloc(gspca_dev, file) != 0) {
- ret |= POLLERR;
- goto out;
- }
- }
-
- poll_wait(file, &gspca_dev->wq, wait);
-
- /* check if an image has been received */
- if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) {
- ret |= POLLERR;
- goto out;
- }
- if (gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i))
- ret |= POLLIN | POLLRDNORM;
- mutex_unlock(&gspca_dev->queue_lock);
- }
-
-out:
- if (!gspca_dev->present)
- ret |= POLLHUP;
-
- return ret;
-}
-
-static ssize_t dev_read(struct file *file, char __user *data,
- size_t count, loff_t *ppos)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- struct gspca_frame *frame;
- struct v4l2_buffer v4l2_buf;
- struct timeval timestamp;
- int n, ret, ret2;
-
- PDEBUG(D_FRAM, "read (%zd)", count);
- if (gspca_dev->memory == GSPCA_MEMORY_NO) { /* first time ? */
- ret = read_alloc(gspca_dev, file);
- if (ret != 0)
- return ret;
- }
-
- /* get a frame */
- timestamp = ktime_to_timeval(ktime_get());
- timestamp.tv_sec--;
- n = 2;
- for (;;) {
- memset(&v4l2_buf, 0, sizeof v4l2_buf);
- v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- v4l2_buf.memory = GSPCA_MEMORY_READ;
- ret = vidioc_dqbuf(file, gspca_dev, &v4l2_buf);
- if (ret != 0) {
- PDEBUG(D_STREAM, "read dqbuf err %d", ret);
- return ret;
- }
-
- /* if the process slept for more than 1 second,
- * get a newer frame */
- frame = &gspca_dev->frame[v4l2_buf.index];
- if (--n < 0)
- break; /* avoid infinite loop */
- if (frame->v4l2_buf.timestamp.tv_sec >= timestamp.tv_sec)
- break;
- ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
- if (ret != 0) {
- PDEBUG(D_STREAM, "read qbuf err %d", ret);
- return ret;
- }
- }
-
- /* copy the frame */
- if (count > frame->v4l2_buf.bytesused)
- count = frame->v4l2_buf.bytesused;
- ret = copy_to_user(data, frame->data, count);
- if (ret != 0) {
- PDEBUG(D_ERR|D_STREAM,
- "read cp to user lack %d / %zd", ret, count);
- ret = -EFAULT;
- goto out;
- }
- ret = count;
-out:
- /* in each case, requeue the buffer */
- ret2 = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
- if (ret2 != 0)
- return ret2;
- return ret;
-}
-
-static struct v4l2_file_operations dev_fops = {
- .owner = THIS_MODULE,
- .open = dev_open,
- .release = dev_close,
- .read = dev_read,
- .mmap = dev_mmap,
- .unlocked_ioctl = video_ioctl2,
- .poll = dev_poll,
-};
-
-static const struct v4l2_ioctl_ops dev_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_querymenu = vidioc_querymenu,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
- .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
- .vidioc_g_parm = vidioc_g_parm,
- .vidioc_s_parm = vidioc_s_parm,
- .vidioc_enum_framesizes = vidioc_enum_framesizes,
- .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vidioc_g_register,
- .vidioc_s_register = vidioc_s_register,
-#endif
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static const struct video_device gspca_template = {
- .name = "gspca main driver",
- .fops = &dev_fops,
- .ioctl_ops = &dev_ioctl_ops,
- .release = video_device_release_empty, /* We use v4l2_dev.release */
-};
-
-/* initialize the controls */
-static void ctrls_init(struct gspca_dev *gspca_dev)
-{
- struct gspca_ctrl *ctrl;
- int i;
-
- for (i = 0, ctrl = gspca_dev->cam.ctrls;
- i < gspca_dev->sd_desc->nctrls;
- i++, ctrl++) {
- ctrl->def = gspca_dev->sd_desc->ctrls[i].qctrl.default_value;
- ctrl->val = ctrl->def;
- ctrl->min = gspca_dev->sd_desc->ctrls[i].qctrl.minimum;
- ctrl->max = gspca_dev->sd_desc->ctrls[i].qctrl.maximum;
- }
-}
-
-/*
- * probe and create a new gspca device
- *
- * This function must be called by the sub-driver when it is
- * called for probing a new device.
- */
-int gspca_dev_probe2(struct usb_interface *intf,
- const struct usb_device_id *id,
- const struct sd_desc *sd_desc,
- int dev_size,
- struct module *module)
-{
- struct gspca_dev *gspca_dev;
- struct usb_device *dev = interface_to_usbdev(intf);
- int ret;
-
- pr_info("%s-" GSPCA_VERSION " probing %04x:%04x\n",
- sd_desc->name, id->idVendor, id->idProduct);
-
- /* create the device */
- if (dev_size < sizeof *gspca_dev)
- dev_size = sizeof *gspca_dev;
- gspca_dev = kzalloc(dev_size, GFP_KERNEL);
- if (!gspca_dev) {
- pr_err("couldn't kzalloc gspca struct\n");
- return -ENOMEM;
- }
- gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL);
- if (!gspca_dev->usb_buf) {
- pr_err("out of memory\n");
- ret = -ENOMEM;
- goto out;
- }
- gspca_dev->dev = dev;
- gspca_dev->iface = intf->cur_altsetting->desc.bInterfaceNumber;
-
- /* check if any audio device */
- if (dev->actconfig->desc.bNumInterfaces != 1) {
- int i;
- struct usb_interface *intf2;
-
- for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
- intf2 = dev->actconfig->interface[i];
- if (intf2 != NULL
- && intf2->altsetting != NULL
- && intf2->altsetting->desc.bInterfaceClass ==
- USB_CLASS_AUDIO) {
- gspca_dev->audio = 1;
- break;
- }
- }
- }
-
- gspca_dev->v4l2_dev.release = gspca_release;
- ret = v4l2_device_register(&intf->dev, &gspca_dev->v4l2_dev);
- if (ret)
- goto out;
- gspca_dev->sd_desc = sd_desc;
- gspca_dev->nbufread = 2;
- gspca_dev->empty_packet = -1; /* don't check the empty packets */
- gspca_dev->vdev = gspca_template;
- gspca_dev->vdev.v4l2_dev = &gspca_dev->v4l2_dev;
- video_set_drvdata(&gspca_dev->vdev, gspca_dev);
- set_bit(V4L2_FL_USE_FH_PRIO, &gspca_dev->vdev.flags);
- gspca_dev->module = module;
- gspca_dev->present = 1;
-
- mutex_init(&gspca_dev->usb_lock);
- gspca_dev->vdev.lock = &gspca_dev->usb_lock;
- mutex_init(&gspca_dev->queue_lock);
- init_waitqueue_head(&gspca_dev->wq);
-
- /* configure the subdriver and initialize the USB device */
- ret = sd_desc->config(gspca_dev, id);
- if (ret < 0)
- goto out;
- if (gspca_dev->cam.ctrls != NULL)
- ctrls_init(gspca_dev);
- ret = sd_desc->init(gspca_dev);
- if (ret < 0)
- goto out;
- if (sd_desc->init_controls)
- ret = sd_desc->init_controls(gspca_dev);
- if (ret < 0)
- goto out;
- gspca_set_default_mode(gspca_dev);
-
- ret = gspca_input_connect(gspca_dev);
- if (ret)
- goto out;
-
- /*
- * Don't take usb_lock for these ioctls. This improves latency if
- * usb_lock is taken for a long time, e.g. when changing a control
- * value, and a new frame is ready to be dequeued.
- */
- v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_DQBUF);
- v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QBUF);
- v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QUERYBUF);
- if (!gspca_dev->sd_desc->get_chip_ident)
- v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_G_CHIP_IDENT);
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- if (!gspca_dev->sd_desc->get_chip_ident ||
- !gspca_dev->sd_desc->get_register)
- v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_G_REGISTER);
- if (!gspca_dev->sd_desc->get_chip_ident ||
- !gspca_dev->sd_desc->set_register)
- v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_S_REGISTER);
-#endif
- if (!gspca_dev->sd_desc->get_jcomp)
- v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_G_JPEGCOMP);
- if (!gspca_dev->sd_desc->set_jcomp)
- v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_S_JPEGCOMP);
-
- /* init video stuff */
- ret = video_register_device(&gspca_dev->vdev,
- VFL_TYPE_GRABBER,
- -1);
- if (ret < 0) {
- pr_err("video_register_device err %d\n", ret);
- goto out;
- }
-
- usb_set_intfdata(intf, gspca_dev);
- PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev));
-
- gspca_input_create_urb(gspca_dev);
-
- return 0;
-out:
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- if (gspca_dev->input_dev)
- input_unregister_device(gspca_dev->input_dev);
-#endif
- v4l2_ctrl_handler_free(gspca_dev->vdev.ctrl_handler);
- kfree(gspca_dev->usb_buf);
- kfree(gspca_dev);
- return ret;
-}
-EXPORT_SYMBOL(gspca_dev_probe2);
-
-/* same function as the previous one, but check the interface */
-int gspca_dev_probe(struct usb_interface *intf,
- const struct usb_device_id *id,
- const struct sd_desc *sd_desc,
- int dev_size,
- struct module *module)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
-
- /* we don't handle multi-config cameras */
- if (dev->descriptor.bNumConfigurations != 1) {
- pr_err("%04x:%04x too many config\n",
- id->idVendor, id->idProduct);
- return -ENODEV;
- }
-
- /* the USB video interface must be the first one */
- if (dev->actconfig->desc.bNumInterfaces != 1
- && intf->cur_altsetting->desc.bInterfaceNumber != 0)
- return -ENODEV;
-
- return gspca_dev_probe2(intf, id, sd_desc, dev_size, module);
-}
-EXPORT_SYMBOL(gspca_dev_probe);
-
-/*
- * USB disconnection
- *
- * This function must be called by the sub-driver
- * when the device disconnects, after the specific resources are freed.
- */
-void gspca_disconnect(struct usb_interface *intf)
-{
- struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- struct input_dev *input_dev;
-#endif
-
- PDEBUG(D_PROBE, "%s disconnect",
- video_device_node_name(&gspca_dev->vdev));
-
- mutex_lock(&gspca_dev->usb_lock);
-
- usb_set_intfdata(intf, NULL);
- gspca_dev->dev = NULL;
- gspca_dev->present = 0;
- destroy_urbs(gspca_dev);
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- gspca_input_destroy_urb(gspca_dev);
- input_dev = gspca_dev->input_dev;
- if (input_dev) {
- gspca_dev->input_dev = NULL;
- input_unregister_device(input_dev);
- }
-#endif
- /* Free subdriver's streaming resources / stop sd workqueue(s) */
- if (gspca_dev->sd_desc->stop0 && gspca_dev->streaming)
- gspca_dev->sd_desc->stop0(gspca_dev);
- gspca_dev->streaming = 0;
- wake_up_interruptible(&gspca_dev->wq);
-
- v4l2_device_disconnect(&gspca_dev->v4l2_dev);
- video_unregister_device(&gspca_dev->vdev);
-
- mutex_unlock(&gspca_dev->usb_lock);
-
- /* (this will call gspca_release() immediately or on last close) */
- v4l2_device_put(&gspca_dev->v4l2_dev);
-}
-EXPORT_SYMBOL(gspca_disconnect);
-
-#ifdef CONFIG_PM
-int gspca_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
-
- if (!gspca_dev->streaming)
- return 0;
- mutex_lock(&gspca_dev->usb_lock);
- gspca_dev->frozen = 1; /* avoid urb error messages */
- gspca_dev->usb_err = 0;
- if (gspca_dev->sd_desc->stopN)
- gspca_dev->sd_desc->stopN(gspca_dev);
- destroy_urbs(gspca_dev);
- gspca_input_destroy_urb(gspca_dev);
- gspca_set_alt0(gspca_dev);
- if (gspca_dev->sd_desc->stop0)
- gspca_dev->sd_desc->stop0(gspca_dev);
- mutex_unlock(&gspca_dev->usb_lock);
- return 0;
-}
-EXPORT_SYMBOL(gspca_suspend);
-
-int gspca_resume(struct usb_interface *intf)
-{
- struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
- int streaming, ret = 0;
-
- mutex_lock(&gspca_dev->usb_lock);
- gspca_dev->frozen = 0;
- gspca_dev->usb_err = 0;
- gspca_dev->sd_desc->init(gspca_dev);
- gspca_input_create_urb(gspca_dev);
- /*
- * Most subdrivers send all ctrl values on sd_start and thus
- * only write to the device registers on s_ctrl when streaming ->
- * Clear streaming to avoid setting all ctrls twice.
- */
- streaming = gspca_dev->streaming;
- gspca_dev->streaming = 0;
- if (streaming)
- ret = gspca_init_transfer(gspca_dev);
- mutex_unlock(&gspca_dev->usb_lock);
- return ret;
-}
-EXPORT_SYMBOL(gspca_resume);
-#endif
-
-/* -- module insert / remove -- */
-static int __init gspca_init(void)
-{
- pr_info("v" GSPCA_VERSION " registered\n");
- return 0;
-}
-static void __exit gspca_exit(void)
-{
-}
-
-module_init(gspca_init);
-module_exit(gspca_exit);
-
-#ifdef GSPCA_DEBUG
-module_param_named(debug, gspca_debug, int, 0644);
-MODULE_PARM_DESC(debug,
- "Debug (bit) 0x01:error 0x02:probe 0x04:config"
- " 0x08:stream 0x10:frame 0x20:packet"
- " 0x0100: v4l2");
-#endif
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
deleted file mode 100644
index dc688c7f5e4..00000000000
--- a/drivers/media/video/gspca/gspca.h
+++ /dev/null
@@ -1,259 +0,0 @@
-#ifndef GSPCAV2_H
-#define GSPCAV2_H
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <linux/mutex.h>
-
-/* compilation option */
-/*#define GSPCA_DEBUG 1*/
-
-#ifdef GSPCA_DEBUG
-/* GSPCA our debug messages */
-extern int gspca_debug;
-#define PDEBUG(level, fmt, ...) \
-do { \
- if (gspca_debug & (level)) \
- pr_info(fmt, ##__VA_ARGS__); \
-} while (0)
-
-#define D_ERR 0x01
-#define D_PROBE 0x02
-#define D_CONF 0x04
-#define D_STREAM 0x08
-#define D_FRAM 0x10
-#define D_PACK 0x20
-#define D_USBI 0x00
-#define D_USBO 0x00
-#define D_V4L2 0x0100
-#else
-#define PDEBUG(level, fmt, ...)
-#endif
-
-#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */
-/* image transfers */
-#define MAX_NURBS 4 /* max number of URBs */
-
-
-/* used to list framerates supported by a camera mode (resolution) */
-struct framerates {
- const u8 *rates;
- int nrates;
-};
-
-/* control definition */
-struct gspca_ctrl {
- s16 val; /* current value */
- s16 def; /* default value */
- s16 min, max; /* minimum and maximum values */
-};
-
-/* device information - set at probe time */
-struct cam {
- const struct v4l2_pix_format *cam_mode; /* size nmodes */
- const struct framerates *mode_framerates; /* must have size nmodes,
- * just like cam_mode */
- struct gspca_ctrl *ctrls; /* control table - size nctrls */
- /* may be NULL */
- u32 bulk_size; /* buffer size when image transfer by bulk */
- u32 input_flags; /* value for ENUM_INPUT status flags */
- u8 nmodes; /* size of cam_mode */
- u8 no_urb_create; /* don't create transfer URBs */
- u8 bulk_nurbs; /* number of URBs in bulk mode
- * - cannot be > MAX_NURBS
- * - when 0 and bulk_size != 0 means
- * 1 URB and submit done by subdriver */
- u8 bulk; /* image transfer by 0:isoc / 1:bulk */
- u8 npkt; /* number of packets in an ISOC message
- * 0 is the default value: 32 packets */
- u8 needs_full_bandwidth;/* Set this flag to notify the bandwidth calc.
- * code that the cam fills all image buffers to
- * the max, even when using compression. */
-};
-
-struct gspca_dev;
-struct gspca_frame;
-
-/* subdriver operations */
-typedef int (*cam_op) (struct gspca_dev *);
-typedef void (*cam_v_op) (struct gspca_dev *);
-typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *);
-typedef int (*cam_jpg_op) (struct gspca_dev *,
- struct v4l2_jpegcompression *);
-typedef int (*cam_reg_op) (struct gspca_dev *,
- struct v4l2_dbg_register *);
-typedef int (*cam_ident_op) (struct gspca_dev *,
- struct v4l2_dbg_chip_ident *);
-typedef void (*cam_streamparm_op) (struct gspca_dev *,
- struct v4l2_streamparm *);
-typedef int (*cam_qmnu_op) (struct gspca_dev *,
- struct v4l2_querymenu *);
-typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
- u8 *data,
- int len);
-typedef int (*cam_int_pkt_op) (struct gspca_dev *gspca_dev,
- u8 *data,
- int len);
-
-struct ctrl {
- struct v4l2_queryctrl qctrl;
- int (*set)(struct gspca_dev *, __s32);
- int (*get)(struct gspca_dev *, __s32 *);
- cam_v_op set_control;
-};
-
-/* subdriver description */
-struct sd_desc {
-/* information */
- const char *name; /* sub-driver name */
-/* controls */
- const struct ctrl *ctrls; /* static control definition */
- int nctrls;
-/* mandatory operations */
- cam_cf_op config; /* called on probe */
- cam_op init; /* called on probe and resume */
- cam_op init_controls; /* called on probe */
- cam_op start; /* called on stream on after URBs creation */
- cam_pkt_op pkt_scan;
-/* optional operations */
- cam_op isoc_init; /* called on stream on before getting the EP */
- cam_op isoc_nego; /* called when URB submit failed with NOSPC */
- cam_v_op stopN; /* called on stream off - main alt */
- cam_v_op stop0; /* called on stream off & disconnect - alt 0 */
- cam_v_op dq_callback; /* called when a frame has been dequeued */
- cam_jpg_op get_jcomp;
- cam_jpg_op set_jcomp;
- cam_qmnu_op querymenu;
- cam_streamparm_op get_streamparm;
- cam_streamparm_op set_streamparm;
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- cam_reg_op set_register;
- cam_reg_op get_register;
-#endif
- cam_ident_op get_chip_ident;
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- cam_int_pkt_op int_pkt_scan;
- /* other_input makes the gspca core create gspca_dev->input even when
- int_pkt_scan is NULL, for cams with non interrupt driven buttons */
- u8 other_input;
-#endif
-};
-
-/* packet types when moving from iso buf to frame buf */
-enum gspca_packet_type {
- DISCARD_PACKET,
- FIRST_PACKET,
- INTER_PACKET,
- LAST_PACKET
-};
-
-struct gspca_frame {
- __u8 *data; /* frame buffer */
- int vma_use_count;
- struct v4l2_buffer v4l2_buf;
-};
-
-struct gspca_dev {
- struct video_device vdev; /* !! must be the first item */
- struct module *module; /* subdriver handling the device */
- struct v4l2_device v4l2_dev;
- struct usb_device *dev;
- struct file *capt_file; /* file doing video capture */
- /* protected by queue_lock */
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- struct input_dev *input_dev;
- char phys[64]; /* physical device path */
-#endif
-
- struct cam cam; /* device information */
- const struct sd_desc *sd_desc; /* subdriver description */
- unsigned ctrl_dis; /* disabled controls (bit map) */
- unsigned ctrl_inac; /* inactive controls (bit map) */
- struct v4l2_ctrl_handler ctrl_handler;
-
- /* autogain and exposure or gain control cluster, these are global as
- the autogain/exposure functions in autogain_functions.c use them */
- struct {
- struct v4l2_ctrl *autogain;
- struct v4l2_ctrl *exposure;
- struct v4l2_ctrl *gain;
- int exp_too_low_cnt, exp_too_high_cnt;
- };
-
-#define USB_BUF_SZ 64
- __u8 *usb_buf; /* buffer for USB exchanges */
- struct urb *urb[MAX_NURBS];
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- struct urb *int_urb;
-#endif
-
- __u8 *frbuf; /* buffer for nframes */
- struct gspca_frame frame[GSPCA_MAX_FRAMES];
- u8 *image; /* image beeing filled */
- __u32 frsz; /* frame size */
- u32 image_len; /* current length of image */
- atomic_t fr_q; /* next frame to queue */
- atomic_t fr_i; /* frame being filled */
- signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */
- char nframes; /* number of frames */
- u8 fr_o; /* next frame to dequeue */
- __u8 last_packet_type;
- __s8 empty_packet; /* if (-1) don't check empty packets */
- __u8 streaming; /* protected by both mutexes (*) */
-
- __u8 curr_mode; /* current camera mode */
- __u32 pixfmt; /* current mode parameters */
- __u16 width;
- __u16 height;
- __u32 sequence; /* frame sequence number */
-
- wait_queue_head_t wq; /* wait queue */
- struct mutex usb_lock; /* usb exchange protection */
- struct mutex queue_lock; /* ISOC queue protection */
- int usb_err; /* USB error - protected by usb_lock */
- u16 pkt_size; /* ISOC packet size */
-#ifdef CONFIG_PM
- char frozen; /* suspend - resume */
-#endif
- char present; /* device connected */
- char nbufread; /* number of buffers for read() */
- char memory; /* memory type (V4L2_MEMORY_xxx) */
- __u8 iface; /* USB interface number */
- __u8 alt; /* USB alternate setting */
- u8 audio; /* presence of audio device */
-
- /* (*) These variables are proteced by both usb_lock and queue_lock,
- that is any code setting them is holding *both*, which means that
- any code getting them needs to hold at least one of them */
-};
-
-int gspca_dev_probe(struct usb_interface *intf,
- const struct usb_device_id *id,
- const struct sd_desc *sd_desc,
- int dev_size,
- struct module *module);
-int gspca_dev_probe2(struct usb_interface *intf,
- const struct usb_device_id *id,
- const struct sd_desc *sd_desc,
- int dev_size,
- struct module *module);
-void gspca_disconnect(struct usb_interface *intf);
-void gspca_frame_add(struct gspca_dev *gspca_dev,
- enum gspca_packet_type packet_type,
- const u8 *data,
- int len);
-#ifdef CONFIG_PM
-int gspca_suspend(struct usb_interface *intf, pm_message_t message);
-int gspca_resume(struct usb_interface *intf);
-#endif
-int gspca_expo_autogain(struct gspca_dev *gspca_dev, int avg_lum,
- int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee);
-int gspca_coarse_grained_expo_autogain(struct gspca_dev *gspca_dev,
- int avg_lum, int desired_avg_lum, int deadzone);
-
-#endif /* GSPCAV2_H */
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
deleted file mode 100644
index 26b99310d62..00000000000
--- a/drivers/media/video/gspca/jeilinj.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * Jeilinj subdriver
- *
- * Supports some Jeilin dual-mode cameras which use bulk transport and
- * download raw JPEG data.
- *
- * Copyright (C) 2009 Theodore Kilgore
- *
- * Sportscam DV15 support and control settings are
- * Copyright (C) 2011 Patrice Chotard
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "jeilinj"
-
-#include <linux/slab.h>
-#include "gspca.h"
-#include "jpeg.h"
-
-MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
-MODULE_DESCRIPTION("GSPCA/JEILINJ USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* Default timeouts, in ms */
-#define JEILINJ_CMD_TIMEOUT 500
-#define JEILINJ_CMD_DELAY 160
-#define JEILINJ_DATA_TIMEOUT 1000
-
-/* Maximum transfer size to use. */
-#define JEILINJ_MAX_TRANSFER 0x200
-#define FRAME_HEADER_LEN 0x10
-#define FRAME_START 0xFFFFFFFF
-
-enum {
- SAKAR_57379,
- SPORTSCAM_DV15,
-};
-
-#define CAMQUALITY_MIN 0 /* highest cam quality */
-#define CAMQUALITY_MAX 97 /* lowest cam quality */
-
-/* Structure to hold all of our device specific stuff */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- int blocks_left;
- const struct v4l2_pix_format *cap_mode;
- struct v4l2_ctrl *freq;
- struct v4l2_ctrl *jpegqual;
- /* Driver stuff */
- u8 type;
- u8 quality; /* image quality */
-#define QUALITY_MIN 35
-#define QUALITY_MAX 85
-#define QUALITY_DEF 85
- u8 jpeg_hdr[JPEG_HDR_SZ];
-};
-
-struct jlj_command {
- unsigned char instruction[2];
- unsigned char ack_wanted;
- unsigned char delay;
-};
-
-/* AFAICT these cameras will only do 320x240. */
-static struct v4l2_pix_format jlj_mode[] = {
- { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
- { 640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0}
-};
-
-/*
- * cam uses endpoint 0x03 to send commands, 0x84 for read commands,
- * and 0x82 for bulk transfer.
- */
-
-/* All commands are two bytes only */
-static void jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
-{
- int retval;
-
- if (gspca_dev->usb_err < 0)
- return;
- memcpy(gspca_dev->usb_buf, command, 2);
- retval = usb_bulk_msg(gspca_dev->dev,
- usb_sndbulkpipe(gspca_dev->dev, 3),
- gspca_dev->usb_buf, 2, NULL, 500);
- if (retval < 0) {
- pr_err("command write [%02x] error %d\n",
- gspca_dev->usb_buf[0], retval);
- gspca_dev->usb_err = retval;
- }
-}
-
-/* Responses are one byte only */
-static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char response)
-{
- int retval;
-
- if (gspca_dev->usb_err < 0)
- return;
- retval = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev, 0x84),
- gspca_dev->usb_buf, 1, NULL, 500);
- response = gspca_dev->usb_buf[0];
- if (retval < 0) {
- pr_err("read command [%02x] error %d\n",
- gspca_dev->usb_buf[0], retval);
- gspca_dev->usb_err = retval;
- }
-}
-
-static void setfreq(struct gspca_dev *gspca_dev, s32 val)
-{
- u8 freq_commands[][2] = {
- {0x71, 0x80},
- {0x70, 0x07}
- };
-
- freq_commands[0][1] |= val >> 1;
-
- jlj_write2(gspca_dev, freq_commands[0]);
- jlj_write2(gspca_dev, freq_commands[1]);
-}
-
-static void setcamquality(struct gspca_dev *gspca_dev, s32 val)
-{
- u8 quality_commands[][2] = {
- {0x71, 0x1E},
- {0x70, 0x06}
- };
- u8 camquality;
-
- /* adapt camera quality from jpeg quality */
- camquality = ((QUALITY_MAX - val) * CAMQUALITY_MAX)
- / (QUALITY_MAX - QUALITY_MIN);
- quality_commands[0][1] += camquality;
-
- jlj_write2(gspca_dev, quality_commands[0]);
- jlj_write2(gspca_dev, quality_commands[1]);
-}
-
-static void setautogain(struct gspca_dev *gspca_dev, s32 val)
-{
- u8 autogain_commands[][2] = {
- {0x94, 0x02},
- {0xcf, 0x00}
- };
-
- autogain_commands[1][1] = val << 4;
-
- jlj_write2(gspca_dev, autogain_commands[0]);
- jlj_write2(gspca_dev, autogain_commands[1]);
-}
-
-static void setred(struct gspca_dev *gspca_dev, s32 val)
-{
- u8 setred_commands[][2] = {
- {0x94, 0x02},
- {0xe6, 0x00}
- };
-
- setred_commands[1][1] = val;
-
- jlj_write2(gspca_dev, setred_commands[0]);
- jlj_write2(gspca_dev, setred_commands[1]);
-}
-
-static void setgreen(struct gspca_dev *gspca_dev, s32 val)
-{
- u8 setgreen_commands[][2] = {
- {0x94, 0x02},
- {0xe7, 0x00}
- };
-
- setgreen_commands[1][1] = val;
-
- jlj_write2(gspca_dev, setgreen_commands[0]);
- jlj_write2(gspca_dev, setgreen_commands[1]);
-}
-
-static void setblue(struct gspca_dev *gspca_dev, s32 val)
-{
- u8 setblue_commands[][2] = {
- {0x94, 0x02},
- {0xe9, 0x00}
- };
-
- setblue_commands[1][1] = val;
-
- jlj_write2(gspca_dev, setblue_commands[0]);
- jlj_write2(gspca_dev, setblue_commands[1]);
-}
-
-static int jlj_start(struct gspca_dev *gspca_dev)
-{
- int i;
- int start_commands_size;
- u8 response = 0xff;
- struct sd *sd = (struct sd *) gspca_dev;
- struct jlj_command start_commands[] = {
- {{0x71, 0x81}, 0, 0},
- {{0x70, 0x05}, 0, JEILINJ_CMD_DELAY},
- {{0x95, 0x70}, 1, 0},
- {{0x71, 0x81 - gspca_dev->curr_mode}, 0, 0},
- {{0x70, 0x04}, 0, JEILINJ_CMD_DELAY},
- {{0x95, 0x70}, 1, 0},
- {{0x71, 0x00}, 0, 0}, /* start streaming ??*/
- {{0x70, 0x08}, 0, JEILINJ_CMD_DELAY},
- {{0x95, 0x70}, 1, 0},
-#define SPORTSCAM_DV15_CMD_SIZE 9
- {{0x94, 0x02}, 0, 0},
- {{0xde, 0x24}, 0, 0},
- {{0x94, 0x02}, 0, 0},
- {{0xdd, 0xf0}, 0, 0},
- {{0x94, 0x02}, 0, 0},
- {{0xe3, 0x2c}, 0, 0},
- {{0x94, 0x02}, 0, 0},
- {{0xe4, 0x00}, 0, 0},
- {{0x94, 0x02}, 0, 0},
- {{0xe5, 0x00}, 0, 0},
- {{0x94, 0x02}, 0, 0},
- {{0xe6, 0x2c}, 0, 0},
- {{0x94, 0x03}, 0, 0},
- {{0xaa, 0x00}, 0, 0}
- };
-
- sd->blocks_left = 0;
- /* Under Windows, USB spy shows that only the 9 first start
- * commands are used for SPORTSCAM_DV15 webcam
- */
- if (sd->type == SPORTSCAM_DV15)
- start_commands_size = SPORTSCAM_DV15_CMD_SIZE;
- else
- start_commands_size = ARRAY_SIZE(start_commands);
-
- for (i = 0; i < start_commands_size; i++) {
- jlj_write2(gspca_dev, start_commands[i].instruction);
- if (start_commands[i].delay)
- msleep(start_commands[i].delay);
- if (start_commands[i].ack_wanted)
- jlj_read1(gspca_dev, response);
- }
- setcamquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual));
- msleep(2);
- setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq));
- if (gspca_dev->usb_err < 0)
- PDEBUG(D_ERR, "Start streaming command failed");
- return gspca_dev->usb_err;
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int packet_type;
- u32 header_marker;
-
- PDEBUG(D_STREAM, "Got %d bytes out of %d for Block 0",
- len, JEILINJ_MAX_TRANSFER);
- if (len != JEILINJ_MAX_TRANSFER) {
- PDEBUG(D_PACK, "bad length");
- goto discard;
- }
- /* check if it's start of frame */
- header_marker = ((u32 *)data)[0];
- if (header_marker == FRAME_START) {
- sd->blocks_left = data[0x0a] - 1;
- PDEBUG(D_STREAM, "blocks_left = 0x%x", sd->blocks_left);
- /* Start a new frame, and add the JPEG header, first thing */
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sd->jpeg_hdr, JPEG_HDR_SZ);
- /* Toss line 0 of data block 0, keep the rest. */
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data + FRAME_HEADER_LEN,
- JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
- } else if (sd->blocks_left > 0) {
- PDEBUG(D_STREAM, "%d blocks remaining for frame",
- sd->blocks_left);
- sd->blocks_left -= 1;
- if (sd->blocks_left == 0)
- packet_type = LAST_PACKET;
- else
- packet_type = INTER_PACKET;
- gspca_frame_add(gspca_dev, packet_type,
- data, JEILINJ_MAX_TRANSFER);
- } else
- goto discard;
- return;
-discard:
- /* Discard data until a new frame starts. */
- gspca_dev->last_packet_type = DISCARD_PACKET;
-}
-
-/* This function is called at probe time just before sd_init */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct cam *cam = &gspca_dev->cam;
- struct sd *dev = (struct sd *) gspca_dev;
-
- dev->type = id->driver_info;
- dev->quality = QUALITY_DEF;
-
- cam->cam_mode = jlj_mode;
- cam->nmodes = ARRAY_SIZE(jlj_mode);
- cam->bulk = 1;
- cam->bulk_nurbs = 1;
- cam->bulk_size = JEILINJ_MAX_TRANSFER;
- return 0;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- int i;
- u8 *buf;
- static u8 stop_commands[][2] = {
- {0x71, 0x00},
- {0x70, 0x09},
- {0x71, 0x80},
- {0x70, 0x05}
- };
-
- for (;;) {
- /* get the image remaining blocks */
- usb_bulk_msg(gspca_dev->dev,
- gspca_dev->urb[0]->pipe,
- gspca_dev->urb[0]->transfer_buffer,
- JEILINJ_MAX_TRANSFER, NULL,
- JEILINJ_DATA_TIMEOUT);
-
- /* search for 0xff 0xd9 (EOF for JPEG) */
- i = 0;
- buf = gspca_dev->urb[0]->transfer_buffer;
- while ((i < (JEILINJ_MAX_TRANSFER - 1)) &&
- ((buf[i] != 0xff) || (buf[i+1] != 0xd9)))
- i++;
-
- if (i != (JEILINJ_MAX_TRANSFER - 1))
- /* last remaining block found */
- break;
- }
-
- for (i = 0; i < ARRAY_SIZE(stop_commands); i++)
- jlj_write2(gspca_dev, stop_commands[i]);
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- return gspca_dev->usb_err;
-}
-
-/* Set up for getting frames. */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *dev = (struct sd *) gspca_dev;
-
- /* create the JPEG header */
- jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width,
- 0x21); /* JPEG 422 */
- jpeg_set_qual(dev->jpeg_hdr, dev->quality);
- PDEBUG(D_STREAM, "Start streaming at %dx%d",
- gspca_dev->height, gspca_dev->width);
- jlj_start(gspca_dev);
- return gspca_dev->usb_err;
-}
-
-/* Table of supported USB devices */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x0979, 0x0280), .driver_info = SAKAR_57379},
- {USB_DEVICE(0x0979, 0x0270), .driver_info = SPORTSCAM_DV15},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_POWER_LINE_FREQUENCY:
- setfreq(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_RED_BALANCE:
- setred(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_GAIN:
- setgreen(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_BLUE_BALANCE:
- setblue(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_AUTOGAIN:
- setautogain(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_JPEG_COMPRESSION_QUALITY:
- jpeg_set_qual(sd->jpeg_hdr, ctrl->val);
- setcamquality(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
- static const struct v4l2_ctrl_config custom_autogain = {
- .ops = &sd_ctrl_ops,
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Automatic Gain (and Exposure)",
- .max = 3,
- .step = 1,
- .def = 0,
- };
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 6);
- sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
- V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
- V4L2_CID_POWER_LINE_FREQUENCY_60HZ);
- v4l2_ctrl_new_custom(hdl, &custom_autogain, NULL);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_RED_BALANCE, 0, 3, 1, 2);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 3, 1, 2);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BLUE_BALANCE, 0, 3, 1, 2);
- sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_JPEG_COMPRESSION_QUALITY,
- QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-static int sd_set_jcomp(struct gspca_dev *gspca_dev,
- struct v4l2_jpegcompression *jcomp)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
- return 0;
-}
-
-static int sd_get_jcomp(struct gspca_dev *gspca_dev,
- struct v4l2_jpegcompression *jcomp)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- memset(jcomp, 0, sizeof *jcomp);
- jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
- jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
- | V4L2_JPEG_MARKER_DQT;
- return 0;
-}
-
-
-/* sub-driver description */
-static const struct sd_desc sd_desc_sakar_57379 = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* sub-driver description */
-static const struct sd_desc sd_desc_sportscam_dv15 = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
- .get_jcomp = sd_get_jcomp,
- .set_jcomp = sd_set_jcomp,
-};
-
-static const struct sd_desc *sd_desc[2] = {
- &sd_desc_sakar_57379,
- &sd_desc_sportscam_dv15
-};
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id,
- sd_desc[id->driver_info],
- sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/jl2005bcd.c b/drivers/media/video/gspca/jl2005bcd.c
deleted file mode 100644
index 234777116e5..00000000000
--- a/drivers/media/video/gspca/jl2005bcd.c
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * Jeilin JL2005B/C/D library
- *
- * Copyright (C) 2011 Theodore Kilgore <kilgota@auburn.edu>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define MODULE_NAME "jl2005bcd"
-
-#include <linux/workqueue.h>
-#include <linux/slab.h>
-#include "gspca.h"
-
-
-MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
-MODULE_DESCRIPTION("JL2005B/C/D USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* Default timeouts, in ms */
-#define JL2005C_CMD_TIMEOUT 500
-#define JL2005C_DATA_TIMEOUT 1000
-
-/* Maximum transfer size to use. */
-#define JL2005C_MAX_TRANSFER 0x200
-#define FRAME_HEADER_LEN 16
-
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- unsigned char firmware_id[6];
- const struct v4l2_pix_format *cap_mode;
- /* Driver stuff */
- struct work_struct work_struct;
- struct workqueue_struct *work_thread;
- u8 frame_brightness;
- int block_size; /* block size of camera */
- int vga; /* 1 if vga cam, 0 if cif cam */
-};
-
-
-/* Camera has two resolution settings. What they are depends on model. */
-static const struct v4l2_pix_format cif_mode[] = {
- {176, 144, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
- {352, 288, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
- {640, 480, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-/*
- * cam uses endpoint 0x03 to send commands, 0x84 for read commands,
- * and 0x82 for bulk data transfer.
- */
-
-/* All commands are two bytes only */
-static int jl2005c_write2(struct gspca_dev *gspca_dev, unsigned char *command)
-{
- int retval;
-
- memcpy(gspca_dev->usb_buf, command, 2);
- retval = usb_bulk_msg(gspca_dev->dev,
- usb_sndbulkpipe(gspca_dev->dev, 3),
- gspca_dev->usb_buf, 2, NULL, 500);
- if (retval < 0)
- pr_err("command write [%02x] error %d\n",
- gspca_dev->usb_buf[0], retval);
- return retval;
-}
-
-/* Response to a command is one byte in usb_buf[0], only if requested. */
-static int jl2005c_read1(struct gspca_dev *gspca_dev)
-{
- int retval;
-
- retval = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev, 0x84),
- gspca_dev->usb_buf, 1, NULL, 500);
- if (retval < 0)
- pr_err("read command [0x%02x] error %d\n",
- gspca_dev->usb_buf[0], retval);
- return retval;
-}
-
-/* Response appears in gspca_dev->usb_buf[0] */
-static int jl2005c_read_reg(struct gspca_dev *gspca_dev, unsigned char reg)
-{
- int retval;
-
- static u8 instruction[2] = {0x95, 0x00};
- /* put register to read in byte 1 */
- instruction[1] = reg;
- /* Send the read request */
- retval = jl2005c_write2(gspca_dev, instruction);
- if (retval < 0)
- return retval;
- retval = jl2005c_read1(gspca_dev);
-
- return retval;
-}
-
-static int jl2005c_start_new_frame(struct gspca_dev *gspca_dev)
-{
- int i;
- int retval;
- int frame_brightness = 0;
-
- static u8 instruction[2] = {0x7f, 0x01};
-
- retval = jl2005c_write2(gspca_dev, instruction);
- if (retval < 0)
- return retval;
-
- i = 0;
- while (i < 20 && !frame_brightness) {
- /* If we tried 20 times, give up. */
- retval = jl2005c_read_reg(gspca_dev, 0x7e);
- if (retval < 0)
- return retval;
- frame_brightness = gspca_dev->usb_buf[0];
- retval = jl2005c_read_reg(gspca_dev, 0x7d);
- if (retval < 0)
- return retval;
- i++;
- }
- PDEBUG(D_FRAM, "frame_brightness is 0x%02x", gspca_dev->usb_buf[0]);
- return retval;
-}
-
-static int jl2005c_write_reg(struct gspca_dev *gspca_dev, unsigned char reg,
- unsigned char value)
-{
- int retval;
- u8 instruction[2];
-
- instruction[0] = reg;
- instruction[1] = value;
-
- retval = jl2005c_write2(gspca_dev, instruction);
- if (retval < 0)
- return retval;
-
- return retval;
-}
-
-static int jl2005c_get_firmware_id(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- int i = 0;
- int retval = -1;
- unsigned char regs_to_read[] = {0x57, 0x02, 0x03, 0x5d, 0x5e, 0x5f};
-
- PDEBUG(D_PROBE, "Running jl2005c_get_firmware_id");
- /* Read the first ID byte once for warmup */
- retval = jl2005c_read_reg(gspca_dev, regs_to_read[0]);
- PDEBUG(D_PROBE, "response is %02x", gspca_dev->usb_buf[0]);
- if (retval < 0)
- return retval;
- /* Now actually get the ID string */
- for (i = 0; i < 6; i++) {
- retval = jl2005c_read_reg(gspca_dev, regs_to_read[i]);
- if (retval < 0)
- return retval;
- sd->firmware_id[i] = gspca_dev->usb_buf[0];
- }
- PDEBUG(D_PROBE, "firmware ID is %02x%02x%02x%02x%02x%02x",
- sd->firmware_id[0],
- sd->firmware_id[1],
- sd->firmware_id[2],
- sd->firmware_id[3],
- sd->firmware_id[4],
- sd->firmware_id[5]);
- return 0;
-}
-
-static int jl2005c_stream_start_vga_lg
- (struct gspca_dev *gspca_dev)
-{
- int i;
- int retval = -1;
- static u8 instruction[][2] = {
- {0x05, 0x00},
- {0x7c, 0x00},
- {0x7d, 0x18},
- {0x02, 0x00},
- {0x01, 0x00},
- {0x04, 0x52},
- };
-
- for (i = 0; i < ARRAY_SIZE(instruction); i++) {
- msleep(60);
- retval = jl2005c_write2(gspca_dev, instruction[i]);
- if (retval < 0)
- return retval;
- }
- msleep(60);
- return retval;
-}
-
-static int jl2005c_stream_start_vga_small(struct gspca_dev *gspca_dev)
-{
- int i;
- int retval = -1;
- static u8 instruction[][2] = {
- {0x06, 0x00},
- {0x7c, 0x00},
- {0x7d, 0x1a},
- {0x02, 0x00},
- {0x01, 0x00},
- {0x04, 0x52},
- };
-
- for (i = 0; i < ARRAY_SIZE(instruction); i++) {
- msleep(60);
- retval = jl2005c_write2(gspca_dev, instruction[i]);
- if (retval < 0)
- return retval;
- }
- msleep(60);
- return retval;
-}
-
-static int jl2005c_stream_start_cif_lg(struct gspca_dev *gspca_dev)
-{
- int i;
- int retval = -1;
- static u8 instruction[][2] = {
- {0x05, 0x00},
- {0x7c, 0x00},
- {0x7d, 0x30},
- {0x02, 0x00},
- {0x01, 0x00},
- {0x04, 0x42},
- };
-
- for (i = 0; i < ARRAY_SIZE(instruction); i++) {
- msleep(60);
- retval = jl2005c_write2(gspca_dev, instruction[i]);
- if (retval < 0)
- return retval;
- }
- msleep(60);
- return retval;
-}
-
-static int jl2005c_stream_start_cif_small(struct gspca_dev *gspca_dev)
-{
- int i;
- int retval = -1;
- static u8 instruction[][2] = {
- {0x06, 0x00},
- {0x7c, 0x00},
- {0x7d, 0x32},
- {0x02, 0x00},
- {0x01, 0x00},
- {0x04, 0x42},
- };
-
- for (i = 0; i < ARRAY_SIZE(instruction); i++) {
- msleep(60);
- retval = jl2005c_write2(gspca_dev, instruction[i]);
- if (retval < 0)
- return retval;
- }
- msleep(60);
- return retval;
-}
-
-
-static int jl2005c_stop(struct gspca_dev *gspca_dev)
-{
- int retval;
-
- retval = jl2005c_write_reg(gspca_dev, 0x07, 0x00);
- return retval;
-}
-
-/* This function is called as a workqueue function and runs whenever the camera
- * is streaming data. Because it is a workqueue function it is allowed to sleep
- * so we can use synchronous USB calls. To avoid possible collisions with other
- * threads attempting to use the camera's USB interface the gspca usb_lock is
- * used when performing the one USB control operation inside the workqueue,
- * which tells the camera to close the stream. In practice the only thing
- * which needs to be protected against is the usb_set_interface call that
- * gspca makes during stream_off. Otherwise the camera doesn't provide any
- * controls that the user could try to change.
- */
-static void jl2005c_dostream(struct work_struct *work)
-{
- struct sd *dev = container_of(work, struct sd, work_struct);
- struct gspca_dev *gspca_dev = &dev->gspca_dev;
- int bytes_left = 0; /* bytes remaining in current frame. */
- int data_len; /* size to use for the next read. */
- int header_read = 0;
- unsigned char header_sig[2] = {0x4a, 0x4c};
- int act_len;
- int packet_type;
- int ret;
- u8 *buffer;
-
- buffer = kmalloc(JL2005C_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
- if (!buffer) {
- pr_err("Couldn't allocate USB buffer\n");
- goto quit_stream;
- }
-
- while (gspca_dev->dev && gspca_dev->streaming) {
-#ifdef CONFIG_PM
- if (gspca_dev->frozen)
- break;
-#endif
- /* Check if this is a new frame. If so, start the frame first */
- if (!header_read) {
- mutex_lock(&gspca_dev->usb_lock);
- ret = jl2005c_start_new_frame(gspca_dev);
- mutex_unlock(&gspca_dev->usb_lock);
- if (ret < 0)
- goto quit_stream;
- ret = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev, 0x82),
- buffer, JL2005C_MAX_TRANSFER, &act_len,
- JL2005C_DATA_TIMEOUT);
- PDEBUG(D_PACK,
- "Got %d bytes out of %d for header",
- act_len, JL2005C_MAX_TRANSFER);
- if (ret < 0 || act_len < JL2005C_MAX_TRANSFER)
- goto quit_stream;
- /* Check whether we actually got the first blodk */
- if (memcmp(header_sig, buffer, 2) != 0) {
- pr_err("First block is not the first block\n");
- goto quit_stream;
- }
- /* total size to fetch is byte 7, times blocksize
- * of which we already got act_len */
- bytes_left = buffer[0x07] * dev->block_size - act_len;
- PDEBUG(D_PACK, "bytes_left = 0x%x", bytes_left);
- /* We keep the header. It has other information, too.*/
- packet_type = FIRST_PACKET;
- gspca_frame_add(gspca_dev, packet_type,
- buffer, act_len);
- header_read = 1;
- }
- while (bytes_left > 0 && gspca_dev->dev) {
- data_len = bytes_left > JL2005C_MAX_TRANSFER ?
- JL2005C_MAX_TRANSFER : bytes_left;
- ret = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev, 0x82),
- buffer, data_len, &act_len,
- JL2005C_DATA_TIMEOUT);
- if (ret < 0 || act_len < data_len)
- goto quit_stream;
- PDEBUG(D_PACK,
- "Got %d bytes out of %d for frame",
- data_len, bytes_left);
- bytes_left -= data_len;
- if (bytes_left == 0) {
- packet_type = LAST_PACKET;
- header_read = 0;
- } else
- packet_type = INTER_PACKET;
- gspca_frame_add(gspca_dev, packet_type,
- buffer, data_len);
- }
- }
-quit_stream:
- if (gspca_dev->dev) {
- mutex_lock(&gspca_dev->usb_lock);
- jl2005c_stop(gspca_dev);
- mutex_unlock(&gspca_dev->usb_lock);
- }
- kfree(buffer);
-}
-
-
-
-
-/* This function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct cam *cam;
- struct sd *sd = (struct sd *) gspca_dev;
-
- cam = &gspca_dev->cam;
- /* We don't use the buffer gspca allocates so make it small. */
- cam->bulk_size = 64;
- cam->bulk = 1;
- /* For the rest, the camera needs to be detected */
- jl2005c_get_firmware_id(gspca_dev);
- /* Here are some known firmware IDs
- * First some JL2005B cameras
- * {0x41, 0x07, 0x04, 0x2c, 0xe8, 0xf2} Sakar KidzCam
- * {0x45, 0x02, 0x08, 0xb9, 0x00, 0xd2} No-name JL2005B
- * JL2005C cameras
- * {0x01, 0x0c, 0x16, 0x10, 0xf8, 0xc8} Argus DC-1512
- * {0x12, 0x04, 0x03, 0xc0, 0x00, 0xd8} ICarly
- * {0x86, 0x08, 0x05, 0x02, 0x00, 0xd4} Jazz
- *
- * Based upon this scanty evidence, we can detect a CIF camera by
- * testing byte 0 for 0x4x.
- */
- if ((sd->firmware_id[0] & 0xf0) == 0x40) {
- cam->cam_mode = cif_mode;
- cam->nmodes = ARRAY_SIZE(cif_mode);
- sd->block_size = 0x80;
- } else {
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- sd->block_size = 0x200;
- }
-
- INIT_WORK(&sd->work_struct, jl2005c_dostream);
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- return 0;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
-
- struct sd *sd = (struct sd *) gspca_dev;
- sd->cap_mode = gspca_dev->cam.cam_mode;
-
- switch (gspca_dev->width) {
- case 640:
- PDEBUG(D_STREAM, "Start streaming at vga resolution");
- jl2005c_stream_start_vga_lg(gspca_dev);
- break;
- case 320:
- PDEBUG(D_STREAM, "Start streaming at qvga resolution");
- jl2005c_stream_start_vga_small(gspca_dev);
- break;
- case 352:
- PDEBUG(D_STREAM, "Start streaming at cif resolution");
- jl2005c_stream_start_cif_lg(gspca_dev);
- break;
- case 176:
- PDEBUG(D_STREAM, "Start streaming at qcif resolution");
- jl2005c_stream_start_cif_small(gspca_dev);
- break;
- default:
- pr_err("Unknown resolution specified\n");
- return -1;
- }
-
- /* Start the workqueue function to do the streaming */
- sd->work_thread = create_singlethread_workqueue(MODULE_NAME);
- queue_work(sd->work_thread, &sd->work_struct);
-
- return 0;
-}
-
-/* called on streamoff with alt==0 and on disconnect */
-/* the usb_lock is held at entry - restore on exit */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *dev = (struct sd *) gspca_dev;
-
- /* wait for the work queue to terminate */
- mutex_unlock(&gspca_dev->usb_lock);
- /* This waits for sq905c_dostream to finish */
- destroy_workqueue(dev->work_thread);
- dev->work_thread = NULL;
- mutex_lock(&gspca_dev->usb_lock);
-}
-
-
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .start = sd_start,
- .stop0 = sd_stop0,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x0979, 0x0227)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-/* -- module insert / remove -- */
-static int __init sd_mod_init(void)
-{
- int ret;
-
- ret = usb_register(&sd_driver);
- if (ret < 0)
- return ret;
- return 0;
-}
-static void __exit sd_mod_exit(void)
-{
- usb_deregister(&sd_driver);
-}
-
-module_init(sd_mod_init);
-module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/jpeg.h b/drivers/media/video/gspca/jpeg.h
deleted file mode 100644
index ab54910418b..00000000000
--- a/drivers/media/video/gspca/jpeg.h
+++ /dev/null
@@ -1,168 +0,0 @@
-#ifndef JPEG_H
-#define JPEG_H 1
-/*
- * Insert a JPEG header at start of frame
- *
- * This module is used by the gspca subdrivers.
- * A special case is done for Conexant webcams.
- *
- * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * generation options
- * CONEX_CAM Conexant if present
- */
-
-/* JPEG header */
-static const u8 jpeg_head[] = {
- 0xff, 0xd8, /* jpeg */
-
-/* quantization table quality 50% */
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
-#define JPEG_QT0_OFFSET 7
- 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
- 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
- 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
- 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
- 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
- 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
- 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
- 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
-1,
-#define JPEG_QT1_OFFSET 72
- 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
- 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-
-/* huffman table */
- 0xff, 0xc4, 0x01, 0xa2,
- 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
- 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x03,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
- 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03,
- 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00,
- 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04,
- 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13,
- 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81,
- 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15,
- 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82,
- 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25,
- 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36,
- 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46,
- 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56,
- 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66,
- 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
- 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86,
- 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95,
- 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4,
- 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3,
- 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
- 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
- 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
- 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,
- 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x11, 0x00, 0x02,
- 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05,
- 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01,
- 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06,
- 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22,
- 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1,
- 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62,
- 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25,
- 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28,
- 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
- 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
- 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
- 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
- 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
- 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
- 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
- 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
- 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
- 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
- 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3,
- 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2,
- 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
-#ifdef CONEX_CAM
-/* the Conexant frames start with SOF0 */
-#define JPEG_HDR_SZ 556
-#else
- 0xff, 0xc0, 0x00, 0x11, /* SOF0 (start of frame 0 */
- 0x08, /* data precision */
-#define JPEG_HEIGHT_OFFSET 561
- 0x01, 0xe0, /* height */
- 0x02, 0x80, /* width */
- 0x03, /* component number */
- 0x01,
- 0x21, /* samples Y */
- 0x00, /* quant Y */
- 0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */
- 0x03, 0x11, 0x01,
-
- 0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan) */
- 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
-#define JPEG_HDR_SZ 589
-#endif
-};
-
-/* define the JPEG header */
-static void jpeg_define(u8 *jpeg_hdr,
- int height,
- int width,
- int samplesY)
-{
- memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head);
-#ifndef CONEX_CAM
- jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8;
- jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height;
- jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8;
- jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width;
- jpeg_hdr[JPEG_HEIGHT_OFFSET + 6] = samplesY;
-#endif
-}
-
-/* set the JPEG quality */
-static void jpeg_set_qual(u8 *jpeg_hdr,
- int quality)
-{
- int i, sc;
-
- if (quality < 50)
- sc = 5000 / quality;
- else
- sc = 200 - quality * 2;
- for (i = 0; i < 64; i++) {
- jpeg_hdr[JPEG_QT0_OFFSET + i] =
- (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
- jpeg_hdr[JPEG_QT1_OFFSET + i] =
- (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
- }
-}
-#endif
diff --git a/drivers/media/video/gspca/kinect.c b/drivers/media/video/gspca/kinect.c
deleted file mode 100644
index 40ad6687ee5..00000000000
--- a/drivers/media/video/gspca/kinect.c
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * kinect sensor device camera, gspca driver
- *
- * Copyright (C) 2011 Antonio Ospite <ospite@studenti.unina.it>
- *
- * Based on the OpenKinect project and libfreenect
- * http://openkinect.org/wiki/Init_Analysis
- *
- * Special thanks to Steven Toth and kernellabs.com for sponsoring a Kinect
- * sensor device which I tested the driver on.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "kinect"
-
-#include "gspca.h"
-
-#define CTRL_TIMEOUT 500
-
-MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
-MODULE_DESCRIPTION("GSPCA/Kinect Sensor Device USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-struct pkt_hdr {
- uint8_t magic[2];
- uint8_t pad;
- uint8_t flag;
- uint8_t unk1;
- uint8_t seq;
- uint8_t unk2;
- uint8_t unk3;
- uint32_t timestamp;
-};
-
-struct cam_hdr {
- uint8_t magic[2];
- uint16_t len;
- uint16_t cmd;
- uint16_t tag;
-};
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- uint16_t cam_tag; /* a sequence number for packets */
- uint8_t stream_flag; /* to identify different stream types */
- uint8_t obuf[0x400]; /* output buffer for control commands */
- uint8_t ibuf[0x200]; /* input buffer for control commands */
-};
-
-#define MODE_640x480 0x0001
-#define MODE_640x488 0x0002
-#define MODE_1280x1024 0x0004
-
-#define FORMAT_BAYER 0x0010
-#define FORMAT_UYVY 0x0020
-#define FORMAT_Y10B 0x0040
-
-#define FPS_HIGH 0x0100
-
-static const struct v4l2_pix_format video_camera_mode[] = {
- {640, 480, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = MODE_640x480 | FORMAT_BAYER | FPS_HIGH},
- {640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
- .bytesperline = 640 * 2,
- .sizeimage = 640 * 480 * 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = MODE_640x480 | FORMAT_UYVY},
- {1280, 1024, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
- .bytesperline = 1280,
- .sizeimage = 1280 * 1024,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = MODE_1280x1024 | FORMAT_BAYER},
- {640, 488, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE,
- .bytesperline = 640 * 10 / 8,
- .sizeimage = 640 * 488 * 10 / 8,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = MODE_640x488 | FORMAT_Y10B | FPS_HIGH},
- {1280, 1024, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE,
- .bytesperline = 1280 * 10 / 8,
- .sizeimage = 1280 * 1024 * 10 / 8,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = MODE_1280x1024 | FORMAT_Y10B},
-};
-
-static int kinect_write(struct usb_device *udev, uint8_t *data,
- uint16_t wLength)
-{
- return usb_control_msg(udev,
- usb_sndctrlpipe(udev, 0),
- 0x00,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, 0, data, wLength, CTRL_TIMEOUT);
-}
-
-static int kinect_read(struct usb_device *udev, uint8_t *data, uint16_t wLength)
-{
- return usb_control_msg(udev,
- usb_rcvctrlpipe(udev, 0),
- 0x00,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, 0, data, wLength, CTRL_TIMEOUT);
-}
-
-static int send_cmd(struct gspca_dev *gspca_dev, uint16_t cmd, void *cmdbuf,
- unsigned int cmd_len, void *replybuf, unsigned int reply_len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct usb_device *udev = gspca_dev->dev;
- int res, actual_len;
- uint8_t *obuf = sd->obuf;
- uint8_t *ibuf = sd->ibuf;
- struct cam_hdr *chdr = (void *)obuf;
- struct cam_hdr *rhdr = (void *)ibuf;
-
- if (cmd_len & 1 || cmd_len > (0x400 - sizeof(*chdr))) {
- pr_err("send_cmd: Invalid command length (0x%x)\n", cmd_len);
- return -1;
- }
-
- chdr->magic[0] = 0x47;
- chdr->magic[1] = 0x4d;
- chdr->cmd = cpu_to_le16(cmd);
- chdr->tag = cpu_to_le16(sd->cam_tag);
- chdr->len = cpu_to_le16(cmd_len / 2);
-
- memcpy(obuf+sizeof(*chdr), cmdbuf, cmd_len);
-
- res = kinect_write(udev, obuf, cmd_len + sizeof(*chdr));
- PDEBUG(D_USBO, "Control cmd=%04x tag=%04x len=%04x: %d", cmd,
- sd->cam_tag, cmd_len, res);
- if (res < 0) {
- pr_err("send_cmd: Output control transfer failed (%d)\n", res);
- return res;
- }
-
- do {
- actual_len = kinect_read(udev, ibuf, 0x200);
- } while (actual_len == 0);
- PDEBUG(D_USBO, "Control reply: %d", res);
- if (actual_len < sizeof(*rhdr)) {
- pr_err("send_cmd: Input control transfer failed (%d)\n", res);
- return res;
- }
- actual_len -= sizeof(*rhdr);
-
- if (rhdr->magic[0] != 0x52 || rhdr->magic[1] != 0x42) {
- pr_err("send_cmd: Bad magic %02x %02x\n",
- rhdr->magic[0], rhdr->magic[1]);
- return -1;
- }
- if (rhdr->cmd != chdr->cmd) {
- pr_err("send_cmd: Bad cmd %02x != %02x\n",
- rhdr->cmd, chdr->cmd);
- return -1;
- }
- if (rhdr->tag != chdr->tag) {
- pr_err("send_cmd: Bad tag %04x != %04x\n",
- rhdr->tag, chdr->tag);
- return -1;
- }
- if (cpu_to_le16(rhdr->len) != (actual_len/2)) {
- pr_err("send_cmd: Bad len %04x != %04x\n",
- cpu_to_le16(rhdr->len), (int)(actual_len/2));
- return -1;
- }
-
- if (actual_len > reply_len) {
- pr_warn("send_cmd: Data buffer is %d bytes long, but got %d bytes\n",
- reply_len, actual_len);
- memcpy(replybuf, ibuf+sizeof(*rhdr), reply_len);
- } else {
- memcpy(replybuf, ibuf+sizeof(*rhdr), actual_len);
- }
-
- sd->cam_tag++;
-
- return actual_len;
-}
-
-static int write_register(struct gspca_dev *gspca_dev, uint16_t reg,
- uint16_t data)
-{
- uint16_t reply[2];
- uint16_t cmd[2];
- int res;
-
- cmd[0] = cpu_to_le16(reg);
- cmd[1] = cpu_to_le16(data);
-
- PDEBUG(D_USBO, "Write Reg 0x%04x <= 0x%02x", reg, data);
- res = send_cmd(gspca_dev, 0x03, cmd, 4, reply, 4);
- if (res < 0)
- return res;
- if (res != 2) {
- pr_warn("send_cmd returned %d [%04x %04x], 0000 expected\n",
- res, reply[0], reply[1]);
- }
- return 0;
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
-
- sd->cam_tag = 0;
-
- /* Only video stream is supported for now,
- * which has stream flag = 0x80 */
- sd->stream_flag = 0x80;
-
- cam = &gspca_dev->cam;
-
- cam->cam_mode = video_camera_mode;
- cam->nmodes = ARRAY_SIZE(video_camera_mode);
-
-#if 0
- /* Setting those values is not needed for video stream */
- cam->npkt = 15;
- gspca_dev->pkt_size = 960 * 2;
-#endif
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- PDEBUG(D_PROBE, "Kinect Camera device.");
-
- return 0;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- int mode;
- uint8_t fmt_reg, fmt_val;
- uint8_t res_reg, res_val;
- uint8_t fps_reg, fps_val;
- uint8_t mode_val;
-
- mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
-
- if (mode & FORMAT_Y10B) {
- fmt_reg = 0x19;
- res_reg = 0x1a;
- fps_reg = 0x1b;
- mode_val = 0x03;
- } else {
- fmt_reg = 0x0c;
- res_reg = 0x0d;
- fps_reg = 0x0e;
- mode_val = 0x01;
- }
-
- /* format */
- if (mode & FORMAT_UYVY)
- fmt_val = 0x05;
- else
- fmt_val = 0x00;
-
- if (mode & MODE_1280x1024)
- res_val = 0x02;
- else
- res_val = 0x01;
-
- if (mode & FPS_HIGH)
- fps_val = 0x1e;
- else
- fps_val = 0x0f;
-
-
- /* turn off IR-reset function */
- write_register(gspca_dev, 0x105, 0x00);
-
- /* Reset video stream */
- write_register(gspca_dev, 0x05, 0x00);
-
- /* Due to some ridiculous condition in the firmware, we have to start
- * and stop the depth stream before the camera will hand us 1280x1024
- * IR. This is a stupid workaround, but we've yet to find a better
- * solution.
- *
- * Thanks to Drew Fisher for figuring this out.
- */
- if (mode & (FORMAT_Y10B | MODE_1280x1024)) {
- write_register(gspca_dev, 0x13, 0x01);
- write_register(gspca_dev, 0x14, 0x1e);
- write_register(gspca_dev, 0x06, 0x02);
- write_register(gspca_dev, 0x06, 0x00);
- }
-
- write_register(gspca_dev, fmt_reg, fmt_val);
- write_register(gspca_dev, res_reg, res_val);
- write_register(gspca_dev, fps_reg, fps_val);
-
- /* Start video stream */
- write_register(gspca_dev, 0x05, mode_val);
-
- /* disable Hflip */
- write_register(gspca_dev, 0x47, 0x00);
-
- return 0;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- /* reset video stream */
- write_register(gspca_dev, 0x05, 0x00);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *__data, int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- struct pkt_hdr *hdr = (void *)__data;
- uint8_t *data = __data + sizeof(*hdr);
- int datalen = len - sizeof(*hdr);
-
- uint8_t sof = sd->stream_flag | 1;
- uint8_t mof = sd->stream_flag | 2;
- uint8_t eof = sd->stream_flag | 5;
-
- if (len < 12)
- return;
-
- if (hdr->magic[0] != 'R' || hdr->magic[1] != 'B') {
- pr_warn("[Stream %02x] Invalid magic %02x%02x\n",
- sd->stream_flag, hdr->magic[0], hdr->magic[1]);
- return;
- }
-
- if (hdr->flag == sof)
- gspca_frame_add(gspca_dev, FIRST_PACKET, data, datalen);
-
- else if (hdr->flag == mof)
- gspca_frame_add(gspca_dev, INTER_PACKET, data, datalen);
-
- else if (hdr->flag == eof)
- gspca_frame_add(gspca_dev, LAST_PACKET, data, datalen);
-
- else
- pr_warn("Packet type not recognized...\n");
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
- /*
- .get_streamparm = sd_get_streamparm,
- .set_streamparm = sd_set_streamparm,
- */
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x045e, 0x02ae)},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/konica.c b/drivers/media/video/gspca/konica.c
deleted file mode 100644
index bbf91e07e38..00000000000
--- a/drivers/media/video/gspca/konica.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * Driver for USB webcams based on Konica chipset. This
- * chipset is used in Intel YC76 camera.
- *
- * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
- *
- * Based on the usbvideo v4l1 konicawc driver which is:
- *
- * Copyright (C) 2002 Simon Evans <spse@secret.org.uk>
- *
- * The code for making gspca work with a webcam with 2 isoc endpoints was
- * taken from the benq gspca subdriver which is:
- *
- * Copyright (C) 2009 Jean-Francois Moine (http://moinejf.free.fr)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "konica"
-
-#include <linux/input.h>
-#include "gspca.h"
-
-MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
-MODULE_DESCRIPTION("Konica chipset USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-#define WHITEBAL_REG 0x01
-#define BRIGHTNESS_REG 0x02
-#define SHARPNESS_REG 0x03
-#define CONTRAST_REG 0x04
-#define SATURATION_REG 0x05
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- struct urb *last_data_urb;
- u8 snapshot_pressed;
-};
-
-
-/* .priv is what goes to register 8 for this mode, known working values:
- 0x00 -> 176x144, cropped
- 0x01 -> 176x144, cropped
- 0x02 -> 176x144, cropped
- 0x03 -> 176x144, cropped
- 0x04 -> 176x144, binned
- 0x05 -> 320x240
- 0x06 -> 320x240
- 0x07 -> 160x120, cropped
- 0x08 -> 160x120, cropped
- 0x09 -> 160x120, binned (note has 136 lines)
- 0x0a -> 160x120, binned (note has 136 lines)
- 0x0b -> 160x120, cropped
-*/
-static const struct v4l2_pix_format vga_mode[] = {
- {160, 120, V4L2_PIX_FMT_KONICA420, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 136 * 3 / 2 + 960,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0x0a},
- {176, 144, V4L2_PIX_FMT_KONICA420, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 2 + 960,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0x04},
- {320, 240, V4L2_PIX_FMT_KONICA420, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 2 + 960,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0x05},
-};
-
-static void sd_isoc_irq(struct urb *urb);
-
-static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x02,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value,
- index,
- NULL,
- 0,
- 1000);
- if (ret < 0) {
- pr_err("reg_w err writing %02x to %02x: %d\n",
- value, index, ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void reg_r(struct gspca_dev *gspca_dev, u16 value, u16 index)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- 0x03,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value,
- index,
- gspca_dev->usb_buf,
- 2,
- 1000);
- if (ret < 0) {
- pr_err("reg_r err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void konica_stream_on(struct gspca_dev *gspca_dev)
-{
- reg_w(gspca_dev, 1, 0x0b);
-}
-
-static void konica_stream_off(struct gspca_dev *gspca_dev)
-{
- reg_w(gspca_dev, 0, 0x0b);
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- gspca_dev->cam.cam_mode = vga_mode;
- gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
- gspca_dev->cam.no_urb_create = 1;
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- int i;
-
- /*
- * The konica needs a freaking large time to "boot" (approx 6.5 sec.),
- * and does not want to be bothered while doing so :|
- * Register 0x10 counts from 1 - 3, with 3 being "ready"
- */
- msleep(6000);
- for (i = 0; i < 20; i++) {
- reg_r(gspca_dev, 0, 0x10);
- if (gspca_dev->usb_buf[0] == 3)
- break;
- msleep(100);
- }
- reg_w(gspca_dev, 0, 0x0d);
-
- return gspca_dev->usb_err;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct urb *urb;
- int i, n, packet_size;
- struct usb_host_interface *alt;
- struct usb_interface *intf;
-
- intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
- alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
- if (!alt) {
- pr_err("Couldn't get altsetting\n");
- return -EIO;
- }
-
- packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
-
- n = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
- reg_w(gspca_dev, n, 0x08);
-
- konica_stream_on(gspca_dev);
-
- if (gspca_dev->usb_err)
- return gspca_dev->usb_err;
-
- /* create 4 URBs - 2 on endpoint 0x83 and 2 on 0x082 */
-#if MAX_NURBS < 4
-#error "Not enough URBs in the gspca table"
-#endif
-#define SD_NPKT 32
- for (n = 0; n < 4; n++) {
- i = n & 1 ? 0 : 1;
- packet_size =
- le16_to_cpu(alt->endpoint[i].desc.wMaxPacketSize);
- urb = usb_alloc_urb(SD_NPKT, GFP_KERNEL);
- if (!urb) {
- pr_err("usb_alloc_urb failed\n");
- return -ENOMEM;
- }
- gspca_dev->urb[n] = urb;
- urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev,
- packet_size * SD_NPKT,
- GFP_KERNEL,
- &urb->transfer_dma);
- if (urb->transfer_buffer == NULL) {
- pr_err("usb_buffer_alloc failed\n");
- return -ENOMEM;
- }
-
- urb->dev = gspca_dev->dev;
- urb->context = gspca_dev;
- urb->transfer_buffer_length = packet_size * SD_NPKT;
- urb->pipe = usb_rcvisocpipe(gspca_dev->dev,
- n & 1 ? 0x81 : 0x82);
- urb->transfer_flags = URB_ISO_ASAP
- | URB_NO_TRANSFER_DMA_MAP;
- urb->interval = 1;
- urb->complete = sd_isoc_irq;
- urb->number_of_packets = SD_NPKT;
- for (i = 0; i < SD_NPKT; i++) {
- urb->iso_frame_desc[i].length = packet_size;
- urb->iso_frame_desc[i].offset = packet_size * i;
- }
- }
-
- return 0;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- konica_stream_off(gspca_dev);
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- /* Don't keep the button in the pressed state "forever" if it was
- pressed when streaming is stopped */
- if (sd->snapshot_pressed) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
- input_sync(gspca_dev->input_dev);
- sd->snapshot_pressed = 0;
- }
-#endif
-}
-
-/* reception of an URB */
-static void sd_isoc_irq(struct urb *urb)
-{
- struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
- struct sd *sd = (struct sd *) gspca_dev;
- struct urb *data_urb, *status_urb;
- u8 *data;
- int i, st;
-
- PDEBUG(D_PACK, "sd isoc irq");
- if (!gspca_dev->streaming)
- return;
-
- if (urb->status != 0) {
- if (urb->status == -ESHUTDOWN)
- return; /* disconnection */
-#ifdef CONFIG_PM
- if (gspca_dev->frozen)
- return;
-#endif
- PDEBUG(D_ERR, "urb status: %d", urb->status);
- st = usb_submit_urb(urb, GFP_ATOMIC);
- if (st < 0)
- pr_err("resubmit urb error %d\n", st);
- return;
- }
-
- /* if this is a data URB (ep 0x82), wait */
- if (urb->transfer_buffer_length > 32) {
- sd->last_data_urb = urb;
- return;
- }
-
- status_urb = urb;
- data_urb = sd->last_data_urb;
- sd->last_data_urb = NULL;
-
- if (!data_urb || data_urb->start_frame != status_urb->start_frame) {
- PDEBUG(D_ERR|D_PACK, "lost sync on frames");
- goto resubmit;
- }
-
- if (data_urb->number_of_packets != status_urb->number_of_packets) {
- PDEBUG(D_ERR|D_PACK,
- "no packets does not match, data: %d, status: %d",
- data_urb->number_of_packets,
- status_urb->number_of_packets);
- goto resubmit;
- }
-
- for (i = 0; i < status_urb->number_of_packets; i++) {
- if (data_urb->iso_frame_desc[i].status ||
- status_urb->iso_frame_desc[i].status) {
- PDEBUG(D_ERR|D_PACK,
- "pkt %d data-status %d, status-status %d", i,
- data_urb->iso_frame_desc[i].status,
- status_urb->iso_frame_desc[i].status);
- gspca_dev->last_packet_type = DISCARD_PACKET;
- continue;
- }
-
- if (status_urb->iso_frame_desc[i].actual_length != 1) {
- PDEBUG(D_ERR|D_PACK,
- "bad status packet length %d",
- status_urb->iso_frame_desc[i].actual_length);
- gspca_dev->last_packet_type = DISCARD_PACKET;
- continue;
- }
-
- st = *((u8 *)status_urb->transfer_buffer
- + status_urb->iso_frame_desc[i].offset);
-
- data = (u8 *)data_urb->transfer_buffer
- + data_urb->iso_frame_desc[i].offset;
-
- /* st: 0x80-0xff: frame start with frame number (ie 0-7f)
- * otherwise:
- * bit 0 0: keep packet
- * 1: drop packet (padding data)
- *
- * bit 4 0 button not clicked
- * 1 button clicked
- * button is used to `take a picture' (in software)
- */
- if (st & 0x80) {
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
- gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
- } else {
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- u8 button_state = st & 0x40 ? 1 : 0;
- if (sd->snapshot_pressed != button_state) {
- input_report_key(gspca_dev->input_dev,
- KEY_CAMERA,
- button_state);
- input_sync(gspca_dev->input_dev);
- sd->snapshot_pressed = button_state;
- }
-#endif
- if (st & 0x01)
- continue;
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, data,
- data_urb->iso_frame_desc[i].actual_length);
- }
-
-resubmit:
- if (data_urb) {
- st = usb_submit_urb(data_urb, GFP_ATOMIC);
- if (st < 0)
- PDEBUG(D_ERR|D_PACK,
- "usb_submit_urb(data_urb) ret %d", st);
- }
- st = usb_submit_urb(status_urb, GFP_ATOMIC);
- if (st < 0)
- pr_err("usb_submit_urb(status_urb) ret %d\n", st);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- konica_stream_off(gspca_dev);
- reg_w(gspca_dev, ctrl->val, BRIGHTNESS_REG);
- konica_stream_on(gspca_dev);
- break;
- case V4L2_CID_CONTRAST:
- konica_stream_off(gspca_dev);
- reg_w(gspca_dev, ctrl->val, CONTRAST_REG);
- konica_stream_on(gspca_dev);
- break;
- case V4L2_CID_SATURATION:
- konica_stream_off(gspca_dev);
- reg_w(gspca_dev, ctrl->val, SATURATION_REG);
- konica_stream_on(gspca_dev);
- break;
- case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
- konica_stream_off(gspca_dev);
- reg_w(gspca_dev, ctrl->val, WHITEBAL_REG);
- konica_stream_on(gspca_dev);
- break;
- case V4L2_CID_SHARPNESS:
- konica_stream_off(gspca_dev);
- reg_w(gspca_dev, ctrl->val, SHARPNESS_REG);
- konica_stream_on(gspca_dev);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 5);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 9, 1, 4);
- /* Needs to be verified */
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 9, 1, 4);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0, 9, 1, 4);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_WHITE_BALANCE_TEMPERATURE,
- 0, 33, 1, 25);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SHARPNESS, 0, 9, 1, 4);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .other_input = 1,
-#endif
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x04c8, 0x0720)}, /* Intel YC 76 */
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/m5602/Kconfig b/drivers/media/video/gspca/m5602/Kconfig
deleted file mode 100644
index 5a69016ed75..00000000000
--- a/drivers/media/video/gspca/m5602/Kconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-config USB_M5602
- tristate "ALi USB m5602 Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
- Say Y here if you want support for cameras based on the
- ALi m5602 connected to various image sensors.
-
- See <file:Documentation/video4linux/m5602.txt> for more info.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_m5602.
diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/video/gspca/m5602/Makefile
deleted file mode 100644
index 575b75bacb6..00000000000
--- a/drivers/media/video/gspca/m5602/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-obj-$(CONFIG_USB_M5602) += gspca_m5602.o
-
-gspca_m5602-objs := m5602_core.o \
- m5602_ov9650.o \
- m5602_ov7660.o \
- m5602_mt9m111.o \
- m5602_po1030.o \
- m5602_s5k83a.o \
- m5602_s5k4aa.o
-
-ccflags-y += -I$(srctree)/drivers/media/video/gspca
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h
deleted file mode 100644
index 51af3ee3ab8..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * USB Driver for ALi m5602 based webcams
- *
- * Copyright (C) 2008 Erik Andrén
- * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#ifndef M5602_BRIDGE_H_
-#define M5602_BRIDGE_H_
-
-#include <linux/slab.h>
-#include "gspca.h"
-
-#define MODULE_NAME "ALi m5602"
-
-/*****************************************************************************/
-
-#define M5602_XB_SENSOR_TYPE 0x00
-#define M5602_XB_SENSOR_CTRL 0x01
-#define M5602_XB_LINE_OF_FRAME_H 0x02
-#define M5602_XB_LINE_OF_FRAME_L 0x03
-#define M5602_XB_PIX_OF_LINE_H 0x04
-#define M5602_XB_PIX_OF_LINE_L 0x05
-#define M5602_XB_VSYNC_PARA 0x06
-#define M5602_XB_HSYNC_PARA 0x07
-#define M5602_XB_TEST_MODE_1 0x08
-#define M5602_XB_TEST_MODE_2 0x09
-#define M5602_XB_SIG_INI 0x0a
-#define M5602_XB_DS_PARA 0x0e
-#define M5602_XB_TRIG_PARA 0x0f
-#define M5602_XB_CLK_PD 0x10
-#define M5602_XB_MCU_CLK_CTRL 0x12
-#define M5602_XB_MCU_CLK_DIV 0x13
-#define M5602_XB_SEN_CLK_CTRL 0x14
-#define M5602_XB_SEN_CLK_DIV 0x15
-#define M5602_XB_AUD_CLK_CTRL 0x16
-#define M5602_XB_AUD_CLK_DIV 0x17
-#define M5602_OB_AC_LINK_STATE 0x22
-#define M5602_OB_PCM_SLOT_INDEX 0x24
-#define M5602_OB_GPIO_SLOT_INDEX 0x25
-#define M5602_OB_ACRX_STATUS_ADDRESS_H 0x28
-#define M5602_OB_ACRX_STATUS_DATA_L 0x29
-#define M5602_OB_ACRX_STATUS_DATA_H 0x2a
-#define M5602_OB_ACTX_COMMAND_ADDRESS 0x31
-#define M5602_OB_ACRX_COMMAND_DATA_L 0x32
-#define M5602_OB_ACTX_COMMAND_DATA_H 0X33
-#define M5602_XB_DEVCTR1 0x41
-#define M5602_XB_EPSETR0 0x42
-#define M5602_XB_EPAFCTR 0x47
-#define M5602_XB_EPBFCTR 0x49
-#define M5602_XB_EPEFCTR 0x4f
-#define M5602_XB_TEST_REG 0x53
-#define M5602_XB_ALT2SIZE 0x54
-#define M5602_XB_ALT3SIZE 0x55
-#define M5602_XB_OBSFRAME 0x56
-#define M5602_XB_PWR_CTL 0x59
-#define M5602_XB_ADC_CTRL 0x60
-#define M5602_XB_ADC_DATA 0x61
-#define M5602_XB_MISC_CTRL 0x62
-#define M5602_XB_SNAPSHOT 0x63
-#define M5602_XB_SCRATCH_1 0x64
-#define M5602_XB_SCRATCH_2 0x65
-#define M5602_XB_SCRATCH_3 0x66
-#define M5602_XB_SCRATCH_4 0x67
-#define M5602_XB_I2C_CTRL 0x68
-#define M5602_XB_I2C_CLK_DIV 0x69
-#define M5602_XB_I2C_DEV_ADDR 0x6a
-#define M5602_XB_I2C_REG_ADDR 0x6b
-#define M5602_XB_I2C_DATA 0x6c
-#define M5602_XB_I2C_STATUS 0x6d
-#define M5602_XB_GPIO_DAT_H 0x70
-#define M5602_XB_GPIO_DAT_L 0x71
-#define M5602_XB_GPIO_DIR_H 0x72
-#define M5602_XB_GPIO_DIR_L 0x73
-#define M5602_XB_GPIO_EN_H 0x74
-#define M5602_XB_GPIO_EN_L 0x75
-#define M5602_XB_GPIO_DAT 0x76
-#define M5602_XB_GPIO_DIR 0x77
-#define M5602_XB_SEN_CLK_CONTROL 0x80
-#define M5602_XB_SEN_CLK_DIVISION 0x81
-#define M5602_XB_CPR_CLK_CONTROL 0x82
-#define M5602_XB_CPR_CLK_DIVISION 0x83
-#define M5602_XB_MCU_CLK_CONTROL 0x84
-#define M5602_XB_MCU_CLK_DIVISION 0x85
-#define M5602_XB_DCT_CLK_CONTROL 0x86
-#define M5602_XB_DCT_CLK_DIVISION 0x87
-#define M5602_XB_EC_CLK_CONTROL 0x88
-#define M5602_XB_EC_CLK_DIVISION 0x89
-#define M5602_XB_LBUF_CLK_CONTROL 0x8a
-#define M5602_XB_LBUF_CLK_DIVISION 0x8b
-
-#define I2C_BUSY 0x80
-
-/*****************************************************************************/
-
-/* Driver info */
-#define DRIVER_AUTHOR "ALi m5602 Linux Driver Project"
-#define DRIVER_DESC "ALi m5602 webcam driver"
-
-#define M5602_ISOC_ENDPOINT_ADDR 0x81
-#define M5602_INTR_ENDPOINT_ADDR 0x82
-
-#define M5602_URB_MSG_TIMEOUT 5000
-
-/*****************************************************************************/
-
-/* A skeleton used for sending messages to the m5602 bridge */
-static const unsigned char bridge_urb_skeleton[] = {
- 0x13, 0x00, 0x81, 0x00
-};
-
-/* A skeleton used for sending messages to the sensor */
-static const unsigned char sensor_urb_skeleton[] = {
- 0x23, M5602_XB_GPIO_EN_H, 0x81, 0x06,
- 0x23, M5602_XB_MISC_CTRL, 0x81, 0x80,
- 0x13, M5602_XB_I2C_DEV_ADDR, 0x81, 0x00,
- 0x13, M5602_XB_I2C_REG_ADDR, 0x81, 0x00,
- 0x13, M5602_XB_I2C_DATA, 0x81, 0x00,
- 0x13, M5602_XB_I2C_CTRL, 0x81, 0x11
-};
-
-struct sd {
- struct gspca_dev gspca_dev;
-
- /* A pointer to the currently connected sensor */
- const struct m5602_sensor *sensor;
-
- struct sd_desc *desc;
-
- /* Sensor private data */
- void *sensor_priv;
-
- /* The current frame's id, used to detect frame boundaries */
- u8 frame_id;
-
- /* The current frame count */
- u32 frame_count;
-};
-
-int m5602_read_bridge(
- struct sd *sd, const u8 address, u8 *i2c_data);
-
-int m5602_write_bridge(
- struct sd *sd, const u8 address, const u8 i2c_data);
-
-int m5602_write_sensor(struct sd *sd, const u8 address,
- u8 *i2c_data, const u8 len);
-
-int m5602_read_sensor(struct sd *sd, const u8 address,
- u8 *i2c_data, const u8 len);
-
-#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
deleted file mode 100644
index ed22638978c..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ /dev/null
@@ -1,424 +0,0 @@
- /*
- * USB Driver for ALi m5602 based webcams
- *
- * Copyright (C) 2008 Erik Andrén
- * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "m5602_ov9650.h"
-#include "m5602_ov7660.h"
-#include "m5602_mt9m111.h"
-#include "m5602_po1030.h"
-#include "m5602_s5k83a.h"
-#include "m5602_s5k4aa.h"
-
-/* Kernel module parameters */
-int force_sensor;
-static bool dump_bridge;
-bool dump_sensor;
-
-static const struct usb_device_id m5602_table[] = {
- {USB_DEVICE(0x0402, 0x5602)},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, m5602_table);
-
-/* Reads a byte from the m5602 */
-int m5602_read_bridge(struct sd *sd, const u8 address, u8 *i2c_data)
-{
- int err;
- struct usb_device *udev = sd->gspca_dev.dev;
- __u8 *buf = sd->gspca_dev.usb_buf;
-
- err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- 0x04, 0xc0, 0x14,
- 0x8100 + address, buf,
- 1, M5602_URB_MSG_TIMEOUT);
- *i2c_data = buf[0];
-
- PDEBUG(D_CONF, "Reading bridge register 0x%x containing 0x%x",
- address, *i2c_data);
-
- /* usb_control_msg(...) returns the number of bytes sent upon success,
- mask that and return zero instead*/
- return (err < 0) ? err : 0;
-}
-
-/* Writes a byte to the m5602 */
-int m5602_write_bridge(struct sd *sd, const u8 address, const u8 i2c_data)
-{
- int err;
- struct usb_device *udev = sd->gspca_dev.dev;
- __u8 *buf = sd->gspca_dev.usb_buf;
-
- PDEBUG(D_CONF, "Writing bridge register 0x%x with 0x%x",
- address, i2c_data);
-
- memcpy(buf, bridge_urb_skeleton,
- sizeof(bridge_urb_skeleton));
- buf[1] = address;
- buf[3] = i2c_data;
-
- err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- 0x04, 0x40, 0x19,
- 0x0000, buf,
- 4, M5602_URB_MSG_TIMEOUT);
-
- /* usb_control_msg(...) returns the number of bytes sent upon success,
- mask that and return zero instead */
- return (err < 0) ? err : 0;
-}
-
-static int m5602_wait_for_i2c(struct sd *sd)
-{
- int err;
- u8 data;
-
- do {
- err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, &data);
- } while ((data & I2C_BUSY) && !err);
- return err;
-}
-
-int m5602_read_sensor(struct sd *sd, const u8 address,
- u8 *i2c_data, const u8 len)
-{
- int err, i;
-
- if (!len || len > sd->sensor->i2c_regW)
- return -EINVAL;
-
- err = m5602_wait_for_i2c(sd);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
- sd->sensor->i2c_slave_id);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
- if (err < 0)
- return err;
-
- /* Sensors with registers that are of only
- one byte width are differently read */
-
- /* FIXME: This works with the ov9650, but has issues with the po1030 */
- if (sd->sensor->i2c_regW == 1) {
- err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 1);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
- } else {
- err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
- }
-
- for (i = 0; (i < len) && !err; i++) {
- err = m5602_wait_for_i2c(sd);
- if (err < 0)
- return err;
-
- err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
-
- PDEBUG(D_CONF, "Reading sensor register "
- "0x%x containing 0x%x ", address, *i2c_data);
- }
- return err;
-}
-
-int m5602_write_sensor(struct sd *sd, const u8 address,
- u8 *i2c_data, const u8 len)
-{
- int err, i;
- u8 *p;
- struct usb_device *udev = sd->gspca_dev.dev;
- __u8 *buf = sd->gspca_dev.usb_buf;
-
- /* No sensor with a data width larger than 16 bits has yet been seen */
- if (len > sd->sensor->i2c_regW || !len)
- return -EINVAL;
-
- memcpy(buf, sensor_urb_skeleton,
- sizeof(sensor_urb_skeleton));
-
- buf[11] = sd->sensor->i2c_slave_id;
- buf[15] = address;
-
- /* Special case larger sensor writes */
- p = buf + 16;
-
- /* Copy a four byte write sequence for each byte to be written to */
- for (i = 0; i < len; i++) {
- memcpy(p, sensor_urb_skeleton + 16, 4);
- p[3] = i2c_data[i];
- p += 4;
- PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
- address, i2c_data[i]);
- }
-
- /* Copy the tailer */
- memcpy(p, sensor_urb_skeleton + 20, 4);
-
- /* Set the total length */
- p[3] = 0x10 + len;
-
- err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- 0x04, 0x40, 0x19,
- 0x0000, buf,
- 20 + len * 4, M5602_URB_MSG_TIMEOUT);
-
- return (err < 0) ? err : 0;
-}
-
-/* Dump all the registers of the m5602 bridge,
- unfortunately this breaks the camera until it's power cycled */
-static void m5602_dump_bridge(struct sd *sd)
-{
- int i;
- for (i = 0; i < 0x80; i++) {
- unsigned char val = 0;
- m5602_read_bridge(sd, i, &val);
- pr_info("ALi m5602 address 0x%x contains 0x%x\n", i, val);
- }
- pr_info("Warning: The ALi m5602 webcam probably won't work until it's power cycled\n");
-}
-
-static int m5602_probe_sensor(struct sd *sd)
-{
- /* Try the po1030 */
- sd->sensor = &po1030;
- if (!sd->sensor->probe(sd))
- return 0;
-
- /* Try the mt9m111 sensor */
- sd->sensor = &mt9m111;
- if (!sd->sensor->probe(sd))
- return 0;
-
- /* Try the s5k4aa */
- sd->sensor = &s5k4aa;
- if (!sd->sensor->probe(sd))
- return 0;
-
- /* Try the ov9650 */
- sd->sensor = &ov9650;
- if (!sd->sensor->probe(sd))
- return 0;
-
- /* Try the ov7660 */
- sd->sensor = &ov7660;
- if (!sd->sensor->probe(sd))
- return 0;
-
- /* Try the s5k83a */
- sd->sensor = &s5k83a;
- if (!sd->sensor->probe(sd))
- return 0;
-
- /* More sensor probe function goes here */
- pr_info("Failed to find a sensor\n");
- sd->sensor = NULL;
- return -ENODEV;
-}
-
-static int m5602_configure(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id);
-
-static int m5602_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int err;
-
- PDEBUG(D_CONF, "Initializing ALi m5602 webcam");
- /* Run the init sequence */
- err = sd->sensor->init(sd);
-
- return err;
-}
-
-static int m5602_start_transfer(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- __u8 *buf = sd->gspca_dev.usb_buf;
- int err;
-
- /* Send start command to the camera */
- const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01};
-
- if (sd->sensor->start)
- sd->sensor->start(sd);
-
- memcpy(buf, buffer, sizeof(buffer));
- err = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x04, 0x40, 0x19, 0x0000, buf,
- sizeof(buffer), M5602_URB_MSG_TIMEOUT);
-
- PDEBUG(D_STREAM, "Transfer started");
- return (err < 0) ? err : 0;
-}
-
-static void m5602_urb_complete(struct gspca_dev *gspca_dev,
- u8 *data, int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (len < 6) {
- PDEBUG(D_PACK, "Packet is less than 6 bytes");
- return;
- }
-
- /* Frame delimiter: ff xx xx xx ff ff */
- if (data[0] == 0xff && data[4] == 0xff && data[5] == 0xff &&
- data[2] != sd->frame_id) {
- PDEBUG(D_FRAM, "Frame delimiter detected");
- sd->frame_id = data[2];
-
- /* Remove the extra fluff appended on each header */
- data += 6;
- len -= 6;
-
- /* Complete the last frame (if any) */
- gspca_frame_add(gspca_dev, LAST_PACKET,
- NULL, 0);
- sd->frame_count++;
-
- /* Create a new frame */
- gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
-
- PDEBUG(D_FRAM, "Starting new frame %d",
- sd->frame_count);
-
- } else {
- int cur_frame_len;
-
- cur_frame_len = gspca_dev->image_len;
- /* Remove urb header */
- data += 4;
- len -= 4;
-
- if (cur_frame_len + len <= gspca_dev->frsz) {
- PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
- sd->frame_count, len);
-
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data, len);
- } else {
- /* Add the remaining data up to frame size */
- gspca_frame_add(gspca_dev, INTER_PACKET, data,
- gspca_dev->frsz - cur_frame_len);
- }
- }
-}
-
-static void m5602_stop_transfer(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* Run the sensor specific end transfer sequence */
- if (sd->sensor->stop)
- sd->sensor->stop(sd);
-}
-
-/* sub-driver description, the ctrl and nctrl is filled at probe time */
-static struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = m5602_configure,
- .init = m5602_init,
- .start = m5602_start_transfer,
- .stopN = m5602_stop_transfer,
- .pkt_scan = m5602_urb_complete
-};
-
-/* this function is called at probe time */
-static int m5602_configure(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
- int err;
-
- cam = &gspca_dev->cam;
- sd->desc = &sd_desc;
-
- if (dump_bridge)
- m5602_dump_bridge(sd);
-
- /* Probe sensor */
- err = m5602_probe_sensor(sd);
- if (err)
- goto fail;
-
- return 0;
-
-fail:
- PDEBUG(D_ERR, "ALi m5602 webcam failed");
- cam->cam_mode = NULL;
- cam->nmodes = 0;
-
- return err;
-}
-
-static int m5602_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static void m5602_disconnect(struct usb_interface *intf)
-{
- struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor->disconnect)
- sd->sensor->disconnect(sd);
-
- gspca_disconnect(intf);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = m5602_table,
- .probe = m5602_probe,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
- .disconnect = m5602_disconnect
-};
-
-module_usb_driver(sd_driver);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-module_param(force_sensor, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(force_sensor,
- "forces detection of a sensor, "
- "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, "
- "4 = MT9M111, 5 = PO1030, 6 = OV7660");
-
-module_param(dump_bridge, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup");
-
-module_param(dump_sensor, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(dump_sensor, "Dumps all usb sensor registers "
- "at startup providing a sensor is found");
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
deleted file mode 100644
index 6268aa24ec5..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ /dev/null
@@ -1,647 +0,0 @@
-/*
- * Driver for the mt9m111 sensor
- *
- * Copyright (C) 2008 Erik Andrén
- * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "m5602_mt9m111.h"
-
-static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 val);
-static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 *val);
-static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
-static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
-static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
-static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
-static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
-static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
-
-static struct v4l2_pix_format mt9m111_modes[] = {
- {
- 640,
- 480,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage = 640 * 480,
- .bytesperline = 640,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- }
-};
-
-static const struct ctrl mt9m111_ctrls[] = {
-#define VFLIP_IDX 0
- {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = mt9m111_set_vflip,
- .get = mt9m111_get_vflip
- },
-#define HFLIP_IDX 1
- {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = mt9m111_set_hflip,
- .get = mt9m111_get_hflip
- },
-#define GAIN_IDX 2
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "gain",
- .minimum = 0,
- .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2,
- .step = 1,
- .default_value = MT9M111_DEFAULT_GAIN,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = mt9m111_set_gain,
- .get = mt9m111_get_gain
- },
-#define AUTO_WHITE_BALANCE_IDX 3
- {
- {
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto white balance",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- .set = mt9m111_set_auto_white_balance,
- .get = mt9m111_get_auto_white_balance
- },
-#define GREEN_BALANCE_IDX 4
- {
- {
- .id = M5602_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x7ff,
- .step = 0x1,
- .default_value = MT9M111_GREEN_GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = mt9m111_set_green_balance,
- .get = mt9m111_get_green_balance
- },
-#define BLUE_BALANCE_IDX 5
- {
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x7ff,
- .step = 0x1,
- .default_value = MT9M111_BLUE_GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = mt9m111_set_blue_balance,
- .get = mt9m111_get_blue_balance
- },
-#define RED_BALANCE_IDX 5
- {
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x7ff,
- .step = 0x1,
- .default_value = MT9M111_RED_GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = mt9m111_set_red_balance,
- .get = mt9m111_get_red_balance
- },
-};
-
-static void mt9m111_dump_registers(struct sd *sd);
-
-int mt9m111_probe(struct sd *sd)
-{
- u8 data[2] = {0x00, 0x00};
- int i;
- s32 *sensor_settings;
-
- if (force_sensor) {
- if (force_sensor == MT9M111_SENSOR) {
- pr_info("Forcing a %s sensor\n", mt9m111.name);
- goto sensor_found;
- }
- /* If we want to force another sensor, don't try to probe this
- * one */
- return -ENODEV;
- }
-
- PDEBUG(D_PROBE, "Probing for a mt9m111 sensor");
-
- /* Do the preinit */
- for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) {
- if (preinit_mt9m111[i][0] == BRIDGE) {
- m5602_write_bridge(sd,
- preinit_mt9m111[i][1],
- preinit_mt9m111[i][2]);
- } else {
- data[0] = preinit_mt9m111[i][2];
- data[1] = preinit_mt9m111[i][3];
- m5602_write_sensor(sd,
- preinit_mt9m111[i][1], data, 2);
- }
- }
-
- if (m5602_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2))
- return -ENODEV;
-
- if ((data[0] == 0x14) && (data[1] == 0x3a)) {
- pr_info("Detected a mt9m111 sensor\n");
- goto sensor_found;
- }
-
- return -ENODEV;
-
-sensor_found:
- sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32),
- GFP_KERNEL);
- if (!sensor_settings)
- return -ENOMEM;
-
- sd->gspca_dev.cam.cam_mode = mt9m111_modes;
- sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes);
- sd->desc->ctrls = mt9m111_ctrls;
- sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls);
-
- for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++)
- sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value;
- sd->sensor_priv = sensor_settings;
-
- return 0;
-}
-
-int mt9m111_init(struct sd *sd)
-{
- int i, err = 0;
- s32 *sensor_settings = sd->sensor_priv;
-
- /* Init the sensor */
- for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) {
- u8 data[2];
-
- if (init_mt9m111[i][0] == BRIDGE) {
- err = m5602_write_bridge(sd,
- init_mt9m111[i][1],
- init_mt9m111[i][2]);
- } else {
- data[0] = init_mt9m111[i][2];
- data[1] = init_mt9m111[i][3];
- err = m5602_write_sensor(sd,
- init_mt9m111[i][1], data, 2);
- }
- }
-
- if (dump_sensor)
- mt9m111_dump_registers(sd);
-
- err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
- if (err < 0)
- return err;
-
- err = mt9m111_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
- if (err < 0)
- return err;
-
- err = mt9m111_set_green_balance(&sd->gspca_dev,
- sensor_settings[GREEN_BALANCE_IDX]);
- if (err < 0)
- return err;
-
- err = mt9m111_set_blue_balance(&sd->gspca_dev,
- sensor_settings[BLUE_BALANCE_IDX]);
- if (err < 0)
- return err;
-
- err = mt9m111_set_red_balance(&sd->gspca_dev,
- sensor_settings[RED_BALANCE_IDX]);
- if (err < 0)
- return err;
-
- return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
-}
-
-int mt9m111_start(struct sd *sd)
-{
- int i, err = 0;
- u8 data[2];
- struct cam *cam = &sd->gspca_dev.cam;
- s32 *sensor_settings = sd->sensor_priv;
-
- int width = cam->cam_mode[sd->gspca_dev.curr_mode].width - 1;
- int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
-
- for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) {
- if (start_mt9m111[i][0] == BRIDGE) {
- err = m5602_write_bridge(sd,
- start_mt9m111[i][1],
- start_mt9m111[i][2]);
- } else {
- data[0] = start_mt9m111[i][2];
- data[1] = start_mt9m111[i][3];
- err = m5602_write_sensor(sd,
- start_mt9m111[i][1], data, 2);
- }
- }
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
- if (err < 0)
- return err;
-
- for (i = 0; i < 2 && !err; i++)
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
- if (err < 0)
- return err;
-
- for (i = 0; i < 2 && !err; i++)
- err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
- (width >> 8) & 0xff);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, width & 0xff);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
- if (err < 0)
- return err;
-
- switch (width) {
- case 640:
- PDEBUG(D_V4L2, "Configuring camera for VGA mode");
- data[0] = MT9M111_RMB_OVER_SIZED;
- data[1] = MT9M111_RMB_ROW_SKIP_2X |
- MT9M111_RMB_COLUMN_SKIP_2X |
- (sensor_settings[VFLIP_IDX] << 0) |
- (sensor_settings[HFLIP_IDX] << 1);
-
- err = m5602_write_sensor(sd,
- MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
- break;
-
- case 320:
- PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
- data[0] = MT9M111_RMB_OVER_SIZED;
- data[1] = MT9M111_RMB_ROW_SKIP_4X |
- MT9M111_RMB_COLUMN_SKIP_4X |
- (sensor_settings[VFLIP_IDX] << 0) |
- (sensor_settings[HFLIP_IDX] << 1);
- err = m5602_write_sensor(sd,
- MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
- break;
- }
- return err;
-}
-
-void mt9m111_disconnect(struct sd *sd)
-{
- sd->sensor = NULL;
- kfree(sd->sensor_priv);
-}
-
-static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[VFLIP_IDX];
- PDEBUG(D_V4L2, "Read vertical flip %d", *val);
-
- return 0;
-}
-
-static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 data[2] = {0x00, 0x00};
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Set vertical flip to %d", val);
-
- sensor_settings[VFLIP_IDX] = val;
-
- /* The mt9m111 is flipped by default */
- val = !val;
-
- /* Set the correct page map */
- err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
- if (err < 0)
- return err;
-
- err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
- if (err < 0)
- return err;
-
- data[1] = (data[1] & 0xfe) | val;
- err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
- data, 2);
- return err;
-}
-
-static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[HFLIP_IDX];
- PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
-
- return 0;
-}
-
-static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 data[2] = {0x00, 0x00};
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
-
- sensor_settings[HFLIP_IDX] = val;
-
- /* The mt9m111 is flipped by default */
- val = !val;
-
- /* Set the correct page map */
- err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
- if (err < 0)
- return err;
-
- err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
- if (err < 0)
- return err;
-
- data[1] = (data[1] & 0xfd) | ((val << 1) & 0x02);
- err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
- data, 2);
- return err;
-}
-
-static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[GAIN_IDX];
- PDEBUG(D_V4L2, "Read gain %d", *val);
-
- return 0;
-}
-
-static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- int err;
- u8 data[2];
-
- err = m5602_read_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
- if (err < 0)
- return err;
-
- sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01;
- data[1] = ((data[1] & 0xfd) | ((val & 0x01) << 1));
-
- err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
-
- PDEBUG(D_V4L2, "Set auto white balance %d", val);
- return err;
-}
-
-static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 *val) {
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
- PDEBUG(D_V4L2, "Read auto white balance %d", *val);
- return 0;
-}
-
-static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err, tmp;
- u8 data[2] = {0x00, 0x00};
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- sensor_settings[GAIN_IDX] = val;
-
- /* Set the correct page map */
- err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
- if (err < 0)
- return err;
-
- if (val >= INITIAL_MAX_GAIN * 2 * 2 * 2)
- return -EINVAL;
-
- if ((val >= INITIAL_MAX_GAIN * 2 * 2) &&
- (val < (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2))
- tmp = (1 << 10) | (val << 9) |
- (val << 8) | (val / 8);
- else if ((val >= INITIAL_MAX_GAIN * 2) &&
- (val < INITIAL_MAX_GAIN * 2 * 2))
- tmp = (1 << 9) | (1 << 8) | (val / 4);
- else if ((val >= INITIAL_MAX_GAIN) &&
- (val < INITIAL_MAX_GAIN * 2))
- tmp = (1 << 8) | (val / 2);
- else
- tmp = val;
-
- data[1] = (tmp & 0xff);
- data[0] = (tmp & 0xff00) >> 8;
- PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
- data[1], data[0]);
-
- err = m5602_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
- data, 2);
-
- return err;
-}
-
-static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 data[2];
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- sensor_settings[GREEN_BALANCE_IDX] = val;
- data[1] = (val & 0xff);
- data[0] = (val & 0xff00) >> 8;
-
- PDEBUG(D_V4L2, "Set green balance %d", val);
- err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN,
- data, 2);
- if (err < 0)
- return err;
-
- return m5602_write_sensor(sd, MT9M111_SC_GREEN_2_GAIN,
- data, 2);
-}
-
-static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[GREEN_BALANCE_IDX];
- PDEBUG(D_V4L2, "Read green balance %d", *val);
- return 0;
-}
-
-static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
-{
- u8 data[2];
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- sensor_settings[BLUE_BALANCE_IDX] = val;
- data[1] = (val & 0xff);
- data[0] = (val & 0xff00) >> 8;
-
- PDEBUG(D_V4L2, "Set blue balance %d", val);
-
- return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN,
- data, 2);
-}
-
-static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[BLUE_BALANCE_IDX];
- PDEBUG(D_V4L2, "Read blue balance %d", *val);
- return 0;
-}
-
-static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
-{
- u8 data[2];
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- sensor_settings[RED_BALANCE_IDX] = val;
- data[1] = (val & 0xff);
- data[0] = (val & 0xff00) >> 8;
-
- PDEBUG(D_V4L2, "Set red balance %d", val);
-
- return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN,
- data, 2);
-}
-
-static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[RED_BALANCE_IDX];
- PDEBUG(D_V4L2, "Read red balance %d", *val);
- return 0;
-}
-
-static void mt9m111_dump_registers(struct sd *sd)
-{
- u8 address, value[2] = {0x00, 0x00};
-
- pr_info("Dumping the mt9m111 register state\n");
-
- pr_info("Dumping the mt9m111 sensor core registers\n");
- value[1] = MT9M111_SENSOR_CORE;
- m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
- for (address = 0; address < 0xff; address++) {
- m5602_read_sensor(sd, address, value, 2);
- pr_info("register 0x%x contains 0x%x%x\n",
- address, value[0], value[1]);
- }
-
- pr_info("Dumping the mt9m111 color pipeline registers\n");
- value[1] = MT9M111_COLORPIPE;
- m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
- for (address = 0; address < 0xff; address++) {
- m5602_read_sensor(sd, address, value, 2);
- pr_info("register 0x%x contains 0x%x%x\n",
- address, value[0], value[1]);
- }
-
- pr_info("Dumping the mt9m111 camera control registers\n");
- value[1] = MT9M111_CAMERA_CONTROL;
- m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
- for (address = 0; address < 0xff; address++) {
- m5602_read_sensor(sd, address, value, 2);
- pr_info("register 0x%x contains 0x%x%x\n",
- address, value[0], value[1]);
- }
-
- pr_info("mt9m111 register state dump complete\n");
-}
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
deleted file mode 100644
index 8c672b5c8c6..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Driver for the mt9m111 sensor
- *
- * Copyright (C) 2008 Erik Andrén
- * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * Some defines taken from the mt9m111 sensor driver
- * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#ifndef M5602_MT9M111_H_
-#define M5602_MT9M111_H_
-
-#include "m5602_sensor.h"
-
-/*****************************************************************************/
-
-#define MT9M111_SC_CHIPVER 0x00
-#define MT9M111_SC_ROWSTART 0x01
-#define MT9M111_SC_COLSTART 0x02
-#define MT9M111_SC_WINDOW_HEIGHT 0x03
-#define MT9M111_SC_WINDOW_WIDTH 0x04
-#define MT9M111_SC_HBLANK_CONTEXT_B 0x05
-#define MT9M111_SC_VBLANK_CONTEXT_B 0x06
-#define MT9M111_SC_HBLANK_CONTEXT_A 0x07
-#define MT9M111_SC_VBLANK_CONTEXT_A 0x08
-#define MT9M111_SC_SHUTTER_WIDTH 0x09
-#define MT9M111_SC_ROW_SPEED 0x0a
-#define MT9M111_SC_EXTRA_DELAY 0x0b
-#define MT9M111_SC_SHUTTER_DELAY 0x0c
-#define MT9M111_SC_RESET 0x0d
-#define MT9M111_SC_R_MODE_CONTEXT_B 0x20
-#define MT9M111_SC_R_MODE_CONTEXT_A 0x21
-#define MT9M111_SC_FLASH_CONTROL 0x23
-#define MT9M111_SC_GREEN_1_GAIN 0x2b
-#define MT9M111_SC_BLUE_GAIN 0x2c
-#define MT9M111_SC_RED_GAIN 0x2d
-#define MT9M111_SC_GREEN_2_GAIN 0x2e
-#define MT9M111_SC_GLOBAL_GAIN 0x2f
-
-#define MT9M111_CONTEXT_CONTROL 0xc8
-#define MT9M111_PAGE_MAP 0xf0
-#define MT9M111_BYTEWISE_ADDRESS 0xf1
-
-#define MT9M111_CP_OPERATING_MODE_CTL 0x06
-#define MT9M111_CP_LUMA_OFFSET 0x34
-#define MT9M111_CP_LUMA_CLIP 0x35
-#define MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A 0x3a
-#define MT9M111_CP_LENS_CORRECTION_1 0x3b
-#define MT9M111_CP_DEFECT_CORR_CONTEXT_A 0x4c
-#define MT9M111_CP_DEFECT_CORR_CONTEXT_B 0x4d
-#define MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B 0x9b
-#define MT9M111_CP_GLOBAL_CLK_CONTROL 0xb3
-
-#define MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18 0x65
-#define MT9M111_CC_AWB_PARAMETER_7 0x28
-
-#define MT9M111_SENSOR_CORE 0x00
-#define MT9M111_COLORPIPE 0x01
-#define MT9M111_CAMERA_CONTROL 0x02
-
-#define MT9M111_RESET (1 << 0)
-#define MT9M111_RESTART (1 << 1)
-#define MT9M111_ANALOG_STANDBY (1 << 2)
-#define MT9M111_CHIP_ENABLE (1 << 3)
-#define MT9M111_CHIP_DISABLE (0 << 3)
-#define MT9M111_OUTPUT_DISABLE (1 << 4)
-#define MT9M111_SHOW_BAD_FRAMES (1 << 0)
-#define MT9M111_RESTART_BAD_FRAMES (1 << 1)
-#define MT9M111_SYNCHRONIZE_CHANGES (1 << 7)
-
-#define MT9M111_RMB_OVER_SIZED (1 << 0)
-#define MT9M111_RMB_MIRROR_ROWS (1 << 0)
-#define MT9M111_RMB_MIRROR_COLS (1 << 1)
-#define MT9M111_RMB_ROW_SKIP_2X (1 << 2)
-#define MT9M111_RMB_COLUMN_SKIP_2X (1 << 3)
-#define MT9M111_RMB_ROW_SKIP_4X (1 << 4)
-#define MT9M111_RMB_COLUMN_SKIP_4X (1 << 5)
-
-#define MT9M111_COLOR_MATRIX_BYPASS (1 << 4)
-#define MT9M111_SEL_CONTEXT_B (1 << 3)
-
-#define MT9M111_TRISTATE_PIN_IN_STANDBY (1 << 1)
-#define MT9M111_SOC_SOFT_STANDBY (1 << 0)
-
-#define MT9M111_2D_DEFECT_CORRECTION_ENABLE (1 << 0)
-
-#define INITIAL_MAX_GAIN 64
-#define MT9M111_DEFAULT_GAIN 283
-#define MT9M111_GREEN_GAIN_DEFAULT 0x20
-#define MT9M111_BLUE_GAIN_DEFAULT 0x20
-#define MT9M111_RED_GAIN_DEFAULT 0x20
-
-/*****************************************************************************/
-
-/* Kernel module parameters */
-extern int force_sensor;
-extern bool dump_sensor;
-
-int mt9m111_probe(struct sd *sd);
-int mt9m111_init(struct sd *sd);
-int mt9m111_start(struct sd *sd);
-void mt9m111_disconnect(struct sd *sd);
-
-static const struct m5602_sensor mt9m111 = {
- .name = "MT9M111",
-
- .i2c_slave_id = 0xba,
- .i2c_regW = 2,
-
- .probe = mt9m111_probe,
- .init = mt9m111_init,
- .disconnect = mt9m111_disconnect,
- .start = mt9m111_start,
-};
-
-static const unsigned char preinit_mt9m111[][4] = {
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
- {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_RESET,
- MT9M111_RESET |
- MT9M111_RESTART |
- MT9M111_ANALOG_STANDBY |
- MT9M111_CHIP_DISABLE,
- MT9M111_SHOW_BAD_FRAMES |
- MT9M111_RESTART_BAD_FRAMES |
- MT9M111_SYNCHRONIZE_CHANGES},
-
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
-
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
-
- {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}
-};
-
-static const unsigned char init_mt9m111[][4] = {
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
- {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
-
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
- {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00,
- MT9M111_CP_OPERATING_MODE_CTL},
- {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
- {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00,
- MT9M111_2D_DEFECT_CORRECTION_ENABLE},
- {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00,
- MT9M111_2D_DEFECT_CORRECTION_ENABLE},
- {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
- {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
- {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
- {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
- {SENSOR, 0xcd, 0x00, 0x0e},
- {SENSOR, 0xd0, 0x00, 0x40},
-
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
- {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
- {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
-
- {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
- {SENSOR, 0x33, 0x03, 0x49},
- {SENSOR, 0x34, 0xc0, 0x19},
- {SENSOR, 0x3f, 0x20, 0x20},
- {SENSOR, 0x40, 0x20, 0x20},
- {SENSOR, 0x5a, 0xc0, 0x0a},
- {SENSOR, 0x70, 0x7b, 0x0a},
- {SENSOR, 0x71, 0xff, 0x00},
- {SENSOR, 0x72, 0x19, 0x0e},
- {SENSOR, 0x73, 0x18, 0x0f},
- {SENSOR, 0x74, 0x57, 0x32},
- {SENSOR, 0x75, 0x56, 0x34},
- {SENSOR, 0x76, 0x73, 0x35},
- {SENSOR, 0x77, 0x30, 0x12},
- {SENSOR, 0x78, 0x79, 0x02},
- {SENSOR, 0x79, 0x75, 0x06},
- {SENSOR, 0x7a, 0x77, 0x0a},
- {SENSOR, 0x7b, 0x78, 0x09},
- {SENSOR, 0x7c, 0x7d, 0x06},
- {SENSOR, 0x7d, 0x31, 0x10},
- {SENSOR, 0x7e, 0x00, 0x7e},
- {SENSOR, 0x80, 0x59, 0x04},
- {SENSOR, 0x81, 0x59, 0x04},
- {SENSOR, 0x82, 0x57, 0x0a},
- {SENSOR, 0x83, 0x58, 0x0b},
- {SENSOR, 0x84, 0x47, 0x0c},
- {SENSOR, 0x85, 0x48, 0x0e},
- {SENSOR, 0x86, 0x5b, 0x02},
- {SENSOR, 0x87, 0x00, 0x5c},
- {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, MT9M111_SEL_CONTEXT_B},
- {SENSOR, 0x60, 0x00, 0x80},
- {SENSOR, 0x61, 0x00, 0x00},
- {SENSOR, 0x62, 0x00, 0x00},
- {SENSOR, 0x63, 0x00, 0x00},
- {SENSOR, 0x64, 0x00, 0x00},
-
- {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, /* 13 */
- {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, /* 18 */
- {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, /* 1024 */
- {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, /* 1296 */
- {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, /* 352 */
- {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, /* 17 */
- {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, /* 352 */
- {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, /* 17 */
- {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, /* 271 */
- {SENSOR, 0x30, 0x04, 0x00},
- /* Set number of blank rows chosen to 400 */
- {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
-};
-
-static const unsigned char start_mt9m111[][4] = {
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-};
-#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c
deleted file mode 100644
index 9a14835c128..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Driver for the ov7660 sensor
- *
- * Copyright (C) 2009 Erik Andrén
- * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "m5602_ov7660.h"
-
-static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 *val);
-static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 val);
-static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
-static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
-static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val);
-static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-
-static const struct ctrl ov7660_ctrls[] = {
-#define GAIN_IDX 1
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "gain",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x1,
- .default_value = OV7660_DEFAULT_GAIN,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = ov7660_set_gain,
- .get = ov7660_get_gain
- },
-#define BLUE_BALANCE_IDX 2
-#define RED_BALANCE_IDX 3
-#define AUTO_WHITE_BALANCE_IDX 4
- {
- {
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto white balance",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = ov7660_set_auto_white_balance,
- .get = ov7660_get_auto_white_balance
- },
-#define AUTO_GAIN_CTRL_IDX 5
- {
- {
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto gain control",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = ov7660_set_auto_gain,
- .get = ov7660_get_auto_gain
- },
-#define AUTO_EXPOSURE_IDX 6
- {
- {
- .id = V4L2_CID_EXPOSURE_AUTO,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto exposure",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = ov7660_set_auto_exposure,
- .get = ov7660_get_auto_exposure
- },
-#define HFLIP_IDX 7
- {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = ov7660_set_hflip,
- .get = ov7660_get_hflip
- },
-#define VFLIP_IDX 8
- {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = ov7660_set_vflip,
- .get = ov7660_get_vflip
- },
-
-};
-
-static struct v4l2_pix_format ov7660_modes[] = {
- {
- 640,
- 480,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 640 * 480,
- .bytesperline = 640,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- }
-};
-
-static void ov7660_dump_registers(struct sd *sd);
-
-int ov7660_probe(struct sd *sd)
-{
- int err = 0, i;
- u8 prod_id = 0, ver_id = 0;
-
- s32 *sensor_settings;
-
- if (force_sensor) {
- if (force_sensor == OV7660_SENSOR) {
- pr_info("Forcing an %s sensor\n", ov7660.name);
- goto sensor_found;
- }
- /* If we want to force another sensor,
- don't try to probe this one */
- return -ENODEV;
- }
-
- /* Do the preinit */
- for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) {
- u8 data[2];
-
- if (preinit_ov7660[i][0] == BRIDGE) {
- err = m5602_write_bridge(sd,
- preinit_ov7660[i][1],
- preinit_ov7660[i][2]);
- } else {
- data[0] = preinit_ov7660[i][2];
- err = m5602_write_sensor(sd,
- preinit_ov7660[i][1], data, 1);
- }
- }
- if (err < 0)
- return err;
-
- if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1))
- return -ENODEV;
-
- if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1))
- return -ENODEV;
-
- pr_info("Sensor reported 0x%x%x\n", prod_id, ver_id);
-
- if ((prod_id == 0x76) && (ver_id == 0x60)) {
- pr_info("Detected a ov7660 sensor\n");
- goto sensor_found;
- }
- return -ENODEV;
-
-sensor_found:
- sensor_settings = kmalloc(
- ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL);
- if (!sensor_settings)
- return -ENOMEM;
-
- sd->gspca_dev.cam.cam_mode = ov7660_modes;
- sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes);
- sd->desc->ctrls = ov7660_ctrls;
- sd->desc->nctrls = ARRAY_SIZE(ov7660_ctrls);
-
- for (i = 0; i < ARRAY_SIZE(ov7660_ctrls); i++)
- sensor_settings[i] = ov7660_ctrls[i].qctrl.default_value;
- sd->sensor_priv = sensor_settings;
-
- return 0;
-}
-
-int ov7660_init(struct sd *sd)
-{
- int i, err = 0;
- s32 *sensor_settings = sd->sensor_priv;
-
- /* Init the sensor */
- for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) {
- u8 data[2];
-
- if (init_ov7660[i][0] == BRIDGE) {
- err = m5602_write_bridge(sd,
- init_ov7660[i][1],
- init_ov7660[i][2]);
- } else {
- data[0] = init_ov7660[i][2];
- err = m5602_write_sensor(sd,
- init_ov7660[i][1], data, 1);
- }
- }
-
- if (dump_sensor)
- ov7660_dump_registers(sd);
-
- err = ov7660_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
- if (err < 0)
- return err;
-
- err = ov7660_set_auto_white_balance(&sd->gspca_dev,
- sensor_settings[AUTO_WHITE_BALANCE_IDX]);
- if (err < 0)
- return err;
-
- err = ov7660_set_auto_gain(&sd->gspca_dev,
- sensor_settings[AUTO_GAIN_CTRL_IDX]);
- if (err < 0)
- return err;
-
- err = ov7660_set_auto_exposure(&sd->gspca_dev,
- sensor_settings[AUTO_EXPOSURE_IDX]);
- if (err < 0)
- return err;
- err = ov7660_set_hflip(&sd->gspca_dev,
- sensor_settings[HFLIP_IDX]);
- if (err < 0)
- return err;
-
- err = ov7660_set_vflip(&sd->gspca_dev,
- sensor_settings[VFLIP_IDX]);
-
- return err;
-}
-
-int ov7660_start(struct sd *sd)
-{
- return 0;
-}
-
-int ov7660_stop(struct sd *sd)
-{
- return 0;
-}
-
-void ov7660_disconnect(struct sd *sd)
-{
- ov7660_stop(sd);
-
- sd->sensor = NULL;
- kfree(sd->sensor_priv);
-}
-
-static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[GAIN_IDX];
- PDEBUG(D_V4L2, "Read gain %d", *val);
- return 0;
-}
-
-static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Setting gain to %d", val);
-
- sensor_settings[GAIN_IDX] = val;
-
- err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1);
- return err;
-}
-
-
-static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
- return 0;
-}
-
-static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 val)
-{
- int err;
- u8 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Set auto white balance to %d", val);
-
- sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
- err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
- if (err < 0)
- return err;
-
- i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
- err = m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
-
- return err;
-}
-
-static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[AUTO_GAIN_CTRL_IDX];
- PDEBUG(D_V4L2, "Read auto gain control %d", *val);
- return 0;
-}
-
-static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Set auto gain control to %d", val);
-
- sensor_settings[AUTO_GAIN_CTRL_IDX] = val;
- err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
- if (err < 0)
- return err;
-
- i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
-
- return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
-}
-
-static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[AUTO_EXPOSURE_IDX];
- PDEBUG(D_V4L2, "Read auto exposure control %d", *val);
- return 0;
-}
-
-static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev,
- __s32 val)
-{
- int err;
- u8 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Set auto exposure control to %d", val);
-
- sensor_settings[AUTO_EXPOSURE_IDX] = val;
- err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
- if (err < 0)
- return err;
-
- i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
-
- return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
-}
-
-static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[HFLIP_IDX];
- PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
- return 0;
-}
-
-static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
-
- sensor_settings[HFLIP_IDX] = val;
-
- i2c_data = ((val & 0x01) << 5) |
- (sensor_settings[VFLIP_IDX] << 4);
-
- err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
-
- return err;
-}
-
-static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[VFLIP_IDX];
- PDEBUG(D_V4L2, "Read vertical flip %d", *val);
-
- return 0;
-}
-
-static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Set vertical flip to %d", val);
- sensor_settings[VFLIP_IDX] = val;
-
- i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
- err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
- if (err < 0)
- return err;
-
- /* When vflip is toggled we need to readjust the bridge hsync/vsync */
- if (gspca_dev->streaming)
- err = ov7660_start(sd);
-
- return err;
-}
-
-static void ov7660_dump_registers(struct sd *sd)
-{
- int address;
- pr_info("Dumping the ov7660 register state\n");
- for (address = 0; address < 0xa9; address++) {
- u8 value;
- m5602_read_sensor(sd, address, &value, 1);
- pr_info("register 0x%x contains 0x%x\n", address, value);
- }
-
- pr_info("ov7660 register state dump complete\n");
-
- pr_info("Probing for which registers that are read/write\n");
- for (address = 0; address < 0xff; address++) {
- u8 old_value, ctrl_value;
- u8 test_value[2] = {0xff, 0xff};
-
- m5602_read_sensor(sd, address, &old_value, 1);
- m5602_write_sensor(sd, address, test_value, 1);
- m5602_read_sensor(sd, address, &ctrl_value, 1);
-
- if (ctrl_value == test_value[0])
- pr_info("register 0x%x is writeable\n", address);
- else
- pr_info("register 0x%x is read only\n", address);
-
- /* Restore original value */
- m5602_write_sensor(sd, address, &old_value, 1);
- }
-}
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
deleted file mode 100644
index 2b6a13b508f..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.h
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Driver for the ov7660 sensor
- *
- * Copyright (C) 2009 Erik Andrén
- * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#ifndef M5602_OV7660_H_
-#define M5602_OV7660_H_
-
-#include "m5602_sensor.h"
-
-#define OV7660_GAIN 0x00
-#define OV7660_BLUE_GAIN 0x01
-#define OV7660_RED_GAIN 0x02
-#define OV7660_VREF 0x03
-#define OV7660_COM1 0x04
-#define OV7660_BAVE 0x05
-#define OV7660_GEAVE 0x06
-#define OV7660_AECHH 0x07
-#define OV7660_RAVE 0x08
-#define OV7660_COM2 0x09
-#define OV7660_PID 0x0a
-#define OV7660_VER 0x0b
-#define OV7660_COM3 0x0c
-#define OV7660_COM4 0x0d
-#define OV7660_COM5 0x0e
-#define OV7660_COM6 0x0f
-#define OV7660_AECH 0x10
-#define OV7660_CLKRC 0x11
-#define OV7660_COM7 0x12
-#define OV7660_COM8 0x13
-#define OV7660_COM9 0x14
-#define OV7660_COM10 0x15
-#define OV7660_RSVD16 0x16
-#define OV7660_HSTART 0x17
-#define OV7660_HSTOP 0x18
-#define OV7660_VSTART 0x19
-#define OV7660_VSTOP 0x1a
-#define OV7660_PSHFT 0x1b
-#define OV7660_MIDH 0x1c
-#define OV7660_MIDL 0x1d
-#define OV7660_MVFP 0x1e
-#define OV7660_LAEC 0x1f
-#define OV7660_BOS 0x20
-#define OV7660_GBOS 0x21
-#define OV7660_GROS 0x22
-#define OV7660_ROS 0x23
-#define OV7660_AEW 0x24
-#define OV7660_AEB 0x25
-#define OV7660_VPT 0x26
-#define OV7660_BBIAS 0x27
-#define OV7660_GbBIAS 0x28
-#define OV7660_RSVD29 0x29
-#define OV7660_RBIAS 0x2c
-#define OV7660_HREF 0x32
-#define OV7660_ADC 0x37
-#define OV7660_OFON 0x39
-#define OV7660_TSLB 0x3a
-#define OV7660_COM12 0x3c
-#define OV7660_COM13 0x3d
-#define OV7660_LCC1 0x62
-#define OV7660_LCC2 0x63
-#define OV7660_LCC3 0x64
-#define OV7660_LCC4 0x65
-#define OV7660_LCC5 0x66
-#define OV7660_HV 0x69
-#define OV7660_RSVDA1 0xa1
-
-#define OV7660_DEFAULT_GAIN 0x0e
-#define OV7660_DEFAULT_RED_GAIN 0x80
-#define OV7660_DEFAULT_BLUE_GAIN 0x80
-#define OV7660_DEFAULT_SATURATION 0x00
-#define OV7660_DEFAULT_EXPOSURE 0x20
-
-/* Kernel module parameters */
-extern int force_sensor;
-extern bool dump_sensor;
-
-int ov7660_probe(struct sd *sd);
-int ov7660_init(struct sd *sd);
-int ov7660_start(struct sd *sd);
-int ov7660_stop(struct sd *sd);
-void ov7660_disconnect(struct sd *sd);
-
-static const struct m5602_sensor ov7660 = {
- .name = "ov7660",
- .i2c_slave_id = 0x42,
- .i2c_regW = 1,
- .probe = ov7660_probe,
- .init = ov7660_init,
- .start = ov7660_start,
- .stop = ov7660_stop,
- .disconnect = ov7660_disconnect,
-};
-
-static const unsigned char preinit_ov7660[][4] = {
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
- {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
-
- {SENSOR, OV7660_OFON, 0x0c},
- {SENSOR, OV7660_COM2, 0x11},
- {SENSOR, OV7660_COM7, 0x05},
-
- {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}
-};
-
-static const unsigned char init_ov7660[][4] = {
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
- {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
- {SENSOR, OV7660_COM7, 0x80},
- {SENSOR, OV7660_CLKRC, 0x80},
- {SENSOR, OV7660_COM9, 0x4c},
- {SENSOR, OV7660_OFON, 0x43},
- {SENSOR, OV7660_COM12, 0x28},
- {SENSOR, OV7660_COM8, 0x00},
- {SENSOR, OV7660_COM10, 0x40},
- {SENSOR, OV7660_HSTART, 0x0c},
- {SENSOR, OV7660_HSTOP, 0x61},
- {SENSOR, OV7660_HREF, 0xa4},
- {SENSOR, OV7660_PSHFT, 0x0b},
- {SENSOR, OV7660_VSTART, 0x01},
- {SENSOR, OV7660_VSTOP, 0x7a},
- {SENSOR, OV7660_VSTOP, 0x00},
- {SENSOR, OV7660_COM7, 0x05},
- {SENSOR, OV7660_COM6, 0x42},
- {SENSOR, OV7660_BBIAS, 0x94},
- {SENSOR, OV7660_GbBIAS, 0x94},
- {SENSOR, OV7660_RSVD29, 0x94},
- {SENSOR, OV7660_RBIAS, 0x94},
- {SENSOR, OV7660_COM1, 0x00},
- {SENSOR, OV7660_AECH, 0x00},
- {SENSOR, OV7660_AECHH, 0x00},
- {SENSOR, OV7660_ADC, 0x05},
- {SENSOR, OV7660_COM13, 0x00},
- {SENSOR, OV7660_RSVDA1, 0x23},
- {SENSOR, OV7660_TSLB, 0x0d},
- {SENSOR, OV7660_HV, 0x80},
- {SENSOR, OV7660_LCC1, 0x00},
- {SENSOR, OV7660_LCC2, 0x00},
- {SENSOR, OV7660_LCC3, 0x10},
- {SENSOR, OV7660_LCC4, 0x40},
- {SENSOR, OV7660_LCC5, 0x01},
-
- {SENSOR, OV7660_AECH, 0x20},
- {SENSOR, OV7660_COM1, 0x00},
- {SENSOR, OV7660_OFON, 0x0c},
- {SENSOR, OV7660_COM2, 0x11},
- {SENSOR, OV7660_COM7, 0x05},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
- {SENSOR, OV7660_AECH, 0x5f},
- {SENSOR, OV7660_COM1, 0x03},
- {SENSOR, OV7660_OFON, 0x0c},
- {SENSOR, OV7660_COM2, 0x11},
- {SENSOR, OV7660_COM7, 0x05},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
-
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
- {BRIDGE, M5602_XB_SIG_INI, 0x01},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x02},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x27},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0xa7},
- {BRIDGE, M5602_XB_SIG_INI, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-};
-#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
deleted file mode 100644
index 2114a8b90ec..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * Driver for the ov9650 sensor
- *
- * Copyright (C) 2008 Erik Andrén
- * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "m5602_ov9650.h"
-
-static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
-static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
-static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
-static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
-static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 *val);
-static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 val);
-static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
-static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
-static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val);
-
-/* Vertically and horizontally flips the image if matched, needed for machines
- where the sensor is mounted upside down */
-static
- const
- struct dmi_system_id ov9650_flip_dmi_table[] = {
- {
- .ident = "ASUS A6Ja",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "A6J")
- }
- },
- {
- .ident = "ASUS A6JC",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "A6JC")
- }
- },
- {
- .ident = "ASUS A6K",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "A6K")
- }
- },
- {
- .ident = "ASUS A6Kt",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
- }
- },
- {
- .ident = "ASUS A6VA",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "A6VA")
- }
- },
- {
-
- .ident = "ASUS A6VC",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "A6VC")
- }
- },
- {
- .ident = "ASUS A6VM",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
- }
- },
- {
- .ident = "ASUS A7V",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "A7V")
- }
- },
- {
- .ident = "Alienware Aurora m9700",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "alienware"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700")
- }
- },
- {}
-};
-
-static const struct ctrl ov9650_ctrls[] = {
-#define EXPOSURE_IDX 0
- {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0x1ff,
- .step = 0x4,
- .default_value = EXPOSURE_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = ov9650_set_exposure,
- .get = ov9650_get_exposure
- },
-#define GAIN_IDX 1
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "gain",
- .minimum = 0x00,
- .maximum = 0x3ff,
- .step = 0x1,
- .default_value = GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = ov9650_set_gain,
- .get = ov9650_get_gain
- },
-#define RED_BALANCE_IDX 2
- {
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x1,
- .default_value = RED_GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = ov9650_set_red_balance,
- .get = ov9650_get_red_balance
- },
-#define BLUE_BALANCE_IDX 3
- {
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x1,
- .default_value = BLUE_GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = ov9650_set_blue_balance,
- .get = ov9650_get_blue_balance
- },
-#define HFLIP_IDX 4
- {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = ov9650_set_hflip,
- .get = ov9650_get_hflip
- },
-#define VFLIP_IDX 5
- {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = ov9650_set_vflip,
- .get = ov9650_get_vflip
- },
-#define AUTO_WHITE_BALANCE_IDX 6
- {
- {
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto white balance",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = ov9650_set_auto_white_balance,
- .get = ov9650_get_auto_white_balance
- },
-#define AUTO_GAIN_CTRL_IDX 7
- {
- {
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto gain control",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = ov9650_set_auto_gain,
- .get = ov9650_get_auto_gain
- },
-#define AUTO_EXPOSURE_IDX 8
- {
- {
- .id = V4L2_CID_EXPOSURE_AUTO,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto exposure",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = ov9650_set_auto_exposure,
- .get = ov9650_get_auto_exposure
- }
-
-};
-
-static struct v4l2_pix_format ov9650_modes[] = {
- {
- 176,
- 144,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 176 * 144,
- .bytesperline = 176,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 9
- }, {
- 320,
- 240,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 320 * 240,
- .bytesperline = 320,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 8
- }, {
- 352,
- 288,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 352 * 288,
- .bytesperline = 352,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 9
- }, {
- 640,
- 480,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 640 * 480,
- .bytesperline = 640,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 9
- }
-};
-
-static void ov9650_dump_registers(struct sd *sd);
-
-int ov9650_probe(struct sd *sd)
-{
- int err = 0;
- u8 prod_id = 0, ver_id = 0, i;
- s32 *sensor_settings;
-
- if (force_sensor) {
- if (force_sensor == OV9650_SENSOR) {
- pr_info("Forcing an %s sensor\n", ov9650.name);
- goto sensor_found;
- }
- /* If we want to force another sensor,
- don't try to probe this one */
- return -ENODEV;
- }
-
- PDEBUG(D_PROBE, "Probing for an ov9650 sensor");
-
- /* Run the pre-init before probing the sensor */
- for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) {
- u8 data = preinit_ov9650[i][2];
- if (preinit_ov9650[i][0] == SENSOR)
- err = m5602_write_sensor(sd,
- preinit_ov9650[i][1], &data, 1);
- else
- err = m5602_write_bridge(sd,
- preinit_ov9650[i][1], data);
- }
-
- if (err < 0)
- return err;
-
- if (m5602_read_sensor(sd, OV9650_PID, &prod_id, 1))
- return -ENODEV;
-
- if (m5602_read_sensor(sd, OV9650_VER, &ver_id, 1))
- return -ENODEV;
-
- if ((prod_id == 0x96) && (ver_id == 0x52)) {
- pr_info("Detected an ov9650 sensor\n");
- goto sensor_found;
- }
- return -ENODEV;
-
-sensor_found:
- sensor_settings = kmalloc(
- ARRAY_SIZE(ov9650_ctrls) * sizeof(s32), GFP_KERNEL);
- if (!sensor_settings)
- return -ENOMEM;
-
- sd->gspca_dev.cam.cam_mode = ov9650_modes;
- sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov9650_modes);
- sd->desc->ctrls = ov9650_ctrls;
- sd->desc->nctrls = ARRAY_SIZE(ov9650_ctrls);
-
- for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++)
- sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value;
- sd->sensor_priv = sensor_settings;
- return 0;
-}
-
-int ov9650_init(struct sd *sd)
-{
- int i, err = 0;
- u8 data;
- s32 *sensor_settings = sd->sensor_priv;
-
- if (dump_sensor)
- ov9650_dump_registers(sd);
-
- for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) {
- data = init_ov9650[i][2];
- if (init_ov9650[i][0] == SENSOR)
- err = m5602_write_sensor(sd, init_ov9650[i][1],
- &data, 1);
- else
- err = m5602_write_bridge(sd, init_ov9650[i][1], data);
- }
-
- err = ov9650_set_exposure(&sd->gspca_dev,
- sensor_settings[EXPOSURE_IDX]);
- if (err < 0)
- return err;
-
- err = ov9650_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
- if (err < 0)
- return err;
-
- err = ov9650_set_red_balance(&sd->gspca_dev,
- sensor_settings[RED_BALANCE_IDX]);
- if (err < 0)
- return err;
-
- err = ov9650_set_blue_balance(&sd->gspca_dev,
- sensor_settings[BLUE_BALANCE_IDX]);
- if (err < 0)
- return err;
-
- err = ov9650_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
- if (err < 0)
- return err;
-
- err = ov9650_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
- if (err < 0)
- return err;
-
- err = ov9650_set_auto_exposure(&sd->gspca_dev,
- sensor_settings[AUTO_EXPOSURE_IDX]);
- if (err < 0)
- return err;
-
- err = ov9650_set_auto_white_balance(&sd->gspca_dev,
- sensor_settings[AUTO_WHITE_BALANCE_IDX]);
- if (err < 0)
- return err;
-
- err = ov9650_set_auto_gain(&sd->gspca_dev,
- sensor_settings[AUTO_GAIN_CTRL_IDX]);
- return err;
-}
-
-int ov9650_start(struct sd *sd)
-{
- u8 data;
- int i, err = 0;
- struct cam *cam = &sd->gspca_dev.cam;
- s32 *sensor_settings = sd->sensor_priv;
-
- int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
- int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
- int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
- int hor_offs = OV9650_LEFT_OFFSET;
-
- if ((!dmi_check_system(ov9650_flip_dmi_table) &&
- sensor_settings[VFLIP_IDX]) ||
- (dmi_check_system(ov9650_flip_dmi_table) &&
- !sensor_settings[VFLIP_IDX]))
- ver_offs--;
-
- if (width <= 320)
- hor_offs /= 2;
-
- /* Synthesize the vsync/hsync setup */
- for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) {
- if (res_init_ov9650[i][0] == BRIDGE)
- err = m5602_write_bridge(sd, res_init_ov9650[i][1],
- res_init_ov9650[i][2]);
- else if (res_init_ov9650[i][0] == SENSOR) {
- data = res_init_ov9650[i][2];
- err = m5602_write_sensor(sd,
- res_init_ov9650[i][1], &data, 1);
- }
- }
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
- ((ver_offs >> 8) & 0xff));
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
- if (err < 0)
- return err;
-
- for (i = 0; i < 2 && !err; i++)
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
- (hor_offs >> 8) & 0xff);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, hor_offs & 0xff);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
- ((width + hor_offs) >> 8) & 0xff);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
- ((width + hor_offs) & 0xff));
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
- if (err < 0)
- return err;
-
- switch (width) {
- case 640:
- PDEBUG(D_V4L2, "Configuring camera for VGA mode");
-
- data = OV9650_VGA_SELECT | OV9650_RGB_SELECT |
- OV9650_RAW_RGB_SELECT;
- err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
- break;
-
- case 352:
- PDEBUG(D_V4L2, "Configuring camera for CIF mode");
-
- data = OV9650_CIF_SELECT | OV9650_RGB_SELECT |
- OV9650_RAW_RGB_SELECT;
- err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
- break;
-
- case 320:
- PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
-
- data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT |
- OV9650_RAW_RGB_SELECT;
- err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
- break;
-
- case 176:
- PDEBUG(D_V4L2, "Configuring camera for QCIF mode");
-
- data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT |
- OV9650_RAW_RGB_SELECT;
- err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
- break;
- }
- return err;
-}
-
-int ov9650_stop(struct sd *sd)
-{
- u8 data = OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X;
- return m5602_write_sensor(sd, OV9650_COM2, &data, 1);
-}
-
-void ov9650_disconnect(struct sd *sd)
-{
- ov9650_stop(sd);
-
- sd->sensor = NULL;
- kfree(sd->sensor_priv);
-}
-
-static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[EXPOSURE_IDX];
- PDEBUG(D_V4L2, "Read exposure %d", *val);
- return 0;
-}
-
-static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 i2c_data;
- int err;
-
- PDEBUG(D_V4L2, "Set exposure to %d", val);
-
- sensor_settings[EXPOSURE_IDX] = val;
- /* The 6 MSBs */
- i2c_data = (val >> 10) & 0x3f;
- err = m5602_write_sensor(sd, OV9650_AECHM,
- &i2c_data, 1);
- if (err < 0)
- return err;
-
- /* The 8 middle bits */
- i2c_data = (val >> 2) & 0xff;
- err = m5602_write_sensor(sd, OV9650_AECH,
- &i2c_data, 1);
- if (err < 0)
- return err;
-
- /* The 2 LSBs */
- i2c_data = val & 0x03;
- err = m5602_write_sensor(sd, OV9650_COM1, &i2c_data, 1);
- return err;
-}
-
-static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[GAIN_IDX];
- PDEBUG(D_V4L2, "Read gain %d", *val);
- return 0;
-}
-
-static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Setting gain to %d", val);
-
- sensor_settings[GAIN_IDX] = val;
-
- /* The 2 MSB */
- /* Read the OV9650_VREF register first to avoid
- corrupting the VREF high and low bits */
- err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
- if (err < 0)
- return err;
-
- /* Mask away all uninteresting bits */
- i2c_data = ((val & 0x0300) >> 2) |
- (i2c_data & 0x3f);
- err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
- if (err < 0)
- return err;
-
- /* The 8 LSBs */
- i2c_data = val & 0xff;
- err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
- return err;
-}
-
-static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[RED_BALANCE_IDX];
- PDEBUG(D_V4L2, "Read red gain %d", *val);
- return 0;
-}
-
-static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Set red gain to %d", val);
-
- sensor_settings[RED_BALANCE_IDX] = val;
-
- i2c_data = val & 0xff;
- err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1);
- return err;
-}
-
-static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[BLUE_BALANCE_IDX];
- PDEBUG(D_V4L2, "Read blue gain %d", *val);
-
- return 0;
-}
-
-static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Set blue gain to %d", val);
-
- sensor_settings[BLUE_BALANCE_IDX] = val;
-
- i2c_data = val & 0xff;
- err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1);
- return err;
-}
-
-static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[HFLIP_IDX];
- PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
- return 0;
-}
-
-static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
-
- sensor_settings[HFLIP_IDX] = val;
-
- if (!dmi_check_system(ov9650_flip_dmi_table))
- i2c_data = ((val & 0x01) << 5) |
- (sensor_settings[VFLIP_IDX] << 4);
- else
- i2c_data = ((val & 0x01) << 5) |
- (!sensor_settings[VFLIP_IDX] << 4);
-
- err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
-
- return err;
-}
-
-static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[VFLIP_IDX];
- PDEBUG(D_V4L2, "Read vertical flip %d", *val);
-
- return 0;
-}
-
-static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Set vertical flip to %d", val);
- sensor_settings[VFLIP_IDX] = val;
-
- if (dmi_check_system(ov9650_flip_dmi_table))
- val = !val;
-
- i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
- err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
- if (err < 0)
- return err;
-
- /* When vflip is toggled we need to readjust the bridge hsync/vsync */
- if (gspca_dev->streaming)
- err = ov9650_start(sd);
-
- return err;
-}
-
-static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[AUTO_EXPOSURE_IDX];
- PDEBUG(D_V4L2, "Read auto exposure control %d", *val);
- return 0;
-}
-
-static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev,
- __s32 val)
-{
- int err;
- u8 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Set auto exposure control to %d", val);
-
- sensor_settings[AUTO_EXPOSURE_IDX] = val;
- err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
- if (err < 0)
- return err;
-
- i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
-
- return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
-}
-
-static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
- return 0;
-}
-
-static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 val)
-{
- int err;
- u8 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Set auto white balance to %d", val);
-
- sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
- err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
- if (err < 0)
- return err;
-
- i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
- err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
-
- return err;
-}
-
-static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[AUTO_GAIN_CTRL_IDX];
- PDEBUG(D_V4L2, "Read auto gain control %d", *val);
- return 0;
-}
-
-static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- PDEBUG(D_V4L2, "Set auto gain control to %d", val);
-
- sensor_settings[AUTO_GAIN_CTRL_IDX] = val;
- err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
- if (err < 0)
- return err;
-
- i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
-
- return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
-}
-
-static void ov9650_dump_registers(struct sd *sd)
-{
- int address;
- pr_info("Dumping the ov9650 register state\n");
- for (address = 0; address < 0xa9; address++) {
- u8 value;
- m5602_read_sensor(sd, address, &value, 1);
- pr_info("register 0x%x contains 0x%x\n", address, value);
- }
-
- pr_info("ov9650 register state dump complete\n");
-
- pr_info("Probing for which registers that are read/write\n");
- for (address = 0; address < 0xff; address++) {
- u8 old_value, ctrl_value;
- u8 test_value[2] = {0xff, 0xff};
-
- m5602_read_sensor(sd, address, &old_value, 1);
- m5602_write_sensor(sd, address, test_value, 1);
- m5602_read_sensor(sd, address, &ctrl_value, 1);
-
- if (ctrl_value == test_value[0])
- pr_info("register 0x%x is writeable\n", address);
- else
- pr_info("register 0x%x is read only\n", address);
-
- /* Restore original value */
- m5602_write_sensor(sd, address, &old_value, 1);
- }
-}
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
deleted file mode 100644
index f7aa5bf6898..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Driver for the ov9650 sensor
- *
- * Copyright (C) 2008 Erik Andrén
- * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#ifndef M5602_OV9650_H_
-#define M5602_OV9650_H_
-
-#include <linux/dmi.h>
-#include "m5602_sensor.h"
-
-/*****************************************************************************/
-
-#define OV9650_GAIN 0x00
-#define OV9650_BLUE 0x01
-#define OV9650_RED 0x02
-#define OV9650_VREF 0x03
-#define OV9650_COM1 0x04
-#define OV9650_BAVE 0x05
-#define OV9650_GEAVE 0x06
-#define OV9650_RSVD7 0x07
-#define OV9650_COM2 0x09
-#define OV9650_PID 0x0a
-#define OV9650_VER 0x0b
-#define OV9650_COM3 0x0c
-#define OV9650_COM4 0x0d
-#define OV9650_COM5 0x0e
-#define OV9650_COM6 0x0f
-#define OV9650_AECH 0x10
-#define OV9650_CLKRC 0x11
-#define OV9650_COM7 0x12
-#define OV9650_COM8 0x13
-#define OV9650_COM9 0x14
-#define OV9650_COM10 0x15
-#define OV9650_RSVD16 0x16
-#define OV9650_HSTART 0x17
-#define OV9650_HSTOP 0x18
-#define OV9650_VSTRT 0x19
-#define OV9650_VSTOP 0x1a
-#define OV9650_PSHFT 0x1b
-#define OV9650_MVFP 0x1e
-#define OV9650_AEW 0x24
-#define OV9650_AEB 0x25
-#define OV9650_VPT 0x26
-#define OV9650_BBIAS 0x27
-#define OV9650_GbBIAS 0x28
-#define OV9650_Gr_COM 0x29
-#define OV9650_RBIAS 0x2c
-#define OV9650_HREF 0x32
-#define OV9650_CHLF 0x33
-#define OV9650_ARBLM 0x34
-#define OV9650_RSVD35 0x35
-#define OV9650_RSVD36 0x36
-#define OV9650_ADC 0x37
-#define OV9650_ACOM38 0x38
-#define OV9650_OFON 0x39
-#define OV9650_TSLB 0x3a
-#define OV9650_COM12 0x3c
-#define OV9650_COM13 0x3d
-#define OV9650_COM15 0x40
-#define OV9650_COM16 0x41
-#define OV9650_LCC1 0x62
-#define OV9650_LCC2 0x63
-#define OV9650_LCC3 0x64
-#define OV9650_LCC4 0x65
-#define OV9650_LCC5 0x66
-#define OV9650_HV 0x69
-#define OV9650_DBLV 0x6b
-#define OV9650_COM21 0x8b
-#define OV9650_COM22 0x8c
-#define OV9650_COM24 0x8e
-#define OV9650_DBLC1 0x8f
-#define OV9650_RSVD94 0x94
-#define OV9650_RSVD95 0x95
-#define OV9650_RSVD96 0x96
-#define OV9650_LCCFB 0x9d
-#define OV9650_LCCFR 0x9e
-#define OV9650_AECHM 0xa1
-#define OV9650_COM26 0xa5
-#define OV9650_ACOMA8 0xa8
-#define OV9650_ACOMA9 0xa9
-
-#define OV9650_REGISTER_RESET (1 << 7)
-#define OV9650_VGA_SELECT (1 << 6)
-#define OV9650_CIF_SELECT (1 << 5)
-#define OV9650_QVGA_SELECT (1 << 4)
-#define OV9650_QCIF_SELECT (1 << 3)
-#define OV9650_RGB_SELECT (1 << 2)
-#define OV9650_RAW_RGB_SELECT (1 << 0)
-
-#define OV9650_FAST_AGC_AEC (1 << 7)
-#define OV9650_AEC_UNLIM_STEP_SIZE (1 << 6)
-#define OV9650_BANDING (1 << 5)
-#define OV9650_AGC_EN (1 << 2)
-#define OV9650_AWB_EN (1 << 1)
-#define OV9650_AEC_EN (1 << 0)
-
-#define OV9650_VARIOPIXEL (1 << 2)
-#define OV9650_SYSTEM_CLK_SEL (1 << 7)
-#define OV9650_SLAM_MODE (1 << 4)
-
-#define OV9650_QVGA_VARIOPIXEL (1 << 7)
-
-#define OV9650_VFLIP (1 << 4)
-#define OV9650_HFLIP (1 << 5)
-
-#define OV9650_SOFT_SLEEP (1 << 4)
-#define OV9650_OUTPUT_DRIVE_2X (1 << 0)
-
-#define OV9650_DENOISE_ENABLE (1 << 5)
-#define OV9650_WHITE_PIXEL_ENABLE (1 << 1)
-#define OV9650_WHITE_PIXEL_OPTION (1 << 0)
-
-#define OV9650_LEFT_OFFSET 0x62
-
-#define GAIN_DEFAULT 0x14
-#define RED_GAIN_DEFAULT 0x70
-#define BLUE_GAIN_DEFAULT 0x20
-#define EXPOSURE_DEFAULT 0x1ff
-
-/*****************************************************************************/
-
-/* Kernel module parameters */
-extern int force_sensor;
-extern bool dump_sensor;
-
-int ov9650_probe(struct sd *sd);
-int ov9650_init(struct sd *sd);
-int ov9650_start(struct sd *sd);
-int ov9650_stop(struct sd *sd);
-void ov9650_disconnect(struct sd *sd);
-
-static const struct m5602_sensor ov9650 = {
- .name = "OV9650",
- .i2c_slave_id = 0x60,
- .i2c_regW = 1,
- .probe = ov9650_probe,
- .init = ov9650_init,
- .start = ov9650_start,
- .stop = ov9650_stop,
- .disconnect = ov9650_disconnect,
-};
-
-static const unsigned char preinit_ov9650[][3] = {
- /* [INITCAM] */
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
-
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
- {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
- /* Reset chip */
- {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
- /* Enable double clock */
- {SENSOR, OV9650_CLKRC, 0x80},
- /* Do something out of spec with the power */
- {SENSOR, OV9650_OFON, 0x40}
-};
-
-static const unsigned char init_ov9650[][3] = {
- /* [INITCAM] */
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
-
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
- {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
-
- /* Reset chip */
- {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
- /* One extra reset is needed in order to make the sensor behave
- properly when resuming from ram, could be a timing issue */
- {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
-
- /* Enable double clock */
- {SENSOR, OV9650_CLKRC, 0x80},
- /* Do something out of spec with the power */
- {SENSOR, OV9650_OFON, 0x40},
-
- /* Set fast AGC/AEC algorithm with unlimited step size */
- {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
- OV9650_AEC_UNLIM_STEP_SIZE},
-
- {SENSOR, OV9650_CHLF, 0x10},
- {SENSOR, OV9650_ARBLM, 0xbf},
- {SENSOR, OV9650_ACOM38, 0x81},
- /* Turn off color matrix coefficient double option */
- {SENSOR, OV9650_COM16, 0x00},
- /* Enable color matrix for RGB/YUV, Delay Y channel,
- set output Y/UV delay to 1 */
- {SENSOR, OV9650_COM13, 0x19},
- /* Enable digital BLC, Set output mode to U Y V Y */
- {SENSOR, OV9650_TSLB, 0x0c},
- /* Limit the AGC/AEC stable upper region */
- {SENSOR, OV9650_COM24, 0x00},
- /* Enable HREF and some out of spec things */
- {SENSOR, OV9650_COM12, 0x73},
- /* Set all DBLC offset signs to positive and
- do some out of spec stuff */
- {SENSOR, OV9650_DBLC1, 0xdf},
- {SENSOR, OV9650_COM21, 0x06},
- {SENSOR, OV9650_RSVD35, 0x91},
- /* Necessary, no camera stream without it */
- {SENSOR, OV9650_RSVD16, 0x06},
- {SENSOR, OV9650_RSVD94, 0x99},
- {SENSOR, OV9650_RSVD95, 0x99},
- {SENSOR, OV9650_RSVD96, 0x04},
- /* Enable full range output */
- {SENSOR, OV9650_COM15, 0x0},
- /* Enable HREF at optical black, enable ADBLC bias,
- enable ADBLC, reset timings at format change */
- {SENSOR, OV9650_COM6, 0x4b},
- /* Subtract 32 from the B channel bias */
- {SENSOR, OV9650_BBIAS, 0xa0},
- /* Subtract 32 from the Gb channel bias */
- {SENSOR, OV9650_GbBIAS, 0xa0},
- /* Do not bypass the analog BLC and to some out of spec stuff */
- {SENSOR, OV9650_Gr_COM, 0x00},
- /* Subtract 32 from the R channel bias */
- {SENSOR, OV9650_RBIAS, 0xa0},
- /* Subtract 32 from the R channel bias */
- {SENSOR, OV9650_RBIAS, 0x0},
- {SENSOR, OV9650_COM26, 0x80},
- {SENSOR, OV9650_ACOMA9, 0x98},
- /* Set the AGC/AEC stable region upper limit */
- {SENSOR, OV9650_AEW, 0x68},
- /* Set the AGC/AEC stable region lower limit */
- {SENSOR, OV9650_AEB, 0x5c},
- /* Set the high and low limit nibbles to 3 */
- {SENSOR, OV9650_VPT, 0xc3},
- /* Set the Automatic Gain Ceiling (AGC) to 128x,
- drop VSYNC at frame drop,
- limit exposure timing,
- drop frame when the AEC step is larger than the exposure gap */
- {SENSOR, OV9650_COM9, 0x6e},
- /* Set VSYNC negative, Set RESET to SLHS (slave mode horizontal sync)
- and set PWDN to SLVS (slave mode vertical sync) */
- {SENSOR, OV9650_COM10, 0x42},
- /* Set horizontal column start high to default value */
- {SENSOR, OV9650_HSTART, 0x1a}, /* 210 */
- /* Set horizontal column end */
- {SENSOR, OV9650_HSTOP, 0xbf}, /* 1534 */
- /* Complementing register to the two writes above */
- {SENSOR, OV9650_HREF, 0xb2},
- /* Set vertical row start high bits */
- {SENSOR, OV9650_VSTRT, 0x02},
- /* Set vertical row end low bits */
- {SENSOR, OV9650_VSTOP, 0x7e},
- /* Set complementing vertical frame control */
- {SENSOR, OV9650_VREF, 0x10},
- {SENSOR, OV9650_ADC, 0x04},
- {SENSOR, OV9650_HV, 0x40},
-
- /* Enable denoise, and white-pixel erase */
- {SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE |
- OV9650_WHITE_PIXEL_ENABLE |
- OV9650_WHITE_PIXEL_OPTION},
-
- /* Enable VARIOPIXEL */
- {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
- {SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL},
-
- /* Put the sensor in soft sleep mode */
- {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X},
-};
-
-static const unsigned char res_init_ov9650[][3] = {
- {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X},
-
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
- {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x01}
-};
-#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
deleted file mode 100644
index b8771698cbc..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
- * Driver for the po1030 sensor
- *
- * Copyright (c) 2008 Erik Andrén
- * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "m5602_po1030.h"
-
-static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
-static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
-static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
-static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
-static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
-static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
-static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 val);
-static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 *val);
-static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
- __s32 val);
-static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
- __s32 *val);
-
-static struct v4l2_pix_format po1030_modes[] = {
- {
- 640,
- 480,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage = 640 * 480,
- .bytesperline = 640,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2
- }
-};
-
-static const struct ctrl po1030_ctrls[] = {
-#define GAIN_IDX 0
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "gain",
- .minimum = 0x00,
- .maximum = 0x4f,
- .step = 0x1,
- .default_value = PO1030_GLOBAL_GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = po1030_set_gain,
- .get = po1030_get_gain
- },
-#define EXPOSURE_IDX 1
- {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0x02ff,
- .step = 0x1,
- .default_value = PO1030_EXPOSURE_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = po1030_set_exposure,
- .get = po1030_get_exposure
- },
-#define RED_BALANCE_IDX 2
- {
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x1,
- .default_value = PO1030_RED_GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = po1030_set_red_balance,
- .get = po1030_get_red_balance
- },
-#define BLUE_BALANCE_IDX 3
- {
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x1,
- .default_value = PO1030_BLUE_GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = po1030_set_blue_balance,
- .get = po1030_get_blue_balance
- },
-#define HFLIP_IDX 4
- {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- .set = po1030_set_hflip,
- .get = po1030_get_hflip
- },
-#define VFLIP_IDX 5
- {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- .set = po1030_set_vflip,
- .get = po1030_get_vflip
- },
-#define AUTO_WHITE_BALANCE_IDX 6
- {
- {
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto white balance",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- .set = po1030_set_auto_white_balance,
- .get = po1030_get_auto_white_balance
- },
-#define AUTO_EXPOSURE_IDX 7
- {
- {
- .id = V4L2_CID_EXPOSURE_AUTO,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto exposure",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- .set = po1030_set_auto_exposure,
- .get = po1030_get_auto_exposure
- },
-#define GREEN_BALANCE_IDX 8
- {
- {
- .id = M5602_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x1,
- .default_value = PO1030_GREEN_GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = po1030_set_green_balance,
- .get = po1030_get_green_balance
- },
-};
-
-static void po1030_dump_registers(struct sd *sd);
-
-int po1030_probe(struct sd *sd)
-{
- u8 dev_id_h = 0, i;
- s32 *sensor_settings;
-
- if (force_sensor) {
- if (force_sensor == PO1030_SENSOR) {
- pr_info("Forcing a %s sensor\n", po1030.name);
- goto sensor_found;
- }
- /* If we want to force another sensor, don't try to probe this
- * one */
- return -ENODEV;
- }
-
- PDEBUG(D_PROBE, "Probing for a po1030 sensor");
-
- /* Run the pre-init to actually probe the unit */
- for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
- u8 data = preinit_po1030[i][2];
- if (preinit_po1030[i][0] == SENSOR)
- m5602_write_sensor(sd,
- preinit_po1030[i][1], &data, 1);
- else
- m5602_write_bridge(sd, preinit_po1030[i][1], data);
- }
-
- if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1))
- return -ENODEV;
-
- if (dev_id_h == 0x30) {
- pr_info("Detected a po1030 sensor\n");
- goto sensor_found;
- }
- return -ENODEV;
-
-sensor_found:
- sensor_settings = kmalloc(
- ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL);
- if (!sensor_settings)
- return -ENOMEM;
-
- sd->gspca_dev.cam.cam_mode = po1030_modes;
- sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes);
- sd->desc->ctrls = po1030_ctrls;
- sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls);
-
- for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++)
- sensor_settings[i] = po1030_ctrls[i].qctrl.default_value;
- sd->sensor_priv = sensor_settings;
-
- return 0;
-}
-
-int po1030_init(struct sd *sd)
-{
- s32 *sensor_settings = sd->sensor_priv;
- int i, err = 0;
-
- /* Init the sensor */
- for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) {
- u8 data[2] = {0x00, 0x00};
-
- switch (init_po1030[i][0]) {
- case BRIDGE:
- err = m5602_write_bridge(sd,
- init_po1030[i][1],
- init_po1030[i][2]);
- break;
-
- case SENSOR:
- data[0] = init_po1030[i][2];
- err = m5602_write_sensor(sd,
- init_po1030[i][1], data, 1);
- break;
-
- default:
- pr_info("Invalid stream command, exiting init\n");
- return -EINVAL;
- }
- }
- if (err < 0)
- return err;
-
- if (dump_sensor)
- po1030_dump_registers(sd);
-
- err = po1030_set_exposure(&sd->gspca_dev,
- sensor_settings[EXPOSURE_IDX]);
- if (err < 0)
- return err;
-
- err = po1030_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
- if (err < 0)
- return err;
-
- err = po1030_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
- if (err < 0)
- return err;
-
- err = po1030_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
- if (err < 0)
- return err;
-
- err = po1030_set_red_balance(&sd->gspca_dev,
- sensor_settings[RED_BALANCE_IDX]);
- if (err < 0)
- return err;
-
- err = po1030_set_blue_balance(&sd->gspca_dev,
- sensor_settings[BLUE_BALANCE_IDX]);
- if (err < 0)
- return err;
-
- err = po1030_set_green_balance(&sd->gspca_dev,
- sensor_settings[GREEN_BALANCE_IDX]);
- if (err < 0)
- return err;
-
- err = po1030_set_auto_white_balance(&sd->gspca_dev,
- sensor_settings[AUTO_WHITE_BALANCE_IDX]);
- if (err < 0)
- return err;
-
- err = po1030_set_auto_exposure(&sd->gspca_dev,
- sensor_settings[AUTO_EXPOSURE_IDX]);
- return err;
-}
-
-int po1030_start(struct sd *sd)
-{
- struct cam *cam = &sd->gspca_dev.cam;
- int i, err = 0;
- int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
- int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
- int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
- u8 data;
-
- switch (width) {
- case 320:
- data = PO1030_SUBSAMPLING;
- err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
- if (err < 0)
- return err;
-
- data = ((width + 3) >> 8) & 0xff;
- err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
- if (err < 0)
- return err;
-
- data = (width + 3) & 0xff;
- err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
- if (err < 0)
- return err;
-
- data = ((height + 1) >> 8) & 0xff;
- err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
- if (err < 0)
- return err;
-
- data = (height + 1) & 0xff;
- err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
-
- height += 6;
- width -= 1;
- break;
-
- case 640:
- data = 0;
- err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
- if (err < 0)
- return err;
-
- data = ((width + 7) >> 8) & 0xff;
- err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
- if (err < 0)
- return err;
-
- data = (width + 7) & 0xff;
- err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
- if (err < 0)
- return err;
-
- data = ((height + 3) >> 8) & 0xff;
- err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
- if (err < 0)
- return err;
-
- data = (height + 3) & 0xff;
- err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
-
- height += 12;
- width -= 2;
- break;
- }
- err = m5602_write_bridge(sd, M5602_XB_SENSOR_TYPE, 0x0c);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_LINE_OF_FRAME_H, 0x81);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_PIX_OF_LINE_H, 0x82);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0x01);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
- ((ver_offs >> 8) & 0xff));
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
- if (err < 0)
- return err;
-
- for (i = 0; i < 2 && !err; i++)
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
- if (err < 0)
- return err;
-
- for (i = 0; i < 2 && !err; i++)
- err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
-
- for (i = 0; i < 2 && !err; i++)
- err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
-
- for (i = 0; i < 2 && !err; i++)
- err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width >> 8) & 0xff);
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width & 0xff));
- if (err < 0)
- return err;
-
- err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
- return err;
-}
-
-static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[EXPOSURE_IDX];
- PDEBUG(D_V4L2, "Exposure read as %d", *val);
- return 0;
-}
-
-static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 i2c_data;
- int err;
-
- sensor_settings[EXPOSURE_IDX] = val;
- PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
-
- i2c_data = ((val & 0xff00) >> 8);
- PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
- i2c_data);
-
- err = m5602_write_sensor(sd, PO1030_INTEGLINES_H,
- &i2c_data, 1);
- if (err < 0)
- return err;
-
- i2c_data = (val & 0xff);
- PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
- i2c_data);
- err = m5602_write_sensor(sd, PO1030_INTEGLINES_M,
- &i2c_data, 1);
-
- return err;
-}
-
-static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[GAIN_IDX];
- PDEBUG(D_V4L2, "Read global gain %d", *val);
- return 0;
-}
-
-static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 i2c_data;
- int err;
-
- sensor_settings[GAIN_IDX] = val;
-
- i2c_data = val & 0xff;
- PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
- err = m5602_write_sensor(sd, PO1030_GLOBALGAIN,
- &i2c_data, 1);
- return err;
-}
-
-static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[HFLIP_IDX];
- PDEBUG(D_V4L2, "Read hflip %d", *val);
-
- return 0;
-}
-
-static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 i2c_data;
- int err;
-
- sensor_settings[HFLIP_IDX] = val;
-
- PDEBUG(D_V4L2, "Set hflip %d", val);
- err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
- if (err < 0)
- return err;
-
- i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
-
- err = m5602_write_sensor(sd, PO1030_CONTROL2,
- &i2c_data, 1);
-
- return err;
-}
-
-static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[VFLIP_IDX];
- PDEBUG(D_V4L2, "Read vflip %d", *val);
-
- return 0;
-}
-
-static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 i2c_data;
- int err;
-
- sensor_settings[VFLIP_IDX] = val;
-
- PDEBUG(D_V4L2, "Set vflip %d", val);
- err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
- if (err < 0)
- return err;
-
- i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
-
- err = m5602_write_sensor(sd, PO1030_CONTROL2,
- &i2c_data, 1);
-
- return err;
-}
-
-static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[RED_BALANCE_IDX];
- PDEBUG(D_V4L2, "Read red gain %d", *val);
- return 0;
-}
-
-static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 i2c_data;
- int err;
-
- sensor_settings[RED_BALANCE_IDX] = val;
-
- i2c_data = val & 0xff;
- PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
- err = m5602_write_sensor(sd, PO1030_RED_GAIN,
- &i2c_data, 1);
- return err;
-}
-
-static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[BLUE_BALANCE_IDX];
- PDEBUG(D_V4L2, "Read blue gain %d", *val);
-
- return 0;
-}
-
-static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 i2c_data;
- int err;
-
- sensor_settings[BLUE_BALANCE_IDX] = val;
-
- i2c_data = val & 0xff;
- PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
- err = m5602_write_sensor(sd, PO1030_BLUE_GAIN,
- &i2c_data, 1);
-
- return err;
-}
-
-static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[GREEN_BALANCE_IDX];
- PDEBUG(D_V4L2, "Read green gain %d", *val);
-
- return 0;
-}
-
-static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 i2c_data;
- int err;
-
- sensor_settings[GREEN_BALANCE_IDX] = val;
- i2c_data = val & 0xff;
- PDEBUG(D_V4L2, "Set green gain to %d", i2c_data);
-
- err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN,
- &i2c_data, 1);
- if (err < 0)
- return err;
-
- return m5602_write_sensor(sd, PO1030_GREEN_2_GAIN,
- &i2c_data, 1);
-}
-
-static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
- PDEBUG(D_V4L2, "Auto white balancing is %d", *val);
-
- return 0;
-}
-
-static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
- __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 i2c_data;
- int err;
-
- sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
-
- err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
- if (err < 0)
- return err;
-
- PDEBUG(D_V4L2, "Set auto white balance to %d", val);
- i2c_data = (i2c_data & 0xfe) | (val & 0x01);
- err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
- return err;
-}
-
-static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
- __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[AUTO_EXPOSURE_IDX];
- PDEBUG(D_V4L2, "Auto exposure is %d", *val);
- return 0;
-}
-
-static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
- __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 i2c_data;
- int err;
-
- sensor_settings[AUTO_EXPOSURE_IDX] = val;
- err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
- if (err < 0)
- return err;
-
- PDEBUG(D_V4L2, "Set auto exposure to %d", val);
- i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1);
- return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
-}
-
-void po1030_disconnect(struct sd *sd)
-{
- sd->sensor = NULL;
- kfree(sd->sensor_priv);
-}
-
-static void po1030_dump_registers(struct sd *sd)
-{
- int address;
- u8 value = 0;
-
- pr_info("Dumping the po1030 sensor core registers\n");
- for (address = 0; address < 0x7f; address++) {
- m5602_read_sensor(sd, address, &value, 1);
- pr_info("register 0x%x contains 0x%x\n", address, value);
- }
-
- pr_info("po1030 register state dump complete\n");
-
- pr_info("Probing for which registers that are read/write\n");
- for (address = 0; address < 0xff; address++) {
- u8 old_value, ctrl_value;
- u8 test_value[2] = {0xff, 0xff};
-
- m5602_read_sensor(sd, address, &old_value, 1);
- m5602_write_sensor(sd, address, test_value, 1);
- m5602_read_sensor(sd, address, &ctrl_value, 1);
-
- if (ctrl_value == test_value[0])
- pr_info("register 0x%x is writeable\n", address);
- else
- pr_info("register 0x%x is read only\n", address);
-
- /* Restore original value */
- m5602_write_sensor(sd, address, &old_value, 1);
- }
-}
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
deleted file mode 100644
index 81a2bcb88fe..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Driver for the po1030 sensor.
- *
- * Copyright (c) 2008 Erik Andrén
- * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * Register defines taken from Pascal Stangs Procyon Armlib
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#ifndef M5602_PO1030_H_
-#define M5602_PO1030_H_
-
-#include "m5602_sensor.h"
-
-/*****************************************************************************/
-
-#define PO1030_DEVID_H 0x00
-#define PO1030_DEVID_L 0x01
-#define PO1030_FRAMEWIDTH_H 0x04
-#define PO1030_FRAMEWIDTH_L 0x05
-#define PO1030_FRAMEHEIGHT_H 0x06
-#define PO1030_FRAMEHEIGHT_L 0x07
-#define PO1030_WINDOWX_H 0x08
-#define PO1030_WINDOWX_L 0x09
-#define PO1030_WINDOWY_H 0x0a
-#define PO1030_WINDOWY_L 0x0b
-#define PO1030_WINDOWWIDTH_H 0x0c
-#define PO1030_WINDOWWIDTH_L 0x0d
-#define PO1030_WINDOWHEIGHT_H 0x0e
-#define PO1030_WINDOWHEIGHT_L 0x0f
-
-#define PO1030_GLOBALIBIAS 0x12
-#define PO1030_PIXELIBIAS 0x13
-
-#define PO1030_GLOBALGAIN 0x15
-#define PO1030_RED_GAIN 0x16
-#define PO1030_GREEN_1_GAIN 0x17
-#define PO1030_BLUE_GAIN 0x18
-#define PO1030_GREEN_2_GAIN 0x19
-
-#define PO1030_INTEGLINES_H 0x1a
-#define PO1030_INTEGLINES_M 0x1b
-#define PO1030_INTEGLINES_L 0x1c
-
-#define PO1030_CONTROL1 0x1d
-#define PO1030_CONTROL2 0x1e
-#define PO1030_CONTROL3 0x1f
-#define PO1030_CONTROL4 0x20
-
-#define PO1030_PERIOD50_H 0x23
-#define PO1030_PERIOD50_L 0x24
-#define PO1030_PERIOD60_H 0x25
-#define PO1030_PERIOD60_L 0x26
-#define PO1030_REGCLK167 0x27
-#define PO1030_FLICKER_DELTA50 0x28
-#define PO1030_FLICKERDELTA60 0x29
-
-#define PO1030_ADCOFFSET 0x2c
-
-/* Gamma Correction Coeffs */
-#define PO1030_GC0 0x2d
-#define PO1030_GC1 0x2e
-#define PO1030_GC2 0x2f
-#define PO1030_GC3 0x30
-#define PO1030_GC4 0x31
-#define PO1030_GC5 0x32
-#define PO1030_GC6 0x33
-#define PO1030_GC7 0x34
-
-/* Color Transform Matrix */
-#define PO1030_CT0 0x35
-#define PO1030_CT1 0x36
-#define PO1030_CT2 0x37
-#define PO1030_CT3 0x38
-#define PO1030_CT4 0x39
-#define PO1030_CT5 0x3a
-#define PO1030_CT6 0x3b
-#define PO1030_CT7 0x3c
-#define PO1030_CT8 0x3d
-
-#define PO1030_AUTOCTRL1 0x3e
-#define PO1030_AUTOCTRL2 0x3f
-
-#define PO1030_YTARGET 0x40
-#define PO1030_GLOBALGAINMIN 0x41
-#define PO1030_GLOBALGAINMAX 0x42
-
-#define PO1030_AWB_RED_TUNING 0x47
-#define PO1030_AWB_BLUE_TUNING 0x48
-
-/* Output format control */
-#define PO1030_OUTFORMCTRL1 0x5a
-#define PO1030_OUTFORMCTRL2 0x5b
-#define PO1030_OUTFORMCTRL3 0x5c
-#define PO1030_OUTFORMCTRL4 0x5d
-#define PO1030_OUTFORMCTRL5 0x5e
-
-#define PO1030_EDGE_ENH_OFF 0x5f
-#define PO1030_EGA 0x60
-
-#define PO1030_Cb_U_GAIN 0x63
-#define PO1030_Cr_V_GAIN 0x64
-
-#define PO1030_YCONTRAST 0x74
-#define PO1030_YSATURATION 0x75
-
-#define PO1030_HFLIP (1 << 7)
-#define PO1030_VFLIP (1 << 6)
-
-#define PO1030_HREF_ENABLE (1 << 6)
-
-#define PO1030_RAW_RGB_BAYER 0x4
-
-#define PO1030_FRAME_EQUAL (1 << 3)
-#define PO1030_AUTO_SUBSAMPLING (1 << 4)
-
-#define PO1030_WEIGHT_WIN_2X (1 << 3)
-
-#define PO1030_SHUTTER_MODE (1 << 6)
-#define PO1030_AUTO_SUBSAMPLING (1 << 4)
-#define PO1030_FRAME_EQUAL (1 << 3)
-
-#define PO1030_SENSOR_RESET (1 << 5)
-
-#define PO1030_SUBSAMPLING (1 << 6)
-
-/*****************************************************************************/
-
-#define PO1030_GLOBAL_GAIN_DEFAULT 0x12
-#define PO1030_EXPOSURE_DEFAULT 0x0085
-#define PO1030_BLUE_GAIN_DEFAULT 0x36
-#define PO1030_RED_GAIN_DEFAULT 0x36
-#define PO1030_GREEN_GAIN_DEFAULT 0x40
-
-/*****************************************************************************/
-
-/* Kernel module parameters */
-extern int force_sensor;
-extern bool dump_sensor;
-
-int po1030_probe(struct sd *sd);
-int po1030_init(struct sd *sd);
-int po1030_start(struct sd *sd);
-void po1030_disconnect(struct sd *sd);
-
-static const struct m5602_sensor po1030 = {
- .name = "PO1030",
-
- .i2c_slave_id = 0xdc,
- .i2c_regW = 1,
-
- .probe = po1030_probe,
- .init = po1030_init,
- .start = po1030_start,
- .disconnect = po1030_disconnect,
-};
-
-static const unsigned char preinit_po1030[][3] = {
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
-
- {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
-
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x00}
-};
-
-static const unsigned char init_po1030[][3] = {
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
- {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
-
- {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
-
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
-
- {SENSOR, PO1030_AUTOCTRL2, 0x04},
-
- {SENSOR, PO1030_OUTFORMCTRL2, PO1030_RAW_RGB_BAYER},
- {SENSOR, PO1030_AUTOCTRL1, PO1030_WEIGHT_WIN_2X},
-
- {SENSOR, PO1030_CONTROL2, 0x03},
- {SENSOR, 0x21, 0x90},
- {SENSOR, PO1030_YTARGET, 0x60},
- {SENSOR, 0x59, 0x13},
- {SENSOR, PO1030_OUTFORMCTRL1, PO1030_HREF_ENABLE},
- {SENSOR, PO1030_EDGE_ENH_OFF, 0x00},
- {SENSOR, PO1030_EGA, 0x80},
- {SENSOR, 0x78, 0x14},
- {SENSOR, 0x6f, 0x01},
- {SENSOR, PO1030_GLOBALGAINMAX, 0x14},
- {SENSOR, PO1030_Cb_U_GAIN, 0x38},
- {SENSOR, PO1030_Cr_V_GAIN, 0x38},
- {SENSOR, PO1030_CONTROL1, PO1030_SHUTTER_MODE |
- PO1030_AUTO_SUBSAMPLING |
- PO1030_FRAME_EQUAL},
- {SENSOR, PO1030_GC0, 0x10},
- {SENSOR, PO1030_GC1, 0x20},
- {SENSOR, PO1030_GC2, 0x40},
- {SENSOR, PO1030_GC3, 0x60},
- {SENSOR, PO1030_GC4, 0x80},
- {SENSOR, PO1030_GC5, 0xa0},
- {SENSOR, PO1030_GC6, 0xc0},
- {SENSOR, PO1030_GC7, 0xff},
-
- /* Set the width to 751 */
- {SENSOR, PO1030_FRAMEWIDTH_H, 0x02},
- {SENSOR, PO1030_FRAMEWIDTH_L, 0xef},
-
- /* Set the height to 540 */
- {SENSOR, PO1030_FRAMEHEIGHT_H, 0x02},
- {SENSOR, PO1030_FRAMEHEIGHT_L, 0x1c},
-
- /* Set the x window to 1 */
- {SENSOR, PO1030_WINDOWX_H, 0x00},
- {SENSOR, PO1030_WINDOWX_L, 0x01},
-
- /* Set the y window to 1 */
- {SENSOR, PO1030_WINDOWY_H, 0x00},
- {SENSOR, PO1030_WINDOWY_L, 0x01},
-
- /* with a very low lighted environment increase the exposure but
- * decrease the FPS (Frame Per Second) */
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-
- {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
-};
-#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
deleted file mode 100644
index cc8ec3f7e8d..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ /dev/null
@@ -1,726 +0,0 @@
-/*
- * Driver for the s5k4aa sensor
- *
- * Copyright (C) 2008 Erik Andrén
- * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "m5602_s5k4aa.h"
-
-static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val);
-static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val);
-static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
-static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
-
-static
- const
- struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
- {
- .ident = "BRUNEINIT",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "BRUNENIT"),
- DMI_MATCH(DMI_PRODUCT_NAME, "BRUNENIT"),
- DMI_MATCH(DMI_BOARD_VERSION, "00030D0000000001")
- }
- }, {
- .ident = "Fujitsu-Siemens Amilo Xa 2528",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
- DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528")
- }
- }, {
- .ident = "Fujitsu-Siemens Amilo Xi 2428",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
- DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2428")
- }
- }, {
- .ident = "Fujitsu-Siemens Amilo Xi 2528",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
- DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2528")
- }
- }, {
- .ident = "Fujitsu-Siemens Amilo Xi 2550",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
- DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550")
- }
- }, {
- .ident = "Fujitsu-Siemens Amilo Pa 2548",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
- DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 2548")
- }
- }, {
- .ident = "MSI GX700",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
- DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
- DMI_MATCH(DMI_BIOS_DATE, "12/02/2008")
- }
- }, {
- .ident = "MSI GX700",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
- DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
- DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
- }
- }, {
- .ident = "MSI GX700",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
- DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
- DMI_MATCH(DMI_BIOS_DATE, "07/19/2007")
- }
- }, {
- .ident = "MSI GX700/GX705/EX700",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
- DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700")
- }
- }, {
- .ident = "MSI L735",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MS-1717X")
- }
- }, {
- .ident = "Lenovo Y300",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "L3000 Y300"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Y300")
- }
- },
- { }
-};
-
-static struct v4l2_pix_format s5k4aa_modes[] = {
- {
- 640,
- 480,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 640 * 480,
- .bytesperline = 640,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- },
- {
- 1280,
- 1024,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 1280 * 1024,
- .bytesperline = 1280,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- }
-};
-
-static const struct ctrl s5k4aa_ctrls[] = {
-#define VFLIP_IDX 0
- {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = s5k4aa_set_vflip,
- .get = s5k4aa_get_vflip
- },
-#define HFLIP_IDX 1
- {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = s5k4aa_set_hflip,
- .get = s5k4aa_get_hflip
- },
-#define GAIN_IDX 2
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain",
- .minimum = 0,
- .maximum = 127,
- .step = 1,
- .default_value = S5K4AA_DEFAULT_GAIN,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = s5k4aa_set_gain,
- .get = s5k4aa_get_gain
- },
-#define EXPOSURE_IDX 3
- {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Exposure",
- .minimum = 13,
- .maximum = 0xfff,
- .step = 1,
- .default_value = 0x100,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = s5k4aa_set_exposure,
- .get = s5k4aa_get_exposure
- },
-#define NOISE_SUPP_IDX 4
- {
- {
- .id = V4L2_CID_PRIVATE_BASE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Noise suppression (smoothing)",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1,
- },
- .set = s5k4aa_set_noise,
- .get = s5k4aa_get_noise
- },
-#define BRIGHTNESS_IDX 5
- {
- {
- .id = V4L2_CID_BRIGHTNESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Brightness",
- .minimum = 0,
- .maximum = 0x1f,
- .step = 1,
- .default_value = S5K4AA_DEFAULT_BRIGHTNESS,
- },
- .set = s5k4aa_set_brightness,
- .get = s5k4aa_get_brightness
- },
-
-};
-
-static void s5k4aa_dump_registers(struct sd *sd);
-
-int s5k4aa_probe(struct sd *sd)
-{
- u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75};
- int i, err = 0;
- s32 *sensor_settings;
-
- if (force_sensor) {
- if (force_sensor == S5K4AA_SENSOR) {
- pr_info("Forcing a %s sensor\n", s5k4aa.name);
- goto sensor_found;
- }
- /* If we want to force another sensor, don't try to probe this
- * one */
- return -ENODEV;
- }
-
- PDEBUG(D_PROBE, "Probing for a s5k4aa sensor");
-
- /* Preinit the sensor */
- for (i = 0; i < ARRAY_SIZE(preinit_s5k4aa) && !err; i++) {
- u8 data[2] = {0x00, 0x00};
-
- switch (preinit_s5k4aa[i][0]) {
- case BRIDGE:
- err = m5602_write_bridge(sd,
- preinit_s5k4aa[i][1],
- preinit_s5k4aa[i][2]);
- break;
-
- case SENSOR:
- data[0] = preinit_s5k4aa[i][2];
- err = m5602_write_sensor(sd,
- preinit_s5k4aa[i][1],
- data, 1);
- break;
-
- case SENSOR_LONG:
- data[0] = preinit_s5k4aa[i][2];
- data[1] = preinit_s5k4aa[i][3];
- err = m5602_write_sensor(sd,
- preinit_s5k4aa[i][1],
- data, 2);
- break;
- default:
- pr_info("Invalid stream command, exiting init\n");
- return -EINVAL;
- }
- }
-
- /* Test some registers, but we don't know their exact meaning yet */
- if (m5602_read_sensor(sd, 0x00, prod_id, 2))
- return -ENODEV;
- if (m5602_read_sensor(sd, 0x02, prod_id+2, 2))
- return -ENODEV;
- if (m5602_read_sensor(sd, 0x04, prod_id+4, 2))
- return -ENODEV;
-
- if (memcmp(prod_id, expected_prod_id, sizeof(prod_id)))
- return -ENODEV;
- else
- pr_info("Detected a s5k4aa sensor\n");
-
-sensor_found:
- sensor_settings = kmalloc(
- ARRAY_SIZE(s5k4aa_ctrls) * sizeof(s32), GFP_KERNEL);
- if (!sensor_settings)
- return -ENOMEM;
-
- sd->gspca_dev.cam.cam_mode = s5k4aa_modes;
- sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes);
- sd->desc->ctrls = s5k4aa_ctrls;
- sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls);
-
- for (i = 0; i < ARRAY_SIZE(s5k4aa_ctrls); i++)
- sensor_settings[i] = s5k4aa_ctrls[i].qctrl.default_value;
- sd->sensor_priv = sensor_settings;
-
- return 0;
-}
-
-int s5k4aa_start(struct sd *sd)
-{
- int i, err = 0;
- u8 data[2];
- struct cam *cam = &sd->gspca_dev.cam;
- s32 *sensor_settings = sd->sensor_priv;
-
- switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) {
- case 1280:
- PDEBUG(D_V4L2, "Configuring camera for SXGA mode");
-
- for (i = 0; i < ARRAY_SIZE(SXGA_s5k4aa); i++) {
- switch (SXGA_s5k4aa[i][0]) {
- case BRIDGE:
- err = m5602_write_bridge(sd,
- SXGA_s5k4aa[i][1],
- SXGA_s5k4aa[i][2]);
- break;
-
- case SENSOR:
- data[0] = SXGA_s5k4aa[i][2];
- err = m5602_write_sensor(sd,
- SXGA_s5k4aa[i][1],
- data, 1);
- break;
-
- case SENSOR_LONG:
- data[0] = SXGA_s5k4aa[i][2];
- data[1] = SXGA_s5k4aa[i][3];
- err = m5602_write_sensor(sd,
- SXGA_s5k4aa[i][1],
- data, 2);
- break;
-
- default:
- pr_err("Invalid stream command, exiting init\n");
- return -EINVAL;
- }
- }
- err = s5k4aa_set_noise(&sd->gspca_dev, 0);
- if (err < 0)
- return err;
- break;
-
- case 640:
- PDEBUG(D_V4L2, "Configuring camera for VGA mode");
-
- for (i = 0; i < ARRAY_SIZE(VGA_s5k4aa); i++) {
- switch (VGA_s5k4aa[i][0]) {
- case BRIDGE:
- err = m5602_write_bridge(sd,
- VGA_s5k4aa[i][1],
- VGA_s5k4aa[i][2]);
- break;
-
- case SENSOR:
- data[0] = VGA_s5k4aa[i][2];
- err = m5602_write_sensor(sd,
- VGA_s5k4aa[i][1],
- data, 1);
- break;
-
- case SENSOR_LONG:
- data[0] = VGA_s5k4aa[i][2];
- data[1] = VGA_s5k4aa[i][3];
- err = m5602_write_sensor(sd,
- VGA_s5k4aa[i][1],
- data, 2);
- break;
-
- default:
- pr_err("Invalid stream command, exiting init\n");
- return -EINVAL;
- }
- }
- err = s5k4aa_set_noise(&sd->gspca_dev, 1);
- if (err < 0)
- return err;
- break;
- }
- if (err < 0)
- return err;
-
- err = s5k4aa_set_exposure(&sd->gspca_dev,
- sensor_settings[EXPOSURE_IDX]);
- if (err < 0)
- return err;
-
- err = s5k4aa_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
- if (err < 0)
- return err;
-
- err = s5k4aa_set_brightness(&sd->gspca_dev,
- sensor_settings[BRIGHTNESS_IDX]);
- if (err < 0)
- return err;
-
- err = s5k4aa_set_noise(&sd->gspca_dev, sensor_settings[NOISE_SUPP_IDX]);
- if (err < 0)
- return err;
-
- err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
- if (err < 0)
- return err;
-
- return s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
-}
-
-int s5k4aa_init(struct sd *sd)
-{
- int i, err = 0;
-
- for (i = 0; i < ARRAY_SIZE(init_s5k4aa) && !err; i++) {
- u8 data[2] = {0x00, 0x00};
-
- switch (init_s5k4aa[i][0]) {
- case BRIDGE:
- err = m5602_write_bridge(sd,
- init_s5k4aa[i][1],
- init_s5k4aa[i][2]);
- break;
-
- case SENSOR:
- data[0] = init_s5k4aa[i][2];
- err = m5602_write_sensor(sd,
- init_s5k4aa[i][1], data, 1);
- break;
-
- case SENSOR_LONG:
- data[0] = init_s5k4aa[i][2];
- data[1] = init_s5k4aa[i][3];
- err = m5602_write_sensor(sd,
- init_s5k4aa[i][1], data, 2);
- break;
- default:
- pr_info("Invalid stream command, exiting init\n");
- return -EINVAL;
- }
- }
-
- if (dump_sensor)
- s5k4aa_dump_registers(sd);
-
- return err;
-}
-
-static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[EXPOSURE_IDX];
- PDEBUG(D_V4L2, "Read exposure %d", *val);
-
- return 0;
-}
-
-static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 data = S5K4AA_PAGE_MAP_2;
- int err;
-
- sensor_settings[EXPOSURE_IDX] = val;
- PDEBUG(D_V4L2, "Set exposure to %d", val);
- err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
- if (err < 0)
- return err;
- data = (val >> 8) & 0xff;
- err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
- if (err < 0)
- return err;
- data = val & 0xff;
- err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
-
- return err;
-}
-
-static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[VFLIP_IDX];
- PDEBUG(D_V4L2, "Read vertical flip %d", *val);
-
- return 0;
-}
-
-static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 data = S5K4AA_PAGE_MAP_2;
- int err;
-
- sensor_settings[VFLIP_IDX] = val;
-
- PDEBUG(D_V4L2, "Set vertical flip to %d", val);
- err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
- if (err < 0)
- return err;
-
- err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
- if (err < 0)
- return err;
-
- if (dmi_check_system(s5k4aa_vflip_dmi_table))
- val = !val;
-
- data = ((data & ~S5K4AA_RM_V_FLIP) | ((val & 0x01) << 7));
- err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
- if (err < 0)
- return err;
-
- err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
- if (err < 0)
- return err;
- if (val)
- data &= 0xfe;
- else
- data |= 0x01;
- err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
- return err;
-}
-
-static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[HFLIP_IDX];
- PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
-
- return 0;
-}
-
-static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 data = S5K4AA_PAGE_MAP_2;
- int err;
-
- sensor_settings[HFLIP_IDX] = val;
-
- PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
- err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
- if (err < 0)
- return err;
-
- err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
- if (err < 0)
- return err;
-
- if (dmi_check_system(s5k4aa_vflip_dmi_table))
- val = !val;
-
- data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6));
- err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
- if (err < 0)
- return err;
-
- err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
- if (err < 0)
- return err;
- if (val)
- data &= 0xfe;
- else
- data |= 0x01;
- err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
- return err;
-}
-
-static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[GAIN_IDX];
- PDEBUG(D_V4L2, "Read gain %d", *val);
- return 0;
-}
-
-static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 data = S5K4AA_PAGE_MAP_2;
- int err;
-
- sensor_settings[GAIN_IDX] = val;
-
- PDEBUG(D_V4L2, "Set gain to %d", val);
- err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
- if (err < 0)
- return err;
-
- data = val & 0xff;
- err = m5602_write_sensor(sd, S5K4AA_GAIN, &data, 1);
-
- return err;
-}
-
-static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[BRIGHTNESS_IDX];
- PDEBUG(D_V4L2, "Read brightness %d", *val);
- return 0;
-}
-
-static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 data = S5K4AA_PAGE_MAP_2;
- int err;
-
- sensor_settings[BRIGHTNESS_IDX] = val;
-
- PDEBUG(D_V4L2, "Set brightness to %d", val);
- err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
- if (err < 0)
- return err;
-
- data = val & 0xff;
- return m5602_write_sensor(sd, S5K4AA_BRIGHTNESS, &data, 1);
-}
-
-static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
-
- *val = sensor_settings[NOISE_SUPP_IDX];
- PDEBUG(D_V4L2, "Read noise %d", *val);
- return 0;
-}
-
-static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 *sensor_settings = sd->sensor_priv;
- u8 data = S5K4AA_PAGE_MAP_2;
- int err;
-
- sensor_settings[NOISE_SUPP_IDX] = val;
-
- PDEBUG(D_V4L2, "Set noise to %d", val);
- err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
- if (err < 0)
- return err;
-
- data = val & 0x01;
- return m5602_write_sensor(sd, S5K4AA_NOISE_SUPP, &data, 1);
-}
-
-void s5k4aa_disconnect(struct sd *sd)
-{
- sd->sensor = NULL;
- kfree(sd->sensor_priv);
-}
-
-static void s5k4aa_dump_registers(struct sd *sd)
-{
- int address;
- u8 page, old_page;
- m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1);
- for (page = 0; page < 16; page++) {
- m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1);
- pr_info("Dumping the s5k4aa register state for page 0x%x\n",
- page);
- for (address = 0; address <= 0xff; address++) {
- u8 value = 0;
- m5602_read_sensor(sd, address, &value, 1);
- pr_info("register 0x%x contains 0x%x\n",
- address, value);
- }
- }
- pr_info("s5k4aa register state dump complete\n");
-
- for (page = 0; page < 16; page++) {
- m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1);
- pr_info("Probing for which registers that are read/write for page 0x%x\n",
- page);
- for (address = 0; address <= 0xff; address++) {
- u8 old_value, ctrl_value, test_value = 0xff;
-
- m5602_read_sensor(sd, address, &old_value, 1);
- m5602_write_sensor(sd, address, &test_value, 1);
- m5602_read_sensor(sd, address, &ctrl_value, 1);
-
- if (ctrl_value == test_value)
- pr_info("register 0x%x is writeable\n",
- address);
- else
- pr_info("register 0x%x is read only\n",
- address);
-
- /* Restore original value */
- m5602_write_sensor(sd, address, &old_value, 1);
- }
- }
- pr_info("Read/write register probing complete\n");
- m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1);
-}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
deleted file mode 100644
index 8e0035e731c..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Driver for the s5k4aa sensor
- *
- * Copyright (C) 2008 Erik Andrén
- * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#ifndef M5602_S5K4AA_H_
-#define M5602_S5K4AA_H_
-
-#include <linux/dmi.h>
-
-#include "m5602_sensor.h"
-
-/*****************************************************************************/
-
-#define S5K4AA_PAGE_MAP 0xec
-
-#define S5K4AA_PAGE_MAP_0 0x00
-#define S5K4AA_PAGE_MAP_1 0x01
-#define S5K4AA_PAGE_MAP_2 0x02
-
-/* Sensor register definitions for page 0x02 */
-#define S5K4AA_READ_MODE 0x03
-#define S5K4AA_ROWSTART_HI 0x04
-#define S5K4AA_ROWSTART_LO 0x05
-#define S5K4AA_COLSTART_HI 0x06
-#define S5K4AA_COLSTART_LO 0x07
-#define S5K4AA_WINDOW_HEIGHT_HI 0x08
-#define S5K4AA_WINDOW_HEIGHT_LO 0x09
-#define S5K4AA_WINDOW_WIDTH_HI 0x0a
-#define S5K4AA_WINDOW_WIDTH_LO 0x0b
-#define S5K4AA_GLOBAL_GAIN__ 0x0f
-/* sync lost, if too low, reduces frame rate if too high */
-#define S5K4AA_H_BLANK_HI__ 0x1d
-#define S5K4AA_H_BLANK_LO__ 0x1e
-#define S5K4AA_EXPOSURE_HI 0x17
-#define S5K4AA_EXPOSURE_LO 0x18
-#define S5K4AA_BRIGHTNESS 0x1f /* (digital?) gain : 5 bits */
-#define S5K4AA_GAIN 0x20 /* (analogue?) gain : 7 bits */
-#define S5K4AA_NOISE_SUPP 0x37
-
-#define S5K4AA_RM_ROW_SKIP_4X 0x08
-#define S5K4AA_RM_ROW_SKIP_2X 0x04
-#define S5K4AA_RM_COL_SKIP_4X 0x02
-#define S5K4AA_RM_COL_SKIP_2X 0x01
-#define S5K4AA_RM_H_FLIP 0x40
-#define S5K4AA_RM_V_FLIP 0x80
-
-#define S5K4AA_DEFAULT_GAIN 0x5f
-#define S5K4AA_DEFAULT_BRIGHTNESS 0x10
-
-/*****************************************************************************/
-
-/* Kernel module parameters */
-extern int force_sensor;
-extern bool dump_sensor;
-
-int s5k4aa_probe(struct sd *sd);
-int s5k4aa_init(struct sd *sd);
-int s5k4aa_start(struct sd *sd);
-void s5k4aa_disconnect(struct sd *sd);
-
-static const struct m5602_sensor s5k4aa = {
- .name = "S5K4AA",
- .i2c_slave_id = 0x5a,
- .i2c_regW = 2,
-
- .probe = s5k4aa_probe,
- .init = s5k4aa_init,
- .start = s5k4aa_start,
- .disconnect = s5k4aa_disconnect,
-};
-
-static const unsigned char preinit_s5k4aa[][4] = {
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
- {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
-
- {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
-
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x14, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
-
- {SENSOR, S5K4AA_PAGE_MAP, 0x00, 0x00}
-};
-
-static const unsigned char init_s5k4aa[][4] = {
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
- {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
-
- {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
-
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x14, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
-
- {SENSOR, S5K4AA_PAGE_MAP, 0x07, 0x00},
- {SENSOR, 0x36, 0x01, 0x00},
- {SENSOR, S5K4AA_PAGE_MAP, 0x00, 0x00},
- {SENSOR, 0x7b, 0xff, 0x00},
- {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
- {SENSOR, 0x0c, 0x05, 0x00},
- {SENSOR, 0x02, 0x0e, 0x00},
- {SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00},
- {SENSOR, 0x37, 0x00, 0x00},
-};
-
-static const unsigned char VGA_s5k4aa[][4] = {
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- /* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- /* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
-
- {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
- {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X
- | S5K4AA_RM_COL_SKIP_2X, 0x00},
- /* 0x37 : Fix image stability when light is too bright and improves
- * image quality in 640x480, but worsens it in 1280x1024 */
- {SENSOR, 0x37, 0x01, 0x00},
- /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */
- {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
- {SENSOR, S5K4AA_ROWSTART_LO, 0x29, 0x00},
- {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
- {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00},
- /* window_height_hi, window_height_lo : 960 = 0x03c0 */
- {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00},
- {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00},
- /* window_width_hi, window_width_lo : 1280 = 0x0500 */
- {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
- {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
- {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
- {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */
- {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
- {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
- {SENSOR, 0x11, 0x04, 0x00},
- {SENSOR, 0x12, 0xc3, 0x00},
- {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
- {SENSOR, 0x02, 0x0e, 0x00},
-};
-
-static const unsigned char SXGA_s5k4aa[][4] = {
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- /* VSYNC_PARA, VSYNC_PARA : img height 1024 = 0x0400 */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- /* HSYNC_PARA, HSYNC_PARA : img width 1280 = 0x0500 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
-
- {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
- {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP, 0x00},
- {SENSOR, 0x37, 0x01, 0x00},
- {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
- {SENSOR, S5K4AA_ROWSTART_LO, 0x09, 0x00},
- {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
- {SENSOR, S5K4AA_COLSTART_LO, 0x0a, 0x00},
- {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x04, 0x00},
- {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0x00, 0x00},
- {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
- {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
- {SENSOR, S5K4AA_H_BLANK_HI__, 0x01, 0x00},
- {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00},
- {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
- {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
- {SENSOR, 0x11, 0x04, 0x00},
- {SENSOR, 0x12, 0xc3, 0x00},
- {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
- {SENSOR, 0x02, 0x0e, 0x00},
-};
-#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
deleted file mode 100644
index 1de743a02b0..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- * Driver for the s5k83a sensor
- *
- * Copyright (C) 2008 Erik Andrén
- * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kthread.h>
-#include "m5602_s5k83a.h"
-
-static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
-static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
-static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-
-static struct v4l2_pix_format s5k83a_modes[] = {
- {
- 640,
- 480,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 640 * 480,
- .bytesperline = 640,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- }
-};
-
-static const struct ctrl s5k83a_ctrls[] = {
-#define GAIN_IDX 0
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "gain",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = S5K83A_DEFAULT_GAIN,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = s5k83a_set_gain,
- .get = s5k83a_get_gain
-
- },
-#define BRIGHTNESS_IDX 1
- {
- {
- .id = V4L2_CID_BRIGHTNESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "brightness",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = S5K83A_DEFAULT_BRIGHTNESS,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = s5k83a_set_brightness,
- .get = s5k83a_get_brightness,
- },
-#define EXPOSURE_IDX 2
- {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = S5K83A_MAXIMUM_EXPOSURE,
- .step = 0x01,
- .default_value = S5K83A_DEFAULT_EXPOSURE,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = s5k83a_set_exposure,
- .get = s5k83a_get_exposure
- },
-#define HFLIP_IDX 3
- {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = s5k83a_set_hflip,
- .get = s5k83a_get_hflip
- },
-#define VFLIP_IDX 4
- {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = s5k83a_set_vflip,
- .get = s5k83a_get_vflip
- }
-};
-
-static void s5k83a_dump_registers(struct sd *sd);
-static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data);
-static int s5k83a_set_led_indication(struct sd *sd, u8 val);
-static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
- __s32 vflip, __s32 hflip);
-
-int s5k83a_probe(struct sd *sd)
-{
- struct s5k83a_priv *sens_priv;
- u8 prod_id = 0, ver_id = 0;
- int i, err = 0;
-
- if (force_sensor) {
- if (force_sensor == S5K83A_SENSOR) {
- pr_info("Forcing a %s sensor\n", s5k83a.name);
- goto sensor_found;
- }
- /* If we want to force another sensor, don't try to probe this
- * one */
- return -ENODEV;
- }
-
- PDEBUG(D_PROBE, "Probing for a s5k83a sensor");
-
- /* Preinit the sensor */
- for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
- u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]};
- if (preinit_s5k83a[i][0] == SENSOR)
- err = m5602_write_sensor(sd, preinit_s5k83a[i][1],
- data, 2);
- else
- err = m5602_write_bridge(sd, preinit_s5k83a[i][1],
- data[0]);
- }
-
- /* We don't know what register (if any) that contain the product id
- * Just pick the first addresses that seem to produce the same results
- * on multiple machines */
- if (m5602_read_sensor(sd, 0x00, &prod_id, 1))
- return -ENODEV;
-
- if (m5602_read_sensor(sd, 0x01, &ver_id, 1))
- return -ENODEV;
-
- if ((prod_id == 0xff) || (ver_id == 0xff))
- return -ENODEV;
- else
- pr_info("Detected a s5k83a sensor\n");
-
-sensor_found:
- sens_priv = kmalloc(
- sizeof(struct s5k83a_priv), GFP_KERNEL);
- if (!sens_priv)
- return -ENOMEM;
-
- sens_priv->settings =
- kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL);
- if (!sens_priv->settings) {
- kfree(sens_priv);
- return -ENOMEM;
- }
-
- sd->gspca_dev.cam.cam_mode = s5k83a_modes;
- sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
- sd->desc->ctrls = s5k83a_ctrls;
- sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls);
-
- /* null the pointer! thread is't running now */
- sens_priv->rotation_thread = NULL;
-
- for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++)
- sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value;
-
- sd->sensor_priv = sens_priv;
- return 0;
-}
-
-int s5k83a_init(struct sd *sd)
-{
- int i, err = 0;
- s32 *sensor_settings =
- ((struct s5k83a_priv *) sd->sensor_priv)->settings;
-
- for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) {
- u8 data[2] = {0x00, 0x00};
-
- switch (init_s5k83a[i][0]) {
- case BRIDGE:
- err = m5602_write_bridge(sd,
- init_s5k83a[i][1],
- init_s5k83a[i][2]);
- break;
-
- case SENSOR:
- data[0] = init_s5k83a[i][2];
- err = m5602_write_sensor(sd,
- init_s5k83a[i][1], data, 1);
- break;
-
- case SENSOR_LONG:
- data[0] = init_s5k83a[i][2];
- data[1] = init_s5k83a[i][3];
- err = m5602_write_sensor(sd,
- init_s5k83a[i][1], data, 2);
- break;
- default:
- pr_info("Invalid stream command, exiting init\n");
- return -EINVAL;
- }
- }
-
- if (dump_sensor)
- s5k83a_dump_registers(sd);
-
- err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
- if (err < 0)
- return err;
-
- err = s5k83a_set_brightness(&sd->gspca_dev,
- sensor_settings[BRIGHTNESS_IDX]);
- if (err < 0)
- return err;
-
- err = s5k83a_set_exposure(&sd->gspca_dev,
- sensor_settings[EXPOSURE_IDX]);
- if (err < 0)
- return err;
-
- err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
- if (err < 0)
- return err;
-
- err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
-
- return err;
-}
-
-static int rotation_thread_function(void *data)
-{
- struct sd *sd = (struct sd *) data;
- struct s5k83a_priv *sens_priv = sd->sensor_priv;
- u8 reg, previous_rotation = 0;
- __s32 vflip, hflip;
-
- set_current_state(TASK_INTERRUPTIBLE);
- while (!schedule_timeout(100)) {
- if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock))
- break;
-
- s5k83a_get_rotation(sd, &reg);
- if (previous_rotation != reg) {
- previous_rotation = reg;
- pr_info("Camera was flipped\n");
-
- s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
- s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
-
- if (reg) {
- vflip = !vflip;
- hflip = !hflip;
- }
- s5k83a_set_flip_real((struct gspca_dev *) sd,
- vflip, hflip);
- }
-
- mutex_unlock(&sd->gspca_dev.usb_lock);
- set_current_state(TASK_INTERRUPTIBLE);
- }
-
- /* return to "front" flip */
- if (previous_rotation) {
- s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
- s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
- s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
- }
-
- sens_priv->rotation_thread = NULL;
- return 0;
-}
-
-int s5k83a_start(struct sd *sd)
-{
- int i, err = 0;
- struct s5k83a_priv *sens_priv = sd->sensor_priv;
-
- /* Create another thread, polling the GPIO ports of the camera to check
- if it got rotated. This is how the windows driver does it so we have
- to assume that there is no better way of accomplishing this */
- sens_priv->rotation_thread = kthread_create(rotation_thread_function,
- sd, "rotation thread");
- wake_up_process(sens_priv->rotation_thread);
-
- /* Preinit the sensor */
- for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) {
- u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]};
- if (start_s5k83a[i][0] == SENSOR)
- err = m5602_write_sensor(sd, start_s5k83a[i][1],
- data, 2);
- else
- err = m5602_write_bridge(sd, start_s5k83a[i][1],
- data[0]);
- }
- if (err < 0)
- return err;
-
- return s5k83a_set_led_indication(sd, 1);
-}
-
-int s5k83a_stop(struct sd *sd)
-{
- struct s5k83a_priv *sens_priv = sd->sensor_priv;
-
- if (sens_priv->rotation_thread)
- kthread_stop(sens_priv->rotation_thread);
-
- return s5k83a_set_led_indication(sd, 0);
-}
-
-void s5k83a_disconnect(struct sd *sd)
-{
- struct s5k83a_priv *sens_priv = sd->sensor_priv;
-
- s5k83a_stop(sd);
-
- sd->sensor = NULL;
- kfree(sens_priv->settings);
- kfree(sens_priv);
-}
-
-static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct s5k83a_priv *sens_priv = sd->sensor_priv;
-
- *val = sens_priv->settings[GAIN_IDX];
- return 0;
-}
-
-static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 data[2];
- struct sd *sd = (struct sd *) gspca_dev;
- struct s5k83a_priv *sens_priv = sd->sensor_priv;
-
- sens_priv->settings[GAIN_IDX] = val;
-
- data[0] = 0x00;
- data[1] = 0x20;
- err = m5602_write_sensor(sd, 0x14, data, 2);
- if (err < 0)
- return err;
-
- data[0] = 0x01;
- data[1] = 0x00;
- err = m5602_write_sensor(sd, 0x0d, data, 2);
- if (err < 0)
- return err;
-
- /* FIXME: This is not sane, we need to figure out the composition
- of these registers */
- data[0] = val >> 3; /* gain, high 5 bits */
- data[1] = val >> 1; /* gain, high 7 bits */
- err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
-
- return err;
-}
-
-static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct s5k83a_priv *sens_priv = sd->sensor_priv;
-
- *val = sens_priv->settings[BRIGHTNESS_IDX];
- return 0;
-}
-
-static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 data[1];
- struct sd *sd = (struct sd *) gspca_dev;
- struct s5k83a_priv *sens_priv = sd->sensor_priv;
-
- sens_priv->settings[BRIGHTNESS_IDX] = val;
- data[0] = val;
- err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1);
- return err;
-}
-
-static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct s5k83a_priv *sens_priv = sd->sensor_priv;
-
- *val = sens_priv->settings[EXPOSURE_IDX];
- return 0;
-}
-
-static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 data[2];
- struct sd *sd = (struct sd *) gspca_dev;
- struct s5k83a_priv *sens_priv = sd->sensor_priv;
-
- sens_priv->settings[EXPOSURE_IDX] = val;
- data[0] = 0;
- data[1] = val;
- err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2);
- return err;
-}
-
-static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct s5k83a_priv *sens_priv = sd->sensor_priv;
-
- *val = sens_priv->settings[VFLIP_IDX];
- return 0;
-}
-
-static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
- __s32 vflip, __s32 hflip)
-{
- int err;
- u8 data[1];
- struct sd *sd = (struct sd *) gspca_dev;
-
- data[0] = 0x05;
- err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
- if (err < 0)
- return err;
-
- /* six bit is vflip, seven is hflip */
- data[0] = S5K83A_FLIP_MASK;
- data[0] = (vflip) ? data[0] | 0x40 : data[0];
- data[0] = (hflip) ? data[0] | 0x80 : data[0];
-
- err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
- if (err < 0)
- return err;
-
- data[0] = (vflip) ? 0x0b : 0x0a;
- err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
- if (err < 0)
- return err;
-
- data[0] = (hflip) ? 0x0a : 0x0b;
- err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
- return err;
-}
-
-static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 reg;
- __s32 hflip;
- struct sd *sd = (struct sd *) gspca_dev;
- struct s5k83a_priv *sens_priv = sd->sensor_priv;
-
- sens_priv->settings[VFLIP_IDX] = val;
-
- s5k83a_get_hflip(gspca_dev, &hflip);
-
- err = s5k83a_get_rotation(sd, &reg);
- if (err < 0)
- return err;
- if (reg) {
- val = !val;
- hflip = !hflip;
- }
-
- err = s5k83a_set_flip_real(gspca_dev, val, hflip);
- return err;
-}
-
-static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct s5k83a_priv *sens_priv = sd->sensor_priv;
-
- *val = sens_priv->settings[HFLIP_IDX];
- return 0;
-}
-
-static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u8 reg;
- __s32 vflip;
- struct sd *sd = (struct sd *) gspca_dev;
- struct s5k83a_priv *sens_priv = sd->sensor_priv;
-
- sens_priv->settings[HFLIP_IDX] = val;
-
- s5k83a_get_vflip(gspca_dev, &vflip);
-
- err = s5k83a_get_rotation(sd, &reg);
- if (err < 0)
- return err;
- if (reg) {
- val = !val;
- vflip = !vflip;
- }
-
- err = s5k83a_set_flip_real(gspca_dev, vflip, val);
- return err;
-}
-
-static int s5k83a_set_led_indication(struct sd *sd, u8 val)
-{
- int err = 0;
- u8 data[1];
-
- err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, data);
- if (err < 0)
- return err;
-
- if (val)
- data[0] = data[0] | S5K83A_GPIO_LED_MASK;
- else
- data[0] = data[0] & ~S5K83A_GPIO_LED_MASK;
-
- err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
-
- return err;
-}
-
-/* Get camera rotation on Acer notebooks */
-static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data)
-{
- int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data);
- *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1;
- return err;
-}
-
-static void s5k83a_dump_registers(struct sd *sd)
-{
- int address;
- u8 page, old_page;
- m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
-
- for (page = 0; page < 16; page++) {
- m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
- pr_info("Dumping the s5k83a register state for page 0x%x\n",
- page);
- for (address = 0; address <= 0xff; address++) {
- u8 val = 0;
- m5602_read_sensor(sd, address, &val, 1);
- pr_info("register 0x%x contains 0x%x\n", address, val);
- }
- }
- pr_info("s5k83a register state dump complete\n");
-
- for (page = 0; page < 16; page++) {
- m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
- pr_info("Probing for which registers that are read/write for page 0x%x\n",
- page);
- for (address = 0; address <= 0xff; address++) {
- u8 old_val, ctrl_val, test_val = 0xff;
-
- m5602_read_sensor(sd, address, &old_val, 1);
- m5602_write_sensor(sd, address, &test_val, 1);
- m5602_read_sensor(sd, address, &ctrl_val, 1);
-
- if (ctrl_val == test_val)
- pr_info("register 0x%x is writeable\n",
- address);
- else
- pr_info("register 0x%x is read only\n",
- address);
-
- /* Restore original val */
- m5602_write_sensor(sd, address, &old_val, 1);
- }
- }
- pr_info("Read/write register probing complete\n");
- m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
-}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
deleted file mode 100644
index 79952247b53..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Driver for the s5k83a sensor
- *
- * Copyright (C) 2008 Erik Andrén
- * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#ifndef M5602_S5K83A_H_
-#define M5602_S5K83A_H_
-
-#include "m5602_sensor.h"
-
-#define S5K83A_FLIP 0x01
-#define S5K83A_HFLIP_TUNE 0x03
-#define S5K83A_VFLIP_TUNE 0x05
-#define S5K83A_BRIGHTNESS 0x0a
-#define S5K83A_EXPOSURE 0x18
-#define S5K83A_GAIN 0x1b
-#define S5K83A_PAGE_MAP 0xec
-
-#define S5K83A_DEFAULT_GAIN 0x71
-#define S5K83A_DEFAULT_BRIGHTNESS 0x7e
-#define S5K83A_DEFAULT_EXPOSURE 0x00
-#define S5K83A_MAXIMUM_EXPOSURE 0x3c
-#define S5K83A_FLIP_MASK 0x10
-#define S5K83A_GPIO_LED_MASK 0x10
-#define S5K83A_GPIO_ROTATION_MASK 0x40
-
-/*****************************************************************************/
-
-/* Kernel module parameters */
-extern int force_sensor;
-extern bool dump_sensor;
-
-int s5k83a_probe(struct sd *sd);
-int s5k83a_init(struct sd *sd);
-int s5k83a_start(struct sd *sd);
-int s5k83a_stop(struct sd *sd);
-void s5k83a_disconnect(struct sd *sd);
-
-static const struct m5602_sensor s5k83a = {
- .name = "S5K83A",
- .probe = s5k83a_probe,
- .init = s5k83a_init,
- .start = s5k83a_start,
- .stop = s5k83a_stop,
- .disconnect = s5k83a_disconnect,
- .i2c_slave_id = 0x5a,
- .i2c_regW = 2,
-};
-
-struct s5k83a_priv {
- /* We use another thread periodically
- probing the orientation of the camera */
- struct task_struct *rotation_thread;
- s32 *settings;
-};
-
-static const unsigned char preinit_s5k83a[][4] = {
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
- {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
-
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
-};
-
-/* This could probably be considerably shortened.
- I don't have the hardware to experiment with it, patches welcome
-*/
-static const unsigned char init_s5k83a[][4] = {
- /* The following sequence is useless after a clean boot
- but is necessary after resume from suspend */
- {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
- {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
- {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
- {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
-
- {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
- {SENSOR, 0xaf, 0x01, 0x00},
- {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
- {SENSOR, 0x7b, 0xff, 0x00},
- {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
- {SENSOR, 0x01, 0x50, 0x00},
- {SENSOR, 0x12, 0x20, 0x00},
- {SENSOR, 0x17, 0x40, 0x00},
- {SENSOR, 0x1c, 0x00, 0x00},
- {SENSOR, 0x02, 0x70, 0x00},
- {SENSOR, 0x03, 0x0b, 0x00},
- {SENSOR, 0x04, 0xf0, 0x00},
- {SENSOR, 0x05, 0x0b, 0x00},
- {SENSOR, 0x06, 0x71, 0x00},
- {SENSOR, 0x07, 0xe8, 0x00}, /* 488 */
- {SENSOR, 0x08, 0x02, 0x00},
- {SENSOR, 0x09, 0x88, 0x00}, /* 648 */
- {SENSOR, 0x14, 0x00, 0x00},
- {SENSOR, 0x15, 0x20, 0x00}, /* 32 */
- {SENSOR, 0x19, 0x00, 0x00},
- {SENSOR, 0x1a, 0x98, 0x00}, /* 152 */
- {SENSOR, 0x0f, 0x02, 0x00},
- {SENSOR, 0x10, 0xe5, 0x00}, /* 741 */
- /* normal colors
- (this is value after boot, but after tries can be different) */
- {SENSOR, 0x00, 0x06, 0x00},
-};
-
-static const unsigned char start_s5k83a[][4] = {
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
- {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
- {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
- {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
- {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, /* 484 */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, /* 639 */
- {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
- {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-};
-#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h
deleted file mode 100644
index edff4f1f586..00000000000
--- a/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * USB Driver for ALi m5602 based webcams
- *
- * Copyright (C) 2008 Erik Andrén
- * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
- * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
- *
- * Portions of code to USB interface and ALi driver software,
- * Copyright (c) 2006 Willem Duinker
- * v4l2 interface modeled after the V4L2 driver
- * for SN9C10x PC Camera Controllers
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#ifndef M5602_SENSOR_H_
-#define M5602_SENSOR_H_
-
-#include "m5602_bridge.h"
-
-#define M5602_V4L2_CID_GREEN_BALANCE (V4L2_CID_PRIVATE_BASE + 0)
-#define M5602_V4L2_CID_NOISE_SUPPRESION (V4L2_CID_PRIVATE_BASE + 1)
-
-/* Enumerates all supported sensors */
-enum sensors {
- OV9650_SENSOR = 1,
- S5K83A_SENSOR = 2,
- S5K4AA_SENSOR = 3,
- MT9M111_SENSOR = 4,
- PO1030_SENSOR = 5,
- OV7660_SENSOR = 6,
-};
-
-/* Enumerates all possible instruction types */
-enum instruction {
- BRIDGE,
- SENSOR,
- SENSOR_LONG
-};
-
-struct m5602_sensor {
- /* Defines the name of a sensor */
- char name[32];
-
- /* What i2c address the sensor is connected to */
- u8 i2c_slave_id;
-
- /* Width of each i2c register (in bytes) */
- u8 i2c_regW;
-
- /* Probes if the sensor is connected */
- int (*probe)(struct sd *sd);
-
- /* Performs a initialization sequence */
- int (*init)(struct sd *sd);
-
- /* Executed when the camera starts to send data */
- int (*start)(struct sd *sd);
-
- /* Executed when the camera ends to send data */
- int (*stop)(struct sd *sd);
-
- /* Executed when the device is disconnected */
- void (*disconnect)(struct sd *sd);
-};
-
-#endif
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
deleted file mode 100644
index ff2c5abf115..00000000000
--- a/drivers/media/video/gspca/mars.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * Mars-Semi MR97311A library
- * Copyright (C) 2005 <bradlch@hotmail.com>
- *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "mars"
-
-#include "gspca.h"
-#include "jpeg.h"
-
-MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
-MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-#define QUALITY 50
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- struct v4l2_ctrl *brightness;
- struct v4l2_ctrl *saturation;
- struct v4l2_ctrl *sharpness;
- struct v4l2_ctrl *gamma;
- struct { /* illuminator control cluster */
- struct v4l2_ctrl *illum_top;
- struct v4l2_ctrl *illum_bottom;
- };
- u8 jpeg_hdr[JPEG_HDR_SZ];
-};
-
-/* V4L2 controls supported by the driver */
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val);
-static void setcolors(struct gspca_dev *gspca_dev, s32 val);
-static void setgamma(struct gspca_dev *gspca_dev, s32 val);
-static void setsharpness(struct gspca_dev *gspca_dev, s32 val);
-
-static const struct v4l2_pix_format vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
-};
-
-static const __u8 mi_data[0x20] = {
-/* 01 02 03 04 05 06 07 08 */
- 0x48, 0x22, 0x01, 0x47, 0x10, 0x00, 0x00, 0x00,
-/* 09 0a 0b 0c 0d 0e 0f 10 */
- 0x00, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01,
-/* 11 12 13 14 15 16 17 18 */
- 0x30, 0x00, 0x04, 0x00, 0x06, 0x01, 0xe2, 0x02,
-/* 19 1a 1b 1c 1d 1e 1f 20 */
- 0x82, 0x00, 0x20, 0x17, 0x80, 0x08, 0x0c, 0x00
-};
-
-/* write <len> bytes from gspca_dev->usb_buf */
-static void reg_w(struct gspca_dev *gspca_dev,
- int len)
-{
- int alen, ret;
-
- if (gspca_dev->usb_err < 0)
- return;
-
- ret = usb_bulk_msg(gspca_dev->dev,
- usb_sndbulkpipe(gspca_dev->dev, 4),
- gspca_dev->usb_buf,
- len,
- &alen,
- 500); /* timeout in milliseconds */
- if (ret < 0) {
- pr_err("reg write [%02x] error %d\n",
- gspca_dev->usb_buf[0], ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void mi_w(struct gspca_dev *gspca_dev,
- u8 addr,
- u8 value)
-{
- gspca_dev->usb_buf[0] = 0x1f;
- gspca_dev->usb_buf[1] = 0; /* control byte */
- gspca_dev->usb_buf[2] = addr;
- gspca_dev->usb_buf[3] = value;
-
- reg_w(gspca_dev, 4);
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
-{
- gspca_dev->usb_buf[0] = 0x61;
- gspca_dev->usb_buf[1] = val;
- reg_w(gspca_dev, 2);
-}
-
-static void setcolors(struct gspca_dev *gspca_dev, s32 val)
-{
- gspca_dev->usb_buf[0] = 0x5f;
- gspca_dev->usb_buf[1] = val << 3;
- gspca_dev->usb_buf[2] = ((val >> 2) & 0xf8) | 0x04;
- reg_w(gspca_dev, 3);
-}
-
-static void setgamma(struct gspca_dev *gspca_dev, s32 val)
-{
- gspca_dev->usb_buf[0] = 0x06;
- gspca_dev->usb_buf[1] = val * 0x40;
- reg_w(gspca_dev, 2);
-}
-
-static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
-{
- gspca_dev->usb_buf[0] = 0x67;
- gspca_dev->usb_buf[1] = val * 4 + 3;
- reg_w(gspca_dev, 2);
-}
-
-static void setilluminators(struct gspca_dev *gspca_dev, bool top, bool bottom)
-{
- /* both are off if not streaming */
- gspca_dev->usb_buf[0] = 0x22;
- if (top)
- gspca_dev->usb_buf[1] = 0x76;
- else if (bottom)
- gspca_dev->usb_buf[1] = 0x7a;
- else
- gspca_dev->usb_buf[1] = 0x7e;
- reg_w(gspca_dev, 2);
-}
-
-static int mars_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (ctrl->id == V4L2_CID_ILLUMINATORS_1) {
- /* only one can be on at a time */
- if (ctrl->is_new && ctrl->val)
- sd->illum_bottom->val = 0;
- if (sd->illum_bottom->is_new && sd->illum_bottom->val)
- sd->illum_top->val = 0;
- }
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- setcolors(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_GAMMA:
- setgamma(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_ILLUMINATORS_1:
- setilluminators(gspca_dev, sd->illum_top->val,
- sd->illum_bottom->val);
- break;
- case V4L2_CID_SHARPNESS:
- setsharpness(gspca_dev, ctrl->val);
- break;
- default:
- return -EINVAL;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops mars_ctrl_ops = {
- .s_ctrl = mars_s_ctrl,
-};
-
-/* this function is called at probe time */
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 6);
- sd->brightness = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 30, 1, 15);
- sd->saturation = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, 200);
- sd->gamma = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops,
- V4L2_CID_GAMMA, 0, 3, 1, 1);
- sd->sharpness = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops,
- V4L2_CID_SHARPNESS, 0, 2, 1, 1);
- sd->illum_top = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops,
- V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0);
- sd->illum_top->flags |= V4L2_CTRL_FLAG_UPDATE;
- sd->illum_bottom = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops,
- V4L2_CID_ILLUMINATORS_2, 0, 1, 1, 0);
- sd->illum_bottom->flags |= V4L2_CTRL_FLAG_UPDATE;
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- v4l2_ctrl_cluster(2, &sd->illum_top);
- return 0;
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct cam *cam;
-
- cam = &gspca_dev->cam;
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- return 0;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 *data;
- int i;
-
- /* create the JPEG header */
- jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
- 0x21); /* JPEG 422 */
- jpeg_set_qual(sd->jpeg_hdr, QUALITY);
-
- data = gspca_dev->usb_buf;
-
- data[0] = 0x01; /* address */
- data[1] = 0x01;
- reg_w(gspca_dev, 2);
-
- /*
- Initialize the MR97113 chip register
- */
- data[0] = 0x00; /* address */
- data[1] = 0x0c | 0x01; /* reg 0 */
- data[2] = 0x01; /* reg 1 */
- data[3] = gspca_dev->width / 8; /* h_size , reg 2 */
- data[4] = gspca_dev->height / 8; /* v_size , reg 3 */
- data[5] = 0x30; /* reg 4, MI, PAS5101 :
- * 0x30 for 24mhz , 0x28 for 12mhz */
- data[6] = 0x02; /* reg 5, H start - was 0x04 */
- data[7] = v4l2_ctrl_g_ctrl(sd->gamma) * 0x40; /* reg 0x06: gamma */
- data[8] = 0x01; /* reg 7, V start - was 0x03 */
-/* if (h_size == 320 ) */
-/* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */
-/* else */
- data[9] = 0x52; /* reg 8, 24MHz, no scale down */
-/*jfm: from win trace*/
- data[10] = 0x18;
-
- reg_w(gspca_dev, 11);
-
- data[0] = 0x23; /* address */
- data[1] = 0x09; /* reg 35, append frame header */
-
- reg_w(gspca_dev, 2);
-
- data[0] = 0x3c; /* address */
-/* if (gspca_dev->width == 1280) */
-/* data[1] = 200; * reg 60, pc-cam frame size
- * (unit: 4KB) 800KB */
-/* else */
- data[1] = 50; /* 50 reg 60, pc-cam frame size
- * (unit: 4KB) 200KB */
- reg_w(gspca_dev, 2);
-
- /* auto dark-gain */
- data[0] = 0x5e; /* address */
- data[1] = 0; /* reg 94, Y Gain (auto) */
-/*jfm: from win trace*/
- /* reg 0x5f/0x60 (LE) = saturation */
- /* h (60): xxxx x100
- * l (5f): xxxx x000 */
- data[2] = v4l2_ctrl_g_ctrl(sd->saturation) << 3;
- data[3] = ((v4l2_ctrl_g_ctrl(sd->saturation) >> 2) & 0xf8) | 0x04;
- data[4] = v4l2_ctrl_g_ctrl(sd->brightness); /* reg 0x61 = brightness */
- data[5] = 0x00;
-
- reg_w(gspca_dev, 6);
-
- data[0] = 0x67;
-/*jfm: from win trace*/
- data[1] = v4l2_ctrl_g_ctrl(sd->sharpness) * 4 + 3;
- data[2] = 0x14;
- reg_w(gspca_dev, 3);
-
- data[0] = 0x69;
- data[1] = 0x2f;
- data[2] = 0x28;
- data[3] = 0x42;
- reg_w(gspca_dev, 4);
-
- data[0] = 0x63;
- data[1] = 0x07;
- reg_w(gspca_dev, 2);
-/*jfm: win trace - many writes here to reg 0x64*/
-
- /* initialize the MI sensor */
- for (i = 0; i < sizeof mi_data; i++)
- mi_w(gspca_dev, i + 1, mi_data[i]);
-
- data[0] = 0x00;
- data[1] = 0x4d; /* ISOC transferring enable... */
- reg_w(gspca_dev, 2);
-
- setilluminators(gspca_dev, v4l2_ctrl_g_ctrl(sd->illum_top),
- v4l2_ctrl_g_ctrl(sd->illum_bottom));
-
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (v4l2_ctrl_g_ctrl(sd->illum_top) ||
- v4l2_ctrl_g_ctrl(sd->illum_bottom)) {
- setilluminators(gspca_dev, false, false);
- msleep(20);
- }
-
- gspca_dev->usb_buf[0] = 1;
- gspca_dev->usb_buf[1] = 0;
- reg_w(gspca_dev, 2);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int p;
-
- if (len < 6) {
-/* gspca_dev->last_packet_type = DISCARD_PACKET; */
- return;
- }
- for (p = 0; p < len - 6; p++) {
- if (data[0 + p] == 0xff
- && data[1 + p] == 0xff
- && data[2 + p] == 0x00
- && data[3 + p] == 0xff
- && data[4 + p] == 0x96) {
- if (data[5 + p] == 0x64
- || data[5 + p] == 0x65
- || data[5 + p] == 0x66
- || data[5 + p] == 0x67) {
- PDEBUG(D_PACK, "sof offset: %d len: %d",
- p, len);
- gspca_frame_add(gspca_dev, LAST_PACKET,
- data, p);
-
- /* put the JPEG header */
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sd->jpeg_hdr, JPEG_HDR_SZ);
- data += p + 16;
- len -= p + 16;
- break;
- }
- }
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x093a, 0x050f)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
deleted file mode 100644
index 8f4714df599..00000000000
--- a/drivers/media/video/gspca/mr97310a.c
+++ /dev/null
@@ -1,1091 +0,0 @@
-/*
- * Mars MR97310A library
- *
- * The original mr97310a driver, which supported the Aiptek Pencam VGA+, is
- * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
- *
- * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+
- * and for the routines for detecting and classifying these various cameras,
- * is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
- *
- * Support for the control settings for the CIF cameras is
- * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> and
- * Thomas Kaiser <thomas@kaiser-linux.li>
- *
- * Support for the control settings for the VGA cameras is
- * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
- *
- * Several previously unsupported cameras are owned and have been tested by
- * Hans de Goede <hdegoede@redhat.com> and
- * Thomas Kaiser <thomas@kaiser-linux.li> and
- * Theodore Kilgore <kilgota@auburn.edu> and
- * Edmond Rodriguez <erodrig_97@yahoo.com> and
- * Aurelien Jacobs <aurel@gnuage.org>
- *
- * The MR97311A support in gspca/mars.c has been helpful in understanding some
- * of the registers in these cameras.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "mr97310a"
-
-#include "gspca.h"
-
-#define CAM_TYPE_CIF 0
-#define CAM_TYPE_VGA 1
-
-#define MR97310A_BRIGHTNESS_DEFAULT 0
-
-#define MR97310A_EXPOSURE_MIN 0
-#define MR97310A_EXPOSURE_MAX 4095
-#define MR97310A_EXPOSURE_DEFAULT 1000
-
-#define MR97310A_GAIN_MIN 0
-#define MR97310A_GAIN_MAX 31
-#define MR97310A_GAIN_DEFAULT 25
-
-#define MR97310A_CONTRAST_MIN 0
-#define MR97310A_CONTRAST_MAX 31
-#define MR97310A_CONTRAST_DEFAULT 23
-
-#define MR97310A_CS_GAIN_MIN 0
-#define MR97310A_CS_GAIN_MAX 0x7ff
-#define MR97310A_CS_GAIN_DEFAULT 0x110
-
-#define MR97310A_CID_CLOCKDIV (V4L2_CTRL_CLASS_USER + 0x1000)
-#define MR97310A_MIN_CLOCKDIV_MIN 3
-#define MR97310A_MIN_CLOCKDIV_MAX 8
-#define MR97310A_MIN_CLOCKDIV_DEFAULT 3
-
-MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
- "Theodore Kilgore <kilgota@auburn.edu>");
-MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* global parameters */
-static int force_sensor_type = -1;
-module_param(force_sensor_type, int, 0644);
-MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- struct { /* exposure/min_clockdiv control cluster */
- struct v4l2_ctrl *exposure;
- struct v4l2_ctrl *min_clockdiv;
- };
- u8 sof_read;
- u8 cam_type; /* 0 is CIF and 1 is VGA */
- u8 sensor_type; /* We use 0 and 1 here, too. */
- u8 do_lcd_stop;
- u8 adj_colors;
-};
-
-struct sensor_w_data {
- u8 reg;
- u8 flags;
- u8 data[16];
- int len;
-};
-
-static void sd_stopN(struct gspca_dev *gspca_dev);
-
-static const struct v4l2_pix_format vga_mode[] = {
- {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 4},
- {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 3},
- {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
- {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-/* the bytes to write are in gspca_dev->usb_buf */
-static int mr_write(struct gspca_dev *gspca_dev, int len)
-{
- int rc;
-
- rc = usb_bulk_msg(gspca_dev->dev,
- usb_sndbulkpipe(gspca_dev->dev, 4),
- gspca_dev->usb_buf, len, NULL, 500);
- if (rc < 0)
- pr_err("reg write [%02x] error %d\n",
- gspca_dev->usb_buf[0], rc);
- return rc;
-}
-
-/* the bytes are read into gspca_dev->usb_buf */
-static int mr_read(struct gspca_dev *gspca_dev, int len)
-{
- int rc;
-
- rc = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev, 3),
- gspca_dev->usb_buf, len, NULL, 500);
- if (rc < 0)
- pr_err("reg read [%02x] error %d\n",
- gspca_dev->usb_buf[0], rc);
- return rc;
-}
-
-static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags,
- const u8 *data, int len)
-{
- gspca_dev->usb_buf[0] = 0x1f;
- gspca_dev->usb_buf[1] = flags;
- gspca_dev->usb_buf[2] = reg;
- memcpy(gspca_dev->usb_buf + 3, data, len);
-
- return mr_write(gspca_dev, len + 3);
-}
-
-static int sensor_write_regs(struct gspca_dev *gspca_dev,
- const struct sensor_w_data *data, int len)
-{
- int i, rc;
-
- for (i = 0; i < len; i++) {
- rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags,
- data[i].data, data[i].len);
- if (rc < 0)
- return rc;
- }
-
- return 0;
-}
-
-static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 buf, confirm_reg;
- int rc;
-
- buf = data;
- if (sd->cam_type == CAM_TYPE_CIF) {
- rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
- confirm_reg = sd->sensor_type ? 0x13 : 0x11;
- } else {
- rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1);
- confirm_reg = 0x11;
- }
- if (rc < 0)
- return rc;
-
- buf = 0x01;
- rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
- if (rc < 0)
- return rc;
-
- return 0;
-}
-
-static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)
-{
- int err_code;
-
- gspca_dev->usb_buf[0] = reg;
- err_code = mr_write(gspca_dev, 1);
- if (err_code < 0)
- return err_code;
-
- err_code = mr_read(gspca_dev, 16);
- if (err_code < 0)
- return err_code;
-
- if (verbose)
- PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg,
- gspca_dev->usb_buf[0],
- gspca_dev->usb_buf[1],
- gspca_dev->usb_buf[2]);
-
- return 0;
-}
-
-static int zero_the_pointer(struct gspca_dev *gspca_dev)
-{
- __u8 *data = gspca_dev->usb_buf;
- int err_code;
- u8 status = 0;
- int tries = 0;
-
- err_code = cam_get_response16(gspca_dev, 0x21, 0);
- if (err_code < 0)
- return err_code;
-
- data[0] = 0x19;
- data[1] = 0x51;
- err_code = mr_write(gspca_dev, 2);
- if (err_code < 0)
- return err_code;
-
- err_code = cam_get_response16(gspca_dev, 0x21, 0);
- if (err_code < 0)
- return err_code;
-
- data[0] = 0x19;
- data[1] = 0xba;
- err_code = mr_write(gspca_dev, 2);
- if (err_code < 0)
- return err_code;
-
- err_code = cam_get_response16(gspca_dev, 0x21, 0);
- if (err_code < 0)
- return err_code;
-
- data[0] = 0x19;
- data[1] = 0x00;
- err_code = mr_write(gspca_dev, 2);
- if (err_code < 0)
- return err_code;
-
- err_code = cam_get_response16(gspca_dev, 0x21, 0);
- if (err_code < 0)
- return err_code;
-
- data[0] = 0x19;
- data[1] = 0x00;
- err_code = mr_write(gspca_dev, 2);
- if (err_code < 0)
- return err_code;
-
- while (status != 0x0a && tries < 256) {
- err_code = cam_get_response16(gspca_dev, 0x21, 0);
- status = data[0];
- tries++;
- if (err_code < 0)
- return err_code;
- }
- if (status != 0x0a)
- PDEBUG(D_ERR, "status is %02x", status);
-
- tries = 0;
- while (tries < 4) {
- data[0] = 0x19;
- data[1] = 0x00;
- err_code = mr_write(gspca_dev, 2);
- if (err_code < 0)
- return err_code;
-
- err_code = cam_get_response16(gspca_dev, 0x21, 0);
- status = data[0];
- tries++;
- if (err_code < 0)
- return err_code;
- }
-
- data[0] = 0x19;
- err_code = mr_write(gspca_dev, 1);
- if (err_code < 0)
- return err_code;
-
- err_code = mr_read(gspca_dev, 16);
- if (err_code < 0)
- return err_code;
-
- return 0;
-}
-
-static int stream_start(struct gspca_dev *gspca_dev)
-{
- gspca_dev->usb_buf[0] = 0x01;
- gspca_dev->usb_buf[1] = 0x01;
- return mr_write(gspca_dev, 2);
-}
-
-static void stream_stop(struct gspca_dev *gspca_dev)
-{
- gspca_dev->usb_buf[0] = 0x01;
- gspca_dev->usb_buf[1] = 0x00;
- if (mr_write(gspca_dev, 2) < 0)
- PDEBUG(D_ERR, "Stream Stop failed");
-}
-
-static void lcd_stop(struct gspca_dev *gspca_dev)
-{
- gspca_dev->usb_buf[0] = 0x19;
- gspca_dev->usb_buf[1] = 0x54;
- if (mr_write(gspca_dev, 2) < 0)
- PDEBUG(D_ERR, "LCD Stop failed");
-}
-
-static int isoc_enable(struct gspca_dev *gspca_dev)
-{
- gspca_dev->usb_buf[0] = 0x00;
- gspca_dev->usb_buf[1] = 0x4d; /* ISOC transferring enable... */
- return mr_write(gspca_dev, 2);
-}
-
-/* This function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
- int err_code;
-
- cam = &gspca_dev->cam;
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- sd->do_lcd_stop = 0;
-
- /* Several of the supported CIF cameras share the same USB ID but
- * require different initializations and different control settings.
- * The same is true of the VGA cameras. Therefore, we are forced
- * to start the initialization process in order to determine which
- * camera is present. Some of the supported cameras require the
- * memory pointer to be set to 0 as the very first item of business
- * or else they will not stream. So we do that immediately.
- */
- err_code = zero_the_pointer(gspca_dev);
- if (err_code < 0)
- return err_code;
-
- err_code = stream_start(gspca_dev);
- if (err_code < 0)
- return err_code;
-
- /* Now, the query for sensor type. */
- err_code = cam_get_response16(gspca_dev, 0x07, 1);
- if (err_code < 0)
- return err_code;
-
- if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
- sd->cam_type = CAM_TYPE_CIF;
- cam->nmodes--;
- /*
- * All but one of the known CIF cameras share the same USB ID,
- * but two different init routines are in use, and the control
- * settings are different, too. We need to detect which camera
- * of the two known varieties is connected!
- *
- * A list of known CIF cameras follows. They all report either
- * 0200 for type 0 or 0300 for type 1.
- * If you have another to report, please do
- *
- * Name sd->sensor_type reported by
- *
- * Sakar 56379 Spy-shot 0 T. Kilgore
- * Innovage 0 T. Kilgore
- * Vivitar Mini 0 H. De Goede
- * Vivitar Mini 0 E. Rodriguez
- * Vivitar Mini 1 T. Kilgore
- * Elta-Media 8212dc 1 T. Kaiser
- * Philips dig. keych. 1 T. Kilgore
- * Trust Spyc@m 100 1 A. Jacobs
- */
- switch (gspca_dev->usb_buf[0]) {
- case 2:
- sd->sensor_type = 0;
- break;
- case 3:
- sd->sensor_type = 1;
- break;
- default:
- pr_err("Unknown CIF Sensor id : %02x\n",
- gspca_dev->usb_buf[1]);
- return -ENODEV;
- }
- PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
- sd->sensor_type);
- } else {
- sd->cam_type = CAM_TYPE_VGA;
-
- /*
- * Here is a table of the responses to the query for sensor
- * type, from the known MR97310A VGA cameras. Six different
- * cameras of which five share the same USB ID.
- *
- * Name gspca_dev->usb_buf[] sd->sensor_type
- * sd->do_lcd_stop
- * Aiptek Pencam VGA+ 0300 0 1
- * ION digital 0300 0 1
- * Argus DC-1620 0450 1 0
- * Argus QuickClix 0420 1 1
- * Sakar 77379 Digital 0350 0 1
- * Sakar 1638x CyberPix 0120 0 2
- *
- * Based upon these results, we assume default settings
- * and then correct as necessary, as follows.
- *
- */
-
- sd->sensor_type = 1;
- sd->do_lcd_stop = 0;
- sd->adj_colors = 0;
- if (gspca_dev->usb_buf[0] == 0x01) {
- sd->sensor_type = 2;
- } else if ((gspca_dev->usb_buf[0] != 0x03) &&
- (gspca_dev->usb_buf[0] != 0x04)) {
- pr_err("Unknown VGA Sensor id Byte 0: %02x\n",
- gspca_dev->usb_buf[0]);
- pr_err("Defaults assumed, may not work\n");
- pr_err("Please report this\n");
- }
- /* Sakar Digital color needs to be adjusted. */
- if ((gspca_dev->usb_buf[0] == 0x03) &&
- (gspca_dev->usb_buf[1] == 0x50))
- sd->adj_colors = 1;
- if (gspca_dev->usb_buf[0] == 0x04) {
- sd->do_lcd_stop = 1;
- switch (gspca_dev->usb_buf[1]) {
- case 0x50:
- sd->sensor_type = 0;
- PDEBUG(D_PROBE, "sensor_type corrected to 0");
- break;
- case 0x20:
- /* Nothing to do here. */
- break;
- default:
- pr_err("Unknown VGA Sensor id Byte 1: %02x\n",
- gspca_dev->usb_buf[1]);
- pr_err("Defaults assumed, may not work\n");
- pr_err("Please report this\n");
- }
- }
- PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
- sd->sensor_type);
- }
- /* Stop streaming as we've started it only to probe the sensor type. */
- sd_stopN(gspca_dev);
-
- if (force_sensor_type != -1) {
- sd->sensor_type = !!force_sensor_type;
- PDEBUG(D_PROBE, "Forcing sensor type to: %d",
- sd->sensor_type);
- }
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- return 0;
-}
-
-static int start_cif_cam(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- __u8 *data = gspca_dev->usb_buf;
- int err_code;
- static const __u8 startup_string[] = {
- 0x00,
- 0x0d,
- 0x01,
- 0x00, /* Hsize/8 for 352 or 320 */
- 0x00, /* Vsize/4 for 288 or 240 */
- 0x13, /* or 0xbb, depends on sensor */
- 0x00, /* Hstart, depends on res. */
- 0x00, /* reserved ? */
- 0x00, /* Vstart, depends on res. and sensor */
- 0x50, /* 0x54 to get 176 or 160 */
- 0xc0
- };
-
- /* Note: Some of the above descriptions guessed from MR97113A driver */
-
- memcpy(data, startup_string, 11);
- if (sd->sensor_type)
- data[5] = 0xbb;
-
- switch (gspca_dev->width) {
- case 160:
- data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */
- /* fall thru */
- case 320:
- default:
- data[3] = 0x28; /* reg 2, H size/8 */
- data[4] = 0x3c; /* reg 3, V size/4 */
- data[6] = 0x14; /* reg 5, H start */
- data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */
- break;
- case 176:
- data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */
- /* fall thru */
- case 352:
- data[3] = 0x2c; /* reg 2, H size/8 */
- data[4] = 0x48; /* reg 3, V size/4 */
- data[6] = 0x06; /* reg 5, H start */
- data[8] = 0x06 - sd->sensor_type; /* reg 7, V start */
- break;
- }
- err_code = mr_write(gspca_dev, 11);
- if (err_code < 0)
- return err_code;
-
- if (!sd->sensor_type) {
- static const struct sensor_w_data cif_sensor0_init_data[] = {
- {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
- 0x0f, 0x14, 0x0f, 0x10}, 8},
- {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
- {0x12, 0x00, {0x07}, 1},
- {0x1f, 0x00, {0x06}, 1},
- {0x27, 0x00, {0x04}, 1},
- {0x29, 0x00, {0x0c}, 1},
- {0x40, 0x00, {0x40, 0x00, 0x04}, 3},
- {0x50, 0x00, {0x60}, 1},
- {0x60, 0x00, {0x06}, 1},
- {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
- {0x72, 0x00, {0x1e, 0x56}, 2},
- {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
- 0x31, 0x80, 0x00}, 9},
- {0x11, 0x00, {0x01}, 1},
- {0, 0, {0}, 0}
- };
- err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
- ARRAY_SIZE(cif_sensor0_init_data));
- } else { /* sd->sensor_type = 1 */
- static const struct sensor_w_data cif_sensor1_init_data[] = {
- /* Reg 3,4, 7,8 get set by the controls */
- {0x02, 0x00, {0x10}, 1},
- {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
- {0x06, 0x01, {0x00}, 1},
- {0x09, 0x02, {0x0e}, 1},
- {0x0a, 0x02, {0x05}, 1},
- {0x0b, 0x02, {0x05}, 1},
- {0x0c, 0x02, {0x0f}, 1},
- {0x0d, 0x02, {0x07}, 1},
- {0x0e, 0x02, {0x0c}, 1},
- {0x0f, 0x00, {0x00}, 1},
- {0x10, 0x00, {0x06}, 1},
- {0x11, 0x00, {0x07}, 1},
- {0x12, 0x00, {0x00}, 1},
- {0x13, 0x00, {0x01}, 1},
- {0, 0, {0}, 0}
- };
- /* Without this command the cam won't work with USB-UHCI */
- gspca_dev->usb_buf[0] = 0x0a;
- gspca_dev->usb_buf[1] = 0x00;
- err_code = mr_write(gspca_dev, 2);
- if (err_code < 0)
- return err_code;
- err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
- ARRAY_SIZE(cif_sensor1_init_data));
- }
- return err_code;
-}
-
-static int start_vga_cam(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- __u8 *data = gspca_dev->usb_buf;
- int err_code;
- static const __u8 startup_string[] =
- {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, 0x00, 0x00,
- 0x00, 0x50, 0xc0};
- /* What some of these mean is explained in start_cif_cam(), above */
-
- memcpy(data, startup_string, 11);
- if (!sd->sensor_type) {
- data[5] = 0x00;
- data[10] = 0x91;
- }
- if (sd->sensor_type == 2) {
- data[5] = 0x00;
- data[10] = 0x18;
- }
-
- switch (gspca_dev->width) {
- case 160:
- data[9] |= 0x0c; /* reg 8, 4:1 scale down */
- /* fall thru */
- case 320:
- data[9] |= 0x04; /* reg 8, 2:1 scale down */
- /* fall thru */
- case 640:
- default:
- data[3] = 0x50; /* reg 2, H size/8 */
- data[4] = 0x78; /* reg 3, V size/4 */
- data[6] = 0x04; /* reg 5, H start */
- data[8] = 0x03; /* reg 7, V start */
- if (sd->sensor_type == 2) {
- data[6] = 2;
- data[8] = 1;
- }
- if (sd->do_lcd_stop)
- data[8] = 0x04; /* Bayer tile shifted */
- break;
-
- case 176:
- data[9] |= 0x04; /* reg 8, 2:1 scale down */
- /* fall thru */
- case 352:
- data[3] = 0x2c; /* reg 2, H size */
- data[4] = 0x48; /* reg 3, V size */
- data[6] = 0x94; /* reg 5, H start */
- data[8] = 0x63; /* reg 7, V start */
- if (sd->do_lcd_stop)
- data[8] = 0x64; /* Bayer tile shifted */
- break;
- }
-
- err_code = mr_write(gspca_dev, 11);
- if (err_code < 0)
- return err_code;
-
- if (!sd->sensor_type) {
- static const struct sensor_w_data vga_sensor0_init_data[] = {
- {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
- {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
- {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
- {0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
- {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
- {0, 0, {0}, 0}
- };
- err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
- ARRAY_SIZE(vga_sensor0_init_data));
- } else if (sd->sensor_type == 1) {
- static const struct sensor_w_data color_adj[] = {
- {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
- /* adjusted blue, green, red gain correct
- too much blue from the Sakar Digital */
- 0x05, 0x01, 0x04}, 8}
- };
-
- static const struct sensor_w_data color_no_adj[] = {
- {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
- /* default blue, green, red gain settings */
- 0x07, 0x00, 0x01}, 8}
- };
-
- static const struct sensor_w_data vga_sensor1_init_data[] = {
- {0x11, 0x04, {0x01}, 1},
- {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01,
- /* These settings may be better for some cameras */
- /* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */
- 0x00, 0x0a}, 7},
- {0x11, 0x04, {0x01}, 1},
- {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
- {0x11, 0x04, {0x01}, 1},
- {0, 0, {0}, 0}
- };
-
- if (sd->adj_colors)
- err_code = sensor_write_regs(gspca_dev, color_adj,
- ARRAY_SIZE(color_adj));
- else
- err_code = sensor_write_regs(gspca_dev, color_no_adj,
- ARRAY_SIZE(color_no_adj));
-
- if (err_code < 0)
- return err_code;
-
- err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
- ARRAY_SIZE(vga_sensor1_init_data));
- } else { /* sensor type == 2 */
- static const struct sensor_w_data vga_sensor2_init_data[] = {
-
- {0x01, 0x00, {0x48}, 1},
- {0x02, 0x00, {0x22}, 1},
- /* Reg 3 msb and 4 is lsb of the exposure setting*/
- {0x05, 0x00, {0x10}, 1},
- {0x06, 0x00, {0x00}, 1},
- {0x07, 0x00, {0x00}, 1},
- {0x08, 0x00, {0x00}, 1},
- {0x09, 0x00, {0x00}, 1},
- /* The following are used in the gain control
- * which is BTW completely borked in the OEM driver
- * The values for each color go from 0 to 0x7ff
- *{0x0a, 0x00, {0x01}, 1}, green1 gain msb
- *{0x0b, 0x00, {0x10}, 1}, green1 gain lsb
- *{0x0c, 0x00, {0x01}, 1}, red gain msb
- *{0x0d, 0x00, {0x10}, 1}, red gain lsb
- *{0x0e, 0x00, {0x01}, 1}, blue gain msb
- *{0x0f, 0x00, {0x10}, 1}, blue gain lsb
- *{0x10, 0x00, {0x01}, 1}, green2 gain msb
- *{0x11, 0x00, {0x10}, 1}, green2 gain lsb
- */
- {0x12, 0x00, {0x00}, 1},
- {0x13, 0x00, {0x04}, 1}, /* weird effect on colors */
- {0x14, 0x00, {0x00}, 1},
- {0x15, 0x00, {0x06}, 1},
- {0x16, 0x00, {0x01}, 1},
- {0x17, 0x00, {0xe2}, 1}, /* vertical alignment */
- {0x18, 0x00, {0x02}, 1},
- {0x19, 0x00, {0x82}, 1}, /* don't mess with */
- {0x1a, 0x00, {0x00}, 1},
- {0x1b, 0x00, {0x20}, 1},
- /* {0x1c, 0x00, {0x17}, 1}, contrast control */
- {0x1d, 0x00, {0x80}, 1}, /* moving causes a mess */
- {0x1e, 0x00, {0x08}, 1}, /* moving jams the camera */
- {0x1f, 0x00, {0x0c}, 1},
- {0x20, 0x00, {0x00}, 1},
- {0, 0, {0}, 0}
- };
- err_code = sensor_write_regs(gspca_dev, vga_sensor2_init_data,
- ARRAY_SIZE(vga_sensor2_init_data));
- }
- return err_code;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int err_code;
-
- sd->sof_read = 0;
-
- /* Some of the VGA cameras require the memory pointer
- * to be set to 0 again. We have been forced to start the
- * stream in sd_config() to detect the hardware, and closed it.
- * Thus, we need here to do a completely fresh and clean start. */
- err_code = zero_the_pointer(gspca_dev);
- if (err_code < 0)
- return err_code;
-
- err_code = stream_start(gspca_dev);
- if (err_code < 0)
- return err_code;
-
- if (sd->cam_type == CAM_TYPE_CIF) {
- err_code = start_cif_cam(gspca_dev);
- } else {
- err_code = start_vga_cam(gspca_dev);
- }
- if (err_code < 0)
- return err_code;
-
- return isoc_enable(gspca_dev);
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- stream_stop(gspca_dev);
- /* Not all the cams need this, but even if not, probably a good idea */
- zero_the_pointer(gspca_dev);
- if (sd->do_lcd_stop)
- lcd_stop(gspca_dev);
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */
- u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */
- static const u8 quick_clix_table[] =
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
- { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15};
- if (sd->cam_type == CAM_TYPE_VGA) {
- sign_reg += 4;
- value_reg += 4;
- }
-
- /* Note register 7 is also seen as 0x8x or 0xCx in some dumps */
- if (val > 0) {
- sensor_write1(gspca_dev, sign_reg, 0x00);
- } else {
- sensor_write1(gspca_dev, sign_reg, 0x01);
- val = 257 - val;
- }
- /* Use lookup table for funky Argus QuickClix brightness */
- if (sd->do_lcd_stop)
- val = quick_clix_table[val];
-
- sensor_write1(gspca_dev, value_reg, val);
-}
-
-static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 min_clockdiv)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int exposure = MR97310A_EXPOSURE_DEFAULT;
- u8 buf[2];
-
- if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
- /* This cam does not like exposure settings < 300,
- so scale 0 - 4095 to 300 - 4095 */
- exposure = (expo * 9267) / 10000 + 300;
- sensor_write1(gspca_dev, 3, exposure >> 4);
- sensor_write1(gspca_dev, 4, exposure & 0x0f);
- } else if (sd->sensor_type == 2) {
- exposure = expo;
- exposure >>= 3;
- sensor_write1(gspca_dev, 3, exposure >> 8);
- sensor_write1(gspca_dev, 4, exposure & 0xff);
- } else {
- /* We have both a clock divider and an exposure register.
- We first calculate the clock divider, as that determines
- the maximum exposure and then we calculate the exposure
- register setting (which goes from 0 - 511).
-
- Note our 0 - 4095 exposure is mapped to 0 - 511
- milliseconds exposure time */
- u8 clockdiv = (60 * expo + 7999) / 8000;
-
- /* Limit framerate to not exceed usb bandwidth */
- if (clockdiv < min_clockdiv && gspca_dev->width >= 320)
- clockdiv = min_clockdiv;
- else if (clockdiv < 2)
- clockdiv = 2;
-
- if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4)
- clockdiv = 4;
-
- /* Frame exposure time in ms = 1000 * clockdiv / 60 ->
- exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
- exposure = (60 * 511 * expo) / (8000 * clockdiv);
- if (exposure > 511)
- exposure = 511;
-
- /* exposure register value is reversed! */
- exposure = 511 - exposure;
-
- buf[0] = exposure & 0xff;
- buf[1] = exposure >> 8;
- sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2);
- sensor_write1(gspca_dev, 0x02, clockdiv);
- }
-}
-
-static void setgain(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 gainreg;
-
- if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1)
- sensor_write1(gspca_dev, 0x0e, val);
- else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2)
- for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) {
- sensor_write1(gspca_dev, gainreg, val >> 8);
- sensor_write1(gspca_dev, gainreg + 1, val & 0xff);
- }
- else
- sensor_write1(gspca_dev, 0x10, val);
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
-{
- sensor_write1(gspca_dev, 0x1c, val);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_EXPOSURE:
- setexposure(gspca_dev, sd->exposure->val,
- sd->min_clockdiv ? sd->min_clockdiv->val : 0);
- break;
- case V4L2_CID_GAIN:
- setgain(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
- static const struct v4l2_ctrl_config clockdiv = {
- .ops = &sd_ctrl_ops,
- .id = MR97310A_CID_CLOCKDIV,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Minimum Clock Divider",
- .min = MR97310A_MIN_CLOCKDIV_MIN,
- .max = MR97310A_MIN_CLOCKDIV_MAX,
- .step = 1,
- .def = MR97310A_MIN_CLOCKDIV_DEFAULT,
- };
- bool has_brightness = false;
- bool has_argus_brightness = false;
- bool has_contrast = false;
- bool has_gain = false;
- bool has_cs_gain = false;
- bool has_exposure = false;
- bool has_clockdiv = false;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 4);
-
- /* Setup controls depending on camera type */
- if (sd->cam_type == CAM_TYPE_CIF) {
- /* No brightness for sensor_type 0 */
- if (sd->sensor_type == 0)
- has_exposure = has_gain = has_clockdiv = true;
- else
- has_exposure = has_gain = has_brightness = true;
- } else {
- /* All controls need to be disabled if VGA sensor_type is 0 */
- if (sd->sensor_type == 0)
- ; /* no controls! */
- else if (sd->sensor_type == 2)
- has_exposure = has_cs_gain = has_contrast = true;
- else if (sd->do_lcd_stop)
- has_exposure = has_gain = has_argus_brightness =
- has_clockdiv = true;
- else
- has_exposure = has_gain = has_brightness =
- has_clockdiv = true;
- }
-
- /* Separate brightness control description for Argus QuickClix as it has
- * different limits from the other mr97310a cameras, and separate gain
- * control for Sakar CyberPix camera. */
- /*
- * This control is disabled for CIF type 1 and VGA type 0 cameras.
- * It does not quite act linearly for the Argus QuickClix camera,
- * but it does control brightness. The values are 0 - 15 only, and
- * the table above makes them act consecutively.
- */
- if (has_brightness)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, -254, 255, 1,
- MR97310A_BRIGHTNESS_DEFAULT);
- else if (has_argus_brightness)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 15, 1,
- MR97310A_BRIGHTNESS_DEFAULT);
- if (has_contrast)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, MR97310A_CONTRAST_MIN,
- MR97310A_CONTRAST_MAX, 1, MR97310A_CONTRAST_DEFAULT);
- if (has_gain)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, MR97310A_GAIN_MIN, MR97310A_GAIN_MAX,
- 1, MR97310A_GAIN_DEFAULT);
- else if (has_cs_gain)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAIN,
- MR97310A_CS_GAIN_MIN, MR97310A_CS_GAIN_MAX,
- 1, MR97310A_CS_GAIN_DEFAULT);
- if (has_exposure)
- sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, MR97310A_EXPOSURE_MIN,
- MR97310A_EXPOSURE_MAX, 1, MR97310A_EXPOSURE_DEFAULT);
- if (has_clockdiv)
- sd->min_clockdiv = v4l2_ctrl_new_custom(hdl, &clockdiv, NULL);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- if (has_exposure && has_clockdiv)
- v4l2_ctrl_cluster(2, &sd->exposure);
- return 0;
-}
-
-/* Include pac common sof detection functions */
-#include "pac_common.h"
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
- unsigned char *sof;
-
- sof = pac_find_sof(&sd->sof_read, data, len);
- if (sof) {
- int n;
-
- /* finish decoding current frame */
- n = sof - data;
- if (n > sizeof pac_sof_marker)
- n -= sizeof pac_sof_marker;
- else
- n = 0;
- gspca_frame_add(gspca_dev, LAST_PACKET,
- data, n);
- /* Start next frame. */
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- pac_sof_marker, sizeof pac_sof_marker);
- len -= sof - data;
- data = sof;
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x08ca, 0x0110)}, /* Trust Spyc@m 100 */
- {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
- {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */
- {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/nw80x.c b/drivers/media/video/gspca/nw80x.c
deleted file mode 100644
index 44c9964b1b3..00000000000
--- a/drivers/media/video/gspca/nw80x.c
+++ /dev/null
@@ -1,2110 +0,0 @@
-/*
- * DivIO nw80x subdriver
- *
- * Copyright (C) 2011 Jean-François Moine (http://moinejf.free.fr)
- * Copyright (C) 2003 Sylvain Munaut <tnt@246tNt.com>
- * Kjell Claesson <keyson@users.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "nw80x"
-
-#include "gspca.h"
-
-MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
-MODULE_DESCRIPTION("NW80x USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-static int webcam;
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- u32 ae_res;
- s8 ag_cnt;
-#define AG_CNT_START 13
- u8 exp_too_low_cnt;
- u8 exp_too_high_cnt;
-
- u8 bridge;
- u8 webcam;
-};
-
-enum bridges {
- BRIDGE_NW800, /* and et31x110 */
- BRIDGE_NW801,
- BRIDGE_NW802,
-};
-enum webcams {
- Generic800,
- SpaceCam, /* Trust 120 SpaceCam */
- SpaceCam2, /* other Trust 120 SpaceCam */
- Cvideopro, /* Conceptronic Video Pro */
- Dlink350c,
- DS3303u,
- Kr651us,
- Kritter,
- Mustek300,
- Proscope,
- Twinkle,
- DvcV6,
- P35u,
- Generic802,
- NWEBCAMS /* number of webcams */
-};
-
-static const u8 webcam_chip[NWEBCAMS] = {
- [Generic800] = BRIDGE_NW800, /* 06a5:0000
- * Typhoon Webcam 100 USB */
-
- [SpaceCam] = BRIDGE_NW800, /* 06a5:d800
- * Trust SpaceCam120 or SpaceCam100 PORTABLE */
-
- [SpaceCam2] = BRIDGE_NW800, /* 06a5:d800 - pas106
- * other Trust SpaceCam120 or SpaceCam100 PORTABLE */
-
- [Cvideopro] = BRIDGE_NW802, /* 06a5:d001
- * Conceptronic Video Pro 'CVIDEOPRO USB Webcam CCD' */
-
- [Dlink350c] = BRIDGE_NW802, /* 06a5:d001
- * D-Link NetQam Pro 250plus */
-
- [DS3303u] = BRIDGE_NW801, /* 06a5:d001
- * Plustek Opticam 500U or ProLink DS3303u */
-
- [Kr651us] = BRIDGE_NW802, /* 06a5:d001
- * Panasonic GP-KR651US */
-
- [Kritter] = BRIDGE_NW802, /* 06a5:d001
- * iRez Kritter cam */
-
- [Mustek300] = BRIDGE_NW802, /* 055f:d001
- * Mustek Wcam 300 mini */
-
- [Proscope] = BRIDGE_NW802, /* 06a5:d001
- * Scalar USB Microscope (ProScope) */
-
- [Twinkle] = BRIDGE_NW800, /* 06a5:d800 - hv7121b? (seems pas106)
- * Divio Chicony TwinkleCam
- * DSB-C110 */
-
- [DvcV6] = BRIDGE_NW802, /* 0502:d001
- * DVC V6 */
-
- [P35u] = BRIDGE_NW801, /* 052b:d001, 06a5:d001 and 06be:d001
- * EZCam Pro p35u */
-
- [Generic802] = BRIDGE_NW802,
-};
-/*
- * other webcams:
- * - nw801 046d:d001
- * Logitech QuickCam Pro (dark focus ring)
- * - nw801 0728:d001
- * AVerMedia Camguard
- * - nw??? 06a5:d001
- * D-Link NetQam Pro 250plus
- * - nw800 065a:d800
- * Showcam NGS webcam
- * - nw??? ????:????
- * Sceptre svc300
- */
-
-/*
- * registers
- * nw800/et31x110 nw801 nw802
- * 0000..009e 0000..00a1 0000..009e
- * 0200..0211 id id
- * 0300..0302 id id
- * 0400..0406 (inex) 0400..0406
- * 0500..0505 0500..0506 (inex)
- * 0600..061a 0600..0601 0600..0601
- * 0800..0814 id id
- * 1000..109c 1000..10a1 1000..109a
- */
-
-/* resolutions
- * nw800: 320x240, 352x288
- * nw801/802: 320x240, 640x480
- */
-static const struct v4l2_pix_format cif_mode[] = {
- {320, 240, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 4 / 8,
- .colorspace = V4L2_COLORSPACE_JPEG},
- {352, 288, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 4 / 8,
- .colorspace = V4L2_COLORSPACE_JPEG}
-};
-static const struct v4l2_pix_format vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 4 / 8,
- .colorspace = V4L2_COLORSPACE_JPEG},
- {640, 480, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8,
- .colorspace = V4L2_COLORSPACE_JPEG},
-};
-
-/*
- * The sequences below contain:
- * - 1st and 2nd bytes: either
- * - register number (BE)
- * - I2C0 + i2c address
- * - 3rd byte: data length (=0 for end of sequence)
- * - n bytes: data
- */
-#define I2C0 0xff
-
-static const u8 nw800_init[] = {
- 0x04, 0x05, 0x01, 0x61,
- 0x04, 0x04, 0x01, 0x01,
- 0x04, 0x06, 0x01, 0x04,
- 0x04, 0x04, 0x03, 0x00, 0x00, 0x00,
- 0x05, 0x05, 0x01, 0x00,
- 0, 0, 0
-};
-static const u8 nw800_start[] = {
- 0x04, 0x06, 0x01, 0xc0,
- 0x00, 0x00, 0x40, 0x10, 0x43, 0x00, 0xb4, 0x01, 0x10, 0x00, 0x4f,
- 0xef, 0x0e, 0x00, 0x74, 0x01, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x3e, 0x00, 0x24,
- 0x03, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
- 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
- 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
- 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
- 0x00, 0x80, 0x1f, 0xa0, 0x48, 0xc3, 0x02, 0x88, 0x0c, 0x68, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xa8, 0x06, 0x00, 0x08,
- 0x00, 0x32, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
- 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00,
- 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
- 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0xc0,
- 0x05, 0x00, 0x06, 0xe8, 0x00, 0x00, 0x00, 0x20, 0x20,
- 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0x83, 0x02, 0x20, 0x00, 0x13, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
- 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
- 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
- 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
- 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
- 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
- 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x62,
- 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
- 0x01, 0x60, 0x01, 0x00, 0x00,
-
- 0x04, 0x04, 0x01, 0xff,
- 0x04, 0x06, 0x01, 0xc4,
-
- 0x04, 0x06, 0x01, 0xc0,
- 0x00, 0x00, 0x40, 0x10, 0x43, 0x00, 0xb4, 0x01, 0x10, 0x00, 0x4f,
- 0xef, 0x0e, 0x00, 0x74, 0x01, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x3e, 0x00, 0x24,
- 0x03, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
- 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
- 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
- 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
- 0x00, 0x80, 0x1f, 0xa0, 0x48, 0xc3, 0x02, 0x88, 0x0c, 0x68, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xa8, 0x06, 0x00, 0x08,
- 0x00, 0x32, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
- 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00,
- 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
- 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0xc0,
- 0x05, 0x00, 0x06, 0xe8, 0x00, 0x00, 0x00, 0x20, 0x20,
- 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0x83, 0x02, 0x20, 0x00, 0x13, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
- 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
- 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
- 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
- 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
- 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
- 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x62,
- 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
- 0x01, 0x60, 0x01, 0x00, 0x00,
-
- 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00,
- 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65,
- 0x40,
- 0x00, 0x80, 0x01, 0xa0,
- 0x10, 0x1a, 0x01, 0x00,
- 0x00, 0x91, 0x02, 0x6c, 0x01,
- 0x00, 0x03, 0x02, 0xc8, 0x01,
- 0x10, 0x1a, 0x01, 0x00,
- 0x10, 0x00, 0x01, 0x83,
- 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01,
- 0x20, 0x01, 0x60, 0x01,
- 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
- 0x10, 0x1b, 0x02, 0x69, 0x00,
- 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
- 0x05, 0x02, 0x01, 0x02,
- 0x06, 0x00, 0x02, 0x04, 0xd9,
- 0x05, 0x05, 0x01, 0x20,
- 0x05, 0x05, 0x01, 0x21,
- 0x10, 0x0e, 0x01, 0x08,
- 0x10, 0x41, 0x11, 0x00, 0x08, 0x21, 0x3d, 0x52, 0x63, 0x75, 0x83,
- 0x91, 0x9e, 0xaa, 0xb6, 0xc1, 0xcc, 0xd6, 0xe0,
- 0xea,
- 0x10, 0x03, 0x01, 0x00,
- 0x10, 0x0f, 0x02, 0x13, 0x13,
- 0x10, 0x03, 0x01, 0x14,
- 0x10, 0x41, 0x11, 0x00, 0x08, 0x21, 0x3d, 0x52, 0x63, 0x75, 0x83,
- 0x91, 0x9e, 0xaa, 0xb6, 0xc1, 0xcc, 0xd6, 0xe0,
- 0xea,
- 0x10, 0x0b, 0x01, 0x14,
- 0x10, 0x0d, 0x01, 0x20,
- 0x10, 0x0c, 0x01, 0x34,
- 0x04, 0x06, 0x01, 0xc3,
- 0x04, 0x04, 0x01, 0x00,
- 0x05, 0x02, 0x01, 0x02,
- 0x06, 0x00, 0x02, 0x00, 0x48,
- 0x05, 0x05, 0x01, 0x20,
- 0x05, 0x05, 0x01, 0x21,
- 0, 0, 0
-};
-
-/* 06a5:d001 - nw801 - Panasonic
- * P35u */
-static const u8 nw801_start_1[] = {
- 0x05, 0x06, 0x01, 0x04,
- 0x00, 0x00, 0x40, 0x0e, 0x00, 0x00, 0xf9, 0x02, 0x11, 0x00, 0x0e,
- 0x01, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
- 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
- 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
- 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
- 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
- 0x00, 0x80, 0x22, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x69, 0xa8, 0x1f, 0x00,
- 0x0d, 0x02, 0x07, 0x00, 0x01, 0x00, 0x19, 0x00,
- 0xf2, 0x00, 0x18, 0x06, 0x10, 0x06, 0x10, 0x00,
- 0x36, 0x00,
- 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x06, 0x00, 0x02, 0x09, 0x99,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0x22, 0x02, 0x80, 0x00, 0x1e, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x15, 0x08, 0x08, 0x0a,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x35, 0xfd, 0x07, 0x3d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x02,
- 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
- 0x40, 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x06,
- 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, 0xf7,
- 0x10, 0x40, 0x40, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, 0x80,
- 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, 0xa4,
- 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, 0xcf,
- 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, 0x64,
- 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, 0xe2,
- 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x10, 0x80, 0x22, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x82, 0x02,
- 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, 0x01,
- 0xf0, 0x00,
- 0, 0, 0,
-};
-static const u8 nw801_start_qvga[] = {
- 0x02, 0x00, 0x10, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
- 0x00, 0x78, 0x18, 0x0b, 0x06, 0xa2, 0x86, 0x78,
- 0x02, 0x0f, 0x01, 0x6b,
- 0x10, 0x1a, 0x01, 0x15,
- 0x00, 0x00, 0x01, 0x1e,
- 0x10, 0x00, 0x01, 0x2f,
- 0x10, 0x8c, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
- 0x10, 0x11, 0x08, 0x29, 0x00, 0x18, 0x01, 0x1f, 0x00, 0xd2, 0x00,
- /* AE window */
- 0, 0, 0,
-};
-static const u8 nw801_start_vga[] = {
- 0x02, 0x00, 0x10, 0x78, 0xa0, 0x97, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xf0,
- 0x02, 0x0f, 0x01, 0xd5,
- 0x10, 0x1a, 0x01, 0x15,
- 0x00, 0x00, 0x01, 0x0e,
- 0x10, 0x00, 0x01, 0x22,
- 0x10, 0x8c, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01,
- 0x10, 0x11, 0x08, 0x51, 0x00, 0x30, 0x02, 0x3d, 0x00, 0xa4, 0x01,
- 0, 0, 0,
-};
-static const u8 nw801_start_2[] = {
- 0x10, 0x04, 0x01, 0x1a,
- 0x10, 0x19, 0x01, 0x09, /* clock */
- 0x10, 0x24, 0x06, 0xc0, 0x00, 0x3f, 0x02, 0x00, 0x01,
- /* .. gain .. */
- 0x00, 0x03, 0x02, 0x92, 0x03,
- 0x00, 0x1d, 0x04, 0xf2, 0x00, 0x24, 0x07,
- 0x00, 0x7b, 0x01, 0xcf,
- 0x10, 0x94, 0x01, 0x07,
- 0x05, 0x05, 0x01, 0x01,
- 0x05, 0x04, 0x01, 0x01,
- 0x10, 0x0e, 0x01, 0x08,
- 0x10, 0x48, 0x11, 0x00, 0x37, 0x55, 0x6b, 0x7d, 0x8d, 0x9b, 0xa8,
- 0xb4, 0xbf, 0xca, 0xd4, 0xdd, 0xe6, 0xef, 0xf0,
- 0xf0,
- 0x10, 0x03, 0x01, 0x00,
- 0x10, 0x0f, 0x02, 0x0c, 0x0c,
- 0x10, 0x03, 0x01, 0x08,
- 0x10, 0x48, 0x11, 0x00, 0x37, 0x55, 0x6b, 0x7d, 0x8d, 0x9b, 0xa8,
- 0xb4, 0xbf, 0xca, 0xd4, 0xdd, 0xe6, 0xef, 0xf0,
- 0xf0,
- 0x10, 0x0b, 0x01, 0x0b,
- 0x10, 0x0d, 0x01, 0x0b,
- 0x10, 0x0c, 0x01, 0x1f,
- 0x05, 0x06, 0x01, 0x03,
- 0, 0, 0
-};
-
-/* nw802 (sharp IR3Y38M?) */
-static const u8 nw802_start[] = {
- 0x04, 0x06, 0x01, 0x04,
- 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0xf9, 0x02, 0x10, 0x00, 0x4d,
- 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
- 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
- 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
- 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
- 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
- 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x68, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
- 0x00, 0x0c, 0x02, 0x01, 0x00, 0x16, 0x00, 0x94,
- 0x00, 0x10, 0x06, 0x08, 0x00, 0x18, 0x00,
- 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
- 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
- 0x06, 0x00, 0x02, 0x09, 0x99,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0xa1, 0x02, 0x80, 0x00, 0x1d, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x49, 0x13, 0xff, 0x01, 0xc0, 0x00, 0x14,
- 0x02, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
- 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
- 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
- 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
- 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
- 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
- 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x05, 0x82,
- 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
- 0x01, 0xf0, 0x00,
- 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
- 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
- 0x40,
- 0x10, 0x1a, 0x01, 0x00,
- 0x10, 0x00, 0x01, 0xad,
- 0x00, 0x00, 0x01, 0x08,
- 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
- 0x10, 0x1b, 0x02, 0x00, 0x00,
- 0x10, 0x11, 0x08, 0x51, 0x00, 0xf0, 0x00, 0x3d, 0x00, 0xb4, 0x00,
- 0x10, 0x1d, 0x08, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
- 0x10, 0x0e, 0x01, 0x27,
- 0x10, 0x41, 0x11, 0x00, 0x0e, 0x35, 0x4f, 0x62, 0x71, 0x7f, 0x8b,
- 0x96, 0xa0, 0xa9, 0xb2, 0xbb, 0xc3, 0xca, 0xd2,
- 0xd8,
- 0x10, 0x03, 0x01, 0x00,
- 0x10, 0x0f, 0x02, 0x14, 0x14,
- 0x10, 0x03, 0x01, 0x0c,
- 0x10, 0x41, 0x11, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, 0x64, 0x74,
- 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, 0xe2, 0xf1,
- 0xff,
-/* 0x00, 0x0e, 0x35, 0x4f, 0x62, 0x71, 0x7f, 0x8b,
- * 0x96, 0xa0, 0xa9, 0xb2, 0xbb, 0xc3, 0xca, 0xd2,
- * 0xd8, */
- 0x10, 0x0b, 0x01, 0x10,
- 0x10, 0x0d, 0x01, 0x11,
- 0x10, 0x0c, 0x01, 0x1c,
- 0x04, 0x06, 0x01, 0x03,
- 0x04, 0x04, 0x01, 0x00,
- 0, 0, 0
-};
-/* et31x110 - Trust 120 SpaceCam */
-static const u8 spacecam_init[] = {
- 0x04, 0x05, 0x01, 0x01,
- 0x04, 0x04, 0x01, 0x01,
- 0x04, 0x06, 0x01, 0x04,
- 0x04, 0x04, 0x03, 0x00, 0x00, 0x00,
- 0x05, 0x05, 0x01, 0x00,
- 0, 0, 0
-};
-static const u8 spacecam_start[] = {
- 0x04, 0x06, 0x01, 0x44,
- 0x00, 0x00, 0x40, 0x10, 0x43, 0x00, 0xb4, 0x01, 0x10, 0x00, 0x4f,
- 0xef, 0x0e, 0x00, 0x74, 0x01, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x3e, 0x00, 0x24,
- 0x03, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
- 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
- 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
- 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
- 0x00, 0x80, 0x1f, 0xa0, 0x48, 0xc3, 0x02, 0x88, 0x0c, 0x68, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xa8, 0x06, 0x00, 0x08,
- 0x00, 0x32, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
- 0x00, 0x4b, 0x00, 0x7c, 0x00, 0x80, 0x00,
- 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
- 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0x83, 0x02, 0x20, 0x00, 0x11, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
- 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
- 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
- 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
- 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
- 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
- 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x62,
- 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
- 0x01, 0x60, 0x01, 0x00, 0x00,
- 0x04, 0x06, 0x01, 0xc0,
- 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
- 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00,
- 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65,
- 0x40,
- 0x00, 0x80, 0x01, 0xa0,
- 0x10, 0x1a, 0x01, 0x00,
- 0x00, 0x91, 0x02, 0x32, 0x01,
- 0x00, 0x03, 0x02, 0x08, 0x02,
- 0x10, 0x00, 0x01, 0x83,
- 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01,
- 0x20, 0x01, 0x60, 0x01,
- 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
- 0x10, 0x0e, 0x01, 0x08,
- 0x10, 0x41, 0x11, 0x00, 0x64, 0x99, 0xc0, 0xe2, 0xf9, 0xf9, 0xf9,
- 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
- 0xf9,
- 0x10, 0x03, 0x01, 0x00,
- 0x10, 0x0f, 0x02, 0x13, 0x13,
- 0x10, 0x03, 0x01, 0x06,
- 0x10, 0x41, 0x11, 0x00, 0x64, 0x99, 0xc0, 0xe2, 0xf9, 0xf9, 0xf9,
- 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
- 0xf9,
- 0x10, 0x0b, 0x01, 0x08,
- 0x10, 0x0d, 0x01, 0x10,
- 0x10, 0x0c, 0x01, 0x1f,
- 0x04, 0x06, 0x01, 0xc3,
- 0x04, 0x05, 0x01, 0x40,
- 0x04, 0x04, 0x01, 0x40,
- 0, 0, 0
-};
-/* et31x110 - pas106 - other Trust SpaceCam120 */
-static const u8 spacecam2_start[] = {
- 0x04, 0x06, 0x01, 0x44,
- 0x04, 0x06, 0x01, 0x00,
- 0x00, 0x00, 0x40, 0x14, 0x83, 0x00, 0xba, 0x01, 0x10, 0x00, 0x4f,
- 0xef, 0x00, 0x00, 0x60, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x06, 0x00, 0xfc,
- 0x01, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
- 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
- 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
- 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
- 0x00, 0x80, 0x1f, 0xb8, 0x48, 0x0f, 0x04, 0x88, 0x14, 0x68, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x03,
- 0x00, 0x24, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
- 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00,
- 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
- 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0x00,
- 0x05, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0x80, 0x02, 0x20, 0x00, 0x13, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
- 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
- 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
- 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
- 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
- 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
- 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62,
- 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
- 0x01, 0x60, 0x01, 0x00, 0x00,
- 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
- 0x04, 0x04, 0x01, 0x40,
- 0x04, 0x04, 0x01, 0x00,
- I2C0, 0x40, 0x0c, 0x02, 0x0c, 0x12, 0x07, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x05, 0x05,
- I2C0, 0x40, 0x02, 0x11, 0x06,
- I2C0, 0x40, 0x02, 0x14, 0x00,
- I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */
- 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00,
- 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65,
- 0x40,
- I2C0, 0x40, 0x02, 0x02, 0x0c, /* pixel clock */
- I2C0, 0x40, 0x02, 0x0f, 0x00,
- I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */
- 0x10, 0x00, 0x01, 0x01,
- 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01,
- 0x20, 0x01, 0x60, 0x01,
- I2C0, 0x40, 0x02, 0x05, 0x0f, /* exposure */
- I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */
- I2C0, 0x40, 0x07, 0x09, 0x0b, 0x0f, 0x05, 0x05, 0x0f, 0x00,
- /* gains */
- I2C0, 0x40, 0x03, 0x12, 0x04, 0x01,
- 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
- 0x10, 0x0e, 0x01, 0x08,
- 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7,
- 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7,
- 0xf9,
- 0x10, 0x03, 0x01, 0x00,
- 0x10, 0x0f, 0x02, 0x13, 0x13,
- 0x10, 0x03, 0x01, 0x06,
- 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7,
- 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7,
- 0xf9,
- 0x10, 0x0b, 0x01, 0x11,
- 0x10, 0x0d, 0x01, 0x10,
- 0x10, 0x0c, 0x01, 0x14,
- 0x04, 0x06, 0x01, 0x03,
- 0x04, 0x05, 0x01, 0x61,
- 0x04, 0x04, 0x01, 0x00,
- 0, 0, 0
-};
-
-/* nw802 - Conceptronic Video Pro */
-static const u8 cvideopro_start[] = {
- 0x04, 0x06, 0x01, 0x04,
- 0x00, 0x00, 0x40, 0x54, 0x96, 0x98, 0xf9, 0x02, 0x18, 0x00, 0x4c,
- 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x0b, 0x00, 0x1b, 0x00, 0xc8, 0x00, 0xf4,
- 0x05, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54,
- 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6,
- 0x00, 0x5d, 0x00, 0xc7, 0x00, 0x7e, 0x00, 0x30,
- 0x00, 0x80, 0x1f, 0x98, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f,
- 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
- 0x00, 0x0c, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94,
- 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00,
- 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
- 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x06, 0x00, 0x02, 0x09, 0x99,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c,
- 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
- 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
- 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
- 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
- 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
- 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
- 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x82,
- 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
- 0x01, 0xf0, 0x00,
- 0x02, 0x00, 0x11, 0x3c, 0x50, 0x8c, 0x3c, 0x50, 0x00, 0x00, 0x00,
- 0x00, 0x78, 0x3f, 0x3f, 0x06, 0xf2, 0x8f, 0xf0,
- 0x40,
- 0x10, 0x1a, 0x01, 0x03,
- 0x10, 0x00, 0x01, 0xac,
- 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
- 0x10, 0x1b, 0x02, 0x3b, 0x01,
- 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00,
- 0x10, 0x1f, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
- 0x10, 0x1d, 0x02, 0x40, 0x06,
- 0x10, 0x0e, 0x01, 0x08,
- 0x10, 0x41, 0x11, 0x00, 0x0f, 0x46, 0x62, 0x76, 0x86, 0x94, 0xa0,
- 0xab, 0xb6, 0xbf, 0xc8, 0xcf, 0xd7, 0xdc, 0xdc,
- 0xdc,
- 0x10, 0x03, 0x01, 0x00,
- 0x10, 0x0f, 0x02, 0x12, 0x12,
- 0x10, 0x03, 0x01, 0x0c,
- 0x10, 0x41, 0x11, 0x00, 0x0f, 0x46, 0x62, 0x76, 0x86, 0x94, 0xa0,
- 0xab, 0xb6, 0xbf, 0xc8, 0xcf, 0xd7, 0xdc, 0xdc,
- 0xdc,
- 0x10, 0x0b, 0x01, 0x09,
- 0x10, 0x0d, 0x01, 0x10,
- 0x10, 0x0c, 0x01, 0x2f,
- 0x04, 0x06, 0x01, 0x03,
- 0x04, 0x04, 0x01, 0x00,
- 0, 0, 0
-};
-
-/* nw802 - D-link dru-350c cam */
-static const u8 dlink_start[] = {
- 0x04, 0x06, 0x01, 0x04,
- 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x92, 0x03, 0x10, 0x00, 0x4d,
- 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
- 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
- 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
- 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
- 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
- 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x68, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
- 0x00, 0x0c, 0x02, 0x01, 0x00, 0x16, 0x00, 0x94,
- 0x00, 0x10, 0x06, 0x10, 0x00, 0x36, 0x00,
- 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
- 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
- 0x06, 0x00, 0x02, 0x09, 0x99,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0xa1, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x49, 0x13, 0x00, 0x00, 0xc0, 0x00, 0x14,
- 0x02, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
- 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
- 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
- 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
- 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
- 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
- 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x01, 0x82,
- 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
- 0x01, 0xf0, 0x00,
- 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
- 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
- 0x40,
- 0x10, 0x1a, 0x01, 0x00,
- 0x10, 0x00, 0x01, 0xad,
- 0x00, 0x00, 0x01, 0x08,
- 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
- 0x10, 0x1b, 0x02, 0x00, 0x00,
- 0x10, 0x11, 0x08, 0x51, 0x00, 0xf0, 0x00, 0x3d, 0x00, 0xb4, 0x00,
- 0x10, 0x1d, 0x08, 0x40, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
- 0x10, 0x0e, 0x01, 0x20,
- 0x10, 0x41, 0x11, 0x00, 0x07, 0x1e, 0x38, 0x4d, 0x60, 0x70, 0x7f,
- 0x8e, 0x9b, 0xa8, 0xb4, 0xbf, 0xca, 0xd5, 0xdf,
- 0xea,
- 0x10, 0x03, 0x01, 0x00,
- 0x10, 0x0f, 0x02, 0x11, 0x11,
- 0x10, 0x03, 0x01, 0x10,
- 0x10, 0x41, 0x11, 0x00, 0x07, 0x1e, 0x38, 0x4d, 0x60, 0x70, 0x7f,
- 0x8e, 0x9b, 0xa8, 0xb4, 0xbf, 0xca, 0xd5, 0xdf,
- 0xea,
- 0x10, 0x0b, 0x01, 0x19,
- 0x10, 0x0d, 0x01, 0x10,
- 0x10, 0x0c, 0x01, 0x1e,
- 0x04, 0x06, 0x01, 0x03,
- 0x04, 0x04, 0x01, 0x00,
- 0, 0, 0
-};
-
-/* 06a5:d001 - nw801 - Sony
- * Plustek Opticam 500U or ProLink DS3303u (Hitachi HD49322BF) */
-/*fixme: 320x240 only*/
-static const u8 ds3303_start[] = {
- 0x05, 0x06, 0x01, 0x04,
- 0x00, 0x00, 0x40, 0x16, 0x00, 0x00, 0xf9, 0x02, 0x11, 0x00, 0x0e,
- 0x01, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
- 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
- 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
- 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
- 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
- 0x00, 0x80, 0x22, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xa9, 0xa8, 0x1f, 0x00,
- 0x0d, 0x02, 0x07, 0x00, 0x01, 0x00, 0x19, 0x00,
- 0xf2, 0x00, 0x18, 0x06, 0x10, 0x06, 0x10, 0x00,
- 0x36, 0x00,
- 0x02, 0x00, 0x12, 0x03, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0x50,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
- 0x05, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x06, 0x00, 0x02, 0x09, 0x99,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0x2f, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x1f, 0x10, 0x08, 0x0a,
- 0x0a, 0x51, 0x00, 0xf1, 0x00, 0x3c, 0x00, 0xb4,
- 0x00, 0x01, 0x15, 0xfd, 0x07, 0x3d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x8c, 0x04, 0x01, 0x20,
- 0x02, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x03,
- 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, 0xf7,
- 0x10, 0x40, 0x40, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, 0x80,
- 0x00, 0x2d, 0x46, 0x58, 0x67, 0x74, 0x7f, 0x88,
- 0x94, 0x9d, 0xa6, 0xae, 0xb5, 0xbd, 0xc4, 0xcb,
- 0xd1, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, 0x64,
- 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, 0xe2,
- 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x10, 0x80, 0x22, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x3f, 0x01,
- 0x00, 0x00, 0xef, 0x00, 0x02, 0x0a, 0x82, 0x02,
- 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, 0x01,
- 0xf0, 0x00,
-
- 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
- 0x00, 0x78, 0x3f, 0x3f, 0x00, 0xf2, 0x8f, 0x81,
- 0x40,
- 0x10, 0x1a, 0x01, 0x15,
- 0x10, 0x00, 0x01, 0x2f,
- 0x10, 0x8c, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
- 0x10, 0x1b, 0x02, 0x00, 0x00,
- 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00,
- 0x10, 0x26, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
- 0x10, 0x24, 0x02, 0x40, 0x06,
- 0x10, 0x0e, 0x01, 0x08,
- 0x10, 0x48, 0x11, 0x00, 0x15, 0x40, 0x67, 0x84, 0x9d, 0xb2, 0xc6,
- 0xd6, 0xe7, 0xf6, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
- 0xf9,
- 0x10, 0x03, 0x01, 0x00,
- 0x10, 0x0f, 0x02, 0x16, 0x16,
- 0x10, 0x03, 0x01, 0x0c,
- 0x10, 0x48, 0x11, 0x00, 0x15, 0x40, 0x67, 0x84, 0x9d, 0xb2, 0xc6,
- 0xd6, 0xe7, 0xf6, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
- 0xf9,
- 0x10, 0x0b, 0x01, 0x26,
- 0x10, 0x0d, 0x01, 0x10,
- 0x10, 0x0c, 0x01, 0x1c,
- 0x05, 0x06, 0x01, 0x03,
- 0x05, 0x04, 0x01, 0x00,
- 0, 0, 0
-};
-
-/* 06a5:d001 - nw802 - Panasonic
- * GP-KR651US (Philips TDA8786) */
-static const u8 kr651_start_1[] = {
- 0x04, 0x06, 0x01, 0x04,
- 0x00, 0x00, 0x40, 0x44, 0x96, 0x98, 0xf9, 0x02, 0x18, 0x00, 0x48,
- 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x0b, 0x00, 0x1b, 0x00, 0xc8, 0x00, 0xf4,
- 0x05, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54,
- 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6,
- 0x00, 0x5d, 0x00, 0xc7, 0x00, 0x7e, 0x00, 0x30,
- 0x00, 0x80, 0x1f, 0x18, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f,
- 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
- 0x00, 0x0c, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94,
- 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00,
- 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x02, 0x00, 0x00,
- 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
- 0x06, 0x00, 0x02, 0x09, 0x99,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c,
- 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
- 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
- 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
- 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
- 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
- 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
- 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x82,
- 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
- 0x01, 0xf0, 0x00,
- 0, 0, 0
-};
-static const u8 kr651_start_qvga[] = {
- 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
- 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
- 0x40,
- 0x10, 0x1a, 0x01, 0x03,
- 0x10, 0x00, 0x01, 0xac,
- 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
- 0x10, 0x1b, 0x02, 0x00, 0x00,
- 0x10, 0x11, 0x08, 0x29, 0x00, 0x18, 0x01, 0x1f, 0x00, 0xd2, 0x00,
- 0x10, 0x1d, 0x06, 0xe0, 0x00, 0x0c, 0x00, 0x52, 0x00,
- 0x10, 0x1d, 0x02, 0x28, 0x01,
- 0, 0, 0
-};
-static const u8 kr651_start_vga[] = {
- 0x02, 0x00, 0x11, 0x78, 0xa0, 0x8c, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x30, 0x03, 0x01, 0x82, 0x82, 0x98,
- 0x80,
- 0x10, 0x1a, 0x01, 0x03,
- 0x10, 0x00, 0x01, 0xa0,
- 0x10, 0x85, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01,
- 0x10, 0x1b, 0x02, 0x00, 0x00,
- 0x10, 0x11, 0x08, 0x51, 0x00, 0x30, 0x02, 0x3d, 0x00, 0xa4, 0x01,
- 0x10, 0x1d, 0x06, 0xe0, 0x00, 0x0c, 0x00, 0x52, 0x00,
- 0x10, 0x1d, 0x02, 0x68, 0x00,
-};
-static const u8 kr651_start_2[] = {
- 0x10, 0x0e, 0x01, 0x08,
- 0x10, 0x41, 0x11, 0x00, 0x11, 0x3c, 0x5c, 0x74, 0x88, 0x99, 0xa8,
- 0xb7, 0xc4, 0xd0, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc,
- 0xdc,
- 0x10, 0x03, 0x01, 0x00,
- 0x10, 0x0f, 0x02, 0x0c, 0x0c,
- 0x10, 0x03, 0x01, 0x0c,
- 0x10, 0x41, 0x11, 0x00, 0x11, 0x3c, 0x5c, 0x74, 0x88, 0x99, 0xa8,
- 0xb7, 0xc4, 0xd0, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc,
- 0xdc,
- 0x10, 0x0b, 0x01, 0x10,
- 0x10, 0x0d, 0x01, 0x10,
- 0x10, 0x0c, 0x01, 0x2d,
- 0x04, 0x06, 0x01, 0x03,
- 0x04, 0x04, 0x01, 0x00,
- 0, 0, 0
-};
-
-/* nw802 - iRez Kritter cam */
-static const u8 kritter_start[] = {
- 0x04, 0x06, 0x01, 0x06,
- 0x00, 0x00, 0x40, 0x44, 0x96, 0x98, 0x94, 0x03, 0x18, 0x00, 0x48,
- 0x0f, 0x1e, 0x00, 0x0c, 0x02, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x0b, 0x00, 0x1b, 0x00, 0x0a, 0x01, 0x28,
- 0x07, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54,
- 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6,
- 0x00, 0x5d, 0x00, 0x0e, 0x00, 0x7e, 0x00, 0x30,
- 0x00, 0x80, 0x1f, 0x18, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f,
- 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
- 0x00, 0x0b, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94,
- 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00,
- 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x02, 0x00, 0x00,
- 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x06, 0x00, 0x02, 0x09, 0x99,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c,
- 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
- 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
- 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
- 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
- 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
- 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
- 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x82,
- 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
- 0x01, 0xf0, 0x00,
- 0x02, 0x00, 0x11, 0x3c, 0x50, 0x8c, 0x3c, 0x50, 0x00, 0x00, 0x00,
- 0x00, 0x78, 0x3f, 0x3f, 0x06, 0xf2, 0x8f, 0xf0,
- 0x40,
- 0x10, 0x1a, 0x01, 0x03,
- 0x10, 0x00, 0x01, 0xaf,
- 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
- 0x10, 0x1b, 0x02, 0x3b, 0x01,
- 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00,
- 0x10, 0x1d, 0x06, 0xe0, 0x00, 0x0c, 0x00, 0x52, 0x00,
- 0x10, 0x1d, 0x02, 0x00, 0x00,
- 0x10, 0x0e, 0x01, 0x08,
- 0x10, 0x41, 0x11, 0x00, 0x0d, 0x36, 0x4e, 0x60, 0x6f, 0x7b, 0x86,
- 0x90, 0x98, 0xa1, 0xa9, 0xb1, 0xb7, 0xbe, 0xc4,
- 0xcb,
- 0x10, 0x03, 0x01, 0x00,
- 0x10, 0x0f, 0x02, 0x0d, 0x0d,
- 0x10, 0x03, 0x01, 0x02,
- 0x10, 0x41, 0x11, 0x00, 0x0d, 0x36, 0x4e, 0x60, 0x6f, 0x7b, 0x86,
- 0x90, 0x98, 0xa1, 0xa9, 0xb1, 0xb7, 0xbe, 0xc4,
- 0xcb,
- 0x10, 0x0b, 0x01, 0x17,
- 0x10, 0x0d, 0x01, 0x10,
- 0x10, 0x0c, 0x01, 0x1e,
- 0x04, 0x06, 0x01, 0x03,
- 0x04, 0x04, 0x01, 0x00,
- 0, 0, 0
-};
-
-/* nw802 - Mustek Wcam 300 mini */
-static const u8 mustek_start[] = {
- 0x04, 0x06, 0x01, 0x04,
- 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x92, 0x03, 0x10, 0x00, 0x4d,
- 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
- 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
- 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
- 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
- 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
- 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x68, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
- 0x00, 0x0c, 0x02, 0x01, 0x00, 0x16, 0x00, 0x94,
- 0x00, 0x10, 0x06, 0xfc, 0x05, 0x0c, 0x06,
- 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
- 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
- 0x06, 0x00, 0x02, 0x09, 0x99,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0xa1, 0x02, 0x80, 0x00, 0x13, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x49, 0x13, 0x00, 0x00, 0xc0, 0x00, 0x14,
- 0x02, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
- 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
- 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
- 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
- 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
- 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
- 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x01, 0x82,
- 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
- 0x01, 0xf0, 0x00,
- 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
- 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
- 0x40,
- 0x10, 0x1a, 0x01, 0x00,
- 0x10, 0x00, 0x01, 0xad,
- 0x00, 0x00, 0x01, 0x08,
- 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
- 0x10, 0x1b, 0x02, 0x00, 0x00,
- 0x10, 0x11, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
- 0x10, 0x1d, 0x08, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
- 0x10, 0x0e, 0x01, 0x0f,
- 0x10, 0x41, 0x11, 0x00, 0x0f, 0x29, 0x4a, 0x64, 0x7a, 0x8c, 0x9e,
- 0xad, 0xba, 0xc7, 0xd3, 0xde, 0xe8, 0xf1, 0xf9,
- 0xff,
- 0x10, 0x0f, 0x02, 0x11, 0x11,
- 0x10, 0x03, 0x01, 0x0c,
- 0x10, 0x41, 0x11, 0x00, 0x0f, 0x29, 0x4a, 0x64, 0x7a, 0x8c, 0x9e,
- 0xad, 0xba, 0xc7, 0xd3, 0xde, 0xe8, 0xf1, 0xf9,
- 0xff,
- 0x10, 0x0b, 0x01, 0x1c,
- 0x10, 0x0d, 0x01, 0x1a,
- 0x10, 0x0c, 0x01, 0x34,
- 0x04, 0x05, 0x01, 0x61,
- 0x04, 0x04, 0x01, 0x40,
- 0x04, 0x06, 0x01, 0x03,
- 0, 0, 0
-};
-
-/* nw802 - Scope USB Microscope M2 (ProScope) (Hitachi HD49322BF) */
-static const u8 proscope_init[] = {
- 0x04, 0x05, 0x01, 0x21,
- 0x04, 0x04, 0x01, 0x01,
- 0, 0, 0
-};
-static const u8 proscope_start_1[] = {
- 0x04, 0x06, 0x01, 0x04,
- 0x00, 0x00, 0x40, 0x10, 0x01, 0x00, 0xf9, 0x02, 0x10, 0x00, 0x04,
- 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x08, 0x00, 0x17, 0x00, 0xce, 0x00, 0xf4,
- 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
- 0x00, 0xce, 0x00, 0xf8, 0x03, 0x3e, 0x00, 0x86,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0xb6,
- 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xf6, 0x03, 0x34, 0x04, 0xf6, 0x03, 0x34,
- 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xe8,
- 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
- 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x1f, 0x0f, 0x08, 0x20, 0xa8, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
- 0x00, 0x0c, 0x02, 0x01, 0x00, 0x19, 0x00, 0x94,
- 0x00, 0x10, 0x06, 0x10, 0x00, 0x36, 0x00,
- 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
- 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
- 0x06, 0x00, 0x02, 0x09, 0x99,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0xad, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x1f, 0x10, 0x08, 0x0a,
- 0x0a, 0x51, 0x00, 0xf1, 0x00, 0x3c, 0x00, 0xb4,
- 0x00, 0x49, 0x13, 0x00, 0x00, 0x8c, 0x04, 0x01,
- 0x20, 0x02, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
- 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
- 0x10, 0x40, 0x40, 0x80, 0x00, 0x2d, 0x46, 0x58, 0x67, 0x74, 0x7f,
- 0x88, 0x94, 0x9d, 0xa6, 0xae, 0xb5, 0xbd, 0xc4,
- 0xcb, 0xd1, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
- 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
- 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x3f,
- 0x01, 0x00, 0x00, 0xef, 0x00, 0x09, 0x05, 0x82,
- 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
- 0x01, 0xf0, 0x00,
- 0, 0, 0
-};
-static const u8 proscope_start_qvga[] = {
- 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
- 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
- 0x40,
- 0x10, 0x1a, 0x01, 0x06,
- 0x00, 0x03, 0x02, 0xf9, 0x02,
- 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
- 0x10, 0x1b, 0x02, 0x00, 0x00,
- 0x10, 0x11, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
- 0x10, 0x1d, 0x08, 0xc0, 0x0d, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
- 0x10, 0x0e, 0x01, 0x10,
- 0, 0, 0
-};
-static const u8 proscope_start_vga[] = {
- 0x00, 0x03, 0x02, 0xf9, 0x02,
- 0x10, 0x85, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01,
- 0x02, 0x00, 0x11, 0x78, 0xa0, 0x8c, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x16, 0x00, 0x00, 0x82, 0x84, 0x00,
- 0x80,
- 0x10, 0x1a, 0x01, 0x06,
- 0x10, 0x00, 0x01, 0xa1,
- 0x10, 0x1b, 0x02, 0x00, 0x00,
- 0x10, 0x1d, 0x08, 0xc0, 0x0d, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
- 0x10, 0x11, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01,
- 0x10, 0x0e, 0x01, 0x10,
- 0x10, 0x41, 0x11, 0x00, 0x10, 0x51, 0x6e, 0x83, 0x93, 0xa1, 0xae,
- 0xb9, 0xc3, 0xcc, 0xd4, 0xdd, 0xe4, 0xeb, 0xf2,
- 0xf9,
- 0x10, 0x03, 0x01, 0x00,
- 0, 0, 0
-};
-static const u8 proscope_start_2[] = {
- 0x10, 0x0f, 0x02, 0x0c, 0x0c,
- 0x10, 0x03, 0x01, 0x0c,
- 0x10, 0x41, 0x11, 0x00, 0x10, 0x51, 0x6e, 0x83, 0x93, 0xa1, 0xae,
- 0xb9, 0xc3, 0xcc, 0xd4, 0xdd, 0xe4, 0xeb, 0xf2,
- 0xf9,
- 0x10, 0x0b, 0x01, 0x0b,
- 0x10, 0x0d, 0x01, 0x10,
- 0x10, 0x0c, 0x01, 0x1b,
- 0x04, 0x06, 0x01, 0x03,
- 0x04, 0x05, 0x01, 0x21,
- 0x04, 0x04, 0x01, 0x00,
- 0, 0, 0
-};
-
-/* nw800 - hv7121b? (seems pas106) - Divio Chicony TwinkleCam */
-static const u8 twinkle_start[] = {
- 0x04, 0x06, 0x01, 0x44,
- 0x04, 0x06, 0x01, 0x00,
- 0x00, 0x00, 0x40, 0x14, 0x83, 0x00, 0xba, 0x01, 0x10, 0x00, 0x4f,
- 0xef, 0x00, 0x00, 0x60, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x06, 0x00, 0xfc,
- 0x01, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
- 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
- 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
- 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
- 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
- 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
- 0x00, 0x80, 0x1f, 0xb8, 0x48, 0x0f, 0x04, 0x88, 0x14, 0x68, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x03,
- 0x00, 0x24, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
- 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00,
- 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
- 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0x00,
- 0x05, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0x80, 0x02, 0x20, 0x00, 0x11, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x08,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
- 0x03, 0x00, 0x00, 0x10, 0x00, 0x20, 0x10, 0x06,
- 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x00, 0x80,
- 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
- 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
- 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
- 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
- 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62,
- 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
- 0x01, 0x60, 0x01, 0x00, 0x00,
-
- 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
- 0x04, 0x04, 0x01, 0x10,
- 0x04, 0x04, 0x01, 0x00,
- 0x04, 0x05, 0x01, 0x61,
- 0x04, 0x04, 0x01, 0x01,
- I2C0, 0x40, 0x0c, 0x02, 0x0c, 0x12, 0x07, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0a,
- I2C0, 0x40, 0x02, 0x11, 0x06,
- I2C0, 0x40, 0x02, 0x14, 0x00,
- I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */
- I2C0, 0x40, 0x02, 0x07, 0x01,
- 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00,
- 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65,
- 0x40,
- I2C0, 0x40, 0x02, 0x02, 0x0c,
- I2C0, 0x40, 0x02, 0x13, 0x01,
- 0x10, 0x00, 0x01, 0x01,
- 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01,
- 0x20, 0x01, 0x60, 0x01,
- I2C0, 0x40, 0x02, 0x05, 0x0f,
- I2C0, 0x40, 0x02, 0x13, 0x01,
- I2C0, 0x40, 0x08, 0x08, 0x04, 0x0b, 0x01, 0x01, 0x02, 0x00, 0x17,
- I2C0, 0x40, 0x03, 0x12, 0x00, 0x01,
- 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
- I2C0, 0x40, 0x02, 0x12, 0x00,
- I2C0, 0x40, 0x02, 0x0e, 0x00,
- I2C0, 0x40, 0x02, 0x11, 0x06,
- 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7,
- 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7,
- 0xf9,
- 0x10, 0x03, 0x01, 0x00,
- 0x10, 0x0f, 0x02, 0x0c, 0x0c,
- 0x10, 0x03, 0x01, 0x06,
- 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7,
- 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7,
- 0xf9,
- 0x10, 0x0b, 0x01, 0x19,
- 0x10, 0x0d, 0x01, 0x10,
- 0x10, 0x0c, 0x01, 0x0d,
- 0x04, 0x06, 0x01, 0x03,
- 0x04, 0x05, 0x01, 0x61,
- 0x04, 0x04, 0x01, 0x41,
- 0, 0, 0
-};
-
-/* nw802 dvc-v6 */
-static const u8 dvcv6_start[] = {
- 0x04, 0x06, 0x01, 0x06,
- 0x00, 0x00, 0x40, 0x54, 0x96, 0x98, 0xf9, 0x02, 0x18, 0x00, 0x4c,
- 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
- 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
- 0x00, 0x0b, 0x00, 0x1b, 0x00, 0xc8, 0x00, 0xf4,
- 0x05, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54,
- 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6,
- 0x00, 0x5d, 0x00, 0xc7, 0x00, 0x7e, 0x00, 0x30,
- 0x00, 0x80, 0x1f, 0x98, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f,
- 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
- 0x00, 0x0c, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94,
- 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00,
- 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
- 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
- 0x40, 0x20,
- 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
- 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00,
- 0x06, 0x00, 0x02, 0x09, 0x99,
- 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c,
- 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
- 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
- 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
- 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
- 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
- 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
- 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
- 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
- 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
- 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
- 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x82,
- 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
- 0x01, 0xf0, 0x00,
- 0x00, 0x03, 0x02, 0x94, 0x03,
- 0x00, 0x1d, 0x04, 0x0a, 0x01, 0x28, 0x07,
- 0x00, 0x7b, 0x02, 0xe0, 0x00,
- 0x10, 0x8d, 0x01, 0x00,
- 0x00, 0x09, 0x04, 0x1e, 0x00, 0x0c, 0x02,
- 0x00, 0x91, 0x02, 0x0b, 0x02,
- 0x10, 0x00, 0x01, 0xaf,
- 0x02, 0x00, 0x11, 0x3c, 0x50, 0x8f, 0x3c, 0x50, 0x00, 0x00, 0x00,
- 0x00, 0x78, 0x3f, 0x3f, 0x06, 0xf2, 0x8f, 0xf0,
- 0x40,
- 0x10, 0x1a, 0x01, 0x02,
- 0x10, 0x00, 0x01, 0xaf,
- 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
- 0x10, 0x1b, 0x02, 0x07, 0x01,
- 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00,
- 0x10, 0x1f, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
- 0x10, 0x1d, 0x02, 0x40, 0x06,
- 0x10, 0x0e, 0x01, 0x08,
- 0x10, 0x41, 0x11, 0x00, 0x0f, 0x54, 0x6f, 0x82, 0x91, 0x9f, 0xaa,
- 0xb4, 0xbd, 0xc5, 0xcd, 0xd5, 0xdb, 0xdc, 0xdc,
- 0xdc,
- 0x10, 0x03, 0x01, 0x00,
- 0x10, 0x0f, 0x02, 0x12, 0x12,
- 0x10, 0x03, 0x01, 0x11,
- 0x10, 0x41, 0x11, 0x00, 0x0f, 0x54, 0x6f, 0x82, 0x91, 0x9f, 0xaa,
- 0xb4, 0xbd, 0xc5, 0xcd, 0xd5, 0xdb, 0xdc, 0xdc,
- 0xdc,
- 0x10, 0x0b, 0x01, 0x16,
- 0x10, 0x0d, 0x01, 0x10,
- 0x10, 0x0c, 0x01, 0x1a,
- 0x04, 0x06, 0x01, 0x03,
- 0x04, 0x04, 0x01, 0x00,
-};
-
-static const u8 *webcam_start[] = {
- [Generic800] = nw800_start,
- [SpaceCam] = spacecam_start,
- [SpaceCam2] = spacecam2_start,
- [Cvideopro] = cvideopro_start,
- [Dlink350c] = dlink_start,
- [DS3303u] = ds3303_start,
- [Kr651us] = kr651_start_1,
- [Kritter] = kritter_start,
- [Mustek300] = mustek_start,
- [Proscope] = proscope_start_1,
- [Twinkle] = twinkle_start,
- [DvcV6] = dvcv6_start,
- [P35u] = nw801_start_1,
- [Generic802] = nw802_start,
-};
-
-/* -- write a register -- */
-static void reg_w(struct gspca_dev *gspca_dev,
- u16 index,
- const u8 *data,
- int len)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- if (len == 1)
- PDEBUG(D_USBO, "SET 00 0000 %04x %02x", index, *data);
- else
- PDEBUG(D_USBO, "SET 00 0000 %04x %02x %02x ...",
- index, *data, data[1]);
- memcpy(gspca_dev->usb_buf, data, len);
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x00,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x00, /* value */
- index,
- gspca_dev->usb_buf,
- len,
- 500);
- if (ret < 0) {
- pr_err("reg_w err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-/* -- read registers in usb_buf -- */
-static void reg_r(struct gspca_dev *gspca_dev,
- u16 index,
- int len)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- 0x00,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x00, index,
- gspca_dev->usb_buf, len, 500);
- if (ret < 0) {
- pr_err("reg_r err %d\n", ret);
- gspca_dev->usb_err = ret;
- return;
- }
- if (len == 1)
- PDEBUG(D_USBI, "GET 00 0000 %04x %02x",
- index, gspca_dev->usb_buf[0]);
- else
- PDEBUG(D_USBI, "GET 00 0000 %04x %02x %02x ..",
- index, gspca_dev->usb_buf[0],
- gspca_dev->usb_buf[1]);
-}
-
-static void i2c_w(struct gspca_dev *gspca_dev,
- u8 i2c_addr,
- const u8 *data,
- int len)
-{
- u8 val[2];
- int i;
-
- reg_w(gspca_dev, 0x0600, data + 1, len - 1);
- reg_w(gspca_dev, 0x0600, data, len);
- val[0] = len;
- val[1] = i2c_addr;
- reg_w(gspca_dev, 0x0502, val, 2);
- val[0] = 0x01;
- reg_w(gspca_dev, 0x0501, val, 1);
- for (i = 5; --i >= 0; ) {
- msleep(4);
- reg_r(gspca_dev, 0x0505, 1);
- if (gspca_dev->usb_err < 0)
- return;
- if (gspca_dev->usb_buf[0] == 0)
- return;
- }
- gspca_dev->usb_err = -ETIME;
-}
-
-static void reg_w_buf(struct gspca_dev *gspca_dev,
- const u8 *cmd)
-{
- u16 reg;
- int len;
-
- for (;;) {
- reg = *cmd++ << 8;
- reg += *cmd++;
- len = *cmd++;
- if (len == 0)
- break;
- if (cmd[-3] != I2C0)
- reg_w(gspca_dev, reg, cmd, len);
- else
- i2c_w(gspca_dev, reg, cmd, len);
- cmd += len;
- }
-}
-
-static int swap_bits(int v)
-{
- int r, i;
-
- r = 0;
- for (i = 0; i < 8; i++) {
- r <<= 1;
- if (v & 1)
- r++;
- v >>= 1;
- }
- return r;
-}
-
-static void setgain(struct gspca_dev *gspca_dev, u8 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 v[2];
-
- switch (sd->webcam) {
- case P35u:
- reg_w(gspca_dev, 0x1026, &val, 1);
- break;
- case Kr651us:
- /* 0 - 253 */
- val = swap_bits(val);
- v[0] = val << 3;
- v[1] = val >> 5;
- reg_w(gspca_dev, 0x101d, v, 2); /* SIF reg0/1 (AGC) */
- break;
- }
-}
-
-static void setexposure(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 v[2];
-
- switch (sd->webcam) {
- case P35u:
- v[0] = ((9 - val) << 3) | 0x01;
- reg_w(gspca_dev, 0x1019, v, 1);
- break;
- case Cvideopro:
- case DvcV6:
- case Kritter:
- case Kr651us:
- v[0] = val;
- v[1] = val >> 8;
- reg_w(gspca_dev, 0x101b, v, 2);
- break;
- }
-}
-
-static void setautogain(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int w, h;
-
- if (!val) {
- sd->ag_cnt = -1;
- return;
- }
- sd->ag_cnt = AG_CNT_START;
-
- reg_r(gspca_dev, 0x1004, 1);
- if (gspca_dev->usb_buf[0] & 0x04) { /* if AE_FULL_FRM */
- sd->ae_res = gspca_dev->width * gspca_dev->height;
- } else { /* get the AE window size */
- reg_r(gspca_dev, 0x1011, 8);
- w = (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]
- - (gspca_dev->usb_buf[3] << 8) - gspca_dev->usb_buf[2];
- h = (gspca_dev->usb_buf[5] << 8) + gspca_dev->usb_buf[4]
- - (gspca_dev->usb_buf[7] << 8) - gspca_dev->usb_buf[6];
- sd->ae_res = h * w;
- if (sd->ae_res == 0)
- sd->ae_res = gspca_dev->width * gspca_dev->height;
- }
-}
-
-static int nw802_test_reg(struct gspca_dev *gspca_dev,
- u16 index,
- u8 value)
-{
- /* write the value */
- reg_w(gspca_dev, index, &value, 1);
-
- /* read it */
- reg_r(gspca_dev, index, 1);
-
- return gspca_dev->usb_buf[0] == value;
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if ((unsigned) webcam >= NWEBCAMS)
- webcam = 0;
- sd->webcam = webcam;
- gspca_dev->cam.needs_full_bandwidth = 1;
- sd->ag_cnt = -1;
-
- /*
- * Autodetect sequence inspired from some log.
- * We try to detect what registers exist or not.
- * If 0x0500 does not exist => NW802
- * If it does, test 0x109b. If it doesn't exist,
- * then it's a NW801. Else, a NW800
- * If a et31x110 (nw800 and 06a5:d800)
- * get the sensor ID
- */
- if (!nw802_test_reg(gspca_dev, 0x0500, 0x55)) {
- sd->bridge = BRIDGE_NW802;
- if (sd->webcam == Generic800)
- sd->webcam = Generic802;
- } else if (!nw802_test_reg(gspca_dev, 0x109b, 0xaa)) {
- sd->bridge = BRIDGE_NW801;
- if (sd->webcam == Generic800)
- sd->webcam = P35u;
- } else if (id->idVendor == 0x06a5 && id->idProduct == 0xd800) {
- reg_r(gspca_dev, 0x0403, 1); /* GPIO */
- PDEBUG(D_PROBE, "et31x110 sensor type %02x",
- gspca_dev->usb_buf[0]);
- switch (gspca_dev->usb_buf[0] >> 1) {
- case 0x00: /* ?? */
- if (sd->webcam == Generic800)
- sd->webcam = SpaceCam;
- break;
- case 0x01: /* Hynix? */
- if (sd->webcam == Generic800)
- sd->webcam = Twinkle;
- break;
- case 0x0a: /* Pixart */
- if (sd->webcam == Generic800)
- sd->webcam = SpaceCam2;
- break;
- }
- }
- if (webcam_chip[sd->webcam] != sd->bridge) {
- pr_err("Bad webcam type %d for NW80%d\n",
- sd->webcam, sd->bridge);
- gspca_dev->usb_err = -ENODEV;
- return gspca_dev->usb_err;
- }
- PDEBUG(D_PROBE, "Bridge nw80%d - type: %d", sd->bridge, sd->webcam);
-
- if (sd->bridge == BRIDGE_NW800) {
- switch (sd->webcam) {
- case DS3303u:
- gspca_dev->cam.cam_mode = cif_mode; /* qvga */
- break;
- default:
- gspca_dev->cam.cam_mode = &cif_mode[1]; /* cif */
- break;
- }
- gspca_dev->cam.nmodes = 1;
- } else {
- gspca_dev->cam.cam_mode = vga_mode;
- switch (sd->webcam) {
- case Kr651us:
- case Proscope:
- case P35u:
- gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
- break;
- default:
- gspca_dev->cam.nmodes = 1; /* qvga only */
- break;
- }
- }
-
- return gspca_dev->usb_err;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->bridge) {
- case BRIDGE_NW800:
- switch (sd->webcam) {
- case SpaceCam:
- reg_w_buf(gspca_dev, spacecam_init);
- break;
- default:
- reg_w_buf(gspca_dev, nw800_init);
- break;
- }
- break;
- default:
- switch (sd->webcam) {
- case Mustek300:
- case P35u:
- case Proscope:
- reg_w_buf(gspca_dev, proscope_init);
- break;
- }
- break;
- }
- return gspca_dev->usb_err;
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- const u8 *cmd;
-
- cmd = webcam_start[sd->webcam];
- reg_w_buf(gspca_dev, cmd);
- switch (sd->webcam) {
- case P35u:
- if (gspca_dev->width == 320)
- reg_w_buf(gspca_dev, nw801_start_qvga);
- else
- reg_w_buf(gspca_dev, nw801_start_vga);
- reg_w_buf(gspca_dev, nw801_start_2);
- break;
- case Kr651us:
- if (gspca_dev->width == 320)
- reg_w_buf(gspca_dev, kr651_start_qvga);
- else
- reg_w_buf(gspca_dev, kr651_start_vga);
- reg_w_buf(gspca_dev, kr651_start_2);
- break;
- case Proscope:
- if (gspca_dev->width == 320)
- reg_w_buf(gspca_dev, proscope_start_qvga);
- else
- reg_w_buf(gspca_dev, proscope_start_vga);
- reg_w_buf(gspca_dev, proscope_start_2);
- break;
- }
-
- sd->exp_too_high_cnt = 0;
- sd->exp_too_low_cnt = 0;
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 value;
-
- /* 'go' off */
- if (sd->bridge != BRIDGE_NW801) {
- value = 0x02;
- reg_w(gspca_dev, 0x0406, &value, 1);
- }
-
- /* LED off */
- switch (sd->webcam) {
- case Cvideopro:
- case Kr651us:
- case DvcV6:
- case Kritter:
- value = 0xff;
- break;
- case Dlink350c:
- value = 0x21;
- break;
- case SpaceCam:
- case SpaceCam2:
- case Proscope:
- case Twinkle:
- value = 0x01;
- break;
- default:
- return;
- }
- reg_w(gspca_dev, 0x0404, &value, 1);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- /*
- * frame header = '00 00 hh ww ss xx ff ff'
- * with:
- * - 'hh': height / 4
- * - 'ww': width / 4
- * - 'ss': frame sequence number c0..dd
- */
- if (data[0] == 0x00 && data[1] == 0x00
- && data[6] == 0xff && data[7] == 0xff) {
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
- gspca_frame_add(gspca_dev, FIRST_PACKET, data + 8, len - 8);
- } else {
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
- }
-}
-
-static void do_autogain(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int luma;
-
- if (sd->ag_cnt < 0)
- return;
- if (--sd->ag_cnt >= 0)
- return;
- sd->ag_cnt = AG_CNT_START;
-
- /* get the average luma */
- reg_r(gspca_dev, sd->bridge == BRIDGE_NW801 ? 0x080d : 0x080c, 4);
- luma = (gspca_dev->usb_buf[3] << 24) + (gspca_dev->usb_buf[2] << 16)
- + (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
- luma /= sd->ae_res;
-
- switch (sd->webcam) {
- case P35u:
- gspca_coarse_grained_expo_autogain(gspca_dev, luma, 100, 5);
- break;
- default:
- gspca_expo_autogain(gspca_dev, luma, 100, 5, 230, 0);
- break;
- }
-}
-
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- /* autogain/gain/exposure control cluster */
- case V4L2_CID_AUTOGAIN:
- if (ctrl->is_new)
- setautogain(gspca_dev, ctrl->val);
- if (!ctrl->val) {
- if (gspca_dev->gain->is_new)
- setgain(gspca_dev, gspca_dev->gain->val);
- if (gspca_dev->exposure->is_new)
- setexposure(gspca_dev,
- gspca_dev->exposure->val);
- }
- break;
- /* Some webcams only have exposure, so handle that separately from the
- autogain/gain/exposure cluster in the previous case. */
- case V4L2_CID_EXPOSURE:
- setexposure(gspca_dev, gspca_dev->exposure->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 3);
- switch (sd->webcam) {
- case P35u:
- gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- /* For P35u choose coarse expo auto gain function gain minimum,
- * to avoid a large settings jump the first auto adjustment */
- gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 127, 1, 127 / 5 * 2);
- gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 9, 1, 9);
- break;
- case Kr651us:
- gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 253, 1, 128);
- /* fall through */
- case Cvideopro:
- case DvcV6:
- case Kritter:
- gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 315, 1, 150);
- break;
- default:
- break;
- }
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- if (gspca_dev->autogain)
- v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
- .dq_callback = do_autogain,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x046d, 0xd001)},
- {USB_DEVICE(0x0502, 0xd001)},
- {USB_DEVICE(0x052b, 0xd001)},
- {USB_DEVICE(0x055f, 0xd001)},
- {USB_DEVICE(0x06a5, 0x0000)},
- {USB_DEVICE(0x06a5, 0xd001)},
- {USB_DEVICE(0x06a5, 0xd800)},
- {USB_DEVICE(0x06be, 0xd001)},
- {USB_DEVICE(0x0728, 0xd001)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
-
-module_param(webcam, int, 0644);
-MODULE_PARM_DESC(webcam,
- "Webcam type\n"
- "0: generic\n"
- "1: Trust 120 SpaceCam\n"
- "2: other Trust 120 SpaceCam\n"
- "3: Conceptronic Video Pro\n"
- "4: D-link dru-350c\n"
- "5: Plustek Opticam 500U\n"
- "6: Panasonic GP-KR651US\n"
- "7: iRez Kritter\n"
- "8: Mustek Wcam 300 mini\n"
- "9: Scalar USB Microscope M2 (Proscope)\n"
- "10: Divio Chicony TwinkleCam\n"
- "11: DVC-V6\n");
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
deleted file mode 100644
index bfc7cefa59f..00000000000
--- a/drivers/media/video/gspca/ov519.c
+++ /dev/null
@@ -1,4991 +0,0 @@
-/**
- * OV519 driver
- *
- * Copyright (C) 2008-2011 Jean-François Moine <moinejf@free.fr>
- * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
- *
- * This module is adapted from the ov51x-jpeg package, which itself
- * was adapted from the ov511 driver.
- *
- * Original copyright for the ov511 driver is:
- *
- * Copyright (c) 1999-2006 Mark W. McClelland
- * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach
- * Many improvements by Bret Wallach <bwallac1@san.rr.com>
- * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
- * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
- * Changes by Claudio Matsuoka <claudio@conectiva.com>
- *
- * ov51x-jpeg original copyright is:
- *
- * Copyright (c) 2004-2007 Romain Beauxis <toots@rastageeks.org>
- * Support for OV7670 sensors was contributed by Sam Skipsey <aoanla@yahoo.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "ov519"
-
-#include <linux/input.h>
-#include "gspca.h"
-
-/* The jpeg_hdr is used by w996Xcf only */
-/* The CONEX_CAM define for jpeg.h needs renaming, now its used here too */
-#define CONEX_CAM
-#include "jpeg.h"
-
-MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
-MODULE_DESCRIPTION("OV519 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* global parameters */
-static int frame_rate;
-
-/* Number of times to retry a failed I2C transaction. Increase this if you
- * are getting "Failed to read sensor ID..." */
-static int i2c_detect_tries = 10;
-
-/* ov519 device descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- struct v4l2_ctrl *jpegqual;
- struct v4l2_ctrl *freq;
- struct { /* h/vflip control cluster */
- struct v4l2_ctrl *hflip;
- struct v4l2_ctrl *vflip;
- };
- struct { /* autobrightness/brightness control cluster */
- struct v4l2_ctrl *autobright;
- struct v4l2_ctrl *brightness;
- };
-
- u8 packet_nr;
-
- char bridge;
-#define BRIDGE_OV511 0
-#define BRIDGE_OV511PLUS 1
-#define BRIDGE_OV518 2
-#define BRIDGE_OV518PLUS 3
-#define BRIDGE_OV519 4 /* = ov530 */
-#define BRIDGE_OVFX2 5
-#define BRIDGE_W9968CF 6
-#define BRIDGE_MASK 7
-
- char invert_led;
-#define BRIDGE_INVERT_LED 8
-
- char snapshot_pressed;
- char snapshot_needs_reset;
-
- /* Determined by sensor type */
- u8 sif;
-
-#define QUALITY_MIN 50
-#define QUALITY_MAX 70
-#define QUALITY_DEF 50
-
- u8 stopped; /* Streaming is temporarily paused */
- u8 first_frame;
-
- u8 frame_rate; /* current Framerate */
- u8 clockdiv; /* clockdiv override */
-
- s8 sensor; /* Type of image sensor chip (SEN_*) */
-
- u8 sensor_addr;
- u16 sensor_width;
- u16 sensor_height;
- s16 sensor_reg_cache[256];
-
- u8 jpeg_hdr[JPEG_HDR_SZ];
-};
-enum sensors {
- SEN_OV2610,
- SEN_OV2610AE,
- SEN_OV3610,
- SEN_OV6620,
- SEN_OV6630,
- SEN_OV66308AF,
- SEN_OV7610,
- SEN_OV7620,
- SEN_OV7620AE,
- SEN_OV7640,
- SEN_OV7648,
- SEN_OV7660,
- SEN_OV7670,
- SEN_OV76BE,
- SEN_OV8610,
- SEN_OV9600,
-};
-
-/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
- the ov sensors which is already present here. When we have the time we
- really should move the sensor drivers to v4l2 sub drivers. */
-#include "w996Xcf.c"
-
-/* table of the disabled controls */
-struct ctrl_valid {
- int has_brightness:1;
- int has_contrast:1;
- int has_exposure:1;
- int has_autogain:1;
- int has_sat:1;
- int has_hvflip:1;
- int has_autobright:1;
- int has_freq:1;
-};
-
-static const struct ctrl_valid valid_controls[] = {
- [SEN_OV2610] = {
- .has_exposure = 1,
- .has_autogain = 1,
- },
- [SEN_OV2610AE] = {
- .has_exposure = 1,
- .has_autogain = 1,
- },
- [SEN_OV3610] = {
- /* No controls */
- },
- [SEN_OV6620] = {
- .has_brightness = 1,
- .has_contrast = 1,
- .has_sat = 1,
- .has_autobright = 1,
- .has_freq = 1,
- },
- [SEN_OV6630] = {
- .has_brightness = 1,
- .has_contrast = 1,
- .has_sat = 1,
- .has_autobright = 1,
- .has_freq = 1,
- },
- [SEN_OV66308AF] = {
- .has_brightness = 1,
- .has_contrast = 1,
- .has_sat = 1,
- .has_autobright = 1,
- .has_freq = 1,
- },
- [SEN_OV7610] = {
- .has_brightness = 1,
- .has_contrast = 1,
- .has_sat = 1,
- .has_autobright = 1,
- .has_freq = 1,
- },
- [SEN_OV7620] = {
- .has_brightness = 1,
- .has_contrast = 1,
- .has_sat = 1,
- .has_autobright = 1,
- .has_freq = 1,
- },
- [SEN_OV7620AE] = {
- .has_brightness = 1,
- .has_contrast = 1,
- .has_sat = 1,
- .has_autobright = 1,
- .has_freq = 1,
- },
- [SEN_OV7640] = {
- .has_brightness = 1,
- .has_sat = 1,
- .has_freq = 1,
- },
- [SEN_OV7648] = {
- .has_brightness = 1,
- .has_sat = 1,
- .has_freq = 1,
- },
- [SEN_OV7660] = {
- .has_brightness = 1,
- .has_contrast = 1,
- .has_sat = 1,
- .has_hvflip = 1,
- .has_freq = 1,
- },
- [SEN_OV7670] = {
- .has_brightness = 1,
- .has_contrast = 1,
- .has_hvflip = 1,
- .has_freq = 1,
- },
- [SEN_OV76BE] = {
- .has_brightness = 1,
- .has_contrast = 1,
- .has_sat = 1,
- .has_autobright = 1,
- .has_freq = 1,
- },
- [SEN_OV8610] = {
- .has_brightness = 1,
- .has_contrast = 1,
- .has_sat = 1,
- .has_autobright = 1,
- },
- [SEN_OV9600] = {
- .has_exposure = 1,
- .has_autogain = 1,
- },
-};
-
-static const struct v4l2_pix_format ov519_vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-static const struct v4l2_pix_format ov519_sif_mode[] = {
- {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 3},
- {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2},
- {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-
-/* Note some of the sizeimage values for the ov511 / ov518 may seem
- larger then necessary, however they need to be this big as the ov511 /
- ov518 always fills the entire isoc frame, using 0 padding bytes when
- it doesn't have any data. So with low framerates the amount of data
- transferred can become quite large (libv4l will remove all the 0 padding
- in userspace). */
-static const struct v4l2_pix_format ov518_vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 2,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-static const struct v4l2_pix_format ov518_sif_mode[] = {
- {160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 70000,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 3},
- {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 70000,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2},
- {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 3,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-
-static const struct v4l2_pix_format ov511_vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 2,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-static const struct v4l2_pix_format ov511_sif_mode[] = {
- {160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 70000,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 3},
- {176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 70000,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2},
- {352, 288, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 3,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-
-static const struct v4l2_pix_format ovfx2_vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-static const struct v4l2_pix_format ovfx2_cif_mode[] = {
- {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 3},
- {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
- {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
- {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 800,
- .sizeimage = 800 * 600,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 1600,
- .sizeimage = 1600 * 1200,
- .colorspace = V4L2_COLORSPACE_SRGB},
-};
-static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
- {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 800,
- .sizeimage = 800 * 600,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 1024,
- .sizeimage = 1024 * 768,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 1600,
- .sizeimage = 1600 * 1200,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
- {2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 2048,
- .sizeimage = 2048 * 1536,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-static const struct v4l2_pix_format ovfx2_ov9600_mode[] = {
- {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 1280,
- .sizeimage = 1280 * 1024,
- .colorspace = V4L2_COLORSPACE_SRGB},
-};
-
-/* Registers common to OV511 / OV518 */
-#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
-#define R51x_SYS_RESET 0x50
- /* Reset type flags */
- #define OV511_RESET_OMNICE 0x08
-#define R51x_SYS_INIT 0x53
-#define R51x_SYS_SNAP 0x52
-#define R51x_SYS_CUST_ID 0x5f
-#define R51x_COMP_LUT_BEGIN 0x80
-
-/* OV511 Camera interface register numbers */
-#define R511_CAM_DELAY 0x10
-#define R511_CAM_EDGE 0x11
-#define R511_CAM_PXCNT 0x12
-#define R511_CAM_LNCNT 0x13
-#define R511_CAM_PXDIV 0x14
-#define R511_CAM_LNDIV 0x15
-#define R511_CAM_UV_EN 0x16
-#define R511_CAM_LINE_MODE 0x17
-#define R511_CAM_OPTS 0x18
-
-#define R511_SNAP_FRAME 0x19
-#define R511_SNAP_PXCNT 0x1a
-#define R511_SNAP_LNCNT 0x1b
-#define R511_SNAP_PXDIV 0x1c
-#define R511_SNAP_LNDIV 0x1d
-#define R511_SNAP_UV_EN 0x1e
-#define R511_SNAP_OPTS 0x1f
-
-#define R511_DRAM_FLOW_CTL 0x20
-#define R511_FIFO_OPTS 0x31
-#define R511_I2C_CTL 0x40
-#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
-#define R511_COMP_EN 0x78
-#define R511_COMP_LUT_EN 0x79
-
-/* OV518 Camera interface register numbers */
-#define R518_GPIO_OUT 0x56 /* OV518(+) only */
-#define R518_GPIO_CTL 0x57 /* OV518(+) only */
-
-/* OV519 Camera interface register numbers */
-#define OV519_R10_H_SIZE 0x10
-#define OV519_R11_V_SIZE 0x11
-#define OV519_R12_X_OFFSETL 0x12
-#define OV519_R13_X_OFFSETH 0x13
-#define OV519_R14_Y_OFFSETL 0x14
-#define OV519_R15_Y_OFFSETH 0x15
-#define OV519_R16_DIVIDER 0x16
-#define OV519_R20_DFR 0x20
-#define OV519_R25_FORMAT 0x25
-
-/* OV519 System Controller register numbers */
-#define OV519_R51_RESET1 0x51
-#define OV519_R54_EN_CLK1 0x54
-#define OV519_R57_SNAPSHOT 0x57
-
-#define OV519_GPIO_DATA_OUT0 0x71
-#define OV519_GPIO_IO_CTRL0 0x72
-
-/*#define OV511_ENDPOINT_ADDRESS 1 * Isoc endpoint number */
-
-/*
- * The FX2 chip does not give us a zero length read at end of frame.
- * It does, however, give a short read at the end of a frame, if
- * necessary, rather than run two frames together.
- *
- * By choosing the right bulk transfer size, we are guaranteed to always
- * get a short read for the last read of each frame. Frame sizes are
- * always a composite number (width * height, or a multiple) so if we
- * choose a prime number, we are guaranteed that the last read of a
- * frame will be short.
- *
- * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB,
- * otherwise EOVERFLOW "babbling" errors occur. I have not been able
- * to figure out why. [PMiller]
- *
- * The constant (13 * 4096) is the largest "prime enough" number less than 64KB.
- *
- * It isn't enough to know the number of bytes per frame, in case we
- * have data dropouts or buffer overruns (even though the FX2 double
- * buffers, there are some pretty strict real time constraints for
- * isochronous transfer for larger frame sizes).
- */
-/*jfm: this value does not work for 800x600 - see isoc_init */
-#define OVFX2_BULK_SIZE (13 * 4096)
-
-/* I2C registers */
-#define R51x_I2C_W_SID 0x41
-#define R51x_I2C_SADDR_3 0x42
-#define R51x_I2C_SADDR_2 0x43
-#define R51x_I2C_R_SID 0x44
-#define R51x_I2C_DATA 0x45
-#define R518_I2C_CTL 0x47 /* OV518(+) only */
-#define OVFX2_I2C_ADDR 0x00
-
-/* I2C ADDRESSES */
-#define OV7xx0_SID 0x42
-#define OV_HIRES_SID 0x60 /* OV9xxx / OV2xxx / OV3xxx */
-#define OV8xx0_SID 0xa0
-#define OV6xx0_SID 0xc0
-
-/* OV7610 registers */
-#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
-#define OV7610_REG_BLUE 0x01 /* blue channel balance */
-#define OV7610_REG_RED 0x02 /* red channel balance */
-#define OV7610_REG_SAT 0x03 /* saturation */
-#define OV8610_REG_HUE 0x04 /* 04 reserved */
-#define OV7610_REG_CNT 0x05 /* Y contrast */
-#define OV7610_REG_BRT 0x06 /* Y brightness */
-#define OV7610_REG_COM_C 0x14 /* misc common regs */
-#define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */
-#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */
-#define OV7610_REG_COM_I 0x29 /* misc settings */
-
-/* OV7660 and OV7670 registers */
-#define OV7670_R00_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
-#define OV7670_R01_BLUE 0x01 /* blue gain */
-#define OV7670_R02_RED 0x02 /* red gain */
-#define OV7670_R03_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
-#define OV7670_R04_COM1 0x04 /* Control 1 */
-/*#define OV7670_R07_AECHH 0x07 * AEC MS 5 bits */
-#define OV7670_R0C_COM3 0x0c /* Control 3 */
-#define OV7670_R0D_COM4 0x0d /* Control 4 */
-#define OV7670_R0E_COM5 0x0e /* All "reserved" */
-#define OV7670_R0F_COM6 0x0f /* Control 6 */
-#define OV7670_R10_AECH 0x10 /* More bits of AEC value */
-#define OV7670_R11_CLKRC 0x11 /* Clock control */
-#define OV7670_R12_COM7 0x12 /* Control 7 */
-#define OV7670_COM7_FMT_VGA 0x00
-/*#define OV7670_COM7_YUV 0x00 * YUV */
-#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */
-#define OV7670_COM7_FMT_MASK 0x38
-#define OV7670_COM7_RESET 0x80 /* Register reset */
-#define OV7670_R13_COM8 0x13 /* Control 8 */
-#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */
-#define OV7670_COM8_AWB 0x02 /* White balance enable */
-#define OV7670_COM8_AGC 0x04 /* Auto gain enable */
-#define OV7670_COM8_BFILT 0x20 /* Band filter enable */
-#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */
-#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
-#define OV7670_R14_COM9 0x14 /* Control 9 - gain ceiling */
-#define OV7670_R15_COM10 0x15 /* Control 10 */
-#define OV7670_R17_HSTART 0x17 /* Horiz start high bits */
-#define OV7670_R18_HSTOP 0x18 /* Horiz stop high bits */
-#define OV7670_R19_VSTART 0x19 /* Vert start high bits */
-#define OV7670_R1A_VSTOP 0x1a /* Vert stop high bits */
-#define OV7670_R1E_MVFP 0x1e /* Mirror / vflip */
-#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
-#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
-#define OV7670_R24_AEW 0x24 /* AGC upper limit */
-#define OV7670_R25_AEB 0x25 /* AGC lower limit */
-#define OV7670_R26_VPT 0x26 /* AGC/AEC fast mode op region */
-#define OV7670_R32_HREF 0x32 /* HREF pieces */
-#define OV7670_R3A_TSLB 0x3a /* lots of stuff */
-#define OV7670_R3B_COM11 0x3b /* Control 11 */
-#define OV7670_COM11_EXP 0x02
-#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
-#define OV7670_R3C_COM12 0x3c /* Control 12 */
-#define OV7670_R3D_COM13 0x3d /* Control 13 */
-#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */
-#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */
-#define OV7670_R3E_COM14 0x3e /* Control 14 */
-#define OV7670_R3F_EDGE 0x3f /* Edge enhancement factor */
-#define OV7670_R40_COM15 0x40 /* Control 15 */
-/*#define OV7670_COM15_R00FF 0xc0 * 00 to FF */
-#define OV7670_R41_COM16 0x41 /* Control 16 */
-#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
-/* end of ov7660 common registers */
-#define OV7670_R55_BRIGHT 0x55 /* Brightness */
-#define OV7670_R56_CONTRAS 0x56 /* Contrast control */
-#define OV7670_R69_GFIX 0x69 /* Fix gain control */
-/*#define OV7670_R8C_RGB444 0x8c * RGB 444 control */
-#define OV7670_R9F_HAECC1 0x9f /* Hist AEC/AGC control 1 */
-#define OV7670_RA0_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
-#define OV7670_RA5_BD50MAX 0xa5 /* 50hz banding step limit */
-#define OV7670_RA6_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
-#define OV7670_RA7_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
-#define OV7670_RA8_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
-#define OV7670_RA9_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
-#define OV7670_RAA_HAECC7 0xaa /* Hist AEC/AGC control 7 */
-#define OV7670_RAB_BD60MAX 0xab /* 60hz banding step limit */
-
-struct ov_regvals {
- u8 reg;
- u8 val;
-};
-struct ov_i2c_regvals {
- u8 reg;
- u8 val;
-};
-
-/* Settings for OV2610 camera chip */
-static const struct ov_i2c_regvals norm_2610[] = {
- { 0x12, 0x80 }, /* reset */
-};
-
-static const struct ov_i2c_regvals norm_2610ae[] = {
- {0x12, 0x80}, /* reset */
- {0x13, 0xcd},
- {0x09, 0x01},
- {0x0d, 0x00},
- {0x11, 0x80},
- {0x12, 0x20}, /* 1600x1200 */
- {0x33, 0x0c},
- {0x35, 0x90},
- {0x36, 0x37},
-/* ms-win traces */
- {0x11, 0x83}, /* clock / 3 ? */
- {0x2d, 0x00}, /* 60 Hz filter */
- {0x24, 0xb0}, /* normal colors */
- {0x25, 0x90},
- {0x10, 0x43},
-};
-
-static const struct ov_i2c_regvals norm_3620b[] = {
- /*
- * From the datasheet: "Note that after writing to register COMH
- * (0x12) to change the sensor mode, registers related to the
- * sensor’s cropping window will be reset back to their default
- * values."
- *
- * "wait 4096 external clock ... to make sure the sensor is
- * stable and ready to access registers" i.e. 160us at 24MHz
- */
- { 0x12, 0x80 }, /* COMH reset */
- { 0x12, 0x00 }, /* QXGA, master */
-
- /*
- * 11 CLKRC "Clock Rate Control"
- * [7] internal frequency doublers: on
- * [6] video port mode: master
- * [5:0] clock divider: 1
- */
- { 0x11, 0x80 },
-
- /*
- * 13 COMI "Common Control I"
- * = 192 (0xC0) 11000000
- * COMI[7] "AEC speed selection"
- * = 1 (0x01) 1....... "Faster AEC correction"
- * COMI[6] "AEC speed step selection"
- * = 1 (0x01) .1...... "Big steps, fast"
- * COMI[5] "Banding filter on off"
- * = 0 (0x00) ..0..... "Off"
- * COMI[4] "Banding filter option"
- * = 0 (0x00) ...0.... "Main clock is 48 MHz and
- * the PLL is ON"
- * COMI[3] "Reserved"
- * = 0 (0x00) ....0...
- * COMI[2] "AGC auto manual control selection"
- * = 0 (0x00) .....0.. "Manual"
- * COMI[1] "AWB auto manual control selection"
- * = 0 (0x00) ......0. "Manual"
- * COMI[0] "Exposure control"
- * = 0 (0x00) .......0 "Manual"
- */
- { 0x13, 0xc0 },
-
- /*
- * 09 COMC "Common Control C"
- * = 8 (0x08) 00001000
- * COMC[7:5] "Reserved"
- * = 0 (0x00) 000.....
- * COMC[4] "Sleep Mode Enable"
- * = 0 (0x00) ...0.... "Normal mode"
- * COMC[3:2] "Sensor sampling reset timing selection"
- * = 2 (0x02) ....10.. "Longer reset time"
- * COMC[1:0] "Output drive current select"
- * = 0 (0x00) ......00 "Weakest"
- */
- { 0x09, 0x08 },
-
- /*
- * 0C COMD "Common Control D"
- * = 8 (0x08) 00001000
- * COMD[7] "Reserved"
- * = 0 (0x00) 0.......
- * COMD[6] "Swap MSB and LSB at the output port"
- * = 0 (0x00) .0...... "False"
- * COMD[5:3] "Reserved"
- * = 1 (0x01) ..001...
- * COMD[2] "Output Average On Off"
- * = 0 (0x00) .....0.. "Output Normal"
- * COMD[1] "Sensor precharge voltage selection"
- * = 0 (0x00) ......0. "Selects internal
- * reference precharge
- * voltage"
- * COMD[0] "Snapshot option"
- * = 0 (0x00) .......0 "Enable live video output
- * after snapshot sequence"
- */
- { 0x0c, 0x08 },
-
- /*
- * 0D COME "Common Control E"
- * = 161 (0xA1) 10100001
- * COME[7] "Output average option"
- * = 1 (0x01) 1....... "Output average of 4 pixels"
- * COME[6] "Anti-blooming control"
- * = 0 (0x00) .0...... "Off"
- * COME[5:3] "Reserved"
- * = 4 (0x04) ..100...
- * COME[2] "Clock output power down pin status"
- * = 0 (0x00) .....0.. "Tri-state data output pin
- * on power down"
- * COME[1] "Data output pin status selection at power down"
- * = 0 (0x00) ......0. "Tri-state VSYNC, PCLK,
- * HREF, and CHSYNC pins on
- * power down"
- * COME[0] "Auto zero circuit select"
- * = 1 (0x01) .......1 "On"
- */
- { 0x0d, 0xa1 },
-
- /*
- * 0E COMF "Common Control F"
- * = 112 (0x70) 01110000
- * COMF[7] "System clock selection"
- * = 0 (0x00) 0....... "Use 24 MHz system clock"
- * COMF[6:4] "Reserved"
- * = 7 (0x07) .111....
- * COMF[3] "Manual auto negative offset canceling selection"
- * = 0 (0x00) ....0... "Auto detect negative
- * offset and cancel it"
- * COMF[2:0] "Reserved"
- * = 0 (0x00) .....000
- */
- { 0x0e, 0x70 },
-
- /*
- * 0F COMG "Common Control G"
- * = 66 (0x42) 01000010
- * COMG[7] "Optical black output selection"
- * = 0 (0x00) 0....... "Disable"
- * COMG[6] "Black level calibrate selection"
- * = 1 (0x01) .1...... "Use optical black pixels
- * to calibrate"
- * COMG[5:4] "Reserved"
- * = 0 (0x00) ..00....
- * COMG[3] "Channel offset adjustment"
- * = 0 (0x00) ....0... "Disable offset adjustment"
- * COMG[2] "ADC black level calibration option"
- * = 0 (0x00) .....0.. "Use B/G line and G/R
- * line to calibrate each
- * channel's black level"
- * COMG[1] "Reserved"
- * = 1 (0x01) ......1.
- * COMG[0] "ADC black level calibration enable"
- * = 0 (0x00) .......0 "Disable"
- */
- { 0x0f, 0x42 },
-
- /*
- * 14 COMJ "Common Control J"
- * = 198 (0xC6) 11000110
- * COMJ[7:6] "AGC gain ceiling"
- * = 3 (0x03) 11...... "8x"
- * COMJ[5:4] "Reserved"
- * = 0 (0x00) ..00....
- * COMJ[3] "Auto banding filter"
- * = 0 (0x00) ....0... "Banding filter is always
- * on off depending on
- * COMI[5] setting"
- * COMJ[2] "VSYNC drop option"
- * = 1 (0x01) .....1.. "SYNC is dropped if frame
- * data is dropped"
- * COMJ[1] "Frame data drop"
- * = 1 (0x01) ......1. "Drop frame data if
- * exposure is not within
- * tolerance. In AEC mode,
- * data is normally dropped
- * when data is out of
- * range."
- * COMJ[0] "Reserved"
- * = 0 (0x00) .......0
- */
- { 0x14, 0xc6 },
-
- /*
- * 15 COMK "Common Control K"
- * = 2 (0x02) 00000010
- * COMK[7] "CHSYNC pin output swap"
- * = 0 (0x00) 0....... "CHSYNC"
- * COMK[6] "HREF pin output swap"
- * = 0 (0x00) .0...... "HREF"
- * COMK[5] "PCLK output selection"
- * = 0 (0x00) ..0..... "PCLK always output"
- * COMK[4] "PCLK edge selection"
- * = 0 (0x00) ...0.... "Data valid on falling edge"
- * COMK[3] "HREF output polarity"
- * = 0 (0x00) ....0... "positive"
- * COMK[2] "Reserved"
- * = 0 (0x00) .....0..
- * COMK[1] "VSYNC polarity"
- * = 1 (0x01) ......1. "negative"
- * COMK[0] "HSYNC polarity"
- * = 0 (0x00) .......0 "positive"
- */
- { 0x15, 0x02 },
-
- /*
- * 33 CHLF "Current Control"
- * = 9 (0x09) 00001001
- * CHLF[7:6] "Sensor current control"
- * = 0 (0x00) 00......
- * CHLF[5] "Sensor current range control"
- * = 0 (0x00) ..0..... "normal range"
- * CHLF[4] "Sensor current"
- * = 0 (0x00) ...0.... "normal current"
- * CHLF[3] "Sensor buffer current control"
- * = 1 (0x01) ....1... "half current"
- * CHLF[2] "Column buffer current control"
- * = 0 (0x00) .....0.. "normal current"
- * CHLF[1] "Analog DSP current control"
- * = 0 (0x00) ......0. "normal current"
- * CHLF[1] "ADC current control"
- * = 0 (0x00) ......0. "normal current"
- */
- { 0x33, 0x09 },
-
- /*
- * 34 VBLM "Blooming Control"
- * = 80 (0x50) 01010000
- * VBLM[7] "Hard soft reset switch"
- * = 0 (0x00) 0....... "Hard reset"
- * VBLM[6:4] "Blooming voltage selection"
- * = 5 (0x05) .101....
- * VBLM[3:0] "Sensor current control"
- * = 0 (0x00) ....0000
- */
- { 0x34, 0x50 },
-
- /*
- * 36 VCHG "Sensor Precharge Voltage Control"
- * = 0 (0x00) 00000000
- * VCHG[7] "Reserved"
- * = 0 (0x00) 0.......
- * VCHG[6:4] "Sensor precharge voltage control"
- * = 0 (0x00) .000....
- * VCHG[3:0] "Sensor array common reference"
- * = 0 (0x00) ....0000
- */
- { 0x36, 0x00 },
-
- /*
- * 37 ADC "ADC Reference Control"
- * = 4 (0x04) 00000100
- * ADC[7:4] "Reserved"
- * = 0 (0x00) 0000....
- * ADC[3] "ADC input signal range"
- * = 0 (0x00) ....0... "Input signal 1.0x"
- * ADC[2:0] "ADC range control"
- * = 4 (0x04) .....100
- */
- { 0x37, 0x04 },
-
- /*
- * 38 ACOM "Analog Common Ground"
- * = 82 (0x52) 01010010
- * ACOM[7] "Analog gain control"
- * = 0 (0x00) 0....... "Gain 1x"
- * ACOM[6] "Analog black level calibration"
- * = 1 (0x01) .1...... "On"
- * ACOM[5:0] "Reserved"
- * = 18 (0x12) ..010010
- */
- { 0x38, 0x52 },
-
- /*
- * 3A FREFA "Internal Reference Adjustment"
- * = 0 (0x00) 00000000
- * FREFA[7:0] "Range"
- * = 0 (0x00) 00000000
- */
- { 0x3a, 0x00 },
-
- /*
- * 3C FVOPT "Internal Reference Adjustment"
- * = 31 (0x1F) 00011111
- * FVOPT[7:0] "Range"
- * = 31 (0x1F) 00011111
- */
- { 0x3c, 0x1f },
-
- /*
- * 44 Undocumented = 0 (0x00) 00000000
- * 44[7:0] "It's a secret"
- * = 0 (0x00) 00000000
- */
- { 0x44, 0x00 },
-
- /*
- * 40 Undocumented = 0 (0x00) 00000000
- * 40[7:0] "It's a secret"
- * = 0 (0x00) 00000000
- */
- { 0x40, 0x00 },
-
- /*
- * 41 Undocumented = 0 (0x00) 00000000
- * 41[7:0] "It's a secret"
- * = 0 (0x00) 00000000
- */
- { 0x41, 0x00 },
-
- /*
- * 42 Undocumented = 0 (0x00) 00000000
- * 42[7:0] "It's a secret"
- * = 0 (0x00) 00000000
- */
- { 0x42, 0x00 },
-
- /*
- * 43 Undocumented = 0 (0x00) 00000000
- * 43[7:0] "It's a secret"
- * = 0 (0x00) 00000000
- */
- { 0x43, 0x00 },
-
- /*
- * 45 Undocumented = 128 (0x80) 10000000
- * 45[7:0] "It's a secret"
- * = 128 (0x80) 10000000
- */
- { 0x45, 0x80 },
-
- /*
- * 48 Undocumented = 192 (0xC0) 11000000
- * 48[7:0] "It's a secret"
- * = 192 (0xC0) 11000000
- */
- { 0x48, 0xc0 },
-
- /*
- * 49 Undocumented = 25 (0x19) 00011001
- * 49[7:0] "It's a secret"
- * = 25 (0x19) 00011001
- */
- { 0x49, 0x19 },
-
- /*
- * 4B Undocumented = 128 (0x80) 10000000
- * 4B[7:0] "It's a secret"
- * = 128 (0x80) 10000000
- */
- { 0x4b, 0x80 },
-
- /*
- * 4D Undocumented = 196 (0xC4) 11000100
- * 4D[7:0] "It's a secret"
- * = 196 (0xC4) 11000100
- */
- { 0x4d, 0xc4 },
-
- /*
- * 35 VREF "Reference Voltage Control"
- * = 76 (0x4c) 01001100
- * VREF[7:5] "Column high reference control"
- * = 2 (0x02) 010..... "higher voltage"
- * VREF[4:2] "Column low reference control"
- * = 3 (0x03) ...011.. "Highest voltage"
- * VREF[1:0] "Reserved"
- * = 0 (0x00) ......00
- */
- { 0x35, 0x4c },
-
- /*
- * 3D Undocumented = 0 (0x00) 00000000
- * 3D[7:0] "It's a secret"
- * = 0 (0x00) 00000000
- */
- { 0x3d, 0x00 },
-
- /*
- * 3E Undocumented = 0 (0x00) 00000000
- * 3E[7:0] "It's a secret"
- * = 0 (0x00) 00000000
- */
- { 0x3e, 0x00 },
-
- /*
- * 3B FREFB "Internal Reference Adjustment"
- * = 24 (0x18) 00011000
- * FREFB[7:0] "Range"
- * = 24 (0x18) 00011000
- */
- { 0x3b, 0x18 },
-
- /*
- * 33 CHLF "Current Control"
- * = 25 (0x19) 00011001
- * CHLF[7:6] "Sensor current control"
- * = 0 (0x00) 00......
- * CHLF[5] "Sensor current range control"
- * = 0 (0x00) ..0..... "normal range"
- * CHLF[4] "Sensor current"
- * = 1 (0x01) ...1.... "double current"
- * CHLF[3] "Sensor buffer current control"
- * = 1 (0x01) ....1... "half current"
- * CHLF[2] "Column buffer current control"
- * = 0 (0x00) .....0.. "normal current"
- * CHLF[1] "Analog DSP current control"
- * = 0 (0x00) ......0. "normal current"
- * CHLF[1] "ADC current control"
- * = 0 (0x00) ......0. "normal current"
- */
- { 0x33, 0x19 },
-
- /*
- * 34 VBLM "Blooming Control"
- * = 90 (0x5A) 01011010
- * VBLM[7] "Hard soft reset switch"
- * = 0 (0x00) 0....... "Hard reset"
- * VBLM[6:4] "Blooming voltage selection"
- * = 5 (0x05) .101....
- * VBLM[3:0] "Sensor current control"
- * = 10 (0x0A) ....1010
- */
- { 0x34, 0x5a },
-
- /*
- * 3B FREFB "Internal Reference Adjustment"
- * = 0 (0x00) 00000000
- * FREFB[7:0] "Range"
- * = 0 (0x00) 00000000
- */
- { 0x3b, 0x00 },
-
- /*
- * 33 CHLF "Current Control"
- * = 9 (0x09) 00001001
- * CHLF[7:6] "Sensor current control"
- * = 0 (0x00) 00......
- * CHLF[5] "Sensor current range control"
- * = 0 (0x00) ..0..... "normal range"
- * CHLF[4] "Sensor current"
- * = 0 (0x00) ...0.... "normal current"
- * CHLF[3] "Sensor buffer current control"
- * = 1 (0x01) ....1... "half current"
- * CHLF[2] "Column buffer current control"
- * = 0 (0x00) .....0.. "normal current"
- * CHLF[1] "Analog DSP current control"
- * = 0 (0x00) ......0. "normal current"
- * CHLF[1] "ADC current control"
- * = 0 (0x00) ......0. "normal current"
- */
- { 0x33, 0x09 },
-
- /*
- * 34 VBLM "Blooming Control"
- * = 80 (0x50) 01010000
- * VBLM[7] "Hard soft reset switch"
- * = 0 (0x00) 0....... "Hard reset"
- * VBLM[6:4] "Blooming voltage selection"
- * = 5 (0x05) .101....
- * VBLM[3:0] "Sensor current control"
- * = 0 (0x00) ....0000
- */
- { 0x34, 0x50 },
-
- /*
- * 12 COMH "Common Control H"
- * = 64 (0x40) 01000000
- * COMH[7] "SRST"
- * = 0 (0x00) 0....... "No-op"
- * COMH[6:4] "Resolution selection"
- * = 4 (0x04) .100.... "XGA"
- * COMH[3] "Master slave selection"
- * = 0 (0x00) ....0... "Master mode"
- * COMH[2] "Internal B/R channel option"
- * = 0 (0x00) .....0.. "B/R use same channel"
- * COMH[1] "Color bar test pattern"
- * = 0 (0x00) ......0. "Off"
- * COMH[0] "Reserved"
- * = 0 (0x00) .......0
- */
- { 0x12, 0x40 },
-
- /*
- * 17 HREFST "Horizontal window start"
- * = 31 (0x1F) 00011111
- * HREFST[7:0] "Horizontal window start, 8 MSBs"
- * = 31 (0x1F) 00011111
- */
- { 0x17, 0x1f },
-
- /*
- * 18 HREFEND "Horizontal window end"
- * = 95 (0x5F) 01011111
- * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
- * = 95 (0x5F) 01011111
- */
- { 0x18, 0x5f },
-
- /*
- * 19 VSTRT "Vertical window start"
- * = 0 (0x00) 00000000
- * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
- * = 0 (0x00) 00000000
- */
- { 0x19, 0x00 },
-
- /*
- * 1A VEND "Vertical window end"
- * = 96 (0x60) 01100000
- * VEND[7:0] "Vertical Window End, 8 MSBs"
- * = 96 (0x60) 01100000
- */
- { 0x1a, 0x60 },
-
- /*
- * 32 COMM "Common Control M"
- * = 18 (0x12) 00010010
- * COMM[7:6] "Pixel clock divide option"
- * = 0 (0x00) 00...... "/1"
- * COMM[5:3] "Horizontal window end position, 3 LSBs"
- * = 2 (0x02) ..010...
- * COMM[2:0] "Horizontal window start position, 3 LSBs"
- * = 2 (0x02) .....010
- */
- { 0x32, 0x12 },
-
- /*
- * 03 COMA "Common Control A"
- * = 74 (0x4A) 01001010
- * COMA[7:4] "AWB Update Threshold"
- * = 4 (0x04) 0100....
- * COMA[3:2] "Vertical window end line control 2 LSBs"
- * = 2 (0x02) ....10..
- * COMA[1:0] "Vertical window start line control 2 LSBs"
- * = 2 (0x02) ......10
- */
- { 0x03, 0x4a },
-
- /*
- * 11 CLKRC "Clock Rate Control"
- * = 128 (0x80) 10000000
- * CLKRC[7] "Internal frequency doublers on off seclection"
- * = 1 (0x01) 1....... "On"
- * CLKRC[6] "Digital video master slave selection"
- * = 0 (0x00) .0...... "Master mode, sensor
- * provides PCLK"
- * CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }"
- * = 0 (0x00) ..000000
- */
- { 0x11, 0x80 },
-
- /*
- * 12 COMH "Common Control H"
- * = 0 (0x00) 00000000
- * COMH[7] "SRST"
- * = 0 (0x00) 0....... "No-op"
- * COMH[6:4] "Resolution selection"
- * = 0 (0x00) .000.... "QXGA"
- * COMH[3] "Master slave selection"
- * = 0 (0x00) ....0... "Master mode"
- * COMH[2] "Internal B/R channel option"
- * = 0 (0x00) .....0.. "B/R use same channel"
- * COMH[1] "Color bar test pattern"
- * = 0 (0x00) ......0. "Off"
- * COMH[0] "Reserved"
- * = 0 (0x00) .......0
- */
- { 0x12, 0x00 },
-
- /*
- * 12 COMH "Common Control H"
- * = 64 (0x40) 01000000
- * COMH[7] "SRST"
- * = 0 (0x00) 0....... "No-op"
- * COMH[6:4] "Resolution selection"
- * = 4 (0x04) .100.... "XGA"
- * COMH[3] "Master slave selection"
- * = 0 (0x00) ....0... "Master mode"
- * COMH[2] "Internal B/R channel option"
- * = 0 (0x00) .....0.. "B/R use same channel"
- * COMH[1] "Color bar test pattern"
- * = 0 (0x00) ......0. "Off"
- * COMH[0] "Reserved"
- * = 0 (0x00) .......0
- */
- { 0x12, 0x40 },
-
- /*
- * 17 HREFST "Horizontal window start"
- * = 31 (0x1F) 00011111
- * HREFST[7:0] "Horizontal window start, 8 MSBs"
- * = 31 (0x1F) 00011111
- */
- { 0x17, 0x1f },
-
- /*
- * 18 HREFEND "Horizontal window end"
- * = 95 (0x5F) 01011111
- * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
- * = 95 (0x5F) 01011111
- */
- { 0x18, 0x5f },
-
- /*
- * 19 VSTRT "Vertical window start"
- * = 0 (0x00) 00000000
- * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
- * = 0 (0x00) 00000000
- */
- { 0x19, 0x00 },
-
- /*
- * 1A VEND "Vertical window end"
- * = 96 (0x60) 01100000
- * VEND[7:0] "Vertical Window End, 8 MSBs"
- * = 96 (0x60) 01100000
- */
- { 0x1a, 0x60 },
-
- /*
- * 32 COMM "Common Control M"
- * = 18 (0x12) 00010010
- * COMM[7:6] "Pixel clock divide option"
- * = 0 (0x00) 00...... "/1"
- * COMM[5:3] "Horizontal window end position, 3 LSBs"
- * = 2 (0x02) ..010...
- * COMM[2:0] "Horizontal window start position, 3 LSBs"
- * = 2 (0x02) .....010
- */
- { 0x32, 0x12 },
-
- /*
- * 03 COMA "Common Control A"
- * = 74 (0x4A) 01001010
- * COMA[7:4] "AWB Update Threshold"
- * = 4 (0x04) 0100....
- * COMA[3:2] "Vertical window end line control 2 LSBs"
- * = 2 (0x02) ....10..
- * COMA[1:0] "Vertical window start line control 2 LSBs"
- * = 2 (0x02) ......10
- */
- { 0x03, 0x4a },
-
- /*
- * 02 RED "Red Gain Control"
- * = 175 (0xAF) 10101111
- * RED[7] "Action"
- * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
- * RED[6:0] "Value"
- * = 47 (0x2F) .0101111
- */
- { 0x02, 0xaf },
-
- /*
- * 2D ADDVSL "VSYNC Pulse Width"
- * = 210 (0xD2) 11010010
- * ADDVSL[7:0] "VSYNC pulse width, LSB"
- * = 210 (0xD2) 11010010
- */
- { 0x2d, 0xd2 },
-
- /*
- * 00 GAIN = 24 (0x18) 00011000
- * GAIN[7:6] "Reserved"
- * = 0 (0x00) 00......
- * GAIN[5] "Double"
- * = 0 (0x00) ..0..... "False"
- * GAIN[4] "Double"
- * = 1 (0x01) ...1.... "True"
- * GAIN[3:0] "Range"
- * = 8 (0x08) ....1000
- */
- { 0x00, 0x18 },
-
- /*
- * 01 BLUE "Blue Gain Control"
- * = 240 (0xF0) 11110000
- * BLUE[7] "Action"
- * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
- * BLUE[6:0] "Value"
- * = 112 (0x70) .1110000
- */
- { 0x01, 0xf0 },
-
- /*
- * 10 AEC "Automatic Exposure Control"
- * = 10 (0x0A) 00001010
- * AEC[7:0] "Automatic Exposure Control, 8 MSBs"
- * = 10 (0x0A) 00001010
- */
- { 0x10, 0x0a },
-
- { 0xe1, 0x67 },
- { 0xe3, 0x03 },
- { 0xe4, 0x26 },
- { 0xe5, 0x3e },
- { 0xf8, 0x01 },
- { 0xff, 0x01 },
-};
-
-static const struct ov_i2c_regvals norm_6x20[] = {
- { 0x12, 0x80 }, /* reset */
- { 0x11, 0x01 },
- { 0x03, 0x60 },
- { 0x05, 0x7f }, /* For when autoadjust is off */
- { 0x07, 0xa8 },
- /* The ratio of 0x0c and 0x0d controls the white point */
- { 0x0c, 0x24 },
- { 0x0d, 0x24 },
- { 0x0f, 0x15 }, /* COMS */
- { 0x10, 0x75 }, /* AEC Exposure time */
- { 0x12, 0x24 }, /* Enable AGC */
- { 0x14, 0x04 },
- /* 0x16: 0x06 helps frame stability with moving objects */
- { 0x16, 0x06 },
-/* { 0x20, 0x30 }, * Aperture correction enable */
- { 0x26, 0xb2 }, /* BLC enable */
- /* 0x28: 0x05 Selects RGB format if RGB on */
- { 0x28, 0x05 },
- { 0x2a, 0x04 }, /* Disable framerate adjust */
-/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */
- { 0x2d, 0x85 },
- { 0x33, 0xa0 }, /* Color Processing Parameter */
- { 0x34, 0xd2 }, /* Max A/D range */
- { 0x38, 0x8b },
- { 0x39, 0x40 },
-
- { 0x3c, 0x39 }, /* Enable AEC mode changing */
- { 0x3c, 0x3c }, /* Change AEC mode */
- { 0x3c, 0x24 }, /* Disable AEC mode changing */
-
- { 0x3d, 0x80 },
- /* These next two registers (0x4a, 0x4b) are undocumented.
- * They control the color balance */
- { 0x4a, 0x80 },
- { 0x4b, 0x80 },
- { 0x4d, 0xd2 }, /* This reduces noise a bit */
- { 0x4e, 0xc1 },
- { 0x4f, 0x04 },
-/* Do 50-53 have any effect? */
-/* Toggle 0x12[2] off and on here? */
-};
-
-static const struct ov_i2c_regvals norm_6x30[] = {
- { 0x12, 0x80 }, /* Reset */
- { 0x00, 0x1f }, /* Gain */
- { 0x01, 0x99 }, /* Blue gain */
- { 0x02, 0x7c }, /* Red gain */
- { 0x03, 0xc0 }, /* Saturation */
- { 0x05, 0x0a }, /* Contrast */
- { 0x06, 0x95 }, /* Brightness */
- { 0x07, 0x2d }, /* Sharpness */
- { 0x0c, 0x20 },
- { 0x0d, 0x20 },
- { 0x0e, 0xa0 }, /* Was 0x20, bit7 enables a 2x gain which we need */
- { 0x0f, 0x05 },
- { 0x10, 0x9a },
- { 0x11, 0x00 }, /* Pixel clock = fastest */
- { 0x12, 0x24 }, /* Enable AGC and AWB */
- { 0x13, 0x21 },
- { 0x14, 0x80 },
- { 0x15, 0x01 },
- { 0x16, 0x03 },
- { 0x17, 0x38 },
- { 0x18, 0xea },
- { 0x19, 0x04 },
- { 0x1a, 0x93 },
- { 0x1b, 0x00 },
- { 0x1e, 0xc4 },
- { 0x1f, 0x04 },
- { 0x20, 0x20 },
- { 0x21, 0x10 },
- { 0x22, 0x88 },
- { 0x23, 0xc0 }, /* Crystal circuit power level */
- { 0x25, 0x9a }, /* Increase AEC black ratio */
- { 0x26, 0xb2 }, /* BLC enable */
- { 0x27, 0xa2 },
- { 0x28, 0x00 },
- { 0x29, 0x00 },
- { 0x2a, 0x84 }, /* 60 Hz power */
- { 0x2b, 0xa8 }, /* 60 Hz power */
- { 0x2c, 0xa0 },
- { 0x2d, 0x95 }, /* Enable auto-brightness */
- { 0x2e, 0x88 },
- { 0x33, 0x26 },
- { 0x34, 0x03 },
- { 0x36, 0x8f },
- { 0x37, 0x80 },
- { 0x38, 0x83 },
- { 0x39, 0x80 },
- { 0x3a, 0x0f },
- { 0x3b, 0x3c },
- { 0x3c, 0x1a },
- { 0x3d, 0x80 },
- { 0x3e, 0x80 },
- { 0x3f, 0x0e },
- { 0x40, 0x00 }, /* White bal */
- { 0x41, 0x00 }, /* White bal */
- { 0x42, 0x80 },
- { 0x43, 0x3f }, /* White bal */
- { 0x44, 0x80 },
- { 0x45, 0x20 },
- { 0x46, 0x20 },
- { 0x47, 0x80 },
- { 0x48, 0x7f },
- { 0x49, 0x00 },
- { 0x4a, 0x00 },
- { 0x4b, 0x80 },
- { 0x4c, 0xd0 },
- { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
- { 0x4e, 0x40 },
- { 0x4f, 0x07 }, /* UV avg., col. killer: max */
- { 0x50, 0xff },
- { 0x54, 0x23 }, /* Max AGC gain: 18dB */
- { 0x55, 0xff },
- { 0x56, 0x12 },
- { 0x57, 0x81 },
- { 0x58, 0x75 },
- { 0x59, 0x01 }, /* AGC dark current comp.: +1 */
- { 0x5a, 0x2c },
- { 0x5b, 0x0f }, /* AWB chrominance levels */
- { 0x5c, 0x10 },
- { 0x3d, 0x80 },
- { 0x27, 0xa6 },
- { 0x12, 0x20 }, /* Toggle AWB */
- { 0x12, 0x24 },
-};
-
-/* Lawrence Glaister <lg@jfm.bc.ca> reports:
- *
- * Register 0x0f in the 7610 has the following effects:
- *
- * 0x85 (AEC method 1): Best overall, good contrast range
- * 0x45 (AEC method 2): Very overexposed
- * 0xa5 (spec sheet default): Ok, but the black level is
- * shifted resulting in loss of contrast
- * 0x05 (old driver setting): very overexposed, too much
- * contrast
- */
-static const struct ov_i2c_regvals norm_7610[] = {
- { 0x10, 0xff },
- { 0x16, 0x06 },
- { 0x28, 0x24 },
- { 0x2b, 0xac },
- { 0x12, 0x00 },
- { 0x38, 0x81 },
- { 0x28, 0x24 }, /* 0c */
- { 0x0f, 0x85 }, /* lg's setting */
- { 0x15, 0x01 },
- { 0x20, 0x1c },
- { 0x23, 0x2a },
- { 0x24, 0x10 },
- { 0x25, 0x8a },
- { 0x26, 0xa2 },
- { 0x27, 0xc2 },
- { 0x2a, 0x04 },
- { 0x2c, 0xfe },
- { 0x2d, 0x93 },
- { 0x30, 0x71 },
- { 0x31, 0x60 },
- { 0x32, 0x26 },
- { 0x33, 0x20 },
- { 0x34, 0x48 },
- { 0x12, 0x24 },
- { 0x11, 0x01 },
- { 0x0c, 0x24 },
- { 0x0d, 0x24 },
-};
-
-static const struct ov_i2c_regvals norm_7620[] = {
- { 0x12, 0x80 }, /* reset */
- { 0x00, 0x00 }, /* gain */
- { 0x01, 0x80 }, /* blue gain */
- { 0x02, 0x80 }, /* red gain */
- { 0x03, 0xc0 }, /* OV7670_R03_VREF */
- { 0x06, 0x60 },
- { 0x07, 0x00 },
- { 0x0c, 0x24 },
- { 0x0c, 0x24 },
- { 0x0d, 0x24 },
- { 0x11, 0x01 },
- { 0x12, 0x24 },
- { 0x13, 0x01 },
- { 0x14, 0x84 },
- { 0x15, 0x01 },
- { 0x16, 0x03 },
- { 0x17, 0x2f },
- { 0x18, 0xcf },
- { 0x19, 0x06 },
- { 0x1a, 0xf5 },
- { 0x1b, 0x00 },
- { 0x20, 0x18 },
- { 0x21, 0x80 },
- { 0x22, 0x80 },
- { 0x23, 0x00 },
- { 0x26, 0xa2 },
- { 0x27, 0xea },
- { 0x28, 0x22 }, /* Was 0x20, bit1 enables a 2x gain which we need */
- { 0x29, 0x00 },
- { 0x2a, 0x10 },
- { 0x2b, 0x00 },
- { 0x2c, 0x88 },
- { 0x2d, 0x91 },
- { 0x2e, 0x80 },
- { 0x2f, 0x44 },
- { 0x60, 0x27 },
- { 0x61, 0x02 },
- { 0x62, 0x5f },
- { 0x63, 0xd5 },
- { 0x64, 0x57 },
- { 0x65, 0x83 },
- { 0x66, 0x55 },
- { 0x67, 0x92 },
- { 0x68, 0xcf },
- { 0x69, 0x76 },
- { 0x6a, 0x22 },
- { 0x6b, 0x00 },
- { 0x6c, 0x02 },
- { 0x6d, 0x44 },
- { 0x6e, 0x80 },
- { 0x6f, 0x1d },
- { 0x70, 0x8b },
- { 0x71, 0x00 },
- { 0x72, 0x14 },
- { 0x73, 0x54 },
- { 0x74, 0x00 },
- { 0x75, 0x8e },
- { 0x76, 0x00 },
- { 0x77, 0xff },
- { 0x78, 0x80 },
- { 0x79, 0x80 },
- { 0x7a, 0x80 },
- { 0x7b, 0xe2 },
- { 0x7c, 0x00 },
-};
-
-/* 7640 and 7648. The defaults should be OK for most registers. */
-static const struct ov_i2c_regvals norm_7640[] = {
- { 0x12, 0x80 },
- { 0x12, 0x14 },
-};
-
-static const struct ov_regvals init_519_ov7660[] = {
- { 0x5d, 0x03 }, /* Turn off suspend mode */
- { 0x53, 0x9b }, /* 0x9f enables the (unused) microcontroller */
- { 0x54, 0x0f }, /* bit2 (jpeg enable) */
- { 0xa2, 0x20 }, /* a2-a5 are undocumented */
- { 0xa3, 0x18 },
- { 0xa4, 0x04 },
- { 0xa5, 0x28 },
- { 0x37, 0x00 }, /* SetUsbInit */
- { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
- /* Enable both fields, YUV Input, disable defect comp (why?) */
- { 0x20, 0x0c }, /* 0x0d does U <-> V swap */
- { 0x21, 0x38 },
- { 0x22, 0x1d },
- { 0x17, 0x50 }, /* undocumented */
- { 0x37, 0x00 }, /* undocumented */
- { 0x40, 0xff }, /* I2C timeout counter */
- { 0x46, 0x00 }, /* I2C clock prescaler */
-};
-static const struct ov_i2c_regvals norm_7660[] = {
- {OV7670_R12_COM7, OV7670_COM7_RESET},
- {OV7670_R11_CLKRC, 0x81},
- {0x92, 0x00}, /* DM_LNL */
- {0x93, 0x00}, /* DM_LNH */
- {0x9d, 0x4c}, /* BD50ST */
- {0x9e, 0x3f}, /* BD60ST */
- {OV7670_R3B_COM11, 0x02},
- {OV7670_R13_COM8, 0xf5},
- {OV7670_R10_AECH, 0x00},
- {OV7670_R00_GAIN, 0x00},
- {OV7670_R01_BLUE, 0x7c},
- {OV7670_R02_RED, 0x9d},
- {OV7670_R12_COM7, 0x00},
- {OV7670_R04_COM1, 00},
- {OV7670_R18_HSTOP, 0x01},
- {OV7670_R17_HSTART, 0x13},
- {OV7670_R32_HREF, 0x92},
- {OV7670_R19_VSTART, 0x02},
- {OV7670_R1A_VSTOP, 0x7a},
- {OV7670_R03_VREF, 0x00},
- {OV7670_R0E_COM5, 0x04},
- {OV7670_R0F_COM6, 0x62},
- {OV7670_R15_COM10, 0x00},
- {0x16, 0x02}, /* RSVD */
- {0x1b, 0x00}, /* PSHFT */
- {OV7670_R1E_MVFP, 0x01},
- {0x29, 0x3c}, /* RSVD */
- {0x33, 0x00}, /* CHLF */
- {0x34, 0x07}, /* ARBLM */
- {0x35, 0x84}, /* RSVD */
- {0x36, 0x00}, /* RSVD */
- {0x37, 0x04}, /* ADC */
- {0x39, 0x43}, /* OFON */
- {OV7670_R3A_TSLB, 0x00},
- {OV7670_R3C_COM12, 0x6c},
- {OV7670_R3D_COM13, 0x98},
- {OV7670_R3F_EDGE, 0x23},
- {OV7670_R40_COM15, 0xc1},
- {OV7670_R41_COM16, 0x22},
- {0x6b, 0x0a}, /* DBLV */
- {0xa1, 0x08}, /* RSVD */
- {0x69, 0x80}, /* HV */
- {0x43, 0xf0}, /* RSVD.. */
- {0x44, 0x10},
- {0x45, 0x78},
- {0x46, 0xa8},
- {0x47, 0x60},
- {0x48, 0x80},
- {0x59, 0xba},
- {0x5a, 0x9a},
- {0x5b, 0x22},
- {0x5c, 0xb9},
- {0x5d, 0x9b},
- {0x5e, 0x10},
- {0x5f, 0xe0},
- {0x60, 0x85},
- {0x61, 0x60},
- {0x9f, 0x9d}, /* RSVD */
- {0xa0, 0xa0}, /* DSPC2 */
- {0x4f, 0x60}, /* matrix */
- {0x50, 0x64},
- {0x51, 0x04},
- {0x52, 0x18},
- {0x53, 0x3c},
- {0x54, 0x54},
- {0x55, 0x40},
- {0x56, 0x40},
- {0x57, 0x40},
- {0x58, 0x0d}, /* matrix sign */
- {0x8b, 0xcc}, /* RSVD */
- {0x8c, 0xcc},
- {0x8d, 0xcf},
- {0x6c, 0x40}, /* gamma curve */
- {0x6d, 0xe0},
- {0x6e, 0xa0},
- {0x6f, 0x80},
- {0x70, 0x70},
- {0x71, 0x80},
- {0x72, 0x60},
- {0x73, 0x60},
- {0x74, 0x50},
- {0x75, 0x40},
- {0x76, 0x38},
- {0x77, 0x3c},
- {0x78, 0x32},
- {0x79, 0x1a},
- {0x7a, 0x28},
- {0x7b, 0x24},
- {0x7c, 0x04}, /* gamma curve */
- {0x7d, 0x12},
- {0x7e, 0x26},
- {0x7f, 0x46},
- {0x80, 0x54},
- {0x81, 0x64},
- {0x82, 0x70},
- {0x83, 0x7c},
- {0x84, 0x86},
- {0x85, 0x8e},
- {0x86, 0x9c},
- {0x87, 0xab},
- {0x88, 0xc4},
- {0x89, 0xd1},
- {0x8a, 0xe5},
- {OV7670_R14_COM9, 0x1e},
- {OV7670_R24_AEW, 0x80},
- {OV7670_R25_AEB, 0x72},
- {OV7670_R26_VPT, 0xb3},
- {0x62, 0x80}, /* LCC1 */
- {0x63, 0x80}, /* LCC2 */
- {0x64, 0x06}, /* LCC3 */
- {0x65, 0x00}, /* LCC4 */
- {0x66, 0x01}, /* LCC5 */
- {0x94, 0x0e}, /* RSVD.. */
- {0x95, 0x14},
- {OV7670_R13_COM8, OV7670_COM8_FASTAEC
- | OV7670_COM8_AECSTEP
- | OV7670_COM8_BFILT
- | 0x10
- | OV7670_COM8_AGC
- | OV7670_COM8_AWB
- | OV7670_COM8_AEC},
- {0xa1, 0xc8}
-};
-static const struct ov_i2c_regvals norm_9600[] = {
- {0x12, 0x80},
- {0x0c, 0x28},
- {0x11, 0x80},
- {0x13, 0xb5},
- {0x14, 0x3e},
- {0x1b, 0x04},
- {0x24, 0xb0},
- {0x25, 0x90},
- {0x26, 0x94},
- {0x35, 0x90},
- {0x37, 0x07},
- {0x38, 0x08},
- {0x01, 0x8e},
- {0x02, 0x85}
-};
-
-/* 7670. Defaults taken from OmniVision provided data,
-* as provided by Jonathan Corbet of OLPC */
-static const struct ov_i2c_regvals norm_7670[] = {
- { OV7670_R12_COM7, OV7670_COM7_RESET },
- { OV7670_R3A_TSLB, 0x04 }, /* OV */
- { OV7670_R12_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
- { OV7670_R11_CLKRC, 0x01 },
-/*
- * Set the hardware window. These values from OV don't entirely
- * make sense - hstop is less than hstart. But they work...
- */
- { OV7670_R17_HSTART, 0x13 },
- { OV7670_R18_HSTOP, 0x01 },
- { OV7670_R32_HREF, 0xb6 },
- { OV7670_R19_VSTART, 0x02 },
- { OV7670_R1A_VSTOP, 0x7a },
- { OV7670_R03_VREF, 0x0a },
-
- { OV7670_R0C_COM3, 0x00 },
- { OV7670_R3E_COM14, 0x00 },
-/* Mystery scaling numbers */
- { 0x70, 0x3a },
- { 0x71, 0x35 },
- { 0x72, 0x11 },
- { 0x73, 0xf0 },
- { 0xa2, 0x02 },
-/* { OV7670_R15_COM10, 0x0 }, */
-
-/* Gamma curve values */
- { 0x7a, 0x20 },
- { 0x7b, 0x10 },
- { 0x7c, 0x1e },
- { 0x7d, 0x35 },
- { 0x7e, 0x5a },
- { 0x7f, 0x69 },
- { 0x80, 0x76 },
- { 0x81, 0x80 },
- { 0x82, 0x88 },
- { 0x83, 0x8f },
- { 0x84, 0x96 },
- { 0x85, 0xa3 },
- { 0x86, 0xaf },
- { 0x87, 0xc4 },
- { 0x88, 0xd7 },
- { 0x89, 0xe8 },
-
-/* AGC and AEC parameters. Note we start by disabling those features,
- then turn them only after tweaking the values. */
- { OV7670_R13_COM8, OV7670_COM8_FASTAEC
- | OV7670_COM8_AECSTEP
- | OV7670_COM8_BFILT },
- { OV7670_R00_GAIN, 0x00 },
- { OV7670_R10_AECH, 0x00 },
- { OV7670_R0D_COM4, 0x40 }, /* magic reserved bit */
- { OV7670_R14_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
- { OV7670_RA5_BD50MAX, 0x05 },
- { OV7670_RAB_BD60MAX, 0x07 },
- { OV7670_R24_AEW, 0x95 },
- { OV7670_R25_AEB, 0x33 },
- { OV7670_R26_VPT, 0xe3 },
- { OV7670_R9F_HAECC1, 0x78 },
- { OV7670_RA0_HAECC2, 0x68 },
- { 0xa1, 0x03 }, /* magic */
- { OV7670_RA6_HAECC3, 0xd8 },
- { OV7670_RA7_HAECC4, 0xd8 },
- { OV7670_RA8_HAECC5, 0xf0 },
- { OV7670_RA9_HAECC6, 0x90 },
- { OV7670_RAA_HAECC7, 0x94 },
- { OV7670_R13_COM8, OV7670_COM8_FASTAEC
- | OV7670_COM8_AECSTEP
- | OV7670_COM8_BFILT
- | OV7670_COM8_AGC
- | OV7670_COM8_AEC },
-
-/* Almost all of these are magic "reserved" values. */
- { OV7670_R0E_COM5, 0x61 },
- { OV7670_R0F_COM6, 0x4b },
- { 0x16, 0x02 },
- { OV7670_R1E_MVFP, 0x07 },
- { 0x21, 0x02 },
- { 0x22, 0x91 },
- { 0x29, 0x07 },
- { 0x33, 0x0b },
- { 0x35, 0x0b },
- { 0x37, 0x1d },
- { 0x38, 0x71 },
- { 0x39, 0x2a },
- { OV7670_R3C_COM12, 0x78 },
- { 0x4d, 0x40 },
- { 0x4e, 0x20 },
- { OV7670_R69_GFIX, 0x00 },
- { 0x6b, 0x4a },
- { 0x74, 0x10 },
- { 0x8d, 0x4f },
- { 0x8e, 0x00 },
- { 0x8f, 0x00 },
- { 0x90, 0x00 },
- { 0x91, 0x00 },
- { 0x96, 0x00 },
- { 0x9a, 0x00 },
- { 0xb0, 0x84 },
- { 0xb1, 0x0c },
- { 0xb2, 0x0e },
- { 0xb3, 0x82 },
- { 0xb8, 0x0a },
-
-/* More reserved magic, some of which tweaks white balance */
- { 0x43, 0x0a },
- { 0x44, 0xf0 },
- { 0x45, 0x34 },
- { 0x46, 0x58 },
- { 0x47, 0x28 },
- { 0x48, 0x3a },
- { 0x59, 0x88 },
- { 0x5a, 0x88 },
- { 0x5b, 0x44 },
- { 0x5c, 0x67 },
- { 0x5d, 0x49 },
- { 0x5e, 0x0e },
- { 0x6c, 0x0a },
- { 0x6d, 0x55 },
- { 0x6e, 0x11 },
- { 0x6f, 0x9f }, /* "9e for advance AWB" */
- { 0x6a, 0x40 },
- { OV7670_R01_BLUE, 0x40 },
- { OV7670_R02_RED, 0x60 },
- { OV7670_R13_COM8, OV7670_COM8_FASTAEC
- | OV7670_COM8_AECSTEP
- | OV7670_COM8_BFILT
- | OV7670_COM8_AGC
- | OV7670_COM8_AEC
- | OV7670_COM8_AWB },
-
-/* Matrix coefficients */
- { 0x4f, 0x80 },
- { 0x50, 0x80 },
- { 0x51, 0x00 },
- { 0x52, 0x22 },
- { 0x53, 0x5e },
- { 0x54, 0x80 },
- { 0x58, 0x9e },
-
- { OV7670_R41_COM16, OV7670_COM16_AWBGAIN },
- { OV7670_R3F_EDGE, 0x00 },
- { 0x75, 0x05 },
- { 0x76, 0xe1 },
- { 0x4c, 0x00 },
- { 0x77, 0x01 },
- { OV7670_R3D_COM13, OV7670_COM13_GAMMA
- | OV7670_COM13_UVSAT
- | 2}, /* was 3 */
- { 0x4b, 0x09 },
- { 0xc9, 0x60 },
- { OV7670_R41_COM16, 0x38 },
- { 0x56, 0x40 },
-
- { 0x34, 0x11 },
- { OV7670_R3B_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
- { 0xa4, 0x88 },
- { 0x96, 0x00 },
- { 0x97, 0x30 },
- { 0x98, 0x20 },
- { 0x99, 0x30 },
- { 0x9a, 0x84 },
- { 0x9b, 0x29 },
- { 0x9c, 0x03 },
- { 0x9d, 0x4c },
- { 0x9e, 0x3f },
- { 0x78, 0x04 },
-
-/* Extra-weird stuff. Some sort of multiplexor register */
- { 0x79, 0x01 },
- { 0xc8, 0xf0 },
- { 0x79, 0x0f },
- { 0xc8, 0x00 },
- { 0x79, 0x10 },
- { 0xc8, 0x7e },
- { 0x79, 0x0a },
- { 0xc8, 0x80 },
- { 0x79, 0x0b },
- { 0xc8, 0x01 },
- { 0x79, 0x0c },
- { 0xc8, 0x0f },
- { 0x79, 0x0d },
- { 0xc8, 0x20 },
- { 0x79, 0x09 },
- { 0xc8, 0x80 },
- { 0x79, 0x02 },
- { 0xc8, 0xc0 },
- { 0x79, 0x03 },
- { 0xc8, 0x40 },
- { 0x79, 0x05 },
- { 0xc8, 0x30 },
- { 0x79, 0x26 },
-};
-
-static const struct ov_i2c_regvals norm_8610[] = {
- { 0x12, 0x80 },
- { 0x00, 0x00 },
- { 0x01, 0x80 },
- { 0x02, 0x80 },
- { 0x03, 0xc0 },
- { 0x04, 0x30 },
- { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
- { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
- { 0x0a, 0x86 },
- { 0x0b, 0xb0 },
- { 0x0c, 0x20 },
- { 0x0d, 0x20 },
- { 0x11, 0x01 },
- { 0x12, 0x25 },
- { 0x13, 0x01 },
- { 0x14, 0x04 },
- { 0x15, 0x01 }, /* Lin and Win think different about UV order */
- { 0x16, 0x03 },
- { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
- { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
- { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
- { 0x1a, 0xf5 },
- { 0x1b, 0x00 },
- { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
- { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
- { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
- { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
- { 0x26, 0xa2 },
- { 0x27, 0xea },
- { 0x28, 0x00 },
- { 0x29, 0x00 },
- { 0x2a, 0x80 },
- { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
- { 0x2c, 0xac },
- { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
- { 0x2e, 0x80 },
- { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
- { 0x4c, 0x00 },
- { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
- { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
- { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
- { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
- { 0x63, 0xff },
- { 0x64, 0x53 }, /* new windrv 090403 says 0x57,
- * maybe thats wrong */
- { 0x65, 0x00 },
- { 0x66, 0x55 },
- { 0x67, 0xb0 },
- { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
- { 0x69, 0x02 },
- { 0x6a, 0x22 },
- { 0x6b, 0x00 },
- { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
- * deleting bit7 colors the first images red */
- { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
- { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
- { 0x6f, 0x01 },
- { 0x70, 0x8b },
- { 0x71, 0x00 },
- { 0x72, 0x14 },
- { 0x73, 0x54 },
- { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
- { 0x75, 0x0e },
- { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
- { 0x77, 0xff },
- { 0x78, 0x80 },
- { 0x79, 0x80 },
- { 0x7a, 0x80 },
- { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
- { 0x7c, 0x00 },
- { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
- { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
- { 0x7f, 0xfb },
- { 0x80, 0x28 },
- { 0x81, 0x00 },
- { 0x82, 0x23 },
- { 0x83, 0x0b },
- { 0x84, 0x00 },
- { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
- { 0x86, 0xc9 },
- { 0x87, 0x00 },
- { 0x88, 0x00 },
- { 0x89, 0x01 },
- { 0x12, 0x20 },
- { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
-};
-
-static unsigned char ov7670_abs_to_sm(unsigned char v)
-{
- if (v > 127)
- return v & 0x7f;
- return (128 - v) | 0x80;
-}
-
-/* Write a OV519 register */
-static void reg_w(struct sd *sd, u16 index, u16 value)
-{
- int ret, req = 0;
-
- if (sd->gspca_dev.usb_err < 0)
- return;
-
- switch (sd->bridge) {
- case BRIDGE_OV511:
- case BRIDGE_OV511PLUS:
- req = 2;
- break;
- case BRIDGE_OVFX2:
- req = 0x0a;
- /* fall through */
- case BRIDGE_W9968CF:
- PDEBUG(D_USBO, "SET %02x %04x %04x",
- req, value, index);
- ret = usb_control_msg(sd->gspca_dev.dev,
- usb_sndctrlpipe(sd->gspca_dev.dev, 0),
- req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, NULL, 0, 500);
- goto leave;
- default:
- req = 1;
- }
-
- PDEBUG(D_USBO, "SET %02x 0000 %04x %02x",
- req, index, value);
- sd->gspca_dev.usb_buf[0] = value;
- ret = usb_control_msg(sd->gspca_dev.dev,
- usb_sndctrlpipe(sd->gspca_dev.dev, 0),
- req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, index,
- sd->gspca_dev.usb_buf, 1, 500);
-leave:
- if (ret < 0) {
- pr_err("reg_w %02x failed %d\n", index, ret);
- sd->gspca_dev.usb_err = ret;
- return;
- }
-}
-
-/* Read from a OV519 register, note not valid for the w9968cf!! */
-/* returns: negative is error, pos or zero is data */
-static int reg_r(struct sd *sd, u16 index)
-{
- int ret;
- int req;
-
- if (sd->gspca_dev.usb_err < 0)
- return -1;
-
- switch (sd->bridge) {
- case BRIDGE_OV511:
- case BRIDGE_OV511PLUS:
- req = 3;
- break;
- case BRIDGE_OVFX2:
- req = 0x0b;
- break;
- default:
- req = 1;
- }
-
- ret = usb_control_msg(sd->gspca_dev.dev,
- usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
- req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, index, sd->gspca_dev.usb_buf, 1, 500);
-
- if (ret >= 0) {
- ret = sd->gspca_dev.usb_buf[0];
- PDEBUG(D_USBI, "GET %02x 0000 %04x %02x",
- req, index, ret);
- } else {
- pr_err("reg_r %02x failed %d\n", index, ret);
- sd->gspca_dev.usb_err = ret;
- }
-
- return ret;
-}
-
-/* Read 8 values from a OV519 register */
-static int reg_r8(struct sd *sd,
- u16 index)
-{
- int ret;
-
- if (sd->gspca_dev.usb_err < 0)
- return -1;
-
- ret = usb_control_msg(sd->gspca_dev.dev,
- usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
- 1, /* REQ_IO */
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, index, sd->gspca_dev.usb_buf, 8, 500);
-
- if (ret >= 0) {
- ret = sd->gspca_dev.usb_buf[0];
- } else {
- pr_err("reg_r8 %02x failed %d\n", index, ret);
- sd->gspca_dev.usb_err = ret;
- }
-
- return ret;
-}
-
-/*
- * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
- * the same position as 1's in "mask" are cleared and set to "value". Bits
- * that are in the same position as 0's in "mask" are preserved, regardless
- * of their respective state in "value".
- */
-static void reg_w_mask(struct sd *sd,
- u16 index,
- u8 value,
- u8 mask)
-{
- int ret;
- u8 oldval;
-
- if (mask != 0xff) {
- value &= mask; /* Enforce mask on value */
- ret = reg_r(sd, index);
- if (ret < 0)
- return;
-
- oldval = ret & ~mask; /* Clear the masked bits */
- value |= oldval; /* Set the desired bits */
- }
- reg_w(sd, index, value);
-}
-
-/*
- * Writes multiple (n) byte value to a single register. Only valid with certain
- * registers (0x30 and 0xc4 - 0xce).
- */
-static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n)
-{
- int ret;
-
- if (sd->gspca_dev.usb_err < 0)
- return;
-
- *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
-
- ret = usb_control_msg(sd->gspca_dev.dev,
- usb_sndctrlpipe(sd->gspca_dev.dev, 0),
- 1 /* REG_IO */,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, index,
- sd->gspca_dev.usb_buf, n, 500);
- if (ret < 0) {
- pr_err("reg_w32 %02x failed %d\n", index, ret);
- sd->gspca_dev.usb_err = ret;
- }
-}
-
-static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value)
-{
- int rc, retries;
-
- PDEBUG(D_USBO, "ov511_i2c_w %02x %02x", reg, value);
-
- /* Three byte write cycle */
- for (retries = 6; ; ) {
- /* Select camera register */
- reg_w(sd, R51x_I2C_SADDR_3, reg);
-
- /* Write "value" to I2C data port of OV511 */
- reg_w(sd, R51x_I2C_DATA, value);
-
- /* Initiate 3-byte write cycle */
- reg_w(sd, R511_I2C_CTL, 0x01);
-
- do {
- rc = reg_r(sd, R511_I2C_CTL);
- } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
-
- if (rc < 0)
- return;
-
- if ((rc & 2) == 0) /* Ack? */
- break;
- if (--retries < 0) {
- PDEBUG(D_USBO, "i2c write retries exhausted");
- return;
- }
- }
-}
-
-static int ov511_i2c_r(struct sd *sd, u8 reg)
-{
- int rc, value, retries;
-
- /* Two byte write cycle */
- for (retries = 6; ; ) {
- /* Select camera register */
- reg_w(sd, R51x_I2C_SADDR_2, reg);
-
- /* Initiate 2-byte write cycle */
- reg_w(sd, R511_I2C_CTL, 0x03);
-
- do {
- rc = reg_r(sd, R511_I2C_CTL);
- } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
-
- if (rc < 0)
- return rc;
-
- if ((rc & 2) == 0) /* Ack? */
- break;
-
- /* I2C abort */
- reg_w(sd, R511_I2C_CTL, 0x10);
-
- if (--retries < 0) {
- PDEBUG(D_USBI, "i2c write retries exhausted");
- return -1;
- }
- }
-
- /* Two byte read cycle */
- for (retries = 6; ; ) {
- /* Initiate 2-byte read cycle */
- reg_w(sd, R511_I2C_CTL, 0x05);
-
- do {
- rc = reg_r(sd, R511_I2C_CTL);
- } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
-
- if (rc < 0)
- return rc;
-
- if ((rc & 2) == 0) /* Ack? */
- break;
-
- /* I2C abort */
- reg_w(sd, R511_I2C_CTL, 0x10);
-
- if (--retries < 0) {
- PDEBUG(D_USBI, "i2c read retries exhausted");
- return -1;
- }
- }
-
- value = reg_r(sd, R51x_I2C_DATA);
-
- PDEBUG(D_USBI, "ov511_i2c_r %02x %02x", reg, value);
-
- /* This is needed to make i2c_w() work */
- reg_w(sd, R511_I2C_CTL, 0x05);
-
- return value;
-}
-
-/*
- * The OV518 I2C I/O procedure is different, hence, this function.
- * This is normally only called from i2c_w(). Note that this function
- * always succeeds regardless of whether the sensor is present and working.
- */
-static void ov518_i2c_w(struct sd *sd,
- u8 reg,
- u8 value)
-{
- PDEBUG(D_USBO, "ov518_i2c_w %02x %02x", reg, value);
-
- /* Select camera register */
- reg_w(sd, R51x_I2C_SADDR_3, reg);
-
- /* Write "value" to I2C data port of OV511 */
- reg_w(sd, R51x_I2C_DATA, value);
-
- /* Initiate 3-byte write cycle */
- reg_w(sd, R518_I2C_CTL, 0x01);
-
- /* wait for write complete */
- msleep(4);
- reg_r8(sd, R518_I2C_CTL);
-}
-
-/*
- * returns: negative is error, pos or zero is data
- *
- * The OV518 I2C I/O procedure is different, hence, this function.
- * This is normally only called from i2c_r(). Note that this function
- * always succeeds regardless of whether the sensor is present and working.
- */
-static int ov518_i2c_r(struct sd *sd, u8 reg)
-{
- int value;
-
- /* Select camera register */
- reg_w(sd, R51x_I2C_SADDR_2, reg);
-
- /* Initiate 2-byte write cycle */
- reg_w(sd, R518_I2C_CTL, 0x03);
- reg_r8(sd, R518_I2C_CTL);
-
- /* Initiate 2-byte read cycle */
- reg_w(sd, R518_I2C_CTL, 0x05);
- reg_r8(sd, R518_I2C_CTL);
-
- value = reg_r(sd, R51x_I2C_DATA);
- PDEBUG(D_USBI, "ov518_i2c_r %02x %02x", reg, value);
- return value;
-}
-
-static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value)
-{
- int ret;
-
- if (sd->gspca_dev.usb_err < 0)
- return;
-
- ret = usb_control_msg(sd->gspca_dev.dev,
- usb_sndctrlpipe(sd->gspca_dev.dev, 0),
- 0x02,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- (u16) value, (u16) reg, NULL, 0, 500);
-
- if (ret < 0) {
- pr_err("ovfx2_i2c_w %02x failed %d\n", reg, ret);
- sd->gspca_dev.usb_err = ret;
- }
-
- PDEBUG(D_USBO, "ovfx2_i2c_w %02x %02x", reg, value);
-}
-
-static int ovfx2_i2c_r(struct sd *sd, u8 reg)
-{
- int ret;
-
- if (sd->gspca_dev.usb_err < 0)
- return -1;
-
- ret = usb_control_msg(sd->gspca_dev.dev,
- usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
- 0x03,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, (u16) reg, sd->gspca_dev.usb_buf, 1, 500);
-
- if (ret >= 0) {
- ret = sd->gspca_dev.usb_buf[0];
- PDEBUG(D_USBI, "ovfx2_i2c_r %02x %02x", reg, ret);
- } else {
- pr_err("ovfx2_i2c_r %02x failed %d\n", reg, ret);
- sd->gspca_dev.usb_err = ret;
- }
-
- return ret;
-}
-
-static void i2c_w(struct sd *sd, u8 reg, u8 value)
-{
- if (sd->sensor_reg_cache[reg] == value)
- return;
-
- switch (sd->bridge) {
- case BRIDGE_OV511:
- case BRIDGE_OV511PLUS:
- ov511_i2c_w(sd, reg, value);
- break;
- case BRIDGE_OV518:
- case BRIDGE_OV518PLUS:
- case BRIDGE_OV519:
- ov518_i2c_w(sd, reg, value);
- break;
- case BRIDGE_OVFX2:
- ovfx2_i2c_w(sd, reg, value);
- break;
- case BRIDGE_W9968CF:
- w9968cf_i2c_w(sd, reg, value);
- break;
- }
-
- if (sd->gspca_dev.usb_err >= 0) {
- /* Up on sensor reset empty the register cache */
- if (reg == 0x12 && (value & 0x80))
- memset(sd->sensor_reg_cache, -1,
- sizeof(sd->sensor_reg_cache));
- else
- sd->sensor_reg_cache[reg] = value;
- }
-}
-
-static int i2c_r(struct sd *sd, u8 reg)
-{
- int ret = -1;
-
- if (sd->sensor_reg_cache[reg] != -1)
- return sd->sensor_reg_cache[reg];
-
- switch (sd->bridge) {
- case BRIDGE_OV511:
- case BRIDGE_OV511PLUS:
- ret = ov511_i2c_r(sd, reg);
- break;
- case BRIDGE_OV518:
- case BRIDGE_OV518PLUS:
- case BRIDGE_OV519:
- ret = ov518_i2c_r(sd, reg);
- break;
- case BRIDGE_OVFX2:
- ret = ovfx2_i2c_r(sd, reg);
- break;
- case BRIDGE_W9968CF:
- ret = w9968cf_i2c_r(sd, reg);
- break;
- }
-
- if (ret >= 0)
- sd->sensor_reg_cache[reg] = ret;
-
- return ret;
-}
-
-/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
- * the same position as 1's in "mask" are cleared and set to "value". Bits
- * that are in the same position as 0's in "mask" are preserved, regardless
- * of their respective state in "value".
- */
-static void i2c_w_mask(struct sd *sd,
- u8 reg,
- u8 value,
- u8 mask)
-{
- int rc;
- u8 oldval;
-
- value &= mask; /* Enforce mask on value */
- rc = i2c_r(sd, reg);
- if (rc < 0)
- return;
- oldval = rc & ~mask; /* Clear the masked bits */
- value |= oldval; /* Set the desired bits */
- i2c_w(sd, reg, value);
-}
-
-/* Temporarily stops OV511 from functioning. Must do this before changing
- * registers while the camera is streaming */
-static inline void ov51x_stop(struct sd *sd)
-{
- PDEBUG(D_STREAM, "stopping");
- sd->stopped = 1;
- switch (sd->bridge) {
- case BRIDGE_OV511:
- case BRIDGE_OV511PLUS:
- reg_w(sd, R51x_SYS_RESET, 0x3d);
- break;
- case BRIDGE_OV518:
- case BRIDGE_OV518PLUS:
- reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
- break;
- case BRIDGE_OV519:
- reg_w(sd, OV519_R51_RESET1, 0x0f);
- reg_w(sd, OV519_R51_RESET1, 0x00);
- reg_w(sd, 0x22, 0x00); /* FRAR */
- break;
- case BRIDGE_OVFX2:
- reg_w_mask(sd, 0x0f, 0x00, 0x02);
- break;
- case BRIDGE_W9968CF:
- reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
- break;
- }
-}
-
-/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
- * actually stopped (for performance). */
-static inline void ov51x_restart(struct sd *sd)
-{
- PDEBUG(D_STREAM, "restarting");
- if (!sd->stopped)
- return;
- sd->stopped = 0;
-
- /* Reinitialize the stream */
- switch (sd->bridge) {
- case BRIDGE_OV511:
- case BRIDGE_OV511PLUS:
- reg_w(sd, R51x_SYS_RESET, 0x00);
- break;
- case BRIDGE_OV518:
- case BRIDGE_OV518PLUS:
- reg_w(sd, 0x2f, 0x80);
- reg_w(sd, R51x_SYS_RESET, 0x00);
- break;
- case BRIDGE_OV519:
- reg_w(sd, OV519_R51_RESET1, 0x0f);
- reg_w(sd, OV519_R51_RESET1, 0x00);
- reg_w(sd, 0x22, 0x1d); /* FRAR */
- break;
- case BRIDGE_OVFX2:
- reg_w_mask(sd, 0x0f, 0x02, 0x02);
- break;
- case BRIDGE_W9968CF:
- reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
- break;
- }
-}
-
-static void ov51x_set_slave_ids(struct sd *sd, u8 slave);
-
-/* This does an initial reset of an OmniVision sensor and ensures that I2C
- * is synchronized. Returns <0 on failure.
- */
-static int init_ov_sensor(struct sd *sd, u8 slave)
-{
- int i;
-
- ov51x_set_slave_ids(sd, slave);
-
- /* Reset the sensor */
- i2c_w(sd, 0x12, 0x80);
-
- /* Wait for it to initialize */
- msleep(150);
-
- for (i = 0; i < i2c_detect_tries; i++) {
- if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
- i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
- PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
- return 0;
- }
-
- /* Reset the sensor */
- i2c_w(sd, 0x12, 0x80);
-
- /* Wait for it to initialize */
- msleep(150);
-
- /* Dummy read to sync I2C */
- if (i2c_r(sd, 0x00) < 0)
- return -1;
- }
- return -1;
-}
-
-/* Set the read and write slave IDs. The "slave" argument is the write slave,
- * and the read slave will be set to (slave + 1).
- * This should not be called from outside the i2c I/O functions.
- * Sets I2C read and write slave IDs. Returns <0 for error
- */
-static void ov51x_set_slave_ids(struct sd *sd,
- u8 slave)
-{
- switch (sd->bridge) {
- case BRIDGE_OVFX2:
- reg_w(sd, OVFX2_I2C_ADDR, slave);
- return;
- case BRIDGE_W9968CF:
- sd->sensor_addr = slave;
- return;
- }
-
- reg_w(sd, R51x_I2C_W_SID, slave);
- reg_w(sd, R51x_I2C_R_SID, slave + 1);
-}
-
-static void write_regvals(struct sd *sd,
- const struct ov_regvals *regvals,
- int n)
-{
- while (--n >= 0) {
- reg_w(sd, regvals->reg, regvals->val);
- regvals++;
- }
-}
-
-static void write_i2c_regvals(struct sd *sd,
- const struct ov_i2c_regvals *regvals,
- int n)
-{
- while (--n >= 0) {
- i2c_w(sd, regvals->reg, regvals->val);
- regvals++;
- }
-}
-
-/****************************************************************************
- *
- * OV511 and sensor configuration
- *
- ***************************************************************************/
-
-/* This initializes the OV2x10 / OV3610 / OV3620 / OV9600 */
-static void ov_hires_configure(struct sd *sd)
-{
- int high, low;
-
- if (sd->bridge != BRIDGE_OVFX2) {
- pr_err("error hires sensors only supported with ovfx2\n");
- return;
- }
-
- PDEBUG(D_PROBE, "starting ov hires configuration");
-
- /* Detect sensor (sub)type */
- high = i2c_r(sd, 0x0a);
- low = i2c_r(sd, 0x0b);
- /* info("%x, %x", high, low); */
- switch (high) {
- case 0x96:
- switch (low) {
- case 0x40:
- PDEBUG(D_PROBE, "Sensor is a OV2610");
- sd->sensor = SEN_OV2610;
- return;
- case 0x41:
- PDEBUG(D_PROBE, "Sensor is a OV2610AE");
- sd->sensor = SEN_OV2610AE;
- return;
- case 0xb1:
- PDEBUG(D_PROBE, "Sensor is a OV9600");
- sd->sensor = SEN_OV9600;
- return;
- }
- break;
- case 0x36:
- if ((low & 0x0f) == 0x00) {
- PDEBUG(D_PROBE, "Sensor is a OV3610");
- sd->sensor = SEN_OV3610;
- return;
- }
- break;
- }
- pr_err("Error unknown sensor type: %02x%02x\n", high, low);
-}
-
-/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
- * the same register settings as the OV8610, since they are very similar.
- */
-static void ov8xx0_configure(struct sd *sd)
-{
- int rc;
-
- PDEBUG(D_PROBE, "starting ov8xx0 configuration");
-
- /* Detect sensor (sub)type */
- rc = i2c_r(sd, OV7610_REG_COM_I);
- if (rc < 0) {
- PDEBUG(D_ERR, "Error detecting sensor type");
- return;
- }
- if ((rc & 3) == 1)
- sd->sensor = SEN_OV8610;
- else
- pr_err("Unknown image sensor version: %d\n", rc & 3);
-}
-
-/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
- * the same register settings as the OV7610, since they are very similar.
- */
-static void ov7xx0_configure(struct sd *sd)
-{
- int rc, high, low;
-
- PDEBUG(D_PROBE, "starting OV7xx0 configuration");
-
- /* Detect sensor (sub)type */
- rc = i2c_r(sd, OV7610_REG_COM_I);
-
- /* add OV7670 here
- * it appears to be wrongly detected as a 7610 by default */
- if (rc < 0) {
- pr_err("Error detecting sensor type\n");
- return;
- }
- if ((rc & 3) == 3) {
- /* quick hack to make OV7670s work */
- high = i2c_r(sd, 0x0a);
- low = i2c_r(sd, 0x0b);
- /* info("%x, %x", high, low); */
- if (high == 0x76 && (low & 0xf0) == 0x70) {
- PDEBUG(D_PROBE, "Sensor is an OV76%02x", low);
- sd->sensor = SEN_OV7670;
- } else {
- PDEBUG(D_PROBE, "Sensor is an OV7610");
- sd->sensor = SEN_OV7610;
- }
- } else if ((rc & 3) == 1) {
- /* I don't know what's different about the 76BE yet. */
- if (i2c_r(sd, 0x15) & 1) {
- PDEBUG(D_PROBE, "Sensor is an OV7620AE");
- sd->sensor = SEN_OV7620AE;
- } else {
- PDEBUG(D_PROBE, "Sensor is an OV76BE");
- sd->sensor = SEN_OV76BE;
- }
- } else if ((rc & 3) == 0) {
- /* try to read product id registers */
- high = i2c_r(sd, 0x0a);
- if (high < 0) {
- pr_err("Error detecting camera chip PID\n");
- return;
- }
- low = i2c_r(sd, 0x0b);
- if (low < 0) {
- pr_err("Error detecting camera chip VER\n");
- return;
- }
- if (high == 0x76) {
- switch (low) {
- case 0x30:
- pr_err("Sensor is an OV7630/OV7635\n");
- pr_err("7630 is not supported by this driver\n");
- return;
- case 0x40:
- PDEBUG(D_PROBE, "Sensor is an OV7645");
- sd->sensor = SEN_OV7640; /* FIXME */
- break;
- case 0x45:
- PDEBUG(D_PROBE, "Sensor is an OV7645B");
- sd->sensor = SEN_OV7640; /* FIXME */
- break;
- case 0x48:
- PDEBUG(D_PROBE, "Sensor is an OV7648");
- sd->sensor = SEN_OV7648;
- break;
- case 0x60:
- PDEBUG(D_PROBE, "Sensor is a OV7660");
- sd->sensor = SEN_OV7660;
- break;
- default:
- pr_err("Unknown sensor: 0x76%02x\n", low);
- return;
- }
- } else {
- PDEBUG(D_PROBE, "Sensor is an OV7620");
- sd->sensor = SEN_OV7620;
- }
- } else {
- pr_err("Unknown image sensor version: %d\n", rc & 3);
- }
-}
-
-/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
-static void ov6xx0_configure(struct sd *sd)
-{
- int rc;
- PDEBUG(D_PROBE, "starting OV6xx0 configuration");
-
- /* Detect sensor (sub)type */
- rc = i2c_r(sd, OV7610_REG_COM_I);
- if (rc < 0) {
- pr_err("Error detecting sensor type\n");
- return;
- }
-
- /* Ugh. The first two bits are the version bits, but
- * the entire register value must be used. I guess OVT
- * underestimated how many variants they would make. */
- switch (rc) {
- case 0x00:
- sd->sensor = SEN_OV6630;
- pr_warn("WARNING: Sensor is an OV66308. Your camera may have been misdetected in previous driver versions.\n");
- break;
- case 0x01:
- sd->sensor = SEN_OV6620;
- PDEBUG(D_PROBE, "Sensor is an OV6620");
- break;
- case 0x02:
- sd->sensor = SEN_OV6630;
- PDEBUG(D_PROBE, "Sensor is an OV66308AE");
- break;
- case 0x03:
- sd->sensor = SEN_OV66308AF;
- PDEBUG(D_PROBE, "Sensor is an OV66308AF");
- break;
- case 0x90:
- sd->sensor = SEN_OV6630;
- pr_warn("WARNING: Sensor is an OV66307. Your camera may have been misdetected in previous driver versions.\n");
- break;
- default:
- pr_err("FATAL: Unknown sensor version: 0x%02x\n", rc);
- return;
- }
-
- /* Set sensor-specific vars */
- sd->sif = 1;
-}
-
-/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
-static void ov51x_led_control(struct sd *sd, int on)
-{
- if (sd->invert_led)
- on = !on;
-
- switch (sd->bridge) {
- /* OV511 has no LED control */
- case BRIDGE_OV511PLUS:
- reg_w(sd, R511_SYS_LED_CTL, on);
- break;
- case BRIDGE_OV518:
- case BRIDGE_OV518PLUS:
- reg_w_mask(sd, R518_GPIO_OUT, 0x02 * on, 0x02);
- break;
- case BRIDGE_OV519:
- reg_w_mask(sd, OV519_GPIO_DATA_OUT0, on, 1);
- break;
- }
-}
-
-static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (!sd->snapshot_needs_reset)
- return;
-
- /* Note it is important that we clear sd->snapshot_needs_reset,
- before actually clearing the snapshot state in the bridge
- otherwise we might race with the pkt_scan interrupt handler */
- sd->snapshot_needs_reset = 0;
-
- switch (sd->bridge) {
- case BRIDGE_OV511:
- case BRIDGE_OV511PLUS:
- reg_w(sd, R51x_SYS_SNAP, 0x02);
- reg_w(sd, R51x_SYS_SNAP, 0x00);
- break;
- case BRIDGE_OV518:
- case BRIDGE_OV518PLUS:
- reg_w(sd, R51x_SYS_SNAP, 0x02); /* Reset */
- reg_w(sd, R51x_SYS_SNAP, 0x01); /* Enable */
- break;
- case BRIDGE_OV519:
- reg_w(sd, R51x_SYS_RESET, 0x40);
- reg_w(sd, R51x_SYS_RESET, 0x00);
- break;
- }
-}
-
-static void ov51x_upload_quan_tables(struct sd *sd)
-{
- const unsigned char yQuanTable511[] = {
- 0, 1, 1, 2, 2, 3, 3, 4,
- 1, 1, 1, 2, 2, 3, 4, 4,
- 1, 1, 2, 2, 3, 4, 4, 4,
- 2, 2, 2, 3, 4, 4, 4, 4,
- 2, 2, 3, 4, 4, 5, 5, 5,
- 3, 3, 4, 4, 5, 5, 5, 5,
- 3, 4, 4, 4, 5, 5, 5, 5,
- 4, 4, 4, 4, 5, 5, 5, 5
- };
-
- const unsigned char uvQuanTable511[] = {
- 0, 2, 2, 3, 4, 4, 4, 4,
- 2, 2, 2, 4, 4, 4, 4, 4,
- 2, 2, 3, 4, 4, 4, 4, 4,
- 3, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4
- };
-
- /* OV518 quantization tables are 8x4 (instead of 8x8) */
- const unsigned char yQuanTable518[] = {
- 5, 4, 5, 6, 6, 7, 7, 7,
- 5, 5, 5, 5, 6, 7, 7, 7,
- 6, 6, 6, 6, 7, 7, 7, 8,
- 7, 7, 6, 7, 7, 7, 8, 8
- };
- const unsigned char uvQuanTable518[] = {
- 6, 6, 6, 7, 7, 7, 7, 7,
- 6, 6, 6, 7, 7, 7, 7, 7,
- 6, 6, 6, 7, 7, 7, 7, 8,
- 7, 7, 7, 7, 7, 7, 8, 8
- };
-
- const unsigned char *pYTable, *pUVTable;
- unsigned char val0, val1;
- int i, size, reg = R51x_COMP_LUT_BEGIN;
-
- PDEBUG(D_PROBE, "Uploading quantization tables");
-
- if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
- pYTable = yQuanTable511;
- pUVTable = uvQuanTable511;
- size = 32;
- } else {
- pYTable = yQuanTable518;
- pUVTable = uvQuanTable518;
- size = 16;
- }
-
- for (i = 0; i < size; i++) {
- val0 = *pYTable++;
- val1 = *pYTable++;
- val0 &= 0x0f;
- val1 &= 0x0f;
- val0 |= val1 << 4;
- reg_w(sd, reg, val0);
-
- val0 = *pUVTable++;
- val1 = *pUVTable++;
- val0 &= 0x0f;
- val1 &= 0x0f;
- val0 |= val1 << 4;
- reg_w(sd, reg + size, val0);
-
- reg++;
- }
-}
-
-/* This initializes the OV511/OV511+ and the sensor */
-static void ov511_configure(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* For 511 and 511+ */
- const struct ov_regvals init_511[] = {
- { R51x_SYS_RESET, 0x7f },
- { R51x_SYS_INIT, 0x01 },
- { R51x_SYS_RESET, 0x7f },
- { R51x_SYS_INIT, 0x01 },
- { R51x_SYS_RESET, 0x3f },
- { R51x_SYS_INIT, 0x01 },
- { R51x_SYS_RESET, 0x3d },
- };
-
- const struct ov_regvals norm_511[] = {
- { R511_DRAM_FLOW_CTL, 0x01 },
- { R51x_SYS_SNAP, 0x00 },
- { R51x_SYS_SNAP, 0x02 },
- { R51x_SYS_SNAP, 0x00 },
- { R511_FIFO_OPTS, 0x1f },
- { R511_COMP_EN, 0x00 },
- { R511_COMP_LUT_EN, 0x03 },
- };
-
- const struct ov_regvals norm_511_p[] = {
- { R511_DRAM_FLOW_CTL, 0xff },
- { R51x_SYS_SNAP, 0x00 },
- { R51x_SYS_SNAP, 0x02 },
- { R51x_SYS_SNAP, 0x00 },
- { R511_FIFO_OPTS, 0xff },
- { R511_COMP_EN, 0x00 },
- { R511_COMP_LUT_EN, 0x03 },
- };
-
- const struct ov_regvals compress_511[] = {
- { 0x70, 0x1f },
- { 0x71, 0x05 },
- { 0x72, 0x06 },
- { 0x73, 0x06 },
- { 0x74, 0x14 },
- { 0x75, 0x03 },
- { 0x76, 0x04 },
- { 0x77, 0x04 },
- };
-
- PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
-
- write_regvals(sd, init_511, ARRAY_SIZE(init_511));
-
- switch (sd->bridge) {
- case BRIDGE_OV511:
- write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
- break;
- case BRIDGE_OV511PLUS:
- write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
- break;
- }
-
- /* Init compression */
- write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
-
- ov51x_upload_quan_tables(sd);
-}
-
-/* This initializes the OV518/OV518+ and the sensor */
-static void ov518_configure(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* For 518 and 518+ */
- const struct ov_regvals init_518[] = {
- { R51x_SYS_RESET, 0x40 },
- { R51x_SYS_INIT, 0xe1 },
- { R51x_SYS_RESET, 0x3e },
- { R51x_SYS_INIT, 0xe1 },
- { R51x_SYS_RESET, 0x00 },
- { R51x_SYS_INIT, 0xe1 },
- { 0x46, 0x00 },
- { 0x5d, 0x03 },
- };
-
- const struct ov_regvals norm_518[] = {
- { R51x_SYS_SNAP, 0x02 }, /* Reset */
- { R51x_SYS_SNAP, 0x01 }, /* Enable */
- { 0x31, 0x0f },
- { 0x5d, 0x03 },
- { 0x24, 0x9f },
- { 0x25, 0x90 },
- { 0x20, 0x00 },
- { 0x51, 0x04 },
- { 0x71, 0x19 },
- { 0x2f, 0x80 },
- };
-
- const struct ov_regvals norm_518_p[] = {
- { R51x_SYS_SNAP, 0x02 }, /* Reset */
- { R51x_SYS_SNAP, 0x01 }, /* Enable */
- { 0x31, 0x0f },
- { 0x5d, 0x03 },
- { 0x24, 0x9f },
- { 0x25, 0x90 },
- { 0x20, 0x60 },
- { 0x51, 0x02 },
- { 0x71, 0x19 },
- { 0x40, 0xff },
- { 0x41, 0x42 },
- { 0x46, 0x00 },
- { 0x33, 0x04 },
- { 0x21, 0x19 },
- { 0x3f, 0x10 },
- { 0x2f, 0x80 },
- };
-
- /* First 5 bits of custom ID reg are a revision ID on OV518 */
- PDEBUG(D_PROBE, "Device revision %d",
- 0x1f & reg_r(sd, R51x_SYS_CUST_ID));
-
- write_regvals(sd, init_518, ARRAY_SIZE(init_518));
-
- /* Set LED GPIO pin to output mode */
- reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
-
- switch (sd->bridge) {
- case BRIDGE_OV518:
- write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
- break;
- case BRIDGE_OV518PLUS:
- write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
- break;
- }
-
- ov51x_upload_quan_tables(sd);
-
- reg_w(sd, 0x2f, 0x80);
-}
-
-static void ov519_configure(struct sd *sd)
-{
- static const struct ov_regvals init_519[] = {
- { 0x5a, 0x6d }, /* EnableSystem */
- { 0x53, 0x9b }, /* don't enable the microcontroller */
- { OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */
- { 0x5d, 0x03 },
- { 0x49, 0x01 },
- { 0x48, 0x00 },
- /* Set LED pin to output mode. Bit 4 must be cleared or sensor
- * detection will fail. This deserves further investigation. */
- { OV519_GPIO_IO_CTRL0, 0xee },
- { OV519_R51_RESET1, 0x0f },
- { OV519_R51_RESET1, 0x00 },
- { 0x22, 0x00 },
- /* windows reads 0x55 at this point*/
- };
-
- write_regvals(sd, init_519, ARRAY_SIZE(init_519));
-}
-
-static void ovfx2_configure(struct sd *sd)
-{
- static const struct ov_regvals init_fx2[] = {
- { 0x00, 0x60 },
- { 0x02, 0x01 },
- { 0x0f, 0x1d },
- { 0xe9, 0x82 },
- { 0xea, 0xc7 },
- { 0xeb, 0x10 },
- { 0xec, 0xf6 },
- };
-
- sd->stopped = 1;
-
- write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
-}
-
-/* set the mode */
-/* This function works for ov7660 only */
-static void ov519_set_mode(struct sd *sd)
-{
- static const struct ov_regvals bridge_ov7660[2][10] = {
- {{0x10, 0x14}, {0x11, 0x1e}, {0x12, 0x00}, {0x13, 0x00},
- {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
- {0x25, 0x01}, {0x26, 0x00}},
- {{0x10, 0x28}, {0x11, 0x3c}, {0x12, 0x00}, {0x13, 0x00},
- {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
- {0x25, 0x03}, {0x26, 0x00}}
- };
- static const struct ov_i2c_regvals sensor_ov7660[2][3] = {
- {{0x12, 0x00}, {0x24, 0x00}, {0x0c, 0x0c}},
- {{0x12, 0x00}, {0x04, 0x00}, {0x0c, 0x00}}
- };
- static const struct ov_i2c_regvals sensor_ov7660_2[] = {
- {OV7670_R17_HSTART, 0x13},
- {OV7670_R18_HSTOP, 0x01},
- {OV7670_R32_HREF, 0x92},
- {OV7670_R19_VSTART, 0x02},
- {OV7670_R1A_VSTOP, 0x7a},
- {OV7670_R03_VREF, 0x00},
-/* {0x33, 0x00}, */
-/* {0x34, 0x07}, */
-/* {0x36, 0x00}, */
-/* {0x6b, 0x0a}, */
- };
-
- write_regvals(sd, bridge_ov7660[sd->gspca_dev.curr_mode],
- ARRAY_SIZE(bridge_ov7660[0]));
- write_i2c_regvals(sd, sensor_ov7660[sd->gspca_dev.curr_mode],
- ARRAY_SIZE(sensor_ov7660[0]));
- write_i2c_regvals(sd, sensor_ov7660_2,
- ARRAY_SIZE(sensor_ov7660_2));
-}
-
-/* set the frame rate */
-/* This function works for sensors ov7640, ov7648 ov7660 and ov7670 only */
-static void ov519_set_fr(struct sd *sd)
-{
- int fr;
- u8 clock;
- /* frame rate table with indices:
- * - mode = 0: 320x240, 1: 640x480
- * - fr rate = 0: 30, 1: 25, 2: 20, 3: 15, 4: 10, 5: 5
- * - reg = 0: bridge a4, 1: bridge 23, 2: sensor 11 (clock)
- */
- static const u8 fr_tb[2][6][3] = {
- {{0x04, 0xff, 0x00},
- {0x04, 0x1f, 0x00},
- {0x04, 0x1b, 0x00},
- {0x04, 0x15, 0x00},
- {0x04, 0x09, 0x00},
- {0x04, 0x01, 0x00}},
- {{0x0c, 0xff, 0x00},
- {0x0c, 0x1f, 0x00},
- {0x0c, 0x1b, 0x00},
- {0x04, 0xff, 0x01},
- {0x04, 0x1f, 0x01},
- {0x04, 0x1b, 0x01}},
- };
-
- if (frame_rate > 0)
- sd->frame_rate = frame_rate;
- if (sd->frame_rate >= 30)
- fr = 0;
- else if (sd->frame_rate >= 25)
- fr = 1;
- else if (sd->frame_rate >= 20)
- fr = 2;
- else if (sd->frame_rate >= 15)
- fr = 3;
- else if (sd->frame_rate >= 10)
- fr = 4;
- else
- fr = 5;
- reg_w(sd, 0xa4, fr_tb[sd->gspca_dev.curr_mode][fr][0]);
- reg_w(sd, 0x23, fr_tb[sd->gspca_dev.curr_mode][fr][1]);
- clock = fr_tb[sd->gspca_dev.curr_mode][fr][2];
- if (sd->sensor == SEN_OV7660)
- clock |= 0x80; /* enable double clock */
- ov518_i2c_w(sd, OV7670_R11_CLKRC, clock);
-}
-
-static void setautogain(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- i2c_w_mask(sd, 0x13, val ? 0x05 : 0x00, 0x05);
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam = &gspca_dev->cam;
-
- sd->bridge = id->driver_info & BRIDGE_MASK;
- sd->invert_led = (id->driver_info & BRIDGE_INVERT_LED) != 0;
-
- switch (sd->bridge) {
- case BRIDGE_OV511:
- case BRIDGE_OV511PLUS:
- cam->cam_mode = ov511_vga_mode;
- cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
- break;
- case BRIDGE_OV518:
- case BRIDGE_OV518PLUS:
- cam->cam_mode = ov518_vga_mode;
- cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
- break;
- case BRIDGE_OV519:
- cam->cam_mode = ov519_vga_mode;
- cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
- break;
- case BRIDGE_OVFX2:
- cam->cam_mode = ov519_vga_mode;
- cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
- cam->bulk_size = OVFX2_BULK_SIZE;
- cam->bulk_nurbs = MAX_NURBS;
- cam->bulk = 1;
- break;
- case BRIDGE_W9968CF:
- cam->cam_mode = w9968cf_vga_mode;
- cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
- break;
- }
-
- sd->frame_rate = 15;
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam = &gspca_dev->cam;
-
- switch (sd->bridge) {
- case BRIDGE_OV511:
- case BRIDGE_OV511PLUS:
- ov511_configure(gspca_dev);
- break;
- case BRIDGE_OV518:
- case BRIDGE_OV518PLUS:
- ov518_configure(gspca_dev);
- break;
- case BRIDGE_OV519:
- ov519_configure(sd);
- break;
- case BRIDGE_OVFX2:
- ovfx2_configure(sd);
- break;
- case BRIDGE_W9968CF:
- w9968cf_configure(sd);
- break;
- }
-
- /* The OV519 must be more aggressive about sensor detection since
- * I2C write will never fail if the sensor is not present. We have
- * to try to initialize the sensor to detect its presence */
- sd->sensor = -1;
-
- /* Test for 76xx */
- if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
- ov7xx0_configure(sd);
-
- /* Test for 6xx0 */
- } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
- ov6xx0_configure(sd);
-
- /* Test for 8xx0 */
- } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
- ov8xx0_configure(sd);
-
- /* Test for 3xxx / 2xxx */
- } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
- ov_hires_configure(sd);
- } else {
- pr_err("Can't determine sensor slave IDs\n");
- goto error;
- }
-
- if (sd->sensor < 0)
- goto error;
-
- ov51x_led_control(sd, 0); /* turn LED off */
-
- switch (sd->bridge) {
- case BRIDGE_OV511:
- case BRIDGE_OV511PLUS:
- if (sd->sif) {
- cam->cam_mode = ov511_sif_mode;
- cam->nmodes = ARRAY_SIZE(ov511_sif_mode);
- }
- break;
- case BRIDGE_OV518:
- case BRIDGE_OV518PLUS:
- if (sd->sif) {
- cam->cam_mode = ov518_sif_mode;
- cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
- }
- break;
- case BRIDGE_OV519:
- if (sd->sif) {
- cam->cam_mode = ov519_sif_mode;
- cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
- }
- break;
- case BRIDGE_OVFX2:
- switch (sd->sensor) {
- case SEN_OV2610:
- case SEN_OV2610AE:
- cam->cam_mode = ovfx2_ov2610_mode;
- cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
- break;
- case SEN_OV3610:
- cam->cam_mode = ovfx2_ov3610_mode;
- cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
- break;
- case SEN_OV9600:
- cam->cam_mode = ovfx2_ov9600_mode;
- cam->nmodes = ARRAY_SIZE(ovfx2_ov9600_mode);
- break;
- default:
- if (sd->sif) {
- cam->cam_mode = ov519_sif_mode;
- cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
- }
- break;
- }
- break;
- case BRIDGE_W9968CF:
- if (sd->sif)
- cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode) - 1;
-
- /* w9968cf needs initialisation once the sensor is known */
- w9968cf_init(sd);
- break;
- }
-
- /* initialize the sensor */
- switch (sd->sensor) {
- case SEN_OV2610:
- write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610));
-
- /* Enable autogain, autoexpo, awb, bandfilter */
- i2c_w_mask(sd, 0x13, 0x27, 0x27);
- break;
- case SEN_OV2610AE:
- write_i2c_regvals(sd, norm_2610ae, ARRAY_SIZE(norm_2610ae));
-
- /* enable autoexpo */
- i2c_w_mask(sd, 0x13, 0x05, 0x05);
- break;
- case SEN_OV3610:
- write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b));
-
- /* Enable autogain, autoexpo, awb, bandfilter */
- i2c_w_mask(sd, 0x13, 0x27, 0x27);
- break;
- case SEN_OV6620:
- write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20));
- break;
- case SEN_OV6630:
- case SEN_OV66308AF:
- write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30));
- break;
- default:
-/* case SEN_OV7610: */
-/* case SEN_OV76BE: */
- write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610));
- i2c_w_mask(sd, 0x0e, 0x00, 0x40);
- break;
- case SEN_OV7620:
- case SEN_OV7620AE:
- write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620));
- break;
- case SEN_OV7640:
- case SEN_OV7648:
- write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640));
- break;
- case SEN_OV7660:
- i2c_w(sd, OV7670_R12_COM7, OV7670_COM7_RESET);
- msleep(14);
- reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
- write_regvals(sd, init_519_ov7660,
- ARRAY_SIZE(init_519_ov7660));
- write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660));
- sd->gspca_dev.curr_mode = 1; /* 640x480 */
- ov519_set_mode(sd);
- ov519_set_fr(sd);
- sd_reset_snapshot(gspca_dev);
- ov51x_restart(sd);
- ov51x_stop(sd); /* not in win traces */
- ov51x_led_control(sd, 0);
- break;
- case SEN_OV7670:
- write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670));
- break;
- case SEN_OV8610:
- write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610));
- break;
- case SEN_OV9600:
- write_i2c_regvals(sd, norm_9600, ARRAY_SIZE(norm_9600));
-
- /* enable autoexpo */
-/* i2c_w_mask(sd, 0x13, 0x05, 0x05); */
- break;
- }
- return gspca_dev->usb_err;
-error:
- PDEBUG(D_ERR, "OV519 Config failed");
- return -EINVAL;
-}
-
-/* function called at start time before URB creation */
-static int sd_isoc_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->bridge) {
- case BRIDGE_OVFX2:
- if (gspca_dev->width != 800)
- gspca_dev->cam.bulk_size = OVFX2_BULK_SIZE;
- else
- gspca_dev->cam.bulk_size = 7 * 4096;
- break;
- }
- return 0;
-}
-
-/* Set up the OV511/OV511+ with the given image parameters.
- *
- * Do not put any sensor-specific code in here (including I2C I/O functions)
- */
-static void ov511_mode_init_regs(struct sd *sd)
-{
- int hsegs, vsegs, packet_size, fps, needed;
- int interlaced = 0;
- struct usb_host_interface *alt;
- struct usb_interface *intf;
-
- intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
- alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
- if (!alt) {
- pr_err("Couldn't get altsetting\n");
- sd->gspca_dev.usb_err = -EIO;
- return;
- }
-
- packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
- reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
-
- reg_w(sd, R511_CAM_UV_EN, 0x01);
- reg_w(sd, R511_SNAP_UV_EN, 0x01);
- reg_w(sd, R511_SNAP_OPTS, 0x03);
-
- /* Here I'm assuming that snapshot size == image size.
- * I hope that's always true. --claudio
- */
- hsegs = (sd->gspca_dev.width >> 3) - 1;
- vsegs = (sd->gspca_dev.height >> 3) - 1;
-
- reg_w(sd, R511_CAM_PXCNT, hsegs);
- reg_w(sd, R511_CAM_LNCNT, vsegs);
- reg_w(sd, R511_CAM_PXDIV, 0x00);
- reg_w(sd, R511_CAM_LNDIV, 0x00);
-
- /* YUV420, low pass filter on */
- reg_w(sd, R511_CAM_OPTS, 0x03);
-
- /* Snapshot additions */
- reg_w(sd, R511_SNAP_PXCNT, hsegs);
- reg_w(sd, R511_SNAP_LNCNT, vsegs);
- reg_w(sd, R511_SNAP_PXDIV, 0x00);
- reg_w(sd, R511_SNAP_LNDIV, 0x00);
-
- /******** Set the framerate ********/
- if (frame_rate > 0)
- sd->frame_rate = frame_rate;
-
- switch (sd->sensor) {
- case SEN_OV6620:
- /* No framerate control, doesn't like higher rates yet */
- sd->clockdiv = 3;
- break;
-
- /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed
- for more sensors we need to do this for them too */
- case SEN_OV7620:
- case SEN_OV7620AE:
- case SEN_OV7640:
- case SEN_OV7648:
- case SEN_OV76BE:
- if (sd->gspca_dev.width == 320)
- interlaced = 1;
- /* Fall through */
- case SEN_OV6630:
- case SEN_OV7610:
- case SEN_OV7670:
- switch (sd->frame_rate) {
- case 30:
- case 25:
- /* Not enough bandwidth to do 640x480 @ 30 fps */
- if (sd->gspca_dev.width != 640) {
- sd->clockdiv = 0;
- break;
- }
- /* Fall through for 640x480 case */
- default:
-/* case 20: */
-/* case 15: */
- sd->clockdiv = 1;
- break;
- case 10:
- sd->clockdiv = 2;
- break;
- case 5:
- sd->clockdiv = 5;
- break;
- }
- if (interlaced) {
- sd->clockdiv = (sd->clockdiv + 1) * 2 - 1;
- /* Higher then 10 does not work */
- if (sd->clockdiv > 10)
- sd->clockdiv = 10;
- }
- break;
-
- case SEN_OV8610:
- /* No framerate control ?? */
- sd->clockdiv = 0;
- break;
- }
-
- /* Check if we have enough bandwidth to disable compression */
- fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1;
- needed = fps * sd->gspca_dev.width * sd->gspca_dev.height * 3 / 2;
- /* 1000 isoc packets/sec */
- if (needed > 1000 * packet_size) {
- /* Enable Y and UV quantization and compression */
- reg_w(sd, R511_COMP_EN, 0x07);
- reg_w(sd, R511_COMP_LUT_EN, 0x03);
- } else {
- reg_w(sd, R511_COMP_EN, 0x06);
- reg_w(sd, R511_COMP_LUT_EN, 0x00);
- }
-
- reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE);
- reg_w(sd, R51x_SYS_RESET, 0);
-}
-
-/* Sets up the OV518/OV518+ with the given image parameters
- *
- * OV518 needs a completely different approach, until we can figure out what
- * the individual registers do. Also, only 15 FPS is supported now.
- *
- * Do not put any sensor-specific code in here (including I2C I/O functions)
- */
-static void ov518_mode_init_regs(struct sd *sd)
-{
- int hsegs, vsegs, packet_size;
- struct usb_host_interface *alt;
- struct usb_interface *intf;
-
- intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
- alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
- if (!alt) {
- pr_err("Couldn't get altsetting\n");
- sd->gspca_dev.usb_err = -EIO;
- return;
- }
-
- packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
- ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
-
- /******** Set the mode ********/
- reg_w(sd, 0x2b, 0);
- reg_w(sd, 0x2c, 0);
- reg_w(sd, 0x2d, 0);
- reg_w(sd, 0x2e, 0);
- reg_w(sd, 0x3b, 0);
- reg_w(sd, 0x3c, 0);
- reg_w(sd, 0x3d, 0);
- reg_w(sd, 0x3e, 0);
-
- if (sd->bridge == BRIDGE_OV518) {
- /* Set 8-bit (YVYU) input format */
- reg_w_mask(sd, 0x20, 0x08, 0x08);
-
- /* Set 12-bit (4:2:0) output format */
- reg_w_mask(sd, 0x28, 0x80, 0xf0);
- reg_w_mask(sd, 0x38, 0x80, 0xf0);
- } else {
- reg_w(sd, 0x28, 0x80);
- reg_w(sd, 0x38, 0x80);
- }
-
- hsegs = sd->gspca_dev.width / 16;
- vsegs = sd->gspca_dev.height / 4;
-
- reg_w(sd, 0x29, hsegs);
- reg_w(sd, 0x2a, vsegs);
-
- reg_w(sd, 0x39, hsegs);
- reg_w(sd, 0x3a, vsegs);
-
- /* Windows driver does this here; who knows why */
- reg_w(sd, 0x2f, 0x80);
-
- /******** Set the framerate ********/
- sd->clockdiv = 1;
-
- /* Mode independent, but framerate dependent, regs */
- /* 0x51: Clock divider; Only works on some cams which use 2 crystals */
- reg_w(sd, 0x51, 0x04);
- reg_w(sd, 0x22, 0x18);
- reg_w(sd, 0x23, 0xff);
-
- if (sd->bridge == BRIDGE_OV518PLUS) {
- switch (sd->sensor) {
- case SEN_OV7620AE:
- if (sd->gspca_dev.width == 320) {
- reg_w(sd, 0x20, 0x00);
- reg_w(sd, 0x21, 0x19);
- } else {
- reg_w(sd, 0x20, 0x60);
- reg_w(sd, 0x21, 0x1f);
- }
- break;
- case SEN_OV7620:
- reg_w(sd, 0x20, 0x00);
- reg_w(sd, 0x21, 0x19);
- break;
- default:
- reg_w(sd, 0x21, 0x19);
- }
- } else
- reg_w(sd, 0x71, 0x17); /* Compression-related? */
-
- /* FIXME: Sensor-specific */
- /* Bit 5 is what matters here. Of course, it is "reserved" */
- i2c_w(sd, 0x54, 0x23);
-
- reg_w(sd, 0x2f, 0x80);
-
- if (sd->bridge == BRIDGE_OV518PLUS) {
- reg_w(sd, 0x24, 0x94);
- reg_w(sd, 0x25, 0x90);
- ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
- ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */
- ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */
- ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */
- ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */
- ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */
- ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */
- ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */
- ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */
- } else {
- reg_w(sd, 0x24, 0x9f);
- reg_w(sd, 0x25, 0x90);
- ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
- ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */
- ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */
- ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */
- ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */
- ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */
- ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */
- ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */
- ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */
- }
-
- reg_w(sd, 0x2f, 0x80);
-}
-
-/* Sets up the OV519 with the given image parameters
- *
- * OV519 needs a completely different approach, until we can figure out what
- * the individual registers do.
- *
- * Do not put any sensor-specific code in here (including I2C I/O functions)
- */
-static void ov519_mode_init_regs(struct sd *sd)
-{
- static const struct ov_regvals mode_init_519_ov7670[] = {
- { 0x5d, 0x03 }, /* Turn off suspend mode */
- { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
- { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
- { 0xa2, 0x20 }, /* a2-a5 are undocumented */
- { 0xa3, 0x18 },
- { 0xa4, 0x04 },
- { 0xa5, 0x28 },
- { 0x37, 0x00 }, /* SetUsbInit */
- { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
- /* Enable both fields, YUV Input, disable defect comp (why?) */
- { 0x20, 0x0c },
- { 0x21, 0x38 },
- { 0x22, 0x1d },
- { 0x17, 0x50 }, /* undocumented */
- { 0x37, 0x00 }, /* undocumented */
- { 0x40, 0xff }, /* I2C timeout counter */
- { 0x46, 0x00 }, /* I2C clock prescaler */
- { 0x59, 0x04 }, /* new from windrv 090403 */
- { 0xff, 0x00 }, /* undocumented */
- /* windows reads 0x55 at this point, why? */
- };
-
- static const struct ov_regvals mode_init_519[] = {
- { 0x5d, 0x03 }, /* Turn off suspend mode */
- { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
- { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
- { 0xa2, 0x20 }, /* a2-a5 are undocumented */
- { 0xa3, 0x18 },
- { 0xa4, 0x04 },
- { 0xa5, 0x28 },
- { 0x37, 0x00 }, /* SetUsbInit */
- { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
- /* Enable both fields, YUV Input, disable defect comp (why?) */
- { 0x22, 0x1d },
- { 0x17, 0x50 }, /* undocumented */
- { 0x37, 0x00 }, /* undocumented */
- { 0x40, 0xff }, /* I2C timeout counter */
- { 0x46, 0x00 }, /* I2C clock prescaler */
- { 0x59, 0x04 }, /* new from windrv 090403 */
- { 0xff, 0x00 }, /* undocumented */
- /* windows reads 0x55 at this point, why? */
- };
-
- /******** Set the mode ********/
- switch (sd->sensor) {
- default:
- write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519));
- if (sd->sensor == SEN_OV7640 ||
- sd->sensor == SEN_OV7648) {
- /* Select 8-bit input mode */
- reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
- }
- break;
- case SEN_OV7660:
- return; /* done by ov519_set_mode/fr() */
- case SEN_OV7670:
- write_regvals(sd, mode_init_519_ov7670,
- ARRAY_SIZE(mode_init_519_ov7670));
- break;
- }
-
- reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
- reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.height >> 3);
- if (sd->sensor == SEN_OV7670 &&
- sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
- reg_w(sd, OV519_R12_X_OFFSETL, 0x04);
- else if (sd->sensor == SEN_OV7648 &&
- sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
- reg_w(sd, OV519_R12_X_OFFSETL, 0x01);
- else
- reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
- reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
- reg_w(sd, OV519_R14_Y_OFFSETL, 0x00);
- reg_w(sd, OV519_R15_Y_OFFSETH, 0x00);
- reg_w(sd, OV519_R16_DIVIDER, 0x00);
- reg_w(sd, OV519_R25_FORMAT, 0x03); /* YUV422 */
- reg_w(sd, 0x26, 0x00); /* Undocumented */
-
- /******** Set the framerate ********/
- if (frame_rate > 0)
- sd->frame_rate = frame_rate;
-
-/* FIXME: These are only valid at the max resolution. */
- sd->clockdiv = 0;
- switch (sd->sensor) {
- case SEN_OV7640:
- case SEN_OV7648:
- switch (sd->frame_rate) {
- default:
-/* case 30: */
- reg_w(sd, 0xa4, 0x0c);
- reg_w(sd, 0x23, 0xff);
- break;
- case 25:
- reg_w(sd, 0xa4, 0x0c);
- reg_w(sd, 0x23, 0x1f);
- break;
- case 20:
- reg_w(sd, 0xa4, 0x0c);
- reg_w(sd, 0x23, 0x1b);
- break;
- case 15:
- reg_w(sd, 0xa4, 0x04);
- reg_w(sd, 0x23, 0xff);
- sd->clockdiv = 1;
- break;
- case 10:
- reg_w(sd, 0xa4, 0x04);
- reg_w(sd, 0x23, 0x1f);
- sd->clockdiv = 1;
- break;
- case 5:
- reg_w(sd, 0xa4, 0x04);
- reg_w(sd, 0x23, 0x1b);
- sd->clockdiv = 1;
- break;
- }
- break;
- case SEN_OV8610:
- switch (sd->frame_rate) {
- default: /* 15 fps */
-/* case 15: */
- reg_w(sd, 0xa4, 0x06);
- reg_w(sd, 0x23, 0xff);
- break;
- case 10:
- reg_w(sd, 0xa4, 0x06);
- reg_w(sd, 0x23, 0x1f);
- break;
- case 5:
- reg_w(sd, 0xa4, 0x06);
- reg_w(sd, 0x23, 0x1b);
- break;
- }
- break;
- case SEN_OV7670: /* guesses, based on 7640 */
- PDEBUG(D_STREAM, "Setting framerate to %d fps",
- (sd->frame_rate == 0) ? 15 : sd->frame_rate);
- reg_w(sd, 0xa4, 0x10);
- switch (sd->frame_rate) {
- case 30:
- reg_w(sd, 0x23, 0xff);
- break;
- case 20:
- reg_w(sd, 0x23, 0x1b);
- break;
- default:
-/* case 15: */
- reg_w(sd, 0x23, 0xff);
- sd->clockdiv = 1;
- break;
- }
- break;
- }
-}
-
-static void mode_init_ov_sensor_regs(struct sd *sd)
-{
- struct gspca_dev *gspca_dev;
- int qvga, xstart, xend, ystart, yend;
- u8 v;
-
- gspca_dev = &sd->gspca_dev;
- qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
-
- /******** Mode (VGA/QVGA) and sensor specific regs ********/
- switch (sd->sensor) {
- case SEN_OV2610:
- i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
- i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
- i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
- i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
- i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
- i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
- i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
- return;
- case SEN_OV2610AE: {
- u8 v;
-
- /* frame rates:
- * 10fps / 5 fps for 1600x1200
- * 40fps / 20fps for 800x600
- */
- v = 80;
- if (qvga) {
- if (sd->frame_rate < 25)
- v = 0x81;
- } else {
- if (sd->frame_rate < 10)
- v = 0x81;
- }
- i2c_w(sd, 0x11, v);
- i2c_w(sd, 0x12, qvga ? 0x60 : 0x20);
- return;
- }
- case SEN_OV3610:
- if (qvga) {
- xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
- ystart = (776 - gspca_dev->height) / 2;
- } else {
- xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4);
- ystart = (1544 - gspca_dev->height) / 2;
- }
- xend = xstart + gspca_dev->width;
- yend = ystart + gspca_dev->height;
- /* Writing to the COMH register resets the other windowing regs
- to their default values, so we must do this first. */
- i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
- i2c_w_mask(sd, 0x32,
- (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
- 0x3f);
- i2c_w_mask(sd, 0x03,
- (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
- 0x0f);
- i2c_w(sd, 0x17, xstart >> 4);
- i2c_w(sd, 0x18, xend >> 4);
- i2c_w(sd, 0x19, ystart >> 3);
- i2c_w(sd, 0x1a, yend >> 3);
- return;
- case SEN_OV8610:
- /* For OV8610 qvga means qsvga */
- i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
- i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
- i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
- i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */
- i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */
- break;
- case SEN_OV7610:
- i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
- i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
- i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
- i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
- break;
- case SEN_OV7620:
- case SEN_OV7620AE:
- case SEN_OV76BE:
- i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
- i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
- i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
- i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
- i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
- i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
- i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
- i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
- i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
- if (sd->sensor == SEN_OV76BE)
- i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
- break;
- case SEN_OV7640:
- case SEN_OV7648:
- i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
- i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
- /* Setting this undocumented bit in qvga mode removes a very
- annoying vertical shaking of the image */
- i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
- /* Unknown */
- i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
- /* Allow higher automatic gain (to allow higher framerates) */
- i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
- i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
- break;
- case SEN_OV7670:
- /* set COM7_FMT_VGA or COM7_FMT_QVGA
- * do we need to set anything else?
- * HSTART etc are set in set_ov_sensor_window itself */
- i2c_w_mask(sd, OV7670_R12_COM7,
- qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
- OV7670_COM7_FMT_MASK);
- i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
- i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_AWB,
- OV7670_COM8_AWB);
- if (qvga) { /* QVGA from ov7670.c by
- * Jonathan Corbet */
- xstart = 164;
- xend = 28;
- ystart = 14;
- yend = 494;
- } else { /* VGA */
- xstart = 158;
- xend = 14;
- ystart = 10;
- yend = 490;
- }
- /* OV7670 hardware window registers are split across
- * multiple locations */
- i2c_w(sd, OV7670_R17_HSTART, xstart >> 3);
- i2c_w(sd, OV7670_R18_HSTOP, xend >> 3);
- v = i2c_r(sd, OV7670_R32_HREF);
- v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
- msleep(10); /* need to sleep between read and write to
- * same reg! */
- i2c_w(sd, OV7670_R32_HREF, v);
-
- i2c_w(sd, OV7670_R19_VSTART, ystart >> 2);
- i2c_w(sd, OV7670_R1A_VSTOP, yend >> 2);
- v = i2c_r(sd, OV7670_R03_VREF);
- v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
- msleep(10); /* need to sleep between read and write to
- * same reg! */
- i2c_w(sd, OV7670_R03_VREF, v);
- break;
- case SEN_OV6620:
- i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
- i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
- i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
- break;
- case SEN_OV6630:
- case SEN_OV66308AF:
- i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
- i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
- break;
- case SEN_OV9600: {
- const struct ov_i2c_regvals *vals;
- static const struct ov_i2c_regvals sxga_15[] = {
- {0x11, 0x80}, {0x14, 0x3e}, {0x24, 0x85}, {0x25, 0x75}
- };
- static const struct ov_i2c_regvals sxga_7_5[] = {
- {0x11, 0x81}, {0x14, 0x3e}, {0x24, 0x85}, {0x25, 0x75}
- };
- static const struct ov_i2c_regvals vga_30[] = {
- {0x11, 0x81}, {0x14, 0x7e}, {0x24, 0x70}, {0x25, 0x60}
- };
- static const struct ov_i2c_regvals vga_15[] = {
- {0x11, 0x83}, {0x14, 0x3e}, {0x24, 0x80}, {0x25, 0x70}
- };
-
- /* frame rates:
- * 15fps / 7.5 fps for 1280x1024
- * 30fps / 15fps for 640x480
- */
- i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0x40);
- if (qvga)
- vals = sd->frame_rate < 30 ? vga_15 : vga_30;
- else
- vals = sd->frame_rate < 15 ? sxga_7_5 : sxga_15;
- write_i2c_regvals(sd, vals, ARRAY_SIZE(sxga_15));
- return;
- }
- default:
- return;
- }
-
- /******** Clock programming ********/
- i2c_w(sd, 0x11, sd->clockdiv);
-}
-
-/* this function works for bridge ov519 and sensors ov7660 and ov7670 only */
-static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->gspca_dev.streaming)
- reg_w(sd, OV519_R51_RESET1, 0x0f); /* block stream */
- i2c_w_mask(sd, OV7670_R1E_MVFP,
- OV7670_MVFP_MIRROR * hflip | OV7670_MVFP_VFLIP * vflip,
- OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
- if (sd->gspca_dev.streaming)
- reg_w(sd, OV519_R51_RESET1, 0x00); /* restart stream */
-}
-
-static void set_ov_sensor_window(struct sd *sd)
-{
- struct gspca_dev *gspca_dev;
- int qvga, crop;
- int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
-
- /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
- switch (sd->sensor) {
- case SEN_OV2610:
- case SEN_OV2610AE:
- case SEN_OV3610:
- case SEN_OV7670:
- case SEN_OV9600:
- mode_init_ov_sensor_regs(sd);
- return;
- case SEN_OV7660:
- ov519_set_mode(sd);
- ov519_set_fr(sd);
- return;
- }
-
- gspca_dev = &sd->gspca_dev;
- qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
- crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2;
-
- /* The different sensor ICs handle setting up of window differently.
- * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
- switch (sd->sensor) {
- case SEN_OV8610:
- hwsbase = 0x1e;
- hwebase = 0x1e;
- vwsbase = 0x02;
- vwebase = 0x02;
- break;
- case SEN_OV7610:
- case SEN_OV76BE:
- hwsbase = 0x38;
- hwebase = 0x3a;
- vwsbase = vwebase = 0x05;
- break;
- case SEN_OV6620:
- case SEN_OV6630:
- case SEN_OV66308AF:
- hwsbase = 0x38;
- hwebase = 0x3a;
- vwsbase = 0x05;
- vwebase = 0x06;
- if (sd->sensor == SEN_OV66308AF && qvga)
- /* HDG: this fixes U and V getting swapped */
- hwsbase++;
- if (crop) {
- hwsbase += 8;
- hwebase += 8;
- vwsbase += 11;
- vwebase += 11;
- }
- break;
- case SEN_OV7620:
- case SEN_OV7620AE:
- hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
- hwebase = 0x2f;
- vwsbase = vwebase = 0x05;
- break;
- case SEN_OV7640:
- case SEN_OV7648:
- hwsbase = 0x1a;
- hwebase = 0x1a;
- vwsbase = vwebase = 0x03;
- break;
- default:
- return;
- }
-
- switch (sd->sensor) {
- case SEN_OV6620:
- case SEN_OV6630:
- case SEN_OV66308AF:
- if (qvga) { /* QCIF */
- hwscale = 0;
- vwscale = 0;
- } else { /* CIF */
- hwscale = 1;
- vwscale = 1; /* The datasheet says 0;
- * it's wrong */
- }
- break;
- case SEN_OV8610:
- if (qvga) { /* QSVGA */
- hwscale = 1;
- vwscale = 1;
- } else { /* SVGA */
- hwscale = 2;
- vwscale = 2;
- }
- break;
- default: /* SEN_OV7xx0 */
- if (qvga) { /* QVGA */
- hwscale = 1;
- vwscale = 0;
- } else { /* VGA */
- hwscale = 2;
- vwscale = 1;
- }
- }
-
- mode_init_ov_sensor_regs(sd);
-
- i2c_w(sd, 0x17, hwsbase);
- i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
- i2c_w(sd, 0x19, vwsbase);
- i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* Default for most bridges, allow bridge_mode_init_regs to override */
- sd->sensor_width = sd->gspca_dev.width;
- sd->sensor_height = sd->gspca_dev.height;
-
- switch (sd->bridge) {
- case BRIDGE_OV511:
- case BRIDGE_OV511PLUS:
- ov511_mode_init_regs(sd);
- break;
- case BRIDGE_OV518:
- case BRIDGE_OV518PLUS:
- ov518_mode_init_regs(sd);
- break;
- case BRIDGE_OV519:
- ov519_mode_init_regs(sd);
- break;
- /* case BRIDGE_OVFX2: nothing to do */
- case BRIDGE_W9968CF:
- w9968cf_mode_init_regs(sd);
- break;
- }
-
- set_ov_sensor_window(sd);
-
- /* Force clear snapshot state in case the snapshot button was
- pressed while we weren't streaming */
- sd->snapshot_needs_reset = 1;
- sd_reset_snapshot(gspca_dev);
-
- sd->first_frame = 3;
-
- ov51x_restart(sd);
- ov51x_led_control(sd, 1);
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- ov51x_stop(sd);
- ov51x_led_control(sd, 0);
-}
-
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (!sd->gspca_dev.present)
- return;
- if (sd->bridge == BRIDGE_W9968CF)
- w9968cf_stop0(sd);
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- /* If the last button state is pressed, release it now! */
- if (sd->snapshot_pressed) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
- input_sync(gspca_dev->input_dev);
- sd->snapshot_pressed = 0;
- }
-#endif
- if (sd->bridge == BRIDGE_OV519)
- reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
-}
-
-static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->snapshot_pressed != state) {
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
- input_sync(gspca_dev->input_dev);
-#endif
- if (state)
- sd->snapshot_needs_reset = 1;
-
- sd->snapshot_pressed = state;
- } else {
- /* On the ov511 / ov519 we need to reset the button state
- multiple times, as resetting does not work as long as the
- button stays pressed */
- switch (sd->bridge) {
- case BRIDGE_OV511:
- case BRIDGE_OV511PLUS:
- case BRIDGE_OV519:
- if (state)
- sd->snapshot_needs_reset = 1;
- break;
- }
- }
-}
-
-static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *in, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
- * byte non-zero. The EOF packet has image width/height in the
- * 10th and 11th bytes. The 9th byte is given as follows:
- *
- * bit 7: EOF
- * 6: compression enabled
- * 5: 422/420/400 modes
- * 4: 422/420/400 modes
- * 3: 1
- * 2: snapshot button on
- * 1: snapshot frame
- * 0: even/odd field
- */
- if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) &&
- (in[8] & 0x08)) {
- ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1);
- if (in[8] & 0x80) {
- /* Frame end */
- if ((in[9] + 1) * 8 != gspca_dev->width ||
- (in[10] + 1) * 8 != gspca_dev->height) {
- PDEBUG(D_ERR, "Invalid frame size, got: %dx%d,"
- " requested: %dx%d\n",
- (in[9] + 1) * 8, (in[10] + 1) * 8,
- gspca_dev->width, gspca_dev->height);
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
- /* Add 11 byte footer to frame, might be useful */
- gspca_frame_add(gspca_dev, LAST_PACKET, in, 11);
- return;
- } else {
- /* Frame start */
- gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0);
- sd->packet_nr = 0;
- }
- }
-
- /* Ignore the packet number */
- len--;
-
- /* intermediate packet */
- gspca_frame_add(gspca_dev, INTER_PACKET, in, len);
-}
-
-static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* A false positive here is likely, until OVT gives me
- * the definitive SOF/EOF format */
- if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
- ov51x_handle_button(gspca_dev, (data[6] >> 1) & 1);
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
- gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
- sd->packet_nr = 0;
- }
-
- if (gspca_dev->last_packet_type == DISCARD_PACKET)
- return;
-
- /* Does this device use packet numbers ? */
- if (len & 7) {
- len--;
- if (sd->packet_nr == data[len])
- sd->packet_nr++;
- /* The last few packets of the frame (which are all 0's
- except that they may contain part of the footer), are
- numbered 0 */
- else if (sd->packet_nr == 0 || data[len]) {
- PDEBUG(D_ERR, "Invalid packet nr: %d (expect: %d)",
- (int)data[len], (int)sd->packet_nr);
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
- }
-
- /* intermediate packet */
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- /* Header of ov519 is 16 bytes:
- * Byte Value Description
- * 0 0xff magic
- * 1 0xff magic
- * 2 0xff magic
- * 3 0xXX 0x50 = SOF, 0x51 = EOF
- * 9 0xXX 0x01 initial frame without data,
- * 0x00 standard frame with image
- * 14 Lo in EOF: length of image data / 8
- * 15 Hi
- */
-
- if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) {
- switch (data[3]) {
- case 0x50: /* start of frame */
- /* Don't check the button state here, as the state
- usually (always ?) changes at EOF and checking it
- here leads to unnecessary snapshot state resets. */
-#define HDRSZ 16
- data += HDRSZ;
- len -= HDRSZ;
-#undef HDRSZ
- if (data[0] == 0xff || data[1] == 0xd8)
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- data, len);
- else
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- case 0x51: /* end of frame */
- ov51x_handle_button(gspca_dev, data[11] & 1);
- if (data[9] != 0)
- gspca_dev->last_packet_type = DISCARD_PACKET;
- gspca_frame_add(gspca_dev, LAST_PACKET,
- NULL, 0);
- return;
- }
- }
-
- /* intermediate packet */
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-
- /* A short read signals EOF */
- if (len < gspca_dev->cam.bulk_size) {
- /* If the frame is short, and it is one of the first ones
- the sensor and bridge are still syncing, so drop it. */
- if (sd->first_frame) {
- sd->first_frame--;
- if (gspca_dev->image_len <
- sd->gspca_dev.width * sd->gspca_dev.height)
- gspca_dev->last_packet_type = DISCARD_PACKET;
- }
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
- gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
- }
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->bridge) {
- case BRIDGE_OV511:
- case BRIDGE_OV511PLUS:
- ov511_pkt_scan(gspca_dev, data, len);
- break;
- case BRIDGE_OV518:
- case BRIDGE_OV518PLUS:
- ov518_pkt_scan(gspca_dev, data, len);
- break;
- case BRIDGE_OV519:
- ov519_pkt_scan(gspca_dev, data, len);
- break;
- case BRIDGE_OVFX2:
- ovfx2_pkt_scan(gspca_dev, data, len);
- break;
- case BRIDGE_W9968CF:
- w9968cf_pkt_scan(gspca_dev, data, len);
- break;
- }
-}
-
-/* -- management routines -- */
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- static const struct ov_i2c_regvals brit_7660[][7] = {
- {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90},
- {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}},
- {{0x0f, 0x6a}, {0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa1},
- {0x27, 0xc0}, {0x28, 0xc0}, {0x2c, 0xc0}},
- {{0x0f, 0x6a}, {0x24, 0x68}, {0x25, 0x58}, {0x26, 0xc2},
- {0x27, 0xa0}, {0x28, 0xa0}, {0x2c, 0xa0}},
- {{0x0f, 0x6a}, {0x24, 0x70}, {0x25, 0x68}, {0x26, 0xd3},
- {0x27, 0x80}, {0x28, 0x80}, {0x2c, 0x80}},
- {{0x0f, 0x6a}, {0x24, 0x80}, {0x25, 0x70}, {0x26, 0xd3},
- {0x27, 0x20}, {0x28, 0x20}, {0x2c, 0x20}},
- {{0x0f, 0x6a}, {0x24, 0x88}, {0x25, 0x78}, {0x26, 0xd3},
- {0x27, 0x40}, {0x28, 0x40}, {0x2c, 0x40}},
- {{0x0f, 0x6a}, {0x24, 0x90}, {0x25, 0x80}, {0x26, 0xd4},
- {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}}
- };
-
- switch (sd->sensor) {
- case SEN_OV8610:
- case SEN_OV7610:
- case SEN_OV76BE:
- case SEN_OV6620:
- case SEN_OV6630:
- case SEN_OV66308AF:
- case SEN_OV7640:
- case SEN_OV7648:
- i2c_w(sd, OV7610_REG_BRT, val);
- break;
- case SEN_OV7620:
- case SEN_OV7620AE:
- i2c_w(sd, OV7610_REG_BRT, val);
- break;
- case SEN_OV7660:
- write_i2c_regvals(sd, brit_7660[val],
- ARRAY_SIZE(brit_7660[0]));
- break;
- case SEN_OV7670:
-/*win trace
- * i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */
- i2c_w(sd, OV7670_R55_BRIGHT, ov7670_abs_to_sm(val));
- break;
- }
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- static const struct ov_i2c_regvals contrast_7660[][31] = {
- {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0},
- {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30},
- {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x24}, {0x77, 0x24},
- {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x34},
- {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x65},
- {0x80, 0x70}, {0x81, 0x77}, {0x82, 0x7d}, {0x83, 0x83},
- {0x84, 0x88}, {0x85, 0x8d}, {0x86, 0x96}, {0x87, 0x9f},
- {0x88, 0xb0}, {0x89, 0xc4}, {0x8a, 0xd9}},
- {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0x94},
- {0x70, 0x58}, {0x71, 0x40}, {0x72, 0x30}, {0x73, 0x30},
- {0x74, 0x30}, {0x75, 0x30}, {0x76, 0x2c}, {0x77, 0x24},
- {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x31},
- {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x62},
- {0x80, 0x6d}, {0x81, 0x75}, {0x82, 0x7b}, {0x83, 0x81},
- {0x84, 0x87}, {0x85, 0x8d}, {0x86, 0x98}, {0x87, 0xa1},
- {0x88, 0xb2}, {0x89, 0xc6}, {0x8a, 0xdb}},
- {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x84},
- {0x70, 0x58}, {0x71, 0x48}, {0x72, 0x40}, {0x73, 0x40},
- {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x28}, {0x77, 0x24},
- {0x78, 0x26}, {0x79, 0x28}, {0x7a, 0x28}, {0x7b, 0x34},
- {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x5d},
- {0x80, 0x68}, {0x81, 0x71}, {0x82, 0x79}, {0x83, 0x81},
- {0x84, 0x86}, {0x85, 0x8b}, {0x86, 0x95}, {0x87, 0x9e},
- {0x88, 0xb1}, {0x89, 0xc5}, {0x8a, 0xd9}},
- {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x70},
- {0x70, 0x58}, {0x71, 0x58}, {0x72, 0x48}, {0x73, 0x48},
- {0x74, 0x38}, {0x75, 0x40}, {0x76, 0x34}, {0x77, 0x34},
- {0x78, 0x2e}, {0x79, 0x28}, {0x7a, 0x24}, {0x7b, 0x22},
- {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x58},
- {0x80, 0x63}, {0x81, 0x6e}, {0x82, 0x77}, {0x83, 0x80},
- {0x84, 0x87}, {0x85, 0x8f}, {0x86, 0x9c}, {0x87, 0xa9},
- {0x88, 0xc0}, {0x89, 0xd4}, {0x8a, 0xe6}},
- {{0x6c, 0xa0}, {0x6d, 0xf0}, {0x6e, 0x90}, {0x6f, 0x80},
- {0x70, 0x70}, {0x71, 0x80}, {0x72, 0x60}, {0x73, 0x60},
- {0x74, 0x58}, {0x75, 0x60}, {0x76, 0x4c}, {0x77, 0x38},
- {0x78, 0x38}, {0x79, 0x2a}, {0x7a, 0x20}, {0x7b, 0x0e},
- {0x7c, 0x0a}, {0x7d, 0x14}, {0x7e, 0x26}, {0x7f, 0x46},
- {0x80, 0x54}, {0x81, 0x64}, {0x82, 0x70}, {0x83, 0x7c},
- {0x84, 0x87}, {0x85, 0x93}, {0x86, 0xa6}, {0x87, 0xb4},
- {0x88, 0xd0}, {0x89, 0xe5}, {0x8a, 0xf5}},
- {{0x6c, 0x60}, {0x6d, 0x80}, {0x6e, 0x60}, {0x6f, 0x80},
- {0x70, 0x80}, {0x71, 0x80}, {0x72, 0x88}, {0x73, 0x30},
- {0x74, 0x70}, {0x75, 0x68}, {0x76, 0x64}, {0x77, 0x50},
- {0x78, 0x3c}, {0x79, 0x22}, {0x7a, 0x10}, {0x7b, 0x08},
- {0x7c, 0x06}, {0x7d, 0x0e}, {0x7e, 0x1a}, {0x7f, 0x3a},
- {0x80, 0x4a}, {0x81, 0x5a}, {0x82, 0x6b}, {0x83, 0x7b},
- {0x84, 0x89}, {0x85, 0x96}, {0x86, 0xaf}, {0x87, 0xc3},
- {0x88, 0xe1}, {0x89, 0xf2}, {0x8a, 0xfa}},
- {{0x6c, 0x20}, {0x6d, 0x40}, {0x6e, 0x20}, {0x6f, 0x60},
- {0x70, 0x88}, {0x71, 0xc8}, {0x72, 0xc0}, {0x73, 0xb8},
- {0x74, 0xa8}, {0x75, 0xb8}, {0x76, 0x80}, {0x77, 0x5c},
- {0x78, 0x26}, {0x79, 0x10}, {0x7a, 0x08}, {0x7b, 0x04},
- {0x7c, 0x02}, {0x7d, 0x06}, {0x7e, 0x0a}, {0x7f, 0x22},
- {0x80, 0x33}, {0x81, 0x4c}, {0x82, 0x64}, {0x83, 0x7b},
- {0x84, 0x90}, {0x85, 0xa7}, {0x86, 0xc7}, {0x87, 0xde},
- {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}},
- };
-
- switch (sd->sensor) {
- case SEN_OV7610:
- case SEN_OV6620:
- i2c_w(sd, OV7610_REG_CNT, val);
- break;
- case SEN_OV6630:
- case SEN_OV66308AF:
- i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
- break;
- case SEN_OV8610: {
- static const u8 ctab[] = {
- 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
- };
-
- /* Use Y gamma control instead. Bit 0 enables it. */
- i2c_w(sd, 0x64, ctab[val >> 5]);
- break;
- }
- case SEN_OV7620:
- case SEN_OV7620AE: {
- static const u8 ctab[] = {
- 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
- 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
- };
-
- /* Use Y gamma control instead. Bit 0 enables it. */
- i2c_w(sd, 0x64, ctab[val >> 4]);
- break;
- }
- case SEN_OV7660:
- write_i2c_regvals(sd, contrast_7660[val],
- ARRAY_SIZE(contrast_7660[0]));
- break;
- case SEN_OV7670:
- /* check that this isn't just the same as ov7610 */
- i2c_w(sd, OV7670_R56_CONTRAS, val >> 1);
- break;
- }
-}
-
-static void setexposure(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- i2c_w(sd, 0x10, val);
-}
-
-static void setcolors(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- static const struct ov_i2c_regvals colors_7660[][6] = {
- {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a},
- {0x53, 0x19}, {0x54, 0x23}},
- {{0x4f, 0x47}, {0x50, 0x4a}, {0x51, 0x03}, {0x52, 0x11},
- {0x53, 0x2c}, {0x54, 0x3e}},
- {{0x4f, 0x66}, {0x50, 0x6b}, {0x51, 0x05}, {0x52, 0x19},
- {0x53, 0x40}, {0x54, 0x59}},
- {{0x4f, 0x84}, {0x50, 0x8b}, {0x51, 0x06}, {0x52, 0x20},
- {0x53, 0x53}, {0x54, 0x73}},
- {{0x4f, 0xa3}, {0x50, 0xab}, {0x51, 0x08}, {0x52, 0x28},
- {0x53, 0x66}, {0x54, 0x8e}},
- };
-
- switch (sd->sensor) {
- case SEN_OV8610:
- case SEN_OV7610:
- case SEN_OV76BE:
- case SEN_OV6620:
- case SEN_OV6630:
- case SEN_OV66308AF:
- i2c_w(sd, OV7610_REG_SAT, val);
- break;
- case SEN_OV7620:
- case SEN_OV7620AE:
- /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
-/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e);
- if (rc < 0)
- goto out; */
- i2c_w(sd, OV7610_REG_SAT, val);
- break;
- case SEN_OV7640:
- case SEN_OV7648:
- i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
- break;
- case SEN_OV7660:
- write_i2c_regvals(sd, colors_7660[val],
- ARRAY_SIZE(colors_7660[0]));
- break;
- case SEN_OV7670:
- /* supported later once I work out how to do it
- * transparently fail now! */
- /* set REG_COM13 values for UV sat auto mode */
- break;
- }
-}
-
-static void setautobright(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- i2c_w_mask(sd, 0x2d, val ? 0x10 : 0x00, 0x10);
-}
-
-static void setfreq_i(struct sd *sd, s32 val)
-{
- if (sd->sensor == SEN_OV7660
- || sd->sensor == SEN_OV7670) {
- switch (val) {
- case 0: /* Banding filter disabled */
- i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT);
- break;
- case 1: /* 50 hz */
- i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
- OV7670_COM8_BFILT);
- i2c_w_mask(sd, OV7670_R3B_COM11, 0x08, 0x18);
- break;
- case 2: /* 60 hz */
- i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
- OV7670_COM8_BFILT);
- i2c_w_mask(sd, OV7670_R3B_COM11, 0x00, 0x18);
- break;
- case 3: /* Auto hz - ov7670 only */
- i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
- OV7670_COM8_BFILT);
- i2c_w_mask(sd, OV7670_R3B_COM11, OV7670_COM11_HZAUTO,
- 0x18);
- break;
- }
- } else {
- switch (val) {
- case 0: /* Banding filter disabled */
- i2c_w_mask(sd, 0x2d, 0x00, 0x04);
- i2c_w_mask(sd, 0x2a, 0x00, 0x80);
- break;
- case 1: /* 50 hz (filter on and framerate adj) */
- i2c_w_mask(sd, 0x2d, 0x04, 0x04);
- i2c_w_mask(sd, 0x2a, 0x80, 0x80);
- /* 20 fps -> 16.667 fps */
- if (sd->sensor == SEN_OV6620 ||
- sd->sensor == SEN_OV6630 ||
- sd->sensor == SEN_OV66308AF)
- i2c_w(sd, 0x2b, 0x5e);
- else
- i2c_w(sd, 0x2b, 0xac);
- break;
- case 2: /* 60 hz (filter on, ...) */
- i2c_w_mask(sd, 0x2d, 0x04, 0x04);
- if (sd->sensor == SEN_OV6620 ||
- sd->sensor == SEN_OV6630 ||
- sd->sensor == SEN_OV66308AF) {
- /* 20 fps -> 15 fps */
- i2c_w_mask(sd, 0x2a, 0x80, 0x80);
- i2c_w(sd, 0x2b, 0xa8);
- } else {
- /* no framerate adj. */
- i2c_w_mask(sd, 0x2a, 0x00, 0x80);
- }
- break;
- }
- }
-}
-
-static void setfreq(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- setfreq_i(sd, val);
-
- /* Ugly but necessary */
- if (sd->bridge == BRIDGE_W9968CF)
- w9968cf_set_crop_window(sd);
-}
-
-static int sd_get_jcomp(struct gspca_dev *gspca_dev,
- struct v4l2_jpegcompression *jcomp)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->bridge != BRIDGE_W9968CF)
- return -ENOTTY;
-
- memset(jcomp, 0, sizeof *jcomp);
- jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
- jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT |
- V4L2_JPEG_MARKER_DRI;
- return 0;
-}
-
-static int sd_set_jcomp(struct gspca_dev *gspca_dev,
- struct v4l2_jpegcompression *jcomp)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->bridge != BRIDGE_W9968CF)
- return -ENOTTY;
-
- v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
- return 0;
-}
-
-static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTOGAIN:
- gspca_dev->exposure->val = i2c_r(sd, 0x10);
- break;
- }
- return 0;
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY:
- setfreq(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_AUTOBRIGHTNESS:
- if (ctrl->is_new)
- setautobright(gspca_dev, ctrl->val);
- if (!ctrl->val && sd->brightness->is_new)
- setbrightness(gspca_dev, sd->brightness->val);
- break;
- case V4L2_CID_SATURATION:
- setcolors(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_HFLIP:
- sethvflip(gspca_dev, ctrl->val, sd->vflip->val);
- break;
- case V4L2_CID_AUTOGAIN:
- if (ctrl->is_new)
- setautogain(gspca_dev, ctrl->val);
- if (!ctrl->val && gspca_dev->exposure->is_new)
- setexposure(gspca_dev, gspca_dev->exposure->val);
- break;
- case V4L2_CID_JPEG_COMPRESSION_QUALITY:
- return -EBUSY; /* Should never happen, as we grab the ctrl */
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .g_volatile_ctrl = sd_g_volatile_ctrl,
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 10);
- if (valid_controls[sd->sensor].has_brightness)
- sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0,
- sd->sensor == SEN_OV7660 ? 6 : 255, 1,
- sd->sensor == SEN_OV7660 ? 3 : 127);
- if (valid_controls[sd->sensor].has_contrast) {
- if (sd->sensor == SEN_OV7660)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 6, 1, 3);
- else
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1,
- (sd->sensor == SEN_OV6630 ||
- sd->sensor == SEN_OV66308AF) ? 200 : 127);
- }
- if (valid_controls[sd->sensor].has_sat)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0,
- sd->sensor == SEN_OV7660 ? 4 : 255, 1,
- sd->sensor == SEN_OV7660 ? 2 : 127);
- if (valid_controls[sd->sensor].has_exposure)
- gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 255, 1, 127);
- if (valid_controls[sd->sensor].has_hvflip) {
- sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- }
- if (valid_controls[sd->sensor].has_autobright)
- sd->autobright = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOBRIGHTNESS, 0, 1, 1, 1);
- if (valid_controls[sd->sensor].has_autogain)
- gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- if (valid_controls[sd->sensor].has_freq) {
- if (sd->sensor == SEN_OV7670)
- sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
- V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
- V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
- else
- sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
- V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0);
- }
- if (sd->bridge == BRIDGE_W9968CF)
- sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_JPEG_COMPRESSION_QUALITY,
- QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- if (gspca_dev->autogain)
- v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, true);
- if (sd->autobright)
- v4l2_ctrl_auto_cluster(2, &sd->autobright, 0, false);
- if (sd->hflip)
- v4l2_ctrl_cluster(2, &sd->hflip);
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .isoc_init = sd_isoc_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
- .dq_callback = sd_reset_snapshot,
- .get_jcomp = sd_get_jcomp,
- .set_jcomp = sd_set_jcomp,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .other_input = 1,
-#endif
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
- {USB_DEVICE(0x041e, 0x4052),
- .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
- {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x045e, 0x028c),
- .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
- {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
- {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
- {USB_DEVICE(0x05a9, 0x0519),
- .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
- {USB_DEVICE(0x05a9, 0x0530),
- .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
- {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
- {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
- {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
- {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
- {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
- {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
- {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
- {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
- {USB_DEVICE(0x8020, 0xef04), .driver_info = BRIDGE_OVFX2 },
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
-
-module_param(frame_rate, int, 0644);
-MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
deleted file mode 100644
index bb09d7884b8..00000000000
--- a/drivers/media/video/gspca/ov534.c
+++ /dev/null
@@ -1,1544 +0,0 @@
-/*
- * ov534-ov7xxx gspca driver
- *
- * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
- * Copyright (C) 2008 Jim Paris <jim@jtan.com>
- * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr
- *
- * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
- * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
- * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
- *
- * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr
- * PS3 Eye camera - brightness, contrast, awb, agc, aec controls
- * added by Max Thrun <bear24rw@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "ov534"
-
-#include "gspca.h"
-
-#include <linux/fixp-arith.h>
-#include <media/v4l2-ctrls.h>
-
-#define OV534_REG_ADDRESS 0xf1 /* sensor address */
-#define OV534_REG_SUBADDR 0xf2
-#define OV534_REG_WRITE 0xf3
-#define OV534_REG_READ 0xf4
-#define OV534_REG_OPERATION 0xf5
-#define OV534_REG_STATUS 0xf6
-
-#define OV534_OP_WRITE_3 0x37
-#define OV534_OP_WRITE_2 0x33
-#define OV534_OP_READ_2 0xf9
-
-#define CTRL_TIMEOUT 500
-
-MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
-MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- struct v4l2_ctrl_handler ctrl_handler;
- struct v4l2_ctrl *hue;
- struct v4l2_ctrl *saturation;
- struct v4l2_ctrl *brightness;
- struct v4l2_ctrl *contrast;
- struct { /* gain control cluster */
- struct v4l2_ctrl *autogain;
- struct v4l2_ctrl *gain;
- };
- struct v4l2_ctrl *autowhitebalance;
- struct { /* exposure control cluster */
- struct v4l2_ctrl *autoexposure;
- struct v4l2_ctrl *exposure;
- };
- struct v4l2_ctrl *sharpness;
- struct v4l2_ctrl *hflip;
- struct v4l2_ctrl *vflip;
- struct v4l2_ctrl *plfreq;
-
- __u32 last_pts;
- u16 last_fid;
- u8 frame_rate;
-
- u8 sensor;
-};
-enum sensors {
- SENSOR_OV767x,
- SENSOR_OV772x,
- NSENSORS
-};
-
-static int sd_start(struct gspca_dev *gspca_dev);
-static void sd_stopN(struct gspca_dev *gspca_dev);
-
-
-static const struct v4l2_pix_format ov772x_mode[] = {
- {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 320 * 2,
- .sizeimage = 320 * 240 * 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 640 * 2,
- .sizeimage = 640 * 480 * 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-static const struct v4l2_pix_format ov767x_mode[] = {
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG},
-};
-
-static const u8 qvga_rates[] = {125, 100, 75, 60, 50, 40, 30};
-static const u8 vga_rates[] = {60, 50, 40, 30, 15};
-
-static const struct framerates ov772x_framerates[] = {
- { /* 320x240 */
- .rates = qvga_rates,
- .nrates = ARRAY_SIZE(qvga_rates),
- },
- { /* 640x480 */
- .rates = vga_rates,
- .nrates = ARRAY_SIZE(vga_rates),
- },
-};
-
-struct reg_array {
- const u8 (*val)[2];
- int len;
-};
-
-static const u8 bridge_init_767x[][2] = {
-/* comments from the ms-win file apollo7670.set */
-/* str1 */
- {0xf1, 0x42},
- {0x88, 0xf8},
- {0x89, 0xff},
- {0x76, 0x03},
- {0x92, 0x03},
- {0x95, 0x10},
- {0xe2, 0x00},
- {0xe7, 0x3e},
- {0x8d, 0x1c},
- {0x8e, 0x00},
- {0x8f, 0x00},
- {0x1f, 0x00},
- {0xc3, 0xf9},
- {0x89, 0xff},
- {0x88, 0xf8},
- {0x76, 0x03},
- {0x92, 0x01},
- {0x93, 0x18},
- {0x1c, 0x00},
- {0x1d, 0x48},
- {0x1d, 0x00},
- {0x1d, 0xff},
- {0x1d, 0x02},
- {0x1d, 0x58},
- {0x1d, 0x00},
- {0x1c, 0x0a},
- {0x1d, 0x0a},
- {0x1d, 0x0e},
- {0xc0, 0x50}, /* HSize 640 */
- {0xc1, 0x3c}, /* VSize 480 */
- {0x34, 0x05}, /* enable Audio Suspend mode */
- {0xc2, 0x0c}, /* Input YUV */
- {0xc3, 0xf9}, /* enable PRE */
- {0x34, 0x05}, /* enable Audio Suspend mode */
- {0xe7, 0x2e}, /* this solves failure of "SuspendResumeTest" */
- {0x31, 0xf9}, /* enable 1.8V Suspend */
- {0x35, 0x02}, /* turn on JPEG */
- {0xd9, 0x10},
- {0x25, 0x42}, /* GPIO[8]:Input */
- {0x94, 0x11}, /* If the default setting is loaded when
- * system boots up, this flag is closed here */
-};
-static const u8 sensor_init_767x[][2] = {
- {0x12, 0x80},
- {0x11, 0x03},
- {0x3a, 0x04},
- {0x12, 0x00},
- {0x17, 0x13},
- {0x18, 0x01},
- {0x32, 0xb6},
- {0x19, 0x02},
- {0x1a, 0x7a},
- {0x03, 0x0a},
- {0x0c, 0x00},
- {0x3e, 0x00},
- {0x70, 0x3a},
- {0x71, 0x35},
- {0x72, 0x11},
- {0x73, 0xf0},
- {0xa2, 0x02},
- {0x7a, 0x2a}, /* set Gamma=1.6 below */
- {0x7b, 0x12},
- {0x7c, 0x1d},
- {0x7d, 0x2d},
- {0x7e, 0x45},
- {0x7f, 0x50},
- {0x80, 0x59},
- {0x81, 0x62},
- {0x82, 0x6b},
- {0x83, 0x73},
- {0x84, 0x7b},
- {0x85, 0x8a},
- {0x86, 0x98},
- {0x87, 0xb2},
- {0x88, 0xca},
- {0x89, 0xe0},
- {0x13, 0xe0},
- {0x00, 0x00},
- {0x10, 0x00},
- {0x0d, 0x40},
- {0x14, 0x38}, /* gain max 16x */
- {0xa5, 0x05},
- {0xab, 0x07},
- {0x24, 0x95},
- {0x25, 0x33},
- {0x26, 0xe3},
- {0x9f, 0x78},
- {0xa0, 0x68},
- {0xa1, 0x03},
- {0xa6, 0xd8},
- {0xa7, 0xd8},
- {0xa8, 0xf0},
- {0xa9, 0x90},
- {0xaa, 0x94},
- {0x13, 0xe5},
- {0x0e, 0x61},
- {0x0f, 0x4b},
- {0x16, 0x02},
- {0x21, 0x02},
- {0x22, 0x91},
- {0x29, 0x07},
- {0x33, 0x0b},
- {0x35, 0x0b},
- {0x37, 0x1d},
- {0x38, 0x71},
- {0x39, 0x2a},
- {0x3c, 0x78},
- {0x4d, 0x40},
- {0x4e, 0x20},
- {0x69, 0x00},
- {0x6b, 0x4a},
- {0x74, 0x10},
- {0x8d, 0x4f},
- {0x8e, 0x00},
- {0x8f, 0x00},
- {0x90, 0x00},
- {0x91, 0x00},
- {0x96, 0x00},
- {0x9a, 0x80},
- {0xb0, 0x84},
- {0xb1, 0x0c},
- {0xb2, 0x0e},
- {0xb3, 0x82},
- {0xb8, 0x0a},
- {0x43, 0x0a},
- {0x44, 0xf0},
- {0x45, 0x34},
- {0x46, 0x58},
- {0x47, 0x28},
- {0x48, 0x3a},
- {0x59, 0x88},
- {0x5a, 0x88},
- {0x5b, 0x44},
- {0x5c, 0x67},
- {0x5d, 0x49},
- {0x5e, 0x0e},
- {0x6c, 0x0a},
- {0x6d, 0x55},
- {0x6e, 0x11},
- {0x6f, 0x9f},
- {0x6a, 0x40},
- {0x01, 0x40},
- {0x02, 0x40},
- {0x13, 0xe7},
- {0x4f, 0x80},
- {0x50, 0x80},
- {0x51, 0x00},
- {0x52, 0x22},
- {0x53, 0x5e},
- {0x54, 0x80},
- {0x58, 0x9e},
- {0x41, 0x08},
- {0x3f, 0x00},
- {0x75, 0x04},
- {0x76, 0xe1},
- {0x4c, 0x00},
- {0x77, 0x01},
- {0x3d, 0xc2},
- {0x4b, 0x09},
- {0xc9, 0x60},
- {0x41, 0x38}, /* jfm: auto sharpness + auto de-noise */
- {0x56, 0x40},
- {0x34, 0x11},
- {0x3b, 0xc2},
- {0xa4, 0x8a}, /* Night mode trigger point */
- {0x96, 0x00},
- {0x97, 0x30},
- {0x98, 0x20},
- {0x99, 0x20},
- {0x9a, 0x84},
- {0x9b, 0x29},
- {0x9c, 0x03},
- {0x9d, 0x4c},
- {0x9e, 0x3f},
- {0x78, 0x04},
- {0x79, 0x01},
- {0xc8, 0xf0},
- {0x79, 0x0f},
- {0xc8, 0x00},
- {0x79, 0x10},
- {0xc8, 0x7e},
- {0x79, 0x0a},
- {0xc8, 0x80},
- {0x79, 0x0b},
- {0xc8, 0x01},
- {0x79, 0x0c},
- {0xc8, 0x0f},
- {0x79, 0x0d},
- {0xc8, 0x20},
- {0x79, 0x09},
- {0xc8, 0x80},
- {0x79, 0x02},
- {0xc8, 0xc0},
- {0x79, 0x03},
- {0xc8, 0x20},
- {0x79, 0x26},
-};
-static const u8 bridge_start_vga_767x[][2] = {
-/* str59 JPG */
- {0x94, 0xaa},
- {0xf1, 0x42},
- {0xe5, 0x04},
- {0xc0, 0x50},
- {0xc1, 0x3c},
- {0xc2, 0x0c},
- {0x35, 0x02}, /* turn on JPEG */
- {0xd9, 0x10},
- {0xda, 0x00}, /* for higher clock rate(30fps) */
- {0x34, 0x05}, /* enable Audio Suspend mode */
- {0xc3, 0xf9}, /* enable PRE */
- {0x8c, 0x00}, /* CIF VSize LSB[2:0] */
- {0x8d, 0x1c}, /* output YUV */
-/* {0x34, 0x05}, * enable Audio Suspend mode (?) */
- {0x50, 0x00}, /* H/V divider=0 */
- {0x51, 0xa0}, /* input H=640/4 */
- {0x52, 0x3c}, /* input V=480/4 */
- {0x53, 0x00}, /* offset X=0 */
- {0x54, 0x00}, /* offset Y=0 */
- {0x55, 0x00}, /* H/V size[8]=0 */
- {0x57, 0x00}, /* H-size[9]=0 */
- {0x5c, 0x00}, /* output size[9:8]=0 */
- {0x5a, 0xa0}, /* output H=640/4 */
- {0x5b, 0x78}, /* output V=480/4 */
- {0x1c, 0x0a},
- {0x1d, 0x0a},
- {0x94, 0x11},
-};
-static const u8 sensor_start_vga_767x[][2] = {
- {0x11, 0x01},
- {0x1e, 0x04},
- {0x19, 0x02},
- {0x1a, 0x7a},
-};
-static const u8 bridge_start_qvga_767x[][2] = {
-/* str86 JPG */
- {0x94, 0xaa},
- {0xf1, 0x42},
- {0xe5, 0x04},
- {0xc0, 0x80},
- {0xc1, 0x60},
- {0xc2, 0x0c},
- {0x35, 0x02}, /* turn on JPEG */
- {0xd9, 0x10},
- {0xc0, 0x50}, /* CIF HSize 640 */
- {0xc1, 0x3c}, /* CIF VSize 480 */
- {0x8c, 0x00}, /* CIF VSize LSB[2:0] */
- {0x8d, 0x1c}, /* output YUV */
- {0x34, 0x05}, /* enable Audio Suspend mode */
- {0xc2, 0x4c}, /* output YUV and Enable DCW */
- {0xc3, 0xf9}, /* enable PRE */
- {0x1c, 0x00}, /* indirect addressing */
- {0x1d, 0x48}, /* output YUV422 */
- {0x50, 0x89}, /* H/V divider=/2; plus DCW AVG */
- {0x51, 0xa0}, /* DCW input H=640/4 */
- {0x52, 0x78}, /* DCW input V=480/4 */
- {0x53, 0x00}, /* offset X=0 */
- {0x54, 0x00}, /* offset Y=0 */
- {0x55, 0x00}, /* H/V size[8]=0 */
- {0x57, 0x00}, /* H-size[9]=0 */
- {0x5c, 0x00}, /* DCW output size[9:8]=0 */
- {0x5a, 0x50}, /* DCW output H=320/4 */
- {0x5b, 0x3c}, /* DCW output V=240/4 */
- {0x1c, 0x0a},
- {0x1d, 0x0a},
- {0x94, 0x11},
-};
-static const u8 sensor_start_qvga_767x[][2] = {
- {0x11, 0x01},
- {0x1e, 0x04},
- {0x19, 0x02},
- {0x1a, 0x7a},
-};
-
-static const u8 bridge_init_772x[][2] = {
- { 0xc2, 0x0c },
- { 0x88, 0xf8 },
- { 0xc3, 0x69 },
- { 0x89, 0xff },
- { 0x76, 0x03 },
- { 0x92, 0x01 },
- { 0x93, 0x18 },
- { 0x94, 0x10 },
- { 0x95, 0x10 },
- { 0xe2, 0x00 },
- { 0xe7, 0x3e },
-
- { 0x96, 0x00 },
-
- { 0x97, 0x20 },
- { 0x97, 0x20 },
- { 0x97, 0x20 },
- { 0x97, 0x0a },
- { 0x97, 0x3f },
- { 0x97, 0x4a },
- { 0x97, 0x20 },
- { 0x97, 0x15 },
- { 0x97, 0x0b },
-
- { 0x8e, 0x40 },
- { 0x1f, 0x81 },
- { 0x34, 0x05 },
- { 0xe3, 0x04 },
- { 0x88, 0x00 },
- { 0x89, 0x00 },
- { 0x76, 0x00 },
- { 0xe7, 0x2e },
- { 0x31, 0xf9 },
- { 0x25, 0x42 },
- { 0x21, 0xf0 },
-
- { 0x1c, 0x00 },
- { 0x1d, 0x40 },
- { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */
- { 0x1d, 0x00 }, /* payload size */
-
- { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */
- { 0x1d, 0x58 }, /* frame size */
- { 0x1d, 0x00 }, /* frame size */
-
- { 0x1c, 0x0a },
- { 0x1d, 0x08 }, /* turn on UVC header */
- { 0x1d, 0x0e }, /* .. */
-
- { 0x8d, 0x1c },
- { 0x8e, 0x80 },
- { 0xe5, 0x04 },
-
- { 0xc0, 0x50 },
- { 0xc1, 0x3c },
- { 0xc2, 0x0c },
-};
-static const u8 sensor_init_772x[][2] = {
- { 0x12, 0x80 },
- { 0x11, 0x01 },
-/*fixme: better have a delay?*/
- { 0x11, 0x01 },
- { 0x11, 0x01 },
- { 0x11, 0x01 },
- { 0x11, 0x01 },
- { 0x11, 0x01 },
- { 0x11, 0x01 },
- { 0x11, 0x01 },
- { 0x11, 0x01 },
- { 0x11, 0x01 },
- { 0x11, 0x01 },
-
- { 0x3d, 0x03 },
- { 0x17, 0x26 },
- { 0x18, 0xa0 },
- { 0x19, 0x07 },
- { 0x1a, 0xf0 },
- { 0x32, 0x00 },
- { 0x29, 0xa0 },
- { 0x2c, 0xf0 },
- { 0x65, 0x20 },
- { 0x11, 0x01 },
- { 0x42, 0x7f },
- { 0x63, 0xaa }, /* AWB - was e0 */
- { 0x64, 0xff },
- { 0x66, 0x00 },
- { 0x13, 0xf0 }, /* com8 */
- { 0x0d, 0x41 },
- { 0x0f, 0xc5 },
- { 0x14, 0x11 },
-
- { 0x22, 0x7f },
- { 0x23, 0x03 },
- { 0x24, 0x40 },
- { 0x25, 0x30 },
- { 0x26, 0xa1 },
- { 0x2a, 0x00 },
- { 0x2b, 0x00 },
- { 0x6b, 0xaa },
- { 0x13, 0xff }, /* AWB */
-
- { 0x90, 0x05 },
- { 0x91, 0x01 },
- { 0x92, 0x03 },
- { 0x93, 0x00 },
- { 0x94, 0x60 },
- { 0x95, 0x3c },
- { 0x96, 0x24 },
- { 0x97, 0x1e },
- { 0x98, 0x62 },
- { 0x99, 0x80 },
- { 0x9a, 0x1e },
- { 0x9b, 0x08 },
- { 0x9c, 0x20 },
- { 0x9e, 0x81 },
-
- { 0xa6, 0x07 },
- { 0x7e, 0x0c },
- { 0x7f, 0x16 },
- { 0x80, 0x2a },
- { 0x81, 0x4e },
- { 0x82, 0x61 },
- { 0x83, 0x6f },
- { 0x84, 0x7b },
- { 0x85, 0x86 },
- { 0x86, 0x8e },
- { 0x87, 0x97 },
- { 0x88, 0xa4 },
- { 0x89, 0xaf },
- { 0x8a, 0xc5 },
- { 0x8b, 0xd7 },
- { 0x8c, 0xe8 },
- { 0x8d, 0x20 },
-
- { 0x0c, 0x90 },
-
- { 0x2b, 0x00 },
- { 0x22, 0x7f },
- { 0x23, 0x03 },
- { 0x11, 0x01 },
- { 0x0c, 0xd0 },
- { 0x64, 0xff },
- { 0x0d, 0x41 },
-
- { 0x14, 0x41 },
- { 0x0e, 0xcd },
- { 0xac, 0xbf },
- { 0x8e, 0x00 }, /* De-noise threshold */
- { 0x0c, 0xd0 }
-};
-static const u8 bridge_start_vga_772x[][2] = {
- {0x1c, 0x00},
- {0x1d, 0x40},
- {0x1d, 0x02},
- {0x1d, 0x00},
- {0x1d, 0x02},
- {0x1d, 0x58},
- {0x1d, 0x00},
- {0xc0, 0x50},
- {0xc1, 0x3c},
-};
-static const u8 sensor_start_vga_772x[][2] = {
- {0x12, 0x00},
- {0x17, 0x26},
- {0x18, 0xa0},
- {0x19, 0x07},
- {0x1a, 0xf0},
- {0x29, 0xa0},
- {0x2c, 0xf0},
- {0x65, 0x20},
-};
-static const u8 bridge_start_qvga_772x[][2] = {
- {0x1c, 0x00},
- {0x1d, 0x40},
- {0x1d, 0x02},
- {0x1d, 0x00},
- {0x1d, 0x01},
- {0x1d, 0x4b},
- {0x1d, 0x00},
- {0xc0, 0x28},
- {0xc1, 0x1e},
-};
-static const u8 sensor_start_qvga_772x[][2] = {
- {0x12, 0x40},
- {0x17, 0x3f},
- {0x18, 0x50},
- {0x19, 0x03},
- {0x1a, 0x78},
- {0x29, 0x50},
- {0x2c, 0x78},
- {0x65, 0x2f},
-};
-
-static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
-{
- struct usb_device *udev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
-
- PDEBUG(D_USBO, "SET 01 0000 %04x %02x", reg, val);
- gspca_dev->usb_buf[0] = val;
- ret = usb_control_msg(udev,
- usb_sndctrlpipe(udev, 0),
- 0x01,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
- if (ret < 0) {
- pr_err("write failed %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
-{
- struct usb_device *udev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return 0;
- ret = usb_control_msg(udev,
- usb_rcvctrlpipe(udev, 0),
- 0x01,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
- PDEBUG(D_USBI, "GET 01 0000 %04x %02x", reg, gspca_dev->usb_buf[0]);
- if (ret < 0) {
- pr_err("read failed %d\n", ret);
- gspca_dev->usb_err = ret;
- }
- return gspca_dev->usb_buf[0];
-}
-
-/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
- * (direction and output)? */
-static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
-{
- u8 data;
-
- PDEBUG(D_CONF, "led status: %d", status);
-
- data = ov534_reg_read(gspca_dev, 0x21);
- data |= 0x80;
- ov534_reg_write(gspca_dev, 0x21, data);
-
- data = ov534_reg_read(gspca_dev, 0x23);
- if (status)
- data |= 0x80;
- else
- data &= ~0x80;
-
- ov534_reg_write(gspca_dev, 0x23, data);
-
- if (!status) {
- data = ov534_reg_read(gspca_dev, 0x21);
- data &= ~0x80;
- ov534_reg_write(gspca_dev, 0x21, data);
- }
-}
-
-static int sccb_check_status(struct gspca_dev *gspca_dev)
-{
- u8 data;
- int i;
-
- for (i = 0; i < 5; i++) {
- msleep(10);
- data = ov534_reg_read(gspca_dev, OV534_REG_STATUS);
-
- switch (data) {
- case 0x00:
- return 1;
- case 0x04:
- return 0;
- case 0x03:
- break;
- default:
- PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5",
- data, i + 1);
- }
- }
- return 0;
-}
-
-static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
-{
- PDEBUG(D_USBO, "sccb write: %02x %02x", reg, val);
- ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
- ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
- ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
-
- if (!sccb_check_status(gspca_dev)) {
- pr_err("sccb_reg_write failed\n");
- gspca_dev->usb_err = -EIO;
- }
-}
-
-static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
-{
- ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
- ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
- if (!sccb_check_status(gspca_dev))
- pr_err("sccb_reg_read failed 1\n");
-
- ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
- if (!sccb_check_status(gspca_dev))
- pr_err("sccb_reg_read failed 2\n");
-
- return ov534_reg_read(gspca_dev, OV534_REG_READ);
-}
-
-/* output a bridge sequence (reg - val) */
-static void reg_w_array(struct gspca_dev *gspca_dev,
- const u8 (*data)[2], int len)
-{
- while (--len >= 0) {
- ov534_reg_write(gspca_dev, (*data)[0], (*data)[1]);
- data++;
- }
-}
-
-/* output a sensor sequence (reg - val) */
-static void sccb_w_array(struct gspca_dev *gspca_dev,
- const u8 (*data)[2], int len)
-{
- while (--len >= 0) {
- if ((*data)[0] != 0xff) {
- sccb_reg_write(gspca_dev, (*data)[0], (*data)[1]);
- } else {
- sccb_reg_read(gspca_dev, (*data)[1]);
- sccb_reg_write(gspca_dev, 0xff, 0x00);
- }
- data++;
- }
-}
-
-/* ov772x specific controls */
-static void set_frame_rate(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- struct rate_s {
- u8 fps;
- u8 r11;
- u8 r0d;
- u8 re5;
- };
- const struct rate_s *r;
- static const struct rate_s rate_0[] = { /* 640x480 */
- {60, 0x01, 0xc1, 0x04},
- {50, 0x01, 0x41, 0x02},
- {40, 0x02, 0xc1, 0x04},
- {30, 0x04, 0x81, 0x02},
- {15, 0x03, 0x41, 0x04},
- };
- static const struct rate_s rate_1[] = { /* 320x240 */
- {125, 0x02, 0x81, 0x02},
- {100, 0x02, 0xc1, 0x04},
- {75, 0x03, 0xc1, 0x04},
- {60, 0x04, 0xc1, 0x04},
- {50, 0x02, 0x41, 0x04},
- {40, 0x03, 0x41, 0x04},
- {30, 0x04, 0x41, 0x04},
- };
-
- if (sd->sensor != SENSOR_OV772x)
- return;
- if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) {
- r = rate_0;
- i = ARRAY_SIZE(rate_0);
- } else {
- r = rate_1;
- i = ARRAY_SIZE(rate_1);
- }
- while (--i > 0) {
- if (sd->frame_rate >= r->fps)
- break;
- r++;
- }
-
- sccb_reg_write(gspca_dev, 0x11, r->r11);
- sccb_reg_write(gspca_dev, 0x0d, r->r0d);
- ov534_reg_write(gspca_dev, 0xe5, r->re5);
-
- PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
-}
-
-static void sethue(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_OV767x) {
- /* TBD */
- } else {
- s16 huesin;
- s16 huecos;
-
- /* fixp_sin and fixp_cos accept only positive values, while
- * our val is between -90 and 90
- */
- val += 360;
-
- /* According to the datasheet the registers expect HUESIN and
- * HUECOS to be the result of the trigonometric functions,
- * scaled by 0x80.
- *
- * The 0x100 here represents the maximun absolute value
- * returned byt fixp_sin and fixp_cos, so the scaling will
- * consider the result like in the interval [-1.0, 1.0].
- */
- huesin = fixp_sin(val) * 0x80 / 0x100;
- huecos = fixp_cos(val) * 0x80 / 0x100;
-
- if (huesin < 0) {
- sccb_reg_write(gspca_dev, 0xab,
- sccb_reg_read(gspca_dev, 0xab) | 0x2);
- huesin = -huesin;
- } else {
- sccb_reg_write(gspca_dev, 0xab,
- sccb_reg_read(gspca_dev, 0xab) & ~0x2);
-
- }
- sccb_reg_write(gspca_dev, 0xa9, (u8)huecos);
- sccb_reg_write(gspca_dev, 0xaa, (u8)huesin);
- }
-}
-
-static void setsaturation(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_OV767x) {
- int i;
- static u8 color_tb[][6] = {
- {0x42, 0x42, 0x00, 0x11, 0x30, 0x41},
- {0x52, 0x52, 0x00, 0x16, 0x3c, 0x52},
- {0x66, 0x66, 0x00, 0x1b, 0x4b, 0x66},
- {0x80, 0x80, 0x00, 0x22, 0x5e, 0x80},
- {0x9a, 0x9a, 0x00, 0x29, 0x71, 0x9a},
- {0xb8, 0xb8, 0x00, 0x31, 0x87, 0xb8},
- {0xdd, 0xdd, 0x00, 0x3b, 0xa2, 0xdd},
- };
-
- for (i = 0; i < ARRAY_SIZE(color_tb[0]); i++)
- sccb_reg_write(gspca_dev, 0x4f + i, color_tb[val][i]);
- } else {
- sccb_reg_write(gspca_dev, 0xa7, val); /* U saturation */
- sccb_reg_write(gspca_dev, 0xa8, val); /* V saturation */
- }
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_OV767x) {
- if (val < 0)
- val = 0x80 - val;
- sccb_reg_write(gspca_dev, 0x55, val); /* bright */
- } else {
- sccb_reg_write(gspca_dev, 0x9b, val);
- }
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_OV767x)
- sccb_reg_write(gspca_dev, 0x56, val); /* contras */
- else
- sccb_reg_write(gspca_dev, 0x9c, val);
-}
-
-static void setgain(struct gspca_dev *gspca_dev, s32 val)
-{
- switch (val & 0x30) {
- case 0x00:
- val &= 0x0f;
- break;
- case 0x10:
- val &= 0x0f;
- val |= 0x30;
- break;
- case 0x20:
- val &= 0x0f;
- val |= 0x70;
- break;
- default:
-/* case 0x30: */
- val &= 0x0f;
- val |= 0xf0;
- break;
- }
- sccb_reg_write(gspca_dev, 0x00, val);
-}
-
-static s32 getgain(struct gspca_dev *gspca_dev)
-{
- return sccb_reg_read(gspca_dev, 0x00);
-}
-
-static void setexposure(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_OV767x) {
-
- /* set only aec[9:2] */
- sccb_reg_write(gspca_dev, 0x10, val); /* aech */
- } else {
-
- /* 'val' is one byte and represents half of the exposure value
- * we are going to set into registers, a two bytes value:
- *
- * MSB: ((u16) val << 1) >> 8 == val >> 7
- * LSB: ((u16) val << 1) & 0xff == val << 1
- */
- sccb_reg_write(gspca_dev, 0x08, val >> 7);
- sccb_reg_write(gspca_dev, 0x10, val << 1);
- }
-}
-
-static s32 getexposure(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_OV767x) {
- /* get only aec[9:2] */
- return sccb_reg_read(gspca_dev, 0x10); /* aech */
- } else {
- u8 hi = sccb_reg_read(gspca_dev, 0x08);
- u8 lo = sccb_reg_read(gspca_dev, 0x10);
- return (hi << 8 | lo) >> 1;
- }
-}
-
-static void setagc(struct gspca_dev *gspca_dev, s32 val)
-{
- if (val) {
- sccb_reg_write(gspca_dev, 0x13,
- sccb_reg_read(gspca_dev, 0x13) | 0x04);
- sccb_reg_write(gspca_dev, 0x64,
- sccb_reg_read(gspca_dev, 0x64) | 0x03);
- } else {
- sccb_reg_write(gspca_dev, 0x13,
- sccb_reg_read(gspca_dev, 0x13) & ~0x04);
- sccb_reg_write(gspca_dev, 0x64,
- sccb_reg_read(gspca_dev, 0x64) & ~0x03);
- }
-}
-
-static void setawb(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (val) {
- sccb_reg_write(gspca_dev, 0x13,
- sccb_reg_read(gspca_dev, 0x13) | 0x02);
- if (sd->sensor == SENSOR_OV772x)
- sccb_reg_write(gspca_dev, 0x63,
- sccb_reg_read(gspca_dev, 0x63) | 0xc0);
- } else {
- sccb_reg_write(gspca_dev, 0x13,
- sccb_reg_read(gspca_dev, 0x13) & ~0x02);
- if (sd->sensor == SENSOR_OV772x)
- sccb_reg_write(gspca_dev, 0x63,
- sccb_reg_read(gspca_dev, 0x63) & ~0xc0);
- }
-}
-
-static void setaec(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 data;
-
- data = sd->sensor == SENSOR_OV767x ?
- 0x05 : /* agc + aec */
- 0x01; /* agc */
- switch (val) {
- case V4L2_EXPOSURE_AUTO:
- sccb_reg_write(gspca_dev, 0x13,
- sccb_reg_read(gspca_dev, 0x13) | data);
- break;
- case V4L2_EXPOSURE_MANUAL:
- sccb_reg_write(gspca_dev, 0x13,
- sccb_reg_read(gspca_dev, 0x13) & ~data);
- break;
- }
-}
-
-static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
-{
- sccb_reg_write(gspca_dev, 0x91, val); /* Auto de-noise threshold */
- sccb_reg_write(gspca_dev, 0x8e, val); /* De-noise threshold */
-}
-
-static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 val;
-
- if (sd->sensor == SENSOR_OV767x) {
- val = sccb_reg_read(gspca_dev, 0x1e); /* mvfp */
- val &= ~0x30;
- if (hflip)
- val |= 0x20;
- if (vflip)
- val |= 0x10;
- sccb_reg_write(gspca_dev, 0x1e, val);
- } else {
- val = sccb_reg_read(gspca_dev, 0x0c);
- val &= ~0xc0;
- if (hflip == 0)
- val |= 0x40;
- if (vflip == 0)
- val |= 0x80;
- sccb_reg_write(gspca_dev, 0x0c, val);
- }
-}
-
-static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- val = val ? 0x9e : 0x00;
- if (sd->sensor == SENSOR_OV767x) {
- sccb_reg_write(gspca_dev, 0x2a, 0x00);
- if (val)
- val = 0x9d; /* insert dummy to 25fps for 50Hz */
- }
- sccb_reg_write(gspca_dev, 0x2b, val);
-}
-
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
-
- cam = &gspca_dev->cam;
-
- cam->cam_mode = ov772x_mode;
- cam->nmodes = ARRAY_SIZE(ov772x_mode);
-
- sd->frame_rate = 30;
-
- return 0;
-}
-
-static int ov534_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct sd *sd = container_of(ctrl->handler, struct sd, ctrl_handler);
- struct gspca_dev *gspca_dev = &sd->gspca_dev;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTOGAIN:
- gspca_dev->usb_err = 0;
- if (ctrl->val && sd->gain && gspca_dev->streaming)
- sd->gain->val = getgain(gspca_dev);
- return gspca_dev->usb_err;
-
- case V4L2_CID_EXPOSURE_AUTO:
- gspca_dev->usb_err = 0;
- if (ctrl->val == V4L2_EXPOSURE_AUTO && sd->exposure &&
- gspca_dev->streaming)
- sd->exposure->val = getexposure(gspca_dev);
- return gspca_dev->usb_err;
- }
- return -EINVAL;
-}
-
-static int ov534_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct sd *sd = container_of(ctrl->handler, struct sd, ctrl_handler);
- struct gspca_dev *gspca_dev = &sd->gspca_dev;
-
- gspca_dev->usb_err = 0;
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_HUE:
- sethue(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- setsaturation(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_AUTOGAIN:
- /* case V4L2_CID_GAIN: */
- setagc(gspca_dev, ctrl->val);
- if (!gspca_dev->usb_err && !ctrl->val && sd->gain)
- setgain(gspca_dev, sd->gain->val);
- break;
- case V4L2_CID_AUTO_WHITE_BALANCE:
- setawb(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_EXPOSURE_AUTO:
- /* case V4L2_CID_EXPOSURE: */
- setaec(gspca_dev, ctrl->val);
- if (!gspca_dev->usb_err && ctrl->val == V4L2_EXPOSURE_MANUAL &&
- sd->exposure)
- setexposure(gspca_dev, sd->exposure->val);
- break;
- case V4L2_CID_SHARPNESS:
- setsharpness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_HFLIP:
- sethvflip(gspca_dev, ctrl->val, sd->vflip->val);
- break;
- case V4L2_CID_VFLIP:
- sethvflip(gspca_dev, sd->hflip->val, ctrl->val);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY:
- setlightfreq(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops ov534_ctrl_ops = {
- .g_volatile_ctrl = ov534_g_volatile_ctrl,
- .s_ctrl = ov534_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct v4l2_ctrl_handler *hdl = &sd->ctrl_handler;
- /* parameters with different values between the supported sensors */
- int saturation_min;
- int saturation_max;
- int saturation_def;
- int brightness_min;
- int brightness_max;
- int brightness_def;
- int contrast_max;
- int contrast_def;
- int exposure_min;
- int exposure_max;
- int exposure_def;
- int hflip_def;
-
- if (sd->sensor == SENSOR_OV767x) {
- saturation_min = 0,
- saturation_max = 6,
- saturation_def = 3,
- brightness_min = -127;
- brightness_max = 127;
- brightness_def = 0;
- contrast_max = 0x80;
- contrast_def = 0x40;
- exposure_min = 0x08;
- exposure_max = 0x60;
- exposure_def = 0x13;
- hflip_def = 1;
- } else {
- saturation_min = 0,
- saturation_max = 255,
- saturation_def = 64,
- brightness_min = 0;
- brightness_max = 255;
- brightness_def = 0;
- contrast_max = 255;
- contrast_def = 32;
- exposure_min = 0;
- exposure_max = 255;
- exposure_def = 120;
- hflip_def = 0;
- }
-
- gspca_dev->vdev.ctrl_handler = hdl;
-
- v4l2_ctrl_handler_init(hdl, 13);
-
- if (sd->sensor == SENSOR_OV772x)
- sd->hue = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops,
- V4L2_CID_HUE, -90, 90, 1, 0);
-
- sd->saturation = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops,
- V4L2_CID_SATURATION, saturation_min, saturation_max, 1,
- saturation_def);
- sd->brightness = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops,
- V4L2_CID_BRIGHTNESS, brightness_min, brightness_max, 1,
- brightness_def);
- sd->contrast = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops,
- V4L2_CID_CONTRAST, 0, contrast_max, 1, contrast_def);
-
- if (sd->sensor == SENSOR_OV772x) {
- sd->autogain = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- sd->gain = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops,
- V4L2_CID_GAIN, 0, 63, 1, 20);
- }
-
- sd->autoexposure = v4l2_ctrl_new_std_menu(hdl, &ov534_ctrl_ops,
- V4L2_CID_EXPOSURE_AUTO,
- V4L2_EXPOSURE_MANUAL, 0,
- V4L2_EXPOSURE_AUTO);
- sd->exposure = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops,
- V4L2_CID_EXPOSURE, exposure_min, exposure_max, 1,
- exposure_def);
-
- sd->autowhitebalance = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops,
- V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
-
- if (sd->sensor == SENSOR_OV772x)
- sd->sharpness = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops,
- V4L2_CID_SHARPNESS, 0, 63, 1, 0);
-
- sd->hflip = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, hflip_def);
- sd->vflip = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &ov534_ctrl_ops,
- V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_50HZ, 0,
- V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
-
- if (sd->sensor == SENSOR_OV772x)
- v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, true);
-
- v4l2_ctrl_auto_cluster(2, &sd->autoexposure, V4L2_EXPOSURE_MANUAL,
- true);
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u16 sensor_id;
- static const struct reg_array bridge_init[NSENSORS] = {
- [SENSOR_OV767x] = {bridge_init_767x, ARRAY_SIZE(bridge_init_767x)},
- [SENSOR_OV772x] = {bridge_init_772x, ARRAY_SIZE(bridge_init_772x)},
- };
- static const struct reg_array sensor_init[NSENSORS] = {
- [SENSOR_OV767x] = {sensor_init_767x, ARRAY_SIZE(sensor_init_767x)},
- [SENSOR_OV772x] = {sensor_init_772x, ARRAY_SIZE(sensor_init_772x)},
- };
-
- /* reset bridge */
- ov534_reg_write(gspca_dev, 0xe7, 0x3a);
- ov534_reg_write(gspca_dev, 0xe0, 0x08);
- msleep(100);
-
- /* initialize the sensor address */
- ov534_reg_write(gspca_dev, OV534_REG_ADDRESS, 0x42);
-
- /* reset sensor */
- sccb_reg_write(gspca_dev, 0x12, 0x80);
- msleep(10);
-
- /* probe the sensor */
- sccb_reg_read(gspca_dev, 0x0a);
- sensor_id = sccb_reg_read(gspca_dev, 0x0a) << 8;
- sccb_reg_read(gspca_dev, 0x0b);
- sensor_id |= sccb_reg_read(gspca_dev, 0x0b);
- PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
-
- if ((sensor_id & 0xfff0) == 0x7670) {
- sd->sensor = SENSOR_OV767x;
- gspca_dev->cam.cam_mode = ov767x_mode;
- gspca_dev->cam.nmodes = ARRAY_SIZE(ov767x_mode);
- } else {
- sd->sensor = SENSOR_OV772x;
- gspca_dev->cam.bulk = 1;
- gspca_dev->cam.bulk_size = 16384;
- gspca_dev->cam.bulk_nurbs = 2;
- gspca_dev->cam.mode_framerates = ov772x_framerates;
- }
-
- /* initialize */
- reg_w_array(gspca_dev, bridge_init[sd->sensor].val,
- bridge_init[sd->sensor].len);
- ov534_set_led(gspca_dev, 1);
- sccb_w_array(gspca_dev, sensor_init[sd->sensor].val,
- sensor_init[sd->sensor].len);
- if (sd->sensor == SENSOR_OV767x)
- sd_start(gspca_dev);
- sd_stopN(gspca_dev);
-/* set_frame_rate(gspca_dev); */
-
- return gspca_dev->usb_err;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int mode;
- static const struct reg_array bridge_start[NSENSORS][2] = {
- [SENSOR_OV767x] = {{bridge_start_qvga_767x,
- ARRAY_SIZE(bridge_start_qvga_767x)},
- {bridge_start_vga_767x,
- ARRAY_SIZE(bridge_start_vga_767x)}},
- [SENSOR_OV772x] = {{bridge_start_qvga_772x,
- ARRAY_SIZE(bridge_start_qvga_772x)},
- {bridge_start_vga_772x,
- ARRAY_SIZE(bridge_start_vga_772x)}},
- };
- static const struct reg_array sensor_start[NSENSORS][2] = {
- [SENSOR_OV767x] = {{sensor_start_qvga_767x,
- ARRAY_SIZE(sensor_start_qvga_767x)},
- {sensor_start_vga_767x,
- ARRAY_SIZE(sensor_start_vga_767x)}},
- [SENSOR_OV772x] = {{sensor_start_qvga_772x,
- ARRAY_SIZE(sensor_start_qvga_772x)},
- {sensor_start_vga_772x,
- ARRAY_SIZE(sensor_start_vga_772x)}},
- };
-
- /* (from ms-win trace) */
- if (sd->sensor == SENSOR_OV767x)
- sccb_reg_write(gspca_dev, 0x1e, 0x04);
- /* black sun enable ? */
-
- mode = gspca_dev->curr_mode; /* 0: 320x240, 1: 640x480 */
- reg_w_array(gspca_dev, bridge_start[sd->sensor][mode].val,
- bridge_start[sd->sensor][mode].len);
- sccb_w_array(gspca_dev, sensor_start[sd->sensor][mode].val,
- sensor_start[sd->sensor][mode].len);
-
- set_frame_rate(gspca_dev);
-
- if (sd->hue)
- sethue(gspca_dev, v4l2_ctrl_g_ctrl(sd->hue));
- setsaturation(gspca_dev, v4l2_ctrl_g_ctrl(sd->saturation));
- if (sd->autogain)
- setagc(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain));
- setawb(gspca_dev, v4l2_ctrl_g_ctrl(sd->autowhitebalance));
- setaec(gspca_dev, v4l2_ctrl_g_ctrl(sd->autoexposure));
- if (sd->gain)
- setgain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain));
- setexposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
- setbrightness(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness));
- setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->contrast));
- if (sd->sharpness)
- setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness));
- sethvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip),
- v4l2_ctrl_g_ctrl(sd->vflip));
- setlightfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->plfreq));
-
- ov534_set_led(gspca_dev, 1);
- ov534_reg_write(gspca_dev, 0xe0, 0x00);
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- ov534_reg_write(gspca_dev, 0xe0, 0x09);
- ov534_set_led(gspca_dev, 0);
-}
-
-/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
-#define UVC_STREAM_EOH (1 << 7)
-#define UVC_STREAM_ERR (1 << 6)
-#define UVC_STREAM_STI (1 << 5)
-#define UVC_STREAM_RES (1 << 4)
-#define UVC_STREAM_SCR (1 << 3)
-#define UVC_STREAM_PTS (1 << 2)
-#define UVC_STREAM_EOF (1 << 1)
-#define UVC_STREAM_FID (1 << 0)
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- __u32 this_pts;
- u16 this_fid;
- int remaining_len = len;
- int payload_len;
-
- payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
- do {
- len = min(remaining_len, payload_len);
-
- /* Payloads are prefixed with a UVC-style header. We
- consider a frame to start when the FID toggles, or the PTS
- changes. A frame ends when EOF is set, and we've received
- the correct number of bytes. */
-
- /* Verify UVC header. Header length is always 12 */
- if (data[0] != 12 || len < 12) {
- PDEBUG(D_PACK, "bad header");
- goto discard;
- }
-
- /* Check errors */
- if (data[1] & UVC_STREAM_ERR) {
- PDEBUG(D_PACK, "payload error");
- goto discard;
- }
-
- /* Extract PTS and FID */
- if (!(data[1] & UVC_STREAM_PTS)) {
- PDEBUG(D_PACK, "PTS not present");
- goto discard;
- }
- this_pts = (data[5] << 24) | (data[4] << 16)
- | (data[3] << 8) | data[2];
- this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
-
- /* If PTS or FID has changed, start a new frame. */
- if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
- if (gspca_dev->last_packet_type == INTER_PACKET)
- gspca_frame_add(gspca_dev, LAST_PACKET,
- NULL, 0);
- sd->last_pts = this_pts;
- sd->last_fid = this_fid;
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- data + 12, len - 12);
- /* If this packet is marked as EOF, end the frame */
- } else if (data[1] & UVC_STREAM_EOF) {
- sd->last_pts = 0;
- if (gspca_dev->pixfmt == V4L2_PIX_FMT_YUYV
- && gspca_dev->image_len + len - 12 !=
- gspca_dev->width * gspca_dev->height * 2) {
- PDEBUG(D_PACK, "wrong sized frame");
- goto discard;
- }
- gspca_frame_add(gspca_dev, LAST_PACKET,
- data + 12, len - 12);
- } else {
-
- /* Add the data from this payload */
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data + 12, len - 12);
- }
-
- /* Done this payload */
- goto scan_next;
-
-discard:
- /* Discard data until a new frame starts. */
- gspca_dev->last_packet_type = DISCARD_PACKET;
-
-scan_next:
- remaining_len -= len;
- data += len;
- } while (remaining_len > 0);
-}
-
-/* get stream parameters (framerate) */
-static void sd_get_streamparm(struct gspca_dev *gspca_dev,
- struct v4l2_streamparm *parm)
-{
- struct v4l2_captureparm *cp = &parm->parm.capture;
- struct v4l2_fract *tpf = &cp->timeperframe;
- struct sd *sd = (struct sd *) gspca_dev;
-
- cp->capability |= V4L2_CAP_TIMEPERFRAME;
- tpf->numerator = 1;
- tpf->denominator = sd->frame_rate;
-}
-
-/* set stream parameters (framerate) */
-static void sd_set_streamparm(struct gspca_dev *gspca_dev,
- struct v4l2_streamparm *parm)
-{
- struct v4l2_captureparm *cp = &parm->parm.capture;
- struct v4l2_fract *tpf = &cp->timeperframe;
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* Set requested framerate */
- sd->frame_rate = tpf->denominator / tpf->numerator;
- if (gspca_dev->streaming)
- set_frame_rate(gspca_dev);
-
- /* Return the actual framerate */
- tpf->numerator = 1;
- tpf->denominator = sd->frame_rate;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
- .get_streamparm = sd_get_streamparm,
- .set_streamparm = sd_set_streamparm,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x1415, 0x2000)},
- {USB_DEVICE(0x06f8, 0x3002)},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c
deleted file mode 100644
index c4cd028fe0b..00000000000
--- a/drivers/media/video/gspca/ov534_9.c
+++ /dev/null
@@ -1,1500 +0,0 @@
-/*
- * ov534-ov9xxx gspca driver
- *
- * Copyright (C) 2009-2011 Jean-Francois Moine http://moinejf.free.fr
- * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
- * Copyright (C) 2008 Jim Paris <jim@jtan.com>
- *
- * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
- * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
- * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "ov534_9"
-
-#include "gspca.h"
-
-#define OV534_REG_ADDRESS 0xf1 /* sensor address */
-#define OV534_REG_SUBADDR 0xf2
-#define OV534_REG_WRITE 0xf3
-#define OV534_REG_READ 0xf4
-#define OV534_REG_OPERATION 0xf5
-#define OV534_REG_STATUS 0xf6
-
-#define OV534_OP_WRITE_3 0x37
-#define OV534_OP_WRITE_2 0x33
-#define OV534_OP_READ_2 0xf9
-
-#define CTRL_TIMEOUT 500
-
-MODULE_AUTHOR("Jean-Francois Moine <moinejf@free.fr>");
-MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- __u32 last_pts;
- u8 last_fid;
-
- u8 sensor;
-};
-enum sensors {
- SENSOR_OV965x, /* ov9657 */
- SENSOR_OV971x, /* ov9712 */
- SENSOR_OV562x, /* ov5621 */
- NSENSORS
-};
-
-static const struct v4l2_pix_format ov965x_mode[] = {
-#define QVGA_MODE 0
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG},
-#define VGA_MODE 1
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG},
-#define SVGA_MODE 2
- {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 800,
- .sizeimage = 800 * 600 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG},
-#define XGA_MODE 3
- {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 1024,
- .sizeimage = 1024 * 768 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG},
-#define SXGA_MODE 4
- {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 1280,
- .sizeimage = 1280 * 1024 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG},
-};
-
-static const struct v4l2_pix_format ov971x_mode[] = {
- {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB
- }
-};
-
-static const struct v4l2_pix_format ov562x_mode[] = {
- {2592, 1680, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 2592,
- .sizeimage = 2592 * 1680,
- .colorspace = V4L2_COLORSPACE_SRGB
- }
-};
-
-static const u8 bridge_init[][2] = {
- {0x88, 0xf8},
- {0x89, 0xff},
- {0x76, 0x03},
- {0x92, 0x03},
- {0x95, 0x10},
- {0xe2, 0x00},
- {0xe7, 0x3e},
- {0x8d, 0x1c},
- {0x8e, 0x00},
- {0x8f, 0x00},
- {0x1f, 0x00},
- {0xc3, 0xf9},
- {0x89, 0xff},
- {0x88, 0xf8},
- {0x76, 0x03},
- {0x92, 0x01},
- {0x93, 0x18},
- {0x1c, 0x0a},
- {0x1d, 0x48},
- {0xc0, 0x50},
- {0xc1, 0x3c},
- {0x34, 0x05},
- {0xc2, 0x0c},
- {0xc3, 0xf9},
- {0x34, 0x05},
- {0xe7, 0x2e},
- {0x31, 0xf9},
- {0x35, 0x02},
- {0xd9, 0x10},
- {0x25, 0x42},
- {0x94, 0x11},
-};
-
-static const u8 ov965x_init[][2] = {
- {0x12, 0x80}, /* com7 - SSCB reset */
- {0x00, 0x00}, /* gain */
- {0x01, 0x80}, /* blue */
- {0x02, 0x80}, /* red */
- {0x03, 0x1b}, /* vref */
- {0x04, 0x03}, /* com1 - exposure low bits */
- {0x0b, 0x57}, /* ver */
- {0x0e, 0x61}, /* com5 */
- {0x0f, 0x42}, /* com6 */
- {0x11, 0x00}, /* clkrc */
- {0x12, 0x02}, /* com7 - 15fps VGA YUYV */
- {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
- {0x14, 0x28}, /* com9 */
- {0x16, 0x24}, /* reg16 */
- {0x17, 0x1d}, /* hstart*/
- {0x18, 0xbd}, /* hstop */
- {0x19, 0x01}, /* vstrt */
- {0x1a, 0x81}, /* vstop*/
- {0x1e, 0x04}, /* mvfp */
- {0x24, 0x3c}, /* aew */
- {0x25, 0x36}, /* aeb */
- {0x26, 0x71}, /* vpt */
- {0x27, 0x08}, /* bbias */
- {0x28, 0x08}, /* gbbias */
- {0x29, 0x15}, /* gr com */
- {0x2a, 0x00}, /* exhch */
- {0x2b, 0x00}, /* exhcl */
- {0x2c, 0x08}, /* rbias */
- {0x32, 0xff}, /* href */
- {0x33, 0x00}, /* chlf */
- {0x34, 0x3f}, /* aref1 */
- {0x35, 0x00}, /* aref2 */
- {0x36, 0xf8}, /* aref3 */
- {0x38, 0x72}, /* adc2 */
- {0x39, 0x57}, /* aref4 */
- {0x3a, 0x80}, /* tslb - yuyv */
- {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
- {0x3d, 0x99}, /* com13 */
- {0x3f, 0xc1}, /* edge */
- {0x40, 0xc0}, /* com15 */
- {0x41, 0x40}, /* com16 */
- {0x42, 0xc0}, /* com17 */
- {0x43, 0x0a}, /* rsvd */
- {0x44, 0xf0},
- {0x45, 0x46},
- {0x46, 0x62},
- {0x47, 0x2a},
- {0x48, 0x3c},
- {0x4a, 0xfc},
- {0x4b, 0xfc},
- {0x4c, 0x7f},
- {0x4d, 0x7f},
- {0x4e, 0x7f},
- {0x4f, 0x98}, /* matrix */
- {0x50, 0x98},
- {0x51, 0x00},
- {0x52, 0x28},
- {0x53, 0x70},
- {0x54, 0x98},
- {0x58, 0x1a}, /* matrix coef sign */
- {0x59, 0x85}, /* AWB control */
- {0x5a, 0xa9},
- {0x5b, 0x64},
- {0x5c, 0x84},
- {0x5d, 0x53},
- {0x5e, 0x0e},
- {0x5f, 0xf0}, /* AWB blue limit */
- {0x60, 0xf0}, /* AWB red limit */
- {0x61, 0xf0}, /* AWB green limit */
- {0x62, 0x00}, /* lcc1 */
- {0x63, 0x00}, /* lcc2 */
- {0x64, 0x02}, /* lcc3 */
- {0x65, 0x16}, /* lcc4 */
- {0x66, 0x01}, /* lcc5 */
- {0x69, 0x02}, /* hv */
- {0x6b, 0x5a}, /* dbvl */
- {0x6c, 0x04},
- {0x6d, 0x55},
- {0x6e, 0x00},
- {0x6f, 0x9d},
- {0x70, 0x21}, /* dnsth */
- {0x71, 0x78},
- {0x72, 0x00}, /* poidx */
- {0x73, 0x01}, /* pckdv */
- {0x74, 0x3a}, /* xindx */
- {0x75, 0x35}, /* yindx */
- {0x76, 0x01},
- {0x77, 0x02},
- {0x7a, 0x12}, /* gamma curve */
- {0x7b, 0x08},
- {0x7c, 0x16},
- {0x7d, 0x30},
- {0x7e, 0x5e},
- {0x7f, 0x72},
- {0x80, 0x82},
- {0x81, 0x8e},
- {0x82, 0x9a},
- {0x83, 0xa4},
- {0x84, 0xac},
- {0x85, 0xb8},
- {0x86, 0xc3},
- {0x87, 0xd6},
- {0x88, 0xe6},
- {0x89, 0xf2},
- {0x8a, 0x03},
- {0x8c, 0x89}, /* com19 */
- {0x14, 0x28}, /* com9 */
- {0x90, 0x7d},
- {0x91, 0x7b},
- {0x9d, 0x03}, /* lcc6 */
- {0x9e, 0x04}, /* lcc7 */
- {0x9f, 0x7a},
- {0xa0, 0x79},
- {0xa1, 0x40}, /* aechm */
- {0xa4, 0x50}, /* com21 */
- {0xa5, 0x68}, /* com26 */
- {0xa6, 0x4a}, /* AWB green */
- {0xa8, 0xc1}, /* refa8 */
- {0xa9, 0xef}, /* refa9 */
- {0xaa, 0x92},
- {0xab, 0x04},
- {0xac, 0x80}, /* black level control */
- {0xad, 0x80},
- {0xae, 0x80},
- {0xaf, 0x80},
- {0xb2, 0xf2},
- {0xb3, 0x20},
- {0xb4, 0x20}, /* ctrlb4 */
- {0xb5, 0x00},
- {0xb6, 0xaf},
- {0xbb, 0xae},
- {0xbc, 0x7f}, /* ADC channel offsets */
- {0xdb, 0x7f},
- {0xbe, 0x7f},
- {0xbf, 0x7f},
- {0xc0, 0xe2},
- {0xc1, 0xc0},
- {0xc2, 0x01},
- {0xc3, 0x4e},
- {0xc6, 0x85},
- {0xc7, 0x80}, /* com24 */
- {0xc9, 0xe0},
- {0xca, 0xe8},
- {0xcb, 0xf0},
- {0xcc, 0xd8},
- {0xcd, 0xf1},
- {0x4f, 0x98}, /* matrix */
- {0x50, 0x98},
- {0x51, 0x00},
- {0x52, 0x28},
- {0x53, 0x70},
- {0x54, 0x98},
- {0x58, 0x1a},
- {0xff, 0x41}, /* read 41, write ff 00 */
- {0x41, 0x40}, /* com16 */
-
- {0xc5, 0x03}, /* 60 Hz banding filter */
- {0x6a, 0x02}, /* 50 Hz banding filter */
-
- {0x12, 0x62}, /* com7 - 30fps VGA YUV */
- {0x36, 0xfa}, /* aref3 */
- {0x69, 0x0a}, /* hv */
- {0x8c, 0x89}, /* com22 */
- {0x14, 0x28}, /* com9 */
- {0x3e, 0x0c},
- {0x41, 0x40}, /* com16 */
- {0x72, 0x00},
- {0x73, 0x00},
- {0x74, 0x3a},
- {0x75, 0x35},
- {0x76, 0x01},
- {0xc7, 0x80},
- {0x03, 0x12}, /* vref */
- {0x17, 0x16}, /* hstart */
- {0x18, 0x02}, /* hstop */
- {0x19, 0x01}, /* vstrt */
- {0x1a, 0x3d}, /* vstop */
- {0x32, 0xff}, /* href */
- {0xc0, 0xaa},
-};
-
-static const u8 bridge_init_2[][2] = {
- {0x94, 0xaa},
- {0xf1, 0x60},
- {0xe5, 0x04},
- {0xc0, 0x50},
- {0xc1, 0x3c},
- {0x8c, 0x00},
- {0x8d, 0x1c},
- {0x34, 0x05},
-
- {0xc2, 0x0c},
- {0xc3, 0xf9},
- {0xda, 0x01},
- {0x50, 0x00},
- {0x51, 0xa0},
- {0x52, 0x3c},
- {0x53, 0x00},
- {0x54, 0x00},
- {0x55, 0x00},
- {0x57, 0x00},
- {0x5c, 0x00},
- {0x5a, 0xa0},
- {0x5b, 0x78},
- {0x35, 0x02},
- {0xd9, 0x10},
- {0x94, 0x11},
-};
-
-static const u8 ov965x_init_2[][2] = {
- {0x3b, 0xc4},
- {0x1e, 0x04}, /* mvfp */
- {0x13, 0xe0}, /* com8 */
- {0x00, 0x00}, /* gain */
- {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
- {0x11, 0x03}, /* clkrc */
- {0x6b, 0x5a}, /* dblv */
- {0x6a, 0x05},
- {0xc5, 0x07},
- {0xa2, 0x4b},
- {0xa3, 0x3e},
- {0x2d, 0x00},
- {0xff, 0x42}, /* read 42, write ff 00 */
- {0x42, 0xc0}, /* com17 */
- {0x2d, 0x00},
- {0xff, 0x42}, /* read 42, write ff 00 */
- {0x42, 0xc1}, /* com17 */
-/* sharpness */
- {0x3f, 0x01},
- {0xff, 0x42}, /* read 42, write ff 00 */
- {0x42, 0xc1}, /* com17 */
-/* saturation */
- {0x4f, 0x98}, /* matrix */
- {0x50, 0x98},
- {0x51, 0x00},
- {0x52, 0x28},
- {0x53, 0x70},
- {0x54, 0x98},
- {0x58, 0x1a},
- {0xff, 0x41}, /* read 41, write ff 00 */
- {0x41, 0x40}, /* com16 */
-/* contrast */
- {0x56, 0x40},
-/* brightness */
- {0x55, 0x8f},
-/* expo */
- {0x10, 0x25}, /* aech - exposure high bits */
- {0xff, 0x13}, /* read 13, write ff 00 */
- {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
-};
-
-static const u8 ov971x_init[][2] = {
- {0x12, 0x80},
- {0x09, 0x10},
- {0x1e, 0x07},
- {0x5f, 0x18},
- {0x69, 0x04},
- {0x65, 0x2a},
- {0x68, 0x0a},
- {0x39, 0x28},
- {0x4d, 0x90},
- {0xc1, 0x80},
- {0x0c, 0x30},
- {0x6d, 0x02},
- {0x96, 0xf1},
- {0xbc, 0x68},
- {0x12, 0x00},
- {0x3b, 0x00},
- {0x97, 0x80},
- {0x17, 0x25},
- {0x18, 0xa2},
- {0x19, 0x01},
- {0x1a, 0xca},
- {0x03, 0x0a},
- {0x32, 0x07},
- {0x98, 0x40}, /*{0x98, 0x00},*/
- {0x99, 0xA0}, /*{0x99, 0x00},*/
- {0x9a, 0x01}, /*{0x9a, 0x00},*/
- {0x57, 0x00},
- {0x58, 0x78}, /*{0x58, 0xc8},*/
- {0x59, 0x50}, /*{0x59, 0xa0},*/
- {0x4c, 0x13},
- {0x4b, 0x36},
- {0x3d, 0x3c},
- {0x3e, 0x03},
- {0xbd, 0x50}, /*{0xbd, 0xa0},*/
- {0xbe, 0x78}, /*{0xbe, 0xc8},*/
- {0x4e, 0x55},
- {0x4f, 0x55},
- {0x50, 0x55},
- {0x51, 0x55},
- {0x24, 0x55},
- {0x25, 0x40},
- {0x26, 0xa1},
- {0x5c, 0x59},
- {0x5d, 0x00},
- {0x11, 0x00},
- {0x2a, 0x98},
- {0x2b, 0x06},
- {0x2d, 0x00},
- {0x2e, 0x00},
- {0x13, 0xa5},
- {0x14, 0x40},
- {0x4a, 0x00},
- {0x49, 0xce},
- {0x22, 0x03},
- {0x09, 0x00}
-};
-
-static const u8 ov965x_start_1_vga[][2] = { /* same for qvga */
- {0x12, 0x62}, /* com7 - 30fps VGA YUV */
- {0x36, 0xfa}, /* aref3 */
- {0x69, 0x0a}, /* hv */
- {0x8c, 0x89}, /* com22 */
- {0x14, 0x28}, /* com9 */
- {0x3e, 0x0c}, /* com14 */
- {0x41, 0x40}, /* com16 */
- {0x72, 0x00},
- {0x73, 0x00},
- {0x74, 0x3a},
- {0x75, 0x35},
- {0x76, 0x01},
- {0xc7, 0x80}, /* com24 */
- {0x03, 0x12}, /* vref */
- {0x17, 0x16}, /* hstart */
- {0x18, 0x02}, /* hstop */
- {0x19, 0x01}, /* vstrt */
- {0x1a, 0x3d}, /* vstop */
- {0x32, 0xff}, /* href */
- {0xc0, 0xaa},
-};
-
-static const u8 ov965x_start_1_svga[][2] = {
- {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */
- {0x36, 0xf8}, /* aref3 */
- {0x69, 0x02}, /* hv */
- {0x8c, 0x0d}, /* com22 */
- {0x3e, 0x0c}, /* com14 */
- {0x41, 0x40}, /* com16 */
- {0x72, 0x00},
- {0x73, 0x01},
- {0x74, 0x3a},
- {0x75, 0x35},
- {0x76, 0x01},
- {0xc7, 0x80}, /* com24 */
- {0x03, 0x1b}, /* vref */
- {0x17, 0x1d}, /* hstart */
- {0x18, 0xbd}, /* hstop */
- {0x19, 0x01}, /* vstrt */
- {0x1a, 0x81}, /* vstop */
- {0x32, 0xff}, /* href */
- {0xc0, 0xe2},
-};
-
-static const u8 ov965x_start_1_xga[][2] = {
- {0x12, 0x02}, /* com7 */
- {0x36, 0xf8}, /* aref3 */
- {0x69, 0x02}, /* hv */
- {0x8c, 0x89}, /* com22 */
- {0x14, 0x28}, /* com9 */
- {0x3e, 0x0c}, /* com14 */
- {0x41, 0x40}, /* com16 */
- {0x72, 0x00},
- {0x73, 0x01},
- {0x74, 0x3a},
- {0x75, 0x35},
- {0x76, 0x01},
- {0xc7, 0x80}, /* com24 */
- {0x03, 0x1b}, /* vref */
- {0x17, 0x1d}, /* hstart */
- {0x18, 0xbd}, /* hstop */
- {0x19, 0x01}, /* vstrt */
- {0x1a, 0x81}, /* vstop */
- {0x32, 0xff}, /* href */
- {0xc0, 0xe2},
-};
-
-static const u8 ov965x_start_1_sxga[][2] = {
- {0x12, 0x02}, /* com7 */
- {0x36, 0xf8}, /* aref3 */
- {0x69, 0x02}, /* hv */
- {0x8c, 0x89}, /* com22 */
- {0x14, 0x28}, /* com9 */
- {0x3e, 0x0c}, /* com14 */
- {0x41, 0x40}, /* com16 */
- {0x72, 0x00},
- {0x73, 0x01},
- {0x74, 0x3a},
- {0x75, 0x35},
- {0x76, 0x01},
- {0xc7, 0x80}, /* com24 */
- {0x03, 0x1b}, /* vref */
- {0x17, 0x1d}, /* hstart */
- {0x18, 0x02}, /* hstop */
- {0x19, 0x01}, /* vstrt */
- {0x1a, 0x81}, /* vstop */
- {0x32, 0xff}, /* href */
- {0xc0, 0xe2},
-};
-
-static const u8 bridge_start_qvga[][2] = {
- {0x94, 0xaa},
- {0xf1, 0x60},
- {0xe5, 0x04},
- {0xc0, 0x50},
- {0xc1, 0x3c},
- {0x8c, 0x00},
- {0x8d, 0x1c},
- {0x34, 0x05},
-
- {0xc2, 0x4c},
- {0xc3, 0xf9},
- {0xda, 0x00},
- {0x50, 0x00},
- {0x51, 0xa0},
- {0x52, 0x78},
- {0x53, 0x00},
- {0x54, 0x00},
- {0x55, 0x00},
- {0x57, 0x00},
- {0x5c, 0x00},
- {0x5a, 0x50},
- {0x5b, 0x3c},
- {0x35, 0x02},
- {0xd9, 0x10},
- {0x94, 0x11},
-};
-
-static const u8 bridge_start_vga[][2] = {
- {0x94, 0xaa},
- {0xf1, 0x60},
- {0xe5, 0x04},
- {0xc0, 0x50},
- {0xc1, 0x3c},
- {0x8c, 0x00},
- {0x8d, 0x1c},
- {0x34, 0x05},
- {0xc2, 0x0c},
- {0xc3, 0xf9},
- {0xda, 0x01},
- {0x50, 0x00},
- {0x51, 0xa0},
- {0x52, 0x3c},
- {0x53, 0x00},
- {0x54, 0x00},
- {0x55, 0x00},
- {0x57, 0x00},
- {0x5c, 0x00},
- {0x5a, 0xa0},
- {0x5b, 0x78},
- {0x35, 0x02},
- {0xd9, 0x10},
- {0x94, 0x11},
-};
-
-static const u8 bridge_start_svga[][2] = {
- {0x94, 0xaa},
- {0xf1, 0x60},
- {0xe5, 0x04},
- {0xc0, 0xa0},
- {0xc1, 0x80},
- {0x8c, 0x00},
- {0x8d, 0x1c},
- {0x34, 0x05},
- {0xc2, 0x4c},
- {0xc3, 0xf9},
- {0x50, 0x00},
- {0x51, 0x40},
- {0x52, 0x00},
- {0x53, 0x00},
- {0x54, 0x00},
- {0x55, 0x88},
- {0x57, 0x00},
- {0x5c, 0x00},
- {0x5a, 0xc8},
- {0x5b, 0x96},
- {0x35, 0x02},
- {0xd9, 0x10},
- {0xda, 0x00},
- {0x94, 0x11},
-};
-
-static const u8 bridge_start_xga[][2] = {
- {0x94, 0xaa},
- {0xf1, 0x60},
- {0xe5, 0x04},
- {0xc0, 0xa0},
- {0xc1, 0x80},
- {0x8c, 0x00},
- {0x8d, 0x1c},
- {0x34, 0x05},
- {0xc2, 0x4c},
- {0xc3, 0xf9},
- {0x50, 0x00},
- {0x51, 0x40},
- {0x52, 0x00},
- {0x53, 0x00},
- {0x54, 0x00},
- {0x55, 0x88},
- {0x57, 0x00},
- {0x5c, 0x01},
- {0x5a, 0x00},
- {0x5b, 0xc0},
- {0x35, 0x02},
- {0xd9, 0x10},
- {0xda, 0x01},
- {0x94, 0x11},
-};
-
-static const u8 bridge_start_sxga[][2] = {
- {0x94, 0xaa},
- {0xf1, 0x60},
- {0xe5, 0x04},
- {0xc0, 0xa0},
- {0xc1, 0x80},
- {0x8c, 0x00},
- {0x8d, 0x1c},
- {0x34, 0x05},
- {0xc2, 0x0c},
- {0xc3, 0xf9},
- {0xda, 0x00},
- {0x35, 0x02},
- {0xd9, 0x10},
- {0x94, 0x11},
-};
-
-static const u8 ov965x_start_2_qvga[][2] = {
- {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */
- {0x1e, 0x04}, /* mvfp */
- {0x13, 0xe0}, /* com8 */
- {0x00, 0x00},
- {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
- {0x11, 0x01}, /* clkrc */
- {0x6b, 0x5a}, /* dblv */
- {0x6a, 0x02}, /* 50 Hz banding filter */
- {0xc5, 0x03}, /* 60 Hz banding filter */
- {0xa2, 0x96}, /* bd50 */
- {0xa3, 0x7d}, /* bd60 */
-
- {0xff, 0x13}, /* read 13, write ff 00 */
- {0x13, 0xe7},
- {0x3a, 0x80}, /* tslb - yuyv */
-};
-
-static const u8 ov965x_start_2_vga[][2] = {
- {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
- {0x1e, 0x04}, /* mvfp */
- {0x13, 0xe0}, /* com8 */
- {0x00, 0x00},
- {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
- {0x11, 0x03}, /* clkrc */
- {0x6b, 0x5a}, /* dblv */
- {0x6a, 0x05}, /* 50 Hz banding filter */
- {0xc5, 0x07}, /* 60 Hz banding filter */
- {0xa2, 0x4b}, /* bd50 */
- {0xa3, 0x3e}, /* bd60 */
-
- {0x2d, 0x00}, /* advfl */
-};
-
-static const u8 ov965x_start_2_svga[][2] = { /* same for xga */
- {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
- {0x1e, 0x04}, /* mvfp */
- {0x13, 0xe0}, /* com8 */
- {0x00, 0x00},
- {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
- {0x11, 0x01}, /* clkrc */
- {0x6b, 0x5a}, /* dblv */
- {0x6a, 0x0c}, /* 50 Hz banding filter */
- {0xc5, 0x0f}, /* 60 Hz banding filter */
- {0xa2, 0x4e}, /* bd50 */
- {0xa3, 0x41}, /* bd60 */
-};
-
-static const u8 ov965x_start_2_sxga[][2] = {
- {0x13, 0xe0}, /* com8 */
- {0x00, 0x00},
- {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
- {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
- {0x1e, 0x04}, /* mvfp */
- {0x11, 0x01}, /* clkrc */
- {0x6b, 0x5a}, /* dblv */
- {0x6a, 0x0c}, /* 50 Hz banding filter */
- {0xc5, 0x0f}, /* 60 Hz banding filter */
- {0xa2, 0x4e}, /* bd50 */
- {0xa3, 0x41}, /* bd60 */
-};
-
-static const u8 ov562x_init[][2] = {
- {0x88, 0x20},
- {0x89, 0x0a},
- {0x8a, 0x90},
- {0x8b, 0x06},
- {0x8c, 0x01},
- {0x8d, 0x10},
- {0x1c, 0x00},
- {0x1d, 0x48},
- {0x1d, 0x00},
- {0x1d, 0xff},
- {0x1c, 0x0a},
- {0x1d, 0x2e},
- {0x1d, 0x1e},
-};
-
-static const u8 ov562x_init_2[][2] = {
- {0x12, 0x80},
- {0x11, 0x41},
- {0x13, 0x00},
- {0x10, 0x1e},
- {0x3b, 0x07},
- {0x5b, 0x40},
- {0x39, 0x07},
- {0x53, 0x02},
- {0x54, 0x60},
- {0x04, 0x20},
- {0x27, 0x04},
- {0x3d, 0x40},
- {0x36, 0x00},
- {0xc5, 0x04},
- {0x4e, 0x00},
- {0x4f, 0x93},
- {0x50, 0x7b},
- {0xca, 0x0c},
- {0xcb, 0x0f},
- {0x39, 0x07},
- {0x4a, 0x10},
- {0x3e, 0x0a},
- {0x3d, 0x00},
- {0x0c, 0x38},
- {0x38, 0x90},
- {0x46, 0x30},
- {0x4f, 0x93},
- {0x50, 0x7b},
- {0xab, 0x00},
- {0xca, 0x0c},
- {0xcb, 0x0f},
- {0x37, 0x02},
- {0x44, 0x48},
- {0x8d, 0x44},
- {0x2a, 0x00},
- {0x2b, 0x00},
- {0x32, 0x00},
- {0x38, 0x90},
- {0x53, 0x02},
- {0x54, 0x60},
- {0x12, 0x00},
- {0x17, 0x12},
- {0x18, 0xb4},
- {0x19, 0x0c},
- {0x1a, 0xf4},
- {0x03, 0x4a},
- {0x89, 0x20},
- {0x83, 0x80},
- {0xb7, 0x9d},
- {0xb6, 0x11},
- {0xb5, 0x55},
- {0xb4, 0x00},
- {0xa9, 0xf0},
- {0xa8, 0x0a},
- {0xb8, 0xf0},
- {0xb9, 0xf0},
- {0xba, 0xf0},
- {0x81, 0x07},
- {0x63, 0x44},
- {0x13, 0xc7},
- {0x14, 0x60},
- {0x33, 0x75},
- {0x2c, 0x00},
- {0x09, 0x00},
- {0x35, 0x30},
- {0x27, 0x04},
- {0x3c, 0x07},
- {0x3a, 0x0a},
- {0x3b, 0x07},
- {0x01, 0x40},
- {0x02, 0x40},
- {0x16, 0x40},
- {0x52, 0xb0},
- {0x51, 0x83},
- {0x21, 0xbb},
- {0x22, 0x10},
- {0x23, 0x03},
- {0x35, 0x38},
- {0x20, 0x90},
- {0x28, 0x30},
- {0x73, 0xe1},
- {0x6c, 0x00},
- {0x6d, 0x80},
- {0x6e, 0x00},
- {0x70, 0x04},
- {0x71, 0x00},
- {0x8d, 0x04},
- {0x64, 0x00},
- {0x65, 0x00},
- {0x66, 0x00},
- {0x67, 0x00},
- {0x68, 0x00},
- {0x69, 0x00},
- {0x6a, 0x00},
- {0x6b, 0x00},
- {0x71, 0x94},
- {0x74, 0x20},
- {0x80, 0x09},
- {0x85, 0xc0},
-};
-
-static void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val)
-{
- struct usb_device *udev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- gspca_dev->usb_buf[0] = val;
- ret = usb_control_msg(udev,
- usb_sndctrlpipe(udev, 0),
- 0x01,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
- if (ret < 0) {
- pr_err("reg_w failed %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void reg_w(struct gspca_dev *gspca_dev, u16 reg, u8 val)
-{
- PDEBUG(D_USBO, "reg_w [%04x] = %02x", reg, val);
- reg_w_i(gspca_dev, reg, val);
-}
-
-static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg)
-{
- struct usb_device *udev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return 0;
- ret = usb_control_msg(udev,
- usb_rcvctrlpipe(udev, 0),
- 0x01,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
- PDEBUG(D_USBI, "reg_r [%04x] -> %02x", reg, gspca_dev->usb_buf[0]);
- if (ret < 0) {
- pr_err("reg_r err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
- return gspca_dev->usb_buf[0];
-}
-
-static int sccb_check_status(struct gspca_dev *gspca_dev)
-{
- u8 data;
- int i;
-
- for (i = 0; i < 5; i++) {
- msleep(10);
- data = reg_r(gspca_dev, OV534_REG_STATUS);
-
- switch (data) {
- case 0x00:
- return 1;
- case 0x04:
- return 0;
- case 0x03:
- break;
- default:
- PDEBUG(D_USBI|D_USBO,
- "sccb status 0x%02x, attempt %d/5",
- data, i + 1);
- }
- }
- return 0;
-}
-
-static void sccb_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
-{
- PDEBUG(D_USBO, "sccb_write [%02x] = %02x", reg, val);
- reg_w_i(gspca_dev, OV534_REG_SUBADDR, reg);
- reg_w_i(gspca_dev, OV534_REG_WRITE, val);
- reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
-
- if (!sccb_check_status(gspca_dev))
- pr_err("sccb_write failed\n");
-}
-
-static u8 sccb_read(struct gspca_dev *gspca_dev, u16 reg)
-{
- reg_w(gspca_dev, OV534_REG_SUBADDR, reg);
- reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
- if (!sccb_check_status(gspca_dev))
- pr_err("sccb_read failed 1\n");
-
- reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
- if (!sccb_check_status(gspca_dev))
- pr_err("sccb_read failed 2\n");
-
- return reg_r(gspca_dev, OV534_REG_READ);
-}
-
-/* output a bridge sequence (reg - val) */
-static void reg_w_array(struct gspca_dev *gspca_dev,
- const u8 (*data)[2], int len)
-{
- while (--len >= 0) {
- reg_w(gspca_dev, (*data)[0], (*data)[1]);
- data++;
- }
-}
-
-/* output a sensor sequence (reg - val) */
-static void sccb_w_array(struct gspca_dev *gspca_dev,
- const u8 (*data)[2], int len)
-{
- while (--len >= 0) {
- if ((*data)[0] != 0xff) {
- sccb_write(gspca_dev, (*data)[0], (*data)[1]);
- } else {
- sccb_read(gspca_dev, (*data)[1]);
- sccb_write(gspca_dev, 0xff, 0x00);
- }
- data++;
- }
-}
-
-/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
- * (direction and output)? */
-static void set_led(struct gspca_dev *gspca_dev, int status)
-{
- u8 data;
-
- PDEBUG(D_CONF, "led status: %d", status);
-
- data = reg_r(gspca_dev, 0x21);
- data |= 0x80;
- reg_w(gspca_dev, 0x21, data);
-
- data = reg_r(gspca_dev, 0x23);
- if (status)
- data |= 0x80;
- else
- data &= ~0x80;
-
- reg_w(gspca_dev, 0x23, data);
-
- if (!status) {
- data = reg_r(gspca_dev, 0x21);
- data &= ~0x80;
- reg_w(gspca_dev, 0x21, data);
- }
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 val;
- s8 sval;
-
- if (sd->sensor == SENSOR_OV562x) {
- sval = brightness;
- val = 0x76;
- val += sval;
- sccb_write(gspca_dev, 0x24, val);
- val = 0x6a;
- val += sval;
- sccb_write(gspca_dev, 0x25, val);
- if (sval < -40)
- val = 0x71;
- else if (sval < 20)
- val = 0x94;
- else
- val = 0xe6;
- sccb_write(gspca_dev, 0x26, val);
- } else {
- val = brightness;
- if (val < 8)
- val = 15 - val; /* f .. 8 */
- else
- val = val - 8; /* 0 .. 7 */
- sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */
- 0x0f | (val << 4));
- }
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
-{
- sccb_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */
- val << 4);
-}
-
-static void setautogain(struct gspca_dev *gspca_dev, s32 autogain)
-{
- u8 val;
-
-/*fixme: should adjust agc/awb/aec by different controls */
- val = sccb_read(gspca_dev, 0x13); /* com8 */
- sccb_write(gspca_dev, 0xff, 0x00);
- if (autogain)
- val |= 0x05; /* agc & aec */
- else
- val &= 0xfa;
- sccb_write(gspca_dev, 0x13, val);
-}
-
-static void setexposure(struct gspca_dev *gspca_dev, s32 exposure)
-{
- static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
- u8 val;
-
- sccb_write(gspca_dev, 0x10, expo[exposure]); /* aec[9:2] */
-
- val = sccb_read(gspca_dev, 0x13); /* com8 */
- sccb_write(gspca_dev, 0xff, 0x00);
- sccb_write(gspca_dev, 0x13, val);
-
- val = sccb_read(gspca_dev, 0xa1); /* aech */
- sccb_write(gspca_dev, 0xff, 0x00);
- sccb_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */
-}
-
-static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
-{
- if (val < 0) { /* auto */
- val = sccb_read(gspca_dev, 0x42); /* com17 */
- sccb_write(gspca_dev, 0xff, 0x00);
- sccb_write(gspca_dev, 0x42, val | 0x40);
- /* Edge enhancement strength auto adjust */
- return;
- }
- if (val != 0)
- val = 1 << (val - 1);
- sccb_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */
- val);
- val = sccb_read(gspca_dev, 0x42); /* com17 */
- sccb_write(gspca_dev, 0xff, 0x00);
- sccb_write(gspca_dev, 0x42, val & 0xbf);
-}
-
-static void setsatur(struct gspca_dev *gspca_dev, s32 val)
-{
- u8 val1, val2, val3;
- static const u8 matrix[5][2] = {
- {0x14, 0x38},
- {0x1e, 0x54},
- {0x28, 0x70},
- {0x32, 0x8c},
- {0x48, 0x90}
- };
-
- val1 = matrix[val][0];
- val2 = matrix[val][1];
- val3 = val1 + val2;
- sccb_write(gspca_dev, 0x4f, val3); /* matrix coeff */
- sccb_write(gspca_dev, 0x50, val3);
- sccb_write(gspca_dev, 0x51, 0x00);
- sccb_write(gspca_dev, 0x52, val1);
- sccb_write(gspca_dev, 0x53, val2);
- sccb_write(gspca_dev, 0x54, val3);
- sccb_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */
-
- val1 = sccb_read(gspca_dev, 0x41); /* com16 */
- sccb_write(gspca_dev, 0xff, 0x00);
- sccb_write(gspca_dev, 0x41, val1);
-}
-
-static void setlightfreq(struct gspca_dev *gspca_dev, s32 freq)
-{
- u8 val;
-
- val = sccb_read(gspca_dev, 0x13); /* com8 */
- sccb_write(gspca_dev, 0xff, 0x00);
- if (freq == 0) {
- sccb_write(gspca_dev, 0x13, val & 0xdf);
- return;
- }
- sccb_write(gspca_dev, 0x13, val | 0x20);
-
- val = sccb_read(gspca_dev, 0x42); /* com17 */
- sccb_write(gspca_dev, 0xff, 0x00);
- if (freq == 1)
- val |= 0x01;
- else
- val &= 0xfe;
- sccb_write(gspca_dev, 0x42, val);
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u16 sensor_id;
-
- /* reset bridge */
- reg_w(gspca_dev, 0xe7, 0x3a);
- reg_w(gspca_dev, 0xe0, 0x08);
- msleep(100);
-
- /* initialize the sensor address */
- reg_w(gspca_dev, OV534_REG_ADDRESS, 0x60);
-
- /* reset sensor */
- sccb_write(gspca_dev, 0x12, 0x80);
- msleep(10);
-
- /* probe the sensor */
- sccb_read(gspca_dev, 0x0a);
- sensor_id = sccb_read(gspca_dev, 0x0a) << 8;
- sccb_read(gspca_dev, 0x0b);
- sensor_id |= sccb_read(gspca_dev, 0x0b);
- PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
-
- /* initialize */
- if ((sensor_id & 0xfff0) == 0x9650) {
- sd->sensor = SENSOR_OV965x;
-
- gspca_dev->cam.cam_mode = ov965x_mode;
- gspca_dev->cam.nmodes = ARRAY_SIZE(ov965x_mode);
-
- reg_w_array(gspca_dev, bridge_init,
- ARRAY_SIZE(bridge_init));
- sccb_w_array(gspca_dev, ov965x_init,
- ARRAY_SIZE(ov965x_init));
- reg_w_array(gspca_dev, bridge_init_2,
- ARRAY_SIZE(bridge_init_2));
- sccb_w_array(gspca_dev, ov965x_init_2,
- ARRAY_SIZE(ov965x_init_2));
- reg_w(gspca_dev, 0xe0, 0x00);
- reg_w(gspca_dev, 0xe0, 0x01);
- set_led(gspca_dev, 0);
- reg_w(gspca_dev, 0xe0, 0x00);
- } else if ((sensor_id & 0xfff0) == 0x9710) {
- const char *p;
- int l;
-
- sd->sensor = SENSOR_OV971x;
-
- gspca_dev->cam.cam_mode = ov971x_mode;
- gspca_dev->cam.nmodes = ARRAY_SIZE(ov971x_mode);
-
- gspca_dev->cam.bulk = 1;
- gspca_dev->cam.bulk_size = 16384;
- gspca_dev->cam.bulk_nurbs = 2;
-
- sccb_w_array(gspca_dev, ov971x_init,
- ARRAY_SIZE(ov971x_init));
-
- /* set video format on bridge processor */
- /* access bridge processor's video format registers at: 0x00 */
- reg_w(gspca_dev, 0x1c, 0x00);
- /*set register: 0x00 is 'RAW8', 0x40 is 'YUV422' (YUYV?)*/
- reg_w(gspca_dev, 0x1d, 0x00);
-
- /* Will W. specific stuff
- * set VSYNC to
- * output (0x1f) if first webcam
- * input (0x17) if 2nd or 3rd webcam */
- p = video_device_node_name(&gspca_dev->vdev);
- l = strlen(p) - 1;
- if (p[l] == '0')
- reg_w(gspca_dev, 0x56, 0x1f);
- else
- reg_w(gspca_dev, 0x56, 0x17);
- } else if ((sensor_id & 0xfff0) == 0x5620) {
- sd->sensor = SENSOR_OV562x;
- gspca_dev->cam.cam_mode = ov562x_mode;
- gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode);
-
- reg_w_array(gspca_dev, ov562x_init,
- ARRAY_SIZE(ov562x_init));
- sccb_w_array(gspca_dev, ov562x_init_2,
- ARRAY_SIZE(ov562x_init_2));
- reg_w(gspca_dev, 0xe0, 0x00);
- } else {
- pr_err("Unknown sensor %04x", sensor_id);
- return -EINVAL;
- }
-
- return gspca_dev->usb_err;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_OV971x)
- return gspca_dev->usb_err;
- if (sd->sensor == SENSOR_OV562x)
- return gspca_dev->usb_err;
-
- switch (gspca_dev->curr_mode) {
- case QVGA_MODE: /* 320x240 */
- sccb_w_array(gspca_dev, ov965x_start_1_vga,
- ARRAY_SIZE(ov965x_start_1_vga));
- reg_w_array(gspca_dev, bridge_start_qvga,
- ARRAY_SIZE(bridge_start_qvga));
- sccb_w_array(gspca_dev, ov965x_start_2_qvga,
- ARRAY_SIZE(ov965x_start_2_qvga));
- break;
- case VGA_MODE: /* 640x480 */
- sccb_w_array(gspca_dev, ov965x_start_1_vga,
- ARRAY_SIZE(ov965x_start_1_vga));
- reg_w_array(gspca_dev, bridge_start_vga,
- ARRAY_SIZE(bridge_start_vga));
- sccb_w_array(gspca_dev, ov965x_start_2_vga,
- ARRAY_SIZE(ov965x_start_2_vga));
- break;
- case SVGA_MODE: /* 800x600 */
- sccb_w_array(gspca_dev, ov965x_start_1_svga,
- ARRAY_SIZE(ov965x_start_1_svga));
- reg_w_array(gspca_dev, bridge_start_svga,
- ARRAY_SIZE(bridge_start_svga));
- sccb_w_array(gspca_dev, ov965x_start_2_svga,
- ARRAY_SIZE(ov965x_start_2_svga));
- break;
- case XGA_MODE: /* 1024x768 */
- sccb_w_array(gspca_dev, ov965x_start_1_xga,
- ARRAY_SIZE(ov965x_start_1_xga));
- reg_w_array(gspca_dev, bridge_start_xga,
- ARRAY_SIZE(bridge_start_xga));
- sccb_w_array(gspca_dev, ov965x_start_2_svga,
- ARRAY_SIZE(ov965x_start_2_svga));
- break;
- default:
-/* case SXGA_MODE: * 1280x1024 */
- sccb_w_array(gspca_dev, ov965x_start_1_sxga,
- ARRAY_SIZE(ov965x_start_1_sxga));
- reg_w_array(gspca_dev, bridge_start_sxga,
- ARRAY_SIZE(bridge_start_sxga));
- sccb_w_array(gspca_dev, ov965x_start_2_sxga,
- ARRAY_SIZE(ov965x_start_2_sxga));
- break;
- }
-
- reg_w(gspca_dev, 0xe0, 0x00);
- reg_w(gspca_dev, 0xe0, 0x00);
- set_led(gspca_dev, 1);
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- reg_w(gspca_dev, 0xe0, 0x01);
- set_led(gspca_dev, 0);
- reg_w(gspca_dev, 0xe0, 0x00);
-}
-
-/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
-#define UVC_STREAM_EOH (1 << 7)
-#define UVC_STREAM_ERR (1 << 6)
-#define UVC_STREAM_STI (1 << 5)
-#define UVC_STREAM_RES (1 << 4)
-#define UVC_STREAM_SCR (1 << 3)
-#define UVC_STREAM_PTS (1 << 2)
-#define UVC_STREAM_EOF (1 << 1)
-#define UVC_STREAM_FID (1 << 0)
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- __u32 this_pts;
- u8 this_fid;
- int remaining_len = len;
- int payload_len;
-
- payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
- do {
- len = min(remaining_len, payload_len);
-
- /* Payloads are prefixed with a UVC-style header. We
- consider a frame to start when the FID toggles, or the PTS
- changes. A frame ends when EOF is set, and we've received
- the correct number of bytes. */
-
- /* Verify UVC header. Header length is always 12 */
- if (data[0] != 12 || len < 12) {
- PDEBUG(D_PACK, "bad header");
- goto discard;
- }
-
- /* Check errors */
- if (data[1] & UVC_STREAM_ERR) {
- PDEBUG(D_PACK, "payload error");
- goto discard;
- }
-
- /* Extract PTS and FID */
- if (!(data[1] & UVC_STREAM_PTS)) {
- PDEBUG(D_PACK, "PTS not present");
- goto discard;
- }
- this_pts = (data[5] << 24) | (data[4] << 16)
- | (data[3] << 8) | data[2];
- this_fid = data[1] & UVC_STREAM_FID;
-
- /* If PTS or FID has changed, start a new frame. */
- if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
- if (gspca_dev->last_packet_type == INTER_PACKET)
- gspca_frame_add(gspca_dev, LAST_PACKET,
- NULL, 0);
- sd->last_pts = this_pts;
- sd->last_fid = this_fid;
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- data + 12, len - 12);
- /* If this packet is marked as EOF, end the frame */
- } else if (data[1] & UVC_STREAM_EOF) {
- sd->last_pts = 0;
- gspca_frame_add(gspca_dev, LAST_PACKET,
- data + 12, len - 12);
- } else {
-
- /* Add the data from this payload */
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data + 12, len - 12);
- }
-
- /* Done this payload */
- goto scan_next;
-
-discard:
- /* Discard data until a new frame starts. */
- gspca_dev->last_packet_type = DISCARD_PACKET;
-
-scan_next:
- remaining_len -= len;
- data += len;
- } while (remaining_len > 0);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- setsatur(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY:
- setlightfreq(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SHARPNESS:
- setsharpness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_AUTOGAIN:
- if (ctrl->is_new)
- setautogain(gspca_dev, ctrl->val);
- if (!ctrl->val && gspca_dev->exposure->is_new)
- setexposure(gspca_dev, gspca_dev->exposure->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- if (sd->sensor == SENSOR_OV971x)
- return 0;
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 7);
- if (sd->sensor == SENSOR_OV562x) {
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, -90, 90, 1, 0);
- } else {
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 15, 1, 7);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 15, 1, 3);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0, 4, 1, 2);
- /* -1 = auto */
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SHARPNESS, -1, 4, 1, -1);
- gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 3, 1, 0);
- v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
- V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0);
- v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
- }
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x05a9, 0x8065)},
- {USB_DEVICE(0x06f8, 0x3003)},
- {USB_DEVICE(0x05a9, 0x1550)},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
deleted file mode 100644
index d236d1791f7..00000000000
--- a/drivers/media/video/gspca/pac207.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Pixart PAC207BCA library
- *
- * Copyright (C) 2008 Hans de Goede <hdegoede@redhat.com>
- * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
- * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr
- *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "pac207"
-
-#include <linux/input.h>
-#include "gspca.h"
-/* Include pac common sof detection functions */
-#include "pac_common.h"
-
-MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
-MODULE_DESCRIPTION("Pixart PAC207");
-MODULE_LICENSE("GPL");
-
-#define PAC207_CTRL_TIMEOUT 100 /* ms */
-
-#define PAC207_BRIGHTNESS_MIN 0
-#define PAC207_BRIGHTNESS_MAX 255
-#define PAC207_BRIGHTNESS_DEFAULT 46
-#define PAC207_BRIGHTNESS_REG 0x08
-
-#define PAC207_EXPOSURE_MIN 3
-#define PAC207_EXPOSURE_MAX 90 /* 1 sec expo time / 1 fps */
-#define PAC207_EXPOSURE_DEFAULT 5 /* power on default: 3 */
-#define PAC207_EXPOSURE_REG 0x02
-
-#define PAC207_GAIN_MIN 0
-#define PAC207_GAIN_MAX 31
-#define PAC207_GAIN_DEFAULT 7 /* power on default: 9 */
-#define PAC207_GAIN_REG 0x0e
-
-#define PAC207_AUTOGAIN_DEADZONE 30
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- struct v4l2_ctrl *brightness;
-
- u8 mode;
- u8 sof_read;
- u8 header_read;
- u8 autogain_ignore_frames;
-
- atomic_t avg_lum;
-};
-
-static const struct v4l2_pix_format sif_mode[] = {
- {176, 144, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = (176 + 2) * 144,
- /* uncompressed, add 2 bytes / line for line header */
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {352, 288, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE,
- .bytesperline = 352,
- /* compressed, but only when needed (not compressed
- when the framerate is low) */
- .sizeimage = (352 + 2) * 288,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-static const __u8 pac207_sensor_init[][8] = {
- {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0x84},
- {0x49, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30},
- {0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00},
- {0x32, 0x00, 0x96, 0x00, 0xa2, 0x02, 0xaf, 0x00},
-};
-
-static void pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
- const u8 *buffer, u16 length)
-{
- struct usb_device *udev = gspca_dev->dev;
- int err;
-
- if (gspca_dev->usb_err < 0)
- return;
-
- memcpy(gspca_dev->usb_buf, buffer, length);
-
- err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- 0x00, index,
- gspca_dev->usb_buf, length, PAC207_CTRL_TIMEOUT);
- if (err < 0) {
- pr_err("Failed to write registers to index 0x%04X, error %d\n",
- index, err);
- gspca_dev->usb_err = err;
- }
-}
-
-static void pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
-{
- struct usb_device *udev = gspca_dev->dev;
- int err;
-
- if (gspca_dev->usb_err < 0)
- return;
-
- err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- value, index, NULL, 0, PAC207_CTRL_TIMEOUT);
- if (err) {
- pr_err("Failed to write a register (index 0x%04X, value 0x%02X, error %d)\n",
- index, value, err);
- gspca_dev->usb_err = err;
- }
-}
-
-static int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
-{
- struct usb_device *udev = gspca_dev->dev;
- int res;
-
- if (gspca_dev->usb_err < 0)
- return 0;
-
- res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- 0x00, index,
- gspca_dev->usb_buf, 1, PAC207_CTRL_TIMEOUT);
- if (res < 0) {
- pr_err("Failed to read a register (index 0x%04X, error %d)\n",
- index, res);
- gspca_dev->usb_err = res;
- return 0;
- }
-
- return gspca_dev->usb_buf[0];
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct cam *cam;
- u8 idreg[2];
-
- idreg[0] = pac207_read_reg(gspca_dev, 0x0000);
- idreg[1] = pac207_read_reg(gspca_dev, 0x0001);
- idreg[0] = ((idreg[0] & 0x0f) << 4) | ((idreg[1] & 0xf0) >> 4);
- idreg[1] = idreg[1] & 0x0f;
- PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X",
- idreg[0], idreg[1]);
-
- if (idreg[0] != 0x27) {
- PDEBUG(D_PROBE, "Error invalid sensor ID!");
- return -ENODEV;
- }
-
- PDEBUG(D_PROBE,
- "Pixart PAC207BCA Image Processor and Control Chip detected"
- " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
-
- cam = &gspca_dev->cam;
- cam->cam_mode = sif_mode;
- cam->nmodes = ARRAY_SIZE(sif_mode);
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- pac207_write_reg(gspca_dev, 0x41, 0x00);
- /* Bit_0=Image Format,
- * Bit_1=LED,
- * Bit_2=Compression test mode enable */
- pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
-
- return gspca_dev->usb_err;
-}
-
-static void setcontrol(struct gspca_dev *gspca_dev, u16 reg, u16 val)
-{
- pac207_write_reg(gspca_dev, reg, val);
- pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
- pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
- /* when switching to autogain set defaults to make sure
- we are on a valid point of the autogain gain /
- exposure knee graph, and give this change time to
- take effect before doing autogain. */
- gspca_dev->exposure->val = PAC207_EXPOSURE_DEFAULT;
- gspca_dev->gain->val = PAC207_GAIN_DEFAULT;
- sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
- }
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setcontrol(gspca_dev, PAC207_BRIGHTNESS_REG, ctrl->val);
- break;
- case V4L2_CID_AUTOGAIN:
- if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
- setcontrol(gspca_dev, PAC207_EXPOSURE_REG,
- gspca_dev->exposure->val);
- if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
- setcontrol(gspca_dev, PAC207_GAIN_REG,
- gspca_dev->gain->val);
- break;
- default:
- return -EINVAL;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-/* this function is called at probe time */
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 4);
-
- sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS,
- PAC207_BRIGHTNESS_MIN, PAC207_BRIGHTNESS_MAX,
- 1, PAC207_BRIGHTNESS_DEFAULT);
- gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE,
- PAC207_EXPOSURE_MIN, PAC207_EXPOSURE_MAX,
- 1, PAC207_EXPOSURE_DEFAULT);
- gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN,
- PAC207_GAIN_MIN, PAC207_GAIN_MAX,
- 1, PAC207_GAIN_DEFAULT);
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
- return 0;
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- __u8 mode;
-
- pac207_write_reg(gspca_dev, 0x0f, 0x10); /* Power control (Bit 6-0) */
- pac207_write_regs(gspca_dev, 0x0002, pac207_sensor_init[0], 8);
- pac207_write_regs(gspca_dev, 0x000a, pac207_sensor_init[1], 8);
- pac207_write_regs(gspca_dev, 0x0012, pac207_sensor_init[2], 8);
- pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[3], 8);
-
- /* Compression Balance */
- if (gspca_dev->width == 176)
- pac207_write_reg(gspca_dev, 0x4a, 0xff);
- else
- pac207_write_reg(gspca_dev, 0x4a, 0x30);
- pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */
- pac207_write_reg(gspca_dev, 0x08, v4l2_ctrl_g_ctrl(sd->brightness));
-
- /* PGA global gain (Bit 4-0) */
- pac207_write_reg(gspca_dev, 0x0e,
- v4l2_ctrl_g_ctrl(gspca_dev->gain));
- pac207_write_reg(gspca_dev, 0x02,
- v4l2_ctrl_g_ctrl(gspca_dev->exposure)); /* PXCK = 12MHz /n */
-
- mode = 0x02; /* Image Format (Bit 0), LED (1), Compr. test mode (2) */
- if (gspca_dev->width == 176) { /* 176x144 */
- mode |= 0x01;
- PDEBUG(D_STREAM, "pac207_start mode 176x144");
- } else { /* 352x288 */
- PDEBUG(D_STREAM, "pac207_start mode 352x288");
- }
- pac207_write_reg(gspca_dev, 0x41, mode);
-
- pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
- pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
- msleep(10);
- pac207_write_reg(gspca_dev, 0x40, 0x01); /* Start ISO pipe */
-
- sd->sof_read = 0;
- sd->autogain_ignore_frames = 0;
- atomic_set(&sd->avg_lum, -1);
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- pac207_write_reg(gspca_dev, 0x40, 0x00); /* Stop ISO pipe */
- pac207_write_reg(gspca_dev, 0x41, 0x00); /* Turn of LED */
- pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
-}
-
-
-static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int avg_lum = atomic_read(&sd->avg_lum);
-
- if (avg_lum == -1)
- return;
-
- if (sd->autogain_ignore_frames > 0)
- sd->autogain_ignore_frames--;
- else if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
- 90, PAC207_AUTOGAIN_DEADZONE))
- sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data,
- int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- unsigned char *sof;
-
- sof = pac_find_sof(&sd->sof_read, data, len);
- if (sof) {
- int n;
-
- /* finish decoding current frame */
- n = sof - data;
- if (n > sizeof pac_sof_marker)
- n -= sizeof pac_sof_marker;
- else
- n = 0;
- gspca_frame_add(gspca_dev, LAST_PACKET,
- data, n);
- sd->header_read = 0;
- gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
- len -= sof - data;
- data = sof;
- }
- if (sd->header_read < 11) {
- int needed;
-
- /* get average lumination from frame header (byte 5) */
- if (sd->header_read < 5) {
- needed = 5 - sd->header_read;
- if (len >= needed)
- atomic_set(&sd->avg_lum, data[needed - 1]);
- }
- /* skip the rest of the header */
- needed = 11 - sd->header_read;
- if (len <= needed) {
- sd->header_read += len;
- return;
- }
- data += needed;
- len -= needed;
- sd->header_read = 11;
- }
-
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
-static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* interrupt packet data */
- int len) /* interrput packet length */
-{
- int ret = -EINVAL;
-
- if (len == 2 && data[0] == 0x5a && data[1] == 0x5a) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
- input_sync(gspca_dev->input_dev);
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
- input_sync(gspca_dev->input_dev);
- ret = 0;
- }
-
- return ret;
-}
-#endif
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .dq_callback = pac207_do_auto_gain,
- .pkt_scan = sd_pkt_scan,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .int_pkt_scan = sd_int_pkt_scan,
-#endif
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x041e, 0x4028)},
- {USB_DEVICE(0x093a, 0x2460)},
- {USB_DEVICE(0x093a, 0x2461)},
- {USB_DEVICE(0x093a, 0x2463)},
- {USB_DEVICE(0x093a, 0x2464)},
- {USB_DEVICE(0x093a, 0x2468)},
- {USB_DEVICE(0x093a, 0x2470)},
- {USB_DEVICE(0x093a, 0x2471)},
- {USB_DEVICE(0x093a, 0x2472)},
- {USB_DEVICE(0x093a, 0x2474)},
- {USB_DEVICE(0x093a, 0x2476)},
- {USB_DEVICE(0x145f, 0x013a)},
- {USB_DEVICE(0x2001, 0xf115)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c
deleted file mode 100644
index 4877f7ab3d5..00000000000
--- a/drivers/media/video/gspca/pac7302.c
+++ /dev/null
@@ -1,932 +0,0 @@
-/*
- * Pixart PAC7302 driver
- *
- * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr>
- * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
- *
- * Separated from Pixart PAC7311 library by Márton Németh
- * Camera button input handling by Márton Németh <nm127@freemail.hu>
- * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Some documentation about various registers as determined by trial and error.
- *
- * Register page 1:
- *
- * Address Description
- * 0x78 Global control, bit 6 controls the LED (inverted)
- * 0x80 Compression balance, 2 interesting settings:
- * 0x0f Default
- * 0x50 Values >= this switch the camera to a lower compression,
- * using the same table for both luminance and chrominance.
- * This gives a sharper picture. Only usable when running
- * at < 15 fps! Note currently the driver does not use this
- * as the quality gain is small and the generated JPG-s are
- * only understood by v4l-utils >= 0.8.9
- *
- * Register page 3:
- *
- * Address Description
- * 0x02 Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
- * the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
- * 0x03 Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
- * 0x04 Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
- * 63 -> ~27 fps, the 2 msb's must always be 1 !!
- * 0x05 Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
- * 1 -> ~30 fps, 2 -> ~20 fps
- * 0x0e Exposure bits 0-7, 0-448, 0 = use full frame time
- * 0x0f Exposure bit 8, 0-448, 448 = no exposure at all
- * 0x10 Gain 0-31
- * 0x12 Another gain 0-31, unlike 0x10 this one seems to start with an
- * amplification value of 1 rather then 0 at its lowest setting
- * 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
- * 0x80 Another framerate control, best left at 1, moving it from 1 to
- * 2 causes the framerate to become 3/4th of what it was, and
- * also seems to cause pixel averaging, resulting in an effective
- * resolution of 320x240 and thus a much blockier image
- *
- * The registers are accessed in the following functions:
- *
- * Page | Register | Function
- * -----+------------+---------------------------------------------------
- * 0 | 0x0f..0x20 | setcolors()
- * 0 | 0xa2..0xab | setbrightcont()
- * 0 | 0xc5 | setredbalance()
- * 0 | 0xc6 | setwhitebalance()
- * 0 | 0xc7 | setbluebalance()
- * 0 | 0xdc | setbrightcont(), setcolors()
- * 3 | 0x02 | setexposure()
- * 3 | 0x10, 0x12 | setgain()
- * 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip()
- * 3 | 0x21 | sethvflip()
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/input.h>
-#include <media/v4l2-chip-ident.h>
-#include "gspca.h"
-/* Include pac common sof detection functions */
-#include "pac_common.h"
-
-#define PAC7302_GAIN_DEFAULT 15
-#define PAC7302_GAIN_KNEE 42
-#define PAC7302_EXPOSURE_DEFAULT 66 /* 33 ms / 30 fps */
-#define PAC7302_EXPOSURE_KNEE 133 /* 66 ms / 15 fps */
-
-MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
- "Thomas Kaiser thomas@kaiser-linux.li");
-MODULE_DESCRIPTION("Pixart PAC7302");
-MODULE_LICENSE("GPL");
-
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- struct { /* brightness / contrast cluster */
- struct v4l2_ctrl *brightness;
- struct v4l2_ctrl *contrast;
- };
- struct v4l2_ctrl *saturation;
- struct v4l2_ctrl *white_balance;
- struct v4l2_ctrl *red_balance;
- struct v4l2_ctrl *blue_balance;
- struct { /* flip cluster */
- struct v4l2_ctrl *hflip;
- struct v4l2_ctrl *vflip;
- };
- u8 flags;
-#define FL_HFLIP 0x01 /* mirrored by default */
-#define FL_VFLIP 0x02 /* vertical flipped by default */
-
- u8 sof_read;
- s8 autogain_ignore_frames;
-
- atomic_t avg_lum;
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- },
-};
-
-#define LOAD_PAGE3 255
-#define END_OF_SEQUENCE 0
-
-static const u8 init_7302[] = {
-/* index,value */
- 0xff, 0x01, /* page 1 */
- 0x78, 0x00, /* deactivate */
- 0xff, 0x01,
- 0x78, 0x40, /* led off */
-};
-static const u8 start_7302[] = {
-/* index, len, [value]* */
- 0xff, 1, 0x00, /* page 0 */
- 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
- 0x00, 0x00, 0x00, 0x00,
- 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
- 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
- 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
- 0x26, 2, 0xaa, 0xaa,
- 0x2e, 1, 0x31,
- 0x38, 1, 0x01,
- 0x3a, 3, 0x14, 0xff, 0x5a,
- 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
- 0x00, 0x54, 0x11,
- 0x55, 1, 0x00,
- 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
- 0x6b, 1, 0x00,
- 0x6e, 3, 0x08, 0x06, 0x00,
- 0x72, 3, 0x00, 0xff, 0x00,
- 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
- 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
- 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
- 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
- 0xd2, 0xeb,
- 0xaf, 1, 0x02,
- 0xb5, 2, 0x08, 0x08,
- 0xb8, 2, 0x08, 0x88,
- 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
- 0xcc, 1, 0x00,
- 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
- 0xc1, 0xd7, 0xec,
- 0xdc, 1, 0x01,
- 0xff, 1, 0x01, /* page 1 */
- 0x12, 3, 0x02, 0x00, 0x01,
- 0x3e, 2, 0x00, 0x00,
- 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
- 0x7c, 1, 0x00,
- 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
- 0x02, 0x00,
- 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
- 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
- 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
- 0xd8, 1, 0x01,
- 0xdb, 2, 0x00, 0x01,
- 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
- 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
- 0xeb, 1, 0x00,
- 0xff, 1, 0x02, /* page 2 */
- 0x22, 1, 0x00,
- 0xff, 1, 0x03, /* page 3 */
- 0, LOAD_PAGE3, /* load the page 3 */
- 0x11, 1, 0x01,
- 0xff, 1, 0x02, /* page 2 */
- 0x13, 1, 0x00,
- 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
- 0x27, 2, 0x14, 0x0c,
- 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
- 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
- 0x6e, 1, 0x08,
- 0xff, 1, 0x01, /* page 1 */
- 0x78, 1, 0x00,
- 0, END_OF_SEQUENCE /* end of sequence */
-};
-
-#define SKIP 0xaa
-/* page 3 - the value SKIP says skip the index - see reg_w_page() */
-static const u8 page3_7302[] = {
- 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
- 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
- 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
- 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
- 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
- 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
- 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
- SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
- 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
- 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
- 0x00
-};
-
-static void reg_w_buf(struct gspca_dev *gspca_dev,
- u8 index,
- const u8 *buffer, int len)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- memcpy(gspca_dev->usb_buf, buffer, len);
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, /* value */
- index, gspca_dev->usb_buf, len,
- 500);
- if (ret < 0) {
- pr_err("reg_w_buf failed i: %02x error %d\n",
- index, ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-
-static void reg_w(struct gspca_dev *gspca_dev,
- u8 index,
- u8 value)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- gspca_dev->usb_buf[0] = value;
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, index, gspca_dev->usb_buf, 1,
- 500);
- if (ret < 0) {
- pr_err("reg_w() failed i: %02x v: %02x error %d\n",
- index, value, ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void reg_w_seq(struct gspca_dev *gspca_dev,
- const u8 *seq, int len)
-{
- while (--len >= 0) {
- reg_w(gspca_dev, seq[0], seq[1]);
- seq += 2;
- }
-}
-
-/* load the beginning of a page */
-static void reg_w_page(struct gspca_dev *gspca_dev,
- const u8 *page, int len)
-{
- int index;
- int ret = 0;
-
- if (gspca_dev->usb_err < 0)
- return;
- for (index = 0; index < len; index++) {
- if (page[index] == SKIP) /* skip this index */
- continue;
- gspca_dev->usb_buf[0] = page[index];
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, index, gspca_dev->usb_buf, 1,
- 500);
- if (ret < 0) {
- pr_err("reg_w_page() failed i: %02x v: %02x error %d\n",
- index, page[index], ret);
- gspca_dev->usb_err = ret;
- break;
- }
- }
-}
-
-/* output a variable sequence */
-static void reg_w_var(struct gspca_dev *gspca_dev,
- const u8 *seq,
- const u8 *page3, unsigned int page3_len)
-{
- int index, len;
-
- for (;;) {
- index = *seq++;
- len = *seq++;
- switch (len) {
- case END_OF_SEQUENCE:
- return;
- case LOAD_PAGE3:
- reg_w_page(gspca_dev, page3, page3_len);
- break;
- default:
-#ifdef GSPCA_DEBUG
- if (len > USB_BUF_SZ) {
- PDEBUG(D_ERR|D_STREAM,
- "Incorrect variable sequence");
- return;
- }
-#endif
- while (len > 0) {
- if (len < 8) {
- reg_w_buf(gspca_dev,
- index, seq, len);
- seq += len;
- break;
- }
- reg_w_buf(gspca_dev, index, seq, 8);
- seq += 8;
- index += 8;
- len -= 8;
- }
- }
- }
- /* not reached */
-}
-
-/* this function is called at probe time for pac7302 */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
-
- cam = &gspca_dev->cam;
-
- cam->cam_mode = vga_mode; /* only 640x480 */
- cam->nmodes = ARRAY_SIZE(vga_mode);
-
- sd->flags = id->driver_info;
- return 0;
-}
-
-static void setbrightcont(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i, v;
- static const u8 max[10] =
- {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
- 0xd4, 0xec};
- static const u8 delta[10] =
- {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
- 0x11, 0x0b};
-
- reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
- for (i = 0; i < 10; i++) {
- v = max[i];
- v += (sd->brightness->val - sd->brightness->maximum)
- * 150 / sd->brightness->maximum; /* 200 ? */
- v -= delta[i] * sd->contrast->val / sd->contrast->maximum;
- if (v < 0)
- v = 0;
- else if (v > 0xff)
- v = 0xff;
- reg_w(gspca_dev, 0xa2 + i, v);
- }
- reg_w(gspca_dev, 0xdc, 0x01);
-}
-
-static void setcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i, v;
- static const int a[9] =
- {217, -212, 0, -101, 170, -67, -38, -315, 355};
- static const int b[9] =
- {19, 106, 0, 19, 106, 1, 19, 106, 1};
-
- reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
- reg_w(gspca_dev, 0x11, 0x01);
- reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
- for (i = 0; i < 9; i++) {
- v = a[i] * sd->saturation->val / sd->saturation->maximum;
- v += b[i];
- reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
- reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
- }
- reg_w(gspca_dev, 0xdc, 0x01);
-}
-
-static void setwhitebalance(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
- reg_w(gspca_dev, 0xc6, sd->white_balance->val);
-
- reg_w(gspca_dev, 0xdc, 0x01);
-}
-
-static void setredbalance(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
- reg_w(gspca_dev, 0xc5, sd->red_balance->val);
-
- reg_w(gspca_dev, 0xdc, 0x01);
-}
-
-static void setbluebalance(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
- reg_w(gspca_dev, 0xc7, sd->blue_balance->val);
-
- reg_w(gspca_dev, 0xdc, 0x01);
-}
-
-static void setgain(struct gspca_dev *gspca_dev)
-{
- u8 reg10, reg12;
-
- if (gspca_dev->gain->val < 32) {
- reg10 = gspca_dev->gain->val;
- reg12 = 0;
- } else {
- reg10 = 31;
- reg12 = gspca_dev->gain->val - 31;
- }
-
- reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
- reg_w(gspca_dev, 0x10, reg10);
- reg_w(gspca_dev, 0x12, reg12);
-
- /* load registers to sensor (Bit 0, auto clear) */
- reg_w(gspca_dev, 0x11, 0x01);
-}
-
-static void setexposure(struct gspca_dev *gspca_dev)
-{
- u8 clockdiv;
- u16 exposure;
-
- /*
- * Register 2 of frame 3 contains the clock divider configuring the
- * no fps according to the formula: 90 / reg. sd->exposure is the
- * desired exposure time in 0.5 ms.
- */
- clockdiv = (90 * gspca_dev->exposure->val + 1999) / 2000;
-
- /*
- * Note clockdiv = 3 also works, but when running at 30 fps, depending
- * on the scene being recorded, the camera switches to another
- * quantization table for certain JPEG blocks, and we don't know how
- * to decompress these blocks. So we cap the framerate at 15 fps.
- */
- if (clockdiv < 6)
- clockdiv = 6;
- else if (clockdiv > 63)
- clockdiv = 63;
-
- /*
- * Register 2 MUST be a multiple of 3, except when between 6 and 12?
- * Always round up, otherwise we cannot get the desired frametime
- * using the partial frame time exposure control.
- */
- if (clockdiv < 6 || clockdiv > 12)
- clockdiv = ((clockdiv + 2) / 3) * 3;
-
- /*
- * frame exposure time in ms = 1000 * clockdiv / 90 ->
- * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
- */
- exposure = (gspca_dev->exposure->val * 45 * 448) / (1000 * clockdiv);
- /* 0 = use full frametime, 448 = no exposure, reverse it */
- exposure = 448 - exposure;
-
- reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
- reg_w(gspca_dev, 0x02, clockdiv);
- reg_w(gspca_dev, 0x0e, exposure & 0xff);
- reg_w(gspca_dev, 0x0f, exposure >> 8);
-
- /* load registers to sensor (Bit 0, auto clear) */
- reg_w(gspca_dev, 0x11, 0x01);
-}
-
-static void sethvflip(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 data, hflip, vflip;
-
- hflip = sd->hflip->val;
- if (sd->flags & FL_HFLIP)
- hflip = !hflip;
- vflip = sd->vflip->val;
- if (sd->flags & FL_VFLIP)
- vflip = !vflip;
-
- reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
- data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
- reg_w(gspca_dev, 0x21, data);
-
- /* load registers to sensor (Bit 0, auto clear) */
- reg_w(gspca_dev, 0x11, 0x01);
-}
-
-/* this function is called at probe and resume time for pac7302 */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
- return gspca_dev->usb_err;
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
- /* when switching to autogain set defaults to make sure
- we are on a valid point of the autogain gain /
- exposure knee graph, and give this change time to
- take effect before doing autogain. */
- gspca_dev->exposure->val = PAC7302_EXPOSURE_DEFAULT;
- gspca_dev->gain->val = PAC7302_GAIN_DEFAULT;
- sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
- }
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightcont(gspca_dev);
- break;
- case V4L2_CID_SATURATION:
- setcolors(gspca_dev);
- break;
- case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
- setwhitebalance(gspca_dev);
- break;
- case V4L2_CID_RED_BALANCE:
- setredbalance(gspca_dev);
- break;
- case V4L2_CID_BLUE_BALANCE:
- setbluebalance(gspca_dev);
- break;
- case V4L2_CID_AUTOGAIN:
- if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
- setexposure(gspca_dev);
- if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
- setgain(gspca_dev);
- break;
- case V4L2_CID_HFLIP:
- sethvflip(gspca_dev);
- break;
- default:
- return -EINVAL;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-/* this function is called at probe time */
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 11);
-
- sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 32, 1, 16);
- sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 127);
-
- sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, 127);
- sd->white_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_WHITE_BALANCE_TEMPERATURE,
- 0, 255, 1, 4);
- sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_RED_BALANCE, 0, 3, 1, 1);
- sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_RED_BALANCE, 0, 3, 1, 1);
-
- gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 1023, 1,
- PAC7302_EXPOSURE_DEFAULT);
- gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 62, 1,
- PAC7302_GAIN_DEFAULT);
-
- sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
-
- v4l2_ctrl_cluster(2, &sd->brightness);
- v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
- v4l2_ctrl_cluster(2, &sd->hflip);
- return 0;
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- reg_w_var(gspca_dev, start_7302,
- page3_7302, sizeof(page3_7302));
- setbrightcont(gspca_dev);
- setcolors(gspca_dev);
- setwhitebalance(gspca_dev);
- setredbalance(gspca_dev);
- setbluebalance(gspca_dev);
- setexposure(gspca_dev);
- setgain(gspca_dev);
- sethvflip(gspca_dev);
-
- sd->sof_read = 0;
- sd->autogain_ignore_frames = 0;
- atomic_set(&sd->avg_lum, 270 + sd->brightness->val);
-
- /* start stream */
- reg_w(gspca_dev, 0xff, 0x01);
- reg_w(gspca_dev, 0x78, 0x01);
-
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
-
- /* stop stream */
- reg_w(gspca_dev, 0xff, 0x01);
- reg_w(gspca_dev, 0x78, 0x00);
-}
-
-/* called on streamoff with alt 0 and on disconnect for pac7302 */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- if (!gspca_dev->present)
- return;
- reg_w(gspca_dev, 0xff, 0x01);
- reg_w(gspca_dev, 0x78, 0x40);
-}
-
-static void do_autogain(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int avg_lum = atomic_read(&sd->avg_lum);
- int desired_lum;
- const int deadzone = 30;
-
- if (sd->autogain_ignore_frames < 0)
- return;
-
- if (sd->autogain_ignore_frames > 0) {
- sd->autogain_ignore_frames--;
- } else {
- desired_lum = 270 + sd->brightness->val;
-
- if (gspca_expo_autogain(gspca_dev, avg_lum, desired_lum,
- deadzone, PAC7302_GAIN_KNEE,
- PAC7302_EXPOSURE_KNEE))
- sd->autogain_ignore_frames =
- PAC_AUTOGAIN_IGNORE_FRAMES;
- }
-}
-
-/* JPEG header */
-static const u8 jpeg_header[] = {
- 0xff, 0xd8, /* SOI: Start of Image */
-
- 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
- 0x00, 0x11, /* length = 17 bytes (including this length field) */
- 0x08, /* Precision: 8 */
- 0x02, 0x80, /* height = 640 (image rotated) */
- 0x01, 0xe0, /* width = 480 */
- 0x03, /* Number of image components: 3 */
- 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
- 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
- 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
-
- 0xff, 0xda, /* SOS: Start Of Scan */
- 0x00, 0x0c, /* length = 12 bytes (including this length field) */
- 0x03, /* number of components: 3 */
- 0x01, 0x00, /* selector 1, table 0x00 */
- 0x02, 0x11, /* selector 2, table 0x11 */
- 0x03, 0x11, /* selector 3, table 0x11 */
- 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
- 0x00 /* Successive approximation: 0 */
-};
-
-/* this function is run at interrupt level */
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 *image;
- u8 *sof;
-
- sof = pac_find_sof(&sd->sof_read, data, len);
- if (sof) {
- int n, lum_offset, footer_length;
-
- /*
- * 6 bytes after the FF D9 EOF marker a number of lumination
- * bytes are send corresponding to different parts of the
- * image, the 14th and 15th byte after the EOF seem to
- * correspond to the center of the image.
- */
- lum_offset = 61 + sizeof pac_sof_marker;
- footer_length = 74;
-
- /* Finish decoding current frame */
- n = (sof - data) - (footer_length + sizeof pac_sof_marker);
- if (n < 0) {
- gspca_dev->image_len += n;
- n = 0;
- } else {
- gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
- }
-
- image = gspca_dev->image;
- if (image != NULL
- && image[gspca_dev->image_len - 2] == 0xff
- && image[gspca_dev->image_len - 1] == 0xd9)
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
-
- n = sof - data;
- len -= n;
- data = sof;
-
- /* Get average lumination */
- if (gspca_dev->last_packet_type == LAST_PACKET &&
- n >= lum_offset)
- atomic_set(&sd->avg_lum, data[-lum_offset] +
- data[-lum_offset + 1]);
-
- /* Start the new frame with the jpeg header */
- /* The PAC7302 has the image rotated 90 degrees */
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- jpeg_header, sizeof jpeg_header);
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
- struct v4l2_dbg_register *reg)
-{
- u8 index;
- u8 value;
-
- /*
- * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
- * long on the USB bus)
- */
- if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
- reg->match.addr == 0 &&
- (reg->reg < 0x000000ff) &&
- (reg->val <= 0x000000ff)
- ) {
- /* Currently writing to page 0 is only supported. */
- /* reg_w() only supports 8bit index */
- index = reg->reg;
- value = reg->val;
-
- /*
- * Note that there shall be no access to other page
- * by any other function between the page switch and
- * the actual register write.
- */
- reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
- reg_w(gspca_dev, index, value);
-
- reg_w(gspca_dev, 0xdc, 0x01);
- }
- return gspca_dev->usb_err;
-}
-
-static int sd_chip_ident(struct gspca_dev *gspca_dev,
- struct v4l2_dbg_chip_ident *chip)
-{
- int ret = -EINVAL;
-
- if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
- chip->match.addr == 0) {
- chip->revision = 0;
- chip->ident = V4L2_IDENT_UNKNOWN;
- ret = 0;
- }
- return ret;
-}
-#endif
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
-static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* interrupt packet data */
- int len) /* interrput packet length */
-{
- int ret = -EINVAL;
- u8 data0, data1;
-
- if (len == 2) {
- data0 = data[0];
- data1 = data[1];
- if ((data0 == 0x00 && data1 == 0x11) ||
- (data0 == 0x22 && data1 == 0x33) ||
- (data0 == 0x44 && data1 == 0x55) ||
- (data0 == 0x66 && data1 == 0x77) ||
- (data0 == 0x88 && data1 == 0x99) ||
- (data0 == 0xaa && data1 == 0xbb) ||
- (data0 == 0xcc && data1 == 0xdd) ||
- (data0 == 0xee && data1 == 0xff)) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
- input_sync(gspca_dev->input_dev);
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
- input_sync(gspca_dev->input_dev);
- ret = 0;
- }
- }
-
- return ret;
-}
-#endif
-
-/* sub-driver description for pac7302 */
-static const struct sd_desc sd_desc = {
- .name = KBUILD_MODNAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
- .dq_callback = do_autogain,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .set_register = sd_dbg_s_register,
- .get_chip_ident = sd_chip_ident,
-#endif
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .int_pkt_scan = sd_int_pkt_scan,
-#endif
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x06f8, 0x3009)},
- {USB_DEVICE(0x06f8, 0x301b)},
- {USB_DEVICE(0x093a, 0x2620)},
- {USB_DEVICE(0x093a, 0x2621)},
- {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
- {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
- {USB_DEVICE(0x093a, 0x2625)},
- {USB_DEVICE(0x093a, 0x2626)},
- {USB_DEVICE(0x093a, 0x2627), .driver_info = FL_VFLIP},
- {USB_DEVICE(0x093a, 0x2628)},
- {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
- {USB_DEVICE(0x093a, 0x262a)},
- {USB_DEVICE(0x093a, 0x262c)},
- {USB_DEVICE(0x145f, 0x013c)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = KBUILD_MODNAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
deleted file mode 100644
index ba3558d3f01..00000000000
--- a/drivers/media/video/gspca/pac7311.c
+++ /dev/null
@@ -1,701 +0,0 @@
-/*
- * Pixart PAC7311 library
- * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
- *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* Some documentation about various registers as determined by trial and error.
- *
- * Register page 1:
- *
- * Address Description
- * 0x08 Unknown compressor related, must always be 8 except when not
- * in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
- * 0x1b Auto white balance related, bit 0 is AWB enable (inverted)
- * bits 345 seem to toggle per color gains on/off (inverted)
- * 0x78 Global control, bit 6 controls the LED (inverted)
- * 0x80 Compression balance, interesting settings:
- * 0x01 Use this to allow the camera to switch to higher compr.
- * on the fly. Needed to stay within bandwidth @ 640x480@30
- * 0x1c From usb captures under Windows for 640x480
- * 0x2a Values >= this switch the camera to a lower compression,
- * using the same table for both luminance and chrominance.
- * This gives a sharper picture. Usable only at 640x480@ <
- * 15 fps or 320x240 / 160x120. Note currently the driver
- * does not use this as the quality gain is small and the
- * generated JPG-s are only understood by v4l-utils >= 0.8.9
- * 0x3f From usb captures under Windows for 320x240
- * 0x69 From usb captures under Windows for 160x120
- *
- * Register page 4:
- *
- * Address Description
- * 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
- * the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
- * 0x0f Master gain 1-245, low value = high gain
- * 0x10 Another gain 0-15, limited influence (1-2x gain I guess)
- * 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
- * Note setting vflip disabled leads to a much lower image quality,
- * so we always vflip, and tell userspace to flip it back
- * 0x27 Seems to toggle various gains on / off, Setting bit 7 seems to
- * completely disable the analog amplification block. Set to 0x68
- * for max gain, 0x14 for minimal gain.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "pac7311"
-
-#include <linux/input.h>
-#include "gspca.h"
-/* Include pac common sof detection functions */
-#include "pac_common.h"
-
-#define PAC7311_GAIN_DEFAULT 122
-#define PAC7311_EXPOSURE_DEFAULT 3 /* 20 fps, avoid using high compr. */
-
-MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
-MODULE_DESCRIPTION("Pixart PAC7311");
-MODULE_LICENSE("GPL");
-
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- struct v4l2_ctrl *contrast;
- struct v4l2_ctrl *hflip;
-
- u8 sof_read;
- u8 autogain_ignore_frames;
-
- atomic_t avg_lum;
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2},
- {320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-
-#define LOAD_PAGE4 254
-#define END_OF_SEQUENCE 0
-
-static const __u8 init_7311[] = {
- 0xff, 0x01,
- 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */
- 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */
- 0x78, 0x44, /* Bit_0=start stream, Bit_6=LED */
- 0xff, 0x04,
- 0x27, 0x80,
- 0x28, 0xca,
- 0x29, 0x53,
- 0x2a, 0x0e,
- 0xff, 0x01,
- 0x3e, 0x20,
-};
-
-static const __u8 start_7311[] = {
-/* index, len, [value]* */
- 0xff, 1, 0x01, /* page 1 */
- 0x02, 43, 0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
- 0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
- 0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0x3e, 42, 0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
- 0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
- 0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
- 0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
- 0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
- 0xd0, 0xff,
- 0x78, 6, 0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
- 0x7f, 18, 0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
- 0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
- 0x18, 0x20,
- 0x96, 3, 0x01, 0x08, 0x04,
- 0xa0, 4, 0x44, 0x44, 0x44, 0x04,
- 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
- 0x3f, 0x00, 0x0a, 0x01, 0x00,
- 0xff, 1, 0x04, /* page 4 */
- 0, LOAD_PAGE4, /* load the page 4 */
- 0x11, 1, 0x01,
- 0, END_OF_SEQUENCE /* end of sequence */
-};
-
-#define SKIP 0xaa
-/* page 4 - the value SKIP says skip the index - see reg_w_page() */
-static const __u8 page4_7311[] = {
- SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
- 0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62,
- 0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP,
- SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68,
- 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
- 0x23, 0x28, 0x04, 0x11, 0x00, 0x00
-};
-
-static void reg_w_buf(struct gspca_dev *gspca_dev,
- __u8 index,
- const u8 *buffer, int len)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- memcpy(gspca_dev->usb_buf, buffer, len);
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, /* value */
- index, gspca_dev->usb_buf, len,
- 500);
- if (ret < 0) {
- pr_err("reg_w_buf() failed index 0x%02x, error %d\n",
- index, ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-
-static void reg_w(struct gspca_dev *gspca_dev,
- __u8 index,
- __u8 value)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- gspca_dev->usb_buf[0] = value;
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, index, gspca_dev->usb_buf, 1,
- 500);
- if (ret < 0) {
- pr_err("reg_w() failed index 0x%02x, value 0x%02x, error %d\n",
- index, value, ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void reg_w_seq(struct gspca_dev *gspca_dev,
- const __u8 *seq, int len)
-{
- while (--len >= 0) {
- reg_w(gspca_dev, seq[0], seq[1]);
- seq += 2;
- }
-}
-
-/* load the beginning of a page */
-static void reg_w_page(struct gspca_dev *gspca_dev,
- const __u8 *page, int len)
-{
- int index;
- int ret = 0;
-
- if (gspca_dev->usb_err < 0)
- return;
- for (index = 0; index < len; index++) {
- if (page[index] == SKIP) /* skip this index */
- continue;
- gspca_dev->usb_buf[0] = page[index];
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, index, gspca_dev->usb_buf, 1,
- 500);
- if (ret < 0) {
- pr_err("reg_w_page() failed index 0x%02x, value 0x%02x, error %d\n",
- index, page[index], ret);
- gspca_dev->usb_err = ret;
- break;
- }
- }
-}
-
-/* output a variable sequence */
-static void reg_w_var(struct gspca_dev *gspca_dev,
- const __u8 *seq,
- const __u8 *page4, unsigned int page4_len)
-{
- int index, len;
-
- for (;;) {
- index = *seq++;
- len = *seq++;
- switch (len) {
- case END_OF_SEQUENCE:
- return;
- case LOAD_PAGE4:
- reg_w_page(gspca_dev, page4, page4_len);
- break;
- default:
- if (len > USB_BUF_SZ) {
- PDEBUG(D_ERR|D_STREAM,
- "Incorrect variable sequence");
- return;
- }
- while (len > 0) {
- if (len < 8) {
- reg_w_buf(gspca_dev,
- index, seq, len);
- seq += len;
- break;
- }
- reg_w_buf(gspca_dev, index, seq, 8);
- seq += 8;
- index += 8;
- len -= 8;
- }
- }
- }
- /* not reached */
-}
-
-/* this function is called at probe time for pac7311 */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct cam *cam = &gspca_dev->cam;
-
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- cam->input_flags = V4L2_IN_ST_VFLIP;
-
- return 0;
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_w(gspca_dev, 0xff, 0x04);
- reg_w(gspca_dev, 0x10, val);
- /* load registers to sensor (Bit 0, auto clear) */
- reg_w(gspca_dev, 0x11, 0x01);
-}
-
-static void setgain(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
- reg_w(gspca_dev, 0x0e, 0x00);
- reg_w(gspca_dev, 0x0f, gspca_dev->gain->maximum - val + 1);
-
- /* load registers to sensor (Bit 0, auto clear) */
- reg_w(gspca_dev, 0x11, 0x01);
-}
-
-static void setexposure(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
- reg_w(gspca_dev, 0x02, val);
-
- /* load registers to sensor (Bit 0, auto clear) */
- reg_w(gspca_dev, 0x11, 0x01);
-
- /*
- * Page 1 register 8 must always be 0x08 except when not in
- * 640x480 mode and page 4 reg 2 <= 3 then it must be 9
- */
- reg_w(gspca_dev, 0xff, 0x01);
- if (gspca_dev->width != 640 && val <= 3)
- reg_w(gspca_dev, 0x08, 0x09);
- else
- reg_w(gspca_dev, 0x08, 0x08);
-
- /*
- * Page1 register 80 sets the compression balance, normally we
- * want / use 0x1c, but for 640x480@30fps we must allow the
- * camera to use higher compression or we may run out of
- * bandwidth.
- */
- if (gspca_dev->width == 640 && val == 2)
- reg_w(gspca_dev, 0x80, 0x01);
- else
- reg_w(gspca_dev, 0x80, 0x1c);
-
- /* load registers to sensor (Bit 0, auto clear) */
- reg_w(gspca_dev, 0x11, 0x01);
-}
-
-static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
-{
- __u8 data;
-
- reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
- data = (hflip ? 0x04 : 0x00) |
- (vflip ? 0x08 : 0x00);
- reg_w(gspca_dev, 0x21, data);
-
- /* load registers to sensor (Bit 0, auto clear) */
- reg_w(gspca_dev, 0x11, 0x01);
-}
-
-/* this function is called at probe and resume time for pac7311 */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
- return gspca_dev->usb_err;
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
- /* when switching to autogain set defaults to make sure
- we are on a valid point of the autogain gain /
- exposure knee graph, and give this change time to
- take effect before doing autogain. */
- gspca_dev->exposure->val = PAC7311_EXPOSURE_DEFAULT;
- gspca_dev->gain->val = PAC7311_GAIN_DEFAULT;
- sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
- }
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_AUTOGAIN:
- if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
- setexposure(gspca_dev, gspca_dev->exposure->val);
- if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
- setgain(gspca_dev, gspca_dev->gain->val);
- break;
- case V4L2_CID_HFLIP:
- sethvflip(gspca_dev, sd->hflip->val, 1);
- break;
- default:
- return -EINVAL;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-/* this function is called at probe time */
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 5);
-
- sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 15, 1, 7);
- gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 2, 63, 1,
- PAC7311_EXPOSURE_DEFAULT);
- gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 244, 1,
- PAC7311_GAIN_DEFAULT);
- sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
-
- v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
- return 0;
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->sof_read = 0;
-
- reg_w_var(gspca_dev, start_7311,
- page4_7311, sizeof(page4_7311));
- setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->contrast));
- setgain(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->gain));
- setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure));
- sethvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), 1);
-
- /* set correct resolution */
- switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
- case 2: /* 160x120 */
- reg_w(gspca_dev, 0xff, 0x01);
- reg_w(gspca_dev, 0x17, 0x20);
- reg_w(gspca_dev, 0x87, 0x10);
- break;
- case 1: /* 320x240 */
- reg_w(gspca_dev, 0xff, 0x01);
- reg_w(gspca_dev, 0x17, 0x30);
- reg_w(gspca_dev, 0x87, 0x11);
- break;
- case 0: /* 640x480 */
- reg_w(gspca_dev, 0xff, 0x01);
- reg_w(gspca_dev, 0x17, 0x00);
- reg_w(gspca_dev, 0x87, 0x12);
- break;
- }
-
- sd->sof_read = 0;
- sd->autogain_ignore_frames = 0;
- atomic_set(&sd->avg_lum, -1);
-
- /* start stream */
- reg_w(gspca_dev, 0xff, 0x01);
- reg_w(gspca_dev, 0x78, 0x05);
-
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- reg_w(gspca_dev, 0xff, 0x04);
- reg_w(gspca_dev, 0x27, 0x80);
- reg_w(gspca_dev, 0x28, 0xca);
- reg_w(gspca_dev, 0x29, 0x53);
- reg_w(gspca_dev, 0x2a, 0x0e);
- reg_w(gspca_dev, 0xff, 0x01);
- reg_w(gspca_dev, 0x3e, 0x20);
- reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
- reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
- reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
-}
-
-static void do_autogain(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int avg_lum = atomic_read(&sd->avg_lum);
- int desired_lum, deadzone;
-
- if (avg_lum == -1)
- return;
-
- desired_lum = 170;
- deadzone = 20;
-
- if (sd->autogain_ignore_frames > 0)
- sd->autogain_ignore_frames--;
- else if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
- desired_lum, deadzone))
- sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
-}
-
-/* JPEG header, part 1 */
-static const unsigned char pac_jpeg_header1[] = {
- 0xff, 0xd8, /* SOI: Start of Image */
-
- 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
- 0x00, 0x11, /* length = 17 bytes (including this length field) */
- 0x08 /* Precision: 8 */
- /* 2 bytes is placed here: number of image lines */
- /* 2 bytes is placed here: samples per line */
-};
-
-/* JPEG header, continued */
-static const unsigned char pac_jpeg_header2[] = {
- 0x03, /* Number of image components: 3 */
- 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
- 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
- 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
-
- 0xff, 0xda, /* SOS: Start Of Scan */
- 0x00, 0x0c, /* length = 12 bytes (including this length field) */
- 0x03, /* number of components: 3 */
- 0x01, 0x00, /* selector 1, table 0x00 */
- 0x02, 0x11, /* selector 2, table 0x11 */
- 0x03, 0x11, /* selector 3, table 0x11 */
- 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
- 0x00 /* Successive approximation: 0 */
-};
-
-static void pac_start_frame(struct gspca_dev *gspca_dev,
- __u16 lines, __u16 samples_per_line)
-{
- unsigned char tmpbuf[4];
-
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- pac_jpeg_header1, sizeof(pac_jpeg_header1));
-
- tmpbuf[0] = lines >> 8;
- tmpbuf[1] = lines & 0xff;
- tmpbuf[2] = samples_per_line >> 8;
- tmpbuf[3] = samples_per_line & 0xff;
-
- gspca_frame_add(gspca_dev, INTER_PACKET,
- tmpbuf, sizeof(tmpbuf));
- gspca_frame_add(gspca_dev, INTER_PACKET,
- pac_jpeg_header2, sizeof(pac_jpeg_header2));
-}
-
-/* this function is run at interrupt level */
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 *image;
- unsigned char *sof;
-
- sof = pac_find_sof(&sd->sof_read, data, len);
- if (sof) {
- int n, lum_offset, footer_length;
-
- /*
- * 6 bytes after the FF D9 EOF marker a number of lumination
- * bytes are send corresponding to different parts of the
- * image, the 14th and 15th byte after the EOF seem to
- * correspond to the center of the image.
- */
- lum_offset = 24 + sizeof pac_sof_marker;
- footer_length = 26;
-
- /* Finish decoding current frame */
- n = (sof - data) - (footer_length + sizeof pac_sof_marker);
- if (n < 0) {
- gspca_dev->image_len += n;
- n = 0;
- } else {
- gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
- }
- image = gspca_dev->image;
- if (image != NULL
- && image[gspca_dev->image_len - 2] == 0xff
- && image[gspca_dev->image_len - 1] == 0xd9)
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
-
- n = sof - data;
- len -= n;
- data = sof;
-
- /* Get average lumination */
- if (gspca_dev->last_packet_type == LAST_PACKET &&
- n >= lum_offset)
- atomic_set(&sd->avg_lum, data[-lum_offset] +
- data[-lum_offset + 1]);
- else
- atomic_set(&sd->avg_lum, -1);
-
- /* Start the new frame with the jpeg header */
- pac_start_frame(gspca_dev,
- gspca_dev->height, gspca_dev->width);
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
-static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* interrupt packet data */
- int len) /* interrupt packet length */
-{
- int ret = -EINVAL;
- u8 data0, data1;
-
- if (len == 2) {
- data0 = data[0];
- data1 = data[1];
- if ((data0 == 0x00 && data1 == 0x11) ||
- (data0 == 0x22 && data1 == 0x33) ||
- (data0 == 0x44 && data1 == 0x55) ||
- (data0 == 0x66 && data1 == 0x77) ||
- (data0 == 0x88 && data1 == 0x99) ||
- (data0 == 0xaa && data1 == 0xbb) ||
- (data0 == 0xcc && data1 == 0xdd) ||
- (data0 == 0xee && data1 == 0xff)) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
- input_sync(gspca_dev->input_dev);
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
- input_sync(gspca_dev->input_dev);
- ret = 0;
- }
- }
-
- return ret;
-}
-#endif
-
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
- .dq_callback = do_autogain,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .int_pkt_scan = sd_int_pkt_scan,
-#endif
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x093a, 0x2600)},
- {USB_DEVICE(0x093a, 0x2601)},
- {USB_DEVICE(0x093a, 0x2603)},
- {USB_DEVICE(0x093a, 0x2608)},
- {USB_DEVICE(0x093a, 0x260e)},
- {USB_DEVICE(0x093a, 0x260f)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/pac_common.h b/drivers/media/video/gspca/pac_common.h
deleted file mode 100644
index 8462a7c1a33..00000000000
--- a/drivers/media/video/gspca/pac_common.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Pixart PAC207BCA / PAC73xx common functions
- *
- * Copyright (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl>
- * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
- * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr
- *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/* We calculate the autogain at the end of the transfer of a frame, at this
- moment a frame with the old settings is being captured and transmitted. So
- if we adjust the gain or exposure we must ignore atleast the next frame for
- the new settings to come into effect before doing any other adjustments. */
-#define PAC_AUTOGAIN_IGNORE_FRAMES 2
-
-static const unsigned char pac_sof_marker[5] =
- { 0xff, 0xff, 0x00, 0xff, 0x96 };
-
-/*
- The following state machine finds the SOF marker sequence
- 0xff, 0xff, 0x00, 0xff, 0x96 in a byte stream.
-
- +----------+
- | 0: START |<---------------\
- +----------+<-\ |
- | \---/otherwise |
- v 0xff |
- +----------+ otherwise |
- | 1 |--------------->*
- | | ^
- +----------+ |
- | |
- v 0xff |
- +----------+<-\0xff |
- /->| |--/ |
- | | 2 |--------------->*
- | | | otherwise ^
- | +----------+ |
- | | |
- | v 0x00 |
- | +----------+ |
- | | 3 | |
- | | |--------------->*
- | +----------+ otherwise ^
- | | |
- 0xff | v 0xff |
- | +----------+ |
- \--| 4 | |
- | |----------------/
- +----------+ otherwise
- |
- v 0x96
- +----------+
- | FOUND |
- +----------+
-*/
-
-static unsigned char *pac_find_sof(u8 *sof_read,
- unsigned char *m, int len)
-{
- int i;
-
- /* Search for the SOF marker (fixed part) in the header */
- for (i = 0; i < len; i++) {
- switch (*sof_read) {
- case 0:
- if (m[i] == 0xff)
- *sof_read = 1;
- break;
- case 1:
- if (m[i] == 0xff)
- *sof_read = 2;
- else
- *sof_read = 0;
- break;
- case 2:
- switch (m[i]) {
- case 0x00:
- *sof_read = 3;
- break;
- case 0xff:
- /* stay in this state */
- break;
- default:
- *sof_read = 0;
- }
- break;
- case 3:
- if (m[i] == 0xff)
- *sof_read = 4;
- else
- *sof_read = 0;
- break;
- case 4:
- switch (m[i]) {
- case 0x96:
- /* Pattern found */
- PDEBUG(D_FRAM,
- "SOF found, bytes to analyze: %u."
- " Frame starts at byte #%u",
- len, i + 1);
- *sof_read = 0;
- return m + i + 1;
- break;
- case 0xff:
- *sof_read = 2;
- break;
- default:
- *sof_read = 0;
- }
- break;
- default:
- *sof_read = 0;
- }
- }
-
- return NULL;
-}
diff --git a/drivers/media/video/gspca/se401.c b/drivers/media/video/gspca/se401.c
deleted file mode 100644
index a33cb78a839..00000000000
--- a/drivers/media/video/gspca/se401.c
+++ /dev/null
@@ -1,739 +0,0 @@
-/*
- * GSPCA Endpoints (formerly known as AOX) se401 USB Camera sub Driver
- *
- * Copyright (C) 2011 Hans de Goede <hdegoede@redhat.com>
- *
- * Based on the v4l1 se401 driver which is:
- *
- * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "se401"
-
-#define BULK_SIZE 4096
-#define PACKET_SIZE 1024
-#define READ_REQ_SIZE 64
-#define MAX_MODES ((READ_REQ_SIZE - 6) / 4)
-/* The se401 compression algorithm uses a fixed quant factor, which
- can be configured by setting the high nibble of the SE401_OPERATINGMODE
- feature. This needs to exactly match what is in libv4l! */
-#define SE401_QUANT_FACT 8
-
-#include <linux/input.h>
-#include <linux/slab.h>
-#include "gspca.h"
-#include "se401.h"
-
-MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
-MODULE_DESCRIPTION("Endpoints se401");
-MODULE_LICENSE("GPL");
-
-/* exposure change state machine states */
-enum {
- EXPO_CHANGED,
- EXPO_DROP_FRAME,
- EXPO_NO_CHANGE,
-};
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- struct { /* exposure/freq control cluster */
- struct v4l2_ctrl *exposure;
- struct v4l2_ctrl *freq;
- };
- bool has_brightness;
- struct v4l2_pix_format fmts[MAX_MODES];
- int pixels_read;
- int packet_read;
- u8 packet[PACKET_SIZE];
- u8 restart_stream;
- u8 button_state;
- u8 resetlevel;
- u8 resetlevel_frame_count;
- int resetlevel_adjust_dir;
- int expo_change_state;
-};
-
-
-static void se401_write_req(struct gspca_dev *gspca_dev, u16 req, u16 value,
- int silent)
-{
- int err;
-
- if (gspca_dev->usb_err < 0)
- return;
-
- err = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0), req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, 0, NULL, 0, 1000);
- if (err < 0) {
- if (!silent)
- pr_err("write req failed req %#04x val %#04x error %d\n",
- req, value, err);
- gspca_dev->usb_err = err;
- }
-}
-
-static void se401_read_req(struct gspca_dev *gspca_dev, u16 req, int silent)
-{
- int err;
-
- if (gspca_dev->usb_err < 0)
- return;
-
- if (USB_BUF_SZ < READ_REQ_SIZE) {
- pr_err("USB_BUF_SZ too small!!\n");
- gspca_dev->usb_err = -ENOBUFS;
- return;
- }
-
- err = usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0), req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, 0, gspca_dev->usb_buf, READ_REQ_SIZE, 1000);
- if (err < 0) {
- if (!silent)
- pr_err("read req failed req %#04x error %d\n",
- req, err);
- gspca_dev->usb_err = err;
- }
-}
-
-static void se401_set_feature(struct gspca_dev *gspca_dev,
- u16 selector, u16 param)
-{
- int err;
-
- if (gspca_dev->usb_err < 0)
- return;
-
- err = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- SE401_REQ_SET_EXT_FEATURE,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- param, selector, NULL, 0, 1000);
- if (err < 0) {
- pr_err("set feature failed sel %#04x param %#04x error %d\n",
- selector, param, err);
- gspca_dev->usb_err = err;
- }
-}
-
-static int se401_get_feature(struct gspca_dev *gspca_dev, u16 selector)
-{
- int err;
-
- if (gspca_dev->usb_err < 0)
- return gspca_dev->usb_err;
-
- if (USB_BUF_SZ < 2) {
- pr_err("USB_BUF_SZ too small!!\n");
- gspca_dev->usb_err = -ENOBUFS;
- return gspca_dev->usb_err;
- }
-
- err = usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- SE401_REQ_GET_EXT_FEATURE,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, selector, gspca_dev->usb_buf, 2, 1000);
- if (err < 0) {
- pr_err("get feature failed sel %#04x error %d\n",
- selector, err);
- gspca_dev->usb_err = err;
- return err;
- }
- return gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
-{
- /* HDG: this does not seem to do anything on my cam */
- se401_write_req(gspca_dev, SE401_REQ_SET_BRT, val, 0);
-}
-
-static void setgain(struct gspca_dev *gspca_dev, s32 val)
-{
- u16 gain = 63 - val;
-
- /* red color gain */
- se401_set_feature(gspca_dev, HV7131_REG_ARCG, gain);
- /* green color gain */
- se401_set_feature(gspca_dev, HV7131_REG_AGCG, gain);
- /* blue color gain */
- se401_set_feature(gspca_dev, HV7131_REG_ABCG, gain);
-}
-
-static void setexposure(struct gspca_dev *gspca_dev, s32 val, s32 freq)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int integration = val << 6;
- u8 expose_h, expose_m, expose_l;
-
- /* Do this before the set_feature calls, for proper timing wrt
- the interrupt driven pkt_scan. Note we may still race but that
- is not a big issue, the expo change state machine is merely for
- avoiding underexposed frames getting send out, if one sneaks
- through so be it */
- sd->expo_change_state = EXPO_CHANGED;
-
- if (freq == V4L2_CID_POWER_LINE_FREQUENCY_50HZ)
- integration = integration - integration % 106667;
- if (freq == V4L2_CID_POWER_LINE_FREQUENCY_60HZ)
- integration = integration - integration % 88889;
-
- expose_h = (integration >> 16);
- expose_m = (integration >> 8);
- expose_l = integration;
-
- /* integration time low */
- se401_set_feature(gspca_dev, HV7131_REG_TITL, expose_l);
- /* integration time mid */
- se401_set_feature(gspca_dev, HV7131_REG_TITM, expose_m);
- /* integration time high */
- se401_set_feature(gspca_dev, HV7131_REG_TITU, expose_h);
-}
-
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct cam *cam = &gspca_dev->cam;
- u8 *cd = gspca_dev->usb_buf;
- int i, j, n;
- int widths[MAX_MODES], heights[MAX_MODES];
-
- /* Read the camera descriptor */
- se401_read_req(gspca_dev, SE401_REQ_GET_CAMERA_DESCRIPTOR, 1);
- if (gspca_dev->usb_err) {
- /* Sometimes after being idle for a while the se401 won't
- respond and needs a good kicking */
- usb_reset_device(gspca_dev->dev);
- gspca_dev->usb_err = 0;
- se401_read_req(gspca_dev, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0);
- }
-
- /* Some cameras start with their LED on */
- se401_write_req(gspca_dev, SE401_REQ_LED_CONTROL, 0, 0);
- if (gspca_dev->usb_err)
- return gspca_dev->usb_err;
-
- if (cd[1] != 0x41) {
- pr_err("Wrong descriptor type\n");
- return -ENODEV;
- }
-
- if (!(cd[2] & SE401_FORMAT_BAYER)) {
- pr_err("Bayer format not supported!\n");
- return -ENODEV;
- }
-
- if (cd[3])
- pr_info("ExtraFeatures: %d\n", cd[3]);
-
- n = cd[4] | (cd[5] << 8);
- if (n > MAX_MODES) {
- pr_err("Too many frame sizes\n");
- return -ENODEV;
- }
-
- for (i = 0; i < n ; i++) {
- widths[i] = cd[6 + i * 4 + 0] | (cd[6 + i * 4 + 1] << 8);
- heights[i] = cd[6 + i * 4 + 2] | (cd[6 + i * 4 + 3] << 8);
- }
-
- for (i = 0; i < n ; i++) {
- sd->fmts[i].width = widths[i];
- sd->fmts[i].height = heights[i];
- sd->fmts[i].field = V4L2_FIELD_NONE;
- sd->fmts[i].colorspace = V4L2_COLORSPACE_SRGB;
- sd->fmts[i].priv = 1;
-
- /* janggu compression only works for 1/4th or 1/16th res */
- for (j = 0; j < n; j++) {
- if (widths[j] / 2 == widths[i] &&
- heights[j] / 2 == heights[i]) {
- sd->fmts[i].priv = 2;
- break;
- }
- }
- /* 1/16th if available too is better then 1/4th, because
- we then use a larger area of the sensor */
- for (j = 0; j < n; j++) {
- if (widths[j] / 4 == widths[i] &&
- heights[j] / 4 == heights[i]) {
- sd->fmts[i].priv = 4;
- break;
- }
- }
-
- if (sd->fmts[i].priv == 1) {
- /* Not a 1/4th or 1/16th res, use bayer */
- sd->fmts[i].pixelformat = V4L2_PIX_FMT_SBGGR8;
- sd->fmts[i].bytesperline = widths[i];
- sd->fmts[i].sizeimage = widths[i] * heights[i];
- pr_info("Frame size: %dx%d bayer\n",
- widths[i], heights[i]);
- } else {
- /* Found a match use janggu compression */
- sd->fmts[i].pixelformat = V4L2_PIX_FMT_SE401;
- sd->fmts[i].bytesperline = 0;
- sd->fmts[i].sizeimage = widths[i] * heights[i] * 3;
- pr_info("Frame size: %dx%d 1/%dth janggu\n",
- widths[i], heights[i],
- sd->fmts[i].priv * sd->fmts[i].priv);
- }
- }
-
- cam->cam_mode = sd->fmts;
- cam->nmodes = n;
- cam->bulk = 1;
- cam->bulk_size = BULK_SIZE;
- cam->bulk_nurbs = 4;
- sd->resetlevel = 0x2d; /* Set initial resetlevel */
-
- /* See if the camera supports brightness */
- se401_read_req(gspca_dev, SE401_REQ_GET_BRT, 1);
- sd->has_brightness = !!gspca_dev->usb_err;
- gspca_dev->usb_err = 0;
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- return 0;
-}
-
-/* function called at start time before URB creation */
-static int sd_isoc_init(struct gspca_dev *gspca_dev)
-{
- gspca_dev->alt = 1; /* Ignore the bogus isoc alt settings */
-
- return gspca_dev->usb_err;
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- int mult = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
- int mode = 0;
-
- se401_write_req(gspca_dev, SE401_REQ_CAMERA_POWER, 1, 1);
- if (gspca_dev->usb_err) {
- /* Sometimes after being idle for a while the se401 won't
- respond and needs a good kicking */
- usb_reset_device(gspca_dev->dev);
- gspca_dev->usb_err = 0;
- se401_write_req(gspca_dev, SE401_REQ_CAMERA_POWER, 1, 0);
- }
- se401_write_req(gspca_dev, SE401_REQ_LED_CONTROL, 1, 0);
-
- se401_set_feature(gspca_dev, HV7131_REG_MODE_B, 0x05);
-
- /* set size + mode */
- se401_write_req(gspca_dev, SE401_REQ_SET_WIDTH,
- gspca_dev->width * mult, 0);
- se401_write_req(gspca_dev, SE401_REQ_SET_HEIGHT,
- gspca_dev->height * mult, 0);
- /*
- * HDG: disabled this as it does not seem to do anything
- * se401_write_req(gspca_dev, SE401_REQ_SET_OUTPUT_MODE,
- * SE401_FORMAT_BAYER, 0);
- */
-
- switch (mult) {
- case 1: /* Raw bayer */
- mode = 0x03; break;
- case 2: /* 1/4th janggu */
- mode = SE401_QUANT_FACT << 4; break;
- case 4: /* 1/16th janggu */
- mode = (SE401_QUANT_FACT << 4) | 0x02; break;
- }
- se401_set_feature(gspca_dev, SE401_OPERATINGMODE, mode);
-
- se401_set_feature(gspca_dev, HV7131_REG_ARLV, sd->resetlevel);
-
- sd->packet_read = 0;
- sd->pixels_read = 0;
- sd->restart_stream = 0;
- sd->resetlevel_frame_count = 0;
- sd->resetlevel_adjust_dir = 0;
- sd->expo_change_state = EXPO_NO_CHANGE;
-
- se401_write_req(gspca_dev, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, 0);
-
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- se401_write_req(gspca_dev, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, 0);
- se401_write_req(gspca_dev, SE401_REQ_LED_CONTROL, 0, 0);
- se401_write_req(gspca_dev, SE401_REQ_CAMERA_POWER, 0, 0);
-}
-
-static void sd_dq_callback(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- unsigned int ahrc, alrc;
- int oldreset, adjust_dir;
-
- /* Restart the stream if requested do so by pkt_scan */
- if (sd->restart_stream) {
- sd_stopN(gspca_dev);
- sd_start(gspca_dev);
- sd->restart_stream = 0;
- }
-
- /* Automatically adjust sensor reset level
- Hyundai have some really nice docs about this and other sensor
- related stuff on their homepage: www.hei.co.kr */
- sd->resetlevel_frame_count++;
- if (sd->resetlevel_frame_count < 20)
- return;
-
- /* For some reason this normally read-only register doesn't get reset
- to zero after reading them just once... */
- se401_get_feature(gspca_dev, HV7131_REG_HIREFNOH);
- se401_get_feature(gspca_dev, HV7131_REG_HIREFNOL);
- se401_get_feature(gspca_dev, HV7131_REG_LOREFNOH);
- se401_get_feature(gspca_dev, HV7131_REG_LOREFNOL);
- ahrc = 256*se401_get_feature(gspca_dev, HV7131_REG_HIREFNOH) +
- se401_get_feature(gspca_dev, HV7131_REG_HIREFNOL);
- alrc = 256*se401_get_feature(gspca_dev, HV7131_REG_LOREFNOH) +
- se401_get_feature(gspca_dev, HV7131_REG_LOREFNOL);
-
- /* Not an exact science, but it seems to work pretty well... */
- oldreset = sd->resetlevel;
- if (alrc > 10) {
- while (alrc >= 10 && sd->resetlevel < 63) {
- sd->resetlevel++;
- alrc /= 2;
- }
- } else if (ahrc > 20) {
- while (ahrc >= 20 && sd->resetlevel > 0) {
- sd->resetlevel--;
- ahrc /= 2;
- }
- }
- /* Detect ping-pong-ing and halve adjustment to avoid overshoot */
- if (sd->resetlevel > oldreset)
- adjust_dir = 1;
- else
- adjust_dir = -1;
- if (sd->resetlevel_adjust_dir &&
- sd->resetlevel_adjust_dir != adjust_dir)
- sd->resetlevel = oldreset + (sd->resetlevel - oldreset) / 2;
-
- if (sd->resetlevel != oldreset) {
- sd->resetlevel_adjust_dir = adjust_dir;
- se401_set_feature(gspca_dev, HV7131_REG_ARLV, sd->resetlevel);
- }
-
- sd->resetlevel_frame_count = 0;
-}
-
-static void sd_complete_frame(struct gspca_dev *gspca_dev, u8 *data, int len)
-{
- struct sd *sd = (struct sd *)gspca_dev;
-
- switch (sd->expo_change_state) {
- case EXPO_CHANGED:
- /* The exposure was changed while this frame
- was being send, so this frame is ok */
- sd->expo_change_state = EXPO_DROP_FRAME;
- break;
- case EXPO_DROP_FRAME:
- /* The exposure was changed while this frame
- was being captured, drop it! */
- gspca_dev->last_packet_type = DISCARD_PACKET;
- sd->expo_change_state = EXPO_NO_CHANGE;
- break;
- case EXPO_NO_CHANGE:
- break;
- }
- gspca_frame_add(gspca_dev, LAST_PACKET, data, len);
-}
-
-static void sd_pkt_scan_janggu(struct gspca_dev *gspca_dev, u8 *data, int len)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- int imagesize = gspca_dev->width * gspca_dev->height;
- int i, plen, bits, pixels, info, count;
-
- if (sd->restart_stream)
- return;
-
- /* Sometimes a 1024 bytes garbage bulk packet is send between frames */
- if (gspca_dev->last_packet_type == LAST_PACKET && len == 1024) {
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
-
- i = 0;
- while (i < len) {
- /* Read header if not already be present from prev bulk pkt */
- if (sd->packet_read < 4) {
- count = 4 - sd->packet_read;
- if (count > len - i)
- count = len - i;
- memcpy(&sd->packet[sd->packet_read], &data[i], count);
- sd->packet_read += count;
- i += count;
- if (sd->packet_read < 4)
- break;
- }
- bits = sd->packet[3] + (sd->packet[2] << 8);
- pixels = sd->packet[1] + ((sd->packet[0] & 0x3f) << 8);
- info = (sd->packet[0] & 0xc0) >> 6;
- plen = ((bits + 47) >> 4) << 1;
- /* Sanity checks */
- if (plen > 1024) {
- pr_err("invalid packet len %d restarting stream\n",
- plen);
- goto error;
- }
- if (info == 3) {
- pr_err("unknown frame info value restarting stream\n");
- goto error;
- }
-
- /* Read (remainder of) packet contents */
- count = plen - sd->packet_read;
- if (count > len - i)
- count = len - i;
- memcpy(&sd->packet[sd->packet_read], &data[i], count);
- sd->packet_read += count;
- i += count;
- if (sd->packet_read < plen)
- break;
-
- sd->pixels_read += pixels;
- sd->packet_read = 0;
-
- switch (info) {
- case 0: /* Frame data */
- gspca_frame_add(gspca_dev, INTER_PACKET, sd->packet,
- plen);
- break;
- case 1: /* EOF */
- if (sd->pixels_read != imagesize) {
- pr_err("frame size %d expected %d\n",
- sd->pixels_read, imagesize);
- goto error;
- }
- sd_complete_frame(gspca_dev, sd->packet, plen);
- return; /* Discard the rest of the bulk packet !! */
- case 2: /* SOF */
- gspca_frame_add(gspca_dev, FIRST_PACKET, sd->packet,
- plen);
- sd->pixels_read = pixels;
- break;
- }
- }
- return;
-
-error:
- sd->restart_stream = 1;
- /* Give userspace a 0 bytes frame, so our dq callback gets
- called and it can restart the stream */
- gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
-}
-
-static void sd_pkt_scan_bayer(struct gspca_dev *gspca_dev, u8 *data, int len)
-{
- struct cam *cam = &gspca_dev->cam;
- int imagesize = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
-
- if (gspca_dev->image_len == 0) {
- gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
- return;
- }
-
- if (gspca_dev->image_len + len >= imagesize) {
- sd_complete_frame(gspca_dev, data, len);
- return;
- }
-
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *data, int len)
-{
- int mult = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
-
- if (len == 0)
- return;
-
- if (mult == 1) /* mult == 1 means raw bayer */
- sd_pkt_scan_bayer(gspca_dev, data, len);
- else
- sd_pkt_scan_janggu(gspca_dev, data, len);
-}
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
-static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, u8 *data, int len)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- u8 state;
-
- if (len != 2)
- return -EINVAL;
-
- switch (data[0]) {
- case 0:
- case 1:
- state = data[0];
- break;
- default:
- return -EINVAL;
- }
- if (sd->button_state != state) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
- input_sync(gspca_dev->input_dev);
- sd->button_state = state;
- }
-
- return 0;
-}
-#endif
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_GAIN:
- setgain(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_EXPOSURE:
- setexposure(gspca_dev, ctrl->val, sd->freq->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 4);
- if (sd->has_brightness)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 15);
- /* max is really 63 but > 50 is not pretty */
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 50, 1, 25);
- sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 32767, 1, 15000);
- sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
- V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- v4l2_ctrl_cluster(2, &sd->exposure);
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .isoc_init = sd_isoc_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .dq_callback = sd_dq_callback,
- .pkt_scan = sd_pkt_scan,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .int_pkt_scan = sd_int_pkt_scan,
-#endif
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x03e8, 0x0004)}, /* Endpoints/Aox SE401 */
- {USB_DEVICE(0x0471, 0x030b)}, /* Philips PCVC665K */
- {USB_DEVICE(0x047d, 0x5001)}, /* Kensington 67014 */
- {USB_DEVICE(0x047d, 0x5002)}, /* Kensington 6701(5/7) */
- {USB_DEVICE(0x047d, 0x5003)}, /* Kensington 67016 */
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static int sd_pre_reset(struct usb_interface *intf)
-{
- return 0;
-}
-
-static int sd_post_reset(struct usb_interface *intf)
-{
- return 0;
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
- .pre_reset = sd_pre_reset,
- .post_reset = sd_post_reset,
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/se401.h b/drivers/media/video/gspca/se401.h
deleted file mode 100644
index 96d8ebf3cf5..00000000000
--- a/drivers/media/video/gspca/se401.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * GSPCA Endpoints (formerly known as AOX) se401 USB Camera sub Driver
- *
- * Copyright (C) 2011 Hans de Goede <hdegoede@redhat.com>
- *
- * Based on the v4l1 se401 driver which is:
- *
- * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define SE401_REQ_GET_CAMERA_DESCRIPTOR 0x06
-#define SE401_REQ_START_CONTINUOUS_CAPTURE 0x41
-#define SE401_REQ_STOP_CONTINUOUS_CAPTURE 0x42
-#define SE401_REQ_CAPTURE_FRAME 0x43
-#define SE401_REQ_GET_BRT 0x44
-#define SE401_REQ_SET_BRT 0x45
-#define SE401_REQ_GET_WIDTH 0x4c
-#define SE401_REQ_SET_WIDTH 0x4d
-#define SE401_REQ_GET_HEIGHT 0x4e
-#define SE401_REQ_SET_HEIGHT 0x4f
-#define SE401_REQ_GET_OUTPUT_MODE 0x50
-#define SE401_REQ_SET_OUTPUT_MODE 0x51
-#define SE401_REQ_GET_EXT_FEATURE 0x52
-#define SE401_REQ_SET_EXT_FEATURE 0x53
-#define SE401_REQ_CAMERA_POWER 0x56
-#define SE401_REQ_LED_CONTROL 0x57
-#define SE401_REQ_BIOS 0xff
-
-#define SE401_BIOS_READ 0x07
-
-#define SE401_FORMAT_BAYER 0x40
-
-/* Hyundai hv7131b registers
- 7121 and 7141 should be the same (haven't really checked...) */
-/* Mode registers: */
-#define HV7131_REG_MODE_A 0x00
-#define HV7131_REG_MODE_B 0x01
-#define HV7131_REG_MODE_C 0x02
-/* Frame registers: */
-#define HV7131_REG_FRSU 0x10
-#define HV7131_REG_FRSL 0x11
-#define HV7131_REG_FCSU 0x12
-#define HV7131_REG_FCSL 0x13
-#define HV7131_REG_FWHU 0x14
-#define HV7131_REG_FWHL 0x15
-#define HV7131_REG_FWWU 0x16
-#define HV7131_REG_FWWL 0x17
-/* Timing registers: */
-#define HV7131_REG_THBU 0x20
-#define HV7131_REG_THBL 0x21
-#define HV7131_REG_TVBU 0x22
-#define HV7131_REG_TVBL 0x23
-#define HV7131_REG_TITU 0x25
-#define HV7131_REG_TITM 0x26
-#define HV7131_REG_TITL 0x27
-#define HV7131_REG_TMCD 0x28
-/* Adjust Registers: */
-#define HV7131_REG_ARLV 0x30
-#define HV7131_REG_ARCG 0x31
-#define HV7131_REG_AGCG 0x32
-#define HV7131_REG_ABCG 0x33
-#define HV7131_REG_APBV 0x34
-#define HV7131_REG_ASLP 0x54
-/* Offset Registers: */
-#define HV7131_REG_OFSR 0x50
-#define HV7131_REG_OFSG 0x51
-#define HV7131_REG_OFSB 0x52
-/* REset level statistics registers: */
-#define HV7131_REG_LOREFNOH 0x57
-#define HV7131_REG_LOREFNOL 0x58
-#define HV7131_REG_HIREFNOH 0x59
-#define HV7131_REG_HIREFNOL 0x5a
-
-/* se401 registers */
-#define SE401_OPERATINGMODE 0x2000
diff --git a/drivers/media/video/gspca/sn9c2028.c b/drivers/media/video/gspca/sn9c2028.c
deleted file mode 100644
index 03fa3fd940b..00000000000
--- a/drivers/media/video/gspca/sn9c2028.c
+++ /dev/null
@@ -1,735 +0,0 @@
-/*
- * SN9C2028 library
- *
- * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "sn9c2028"
-
-#include "gspca.h"
-
-MODULE_AUTHOR("Theodore Kilgore");
-MODULE_DESCRIPTION("Sonix SN9C2028 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- u8 sof_read;
- u16 model;
-};
-
-struct init_command {
- unsigned char instruction[6];
- unsigned char to_read; /* length to read. 0 means no reply requested */
-};
-
-/* How to change the resolution of any of the VGA cams is unknown */
-static const struct v4l2_pix_format vga_mode[] = {
- {640, 480, V4L2_PIX_FMT_SN9C2028, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 4,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-/* No way to change the resolution of the CIF cams is known */
-static const struct v4l2_pix_format cif_mode[] = {
- {352, 288, V4L2_PIX_FMT_SN9C2028, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 3 / 4,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-/* the bytes to write are in gspca_dev->usb_buf */
-static int sn9c2028_command(struct gspca_dev *gspca_dev, u8 *command)
-{
- int rc;
-
- PDEBUG(D_USBO, "sending command %02x%02x%02x%02x%02x%02x", command[0],
- command[1], command[2], command[3], command[4], command[5]);
-
- memcpy(gspca_dev->usb_buf, command, 6);
- rc = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- USB_REQ_GET_CONFIGURATION,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- 2, 0, gspca_dev->usb_buf, 6, 500);
- if (rc < 0) {
- pr_err("command write [%02x] error %d\n",
- gspca_dev->usb_buf[0], rc);
- return rc;
- }
-
- return 0;
-}
-
-static int sn9c2028_read1(struct gspca_dev *gspca_dev)
-{
- int rc;
-
- rc = usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- USB_REQ_GET_STATUS,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- 1, 0, gspca_dev->usb_buf, 1, 500);
- if (rc != 1) {
- pr_err("read1 error %d\n", rc);
- return (rc < 0) ? rc : -EIO;
- }
- PDEBUG(D_USBI, "read1 response %02x", gspca_dev->usb_buf[0]);
- return gspca_dev->usb_buf[0];
-}
-
-static int sn9c2028_read4(struct gspca_dev *gspca_dev, u8 *reading)
-{
- int rc;
- rc = usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- USB_REQ_GET_STATUS,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- 4, 0, gspca_dev->usb_buf, 4, 500);
- if (rc != 4) {
- pr_err("read4 error %d\n", rc);
- return (rc < 0) ? rc : -EIO;
- }
- memcpy(reading, gspca_dev->usb_buf, 4);
- PDEBUG(D_USBI, "read4 response %02x%02x%02x%02x", reading[0],
- reading[1], reading[2], reading[3]);
- return rc;
-}
-
-static int sn9c2028_long_command(struct gspca_dev *gspca_dev, u8 *command)
-{
- int i, status;
- __u8 reading[4];
-
- status = sn9c2028_command(gspca_dev, command);
- if (status < 0)
- return status;
-
- status = -1;
- for (i = 0; i < 256 && status < 2; i++)
- status = sn9c2028_read1(gspca_dev);
- if (status != 2) {
- pr_err("long command status read error %d\n", status);
- return (status < 0) ? status : -EIO;
- }
-
- memset(reading, 0, 4);
- status = sn9c2028_read4(gspca_dev, reading);
- if (status < 0)
- return status;
-
- /* in general, the first byte of the response is the first byte of
- * the command, or'ed with 8 */
- status = sn9c2028_read1(gspca_dev);
- if (status < 0)
- return status;
-
- return 0;
-}
-
-static int sn9c2028_short_command(struct gspca_dev *gspca_dev, u8 *command)
-{
- int err_code;
-
- err_code = sn9c2028_command(gspca_dev, command);
- if (err_code < 0)
- return err_code;
-
- err_code = sn9c2028_read1(gspca_dev);
- if (err_code < 0)
- return err_code;
-
- return 0;
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam = &gspca_dev->cam;
-
- PDEBUG(D_PROBE, "SN9C2028 camera detected (vid/pid 0x%04X:0x%04X)",
- id->idVendor, id->idProduct);
-
- sd->model = id->idProduct;
-
- switch (sd->model) {
- case 0x7005:
- PDEBUG(D_PROBE, "Genius Smart 300 camera");
- break;
- case 0x8000:
- PDEBUG(D_PROBE, "DC31VC");
- break;
- case 0x8001:
- PDEBUG(D_PROBE, "Spy camera");
- break;
- case 0x8003:
- PDEBUG(D_PROBE, "CIF camera");
- break;
- case 0x8008:
- PDEBUG(D_PROBE, "Mini-Shotz ms-350 camera");
- break;
- case 0x800a:
- PDEBUG(D_PROBE, "Vivitar 3350b type camera");
- cam->input_flags = V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
- break;
- }
-
- switch (sd->model) {
- case 0x8000:
- case 0x8001:
- case 0x8003:
- cam->cam_mode = cif_mode;
- cam->nmodes = ARRAY_SIZE(cif_mode);
- break;
- default:
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- }
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- int status = -1;
-
- sn9c2028_read1(gspca_dev);
- sn9c2028_read1(gspca_dev);
- status = sn9c2028_read1(gspca_dev);
-
- return (status < 0) ? status : 0;
-}
-
-static int run_start_commands(struct gspca_dev *gspca_dev,
- struct init_command *cam_commands, int n)
-{
- int i, err_code = -1;
-
- for (i = 0; i < n; i++) {
- switch (cam_commands[i].to_read) {
- case 4:
- err_code = sn9c2028_long_command(gspca_dev,
- cam_commands[i].instruction);
- break;
- case 1:
- err_code = sn9c2028_short_command(gspca_dev,
- cam_commands[i].instruction);
- break;
- case 0:
- err_code = sn9c2028_command(gspca_dev,
- cam_commands[i].instruction);
- break;
- }
- if (err_code < 0)
- return err_code;
- }
- return 0;
-}
-
-static int start_spy_cam(struct gspca_dev *gspca_dev)
-{
- struct init_command spy_start_commands[] = {
- {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x22, 0x01, 0x04, 0x00, 0x00}, 4},
- {{0x13, 0x23, 0x01, 0x03, 0x00, 0x00}, 4},
- {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4}, /* width 352 */
- {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4}, /* height 288 */
- /* {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4}, */
- {{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4},
- {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4}, /* red gain ?*/
- /* {{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4}, */
- {{0x13, 0x29, 0x01, 0x00, 0x00, 0x00}, 4},
- /* {{0x13, 0x29, 0x01, 0x0c, 0x00, 0x00}, 4}, */
- {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
- /* {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, */
- {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
- {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4},
- /* {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4}, */
- {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4},
- {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4},
- {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
- {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x02, 0x06, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x03, 0x13, 0x00, 0x00, 0x00}, 4}, /*don't mess with*/
- /*{{0x11, 0x04, 0x06, 0x00, 0x00, 0x00}, 4}, observed */
- {{0x11, 0x04, 0x00, 0x00, 0x00, 0x00}, 4}, /* brighter */
- /*{{0x11, 0x05, 0x65, 0x00, 0x00, 0x00}, 4}, observed */
- {{0x11, 0x05, 0x00, 0x00, 0x00, 0x00}, 4}, /* brighter */
- {{0x11, 0x06, 0xb1, 0x00, 0x00, 0x00}, 4}, /* observed */
- {{0x11, 0x07, 0x00, 0x00, 0x00, 0x00}, 4},
- /*{{0x11, 0x08, 0x06, 0x00, 0x00, 0x00}, 4}, observed */
- {{0x11, 0x08, 0x0b, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x09, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x0a, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x0b, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x0c, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x0d, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x0e, 0x04, 0x00, 0x00, 0x00}, 4},
- /* {{0x11, 0x0f, 0x00, 0x00, 0x00, 0x00}, 4}, */
- /* brightness or gain. 0 is default. 4 is good
- * indoors at night with incandescent lighting */
- {{0x11, 0x0f, 0x04, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x10, 0x06, 0x00, 0x00, 0x00}, 4}, /*hstart or hoffs*/
- {{0x11, 0x11, 0x06, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x14, 0x02, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x13, 0x01, 0x00, 0x00, 0x00}, 4},
- /* {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1}, observed */
- {{0x1b, 0x02, 0x11, 0x00, 0x00, 0x00}, 1}, /* brighter */
- /* {{0x1b, 0x13, 0x01, 0x00, 0x00, 0x00}, 1}, observed */
- {{0x1b, 0x13, 0x11, 0x00, 0x00, 0x00}, 1},
- {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1}, /* compresses */
- /* Camera should start to capture now. */
- };
-
- return run_start_commands(gspca_dev, spy_start_commands,
- ARRAY_SIZE(spy_start_commands));
-}
-
-static int start_cif_cam(struct gspca_dev *gspca_dev)
-{
- struct init_command cif_start_commands[] = {
- {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
- /* The entire sequence below seems redundant */
- /* {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x22, 0x01, 0x06, 0x00, 0x00}, 4},
- {{0x13, 0x23, 0x01, 0x02, 0x00, 0x00}, 4},
- {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4}, width?
- {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4}, height?
- {{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4}, subsample?
- {{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x29, 0x01, 0x20, 0x00, 0x00}, 4},
- {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
- {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
- {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
- {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
- {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
- {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},*/
- {{0x1b, 0x21, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x17, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x19, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x03, 0x5a, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x04, 0x27, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x05, 0x01, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x12, 0x14, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x13, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x14, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x15, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x16, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x77, 0xa2, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x06, 0x0f, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x07, 0x14, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x08, 0x0f, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x09, 0x10, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x0f, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x12, 0x07, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x10, 0x1f, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
- {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 1}, /* width/8 */
- {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 1}, /* height/8 */
- /* {{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4}, subsample?
- * {{0x13, 0x28, 0x01, 0x1e, 0x00, 0x00}, 4}, does nothing
- * {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4}, */
- /* {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4},
- * causes subsampling
- * but not a change in the resolution setting! */
- {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
- {{0x13, 0x2d, 0x01, 0x01, 0x00, 0x00}, 4},
- {{0x13, 0x2e, 0x01, 0x08, 0x00, 0x00}, 4},
- {{0x13, 0x2f, 0x01, 0x06, 0x00, 0x00}, 4},
- {{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x1b, 0x04, 0x6d, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x05, 0x03, 0x00, 0x00, 0x00}, 1},
- {{0x20, 0x36, 0x06, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x0e, 0x01, 0x00, 0x00, 0x00}, 1},
- {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x1b, 0x0f, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x20, 0x36, 0x05, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x10, 0x0f, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
- {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1},/* use compression */
- /* Camera should start to capture now. */
- };
-
- return run_start_commands(gspca_dev, cif_start_commands,
- ARRAY_SIZE(cif_start_commands));
-}
-
-static int start_ms350_cam(struct gspca_dev *gspca_dev)
-{
- struct init_command ms350_start_commands[] = {
- {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x22, 0x01, 0x04, 0x00, 0x00}, 4},
- {{0x13, 0x23, 0x01, 0x03, 0x00, 0x00}, 4},
- {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
- {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
- {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4},
- {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4},
- {{0x13, 0x29, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
- {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
- {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
- {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
- {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
- {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x00, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x01, 0x70, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x02, 0x05, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x03, 0x5d, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x04, 0x07, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x05, 0x25, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x06, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x07, 0x09, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x08, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x09, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x0b, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x0c, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x0d, 0x0c, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x0e, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x0f, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x11, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x13, 0x63, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x15, 0x70, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x18, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x11, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4}, /* width */
- {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4}, /* height */
- {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4}, /* vstart? */
- {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4},
- {{0x13, 0x29, 0x01, 0x40, 0x00, 0x00}, 4}, /* hstart? */
- {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
- {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
- {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
- {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
- {{0x1b, 0x02, 0x05, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
- {{0x20, 0x18, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x02, 0x0a, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 0},
- /* Camera should start to capture now. */
- };
-
- return run_start_commands(gspca_dev, ms350_start_commands,
- ARRAY_SIZE(ms350_start_commands));
-}
-
-static int start_genius_cam(struct gspca_dev *gspca_dev)
-{
- struct init_command genius_start_commands[] = {
- {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x10, 0x00, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
- {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
- /* "preliminary" width and height settings */
- {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
- {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
- {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4},
- {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
- {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4},
- {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4},
- {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4},
- {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x11, 0x64, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x13, 0x91, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x15, 0x20, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x16, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x17, 0x60, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x25, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x26, 0x02, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x27, 0x88, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x30, 0x38, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x31, 0x2a, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x32, 0x2a, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x33, 0x2a, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x34, 0x02, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x5b, 0x0a, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4}, /* real width */
- {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4}, /* real height */
- {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
- {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
- {{0x13, 0x29, 0x01, 0x62, 0x00, 0x00}, 4},
- {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
- {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
- {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
- {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
- {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x21, 0x2a, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x23, 0x28, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x11, 0x04, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x13, 0x03, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x15, 0xe0, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x16, 0x02, 0x00, 0x00, 0x00}, 4},
- {{0x11, 0x17, 0x80, 0x00, 0x00, 0x00}, 4},
- {{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1},
- {{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1},
- {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 0}
- /* Camera should start to capture now. */
- };
-
- return run_start_commands(gspca_dev, genius_start_commands,
- ARRAY_SIZE(genius_start_commands));
-}
-
-static int start_vivitar_cam(struct gspca_dev *gspca_dev)
-{
- struct init_command vivitar_start_commands[] = {
- {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x22, 0x01, 0x01, 0x00, 0x00}, 4},
- {{0x13, 0x23, 0x01, 0x01, 0x00, 0x00}, 4},
- {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4},
- {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4},
- {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
- {{0x13, 0x28, 0x01, 0x0a, 0x00, 0x00}, 4},
- /*
- * Above is changed from OEM 0x0b. Fixes Bayer tiling.
- * Presumably gives a vertical shift of one row.
- */
- {{0x13, 0x29, 0x01, 0x20, 0x00, 0x00}, 4},
- /* Above seems to do horizontal shift. */
- {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
- {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
- {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
- {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
- /* Above three commands seem to relate to brightness. */
- {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
- {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x1b, 0x12, 0x80, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x01, 0x77, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x02, 0x3a, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x12, 0x78, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x13, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x14, 0x80, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x15, 0x34, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x1b, 0x04, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x20, 0x44, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x23, 0xee, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x26, 0xa0, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x27, 0x9a, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x28, 0xa0, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x29, 0x30, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x2a, 0x80, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x2b, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x2f, 0x3d, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x30, 0x24, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x32, 0x86, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x60, 0xa9, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x61, 0x42, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x65, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x69, 0x38, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x6f, 0x88, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x70, 0x0b, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x71, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x74, 0x21, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x75, 0x86, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x76, 0x00, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x7d, 0xf3, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x17, 0x1c, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x18, 0xc0, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x19, 0x05, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x1a, 0xf6, 0x00, 0x00, 0x00}, 1},
- /* {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4},
- {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4},
- {{0x13, 0x28, 0x01, 0x0b, 0x00, 0x00}, 4}, */
- {{0x20, 0x36, 0x06, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x10, 0x26, 0x00, 0x00, 0x00}, 1},
- {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x1b, 0x76, 0x03, 0x00, 0x00, 0x00}, 1},
- {{0x20, 0x36, 0x05, 0x00, 0x00, 0x00}, 1},
- {{0x1b, 0x00, 0x3f, 0x00, 0x00, 0x00}, 1},
- /* Above is brightness; OEM driver setting is 0x10 */
- {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
- {{0x20, 0x29, 0x30, 0x00, 0x00, 0x00}, 1},
- {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1}
- };
-
- return run_start_commands(gspca_dev, vivitar_start_commands,
- ARRAY_SIZE(vivitar_start_commands));
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int err_code;
-
- sd->sof_read = 0;
-
- switch (sd->model) {
- case 0x7005:
- err_code = start_genius_cam(gspca_dev);
- break;
- case 0x8001:
- err_code = start_spy_cam(gspca_dev);
- break;
- case 0x8003:
- err_code = start_cif_cam(gspca_dev);
- break;
- case 0x8008:
- err_code = start_ms350_cam(gspca_dev);
- break;
- case 0x800a:
- err_code = start_vivitar_cam(gspca_dev);
- break;
- default:
- pr_err("Starting unknown camera, please report this\n");
- return -ENXIO;
- }
-
- return err_code;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- int result;
- __u8 data[6];
-
- result = sn9c2028_read1(gspca_dev);
- if (result < 0)
- PDEBUG(D_ERR, "Camera Stop read failed");
-
- memset(data, 0, 6);
- data[0] = 0x14;
- result = sn9c2028_command(gspca_dev, data);
- if (result < 0)
- PDEBUG(D_ERR, "Camera Stop command failed");
-}
-
-/* Include sn9c2028 sof detection functions */
-#include "sn9c2028.h"
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- __u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- unsigned char *sof;
-
- sof = sn9c2028_find_sof(gspca_dev, data, len);
- if (sof) {
- int n;
-
- /* finish decoding current frame */
- n = sof - data;
- if (n > sizeof sn9c2028_sof_marker)
- n -= sizeof sn9c2028_sof_marker;
- else
- n = 0;
- gspca_frame_add(gspca_dev, LAST_PACKET, data, n);
- /* Start next frame. */
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sn9c2028_sof_marker, sizeof sn9c2028_sof_marker);
- len -= sof - data;
- data = sof;
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x0458, 0x7005)}, /* Genius Smart 300, version 2 */
- /* The Genius Smart is untested. I can't find an owner ! */
- /* {USB_DEVICE(0x0c45, 0x8000)}, DC31VC, Don't know this camera */
- {USB_DEVICE(0x0c45, 0x8001)}, /* Wild Planet digital spy cam */
- {USB_DEVICE(0x0c45, 0x8003)}, /* Several small CIF cameras */
- /* {USB_DEVICE(0x0c45, 0x8006)}, Unknown VGA camera */
- {USB_DEVICE(0x0c45, 0x8008)}, /* Mini-Shotz ms-350 */
- {USB_DEVICE(0x0c45, 0x800a)}, /* Vivicam 3350B */
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/sn9c2028.h b/drivers/media/video/gspca/sn9c2028.h
deleted file mode 100644
index 8fd1d3e0566..00000000000
--- a/drivers/media/video/gspca/sn9c2028.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SN9C2028 common functions
- *
- * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn,edu>
- *
- * Based closely upon the file gspca/pac_common.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-static const unsigned char sn9c2028_sof_marker[5] =
- { 0xff, 0xff, 0x00, 0xc4, 0xc4 };
-
-static unsigned char *sn9c2028_find_sof(struct gspca_dev *gspca_dev,
- unsigned char *m, int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
-
- /* Search for the SOF marker (fixed part) in the header */
- for (i = 0; i < len; i++) {
- if (m[i] == sn9c2028_sof_marker[sd->sof_read]) {
- sd->sof_read++;
- if (sd->sof_read == sizeof(sn9c2028_sof_marker)) {
- PDEBUG(D_FRAM,
- "SOF found, bytes to analyze: %u."
- " Frame starts at byte #%u",
- len, i + 1);
- sd->sof_read = 0;
- return m + i + 1;
- }
- } else {
- sd->sof_read = 0;
- }
- }
-
- return NULL;
-}
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
deleted file mode 100644
index b9c6f17eabb..00000000000
--- a/drivers/media/video/gspca/sn9c20x.c
+++ /dev/null
@@ -1,2428 +0,0 @@
-/*
- * Sonix sn9c201 sn9c202 library
- *
- * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr>
- * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
- * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/input.h>
-
-#include "gspca.h"
-#include "jpeg.h"
-
-#include <media/v4l2-chip-ident.h>
-#include <linux/dmi.h>
-
-MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
- "microdia project <microdia@googlegroups.com>");
-MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/*
- * Pixel format private data
- */
-#define SCALE_MASK 0x0f
-#define SCALE_160x120 0
-#define SCALE_320x240 1
-#define SCALE_640x480 2
-#define SCALE_1280x1024 3
-#define MODE_RAW 0x10
-#define MODE_JPEG 0x20
-#define MODE_SXGA 0x80
-
-#define SENSOR_OV9650 0
-#define SENSOR_OV9655 1
-#define SENSOR_SOI968 2
-#define SENSOR_OV7660 3
-#define SENSOR_OV7670 4
-#define SENSOR_MT9V011 5
-#define SENSOR_MT9V111 6
-#define SENSOR_MT9V112 7
-#define SENSOR_MT9M001 8
-#define SENSOR_MT9M111 9
-#define SENSOR_MT9M112 10
-#define SENSOR_HV7131R 11
-#define SENSOR_MT9VPRB 12
-
-/* camera flags */
-#define HAS_NO_BUTTON 0x1
-#define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
-#define FLIP_DETECT 0x4
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev;
-
- struct { /* color control cluster */
- struct v4l2_ctrl *brightness;
- struct v4l2_ctrl *contrast;
- struct v4l2_ctrl *saturation;
- struct v4l2_ctrl *hue;
- };
- struct { /* blue/red balance control cluster */
- struct v4l2_ctrl *blue;
- struct v4l2_ctrl *red;
- };
- struct { /* h/vflip control cluster */
- struct v4l2_ctrl *hflip;
- struct v4l2_ctrl *vflip;
- };
- struct v4l2_ctrl *gamma;
- struct { /* autogain and exposure or gain control cluster */
- struct v4l2_ctrl *autogain;
- struct v4l2_ctrl *exposure;
- struct v4l2_ctrl *gain;
- };
- struct v4l2_ctrl *jpegqual;
-
- struct work_struct work;
- struct workqueue_struct *work_thread;
-
- u32 pktsz; /* (used by pkt_scan) */
- u16 npkt;
- s8 nchg;
- u8 fmt; /* (used for JPEG QTAB update */
-
-#define MIN_AVG_LUM 80
-#define MAX_AVG_LUM 130
- atomic_t avg_lum;
- u8 old_step;
- u8 older_step;
- u8 exposure_step;
-
- u8 i2c_addr;
- u8 i2c_intf;
- u8 sensor;
- u8 hstart;
- u8 vstart;
-
- u8 jpeg_hdr[JPEG_HDR_SZ];
-
- u8 flags;
-};
-
-static void qual_upd(struct work_struct *work);
-
-struct i2c_reg_u8 {
- u8 reg;
- u8 val;
-};
-
-struct i2c_reg_u16 {
- u8 reg;
- u16 val;
-};
-
-static const struct dmi_system_id flip_dmi_table[] = {
- {
- .ident = "MSI MS-1034",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
- DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
- }
- },
- {
- .ident = "MSI MS-1632",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
- DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
- }
- },
- {
- .ident = "MSI MS-1633X",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
- DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
- }
- },
- {
- .ident = "MSI MS-1635X",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
- DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
- }
- },
- {
- .ident = "ASUSTeK W7J",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
- DMI_MATCH(DMI_BOARD_NAME, "W7J ")
- }
- },
- {}
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 4 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = SCALE_160x120 | MODE_JPEG},
- {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_160x120 | MODE_RAW},
- {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 240 * 120,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_160x120},
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 4 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = SCALE_320x240 | MODE_JPEG},
- {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 ,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_320x240 | MODE_RAW},
- {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 480 * 240 ,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_320x240},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 4 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = SCALE_640x480 | MODE_JPEG},
- {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_640x480 | MODE_RAW},
- {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 960 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_640x480},
-};
-
-static const struct v4l2_pix_format sxga_mode[] = {
- {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 4 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = SCALE_160x120 | MODE_JPEG},
- {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_160x120 | MODE_RAW},
- {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 240 * 120,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_160x120},
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 4 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = SCALE_320x240 | MODE_JPEG},
- {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 ,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_320x240 | MODE_RAW},
- {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 480 * 240 ,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_320x240},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 4 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = SCALE_640x480 | MODE_JPEG},
- {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_640x480 | MODE_RAW},
- {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 960 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_640x480},
- {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 1280,
- .sizeimage = 1280 * 1024,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
-};
-
-static const struct v4l2_pix_format mono_mode[] = {
- {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_160x120 | MODE_RAW},
- {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 ,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_320x240 | MODE_RAW},
- {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_640x480 | MODE_RAW},
- {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
- .bytesperline = 1280,
- .sizeimage = 1280 * 1024,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
-};
-
-static const s16 hsv_red_x[] = {
- 41, 44, 46, 48, 50, 52, 54, 56,
- 58, 60, 62, 64, 66, 68, 70, 72,
- 74, 76, 78, 80, 81, 83, 85, 87,
- 88, 90, 92, 93, 95, 97, 98, 100,
- 101, 102, 104, 105, 107, 108, 109, 110,
- 112, 113, 114, 115, 116, 117, 118, 119,
- 120, 121, 122, 123, 123, 124, 125, 125,
- 126, 127, 127, 128, 128, 129, 129, 129,
- 130, 130, 130, 130, 131, 131, 131, 131,
- 131, 131, 131, 131, 130, 130, 130, 130,
- 129, 129, 129, 128, 128, 127, 127, 126,
- 125, 125, 124, 123, 122, 122, 121, 120,
- 119, 118, 117, 116, 115, 114, 112, 111,
- 110, 109, 107, 106, 105, 103, 102, 101,
- 99, 98, 96, 94, 93, 91, 90, 88,
- 86, 84, 83, 81, 79, 77, 75, 74,
- 72, 70, 68, 66, 64, 62, 60, 58,
- 56, 54, 52, 49, 47, 45, 43, 41,
- 39, 36, 34, 32, 30, 28, 25, 23,
- 21, 19, 16, 14, 12, 9, 7, 5,
- 3, 0, -1, -3, -6, -8, -10, -12,
- -15, -17, -19, -22, -24, -26, -28, -30,
- -33, -35, -37, -39, -41, -44, -46, -48,
- -50, -52, -54, -56, -58, -60, -62, -64,
- -66, -68, -70, -72, -74, -76, -78, -80,
- -81, -83, -85, -87, -88, -90, -92, -93,
- -95, -97, -98, -100, -101, -102, -104, -105,
- -107, -108, -109, -110, -112, -113, -114, -115,
- -116, -117, -118, -119, -120, -121, -122, -123,
- -123, -124, -125, -125, -126, -127, -127, -128,
- -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -127, -127, -126, -125, -125, -124, -123,
- -122, -122, -121, -120, -119, -118, -117, -116,
- -115, -114, -112, -111, -110, -109, -107, -106,
- -105, -103, -102, -101, -99, -98, -96, -94,
- -93, -91, -90, -88, -86, -84, -83, -81,
- -79, -77, -75, -74, -72, -70, -68, -66,
- -64, -62, -60, -58, -56, -54, -52, -49,
- -47, -45, -43, -41, -39, -36, -34, -32,
- -30, -28, -25, -23, -21, -19, -16, -14,
- -12, -9, -7, -5, -3, 0, 1, 3,
- 6, 8, 10, 12, 15, 17, 19, 22,
- 24, 26, 28, 30, 33, 35, 37, 39, 41
-};
-
-static const s16 hsv_red_y[] = {
- 82, 80, 78, 76, 74, 73, 71, 69,
- 67, 65, 63, 61, 58, 56, 54, 52,
- 50, 48, 46, 44, 41, 39, 37, 35,
- 32, 30, 28, 26, 23, 21, 19, 16,
- 14, 12, 10, 7, 5, 3, 0, -1,
- -3, -6, -8, -10, -13, -15, -17, -19,
- -22, -24, -26, -29, -31, -33, -35, -38,
- -40, -42, -44, -46, -48, -51, -53, -55,
- -57, -59, -61, -63, -65, -67, -69, -71,
- -73, -75, -77, -79, -81, -82, -84, -86,
- -88, -89, -91, -93, -94, -96, -98, -99,
- -101, -102, -104, -105, -106, -108, -109, -110,
- -112, -113, -114, -115, -116, -117, -119, -120,
- -120, -121, -122, -123, -124, -125, -126, -126,
- -127, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128,
- -127, -127, -126, -125, -125, -124, -123, -122,
- -121, -120, -119, -118, -117, -116, -115, -114,
- -113, -111, -110, -109, -107, -106, -105, -103,
- -102, -100, -99, -97, -96, -94, -92, -91,
- -89, -87, -85, -84, -82, -80, -78, -76,
- -74, -73, -71, -69, -67, -65, -63, -61,
- -58, -56, -54, -52, -50, -48, -46, -44,
- -41, -39, -37, -35, -32, -30, -28, -26,
- -23, -21, -19, -16, -14, -12, -10, -7,
- -5, -3, 0, 1, 3, 6, 8, 10,
- 13, 15, 17, 19, 22, 24, 26, 29,
- 31, 33, 35, 38, 40, 42, 44, 46,
- 48, 51, 53, 55, 57, 59, 61, 63,
- 65, 67, 69, 71, 73, 75, 77, 79,
- 81, 82, 84, 86, 88, 89, 91, 93,
- 94, 96, 98, 99, 101, 102, 104, 105,
- 106, 108, 109, 110, 112, 113, 114, 115,
- 116, 117, 119, 120, 120, 121, 122, 123,
- 124, 125, 126, 126, 127, 128, 128, 129,
- 129, 130, 130, 131, 131, 131, 131, 132,
- 132, 132, 132, 132, 132, 132, 132, 132,
- 132, 132, 132, 131, 131, 131, 130, 130,
- 130, 129, 129, 128, 127, 127, 126, 125,
- 125, 124, 123, 122, 121, 120, 119, 118,
- 117, 116, 115, 114, 113, 111, 110, 109,
- 107, 106, 105, 103, 102, 100, 99, 97,
- 96, 94, 92, 91, 89, 87, 85, 84, 82
-};
-
-static const s16 hsv_green_x[] = {
- -124, -124, -125, -125, -125, -125, -125, -125,
- -125, -126, -126, -125, -125, -125, -125, -125,
- -125, -124, -124, -124, -123, -123, -122, -122,
- -121, -121, -120, -120, -119, -118, -117, -117,
- -116, -115, -114, -113, -112, -111, -110, -109,
- -108, -107, -105, -104, -103, -102, -100, -99,
- -98, -96, -95, -93, -92, -91, -89, -87,
- -86, -84, -83, -81, -79, -77, -76, -74,
- -72, -70, -69, -67, -65, -63, -61, -59,
- -57, -55, -53, -51, -49, -47, -45, -43,
- -41, -39, -37, -35, -33, -30, -28, -26,
- -24, -22, -20, -18, -15, -13, -11, -9,
- -7, -4, -2, 0, 1, 3, 6, 8,
- 10, 12, 14, 17, 19, 21, 23, 25,
- 27, 29, 32, 34, 36, 38, 40, 42,
- 44, 46, 48, 50, 52, 54, 56, 58,
- 60, 62, 64, 66, 68, 70, 71, 73,
- 75, 77, 78, 80, 82, 83, 85, 87,
- 88, 90, 91, 93, 94, 96, 97, 98,
- 100, 101, 102, 104, 105, 106, 107, 108,
- 109, 111, 112, 113, 113, 114, 115, 116,
- 117, 118, 118, 119, 120, 120, 121, 122,
- 122, 123, 123, 124, 124, 124, 125, 125,
- 125, 125, 125, 125, 125, 126, 126, 125,
- 125, 125, 125, 125, 125, 124, 124, 124,
- 123, 123, 122, 122, 121, 121, 120, 120,
- 119, 118, 117, 117, 116, 115, 114, 113,
- 112, 111, 110, 109, 108, 107, 105, 104,
- 103, 102, 100, 99, 98, 96, 95, 93,
- 92, 91, 89, 87, 86, 84, 83, 81,
- 79, 77, 76, 74, 72, 70, 69, 67,
- 65, 63, 61, 59, 57, 55, 53, 51,
- 49, 47, 45, 43, 41, 39, 37, 35,
- 33, 30, 28, 26, 24, 22, 20, 18,
- 15, 13, 11, 9, 7, 4, 2, 0,
- -1, -3, -6, -8, -10, -12, -14, -17,
- -19, -21, -23, -25, -27, -29, -32, -34,
- -36, -38, -40, -42, -44, -46, -48, -50,
- -52, -54, -56, -58, -60, -62, -64, -66,
- -68, -70, -71, -73, -75, -77, -78, -80,
- -82, -83, -85, -87, -88, -90, -91, -93,
- -94, -96, -97, -98, -100, -101, -102, -104,
- -105, -106, -107, -108, -109, -111, -112, -113,
- -113, -114, -115, -116, -117, -118, -118, -119,
- -120, -120, -121, -122, -122, -123, -123, -124, -124
-};
-
-static const s16 hsv_green_y[] = {
- -100, -99, -98, -97, -95, -94, -93, -91,
- -90, -89, -87, -86, -84, -83, -81, -80,
- -78, -76, -75, -73, -71, -70, -68, -66,
- -64, -63, -61, -59, -57, -55, -53, -51,
- -49, -48, -46, -44, -42, -40, -38, -36,
- -34, -32, -30, -27, -25, -23, -21, -19,
- -17, -15, -13, -11, -9, -7, -4, -2,
- 0, 1, 3, 5, 7, 9, 11, 14,
- 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46,
- 48, 50, 52, 54, 56, 58, 59, 61,
- 63, 65, 67, 68, 70, 72, 74, 75,
- 77, 78, 80, 82, 83, 85, 86, 88,
- 89, 90, 92, 93, 95, 96, 97, 98,
- 100, 101, 102, 103, 104, 105, 106, 107,
- 108, 109, 110, 111, 112, 112, 113, 114,
- 115, 115, 116, 116, 117, 117, 118, 118,
- 119, 119, 119, 120, 120, 120, 120, 120,
- 121, 121, 121, 121, 121, 121, 120, 120,
- 120, 120, 120, 119, 119, 119, 118, 118,
- 117, 117, 116, 116, 115, 114, 114, 113,
- 112, 111, 111, 110, 109, 108, 107, 106,
- 105, 104, 103, 102, 100, 99, 98, 97,
- 95, 94, 93, 91, 90, 89, 87, 86,
- 84, 83, 81, 80, 78, 76, 75, 73,
- 71, 70, 68, 66, 64, 63, 61, 59,
- 57, 55, 53, 51, 49, 48, 46, 44,
- 42, 40, 38, 36, 34, 32, 30, 27,
- 25, 23, 21, 19, 17, 15, 13, 11,
- 9, 7, 4, 2, 0, -1, -3, -5,
- -7, -9, -11, -14, -16, -18, -20, -22,
- -24, -26, -28, -30, -32, -34, -36, -38,
- -40, -42, -44, -46, -48, -50, -52, -54,
- -56, -58, -59, -61, -63, -65, -67, -68,
- -70, -72, -74, -75, -77, -78, -80, -82,
- -83, -85, -86, -88, -89, -90, -92, -93,
- -95, -96, -97, -98, -100, -101, -102, -103,
- -104, -105, -106, -107, -108, -109, -110, -111,
- -112, -112, -113, -114, -115, -115, -116, -116,
- -117, -117, -118, -118, -119, -119, -119, -120,
- -120, -120, -120, -120, -121, -121, -121, -121,
- -121, -121, -120, -120, -120, -120, -120, -119,
- -119, -119, -118, -118, -117, -117, -116, -116,
- -115, -114, -114, -113, -112, -111, -111, -110,
- -109, -108, -107, -106, -105, -104, -103, -102, -100
-};
-
-static const s16 hsv_blue_x[] = {
- 112, 113, 114, 114, 115, 116, 117, 117,
- 118, 118, 119, 119, 120, 120, 120, 121,
- 121, 121, 122, 122, 122, 122, 122, 122,
- 122, 122, 122, 122, 122, 122, 121, 121,
- 121, 120, 120, 120, 119, 119, 118, 118,
- 117, 116, 116, 115, 114, 113, 113, 112,
- 111, 110, 109, 108, 107, 106, 105, 104,
- 103, 102, 100, 99, 98, 97, 95, 94,
- 93, 91, 90, 88, 87, 85, 84, 82,
- 80, 79, 77, 76, 74, 72, 70, 69,
- 67, 65, 63, 61, 60, 58, 56, 54,
- 52, 50, 48, 46, 44, 42, 40, 38,
- 36, 34, 32, 30, 28, 26, 24, 22,
- 19, 17, 15, 13, 11, 9, 7, 5,
- 2, 0, -1, -3, -5, -7, -9, -12,
- -14, -16, -18, -20, -22, -24, -26, -28,
- -31, -33, -35, -37, -39, -41, -43, -45,
- -47, -49, -51, -53, -54, -56, -58, -60,
- -62, -64, -66, -67, -69, -71, -73, -74,
- -76, -78, -79, -81, -83, -84, -86, -87,
- -89, -90, -92, -93, -94, -96, -97, -98,
- -99, -101, -102, -103, -104, -105, -106, -107,
- -108, -109, -110, -111, -112, -113, -114, -114,
- -115, -116, -117, -117, -118, -118, -119, -119,
- -120, -120, -120, -121, -121, -121, -122, -122,
- -122, -122, -122, -122, -122, -122, -122, -122,
- -122, -122, -121, -121, -121, -120, -120, -120,
- -119, -119, -118, -118, -117, -116, -116, -115,
- -114, -113, -113, -112, -111, -110, -109, -108,
- -107, -106, -105, -104, -103, -102, -100, -99,
- -98, -97, -95, -94, -93, -91, -90, -88,
- -87, -85, -84, -82, -80, -79, -77, -76,
- -74, -72, -70, -69, -67, -65, -63, -61,
- -60, -58, -56, -54, -52, -50, -48, -46,
- -44, -42, -40, -38, -36, -34, -32, -30,
- -28, -26, -24, -22, -19, -17, -15, -13,
- -11, -9, -7, -5, -2, 0, 1, 3,
- 5, 7, 9, 12, 14, 16, 18, 20,
- 22, 24, 26, 28, 31, 33, 35, 37,
- 39, 41, 43, 45, 47, 49, 51, 53,
- 54, 56, 58, 60, 62, 64, 66, 67,
- 69, 71, 73, 74, 76, 78, 79, 81,
- 83, 84, 86, 87, 89, 90, 92, 93,
- 94, 96, 97, 98, 99, 101, 102, 103,
- 104, 105, 106, 107, 108, 109, 110, 111, 112
-};
-
-static const s16 hsv_blue_y[] = {
- -11, -13, -15, -17, -19, -21, -23, -25,
- -27, -29, -31, -33, -35, -37, -39, -41,
- -43, -45, -46, -48, -50, -52, -54, -55,
- -57, -59, -61, -62, -64, -66, -67, -69,
- -71, -72, -74, -75, -77, -78, -80, -81,
- -83, -84, -86, -87, -88, -90, -91, -92,
- -93, -95, -96, -97, -98, -99, -100, -101,
- -102, -103, -104, -105, -106, -106, -107, -108,
- -109, -109, -110, -111, -111, -112, -112, -113,
- -113, -114, -114, -114, -115, -115, -115, -115,
- -116, -116, -116, -116, -116, -116, -116, -116,
- -116, -115, -115, -115, -115, -114, -114, -114,
- -113, -113, -112, -112, -111, -111, -110, -110,
- -109, -108, -108, -107, -106, -105, -104, -103,
- -102, -101, -100, -99, -98, -97, -96, -95,
- -94, -93, -91, -90, -89, -88, -86, -85,
- -84, -82, -81, -79, -78, -76, -75, -73,
- -71, -70, -68, -67, -65, -63, -62, -60,
- -58, -56, -55, -53, -51, -49, -47, -45,
- -44, -42, -40, -38, -36, -34, -32, -30,
- -28, -26, -24, -22, -20, -18, -16, -14,
- -12, -10, -8, -6, -4, -2, 0, 1,
- 3, 5, 7, 9, 11, 13, 15, 17,
- 19, 21, 23, 25, 27, 29, 31, 33,
- 35, 37, 39, 41, 43, 45, 46, 48,
- 50, 52, 54, 55, 57, 59, 61, 62,
- 64, 66, 67, 69, 71, 72, 74, 75,
- 77, 78, 80, 81, 83, 84, 86, 87,
- 88, 90, 91, 92, 93, 95, 96, 97,
- 98, 99, 100, 101, 102, 103, 104, 105,
- 106, 106, 107, 108, 109, 109, 110, 111,
- 111, 112, 112, 113, 113, 114, 114, 114,
- 115, 115, 115, 115, 116, 116, 116, 116,
- 116, 116, 116, 116, 116, 115, 115, 115,
- 115, 114, 114, 114, 113, 113, 112, 112,
- 111, 111, 110, 110, 109, 108, 108, 107,
- 106, 105, 104, 103, 102, 101, 100, 99,
- 98, 97, 96, 95, 94, 93, 91, 90,
- 89, 88, 86, 85, 84, 82, 81, 79,
- 78, 76, 75, 73, 71, 70, 68, 67,
- 65, 63, 62, 60, 58, 56, 55, 53,
- 51, 49, 47, 45, 44, 42, 40, 38,
- 36, 34, 32, 30, 28, 26, 24, 22,
- 20, 18, 16, 14, 12, 10, 8, 6,
- 4, 2, 0, -1, -3, -5, -7, -9, -11
-};
-
-static const u16 i2c_ident[] = {
- V4L2_IDENT_OV9650,
- V4L2_IDENT_OV9655,
- V4L2_IDENT_SOI968,
- V4L2_IDENT_OV7660,
- V4L2_IDENT_OV7670,
- V4L2_IDENT_MT9V011,
- V4L2_IDENT_MT9V111,
- V4L2_IDENT_MT9V112,
- V4L2_IDENT_MT9M001C12ST,
- V4L2_IDENT_MT9M111,
- V4L2_IDENT_MT9M112,
- V4L2_IDENT_HV7131R,
-[SENSOR_MT9VPRB] = V4L2_IDENT_UNKNOWN,
-};
-
-static const u16 bridge_init[][2] = {
- {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
- {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
- {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
- {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
- {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
- {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
- {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
- {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
- {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
- {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
- {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
- {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
- {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
- {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
- {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
- {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
- {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
- {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
- {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
- {0x1007, 0x00}
-};
-
-/* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
-static const u8 ov_gain[] = {
- 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
- 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
- 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
- 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
- 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
- 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
- 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
- 0x70 /* 8x */
-};
-
-/* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
-static const u16 micron1_gain[] = {
- /* 1x 1.25x 1.5x 1.75x */
- 0x0020, 0x0028, 0x0030, 0x0038,
- /* 2x 2.25x 2.5x 2.75x */
- 0x00a0, 0x00a4, 0x00a8, 0x00ac,
- /* 3x 3.25x 3.5x 3.75x */
- 0x00b0, 0x00b4, 0x00b8, 0x00bc,
- /* 4x 4.25x 4.5x 4.75x */
- 0x00c0, 0x00c4, 0x00c8, 0x00cc,
- /* 5x 5.25x 5.5x 5.75x */
- 0x00d0, 0x00d4, 0x00d8, 0x00dc,
- /* 6x 6.25x 6.5x 6.75x */
- 0x00e0, 0x00e4, 0x00e8, 0x00ec,
- /* 7x 7.25x 7.5x 7.75x */
- 0x00f0, 0x00f4, 0x00f8, 0x00fc,
- /* 8x */
- 0x01c0
-};
-
-/* mt9m001 sensor uses a different gain formula then other micron sensors */
-/* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
-static const u16 micron2_gain[] = {
- /* 1x 1.25x 1.5x 1.75x */
- 0x0008, 0x000a, 0x000c, 0x000e,
- /* 2x 2.25x 2.5x 2.75x */
- 0x0010, 0x0012, 0x0014, 0x0016,
- /* 3x 3.25x 3.5x 3.75x */
- 0x0018, 0x001a, 0x001c, 0x001e,
- /* 4x 4.25x 4.5x 4.75x */
- 0x0020, 0x0051, 0x0052, 0x0053,
- /* 5x 5.25x 5.5x 5.75x */
- 0x0054, 0x0055, 0x0056, 0x0057,
- /* 6x 6.25x 6.5x 6.75x */
- 0x0058, 0x0059, 0x005a, 0x005b,
- /* 7x 7.25x 7.5x 7.75x */
- 0x005c, 0x005d, 0x005e, 0x005f,
- /* 8x */
- 0x0060
-};
-
-/* Gain = .5 + bit[7:0] / 16 */
-static const u8 hv7131r_gain[] = {
- 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
- 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
- 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
- 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
- 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
- 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
- 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
- 0x78 /* 8x */
-};
-
-static const struct i2c_reg_u8 soi968_init[] = {
- {0x0c, 0x00}, {0x0f, 0x1f},
- {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
- {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
- {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
- {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
- {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
- {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
- {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
- {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
- {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
- {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
-};
-
-static const struct i2c_reg_u8 ov7660_init[] = {
- {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
- {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
- {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
- /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
- 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
- {0x17, 0x10}, {0x18, 0x61},
- {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
- {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
- {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
-};
-
-static const struct i2c_reg_u8 ov7670_init[] = {
- {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
- {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
- {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
- {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
- {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
- {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
- {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
- {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
- {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
- {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
- {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
- {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
- {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
- {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
- {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
- {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
- {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
- {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
- {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
- {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
- {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
- {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
- {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
- {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
- {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
- {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
- {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
- {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
- {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
- {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
- {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
- {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
- {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
- {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
- {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
- {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
- {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
- {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
- {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
- {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
- {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
- {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
- {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
- {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
- {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
- {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
- {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
- {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
- {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
- {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
- {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
- {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
- {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
- {0x93, 0x00},
-};
-
-static const struct i2c_reg_u8 ov9650_init[] = {
- {0x00, 0x00}, {0x01, 0x78},
- {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
- {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
- {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
- {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
- {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
- {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
- {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
- {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
- {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
- {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
- {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
- {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
- {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
- {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
- {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
- {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
- {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
- {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
- {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
- {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
- {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
- {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
- {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
- {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
- {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
- {0xaa, 0x92}, {0xab, 0x0a},
-};
-
-static const struct i2c_reg_u8 ov9655_init[] = {
- {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
- {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
- {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
- {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
- {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
- {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
- {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
- {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
- {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
- {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
- {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
- {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
- {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
- {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
- {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
- {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
- {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
- {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
- {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
- {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
- {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
- {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
- {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
- {0x04, 0x03}, {0x00, 0x13},
-};
-
-static const struct i2c_reg_u16 mt9v112_init[] = {
- {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
- {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
- {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
- {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
- {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
- {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
- {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
- {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
- {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
- {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
- {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
- {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
- {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
- {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
- {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
- {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
-};
-
-static const struct i2c_reg_u16 mt9v111_init[] = {
- {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
- {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
- {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
- {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
- {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
- {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
- {0x0e, 0x0008}, {0x20, 0x0000}
-};
-
-static const struct i2c_reg_u16 mt9v011_init[] = {
- {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
- {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
- {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
- {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
- {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
- {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
- {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
- {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
- {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
- {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
- {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
- {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
- {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
- {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
- {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
- {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
- {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
- {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
- {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
- {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
- {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
- {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
- {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
- {0x06, 0x0029}, {0x05, 0x0009},
-};
-
-static const struct i2c_reg_u16 mt9m001_init[] = {
- {0x0d, 0x0001},
- {0x0d, 0x0000},
- {0x04, 0x0500}, /* hres = 1280 */
- {0x03, 0x0400}, /* vres = 1024 */
- {0x20, 0x1100},
- {0x06, 0x0010},
- {0x2b, 0x0024},
- {0x2e, 0x0024},
- {0x35, 0x0024},
- {0x2d, 0x0020},
- {0x2c, 0x0020},
- {0x09, 0x0ad4},
- {0x35, 0x0057},
-};
-
-static const struct i2c_reg_u16 mt9m111_init[] = {
- {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
- {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
- {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
- {0xf0, 0x0000},
-};
-
-static const struct i2c_reg_u16 mt9m112_init[] = {
- {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
- {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
- {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
- {0xf0, 0x0000},
-};
-
-static const struct i2c_reg_u8 hv7131r_init[] = {
- {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
- {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
- {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
- {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
- {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
- {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
- {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
- {0x23, 0x09}, {0x01, 0x08},
-};
-
-static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
-{
- struct usb_device *dev = gspca_dev->dev;
- int result;
-
- if (gspca_dev->usb_err < 0)
- return;
- result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- 0x00,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- reg,
- 0x00,
- gspca_dev->usb_buf,
- length,
- 500);
- if (unlikely(result < 0 || result != length)) {
- pr_err("Read register %02x failed %d\n", reg, result);
- gspca_dev->usb_err = result;
- }
-}
-
-static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
- const u8 *buffer, int length)
-{
- struct usb_device *dev = gspca_dev->dev;
- int result;
-
- if (gspca_dev->usb_err < 0)
- return;
- memcpy(gspca_dev->usb_buf, buffer, length);
- result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x08,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- reg,
- 0x00,
- gspca_dev->usb_buf,
- length,
- 500);
- if (unlikely(result < 0 || result != length)) {
- pr_err("Write register %02x failed %d\n", reg, result);
- gspca_dev->usb_err = result;
- }
-}
-
-static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
-{
- reg_w(gspca_dev, reg, &value, 1);
-}
-
-static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
-{
- int i;
-
- reg_w(gspca_dev, 0x10c0, buffer, 8);
- for (i = 0; i < 5; i++) {
- reg_r(gspca_dev, 0x10c0, 1);
- if (gspca_dev->usb_err < 0)
- return;
- if (gspca_dev->usb_buf[0] & 0x04) {
- if (gspca_dev->usb_buf[0] & 0x08) {
- pr_err("i2c_w error\n");
- gspca_dev->usb_err = -EIO;
- }
- return;
- }
- msleep(10);
- }
- pr_err("i2c_w reg %02x no response\n", buffer[2]);
-/* gspca_dev->usb_err = -EIO; fixme: may occur */
-}
-
-static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 row[8];
-
- /*
- * from the point of view of the bridge, the length
- * includes the address
- */
- row[0] = sd->i2c_intf | (2 << 4);
- row[1] = sd->i2c_addr;
- row[2] = reg;
- row[3] = val;
- row[4] = 0x00;
- row[5] = 0x00;
- row[6] = 0x00;
- row[7] = 0x10;
-
- i2c_w(gspca_dev, row);
-}
-
-static void i2c_w1_buf(struct gspca_dev *gspca_dev,
- const struct i2c_reg_u8 *buf, int sz)
-{
- while (--sz >= 0) {
- i2c_w1(gspca_dev, buf->reg, buf->val);
- buf++;
- }
-}
-
-static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 row[8];
-
- /*
- * from the point of view of the bridge, the length
- * includes the address
- */
- row[0] = sd->i2c_intf | (3 << 4);
- row[1] = sd->i2c_addr;
- row[2] = reg;
- row[3] = val >> 8;
- row[4] = val;
- row[5] = 0x00;
- row[6] = 0x00;
- row[7] = 0x10;
-
- i2c_w(gspca_dev, row);
-}
-
-static void i2c_w2_buf(struct gspca_dev *gspca_dev,
- const struct i2c_reg_u16 *buf, int sz)
-{
- while (--sz >= 0) {
- i2c_w2(gspca_dev, buf->reg, buf->val);
- buf++;
- }
-}
-
-static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 row[8];
-
- row[0] = sd->i2c_intf | (1 << 4);
- row[1] = sd->i2c_addr;
- row[2] = reg;
- row[3] = 0;
- row[4] = 0;
- row[5] = 0;
- row[6] = 0;
- row[7] = 0x10;
- i2c_w(gspca_dev, row);
- row[0] = sd->i2c_intf | (1 << 4) | 0x02;
- row[2] = 0;
- i2c_w(gspca_dev, row);
- reg_r(gspca_dev, 0x10c2, 5);
- *val = gspca_dev->usb_buf[4];
-}
-
-static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 row[8];
-
- row[0] = sd->i2c_intf | (1 << 4);
- row[1] = sd->i2c_addr;
- row[2] = reg;
- row[3] = 0;
- row[4] = 0;
- row[5] = 0;
- row[6] = 0;
- row[7] = 0x10;
- i2c_w(gspca_dev, row);
- row[0] = sd->i2c_intf | (2 << 4) | 0x02;
- row[2] = 0;
- i2c_w(gspca_dev, row);
- reg_r(gspca_dev, 0x10c2, 5);
- *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
-}
-
-static void ov9650_init_sensor(struct gspca_dev *gspca_dev)
-{
- u16 id;
- struct sd *sd = (struct sd *) gspca_dev;
-
- i2c_r2(gspca_dev, 0x1c, &id);
- if (gspca_dev->usb_err < 0)
- return;
-
- if (id != 0x7fa2) {
- pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id);
- gspca_dev->usb_err = -ENODEV;
- return;
- }
-
- i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
- msleep(200);
- i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init));
- if (gspca_dev->usb_err < 0)
- pr_err("OV9650 sensor initialization failed\n");
- sd->hstart = 1;
- sd->vstart = 7;
-}
-
-static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
- msleep(200);
- i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init));
- if (gspca_dev->usb_err < 0)
- pr_err("OV9655 sensor initialization failed\n");
-
- sd->hstart = 1;
- sd->vstart = 2;
-}
-
-static void soi968_init_sensor(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
- msleep(200);
- i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init));
- if (gspca_dev->usb_err < 0)
- pr_err("SOI968 sensor initialization failed\n");
-
- sd->hstart = 60;
- sd->vstart = 11;
-}
-
-static void ov7660_init_sensor(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
- msleep(200);
- i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init));
- if (gspca_dev->usb_err < 0)
- pr_err("OV7660 sensor initialization failed\n");
- sd->hstart = 3;
- sd->vstart = 3;
-}
-
-static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
- msleep(200);
- i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init));
- if (gspca_dev->usb_err < 0)
- pr_err("OV7670 sensor initialization failed\n");
-
- sd->hstart = 0;
- sd->vstart = 1;
-}
-
-static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u16 value;
-
- sd->i2c_addr = 0x5d;
- i2c_r2(gspca_dev, 0xff, &value);
- if (gspca_dev->usb_err >= 0
- && value == 0x8243) {
- i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init));
- if (gspca_dev->usb_err < 0) {
- pr_err("MT9V011 sensor initialization failed\n");
- return;
- }
- sd->hstart = 2;
- sd->vstart = 2;
- sd->sensor = SENSOR_MT9V011;
- pr_info("MT9V011 sensor detected\n");
- return;
- }
-
- gspca_dev->usb_err = 0;
- sd->i2c_addr = 0x5c;
- i2c_w2(gspca_dev, 0x01, 0x0004);
- i2c_r2(gspca_dev, 0xff, &value);
- if (gspca_dev->usb_err >= 0
- && value == 0x823a) {
- i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init));
- if (gspca_dev->usb_err < 0) {
- pr_err("MT9V111 sensor initialization failed\n");
- return;
- }
- sd->hstart = 2;
- sd->vstart = 2;
- sd->sensor = SENSOR_MT9V111;
- pr_info("MT9V111 sensor detected\n");
- return;
- }
-
- gspca_dev->usb_err = 0;
- sd->i2c_addr = 0x5d;
- i2c_w2(gspca_dev, 0xf0, 0x0000);
- if (gspca_dev->usb_err < 0) {
- gspca_dev->usb_err = 0;
- sd->i2c_addr = 0x48;
- i2c_w2(gspca_dev, 0xf0, 0x0000);
- }
- i2c_r2(gspca_dev, 0x00, &value);
- if (gspca_dev->usb_err >= 0
- && value == 0x1229) {
- i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init));
- if (gspca_dev->usb_err < 0) {
- pr_err("MT9V112 sensor initialization failed\n");
- return;
- }
- sd->hstart = 6;
- sd->vstart = 2;
- sd->sensor = SENSOR_MT9V112;
- pr_info("MT9V112 sensor detected\n");
- return;
- }
-
- gspca_dev->usb_err = -ENODEV;
-}
-
-static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init));
- if (gspca_dev->usb_err < 0)
- pr_err("MT9M112 sensor initialization failed\n");
-
- sd->hstart = 0;
- sd->vstart = 2;
-}
-
-static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init));
- if (gspca_dev->usb_err < 0)
- pr_err("MT9M111 sensor initialization failed\n");
-
- sd->hstart = 0;
- sd->vstart = 2;
-}
-
-static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u16 id;
-
- i2c_r2(gspca_dev, 0x00, &id);
- if (gspca_dev->usb_err < 0)
- return;
-
- /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
- switch (id) {
- case 0x8411:
- case 0x8421:
- pr_info("MT9M001 color sensor detected\n");
- break;
- case 0x8431:
- pr_info("MT9M001 mono sensor detected\n");
- break;
- default:
- pr_err("No MT9M001 chip detected, ID = %x\n\n", id);
- gspca_dev->usb_err = -ENODEV;
- return;
- }
-
- i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init));
- if (gspca_dev->usb_err < 0)
- pr_err("MT9M001 sensor initialization failed\n");
-
- sd->hstart = 1;
- sd->vstart = 1;
-}
-
-static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init));
- if (gspca_dev->usb_err < 0)
- pr_err("HV7131R Sensor initialization failed\n");
-
- sd->hstart = 0;
- sd->vstart = 1;
-}
-
-static void set_cmatrix(struct gspca_dev *gspca_dev,
- s32 brightness, s32 contrast, s32 satur, s32 hue)
-{
- s32 hue_coord, hue_index = 180 + hue;
- u8 cmatrix[21];
-
- memset(cmatrix, 0, sizeof cmatrix);
- cmatrix[2] = (contrast * 0x25 / 0x100) + 0x26;
- cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
- cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
- cmatrix[18] = brightness - 0x80;
-
- hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
- cmatrix[6] = hue_coord;
- cmatrix[7] = (hue_coord >> 8) & 0x0f;
-
- hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
- cmatrix[8] = hue_coord;
- cmatrix[9] = (hue_coord >> 8) & 0x0f;
-
- hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
- cmatrix[10] = hue_coord;
- cmatrix[11] = (hue_coord >> 8) & 0x0f;
-
- hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
- cmatrix[12] = hue_coord;
- cmatrix[13] = (hue_coord >> 8) & 0x0f;
-
- hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
- cmatrix[14] = hue_coord;
- cmatrix[15] = (hue_coord >> 8) & 0x0f;
-
- hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
- cmatrix[16] = hue_coord;
- cmatrix[17] = (hue_coord >> 8) & 0x0f;
-
- reg_w(gspca_dev, 0x10e1, cmatrix, 21);
-}
-
-static void set_gamma(struct gspca_dev *gspca_dev, s32 val)
-{
- u8 gamma[17];
- u8 gval = val * 0xb8 / 0x100;
-
- gamma[0] = 0x0a;
- gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
- gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
- gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
- gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
- gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
- gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
- gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
- gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
- gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
- gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
- gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
- gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
- gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
- gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
- gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
- gamma[16] = 0xf5;
-
- reg_w(gspca_dev, 0x1190, gamma, 17);
-}
-
-static void set_redblue(struct gspca_dev *gspca_dev, s32 blue, s32 red)
-{
- reg_w1(gspca_dev, 0x118c, red);
- reg_w1(gspca_dev, 0x118f, blue);
-}
-
-static void set_hvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
-{
- u8 value, tslb;
- u16 value2;
- struct sd *sd = (struct sd *) gspca_dev;
-
- if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
- hflip = !hflip;
- vflip = !vflip;
- }
-
- switch (sd->sensor) {
- case SENSOR_OV7660:
- value = 0x01;
- if (hflip)
- value |= 0x20;
- if (vflip) {
- value |= 0x10;
- sd->vstart = 2;
- } else {
- sd->vstart = 3;
- }
- reg_w1(gspca_dev, 0x1182, sd->vstart);
- i2c_w1(gspca_dev, 0x1e, value);
- break;
- case SENSOR_OV9650:
- i2c_r1(gspca_dev, 0x1e, &value);
- value &= ~0x30;
- tslb = 0x01;
- if (hflip)
- value |= 0x20;
- if (vflip) {
- value |= 0x10;
- tslb = 0x49;
- }
- i2c_w1(gspca_dev, 0x1e, value);
- i2c_w1(gspca_dev, 0x3a, tslb);
- break;
- case SENSOR_MT9V111:
- case SENSOR_MT9V011:
- i2c_r2(gspca_dev, 0x20, &value2);
- value2 &= ~0xc0a0;
- if (hflip)
- value2 |= 0x8080;
- if (vflip)
- value2 |= 0x4020;
- i2c_w2(gspca_dev, 0x20, value2);
- break;
- case SENSOR_MT9M112:
- case SENSOR_MT9M111:
- case SENSOR_MT9V112:
- i2c_r2(gspca_dev, 0x20, &value2);
- value2 &= ~0x0003;
- if (hflip)
- value2 |= 0x0002;
- if (vflip)
- value2 |= 0x0001;
- i2c_w2(gspca_dev, 0x20, value2);
- break;
- case SENSOR_HV7131R:
- i2c_r1(gspca_dev, 0x01, &value);
- value &= ~0x03;
- if (vflip)
- value |= 0x01;
- if (hflip)
- value |= 0x02;
- i2c_w1(gspca_dev, 0x01, value);
- break;
- }
-}
-
-static void set_exposure(struct gspca_dev *gspca_dev, s32 expo)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 exp[8] = {sd->i2c_intf, sd->i2c_addr,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
- int expo2;
-
- if (gspca_dev->streaming)
- exp[7] = 0x1e;
-
- switch (sd->sensor) {
- case SENSOR_OV7660:
- case SENSOR_OV7670:
- case SENSOR_OV9655:
- case SENSOR_OV9650:
- if (expo > 547)
- expo2 = 547;
- else
- expo2 = expo;
- exp[0] |= (2 << 4);
- exp[2] = 0x10; /* AECH */
- exp[3] = expo2 >> 2;
- exp[7] = 0x10;
- i2c_w(gspca_dev, exp);
- exp[2] = 0x04; /* COM1 */
- exp[3] = expo2 & 0x0003;
- exp[7] = 0x10;
- i2c_w(gspca_dev, exp);
- expo -= expo2;
- exp[7] = 0x1e;
- exp[0] |= (3 << 4);
- exp[2] = 0x2d; /* ADVFL & ADVFH */
- exp[3] = expo;
- exp[4] = expo >> 8;
- break;
- case SENSOR_MT9M001:
- case SENSOR_MT9V112:
- case SENSOR_MT9V011:
- exp[0] |= (3 << 4);
- exp[2] = 0x09;
- exp[3] = expo >> 8;
- exp[4] = expo;
- break;
- case SENSOR_HV7131R:
- exp[0] |= (4 << 4);
- exp[2] = 0x25;
- exp[3] = expo >> 5;
- exp[4] = expo << 3;
- exp[5] = 0;
- break;
- default:
- return;
- }
- i2c_w(gspca_dev, exp);
-}
-
-static void set_gain(struct gspca_dev *gspca_dev, s32 g)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 gain[8] = {sd->i2c_intf, sd->i2c_addr,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
-
- if (gspca_dev->streaming)
- gain[7] = 0x15; /* or 1d ? */
-
- switch (sd->sensor) {
- case SENSOR_OV7660:
- case SENSOR_OV7670:
- case SENSOR_SOI968:
- case SENSOR_OV9655:
- case SENSOR_OV9650:
- gain[0] |= (2 << 4);
- gain[3] = ov_gain[g];
- break;
- case SENSOR_MT9V011:
- gain[0] |= (3 << 4);
- gain[2] = 0x35;
- gain[3] = micron1_gain[g] >> 8;
- gain[4] = micron1_gain[g];
- break;
- case SENSOR_MT9V112:
- gain[0] |= (3 << 4);
- gain[2] = 0x2f;
- gain[3] = micron1_gain[g] >> 8;
- gain[4] = micron1_gain[g];
- break;
- case SENSOR_MT9M001:
- gain[0] |= (3 << 4);
- gain[2] = 0x2f;
- gain[3] = micron2_gain[g] >> 8;
- gain[4] = micron2_gain[g];
- break;
- case SENSOR_HV7131R:
- gain[0] |= (2 << 4);
- gain[2] = 0x30;
- gain[3] = hv7131r_gain[g];
- break;
- default:
- return;
- }
- i2c_w(gspca_dev, gain);
-}
-
-static void set_quality(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- jpeg_set_qual(sd->jpeg_hdr, val);
- reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */
- reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
- reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
- reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
- reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */
- reg_w1(gspca_dev, 0x10e0, sd->fmt);
- sd->fmt ^= 0x0c; /* invert QTAB use + write */
- reg_w1(gspca_dev, 0x10e0, sd->fmt);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
- struct v4l2_dbg_register *reg)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- if (reg->match.addr != 0)
- return -EINVAL;
- if (reg->reg < 0x1000 || reg->reg > 0x11ff)
- return -EINVAL;
- reg_r(gspca_dev, reg->reg, 1);
- reg->val = gspca_dev->usb_buf[0];
- return gspca_dev->usb_err;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- if (reg->match.addr != sd->i2c_addr)
- return -EINVAL;
- if (sd->sensor >= SENSOR_MT9V011 &&
- sd->sensor <= SENSOR_MT9M112) {
- i2c_r2(gspca_dev, reg->reg, (u16 *) &reg->val);
- } else {
- i2c_r1(gspca_dev, reg->reg, (u8 *) &reg->val);
- }
- return gspca_dev->usb_err;
- }
- return -EINVAL;
-}
-
-static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
- struct v4l2_dbg_register *reg)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- if (reg->match.addr != 0)
- return -EINVAL;
- if (reg->reg < 0x1000 || reg->reg > 0x11ff)
- return -EINVAL;
- reg_w1(gspca_dev, reg->reg, reg->val);
- return gspca_dev->usb_err;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- if (reg->match.addr != sd->i2c_addr)
- return -EINVAL;
- if (sd->sensor >= SENSOR_MT9V011 &&
- sd->sensor <= SENSOR_MT9M112) {
- i2c_w2(gspca_dev, reg->reg, reg->val);
- } else {
- i2c_w1(gspca_dev, reg->reg, reg->val);
- }
- return gspca_dev->usb_err;
- }
- return -EINVAL;
-}
-#endif
-
-static int sd_chip_ident(struct gspca_dev *gspca_dev,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (chip->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- if (chip->match.addr != 0)
- return -EINVAL;
- chip->revision = 0;
- chip->ident = V4L2_IDENT_SN9C20X;
- return 0;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- if (chip->match.addr != sd->i2c_addr)
- return -EINVAL;
- chip->revision = 0;
- chip->ident = i2c_ident[sd->sensor];
- return 0;
- }
- return -EINVAL;
-}
-
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
-
- cam = &gspca_dev->cam;
- cam->needs_full_bandwidth = 1;
-
- sd->sensor = id->driver_info >> 8;
- sd->i2c_addr = id->driver_info;
- sd->flags = id->driver_info >> 16;
- sd->i2c_intf = 0x80; /* i2c 100 Kb/s */
-
- switch (sd->sensor) {
- case SENSOR_MT9M112:
- case SENSOR_MT9M111:
- case SENSOR_OV9650:
- case SENSOR_SOI968:
- cam->cam_mode = sxga_mode;
- cam->nmodes = ARRAY_SIZE(sxga_mode);
- break;
- case SENSOR_MT9M001:
- cam->cam_mode = mono_mode;
- cam->nmodes = ARRAY_SIZE(mono_mode);
- break;
- case SENSOR_HV7131R:
- sd->i2c_intf = 0x81; /* i2c 400 Kb/s */
- /* fall thru */
- default:
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- break;
- }
-
- sd->old_step = 0;
- sd->older_step = 0;
- sd->exposure_step = 16;
-
- INIT_WORK(&sd->work, qual_upd);
-
- return 0;
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- /* color control cluster */
- case V4L2_CID_BRIGHTNESS:
- set_cmatrix(gspca_dev, sd->brightness->val,
- sd->contrast->val, sd->saturation->val, sd->hue->val);
- break;
- case V4L2_CID_GAMMA:
- set_gamma(gspca_dev, ctrl->val);
- break;
- /* blue/red balance cluster */
- case V4L2_CID_BLUE_BALANCE:
- set_redblue(gspca_dev, sd->blue->val, sd->red->val);
- break;
- /* h/vflip cluster */
- case V4L2_CID_HFLIP:
- set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val);
- break;
- /* standalone exposure control */
- case V4L2_CID_EXPOSURE:
- set_exposure(gspca_dev, ctrl->val);
- break;
- /* standalone gain control */
- case V4L2_CID_GAIN:
- set_gain(gspca_dev, ctrl->val);
- break;
- /* autogain + exposure or gain control cluster */
- case V4L2_CID_AUTOGAIN:
- if (sd->sensor == SENSOR_SOI968)
- set_gain(gspca_dev, sd->gain->val);
- else
- set_exposure(gspca_dev, sd->exposure->val);
- break;
- case V4L2_CID_JPEG_COMPRESSION_QUALITY:
- set_quality(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 13);
-
- sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
- sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 127);
- sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, 127);
- sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_HUE, -180, 180, 1, 0);
-
- sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAMMA, 0, 255, 1, 0x10);
-
- sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28);
- sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28);
-
- if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 &&
- sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 &&
- sd->sensor != SENSOR_MT9VPRB) {
- sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- }
-
- if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB &&
- sd->sensor != SENSOR_MT9M112 && sd->sensor != SENSOR_MT9M111 &&
- sd->sensor != SENSOR_MT9V111)
- sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 0x1780, 1, 0x33);
-
- if (sd->sensor != SENSOR_MT9VPRB && sd->sensor != SENSOR_MT9M112 &&
- sd->sensor != SENSOR_MT9M111 && sd->sensor != SENSOR_MT9V111) {
- sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 28, 1, 0);
- sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- }
-
- sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80);
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
-
- v4l2_ctrl_cluster(4, &sd->brightness);
- v4l2_ctrl_cluster(2, &sd->blue);
- if (sd->hflip)
- v4l2_ctrl_cluster(2, &sd->hflip);
- if (sd->autogain) {
- if (sd->sensor == SENSOR_SOI968)
- /* this sensor doesn't have the exposure control and
- autogain is clustered with gain instead. This works
- because sd->exposure == NULL. */
- v4l2_ctrl_auto_cluster(3, &sd->autogain, 0, false);
- else
- /* Otherwise autogain is clustered with exposure. */
- v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
- }
- return 0;
-}
-
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- u8 value;
- u8 i2c_init[9] =
- {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
-
- for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
- value = bridge_init[i][1];
- reg_w(gspca_dev, bridge_init[i][0], &value, 1);
- if (gspca_dev->usb_err < 0) {
- pr_err("Device initialization failed\n");
- return gspca_dev->usb_err;
- }
- }
-
- if (sd->flags & LED_REVERSE)
- reg_w1(gspca_dev, 0x1006, 0x00);
- else
- reg_w1(gspca_dev, 0x1006, 0x20);
-
- reg_w(gspca_dev, 0x10c0, i2c_init, 9);
- if (gspca_dev->usb_err < 0) {
- pr_err("Device initialization failed\n");
- return gspca_dev->usb_err;
- }
-
- switch (sd->sensor) {
- case SENSOR_OV9650:
- ov9650_init_sensor(gspca_dev);
- if (gspca_dev->usb_err < 0)
- break;
- pr_info("OV9650 sensor detected\n");
- break;
- case SENSOR_OV9655:
- ov9655_init_sensor(gspca_dev);
- if (gspca_dev->usb_err < 0)
- break;
- pr_info("OV9655 sensor detected\n");
- break;
- case SENSOR_SOI968:
- soi968_init_sensor(gspca_dev);
- if (gspca_dev->usb_err < 0)
- break;
- pr_info("SOI968 sensor detected\n");
- break;
- case SENSOR_OV7660:
- ov7660_init_sensor(gspca_dev);
- if (gspca_dev->usb_err < 0)
- break;
- pr_info("OV7660 sensor detected\n");
- break;
- case SENSOR_OV7670:
- ov7670_init_sensor(gspca_dev);
- if (gspca_dev->usb_err < 0)
- break;
- pr_info("OV7670 sensor detected\n");
- break;
- case SENSOR_MT9VPRB:
- mt9v_init_sensor(gspca_dev);
- if (gspca_dev->usb_err < 0)
- break;
- pr_info("MT9VPRB sensor detected\n");
- break;
- case SENSOR_MT9M111:
- mt9m111_init_sensor(gspca_dev);
- if (gspca_dev->usb_err < 0)
- break;
- pr_info("MT9M111 sensor detected\n");
- break;
- case SENSOR_MT9M112:
- mt9m112_init_sensor(gspca_dev);
- if (gspca_dev->usb_err < 0)
- break;
- pr_info("MT9M112 sensor detected\n");
- break;
- case SENSOR_MT9M001:
- mt9m001_init_sensor(gspca_dev);
- if (gspca_dev->usb_err < 0)
- break;
- break;
- case SENSOR_HV7131R:
- hv7131r_init_sensor(gspca_dev);
- if (gspca_dev->usb_err < 0)
- break;
- pr_info("HV7131R sensor detected\n");
- break;
- default:
- pr_err("Unsupported sensor\n");
- gspca_dev->usb_err = -ENODEV;
- }
- return gspca_dev->usb_err;
-}
-
-static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 value;
-
- switch (sd->sensor) {
- case SENSOR_SOI968:
- if (mode & MODE_SXGA) {
- i2c_w1(gspca_dev, 0x17, 0x1d);
- i2c_w1(gspca_dev, 0x18, 0xbd);
- i2c_w1(gspca_dev, 0x19, 0x01);
- i2c_w1(gspca_dev, 0x1a, 0x81);
- i2c_w1(gspca_dev, 0x12, 0x00);
- sd->hstart = 140;
- sd->vstart = 19;
- } else {
- i2c_w1(gspca_dev, 0x17, 0x13);
- i2c_w1(gspca_dev, 0x18, 0x63);
- i2c_w1(gspca_dev, 0x19, 0x01);
- i2c_w1(gspca_dev, 0x1a, 0x79);
- i2c_w1(gspca_dev, 0x12, 0x40);
- sd->hstart = 60;
- sd->vstart = 11;
- }
- break;
- case SENSOR_OV9650:
- if (mode & MODE_SXGA) {
- i2c_w1(gspca_dev, 0x17, 0x1b);
- i2c_w1(gspca_dev, 0x18, 0xbc);
- i2c_w1(gspca_dev, 0x19, 0x01);
- i2c_w1(gspca_dev, 0x1a, 0x82);
- i2c_r1(gspca_dev, 0x12, &value);
- i2c_w1(gspca_dev, 0x12, value & 0x07);
- } else {
- i2c_w1(gspca_dev, 0x17, 0x24);
- i2c_w1(gspca_dev, 0x18, 0xc5);
- i2c_w1(gspca_dev, 0x19, 0x00);
- i2c_w1(gspca_dev, 0x1a, 0x3c);
- i2c_r1(gspca_dev, 0x12, &value);
- i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
- }
- break;
- case SENSOR_MT9M112:
- case SENSOR_MT9M111:
- if (mode & MODE_SXGA) {
- i2c_w2(gspca_dev, 0xf0, 0x0002);
- i2c_w2(gspca_dev, 0xc8, 0x970b);
- i2c_w2(gspca_dev, 0xf0, 0x0000);
- } else {
- i2c_w2(gspca_dev, 0xf0, 0x0002);
- i2c_w2(gspca_dev, 0xc8, 0x8000);
- i2c_w2(gspca_dev, 0xf0, 0x0000);
- }
- break;
- }
-}
-
-static int sd_isoc_init(struct gspca_dev *gspca_dev)
-{
- struct usb_interface *intf;
- u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv;
-
- /*
- * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
- * than our regular bandwidth calculations reserve, so we force the
- * use of a specific altsetting when using the SN9C20X_I420 fmt.
- */
- if (!(flags & (MODE_RAW | MODE_JPEG))) {
- intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
-
- if (intf->num_altsetting != 9) {
- pr_warn("sn9c20x camera with unknown number of alt "
- "settings (%d), please report!\n",
- intf->num_altsetting);
- gspca_dev->alt = intf->num_altsetting;
- return 0;
- }
-
- switch (gspca_dev->width) {
- case 160: /* 160x120 */
- gspca_dev->alt = 2;
- break;
- case 320: /* 320x240 */
- gspca_dev->alt = 6;
- break;
- default: /* >= 640x480 */
- gspca_dev->alt = 9;
- break;
- }
- }
-
- return 0;
-}
-
-#define HW_WIN(mode, hstart, vstart) \
-((const u8 []){hstart, 0, vstart, 0, \
-(mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
-(mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
-
-#define CLR_WIN(width, height) \
-((const u8 [])\
-{0, width >> 2, 0, height >> 1,\
-((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
- int width = gspca_dev->width;
- int height = gspca_dev->height;
- u8 fmt, scale = 0;
-
- jpeg_define(sd->jpeg_hdr, height, width,
- 0x21);
- jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
-
- if (mode & MODE_RAW)
- fmt = 0x2d;
- else if (mode & MODE_JPEG)
- fmt = 0x24;
- else
- fmt = 0x2f; /* YUV 420 */
- sd->fmt = fmt;
-
- switch (mode & SCALE_MASK) {
- case SCALE_1280x1024:
- scale = 0xc0;
- pr_info("Set 1280x1024\n");
- break;
- case SCALE_640x480:
- scale = 0x80;
- pr_info("Set 640x480\n");
- break;
- case SCALE_320x240:
- scale = 0x90;
- pr_info("Set 320x240\n");
- break;
- case SCALE_160x120:
- scale = 0xa0;
- pr_info("Set 160x120\n");
- break;
- }
-
- configure_sensor_output(gspca_dev, mode);
- reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
- reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
- reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
- reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
- reg_w1(gspca_dev, 0x1189, scale);
- reg_w1(gspca_dev, 0x10e0, fmt);
-
- set_cmatrix(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness),
- v4l2_ctrl_g_ctrl(sd->contrast),
- v4l2_ctrl_g_ctrl(sd->saturation),
- v4l2_ctrl_g_ctrl(sd->hue));
- set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
- set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue),
- v4l2_ctrl_g_ctrl(sd->red));
- if (sd->gain)
- set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain));
- if (sd->exposure)
- set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
- if (sd->hflip)
- set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip),
- v4l2_ctrl_g_ctrl(sd->vflip));
-
- reg_w1(gspca_dev, 0x1007, 0x20);
- reg_w1(gspca_dev, 0x1061, 0x03);
-
- /* if JPEG, prepare the compression quality update */
- if (mode & MODE_JPEG) {
- sd->pktsz = sd->npkt = 0;
- sd->nchg = 0;
- sd->work_thread =
- create_singlethread_workqueue(KBUILD_MODNAME);
- }
-
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- reg_w1(gspca_dev, 0x1007, 0x00);
- reg_w1(gspca_dev, 0x1061, 0x01);
-}
-
-/* called on streamoff with alt==0 and on disconnect */
-/* the usb_lock is held at entry - restore on exit */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->work_thread != NULL) {
- mutex_unlock(&gspca_dev->usb_lock);
- destroy_workqueue(sd->work_thread);
- mutex_lock(&gspca_dev->usb_lock);
- sd->work_thread = NULL;
- }
-}
-
-static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 cur_exp = v4l2_ctrl_g_ctrl(sd->exposure);
- s32 max = sd->exposure->maximum - sd->exposure_step;
- s32 min = sd->exposure->minimum + sd->exposure_step;
- s16 new_exp;
-
- /*
- * some hardcoded values are present
- * like those for maximal/minimal exposure
- * and exposure steps
- */
- if (avg_lum < MIN_AVG_LUM) {
- if (cur_exp > max)
- return;
-
- new_exp = cur_exp + sd->exposure_step;
- if (new_exp > max)
- new_exp = max;
- if (new_exp < min)
- new_exp = min;
- v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
-
- sd->older_step = sd->old_step;
- sd->old_step = 1;
-
- if (sd->old_step ^ sd->older_step)
- sd->exposure_step /= 2;
- else
- sd->exposure_step += 2;
- }
- if (avg_lum > MAX_AVG_LUM) {
- if (cur_exp < min)
- return;
- new_exp = cur_exp - sd->exposure_step;
- if (new_exp > max)
- new_exp = max;
- if (new_exp < min)
- new_exp = min;
- v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
- sd->older_step = sd->old_step;
- sd->old_step = 0;
-
- if (sd->old_step ^ sd->older_step)
- sd->exposure_step /= 2;
- else
- sd->exposure_step += 2;
- }
-}
-
-static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain);
-
- if (avg_lum < MIN_AVG_LUM && cur_gain < sd->gain->maximum)
- v4l2_ctrl_s_ctrl(sd->gain, cur_gain + 1);
- if (avg_lum > MAX_AVG_LUM && cur_gain > sd->gain->minimum)
- v4l2_ctrl_s_ctrl(sd->gain, cur_gain - 1);
-}
-
-static void sd_dqcallback(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int avg_lum;
-
- if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain))
- return;
-
- avg_lum = atomic_read(&sd->avg_lum);
- if (sd->sensor == SENSOR_SOI968)
- do_autogain(gspca_dev, avg_lum);
- else
- do_autoexposure(gspca_dev, avg_lum);
-}
-
-/* JPEG quality update */
-/* This function is executed from a work queue. */
-static void qual_upd(struct work_struct *work)
-{
- struct sd *sd = container_of(work, struct sd, work);
- struct gspca_dev *gspca_dev = &sd->gspca_dev;
- s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual);
-
- mutex_lock(&gspca_dev->usb_lock);
- PDEBUG(D_STREAM, "qual_upd %d%%", qual);
- set_quality(gspca_dev, qual);
- mutex_unlock(&gspca_dev->usb_lock);
-}
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
-static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* interrupt packet */
- int len) /* interrupt packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
- input_sync(gspca_dev->input_dev);
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
- input_sync(gspca_dev->input_dev);
- return 0;
- }
- return -EINVAL;
-}
-#endif
-
-/* check the JPEG compression */
-static void transfer_check(struct gspca_dev *gspca_dev,
- u8 *data)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int new_qual, r;
-
- new_qual = 0;
-
- /* if USB error, discard the frame and decrease the quality */
- if (data[6] & 0x08) { /* USB FIFO full */
- gspca_dev->last_packet_type = DISCARD_PACKET;
- new_qual = -5;
- } else {
-
- /* else, compute the filling rate and a new JPEG quality */
- r = (sd->pktsz * 100) /
- (sd->npkt *
- gspca_dev->urb[0]->iso_frame_desc[0].length);
- if (r >= 85)
- new_qual = -3;
- else if (r < 75)
- new_qual = 2;
- }
- if (new_qual != 0) {
- sd->nchg += new_qual;
- if (sd->nchg < -6 || sd->nchg >= 12) {
- /* Note: we are in interrupt context, so we can't
- use v4l2_ctrl_g/s_ctrl here. Access the value
- directly instead. */
- s32 curqual = sd->jpegqual->cur.val;
- sd->nchg = 0;
- new_qual += curqual;
- if (new_qual < sd->jpegqual->minimum)
- new_qual = sd->jpegqual->minimum;
- else if (new_qual > sd->jpegqual->maximum)
- new_qual = sd->jpegqual->maximum;
- if (new_qual != curqual) {
- sd->jpegqual->cur.val = new_qual;
- queue_work(sd->work_thread, &sd->work);
- }
- }
- } else {
- sd->nchg = 0;
- }
- sd->pktsz = sd->npkt = 0;
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int avg_lum, is_jpeg;
- static const u8 frame_header[] =
- {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
-
- is_jpeg = (sd->fmt & 0x03) == 0;
- if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
- avg_lum = ((data[35] >> 2) & 3) |
- (data[20] << 2) |
- (data[19] << 10);
- avg_lum += ((data[35] >> 4) & 3) |
- (data[22] << 2) |
- (data[21] << 10);
- avg_lum += ((data[35] >> 6) & 3) |
- (data[24] << 2) |
- (data[23] << 10);
- avg_lum += (data[36] & 3) |
- (data[26] << 2) |
- (data[25] << 10);
- avg_lum += ((data[36] >> 2) & 3) |
- (data[28] << 2) |
- (data[27] << 10);
- avg_lum += ((data[36] >> 4) & 3) |
- (data[30] << 2) |
- (data[29] << 10);
- avg_lum += ((data[36] >> 6) & 3) |
- (data[32] << 2) |
- (data[31] << 10);
- avg_lum += ((data[44] >> 4) & 3) |
- (data[34] << 2) |
- (data[33] << 10);
- avg_lum >>= 9;
- atomic_set(&sd->avg_lum, avg_lum);
-
- if (is_jpeg)
- transfer_check(gspca_dev, data);
-
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
- len -= 64;
- if (len == 0)
- return;
- data += 64;
- }
- if (gspca_dev->last_packet_type == LAST_PACKET) {
- if (is_jpeg) {
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sd->jpeg_hdr, JPEG_HDR_SZ);
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data, len);
- } else {
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- data, len);
- }
- } else {
- /* if JPEG, count the packets and their size */
- if (is_jpeg) {
- sd->npkt++;
- sd->pktsz += len;
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
- }
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = KBUILD_MODNAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .isoc_init = sd_isoc_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .int_pkt_scan = sd_int_pkt_scan,
-#endif
- .dq_callback = sd_dqcallback,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .set_register = sd_dbg_s_register,
- .get_register = sd_dbg_g_register,
-#endif
- .get_chip_ident = sd_chip_ident,
-};
-
-#define SN9C20X(sensor, i2c_addr, flags) \
- .driver_info = ((flags & 0xff) << 16) \
- | (SENSOR_ ## sensor << 8) \
- | (i2c_addr)
-
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
- {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
- {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
- {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
- {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
- {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
- (FLIP_DETECT | HAS_NO_BUTTON))},
- {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
- {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
- {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
- {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
- {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
- {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
- {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
- {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
- {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
- {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
- {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
- {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
- {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
- {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
- {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
- {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
- {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
- {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
- {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
- {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
- {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
- {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
- {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
- {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
- {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
- {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
- {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
- {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
- {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
- {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = KBUILD_MODNAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
deleted file mode 100644
index fd1f8d2d3b0..00000000000
--- a/drivers/media/video/gspca/sonixb.c
+++ /dev/null
@@ -1,1493 +0,0 @@
-/*
- * sonix sn9c102 (bayer) library
- *
- * Copyright (C) 2009-2011 Jean-François Moine <http://moinejf.free.fr>
- * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr
- * Add Pas106 Stefano Mozzi (C) 2004
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* Some documentation on known sonixb registers:
-
-Reg Use
-sn9c101 / sn9c102:
-0x10 high nibble red gain low nibble blue gain
-0x11 low nibble green gain
-sn9c103:
-0x05 red gain 0-127
-0x06 blue gain 0-127
-0x07 green gain 0-127
-all:
-0x08-0x0f i2c / 3wire registers
-0x12 hstart
-0x13 vstart
-0x15 hsize (hsize = register-value * 16)
-0x16 vsize (vsize = register-value * 16)
-0x17 bit 0 toggle compression quality (according to sn9c102 driver)
-0x18 bit 7 enables compression, bit 4-5 set image down scaling:
- 00 scale 1, 01 scale 1/2, 10, scale 1/4
-0x19 high-nibble is sensor clock divider, changes exposure on sensors which
- use a clock generated by the bridge. Some sensors have their own clock.
-0x1c auto_exposure area (for avg_lum) startx (startx = register-value * 32)
-0x1d auto_exposure area (for avg_lum) starty (starty = register-value * 32)
-0x1e auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32)
-0x1f auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32)
-*/
-
-#define MODULE_NAME "sonixb"
-
-#include <linux/input.h>
-#include "gspca.h"
-
-MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
-MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- struct v4l2_ctrl *brightness;
- struct v4l2_ctrl *plfreq;
-
- atomic_t avg_lum;
- int prev_avg_lum;
- int exposure_knee;
- int header_read;
- u8 header[12]; /* Header without sof marker */
-
- unsigned char autogain_ignore_frames;
- unsigned char frames_to_drop;
-
- __u8 bridge; /* Type of bridge */
-#define BRIDGE_101 0
-#define BRIDGE_102 0 /* We make no difference between 101 and 102 */
-#define BRIDGE_103 1
-
- __u8 sensor; /* Type of image sensor chip */
-#define SENSOR_HV7131D 0
-#define SENSOR_HV7131R 1
-#define SENSOR_OV6650 2
-#define SENSOR_OV7630 3
-#define SENSOR_PAS106 4
-#define SENSOR_PAS202 5
-#define SENSOR_TAS5110C 6
-#define SENSOR_TAS5110D 7
-#define SENSOR_TAS5130CXX 8
- __u8 reg11;
-};
-
-typedef const __u8 sensor_init_t[8];
-
-struct sensor_data {
- const __u8 *bridge_init;
- sensor_init_t *sensor_init;
- int sensor_init_size;
- int flags;
- __u8 sensor_addr;
-};
-
-/* sensor_data flags */
-#define F_SIF 0x01 /* sif or vga */
-
-/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
-#define MODE_RAW 0x10 /* raw bayer mode */
-#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
-
-#define COMP 0xc7 /* 0x87 //0x07 */
-#define COMP1 0xc9 /* 0x89 //0x09 */
-
-#define MCK_INIT 0x63
-#define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/
-
-#define SYS_CLK 0x04
-
-#define SENS(bridge, sensor, _flags, _sensor_addr) \
-{ \
- .bridge_init = bridge, \
- .sensor_init = sensor, \
- .sensor_init_size = sizeof(sensor), \
- .flags = _flags, .sensor_addr = _sensor_addr \
-}
-
-/* We calculate the autogain at the end of the transfer of a frame, at this
- moment a frame with the old settings is being captured and transmitted. So
- if we adjust the gain or exposure we must ignore atleast the next frame for
- the new settings to come into effect before doing any other adjustments. */
-#define AUTOGAIN_IGNORE_FRAMES 1
-
-static const struct v4l2_pix_format vga_mode[] = {
- {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2 | MODE_RAW},
- {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 5 / 4,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
- {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 5 / 4,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 5 / 4,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-static const struct v4l2_pix_format sif_mode[] = {
- {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
- {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 5 / 4,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1 | MODE_REDUCED_SIF},
- {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1 | MODE_RAW},
- {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 5 / 4,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 5 / 4,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0 | MODE_REDUCED_SIF},
- {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 5 / 4,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-static const __u8 initHv7131d[] = {
- 0x04, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
- 0x28, 0x1e, 0x60, 0x8e, 0x42,
-};
-static const __u8 hv7131d_sensor_init[][8] = {
- {0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17},
- {0xa0, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x17},
- {0xa0, 0x11, 0x28, 0x00, 0x00, 0x00, 0x00, 0x17},
- {0xa0, 0x11, 0x30, 0x30, 0x00, 0x00, 0x00, 0x17}, /* reset level */
- {0xa0, 0x11, 0x34, 0x02, 0x00, 0x00, 0x00, 0x17}, /* pixel bias volt */
-};
-
-static const __u8 initHv7131r[] = {
- 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
- 0x28, 0x1e, 0x60, 0x8a, 0x20,
-};
-static const __u8 hv7131r_sensor_init[][8] = {
- {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
- {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
- {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
- {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
- {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
-};
-static const __u8 initOv6650[] = {
- 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
- 0x10,
-};
-static const __u8 ov6650_sensor_init[][8] = {
- /* Bright, contrast, etc are set through SCBB interface.
- * AVCAP on win2 do not send any data on this controls. */
- /* Anyway, some registers appears to alter bright and constrat */
-
- /* Reset sensor */
- {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
- /* Set clock register 0x11 low nibble is clock divider */
- {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
- /* Next some unknown stuff */
- {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
-/* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
- * THIS SET GREEN SCREEN
- * (pixels could be innverted in decode kind of "brg",
- * but blue wont be there. Avoid this data ... */
- {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
- {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
- {0xa0, 0x60, 0x30, 0x3d, 0x0a, 0xd8, 0xa4, 0x10},
- /* Enable rgb brightness control */
- {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
- /* HDG: Note windows uses the line below, which sets both register 0x60
- and 0x61 I believe these registers of the ov6650 are identical as
- those of the ov7630, because if this is true the windows settings
- add a bit additional red gain and a lot additional blue gain, which
- matches my findings that the windows settings make blue much too
- blue and red a little too red.
- {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
- /* Some more unknown stuff */
- {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
- {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
-};
-
-static const __u8 initOv7630[] = {
- 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
- 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
- 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
- 0x28, 0x1e, /* H & V sizes r15 .. r16 */
- 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
-};
-static const __u8 ov7630_sensor_init[][8] = {
- {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
- {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
-/* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
- {0xd0, 0x21, 0x12, 0x5c, 0x00, 0x80, 0x34, 0x10}, /* jfm */
- {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
- {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
- {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
- {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
- {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
- {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
- {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
- {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
-/* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */
- {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
- {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
- {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
- {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
- {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
- {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
-};
-
-static const __u8 initPas106[] = {
- 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
- 0x16, 0x12, 0x24, COMP1, MCK_INIT1,
-};
-/* compression 0x86 mckinit1 0x2b */
-
-/* "Known" PAS106B registers:
- 0x02 clock divider
- 0x03 Variable framerate bits 4-11
- 0x04 Var framerate bits 0-3, one must leave the 4 msb's at 0 !!
- The variable framerate control must never be set lower then 300,
- which sets the framerate at 90 / reg02, otherwise vsync is lost.
- 0x05 Shutter Time Line Offset, this can be used as an exposure control:
- 0 = use full frame time, 255 = no exposure at all
- Note this may never be larger then "var-framerate control" / 2 - 2.
- When var-framerate control is < 514, no exposure is reached at the max
- allowed value for the framerate control value, rather then at 255.
- 0x06 Shutter Time Pixel Offset, like reg05 this influences exposure, but
- only a very little bit, leave at 0xcd
- 0x07 offset sign bit (bit0 1 > negative offset)
- 0x08 offset
- 0x09 Blue Gain
- 0x0a Green1 Gain
- 0x0b Green2 Gain
- 0x0c Red Gain
- 0x0e Global gain
- 0x13 Write 1 to commit settings to sensor
-*/
-
-static const __u8 pas106_sensor_init[][8] = {
- /* Pixel Clock Divider 6 */
- { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
- /* Frame Time MSB (also seen as 0x12) */
- { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
- /* Frame Time LSB (also seen as 0x05) */
- { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
- /* Shutter Time Line Offset (also seen as 0x6d) */
- { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
- /* Shutter Time Pixel Offset (also seen as 0xb1) */
- { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
- /* Black Level Subtract Sign (also seen 0x00) */
- { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
- /* Black Level Subtract Level (also seen 0x01) */
- { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
- { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
- /* Color Gain B Pixel 5 a */
- { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
- /* Color Gain G1 Pixel 1 5 */
- { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
- /* Color Gain G2 Pixel 1 0 5 */
- { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
- /* Color Gain R Pixel 3 1 */
- { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
- /* Color GainH Pixel */
- { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
- /* Global Gain */
- { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
- /* Contrast */
- { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
- /* H&V synchro polarity */
- { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
- /* ?default */
- { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
- /* DAC scale */
- { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
- /* ?default */
- { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
- /* Validate Settings */
- { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
-};
-
-static const __u8 initPas202[] = {
- 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
- 0x28, 0x1e, 0x20, 0x89, 0x20,
-};
-
-/* "Known" PAS202BCB registers:
- 0x02 clock divider
- 0x04 Variable framerate bits 6-11 (*)
- 0x05 Var framerate bits 0-5, one must leave the 2 msb's at 0 !!
- 0x07 Blue Gain
- 0x08 Green Gain
- 0x09 Red Gain
- 0x0b offset sign bit (bit0 1 > negative offset)
- 0x0c offset
- 0x0e Unknown image is slightly brighter when bit 0 is 0, if reg0f is 0 too,
- leave at 1 otherwise we get a jump in our exposure control
- 0x0f Exposure 0-255, 0 = use full frame time, 255 = no exposure at all
- 0x10 Master gain 0 - 31
- 0x11 write 1 to apply changes
- (*) The variable framerate control must never be set lower then 500
- which sets the framerate at 30 / reg02, otherwise vsync is lost.
-*/
-static const __u8 pas202_sensor_init[][8] = {
- /* Set the clock divider to 4 -> 30 / 4 = 7.5 fps, we would like
- to set it lower, but for some reason the bridge starts missing
- vsync's then */
- {0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10},
- {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
- {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
- {0xd0, 0x40, 0x0c, 0x00, 0x0c, 0x01, 0x32, 0x10},
- {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
- {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
- {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
- {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
- {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
- {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
-};
-
-static const __u8 initTas5110c[] = {
- 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
- 0x16, 0x12, 0x60, 0x86, 0x2b,
-};
-/* Same as above, except a different hstart */
-static const __u8 initTas5110d[] = {
- 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
- 0x16, 0x12, 0x60, 0x86, 0x2b,
-};
-/* tas5110c is 3 wire, tas5110d is 2 wire (regular i2c) */
-static const __u8 tas5110c_sensor_init[][8] = {
- {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
- {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
-};
-/* Known TAS5110D registers
- * reg02: gain, bit order reversed!! 0 == max gain, 255 == min gain
- * reg03: bit3: vflip, bit4: ~hflip, bit7: ~gainboost (~ == inverted)
- * Note: writing reg03 seems to only work when written together with 02
- */
-static const __u8 tas5110d_sensor_init[][8] = {
- {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17}, /* reset */
-};
-
-static const __u8 initTas5130[] = {
- 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
- 0x28, 0x1e, 0x60, COMP, MCK_INIT,
-};
-static const __u8 tas5130_sensor_init[][8] = {
-/* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
- * shutter 0x47 short exposure? */
- {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
- /* shutter 0x01 long exposure */
- {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
-};
-
-static const struct sensor_data sensor_data[] = {
- SENS(initHv7131d, hv7131d_sensor_init, 0, 0),
- SENS(initHv7131r, hv7131r_sensor_init, 0, 0),
- SENS(initOv6650, ov6650_sensor_init, F_SIF, 0x60),
- SENS(initOv7630, ov7630_sensor_init, 0, 0x21),
- SENS(initPas106, pas106_sensor_init, F_SIF, 0),
- SENS(initPas202, pas202_sensor_init, 0, 0),
- SENS(initTas5110c, tas5110c_sensor_init, F_SIF, 0),
- SENS(initTas5110d, tas5110d_sensor_init, F_SIF, 0),
- SENS(initTas5130, tas5130_sensor_init, 0, 0),
-};
-
-/* get one byte in gspca_dev->usb_buf */
-static void reg_r(struct gspca_dev *gspca_dev,
- __u16 value)
-{
- int res;
-
- if (gspca_dev->usb_err < 0)
- return;
-
- res = usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- 0, /* request */
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- value,
- 0, /* index */
- gspca_dev->usb_buf, 1,
- 500);
-
- if (res < 0) {
- dev_err(gspca_dev->v4l2_dev.dev,
- "Error reading register %02x: %d\n", value, res);
- gspca_dev->usb_err = res;
- }
-}
-
-static void reg_w(struct gspca_dev *gspca_dev,
- __u16 value,
- const __u8 *buffer,
- int len)
-{
- int res;
-
- if (gspca_dev->usb_err < 0)
- return;
-
- memcpy(gspca_dev->usb_buf, buffer, len);
- res = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x08, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- value,
- 0, /* index */
- gspca_dev->usb_buf, len,
- 500);
-
- if (res < 0) {
- dev_err(gspca_dev->v4l2_dev.dev,
- "Error writing register %02x: %d\n", value, res);
- gspca_dev->usb_err = res;
- }
-}
-
-static void i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
-{
- int retry = 60;
-
- if (gspca_dev->usb_err < 0)
- return;
-
- /* is i2c ready */
- reg_w(gspca_dev, 0x08, buffer, 8);
- while (retry--) {
- if (gspca_dev->usb_err < 0)
- return;
- msleep(10);
- reg_r(gspca_dev, 0x08);
- if (gspca_dev->usb_buf[0] & 0x04) {
- if (gspca_dev->usb_buf[0] & 0x08) {
- dev_err(gspca_dev->v4l2_dev.dev,
- "i2c write error\n");
- gspca_dev->usb_err = -EIO;
- }
- return;
- }
- }
-
- dev_err(gspca_dev->v4l2_dev.dev, "i2c write timeout\n");
- gspca_dev->usb_err = -EIO;
-}
-
-static void i2c_w_vector(struct gspca_dev *gspca_dev,
- const __u8 buffer[][8], int len)
-{
- for (;;) {
- if (gspca_dev->usb_err < 0)
- return;
- reg_w(gspca_dev, 0x08, *buffer, 8);
- len -= 8;
- if (len <= 0)
- break;
- buffer++;
- }
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->sensor) {
- case SENSOR_OV6650:
- case SENSOR_OV7630: {
- __u8 i2cOV[] =
- {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
-
- /* change reg 0x06 */
- i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
- i2cOV[3] = sd->brightness->val;
- i2c_w(gspca_dev, i2cOV);
- break;
- }
- case SENSOR_PAS106:
- case SENSOR_PAS202: {
- __u8 i2cpbright[] =
- {0xb0, 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x16};
- __u8 i2cpdoit[] =
- {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
-
- /* PAS106 uses reg 7 and 8 instead of b and c */
- if (sd->sensor == SENSOR_PAS106) {
- i2cpbright[2] = 7;
- i2cpdoit[2] = 0x13;
- }
-
- if (sd->brightness->val < 127) {
- /* change reg 0x0b, signreg */
- i2cpbright[3] = 0x01;
- /* set reg 0x0c, offset */
- i2cpbright[4] = 127 - sd->brightness->val;
- } else
- i2cpbright[4] = sd->brightness->val - 127;
-
- i2c_w(gspca_dev, i2cpbright);
- i2c_w(gspca_dev, i2cpdoit);
- break;
- }
- default:
- break;
- }
-}
-
-static void setgain(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 gain = gspca_dev->gain->val;
-
- switch (sd->sensor) {
- case SENSOR_HV7131D: {
- __u8 i2c[] =
- {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17};
-
- i2c[3] = 0x3f - gain;
- i2c[4] = 0x3f - gain;
- i2c[5] = 0x3f - gain;
-
- i2c_w(gspca_dev, i2c);
- break;
- }
- case SENSOR_TAS5110C:
- case SENSOR_TAS5130CXX: {
- __u8 i2c[] =
- {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
-
- i2c[4] = 255 - gain;
- i2c_w(gspca_dev, i2c);
- break;
- }
- case SENSOR_TAS5110D: {
- __u8 i2c[] = {
- 0xb0, 0x61, 0x02, 0x00, 0x10, 0x00, 0x00, 0x17 };
- gain = 255 - gain;
- /* The bits in the register are the wrong way around!! */
- i2c[3] |= (gain & 0x80) >> 7;
- i2c[3] |= (gain & 0x40) >> 5;
- i2c[3] |= (gain & 0x20) >> 3;
- i2c[3] |= (gain & 0x10) >> 1;
- i2c[3] |= (gain & 0x08) << 1;
- i2c[3] |= (gain & 0x04) << 3;
- i2c[3] |= (gain & 0x02) << 5;
- i2c[3] |= (gain & 0x01) << 7;
- i2c_w(gspca_dev, i2c);
- break;
- }
- case SENSOR_OV6650:
- case SENSOR_OV7630: {
- __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
-
- /*
- * The ov7630's gain is weird, at 32 the gain drops to the
- * same level as at 16, so skip 32-47 (of the 0-63 scale).
- */
- if (sd->sensor == SENSOR_OV7630 && gain >= 32)
- gain += 16;
-
- i2c[1] = sensor_data[sd->sensor].sensor_addr;
- i2c[3] = gain;
- i2c_w(gspca_dev, i2c);
- break;
- }
- case SENSOR_PAS106:
- case SENSOR_PAS202: {
- __u8 i2cpgain[] =
- {0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15};
- __u8 i2cpcolorgain[] =
- {0xc0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x15};
- __u8 i2cpdoit[] =
- {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
-
- /* PAS106 uses different regs (and has split green gains) */
- if (sd->sensor == SENSOR_PAS106) {
- i2cpgain[2] = 0x0e;
- i2cpcolorgain[0] = 0xd0;
- i2cpcolorgain[2] = 0x09;
- i2cpdoit[2] = 0x13;
- }
-
- i2cpgain[3] = gain;
- i2cpcolorgain[3] = gain >> 1;
- i2cpcolorgain[4] = gain >> 1;
- i2cpcolorgain[5] = gain >> 1;
- i2cpcolorgain[6] = gain >> 1;
-
- i2c_w(gspca_dev, i2cpgain);
- i2c_w(gspca_dev, i2cpcolorgain);
- i2c_w(gspca_dev, i2cpdoit);
- break;
- }
- default:
- if (sd->bridge == BRIDGE_103) {
- u8 buf[3] = { gain, gain, gain }; /* R, G, B */
- reg_w(gspca_dev, 0x05, buf, 3);
- } else {
- u8 buf[2];
- buf[0] = gain << 4 | gain; /* Red and blue */
- buf[1] = gain; /* Green */
- reg_w(gspca_dev, 0x10, buf, 2);
- }
- }
-}
-
-static void setexposure(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->sensor) {
- case SENSOR_HV7131D: {
- /* Note the datasheet wrongly says line mode exposure uses reg
- 0x26 and 0x27, testing has shown 0x25 + 0x26 */
- __u8 i2c[] = {0xc0, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x17};
- u16 reg = gspca_dev->exposure->val;
-
- i2c[3] = reg >> 8;
- i2c[4] = reg & 0xff;
- i2c_w(gspca_dev, i2c);
- break;
- }
- case SENSOR_TAS5110C:
- case SENSOR_TAS5110D: {
- /* register 19's high nibble contains the sn9c10x clock divider
- The high nibble configures the no fps according to the
- formula: 60 / high_nibble. With a maximum of 30 fps */
- u8 reg = gspca_dev->exposure->val;
-
- reg = (reg << 4) | 0x0b;
- reg_w(gspca_dev, 0x19, &reg, 1);
- break;
- }
- case SENSOR_OV6650:
- case SENSOR_OV7630: {
- /* The ov6650 / ov7630 have 2 registers which both influence
- exposure, register 11, whose low nibble sets the nr off fps
- according to: fps = 30 / (low_nibble + 1)
-
- The fps configures the maximum exposure setting, but it is
- possible to use less exposure then what the fps maximum
- allows by setting register 10. register 10 configures the
- actual exposure as quotient of the full exposure, with 0
- being no exposure at all (not very useful) and reg10_max
- being max exposure possible at that framerate.
-
- The code maps our 0 - 510 ms exposure ctrl to these 2
- registers, trying to keep fps as high as possible.
- */
- __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
- int reg10, reg11, reg10_max;
-
- /* ov6645 datasheet says reg10_max is 9a, but that uses
- tline * 2 * reg10 as formula for calculating texpo, the
- ov6650 probably uses the same formula as the 7730 which uses
- tline * 4 * reg10, which explains why the reg10max we've
- found experimentally for the ov6650 is exactly half that of
- the ov6645. The ov7630 datasheet says the max is 0x41. */
- if (sd->sensor == SENSOR_OV6650) {
- reg10_max = 0x4d;
- i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
- } else
- reg10_max = 0x41;
-
- reg11 = (15 * gspca_dev->exposure->val + 999) / 1000;
- if (reg11 < 1)
- reg11 = 1;
- else if (reg11 > 16)
- reg11 = 16;
-
- /* In 640x480, if the reg11 has less than 4, the image is
- unstable (the bridge goes into a higher compression mode
- which we have not reverse engineered yet). */
- if (gspca_dev->width == 640 && reg11 < 4)
- reg11 = 4;
-
- /* frame exposure time in ms = 1000 * reg11 / 30 ->
- reg10 = (gspca_dev->exposure->val / 2) * reg10_max
- / (1000 * reg11 / 30) */
- reg10 = (gspca_dev->exposure->val * 15 * reg10_max)
- / (1000 * reg11);
-
- /* Don't allow this to get below 10 when using autogain, the
- steps become very large (relatively) when below 10 causing
- the image to oscilate from much too dark, to much too bright
- and back again. */
- if (gspca_dev->autogain->val && reg10 < 10)
- reg10 = 10;
- else if (reg10 > reg10_max)
- reg10 = reg10_max;
-
- /* Write reg 10 and reg11 low nibble */
- i2c[1] = sensor_data[sd->sensor].sensor_addr;
- i2c[3] = reg10;
- i2c[4] |= reg11 - 1;
-
- /* If register 11 didn't change, don't change it */
- if (sd->reg11 == reg11)
- i2c[0] = 0xa0;
-
- i2c_w(gspca_dev, i2c);
- if (gspca_dev->usb_err == 0)
- sd->reg11 = reg11;
- break;
- }
- case SENSOR_PAS202: {
- __u8 i2cpframerate[] =
- {0xb0, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x16};
- __u8 i2cpexpo[] =
- {0xa0, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x16};
- const __u8 i2cpdoit[] =
- {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
- int framerate_ctrl;
-
- /* The exposure knee for the autogain algorithm is 200
- (100 ms / 10 fps on other sensors), for values below this
- use the control for setting the partial frame expose time,
- above that use variable framerate. This way we run at max
- framerate (640x480@7.5 fps, 320x240@10fps) until the knee
- is reached. Using the variable framerate control above 200
- is better then playing around with both clockdiv + partial
- frame exposure times (like we are doing with the ov chips),
- as that sometimes leads to jumps in the exposure control,
- which are bad for auto exposure. */
- if (gspca_dev->exposure->val < 200) {
- i2cpexpo[3] = 255 - (gspca_dev->exposure->val * 255)
- / 200;
- framerate_ctrl = 500;
- } else {
- /* The PAS202's exposure control goes from 0 - 4095,
- but anything below 500 causes vsync issues, so scale
- our 200-1023 to 500-4095 */
- framerate_ctrl = (gspca_dev->exposure->val - 200)
- * 1000 / 229 + 500;
- }
-
- i2cpframerate[3] = framerate_ctrl >> 6;
- i2cpframerate[4] = framerate_ctrl & 0x3f;
- i2c_w(gspca_dev, i2cpframerate);
- i2c_w(gspca_dev, i2cpexpo);
- i2c_w(gspca_dev, i2cpdoit);
- break;
- }
- case SENSOR_PAS106: {
- __u8 i2cpframerate[] =
- {0xb1, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14};
- __u8 i2cpexpo[] =
- {0xa1, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x14};
- const __u8 i2cpdoit[] =
- {0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14};
- int framerate_ctrl;
-
- /* For values below 150 use partial frame exposure, above
- that use framerate ctrl */
- if (gspca_dev->exposure->val < 150) {
- i2cpexpo[3] = 150 - gspca_dev->exposure->val;
- framerate_ctrl = 300;
- } else {
- /* The PAS106's exposure control goes from 0 - 4095,
- but anything below 300 causes vsync issues, so scale
- our 150-1023 to 300-4095 */
- framerate_ctrl = (gspca_dev->exposure->val - 150)
- * 1000 / 230 + 300;
- }
-
- i2cpframerate[3] = framerate_ctrl >> 4;
- i2cpframerate[4] = framerate_ctrl & 0x0f;
- i2c_w(gspca_dev, i2cpframerate);
- i2c_w(gspca_dev, i2cpexpo);
- i2c_w(gspca_dev, i2cpdoit);
- break;
- }
- default:
- break;
- }
-}
-
-static void setfreq(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630) {
- /* Framerate adjust register for artificial light 50 hz flicker
- compensation, for the ov6650 this is identical to ov6630
- 0x2b register, see ov6630 datasheet.
- 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
- __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
- switch (sd->plfreq->val) {
- default:
-/* case 0: * no filter*/
-/* case 2: * 60 hz */
- i2c[3] = 0;
- break;
- case 1: /* 50 hz */
- i2c[3] = (sd->sensor == SENSOR_OV6650)
- ? 0x4f : 0x8a;
- break;
- }
- i2c[1] = sensor_data[sd->sensor].sensor_addr;
- i2c_w(gspca_dev, i2c);
- }
-}
-
-static void do_autogain(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int deadzone, desired_avg_lum, avg_lum;
-
- avg_lum = atomic_read(&sd->avg_lum);
- if (avg_lum == -1)
- return;
-
- if (sd->autogain_ignore_frames > 0) {
- sd->autogain_ignore_frames--;
- return;
- }
-
- /* SIF / VGA sensors have a different autoexposure area and thus
- different avg_lum values for the same picture brightness */
- if (sensor_data[sd->sensor].flags & F_SIF) {
- deadzone = 500;
- /* SIF sensors tend to overexpose, so keep this small */
- desired_avg_lum = 5000;
- } else {
- deadzone = 1500;
- desired_avg_lum = 13000;
- }
-
- if (sd->brightness)
- desired_avg_lum = sd->brightness->val * desired_avg_lum / 127;
-
- if (gspca_dev->exposure->maximum < 500) {
- if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
- desired_avg_lum, deadzone))
- sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
- } else {
- int gain_knee = gspca_dev->gain->maximum * 9 / 10;
- if (gspca_expo_autogain(gspca_dev, avg_lum, desired_avg_lum,
- deadzone, gain_knee, sd->exposure_knee))
- sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
- }
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
-
- reg_r(gspca_dev, 0x00);
- if (gspca_dev->usb_buf[0] != 0x10)
- return -ENODEV;
-
- /* copy the webcam info from the device id */
- sd->sensor = id->driver_info >> 8;
- sd->bridge = id->driver_info & 0xff;
-
- cam = &gspca_dev->cam;
- if (!(sensor_data[sd->sensor].flags & F_SIF)) {
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- } else {
- cam->cam_mode = sif_mode;
- cam->nmodes = ARRAY_SIZE(sif_mode);
- }
- cam->npkt = 36; /* 36 packets per ISOC message */
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- const __u8 stop = 0x09; /* Disable stream turn of LED */
-
- reg_w(gspca_dev, 0x01, &stop, 1);
-
- return gspca_dev->usb_err;
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
- /* when switching to autogain set defaults to make sure
- we are on a valid point of the autogain gain /
- exposure knee graph, and give this change time to
- take effect before doing autogain. */
- gspca_dev->gain->val = gspca_dev->gain->default_value;
- gspca_dev->exposure->val = gspca_dev->exposure->default_value;
- sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
- }
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev);
- break;
- case V4L2_CID_AUTOGAIN:
- if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
- setexposure(gspca_dev);
- if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
- setgain(gspca_dev);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY:
- setfreq(gspca_dev);
- break;
- default:
- return -EINVAL;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-/* this function is called at probe time */
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 5);
-
- if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630 ||
- sd->sensor == SENSOR_PAS106 || sd->sensor == SENSOR_PAS202)
- sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
-
- /* Gain range is sensor dependent */
- switch (sd->sensor) {
- case SENSOR_OV6650:
- case SENSOR_PAS106:
- case SENSOR_PAS202:
- gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 31, 1, 15);
- break;
- case SENSOR_OV7630:
- gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 47, 1, 31);
- break;
- case SENSOR_HV7131D:
- gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 63, 1, 31);
- break;
- case SENSOR_TAS5110C:
- case SENSOR_TAS5110D:
- case SENSOR_TAS5130CXX:
- gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 255, 1, 127);
- break;
- default:
- if (sd->bridge == BRIDGE_103) {
- gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 127, 1, 63);
- } else {
- gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 15, 1, 7);
- }
- }
-
- /* Exposure range is sensor dependent, and not all have exposure */
- switch (sd->sensor) {
- case SENSOR_HV7131D:
- gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 8191, 1, 482);
- sd->exposure_knee = 964;
- break;
- case SENSOR_OV6650:
- case SENSOR_OV7630:
- case SENSOR_PAS106:
- case SENSOR_PAS202:
- gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 1023, 1, 66);
- sd->exposure_knee = 200;
- break;
- case SENSOR_TAS5110C:
- case SENSOR_TAS5110D:
- gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 2, 15, 1, 2);
- break;
- }
-
- if (gspca_dev->exposure) {
- gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- }
-
- if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630)
- sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
- V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
- V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
-
- if (gspca_dev->autogain)
- v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
-
- return 0;
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam = &gspca_dev->cam;
- int i, mode;
- __u8 regs[0x31];
-
- mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
- /* Copy registers 0x01 - 0x19 from the template */
- memcpy(&regs[0x01], sensor_data[sd->sensor].bridge_init, 0x19);
- /* Set the mode */
- regs[0x18] |= mode << 4;
-
- /* Set bridge gain to 1.0 */
- if (sd->bridge == BRIDGE_103) {
- regs[0x05] = 0x20; /* Red */
- regs[0x06] = 0x20; /* Green */
- regs[0x07] = 0x20; /* Blue */
- } else {
- regs[0x10] = 0x00; /* Red and blue */
- regs[0x11] = 0x00; /* Green */
- }
-
- /* Setup pixel numbers and auto exposure window */
- if (sensor_data[sd->sensor].flags & F_SIF) {
- regs[0x1a] = 0x14; /* HO_SIZE 640, makes no sense */
- regs[0x1b] = 0x0a; /* VO_SIZE 320, makes no sense */
- regs[0x1c] = 0x02; /* AE H-start 64 */
- regs[0x1d] = 0x02; /* AE V-start 64 */
- regs[0x1e] = 0x09; /* AE H-end 288 */
- regs[0x1f] = 0x07; /* AE V-end 224 */
- } else {
- regs[0x1a] = 0x1d; /* HO_SIZE 960, makes no sense */
- regs[0x1b] = 0x10; /* VO_SIZE 512, makes no sense */
- regs[0x1c] = 0x05; /* AE H-start 160 */
- regs[0x1d] = 0x03; /* AE V-start 96 */
- regs[0x1e] = 0x0f; /* AE H-end 480 */
- regs[0x1f] = 0x0c; /* AE V-end 384 */
- }
-
- /* Setup the gamma table (only used with the sn9c103 bridge) */
- for (i = 0; i < 16; i++)
- regs[0x20 + i] = i * 16;
- regs[0x20 + i] = 255;
-
- /* Special cases where some regs depend on mode or bridge */
- switch (sd->sensor) {
- case SENSOR_TAS5130CXX:
- /* FIXME / TESTME
- probably not mode specific at all most likely the upper
- nibble of 0x19 is exposure (clock divider) just as with
- the tas5110, we need someone to test this. */
- regs[0x19] = mode ? 0x23 : 0x43;
- break;
- case SENSOR_OV7630:
- /* FIXME / TESTME for some reason with the 101/102 bridge the
- clock is set to 12 Mhz (reg1 == 0x04), rather then 24.
- Also the hstart needs to go from 1 to 2 when using a 103,
- which is likely related. This does not seem right. */
- if (sd->bridge == BRIDGE_103) {
- regs[0x01] = 0x44; /* Select 24 Mhz clock */
- regs[0x12] = 0x02; /* Set hstart to 2 */
- }
- }
- /* Disable compression when the raw bayer format has been selected */
- if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
- regs[0x18] &= ~0x80;
-
- /* Vga mode emulation on SIF sensor? */
- if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
- regs[0x12] += 16; /* hstart adjust */
- regs[0x13] += 24; /* vstart adjust */
- regs[0x15] = 320 / 16; /* hsize */
- regs[0x16] = 240 / 16; /* vsize */
- }
-
- /* reg 0x01 bit 2 video transfert on */
- reg_w(gspca_dev, 0x01, &regs[0x01], 1);
- /* reg 0x17 SensorClk enable inv Clk 0x60 */
- reg_w(gspca_dev, 0x17, &regs[0x17], 1);
- /* Set the registers from the template */
- reg_w(gspca_dev, 0x01, &regs[0x01],
- (sd->bridge == BRIDGE_103) ? 0x30 : 0x1f);
-
- /* Init the sensor */
- i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
- sensor_data[sd->sensor].sensor_init_size);
-
- /* Mode / bridge specific sensor setup */
- switch (sd->sensor) {
- case SENSOR_PAS202: {
- const __u8 i2cpclockdiv[] =
- {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10};
- /* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */
- if (mode)
- i2c_w(gspca_dev, i2cpclockdiv);
- break;
- }
- case SENSOR_OV7630:
- /* FIXME / TESTME We should be able to handle this identical
- for the 101/102 and the 103 case */
- if (sd->bridge == BRIDGE_103) {
- const __u8 i2c[] = { 0xa0, 0x21, 0x13,
- 0x80, 0x00, 0x00, 0x00, 0x10 };
- i2c_w(gspca_dev, i2c);
- }
- break;
- }
- /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
- reg_w(gspca_dev, 0x15, &regs[0x15], 2);
- /* compression register */
- reg_w(gspca_dev, 0x18, &regs[0x18], 1);
- /* H_start */
- reg_w(gspca_dev, 0x12, &regs[0x12], 1);
- /* V_START */
- reg_w(gspca_dev, 0x13, &regs[0x13], 1);
- /* reset 0x17 SensorClk enable inv Clk 0x60 */
- /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
- reg_w(gspca_dev, 0x17, &regs[0x17], 1);
- /*MCKSIZE ->3 */ /*fixme: not ov7630*/
- reg_w(gspca_dev, 0x19, &regs[0x19], 1);
- /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
- reg_w(gspca_dev, 0x1c, &regs[0x1c], 4);
- /* Enable video transfert */
- reg_w(gspca_dev, 0x01, &regs[0x01], 1);
- /* Compression */
- reg_w(gspca_dev, 0x18, &regs[0x18], 2);
- msleep(20);
-
- sd->reg11 = -1;
-
- setgain(gspca_dev);
- setbrightness(gspca_dev);
- setexposure(gspca_dev);
- setfreq(gspca_dev);
-
- sd->frames_to_drop = 0;
- sd->autogain_ignore_frames = 0;
- gspca_dev->exp_too_high_cnt = 0;
- gspca_dev->exp_too_low_cnt = 0;
- atomic_set(&sd->avg_lum, -1);
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- sd_init(gspca_dev);
-}
-
-static u8* find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i, header_size = (sd->bridge == BRIDGE_103) ? 18 : 12;
-
- /* frames start with:
- * ff ff 00 c4 c4 96 synchro
- * 00 (unknown)
- * xx (frame sequence / size / compression)
- * (xx) (idem - extra byte for sn9c103)
- * ll mm brightness sum inside auto exposure
- * ll mm brightness sum outside auto exposure
- * (xx xx xx xx xx) audio values for snc103
- */
- for (i = 0; i < len; i++) {
- switch (sd->header_read) {
- case 0:
- if (data[i] == 0xff)
- sd->header_read++;
- break;
- case 1:
- if (data[i] == 0xff)
- sd->header_read++;
- else
- sd->header_read = 0;
- break;
- case 2:
- if (data[i] == 0x00)
- sd->header_read++;
- else if (data[i] != 0xff)
- sd->header_read = 0;
- break;
- case 3:
- if (data[i] == 0xc4)
- sd->header_read++;
- else if (data[i] == 0xff)
- sd->header_read = 1;
- else
- sd->header_read = 0;
- break;
- case 4:
- if (data[i] == 0xc4)
- sd->header_read++;
- else if (data[i] == 0xff)
- sd->header_read = 1;
- else
- sd->header_read = 0;
- break;
- case 5:
- if (data[i] == 0x96)
- sd->header_read++;
- else if (data[i] == 0xff)
- sd->header_read = 1;
- else
- sd->header_read = 0;
- break;
- default:
- sd->header[sd->header_read - 6] = data[i];
- sd->header_read++;
- if (sd->header_read == header_size) {
- sd->header_read = 0;
- return data + i + 1;
- }
- }
- }
- return NULL;
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- int fr_h_sz = 0, lum_offset = 0, len_after_sof = 0;
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam = &gspca_dev->cam;
- u8 *sof;
-
- sof = find_sof(gspca_dev, data, len);
- if (sof) {
- if (sd->bridge == BRIDGE_103) {
- fr_h_sz = 18;
- lum_offset = 3;
- } else {
- fr_h_sz = 12;
- lum_offset = 2;
- }
-
- len_after_sof = len - (sof - data);
- len = (sof - data) - fr_h_sz;
- if (len < 0)
- len = 0;
- }
-
- if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
- /* In raw mode we sometimes get some garbage after the frame
- ignore this */
- int used;
- int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
-
- used = gspca_dev->image_len;
- if (used + len > size)
- len = size - used;
- }
-
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-
- if (sof) {
- int lum = sd->header[lum_offset] +
- (sd->header[lum_offset + 1] << 8);
-
- /* When exposure changes midway a frame we
- get a lum of 0 in this case drop 2 frames
- as the frames directly after an exposure
- change have an unstable image. Sometimes lum
- *really* is 0 (cam used in low light with
- low exposure setting), so do not drop frames
- if the previous lum was 0 too. */
- if (lum == 0 && sd->prev_avg_lum != 0) {
- lum = -1;
- sd->frames_to_drop = 2;
- sd->prev_avg_lum = 0;
- } else
- sd->prev_avg_lum = lum;
- atomic_set(&sd->avg_lum, lum);
-
- if (sd->frames_to_drop)
- sd->frames_to_drop--;
- else
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
-
- gspca_frame_add(gspca_dev, FIRST_PACKET, sof, len_after_sof);
- }
-}
-
-static int sd_querymenu(struct gspca_dev *gspca_dev,
- struct v4l2_querymenu *menu)
-{
- switch (menu->id) {
- case V4L2_CID_POWER_LINE_FREQUENCY:
- switch (menu->index) {
- case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
- strcpy((char *) menu->name, "NoFliker");
- return 0;
- case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
- strcpy((char *) menu->name, "50 Hz");
- return 0;
- case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
- strcpy((char *) menu->name, "60 Hz");
- return 0;
- }
- break;
- }
- return -EINVAL;
-}
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
-static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* interrupt packet data */
- int len) /* interrupt packet length */
-{
- int ret = -EINVAL;
-
- if (len == 1 && data[0] == 1) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
- input_sync(gspca_dev->input_dev);
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
- input_sync(gspca_dev->input_dev);
- ret = 0;
- }
-
- return ret;
-}
-#endif
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
- .querymenu = sd_querymenu,
- .dq_callback = do_autogain,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .int_pkt_scan = sd_int_pkt_scan,
-#endif
-};
-
-/* -- module initialisation -- */
-#define SB(sensor, bridge) \
- .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
-
-
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */
- {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */
- {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */
- {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
- {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
- {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
- {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
-#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
- {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
- {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
-#endif
- {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
- {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
- {USB_DEVICE(0x0c45, 0x602a), SB(HV7131D, 102)},
- /* {USB_DEVICE(0x0c45, 0x602b), SB(MI0343, 102)}, */
- {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
- {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
- {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
- /* {USB_DEVICE(0x0c45, 0x6030), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */
- /* {USB_DEVICE(0x0c45, 0x6082), SB(MI03XX, 103)}, */ /* MI0343 MI0360 */
- {USB_DEVICE(0x0c45, 0x6083), SB(HV7131D, 103)},
- {USB_DEVICE(0x0c45, 0x608c), SB(HV7131R, 103)},
- /* {USB_DEVICE(0x0c45, 0x608e), SB(CISVF10, 103)}, */
- {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
- {USB_DEVICE(0x0c45, 0x60a8), SB(PAS106, 103)},
- {USB_DEVICE(0x0c45, 0x60aa), SB(TAS5130CXX, 103)},
- {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
- {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
deleted file mode 100644
index 150b2df40f7..00000000000
--- a/drivers/media/video/gspca/sonixj.c
+++ /dev/null
@@ -1,3206 +0,0 @@
-/*
- * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
- *
- * Copyright (C) 2009-2011 Jean-François Moine <http://moinejf.free.fr>
- * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "sonixj"
-
-#include <linux/input.h>
-#include "gspca.h"
-#include "jpeg.h"
-
-MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
-MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* controls */
-enum e_ctrl {
- BRIGHTNESS,
- CONTRAST,
- COLORS,
- BLUE,
- RED,
- GAMMA,
- EXPOSURE,
- AUTOGAIN,
- GAIN,
- HFLIP,
- VFLIP,
- SHARPNESS,
- ILLUM,
- FREQ,
- NCTRLS /* number of controls */
-};
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- struct gspca_ctrl ctrls[NCTRLS];
-
- atomic_t avg_lum;
- u32 exposure;
-
- struct work_struct work;
- struct workqueue_struct *work_thread;
-
- u32 pktsz; /* (used by pkt_scan) */
- u16 npkt;
- s8 nchg;
- s8 short_mark;
-
- u8 quality; /* image quality */
-#define QUALITY_MIN 25
-#define QUALITY_MAX 90
-#define QUALITY_DEF 70
-
- u8 reg01;
- u8 reg17;
- u8 reg18;
- u8 flags;
-
- s8 ag_cnt;
-#define AG_CNT_START 13
-
- u8 bridge;
-#define BRIDGE_SN9C102P 0
-#define BRIDGE_SN9C105 1
-#define BRIDGE_SN9C110 2
-#define BRIDGE_SN9C120 3
- u8 sensor; /* Type of image sensor chip */
- u8 i2c_addr;
-
- u8 jpeg_hdr[JPEG_HDR_SZ];
-};
-enum sensors {
- SENSOR_ADCM1700,
- SENSOR_GC0307,
- SENSOR_HV7131R,
- SENSOR_MI0360,
- SENSOR_MI0360B,
- SENSOR_MO4000,
- SENSOR_MT9V111,
- SENSOR_OM6802,
- SENSOR_OV7630,
- SENSOR_OV7648,
- SENSOR_OV7660,
- SENSOR_PO1030,
- SENSOR_PO2030N,
- SENSOR_SOI768,
- SENSOR_SP80708,
-};
-
-static void qual_upd(struct work_struct *work);
-
-/* device flags */
-#define F_PDN_INV 0x01 /* inverse pin S_PWR_DN / sn_xxx tables */
-#define F_ILLUM 0x02 /* presence of illuminator */
-
-/* sn9c1xx definitions */
-/* register 0x01 */
-#define S_PWR_DN 0x01 /* sensor power down */
-#define S_PDN_INV 0x02 /* inverse pin S_PWR_DN */
-#define V_TX_EN 0x04 /* video transfer enable */
-#define LED 0x08 /* output to pin LED */
-#define SCL_SEL_OD 0x20 /* open-drain mode */
-#define SYS_SEL_48M 0x40 /* system clock 0: 24MHz, 1: 48MHz */
-/* register 0x17 */
-#define MCK_SIZE_MASK 0x1f /* sensor master clock */
-#define SEN_CLK_EN 0x20 /* enable sensor clock */
-#define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */
-
-/* V4L2 controls supported by the driver */
-static void setbrightness(struct gspca_dev *gspca_dev);
-static void setcontrast(struct gspca_dev *gspca_dev);
-static void setcolors(struct gspca_dev *gspca_dev);
-static void setredblue(struct gspca_dev *gspca_dev);
-static void setgamma(struct gspca_dev *gspca_dev);
-static void setexposure(struct gspca_dev *gspca_dev);
-static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
-static void setgain(struct gspca_dev *gspca_dev);
-static void sethvflip(struct gspca_dev *gspca_dev);
-static void setsharpness(struct gspca_dev *gspca_dev);
-static void setillum(struct gspca_dev *gspca_dev);
-static void setfreq(struct gspca_dev *gspca_dev);
-
-static const struct ctrl sd_ctrls[NCTRLS] = {
-[BRIGHTNESS] = {
- {
- .id = V4L2_CID_BRIGHTNESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Brightness",
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0x80,
- },
- .set_control = setbrightness
- },
-[CONTRAST] = {
- {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contrast",
- .minimum = 0,
-#define CONTRAST_MAX 127
- .maximum = CONTRAST_MAX,
- .step = 1,
- .default_value = 20,
- },
- .set_control = setcontrast
- },
-[COLORS] = {
- {
- .id = V4L2_CID_SATURATION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 40,
- .step = 1,
-#define COLORS_DEF 25
- .default_value = COLORS_DEF,
- },
- .set_control = setcolors
- },
-[BLUE] = {
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Blue Balance",
- .minimum = 24,
- .maximum = 40,
- .step = 1,
- .default_value = 32,
- },
- .set_control = setredblue
- },
-[RED] = {
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Red Balance",
- .minimum = 24,
- .maximum = 40,
- .step = 1,
- .default_value = 32,
- },
- .set_control = setredblue
- },
-[GAMMA] = {
- {
- .id = V4L2_CID_GAMMA,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gamma",
- .minimum = 0,
- .maximum = 40,
- .step = 1,
-#define GAMMA_DEF 20
- .default_value = GAMMA_DEF,
- },
- .set_control = setgamma
- },
-[EXPOSURE] = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Exposure",
- .minimum = 500,
- .maximum = 1500,
- .step = 1,
- .default_value = 1024
- },
- .set_control = setexposure
- },
-[AUTOGAIN] = {
- {
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Auto Gain",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = sd_setautogain,
- },
-[GAIN] = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain",
- .minimum = 4,
- .maximum = 49,
- .step = 1,
- .default_value = 15
- },
- .set_control = setgain
- },
-[HFLIP] = {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- .set_control = sethvflip
- },
-[VFLIP] = {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Vflip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- .set_control = sethvflip
- },
-[SHARPNESS] = {
- {
- .id = V4L2_CID_SHARPNESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Sharpness",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 90,
- },
- .set_control = setsharpness
- },
-[ILLUM] = {
- {
- .id = V4L2_CID_ILLUMINATORS_1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Illuminator / infrared",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- .set_control = setillum
- },
-/* ov7630/ov7648/ov7660 only */
-[FREQ] = {
- {
- .id = V4L2_CID_POWER_LINE_FREQUENCY,
- .type = V4L2_CTRL_TYPE_MENU,
- .name = "Light frequency filter",
- .minimum = 0,
- .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
- .step = 1,
- .default_value = 1,
- },
- .set_control = setfreq
- },
-};
-
-/* table of the disabled controls */
-static const __u32 ctrl_dis[] = {
-[SENSOR_ADCM1700] = (1 << EXPOSURE) |
- (1 << AUTOGAIN) |
- (1 << GAIN) |
- (1 << HFLIP) |
- (1 << VFLIP) |
- (1 << FREQ),
-
-[SENSOR_GC0307] = (1 << EXPOSURE) |
- (1 << GAIN) |
- (1 << HFLIP) |
- (1 << VFLIP) |
- (1 << FREQ),
-
-[SENSOR_HV7131R] = (1 << EXPOSURE) |
- (1 << GAIN) |
- (1 << HFLIP) |
- (1 << FREQ),
-
-[SENSOR_MI0360] = (1 << EXPOSURE) |
- (1 << GAIN) |
- (1 << HFLIP) |
- (1 << VFLIP) |
- (1 << FREQ),
-
-[SENSOR_MI0360B] = (1 << EXPOSURE) |
- (1 << GAIN) |
- (1 << HFLIP) |
- (1 << VFLIP) |
- (1 << FREQ),
-
-[SENSOR_MO4000] = (1 << EXPOSURE) |
- (1 << GAIN) |
- (1 << HFLIP) |
- (1 << VFLIP) |
- (1 << FREQ),
-
-[SENSOR_MT9V111] = (1 << EXPOSURE) |
- (1 << GAIN) |
- (1 << HFLIP) |
- (1 << VFLIP) |
- (1 << FREQ),
-
-[SENSOR_OM6802] = (1 << EXPOSURE) |
- (1 << GAIN) |
- (1 << HFLIP) |
- (1 << VFLIP) |
- (1 << FREQ),
-
-[SENSOR_OV7630] = (1 << EXPOSURE) |
- (1 << GAIN) |
- (1 << HFLIP),
-
-[SENSOR_OV7648] = (1 << EXPOSURE) |
- (1 << GAIN) |
- (1 << HFLIP),
-
-[SENSOR_OV7660] = (1 << EXPOSURE) |
- (1 << AUTOGAIN) |
- (1 << GAIN) |
- (1 << HFLIP) |
- (1 << VFLIP),
-
-[SENSOR_PO1030] = (1 << EXPOSURE) |
- (1 << AUTOGAIN) |
- (1 << GAIN) |
- (1 << HFLIP) |
- (1 << VFLIP) |
- (1 << FREQ),
-
-[SENSOR_PO2030N] = (1 << FREQ),
-
-[SENSOR_SOI768] = (1 << EXPOSURE) |
- (1 << AUTOGAIN) |
- (1 << GAIN) |
- (1 << HFLIP) |
- (1 << VFLIP) |
- (1 << FREQ),
-
-[SENSOR_SP80708] = (1 << EXPOSURE) |
- (1 << AUTOGAIN) |
- (1 << GAIN) |
- (1 << HFLIP) |
- (1 << VFLIP) |
- (1 << FREQ),
-};
-
-static const struct v4l2_pix_format cif_mode[] = {
- {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 4 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-static const struct v4l2_pix_format vga_mode[] = {
- {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 4 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2},
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- /* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
- .sizeimage = 640 * 480 * 3 / 4 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-
-static const u8 sn_adcm1700[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x43, 0x60, 0x00, 0x1a, 0x00, 0x00, 0x00,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x80, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x05, 0x01, 0x05, 0x16, 0x12, 0x42,
-/* reg18 reg19 reg1a reg1b */
- 0x06, 0x00, 0x00, 0x00
-};
-
-static const u8 sn_gc0307[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x61, 0x62, 0x00, 0x1a, 0x00, 0x00, 0x00,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x03, 0x01, 0x08, 0x28, 0x1e, 0x02,
-/* reg18 reg19 reg1a reg1b */
- 0x06, 0x00, 0x00, 0x00
-};
-
-static const u8 sn_hv7131[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x03, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x81, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
-/* reg18 reg19 reg1a reg1b */
- 0x0a, 0x00, 0x00, 0x00
-};
-
-static const u8 sn_mi0360[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
-/* reg18 reg19 reg1a reg1b */
- 0x06, 0x00, 0x00, 0x00
-};
-
-static const u8 sn_mi0360b[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x40,
-/* reg18 reg19 reg1a reg1b */
- 0x06, 0x00, 0x00, 0x00
-};
-
-static const u8 sn_mo4000[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
-/* reg18 reg19 reg1a reg1b */
- 0x08, 0x00, 0x00, 0x00
-};
-
-static const u8 sn_mt9v111[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x81, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
-/* reg18 reg19 reg1a reg1b */
- 0x06, 0x00, 0x00, 0x00
-};
-
-static const u8 sn_om6802[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x23, 0x72, 0x00, 0x1a, 0x20, 0x20, 0x19,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
-/* reg18 reg19 reg1a reg1b */
- 0x05, 0x00, 0x00, 0x00
-};
-
-static const u8 sn_ov7630[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
-/* reg18 reg19 reg1a reg1b */
- 0x0b, 0x00, 0x00, 0x00
-};
-
-static const u8 sn_ov7648[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
-/* reg18 reg19 reg1a reg1b */
- 0x0b, 0x00, 0x00, 0x00
-};
-
-static const u8 sn_ov7660[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
-/* reg18 reg19 reg1a reg1b */
- 0x07, 0x00, 0x00, 0x00
-};
-
-static const u8 sn_po1030[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x00,
-/* reg18 reg19 reg1a reg1b */
- 0x07, 0x00, 0x00, 0x00
-};
-
-static const u8 sn_po2030n[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x63, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x00, 0x01, 0x14, 0x28, 0x1e, 0x00,
-/* reg18 reg19 reg1a reg1b */
- 0x07, 0x00, 0x00, 0x00
-};
-
-static const u8 sn_soi768[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x00, 0x01, 0x08, 0x28, 0x1e, 0x00,
-/* reg18 reg19 reg1a reg1b */
- 0x07, 0x00, 0x00, 0x00
-};
-
-static const u8 sn_sp80708[0x1c] = {
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
-/* reg8 reg9 rega regb regc regd rege regf */
- 0x81, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
- 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
-/* reg18 reg19 reg1a reg1b */
- 0x07, 0x00, 0x00, 0x00
-};
-
-/* sequence specific to the sensors - !! index = SENSOR_xxx */
-static const u8 *sn_tb[] = {
-[SENSOR_ADCM1700] = sn_adcm1700,
-[SENSOR_GC0307] = sn_gc0307,
-[SENSOR_HV7131R] = sn_hv7131,
-[SENSOR_MI0360] = sn_mi0360,
-[SENSOR_MI0360B] = sn_mi0360b,
-[SENSOR_MO4000] = sn_mo4000,
-[SENSOR_MT9V111] = sn_mt9v111,
-[SENSOR_OM6802] = sn_om6802,
-[SENSOR_OV7630] = sn_ov7630,
-[SENSOR_OV7648] = sn_ov7648,
-[SENSOR_OV7660] = sn_ov7660,
-[SENSOR_PO1030] = sn_po1030,
-[SENSOR_PO2030N] = sn_po2030n,
-[SENSOR_SOI768] = sn_soi768,
-[SENSOR_SP80708] = sn_sp80708,
-};
-
-/* default gamma table */
-static const u8 gamma_def[17] = {
- 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
- 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
-};
-/* gamma for sensor ADCM1700 */
-static const u8 gamma_spec_0[17] = {
- 0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
- 0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
-};
-/* gamma for sensors HV7131R and MT9V111 */
-static const u8 gamma_spec_1[17] = {
- 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
- 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
-};
-/* gamma for sensor GC0307 */
-static const u8 gamma_spec_2[17] = {
- 0x14, 0x37, 0x50, 0x6a, 0x7c, 0x8d, 0x9d, 0xab,
- 0xb5, 0xbf, 0xc2, 0xcb, 0xd1, 0xd6, 0xdb, 0xe1, 0xeb
-};
-/* gamma for sensor SP80708 */
-static const u8 gamma_spec_3[17] = {
- 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
- 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
-};
-
-/* color matrix and offsets */
-static const u8 reg84[] = {
- 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
- 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
- 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
- 0x00, 0x00, 0x00 /* YUV offsets */
-};
-
-#define DELAY 0xdd
-
-static const u8 adcm1700_sensor_init[][8] = {
- {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10}, /* reset */
- {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
- {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
- {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
- {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
- {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
- {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
- {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
- {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
- {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
- {0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
- {}
-};
-static const u8 adcm1700_sensor_param1[][8] = {
- {0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10}, /* exposure? */
- {0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
-
- {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
- {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
- {0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
- {0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10}, /* exposure? */
-
- {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
- {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
- {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
- {}
-};
-static const u8 gc0307_sensor_init[][8] = {
- {0xa0, 0x21, 0x43, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x44, 0xa2, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x11, 0x05, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x08, 0x02, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x09, 0x01, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x0d, 0x22, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10},
- {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/
- {0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x17, 0x52, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x18, 0x50, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x1e, 0x0d, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x1f, 0x32, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x61, 0x90, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x63, 0x70, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x65, 0x98, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x67, 0x90, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x04, 0x96, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x45, 0x27, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x47, 0x2c, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x43, 0x47, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x44, 0xd8, 0x00, 0x00, 0x00, 0x10},
- {}
-};
-static const u8 gc0307_sensor_param1[][8] = {
- {0xa0, 0x21, 0x68, 0x13, 0x00, 0x00, 0x00, 0x10},
- {0xd0, 0x21, 0x61, 0x80, 0x00, 0x80, 0x00, 0x10},
- {0xc0, 0x21, 0x65, 0x80, 0x00, 0x80, 0x00, 0x10},
- {0xc0, 0x21, 0x63, 0xa0, 0x00, 0xa6, 0x00, 0x10},
-/*param3*/
- {0xa0, 0x21, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x02, 0x88, 0x00, 0x00, 0x00, 0x10},
- {}
-};
-
-static const u8 hv7131r_sensor_init[][8] = {
- {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
- {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
- {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
-/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
- {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
-/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
-
- {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
- {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
- {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
- {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
- {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
- {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
-
- {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
-
- {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
- /* set sensor clock */
- {}
-};
-static const u8 mi0360_sensor_init[][8] = {
- {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
- {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
- {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
- {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
- {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
- {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
- {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
- {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
- {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
- {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
-
- {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
- {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
-
- {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
- {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
-
- {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
- {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
-/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
-/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
- {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
- {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
- {}
-};
-static const u8 mi0360b_sensor_init[][8] = {
- {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
- {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
- {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
- {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
- {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
- {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
- {0xd1, 0x5d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
- {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
- {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
- {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
- {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
- {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
- {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
-
- {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
- {0xd1, 0x5d, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10},
- {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10},
- {}
-};
-static const u8 mi0360b_sensor_param1[][8] = {
- {0xb1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x06, 0x00, 0x53, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10},
- {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
-
- {0xd1, 0x5d, 0x2b, 0x00, 0xd1, 0x01, 0xc9, 0x10},
- {0xd1, 0x5d, 0x2d, 0x00, 0xed, 0x00, 0xd1, 0x10},
- {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
- {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
- {}
-};
-static const u8 mo4000_sensor_init[][8] = {
- {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
- {}
-};
-static const u8 mt9v111_sensor_init[][8] = {
- {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
- {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
- {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
- {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
- {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
- {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
- {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
- {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
- {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
- {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
- {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
- {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
- {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
- {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
- {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
- {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
- {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
- {}
-};
-static const u8 mt9v111_sensor_param1[][8] = {
- {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xad, 0x10}, /* G1 and B gains */
- {0xd1, 0x5c, 0x2d, 0x00, 0xad, 0x00, 0x33, 0x10}, /* R and G2 gains */
- {0xb1, 0x5c, 0x06, 0x00, 0x40, 0x00, 0x00, 0x10}, /* vert blanking */
- {0xb1, 0x5c, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10}, /* horiz blanking */
- {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
- {}
-};
-static const u8 om6802_init0[2][8] = {
-/*fixme: variable*/
- {0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
-};
-static const u8 om6802_sensor_init[][8] = {
- {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
- /* factory mode */
- {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
- /* output raw RGB */
- {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
-/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
- {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
- /* auto-exposure speed (0) / white balance mode (auto RGB) */
-/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
- * set color mode */
-/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
- * max AGC value in AE */
-/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
- * preset AGC */
-/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
- * preset brightness */
-/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
- * preset contrast */
-/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
- * preset gamma */
- {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
- /* luminance mode (0x4f -> AutoExpo on) */
- {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
- /* preset shutter */
-/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
- * auto frame rate */
-/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
- {0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
- {}
-};
-static const u8 om6802_sensor_param1[][8] = {
- {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
- {}
-};
-static const u8 ov7630_sensor_init[][8] = {
- {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
- {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
- {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
- {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
- {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
-/* win: i2c_r from 00 to 80 */
- {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
- {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
-/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
- 0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
- {0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
- {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
- {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
- {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
- {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
- {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
- {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
- {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
- {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
- {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
- {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
- {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
- {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
- {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
- {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
- {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
- {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
- {}
-};
-static const u8 ov7630_sensor_param1[][8] = {
- {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
-/*fixme: + 0x12, 0x04*/
-/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
- * set by setvflip */
- {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
-/* */
-/* {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
-/* {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
-/* */
- {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
-/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
- {}
-};
-
-static const u8 ov7648_sensor_init[][8] = {
- {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
- {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
- {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
- {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
- {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
- {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
- {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
- {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
- {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
- {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
- {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
- {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
- {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
- {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
- {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
- {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
- {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
- {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
- {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
-
- {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
-/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
-/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
-/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
- {}
-};
-static const u8 ov7648_sensor_param1[][8] = {
-/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
-/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
- * set by setvflip */
- {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
-/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
-/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
-/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
-/*...*/
- {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
-/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
-/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
-/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
-/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
-/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
-
- {}
-};
-
-static const u8 ov7660_sensor_init[][8] = {
- {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
- {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
- {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
- /* Outformat = rawRGB */
- {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
- {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
- /* GAIN BLUE RED VREF */
- {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
- /* COM 1 BAVE GEAVE AECHH */
- {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
- {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
- {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
- /* AECH CLKRC COM7 COM8 */
- {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
- {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
- /* HSTART HSTOP VSTRT VSTOP */
- {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
- {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
- {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
- /* BOS GBOS GROS ROS (BGGR offset) */
-/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
- {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
- /* AEW AEB VPT BBIAS */
- {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
- /* GbBIAS RSVD EXHCH EXHCL */
- {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
- /* RBIAS ADVFL ASDVFH YAVE */
- {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
- /* HSYST HSYEN HREF */
- {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
- {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
- /* ADC ACOM OFON TSLB */
- {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
- /* COM11 COM12 COM13 COM14 */
- {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
- /* EDGE COM15 COM16 COM17 */
- {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
- {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
- {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
- {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
- {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
- {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
- {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
- {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
- {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
- {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
- /* LCC1 LCC2 LCC3 LCC4 */
- {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
- {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
- {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
- /* band gap reference [0:3] DBLV */
- {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
- {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
- {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
- {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
- {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
- {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
- {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
- {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
- {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
- {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
-/* not in all ms-win traces*/
- {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
- {}
-};
-static const u8 ov7660_sensor_param1[][8] = {
- {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
- /* bits[3..0]reserved */
- {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
- /* VREF vertical frame ctrl */
- {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
- {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
- {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
- {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
-/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
-/****** (some exchanges in the win trace) ******/
-/*fixme:param2*/
- {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
- {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
- {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
- {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
-/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
-/****** (some exchanges in the win trace) ******/
-/******!! startsensor KO if changed !!****/
-/*fixme: param3*/
- {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
- {}
-};
-
-static const u8 po1030_sensor_init[][8] = {
-/* the sensor registers are described in m5602/m5602_po1030.h */
- {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
- {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
- {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
- {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
- {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
- {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
- {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
- {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
- {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
- {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
- {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
- {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
- {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
- {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
- {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
- {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
- {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
- {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
- {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
- {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
-
- {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
- {}
-};
-static const u8 po1030_sensor_param1[][8] = {
-/* from ms-win traces - these values change with auto gain/expo/wb.. */
- {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
-/* mean values */
- {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
- {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
- {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
-
- {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
- {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
- {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
-/* {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
- {}
-};
-
-static const u8 po2030n_sensor_init[][8] = {
- {0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10},
- {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
- {0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10},
- {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
- {0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x10},
- {0xd1, 0x6e, 0x0c, 0x03, 0x50, 0x01, 0xe8, 0x10},
- {0xd1, 0x6e, 0x1d, 0x20, 0x0a, 0x19, 0x44, 0x10},
- {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x45, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x4d, 0x00, 0x00, 0x00, 0xed, 0x10},
- {0xd1, 0x6e, 0x51, 0x17, 0x4a, 0x2f, 0xc0, 0x10},
- {0xd1, 0x6e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x79, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x85, 0x00, 0x00, 0x00, 0x08, 0x10},
- {0xd1, 0x6e, 0x89, 0x01, 0xe8, 0x00, 0x01, 0x10},
- {0xa1, 0x6e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x01, 0x10},
- {0xd1, 0x6e, 0x29, 0xe6, 0x00, 0xbd, 0x03, 0x10},
- {0xd1, 0x6e, 0x2d, 0x41, 0x38, 0x68, 0x40, 0x10},
- {0xd1, 0x6e, 0x31, 0x2b, 0x00, 0x36, 0x00, 0x10},
- {0xd1, 0x6e, 0x35, 0x30, 0x30, 0x08, 0x00, 0x10},
- {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x33, 0x06, 0x10},
- {0xb1, 0x6e, 0x3d, 0x06, 0x02, 0x00, 0x00, 0x10},
- {}
-};
-static const u8 po2030n_sensor_param1[][8] = {
- {0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10},
- {DELAY, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */
- {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
- {0xd1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x40, 0x10}, /* RGBG gains */
-/*param2*/
- {0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
- {}
-};
-
-static const u8 soi768_sensor_init[][8] = {
- {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
- {DELAY, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */
- {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10},
- {}
-};
-static const u8 soi768_sensor_param1[][8] = {
- {0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10},
-/* */
-/* {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */
-/* {0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */
- {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
-/* {0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */
- {0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10},
-/* the next sequence should be used for auto gain */
- {0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10},
- /* global gain ? : 07 - change with 0x15 at the end */
- {0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */
- {0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10},
- {0xb1, 0x21, 0x2d, 0x63, 0x03, 0x00, 0x00, 0x10},
- /* exposure ? : 0200 - change with 0x1e at the end */
- {}
-};
-
-static const u8 sp80708_sensor_init[][8] = {
- {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
- {}
-};
-static const u8 sp80708_sensor_param1[][8] = {
- {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
- {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
- {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
- {}
-};
-
-static const u8 (*sensor_init[])[8] = {
-[SENSOR_ADCM1700] = adcm1700_sensor_init,
-[SENSOR_GC0307] = gc0307_sensor_init,
-[SENSOR_HV7131R] = hv7131r_sensor_init,
-[SENSOR_MI0360] = mi0360_sensor_init,
-[SENSOR_MI0360B] = mi0360b_sensor_init,
-[SENSOR_MO4000] = mo4000_sensor_init,
-[SENSOR_MT9V111] = mt9v111_sensor_init,
-[SENSOR_OM6802] = om6802_sensor_init,
-[SENSOR_OV7630] = ov7630_sensor_init,
-[SENSOR_OV7648] = ov7648_sensor_init,
-[SENSOR_OV7660] = ov7660_sensor_init,
-[SENSOR_PO1030] = po1030_sensor_init,
-[SENSOR_PO2030N] = po2030n_sensor_init,
-[SENSOR_SOI768] = soi768_sensor_init,
-[SENSOR_SP80708] = sp80708_sensor_init,
-};
-
-/* read <len> bytes to gspca_dev->usb_buf */
-static void reg_r(struct gspca_dev *gspca_dev,
- u16 value, int len)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
-#ifdef GSPCA_DEBUG
- if (len > USB_BUF_SZ) {
- pr_err("reg_r: buffer overflow\n");
- return;
- }
-#endif
- ret = usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- 0,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- value, 0,
- gspca_dev->usb_buf, len,
- 500);
- PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
- if (ret < 0) {
- pr_err("reg_r err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void reg_w1(struct gspca_dev *gspca_dev,
- u16 value,
- u8 data)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
- gspca_dev->usb_buf[0] = data;
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x08,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- value,
- 0,
- gspca_dev->usb_buf, 1,
- 500);
- if (ret < 0) {
- pr_err("reg_w1 err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-static void reg_w(struct gspca_dev *gspca_dev,
- u16 value,
- const u8 *buffer,
- int len)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
- value, buffer[0], buffer[1]);
-#ifdef GSPCA_DEBUG
- if (len > USB_BUF_SZ) {
- pr_err("reg_w: buffer overflow\n");
- return;
- }
-#endif
- memcpy(gspca_dev->usb_buf, buffer, len);
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x08,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- value, 0,
- gspca_dev->usb_buf, len,
- 500);
- if (ret < 0) {
- pr_err("reg_w err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-/* I2C write 1 byte */
-static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val);
- switch (sd->sensor) {
- case SENSOR_ADCM1700:
- case SENSOR_OM6802:
- case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */
- gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
- break;
- default: /* i2c command = a1 (400 kHz) */
- gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
- break;
- }
- gspca_dev->usb_buf[1] = sd->i2c_addr;
- gspca_dev->usb_buf[2] = reg;
- gspca_dev->usb_buf[3] = val;
- gspca_dev->usb_buf[4] = 0;
- gspca_dev->usb_buf[5] = 0;
- gspca_dev->usb_buf[6] = 0;
- gspca_dev->usb_buf[7] = 0x10;
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x08,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- 0x08, /* value = i2c */
- 0,
- gspca_dev->usb_buf, 8,
- 500);
- if (ret < 0) {
- pr_err("i2c_w1 err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-/* I2C write 8 bytes */
-static void i2c_w8(struct gspca_dev *gspca_dev,
- const u8 *buffer)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..",
- buffer[2], buffer[3]);
- memcpy(gspca_dev->usb_buf, buffer, 8);
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x08,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- 0x08, 0, /* value, index */
- gspca_dev->usb_buf, 8,
- 500);
- msleep(2);
- if (ret < 0) {
- pr_err("i2c_w8 err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
-static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 mode[8];
-
- switch (sd->sensor) {
- case SENSOR_ADCM1700:
- case SENSOR_OM6802:
- case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */
- mode[0] = 0x80 | 0x10;
- break;
- default: /* i2c command = 91 (400 kHz) */
- mode[0] = 0x81 | 0x10;
- break;
- }
- mode[1] = sd->i2c_addr;
- mode[2] = reg;
- mode[3] = 0;
- mode[4] = 0;
- mode[5] = 0;
- mode[6] = 0;
- mode[7] = 0x10;
- i2c_w8(gspca_dev, mode);
- msleep(2);
- mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
- mode[2] = 0;
- i2c_w8(gspca_dev, mode);
- msleep(2);
- reg_r(gspca_dev, 0x0a, 5);
-}
-
-static void i2c_w_seq(struct gspca_dev *gspca_dev,
- const u8 (*data)[8])
-{
- while ((*data)[0] != 0) {
- if ((*data)[0] != DELAY)
- i2c_w8(gspca_dev, *data);
- else
- msleep((*data)[1]);
- data++;
- }
-}
-
-/* check the ID of the hv7131 sensor */
-/* this sequence is needed because it activates the sensor */
-static void hv7131r_probe(struct gspca_dev *gspca_dev)
-{
- i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
- msleep(10);
- reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
- msleep(10);
- i2c_r(gspca_dev, 0, 5); /* read sensor id */
- if (gspca_dev->usb_buf[0] == 0x02 /* chip ID (02 is R) */
- && gspca_dev->usb_buf[1] == 0x09
- && gspca_dev->usb_buf[2] == 0x01) {
- PDEBUG(D_PROBE, "Sensor HV7131R found");
- return;
- }
- pr_warn("Erroneous HV7131R ID 0x%02x 0x%02x 0x%02x\n",
- gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
- gspca_dev->usb_buf[2]);
-}
-
-static void mi0360_probe(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i, j;
- u16 val = 0;
- static const u8 probe_tb[][4][8] = {
- { /* mi0360 */
- {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
- {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
- },
- { /* mt9v111 */
- {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
- {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
- {}
- },
- };
-
- for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
- reg_w1(gspca_dev, 0x17, 0x62);
- reg_w1(gspca_dev, 0x01, 0x08);
- for (j = 0; j < 3; j++)
- i2c_w8(gspca_dev, probe_tb[i][j]);
- msleep(2);
- reg_r(gspca_dev, 0x0a, 5);
- val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
- if (probe_tb[i][3][0] != 0)
- i2c_w8(gspca_dev, probe_tb[i][3]);
- reg_w1(gspca_dev, 0x01, 0x29);
- reg_w1(gspca_dev, 0x17, 0x42);
- if (val != 0xffff)
- break;
- }
- if (gspca_dev->usb_err < 0)
- return;
- switch (val) {
- case 0x8221:
- PDEBUG(D_PROBE, "Sensor mi0360b");
- sd->sensor = SENSOR_MI0360B;
- break;
- case 0x823a:
- PDEBUG(D_PROBE, "Sensor mt9v111");
- sd->sensor = SENSOR_MT9V111;
- break;
- case 0x8243:
- PDEBUG(D_PROBE, "Sensor mi0360");
- break;
- default:
- PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
- break;
- }
-}
-
-static void ov7630_probe(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u16 val;
-
- /* check ov76xx */
- reg_w1(gspca_dev, 0x17, 0x62);
- reg_w1(gspca_dev, 0x01, 0x08);
- sd->i2c_addr = 0x21;
- i2c_r(gspca_dev, 0x0a, 2);
- val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
- reg_w1(gspca_dev, 0x01, 0x29);
- reg_w1(gspca_dev, 0x17, 0x42);
- if (gspca_dev->usb_err < 0)
- return;
- if (val == 0x7628) { /* soi768 */
- sd->sensor = SENSOR_SOI768;
-/*fixme: only valid for 0c45:613e?*/
- gspca_dev->cam.input_flags =
- V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
- PDEBUG(D_PROBE, "Sensor soi768");
- return;
- }
- PDEBUG(D_PROBE, "Sensor ov%04x", val);
-}
-
-static void ov7648_probe(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u16 val;
-
- /* check ov76xx */
- reg_w1(gspca_dev, 0x17, 0x62);
- reg_w1(gspca_dev, 0x01, 0x08);
- sd->i2c_addr = 0x21;
- i2c_r(gspca_dev, 0x0a, 2);
- val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
- reg_w1(gspca_dev, 0x01, 0x29);
- reg_w1(gspca_dev, 0x17, 0x42);
- if ((val & 0xff00) == 0x7600) { /* ov76xx */
- PDEBUG(D_PROBE, "Sensor ov%04x", val);
- return;
- }
-
- /* check po1030 */
- reg_w1(gspca_dev, 0x17, 0x62);
- reg_w1(gspca_dev, 0x01, 0x08);
- sd->i2c_addr = 0x6e;
- i2c_r(gspca_dev, 0x00, 2);
- val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
- reg_w1(gspca_dev, 0x01, 0x29);
- reg_w1(gspca_dev, 0x17, 0x42);
- if (gspca_dev->usb_err < 0)
- return;
- if (val == 0x1030) { /* po1030 */
- PDEBUG(D_PROBE, "Sensor po1030");
- sd->sensor = SENSOR_PO1030;
- return;
- }
- pr_err("Unknown sensor %04x\n", val);
-}
-
-/* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */
-static void po2030n_probe(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u16 val;
-
- /* check gc0307 */
- reg_w1(gspca_dev, 0x17, 0x62);
- reg_w1(gspca_dev, 0x01, 0x08);
- reg_w1(gspca_dev, 0x02, 0x22);
- sd->i2c_addr = 0x21;
- i2c_r(gspca_dev, 0x00, 1);
- val = gspca_dev->usb_buf[4];
- reg_w1(gspca_dev, 0x01, 0x29); /* reset */
- reg_w1(gspca_dev, 0x17, 0x42);
- if (val == 0x99) { /* gc0307 (?) */
- PDEBUG(D_PROBE, "Sensor gc0307");
- sd->sensor = SENSOR_GC0307;
- return;
- }
-
- /* check po2030n */
- reg_w1(gspca_dev, 0x17, 0x62);
- reg_w1(gspca_dev, 0x01, 0x0a);
- sd->i2c_addr = 0x6e;
- i2c_r(gspca_dev, 0x00, 2);
- val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
- reg_w1(gspca_dev, 0x01, 0x29);
- reg_w1(gspca_dev, 0x17, 0x42);
- if (gspca_dev->usb_err < 0)
- return;
- if (val == 0x2030) {
- PDEBUG(D_PROBE, "Sensor po2030n");
-/* sd->sensor = SENSOR_PO2030N; */
- } else {
- pr_err("Unknown sensor ID %04x\n", val);
- }
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
-
- sd->bridge = id->driver_info >> 16;
- sd->sensor = id->driver_info >> 8;
- sd->flags = id->driver_info;
-
- cam = &gspca_dev->cam;
- if (sd->sensor == SENSOR_ADCM1700) {
- cam->cam_mode = cif_mode;
- cam->nmodes = ARRAY_SIZE(cif_mode);
- } else {
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- }
- cam->npkt = 24; /* 24 packets per ISOC message */
- cam->ctrls = sd->ctrls;
-
- sd->ag_cnt = -1;
- sd->quality = QUALITY_DEF;
-
- INIT_WORK(&sd->work, qual_upd);
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- const u8 *sn9c1xx;
- u8 regGpio[] = { 0x29, 0x70 }; /* no audio */
- u8 regF1;
-
- /* setup a selector by bridge */
- reg_w1(gspca_dev, 0xf1, 0x01);
- reg_r(gspca_dev, 0x00, 1);
- reg_w1(gspca_dev, 0xf1, 0x00);
- reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
- regF1 = gspca_dev->usb_buf[0];
- if (gspca_dev->usb_err < 0)
- return gspca_dev->usb_err;
- PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
- if (gspca_dev->audio)
- regGpio[1] |= 0x04; /* with audio */
- switch (sd->bridge) {
- case BRIDGE_SN9C102P:
- case BRIDGE_SN9C105:
- if (regF1 != 0x11)
- return -ENODEV;
- break;
- default:
-/* case BRIDGE_SN9C110: */
-/* case BRIDGE_SN9C120: */
- if (regF1 != 0x12)
- return -ENODEV;
- }
-
- switch (sd->sensor) {
- case SENSOR_MI0360:
- mi0360_probe(gspca_dev);
- break;
- case SENSOR_OV7630:
- ov7630_probe(gspca_dev);
- break;
- case SENSOR_OV7648:
- ov7648_probe(gspca_dev);
- break;
- case SENSOR_PO2030N:
- po2030n_probe(gspca_dev);
- break;
- }
-
- switch (sd->bridge) {
- case BRIDGE_SN9C102P:
- reg_w1(gspca_dev, 0x02, regGpio[1]);
- break;
- default:
- reg_w(gspca_dev, 0x01, regGpio, 2);
- break;
- }
-
- if (sd->sensor == SENSOR_OM6802)
- sd->ctrls[SHARPNESS].def = 0x10;
-
- /* Note we do not disable the sensor clock here (power saving mode),
- as that also disables the button on the cam. */
- reg_w1(gspca_dev, 0xf1, 0x00);
-
- /* set the i2c address */
- sn9c1xx = sn_tb[sd->sensor];
- sd->i2c_addr = sn9c1xx[9];
-
- gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
- if (!(sd->flags & F_ILLUM))
- gspca_dev->ctrl_dis |= (1 << ILLUM);
-
- return gspca_dev->usb_err;
-}
-
-static u32 expo_adjust(struct gspca_dev *gspca_dev,
- u32 expo)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->sensor) {
- case SENSOR_GC0307: {
- int a, b;
-
- /* expo = 0..255 -> a = 19..43 */
- a = 19 + expo * 25 / 256;
- i2c_w1(gspca_dev, 0x68, a);
- a -= 12;
- b = a * a * 4; /* heuristic */
- i2c_w1(gspca_dev, 0x03, b >> 8);
- i2c_w1(gspca_dev, 0x04, b);
- break;
- }
- case SENSOR_HV7131R: {
- u8 Expodoit[] =
- { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
-
- Expodoit[3] = expo >> 16;
- Expodoit[4] = expo >> 8;
- Expodoit[5] = expo;
- i2c_w8(gspca_dev, Expodoit);
- break;
- }
- case SENSOR_MI0360:
- case SENSOR_MI0360B: {
- u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
- { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
- static const u8 doit[] = /* update sensor */
- { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
- static const u8 sensorgo[] = /* sensor on */
- { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
-
- if (expo > 0x0635)
- expo = 0x0635;
- else if (expo < 0x0001)
- expo = 0x0001;
- expoMi[3] = expo >> 8;
- expoMi[4] = expo;
- i2c_w8(gspca_dev, expoMi);
- i2c_w8(gspca_dev, doit);
- i2c_w8(gspca_dev, sensorgo);
- break;
- }
- case SENSOR_MO4000: {
- u8 expoMof[] =
- { 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
- u8 expoMo10[] =
- { 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
- static const u8 gainMo[] =
- { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
-
- if (expo > 0x1fff)
- expo = 0x1fff;
- else if (expo < 0x0001)
- expo = 0x0001;
- expoMof[3] = (expo & 0x03fc) >> 2;
- i2c_w8(gspca_dev, expoMof);
- expoMo10[3] = ((expo & 0x1c00) >> 10)
- | ((expo & 0x0003) << 4);
- i2c_w8(gspca_dev, expoMo10);
- i2c_w8(gspca_dev, gainMo);
- PDEBUG(D_FRAM, "set exposure %d",
- ((expoMo10[3] & 0x07) << 10)
- | (expoMof[3] << 2)
- | ((expoMo10[3] & 0x30) >> 4));
- break;
- }
- case SENSOR_MT9V111: {
- u8 expo_c1[] =
- { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
-
- if (expo > 0x0390)
- expo = 0x0390;
- else if (expo < 0x0060)
- expo = 0x0060;
- expo_c1[3] = expo >> 8;
- expo_c1[4] = expo;
- i2c_w8(gspca_dev, expo_c1);
- break;
- }
- case SENSOR_OM6802: {
- u8 gainOm[] =
- { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
- /* preset AGC - works when AutoExpo = off */
-
- if (expo > 0x03ff)
- expo = 0x03ff;
- if (expo < 0x0001)
- expo = 0x0001;
- gainOm[3] = expo >> 2;
- i2c_w8(gspca_dev, gainOm);
- reg_w1(gspca_dev, 0x96, expo >> 5);
- PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
- break;
- }
- }
- return expo;
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- unsigned int expo;
- int brightness;
- u8 k2;
-
- brightness = sd->ctrls[BRIGHTNESS].val;
- k2 = (brightness - 0x80) >> 2;
- switch (sd->sensor) {
- case SENSOR_ADCM1700:
- if (k2 > 0x1f)
- k2 = 0; /* only positive Y offset */
- break;
- case SENSOR_HV7131R:
- expo = brightness << 12;
- if (expo > 0x002dc6c0)
- expo = 0x002dc6c0;
- else if (expo < 0x02a0)
- expo = 0x02a0;
- sd->exposure = expo_adjust(gspca_dev, expo);
- break;
- case SENSOR_MI0360:
- case SENSOR_MO4000:
- expo = brightness << 4;
- sd->exposure = expo_adjust(gspca_dev, expo);
- break;
- case SENSOR_MI0360B:
- expo = brightness << 2;
- sd->exposure = expo_adjust(gspca_dev, expo);
- break;
- case SENSOR_GC0307:
- expo = brightness;
- sd->exposure = expo_adjust(gspca_dev, expo);
- return; /* don't set the Y offset */
- case SENSOR_MT9V111:
- expo = brightness << 2;
- sd->exposure = expo_adjust(gspca_dev, expo);
- return; /* don't set the Y offset */
- case SENSOR_OM6802:
- expo = brightness << 2;
- sd->exposure = expo_adjust(gspca_dev, expo);
- return; /* Y offset already set */
- }
-
- reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 k2;
- u8 contrast[6];
-
- k2 = sd->ctrls[CONTRAST].val * 37 / (CONTRAST_MAX + 1)
- + 37; /* 37..73 */
- contrast[0] = (k2 + 1) / 2; /* red */
- contrast[1] = 0;
- contrast[2] = k2; /* green */
- contrast[3] = 0;
- contrast[4] = k2 / 5; /* blue */
- contrast[5] = 0;
- reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
-}
-
-static void setcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i, v, colors;
- const s16 *uv;
- u8 reg8a[12]; /* U & V gains */
- static const s16 uv_com[6] = { /* same as reg84 in signed decimal */
- -24, -38, 64, /* UR UG UB */
- 62, -51, -9 /* VR VG VB */
- };
- static const s16 uv_mi0360b[6] = {
- -20, -38, 64, /* UR UG UB */
- 60, -51, -9 /* VR VG VB */
- };
-
- colors = sd->ctrls[COLORS].val;
- if (sd->sensor == SENSOR_MI0360B)
- uv = uv_mi0360b;
- else
- uv = uv_com;
- for (i = 0; i < 6; i++) {
- v = uv[i] * colors / COLORS_DEF;
- reg8a[i * 2] = v;
- reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
- }
- reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
-}
-
-static void setredblue(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_PO2030N) {
- u8 rg1b[] = /* red green1 blue (no g2) */
- {0xc1, 0x6e, 0x16, 0x00, 0x40, 0x00, 0x00, 0x10};
-
- /* 0x40 = normal value = gain x 1 */
- rg1b[3] = sd->ctrls[RED].val * 2;
- rg1b[5] = sd->ctrls[BLUE].val * 2;
- i2c_w8(gspca_dev, rg1b);
- return;
- }
- reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val);
-/* reg_w1(gspca_dev, 0x07, 32); */
- reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val);
-}
-
-static void setgamma(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i, val;
- u8 gamma[17];
- const u8 *gamma_base;
- static const u8 delta[17] = {
- 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
- 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
- };
-
- switch (sd->sensor) {
- case SENSOR_ADCM1700:
- gamma_base = gamma_spec_0;
- break;
- case SENSOR_HV7131R:
- case SENSOR_MI0360B:
- case SENSOR_MT9V111:
- gamma_base = gamma_spec_1;
- break;
- case SENSOR_GC0307:
- gamma_base = gamma_spec_2;
- break;
- case SENSOR_SP80708:
- gamma_base = gamma_spec_3;
- break;
- default:
- gamma_base = gamma_def;
- break;
- }
-
- val = sd->ctrls[GAMMA].val;
- for (i = 0; i < sizeof gamma; i++)
- gamma[i] = gamma_base[i]
- + delta[i] * (val - GAMMA_DEF) / 32;
- reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
-}
-
-static void setexposure(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_PO2030N) {
- u8 rexpo[] = /* 1a: expo H, 1b: expo M */
- {0xa1, 0x6e, 0x1a, 0x00, 0x40, 0x00, 0x00, 0x10};
-
- rexpo[3] = sd->ctrls[EXPOSURE].val >> 8;
- i2c_w8(gspca_dev, rexpo);
- msleep(6);
- rexpo[2] = 0x1b;
- rexpo[3] = sd->ctrls[EXPOSURE].val;
- i2c_w8(gspca_dev, rexpo);
- }
-}
-
-static void setautogain(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (gspca_dev->ctrl_dis & (1 << AUTOGAIN))
- return;
- switch (sd->sensor) {
- case SENSOR_OV7630:
- case SENSOR_OV7648: {
- u8 comb;
-
- if (sd->sensor == SENSOR_OV7630)
- comb = 0xc0;
- else
- comb = 0xa0;
- if (sd->ctrls[AUTOGAIN].val)
- comb |= 0x03;
- i2c_w1(&sd->gspca_dev, 0x13, comb);
- return;
- }
- }
- if (sd->ctrls[AUTOGAIN].val)
- sd->ag_cnt = AG_CNT_START;
- else
- sd->ag_cnt = -1;
-}
-
-static void setgain(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_PO2030N) {
- u8 rgain[] = /* 15: gain */
- {0xa1, 0x6e, 0x15, 0x00, 0x40, 0x00, 0x00, 0x15};
-
- rgain[3] = sd->ctrls[GAIN].val;
- i2c_w8(gspca_dev, rgain);
- }
-}
-
-static void sethvflip(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 comn;
-
- switch (sd->sensor) {
- case SENSOR_HV7131R:
- comn = 0x18; /* clkdiv = 1, ablcen = 1 */
- if (sd->ctrls[VFLIP].val)
- comn |= 0x01;
- i2c_w1(gspca_dev, 0x01, comn); /* sctra */
- break;
- case SENSOR_OV7630:
- comn = 0x02;
- if (!sd->ctrls[VFLIP].val)
- comn |= 0x80;
- i2c_w1(gspca_dev, 0x75, comn);
- break;
- case SENSOR_OV7648:
- comn = 0x06;
- if (sd->ctrls[VFLIP].val)
- comn |= 0x80;
- i2c_w1(gspca_dev, 0x75, comn);
- break;
- case SENSOR_PO2030N:
- /* Reg. 0x1E: Timing Generator Control Register 2 (Tgcontrol2)
- * (reset value: 0x0A)
- * bit7: HM: Horizontal Mirror: 0: disable, 1: enable
- * bit6: VM: Vertical Mirror: 0: disable, 1: enable
- * bit5: ST: Shutter Selection: 0: electrical, 1: mechanical
- * bit4: FT: Single Frame Transfer: 0: disable, 1: enable
- * bit3-0: X
- */
- comn = 0x0a;
- if (sd->ctrls[HFLIP].val)
- comn |= 0x80;
- if (sd->ctrls[VFLIP].val)
- comn |= 0x40;
- i2c_w1(&sd->gspca_dev, 0x1e, comn);
- break;
- }
-}
-
-static void setsharpness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val);
-}
-
-static void setillum(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (gspca_dev->ctrl_dis & (1 << ILLUM))
- return;
- switch (sd->sensor) {
- case SENSOR_ADCM1700:
- reg_w1(gspca_dev, 0x02, /* gpio */
- sd->ctrls[ILLUM].val ? 0x64 : 0x60);
- break;
- case SENSOR_MT9V111:
- reg_w1(gspca_dev, 0x02,
- sd->ctrls[ILLUM].val ? 0x77 : 0x74);
-/* should have been: */
-/* 0x55 : 0x54); * 370i */
-/* 0x66 : 0x64); * Clip */
- break;
- }
-}
-
-static void setfreq(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (gspca_dev->ctrl_dis & (1 << FREQ))
- return;
- if (sd->sensor == SENSOR_OV7660) {
- u8 com8;
-
- com8 = 0xdf; /* auto gain/wb/expo */
- switch (sd->ctrls[FREQ].val) {
- case 0: /* Banding filter disabled */
- i2c_w1(gspca_dev, 0x13, com8 | 0x20);
- break;
- case 1: /* 50 hz */
- i2c_w1(gspca_dev, 0x13, com8);
- i2c_w1(gspca_dev, 0x3b, 0x0a);
- break;
- case 2: /* 60 hz */
- i2c_w1(gspca_dev, 0x13, com8);
- i2c_w1(gspca_dev, 0x3b, 0x02);
- break;
- }
- } else {
- u8 reg2a = 0, reg2b = 0, reg2d = 0;
-
- /* Get reg2a / reg2d base values */
- switch (sd->sensor) {
- case SENSOR_OV7630:
- reg2a = 0x08;
- reg2d = 0x01;
- break;
- case SENSOR_OV7648:
- reg2a = 0x11;
- reg2d = 0x81;
- break;
- }
-
- switch (sd->ctrls[FREQ].val) {
- case 0: /* Banding filter disabled */
- break;
- case 1: /* 50 hz (filter on and framerate adj) */
- reg2a |= 0x80;
- reg2b = 0xac;
- reg2d |= 0x04;
- break;
- case 2: /* 60 hz (filter on, no framerate adj) */
- reg2a |= 0x80;
- reg2d |= 0x04;
- break;
- }
- i2c_w1(gspca_dev, 0x2a, reg2a);
- i2c_w1(gspca_dev, 0x2b, reg2b);
- i2c_w1(gspca_dev, 0x2d, reg2d);
- }
-}
-
-static void setjpegqual(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- jpeg_set_qual(sd->jpeg_hdr, sd->quality);
-#if USB_BUF_SZ < 64
-#error "No room enough in usb_buf for quantization table"
-#endif
- memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
- usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x08,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- 0x0100, 0,
- gspca_dev->usb_buf, 64,
- 500);
- memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
- usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x08,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- 0x0140, 0,
- gspca_dev->usb_buf, 64,
- 500);
-
- sd->reg18 ^= 0x40;
- reg_w1(gspca_dev, 0x18, sd->reg18);
-}
-
-/* JPEG quality update */
-/* This function is executed from a work queue. */
-static void qual_upd(struct work_struct *work)
-{
- struct sd *sd = container_of(work, struct sd, work);
- struct gspca_dev *gspca_dev = &sd->gspca_dev;
-
- mutex_lock(&gspca_dev->usb_lock);
- PDEBUG(D_STREAM, "qual_upd %d%%", sd->quality);
- setjpegqual(gspca_dev);
- mutex_unlock(&gspca_dev->usb_lock);
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- u8 reg01, reg17;
- u8 reg0102[2];
- const u8 *sn9c1xx;
- const u8 (*init)[8];
- const u8 *reg9a;
- int mode;
- static const u8 reg9a_def[] =
- {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
- static const u8 reg9a_spec[] =
- {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
- static const u8 regd4[] = {0x60, 0x00, 0x00};
- static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
- static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
- static const u8 CA_adcm1700[] =
- { 0x14, 0xec, 0x0a, 0xf6 };
- static const u8 CA_po2030n[] =
- { 0x1e, 0xe2, 0x14, 0xec };
- static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
- static const u8 CE_gc0307[] =
- { 0x32, 0xce, 0x2d, 0xd3 };
- static const u8 CE_ov76xx[] =
- { 0x32, 0xdd, 0x32, 0xdd };
- static const u8 CE_po2030n[] =
- { 0x14, 0xe7, 0x1e, 0xdd };
-
- /* create the JPEG header */
- jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
- 0x21); /* JPEG 422 */
-
- /* initialize the bridge */
- sn9c1xx = sn_tb[sd->sensor];
-
- /* sensor clock already enabled in sd_init */
- /* reg_w1(gspca_dev, 0xf1, 0x00); */
- reg01 = sn9c1xx[1];
- if (sd->flags & F_PDN_INV)
- reg01 ^= S_PDN_INV; /* power down inverted */
- reg_w1(gspca_dev, 0x01, reg01);
-
- /* configure gpio */
- reg0102[0] = reg01;
- reg0102[1] = sn9c1xx[2];
- if (gspca_dev->audio)
- reg0102[1] |= 0x04; /* keep the audio connection */
- reg_w(gspca_dev, 0x01, reg0102, 2);
- reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
- reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
- switch (sd->sensor) {
- case SENSOR_GC0307:
- case SENSOR_OV7660:
- case SENSOR_PO1030:
- case SENSOR_PO2030N:
- case SENSOR_SOI768:
- case SENSOR_SP80708:
- reg9a = reg9a_spec;
- break;
- default:
- reg9a = reg9a_def;
- break;
- }
- reg_w(gspca_dev, 0x9a, reg9a, 6);
-
- reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
-
- reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
-
- reg17 = sn9c1xx[0x17];
- switch (sd->sensor) {
- case SENSOR_GC0307:
- msleep(50); /*fixme: is it useful? */
- break;
- case SENSOR_OM6802:
- msleep(10);
- reg_w1(gspca_dev, 0x02, 0x73);
- reg17 |= SEN_CLK_EN;
- reg_w1(gspca_dev, 0x17, reg17);
- reg_w1(gspca_dev, 0x01, 0x22);
- msleep(100);
- reg01 = SCL_SEL_OD | S_PDN_INV;
- reg17 &= ~MCK_SIZE_MASK;
- reg17 |= 0x04; /* clock / 4 */
- break;
- }
- reg01 |= SYS_SEL_48M;
- reg_w1(gspca_dev, 0x01, reg01);
- reg17 |= SEN_CLK_EN;
- reg_w1(gspca_dev, 0x17, reg17);
- reg01 &= ~S_PWR_DN; /* sensor power on */
- reg_w1(gspca_dev, 0x01, reg01);
- reg01 &= ~SCL_SEL_OD; /* remove open-drain mode */
- reg_w1(gspca_dev, 0x01, reg01);
-
- switch (sd->sensor) {
- case SENSOR_HV7131R:
- hv7131r_probe(gspca_dev); /*fixme: is it useful? */
- break;
- case SENSOR_OM6802:
- msleep(10);
- reg_w1(gspca_dev, 0x01, reg01);
- i2c_w8(gspca_dev, om6802_init0[0]);
- i2c_w8(gspca_dev, om6802_init0[1]);
- msleep(15);
- reg_w1(gspca_dev, 0x02, 0x71);
- msleep(150);
- break;
- case SENSOR_SP80708:
- msleep(100);
- reg_w1(gspca_dev, 0x02, 0x62);
- break;
- }
-
- /* initialize the sensor */
- i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
-
- reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
- reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
- reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
- reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
- reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
- if (sd->sensor == SENSOR_ADCM1700) {
- reg_w1(gspca_dev, 0xd2, 0x3a); /* AE_H_SIZE = 116 */
- reg_w1(gspca_dev, 0xd3, 0x30); /* AE_V_SIZE = 96 */
- } else {
- reg_w1(gspca_dev, 0xd2, 0x6a); /* AE_H_SIZE = 212 */
- reg_w1(gspca_dev, 0xd3, 0x50); /* AE_V_SIZE = 160 */
- }
- reg_w1(gspca_dev, 0xc6, 0x00);
- reg_w1(gspca_dev, 0xc7, 0x00);
- if (sd->sensor == SENSOR_ADCM1700) {
- reg_w1(gspca_dev, 0xc8, 0x2c); /* AW_H_STOP = 352 */
- reg_w1(gspca_dev, 0xc9, 0x24); /* AW_V_STOP = 288 */
- } else {
- reg_w1(gspca_dev, 0xc8, 0x50); /* AW_H_STOP = 640 */
- reg_w1(gspca_dev, 0xc9, 0x3c); /* AW_V_STOP = 480 */
- }
- reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
- switch (sd->sensor) {
- case SENSOR_OM6802:
-/* case SENSOR_OV7648: * fixme: sometimes */
- break;
- default:
- reg17 |= DEF_EN;
- break;
- }
- reg_w1(gspca_dev, 0x17, reg17);
-
- reg_w1(gspca_dev, 0x05, 0x00); /* red */
- reg_w1(gspca_dev, 0x07, 0x00); /* green */
- reg_w1(gspca_dev, 0x06, 0x00); /* blue */
- reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
-
- setgamma(gspca_dev);
-
-/*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
- for (i = 0; i < 8; i++)
- reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
- switch (sd->sensor) {
- case SENSOR_ADCM1700:
- case SENSOR_OV7660:
- case SENSOR_SP80708:
- reg_w1(gspca_dev, 0x9a, 0x05);
- break;
- case SENSOR_GC0307:
- case SENSOR_MT9V111:
- case SENSOR_MI0360B:
- reg_w1(gspca_dev, 0x9a, 0x07);
- break;
- case SENSOR_OV7630:
- case SENSOR_OV7648:
- reg_w1(gspca_dev, 0x9a, 0x0a);
- break;
- case SENSOR_PO2030N:
- case SENSOR_SOI768:
- reg_w1(gspca_dev, 0x9a, 0x06);
- break;
- default:
- reg_w1(gspca_dev, 0x9a, 0x08);
- break;
- }
- setsharpness(gspca_dev);
-
- reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
- reg_w1(gspca_dev, 0x05, 0x20); /* red */
- reg_w1(gspca_dev, 0x07, 0x20); /* green */
- reg_w1(gspca_dev, 0x06, 0x20); /* blue */
-
- init = NULL;
- mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
- reg01 |= SYS_SEL_48M | V_TX_EN;
- reg17 &= ~MCK_SIZE_MASK;
- reg17 |= 0x02; /* clock / 2 */
- switch (sd->sensor) {
- case SENSOR_ADCM1700:
- init = adcm1700_sensor_param1;
- break;
- case SENSOR_GC0307:
- init = gc0307_sensor_param1;
- break;
- case SENSOR_HV7131R:
- case SENSOR_MI0360:
- if (!mode)
- reg01 &= ~SYS_SEL_48M; /* 640x480: clk 24Mhz */
- reg17 &= ~MCK_SIZE_MASK;
- reg17 |= 0x01; /* clock / 1 */
- break;
- case SENSOR_MI0360B:
- init = mi0360b_sensor_param1;
- break;
- case SENSOR_MO4000:
- if (mode) { /* if 320x240 */
- reg01 &= ~SYS_SEL_48M; /* clk 24Mz */
- reg17 &= ~MCK_SIZE_MASK;
- reg17 |= 0x01; /* clock / 1 */
- }
- break;
- case SENSOR_MT9V111:
- init = mt9v111_sensor_param1;
- break;
- case SENSOR_OM6802:
- init = om6802_sensor_param1;
- if (!mode) { /* if 640x480 */
- reg17 &= ~MCK_SIZE_MASK;
- reg17 |= 0x04; /* clock / 4 */
- } else {
- reg01 &= ~SYS_SEL_48M; /* clk 24Mz */
- reg17 &= ~MCK_SIZE_MASK;
- reg17 |= 0x02; /* clock / 2 */
- }
- break;
- case SENSOR_OV7630:
- init = ov7630_sensor_param1;
- break;
- case SENSOR_OV7648:
- init = ov7648_sensor_param1;
- reg17 &= ~MCK_SIZE_MASK;
- reg17 |= 0x01; /* clock / 1 */
- break;
- case SENSOR_OV7660:
- init = ov7660_sensor_param1;
- break;
- case SENSOR_PO1030:
- init = po1030_sensor_param1;
- break;
- case SENSOR_PO2030N:
- init = po2030n_sensor_param1;
- break;
- case SENSOR_SOI768:
- init = soi768_sensor_param1;
- break;
- case SENSOR_SP80708:
- init = sp80708_sensor_param1;
- break;
- }
-
- /* more sensor initialization - param1 */
- if (init != NULL) {
- i2c_w_seq(gspca_dev, init);
-/* init = NULL; */
- }
-
- reg_w(gspca_dev, 0xc0, C0, 6);
- switch (sd->sensor) {
- case SENSOR_ADCM1700:
- case SENSOR_GC0307:
- case SENSOR_SOI768:
- reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
- break;
- case SENSOR_PO2030N:
- reg_w(gspca_dev, 0xca, CA_po2030n, 4);
- break;
- default:
- reg_w(gspca_dev, 0xca, CA, 4);
- break;
- }
- switch (sd->sensor) {
- case SENSOR_ADCM1700:
- case SENSOR_OV7630:
- case SENSOR_OV7648:
- case SENSOR_OV7660:
- case SENSOR_SOI768:
- reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
- break;
- case SENSOR_GC0307:
- reg_w(gspca_dev, 0xce, CE_gc0307, 4);
- break;
- case SENSOR_PO2030N:
- reg_w(gspca_dev, 0xce, CE_po2030n, 4);
- break;
- default:
- reg_w(gspca_dev, 0xce, CE, 4);
- /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
- break;
- }
-
- /* here change size mode 0 -> VGA; 1 -> CIF */
- sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
- reg_w1(gspca_dev, 0x18, sd->reg18);
- setjpegqual(gspca_dev);
-
- reg_w1(gspca_dev, 0x17, reg17);
- reg_w1(gspca_dev, 0x01, reg01);
- sd->reg01 = reg01;
- sd->reg17 = reg17;
-
- sethvflip(gspca_dev);
- setbrightness(gspca_dev);
- setcontrast(gspca_dev);
- setcolors(gspca_dev);
- setautogain(gspca_dev);
- if (!(gspca_dev->ctrl_inac & ((1 << EXPOSURE) | (1 << GAIN)))) {
- setexposure(gspca_dev);
- setgain(gspca_dev);
- }
- setfreq(gspca_dev);
-
- sd->pktsz = sd->npkt = 0;
- sd->nchg = sd->short_mark = 0;
- sd->work_thread = create_singlethread_workqueue(MODULE_NAME);
-
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- static const u8 stophv7131[] =
- { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
- static const u8 stopmi0360[] =
- { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
- static const u8 stopov7648[] =
- { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
- static const u8 stopsoi768[] =
- { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
- u8 reg01;
- u8 reg17;
-
- reg01 = sd->reg01;
- reg17 = sd->reg17 & ~SEN_CLK_EN;
- switch (sd->sensor) {
- case SENSOR_ADCM1700:
- case SENSOR_GC0307:
- case SENSOR_PO2030N:
- case SENSOR_SP80708:
- reg01 |= LED;
- reg_w1(gspca_dev, 0x01, reg01);
- reg01 &= ~(LED | V_TX_EN);
- reg_w1(gspca_dev, 0x01, reg01);
-/* reg_w1(gspca_dev, 0x02, 0x??); * LED off ? */
- break;
- case SENSOR_HV7131R:
- reg01 &= ~V_TX_EN;
- reg_w1(gspca_dev, 0x01, reg01);
- i2c_w8(gspca_dev, stophv7131);
- break;
- case SENSOR_MI0360:
- case SENSOR_MI0360B:
- reg01 &= ~V_TX_EN;
- reg_w1(gspca_dev, 0x01, reg01);
-/* reg_w1(gspca_dev, 0x02, 0x40); * LED off ? */
- i2c_w8(gspca_dev, stopmi0360);
- break;
- case SENSOR_MT9V111:
- case SENSOR_OM6802:
- case SENSOR_PO1030:
- reg01 &= ~V_TX_EN;
- reg_w1(gspca_dev, 0x01, reg01);
- break;
- case SENSOR_OV7630:
- case SENSOR_OV7648:
- reg01 &= ~V_TX_EN;
- reg_w1(gspca_dev, 0x01, reg01);
- i2c_w8(gspca_dev, stopov7648);
- break;
- case SENSOR_OV7660:
- reg01 &= ~V_TX_EN;
- reg_w1(gspca_dev, 0x01, reg01);
- break;
- case SENSOR_SOI768:
- i2c_w8(gspca_dev, stopsoi768);
- break;
- }
-
- reg01 |= SCL_SEL_OD;
- reg_w1(gspca_dev, 0x01, reg01);
- reg01 |= S_PWR_DN; /* sensor power down */
- reg_w1(gspca_dev, 0x01, reg01);
- reg_w1(gspca_dev, 0x17, reg17);
- reg01 &= ~SYS_SEL_48M; /* clock 24MHz */
- reg_w1(gspca_dev, 0x01, reg01);
- reg01 |= LED;
- reg_w1(gspca_dev, 0x01, reg01);
- /* Don't disable sensor clock as that disables the button on the cam */
- /* reg_w1(gspca_dev, 0xf1, 0x01); */
-}
-
-/* called on streamoff with alt==0 and on disconnect */
-/* the usb_lock is held at entry - restore on exit */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->work_thread != NULL) {
- mutex_unlock(&gspca_dev->usb_lock);
- destroy_workqueue(sd->work_thread);
- mutex_lock(&gspca_dev->usb_lock);
- sd->work_thread = NULL;
- }
-}
-
-#define WANT_REGULAR_AUTOGAIN
-#include "autogain_functions.h"
-
-static void do_autogain(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int delta;
- int expotimes;
- u8 luma_mean = 130;
- u8 luma_delta = 20;
-
- /* Thanks S., without your advice, autobright should not work :) */
- if (sd->ag_cnt < 0)
- return;
- if (--sd->ag_cnt >= 0)
- return;
- sd->ag_cnt = AG_CNT_START;
-
- delta = atomic_read(&sd->avg_lum);
- PDEBUG(D_FRAM, "mean lum %d", delta);
-
- if (sd->sensor == SENSOR_PO2030N) {
- auto_gain_n_exposure(gspca_dev, delta, luma_mean, luma_delta,
- 15, 1024);
- return;
- }
-
- if (delta < luma_mean - luma_delta ||
- delta > luma_mean + luma_delta) {
- switch (sd->sensor) {
- case SENSOR_GC0307:
- expotimes = sd->exposure;
- expotimes += (luma_mean - delta) >> 6;
- if (expotimes < 0)
- expotimes = 0;
- sd->exposure = expo_adjust(gspca_dev,
- (unsigned int) expotimes);
- break;
- case SENSOR_HV7131R:
- expotimes = sd->exposure >> 8;
- expotimes += (luma_mean - delta) >> 4;
- if (expotimes < 0)
- expotimes = 0;
- sd->exposure = expo_adjust(gspca_dev,
- (unsigned int) (expotimes << 8));
- break;
- case SENSOR_OM6802:
- case SENSOR_MT9V111:
- expotimes = sd->exposure;
- expotimes += (luma_mean - delta) >> 2;
- if (expotimes < 0)
- expotimes = 0;
- sd->exposure = expo_adjust(gspca_dev,
- (unsigned int) expotimes);
- setredblue(gspca_dev);
- break;
- default:
-/* case SENSOR_MO4000: */
-/* case SENSOR_MI0360: */
-/* case SENSOR_MI0360B: */
- expotimes = sd->exposure;
- expotimes += (luma_mean - delta) >> 6;
- if (expotimes < 0)
- expotimes = 0;
- sd->exposure = expo_adjust(gspca_dev,
- (unsigned int) expotimes);
- setredblue(gspca_dev);
- break;
- }
- }
-}
-
-/* set the average luminosity from an isoc marker */
-static void set_lum(struct sd *sd,
- u8 *data)
-{
- int avg_lum;
-
- /* w0 w1 w2
- * w3 w4 w5
- * w6 w7 w8
- */
- avg_lum = (data[27] << 8) + data[28] /* w3 */
-
- + (data[31] << 8) + data[32] /* w5 */
-
- + (data[23] << 8) + data[24] /* w1 */
-
- + (data[35] << 8) + data[36] /* w7 */
-
- + (data[29] << 10) + (data[30] << 2); /* w4 * 4 */
- avg_lum >>= 10;
- atomic_set(&sd->avg_lum, avg_lum);
-}
-
-/* scan the URB packets */
-/* This function is run at interrupt level. */
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i, new_qual;
-
- /*
- * A frame ends on the marker
- * ff ff 00 c4 c4 96 ..
- * which is 62 bytes long and is followed by various information
- * including statuses and luminosity.
- *
- * A marker may be splitted on two packets.
- *
- * The 6th byte of a marker contains the bits:
- * 0x08: USB full
- * 0xc0: frame sequence
- * When the bit 'USB full' is set, the frame must be discarded;
- * this is also the case when the 2 bytes before the marker are
- * not the JPEG end of frame ('ff d9').
- */
-
- /* count the packets and their size */
- sd->npkt++;
- sd->pktsz += len;
-
-/*fixme: assumption about the following code:
- * - there can be only one marker in a packet
- */
-
- /* skip the remaining bytes of a short marker */
- i = sd->short_mark;
- if (i != 0) {
- sd->short_mark = 0;
- if (i < 0 /* if 'ff' at end of previous packet */
- && data[0] == 0xff
- && data[1] == 0x00)
- goto marker_found;
- if (data[0] == 0xff && data[1] == 0xff) {
- i = 0;
- goto marker_found;
- }
- len -= i;
- if (len <= 0)
- return;
- data += i;
- }
-
- /* search backwards if there is a marker in the packet */
- for (i = len - 1; --i >= 0; ) {
- if (data[i] != 0xff) {
- i--;
- continue;
- }
- if (data[i + 1] == 0xff) {
-
- /* (there may be 'ff ff' inside a marker) */
- if (i + 2 >= len || data[i + 2] == 0x00)
- goto marker_found;
- }
- }
-
- /* no marker found */
- /* add the JPEG header if first fragment */
- if (data[len - 1] == 0xff)
- sd->short_mark = -1;
- if (gspca_dev->last_packet_type == LAST_PACKET)
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sd->jpeg_hdr, JPEG_HDR_SZ);
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
- return;
-
- /* marker found */
- /* if some error, discard the frame and decrease the quality */
-marker_found:
- new_qual = 0;
- if (i > 2) {
- if (data[i - 2] != 0xff || data[i - 1] != 0xd9) {
- gspca_dev->last_packet_type = DISCARD_PACKET;
- new_qual = -3;
- }
- } else if (i + 6 < len) {
- if (data[i + 6] & 0x08) {
- gspca_dev->last_packet_type = DISCARD_PACKET;
- new_qual = -5;
- }
- }
-
- gspca_frame_add(gspca_dev, LAST_PACKET, data, i);
-
- /* compute the filling rate and a new JPEG quality */
- if (new_qual == 0) {
- int r;
-
- r = (sd->pktsz * 100) /
- (sd->npkt *
- gspca_dev->urb[0]->iso_frame_desc[0].length);
- if (r >= 85)
- new_qual = -3;
- else if (r < 75)
- new_qual = 2;
- }
- if (new_qual != 0) {
- sd->nchg += new_qual;
- if (sd->nchg < -6 || sd->nchg >= 12) {
- sd->nchg = 0;
- new_qual += sd->quality;
- if (new_qual < QUALITY_MIN)
- new_qual = QUALITY_MIN;
- else if (new_qual > QUALITY_MAX)
- new_qual = QUALITY_MAX;
- if (new_qual != sd->quality) {
- sd->quality = new_qual;
- queue_work(sd->work_thread, &sd->work);
- }
- }
- } else {
- sd->nchg = 0;
- }
- sd->pktsz = sd->npkt = 0;
-
- /* if the marker is smaller than 62 bytes,
- * memorize the number of bytes to skip in the next packet */
- if (i + 62 > len) { /* no more usable data */
- sd->short_mark = i + 62 - len;
- return;
- }
- if (sd->ag_cnt >= 0)
- set_lum(sd, data + i);
-
- /* if more data, start a new frame */
- i += 62;
- if (i < len) {
- data += i;
- len -= i;
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sd->jpeg_hdr, JPEG_HDR_SZ);
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
- }
-}
-
-static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->ctrls[AUTOGAIN].val = val;
- if (val)
- gspca_dev->ctrl_inac |= (1 << EXPOSURE) | (1 << GAIN);
- else
- gspca_dev->ctrl_inac &= ~(1 << EXPOSURE) & ~(1 << GAIN);
- if (gspca_dev->streaming)
- setautogain(gspca_dev);
- return gspca_dev->usb_err;
-}
-
-static int sd_querymenu(struct gspca_dev *gspca_dev,
- struct v4l2_querymenu *menu)
-{
- switch (menu->id) {
- case V4L2_CID_POWER_LINE_FREQUENCY:
- switch (menu->index) {
- case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
- strcpy((char *) menu->name, "NoFliker");
- return 0;
- case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
- strcpy((char *) menu->name, "50 Hz");
- return 0;
- case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
- strcpy((char *) menu->name, "60 Hz");
- return 0;
- }
- break;
- }
- return -EINVAL;
-}
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
-static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* interrupt packet data */
- int len) /* interrupt packet length */
-{
- int ret = -EINVAL;
-
- if (len == 1 && data[0] == 1) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
- input_sync(gspca_dev->input_dev);
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
- input_sync(gspca_dev->input_dev);
- ret = 0;
- }
-
- return ret;
-}
-#endif
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .ctrls = sd_ctrls,
- .nctrls = NCTRLS,
- .config = sd_config,
- .init = sd_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
- .dq_callback = do_autogain,
- .querymenu = sd_querymenu,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .int_pkt_scan = sd_int_pkt_scan,
-#endif
-};
-
-/* -- module initialisation -- */
-#define BS(bridge, sensor) \
- .driver_info = (BRIDGE_ ## bridge << 16) \
- | (SENSOR_ ## sensor << 8)
-#define BSF(bridge, sensor, flags) \
- .driver_info = (BRIDGE_ ## bridge << 16) \
- | (SENSOR_ ## sensor << 8) \
- | (flags)
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x0458, 0x7025), BSF(SN9C120, MI0360B, F_PDN_INV)},
- {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
- {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, F_PDN_INV)},
- {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, F_PDN_INV)},
- {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
- {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
- {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
- {USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
- {USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
-/* {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
- {USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
-/* {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
-/* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
- {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
-/* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
- {USB_DEVICE(0x0c45, 0x60c0), BSF(SN9C105, MI0360, F_ILLUM)},
- /* or MT9V111 */
-/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
-/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
-/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
- {USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)},
- {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
-/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
-/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
-/* {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
- {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
- {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
- {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
- {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/
- {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, /* /GC0305*/
-/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
- {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/
- {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/
- {USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)}, /*sn9c128*/
- {USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)}, /*sn9c128*/
-/* {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
-/* {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
-/* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
- {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/
-/*bw600.inf:*/
- {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/
- {USB_DEVICE(0x0c45, 0x612b), BS(SN9C110, ADCM1700)},
- {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
- {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
-/* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
- {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
- /* or MT9V111 / MI0360B */
-/* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
- {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
- {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
- {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
- {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
- {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
- {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/
- /* or GC0305 / GC0307 */
- {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
- {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
- {USB_DEVICE(0x0c45, 0x614a), BSF(SN9C120, ADCM1700, F_ILLUM)},
-/* {USB_DEVICE(0x0c45, 0x614c), BS(SN9C120, GC0306)}, */ /*sn9c120b*/
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/spca1528.c b/drivers/media/video/gspca/spca1528.c
deleted file mode 100644
index 14d635277d7..00000000000
--- a/drivers/media/video/gspca/spca1528.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * spca1528 subdriver
- *
- * Copyright (C) 2010-2011 Jean-Francois Moine (http://moinejf.free.fr)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "spca1528"
-
-#include "gspca.h"
-#include "jpeg.h"
-
-MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
-MODULE_DESCRIPTION("SPCA1528 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- u8 pkt_seq;
-
- u8 jpeg_hdr[JPEG_HDR_SZ];
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
-/* (does not work correctly)
- {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 5 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 3},
-*/
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 4 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
-};
-
-/* read <len> bytes to gspca usb_buf */
-static void reg_r(struct gspca_dev *gspca_dev,
- u8 req,
- u16 index,
- int len)
-{
-#if USB_BUF_SZ < 64
-#error "USB buffer too small"
-#endif
- struct usb_device *dev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0000, /* value */
- index,
- gspca_dev->usb_buf, len,
- 500);
- PDEBUG(D_USBI, "GET %02x 0000 %04x %02x", req, index,
- gspca_dev->usb_buf[0]);
- if (ret < 0) {
- pr_err("reg_r err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void reg_w(struct gspca_dev *gspca_dev,
- u8 req,
- u16 value,
- u16 index)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- PDEBUG(D_USBO, "SET %02x %04x %04x", req, value, index);
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index,
- NULL, 0, 500);
- if (ret < 0) {
- pr_err("reg_w err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void reg_wb(struct gspca_dev *gspca_dev,
- u8 req,
- u16 value,
- u16 index,
- u8 byte)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- PDEBUG(D_USBO, "SET %02x %04x %04x %02x", req, value, index, byte);
- gspca_dev->usb_buf[0] = byte;
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index,
- gspca_dev->usb_buf, 1, 500);
- if (ret < 0) {
- pr_err("reg_w err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void wait_status_0(struct gspca_dev *gspca_dev)
-{
- int i, w;
-
- i = 16;
- w = 0;
- do {
- reg_r(gspca_dev, 0x21, 0x0000, 1);
- if (gspca_dev->usb_buf[0] == 0)
- return;
- w += 15;
- msleep(w);
- } while (--i > 0);
- PDEBUG(D_ERR, "wait_status_0 timeout");
- gspca_dev->usb_err = -ETIME;
-}
-
-static void wait_status_1(struct gspca_dev *gspca_dev)
-{
- int i;
-
- i = 10;
- do {
- reg_r(gspca_dev, 0x21, 0x0001, 1);
- msleep(10);
- if (gspca_dev->usb_buf[0] == 1) {
- reg_wb(gspca_dev, 0x21, 0x0000, 0x0001, 0x00);
- reg_r(gspca_dev, 0x21, 0x0001, 1);
- return;
- }
- } while (--i > 0);
- PDEBUG(D_ERR, "wait_status_1 timeout");
- gspca_dev->usb_err = -ETIME;
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_wb(gspca_dev, 0xc0, 0x0000, 0x00c0, val);
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_wb(gspca_dev, 0xc1, 0x0000, 0x00c1, val);
-}
-
-static void sethue(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_wb(gspca_dev, 0xc2, 0x0000, 0x0000, val);
-}
-
-static void setcolor(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_wb(gspca_dev, 0xc3, 0x0000, 0x00c3, val);
-}
-
-static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_wb(gspca_dev, 0xc4, 0x0000, 0x00c4, val);
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- gspca_dev->cam.cam_mode = vga_mode;
- gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
- gspca_dev->cam.npkt = 128; /* number of packets per ISOC message */
- /*fixme: 256 in ms-win traces*/
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- reg_w(gspca_dev, 0x00, 0x0001, 0x2067);
- reg_w(gspca_dev, 0x00, 0x00d0, 0x206b);
- reg_w(gspca_dev, 0x00, 0x0000, 0x206c);
- reg_w(gspca_dev, 0x00, 0x0001, 0x2069);
- msleep(8);
- reg_w(gspca_dev, 0x00, 0x00c0, 0x206b);
- reg_w(gspca_dev, 0x00, 0x0000, 0x206c);
- reg_w(gspca_dev, 0x00, 0x0001, 0x2069);
-
- reg_r(gspca_dev, 0x20, 0x0000, 1);
- reg_r(gspca_dev, 0x20, 0x0000, 5);
- reg_r(gspca_dev, 0x23, 0x0000, 64);
- PDEBUG(D_PROBE, "%s%s", &gspca_dev->usb_buf[0x1c],
- &gspca_dev->usb_buf[0x30]);
- reg_r(gspca_dev, 0x23, 0x0001, 64);
- return gspca_dev->usb_err;
-}
-
-/* function called at start time before URB creation */
-static int sd_isoc_init(struct gspca_dev *gspca_dev)
-{
- u8 mode;
-
- reg_r(gspca_dev, 0x00, 0x2520, 1);
- wait_status_0(gspca_dev);
- reg_w(gspca_dev, 0xc5, 0x0003, 0x0000);
- wait_status_1(gspca_dev);
-
- wait_status_0(gspca_dev);
- mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
- reg_wb(gspca_dev, 0x25, 0x0000, 0x0004, mode);
- reg_r(gspca_dev, 0x25, 0x0004, 1);
- reg_wb(gspca_dev, 0x27, 0x0000, 0x0000, 0x06); /* 420 */
- reg_r(gspca_dev, 0x27, 0x0000, 1);
-
-/* not useful..
- gspca_dev->alt = 4; * use alternate setting 3 */
-
- return gspca_dev->usb_err;
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* initialize the JPEG header */
- jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
- 0x22); /* JPEG 411 */
-
- /* the JPEG quality shall be 85% */
- jpeg_set_qual(sd->jpeg_hdr, 85);
-
- reg_r(gspca_dev, 0x00, 0x2520, 1);
- msleep(8);
-
- /* start the capture */
- wait_status_0(gspca_dev);
- reg_w(gspca_dev, 0x31, 0x0000, 0x0004); /* start request */
- wait_status_1(gspca_dev);
- wait_status_0(gspca_dev);
- msleep(200);
-
- sd->pkt_seq = 0;
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- /* stop the capture */
- wait_status_0(gspca_dev);
- reg_w(gspca_dev, 0x31, 0x0000, 0x0000); /* stop request */
- wait_status_1(gspca_dev);
- wait_status_0(gspca_dev);
-}
-
-/* move a packet adding 0x00 after 0xff */
-static void add_packet(struct gspca_dev *gspca_dev,
- u8 *data,
- int len)
-{
- int i;
-
- i = 0;
- do {
- if (data[i] == 0xff) {
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data, i + 1);
- len -= i;
- data += i;
- *data = 0x00;
- i = 0;
- }
- } while (++i < len);
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
- static const u8 ffd9[] = {0xff, 0xd9};
-
- /* image packets start with:
- * 02 8n
- * with <n> bit:
- * 0x01: even (0) / odd (1) image
- * 0x02: end of image when set
- */
- if (len < 3)
- return; /* empty packet */
- if (*data == 0x02) {
- if (data[1] & 0x02) {
- sd->pkt_seq = !(data[1] & 1);
- add_packet(gspca_dev, data + 2, len - 2);
- gspca_frame_add(gspca_dev, LAST_PACKET,
- ffd9, 2);
- return;
- }
- if ((data[1] & 1) != sd->pkt_seq)
- goto err;
- if (gspca_dev->last_packet_type == LAST_PACKET)
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sd->jpeg_hdr, JPEG_HDR_SZ);
- add_packet(gspca_dev, data + 2, len - 2);
- return;
- }
-err:
- gspca_dev->last_packet_type = DISCARD_PACKET;
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_HUE:
- sethue(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- setcolor(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SHARPNESS:
- setsharpness(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 5);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 8, 1, 1);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_HUE, 0, 255, 1, 0);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0, 8, 1, 1);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SHARPNESS, 0, 255, 1, 0);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .isoc_init = sd_isoc_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x04fc, 0x1528)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- /* the video interface for isochronous transfer is 1 */
- if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
- return -ENODEV;
-
- return gspca_dev_probe2(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
deleted file mode 100644
index 25cb68d0556..00000000000
--- a/drivers/media/video/gspca/spca500.c
+++ /dev/null
@@ -1,990 +0,0 @@
-/*
- * SPCA500 chip based cameras initialization data
- *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "spca500"
-
-#include "gspca.h"
-#include "jpeg.h"
-
-MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
-MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-#define QUALITY 85
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- char subtype;
-#define AgfaCl20 0
-#define AiptekPocketDV 1
-#define BenqDC1016 2
-#define CreativePCCam300 3
-#define DLinkDSC350 4
-#define Gsmartmini 5
-#define IntelPocketPCCamera 6
-#define KodakEZ200 7
-#define LogitechClickSmart310 8
-#define LogitechClickSmart510 9
-#define LogitechTraveler 10
-#define MustekGsmart300 11
-#define Optimedia 12
-#define PalmPixDC85 13
-#define ToptroIndus 14
-
- u8 jpeg_hdr[JPEG_HDR_SZ];
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-
-static const struct v4l2_pix_format sif_mode[] = {
- {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-
-/* Frame packet header offsets for the spca500 */
-#define SPCA500_OFFSET_PADDINGLB 2
-#define SPCA500_OFFSET_PADDINGHB 3
-#define SPCA500_OFFSET_MODE 4
-#define SPCA500_OFFSET_IMGWIDTH 5
-#define SPCA500_OFFSET_IMGHEIGHT 6
-#define SPCA500_OFFSET_IMGMODE 7
-#define SPCA500_OFFSET_QTBLINDEX 8
-#define SPCA500_OFFSET_FRAMSEQ 9
-#define SPCA500_OFFSET_CDSPINFO 10
-#define SPCA500_OFFSET_GPIO 11
-#define SPCA500_OFFSET_AUGPIO 12
-#define SPCA500_OFFSET_DATA 16
-
-
-static const __u16 spca500_visual_defaults[][3] = {
- {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
- * hue (H byte) = 0,
- * saturation/hue enable,
- * brightness/contrast enable.
- */
- {0x00, 0x0000, 0x8167}, /* brightness = 0 */
- {0x00, 0x0020, 0x8168}, /* contrast = 0 */
- {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
- * hue (H byte) = 0, saturation/hue enable,
- * brightness/contrast enable.
- * was 0x0003, now 0x0000.
- */
- {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
- {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
- {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
- {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
- {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
- {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
- {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
- {0x0c, 0x0004, 0x0000},
- /* set interface */
- {}
-};
-static const __u16 Clicksmart510_defaults[][3] = {
- {0x00, 0x00, 0x8211},
- {0x00, 0x01, 0x82c0},
- {0x00, 0x10, 0x82cb},
- {0x00, 0x0f, 0x800d},
- {0x00, 0x82, 0x8225},
- {0x00, 0x21, 0x8228},
- {0x00, 0x00, 0x8203},
- {0x00, 0x00, 0x8204},
- {0x00, 0x08, 0x8205},
- {0x00, 0xf8, 0x8206},
- {0x00, 0x28, 0x8207},
- {0x00, 0xa0, 0x8208},
- {0x00, 0x08, 0x824a},
- {0x00, 0x08, 0x8214},
- {0x00, 0x80, 0x82c1},
- {0x00, 0x00, 0x82c2},
- {0x00, 0x00, 0x82ca},
- {0x00, 0x80, 0x82c1},
- {0x00, 0x04, 0x82c2},
- {0x00, 0x00, 0x82ca},
- {0x00, 0xfc, 0x8100},
- {0x00, 0xfc, 0x8105},
- {0x00, 0x30, 0x8101},
- {0x00, 0x00, 0x8102},
- {0x00, 0x00, 0x8103},
- {0x00, 0x66, 0x8107},
- {0x00, 0x00, 0x816b},
- {0x00, 0x00, 0x8155},
- {0x00, 0x01, 0x8156},
- {0x00, 0x60, 0x8157},
- {0x00, 0x40, 0x8158},
- {0x00, 0x0a, 0x8159},
- {0x00, 0x06, 0x815a},
- {0x00, 0x00, 0x813f},
- {0x00, 0x00, 0x8200},
- {0x00, 0x19, 0x8201},
- {0x00, 0x00, 0x82c1},
- {0x00, 0xa0, 0x82c2},
- {0x00, 0x00, 0x82ca},
- {0x00, 0x00, 0x8117},
- {0x00, 0x00, 0x8118},
- {0x00, 0x65, 0x8119},
- {0x00, 0x00, 0x811a},
- {0x00, 0x00, 0x811b},
- {0x00, 0x55, 0x811c},
- {0x00, 0x65, 0x811d},
- {0x00, 0x55, 0x811e},
- {0x00, 0x16, 0x811f},
- {0x00, 0x19, 0x8120},
- {0x00, 0x80, 0x8103},
- {0x00, 0x83, 0x816b},
- {0x00, 0x25, 0x8168},
- {0x00, 0x01, 0x820f},
- {0x00, 0xff, 0x8115},
- {0x00, 0x48, 0x8116},
- {0x00, 0x50, 0x8151},
- {0x00, 0x40, 0x8152},
- {0x00, 0x78, 0x8153},
- {0x00, 0x40, 0x8154},
- {0x00, 0x00, 0x8167},
- {0x00, 0x20, 0x8168},
- {0x00, 0x00, 0x816a},
- {0x00, 0x03, 0x816b},
- {0x00, 0x20, 0x8169},
- {0x00, 0x60, 0x8157},
- {0x00, 0x00, 0x8190},
- {0x00, 0x00, 0x81a1},
- {0x00, 0x00, 0x81b2},
- {0x00, 0x27, 0x8191},
- {0x00, 0x27, 0x81a2},
- {0x00, 0x27, 0x81b3},
- {0x00, 0x4b, 0x8192},
- {0x00, 0x4b, 0x81a3},
- {0x00, 0x4b, 0x81b4},
- {0x00, 0x66, 0x8193},
- {0x00, 0x66, 0x81a4},
- {0x00, 0x66, 0x81b5},
- {0x00, 0x79, 0x8194},
- {0x00, 0x79, 0x81a5},
- {0x00, 0x79, 0x81b6},
- {0x00, 0x8a, 0x8195},
- {0x00, 0x8a, 0x81a6},
- {0x00, 0x8a, 0x81b7},
- {0x00, 0x9b, 0x8196},
- {0x00, 0x9b, 0x81a7},
- {0x00, 0x9b, 0x81b8},
- {0x00, 0xa6, 0x8197},
- {0x00, 0xa6, 0x81a8},
- {0x00, 0xa6, 0x81b9},
- {0x00, 0xb2, 0x8198},
- {0x00, 0xb2, 0x81a9},
- {0x00, 0xb2, 0x81ba},
- {0x00, 0xbe, 0x8199},
- {0x00, 0xbe, 0x81aa},
- {0x00, 0xbe, 0x81bb},
- {0x00, 0xc8, 0x819a},
- {0x00, 0xc8, 0x81ab},
- {0x00, 0xc8, 0x81bc},
- {0x00, 0xd2, 0x819b},
- {0x00, 0xd2, 0x81ac},
- {0x00, 0xd2, 0x81bd},
- {0x00, 0xdb, 0x819c},
- {0x00, 0xdb, 0x81ad},
- {0x00, 0xdb, 0x81be},
- {0x00, 0xe4, 0x819d},
- {0x00, 0xe4, 0x81ae},
- {0x00, 0xe4, 0x81bf},
- {0x00, 0xed, 0x819e},
- {0x00, 0xed, 0x81af},
- {0x00, 0xed, 0x81c0},
- {0x00, 0xf7, 0x819f},
- {0x00, 0xf7, 0x81b0},
- {0x00, 0xf7, 0x81c1},
- {0x00, 0xff, 0x81a0},
- {0x00, 0xff, 0x81b1},
- {0x00, 0xff, 0x81c2},
- {0x00, 0x03, 0x8156},
- {0x00, 0x00, 0x8211},
- {0x00, 0x20, 0x8168},
- {0x00, 0x01, 0x8202},
- {0x00, 0x30, 0x8101},
- {0x00, 0x00, 0x8111},
- {0x00, 0x00, 0x8112},
- {0x00, 0x00, 0x8113},
- {0x00, 0x00, 0x8114},
- {}
-};
-
-static const __u8 qtable_creative_pccam[2][64] = {
- { /* Q-table Y-components */
- 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
- 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
- 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
- 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
- 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
- 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
- 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
- 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
- { /* Q-table C-components */
- 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
-};
-
-static const __u8 qtable_kodak_ez200[2][64] = {
- { /* Q-table Y-components */
- 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
- 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
- 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
- 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
- 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
- 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
- 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
- 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
- { /* Q-table C-components */
- 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
-};
-
-static const __u8 qtable_pocketdv[2][64] = {
- { /* Q-table Y-components start registers 0x8800 */
- 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
- 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
- 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
- 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
- 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
- 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
- 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
- 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
- },
- { /* Q-table C-components start registers 0x8840 */
- 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
- 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
- 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
-};
-
-/* read 'len' bytes to gspca_dev->usb_buf */
-static void reg_r(struct gspca_dev *gspca_dev,
- __u16 index,
- __u16 length)
-{
- usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- 0,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, /* value */
- index, gspca_dev->usb_buf, length, 500);
-}
-
-static int reg_w(struct gspca_dev *gspca_dev,
- __u16 req, __u16 index, __u16 value)
-{
- int ret;
-
- PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, NULL, 0, 500);
- if (ret < 0)
- pr_err("reg write: error %d\n", ret);
- return ret;
-}
-
-/* returns: negative is error, pos or zero is data */
-static int reg_r_12(struct gspca_dev *gspca_dev,
- __u16 req, /* bRequest */
- __u16 index, /* wIndex */
- __u16 length) /* wLength (1 or 2 only) */
-{
- int ret;
-
- gspca_dev->usb_buf[1] = 0;
- ret = usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, /* value */
- index,
- gspca_dev->usb_buf, length,
- 500); /* timeout */
- if (ret < 0) {
- pr_err("reg_r_12 err %d\n", ret);
- return ret;
- }
- return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
-}
-
-/*
- * Simple function to wait for a given 8-bit value to be returned from
- * a reg_read call.
- * Returns: negative is error or timeout, zero is success.
- */
-static int reg_r_wait(struct gspca_dev *gspca_dev,
- __u16 reg, __u16 index, __u16 value)
-{
- int ret, cnt = 20;
-
- while (--cnt > 0) {
- ret = reg_r_12(gspca_dev, reg, index, 1);
- if (ret == value)
- return 0;
- msleep(50);
- }
- return -EIO;
-}
-
-static int write_vector(struct gspca_dev *gspca_dev,
- const __u16 data[][3])
-{
- int ret, i = 0;
-
- while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
- ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
- if (ret < 0)
- return ret;
- i++;
- }
- return 0;
-}
-
-static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
- unsigned int request,
- unsigned int ybase,
- unsigned int cbase,
- const __u8 qtable[2][64])
-{
- int i, err;
-
- /* loop over y components */
- for (i = 0; i < 64; i++) {
- err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
- if (err < 0)
- return err;
- }
-
- /* loop over c components */
- for (i = 0; i < 64; i++) {
- err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static void spca500_ping310(struct gspca_dev *gspca_dev)
-{
- reg_r(gspca_dev, 0x0d04, 2);
- PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
- gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
-}
-
-static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
-{
- reg_r(gspca_dev, 0x0d05, 2);
- PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
- gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
- reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
- spca500_ping310(gspca_dev);
-
- reg_w(gspca_dev, 0x00, 0x8168, 0x22);
- reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
- reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
- reg_w(gspca_dev, 0x00, 0x8169, 0x25);
- reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
- reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
- reg_w(gspca_dev, 0x00, 0x813f, 0x03);
- reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
- reg_w(gspca_dev, 0x00, 0x8153, 0x78);
- reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
- /* 00 for adjust shutter */
- reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
- reg_w(gspca_dev, 0x00, 0x8169, 0x25);
- reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
-}
-
-static void spca500_setmode(struct gspca_dev *gspca_dev,
- __u8 xmult, __u8 ymult)
-{
- int mode;
-
- /* set x multiplier */
- reg_w(gspca_dev, 0, 0x8001, xmult);
-
- /* set y multiplier */
- reg_w(gspca_dev, 0, 0x8002, ymult);
-
- /* use compressed mode, VGA, with mode specific subsample */
- mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
- reg_w(gspca_dev, 0, 0x8003, mode << 4);
-}
-
-static int spca500_full_reset(struct gspca_dev *gspca_dev)
-{
- int err;
-
- /* send the reset command */
- err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
- if (err < 0)
- return err;
-
- /* wait for the reset to complete */
- err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
- if (err < 0)
- return err;
- err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
- if (err < 0)
- return err;
- err = reg_r_wait(gspca_dev, 0x06, 0, 0);
- if (err < 0) {
- PDEBUG(D_ERR, "reg_r_wait() failed");
- return err;
- }
- /* all ok */
- return 0;
-}
-
-/* Synchro the Bridge with sensor */
-/* Maybe that will work on all spca500 chip */
-/* because i only own a clicksmart310 try for that chip */
-/* using spca50x_set_packet_size() cause an Ooops here */
-/* usb_set_interface from kernel 2.6.x clear all the urb stuff */
-/* up-port the same feature as in 2.4.x kernel */
-static int spca500_synch310(struct gspca_dev *gspca_dev)
-{
- if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
- PDEBUG(D_ERR, "Set packet size: set interface error");
- goto error;
- }
- spca500_ping310(gspca_dev);
-
- reg_r(gspca_dev, 0x0d00, 1);
-
- /* need alt setting here */
- PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
-
- /* Windoze use pipe with altsetting 6 why 7 here */
- if (usb_set_interface(gspca_dev->dev,
- gspca_dev->iface,
- gspca_dev->alt) < 0) {
- PDEBUG(D_ERR, "Set packet size: set interface error");
- goto error;
- }
- return 0;
-error:
- return -EBUSY;
-}
-
-static void spca500_reinit(struct gspca_dev *gspca_dev)
-{
- int err;
- __u8 Data;
-
- /* some unknown command from Aiptek pocket dv and family300 */
-
- reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
- reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
- reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
-
- /* enable drop packet */
- reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
-
- err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
- qtable_pocketdv);
- if (err < 0)
- PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
-
- /* set qtable index */
- reg_w(gspca_dev, 0x00, 0x8880, 2);
- /* family cam Quicksmart stuff */
- reg_w(gspca_dev, 0x00, 0x800a, 0x00);
- /* Set agc transfer: synced between frames */
- reg_w(gspca_dev, 0x00, 0x820f, 0x01);
- /* Init SDRAM - needed for SDRAM access */
- reg_w(gspca_dev, 0x00, 0x870a, 0x04);
- /*Start init sequence or stream */
- reg_w(gspca_dev, 0, 0x8003, 0x00);
- /* switch to video camera mode */
- reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
- msleep(2000);
- if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
- reg_r(gspca_dev, 0x816b, 1);
- Data = gspca_dev->usb_buf[0];
- reg_w(gspca_dev, 0x00, 0x816b, Data);
- }
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
-
- cam = &gspca_dev->cam;
- sd->subtype = id->driver_info;
- if (sd->subtype != LogitechClickSmart310) {
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- } else {
- cam->cam_mode = sif_mode;
- cam->nmodes = ARRAY_SIZE(sif_mode);
- }
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* initialisation of spca500 based cameras is deferred */
- PDEBUG(D_STREAM, "SPCA500 init");
- if (sd->subtype == LogitechClickSmart310)
- spca500_clksmart310_init(gspca_dev);
-/* else
- spca500_initialise(gspca_dev); */
- PDEBUG(D_STREAM, "SPCA500 init done");
- return 0;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int err;
- __u8 Data;
- __u8 xmult, ymult;
-
- /* create the JPEG header */
- jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
- 0x22); /* JPEG 411 */
- jpeg_set_qual(sd->jpeg_hdr, QUALITY);
-
- if (sd->subtype == LogitechClickSmart310) {
- xmult = 0x16;
- ymult = 0x12;
- } else {
- xmult = 0x28;
- ymult = 0x1e;
- }
-
- /* is there a sensor here ? */
- reg_r(gspca_dev, 0x8a04, 1);
- PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
- gspca_dev->usb_buf[0]);
- PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
- gspca_dev->curr_mode, xmult, ymult);
-
- /* setup qtable */
- switch (sd->subtype) {
- case LogitechClickSmart310:
- spca500_setmode(gspca_dev, xmult, ymult);
-
- /* enable drop packet */
- reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
- reg_w(gspca_dev, 0x00, 0x8880, 3);
- err = spca50x_setup_qtable(gspca_dev,
- 0x00, 0x8800, 0x8840,
- qtable_creative_pccam);
- if (err < 0)
- PDEBUG(D_ERR, "spca50x_setup_qtable failed");
- /* Init SDRAM - needed for SDRAM access */
- reg_w(gspca_dev, 0x00, 0x870a, 0x04);
-
- /* switch to video camera mode */
- reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
- msleep(500);
- if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
- PDEBUG(D_ERR, "reg_r_wait() failed");
-
- reg_r(gspca_dev, 0x816b, 1);
- Data = gspca_dev->usb_buf[0];
- reg_w(gspca_dev, 0x00, 0x816b, Data);
-
- spca500_synch310(gspca_dev);
-
- write_vector(gspca_dev, spca500_visual_defaults);
- spca500_setmode(gspca_dev, xmult, ymult);
- /* enable drop packet */
- err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
- if (err < 0)
- PDEBUG(D_ERR, "failed to enable drop packet");
- reg_w(gspca_dev, 0x00, 0x8880, 3);
- err = spca50x_setup_qtable(gspca_dev,
- 0x00, 0x8800, 0x8840,
- qtable_creative_pccam);
- if (err < 0)
- PDEBUG(D_ERR, "spca50x_setup_qtable failed");
-
- /* Init SDRAM - needed for SDRAM access */
- reg_w(gspca_dev, 0x00, 0x870a, 0x04);
-
- /* switch to video camera mode */
- reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
-
- if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
- PDEBUG(D_ERR, "reg_r_wait() failed");
-
- reg_r(gspca_dev, 0x816b, 1);
- Data = gspca_dev->usb_buf[0];
- reg_w(gspca_dev, 0x00, 0x816b, Data);
- break;
- case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */
- case IntelPocketPCCamera: /* FIXME: Temporary fix for
- * Intel Pocket PC Camera
- * - NWG (Sat 29th March 2003) */
-
- /* do a full reset */
- err = spca500_full_reset(gspca_dev);
- if (err < 0)
- PDEBUG(D_ERR, "spca500_full_reset failed");
-
- /* enable drop packet */
- err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
- if (err < 0)
- PDEBUG(D_ERR, "failed to enable drop packet");
- reg_w(gspca_dev, 0x00, 0x8880, 3);
- err = spca50x_setup_qtable(gspca_dev,
- 0x00, 0x8800, 0x8840,
- qtable_creative_pccam);
- if (err < 0)
- PDEBUG(D_ERR, "spca50x_setup_qtable failed");
-
- spca500_setmode(gspca_dev, xmult, ymult);
- reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
-
- /* switch to video camera mode */
- reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
-
- if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
- PDEBUG(D_ERR, "reg_r_wait() failed");
-
- reg_r(gspca_dev, 0x816b, 1);
- Data = gspca_dev->usb_buf[0];
- reg_w(gspca_dev, 0x00, 0x816b, Data);
-
-/* write_vector(gspca_dev, spca500_visual_defaults); */
- break;
- case KodakEZ200: /* Kodak EZ200 */
-
- /* do a full reset */
- err = spca500_full_reset(gspca_dev);
- if (err < 0)
- PDEBUG(D_ERR, "spca500_full_reset failed");
- /* enable drop packet */
- reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
- reg_w(gspca_dev, 0x00, 0x8880, 0);
- err = spca50x_setup_qtable(gspca_dev,
- 0x00, 0x8800, 0x8840,
- qtable_kodak_ez200);
- if (err < 0)
- PDEBUG(D_ERR, "spca50x_setup_qtable failed");
- spca500_setmode(gspca_dev, xmult, ymult);
-
- reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
-
- /* switch to video camera mode */
- reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
-
- if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
- PDEBUG(D_ERR, "reg_r_wait() failed");
-
- reg_r(gspca_dev, 0x816b, 1);
- Data = gspca_dev->usb_buf[0];
- reg_w(gspca_dev, 0x00, 0x816b, Data);
-
-/* write_vector(gspca_dev, spca500_visual_defaults); */
- break;
-
- case BenqDC1016:
- case DLinkDSC350: /* FamilyCam 300 */
- case AiptekPocketDV: /* Aiptek PocketDV */
- case Gsmartmini: /*Mustek Gsmart Mini */
- case MustekGsmart300: /* Mustek Gsmart 300 */
- case PalmPixDC85:
- case Optimedia:
- case ToptroIndus:
- case AgfaCl20:
- spca500_reinit(gspca_dev);
- reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
- /* enable drop packet */
- reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
-
- err = spca50x_setup_qtable(gspca_dev,
- 0x00, 0x8800, 0x8840, qtable_pocketdv);
- if (err < 0)
- PDEBUG(D_ERR, "spca50x_setup_qtable failed");
- reg_w(gspca_dev, 0x00, 0x8880, 2);
-
- /* familycam Quicksmart pocketDV stuff */
- reg_w(gspca_dev, 0x00, 0x800a, 0x00);
- /* Set agc transfer: synced between frames */
- reg_w(gspca_dev, 0x00, 0x820f, 0x01);
- /* Init SDRAM - needed for SDRAM access */
- reg_w(gspca_dev, 0x00, 0x870a, 0x04);
-
- spca500_setmode(gspca_dev, xmult, ymult);
- /* switch to video camera mode */
- reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
-
- reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
-
- reg_r(gspca_dev, 0x816b, 1);
- Data = gspca_dev->usb_buf[0];
- reg_w(gspca_dev, 0x00, 0x816b, Data);
- break;
- case LogitechTraveler:
- case LogitechClickSmart510:
- reg_w(gspca_dev, 0x02, 0x00, 0x00);
- /* enable drop packet */
- reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
-
- err = spca50x_setup_qtable(gspca_dev,
- 0x00, 0x8800,
- 0x8840, qtable_creative_pccam);
- if (err < 0)
- PDEBUG(D_ERR, "spca50x_setup_qtable failed");
- reg_w(gspca_dev, 0x00, 0x8880, 3);
- reg_w(gspca_dev, 0x00, 0x800a, 0x00);
- /* Init SDRAM - needed for SDRAM access */
- reg_w(gspca_dev, 0x00, 0x870a, 0x04);
-
- spca500_setmode(gspca_dev, xmult, ymult);
-
- /* switch to video camera mode */
- reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
- reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
-
- reg_r(gspca_dev, 0x816b, 1);
- Data = gspca_dev->usb_buf[0];
- reg_w(gspca_dev, 0x00, 0x816b, Data);
- write_vector(gspca_dev, Clicksmart510_defaults);
- break;
- }
- return 0;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- reg_w(gspca_dev, 0, 0x8003, 0x00);
-
- /* switch to video camera mode */
- reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
- reg_r(gspca_dev, 0x8000, 1);
- PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
- gspca_dev->usb_buf[0]);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- static __u8 ffd9[] = {0xff, 0xd9};
-
-/* frames are jpeg 4.1.1 without 0xff escape */
- if (data[0] == 0xff) {
- if (data[1] != 0x01) { /* drop packet */
-/* gspca_dev->last_packet_type = DISCARD_PACKET; */
- return;
- }
- gspca_frame_add(gspca_dev, LAST_PACKET,
- ffd9, 2);
-
- /* put the JPEG header in the new frame */
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sd->jpeg_hdr, JPEG_HDR_SZ);
-
- data += SPCA500_OFFSET_DATA;
- len -= SPCA500_OFFSET_DATA;
- } else {
- data += 1;
- len -= 1;
- }
-
- /* add 0x00 after 0xff */
- i = 0;
- do {
- if (data[i] == 0xff) {
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data, i + 1);
- len -= i;
- data += i;
- *data = 0x00;
- i = 0;
- }
- i++;
- } while (i < len);
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_w(gspca_dev, 0x00, 0x8167,
- (__u8) (val - 128));
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_w(gspca_dev, 0x00, 0x8168, val);
-}
-
-static void setcolors(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_w(gspca_dev, 0x00, 0x8169, val);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- setcolors(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 3);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 63, 1, 31);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0, 63, 1, 31);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
- {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
- {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
- {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
- {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
- {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
- {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
- {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
- {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
- {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
- {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
- {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
- {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
- {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
- {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
deleted file mode 100644
index 3b7f777785b..00000000000
--- a/drivers/media/video/gspca/spca501.c
+++ /dev/null
@@ -1,2054 +0,0 @@
-/*
- * SPCA501 chip based cameras initialization data
- *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "spca501"
-
-#include "gspca.h"
-
-MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
-MODULE_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- unsigned short contrast;
- __u8 brightness;
- __u8 colors;
- __u8 blue_balance;
- __u8 red_balance;
-
- char subtype;
-#define Arowana300KCMOSCamera 0
-#define IntelCreateAndShare 1
-#define KodakDVC325 2
-#define MystFromOriUnknownCamera 3
-#define SmileIntlCamera 4
-#define ThreeComHomeConnectLite 5
-#define ViewQuestM318B 6
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {160, 120, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
- {320, 240, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-#define SPCA50X_REG_USB 0x2 /* spca505 501 */
-/*
- * Data to initialize a SPCA501. From a capture file provided by Bill Roehl
- * With SPCA501 chip description
- */
-#define CCDSP_SET /* set CCDSP parameters */
-#define TG_SET /* set time generator set */
-#undef DSPWIN_SET /* set DSP windows parameters */
-#undef ALTER_GAMA /* Set alternate set to YUV transform coeffs. */
-#define SPCA501_SNAPBIT 0x80
-#define SPCA501_SNAPCTRL 0x10
-/* Frame packet header offsets for the spca501 */
-#define SPCA501_OFFSET_GPIO 1
-#define SPCA501_OFFSET_TYPE 2
-#define SPCA501_OFFSET_TURN3A 3
-#define SPCA501_OFFSET_FRAMSEQ 4
-#define SPCA501_OFFSET_COMPRESS 5
-#define SPCA501_OFFSET_QUANT 6
-#define SPCA501_OFFSET_QUANT2 7
-#define SPCA501_OFFSET_DATA 8
-
-#define SPCA501_PROP_COMP_ENABLE(d) ((d) & 1)
-#define SPCA501_PROP_SNAP(d) ((d) & 0x40)
-#define SPCA501_PROP_SNAP_CTRL(d) ((d) & 0x10)
-#define SPCA501_PROP_COMP_THRESH(d) (((d) & 0x0e) >> 1)
-#define SPCA501_PROP_COMP_QUANT(d) (((d) & 0x70) >> 4)
-
-/* SPCA501 CCDSP control */
-#define SPCA501_REG_CCDSP 0x01
-/* SPCA501 control/status registers */
-#define SPCA501_REG_CTLRL 0x02
-
-/* registers for color correction and YUV transformation */
-#define SPCA501_A11 0x08
-#define SPCA501_A12 0x09
-#define SPCA501_A13 0x0A
-#define SPCA501_A21 0x0B
-#define SPCA501_A22 0x0C
-#define SPCA501_A23 0x0D
-#define SPCA501_A31 0x0E
-#define SPCA501_A32 0x0F
-#define SPCA501_A33 0x10
-
-/* Data for video camera initialization before capturing */
-static const __u16 spca501_open_data[][3] = {
- /* bmRequest,value,index */
-
- {0x2, 0x50, 0x00}, /* C/S enable soft reset */
- {0x2, 0x40, 0x00}, /* C/S disable soft reset */
- {0x2, 0x02, 0x05}, /* C/S general purpose I/O data */
- {0x2, 0x03, 0x05}, /* C/S general purpose I/O data */
-
-#ifdef CCDSP_SET
- {0x1, 0x38, 0x01}, /* CCDSP options */
- {0x1, 0x05, 0x02}, /* CCDSP Optical black level for user settings */
- {0x1, 0xC0, 0x03}, /* CCDSP Optical black settings */
-
- {0x1, 0x67, 0x07},
- {0x1, 0x63, 0x3f}, /* CCDSP CCD gamma enable */
- {0x1, 0x03, 0x56}, /* Add gamma correction */
-
- {0x1, 0xFF, 0x15}, /* CCDSP High luminance for white balance */
- {0x1, 0x01, 0x16}, /* CCDSP Low luminance for white balance */
-
-/* Color correction and RGB-to-YUV transformation coefficients changing */
-#ifdef ALTER_GAMA
- {0x0, 0x00, 0x08}, /* A11 */
- {0x0, 0x00, 0x09}, /* A12 */
- {0x0, 0x90, 0x0A}, /* A13 */
- {0x0, 0x12, 0x0B}, /* A21 */
- {0x0, 0x00, 0x0C}, /* A22 */
- {0x0, 0x00, 0x0D}, /* A23 */
- {0x0, 0x00, 0x0E}, /* A31 */
- {0x0, 0x02, 0x0F}, /* A32 */
- {0x0, 0x00, 0x10}, /* A33 */
-#else
- {0x1, 0x2a, 0x08}, /* A11 0x31 */
- {0x1, 0xf8, 0x09}, /* A12 f8 */
- {0x1, 0xf8, 0x0A}, /* A13 f8 */
- {0x1, 0xf8, 0x0B}, /* A21 f8 */
- {0x1, 0x14, 0x0C}, /* A22 0x14 */
- {0x1, 0xf8, 0x0D}, /* A23 f8 */
- {0x1, 0xf8, 0x0E}, /* A31 f8 */
- {0x1, 0xf8, 0x0F}, /* A32 f8 */
- {0x1, 0x20, 0x10}, /* A33 0x20 */
-#endif
- {0x1, 0x00, 0x11}, /* R offset */
- {0x1, 0x00, 0x12}, /* G offset */
- {0x1, 0x00, 0x13}, /* B offset */
- {0x1, 0x00, 0x14}, /* GB offset */
-
-#endif
-
-#ifdef TG_SET
- /* Time generator manipulations */
- {0x0, 0xfc, 0x0}, /* Set up high bits of shutter speed */
- {0x0, 0x01, 0x1}, /* Set up low bits of shutter speed */
-
- {0x0, 0xe4, 0x04}, /* DCLK*2 clock phase adjustment */
- {0x0, 0x08, 0x05}, /* ADCK phase adjustment, inv. ext. VB */
- {0x0, 0x03, 0x06}, /* FR phase adjustment */
- {0x0, 0x01, 0x07}, /* FCDS phase adjustment */
- {0x0, 0x39, 0x08}, /* FS phase adjustment */
- {0x0, 0x88, 0x0a}, /* FH1 phase and delay adjustment */
- {0x0, 0x03, 0x0f}, /* pixel identification */
- {0x0, 0x00, 0x11}, /* clock source selection (default) */
-
- /*VERY strange manipulations with
- * select DMCLP or OBPX to be ADCLP output (0x0C)
- * OPB always toggle or not (0x0D) but they allow
- * us to set up brightness
- */
- {0x0, 0x01, 0x0c},
- {0x0, 0xe0, 0x0d},
- /* Done */
-#endif
-
-#ifdef DSPWIN_SET
- {0x1, 0xa0, 0x01}, /* Setting image processing parameters */
- {0x1, 0x1c, 0x17}, /* Changing Windows positions X1 */
- {0x1, 0xe2, 0x19}, /* X2 */
- {0x1, 0x1c, 0x1b}, /* X3 */
- {0x1, 0xe2, 0x1d}, /* X4 */
- {0x1, 0x5f, 0x1f}, /* X5 */
- {0x1, 0x32, 0x20}, /* Y5 */
- {0x1, 0x01, 0x10}, /* Changing A33 */
-#endif
-
- {0x2, 0x204a, 0x07},/* Setting video compression & resolution 160x120 */
- {0x2, 0x94, 0x06}, /* Setting video no compression */
- {}
-};
-
-/*
- The SPCAxxx docs from Sunplus document these values
- in tables, one table per register number. In the data
- below, dmRequest is the register number, index is the Addr,
- and value is a combination of Bit values.
- Bit Value (hex)
- 0 01
- 1 02
- 2 04
- 3 08
- 4 10
- 5 20
- 6 40
- 7 80
- */
-
-/* Data for chip initialization (set default values) */
-static const __u16 spca501_init_data[][3] = {
- /* Set all the values to powerup defaults */
- /* bmRequest,value,index */
- {0x0, 0xAA, 0x00},
- {0x0, 0x02, 0x01},
- {0x0, 0x01, 0x02},
- {0x0, 0x02, 0x03},
- {0x0, 0xCE, 0x04},
- {0x0, 0x00, 0x05},
- {0x0, 0x00, 0x06},
- {0x0, 0x00, 0x07},
- {0x0, 0x00, 0x08},
- {0x0, 0x00, 0x09},
- {0x0, 0x90, 0x0A},
- {0x0, 0x12, 0x0B},
- {0x0, 0x00, 0x0C},
- {0x0, 0x00, 0x0D},
- {0x0, 0x00, 0x0E},
- {0x0, 0x02, 0x0F},
- {0x0, 0x00, 0x10},
- {0x0, 0x00, 0x11},
- {0x0, 0x00, 0x12},
- {0x0, 0x00, 0x13},
- {0x0, 0x00, 0x14},
- {0x0, 0x00, 0x15},
- {0x0, 0x00, 0x16},
- {0x0, 0x00, 0x17},
- {0x0, 0x00, 0x18},
- {0x0, 0x00, 0x19},
- {0x0, 0x00, 0x1A},
- {0x0, 0x00, 0x1B},
- {0x0, 0x00, 0x1C},
- {0x0, 0x00, 0x1D},
- {0x0, 0x00, 0x1E},
- {0x0, 0x00, 0x1F},
- {0x0, 0x00, 0x20},
- {0x0, 0x00, 0x21},
- {0x0, 0x00, 0x22},
- {0x0, 0x00, 0x23},
- {0x0, 0x00, 0x24},
- {0x0, 0x00, 0x25},
- {0x0, 0x00, 0x26},
- {0x0, 0x00, 0x27},
- {0x0, 0x00, 0x28},
- {0x0, 0x00, 0x29},
- {0x0, 0x00, 0x2A},
- {0x0, 0x00, 0x2B},
- {0x0, 0x00, 0x2C},
- {0x0, 0x00, 0x2D},
- {0x0, 0x00, 0x2E},
- {0x0, 0x00, 0x2F},
- {0x0, 0x00, 0x30},
- {0x0, 0x00, 0x31},
- {0x0, 0x00, 0x32},
- {0x0, 0x00, 0x33},
- {0x0, 0x00, 0x34},
- {0x0, 0x00, 0x35},
- {0x0, 0x00, 0x36},
- {0x0, 0x00, 0x37},
- {0x0, 0x00, 0x38},
- {0x0, 0x00, 0x39},
- {0x0, 0x00, 0x3A},
- {0x0, 0x00, 0x3B},
- {0x0, 0x00, 0x3C},
- {0x0, 0x00, 0x3D},
- {0x0, 0x00, 0x3E},
- {0x0, 0x00, 0x3F},
- {0x0, 0x00, 0x40},
- {0x0, 0x00, 0x41},
- {0x0, 0x00, 0x42},
- {0x0, 0x00, 0x43},
- {0x0, 0x00, 0x44},
- {0x0, 0x00, 0x45},
- {0x0, 0x00, 0x46},
- {0x0, 0x00, 0x47},
- {0x0, 0x00, 0x48},
- {0x0, 0x00, 0x49},
- {0x0, 0x00, 0x4A},
- {0x0, 0x00, 0x4B},
- {0x0, 0x00, 0x4C},
- {0x0, 0x00, 0x4D},
- {0x0, 0x00, 0x4E},
- {0x0, 0x00, 0x4F},
- {0x0, 0x00, 0x50},
- {0x0, 0x00, 0x51},
- {0x0, 0x00, 0x52},
- {0x0, 0x00, 0x53},
- {0x0, 0x00, 0x54},
- {0x0, 0x00, 0x55},
- {0x0, 0x00, 0x56},
- {0x0, 0x00, 0x57},
- {0x0, 0x00, 0x58},
- {0x0, 0x00, 0x59},
- {0x0, 0x00, 0x5A},
- {0x0, 0x00, 0x5B},
- {0x0, 0x00, 0x5C},
- {0x0, 0x00, 0x5D},
- {0x0, 0x00, 0x5E},
- {0x0, 0x00, 0x5F},
- {0x0, 0x00, 0x60},
- {0x0, 0x00, 0x61},
- {0x0, 0x00, 0x62},
- {0x0, 0x00, 0x63},
- {0x0, 0x00, 0x64},
- {0x0, 0x00, 0x65},
- {0x0, 0x00, 0x66},
- {0x0, 0x00, 0x67},
- {0x0, 0x00, 0x68},
- {0x0, 0x00, 0x69},
- {0x0, 0x00, 0x6A},
- {0x0, 0x00, 0x6B},
- {0x0, 0x00, 0x6C},
- {0x0, 0x00, 0x6D},
- {0x0, 0x00, 0x6E},
- {0x0, 0x00, 0x6F},
- {0x0, 0x00, 0x70},
- {0x0, 0x00, 0x71},
- {0x0, 0x00, 0x72},
- {0x0, 0x00, 0x73},
- {0x0, 0x00, 0x74},
- {0x0, 0x00, 0x75},
- {0x0, 0x00, 0x76},
- {0x0, 0x00, 0x77},
- {0x0, 0x00, 0x78},
- {0x0, 0x00, 0x79},
- {0x0, 0x00, 0x7A},
- {0x0, 0x00, 0x7B},
- {0x0, 0x00, 0x7C},
- {0x0, 0x00, 0x7D},
- {0x0, 0x00, 0x7E},
- {0x0, 0x00, 0x7F},
- {0x0, 0x00, 0x80},
- {0x0, 0x00, 0x81},
- {0x0, 0x00, 0x82},
- {0x0, 0x00, 0x83},
- {0x0, 0x00, 0x84},
- {0x0, 0x00, 0x85},
- {0x0, 0x00, 0x86},
- {0x0, 0x00, 0x87},
- {0x0, 0x00, 0x88},
- {0x0, 0x00, 0x89},
- {0x0, 0x00, 0x8A},
- {0x0, 0x00, 0x8B},
- {0x0, 0x00, 0x8C},
- {0x0, 0x00, 0x8D},
- {0x0, 0x00, 0x8E},
- {0x0, 0x00, 0x8F},
- {0x0, 0x00, 0x90},
- {0x0, 0x00, 0x91},
- {0x0, 0x00, 0x92},
- {0x0, 0x00, 0x93},
- {0x0, 0x00, 0x94},
- {0x0, 0x00, 0x95},
- {0x0, 0x00, 0x96},
- {0x0, 0x00, 0x97},
- {0x0, 0x00, 0x98},
- {0x0, 0x00, 0x99},
- {0x0, 0x00, 0x9A},
- {0x0, 0x00, 0x9B},
- {0x0, 0x00, 0x9C},
- {0x0, 0x00, 0x9D},
- {0x0, 0x00, 0x9E},
- {0x0, 0x00, 0x9F},
- {0x0, 0x00, 0xA0},
- {0x0, 0x00, 0xA1},
- {0x0, 0x00, 0xA2},
- {0x0, 0x00, 0xA3},
- {0x0, 0x00, 0xA4},
- {0x0, 0x00, 0xA5},
- {0x0, 0x00, 0xA6},
- {0x0, 0x00, 0xA7},
- {0x0, 0x00, 0xA8},
- {0x0, 0x00, 0xA9},
- {0x0, 0x00, 0xAA},
- {0x0, 0x00, 0xAB},
- {0x0, 0x00, 0xAC},
- {0x0, 0x00, 0xAD},
- {0x0, 0x00, 0xAE},
- {0x0, 0x00, 0xAF},
- {0x0, 0x00, 0xB0},
- {0x0, 0x00, 0xB1},
- {0x0, 0x00, 0xB2},
- {0x0, 0x00, 0xB3},
- {0x0, 0x00, 0xB4},
- {0x0, 0x00, 0xB5},
- {0x0, 0x00, 0xB6},
- {0x0, 0x00, 0xB7},
- {0x0, 0x00, 0xB8},
- {0x0, 0x00, 0xB9},
- {0x0, 0x00, 0xBA},
- {0x0, 0x00, 0xBB},
- {0x0, 0x00, 0xBC},
- {0x0, 0x00, 0xBD},
- {0x0, 0x00, 0xBE},
- {0x0, 0x00, 0xBF},
- {0x0, 0x00, 0xC0},
- {0x0, 0x00, 0xC1},
- {0x0, 0x00, 0xC2},
- {0x0, 0x00, 0xC3},
- {0x0, 0x00, 0xC4},
- {0x0, 0x00, 0xC5},
- {0x0, 0x00, 0xC6},
- {0x0, 0x00, 0xC7},
- {0x0, 0x00, 0xC8},
- {0x0, 0x00, 0xC9},
- {0x0, 0x00, 0xCA},
- {0x0, 0x00, 0xCB},
- {0x0, 0x00, 0xCC},
- {0x1, 0xF4, 0x00},
- {0x1, 0x38, 0x01},
- {0x1, 0x40, 0x02},
- {0x1, 0x0A, 0x03},
- {0x1, 0x40, 0x04},
- {0x1, 0x40, 0x05},
- {0x1, 0x40, 0x06},
- {0x1, 0x67, 0x07},
- {0x1, 0x31, 0x08},
- {0x1, 0x00, 0x09},
- {0x1, 0x00, 0x0A},
- {0x1, 0x00, 0x0B},
- {0x1, 0x14, 0x0C},
- {0x1, 0x00, 0x0D},
- {0x1, 0x00, 0x0E},
- {0x1, 0x00, 0x0F},
- {0x1, 0x1E, 0x10},
- {0x1, 0x00, 0x11},
- {0x1, 0x00, 0x12},
- {0x1, 0x00, 0x13},
- {0x1, 0x00, 0x14},
- {0x1, 0xFF, 0x15},
- {0x1, 0x01, 0x16},
- {0x1, 0x32, 0x17},
- {0x1, 0x23, 0x18},
- {0x1, 0xCE, 0x19},
- {0x1, 0x23, 0x1A},
- {0x1, 0x32, 0x1B},
- {0x1, 0x8D, 0x1C},
- {0x1, 0xCE, 0x1D},
- {0x1, 0x8D, 0x1E},
- {0x1, 0x00, 0x1F},
- {0x1, 0x00, 0x20},
- {0x1, 0xFF, 0x3E},
- {0x1, 0x02, 0x3F},
- {0x1, 0x00, 0x40},
- {0x1, 0x00, 0x41},
- {0x1, 0x00, 0x42},
- {0x1, 0x00, 0x43},
- {0x1, 0x00, 0x44},
- {0x1, 0x00, 0x45},
- {0x1, 0x00, 0x46},
- {0x1, 0x00, 0x47},
- {0x1, 0x00, 0x48},
- {0x1, 0x00, 0x49},
- {0x1, 0x00, 0x4A},
- {0x1, 0x00, 0x4B},
- {0x1, 0x00, 0x4C},
- {0x1, 0x00, 0x4D},
- {0x1, 0x00, 0x4E},
- {0x1, 0x00, 0x4F},
- {0x1, 0x00, 0x50},
- {0x1, 0x00, 0x51},
- {0x1, 0x00, 0x52},
- {0x1, 0x00, 0x53},
- {0x1, 0x00, 0x54},
- {0x1, 0x00, 0x55},
- {0x1, 0x00, 0x56},
- {0x1, 0x00, 0x57},
- {0x1, 0x00, 0x58},
- {0x1, 0x00, 0x59},
- {0x1, 0x00, 0x5A},
- {0x2, 0x03, 0x00},
- {0x2, 0x00, 0x01},
- {0x2, 0x00, 0x05},
- {0x2, 0x00, 0x06},
- {0x2, 0x00, 0x07},
- {0x2, 0x00, 0x10},
- {0x2, 0x00, 0x11},
- /* Strange - looks like the 501 driver doesn't do anything
- * at insert time except read the EEPROM
- */
- {}
-};
-
-/* Data for video camera init before capture.
- * Capture and decoding by Colin Peart.
- * This is is for the 3com HomeConnect Lite which is spca501a based.
- */
-static const __u16 spca501_3com_open_data[][3] = {
- /* bmRequest,value,index */
- {0x2, 0x0050, 0x0000}, /* C/S Enable TG soft reset, timing mode=010 */
- {0x2, 0x0043, 0x0000}, /* C/S Disable TG soft reset, timing mode=010 */
- {0x2, 0x0002, 0x0005}, /* C/S GPIO */
- {0x2, 0x0003, 0x0005}, /* C/S GPIO */
-
-#ifdef CCDSP_SET
- {0x1, 0x0020, 0x0001}, /* CCDSP Options */
-
- {0x1, 0x0020, 0x0002}, /* CCDSP Black Level */
- {0x1, 0x006e, 0x0007}, /* CCDSP Gamma options */
- {0x1, 0x0090, 0x0015}, /* CCDSP Luminance Low */
- {0x1, 0x00ff, 0x0016}, /* CCDSP Luminance High */
- {0x1, 0x0003, 0x003F}, /* CCDSP Gamma correction toggle */
-
-#ifdef ALTER_GAMMA
- {0x1, 0x0010, 0x0008}, /* CCDSP YUV A11 */
- {0x1, 0x0000, 0x0009}, /* CCDSP YUV A12 */
- {0x1, 0x0000, 0x000a}, /* CCDSP YUV A13 */
- {0x1, 0x0000, 0x000b}, /* CCDSP YUV A21 */
- {0x1, 0x0010, 0x000c}, /* CCDSP YUV A22 */
- {0x1, 0x0000, 0x000d}, /* CCDSP YUV A23 */
- {0x1, 0x0000, 0x000e}, /* CCDSP YUV A31 */
- {0x1, 0x0000, 0x000f}, /* CCDSP YUV A32 */
- {0x1, 0x0010, 0x0010}, /* CCDSP YUV A33 */
- {0x1, 0x0000, 0x0011}, /* CCDSP R Offset */
- {0x1, 0x0000, 0x0012}, /* CCDSP G Offset */
- {0x1, 0x0001, 0x0013}, /* CCDSP B Offset */
- {0x1, 0x0001, 0x0014}, /* CCDSP BG Offset */
- {0x1, 0x003f, 0x00C1}, /* CCDSP Gamma Correction Enable */
-#endif
-#endif
-
-#ifdef TG_SET
- {0x0, 0x00fc, 0x0000}, /* TG Shutter Speed High Bits */
- {0x0, 0x0000, 0x0001}, /* TG Shutter Speed Low Bits */
- {0x0, 0x00e4, 0x0004}, /* TG DCLK*2 Adjust */
- {0x0, 0x0008, 0x0005}, /* TG ADCK Adjust */
- {0x0, 0x0003, 0x0006}, /* TG FR Phase Adjust */
- {0x0, 0x0001, 0x0007}, /* TG FCDS Phase Adjust */
- {0x0, 0x0039, 0x0008}, /* TG FS Phase Adjust */
- {0x0, 0x0088, 0x000a}, /* TG MH1 */
- {0x0, 0x0003, 0x000f}, /* TG Pixel ID */
-
- /* Like below, unexplained toglleing */
- {0x0, 0x0080, 0x000c},
- {0x0, 0x0000, 0x000d},
- {0x0, 0x0080, 0x000c},
- {0x0, 0x0004, 0x000d},
- {0x0, 0x0000, 0x000c},
- {0x0, 0x0000, 0x000d},
- {0x0, 0x0040, 0x000c},
- {0x0, 0x0017, 0x000d},
- {0x0, 0x00c0, 0x000c},
- {0x0, 0x0000, 0x000d},
- {0x0, 0x0080, 0x000c},
- {0x0, 0x0006, 0x000d},
- {0x0, 0x0080, 0x000c},
- {0x0, 0x0004, 0x000d},
- {0x0, 0x0002, 0x0003},
-#endif
-
-#ifdef DSPWIN_SET
- {0x1, 0x001c, 0x0017}, /* CCDSP W1 Start X */
- {0x1, 0x00e2, 0x0019}, /* CCDSP W2 Start X */
- {0x1, 0x001c, 0x001b}, /* CCDSP W3 Start X */
- {0x1, 0x00e2, 0x001d}, /* CCDSP W4 Start X */
- {0x1, 0x00aa, 0x001f}, /* CCDSP W5 Start X */
- {0x1, 0x0070, 0x0020}, /* CCDSP W5 Start Y */
-#endif
- {0x0, 0x0001, 0x0010}, /* TG Start Clock */
-
-/* {0x2, 0x006a, 0x0001}, * C/S Enable ISOSYNCH Packet Engine */
- {0x2, 0x0068, 0x0001}, /* C/S Diable ISOSYNCH Packet Engine */
- {0x2, 0x0000, 0x0005},
- {0x2, 0x0043, 0x0000}, /* C/S Set Timing Mode, Disable TG soft reset */
- {0x2, 0x0043, 0x0000}, /* C/S Set Timing Mode, Disable TG soft reset */
- {0x2, 0x0002, 0x0005}, /* C/S GPIO */
- {0x2, 0x0003, 0x0005}, /* C/S GPIO */
-
- {0x2, 0x006a, 0x0001}, /* C/S Enable ISOSYNCH Packet Engine */
- {}
-};
-
-/*
- * Data used to initialize a SPCA501C with HV7131B sensor.
- * From a capture file taken with USBSnoop v 1.5
- * I have a "SPCA501C pc camera chipset" manual by sunplus, but some
- * of the value meanings are obscure or simply "reserved".
- * to do list:
- * 1) Understand what every value means
- * 2) Understand why some values seem to appear more than once
- * 3) Write a small comment for each line of the following arrays.
- */
-static const __u16 spca501c_arowana_open_data[][3] = {
- /* bmRequest,value,index */
- {0x02, 0x0007, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x01, 0x0006, 0x0011},
- {0x01, 0x00ff, 0x0012},
- {0x01, 0x0014, 0x0013},
- {0x01, 0x0000, 0x0014},
- {0x01, 0x0042, 0x0051},
- {0x01, 0x0040, 0x0052},
- {0x01, 0x0051, 0x0053},
- {0x01, 0x0040, 0x0054},
- {0x01, 0x0000, 0x0055},
- {0x00, 0x0025, 0x0000},
- {0x00, 0x0026, 0x0000},
- {0x00, 0x0001, 0x0000},
- {0x00, 0x0027, 0x0000},
- {0x00, 0x008a, 0x0000},
- {}
-};
-
-static const __u16 spca501c_arowana_init_data[][3] = {
- /* bmRequest,value,index */
- {0x02, 0x0007, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x01, 0x0006, 0x0011},
- {0x01, 0x00ff, 0x0012},
- {0x01, 0x0014, 0x0013},
- {0x01, 0x0000, 0x0014},
- {0x01, 0x0042, 0x0051},
- {0x01, 0x0040, 0x0052},
- {0x01, 0x0051, 0x0053},
- {0x01, 0x0040, 0x0054},
- {0x01, 0x0000, 0x0055},
- {0x00, 0x0025, 0x0000},
- {0x00, 0x0026, 0x0000},
- {0x00, 0x0001, 0x0000},
- {0x00, 0x0027, 0x0000},
- {0x00, 0x008a, 0x0000},
- {0x02, 0x0000, 0x0005},
- {0x02, 0x0007, 0x0005},
- {0x02, 0x2000, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x05, 0x0015, 0x0001},
- {0x05, 0x00ea, 0x0000},
- {0x05, 0x0021, 0x0001},
- {0x05, 0x00d2, 0x0000},
- {0x05, 0x0023, 0x0001},
- {0x05, 0x0003, 0x0000},
- {0x05, 0x0030, 0x0001},
- {0x05, 0x002b, 0x0000},
- {0x05, 0x0031, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0032, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0033, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0034, 0x0001},
- {0x05, 0x0002, 0x0000},
- {0x05, 0x0050, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0051, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0052, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0054, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x00, 0x0000, 0x0001},
- {0x00, 0x0000, 0x0002},
- {0x00, 0x000c, 0x0003},
- {0x00, 0x0000, 0x0004},
- {0x00, 0x0090, 0x0005},
- {0x00, 0x0000, 0x0006},
- {0x00, 0x0040, 0x0007},
- {0x00, 0x00c0, 0x0008},
- {0x00, 0x004a, 0x0009},
- {0x00, 0x0000, 0x000a},
- {0x00, 0x0000, 0x000b},
- {0x00, 0x0001, 0x000c},
- {0x00, 0x0001, 0x000d},
- {0x00, 0x0000, 0x000e},
- {0x00, 0x0002, 0x000f},
- {0x00, 0x0001, 0x0010},
- {0x00, 0x0000, 0x0011},
- {0x00, 0x0000, 0x0012},
- {0x00, 0x0002, 0x0020},
- {0x00, 0x0080, 0x0021},
- {0x00, 0x0001, 0x0022},
- {0x00, 0x00e0, 0x0023},
- {0x00, 0x0000, 0x0024},
- {0x00, 0x00d5, 0x0025},
- {0x00, 0x0000, 0x0026},
- {0x00, 0x000b, 0x0027},
- {0x00, 0x0000, 0x0046},
- {0x00, 0x0000, 0x0047},
- {0x00, 0x0000, 0x0048},
- {0x00, 0x0000, 0x0049},
- {0x00, 0x0008, 0x004a},
- {0xff, 0x0000, 0x00d0},
- {0xff, 0x00d8, 0x00d1},
- {0xff, 0x0000, 0x00d4},
- {0xff, 0x0000, 0x00d5},
- {0x01, 0x00a6, 0x0000},
- {0x01, 0x0028, 0x0001},
- {0x01, 0x0000, 0x0002},
- {0x01, 0x000a, 0x0003},
- {0x01, 0x0040, 0x0004},
- {0x01, 0x0066, 0x0007},
- {0x01, 0x0011, 0x0008},
- {0x01, 0x0032, 0x0009},
- {0x01, 0x00fd, 0x000a},
- {0x01, 0x0038, 0x000b},
- {0x01, 0x00d1, 0x000c},
- {0x01, 0x00f7, 0x000d},
- {0x01, 0x00ed, 0x000e},
- {0x01, 0x00d8, 0x000f},
- {0x01, 0x0038, 0x0010},
- {0x01, 0x00ff, 0x0015},
- {0x01, 0x0001, 0x0016},
- {0x01, 0x0032, 0x0017},
- {0x01, 0x0023, 0x0018},
- {0x01, 0x00ce, 0x0019},
- {0x01, 0x0023, 0x001a},
- {0x01, 0x0032, 0x001b},
- {0x01, 0x008d, 0x001c},
- {0x01, 0x00ce, 0x001d},
- {0x01, 0x008d, 0x001e},
- {0x01, 0x0000, 0x001f},
- {0x01, 0x0000, 0x0020},
- {0x01, 0x00ff, 0x003e},
- {0x01, 0x0003, 0x003f},
- {0x01, 0x0000, 0x0040},
- {0x01, 0x0035, 0x0041},
- {0x01, 0x0053, 0x0042},
- {0x01, 0x0069, 0x0043},
- {0x01, 0x007c, 0x0044},
- {0x01, 0x008c, 0x0045},
- {0x01, 0x009a, 0x0046},
- {0x01, 0x00a8, 0x0047},
- {0x01, 0x00b4, 0x0048},
- {0x01, 0x00bf, 0x0049},
- {0x01, 0x00ca, 0x004a},
- {0x01, 0x00d4, 0x004b},
- {0x01, 0x00dd, 0x004c},
- {0x01, 0x00e7, 0x004d},
- {0x01, 0x00ef, 0x004e},
- {0x01, 0x00f8, 0x004f},
- {0x01, 0x00ff, 0x0050},
- {0x01, 0x0001, 0x0056},
- {0x01, 0x0060, 0x0057},
- {0x01, 0x0040, 0x0058},
- {0x01, 0x0011, 0x0059},
- {0x01, 0x0001, 0x005a},
- {0x02, 0x0007, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x02, 0x0007, 0x0005},
- {0x02, 0x0015, 0x0006},
- {0x02, 0x100a, 0x0007},
- {0x02, 0xa048, 0x0000},
- {0x02, 0xc002, 0x0001},
- {0x02, 0x000f, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x05, 0x0025, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0026, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x05, 0x0027, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0001, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0021, 0x0001},
- {0x05, 0x00d2, 0x0000},
- {0x05, 0x0020, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x00, 0x0090, 0x0005},
- {0x01, 0x00a6, 0x0000},
- {0x02, 0x0007, 0x0005},
- {0x02, 0x2000, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x05, 0x0015, 0x0001},
- {0x05, 0x00ea, 0x0000},
- {0x05, 0x0021, 0x0001},
- {0x05, 0x00d2, 0x0000},
- {0x05, 0x0023, 0x0001},
- {0x05, 0x0003, 0x0000},
- {0x05, 0x0030, 0x0001},
- {0x05, 0x002b, 0x0000},
- {0x05, 0x0031, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0032, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0033, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0034, 0x0001},
- {0x05, 0x0002, 0x0000},
- {0x05, 0x0050, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0051, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0052, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0054, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x00, 0x0000, 0x0001},
- {0x00, 0x0000, 0x0002},
- {0x00, 0x000c, 0x0003},
- {0x00, 0x0000, 0x0004},
- {0x00, 0x0090, 0x0005},
- {0x00, 0x0000, 0x0006},
- {0x00, 0x0040, 0x0007},
- {0x00, 0x00c0, 0x0008},
- {0x00, 0x004a, 0x0009},
- {0x00, 0x0000, 0x000a},
- {0x00, 0x0000, 0x000b},
- {0x00, 0x0001, 0x000c},
- {0x00, 0x0001, 0x000d},
- {0x00, 0x0000, 0x000e},
- {0x00, 0x0002, 0x000f},
- {0x00, 0x0001, 0x0010},
- {0x00, 0x0000, 0x0011},
- {0x00, 0x0000, 0x0012},
- {0x00, 0x0002, 0x0020},
- {0x00, 0x0080, 0x0021},
- {0x00, 0x0001, 0x0022},
- {0x00, 0x00e0, 0x0023},
- {0x00, 0x0000, 0x0024},
- {0x00, 0x00d5, 0x0025},
- {0x00, 0x0000, 0x0026},
- {0x00, 0x000b, 0x0027},
- {0x00, 0x0000, 0x0046},
- {0x00, 0x0000, 0x0047},
- {0x00, 0x0000, 0x0048},
- {0x00, 0x0000, 0x0049},
- {0x00, 0x0008, 0x004a},
- {0xff, 0x0000, 0x00d0},
- {0xff, 0x00d8, 0x00d1},
- {0xff, 0x0000, 0x00d4},
- {0xff, 0x0000, 0x00d5},
- {0x01, 0x00a6, 0x0000},
- {0x01, 0x0028, 0x0001},
- {0x01, 0x0000, 0x0002},
- {0x01, 0x000a, 0x0003},
- {0x01, 0x0040, 0x0004},
- {0x01, 0x0066, 0x0007},
- {0x01, 0x0011, 0x0008},
- {0x01, 0x0032, 0x0009},
- {0x01, 0x00fd, 0x000a},
- {0x01, 0x0038, 0x000b},
- {0x01, 0x00d1, 0x000c},
- {0x01, 0x00f7, 0x000d},
- {0x01, 0x00ed, 0x000e},
- {0x01, 0x00d8, 0x000f},
- {0x01, 0x0038, 0x0010},
- {0x01, 0x00ff, 0x0015},
- {0x01, 0x0001, 0x0016},
- {0x01, 0x0032, 0x0017},
- {0x01, 0x0023, 0x0018},
- {0x01, 0x00ce, 0x0019},
- {0x01, 0x0023, 0x001a},
- {0x01, 0x0032, 0x001b},
- {0x01, 0x008d, 0x001c},
- {0x01, 0x00ce, 0x001d},
- {0x01, 0x008d, 0x001e},
- {0x01, 0x0000, 0x001f},
- {0x01, 0x0000, 0x0020},
- {0x01, 0x00ff, 0x003e},
- {0x01, 0x0003, 0x003f},
- {0x01, 0x0000, 0x0040},
- {0x01, 0x0035, 0x0041},
- {0x01, 0x0053, 0x0042},
- {0x01, 0x0069, 0x0043},
- {0x01, 0x007c, 0x0044},
- {0x01, 0x008c, 0x0045},
- {0x01, 0x009a, 0x0046},
- {0x01, 0x00a8, 0x0047},
- {0x01, 0x00b4, 0x0048},
- {0x01, 0x00bf, 0x0049},
- {0x01, 0x00ca, 0x004a},
- {0x01, 0x00d4, 0x004b},
- {0x01, 0x00dd, 0x004c},
- {0x01, 0x00e7, 0x004d},
- {0x01, 0x00ef, 0x004e},
- {0x01, 0x00f8, 0x004f},
- {0x01, 0x00ff, 0x0050},
- {0x01, 0x0001, 0x0056},
- {0x01, 0x0060, 0x0057},
- {0x01, 0x0040, 0x0058},
- {0x01, 0x0011, 0x0059},
- {0x01, 0x0001, 0x005a},
- {0x02, 0x0007, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x02, 0x0007, 0x0005},
- {0x02, 0x0015, 0x0006},
- {0x02, 0x100a, 0x0007},
- {0x02, 0xa048, 0x0000},
- {0x02, 0xc002, 0x0001},
- {0x02, 0x000f, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x05, 0x0025, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0026, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x05, 0x0027, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0001, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0021, 0x0001},
- {0x05, 0x00d2, 0x0000},
- {0x05, 0x0020, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x00, 0x0090, 0x0005},
- {0x01, 0x00a6, 0x0000},
- {0x01, 0x0003, 0x003f},
- {0x01, 0x0001, 0x0056},
- {0x01, 0x0011, 0x0008},
- {0x01, 0x0032, 0x0009},
- {0x01, 0xfffd, 0x000a},
- {0x01, 0x0023, 0x000b},
- {0x01, 0xffea, 0x000c},
- {0x01, 0xfff4, 0x000d},
- {0x01, 0xfffc, 0x000e},
- {0x01, 0xffe3, 0x000f},
- {0x01, 0x001f, 0x0010},
- {0x01, 0x00a8, 0x0001},
- {0x01, 0x0067, 0x0007},
- {0x01, 0x0032, 0x0017},
- {0x01, 0x0023, 0x0018},
- {0x01, 0x00ce, 0x0019},
- {0x01, 0x0023, 0x001a},
- {0x01, 0x0032, 0x001b},
- {0x01, 0x008d, 0x001c},
- {0x01, 0x00ce, 0x001d},
- {0x01, 0x008d, 0x001e},
- {0x01, 0x00c8, 0x0015},
- {0x01, 0x0032, 0x0016},
- {0x01, 0x0000, 0x0011},
- {0x01, 0x0000, 0x0012},
- {0x01, 0x0000, 0x0013},
- {0x01, 0x000a, 0x0003},
- {0x02, 0xc002, 0x0001},
- {0x02, 0x0007, 0x0005},
- {0x02, 0xc000, 0x0001},
- {0x02, 0x0000, 0x0005},
- {0x02, 0x0007, 0x0005},
- {0x02, 0x2000, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x05, 0x0015, 0x0001},
- {0x05, 0x00ea, 0x0000},
- {0x05, 0x0021, 0x0001},
- {0x05, 0x00d2, 0x0000},
- {0x05, 0x0023, 0x0001},
- {0x05, 0x0003, 0x0000},
- {0x05, 0x0030, 0x0001},
- {0x05, 0x002b, 0x0000},
- {0x05, 0x0031, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0032, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0033, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0034, 0x0001},
- {0x05, 0x0002, 0x0000},
- {0x05, 0x0050, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0051, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0052, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0054, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x00, 0x0000, 0x0001},
- {0x00, 0x0000, 0x0002},
- {0x00, 0x000c, 0x0003},
- {0x00, 0x0000, 0x0004},
- {0x00, 0x0090, 0x0005},
- {0x00, 0x0000, 0x0006},
- {0x00, 0x0040, 0x0007},
- {0x00, 0x00c0, 0x0008},
- {0x00, 0x004a, 0x0009},
- {0x00, 0x0000, 0x000a},
- {0x00, 0x0000, 0x000b},
- {0x00, 0x0001, 0x000c},
- {0x00, 0x0001, 0x000d},
- {0x00, 0x0000, 0x000e},
- {0x00, 0x0002, 0x000f},
- {0x00, 0x0001, 0x0010},
- {0x00, 0x0000, 0x0011},
- {0x00, 0x0000, 0x0012},
- {0x00, 0x0002, 0x0020},
- {0x00, 0x0080, 0x0021},
- {0x00, 0x0001, 0x0022},
- {0x00, 0x00e0, 0x0023},
- {0x00, 0x0000, 0x0024},
- {0x00, 0x00d5, 0x0025},
- {0x00, 0x0000, 0x0026},
- {0x00, 0x000b, 0x0027},
- {0x00, 0x0000, 0x0046},
- {0x00, 0x0000, 0x0047},
- {0x00, 0x0000, 0x0048},
- {0x00, 0x0000, 0x0049},
- {0x00, 0x0008, 0x004a},
- {0xff, 0x0000, 0x00d0},
- {0xff, 0x00d8, 0x00d1},
- {0xff, 0x0000, 0x00d4},
- {0xff, 0x0000, 0x00d5},
- {0x01, 0x00a6, 0x0000},
- {0x01, 0x0028, 0x0001},
- {0x01, 0x0000, 0x0002},
- {0x01, 0x000a, 0x0003},
- {0x01, 0x0040, 0x0004},
- {0x01, 0x0066, 0x0007},
- {0x01, 0x0011, 0x0008},
- {0x01, 0x0032, 0x0009},
- {0x01, 0x00fd, 0x000a},
- {0x01, 0x0038, 0x000b},
- {0x01, 0x00d1, 0x000c},
- {0x01, 0x00f7, 0x000d},
- {0x01, 0x00ed, 0x000e},
- {0x01, 0x00d8, 0x000f},
- {0x01, 0x0038, 0x0010},
- {0x01, 0x00ff, 0x0015},
- {0x01, 0x0001, 0x0016},
- {0x01, 0x0032, 0x0017},
- {0x01, 0x0023, 0x0018},
- {0x01, 0x00ce, 0x0019},
- {0x01, 0x0023, 0x001a},
- {0x01, 0x0032, 0x001b},
- {0x01, 0x008d, 0x001c},
- {0x01, 0x00ce, 0x001d},
- {0x01, 0x008d, 0x001e},
- {0x01, 0x0000, 0x001f},
- {0x01, 0x0000, 0x0020},
- {0x01, 0x00ff, 0x003e},
- {0x01, 0x0003, 0x003f},
- {0x01, 0x0000, 0x0040},
- {0x01, 0x0035, 0x0041},
- {0x01, 0x0053, 0x0042},
- {0x01, 0x0069, 0x0043},
- {0x01, 0x007c, 0x0044},
- {0x01, 0x008c, 0x0045},
- {0x01, 0x009a, 0x0046},
- {0x01, 0x00a8, 0x0047},
- {0x01, 0x00b4, 0x0048},
- {0x01, 0x00bf, 0x0049},
- {0x01, 0x00ca, 0x004a},
- {0x01, 0x00d4, 0x004b},
- {0x01, 0x00dd, 0x004c},
- {0x01, 0x00e7, 0x004d},
- {0x01, 0x00ef, 0x004e},
- {0x01, 0x00f8, 0x004f},
- {0x01, 0x00ff, 0x0050},
- {0x01, 0x0001, 0x0056},
- {0x01, 0x0060, 0x0057},
- {0x01, 0x0040, 0x0058},
- {0x01, 0x0011, 0x0059},
- {0x01, 0x0001, 0x005a},
- {0x02, 0x0007, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x02, 0x0007, 0x0005},
- {0x02, 0x0015, 0x0006},
- {0x02, 0x100a, 0x0007},
- {0x02, 0xa048, 0x0000},
- {0x02, 0xc002, 0x0001},
- {0x02, 0x000f, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x05, 0x0025, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0026, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x05, 0x0027, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0001, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0021, 0x0001},
- {0x05, 0x00d2, 0x0000},
- {0x05, 0x0020, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x00, 0x0090, 0x0005},
- {0x01, 0x00a6, 0x0000},
- {0x02, 0x0007, 0x0005},
- {0x02, 0x2000, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x05, 0x0015, 0x0001},
- {0x05, 0x00ea, 0x0000},
- {0x05, 0x0021, 0x0001},
- {0x05, 0x00d2, 0x0000},
- {0x05, 0x0023, 0x0001},
- {0x05, 0x0003, 0x0000},
- {0x05, 0x0030, 0x0001},
- {0x05, 0x002b, 0x0000},
- {0x05, 0x0031, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0032, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0033, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0034, 0x0001},
- {0x05, 0x0002, 0x0000},
- {0x05, 0x0050, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0051, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0052, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0054, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x00, 0x0000, 0x0001},
- {0x00, 0x0000, 0x0002},
- {0x00, 0x000c, 0x0003},
- {0x00, 0x0000, 0x0004},
- {0x00, 0x0090, 0x0005},
- {0x00, 0x0000, 0x0006},
- {0x00, 0x0040, 0x0007},
- {0x00, 0x00c0, 0x0008},
- {0x00, 0x004a, 0x0009},
- {0x00, 0x0000, 0x000a},
- {0x00, 0x0000, 0x000b},
- {0x00, 0x0001, 0x000c},
- {0x00, 0x0001, 0x000d},
- {0x00, 0x0000, 0x000e},
- {0x00, 0x0002, 0x000f},
- {0x00, 0x0001, 0x0010},
- {0x00, 0x0000, 0x0011},
- {0x00, 0x0000, 0x0012},
- {0x00, 0x0002, 0x0020},
- {0x00, 0x0080, 0x0021},
- {0x00, 0x0001, 0x0022},
- {0x00, 0x00e0, 0x0023},
- {0x00, 0x0000, 0x0024},
- {0x00, 0x00d5, 0x0025},
- {0x00, 0x0000, 0x0026},
- {0x00, 0x000b, 0x0027},
- {0x00, 0x0000, 0x0046},
- {0x00, 0x0000, 0x0047},
- {0x00, 0x0000, 0x0048},
- {0x00, 0x0000, 0x0049},
- {0x00, 0x0008, 0x004a},
- {0xff, 0x0000, 0x00d0},
- {0xff, 0x00d8, 0x00d1},
- {0xff, 0x0000, 0x00d4},
- {0xff, 0x0000, 0x00d5},
- {0x01, 0x00a6, 0x0000},
- {0x01, 0x0028, 0x0001},
- {0x01, 0x0000, 0x0002},
- {0x01, 0x000a, 0x0003},
- {0x01, 0x0040, 0x0004},
- {0x01, 0x0066, 0x0007},
- {0x01, 0x0011, 0x0008},
- {0x01, 0x0032, 0x0009},
- {0x01, 0x00fd, 0x000a},
- {0x01, 0x0038, 0x000b},
- {0x01, 0x00d1, 0x000c},
- {0x01, 0x00f7, 0x000d},
- {0x01, 0x00ed, 0x000e},
- {0x01, 0x00d8, 0x000f},
- {0x01, 0x0038, 0x0010},
- {0x01, 0x00ff, 0x0015},
- {0x01, 0x0001, 0x0016},
- {0x01, 0x0032, 0x0017},
- {0x01, 0x0023, 0x0018},
- {0x01, 0x00ce, 0x0019},
- {0x01, 0x0023, 0x001a},
- {0x01, 0x0032, 0x001b},
- {0x01, 0x008d, 0x001c},
- {0x01, 0x00ce, 0x001d},
- {0x01, 0x008d, 0x001e},
- {0x01, 0x0000, 0x001f},
- {0x01, 0x0000, 0x0020},
- {0x01, 0x00ff, 0x003e},
- {0x01, 0x0003, 0x003f},
- {0x01, 0x0000, 0x0040},
- {0x01, 0x0035, 0x0041},
- {0x01, 0x0053, 0x0042},
- {0x01, 0x0069, 0x0043},
- {0x01, 0x007c, 0x0044},
- {0x01, 0x008c, 0x0045},
- {0x01, 0x009a, 0x0046},
- {0x01, 0x00a8, 0x0047},
- {0x01, 0x00b4, 0x0048},
- {0x01, 0x00bf, 0x0049},
- {0x01, 0x00ca, 0x004a},
- {0x01, 0x00d4, 0x004b},
- {0x01, 0x00dd, 0x004c},
- {0x01, 0x00e7, 0x004d},
- {0x01, 0x00ef, 0x004e},
- {0x01, 0x00f8, 0x004f},
- {0x01, 0x00ff, 0x0050},
- {0x01, 0x0001, 0x0056},
- {0x01, 0x0060, 0x0057},
- {0x01, 0x0040, 0x0058},
- {0x01, 0x0011, 0x0059},
- {0x01, 0x0001, 0x005a},
- {0x02, 0x0007, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x02, 0x0007, 0x0005},
- {0x02, 0x0015, 0x0006},
- {0x02, 0x100a, 0x0007},
- {0x02, 0xa048, 0x0000},
- {0x02, 0xc002, 0x0001},
- {0x02, 0x000f, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x05, 0x0025, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0026, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x05, 0x0027, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0001, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0021, 0x0001},
- {0x05, 0x00d2, 0x0000},
- {0x05, 0x0020, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x00, 0x0090, 0x0005},
- {0x01, 0x00a6, 0x0000},
- {0x05, 0x0026, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x05, 0x0027, 0x0001},
- {0x05, 0x000f, 0x0000},
- {0x01, 0x0003, 0x003f},
- {0x01, 0x0001, 0x0056},
- {0x01, 0x0011, 0x0008},
- {0x01, 0x0032, 0x0009},
- {0x01, 0xfffd, 0x000a},
- {0x01, 0x0023, 0x000b},
- {0x01, 0xffea, 0x000c},
- {0x01, 0xfff4, 0x000d},
- {0x01, 0xfffc, 0x000e},
- {0x01, 0xffe3, 0x000f},
- {0x01, 0x001f, 0x0010},
- {0x01, 0x00a8, 0x0001},
- {0x01, 0x0067, 0x0007},
- {0x01, 0x0042, 0x0051},
- {0x01, 0x0051, 0x0053},
- {0x01, 0x000a, 0x0003},
- {0x02, 0xc002, 0x0001},
- {0x02, 0x0007, 0x0005},
- {0x02, 0xc000, 0x0001},
- {0x02, 0x0000, 0x0005},
- {0x02, 0x0007, 0x0005},
- {0x02, 0x2000, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x05, 0x0015, 0x0001},
- {0x05, 0x00ea, 0x0000},
- {0x05, 0x0021, 0x0001},
- {0x05, 0x00d2, 0x0000},
- {0x05, 0x0023, 0x0001},
- {0x05, 0x0003, 0x0000},
- {0x05, 0x0030, 0x0001},
- {0x05, 0x002b, 0x0000},
- {0x05, 0x0031, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0032, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0033, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0034, 0x0001},
- {0x05, 0x0002, 0x0000},
- {0x05, 0x0050, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0051, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0052, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0054, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x00, 0x0000, 0x0001},
- {0x00, 0x0000, 0x0002},
- {0x00, 0x000c, 0x0003},
- {0x00, 0x0000, 0x0004},
- {0x00, 0x0090, 0x0005},
- {0x00, 0x0000, 0x0006},
- {0x00, 0x0040, 0x0007},
- {0x00, 0x00c0, 0x0008},
- {0x00, 0x004a, 0x0009},
- {0x00, 0x0000, 0x000a},
- {0x00, 0x0000, 0x000b},
- {0x00, 0x0001, 0x000c},
- {0x00, 0x0001, 0x000d},
- {0x00, 0x0000, 0x000e},
- {0x00, 0x0002, 0x000f},
- {0x00, 0x0001, 0x0010},
- {0x00, 0x0000, 0x0011},
- {0x00, 0x0000, 0x0012},
- {0x00, 0x0002, 0x0020},
- {0x00, 0x0080, 0x0021},
- {0x00, 0x0001, 0x0022},
- {0x00, 0x00e0, 0x0023},
- {0x00, 0x0000, 0x0024},
- {0x00, 0x00d5, 0x0025},
- {0x00, 0x0000, 0x0026},
- {0x00, 0x000b, 0x0027},
- {0x00, 0x0000, 0x0046},
- {0x00, 0x0000, 0x0047},
- {0x00, 0x0000, 0x0048},
- {0x00, 0x0000, 0x0049},
- {0x00, 0x0008, 0x004a},
- {0xff, 0x0000, 0x00d0},
- {0xff, 0x00d8, 0x00d1},
- {0xff, 0x0000, 0x00d4},
- {0xff, 0x0000, 0x00d5},
- {0x01, 0x00a6, 0x0000},
- {0x01, 0x0028, 0x0001},
- {0x01, 0x0000, 0x0002},
- {0x01, 0x000a, 0x0003},
- {0x01, 0x0040, 0x0004},
- {0x01, 0x0066, 0x0007},
- {0x01, 0x0011, 0x0008},
- {0x01, 0x0032, 0x0009},
- {0x01, 0x00fd, 0x000a},
- {0x01, 0x0038, 0x000b},
- {0x01, 0x00d1, 0x000c},
- {0x01, 0x00f7, 0x000d},
- {0x01, 0x00ed, 0x000e},
- {0x01, 0x00d8, 0x000f},
- {0x01, 0x0038, 0x0010},
- {0x01, 0x00ff, 0x0015},
- {0x01, 0x0001, 0x0016},
- {0x01, 0x0032, 0x0017},
- {0x01, 0x0023, 0x0018},
- {0x01, 0x00ce, 0x0019},
- {0x01, 0x0023, 0x001a},
- {0x01, 0x0032, 0x001b},
- {0x01, 0x008d, 0x001c},
- {0x01, 0x00ce, 0x001d},
- {0x01, 0x008d, 0x001e},
- {0x01, 0x0000, 0x001f},
- {0x01, 0x0000, 0x0020},
- {0x01, 0x00ff, 0x003e},
- {0x01, 0x0003, 0x003f},
- {0x01, 0x0000, 0x0040},
- {0x01, 0x0035, 0x0041},
- {0x01, 0x0053, 0x0042},
- {0x01, 0x0069, 0x0043},
- {0x01, 0x007c, 0x0044},
- {0x01, 0x008c, 0x0045},
- {0x01, 0x009a, 0x0046},
- {0x01, 0x00a8, 0x0047},
- {0x01, 0x00b4, 0x0048},
- {0x01, 0x00bf, 0x0049},
- {0x01, 0x00ca, 0x004a},
- {0x01, 0x00d4, 0x004b},
- {0x01, 0x00dd, 0x004c},
- {0x01, 0x00e7, 0x004d},
- {0x01, 0x00ef, 0x004e},
- {0x01, 0x00f8, 0x004f},
- {0x01, 0x00ff, 0x0050},
- {0x01, 0x0001, 0x0056},
- {0x01, 0x0060, 0x0057},
- {0x01, 0x0040, 0x0058},
- {0x01, 0x0011, 0x0059},
- {0x01, 0x0001, 0x005a},
- {0x02, 0x0007, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x02, 0x0007, 0x0005},
- {0x02, 0x0015, 0x0006},
- {0x02, 0x100a, 0x0007},
- {0x02, 0xa048, 0x0000},
- {0x02, 0xc002, 0x0001},
- {0x02, 0x000f, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x05, 0x0025, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0026, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x05, 0x0027, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0001, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0021, 0x0001},
- {0x05, 0x00d2, 0x0000},
- {0x05, 0x0020, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x00, 0x0090, 0x0005},
- {0x01, 0x00a6, 0x0000},
- {0x02, 0x0007, 0x0005},
- {0x02, 0x2000, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x05, 0x0015, 0x0001},
- {0x05, 0x00ea, 0x0000},
- {0x05, 0x0021, 0x0001},
- {0x05, 0x00d2, 0x0000},
- {0x05, 0x0023, 0x0001},
- {0x05, 0x0003, 0x0000},
- {0x05, 0x0030, 0x0001},
- {0x05, 0x002b, 0x0000},
- {0x05, 0x0031, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0032, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0033, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0034, 0x0001},
- {0x05, 0x0002, 0x0000},
- {0x05, 0x0050, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0051, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0052, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0054, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x00, 0x0000, 0x0001},
- {0x00, 0x0000, 0x0002},
- {0x00, 0x000c, 0x0003},
- {0x00, 0x0000, 0x0004},
- {0x00, 0x0090, 0x0005},
- {0x00, 0x0000, 0x0006},
- {0x00, 0x0040, 0x0007},
- {0x00, 0x00c0, 0x0008},
- {0x00, 0x004a, 0x0009},
- {0x00, 0x0000, 0x000a},
- {0x00, 0x0000, 0x000b},
- {0x00, 0x0001, 0x000c},
- {0x00, 0x0001, 0x000d},
- {0x00, 0x0000, 0x000e},
- {0x00, 0x0002, 0x000f},
- {0x00, 0x0001, 0x0010},
- {0x00, 0x0000, 0x0011},
- {0x00, 0x0000, 0x0012},
- {0x00, 0x0002, 0x0020},
- {0x00, 0x0080, 0x0021},
- {0x00, 0x0001, 0x0022},
- {0x00, 0x00e0, 0x0023},
- {0x00, 0x0000, 0x0024},
- {0x00, 0x00d5, 0x0025},
- {0x00, 0x0000, 0x0026},
- {0x00, 0x000b, 0x0027},
- {0x00, 0x0000, 0x0046},
- {0x00, 0x0000, 0x0047},
- {0x00, 0x0000, 0x0048},
- {0x00, 0x0000, 0x0049},
- {0x00, 0x0008, 0x004a},
- {0xff, 0x0000, 0x00d0},
- {0xff, 0x00d8, 0x00d1},
- {0xff, 0x0000, 0x00d4},
- {0xff, 0x0000, 0x00d5},
- {0x01, 0x00a6, 0x0000},
- {0x01, 0x0028, 0x0001},
- {0x01, 0x0000, 0x0002},
- {0x01, 0x000a, 0x0003},
- {0x01, 0x0040, 0x0004},
- {0x01, 0x0066, 0x0007},
- {0x01, 0x0011, 0x0008},
- {0x01, 0x0032, 0x0009},
- {0x01, 0x00fd, 0x000a},
- {0x01, 0x0038, 0x000b},
- {0x01, 0x00d1, 0x000c},
- {0x01, 0x00f7, 0x000d},
- {0x01, 0x00ed, 0x000e},
- {0x01, 0x00d8, 0x000f},
- {0x01, 0x0038, 0x0010},
- {0x01, 0x00ff, 0x0015},
- {0x01, 0x0001, 0x0016},
- {0x01, 0x0032, 0x0017},
- {0x01, 0x0023, 0x0018},
- {0x01, 0x00ce, 0x0019},
- {0x01, 0x0023, 0x001a},
- {0x01, 0x0032, 0x001b},
- {0x01, 0x008d, 0x001c},
- {0x01, 0x00ce, 0x001d},
- {0x01, 0x008d, 0x001e},
- {0x01, 0x0000, 0x001f},
- {0x01, 0x0000, 0x0020},
- {0x01, 0x00ff, 0x003e},
- {0x01, 0x0003, 0x003f},
- {0x01, 0x0000, 0x0040},
- {0x01, 0x0035, 0x0041},
- {0x01, 0x0053, 0x0042},
- {0x01, 0x0069, 0x0043},
- {0x01, 0x007c, 0x0044},
- {0x01, 0x008c, 0x0045},
- {0x01, 0x009a, 0x0046},
- {0x01, 0x00a8, 0x0047},
- {0x01, 0x00b4, 0x0048},
- {0x01, 0x00bf, 0x0049},
- {0x01, 0x00ca, 0x004a},
- {0x01, 0x00d4, 0x004b},
- {0x01, 0x00dd, 0x004c},
- {0x01, 0x00e7, 0x004d},
- {0x01, 0x00ef, 0x004e},
- {0x01, 0x00f8, 0x004f},
- {0x01, 0x00ff, 0x0050},
- {0x01, 0x0001, 0x0056},
- {0x01, 0x0060, 0x0057},
- {0x01, 0x0040, 0x0058},
- {0x01, 0x0011, 0x0059},
- {0x01, 0x0001, 0x005a},
- {0x02, 0x0007, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x02, 0x0007, 0x0005},
- {0x02, 0x0015, 0x0006},
- {0x02, 0x100a, 0x0007},
- {0x02, 0xa048, 0x0000},
- {0x02, 0xc002, 0x0001},
- {0x02, 0x000f, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x05, 0x0025, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0026, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x05, 0x0027, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0001, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0021, 0x0001},
- {0x05, 0x00d2, 0x0000},
- {0x05, 0x0020, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x00, 0x0090, 0x0005},
- {0x01, 0x00a6, 0x0000},
- {0x05, 0x0026, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x05, 0x0027, 0x0001},
- {0x05, 0x001e, 0x0000},
- {0x01, 0x0003, 0x003f},
- {0x01, 0x0001, 0x0056},
- {0x01, 0x0011, 0x0008},
- {0x01, 0x0032, 0x0009},
- {0x01, 0xfffd, 0x000a},
- {0x01, 0x0023, 0x000b},
- {0x01, 0xffea, 0x000c},
- {0x01, 0xfff4, 0x000d},
- {0x01, 0xfffc, 0x000e},
- {0x01, 0xffe3, 0x000f},
- {0x01, 0x001f, 0x0010},
- {0x01, 0x00a8, 0x0001},
- {0x01, 0x0067, 0x0007},
- {0x01, 0x0042, 0x0051},
- {0x01, 0x0051, 0x0053},
- {0x01, 0x000a, 0x0003},
- {0x02, 0xc002, 0x0001},
- {0x02, 0x0007, 0x0005},
- {0x01, 0x0042, 0x0051},
- {0x01, 0x0051, 0x0053},
- {0x05, 0x0026, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x05, 0x0027, 0x0001},
- {0x05, 0x002d, 0x0000},
- {0x01, 0x0003, 0x003f},
- {0x01, 0x0001, 0x0056},
- {0x02, 0xc000, 0x0001},
- {0x02, 0x0000, 0x0005},
- {}
-};
-
-/* Unknown camera from Ori Usbid 0x0000:0x0000 */
-/* Based on snoops from Ori Cohen */
-static const __u16 spca501c_mysterious_open_data[][3] = {
- {0x02, 0x000f, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x05, 0x0022, 0x0004},
-/* DSP Registers */
- {0x01, 0x0016, 0x0011}, /* RGB offset */
- {0x01, 0x0000, 0x0012},
- {0x01, 0x0006, 0x0013},
- {0x01, 0x0078, 0x0051},
- {0x01, 0x0040, 0x0052},
- {0x01, 0x0046, 0x0053},
- {0x01, 0x0040, 0x0054},
- {0x00, 0x0025, 0x0000},
-/* {0x00, 0x0000, 0x0000 }, */
-/* Part 2 */
-/* TG Registers */
- {0x00, 0x0026, 0x0000},
- {0x00, 0x0001, 0x0000},
- {0x00, 0x0027, 0x0000},
- {0x00, 0x008a, 0x0000},
- {0x02, 0x0007, 0x0005},
- {0x02, 0x2000, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x05, 0x0015, 0x0001},
- {0x05, 0x00ea, 0x0000},
- {0x05, 0x0021, 0x0001},
- {0x05, 0x00d2, 0x0000},
- {0x05, 0x0023, 0x0001},
- {0x05, 0x0003, 0x0000},
- {0x05, 0x0030, 0x0001},
- {0x05, 0x002b, 0x0000},
- {0x05, 0x0031, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0032, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0033, 0x0001},
- {0x05, 0x0023, 0x0000},
- {0x05, 0x0034, 0x0001},
- {0x05, 0x0002, 0x0000},
- {0x05, 0x0050, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0051, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0052, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0054, 0x0001},
- {0x05, 0x0001, 0x0000},
- {}
-};
-
-/* Based on snoops from Ori Cohen */
-static const __u16 spca501c_mysterious_init_data[][3] = {
-/* Part 3 */
-/* TG registers */
-/* {0x00, 0x0000, 0x0000}, */
- {0x00, 0x0000, 0x0001},
- {0x00, 0x0000, 0x0002},
- {0x00, 0x0006, 0x0003},
- {0x00, 0x0000, 0x0004},
- {0x00, 0x0090, 0x0005},
- {0x00, 0x0000, 0x0006},
- {0x00, 0x0040, 0x0007},
- {0x00, 0x00c0, 0x0008},
- {0x00, 0x004a, 0x0009},
- {0x00, 0x0000, 0x000a},
- {0x00, 0x0000, 0x000b},
- {0x00, 0x0001, 0x000c},
- {0x00, 0x0001, 0x000d},
- {0x00, 0x0000, 0x000e},
- {0x00, 0x0002, 0x000f},
- {0x00, 0x0001, 0x0010},
- {0x00, 0x0000, 0x0011},
- {0x00, 0x0001, 0x0012},
- {0x00, 0x0002, 0x0020},
- {0x00, 0x0080, 0x0021}, /* 640 */
- {0x00, 0x0001, 0x0022},
- {0x00, 0x00e0, 0x0023}, /* 480 */
- {0x00, 0x0000, 0x0024}, /* Offset H hight */
- {0x00, 0x00d3, 0x0025}, /* low */
- {0x00, 0x0000, 0x0026}, /* Offset V */
- {0x00, 0x000d, 0x0027}, /* low */
- {0x00, 0x0000, 0x0046},
- {0x00, 0x0000, 0x0047},
- {0x00, 0x0000, 0x0048},
- {0x00, 0x0000, 0x0049},
- {0x00, 0x0008, 0x004a},
-/* DSP Registers */
- {0x01, 0x00a6, 0x0000},
- {0x01, 0x0028, 0x0001},
- {0x01, 0x0000, 0x0002},
- {0x01, 0x000a, 0x0003}, /* Level Calc bit7 ->1 Auto */
- {0x01, 0x0040, 0x0004},
- {0x01, 0x0066, 0x0007},
- {0x01, 0x000f, 0x0008}, /* A11 Color correction coeff */
- {0x01, 0x002d, 0x0009}, /* A12 */
- {0x01, 0x0005, 0x000a}, /* A13 */
- {0x01, 0x0023, 0x000b}, /* A21 */
- {0x01, 0x00e0, 0x000c}, /* A22 */
- {0x01, 0x00fd, 0x000d}, /* A23 */
- {0x01, 0x00f4, 0x000e}, /* A31 */
- {0x01, 0x00e4, 0x000f}, /* A32 */
- {0x01, 0x0028, 0x0010}, /* A33 */
- {0x01, 0x00ff, 0x0015}, /* Reserved */
- {0x01, 0x0001, 0x0016}, /* Reserved */
- {0x01, 0x0032, 0x0017}, /* Win1 Start begin */
- {0x01, 0x0023, 0x0018},
- {0x01, 0x00ce, 0x0019},
- {0x01, 0x0023, 0x001a},
- {0x01, 0x0032, 0x001b},
- {0x01, 0x008d, 0x001c},
- {0x01, 0x00ce, 0x001d},
- {0x01, 0x008d, 0x001e},
- {0x01, 0x0000, 0x001f},
- {0x01, 0x0000, 0x0020}, /* Win1 Start end */
- {0x01, 0x00ff, 0x003e}, /* Reserved begin */
- {0x01, 0x0002, 0x003f},
- {0x01, 0x0000, 0x0040},
- {0x01, 0x0035, 0x0041},
- {0x01, 0x0053, 0x0042},
- {0x01, 0x0069, 0x0043},
- {0x01, 0x007c, 0x0044},
- {0x01, 0x008c, 0x0045},
- {0x01, 0x009a, 0x0046},
- {0x01, 0x00a8, 0x0047},
- {0x01, 0x00b4, 0x0048},
- {0x01, 0x00bf, 0x0049},
- {0x01, 0x00ca, 0x004a},
- {0x01, 0x00d4, 0x004b},
- {0x01, 0x00dd, 0x004c},
- {0x01, 0x00e7, 0x004d},
- {0x01, 0x00ef, 0x004e},
- {0x01, 0x00f8, 0x004f},
- {0x01, 0x00ff, 0x0050},
- {0x01, 0x0003, 0x0056}, /* Reserved end */
- {0x01, 0x0060, 0x0057}, /* Edge Gain */
- {0x01, 0x0040, 0x0058},
- {0x01, 0x0011, 0x0059}, /* Edge Bandwidth */
- {0x01, 0x0001, 0x005a},
- {0x02, 0x0007, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x02, 0x0007, 0x0005},
- {0x02, 0x0015, 0x0006},
- {0x02, 0x200a, 0x0007},
- {0x02, 0xa048, 0x0000},
- {0x02, 0xc000, 0x0001},
- {0x02, 0x000f, 0x0005},
- {0x02, 0xa048, 0x0000},
- {0x05, 0x0022, 0x0004},
- {0x05, 0x0025, 0x0001},
- {0x05, 0x0000, 0x0000},
-/* Part 4 */
- {0x05, 0x0026, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x05, 0x0027, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0001, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x05, 0x0021, 0x0001},
- {0x05, 0x00d2, 0x0000},
- {0x05, 0x0020, 0x0001},
- {0x05, 0x0000, 0x0000},
- {0x00, 0x0090, 0x0005},
- {0x01, 0x00a6, 0x0000},
- {0x02, 0x0000, 0x0005},
- {0x05, 0x0026, 0x0001},
- {0x05, 0x0001, 0x0000},
- {0x05, 0x0027, 0x0001},
- {0x05, 0x004e, 0x0000},
-/* Part 5 */
- {0x01, 0x0003, 0x003f},
- {0x01, 0x0001, 0x0056},
- {0x01, 0x000f, 0x0008},
- {0x01, 0x002d, 0x0009},
- {0x01, 0x0005, 0x000a},
- {0x01, 0x0023, 0x000b},
- {0x01, 0xffe0, 0x000c},
- {0x01, 0xfffd, 0x000d},
- {0x01, 0xfff4, 0x000e},
- {0x01, 0xffe4, 0x000f},
- {0x01, 0x0028, 0x0010},
- {0x01, 0x00a8, 0x0001},
- {0x01, 0x0066, 0x0007},
- {0x01, 0x0032, 0x0017},
- {0x01, 0x0023, 0x0018},
- {0x01, 0x00ce, 0x0019},
- {0x01, 0x0023, 0x001a},
- {0x01, 0x0032, 0x001b},
- {0x01, 0x008d, 0x001c},
- {0x01, 0x00ce, 0x001d},
- {0x01, 0x008d, 0x001e},
- {0x01, 0x00c8, 0x0015}, /* c8 Poids fort Luma */
- {0x01, 0x0032, 0x0016}, /* 32 */
- {0x01, 0x0016, 0x0011}, /* R 00 */
- {0x01, 0x0016, 0x0012}, /* G 00 */
- {0x01, 0x0016, 0x0013}, /* B 00 */
- {0x01, 0x000a, 0x0003},
- {0x02, 0xc002, 0x0001},
- {0x02, 0x0007, 0x0005},
- {}
-};
-
-static int reg_write(struct usb_device *dev,
- __u16 req, __u16 index, __u16 value)
-{
- int ret;
-
- ret = usb_control_msg(dev,
- usb_sndctrlpipe(dev, 0),
- req,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, NULL, 0, 500);
- PDEBUG(D_USBO, "reg write: 0x%02x 0x%02x 0x%02x",
- req, index, value);
- if (ret < 0)
- pr_err("reg write: error %d\n", ret);
- return ret;
-}
-
-
-static int write_vector(struct gspca_dev *gspca_dev,
- const __u16 data[][3])
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret, i = 0;
-
- while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
- ret = reg_write(dev, data[i][0], data[i][2], data[i][1]);
- if (ret < 0) {
- PDEBUG(D_ERR,
- "Reg write failed for 0x%02x,0x%02x,0x%02x",
- data[i][0], data[i][1], data[i][2]);
- return ret;
- }
- i++;
- }
- return 0;
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, val);
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_write(gspca_dev->dev, 0x00, 0x00,
- (val >> 8) & 0xff);
- reg_write(gspca_dev->dev, 0x00, 0x01,
- val & 0xff);
-}
-
-static void setcolors(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, val);
-}
-
-static void setblue_balance(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, val);
-}
-
-static void setred_balance(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, val);
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
-
- cam = &gspca_dev->cam;
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- sd->subtype = id->driver_info;
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->subtype) {
- case Arowana300KCMOSCamera:
- case SmileIntlCamera:
- /* Arowana 300k CMOS Camera data */
- if (write_vector(gspca_dev, spca501c_arowana_init_data))
- goto error;
- break;
- case MystFromOriUnknownCamera:
- /* Unknown Ori CMOS Camera data */
- if (write_vector(gspca_dev, spca501c_mysterious_open_data))
- goto error;
- break;
- default:
- /* generic spca501 init data */
- if (write_vector(gspca_dev, spca501_init_data))
- goto error;
- break;
- }
- PDEBUG(D_STREAM, "Initializing SPCA501 finished");
- return 0;
-error:
- return -EINVAL;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct usb_device *dev = gspca_dev->dev;
- int mode;
-
- switch (sd->subtype) {
- case ThreeComHomeConnectLite:
- /* Special handling for 3com data */
- write_vector(gspca_dev, spca501_3com_open_data);
- break;
- case Arowana300KCMOSCamera:
- case SmileIntlCamera:
- /* Arowana 300k CMOS Camera data */
- write_vector(gspca_dev, spca501c_arowana_open_data);
- break;
- case MystFromOriUnknownCamera:
- /* Unknown CMOS Camera data */
- write_vector(gspca_dev, spca501c_mysterious_init_data);
- break;
- default:
- /* Generic 501 open data */
- write_vector(gspca_dev, spca501_open_data);
- }
-
- /* memorize the wanted pixel format */
- mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
-
- /* Enable ISO packet machine CTRL reg=2,
- * index=1 bitmask=0x2 (bit ordinal 1) */
- reg_write(dev, SPCA50X_REG_USB, 0x6, 0x94);
- switch (mode) {
- case 0: /* 640x480 */
- reg_write(dev, SPCA50X_REG_USB, 0x07, 0x004a);
- break;
- case 1: /* 320x240 */
- reg_write(dev, SPCA50X_REG_USB, 0x07, 0x104a);
- break;
- default:
-/* case 2: * 160x120 */
- reg_write(dev, SPCA50X_REG_USB, 0x07, 0x204a);
- break;
- }
- reg_write(dev, SPCA501_REG_CTLRL, 0x01, 0x02);
-
- return 0;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- /* Disable ISO packet
- * machine CTRL reg=2, index=1 bitmask=0x0 (bit ordinal 1) */
- reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x01, 0x00);
-}
-
-/* called on streamoff with alt 0 and on disconnect */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- if (!gspca_dev->present)
- return;
- reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- switch (data[0]) {
- case 0: /* start of frame */
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
- data += SPCA501_OFFSET_DATA;
- len -= SPCA501_OFFSET_DATA;
- gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
- return;
- case 0xff: /* drop */
-/* gspca_dev->last_packet_type = DISCARD_PACKET; */
- return;
- }
- data++;
- len--;
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- setcolors(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_BLUE_BALANCE:
- setblue_balance(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_RED_BALANCE:
- setred_balance(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 5);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 127, 1, 0);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 64725, 1, 64725);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0, 63, 1, 20);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_RED_BALANCE, 0, 127, 1, 0);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x040a, 0x0002), .driver_info = KodakDVC325},
- {USB_DEVICE(0x0497, 0xc001), .driver_info = SmileIntlCamera},
- {USB_DEVICE(0x0506, 0x00df), .driver_info = ThreeComHomeConnectLite},
- {USB_DEVICE(0x0733, 0x0401), .driver_info = IntelCreateAndShare},
- {USB_DEVICE(0x0733, 0x0402), .driver_info = ViewQuestM318B},
- {USB_DEVICE(0x1776, 0x501c), .driver_info = Arowana300KCMOSCamera},
- {USB_DEVICE(0x0000, 0x0000), .driver_info = MystFromOriUnknownCamera},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
deleted file mode 100644
index bc7d67c3cb0..00000000000
--- a/drivers/media/video/gspca/spca505.c
+++ /dev/null
@@ -1,807 +0,0 @@
-/*
- * SPCA505 chip based cameras initialization data
- *
- * V4L2 by Jean-Francis Moine <http://moinejf.free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "spca505"
-
-#include "gspca.h"
-
-MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
-MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- u8 subtype;
-#define IntelPCCameraPro 0
-#define Nxultra 1
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 4},
- {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 3},
- {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
- {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-#define SPCA50X_OFFSET_DATA 10
-
-#define SPCA50X_REG_USB 0x02 /* spca505 501 */
-
-#define SPCA50X_USB_CTRL 0x00 /* spca505 */
-#define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */
-
-#define SPCA50X_REG_GLOBAL 0x03 /* spca505 */
-#define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */
-#define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */
-
-#define SPCA50X_GLOBAL_MISC1 0x01 /* 505 */
-#define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */
-#define SPCA50X_GMISC3_SAA7113RST 0x20 /* Not sure about this one spca505 */
-
-/* Image format and compression control */
-#define SPCA50X_REG_COMPRESS 0x04
-
-/*
- * Data to initialize a SPCA505. Common to the CCD and external modes
- */
-static const u8 spca505_init_data[][3] = {
- /* bmRequest,value,index */
- {SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3},
- /* Sensor reset */
- {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3},
- {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1},
- /* Block USB reset */
- {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, SPCA50X_GLOBAL_MISC0},
-
- {0x05, 0x01, 0x10},
- /* Maybe power down some stuff */
- {0x05, 0x0f, 0x11},
-
- /* Setup internal CCD ? */
- {0x06, 0x10, 0x08},
- {0x06, 0x00, 0x09},
- {0x06, 0x00, 0x0a},
- {0x06, 0x00, 0x0b},
- {0x06, 0x10, 0x0c},
- {0x06, 0x00, 0x0d},
- {0x06, 0x00, 0x0e},
- {0x06, 0x00, 0x0f},
- {0x06, 0x10, 0x10},
- {0x06, 0x02, 0x11},
- {0x06, 0x00, 0x12},
- {0x06, 0x04, 0x13},
- {0x06, 0x02, 0x14},
- {0x06, 0x8a, 0x51},
- {0x06, 0x40, 0x52},
- {0x06, 0xb6, 0x53},
- {0x06, 0x3d, 0x54},
- {}
-};
-
-/*
- * Data to initialize the camera using the internal CCD
- */
-static const u8 spca505_open_data_ccd[][3] = {
- /* bmRequest,value,index */
- /* Internal CCD data set */
- {0x03, 0x04, 0x01},
- /* This could be a reset */
- {0x03, 0x00, 0x01},
-
- /* Setup compression and image registers. 0x6 and 0x7 seem to be
- related to H&V hold, and are resolution mode specific */
- {0x04, 0x10, 0x01},
- /* DIFF(0x50), was (0x10) */
- {0x04, 0x00, 0x04},
- {0x04, 0x00, 0x05},
- {0x04, 0x20, 0x06},
- {0x04, 0x20, 0x07},
-
- {0x08, 0x0a, 0x00},
- /* DIFF (0x4a), was (0xa) */
-
- {0x05, 0x00, 0x10},
- {0x05, 0x00, 0x11},
- {0x05, 0x00, 0x00},
- /* DIFF not written */
- {0x05, 0x00, 0x01},
- /* DIFF not written */
- {0x05, 0x00, 0x02},
- /* DIFF not written */
- {0x05, 0x00, 0x03},
- /* DIFF not written */
- {0x05, 0x00, 0x04},
- /* DIFF not written */
- {0x05, 0x80, 0x05},
- /* DIFF not written */
- {0x05, 0xe0, 0x06},
- /* DIFF not written */
- {0x05, 0x20, 0x07},
- /* DIFF not written */
- {0x05, 0xa0, 0x08},
- /* DIFF not written */
- {0x05, 0x0, 0x12},
- /* DIFF not written */
- {0x05, 0x02, 0x0f},
- /* DIFF not written */
- {0x05, 0x10, 0x46},
- /* DIFF not written */
- {0x05, 0x8, 0x4a},
- /* DIFF not written */
-
- {0x03, 0x08, 0x03},
- /* DIFF (0x3,0x28,0x3) */
- {0x03, 0x08, 0x01},
- {0x03, 0x0c, 0x03},
- /* DIFF not written */
- {0x03, 0x21, 0x00},
- /* DIFF (0x39) */
-
-/* Extra block copied from init to hopefully ensure CCD is in a sane state */
- {0x06, 0x10, 0x08},
- {0x06, 0x00, 0x09},
- {0x06, 0x00, 0x0a},
- {0x06, 0x00, 0x0b},
- {0x06, 0x10, 0x0c},
- {0x06, 0x00, 0x0d},
- {0x06, 0x00, 0x0e},
- {0x06, 0x00, 0x0f},
- {0x06, 0x10, 0x10},
- {0x06, 0x02, 0x11},
- {0x06, 0x00, 0x12},
- {0x06, 0x04, 0x13},
- {0x06, 0x02, 0x14},
- {0x06, 0x8a, 0x51},
- {0x06, 0x40, 0x52},
- {0x06, 0xb6, 0x53},
- {0x06, 0x3d, 0x54},
- /* End of extra block */
-
- {0x06, 0x3f, 0x1},
- /* Block skipped */
- {0x06, 0x10, 0x02},
- {0x06, 0x64, 0x07},
- {0x06, 0x10, 0x08},
- {0x06, 0x00, 0x09},
- {0x06, 0x00, 0x0a},
- {0x06, 0x00, 0x0b},
- {0x06, 0x10, 0x0c},
- {0x06, 0x00, 0x0d},
- {0x06, 0x00, 0x0e},
- {0x06, 0x00, 0x0f},
- {0x06, 0x10, 0x10},
- {0x06, 0x02, 0x11},
- {0x06, 0x00, 0x12},
- {0x06, 0x04, 0x13},
- {0x06, 0x02, 0x14},
- {0x06, 0x8a, 0x51},
- {0x06, 0x40, 0x52},
- {0x06, 0xb6, 0x53},
- {0x06, 0x3d, 0x54},
- {0x06, 0x60, 0x57},
- {0x06, 0x20, 0x58},
- {0x06, 0x15, 0x59},
- {0x06, 0x05, 0x5a},
-
- {0x05, 0x01, 0xc0},
- {0x05, 0x10, 0xcb},
- {0x05, 0x80, 0xc1},
- /* */
- {0x05, 0x0, 0xc2},
- /* 4 was 0 */
- {0x05, 0x00, 0xca},
- {0x05, 0x80, 0xc1},
- /* */
- {0x05, 0x04, 0xc2},
- {0x05, 0x00, 0xca},
- {0x05, 0x0, 0xc1},
- /* */
- {0x05, 0x00, 0xc2},
- {0x05, 0x00, 0xca},
- {0x05, 0x40, 0xc1},
- /* */
- {0x05, 0x17, 0xc2},
- {0x05, 0x00, 0xca},
- {0x05, 0x80, 0xc1},
- /* */
- {0x05, 0x06, 0xc2},
- {0x05, 0x00, 0xca},
- {0x05, 0x80, 0xc1},
- /* */
- {0x05, 0x04, 0xc2},
- {0x05, 0x00, 0xca},
-
- {0x03, 0x4c, 0x3},
- {0x03, 0x18, 0x1},
-
- {0x06, 0x70, 0x51},
- {0x06, 0xbe, 0x53},
- {0x06, 0x71, 0x57},
- {0x06, 0x20, 0x58},
- {0x06, 0x05, 0x59},
- {0x06, 0x15, 0x5a},
-
- {0x04, 0x00, 0x08},
- /* Compress = OFF (0x1 to turn on) */
- {0x04, 0x12, 0x09},
- {0x04, 0x21, 0x0a},
- {0x04, 0x10, 0x0b},
- {0x04, 0x21, 0x0c},
- {0x04, 0x05, 0x00},
- /* was 5 (Image Type ? ) */
- {0x04, 0x00, 0x01},
-
- {0x06, 0x3f, 0x01},
-
- {0x04, 0x00, 0x04},
- {0x04, 0x00, 0x05},
- {0x04, 0x40, 0x06},
- {0x04, 0x40, 0x07},
-
- {0x06, 0x1c, 0x17},
- {0x06, 0xe2, 0x19},
- {0x06, 0x1c, 0x1b},
- {0x06, 0xe2, 0x1d},
- {0x06, 0xaa, 0x1f},
- {0x06, 0x70, 0x20},
-
- {0x05, 0x01, 0x10},
- {0x05, 0x00, 0x11},
- {0x05, 0x01, 0x00},
- {0x05, 0x05, 0x01},
- {0x05, 0x00, 0xc1},
- /* */
- {0x05, 0x00, 0xc2},
- {0x05, 0x00, 0xca},
-
- {0x06, 0x70, 0x51},
- {0x06, 0xbe, 0x53},
- {}
-};
-
-/*
- * Made by Tomasz Zablocki (skalamandra@poczta.onet.pl)
- * SPCA505b chip based cameras initialization data
- */
-/* jfm */
-#define initial_brightness 0x7f /* 0x0(white)-0xff(black) */
-/* #define initial_brightness 0x0 //0x0(white)-0xff(black) */
-/*
- * Data to initialize a SPCA505. Common to the CCD and external modes
- */
-static const u8 spca505b_init_data[][3] = {
-/* start */
- {0x02, 0x00, 0x00}, /* init */
- {0x02, 0x00, 0x01},
- {0x02, 0x00, 0x02},
- {0x02, 0x00, 0x03},
- {0x02, 0x00, 0x04},
- {0x02, 0x00, 0x05},
- {0x02, 0x00, 0x06},
- {0x02, 0x00, 0x07},
- {0x02, 0x00, 0x08},
- {0x02, 0x00, 0x09},
- {0x03, 0x00, 0x00},
- {0x03, 0x00, 0x01},
- {0x03, 0x00, 0x02},
- {0x03, 0x00, 0x03},
- {0x03, 0x00, 0x04},
- {0x03, 0x00, 0x05},
- {0x03, 0x00, 0x06},
- {0x04, 0x00, 0x00},
- {0x04, 0x00, 0x02},
- {0x04, 0x00, 0x04},
- {0x04, 0x00, 0x05},
- {0x04, 0x00, 0x06},
- {0x04, 0x00, 0x07},
- {0x04, 0x00, 0x08},
- {0x04, 0x00, 0x09},
- {0x04, 0x00, 0x0a},
- {0x04, 0x00, 0x0b},
- {0x04, 0x00, 0x0c},
- {0x07, 0x00, 0x00},
- {0x07, 0x00, 0x03},
- {0x08, 0x00, 0x00},
- {0x08, 0x00, 0x01},
- {0x08, 0x00, 0x02},
- {0x06, 0x18, 0x08},
- {0x06, 0xfc, 0x09},
- {0x06, 0xfc, 0x0a},
- {0x06, 0xfc, 0x0b},
- {0x06, 0x18, 0x0c},
- {0x06, 0xfc, 0x0d},
- {0x06, 0xfc, 0x0e},
- {0x06, 0xfc, 0x0f},
- {0x06, 0x18, 0x10},
- {0x06, 0xfe, 0x12},
- {0x06, 0x00, 0x11},
- {0x06, 0x00, 0x14},
- {0x06, 0x00, 0x13},
- {0x06, 0x28, 0x51},
- {0x06, 0xff, 0x53},
- {0x02, 0x00, 0x08},
-
- {0x03, 0x00, 0x03},
- {0x03, 0x10, 0x03},
- {}
-};
-
-/*
- * Data to initialize the camera using the internal CCD
- */
-static const u8 spca505b_open_data_ccd[][3] = {
-
-/* {0x02,0x00,0x00}, */
- {0x03, 0x04, 0x01}, /* rst */
- {0x03, 0x00, 0x01},
- {0x03, 0x00, 0x00},
- {0x03, 0x21, 0x00},
- {0x03, 0x00, 0x04},
- {0x03, 0x00, 0x03},
- {0x03, 0x18, 0x03},
- {0x03, 0x08, 0x01},
- {0x03, 0x1c, 0x03},
- {0x03, 0x5c, 0x03},
- {0x03, 0x5c, 0x03},
- {0x03, 0x18, 0x01},
-
-/* same as 505 */
- {0x04, 0x10, 0x01},
- {0x04, 0x00, 0x04},
- {0x04, 0x00, 0x05},
- {0x04, 0x20, 0x06},
- {0x04, 0x20, 0x07},
-
- {0x08, 0x0a, 0x00},
-
- {0x05, 0x00, 0x10},
- {0x05, 0x00, 0x11},
- {0x05, 0x00, 0x12},
- {0x05, 0x6f, 0x00},
- {0x05, initial_brightness >> 6, 0x00},
- {0x05, (initial_brightness << 2) & 0xff, 0x01},
- {0x05, 0x00, 0x02},
- {0x05, 0x01, 0x03},
- {0x05, 0x00, 0x04},
- {0x05, 0x03, 0x05},
- {0x05, 0xe0, 0x06},
- {0x05, 0x20, 0x07},
- {0x05, 0xa0, 0x08},
- {0x05, 0x00, 0x12},
- {0x05, 0x02, 0x0f},
- {0x05, 0x80, 0x14}, /* max exposure off (0=on) */
- {0x05, 0x01, 0xb0},
- {0x05, 0x01, 0xbf},
- {0x03, 0x02, 0x06},
- {0x05, 0x10, 0x46},
- {0x05, 0x08, 0x4a},
-
- {0x06, 0x00, 0x01},
- {0x06, 0x10, 0x02},
- {0x06, 0x64, 0x07},
- {0x06, 0x18, 0x08},
- {0x06, 0xfc, 0x09},
- {0x06, 0xfc, 0x0a},
- {0x06, 0xfc, 0x0b},
- {0x04, 0x00, 0x01},
- {0x06, 0x18, 0x0c},
- {0x06, 0xfc, 0x0d},
- {0x06, 0xfc, 0x0e},
- {0x06, 0xfc, 0x0f},
- {0x06, 0x11, 0x10}, /* contrast */
- {0x06, 0x00, 0x11},
- {0x06, 0xfe, 0x12},
- {0x06, 0x00, 0x13},
- {0x06, 0x00, 0x14},
- {0x06, 0x9d, 0x51},
- {0x06, 0x40, 0x52},
- {0x06, 0x7c, 0x53},
- {0x06, 0x40, 0x54},
- {0x06, 0x02, 0x57},
- {0x06, 0x03, 0x58},
- {0x06, 0x15, 0x59},
- {0x06, 0x05, 0x5a},
- {0x06, 0x03, 0x56},
- {0x06, 0x02, 0x3f},
- {0x06, 0x00, 0x40},
- {0x06, 0x39, 0x41},
- {0x06, 0x69, 0x42},
- {0x06, 0x87, 0x43},
- {0x06, 0x9e, 0x44},
- {0x06, 0xb1, 0x45},
- {0x06, 0xbf, 0x46},
- {0x06, 0xcc, 0x47},
- {0x06, 0xd5, 0x48},
- {0x06, 0xdd, 0x49},
- {0x06, 0xe3, 0x4a},
- {0x06, 0xe8, 0x4b},
- {0x06, 0xed, 0x4c},
- {0x06, 0xf2, 0x4d},
- {0x06, 0xf7, 0x4e},
- {0x06, 0xfc, 0x4f},
- {0x06, 0xff, 0x50},
-
- {0x05, 0x01, 0xc0},
- {0x05, 0x10, 0xcb},
- {0x05, 0x40, 0xc1},
- {0x05, 0x04, 0xc2},
- {0x05, 0x00, 0xca},
- {0x05, 0x40, 0xc1},
- {0x05, 0x09, 0xc2},
- {0x05, 0x00, 0xca},
- {0x05, 0xc0, 0xc1},
- {0x05, 0x09, 0xc2},
- {0x05, 0x00, 0xca},
- {0x05, 0x40, 0xc1},
- {0x05, 0x59, 0xc2},
- {0x05, 0x00, 0xca},
- {0x04, 0x00, 0x01},
- {0x05, 0x80, 0xc1},
- {0x05, 0xec, 0xc2},
- {0x05, 0x0, 0xca},
-
- {0x06, 0x02, 0x57},
- {0x06, 0x01, 0x58},
- {0x06, 0x15, 0x59},
- {0x06, 0x0a, 0x5a},
- {0x06, 0x01, 0x57},
- {0x06, 0x8a, 0x03},
- {0x06, 0x0a, 0x6c},
- {0x06, 0x30, 0x01},
- {0x06, 0x20, 0x02},
- {0x06, 0x00, 0x03},
-
- {0x05, 0x8c, 0x25},
-
- {0x06, 0x4d, 0x51}, /* maybe saturation (4d) */
- {0x06, 0x84, 0x53}, /* making green (84) */
- {0x06, 0x00, 0x57}, /* sharpness (1) */
- {0x06, 0x18, 0x08},
- {0x06, 0xfc, 0x09},
- {0x06, 0xfc, 0x0a},
- {0x06, 0xfc, 0x0b},
- {0x06, 0x18, 0x0c}, /* maybe hue (18) */
- {0x06, 0xfc, 0x0d},
- {0x06, 0xfc, 0x0e},
- {0x06, 0xfc, 0x0f},
- {0x06, 0x18, 0x10}, /* maybe contrast (18) */
-
- {0x05, 0x01, 0x02},
-
- {0x04, 0x00, 0x08}, /* compression */
- {0x04, 0x12, 0x09},
- {0x04, 0x21, 0x0a},
- {0x04, 0x10, 0x0b},
- {0x04, 0x21, 0x0c},
- {0x04, 0x1d, 0x00}, /* imagetype (1d) */
- {0x04, 0x41, 0x01}, /* hardware snapcontrol */
-
- {0x04, 0x00, 0x04},
- {0x04, 0x00, 0x05},
- {0x04, 0x10, 0x06},
- {0x04, 0x10, 0x07},
- {0x04, 0x40, 0x06},
- {0x04, 0x40, 0x07},
- {0x04, 0x00, 0x04},
- {0x04, 0x00, 0x05},
-
- {0x06, 0x1c, 0x17},
- {0x06, 0xe2, 0x19},
- {0x06, 0x1c, 0x1b},
- {0x06, 0xe2, 0x1d},
- {0x06, 0x5f, 0x1f},
- {0x06, 0x32, 0x20},
-
- {0x05, initial_brightness >> 6, 0x00},
- {0x05, (initial_brightness << 2) & 0xff, 0x01},
- {0x05, 0x06, 0xc1},
- {0x05, 0x58, 0xc2},
- {0x05, 0x00, 0xca},
- {0x05, 0x00, 0x11},
- {}
-};
-
-static int reg_write(struct usb_device *dev,
- u16 req, u16 index, u16 value)
-{
- int ret;
-
- ret = usb_control_msg(dev,
- usb_sndctrlpipe(dev, 0),
- req,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, NULL, 0, 500);
- PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
- req, index, value, ret);
- if (ret < 0)
- pr_err("reg write: error %d\n", ret);
- return ret;
-}
-
-/* returns: negative is error, pos or zero is data */
-static int reg_read(struct gspca_dev *gspca_dev,
- u16 req, /* bRequest */
- u16 index) /* wIndex */
-{
- int ret;
-
- ret = usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, /* value */
- index,
- gspca_dev->usb_buf, 2,
- 500); /* timeout */
- if (ret < 0)
- return ret;
- return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
-}
-
-static int write_vector(struct gspca_dev *gspca_dev,
- const u8 data[][3])
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret, i = 0;
-
- while (data[i][0] != 0) {
- ret = reg_write(dev, data[i][0], data[i][2], data[i][1]);
- if (ret < 0)
- return ret;
- i++;
- }
- return 0;
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
-
- cam = &gspca_dev->cam;
- cam->cam_mode = vga_mode;
- sd->subtype = id->driver_info;
- if (sd->subtype != IntelPCCameraPro)
- cam->nmodes = ARRAY_SIZE(vga_mode);
- else /* no 640x480 for IntelPCCameraPro */
- cam->nmodes = ARRAY_SIZE(vga_mode) - 1;
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (write_vector(gspca_dev,
- sd->subtype == Nxultra
- ? spca505b_init_data
- : spca505_init_data))
- return -EIO;
- return 0;
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
-{
- reg_write(gspca_dev->dev, 0x05, 0x00, (255 - brightness) >> 6);
- reg_write(gspca_dev->dev, 0x05, 0x01, (255 - brightness) << 2);
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct usb_device *dev = gspca_dev->dev;
- int ret, mode;
- static u8 mode_tb[][3] = {
- /* r00 r06 r07 */
- {0x00, 0x10, 0x10}, /* 640x480 */
- {0x01, 0x1a, 0x1a}, /* 352x288 */
- {0x02, 0x1c, 0x1d}, /* 320x240 */
- {0x04, 0x34, 0x34}, /* 176x144 */
- {0x05, 0x40, 0x40} /* 160x120 */
- };
-
- if (sd->subtype == Nxultra)
- write_vector(gspca_dev, spca505b_open_data_ccd);
- else
- write_vector(gspca_dev, spca505_open_data_ccd);
- ret = reg_read(gspca_dev, 0x06, 0x16);
-
- if (ret < 0) {
- PDEBUG(D_ERR|D_CONF,
- "register read failed err: %d",
- ret);
- return ret;
- }
- if (ret != 0x0101) {
- pr_err("After vector read returns 0x%04x should be 0x0101\n",
- ret);
- }
-
- ret = reg_write(gspca_dev->dev, 0x06, 0x16, 0x0a);
- if (ret < 0)
- return ret;
- reg_write(gspca_dev->dev, 0x05, 0xc2, 0x12);
-
- /* necessary because without it we can see stream
- * only once after loading module */
- /* stopping usb registers Tomasz change */
- reg_write(dev, 0x02, 0x00, 0x00);
-
- mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
- reg_write(dev, SPCA50X_REG_COMPRESS, 0x00, mode_tb[mode][0]);
- reg_write(dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]);
- reg_write(dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]);
-
- return reg_write(dev, SPCA50X_REG_USB,
- SPCA50X_USB_CTRL,
- SPCA50X_CUSB_ENABLE);
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- /* Disable ISO packet machine */
- reg_write(gspca_dev->dev, 0x02, 0x00, 0x00);
-}
-
-/* called on streamoff with alt 0 and on disconnect */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- if (!gspca_dev->present)
- return;
-
- /* This maybe reset or power control */
- reg_write(gspca_dev->dev, 0x03, 0x03, 0x20);
- reg_write(gspca_dev->dev, 0x03, 0x01, 0x00);
- reg_write(gspca_dev->dev, 0x03, 0x00, 0x01);
- reg_write(gspca_dev->dev, 0x05, 0x10, 0x01);
- reg_write(gspca_dev->dev, 0x05, 0x11, 0x0f);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- switch (data[0]) {
- case 0: /* start of frame */
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
- data += SPCA50X_OFFSET_DATA;
- len -= SPCA50X_OFFSET_DATA;
- gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
- break;
- case 0xff: /* drop */
- break;
- default:
- data += 1;
- len -= 1;
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
- break;
- }
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 5);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init_controls = sd_init_controls,
- .init = sd_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra},
- {USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro},
-/*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
deleted file mode 100644
index bab01c86c31..00000000000
--- a/drivers/media/video/gspca/spca506.c
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * SPCA506 chip based cameras function
- * M Xhaard 15/04/2004 based on different work Mark Taylor and others
- * and my own snoopy file on a pv-321c donate by a german compagny
- * "Firma Frank Gmbh" from Saarbruecken
- *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define MODULE_NAME "spca506"
-
-#include "gspca.h"
-
-MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
-MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- char norme;
- char channel;
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 5},
- {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 4},
- {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
- {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-#define SPCA50X_OFFSET_DATA 10
-
-#define SAA7113_bright 0x0a /* defaults 0x80 */
-#define SAA7113_contrast 0x0b /* defaults 0x47 */
-#define SAA7113_saturation 0x0c /* defaults 0x40 */
-#define SAA7113_hue 0x0d /* defaults 0x00 */
-#define SAA7113_I2C_BASE_WRITE 0x4a
-
-/* read 'len' bytes to gspca_dev->usb_buf */
-static void reg_r(struct gspca_dev *gspca_dev,
- __u16 req,
- __u16 index,
- __u16 length)
-{
- usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, /* value */
- index, gspca_dev->usb_buf, length,
- 500);
-}
-
-static void reg_w(struct usb_device *dev,
- __u16 req,
- __u16 value,
- __u16 index)
-{
- usb_control_msg(dev,
- usb_sndctrlpipe(dev, 0),
- req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index,
- NULL, 0, 500);
-}
-
-static void spca506_Initi2c(struct gspca_dev *gspca_dev)
-{
- reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004);
-}
-
-static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur,
- __u16 reg)
-{
- int retry = 60;
-
- reg_w(gspca_dev->dev, 0x07, reg, 0x0001);
- reg_w(gspca_dev->dev, 0x07, valeur, 0x0000);
- while (retry--) {
- reg_r(gspca_dev, 0x07, 0x0003, 2);
- if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00)
- break;
- }
-}
-
-static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
- __u16 norme,
- __u16 channel)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-/* fixme: check if channel == 0..3 and 6..9 (8 values) */
- __u8 setbit0 = 0x00;
- __u8 setbit1 = 0x00;
- __u8 videomask = 0x00;
-
- PDEBUG(D_STREAM, "** Open Set Norme **");
- spca506_Initi2c(gspca_dev);
- /* NTSC bit0 -> 1(525 l) PAL SECAM bit0 -> 0 (625 l) */
- /* Composite channel bit1 -> 1 S-video bit 1 -> 0 */
- /* and exclude SAA7113 reserved channel set default 0 otherwise */
- if (norme & V4L2_STD_NTSC)
- setbit0 = 0x01;
- if (channel == 4 || channel == 5 || channel > 9)
- channel = 0;
- if (channel < 4)
- setbit1 = 0x02;
- videomask = (0x48 | setbit0 | setbit1);
- reg_w(gspca_dev->dev, 0x08, videomask, 0x0000);
- spca506_WriteI2c(gspca_dev, (0xc0 | (channel & 0x0F)), 0x02);
-
- if (norme & V4L2_STD_NTSC)
- spca506_WriteI2c(gspca_dev, 0x33, 0x0e);
- /* Chrominance Control NTSC N */
- else if (norme & V4L2_STD_SECAM)
- spca506_WriteI2c(gspca_dev, 0x53, 0x0e);
- /* Chrominance Control SECAM */
- else
- spca506_WriteI2c(gspca_dev, 0x03, 0x0e);
- /* Chrominance Control PAL BGHIV */
-
- sd->norme = norme;
- sd->channel = channel;
- PDEBUG(D_STREAM, "Set Video Byte to 0x%2x", videomask);
- PDEBUG(D_STREAM, "Set Norme: %08x Channel %d", norme, channel);
-}
-
-static void spca506_GetNormeInput(struct gspca_dev *gspca_dev,
- __u16 *norme, __u16 *channel)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* Read the register is not so good value change so
- we use your own copy in spca50x struct */
- *norme = sd->norme;
- *channel = sd->channel;
- PDEBUG(D_STREAM, "Get Norme: %d Channel %d", *norme, *channel);
-}
-
-static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code,
- __u16 xmult, __u16 ymult)
-{
- struct usb_device *dev = gspca_dev->dev;
-
- PDEBUG(D_STREAM, "** SetSize **");
- reg_w(dev, 0x04, (0x18 | (code & 0x07)), 0x0000);
- /* Soft snap 0x40 Hard 0x41 */
- reg_w(dev, 0x04, 0x41, 0x0001);
- reg_w(dev, 0x04, 0x00, 0x0002);
- /* reserved */
- reg_w(dev, 0x04, 0x00, 0x0003);
-
- /* reserved */
- reg_w(dev, 0x04, 0x00, 0x0004);
- /* reserved */
- reg_w(dev, 0x04, 0x01, 0x0005);
- /* reserced */
- reg_w(dev, 0x04, xmult, 0x0006);
- /* reserved */
- reg_w(dev, 0x04, ymult, 0x0007);
- /* compression 1 */
- reg_w(dev, 0x04, 0x00, 0x0008);
- /* T=64 -> 2 */
- reg_w(dev, 0x04, 0x00, 0x0009);
- /* threshold2D */
- reg_w(dev, 0x04, 0x21, 0x000a);
- /* quantization */
- reg_w(dev, 0x04, 0x00, 0x000b);
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct cam *cam;
-
- cam = &gspca_dev->cam;
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct usb_device *dev = gspca_dev->dev;
-
- reg_w(dev, 0x03, 0x00, 0x0004);
- reg_w(dev, 0x03, 0xFF, 0x0003);
- reg_w(dev, 0x03, 0x00, 0x0000);
- reg_w(dev, 0x03, 0x1c, 0x0001);
- reg_w(dev, 0x03, 0x18, 0x0001);
- /* Init on PAL and composite input0 */
- spca506_SetNormeInput(gspca_dev, 0, 0);
- reg_w(dev, 0x03, 0x1c, 0x0001);
- reg_w(dev, 0x03, 0x18, 0x0001);
- reg_w(dev, 0x05, 0x00, 0x0000);
- reg_w(dev, 0x05, 0xef, 0x0001);
- reg_w(dev, 0x05, 0x00, 0x00c1);
- reg_w(dev, 0x05, 0x00, 0x00c2);
- reg_w(dev, 0x06, 0x18, 0x0002);
- reg_w(dev, 0x06, 0xf5, 0x0011);
- reg_w(dev, 0x06, 0x02, 0x0012);
- reg_w(dev, 0x06, 0xfb, 0x0013);
- reg_w(dev, 0x06, 0x00, 0x0014);
- reg_w(dev, 0x06, 0xa4, 0x0051);
- reg_w(dev, 0x06, 0x40, 0x0052);
- reg_w(dev, 0x06, 0x71, 0x0053);
- reg_w(dev, 0x06, 0x40, 0x0054);
- /************************************************/
- reg_w(dev, 0x03, 0x00, 0x0004);
- reg_w(dev, 0x03, 0x00, 0x0003);
- reg_w(dev, 0x03, 0x00, 0x0004);
- reg_w(dev, 0x03, 0xFF, 0x0003);
- reg_w(dev, 0x02, 0x00, 0x0000);
- reg_w(dev, 0x03, 0x60, 0x0000);
- reg_w(dev, 0x03, 0x18, 0x0001);
- /* for a better reading mx :) */
- /*sdca506_WriteI2c(value,register) */
- spca506_Initi2c(gspca_dev);
- spca506_WriteI2c(gspca_dev, 0x08, 0x01);
- spca506_WriteI2c(gspca_dev, 0xc0, 0x02);
- /* input composite video */
- spca506_WriteI2c(gspca_dev, 0x33, 0x03);
- spca506_WriteI2c(gspca_dev, 0x00, 0x04);
- spca506_WriteI2c(gspca_dev, 0x00, 0x05);
- spca506_WriteI2c(gspca_dev, 0x0d, 0x06);
- spca506_WriteI2c(gspca_dev, 0xf0, 0x07);
- spca506_WriteI2c(gspca_dev, 0x98, 0x08);
- spca506_WriteI2c(gspca_dev, 0x03, 0x09);
- spca506_WriteI2c(gspca_dev, 0x80, 0x0a);
- spca506_WriteI2c(gspca_dev, 0x47, 0x0b);
- spca506_WriteI2c(gspca_dev, 0x48, 0x0c);
- spca506_WriteI2c(gspca_dev, 0x00, 0x0d);
- spca506_WriteI2c(gspca_dev, 0x03, 0x0e); /* Chroma Pal adjust */
- spca506_WriteI2c(gspca_dev, 0x2a, 0x0f);
- spca506_WriteI2c(gspca_dev, 0x00, 0x10);
- spca506_WriteI2c(gspca_dev, 0x0c, 0x11);
- spca506_WriteI2c(gspca_dev, 0xb8, 0x12);
- spca506_WriteI2c(gspca_dev, 0x01, 0x13);
- spca506_WriteI2c(gspca_dev, 0x00, 0x14);
- spca506_WriteI2c(gspca_dev, 0x00, 0x15);
- spca506_WriteI2c(gspca_dev, 0x00, 0x16);
- spca506_WriteI2c(gspca_dev, 0x00, 0x17);
- spca506_WriteI2c(gspca_dev, 0x00, 0x18);
- spca506_WriteI2c(gspca_dev, 0x00, 0x19);
- spca506_WriteI2c(gspca_dev, 0x00, 0x1a);
- spca506_WriteI2c(gspca_dev, 0x00, 0x1b);
- spca506_WriteI2c(gspca_dev, 0x00, 0x1c);
- spca506_WriteI2c(gspca_dev, 0x00, 0x1d);
- spca506_WriteI2c(gspca_dev, 0x00, 0x1e);
- spca506_WriteI2c(gspca_dev, 0xa1, 0x1f);
- spca506_WriteI2c(gspca_dev, 0x02, 0x40);
- spca506_WriteI2c(gspca_dev, 0xff, 0x41);
- spca506_WriteI2c(gspca_dev, 0xff, 0x42);
- spca506_WriteI2c(gspca_dev, 0xff, 0x43);
- spca506_WriteI2c(gspca_dev, 0xff, 0x44);
- spca506_WriteI2c(gspca_dev, 0xff, 0x45);
- spca506_WriteI2c(gspca_dev, 0xff, 0x46);
- spca506_WriteI2c(gspca_dev, 0xff, 0x47);
- spca506_WriteI2c(gspca_dev, 0xff, 0x48);
- spca506_WriteI2c(gspca_dev, 0xff, 0x49);
- spca506_WriteI2c(gspca_dev, 0xff, 0x4a);
- spca506_WriteI2c(gspca_dev, 0xff, 0x4b);
- spca506_WriteI2c(gspca_dev, 0xff, 0x4c);
- spca506_WriteI2c(gspca_dev, 0xff, 0x4d);
- spca506_WriteI2c(gspca_dev, 0xff, 0x4e);
- spca506_WriteI2c(gspca_dev, 0xff, 0x4f);
- spca506_WriteI2c(gspca_dev, 0xff, 0x50);
- spca506_WriteI2c(gspca_dev, 0xff, 0x51);
- spca506_WriteI2c(gspca_dev, 0xff, 0x52);
- spca506_WriteI2c(gspca_dev, 0xff, 0x53);
- spca506_WriteI2c(gspca_dev, 0xff, 0x54);
- spca506_WriteI2c(gspca_dev, 0xff, 0x55);
- spca506_WriteI2c(gspca_dev, 0xff, 0x56);
- spca506_WriteI2c(gspca_dev, 0xff, 0x57);
- spca506_WriteI2c(gspca_dev, 0x00, 0x58);
- spca506_WriteI2c(gspca_dev, 0x54, 0x59);
- spca506_WriteI2c(gspca_dev, 0x07, 0x5a);
- spca506_WriteI2c(gspca_dev, 0x83, 0x5b);
- spca506_WriteI2c(gspca_dev, 0x00, 0x5c);
- spca506_WriteI2c(gspca_dev, 0x00, 0x5d);
- spca506_WriteI2c(gspca_dev, 0x00, 0x5e);
- spca506_WriteI2c(gspca_dev, 0x00, 0x5f);
- spca506_WriteI2c(gspca_dev, 0x00, 0x60);
- spca506_WriteI2c(gspca_dev, 0x05, 0x61);
- spca506_WriteI2c(gspca_dev, 0x9f, 0x62);
- PDEBUG(D_STREAM, "** Close Init *");
- return 0;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct usb_device *dev = gspca_dev->dev;
- __u16 norme;
- __u16 channel;
-
- /**************************************/
- reg_w(dev, 0x03, 0x00, 0x0004);
- reg_w(dev, 0x03, 0x00, 0x0003);
- reg_w(dev, 0x03, 0x00, 0x0004);
- reg_w(dev, 0x03, 0xFF, 0x0003);
- reg_w(dev, 0x02, 0x00, 0x0000);
- reg_w(dev, 0x03, 0x60, 0x0000);
- reg_w(dev, 0x03, 0x18, 0x0001);
-
- /*sdca506_WriteI2c(value,register) */
- spca506_Initi2c(gspca_dev);
- spca506_WriteI2c(gspca_dev, 0x08, 0x01); /* Increment Delay */
-/* spca506_WriteI2c(gspca_dev, 0xc0, 0x02); * Analog Input Control 1 */
- spca506_WriteI2c(gspca_dev, 0x33, 0x03);
- /* Analog Input Control 2 */
- spca506_WriteI2c(gspca_dev, 0x00, 0x04);
- /* Analog Input Control 3 */
- spca506_WriteI2c(gspca_dev, 0x00, 0x05);
- /* Analog Input Control 4 */
- spca506_WriteI2c(gspca_dev, 0x0d, 0x06);
- /* Horizontal Sync Start 0xe9-0x0d */
- spca506_WriteI2c(gspca_dev, 0xf0, 0x07);
- /* Horizontal Sync Stop 0x0d-0xf0 */
-
- spca506_WriteI2c(gspca_dev, 0x98, 0x08); /* Sync Control */
-/* Defaults value */
- spca506_WriteI2c(gspca_dev, 0x03, 0x09); /* Luminance Control */
- spca506_WriteI2c(gspca_dev, 0x80, 0x0a);
- /* Luminance Brightness */
- spca506_WriteI2c(gspca_dev, 0x47, 0x0b); /* Luminance Contrast */
- spca506_WriteI2c(gspca_dev, 0x48, 0x0c);
- /* Chrominance Saturation */
- spca506_WriteI2c(gspca_dev, 0x00, 0x0d);
- /* Chrominance Hue Control */
- spca506_WriteI2c(gspca_dev, 0x2a, 0x0f);
- /* Chrominance Gain Control */
- /**************************************/
- spca506_WriteI2c(gspca_dev, 0x00, 0x10);
- /* Format/Delay Control */
- spca506_WriteI2c(gspca_dev, 0x0c, 0x11); /* Output Control 1 */
- spca506_WriteI2c(gspca_dev, 0xb8, 0x12); /* Output Control 2 */
- spca506_WriteI2c(gspca_dev, 0x01, 0x13); /* Output Control 3 */
- spca506_WriteI2c(gspca_dev, 0x00, 0x14); /* reserved */
- spca506_WriteI2c(gspca_dev, 0x00, 0x15); /* VGATE START */
- spca506_WriteI2c(gspca_dev, 0x00, 0x16); /* VGATE STOP */
- spca506_WriteI2c(gspca_dev, 0x00, 0x17); /* VGATE Control (MSB) */
- spca506_WriteI2c(gspca_dev, 0x00, 0x18);
- spca506_WriteI2c(gspca_dev, 0x00, 0x19);
- spca506_WriteI2c(gspca_dev, 0x00, 0x1a);
- spca506_WriteI2c(gspca_dev, 0x00, 0x1b);
- spca506_WriteI2c(gspca_dev, 0x00, 0x1c);
- spca506_WriteI2c(gspca_dev, 0x00, 0x1d);
- spca506_WriteI2c(gspca_dev, 0x00, 0x1e);
- spca506_WriteI2c(gspca_dev, 0xa1, 0x1f);
- spca506_WriteI2c(gspca_dev, 0x02, 0x40);
- spca506_WriteI2c(gspca_dev, 0xff, 0x41);
- spca506_WriteI2c(gspca_dev, 0xff, 0x42);
- spca506_WriteI2c(gspca_dev, 0xff, 0x43);
- spca506_WriteI2c(gspca_dev, 0xff, 0x44);
- spca506_WriteI2c(gspca_dev, 0xff, 0x45);
- spca506_WriteI2c(gspca_dev, 0xff, 0x46);
- spca506_WriteI2c(gspca_dev, 0xff, 0x47);
- spca506_WriteI2c(gspca_dev, 0xff, 0x48);
- spca506_WriteI2c(gspca_dev, 0xff, 0x49);
- spca506_WriteI2c(gspca_dev, 0xff, 0x4a);
- spca506_WriteI2c(gspca_dev, 0xff, 0x4b);
- spca506_WriteI2c(gspca_dev, 0xff, 0x4c);
- spca506_WriteI2c(gspca_dev, 0xff, 0x4d);
- spca506_WriteI2c(gspca_dev, 0xff, 0x4e);
- spca506_WriteI2c(gspca_dev, 0xff, 0x4f);
- spca506_WriteI2c(gspca_dev, 0xff, 0x50);
- spca506_WriteI2c(gspca_dev, 0xff, 0x51);
- spca506_WriteI2c(gspca_dev, 0xff, 0x52);
- spca506_WriteI2c(gspca_dev, 0xff, 0x53);
- spca506_WriteI2c(gspca_dev, 0xff, 0x54);
- spca506_WriteI2c(gspca_dev, 0xff, 0x55);
- spca506_WriteI2c(gspca_dev, 0xff, 0x56);
- spca506_WriteI2c(gspca_dev, 0xff, 0x57);
- spca506_WriteI2c(gspca_dev, 0x00, 0x58);
- spca506_WriteI2c(gspca_dev, 0x54, 0x59);
- spca506_WriteI2c(gspca_dev, 0x07, 0x5a);
- spca506_WriteI2c(gspca_dev, 0x83, 0x5b);
- spca506_WriteI2c(gspca_dev, 0x00, 0x5c);
- spca506_WriteI2c(gspca_dev, 0x00, 0x5d);
- spca506_WriteI2c(gspca_dev, 0x00, 0x5e);
- spca506_WriteI2c(gspca_dev, 0x00, 0x5f);
- spca506_WriteI2c(gspca_dev, 0x00, 0x60);
- spca506_WriteI2c(gspca_dev, 0x05, 0x61);
- spca506_WriteI2c(gspca_dev, 0x9f, 0x62);
- /**************************************/
- reg_w(dev, 0x05, 0x00, 0x0003);
- reg_w(dev, 0x05, 0x00, 0x0004);
- reg_w(dev, 0x03, 0x10, 0x0001);
- reg_w(dev, 0x03, 0x78, 0x0000);
- switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
- case 0:
- spca506_Setsize(gspca_dev, 0, 0x10, 0x10);
- break;
- case 1:
- spca506_Setsize(gspca_dev, 1, 0x1a, 0x1a);
- break;
- case 2:
- spca506_Setsize(gspca_dev, 2, 0x1c, 0x1c);
- break;
- case 4:
- spca506_Setsize(gspca_dev, 4, 0x34, 0x34);
- break;
- default:
-/* case 5: */
- spca506_Setsize(gspca_dev, 5, 0x40, 0x40);
- break;
- }
-
- /* compress setting and size */
- /* set i2c luma */
- reg_w(dev, 0x02, 0x01, 0x0000);
- reg_w(dev, 0x03, 0x12, 0x0000);
- reg_r(gspca_dev, 0x04, 0x0001, 2);
- PDEBUG(D_STREAM, "webcam started");
- spca506_GetNormeInput(gspca_dev, &norme, &channel);
- spca506_SetNormeInput(gspca_dev, norme, channel);
- return 0;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct usb_device *dev = gspca_dev->dev;
-
- reg_w(dev, 0x02, 0x00, 0x0000);
- reg_w(dev, 0x03, 0x00, 0x0004);
- reg_w(dev, 0x03, 0x00, 0x0003);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- switch (data[0]) {
- case 0: /* start of frame */
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
- data += SPCA50X_OFFSET_DATA;
- len -= SPCA50X_OFFSET_DATA;
- gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
- break;
- case 0xff: /* drop */
-/* gspca_dev->last_packet_type = DISCARD_PACKET; */
- break;
- default:
- data += 1;
- len -= 1;
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
- break;
- }
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
-{
- spca506_Initi2c(gspca_dev);
- spca506_WriteI2c(gspca_dev, val, SAA7113_bright);
- spca506_WriteI2c(gspca_dev, 0x01, 0x09);
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
-{
- spca506_Initi2c(gspca_dev);
- spca506_WriteI2c(gspca_dev, val, SAA7113_contrast);
- spca506_WriteI2c(gspca_dev, 0x01, 0x09);
-}
-
-static void setcolors(struct gspca_dev *gspca_dev, s32 val)
-{
- spca506_Initi2c(gspca_dev);
- spca506_WriteI2c(gspca_dev, val, SAA7113_saturation);
- spca506_WriteI2c(gspca_dev, 0x01, 0x09);
-}
-
-static void sethue(struct gspca_dev *gspca_dev, s32 val)
-{
- spca506_Initi2c(gspca_dev);
- spca506_WriteI2c(gspca_dev, val, SAA7113_hue);
- spca506_WriteI2c(gspca_dev, 0x01, 0x09);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- setcolors(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_HUE:
- sethue(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 4);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 0x47);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, 0x40);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_HUE, 0, 255, 1, 0);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x06e1, 0xa190)},
-/*fixme: may be IntelPCCameraPro BRIDGE_SPCA505
- {USB_DEVICE(0x0733, 0x0430)}, */
- {USB_DEVICE(0x0734, 0x043b)},
- {USB_DEVICE(0x99fa, 0x8988)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int __devinit sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
deleted file mode 100644
index 1286b4170b8..00000000000
--- a/drivers/media/video/gspca/spca508.c
+++ /dev/null
@@ -1,1540 +0,0 @@
-/*
- * SPCA508 chip based cameras subdriver
- *
- * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "spca508"
-
-#include "gspca.h"
-
-MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
-MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- u8 subtype;
-#define CreativeVista 0
-#define HamaUSBSightcam 1
-#define HamaUSBSightcam2 2
-#define IntelEasyPCCamera 3
-#define MicroInnovationIC200 4
-#define ViewQuestVQ110 5
-};
-
-static const struct v4l2_pix_format sif_mode[] = {
- {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 3},
- {176, 144, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
- {320, 240, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {352, 288, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 3 / 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-/* Frame packet header offsets for the spca508 */
-#define SPCA508_OFFSET_DATA 37
-
-/*
- * Initialization data: this is the first set-up data written to the
- * device (before the open data).
- */
-static const u16 spca508_init_data[][2] = {
- {0x0000, 0x870b},
-
- {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */
- {0x0003, 0x8111}, /* Reset compression & memory */
- {0x0000, 0x8110}, /* Disable all outputs */
- /* READ {0x0000, 0x8114} -> 0000: 00 */
- {0x0000, 0x8114}, /* SW GPIO data */
- {0x0008, 0x8110}, /* Enable charge pump output */
- {0x0002, 0x8116}, /* 200 kHz pump clock */
- /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */
- {0x0003, 0x8111}, /* Reset compression & memory */
- {0x0000, 0x8111}, /* Normal mode (not reset) */
- {0x0098, 0x8110},
- /* Enable charge pump output, sync.serial,external 2x clock */
- {0x000d, 0x8114}, /* SW GPIO data */
- {0x0002, 0x8116}, /* 200 kHz pump clock */
- {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */
-/* --------------------------------------- */
- {0x000f, 0x8402}, /* memory bank */
- {0x0000, 0x8403}, /* ... address */
-/* --------------------------------------- */
-/* 0x88__ is Synchronous Serial Interface. */
-/* TBD: This table could be expressed more compactly */
-/* using spca508_write_i2c_vector(). */
-/* TBD: Should see if the values in spca50x_i2c_data */
-/* would work with the VQ110 instead of the values */
-/* below. */
- {0x00c0, 0x8804}, /* SSI slave addr */
- {0x0008, 0x8802}, /* 375 Khz SSI clock */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802}, /* 375 Khz SSI clock */
- {0x0012, 0x8801}, /* SSI reg addr */
- {0x0080, 0x8800}, /* SSI data to write */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802}, /* 375 Khz SSI clock */
- {0x0012, 0x8801}, /* SSI reg addr */
- {0x0000, 0x8800}, /* SSI data to write */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802}, /* 375 Khz SSI clock */
- {0x0011, 0x8801}, /* SSI reg addr */
- {0x0040, 0x8800}, /* SSI data to write */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0013, 0x8801},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0014, 0x8801},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0015, 0x8801},
- {0x0001, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0016, 0x8801},
- {0x0003, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0017, 0x8801},
- {0x0036, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0018, 0x8801},
- {0x00ec, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x001a, 0x8801},
- {0x0094, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x001b, 0x8801},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0027, 0x8801},
- {0x00a2, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0028, 0x8801},
- {0x0040, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x002a, 0x8801},
- {0x0084, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x002b, 0x8801},
- {0x00a8, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x002c, 0x8801},
- {0x00fe, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x002d, 0x8801},
- {0x0003, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0038, 0x8801},
- {0x0083, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0033, 0x8801},
- {0x0081, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0034, 0x8801},
- {0x004a, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0039, 0x8801},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0010, 0x8801},
- {0x00a8, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0006, 0x8801},
- {0x0058, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0000, 0x8801},
- {0x0004, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0040, 0x8801},
- {0x0080, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0041, 0x8801},
- {0x000c, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0042, 0x8801},
- {0x000c, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0043, 0x8801},
- {0x0028, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0044, 0x8801},
- {0x0080, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0045, 0x8801},
- {0x0020, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0046, 0x8801},
- {0x0020, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0047, 0x8801},
- {0x0080, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0048, 0x8801},
- {0x004c, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x0049, 0x8801},
- {0x0084, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x004a, 0x8801},
- {0x0084, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x0008, 0x8802},
- {0x004b, 0x8801},
- {0x0084, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* --------------------------------------- */
- {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
- {0x0000, 0x8701}, /* CKx1 clock delay adj */
- {0x0000, 0x8701}, /* CKx1 clock delay adj */
- {0x0001, 0x870c}, /* CKOx2 output */
- /* --------------------------------------- */
- {0x0080, 0x8600}, /* Line memory read counter (L) */
- {0x0001, 0x8606}, /* reserved */
- {0x0064, 0x8607}, /* Line memory read counter (H) 0x6480=25,728 */
- {0x002a, 0x8601}, /* CDSP sharp interpolation mode,
- * line sel for color sep, edge enhance enab */
- {0x0000, 0x8602}, /* optical black level for user settng = 0 */
- {0x0080, 0x8600}, /* Line memory read counter (L) */
- {0x000a, 0x8603}, /* optical black level calc mode:
- * auto; optical black offset = 10 */
- {0x00df, 0x865b}, /* Horiz offset for valid pixels (L)=0xdf */
- {0x0012, 0x865c}, /* Vert offset for valid lines (L)=0x12 */
-
-/* The following two lines seem to be the "wrong" resolution. */
-/* But perhaps these indicate the actual size of the sensor */
-/* rather than the size of the current video mode. */
- {0x0058, 0x865d}, /* Horiz valid pixels (*4) (L) = 352 */
- {0x0048, 0x865e}, /* Vert valid lines (*4) (L) = 288 */
-
- {0x0015, 0x8608}, /* A11 Coef ... */
- {0x0030, 0x8609},
- {0x00fb, 0x860a},
- {0x003e, 0x860b},
- {0x00ce, 0x860c},
- {0x00f4, 0x860d},
- {0x00eb, 0x860e},
- {0x00dc, 0x860f},
- {0x0039, 0x8610},
- {0x0001, 0x8611}, /* R offset for white balance ... */
- {0x0000, 0x8612},
- {0x0001, 0x8613},
- {0x0000, 0x8614},
- {0x005b, 0x8651}, /* R gain for white balance ... */
- {0x0040, 0x8652},
- {0x0060, 0x8653},
- {0x0040, 0x8654},
- {0x0000, 0x8655},
- {0x0001, 0x863f}, /* Fixed gamma correction enable, USB control,
- * lum filter disable, lum noise clip disable */
- {0x00a1, 0x8656}, /* Window1 size 256x256, Windows2 size 64x64,
- * gamma look-up disable,
- * new edge enhancement enable */
- {0x0018, 0x8657}, /* Edge gain high thresh */
- {0x0020, 0x8658}, /* Edge gain low thresh */
- {0x000a, 0x8659}, /* Edge bandwidth high threshold */
- {0x0005, 0x865a}, /* Edge bandwidth low threshold */
- /* -------------------------------- */
- {0x0030, 0x8112}, /* Video drop enable, ISO streaming enable */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0xa908, 0x8802},
- {0x0034, 0x8801}, /* SSI reg addr */
- {0x00ca, 0x8800},
- /* SSI data to write */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0x1f08, 0x8802},
- {0x0006, 0x8801},
- {0x0080, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
-/* ----- Read back coefs we wrote earlier. */
- /* READ { 0x0000, 0x8608 } -> 0000: 15 */
- /* READ { 0x0000, 0x8609 } -> 0000: 30 */
- /* READ { 0x0000, 0x860a } -> 0000: fb */
- /* READ { 0x0000, 0x860b } -> 0000: 3e */
- /* READ { 0x0000, 0x860c } -> 0000: ce */
- /* READ { 0x0000, 0x860d } -> 0000: f4 */
- /* READ { 0x0000, 0x860e } -> 0000: eb */
- /* READ { 0x0000, 0x860f } -> 0000: dc */
- /* READ { 0x0000, 0x8610 } -> 0000: 39 */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 08 */
- {0xb008, 0x8802},
- {0x0006, 0x8801},
- {0x007d, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
-
- /* This chunk is seemingly redundant with */
- /* earlier commands (A11 Coef...), but if I disable it, */
- /* the image appears too dark. Maybe there was some kind of */
- /* reset since the earlier commands, so this is necessary again. */
- {0x0015, 0x8608},
- {0x0030, 0x8609},
- {0xfffb, 0x860a},
- {0x003e, 0x860b},
- {0xffce, 0x860c},
- {0xfff4, 0x860d},
- {0xffeb, 0x860e},
- {0xffdc, 0x860f},
- {0x0039, 0x8610},
- {0x0018, 0x8657},
-
- {0x0000, 0x8508}, /* Disable compression. */
- /* Previous line was:
- {0x0021, 0x8508}, * Enable compression. */
- {0x0032, 0x850b}, /* compression stuff */
- {0x0003, 0x8509}, /* compression stuff */
- {0x0011, 0x850a}, /* compression stuff */
- {0x0021, 0x850d}, /* compression stuff */
- {0x0010, 0x850c}, /* compression stuff */
- {0x0003, 0x8500}, /* *** Video mode: 160x120 */
- {0x0001, 0x8501}, /* Hardware-dominated snap control */
- {0x0061, 0x8656}, /* Window1 size 128x128, Windows2 size 128x128,
- * gamma look-up disable,
- * new edge enhancement enable */
- {0x0018, 0x8617}, /* Window1 start X (*2) */
- {0x0008, 0x8618}, /* Window1 start Y (*2) */
- {0x0061, 0x8656}, /* Window1 size 128x128, Windows2 size 128x128,
- * gamma look-up disable,
- * new edge enhancement enable */
- {0x0058, 0x8619}, /* Window2 start X (*2) */
- {0x0008, 0x861a}, /* Window2 start Y (*2) */
- {0x00ff, 0x8615}, /* High lum thresh for white balance */
- {0x0000, 0x8616}, /* Low lum thresh for white balance */
- {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
- {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
- /* READ { 0x0000, 0x8656 } -> 0000: 61 */
- {0x0028, 0x8802}, /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 28 */
- {0x1f28, 0x8802}, /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
- {0x0010, 0x8801}, /* SSI reg addr */
- {0x003e, 0x8800}, /* SSI data to write */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- {0x0028, 0x8802},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 28 */
- {0x1f28, 0x8802},
- {0x0000, 0x8801},
- {0x001f, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- {0x0001, 0x8602}, /* optical black level for user settning = 1 */
-
- /* Original: */
- {0x0023, 0x8700}, /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */
- {0x000f, 0x8602}, /* optical black level for user settning = 15 */
-
- {0x0028, 0x8802},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 28 */
- {0x1f28, 0x8802},
- {0x0010, 0x8801},
- {0x007b, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- {0x002f, 0x8651}, /* R gain for white balance ... */
- {0x0080, 0x8653},
- /* READ { 0x0000, 0x8655 } -> 0000: 00 */
- {0x0000, 0x8655},
-
- {0x0030, 0x8112}, /* Video drop enable, ISO streaming enable */
- {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */
- /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */
- {}
-};
-
-/*
- * Initialization data for Intel EasyPC Camera CS110
- */
-static const u16 spca508cs110_init_data[][2] = {
- {0x0000, 0x870b}, /* Reset CTL3 */
- {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */
- {0x0000, 0x8111}, /* Normal operation on reset */
- {0x0090, 0x8110},
- /* External Clock 2x & Synchronous Serial Interface Output */
- {0x0020, 0x8112}, /* Video Drop packet enable */
- {0x0000, 0x8114}, /* Software GPIO output data */
- {0x0001, 0x8114},
- {0x0001, 0x8114},
- {0x0001, 0x8114},
- {0x0003, 0x8114},
-
- /* Initial sequence Synchronous Serial Interface */
- {0x000f, 0x8402}, /* Memory bank Address */
- {0x0000, 0x8403}, /* Memory bank Address */
- {0x00ba, 0x8804}, /* SSI Slave address */
- {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */
- {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */
-
- {0x0001, 0x8801},
- {0x000a, 0x8805}, /* a - NWG: Dunno what this is about */
- {0x0000, 0x8800},
- {0x0010, 0x8802},
-
- {0x0002, 0x8801},
- {0x0000, 0x8805},
- {0x0000, 0x8800},
- {0x0010, 0x8802},
-
- {0x0003, 0x8801},
- {0x0027, 0x8805},
- {0x0001, 0x8800},
- {0x0010, 0x8802},
-
- {0x0004, 0x8801},
- {0x0065, 0x8805},
- {0x0001, 0x8800},
- {0x0010, 0x8802},
-
- {0x0005, 0x8801},
- {0x0003, 0x8805},
- {0x0000, 0x8800},
- {0x0010, 0x8802},
-
- {0x0006, 0x8801},
- {0x001c, 0x8805},
- {0x0000, 0x8800},
- {0x0010, 0x8802},
-
- {0x0007, 0x8801},
- {0x002a, 0x8805},
- {0x0000, 0x8800},
- {0x0010, 0x8802},
-
- {0x0002, 0x8704}, /* External input CKIx1 */
- {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */
- {0x009a, 0x8600}, /* Line memory Read Counter (L) */
- {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */
- {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */
- {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */
-
- {0x0006, 0x8660}, /* Nibble data + input order */
-
- {0x000a, 0x8602}, /* Optical black level set to 0x0a */
- {0x0000, 0x8603}, /* Optical black level Offset */
-
-/* {0x0000, 0x8611}, * 0 R Offset for white Balance */
-/* {0x0000, 0x8612}, * 1 Gr Offset for white Balance */
-/* {0x0000, 0x8613}, * 1f B Offset for white Balance */
-/* {0x0000, 0x8614}, * f0 Gb Offset for white Balance */
-
- {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */
- {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */
- {0x0035, 0x8653}, /* 26 RED gain for white balance */
- {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */
- {0x0041, 0x863f},
- /* Fixed Gamma correction enabled (makes colours look better) */
-
- {0x0000, 0x8655},
- /* High bits for white balance*****brightness control*** */
- {}
-};
-
-static const u16 spca508_sightcam_init_data[][2] = {
-/* This line seems to setup the frame/canvas */
- {0x000f, 0x8402},
-
-/* These 6 lines are needed to startup the webcam */
- {0x0090, 0x8110},
- {0x0001, 0x8114},
- {0x0001, 0x8114},
- {0x0001, 0x8114},
- {0x0003, 0x8114},
- {0x0080, 0x8804},
-
-/* This part seems to make the pictures darker? (autobrightness?) */
- {0x0001, 0x8801},
- {0x0004, 0x8800},
- {0x0003, 0x8801},
- {0x00e0, 0x8800},
- {0x0004, 0x8801},
- {0x00b4, 0x8800},
- {0x0005, 0x8801},
- {0x0000, 0x8800},
-
- {0x0006, 0x8801},
- {0x00e0, 0x8800},
- {0x0007, 0x8801},
- {0x000c, 0x8800},
-
-/* This section is just needed, it probably
- * does something like the previous section,
- * but the cam won't start if it's not included.
- */
- {0x0014, 0x8801},
- {0x0008, 0x8800},
- {0x0015, 0x8801},
- {0x0067, 0x8800},
- {0x0016, 0x8801},
- {0x0000, 0x8800},
- {0x0017, 0x8801},
- {0x0020, 0x8800},
- {0x0018, 0x8801},
- {0x0044, 0x8800},
-
-/* Makes the picture darker - and the
- * cam won't start if not included
- */
- {0x001e, 0x8801},
- {0x00ea, 0x8800},
- {0x001f, 0x8801},
- {0x0001, 0x8800},
- {0x0003, 0x8801},
- {0x00e0, 0x8800},
-
-/* seems to place the colors ontop of each other #1 */
- {0x0006, 0x8704},
- {0x0001, 0x870c},
- {0x0016, 0x8600},
- {0x0002, 0x8606},
-
-/* if not included the pictures becomes _very_ dark */
- {0x0064, 0x8607},
- {0x003a, 0x8601},
- {0x0000, 0x8602},
-
-/* seems to place the colors ontop of each other #2 */
- {0x0016, 0x8600},
- {0x0018, 0x8617},
- {0x0008, 0x8618},
- {0x00a1, 0x8656},
-
-/* webcam won't start if not included */
- {0x0007, 0x865b},
- {0x0001, 0x865c},
- {0x0058, 0x865d},
- {0x0048, 0x865e},
-
-/* adjusts the colors */
- {0x0049, 0x8651},
- {0x0040, 0x8652},
- {0x004c, 0x8653},
- {0x0040, 0x8654},
- {}
-};
-
-static const u16 spca508_sightcam2_init_data[][2] = {
- {0x0020, 0x8112},
-
- {0x000f, 0x8402},
- {0x0000, 0x8403},
-
- {0x0008, 0x8201},
- {0x0008, 0x8200},
- {0x0001, 0x8200},
- {0x0009, 0x8201},
- {0x0008, 0x8200},
- {0x0001, 0x8200},
- {0x000a, 0x8201},
- {0x0008, 0x8200},
- {0x0001, 0x8200},
- {0x000b, 0x8201},
- {0x0008, 0x8200},
- {0x0001, 0x8200},
- {0x000c, 0x8201},
- {0x0008, 0x8200},
- {0x0001, 0x8200},
- {0x000d, 0x8201},
- {0x0008, 0x8200},
- {0x0001, 0x8200},
- {0x000e, 0x8201},
- {0x0008, 0x8200},
- {0x0001, 0x8200},
- {0x0007, 0x8201},
- {0x0008, 0x8200},
- {0x0001, 0x8200},
- {0x000f, 0x8201},
- {0x0008, 0x8200},
- {0x0001, 0x8200},
-
- {0x0018, 0x8660},
- {0x0010, 0x8201},
-
- {0x0008, 0x8200},
- {0x0001, 0x8200},
- {0x0011, 0x8201},
- {0x0008, 0x8200},
- {0x0001, 0x8200},
-
- {0x0000, 0x86b0},
- {0x0034, 0x86b1},
- {0x0000, 0x86b2},
- {0x0049, 0x86b3},
- {0x0000, 0x86b4},
- {0x0000, 0x86b4},
-
- {0x0012, 0x8201},
- {0x0008, 0x8200},
- {0x0001, 0x8200},
- {0x0013, 0x8201},
- {0x0008, 0x8200},
- {0x0001, 0x8200},
-
- {0x0001, 0x86b0},
- {0x00aa, 0x86b1},
- {0x0000, 0x86b2},
- {0x00e4, 0x86b3},
- {0x0000, 0x86b4},
- {0x0000, 0x86b4},
-
- {0x0018, 0x8660},
-
- {0x0090, 0x8110},
- {0x0001, 0x8114},
- {0x0001, 0x8114},
- {0x0001, 0x8114},
- {0x0003, 0x8114},
-
- {0x0080, 0x8804},
- {0x0003, 0x8801},
- {0x0012, 0x8800},
- {0x0004, 0x8801},
- {0x0005, 0x8800},
- {0x0005, 0x8801},
- {0x0000, 0x8800},
- {0x0006, 0x8801},
- {0x0000, 0x8800},
- {0x0007, 0x8801},
- {0x0000, 0x8800},
- {0x0008, 0x8801},
- {0x0005, 0x8800},
- {0x000a, 0x8700},
- {0x000e, 0x8801},
- {0x0004, 0x8800},
- {0x0005, 0x8801},
- {0x0047, 0x8800},
- {0x0006, 0x8801},
- {0x0000, 0x8800},
- {0x0007, 0x8801},
- {0x00c0, 0x8800},
- {0x0008, 0x8801},
- {0x0003, 0x8800},
- {0x0013, 0x8801},
- {0x0001, 0x8800},
- {0x0009, 0x8801},
- {0x0000, 0x8800},
- {0x000a, 0x8801},
- {0x0000, 0x8800},
- {0x000b, 0x8801},
- {0x0000, 0x8800},
- {0x000c, 0x8801},
- {0x0000, 0x8800},
- {0x000e, 0x8801},
- {0x0004, 0x8800},
- {0x000f, 0x8801},
- {0x0000, 0x8800},
- {0x0010, 0x8801},
- {0x0006, 0x8800},
- {0x0011, 0x8801},
- {0x0006, 0x8800},
- {0x0012, 0x8801},
- {0x0000, 0x8800},
- {0x0013, 0x8801},
- {0x0001, 0x8800},
-
- {0x000a, 0x8700},
- {0x0000, 0x8702},
- {0x0000, 0x8703},
- {0x00c2, 0x8704},
- {0x0001, 0x870c},
-
- {0x0044, 0x8600},
- {0x0002, 0x8606},
- {0x0064, 0x8607},
- {0x003a, 0x8601},
- {0x0008, 0x8602},
- {0x0044, 0x8600},
- {0x0018, 0x8617},
- {0x0008, 0x8618},
- {0x00a1, 0x8656},
- {0x0004, 0x865b},
- {0x0002, 0x865c},
- {0x0058, 0x865d},
- {0x0048, 0x865e},
- {0x0012, 0x8608},
- {0x002c, 0x8609},
- {0x0002, 0x860a},
- {0x002c, 0x860b},
- {0x00db, 0x860c},
- {0x00f9, 0x860d},
- {0x00f1, 0x860e},
- {0x00e3, 0x860f},
- {0x002c, 0x8610},
- {0x006c, 0x8651},
- {0x0041, 0x8652},
- {0x0059, 0x8653},
- {0x0040, 0x8654},
- {0x00fa, 0x8611},
- {0x00ff, 0x8612},
- {0x00f8, 0x8613},
- {0x0000, 0x8614},
- {0x0001, 0x863f},
- {0x0000, 0x8640},
- {0x0026, 0x8641},
- {0x0045, 0x8642},
- {0x0060, 0x8643},
- {0x0075, 0x8644},
- {0x0088, 0x8645},
- {0x009b, 0x8646},
- {0x00b0, 0x8647},
- {0x00c5, 0x8648},
- {0x00d2, 0x8649},
- {0x00dc, 0x864a},
- {0x00e5, 0x864b},
- {0x00eb, 0x864c},
- {0x00f0, 0x864d},
- {0x00f6, 0x864e},
- {0x00fa, 0x864f},
- {0x00ff, 0x8650},
- {0x0060, 0x8657},
- {0x0010, 0x8658},
- {0x0018, 0x8659},
- {0x0005, 0x865a},
- {0x0018, 0x8660},
- {0x0003, 0x8509},
- {0x0011, 0x850a},
- {0x0032, 0x850b},
- {0x0010, 0x850c},
- {0x0021, 0x850d},
- {0x0001, 0x8500},
- {0x0000, 0x8508},
- {0x0012, 0x8608},
- {0x002c, 0x8609},
- {0x0002, 0x860a},
- {0x0039, 0x860b},
- {0x00d0, 0x860c},
- {0x00f7, 0x860d},
- {0x00ed, 0x860e},
- {0x00db, 0x860f},
- {0x0039, 0x8610},
- {0x0012, 0x8657},
- {0x000c, 0x8619},
- {0x0004, 0x861a},
- {0x00a1, 0x8656},
- {0x00c8, 0x8615},
- {0x0032, 0x8616},
-
- {0x0030, 0x8112},
- {0x0020, 0x8112},
- {0x0020, 0x8112},
- {0x000f, 0x8402},
- {0x0000, 0x8403},
-
- {0x0090, 0x8110},
- {0x0001, 0x8114},
- {0x0001, 0x8114},
- {0x0001, 0x8114},
- {0x0003, 0x8114},
- {0x0080, 0x8804},
-
- {0x0003, 0x8801},
- {0x0012, 0x8800},
- {0x0004, 0x8801},
- {0x0005, 0x8800},
- {0x0005, 0x8801},
- {0x0047, 0x8800},
- {0x0006, 0x8801},
- {0x0000, 0x8800},
- {0x0007, 0x8801},
- {0x00c0, 0x8800},
- {0x0008, 0x8801},
- {0x0003, 0x8800},
- {0x000a, 0x8700},
- {0x000e, 0x8801},
- {0x0004, 0x8800},
- {0x0005, 0x8801},
- {0x0047, 0x8800},
- {0x0006, 0x8801},
- {0x0000, 0x8800},
- {0x0007, 0x8801},
- {0x00c0, 0x8800},
- {0x0008, 0x8801},
- {0x0003, 0x8800},
- {0x0013, 0x8801},
- {0x0001, 0x8800},
- {0x0009, 0x8801},
- {0x0000, 0x8800},
- {0x000a, 0x8801},
- {0x0000, 0x8800},
- {0x000b, 0x8801},
- {0x0000, 0x8800},
- {0x000c, 0x8801},
- {0x0000, 0x8800},
- {0x000e, 0x8801},
- {0x0004, 0x8800},
- {0x000f, 0x8801},
- {0x0000, 0x8800},
- {0x0010, 0x8801},
- {0x0006, 0x8800},
- {0x0011, 0x8801},
- {0x0006, 0x8800},
- {0x0012, 0x8801},
- {0x0000, 0x8800},
- {0x0013, 0x8801},
- {0x0001, 0x8800},
- {0x000a, 0x8700},
- {0x0000, 0x8702},
- {0x0000, 0x8703},
- {0x00c2, 0x8704},
- {0x0001, 0x870c},
- {0x0044, 0x8600},
- {0x0002, 0x8606},
- {0x0064, 0x8607},
- {0x003a, 0x8601},
- {0x0008, 0x8602},
- {0x0044, 0x8600},
- {0x0018, 0x8617},
- {0x0008, 0x8618},
- {0x00a1, 0x8656},
- {0x0004, 0x865b},
- {0x0002, 0x865c},
- {0x0058, 0x865d},
- {0x0048, 0x865e},
- {0x0012, 0x8608},
- {0x002c, 0x8609},
- {0x0002, 0x860a},
- {0x002c, 0x860b},
- {0x00db, 0x860c},
- {0x00f9, 0x860d},
- {0x00f1, 0x860e},
- {0x00e3, 0x860f},
- {0x002c, 0x8610},
- {0x006c, 0x8651},
- {0x0041, 0x8652},
- {0x0059, 0x8653},
- {0x0040, 0x8654},
- {0x00fa, 0x8611},
- {0x00ff, 0x8612},
- {0x00f8, 0x8613},
- {0x0000, 0x8614},
- {0x0001, 0x863f},
- {0x0000, 0x8640},
- {0x0026, 0x8641},
- {0x0045, 0x8642},
- {0x0060, 0x8643},
- {0x0075, 0x8644},
- {0x0088, 0x8645},
- {0x009b, 0x8646},
- {0x00b0, 0x8647},
- {0x00c5, 0x8648},
- {0x00d2, 0x8649},
- {0x00dc, 0x864a},
- {0x00e5, 0x864b},
- {0x00eb, 0x864c},
- {0x00f0, 0x864d},
- {0x00f6, 0x864e},
- {0x00fa, 0x864f},
- {0x00ff, 0x8650},
- {0x0060, 0x8657},
- {0x0010, 0x8658},
- {0x0018, 0x8659},
- {0x0005, 0x865a},
- {0x0018, 0x8660},
- {0x0003, 0x8509},
- {0x0011, 0x850a},
- {0x0032, 0x850b},
- {0x0010, 0x850c},
- {0x0021, 0x850d},
- {0x0001, 0x8500},
- {0x0000, 0x8508},
-
- {0x0012, 0x8608},
- {0x002c, 0x8609},
- {0x0002, 0x860a},
- {0x0039, 0x860b},
- {0x00d0, 0x860c},
- {0x00f7, 0x860d},
- {0x00ed, 0x860e},
- {0x00db, 0x860f},
- {0x0039, 0x8610},
- {0x0012, 0x8657},
- {0x0064, 0x8619},
-
-/* This line starts it all, it is not needed here */
-/* since it has been build into the driver */
-/* jfm: don't start now */
-/* {0x0030, 0x8112}, */
- {}
-};
-
-/*
- * Initialization data for Creative Webcam Vista
- */
-static const u16 spca508_vista_init_data[][2] = {
- {0x0008, 0x8200}, /* Clear register */
- {0x0000, 0x870b}, /* Reset CTL3 */
- {0x0020, 0x8112}, /* Video Drop packet enable */
- {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */
- {0x0000, 0x8110}, /* Disable everything */
- {0x0000, 0x8114}, /* Software GPIO output data */
- {0x0000, 0x8114},
-
- {0x0003, 0x8111},
- {0x0000, 0x8111},
- {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */
- {0x0020, 0x8112},
- {0x0000, 0x8114},
- {0x0001, 0x8114},
- {0x0001, 0x8114},
- {0x0001, 0x8114},
- {0x0003, 0x8114},
-
- {0x000f, 0x8402}, /* Memory bank Address */
- {0x0000, 0x8403}, /* Memory bank Address */
- {0x00ba, 0x8804}, /* SSI Slave address */
- {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */
- {0x0020, 0x8801}, /* Register address for SSI read/write */
- {0x0044, 0x8805}, /* DATA2 */
- {0x0004, 0x8800}, /* DATA1 -> write triggered */
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x0009, 0x8801},
- {0x0042, 0x8805},
- {0x0001, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x003c, 0x8801},
- {0x0001, 0x8805},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x0001, 0x8801},
- {0x000a, 0x8805},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x0002, 0x8801},
- {0x0000, 0x8805},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x0003, 0x8801},
- {0x0027, 0x8805},
- {0x0001, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x0004, 0x8801},
- {0x0065, 0x8805},
- {0x0001, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x0005, 0x8801},
- {0x0003, 0x8805},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x0006, 0x8801},
- {0x001c, 0x8805},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x0007, 0x8801},
- {0x002a, 0x8805},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x000e, 0x8801},
- {0x0000, 0x8805},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x0028, 0x8801},
- {0x002e, 0x8805},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x0039, 0x8801},
- {0x0013, 0x8805},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x003b, 0x8801},
- {0x000c, 0x8805},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x0035, 0x8801},
- {0x0028, 0x8805},
- {0x0000, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
- /* READ { 0x0001, 0x8802 } -> 0000: 10 */
- {0x0010, 0x8802},
- {0x0009, 0x8801},
- {0x0042, 0x8805},
- {0x0001, 0x8800},
- /* READ { 0x0001, 0x8803 } -> 0000: 00 */
-
- {0x0050, 0x8703},
- {0x0002, 0x8704}, /* External input CKIx1 */
- {0x0001, 0x870c}, /* Select CKOx2 output */
- {0x009a, 0x8600}, /* Line memory Read Counter (L) */
- {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */
- {0x0023, 0x8601},
- {0x0010, 0x8602},
- {0x000a, 0x8603},
- {0x009a, 0x8600},
- {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */
- {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */
- {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */
- {0x0048, 0x865e}, /* Vertical valid lines window (L) */
- {0x0000, 0x865f},
-
- {0x0006, 0x8660},
- /* Enable nibble data input, select nibble input order */
-
- {0x0013, 0x8608}, /* A11 Coeficients for color correction */
- {0x0028, 0x8609},
- /* Note: these values are confirmed at the end of array */
- {0x0005, 0x860a}, /* ... */
- {0x0025, 0x860b},
- {0x00e1, 0x860c},
- {0x00fa, 0x860d},
- {0x00f4, 0x860e},
- {0x00e8, 0x860f},
- {0x0025, 0x8610}, /* A33 Coef. */
- {0x00fc, 0x8611}, /* White balance offset: R */
- {0x0001, 0x8612}, /* White balance offset: Gr */
- {0x00fe, 0x8613}, /* White balance offset: B */
- {0x0000, 0x8614}, /* White balance offset: Gb */
-
- {0x0064, 0x8651}, /* R gain for white balance (L) */
- {0x0040, 0x8652}, /* Gr gain for white balance (L) */
- {0x0066, 0x8653}, /* B gain for white balance (L) */
- {0x0040, 0x8654}, /* Gb gain for white balance (L) */
- {0x0001, 0x863f}, /* Enable fixed gamma correction */
-
- {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128,
- * UV division: UV no change,
- * Enable New edge enhancement */
- {0x0018, 0x8657}, /* Edge gain high threshold */
- {0x0020, 0x8658}, /* Edge gain low threshold */
- {0x000a, 0x8659}, /* Edge bandwidth high threshold */
- {0x0005, 0x865a}, /* Edge bandwidth low threshold */
- {0x0064, 0x8607}, /* UV filter enable */
-
- {0x0016, 0x8660},
- {0x0000, 0x86b0}, /* Bad pixels compensation address */
- {0x00dc, 0x86b1}, /* X coord for bad pixels compensation (L) */
- {0x0000, 0x86b2},
- {0x0009, 0x86b3}, /* Y coord for bad pixels compensation (L) */
- {0x0000, 0x86b4},
-
- {0x0001, 0x86b0},
- {0x00f5, 0x86b1},
- {0x0000, 0x86b2},
- {0x00c6, 0x86b3},
- {0x0000, 0x86b4},
-
- {0x0002, 0x86b0},
- {0x001c, 0x86b1},
- {0x0001, 0x86b2},
- {0x00d7, 0x86b3},
- {0x0000, 0x86b4},
-
- {0x0003, 0x86b0},
- {0x001c, 0x86b1},
- {0x0001, 0x86b2},
- {0x00d8, 0x86b3},
- {0x0000, 0x86b4},
-
- {0x0004, 0x86b0},
- {0x001d, 0x86b1},
- {0x0001, 0x86b2},
- {0x00d8, 0x86b3},
- {0x0000, 0x86b4},
- {0x001e, 0x8660},
-
- /* READ { 0x0000, 0x8608 } -> 0000: 13 */
- /* READ { 0x0000, 0x8609 } -> 0000: 28 */
- /* READ { 0x0000, 0x8610 } -> 0000: 05 */
- /* READ { 0x0000, 0x8611 } -> 0000: 25 */
- /* READ { 0x0000, 0x8612 } -> 0000: e1 */
- /* READ { 0x0000, 0x8613 } -> 0000: fa */
- /* READ { 0x0000, 0x8614 } -> 0000: f4 */
- /* READ { 0x0000, 0x8615 } -> 0000: e8 */
- /* READ { 0x0000, 0x8616 } -> 0000: 25 */
- {}
-};
-
-static int reg_write(struct usb_device *dev,
- u16 index, u16 value)
-{
- int ret;
-
- ret = usb_control_msg(dev,
- usb_sndctrlpipe(dev, 0),
- 0, /* request */
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, NULL, 0, 500);
- PDEBUG(D_USBO, "reg write i:0x%04x = 0x%02x",
- index, value);
- if (ret < 0)
- pr_err("reg write: error %d\n", ret);
- return ret;
-}
-
-/* read 1 byte */
-/* returns: negative is error, pos or zero is data */
-static int reg_read(struct gspca_dev *gspca_dev,
- u16 index) /* wIndex */
-{
- int ret;
-
- ret = usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- 0, /* register */
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, /* value */
- index,
- gspca_dev->usb_buf, 1,
- 500); /* timeout */
- PDEBUG(D_USBI, "reg read i:%04x --> %02x",
- index, gspca_dev->usb_buf[0]);
- if (ret < 0) {
- pr_err("reg_read err %d\n", ret);
- return ret;
- }
- return gspca_dev->usb_buf[0];
-}
-
-/* send 1 or 2 bytes to the sensor via the Synchronous Serial Interface */
-static int ssi_w(struct gspca_dev *gspca_dev,
- u16 reg, u16 val)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret, retry;
-
- ret = reg_write(dev, 0x8802, reg >> 8);
- if (ret < 0)
- goto out;
- ret = reg_write(dev, 0x8801, reg & 0x00ff);
- if (ret < 0)
- goto out;
- if ((reg & 0xff00) == 0x1000) { /* if 2 bytes */
- ret = reg_write(dev, 0x8805, val & 0x00ff);
- if (ret < 0)
- goto out;
- val >>= 8;
- }
- ret = reg_write(dev, 0x8800, val);
- if (ret < 0)
- goto out;
-
- /* poll until not busy */
- retry = 10;
- for (;;) {
- ret = reg_read(gspca_dev, 0x8803);
- if (ret < 0)
- break;
- if (gspca_dev->usb_buf[0] == 0)
- break;
- if (--retry <= 0) {
- PDEBUG(D_ERR, "ssi_w busy %02x",
- gspca_dev->usb_buf[0]);
- ret = -1;
- break;
- }
- msleep(8);
- }
-
-out:
- return ret;
-}
-
-static int write_vector(struct gspca_dev *gspca_dev,
- const u16 (*data)[2])
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret = 0;
-
- while ((*data)[1] != 0) {
- if ((*data)[1] & 0x8000) {
- if ((*data)[1] == 0xdd00) /* delay */
- msleep((*data)[0]);
- else
- ret = reg_write(dev, (*data)[1], (*data)[0]);
- } else {
- ret = ssi_w(gspca_dev, (*data)[1], (*data)[0]);
- }
- if (ret < 0)
- break;
- data++;
- }
- return ret;
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
- const u16 (*init_data)[2];
- static const u16 (*(init_data_tb[]))[2] = {
- spca508_vista_init_data, /* CreativeVista 0 */
- spca508_sightcam_init_data, /* HamaUSBSightcam 1 */
- spca508_sightcam2_init_data, /* HamaUSBSightcam2 2 */
- spca508cs110_init_data, /* IntelEasyPCCamera 3 */
- spca508cs110_init_data, /* MicroInnovationIC200 4 */
- spca508_init_data, /* ViewQuestVQ110 5 */
- };
-
-#ifdef GSPCA_DEBUG
- int data1, data2;
-
- /* Read from global register the USB product and vendor IDs, just to
- * prove that we can communicate with the device. This works, which
- * confirms at we are communicating properly and that the device
- * is a 508. */
- data1 = reg_read(gspca_dev, 0x8104);
- data2 = reg_read(gspca_dev, 0x8105);
- PDEBUG(D_PROBE, "Webcam Vendor ID: 0x%02x%02x", data2, data1);
-
- data1 = reg_read(gspca_dev, 0x8106);
- data2 = reg_read(gspca_dev, 0x8107);
- PDEBUG(D_PROBE, "Webcam Product ID: 0x%02x%02x", data2, data1);
-
- data1 = reg_read(gspca_dev, 0x8621);
- PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
-#endif
-
- cam = &gspca_dev->cam;
- cam->cam_mode = sif_mode;
- cam->nmodes = ARRAY_SIZE(sif_mode);
-
- sd->subtype = id->driver_info;
-
- init_data = init_data_tb[sd->subtype];
- return write_vector(gspca_dev, init_data);
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- return 0;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- int mode;
-
- mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
- reg_write(gspca_dev->dev, 0x8500, mode);
- switch (mode) {
- case 0:
- case 1:
- reg_write(gspca_dev->dev, 0x8700, 0x28); /* clock */
- break;
- default:
-/* case 2: */
-/* case 3: */
- reg_write(gspca_dev->dev, 0x8700, 0x23); /* clock */
- break;
- }
- reg_write(gspca_dev->dev, 0x8112, 0x10 | 0x20);
- return 0;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- /* Video ISO disable, Video Drop Packet enable: */
- reg_write(gspca_dev->dev, 0x8112, 0x20);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- switch (data[0]) {
- case 0: /* start of frame */
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
- data += SPCA508_OFFSET_DATA;
- len -= SPCA508_OFFSET_DATA;
- gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
- break;
- case 0xff: /* drop */
- break;
- default:
- data += 1;
- len -= 1;
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
- break;
- }
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
-{
- /* MX seem contrast */
- reg_write(gspca_dev->dev, 0x8651, brightness);
- reg_write(gspca_dev->dev, 0x8652, brightness);
- reg_write(gspca_dev->dev, 0x8653, brightness);
- reg_write(gspca_dev->dev, 0x8654, brightness);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 5);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam},
- {USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista},
- {USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110},
- {USB_DEVICE(0x0af9, 0x0010), .driver_info = HamaUSBSightcam},
- {USB_DEVICE(0x0af9, 0x0011), .driver_info = HamaUSBSightcam2},
- {USB_DEVICE(0x8086, 0x0110), .driver_info = IntelEasyPCCamera},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
deleted file mode 100644
index cfe71dd6747..00000000000
--- a/drivers/media/video/gspca/spca561.c
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
- * Sunplus spca561 subdriver
- *
- * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
- *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "spca561"
-
-#include <linux/input.h>
-#include "gspca.h"
-
-MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
-MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-#define EXPOSURE_MAX (2047 + 325)
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- struct { /* hue/contrast control cluster */
- struct v4l2_ctrl *contrast;
- struct v4l2_ctrl *hue;
- };
- struct v4l2_ctrl *autogain;
-
-#define EXPO12A_DEF 3
- __u8 expo12a; /* expo/gain? for rev 12a */
-
- __u8 chip_revision;
-#define Rev012A 0
-#define Rev072A 1
-
- signed char ag_cnt;
-#define AG_CNT_START 13
-};
-
-static const struct v4l2_pix_format sif_012a_mode[] = {
- {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 3},
- {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
- {320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 4 / 8,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 4 / 8,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-static const struct v4l2_pix_format sif_072a_mode[] = {
- {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 3},
- {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
- {320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-/*
- * Initialization data
- * I'm not very sure how to split initialization from open data
- * chunks. For now, we'll consider everything as initialization
- */
-/* Frame packet header offsets for the spca561 */
-#define SPCA561_OFFSET_SNAP 1
-#define SPCA561_OFFSET_TYPE 2
-#define SPCA561_OFFSET_COMPRESS 3
-#define SPCA561_OFFSET_FRAMSEQ 4
-#define SPCA561_OFFSET_GPIO 5
-#define SPCA561_OFFSET_USBBUFF 6
-#define SPCA561_OFFSET_WIN2GRAVE 7
-#define SPCA561_OFFSET_WIN2RAVE 8
-#define SPCA561_OFFSET_WIN2BAVE 9
-#define SPCA561_OFFSET_WIN2GBAVE 10
-#define SPCA561_OFFSET_WIN1GRAVE 11
-#define SPCA561_OFFSET_WIN1RAVE 12
-#define SPCA561_OFFSET_WIN1BAVE 13
-#define SPCA561_OFFSET_WIN1GBAVE 14
-#define SPCA561_OFFSET_FREQ 15
-#define SPCA561_OFFSET_VSYNC 16
-#define SPCA561_INDEX_I2C_BASE 0x8800
-#define SPCA561_SNAPBIT 0x20
-#define SPCA561_SNAPCTRL 0x40
-
-static const u16 rev72a_reset[][2] = {
- {0x0000, 0x8114}, /* Software GPIO output data */
- {0x0001, 0x8114}, /* Software GPIO output data */
- {0x0000, 0x8112}, /* Some kind of reset */
- {}
-};
-static const __u16 rev72a_init_data1[][2] = {
- {0x0003, 0x8701}, /* PCLK clock delay adjustment */
- {0x0001, 0x8703}, /* HSYNC from cmos inverted */
- {0x0011, 0x8118}, /* Enable and conf sensor */
- {0x0001, 0x8118}, /* Conf sensor */
- {0x0092, 0x8804}, /* I know nothing about these */
- {0x0010, 0x8802}, /* 0x88xx registers, so I won't */
- {}
-};
-static const u16 rev72a_init_sensor1[][2] = {
- {0x0001, 0x000d},
- {0x0002, 0x0018},
- {0x0004, 0x0165},
- {0x0005, 0x0021},
- {0x0007, 0x00aa},
- {0x0020, 0x1504},
- {0x0039, 0x0002},
- {0x0035, 0x0010},
- {0x0009, 0x1049},
- {0x0028, 0x000b},
- {0x003b, 0x000f},
- {0x003c, 0x0000},
- {}
-};
-static const __u16 rev72a_init_data2[][2] = {
- {0x0018, 0x8601}, /* Pixel/line selection for color separation */
- {0x0000, 0x8602}, /* Optical black level for user setting */
- {0x0060, 0x8604}, /* Optical black horizontal offset */
- {0x0002, 0x8605}, /* Optical black vertical offset */
- {0x0000, 0x8603}, /* Non-automatic optical black level */
- {0x0002, 0x865b}, /* Horizontal offset for valid pixels */
- {0x0000, 0x865f}, /* Vertical valid pixels window (x2) */
- {0x00b0, 0x865d}, /* Horizontal valid pixels window (x2) */
- {0x0090, 0x865e}, /* Vertical valid lines window (x2) */
- {0x00e0, 0x8406}, /* Memory buffer threshold */
- {0x0000, 0x8660}, /* Compensation memory stuff */
- {0x0002, 0x8201}, /* Output address for r/w serial EEPROM */
- {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */
- {0x0001, 0x8200}, /* OprMode to be executed by hardware */
-/* from ms-win */
- {0x0000, 0x8611}, /* R offset for white balance */
- {0x00fd, 0x8612}, /* Gr offset for white balance */
- {0x0003, 0x8613}, /* B offset for white balance */
- {0x0000, 0x8614}, /* Gb offset for white balance */
-/* from ms-win */
- {0x0035, 0x8651}, /* R gain for white balance */
- {0x0040, 0x8652}, /* Gr gain for white balance */
- {0x005f, 0x8653}, /* B gain for white balance */
- {0x0040, 0x8654}, /* Gb gain for white balance */
- {0x0002, 0x8502}, /* Maximum average bit rate stuff */
- {0x0011, 0x8802},
-
- {0x0087, 0x8700}, /* Set master clock (96Mhz????) */
- {0x0081, 0x8702}, /* Master clock output enable */
-
- {0x0000, 0x8500}, /* Set image type (352x288 no compression) */
- /* Originally was 0x0010 (352x288 compression) */
-
- {0x0002, 0x865b}, /* Horizontal offset for valid pixels */
- {0x0003, 0x865c}, /* Vertical offset for valid lines */
- {}
-};
-static const u16 rev72a_init_sensor2[][2] = {
- {0x0003, 0x0121},
- {0x0004, 0x0165},
- {0x0005, 0x002f}, /* blanking control column */
- {0x0006, 0x0000}, /* blanking mode row*/
- {0x000a, 0x0002},
- {0x0009, 0x1061}, /* setexposure times && pixel clock
- * 0001 0 | 000 0110 0001 */
- {0x0035, 0x0014},
- {}
-};
-
-/******************** QC Express etch2 stuff ********************/
-static const __u16 Pb100_1map8300[][2] = {
- /* reg, value */
- {0x8320, 0x3304},
-
- {0x8303, 0x0125}, /* image area */
- {0x8304, 0x0169},
- {0x8328, 0x000b},
- {0x833c, 0x0001}, /*fixme: win:07*/
-
- {0x832f, 0x1904}, /*fixme: was 0419*/
- {0x8307, 0x00aa},
- {0x8301, 0x0003},
- {0x8302, 0x000e},
- {}
-};
-static const __u16 Pb100_2map8300[][2] = {
- /* reg, value */
- {0x8339, 0x0000},
- {0x8307, 0x00aa},
- {}
-};
-
-static const __u16 spca561_161rev12A_data1[][2] = {
- {0x29, 0x8118}, /* Control register (various enable bits) */
- {0x08, 0x8114}, /* GPIO: Led off */
- {0x0e, 0x8112}, /* 0x0e stream off 0x3e stream on */
- {0x00, 0x8102}, /* white balance - new */
- {0x92, 0x8804},
- {0x04, 0x8802}, /* windows uses 08 */
- {}
-};
-static const __u16 spca561_161rev12A_data2[][2] = {
- {0x21, 0x8118},
- {0x10, 0x8500},
- {0x07, 0x8601},
- {0x07, 0x8602},
- {0x04, 0x8501},
-
- {0x07, 0x8201}, /* windows uses 02 */
- {0x08, 0x8200},
- {0x01, 0x8200},
-
- {0x90, 0x8604},
- {0x00, 0x8605},
- {0xb0, 0x8603},
-
- /* sensor gains */
- {0x07, 0x8601}, /* white balance - new */
- {0x07, 0x8602}, /* white balance - new */
- {0x00, 0x8610}, /* *red */
- {0x00, 0x8611}, /* 3f *green */
- {0x00, 0x8612}, /* green *blue */
- {0x00, 0x8613}, /* blue *green */
- {0x43, 0x8614}, /* green *red - white balance - was 0x35 */
- {0x40, 0x8615}, /* 40 *green - white balance - was 0x35 */
- {0x71, 0x8616}, /* 7a *blue - white balance - was 0x35 */
- {0x40, 0x8617}, /* 40 *green - white balance - was 0x35 */
-
- {0x0c, 0x8620}, /* 0c */
- {0xc8, 0x8631}, /* c8 */
- {0xc8, 0x8634}, /* c8 */
- {0x23, 0x8635}, /* 23 */
- {0x1f, 0x8636}, /* 1f */
- {0xdd, 0x8637}, /* dd */
- {0xe1, 0x8638}, /* e1 */
- {0x1d, 0x8639}, /* 1d */
- {0x21, 0x863a}, /* 21 */
- {0xe3, 0x863b}, /* e3 */
- {0xdf, 0x863c}, /* df */
- {0xf0, 0x8505},
- {0x32, 0x850a},
-/* {0x99, 0x8700}, * - white balance - new (removed) */
- /* HDG we used to do this in stop0, making the init state and the state
- after a start / stop different, so do this here instead. */
- {0x29, 0x8118},
- {}
-};
-
-static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
-{
- int ret;
-
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, NULL, 0, 500);
- PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
- if (ret < 0)
- pr_err("reg write: error %d\n", ret);
-}
-
-static void write_vector(struct gspca_dev *gspca_dev,
- const __u16 data[][2])
-{
- struct usb_device *dev = gspca_dev->dev;
- int i;
-
- i = 0;
- while (data[i][1] != 0) {
- reg_w_val(dev, data[i][1], data[i][0]);
- i++;
- }
-}
-
-/* read 'len' bytes to gspca_dev->usb_buf */
-static void reg_r(struct gspca_dev *gspca_dev,
- __u16 index, __u16 length)
-{
- usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- 0, /* request */
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, /* value */
- index, gspca_dev->usb_buf, length, 500);
-}
-
-/* write 'len' bytes from gspca_dev->usb_buf */
-static void reg_w_buf(struct gspca_dev *gspca_dev,
- __u16 index, __u16 len)
-{
- usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, /* value */
- index, gspca_dev->usb_buf, len, 500);
-}
-
-static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
-{
- int retry = 60;
-
- reg_w_val(gspca_dev->dev, 0x8801, reg);
- reg_w_val(gspca_dev->dev, 0x8805, value);
- reg_w_val(gspca_dev->dev, 0x8800, value >> 8);
- do {
- reg_r(gspca_dev, 0x8803, 1);
- if (!gspca_dev->usb_buf[0])
- return;
- msleep(10);
- } while (--retry);
-}
-
-static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
-{
- int retry = 60;
- __u8 value;
-
- reg_w_val(gspca_dev->dev, 0x8804, 0x92);
- reg_w_val(gspca_dev->dev, 0x8801, reg);
- reg_w_val(gspca_dev->dev, 0x8802, mode | 0x01);
- do {
- reg_r(gspca_dev, 0x8803, 1);
- if (!gspca_dev->usb_buf[0]) {
- reg_r(gspca_dev, 0x8800, 1);
- value = gspca_dev->usb_buf[0];
- reg_r(gspca_dev, 0x8805, 1);
- return ((int) value << 8) | gspca_dev->usb_buf[0];
- }
- msleep(10);
- } while (--retry);
- return -1;
-}
-
-static void sensor_mapwrite(struct gspca_dev *gspca_dev,
- const __u16 (*sensormap)[2])
-{
- while ((*sensormap)[0]) {
- gspca_dev->usb_buf[0] = (*sensormap)[1];
- gspca_dev->usb_buf[1] = (*sensormap)[1] >> 8;
- reg_w_buf(gspca_dev, (*sensormap)[0], 2);
- sensormap++;
- }
-}
-
-static void write_sensor_72a(struct gspca_dev *gspca_dev,
- const __u16 (*sensor)[2])
-{
- while ((*sensor)[0]) {
- i2c_write(gspca_dev, (*sensor)[1], (*sensor)[0]);
- sensor++;
- }
-}
-
-static void init_161rev12A(struct gspca_dev *gspca_dev)
-{
- write_vector(gspca_dev, spca561_161rev12A_data1);
- sensor_mapwrite(gspca_dev, Pb100_1map8300);
-/*fixme: should be in sd_start*/
- write_vector(gspca_dev, spca561_161rev12A_data2);
- sensor_mapwrite(gspca_dev, Pb100_2map8300);
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
- __u16 vendor, product;
- __u8 data1, data2;
-
- /* Read frm global register the USB product and vendor IDs, just to
- * prove that we can communicate with the device. This works, which
- * confirms at we are communicating properly and that the device
- * is a 561. */
- reg_r(gspca_dev, 0x8104, 1);
- data1 = gspca_dev->usb_buf[0];
- reg_r(gspca_dev, 0x8105, 1);
- data2 = gspca_dev->usb_buf[0];
- vendor = (data2 << 8) | data1;
- reg_r(gspca_dev, 0x8106, 1);
- data1 = gspca_dev->usb_buf[0];
- reg_r(gspca_dev, 0x8107, 1);
- data2 = gspca_dev->usb_buf[0];
- product = (data2 << 8) | data1;
- if (vendor != id->idVendor || product != id->idProduct) {
- PDEBUG(D_PROBE, "Bad vendor / product from device");
- return -EINVAL;
- }
-
- cam = &gspca_dev->cam;
- cam->needs_full_bandwidth = 1;
-
- sd->chip_revision = id->driver_info;
- if (sd->chip_revision == Rev012A) {
- cam->cam_mode = sif_012a_mode;
- cam->nmodes = ARRAY_SIZE(sif_012a_mode);
- } else {
- cam->cam_mode = sif_072a_mode;
- cam->nmodes = ARRAY_SIZE(sif_072a_mode);
- }
- sd->expo12a = EXPO12A_DEF;
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init_12a(struct gspca_dev *gspca_dev)
-{
- PDEBUG(D_STREAM, "Chip revision: 012a");
- init_161rev12A(gspca_dev);
- return 0;
-}
-static int sd_init_72a(struct gspca_dev *gspca_dev)
-{
- PDEBUG(D_STREAM, "Chip revision: 072a");
- write_vector(gspca_dev, rev72a_reset);
- msleep(200);
- write_vector(gspca_dev, rev72a_init_data1);
- write_sensor_72a(gspca_dev, rev72a_init_sensor1);
- write_vector(gspca_dev, rev72a_init_data2);
- write_sensor_72a(gspca_dev, rev72a_init_sensor2);
- reg_w_val(gspca_dev->dev, 0x8112, 0x30);
- return 0;
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct usb_device *dev = gspca_dev->dev;
- __u16 reg;
-
- if (sd->chip_revision == Rev012A)
- reg = 0x8610;
- else
- reg = 0x8611;
-
- reg_w_val(dev, reg + 0, val); /* R */
- reg_w_val(dev, reg + 1, val); /* Gr */
- reg_w_val(dev, reg + 2, val); /* B */
- reg_w_val(dev, reg + 3, val); /* Gb */
-}
-
-static void setwhite(struct gspca_dev *gspca_dev, s32 white, s32 contrast)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct usb_device *dev = gspca_dev->dev;
- __u8 blue, red;
- __u16 reg;
-
- /* try to emulate MS-win as possible */
- red = 0x20 + white * 3 / 8;
- blue = 0x90 - white * 5 / 8;
- if (sd->chip_revision == Rev012A) {
- reg = 0x8614;
- } else {
- reg = 0x8651;
- red += contrast - 0x20;
- blue += contrast - 0x20;
- reg_w_val(dev, 0x8652, contrast + 0x20); /* Gr */
- reg_w_val(dev, 0x8654, contrast + 0x20); /* Gb */
- }
- reg_w_val(dev, reg, red);
- reg_w_val(dev, reg + 2, blue);
-}
-
-/* rev 12a only */
-static void setexposure(struct gspca_dev *gspca_dev, s32 val)
-{
- int i, expo = 0;
-
- /* Register 0x8309 controls exposure for the spca561,
- the basic exposure setting goes from 1-2047, where 1 is completely
- dark and 2047 is very bright. It not only influences exposure but
- also the framerate (to allow for longer exposure) from 1 - 300 it
- only raises the exposure time then from 300 - 600 it halves the
- framerate to be able to further raise the exposure time and for every
- 300 more it halves the framerate again. This allows for a maximum
- exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
- Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
- configure a divider for the base framerate which us used at the
- exposure setting of 1-300. These bits configure the base framerate
- according to the following formula: fps = 60 / (value + 2) */
-
- /* We choose to use the high bits setting the fixed framerate divisor
- asap, as setting high basic exposure setting without the fixed
- divider in combination with high gains makes the cam stop */
- int table[] = { 0, 450, 550, 625, EXPOSURE_MAX };
-
- for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
- if (val <= table[i + 1]) {
- expo = val - table[i];
- if (i)
- expo += 300;
- expo |= i << 11;
- break;
- }
- }
-
- gspca_dev->usb_buf[0] = expo;
- gspca_dev->usb_buf[1] = expo >> 8;
- reg_w_buf(gspca_dev, 0x8309, 2);
-}
-
-/* rev 12a only */
-static void setgain(struct gspca_dev *gspca_dev, s32 val)
-{
- /* gain reg low 6 bits 0-63 gain, bit 6 and 7, both double the
- sensitivity when set, so 31 + one of them set == 63, and 15
- with both of them set == 63 */
- if (val < 64)
- gspca_dev->usb_buf[0] = val;
- else if (val < 128)
- gspca_dev->usb_buf[0] = (val / 2) | 0x40;
- else
- gspca_dev->usb_buf[0] = (val / 4) | 0xc0;
-
- gspca_dev->usb_buf[1] = 0;
- reg_w_buf(gspca_dev, 0x8335, 2);
-}
-
-static void setautogain(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (val)
- sd->ag_cnt = AG_CNT_START;
- else
- sd->ag_cnt = -1;
-}
-
-static int sd_start_12a(struct gspca_dev *gspca_dev)
-{
- struct usb_device *dev = gspca_dev->dev;
- int mode;
- static const __u8 Reg8391[8] =
- {0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00};
-
- mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
- if (mode <= 1) {
- /* Use compression on 320x240 and above */
- reg_w_val(dev, 0x8500, 0x10 | mode);
- } else {
- /* I couldn't get the compression to work below 320x240
- * Fortunately at these resolutions the bandwidth
- * is sufficient to push raw frames at ~20fps */
- reg_w_val(dev, 0x8500, mode);
- } /* -- qq@kuku.eu.org */
-
- gspca_dev->usb_buf[0] = 0xaa;
- gspca_dev->usb_buf[1] = 0x00;
- reg_w_buf(gspca_dev, 0x8307, 2);
- /* clock - lower 0x8X values lead to fps > 30 */
- reg_w_val(gspca_dev->dev, 0x8700, 0x8a);
- /* 0x8f 0x85 0x27 clock */
- reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
- reg_w_val(gspca_dev->dev, 0x850b, 0x03);
- memcpy(gspca_dev->usb_buf, Reg8391, 8);
- reg_w_buf(gspca_dev, 0x8391, 8);
- reg_w_buf(gspca_dev, 0x8390, 8);
-
- /* Led ON (bit 3 -> 0 */
- reg_w_val(gspca_dev->dev, 0x8114, 0x00);
- return 0;
-}
-static int sd_start_72a(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct usb_device *dev = gspca_dev->dev;
- int Clck;
- int mode;
-
- write_vector(gspca_dev, rev72a_reset);
- msleep(200);
- write_vector(gspca_dev, rev72a_init_data1);
- write_sensor_72a(gspca_dev, rev72a_init_sensor1);
-
- mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
- switch (mode) {
- default:
- case 0:
- Clck = 0x27; /* ms-win 0x87 */
- break;
- case 1:
- Clck = 0x25;
- break;
- case 2:
- Clck = 0x22;
- break;
- case 3:
- Clck = 0x21;
- break;
- }
- reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
- reg_w_val(dev, 0x8702, 0x81);
- reg_w_val(dev, 0x8500, mode); /* mode */
- write_sensor_72a(gspca_dev, rev72a_init_sensor2);
- setwhite(gspca_dev, v4l2_ctrl_g_ctrl(sd->hue),
- v4l2_ctrl_g_ctrl(sd->contrast));
-/* setbrightness(gspca_dev); * fixme: bad values */
- setautogain(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain));
- reg_w_val(dev, 0x8112, 0x10 | 0x20);
- return 0;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->chip_revision == Rev012A) {
- reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
- /* Led Off (bit 3 -> 1 */
- reg_w_val(gspca_dev->dev, 0x8114, 0x08);
- } else {
- reg_w_val(gspca_dev->dev, 0x8112, 0x20);
-/* reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */
- }
-}
-
-static void do_autogain(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int expotimes;
- int pixelclk;
- int gainG;
- __u8 R, Gr, Gb, B;
- int y;
- __u8 luma_mean = 110;
- __u8 luma_delta = 20;
- __u8 spring = 4;
-
- if (sd->ag_cnt < 0)
- return;
- if (--sd->ag_cnt >= 0)
- return;
- sd->ag_cnt = AG_CNT_START;
-
- switch (sd->chip_revision) {
- case Rev072A:
- reg_r(gspca_dev, 0x8621, 1);
- Gr = gspca_dev->usb_buf[0];
- reg_r(gspca_dev, 0x8622, 1);
- R = gspca_dev->usb_buf[0];
- reg_r(gspca_dev, 0x8623, 1);
- B = gspca_dev->usb_buf[0];
- reg_r(gspca_dev, 0x8624, 1);
- Gb = gspca_dev->usb_buf[0];
- y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
- /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
- /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
- /* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */
-
- if (y < luma_mean - luma_delta ||
- y > luma_mean + luma_delta) {
- expotimes = i2c_read(gspca_dev, 0x09, 0x10);
- pixelclk = 0x0800;
- expotimes = expotimes & 0x07ff;
- /* PDEBUG(D_PACK,
- "Exposition Times 0x%03X Clock 0x%04X ",
- expotimes,pixelclk); */
- gainG = i2c_read(gspca_dev, 0x35, 0x10);
- /* PDEBUG(D_PACK,
- "reading Gain register %d", gainG); */
-
- expotimes += (luma_mean - y) >> spring;
- gainG += (luma_mean - y) / 50;
- /* PDEBUG(D_PACK,
- "compute expotimes %d gain %d",
- expotimes,gainG); */
-
- if (gainG > 0x3f)
- gainG = 0x3f;
- else if (gainG < 3)
- gainG = 3;
- i2c_write(gspca_dev, gainG, 0x35);
-
- if (expotimes > 0x0256)
- expotimes = 0x0256;
- else if (expotimes < 3)
- expotimes = 3;
- i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
- }
- break;
- }
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- len--;
- switch (*data++) { /* sequence number */
- case 0: /* start of frame */
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
-
- /* This should never happen */
- if (len < 2) {
- PDEBUG(D_ERR, "Short SOF packet, ignoring");
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- if (data[0] & 0x20) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
- input_sync(gspca_dev->input_dev);
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
- input_sync(gspca_dev->input_dev);
- }
-#endif
-
- if (data[1] & 0x10) {
- /* compressed bayer */
- gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
- } else {
- /* raw bayer (with a header, which we skip) */
- if (sd->chip_revision == Rev012A) {
- data += 20;
- len -= 20;
- } else {
- data += 16;
- len -= 16;
- }
- gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
- }
- return;
- case 0xff: /* drop (empty mpackets) */
- return;
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- /* hue/contrast control cluster for 72a */
- setwhite(gspca_dev, sd->hue->val, ctrl->val);
- break;
- case V4L2_CID_HUE:
- /* just plain hue control for 12a */
- setwhite(gspca_dev, ctrl->val, 0);
- break;
- case V4L2_CID_EXPOSURE:
- setexposure(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_GAIN:
- setgain(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_AUTOGAIN:
- setautogain(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls_12a(struct gspca_dev *gspca_dev)
-{
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 3);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_HUE, 1, 0x7f, 1, 0x40);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 1, EXPOSURE_MAX, 1, 700);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 255, 1, 63);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-static int sd_init_controls_72a(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 4);
- sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 0x3f, 1, 0x20);
- sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_HUE, 1, 0x7f, 1, 0x40);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 0x3f, 1, 0x20);
- sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- v4l2_ctrl_cluster(2, &sd->contrast);
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc_12a = {
- .name = MODULE_NAME,
- .init_controls = sd_init_controls_12a,
- .config = sd_config,
- .init = sd_init_12a,
- .start = sd_start_12a,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .other_input = 1,
-#endif
-};
-static const struct sd_desc sd_desc_72a = {
- .name = MODULE_NAME,
- .init_controls = sd_init_controls_72a,
- .config = sd_config,
- .init = sd_init_72a,
- .start = sd_start_72a,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
- .dq_callback = do_autogain,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .other_input = 1,
-#endif
-};
-static const struct sd_desc *sd_desc[2] = {
- &sd_desc_12a,
- &sd_desc_72a
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
- {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
- {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
- {USB_DEVICE(0x0461, 0x0815), .driver_info = Rev072A},
- {USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
- {USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
- {USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
- {USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A},
- {USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A},
- {USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A},
- {USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A},
- {USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A},
- {USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A},
- {USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A},
- {USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A},
- {USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id,
- sd_desc[id->driver_info],
- sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c
deleted file mode 100644
index a8ac97931ad..00000000000
--- a/drivers/media/video/gspca/sq905.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * SQ905 subdriver
- *
- * Copyright (C) 2008, 2009 Adam Baker and Theodore Kilgore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * History and Acknowledgments
- *
- * The original Linux driver for SQ905 based cameras was written by
- * Marcell Lengyel and furter developed by many other contributors
- * and is available from http://sourceforge.net/projects/sqcam/
- *
- * This driver takes advantage of the reverse engineering work done for
- * that driver and for libgphoto2 but shares no code with them.
- *
- * This driver has used as a base the finepix driver and other gspca
- * based drivers and may still contain code fragments taken from those
- * drivers.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "sq905"
-
-#include <linux/workqueue.h>
-#include <linux/slab.h>
-#include "gspca.h"
-
-MODULE_AUTHOR("Adam Baker <linux@baker-net.org.uk>, "
- "Theodore Kilgore <kilgota@auburn.edu>");
-MODULE_DESCRIPTION("GSPCA/SQ905 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* Default timeouts, in ms */
-#define SQ905_CMD_TIMEOUT 500
-#define SQ905_DATA_TIMEOUT 1000
-
-/* Maximum transfer size to use. */
-#define SQ905_MAX_TRANSFER 0x8000
-#define FRAME_HEADER_LEN 64
-
-/* The known modes, or registers. These go in the "value" slot. */
-
-/* 00 is "none" obviously */
-
-#define SQ905_BULK_READ 0x03 /* precedes any bulk read */
-#define SQ905_COMMAND 0x06 /* precedes the command codes below */
-#define SQ905_PING 0x07 /* when reading an "idling" command */
-#define SQ905_READ_DONE 0xc0 /* ack bulk read completed */
-
-/* Any non-zero value in the bottom 2 bits of the 2nd byte of
- * the ID appears to indicate the camera can do 640*480. If the
- * LSB of that byte is set the image is just upside down, otherwise
- * it is rotated 180 degrees. */
-#define SQ905_HIRES_MASK 0x00000300
-#define SQ905_ORIENTATION_MASK 0x00000100
-
-/* Some command codes. These go in the "index" slot. */
-
-#define SQ905_ID 0xf0 /* asks for model string */
-#define SQ905_CONFIG 0x20 /* gets photo alloc. table, not used here */
-#define SQ905_DATA 0x30 /* accesses photo data, not used here */
-#define SQ905_CLEAR 0xa0 /* clear everything */
-#define SQ905_CAPTURE_LOW 0x60 /* Starts capture at 160x120 */
-#define SQ905_CAPTURE_MED 0x61 /* Starts capture at 320x240 */
-#define SQ905_CAPTURE_HIGH 0x62 /* Starts capture at 640x480 (some cams only) */
-/* note that the capture command also controls the output dimensions */
-
-/* Structure to hold all of our device specific stuff */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- /*
- * Driver stuff
- */
- struct work_struct work_struct;
- struct workqueue_struct *work_thread;
-};
-
-static struct v4l2_pix_format sq905_mode[] = {
- { 160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
- { 320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
- { 640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0}
-};
-
-/*
- * Send a command to the camera.
- */
-static int sq905_command(struct gspca_dev *gspca_dev, u16 index)
-{
- int ret;
-
- gspca_dev->usb_buf[0] = '\0';
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- USB_REQ_SYNCH_FRAME, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- SQ905_COMMAND, index, gspca_dev->usb_buf, 1,
- SQ905_CMD_TIMEOUT);
- if (ret < 0) {
- pr_err("%s: usb_control_msg failed (%d)\n", __func__, ret);
- return ret;
- }
-
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- USB_REQ_SYNCH_FRAME, /* request */
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- SQ905_PING, 0, gspca_dev->usb_buf, 1,
- SQ905_CMD_TIMEOUT);
- if (ret < 0) {
- pr_err("%s: usb_control_msg failed 2 (%d)\n", __func__, ret);
- return ret;
- }
-
- return 0;
-}
-
-/*
- * Acknowledge the end of a frame - see warning on sq905_command.
- */
-static int sq905_ack_frame(struct gspca_dev *gspca_dev)
-{
- int ret;
-
- gspca_dev->usb_buf[0] = '\0';
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- USB_REQ_SYNCH_FRAME, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- SQ905_READ_DONE, 0, gspca_dev->usb_buf, 1,
- SQ905_CMD_TIMEOUT);
- if (ret < 0) {
- pr_err("%s: usb_control_msg failed (%d)\n", __func__, ret);
- return ret;
- }
-
- return 0;
-}
-
-/*
- * request and read a block of data - see warning on sq905_command.
- */
-static int
-sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock)
-{
- int ret;
- int act_len;
-
- gspca_dev->usb_buf[0] = '\0';
- if (need_lock)
- mutex_lock(&gspca_dev->usb_lock);
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- USB_REQ_SYNCH_FRAME, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- SQ905_BULK_READ, size, gspca_dev->usb_buf,
- 1, SQ905_CMD_TIMEOUT);
- if (need_lock)
- mutex_unlock(&gspca_dev->usb_lock);
- if (ret < 0) {
- pr_err("%s: usb_control_msg failed (%d)\n", __func__, ret);
- return ret;
- }
- ret = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev, 0x81),
- data, size, &act_len, SQ905_DATA_TIMEOUT);
-
- /* successful, it returns 0, otherwise negative */
- if (ret < 0 || act_len != size) {
- pr_err("bulk read fail (%d) len %d/%d\n", ret, act_len, size);
- return -EIO;
- }
- return 0;
-}
-
-/* This function is called as a workqueue function and runs whenever the camera
- * is streaming data. Because it is a workqueue function it is allowed to sleep
- * so we can use synchronous USB calls. To avoid possible collisions with other
- * threads attempting to use the camera's USB interface we take the gspca
- * usb_lock when performing USB operations. In practice the only thing we need
- * to protect against is the usb_set_interface call that gspca makes during
- * stream_off as the camera doesn't provide any controls that the user could try
- * to change.
- */
-static void sq905_dostream(struct work_struct *work)
-{
- struct sd *dev = container_of(work, struct sd, work_struct);
- struct gspca_dev *gspca_dev = &dev->gspca_dev;
- int bytes_left; /* bytes remaining in current frame. */
- int data_len; /* size to use for the next read. */
- int header_read; /* true if we have already read the frame header. */
- int packet_type;
- int frame_sz;
- int ret;
- u8 *data;
- u8 *buffer;
-
- buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
- if (!buffer) {
- pr_err("Couldn't allocate USB buffer\n");
- goto quit_stream;
- }
-
- frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage
- + FRAME_HEADER_LEN;
-
- while (gspca_dev->dev && gspca_dev->streaming) {
-#ifdef CONFIG_PM
- if (gspca_dev->frozen)
- break;
-#endif
- /* request some data and then read it until we have
- * a complete frame. */
- bytes_left = frame_sz;
- header_read = 0;
-
- /* Note we do not check for gspca_dev->streaming here, as
- we must finish reading an entire frame, otherwise the
- next time we stream we start reading in the middle of a
- frame. */
- while (bytes_left > 0 && gspca_dev->dev) {
- data_len = bytes_left > SQ905_MAX_TRANSFER ?
- SQ905_MAX_TRANSFER : bytes_left;
- ret = sq905_read_data(gspca_dev, buffer, data_len, 1);
- if (ret < 0)
- goto quit_stream;
- PDEBUG(D_PACK,
- "Got %d bytes out of %d for frame",
- data_len, bytes_left);
- bytes_left -= data_len;
- data = buffer;
- if (!header_read) {
- packet_type = FIRST_PACKET;
- /* The first 64 bytes of each frame are
- * a header full of FF 00 bytes */
- data += FRAME_HEADER_LEN;
- data_len -= FRAME_HEADER_LEN;
- header_read = 1;
- } else if (bytes_left == 0) {
- packet_type = LAST_PACKET;
- } else {
- packet_type = INTER_PACKET;
- }
- gspca_frame_add(gspca_dev, packet_type,
- data, data_len);
- /* If entire frame fits in one packet we still
- need to add a LAST_PACKET */
- if (packet_type == FIRST_PACKET &&
- bytes_left == 0)
- gspca_frame_add(gspca_dev, LAST_PACKET,
- NULL, 0);
- }
- if (gspca_dev->dev) {
- /* acknowledge the frame */
- mutex_lock(&gspca_dev->usb_lock);
- ret = sq905_ack_frame(gspca_dev);
- mutex_unlock(&gspca_dev->usb_lock);
- if (ret < 0)
- goto quit_stream;
- }
- }
-quit_stream:
- if (gspca_dev->dev) {
- mutex_lock(&gspca_dev->usb_lock);
- sq905_command(gspca_dev, SQ905_CLEAR);
- mutex_unlock(&gspca_dev->usb_lock);
- }
- kfree(buffer);
-}
-
-/* This function is called at probe time just before sd_init */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct cam *cam = &gspca_dev->cam;
- struct sd *dev = (struct sd *) gspca_dev;
-
- /* We don't use the buffer gspca allocates so make it small. */
- cam->bulk = 1;
- cam->bulk_size = 64;
-
- INIT_WORK(&dev->work_struct, sq905_dostream);
-
- return 0;
-}
-
-/* called on streamoff with alt==0 and on disconnect */
-/* the usb_lock is held at entry - restore on exit */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *dev = (struct sd *) gspca_dev;
-
- /* wait for the work queue to terminate */
- mutex_unlock(&gspca_dev->usb_lock);
- /* This waits for sq905_dostream to finish */
- destroy_workqueue(dev->work_thread);
- dev->work_thread = NULL;
- mutex_lock(&gspca_dev->usb_lock);
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- u32 ident;
- int ret;
-
- /* connect to the camera and read
- * the model ID and process that and put it away.
- */
- ret = sq905_command(gspca_dev, SQ905_CLEAR);
- if (ret < 0)
- return ret;
- ret = sq905_command(gspca_dev, SQ905_ID);
- if (ret < 0)
- return ret;
- ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4, 0);
- if (ret < 0)
- return ret;
- /* usb_buf is allocated with kmalloc so is aligned.
- * Camera model number is the right way round if we assume this
- * reverse engineered ID is supposed to be big endian. */
- ident = be32_to_cpup((__be32 *)gspca_dev->usb_buf);
- ret = sq905_command(gspca_dev, SQ905_CLEAR);
- if (ret < 0)
- return ret;
- PDEBUG(D_CONF, "SQ905 camera ID %08x detected", ident);
- gspca_dev->cam.cam_mode = sq905_mode;
- gspca_dev->cam.nmodes = ARRAY_SIZE(sq905_mode);
- if (!(ident & SQ905_HIRES_MASK))
- gspca_dev->cam.nmodes--;
-
- if (ident & SQ905_ORIENTATION_MASK)
- gspca_dev->cam.input_flags = V4L2_IN_ST_VFLIP;
- else
- gspca_dev->cam.input_flags = V4L2_IN_ST_VFLIP |
- V4L2_IN_ST_HFLIP;
- return 0;
-}
-
-/* Set up for getting frames. */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *dev = (struct sd *) gspca_dev;
- int ret;
-
- /* "Open the shutter" and set size, to start capture */
- switch (gspca_dev->curr_mode) {
- default:
-/* case 2: */
- PDEBUG(D_STREAM, "Start streaming at high resolution");
- ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_HIGH);
- break;
- case 1:
- PDEBUG(D_STREAM, "Start streaming at medium resolution");
- ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_MED);
- break;
- case 0:
- PDEBUG(D_STREAM, "Start streaming at low resolution");
- ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_LOW);
- }
-
- if (ret < 0) {
- PDEBUG(D_ERR, "Start streaming command failed");
- return ret;
- }
- /* Start the workqueue function to do the streaming */
- dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
- queue_work(dev->work_thread, &dev->work_struct);
-
- return 0;
-}
-
-/* Table of supported USB devices */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x2770, 0x9120)},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .start = sd_start,
- .stop0 = sd_stop0,
-};
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id,
- &sd_desc,
- sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
deleted file mode 100644
index 2c2f3d2f357..00000000000
--- a/drivers/media/video/gspca/sq905c.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * SQ905C subdriver
- *
- * Copyright (C) 2009 Theodore Kilgore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- *
- * This driver uses work done in
- * libgphoto2/camlibs/digigr8, Copyright (C) Theodore Kilgore.
- *
- * This driver has also used as a base the sq905c driver
- * and may contain code fragments from it.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "sq905c"
-
-#include <linux/workqueue.h>
-#include <linux/slab.h>
-#include "gspca.h"
-
-MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
-MODULE_DESCRIPTION("GSPCA/SQ905C USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* Default timeouts, in ms */
-#define SQ905C_CMD_TIMEOUT 500
-#define SQ905C_DATA_TIMEOUT 1000
-
-/* Maximum transfer size to use. */
-#define SQ905C_MAX_TRANSFER 0x8000
-
-#define FRAME_HEADER_LEN 0x50
-
-/* Commands. These go in the "value" slot. */
-#define SQ905C_CLEAR 0xa0 /* clear everything */
-#define SQ905C_GET_ID 0x14f4 /* Read version number */
-#define SQ905C_CAPTURE_LOW 0xa040 /* Starts capture at 160x120 */
-#define SQ905C_CAPTURE_MED 0x1440 /* Starts capture at 320x240 */
-#define SQ905C_CAPTURE_HI 0x2840 /* Starts capture at 320x240 */
-
-/* For capture, this must go in the "index" slot. */
-#define SQ905C_CAPTURE_INDEX 0x110f
-
-/* Structure to hold all of our device specific stuff */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- const struct v4l2_pix_format *cap_mode;
- /* Driver stuff */
- struct work_struct work_struct;
- struct workqueue_struct *work_thread;
-};
-
-/*
- * Most of these cameras will do 640x480 and 320x240. 160x120 works
- * in theory but gives very poor output. Therefore, not supported.
- * The 0x2770:0x9050 cameras have max resolution of 320x240.
- */
-static struct v4l2_pix_format sq905c_mode[] = {
- { 320, 240, V4L2_PIX_FMT_SQ905C, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
- { 640, 480, V4L2_PIX_FMT_SQ905C, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0}
-};
-
-/* Send a command to the camera. */
-static int sq905c_command(struct gspca_dev *gspca_dev, u16 command, u16 index)
-{
- int ret;
-
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- USB_REQ_SYNCH_FRAME, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- command, index, NULL, 0,
- SQ905C_CMD_TIMEOUT);
- if (ret < 0) {
- pr_err("%s: usb_control_msg failed (%d)\n", __func__, ret);
- return ret;
- }
-
- return 0;
-}
-
-static int sq905c_read(struct gspca_dev *gspca_dev, u16 command, u16 index,
- int size)
-{
- int ret;
-
- ret = usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- USB_REQ_SYNCH_FRAME, /* request */
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- command, index, gspca_dev->usb_buf, size,
- SQ905C_CMD_TIMEOUT);
- if (ret < 0) {
- pr_err("%s: usb_control_msg failed (%d)\n", __func__, ret);
- return ret;
- }
-
- return 0;
-}
-
-/* This function is called as a workqueue function and runs whenever the camera
- * is streaming data. Because it is a workqueue function it is allowed to sleep
- * so we can use synchronous USB calls. To avoid possible collisions with other
- * threads attempting to use the camera's USB interface the gspca usb_lock is
- * used when performing the one USB control operation inside the workqueue,
- * which tells the camera to close the stream. In practice the only thing
- * which needs to be protected against is the usb_set_interface call that
- * gspca makes during stream_off. Otherwise the camera doesn't provide any
- * controls that the user could try to change.
- */
-static void sq905c_dostream(struct work_struct *work)
-{
- struct sd *dev = container_of(work, struct sd, work_struct);
- struct gspca_dev *gspca_dev = &dev->gspca_dev;
- int bytes_left; /* bytes remaining in current frame. */
- int data_len; /* size to use for the next read. */
- int act_len;
- int packet_type;
- int ret;
- u8 *buffer;
-
- buffer = kmalloc(SQ905C_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
- if (!buffer) {
- pr_err("Couldn't allocate USB buffer\n");
- goto quit_stream;
- }
-
- while (gspca_dev->dev && gspca_dev->streaming) {
-#ifdef CONFIG_PM
- if (gspca_dev->frozen)
- break;
-#endif
- /* Request the header, which tells the size to download */
- ret = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev, 0x81),
- buffer, FRAME_HEADER_LEN, &act_len,
- SQ905C_DATA_TIMEOUT);
- PDEBUG(D_STREAM,
- "Got %d bytes out of %d for header",
- act_len, FRAME_HEADER_LEN);
- if (ret < 0 || act_len < FRAME_HEADER_LEN)
- goto quit_stream;
- /* size is read from 4 bytes starting 0x40, little endian */
- bytes_left = buffer[0x40]|(buffer[0x41]<<8)|(buffer[0x42]<<16)
- |(buffer[0x43]<<24);
- PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left);
- /* We keep the header. It has other information, too. */
- packet_type = FIRST_PACKET;
- gspca_frame_add(gspca_dev, packet_type,
- buffer, FRAME_HEADER_LEN);
- while (bytes_left > 0 && gspca_dev->dev) {
- data_len = bytes_left > SQ905C_MAX_TRANSFER ?
- SQ905C_MAX_TRANSFER : bytes_left;
- ret = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev, 0x81),
- buffer, data_len, &act_len,
- SQ905C_DATA_TIMEOUT);
- if (ret < 0 || act_len < data_len)
- goto quit_stream;
- PDEBUG(D_STREAM,
- "Got %d bytes out of %d for frame",
- data_len, bytes_left);
- bytes_left -= data_len;
- if (bytes_left == 0)
- packet_type = LAST_PACKET;
- else
- packet_type = INTER_PACKET;
- gspca_frame_add(gspca_dev, packet_type,
- buffer, data_len);
- }
- }
-quit_stream:
- if (gspca_dev->dev) {
- mutex_lock(&gspca_dev->usb_lock);
- sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
- mutex_unlock(&gspca_dev->usb_lock);
- }
- kfree(buffer);
-}
-
-/* This function is called at probe time just before sd_init */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct cam *cam = &gspca_dev->cam;
- struct sd *dev = (struct sd *) gspca_dev;
- int ret;
-
- PDEBUG(D_PROBE,
- "SQ9050 camera detected"
- " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
-
- ret = sq905c_command(gspca_dev, SQ905C_GET_ID, 0);
- if (ret < 0) {
- PDEBUG(D_ERR, "Get version command failed");
- return ret;
- }
-
- ret = sq905c_read(gspca_dev, 0xf5, 0, 20);
- if (ret < 0) {
- PDEBUG(D_ERR, "Reading version command failed");
- return ret;
- }
- /* Note we leave out the usb id and the manufacturing date */
- PDEBUG(D_PROBE,
- "SQ9050 ID string: %02x - %02x %02x %02x %02x %02x %02x",
- gspca_dev->usb_buf[3],
- gspca_dev->usb_buf[14], gspca_dev->usb_buf[15],
- gspca_dev->usb_buf[16], gspca_dev->usb_buf[17],
- gspca_dev->usb_buf[18], gspca_dev->usb_buf[19]);
-
- cam->cam_mode = sq905c_mode;
- cam->nmodes = 2;
- if (gspca_dev->usb_buf[15] == 0)
- cam->nmodes = 1;
- /* We don't use the buffer gspca allocates so make it small. */
- cam->bulk_size = 32;
- cam->bulk = 1;
- INIT_WORK(&dev->work_struct, sq905c_dostream);
- return 0;
-}
-
-/* called on streamoff with alt==0 and on disconnect */
-/* the usb_lock is held at entry - restore on exit */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *dev = (struct sd *) gspca_dev;
-
- /* wait for the work queue to terminate */
- mutex_unlock(&gspca_dev->usb_lock);
- /* This waits for sq905c_dostream to finish */
- destroy_workqueue(dev->work_thread);
- dev->work_thread = NULL;
- mutex_lock(&gspca_dev->usb_lock);
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- int ret;
-
- /* connect to the camera and reset it. */
- ret = sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
- return ret;
-}
-
-/* Set up for getting frames. */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *dev = (struct sd *) gspca_dev;
- int ret;
-
- dev->cap_mode = gspca_dev->cam.cam_mode;
- /* "Open the shutter" and set size, to start capture */
- switch (gspca_dev->width) {
- case 640:
- PDEBUG(D_STREAM, "Start streaming at high resolution");
- dev->cap_mode++;
- ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_HI,
- SQ905C_CAPTURE_INDEX);
- break;
- default: /* 320 */
- PDEBUG(D_STREAM, "Start streaming at medium resolution");
- ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_MED,
- SQ905C_CAPTURE_INDEX);
- }
-
- if (ret < 0) {
- PDEBUG(D_ERR, "Start streaming command failed");
- return ret;
- }
- /* Start the workqueue function to do the streaming */
- dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
- queue_work(dev->work_thread, &dev->work_struct);
-
- return 0;
-}
-
-/* Table of supported USB devices */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x2770, 0x905c)},
- {USB_DEVICE(0x2770, 0x9050)},
- {USB_DEVICE(0x2770, 0x9051)},
- {USB_DEVICE(0x2770, 0x9052)},
- {USB_DEVICE(0x2770, 0x913d)},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .start = sd_start,
- .stop0 = sd_stop0,
-};
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id,
- &sd_desc,
- sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/sq930x.c b/drivers/media/video/gspca/sq930x.c
deleted file mode 100644
index 3e1e486af88..00000000000
--- a/drivers/media/video/gspca/sq930x.c
+++ /dev/null
@@ -1,1172 +0,0 @@
-/*
- * SQ930x subdriver
- *
- * Copyright (C) 2010 Jean-François Moine <http://moinejf.free.fr>
- * Copyright (C) 2006 -2008 Gerard Klaver <gerard at gkall dot hobby dot nl>
- * Copyright (C) 2007 Sam Revitch <samr7@cs.washington.edu>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "sq930x"
-
-#include "gspca.h"
-
-MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>\n"
- "Gerard Klaver <gerard at gkall dot hobby dot nl\n"
- "Sam Revitch <samr7@cs.washington.edu>");
-MODULE_DESCRIPTION("GSPCA/SQ930x USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* Structure to hold all of our device specific stuff */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- struct { /* exposure/gain control cluster */
- struct v4l2_ctrl *exposure;
- struct v4l2_ctrl *gain;
- };
-
- u8 do_ctrl;
- u8 gpio[2];
- u8 sensor;
- u8 type;
-#define Generic 0
-#define Creative_live_motion 1
-};
-enum sensors {
- SENSOR_ICX098BQ,
- SENSOR_LZ24BP,
- SENSOR_MI0360,
- SENSOR_MT9V111, /* = MI360SOC */
- SENSOR_OV7660,
- SENSOR_OV9630,
-};
-
-static struct v4l2_pix_format vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
- {640, 480, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
-};
-
-/* sq930x registers */
-#define SQ930_CTRL_UCBUS_IO 0x0001
-#define SQ930_CTRL_I2C_IO 0x0002
-#define SQ930_CTRL_GPIO 0x0005
-#define SQ930_CTRL_CAP_START 0x0010
-#define SQ930_CTRL_CAP_STOP 0x0011
-#define SQ930_CTRL_SET_EXPOSURE 0x001d
-#define SQ930_CTRL_RESET 0x001e
-#define SQ930_CTRL_GET_DEV_INFO 0x001f
-
-/* gpio 1 (8..15) */
-#define SQ930_GPIO_DFL_I2C_SDA 0x0001
-#define SQ930_GPIO_DFL_I2C_SCL 0x0002
-#define SQ930_GPIO_RSTBAR 0x0004
-#define SQ930_GPIO_EXTRA1 0x0040
-#define SQ930_GPIO_EXTRA2 0x0080
-/* gpio 3 (24..31) */
-#define SQ930_GPIO_POWER 0x0200
-#define SQ930_GPIO_DFL_LED 0x1000
-
-struct ucbus_write_cmd {
- u16 bw_addr;
- u8 bw_data;
-};
-struct i2c_write_cmd {
- u8 reg;
- u16 val;
-};
-
-static const struct ucbus_write_cmd icx098bq_start_0[] = {
- {0x0354, 0x00}, {0x03fa, 0x00}, {0xf800, 0x02}, {0xf801, 0xce},
- {0xf802, 0xc1}, {0xf804, 0x00}, {0xf808, 0x00}, {0xf809, 0x0e},
- {0xf80a, 0x01}, {0xf80b, 0xee}, {0xf807, 0x60}, {0xf80c, 0x02},
- {0xf80d, 0xf0}, {0xf80e, 0x03}, {0xf80f, 0x0a}, {0xf81c, 0x02},
- {0xf81d, 0xf0}, {0xf81e, 0x03}, {0xf81f, 0x0a}, {0xf83a, 0x00},
- {0xf83b, 0x10}, {0xf83c, 0x00}, {0xf83d, 0x4e}, {0xf810, 0x04},
- {0xf811, 0x00}, {0xf812, 0x02}, {0xf813, 0x10}, {0xf803, 0x00},
- {0xf814, 0x01}, {0xf815, 0x18}, {0xf816, 0x00}, {0xf817, 0x48},
- {0xf818, 0x00}, {0xf819, 0x25}, {0xf81a, 0x00}, {0xf81b, 0x3c},
- {0xf82f, 0x03}, {0xf820, 0xff}, {0xf821, 0x0d}, {0xf822, 0xff},
- {0xf823, 0x07}, {0xf824, 0xff}, {0xf825, 0x03}, {0xf826, 0xff},
- {0xf827, 0x06}, {0xf828, 0xff}, {0xf829, 0x03}, {0xf82a, 0xff},
- {0xf82b, 0x0c}, {0xf82c, 0xfd}, {0xf82d, 0x01}, {0xf82e, 0x00},
- {0xf830, 0x00}, {0xf831, 0x47}, {0xf832, 0x00}, {0xf833, 0x00},
- {0xf850, 0x00}, {0xf851, 0x00}, {0xf852, 0x00}, {0xf853, 0x24},
- {0xf854, 0x00}, {0xf855, 0x18}, {0xf856, 0x00}, {0xf857, 0x3c},
- {0xf858, 0x00}, {0xf859, 0x0c}, {0xf85a, 0x00}, {0xf85b, 0x30},
- {0xf85c, 0x00}, {0xf85d, 0x0c}, {0xf85e, 0x00}, {0xf85f, 0x30},
- {0xf860, 0x00}, {0xf861, 0x48}, {0xf862, 0x01}, {0xf863, 0xdc},
- {0xf864, 0xff}, {0xf865, 0x98}, {0xf866, 0xff}, {0xf867, 0xc0},
- {0xf868, 0xff}, {0xf869, 0x70}, {0xf86c, 0xff}, {0xf86d, 0x00},
- {0xf86a, 0xff}, {0xf86b, 0x48}, {0xf86e, 0xff}, {0xf86f, 0x00},
- {0xf870, 0x01}, {0xf871, 0xdb}, {0xf872, 0x01}, {0xf873, 0xfa},
- {0xf874, 0x01}, {0xf875, 0xdb}, {0xf876, 0x01}, {0xf877, 0xfa},
- {0xf878, 0x0f}, {0xf879, 0x0f}, {0xf87a, 0xff}, {0xf87b, 0xff},
- {0xf800, 0x03}
-};
-static const struct ucbus_write_cmd icx098bq_start_1[] = {
- {0xf5f0, 0x00}, {0xf5f1, 0xcd}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
- {0xf5f4, 0xc0},
- {0xf5f0, 0x49}, {0xf5f1, 0xcd}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
- {0xf5f4, 0xc0},
- {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
- {0xf5f9, 0x00}
-};
-
-static const struct ucbus_write_cmd icx098bq_start_2[] = {
- {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x82}, {0xf806, 0x00},
- {0xf807, 0x7f}, {0xf800, 0x03},
- {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x40}, {0xf806, 0x00},
- {0xf807, 0x7f}, {0xf800, 0x03},
- {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0xcf}, {0xf806, 0xd0},
- {0xf807, 0x7f}, {0xf800, 0x03},
- {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x00}, {0xf806, 0x00},
- {0xf807, 0x7f}, {0xf800, 0x03}
-};
-
-static const struct ucbus_write_cmd lz24bp_start_0[] = {
- {0x0354, 0x00}, {0x03fa, 0x00}, {0xf800, 0x02}, {0xf801, 0xbe},
- {0xf802, 0xc6}, {0xf804, 0x00}, {0xf808, 0x00}, {0xf809, 0x06},
- {0xf80a, 0x01}, {0xf80b, 0xfe}, {0xf807, 0x84}, {0xf80c, 0x02},
- {0xf80d, 0xf7}, {0xf80e, 0x03}, {0xf80f, 0x0b}, {0xf81c, 0x00},
- {0xf81d, 0x49}, {0xf81e, 0x03}, {0xf81f, 0x0b}, {0xf83a, 0x00},
- {0xf83b, 0x01}, {0xf83c, 0x00}, {0xf83d, 0x6b}, {0xf810, 0x03},
- {0xf811, 0x10}, {0xf812, 0x02}, {0xf813, 0x6f}, {0xf803, 0x00},
- {0xf814, 0x00}, {0xf815, 0x44}, {0xf816, 0x00}, {0xf817, 0x48},
- {0xf818, 0x00}, {0xf819, 0x25}, {0xf81a, 0x00}, {0xf81b, 0x3c},
- {0xf82f, 0x03}, {0xf820, 0xff}, {0xf821, 0x0d}, {0xf822, 0xff},
- {0xf823, 0x07}, {0xf824, 0xfd}, {0xf825, 0x07}, {0xf826, 0xf0},
- {0xf827, 0x0c}, {0xf828, 0xff}, {0xf829, 0x03}, {0xf82a, 0xff},
- {0xf82b, 0x0c}, {0xf82c, 0xfc}, {0xf82d, 0x01}, {0xf82e, 0x00},
- {0xf830, 0x00}, {0xf831, 0x47}, {0xf832, 0x00}, {0xf833, 0x00},
- {0xf850, 0x00}, {0xf851, 0x00}, {0xf852, 0x00}, {0xf853, 0x24},
- {0xf854, 0x00}, {0xf855, 0x0c}, {0xf856, 0x00}, {0xf857, 0x30},
- {0xf858, 0x00}, {0xf859, 0x18}, {0xf85a, 0x00}, {0xf85b, 0x3c},
- {0xf85c, 0x00}, {0xf85d, 0x18}, {0xf85e, 0x00}, {0xf85f, 0x3c},
- {0xf860, 0xff}, {0xf861, 0x37}, {0xf862, 0xff}, {0xf863, 0x1d},
- {0xf864, 0xff}, {0xf865, 0x98}, {0xf866, 0xff}, {0xf867, 0xc0},
- {0xf868, 0x00}, {0xf869, 0x37}, {0xf86c, 0x02}, {0xf86d, 0x1d},
- {0xf86a, 0x00}, {0xf86b, 0x37}, {0xf86e, 0x02}, {0xf86f, 0x1d},
- {0xf870, 0x01}, {0xf871, 0xc6}, {0xf872, 0x02}, {0xf873, 0x04},
- {0xf874, 0x01}, {0xf875, 0xc6}, {0xf876, 0x02}, {0xf877, 0x04},
- {0xf878, 0x0f}, {0xf879, 0x0f}, {0xf87a, 0xff}, {0xf87b, 0xff},
- {0xf800, 0x03}
-};
-static const struct ucbus_write_cmd lz24bp_start_1_gen[] = {
- {0xf5f0, 0x00}, {0xf5f1, 0xff}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
- {0xf5f4, 0xb3},
- {0xf5f0, 0x40}, {0xf5f1, 0xff}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
- {0xf5f4, 0xb3},
- {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
- {0xf5f9, 0x00}
-};
-
-static const struct ucbus_write_cmd lz24bp_start_1_clm[] = {
- {0xf5f0, 0x00}, {0xf5f1, 0xff}, {0xf5f2, 0x88}, {0xf5f3, 0x88},
- {0xf5f4, 0xc0},
- {0xf5f0, 0x40}, {0xf5f1, 0xff}, {0xf5f2, 0x88}, {0xf5f3, 0x88},
- {0xf5f4, 0xc0},
- {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
- {0xf5f9, 0x00}
-};
-
-static const struct ucbus_write_cmd lz24bp_start_2[] = {
- {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x80}, {0xf806, 0x00},
- {0xf807, 0x7f}, {0xf800, 0x03},
- {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x4e}, {0xf806, 0x00},
- {0xf807, 0x7f}, {0xf800, 0x03},
- {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0xc0}, {0xf806, 0x48},
- {0xf807, 0x7f}, {0xf800, 0x03},
- {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x00}, {0xf806, 0x00},
- {0xf807, 0x7f}, {0xf800, 0x03}
-};
-
-static const struct ucbus_write_cmd mi0360_start_0[] = {
- {0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0xcc}, {0xf333, 0xcc},
- {0xf334, 0xcc}, {0xf335, 0xcc}, {0xf33f, 0x00}
-};
-static const struct i2c_write_cmd mi0360_init_23[] = {
- {0x30, 0x0040}, /* reserved - def 0x0005 */
- {0x31, 0x0000}, /* reserved - def 0x002a */
- {0x34, 0x0100}, /* reserved - def 0x0100 */
- {0x3d, 0x068f}, /* reserved - def 0x068f */
-};
-static const struct i2c_write_cmd mi0360_init_24[] = {
- {0x03, 0x01e5}, /* window height */
- {0x04, 0x0285}, /* window width */
-};
-static const struct i2c_write_cmd mi0360_init_25[] = {
- {0x35, 0x0020}, /* global gain */
- {0x2b, 0x0020}, /* green1 gain */
- {0x2c, 0x002a}, /* blue gain */
- {0x2d, 0x0028}, /* red gain */
- {0x2e, 0x0020}, /* green2 gain */
-};
-static const struct ucbus_write_cmd mi0360_start_1[] = {
- {0xf5f0, 0x11}, {0xf5f1, 0x99}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
- {0xf5f4, 0xa6},
- {0xf5f0, 0x51}, {0xf5f1, 0x99}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
- {0xf5f4, 0xa6},
- {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
- {0xf5f9, 0x00}
-};
-static const struct i2c_write_cmd mi0360_start_2[] = {
- {0x62, 0x041d}, /* reserved - def 0x0418 */
-};
-static const struct i2c_write_cmd mi0360_start_3[] = {
- {0x05, 0x007b}, /* horiz blanking */
-};
-static const struct i2c_write_cmd mi0360_start_4[] = {
- {0x05, 0x03f5}, /* horiz blanking */
-};
-
-static const struct i2c_write_cmd mt9v111_init_0[] = {
- {0x01, 0x0001}, /* select IFP/SOC registers */
- {0x06, 0x300c}, /* operating mode control */
- {0x08, 0xcc00}, /* output format control (RGB) */
- {0x01, 0x0004}, /* select sensor core registers */
-};
-static const struct i2c_write_cmd mt9v111_init_1[] = {
- {0x03, 0x01e5}, /* window height */
- {0x04, 0x0285}, /* window width */
-};
-static const struct i2c_write_cmd mt9v111_init_2[] = {
- {0x30, 0x7800},
- {0x31, 0x0000},
- {0x07, 0x3002}, /* output control */
- {0x35, 0x0020}, /* global gain */
- {0x2b, 0x0020}, /* green1 gain */
- {0x2c, 0x0020}, /* blue gain */
- {0x2d, 0x0020}, /* red gain */
- {0x2e, 0x0020}, /* green2 gain */
-};
-static const struct ucbus_write_cmd mt9v111_start_1[] = {
- {0xf5f0, 0x11}, {0xf5f1, 0x96}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
- {0xf5f4, 0xaa},
- {0xf5f0, 0x51}, {0xf5f1, 0x96}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
- {0xf5f4, 0xaa},
- {0xf5fa, 0x00}, {0xf5f6, 0x0a}, {0xf5f7, 0x0a}, {0xf5f8, 0x0a},
- {0xf5f9, 0x0a}
-};
-static const struct i2c_write_cmd mt9v111_init_3[] = {
- {0x62, 0x0405},
-};
-static const struct i2c_write_cmd mt9v111_init_4[] = {
-/* {0x05, 0x00ce}, */
- {0x05, 0x005d}, /* horizontal blanking */
-};
-
-static const struct ucbus_write_cmd ov7660_start_0[] = {
- {0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0x00}, {0xf333, 0xc0},
- {0xf334, 0x39}, {0xf335, 0xe7}, {0xf33f, 0x03}
-};
-
-static const struct ucbus_write_cmd ov9630_start_0[] = {
- {0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0x00}, {0xf333, 0x00},
- {0xf334, 0x3e}, {0xf335, 0xf8}, {0xf33f, 0x03}
-};
-
-/* start parameters indexed by [sensor][mode] */
-static const struct cap_s {
- u8 cc_sizeid;
- u8 cc_bytes[32];
-} capconfig[4][2] = {
- [SENSOR_ICX098BQ] = {
- {2, /* Bayer 320x240 */
- {0x05, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
- 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
- {4, /* Bayer 640x480 */
- {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
- 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
- },
- [SENSOR_LZ24BP] = {
- {2, /* Bayer 320x240 */
- {0x05, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee,
- 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
- {4, /* Bayer 640x480 */
- {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee,
- 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
- },
- [SENSOR_MI0360] = {
- {2, /* Bayer 320x240 */
- {0x05, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
- 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
- {4, /* Bayer 640x480 */
- {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
- 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
- },
- [SENSOR_MT9V111] = {
- {2, /* Bayer 320x240 */
- {0x05, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
- 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
- {4, /* Bayer 640x480 */
- {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
- 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
- },
-};
-
-struct sensor_s {
- const char *name;
- u8 i2c_addr;
- u8 i2c_dum;
- u8 gpio[5];
- u8 cmd_len;
- const struct ucbus_write_cmd *cmd;
-};
-
-static const struct sensor_s sensor_tb[] = {
- [SENSOR_ICX098BQ] = {
- "icx098bp",
- 0x00, 0x00,
- {0,
- SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
- SQ930_GPIO_DFL_I2C_SDA,
- 0,
- SQ930_GPIO_RSTBAR
- },
- 8, icx098bq_start_0
- },
- [SENSOR_LZ24BP] = {
- "lz24bp",
- 0x00, 0x00,
- {0,
- SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
- SQ930_GPIO_DFL_I2C_SDA,
- 0,
- SQ930_GPIO_RSTBAR
- },
- 8, lz24bp_start_0
- },
- [SENSOR_MI0360] = {
- "mi0360",
- 0x5d, 0x80,
- {SQ930_GPIO_RSTBAR,
- SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
- SQ930_GPIO_DFL_I2C_SDA,
- 0,
- 0
- },
- 7, mi0360_start_0
- },
- [SENSOR_MT9V111] = {
- "mt9v111",
- 0x5c, 0x7f,
- {SQ930_GPIO_RSTBAR,
- SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
- SQ930_GPIO_DFL_I2C_SDA,
- 0,
- 0
- },
- 7, mi0360_start_0
- },
- [SENSOR_OV7660] = {
- "ov7660",
- 0x21, 0x00,
- {0,
- SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
- SQ930_GPIO_DFL_I2C_SDA,
- 0,
- SQ930_GPIO_RSTBAR
- },
- 7, ov7660_start_0
- },
- [SENSOR_OV9630] = {
- "ov9630",
- 0x30, 0x00,
- {0,
- SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
- SQ930_GPIO_DFL_I2C_SDA,
- 0,
- SQ930_GPIO_RSTBAR
- },
- 7, ov9630_start_0
- },
-};
-
-static void reg_r(struct gspca_dev *gspca_dev,
- u16 value, int len)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- 0x0c,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, 0, gspca_dev->usb_buf, len,
- 500);
- if (ret < 0) {
- pr_err("reg_r %04x failed %d\n", value, ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- PDEBUG(D_USBO, "reg_w v: %04x i: %04x", value, index);
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x0c, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, NULL, 0,
- 500);
- msleep(30);
- if (ret < 0) {
- pr_err("reg_w %04x %04x failed %d\n", value, index, ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void reg_wb(struct gspca_dev *gspca_dev, u16 value, u16 index,
- const u8 *data, int len)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- PDEBUG(D_USBO, "reg_wb v: %04x i: %04x %02x...%02x",
- value, index, *data, data[len - 1]);
- memcpy(gspca_dev->usb_buf, data, len);
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x0c, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, gspca_dev->usb_buf, len,
- 1000);
- msleep(30);
- if (ret < 0) {
- pr_err("reg_wb %04x %04x failed %d\n", value, index, ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void i2c_write(struct sd *sd,
- const struct i2c_write_cmd *cmd,
- int ncmds)
-{
- struct gspca_dev *gspca_dev = &sd->gspca_dev;
- const struct sensor_s *sensor;
- u16 val, idx;
- u8 *buf;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
-
- sensor = &sensor_tb[sd->sensor];
-
- val = (sensor->i2c_addr << 8) | SQ930_CTRL_I2C_IO;
- idx = (cmd->val & 0xff00) | cmd->reg;
-
- buf = gspca_dev->usb_buf;
- *buf++ = sensor->i2c_dum;
- *buf++ = cmd->val;
-
- while (--ncmds > 0) {
- cmd++;
- *buf++ = cmd->reg;
- *buf++ = cmd->val >> 8;
- *buf++ = sensor->i2c_dum;
- *buf++ = cmd->val;
- }
-
- PDEBUG(D_USBO, "i2c_w v: %04x i: %04x %02x...%02x",
- val, idx, gspca_dev->usb_buf[0], buf[-1]);
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x0c, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- val, idx,
- gspca_dev->usb_buf, buf - gspca_dev->usb_buf,
- 500);
- if (ret < 0) {
- pr_err("i2c_write failed %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void ucbus_write(struct gspca_dev *gspca_dev,
- const struct ucbus_write_cmd *cmd,
- int ncmds,
- int batchsize)
-{
- u8 *buf;
- u16 val, idx;
- int len, ret;
-
- if (gspca_dev->usb_err < 0)
- return;
-
-#ifdef GSPCA_DEBUG
- if ((batchsize - 1) * 3 > USB_BUF_SZ) {
- pr_err("Bug: usb_buf overflow\n");
- gspca_dev->usb_err = -ENOMEM;
- return;
- }
-#endif
-
- for (;;) {
- len = ncmds;
- if (len > batchsize)
- len = batchsize;
- ncmds -= len;
-
- val = (cmd->bw_addr << 8) | SQ930_CTRL_UCBUS_IO;
- idx = (cmd->bw_data << 8) | (cmd->bw_addr >> 8);
-
- buf = gspca_dev->usb_buf;
- while (--len > 0) {
- cmd++;
- *buf++ = cmd->bw_addr;
- *buf++ = cmd->bw_addr >> 8;
- *buf++ = cmd->bw_data;
- }
- if (buf != gspca_dev->usb_buf)
- PDEBUG(D_USBO, "ucbus v: %04x i: %04x %02x...%02x",
- val, idx,
- gspca_dev->usb_buf[0], buf[-1]);
- else
- PDEBUG(D_USBO, "ucbus v: %04x i: %04x",
- val, idx);
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x0c, /* request */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- val, idx,
- gspca_dev->usb_buf, buf - gspca_dev->usb_buf,
- 500);
- if (ret < 0) {
- pr_err("ucbus_write failed %d\n", ret);
- gspca_dev->usb_err = ret;
- return;
- }
- msleep(30);
- if (ncmds <= 0)
- break;
- cmd++;
- }
-}
-
-static void gpio_set(struct sd *sd, u16 val, u16 mask)
-{
- struct gspca_dev *gspca_dev = &sd->gspca_dev;
-
- if (mask & 0x00ff) {
- sd->gpio[0] &= ~mask;
- sd->gpio[0] |= val;
- reg_w(gspca_dev, 0x0100 | SQ930_CTRL_GPIO,
- ~sd->gpio[0] << 8);
- }
- mask >>= 8;
- val >>= 8;
- if (mask) {
- sd->gpio[1] &= ~mask;
- sd->gpio[1] |= val;
- reg_w(gspca_dev, 0x0300 | SQ930_CTRL_GPIO,
- ~sd->gpio[1] << 8);
- }
-}
-
-static void gpio_init(struct sd *sd,
- const u8 *gpio)
-{
- gpio_set(sd, *gpio++, 0x000f);
- gpio_set(sd, *gpio++, 0x000f);
- gpio_set(sd, *gpio++, 0x000f);
- gpio_set(sd, *gpio++, 0x000f);
- gpio_set(sd, *gpio, 0x000f);
-}
-
-static void bridge_init(struct sd *sd)
-{
- static const struct ucbus_write_cmd clkfreq_cmd = {
- 0xf031, 0 /* SQ930_CLKFREQ_60MHZ */
- };
-
- ucbus_write(&sd->gspca_dev, &clkfreq_cmd, 1, 1);
-
- gpio_set(sd, SQ930_GPIO_POWER, 0xff00);
-}
-
-static void cmos_probe(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- const struct sensor_s *sensor;
- static const u8 probe_order[] = {
-/* SENSOR_LZ24BP, (tested as ccd) */
- SENSOR_OV9630,
- SENSOR_MI0360,
- SENSOR_OV7660,
- SENSOR_MT9V111,
- };
-
- for (i = 0; i < ARRAY_SIZE(probe_order); i++) {
- sensor = &sensor_tb[probe_order[i]];
- ucbus_write(&sd->gspca_dev, sensor->cmd, sensor->cmd_len, 8);
- gpio_init(sd, sensor->gpio);
- msleep(100);
- reg_r(gspca_dev, (sensor->i2c_addr << 8) | 0x001c, 1);
- msleep(100);
- if (gspca_dev->usb_buf[0] != 0)
- break;
- }
- if (i >= ARRAY_SIZE(probe_order)) {
- pr_err("Unknown sensor\n");
- gspca_dev->usb_err = -EINVAL;
- return;
- }
- sd->sensor = probe_order[i];
- switch (sd->sensor) {
- case SENSOR_OV7660:
- case SENSOR_OV9630:
- pr_err("Sensor %s not yet treated\n",
- sensor_tb[sd->sensor].name);
- gspca_dev->usb_err = -EINVAL;
- break;
- }
-}
-
-static void mt9v111_init(struct gspca_dev *gspca_dev)
-{
- int i, nwait;
- static const u8 cmd_001b[] = {
- 0x00, 0x3b, 0xf6, 0x01, 0x03, 0x02, 0x00, 0x00,
- 0x00, 0x00, 0x00
- };
- static const u8 cmd_011b[][7] = {
- {0x10, 0x01, 0x66, 0x08, 0x00, 0x00, 0x00},
- {0x01, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x00},
- {0x20, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00},
- {0x02, 0x01, 0xae, 0x01, 0x00, 0x00, 0x00},
- };
-
- reg_wb(gspca_dev, 0x001b, 0x0000, cmd_001b, sizeof cmd_001b);
- for (i = 0; i < ARRAY_SIZE(cmd_011b); i++) {
- reg_wb(gspca_dev, 0x001b, 0x0000, cmd_011b[i],
- ARRAY_SIZE(cmd_011b[0]));
- msleep(400);
- nwait = 20;
- for (;;) {
- reg_r(gspca_dev, 0x031b, 1);
- if (gspca_dev->usb_buf[0] == 0
- || gspca_dev->usb_err != 0)
- break;
- if (--nwait < 0) {
- PDEBUG(D_PROBE, "mt9v111_init timeout");
- gspca_dev->usb_err = -ETIME;
- return;
- }
- msleep(50);
- }
- }
-}
-
-static void global_init(struct sd *sd, int first_time)
-{
- switch (sd->sensor) {
- case SENSOR_ICX098BQ:
- if (first_time)
- ucbus_write(&sd->gspca_dev,
- icx098bq_start_0,
- 8, 8);
- gpio_init(sd, sensor_tb[sd->sensor].gpio);
- break;
- case SENSOR_LZ24BP:
- if (sd->type != Creative_live_motion)
- gpio_set(sd, SQ930_GPIO_EXTRA1, 0x00ff);
- else
- gpio_set(sd, 0, 0x00ff);
- msleep(50);
- if (first_time)
- ucbus_write(&sd->gspca_dev,
- lz24bp_start_0,
- 8, 8);
- gpio_init(sd, sensor_tb[sd->sensor].gpio);
- break;
- case SENSOR_MI0360:
- if (first_time)
- ucbus_write(&sd->gspca_dev,
- mi0360_start_0,
- ARRAY_SIZE(mi0360_start_0),
- 8);
- gpio_init(sd, sensor_tb[sd->sensor].gpio);
- gpio_set(sd, SQ930_GPIO_EXTRA2, SQ930_GPIO_EXTRA2);
- break;
- default:
-/* case SENSOR_MT9V111: */
- if (first_time)
- mt9v111_init(&sd->gspca_dev);
- else
- gpio_init(sd, sensor_tb[sd->sensor].gpio);
- break;
- }
-}
-
-static void lz24bp_ppl(struct sd *sd, u16 ppl)
-{
- struct ucbus_write_cmd cmds[2] = {
- {0xf810, ppl >> 8},
- {0xf811, ppl}
- };
-
- ucbus_write(&sd->gspca_dev, cmds, ARRAY_SIZE(cmds), 2);
-}
-
-static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 gain)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i, integclks, intstartclk, frameclks, min_frclk;
- const struct sensor_s *sensor;
- u16 cmd;
- u8 buf[15];
-
- integclks = expo;
- i = 0;
- cmd = SQ930_CTRL_SET_EXPOSURE;
-
- switch (sd->sensor) {
- case SENSOR_ICX098BQ: /* ccd */
- case SENSOR_LZ24BP:
- min_frclk = sd->sensor == SENSOR_ICX098BQ ? 0x210 : 0x26f;
- if (integclks >= min_frclk) {
- intstartclk = 0;
- frameclks = integclks;
- } else {
- intstartclk = min_frclk - integclks;
- frameclks = min_frclk;
- }
- buf[i++] = intstartclk >> 8;
- buf[i++] = intstartclk;
- buf[i++] = frameclks >> 8;
- buf[i++] = frameclks;
- buf[i++] = gain;
- break;
- default: /* cmos */
-/* case SENSOR_MI0360: */
-/* case SENSOR_MT9V111: */
- cmd |= 0x0100;
- sensor = &sensor_tb[sd->sensor];
- buf[i++] = sensor->i2c_addr; /* i2c_slave_addr */
- buf[i++] = 0x08; /* 2 * ni2c */
- buf[i++] = 0x09; /* reg = shutter width */
- buf[i++] = integclks >> 8; /* val H */
- buf[i++] = sensor->i2c_dum;
- buf[i++] = integclks; /* val L */
- buf[i++] = 0x35; /* reg = global gain */
- buf[i++] = 0x00; /* val H */
- buf[i++] = sensor->i2c_dum;
- buf[i++] = 0x80 + gain / 2; /* val L */
- buf[i++] = 0x00;
- buf[i++] = 0x00;
- buf[i++] = 0x00;
- buf[i++] = 0x00;
- buf[i++] = 0x83;
- break;
- }
- reg_wb(gspca_dev, cmd, 0, buf, i);
-}
-
-/* This function is called at probe time just before sd_init */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam = &gspca_dev->cam;
-
- sd->sensor = id->driver_info >> 8;
- sd->type = id->driver_info;
-
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
-
- cam->bulk = 1;
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->gpio[0] = sd->gpio[1] = 0xff; /* force gpio rewrite */
-
-/*fixme: is this needed for icx098bp and mi0360?
- if (sd->sensor != SENSOR_LZ24BP)
- reg_w(gspca_dev, SQ930_CTRL_RESET, 0x0000);
- */
-
- reg_r(gspca_dev, SQ930_CTRL_GET_DEV_INFO, 8);
- if (gspca_dev->usb_err < 0)
- return gspca_dev->usb_err;
-
-/* it returns:
- * 03 00 12 93 0b f6 c9 00 live! ultra
- * 03 00 07 93 0b f6 ca 00 live! ultra for notebook
- * 03 00 12 93 0b fe c8 00 Trust WB-3500T
- * 02 00 06 93 0b fe c8 00 Joy-IT 318S
- * 03 00 12 93 0b f6 cf 00 icam tracer - sensor icx098bq
- * 02 00 12 93 0b fe cf 00 ProQ Motion Webcam
- *
- * byte
- * 0: 02 = usb 1.0 (12Mbit) / 03 = usb2.0 (480Mbit)
- * 1: 00
- * 2: 06 / 07 / 12 = mode webcam? firmware??
- * 3: 93 chip = 930b (930b or 930c)
- * 4: 0b
- * 5: f6 = cdd (icx098bq, lz24bp) / fe or de = cmos (i2c) (other sensors)
- * 6: c8 / c9 / ca / cf = mode webcam?, sensor? webcam?
- * 7: 00
- */
- PDEBUG(D_PROBE, "info: %02x %02x %02x %02x %02x %02x %02x %02x",
- gspca_dev->usb_buf[0],
- gspca_dev->usb_buf[1],
- gspca_dev->usb_buf[2],
- gspca_dev->usb_buf[3],
- gspca_dev->usb_buf[4],
- gspca_dev->usb_buf[5],
- gspca_dev->usb_buf[6],
- gspca_dev->usb_buf[7]);
-
- bridge_init(sd);
-
- if (sd->sensor == SENSOR_MI0360) {
-
- /* no sensor probe for icam tracer */
- if (gspca_dev->usb_buf[5] == 0xf6) /* if ccd */
- sd->sensor = SENSOR_ICX098BQ;
- else
- cmos_probe(gspca_dev);
- }
- if (gspca_dev->usb_err >= 0) {
- PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name);
- global_init(sd, 1);
- }
- return gspca_dev->usb_err;
-}
-
-/* send the start/stop commands to the webcam */
-static void send_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- const struct cap_s *cap;
- int mode;
-
- mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
- cap = &capconfig[sd->sensor][mode];
- reg_wb(gspca_dev, 0x0900 | SQ930_CTRL_CAP_START,
- 0x0a00 | cap->cc_sizeid,
- cap->cc_bytes, 32);
-}
-
-static void send_stop(struct gspca_dev *gspca_dev)
-{
- reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0);
-}
-
-/* function called at start time before URB creation */
-static int sd_isoc_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- gspca_dev->cam.bulk_nurbs = 1; /* there must be one URB only */
- sd->do_ctrl = 0;
- gspca_dev->cam.bulk_size = gspca_dev->width * gspca_dev->height + 8;
- return 0;
-}
-
-/* start the capture */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int mode;
-
- bridge_init(sd);
- global_init(sd, 0);
- msleep(100);
-
- switch (sd->sensor) {
- case SENSOR_ICX098BQ:
- ucbus_write(gspca_dev, icx098bq_start_0,
- ARRAY_SIZE(icx098bq_start_0),
- 8);
- ucbus_write(gspca_dev, icx098bq_start_1,
- ARRAY_SIZE(icx098bq_start_1),
- 5);
- ucbus_write(gspca_dev, icx098bq_start_2,
- ARRAY_SIZE(icx098bq_start_2),
- 6);
- msleep(50);
-
- /* 1st start */
- send_start(gspca_dev);
- gpio_set(sd, SQ930_GPIO_EXTRA2 | SQ930_GPIO_RSTBAR, 0x00ff);
- msleep(70);
- reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0x0000);
- gpio_set(sd, 0x7f, 0x00ff);
-
- /* 2nd start */
- send_start(gspca_dev);
- gpio_set(sd, SQ930_GPIO_EXTRA2 | SQ930_GPIO_RSTBAR, 0x00ff);
- goto out;
- case SENSOR_LZ24BP:
- ucbus_write(gspca_dev, lz24bp_start_0,
- ARRAY_SIZE(lz24bp_start_0),
- 8);
- if (sd->type != Creative_live_motion)
- ucbus_write(gspca_dev, lz24bp_start_1_gen,
- ARRAY_SIZE(lz24bp_start_1_gen),
- 5);
- else
- ucbus_write(gspca_dev, lz24bp_start_1_clm,
- ARRAY_SIZE(lz24bp_start_1_clm),
- 5);
- ucbus_write(gspca_dev, lz24bp_start_2,
- ARRAY_SIZE(lz24bp_start_2),
- 6);
- mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
- lz24bp_ppl(sd, mode == 1 ? 0x0564 : 0x0310);
- msleep(10);
- break;
- case SENSOR_MI0360:
- ucbus_write(gspca_dev, mi0360_start_0,
- ARRAY_SIZE(mi0360_start_0),
- 8);
- i2c_write(sd, mi0360_init_23,
- ARRAY_SIZE(mi0360_init_23));
- i2c_write(sd, mi0360_init_24,
- ARRAY_SIZE(mi0360_init_24));
- i2c_write(sd, mi0360_init_25,
- ARRAY_SIZE(mi0360_init_25));
- ucbus_write(gspca_dev, mi0360_start_1,
- ARRAY_SIZE(mi0360_start_1),
- 5);
- i2c_write(sd, mi0360_start_2,
- ARRAY_SIZE(mi0360_start_2));
- i2c_write(sd, mi0360_start_3,
- ARRAY_SIZE(mi0360_start_3));
-
- /* 1st start */
- send_start(gspca_dev);
- msleep(60);
- send_stop(gspca_dev);
-
- i2c_write(sd,
- mi0360_start_4, ARRAY_SIZE(mi0360_start_4));
- break;
- default:
-/* case SENSOR_MT9V111: */
- ucbus_write(gspca_dev, mi0360_start_0,
- ARRAY_SIZE(mi0360_start_0),
- 8);
- i2c_write(sd, mt9v111_init_0,
- ARRAY_SIZE(mt9v111_init_0));
- i2c_write(sd, mt9v111_init_1,
- ARRAY_SIZE(mt9v111_init_1));
- i2c_write(sd, mt9v111_init_2,
- ARRAY_SIZE(mt9v111_init_2));
- ucbus_write(gspca_dev, mt9v111_start_1,
- ARRAY_SIZE(mt9v111_start_1),
- 5);
- i2c_write(sd, mt9v111_init_3,
- ARRAY_SIZE(mt9v111_init_3));
- i2c_write(sd, mt9v111_init_4,
- ARRAY_SIZE(mt9v111_init_4));
- break;
- }
-
- send_start(gspca_dev);
-out:
- msleep(1000);
-
- if (sd->sensor == SENSOR_MT9V111)
- gpio_set(sd, SQ930_GPIO_DFL_LED, SQ930_GPIO_DFL_LED);
-
- sd->do_ctrl = 1; /* set the exposure */
-
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_MT9V111)
- gpio_set(sd, 0, SQ930_GPIO_DFL_LED);
- send_stop(gspca_dev);
-}
-
-/* function called when the application gets a new frame */
-/* It sets the exposure if required and restart the bulk transfer. */
-static void sd_dq_callback(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- if (!sd->do_ctrl || gspca_dev->cam.bulk_nurbs != 0)
- return;
- sd->do_ctrl = 0;
-
- setexposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure),
- v4l2_ctrl_g_ctrl(sd->gain));
-
- gspca_dev->cam.bulk_nurbs = 1;
- ret = usb_submit_urb(gspca_dev->urb[0], GFP_ATOMIC);
- if (ret < 0)
- pr_err("sd_dq_callback() err %d\n", ret);
-
- /* wait a little time, otherwise the webcam crashes */
- msleep(100);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->do_ctrl)
- gspca_dev->cam.bulk_nurbs = 0;
- gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len - 8);
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *) gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- setexposure(gspca_dev, ctrl->val, sd->gain->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
- struct sd *sd = (struct sd *) gspca_dev;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 2);
- sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 1, 0xfff, 1, 0x356);
- sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 1, 255, 1, 0x8d);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- v4l2_ctrl_cluster(2, &sd->exposure);
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .isoc_init = sd_isoc_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
- .dq_callback = sd_dq_callback,
-};
-
-/* Table of supported USB devices */
-#define ST(sensor, type) \
- .driver_info = (SENSOR_ ## sensor << 8) \
- | (type)
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x041e, 0x4038), ST(MI0360, 0)},
- {USB_DEVICE(0x041e, 0x403c), ST(LZ24BP, 0)},
- {USB_DEVICE(0x041e, 0x403d), ST(LZ24BP, 0)},
- {USB_DEVICE(0x041e, 0x4041), ST(LZ24BP, Creative_live_motion)},
- {USB_DEVICE(0x2770, 0x930b), ST(MI0360, 0)},
- {USB_DEVICE(0x2770, 0x930c), ST(MI0360, 0)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
deleted file mode 100644
index 8c0982607f2..00000000000
--- a/drivers/media/video/gspca/stk014.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Syntek DV4000 (STK014) subdriver
- *
- * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "stk014"
-
-#include "gspca.h"
-#include "jpeg.h"
-
-MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
-MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-#define QUALITY 50
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- u8 jpeg_hdr[JPEG_HDR_SZ];
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-
-/* -- read a register -- */
-static u8 reg_r(struct gspca_dev *gspca_dev,
- __u16 index)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return 0;
- ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- 0x00,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x00,
- index,
- gspca_dev->usb_buf, 1,
- 500);
- if (ret < 0) {
- pr_err("reg_r err %d\n", ret);
- gspca_dev->usb_err = ret;
- return 0;
- }
- return gspca_dev->usb_buf[0];
-}
-
-/* -- write a register -- */
-static void reg_w(struct gspca_dev *gspca_dev,
- __u16 index, __u16 value)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x01,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value,
- index,
- NULL,
- 0,
- 500);
- if (ret < 0) {
- pr_err("reg_w err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-/* -- get a bulk value (4 bytes) -- */
-static void rcv_val(struct gspca_dev *gspca_dev,
- int ads)
-{
- struct usb_device *dev = gspca_dev->dev;
- int alen, ret;
-
- reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff);
- reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff);
- reg_w(gspca_dev, 0x636, ads & 0xff);
- reg_w(gspca_dev, 0x637, 0);
- reg_w(gspca_dev, 0x638, 4); /* len & 0xff */
- reg_w(gspca_dev, 0x639, 0); /* len >> 8 */
- reg_w(gspca_dev, 0x63a, 0);
- reg_w(gspca_dev, 0x63b, 0);
- reg_w(gspca_dev, 0x630, 5);
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_bulk_msg(dev,
- usb_rcvbulkpipe(dev, 0x05),
- gspca_dev->usb_buf,
- 4, /* length */
- &alen,
- 500); /* timeout in milliseconds */
- if (ret < 0) {
- pr_err("rcv_val err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-/* -- send a bulk value -- */
-static void snd_val(struct gspca_dev *gspca_dev,
- int ads,
- unsigned int val)
-{
- struct usb_device *dev = gspca_dev->dev;
- int alen, ret;
- __u8 seq = 0;
-
- if (ads == 0x003f08) {
- reg_r(gspca_dev, 0x0704);
- seq = reg_r(gspca_dev, 0x0705);
- reg_r(gspca_dev, 0x0650);
- reg_w(gspca_dev, 0x654, seq);
- } else {
- reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff);
- }
- reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff);
- reg_w(gspca_dev, 0x656, ads & 0xff);
- reg_w(gspca_dev, 0x657, 0);
- reg_w(gspca_dev, 0x658, 0x04); /* size */
- reg_w(gspca_dev, 0x659, 0);
- reg_w(gspca_dev, 0x65a, 0);
- reg_w(gspca_dev, 0x65b, 0);
- reg_w(gspca_dev, 0x650, 5);
- if (gspca_dev->usb_err < 0)
- return;
- gspca_dev->usb_buf[0] = val >> 24;
- gspca_dev->usb_buf[1] = val >> 16;
- gspca_dev->usb_buf[2] = val >> 8;
- gspca_dev->usb_buf[3] = val;
- ret = usb_bulk_msg(dev,
- usb_sndbulkpipe(dev, 6),
- gspca_dev->usb_buf,
- 4,
- &alen,
- 500); /* timeout in milliseconds */
- if (ret < 0) {
- pr_err("snd_val err %d\n", ret);
- gspca_dev->usb_err = ret;
- } else {
- if (ads == 0x003f08) {
- seq += 4;
- seq &= 0x3f;
- reg_w(gspca_dev, 0x705, seq);
- }
- }
-}
-
-/* set a camera parameter */
-static void set_par(struct gspca_dev *gspca_dev,
- int parval)
-{
- snd_val(gspca_dev, 0x003f08, parval);
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
-{
- int parval;
-
- parval = 0x06000000 /* whiteness */
- + (val << 16);
- set_par(gspca_dev, parval);
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
-{
- int parval;
-
- parval = 0x07000000 /* contrast */
- + (val << 16);
- set_par(gspca_dev, parval);
-}
-
-static void setcolors(struct gspca_dev *gspca_dev, s32 val)
-{
- int parval;
-
- parval = 0x08000000 /* saturation */
- + (val << 16);
- set_par(gspca_dev, parval);
-}
-
-static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
-{
- set_par(gspca_dev, val == 1
- ? 0x33640000 /* 50 Hz */
- : 0x33780000); /* 60 Hz */
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- gspca_dev->cam.cam_mode = vga_mode;
- gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- u8 ret;
-
- /* check if the device responds */
- usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
- ret = reg_r(gspca_dev, 0x0740);
- if (gspca_dev->usb_err >= 0) {
- if (ret != 0xff) {
- pr_err("init reg: 0x%02x\n", ret);
- gspca_dev->usb_err = -EIO;
- }
- }
- return gspca_dev->usb_err;
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret, value;
-
- /* create the JPEG header */
- jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
- 0x22); /* JPEG 411 */
- jpeg_set_qual(sd->jpeg_hdr, QUALITY);
-
- /* work on alternate 1 */
- usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
-
- set_par(gspca_dev, 0x10000000);
- set_par(gspca_dev, 0x00000000);
- set_par(gspca_dev, 0x8002e001);
- set_par(gspca_dev, 0x14000000);
- if (gspca_dev->width > 320)
- value = 0x8002e001; /* 640x480 */
- else
- value = 0x4001f000; /* 320x240 */
- set_par(gspca_dev, value);
- ret = usb_set_interface(gspca_dev->dev,
- gspca_dev->iface,
- gspca_dev->alt);
- if (ret < 0) {
- pr_err("set intf %d %d failed\n",
- gspca_dev->iface, gspca_dev->alt);
- gspca_dev->usb_err = ret;
- goto out;
- }
- reg_r(gspca_dev, 0x0630);
- rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */
- reg_r(gspca_dev, 0x0650);
- snd_val(gspca_dev, 0x000020, 0xffffffff);
- reg_w(gspca_dev, 0x0620, 0);
- reg_w(gspca_dev, 0x0630, 0);
- reg_w(gspca_dev, 0x0640, 0);
- reg_w(gspca_dev, 0x0650, 0);
- reg_w(gspca_dev, 0x0660, 0);
- set_par(gspca_dev, 0x09800000); /* Red ? */
- set_par(gspca_dev, 0x0a800000); /* Green ? */
- set_par(gspca_dev, 0x0b800000); /* Blue ? */
- set_par(gspca_dev, 0x0d030000); /* Gamma ? */
-
- /* start the video flow */
- set_par(gspca_dev, 0x01000000);
- set_par(gspca_dev, 0x01000000);
- if (gspca_dev->usb_err >= 0)
- PDEBUG(D_STREAM, "camera started alt: 0x%02x",
- gspca_dev->alt);
-out:
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct usb_device *dev = gspca_dev->dev;
-
- set_par(gspca_dev, 0x02000000);
- set_par(gspca_dev, 0x02000000);
- usb_set_interface(dev, gspca_dev->iface, 1);
- reg_r(gspca_dev, 0x0630);
- rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */
- reg_r(gspca_dev, 0x0650);
- snd_val(gspca_dev, 0x000020, 0xffffffff);
- reg_w(gspca_dev, 0x0620, 0);
- reg_w(gspca_dev, 0x0630, 0);
- reg_w(gspca_dev, 0x0640, 0);
- reg_w(gspca_dev, 0x0650, 0);
- reg_w(gspca_dev, 0x0660, 0);
- PDEBUG(D_STREAM, "camera stopped");
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
- static unsigned char ffd9[] = {0xff, 0xd9};
-
- /* a frame starts with:
- * - 0xff 0xfe
- * - 0x08 0x00 - length (little endian ?!)
- * - 4 bytes = size of whole frame (BE - including header)
- * - 0x00 0x0c
- * - 0xff 0xd8
- * - .. JPEG image with escape sequences (ff 00)
- * (without ending - ff d9)
- */
- if (data[0] == 0xff && data[1] == 0xfe) {
- gspca_frame_add(gspca_dev, LAST_PACKET,
- ffd9, 2);
-
- /* put the JPEG 411 header */
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sd->jpeg_hdr, JPEG_HDR_SZ);
-
- /* beginning of the frame */
-#define STKHDRSZ 12
- data += STKHDRSZ;
- len -= STKHDRSZ;
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- setcolors(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY:
- setlightfreq(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 4);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 127);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, 127);
- v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
- V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
- V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x05e1, 0x0893)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/video/gspca/stv0680.c
deleted file mode 100644
index 67605272aaa..00000000000
--- a/drivers/media/video/gspca/stv0680.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * STV0680 USB Camera Driver
- *
- * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
- *
- * This module is adapted from the in kernel v4l1 stv680 driver:
- *
- * STV0680 USB Camera Driver, by Kevin Sisson (kjsisson@bellsouth.net)
- *
- * Thanks to STMicroelectronics for information on the usb commands, and
- * to Steve Miller at STM for his help and encouragement while I was
- * writing this driver.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "stv0680"
-
-#include "gspca.h"
-
-MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
-MODULE_DESCRIPTION("STV0680 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- struct v4l2_pix_format mode;
- u8 orig_mode;
- u8 video_mode;
- u8 current_mode;
-};
-
-static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val,
- int size)
-{
- int ret = -1;
- u8 req_type = 0;
- unsigned int pipe = 0;
-
- switch (set) {
- case 0: /* 0xc1 */
- req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
- pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
- break;
- case 1: /* 0x41 */
- req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
- pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
- break;
- case 2: /* 0x80 */
- req_type = USB_DIR_IN | USB_RECIP_DEVICE;
- pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
- break;
- case 3: /* 0x40 */
- req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
- pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
- break;
- }
-
- ret = usb_control_msg(gspca_dev->dev, pipe,
- req, req_type,
- val, 0, gspca_dev->usb_buf, size, 500);
-
- if ((ret < 0) && (req != 0x0a))
- pr_err("usb_control_msg error %i, request = 0x%x, error = %i\n",
- set, req, ret);
-
- return ret;
-}
-
-static int stv0680_handle_error(struct gspca_dev *gspca_dev, int ret)
-{
- stv_sndctrl(gspca_dev, 0, 0x80, 0, 0x02); /* Get Last Error */
- PDEBUG(D_ERR, "last error: %i, command = 0x%x",
- gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
- return ret;
-}
-
-static int stv0680_get_video_mode(struct gspca_dev *gspca_dev)
-{
- /* Note not sure if this init of usb_buf is really necessary */
- memset(gspca_dev->usb_buf, 0, 8);
- gspca_dev->usb_buf[0] = 0x0f;
-
- if (stv_sndctrl(gspca_dev, 0, 0x87, 0, 0x08) != 0x08) {
- PDEBUG(D_ERR, "Get_Camera_Mode failed");
- return stv0680_handle_error(gspca_dev, -EIO);
- }
-
- return gspca_dev->usb_buf[0]; /* 01 = VGA, 03 = QVGA, 00 = CIF */
-}
-
-static int stv0680_set_video_mode(struct gspca_dev *gspca_dev, u8 mode)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->current_mode == mode)
- return 0;
-
- memset(gspca_dev->usb_buf, 0, 8);
- gspca_dev->usb_buf[0] = mode;
-
- if (stv_sndctrl(gspca_dev, 3, 0x07, 0x0100, 0x08) != 0x08) {
- PDEBUG(D_ERR, "Set_Camera_Mode failed");
- return stv0680_handle_error(gspca_dev, -EIO);
- }
-
- /* Verify we got what we've asked for */
- if (stv0680_get_video_mode(gspca_dev) != mode) {
- PDEBUG(D_ERR, "Error setting camera video mode!");
- return -EIO;
- }
-
- sd->current_mode = mode;
-
- return 0;
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- int ret;
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam = &gspca_dev->cam;
-
- /* Give the camera some time to settle, otherwise initalization will
- fail on hotplug, and yes it really needs a full second. */
- msleep(1000);
-
- /* ping camera to be sure STV0680 is present */
- if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 ||
- gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) {
- PDEBUG(D_ERR, "STV(e): camera ping failed!!");
- return stv0680_handle_error(gspca_dev, -ENODEV);
- }
-
- /* get camera descriptor */
- if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x09) != 0x09)
- return stv0680_handle_error(gspca_dev, -ENODEV);
-
- if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x22) != 0x22 ||
- gspca_dev->usb_buf[7] != 0xa0 || gspca_dev->usb_buf[8] != 0x23) {
- PDEBUG(D_ERR, "Could not get descriptor 0200.");
- return stv0680_handle_error(gspca_dev, -ENODEV);
- }
- if (stv_sndctrl(gspca_dev, 0, 0x8a, 0, 0x02) != 0x02)
- return stv0680_handle_error(gspca_dev, -ENODEV);
- if (stv_sndctrl(gspca_dev, 0, 0x8b, 0, 0x24) != 0x24)
- return stv0680_handle_error(gspca_dev, -ENODEV);
- if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10)
- return stv0680_handle_error(gspca_dev, -ENODEV);
-
- if (!(gspca_dev->usb_buf[7] & 0x09)) {
- PDEBUG(D_ERR, "Camera supports neither CIF nor QVGA mode");
- return -ENODEV;
- }
- if (gspca_dev->usb_buf[7] & 0x01)
- PDEBUG(D_PROBE, "Camera supports CIF mode");
- if (gspca_dev->usb_buf[7] & 0x02)
- PDEBUG(D_PROBE, "Camera supports VGA mode");
- if (gspca_dev->usb_buf[7] & 0x04)
- PDEBUG(D_PROBE, "Camera supports QCIF mode");
- if (gspca_dev->usb_buf[7] & 0x08)
- PDEBUG(D_PROBE, "Camera supports QVGA mode");
-
- if (gspca_dev->usb_buf[7] & 0x01)
- sd->video_mode = 0x00; /* CIF */
- else
- sd->video_mode = 0x03; /* QVGA */
-
- /* FW rev, ASIC rev, sensor ID */
- PDEBUG(D_PROBE, "Firmware rev is %i.%i",
- gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
- PDEBUG(D_PROBE, "ASIC rev is %i.%i",
- gspca_dev->usb_buf[2], gspca_dev->usb_buf[3]);
- PDEBUG(D_PROBE, "Sensor ID is %i",
- (gspca_dev->usb_buf[4]*16) + (gspca_dev->usb_buf[5]>>4));
-
-
- ret = stv0680_get_video_mode(gspca_dev);
- if (ret < 0)
- return ret;
- sd->current_mode = sd->orig_mode = ret;
-
- ret = stv0680_set_video_mode(gspca_dev, sd->video_mode);
- if (ret < 0)
- return ret;
-
- /* Get mode details */
- if (stv_sndctrl(gspca_dev, 0, 0x8f, 0, 0x10) != 0x10)
- return stv0680_handle_error(gspca_dev, -EIO);
-
- cam->bulk = 1;
- cam->bulk_nurbs = 1; /* The cam cannot handle more */
- cam->bulk_size = (gspca_dev->usb_buf[0] << 24) |
- (gspca_dev->usb_buf[1] << 16) |
- (gspca_dev->usb_buf[2] << 8) |
- (gspca_dev->usb_buf[3]);
- sd->mode.width = (gspca_dev->usb_buf[4] << 8) |
- (gspca_dev->usb_buf[5]); /* 322, 356, 644 */
- sd->mode.height = (gspca_dev->usb_buf[6] << 8) |
- (gspca_dev->usb_buf[7]); /* 242, 292, 484 */
- sd->mode.pixelformat = V4L2_PIX_FMT_STV0680;
- sd->mode.field = V4L2_FIELD_NONE;
- sd->mode.bytesperline = sd->mode.width;
- sd->mode.sizeimage = cam->bulk_size;
- sd->mode.colorspace = V4L2_COLORSPACE_SRGB;
-
- /* origGain = gspca_dev->usb_buf[12]; */
-
- cam->cam_mode = &sd->mode;
- cam->nmodes = 1;
-
-
- ret = stv0680_set_video_mode(gspca_dev, sd->orig_mode);
- if (ret < 0)
- return ret;
-
- if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0100, 0x12) != 0x12 ||
- gspca_dev->usb_buf[8] != 0x53 || gspca_dev->usb_buf[9] != 0x05) {
- pr_err("Could not get descriptor 0100\n");
- return stv0680_handle_error(gspca_dev, -EIO);
- }
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- return 0;
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- int ret;
- struct sd *sd = (struct sd *) gspca_dev;
-
- ret = stv0680_set_video_mode(gspca_dev, sd->video_mode);
- if (ret < 0)
- return ret;
-
- if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10)
- return stv0680_handle_error(gspca_dev, -EIO);
-
- /* Start stream at:
- 0x0000 = CIF (352x288)
- 0x0100 = VGA (640x480)
- 0x0300 = QVGA (320x240) */
- if (stv_sndctrl(gspca_dev, 1, 0x09, sd->video_mode << 8, 0x0) != 0x0)
- return stv0680_handle_error(gspca_dev, -EIO);
-
- return 0;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- /* This is a high priority command; it stops all lower order cmds */
- if (stv_sndctrl(gspca_dev, 1, 0x04, 0x0000, 0x0) != 0x0)
- stv0680_handle_error(gspca_dev, -EIO);
-}
-
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (!sd->gspca_dev.present)
- return;
-
- stv0680_set_video_mode(gspca_dev, sd->orig_mode);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data,
- int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* Every now and then the camera sends a 16 byte packet, no idea
- what it contains, but it is not image data, when this
- happens the frame received before this packet is corrupt,
- so discard it. */
- if (len != sd->mode.sizeimage) {
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
-
- /* Finish the previous frame, we do this upon reception of the next
- packet, even though it is already complete so that the strange 16
- byte packets send after a corrupt frame can discard it. */
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
-
- /* Store the just received frame */
- gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x0553, 0x0202)},
- {USB_DEVICE(0x041e, 0x4007)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/stv06xx/Kconfig b/drivers/media/video/gspca/stv06xx/Kconfig
deleted file mode 100644
index 634ad38d9fb..00000000000
--- a/drivers/media/video/gspca/stv06xx/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-config USB_STV06XX
- tristate "STV06XX USB Camera Driver"
- depends on USB_GSPCA
- help
- Say Y here if you want support for cameras based on
- the ST STV06XX chip.
-
- To compile this driver as a module, choose M here: the
- module will be called gspca_stv06xx.
diff --git a/drivers/media/video/gspca/stv06xx/Makefile b/drivers/media/video/gspca/stv06xx/Makefile
deleted file mode 100644
index 38bc41061d8..00000000000
--- a/drivers/media/video/gspca/stv06xx/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-obj-$(CONFIG_USB_STV06XX) += gspca_stv06xx.o
-
-gspca_stv06xx-objs := stv06xx.o \
- stv06xx_vv6410.o \
- stv06xx_hdcs.o \
- stv06xx_pb0100.o \
- stv06xx_st6422.o
-
-ccflags-y += -I$(srctree)/drivers/media/video/gspca
-
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
deleted file mode 100644
index 999ec776444..00000000000
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ /dev/null
@@ -1,634 +0,0 @@
-/*
- * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
- * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
- * Copyright (c) 2002, 2003 Tuukka Toivonen
- * Copyright (c) 2008 Erik Andrén
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * P/N 861037: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
- * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
- * P/N 861075-0040: Sensor HDCS1000 ASIC
- * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
- * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/input.h>
-#include "stv06xx_sensor.h"
-
-MODULE_AUTHOR("Erik Andrén");
-MODULE_DESCRIPTION("STV06XX USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-static bool dump_bridge;
-static bool dump_sensor;
-
-int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data)
-{
- int err;
- struct usb_device *udev = sd->gspca_dev.dev;
- __u8 *buf = sd->gspca_dev.usb_buf;
- u8 len = (i2c_data > 0xff) ? 2 : 1;
-
- buf[0] = i2c_data & 0xff;
- buf[1] = (i2c_data >> 8) & 0xff;
-
- err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- 0x04, 0x40, address, 0, buf, len,
- STV06XX_URB_MSG_TIMEOUT);
-
- PDEBUG(D_CONF, "Written 0x%x to address 0x%x, status: %d",
- i2c_data, address, err);
-
- return (err < 0) ? err : 0;
-}
-
-int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data)
-{
- int err;
- struct usb_device *udev = sd->gspca_dev.dev;
- __u8 *buf = sd->gspca_dev.usb_buf;
-
- err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- 0x04, 0xc0, address, 0, buf, 1,
- STV06XX_URB_MSG_TIMEOUT);
-
- *i2c_data = buf[0];
-
- PDEBUG(D_CONF, "Reading 0x%x from address 0x%x, status %d",
- *i2c_data, address, err);
-
- return (err < 0) ? err : 0;
-}
-
-/* Wraps the normal write sensor bytes / words functions for writing a
- single value */
-int stv06xx_write_sensor(struct sd *sd, u8 address, u16 value)
-{
- if (sd->sensor->i2c_len == 2) {
- u16 data[2] = { address, value };
- return stv06xx_write_sensor_words(sd, data, 1);
- } else {
- u8 data[2] = { address, value };
- return stv06xx_write_sensor_bytes(sd, data, 1);
- }
-}
-
-static int stv06xx_write_sensor_finish(struct sd *sd)
-{
- int err = 0;
-
- if (sd->bridge == BRIDGE_STV610) {
- struct usb_device *udev = sd->gspca_dev.dev;
- __u8 *buf = sd->gspca_dev.usb_buf;
-
- buf[0] = 0;
- err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- 0x04, 0x40, 0x1704, 0, buf, 1,
- STV06XX_URB_MSG_TIMEOUT);
- }
-
- return (err < 0) ? err : 0;
-}
-
-int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len)
-{
- int err, i, j;
- struct usb_device *udev = sd->gspca_dev.dev;
- __u8 *buf = sd->gspca_dev.usb_buf;
-
- PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len);
- for (i = 0; i < len;) {
- /* Build the command buffer */
- memset(buf, 0, I2C_BUFFER_LENGTH);
- for (j = 0; j < I2C_MAX_BYTES && i < len; j++, i++) {
- buf[j] = data[2*i];
- buf[0x10 + j] = data[2*i+1];
- PDEBUG(D_CONF, "I2C: Writing 0x%02x to reg 0x%02x",
- data[2*i+1], data[2*i]);
- }
- buf[0x20] = sd->sensor->i2c_addr;
- buf[0x21] = j - 1; /* Number of commands to send - 1 */
- buf[0x22] = I2C_WRITE_CMD;
- err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- 0x04, 0x40, 0x0400, 0, buf,
- I2C_BUFFER_LENGTH,
- STV06XX_URB_MSG_TIMEOUT);
- if (err < 0)
- return err;
- }
- return stv06xx_write_sensor_finish(sd);
-}
-
-int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
-{
- int err, i, j;
- struct usb_device *udev = sd->gspca_dev.dev;
- __u8 *buf = sd->gspca_dev.usb_buf;
-
- PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len);
-
- for (i = 0; i < len;) {
- /* Build the command buffer */
- memset(buf, 0, I2C_BUFFER_LENGTH);
- for (j = 0; j < I2C_MAX_WORDS && i < len; j++, i++) {
- buf[j] = data[2*i];
- buf[0x10 + j * 2] = data[2*i+1];
- buf[0x10 + j * 2 + 1] = data[2*i+1] >> 8;
- PDEBUG(D_CONF, "I2C: Writing 0x%04x to reg 0x%02x",
- data[2*i+1], data[2*i]);
- }
- buf[0x20] = sd->sensor->i2c_addr;
- buf[0x21] = j - 1; /* Number of commands to send - 1 */
- buf[0x22] = I2C_WRITE_CMD;
- err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- 0x04, 0x40, 0x0400, 0, buf,
- I2C_BUFFER_LENGTH,
- STV06XX_URB_MSG_TIMEOUT);
- if (err < 0)
- return err;
- }
- return stv06xx_write_sensor_finish(sd);
-}
-
-int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value)
-{
- int err;
- struct usb_device *udev = sd->gspca_dev.dev;
- __u8 *buf = sd->gspca_dev.usb_buf;
-
- err = stv06xx_write_bridge(sd, STV_I2C_FLUSH, sd->sensor->i2c_flush);
- if (err < 0)
- return err;
-
- /* Clear mem */
- memset(buf, 0, I2C_BUFFER_LENGTH);
-
- buf[0] = address;
- buf[0x20] = sd->sensor->i2c_addr;
- buf[0x21] = 0;
-
- /* Read I2C register */
- buf[0x22] = I2C_READ_CMD;
-
- err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- 0x04, 0x40, 0x1400, 0, buf, I2C_BUFFER_LENGTH,
- STV06XX_URB_MSG_TIMEOUT);
- if (err < 0) {
- pr_err("I2C: Read error writing address: %d\n", err);
- return err;
- }
-
- err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- 0x04, 0xc0, 0x1410, 0, buf, sd->sensor->i2c_len,
- STV06XX_URB_MSG_TIMEOUT);
- if (sd->sensor->i2c_len == 2)
- *value = buf[0] | (buf[1] << 8);
- else
- *value = buf[0];
-
- PDEBUG(D_CONF, "I2C: Read 0x%x from address 0x%x, status: %d",
- *value, address, err);
-
- return (err < 0) ? err : 0;
-}
-
-/* Dumps all bridge registers */
-static void stv06xx_dump_bridge(struct sd *sd)
-{
- int i;
- u8 data, buf;
-
- pr_info("Dumping all stv06xx bridge registers\n");
- for (i = 0x1400; i < 0x160f; i++) {
- stv06xx_read_bridge(sd, i, &data);
-
- pr_info("Read 0x%x from address 0x%x\n", data, i);
- }
-
- pr_info("Testing stv06xx bridge registers for writability\n");
- for (i = 0x1400; i < 0x160f; i++) {
- stv06xx_read_bridge(sd, i, &data);
- buf = data;
-
- stv06xx_write_bridge(sd, i, 0xff);
- stv06xx_read_bridge(sd, i, &data);
- if (data == 0xff)
- pr_info("Register 0x%x is read/write\n", i);
- else if (data != buf)
- pr_info("Register 0x%x is read/write, but only partially\n",
- i);
- else
- pr_info("Register 0x%x is read-only\n", i);
-
- stv06xx_write_bridge(sd, i, buf);
- }
-}
-
-/* this function is called at probe and resume time */
-static int stv06xx_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int err;
-
- PDEBUG(D_PROBE, "Initializing camera");
-
- /* Let the usb init settle for a bit
- before performing the initialization */
- msleep(250);
-
- err = sd->sensor->init(sd);
-
- if (dump_sensor && sd->sensor->dump)
- sd->sensor->dump(sd);
-
- return (err < 0) ? err : 0;
-}
-
-/* this function is called at probe time */
-static int stv06xx_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- PDEBUG(D_PROBE, "Initializing controls");
-
- gspca_dev->vdev.ctrl_handler = &gspca_dev->ctrl_handler;
- return sd->sensor->init_controls(sd);
-}
-
-/* Start the camera */
-static int stv06xx_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct usb_host_interface *alt;
- struct usb_interface *intf;
- int err, packet_size;
-
- intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
- alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
- if (!alt) {
- PDEBUG(D_ERR, "Couldn't get altsetting");
- return -EIO;
- }
-
- packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
- err = stv06xx_write_bridge(sd, STV_ISO_SIZE_L, packet_size);
- if (err < 0)
- return err;
-
- /* Prepare the sensor for start */
- err = sd->sensor->start(sd);
- if (err < 0)
- goto out;
-
- /* Start isochronous streaming */
- err = stv06xx_write_bridge(sd, STV_ISO_ENABLE, 1);
-
-out:
- if (err < 0)
- PDEBUG(D_STREAM, "Starting stream failed");
- else
- PDEBUG(D_STREAM, "Started streaming");
-
- return (err < 0) ? err : 0;
-}
-
-static int stv06xx_isoc_init(struct gspca_dev *gspca_dev)
-{
- struct usb_host_interface *alt;
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* Start isoc bandwidth "negotiation" at max isoc bandwidth */
- alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
- alt->endpoint[0].desc.wMaxPacketSize =
- cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]);
-
- return 0;
-}
-
-static int stv06xx_isoc_nego(struct gspca_dev *gspca_dev)
-{
- int ret, packet_size, min_packet_size;
- struct usb_host_interface *alt;
- struct sd *sd = (struct sd *) gspca_dev;
-
- alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
- packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
- min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode];
- if (packet_size <= min_packet_size)
- return -EIO;
-
- packet_size -= 100;
- if (packet_size < min_packet_size)
- packet_size = min_packet_size;
- alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
-
- ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
- if (ret < 0)
- PDEBUG(D_ERR|D_STREAM, "set alt 1 err %d", ret);
-
- return ret;
-}
-
-static void stv06xx_stopN(struct gspca_dev *gspca_dev)
-{
- int err;
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* stop ISO-streaming */
- err = stv06xx_write_bridge(sd, STV_ISO_ENABLE, 0);
- if (err < 0)
- goto out;
-
- err = sd->sensor->stop(sd);
-
-out:
- if (err < 0)
- PDEBUG(D_STREAM, "Failed to stop stream");
- else
- PDEBUG(D_STREAM, "Stopped streaming");
-}
-
-/*
- * Analyse an USB packet of the data stream and store it appropriately.
- * Each packet contains an integral number of chunks. Each chunk has
- * 2-bytes identification, followed by 2-bytes that describe the chunk
- * length. Known/guessed chunk identifications are:
- * 8001/8005/C001/C005 - Begin new frame
- * 8002/8006/C002/C006 - End frame
- * 0200/4200 - Contains actual image data, bayer or compressed
- * 0005 - 11 bytes of unknown data
- * 0100 - 2 bytes of unknown data
- * The 0005 and 0100 chunks seem to appear only in compressed stream.
- */
-static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- PDEBUG(D_PACK, "Packet of length %d arrived", len);
-
- /* A packet may contain several frames
- loop until the whole packet is reached */
- while (len) {
- int id, chunk_len;
-
- if (len < 4) {
- PDEBUG(D_PACK, "Packet is smaller than 4 bytes");
- return;
- }
-
- /* Capture the id */
- id = (data[0] << 8) | data[1];
-
- /* Capture the chunk length */
- chunk_len = (data[2] << 8) | data[3];
- PDEBUG(D_PACK, "Chunk id: %x, length: %d", id, chunk_len);
-
- data += 4;
- len -= 4;
-
- if (len < chunk_len) {
- PDEBUG(D_ERR, "URB packet length is smaller"
- " than the specified chunk length");
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
-
- /* First byte seem to be 02=data 2nd byte is unknown??? */
- if (sd->bridge == BRIDGE_ST6422 && (id & 0xff00) == 0x0200)
- goto frame_data;
-
- switch (id) {
- case 0x0200:
- case 0x4200:
-frame_data:
- PDEBUG(D_PACK, "Frame data packet detected");
-
- if (sd->to_skip) {
- int skip = (sd->to_skip < chunk_len) ?
- sd->to_skip : chunk_len;
- data += skip;
- len -= skip;
- chunk_len -= skip;
- sd->to_skip -= skip;
- }
-
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data, chunk_len);
- break;
-
- case 0x8001:
- case 0x8005:
- case 0xc001:
- case 0xc005:
- PDEBUG(D_PACK, "Starting new frame");
-
- /* Create a new frame, chunk length should be zero */
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- NULL, 0);
-
- if (sd->bridge == BRIDGE_ST6422)
- sd->to_skip = gspca_dev->width * 4;
-
- if (chunk_len)
- PDEBUG(D_ERR, "Chunk length is "
- "non-zero on a SOF");
- break;
-
- case 0x8002:
- case 0x8006:
- case 0xc002:
- PDEBUG(D_PACK, "End of frame detected");
-
- /* Complete the last frame (if any) */
- gspca_frame_add(gspca_dev, LAST_PACKET,
- NULL, 0);
-
- if (chunk_len)
- PDEBUG(D_ERR, "Chunk length is "
- "non-zero on a EOF");
- break;
-
- case 0x0005:
- PDEBUG(D_PACK, "Chunk 0x005 detected");
- /* Unknown chunk with 11 bytes of data,
- occurs just before end of each frame
- in compressed mode */
- break;
-
- case 0x0100:
- PDEBUG(D_PACK, "Chunk 0x0100 detected");
- /* Unknown chunk with 2 bytes of data,
- occurs 2-3 times per USB interrupt */
- break;
- case 0x42ff:
- PDEBUG(D_PACK, "Chunk 0x42ff detected");
- /* Special chunk seen sometimes on the ST6422 */
- break;
- default:
- PDEBUG(D_PACK, "Unknown chunk 0x%04x detected", id);
- /* Unknown chunk */
- }
- data += chunk_len;
- len -= chunk_len;
- }
-}
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
-static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* interrupt packet data */
- int len) /* interrupt packet length */
-{
- int ret = -EINVAL;
-
- if (len == 1 && data[0] == 0x80) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
- input_sync(gspca_dev->input_dev);
- ret = 0;
- }
-
- if (len == 1 && data[0] == 0x88) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
- input_sync(gspca_dev->input_dev);
- ret = 0;
- }
-
- return ret;
-}
-#endif
-
-static int stv06xx_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id);
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = stv06xx_config,
- .init = stv06xx_init,
- .init_controls = stv06xx_init_controls,
- .start = stv06xx_start,
- .stopN = stv06xx_stopN,
- .pkt_scan = stv06xx_pkt_scan,
- .isoc_init = stv06xx_isoc_init,
- .isoc_nego = stv06xx_isoc_nego,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .int_pkt_scan = sd_int_pkt_scan,
-#endif
-};
-
-/* This function is called at probe time */
-static int stv06xx_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- PDEBUG(D_PROBE, "Configuring camera");
-
- sd->bridge = id->driver_info;
- gspca_dev->sd_desc = &sd_desc;
-
- if (dump_bridge)
- stv06xx_dump_bridge(sd);
-
- sd->sensor = &stv06xx_sensor_st6422;
- if (!sd->sensor->probe(sd))
- return 0;
-
- sd->sensor = &stv06xx_sensor_vv6410;
- if (!sd->sensor->probe(sd))
- return 0;
-
- sd->sensor = &stv06xx_sensor_hdcs1x00;
- if (!sd->sensor->probe(sd))
- return 0;
-
- sd->sensor = &stv06xx_sensor_hdcs1020;
- if (!sd->sensor->probe(sd))
- return 0;
-
- sd->sensor = &stv06xx_sensor_pb0100;
- if (!sd->sensor->probe(sd))
- return 0;
-
- sd->sensor = NULL;
- return -ENODEV;
-}
-
-
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- /* QuickCam Express */
- {USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 },
- /* LEGO cam / QuickCam Web */
- {USB_DEVICE(0x046d, 0x0850), .driver_info = BRIDGE_STV610 },
- /* Dexxa WebCam USB */
- {USB_DEVICE(0x046d, 0x0870), .driver_info = BRIDGE_STV602 },
- /* QuickCam Messenger */
- {USB_DEVICE(0x046D, 0x08F0), .driver_info = BRIDGE_ST6422 },
- /* QuickCam Communicate */
- {USB_DEVICE(0x046D, 0x08F5), .driver_info = BRIDGE_ST6422 },
- /* QuickCam Messenger (new) */
- {USB_DEVICE(0x046D, 0x08F6), .driver_info = BRIDGE_ST6422 },
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- PDEBUG(D_PROBE, "Probing for a stv06xx device");
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static void sd_disconnect(struct usb_interface *intf)
-{
- struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
- struct sd *sd = (struct sd *) gspca_dev;
- void *priv = sd->sensor_priv;
- PDEBUG(D_PROBE, "Disconnecting the stv06xx device");
-
- sd->sensor = NULL;
- gspca_disconnect(intf);
- kfree(priv);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = sd_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
-
-module_param(dump_bridge, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup");
-
-module_param(dump_sensor, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(dump_sensor, "Dumps all sensor registers at startup");
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.h b/drivers/media/video/gspca/stv06xx/stv06xx.h
deleted file mode 100644
index 34957a4ec15..00000000000
--- a/drivers/media/video/gspca/stv06xx/stv06xx.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
- * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
- * Copyright (c) 2002, 2003 Tuukka Toivonen
- * Copyright (c) 2008 Erik Andrén
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * P/N 861037: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
- * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
- * P/N 861075-0040: Sensor HDCS1000 ASIC
- * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
- * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
- */
-
-#ifndef STV06XX_H_
-#define STV06XX_H_
-
-#include <linux/slab.h>
-#include "gspca.h"
-
-#define MODULE_NAME "STV06xx"
-
-#define STV_ISOC_ENDPOINT_ADDR 0x81
-
-#define STV_R 0x0509
-
-#define STV_REG23 0x0423
-
-/* Control registers of the STV0600 ASIC */
-#define STV_I2C_PARTNER 0x1420
-#define STV_I2C_VAL_REG_VAL_PAIRS_MIN1 0x1421
-#define STV_I2C_READ_WRITE_TOGGLE 0x1422
-#define STV_I2C_FLUSH 0x1423
-#define STV_I2C_SUCC_READ_REG_VALS 0x1424
-
-#define STV_ISO_ENABLE 0x1440
-#define STV_SCAN_RATE 0x1443
-#define STV_LED_CTRL 0x1445
-#define STV_STV0600_EMULATION 0x1446
-#define STV_REG00 0x1500
-#define STV_REG01 0x1501
-#define STV_REG02 0x1502
-#define STV_REG03 0x1503
-#define STV_REG04 0x1504
-
-#define STV_ISO_SIZE_L 0x15c1
-#define STV_ISO_SIZE_H 0x15c2
-
-/* Refers to the CIF 352x288 and QCIF 176x144 */
-/* 1: 288 lines, 2: 144 lines */
-#define STV_Y_CTRL 0x15c3
-
-#define STV_RESET 0x1620
-
-/* 0xa: 352 columns, 0x6: 176 columns */
-#define STV_X_CTRL 0x1680
-
-#define STV06XX_URB_MSG_TIMEOUT 5000
-
-#define I2C_MAX_BYTES 16
-#define I2C_MAX_WORDS 8
-
-#define I2C_BUFFER_LENGTH 0x23
-#define I2C_READ_CMD 3
-#define I2C_WRITE_CMD 1
-
-#define LED_ON 1
-#define LED_OFF 0
-
-/* STV06xx device descriptor */
-struct sd {
- struct gspca_dev gspca_dev;
-
- /* A pointer to the currently connected sensor */
- const struct stv06xx_sensor *sensor;
-
- /* Sensor private data */
- void *sensor_priv;
-
- /* The first 4 lines produced by the stv6422 are no good, this keeps
- track of how many bytes we still need to skip during a frame */
- int to_skip;
-
- /* Bridge / Camera type */
- u8 bridge;
- #define BRIDGE_STV600 0
- #define BRIDGE_STV602 1
- #define BRIDGE_STV610 2
- #define BRIDGE_ST6422 3 /* With integrated sensor */
-};
-
-int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data);
-int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data);
-
-int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len);
-int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len);
-
-int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value);
-int stv06xx_write_sensor(struct sd *sd, u8 address, u16 value);
-
-#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
deleted file mode 100644
index 06fa54c5efb..00000000000
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
- * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
- * Copyright (c) 2002, 2003 Tuukka Toivonen
- * Copyright (c) 2008 Erik Andrén
- * Copyright (c) 2008 Chia-I Wu
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * P/N 861037: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
- * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
- * P/N 861075-0040: Sensor HDCS1000 ASIC
- * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
- * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "stv06xx_hdcs.h"
-
-static struct v4l2_pix_format hdcs1x00_mode[] = {
- {
- HDCS_1X00_DEF_WIDTH,
- HDCS_1X00_DEF_HEIGHT,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage =
- HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
- .bytesperline = HDCS_1X00_DEF_WIDTH,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- }
-};
-
-static struct v4l2_pix_format hdcs1020_mode[] = {
- {
- HDCS_1020_DEF_WIDTH,
- HDCS_1020_DEF_HEIGHT,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage =
- HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
- .bytesperline = HDCS_1020_DEF_WIDTH,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- }
-};
-
-enum hdcs_power_state {
- HDCS_STATE_SLEEP,
- HDCS_STATE_IDLE,
- HDCS_STATE_RUN
-};
-
-/* no lock? */
-struct hdcs {
- enum hdcs_power_state state;
- int w, h;
-
- /* visible area of the sensor array */
- struct {
- int left, top;
- int width, height;
- int border;
- } array;
-
- struct {
- /* Column timing overhead */
- u8 cto;
- /* Column processing overhead */
- u8 cpo;
- /* Row sample period constant */
- u16 rs;
- /* Exposure reset duration */
- u16 er;
- } exp;
-
- int psmp;
-};
-
-static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len)
-{
- u8 regs[I2C_MAX_BYTES * 2];
- int i;
-
- if (unlikely((len <= 0) || (len >= I2C_MAX_BYTES) ||
- (reg + len > 0xff)))
- return -EINVAL;
-
- for (i = 0; i < len; i++) {
- regs[2 * i] = reg;
- regs[2 * i + 1] = vals[i];
- /* All addresses are shifted left one bit
- * as bit 0 toggles r/w */
- reg += 2;
- }
-
- return stv06xx_write_sensor_bytes(sd, regs, len);
-}
-
-static int hdcs_set_state(struct sd *sd, enum hdcs_power_state state)
-{
- struct hdcs *hdcs = sd->sensor_priv;
- u8 val;
- int ret;
-
- if (hdcs->state == state)
- return 0;
-
- /* we need to go idle before running or sleeping */
- if (hdcs->state != HDCS_STATE_IDLE) {
- ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0);
- if (ret)
- return ret;
- }
-
- hdcs->state = HDCS_STATE_IDLE;
-
- if (state == HDCS_STATE_IDLE)
- return 0;
-
- switch (state) {
- case HDCS_STATE_SLEEP:
- val = HDCS_SLEEP_MODE;
- break;
-
- case HDCS_STATE_RUN:
- val = HDCS_RUN_ENABLE;
- break;
-
- default:
- return -EINVAL;
- }
-
- ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val);
-
- /* Update the state if the write succeeded */
- if (!ret)
- hdcs->state = state;
-
- return ret;
-}
-
-static int hdcs_reset(struct sd *sd)
-{
- struct hdcs *hdcs = sd->sensor_priv;
- int err;
-
- err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 1);
- if (err < 0)
- return err;
-
- err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0);
- if (err < 0)
- hdcs->state = HDCS_STATE_IDLE;
-
- return err;
-}
-
-static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct hdcs *hdcs = sd->sensor_priv;
- int rowexp, srowexp;
- int max_srowexp;
- /* Column time period */
- int ct;
- /* Column processing period */
- int cp;
- /* Row processing period */
- int rp;
- /* Minimum number of column timing periods
- within the column processing period */
- int mnct;
- int cycles, err;
- u8 exp[14];
-
- cycles = val * HDCS_CLK_FREQ_MHZ * 257;
-
- ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
- cp = hdcs->exp.cto + (hdcs->w * ct / 2);
-
- /* the cycles one row takes */
- rp = hdcs->exp.rs + cp;
-
- rowexp = cycles / rp;
-
- /* the remaining cycles */
- cycles -= rowexp * rp;
-
- /* calculate sub-row exposure */
- if (IS_1020(sd)) {
- /* see HDCS-1020 datasheet 3.5.6.4, p. 63 */
- srowexp = hdcs->w - (cycles + hdcs->exp.er + 13) / ct;
-
- mnct = (hdcs->exp.er + 12 + ct - 1) / ct;
- max_srowexp = hdcs->w - mnct;
- } else {
- /* see HDCS-1000 datasheet 3.4.5.5, p. 61 */
- srowexp = cp - hdcs->exp.er - 6 - cycles;
-
- mnct = (hdcs->exp.er + 5 + ct - 1) / ct;
- max_srowexp = cp - mnct * ct - 1;
- }
-
- if (srowexp < 0)
- srowexp = 0;
- else if (srowexp > max_srowexp)
- srowexp = max_srowexp;
-
- if (IS_1020(sd)) {
- exp[0] = HDCS20_CONTROL;
- exp[1] = 0x00; /* Stop streaming */
- exp[2] = HDCS_ROWEXPL;
- exp[3] = rowexp & 0xff;
- exp[4] = HDCS_ROWEXPH;
- exp[5] = rowexp >> 8;
- exp[6] = HDCS20_SROWEXP;
- exp[7] = (srowexp >> 2) & 0xff;
- exp[8] = HDCS20_ERROR;
- exp[9] = 0x10; /* Clear exposure error flag*/
- exp[10] = HDCS20_CONTROL;
- exp[11] = 0x04; /* Restart streaming */
- err = stv06xx_write_sensor_bytes(sd, exp, 6);
- } else {
- exp[0] = HDCS00_CONTROL;
- exp[1] = 0x00; /* Stop streaming */
- exp[2] = HDCS_ROWEXPL;
- exp[3] = rowexp & 0xff;
- exp[4] = HDCS_ROWEXPH;
- exp[5] = rowexp >> 8;
- exp[6] = HDCS00_SROWEXPL;
- exp[7] = srowexp & 0xff;
- exp[8] = HDCS00_SROWEXPH;
- exp[9] = srowexp >> 8;
- exp[10] = HDCS_STATUS;
- exp[11] = 0x10; /* Clear exposure error flag*/
- exp[12] = HDCS00_CONTROL;
- exp[13] = 0x04; /* Restart streaming */
- err = stv06xx_write_sensor_bytes(sd, exp, 7);
- if (err < 0)
- return err;
- }
- PDEBUG(D_V4L2, "Writing exposure %d, rowexp %d, srowexp %d",
- val, rowexp, srowexp);
- return err;
-}
-
-static int hdcs_set_gains(struct sd *sd, u8 g)
-{
- int err;
- u8 gains[4];
-
- /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */
- if (g > 127)
- g = 0x80 | (g / 2);
-
- gains[0] = g;
- gains[1] = g;
- gains[2] = g;
- gains[3] = g;
-
- err = hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4);
- return err;
-}
-
-static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val)
-{
- PDEBUG(D_V4L2, "Writing gain %d", val);
- return hdcs_set_gains((struct sd *) gspca_dev,
- val & 0xff);
-}
-
-static int hdcs_set_size(struct sd *sd,
- unsigned int width, unsigned int height)
-{
- struct hdcs *hdcs = sd->sensor_priv;
- u8 win[4];
- unsigned int x, y;
- int err;
-
- /* must be multiple of 4 */
- width = (width + 3) & ~0x3;
- height = (height + 3) & ~0x3;
-
- if (width > hdcs->array.width)
- width = hdcs->array.width;
-
- if (IS_1020(sd)) {
- /* the borders are also invalid */
- if (height + 2 * hdcs->array.border + HDCS_1020_BOTTOM_Y_SKIP
- > hdcs->array.height)
- height = hdcs->array.height - 2 * hdcs->array.border -
- HDCS_1020_BOTTOM_Y_SKIP;
-
- y = (hdcs->array.height - HDCS_1020_BOTTOM_Y_SKIP - height) / 2
- + hdcs->array.top;
- } else {
- if (height > hdcs->array.height)
- height = hdcs->array.height;
-
- y = hdcs->array.top + (hdcs->array.height - height) / 2;
- }
-
- x = hdcs->array.left + (hdcs->array.width - width) / 2;
-
- win[0] = y / 4;
- win[1] = x / 4;
- win[2] = (y + height) / 4 - 1;
- win[3] = (x + width) / 4 - 1;
-
- err = hdcs_reg_write_seq(sd, HDCS_FWROW, win, 4);
- if (err < 0)
- return err;
-
- /* Update the current width and height */
- hdcs->w = width;
- hdcs->h = height;
- return err;
-}
-
-static int hdcs_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- int err = -EINVAL;
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- err = hdcs_set_gain(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_EXPOSURE:
- err = hdcs_set_exposure(gspca_dev, ctrl->val);
- break;
- }
- return err;
-}
-
-static const struct v4l2_ctrl_ops hdcs_ctrl_ops = {
- .s_ctrl = hdcs_s_ctrl,
-};
-
-static int hdcs_init_controls(struct sd *sd)
-{
- struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
-
- v4l2_ctrl_handler_init(hdl, 2);
- v4l2_ctrl_new_std(hdl, &hdcs_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 0xff, 1, HDCS_DEFAULT_EXPOSURE);
- v4l2_ctrl_new_std(hdl, &hdcs_ctrl_ops,
- V4L2_CID_GAIN, 0, 0xff, 1, HDCS_DEFAULT_GAIN);
- return hdl->error;
-}
-
-static int hdcs_probe_1x00(struct sd *sd)
-{
- struct hdcs *hdcs;
- u16 sensor;
- int ret;
-
- ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor);
- if (ret < 0 || sensor != 0x08)
- return -ENODEV;
-
- pr_info("HDCS-1000/1100 sensor detected\n");
-
- sd->gspca_dev.cam.cam_mode = hdcs1x00_mode;
- sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode);
-
- hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
- if (!hdcs)
- return -ENOMEM;
-
- hdcs->array.left = 8;
- hdcs->array.top = 8;
- hdcs->array.width = HDCS_1X00_DEF_WIDTH;
- hdcs->array.height = HDCS_1X00_DEF_HEIGHT;
- hdcs->array.border = 4;
-
- hdcs->exp.cto = 4;
- hdcs->exp.cpo = 2;
- hdcs->exp.rs = 186;
- hdcs->exp.er = 100;
-
- /*
- * Frame rate on HDCS-1000 with STV600 depends on PSMP:
- * 4 = doesn't work at all
- * 5 = 7.8 fps,
- * 6 = 6.9 fps,
- * 8 = 6.3 fps,
- * 10 = 5.5 fps,
- * 15 = 4.4 fps,
- * 31 = 2.8 fps
- *
- * Frame rate on HDCS-1000 with STV602 depends on PSMP:
- * 15 = doesn't work at all
- * 18 = doesn't work at all
- * 19 = 7.3 fps
- * 20 = 7.4 fps
- * 21 = 7.4 fps
- * 22 = 7.4 fps
- * 24 = 6.3 fps
- * 30 = 5.4 fps
- */
- hdcs->psmp = (sd->bridge == BRIDGE_STV602) ? 20 : 5;
-
- sd->sensor_priv = hdcs;
-
- return 0;
-}
-
-static int hdcs_probe_1020(struct sd *sd)
-{
- struct hdcs *hdcs;
- u16 sensor;
- int ret;
-
- ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor);
- if (ret < 0 || sensor != 0x10)
- return -ENODEV;
-
- pr_info("HDCS-1020 sensor detected\n");
-
- sd->gspca_dev.cam.cam_mode = hdcs1020_mode;
- sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode);
-
- hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
- if (!hdcs)
- return -ENOMEM;
-
- /*
- * From Andrey's test image: looks like HDCS-1020 upper-left
- * visible pixel is at 24,8 (y maybe even smaller?) and lower-right
- * visible pixel at 375,299 (x maybe even larger?)
- */
- hdcs->array.left = 24;
- hdcs->array.top = 4;
- hdcs->array.width = HDCS_1020_DEF_WIDTH;
- hdcs->array.height = 304;
- hdcs->array.border = 4;
-
- hdcs->psmp = 6;
-
- hdcs->exp.cto = 3;
- hdcs->exp.cpo = 3;
- hdcs->exp.rs = 155;
- hdcs->exp.er = 96;
-
- sd->sensor_priv = hdcs;
-
- return 0;
-}
-
-static int hdcs_start(struct sd *sd)
-{
- PDEBUG(D_STREAM, "Starting stream");
-
- return hdcs_set_state(sd, HDCS_STATE_RUN);
-}
-
-static int hdcs_stop(struct sd *sd)
-{
- PDEBUG(D_STREAM, "Halting stream");
-
- return hdcs_set_state(sd, HDCS_STATE_SLEEP);
-}
-
-static int hdcs_init(struct sd *sd)
-{
- struct hdcs *hdcs = sd->sensor_priv;
- int i, err = 0;
-
- /* Set the STV0602AA in STV0600 emulation mode */
- if (sd->bridge == BRIDGE_STV602)
- stv06xx_write_bridge(sd, STV_STV0600_EMULATION, 1);
-
- /* Execute the bridge init */
- for (i = 0; i < ARRAY_SIZE(stv_bridge_init) && !err; i++) {
- err = stv06xx_write_bridge(sd, stv_bridge_init[i][0],
- stv_bridge_init[i][1]);
- }
- if (err < 0)
- return err;
-
- /* sensor soft reset */
- hdcs_reset(sd);
-
- /* Execute the sensor init */
- for (i = 0; i < ARRAY_SIZE(stv_sensor_init) && !err; i++) {
- err = stv06xx_write_sensor(sd, stv_sensor_init[i][0],
- stv_sensor_init[i][1]);
- }
- if (err < 0)
- return err;
-
- /* Enable continuous frame capture, bit 2: stop when frame complete */
- err = stv06xx_write_sensor(sd, HDCS_REG_CONFIG(sd), BIT(3));
- if (err < 0)
- return err;
-
- /* Set PGA sample duration
- (was 0x7E for the STV602, but caused slow framerate with HDCS-1020) */
- if (IS_1020(sd))
- err = stv06xx_write_sensor(sd, HDCS_TCTRL,
- (HDCS_ADC_START_SIG_DUR << 6) | hdcs->psmp);
- else
- err = stv06xx_write_sensor(sd, HDCS_TCTRL,
- (HDCS_ADC_START_SIG_DUR << 5) | hdcs->psmp);
- if (err < 0)
- return err;
-
- return hdcs_set_size(sd, hdcs->array.width, hdcs->array.height);
-}
-
-static int hdcs_dump(struct sd *sd)
-{
- u16 reg, val;
-
- pr_info("Dumping sensor registers:\n");
-
- for (reg = HDCS_IDENT; reg <= HDCS_ROWEXPH; reg++) {
- stv06xx_read_sensor(sd, reg, &val);
- pr_info("reg 0x%02x = 0x%02x\n", reg, val);
- }
- return 0;
-}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
deleted file mode 100644
index 1ba9158d010..00000000000
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
- * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
- * Copyright (c) 2002, 2003 Tuukka Toivonen
- * Copyright (c) 2008 Erik Andrén
- * Copyright (c) 2008 Chia-I Wu
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * P/N 861037: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
- * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
- * P/N 861075-0040: Sensor HDCS1000 ASIC
- * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
- * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
- */
-
-#ifndef STV06XX_HDCS_H_
-#define STV06XX_HDCS_H_
-
-#include "stv06xx_sensor.h"
-
-#define HDCS_REG_CONFIG(sd) (IS_1020(sd) ? HDCS20_CONFIG : HDCS00_CONFIG)
-#define HDCS_REG_CONTROL(sd) (IS_1020(sd) ? HDCS20_CONTROL : HDCS00_CONTROL)
-
-#define HDCS_1X00_DEF_WIDTH 360
-#define HDCS_1X00_DEF_HEIGHT 296
-
-#define HDCS_1020_DEF_WIDTH 352
-#define HDCS_1020_DEF_HEIGHT 292
-
-#define HDCS_1020_BOTTOM_Y_SKIP 4
-
-#define HDCS_CLK_FREQ_MHZ 25
-
-#define HDCS_ADC_START_SIG_DUR 3
-
-/* LSB bit of I2C or register address signifies write (0) or read (1) */
-/* I2C Registers common for both HDCS-1000/1100 and HDCS-1020 */
-/* Identifications Register */
-#define HDCS_IDENT (0x00 << 1)
-/* Status Register */
-#define HDCS_STATUS (0x01 << 1)
-/* Interrupt Mask Register */
-#define HDCS_IMASK (0x02 << 1)
-/* Pad Control Register */
-#define HDCS_PCTRL (0x03 << 1)
-/* Pad Drive Control Register */
-#define HDCS_PDRV (0x04 << 1)
-/* Interface Control Register */
-#define HDCS_ICTRL (0x05 << 1)
-/* Interface Timing Register */
-#define HDCS_ITMG (0x06 << 1)
-/* Baud Fraction Register */
-#define HDCS_BFRAC (0x07 << 1)
-/* Baud Rate Register */
-#define HDCS_BRATE (0x08 << 1)
-/* ADC Control Register */
-#define HDCS_ADCCTRL (0x09 << 1)
-/* First Window Row Register */
-#define HDCS_FWROW (0x0a << 1)
-/* First Window Column Register */
-#define HDCS_FWCOL (0x0b << 1)
-/* Last Window Row Register */
-#define HDCS_LWROW (0x0c << 1)
-/* Last Window Column Register */
-#define HDCS_LWCOL (0x0d << 1)
-/* Timing Control Register */
-#define HDCS_TCTRL (0x0e << 1)
-/* PGA Gain Register: Even Row, Even Column */
-#define HDCS_ERECPGA (0x0f << 1)
-/* PGA Gain Register: Even Row, Odd Column */
-#define HDCS_EROCPGA (0x10 << 1)
-/* PGA Gain Register: Odd Row, Even Column */
-#define HDCS_ORECPGA (0x11 << 1)
-/* PGA Gain Register: Odd Row, Odd Column */
-#define HDCS_OROCPGA (0x12 << 1)
-/* Row Exposure Low Register */
-#define HDCS_ROWEXPL (0x13 << 1)
-/* Row Exposure High Register */
-#define HDCS_ROWEXPH (0x14 << 1)
-
-/* I2C Registers only for HDCS-1000/1100 */
-/* Sub-Row Exposure Low Register */
-#define HDCS00_SROWEXPL (0x15 << 1)
-/* Sub-Row Exposure High Register */
-#define HDCS00_SROWEXPH (0x16 << 1)
-/* Configuration Register */
-#define HDCS00_CONFIG (0x17 << 1)
-/* Control Register */
-#define HDCS00_CONTROL (0x18 << 1)
-
-/* I2C Registers only for HDCS-1020 */
-/* Sub-Row Exposure Register */
-#define HDCS20_SROWEXP (0x15 << 1)
-/* Error Control Register */
-#define HDCS20_ERROR (0x16 << 1)
-/* Interface Timing 2 Register */
-#define HDCS20_ITMG2 (0x17 << 1)
-/* Interface Control 2 Register */
-#define HDCS20_ICTRL2 (0x18 << 1)
-/* Horizontal Blank Register */
-#define HDCS20_HBLANK (0x19 << 1)
-/* Vertical Blank Register */
-#define HDCS20_VBLANK (0x1a << 1)
-/* Configuration Register */
-#define HDCS20_CONFIG (0x1b << 1)
-/* Control Register */
-#define HDCS20_CONTROL (0x1c << 1)
-
-#define HDCS_RUN_ENABLE (1 << 2)
-#define HDCS_SLEEP_MODE (1 << 1)
-
-#define HDCS_DEFAULT_EXPOSURE 48
-#define HDCS_DEFAULT_GAIN 50
-
-static int hdcs_probe_1x00(struct sd *sd);
-static int hdcs_probe_1020(struct sd *sd);
-static int hdcs_start(struct sd *sd);
-static int hdcs_init(struct sd *sd);
-static int hdcs_init_controls(struct sd *sd);
-static int hdcs_stop(struct sd *sd);
-static int hdcs_dump(struct sd *sd);
-
-static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-
-const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = {
- .name = "HP HDCS-1000/1100",
- .i2c_flush = 0,
- .i2c_addr = (0x55 << 1),
- .i2c_len = 1,
-
- /* FIXME (see if we can lower min_packet_size, needs testing, and also
- adjusting framerate when the bandwidth gets lower) */
- .min_packet_size = { 847 },
- .max_packet_size = { 847 },
-
- .init = hdcs_init,
- .init_controls = hdcs_init_controls,
- .probe = hdcs_probe_1x00,
- .start = hdcs_start,
- .stop = hdcs_stop,
- .dump = hdcs_dump,
-};
-
-const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
- .name = "HDCS-1020",
- .i2c_flush = 0,
- .i2c_addr = (0x55 << 1),
- .i2c_len = 1,
-
- /* FIXME (see if we can lower min_packet_size, needs testing, and also
- adjusting framerate when the bandwidthm gets lower) */
- .min_packet_size = { 847 },
- .max_packet_size = { 847 },
-
- .init = hdcs_init,
- .init_controls = hdcs_init_controls,
- .probe = hdcs_probe_1020,
- .start = hdcs_start,
- .stop = hdcs_stop,
- .dump = hdcs_dump,
-};
-
-static const u16 stv_bridge_init[][2] = {
- {STV_ISO_ENABLE, 0},
- {STV_REG23, 0},
- {STV_REG00, 0x1d},
- {STV_REG01, 0xb5},
- {STV_REG02, 0xa8},
- {STV_REG03, 0x95},
- {STV_REG04, 0x07},
-
- {STV_SCAN_RATE, 0x20},
- {STV_Y_CTRL, 0x01},
- {STV_X_CTRL, 0x0a}
-};
-
-static const u8 stv_sensor_init[][2] = {
- /* Clear status (writing 1 will clear the corresponding status bit) */
- {HDCS_STATUS, BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1)},
- /* Disable all interrupts */
- {HDCS_IMASK, 0x00},
- {HDCS_PCTRL, BIT(6) | BIT(5) | BIT(1) | BIT(0)},
- {HDCS_PDRV, 0x00},
- {HDCS_ICTRL, BIT(5)},
- {HDCS_ITMG, BIT(4) | BIT(1)},
- /* ADC output resolution to 10 bits */
- {HDCS_ADCCTRL, 10}
-};
-
-#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
deleted file mode 100644
index cdfc3d05ab6..00000000000
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
- * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
- * Copyright (c) 2002, 2003 Tuukka Toivonen
- * Copyright (c) 2008 Erik Andrén
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * P/N 861037: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
- * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
- * P/N 861075-0040: Sensor HDCS1000 ASIC
- * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
- * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
- */
-
-/*
- * The spec file for the PB-0100 suggests the following for best quality
- * images after the sensor has been reset :
- *
- * PB_ADCGAINL = R60 = 0x03 (3 dec) : sets low reference of ADC
- to produce good black level
- * PB_PREADCTRL = R32 = 0x1400 (5120 dec) : Enables global gain changes
- through R53
- * PB_ADCMINGAIN = R52 = 0x10 (16 dec) : Sets the minimum gain for
- auto-exposure
- * PB_ADCGLOBALGAIN = R53 = 0x10 (16 dec) : Sets the global gain
- * PB_EXPGAIN = R14 = 0x11 (17 dec) : Sets the auto-exposure value
- * PB_UPDATEINT = R23 = 0x02 (2 dec) : Sets the speed on
- auto-exposure routine
- * PB_CFILLIN = R5 = 0x0E (14 dec) : Sets the frame rate
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "stv06xx_pb0100.h"
-
-struct pb0100_ctrls {
- struct { /* one big happy control cluster... */
- struct v4l2_ctrl *autogain;
- struct v4l2_ctrl *gain;
- struct v4l2_ctrl *exposure;
- struct v4l2_ctrl *red;
- struct v4l2_ctrl *blue;
- struct v4l2_ctrl *natural;
- };
- struct v4l2_ctrl *target;
-};
-
-static struct v4l2_pix_format pb0100_mode[] = {
-/* low res / subsample modes disabled as they are only half res horizontal,
- halving the vertical resolution does not seem to work */
- {
- 320,
- 240,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage = 320 * 240,
- .bytesperline = 320,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = PB0100_CROP_TO_VGA
- },
- {
- 352,
- 288,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage = 352 * 288,
- .bytesperline = 352,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- }
-};
-
-static int pb0100_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
- struct pb0100_ctrls *ctrls = sd->sensor_priv;
- int err = -EINVAL;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTOGAIN:
- err = pb0100_set_autogain(gspca_dev, ctrl->val);
- if (err)
- break;
- if (ctrl->val)
- break;
- err = pb0100_set_gain(gspca_dev, ctrls->gain->val);
- if (err)
- break;
- err = pb0100_set_exposure(gspca_dev, ctrls->exposure->val);
- break;
- case V4L2_CTRL_CLASS_USER + 0x1001:
- err = pb0100_set_autogain_target(gspca_dev, ctrl->val);
- break;
- }
- return err;
-}
-
-static const struct v4l2_ctrl_ops pb0100_ctrl_ops = {
- .s_ctrl = pb0100_s_ctrl,
-};
-
-static int pb0100_init_controls(struct sd *sd)
-{
- struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
- struct pb0100_ctrls *ctrls;
- static const struct v4l2_ctrl_config autogain_target = {
- .ops = &pb0100_ctrl_ops,
- .id = V4L2_CTRL_CLASS_USER + 0x1000,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Automatic Gain Target",
- .max = 255,
- .step = 1,
- .def = 128,
- };
- static const struct v4l2_ctrl_config natural_light = {
- .ops = &pb0100_ctrl_ops,
- .id = V4L2_CTRL_CLASS_USER + 0x1001,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Natural Light Source",
- .max = 1,
- .step = 1,
- .def = 1,
- };
-
- ctrls = kzalloc(sizeof(*ctrls), GFP_KERNEL);
- if (!ctrls)
- return -ENOMEM;
-
- v4l2_ctrl_handler_init(hdl, 6);
- ctrls->autogain = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- ctrls->exposure = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 511, 1, 12);
- ctrls->gain = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
- V4L2_CID_GAIN, 0, 255, 1, 128);
- ctrls->red = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
- V4L2_CID_RED_BALANCE, -255, 255, 1, 0);
- ctrls->blue = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
- V4L2_CID_BLUE_BALANCE, -255, 255, 1, 0);
- ctrls->natural = v4l2_ctrl_new_custom(hdl, &natural_light, NULL);
- ctrls->target = v4l2_ctrl_new_custom(hdl, &autogain_target, NULL);
- if (hdl->error) {
- kfree(ctrls);
- return hdl->error;
- }
- sd->sensor_priv = ctrls;
- v4l2_ctrl_auto_cluster(5, &ctrls->autogain, 0, false);
- return 0;
-}
-
-static int pb0100_probe(struct sd *sd)
-{
- u16 sensor;
- int err;
-
- err = stv06xx_read_sensor(sd, PB_IDENT, &sensor);
-
- if (err < 0)
- return -ENODEV;
- if ((sensor >> 8) != 0x64)
- return -ENODEV;
-
- pr_info("Photobit pb0100 sensor detected\n");
-
- sd->gspca_dev.cam.cam_mode = pb0100_mode;
- sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode);
-
- return 0;
-}
-
-static int pb0100_start(struct sd *sd)
-{
- int err, packet_size, max_packet_size;
- struct usb_host_interface *alt;
- struct usb_interface *intf;
- struct cam *cam = &sd->gspca_dev.cam;
- u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
-
- intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
- alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
- if (!alt)
- return -ENODEV;
- packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
-
- /* If we don't have enough bandwidth use a lower framerate */
- max_packet_size = sd->sensor->max_packet_size[sd->gspca_dev.curr_mode];
- if (packet_size < max_packet_size)
- stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
- else
- stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(5)|BIT(3)|BIT(1));
-
- /* Setup sensor window */
- if (mode & PB0100_CROP_TO_VGA) {
- stv06xx_write_sensor(sd, PB_RSTART, 30);
- stv06xx_write_sensor(sd, PB_CSTART, 20);
- stv06xx_write_sensor(sd, PB_RWSIZE, 240 - 1);
- stv06xx_write_sensor(sd, PB_CWSIZE, 320 - 1);
- } else {
- stv06xx_write_sensor(sd, PB_RSTART, 8);
- stv06xx_write_sensor(sd, PB_CSTART, 4);
- stv06xx_write_sensor(sd, PB_RWSIZE, 288 - 1);
- stv06xx_write_sensor(sd, PB_CWSIZE, 352 - 1);
- }
-
- if (mode & PB0100_SUBSAMPLE) {
- stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02); /* Wrong, FIXME */
- stv06xx_write_bridge(sd, STV_X_CTRL, 0x06);
-
- stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10);
- } else {
- stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01);
- stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a);
- /* larger -> slower */
- stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20);
- }
-
- err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1));
- PDEBUG(D_STREAM, "Started stream, status: %d", err);
-
- return (err < 0) ? err : 0;
-}
-
-static int pb0100_stop(struct sd *sd)
-{
- int err;
-
- err = stv06xx_write_sensor(sd, PB_ABORTFRAME, 1);
-
- if (err < 0)
- goto out;
-
- /* Set bit 1 to zero */
- err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
-
- PDEBUG(D_STREAM, "Halting stream");
-out:
- return (err < 0) ? err : 0;
-}
-
-/* FIXME: Sort the init commands out and put them into tables,
- this is only for getting the camera to work */
-/* FIXME: No error handling for now,
- add this once the init has been converted to proper tables */
-static int pb0100_init(struct sd *sd)
-{
- stv06xx_write_bridge(sd, STV_REG00, 1);
- stv06xx_write_bridge(sd, STV_SCAN_RATE, 0);
-
- /* Reset sensor */
- stv06xx_write_sensor(sd, PB_RESET, 1);
- stv06xx_write_sensor(sd, PB_RESET, 0);
-
- /* Disable chip */
- stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
-
- /* Gain stuff...*/
- stv06xx_write_sensor(sd, PB_PREADCTRL, BIT(12)|BIT(10)|BIT(6));
- stv06xx_write_sensor(sd, PB_ADCGLOBALGAIN, 12);
-
- /* Set up auto-exposure */
- /* ADC VREF_HI new setting for a transition
- from the Expose1 to the Expose2 setting */
- stv06xx_write_sensor(sd, PB_R28, 12);
- /* gain max for autoexposure */
- stv06xx_write_sensor(sd, PB_ADCMAXGAIN, 180);
- /* gain min for autoexposure */
- stv06xx_write_sensor(sd, PB_ADCMINGAIN, 12);
- /* Maximum frame integration time (programmed into R8)
- allowed for auto-exposure routine */
- stv06xx_write_sensor(sd, PB_R54, 3);
- /* Minimum frame integration time (programmed into R8)
- allowed for auto-exposure routine */
- stv06xx_write_sensor(sd, PB_R55, 0);
- stv06xx_write_sensor(sd, PB_UPDATEINT, 1);
- /* R15 Expose0 (maximum that auto-exposure may use) */
- stv06xx_write_sensor(sd, PB_R15, 800);
- /* R17 Expose2 (minimum that auto-exposure may use) */
- stv06xx_write_sensor(sd, PB_R17, 10);
-
- stv06xx_write_sensor(sd, PB_EXPGAIN, 0);
-
- /* 0x14 */
- stv06xx_write_sensor(sd, PB_VOFFSET, 0);
- /* 0x0D */
- stv06xx_write_sensor(sd, PB_ADCGAINH, 11);
- /* Set black level (important!) */
- stv06xx_write_sensor(sd, PB_ADCGAINL, 0);
-
- /* ??? */
- stv06xx_write_bridge(sd, STV_REG00, 0x11);
- stv06xx_write_bridge(sd, STV_REG03, 0x45);
- stv06xx_write_bridge(sd, STV_REG04, 0x07);
-
- /* Scan/timing for the sensor */
- stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
- stv06xx_write_sensor(sd, PB_CFILLIN, 14);
- stv06xx_write_sensor(sd, PB_VBL, 0);
- stv06xx_write_sensor(sd, PB_FINTTIME, 0);
- stv06xx_write_sensor(sd, PB_RINTTIME, 123);
-
- stv06xx_write_bridge(sd, STV_REG01, 0xc2);
- stv06xx_write_bridge(sd, STV_REG02, 0xb0);
- return 0;
-}
-
-static int pb0100_dump(struct sd *sd)
-{
- return 0;
-}
-
-static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- struct sd *sd = (struct sd *) gspca_dev;
- struct pb0100_ctrls *ctrls = sd->sensor_priv;
-
- err = stv06xx_write_sensor(sd, PB_G1GAIN, val);
- if (!err)
- err = stv06xx_write_sensor(sd, PB_G2GAIN, val);
- PDEBUG(D_V4L2, "Set green gain to %d, status: %d", val, err);
-
- if (!err)
- err = pb0100_set_red_balance(gspca_dev, ctrls->red->val);
- if (!err)
- err = pb0100_set_blue_balance(gspca_dev, ctrls->blue->val);
-
- return err;
-}
-
-static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- struct sd *sd = (struct sd *) gspca_dev;
- struct pb0100_ctrls *ctrls = sd->sensor_priv;
-
- val += ctrls->gain->val;
- if (val < 0)
- val = 0;
- else if (val > 255)
- val = 255;
-
- err = stv06xx_write_sensor(sd, PB_RGAIN, val);
- PDEBUG(D_V4L2, "Set red gain to %d, status: %d", val, err);
-
- return err;
-}
-
-static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- struct sd *sd = (struct sd *) gspca_dev;
- struct pb0100_ctrls *ctrls = sd->sensor_priv;
-
- val += ctrls->gain->val;
- if (val < 0)
- val = 0;
- else if (val > 255)
- val = 255;
-
- err = stv06xx_write_sensor(sd, PB_BGAIN, val);
- PDEBUG(D_V4L2, "Set blue gain to %d, status: %d", val, err);
-
- return err;
-}
-
-static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int err;
-
- err = stv06xx_write_sensor(sd, PB_RINTTIME, val);
- PDEBUG(D_V4L2, "Set exposure to %d, status: %d", val, err);
-
- return err;
-}
-
-static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- struct sd *sd = (struct sd *) gspca_dev;
- struct pb0100_ctrls *ctrls = sd->sensor_priv;
-
- if (val) {
- if (ctrls->natural->val)
- val = BIT(6)|BIT(4)|BIT(0);
- else
- val = BIT(4)|BIT(0);
- } else
- val = 0;
-
- err = stv06xx_write_sensor(sd, PB_EXPGAIN, val);
- PDEBUG(D_V4L2, "Set autogain to %d (natural: %d), status: %d",
- val, ctrls->natural->val, err);
-
- return err;
-}
-
-static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err, totalpixels, brightpixels, darkpixels;
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* Number of pixels counted by the sensor when subsampling the pixels.
- * Slightly larger than the real value to avoid oscillation */
- totalpixels = gspca_dev->width * gspca_dev->height;
- totalpixels = totalpixels/(8*8) + totalpixels/(64*64);
-
- brightpixels = (totalpixels * val) >> 8;
- darkpixels = totalpixels - brightpixels;
- err = stv06xx_write_sensor(sd, PB_R21, brightpixels);
- if (!err)
- err = stv06xx_write_sensor(sd, PB_R22, darkpixels);
-
- PDEBUG(D_V4L2, "Set autogain target to %d, status: %d", val, err);
-
- return err;
-}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
deleted file mode 100644
index 5071e5353fd..00000000000
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
- * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
- * Copyright (c) 2002, 2003 Tuukka Toivonen
- * Copyright (c) 2008 Erik Andrén
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * P/N 861037: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
- * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
- * P/N 861075-0040: Sensor HDCS1000 ASIC
- * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
- * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
- */
-
-#ifndef STV06XX_PB0100_H_
-#define STV06XX_PB0100_H_
-
-#include "stv06xx_sensor.h"
-
-/* mode priv field flags */
-#define PB0100_CROP_TO_VGA 0x01
-#define PB0100_SUBSAMPLE 0x02
-
-/* I2C Registers */
-#define PB_IDENT 0x00 /* Chip Version */
-#define PB_RSTART 0x01 /* Row Window Start */
-#define PB_CSTART 0x02 /* Column Window Start */
-#define PB_RWSIZE 0x03 /* Row Window Size */
-#define PB_CWSIZE 0x04 /* Column Window Size */
-#define PB_CFILLIN 0x05 /* Column Fill-In */
-#define PB_VBL 0x06 /* Vertical Blank Count */
-#define PB_CONTROL 0x07 /* Control Mode */
-#define PB_FINTTIME 0x08 /* Integration Time/Frame Unit Count */
-#define PB_RINTTIME 0x09 /* Integration Time/Row Unit Count */
-#define PB_ROWSPEED 0x0a /* Row Speed Control */
-#define PB_ABORTFRAME 0x0b /* Abort Frame */
-#define PB_R12 0x0c /* Reserved */
-#define PB_RESET 0x0d /* Reset */
-#define PB_EXPGAIN 0x0e /* Exposure Gain Command */
-#define PB_R15 0x0f /* Expose0 */
-#define PB_R16 0x10 /* Expose1 */
-#define PB_R17 0x11 /* Expose2 */
-#define PB_R18 0x12 /* Low0_DAC */
-#define PB_R19 0x13 /* Low1_DAC */
-#define PB_R20 0x14 /* Low2_DAC */
-#define PB_R21 0x15 /* Threshold11 */
-#define PB_R22 0x16 /* Threshold0x */
-#define PB_UPDATEINT 0x17 /* Update Interval */
-#define PB_R24 0x18 /* High_DAC */
-#define PB_R25 0x19 /* Trans0H */
-#define PB_R26 0x1a /* Trans1L */
-#define PB_R27 0x1b /* Trans1H */
-#define PB_R28 0x1c /* Trans2L */
-#define PB_R29 0x1d /* Reserved */
-#define PB_R30 0x1e /* Reserved */
-#define PB_R31 0x1f /* Wait to Read */
-#define PB_PREADCTRL 0x20 /* Pixel Read Control Mode */
-#define PB_R33 0x21 /* IREF_VLN */
-#define PB_R34 0x22 /* IREF_VLP */
-#define PB_R35 0x23 /* IREF_VLN_INTEG */
-#define PB_R36 0x24 /* IREF_MASTER */
-#define PB_R37 0x25 /* IDACP */
-#define PB_R38 0x26 /* IDACN */
-#define PB_R39 0x27 /* DAC_Control_Reg */
-#define PB_R40 0x28 /* VCL */
-#define PB_R41 0x29 /* IREF_VLN_ADCIN */
-#define PB_R42 0x2a /* Reserved */
-#define PB_G1GAIN 0x2b /* Green 1 Gain */
-#define PB_BGAIN 0x2c /* Blue Gain */
-#define PB_RGAIN 0x2d /* Red Gain */
-#define PB_G2GAIN 0x2e /* Green 2 Gain */
-#define PB_R47 0x2f /* Dark Row Address */
-#define PB_R48 0x30 /* Dark Row Options */
-#define PB_R49 0x31 /* Reserved */
-#define PB_R50 0x32 /* Image Test Data */
-#define PB_ADCMAXGAIN 0x33 /* Maximum Gain */
-#define PB_ADCMINGAIN 0x34 /* Minimum Gain */
-#define PB_ADCGLOBALGAIN 0x35 /* Global Gain */
-#define PB_R54 0x36 /* Maximum Frame */
-#define PB_R55 0x37 /* Minimum Frame */
-#define PB_R56 0x38 /* Reserved */
-#define PB_VOFFSET 0x39 /* VOFFSET */
-#define PB_R58 0x3a /* Snap-Shot Sequence Trigger */
-#define PB_ADCGAINH 0x3b /* VREF_HI */
-#define PB_ADCGAINL 0x3c /* VREF_LO */
-#define PB_R61 0x3d /* Reserved */
-#define PB_R62 0x3e /* Reserved */
-#define PB_R63 0x3f /* Reserved */
-#define PB_R64 0x40 /* Red/Blue Gain */
-#define PB_R65 0x41 /* Green 2/Green 1 Gain */
-#define PB_R66 0x42 /* VREF_HI/LO */
-#define PB_R67 0x43 /* Integration Time/Row Unit Count */
-#define PB_R240 0xf0 /* ADC Test */
-#define PB_R241 0xf1 /* Chip Enable */
-#define PB_R242 0xf2 /* Reserved */
-
-static int pb0100_probe(struct sd *sd);
-static int pb0100_start(struct sd *sd);
-static int pb0100_init(struct sd *sd);
-static int pb0100_init_controls(struct sd *sd);
-static int pb0100_stop(struct sd *sd);
-static int pb0100_dump(struct sd *sd);
-
-/* V4L2 controls supported by the driver */
-static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
-static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
-static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val);
-static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val);
-
-const struct stv06xx_sensor stv06xx_sensor_pb0100 = {
- .name = "PB-0100",
- .i2c_flush = 1,
- .i2c_addr = 0xba,
- .i2c_len = 2,
-
- .min_packet_size = { 635, 847 },
- .max_packet_size = { 847, 923 },
-
- .init = pb0100_init,
- .init_controls = pb0100_init_controls,
- .probe = pb0100_probe,
- .start = pb0100_start,
- .stop = pb0100_stop,
- .dump = pb0100_dump,
-};
-
-#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
deleted file mode 100644
index 3a498c2495c..00000000000
--- a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
- * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
- * Copyright (c) 2002, 2003 Tuukka Toivonen
- * Copyright (c) 2008 Erik Andrén
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * P/N 861037: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
- * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
- * P/N 861075-0040: Sensor HDCS1000 ASIC
- * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
- * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
- */
-
-#ifndef STV06XX_SENSOR_H_
-#define STV06XX_SENSOR_H_
-
-#include "stv06xx.h"
-
-#define IS_1020(sd) ((sd)->sensor == &stv06xx_sensor_hdcs1020)
-
-extern const struct stv06xx_sensor stv06xx_sensor_vv6410;
-extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00;
-extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020;
-extern const struct stv06xx_sensor stv06xx_sensor_pb0100;
-extern const struct stv06xx_sensor stv06xx_sensor_st6422;
-
-struct stv06xx_sensor {
- /* Defines the name of a sensor */
- char name[32];
-
- /* Sensor i2c address */
- u8 i2c_addr;
-
- /* Flush value*/
- u8 i2c_flush;
-
- /* length of an i2c word */
- u8 i2c_len;
-
- /* Isoc packet size (per mode) */
- int min_packet_size[4];
- int max_packet_size[4];
-
- /* Probes if the sensor is connected */
- int (*probe)(struct sd *sd);
-
- /* Performs a initialization sequence */
- int (*init)(struct sd *sd);
-
- /* Initializes the controls */
- int (*init_controls)(struct sd *sd);
-
- /* Reads a sensor register */
- int (*read_sensor)(struct sd *sd, const u8 address,
- u8 *i2c_data, const u8 len);
-
- /* Writes to a sensor register */
- int (*write_sensor)(struct sd *sd, const u8 address,
- u8 *i2c_data, const u8 len);
-
- /* Instructs the sensor to start streaming */
- int (*start)(struct sd *sd);
-
- /* Instructs the sensor to stop streaming */
- int (*stop)(struct sd *sd);
-
- /* Instructs the sensor to dump all its contents */
- int (*dump)(struct sd *sd);
-};
-
-#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
deleted file mode 100644
index 8a57990dfe0..00000000000
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Support for the sensor part which is integrated (I think) into the
- * st6422 stv06xx alike bridge, as its integrated there are no i2c writes
- * but instead direct bridge writes.
- *
- * Copyright (c) 2009 Hans de Goede <hdegoede@redhat.com>
- *
- * Strongly based on qc-usb-messenger, which is:
- * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
- * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
- * Copyright (c) 2002, 2003 Tuukka Toivonen
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "stv06xx_st6422.h"
-
-static struct v4l2_pix_format st6422_mode[] = {
- /* Note we actually get 124 lines of data, of which we skip the 4st
- 4 as they are garbage */
- {
- 162,
- 120,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage = 162 * 120,
- .bytesperline = 162,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- },
- /* Note we actually get 248 lines of data, of which we skip the 4st
- 4 as they are garbage, and we tell the app it only gets the
- first 240 of the 244 lines it actually gets, so that it ignores
- the last 4. */
- {
- 324,
- 240,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage = 324 * 244,
- .bytesperline = 324,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- },
-};
-
-/* V4L2 controls supported by the driver */
-static int setbrightness(struct sd *sd, s32 val);
-static int setcontrast(struct sd *sd, s32 val);
-static int setgain(struct sd *sd, u8 gain);
-static int setexposure(struct sd *sd, s16 expo);
-
-static int st6422_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
- int err = -EINVAL;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- err = setbrightness(sd, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- err = setcontrast(sd, ctrl->val);
- break;
- case V4L2_CID_GAIN:
- err = setgain(sd, ctrl->val);
- break;
- case V4L2_CID_EXPOSURE:
- err = setexposure(sd, ctrl->val);
- break;
- }
-
- /* commit settings */
- if (err >= 0)
- err = stv06xx_write_bridge(sd, 0x143f, 0x01);
- sd->gspca_dev.usb_err = err;
- return err;
-}
-
-static const struct v4l2_ctrl_ops st6422_ctrl_ops = {
- .s_ctrl = st6422_s_ctrl,
-};
-
-static int st6422_init_controls(struct sd *sd)
-{
- struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
-
- v4l2_ctrl_handler_init(hdl, 4);
- v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 31, 1, 3);
- v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 15, 1, 11);
- v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 1023, 1, 256);
- v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops,
- V4L2_CID_GAIN, 0, 255, 1, 64);
-
- return hdl->error;
-}
-
-static int st6422_probe(struct sd *sd)
-{
- if (sd->bridge != BRIDGE_ST6422)
- return -ENODEV;
-
- pr_info("st6422 sensor detected\n");
-
- sd->gspca_dev.cam.cam_mode = st6422_mode;
- sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode);
- return 0;
-}
-
-static int st6422_init(struct sd *sd)
-{
- int err = 0, i;
-
- const u16 st6422_bridge_init[][2] = {
- { STV_ISO_ENABLE, 0x00 }, /* disable capture */
- { 0x1436, 0x00 },
- { 0x1432, 0x03 }, /* 0x00-0x1F brightness */
- { 0x143a, 0xf9 }, /* 0x00-0x0F contrast */
- { 0x0509, 0x38 }, /* R */
- { 0x050a, 0x38 }, /* G */
- { 0x050b, 0x38 }, /* B */
- { 0x050c, 0x2a },
- { 0x050d, 0x01 },
-
-
- { 0x1431, 0x00 }, /* 0x00-0x07 ??? */
- { 0x1433, 0x34 }, /* 160x120, 0x00-0x01 night filter */
- { 0x1438, 0x18 }, /* 640x480 */
-/* 18 bayes */
-/* 10 compressed? */
-
- { 0x1439, 0x00 },
-/* anti-noise? 0xa2 gives a perfect image */
-
- { 0x143b, 0x05 },
- { 0x143c, 0x00 }, /* 0x00-0x01 - ??? */
-
-
-/* shutter time 0x0000-0x03FF */
-/* low value give good picures on moving objects (but requires much light) */
-/* high value gives good picures in darkness (but tends to be overexposed) */
- { 0x143e, 0x01 },
- { 0x143d, 0x00 },
-
- { 0x1442, 0xe2 },
-/* write: 1x1x xxxx */
-/* read: 1x1x xxxx */
-/* bit 5 == button pressed and hold if 0 */
-/* write 0xe2,0xea */
-
-/* 0x144a */
-/* 0x00 init */
-/* bit 7 == button has been pressed, but not handled */
-
-/* interrupt */
-/* if(urb->iso_frame_desc[i].status == 0x80) { */
-/* if(urb->iso_frame_desc[i].status == 0x88) { */
-
- { 0x1500, 0xd0 },
- { 0x1500, 0xd0 },
- { 0x1500, 0x50 }, /* 0x00 - 0xFF 0x80 == compr ? */
-
- { 0x1501, 0xaf },
-/* high val-> light area gets darker */
-/* low val -> light area gets lighter */
- { 0x1502, 0xc2 },
-/* high val-> light area gets darker */
-/* low val -> light area gets lighter */
- { 0x1503, 0x45 },
-/* high val-> light area gets darker */
-/* low val -> light area gets lighter */
- { 0x1505, 0x02 },
-/* 2 : 324x248 80352 bytes */
-/* 7 : 248x162 40176 bytes */
-/* c+f: 162*124 20088 bytes */
-
- { 0x150e, 0x8e },
- { 0x150f, 0x37 },
- { 0x15c0, 0x00 },
- { 0x15c3, 0x08 }, /* 0x04/0x14 ... test pictures ??? */
-
-
- { 0x143f, 0x01 }, /* commit settings */
-
- };
-
- for (i = 0; i < ARRAY_SIZE(st6422_bridge_init) && !err; i++) {
- err = stv06xx_write_bridge(sd, st6422_bridge_init[i][0],
- st6422_bridge_init[i][1]);
- }
-
- return err;
-}
-
-static int setbrightness(struct sd *sd, s32 val)
-{
- /* val goes from 0 -> 31 */
- return stv06xx_write_bridge(sd, 0x1432, val);
-}
-
-static int setcontrast(struct sd *sd, s32 val)
-{
- /* Val goes from 0 -> 15 */
- return stv06xx_write_bridge(sd, 0x143a, val | 0xf0);
-}
-
-static int setgain(struct sd *sd, u8 gain)
-{
- int err;
-
- /* Set red, green, blue, gain */
- err = stv06xx_write_bridge(sd, 0x0509, gain);
- if (err < 0)
- return err;
-
- err = stv06xx_write_bridge(sd, 0x050a, gain);
- if (err < 0)
- return err;
-
- err = stv06xx_write_bridge(sd, 0x050b, gain);
- if (err < 0)
- return err;
-
- /* 2 mystery writes */
- err = stv06xx_write_bridge(sd, 0x050c, 0x2a);
- if (err < 0)
- return err;
-
- return stv06xx_write_bridge(sd, 0x050d, 0x01);
-}
-
-static int setexposure(struct sd *sd, s16 expo)
-{
- int err;
-
- err = stv06xx_write_bridge(sd, 0x143d, expo & 0xff);
- if (err < 0)
- return err;
-
- return stv06xx_write_bridge(sd, 0x143e, expo >> 8);
-}
-
-static int st6422_start(struct sd *sd)
-{
- int err;
- struct cam *cam = &sd->gspca_dev.cam;
-
- if (cam->cam_mode[sd->gspca_dev.curr_mode].priv)
- err = stv06xx_write_bridge(sd, 0x1505, 0x0f);
- else
- err = stv06xx_write_bridge(sd, 0x1505, 0x02);
- if (err < 0)
- return err;
-
- /* commit settings */
- err = stv06xx_write_bridge(sd, 0x143f, 0x01);
- return (err < 0) ? err : 0;
-}
-
-static int st6422_stop(struct sd *sd)
-{
- PDEBUG(D_STREAM, "Halting stream");
-
- return 0;
-}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
deleted file mode 100644
index 8f20fbf30f3..00000000000
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Support for the sensor part which is integrated (I think) into the
- * st6422 stv06xx alike bridge, as its integrated there are no i2c writes
- * but instead direct bridge writes.
- *
- * Copyright (c) 2009 Hans de Goede <hdegoede@redhat.com>
- *
- * Strongly based on qc-usb-messenger, which is:
- * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
- * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
- * Copyright (c) 2002, 2003 Tuukka Toivonen
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef STV06XX_ST6422_H_
-#define STV06XX_ST6422_H_
-
-#include "stv06xx_sensor.h"
-
-static int st6422_probe(struct sd *sd);
-static int st6422_start(struct sd *sd);
-static int st6422_init(struct sd *sd);
-static int st6422_init_controls(struct sd *sd);
-static int st6422_stop(struct sd *sd);
-
-const struct stv06xx_sensor stv06xx_sensor_st6422 = {
- .name = "ST6422",
- /* No known way to lower framerate in case of less bandwidth */
- .min_packet_size = { 300, 847 },
- .max_packet_size = { 300, 847 },
- .init = st6422_init,
- .init_controls = st6422_init_controls,
- .probe = st6422_probe,
- .start = st6422_start,
- .stop = st6422_stop,
-};
-
-#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
deleted file mode 100644
index 748e1421d6d..00000000000
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
- * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
- * Copyright (c) 2002, 2003 Tuukka Toivonen
- * Copyright (c) 2008 Erik Andrén
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * P/N 861037: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
- * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
- * P/N 861075-0040: Sensor HDCS1000 ASIC
- * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
- * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "stv06xx_vv6410.h"
-
-static struct v4l2_pix_format vv6410_mode[] = {
- {
- 356,
- 292,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage = 356 * 292,
- .bytesperline = 356,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- }
-};
-
-static int vv6410_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- int err = -EINVAL;
-
- switch (ctrl->id) {
- case V4L2_CID_HFLIP:
- err = vv6410_set_hflip(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_VFLIP:
- err = vv6410_set_vflip(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_GAIN:
- err = vv6410_set_analog_gain(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_EXPOSURE:
- err = vv6410_set_exposure(gspca_dev, ctrl->val);
- break;
- }
- return err;
-}
-
-static const struct v4l2_ctrl_ops vv6410_ctrl_ops = {
- .s_ctrl = vv6410_s_ctrl,
-};
-
-static int vv6410_probe(struct sd *sd)
-{
- u16 data;
- int err;
-
- err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data);
- if (err < 0)
- return -ENODEV;
-
- if (data != 0x19)
- return -ENODEV;
-
- pr_info("vv6410 sensor detected\n");
-
- sd->gspca_dev.cam.cam_mode = vv6410_mode;
- sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode);
- return 0;
-}
-
-static int vv6410_init_controls(struct sd *sd)
-{
- struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
-
- v4l2_ctrl_handler_init(hdl, 4);
- v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 32768, 1, 20000);
- v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops,
- V4L2_CID_GAIN, 0, 15, 1, 10);
- return hdl->error;
-}
-
-static int vv6410_init(struct sd *sd)
-{
- int err = 0, i;
-
- for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++)
- stv06xx_write_bridge(sd, stv_bridge_init[i].addr, stv_bridge_init[i].data);
-
- if (err < 0)
- return err;
-
- err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init,
- ARRAY_SIZE(vv6410_sensor_init));
- return (err < 0) ? err : 0;
-}
-
-static int vv6410_start(struct sd *sd)
-{
- int err;
- struct cam *cam = &sd->gspca_dev.cam;
- u32 priv = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
-
- if (priv & VV6410_SUBSAMPLE) {
- PDEBUG(D_CONF, "Enabling subsampling");
- stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02);
- stv06xx_write_bridge(sd, STV_X_CTRL, 0x06);
-
- stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10);
- } else {
- stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01);
- stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a);
- stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x00);
-
- }
-
- /* Turn on LED */
- err = stv06xx_write_bridge(sd, STV_LED_CTRL, LED_ON);
- if (err < 0)
- return err;
-
- err = stv06xx_write_sensor(sd, VV6410_SETUP0, 0);
- if (err < 0)
- return err;
-
- PDEBUG(D_STREAM, "Starting stream");
-
- return 0;
-}
-
-static int vv6410_stop(struct sd *sd)
-{
- int err;
-
- /* Turn off LED */
- err = stv06xx_write_bridge(sd, STV_LED_CTRL, LED_OFF);
- if (err < 0)
- return err;
-
- err = stv06xx_write_sensor(sd, VV6410_SETUP0, VV6410_LOW_POWER_MODE);
- if (err < 0)
- return err;
-
- PDEBUG(D_STREAM, "Halting stream");
-
- return (err < 0) ? err : 0;
-}
-
-static int vv6410_dump(struct sd *sd)
-{
- u8 i;
- int err = 0;
-
- pr_info("Dumping all vv6410 sensor registers\n");
- for (i = 0; i < 0xff && !err; i++) {
- u16 data;
- err = stv06xx_read_sensor(sd, i, &data);
- pr_info("Register 0x%x contained 0x%x\n", i, data);
- }
- return (err < 0) ? err : 0;
-}
-
-static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u16 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
-
- err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
- if (err < 0)
- return err;
-
- if (val)
- i2c_data |= VV6410_HFLIP;
- else
- i2c_data &= ~VV6410_HFLIP;
-
- PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
- err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data);
-
- return (err < 0) ? err : 0;
-}
-
-static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- u16 i2c_data;
- struct sd *sd = (struct sd *) gspca_dev;
-
- err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
- if (err < 0)
- return err;
-
- if (val)
- i2c_data |= VV6410_VFLIP;
- else
- i2c_data &= ~VV6410_VFLIP;
-
- PDEBUG(D_V4L2, "Set vertical flip to %d", val);
- err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data);
-
- return (err < 0) ? err : 0;
-}
-
-static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- struct sd *sd = (struct sd *) gspca_dev;
-
- PDEBUG(D_V4L2, "Set analog gain to %d", val);
- err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf));
-
- return (err < 0) ? err : 0;
-}
-
-static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
-{
- int err;
- struct sd *sd = (struct sd *) gspca_dev;
- unsigned int fine, coarse;
-
- val = (val * val >> 14) + val / 4;
-
- fine = val % VV6410_CIF_LINELENGTH;
- coarse = min(512, val / VV6410_CIF_LINELENGTH);
-
- PDEBUG(D_V4L2, "Set coarse exposure to %d, fine expsure to %d",
- coarse, fine);
-
- err = stv06xx_write_sensor(sd, VV6410_FINEH, fine >> 8);
- if (err < 0)
- goto out;
-
- err = stv06xx_write_sensor(sd, VV6410_FINEL, fine & 0xff);
- if (err < 0)
- goto out;
-
- err = stv06xx_write_sensor(sd, VV6410_COARSEH, coarse >> 8);
- if (err < 0)
- goto out;
-
- err = stv06xx_write_sensor(sd, VV6410_COARSEL, coarse & 0xff);
-
-out:
- return err;
-}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
deleted file mode 100644
index 53e67b40ca0..00000000000
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
- * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
- * Copyright (c) 2002, 2003 Tuukka Toivonen
- * Copyright (c) 2008 Erik Andrén
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * P/N 861037: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
- * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
- * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
- * P/N 861075-0040: Sensor HDCS1000 ASIC
- * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
- * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
- */
-
-#ifndef STV06XX_VV6410_H_
-#define STV06XX_VV6410_H_
-
-#include "stv06xx_sensor.h"
-
-#define VV6410_COLS 416
-#define VV6410_ROWS 320
-
-/* Status registers */
-/* Chip identification number including revision indicator */
-#define VV6410_DEVICEH 0x00
-#define VV6410_DEVICEL 0x01
-
-/* User can determine whether timed I2C data
- has been consumed by interrogating flag states */
-#define VV6410_STATUS0 0x02
-
-/* Current line counter value */
-#define VV6410_LINECOUNTH 0x03
-#define VV6410_LINECOUNTL 0x04
-
-/* End x coordinate of image size */
-#define VV6410_XENDH 0x05
-#define VV6410_XENDL 0x06
-
-/* End y coordinate of image size */
-#define VV6410_YENDH 0x07
-#define VV6410_YENDL 0x08
-
-/* This is the average pixel value returned from the
- dark line offset cancellation algorithm */
-#define VV6410_DARKAVGH 0x09
-#define VV6410_DARKAVGL 0x0a
-
-/* This is the average pixel value returned from the
- black line offset cancellation algorithm */
-#define VV6410_BLACKAVGH 0x0b
-#define VV6410_BLACKAVGL 0x0c
-
-/* Flags to indicate whether the x or y image coordinates have been clipped */
-#define VV6410_STATUS1 0x0d
-
-/* Setup registers */
-
-/* Low-power/sleep modes & video timing */
-#define VV6410_SETUP0 0x10
-
-/* Various parameters */
-#define VV6410_SETUP1 0x11
-
-/* Contains pixel counter reset value used by external sync */
-#define VV6410_SYNCVALUE 0x12
-
-/* Frame grabbing modes (FST, LST and QCK) */
-#define VV6410_FGMODES 0x14
-
-/* FST and QCK mapping modes. */
-#define VV6410_PINMAPPING 0x15
-
-/* Data resolution */
-#define VV6410_DATAFORMAT 0x16
-
-/* Output coding formats */
-#define VV6410_OPFORMAT 0x17
-
-/* Various mode select bits */
-#define VV6410_MODESELECT 0x18
-
-/* Exposure registers */
-/* Fine exposure. */
-#define VV6410_FINEH 0x20
-#define VV6410_FINEL 0x21
-
-/* Coarse exposure */
-#define VV6410_COARSEH 0x22
-#define VV6410_COARSEL 0x23
-
-/* Analog gain setting */
-#define VV6410_ANALOGGAIN 0x24
-
-/* Clock division */
-#define VV6410_CLKDIV 0x25
-
-/* Dark line offset cancellation value */
-#define VV6410_DARKOFFSETH 0x2c
-#define VV6410_DARKOFFSETL 0x2d
-
-/* Dark line offset cancellation enable */
-#define VV6410_DARKOFFSETSETUP 0x2e
-
-/* Video timing registers */
-/* Line Length (Pixel Clocks) */
-#define VV6410_LINELENGTHH 0x52
-#define VV6410_LINELENGTHL 0x53
-
-/* X-co-ordinate of top left corner of region of interest (x-offset) */
-#define VV6410_XOFFSETH 0x57
-#define VV6410_XOFFSETL 0x58
-
-/* Y-coordinate of top left corner of region of interest (y-offset) */
-#define VV6410_YOFFSETH 0x59
-#define VV6410_YOFFSETL 0x5a
-
-/* Field length (Lines) */
-#define VV6410_FIELDLENGTHH 0x61
-#define VV6410_FIELDLENGTHL 0x62
-
-/* System registers */
-/* Black offset cancellation default value */
-#define VV6410_BLACKOFFSETH 0x70
-#define VV6410_BLACKOFFSETL 0x71
-
-/* Black offset cancellation setup */
-#define VV6410_BLACKOFFSETSETUP 0x72
-
-/* Analog Control Register 0 */
-#define VV6410_CR0 0x75
-
-/* Analog Control Register 1 */
-#define VV6410_CR1 0x76
-
-/* ADC Setup Register */
-#define VV6410_AS0 0x77
-
-/* Analog Test Register */
-#define VV6410_AT0 0x78
-
-/* Audio Amplifier Setup Register */
-#define VV6410_AT1 0x79
-
-#define VV6410_HFLIP (1 << 3)
-#define VV6410_VFLIP (1 << 4)
-
-#define VV6410_LOW_POWER_MODE (1 << 0)
-#define VV6410_SOFT_RESET (1 << 2)
-#define VV6410_PAL_25_FPS (0 << 3)
-
-#define VV6410_CLK_DIV_2 (1 << 1)
-
-#define VV6410_FINE_EXPOSURE 320
-#define VV6410_COARSE_EXPOSURE 192
-#define VV6410_DEFAULT_GAIN 5
-
-#define VV6410_SUBSAMPLE 0x01
-#define VV6410_CROP_TO_QVGA 0x02
-
-#define VV6410_CIF_LINELENGTH 415
-
-static int vv6410_probe(struct sd *sd);
-static int vv6410_start(struct sd *sd);
-static int vv6410_init(struct sd *sd);
-static int vv6410_init_controls(struct sd *sd);
-static int vv6410_stop(struct sd *sd);
-static int vv6410_dump(struct sd *sd);
-
-/* V4L2 controls supported by the driver */
-static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val);
-static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-
-const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
- .name = "ST VV6410",
- .i2c_flush = 5,
- .i2c_addr = 0x20,
- .i2c_len = 1,
- /* FIXME (see if we can lower packet_size-s, needs testing, and also
- adjusting framerate when the bandwidth gets lower) */
- .min_packet_size = { 1023 },
- .max_packet_size = { 1023 },
- .init = vv6410_init,
- .init_controls = vv6410_init_controls,
- .probe = vv6410_probe,
- .start = vv6410_start,
- .stop = vv6410_stop,
- .dump = vv6410_dump,
-};
-
-/* If NULL, only single value to write, stored in len */
-struct stv_init {
- u16 addr;
- u8 data;
-};
-
-static const struct stv_init stv_bridge_init[] = {
- /* This reg is written twice. Some kind of reset? */
- {STV_RESET, 0x80},
- {STV_RESET, 0x00},
- {STV_SCAN_RATE, 0x00},
- {STV_I2C_FLUSH, 0x04},
- {STV_REG00, 0x0b},
- {STV_REG01, 0xa7},
- {STV_REG02, 0xb7},
- {STV_REG03, 0x00},
- {STV_REG04, 0x00},
- {0x1536, 0x02},
- {0x1537, 0x00},
- {0x1538, 0x60},
- {0x1539, 0x01},
- {0x153a, 0x20},
- {0x153b, 0x01},
-};
-
-static const u8 vv6410_sensor_init[][2] = {
- /* Setup registers */
- {VV6410_SETUP0, VV6410_SOFT_RESET},
- {VV6410_SETUP0, VV6410_LOW_POWER_MODE},
- /* Use shuffled read-out mode */
- {VV6410_SETUP1, BIT(6)},
- /* All modes to 1, FST, Fast QCK, Free running QCK, Free running LST, FST will qualify visible pixels */
- {VV6410_FGMODES, BIT(6) | BIT(4) | BIT(2) | BIT(0)},
- {VV6410_PINMAPPING, 0x00},
- /* Pre-clock generator divide off */
- {VV6410_DATAFORMAT, BIT(7) | BIT(0)},
-
- {VV6410_CLKDIV, VV6410_CLK_DIV_2},
-
- /* System registers */
- /* Enable voltage doubler */
- {VV6410_AS0, BIT(6) | BIT(4) | BIT(3) | BIT(2) | BIT(1)},
- {VV6410_AT0, 0x00},
- /* Power up audio, differential */
- {VV6410_AT1, BIT(4) | BIT(0)},
-};
-
-#endif
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
deleted file mode 100644
index 9ccfcb1c647..00000000000
--- a/drivers/media/video/gspca/sunplus.c
+++ /dev/null
@@ -1,1085 +0,0 @@
-/*
- * Sunplus spca504(abc) spca533 spca536 library
- * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
- *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "sunplus"
-
-#include "gspca.h"
-#include "jpeg.h"
-
-MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
-MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-#define QUALITY 85
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- bool autogain;
-
- u8 bridge;
-#define BRIDGE_SPCA504 0
-#define BRIDGE_SPCA504B 1
-#define BRIDGE_SPCA504C 2
-#define BRIDGE_SPCA533 3
-#define BRIDGE_SPCA536 4
- u8 subtype;
-#define AiptekMiniPenCam13 1
-#define LogitechClickSmart420 2
-#define LogitechClickSmart820 3
-#define MegapixV4 4
-#define MegaImageVI 5
-
- u8 jpeg_hdr[JPEG_HDR_SZ];
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
-};
-
-static const struct v4l2_pix_format custom_mode[] = {
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2},
- {464, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 464,
- .sizeimage = 464 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
-};
-
-static const struct v4l2_pix_format vga_mode2[] = {
- {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 4},
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 3},
- {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
-};
-
-#define SPCA50X_OFFSET_DATA 10
-#define SPCA504_PCCAM600_OFFSET_SNAPSHOT 3
-#define SPCA504_PCCAM600_OFFSET_COMPRESS 4
-#define SPCA504_PCCAM600_OFFSET_MODE 5
-#define SPCA504_PCCAM600_OFFSET_DATA 14
- /* Frame packet header offsets for the spca533 */
-#define SPCA533_OFFSET_DATA 16
-#define SPCA533_OFFSET_FRAMSEQ 15
-/* Frame packet header offsets for the spca536 */
-#define SPCA536_OFFSET_DATA 4
-#define SPCA536_OFFSET_FRAMSEQ 1
-
-struct cmd {
- u8 req;
- u16 val;
- u16 idx;
-};
-
-/* Initialisation data for the Creative PC-CAM 600 */
-static const struct cmd spca504_pccam600_init_data[] = {
-/* {0xa0, 0x0000, 0x0503}, * capture mode */
- {0x00, 0x0000, 0x2000},
- {0x00, 0x0013, 0x2301},
- {0x00, 0x0003, 0x2000},
- {0x00, 0x0001, 0x21ac},
- {0x00, 0x0001, 0x21a6},
- {0x00, 0x0000, 0x21a7}, /* brightness */
- {0x00, 0x0020, 0x21a8}, /* contrast */
- {0x00, 0x0001, 0x21ac}, /* sat/hue */
- {0x00, 0x0000, 0x21ad}, /* hue */
- {0x00, 0x001a, 0x21ae}, /* saturation */
- {0x00, 0x0002, 0x21a3}, /* gamma */
- {0x30, 0x0154, 0x0008},
- {0x30, 0x0004, 0x0006},
- {0x30, 0x0258, 0x0009},
- {0x30, 0x0004, 0x0000},
- {0x30, 0x0093, 0x0004},
- {0x30, 0x0066, 0x0005},
- {0x00, 0x0000, 0x2000},
- {0x00, 0x0013, 0x2301},
- {0x00, 0x0003, 0x2000},
- {0x00, 0x0013, 0x2301},
- {0x00, 0x0003, 0x2000},
-};
-
-/* Creative PC-CAM 600 specific open data, sent before using the
- * generic initialisation data from spca504_open_data.
- */
-static const struct cmd spca504_pccam600_open_data[] = {
- {0x00, 0x0001, 0x2501},
- {0x20, 0x0500, 0x0001}, /* snapshot mode */
- {0x00, 0x0003, 0x2880},
- {0x00, 0x0001, 0x2881},
-};
-
-/* Initialisation data for the logitech clicksmart 420 */
-static const struct cmd spca504A_clicksmart420_init_data[] = {
-/* {0xa0, 0x0000, 0x0503}, * capture mode */
- {0x00, 0x0000, 0x2000},
- {0x00, 0x0013, 0x2301},
- {0x00, 0x0003, 0x2000},
- {0x00, 0x0001, 0x21ac},
- {0x00, 0x0001, 0x21a6},
- {0x00, 0x0000, 0x21a7}, /* brightness */
- {0x00, 0x0020, 0x21a8}, /* contrast */
- {0x00, 0x0001, 0x21ac}, /* sat/hue */
- {0x00, 0x0000, 0x21ad}, /* hue */
- {0x00, 0x001a, 0x21ae}, /* saturation */
- {0x00, 0x0002, 0x21a3}, /* gamma */
- {0x30, 0x0004, 0x000a},
- {0xb0, 0x0001, 0x0000},
-
- {0xa1, 0x0080, 0x0001},
- {0x30, 0x0049, 0x0000},
- {0x30, 0x0060, 0x0005},
- {0x0c, 0x0004, 0x0000},
- {0x00, 0x0000, 0x0000},
- {0x00, 0x0000, 0x2000},
- {0x00, 0x0013, 0x2301},
- {0x00, 0x0003, 0x2000},
-};
-
-/* clicksmart 420 open data ? */
-static const struct cmd spca504A_clicksmart420_open_data[] = {
- {0x00, 0x0001, 0x2501},
- {0x20, 0x0502, 0x0000},
- {0x06, 0x0000, 0x0000},
- {0x00, 0x0004, 0x2880},
- {0x00, 0x0001, 0x2881},
-
- {0xa0, 0x0000, 0x0503},
-};
-
-static const u8 qtable_creative_pccam[2][64] = {
- { /* Q-table Y-components */
- 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
- 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
- 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
- 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
- 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
- 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
- 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
- 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
- { /* Q-table C-components */
- 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
-};
-
-/* FIXME: This Q-table is identical to the Creative PC-CAM one,
- * except for one byte. Possibly a typo?
- * NWG: 18/05/2003.
- */
-static const u8 qtable_spca504_default[2][64] = {
- { /* Q-table Y-components */
- 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
- 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
- 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
- 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
- 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
- 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
- 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
- 0x16, 0x1c, 0x1d, 0x1d, 0x1d /* 0x22 */ , 0x1e, 0x1f, 0x1e,
- },
- { /* Q-table C-components */
- 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
-};
-
-/* read <len> bytes to gspca_dev->usb_buf */
-static void reg_r(struct gspca_dev *gspca_dev,
- u8 req,
- u16 index,
- u16 len)
-{
- int ret;
-
-#ifdef GSPCA_DEBUG
- if (len > USB_BUF_SZ) {
- pr_err("reg_r: buffer overflow\n");
- return;
- }
-#endif
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, /* value */
- index,
- len ? gspca_dev->usb_buf : NULL, len,
- 500);
- if (ret < 0) {
- pr_err("reg_r err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-/* write one byte */
-static void reg_w_1(struct gspca_dev *gspca_dev,
- u8 req,
- u16 value,
- u16 index,
- u16 byte)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- gspca_dev->usb_buf[0] = byte;
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index,
- gspca_dev->usb_buf, 1,
- 500);
- if (ret < 0) {
- pr_err("reg_w_1 err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-/* write req / index / value */
-static void reg_w_riv(struct gspca_dev *gspca_dev,
- u8 req, u16 index, u16 value)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(dev,
- usb_sndctrlpipe(dev, 0),
- req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, NULL, 0, 500);
- if (ret < 0) {
- pr_err("reg_w_riv err %d\n", ret);
- gspca_dev->usb_err = ret;
- return;
- }
- PDEBUG(D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x",
- req, index, value);
-}
-
-static void write_vector(struct gspca_dev *gspca_dev,
- const struct cmd *data, int ncmds)
-{
- while (--ncmds >= 0) {
- reg_w_riv(gspca_dev, data->req, data->idx, data->val);
- data++;
- }
-}
-
-static void setup_qtable(struct gspca_dev *gspca_dev,
- const u8 qtable[2][64])
-{
- int i;
-
- /* loop over y components */
- for (i = 0; i < 64; i++)
- reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]);
-
- /* loop over c components */
- for (i = 0; i < 64; i++)
- reg_w_riv(gspca_dev, 0x00, 0x2840 + i, qtable[1][i]);
-}
-
-static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
- u8 req, u16 idx, u16 val)
-{
- reg_w_riv(gspca_dev, req, idx, val);
- reg_r(gspca_dev, 0x01, 0x0001, 1);
- PDEBUG(D_FRAM, "before wait 0x%04x", gspca_dev->usb_buf[0]);
- reg_w_riv(gspca_dev, req, idx, val);
-
- msleep(200);
- reg_r(gspca_dev, 0x01, 0x0001, 1);
- PDEBUG(D_FRAM, "after wait 0x%04x", gspca_dev->usb_buf[0]);
-}
-
-#ifdef GSPCA_DEBUG
-static void spca504_read_info(struct gspca_dev *gspca_dev)
-{
- int i;
- u8 info[6];
-
- for (i = 0; i < 6; i++) {
- reg_r(gspca_dev, 0, i, 1);
- info[i] = gspca_dev->usb_buf[0];
- }
- PDEBUG(D_STREAM,
- "Read info: %d %d %d %d %d %d."
- " Should be 1,0,2,2,0,0",
- info[0], info[1], info[2],
- info[3], info[4], info[5]);
-}
-#endif
-
-static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
- u8 req,
- u16 idx, u16 val, u8 endcode, u8 count)
-{
- u16 status;
-
- reg_w_riv(gspca_dev, req, idx, val);
- reg_r(gspca_dev, 0x01, 0x0001, 1);
- if (gspca_dev->usb_err < 0)
- return;
- PDEBUG(D_FRAM, "Status 0x%02x Need 0x%02x",
- gspca_dev->usb_buf[0], endcode);
- if (!count)
- return;
- count = 200;
- while (--count > 0) {
- msleep(10);
- /* gsmart mini2 write a each wait setting 1 ms is enough */
-/* reg_w_riv(gspca_dev, req, idx, val); */
- reg_r(gspca_dev, 0x01, 0x0001, 1);
- status = gspca_dev->usb_buf[0];
- if (status == endcode) {
- PDEBUG(D_FRAM, "status 0x%04x after wait %d",
- status, 200 - count);
- break;
- }
- }
-}
-
-static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
-{
- int count = 10;
-
- while (--count > 0) {
- reg_r(gspca_dev, 0x21, 0, 1);
- if ((gspca_dev->usb_buf[0] & 0x01) == 0)
- break;
- msleep(10);
- }
-}
-
-static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
-{
- int count = 50;
-
- while (--count > 0) {
- reg_r(gspca_dev, 0x21, 1, 1);
- if (gspca_dev->usb_buf[0] != 0) {
- reg_w_1(gspca_dev, 0x21, 0, 1, 0);
- reg_r(gspca_dev, 0x21, 1, 1);
- spca504B_PollingDataReady(gspca_dev);
- break;
- }
- msleep(10);
- }
-}
-
-#ifdef GSPCA_DEBUG
-static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
-{
- u8 *data;
-
- data = gspca_dev->usb_buf;
- reg_r(gspca_dev, 0x20, 0, 5);
- PDEBUG(D_STREAM, "FirmWare: %d %d %d %d %d",
- data[0], data[1], data[2], data[3], data[4]);
- reg_r(gspca_dev, 0x23, 0, 64);
- reg_r(gspca_dev, 0x23, 1, 64);
-}
-#endif
-
-static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 Size;
-
- Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
- switch (sd->bridge) {
- case BRIDGE_SPCA533:
- reg_w_riv(gspca_dev, 0x31, 0, 0);
- spca504B_WaitCmdStatus(gspca_dev);
- spca504B_PollingDataReady(gspca_dev);
-#ifdef GSPCA_DEBUG
- spca50x_GetFirmware(gspca_dev);
-#endif
- reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */
- reg_r(gspca_dev, 0x24, 8, 1);
-
- reg_w_1(gspca_dev, 0x25, 0, 4, Size);
- reg_r(gspca_dev, 0x25, 4, 1); /* size */
- spca504B_PollingDataReady(gspca_dev);
-
- /* Init the cam width height with some values get on init ? */
- reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
- spca504B_WaitCmdStatus(gspca_dev);
- spca504B_PollingDataReady(gspca_dev);
- break;
- default:
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA536: */
- reg_w_1(gspca_dev, 0x25, 0, 4, Size);
- reg_r(gspca_dev, 0x25, 4, 1); /* size */
- reg_w_1(gspca_dev, 0x27, 0, 0, 6);
- reg_r(gspca_dev, 0x27, 0, 1); /* type */
- spca504B_PollingDataReady(gspca_dev);
- break;
- case BRIDGE_SPCA504:
- Size += 3;
- if (sd->subtype == AiptekMiniPenCam13) {
- /* spca504a aiptek */
- spca504A_acknowledged_command(gspca_dev,
- 0x08, Size, 0,
- 0x80 | (Size & 0x0f), 1);
- spca504A_acknowledged_command(gspca_dev,
- 1, 3, 0, 0x9f, 0);
- } else {
- spca504_acknowledged_command(gspca_dev, 0x08, Size, 0);
- }
- break;
- case BRIDGE_SPCA504C:
- /* capture mode */
- reg_w_riv(gspca_dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
- reg_w_riv(gspca_dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
- break;
- }
-}
-
-static void spca504_wait_status(struct gspca_dev *gspca_dev)
-{
- int cnt;
-
- cnt = 256;
- while (--cnt > 0) {
- /* With this we get the status, when return 0 it's all ok */
- reg_r(gspca_dev, 0x06, 0x00, 1);
- if (gspca_dev->usb_buf[0] == 0)
- return;
- msleep(10);
- }
-}
-
-static void spca504B_setQtable(struct gspca_dev *gspca_dev)
-{
- reg_w_1(gspca_dev, 0x26, 0, 0, 3);
- reg_r(gspca_dev, 0x26, 0, 1);
- spca504B_PollingDataReady(gspca_dev);
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u16 reg;
-
- reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
- reg_w_riv(gspca_dev, 0x00, reg, val);
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u16 reg;
-
- reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
- reg_w_riv(gspca_dev, 0x00, reg, val);
-}
-
-static void setcolors(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u16 reg;
-
- reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
- reg_w_riv(gspca_dev, 0x00, reg, val);
-}
-
-static void init_ctl_reg(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int pollreg = 1;
-
- switch (sd->bridge) {
- case BRIDGE_SPCA504:
- case BRIDGE_SPCA504C:
- pollreg = 0;
- /* fall thru */
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
- reg_w_riv(gspca_dev, 0, 0x21ad, 0x00); /* hue */
- reg_w_riv(gspca_dev, 0, 0x21ac, 0x01); /* sat/hue */
- reg_w_riv(gspca_dev, 0, 0x21a3, 0x00); /* gamma */
- break;
- case BRIDGE_SPCA536:
- reg_w_riv(gspca_dev, 0, 0x20f5, 0x40);
- reg_w_riv(gspca_dev, 0, 0x20f4, 0x01);
- reg_w_riv(gspca_dev, 0, 0x2089, 0x00);
- break;
- }
- if (pollreg)
- spca504B_PollingDataReady(gspca_dev);
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
-
- cam = &gspca_dev->cam;
-
- sd->bridge = id->driver_info >> 8;
- sd->subtype = id->driver_info;
-
- if (sd->subtype == AiptekMiniPenCam13) {
-
- /* try to get the firmware as some cam answer 2.0.1.2.2
- * and should be a spca504b then overwrite that setting */
- reg_r(gspca_dev, 0x20, 0, 1);
- switch (gspca_dev->usb_buf[0]) {
- case 1:
- break; /* (right bridge/subtype) */
- case 2:
- sd->bridge = BRIDGE_SPCA504B;
- sd->subtype = 0;
- break;
- default:
- return -ENODEV;
- }
- }
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA536: */
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- break;
- case BRIDGE_SPCA533:
- cam->cam_mode = custom_mode;
- if (sd->subtype == MegaImageVI) /* 320x240 only */
- cam->nmodes = ARRAY_SIZE(custom_mode) - 1;
- else
- cam->nmodes = ARRAY_SIZE(custom_mode);
- break;
- case BRIDGE_SPCA504C:
- cam->cam_mode = vga_mode2;
- cam->nmodes = ARRAY_SIZE(vga_mode2);
- break;
- }
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->bridge) {
- case BRIDGE_SPCA504B:
- reg_w_riv(gspca_dev, 0x1d, 0x00, 0);
- reg_w_riv(gspca_dev, 0x00, 0x2306, 0x01);
- reg_w_riv(gspca_dev, 0x00, 0x0d04, 0x00);
- reg_w_riv(gspca_dev, 0x00, 0x2000, 0x00);
- reg_w_riv(gspca_dev, 0x00, 0x2301, 0x13);
- reg_w_riv(gspca_dev, 0x00, 0x2306, 0x00);
- /* fall thru */
- case BRIDGE_SPCA533:
- spca504B_PollingDataReady(gspca_dev);
-#ifdef GSPCA_DEBUG
- spca50x_GetFirmware(gspca_dev);
-#endif
- break;
- case BRIDGE_SPCA536:
-#ifdef GSPCA_DEBUG
- spca50x_GetFirmware(gspca_dev);
-#endif
- reg_r(gspca_dev, 0x00, 0x5002, 1);
- reg_w_1(gspca_dev, 0x24, 0, 0, 0);
- reg_r(gspca_dev, 0x24, 0, 1);
- spca504B_PollingDataReady(gspca_dev);
- reg_w_riv(gspca_dev, 0x34, 0, 0);
- spca504B_WaitCmdStatus(gspca_dev);
- break;
- case BRIDGE_SPCA504C: /* pccam600 */
- PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
- reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000);
- reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001); /* reset */
- spca504_wait_status(gspca_dev);
- if (sd->subtype == LogitechClickSmart420)
- write_vector(gspca_dev,
- spca504A_clicksmart420_open_data,
- ARRAY_SIZE(spca504A_clicksmart420_open_data));
- else
- write_vector(gspca_dev, spca504_pccam600_open_data,
- ARRAY_SIZE(spca504_pccam600_open_data));
- setup_qtable(gspca_dev, qtable_creative_pccam);
- break;
- default:
-/* case BRIDGE_SPCA504: */
- PDEBUG(D_STREAM, "Opening SPCA504");
- if (sd->subtype == AiptekMiniPenCam13) {
-#ifdef GSPCA_DEBUG
- spca504_read_info(gspca_dev);
-#endif
-
- /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
- spca504A_acknowledged_command(gspca_dev, 0x24,
- 8, 3, 0x9e, 1);
- /* Twice sequential need status 0xff->0x9e->0x9d */
- spca504A_acknowledged_command(gspca_dev, 0x24,
- 8, 3, 0x9e, 0);
-
- spca504A_acknowledged_command(gspca_dev, 0x24,
- 0, 0, 0x9d, 1);
- /******************************/
- /* spca504a aiptek */
- spca504A_acknowledged_command(gspca_dev, 0x08,
- 6, 0, 0x86, 1);
-/* reg_write (dev, 0, 0x2000, 0); */
-/* reg_write (dev, 0, 0x2883, 1); */
-/* spca504A_acknowledged_command (gspca_dev, 0x08,
- 6, 0, 0x86, 1); */
-/* spca504A_acknowledged_command (gspca_dev, 0x24,
- 0, 0, 0x9D, 1); */
- reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
- /* L92 sno1t.txt */
- reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
- spca504A_acknowledged_command(gspca_dev, 0x01,
- 0x0f, 0, 0xff, 0);
- }
- /* setup qtable */
- reg_w_riv(gspca_dev, 0, 0x2000, 0);
- reg_w_riv(gspca_dev, 0, 0x2883, 1);
- setup_qtable(gspca_dev, qtable_spca504_default);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int enable;
-
- /* create the JPEG header */
- jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
- 0x22); /* JPEG 411 */
- jpeg_set_qual(sd->jpeg_hdr, QUALITY);
-
- if (sd->bridge == BRIDGE_SPCA504B)
- spca504B_setQtable(gspca_dev);
- spca504B_SetSizeType(gspca_dev);
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA536: */
- switch (sd->subtype) {
- case MegapixV4:
- case LogitechClickSmart820:
- case MegaImageVI:
- reg_w_riv(gspca_dev, 0xf0, 0, 0);
- spca504B_WaitCmdStatus(gspca_dev);
- reg_r(gspca_dev, 0xf0, 4, 0);
- spca504B_WaitCmdStatus(gspca_dev);
- break;
- default:
- reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
- spca504B_WaitCmdStatus(gspca_dev);
- spca504B_PollingDataReady(gspca_dev);
- break;
- }
- break;
- case BRIDGE_SPCA504:
- if (sd->subtype == AiptekMiniPenCam13) {
-#ifdef GSPCA_DEBUG
- spca504_read_info(gspca_dev);
-#endif
-
- /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
- spca504A_acknowledged_command(gspca_dev, 0x24,
- 8, 3, 0x9e, 1);
- /* Twice sequential need status 0xff->0x9e->0x9d */
- spca504A_acknowledged_command(gspca_dev, 0x24,
- 8, 3, 0x9e, 0);
- spca504A_acknowledged_command(gspca_dev, 0x24,
- 0, 0, 0x9d, 1);
- } else {
- spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
-#ifdef GSPCA_DEBUG
- spca504_read_info(gspca_dev);
-#endif
- spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
- spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
- }
- spca504B_SetSizeType(gspca_dev);
- reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
- /* L92 sno1t.txt */
- reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
- break;
- case BRIDGE_SPCA504C:
- if (sd->subtype == LogitechClickSmart420) {
- write_vector(gspca_dev,
- spca504A_clicksmart420_init_data,
- ARRAY_SIZE(spca504A_clicksmart420_init_data));
- } else {
- write_vector(gspca_dev, spca504_pccam600_init_data,
- ARRAY_SIZE(spca504_pccam600_init_data));
- }
- enable = (sd->autogain ? 0x04 : 0x01);
- reg_w_riv(gspca_dev, 0x0c, 0x0000, enable);
- /* auto exposure */
- reg_w_riv(gspca_dev, 0xb0, 0x0000, enable);
- /* auto whiteness */
-
- /* set default exposure compensation and whiteness balance */
- reg_w_riv(gspca_dev, 0x30, 0x0001, 800); /* ~ 20 fps */
- reg_w_riv(gspca_dev, 0x30, 0x0002, 1600);
- spca504B_SetSizeType(gspca_dev);
- break;
- }
- init_ctl_reg(gspca_dev);
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA536: */
-/* case BRIDGE_SPCA504B: */
- reg_w_riv(gspca_dev, 0x31, 0, 0);
- spca504B_WaitCmdStatus(gspca_dev);
- spca504B_PollingDataReady(gspca_dev);
- break;
- case BRIDGE_SPCA504:
- case BRIDGE_SPCA504C:
- reg_w_riv(gspca_dev, 0x00, 0x2000, 0x0000);
-
- if (sd->subtype == AiptekMiniPenCam13) {
- /* spca504a aiptek */
-/* spca504A_acknowledged_command(gspca_dev, 0x08,
- 6, 0, 0x86, 1); */
- spca504A_acknowledged_command(gspca_dev, 0x24,
- 0x00, 0x00, 0x9d, 1);
- spca504A_acknowledged_command(gspca_dev, 0x01,
- 0x0f, 0x00, 0xff, 1);
- } else {
- spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
- reg_w_riv(gspca_dev, 0x01, 0x000f, 0x0000);
- }
- break;
- }
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i, sof = 0;
- static u8 ffd9[] = {0xff, 0xd9};
-
-/* frames are jpeg 4.1.1 without 0xff escape */
- switch (sd->bridge) {
- case BRIDGE_SPCA533:
- if (data[0] == 0xff) {
- if (data[1] != 0x01) { /* drop packet */
-/* gspca_dev->last_packet_type = DISCARD_PACKET; */
- return;
- }
- sof = 1;
- data += SPCA533_OFFSET_DATA;
- len -= SPCA533_OFFSET_DATA;
- } else {
- data += 1;
- len -= 1;
- }
- break;
- case BRIDGE_SPCA536:
- if (data[0] == 0xff) {
- sof = 1;
- data += SPCA536_OFFSET_DATA;
- len -= SPCA536_OFFSET_DATA;
- } else {
- data += 2;
- len -= 2;
- }
- break;
- default:
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504B: */
- switch (data[0]) {
- case 0xfe: /* start of frame */
- sof = 1;
- data += SPCA50X_OFFSET_DATA;
- len -= SPCA50X_OFFSET_DATA;
- break;
- case 0xff: /* drop packet */
-/* gspca_dev->last_packet_type = DISCARD_PACKET; */
- return;
- default:
- data += 1;
- len -= 1;
- break;
- }
- break;
- case BRIDGE_SPCA504C:
- switch (data[0]) {
- case 0xfe: /* start of frame */
- sof = 1;
- data += SPCA504_PCCAM600_OFFSET_DATA;
- len -= SPCA504_PCCAM600_OFFSET_DATA;
- break;
- case 0xff: /* drop packet */
-/* gspca_dev->last_packet_type = DISCARD_PACKET; */
- return;
- default:
- data += 1;
- len -= 1;
- break;
- }
- break;
- }
- if (sof) { /* start of frame */
- gspca_frame_add(gspca_dev, LAST_PACKET,
- ffd9, 2);
-
- /* put the JPEG header in the new frame */
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sd->jpeg_hdr, JPEG_HDR_SZ);
- }
-
- /* add 0x00 after 0xff */
- i = 0;
- do {
- if (data[i] == 0xff) {
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data, i + 1);
- len -= i;
- data += i;
- *data = 0x00;
- i = 0;
- }
- i++;
- } while (i < len);
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- setcolors(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_AUTOGAIN:
- sd->autogain = ctrl->val;
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 4);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 0x20);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, 0x1a);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-#define BS(bridge, subtype) \
- .driver_info = (BRIDGE_ ## bridge << 8) \
- | (subtype)
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
- {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
- {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},
- {USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)},
- {USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)},
- {USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)},
- {USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)},
- {USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)},
- {USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)},
- {USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)},
- {USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)},
- {USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)},
- {USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)},
- {USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)},
- {USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)},
- {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
- {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
- {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
- {USB_DEVICE(0x052b, 0x1507), BS(SPCA533, MegapixV4)},
- {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
- {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
- {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
- {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
- {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
- {USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)},
- {USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)},
- {USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)},
- {USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)},
- {USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)},
- {USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)},
- {USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)},
- {USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)},
- {USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)},
- {USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)},
- {USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)},
- {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)},
- {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)},
- {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)},
- {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)},
- {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)},
- {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)},
- {USB_DEVICE(0x0733, 0x2221), BS(SPCA533, 0)},
- {USB_DEVICE(0x0733, 0x3261), BS(SPCA536, 0)},
- {USB_DEVICE(0x0733, 0x3281), BS(SPCA536, 0)},
- {USB_DEVICE(0x08ca, 0x0104), BS(SPCA533, 0)},
- {USB_DEVICE(0x08ca, 0x0106), BS(SPCA533, 0)},
- {USB_DEVICE(0x08ca, 0x2008), BS(SPCA504B, 0)},
- {USB_DEVICE(0x08ca, 0x2010), BS(SPCA533, 0)},
- {USB_DEVICE(0x08ca, 0x2016), BS(SPCA504B, 0)},
- {USB_DEVICE(0x08ca, 0x2018), BS(SPCA504B, 0)},
- {USB_DEVICE(0x08ca, 0x2020), BS(SPCA533, 0)},
- {USB_DEVICE(0x08ca, 0x2022), BS(SPCA533, 0)},
- {USB_DEVICE(0x08ca, 0x2024), BS(SPCA536, 0)},
- {USB_DEVICE(0x08ca, 0x2028), BS(SPCA533, 0)},
- {USB_DEVICE(0x08ca, 0x2040), BS(SPCA536, 0)},
- {USB_DEVICE(0x08ca, 0x2042), BS(SPCA536, 0)},
- {USB_DEVICE(0x08ca, 0x2050), BS(SPCA536, 0)},
- {USB_DEVICE(0x08ca, 0x2060), BS(SPCA536, 0)},
- {USB_DEVICE(0x0d64, 0x0303), BS(SPCA536, 0)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
deleted file mode 100644
index 8bc6c3ceec2..00000000000
--- a/drivers/media/video/gspca/t613.c
+++ /dev/null
@@ -1,1054 +0,0 @@
-/*
- * T613 subdriver
- *
- * Copyright (C) 2010 Jean-Francois Moine (http://moinejf.free.fr)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *Notes: * t613 + tas5130A
- * * Focus to light do not balance well as in win.
- * Quality in win is not good, but its kinda better.
- * * Fix some "extraneous bytes", most of apps will show the image anyway
- * * Gamma table, is there, but its really doing something?
- * * 7~8 Fps, its ok, max on win its 10.
- * Costantino Leandro
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "t613"
-
-#include <linux/input.h>
-#include <linux/slab.h>
-#include "gspca.h"
-
-MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
-MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- struct v4l2_ctrl *freq;
- struct { /* awb / color gains control cluster */
- struct v4l2_ctrl *awb;
- struct v4l2_ctrl *gain;
- struct v4l2_ctrl *red_balance;
- struct v4l2_ctrl *blue_balance;
- };
-
- u8 sensor;
- u8 button_pressed;
-};
-enum sensors {
- SENSOR_OM6802,
- SENSOR_OTHER,
- SENSOR_TAS5130A,
- SENSOR_LT168G, /* must verify if this is the actual model */
-};
-
-static const struct v4l2_pix_format vga_mode_t16[] = {
- {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 4 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 4},
-#if 0 /* HDG: broken with my test cam, so lets disable it */
- {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 3},
-#endif
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2},
-#if 0 /* HDG: broken with my test cam, so lets disable it */
- {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
-#endif
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-
-/* sensor specific data */
-struct additional_sensor_data {
- const u8 n3[6];
- const u8 *n4, n4sz;
- const u8 reg80, reg8e;
- const u8 nset8[6];
- const u8 data1[10];
- const u8 data2[9];
- const u8 data3[9];
- const u8 data5[6];
- const u8 stream[4];
-};
-
-static const u8 n4_om6802[] = {
- 0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
- 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
- 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
- 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
- 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
- 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
- 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
- 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
- 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46
-};
-static const u8 n4_other[] = {
- 0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
- 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
- 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
- 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
- 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
- 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
- 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
- 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00
-};
-static const u8 n4_tas5130a[] = {
- 0x80, 0x3c, 0x81, 0x68, 0x83, 0xa0, 0x84, 0x20,
- 0x8a, 0x68, 0x8b, 0x58, 0x8c, 0x88, 0x8e, 0xb4,
- 0x8f, 0x24, 0xa1, 0xb1, 0xa2, 0x30, 0xa5, 0x10,
- 0xa6, 0x4a, 0xae, 0x03, 0xb1, 0x44, 0xb2, 0x08,
- 0xb7, 0x06, 0xb9, 0xe7, 0xbb, 0xc4, 0xbc, 0x4a,
- 0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
- 0xc6, 0xda
-};
-static const u8 n4_lt168g[] = {
- 0x66, 0x01, 0x7f, 0x00, 0x80, 0x7c, 0x81, 0x28,
- 0x83, 0x44, 0x84, 0x20, 0x86, 0x20, 0x8a, 0x70,
- 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xa0, 0x8e, 0xb3,
- 0x8f, 0x24, 0xa1, 0xb0, 0xa2, 0x38, 0xa5, 0x20,
- 0xa6, 0x4a, 0xa8, 0xe8, 0xaf, 0x38, 0xb0, 0x68,
- 0xb1, 0x44, 0xb2, 0x88, 0xbb, 0x86, 0xbd, 0x40,
- 0xbe, 0x26, 0xc1, 0x05, 0xc2, 0x88, 0xc5, 0xc0,
- 0xda, 0x8e, 0xdb, 0xca, 0xdc, 0xa8, 0xdd, 0x8c,
- 0xde, 0x44, 0xdf, 0x0c, 0xe9, 0x80
-};
-
-static const struct additional_sensor_data sensor_data[] = {
-[SENSOR_OM6802] = {
- .n3 =
- {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
- .n4 = n4_om6802,
- .n4sz = sizeof n4_om6802,
- .reg80 = 0x3c,
- .reg8e = 0x33,
- .nset8 = {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00},
- .data1 =
- {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
- 0xb3, 0xfc},
- .data2 =
- {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
- 0xff},
- .data3 =
- {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
- 0xff},
- .data5 = /* this could be removed later */
- {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
- .stream =
- {0x0b, 0x04, 0x0a, 0x78},
- },
-[SENSOR_OTHER] = {
- .n3 =
- {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
- .n4 = n4_other,
- .n4sz = sizeof n4_other,
- .reg80 = 0xac,
- .reg8e = 0xb8,
- .nset8 = {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00},
- .data1 =
- {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
- 0xe8, 0xfc},
- .data2 =
- {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
- 0xd9},
- .data3 =
- {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
- 0xd9},
- .data5 =
- {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
- .stream =
- {0x0b, 0x04, 0x0a, 0x00},
- },
-[SENSOR_TAS5130A] = {
- .n3 =
- {0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
- .n4 = n4_tas5130a,
- .n4sz = sizeof n4_tas5130a,
- .reg80 = 0x3c,
- .reg8e = 0xb4,
- .nset8 = {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00},
- .data1 =
- {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
- 0xc8, 0xfc},
- .data2 =
- {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
- 0xe0},
- .data3 =
- {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
- 0xe0},
- .data5 =
- {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
- .stream =
- {0x0b, 0x04, 0x0a, 0x40},
- },
-[SENSOR_LT168G] = {
- .n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00},
- .n4 = n4_lt168g,
- .n4sz = sizeof n4_lt168g,
- .reg80 = 0x7c,
- .reg8e = 0xb3,
- .nset8 = {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00},
- .data1 = {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40,
- 0xb0, 0xf4},
- .data2 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
- 0xff},
- .data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
- 0xff},
- .data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b},
- .stream = {0x0b, 0x04, 0x0a, 0x28},
- },
-};
-
-#define MAX_EFFECTS 7
-static const u8 effects_table[MAX_EFFECTS][6] = {
- {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
- {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
- {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
- {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */
- {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */
- {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */
- {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
-};
-
-#define GAMMA_MAX (15)
-static const u8 gamma_table[GAMMA_MAX+1][17] = {
-/* gamma table from cam1690.ini */
- {0x00, 0x00, 0x01, 0x04, 0x08, 0x0e, 0x16, 0x21, /* 0 */
- 0x2e, 0x3d, 0x50, 0x65, 0x7d, 0x99, 0xb8, 0xdb,
- 0xff},
- {0x00, 0x01, 0x03, 0x08, 0x0e, 0x16, 0x21, 0x2d, /* 1 */
- 0x3c, 0x4d, 0x60, 0x75, 0x8d, 0xa6, 0xc2, 0xe1,
- 0xff},
- {0x00, 0x01, 0x05, 0x0b, 0x12, 0x1c, 0x28, 0x35, /* 2 */
- 0x45, 0x56, 0x69, 0x7e, 0x95, 0xad, 0xc7, 0xe3,
- 0xff},
- {0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f, /* 3 */
- 0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6,
- 0xff},
- {0x00, 0x04, 0x0b, 0x15, 0x20, 0x2d, 0x3b, 0x4a, /* 4 */
- 0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9,
- 0xff},
- {0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58, /* 5 */
- 0x68, 0x79, 0x8b, 0x9d, 0xb0, 0xc4, 0xd7, 0xec,
- 0xff},
- {0x00, 0x0c, 0x1a, 0x29, 0x38, 0x47, 0x57, 0x67, /* 6 */
- 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
- 0xff},
- {0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, /* 7 */
- 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
- 0xff},
- {0x00, 0x15, 0x27, 0x38, 0x49, 0x59, 0x69, 0x79, /* 8 */
- 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe2, 0xf0,
- 0xff},
- {0x00, 0x1c, 0x30, 0x43, 0x54, 0x65, 0x75, 0x84, /* 9 */
- 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd8, 0xe5, 0xf2,
- 0xff},
- {0x00, 0x24, 0x3b, 0x4f, 0x60, 0x70, 0x80, 0x8e, /* 10 */
- 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xdc, 0xe8, 0xf3,
- 0xff},
- {0x00, 0x2a, 0x3c, 0x5d, 0x6e, 0x7e, 0x8d, 0x9b, /* 11 */
- 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
- 0xff},
- {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */
- 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
- 0xff},
- {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */
- 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
- 0xff},
- {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */
- 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
- 0xff},
- {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */
- 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
- 0xff}
-};
-
-static const u8 tas5130a_sensor_init[][8] = {
- {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
- {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
- {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
-};
-
-static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
-
-/* read 1 byte */
-static u8 reg_r(struct gspca_dev *gspca_dev,
- u16 index)
-{
- usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- 0, /* request */
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, /* value */
- index,
- gspca_dev->usb_buf, 1, 500);
- return gspca_dev->usb_buf[0];
-}
-
-static void reg_w(struct gspca_dev *gspca_dev,
- u16 index)
-{
- usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, index,
- NULL, 0, 500);
-}
-
-static void reg_w_buf(struct gspca_dev *gspca_dev,
- const u8 *buffer, u16 len)
-{
- if (len <= USB_BUF_SZ) {
- memcpy(gspca_dev->usb_buf, buffer, len);
- usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x01, 0,
- gspca_dev->usb_buf, len, 500);
- } else {
- u8 *tmpbuf;
-
- tmpbuf = kmemdup(buffer, len, GFP_KERNEL);
- if (!tmpbuf) {
- pr_err("Out of memory\n");
- return;
- }
- usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x01, 0,
- tmpbuf, len, 500);
- kfree(tmpbuf);
- }
-}
-
-/* write values to consecutive registers */
-static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
- u8 reg,
- const u8 *buffer, u16 len)
-{
- int i;
- u8 *p, *tmpbuf;
-
- if (len * 2 <= USB_BUF_SZ) {
- p = tmpbuf = gspca_dev->usb_buf;
- } else {
- p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
- if (!tmpbuf) {
- pr_err("Out of memory\n");
- return;
- }
- }
- i = len;
- while (--i >= 0) {
- *p++ = reg++;
- *p++ = *buffer++;
- }
- usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x01, 0,
- tmpbuf, len * 2, 500);
- if (len * 2 > USB_BUF_SZ)
- kfree(tmpbuf);
-}
-
-static void om6802_sensor_init(struct gspca_dev *gspca_dev)
-{
- int i;
- const u8 *p;
- u8 byte;
- u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
- static const u8 sensor_init[] = {
- 0xdf, 0x6d,
- 0xdd, 0x18,
- 0x5a, 0xe0,
- 0x5c, 0x07,
- 0x5d, 0xb0,
- 0x5e, 0x1e,
- 0x60, 0x71,
- 0xef, 0x00,
- 0xe9, 0x00,
- 0xea, 0x00,
- 0x90, 0x24,
- 0x91, 0xb2,
- 0x82, 0x32,
- 0xfd, 0x41,
- 0x00 /* table end */
- };
-
- reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
- msleep(100);
- i = 4;
- while (--i > 0) {
- byte = reg_r(gspca_dev, 0x0060);
- if (!(byte & 0x01))
- break;
- msleep(100);
- }
- byte = reg_r(gspca_dev, 0x0063);
- if (byte != 0x17) {
- pr_err("Bad sensor reset %02x\n", byte);
- /* continue? */
- }
-
- p = sensor_init;
- while (*p != 0) {
- val[1] = *p++;
- val[3] = *p++;
- if (*p == 0)
- reg_w(gspca_dev, 0x3c80);
- reg_w_buf(gspca_dev, val, sizeof val);
- i = 4;
- while (--i >= 0) {
- msleep(15);
- byte = reg_r(gspca_dev, 0x60);
- if (!(byte & 0x01))
- break;
- }
- }
- msleep(15);
- reg_w(gspca_dev, 0x3c80);
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct cam *cam = &gspca_dev->cam;
-
- cam->cam_mode = vga_mode_t16;
- cam->nmodes = ARRAY_SIZE(vga_mode_t16);
-
- return 0;
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
-{
- u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
-
- if (brightness < 7) {
- set6[1] = 0x26;
- set6[3] = 0x70 - brightness * 0x10;
- } else {
- set6[3] = 0x00 + ((brightness - 7) * 0x10);
- }
-
- reg_w_buf(gspca_dev, set6, sizeof set6);
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, s32 contrast)
-{
- u16 reg_to_write;
-
- if (contrast < 7)
- reg_to_write = 0x8ea9 - contrast * 0x200;
- else
- reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
-
- reg_w(gspca_dev, reg_to_write);
-}
-
-static void setcolors(struct gspca_dev *gspca_dev, s32 val)
-{
- u16 reg_to_write;
-
- reg_to_write = 0x80bb + val * 0x100; /* was 0xc0 */
- reg_w(gspca_dev, reg_to_write);
-}
-
-static void setgamma(struct gspca_dev *gspca_dev, s32 val)
-{
- PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
- reg_w_ixbuf(gspca_dev, 0x90,
- gamma_table[val], sizeof gamma_table[0]);
-}
-
-static void setawb_n_RGB(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 all_gain_reg[8] = {
- 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x80, 0x00 };
- s32 red_gain, blue_gain, green_gain;
-
- green_gain = sd->gain->val;
-
- red_gain = green_gain + sd->red_balance->val;
- if (red_gain > 0x40)
- red_gain = 0x40;
- else if (red_gain < 0x10)
- red_gain = 0x10;
-
- blue_gain = green_gain + sd->blue_balance->val;
- if (blue_gain > 0x40)
- blue_gain = 0x40;
- else if (blue_gain < 0x10)
- blue_gain = 0x10;
-
- all_gain_reg[1] = red_gain;
- all_gain_reg[3] = blue_gain;
- all_gain_reg[5] = green_gain;
- all_gain_reg[7] = sensor_data[sd->sensor].reg80;
- if (!sd->awb->val)
- all_gain_reg[7] &= ~0x04; /* AWB off */
-
- reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
-}
-
-static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
-{
- u16 reg_to_write;
-
- reg_to_write = 0x0aa6 + 0x1000 * val;
-
- reg_w(gspca_dev, reg_to_write);
-}
-
-static void setfreq(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 reg66;
- u8 freq[4] = { 0x66, 0x00, 0xa8, 0xe8 };
-
- switch (sd->sensor) {
- case SENSOR_LT168G:
- if (val != 0)
- freq[3] = 0xa8;
- reg66 = 0x41;
- break;
- case SENSOR_OM6802:
- reg66 = 0xca;
- break;
- default:
- reg66 = 0x40;
- break;
- }
- switch (val) {
- case 0: /* no flicker */
- freq[3] = 0xf0;
- break;
- case 2: /* 60Hz */
- reg66 &= ~0x40;
- break;
- }
- freq[1] = reg66;
-
- reg_w_buf(gspca_dev, freq, sizeof freq);
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- /* some of this registers are not really neded, because
- * they are overriden by setbrigthness, setcontrast, etc,
- * but wont hurt anyway, and can help someone with similar webcam
- * to see the initial parameters.*/
- struct sd *sd = (struct sd *) gspca_dev;
- const struct additional_sensor_data *sensor;
- int i;
- u16 sensor_id;
- u8 test_byte = 0;
-
- static const u8 read_indexs[] =
- { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
- 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
- static const u8 n1[] =
- {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
- static const u8 n2[] =
- {0x08, 0x00};
-
- sensor_id = (reg_r(gspca_dev, 0x06) << 8)
- | reg_r(gspca_dev, 0x07);
- switch (sensor_id & 0xff0f) {
- case 0x0801:
- PDEBUG(D_PROBE, "sensor tas5130a");
- sd->sensor = SENSOR_TAS5130A;
- break;
- case 0x0802:
- PDEBUG(D_PROBE, "sensor lt168g");
- sd->sensor = SENSOR_LT168G;
- break;
- case 0x0803:
- PDEBUG(D_PROBE, "sensor 'other'");
- sd->sensor = SENSOR_OTHER;
- break;
- case 0x0807:
- PDEBUG(D_PROBE, "sensor om6802");
- sd->sensor = SENSOR_OM6802;
- break;
- default:
- pr_err("unknown sensor %04x\n", sensor_id);
- return -EINVAL;
- }
-
- if (sd->sensor == SENSOR_OM6802) {
- reg_w_buf(gspca_dev, n1, sizeof n1);
- i = 5;
- while (--i >= 0) {
- reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
- test_byte = reg_r(gspca_dev, 0x0063);
- msleep(100);
- if (test_byte == 0x17)
- break; /* OK */
- }
- if (i < 0) {
- pr_err("Bad sensor reset %02x\n", test_byte);
- return -EIO;
- }
- reg_w_buf(gspca_dev, n2, sizeof n2);
- }
-
- i = 0;
- while (read_indexs[i] != 0x00) {
- test_byte = reg_r(gspca_dev, read_indexs[i]);
- PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
- test_byte);
- i++;
- }
-
- sensor = &sensor_data[sd->sensor];
- reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
- reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
-
- if (sd->sensor == SENSOR_LT168G) {
- test_byte = reg_r(gspca_dev, 0x80);
- PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
- test_byte);
- reg_w(gspca_dev, 0x6c80);
- }
-
- reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
- reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
- reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
-
- reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
- reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
- reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e);
- reg_w(gspca_dev, (0x20 << 8) + 0x87);
- reg_w(gspca_dev, (0x20 << 8) + 0x88);
- reg_w(gspca_dev, (0x20 << 8) + 0x89);
-
- reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5);
- reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
- reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
-
- if (sd->sensor == SENSOR_LT168G) {
- test_byte = reg_r(gspca_dev, 0x80);
- PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
- test_byte);
- reg_w(gspca_dev, 0x6c80);
- }
-
- reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
- reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
- reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
-
- return 0;
-}
-
-static void setmirror(struct gspca_dev *gspca_dev, s32 val)
-{
- u8 hflipcmd[8] =
- {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
-
- if (val)
- hflipcmd[3] = 0x01;
-
- reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd);
-}
-
-static void seteffect(struct gspca_dev *gspca_dev, s32 val)
-{
- int idx = 0;
-
- switch (val) {
- case V4L2_COLORFX_NONE:
- break;
- case V4L2_COLORFX_BW:
- idx = 2;
- break;
- case V4L2_COLORFX_SEPIA:
- idx = 3;
- break;
- case V4L2_COLORFX_SKETCH:
- idx = 4;
- break;
- case V4L2_COLORFX_NEGATIVE:
- idx = 6;
- break;
- default:
- break;
- }
-
- reg_w_buf(gspca_dev, effects_table[idx],
- sizeof effects_table[0]);
-
- if (val == V4L2_COLORFX_SKETCH)
- reg_w(gspca_dev, 0x4aa6);
- else
- reg_w(gspca_dev, 0xfaa6);
-}
-
-/* Is this really needed?
- * i added some module parameters for test with some users */
-static void poll_sensor(struct gspca_dev *gspca_dev)
-{
- static const u8 poll1[] =
- {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
- 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
- 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
- 0x60, 0x14};
- static const u8 poll2[] =
- {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
- 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
- static const u8 noise03[] = /* (some differences / ms-drv) */
- {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
- 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
- 0xc2, 0x80, 0xc3, 0x10};
-
- PDEBUG(D_STREAM, "[Sensor requires polling]");
- reg_w_buf(gspca_dev, poll1, sizeof poll1);
- reg_w_buf(gspca_dev, poll2, sizeof poll2);
- reg_w_buf(gspca_dev, noise03, sizeof noise03);
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- const struct additional_sensor_data *sensor;
- int i, mode;
- u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
- static const u8 t3[] =
- { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
-
- mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
- switch (mode) {
- case 0: /* 640x480 (0x00) */
- break;
- case 1: /* 352x288 */
- t2[1] = 0x40;
- break;
- case 2: /* 320x240 */
- t2[1] = 0x10;
- break;
- case 3: /* 176x144 */
- t2[1] = 0x50;
- break;
- default:
-/* case 4: * 160x120 */
- t2[1] = 0x20;
- break;
- }
-
- switch (sd->sensor) {
- case SENSOR_OM6802:
- om6802_sensor_init(gspca_dev);
- break;
- case SENSOR_TAS5130A:
- i = 0;
- for (;;) {
- reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
- sizeof tas5130a_sensor_init[0]);
- if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1)
- break;
- i++;
- }
- reg_w(gspca_dev, 0x3c80);
- /* just in case and to keep sync with logs (for mine) */
- reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
- sizeof tas5130a_sensor_init[0]);
- reg_w(gspca_dev, 0x3c80);
- break;
- }
- sensor = &sensor_data[sd->sensor];
- setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq));
- reg_r(gspca_dev, 0x0012);
- reg_w_buf(gspca_dev, t2, sizeof t2);
- reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
- reg_w(gspca_dev, 0x0013);
- msleep(15);
- reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
- reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
-
- if (sd->sensor == SENSOR_OM6802)
- poll_sensor(gspca_dev);
-
- return 0;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
- sizeof sensor_data[sd->sensor].stream);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
- sizeof sensor_data[sd->sensor].stream);
- if (sd->sensor == SENSOR_OM6802) {
- msleep(20);
- reg_w(gspca_dev, 0x0309);
- }
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- /* If the last button state is pressed, release it now! */
- if (sd->button_pressed) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
- input_sync(gspca_dev->input_dev);
- sd->button_pressed = 0;
- }
-#endif
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int pkt_type;
-
- if (data[0] == 0x5a) {
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- if (len > 20) {
- u8 state = (data[20] & 0x80) ? 1 : 0;
- if (sd->button_pressed != state) {
- input_report_key(gspca_dev->input_dev,
- KEY_CAMERA, state);
- input_sync(gspca_dev->input_dev);
- sd->button_pressed = state;
- }
- }
-#endif
- /* Control Packet, after this came the header again,
- * but extra bytes came in the packet before this,
- * sometimes an EOF arrives, sometimes not... */
- return;
- }
- data += 2;
- len -= 2;
- if (data[0] == 0xff && data[1] == 0xd8)
- pkt_type = FIRST_PACKET;
- else if (data[len - 2] == 0xff && data[len - 1] == 0xd9)
- pkt_type = LAST_PACKET;
- else
- pkt_type = INTER_PACKET;
- gspca_frame_add(gspca_dev, pkt_type, data, len);
-}
-
-static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
- s32 red_gain, blue_gain, green_gain;
-
- gspca_dev->usb_err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTO_WHITE_BALANCE:
- red_gain = reg_r(gspca_dev, 0x0087);
- if (red_gain > 0x40)
- red_gain = 0x40;
- else if (red_gain < 0x10)
- red_gain = 0x10;
-
- blue_gain = reg_r(gspca_dev, 0x0088);
- if (blue_gain > 0x40)
- blue_gain = 0x40;
- else if (blue_gain < 0x10)
- blue_gain = 0x10;
-
- green_gain = reg_r(gspca_dev, 0x0089);
- if (green_gain > 0x40)
- green_gain = 0x40;
- else if (green_gain < 0x10)
- green_gain = 0x10;
-
- sd->gain->val = green_gain;
- sd->red_balance->val = red_gain - green_gain;
- sd->blue_balance->val = blue_gain - green_gain;
- break;
- }
- return 0;
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- setcolors(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_GAMMA:
- setgamma(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_HFLIP:
- setmirror(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SHARPNESS:
- setsharpness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY:
- setfreq(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_BACKLIGHT_COMPENSATION:
- reg_w(gspca_dev, ctrl->val ? 0xf48e : 0xb48e);
- break;
- case V4L2_CID_AUTO_WHITE_BALANCE:
- setawb_n_RGB(gspca_dev);
- break;
- case V4L2_CID_COLORFX:
- seteffect(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .g_volatile_ctrl = sd_g_volatile_ctrl,
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 12);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 14, 1, 8);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 0x0d, 1, 7);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 0, 0xf, 1, 5);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAMMA, 0, GAMMA_MAX, 1, 10);
- /* Activate lowlight, some apps dont bring up the
- backlight_compensation control) */
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BACKLIGHT_COMPENSATION, 0, 1, 1, 1);
- if (sd->sensor == SENSOR_TAS5130A)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- sd->awb = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
- sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0x10, 0x40, 1, 0x20);
- sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BLUE_BALANCE, -0x30, 0x30, 1, 0);
- sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_RED_BALANCE, -0x30, 0x30, 1, 0);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SHARPNESS, 0, 15, 1, 6);
- v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
- V4L2_CID_COLORFX, V4L2_COLORFX_SKETCH,
- ~((1 << V4L2_COLORFX_NONE) |
- (1 << V4L2_COLORFX_BW) |
- (1 << V4L2_COLORFX_SEPIA) |
- (1 << V4L2_COLORFX_SKETCH) |
- (1 << V4L2_COLORFX_NEGATIVE)),
- V4L2_COLORFX_NONE);
- sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
- V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
- V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
-
- v4l2_ctrl_auto_cluster(4, &sd->awb, 0, true);
-
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .other_input = 1,
-#endif
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x17a1, 0x0128)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/topro.c b/drivers/media/video/gspca/topro.c
deleted file mode 100644
index a6055246cb9..00000000000
--- a/drivers/media/video/gspca/topro.c
+++ /dev/null
@@ -1,4969 +0,0 @@
-/*
- * Topro TP6800/6810 webcam driver.
- *
- * Copyright (C) 2011 Jean-François Moine (http://moinejf.free.fr)
- * Copyright (C) 2009 Anders Blomdell (anders.blomdell@control.lth.se)
- * Copyright (C) 2008 Thomas Champagne (lafeuil@gmail.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "gspca.h"
-
-MODULE_DESCRIPTION("Topro TP6800/6810 gspca webcam driver");
-MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
- "Anders Blomdell <anders.blomdell@control.lth.se>");
-MODULE_LICENSE("GPL");
-
-static int force_sensor = -1;
-
-/* JPEG header */
-static const u8 jpeg_head[] = {
- 0xff, 0xd8, /* jpeg */
-
-/* quantization table quality 50% */
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
-#define JPEG_QT0_OFFSET 7
- 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
- 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
- 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
- 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
- 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
- 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
- 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
- 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
-1,
-#define JPEG_QT1_OFFSET 72
- 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
- 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-
- /* Define Huffman table (thanks to Thomas Kaiser) */
- 0xff, 0xc4, 0x01, 0x5e,
- 0x00, 0x00, 0x02, 0x03,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
- 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
- 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
- 0x07, 0x05, 0x04, 0x06, 0x01, 0x00, 0x00, 0x57,
- 0x01, 0x02, 0x03, 0x00, 0x11, 0x04, 0x12, 0x21,
- 0x31, 0x13, 0x41, 0x51, 0x61, 0x05, 0x22, 0x32,
- 0x14, 0x71, 0x81, 0x91, 0x15, 0x23, 0x42, 0x52,
- 0x62, 0xa1, 0xb1, 0x06, 0x33, 0x72, 0xc1, 0xd1,
- 0x24, 0x43, 0x53, 0x82, 0x16, 0x34, 0x92, 0xa2,
- 0xe1, 0xf1, 0xf0, 0x07, 0x08, 0x17, 0x18, 0x25,
- 0x26, 0x27, 0x28, 0x35, 0x36, 0x37, 0x38, 0x44,
- 0x45, 0x46, 0x47, 0x48, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x73,
- 0x74, 0x75, 0x76, 0x77, 0x78, 0x83, 0x84, 0x85,
- 0x86, 0x87, 0x88, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xb2,
- 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xc2, 0xc3,
- 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xd2, 0xd3, 0xd4,
- 0xd5, 0xd6, 0xd7, 0xd8, 0xe2, 0xe3, 0xe4, 0xe5,
- 0xe6, 0xe7, 0xe8, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
- 0xf7, 0xf8, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
- 0x05, 0x06, 0x07, 0x08, 0x09, 0x11, 0x00, 0x02,
- 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05,
- 0x04, 0x06, 0x01, 0x00, 0x00, 0x57, 0x00, 0x01,
- 0x11, 0x02, 0x21, 0x03, 0x12, 0x31, 0x41, 0x13,
- 0x22, 0x51, 0x61, 0x04, 0x32, 0x71, 0x05, 0x14,
- 0x23, 0x42, 0x33, 0x52, 0x81, 0x91, 0xa1, 0xb1,
- 0xf0, 0x06, 0x15, 0xc1, 0xd1, 0xe1, 0x24, 0x43,
- 0x62, 0xf1, 0x16, 0x25, 0x34, 0x53, 0x72, 0x82,
- 0x92, 0x07, 0x08, 0x17, 0x18, 0x26, 0x27, 0x28,
- 0x35, 0x36, 0x37, 0x38, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x54, 0x55, 0x56, 0x57, 0x58, 0x63, 0x64,
- 0x65, 0x66, 0x67, 0x68, 0x73, 0x74, 0x75, 0x76,
- 0x77, 0x78, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
- 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0xa2, 0xa3,
- 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xb2, 0xb3, 0xb4,
- 0xb5, 0xb6, 0xb7, 0xb8, 0xc2, 0xc3, 0xc4, 0xc5,
- 0xc6, 0xc7, 0xc8, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
- 0xd7, 0xd8, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- 0xe8, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
- 0xff, 0xc0, 0x00, 0x11, /* SOF0 (start of frame 0 */
- 0x08, /* data precision */
-#define JPEG_HEIGHT_OFFSET 493
- 0x01, 0xe0, /* height */
- 0x02, 0x80, /* width */
- 0x03, /* component number */
- 0x01,
- 0x21, /* samples Y = jpeg 422 */
- 0x00, /* quant Y */
- 0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */
- 0x03, 0x11, 0x01,
-
- 0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan) */
- 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
-#define JPEG_HDR_SZ 521
-};
-
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- struct v4l2_ctrl *jpegqual;
- struct v4l2_ctrl *sharpness;
- struct v4l2_ctrl *gamma;
- struct v4l2_ctrl *blue;
- struct v4l2_ctrl *red;
-
- u8 framerate;
- u8 quality; /* webcam current JPEG quality (0..16) */
- s8 ag_cnt; /* autogain / start counter for tp6810 */
-#define AG_CNT_START 13 /* check gain every N frames */
-
- u8 bridge;
- u8 sensor;
-
- u8 jpeg_hdr[JPEG_HDR_SZ];
-};
-
-enum bridges {
- BRIDGE_TP6800,
- BRIDGE_TP6810,
-};
-
-enum sensors {
- SENSOR_CX0342,
- SENSOR_SOI763A, /* ~= ov7630 / ov7648 */
- NSENSORS
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 4 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG}
-};
-
-/*
- * JPEG quality
- * index: webcam compression
- * value: JPEG quality in %
- */
-static const u8 jpeg_q[17] = {
- 88, 77, 67, 57, 55, 55, 45, 45, 36, 36, 30, 30, 26, 26, 22, 22, 94
-};
-
-#define BULK_OUT_SIZE 0x20
-#if BULK_OUT_SIZE > USB_BUF_SZ
-#error "USB buffer too small"
-#endif
-
-static const u8 rates[] = {30, 20, 15, 10, 7, 5};
-static const struct framerates framerates[] = {
- {
- .rates = rates,
- .nrates = ARRAY_SIZE(rates)
- },
- {
- .rates = rates,
- .nrates = ARRAY_SIZE(rates)
- }
-};
-static const u8 rates_6810[] = {30, 15, 10, 7, 5};
-static const struct framerates framerates_6810[] = {
- {
- .rates = rates_6810,
- .nrates = ARRAY_SIZE(rates_6810)
- },
- {
- .rates = rates_6810,
- .nrates = ARRAY_SIZE(rates_6810)
- }
-};
-
-/*
- * webcam quality in %
- * the last value is the ultra fine quality
- */
-
-/* TP6800 register offsets */
-#define TP6800_R10_SIF_TYPE 0x10
-#define TP6800_R11_SIF_CONTROL 0x11
-#define TP6800_R12_SIF_ADDR_S 0x12
-#define TP6800_R13_SIF_TX_DATA 0x13
-#define TP6800_R14_SIF_RX_DATA 0x14
-#define TP6800_R15_GPIO_PU 0x15
-#define TP6800_R16_GPIO_PD 0x16
-#define TP6800_R17_GPIO_IO 0x17
-#define TP6800_R18_GPIO_DATA 0x18
-#define TP6800_R19_SIF_ADDR_S2 0x19
-#define TP6800_R1A_SIF_TX_DATA2 0x1a
-#define TP6800_R1B_SIF_RX_DATA2 0x1b
-#define TP6800_R21_ENDP_1_CTL 0x21
-#define TP6800_R2F_TIMING_CFG 0x2f
-#define TP6800_R30_SENSOR_CFG 0x30
-#define TP6800_R31_PIXEL_START 0x31
-#define TP6800_R32_PIXEL_END_L 0x32
-#define TP6800_R33_PIXEL_END_H 0x33
-#define TP6800_R34_LINE_START 0x34
-#define TP6800_R35_LINE_END_L 0x35
-#define TP6800_R36_LINE_END_H 0x36
-#define TP6800_R37_FRONT_DARK_ST 0x37
-#define TP6800_R38_FRONT_DARK_END 0x38
-#define TP6800_R39_REAR_DARK_ST_L 0x39
-#define TP6800_R3A_REAR_DARK_ST_H 0x3a
-#define TP6800_R3B_REAR_DARK_END_L 0x3b
-#define TP6800_R3C_REAR_DARK_END_H 0x3c
-#define TP6800_R3D_HORIZ_DARK_LINE_L 0x3d
-#define TP6800_R3E_HORIZ_DARK_LINE_H 0x3e
-#define TP6800_R3F_FRAME_RATE 0x3f
-#define TP6800_R50 0x50
-#define TP6800_R51 0x51
-#define TP6800_R52 0x52
-#define TP6800_R53 0x53
-#define TP6800_R54_DARK_CFG 0x54
-#define TP6800_R55_GAMMA_R 0x55
-#define TP6800_R56_GAMMA_G 0x56
-#define TP6800_R57_GAMMA_B 0x57
-#define TP6800_R5C_EDGE_THRLD 0x5c
-#define TP6800_R5D_DEMOSAIC_CFG 0x5d
-#define TP6800_R78_FORMAT 0x78
-#define TP6800_R79_QUALITY 0x79
-#define TP6800_R7A_BLK_THRLD 0x7a
-
-/* CX0342 register offsets */
-
-#define CX0342_SENSOR_ID 0x00
-#define CX0342_VERSION_NO 0x01
-#define CX0342_ORG_X_L 0x02
-#define CX0342_ORG_X_H 0x03
-#define CX0342_ORG_Y_L 0x04
-#define CX0342_ORG_Y_H 0x05
-#define CX0342_STOP_X_L 0x06
-#define CX0342_STOP_X_H 0x07
-#define CX0342_STOP_Y_L 0x08
-#define CX0342_STOP_Y_H 0x09
-#define CX0342_FRAME_WIDTH_L 0x0a
-#define CX0342_FRAME_WIDTH_H 0x0b
-#define CX0342_FRAME_HEIGH_L 0x0c
-#define CX0342_FRAME_HEIGH_H 0x0d
-#define CX0342_EXPO_LINE_L 0x10
-#define CX0342_EXPO_LINE_H 0x11
-#define CX0342_EXPO_CLK_L 0x12
-#define CX0342_EXPO_CLK_H 0x13
-#define CX0342_RAW_GRGAIN_L 0x14
-#define CX0342_RAW_GRGAIN_H 0x15
-#define CX0342_RAW_GBGAIN_L 0x16
-#define CX0342_RAW_GBGAIN_H 0x17
-#define CX0342_RAW_RGAIN_L 0x18
-#define CX0342_RAW_RGAIN_H 0x19
-#define CX0342_RAW_BGAIN_L 0x1a
-#define CX0342_RAW_BGAIN_H 0x1b
-#define CX0342_GLOBAL_GAIN 0x1c
-#define CX0342_SYS_CTRL_0 0x20
-#define CX0342_SYS_CTRL_1 0x21
-#define CX0342_SYS_CTRL_2 0x22
-#define CX0342_BYPASS_MODE 0x23
-#define CX0342_SYS_CTRL_3 0x24
-#define CX0342_TIMING_EN 0x25
-#define CX0342_OUTPUT_CTRL 0x26
-#define CX0342_AUTO_ADC_CALIB 0x27
-#define CX0342_SYS_CTRL_4 0x28
-#define CX0342_ADCGN 0x30
-#define CX0342_SLPCR 0x31
-#define CX0342_SLPFN_LO 0x32
-#define CX0342_ADC_CTL 0x33
-#define CX0342_LVRST_BLBIAS 0x34
-#define CX0342_VTHSEL 0x35
-#define CX0342_RAMP_RIV 0x36
-#define CX0342_LDOSEL 0x37
-#define CX0342_CLOCK_GEN 0x40
-#define CX0342_SOFT_RESET 0x41
-#define CX0342_PLL 0x42
-#define CX0342_DR_ENH_PULSE_OFFSET_L 0x43
-#define CX0342_DR_ENH_PULSE_OFFSET_H 0x44
-#define CX0342_DR_ENH_PULSE_POS_L 0x45
-#define CX0342_DR_ENH_PULSE_POS_H 0x46
-#define CX0342_DR_ENH_PULSE_WIDTH 0x47
-#define CX0342_AS_CURRENT_CNT_L 0x48
-#define CX0342_AS_CURRENT_CNT_H 0x49
-#define CX0342_AS_PREVIOUS_CNT_L 0x4a
-#define CX0342_AS_PREVIOUS_CNT_H 0x4b
-#define CX0342_SPV_VALUE_L 0x4c
-#define CX0342_SPV_VALUE_H 0x4d
-#define CX0342_GPXLTHD_L 0x50
-#define CX0342_GPXLTHD_H 0x51
-#define CX0342_RBPXLTHD_L 0x52
-#define CX0342_RBPXLTHD_H 0x53
-#define CX0342_PLANETHD_L 0x54
-#define CX0342_PLANETHD_H 0x55
-#define CX0342_ROWDARK_TH 0x56
-#define CX0342_ROWDARK_TOL 0x57
-#define CX0342_RB_GAP_L 0x58
-#define CX0342_RB_GAP_H 0x59
-#define CX0342_G_GAP_L 0x5a
-#define CX0342_G_GAP_H 0x5b
-#define CX0342_AUTO_ROW_DARK 0x60
-#define CX0342_MANUAL_DARK_VALUE 0x61
-#define CX0342_GB_DARK_OFFSET 0x62
-#define CX0342_GR_DARK_OFFSET 0x63
-#define CX0342_RED_DARK_OFFSET 0x64
-#define CX0342_BLUE_DARK_OFFSET 0x65
-#define CX0342_DATA_SCALING_MULTI 0x66
-#define CX0342_AUTOD_Q_FRAME 0x67
-#define CX0342_AUTOD_ALLOW_VARI 0x68
-#define CX0342_AUTO_DARK_VALUE_L 0x69
-#define CX0342_AUTO_DARK_VALUE_H 0x6a
-#define CX0342_IO_CTRL_0 0x70
-#define CX0342_IO_CTRL_1 0x71
-#define CX0342_IO_CTRL_2 0x72
-#define CX0342_IDLE_CTRL 0x73
-#define CX0342_TEST_MODE 0x74
-#define CX0342_FRAME_FIX_DATA_TEST 0x75
-#define CX0342_FRAME_CNT_TEST 0x76
-#define CX0342_RST_OVERFLOW_L 0x80
-#define CX0342_RST_OVERFLOW_H 0x81
-#define CX0342_RST_UNDERFLOW_L 0x82
-#define CX0342_RST_UNDERFLOW_H 0x83
-#define CX0342_DATA_OVERFLOW_L 0x84
-#define CX0342_DATA_OVERFLOW_H 0x85
-#define CX0342_DATA_UNDERFLOW_L 0x86
-#define CX0342_DATA_UNDERFLOW_H 0x87
-#define CX0342_CHANNEL_0_0_L_irst 0x90
-#define CX0342_CHANNEL_0_0_H_irst 0x91
-#define CX0342_CHANNEL_0_1_L_irst 0x92
-#define CX0342_CHANNEL_0_1_H_irst 0x93
-#define CX0342_CHANNEL_0_2_L_irst 0x94
-#define CX0342_CHANNEL_0_2_H_irst 0x95
-#define CX0342_CHANNEL_0_3_L_irst 0x96
-#define CX0342_CHANNEL_0_3_H_irst 0x97
-#define CX0342_CHANNEL_0_4_L_irst 0x98
-#define CX0342_CHANNEL_0_4_H_irst 0x99
-#define CX0342_CHANNEL_0_5_L_irst 0x9a
-#define CX0342_CHANNEL_0_5_H_irst 0x9b
-#define CX0342_CHANNEL_0_6_L_irst 0x9c
-#define CX0342_CHANNEL_0_6_H_irst 0x9d
-#define CX0342_CHANNEL_0_7_L_irst 0x9e
-#define CX0342_CHANNEL_0_7_H_irst 0x9f
-#define CX0342_CHANNEL_1_0_L_itx 0xa0
-#define CX0342_CHANNEL_1_0_H_itx 0xa1
-#define CX0342_CHANNEL_1_1_L_itx 0xa2
-#define CX0342_CHANNEL_1_1_H_itx 0xa3
-#define CX0342_CHANNEL_1_2_L_itx 0xa4
-#define CX0342_CHANNEL_1_2_H_itx 0xa5
-#define CX0342_CHANNEL_1_3_L_itx 0xa6
-#define CX0342_CHANNEL_1_3_H_itx 0xa7
-#define CX0342_CHANNEL_1_4_L_itx 0xa8
-#define CX0342_CHANNEL_1_4_H_itx 0xa9
-#define CX0342_CHANNEL_1_5_L_itx 0xaa
-#define CX0342_CHANNEL_1_5_H_itx 0xab
-#define CX0342_CHANNEL_1_6_L_itx 0xac
-#define CX0342_CHANNEL_1_6_H_itx 0xad
-#define CX0342_CHANNEL_1_7_L_itx 0xae
-#define CX0342_CHANNEL_1_7_H_itx 0xaf
-#define CX0342_CHANNEL_2_0_L_iwl 0xb0
-#define CX0342_CHANNEL_2_0_H_iwl 0xb1
-#define CX0342_CHANNEL_2_1_L_iwl 0xb2
-#define CX0342_CHANNEL_2_1_H_iwl 0xb3
-#define CX0342_CHANNEL_2_2_L_iwl 0xb4
-#define CX0342_CHANNEL_2_2_H_iwl 0xb5
-#define CX0342_CHANNEL_2_3_L_iwl 0xb6
-#define CX0342_CHANNEL_2_3_H_iwl 0xb7
-#define CX0342_CHANNEL_2_4_L_iwl 0xb8
-#define CX0342_CHANNEL_2_4_H_iwl 0xb9
-#define CX0342_CHANNEL_2_5_L_iwl 0xba
-#define CX0342_CHANNEL_2_5_H_iwl 0xbb
-#define CX0342_CHANNEL_2_6_L_iwl 0xbc
-#define CX0342_CHANNEL_2_6_H_iwl 0xbd
-#define CX0342_CHANNEL_2_7_L_iwl 0xbe
-#define CX0342_CHANNEL_2_7_H_iwl 0xbf
-#define CX0342_CHANNEL_3_0_L_ensp 0xc0
-#define CX0342_CHANNEL_3_0_H_ensp 0xc1
-#define CX0342_CHANNEL_3_1_L_ensp 0xc2
-#define CX0342_CHANNEL_3_1_H_ensp 0xc3
-#define CX0342_CHANNEL_3_2_L_ensp 0xc4
-#define CX0342_CHANNEL_3_2_H_ensp 0xc5
-#define CX0342_CHANNEL_3_3_L_ensp 0xc6
-#define CX0342_CHANNEL_3_3_H_ensp 0xc7
-#define CX0342_CHANNEL_3_4_L_ensp 0xc8
-#define CX0342_CHANNEL_3_4_H_ensp 0xc9
-#define CX0342_CHANNEL_3_5_L_ensp 0xca
-#define CX0342_CHANNEL_3_5_H_ensp 0xcb
-#define CX0342_CHANNEL_3_6_L_ensp 0xcc
-#define CX0342_CHANNEL_3_6_H_ensp 0xcd
-#define CX0342_CHANNEL_3_7_L_ensp 0xce
-#define CX0342_CHANNEL_3_7_H_ensp 0xcf
-#define CX0342_CHANNEL_4_0_L_sela 0xd0
-#define CX0342_CHANNEL_4_0_H_sela 0xd1
-#define CX0342_CHANNEL_4_1_L_sela 0xd2
-#define CX0342_CHANNEL_4_1_H_sela 0xd3
-#define CX0342_CHANNEL_5_0_L_intla 0xe0
-#define CX0342_CHANNEL_5_0_H_intla 0xe1
-#define CX0342_CHANNEL_5_1_L_intla 0xe2
-#define CX0342_CHANNEL_5_1_H_intla 0xe3
-#define CX0342_CHANNEL_5_2_L_intla 0xe4
-#define CX0342_CHANNEL_5_2_H_intla 0xe5
-#define CX0342_CHANNEL_5_3_L_intla 0xe6
-#define CX0342_CHANNEL_5_3_H_intla 0xe7
-#define CX0342_CHANNEL_6_0_L_xa_sel_pos 0xf0
-#define CX0342_CHANNEL_6_0_H_xa_sel_pos 0xf1
-#define CX0342_CHANNEL_7_1_L_cds_pos 0xf2
-#define CX0342_CHANNEL_7_1_H_cds_pos 0xf3
-#define CX0342_SENSOR_HEIGHT_L 0xfb
-#define CX0342_SENSOR_HEIGHT_H 0xfc
-#define CX0342_SENSOR_WIDTH_L 0xfd
-#define CX0342_SENSOR_WIDTH_H 0xfe
-#define CX0342_VSYNC_HSYNC_READ 0xff
-
-struct cmd {
- u8 reg;
- u8 val;
-};
-
-static const u8 DQT[17][130] = {
- /* Define quantization table (thanks to Thomas Kaiser) */
- { /* Quality 0 */
- 0x00,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x01,
- 0x04, 0x04, 0x04, 0x06, 0x05, 0x06, 0x0b, 0x06,
- 0x06, 0x0b, 0x18, 0x10, 0x0e, 0x10, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- },
- { /* Quality 1 */
- 0x00,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x01,
- 0x08, 0x09, 0x09, 0x0c, 0x0a, 0x0c, 0x17, 0x0d,
- 0x0d, 0x17, 0x31, 0x21, 0x1c, 0x21, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
- },
- { /* Quality 2 */
- 0x00,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x06, 0x06, 0x06, 0x04, 0x04, 0x04,
- 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x01,
- 0x0c, 0x0d, 0x0d, 0x12, 0x0f, 0x12, 0x23, 0x13,
- 0x13, 0x23, 0x4a, 0x31, 0x2a, 0x31, 0x4a, 0x4a,
- 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a,
- 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a,
- 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a,
- 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a,
- 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a,
- 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a,
- },
- { /* Quality 3 */
- 0x00,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04,
- 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x01,
- 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
- 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- },
- { /* Quality 4 */
- 0x00,
- 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x0a, 0x0a, 0x0a, 0x05, 0x05, 0x05,
- 0x05, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x17, 0x17, 0x17, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
- 0x01,
- 0x11, 0x16, 0x16, 0x1e, 0x1a, 0x1e, 0x3a, 0x20,
- 0x20, 0x3a, 0x7b, 0x52, 0x46, 0x52, 0x7b, 0x7b,
- 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
- 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
- 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
- 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
- 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
- 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
- },
- { /* Quality 5 */
- 0x00,
- 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x0c, 0x0c, 0x0c, 0x06, 0x06, 0x06,
- 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x01,
- 0x11, 0x1b, 0x1b, 0x24, 0x1f, 0x24, 0x46, 0x27,
- 0x27, 0x46, 0x94, 0x63, 0x54, 0x63, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- },
- { /* Quality 6 */
- 0x00,
- 0x05, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x0e, 0x0e, 0x0e, 0x07, 0x07, 0x07,
- 0x07, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x01,
- 0x15, 0x1f, 0x1f, 0x2a, 0x24, 0x2a, 0x52, 0x2d,
- 0x2d, 0x52, 0xad, 0x73, 0x62, 0x73, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- },
- { /* Quality 7 */
- 0x00,
- 0x05, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08,
- 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x01,
- 0x15, 0x24, 0x24, 0x30, 0x2a, 0x30, 0x5e, 0x34,
- 0x34, 0x5e, 0xc6, 0x84, 0x70, 0x84, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- },
- { /* Quality 8 */
- 0x00,
- 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x14, 0x14, 0x14, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x01,
- 0x19, 0x2d, 0x2d, 0x3c, 0x34, 0x3c, 0x75, 0x41,
- 0x41, 0x75, 0xf7, 0xa5, 0x8c, 0xa5, 0xf7, 0xf7,
- 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7,
- 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7,
- 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7,
- 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7,
- 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7,
- 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7,
- },
- { /* Quality 9 */
- 0x00,
- 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x39, 0x39, 0x39, 0x39, 0x39,
- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
- 0x01,
- 0x19, 0x36, 0x36, 0x48, 0x3f, 0x48, 0x8d, 0x4e,
- 0x4e, 0x8d, 0xff, 0xc6, 0xa8, 0xc6, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- },
- { /* Quality 10 */
- 0x00,
- 0x07, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x1c, 0x1c, 0x1c, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x42, 0x42, 0x42, 0x42, 0x42,
- 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
- 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
- 0x01,
- 0x1d, 0x3f, 0x3f, 0x54, 0x49, 0x54, 0xa4, 0x5b,
- 0x5b, 0xa4, 0xff, 0xe7, 0xc4, 0xe7, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- },
- { /* Quality 11 */
- 0x00,
- 0x07, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10,
- 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,
- 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,
- 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,
- 0x01,
- 0x1d, 0x48, 0x48, 0x60, 0x54, 0x60, 0xbc, 0x68,
- 0x68, 0xbc, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- },
- { /* Quality 12 */
- 0x00,
- 0x08, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x28, 0x28, 0x28, 0x14, 0x14, 0x14,
- 0x14, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
- 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
- 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
- 0x01,
- 0x22, 0x5a, 0x5a, 0x78, 0x69, 0x78, 0xeb, 0x82,
- 0x82, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- },
- { /* Quality 13 */
- 0x00,
- 0x08, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x30, 0x30, 0x30, 0x18, 0x18, 0x18,
- 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x72, 0x72, 0x72, 0x72, 0x72,
- 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
- 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
- 0x01,
- 0x22, 0x6c, 0x6c, 0x90, 0x7e, 0x90, 0xff, 0x9c,
- 0x9c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- },
- { /* Quality 14 */
- 0x00,
- 0x0a, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x38, 0x38, 0x38, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x01,
- 0x2a, 0x7e, 0x7e, 0xa8, 0x93, 0xa8, 0xff, 0xb6,
- 0xb6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- },
- { /* Quality 15 */
- 0x00,
- 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20,
- 0x20, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
- 0x40, 0x40, 0x40, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x01,
- 0x2a, 0x90, 0x90, 0xc0, 0xa8, 0xc0, 0xff, 0xd0,
- 0xd0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- },
- { /* Quality 16-31 */
- 0x00,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x01,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- }
-};
-
-static const struct cmd tp6810_cx_init_common[] = {
- {0x1c, 0x00},
- {TP6800_R10_SIF_TYPE, 0x00},
- {0x4e, 0x00},
- {0x4f, 0x00},
- {TP6800_R50, 0xff},
- {TP6800_R51, 0x03},
- {0x00, 0x07},
- {TP6800_R79_QUALITY, 0x03},
- {TP6800_R2F_TIMING_CFG, 0x37},
- {TP6800_R30_SENSOR_CFG, 0x10},
- {TP6800_R21_ENDP_1_CTL, 0x00},
- {TP6800_R52, 0x40},
- {TP6800_R53, 0x40},
- {TP6800_R54_DARK_CFG, 0x40},
- {TP6800_R30_SENSOR_CFG, 0x18},
- {0x4b, 0x00},
- {TP6800_R3F_FRAME_RATE, 0x83},
- {TP6800_R79_QUALITY, 0x05},
- {TP6800_R21_ENDP_1_CTL, 0x00},
- {0x7c, 0x04},
- {0x25, 0x14},
- {0x26, 0x0f},
- {0x7b, 0x10},
-};
-
-static const struct cmd tp6810_ov_init_common[] = {
- {0x1c, 0x00},
- {TP6800_R10_SIF_TYPE, 0x00},
- {0x4e, 0x00},
- {0x4f, 0x00},
- {TP6800_R50, 0xff},
- {TP6800_R51, 0x03},
- {0x00, 0x07},
- {TP6800_R52, 0x40},
- {TP6800_R53, 0x40},
- {TP6800_R54_DARK_CFG, 0x40},
- {TP6800_R79_QUALITY, 0x03},
- {TP6800_R2F_TIMING_CFG, 0x17},
- {TP6800_R30_SENSOR_CFG, 0x18},
- {TP6800_R21_ENDP_1_CTL, 0x00},
- {TP6800_R3F_FRAME_RATE, 0x86},
- {0x25, 0x18},
- {0x26, 0x0f},
- {0x7b, 0x90},
-};
-
-static const struct cmd tp6810_bridge_start[] = {
- {0x59, 0x88},
- {0x5a, 0x0f},
- {0x5b, 0x4e},
- {TP6800_R5C_EDGE_THRLD, 0x63},
- {TP6800_R5D_DEMOSAIC_CFG, 0x00},
- {0x03, 0x7f},
- {0x04, 0x80},
- {0x06, 0x00},
- {0x00, 0x00},
-};
-
-static const struct cmd tp6810_late_start[] = {
- {0x7d, 0x01},
- {0xb0, 0x04},
- {0xb1, 0x04},
- {0xb2, 0x04},
- {0xb3, 0x04},
- {0xb4, 0x04},
- {0xb5, 0x04},
- {0xb6, 0x08},
- {0xb7, 0x08},
- {0xb8, 0x04},
- {0xb9, 0x04},
- {0xba, 0x04},
- {0xbb, 0x04},
- {0xbc, 0x04},
- {0xbd, 0x08},
- {0xbe, 0x08},
- {0xbf, 0x08},
- {0xc0, 0x04},
- {0xc1, 0x04},
- {0xc2, 0x08},
- {0xc3, 0x08},
- {0xc4, 0x08},
- {0xc5, 0x08},
- {0xc6, 0x08},
- {0xc7, 0x13},
- {0xc8, 0x04},
- {0xc9, 0x08},
- {0xca, 0x08},
- {0xcb, 0x08},
- {0xcc, 0x08},
- {0xcd, 0x08},
- {0xce, 0x13},
- {0xcf, 0x13},
- {0xd0, 0x08},
- {0xd1, 0x08},
- {0xd2, 0x08},
- {0xd3, 0x08},
- {0xd4, 0x08},
- {0xd5, 0x13},
- {0xd6, 0x13},
- {0xd7, 0x13},
- {0xd8, 0x08},
- {0xd9, 0x08},
- {0xda, 0x08},
- {0xdb, 0x08},
- {0xdc, 0x13},
- {0xdd, 0x13},
- {0xde, 0x13},
- {0xdf, 0x13},
- {0xe0, 0x08},
- {0xe1, 0x08},
- {0xe2, 0x08},
- {0xe3, 0x13},
- {0xe4, 0x13},
- {0xe5, 0x13},
- {0xe6, 0x13},
- {0xe7, 0x13},
- {0xe8, 0x08},
- {0xe9, 0x08},
- {0xea, 0x13},
- {0xeb, 0x13},
- {0xec, 0x13},
- {0xed, 0x13},
- {0xee, 0x13},
- {0xef, 0x13},
- {0x7d, 0x02},
-
- /* later after isoc start */
- {0x7d, 0x08},
- {0x7d, 0x00},
-};
-
-static const struct cmd cx0342_timing_seq[] = {
- {CX0342_CHANNEL_0_1_L_irst, 0x20},
- {CX0342_CHANNEL_0_2_L_irst, 0x24},
- {CX0342_CHANNEL_0_2_H_irst, 0x00},
- {CX0342_CHANNEL_0_3_L_irst, 0x2f},
- {CX0342_CHANNEL_0_3_H_irst, 0x00},
- {CX0342_CHANNEL_1_0_L_itx, 0x02},
- {CX0342_CHANNEL_1_0_H_itx, 0x00},
- {CX0342_CHANNEL_1_1_L_itx, 0x20},
- {CX0342_CHANNEL_1_1_H_itx, 0x00},
- {CX0342_CHANNEL_1_2_L_itx, 0xe4},
- {CX0342_CHANNEL_1_2_H_itx, 0x00},
- {CX0342_CHANNEL_1_3_L_itx, 0xee},
- {CX0342_CHANNEL_1_3_H_itx, 0x00},
- {CX0342_CHANNEL_2_0_L_iwl, 0x30},
- {CX0342_CHANNEL_2_0_H_iwl, 0x00},
- {CX0342_CHANNEL_3_0_L_ensp, 0x34},
- {CX0342_CHANNEL_3_1_L_ensp, 0xe2},
- {CX0342_CHANNEL_3_1_H_ensp, 0x00},
- {CX0342_CHANNEL_3_2_L_ensp, 0xf6},
- {CX0342_CHANNEL_3_2_H_ensp, 0x00},
- {CX0342_CHANNEL_3_3_L_ensp, 0xf4},
- {CX0342_CHANNEL_3_3_H_ensp, 0x02},
- {CX0342_CHANNEL_4_0_L_sela, 0x26},
- {CX0342_CHANNEL_4_0_H_sela, 0x00},
- {CX0342_CHANNEL_4_1_L_sela, 0xe2},
- {CX0342_CHANNEL_4_1_H_sela, 0x00},
- {CX0342_CHANNEL_5_0_L_intla, 0x26},
- {CX0342_CHANNEL_5_1_L_intla, 0x29},
- {CX0342_CHANNEL_5_2_L_intla, 0xf0},
- {CX0342_CHANNEL_5_2_H_intla, 0x00},
- {CX0342_CHANNEL_5_3_L_intla, 0xf3},
- {CX0342_CHANNEL_5_3_H_intla, 0x00},
- {CX0342_CHANNEL_6_0_L_xa_sel_pos, 0x24},
- {CX0342_CHANNEL_7_1_L_cds_pos, 0x02},
- {CX0342_TIMING_EN, 0x01},
-};
-
-/* define the JPEG header */
-static void jpeg_define(u8 *jpeg_hdr,
- int height,
- int width)
-{
- memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head);
- jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8;
- jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height;
- jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8;
- jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width;
-}
-
-/* set the JPEG quality for sensor soi763a */
-static void jpeg_set_qual(u8 *jpeg_hdr,
- int quality)
-{
- int i, sc;
-
- if (quality < 50)
- sc = 5000 / quality;
- else
- sc = 200 - quality * 2;
- for (i = 0; i < 64; i++) {
- jpeg_hdr[JPEG_QT0_OFFSET + i] =
- (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
- jpeg_hdr[JPEG_QT1_OFFSET + i] =
- (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
- }
-}
-
-static void reg_w(struct gspca_dev *gspca_dev, u8 index, u8 value)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x0e,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, NULL, 0, 500);
- if (ret < 0) {
- pr_err("reg_w err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-/* the returned value is in gspca_dev->usb_buf */
-static void reg_r(struct gspca_dev *gspca_dev, u8 index)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- 0x0d,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, index, gspca_dev->usb_buf, 1, 500);
- if (ret < 0) {
- pr_err("reg_r err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static void reg_w_buf(struct gspca_dev *gspca_dev,
- const struct cmd *p, int l)
-{
- do {
- reg_w(gspca_dev, p->reg, p->val);
- p++;
- } while (--l > 0);
-}
-
-static int i2c_w(struct gspca_dev *gspca_dev, u8 index, u8 value)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- reg_w(gspca_dev, TP6800_R11_SIF_CONTROL, 0x00);
- reg_w(gspca_dev, TP6800_R19_SIF_ADDR_S2, index);
- reg_w(gspca_dev, TP6800_R13_SIF_TX_DATA, value);
- reg_w(gspca_dev, TP6800_R11_SIF_CONTROL, 0x01);
- if (sd->bridge == BRIDGE_TP6800)
- return 0;
- msleep(5);
- reg_r(gspca_dev, TP6800_R11_SIF_CONTROL);
- if (gspca_dev->usb_buf[0] == 0)
- return 0;
- reg_w(gspca_dev, TP6800_R11_SIF_CONTROL, 0x00);
- return -1; /* error */
-}
-
-static void i2c_w_buf(struct gspca_dev *gspca_dev,
- const struct cmd *p, int l)
-{
- do {
- i2c_w(gspca_dev, p->reg, p->val);
- p++;
- } while (--l > 0);
-}
-
-static int i2c_r(struct gspca_dev *gspca_dev, u8 index, int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int v;
-
- reg_w(gspca_dev, TP6800_R19_SIF_ADDR_S2, index);
- reg_w(gspca_dev, TP6800_R11_SIF_CONTROL, 0x02);
- msleep(5);
- reg_r(gspca_dev, TP6800_R14_SIF_RX_DATA);
- v = gspca_dev->usb_buf[0];
- if (sd->bridge == BRIDGE_TP6800)
- return v;
- if (len > 1) {
- reg_r(gspca_dev, TP6800_R1B_SIF_RX_DATA2);
- v |= (gspca_dev->usb_buf[0] << 8);
- }
- reg_r(gspca_dev, TP6800_R11_SIF_CONTROL);
- if (gspca_dev->usb_buf[0] == 0)
- return v;
- reg_w(gspca_dev, TP6800_R11_SIF_CONTROL, 0x00);
- return -1;
-}
-
-static void bulk_w(struct gspca_dev *gspca_dev,
- u8 tag,
- const u8 *data,
- int length)
-{
- struct usb_device *dev = gspca_dev->dev;
- int count, actual_count, ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- for (;;) {
- count = length > BULK_OUT_SIZE - 1
- ? BULK_OUT_SIZE - 1 : length;
- gspca_dev->usb_buf[0] = tag;
- memcpy(&gspca_dev->usb_buf[1], data, count);
- ret = usb_bulk_msg(dev,
- usb_sndbulkpipe(dev, 3),
- gspca_dev->usb_buf, count + 1,
- &actual_count, 500);
- if (ret < 0) {
- pr_err("bulk write error %d tag=%02x\n",
- ret, tag);
- gspca_dev->usb_err = ret;
- return;
- }
- length -= count;
- if (length <= 0)
- break;
- data += count;
- }
-}
-
-static int probe_6810(struct gspca_dev *gspca_dev)
-{
- u8 gpio;
- int ret;
-
- reg_r(gspca_dev, TP6800_R18_GPIO_DATA);
- gpio = gspca_dev->usb_buf[0];
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio);
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20);
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio);
- reg_w(gspca_dev, TP6800_R10_SIF_TYPE, 0x04); /* i2c 16 bits */
- reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x21); /* ov??? */
- reg_w(gspca_dev, TP6800_R1A_SIF_TX_DATA2, 0x00);
- if (i2c_w(gspca_dev, 0x00, 0x00) >= 0)
- return SENSOR_SOI763A;
-
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20);
- reg_w(gspca_dev, TP6800_R10_SIF_TYPE, 0x00); /* i2c 8 bits */
- reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x7f); /* (unknown i2c) */
- if (i2c_w(gspca_dev, 0x00, 0x00) >= 0)
- return -2;
-
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20);
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio);
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20);
- reg_w(gspca_dev, TP6800_R10_SIF_TYPE, 0x00); /* i2c 8 bits */
- reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x11); /* tas??? / hv??? */
- ret = i2c_r(gspca_dev, 0x00, 1);
- if (ret > 0)
- return -3;
-
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20);
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio);
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20);
- reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x6e); /* po??? */
- ret = i2c_r(gspca_dev, 0x00, 1);
- if (ret > 0)
- return -4;
-
- ret = i2c_r(gspca_dev, 0x01, 1);
- if (ret > 0)
- return -5;
-
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20);
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio);
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20);
- reg_w(gspca_dev, TP6800_R10_SIF_TYPE, 0x04); /* i2c 16 bits */
- reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x5d); /* mi/mt??? */
- ret = i2c_r(gspca_dev, 0x00, 2);
- if (ret > 0)
- return -6;
-
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20);
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio);
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20);
- reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x5c); /* mi/mt??? */
- ret = i2c_r(gspca_dev, 0x36, 2);
- if (ret > 0)
- return -7;
-
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio);
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20);
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio);
- reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x61); /* (unknown i2c) */
- reg_w(gspca_dev, TP6800_R1A_SIF_TX_DATA2, 0x10);
- if (i2c_w(gspca_dev, 0xff, 0x00) >= 0)
- return -8;
-
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20);
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio);
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20);
- reg_w(gspca_dev, TP6800_R10_SIF_TYPE, 0x00); /* i2c 8 bits */
- reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x20); /* cx0342 */
- ret = i2c_r(gspca_dev, 0x00, 1);
- if (ret > 0)
- return SENSOR_CX0342;
- return -9;
-}
-
-static void cx0342_6810_init(struct gspca_dev *gspca_dev)
-{
- static const struct cmd reg_init_1[] = {
- {TP6800_R2F_TIMING_CFG, 0x2f},
- {0x25, 0x02},
- {TP6800_R21_ENDP_1_CTL, 0x00},
- {TP6800_R3F_FRAME_RATE, 0x80},
- {TP6800_R2F_TIMING_CFG, 0x2f},
- {TP6800_R18_GPIO_DATA, 0xe1},
- {TP6800_R18_GPIO_DATA, 0xc1},
- {TP6800_R18_GPIO_DATA, 0xe1},
- {TP6800_R11_SIF_CONTROL, 0x00},
- };
- static const struct cmd reg_init_2[] = {
- {TP6800_R78_FORMAT, 0x48},
- {TP6800_R11_SIF_CONTROL, 0x00},
- };
- static const struct cmd sensor_init[] = {
- {CX0342_OUTPUT_CTRL, 0x07},
- {CX0342_BYPASS_MODE, 0x58},
- {CX0342_GPXLTHD_L, 0x28},
- {CX0342_RBPXLTHD_L, 0x28},
- {CX0342_PLANETHD_L, 0x50},
- {CX0342_PLANETHD_H, 0x03},
- {CX0342_RB_GAP_L, 0xff},
- {CX0342_RB_GAP_H, 0x07},
- {CX0342_G_GAP_L, 0xff},
- {CX0342_G_GAP_H, 0x07},
- {CX0342_RST_OVERFLOW_L, 0x5c},
- {CX0342_RST_OVERFLOW_H, 0x01},
- {CX0342_DATA_OVERFLOW_L, 0xfc},
- {CX0342_DATA_OVERFLOW_H, 0x03},
- {CX0342_DATA_UNDERFLOW_L, 0x00},
- {CX0342_DATA_UNDERFLOW_H, 0x00},
- {CX0342_SYS_CTRL_0, 0x40},
- {CX0342_GLOBAL_GAIN, 0x01},
- {CX0342_CLOCK_GEN, 0x00},
- {CX0342_SYS_CTRL_0, 0x02},
- {CX0342_IDLE_CTRL, 0x05},
- {CX0342_ADCGN, 0x00},
- {CX0342_ADC_CTL, 0x00},
- {CX0342_LVRST_BLBIAS, 0x01},
- {CX0342_VTHSEL, 0x0b},
- {CX0342_RAMP_RIV, 0x0b},
- {CX0342_LDOSEL, 0x07},
- {CX0342_SPV_VALUE_L, 0x40},
- {CX0342_SPV_VALUE_H, 0x02},
-
- {CX0342_AUTO_ADC_CALIB, 0x81},
- {CX0342_TIMING_EN, 0x01},
- };
-
- reg_w_buf(gspca_dev, reg_init_1, ARRAY_SIZE(reg_init_1));
- reg_w_buf(gspca_dev, tp6810_cx_init_common,
- ARRAY_SIZE(tp6810_cx_init_common));
- reg_w_buf(gspca_dev, reg_init_2, ARRAY_SIZE(reg_init_2));
-
- reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x20); /* cx0342 I2C addr */
- i2c_w_buf(gspca_dev, sensor_init, ARRAY_SIZE(sensor_init));
- i2c_w_buf(gspca_dev, cx0342_timing_seq, ARRAY_SIZE(cx0342_timing_seq));
-}
-
-static void soi763a_6810_init(struct gspca_dev *gspca_dev)
-{
- static const struct cmd reg_init_1[] = {
- {TP6800_R2F_TIMING_CFG, 0x2f},
- {TP6800_R18_GPIO_DATA, 0xe1},
- {0x25, 0x02},
- {TP6800_R21_ENDP_1_CTL, 0x00},
- {TP6800_R3F_FRAME_RATE, 0x80},
- {TP6800_R2F_TIMING_CFG, 0x2f},
- {TP6800_R18_GPIO_DATA, 0xc1},
- };
- static const struct cmd reg_init_2[] = {
- {TP6800_R78_FORMAT, 0x54},
- };
- static const struct cmd sensor_init[] = {
- {0x00, 0x00},
- {0x01, 0x80},
- {0x02, 0x80},
- {0x03, 0x90},
- {0x04, 0x20},
- {0x05, 0x20},
- {0x06, 0x80},
- {0x07, 0x00},
- {0x08, 0xff},
- {0x09, 0xff},
- {0x0a, 0x76}, /* 7630 = soi673a */
- {0x0b, 0x30},
- {0x0c, 0x20},
- {0x0d, 0x20},
- {0x0e, 0xff},
- {0x0f, 0xff},
- {0x10, 0x41},
- {0x15, 0x14},
- {0x11, 0x40},
- {0x12, 0x48},
- {0x13, 0x80},
- {0x14, 0x80},
- {0x16, 0x03},
- {0x28, 0xb0},
- {0x71, 0x20},
- {0x75, 0x8e},
- {0x17, 0x1b},
- {0x18, 0xbd},
- {0x19, 0x05},
- {0x1a, 0xf6},
- {0x1b, 0x04},
- {0x1c, 0x7f}, /* omnivision */
- {0x1d, 0xa2},
- {0x1e, 0x00},
- {0x1f, 0x00},
- {0x20, 0x45},
- {0x21, 0x80},
- {0x22, 0x80},
- {0x23, 0xee},
- {0x24, 0x50},
- {0x25, 0x7a},
- {0x26, 0xa0},
- {0x27, 0x9a},
- {0x29, 0x30},
- {0x2a, 0x80},
- {0x2b, 0x00},
- {0x2c, 0xac},
- {0x2d, 0x05},
- {0x2e, 0x80},
- {0x2f, 0x3c},
- {0x30, 0x22},
- {0x31, 0x00},
- {0x32, 0x86},
- {0x33, 0x08},
- {0x34, 0xff},
- {0x35, 0xff},
- {0x36, 0xff},
- {0x37, 0xff},
- {0x38, 0xff},
- {0x39, 0xff},
- {0x3a, 0xfe},
- {0x3b, 0xfe},
- {0x3c, 0xfe},
- {0x3d, 0xfe},
- {0x3e, 0xfe},
- {0x3f, 0x71},
- {0x40, 0xff},
- {0x41, 0xff},
- {0x42, 0xff},
- {0x43, 0xff},
- {0x44, 0xff},
- {0x45, 0xff},
- {0x46, 0xff},
- {0x47, 0xff},
- {0x48, 0xff},
- {0x49, 0xff},
- {0x4a, 0xfe},
- {0x4b, 0xff},
- {0x4c, 0x00},
- {0x4d, 0x00},
- {0x4e, 0xff},
- {0x4f, 0xff},
- {0x50, 0xff},
- {0x51, 0xff},
- {0x52, 0xff},
- {0x53, 0xff},
- {0x54, 0xff},
- {0x55, 0xff},
- {0x56, 0xff},
- {0x57, 0xff},
- {0x58, 0xff},
- {0x59, 0xff},
- {0x5a, 0xff},
- {0x5b, 0xfe},
- {0x5c, 0xff},
- {0x5d, 0x8f},
- {0x5e, 0xff},
- {0x5f, 0x8f},
- {0x60, 0xa2},
- {0x61, 0x4a},
- {0x62, 0xf3},
- {0x63, 0x75},
- {0x64, 0xf0},
- {0x65, 0x00},
- {0x66, 0x55},
- {0x67, 0x92},
- {0x68, 0xa0},
- {0x69, 0x4a},
- {0x6a, 0x22},
- {0x6b, 0x00},
- {0x6c, 0x33},
- {0x6d, 0x44},
- {0x6e, 0x22},
- {0x6f, 0x84},
- {0x70, 0x0b},
- {0x72, 0x10},
- {0x73, 0x50},
- {0x74, 0x21},
- {0x76, 0x00},
- {0x77, 0xa5},
- {0x78, 0x80},
- {0x79, 0x80},
- {0x7a, 0x80},
- {0x7b, 0xe2},
- {0x7c, 0x00},
- {0x7d, 0xf7},
- {0x7e, 0x00},
- {0x7f, 0x00},
- };
-
- reg_w_buf(gspca_dev, reg_init_1, ARRAY_SIZE(reg_init_1));
- reg_w_buf(gspca_dev, tp6810_ov_init_common,
- ARRAY_SIZE(tp6810_ov_init_common));
- reg_w_buf(gspca_dev, reg_init_2, ARRAY_SIZE(reg_init_2));
-
- i2c_w(gspca_dev, 0x12, 0x80); /* sensor reset */
- msleep(10);
- i2c_w_buf(gspca_dev, sensor_init, ARRAY_SIZE(sensor_init));
-}
-
-/* set the gain and exposure */
-static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 gain,
- s32 blue, s32 red)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor == SENSOR_CX0342) {
- expo = (expo << 2) - 1;
- i2c_w(gspca_dev, CX0342_EXPO_LINE_L, expo);
- i2c_w(gspca_dev, CX0342_EXPO_LINE_H, expo >> 8);
- if (sd->bridge == BRIDGE_TP6800)
- i2c_w(gspca_dev, CX0342_RAW_GBGAIN_H,
- gain >> 8);
- i2c_w(gspca_dev, CX0342_RAW_GBGAIN_L, gain);
- if (sd->bridge == BRIDGE_TP6800)
- i2c_w(gspca_dev, CX0342_RAW_GRGAIN_H,
- gain >> 8);
- i2c_w(gspca_dev, CX0342_RAW_GRGAIN_L, gain);
- if (sd->sensor == SENSOR_CX0342) {
- if (sd->bridge == BRIDGE_TP6800)
- i2c_w(gspca_dev, CX0342_RAW_BGAIN_H,
- blue >> 8);
- i2c_w(gspca_dev, CX0342_RAW_BGAIN_L, blue);
- if (sd->bridge == BRIDGE_TP6800)
- i2c_w(gspca_dev, CX0342_RAW_RGAIN_H,
- red >> 8);
- i2c_w(gspca_dev, CX0342_RAW_RGAIN_L, red);
- }
- i2c_w(gspca_dev, CX0342_SYS_CTRL_0,
- sd->bridge == BRIDGE_TP6800 ? 0x80 : 0x81);
- return;
- }
-
- /* soi763a */
- i2c_w(gspca_dev, 0x10, /* AEC_H (exposure time) */
- expo);
-/* i2c_w(gspca_dev, 0x76, 0x02); * AEC_L ([1:0] */
- i2c_w(gspca_dev, 0x00, /* gain */
- gain);
-}
-
-/* set the JPEG quantization tables */
-static void set_dqt(struct gspca_dev *gspca_dev, u8 q)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* update the jpeg quantization tables */
- PDEBUG(D_STREAM, "q %d -> %d", sd->quality, q);
- sd->quality = q;
- if (q > 16)
- q = 16;
- if (sd->sensor == SENSOR_SOI763A)
- jpeg_set_qual(sd->jpeg_hdr, jpeg_q[q]);
- else
- memcpy(&sd->jpeg_hdr[JPEG_QT0_OFFSET - 1],
- DQT[q], sizeof DQT[0]);
-}
-
-/* set the JPEG compression quality factor */
-static void setquality(struct gspca_dev *gspca_dev, s32 q)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (q != 16)
- q = 15 - q;
-
- reg_w(gspca_dev, TP6800_R7A_BLK_THRLD, 0x00);
- reg_w(gspca_dev, TP6800_R79_QUALITY, 0x04);
- reg_w(gspca_dev, TP6800_R79_QUALITY, q);
-
- /* auto quality */
- if (q == 15 && sd->bridge == BRIDGE_TP6810) {
- msleep(4);
- reg_w(gspca_dev, TP6800_R7A_BLK_THRLD, 0x19);
- }
-}
-
-static const u8 color_null[18] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-static const u8 color_gain[NSENSORS][18] = {
-[SENSOR_CX0342] =
- {0x4c, 0x00, 0xa9, 0x00, 0x31, 0x00, /* Y R/G/B (LE values) */
- 0xb6, 0x03, 0x6c, 0x03, 0xe0, 0x00, /* U R/G/B */
- 0xdf, 0x00, 0x46, 0x03, 0xdc, 0x03}, /* V R/G/B */
-[SENSOR_SOI763A] =
- {0x4c, 0x00, 0x95, 0x00, 0x1d, 0x00, /* Y R/G/B (LE values) */
- 0xb6, 0x03, 0x6c, 0x03, 0xd7, 0x00, /* U R/G/B */
- 0xd5, 0x00, 0x46, 0x03, 0xdc, 0x03}, /* V R/G/B */
-};
-
-static void setgamma(struct gspca_dev *gspca_dev, s32 gamma)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-#define NGAMMA 6
- static const u8 gamma_tb[NGAMMA][3][1024] = {
- { /* gamma 0 - from tp6800 + soi763a */
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02,
- 0x02, 0x03, 0x05, 0x07, 0x07, 0x08, 0x09, 0x09,
- 0x0a, 0x0c, 0x0c, 0x0d, 0x0e, 0x0e, 0x10, 0x11,
- 0x11, 0x12, 0x14, 0x14, 0x15, 0x16, 0x16, 0x17,
- 0x17, 0x18, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1e,
- 0x1e, 0x1f, 0x1f, 0x20, 0x20, 0x22, 0x23, 0x23,
- 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28,
- 0x29, 0x29, 0x2b, 0x2c, 0x2c, 0x2d, 0x2d, 0x2f,
- 0x2f, 0x30, 0x30, 0x31, 0x31, 0x33, 0x33, 0x34,
- 0x34, 0x34, 0x35, 0x35, 0x37, 0x37, 0x38, 0x38,
- 0x39, 0x39, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3c,
- 0x3c, 0x3d, 0x3d, 0x3f, 0x3f, 0x40, 0x40, 0x40,
- 0x42, 0x42, 0x43, 0x43, 0x44, 0x44, 0x44, 0x45,
- 0x45, 0x47, 0x47, 0x47, 0x48, 0x48, 0x49, 0x49,
- 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c,
- 0x4d, 0x4d, 0x4d, 0x4f, 0x4f, 0x50, 0x50, 0x50,
- 0x52, 0x52, 0x52, 0x53, 0x53, 0x54, 0x54, 0x54,
- 0x55, 0x55, 0x55, 0x56, 0x56, 0x58, 0x58, 0x58,
- 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b,
- 0x5b, 0x5c, 0x5c, 0x5c, 0x5e, 0x5e, 0x5e, 0x5f,
- 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61,
- 0x62, 0x62, 0x62, 0x63, 0x63, 0x63, 0x65, 0x65,
- 0x65, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x68,
- 0x68, 0x68, 0x69, 0x69, 0x69, 0x69, 0x6a, 0x6a,
- 0x6a, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e,
- 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70,
- 0x70, 0x71, 0x71, 0x71, 0x71, 0x73, 0x73, 0x73,
- 0x74, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x77,
- 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x79,
- 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b,
- 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
- 0x7d, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80,
- 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82,
- 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x86,
- 0x86, 0x86, 0x86, 0x88, 0x88, 0x88, 0x88, 0x89,
- 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8a, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8d, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x91, 0x91, 0x91, 0x91,
- 0x92, 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x93,
- 0x94, 0x94, 0x94, 0x94, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98,
- 0x98, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e,
- 0x9e, 0x9e, 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xac, 0xad,
- 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb8,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2,
- 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3,
- 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5,
- 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc9, 0xc9, 0xc9,
- 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xca, 0xca,
- 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, 0xcc,
- 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xce,
- 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf,
- 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1,
- 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3,
- 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6,
- 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
- 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9,
- 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb,
- 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf,
- 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0,
- 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2,
- 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3,
- 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5,
- 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7,
- 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8,
- 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb,
- 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed,
- 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee,
- 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0,
- 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3,
- 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4,
- 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6,
- 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8,
- 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02,
- 0x02, 0x03, 0x05, 0x07, 0x07, 0x08, 0x09, 0x09,
- 0x0a, 0x0c, 0x0c, 0x0d, 0x0e, 0x0e, 0x10, 0x11,
- 0x11, 0x12, 0x14, 0x14, 0x15, 0x16, 0x16, 0x17,
- 0x17, 0x18, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1e,
- 0x1e, 0x1f, 0x1f, 0x20, 0x20, 0x22, 0x23, 0x23,
- 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28,
- 0x29, 0x29, 0x2b, 0x2c, 0x2c, 0x2d, 0x2d, 0x2f,
- 0x2f, 0x30, 0x30, 0x31, 0x31, 0x33, 0x33, 0x34,
- 0x34, 0x34, 0x35, 0x35, 0x37, 0x37, 0x38, 0x38,
- 0x39, 0x39, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3c,
- 0x3c, 0x3d, 0x3d, 0x3f, 0x3f, 0x40, 0x40, 0x40,
- 0x42, 0x42, 0x43, 0x43, 0x44, 0x44, 0x44, 0x45,
- 0x45, 0x47, 0x47, 0x47, 0x48, 0x48, 0x49, 0x49,
- 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c,
- 0x4d, 0x4d, 0x4d, 0x4f, 0x4f, 0x50, 0x50, 0x50,
- 0x52, 0x52, 0x52, 0x53, 0x53, 0x54, 0x54, 0x54,
- 0x55, 0x55, 0x55, 0x56, 0x56, 0x58, 0x58, 0x58,
- 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b,
- 0x5b, 0x5c, 0x5c, 0x5c, 0x5e, 0x5e, 0x5e, 0x5f,
- 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61,
- 0x62, 0x62, 0x62, 0x63, 0x63, 0x63, 0x65, 0x65,
- 0x65, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x68,
- 0x68, 0x68, 0x69, 0x69, 0x69, 0x69, 0x6a, 0x6a,
- 0x6a, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e,
- 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70,
- 0x70, 0x71, 0x71, 0x71, 0x71, 0x73, 0x73, 0x73,
- 0x74, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x77,
- 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x79,
- 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b,
- 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
- 0x7d, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80,
- 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82,
- 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x86,
- 0x86, 0x86, 0x86, 0x88, 0x88, 0x88, 0x88, 0x89,
- 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8a, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8d, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x91, 0x91, 0x91, 0x91,
- 0x92, 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x93,
- 0x94, 0x94, 0x94, 0x94, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98,
- 0x98, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e,
- 0x9e, 0x9e, 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xac, 0xad,
- 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb8,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2,
- 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3,
- 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5,
- 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc9, 0xc9, 0xc9,
- 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xca, 0xca,
- 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, 0xcc,
- 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xce,
- 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf,
- 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1,
- 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3,
- 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6,
- 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
- 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9,
- 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb,
- 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf,
- 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0,
- 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2,
- 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3,
- 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5,
- 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7,
- 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8,
- 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb,
- 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed,
- 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee,
- 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0,
- 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3,
- 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4,
- 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6,
- 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8,
- 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02,
- 0x02, 0x03, 0x05, 0x07, 0x07, 0x08, 0x09, 0x09,
- 0x0a, 0x0c, 0x0c, 0x0d, 0x0e, 0x0e, 0x10, 0x11,
- 0x11, 0x12, 0x14, 0x14, 0x15, 0x16, 0x16, 0x17,
- 0x17, 0x18, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1e,
- 0x1e, 0x1f, 0x1f, 0x20, 0x20, 0x22, 0x23, 0x23,
- 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28,
- 0x29, 0x29, 0x2b, 0x2c, 0x2c, 0x2d, 0x2d, 0x2f,
- 0x2f, 0x30, 0x30, 0x31, 0x31, 0x33, 0x33, 0x34,
- 0x34, 0x34, 0x35, 0x35, 0x37, 0x37, 0x38, 0x38,
- 0x39, 0x39, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3c,
- 0x3c, 0x3d, 0x3d, 0x3f, 0x3f, 0x40, 0x40, 0x40,
- 0x42, 0x42, 0x43, 0x43, 0x44, 0x44, 0x44, 0x45,
- 0x45, 0x47, 0x47, 0x47, 0x48, 0x48, 0x49, 0x49,
- 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c,
- 0x4d, 0x4d, 0x4d, 0x4f, 0x4f, 0x50, 0x50, 0x50,
- 0x52, 0x52, 0x52, 0x53, 0x53, 0x54, 0x54, 0x54,
- 0x55, 0x55, 0x55, 0x56, 0x56, 0x58, 0x58, 0x58,
- 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b,
- 0x5b, 0x5c, 0x5c, 0x5c, 0x5e, 0x5e, 0x5e, 0x5f,
- 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61,
- 0x62, 0x62, 0x62, 0x63, 0x63, 0x63, 0x65, 0x65,
- 0x65, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x68,
- 0x68, 0x68, 0x69, 0x69, 0x69, 0x69, 0x6a, 0x6a,
- 0x6a, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e,
- 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70,
- 0x70, 0x71, 0x71, 0x71, 0x71, 0x73, 0x73, 0x73,
- 0x74, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x76,
- 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x79,
- 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b,
- 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
- 0x7d, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80,
- 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82,
- 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x86,
- 0x86, 0x86, 0x86, 0x88, 0x88, 0x88, 0x88, 0x89,
- 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8a, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8d, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x91, 0x91, 0x91, 0x91,
- 0x92, 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x93,
- 0x94, 0x94, 0x94, 0x94, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98,
- 0x98, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e,
- 0x9e, 0x9e, 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xac, 0xad,
- 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb8,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2,
- 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3,
- 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5,
- 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc9, 0xc9, 0xc9,
- 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xca, 0xca,
- 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, 0xcc,
- 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xce,
- 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf,
- 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1,
- 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3,
- 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6,
- 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
- 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9,
- 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb,
- 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf,
- 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0,
- 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2,
- 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3,
- 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5,
- 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7,
- 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8,
- 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb,
- 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed,
- 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee,
- 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0,
- 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3,
- 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4,
- 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6,
- 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8,
- 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb}
- },
- { /* gamma 1 - from tp6810 + soi763a */
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x02, 0x03, 0x05, 0x07, 0x08, 0x09, 0x0a,
- 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x15,
- 0x16, 0x17, 0x18, 0x1a, 0x1a, 0x1b, 0x1c, 0x1e,
- 0x1f, 0x20, 0x22, 0x22, 0x23, 0x25, 0x26, 0x27,
- 0x27, 0x28, 0x29, 0x2b, 0x2b, 0x2c, 0x2d, 0x2f,
- 0x2f, 0x30, 0x31, 0x33, 0x33, 0x34, 0x35, 0x35,
- 0x37, 0x38, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c,
- 0x3c, 0x3d, 0x3f, 0x3f, 0x40, 0x42, 0x42, 0x43,
- 0x43, 0x44, 0x45, 0x45, 0x47, 0x47, 0x48, 0x49,
- 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d,
- 0x4f, 0x4f, 0x50, 0x50, 0x52, 0x52, 0x53, 0x53,
- 0x54, 0x54, 0x55, 0x56, 0x56, 0x58, 0x58, 0x59,
- 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c, 0x5e,
- 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x61, 0x61,
- 0x62, 0x62, 0x63, 0x63, 0x65, 0x65, 0x65, 0x66,
- 0x66, 0x67, 0x67, 0x68, 0x68, 0x69, 0x69, 0x69,
- 0x6a, 0x6a, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e,
- 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70, 0x71, 0x71,
- 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x75, 0x75,
- 0x77, 0x77, 0x77, 0x78, 0x78, 0x79, 0x79, 0x79,
- 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
- 0x7d, 0x7d, 0x7d, 0x7f, 0x7f, 0x80, 0x80, 0x80,
- 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x84, 0x84,
- 0x84, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x88,
- 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8a,
- 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e,
- 0x8e, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x91,
- 0x91, 0x91, 0x92, 0x92, 0x92, 0x92, 0x93, 0x93,
- 0x93, 0x94, 0x94, 0x94, 0x96, 0x96, 0x96, 0x97,
- 0x97, 0x97, 0x97, 0x98, 0x98, 0x98, 0x99, 0x99,
- 0x99, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b,
- 0x9c, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9e,
- 0x9e, 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa2, 0xa3, 0xa3,
- 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab, 0xab,
- 0xac, 0xac, 0xac, 0xad, 0xad, 0xad, 0xad, 0xae,
- 0xae, 0xae, 0xae, 0xaf, 0xaf, 0xaf, 0xaf, 0xb0,
- 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3, 0xb4,
- 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb6, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb8,
- 0xb9, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba,
- 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0xc2,
- 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3, 0xc4, 0xc4,
- 0xc4, 0xc4, 0xc4, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7,
- 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca,
- 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc,
- 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xcd, 0xce,
- 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf,
- 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1,
- 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd4,
- 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
- 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8,
- 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xda,
- 0xda, 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde,
- 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0,
- 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1,
- 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3,
- 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4,
- 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6,
- 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe8,
- 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, 0xe9, 0xe9,
- 0xe9, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec,
- 0xec, 0xec, 0xec, 0xed, 0xed, 0xed, 0xed, 0xed,
- 0xee, 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef,
- 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
- 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, 0xf3, 0xf3,
- 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5,
- 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6,
- 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8,
- 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9,
- 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
- 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe,
- 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
- 0x05, 0x07, 0x07, 0x08, 0x09, 0x0a, 0x0c, 0x0d,
- 0x0e, 0x10, 0x10, 0x11, 0x12, 0x14, 0x15, 0x15,
- 0x16, 0x17, 0x18, 0x1a, 0x1a, 0x1b, 0x1c, 0x1e,
- 0x1e, 0x1f, 0x20, 0x20, 0x22, 0x23, 0x25, 0x25,
- 0x26, 0x27, 0x27, 0x28, 0x29, 0x29, 0x2b, 0x2c,
- 0x2c, 0x2d, 0x2d, 0x2f, 0x30, 0x30, 0x31, 0x31,
- 0x33, 0x34, 0x34, 0x35, 0x35, 0x37, 0x38, 0x38,
- 0x39, 0x39, 0x3a, 0x3a, 0x3b, 0x3b, 0x3c, 0x3d,
- 0x3d, 0x3f, 0x3f, 0x40, 0x40, 0x42, 0x42, 0x43,
- 0x43, 0x44, 0x44, 0x45, 0x45, 0x47, 0x47, 0x48,
- 0x48, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4c,
- 0x4c, 0x4d, 0x4d, 0x4d, 0x4f, 0x4f, 0x50, 0x50,
- 0x52, 0x52, 0x53, 0x53, 0x53, 0x54, 0x54, 0x55,
- 0x55, 0x56, 0x56, 0x56, 0x58, 0x58, 0x59, 0x59,
- 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c,
- 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x60, 0x60, 0x60,
- 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, 0x65,
- 0x65, 0x65, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67,
- 0x68, 0x68, 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a,
- 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e, 0x6e,
- 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x71,
- 0x71, 0x71, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74,
- 0x75, 0x75, 0x75, 0x77, 0x77, 0x77, 0x78, 0x78,
- 0x78, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a,
- 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d,
- 0x7d, 0x7d, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80,
- 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82,
- 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x86,
- 0x86, 0x86, 0x88, 0x88, 0x88, 0x88, 0x89, 0x89,
- 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8d, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x90,
- 0x91, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92, 0x92,
- 0x93, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x94,
- 0x96, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, 0x97,
- 0x98, 0x98, 0x98, 0x98, 0x99, 0x99, 0x99, 0x99,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b,
- 0x9b, 0x9c, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d,
- 0x9d, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, 0xab,
- 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xac, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xae,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb8,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
- 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3,
- 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5,
- 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc9,
- 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca,
- 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc,
- 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce, 0xce, 0xcf,
- 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0,
- 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
- 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4,
- 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
- 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8,
- 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9,
- 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb, 0xdb,
- 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf,
- 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0,
- 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2,
- 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3,
- 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4,
- 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6,
- 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7,
- 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9,
- 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
- 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, 0xed,
- 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee,
- 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0,
- 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1,
- 0xf1, 0xf1, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4,
- 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5,
- 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7,
- 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8,
- 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc,
- 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
- 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe,
- 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x02, 0x03, 0x05, 0x05, 0x07,
- 0x08, 0x09, 0x0a, 0x0a, 0x0c, 0x0d, 0x0e, 0x0e,
- 0x10, 0x11, 0x12, 0x12, 0x14, 0x15, 0x16, 0x16,
- 0x17, 0x18, 0x18, 0x1a, 0x1b, 0x1b, 0x1c, 0x1e,
- 0x1e, 0x1f, 0x1f, 0x20, 0x22, 0x22, 0x23, 0x23,
- 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x29, 0x29,
- 0x2b, 0x2b, 0x2c, 0x2c, 0x2d, 0x2d, 0x2f, 0x30,
- 0x30, 0x31, 0x31, 0x33, 0x33, 0x34, 0x34, 0x35,
- 0x35, 0x37, 0x37, 0x38, 0x38, 0x39, 0x39, 0x3a,
- 0x3a, 0x3b, 0x3b, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d,
- 0x3f, 0x3f, 0x40, 0x40, 0x42, 0x42, 0x42, 0x43,
- 0x43, 0x44, 0x44, 0x45, 0x45, 0x47, 0x47, 0x47,
- 0x48, 0x48, 0x49, 0x49, 0x49, 0x4a, 0x4a, 0x4b,
- 0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, 0x4f,
- 0x4f, 0x50, 0x50, 0x50, 0x52, 0x52, 0x52, 0x53,
- 0x53, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x56,
- 0x56, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x5a,
- 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c,
- 0x5e, 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x60, 0x60,
- 0x60, 0x61, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63,
- 0x63, 0x63, 0x65, 0x65, 0x65, 0x66, 0x66, 0x66,
- 0x66, 0x67, 0x67, 0x67, 0x68, 0x68, 0x68, 0x69,
- 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6a, 0x6c, 0x6c,
- 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e,
- 0x6f, 0x6f, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x71,
- 0x71, 0x71, 0x71, 0x73, 0x73, 0x73, 0x74, 0x74,
- 0x74, 0x74, 0x75, 0x75, 0x75, 0x75, 0x77, 0x77,
- 0x77, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
- 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b,
- 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
- 0x7d, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80,
- 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82,
- 0x82, 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85,
- 0x85, 0x86, 0x86, 0x86, 0x86, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x89, 0x89, 0x89, 0x89, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x91, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92,
- 0x92, 0x92, 0x93, 0x93, 0x93, 0x93, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x97, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98,
- 0x98, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d,
- 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1,
- 0xb1, 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, 0xb2,
- 0xb2, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb4,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba,
- 0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0xc2,
- 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3,
- 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5,
- 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7,
- 0xc7, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca,
- 0xca, 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcb,
- 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xce, 0xce,
- 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf,
- 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0,
- 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3,
- 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
- 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd7,
- 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8,
- 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9,
- 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb,
- 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
- 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0,
- 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1,
- 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3,
- 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4,
- 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
- 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7,
- 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8,
- 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb,
- 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec,
- 0xec, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xee,
- 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef, 0xef,
- 0xef, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf1,
- 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, 0xf3, 0xf3, 0xf3,
- 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, 0xf5,
- 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6,
- 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8,
- 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc,
- 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd,
- 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
- },
- { /* gamma 2 */
- {0x00, 0x01, 0x02, 0x05, 0x07, 0x08, 0x0a, 0x0c,
- 0x0d, 0x0e, 0x10, 0x12, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x1a, 0x1b, 0x1c, 0x1e, 0x1f, 0x20, 0x22,
- 0x23, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2b, 0x2c,
- 0x2d, 0x2d, 0x2f, 0x30, 0x31, 0x33, 0x34, 0x34,
- 0x35, 0x37, 0x38, 0x38, 0x39, 0x3a, 0x3b, 0x3b,
- 0x3c, 0x3d, 0x3f, 0x3f, 0x40, 0x42, 0x42, 0x43,
- 0x44, 0x44, 0x45, 0x47, 0x47, 0x48, 0x49, 0x49,
- 0x4a, 0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4f, 0x4f,
- 0x50, 0x50, 0x52, 0x53, 0x53, 0x54, 0x54, 0x55,
- 0x55, 0x56, 0x56, 0x58, 0x58, 0x59, 0x5a, 0x5a,
- 0x5b, 0x5b, 0x5c, 0x5c, 0x5e, 0x5e, 0x5f, 0x5f,
- 0x60, 0x60, 0x61, 0x61, 0x62, 0x62, 0x63, 0x63,
- 0x65, 0x65, 0x65, 0x66, 0x66, 0x67, 0x67, 0x68,
- 0x68, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6c, 0x6c,
- 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x70,
- 0x70, 0x70, 0x71, 0x71, 0x73, 0x73, 0x73, 0x74,
- 0x74, 0x75, 0x75, 0x75, 0x77, 0x77, 0x78, 0x78,
- 0x78, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7b, 0x7b,
- 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7f, 0x7f,
- 0x7f, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82,
- 0x82, 0x82, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85,
- 0x86, 0x86, 0x86, 0x88, 0x88, 0x88, 0x89, 0x89,
- 0x89, 0x8a, 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f,
- 0x8f, 0x90, 0x90, 0x90, 0x91, 0x91, 0x91, 0x91,
- 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x93, 0x94,
- 0x94, 0x94, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97,
- 0x97, 0x98, 0x98, 0x98, 0x98, 0x99, 0x99, 0x99,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b,
- 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e,
- 0x9e, 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa0, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa2, 0xa3,
- 0xa3, 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, 0xa6, 0xa6, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xab,
- 0xab, 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xae,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2,
- 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3, 0xb4, 0xb4,
- 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb6, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb8,
- 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba,
- 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbe, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xc0, 0xc0,
- 0xc0, 0xc0, 0xc0, 0xc2, 0xc2, 0xc2, 0xc2, 0xc3,
- 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4,
- 0xc4, 0xc4, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7,
- 0xc7, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca,
- 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb,
- 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce, 0xce,
- 0xce, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0,
- 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd1,
- 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4,
- 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd6,
- 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8,
- 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9,
- 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda,
- 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde,
- 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0,
- 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1,
- 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2,
- 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4,
- 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, 0xe5,
- 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
- 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8,
- 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, 0xe9, 0xe9,
- 0xe9, 0xe9, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
- 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, 0xed, 0xed,
- 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, 0xee,
- 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0,
- 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1,
- 0xf1, 0xf1, 0xf1, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3,
- 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5,
- 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6,
- 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7,
- 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9,
- 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb},
- {0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x05,
- 0x07, 0x08, 0x09, 0x0a, 0x0d, 0x0e, 0x10, 0x11,
- 0x12, 0x14, 0x15, 0x16, 0x16, 0x17, 0x18, 0x1a,
- 0x1b, 0x1c, 0x1e, 0x1f, 0x20, 0x20, 0x22, 0x23,
- 0x25, 0x26, 0x26, 0x27, 0x28, 0x29, 0x29, 0x2b,
- 0x2c, 0x2d, 0x2d, 0x2f, 0x30, 0x30, 0x31, 0x33,
- 0x33, 0x34, 0x35, 0x35, 0x37, 0x38, 0x38, 0x39,
- 0x3a, 0x3a, 0x3b, 0x3b, 0x3c, 0x3d, 0x3d, 0x3f,
- 0x3f, 0x40, 0x42, 0x42, 0x43, 0x43, 0x44, 0x44,
- 0x45, 0x45, 0x47, 0x47, 0x48, 0x48, 0x49, 0x4a,
- 0x4a, 0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d,
- 0x4f, 0x4f, 0x50, 0x50, 0x52, 0x52, 0x53, 0x53,
- 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x58,
- 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b,
- 0x5c, 0x5c, 0x5c, 0x5e, 0x5e, 0x5f, 0x5f, 0x5f,
- 0x60, 0x60, 0x61, 0x61, 0x61, 0x62, 0x62, 0x63,
- 0x63, 0x63, 0x65, 0x65, 0x65, 0x66, 0x66, 0x67,
- 0x67, 0x67, 0x68, 0x68, 0x68, 0x69, 0x69, 0x69,
- 0x6a, 0x6a, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d,
- 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70,
- 0x70, 0x71, 0x71, 0x71, 0x73, 0x73, 0x73, 0x73,
- 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x77, 0x77,
- 0x77, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79,
- 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c,
- 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7f, 0x7f,
- 0x7f, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81,
- 0x82, 0x82, 0x82, 0x82, 0x84, 0x84, 0x84, 0x84,
- 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x88,
- 0x88, 0x88, 0x88, 0x89, 0x89, 0x89, 0x89, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, 0x8b, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x90, 0x91,
- 0x91, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92, 0x92,
- 0x93, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x96, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97,
- 0x97, 0x98, 0x98, 0x98, 0x98, 0x98, 0x99, 0x99,
- 0x99, 0x99, 0x99, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b,
- 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e,
- 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xad, 0xad, 0xad, 0xad, 0xad, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb1,
- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2,
- 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
- 0xb7, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb9,
- 0xb9, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba,
- 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
- 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3,
- 0xc3, 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4,
- 0xc4, 0xc4, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7,
- 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc9, 0xc9, 0xc9,
- 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xca, 0xca,
- 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc,
- 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce,
- 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
- 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1,
- 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3,
- 0xd3, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd4,
- 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
- 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8,
- 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9,
- 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda,
- 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb,
- 0xdb, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf,
- 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0,
- 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1,
- 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2,
- 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4,
- 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5,
- 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6,
- 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7,
- 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9,
- 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb,
- 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec,
- 0xec, 0xec, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed,
- 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xef,
- 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0,
- 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
- 0xf1, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4,
- 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, 0xf5,
- 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6,
- 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7,
- 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9,
- 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb},
- {0x00, 0x00, 0x00, 0x01, 0x02, 0x05, 0x07, 0x08,
- 0x09, 0x0a, 0x0c, 0x0e, 0x10, 0x11, 0x12, 0x14,
- 0x15, 0x16, 0x17, 0x18, 0x1a, 0x1b, 0x1c, 0x1e,
- 0x1f, 0x20, 0x20, 0x22, 0x23, 0x25, 0x26, 0x27,
- 0x28, 0x28, 0x29, 0x2b, 0x2c, 0x2d, 0x2d, 0x2f,
- 0x30, 0x31, 0x31, 0x33, 0x34, 0x35, 0x35, 0x37,
- 0x38, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3c,
- 0x3d, 0x3f, 0x3f, 0x40, 0x40, 0x42, 0x43, 0x43,
- 0x44, 0x44, 0x45, 0x47, 0x47, 0x48, 0x48, 0x49,
- 0x4a, 0x4a, 0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4d,
- 0x4f, 0x4f, 0x50, 0x50, 0x52, 0x52, 0x53, 0x53,
- 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x58, 0x58,
- 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c,
- 0x5c, 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x61,
- 0x61, 0x61, 0x62, 0x62, 0x63, 0x63, 0x65, 0x65,
- 0x65, 0x66, 0x66, 0x67, 0x67, 0x67, 0x68, 0x68,
- 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6c, 0x6c,
- 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f,
- 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x73, 0x73,
- 0x73, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x77,
- 0x77, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x7a,
- 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c,
- 0x7c, 0x7d, 0x7d, 0x7d, 0x7f, 0x7f, 0x7f, 0x80,
- 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82,
- 0x82, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85,
- 0x86, 0x86, 0x86, 0x88, 0x88, 0x88, 0x88, 0x89,
- 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8a, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90,
- 0x91, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92, 0x92,
- 0x93, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x94,
- 0x96, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, 0x97,
- 0x98, 0x98, 0x98, 0x98, 0x99, 0x99, 0x99, 0x99,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b,
- 0x9b, 0x9c, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d,
- 0x9d, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xac, 0xac, 0xac, 0xac,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xb0,
- 0xb0, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1,
- 0xb1, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3,
- 0xb3, 0xb3, 0xb3, 0xb4, 0xb3, 0xb4, 0xb4, 0xb4,
- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xba, 0xba,
- 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe,
- 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0xc2,
- 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3,
- 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5,
- 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7,
- 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca,
- 0xca, 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcb,
- 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xce, 0xce,
- 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf,
- 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0,
- 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3,
- 0xd3, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd4,
- 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
- 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8,
- 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9,
- 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda,
- 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde,
- 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf,
- 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0,
- 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2,
- 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3,
- 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4,
- 0xe4, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6,
- 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7,
- 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8,
- 0xe8, 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9,
- 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec,
- 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, 0xed, 0xed,
- 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, 0xee,
- 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0,
- 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1,
- 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, 0xf3, 0xf3, 0xf3,
- 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4,
- 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6,
- 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7,
- 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8,
- 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb}
- },
- { /* gamma 3 - from tp6810 + cx0342 */
- {0x08, 0x09, 0x0c, 0x0d, 0x10, 0x11, 0x14, 0x15,
- 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x1f, 0x20, 0x23,
- 0x25, 0x26, 0x27, 0x28, 0x2b, 0x2c, 0x2d, 0x2f,
- 0x30, 0x31, 0x33, 0x34, 0x35, 0x37, 0x38, 0x39,
- 0x3a, 0x3b, 0x3c, 0x3d, 0x3f, 0x40, 0x42, 0x43,
- 0x44, 0x45, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b,
- 0x4c, 0x4d, 0x4d, 0x4f, 0x50, 0x52, 0x53, 0x53,
- 0x54, 0x55, 0x56, 0x56, 0x58, 0x59, 0x5a, 0x5a,
- 0x5b, 0x5c, 0x5c, 0x5e, 0x5f, 0x5f, 0x60, 0x61,
- 0x61, 0x62, 0x63, 0x63, 0x65, 0x66, 0x66, 0x67,
- 0x68, 0x68, 0x69, 0x69, 0x6a, 0x6c, 0x6c, 0x6d,
- 0x6d, 0x6e, 0x6f, 0x6f, 0x70, 0x70, 0x71, 0x73,
- 0x73, 0x74, 0x74, 0x75, 0x75, 0x77, 0x77, 0x78,
- 0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c,
- 0x7d, 0x7d, 0x7f, 0x7f, 0x80, 0x80, 0x81, 0x81,
- 0x82, 0x82, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86,
- 0x86, 0x88, 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8b,
- 0x8b, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f,
- 0x90, 0x90, 0x91, 0x91, 0x91, 0x92, 0x92, 0x93,
- 0x93, 0x93, 0x94, 0x94, 0x96, 0x96, 0x97, 0x97,
- 0x97, 0x98, 0x98, 0x99, 0x99, 0x99, 0x9a, 0x9a,
- 0x9a, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d,
- 0x9e, 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1,
- 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4,
- 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, 0xa8, 0xa8,
- 0xa8, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab, 0xac,
- 0xac, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xae,
- 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1,
- 0xb1, 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3,
- 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7,
- 0xb7, 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9,
- 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd,
- 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf,
- 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0xc2, 0xc2,
- 0xc3, 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc5,
- 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7,
- 0xc7, 0xc7, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca,
- 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc,
- 0xcc, 0xcd, 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce,
- 0xce, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0,
- 0xd0, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3,
- 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6,
- 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8,
- 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xda,
- 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf,
- 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1,
- 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2,
- 0xe3, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4,
- 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6,
- 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8,
- 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb,
- 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec,
- 0xed, 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee,
- 0xee, 0xee, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0,
- 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
- 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4,
- 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6,
- 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7,
- 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9,
- 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
- 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd,
- 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
- {0x03, 0x05, 0x07, 0x09, 0x0a, 0x0c, 0x0d, 0x10,
- 0x11, 0x12, 0x14, 0x15, 0x17, 0x18, 0x1a, 0x1b,
- 0x1c, 0x1e, 0x1f, 0x20, 0x22, 0x23, 0x25, 0x26,
- 0x27, 0x28, 0x29, 0x2b, 0x2c, 0x2c, 0x2d, 0x2f,
- 0x30, 0x31, 0x33, 0x33, 0x34, 0x35, 0x37, 0x38,
- 0x38, 0x39, 0x3a, 0x3b, 0x3b, 0x3c, 0x3d, 0x3f,
- 0x3f, 0x40, 0x42, 0x42, 0x43, 0x44, 0x45, 0x45,
- 0x47, 0x47, 0x48, 0x49, 0x49, 0x4a, 0x4b, 0x4b,
- 0x4c, 0x4d, 0x4d, 0x4f, 0x4f, 0x50, 0x52, 0x52,
- 0x53, 0x53, 0x54, 0x54, 0x55, 0x55, 0x56, 0x58,
- 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c,
- 0x5c, 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x61,
- 0x61, 0x62, 0x62, 0x63, 0x63, 0x65, 0x65, 0x66,
- 0x66, 0x67, 0x67, 0x67, 0x68, 0x68, 0x69, 0x69,
- 0x6a, 0x6a, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6e,
- 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70, 0x71, 0x71,
- 0x71, 0x73, 0x73, 0x74, 0x74, 0x74, 0x75, 0x75,
- 0x77, 0x77, 0x77, 0x78, 0x78, 0x79, 0x79, 0x79,
- 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c,
- 0x7d, 0x7d, 0x7d, 0x7f, 0x7f, 0x7f, 0x80, 0x80,
- 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x84,
- 0x84, 0x84, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86,
- 0x88, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a,
- 0x8a, 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x90, 0x90,
- 0x90, 0x91, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92,
- 0x93, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x96,
- 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, 0x98, 0x98,
- 0x98, 0x98, 0x99, 0x99, 0x99, 0x9a, 0x9a, 0x9a,
- 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0x9e,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab,
- 0xab, 0xac, 0xac, 0xac, 0xac, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xae, 0xae, 0xae, 0xae, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb1,
- 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4,
- 0xb4, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb8, 0xb9,
- 0xb9, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba,
- 0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0,
- 0xc0, 0xc0, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc3,
- 0xc3, 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4,
- 0xc4, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7,
- 0xc7, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca,
- 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb,
- 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce,
- 0xce, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0,
- 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd1,
- 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd4,
- 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6,
- 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
- 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9,
- 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda,
- 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde,
- 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf,
- 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1,
- 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2,
- 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3,
- 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5,
- 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6,
- 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7,
- 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9,
- 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb,
- 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec,
- 0xec, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xee,
- 0xee, 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef,
- 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
- 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3,
- 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4,
- 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5,
- 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6,
- 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8,
- 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9,
- 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc,
- 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
- 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe,
- 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
- {0x07, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14,
- 0x16, 0x17, 0x18, 0x1b, 0x1c, 0x1e, 0x1f, 0x20,
- 0x23, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2b, 0x2d,
- 0x2f, 0x30, 0x31, 0x33, 0x34, 0x35, 0x37, 0x38,
- 0x39, 0x3a, 0x3b, 0x3b, 0x3c, 0x3d, 0x3f, 0x40,
- 0x42, 0x43, 0x44, 0x44, 0x45, 0x47, 0x48, 0x49,
- 0x4a, 0x4a, 0x4b, 0x4c, 0x4d, 0x4d, 0x4f, 0x50,
- 0x52, 0x52, 0x53, 0x54, 0x55, 0x55, 0x56, 0x58,
- 0x58, 0x59, 0x5a, 0x5b, 0x5b, 0x5c, 0x5e, 0x5e,
- 0x5f, 0x5f, 0x60, 0x61, 0x61, 0x62, 0x63, 0x63,
- 0x65, 0x65, 0x66, 0x67, 0x67, 0x68, 0x68, 0x69,
- 0x6a, 0x6a, 0x6c, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e,
- 0x6f, 0x70, 0x70, 0x71, 0x71, 0x73, 0x73, 0x74,
- 0x74, 0x75, 0x75, 0x77, 0x77, 0x78, 0x78, 0x79,
- 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7d,
- 0x7d, 0x7f, 0x7f, 0x80, 0x80, 0x81, 0x81, 0x81,
- 0x82, 0x82, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86,
- 0x88, 0x88, 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8b,
- 0x8b, 0x8b, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8f,
- 0x8f, 0x90, 0x90, 0x90, 0x91, 0x91, 0x92, 0x92,
- 0x92, 0x93, 0x93, 0x94, 0x94, 0x94, 0x96, 0x96,
- 0x96, 0x97, 0x97, 0x98, 0x98, 0x98, 0x99, 0x99,
- 0x99, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c,
- 0x9c, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0xa0,
- 0xa0, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3,
- 0xa3, 0xa3, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5,
- 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xa8, 0xa9,
- 0xa9, 0xa9, 0xab, 0xab, 0xab, 0xac, 0xac, 0xac,
- 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, 0xb1,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb4,
- 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7,
- 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf,
- 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2,
- 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3, 0xc4,
- 0xc4, 0xc4, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7, 0xc9, 0xc9,
- 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xca, 0xcb, 0xcb,
- 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce, 0xcf,
- 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1,
- 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3,
- 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd6,
- 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8,
- 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda,
- 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde,
- 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0,
- 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2,
- 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4,
- 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, 0xe5,
- 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7,
- 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9,
- 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb, 0xeb,
- 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, 0xed,
- 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, 0xee,
- 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0,
- 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3,
- 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4,
- 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6,
- 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7,
- 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9,
- 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
- 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd,
- 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
- },
- { /* gamma 4 - from tp6800 + soi763a */
- {0x11, 0x14, 0x15, 0x17, 0x1a, 0x1b, 0x1e, 0x1f,
- 0x22, 0x23, 0x25, 0x27, 0x28, 0x2b, 0x2c, 0x2d,
- 0x2f, 0x31, 0x33, 0x34, 0x35, 0x38, 0x39, 0x3a,
- 0x3b, 0x3c, 0x3d, 0x40, 0x42, 0x43, 0x44, 0x45,
- 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4f,
- 0x50, 0x52, 0x53, 0x53, 0x54, 0x55, 0x56, 0x58,
- 0x59, 0x5a, 0x5b, 0x5b, 0x5c, 0x5e, 0x5f, 0x60,
- 0x61, 0x61, 0x62, 0x63, 0x65, 0x65, 0x66, 0x67,
- 0x68, 0x68, 0x69, 0x6a, 0x6c, 0x6c, 0x6d, 0x6e,
- 0x6f, 0x6f, 0x70, 0x71, 0x71, 0x73, 0x74, 0x74,
- 0x75, 0x77, 0x77, 0x78, 0x79, 0x79, 0x7a, 0x7a,
- 0x7b, 0x7c, 0x7c, 0x7d, 0x7f, 0x7f, 0x80, 0x80,
- 0x81, 0x81, 0x82, 0x84, 0x84, 0x85, 0x85, 0x86,
- 0x86, 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8b, 0x8b,
- 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x90, 0x90, 0x91,
- 0x91, 0x92, 0x92, 0x93, 0x93, 0x94, 0x94, 0x96,
- 0x96, 0x97, 0x97, 0x98, 0x98, 0x98, 0x99, 0x99,
- 0x9a, 0x9a, 0x9b, 0x9b, 0x9c, 0x9c, 0x9d, 0x9d,
- 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2,
- 0xa2, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5,
- 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9, 0xab,
- 0xab, 0xab, 0xac, 0xac, 0xad, 0xad, 0xad, 0xae,
- 0xae, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1,
- 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4,
- 0xb4, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb8, 0xb8,
- 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xbc,
- 0xbc, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf,
- 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc2, 0xc2, 0xc2,
- 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5,
- 0xc5, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc9,
- 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb,
- 0xcb, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xce,
- 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0,
- 0xd0, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3,
- 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd7, 0xd7,
- 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9,
- 0xd9, 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb,
- 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xdf,
- 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1,
- 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3,
- 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5,
- 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7,
- 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, 0xe9,
- 0xe9, 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec,
- 0xec, 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee,
- 0xee, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0,
- 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, 0xf3, 0xf3,
- 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5,
- 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7,
- 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9,
- 0xf9, 0xf9, 0xfa, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb},
- {0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11, 0x14, 0x15,
- 0x16, 0x17, 0x1a, 0x1b, 0x1c, 0x1e, 0x1f, 0x20,
- 0x23, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2b, 0x2c,
- 0x2d, 0x2f, 0x30, 0x31, 0x33, 0x34, 0x34, 0x35,
- 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d,
- 0x3f, 0x40, 0x42, 0x42, 0x43, 0x44, 0x45, 0x45,
- 0x47, 0x48, 0x49, 0x49, 0x4a, 0x4b, 0x4b, 0x4c,
- 0x4d, 0x4f, 0x4f, 0x50, 0x52, 0x52, 0x53, 0x54,
- 0x54, 0x55, 0x55, 0x56, 0x58, 0x58, 0x59, 0x5a,
- 0x5a, 0x5b, 0x5b, 0x5c, 0x5e, 0x5e, 0x5f, 0x5f,
- 0x60, 0x60, 0x61, 0x61, 0x62, 0x63, 0x63, 0x65,
- 0x65, 0x66, 0x66, 0x67, 0x67, 0x68, 0x68, 0x69,
- 0x69, 0x6a, 0x6a, 0x6c, 0x6c, 0x6d, 0x6d, 0x6e,
- 0x6e, 0x6f, 0x6f, 0x70, 0x70, 0x71, 0x71, 0x73,
- 0x73, 0x74, 0x74, 0x74, 0x75, 0x75, 0x77, 0x77,
- 0x78, 0x78, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7b,
- 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7f, 0x7f,
- 0x7f, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x82,
- 0x84, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86, 0x86,
- 0x88, 0x88, 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8a,
- 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e,
- 0x8e, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x91, 0x91,
- 0x91, 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x94,
- 0x94, 0x94, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97,
- 0x98, 0x98, 0x98, 0x98, 0x99, 0x99, 0x99, 0x9a,
- 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2,
- 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa4,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa8, 0xa8, 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xab,
- 0xaa, 0xab, 0xab, 0xac, 0xac, 0xac, 0xad, 0xad,
- 0xad, 0xad, 0xae, 0xae, 0xae, 0xae, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1,
- 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3,
- 0xb3, 0xb3, 0xb4, 0xb4, 0xb4, 0xb4, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8,
- 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xba, 0xba,
- 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbf, 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0,
- 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3,
- 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5,
- 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7,
- 0xc7, 0xc7, 0xc7, 0xc7, 0xc9, 0xc9, 0xc9, 0xc9,
- 0xca, 0xca, 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb,
- 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce,
- 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0,
- 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3,
- 0xd3, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd4,
- 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd7, 0xd7,
- 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8,
- 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda,
- 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde,
- 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf,
- 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1,
- 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2,
- 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4,
- 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
- 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7,
- 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8,
- 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb,
- 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec,
- 0xec, 0xec, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed,
- 0xee, 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef,
- 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
- 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3,
- 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4,
- 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5,
- 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7,
- 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8,
- 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb},
- {0x0d, 0x10, 0x11, 0x14, 0x15, 0x17, 0x18, 0x1b,
- 0x1c, 0x1e, 0x20, 0x22, 0x23, 0x26, 0x27, 0x28,
- 0x29, 0x2b, 0x2d, 0x2f, 0x30, 0x31, 0x33, 0x34,
- 0x35, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d,
- 0x3f, 0x40, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48,
- 0x49, 0x4a, 0x4b, 0x4b, 0x4c, 0x4d, 0x4f, 0x50,
- 0x52, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58,
- 0x59, 0x5a, 0x5a, 0x5b, 0x5c, 0x5e, 0x5e, 0x5f,
- 0x60, 0x60, 0x61, 0x62, 0x62, 0x63, 0x65, 0x65,
- 0x66, 0x67, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6c,
- 0x6c, 0x6d, 0x6d, 0x6e, 0x6f, 0x6f, 0x70, 0x70,
- 0x71, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75, 0x77,
- 0x78, 0x78, 0x79, 0x79, 0x7a, 0x7a, 0x7b, 0x7b,
- 0x7c, 0x7c, 0x7d, 0x7d, 0x7f, 0x7f, 0x80, 0x80,
- 0x81, 0x81, 0x82, 0x82, 0x84, 0x84, 0x85, 0x85,
- 0x86, 0x86, 0x88, 0x88, 0x89, 0x89, 0x8a, 0x8a,
- 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f,
- 0x8f, 0x90, 0x90, 0x91, 0x91, 0x91, 0x92, 0x92,
- 0x93, 0x93, 0x94, 0x94, 0x94, 0x96, 0x96, 0x97,
- 0x97, 0x98, 0x98, 0x98, 0x99, 0x99, 0x9a, 0x9a,
- 0x9a, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d,
- 0x9d, 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1,
- 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4,
- 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, 0xa8, 0xa8,
- 0xa8, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab, 0xac,
- 0xac, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xae,
- 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1,
- 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb4,
- 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7,
- 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba,
- 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd,
- 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf,
- 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0xc2, 0xc2, 0xc3,
- 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5,
- 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7,
- 0xc7, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca,
- 0xca, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcc,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce,
- 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, 0xd0,
- 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3,
- 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd6,
- 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, 0xd8,
- 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda,
- 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf,
- 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1,
- 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3,
- 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5,
- 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6,
- 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8,
- 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb,
- 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed,
- 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee,
- 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0,
- 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3,
- 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4,
- 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6,
- 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8,
- 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9,
- 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb}
- },
- { /* gamma 5 */
- {0x16, 0x18, 0x19, 0x1b, 0x1d, 0x1e, 0x20, 0x21,
- 0x23, 0x24, 0x25, 0x27, 0x28, 0x2a, 0x2b, 0x2c,
- 0x2d, 0x2f, 0x30, 0x31, 0x32, 0x34, 0x35, 0x36,
- 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e,
- 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55,
- 0x56, 0x56, 0x57, 0x58, 0x59, 0x59, 0x5a, 0x5b,
- 0x5c, 0x5c, 0x5d, 0x5e, 0x5f, 0x5f, 0x60, 0x61,
- 0x62, 0x62, 0x63, 0x64, 0x64, 0x65, 0x66, 0x66,
- 0x67, 0x68, 0x68, 0x69, 0x6a, 0x6a, 0x6b, 0x6b,
- 0x6c, 0x6d, 0x6d, 0x6e, 0x6f, 0x6f, 0x70, 0x70,
- 0x71, 0x71, 0x72, 0x73, 0x73, 0x74, 0x74, 0x75,
- 0x75, 0x76, 0x77, 0x77, 0x78, 0x78, 0x79, 0x79,
- 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7e,
- 0x7e, 0x7f, 0x7f, 0x80, 0x80, 0x81, 0x81, 0x82,
- 0x82, 0x83, 0x83, 0x84, 0x84, 0x84, 0x85, 0x85,
- 0x86, 0x86, 0x87, 0x87, 0x88, 0x88, 0x89, 0x89,
- 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, 0x8c, 0x8c, 0x8d,
- 0x8d, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x90, 0x90,
- 0x91, 0x91, 0x91, 0x92, 0x92, 0x93, 0x93, 0x94,
- 0x94, 0x94, 0x95, 0x95, 0x96, 0x96, 0x96, 0x97,
- 0x97, 0x98, 0x98, 0x98, 0x99, 0x99, 0x9a, 0x9a,
- 0x9a, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, 0x9d, 0x9d,
- 0x9d, 0x9e, 0x9e, 0x9e, 0x9f, 0x9f, 0xa0, 0xa0,
- 0xa0, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3,
- 0xa3, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6,
- 0xa6, 0xa6, 0xa7, 0xa7, 0xa7, 0xa8, 0xa8, 0xa8,
- 0xa9, 0xa9, 0xa9, 0xaa, 0xaa, 0xaa, 0xab, 0xab,
- 0xab, 0xac, 0xac, 0xac, 0xad, 0xad, 0xad, 0xae,
- 0xae, 0xae, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3,
- 0xb3, 0xb3, 0xb4, 0xb4, 0xb4, 0xb4, 0xb5, 0xb5,
- 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7,
- 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba,
- 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc,
- 0xbc, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
- 0xc1, 0xc1, 0xc1, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3,
- 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5,
- 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7,
- 0xc7, 0xc8, 0xc8, 0xc8, 0xc8, 0xc9, 0xc9, 0xc9,
- 0xc9, 0xca, 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb,
- 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf,
- 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1,
- 0xd1, 0xd2, 0xd2, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3,
- 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd5, 0xd5, 0xd5,
- 0xd5, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd7, 0xd7,
- 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9,
- 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb,
- 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde,
- 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0,
- 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2,
- 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4,
- 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
- 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7,
- 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9,
- 0xe9, 0xe9, 0xea, 0xea, 0xea, 0xea, 0xea, 0xeb,
- 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec,
- 0xed, 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee,
- 0xee, 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0,
- 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
- 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3,
- 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5,
- 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6,
- 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8,
- 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd,
- 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
- {0x0f, 0x11, 0x12, 0x14, 0x15, 0x16, 0x18, 0x19,
- 0x1a, 0x1b, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
- 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
- 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x31, 0x32,
- 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x38, 0x39,
- 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3e, 0x3f, 0x3f,
- 0x40, 0x41, 0x42, 0x42, 0x43, 0x44, 0x44, 0x45,
- 0x46, 0x47, 0x47, 0x48, 0x49, 0x49, 0x4a, 0x4b,
- 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0x4e, 0x4f, 0x50,
- 0x50, 0x51, 0x51, 0x52, 0x53, 0x53, 0x54, 0x54,
- 0x55, 0x55, 0x56, 0x56, 0x57, 0x58, 0x58, 0x59,
- 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c, 0x5d,
- 0x5d, 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x61,
- 0x61, 0x62, 0x62, 0x63, 0x63, 0x64, 0x64, 0x65,
- 0x65, 0x66, 0x66, 0x66, 0x67, 0x67, 0x68, 0x68,
- 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6c,
- 0x6c, 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6f, 0x6f,
- 0x6f, 0x70, 0x70, 0x71, 0x71, 0x71, 0x72, 0x72,
- 0x73, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75, 0x75,
- 0x76, 0x76, 0x76, 0x77, 0x77, 0x78, 0x78, 0x78,
- 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b,
- 0x7b, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e,
- 0x7e, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x81,
- 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83,
- 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x86,
- 0x86, 0x86, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88,
- 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d,
- 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f,
- 0x90, 0x90, 0x90, 0x90, 0x91, 0x91, 0x91, 0x91,
- 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x93, 0x94,
- 0x94, 0x94, 0x94, 0x95, 0x95, 0x95, 0x96, 0x96,
- 0x96, 0x96, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98,
- 0x98, 0x98, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e,
- 0x9e, 0x9e, 0x9f, 0x9f, 0x9f, 0x9f, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xab, 0xab,
- 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xac, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xae,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5,
- 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb8,
- 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xba, 0xba,
- 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
- 0xbb, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0,
- 0xc0, 0xc0, 0xc0, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
- 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3,
- 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
- 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7,
- 0xc7, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc9, 0xc9,
- 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xca,
- 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc,
- 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce,
- 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0,
- 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
- 0xd1, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd3,
- 0xd3, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd4,
- 0xd4, 0xd4, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5,
- 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd7, 0xd7,
- 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8,
- 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xda,
- 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb,
- 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde,
- 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf,
- 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0,
- 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2,
- 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3,
- 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5,
- 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6,
- 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7,
- 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9,
- 0xe9, 0xe9, 0xe9, 0xe9, 0xea, 0xea, 0xea, 0xea,
- 0xea, 0xea, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
- 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, 0xed,
- 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, 0xee,
- 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0,
- 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1,
- 0xf1, 0xf1, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
- 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4,
- 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5,
- 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7,
- 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8,
- 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd,
- 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
- 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
- {0x13, 0x15, 0x16, 0x18, 0x19, 0x1b, 0x1c, 0x1e,
- 0x1f, 0x20, 0x22, 0x23, 0x24, 0x26, 0x27, 0x28,
- 0x29, 0x2a, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
- 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
- 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
- 0x42, 0x43, 0x44, 0x44, 0x45, 0x46, 0x47, 0x48,
- 0x49, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e,
- 0x4f, 0x50, 0x50, 0x51, 0x52, 0x53, 0x53, 0x54,
- 0x55, 0x55, 0x56, 0x57, 0x57, 0x58, 0x59, 0x59,
- 0x5a, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5f,
- 0x5f, 0x60, 0x60, 0x61, 0x62, 0x62, 0x63, 0x63,
- 0x64, 0x65, 0x65, 0x66, 0x66, 0x67, 0x67, 0x68,
- 0x69, 0x69, 0x6a, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c,
- 0x6d, 0x6d, 0x6e, 0x6e, 0x6f, 0x6f, 0x70, 0x70,
- 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x74, 0x74,
- 0x75, 0x75, 0x76, 0x76, 0x77, 0x77, 0x78, 0x78,
- 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c,
- 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f,
- 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x83,
- 0x83, 0x84, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86,
- 0x86, 0x87, 0x87, 0x88, 0x88, 0x88, 0x89, 0x89,
- 0x89, 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, 0x8c, 0x8c,
- 0x8c, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f,
- 0x8f, 0x90, 0x90, 0x90, 0x91, 0x91, 0x92, 0x92,
- 0x92, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x95,
- 0x95, 0x95, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97,
- 0x98, 0x98, 0x98, 0x99, 0x99, 0x99, 0x9a, 0x9a,
- 0x9a, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, 0x9d,
- 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0x9e, 0x9f, 0x9f,
- 0x9f, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4,
- 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, 0xa6,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa8, 0xa8, 0xa8, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xaa, 0xaa, 0xaa, 0xab, 0xab,
- 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xad, 0xad,
- 0xad, 0xae, 0xae, 0xae, 0xae, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb5,
- 0xb6, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb,
- 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, 0xc1, 0xc1,
- 0xc1, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3,
- 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5,
- 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7,
- 0xc7, 0xc7, 0xc7, 0xc7, 0xc8, 0xc8, 0xc8, 0xc8,
- 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca,
- 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc,
- 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xce,
- 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf,
- 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1,
- 0xd1, 0xd1, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd3,
- 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
- 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd6, 0xd6, 0xd6,
- 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8,
- 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9,
- 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb, 0xdb,
- 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde,
- 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0,
- 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1,
- 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3,
- 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4,
- 0xe4, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6,
- 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7,
- 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, 0xe9,
- 0xe9, 0xe9, 0xe9, 0xea, 0xea, 0xea, 0xea, 0xea,
- 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec,
- 0xec, 0xec, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed,
- 0xee, 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef,
- 0xef, 0xef, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
- 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf2, 0xf2, 0xf2,
- 0xf2, 0xf2, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3,
- 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5,
- 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6,
- 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8,
- 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
- 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
- 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe,
- 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
- },
- };
-
- reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x00);
- if (sd->bridge == BRIDGE_TP6810)
- reg_w(gspca_dev, 0x02, 0x28);
-/* msleep(50); */
- bulk_w(gspca_dev, 0x00, gamma_tb[gamma][0], 1024);
- bulk_w(gspca_dev, 0x01, gamma_tb[gamma][1], 1024);
- bulk_w(gspca_dev, 0x02, gamma_tb[gamma][2], 1024);
- if (sd->bridge == BRIDGE_TP6810) {
- int i;
-
- reg_w(gspca_dev, 0x02, 0x2b);
- reg_w(gspca_dev, 0x02, 0x28);
- for (i = 0; i < 6; i++)
- reg_w(gspca_dev, TP6800_R55_GAMMA_R,
- gamma_tb[gamma][0][i]);
- reg_w(gspca_dev, 0x02, 0x2b);
- reg_w(gspca_dev, 0x02, 0x28);
- for (i = 0; i < 6; i++)
- reg_w(gspca_dev, TP6800_R56_GAMMA_G,
- gamma_tb[gamma][1][i]);
- reg_w(gspca_dev, 0x02, 0x2b);
- reg_w(gspca_dev, 0x02, 0x28);
- for (i = 0; i < 6; i++)
- reg_w(gspca_dev, TP6800_R57_GAMMA_B,
- gamma_tb[gamma][2][i]);
- reg_w(gspca_dev, 0x02, 0x28);
- }
- reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x03);
-/* msleep(50); */
-}
-
-static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->bridge == BRIDGE_TP6800) {
- val |= 0x08; /* grid compensation enable */
- if (gspca_dev->width == 640)
- reg_w(gspca_dev, TP6800_R78_FORMAT, 0x00); /* vga */
- else
- val |= 0x04; /* scaling down enable */
- reg_w(gspca_dev, TP6800_R5D_DEMOSAIC_CFG, val);
- } else {
- val = (val << 5) | 0x08;
- reg_w(gspca_dev, 0x59, val);
- }
-}
-
-static void setautogain(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->ag_cnt = val ? AG_CNT_START : -1;
-}
-
-/* set the resolution for sensor cx0342 */
-static void set_resolution(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x00);
- if (gspca_dev->width == 320) {
- reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0x06);
- msleep(100);
- i2c_w(gspca_dev, CX0342_AUTO_ADC_CALIB, 0x01);
- msleep(100);
- reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x03);
- reg_w(gspca_dev, TP6800_R78_FORMAT, 0x01); /* qvga */
- reg_w(gspca_dev, TP6800_R5D_DEMOSAIC_CFG, 0x0d);
- i2c_w(gspca_dev, CX0342_EXPO_LINE_L, 0x37);
- i2c_w(gspca_dev, CX0342_EXPO_LINE_H, 0x01);
- } else {
- reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0x05);
- msleep(100);
- i2c_w(gspca_dev, CX0342_AUTO_ADC_CALIB, 0x01);
- msleep(100);
- reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x03);
- reg_w(gspca_dev, TP6800_R78_FORMAT, 0x00); /* vga */
- reg_w(gspca_dev, TP6800_R5D_DEMOSAIC_CFG, 0x09);
- i2c_w(gspca_dev, CX0342_EXPO_LINE_L, 0xcf);
- i2c_w(gspca_dev, CX0342_EXPO_LINE_H, 0x00);
- }
- i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x01);
- bulk_w(gspca_dev, 0x03, color_gain[SENSOR_CX0342],
- ARRAY_SIZE(color_gain[0]));
- setgamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
- if (sd->sensor == SENSOR_SOI763A)
- setquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual));
-}
-
-/* convert the frame rate to a tp68x0 value */
-static int get_fr_idx(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
-
- if (sd->bridge == BRIDGE_TP6800) {
- for (i = 0; i < ARRAY_SIZE(rates) - 1; i++) {
- if (sd->framerate >= rates[i])
- break;
- }
- i = 6 - i; /* 1 = 5fps .. 6 = 30fps */
-
- /* 640x480 * 30 fps does not work */
- if (i == 6 /* if 30 fps */
- && gspca_dev->width == 640)
- i = 0x05; /* 15 fps */
- } else {
- for (i = 0; i < ARRAY_SIZE(rates_6810) - 1; i++) {
- if (sd->framerate >= rates_6810[i])
- break;
- }
- i = 7 - i; /* 3 = 5fps .. 7 = 30fps */
-
- /* 640x480 * 30 fps does not work */
- if (i == 7 /* if 30 fps */
- && gspca_dev->width == 640)
- i = 6; /* 15 fps */
- i |= 0x80; /* clock * 1 */
- }
- return i;
-}
-
-static void setframerate(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 fr_idx;
-
- fr_idx = get_fr_idx(gspca_dev);
-
- if (sd->bridge == BRIDGE_TP6810) {
- reg_r(gspca_dev, 0x7b);
- reg_w(gspca_dev, 0x7b,
- sd->sensor == SENSOR_CX0342 ? 0x10 : 0x90);
- if (val >= 128)
- fr_idx = 0xf0; /* lower frame rate */
- }
-
- reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, fr_idx);
-
- if (sd->sensor == SENSOR_CX0342)
- i2c_w(gspca_dev, CX0342_AUTO_ADC_CALIB, 0x01);
-}
-
-static void setrgain(struct gspca_dev *gspca_dev, s32 rgain)
-{
- i2c_w(gspca_dev, CX0342_RAW_RGAIN_H, rgain >> 8);
- i2c_w(gspca_dev, CX0342_RAW_RGAIN_L, rgain);
- i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x80);
-}
-
-static int sd_setgain(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- s32 val = gspca_dev->gain->val;
-
- if (sd->sensor == SENSOR_CX0342) {
- s32 old = gspca_dev->gain->cur.val ?
- gspca_dev->gain->cur.val : 1;
-
- sd->blue->val = sd->blue->val * val / old;
- if (sd->blue->val > 4095)
- sd->blue->val = 4095;
- sd->red->val = sd->red->val * val / old;
- if (sd->red->val > 4095)
- sd->red->val = 4095;
- }
- if (gspca_dev->streaming) {
- if (sd->sensor == SENSOR_CX0342)
- setexposure(gspca_dev, gspca_dev->exposure->val,
- gspca_dev->gain->val,
- sd->blue->val, sd->red->val);
- else
- setexposure(gspca_dev, gspca_dev->exposure->val,
- gspca_dev->gain->val, 0, 0);
- }
- return gspca_dev->usb_err;
-}
-
-static void setbgain(struct gspca_dev *gspca_dev, s32 bgain)
-{
- i2c_w(gspca_dev, CX0342_RAW_BGAIN_H, bgain >> 8);
- i2c_w(gspca_dev, CX0342_RAW_BGAIN_L, bgain);
- i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x80);
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->bridge = id->driver_info;
-
- gspca_dev->cam.cam_mode = vga_mode;
- gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
- gspca_dev->cam.mode_framerates = sd->bridge == BRIDGE_TP6800 ?
- framerates : framerates_6810;
-
- sd->framerate = 30; /* default: 30 fps */
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- static const struct cmd tp6800_preinit[] = {
- {TP6800_R10_SIF_TYPE, 0x01}, /* sif */
- {TP6800_R11_SIF_CONTROL, 0x01},
- {TP6800_R15_GPIO_PU, 0x9f},
- {TP6800_R16_GPIO_PD, 0x9f},
- {TP6800_R17_GPIO_IO, 0x80},
- {TP6800_R18_GPIO_DATA, 0x40}, /* LED off */
- };
- static const struct cmd tp6810_preinit[] = {
- {TP6800_R2F_TIMING_CFG, 0x2f},
- {TP6800_R15_GPIO_PU, 0x6f},
- {TP6800_R16_GPIO_PD, 0x40},
- {TP6800_R17_GPIO_IO, 0x9f},
- {TP6800_R18_GPIO_DATA, 0xc1}, /* LED off */
- };
-
- if (sd->bridge == BRIDGE_TP6800)
- reg_w_buf(gspca_dev, tp6800_preinit,
- ARRAY_SIZE(tp6800_preinit));
- else
- reg_w_buf(gspca_dev, tp6810_preinit,
- ARRAY_SIZE(tp6810_preinit));
- msleep(15);
- reg_r(gspca_dev, TP6800_R18_GPIO_DATA);
- PDEBUG(D_PROBE, "gpio: %02x", gspca_dev->usb_buf[0]);
-/* values:
- * 0x80: snapshot button
- * 0x40: LED
- * 0x20: (bridge / sensor) reset for tp6810 ?
- * 0x07: sensor type ?
- */
-
- /* guess the sensor type */
- if (force_sensor >= 0) {
- sd->sensor = force_sensor;
- } else {
- if (sd->bridge == BRIDGE_TP6800) {
-/*fixme: not sure this is working*/
- switch (gspca_dev->usb_buf[0] & 0x07) {
- case 0:
- sd->sensor = SENSOR_SOI763A;
- break;
- case 1:
- sd->sensor = SENSOR_CX0342;
- break;
- }
- } else {
- int sensor;
-
- sensor = probe_6810(gspca_dev);
- if (sensor < 0) {
- pr_warn("Unknown sensor %d - forced to soi763a\n",
- -sensor);
- sensor = SENSOR_SOI763A;
- }
- sd->sensor = sensor;
- }
- }
- if (sd->sensor == SENSOR_SOI763A) {
- pr_info("Sensor soi763a\n");
- if (sd->bridge == BRIDGE_TP6810) {
- soi763a_6810_init(gspca_dev);
- }
- } else {
- pr_info("Sensor cx0342\n");
- if (sd->bridge == BRIDGE_TP6810) {
- cx0342_6810_init(gspca_dev);
- }
- }
-
- set_dqt(gspca_dev, 0);
- return 0;
-}
-
-/* This function is called before choosing the alt setting */
-static int sd_isoc_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- static const struct cmd cx_sensor_init[] = {
- {CX0342_AUTO_ADC_CALIB, 0x81},
- {CX0342_EXPO_LINE_L, 0x37},
- {CX0342_EXPO_LINE_H, 0x01},
- {CX0342_RAW_GRGAIN_L, 0x00},
- {CX0342_RAW_GBGAIN_L, 0x00},
- {CX0342_RAW_RGAIN_L, 0x00},
- {CX0342_RAW_BGAIN_L, 0x00},
- {CX0342_SYS_CTRL_0, 0x81},
- };
- static const struct cmd cx_bridge_init[] = {
- {0x4d, 0x00},
- {0x4c, 0xff},
- {0x4e, 0xff},
- {0x4f, 0x00},
- };
- static const struct cmd ov_sensor_init[] = {
- {0x10, 0x75}, /* exposure */
- {0x76, 0x03},
- {0x00, 0x00}, /* gain */
- };
- static const struct cmd ov_bridge_init[] = {
- {0x7b, 0x90},
- {TP6800_R3F_FRAME_RATE, 0x87},
- };
-
- if (sd->bridge == BRIDGE_TP6800)
- return 0;
- if (sd->sensor == SENSOR_CX0342) {
- reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x20);
- reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0x87);
- i2c_w_buf(gspca_dev, cx_sensor_init,
- ARRAY_SIZE(cx_sensor_init));
- reg_w_buf(gspca_dev, cx_bridge_init,
- ARRAY_SIZE(cx_bridge_init));
- bulk_w(gspca_dev, 0x03, color_null, sizeof color_null);
- reg_w(gspca_dev, 0x59, 0x40);
- } else {
- reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x21);
- i2c_w_buf(gspca_dev, ov_sensor_init,
- ARRAY_SIZE(ov_sensor_init));
- reg_r(gspca_dev, 0x7b);
- reg_w_buf(gspca_dev, ov_bridge_init,
- ARRAY_SIZE(ov_bridge_init));
- }
- reg_w(gspca_dev, TP6800_R78_FORMAT,
- gspca_dev->curr_mode ? 0x00 : 0x01);
- return gspca_dev->usb_err;
-}
-
-static void set_led(struct gspca_dev *gspca_dev, int on)
-{
- u8 data;
-
- reg_r(gspca_dev, TP6800_R18_GPIO_DATA);
- data = gspca_dev->usb_buf[0];
- if (on)
- data &= ~0x40;
- else
- data |= 0x40;
- reg_w(gspca_dev, TP6800_R18_GPIO_DATA, data);
-}
-
-static void cx0342_6800_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- static const struct cmd reg_init[] = {
- /* fixme: is this useful? */
- {TP6800_R17_GPIO_IO, 0x9f},
- {TP6800_R16_GPIO_PD, 0x40},
- {TP6800_R10_SIF_TYPE, 0x00}, /* i2c 8 bits */
- {TP6800_R50, 0x00},
- {TP6800_R51, 0x00},
- {TP6800_R52, 0xff},
- {TP6800_R53, 0x03},
- {TP6800_R54_DARK_CFG, 0x07},
- {TP6800_R5C_EDGE_THRLD, 0x40},
- {TP6800_R7A_BLK_THRLD, 0x40},
- {TP6800_R2F_TIMING_CFG, 0x17},
- {TP6800_R30_SENSOR_CFG, 0x18}, /* G1B..RG0 */
- {TP6800_R37_FRONT_DARK_ST, 0x00},
- {TP6800_R38_FRONT_DARK_END, 0x00},
- {TP6800_R39_REAR_DARK_ST_L, 0x00},
- {TP6800_R3A_REAR_DARK_ST_H, 0x00},
- {TP6800_R3B_REAR_DARK_END_L, 0x00},
- {TP6800_R3C_REAR_DARK_END_H, 0x00},
- {TP6800_R3D_HORIZ_DARK_LINE_L, 0x00},
- {TP6800_R3E_HORIZ_DARK_LINE_H, 0x00},
- {TP6800_R21_ENDP_1_CTL, 0x03},
-
- {TP6800_R31_PIXEL_START, 0x0b},
- {TP6800_R32_PIXEL_END_L, 0x8a},
- {TP6800_R33_PIXEL_END_H, 0x02},
- {TP6800_R34_LINE_START, 0x0e},
- {TP6800_R35_LINE_END_L, 0xf4},
- {TP6800_R36_LINE_END_H, 0x01},
- {TP6800_R78_FORMAT, 0x00},
- {TP6800_R12_SIF_ADDR_S, 0x20}, /* cx0342 i2c addr */
- };
- static const struct cmd sensor_init[] = {
- {CX0342_OUTPUT_CTRL, 0x07},
- {CX0342_BYPASS_MODE, 0x58},
- {CX0342_GPXLTHD_L, 0x16},
- {CX0342_RBPXLTHD_L, 0x16},
- {CX0342_PLANETHD_L, 0xc0},
- {CX0342_PLANETHD_H, 0x03},
- {CX0342_RB_GAP_L, 0xff},
- {CX0342_RB_GAP_H, 0x07},
- {CX0342_G_GAP_L, 0xff},
- {CX0342_G_GAP_H, 0x07},
- {CX0342_RST_OVERFLOW_L, 0x5c},
- {CX0342_RST_OVERFLOW_H, 0x01},
- {CX0342_DATA_OVERFLOW_L, 0xfc},
- {CX0342_DATA_OVERFLOW_H, 0x03},
- {CX0342_DATA_UNDERFLOW_L, 0x00},
- {CX0342_DATA_UNDERFLOW_H, 0x00},
- {CX0342_SYS_CTRL_0, 0x40},
- {CX0342_GLOBAL_GAIN, 0x01},
- {CX0342_CLOCK_GEN, 0x00},
- {CX0342_SYS_CTRL_0, 0x02},
- {CX0342_IDLE_CTRL, 0x05},
- {CX0342_ADCGN, 0x00},
- {CX0342_ADC_CTL, 0x00},
- {CX0342_LVRST_BLBIAS, 0x01},
- {CX0342_VTHSEL, 0x0b},
- {CX0342_RAMP_RIV, 0x0b},
- {CX0342_LDOSEL, 0x07},
- {CX0342_SPV_VALUE_L, 0x40},
- {CX0342_SPV_VALUE_H, 0x02},
- };
-
- reg_w_buf(gspca_dev, reg_init, ARRAY_SIZE(reg_init));
- i2c_w_buf(gspca_dev, sensor_init, ARRAY_SIZE(sensor_init));
- i2c_w_buf(gspca_dev, cx0342_timing_seq, ARRAY_SIZE(cx0342_timing_seq));
- reg_w(gspca_dev, TP6800_R5C_EDGE_THRLD, 0x10);
- reg_w(gspca_dev, TP6800_R54_DARK_CFG, 0x00);
- i2c_w(gspca_dev, CX0342_EXPO_LINE_H, 0x00);
- i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x01);
- if (sd->sensor == SENSOR_CX0342)
- setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure),
- v4l2_ctrl_g_ctrl(gspca_dev->gain),
- v4l2_ctrl_g_ctrl(sd->blue),
- v4l2_ctrl_g_ctrl(sd->red));
- else
- setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure),
- v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0);
- set_led(gspca_dev, 1);
- set_resolution(gspca_dev);
-}
-
-static void cx0342_6810_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- static const struct cmd sensor_init_2[] = {
- {CX0342_EXPO_LINE_L, 0x6f},
- {CX0342_EXPO_LINE_H, 0x02},
- {CX0342_RAW_GRGAIN_L, 0x00},
- {CX0342_RAW_GBGAIN_L, 0x00},
- {CX0342_RAW_RGAIN_L, 0x00},
- {CX0342_RAW_BGAIN_L, 0x00},
- {CX0342_SYS_CTRL_0, 0x81},
- };
- static const struct cmd bridge_init_2[] = {
- {0x4d, 0x00},
- {0x4c, 0xff},
- {0x4e, 0xff},
- {0x4f, 0x00},
- {TP6800_R7A_BLK_THRLD, 0x00},
- {TP6800_R79_QUALITY, 0x04},
- {TP6800_R79_QUALITY, 0x01},
- };
- static const struct cmd bridge_init_3[] = {
- {TP6800_R31_PIXEL_START, 0x08},
- {TP6800_R32_PIXEL_END_L, 0x87},
- {TP6800_R33_PIXEL_END_H, 0x02},
- {TP6800_R34_LINE_START, 0x0e},
- {TP6800_R35_LINE_END_L, 0xf4},
- {TP6800_R36_LINE_END_H, 0x01},
- };
- static const struct cmd sensor_init_3[] = {
- {CX0342_AUTO_ADC_CALIB, 0x81},
- {CX0342_EXPO_LINE_L, 0x6f},
- {CX0342_EXPO_LINE_H, 0x02},
- {CX0342_RAW_GRGAIN_L, 0x00},
- {CX0342_RAW_GBGAIN_L, 0x00},
- {CX0342_RAW_RGAIN_L, 0x00},
- {CX0342_RAW_BGAIN_L, 0x00},
- {CX0342_SYS_CTRL_0, 0x81},
- };
- static const struct cmd bridge_init_5[] = {
- {0x4d, 0x00},
- {0x4c, 0xff},
- {0x4e, 0xff},
- {0x4f, 0x00},
- };
- static const struct cmd sensor_init_4[] = {
- {CX0342_EXPO_LINE_L, 0xd3},
- {CX0342_EXPO_LINE_H, 0x01},
-/*fixme: gains, but 00..80 only*/
- {CX0342_RAW_GRGAIN_L, 0x40},
- {CX0342_RAW_GBGAIN_L, 0x40},
- {CX0342_RAW_RGAIN_L, 0x40},
- {CX0342_RAW_BGAIN_L, 0x40},
- {CX0342_SYS_CTRL_0, 0x81},
- };
- static const struct cmd sensor_init_5[] = {
- {CX0342_IDLE_CTRL, 0x05},
- {CX0342_ADCGN, 0x00},
- {CX0342_ADC_CTL, 0x00},
- {CX0342_LVRST_BLBIAS, 0x01},
- {CX0342_VTHSEL, 0x0b},
- {CX0342_RAMP_RIV, 0x0b},
- {CX0342_LDOSEL, 0x07},
- {CX0342_SPV_VALUE_L, 0x40},
- {CX0342_SPV_VALUE_H, 0x02},
- {CX0342_AUTO_ADC_CALIB, 0x81},
- };
-
- reg_w(gspca_dev, 0x22, gspca_dev->alt);
- i2c_w_buf(gspca_dev, sensor_init_2, ARRAY_SIZE(sensor_init_2));
- reg_w_buf(gspca_dev, bridge_init_2, ARRAY_SIZE(bridge_init_2));
- reg_w_buf(gspca_dev, tp6810_cx_init_common,
- ARRAY_SIZE(tp6810_cx_init_common));
- reg_w_buf(gspca_dev, bridge_init_3, ARRAY_SIZE(bridge_init_3));
- if (gspca_dev->curr_mode) {
- reg_w(gspca_dev, 0x4a, 0x7f);
- reg_w(gspca_dev, 0x07, 0x05);
- reg_w(gspca_dev, TP6800_R78_FORMAT, 0x00); /* vga */
- } else {
- reg_w(gspca_dev, 0x4a, 0xff);
- reg_w(gspca_dev, 0x07, 0x85);
- reg_w(gspca_dev, TP6800_R78_FORMAT, 0x01); /* qvga */
- }
- setgamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
- reg_w_buf(gspca_dev, tp6810_bridge_start,
- ARRAY_SIZE(tp6810_bridge_start));
- setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness));
- bulk_w(gspca_dev, 0x03, color_gain[SENSOR_CX0342],
- ARRAY_SIZE(color_gain[0]));
- reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0x87);
- i2c_w_buf(gspca_dev, sensor_init_3, ARRAY_SIZE(sensor_init_3));
- reg_w_buf(gspca_dev, bridge_init_5, ARRAY_SIZE(bridge_init_5));
- i2c_w_buf(gspca_dev, sensor_init_4, ARRAY_SIZE(sensor_init_4));
- reg_w_buf(gspca_dev, bridge_init_5, ARRAY_SIZE(bridge_init_5));
- i2c_w_buf(gspca_dev, sensor_init_5, ARRAY_SIZE(sensor_init_5));
-
- set_led(gspca_dev, 1);
-/* setquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual)); */
-}
-
-static void soi763a_6800_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- static const struct cmd reg_init[] = {
- {TP6800_R79_QUALITY, 0x04},
- {TP6800_R79_QUALITY, 0x01},
- {TP6800_R10_SIF_TYPE, 0x00}, /* i2c 8 bits */
-
- {TP6800_R50, 0x00},
- {TP6800_R51, 0x00},
- {TP6800_R52, 0xff},
- {TP6800_R53, 0x03},
- {TP6800_R54_DARK_CFG, 0x07},
- {TP6800_R5C_EDGE_THRLD, 0x40},
-
- {TP6800_R79_QUALITY, 0x03},
- {TP6800_R7A_BLK_THRLD, 0x40},
-
- {TP6800_R2F_TIMING_CFG, 0x46},
- {TP6800_R30_SENSOR_CFG, 0x10}, /* BG1..G0R */
- {TP6800_R37_FRONT_DARK_ST, 0x00},
- {TP6800_R38_FRONT_DARK_END, 0x00},
- {TP6800_R39_REAR_DARK_ST_L, 0x00},
- {TP6800_R3A_REAR_DARK_ST_H, 0x00},
- {TP6800_R3B_REAR_DARK_END_L, 0x00},
- {TP6800_R3C_REAR_DARK_END_H, 0x00},
- {TP6800_R3D_HORIZ_DARK_LINE_L, 0x00},
- {TP6800_R3E_HORIZ_DARK_LINE_H, 0x00},
- {TP6800_R21_ENDP_1_CTL, 0x03},
-
- {TP6800_R3F_FRAME_RATE, 0x04}, /* 15 fps */
- {TP6800_R5D_DEMOSAIC_CFG, 0x0e}, /* scale down - medium edge */
-
- {TP6800_R31_PIXEL_START, 0x1b},
- {TP6800_R32_PIXEL_END_L, 0x9a},
- {TP6800_R33_PIXEL_END_H, 0x02},
- {TP6800_R34_LINE_START, 0x0f},
- {TP6800_R35_LINE_END_L, 0xf4},
- {TP6800_R36_LINE_END_H, 0x01},
- {TP6800_R78_FORMAT, 0x01}, /* qvga */
- {TP6800_R12_SIF_ADDR_S, 0x21}, /* soi763a i2c addr */
- {TP6800_R1A_SIF_TX_DATA2, 0x00},
- };
- static const struct cmd sensor_init[] = {
- {0x12, 0x48}, /* mirror - RGB */
- {0x13, 0xa0}, /* clock - no AGC nor AEC */
- {0x03, 0xa4}, /* saturation */
- {0x04, 0x30}, /* hue */
- {0x05, 0x88}, /* contrast */
- {0x06, 0x60}, /* brightness */
- {0x10, 0x41}, /* AEC */
- {0x11, 0x40}, /* clock rate */
- {0x13, 0xa0},
- {0x14, 0x00}, /* 640x480 */
- {0x15, 0x14},
- {0x1f, 0x41},
- {0x20, 0x80},
- {0x23, 0xee},
- {0x24, 0x50},
- {0x25, 0x7a},
- {0x26, 0x00},
- {0x27, 0xe2},
- {0x28, 0xb0},
- {0x2a, 0x00},
- {0x2b, 0x00},
- {0x2d, 0x81},
- {0x2f, 0x9d},
- {0x60, 0x80},
- {0x61, 0x00},
- {0x62, 0x88},
- {0x63, 0x11},
- {0x64, 0x89},
- {0x65, 0x00},
- {0x67, 0x94},
- {0x68, 0x7a},
- {0x69, 0x0f},
- {0x6c, 0x80},
- {0x6d, 0x80},
- {0x6e, 0x80},
- {0x6f, 0xff},
- {0x71, 0x20},
- {0x74, 0x20},
- {0x75, 0x86},
- {0x77, 0xb5},
- {0x17, 0x18}, /* H href start */
- {0x18, 0xbf}, /* H href end */
- {0x19, 0x03}, /* V start */
- {0x1a, 0xf8}, /* V end */
- {0x01, 0x80}, /* blue gain */
- {0x02, 0x80}, /* red gain */
- };
-
- reg_w_buf(gspca_dev, reg_init, ARRAY_SIZE(reg_init));
-
- i2c_w(gspca_dev, 0x12, 0x80); /* sensor reset */
- msleep(10);
-
- i2c_w_buf(gspca_dev, sensor_init, ARRAY_SIZE(sensor_init));
-
- reg_w(gspca_dev, TP6800_R5C_EDGE_THRLD, 0x10);
- reg_w(gspca_dev, TP6800_R54_DARK_CFG, 0x00);
-
- setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness));
-
- bulk_w(gspca_dev, 0x03, color_gain[SENSOR_SOI763A],
- ARRAY_SIZE(color_gain[0]));
-
- set_led(gspca_dev, 1);
- if (sd->sensor == SENSOR_CX0342)
- setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure),
- v4l2_ctrl_g_ctrl(gspca_dev->gain),
- v4l2_ctrl_g_ctrl(sd->blue),
- v4l2_ctrl_g_ctrl(sd->red));
- else
- setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure),
- v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0);
- if (sd->sensor == SENSOR_SOI763A)
- setquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual));
- setgamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
-}
-
-static void soi763a_6810_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- static const struct cmd bridge_init_2[] = {
- {TP6800_R7A_BLK_THRLD, 0x00},
- {TP6800_R79_QUALITY, 0x04},
- {TP6800_R79_QUALITY, 0x01},
- };
- static const struct cmd bridge_init_3[] = {
- {TP6800_R31_PIXEL_START, 0x20},
- {TP6800_R32_PIXEL_END_L, 0x9f},
- {TP6800_R33_PIXEL_END_H, 0x02},
- {TP6800_R34_LINE_START, 0x13},
- {TP6800_R35_LINE_END_L, 0xf8},
- {TP6800_R36_LINE_END_H, 0x01},
- };
- static const struct cmd bridge_init_6[] = {
- {0x08, 0xff},
- {0x09, 0xff},
- {0x0a, 0x5f},
- {0x0b, 0x80},
- };
-
- reg_w(gspca_dev, 0x22, gspca_dev->alt);
- bulk_w(gspca_dev, 0x03, color_null, sizeof color_null);
- reg_w(gspca_dev, 0x59, 0x40);
- if (sd->sensor == SENSOR_CX0342)
- setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure),
- v4l2_ctrl_g_ctrl(gspca_dev->gain),
- v4l2_ctrl_g_ctrl(sd->blue),
- v4l2_ctrl_g_ctrl(sd->red));
- else
- setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure),
- v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0);
- reg_w_buf(gspca_dev, bridge_init_2, ARRAY_SIZE(bridge_init_2));
- reg_w_buf(gspca_dev, tp6810_ov_init_common,
- ARRAY_SIZE(tp6810_ov_init_common));
- reg_w_buf(gspca_dev, bridge_init_3, ARRAY_SIZE(bridge_init_3));
- if (gspca_dev->curr_mode) {
- reg_w(gspca_dev, 0x4a, 0x7f);
- reg_w(gspca_dev, 0x07, 0x05);
- reg_w(gspca_dev, TP6800_R78_FORMAT, 0x00); /* vga */
- } else {
- reg_w(gspca_dev, 0x4a, 0xff);
- reg_w(gspca_dev, 0x07, 0x85);
- reg_w(gspca_dev, TP6800_R78_FORMAT, 0x01); /* qvga */
- }
- setgamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
- reg_w_buf(gspca_dev, tp6810_bridge_start,
- ARRAY_SIZE(tp6810_bridge_start));
-
- if (gspca_dev->curr_mode) {
- reg_w(gspca_dev, 0x4f, 0x00);
- reg_w(gspca_dev, 0x4e, 0x7c);
- }
-
- reg_w(gspca_dev, 0x00, 0x00);
-
- setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness));
- bulk_w(gspca_dev, 0x03, color_gain[SENSOR_SOI763A],
- ARRAY_SIZE(color_gain[0]));
- set_led(gspca_dev, 1);
- reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0xf0);
- if (sd->sensor == SENSOR_CX0342)
- setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure),
- v4l2_ctrl_g_ctrl(gspca_dev->gain),
- v4l2_ctrl_g_ctrl(sd->blue),
- v4l2_ctrl_g_ctrl(sd->red));
- else
- setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure),
- v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0);
- reg_w_buf(gspca_dev, bridge_init_6, ARRAY_SIZE(bridge_init_6));
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width);
- set_dqt(gspca_dev, sd->quality);
- if (sd->bridge == BRIDGE_TP6800) {
- if (sd->sensor == SENSOR_CX0342)
- cx0342_6800_start(gspca_dev);
- else
- soi763a_6800_start(gspca_dev);
- } else {
- if (sd->sensor == SENSOR_CX0342)
- cx0342_6810_start(gspca_dev);
- else
- soi763a_6810_start(gspca_dev);
- reg_w_buf(gspca_dev, tp6810_late_start,
- ARRAY_SIZE(tp6810_late_start));
- reg_w(gspca_dev, 0x80, 0x03);
- reg_w(gspca_dev, 0x82, gspca_dev->curr_mode ? 0x0a : 0x0e);
-
- if (sd->sensor == SENSOR_CX0342)
- setexposure(gspca_dev,
- v4l2_ctrl_g_ctrl(gspca_dev->exposure),
- v4l2_ctrl_g_ctrl(gspca_dev->gain),
- v4l2_ctrl_g_ctrl(sd->blue),
- v4l2_ctrl_g_ctrl(sd->red));
- else
- setexposure(gspca_dev,
- v4l2_ctrl_g_ctrl(gspca_dev->exposure),
- v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0);
- if (sd->sensor == SENSOR_SOI763A)
- setquality(gspca_dev,
- v4l2_ctrl_g_ctrl(sd->jpegqual));
- if (sd->bridge == BRIDGE_TP6810)
- setautogain(gspca_dev,
- v4l2_ctrl_g_ctrl(gspca_dev->autogain));
- }
-
- setframerate(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure));
-
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->bridge == BRIDGE_TP6800)
- reg_w(gspca_dev, TP6800_R2F_TIMING_CFG, 0x03);
- set_led(gspca_dev, 0);
- reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x00);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data,
- int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* the start of frame contains:
- * ff d8
- * ff fe
- * width / 16
- * height / 8
- * quality
- */
- if (sd->bridge == BRIDGE_TP6810) {
- if (*data != 0x5a) {
-/*fixme: don't discard the whole frame..*/
- if (*data == 0xaa || *data == 0x00)
- return;
- if (*data > 0xc0) {
- PDEBUG(D_FRAM, "bad frame");
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
- }
- data++;
- len--;
- if (*data == 0xff && data[1] == 0xd8) {
-/*fixme: there may be information in the 4 high bits*/
- if ((data[6] & 0x0f) != sd->quality)
- set_dqt(gspca_dev, data[6] & 0x0f);
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sd->jpeg_hdr, JPEG_HDR_SZ);
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data + 7, len - 7);
- } else if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
- gspca_frame_add(gspca_dev, LAST_PACKET,
- data, len);
- } else {
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data, len);
- }
- return;
- }
-
- switch (*data) {
- case 0x55:
- gspca_frame_add(gspca_dev, LAST_PACKET, data, 0);
-
- if (len < 8
- || data[1] != 0xff || data[2] != 0xd8
- || data[3] != 0xff || data[4] != 0xfe) {
-
- /* Have only seen this with corrupt frames */
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
- if (data[7] != sd->quality)
- set_dqt(gspca_dev, data[7]);
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sd->jpeg_hdr, JPEG_HDR_SZ);
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data + 8, len - 8);
- break;
- case 0xaa:
- gspca_dev->last_packet_type = DISCARD_PACKET;
- break;
- case 0xcc:
- if (data[1] != 0xff || data[2] != 0xd8)
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data + 1, len - 1);
- else
- gspca_dev->last_packet_type = DISCARD_PACKET;
- break;
- }
-}
-
-static void sd_dq_callback(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret, alen;
- int luma, expo;
-
- if (sd->ag_cnt < 0)
- return;
- if (--sd->ag_cnt > 5)
- return;
- switch (sd->ag_cnt) {
-/* case 5: */
- default:
- reg_w(gspca_dev, 0x7d, 0x00);
- break;
- case 4:
- reg_w(gspca_dev, 0x27, 0xb0);
- break;
- case 3:
- reg_w(gspca_dev, 0x0c, 0x01);
- break;
- case 2:
- ret = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev, 0x02),
- gspca_dev->usb_buf,
- 32,
- &alen,
- 500);
- if (ret < 0) {
- pr_err("bulk err %d\n", ret);
- break;
- }
- /* values not used (unknown) */
- break;
- case 1:
- reg_w(gspca_dev, 0x27, 0xd0);
- break;
- case 0:
- ret = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev, 0x02),
- gspca_dev->usb_buf,
- 32,
- &alen,
- 500);
- if (ret < 0) {
- pr_err("bulk err %d\n", ret);
- break;
- }
- luma = ((gspca_dev->usb_buf[8] << 8) + gspca_dev->usb_buf[7] +
- (gspca_dev->usb_buf[11] << 8) + gspca_dev->usb_buf[10] +
- (gspca_dev->usb_buf[14] << 8) + gspca_dev->usb_buf[13] +
- (gspca_dev->usb_buf[17] << 8) + gspca_dev->usb_buf[16] +
- (gspca_dev->usb_buf[20] << 8) + gspca_dev->usb_buf[19] +
- (gspca_dev->usb_buf[23] << 8) + gspca_dev->usb_buf[22] +
- (gspca_dev->usb_buf[26] << 8) + gspca_dev->usb_buf[25] +
- (gspca_dev->usb_buf[29] << 8) + gspca_dev->usb_buf[28])
- / 8;
- if (gspca_dev->width == 640)
- luma /= 4;
- reg_w(gspca_dev, 0x7d, 0x00);
-
- expo = v4l2_ctrl_g_ctrl(gspca_dev->exposure);
- ret = gspca_expo_autogain(gspca_dev, luma,
- 60, /* desired luma */
- 6, /* dead zone */
- 2, /* gain knee */
- 70); /* expo knee */
- sd->ag_cnt = AG_CNT_START;
- if (sd->bridge == BRIDGE_TP6810) {
- int new_expo = v4l2_ctrl_g_ctrl(gspca_dev->exposure);
-
- if ((expo >= 128 && new_expo < 128)
- || (expo < 128 && new_expo >= 128))
- setframerate(gspca_dev, new_expo);
- }
- break;
- }
-}
-
-/* get stream parameters (framerate) */
-static void sd_get_streamparm(struct gspca_dev *gspca_dev,
- struct v4l2_streamparm *parm)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct v4l2_captureparm *cp = &parm->parm.capture;
- struct v4l2_fract *tpf = &cp->timeperframe;
- int fr, i;
-
- cp->capability |= V4L2_CAP_TIMEPERFRAME;
- tpf->numerator = 1;
- i = get_fr_idx(gspca_dev);
- if (i & 0x80) {
- if (sd->bridge == BRIDGE_TP6800)
- fr = rates[6 - (i & 0x07)];
- else
- fr = rates_6810[7 - (i & 0x07)];
- } else {
- fr = rates[6 - i];
- }
- tpf->denominator = fr;
-}
-
-/* set stream parameters (framerate) */
-static void sd_set_streamparm(struct gspca_dev *gspca_dev,
- struct v4l2_streamparm *parm)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct v4l2_captureparm *cp = &parm->parm.capture;
- struct v4l2_fract *tpf = &cp->timeperframe;
- int fr, i;
-
- sd->framerate = tpf->denominator / tpf->numerator;
- if (gspca_dev->streaming)
- setframerate(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure));
-
- /* Return the actual framerate */
- i = get_fr_idx(gspca_dev);
- if (i & 0x80)
- fr = rates_6810[7 - (i & 0x07)];
- else
- fr = rates[6 - i];
- tpf->numerator = 1;
- tpf->denominator = fr;
-}
-
-static int sd_set_jcomp(struct gspca_dev *gspca_dev,
- struct v4l2_jpegcompression *jcomp)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor != SENSOR_SOI763A)
- return -ENOTTY;
- v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
- return 0;
-}
-
-static int sd_get_jcomp(struct gspca_dev *gspca_dev,
- struct v4l2_jpegcompression *jcomp)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->sensor != SENSOR_SOI763A)
- return -ENOTTY;
- memset(jcomp, 0, sizeof *jcomp);
- jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
- jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
- | V4L2_JPEG_MARKER_DQT;
- return 0;
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_SHARPNESS:
- setsharpness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_GAMMA:
- setgamma(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_BLUE_BALANCE:
- setbgain(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_RED_BALANCE:
- setrgain(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_EXPOSURE:
- sd_setgain(gspca_dev);
- break;
- case V4L2_CID_AUTOGAIN:
- if (ctrl->val)
- break;
- sd_setgain(gspca_dev);
- break;
- case V4L2_CID_JPEG_COMPRESSION_QUALITY:
- jpeg_set_qual(sd->jpeg_hdr, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 4);
- gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 1, 0xdc, 1, 0x4e);
- if (sd->sensor == SENSOR_CX0342) {
- sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_RED_BALANCE, 0, 4095, 1, 256);
- sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BLUE_BALANCE, 0, 4095, 1, 256);
- }
- if (sd->sensor == SENSOR_SOI763A)
- gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 15, 1, 3);
- else
- gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 4095, 1, 256);
- sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SHARPNESS, 0, 3, 1, 2);
- sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAMMA, 0, NGAMMA - 1, 1,
- (sd->sensor == SENSOR_SOI763A &&
- sd->bridge == BRIDGE_TP6800) ? 0 : 1);
- if (sd->bridge == BRIDGE_TP6810)
- gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- if (sd->sensor == SENSOR_SOI763A)
- sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_JPEG_COMPRESSION_QUALITY,
- 0, 15, 1, (sd->bridge == BRIDGE_TP6810) ? 0 : 13);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- if (gspca_dev->autogain)
- v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
- else
- v4l2_ctrl_cluster(2, &gspca_dev->exposure);
- return 0;
-}
-
-static const struct sd_desc sd_desc = {
- .name = KBUILD_MODNAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .isoc_init = sd_isoc_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
- .dq_callback = sd_dq_callback,
- .get_streamparm = sd_get_streamparm,
- .set_streamparm = sd_set_streamparm,
- .get_jcomp = sd_get_jcomp,
- .set_jcomp = sd_set_jcomp,
-};
-
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x06a2, 0x0003), .driver_info = BRIDGE_TP6800},
- {USB_DEVICE(0x06a2, 0x6810), .driver_info = BRIDGE_TP6810},
- {} /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-static int sd_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(interface, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = KBUILD_MODNAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
-
-module_param(force_sensor, int, 0644);
-MODULE_PARM_DESC(force_sensor,
- "Force sensor. 0: cx0342, 1: soi763a");
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
deleted file mode 100644
index 8591324a53e..00000000000
--- a/drivers/media/video/gspca/tv8532.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Quickcam cameras initialization data
- *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#define MODULE_NAME "tv8532"
-
-#include "gspca.h"
-
-MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
-MODULE_DESCRIPTION("TV8532 USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- __u8 packet;
-};
-
-static const struct v4l2_pix_format sif_mode[] = {
- {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-
-/* TV-8532A (ICM532A) registers (LE) */
-#define R00_PART_CONTROL 0x00
-#define LATENT_CHANGE 0x80
-#define EXPO_CHANGE 0x04
-#define R01_TIMING_CONTROL_LOW 0x01
-#define CMD_EEprom_Open 0x30
-#define CMD_EEprom_Close 0x29
-#define R03_TABLE_ADDR 0x03
-#define R04_WTRAM_DATA_L 0x04
-#define R05_WTRAM_DATA_M 0x05
-#define R06_WTRAM_DATA_H 0x06
-#define R07_TABLE_LEN 0x07
-#define R08_RAM_WRITE_ACTION 0x08
-#define R0C_AD_WIDTHL 0x0c
-#define R0D_AD_WIDTHH 0x0d
-#define R0E_AD_HEIGHTL 0x0e
-#define R0F_AD_HEIGHTH 0x0f
-#define R10_AD_COL_BEGINL 0x10
-#define R11_AD_COL_BEGINH 0x11
-#define MIRROR 0x04 /* [10] */
-#define R14_AD_ROW_BEGINL 0x14
-#define R15_AD_ROWBEGINH 0x15
-#define R1C_AD_EXPOSE_TIMEL 0x1c
-#define R20_GAIN_G1L 0x20
-#define R21_GAIN_G1H 0x21
-#define R22_GAIN_RL 0x22
-#define R23_GAIN_RH 0x23
-#define R24_GAIN_BL 0x24
-#define R25_GAIN_BH 0x25
-#define R26_GAIN_G2L 0x26
-#define R27_GAIN_G2H 0x27
-#define R28_QUANT 0x28
-#define R29_LINE 0x29
-#define R2C_POLARITY 0x2c
-#define R2D_POINT 0x2d
-#define R2E_POINTH 0x2e
-#define R2F_POINTB 0x2f
-#define R30_POINTBH 0x30
-#define R31_UPD 0x31
-#define R2A_HIGH_BUDGET 0x2a
-#define R2B_LOW_BUDGET 0x2b
-#define R34_VID 0x34
-#define R35_VIDH 0x35
-#define R36_PID 0x36
-#define R37_PIDH 0x37
-#define R39_Test1 0x39 /* GPIO */
-#define R3B_Test3 0x3b /* GPIO */
-#define R83_AD_IDH 0x83
-#define R91_AD_SLOPEREG 0x91
-#define R94_AD_BITCONTROL 0x94
-
-static const u8 eeprom_data[][3] = {
-/* dataH dataM dataL */
- {0x01, 0x00, 0x01},
- {0x01, 0x80, 0x11},
- {0x05, 0x00, 0x14},
- {0x05, 0x00, 0x1c},
- {0x0d, 0x00, 0x1e},
- {0x05, 0x00, 0x1f},
- {0x05, 0x05, 0x19},
- {0x05, 0x01, 0x1b},
- {0x05, 0x09, 0x1e},
- {0x0d, 0x89, 0x2e},
- {0x05, 0x89, 0x2f},
- {0x05, 0x0d, 0xd9},
- {0x05, 0x09, 0xf1},
-};
-
-
-/* write 1 byte */
-static void reg_w1(struct gspca_dev *gspca_dev,
- __u16 index, __u8 value)
-{
- gspca_dev->usb_buf[0] = value;
- usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x02,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, /* value */
- index, gspca_dev->usb_buf, 1, 500);
-}
-
-/* write 2 bytes */
-static void reg_w2(struct gspca_dev *gspca_dev,
- u16 index, u16 value)
-{
- gspca_dev->usb_buf[0] = value;
- gspca_dev->usb_buf[1] = value >> 8;
- usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x02,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, /* value */
- index, gspca_dev->usb_buf, 2, 500);
-}
-
-static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev)
-{
- int i;
-
- reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Open);
- for (i = 0; i < ARRAY_SIZE(eeprom_data); i++) {
- reg_w1(gspca_dev, R03_TABLE_ADDR, i);
- reg_w1(gspca_dev, R04_WTRAM_DATA_L, eeprom_data[i][2]);
- reg_w1(gspca_dev, R05_WTRAM_DATA_M, eeprom_data[i][1]);
- reg_w1(gspca_dev, R06_WTRAM_DATA_H, eeprom_data[i][0]);
- reg_w1(gspca_dev, R08_RAM_WRITE_ACTION, 0);
- }
- reg_w1(gspca_dev, R07_TABLE_LEN, i);
- reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close);
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct cam *cam;
-
- cam = &gspca_dev->cam;
- cam->cam_mode = sif_mode;
- cam->nmodes = ARRAY_SIZE(sif_mode);
-
- return 0;
-}
-
-static void tv_8532_setReg(struct gspca_dev *gspca_dev)
-{
- reg_w1(gspca_dev, R3B_Test3, 0x0a); /* Test0Sel = 10 */
- /******************************************************/
- reg_w1(gspca_dev, R0E_AD_HEIGHTL, 0x90);
- reg_w1(gspca_dev, R0F_AD_HEIGHTH, 0x01);
- reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f);
- reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44);
- /* begin active line */
- reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00);
- /* mirror and digital gain */
- reg_w1(gspca_dev, R14_AD_ROW_BEGINL, 0x0a);
-
- reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x02);
- reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00);
- reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
- /* = 0x84 */
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- tv_8532WriteEEprom(gspca_dev);
-
- return 0;
-}
-
-static void setexposure(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, val);
- reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
- /* 0x84 */
-}
-
-static void setgain(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_w2(gspca_dev, R20_GAIN_G1L, val);
- reg_w2(gspca_dev, R22_GAIN_RL, val);
- reg_w2(gspca_dev, R24_GAIN_BL, val);
- reg_w2(gspca_dev, R26_GAIN_G2L, val);
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8); /* 0x20; 0x0c */
- reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03);
-
- /************************************************/
- reg_w1(gspca_dev, R28_QUANT, 0x90);
- /* 0x72 compressed mode 0x28 */
- if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
- /* 176x144 */
- reg_w1(gspca_dev, R29_LINE, 0x41);
- /* CIF - 2 lines/packet */
- } else {
- /* 352x288 */
- reg_w1(gspca_dev, R29_LINE, 0x81);
- /* CIF - 2 lines/packet */
- }
- /************************************************/
- reg_w1(gspca_dev, R2C_POLARITY, 0x10); /* slow clock */
- reg_w1(gspca_dev, R2D_POINT, 0x14);
- reg_w1(gspca_dev, R2E_POINTH, 0x01);
- reg_w1(gspca_dev, R2F_POINTB, 0x12);
- reg_w1(gspca_dev, R30_POINTBH, 0x01);
-
- tv_8532_setReg(gspca_dev);
-
- /************************************************/
- reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */
- msleep(200);
- reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
-
- gspca_dev->empty_packet = 0; /* check the empty packets */
- sd->packet = 0; /* ignore the first packets */
-
- return 0;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int packet_type0, packet_type1;
-
- packet_type0 = packet_type1 = INTER_PACKET;
- if (gspca_dev->empty_packet) {
- gspca_dev->empty_packet = 0;
- sd->packet = gspca_dev->height / 2;
- packet_type0 = FIRST_PACKET;
- } else if (sd->packet == 0)
- return; /* 2 more lines in 352x288 ! */
- sd->packet--;
- if (sd->packet == 0)
- packet_type1 = LAST_PACKET;
-
- /* each packet contains:
- * - header 2 bytes
- * - RGRG line
- * - 4 bytes
- * - GBGB line
- * - 4 bytes
- */
- gspca_frame_add(gspca_dev, packet_type0,
- data + 2, gspca_dev->width);
- gspca_frame_add(gspca_dev, packet_type1,
- data + gspca_dev->width + 5, gspca_dev->width);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- setexposure(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_GAIN:
- setgain(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 2);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 0x18f, 1, 0x18f);
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 0x7ff, 1, 0x100);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x046d, 0x0920)},
- {USB_DEVICE(0x046d, 0x0921)},
- {USB_DEVICE(0x0545, 0x808b)},
- {USB_DEVICE(0x0545, 0x8333)},
- {USB_DEVICE(0x0923, 0x010f)},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
deleted file mode 100644
index f21fd1677c3..00000000000
--- a/drivers/media/video/gspca/vc032x.c
+++ /dev/null
@@ -1,3853 +0,0 @@
-/*
- * Z-star vc0321 library
- *
- * Copyright (C) 2009-2010 Jean-François Moine <http://moinejf.free.fr>
- * Copyright (C) 2006 Koninski Artur takeshi87@o2.pl
- * Copyright (C) 2006 Michel Xhaard
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "vc032x"
-
-#include "gspca.h"
-
-MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
-MODULE_DESCRIPTION("GSPCA/VC032X USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- struct { /* hvflip cluster */
- struct v4l2_ctrl *hflip;
- struct v4l2_ctrl *vflip;
- };
-
- u8 image_offset;
-
- u8 bridge;
- u8 sensor;
- u8 flags;
-#define FL_SAMSUNG 0x01 /* SamsungQ1 (2 sensors) */
-#define FL_HFLIP 0x02 /* mirrored by default */
-#define FL_VFLIP 0x04 /* vertical flipped by default */
-};
-enum bridges {
- BRIDGE_VC0321,
- BRIDGE_VC0323,
-};
-enum sensors {
- SENSOR_HV7131R,
- SENSOR_MI0360,
- SENSOR_MI1310_SOC,
- SENSOR_MI1320,
- SENSOR_MI1320_SOC,
- SENSOR_OV7660,
- SENSOR_OV7670,
- SENSOR_PO1200,
- SENSOR_PO3130NC,
- SENSOR_POxxxx,
- NSENSORS
-};
-
-
-static const struct v4l2_pix_format vc0321_mode[] = {
- {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-static const struct v4l2_pix_format vc0323_mode[] = {
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
- {1280, 960, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, /* mi1310_soc only */
- .bytesperline = 1280,
- .sizeimage = 1280 * 960 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2},
-};
-static const struct v4l2_pix_format bi_mode[] = {
- {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
- {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
- {1280, 1024, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 1280,
- .sizeimage = 1280 * 1024 * 2,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
-};
-static const struct v4l2_pix_format svga_mode[] = {
- {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 800,
- .sizeimage = 800 * 600 * 1 / 4 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-
-/* OV7660/7670 registers */
-#define OV7660_REG_MVFP 0x1e
-#define OV7660_MVFP_MIRROR 0x20
-#define OV7660_MVFP_VFLIP 0x10
-
-static const u8 mi0360_matrix[9] = {
- 0x50, 0xf8, 0xf8, 0xf5, 0x50, 0xfb, 0xff, 0xf1, 0x50
-};
-
-static const u8 mi0360_initVGA_JPG[][4] = {
- {0xb0, 0x03, 0x19, 0xcc},
- {0xb0, 0x04, 0x02, 0xcc},
- {0xb3, 0x00, 0x24, 0xcc},
- {0xb3, 0x00, 0x25, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x05, 0x01, 0xcc},
- {0xb3, 0x06, 0x03, 0xcc},
- {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x01, 0xcc},
- {0xb3, 0x23, 0xe0, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x02, 0xcc},
- {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x35, 0xdd, 0xcc}, /* i2c add: 5d */
- {0xb3, 0x34, 0x02, 0xcc},
- {0xb3, 0x00, 0x25, 0xcc},
- {0xbc, 0x00, 0x71, 0xcc},
- {0xb8, 0x00, 0x13, 0xcc},
- {0xb8, 0x27, 0x20, 0xcc},
- {0xb8, 0x2c, 0x50, 0xcc},
- {0xb8, 0x2d, 0xf8, 0xcc},
- {0xb8, 0x2e, 0xf8, 0xcc},
- {0xb8, 0x2f, 0xf8, 0xcc},
- {0xb8, 0x30, 0x50, 0xcc},
- {0xb8, 0x31, 0xf8, 0xcc},
- {0xb8, 0x32, 0xf8, 0xcc},
- {0xb8, 0x33, 0xf8, 0xcc},
- {0xb8, 0x34, 0x50, 0xcc},
- {0xb8, 0x35, 0x00, 0xcc},
- {0xb8, 0x36, 0x00, 0xcc},
- {0xb8, 0x37, 0x00, 0xcc},
- {0xb8, 0x01, 0x79, 0xcc},
- {0xb8, 0x08, 0xe0, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc},
- {0xb8, 0x01, 0x79, 0xcc},
- {0xb8, 0x14, 0x18, 0xcc},
- {0xb8, 0xb2, 0x0a, 0xcc},
- {0xb8, 0xb4, 0x0a, 0xcc},
- {0xb8, 0xb5, 0x0a, 0xcc},
- {0xb8, 0xfe, 0x00, 0xcc},
- {0xb8, 0xff, 0x28, 0xcc},
- {0xb9, 0x00, 0x28, 0xcc},
- {0xb9, 0x01, 0x28, 0xcc},
- {0xb9, 0x02, 0x28, 0xcc},
- {0xb9, 0x03, 0x00, 0xcc},
- {0xb9, 0x04, 0x00, 0xcc},
- {0xb9, 0x05, 0x3c, 0xcc},
- {0xb9, 0x06, 0x3c, 0xcc},
- {0xb9, 0x07, 0x3c, 0xcc},
- {0xb9, 0x08, 0x3c, 0xcc},
- {0xb8, 0x8e, 0x00, 0xcc},
- {0xb8, 0x8f, 0xff, 0xcc},
- {0xb8, 0x81, 0x09, 0xcc},
- {0x31, 0x00, 0x00, 0xbb},
- {0x09, 0x01, 0xc7, 0xbb},
- {0x34, 0x01, 0x00, 0xbb},
- {0x2b, 0x00, 0x28, 0xbb},
- {0x2c, 0x00, 0x30, 0xbb},
- {0x2d, 0x00, 0x30, 0xbb},
- {0x2e, 0x00, 0x28, 0xbb},
- {0x62, 0x04, 0x11, 0xbb},
- {0x03, 0x01, 0xe0, 0xbb},
- {0x2c, 0x00, 0x2c, 0xbb},
- {0x20, 0xd0, 0x00, 0xbb},
- {0x01, 0x00, 0x08, 0xbb},
- {0x06, 0x00, 0x10, 0xbb},
- {0x05, 0x00, 0x20, 0xbb},
- {0x20, 0x00, 0x00, 0xbb},
- {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x02, 0xcc},
- {0xb6, 0x02, 0x80, 0xcc},
- {0xb6, 0x05, 0x01, 0xcc},
- {0xb6, 0x04, 0xe0, 0xcc},
- {0xb6, 0x12, 0x78, 0xcc},
- {0xb6, 0x18, 0x02, 0xcc},
- {0xb6, 0x17, 0x58, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc},
- {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc},
- {0xb3, 0x02, 0x02, 0xcc},
- {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc},
- {0xbf, 0xcc, 0x10, 0xcc},
- {0xb9, 0x12, 0x00, 0xcc},
- {0xb9, 0x13, 0x0a, 0xcc},
- {0xb9, 0x14, 0x0a, 0xcc},
- {0xb9, 0x15, 0x0a, 0xcc},
- {0xb9, 0x16, 0x0a, 0xcc},
- {0xb9, 0x18, 0x00, 0xcc},
- {0xb9, 0x19, 0x0f, 0xcc},
- {0xb9, 0x1a, 0x0f, 0xcc},
- {0xb9, 0x1b, 0x0f, 0xcc},
- {0xb9, 0x1c, 0x0f, 0xcc},
- {0xb8, 0x8e, 0x00, 0xcc},
- {0xb8, 0x8f, 0xff, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb8, 0x0c, 0x20, 0xcc},
- {0xb8, 0x0d, 0x70, 0xcc},
- {0xb6, 0x13, 0x13, 0xcc},
- {0x35, 0x00, 0x60, 0xbb},
- {0xb3, 0x5c, 0x01, 0xcc},
- {}
-};
-static const u8 mi0360_initQVGA_JPG[][4] = {
- {0xb0, 0x03, 0x19, 0xcc},
- {0xb0, 0x04, 0x02, 0xcc},
- {0xb3, 0x00, 0x24, 0xcc},
- {0xb3, 0x00, 0x25, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x05, 0x01, 0xcc},
- {0xb3, 0x06, 0x03, 0xcc},
- {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x01, 0xcc},
- {0xb3, 0x23, 0xe0, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x02, 0xcc},
- {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x35, 0xdd, 0xcc},
- {0xb3, 0x34, 0x02, 0xcc},
- {0xb3, 0x00, 0x25, 0xcc},
- {0xbc, 0x00, 0xd1, 0xcc},
- {0xb8, 0x00, 0x13, 0xcc},
- {0xb8, 0x27, 0x20, 0xcc},
- {0xb8, 0x2c, 0x50, 0xcc},
- {0xb8, 0x2d, 0xf8, 0xcc},
- {0xb8, 0x2e, 0xf8, 0xcc},
- {0xb8, 0x2f, 0xf8, 0xcc},
- {0xb8, 0x30, 0x50, 0xcc},
- {0xb8, 0x31, 0xf8, 0xcc},
- {0xb8, 0x32, 0xf8, 0xcc},
- {0xb8, 0x33, 0xf8, 0xcc},
- {0xb8, 0x34, 0x50, 0xcc},
- {0xb8, 0x35, 0x00, 0xcc},
- {0xb8, 0x36, 0x00, 0xcc},
- {0xb8, 0x37, 0x00, 0xcc},
- {0xb8, 0x01, 0x79, 0xcc},
- {0xb8, 0x08, 0xe0, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc},
- {0xb8, 0x01, 0x79, 0xcc},
- {0xb8, 0x14, 0x18, 0xcc},
- {0xb8, 0xb2, 0x0a, 0xcc},
- {0xb8, 0xb4, 0x0a, 0xcc},
- {0xb8, 0xb5, 0x0a, 0xcc},
- {0xb8, 0xfe, 0x00, 0xcc},
- {0xb8, 0xff, 0x28, 0xcc},
- {0xb9, 0x00, 0x28, 0xcc},
- {0xb9, 0x01, 0x28, 0xcc},
- {0xb9, 0x02, 0x28, 0xcc},
- {0xb9, 0x03, 0x00, 0xcc},
- {0xb9, 0x04, 0x00, 0xcc},
- {0xb9, 0x05, 0x3c, 0xcc},
- {0xb9, 0x06, 0x3c, 0xcc},
- {0xb9, 0x07, 0x3c, 0xcc},
- {0xb9, 0x08, 0x3c, 0xcc},
- {0xb8, 0x8e, 0x00, 0xcc},
- {0xb8, 0x8f, 0xff, 0xcc},
- {0xb8, 0x81, 0x09, 0xcc},
- {0x31, 0x00, 0x00, 0xbb},
- {0x09, 0x01, 0xc7, 0xbb},
- {0x34, 0x01, 0x00, 0xbb},
- {0x2b, 0x00, 0x28, 0xbb},
- {0x2c, 0x00, 0x30, 0xbb},
- {0x2d, 0x00, 0x30, 0xbb},
- {0x2e, 0x00, 0x28, 0xbb},
- {0x62, 0x04, 0x11, 0xbb},
- {0x03, 0x01, 0xe0, 0xbb},
- {0x2c, 0x00, 0x2c, 0xbb},
- {0x20, 0xd0, 0x00, 0xbb},
- {0x01, 0x00, 0x08, 0xbb},
- {0x06, 0x00, 0x10, 0xbb},
- {0x05, 0x00, 0x20, 0xbb},
- {0x20, 0x00, 0x00, 0xbb},
- {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x01, 0xcc},
- {0xb6, 0x02, 0x40, 0xcc},
- {0xb6, 0x05, 0x00, 0xcc},
- {0xb6, 0x04, 0xf0, 0xcc},
- {0xb6, 0x12, 0x78, 0xcc},
- {0xb6, 0x18, 0x00, 0xcc},
- {0xb6, 0x17, 0x96, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc},
- {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc},
- {0xb3, 0x02, 0x02, 0xcc},
- {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc},
- {0xbf, 0xcc, 0x10, 0xcc},
- {0xb9, 0x12, 0x00, 0xcc},
- {0xb9, 0x13, 0x0a, 0xcc},
- {0xb9, 0x14, 0x0a, 0xcc},
- {0xb9, 0x15, 0x0a, 0xcc},
- {0xb9, 0x16, 0x0a, 0xcc},
- {0xb9, 0x18, 0x00, 0xcc},
- {0xb9, 0x19, 0x0f, 0xcc},
- {0xb9, 0x1a, 0x0f, 0xcc},
- {0xb9, 0x1b, 0x0f, 0xcc},
- {0xb9, 0x1c, 0x0f, 0xcc},
- {0xb8, 0x8e, 0x00, 0xcc},
- {0xb8, 0x8f, 0xff, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x13, 0x13, 0xcc},
- {0xbc, 0x02, 0x18, 0xcc},
- {0xbc, 0x03, 0x50, 0xcc},
- {0xbc, 0x04, 0x18, 0xcc},
- {0xbc, 0x05, 0x00, 0xcc},
- {0xbc, 0x06, 0x00, 0xcc},
- {0xbc, 0x08, 0x30, 0xcc},
- {0xbc, 0x09, 0x40, 0xcc},
- {0xbc, 0x0a, 0x10, 0xcc},
- {0xb8, 0x0c, 0x20, 0xcc},
- {0xb8, 0x0d, 0x70, 0xcc},
- {0xbc, 0x0b, 0x00, 0xcc},
- {0xbc, 0x0c, 0x00, 0xcc},
- {0x35, 0x00, 0xef, 0xbb},
- {0xb3, 0x5c, 0x01, 0xcc},
- {}
-};
-
-static const u8 mi1310_socinitVGA_JPG[][4] = {
- {0xb0, 0x03, 0x19, 0xcc},
- {0xb0, 0x04, 0x02, 0xcc},
- {0xb3, 0x00, 0x64, 0xcc},
- {0xb3, 0x00, 0x65, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x00, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x34, 0x02, 0xcc},
- {0xb3, 0x35, 0xdd, 0xcc}, /* i2c add: 5d */
- {0xb3, 0x02, 0x00, 0xcc},
- {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x03, 0xcc},
- {0xb3, 0x23, 0xc0, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x04, 0xcc},
- {0xb3, 0x17, 0xff, 0xcc},
- {0xb3, 0x00, 0x65, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc},
- {0xbc, 0x00, 0xd0, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0xf0, 0x00, 0x02, 0xbb},
- {0xc8, 0x9f, 0x0b, 0xbb},
- {0x5b, 0x00, 0x01, 0xbb},
- {0x2f, 0xde, 0x20, 0xbb},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x20, 0x03, 0x02, 0xbb}, /* h/v flip */
- {0xf0, 0x00, 0x01, 0xbb},
- {0x05, 0x00, 0x07, 0xbb},
- {0x34, 0x00, 0x00, 0xbb},
- {0x35, 0xff, 0x00, 0xbb},
- {0xdc, 0x07, 0x02, 0xbb},
- {0xdd, 0x3c, 0x18, 0xbb},
- {0xde, 0x92, 0x6d, 0xbb},
- {0xdf, 0xcd, 0xb1, 0xbb},
- {0xe0, 0xff, 0xe7, 0xbb},
- {0x06, 0xf0, 0x0d, 0xbb},
- {0x06, 0x70, 0x0e, 0xbb},
- {0x4c, 0x00, 0x01, 0xbb},
- {0x4d, 0x00, 0x01, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x2e, 0x0c, 0x55, 0xbb},
- {0x21, 0xb6, 0x6e, 0xbb},
- {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc1, 0xbb},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x07, 0x00, 0x84, 0xbb},
- {0x08, 0x02, 0x4a, 0xbb},
- {0x05, 0x01, 0x10, 0xbb},
- {0x06, 0x00, 0x39, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x58, 0x02, 0x67, 0xbb},
- {0x57, 0x02, 0x00, 0xbb},
- {0x5a, 0x02, 0x67, 0xbb},
- {0x59, 0x02, 0x00, 0xbb},
- {0x5c, 0x12, 0x0d, 0xbb},
- {0x5d, 0x16, 0x11, 0xbb},
- {0x39, 0x06, 0x18, 0xbb},
- {0x3a, 0x06, 0x18, 0xbb},
- {0x3b, 0x06, 0x18, 0xbb},
- {0x3c, 0x06, 0x18, 0xbb},
- {0x64, 0x7b, 0x5b, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc0, 0xbb},
- {0xbc, 0x0e, 0x00, 0xcc},
- {0xbc, 0x0f, 0x05, 0xcc},
- {0xbc, 0x10, 0xc0, 0xcc},
- {0xbc, 0x11, 0x03, 0xcc},
- {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x02, 0xcc},
- {0xb6, 0x02, 0x80, 0xcc},
- {0xb6, 0x05, 0x01, 0xcc},
- {0xb6, 0x04, 0xe0, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x13, 0x25, 0xcc},
- {0xb6, 0x18, 0x02, 0xcc},
- {0xb6, 0x17, 0x58, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc},
- {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc},
- {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc},
- {0xbf, 0xcc, 0x00, 0xcc},
- {0xbc, 0x02, 0x18, 0xcc},
- {0xbc, 0x03, 0x50, 0xcc},
- {0xbc, 0x04, 0x18, 0xcc},
- {0xbc, 0x05, 0x00, 0xcc},
- {0xbc, 0x06, 0x00, 0xcc},
- {0xbc, 0x08, 0x30, 0xcc},
- {0xbc, 0x09, 0x40, 0xcc},
- {0xbc, 0x0a, 0x10, 0xcc},
- {0xbc, 0x0b, 0x00, 0xcc},
- {0xbc, 0x0c, 0x00, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x80, 0x00, 0x03, 0xbb},
- {0x81, 0xc7, 0x14, 0xbb},
- {0x82, 0xeb, 0xe8, 0xbb},
- {0x83, 0xfe, 0xf4, 0xbb},
- {0x84, 0xcd, 0x10, 0xbb},
- {0x85, 0xf3, 0xee, 0xbb},
- {0x86, 0xff, 0xf1, 0xbb},
- {0x87, 0xcd, 0x10, 0xbb},
- {0x88, 0xf3, 0xee, 0xbb},
- {0x89, 0x01, 0xf1, 0xbb},
- {0x8a, 0xe5, 0x17, 0xbb},
- {0x8b, 0xe8, 0xe2, 0xbb},
- {0x8c, 0xf7, 0xed, 0xbb},
- {0x8d, 0x00, 0xff, 0xbb},
- {0x8e, 0xec, 0x10, 0xbb},
- {0x8f, 0xf0, 0xed, 0xbb},
- {0x90, 0xf9, 0xf2, 0xbb},
- {0x91, 0x00, 0x00, 0xbb},
- {0x92, 0xe9, 0x0d, 0xbb},
- {0x93, 0xf4, 0xf2, 0xbb},
- {0x94, 0xfb, 0xf5, 0xbb},
- {0x95, 0x00, 0xff, 0xbb},
- {0xb6, 0x0f, 0x08, 0xbb},
- {0xb7, 0x3d, 0x16, 0xbb},
- {0xb8, 0x0c, 0x04, 0xbb},
- {0xb9, 0x1c, 0x07, 0xbb},
- {0xba, 0x0a, 0x03, 0xbb},
- {0xbb, 0x1b, 0x09, 0xbb},
- {0xbc, 0x17, 0x0d, 0xbb},
- {0xbd, 0x23, 0x1d, 0xbb},
- {0xbe, 0x00, 0x28, 0xbb},
- {0xbf, 0x11, 0x09, 0xbb},
- {0xc0, 0x16, 0x15, 0xbb},
- {0xc1, 0x00, 0x1b, 0xbb},
- {0xc2, 0x0e, 0x07, 0xbb},
- {0xc3, 0x14, 0x10, 0xbb},
- {0xc4, 0x00, 0x17, 0xbb},
- {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x06, 0xf4, 0x8e, 0xbb},
- {0x00, 0x00, 0x50, 0xdd},
- {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x24, 0x50, 0x20, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x34, 0x0c, 0x50, 0xbb},
- {0xb3, 0x01, 0x41, 0xcc},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x03, 0x03, 0xc0, 0xbb},
- {},
-};
-static const u8 mi1310_socinitQVGA_JPG[][4] = {
- {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc},
- {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x00, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x03, 0xcc},
- {0xb3, 0x23, 0xc0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x04, 0xcc},
- {0xb3, 0x17, 0xff, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc}, {0xbc, 0x00, 0xf0, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb},
- {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb},
- {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
- {0x20, 0x03, 0x02, 0xbb}, /* h/v flip */
- {0xf0, 0x00, 0x01, 0xbb},
- {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb},
- {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb},
- {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb},
- {0xdf, 0xcd, 0xb1, 0xbb}, {0xe0, 0xff, 0xe7, 0xbb},
- {0x06, 0xf0, 0x0d, 0xbb}, {0x06, 0x70, 0x0e, 0xbb},
- {0x4c, 0x00, 0x01, 0xbb}, {0x4d, 0x00, 0x01, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x2e, 0x0c, 0x55, 0xbb},
- {0x21, 0xb6, 0x6e, 0xbb}, {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc1, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
- {0x07, 0x00, 0x84, 0xbb}, {0x08, 0x02, 0x4a, 0xbb},
- {0x05, 0x01, 0x10, 0xbb}, {0x06, 0x00, 0x39, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x58, 0x02, 0x67, 0xbb},
- {0x57, 0x02, 0x00, 0xbb}, {0x5a, 0x02, 0x67, 0xbb},
- {0x59, 0x02, 0x00, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb},
- {0x5d, 0x16, 0x11, 0xbb}, {0x39, 0x06, 0x18, 0xbb},
- {0x3a, 0x06, 0x18, 0xbb}, {0x3b, 0x06, 0x18, 0xbb},
- {0x3c, 0x06, 0x18, 0xbb}, {0x64, 0x7b, 0x5b, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc0, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc},
- {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc},
- {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc},
- {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x25, 0xcc},
- {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc}, {0xf0, 0x00, 0x01, 0xbb},
- {0x80, 0x00, 0x03, 0xbb}, {0x81, 0xc7, 0x14, 0xbb},
- {0x82, 0xeb, 0xe8, 0xbb}, {0x83, 0xfe, 0xf4, 0xbb},
- {0x84, 0xcd, 0x10, 0xbb}, {0x85, 0xf3, 0xee, 0xbb},
- {0x86, 0xff, 0xf1, 0xbb}, {0x87, 0xcd, 0x10, 0xbb},
- {0x88, 0xf3, 0xee, 0xbb}, {0x89, 0x01, 0xf1, 0xbb},
- {0x8a, 0xe5, 0x17, 0xbb}, {0x8b, 0xe8, 0xe2, 0xbb},
- {0x8c, 0xf7, 0xed, 0xbb}, {0x8d, 0x00, 0xff, 0xbb},
- {0x8e, 0xec, 0x10, 0xbb}, {0x8f, 0xf0, 0xed, 0xbb},
- {0x90, 0xf9, 0xf2, 0xbb}, {0x91, 0x00, 0x00, 0xbb},
- {0x92, 0xe9, 0x0d, 0xbb}, {0x93, 0xf4, 0xf2, 0xbb},
- {0x94, 0xfb, 0xf5, 0xbb}, {0x95, 0x00, 0xff, 0xbb},
- {0xb6, 0x0f, 0x08, 0xbb}, {0xb7, 0x3d, 0x16, 0xbb},
- {0xb8, 0x0c, 0x04, 0xbb}, {0xb9, 0x1c, 0x07, 0xbb},
- {0xba, 0x0a, 0x03, 0xbb}, {0xbb, 0x1b, 0x09, 0xbb},
- {0xbc, 0x17, 0x0d, 0xbb}, {0xbd, 0x23, 0x1d, 0xbb},
- {0xbe, 0x00, 0x28, 0xbb}, {0xbf, 0x11, 0x09, 0xbb},
- {0xc0, 0x16, 0x15, 0xbb}, {0xc1, 0x00, 0x1b, 0xbb},
- {0xc2, 0x0e, 0x07, 0xbb}, {0xc3, 0x14, 0x10, 0xbb},
- {0xc4, 0x00, 0x17, 0xbb}, {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0xf4, 0x8e, 0xbb},
- {0x00, 0x00, 0x50, 0xdd}, {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x24, 0x50, 0x20, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x34, 0x0c, 0x50, 0xbb},
- {0xb3, 0x01, 0x41, 0xcc}, {0xf0, 0x00, 0x00, 0xbb},
- {0x03, 0x03, 0xc0, 0xbb},
- {},
-};
-static const u8 mi1310_soc_InitSXGA_JPG[][4] = {
- {0xb0, 0x03, 0x19, 0xcc},
- {0xb0, 0x04, 0x02, 0xcc},
- {0xb3, 0x00, 0x64, 0xcc},
- {0xb3, 0x00, 0x65, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x00, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x34, 0x02, 0xcc},
- {0xb3, 0x35, 0xdd, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc},
- {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x0d, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x03, 0xcc},
- {0xb3, 0x23, 0xc0, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x04, 0xcc},
- {0xb3, 0x17, 0xff, 0xcc},
- {0xb3, 0x00, 0x65, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc},
- {0xbc, 0x00, 0x70, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0xf0, 0x00, 0x02, 0xbb},
- {0xc8, 0x9f, 0x0b, 0xbb},
- {0x5b, 0x00, 0x01, 0xbb},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x20, 0x03, 0x02, 0xbb}, /* h/v flip */
- {0xf0, 0x00, 0x01, 0xbb},
- {0x05, 0x00, 0x07, 0xbb},
- {0x34, 0x00, 0x00, 0xbb},
- {0x35, 0xff, 0x00, 0xbb},
- {0xdc, 0x07, 0x02, 0xbb},
- {0xdd, 0x3c, 0x18, 0xbb},
- {0xde, 0x92, 0x6d, 0xbb},
- {0xdf, 0xcd, 0xb1, 0xbb},
- {0xe0, 0xff, 0xe7, 0xbb},
- {0x06, 0xf0, 0x0d, 0xbb},
- {0x06, 0x70, 0x0e, 0xbb},
- {0x4c, 0x00, 0x01, 0xbb},
- {0x4d, 0x00, 0x01, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x2e, 0x0c, 0x60, 0xbb},
- {0x21, 0xb6, 0x6e, 0xbb},
- {0x37, 0x01, 0x40, 0xbb},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x07, 0x00, 0x84, 0xbb},
- {0x08, 0x02, 0x4a, 0xbb},
- {0x05, 0x01, 0x10, 0xbb},
- {0x06, 0x00, 0x39, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x58, 0x02, 0x67, 0xbb},
- {0x57, 0x02, 0x00, 0xbb},
- {0x5a, 0x02, 0x67, 0xbb},
- {0x59, 0x02, 0x00, 0xbb},
- {0x5c, 0x12, 0x0d, 0xbb},
- {0x5d, 0x16, 0x11, 0xbb},
- {0x39, 0x06, 0x18, 0xbb},
- {0x3a, 0x06, 0x18, 0xbb},
- {0x3b, 0x06, 0x18, 0xbb},
- {0x3c, 0x06, 0x18, 0xbb},
- {0x64, 0x7b, 0x5b, 0xbb},
- {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x05, 0xcc},
- {0xb6, 0x02, 0x00, 0xcc},
- {0xb6, 0x05, 0x03, 0xcc},
- {0xb6, 0x04, 0xc0, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x13, 0x29, 0xcc},
- {0xb6, 0x18, 0x09, 0xcc},
- {0xb6, 0x17, 0x60, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc},
- {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc},
- {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc},
- {0xbf, 0xcc, 0x00, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc},
- {0x00, 0x00, 0x80, 0xdd},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x00, 0x00, 0x10, 0xdd},
- {0x22, 0xa0, 0x78, 0xbb},
- {0x23, 0xa0, 0x78, 0xbb},
- {0x24, 0x7f, 0x00, 0xbb},
- {0x28, 0xea, 0x02, 0xbb},
- {0x29, 0x86, 0x7a, 0xbb},
- {0x5e, 0x52, 0x4c, 0xbb},
- {0x5f, 0x20, 0x24, 0xbb},
- {0x60, 0x00, 0x02, 0xbb},
- {0x02, 0x00, 0xee, 0xbb},
- {0x03, 0x39, 0x23, 0xbb},
- {0x04, 0x07, 0x24, 0xbb},
- {0x09, 0x00, 0xc0, 0xbb},
- {0x0a, 0x00, 0x79, 0xbb},
- {0x0b, 0x00, 0x04, 0xbb},
- {0x0c, 0x00, 0x5c, 0xbb},
- {0x0d, 0x00, 0xd9, 0xbb},
- {0x0e, 0x00, 0x53, 0xbb},
- {0x0f, 0x00, 0x21, 0xbb},
- {0x10, 0x00, 0xa4, 0xbb},
- {0x11, 0x00, 0xe5, 0xbb},
- {0x15, 0x00, 0x00, 0xbb},
- {0x16, 0x00, 0x00, 0xbb},
- {0x17, 0x00, 0x00, 0xbb},
- {0x18, 0x00, 0x00, 0xbb},
- {0x19, 0x00, 0x00, 0xbb},
- {0x1a, 0x00, 0x00, 0xbb},
- {0x1b, 0x00, 0x00, 0xbb},
- {0x1c, 0x00, 0x00, 0xbb},
- {0x1d, 0x00, 0x00, 0xbb},
- {0x1e, 0x00, 0x00, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x00, 0x00, 0x20, 0xdd},
- {0x06, 0xf0, 0x8e, 0xbb},
- {0x00, 0x00, 0x80, 0xdd},
- {0x06, 0x70, 0x8e, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x00, 0x00, 0x20, 0xdd},
- {0x5e, 0x6a, 0x53, 0xbb},
- {0x5f, 0x40, 0x2c, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x00, 0x00, 0x20, 0xdd},
- {0x58, 0x00, 0x00, 0xbb},
- {0x53, 0x09, 0x03, 0xbb},
- {0x54, 0x31, 0x18, 0xbb},
- {0x55, 0x8b, 0x5f, 0xbb},
- {0x56, 0xc0, 0xa9, 0xbb},
- {0x57, 0xe0, 0xd2, 0xbb},
- {0xe1, 0x00, 0x00, 0xbb},
- {0xdc, 0x09, 0x03, 0xbb},
- {0xdd, 0x31, 0x18, 0xbb},
- {0xde, 0x8b, 0x5f, 0xbb},
- {0xdf, 0xc0, 0xa9, 0xbb},
- {0xe0, 0xe0, 0xd2, 0xbb},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x06, 0xf0, 0x8e, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x2f, 0xde, 0x20, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x24, 0x50, 0x20, 0xbb},
- {0xbc, 0x0e, 0x00, 0xcc},
- {0xbc, 0x0f, 0x05, 0xcc},
- {0xbc, 0x10, 0xc0, 0xcc},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x34, 0x0c, 0x50, 0xbb},
- {0xbc, 0x11, 0x03, 0xcc},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x80, 0x00, 0x03, 0xbb},
- {0x81, 0xc7, 0x14, 0xbb},
- {0x82, 0xeb, 0xe8, 0xbb},
- {0x83, 0xfe, 0xf4, 0xbb},
- {0x84, 0xcd, 0x10, 0xbb},
- {0x85, 0xf3, 0xee, 0xbb},
- {0x86, 0xff, 0xf1, 0xbb},
- {0x87, 0xcd, 0x10, 0xbb},
- {0x88, 0xf3, 0xee, 0xbb},
- {0x89, 0x01, 0xf1, 0xbb},
- {0x8a, 0xe5, 0x17, 0xbb},
- {0x8b, 0xe8, 0xe2, 0xbb},
- {0x8c, 0xf7, 0xed, 0xbb},
- {0x8d, 0x00, 0xff, 0xbb},
- {0x8e, 0xec, 0x10, 0xbb},
- {0x8f, 0xf0, 0xed, 0xbb},
- {0x90, 0xf9, 0xf2, 0xbb},
- {0x91, 0x00, 0x00, 0xbb},
- {0x92, 0xe9, 0x0d, 0xbb},
- {0x93, 0xf4, 0xf2, 0xbb},
- {0x94, 0xfb, 0xf5, 0xbb},
- {0x95, 0x00, 0xff, 0xbb},
- {0xb6, 0x0f, 0x08, 0xbb},
- {0xb7, 0x3d, 0x16, 0xbb},
- {0xb8, 0x0c, 0x04, 0xbb},
- {0xb9, 0x1c, 0x07, 0xbb},
- {0xba, 0x0a, 0x03, 0xbb},
- {0xbb, 0x1b, 0x09, 0xbb},
- {0xbc, 0x17, 0x0d, 0xbb},
- {0xbd, 0x23, 0x1d, 0xbb},
- {0xbe, 0x00, 0x28, 0xbb},
- {0xbf, 0x11, 0x09, 0xbb},
- {0xc0, 0x16, 0x15, 0xbb},
- {0xc1, 0x00, 0x1b, 0xbb},
- {0xc2, 0x0e, 0x07, 0xbb},
- {0xc3, 0x14, 0x10, 0xbb},
- {0xc4, 0x00, 0x17, 0xbb},
- {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x03, 0x03, 0xc0, 0xbb},
- {}
-};
-
-static const u8 mi1320_gamma[17] = {
- 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
- 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
-};
-static const u8 mi1320_matrix[9] = {
- 0x54, 0xda, 0x06, 0xf1, 0x50, 0xf4, 0xf7, 0xea, 0x52
-};
-static const u8 mi1320_initVGA_data[][4] = {
- {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
- {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
- {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
- {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
- {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x00, 0xcc}, {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc},
- {0xb3, 0x35, 0xc8, 0xcc}, /* i2c add: 48 */
- {0xb3, 0x02, 0x00, 0xcc},
- {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x03, 0xcc}, {0xb3, 0x23, 0xc0, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x04, 0xcc}, {0xb3, 0x17, 0xff, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc}, {0xbc, 0x00, 0xd0, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x00, 0xbb},
- {0x0d, 0x00, 0x09, 0xbb}, {0x00, 0x01, 0x00, 0xdd},
- {0x0d, 0x00, 0x08, 0xbb}, {0xf0, 0x00, 0x01, 0xbb},
- {0xa1, 0x05, 0x00, 0xbb}, {0xa4, 0x03, 0xc0, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x00, 0x00, 0x10, 0xdd},
- {0xc8, 0x9f, 0x0b, 0xbb}, {0x00, 0x00, 0x10, 0xdd},
- {0xf0, 0x00, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd},
- {0x20, 0x01, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd},
- {0xf0, 0x00, 0x01, 0xbb}, {0x9d, 0x3c, 0xa0, 0xbb},
- {0x47, 0x30, 0x30, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
- {0x0a, 0x80, 0x11, 0xbb}, {0x35, 0x00, 0x22, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x9d, 0xc5, 0x05, 0xbb},
- {0xdc, 0x0f, 0xfc, 0xbb}, {0xf0, 0x00, 0x01, 0xbb},
- {0x06, 0x74, 0x0e, 0xbb}, {0x80, 0x00, 0x06, 0xbb},
- {0x81, 0x04, 0x00, 0xbb}, {0x82, 0x01, 0x02, 0xbb},
- {0x83, 0x03, 0x02, 0xbb}, {0x84, 0x05, 0x00, 0xbb},
- {0x85, 0x01, 0x00, 0xbb}, {0x86, 0x03, 0x02, 0xbb},
- {0x87, 0x05, 0x00, 0xbb}, {0x88, 0x01, 0x00, 0xbb},
- {0x89, 0x02, 0x02, 0xbb}, {0x8a, 0xfd, 0x04, 0xbb},
- {0x8b, 0xfc, 0xfd, 0xbb}, {0x8c, 0xff, 0xfd, 0xbb},
- {0x8d, 0x00, 0x00, 0xbb}, {0x8e, 0xfe, 0x05, 0xbb},
- {0x8f, 0xfc, 0xfd, 0xbb}, {0x90, 0xfe, 0xfd, 0xbb},
- {0x91, 0x00, 0x00, 0xbb}, {0x92, 0xfe, 0x03, 0xbb},
- {0x93, 0xfd, 0xfe, 0xbb}, {0x94, 0xff, 0xfd, 0xbb},
- {0x95, 0x00, 0x00, 0xbb}, {0xb6, 0x07, 0x05, 0xbb},
- {0xb7, 0x13, 0x06, 0xbb}, {0xb8, 0x08, 0x06, 0xbb},
- {0xb9, 0x14, 0x08, 0xbb}, {0xba, 0x06, 0x05, 0xbb},
- {0xbb, 0x13, 0x06, 0xbb}, {0xbc, 0x03, 0x01, 0xbb},
- {0xbd, 0x03, 0x04, 0xbb}, {0xbe, 0x00, 0x02, 0xbb},
- {0xbf, 0x03, 0x01, 0xbb}, {0xc0, 0x02, 0x04, 0xbb},
- {0xc1, 0x00, 0x04, 0xbb}, {0xc2, 0x02, 0x01, 0xbb},
- {0xc3, 0x01, 0x03, 0xbb}, {0xc4, 0x00, 0x04, 0xbb},
- {0xf0, 0x00, 0x00, 0xbb}, {0x05, 0x01, 0x13, 0xbb},
- {0x06, 0x00, 0x11, 0xbb}, {0x07, 0x00, 0x85, 0xbb},
- {0x08, 0x00, 0x27, 0xbb},
- {0x20, 0x01, 0x00, 0xbb}, /* h/v flips - was 03 */
- {0x21, 0x80, 0x00, 0xbb}, {0x22, 0x0d, 0x0f, 0xbb},
- {0x24, 0x80, 0x00, 0xbb}, {0x59, 0x00, 0xff, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x39, 0x03, 0x0d, 0xbb},
- {0x3a, 0x06, 0x1b, 0xbb}, {0x3b, 0x00, 0x95, 0xbb},
- {0x3c, 0x04, 0xdb, 0xbb}, {0x57, 0x02, 0x00, 0xbb},
- {0x58, 0x02, 0x66, 0xbb}, {0x59, 0x00, 0xff, 0xbb},
- {0x5a, 0x01, 0x33, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb},
- {0x5d, 0x16, 0x11, 0xbb}, {0x64, 0x5e, 0x1c, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb},
- {0x5b, 0x00, 0x01, 0xbb}, {0xf0, 0x00, 0x02, 0xbb},
- {0x36, 0x68, 0x10, 0xbb}, {0x00, 0x00, 0x30, 0xdd},
- {0x37, 0x82, 0x00, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc},
- {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc},
- {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x05, 0xcc}, {0xb6, 0x02, 0x00, 0xcc},
- {0xb6, 0x05, 0x04, 0xcc}, {0xb6, 0x04, 0x00, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x29, 0xcc},
- {0xb6, 0x18, 0x0a, 0xcc}, {0xb6, 0x17, 0x00, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x26, 0xcc},
- {0xbf, 0xc1, 0x02, 0xcc}, {0xbf, 0xcc, 0x04, 0xcc},
- {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc},
- {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc},
- {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc},
- {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc},
- {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x41, 0xcc},
- {}
-};
-static const u8 mi1320_initQVGA_data[][4] = {
- {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
- {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
- {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
- {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
- {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x01, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc},
- {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc},
- {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x01, 0xcc}, {0xb3, 0x23, 0xe0, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x00, 0x65, 0xcc}, {0xb8, 0x00, 0x00, 0xcc},
- {0xbc, 0x00, 0xd0, 0xcc}, {0xbc, 0x01, 0x01, 0xcc},
- {0xf0, 0x00, 0x00, 0xbb}, {0x0d, 0x00, 0x09, 0xbb},
- {0x00, 0x01, 0x00, 0xdd}, {0x0d, 0x00, 0x08, 0xbb},
- {0xf0, 0x00, 0x00, 0xbb}, {0x02, 0x00, 0x64, 0xbb},
- {0x05, 0x01, 0x78, 0xbb}, {0x06, 0x00, 0x11, 0xbb},
- {0x07, 0x01, 0x42, 0xbb}, {0x08, 0x00, 0x11, 0xbb},
- {0x20, 0x01, 0x00, 0xbb}, {0x21, 0x80, 0x00, 0xbb},
- {0x22, 0x0d, 0x0f, 0xbb}, {0x24, 0x80, 0x00, 0xbb},
- {0x59, 0x00, 0xff, 0xbb}, {0xf0, 0x00, 0x01, 0xbb},
- {0x9d, 0x3c, 0xa0, 0xbb}, {0x47, 0x30, 0x30, 0xbb},
- {0xf0, 0x00, 0x00, 0xbb}, {0x0a, 0x80, 0x11, 0xbb},
- {0x35, 0x00, 0x22, 0xbb}, {0xf0, 0x00, 0x02, 0xbb},
- {0x9d, 0xc5, 0x05, 0xbb}, {0xdc, 0x0f, 0xfc, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0x74, 0x0e, 0xbb},
- {0x80, 0x00, 0x06, 0xbb}, {0x81, 0x04, 0x00, 0xbb},
- {0x82, 0x01, 0x02, 0xbb}, {0x83, 0x03, 0x02, 0xbb},
- {0x84, 0x05, 0x00, 0xbb}, {0x85, 0x01, 0x00, 0xbb},
- {0x86, 0x03, 0x02, 0xbb}, {0x87, 0x05, 0x00, 0xbb},
- {0x88, 0x01, 0x00, 0xbb}, {0x89, 0x02, 0x02, 0xbb},
- {0x8a, 0xfd, 0x04, 0xbb}, {0x8b, 0xfc, 0xfd, 0xbb},
- {0x8c, 0xff, 0xfd, 0xbb}, {0x8d, 0x00, 0x00, 0xbb},
- {0x8e, 0xfe, 0x05, 0xbb}, {0x8f, 0xfc, 0xfd, 0xbb},
- {0x90, 0xfe, 0xfd, 0xbb}, {0x91, 0x00, 0x00, 0xbb},
- {0x92, 0xfe, 0x03, 0xbb}, {0x93, 0xfd, 0xfe, 0xbb},
- {0x94, 0xff, 0xfd, 0xbb}, {0x95, 0x00, 0x00, 0xbb},
- {0xb6, 0x07, 0x05, 0xbb}, {0xb7, 0x13, 0x06, 0xbb},
- {0xb8, 0x08, 0x06, 0xbb}, {0xb9, 0x14, 0x08, 0xbb},
- {0xba, 0x06, 0x05, 0xbb}, {0xbb, 0x13, 0x06, 0xbb},
- {0xbc, 0x03, 0x01, 0xbb}, {0xbd, 0x03, 0x04, 0xbb},
- {0xbe, 0x00, 0x02, 0xbb}, {0xbf, 0x03, 0x01, 0xbb},
- {0xc0, 0x02, 0x04, 0xbb}, {0xc1, 0x00, 0x04, 0xbb},
- {0xc2, 0x02, 0x01, 0xbb}, {0xc3, 0x01, 0x03, 0xbb},
- {0xc4, 0x00, 0x04, 0xbb}, {0xf0, 0x00, 0x02, 0xbb},
- {0xc8, 0x00, 0x00, 0xbb}, {0x2e, 0x00, 0x00, 0xbb},
- {0x2e, 0x0c, 0x5b, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb},
- {0x39, 0x03, 0xca, 0xbb}, {0x3a, 0x06, 0x80, 0xbb},
- {0x3b, 0x01, 0x52, 0xbb}, {0x3c, 0x05, 0x40, 0xbb},
- {0x57, 0x01, 0x9c, 0xbb}, {0x58, 0x01, 0xee, 0xbb},
- {0x59, 0x00, 0xf0, 0xbb}, {0x5a, 0x01, 0x20, 0xbb},
- {0x5c, 0x1d, 0x17, 0xbb}, {0x5d, 0x22, 0x1c, 0xbb},
- {0x64, 0x1e, 0x1c, 0xbb}, {0x5b, 0x00, 0x01, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x68, 0x10, 0xbb},
- {0x00, 0x00, 0x30, 0xdd}, {0x37, 0x81, 0x00, 0xbb},
- {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc},
- {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc},
- {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc},
- {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc},
- {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc},
- {0xbf, 0xc0, 0x26, 0xcc}, {0xbf, 0xc1, 0x02, 0xcc},
- {0xbf, 0xcc, 0x04, 0xcc}, {0xb3, 0x5c, 0x01, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc},
- {}
-};
-
-static const u8 mi1320_soc_InitVGA[][4] = {
- {0xb3, 0x01, 0x01, 0xcc},
- {0xb0, 0x03, 0x19, 0xcc},
- {0xb0, 0x04, 0x02, 0xcc},
- {0x00, 0x00, 0x30, 0xdd},
- {0xb3, 0x00, 0x64, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb3, 0x05, 0x01, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x34, 0x02, 0xcc},
- {0xb3, 0x35, 0xc8, 0xcc}, /* i2c add: 48 */
- {0xb3, 0x02, 0x00, 0xcc},
- {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x01, 0xcc},
- {0xb3, 0x23, 0xe0, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x02, 0xcc},
- {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc},
- {0xbc, 0x00, 0x71, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x00, 0x00, 0x10, 0xdd},
- {0xc8, 0x00, 0x00, 0xbb},
- {0x00, 0x00, 0x30, 0xdd},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x00, 0x00, 0x10, 0xdd},
- {0x07, 0x00, 0xe0, 0xbb},
- {0x08, 0x00, 0x0b, 0xbb},
- {0x21, 0x00, 0x0c, 0xbb},
- {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
- {0xbf, 0xc0, 0x26, 0xcc},
- {0xbf, 0xc1, 0x02, 0xcc},
- {0xbf, 0xcc, 0x04, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x05, 0x01, 0x78, 0xbb},
- {0x06, 0x00, 0x11, 0xbb},
- {0x07, 0x01, 0x42, 0xbb},
- {0x08, 0x00, 0x11, 0xbb},
- {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
- {0x21, 0x80, 0x00, 0xbb},
- {0x22, 0x0d, 0x0f, 0xbb},
- {0x24, 0x80, 0x00, 0xbb},
- {0x59, 0x00, 0xff, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x39, 0x03, 0xca, 0xbb},
- {0x3a, 0x06, 0x80, 0xbb},
- {0x3b, 0x01, 0x52, 0xbb},
- {0x3c, 0x05, 0x40, 0xbb},
- {0x57, 0x01, 0x9c, 0xbb},
- {0x58, 0x01, 0xee, 0xbb},
- {0x59, 0x00, 0xf0, 0xbb},
- {0x5a, 0x01, 0x20, 0xbb},
- {0x5c, 0x1d, 0x17, 0xbb},
- {0x5d, 0x22, 0x1c, 0xbb},
- {0x64, 0x1e, 0x1c, 0xbb},
- {0x5b, 0x00, 0x00, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x22, 0xa0, 0x78, 0xbb},
- {0x23, 0xa0, 0x78, 0xbb},
- {0x24, 0x7f, 0x00, 0xbb},
- {0x28, 0xea, 0x02, 0xbb},
- {0x29, 0x86, 0x7a, 0xbb},
- {0x5e, 0x52, 0x4c, 0xbb},
- {0x5f, 0x20, 0x24, 0xbb},
- {0x60, 0x00, 0x02, 0xbb},
- {0x02, 0x00, 0xee, 0xbb},
- {0x03, 0x39, 0x23, 0xbb},
- {0x04, 0x07, 0x24, 0xbb},
- {0x09, 0x00, 0xc0, 0xbb},
- {0x0a, 0x00, 0x79, 0xbb},
- {0x0b, 0x00, 0x04, 0xbb},
- {0x0c, 0x00, 0x5c, 0xbb},
- {0x0d, 0x00, 0xd9, 0xbb},
- {0x0e, 0x00, 0x53, 0xbb},
- {0x0f, 0x00, 0x21, 0xbb},
- {0x10, 0x00, 0xa4, 0xbb},
- {0x11, 0x00, 0xe5, 0xbb},
- {0x15, 0x00, 0x00, 0xbb},
- {0x16, 0x00, 0x00, 0xbb},
- {0x17, 0x00, 0x00, 0xbb},
- {0x18, 0x00, 0x00, 0xbb},
- {0x19, 0x00, 0x00, 0xbb},
- {0x1a, 0x00, 0x00, 0xbb},
- {0x1b, 0x00, 0x00, 0xbb},
- {0x1c, 0x00, 0x00, 0xbb},
- {0x1d, 0x00, 0x00, 0xbb},
- {0x1e, 0x00, 0x00, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x06, 0xe0, 0x0e, 0xbb},
- {0x06, 0x60, 0x0e, 0xbb},
- {0xb3, 0x5c, 0x01, 0xcc},
- {}
-};
-static const u8 mi1320_soc_InitQVGA[][4] = {
- {0xb3, 0x01, 0x01, 0xcc},
- {0xb0, 0x03, 0x19, 0xcc},
- {0xb0, 0x04, 0x02, 0xcc},
- {0x00, 0x00, 0x30, 0xdd},
- {0xb3, 0x00, 0x64, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb3, 0x05, 0x01, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x34, 0x02, 0xcc},
- {0xb3, 0x35, 0xc8, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc},
- {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x01, 0xcc},
- {0xb3, 0x23, 0xe0, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x02, 0xcc},
- {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc},
- {0xbc, 0x00, 0xd1, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x00, 0x00, 0x10, 0xdd},
- {0xc8, 0x00, 0x00, 0xbb},
- {0x00, 0x00, 0x30, 0xdd},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x00, 0x00, 0x10, 0xdd},
- {0x07, 0x00, 0xe0, 0xbb},
- {0x08, 0x00, 0x0b, 0xbb},
- {0x21, 0x00, 0x0c, 0xbb},
- {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
- {0xbf, 0xc0, 0x26, 0xcc},
- {0xbf, 0xc1, 0x02, 0xcc},
- {0xbf, 0xcc, 0x04, 0xcc},
- {0xbc, 0x02, 0x18, 0xcc},
- {0xbc, 0x03, 0x50, 0xcc},
- {0xbc, 0x04, 0x18, 0xcc},
- {0xbc, 0x05, 0x00, 0xcc},
- {0xbc, 0x06, 0x00, 0xcc},
- {0xbc, 0x08, 0x30, 0xcc},
- {0xbc, 0x09, 0x40, 0xcc},
- {0xbc, 0x0a, 0x10, 0xcc},
- {0xbc, 0x0b, 0x00, 0xcc},
- {0xbc, 0x0c, 0x00, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x05, 0x01, 0x78, 0xbb},
- {0x06, 0x00, 0x11, 0xbb},
- {0x07, 0x01, 0x42, 0xbb},
- {0x08, 0x00, 0x11, 0xbb},
- {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
- {0x21, 0x80, 0x00, 0xbb},
- {0x22, 0x0d, 0x0f, 0xbb},
- {0x24, 0x80, 0x00, 0xbb},
- {0x59, 0x00, 0xff, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x39, 0x03, 0xca, 0xbb},
- {0x3a, 0x06, 0x80, 0xbb},
- {0x3b, 0x01, 0x52, 0xbb},
- {0x3c, 0x05, 0x40, 0xbb},
- {0x57, 0x01, 0x9c, 0xbb},
- {0x58, 0x01, 0xee, 0xbb},
- {0x59, 0x00, 0xf0, 0xbb},
- {0x5a, 0x01, 0x20, 0xbb},
- {0x5c, 0x1d, 0x17, 0xbb},
- {0x5d, 0x22, 0x1c, 0xbb},
- {0x64, 0x1e, 0x1c, 0xbb},
- {0x5b, 0x00, 0x00, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x22, 0xa0, 0x78, 0xbb},
- {0x23, 0xa0, 0x78, 0xbb},
- {0x24, 0x7f, 0x00, 0xbb},
- {0x28, 0xea, 0x02, 0xbb},
- {0x29, 0x86, 0x7a, 0xbb},
- {0x5e, 0x52, 0x4c, 0xbb},
- {0x5f, 0x20, 0x24, 0xbb},
- {0x60, 0x00, 0x02, 0xbb},
- {0x02, 0x00, 0xee, 0xbb},
- {0x03, 0x39, 0x23, 0xbb},
- {0x04, 0x07, 0x24, 0xbb},
- {0x09, 0x00, 0xc0, 0xbb},
- {0x0a, 0x00, 0x79, 0xbb},
- {0x0b, 0x00, 0x04, 0xbb},
- {0x0c, 0x00, 0x5c, 0xbb},
- {0x0d, 0x00, 0xd9, 0xbb},
- {0x0e, 0x00, 0x53, 0xbb},
- {0x0f, 0x00, 0x21, 0xbb},
- {0x10, 0x00, 0xa4, 0xbb},
- {0x11, 0x00, 0xe5, 0xbb},
- {0x15, 0x00, 0x00, 0xbb},
- {0x16, 0x00, 0x00, 0xbb},
- {0x17, 0x00, 0x00, 0xbb},
- {0x18, 0x00, 0x00, 0xbb},
- {0x19, 0x00, 0x00, 0xbb},
- {0x1a, 0x00, 0x00, 0xbb},
- {0x1b, 0x00, 0x00, 0xbb},
- {0x1c, 0x00, 0x00, 0xbb},
- {0x1d, 0x00, 0x00, 0xbb},
- {0x1e, 0x00, 0x00, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x06, 0xe0, 0x0e, 0xbb},
- {0x06, 0x60, 0x0e, 0xbb},
- {0xb3, 0x5c, 0x01, 0xcc},
- {}
-};
-static const u8 mi1320_soc_InitSXGA[][4] = {
- {0xb3, 0x01, 0x01, 0xcc},
- {0xb0, 0x03, 0x19, 0xcc},
- {0x00, 0x00, 0x30, 0xdd},
- {0xb3, 0x00, 0x64, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb3, 0x05, 0x01, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x34, 0x02, 0xcc},
- {0xb3, 0x35, 0xc8, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc},
- {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x04, 0xcc},
- {0xb3, 0x23, 0x00, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x04, 0xcc},
- {0xb3, 0x17, 0xff, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xbc, 0x00, 0x71, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x00, 0x00, 0x30, 0xdd},
- {0xc8, 0x9f, 0x0b, 0xbb},
- {0x00, 0x00, 0x20, 0xdd},
- {0x5b, 0x00, 0x01, 0xbb},
- {0x00, 0x00, 0x20, 0xdd},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x00, 0x00, 0x30, 0xdd},
- {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
- {0x00, 0x00, 0x20, 0xdd},
- {0xbf, 0xc0, 0x26, 0xcc},
- {0xbf, 0xc1, 0x02, 0xcc},
- {0xbf, 0xcc, 0x04, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x05, 0x01, 0x78, 0xbb},
- {0x06, 0x00, 0x11, 0xbb},
- {0x07, 0x01, 0x42, 0xbb},
- {0x08, 0x00, 0x11, 0xbb},
- {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
- {0x21, 0x80, 0x00, 0xbb},
- {0x22, 0x0d, 0x0f, 0xbb},
- {0x24, 0x80, 0x00, 0xbb},
- {0x59, 0x00, 0xff, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x39, 0x03, 0xca, 0xbb},
- {0x3a, 0x06, 0x80, 0xbb},
- {0x3b, 0x01, 0x52, 0xbb},
- {0x3c, 0x05, 0x40, 0xbb},
- {0x57, 0x01, 0x9c, 0xbb},
- {0x58, 0x01, 0xee, 0xbb},
- {0x59, 0x00, 0xf0, 0xbb},
- {0x5a, 0x01, 0x20, 0xbb},
- {0x5c, 0x1d, 0x17, 0xbb},
- {0x5d, 0x22, 0x1c, 0xbb},
- {0x64, 0x1e, 0x1c, 0xbb},
- {0x5b, 0x00, 0x00, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x22, 0xa0, 0x78, 0xbb},
- {0x23, 0xa0, 0x78, 0xbb},
- {0x24, 0x7f, 0x00, 0xbb},
- {0x28, 0xea, 0x02, 0xbb},
- {0x29, 0x86, 0x7a, 0xbb},
- {0x5e, 0x52, 0x4c, 0xbb},
- {0x5f, 0x20, 0x24, 0xbb},
- {0x60, 0x00, 0x02, 0xbb},
- {0x02, 0x00, 0xee, 0xbb},
- {0x03, 0x39, 0x23, 0xbb},
- {0x04, 0x07, 0x24, 0xbb},
- {0x09, 0x00, 0xc0, 0xbb},
- {0x0a, 0x00, 0x79, 0xbb},
- {0x0b, 0x00, 0x04, 0xbb},
- {0x0c, 0x00, 0x5c, 0xbb},
- {0x0d, 0x00, 0xd9, 0xbb},
- {0x0e, 0x00, 0x53, 0xbb},
- {0x0f, 0x00, 0x21, 0xbb},
- {0x10, 0x00, 0xa4, 0xbb},
- {0x11, 0x00, 0xe5, 0xbb},
- {0x15, 0x00, 0x00, 0xbb},
- {0x16, 0x00, 0x00, 0xbb},
- {0x17, 0x00, 0x00, 0xbb},
- {0x18, 0x00, 0x00, 0xbb},
- {0x19, 0x00, 0x00, 0xbb},
- {0x1a, 0x00, 0x00, 0xbb},
- {0x1b, 0x00, 0x00, 0xbb},
- {0x1c, 0x00, 0x00, 0xbb},
- {0x1d, 0x00, 0x00, 0xbb},
- {0x1e, 0x00, 0x00, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x06, 0xe0, 0x0e, 0xbb},
- {0x06, 0x60, 0x0e, 0xbb},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x05, 0x01, 0x13, 0xbb},
- {0x06, 0x00, 0x11, 0xbb},
- {0x07, 0x00, 0x85, 0xbb},
- {0x08, 0x00, 0x27, 0xbb},
- {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
- {0x21, 0x80, 0x00, 0xbb},
- {0x22, 0x0d, 0x0f, 0xbb},
- {0x24, 0x80, 0x00, 0xbb},
- {0x59, 0x00, 0xff, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x39, 0x03, 0x0d, 0xbb},
- {0x3a, 0x06, 0x1b, 0xbb},
- {0x3b, 0x00, 0x95, 0xbb},
- {0x3c, 0x04, 0xdb, 0xbb},
- {0x57, 0x02, 0x00, 0xbb},
- {0x58, 0x02, 0x66, 0xbb},
- {0x59, 0x00, 0xff, 0xbb},
- {0x5a, 0x01, 0x33, 0xbb},
- {0x5c, 0x12, 0x0d, 0xbb},
- {0x5d, 0x16, 0x11, 0xbb},
- {0x64, 0x5e, 0x1c, 0xbb},
- {}
-};
-static const u8 po3130_gamma[17] = {
- 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
- 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
-};
-static const u8 po3130_matrix[9] = {
- 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63
-};
-
-static const u8 po3130_initVGA_data[][4] = {
- {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
- {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc},
- {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc},
- {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x03, 0x1a, 0xcc},
- {0xb3, 0x04, 0x15, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc},
- {0xb3, 0x23, 0xe8, 0xcc}, {0xb8, 0x08, 0xe8, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x34, 0x01, 0xcc},
- {0xb3, 0x35, 0xf6, 0xcc}, /* i2c add: 76 */
- {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0x71, 0xcc},
- {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc},
- {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc},
- {0xb8, 0x2c, 0x50, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc},
- {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc},
- {0xb8, 0x30, 0x50, 0xcc}, {0xb8, 0x31, 0xf8, 0xcc},
- {0xb8, 0x32, 0xf8, 0xcc}, {0xb8, 0x33, 0xf8, 0xcc},
- {0xb8, 0x34, 0x50, 0xcc}, {0xb8, 0x35, 0x00, 0xcc},
- {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc},
- {0x00, 0x1e, 0xc6, 0xaa}, {0x00, 0x20, 0x44, 0xaa},
- {0x00, 0xad, 0x02, 0xaa}, {0x00, 0xae, 0x2c, 0xaa},
- {0x00, 0x12, 0x08, 0xaa}, {0x00, 0x17, 0x41, 0xaa},
- {0x00, 0x19, 0x41, 0xaa}, {0x00, 0x1e, 0x06, 0xaa},
- {0x00, 0x21, 0x00, 0xaa}, {0x00, 0x36, 0xc0, 0xaa},
- {0x00, 0x37, 0xc8, 0xaa}, {0x00, 0x3b, 0x36, 0xaa},
- {0x00, 0x4b, 0xfe, 0xaa}, {0x00, 0x51, 0x1c, 0xaa},
- {0x00, 0x52, 0x01, 0xaa}, {0x00, 0x55, 0x0a, 0xaa},
- {0x00, 0x59, 0x02, 0xaa}, {0x00, 0x5a, 0x04, 0xaa},
- {0x00, 0x5c, 0x10, 0xaa}, {0x00, 0x5d, 0x10, 0xaa},
- {0x00, 0x5e, 0x10, 0xaa}, {0x00, 0x5f, 0x10, 0xaa},
- {0x00, 0x61, 0x00, 0xaa}, {0x00, 0x62, 0x18, 0xaa},
- {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x70, 0x68, 0xaa},
- {0x00, 0x80, 0x71, 0xaa}, {0x00, 0x81, 0x08, 0xaa},
- {0x00, 0x82, 0x00, 0xaa}, {0x00, 0x83, 0x55, 0xaa},
- {0x00, 0x84, 0x06, 0xaa}, {0x00, 0x85, 0x06, 0xaa},
- {0x00, 0x86, 0x13, 0xaa}, {0x00, 0x87, 0x18, 0xaa},
- {0x00, 0xaa, 0x3f, 0xaa}, {0x00, 0xab, 0x44, 0xaa},
- {0x00, 0xb0, 0x68, 0xaa}, {0x00, 0xb5, 0x10, 0xaa},
- {0x00, 0xb8, 0x20, 0xaa}, {0x00, 0xb9, 0xa0, 0xaa},
- {0x00, 0xbc, 0x04, 0xaa}, {0x00, 0x8b, 0x40, 0xaa},
- {0x00, 0x8c, 0x91, 0xaa}, {0x00, 0x8d, 0x8f, 0xaa},
- {0x00, 0x8e, 0x91, 0xaa}, {0x00, 0x8f, 0x43, 0xaa},
- {0x00, 0x90, 0x92, 0xaa}, {0x00, 0x91, 0x89, 0xaa},
- {0x00, 0x92, 0x9d, 0xaa}, {0x00, 0x93, 0x46, 0xaa},
- {0x00, 0xd6, 0x22, 0xaa}, {0x00, 0x73, 0x00, 0xaa},
- {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa},
- {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa},
- {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa},
- {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa},
- {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa},
- {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0xd6, 0x62, 0xaa},
- {0x00, 0x73, 0x00, 0xaa}, {0x00, 0x74, 0x10, 0xaa},
- {0x00, 0x75, 0x20, 0xaa}, {0x00, 0x76, 0x2b, 0xaa},
- {0x00, 0x77, 0x36, 0xaa}, {0x00, 0x78, 0x49, 0xaa},
- {0x00, 0x79, 0x5a, 0xaa}, {0x00, 0x7a, 0x7f, 0xaa},
- {0x00, 0x7b, 0x9b, 0xaa}, {0x00, 0x7c, 0xba, 0xaa},
- {0x00, 0x7d, 0xd4, 0xaa}, {0x00, 0x7e, 0xea, 0xaa},
- {0x00, 0xd6, 0xa2, 0xaa}, {0x00, 0x73, 0x00, 0xaa},
- {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa},
- {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa},
- {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa},
- {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa},
- {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa},
- {0x00, 0x7e, 0xea, 0xaa},
- {0x00, 0x4c, 0x07, 0xaa},
- {0x00, 0x4b, 0xe0, 0xaa}, {0x00, 0x4e, 0x77, 0xaa},
- {0x00, 0x59, 0x02, 0xaa}, {0x00, 0x4d, 0x0a, 0xaa},
-/* {0x00, 0xd1, 0x00, 0xaa}, {0x00, 0x20, 0xc4, 0xaa},
- {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, */
- {0x00, 0xd1, 0x3c, 0xaa}, {0x00, 0x20, 0xc4, 0xaa},
- {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc},
- {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc},
- {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc},
- {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc},
- {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc},
- {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc},
- {0xb9, 0x08, 0x3c, 0xcc}, {0x00, 0x05, 0x00, 0xaa},
- {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc},
- {}
-};
-static const u8 po3130_rundata[][4] = {
- {0x00, 0x47, 0x45, 0xaa}, {0x00, 0x48, 0x9b, 0xaa},
- {0x00, 0x49, 0x3a, 0xaa}, {0x00, 0x4a, 0x01, 0xaa},
- {0x00, 0x44, 0x40, 0xaa},
-/* {0x00, 0xd5, 0x7c, 0xaa}, */
- {0x00, 0xad, 0x04, 0xaa}, {0x00, 0xae, 0x00, 0xaa},
- {0x00, 0xb0, 0x78, 0xaa}, {0x00, 0x98, 0x02, 0xaa},
- {0x00, 0x94, 0x25, 0xaa}, {0x00, 0x95, 0x25, 0xaa},
- {0x00, 0x59, 0x68, 0xaa}, {0x00, 0x44, 0x20, 0xaa},
- {0x00, 0x17, 0x50, 0xaa}, {0x00, 0x19, 0x50, 0xaa},
- {0x00, 0xd1, 0x3c, 0xaa}, {0x00, 0xd1, 0x3c, 0xaa},
- {0x00, 0x1e, 0x06, 0xaa}, {0x00, 0x1e, 0x06, 0xaa},
- {}
-};
-
-static const u8 po3130_initQVGA_data[][4] = {
- {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
- {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x09, 0xcc},
- {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc},
- {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x03, 0x1a, 0xcc},
- {0xb3, 0x04, 0x15, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc},
- {0xb3, 0x23, 0xe0, 0xcc}, {0xb8, 0x08, 0xe0, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0xf6, 0xcc},
- {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc},
- {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc},
- {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc},
- {0xb8, 0x2c, 0x50, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc},
- {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc},
- {0xb8, 0x30, 0x50, 0xcc}, {0xb8, 0x31, 0xf8, 0xcc},
- {0xb8, 0x32, 0xf8, 0xcc}, {0xb8, 0x33, 0xf8, 0xcc},
- {0xb8, 0x34, 0x50, 0xcc}, {0xb8, 0x35, 0x00, 0xcc},
- {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc},
- {0x00, 0x1e, 0xc6, 0xaa}, {0x00, 0x20, 0x44, 0xaa},
- {0x00, 0xad, 0x02, 0xaa}, {0x00, 0xae, 0x2c, 0xaa},
- {0x00, 0x12, 0x08, 0xaa}, {0x00, 0x17, 0x41, 0xaa},
- {0x00, 0x19, 0x41, 0xaa}, {0x00, 0x1e, 0x06, 0xaa},
- {0x00, 0x21, 0x00, 0xaa}, {0x00, 0x36, 0xc0, 0xaa},
- {0x00, 0x37, 0xc8, 0xaa}, {0x00, 0x3b, 0x36, 0xaa},
- {0x00, 0x4b, 0xfe, 0xaa}, {0x00, 0x51, 0x1c, 0xaa},
- {0x00, 0x52, 0x01, 0xaa}, {0x00, 0x55, 0x0a, 0xaa},
- {0x00, 0x59, 0x6f, 0xaa}, {0x00, 0x5a, 0x04, 0xaa},
- {0x00, 0x5c, 0x10, 0xaa}, {0x00, 0x5d, 0x10, 0xaa},
- {0x00, 0x5e, 0x10, 0xaa}, {0x00, 0x5f, 0x10, 0xaa},
- {0x00, 0x61, 0x00, 0xaa}, {0x00, 0x62, 0x18, 0xaa},
- {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x70, 0x68, 0xaa},
- {0x00, 0x80, 0x71, 0xaa}, {0x00, 0x81, 0x08, 0xaa},
- {0x00, 0x82, 0x00, 0xaa}, {0x00, 0x83, 0x55, 0xaa},
- {0x00, 0x84, 0x06, 0xaa}, {0x00, 0x85, 0x06, 0xaa},
- {0x00, 0x86, 0x13, 0xaa}, {0x00, 0x87, 0x18, 0xaa},
- {0x00, 0xaa, 0x3f, 0xaa}, {0x00, 0xab, 0x44, 0xaa},
- {0x00, 0xb0, 0x68, 0xaa}, {0x00, 0xb5, 0x10, 0xaa},
- {0x00, 0xb8, 0x20, 0xaa}, {0x00, 0xb9, 0xa0, 0xaa},
- {0x00, 0xbc, 0x04, 0xaa}, {0x00, 0x8b, 0x40, 0xaa},
- {0x00, 0x8c, 0x91, 0xaa}, {0x00, 0x8d, 0x8f, 0xaa},
- {0x00, 0x8e, 0x91, 0xaa}, {0x00, 0x8f, 0x43, 0xaa},
- {0x00, 0x90, 0x92, 0xaa}, {0x00, 0x91, 0x89, 0xaa},
- {0x00, 0x92, 0x9d, 0xaa}, {0x00, 0x93, 0x46, 0xaa},
- {0x00, 0xd6, 0x22, 0xaa}, {0x00, 0x73, 0x00, 0xaa},
- {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa},
- {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa},
- {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa},
- {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa},
- {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa},
- {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0xd6, 0x62, 0xaa},
- {0x00, 0x73, 0x00, 0xaa}, {0x00, 0x74, 0x10, 0xaa},
- {0x00, 0x75, 0x20, 0xaa}, {0x00, 0x76, 0x2b, 0xaa},
- {0x00, 0x77, 0x36, 0xaa}, {0x00, 0x78, 0x49, 0xaa},
- {0x00, 0x79, 0x5a, 0xaa}, {0x00, 0x7a, 0x7f, 0xaa},
- {0x00, 0x7b, 0x9b, 0xaa}, {0x00, 0x7c, 0xba, 0xaa},
- {0x00, 0x7d, 0xd4, 0xaa}, {0x00, 0x7e, 0xea, 0xaa},
- {0x00, 0xd6, 0xa2, 0xaa}, {0x00, 0x73, 0x00, 0xaa},
- {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa},
- {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa},
- {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa},
- {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa},
- {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa},
- {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0x4c, 0x07, 0xaa},
- {0x00, 0x4b, 0xe0, 0xaa}, {0x00, 0x4e, 0x77, 0xaa},
- {0x00, 0x59, 0x66, 0xaa}, {0x00, 0x4d, 0x0a, 0xaa},
- {0x00, 0xd1, 0x00, 0xaa}, {0x00, 0x20, 0xc4, 0xaa},
- {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc},
- {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc},
- {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc},
- {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc},
- {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc},
- {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc},
- {0xb9, 0x08, 0x3c, 0xcc}, {0xbc, 0x02, 0x18, 0xcc},
- {0xbc, 0x03, 0x50, 0xcc}, {0xbc, 0x04, 0x18, 0xcc},
- {0xbc, 0x05, 0x00, 0xcc}, {0xbc, 0x06, 0x00, 0xcc},
- {0xbc, 0x08, 0x30, 0xcc}, {0xbc, 0x09, 0x40, 0xcc},
- {0xbc, 0x0a, 0x10, 0xcc}, {0xbc, 0x0b, 0x00, 0xcc},
- {0xbc, 0x0c, 0x00, 0xcc}, {0x00, 0x05, 0x00, 0xaa},
- {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc},
- {}
-};
-
-static const u8 hv7131r_gamma[17] = {
- 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
- 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
-};
-static const u8 hv7131r_matrix[9] = {
- 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63
-};
-static const u8 hv7131r_initVGA_data[][4] = {
- {0xb3, 0x01, 0x01, 0xcc},
- {0xb0, 0x03, 0x19, 0xcc},
- {0xb0, 0x04, 0x02, 0xcc},
- {0x00, 0x00, 0x20, 0xdd},
- {0xb3, 0x00, 0x24, 0xcc},
- {0xb3, 0x00, 0x25, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x05, 0x01, 0xcc},
- {0xb3, 0x06, 0x03, 0xcc},
- {0xb3, 0x01, 0x45, 0xcc},
- {0xb3, 0x03, 0x0b, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x01, 0xcc},
- {0xb3, 0x23, 0xe0, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x02, 0xcc},
- {0xb3, 0x16, 0x02, 0xcc},
- {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x34, 0x01, 0xcc},
- {0xb3, 0x35, 0x91, 0xcc}, /* i2c add: 11 */
- {0xb3, 0x00, 0x27, 0xcc},
- {0xbc, 0x00, 0x73, 0xcc},
- {0xb8, 0x00, 0x23, 0xcc},
- {0xb8, 0x2c, 0x50, 0xcc},
- {0xb8, 0x2d, 0xf8, 0xcc},
- {0xb8, 0x2e, 0xf8, 0xcc},
- {0xb8, 0x2f, 0xf8, 0xcc},
- {0xb8, 0x30, 0x50, 0xcc},
- {0xb8, 0x31, 0xf8, 0xcc},
- {0xb8, 0x32, 0xf8, 0xcc},
- {0xb8, 0x33, 0xf8, 0xcc},
- {0xb8, 0x34, 0x58, 0xcc},
- {0xb8, 0x35, 0x00, 0xcc},
- {0xb8, 0x36, 0x00, 0xcc},
- {0xb8, 0x37, 0x00, 0xcc},
- {0xb8, 0x27, 0x20, 0xcc},
- {0xb8, 0x01, 0x7d, 0xcc},
- {0xb8, 0x81, 0x09, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc},
- {0xb8, 0x8e, 0x00, 0xcc},
- {0xb8, 0x8f, 0xff, 0xcc},
- {0x00, 0x01, 0x0c, 0xaa},
- {0x00, 0x14, 0x01, 0xaa},
- {0x00, 0x15, 0xe6, 0xaa},
- {0x00, 0x16, 0x02, 0xaa},
- {0x00, 0x17, 0x86, 0xaa},
- {0x00, 0x23, 0x00, 0xaa},
- {0x00, 0x25, 0x03, 0xaa},
- {0x00, 0x26, 0xa9, 0xaa},
- {0x00, 0x27, 0x80, 0xaa},
- {0x00, 0x30, 0x18, 0xaa},
- {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x02, 0xcc},
- {0xb6, 0x02, 0x80, 0xcc},
- {0xb6, 0x05, 0x01, 0xcc},
- {0xb6, 0x04, 0xe0, 0xcc},
- {0xb6, 0x12, 0x78, 0xcc},
- {0xb6, 0x18, 0x02, 0xcc},
- {0xb6, 0x17, 0x58, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc},
- {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc},
- {0xb3, 0x02, 0x02, 0xcc},
- {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc},
- {0xbf, 0xcc, 0x10, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x13, 0x13, 0xcc},
- {0xb9, 0x12, 0x00, 0xcc},
- {0xb9, 0x13, 0x0a, 0xcc},
- {0xb9, 0x14, 0x0a, 0xcc},
- {0xb9, 0x15, 0x0a, 0xcc},
- {0xb9, 0x16, 0x0a, 0xcc},
- {0xb8, 0x0c, 0x20, 0xcc},
- {0xb8, 0x0d, 0x70, 0xcc},
- {0xb9, 0x18, 0x00, 0xcc},
- {0xb9, 0x19, 0x0f, 0xcc},
- {0xb9, 0x1a, 0x0f, 0xcc},
- {0xb9, 0x1b, 0x0f, 0xcc},
- {0xb9, 0x1c, 0x0f, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {}
-};
-
-static const u8 hv7131r_initQVGA_data[][4] = {
- {0xb3, 0x01, 0x01, 0xcc},
- {0xb0, 0x03, 0x19, 0xcc},
- {0xb0, 0x04, 0x02, 0xcc},
- {0x00, 0x00, 0x20, 0xdd},
- {0xb3, 0x00, 0x24, 0xcc},
- {0xb3, 0x00, 0x25, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x05, 0x01, 0xcc},
- {0xb3, 0x06, 0x03, 0xcc},
- {0xb3, 0x01, 0x45, 0xcc},
- {0xb3, 0x03, 0x0b, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x01, 0xcc},
- {0xb3, 0x23, 0xe0, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x02, 0xcc},
- {0xb3, 0x16, 0x02, 0xcc},
- {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x34, 0x01, 0xcc},
- {0xb3, 0x35, 0x91, 0xcc},
- {0xb3, 0x00, 0x27, 0xcc},
- {0xbc, 0x00, 0xd3, 0xcc},
- {0xb8, 0x00, 0x23, 0xcc},
- {0xb8, 0x2c, 0x50, 0xcc},
- {0xb8, 0x2d, 0xf8, 0xcc},
- {0xb8, 0x2e, 0xf8, 0xcc},
- {0xb8, 0x2f, 0xf8, 0xcc},
- {0xb8, 0x30, 0x50, 0xcc},
- {0xb8, 0x31, 0xf8, 0xcc},
- {0xb8, 0x32, 0xf8, 0xcc},
- {0xb8, 0x33, 0xf8, 0xcc},
- {0xb8, 0x34, 0x58, 0xcc},
- {0xb8, 0x35, 0x00, 0xcc},
- {0xb8, 0x36, 0x00, 0xcc},
- {0xb8, 0x37, 0x00, 0xcc},
- {0xb8, 0x27, 0x20, 0xcc},
- {0xb8, 0x01, 0x7d, 0xcc},
- {0xb8, 0x81, 0x09, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc},
- {0xb8, 0x8e, 0x00, 0xcc},
- {0xb8, 0x8f, 0xff, 0xcc},
- {0x00, 0x01, 0x0c, 0xaa},
- {0x00, 0x14, 0x01, 0xaa},
- {0x00, 0x15, 0xe6, 0xaa},
- {0x00, 0x16, 0x02, 0xaa},
- {0x00, 0x17, 0x86, 0xaa},
- {0x00, 0x23, 0x00, 0xaa},
- {0x00, 0x25, 0x03, 0xaa},
- {0x00, 0x26, 0xa9, 0xaa},
- {0x00, 0x27, 0x80, 0xaa},
- {0x00, 0x30, 0x18, 0xaa},
- {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x01, 0xcc},
- {0xb6, 0x02, 0x40, 0xcc},
- {0xb6, 0x05, 0x00, 0xcc},
- {0xb6, 0x04, 0xf0, 0xcc},
- {0xb6, 0x12, 0x78, 0xcc},
- {0xb6, 0x18, 0x00, 0xcc},
- {0xb6, 0x17, 0x96, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc},
- {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc},
- {0xb3, 0x02, 0x02, 0xcc},
- {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc},
- {0xbf, 0xcc, 0x10, 0xcc},
- {0xbc, 0x02, 0x18, 0xcc},
- {0xbc, 0x03, 0x50, 0xcc},
- {0xbc, 0x04, 0x18, 0xcc},
- {0xbc, 0x05, 0x00, 0xcc},
- {0xbc, 0x06, 0x00, 0xcc},
- {0xbc, 0x08, 0x30, 0xcc},
- {0xbc, 0x09, 0x40, 0xcc},
- {0xbc, 0x0a, 0x10, 0xcc},
- {0xbc, 0x0b, 0x00, 0xcc},
- {0xbc, 0x0c, 0x00, 0xcc},
- {0xb9, 0x12, 0x00, 0xcc},
- {0xb9, 0x13, 0x0a, 0xcc},
- {0xb9, 0x14, 0x0a, 0xcc},
- {0xb9, 0x15, 0x0a, 0xcc},
- {0xb9, 0x16, 0x0a, 0xcc},
- {0xb9, 0x18, 0x00, 0xcc},
- {0xb9, 0x19, 0x0f, 0xcc},
- {0xb8, 0x0c, 0x20, 0xcc},
- {0xb8, 0x0d, 0x70, 0xcc},
- {0xb9, 0x1a, 0x0f, 0xcc},
- {0xb9, 0x1b, 0x0f, 0xcc},
- {0xb9, 0x1c, 0x0f, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x13, 0x13, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {}
-};
-
-static const u8 ov7660_gamma[17] = {
- 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
- 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
-};
-static const u8 ov7660_matrix[9] = {
- 0x5a, 0xf0, 0xf6, 0xf3, 0x57, 0xf6, 0xf3, 0xef, 0x62
-};
-static const u8 ov7660_initVGA_data[][4] = {
- {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
- {0x00, 0x00, 0x50, 0xdd},
- {0xb0, 0x03, 0x01, 0xcc},
- {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc},
- {0xb3, 0x05, 0x01, 0xcc},
- {0xb3, 0x06, 0x03, 0xcc},
- {0xb3, 0x03, 0x1f, 0xcc}, {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},/* 0xb315 <-0 href startl */
- {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc},
- {0xb3, 0x1f, 0x02, 0xcc},
- {0xb3, 0x34, 0x01, 0xcc},
- {0xb3, 0x35, 0xa1, 0xcc}, /* i2c add: 21 */
- {0xb3, 0x00, 0x26, 0xcc},
- {0xb8, 0x00, 0x33, 0xcc}, /* 13 */
- {0xb8, 0x01, 0x7d, 0xcc},
- {0xbc, 0x00, 0x73, 0xcc}, {0xb8, 0x81, 0x09, 0xcc},
- {0xb8, 0x27, 0x20, 0xcc},
- {0xb8, 0x8f, 0x50, 0xcc},
- {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa},
- {0x00, 0x12, 0x80, 0xaa},
- {0x00, 0x12, 0x05, 0xaa},
- {0x00, 0x1e, 0x01, 0xaa}, /* MVFP */
- {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */
- {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */
- {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa},
- {0x00, 0x13, 0xa7, 0xaa},
- {0x00, 0x40, 0xc1, 0xaa}, {0x00, 0x35, 0x00, 0xaa},
- {0x00, 0x36, 0x00, 0xaa},
- {0x00, 0x3c, 0x68, 0xaa}, {0x00, 0x1b, 0x05, 0xaa},
- {0x00, 0x39, 0x43, 0xaa},
- {0x00, 0x8d, 0xcf, 0xaa},
- {0x00, 0x8b, 0xcc, 0xaa}, {0x00, 0x8c, 0xcc, 0xaa},
- {0x00, 0x0f, 0x62, 0xaa},
- {0x00, 0x35, 0x84, 0xaa},
- {0x00, 0x3b, 0x08, 0xaa}, /* 0 * Nightframe 1/4 + 50Hz -> 0xC8 */
- {0x00, 0x3a, 0x00, 0xaa}, /* mx change yuyv format 00, 04, 01; 08, 0c*/
- {0x00, 0x14, 0x2a, 0xaa}, /* agc ampli */
- {0x00, 0x9e, 0x40, 0xaa}, {0xb8, 0x8f, 0x50, 0xcc},
- {0x00, 0x01, 0x80, 0xaa},
- {0x00, 0x02, 0x80, 0xaa},
- {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc},
- {0xb9, 0x00, 0x28, 0xcc},
- {0xb9, 0x01, 0x28, 0xcc}, {0xb9, 0x02, 0x28, 0xcc},
- {0xb9, 0x03, 0x00, 0xcc},
- {0xb9, 0x04, 0x00, 0xcc},
- {0xb9, 0x05, 0x3c, 0xcc}, {0xb9, 0x06, 0x3c, 0xcc},
- {0xb9, 0x07, 0x3c, 0xcc},
- {0xb9, 0x08, 0x3c, 0xcc},
-
- {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc},
-
- {0x00, 0x29, 0x3c, 0xaa}, {0xb3, 0x01, 0x45, 0xcc},
- {}
-};
-static const u8 ov7660_initQVGA_data[][4] = {
- {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
- {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc},
- {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc},
- {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x03, 0xcc},
- {0xb3, 0x03, 0x1f, 0xcc}, {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x01, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},/* 0xb315 <-0 href startl */
- {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc},
- {0xb3, 0x1f, 0x02, 0xcc}, {0xb3, 0x34, 0x01, 0xcc},
- {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x00, 0x26, 0xcc},
- {0xb8, 0x00, 0x33, 0xcc}, /* 13 */
- {0xb8, 0x01, 0x7d, 0xcc},
-/* sizer */
- {0xbc, 0x00, 0xd3, 0xcc},
- {0xb8, 0x81, 0x09, 0xcc}, {0xb8, 0x81, 0x09, 0xcc},
- {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x8f, 0x50, 0xcc},
- {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa},
- {0x00, 0x12, 0x80, 0xaa}, {0x00, 0x12, 0x05, 0xaa},
- {0x00, 0x1e, 0x01, 0xaa}, /* MVFP */
- {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */
- {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */
- {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa},
- {0x00, 0x13, 0xa7, 0xaa},
- {0x00, 0x40, 0xc1, 0xaa}, {0x00, 0x35, 0x00, 0xaa},
- {0x00, 0x36, 0x00, 0xaa},
- {0x00, 0x3c, 0x68, 0xaa}, {0x00, 0x1b, 0x05, 0xaa},
- {0x00, 0x39, 0x43, 0xaa}, {0x00, 0x8d, 0xcf, 0xaa},
- {0x00, 0x8b, 0xcc, 0xaa}, {0x00, 0x8c, 0xcc, 0xaa},
- {0x00, 0x0f, 0x62, 0xaa}, {0x00, 0x35, 0x84, 0xaa},
- {0x00, 0x3b, 0x08, 0xaa}, /* 0 * Nightframe 1/4 + 50Hz -> 0xC8 */
- {0x00, 0x3a, 0x00, 0xaa}, /* mx change yuyv format 00, 04, 01; 08, 0c*/
- {0x00, 0x14, 0x2a, 0xaa}, /* agc ampli */
- {0x00, 0x9e, 0x40, 0xaa}, {0xb8, 0x8f, 0x50, 0xcc},
- {0x00, 0x01, 0x80, 0xaa},
- {0x00, 0x02, 0x80, 0xaa},
-/* sizer filters */
- {0xbc, 0x02, 0x08, 0xcc},
- {0xbc, 0x03, 0x70, 0xcc},
- {0xb8, 0x35, 0x00, 0xcc},
- {0xb8, 0x36, 0x00, 0xcc},
- {0xb8, 0x37, 0x00, 0xcc},
- {0xbc, 0x04, 0x08, 0xcc},
- {0xbc, 0x05, 0x00, 0xcc},
- {0xbc, 0x06, 0x00, 0xcc},
- {0xbc, 0x08, 0x3c, 0xcc},
- {0xbc, 0x09, 0x40, 0xcc},
- {0xbc, 0x0a, 0x04, 0xcc},
- {0xbc, 0x0b, 0x00, 0xcc},
- {0xbc, 0x0c, 0x00, 0xcc},
-/* */
- {0xb8, 0xfe, 0x00, 0xcc},
- {0xb8, 0xff, 0x28, 0xcc},
-/* */
- {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc},
- {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc},
- {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc},
- {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc},
- {0xb9, 0x08, 0x3c, 0xcc},
-/* */
- {0xb8, 0x8e, 0x00, 0xcc},
- {0xb8, 0x8f, 0xff, 0xcc}, /* ff */
- {0x00, 0x29, 0x3c, 0xaa},
- {0xb3, 0x01, 0x45, 0xcc}, /* 45 */
- {}
-};
-
-static const u8 ov7660_50HZ[][4] = {
- {0x00, 0x3b, 0x08, 0xaa},
- {0x00, 0x9d, 0x40, 0xaa},
- {0x00, 0x13, 0xa7, 0xaa},
- {}
-};
-
-static const u8 ov7660_60HZ[][4] = {
- {0x00, 0x3b, 0x00, 0xaa},
- {0x00, 0x9e, 0x40, 0xaa},
- {0x00, 0x13, 0xa7, 0xaa},
- {}
-};
-
-static const u8 ov7660_NoFliker[][4] = {
- {0x00, 0x13, 0x87, 0xaa},
- {}
-};
-
-static const u8 ov7670_InitVGA[][4] = {
- {0xb3, 0x01, 0x05, 0xcc},
- {0x00, 0x00, 0x30, 0xdd},
- {0xb0, 0x03, 0x19, 0xcc},
- {0x00, 0x00, 0x10, 0xdd},
- {0xb0, 0x04, 0x02, 0xcc},
- {0x00, 0x00, 0x10, 0xdd},
- {0xb3, 0x00, 0x66, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb0, 0x16, 0x01, 0xcc},
- {0xb3, 0x35, 0xa1, 0xcc}, /* i2c add: 21 */
- {0xb3, 0x34, 0x01, 0xcc},
- {0xb3, 0x05, 0x01, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x02, 0x02, 0xcc},
- {0xb3, 0x03, 0x1f, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x02, 0xcc},
- {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x01, 0xcc},
- {0xb3, 0x23, 0xe0, 0xcc},
- {0xbc, 0x00, 0x41, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0x00, 0x12, 0x80, 0xaa},
- {0x00, 0x00, 0x20, 0xdd},
- {0x00, 0x12, 0x00, 0xaa},
- {0x00, 0x11, 0x40, 0xaa},
- {0x00, 0x6b, 0x0a, 0xaa},
- {0x00, 0x3a, 0x04, 0xaa},
- {0x00, 0x40, 0xc0, 0xaa},
- {0x00, 0x8c, 0x00, 0xaa},
- {0x00, 0x7a, 0x29, 0xaa},
- {0x00, 0x7b, 0x0e, 0xaa},
- {0x00, 0x7c, 0x1a, 0xaa},
- {0x00, 0x7d, 0x31, 0xaa},
- {0x00, 0x7e, 0x53, 0xaa},
- {0x00, 0x7f, 0x60, 0xaa},
- {0x00, 0x80, 0x6b, 0xaa},
- {0x00, 0x81, 0x73, 0xaa},
- {0x00, 0x82, 0x7b, 0xaa},
- {0x00, 0x83, 0x82, 0xaa},
- {0x00, 0x84, 0x89, 0xaa},
- {0x00, 0x85, 0x96, 0xaa},
- {0x00, 0x86, 0xa1, 0xaa},
- {0x00, 0x87, 0xb7, 0xaa},
- {0x00, 0x88, 0xcc, 0xaa},
- {0x00, 0x89, 0xe1, 0xaa},
- {0x00, 0x13, 0xe0, 0xaa},
- {0x00, 0x00, 0x00, 0xaa},
- {0x00, 0x10, 0x00, 0xaa},
- {0x00, 0x0d, 0x40, 0xaa},
- {0x00, 0x14, 0x28, 0xaa},
- {0x00, 0xa5, 0x05, 0xaa},
- {0x00, 0xab, 0x07, 0xaa},
- {0x00, 0x24, 0x95, 0xaa},
- {0x00, 0x25, 0x33, 0xaa},
- {0x00, 0x26, 0xe3, 0xaa},
- {0x00, 0x9f, 0x88, 0xaa},
- {0x00, 0xa0, 0x78, 0xaa},
- {0x00, 0x55, 0x90, 0xaa},
- {0x00, 0xa1, 0x03, 0xaa},
- {0x00, 0xa6, 0xe0, 0xaa},
- {0x00, 0xa7, 0xd8, 0xaa},
- {0x00, 0xa8, 0xf0, 0xaa},
- {0x00, 0xa9, 0x90, 0xaa},
- {0x00, 0xaa, 0x14, 0xaa},
- {0x00, 0x13, 0xe5, 0xaa},
- {0x00, 0x0e, 0x61, 0xaa},
- {0x00, 0x0f, 0x4b, 0xaa},
- {0x00, 0x16, 0x02, 0xaa},
- {0x00, 0x1e, 0x07, 0xaa}, /* MVFP */
- {0x00, 0x21, 0x02, 0xaa},
- {0x00, 0x22, 0x91, 0xaa},
- {0x00, 0x29, 0x07, 0xaa},
- {0x00, 0x33, 0x0b, 0xaa},
- {0x00, 0x35, 0x0b, 0xaa},
- {0x00, 0x37, 0x1d, 0xaa},
- {0x00, 0x38, 0x71, 0xaa},
- {0x00, 0x39, 0x2a, 0xaa},
- {0x00, 0x3c, 0x78, 0xaa},
- {0x00, 0x4d, 0x40, 0xaa},
- {0x00, 0x4e, 0x20, 0xaa},
- {0x00, 0x74, 0x19, 0xaa},
- {0x00, 0x8d, 0x4f, 0xaa},
- {0x00, 0x8e, 0x00, 0xaa},
- {0x00, 0x8f, 0x00, 0xaa},
- {0x00, 0x90, 0x00, 0xaa},
- {0x00, 0x91, 0x00, 0xaa},
- {0x00, 0x96, 0x00, 0xaa},
- {0x00, 0x9a, 0x80, 0xaa},
- {0x00, 0xb0, 0x84, 0xaa},
- {0x00, 0xb1, 0x0c, 0xaa},
- {0x00, 0xb2, 0x0e, 0xaa},
- {0x00, 0xb3, 0x82, 0xaa},
- {0x00, 0xb8, 0x0a, 0xaa},
- {0x00, 0x43, 0x14, 0xaa},
- {0x00, 0x44, 0xf0, 0xaa},
- {0x00, 0x45, 0x45, 0xaa},
- {0x00, 0x46, 0x63, 0xaa},
- {0x00, 0x47, 0x2d, 0xaa},
- {0x00, 0x48, 0x46, 0xaa},
- {0x00, 0x59, 0x88, 0xaa},
- {0x00, 0x5a, 0xa0, 0xaa},
- {0x00, 0x5b, 0xc6, 0xaa},
- {0x00, 0x5c, 0x7d, 0xaa},
- {0x00, 0x5d, 0x5f, 0xaa},
- {0x00, 0x5e, 0x19, 0xaa},
- {0x00, 0x6c, 0x0a, 0xaa},
- {0x00, 0x6d, 0x55, 0xaa},
- {0x00, 0x6e, 0x11, 0xaa},
- {0x00, 0x6f, 0x9e, 0xaa},
- {0x00, 0x69, 0x00, 0xaa},
- {0x00, 0x6a, 0x40, 0xaa},
- {0x00, 0x01, 0x40, 0xaa},
- {0x00, 0x02, 0x40, 0xaa},
- {0x00, 0x13, 0xe7, 0xaa},
- {0x00, 0x5f, 0xf0, 0xaa},
- {0x00, 0x60, 0xf0, 0xaa},
- {0x00, 0x61, 0xf0, 0xaa},
- {0x00, 0x27, 0xa0, 0xaa},
- {0x00, 0x28, 0x80, 0xaa},
- {0x00, 0x2c, 0x90, 0xaa},
- {0x00, 0x4f, 0x66, 0xaa},
- {0x00, 0x50, 0x66, 0xaa},
- {0x00, 0x51, 0x00, 0xaa},
- {0x00, 0x52, 0x22, 0xaa},
- {0x00, 0x53, 0x5e, 0xaa},
- {0x00, 0x54, 0x80, 0xaa},
- {0x00, 0x58, 0x9e, 0xaa},
- {0x00, 0x41, 0x08, 0xaa},
- {0x00, 0x3f, 0x00, 0xaa},
- {0x00, 0x75, 0x85, 0xaa},
- {0x00, 0x76, 0xe1, 0xaa},
- {0x00, 0x4c, 0x00, 0xaa},
- {0x00, 0x77, 0x0a, 0xaa},
- {0x00, 0x3d, 0x88, 0xaa},
- {0x00, 0x4b, 0x09, 0xaa},
- {0x00, 0xc9, 0x60, 0xaa},
- {0x00, 0x41, 0x38, 0xaa},
- {0x00, 0x62, 0x30, 0xaa},
- {0x00, 0x63, 0x30, 0xaa},
- {0x00, 0x64, 0x08, 0xaa},
- {0x00, 0x94, 0x07, 0xaa},
- {0x00, 0x95, 0x0b, 0xaa},
- {0x00, 0x65, 0x00, 0xaa},
- {0x00, 0x66, 0x05, 0xaa},
- {0x00, 0x56, 0x50, 0xaa},
- {0x00, 0x34, 0x11, 0xaa},
- {0x00, 0xa4, 0x88, 0xaa},
- {0x00, 0x96, 0x00, 0xaa},
- {0x00, 0x97, 0x30, 0xaa},
- {0x00, 0x98, 0x20, 0xaa},
- {0x00, 0x99, 0x30, 0xaa},
- {0x00, 0x9a, 0x84, 0xaa},
- {0x00, 0x9b, 0x29, 0xaa},
- {0x00, 0x9c, 0x03, 0xaa},
- {0x00, 0x78, 0x04, 0xaa},
- {0x00, 0x79, 0x01, 0xaa},
- {0x00, 0xc8, 0xf0, 0xaa},
- {0x00, 0x79, 0x0f, 0xaa},
- {0x00, 0xc8, 0x00, 0xaa},
- {0x00, 0x79, 0x10, 0xaa},
- {0x00, 0xc8, 0x7e, 0xaa},
- {0x00, 0x79, 0x0a, 0xaa},
- {0x00, 0xc8, 0x80, 0xaa},
- {0x00, 0x79, 0x0b, 0xaa},
- {0x00, 0xc8, 0x01, 0xaa},
- {0x00, 0x79, 0x0c, 0xaa},
- {0x00, 0xc8, 0x0f, 0xaa},
- {0x00, 0x79, 0x0d, 0xaa},
- {0x00, 0xc8, 0x20, 0xaa},
- {0x00, 0x79, 0x09, 0xaa},
- {0x00, 0xc8, 0x80, 0xaa},
- {0x00, 0x79, 0x02, 0xaa},
- {0x00, 0xc8, 0xc0, 0xaa},
- {0x00, 0x79, 0x03, 0xaa},
- {0x00, 0xc8, 0x40, 0xaa},
- {0x00, 0x79, 0x05, 0xaa},
- {0x00, 0xc8, 0x30, 0xaa},
- {0x00, 0x79, 0x26, 0xaa},
- {0x00, 0x11, 0x40, 0xaa},
- {0x00, 0x3a, 0x04, 0xaa},
- {0x00, 0x12, 0x00, 0xaa},
- {0x00, 0x40, 0xc0, 0xaa},
- {0x00, 0x8c, 0x00, 0xaa},
- {0x00, 0x17, 0x14, 0xaa},
- {0x00, 0x18, 0x02, 0xaa},
- {0x00, 0x32, 0x92, 0xaa},
- {0x00, 0x19, 0x02, 0xaa},
- {0x00, 0x1a, 0x7a, 0xaa},
- {0x00, 0x03, 0x0a, 0xaa},
- {0x00, 0x0c, 0x00, 0xaa},
- {0x00, 0x3e, 0x00, 0xaa},
- {0x00, 0x70, 0x3a, 0xaa},
- {0x00, 0x71, 0x35, 0xaa},
- {0x00, 0x72, 0x11, 0xaa},
- {0x00, 0x73, 0xf0, 0xaa},
- {0x00, 0xa2, 0x02, 0xaa},
- {0x00, 0xb1, 0x00, 0xaa},
- {0x00, 0xb1, 0x0c, 0xaa},
- {0x00, 0x1e, 0x37, 0xaa}, /* MVFP */
- {0x00, 0xaa, 0x14, 0xaa},
- {0x00, 0x24, 0x80, 0xaa},
- {0x00, 0x25, 0x74, 0xaa},
- {0x00, 0x26, 0xd3, 0xaa},
- {0x00, 0x0d, 0x00, 0xaa},
- {0x00, 0x14, 0x18, 0xaa},
- {0x00, 0x9d, 0x99, 0xaa},
- {0x00, 0x9e, 0x7f, 0xaa},
- {0x00, 0x64, 0x08, 0xaa},
- {0x00, 0x94, 0x07, 0xaa},
- {0x00, 0x95, 0x06, 0xaa},
- {0x00, 0x66, 0x05, 0xaa},
- {0x00, 0x41, 0x08, 0xaa},
- {0x00, 0x3f, 0x00, 0xaa},
- {0x00, 0x75, 0x07, 0xaa},
- {0x00, 0x76, 0xe1, 0xaa},
- {0x00, 0x4c, 0x00, 0xaa},
- {0x00, 0x77, 0x00, 0xaa},
- {0x00, 0x3d, 0xc2, 0xaa},
- {0x00, 0x4b, 0x09, 0xaa},
- {0x00, 0xc9, 0x60, 0xaa},
- {0x00, 0x41, 0x38, 0xaa},
- {0xbf, 0xc0, 0x26, 0xcc},
- {0xbf, 0xc1, 0x02, 0xcc},
- {0xbf, 0xcc, 0x04, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xb3, 0x01, 0x45, 0xcc},
- {0x00, 0x77, 0x05, 0xaa},
- {},
-};
-
-static const u8 ov7670_InitQVGA[][4] = {
- {0xb3, 0x01, 0x05, 0xcc},
- {0x00, 0x00, 0x30, 0xdd},
- {0xb0, 0x03, 0x19, 0xcc},
- {0x00, 0x00, 0x10, 0xdd},
- {0xb0, 0x04, 0x02, 0xcc},
- {0x00, 0x00, 0x10, 0xdd},
- {0xb3, 0x00, 0x66, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb0, 0x16, 0x01, 0xcc},
- {0xb3, 0x35, 0xa1, 0xcc}, /* i2c add: 21 */
- {0xb3, 0x34, 0x01, 0xcc},
- {0xb3, 0x05, 0x01, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x02, 0x02, 0xcc},
- {0xb3, 0x03, 0x1f, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x02, 0xcc},
- {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x01, 0xcc},
- {0xb3, 0x23, 0xe0, 0xcc},
- {0xbc, 0x00, 0xd1, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0x00, 0x12, 0x80, 0xaa},
- {0x00, 0x00, 0x20, 0xdd},
- {0x00, 0x12, 0x00, 0xaa},
- {0x00, 0x11, 0x40, 0xaa},
- {0x00, 0x6b, 0x0a, 0xaa},
- {0x00, 0x3a, 0x04, 0xaa},
- {0x00, 0x40, 0xc0, 0xaa},
- {0x00, 0x8c, 0x00, 0xaa},
- {0x00, 0x7a, 0x29, 0xaa},
- {0x00, 0x7b, 0x0e, 0xaa},
- {0x00, 0x7c, 0x1a, 0xaa},
- {0x00, 0x7d, 0x31, 0xaa},
- {0x00, 0x7e, 0x53, 0xaa},
- {0x00, 0x7f, 0x60, 0xaa},
- {0x00, 0x80, 0x6b, 0xaa},
- {0x00, 0x81, 0x73, 0xaa},
- {0x00, 0x82, 0x7b, 0xaa},
- {0x00, 0x83, 0x82, 0xaa},
- {0x00, 0x84, 0x89, 0xaa},
- {0x00, 0x85, 0x96, 0xaa},
- {0x00, 0x86, 0xa1, 0xaa},
- {0x00, 0x87, 0xb7, 0xaa},
- {0x00, 0x88, 0xcc, 0xaa},
- {0x00, 0x89, 0xe1, 0xaa},
- {0x00, 0x13, 0xe0, 0xaa},
- {0x00, 0x00, 0x00, 0xaa},
- {0x00, 0x10, 0x00, 0xaa},
- {0x00, 0x0d, 0x40, 0xaa},
- {0x00, 0x14, 0x28, 0xaa},
- {0x00, 0xa5, 0x05, 0xaa},
- {0x00, 0xab, 0x07, 0xaa},
- {0x00, 0x24, 0x95, 0xaa},
- {0x00, 0x25, 0x33, 0xaa},
- {0x00, 0x26, 0xe3, 0xaa},
- {0x00, 0x9f, 0x88, 0xaa},
- {0x00, 0xa0, 0x78, 0xaa},
- {0x00, 0x55, 0x90, 0xaa},
- {0x00, 0xa1, 0x03, 0xaa},
- {0x00, 0xa6, 0xe0, 0xaa},
- {0x00, 0xa7, 0xd8, 0xaa},
- {0x00, 0xa8, 0xf0, 0xaa},
- {0x00, 0xa9, 0x90, 0xaa},
- {0x00, 0xaa, 0x14, 0xaa},
- {0x00, 0x13, 0xe5, 0xaa},
- {0x00, 0x0e, 0x61, 0xaa},
- {0x00, 0x0f, 0x4b, 0xaa},
- {0x00, 0x16, 0x02, 0xaa},
- {0x00, 0x1e, 0x07, 0xaa}, /* MVFP */
- {0x00, 0x21, 0x02, 0xaa},
- {0x00, 0x22, 0x91, 0xaa},
- {0x00, 0x29, 0x07, 0xaa},
- {0x00, 0x33, 0x0b, 0xaa},
- {0x00, 0x35, 0x0b, 0xaa},
- {0x00, 0x37, 0x1d, 0xaa},
- {0x00, 0x38, 0x71, 0xaa},
- {0x00, 0x39, 0x2a, 0xaa},
- {0x00, 0x3c, 0x78, 0xaa},
- {0x00, 0x4d, 0x40, 0xaa},
- {0x00, 0x4e, 0x20, 0xaa},
- {0x00, 0x74, 0x19, 0xaa},
- {0x00, 0x8d, 0x4f, 0xaa},
- {0x00, 0x8e, 0x00, 0xaa},
- {0x00, 0x8f, 0x00, 0xaa},
- {0x00, 0x90, 0x00, 0xaa},
- {0x00, 0x91, 0x00, 0xaa},
- {0x00, 0x96, 0x00, 0xaa},
- {0x00, 0x9a, 0x80, 0xaa},
- {0x00, 0xb0, 0x84, 0xaa},
- {0x00, 0xb1, 0x0c, 0xaa},
- {0x00, 0xb2, 0x0e, 0xaa},
- {0x00, 0xb3, 0x82, 0xaa},
- {0x00, 0xb8, 0x0a, 0xaa},
- {0x00, 0x43, 0x14, 0xaa},
- {0x00, 0x44, 0xf0, 0xaa},
- {0x00, 0x45, 0x45, 0xaa},
- {0x00, 0x46, 0x63, 0xaa},
- {0x00, 0x47, 0x2d, 0xaa},
- {0x00, 0x48, 0x46, 0xaa},
- {0x00, 0x59, 0x88, 0xaa},
- {0x00, 0x5a, 0xa0, 0xaa},
- {0x00, 0x5b, 0xc6, 0xaa},
- {0x00, 0x5c, 0x7d, 0xaa},
- {0x00, 0x5d, 0x5f, 0xaa},
- {0x00, 0x5e, 0x19, 0xaa},
- {0x00, 0x6c, 0x0a, 0xaa},
- {0x00, 0x6d, 0x55, 0xaa},
- {0x00, 0x6e, 0x11, 0xaa},
- {0x00, 0x6f, 0x9e, 0xaa},
- {0x00, 0x69, 0x00, 0xaa},
- {0x00, 0x6a, 0x40, 0xaa},
- {0x00, 0x01, 0x40, 0xaa},
- {0x00, 0x02, 0x40, 0xaa},
- {0x00, 0x13, 0xe7, 0xaa},
- {0x00, 0x5f, 0xf0, 0xaa},
- {0x00, 0x60, 0xf0, 0xaa},
- {0x00, 0x61, 0xf0, 0xaa},
- {0x00, 0x27, 0xa0, 0xaa},
- {0x00, 0x28, 0x80, 0xaa},
- {0x00, 0x2c, 0x90, 0xaa},
- {0x00, 0x4f, 0x66, 0xaa},
- {0x00, 0x50, 0x66, 0xaa},
- {0x00, 0x51, 0x00, 0xaa},
- {0x00, 0x52, 0x22, 0xaa},
- {0x00, 0x53, 0x5e, 0xaa},
- {0x00, 0x54, 0x80, 0xaa},
- {0x00, 0x58, 0x9e, 0xaa},
- {0x00, 0x41, 0x08, 0xaa},
- {0x00, 0x3f, 0x00, 0xaa},
- {0x00, 0x75, 0x85, 0xaa},
- {0x00, 0x76, 0xe1, 0xaa},
- {0x00, 0x4c, 0x00, 0xaa},
- {0x00, 0x77, 0x0a, 0xaa},
- {0x00, 0x3d, 0x88, 0xaa},
- {0x00, 0x4b, 0x09, 0xaa},
- {0x00, 0xc9, 0x60, 0xaa},
- {0x00, 0x41, 0x38, 0xaa},
- {0x00, 0x62, 0x30, 0xaa},
- {0x00, 0x63, 0x30, 0xaa},
- {0x00, 0x64, 0x08, 0xaa},
- {0x00, 0x94, 0x07, 0xaa},
- {0x00, 0x95, 0x0b, 0xaa},
- {0x00, 0x65, 0x00, 0xaa},
- {0x00, 0x66, 0x05, 0xaa},
- {0x00, 0x56, 0x50, 0xaa},
- {0x00, 0x34, 0x11, 0xaa},
- {0x00, 0xa4, 0x88, 0xaa},
- {0x00, 0x96, 0x00, 0xaa},
- {0x00, 0x97, 0x30, 0xaa},
- {0x00, 0x98, 0x20, 0xaa},
- {0x00, 0x99, 0x30, 0xaa},
- {0x00, 0x9a, 0x84, 0xaa},
- {0x00, 0x9b, 0x29, 0xaa},
- {0x00, 0x9c, 0x03, 0xaa},
- {0x00, 0x78, 0x04, 0xaa},
- {0x00, 0x79, 0x01, 0xaa},
- {0x00, 0xc8, 0xf0, 0xaa},
- {0x00, 0x79, 0x0f, 0xaa},
- {0x00, 0xc8, 0x00, 0xaa},
- {0x00, 0x79, 0x10, 0xaa},
- {0x00, 0xc8, 0x7e, 0xaa},
- {0x00, 0x79, 0x0a, 0xaa},
- {0x00, 0xc8, 0x80, 0xaa},
- {0x00, 0x79, 0x0b, 0xaa},
- {0x00, 0xc8, 0x01, 0xaa},
- {0x00, 0x79, 0x0c, 0xaa},
- {0x00, 0xc8, 0x0f, 0xaa},
- {0x00, 0x79, 0x0d, 0xaa},
- {0x00, 0xc8, 0x20, 0xaa},
- {0x00, 0x79, 0x09, 0xaa},
- {0x00, 0xc8, 0x80, 0xaa},
- {0x00, 0x79, 0x02, 0xaa},
- {0x00, 0xc8, 0xc0, 0xaa},
- {0x00, 0x79, 0x03, 0xaa},
- {0x00, 0xc8, 0x40, 0xaa},
- {0x00, 0x79, 0x05, 0xaa},
- {0x00, 0xc8, 0x30, 0xaa},
- {0x00, 0x79, 0x26, 0xaa},
- {0x00, 0x11, 0x40, 0xaa},
- {0x00, 0x3a, 0x04, 0xaa},
- {0x00, 0x12, 0x00, 0xaa},
- {0x00, 0x40, 0xc0, 0xaa},
- {0x00, 0x8c, 0x00, 0xaa},
- {0x00, 0x17, 0x14, 0xaa},
- {0x00, 0x18, 0x02, 0xaa},
- {0x00, 0x32, 0x92, 0xaa},
- {0x00, 0x19, 0x02, 0xaa},
- {0x00, 0x1a, 0x7a, 0xaa},
- {0x00, 0x03, 0x0a, 0xaa},
- {0x00, 0x0c, 0x00, 0xaa},
- {0x00, 0x3e, 0x00, 0xaa},
- {0x00, 0x70, 0x3a, 0xaa},
- {0x00, 0x71, 0x35, 0xaa},
- {0x00, 0x72, 0x11, 0xaa},
- {0x00, 0x73, 0xf0, 0xaa},
- {0x00, 0xa2, 0x02, 0xaa},
- {0x00, 0xb1, 0x00, 0xaa},
- {0x00, 0xb1, 0x0c, 0xaa},
- {0x00, 0x1e, 0x37, 0xaa}, /* MVFP */
- {0x00, 0xaa, 0x14, 0xaa},
- {0x00, 0x24, 0x80, 0xaa},
- {0x00, 0x25, 0x74, 0xaa},
- {0x00, 0x26, 0xd3, 0xaa},
- {0x00, 0x0d, 0x00, 0xaa},
- {0x00, 0x14, 0x18, 0xaa},
- {0x00, 0x9d, 0x99, 0xaa},
- {0x00, 0x9e, 0x7f, 0xaa},
- {0x00, 0x64, 0x08, 0xaa},
- {0x00, 0x94, 0x07, 0xaa},
- {0x00, 0x95, 0x06, 0xaa},
- {0x00, 0x66, 0x05, 0xaa},
- {0x00, 0x41, 0x08, 0xaa},
- {0x00, 0x3f, 0x00, 0xaa},
- {0x00, 0x75, 0x07, 0xaa},
- {0x00, 0x76, 0xe1, 0xaa},
- {0x00, 0x4c, 0x00, 0xaa},
- {0x00, 0x77, 0x00, 0xaa},
- {0x00, 0x3d, 0xc2, 0xaa},
- {0x00, 0x4b, 0x09, 0xaa},
- {0x00, 0xc9, 0x60, 0xaa},
- {0x00, 0x41, 0x38, 0xaa},
- {0xbc, 0x02, 0x18, 0xcc},
- {0xbc, 0x03, 0x50, 0xcc},
- {0xbc, 0x04, 0x18, 0xcc},
- {0xbc, 0x05, 0x00, 0xcc},
- {0xbc, 0x06, 0x00, 0xcc},
- {0xbc, 0x08, 0x30, 0xcc},
- {0xbc, 0x09, 0x40, 0xcc},
- {0xbc, 0x0a, 0x10, 0xcc},
- {0xbc, 0x0b, 0x00, 0xcc},
- {0xbc, 0x0c, 0x00, 0xcc},
- {0xbf, 0xc0, 0x26, 0xcc},
- {0xbf, 0xc1, 0x02, 0xcc},
- {0xbf, 0xcc, 0x04, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xb3, 0x01, 0x45, 0xcc},
- {0x00, 0x77, 0x05, 0xaa},
- {},
-};
-
-/* PO1200 - values from usbvm326.inf and ms-win trace */
-static const u8 po1200_gamma[17] = {
- 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
- 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
-};
-static const u8 po1200_matrix[9] = {
- 0x60, 0xf9, 0xe5, 0xe7, 0x50, 0x05, 0xf3, 0xe6, 0x5e
-};
-static const u8 po1200_initVGA_data[][4] = {
- {0xb0, 0x03, 0x19, 0xcc}, /* reset? */
- {0xb0, 0x03, 0x19, 0xcc},
-/* {0x00, 0x00, 0x33, 0xdd}, */
- {0xb0, 0x04, 0x02, 0xcc},
- {0xb0, 0x02, 0x02, 0xcc},
- {0xb3, 0x5d, 0x00, 0xcc},
- {0xb3, 0x01, 0x01, 0xcc},
- {0xb3, 0x00, 0x64, 0xcc},
- {0xb3, 0x00, 0x65, 0xcc},
- {0xb3, 0x05, 0x01, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb3, 0x02, 0xb2, 0xcc},
- {0xb3, 0x03, 0x18, 0xcc},
- {0xb3, 0x04, 0x15, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x02, 0xcc},
- {0xb3, 0x23, 0x58, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x03, 0xcc},
- {0xb3, 0x17, 0x1f, 0xcc},
- {0xbc, 0x00, 0x71, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0xb0, 0x54, 0x13, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb3, 0x34, 0x01, 0xcc},
- {0xb3, 0x35, 0xdc, 0xcc}, /* i2c add: 5c */
- {0x00, 0x03, 0x00, 0xaa},
- {0x00, 0x12, 0x05, 0xaa},
- {0x00, 0x13, 0x02, 0xaa},
- {0x00, 0x1e, 0xc6, 0xaa}, /* h/v flip */
- {0x00, 0x21, 0x00, 0xaa},
- {0x00, 0x25, 0x02, 0xaa},
- {0x00, 0x3c, 0x4f, 0xaa},
- {0x00, 0x3f, 0xe0, 0xaa},
- {0x00, 0x42, 0xff, 0xaa},
- {0x00, 0x45, 0x34, 0xaa},
- {0x00, 0x55, 0xfe, 0xaa},
- {0x00, 0x59, 0xd3, 0xaa},
- {0x00, 0x5e, 0x04, 0xaa},
- {0x00, 0x61, 0xb8, 0xaa}, /* sharpness */
- {0x00, 0x62, 0x02, 0xaa},
- {0x00, 0xa7, 0x31, 0xaa},
- {0x00, 0xa9, 0x66, 0xaa},
- {0x00, 0xb0, 0x00, 0xaa},
- {0x00, 0xb1, 0x00, 0xaa},
- {0x00, 0xb3, 0x11, 0xaa},
- {0x00, 0xb6, 0x26, 0xaa},
- {0x00, 0xb7, 0x20, 0xaa},
- {0x00, 0xba, 0x04, 0xaa},
- {0x00, 0x88, 0x42, 0xaa},
- {0x00, 0x89, 0x9a, 0xaa},
- {0x00, 0x8a, 0x88, 0xaa},
- {0x00, 0x8b, 0x8e, 0xaa},
- {0x00, 0x8c, 0x3e, 0xaa},
- {0x00, 0x8d, 0x90, 0xaa},
- {0x00, 0x8e, 0x87, 0xaa},
- {0x00, 0x8f, 0x96, 0xaa},
- {0x00, 0x90, 0x3d, 0xaa},
- {0x00, 0x64, 0x00, 0xaa},
- {0x00, 0x65, 0x10, 0xaa},
- {0x00, 0x66, 0x20, 0xaa},
- {0x00, 0x67, 0x2b, 0xaa},
- {0x00, 0x68, 0x36, 0xaa},
- {0x00, 0x69, 0x49, 0xaa},
- {0x00, 0x6a, 0x5a, 0xaa},
- {0x00, 0x6b, 0x7f, 0xaa},
- {0x00, 0x6c, 0x9b, 0xaa},
- {0x00, 0x6d, 0xba, 0xaa},
- {0x00, 0x6e, 0xd4, 0xaa},
- {0x00, 0x6f, 0xea, 0xaa},
- {0x00, 0x70, 0x00, 0xaa},
- {0x00, 0x71, 0x10, 0xaa},
- {0x00, 0x72, 0x20, 0xaa},
- {0x00, 0x73, 0x2b, 0xaa},
- {0x00, 0x74, 0x36, 0xaa},
- {0x00, 0x75, 0x49, 0xaa},
- {0x00, 0x76, 0x5a, 0xaa},
- {0x00, 0x77, 0x7f, 0xaa},
- {0x00, 0x78, 0x9b, 0xaa},
- {0x00, 0x79, 0xba, 0xaa},
- {0x00, 0x7a, 0xd4, 0xaa},
- {0x00, 0x7b, 0xea, 0xaa},
- {0x00, 0x7c, 0x00, 0xaa},
- {0x00, 0x7d, 0x10, 0xaa},
- {0x00, 0x7e, 0x20, 0xaa},
- {0x00, 0x7f, 0x2b, 0xaa},
- {0x00, 0x80, 0x36, 0xaa},
- {0x00, 0x81, 0x49, 0xaa},
- {0x00, 0x82, 0x5a, 0xaa},
- {0x00, 0x83, 0x7f, 0xaa},
- {0x00, 0x84, 0x9b, 0xaa},
- {0x00, 0x85, 0xba, 0xaa},
- {0x00, 0x86, 0xd4, 0xaa},
- {0x00, 0x87, 0xea, 0xaa},
- {0x00, 0x57, 0x2a, 0xaa},
- {0x00, 0x03, 0x01, 0xaa},
- {0x00, 0x04, 0x10, 0xaa},
- {0x00, 0x05, 0x10, 0xaa},
- {0x00, 0x06, 0x10, 0xaa},
- {0x00, 0x07, 0x10, 0xaa},
- {0x00, 0x08, 0x13, 0xaa},
- {0x00, 0x0a, 0x00, 0xaa},
- {0x00, 0x0b, 0x10, 0xaa},
- {0x00, 0x0c, 0x20, 0xaa},
- {0x00, 0x0d, 0x18, 0xaa},
- {0x00, 0x22, 0x01, 0xaa},
- {0x00, 0x23, 0x60, 0xaa},
- {0x00, 0x25, 0x08, 0xaa},
- {0x00, 0x26, 0x82, 0xaa},
- {0x00, 0x2e, 0x0f, 0xaa},
- {0x00, 0x2f, 0x1e, 0xaa},
- {0x00, 0x30, 0x2d, 0xaa},
- {0x00, 0x31, 0x3c, 0xaa},
- {0x00, 0x32, 0x4b, 0xaa},
- {0x00, 0x33, 0x5a, 0xaa},
- {0x00, 0x34, 0x69, 0xaa},
- {0x00, 0x35, 0x78, 0xaa},
- {0x00, 0x36, 0x87, 0xaa},
- {0x00, 0x37, 0x96, 0xaa},
- {0x00, 0x38, 0xa5, 0xaa},
- {0x00, 0x39, 0xb4, 0xaa},
- {0x00, 0x3a, 0xc3, 0xaa},
- {0x00, 0x3b, 0xd2, 0xaa},
- {0x00, 0x3c, 0xe1, 0xaa},
- {0x00, 0x3e, 0xff, 0xaa},
- {0x00, 0x3f, 0xff, 0xaa},
- {0x00, 0x40, 0xff, 0xaa},
- {0x00, 0x41, 0xff, 0xaa},
- {0x00, 0x42, 0xff, 0xaa},
- {0x00, 0x43, 0xff, 0xaa},
- {0x00, 0x03, 0x00, 0xaa},
- {0x00, 0x03, 0x00, 0xaa},
- {0x00, 0x20, 0xc4, 0xaa},
- {0x00, 0x13, 0x03, 0xaa},
- {0x00, 0x3c, 0x50, 0xaa},
- {0x00, 0x61, 0x6a, 0xaa}, /* sharpness? */
- {0x00, 0x51, 0x5b, 0xaa},
- {0x00, 0x52, 0x91, 0xaa},
- {0x00, 0x53, 0x4c, 0xaa},
- {0x00, 0x54, 0x50, 0xaa},
- {0x00, 0x56, 0x02, 0xaa},
- {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x03, 0xcc},
- {0xb6, 0x02, 0x20, 0xcc},
- {0xb6, 0x05, 0x02, 0xcc},
- {0xb6, 0x04, 0x58, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x13, 0x21, 0xcc},
- {0xb6, 0x18, 0x03, 0xcc},
- {0xb6, 0x17, 0xa9, 0xcc},
- {0xb6, 0x16, 0x80, 0xcc},
- {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc},
- {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc},
- {0xbf, 0xcc, 0x00, 0xcc},
- {0xb8, 0x06, 0x20, 0xcc},
- {0xb8, 0x07, 0x03, 0xcc},
- {0xb8, 0x08, 0x58, 0xcc},
- {0xb8, 0x09, 0x02, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc},
- {0x00, 0x03, 0x00, 0xaa},
- {0x00, 0xd9, 0x0f, 0xaa},
- {0x00, 0xda, 0xaa, 0xaa},
- {0x00, 0xd9, 0x10, 0xaa},
- {0x00, 0xda, 0xaa, 0xaa},
- {0x00, 0xd9, 0x11, 0xaa},
- {0x00, 0xda, 0x00, 0xaa},
- {0x00, 0xd9, 0x12, 0xaa},
- {0x00, 0xda, 0xff, 0xaa},
- {0x00, 0xd9, 0x13, 0xaa},
- {0x00, 0xda, 0xff, 0xaa},
- {0x00, 0xe8, 0x11, 0xaa},
- {0x00, 0xe9, 0x12, 0xaa},
- {0x00, 0xea, 0x5c, 0xaa},
- {0x00, 0xeb, 0xff, 0xaa},
- {0x00, 0xd8, 0x80, 0xaa},
- {0x00, 0xe6, 0x02, 0xaa},
- {0x00, 0xd6, 0x40, 0xaa},
- {0x00, 0xe3, 0x05, 0xaa},
- {0x00, 0xe0, 0x40, 0xaa},
- {0x00, 0xde, 0x03, 0xaa},
- {0x00, 0xdf, 0x03, 0xaa},
- {0x00, 0xdb, 0x02, 0xaa},
- {0x00, 0xdc, 0x00, 0xaa},
- {0x00, 0xdd, 0x03, 0xaa},
- {0x00, 0xe1, 0x08, 0xaa},
- {0x00, 0xe2, 0x01, 0xaa},
- {0x00, 0xd6, 0x40, 0xaa},
- {0x00, 0xe4, 0x40, 0xaa},
- {0x00, 0xa8, 0x8f, 0xaa},
- {0x00, 0xb4, 0x16, 0xaa},
- {0xb0, 0x02, 0x06, 0xcc},
- {0xb0, 0x18, 0x06, 0xcc},
- {0xb0, 0x19, 0x06, 0xcc},
- {0xb3, 0x5d, 0x18, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x00, 0xcc},
- {0x00, 0xb4, 0x0e, 0xaa},
- {0x00, 0xb5, 0x49, 0xaa},
- {0x00, 0xb6, 0x1c, 0xaa},
- {0x00, 0xb7, 0x96, 0xaa},
-/* end of usbvm326.inf - start of ms-win trace */
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x13, 0x3d, 0xcc},
-/*read b306*/
- {0x00, 0x03, 0x00, 0xaa},
- {0x00, 0x1a, 0x09, 0xaa},
- {0x00, 0x1b, 0x8a, 0xaa},
-/*read b827*/
- {0xb8, 0x27, 0x00, 0xcc},
- {0xb8, 0x26, 0x60, 0xcc},
- {0xb8, 0x26, 0x60, 0xcc},
-/*gamma - to do?*/
- {0x00, 0x03, 0x00, 0xaa},
- {0x00, 0xae, 0x84, 0xaa},
-/*gamma again*/
- {0x00, 0x03, 0x00, 0xaa},
- {0x00, 0x96, 0xa0, 0xaa},
-/*matrix*/
- {0x00, 0x03, 0x00, 0xaa},
- {0x00, 0x91, 0x35, 0xaa},
- {0x00, 0x92, 0x22, 0xaa},
-/*gamma*/
- {0x00, 0x03, 0x00, 0xaa},
- {0x00, 0x95, 0x85, 0xaa},
-/*matrix*/
- {0x00, 0x03, 0x00, 0xaa},
- {0x00, 0x4d, 0x20, 0xaa},
- {0xb8, 0x22, 0x40, 0xcc},
- {0xb8, 0x23, 0x40, 0xcc},
- {0xb8, 0x24, 0x40, 0xcc},
- {0xb8, 0x81, 0x09, 0xcc},
- {0x00, 0x00, 0x64, 0xdd},
- {0x00, 0x03, 0x01, 0xaa},
-/*read 46*/
- {0x00, 0x46, 0x3c, 0xaa},
- {0x00, 0x03, 0x00, 0xaa},
- {0x00, 0x16, 0x40, 0xaa},
- {0x00, 0x17, 0x40, 0xaa},
- {0x00, 0x18, 0x40, 0xaa},
- {0x00, 0x19, 0x41, 0xaa},
- {0x00, 0x03, 0x01, 0xaa},
- {0x00, 0x46, 0x3c, 0xaa},
- {0x00, 0x00, 0x18, 0xdd},
-/*read bfff*/
- {0x00, 0x03, 0x00, 0xaa},
- {0x00, 0xb4, 0x1c, 0xaa},
- {0x00, 0xb5, 0x92, 0xaa},
- {0x00, 0xb6, 0x39, 0xaa},
- {0x00, 0xb7, 0x24, 0xaa},
-/*write 89 0400 1415*/
- {}
-};
-
-static const u8 poxxxx_init_common[][4] = {
- {0xb3, 0x00, 0x04, 0xcc},
- {0x00, 0x00, 0x10, 0xdd},
- {0xb3, 0x00, 0x64, 0xcc},
- {0x00, 0x00, 0x10, 0xdd},
- {0xb3, 0x00, 0x65, 0xcc},
- {0x00, 0x00, 0x10, 0xdd},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb0, 0x03, 0x09, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x00, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x34, 0x01, 0xcc},
- {0xb3, 0x35, 0xf6, 0xcc}, /* i2c add: 76 */
- {0xb3, 0x02, 0xb0, 0xcc},
- {0xb3, 0x03, 0x18, 0xcc},
- {0xb3, 0x04, 0x15, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x04, 0xcc}, /* sensor height = 1024 */
- {0xb3, 0x23, 0x00, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x04, 0xcc}, /* sensor width = 1280 */
- {0xb3, 0x17, 0xff, 0xcc},
- {0xb3, 0x2c, 0x03, 0xcc},
- {0xb3, 0x2d, 0x56, 0xcc},
- {0xb3, 0x2e, 0x02, 0xcc},
- {0xb3, 0x2f, 0x0a, 0xcc},
- {0xb3, 0x40, 0x00, 0xcc},
- {0xb3, 0x41, 0x34, 0xcc},
- {0xb3, 0x42, 0x01, 0xcc},
- {0xb3, 0x43, 0xe0, 0xcc},
- {0xbc, 0x00, 0x71, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc},
- {0xb3, 0x4d, 0x00, 0xcc},
- {0x00, 0x0b, 0x2a, 0xaa},
- {0x00, 0x0e, 0x03, 0xaa},
- {0x00, 0x0f, 0xea, 0xaa},
- {0x00, 0x12, 0x08, 0xaa},
- {0x00, 0x1e, 0x06, 0xaa},
- {0x00, 0x21, 0x00, 0xaa},
- {0x00, 0x31, 0x1f, 0xaa},
- {0x00, 0x33, 0x38, 0xaa},
- {0x00, 0x36, 0xc0, 0xaa},
- {0x00, 0x37, 0xc8, 0xaa},
- {0x00, 0x3b, 0x36, 0xaa},
- {0x00, 0x4b, 0xfe, 0xaa},
- {0x00, 0x4d, 0x2e, 0xaa},
- {0x00, 0x51, 0x1c, 0xaa},
- {0x00, 0x52, 0x01, 0xaa},
- {0x00, 0x55, 0x0a, 0xaa},
- {0x00, 0x56, 0x0a, 0xaa},
- {0x00, 0x57, 0x07, 0xaa},
- {0x00, 0x58, 0x07, 0xaa},
- {0x00, 0x59, 0x04, 0xaa},
- {0x00, 0x70, 0x68, 0xaa},
- {0x00, 0x71, 0x04, 0xaa},
- {0x00, 0x72, 0x10, 0xaa},
- {0x00, 0x80, 0x71, 0xaa},
- {0x00, 0x81, 0x08, 0xaa},
- {0x00, 0x82, 0x00, 0xaa},
- {0x00, 0x83, 0x55, 0xaa},
- {0x00, 0x84, 0x06, 0xaa},
- {0x00, 0x85, 0x06, 0xaa},
- {0x00, 0x8b, 0x25, 0xaa},
- {0x00, 0x8c, 0x00, 0xaa},
- {0x00, 0x8d, 0x86, 0xaa},
- {0x00, 0x8e, 0x82, 0xaa},
- {0x00, 0x8f, 0x2d, 0xaa},
- {0x00, 0x90, 0x8b, 0xaa},
- {0x00, 0x91, 0x81, 0xaa},
- {0x00, 0x92, 0x81, 0xaa},
- {0x00, 0x93, 0x23, 0xaa},
- {0x00, 0xa3, 0x2a, 0xaa},
- {0x00, 0xa4, 0x03, 0xaa},
- {0x00, 0xa5, 0xea, 0xaa},
- {0x00, 0xb0, 0x68, 0xaa},
- {0x00, 0xbc, 0x04, 0xaa},
- {0x00, 0xbe, 0x3b, 0xaa},
- {0x00, 0x4e, 0x40, 0xaa},
- {0x00, 0x06, 0x04, 0xaa},
- {0x00, 0x07, 0x03, 0xaa},
- {0x00, 0xcd, 0x18, 0xaa},
- {0x00, 0x28, 0x03, 0xaa},
- {0x00, 0x29, 0xef, 0xaa},
-/* reinit on alt 2 (qvga) or alt7 (vga) */
- {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x00, 0xcc},
- {0xb8, 0x00, 0x01, 0xcc},
-
- {0x00, 0x1d, 0x85, 0xaa},
- {0x00, 0x1e, 0xc6, 0xaa},
- {0x00, 0x00, 0x40, 0xdd},
- {0x00, 0x1d, 0x05, 0xaa},
- {}
-};
-static const u8 poxxxx_gamma[][4] = {
- {0x00, 0xd6, 0x22, 0xaa}, /* gamma 0 */
- {0x00, 0x73, 0x00, 0xaa},
- {0x00, 0x74, 0x0a, 0xaa},
- {0x00, 0x75, 0x16, 0xaa},
- {0x00, 0x76, 0x25, 0xaa},
- {0x00, 0x77, 0x34, 0xaa},
- {0x00, 0x78, 0x49, 0xaa},
- {0x00, 0x79, 0x5a, 0xaa},
- {0x00, 0x7a, 0x7f, 0xaa},
- {0x00, 0x7b, 0x9b, 0xaa},
- {0x00, 0x7c, 0xba, 0xaa},
- {0x00, 0x7d, 0xd4, 0xaa},
- {0x00, 0x7e, 0xea, 0xaa},
-
- {0x00, 0xd6, 0x62, 0xaa}, /* gamma 1 */
- {0x00, 0x73, 0x00, 0xaa},
- {0x00, 0x74, 0x0a, 0xaa},
- {0x00, 0x75, 0x16, 0xaa},
- {0x00, 0x76, 0x25, 0xaa},
- {0x00, 0x77, 0x34, 0xaa},
- {0x00, 0x78, 0x49, 0xaa},
- {0x00, 0x79, 0x5a, 0xaa},
- {0x00, 0x7a, 0x7f, 0xaa},
- {0x00, 0x7b, 0x9b, 0xaa},
- {0x00, 0x7c, 0xba, 0xaa},
- {0x00, 0x7d, 0xd4, 0xaa},
- {0x00, 0x7e, 0xea, 0xaa},
-
- {0x00, 0xd6, 0xa2, 0xaa}, /* gamma 2 */
- {0x00, 0x73, 0x00, 0xaa},
- {0x00, 0x74, 0x0a, 0xaa},
- {0x00, 0x75, 0x16, 0xaa},
- {0x00, 0x76, 0x25, 0xaa},
- {0x00, 0x77, 0x34, 0xaa},
- {0x00, 0x78, 0x49, 0xaa},
- {0x00, 0x79, 0x5a, 0xaa},
- {0x00, 0x7a, 0x7f, 0xaa},
- {0x00, 0x7b, 0x9b, 0xaa},
- {0x00, 0x7c, 0xba, 0xaa},
- {0x00, 0x7d, 0xd4, 0xaa},
- {0x00, 0x7e, 0xea, 0xaa},
- {}
-};
-static const u8 poxxxx_init_start_3[][4] = {
- {0x00, 0xb8, 0x28, 0xaa},
- {0x00, 0xb9, 0x1e, 0xaa},
- {0x00, 0xb6, 0x14, 0xaa},
- {0x00, 0xb7, 0x0f, 0xaa},
- {0x00, 0x5c, 0x10, 0xaa},
- {0x00, 0x5d, 0x18, 0xaa},
- {0x00, 0x5e, 0x24, 0xaa},
- {0x00, 0x5f, 0x24, 0xaa},
- {0x00, 0x86, 0x1a, 0xaa},
- {0x00, 0x60, 0x00, 0xaa},
- {0x00, 0x61, 0x1b, 0xaa},
- {0x00, 0x62, 0x30, 0xaa},
- {0x00, 0x63, 0x40, 0xaa},
- {0x00, 0x87, 0x1a, 0xaa},
- {0x00, 0x64, 0x00, 0xaa},
- {0x00, 0x65, 0x08, 0xaa},
- {0x00, 0x66, 0x10, 0xaa},
- {0x00, 0x67, 0x20, 0xaa},
- {0x00, 0x88, 0x10, 0xaa},
- {0x00, 0x68, 0x00, 0xaa},
- {0x00, 0x69, 0x08, 0xaa},
- {0x00, 0x6a, 0x0f, 0xaa},
- {0x00, 0x6b, 0x0f, 0xaa},
- {0x00, 0x89, 0x07, 0xaa},
- {0x00, 0xd5, 0x4c, 0xaa},
- {0x00, 0x0a, 0x00, 0xaa},
- {0x00, 0x0b, 0x2a, 0xaa},
- {0x00, 0x0e, 0x03, 0xaa},
- {0x00, 0x0f, 0xea, 0xaa},
- {0x00, 0xa2, 0x00, 0xaa},
- {0x00, 0xa3, 0x2a, 0xaa},
- {0x00, 0xa4, 0x03, 0xaa},
- {0x00, 0xa5, 0xea, 0xaa},
- {}
-};
-static const u8 poxxxx_initVGA[][4] = {
- {0x00, 0x20, 0x11, 0xaa},
- {0x00, 0x33, 0x38, 0xaa},
- {0x00, 0xbb, 0x0d, 0xaa},
- {0xb3, 0x22, 0x01, 0xcc}, /* change to 640x480 */
- {0xb3, 0x23, 0xe0, 0xcc},
- {0xb3, 0x16, 0x02, 0xcc},
- {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x02, 0xb0, 0xcc},
- {0xb3, 0x06, 0x00, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0x00, 0x04, 0x06, 0xaa},
- {0x00, 0x05, 0x3f, 0xaa},
- {0x00, 0x04, 0x00, 0xdd}, /* delay 1s */
- {}
-};
-static const u8 poxxxx_initQVGA[][4] = {
- {0x00, 0x20, 0x33, 0xaa},
- {0x00, 0x33, 0x38, 0xaa},
- {0x00, 0xbb, 0x0d, 0xaa},
- {0xb3, 0x22, 0x00, 0xcc}, /* change to 320x240 */
- {0xb3, 0x23, 0xf0, 0xcc},
- {0xb3, 0x16, 0x01, 0xcc},
- {0xb3, 0x17, 0x3f, 0xcc},
- {0xb3, 0x02, 0xb0, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc},
- {0xb3, 0x5c, 0x00, 0xcc},
- {0x00, 0x04, 0x06, 0xaa},
- {0x00, 0x05, 0x3f, 0xaa},
- {0x00, 0x04, 0x00, 0xdd}, /* delay 1s */
- {}
-};
-static const u8 poxxxx_init_end_1[][4] = {
- {0x00, 0x47, 0x25, 0xaa},
- {0x00, 0x48, 0x80, 0xaa},
- {0x00, 0x49, 0x1f, 0xaa},
- {0x00, 0x4a, 0x40, 0xaa},
- {0x00, 0x44, 0x40, 0xaa},
- {0x00, 0xab, 0x4a, 0xaa},
- {0x00, 0xb1, 0x00, 0xaa},
- {0x00, 0xb2, 0x04, 0xaa},
- {0x00, 0xb3, 0x08, 0xaa},
- {0x00, 0xb4, 0x0b, 0xaa},
- {0x00, 0xb5, 0x0d, 0xaa},
- {}
-};
-static const u8 poxxxx_init_end_2[][4] = {
- {0x00, 0x1d, 0x85, 0xaa},
- {0x00, 0x1e, 0x06, 0xaa},
- {0x00, 0x1d, 0x05, 0xaa},
- {}
-};
-
-struct sensor_info {
- s8 sensorId;
- u8 I2cAdd;
- u8 IdAdd;
- u16 VpId;
- u8 m1;
- u8 m2;
- u8 op;
-};
-
-/* probe values */
-static const struct sensor_info vc0321_probe_data[] = {
-/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */
-/* 0 OV9640 */
- {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
-/* 1 ICM108T (may respond on IdAdd == 0x83 - tested in vc032x_probe_sensor) */
- {-1, 0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01},
-/* 2 PO2130 (may detect PO3130NC - tested in vc032x_probe_sensor)*/
- {-1, 0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01},
-/* 3 MI1310 */
- {-1, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01},
-/* 4 MI360 - tested in vc032x_probe_sensor */
-/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */
-/* 5 7131R */
- {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
-/* 6 OV7649 */
- {-1, 0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05},
-/* 7 PAS302BCW */
- {-1, 0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05},
-/* 8 OV7660 */
- {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
-/* 9 PO3130NC - (tested in vc032x_probe_sensor) */
-/* {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, */
-/* 10 PO1030KC */
- {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
-/* 11 MI1310_SOC */
- {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
-/* 12 OV9650 */
- {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
-/* 13 S5K532 */
- {-1, 0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01},
-/* 14 MI360_SOC - ??? */
-/* 15 PO1200N */
- {SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01},
-/* 16 PO3030K */
- {-1, 0x80 | 0x18, 0x00, 0x0000, 0x24, 0x25, 0x01},
-/* 17 PO2030 */
- {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
-/* ?? */
- {-1, 0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01},
- {SENSOR_MI1320, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x65, 0x01},
-};
-static const struct sensor_info vc0323_probe_data[] = {
-/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */
-/* 0 OV9640 */
- {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
-/* 1 ICM108T (may respond on IdAdd == 0x83 - tested in vc032x_probe_sensor) */
- {-1, 0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01},
-/* 2 PO2130 (may detect PO3130NC - tested in vc032x_probe_sensor)*/
- {-1, 0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01},
-/* 3 MI1310 */
- {-1, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01},
-/* 4 MI360 - tested in vc032x_probe_sensor */
-/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */
-/* 5 7131R */
- {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
-/* 6 OV7649 */
- {-1, 0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05},
-/* 7 PAS302BCW */
- {-1, 0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05},
-/* 8 OV7660 */
- {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
-/* 9 PO3130NC - (tested in vc032x_probe_sensor) */
-/* {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, */
-/* 10 PO1030KC */
- {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
-/* 11 MI1310_SOC */
- {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
-/* 12 OV9650 */
- {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
-/* 13 S5K532 */
- {-1, 0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01},
-/* 14 MI360_SOC - ??? */
-/* 15 PO1200N */
- {SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01},
-/* 16 ?? */
- {-1, 0x80 | 0x2d, 0x00, 0x0000, 0x65, 0x67, 0x01},
-/* 17 PO2030 */
- {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
-/* ?? */
- {-1, 0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01},
- {SENSOR_MI1320_SOC, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x67, 0x01},
-/*fixme: not in the ms-win probe - may be found before? */
- {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
-};
-
-/* read 'len' bytes in gspca_dev->usb_buf */
-static void reg_r_i(struct gspca_dev *gspca_dev,
- u16 req,
- u16 index,
- u16 len)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 1, /* value */
- index, gspca_dev->usb_buf, len,
- 500);
- if (ret < 0) {
- pr_err("reg_r err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-static void reg_r(struct gspca_dev *gspca_dev,
- u16 req,
- u16 index,
- u16 len)
-{
- reg_r_i(gspca_dev, req, index, len);
-#ifdef GSPCA_DEBUG
- if (gspca_dev->usb_err < 0)
- return;
- if (len == 1)
- PDEBUG(D_USBI, "GET %02x 0001 %04x %02x", req, index,
- gspca_dev->usb_buf[0]);
- else
- PDEBUG(D_USBI, "GET %02x 0001 %04x %02x %02x %02x",
- req, index,
- gspca_dev->usb_buf[0],
- gspca_dev->usb_buf[1],
- gspca_dev->usb_buf[2]);
-#endif
-}
-
-static void reg_w_i(struct gspca_dev *gspca_dev,
- u16 req,
- u16 value,
- u16 index)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, NULL, 0,
- 500);
- if (ret < 0) {
- pr_err("reg_w err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-static void reg_w(struct gspca_dev *gspca_dev,
- u16 req,
- u16 value,
- u16 index)
-{
-#ifdef GSPCA_DEBUG
- if (gspca_dev->usb_err < 0)
- return;
- PDEBUG(D_USBO, "SET %02x %04x %04x", req, value, index);
-#endif
- reg_w_i(gspca_dev, req, value, index);
-}
-
-static u16 read_sensor_register(struct gspca_dev *gspca_dev,
- u16 address)
-{
- u8 ldata, mdata, hdata;
- int retry = 50;
-
- reg_r(gspca_dev, 0xa1, 0xb33f, 1);
- if (!(gspca_dev->usb_buf[0] & 0x02)) {
- pr_err("I2c Bus Busy Wait %02x\n", gspca_dev->usb_buf[0]);
- return 0;
- }
- reg_w(gspca_dev, 0xa0, address, 0xb33a);
- reg_w(gspca_dev, 0xa0, 0x02, 0xb339);
-
- do {
- reg_r(gspca_dev, 0xa1, 0xb33b, 1);
- if (gspca_dev->usb_buf[0] == 0x00)
- break;
- msleep(40);
- } while (--retry >= 0);
-
- reg_r(gspca_dev, 0xa1, 0xb33e, 1);
- ldata = gspca_dev->usb_buf[0];
- reg_r(gspca_dev, 0xa1, 0xb33d, 1);
- mdata = gspca_dev->usb_buf[0];
- reg_r(gspca_dev, 0xa1, 0xb33c, 1);
- hdata = gspca_dev->usb_buf[0];
- if (hdata != 0 && mdata != 0 && ldata != 0)
- PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
- hdata, mdata, ldata);
- reg_r(gspca_dev, 0xa1, 0xb334, 1);
- if (gspca_dev->usb_buf[0] == 0x02)
- return (hdata << 8) + mdata;
- return hdata;
-}
-
-static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i, n;
- u16 value;
- const struct sensor_info *ptsensor_info;
-
-/*fixme: should also check the other sensor (back mi1320_soc, front mc501cb)*/
- if (sd->flags & FL_SAMSUNG) {
- reg_w(gspca_dev, 0xa0, 0x01, 0xb301);
- reg_w(gspca_dev, 0x89, 0xf0ff, 0xffff);
- /* select the back sensor */
- }
-
- reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
- PDEBUG(D_PROBE, "vc032%d check sensor header %02x",
- sd->bridge == BRIDGE_VC0321 ? 1 : 3, gspca_dev->usb_buf[0]);
- if (sd->bridge == BRIDGE_VC0321) {
- ptsensor_info = vc0321_probe_data;
- n = ARRAY_SIZE(vc0321_probe_data);
- } else {
- ptsensor_info = vc0323_probe_data;
- n = ARRAY_SIZE(vc0323_probe_data);
- }
- for (i = 0; i < n; i++) {
- reg_w(gspca_dev, 0xa0, 0x02, 0xb334);
- reg_w(gspca_dev, 0xa0, ptsensor_info->m1, 0xb300);
- reg_w(gspca_dev, 0xa0, ptsensor_info->m2, 0xb300);
- reg_w(gspca_dev, 0xa0, 0x01, 0xb308);
- reg_w(gspca_dev, 0xa0, 0x0c, 0xb309);
- reg_w(gspca_dev, 0xa0, ptsensor_info->I2cAdd, 0xb335);
- reg_w(gspca_dev, 0xa0, ptsensor_info->op, 0xb301);
- value = read_sensor_register(gspca_dev, ptsensor_info->IdAdd);
- if (value == 0 && ptsensor_info->IdAdd == 0x82)
- value = read_sensor_register(gspca_dev, 0x83);
- if (value != 0) {
- PDEBUG(D_ERR|D_PROBE, "Sensor ID %04x (%d)",
- value, i);
- if (value == ptsensor_info->VpId)
- return ptsensor_info->sensorId;
-
- switch (value) {
- case 0x3130:
- return SENSOR_PO3130NC;
- case 0x7673:
- return SENSOR_OV7670;
- case 0x8243:
- return SENSOR_MI0360;
- }
- }
- ptsensor_info++;
- }
- return -1;
-}
-
-static void i2c_write(struct gspca_dev *gspca_dev,
- u8 reg, const u8 *val,
- u8 size) /* 1 or 2 */
-{
- int retry;
-
-#ifdef GSPCA_DEBUG
- if (gspca_dev->usb_err < 0)
- return;
- if (size == 1)
- PDEBUG(D_USBO, "i2c_w %02x %02x", reg, *val);
- else
- PDEBUG(D_USBO, "i2c_w %02x %02x%02x", reg, *val, val[1]);
-#endif
- reg_r_i(gspca_dev, 0xa1, 0xb33f, 1);
-/*fixme:should check if (!(gspca_dev->usb_buf[0] & 0x02)) error*/
- reg_w_i(gspca_dev, 0xa0, size, 0xb334);
- reg_w_i(gspca_dev, 0xa0, reg, 0xb33a);
- reg_w_i(gspca_dev, 0xa0, val[0], 0xb336);
- if (size > 1)
- reg_w_i(gspca_dev, 0xa0, val[1], 0xb337);
- reg_w_i(gspca_dev, 0xa0, 0x01, 0xb339);
- retry = 4;
- do {
- reg_r_i(gspca_dev, 0xa1, 0xb33b, 1);
- if (gspca_dev->usb_buf[0] == 0)
- break;
- msleep(20);
- } while (--retry > 0);
- if (retry <= 0)
- pr_err("i2c_write timeout\n");
-}
-
-static void put_tab_to_reg(struct gspca_dev *gspca_dev,
- const u8 *tab, u8 tabsize, u16 addr)
-{
- int j;
- u16 ad = addr;
-
- for (j = 0; j < tabsize; j++)
- reg_w(gspca_dev, 0xa0, tab[j], ad++);
-}
-
-static void usb_exchange(struct gspca_dev *gspca_dev,
- const u8 data[][4])
-{
- int i = 0;
-
- for (;;) {
- switch (data[i][3]) {
- default:
- return;
- case 0xcc: /* normal write */
- reg_w(gspca_dev, 0xa0, data[i][2],
- (data[i][0]) << 8 | data[i][1]);
- break;
- case 0xaa: /* i2c op */
- i2c_write(gspca_dev, data[i][1], &data[i][2], 1);
- break;
- case 0xbb: /* i2c op */
- i2c_write(gspca_dev, data[i][0], &data[i][1], 2);
- break;
- case 0xdd:
- msleep(data[i][1] * 256 + data[i][2] + 10);
- break;
- }
- i++;
- }
- /*not reached*/
-}
-
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->bridge = id->driver_info >> 8;
- sd->flags = id->driver_info & 0xff;
-
- if (id->idVendor == 0x046d &&
- (id->idProduct == 0x0892 || id->idProduct == 0x0896))
- sd->sensor = SENSOR_POxxxx; /* no probe */
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
- int sensor;
- /* number of packets per ISOC message */
- static u8 npkt[NSENSORS] = {
- [SENSOR_HV7131R] = 64,
- [SENSOR_MI0360] = 32,
- [SENSOR_MI1310_SOC] = 32,
- [SENSOR_MI1320] = 64,
- [SENSOR_MI1320_SOC] = 128,
- [SENSOR_OV7660] = 32,
- [SENSOR_OV7670] = 64,
- [SENSOR_PO1200] = 128,
- [SENSOR_PO3130NC] = 128,
- [SENSOR_POxxxx] = 128,
- };
-
- if (sd->sensor != SENSOR_POxxxx)
- sensor = vc032x_probe_sensor(gspca_dev);
- else
- sensor = sd->sensor;
-
- switch (sensor) {
- case -1:
- pr_err("Unknown sensor...\n");
- return -EINVAL;
- case SENSOR_HV7131R:
- PDEBUG(D_PROBE, "Find Sensor HV7131R");
- break;
- case SENSOR_MI0360:
- PDEBUG(D_PROBE, "Find Sensor MI0360");
- sd->bridge = BRIDGE_VC0323;
- break;
- case SENSOR_MI1310_SOC:
- PDEBUG(D_PROBE, "Find Sensor MI1310_SOC");
- break;
- case SENSOR_MI1320:
- PDEBUG(D_PROBE, "Find Sensor MI1320");
- break;
- case SENSOR_MI1320_SOC:
- PDEBUG(D_PROBE, "Find Sensor MI1320_SOC");
- break;
- case SENSOR_OV7660:
- PDEBUG(D_PROBE, "Find Sensor OV7660");
- break;
- case SENSOR_OV7670:
- PDEBUG(D_PROBE, "Find Sensor OV7670");
- break;
- case SENSOR_PO1200:
- PDEBUG(D_PROBE, "Find Sensor PO1200");
- break;
- case SENSOR_PO3130NC:
- PDEBUG(D_PROBE, "Find Sensor PO3130NC");
- break;
- case SENSOR_POxxxx:
- PDEBUG(D_PROBE, "Sensor POxxxx");
- break;
- }
- sd->sensor = sensor;
-
- cam = &gspca_dev->cam;
- if (sd->bridge == BRIDGE_VC0321) {
- cam->cam_mode = vc0321_mode;
- cam->nmodes = ARRAY_SIZE(vc0321_mode);
- } else {
- switch (sensor) {
- case SENSOR_PO1200:
- cam->cam_mode = svga_mode;
- cam->nmodes = ARRAY_SIZE(svga_mode);
- break;
- case SENSOR_MI1310_SOC:
- cam->cam_mode = vc0323_mode;
- cam->nmodes = ARRAY_SIZE(vc0323_mode);
- break;
- case SENSOR_MI1320_SOC:
- cam->cam_mode = bi_mode;
- cam->nmodes = ARRAY_SIZE(bi_mode);
- break;
- case SENSOR_OV7670:
- cam->cam_mode = bi_mode;
- cam->nmodes = ARRAY_SIZE(bi_mode) - 1;
- break;
- default:
- cam->cam_mode = vc0323_mode;
- cam->nmodes = ARRAY_SIZE(vc0323_mode) - 1;
- break;
- }
- }
- cam->npkt = npkt[sd->sensor];
-
- if (sd->sensor == SENSOR_OV7670)
- sd->flags |= FL_HFLIP | FL_VFLIP;
-
- if (sd->bridge == BRIDGE_VC0321) {
- reg_r(gspca_dev, 0x8a, 0, 3);
- reg_w(gspca_dev, 0x87, 0x00, 0x0f0f);
- reg_r(gspca_dev, 0x8b, 0, 3);
- reg_w(gspca_dev, 0x88, 0x00, 0x0202);
- if (sd->sensor == SENSOR_POxxxx) {
- reg_r(gspca_dev, 0xa1, 0xb300, 1);
- if (gspca_dev->usb_buf[0] != 0) {
- reg_w(gspca_dev, 0xa0, 0x26, 0xb300);
- reg_w(gspca_dev, 0xa0, 0x04, 0xb300);
- }
- reg_w(gspca_dev, 0xa0, 0x00, 0xb300);
- }
- }
- return gspca_dev->usb_err;
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
-{
- u8 data;
-
- data = val;
- if (data >= 0x80)
- data &= 0x7f;
- else
- data = 0xff ^ data;
- i2c_write(gspca_dev, 0x98, &data, 1);
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev, u8 val)
-{
- i2c_write(gspca_dev, 0x99, &val, 1);
-}
-
-static void setcolors(struct gspca_dev *gspca_dev, u8 val)
-{
- u8 data;
-
- data = val - (val >> 3) - 1;
- i2c_write(gspca_dev, 0x94, &data, 1);
- i2c_write(gspca_dev, 0x95, &val, 1);
-}
-
-static void sethvflip(struct gspca_dev *gspca_dev, bool hflip, bool vflip)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 data[2];
-
- if (sd->flags & FL_HFLIP)
- hflip = !hflip;
- if (sd->flags & FL_VFLIP)
- vflip = !vflip;
- switch (sd->sensor) {
- case SENSOR_MI1310_SOC:
- case SENSOR_MI1320:
- case SENSOR_MI1320_SOC:
- data[0] = data[1] = 0; /* select page 0 */
- i2c_write(gspca_dev, 0xf0, data, 2);
- data[0] = sd->sensor == SENSOR_MI1310_SOC ? 0x03 : 0x01;
- data[1] = 0x02 * hflip
- | 0x01 * vflip;
- i2c_write(gspca_dev, 0x20, data, 2);
- break;
- case SENSOR_OV7660:
- case SENSOR_OV7670:
- data[0] = sd->sensor == SENSOR_OV7660 ? 0x01 : 0x07;
- data[0] |= OV7660_MVFP_MIRROR * hflip
- | OV7660_MVFP_VFLIP * vflip;
- i2c_write(gspca_dev, OV7660_REG_MVFP, data, 1);
- break;
- case SENSOR_PO1200:
- data[0] = 0;
- i2c_write(gspca_dev, 0x03, data, 1);
- data[0] = 0x80 * hflip
- | 0x40 * vflip
- | 0x06;
- i2c_write(gspca_dev, 0x1e, data, 1);
- break;
- }
-}
-
-static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- static const u8 (*ov7660_freq_tb[3])[4] =
- {ov7660_NoFliker, ov7660_50HZ, ov7660_60HZ};
-
- if (sd->sensor != SENSOR_OV7660)
- return;
- usb_exchange(gspca_dev, ov7660_freq_tb[val]);
-}
-
-static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 data;
-
- switch (sd->sensor) {
- case SENSOR_PO1200:
- data = 0;
- i2c_write(gspca_dev, 0x03, &data, 1);
- if (val < 0)
- data = 0x6a;
- else
- data = 0xb5 + val * 3;
- i2c_write(gspca_dev, 0x61, &data, 1);
- break;
- case SENSOR_POxxxx:
- if (val < 0)
- data = 0x7e; /* def = max */
- else
- data = 0x60 + val * 0x0f;
- i2c_write(gspca_dev, 0x59, &data, 1);
- break;
- }
-}
-static void setgain(struct gspca_dev *gspca_dev, u8 val)
-{
- i2c_write(gspca_dev, 0x15, &val, 1);
-}
-
-static void setexposure(struct gspca_dev *gspca_dev, s32 val)
-{
- u8 data;
-
- data = val >> 8;
- i2c_write(gspca_dev, 0x1a, &data, 1);
- data = val;
- i2c_write(gspca_dev, 0x1b, &data, 1);
-}
-
-static void setautogain(struct gspca_dev *gspca_dev, s32 val)
-{
- static const u8 data[2] = {0x28, 0x3c};
-
- i2c_write(gspca_dev, 0xd1, &data[val], 1);
-}
-
-static void setgamma(struct gspca_dev *gspca_dev)
-{
-/*fixme:to do */
- usb_exchange(gspca_dev, poxxxx_gamma);
-}
-
-static void setbacklight(struct gspca_dev *gspca_dev, s32 val)
-{
- u16 v;
- u8 data;
-
- data = (val << 4) | 0x0f;
- i2c_write(gspca_dev, 0xaa, &data, 1);
- v = 613 + 12 * val;
- data = v >> 8;
- i2c_write(gspca_dev, 0xc4, &data, 1);
- data = v;
- i2c_write(gspca_dev, 0xc5, &data, 1);
- v = 1093 - 12 * val;
- data = v >> 8;
- i2c_write(gspca_dev, 0xc6, &data, 1);
- data = v;
- i2c_write(gspca_dev, 0xc7, &data, 1);
- v = 342 + 9 * val;
- data = v >> 8;
- i2c_write(gspca_dev, 0xc8, &data, 1);
- data = v;
- i2c_write(gspca_dev, 0xc9, &data, 1);
- v = 702 - 9 * val;
- data = v >> 8;
- i2c_write(gspca_dev, 0xca, &data, 1);
- data = v;
- i2c_write(gspca_dev, 0xcb, &data, 1);
-}
-
-static void setwb(struct gspca_dev *gspca_dev)
-{
-/*fixme:to do - valid when reg d1 = 0x1c - (reg16 + reg15 = 0xa3)*/
- static const u8 data[2] = {0x00, 0x00};
-
- i2c_write(gspca_dev, 0x16, &data[0], 1);
- i2c_write(gspca_dev, 0x18, &data[1], 1);
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- const u8 (*init)[4];
- const u8 *GammaT = NULL;
- const u8 *MatrixT = NULL;
- int mode;
- static const u8 (*mi1320_soc_init[])[4] = {
- mi1320_soc_InitSXGA,
- mi1320_soc_InitVGA,
- mi1320_soc_InitQVGA,
- };
-
-/*fixme: back sensor only*/
- if (sd->flags & FL_SAMSUNG) {
- reg_w(gspca_dev, 0x89, 0xf0ff, 0xffff);
- reg_w(gspca_dev, 0xa9, 0x8348, 0x000e);
- reg_w(gspca_dev, 0xa9, 0x0000, 0x001a);
- }
-
- /* Assume start use the good resolution from gspca_dev->mode */
- if (sd->bridge == BRIDGE_VC0321) {
- reg_w(gspca_dev, 0xa0, 0xff, 0xbfec);
- reg_w(gspca_dev, 0xa0, 0xff, 0xbfed);
- reg_w(gspca_dev, 0xa0, 0xff, 0xbfee);
- reg_w(gspca_dev, 0xa0, 0xff, 0xbfef);
- sd->image_offset = 46;
- } else {
- if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].pixelformat
- == V4L2_PIX_FMT_JPEG)
- sd->image_offset = 0;
- else
- sd->image_offset = 32;
- }
-
- mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
- switch (sd->sensor) {
- case SENSOR_HV7131R:
- GammaT = hv7131r_gamma;
- MatrixT = hv7131r_matrix;
- if (mode)
- init = hv7131r_initQVGA_data; /* 320x240 */
- else
- init = hv7131r_initVGA_data; /* 640x480 */
- break;
- case SENSOR_OV7660:
- GammaT = ov7660_gamma;
- MatrixT = ov7660_matrix;
- if (mode)
- init = ov7660_initQVGA_data; /* 320x240 */
- else
- init = ov7660_initVGA_data; /* 640x480 */
- break;
- case SENSOR_MI0360:
- GammaT = mi1320_gamma;
- MatrixT = mi0360_matrix;
- if (mode)
- init = mi0360_initQVGA_JPG; /* 320x240 */
- else
- init = mi0360_initVGA_JPG; /* 640x480 */
- break;
- case SENSOR_MI1310_SOC:
- GammaT = mi1320_gamma;
- MatrixT = mi1320_matrix;
- switch (mode) {
- case 1:
- init = mi1310_socinitQVGA_JPG; /* 320x240 */
- break;
- case 0:
- init = mi1310_socinitVGA_JPG; /* 640x480 */
- break;
- default:
- init = mi1310_soc_InitSXGA_JPG; /* 1280x1024 */
- break;
- }
- break;
- case SENSOR_MI1320:
- GammaT = mi1320_gamma;
- MatrixT = mi1320_matrix;
- if (mode)
- init = mi1320_initQVGA_data; /* 320x240 */
- else
- init = mi1320_initVGA_data; /* 640x480 */
- break;
- case SENSOR_MI1320_SOC:
- GammaT = mi1320_gamma;
- MatrixT = mi1320_matrix;
- init = mi1320_soc_init[mode];
- break;
- case SENSOR_OV7670:
- init = mode == 1 ? ov7670_InitVGA : ov7670_InitQVGA;
- break;
- case SENSOR_PO3130NC:
- GammaT = po3130_gamma;
- MatrixT = po3130_matrix;
- if (mode)
- init = po3130_initQVGA_data; /* 320x240 */
- else
- init = po3130_initVGA_data; /* 640x480 */
- usb_exchange(gspca_dev, init);
- init = po3130_rundata;
- break;
- case SENSOR_PO1200:
- GammaT = po1200_gamma;
- MatrixT = po1200_matrix;
- init = po1200_initVGA_data;
- break;
- default:
-/* case SENSOR_POxxxx: */
- usb_exchange(gspca_dev, poxxxx_init_common);
- setgamma(gspca_dev);
- usb_exchange(gspca_dev, poxxxx_init_start_3);
- if (mode)
- init = poxxxx_initQVGA;
- else
- init = poxxxx_initVGA;
- usb_exchange(gspca_dev, init);
- reg_r(gspca_dev, 0x8c, 0x0000, 3);
- reg_w(gspca_dev, 0xa0,
- gspca_dev->usb_buf[2] & 1 ? 0 : 1,
- 0xb35c);
- msleep(300);
-/*fixme: i2c read 04 and 05*/
- init = poxxxx_init_end_1;
- break;
- }
- usb_exchange(gspca_dev, init);
- if (GammaT && MatrixT) {
- put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a);
- put_tab_to_reg(gspca_dev, GammaT, 17, 0xb85b);
- put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c);
- put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c);
-
- switch (sd->sensor) {
- case SENSOR_PO1200:
- case SENSOR_HV7131R:
- reg_w(gspca_dev, 0x89, 0x0400, 0x1415);
- break;
- case SENSOR_MI1310_SOC:
- reg_w(gspca_dev, 0x89, 0x058c, 0x0000);
- break;
- }
- msleep(100);
- }
- switch (sd->sensor) {
- case SENSOR_OV7670:
- reg_w(gspca_dev, 0x87, 0xffff, 0xffff);
- reg_w(gspca_dev, 0x88, 0xff00, 0xf0f1);
- reg_w(gspca_dev, 0xa0, 0x0000, 0xbfff);
- break;
- case SENSOR_POxxxx:
- usb_exchange(gspca_dev, poxxxx_init_end_2);
- setwb(gspca_dev);
- msleep(80); /* led on */
- reg_w(gspca_dev, 0x89, 0xffff, 0xfdff);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->sensor) {
- case SENSOR_MI1310_SOC:
- reg_w(gspca_dev, 0x89, 0x058c, 0x00ff);
- break;
- case SENSOR_POxxxx:
- return;
- default:
- if (!(sd->flags & FL_SAMSUNG))
- reg_w(gspca_dev, 0x89, 0xffff, 0xffff);
- break;
- }
- reg_w(gspca_dev, 0xa0, 0x01, 0xb301);
- reg_w(gspca_dev, 0xa0, 0x09, 0xb003);
-}
-
-/* called on streamoff with alt 0 and on disconnect */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (!gspca_dev->present)
- return;
-/*fixme: is this useful?*/
- if (sd->sensor == SENSOR_MI1310_SOC)
- reg_w(gspca_dev, 0x89, 0x058c, 0x00ff);
- else if (!(sd->flags & FL_SAMSUNG))
- reg_w(gspca_dev, 0x89, 0xffff, 0xffff);
-
- if (sd->sensor == SENSOR_POxxxx) {
- reg_w(gspca_dev, 0xa0, 0x26, 0xb300);
- reg_w(gspca_dev, 0xa0, 0x04, 0xb300);
- reg_w(gspca_dev, 0xa0, 0x00, 0xb300);
- }
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso pkt length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (data[0] == 0xff && data[1] == 0xd8) {
- PDEBUG(D_PACK,
- "vc032x header packet found len %d", len);
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
- data += sd->image_offset;
- len -= sd->image_offset;
- gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
- return;
- }
-
- /* The vc0321 sends some additional data after sending the complete
- * frame, we ignore this. */
- if (sd->bridge == BRIDGE_VC0321) {
- int size, l;
-
- l = gspca_dev->image_len;
- size = gspca_dev->frsz;
- if (len > size - l)
- len = size - l;
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- setbrightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- setcontrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- setcolors(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_HFLIP:
- sethvflip(gspca_dev, sd->hflip->val, sd->vflip->val);
- break;
- case V4L2_CID_SHARPNESS:
- setsharpness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_AUTOGAIN:
- setautogain(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_GAIN:
- setgain(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_EXPOSURE:
- setexposure(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_BACKLIGHT_COMPENSATION:
- setbacklight(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY:
- setlightfreq(gspca_dev, ctrl->val);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
- bool has_brightness = false;
- bool has_contrast = false;
- bool has_sat = false;
- bool has_hvflip = false;
- bool has_freq = false;
- bool has_backlight = false;
- bool has_exposure = false;
- bool has_autogain = false;
- bool has_gain = false;
- bool has_sharpness = false;
-
- switch (sd->sensor) {
- case SENSOR_HV7131R:
- case SENSOR_MI0360:
- case SENSOR_PO3130NC:
- break;
- case SENSOR_MI1310_SOC:
- case SENSOR_MI1320:
- case SENSOR_MI1320_SOC:
- case SENSOR_OV7660:
- has_hvflip = true;
- break;
- case SENSOR_OV7670:
- has_hvflip = has_freq = true;
- break;
- case SENSOR_PO1200:
- has_hvflip = has_sharpness = true;
- break;
- case SENSOR_POxxxx:
- has_brightness = has_contrast = has_sat = has_backlight =
- has_exposure = has_autogain = has_gain =
- has_sharpness = true;
- break;
- }
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 8);
- if (has_brightness)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- if (has_contrast)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 127);
- if (has_sat)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SATURATION, 1, 127, 1, 63);
- if (has_hvflip) {
- sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- }
- if (has_sharpness)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SHARPNESS, -1, 2, 1, -1);
- if (has_freq)
- v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
- V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
- V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
- if (has_autogain)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- if (has_gain)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_GAIN, 0, 78, 1, 0);
- if (has_exposure)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 4095, 1, 450);
- if (has_backlight)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BACKLIGHT_COMPENSATION, 0, 15, 1, 15);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- if (sd->hflip)
- v4l2_ctrl_cluster(2, &sd->hflip);
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .init_controls = sd_init_controls,
- .config = sd_config,
- .init = sd_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
-};
-
-/* -- module initialisation -- */
-#define BF(bridge, flags) \
- .driver_info = (BRIDGE_ ## bridge << 8) \
- | (flags)
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x041e, 0x405b), BF(VC0323, FL_VFLIP)},
- {USB_DEVICE(0x046d, 0x0892), BF(VC0321, 0)},
- {USB_DEVICE(0x046d, 0x0896), BF(VC0321, 0)},
- {USB_DEVICE(0x046d, 0x0897), BF(VC0321, 0)},
- {USB_DEVICE(0x0ac8, 0x0321), BF(VC0321, 0)},
- {USB_DEVICE(0x0ac8, 0x0323), BF(VC0323, 0)},
- {USB_DEVICE(0x0ac8, 0x0328), BF(VC0321, 0)},
- {USB_DEVICE(0x0ac8, 0xc001), BF(VC0321, 0)},
- {USB_DEVICE(0x0ac8, 0xc002), BF(VC0321, 0)},
- {USB_DEVICE(0x0ac8, 0xc301), BF(VC0323, FL_SAMSUNG)},
- {USB_DEVICE(0x15b8, 0x6001), BF(VC0323, 0)},
- {USB_DEVICE(0x15b8, 0x6002), BF(VC0323, 0)},
- {USB_DEVICE(0x17ef, 0x4802), BF(VC0323, 0)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/vicam.c b/drivers/media/video/gspca/vicam.c
deleted file mode 100644
index b1a64b91266..00000000000
--- a/drivers/media/video/gspca/vicam.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * gspca ViCam subdriver
- *
- * Copyright (C) 2011 Hans de Goede <hdegoede@redhat.com>
- *
- * Based on the usbvideo vicam driver, which is:
- *
- * Copyright (c) 2002 Joe Burks (jburks@wavicle.org),
- * Christopher L Cheney (ccheney@cheney.cx),
- * Pavel Machek (pavel@ucw.cz),
- * John Tyner (jtyner@cs.ucr.edu),
- * Monroe Williams (monroe@pobox.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "vicam"
-#define HEADER_SIZE 64
-
-#include <linux/workqueue.h>
-#include <linux/slab.h>
-#include <linux/firmware.h>
-#include <linux/ihex.h>
-#include "gspca.h"
-
-#define VICAM_FIRMWARE "vicam/firmware.fw"
-
-MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
-MODULE_DESCRIPTION("GSPCA ViCam USB Camera Driver");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(VICAM_FIRMWARE);
-
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- struct work_struct work_struct;
- struct workqueue_struct *work_thread;
-};
-
-/* The vicam sensor has a resolution of 512 x 244, with I believe square
- pixels, but this is forced to a 4:3 ratio by optics. So it has
- non square pixels :( */
-static struct v4l2_pix_format vicam_mode[] = {
- { 256, 122, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
- .bytesperline = 256,
- .sizeimage = 256 * 122,
- .colorspace = V4L2_COLORSPACE_SRGB,},
- /* 2 modes with somewhat more square pixels */
- { 256, 200, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
- .bytesperline = 256,
- .sizeimage = 256 * 200,
- .colorspace = V4L2_COLORSPACE_SRGB,},
- { 256, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
- .bytesperline = 256,
- .sizeimage = 256 * 240,
- .colorspace = V4L2_COLORSPACE_SRGB,},
-#if 0 /* This mode has extremely non square pixels, testing use only */
- { 512, 122, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
- .bytesperline = 512,
- .sizeimage = 512 * 122,
- .colorspace = V4L2_COLORSPACE_SRGB,},
-#endif
- { 512, 244, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
- .bytesperline = 512,
- .sizeimage = 512 * 244,
- .colorspace = V4L2_COLORSPACE_SRGB,},
-};
-
-static int vicam_control_msg(struct gspca_dev *gspca_dev, u8 request,
- u16 value, u16 index, u8 *data, u16 len)
-{
- int ret;
-
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- request,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, data, len, 1000);
- if (ret < 0)
- pr_err("control msg req %02X error %d\n", request, ret);
-
- return ret;
-}
-
-static int vicam_set_camera_power(struct gspca_dev *gspca_dev, int state)
-{
- int ret;
-
- ret = vicam_control_msg(gspca_dev, 0x50, state, 0, NULL, 0);
- if (ret < 0)
- return ret;
-
- if (state)
- ret = vicam_control_msg(gspca_dev, 0x55, 1, 0, NULL, 0);
-
- return ret;
-}
-
-/*
- * request and read a block of data - see warning on vicam_command.
- */
-static int vicam_read_frame(struct gspca_dev *gspca_dev, u8 *data, int size)
-{
- int ret, unscaled_height, act_len = 0;
- u8 *req_data = gspca_dev->usb_buf;
- s32 expo = v4l2_ctrl_g_ctrl(gspca_dev->exposure);
- s32 gain = v4l2_ctrl_g_ctrl(gspca_dev->gain);
-
- memset(req_data, 0, 16);
- req_data[0] = gain;
- if (gspca_dev->width == 256)
- req_data[1] |= 0x01; /* low nibble x-scale */
- if (gspca_dev->height <= 122) {
- req_data[1] |= 0x10; /* high nibble y-scale */
- unscaled_height = gspca_dev->height * 2;
- } else
- unscaled_height = gspca_dev->height;
- req_data[2] = 0x90; /* unknown, does not seem to do anything */
- if (unscaled_height <= 200)
- req_data[3] = 0x06; /* vend? */
- else if (unscaled_height <= 242) /* Yes 242 not 240 */
- req_data[3] = 0x07; /* vend? */
- else /* Up to 244 lines with req_data[3] == 0x08 */
- req_data[3] = 0x08; /* vend? */
-
- if (expo < 256) {
- /* Frame rate maxed out, use partial frame expo time */
- req_data[4] = 255 - expo;
- req_data[5] = 0x00;
- req_data[6] = 0x00;
- req_data[7] = 0x01;
- } else {
- /* Modify frame rate */
- req_data[4] = 0x00;
- req_data[5] = 0x00;
- req_data[6] = expo & 0xFF;
- req_data[7] = expo >> 8;
- }
- req_data[8] = ((244 - unscaled_height) / 2) & ~0x01; /* vstart */
- /* bytes 9-15 do not seem to affect exposure or image quality */
-
- mutex_lock(&gspca_dev->usb_lock);
- ret = vicam_control_msg(gspca_dev, 0x51, 0x80, 0, req_data, 16);
- mutex_unlock(&gspca_dev->usb_lock);
- if (ret < 0)
- return ret;
-
- ret = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev, 0x81),
- data, size, &act_len, 10000);
- /* successful, it returns 0, otherwise negative */
- if (ret < 0 || act_len != size) {
- pr_err("bulk read fail (%d) len %d/%d\n",
- ret, act_len, size);
- return -EIO;
- }
- return 0;
-}
-
-/* This function is called as a workqueue function and runs whenever the camera
- * is streaming data. Because it is a workqueue function it is allowed to sleep
- * so we can use synchronous USB calls. To avoid possible collisions with other
- * threads attempting to use the camera's USB interface we take the gspca
- * usb_lock when performing USB operations. In practice the only thing we need
- * to protect against is the usb_set_interface call that gspca makes during
- * stream_off as the camera doesn't provide any controls that the user could try
- * to change.
- */
-static void vicam_dostream(struct work_struct *work)
-{
- struct sd *sd = container_of(work, struct sd, work_struct);
- struct gspca_dev *gspca_dev = &sd->gspca_dev;
- int ret, frame_sz;
- u8 *buffer;
-
- frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage +
- HEADER_SIZE;
- buffer = kmalloc(frame_sz, GFP_KERNEL | GFP_DMA);
- if (!buffer) {
- pr_err("Couldn't allocate USB buffer\n");
- goto exit;
- }
-
- while (gspca_dev->dev && gspca_dev->streaming) {
-#ifdef CONFIG_PM
- if (gspca_dev->frozen)
- break;
-#endif
- ret = vicam_read_frame(gspca_dev, buffer, frame_sz);
- if (ret < 0)
- break;
-
- /* Note the frame header contents seem to be completely
- constant, they do not change with either image, or
- settings. So we simply discard it. The frames have
- a very similar 64 byte footer, which we don't even
- bother reading from the cam */
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- buffer + HEADER_SIZE,
- frame_sz - HEADER_SIZE);
- gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
- }
-exit:
- kfree(buffer);
-}
-
-/* This function is called at probe time just before sd_init */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct cam *cam = &gspca_dev->cam;
- struct sd *sd = (struct sd *)gspca_dev;
-
- /* We don't use the buffer gspca allocates so make it small. */
- cam->bulk = 1;
- cam->bulk_size = 64;
- cam->cam_mode = vicam_mode;
- cam->nmodes = ARRAY_SIZE(vicam_mode);
-
- INIT_WORK(&sd->work_struct, vicam_dostream);
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- int ret;
- const struct ihex_binrec *rec;
- const struct firmware *uninitialized_var(fw);
- u8 *firmware_buf;
-
- ret = request_ihex_firmware(&fw, VICAM_FIRMWARE,
- &gspca_dev->dev->dev);
- if (ret) {
- pr_err("Failed to load \"vicam/firmware.fw\": %d\n", ret);
- return ret;
- }
-
- firmware_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (!firmware_buf) {
- ret = -ENOMEM;
- goto exit;
- }
- for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
- memcpy(firmware_buf, rec->data, be16_to_cpu(rec->len));
- ret = vicam_control_msg(gspca_dev, 0xff, 0, 0, firmware_buf,
- be16_to_cpu(rec->len));
- if (ret < 0)
- break;
- }
-
- kfree(firmware_buf);
-exit:
- release_firmware(fw);
- return ret;
-}
-
-/* Set up for getting frames. */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- int ret;
-
- ret = vicam_set_camera_power(gspca_dev, 1);
- if (ret < 0)
- return ret;
-
- /* Start the workqueue function to do the streaming */
- sd->work_thread = create_singlethread_workqueue(MODULE_NAME);
- queue_work(sd->work_thread, &sd->work_struct);
-
- return 0;
-}
-
-/* called on streamoff with alt==0 and on disconnect */
-/* the usb_lock is held at entry - restore on exit */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *dev = (struct sd *)gspca_dev;
-
- /* wait for the work queue to terminate */
- mutex_unlock(&gspca_dev->usb_lock);
- /* This waits for vicam_dostream to finish */
- destroy_workqueue(dev->work_thread);
- dev->work_thread = NULL;
- mutex_lock(&gspca_dev->usb_lock);
-
- if (gspca_dev->dev)
- vicam_set_camera_power(gspca_dev, 0);
-}
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 2);
- gspca_dev->exposure = v4l2_ctrl_new_std(hdl, NULL,
- V4L2_CID_EXPOSURE, 0, 2047, 1, 256);
- gspca_dev->gain = v4l2_ctrl_new_std(hdl, NULL,
- V4L2_CID_GAIN, 0, 255, 1, 200);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* Table of supported USB devices */
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x04c1, 0x009d)},
- {USB_DEVICE(0x0602, 0x1001)},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stop0 = sd_stop0,
-};
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id,
- &sd_desc,
- sizeof(struct sd),
- THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c
deleted file mode 100644
index 9e3a909e0a0..00000000000
--- a/drivers/media/video/gspca/w996Xcf.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/**
- *
- * GSPCA sub driver for W996[78]CF JPEG USB Dual Mode Camera Chip.
- *
- * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
- *
- * This module is adapted from the in kernel v4l1 w9968cf driver:
- *
- * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/* Note this is not a stand alone driver, it gets included in ov519.c, this
- is a bit of a hack, but it needs the driver code for a lot of different
- ov sensors which is already present in ov519.c (the old v4l1 driver used
- the ovchipcam framework). When we have the time we really should move
- the sensor drivers to v4l2 sub drivers, and properly split of this
- driver from ov519.c */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define W9968CF_I2C_BUS_DELAY 4 /* delay in us for I2C bit r/w operations */
-
-#define Y_QUANTABLE (&sd->jpeg_hdr[JPEG_QT0_OFFSET])
-#define UV_QUANTABLE (&sd->jpeg_hdr[JPEG_QT1_OFFSET])
-
-static const struct v4l2_pix_format w9968cf_vga_mode[] = {
- {160, 120, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
- .bytesperline = 160 * 2,
- .sizeimage = 160 * 120 * 2,
- .colorspace = V4L2_COLORSPACE_JPEG},
- {176, 144, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
- .bytesperline = 176 * 2,
- .sizeimage = 176 * 144 * 2,
- .colorspace = V4L2_COLORSPACE_JPEG},
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320 * 2,
- .sizeimage = 320 * 240 * 2,
- .colorspace = V4L2_COLORSPACE_JPEG},
- {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 352 * 2,
- .sizeimage = 352 * 288 * 2,
- .colorspace = V4L2_COLORSPACE_JPEG},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640 * 2,
- .sizeimage = 640 * 480 * 2,
- .colorspace = V4L2_COLORSPACE_JPEG},
-};
-
-static void reg_w(struct sd *sd, u16 index, u16 value);
-
-/*--------------------------------------------------------------------------
- Write 64-bit data to the fast serial bus registers.
- Return 0 on success, -1 otherwise.
- --------------------------------------------------------------------------*/
-static void w9968cf_write_fsb(struct sd *sd, u16* data)
-{
- struct usb_device *udev = sd->gspca_dev.dev;
- u16 value;
- int ret;
-
- if (sd->gspca_dev.usb_err < 0)
- return;
-
- value = *data++;
- memcpy(sd->gspca_dev.usb_buf, data, 6);
-
- ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
- USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
- value, 0x06, sd->gspca_dev.usb_buf, 6, 500);
- if (ret < 0) {
- pr_err("Write FSB registers failed (%d)\n", ret);
- sd->gspca_dev.usb_err = ret;
- }
-}
-
-/*--------------------------------------------------------------------------
- Write data to the serial bus control register.
- Return 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static void w9968cf_write_sb(struct sd *sd, u16 value)
-{
- int ret;
-
- if (sd->gspca_dev.usb_err < 0)
- return;
-
- /* We don't use reg_w here, as that would cause all writes when
- bitbanging i2c to be logged, making the logs impossible to read */
- ret = usb_control_msg(sd->gspca_dev.dev,
- usb_sndctrlpipe(sd->gspca_dev.dev, 0),
- 0,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, 0x01, NULL, 0, 500);
-
- udelay(W9968CF_I2C_BUS_DELAY);
-
- if (ret < 0) {
- pr_err("Write SB reg [01] %04x failed\n", value);
- sd->gspca_dev.usb_err = ret;
- }
-}
-
-/*--------------------------------------------------------------------------
- Read data from the serial bus control register.
- Return 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int w9968cf_read_sb(struct sd *sd)
-{
- int ret;
-
- if (sd->gspca_dev.usb_err < 0)
- return -1;
-
- /* We don't use reg_r here, as the w9968cf is special and has 16
- bit registers instead of 8 bit */
- ret = usb_control_msg(sd->gspca_dev.dev,
- usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
- 1,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, 0x01, sd->gspca_dev.usb_buf, 2, 500);
- if (ret >= 0) {
- ret = sd->gspca_dev.usb_buf[0] |
- (sd->gspca_dev.usb_buf[1] << 8);
- } else {
- pr_err("Read SB reg [01] failed\n");
- sd->gspca_dev.usb_err = ret;
- }
-
- udelay(W9968CF_I2C_BUS_DELAY);
-
- return ret;
-}
-
-/*--------------------------------------------------------------------------
- Upload quantization tables for the JPEG compression.
- This function is called by w9968cf_start_transfer().
- Return 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static void w9968cf_upload_quantizationtables(struct sd *sd)
-{
- u16 a, b;
- int i, j;
-
- reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */
-
- for (i = 0, j = 0; i < 32; i++, j += 2) {
- a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j + 1]) << 8);
- b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j + 1]) << 8);
- reg_w(sd, 0x40 + i, a);
- reg_w(sd, 0x60 + i, b);
- }
- reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */
-}
-
-/****************************************************************************
- * Low-level I2C I/O functions. *
- * The adapter supports the following I2C transfer functions: *
- * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) *
- * i2c_adap_read_byte_data() *
- * i2c_adap_read_byte() *
- ****************************************************************************/
-
-static void w9968cf_smbus_start(struct sd *sd)
-{
- w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
- w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
-}
-
-static void w9968cf_smbus_stop(struct sd *sd)
-{
- w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
- w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
- w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
-}
-
-static void w9968cf_smbus_write_byte(struct sd *sd, u8 v)
-{
- u8 bit;
- int sda;
-
- for (bit = 0 ; bit < 8 ; bit++) {
- sda = (v & 0x80) ? 2 : 0;
- v <<= 1;
- /* SDE=1, SDA=sda, SCL=0 */
- w9968cf_write_sb(sd, 0x10 | sda);
- /* SDE=1, SDA=sda, SCL=1 */
- w9968cf_write_sb(sd, 0x11 | sda);
- /* SDE=1, SDA=sda, SCL=0 */
- w9968cf_write_sb(sd, 0x10 | sda);
- }
-}
-
-static void w9968cf_smbus_read_byte(struct sd *sd, u8 *v)
-{
- u8 bit;
-
- /* No need to ensure SDA is high as we are always called after
- read_ack which ends with SDA high */
- *v = 0;
- for (bit = 0 ; bit < 8 ; bit++) {
- *v <<= 1;
- /* SDE=1, SDA=1, SCL=1 */
- w9968cf_write_sb(sd, 0x0013);
- *v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0;
- /* SDE=1, SDA=1, SCL=0 */
- w9968cf_write_sb(sd, 0x0012);
- }
-}
-
-static void w9968cf_smbus_write_nack(struct sd *sd)
-{
- /* No need to ensure SDA is high as we are always called after
- read_byte which ends with SDA high */
- w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
- w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
-}
-
-static void w9968cf_smbus_read_ack(struct sd *sd)
-{
- int sda;
-
- /* Ensure SDA is high before raising clock to avoid a spurious stop */
- w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
- w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
- sda = w9968cf_read_sb(sd);
- w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
- if (sda >= 0 && (sda & 0x08)) {
- PDEBUG(D_USBI, "Did not receive i2c ACK");
- sd->gspca_dev.usb_err = -EIO;
- }
-}
-
-/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
-static void w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
-{
- u16* data = (u16 *)sd->gspca_dev.usb_buf;
-
- data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0);
- data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0;
- data[1] = 0x2082 | ((sd->sensor_addr & 0x40) ? 0x0005 : 0x0);
- data[1] |= (sd->sensor_addr & 0x20) ? 0x0150 : 0x0;
- data[1] |= (sd->sensor_addr & 0x10) ? 0x5400 : 0x0;
- data[2] = 0x8208 | ((sd->sensor_addr & 0x08) ? 0x0015 : 0x0);
- data[2] |= (sd->sensor_addr & 0x04) ? 0x0540 : 0x0;
- data[2] |= (sd->sensor_addr & 0x02) ? 0x5000 : 0x0;
- data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0);
- data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0;
-
- w9968cf_write_fsb(sd, data);
-
- data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0);
- data[0] |= (reg & 0x40) ? 0x0540 : 0x0;
- data[0] |= (reg & 0x20) ? 0x5000 : 0x0;
- data[1] = 0x0820 | ((reg & 0x20) ? 0x0001 : 0x0);
- data[1] |= (reg & 0x10) ? 0x0054 : 0x0;
- data[1] |= (reg & 0x08) ? 0x1500 : 0x0;
- data[1] |= (reg & 0x04) ? 0x4000 : 0x0;
- data[2] = 0x2082 | ((reg & 0x04) ? 0x0005 : 0x0);
- data[2] |= (reg & 0x02) ? 0x0150 : 0x0;
- data[2] |= (reg & 0x01) ? 0x5400 : 0x0;
- data[3] = 0x001d;
-
- w9968cf_write_fsb(sd, data);
-
- data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
- data[0] |= (value & 0x40) ? 0x0540 : 0x0;
- data[0] |= (value & 0x20) ? 0x5000 : 0x0;
- data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
- data[1] |= (value & 0x10) ? 0x0054 : 0x0;
- data[1] |= (value & 0x08) ? 0x1500 : 0x0;
- data[1] |= (value & 0x04) ? 0x4000 : 0x0;
- data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
- data[2] |= (value & 0x02) ? 0x0150 : 0x0;
- data[2] |= (value & 0x01) ? 0x5400 : 0x0;
- data[3] = 0xfe1d;
-
- w9968cf_write_fsb(sd, data);
-
- PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
-}
-
-/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
-static int w9968cf_i2c_r(struct sd *sd, u8 reg)
-{
- int ret = 0;
- u8 value;
-
- /* Fast serial bus data control disable */
- w9968cf_write_sb(sd, 0x0013); /* don't change ! */
-
- w9968cf_smbus_start(sd);
- w9968cf_smbus_write_byte(sd, sd->sensor_addr);
- w9968cf_smbus_read_ack(sd);
- w9968cf_smbus_write_byte(sd, reg);
- w9968cf_smbus_read_ack(sd);
- w9968cf_smbus_stop(sd);
- w9968cf_smbus_start(sd);
- w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
- w9968cf_smbus_read_ack(sd);
- w9968cf_smbus_read_byte(sd, &value);
- /* signal we don't want to read anymore, the v4l1 driver used to
- send an ack here which is very wrong! (and then fixed
- the issues this gave by retrying reads) */
- w9968cf_smbus_write_nack(sd);
- w9968cf_smbus_stop(sd);
-
- /* Fast serial bus data control re-enable */
- w9968cf_write_sb(sd, 0x0030);
-
- if (sd->gspca_dev.usb_err >= 0) {
- ret = value;
- PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
- } else
- PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
-
- return ret;
-}
-
-/*--------------------------------------------------------------------------
- Turn on the LED on some webcams. A beep should be heard too.
- Return 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static void w9968cf_configure(struct sd *sd)
-{
- reg_w(sd, 0x00, 0xff00); /* power-down */
- reg_w(sd, 0x00, 0xbf17); /* reset everything */
- reg_w(sd, 0x00, 0xbf10); /* normal operation */
- reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */
- reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */
- reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */
- reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */
-
- sd->stopped = 1;
-}
-
-static void w9968cf_init(struct sd *sd)
-{
- unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2),
- y0 = 0x0000,
- u0 = y0 + hw_bufsize / 2,
- v0 = u0 + hw_bufsize / 4,
- y1 = v0 + hw_bufsize / 4,
- u1 = y1 + hw_bufsize / 2,
- v1 = u1 + hw_bufsize / 4;
-
- reg_w(sd, 0x00, 0xff00); /* power off */
- reg_w(sd, 0x00, 0xbf10); /* power on */
-
- reg_w(sd, 0x03, 0x405d); /* DRAM timings */
- reg_w(sd, 0x04, 0x0030); /* SDRAM timings */
-
- reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */
- reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */
- reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */
- reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */
- reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */
- reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */
-
- reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */
- reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */
- reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */
- reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */
- reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */
- reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */
-
- reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */
- reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */
-
- reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */
- reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */
-
- reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */
- reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/
- reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */
- reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */
-}
-
-static void w9968cf_set_crop_window(struct sd *sd)
-{
- int start_cropx, start_cropy, x, y, fw, fh, cw, ch,
- max_width, max_height;
-
- if (sd->sif) {
- max_width = 352;
- max_height = 288;
- } else {
- max_width = 640;
- max_height = 480;
- }
-
- if (sd->sensor == SEN_OV7620) {
- /*
- * Sigh, this is dependend on the clock / framerate changes
- * made by the frequency control, sick.
- *
- * Note we cannot use v4l2_ctrl_g_ctrl here, as we get called
- * from ov519.c:setfreq() with the ctrl lock held!
- */
- if (sd->freq->val == 1) {
- start_cropx = 277;
- start_cropy = 37;
- } else {
- start_cropx = 105;
- start_cropy = 37;
- }
- } else {
- start_cropx = 320;
- start_cropy = 35;
- }
-
- /* Work around to avoid FP arithmetics */
- #define SC(x) ((x) << 10)
-
- /* Scaling factors */
- fw = SC(sd->gspca_dev.width) / max_width;
- fh = SC(sd->gspca_dev.height) / max_height;
-
- cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width) / fh;
- ch = (fw >= fh) ? SC(sd->gspca_dev.height) / fw : max_height;
-
- sd->sensor_width = max_width;
- sd->sensor_height = max_height;
-
- x = (max_width - cw) / 2;
- y = (max_height - ch) / 2;
-
- reg_w(sd, 0x10, start_cropx + x);
- reg_w(sd, 0x11, start_cropy + y);
- reg_w(sd, 0x12, start_cropx + x + cw);
- reg_w(sd, 0x13, start_cropy + y + ch);
-}
-
-static void w9968cf_mode_init_regs(struct sd *sd)
-{
- int val, vs_polarity, hs_polarity;
-
- w9968cf_set_crop_window(sd);
-
- reg_w(sd, 0x14, sd->gspca_dev.width);
- reg_w(sd, 0x15, sd->gspca_dev.height);
-
- /* JPEG width & height */
- reg_w(sd, 0x30, sd->gspca_dev.width);
- reg_w(sd, 0x31, sd->gspca_dev.height);
-
- /* Y & UV frame buffer strides (in WORD) */
- if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
- V4L2_PIX_FMT_JPEG) {
- reg_w(sd, 0x2c, sd->gspca_dev.width / 2);
- reg_w(sd, 0x2d, sd->gspca_dev.width / 4);
- } else
- reg_w(sd, 0x2c, sd->gspca_dev.width);
-
- reg_w(sd, 0x00, 0xbf17); /* reset everything */
- reg_w(sd, 0x00, 0xbf10); /* normal operation */
-
- /* Transfer size in WORDS (for UYVY format only) */
- val = sd->gspca_dev.width * sd->gspca_dev.height;
- reg_w(sd, 0x3d, val & 0xffff); /* low bits */
- reg_w(sd, 0x3e, val >> 16); /* high bits */
-
- if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
- V4L2_PIX_FMT_JPEG) {
- /* We may get called multiple times (usb isoc bw negotiat.) */
- jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height,
- sd->gspca_dev.width, 0x22); /* JPEG 420 */
- jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
- w9968cf_upload_quantizationtables(sd);
- v4l2_ctrl_grab(sd->jpegqual, true);
- }
-
- /* Video Capture Control Register */
- if (sd->sensor == SEN_OV7620) {
- /* Seems to work around a bug in the image sensor */
- vs_polarity = 1;
- hs_polarity = 1;
- } else {
- vs_polarity = 1;
- hs_polarity = 0;
- }
-
- val = (vs_polarity << 12) | (hs_polarity << 11);
-
- /* NOTE: We may not have enough memory to do double buffering while
- doing compression (amount of memory differs per model cam).
- So we use the second image buffer also as jpeg stream buffer
- (see w9968cf_init), and disable double buffering. */
- if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
- V4L2_PIX_FMT_JPEG) {
- /* val |= 0x0002; YUV422P */
- val |= 0x0003; /* YUV420P */
- } else
- val |= 0x0080; /* Enable HW double buffering */
-
- /* val |= 0x0020; enable clamping */
- /* val |= 0x0008; enable (1-2-1) filter */
- /* val |= 0x000c; enable (2-3-6-3-2) filter */
-
- val |= 0x8000; /* capt. enable */
-
- reg_w(sd, 0x16, val);
-
- sd->gspca_dev.empty_packet = 0;
-}
-
-static void w9968cf_stop0(struct sd *sd)
-{
- v4l2_ctrl_grab(sd->jpegqual, false);
- reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
- reg_w(sd, 0x16, 0x0000); /* stop video capture */
-}
-
-/* The w9968cf docs say that a 0 sized packet means EOF (and also SOF
- for the next frame). This seems to simply not be true when operating
- in JPEG mode, in this case there may be empty packets within the
- frame. So in JPEG mode use the JPEG SOI marker to detect SOF.
-
- Note to make things even more interesting the w9968cf sends *PLANAR* jpeg,
- to be precise it sends: SOI, SOF, DRI, SOS, Y-data, SOS, U-data, SOS,
- V-data, EOI. */
-static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* isoc packet */
- int len) /* iso packet length */
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (w9968cf_vga_mode[gspca_dev->curr_mode].pixelformat ==
- V4L2_PIX_FMT_JPEG) {
- if (len >= 2 &&
- data[0] == 0xff &&
- data[1] == 0xd8) {
- gspca_frame_add(gspca_dev, LAST_PACKET,
- NULL, 0);
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sd->jpeg_hdr, JPEG_HDR_SZ);
- /* Strip the ff d8, our own header (which adds
- huffman and quantization tables) already has this */
- len -= 2;
- data += 2;
- }
- } else {
- /* In UYVY mode an empty packet signals EOF */
- if (gspca_dev->empty_packet) {
- gspca_frame_add(gspca_dev, LAST_PACKET,
- NULL, 0);
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- NULL, 0);
- gspca_dev->empty_packet = 0;
- }
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/video/gspca/xirlink_cit.c
deleted file mode 100644
index 13b8d395d21..00000000000
--- a/drivers/media/video/gspca/xirlink_cit.c
+++ /dev/null
@@ -1,3145 +0,0 @@
-/*
- * USB IBM C-It Video Camera driver
- *
- * Supports Xirlink C-It Video Camera, IBM PC Camera,
- * IBM NetCamera and Veo Stingray.
- *
- * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
- *
- * This driver is based on earlier work of:
- *
- * (C) Copyright 1999 Johannes Erdfelt
- * (C) Copyright 1999 Randy Dunlap
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define MODULE_NAME "xirlink-cit"
-
-#include <linux/input.h>
-#include "gspca.h"
-
-MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
-MODULE_DESCRIPTION("Xirlink C-IT");
-MODULE_LICENSE("GPL");
-
-/* FIXME we should autodetect this */
-static int ibm_netcam_pro;
-module_param(ibm_netcam_pro, int, 0);
-MODULE_PARM_DESC(ibm_netcam_pro,
- "Use IBM Netcamera Pro init sequences for Model 3 cams");
-
-/* FIXME this should be handled through the V4L2 input selection API */
-static int rca_input;
-module_param(rca_input, int, 0644);
-MODULE_PARM_DESC(rca_input,
- "Use rca input instead of ccd sensor on Model 3 cams");
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
- struct v4l2_ctrl *lighting;
- u8 model;
-#define CIT_MODEL0 0 /* bcd version 0.01 cams ie the xvp-500 */
-#define CIT_MODEL1 1 /* The model 1 - 4 nomenclature comes from the old */
-#define CIT_MODEL2 2 /* ibmcam driver */
-#define CIT_MODEL3 3
-#define CIT_MODEL4 4
-#define CIT_IBM_NETCAM_PRO 5
- u8 input_index;
- u8 button_state;
- u8 stop_on_control_change;
- u8 sof_read;
- u8 sof_len;
-};
-
-static void sd_stop0(struct gspca_dev *gspca_dev);
-
-static const struct v4l2_pix_format cif_yuv_mode[] = {
- {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 2 + 4,
- .colorspace = V4L2_COLORSPACE_SRGB},
- {352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 3 / 2 + 4,
- .colorspace = V4L2_COLORSPACE_SRGB},
-};
-
-static const struct v4l2_pix_format vga_yuv_mode[] = {
- {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 2 + 4,
- .colorspace = V4L2_COLORSPACE_SRGB},
- {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 2 + 4,
- .colorspace = V4L2_COLORSPACE_SRGB},
- {640, 480, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 2 + 4,
- .colorspace = V4L2_COLORSPACE_SRGB},
-};
-
-static const struct v4l2_pix_format model0_mode[] = {
- {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 2 + 4,
- .colorspace = V4L2_COLORSPACE_SRGB},
- {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 2 + 4,
- .colorspace = V4L2_COLORSPACE_SRGB},
- {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 2 + 4,
- .colorspace = V4L2_COLORSPACE_SRGB},
-};
-
-static const struct v4l2_pix_format model2_mode[] = {
- {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
- .bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 2 + 4,
- .colorspace = V4L2_COLORSPACE_SRGB},
- {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 2 + 4,
- .colorspace = V4L2_COLORSPACE_SRGB},
- {320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 + 4,
- .colorspace = V4L2_COLORSPACE_SRGB},
- {352, 288, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 + 4,
- .colorspace = V4L2_COLORSPACE_SRGB},
-};
-
-/*
- * 01.01.08 - Added for RCA video in support -LO
- * This struct is used to init the Model3 cam to use the RCA video in port
- * instead of the CCD sensor.
- */
-static const u16 rca_initdata[][3] = {
- {0, 0x0000, 0x010c},
- {0, 0x0006, 0x012c},
- {0, 0x0078, 0x012d},
- {0, 0x0046, 0x012f},
- {0, 0xd141, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfea8, 0x0124},
- {1, 0x0000, 0x0116},
- {0, 0x0064, 0x0116},
- {1, 0x0000, 0x0115},
- {0, 0x0003, 0x0115},
- {0, 0x0008, 0x0123},
- {0, 0x0000, 0x0117},
- {0, 0x0000, 0x0112},
- {0, 0x0080, 0x0100},
- {0, 0x0000, 0x0100},
- {1, 0x0000, 0x0116},
- {0, 0x0060, 0x0116},
- {0, 0x0002, 0x0112},
- {0, 0x0000, 0x0123},
- {0, 0x0001, 0x0117},
- {0, 0x0040, 0x0108},
- {0, 0x0019, 0x012c},
- {0, 0x0040, 0x0116},
- {0, 0x000a, 0x0115},
- {0, 0x000b, 0x0115},
- {0, 0x0078, 0x012d},
- {0, 0x0046, 0x012f},
- {0, 0xd141, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfea8, 0x0124},
- {0, 0x0064, 0x0116},
- {0, 0x0000, 0x0115},
- {0, 0x0001, 0x0115},
- {0, 0xffff, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x00aa, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xffff, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x00f2, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x000f, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xffff, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x00f8, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x00fc, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xffff, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x00f9, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x003c, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xffff, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0027, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0019, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0021, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0006, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0045, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x002a, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x000e, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x002b, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x00f4, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x002c, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0004, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x002d, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0014, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x002e, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0003, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x002f, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0003, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0014, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0040, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0040, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0053, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0x0000, 0x0101},
- {0, 0x00a0, 0x0103},
- {0, 0x0078, 0x0105},
- {0, 0x0000, 0x010a},
- {0, 0x0024, 0x010b},
- {0, 0x0028, 0x0119},
- {0, 0x0088, 0x011b},
- {0, 0x0002, 0x011d},
- {0, 0x0003, 0x011e},
- {0, 0x0000, 0x0129},
- {0, 0x00fc, 0x012b},
- {0, 0x0008, 0x0102},
- {0, 0x0000, 0x0104},
- {0, 0x0008, 0x011a},
- {0, 0x0028, 0x011c},
- {0, 0x0021, 0x012a},
- {0, 0x0000, 0x0118},
- {0, 0x0000, 0x0132},
- {0, 0x0000, 0x0109},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0031, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0040, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0040, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x00dc, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0032, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0020, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0001, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0040, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0040, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0037, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0030, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0xfff9, 0x0124},
- {0, 0x0086, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0038, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0008, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0x0000, 0x0127},
- {0, 0xfff8, 0x0124},
- {0, 0xfffd, 0x0124},
- {0, 0xfffa, 0x0124},
- {0, 0x0003, 0x0111},
-};
-
-/* TESTME the old ibmcam driver repeats certain commands to Model1 cameras, we
- do the same for now (testing needed to see if this is really necessary) */
-static const int cit_model1_ntries = 5;
-static const int cit_model1_ntries2 = 2;
-
-static int cit_write_reg(struct gspca_dev *gspca_dev, u16 value, u16 index)
-{
- struct usb_device *udev = gspca_dev->dev;
- int err;
-
- err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
- value, index, NULL, 0, 1000);
- if (err < 0)
- pr_err("Failed to write a register (index 0x%04X, value 0x%02X, error %d)\n",
- index, value, err);
-
- return 0;
-}
-
-static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index, int verbose)
-{
- struct usb_device *udev = gspca_dev->dev;
- __u8 *buf = gspca_dev->usb_buf;
- int res;
-
- res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x01,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
- 0x00, index, buf, 8, 1000);
- if (res < 0) {
- pr_err("Failed to read a register (index 0x%04X, error %d)\n",
- index, res);
- return res;
- }
-
- if (verbose)
- PDEBUG(D_PROBE, "Register %04x value: %02x", index, buf[0]);
-
- return 0;
-}
-
-/*
- * cit_send_FF_04_02()
- *
- * This procedure sends magic 3-command prefix to the camera.
- * The purpose of this prefix is not known.
- *
- * History:
- * 1/2/00 Created.
- */
-static void cit_send_FF_04_02(struct gspca_dev *gspca_dev)
-{
- cit_write_reg(gspca_dev, 0x00FF, 0x0127);
- cit_write_reg(gspca_dev, 0x0004, 0x0124);
- cit_write_reg(gspca_dev, 0x0002, 0x0124);
-}
-
-static void cit_send_00_04_06(struct gspca_dev *gspca_dev)
-{
- cit_write_reg(gspca_dev, 0x0000, 0x0127);
- cit_write_reg(gspca_dev, 0x0004, 0x0124);
- cit_write_reg(gspca_dev, 0x0006, 0x0124);
-}
-
-static void cit_send_x_00(struct gspca_dev *gspca_dev, unsigned short x)
-{
- cit_write_reg(gspca_dev, x, 0x0127);
- cit_write_reg(gspca_dev, 0x0000, 0x0124);
-}
-
-static void cit_send_x_00_05(struct gspca_dev *gspca_dev, unsigned short x)
-{
- cit_send_x_00(gspca_dev, x);
- cit_write_reg(gspca_dev, 0x0005, 0x0124);
-}
-
-static void cit_send_x_00_05_02(struct gspca_dev *gspca_dev, unsigned short x)
-{
- cit_write_reg(gspca_dev, x, 0x0127);
- cit_write_reg(gspca_dev, 0x0000, 0x0124);
- cit_write_reg(gspca_dev, 0x0005, 0x0124);
- cit_write_reg(gspca_dev, 0x0002, 0x0124);
-}
-
-static void cit_send_x_01_00_05(struct gspca_dev *gspca_dev, u16 x)
-{
- cit_write_reg(gspca_dev, x, 0x0127);
- cit_write_reg(gspca_dev, 0x0001, 0x0124);
- cit_write_reg(gspca_dev, 0x0000, 0x0124);
- cit_write_reg(gspca_dev, 0x0005, 0x0124);
-}
-
-static void cit_send_x_00_05_02_01(struct gspca_dev *gspca_dev, u16 x)
-{
- cit_write_reg(gspca_dev, x, 0x0127);
- cit_write_reg(gspca_dev, 0x0000, 0x0124);
- cit_write_reg(gspca_dev, 0x0005, 0x0124);
- cit_write_reg(gspca_dev, 0x0002, 0x0124);
- cit_write_reg(gspca_dev, 0x0001, 0x0124);
-}
-
-static void cit_send_x_00_05_02_08_01(struct gspca_dev *gspca_dev, u16 x)
-{
- cit_write_reg(gspca_dev, x, 0x0127);
- cit_write_reg(gspca_dev, 0x0000, 0x0124);
- cit_write_reg(gspca_dev, 0x0005, 0x0124);
- cit_write_reg(gspca_dev, 0x0002, 0x0124);
- cit_write_reg(gspca_dev, 0x0008, 0x0124);
- cit_write_reg(gspca_dev, 0x0001, 0x0124);
-}
-
-static void cit_Packet_Format1(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
-{
- cit_send_x_01_00_05(gspca_dev, 0x0088);
- cit_send_x_00_05(gspca_dev, fkey);
- cit_send_x_00_05_02_08_01(gspca_dev, val);
- cit_send_x_00_05(gspca_dev, 0x0088);
- cit_send_x_00_05_02_01(gspca_dev, fkey);
- cit_send_x_00_05(gspca_dev, 0x0089);
- cit_send_x_00(gspca_dev, fkey);
- cit_send_00_04_06(gspca_dev);
- cit_read_reg(gspca_dev, 0x0126, 0);
- cit_send_FF_04_02(gspca_dev);
-}
-
-static void cit_PacketFormat2(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
-{
- cit_send_x_01_00_05(gspca_dev, 0x0088);
- cit_send_x_00_05(gspca_dev, fkey);
- cit_send_x_00_05_02(gspca_dev, val);
-}
-
-static void cit_model2_Packet2(struct gspca_dev *gspca_dev)
-{
- cit_write_reg(gspca_dev, 0x00ff, 0x012d);
- cit_write_reg(gspca_dev, 0xfea3, 0x0124);
-}
-
-static void cit_model2_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
-{
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x00ff, 0x012e);
- cit_write_reg(gspca_dev, v1, 0x012f);
- cit_write_reg(gspca_dev, 0x00ff, 0x0130);
- cit_write_reg(gspca_dev, 0xc719, 0x0124);
- cit_write_reg(gspca_dev, v2, 0x0127);
-
- cit_model2_Packet2(gspca_dev);
-}
-
-/*
- * cit_model3_Packet1()
- *
- * 00_0078_012d
- * 00_0097_012f
- * 00_d141_0124
- * 00_0096_0127
- * 00_fea8_0124
-*/
-static void cit_model3_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
-{
- cit_write_reg(gspca_dev, 0x0078, 0x012d);
- cit_write_reg(gspca_dev, v1, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, v2, 0x0127);
- cit_write_reg(gspca_dev, 0xfea8, 0x0124);
-}
-
-static void cit_model4_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
-{
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, v1, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, v2, 0x0127);
- cit_write_reg(gspca_dev, 0xfea8, 0x0124);
-}
-
-static void cit_model4_BrightnessPacket(struct gspca_dev *gspca_dev, u16 val)
-{
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x0026, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, val, 0x0127);
- cit_write_reg(gspca_dev, 0x00aa, 0x0130);
- cit_write_reg(gspca_dev, 0x82a8, 0x0124);
- cit_write_reg(gspca_dev, 0x0038, 0x012d);
- cit_write_reg(gspca_dev, 0x0004, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0xfffa, 0x0124);
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
-
- sd->model = id->driver_info;
- if (sd->model == CIT_MODEL3 && ibm_netcam_pro)
- sd->model = CIT_IBM_NETCAM_PRO;
-
- cam = &gspca_dev->cam;
- switch (sd->model) {
- case CIT_MODEL0:
- cam->cam_mode = model0_mode;
- cam->nmodes = ARRAY_SIZE(model0_mode);
- sd->sof_len = 4;
- break;
- case CIT_MODEL1:
- cam->cam_mode = cif_yuv_mode;
- cam->nmodes = ARRAY_SIZE(cif_yuv_mode);
- sd->sof_len = 4;
- break;
- case CIT_MODEL2:
- cam->cam_mode = model2_mode + 1; /* no 160x120 */
- cam->nmodes = 3;
- break;
- case CIT_MODEL3:
- cam->cam_mode = vga_yuv_mode;
- cam->nmodes = ARRAY_SIZE(vga_yuv_mode);
- sd->stop_on_control_change = 1;
- sd->sof_len = 4;
- break;
- case CIT_MODEL4:
- cam->cam_mode = model2_mode;
- cam->nmodes = ARRAY_SIZE(model2_mode);
- break;
- case CIT_IBM_NETCAM_PRO:
- cam->cam_mode = vga_yuv_mode;
- cam->nmodes = 2; /* no 640 x 480 */
- cam->input_flags = V4L2_IN_ST_VFLIP;
- sd->stop_on_control_change = 1;
- sd->sof_len = 4;
- break;
- }
-
- return 0;
-}
-
-static int cit_init_model0(struct gspca_dev *gspca_dev)
-{
- cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
- cit_write_reg(gspca_dev, 0x0001, 0x0112); /* turn on autogain ? */
- cit_write_reg(gspca_dev, 0x0000, 0x0400);
- cit_write_reg(gspca_dev, 0x0001, 0x0400);
- cit_write_reg(gspca_dev, 0x0000, 0x0420);
- cit_write_reg(gspca_dev, 0x0001, 0x0420);
- cit_write_reg(gspca_dev, 0x000d, 0x0409);
- cit_write_reg(gspca_dev, 0x0002, 0x040a);
- cit_write_reg(gspca_dev, 0x0018, 0x0405);
- cit_write_reg(gspca_dev, 0x0008, 0x0435);
- cit_write_reg(gspca_dev, 0x0026, 0x040b);
- cit_write_reg(gspca_dev, 0x0007, 0x0437);
- cit_write_reg(gspca_dev, 0x0015, 0x042f);
- cit_write_reg(gspca_dev, 0x002b, 0x0439);
- cit_write_reg(gspca_dev, 0x0026, 0x043a);
- cit_write_reg(gspca_dev, 0x0008, 0x0438);
- cit_write_reg(gspca_dev, 0x001e, 0x042b);
- cit_write_reg(gspca_dev, 0x0041, 0x042c);
-
- return 0;
-}
-
-static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev)
-{
- cit_read_reg(gspca_dev, 0x128, 1);
- cit_write_reg(gspca_dev, 0x0003, 0x0133);
- cit_write_reg(gspca_dev, 0x0000, 0x0117);
- cit_write_reg(gspca_dev, 0x0008, 0x0123);
- cit_write_reg(gspca_dev, 0x0000, 0x0100);
- cit_read_reg(gspca_dev, 0x0116, 0);
- cit_write_reg(gspca_dev, 0x0060, 0x0116);
- cit_write_reg(gspca_dev, 0x0002, 0x0112);
- cit_write_reg(gspca_dev, 0x0000, 0x0133);
- cit_write_reg(gspca_dev, 0x0000, 0x0123);
- cit_write_reg(gspca_dev, 0x0001, 0x0117);
- cit_write_reg(gspca_dev, 0x0040, 0x0108);
- cit_write_reg(gspca_dev, 0x0019, 0x012c);
- cit_write_reg(gspca_dev, 0x0060, 0x0116);
- cit_write_reg(gspca_dev, 0x0002, 0x0115);
- cit_write_reg(gspca_dev, 0x000b, 0x0115);
-
- cit_write_reg(gspca_dev, 0x0078, 0x012d);
- cit_write_reg(gspca_dev, 0x0001, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0079, 0x012d);
- cit_write_reg(gspca_dev, 0x00ff, 0x0130);
- cit_write_reg(gspca_dev, 0xcd41, 0x0124);
- cit_write_reg(gspca_dev, 0xfffa, 0x0124);
- cit_read_reg(gspca_dev, 0x0126, 1);
-
- cit_model3_Packet1(gspca_dev, 0x0000, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0000, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x000b, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x000c, 0x0008);
- cit_model3_Packet1(gspca_dev, 0x000d, 0x003a);
- cit_model3_Packet1(gspca_dev, 0x000e, 0x0060);
- cit_model3_Packet1(gspca_dev, 0x000f, 0x0060);
- cit_model3_Packet1(gspca_dev, 0x0010, 0x0008);
- cit_model3_Packet1(gspca_dev, 0x0011, 0x0004);
- cit_model3_Packet1(gspca_dev, 0x0012, 0x0028);
- cit_model3_Packet1(gspca_dev, 0x0013, 0x0002);
- cit_model3_Packet1(gspca_dev, 0x0014, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0015, 0x00fb);
- cit_model3_Packet1(gspca_dev, 0x0016, 0x0002);
- cit_model3_Packet1(gspca_dev, 0x0017, 0x0037);
- cit_model3_Packet1(gspca_dev, 0x0018, 0x0036);
- cit_model3_Packet1(gspca_dev, 0x001e, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x001f, 0x0008);
- cit_model3_Packet1(gspca_dev, 0x0020, 0x00c1);
- cit_model3_Packet1(gspca_dev, 0x0021, 0x0034);
- cit_model3_Packet1(gspca_dev, 0x0022, 0x0034);
- cit_model3_Packet1(gspca_dev, 0x0025, 0x0002);
- cit_model3_Packet1(gspca_dev, 0x0028, 0x0022);
- cit_model3_Packet1(gspca_dev, 0x0029, 0x000a);
- cit_model3_Packet1(gspca_dev, 0x002b, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x002c, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x002d, 0x00ff);
- cit_model3_Packet1(gspca_dev, 0x002e, 0x00ff);
- cit_model3_Packet1(gspca_dev, 0x002f, 0x00ff);
- cit_model3_Packet1(gspca_dev, 0x0030, 0x00ff);
- cit_model3_Packet1(gspca_dev, 0x0031, 0x00ff);
- cit_model3_Packet1(gspca_dev, 0x0032, 0x0007);
- cit_model3_Packet1(gspca_dev, 0x0033, 0x0005);
- cit_model3_Packet1(gspca_dev, 0x0037, 0x0040);
- cit_model3_Packet1(gspca_dev, 0x0039, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x003a, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x003b, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x003c, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0040, 0x000c);
- cit_model3_Packet1(gspca_dev, 0x0041, 0x00fb);
- cit_model3_Packet1(gspca_dev, 0x0042, 0x0002);
- cit_model3_Packet1(gspca_dev, 0x0043, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0045, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0048, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x004a, 0x00ff);
- cit_model3_Packet1(gspca_dev, 0x004b, 0x00ff);
- cit_model3_Packet1(gspca_dev, 0x004c, 0x00ff);
- cit_model3_Packet1(gspca_dev, 0x004f, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0050, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0051, 0x0002);
- cit_model3_Packet1(gspca_dev, 0x0055, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0056, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0057, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0058, 0x0002);
- cit_model3_Packet1(gspca_dev, 0x0059, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x005c, 0x0016);
- cit_model3_Packet1(gspca_dev, 0x005d, 0x0022);
- cit_model3_Packet1(gspca_dev, 0x005e, 0x003c);
- cit_model3_Packet1(gspca_dev, 0x005f, 0x0050);
- cit_model3_Packet1(gspca_dev, 0x0060, 0x0044);
- cit_model3_Packet1(gspca_dev, 0x0061, 0x0005);
- cit_model3_Packet1(gspca_dev, 0x006a, 0x007e);
- cit_model3_Packet1(gspca_dev, 0x006f, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0072, 0x001b);
- cit_model3_Packet1(gspca_dev, 0x0073, 0x0005);
- cit_model3_Packet1(gspca_dev, 0x0074, 0x000a);
- cit_model3_Packet1(gspca_dev, 0x0075, 0x001b);
- cit_model3_Packet1(gspca_dev, 0x0076, 0x002a);
- cit_model3_Packet1(gspca_dev, 0x0077, 0x003c);
- cit_model3_Packet1(gspca_dev, 0x0078, 0x0050);
- cit_model3_Packet1(gspca_dev, 0x007b, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x007c, 0x0011);
- cit_model3_Packet1(gspca_dev, 0x007d, 0x0024);
- cit_model3_Packet1(gspca_dev, 0x007e, 0x0043);
- cit_model3_Packet1(gspca_dev, 0x007f, 0x005a);
- cit_model3_Packet1(gspca_dev, 0x0084, 0x0020);
- cit_model3_Packet1(gspca_dev, 0x0085, 0x0033);
- cit_model3_Packet1(gspca_dev, 0x0086, 0x000a);
- cit_model3_Packet1(gspca_dev, 0x0087, 0x0030);
- cit_model3_Packet1(gspca_dev, 0x0088, 0x0070);
- cit_model3_Packet1(gspca_dev, 0x008b, 0x0008);
- cit_model3_Packet1(gspca_dev, 0x008f, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0090, 0x0006);
- cit_model3_Packet1(gspca_dev, 0x0091, 0x0028);
- cit_model3_Packet1(gspca_dev, 0x0092, 0x005a);
- cit_model3_Packet1(gspca_dev, 0x0093, 0x0082);
- cit_model3_Packet1(gspca_dev, 0x0096, 0x0014);
- cit_model3_Packet1(gspca_dev, 0x0097, 0x0020);
- cit_model3_Packet1(gspca_dev, 0x0098, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00b0, 0x0046);
- cit_model3_Packet1(gspca_dev, 0x00b1, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00b2, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00b3, 0x0004);
- cit_model3_Packet1(gspca_dev, 0x00b4, 0x0007);
- cit_model3_Packet1(gspca_dev, 0x00b6, 0x0002);
- cit_model3_Packet1(gspca_dev, 0x00b7, 0x0004);
- cit_model3_Packet1(gspca_dev, 0x00bb, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00bc, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x00bd, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00bf, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00c0, 0x00c8);
- cit_model3_Packet1(gspca_dev, 0x00c1, 0x0014);
- cit_model3_Packet1(gspca_dev, 0x00c2, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x00c3, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00c4, 0x0004);
- cit_model3_Packet1(gspca_dev, 0x00cb, 0x00bf);
- cit_model3_Packet1(gspca_dev, 0x00cc, 0x00bf);
- cit_model3_Packet1(gspca_dev, 0x00cd, 0x00bf);
- cit_model3_Packet1(gspca_dev, 0x00ce, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00cf, 0x0020);
- cit_model3_Packet1(gspca_dev, 0x00d0, 0x0040);
- cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
- cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
- cit_model3_Packet1(gspca_dev, 0x00d2, 0x00bf);
- cit_model3_Packet1(gspca_dev, 0x00d3, 0x00bf);
- cit_model3_Packet1(gspca_dev, 0x00ea, 0x0008);
- cit_model3_Packet1(gspca_dev, 0x00eb, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00ec, 0x00e8);
- cit_model3_Packet1(gspca_dev, 0x00ed, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x00ef, 0x0022);
- cit_model3_Packet1(gspca_dev, 0x00f0, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00f2, 0x0028);
- cit_model3_Packet1(gspca_dev, 0x00f4, 0x0002);
- cit_model3_Packet1(gspca_dev, 0x00f5, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00fa, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00fb, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x00fc, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00fd, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00fe, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00ff, 0x0000);
-
- cit_model3_Packet1(gspca_dev, 0x00be, 0x0003);
- cit_model3_Packet1(gspca_dev, 0x00c8, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00c9, 0x0020);
- cit_model3_Packet1(gspca_dev, 0x00ca, 0x0040);
- cit_model3_Packet1(gspca_dev, 0x0053, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x0082, 0x000e);
- cit_model3_Packet1(gspca_dev, 0x0083, 0x0020);
- cit_model3_Packet1(gspca_dev, 0x0034, 0x003c);
- cit_model3_Packet1(gspca_dev, 0x006e, 0x0055);
- cit_model3_Packet1(gspca_dev, 0x0062, 0x0005);
- cit_model3_Packet1(gspca_dev, 0x0063, 0x0008);
- cit_model3_Packet1(gspca_dev, 0x0066, 0x000a);
- cit_model3_Packet1(gspca_dev, 0x0067, 0x0006);
- cit_model3_Packet1(gspca_dev, 0x006b, 0x0010);
- cit_model3_Packet1(gspca_dev, 0x005a, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x005b, 0x000a);
- cit_model3_Packet1(gspca_dev, 0x0023, 0x0006);
- cit_model3_Packet1(gspca_dev, 0x0026, 0x0004);
- cit_model3_Packet1(gspca_dev, 0x0036, 0x0069);
- cit_model3_Packet1(gspca_dev, 0x0038, 0x0064);
- cit_model3_Packet1(gspca_dev, 0x003d, 0x0003);
- cit_model3_Packet1(gspca_dev, 0x003e, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x00b8, 0x0014);
- cit_model3_Packet1(gspca_dev, 0x00b9, 0x0014);
- cit_model3_Packet1(gspca_dev, 0x00e6, 0x0004);
- cit_model3_Packet1(gspca_dev, 0x00e8, 0x0001);
-
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->model) {
- case CIT_MODEL0:
- cit_init_model0(gspca_dev);
- sd_stop0(gspca_dev);
- break;
- case CIT_MODEL1:
- case CIT_MODEL2:
- case CIT_MODEL3:
- case CIT_MODEL4:
- break; /* All is done in sd_start */
- case CIT_IBM_NETCAM_PRO:
- cit_init_ibm_netcam_pro(gspca_dev);
- sd_stop0(gspca_dev);
- break;
- }
- return 0;
-}
-
-static int cit_set_brightness(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
-
- switch (sd->model) {
- case CIT_MODEL0:
- case CIT_IBM_NETCAM_PRO:
- /* No (known) brightness control for these */
- break;
- case CIT_MODEL1:
- /* Model 1: Brightness range 0 - 63 */
- cit_Packet_Format1(gspca_dev, 0x0031, val);
- cit_Packet_Format1(gspca_dev, 0x0032, val);
- cit_Packet_Format1(gspca_dev, 0x0033, val);
- break;
- case CIT_MODEL2:
- /* Model 2: Brightness range 0x60 - 0xee */
- /* Scale 0 - 63 to 0x60 - 0xee */
- i = 0x60 + val * 2254 / 1000;
- cit_model2_Packet1(gspca_dev, 0x001a, i);
- break;
- case CIT_MODEL3:
- /* Model 3: Brightness range 'i' in [0x0C..0x3F] */
- i = val;
- if (i < 0x0c)
- i = 0x0c;
- cit_model3_Packet1(gspca_dev, 0x0036, i);
- break;
- case CIT_MODEL4:
- /* Model 4: Brightness range 'i' in [0x04..0xb4] */
- /* Scale 0 - 63 to 0x04 - 0xb4 */
- i = 0x04 + val * 2794 / 1000;
- cit_model4_BrightnessPacket(gspca_dev, i);
- break;
- }
-
- return 0;
-}
-
-static int cit_set_contrast(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->model) {
- case CIT_MODEL0: {
- int i;
- /* gain 0-15, 0-20 -> 0-15 */
- i = val * 1000 / 1333;
- cit_write_reg(gspca_dev, i, 0x0422);
- /* gain 0-31, may not be lower then 0x0422, 0-20 -> 0-31 */
- i = val * 2000 / 1333;
- cit_write_reg(gspca_dev, i, 0x0423);
- /* gain 0-127, may not be lower then 0x0423, 0-20 -> 0-63 */
- i = val * 4000 / 1333;
- cit_write_reg(gspca_dev, i, 0x0424);
- /* gain 0-127, may not be lower then 0x0424, , 0-20 -> 0-127 */
- i = val * 8000 / 1333;
- cit_write_reg(gspca_dev, i, 0x0425);
- break;
- }
- case CIT_MODEL2:
- case CIT_MODEL4:
- /* These models do not have this control. */
- break;
- case CIT_MODEL1:
- {
- /* Scale 0 - 20 to 15 - 0 */
- int i, new_contrast = (20 - val) * 1000 / 1333;
- for (i = 0; i < cit_model1_ntries; i++) {
- cit_Packet_Format1(gspca_dev, 0x0014, new_contrast);
- cit_send_FF_04_02(gspca_dev);
- }
- break;
- }
- case CIT_MODEL3:
- { /* Preset hardware values */
- static const struct {
- unsigned short cv1;
- unsigned short cv2;
- unsigned short cv3;
- } cv[7] = {
- { 0x05, 0x05, 0x0f }, /* Minimum */
- { 0x04, 0x04, 0x16 },
- { 0x02, 0x03, 0x16 },
- { 0x02, 0x08, 0x16 },
- { 0x01, 0x0c, 0x16 },
- { 0x01, 0x0e, 0x16 },
- { 0x01, 0x10, 0x16 } /* Maximum */
- };
- int i = val / 3;
- cit_model3_Packet1(gspca_dev, 0x0067, cv[i].cv1);
- cit_model3_Packet1(gspca_dev, 0x005b, cv[i].cv2);
- cit_model3_Packet1(gspca_dev, 0x005c, cv[i].cv3);
- break;
- }
- case CIT_IBM_NETCAM_PRO:
- cit_model3_Packet1(gspca_dev, 0x005b, val + 1);
- break;
- }
- return 0;
-}
-
-static int cit_set_hue(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->model) {
- case CIT_MODEL0:
- case CIT_MODEL1:
- case CIT_IBM_NETCAM_PRO:
- /* No hue control for these models */
- break;
- case CIT_MODEL2:
- cit_model2_Packet1(gspca_dev, 0x0024, val);
- /* cit_model2_Packet1(gspca_dev, 0x0020, sat); */
- break;
- case CIT_MODEL3: {
- /* Model 3: Brightness range 'i' in [0x05..0x37] */
- /* TESTME according to the ibmcam driver this does not work */
- if (0) {
- /* Scale 0 - 127 to 0x05 - 0x37 */
- int i = 0x05 + val * 1000 / 2540;
- cit_model3_Packet1(gspca_dev, 0x007e, i);
- }
- break;
- }
- case CIT_MODEL4:
- /* HDG: taken from ibmcam, setting the color gains does not
- * really belong here.
- *
- * I am not sure r/g/b_gain variables exactly control gain
- * of those channels. Most likely they subtly change some
- * very internal image processing settings in the camera.
- * In any case, here is what they do, and feel free to tweak:
- *
- * r_gain: seriously affects red gain
- * g_gain: seriously affects green gain
- * b_gain: seriously affects blue gain
- * hue: changes average color from violet (0) to red (0xFF)
- */
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x001e, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 160, 0x0127); /* Green gain */
- cit_write_reg(gspca_dev, 160, 0x012e); /* Red gain */
- cit_write_reg(gspca_dev, 160, 0x0130); /* Blue gain */
- cit_write_reg(gspca_dev, 0x8a28, 0x0124);
- cit_write_reg(gspca_dev, val, 0x012d); /* Hue */
- cit_write_reg(gspca_dev, 0xf545, 0x0124);
- break;
- }
- return 0;
-}
-
-static int cit_set_sharpness(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->model) {
- case CIT_MODEL0:
- case CIT_MODEL2:
- case CIT_MODEL4:
- case CIT_IBM_NETCAM_PRO:
- /* These models do not have this control */
- break;
- case CIT_MODEL1: {
- int i;
- const unsigned short sa[] = {
- 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a };
-
- for (i = 0; i < cit_model1_ntries; i++)
- cit_PacketFormat2(gspca_dev, 0x0013, sa[val]);
- break;
- }
- case CIT_MODEL3:
- { /*
- * "Use a table of magic numbers.
- * This setting doesn't really change much.
- * But that's how Windows does it."
- */
- static const struct {
- unsigned short sv1;
- unsigned short sv2;
- unsigned short sv3;
- unsigned short sv4;
- } sv[7] = {
- { 0x00, 0x00, 0x05, 0x14 }, /* Smoothest */
- { 0x01, 0x04, 0x05, 0x14 },
- { 0x02, 0x04, 0x05, 0x14 },
- { 0x03, 0x04, 0x05, 0x14 },
- { 0x03, 0x05, 0x05, 0x14 },
- { 0x03, 0x06, 0x05, 0x14 },
- { 0x03, 0x07, 0x05, 0x14 } /* Sharpest */
- };
- cit_model3_Packet1(gspca_dev, 0x0060, sv[val].sv1);
- cit_model3_Packet1(gspca_dev, 0x0061, sv[val].sv2);
- cit_model3_Packet1(gspca_dev, 0x0062, sv[val].sv3);
- cit_model3_Packet1(gspca_dev, 0x0063, sv[val].sv4);
- break;
- }
- }
- return 0;
-}
-
-/*
- * cit_set_lighting()
- *
- * Camera model 1:
- * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low.
- *
- * Camera model 2:
- * We have 16 levels of lighting, 0 for bright light and up to 15 for
- * low light. But values above 5 or so are useless because camera is
- * not really capable to produce anything worth viewing at such light.
- * This setting may be altered only in certain camera state.
- *
- * Low lighting forces slower FPS.
- *
- * History:
- * 1/5/00 Created.
- * 2/20/00 Added support for Model 2 cameras.
- */
-static void cit_set_lighting(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->model) {
- case CIT_MODEL0:
- case CIT_MODEL2:
- case CIT_MODEL3:
- case CIT_MODEL4:
- case CIT_IBM_NETCAM_PRO:
- break;
- case CIT_MODEL1: {
- int i;
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x0027, val);
- break;
- }
- }
-}
-
-static void cit_set_hflip(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->model) {
- case CIT_MODEL0:
- if (val)
- cit_write_reg(gspca_dev, 0x0020, 0x0115);
- else
- cit_write_reg(gspca_dev, 0x0040, 0x0115);
- break;
- case CIT_MODEL1:
- case CIT_MODEL2:
- case CIT_MODEL3:
- case CIT_MODEL4:
- case CIT_IBM_NETCAM_PRO:
- break;
- }
-}
-
-static int cit_restart_stream(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->model) {
- case CIT_MODEL0:
- case CIT_MODEL1:
- cit_write_reg(gspca_dev, 0x0001, 0x0114);
- /* Fall through */
- case CIT_MODEL2:
- case CIT_MODEL4:
- cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
- usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
- break;
- case CIT_MODEL3:
- case CIT_IBM_NETCAM_PRO:
- cit_write_reg(gspca_dev, 0x0001, 0x0114);
- cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
- usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
- /* Clear button events from while we were not streaming */
- cit_write_reg(gspca_dev, 0x0001, 0x0113);
- break;
- }
-
- sd->sof_read = 0;
-
- return 0;
-}
-
-static int cit_get_packet_size(struct gspca_dev *gspca_dev)
-{
- struct usb_host_interface *alt;
- struct usb_interface *intf;
-
- intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
- alt = usb_altnum_to_altsetting(intf, gspca_dev->alt);
- if (!alt) {
- pr_err("Couldn't get altsetting\n");
- return -EIO;
- }
-
- return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
-}
-
-/* Calculate the clockdiv giving us max fps given the available bandwidth */
-static int cit_get_clock_div(struct gspca_dev *gspca_dev)
-{
- int clock_div = 7; /* 0=30 1=25 2=20 3=15 4=12 5=7.5 6=6 7=3fps ?? */
- int fps[8] = { 30, 25, 20, 15, 12, 8, 6, 3 };
- int packet_size;
-
- packet_size = cit_get_packet_size(gspca_dev);
- if (packet_size < 0)
- return packet_size;
-
- while (clock_div > 3 &&
- 1000 * packet_size >
- gspca_dev->width * gspca_dev->height *
- fps[clock_div - 1] * 3 / 2)
- clock_div--;
-
- PDEBUG(D_PROBE,
- "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)",
- packet_size, gspca_dev->width, gspca_dev->height, clock_div,
- fps[clock_div]);
-
- return clock_div;
-}
-
-static int cit_start_model0(struct gspca_dev *gspca_dev)
-{
- const unsigned short compression = 0; /* 0=none, 7=best frame rate */
- int clock_div;
-
- clock_div = cit_get_clock_div(gspca_dev);
- if (clock_div < 0)
- return clock_div;
-
- cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
- cit_write_reg(gspca_dev, 0x0003, 0x0438);
- cit_write_reg(gspca_dev, 0x001e, 0x042b);
- cit_write_reg(gspca_dev, 0x0041, 0x042c);
- cit_write_reg(gspca_dev, 0x0008, 0x0436);
- cit_write_reg(gspca_dev, 0x0024, 0x0403);
- cit_write_reg(gspca_dev, 0x002c, 0x0404);
- cit_write_reg(gspca_dev, 0x0002, 0x0426);
- cit_write_reg(gspca_dev, 0x0014, 0x0427);
-
- switch (gspca_dev->width) {
- case 160: /* 160x120 */
- cit_write_reg(gspca_dev, 0x0004, 0x010b);
- cit_write_reg(gspca_dev, 0x0001, 0x010a);
- cit_write_reg(gspca_dev, 0x0010, 0x0102);
- cit_write_reg(gspca_dev, 0x00a0, 0x0103);
- cit_write_reg(gspca_dev, 0x0000, 0x0104);
- cit_write_reg(gspca_dev, 0x0078, 0x0105);
- break;
-
- case 176: /* 176x144 */
- cit_write_reg(gspca_dev, 0x0006, 0x010b);
- cit_write_reg(gspca_dev, 0x0000, 0x010a);
- cit_write_reg(gspca_dev, 0x0005, 0x0102);
- cit_write_reg(gspca_dev, 0x00b0, 0x0103);
- cit_write_reg(gspca_dev, 0x0000, 0x0104);
- cit_write_reg(gspca_dev, 0x0090, 0x0105);
- break;
-
- case 320: /* 320x240 */
- cit_write_reg(gspca_dev, 0x0008, 0x010b);
- cit_write_reg(gspca_dev, 0x0004, 0x010a);
- cit_write_reg(gspca_dev, 0x0005, 0x0102);
- cit_write_reg(gspca_dev, 0x00a0, 0x0103);
- cit_write_reg(gspca_dev, 0x0010, 0x0104);
- cit_write_reg(gspca_dev, 0x0078, 0x0105);
- break;
- }
-
- cit_write_reg(gspca_dev, compression, 0x0109);
- cit_write_reg(gspca_dev, clock_div, 0x0111);
-
- return 0;
-}
-
-static int cit_start_model1(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i, clock_div;
-
- clock_div = cit_get_clock_div(gspca_dev);
- if (clock_div < 0)
- return clock_div;
-
- cit_read_reg(gspca_dev, 0x0128, 1);
- cit_read_reg(gspca_dev, 0x0100, 0);
- cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */
- cit_read_reg(gspca_dev, 0x0100, 0);
- cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */
- cit_read_reg(gspca_dev, 0x0100, 0);
- cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */
- cit_write_reg(gspca_dev, 0x01, 0x0108);
-
- cit_write_reg(gspca_dev, 0x03, 0x0112);
- cit_read_reg(gspca_dev, 0x0115, 0);
- cit_write_reg(gspca_dev, 0x06, 0x0115);
- cit_read_reg(gspca_dev, 0x0116, 0);
- cit_write_reg(gspca_dev, 0x44, 0x0116);
- cit_read_reg(gspca_dev, 0x0116, 0);
- cit_write_reg(gspca_dev, 0x40, 0x0116);
- cit_read_reg(gspca_dev, 0x0115, 0);
- cit_write_reg(gspca_dev, 0x0e, 0x0115);
- cit_write_reg(gspca_dev, 0x19, 0x012c);
-
- cit_Packet_Format1(gspca_dev, 0x00, 0x1e);
- cit_Packet_Format1(gspca_dev, 0x39, 0x0d);
- cit_Packet_Format1(gspca_dev, 0x39, 0x09);
- cit_Packet_Format1(gspca_dev, 0x3b, 0x00);
- cit_Packet_Format1(gspca_dev, 0x28, 0x22);
- cit_Packet_Format1(gspca_dev, 0x27, 0x00);
- cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
- cit_Packet_Format1(gspca_dev, 0x39, 0x08);
-
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x2c, 0x00);
-
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x30, 0x14);
-
- cit_PacketFormat2(gspca_dev, 0x39, 0x02);
- cit_PacketFormat2(gspca_dev, 0x01, 0xe1);
- cit_PacketFormat2(gspca_dev, 0x02, 0xcd);
- cit_PacketFormat2(gspca_dev, 0x03, 0xcd);
- cit_PacketFormat2(gspca_dev, 0x04, 0xfa);
- cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
- cit_PacketFormat2(gspca_dev, 0x39, 0x00);
-
- cit_PacketFormat2(gspca_dev, 0x39, 0x02);
- cit_PacketFormat2(gspca_dev, 0x0a, 0x37);
- cit_PacketFormat2(gspca_dev, 0x0b, 0xb8);
- cit_PacketFormat2(gspca_dev, 0x0c, 0xf3);
- cit_PacketFormat2(gspca_dev, 0x0d, 0xe3);
- cit_PacketFormat2(gspca_dev, 0x0e, 0x0d);
- cit_PacketFormat2(gspca_dev, 0x0f, 0xf2);
- cit_PacketFormat2(gspca_dev, 0x10, 0xd5);
- cit_PacketFormat2(gspca_dev, 0x11, 0xba);
- cit_PacketFormat2(gspca_dev, 0x12, 0x53);
- cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
- cit_PacketFormat2(gspca_dev, 0x39, 0x00);
-
- cit_PacketFormat2(gspca_dev, 0x39, 0x02);
- cit_PacketFormat2(gspca_dev, 0x16, 0x00);
- cit_PacketFormat2(gspca_dev, 0x17, 0x28);
- cit_PacketFormat2(gspca_dev, 0x18, 0x7d);
- cit_PacketFormat2(gspca_dev, 0x19, 0xbe);
- cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
- cit_PacketFormat2(gspca_dev, 0x39, 0x00);
-
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x00, 0x18);
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x13, 0x18);
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x14, 0x06);
-
- /* TESTME These are handled through controls
- KEEP until someone can test leaving this out is ok */
- if (0) {
- /* This is default brightness */
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x31, 0x37);
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x32, 0x46);
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x33, 0x55);
- }
-
- cit_Packet_Format1(gspca_dev, 0x2e, 0x04);
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x2d, 0x04);
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x29, 0x80);
- cit_Packet_Format1(gspca_dev, 0x2c, 0x01);
- cit_Packet_Format1(gspca_dev, 0x30, 0x17);
- cit_Packet_Format1(gspca_dev, 0x39, 0x08);
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x34, 0x00);
-
- cit_write_reg(gspca_dev, 0x00, 0x0101);
- cit_write_reg(gspca_dev, 0x00, 0x010a);
-
- switch (gspca_dev->width) {
- case 128: /* 128x96 */
- cit_write_reg(gspca_dev, 0x80, 0x0103);
- cit_write_reg(gspca_dev, 0x60, 0x0105);
- cit_write_reg(gspca_dev, 0x0c, 0x010b);
- cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x0b, 0x011d);
- cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x00, 0x0129);
- break;
- case 176: /* 176x144 */
- cit_write_reg(gspca_dev, 0xb0, 0x0103);
- cit_write_reg(gspca_dev, 0x8f, 0x0105);
- cit_write_reg(gspca_dev, 0x06, 0x010b);
- cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x0d, 0x011d);
- cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x03, 0x0129);
- break;
- case 352: /* 352x288 */
- cit_write_reg(gspca_dev, 0xb0, 0x0103);
- cit_write_reg(gspca_dev, 0x90, 0x0105);
- cit_write_reg(gspca_dev, 0x02, 0x010b);
- cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x05, 0x011d);
- cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x00, 0x0129);
- break;
- }
-
- cit_write_reg(gspca_dev, 0xff, 0x012b);
-
- /* TESTME These are handled through controls
- KEEP until someone can test leaving this out is ok */
- if (0) {
- /* This is another brightness - don't know why */
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x31, 0xc3);
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x32, 0xd2);
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x33, 0xe1);
-
- /* Default contrast */
- for (i = 0; i < cit_model1_ntries; i++)
- cit_Packet_Format1(gspca_dev, 0x14, 0x0a);
-
- /* Default sharpness */
- for (i = 0; i < cit_model1_ntries2; i++)
- cit_PacketFormat2(gspca_dev, 0x13, 0x1a);
-
- /* Default lighting conditions */
- cit_Packet_Format1(gspca_dev, 0x0027,
- v4l2_ctrl_g_ctrl(sd->lighting));
- }
-
- /* Assorted init */
- switch (gspca_dev->width) {
- case 128: /* 128x96 */
- cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
- cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x36, 0x0102);
- cit_write_reg(gspca_dev, 0x1a, 0x0104);
- cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x2b, 0x011c);
- cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */
- break;
- case 176: /* 176x144 */
- cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
- cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x04, 0x0102);
- cit_write_reg(gspca_dev, 0x02, 0x0104);
- cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x2b, 0x011c);
- cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */
- break;
- case 352: /* 352x288 */
- cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
- cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x08, 0x0102);
- cit_write_reg(gspca_dev, 0x01, 0x0104);
- cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */
- cit_write_reg(gspca_dev, 0x2f, 0x011c);
- cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */
- break;
- }
-
- cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */
- cit_write_reg(gspca_dev, clock_div, 0x0111);
-
- return 0;
-}
-
-static int cit_start_model2(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int clock_div = 0;
-
- cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */
- cit_read_reg(gspca_dev, 0x0116, 0);
- cit_write_reg(gspca_dev, 0x0060, 0x0116);
- cit_write_reg(gspca_dev, 0x0002, 0x0112);
- cit_write_reg(gspca_dev, 0x00bc, 0x012c);
- cit_write_reg(gspca_dev, 0x0008, 0x012b);
- cit_write_reg(gspca_dev, 0x0000, 0x0108);
- cit_write_reg(gspca_dev, 0x0001, 0x0133);
- cit_write_reg(gspca_dev, 0x0001, 0x0102);
- switch (gspca_dev->width) {
- case 176: /* 176x144 */
- cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */
- cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */
- cit_write_reg(gspca_dev, 0x0024, 0x0105); /* 176x144, 352x288 */
- cit_write_reg(gspca_dev, 0x00b9, 0x010a); /* Unique to this mode */
- cit_write_reg(gspca_dev, 0x0038, 0x0119); /* Unique to this mode */
- /* TESTME HDG: this does not seem right
- (it is 2 for all other resolutions) */
- sd->sof_len = 10;
- break;
- case 320: /* 320x240 */
- cit_write_reg(gspca_dev, 0x0028, 0x0103); /* Unique to this mode */
- cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */
- cit_write_reg(gspca_dev, 0x001e, 0x0105); /* 320x240, 352x240 */
- cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */
- cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */
- sd->sof_len = 2;
- break;
- /* case VIDEOSIZE_352x240: */
- cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */
- cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */
- cit_write_reg(gspca_dev, 0x001e, 0x0105); /* 320x240, 352x240 */
- cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */
- cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */
- sd->sof_len = 2;
- break;
- case 352: /* 352x288 */
- cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */
- cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */
- cit_write_reg(gspca_dev, 0x0024, 0x0105); /* 176x144, 352x288 */
- cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */
- cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */
- sd->sof_len = 2;
- break;
- }
-
- cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */
-
- switch (gspca_dev->width) {
- case 176: /* 176x144 */
- cit_write_reg(gspca_dev, 0x0050, 0x0111);
- cit_write_reg(gspca_dev, 0x00d0, 0x0111);
- break;
- case 320: /* 320x240 */
- case 352: /* 352x288 */
- cit_write_reg(gspca_dev, 0x0040, 0x0111);
- cit_write_reg(gspca_dev, 0x00c0, 0x0111);
- break;
- }
- cit_write_reg(gspca_dev, 0x009b, 0x010f);
- cit_write_reg(gspca_dev, 0x00bb, 0x010f);
-
- /*
- * Hardware settings, may affect CMOS sensor; not user controls!
- * -------------------------------------------------------------
- * 0x0004: no effect
- * 0x0006: hardware effect
- * 0x0008: no effect
- * 0x000a: stops video stream, probably important h/w setting
- * 0x000c: changes color in hardware manner (not user setting)
- * 0x0012: changes number of colors (does not affect speed)
- * 0x002a: no effect
- * 0x002c: hardware setting (related to scan lines)
- * 0x002e: stops video stream, probably important h/w setting
- */
- cit_model2_Packet1(gspca_dev, 0x000a, 0x005c);
- cit_model2_Packet1(gspca_dev, 0x0004, 0x0000);
- cit_model2_Packet1(gspca_dev, 0x0006, 0x00fb);
- cit_model2_Packet1(gspca_dev, 0x0008, 0x0000);
- cit_model2_Packet1(gspca_dev, 0x000c, 0x0009);
- cit_model2_Packet1(gspca_dev, 0x0012, 0x000a);
- cit_model2_Packet1(gspca_dev, 0x002a, 0x0000);
- cit_model2_Packet1(gspca_dev, 0x002c, 0x0000);
- cit_model2_Packet1(gspca_dev, 0x002e, 0x0008);
-
- /*
- * Function 0x0030 pops up all over the place. Apparently
- * it is a hardware control register, with every bit assigned to
- * do something.
- */
- cit_model2_Packet1(gspca_dev, 0x0030, 0x0000);
-
- /*
- * Magic control of CMOS sensor. Only lower values like
- * 0-3 work, and picture shifts left or right. Don't change.
- */
- switch (gspca_dev->width) {
- case 176: /* 176x144 */
- cit_model2_Packet1(gspca_dev, 0x0014, 0x0002);
- cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
- cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
- clock_div = 6;
- break;
- case 320: /* 320x240 */
- cit_model2_Packet1(gspca_dev, 0x0014, 0x0009);
- cit_model2_Packet1(gspca_dev, 0x0016, 0x0005); /* Horizontal shift */
- cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Another hardware setting */
- clock_div = 8;
- break;
- /* case VIDEOSIZE_352x240: */
- /* This mode doesn't work as Windows programs it; changed to work */
- cit_model2_Packet1(gspca_dev, 0x0014, 0x0009); /* Windows sets this to 8 */
- cit_model2_Packet1(gspca_dev, 0x0016, 0x0003); /* Horizontal shift */
- cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Windows sets this to 0x0045 */
- clock_div = 10;
- break;
- case 352: /* 352x288 */
- cit_model2_Packet1(gspca_dev, 0x0014, 0x0003);
- cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
- cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
- clock_div = 16;
- break;
- }
-
- /* TESTME These are handled through controls
- KEEP until someone can test leaving this out is ok */
- if (0)
- cit_model2_Packet1(gspca_dev, 0x001a, 0x005a);
-
- /*
- * We have our own frame rate setting varying from 0 (slowest) to 6
- * (fastest). The camera model 2 allows frame rate in range [0..0x1F]
- # where 0 is also the slowest setting. However for all practical
- # reasons high settings make no sense because USB is not fast enough
- # to support high FPS. Be aware that the picture datastream will be
- # severely disrupted if you ask for frame rate faster than allowed
- # for the video size - see below:
- *
- * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz):
- * -----------------------------------------------------------------
- * 176x144: [6..31]
- * 320x240: [8..31]
- * 352x240: [10..31]
- * 352x288: [16..31] I have to raise lower threshold for stability...
- *
- * As usual, slower FPS provides better sensitivity.
- */
- cit_model2_Packet1(gspca_dev, 0x001c, clock_div);
-
- /*
- * This setting does not visibly affect pictures; left it here
- * because it was present in Windows USB data stream. This function
- * does not allow arbitrary values and apparently is a bit mask, to
- * be activated only at appropriate time. Don't change it randomly!
- */
- switch (gspca_dev->width) {
- case 176: /* 176x144 */
- cit_model2_Packet1(gspca_dev, 0x0026, 0x00c2);
- break;
- case 320: /* 320x240 */
- cit_model2_Packet1(gspca_dev, 0x0026, 0x0044);
- break;
- /* case VIDEOSIZE_352x240: */
- cit_model2_Packet1(gspca_dev, 0x0026, 0x0046);
- break;
- case 352: /* 352x288 */
- cit_model2_Packet1(gspca_dev, 0x0026, 0x0048);
- break;
- }
-
- cit_model2_Packet1(gspca_dev, 0x0028, v4l2_ctrl_g_ctrl(sd->lighting));
- /* model2 cannot change the backlight compensation while streaming */
- v4l2_ctrl_grab(sd->lighting, true);
-
- /* color balance rg2 */
- cit_model2_Packet1(gspca_dev, 0x001e, 0x002f);
- /* saturation */
- cit_model2_Packet1(gspca_dev, 0x0020, 0x0034);
- /* color balance yb */
- cit_model2_Packet1(gspca_dev, 0x0022, 0x00a0);
-
- /* Hardware control command */
- cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
-
- return 0;
-}
-
-static int cit_start_model3(struct gspca_dev *gspca_dev)
-{
- const unsigned short compression = 0; /* 0=none, 7=best frame rate */
- int i, clock_div = 0;
-
- /* HDG not in ibmcam driver, added to see if it helps with
- auto-detecting between model3 and ibm netcamera pro */
- cit_read_reg(gspca_dev, 0x128, 1);
-
- cit_write_reg(gspca_dev, 0x0000, 0x0100);
- cit_read_reg(gspca_dev, 0x0116, 0);
- cit_write_reg(gspca_dev, 0x0060, 0x0116);
- cit_write_reg(gspca_dev, 0x0002, 0x0112);
- cit_write_reg(gspca_dev, 0x0000, 0x0123);
- cit_write_reg(gspca_dev, 0x0001, 0x0117);
- cit_write_reg(gspca_dev, 0x0040, 0x0108);
- cit_write_reg(gspca_dev, 0x0019, 0x012c);
- cit_write_reg(gspca_dev, 0x0060, 0x0116);
- cit_write_reg(gspca_dev, 0x0002, 0x0115);
- cit_write_reg(gspca_dev, 0x0003, 0x0115);
- cit_read_reg(gspca_dev, 0x0115, 0);
- cit_write_reg(gspca_dev, 0x000b, 0x0115);
-
- /* TESTME HDG not in ibmcam driver, added to see if it helps with
- auto-detecting between model3 and ibm netcamera pro */
- if (0) {
- cit_write_reg(gspca_dev, 0x0078, 0x012d);
- cit_write_reg(gspca_dev, 0x0001, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0079, 0x012d);
- cit_write_reg(gspca_dev, 0x00ff, 0x0130);
- cit_write_reg(gspca_dev, 0xcd41, 0x0124);
- cit_write_reg(gspca_dev, 0xfffa, 0x0124);
- cit_read_reg(gspca_dev, 0x0126, 1);
- }
-
- cit_model3_Packet1(gspca_dev, 0x000a, 0x0040);
- cit_model3_Packet1(gspca_dev, 0x000b, 0x00f6);
- cit_model3_Packet1(gspca_dev, 0x000c, 0x0002);
- cit_model3_Packet1(gspca_dev, 0x000d, 0x0020);
- cit_model3_Packet1(gspca_dev, 0x000e, 0x0033);
- cit_model3_Packet1(gspca_dev, 0x000f, 0x0007);
- cit_model3_Packet1(gspca_dev, 0x0010, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0011, 0x0070);
- cit_model3_Packet1(gspca_dev, 0x0012, 0x0030);
- cit_model3_Packet1(gspca_dev, 0x0013, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0014, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x0015, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x0016, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x0017, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x0018, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x001e, 0x00c3);
- cit_model3_Packet1(gspca_dev, 0x0020, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0028, 0x0010);
- cit_model3_Packet1(gspca_dev, 0x0029, 0x0054);
- cit_model3_Packet1(gspca_dev, 0x002a, 0x0013);
- cit_model3_Packet1(gspca_dev, 0x002b, 0x0007);
- cit_model3_Packet1(gspca_dev, 0x002d, 0x0028);
- cit_model3_Packet1(gspca_dev, 0x002e, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0031, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0032, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0033, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0034, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0035, 0x0038);
- cit_model3_Packet1(gspca_dev, 0x003a, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x003c, 0x001e);
- cit_model3_Packet1(gspca_dev, 0x003f, 0x000a);
- cit_model3_Packet1(gspca_dev, 0x0041, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0046, 0x003f);
- cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0050, 0x0005);
- cit_model3_Packet1(gspca_dev, 0x0052, 0x001a);
- cit_model3_Packet1(gspca_dev, 0x0053, 0x0003);
- cit_model3_Packet1(gspca_dev, 0x005a, 0x006b);
- cit_model3_Packet1(gspca_dev, 0x005d, 0x001e);
- cit_model3_Packet1(gspca_dev, 0x005e, 0x0030);
- cit_model3_Packet1(gspca_dev, 0x005f, 0x0041);
- cit_model3_Packet1(gspca_dev, 0x0064, 0x0008);
- cit_model3_Packet1(gspca_dev, 0x0065, 0x0015);
- cit_model3_Packet1(gspca_dev, 0x0068, 0x000f);
- cit_model3_Packet1(gspca_dev, 0x0079, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x007a, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x007c, 0x003f);
- cit_model3_Packet1(gspca_dev, 0x0082, 0x000f);
- cit_model3_Packet1(gspca_dev, 0x0085, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0099, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x009b, 0x0023);
- cit_model3_Packet1(gspca_dev, 0x009c, 0x0022);
- cit_model3_Packet1(gspca_dev, 0x009d, 0x0096);
- cit_model3_Packet1(gspca_dev, 0x009e, 0x0096);
- cit_model3_Packet1(gspca_dev, 0x009f, 0x000a);
-
- switch (gspca_dev->width) {
- case 160:
- cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
- cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
- cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
- cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
- cit_write_reg(gspca_dev, 0x0024, 0x010b); /* Differs everywhere */
- cit_write_reg(gspca_dev, 0x00a9, 0x0119);
- cit_write_reg(gspca_dev, 0x0016, 0x011b);
- cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
- cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
- cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
- cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
- cit_write_reg(gspca_dev, 0x0018, 0x0102);
- cit_write_reg(gspca_dev, 0x0004, 0x0104);
- cit_write_reg(gspca_dev, 0x0004, 0x011a);
- cit_write_reg(gspca_dev, 0x0028, 0x011c);
- cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
- cit_write_reg(gspca_dev, 0x0000, 0x0118);
- cit_write_reg(gspca_dev, 0x0000, 0x0132);
- cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
- cit_write_reg(gspca_dev, compression, 0x0109);
- clock_div = 3;
- break;
- case 320:
- cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
- cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
- cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
- cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
- cit_write_reg(gspca_dev, 0x0028, 0x010b); /* Differs everywhere */
- cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same */
- cit_write_reg(gspca_dev, 0x0000, 0x011e);
- cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
- cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
- /* 4 commands from 160x120 skipped */
- cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
- cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
- cit_write_reg(gspca_dev, compression, 0x0109);
- cit_write_reg(gspca_dev, 0x00d9, 0x0119);
- cit_write_reg(gspca_dev, 0x0006, 0x011b);
- cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
- cit_write_reg(gspca_dev, 0x0010, 0x0104);
- cit_write_reg(gspca_dev, 0x0004, 0x011a);
- cit_write_reg(gspca_dev, 0x003f, 0x011c);
- cit_write_reg(gspca_dev, 0x001c, 0x0118);
- cit_write_reg(gspca_dev, 0x0000, 0x0132);
- clock_div = 5;
- break;
- case 640:
- cit_write_reg(gspca_dev, 0x00f0, 0x0105);
- cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
- cit_write_reg(gspca_dev, 0x0038, 0x010b); /* Differs everywhere */
- cit_write_reg(gspca_dev, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */
- cit_write_reg(gspca_dev, 0x0006, 0x011b); /* Same on 320x240, 640x480 */
- cit_write_reg(gspca_dev, 0x0004, 0x011d); /* NC */
- cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
- cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
- cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
- cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
- cit_write_reg(gspca_dev, 0x0016, 0x0104); /* NC */
- cit_write_reg(gspca_dev, 0x0004, 0x011a); /* Same on 320x240, 640x480 */
- cit_write_reg(gspca_dev, 0x003f, 0x011c); /* Same on 320x240, 640x480 */
- cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
- cit_write_reg(gspca_dev, 0x001c, 0x0118); /* Same on 320x240, 640x480 */
- cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
- cit_write_reg(gspca_dev, compression, 0x0109);
- cit_write_reg(gspca_dev, 0x0040, 0x0101);
- cit_write_reg(gspca_dev, 0x0040, 0x0103);
- cit_write_reg(gspca_dev, 0x0000, 0x0132); /* Same on 320x240, 640x480 */
- clock_div = 7;
- break;
- }
-
- cit_model3_Packet1(gspca_dev, 0x007e, 0x000e); /* Hue */
- cit_model3_Packet1(gspca_dev, 0x0036, 0x0011); /* Brightness */
- cit_model3_Packet1(gspca_dev, 0x0060, 0x0002); /* Sharpness */
- cit_model3_Packet1(gspca_dev, 0x0061, 0x0004); /* Sharpness */
- cit_model3_Packet1(gspca_dev, 0x0062, 0x0005); /* Sharpness */
- cit_model3_Packet1(gspca_dev, 0x0063, 0x0014); /* Sharpness */
- cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0); /* Red sharpness */
- cit_model3_Packet1(gspca_dev, 0x0097, 0x0096); /* Blue sharpness */
- cit_model3_Packet1(gspca_dev, 0x0067, 0x0001); /* Contrast */
- cit_model3_Packet1(gspca_dev, 0x005b, 0x000c); /* Contrast */
- cit_model3_Packet1(gspca_dev, 0x005c, 0x0016); /* Contrast */
- cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
- cit_model3_Packet1(gspca_dev, 0x002c, 0x0003); /* Was 1, broke 640x480 */
- cit_model3_Packet1(gspca_dev, 0x002f, 0x002a);
- cit_model3_Packet1(gspca_dev, 0x0030, 0x0029);
- cit_model3_Packet1(gspca_dev, 0x0037, 0x0002);
- cit_model3_Packet1(gspca_dev, 0x0038, 0x0059);
- cit_model3_Packet1(gspca_dev, 0x003d, 0x002e);
- cit_model3_Packet1(gspca_dev, 0x003e, 0x0028);
- cit_model3_Packet1(gspca_dev, 0x0078, 0x0005);
- cit_model3_Packet1(gspca_dev, 0x007b, 0x0011);
- cit_model3_Packet1(gspca_dev, 0x007d, 0x004b);
- cit_model3_Packet1(gspca_dev, 0x007f, 0x0022);
- cit_model3_Packet1(gspca_dev, 0x0080, 0x000c);
- cit_model3_Packet1(gspca_dev, 0x0081, 0x000b);
- cit_model3_Packet1(gspca_dev, 0x0083, 0x00fd);
- cit_model3_Packet1(gspca_dev, 0x0086, 0x000b);
- cit_model3_Packet1(gspca_dev, 0x0087, 0x000b);
- cit_model3_Packet1(gspca_dev, 0x007e, 0x000e);
- cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0); /* Red sharpness */
- cit_model3_Packet1(gspca_dev, 0x0097, 0x0096); /* Blue sharpness */
- cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
-
- /* FIXME we should probably use cit_get_clock_div() here (in
- combination with isoc negotiation using the programmable isoc size)
- like with the IBM netcam pro). */
- cit_write_reg(gspca_dev, clock_div, 0x0111); /* Clock Divider */
-
- switch (gspca_dev->width) {
- case 160:
- cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
- cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
- cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
- cit_model3_Packet1(gspca_dev, 0x0040, 0x000a);
- cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
- break;
- case 320:
- cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
- cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
- cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
- cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
- cit_model3_Packet1(gspca_dev, 0x0051, 0x000b);
- break;
- case 640:
- cit_model3_Packet1(gspca_dev, 0x001f, 0x0002); /* !Same */
- cit_model3_Packet1(gspca_dev, 0x0039, 0x003e); /* !Same */
- cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
- cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
- break;
- }
-
-/* if (sd->input_index) { */
- if (rca_input) {
- for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
- if (rca_initdata[i][0])
- cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
- else
- cit_write_reg(gspca_dev, rca_initdata[i][1],
- rca_initdata[i][2]);
- }
- }
-
- return 0;
-}
-
-static int cit_start_model4(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- cit_write_reg(gspca_dev, 0x0000, 0x0100);
- cit_write_reg(gspca_dev, 0x00c0, 0x0111);
- cit_write_reg(gspca_dev, 0x00bc, 0x012c);
- cit_write_reg(gspca_dev, 0x0080, 0x012b);
- cit_write_reg(gspca_dev, 0x0000, 0x0108);
- cit_write_reg(gspca_dev, 0x0001, 0x0133);
- cit_write_reg(gspca_dev, 0x009b, 0x010f);
- cit_write_reg(gspca_dev, 0x00bb, 0x010f);
- cit_model4_Packet1(gspca_dev, 0x0038, 0x0000);
- cit_model4_Packet1(gspca_dev, 0x000a, 0x005c);
-
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x0004, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0000, 0x0127);
- cit_write_reg(gspca_dev, 0x00fb, 0x012e);
- cit_write_reg(gspca_dev, 0x0000, 0x0130);
- cit_write_reg(gspca_dev, 0x8a28, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012f);
- cit_write_reg(gspca_dev, 0xd055, 0x0124);
- cit_write_reg(gspca_dev, 0x000c, 0x0127);
- cit_write_reg(gspca_dev, 0x0009, 0x012e);
- cit_write_reg(gspca_dev, 0xaa28, 0x0124);
-
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x0012, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0008, 0x0127);
- cit_write_reg(gspca_dev, 0x00aa, 0x0130);
- cit_write_reg(gspca_dev, 0x82a8, 0x0124);
- cit_write_reg(gspca_dev, 0x002a, 0x012d);
- cit_write_reg(gspca_dev, 0x0000, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0xfffa, 0x0124);
- cit_model4_Packet1(gspca_dev, 0x0034, 0x0000);
-
- switch (gspca_dev->width) {
- case 128: /* 128x96 */
- cit_write_reg(gspca_dev, 0x0070, 0x0119);
- cit_write_reg(gspca_dev, 0x00d0, 0x0111);
- cit_write_reg(gspca_dev, 0x0039, 0x010a);
- cit_write_reg(gspca_dev, 0x0001, 0x0102);
- cit_write_reg(gspca_dev, 0x0028, 0x0103);
- cit_write_reg(gspca_dev, 0x0000, 0x0104);
- cit_write_reg(gspca_dev, 0x001e, 0x0105);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x0016, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x000a, 0x0127);
- cit_write_reg(gspca_dev, 0x00aa, 0x0130);
- cit_write_reg(gspca_dev, 0x82a8, 0x0124);
- cit_write_reg(gspca_dev, 0x0014, 0x012d);
- cit_write_reg(gspca_dev, 0x0008, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012e);
- cit_write_reg(gspca_dev, 0x001a, 0x0130);
- cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
- cit_write_reg(gspca_dev, 0x005a, 0x012d);
- cit_write_reg(gspca_dev, 0x9545, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x0127);
- cit_write_reg(gspca_dev, 0x0018, 0x012e);
- cit_write_reg(gspca_dev, 0x0043, 0x0130);
- cit_write_reg(gspca_dev, 0x8a28, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012f);
- cit_write_reg(gspca_dev, 0xd055, 0x0124);
- cit_write_reg(gspca_dev, 0x001c, 0x0127);
- cit_write_reg(gspca_dev, 0x00eb, 0x012e);
- cit_write_reg(gspca_dev, 0xaa28, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x0032, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0000, 0x0127);
- cit_write_reg(gspca_dev, 0x00aa, 0x0130);
- cit_write_reg(gspca_dev, 0x82a8, 0x0124);
- cit_write_reg(gspca_dev, 0x0036, 0x012d);
- cit_write_reg(gspca_dev, 0x0008, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0xfffa, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x001e, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0017, 0x0127);
- cit_write_reg(gspca_dev, 0x0013, 0x012e);
- cit_write_reg(gspca_dev, 0x0031, 0x0130);
- cit_write_reg(gspca_dev, 0x8a28, 0x0124);
- cit_write_reg(gspca_dev, 0x0017, 0x012d);
- cit_write_reg(gspca_dev, 0x0078, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0x0000, 0x0127);
- cit_write_reg(gspca_dev, 0xfea8, 0x0124);
- sd->sof_len = 2;
- break;
- case 160: /* 160x120 */
- cit_write_reg(gspca_dev, 0x0038, 0x0119);
- cit_write_reg(gspca_dev, 0x00d0, 0x0111);
- cit_write_reg(gspca_dev, 0x00b9, 0x010a);
- cit_write_reg(gspca_dev, 0x0001, 0x0102);
- cit_write_reg(gspca_dev, 0x0028, 0x0103);
- cit_write_reg(gspca_dev, 0x0000, 0x0104);
- cit_write_reg(gspca_dev, 0x001e, 0x0105);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x0016, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x000b, 0x0127);
- cit_write_reg(gspca_dev, 0x00aa, 0x0130);
- cit_write_reg(gspca_dev, 0x82a8, 0x0124);
- cit_write_reg(gspca_dev, 0x0014, 0x012d);
- cit_write_reg(gspca_dev, 0x0008, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012e);
- cit_write_reg(gspca_dev, 0x001a, 0x0130);
- cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
- cit_write_reg(gspca_dev, 0x005a, 0x012d);
- cit_write_reg(gspca_dev, 0x9545, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x0127);
- cit_write_reg(gspca_dev, 0x0018, 0x012e);
- cit_write_reg(gspca_dev, 0x0043, 0x0130);
- cit_write_reg(gspca_dev, 0x8a28, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012f);
- cit_write_reg(gspca_dev, 0xd055, 0x0124);
- cit_write_reg(gspca_dev, 0x001c, 0x0127);
- cit_write_reg(gspca_dev, 0x00c7, 0x012e);
- cit_write_reg(gspca_dev, 0xaa28, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x0032, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0025, 0x0127);
- cit_write_reg(gspca_dev, 0x00aa, 0x0130);
- cit_write_reg(gspca_dev, 0x82a8, 0x0124);
- cit_write_reg(gspca_dev, 0x0036, 0x012d);
- cit_write_reg(gspca_dev, 0x0008, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0xfffa, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x001e, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0048, 0x0127);
- cit_write_reg(gspca_dev, 0x0035, 0x012e);
- cit_write_reg(gspca_dev, 0x00d0, 0x0130);
- cit_write_reg(gspca_dev, 0x8a28, 0x0124);
- cit_write_reg(gspca_dev, 0x0048, 0x012d);
- cit_write_reg(gspca_dev, 0x0090, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0x0001, 0x0127);
- cit_write_reg(gspca_dev, 0xfea8, 0x0124);
- sd->sof_len = 2;
- break;
- case 176: /* 176x144 */
- cit_write_reg(gspca_dev, 0x0038, 0x0119);
- cit_write_reg(gspca_dev, 0x00d0, 0x0111);
- cit_write_reg(gspca_dev, 0x00b9, 0x010a);
- cit_write_reg(gspca_dev, 0x0001, 0x0102);
- cit_write_reg(gspca_dev, 0x002c, 0x0103);
- cit_write_reg(gspca_dev, 0x0000, 0x0104);
- cit_write_reg(gspca_dev, 0x0024, 0x0105);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x0016, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0007, 0x0127);
- cit_write_reg(gspca_dev, 0x00aa, 0x0130);
- cit_write_reg(gspca_dev, 0x82a8, 0x0124);
- cit_write_reg(gspca_dev, 0x0014, 0x012d);
- cit_write_reg(gspca_dev, 0x0001, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012e);
- cit_write_reg(gspca_dev, 0x001a, 0x0130);
- cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
- cit_write_reg(gspca_dev, 0x005e, 0x012d);
- cit_write_reg(gspca_dev, 0x9545, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x0127);
- cit_write_reg(gspca_dev, 0x0018, 0x012e);
- cit_write_reg(gspca_dev, 0x0049, 0x0130);
- cit_write_reg(gspca_dev, 0x8a28, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012f);
- cit_write_reg(gspca_dev, 0xd055, 0x0124);
- cit_write_reg(gspca_dev, 0x001c, 0x0127);
- cit_write_reg(gspca_dev, 0x00c7, 0x012e);
- cit_write_reg(gspca_dev, 0xaa28, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x0032, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0028, 0x0127);
- cit_write_reg(gspca_dev, 0x00aa, 0x0130);
- cit_write_reg(gspca_dev, 0x82a8, 0x0124);
- cit_write_reg(gspca_dev, 0x0036, 0x012d);
- cit_write_reg(gspca_dev, 0x0008, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0xfffa, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x001e, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0010, 0x0127);
- cit_write_reg(gspca_dev, 0x0013, 0x012e);
- cit_write_reg(gspca_dev, 0x002a, 0x0130);
- cit_write_reg(gspca_dev, 0x8a28, 0x0124);
- cit_write_reg(gspca_dev, 0x0010, 0x012d);
- cit_write_reg(gspca_dev, 0x006d, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0x0001, 0x0127);
- cit_write_reg(gspca_dev, 0xfea8, 0x0124);
- /* TESTME HDG: this does not seem right
- (it is 2 for all other resolutions) */
- sd->sof_len = 10;
- break;
- case 320: /* 320x240 */
- cit_write_reg(gspca_dev, 0x0070, 0x0119);
- cit_write_reg(gspca_dev, 0x00d0, 0x0111);
- cit_write_reg(gspca_dev, 0x0039, 0x010a);
- cit_write_reg(gspca_dev, 0x0001, 0x0102);
- cit_write_reg(gspca_dev, 0x0028, 0x0103);
- cit_write_reg(gspca_dev, 0x0000, 0x0104);
- cit_write_reg(gspca_dev, 0x001e, 0x0105);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x0016, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x000a, 0x0127);
- cit_write_reg(gspca_dev, 0x00aa, 0x0130);
- cit_write_reg(gspca_dev, 0x82a8, 0x0124);
- cit_write_reg(gspca_dev, 0x0014, 0x012d);
- cit_write_reg(gspca_dev, 0x0008, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012e);
- cit_write_reg(gspca_dev, 0x001a, 0x0130);
- cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
- cit_write_reg(gspca_dev, 0x005a, 0x012d);
- cit_write_reg(gspca_dev, 0x9545, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x0127);
- cit_write_reg(gspca_dev, 0x0018, 0x012e);
- cit_write_reg(gspca_dev, 0x0043, 0x0130);
- cit_write_reg(gspca_dev, 0x8a28, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012f);
- cit_write_reg(gspca_dev, 0xd055, 0x0124);
- cit_write_reg(gspca_dev, 0x001c, 0x0127);
- cit_write_reg(gspca_dev, 0x00eb, 0x012e);
- cit_write_reg(gspca_dev, 0xaa28, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x0032, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0000, 0x0127);
- cit_write_reg(gspca_dev, 0x00aa, 0x0130);
- cit_write_reg(gspca_dev, 0x82a8, 0x0124);
- cit_write_reg(gspca_dev, 0x0036, 0x012d);
- cit_write_reg(gspca_dev, 0x0008, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0xfffa, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x001e, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0017, 0x0127);
- cit_write_reg(gspca_dev, 0x0013, 0x012e);
- cit_write_reg(gspca_dev, 0x0031, 0x0130);
- cit_write_reg(gspca_dev, 0x8a28, 0x0124);
- cit_write_reg(gspca_dev, 0x0017, 0x012d);
- cit_write_reg(gspca_dev, 0x0078, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0x0000, 0x0127);
- cit_write_reg(gspca_dev, 0xfea8, 0x0124);
- sd->sof_len = 2;
- break;
- case 352: /* 352x288 */
- cit_write_reg(gspca_dev, 0x0070, 0x0119);
- cit_write_reg(gspca_dev, 0x00c0, 0x0111);
- cit_write_reg(gspca_dev, 0x0039, 0x010a);
- cit_write_reg(gspca_dev, 0x0001, 0x0102);
- cit_write_reg(gspca_dev, 0x002c, 0x0103);
- cit_write_reg(gspca_dev, 0x0000, 0x0104);
- cit_write_reg(gspca_dev, 0x0024, 0x0105);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x0016, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0006, 0x0127);
- cit_write_reg(gspca_dev, 0x00aa, 0x0130);
- cit_write_reg(gspca_dev, 0x82a8, 0x0124);
- cit_write_reg(gspca_dev, 0x0014, 0x012d);
- cit_write_reg(gspca_dev, 0x0002, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012e);
- cit_write_reg(gspca_dev, 0x001a, 0x0130);
- cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
- cit_write_reg(gspca_dev, 0x005e, 0x012d);
- cit_write_reg(gspca_dev, 0x9545, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x0127);
- cit_write_reg(gspca_dev, 0x0018, 0x012e);
- cit_write_reg(gspca_dev, 0x0049, 0x0130);
- cit_write_reg(gspca_dev, 0x8a28, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012f);
- cit_write_reg(gspca_dev, 0xd055, 0x0124);
- cit_write_reg(gspca_dev, 0x001c, 0x0127);
- cit_write_reg(gspca_dev, 0x00cf, 0x012e);
- cit_write_reg(gspca_dev, 0xaa28, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x0032, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0000, 0x0127);
- cit_write_reg(gspca_dev, 0x00aa, 0x0130);
- cit_write_reg(gspca_dev, 0x82a8, 0x0124);
- cit_write_reg(gspca_dev, 0x0036, 0x012d);
- cit_write_reg(gspca_dev, 0x0008, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0xfffa, 0x0124);
- cit_write_reg(gspca_dev, 0x00aa, 0x012d);
- cit_write_reg(gspca_dev, 0x001e, 0x012f);
- cit_write_reg(gspca_dev, 0xd141, 0x0124);
- cit_write_reg(gspca_dev, 0x0010, 0x0127);
- cit_write_reg(gspca_dev, 0x0013, 0x012e);
- cit_write_reg(gspca_dev, 0x0025, 0x0130);
- cit_write_reg(gspca_dev, 0x8a28, 0x0124);
- cit_write_reg(gspca_dev, 0x0010, 0x012d);
- cit_write_reg(gspca_dev, 0x0048, 0x012f);
- cit_write_reg(gspca_dev, 0xd145, 0x0124);
- cit_write_reg(gspca_dev, 0x0000, 0x0127);
- cit_write_reg(gspca_dev, 0xfea8, 0x0124);
- sd->sof_len = 2;
- break;
- }
-
- cit_model4_Packet1(gspca_dev, 0x0038, 0x0004);
-
- return 0;
-}
-
-static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev)
-{
- const unsigned short compression = 0; /* 0=none, 7=best frame rate */
- int i, clock_div;
-
- clock_div = cit_get_clock_div(gspca_dev);
- if (clock_div < 0)
- return clock_div;
-
- cit_write_reg(gspca_dev, 0x0003, 0x0133);
- cit_write_reg(gspca_dev, 0x0000, 0x0117);
- cit_write_reg(gspca_dev, 0x0008, 0x0123);
- cit_write_reg(gspca_dev, 0x0000, 0x0100);
- cit_write_reg(gspca_dev, 0x0060, 0x0116);
- /* cit_write_reg(gspca_dev, 0x0002, 0x0112); see sd_stop0 */
- cit_write_reg(gspca_dev, 0x0000, 0x0133);
- cit_write_reg(gspca_dev, 0x0000, 0x0123);
- cit_write_reg(gspca_dev, 0x0001, 0x0117);
- cit_write_reg(gspca_dev, 0x0040, 0x0108);
- cit_write_reg(gspca_dev, 0x0019, 0x012c);
- cit_write_reg(gspca_dev, 0x0060, 0x0116);
- /* cit_write_reg(gspca_dev, 0x000b, 0x0115); see sd_stop0 */
-
- cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
-
- cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
- cit_write_reg(gspca_dev, 0x003a, 0x0102); /* Hstart */
- cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
- cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
- cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
- cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
- cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
- cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
- cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
-
- switch (gspca_dev->width) {
- case 160: /* 160x120 */
- cit_write_reg(gspca_dev, 0x0024, 0x010b);
- cit_write_reg(gspca_dev, 0x0089, 0x0119);
- cit_write_reg(gspca_dev, 0x000a, 0x011b);
- cit_write_reg(gspca_dev, 0x0003, 0x011e);
- cit_write_reg(gspca_dev, 0x0007, 0x0104);
- cit_write_reg(gspca_dev, 0x0009, 0x011a);
- cit_write_reg(gspca_dev, 0x008b, 0x011c);
- cit_write_reg(gspca_dev, 0x0008, 0x0118);
- cit_write_reg(gspca_dev, 0x0000, 0x0132);
- break;
- case 320: /* 320x240 */
- cit_write_reg(gspca_dev, 0x0028, 0x010b);
- cit_write_reg(gspca_dev, 0x00d9, 0x0119);
- cit_write_reg(gspca_dev, 0x0006, 0x011b);
- cit_write_reg(gspca_dev, 0x0000, 0x011e);
- cit_write_reg(gspca_dev, 0x000e, 0x0104);
- cit_write_reg(gspca_dev, 0x0004, 0x011a);
- cit_write_reg(gspca_dev, 0x003f, 0x011c);
- cit_write_reg(gspca_dev, 0x000c, 0x0118);
- cit_write_reg(gspca_dev, 0x0000, 0x0132);
- break;
- }
-
- cit_model3_Packet1(gspca_dev, 0x0019, 0x0031);
- cit_model3_Packet1(gspca_dev, 0x001a, 0x0003);
- cit_model3_Packet1(gspca_dev, 0x001b, 0x0038);
- cit_model3_Packet1(gspca_dev, 0x001c, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0024, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x0027, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x002a, 0x0004);
- cit_model3_Packet1(gspca_dev, 0x0035, 0x000b);
- cit_model3_Packet1(gspca_dev, 0x003f, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x0044, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x0054, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00c4, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00e7, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x00e9, 0x0001);
- cit_model3_Packet1(gspca_dev, 0x00ee, 0x0000);
- cit_model3_Packet1(gspca_dev, 0x00f3, 0x00c0);
-
- cit_write_reg(gspca_dev, compression, 0x0109);
- cit_write_reg(gspca_dev, clock_div, 0x0111);
-
-/* if (sd->input_index) { */
- if (rca_input) {
- for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
- if (rca_initdata[i][0])
- cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
- else
- cit_write_reg(gspca_dev, rca_initdata[i][1],
- rca_initdata[i][2]);
- }
- }
-
- return 0;
-}
-
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int packet_size;
-
- packet_size = cit_get_packet_size(gspca_dev);
- if (packet_size < 0)
- return packet_size;
-
- switch (sd->model) {
- case CIT_MODEL0:
- cit_start_model0(gspca_dev);
- break;
- case CIT_MODEL1:
- cit_start_model1(gspca_dev);
- break;
- case CIT_MODEL2:
- cit_start_model2(gspca_dev);
- break;
- case CIT_MODEL3:
- cit_start_model3(gspca_dev);
- break;
- case CIT_MODEL4:
- cit_start_model4(gspca_dev);
- break;
- case CIT_IBM_NETCAM_PRO:
- cit_start_ibm_netcam_pro(gspca_dev);
- break;
- }
-
- /* Program max isoc packet size */
- cit_write_reg(gspca_dev, packet_size >> 8, 0x0106);
- cit_write_reg(gspca_dev, packet_size & 0xff, 0x0107);
-
- cit_restart_stream(gspca_dev);
-
- return 0;
-}
-
-static int sd_isoc_init(struct gspca_dev *gspca_dev)
-{
- struct usb_host_interface *alt;
- int max_packet_size;
-
- switch (gspca_dev->width) {
- case 160:
- max_packet_size = 450;
- break;
- case 176:
- max_packet_size = 600;
- break;
- default:
- max_packet_size = 1022;
- break;
- }
-
- /* Start isoc bandwidth "negotiation" at max isoc bandwidth */
- alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
- alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size);
-
- return 0;
-}
-
-static int sd_isoc_nego(struct gspca_dev *gspca_dev)
-{
- int ret, packet_size, min_packet_size;
- struct usb_host_interface *alt;
-
- switch (gspca_dev->width) {
- case 160:
- min_packet_size = 200;
- break;
- case 176:
- min_packet_size = 266;
- break;
- default:
- min_packet_size = 400;
- break;
- }
-
- alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
- packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
- if (packet_size <= min_packet_size)
- return -EIO;
-
- packet_size -= 100;
- if (packet_size < min_packet_size)
- packet_size = min_packet_size;
- alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
-
- ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
- if (ret < 0)
- pr_err("set alt 1 err %d\n", ret);
-
- return ret;
-}
-
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- cit_write_reg(gspca_dev, 0x0000, 0x010c);
-}
-
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* We cannot use gspca_dev->present here as that is not set when
- sd_init gets called and we get called from sd_init */
- if (!gspca_dev->dev)
- return;
-
- switch (sd->model) {
- case CIT_MODEL0:
- /* HDG windows does this, but it causes the cams autogain to
- restart from a gain of 0, which does not look good when
- changing resolutions. */
- /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
- cit_write_reg(gspca_dev, 0x00c0, 0x0100); /* LED Off */
- break;
- case CIT_MODEL1:
- cit_send_FF_04_02(gspca_dev);
- cit_read_reg(gspca_dev, 0x0100, 0);
- cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */
- break;
- case CIT_MODEL2:
- v4l2_ctrl_grab(sd->lighting, false);
- /* Fall through! */
- case CIT_MODEL4:
- cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
-
- cit_write_reg(gspca_dev, 0x0080, 0x0100); /* LED Off */
- cit_write_reg(gspca_dev, 0x0020, 0x0111);
- cit_write_reg(gspca_dev, 0x00a0, 0x0111);
-
- cit_model2_Packet1(gspca_dev, 0x0030, 0x0002);
-
- cit_write_reg(gspca_dev, 0x0020, 0x0111);
- cit_write_reg(gspca_dev, 0x0000, 0x0112);
- break;
- case CIT_MODEL3:
- cit_write_reg(gspca_dev, 0x0006, 0x012c);
- cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
- cit_read_reg(gspca_dev, 0x0116, 0);
- cit_write_reg(gspca_dev, 0x0064, 0x0116);
- cit_read_reg(gspca_dev, 0x0115, 0);
- cit_write_reg(gspca_dev, 0x0003, 0x0115);
- cit_write_reg(gspca_dev, 0x0008, 0x0123);
- cit_write_reg(gspca_dev, 0x0000, 0x0117);
- cit_write_reg(gspca_dev, 0x0000, 0x0112);
- cit_write_reg(gspca_dev, 0x0080, 0x0100);
- break;
- case CIT_IBM_NETCAM_PRO:
- cit_model3_Packet1(gspca_dev, 0x0049, 0x00ff);
- cit_write_reg(gspca_dev, 0x0006, 0x012c);
- cit_write_reg(gspca_dev, 0x0000, 0x0116);
- /* HDG windows does this, but I cannot get the camera
- to restart with this without redoing the entire init
- sequence which makes switching modes really slow */
- /* cit_write_reg(gspca_dev, 0x0006, 0x0115); */
- cit_write_reg(gspca_dev, 0x0008, 0x0123);
- cit_write_reg(gspca_dev, 0x0000, 0x0117);
- cit_write_reg(gspca_dev, 0x0003, 0x0133);
- cit_write_reg(gspca_dev, 0x0000, 0x0111);
- /* HDG windows does this, but I get a green picture when
- restarting the stream after this */
- /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
- cit_write_reg(gspca_dev, 0x00c0, 0x0100);
- break;
- }
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- /* If the last button state is pressed, release it now! */
- if (sd->button_state) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
- input_sync(gspca_dev->input_dev);
- sd->button_state = 0;
- }
-#endif
-}
-
-static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 byte3 = 0, byte4 = 0;
- int i;
-
- switch (sd->model) {
- case CIT_MODEL0:
- case CIT_MODEL1:
- case CIT_MODEL3:
- case CIT_IBM_NETCAM_PRO:
- switch (gspca_dev->width) {
- case 160: /* 160x120 */
- byte3 = 0x02;
- byte4 = 0x0a;
- break;
- case 176: /* 176x144 */
- byte3 = 0x02;
- byte4 = 0x0e;
- break;
- case 320: /* 320x240 */
- byte3 = 0x02;
- byte4 = 0x08;
- break;
- case 352: /* 352x288 */
- byte3 = 0x02;
- byte4 = 0x00;
- break;
- case 640:
- byte3 = 0x03;
- byte4 = 0x08;
- break;
- }
-
- /* These have a different byte3 */
- if (sd->model <= CIT_MODEL1)
- byte3 = 0x00;
-
- for (i = 0; i < len; i++) {
- /* For this model the SOF always starts at offset 0
- so no need to search the entire frame */
- if (sd->model == CIT_MODEL0 && sd->sof_read != i)
- break;
-
- switch (sd->sof_read) {
- case 0:
- if (data[i] == 0x00)
- sd->sof_read++;
- break;
- case 1:
- if (data[i] == 0xff)
- sd->sof_read++;
- else if (data[i] == 0x00)
- sd->sof_read = 1;
- else
- sd->sof_read = 0;
- break;
- case 2:
- if (data[i] == byte3)
- sd->sof_read++;
- else if (data[i] == 0x00)
- sd->sof_read = 1;
- else
- sd->sof_read = 0;
- break;
- case 3:
- if (data[i] == byte4) {
- sd->sof_read = 0;
- return data + i + (sd->sof_len - 3);
- }
- if (byte3 == 0x00 && data[i] == 0xff)
- sd->sof_read = 2;
- else if (data[i] == 0x00)
- sd->sof_read = 1;
- else
- sd->sof_read = 0;
- break;
- }
- }
- break;
- case CIT_MODEL2:
- case CIT_MODEL4:
- /* TESTME we need to find a longer sof signature to avoid
- false positives */
- for (i = 0; i < len; i++) {
- switch (sd->sof_read) {
- case 0:
- if (data[i] == 0x00)
- sd->sof_read++;
- break;
- case 1:
- sd->sof_read = 0;
- if (data[i] == 0xff) {
- if (i >= 4)
- PDEBUG(D_FRAM,
- "header found at offset: %d: %02x %02x 00 %02x %02x %02x\n",
- i - 1,
- data[i - 4],
- data[i - 3],
- data[i],
- data[i + 1],
- data[i + 2]);
- else
- PDEBUG(D_FRAM,
- "header found at offset: %d: 00 %02x %02x %02x\n",
- i - 1,
- data[i],
- data[i + 1],
- data[i + 2]);
- return data + i + (sd->sof_len - 1);
- }
- break;
- }
- }
- break;
- }
- return NULL;
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- unsigned char *sof;
-
- sof = cit_find_sof(gspca_dev, data, len);
- if (sof) {
- int n;
-
- /* finish decoding current frame */
- n = sof - data;
- if (n > sd->sof_len)
- n -= sd->sof_len;
- else
- n = 0;
- gspca_frame_add(gspca_dev, LAST_PACKET,
- data, n);
- gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
- len -= sof - data;
- data = sof;
- }
-
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
-static void cit_check_button(struct gspca_dev *gspca_dev)
-{
- int new_button_state;
- struct sd *sd = (struct sd *)gspca_dev;
-
- switch (sd->model) {
- case CIT_MODEL3:
- case CIT_IBM_NETCAM_PRO:
- break;
- default: /* TEST ME unknown if this works on other models too */
- return;
- }
-
- /* Read the button state */
- cit_read_reg(gspca_dev, 0x0113, 0);
- new_button_state = !gspca_dev->usb_buf[0];
-
- /* Tell the cam we've seen the button press, notice that this
- is a nop (iow the cam keeps reporting pressed) until the
- button is actually released. */
- if (new_button_state)
- cit_write_reg(gspca_dev, 0x01, 0x0113);
-
- if (sd->button_state != new_button_state) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA,
- new_button_state);
- input_sync(gspca_dev->input_dev);
- sd->button_state = new_button_state;
- }
-}
-#endif
-
-static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- gspca_dev->usb_err = 0;
-
- if (!gspca_dev->streaming)
- return 0;
-
- if (sd->stop_on_control_change)
- sd_stopN(gspca_dev);
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- cit_set_brightness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- cit_set_contrast(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_HUE:
- cit_set_hue(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_HFLIP:
- cit_set_hflip(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SHARPNESS:
- cit_set_sharpness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_BACKLIGHT_COMPENSATION:
- cit_set_lighting(gspca_dev, ctrl->val);
- break;
- }
- if (sd->stop_on_control_change)
- cit_restart_stream(gspca_dev);
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops sd_ctrl_ops = {
- .s_ctrl = sd_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
- bool has_brightness;
- bool has_contrast;
- bool has_hue;
- bool has_sharpness;
- bool has_lighting;
- bool has_hflip;
-
- has_brightness = has_contrast = has_hue =
- has_sharpness = has_hflip = has_lighting = false;
- switch (sd->model) {
- case CIT_MODEL0:
- has_contrast = has_hflip = true;
- break;
- case CIT_MODEL1:
- has_brightness = has_contrast =
- has_sharpness = has_lighting = true;
- break;
- case CIT_MODEL2:
- has_brightness = has_hue = has_lighting = true;
- break;
- case CIT_MODEL3:
- has_brightness = has_contrast = has_sharpness = true;
- break;
- case CIT_MODEL4:
- has_brightness = has_hue = true;
- break;
- case CIT_IBM_NETCAM_PRO:
- has_brightness = has_hue =
- has_sharpness = has_hflip = has_lighting = true;
- break;
- }
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 5);
- if (has_brightness)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 63, 1, 32);
- if (has_contrast)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 20, 1, 10);
- if (has_hue)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_HUE, 0, 127, 1, 63);
- if (has_sharpness)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_SHARPNESS, 0, 6, 1, 3);
- if (has_lighting)
- sd->lighting = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_BACKLIGHT_COMPENSATION, 0, 2, 1, 1);
- if (has_hflip)
- v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
-
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- return 0;
-}
-
-/* sub-driver description */
-static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .stopN = sd_stopN,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .dq_callback = cit_check_button,
- .other_input = 1,
-#endif
-};
-
-static const struct sd_desc sd_desc_isoc_nego = {
- .name = MODULE_NAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .start = sd_start,
- .isoc_init = sd_isoc_init,
- .isoc_nego = sd_isoc_nego,
- .stopN = sd_stopN,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .dq_callback = cit_check_button,
- .other_input = 1,
-#endif
-};
-
-/* -- module initialisation -- */
-static const struct usb_device_id device_table[] = {
- { USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 },
- { USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 },
- { USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
- { USB_DEVICE_VER(0x0545, 0x8080, 0x0301, 0x0301), .driver_info = CIT_MODEL3 },
- { USB_DEVICE_VER(0x0545, 0x8002, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
- { USB_DEVICE_VER(0x0545, 0x800c, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
- { USB_DEVICE_VER(0x0545, 0x800d, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
- {}
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- const struct sd_desc *desc = &sd_desc;
-
- switch (id->driver_info) {
- case CIT_MODEL0:
- case CIT_MODEL1:
- if (intf->cur_altsetting->desc.bInterfaceNumber != 2)
- return -ENODEV;
- break;
- case CIT_MODEL2:
- case CIT_MODEL4:
- if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
- return -ENODEV;
- break;
- case CIT_MODEL3:
- if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
- return -ENODEV;
- /* FIXME this likely applies to all model3 cams and probably
- to other models too. */
- if (ibm_netcam_pro)
- desc = &sd_desc_isoc_nego;
- break;
- }
-
- return gspca_dev_probe2(intf, id, desc, sizeof(struct sd), THIS_MODULE);
-}
-
-static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
diff --git a/drivers/media/video/gspca/zc3xx-reg.h b/drivers/media/video/gspca/zc3xx-reg.h
deleted file mode 100644
index a1bd94e8ce5..00000000000
--- a/drivers/media/video/gspca/zc3xx-reg.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * zc030x registers
- *
- * Copyright (c) 2008 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- * The register aliases used here came from this driver:
- * http://zc0302.sourceforge.net/zc0302.php
- *
- * This code is placed under the terms of the GNU General Public License v2
- */
-
-/* Define the register map */
-#define ZC3XX_R000_SYSTEMCONTROL 0x0000
-#define ZC3XX_R001_SYSTEMOPERATING 0x0001
-
-/* Picture size */
-#define ZC3XX_R002_CLOCKSELECT 0x0002
-#define ZC3XX_R003_FRAMEWIDTHHIGH 0x0003
-#define ZC3XX_R004_FRAMEWIDTHLOW 0x0004
-#define ZC3XX_R005_FRAMEHEIGHTHIGH 0x0005
-#define ZC3XX_R006_FRAMEHEIGHTLOW 0x0006
-
-/* JPEG control */
-#define ZC3XX_R008_CLOCKSETTING 0x0008
-
-/* Test mode */
-#define ZC3XX_R00B_TESTMODECONTROL 0x000b
-
-/* Frame retreiving */
-#define ZC3XX_R00C_LASTACQTIME 0x000c
-#define ZC3XX_R00D_MONITORRES 0x000d
-#define ZC3XX_R00E_TIMESTAMPHIGH 0x000e
-#define ZC3XX_R00F_TIMESTAMPLOW 0x000f
-#define ZC3XX_R018_FRAMELOST 0x0018
-#define ZC3XX_R019_AUTOADJUSTFPS 0x0019
-#define ZC3XX_R01A_LASTFRAMESTATE 0x001a
-#define ZC3XX_R025_DATACOUNTER 0x0025
-
-/* Stream and sensor specific */
-#define ZC3XX_R010_CMOSSENSORSELECT 0x0010
-#define ZC3XX_R011_VIDEOSTATUS 0x0011
-#define ZC3XX_R012_VIDEOCONTROLFUNC 0x0012
-
-/* Horizontal and vertical synchros */
-#define ZC3XX_R01D_HSYNC_0 0x001d
-#define ZC3XX_R01E_HSYNC_1 0x001e
-#define ZC3XX_R01F_HSYNC_2 0x001f
-#define ZC3XX_R020_HSYNC_3 0x0020
-
-/* Target picture size in byte */
-#define ZC3XX_R022_TARGETPICTSIZE_0 0x0022
-#define ZC3XX_R023_TARGETPICTSIZE_1 0x0023
-#define ZC3XX_R024_TARGETPICTSIZE_2 0x0024
-
-/* Audio registers */
-#define ZC3XX_R030_AUDIOADC 0x0030
-#define ZC3XX_R031_AUDIOSTREAMSTATUS 0x0031
-#define ZC3XX_R032_AUDIOSTATUS 0x0032
-
-/* Sensor interface */
-#define ZC3XX_R080_HBLANKHIGH 0x0080
-#define ZC3XX_R081_HBLANKLOW 0x0081
-#define ZC3XX_R082_RESETLEVELADDR 0x0082
-#define ZC3XX_R083_RGAINADDR 0x0083
-#define ZC3XX_R084_GGAINADDR 0x0084
-#define ZC3XX_R085_BGAINADDR 0x0085
-#define ZC3XX_R086_EXPTIMEHIGH 0x0086
-#define ZC3XX_R087_EXPTIMEMID 0x0087
-#define ZC3XX_R088_EXPTIMELOW 0x0088
-#define ZC3XX_R089_RESETBLACKHIGH 0x0089
-#define ZC3XX_R08A_RESETWHITEHIGH 0x008a
-#define ZC3XX_R08B_I2CDEVICEADDR 0x008b
-#define ZC3XX_R08C_I2CIDLEANDNACK 0x008c
-#define ZC3XX_R08D_COMPABILITYMODE 0x008d
-#define ZC3XX_R08E_COMPABILITYMODE2 0x008e
-
-/* I2C control */
-#define ZC3XX_R090_I2CCOMMAND 0x0090
-#define ZC3XX_R091_I2CSTATUS 0x0091
-#define ZC3XX_R092_I2CADDRESSSELECT 0x0092
-#define ZC3XX_R093_I2CSETVALUE 0x0093
-#define ZC3XX_R094_I2CWRITEACK 0x0094
-#define ZC3XX_R095_I2CREAD 0x0095
-#define ZC3XX_R096_I2CREADACK 0x0096
-
-/* Window inside the sensor array */
-#define ZC3XX_R097_WINYSTARTHIGH 0x0097
-#define ZC3XX_R098_WINYSTARTLOW 0x0098
-#define ZC3XX_R099_WINXSTARTHIGH 0x0099
-#define ZC3XX_R09A_WINXSTARTLOW 0x009a
-#define ZC3XX_R09B_WINHEIGHTHIGH 0x009b
-#define ZC3XX_R09C_WINHEIGHTLOW 0x009c
-#define ZC3XX_R09D_WINWIDTHHIGH 0x009d
-#define ZC3XX_R09E_WINWIDTHLOW 0x009e
-#define ZC3XX_R119_FIRSTYHIGH 0x0119
-#define ZC3XX_R11A_FIRSTYLOW 0x011a
-#define ZC3XX_R11B_FIRSTXHIGH 0x011b
-#define ZC3XX_R11C_FIRSTXLOW 0x011c
-
-/* Max sensor array size */
-#define ZC3XX_R09F_MAXXHIGH 0x009f
-#define ZC3XX_R0A0_MAXXLOW 0x00a0
-#define ZC3XX_R0A1_MAXYHIGH 0x00a1
-#define ZC3XX_R0A2_MAXYLOW 0x00a2
-#define ZC3XX_R0A3_EXPOSURETIMEHIGH 0x00a3
-#define ZC3XX_R0A4_EXPOSURETIMELOW 0x00a4
-#define ZC3XX_R0A5_EXPOSUREGAIN 0x00a5
-#define ZC3XX_R0A6_EXPOSUREBLACKLVL 0x00a6
-
-/* Other registers */
-#define ZC3XX_R100_OPERATIONMODE 0x0100
-#define ZC3XX_R101_SENSORCORRECTION 0x0101
-
-/* Gains */
-#define ZC3XX_R116_RGAIN 0x0116
-#define ZC3XX_R117_GGAIN 0x0117
-#define ZC3XX_R118_BGAIN 0x0118
-#define ZC3XX_R11D_GLOBALGAIN 0x011d
-#define ZC3XX_R1A8_DIGITALGAIN 0x01a8
-#define ZC3XX_R1A9_DIGITALLIMITDIFF 0x01a9
-#define ZC3XX_R1AA_DIGITALGAINSTEP 0x01aa
-
-/* Auto correction */
-#define ZC3XX_R180_AUTOCORRECTENABLE 0x0180
-#define ZC3XX_R181_WINXSTART 0x0181
-#define ZC3XX_R182_WINXWIDTH 0x0182
-#define ZC3XX_R183_WINXCENTER 0x0183
-#define ZC3XX_R184_WINYSTART 0x0184
-#define ZC3XX_R185_WINYWIDTH 0x0185
-#define ZC3XX_R186_WINYCENTER 0x0186
-
-/* Gain range */
-#define ZC3XX_R187_MAXGAIN 0x0187
-#define ZC3XX_R188_MINGAIN 0x0188
-
-/* Auto exposure and white balance */
-#define ZC3XX_R189_AWBSTATUS 0x0189
-#define ZC3XX_R18A_AWBFREEZE 0x018a
-#define ZC3XX_R18B_AESTATUS 0x018b
-#define ZC3XX_R18C_AEFREEZE 0x018c
-#define ZC3XX_R18F_AEUNFREEZE 0x018f
-#define ZC3XX_R190_EXPOSURELIMITHIGH 0x0190
-#define ZC3XX_R191_EXPOSURELIMITMID 0x0191
-#define ZC3XX_R192_EXPOSURELIMITLOW 0x0192
-#define ZC3XX_R195_ANTIFLICKERHIGH 0x0195
-#define ZC3XX_R196_ANTIFLICKERMID 0x0196
-#define ZC3XX_R197_ANTIFLICKERLOW 0x0197
-
-/* What is this ? */
-#define ZC3XX_R18D_YTARGET 0x018d
-#define ZC3XX_R18E_RESETLVL 0x018e
-
-/* Color */
-#define ZC3XX_R1A0_REDMEANAFTERAGC 0x01a0
-#define ZC3XX_R1A1_GREENMEANAFTERAGC 0x01a1
-#define ZC3XX_R1A2_BLUEMEANAFTERAGC 0x01a2
-#define ZC3XX_R1A3_REDMEANAFTERAWB 0x01a3
-#define ZC3XX_R1A4_GREENMEANAFTERAWB 0x01a4
-#define ZC3XX_R1A5_BLUEMEANAFTERAWB 0x01a5
-#define ZC3XX_R1A6_YMEANAFTERAE 0x01a6
-#define ZC3XX_R1A7_CALCGLOBALMEAN 0x01a7
-
-/* Matrixes */
-
-/* Color matrix is like :
- R' = R * RGB00 + G * RGB01 + B * RGB02 + RGB03
- G' = R * RGB10 + G * RGB11 + B * RGB22 + RGB13
- B' = R * RGB20 + G * RGB21 + B * RGB12 + RGB23
- */
-#define ZC3XX_R10A_RGB00 0x010a
-#define ZC3XX_R10B_RGB01 0x010b
-#define ZC3XX_R10C_RGB02 0x010c
-#define ZC3XX_R113_RGB03 0x0113
-#define ZC3XX_R10D_RGB10 0x010d
-#define ZC3XX_R10E_RGB11 0x010e
-#define ZC3XX_R10F_RGB12 0x010f
-#define ZC3XX_R114_RGB13 0x0114
-#define ZC3XX_R110_RGB20 0x0110
-#define ZC3XX_R111_RGB21 0x0111
-#define ZC3XX_R112_RGB22 0x0112
-#define ZC3XX_R115_RGB23 0x0115
-
-/* Gamma matrix */
-#define ZC3XX_R120_GAMMA00 0x0120
-#define ZC3XX_R121_GAMMA01 0x0121
-#define ZC3XX_R122_GAMMA02 0x0122
-#define ZC3XX_R123_GAMMA03 0x0123
-#define ZC3XX_R124_GAMMA04 0x0124
-#define ZC3XX_R125_GAMMA05 0x0125
-#define ZC3XX_R126_GAMMA06 0x0126
-#define ZC3XX_R127_GAMMA07 0x0127
-#define ZC3XX_R128_GAMMA08 0x0128
-#define ZC3XX_R129_GAMMA09 0x0129
-#define ZC3XX_R12A_GAMMA0A 0x012a
-#define ZC3XX_R12B_GAMMA0B 0x012b
-#define ZC3XX_R12C_GAMMA0C 0x012c
-#define ZC3XX_R12D_GAMMA0D 0x012d
-#define ZC3XX_R12E_GAMMA0E 0x012e
-#define ZC3XX_R12F_GAMMA0F 0x012f
-#define ZC3XX_R130_GAMMA10 0x0130
-#define ZC3XX_R131_GAMMA11 0x0131
-#define ZC3XX_R132_GAMMA12 0x0132
-#define ZC3XX_R133_GAMMA13 0x0133
-#define ZC3XX_R134_GAMMA14 0x0134
-#define ZC3XX_R135_GAMMA15 0x0135
-#define ZC3XX_R136_GAMMA16 0x0136
-#define ZC3XX_R137_GAMMA17 0x0137
-#define ZC3XX_R138_GAMMA18 0x0138
-#define ZC3XX_R139_GAMMA19 0x0139
-#define ZC3XX_R13A_GAMMA1A 0x013a
-#define ZC3XX_R13B_GAMMA1B 0x013b
-#define ZC3XX_R13C_GAMMA1C 0x013c
-#define ZC3XX_R13D_GAMMA1D 0x013d
-#define ZC3XX_R13E_GAMMA1E 0x013e
-#define ZC3XX_R13F_GAMMA1F 0x013f
-
-/* Luminance gamma */
-#define ZC3XX_R140_YGAMMA00 0x0140
-#define ZC3XX_R141_YGAMMA01 0x0141
-#define ZC3XX_R142_YGAMMA02 0x0142
-#define ZC3XX_R143_YGAMMA03 0x0143
-#define ZC3XX_R144_YGAMMA04 0x0144
-#define ZC3XX_R145_YGAMMA05 0x0145
-#define ZC3XX_R146_YGAMMA06 0x0146
-#define ZC3XX_R147_YGAMMA07 0x0147
-#define ZC3XX_R148_YGAMMA08 0x0148
-#define ZC3XX_R149_YGAMMA09 0x0149
-#define ZC3XX_R14A_YGAMMA0A 0x014a
-#define ZC3XX_R14B_YGAMMA0B 0x014b
-#define ZC3XX_R14C_YGAMMA0C 0x014c
-#define ZC3XX_R14D_YGAMMA0D 0x014d
-#define ZC3XX_R14E_YGAMMA0E 0x014e
-#define ZC3XX_R14F_YGAMMA0F 0x014f
-#define ZC3XX_R150_YGAMMA10 0x0150
-#define ZC3XX_R151_YGAMMA11 0x0151
-
-#define ZC3XX_R1C5_SHARPNESSMODE 0x01c5
-#define ZC3XX_R1C6_SHARPNESS00 0x01c6
-#define ZC3XX_R1C7_SHARPNESS01 0x01c7
-#define ZC3XX_R1C8_SHARPNESS02 0x01c8
-#define ZC3XX_R1C9_SHARPNESS03 0x01c9
-#define ZC3XX_R1CA_SHARPNESS04 0x01ca
-#define ZC3XX_R1CB_SHARPNESS05 0x01cb
-
-/* Dead pixels */
-#define ZC3XX_R250_DEADPIXELSMODE 0x0250
-
-/* EEPROM */
-#define ZC3XX_R300_EEPROMCONFIG 0x0300
-#define ZC3XX_R301_EEPROMACCESS 0x0301
-#define ZC3XX_R302_EEPROMSTATUS 0x0302
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
deleted file mode 100644
index f0bacee33ef..00000000000
--- a/drivers/media/video/gspca/zc3xx.c
+++ /dev/null
@@ -1,7024 +0,0 @@
-/*
- * Z-Star/Vimicro zc301/zc302p/vc30x driver
- *
- * Copyright (C) 2009-2012 Jean-Francois Moine <http://moinejf.free.fr>
- * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/input.h>
-#include "gspca.h"
-#include "jpeg.h"
-
-MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
- "Serge A. Suchkov <Serge.A.S@tochka.ru>");
-MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver");
-MODULE_LICENSE("GPL");
-
-static int force_sensor = -1;
-
-#define REG08_DEF 3 /* default JPEG compression (75%) */
-#include "zc3xx-reg.h"
-
-/* specific webcam descriptor */
-struct sd {
- struct gspca_dev gspca_dev; /* !! must be the first item */
-
- struct { /* gamma/brightness/contrast control cluster */
- struct v4l2_ctrl *gamma;
- struct v4l2_ctrl *brightness;
- struct v4l2_ctrl *contrast;
- };
- struct { /* autogain/exposure control cluster */
- struct v4l2_ctrl *autogain;
- struct v4l2_ctrl *exposure;
- };
- struct v4l2_ctrl *plfreq;
- struct v4l2_ctrl *sharpness;
- struct v4l2_ctrl *jpegqual;
-
- struct work_struct work;
- struct workqueue_struct *work_thread;
-
- u8 reg08; /* webcam compression quality */
-
- u8 bridge;
- u8 sensor; /* Type of image sensor chip */
- u16 chip_revision;
-
- u8 jpeg_hdr[JPEG_HDR_SZ];
-};
-enum bridges {
- BRIDGE_ZC301,
- BRIDGE_ZC303,
-};
-enum sensors {
- SENSOR_ADCM2700,
- SENSOR_CS2102,
- SENSOR_CS2102K,
- SENSOR_GC0303,
- SENSOR_GC0305,
- SENSOR_HDCS2020,
- SENSOR_HV7131B,
- SENSOR_HV7131R,
- SENSOR_ICM105A,
- SENSOR_MC501CB,
- SENSOR_MT9V111_1, /* (mi360soc) zc301 */
- SENSOR_MT9V111_3, /* (mi360soc) zc303 */
- SENSOR_OV7620, /* OV7648 - same values */
- SENSOR_OV7630C,
- SENSOR_PAS106,
- SENSOR_PAS202B,
- SENSOR_PB0330,
- SENSOR_PO2030,
- SENSOR_TAS5130C,
- SENSOR_MAX
-};
-
-static const struct v4l2_pix_format vga_mode[] = {
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-
-static const struct v4l2_pix_format broken_vga_mode[] = {
- {320, 232, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 232 * 4 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {640, 472, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 472 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-
-static const struct v4l2_pix_format sif_mode[] = {
- {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1},
- {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 352,
- .sizeimage = 352 * 288 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0},
-};
-
-/*
- * Bridge reg08 bits 1-2 -> JPEG quality conversion table. Note the highest
- * quality setting is not usable as USB 1 does not have enough bandwidth.
- */
-static u8 jpeg_qual[] = {50, 75, 87, /* 94 */};
-
-/* usb exchanges */
-struct usb_action {
- u8 req;
- u8 val;
- u16 idx;
-};
-
-static const struct usb_action adcm2700_Initial[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
- {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */
- {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
- {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
- {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */
- {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
- {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
- {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
- {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */
- {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
- {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
- {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */
- {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */
- {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
- {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */
- {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */
- {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */
- {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */
- {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */
- {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */
- {0xbb, 0x86, 0x0002}, /* 00,86,02,bb */
- {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */
- {0xbb, 0x86, 0x0802}, /* 08,86,02,bb */
- {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */
-/*mswin+*/
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},
- {0xaa, 0xfe, 0x0002},
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
- {0xaa, 0xb4, 0xcd37},
- {0xaa, 0xa4, 0x0004},
- {0xaa, 0xa8, 0x0007},
- {0xaa, 0xac, 0x0004},
-/*mswin-*/
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */
- {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
- {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */
- {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
- {}
-};
-static const struct usb_action adcm2700_InitialScale[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
- {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
- {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
- {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
- {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
- {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
- {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */
- {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
- {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
- {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */
- {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */
- {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
- {0xdd, 0x00, 0x0050}, /* 00,00,50,dd */
- {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
- {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */
- {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */
- {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */
- {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */
- {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */
- {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */
- {0xbb, 0x86, 0x0002}, /* 00,88,02,bb */
- {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */
- {0xbb, 0x86, 0x0802}, /* 08,88,02,bb */
- {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */
- /*******/
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
- {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */
- {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
- {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */
- {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
- {}
-};
-static const struct usb_action adcm2700_50HZ[] = {
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xbb, 0x05, 0x8400}, /* 84,05,00,bb */
- {0xbb, 0xd0, 0xb007}, /* b0,d0,07,bb */
- {0xbb, 0xa0, 0xb80f}, /* b8,a0,0f,bb */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
- {0xaa, 0x26, 0x00d0}, /* 00,26,d0,aa */
- {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */
- {}
-};
-static const struct usb_action adcm2700_60HZ[] = {
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */
- {0xbb, 0x82, 0xb006}, /* b0,82,06,bb */
- {0xbb, 0x04, 0xb80d}, /* b8,04,0d,bb */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
- {0xaa, 0x26, 0x0057}, /* 00,26,57,aa */
- {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */
- {}
-};
-static const struct usb_action adcm2700_NoFliker[] = {
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
- {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */
- {0xbb, 0x05, 0xb000}, /* b0,05,00,bb */
- {0xbb, 0xa0, 0xb801}, /* b8,a0,01,bb */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
- {}
-};
-static const struct usb_action cs2102_InitialScale[] = { /* 320x240 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x20, ZC3XX_R080_HBLANKHIGH},
- {0xa0, 0x21, ZC3XX_R081_HBLANKLOW},
- {0xa0, 0x30, ZC3XX_R083_RGAINADDR},
- {0xa0, 0x31, ZC3XX_R084_GGAINADDR},
- {0xa0, 0x32, ZC3XX_R085_BGAINADDR},
- {0xa0, 0x23, ZC3XX_R086_EXPTIMEHIGH},
- {0xa0, 0x24, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0x25, ZC3XX_R088_EXPTIMELOW},
- {0xa0, 0xb3, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xaa, 0x02, 0x0008},
- {0xaa, 0x03, 0x0000},
- {0xaa, 0x11, 0x0000},
- {0xaa, 0x12, 0x0089},
- {0xaa, 0x13, 0x0000},
- {0xaa, 0x14, 0x00e9},
- {0xaa, 0x20, 0x0000},
- {0xaa, 0x22, 0x0000},
- {0xaa, 0x0b, 0x0004},
- {0xaa, 0x30, 0x0030},
- {0xaa, 0x31, 0x0030},
- {0xaa, 0x32, 0x0030},
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x10, 0x01ae},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x68, ZC3XX_R18D_YTARGET},
- {0xa0, 0x00, 0x01ad},
- {}
-};
-
-static const struct usb_action cs2102_Initial[] = { /* 640x480 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x20, ZC3XX_R080_HBLANKHIGH},
- {0xa0, 0x21, ZC3XX_R081_HBLANKLOW},
- {0xa0, 0x30, ZC3XX_R083_RGAINADDR},
- {0xa0, 0x31, ZC3XX_R084_GGAINADDR},
- {0xa0, 0x32, ZC3XX_R085_BGAINADDR},
- {0xa0, 0x23, ZC3XX_R086_EXPTIMEHIGH},
- {0xa0, 0x24, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0x25, ZC3XX_R088_EXPTIMELOW},
- {0xa0, 0xb3, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xaa, 0x02, 0x0008},
- {0xaa, 0x03, 0x0000},
- {0xaa, 0x11, 0x0001},
- {0xaa, 0x12, 0x0087},
- {0xaa, 0x13, 0x0001},
- {0xaa, 0x14, 0x00e7},
- {0xaa, 0x20, 0x0000},
- {0xaa, 0x22, 0x0000},
- {0xaa, 0x0b, 0x0004},
- {0xaa, 0x30, 0x0030},
- {0xaa, 0x31, 0x0030},
- {0xaa, 0x32, 0x0030},
- {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x15, 0x01ae},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x68, ZC3XX_R18D_YTARGET},
- {0xa0, 0x00, 0x01ad},
- {}
-};
-static const struct usb_action cs2102_50HZScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x23, 0x0001},
- {0xaa, 0x24, 0x005f},
- {0xaa, 0x25, 0x0090},
- {0xaa, 0x21, 0x00dd},
- {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0xbf, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x3a, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x98, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xdd, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xe4, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action cs2102_50HZ[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x23, 0x0000},
- {0xaa, 0x24, 0x00af},
- {0xaa, 0x25, 0x00c8},
- {0xaa, 0x21, 0x0068},
- {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x5f, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x90, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x1d, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x4c, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x68, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xe3, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action cs2102_60HZScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x23, 0x0001},
- {0xaa, 0x24, 0x0055},
- {0xaa, 0x25, 0x00cc},
- {0xaa, 0x21, 0x003f},
- {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x39, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x70, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xb0, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action cs2102_60HZ[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x23, 0x0000},
- {0xaa, 0x24, 0x00aa},
- {0xaa, 0x25, 0x00e6},
- {0xaa, 0x21, 0x003f},
- {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x55, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xcc, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x18, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x6a, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x3f, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xa5, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action cs2102_NoFlikerScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x23, 0x0001},
- {0xaa, 0x24, 0x005f},
- {0xaa, 0x25, 0x0000},
- {0xaa, 0x21, 0x0001},
- {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0xbf, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x80, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x01, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xa0, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action cs2102_NoFliker[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x23, 0x0000},
- {0xaa, 0x24, 0x00af},
- {0xaa, 0x25, 0x0080},
- {0xaa, 0x21, 0x0001},
- {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x5f, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x80, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x01, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xa0, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {}
-};
-
-/* CS2102_KOCOM */
-static const struct usb_action cs2102K_InitialScale[] = {
- {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
- {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0a, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0b, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0c, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x7c, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0d, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0xa3, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0e, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x78, ZC3XX_R18D_YTARGET},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0x01, 0x01b1},
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x60, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x4c, ZC3XX_R118_BGAIN},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
- {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
- {0xa0, 0x38, ZC3XX_R121_GAMMA01},
- {0xa0, 0x59, ZC3XX_R122_GAMMA02},
- {0xa0, 0x79, ZC3XX_R123_GAMMA03},
- {0xa0, 0x92, ZC3XX_R124_GAMMA04},
- {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
- {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
- {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
- {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
- {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
- {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
- {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
- {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
- {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
- {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
- {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
- {0xa0, 0x26, ZC3XX_R130_GAMMA10},
- {0xa0, 0x22, ZC3XX_R131_GAMMA11},
- {0xa0, 0x20, ZC3XX_R132_GAMMA12},
- {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
- {0xa0, 0x16, ZC3XX_R134_GAMMA14},
- {0xa0, 0x13, ZC3XX_R135_GAMMA15},
- {0xa0, 0x10, ZC3XX_R136_GAMMA16},
- {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
- {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
- {0xa0, 0x09, ZC3XX_R139_GAMMA19},
- {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
- {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
- {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
- {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
- {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
- {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
- {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf4, ZC3XX_R10B_RGB01},
- {0xa0, 0xf4, ZC3XX_R10C_RGB02},
- {0xa0, 0xf4, ZC3XX_R10D_RGB10},
- {0xa0, 0x58, ZC3XX_R10E_RGB11},
- {0xa0, 0xf4, ZC3XX_R10F_RGB12},
- {0xa0, 0xf4, ZC3XX_R110_RGB20},
- {0xa0, 0xf4, ZC3XX_R111_RGB21},
- {0xa0, 0x58, ZC3XX_R112_RGB22},
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
- {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x04, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x19, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x1f, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x60, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x4c, ZC3XX_R118_BGAIN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {}
-};
-
-static const struct usb_action cs2102K_Initial[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
-/*fixme: next sequence = i2c exchanges*/
- {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0a, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0b, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0c, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0d, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0xa3, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0e, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x78, ZC3XX_R18D_YTARGET},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0x01, 0x01b1},
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x60, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x4c, ZC3XX_R118_BGAIN},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
- {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
- {0xa0, 0x38, ZC3XX_R121_GAMMA01},
- {0xa0, 0x59, ZC3XX_R122_GAMMA02},
- {0xa0, 0x79, ZC3XX_R123_GAMMA03},
- {0xa0, 0x92, ZC3XX_R124_GAMMA04},
- {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
- {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
- {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
- {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
- {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
- {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
- {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
- {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
- {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
- {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
- {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
- {0xa0, 0x26, ZC3XX_R130_GAMMA10},
- {0xa0, 0x22, ZC3XX_R131_GAMMA11},
- {0xa0, 0x20, ZC3XX_R132_GAMMA12},
- {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
- {0xa0, 0x16, ZC3XX_R134_GAMMA14},
- {0xa0, 0x13, ZC3XX_R135_GAMMA15},
- {0xa0, 0x10, ZC3XX_R136_GAMMA16},
- {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
- {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
- {0xa0, 0x09, ZC3XX_R139_GAMMA19},
- {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
- {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
- {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
- {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
- {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
- {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
- {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf4, ZC3XX_R10B_RGB01},
- {0xa0, 0xf4, ZC3XX_R10C_RGB02},
- {0xa0, 0xf4, ZC3XX_R10D_RGB10},
- {0xa0, 0x58, ZC3XX_R10E_RGB11},
- {0xa0, 0xf4, ZC3XX_R10F_RGB12},
- {0xa0, 0xf4, ZC3XX_R110_RGB20},
- {0xa0, 0xf4, ZC3XX_R111_RGB21},
- {0xa0, 0x58, ZC3XX_R112_RGB22},
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
- {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x04, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x19, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x1f, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x60, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x4c, ZC3XX_R118_BGAIN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
-/*fixme:what does the next sequence?*/
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0xd0, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0xd0, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x0a, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x0a, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x44, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x44, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x7e, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x7e, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {}
-};
-
-static const struct usb_action gc0305_Initial[] = { /* 640x480 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
- {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc */
- {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
- {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc */
- {0xaa, 0x13, 0x0002}, /* 00,13,02,aa */
- {0xaa, 0x15, 0x0003}, /* 00,15,03,aa */
- {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */
- {0xaa, 0x02, 0x0000}, /* 00,02,00,aa */
- {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
- {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa */
- {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */
- {0xaa, 0x1f, 0x0008}, /* 00,1f,08,aa */
- {0xaa, 0x21, 0x0012}, /* 00,21,12,aa */
- {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc */
- {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc */
- {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc */
- {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */
- {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa */
- {0xaa, 0x0b, 0x00b0}, /* 00,0b,b0,aa */
- {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa */
- {0xaa, 0x0d, 0x00b0}, /* 00,0d,b0,aa */
- {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa */
- {0xaa, 0x0f, 0x00b0}, /* 00,0f,b0,aa */
- {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
- {0xaa, 0x11, 0x00b0}, /* 00,11,b0,aa */
- {0xaa, 0x16, 0x0001}, /* 00,16,01,aa */
- {0xaa, 0x17, 0x00e6}, /* 00,17,e6,aa */
- {0xaa, 0x18, 0x0002}, /* 00,18,02,aa */
- {0xaa, 0x19, 0x0086}, /* 00,19,86,aa */
- {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
- {0xaa, 0x1b, 0x0020}, /* 00,1b,20,aa */
- {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc */
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
- {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc */
- {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
- {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */
- {0xa0, 0x85, ZC3XX_R18D_YTARGET}, /* 01,8d,85,cc */
- {0xa0, 0x00, 0x011e}, /* 01,1e,00,cc */
- {0xa0, 0x52, ZC3XX_R116_RGAIN}, /* 01,16,52,cc */
- {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* 01,17,40,cc */
- {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */
- {0xa0, 0x03, ZC3XX_R113_RGB03}, /* 01,13,03,cc */
- {}
-};
-static const struct usb_action gc0305_InitialScale[] = { /* 320x240 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc */
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
- {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc */
- {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */
- {0xaa, 0x15, 0x0001}, /* 00,15,01,aa */
- {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */
- {0xaa, 0x02, 0x0000}, /* 00,02,00,aa */
- {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
- {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa */
- {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */
- {0xaa, 0x1f, 0x0008}, /* 00,1f,08,aa */
- {0xaa, 0x21, 0x0012}, /* 00,21,12,aa */
- {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc */
- {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc */
- {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc */
- {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */
- {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa */
- {0xaa, 0x0b, 0x00b0}, /* 00,0b,b0,aa */
- {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa */
- {0xaa, 0x0d, 0x00b0}, /* 00,0d,b0,aa */
- {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa */
- {0xaa, 0x0f, 0x00b0}, /* 00,0f,b0,aa */
- {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
- {0xaa, 0x11, 0x00b0}, /* 00,11,b0,aa */
- {0xaa, 0x16, 0x0001}, /* 00,16,01,aa */
- {0xaa, 0x17, 0x00e8}, /* 00,17,e8,aa */
- {0xaa, 0x18, 0x0002}, /* 00,18,02,aa */
- {0xaa, 0x19, 0x0088}, /* 00,19,88,aa */
- {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
- {0xaa, 0x1b, 0x0020}, /* 00,1b,20,aa */
- {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc */
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
- {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc */
- {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
- {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */
- {0xa0, 0x00, 0x011e}, /* 01,1e,00,cc */
- {0xa0, 0x52, ZC3XX_R116_RGAIN}, /* 01,16,52,cc */
- {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* 01,17,40,cc */
- {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */
- {0xa0, 0x03, ZC3XX_R113_RGB03}, /* 01,13,03,cc */
- {}
-};
-static const struct usb_action gc0305_50HZ[] = {
- {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
- {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */
- {0xaa, 0x84, 0x0038}, /* 00,84,38,aa */ /* win: 00,84,ec */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc */
- {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */
- /* win: 01,92,10 */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,8e,cc */
- /* win: 01,97,ec */
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */
- {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
- {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */
- {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
- {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */
-/* {0xa0, 0x85, ZC3XX_R18D_YTARGET}, * 01,8d,85,cc *
- * if 640x480 */
- {}
-};
-static const struct usb_action gc0305_60HZ[] = {
- {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
- {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
- {0xaa, 0x84, 0x00ec}, /* 00,84,ec,aa */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc */
- {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0xec, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,ec,cc */
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */
- {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
- {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */
- {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
- {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */
- {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* 01,8d,80,cc */
- {}
-};
-
-static const struct usb_action gc0305_NoFliker[] = {
- {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc */
- {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
- {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
- {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,00,cc */
- {0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,48,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */
- {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */
- {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */
- {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
- {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */
- {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */
- {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* 01,8d,80,cc */
- {}
-};
-
-static const struct usb_action hdcs2020_InitialScale[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* qtable 0x05 */
- {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
- {0xaa, 0x1c, 0x0000},
- {0xaa, 0x0a, 0x0001},
- {0xaa, 0x0b, 0x0006},
- {0xaa, 0x0c, 0x007b},
- {0xaa, 0x0d, 0x00a7},
- {0xaa, 0x03, 0x00fb},
- {0xaa, 0x05, 0x0000},
- {0xaa, 0x06, 0x0003},
- {0xaa, 0x09, 0x0008},
-
- {0xaa, 0x0f, 0x0018}, /* set sensor gain */
- {0xaa, 0x10, 0x0018},
- {0xaa, 0x11, 0x0018},
- {0xaa, 0x12, 0x0018},
-
- {0xaa, 0x15, 0x004e},
- {0xaa, 0x1c, 0x0004},
- {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x70, ZC3XX_R18D_YTARGET},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa1, 0x01, 0x0002},
- {0xa1, 0x01, 0x0008},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x40, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x40, ZC3XX_R118_BGAIN},
- {0xa1, 0x01, 0x0008},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa1, 0x01, 0x01c8},
- {0xa1, 0x01, 0x01c9},
- {0xa1, 0x01, 0x01ca},
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
- {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
- {0xa0, 0x38, ZC3XX_R121_GAMMA01},
- {0xa0, 0x59, ZC3XX_R122_GAMMA02},
- {0xa0, 0x79, ZC3XX_R123_GAMMA03},
- {0xa0, 0x92, ZC3XX_R124_GAMMA04},
- {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
- {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
- {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
- {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
- {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
- {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
- {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
- {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
- {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
- {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
- {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
- {0xa0, 0x26, ZC3XX_R130_GAMMA10},
- {0xa0, 0x22, ZC3XX_R131_GAMMA11},
- {0xa0, 0x20, ZC3XX_R132_GAMMA12},
- {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
- {0xa0, 0x16, ZC3XX_R134_GAMMA14},
- {0xa0, 0x13, ZC3XX_R135_GAMMA15},
- {0xa0, 0x10, ZC3XX_R136_GAMMA16},
- {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
- {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
- {0xa0, 0x09, ZC3XX_R139_GAMMA19},
- {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
- {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
- {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
- {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
- {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
- {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
-
- {0xa0, 0x66, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xed, ZC3XX_R10B_RGB01},
- {0xa0, 0xed, ZC3XX_R10C_RGB02},
- {0xa0, 0xed, ZC3XX_R10D_RGB10},
- {0xa0, 0x66, ZC3XX_R10E_RGB11},
- {0xa0, 0xed, ZC3XX_R10F_RGB12},
- {0xa0, 0xed, ZC3XX_R110_RGB20},
- {0xa0, 0xed, ZC3XX_R111_RGB21},
- {0xa0, 0x66, ZC3XX_R112_RGB22},
-
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x13, 0x0031},
- {0xaa, 0x14, 0x0001},
- {0xaa, 0x0e, 0x0004},
- {0xaa, 0x19, 0x00cd},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
-
- {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 0x14 */
- {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x04, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x18, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x41, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x40, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x40, ZC3XX_R118_BGAIN},
- {}
-};
-static const struct usb_action hdcs2020_Initial[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
- {0xaa, 0x1c, 0x0000},
- {0xaa, 0x0a, 0x0001},
- {0xaa, 0x0b, 0x0006},
- {0xaa, 0x0c, 0x007a},
- {0xaa, 0x0d, 0x00a7},
- {0xaa, 0x03, 0x00fb},
- {0xaa, 0x05, 0x0000},
- {0xaa, 0x06, 0x0003},
- {0xaa, 0x09, 0x0008},
- {0xaa, 0x0f, 0x0018}, /* original setting */
- {0xaa, 0x10, 0x0018},
- {0xaa, 0x11, 0x0018},
- {0xaa, 0x12, 0x0018},
- {0xaa, 0x15, 0x004e},
- {0xaa, 0x1c, 0x0004},
- {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x70, ZC3XX_R18D_YTARGET},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa1, 0x01, 0x0002},
- {0xa1, 0x01, 0x0008},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x40, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x40, ZC3XX_R118_BGAIN},
- {0xa1, 0x01, 0x0008},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa1, 0x01, 0x01c8},
- {0xa1, 0x01, 0x01c9},
- {0xa1, 0x01, 0x01ca},
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
- {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
- {0xa0, 0x38, ZC3XX_R121_GAMMA01},
- {0xa0, 0x59, ZC3XX_R122_GAMMA02},
- {0xa0, 0x79, ZC3XX_R123_GAMMA03},
- {0xa0, 0x92, ZC3XX_R124_GAMMA04},
- {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
- {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
- {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
- {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
- {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
- {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
- {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
- {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
- {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
- {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
- {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
- {0xa0, 0x26, ZC3XX_R130_GAMMA10},
- {0xa0, 0x22, ZC3XX_R131_GAMMA11},
- {0xa0, 0x20, ZC3XX_R132_GAMMA12},
- {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
- {0xa0, 0x16, ZC3XX_R134_GAMMA14},
- {0xa0, 0x13, ZC3XX_R135_GAMMA15},
- {0xa0, 0x10, ZC3XX_R136_GAMMA16},
- {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
- {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
- {0xa0, 0x09, ZC3XX_R139_GAMMA19},
- {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
- {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
- {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
- {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
- {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
- {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
- {0xa0, 0x66, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xed, ZC3XX_R10B_RGB01},
- {0xa0, 0xed, ZC3XX_R10C_RGB02},
- {0xa0, 0xed, ZC3XX_R10D_RGB10},
- {0xa0, 0x66, ZC3XX_R10E_RGB11},
- {0xa0, 0xed, ZC3XX_R10F_RGB12},
- {0xa0, 0xed, ZC3XX_R110_RGB20},
- {0xa0, 0xed, ZC3XX_R111_RGB21},
- {0xa0, 0x66, ZC3XX_R112_RGB22},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- /**** set exposure ***/
- {0xaa, 0x13, 0x0031},
- {0xaa, 0x14, 0x0001},
- {0xaa, 0x0e, 0x0004},
- {0xaa, 0x19, 0x00cd},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x04, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x18, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x41, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x40, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x40, ZC3XX_R118_BGAIN},
- {}
-};
-static const struct usb_action hdcs2020_50HZ[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */
- {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
- {0xaa, 0x0e, 0x0005}, /* 00,0e,05,aa */
- {0xaa, 0x19, 0x001f}, /* 00,19,1f,aa */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
- {0xa0, 0x76, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,76,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x46, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,46,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
- {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
- {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,28,cc */
- {0xa0, 0x05, ZC3XX_R01D_HSYNC_0}, /* 00,1d,05,cc */
- {0xa0, 0x1a, ZC3XX_R01E_HSYNC_1}, /* 00,1e,1a,cc */
- {0xa0, 0x2f, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2f,cc */
- {}
-};
-static const struct usb_action hdcs2020_60HZ[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */
- {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
- {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */
- {0xaa, 0x19, 0x00cd}, /* 00,19,cd,aa */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
- {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,62,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3d,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
- {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
- {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,28,cc */
- {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, /* 00,1d,04,cc */
- {0xa0, 0x18, ZC3XX_R01E_HSYNC_1}, /* 00,1e,18,cc */
- {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2c,cc */
- {}
-};
-static const struct usb_action hdcs2020_NoFliker[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */
- {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
- {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */
- {0xaa, 0x19, 0x0000}, /* 00,19,00,aa */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
- {0xa0, 0x70, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,70,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
- {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, /* 00,1d,04,cc */
- {0xa0, 0x17, ZC3XX_R01E_HSYNC_1}, /* 00,1e,17,cc */
- {0xa0, 0x2a, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2a,cc */
- {}
-};
-
-static const struct usb_action hv7131b_InitialScale[] = { /* 320x240 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xaa, 0x30, 0x002d},
- {0xaa, 0x01, 0x0005},
- {0xaa, 0x11, 0x0000},
- {0xaa, 0x13, 0x0001}, /* {0xaa, 0x13, 0x0000}, */
- {0xaa, 0x14, 0x0001},
- {0xaa, 0x15, 0x00e8},
- {0xaa, 0x16, 0x0002},
- {0xaa, 0x17, 0x0086}, /* 00,17,88,aa */
- {0xaa, 0x31, 0x0038},
- {0xaa, 0x32, 0x0038},
- {0xaa, 0x33, 0x0038},
- {0xaa, 0x5b, 0x0001},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x68, ZC3XX_R18D_YTARGET},
- {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0xc0, 0x019b},
- {0xa0, 0xa0, 0x019c},
- {0xa0, 0x02, ZC3XX_R188_MINGAIN},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xaa, 0x02, 0x0090}, /* 00,02,80,aa */
- {}
-};
-
-static const struct usb_action hv7131b_Initial[] = { /* 640x480*/
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xaa, 0x30, 0x002d},
- {0xaa, 0x01, 0x0005},
- {0xaa, 0x11, 0x0001},
- {0xaa, 0x13, 0x0000}, /* {0xaa, 0x13, 0x0001}; */
- {0xaa, 0x14, 0x0001},
- {0xaa, 0x15, 0x00e6},
- {0xaa, 0x16, 0x0002},
- {0xaa, 0x17, 0x0086},
- {0xaa, 0x31, 0x0038},
- {0xaa, 0x32, 0x0038},
- {0xaa, 0x33, 0x0038},
- {0xaa, 0x5b, 0x0001},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x70, ZC3XX_R18D_YTARGET},
- {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0xc0, 0x019b},
- {0xa0, 0xa0, 0x019c},
- {0xa0, 0x02, ZC3XX_R188_MINGAIN},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xaa, 0x02, 0x0090}, /* {0xaa, 0x02, 0x0080}, */
- {}
-};
-static const struct usb_action hv7131b_50HZ[] = { /* 640x480*/
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
- {0xaa, 0x26, 0x0053}, /* 00,26,53,aa */
- {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
- {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
- {0xaa, 0x21, 0x0050}, /* 00,21,50,aa */
- {0xaa, 0x22, 0x001b}, /* 00,22,1b,aa */
- {0xaa, 0x23, 0x00fc}, /* 00,23,fc,aa */
- {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
- {0xa0, 0x9b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,9b,cc */
- {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,80,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0xea, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,ea,cc */
- {0xa0, 0x60, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,60,cc */
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */
- {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
- {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
- {0xa0, 0x1b, ZC3XX_R01F_HSYNC_2}, /* 00,1f,1b,cc */
- {0xa0, 0xfc, ZC3XX_R020_HSYNC_3}, /* 00,20,fc,cc */
- {}
-};
-static const struct usb_action hv7131b_50HZScale[] = { /* 320x240 */
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
- {0xaa, 0x26, 0x0053}, /* 00,26,53,aa */
- {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
- {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
- {0xaa, 0x21, 0x0050}, /* 00,21,50,aa */
- {0xaa, 0x22, 0x0012}, /* 00,22,12,aa */
- {0xaa, 0x23, 0x0080}, /* 00,23,80,aa */
- {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
- {0xa0, 0x9b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,9b,cc */
- {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,80,cc */
- {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,01,cc */
- {0xa0, 0xd4, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,d4,cc */
- {0xa0, 0xc0, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,c0,cc */
- {0xa0, 0x07, ZC3XX_R18C_AEFREEZE}, /* 01,8c,07,cc */
- {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,0f,cc */
- {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
- {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
- {0xa0, 0x12, ZC3XX_R01F_HSYNC_2}, /* 00,1f,12,cc */
- {0xa0, 0x80, ZC3XX_R020_HSYNC_3}, /* 00,20,80,cc */
- {}
-};
-static const struct usb_action hv7131b_60HZ[] = { /* 640x480*/
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
- {0xaa, 0x26, 0x00a1}, /* 00,26,a1,aa */
- {0xaa, 0x27, 0x0020}, /* 00,27,20,aa */
- {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
- {0xaa, 0x21, 0x0040}, /* 00,21,40,aa */
- {0xaa, 0x22, 0x0013}, /* 00,22,13,aa */
- {0xaa, 0x23, 0x004c}, /* 00,23,4c,aa */
- {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
- {0xa0, 0x4d, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,4d,cc */
- {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,60,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0xc3, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,c3,cc */
- {0xa0, 0x50, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,50,cc */
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */
- {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
- {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */
- {0xa0, 0x13, ZC3XX_R01F_HSYNC_2}, /* 00,1f,13,cc */
- {0xa0, 0x4c, ZC3XX_R020_HSYNC_3}, /* 00,20,4c,cc */
- {}
-};
-static const struct usb_action hv7131b_60HZScale[] = { /* 320x240 */
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
- {0xaa, 0x26, 0x00a1}, /* 00,26,a1,aa */
- {0xaa, 0x27, 0x0020}, /* 00,27,20,aa */
- {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
- {0xaa, 0x21, 0x00a0}, /* 00,21,a0,aa */
- {0xaa, 0x22, 0x0016}, /* 00,22,16,aa */
- {0xaa, 0x23, 0x0040}, /* 00,23,40,aa */
- {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
- {0xa0, 0x4d, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,4d,cc */
- {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,60,cc */
- {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,01,cc */
- {0xa0, 0x86, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,86,cc */
- {0xa0, 0xa0, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,a0,cc */
- {0xa0, 0x07, ZC3XX_R18C_AEFREEZE}, /* 01,8c,07,cc */
- {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,0f,cc */
- {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
- {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,a0,cc */
- {0xa0, 0x16, ZC3XX_R01F_HSYNC_2}, /* 00,1f,16,cc */
- {0xa0, 0x40, ZC3XX_R020_HSYNC_3}, /* 00,20,40,cc */
- {}
-};
-static const struct usb_action hv7131b_NoFliker[] = { /* 640x480*/
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x25, 0x0003}, /* 00,25,03,aa */
- {0xaa, 0x26, 0x0000}, /* 00,26,00,aa */
- {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
- {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
- {0xaa, 0x21, 0x0010}, /* 00,21,10,aa */
- {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */
- {0xaa, 0x23, 0x0003}, /* 00,23,03,aa */
- {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
- {0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,f8,cc */
- {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,00,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x02, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,02,cc */
- {0xa0, 0x00, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,00,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
- {0xa0, 0x10, ZC3XX_R01E_HSYNC_1}, /* 00,1e,10,cc */
- {0xa0, 0x00, ZC3XX_R01F_HSYNC_2}, /* 00,1f,00,cc */
- {0xa0, 0x03, ZC3XX_R020_HSYNC_3}, /* 00,20,03,cc */
- {}
-};
-static const struct usb_action hv7131b_NoFlikerScale[] = { /* 320x240 */
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x25, 0x0003}, /* 00,25,03,aa */
- {0xaa, 0x26, 0x0000}, /* 00,26,00,aa */
- {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
- {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
- {0xaa, 0x21, 0x00a0}, /* 00,21,a0,aa */
- {0xaa, 0x22, 0x0016}, /* 00,22,16,aa */
- {0xaa, 0x23, 0x0040}, /* 00,23,40,aa */
- {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */
- {0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,f8,cc */
- {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,00,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x02, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,02,cc */
- {0xa0, 0x00, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,00,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
- {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,a0,cc */
- {0xa0, 0x16, ZC3XX_R01F_HSYNC_2}, /* 00,1f,16,cc */
- {0xa0, 0x40, ZC3XX_R020_HSYNC_3}, /* 00,20,40,cc */
- {}
-};
-
-/* from lPEPI264v.inf (hv7131b!) */
-static const struct usb_action hv7131r_InitialScale[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xdd, 0x00, 0x0200},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xaa, 0x01, 0x000c},
- {0xaa, 0x11, 0x0000},
- {0xaa, 0x13, 0x0000},
- {0xaa, 0x14, 0x0001},
- {0xaa, 0x15, 0x00e8},
- {0xaa, 0x16, 0x0002},
- {0xaa, 0x17, 0x0088},
- {0xaa, 0x30, 0x000b},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x78, ZC3XX_R18D_YTARGET},
- {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0xc0, 0x019b},
- {0xa0, 0xa0, 0x019c},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {}
-};
-static const struct usb_action hv7131r_Initial[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
- {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
- {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xdd, 0x00, 0x0200},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xaa, 0x01, 0x000c},
- {0xaa, 0x11, 0x0000},
- {0xaa, 0x13, 0x0000},
- {0xaa, 0x14, 0x0001},
- {0xaa, 0x15, 0x00e6},
- {0xaa, 0x16, 0x0002},
- {0xaa, 0x17, 0x0086},
- {0xaa, 0x30, 0x000b},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x78, ZC3XX_R18D_YTARGET},
- {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0xc0, 0x019b},
- {0xa0, 0xa0, 0x019c},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {}
-};
-static const struct usb_action hv7131r_50HZ[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x06, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x68, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0xea, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x60, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x18, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x00, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x08, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action hv7131r_50HZScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x0c, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0xd1, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x40, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0xd4, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0xc0, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x18, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x00, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x08, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action hv7131r_60HZ[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x06, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x1a, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0xc3, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x50, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x18, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x00, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x08, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action hv7131r_60HZScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x0c, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x35, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x86, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0xa0, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x18, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x00, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x08, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action hv7131r_NoFliker[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x02, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x58, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x00, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x08, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action hv7131r_NoFlikerScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x04, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0xb0, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x00, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x08, ZC3XX_R020_HSYNC_3},
- {}
-};
-
-static const struct usb_action icm105a_InitialScale[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x0c, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x00, ZC3XX_R097_WINYSTARTHIGH},
- {0xa0, 0x01, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R099_WINXSTARTHIGH},
- {0xa0, 0x01, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x01, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x01, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xaa, 0x01, 0x0010},
- {0xaa, 0x03, 0x0000},
- {0xaa, 0x04, 0x0001},
- {0xaa, 0x05, 0x0020},
- {0xaa, 0x06, 0x0001},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0001},
- {0xaa, 0x04, 0x0011},
- {0xaa, 0x05, 0x00a0},
- {0xaa, 0x06, 0x0001},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0002},
- {0xaa, 0x04, 0x0013},
- {0xaa, 0x05, 0x0020},
- {0xaa, 0x06, 0x0001},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0003},
- {0xaa, 0x04, 0x0015},
- {0xaa, 0x05, 0x0020},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0004},
- {0xaa, 0x04, 0x0017},
- {0xaa, 0x05, 0x0020},
- {0xaa, 0x06, 0x000d},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0005},
- {0xaa, 0x04, 0x0019},
- {0xaa, 0x05, 0x0020},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0006},
- {0xaa, 0x04, 0x0017},
- {0xaa, 0x05, 0x0026},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0007},
- {0xaa, 0x04, 0x0019},
- {0xaa, 0x05, 0x0022},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0008},
- {0xaa, 0x04, 0x0021},
- {0xaa, 0x05, 0x00aa},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0009},
- {0xaa, 0x04, 0x0023},
- {0xaa, 0x05, 0x00aa},
- {0xaa, 0x06, 0x000d},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x000a},
- {0xaa, 0x04, 0x0025},
- {0xaa, 0x05, 0x00aa},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x000b},
- {0xaa, 0x04, 0x00ec},
- {0xaa, 0x05, 0x002e},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x000c},
- {0xaa, 0x04, 0x00fa},
- {0xaa, 0x05, 0x002a},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x07, 0x000d},
- {0xaa, 0x01, 0x0005},
- {0xaa, 0x94, 0x0002},
- {0xaa, 0x90, 0x0000},
- {0xaa, 0x91, 0x001f},
- {0xaa, 0x10, 0x0064},
- {0xaa, 0x9b, 0x00f0},
- {0xaa, 0x9c, 0x0002},
- {0xaa, 0x14, 0x001a},
- {0xaa, 0x20, 0x0080},
- {0xaa, 0x22, 0x0080},
- {0xaa, 0x24, 0x0080},
- {0xaa, 0x26, 0x0080},
- {0xaa, 0x00, 0x0084},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xaa, 0xa8, 0x00c0},
- {0xa1, 0x01, 0x0002},
- {0xa1, 0x01, 0x0008},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x40, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x40, ZC3XX_R118_BGAIN},
- {0xa1, 0x01, 0x0008},
-
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa1, 0x01, 0x01c8},
- {0xa1, 0x01, 0x01c9},
- {0xa1, 0x01, 0x01ca},
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
- {0xa0, 0x52, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf7, ZC3XX_R10B_RGB01},
- {0xa0, 0xf7, ZC3XX_R10C_RGB02},
- {0xa0, 0xf7, ZC3XX_R10D_RGB10},
- {0xa0, 0x52, ZC3XX_R10E_RGB11},
- {0xa0, 0xf7, ZC3XX_R10F_RGB12},
- {0xa0, 0xf7, ZC3XX_R110_RGB20},
- {0xa0, 0xf7, ZC3XX_R111_RGB21},
- {0xa0, 0x52, ZC3XX_R112_RGB22},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x0d, 0x0003},
- {0xaa, 0x0c, 0x008c},
- {0xaa, 0x0e, 0x0095},
- {0xaa, 0x0f, 0x0002},
- {0xaa, 0x1c, 0x0094},
- {0xaa, 0x1d, 0x0002},
- {0xaa, 0x20, 0x0080},
- {0xaa, 0x22, 0x0080},
- {0xaa, 0x24, 0x0080},
- {0xaa, 0x26, 0x0080},
- {0xaa, 0x00, 0x0084},
- {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH},
- {0xa0, 0x94, ZC3XX_R0A4_EXPOSURETIMELOW},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x84, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xe3, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xec, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xf5, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0xc0, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x40, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x40, ZC3XX_R118_BGAIN},
- {}
-};
-
-static const struct usb_action icm105a_Initial[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x0c, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x00, ZC3XX_R097_WINYSTARTHIGH},
- {0xa0, 0x02, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R099_WINXSTARTHIGH},
- {0xa0, 0x02, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x02, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
- {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
- {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW},
- {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xaa, 0x01, 0x0010},
- {0xaa, 0x03, 0x0000},
- {0xaa, 0x04, 0x0001},
- {0xaa, 0x05, 0x0020},
- {0xaa, 0x06, 0x0001},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0001},
- {0xaa, 0x04, 0x0011},
- {0xaa, 0x05, 0x00a0},
- {0xaa, 0x06, 0x0001},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0002},
- {0xaa, 0x04, 0x0013},
- {0xaa, 0x05, 0x0020},
- {0xaa, 0x06, 0x0001},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0003},
- {0xaa, 0x04, 0x0015},
- {0xaa, 0x05, 0x0020},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0004},
- {0xaa, 0x04, 0x0017},
- {0xaa, 0x05, 0x0020},
- {0xaa, 0x06, 0x000d},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0005},
- {0xa0, 0x04, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x19, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa1, 0x01, 0x0091},
- {0xaa, 0x05, 0x0020},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0006},
- {0xaa, 0x04, 0x0017},
- {0xaa, 0x05, 0x0026},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0007},
- {0xaa, 0x04, 0x0019},
- {0xaa, 0x05, 0x0022},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0008},
- {0xaa, 0x04, 0x0021},
- {0xaa, 0x05, 0x00aa},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x0009},
- {0xaa, 0x04, 0x0023},
- {0xaa, 0x05, 0x00aa},
- {0xaa, 0x06, 0x000d},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x000a},
- {0xaa, 0x04, 0x0025},
- {0xaa, 0x05, 0x00aa},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x000b},
- {0xaa, 0x04, 0x00ec},
- {0xaa, 0x05, 0x002e},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x03, 0x000c},
- {0xaa, 0x04, 0x00fa},
- {0xaa, 0x05, 0x002a},
- {0xaa, 0x06, 0x0005},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x07, 0x000d},
- {0xaa, 0x01, 0x0005},
- {0xaa, 0x94, 0x0002},
- {0xaa, 0x90, 0x0000},
- {0xaa, 0x91, 0x0010},
- {0xaa, 0x10, 0x0064},
- {0xaa, 0x9b, 0x00f0},
- {0xaa, 0x9c, 0x0002},
- {0xaa, 0x14, 0x001a},
- {0xaa, 0x20, 0x0080},
- {0xaa, 0x22, 0x0080},
- {0xaa, 0x24, 0x0080},
- {0xaa, 0x26, 0x0080},
- {0xaa, 0x00, 0x0084},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xaa, 0xa8, 0x0080},
- {0xa0, 0x78, ZC3XX_R18D_YTARGET},
- {0xa1, 0x01, 0x0002},
- {0xa1, 0x01, 0x0008},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x40, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x40, ZC3XX_R118_BGAIN},
- {0xa1, 0x01, 0x0008},
-
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa1, 0x01, 0x01c8},
- {0xa1, 0x01, 0x01c9},
- {0xa1, 0x01, 0x01ca},
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
-
- {0xa0, 0x52, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf7, ZC3XX_R10B_RGB01},
- {0xa0, 0xf7, ZC3XX_R10C_RGB02},
- {0xa0, 0xf7, ZC3XX_R10D_RGB10},
- {0xa0, 0x52, ZC3XX_R10E_RGB11},
- {0xa0, 0xf7, ZC3XX_R10F_RGB12},
- {0xa0, 0xf7, ZC3XX_R110_RGB20},
- {0xa0, 0xf7, ZC3XX_R111_RGB21},
- {0xa0, 0x52, ZC3XX_R112_RGB22},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x0d, 0x0003},
- {0xaa, 0x0c, 0x0020},
- {0xaa, 0x0e, 0x000e},
- {0xaa, 0x0f, 0x0002},
- {0xaa, 0x1c, 0x000d},
- {0xaa, 0x1d, 0x0002},
- {0xaa, 0x20, 0x0080},
- {0xaa, 0x22, 0x0080},
- {0xaa, 0x24, 0x0080},
- {0xaa, 0x26, 0x0080},
- {0xaa, 0x00, 0x0084},
- {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH},
- {0xa0, 0x0d, ZC3XX_R0A4_EXPOSURETIMELOW},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x1a, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x4b, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xd8, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xea, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x40, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x40, ZC3XX_R118_BGAIN},
- {}
-};
-static const struct usb_action icm105a_50HZScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
- {0xaa, 0x0c, 0x0020}, /* 00,0c,20,aa */
- {0xaa, 0x0e, 0x000e}, /* 00,0e,0e,aa */
- {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */
- {0xaa, 0x1c, 0x000d}, /* 00,1c,0d,aa */
- {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
- {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */
- {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */
- {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */
- {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */
- {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */
- {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */
- {0xa0, 0x0d, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,0d,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
- {0xa0, 0x1a, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,1a,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x4b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,4b,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
- {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */
- {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */
- {0xa0, 0xd8, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d8,cc */
- {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {}
-};
-static const struct usb_action icm105a_50HZ[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
- {0xaa, 0x0c, 0x008c}, /* 00,0c,8c,aa */
- {0xaa, 0x0e, 0x0095}, /* 00,0e,95,aa */
- {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */
- {0xaa, 0x1c, 0x0094}, /* 00,1c,94,aa */
- {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
- {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */
- {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */
- {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */
- {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */
- {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */
- {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */
- {0xa0, 0x94, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,94,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
- {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x84, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,84,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
- {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */
- {0xa0, 0xe3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,e3,cc */
- {0xa0, 0xec, ZC3XX_R01E_HSYNC_1}, /* 00,1e,ec,cc */
- {0xa0, 0xf5, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f5,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */
- {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */
- {}
-};
-static const struct usb_action icm105a_60HZScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
- {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
- {0xaa, 0x0e, 0x000d}, /* 00,0e,0d,aa */
- {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */
- {0xaa, 0x1c, 0x0008}, /* 00,1c,08,aa */
- {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
- {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */
- {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */
- {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */
- {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */
- {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */
- {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */
- {0xa0, 0x08, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,08,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
- {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x41, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,41,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
- {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */
- {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */
- {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */
- {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {}
-};
-static const struct usb_action icm105a_60HZ[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
- {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */
- {0xaa, 0x0e, 0x0086}, /* 00,0e,86,aa */
- {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */
- {0xaa, 0x1c, 0x0085}, /* 00,1c,85,aa */
- {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
- {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */
- {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */
- {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */
- {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */
- {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */
- {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */
- {0xa0, 0x85, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,85,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
- {0xa0, 0x08, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,08,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,81,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
- {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */
- {0xa0, 0xc2, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c2,cc */
- {0xa0, 0xd6, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d6,cc */
- {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */
- {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */
- {}
-};
-static const struct usb_action icm105a_NoFlikerScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
- {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
- {0xaa, 0x0e, 0x000d}, /* 00,0e,0d,aa */
- {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */
- {0xaa, 0x1c, 0x0000}, /* 00,1c,00,aa */
- {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
- {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */
- {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */
- {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */
- {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */
- {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */
- {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */
- {0xa0, 0x00, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,00,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
- {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
- {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */
- {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */
- {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {}
-};
-static const struct usb_action icm105a_NoFliker[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
- {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
- {0xaa, 0x0e, 0x0081}, /* 00,0e,81,aa */
- {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */
- {0xaa, 0x1c, 0x0080}, /* 00,1c,80,aa */
- {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
- {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */
- {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */
- {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */
- {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */
- {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */
- {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */
- {0xa0, 0x80, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,80,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
- {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
- {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */
- {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */
- {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */
- {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */
- {}
-};
-
-static const struct usb_action mc501cb_Initial[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
- {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
- {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */
- {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */
- {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */
- {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
- {0xa0, 0x33, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,33,cc */
- {0xa0, 0x34, ZC3XX_R087_EXPTIMEMID}, /* 00,87,34,cc */
- {0xa0, 0x35, ZC3XX_R088_EXPTIMELOW}, /* 00,88,35,cc */
- {0xa0, 0xb0, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,b0,cc */
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
- {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */
- {0xaa, 0x01, 0x0003}, /* 00,01,03,aa */
- {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */
- {0xaa, 0x03, 0x0000}, /* 00,03,00,aa */
- {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
- {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */
- {0xaa, 0x12, 0x0000}, /* 00,12,00,aa */
- {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */
- {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */
- {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */
- {0xaa, 0x16, 0x0000}, /* 00,16,00,aa */
- {0xaa, 0x17, 0x0001}, /* 00,17,01,aa */
- {0xaa, 0x18, 0x00de}, /* 00,18,de,aa */
- {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */
- {0xaa, 0x1a, 0x0086}, /* 00,1a,86,aa */
- {0xaa, 0x20, 0x00a8}, /* 00,20,a8,aa */
- {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */
- {0xaa, 0x23, 0x0000}, /* 00,23,00,aa */
- {0xaa, 0x24, 0x0000}, /* 00,24,00,aa */
- {0xaa, 0x40, 0x0033}, /* 00,40,33,aa */
- {0xaa, 0x41, 0x0077}, /* 00,41,77,aa */
- {0xaa, 0x42, 0x0053}, /* 00,42,53,aa */
- {0xaa, 0x43, 0x00b0}, /* 00,43,b0,aa */
- {0xaa, 0x4b, 0x0001}, /* 00,4b,01,aa */
- {0xaa, 0x72, 0x0020}, /* 00,72,20,aa */
- {0xaa, 0x73, 0x0000}, /* 00,73,00,aa */
- {0xaa, 0x80, 0x0000}, /* 00,80,00,aa */
- {0xaa, 0x85, 0x0050}, /* 00,85,50,aa */
- {0xaa, 0x91, 0x0070}, /* 00,91,70,aa */
- {0xaa, 0x92, 0x0072}, /* 00,92,72,aa */
- {0xaa, 0x03, 0x0001}, /* 00,03,01,aa */
- {0xaa, 0x10, 0x00a0}, /* 00,10,a0,aa */
- {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */
- {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */
- {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */
- {0xaa, 0xa0, 0x001a}, /* 00,a0,1a,aa */
- {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */
- {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */
- {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */
- {0xaa, 0xa4, 0x0010}, /* 00,a4,10,aa */
- {0xaa, 0xa5, 0x0020}, /* 00,a5,20,aa */
- {0xaa, 0xb1, 0x0044}, /* 00,b1,44,aa */
- {0xaa, 0xd0, 0x0001}, /* 00,d0,01,aa */
- {0xaa, 0xd1, 0x0085}, /* 00,d1,85,aa */
- {0xaa, 0xd2, 0x0080}, /* 00,d2,80,aa */
- {0xaa, 0xd3, 0x0080}, /* 00,d3,80,aa */
- {0xaa, 0xd4, 0x0080}, /* 00,d4,80,aa */
- {0xaa, 0xd5, 0x0080}, /* 00,d5,80,aa */
- {0xaa, 0xc0, 0x00c3}, /* 00,c0,c3,aa */
- {0xaa, 0xc2, 0x0044}, /* 00,c2,44,aa */
- {0xaa, 0xc4, 0x0040}, /* 00,c4,40,aa */
- {0xaa, 0xc5, 0x0020}, /* 00,c5,20,aa */
- {0xaa, 0xc6, 0x0008}, /* 00,c6,08,aa */
- {0xaa, 0x03, 0x0004}, /* 00,03,04,aa */
- {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
- {0xaa, 0x40, 0x0030}, /* 00,40,30,aa */
- {0xaa, 0x41, 0x0020}, /* 00,41,20,aa */
- {0xaa, 0x42, 0x002d}, /* 00,42,2d,aa */
- {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
- {0xaa, 0x1c, 0x0050}, /* 00,1C,50,aa */
- {0xaa, 0x11, 0x0081}, /* 00,11,81,aa */
- {0xaa, 0x3b, 0x001d}, /* 00,3b,1D,aa */
- {0xaa, 0x3c, 0x004c}, /* 00,3c,4C,aa */
- {0xaa, 0x3d, 0x0018}, /* 00,3d,18,aa */
- {0xaa, 0x3e, 0x006a}, /* 00,3e,6A,aa */
- {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */
- {0xaa, 0x52, 0x00ff}, /* 00,52,FF,aa */
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
- {0xaa, 0x03, 0x0002}, /* 00,03,02,aa */
- {0xaa, 0x51, 0x0027}, /* 00,51,27,aa */
- {0xaa, 0x52, 0x0020}, /* 00,52,20,aa */
- {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
- {0xaa, 0x50, 0x0010}, /* 00,50,10,aa */
- {0xaa, 0x51, 0x0010}, /* 00,51,10,aa */
- {0xaa, 0x54, 0x0010}, /* 00,54,10,aa */
- {0xaa, 0x55, 0x0010}, /* 00,55,10,aa */
- {0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */
- {0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */
-
- {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
- {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
- {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */
- {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */
- {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */
- {}
-};
-
-static const struct usb_action mc501cb_InitialScale[] = { /* 320x240 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
- {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
- {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */
- {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */
- {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
- {0xa0, 0x33, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,33,cc */
- {0xa0, 0x34, ZC3XX_R087_EXPTIMEMID}, /* 00,87,34,cc */
- {0xa0, 0x35, ZC3XX_R088_EXPTIMELOW}, /* 00,88,35,cc */
- {0xa0, 0xb0, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,b0,cc */
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
- {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */
- {0xaa, 0x01, 0x0003}, /* 00,01,03,aa */
- {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */
- {0xaa, 0x03, 0x0000}, /* 00,03,00,aa */
- {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
- {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */
- {0xaa, 0x12, 0x0000}, /* 00,12,00,aa */
- {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */
- {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */
- {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */
- {0xaa, 0x16, 0x0000}, /* 00,16,00,aa */
- {0xaa, 0x17, 0x0001}, /* 00,17,01,aa */
- {0xaa, 0x18, 0x00d8}, /* 00,18,d8,aa */
- {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */
- {0xaa, 0x1a, 0x0088}, /* 00,1a,88,aa */
- {0xaa, 0x20, 0x00a8}, /* 00,20,a8,aa */
- {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */
- {0xaa, 0x23, 0x0000}, /* 00,23,00,aa */
- {0xaa, 0x24, 0x0000}, /* 00,24,00,aa */
- {0xaa, 0x40, 0x0033}, /* 00,40,33,aa */
- {0xaa, 0x41, 0x0077}, /* 00,41,77,aa */
- {0xaa, 0x42, 0x0053}, /* 00,42,53,aa */
- {0xaa, 0x43, 0x00b0}, /* 00,43,b0,aa */
- {0xaa, 0x4b, 0x0001}, /* 00,4b,01,aa */
- {0xaa, 0x72, 0x0020}, /* 00,72,20,aa */
- {0xaa, 0x73, 0x0000}, /* 00,73,00,aa */
- {0xaa, 0x80, 0x0000}, /* 00,80,00,aa */
- {0xaa, 0x85, 0x0050}, /* 00,85,50,aa */
- {0xaa, 0x91, 0x0070}, /* 00,91,70,aa */
- {0xaa, 0x92, 0x0072}, /* 00,92,72,aa */
- {0xaa, 0x03, 0x0001}, /* 00,03,01,aa */
- {0xaa, 0x10, 0x00a0}, /* 00,10,a0,aa */
- {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */
- {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */
- {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */
- {0xaa, 0xa0, 0x001a}, /* 00,a0,1a,aa */
- {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */
- {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */
- {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */
- {0xaa, 0xa4, 0x0010}, /* 00,a4,10,aa */
- {0xaa, 0xa5, 0x0020}, /* 00,a5,20,aa */
- {0xaa, 0xb1, 0x0044}, /* 00,b1,44,aa */
- {0xaa, 0xd0, 0x0001}, /* 00,d0,01,aa */
- {0xaa, 0xd1, 0x0085}, /* 00,d1,85,aa */
- {0xaa, 0xd2, 0x0080}, /* 00,d2,80,aa */
- {0xaa, 0xd3, 0x0080}, /* 00,d3,80,aa */
- {0xaa, 0xd4, 0x0080}, /* 00,d4,80,aa */
- {0xaa, 0xd5, 0x0080}, /* 00,d5,80,aa */
- {0xaa, 0xc0, 0x00c3}, /* 00,c0,c3,aa */
- {0xaa, 0xc2, 0x0044}, /* 00,c2,44,aa */
- {0xaa, 0xc4, 0x0040}, /* 00,c4,40,aa */
- {0xaa, 0xc5, 0x0020}, /* 00,c5,20,aa */
- {0xaa, 0xc6, 0x0008}, /* 00,c6,08,aa */
- {0xaa, 0x03, 0x0004}, /* 00,03,04,aa */
- {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
- {0xaa, 0x40, 0x0030}, /* 00,40,30,aa */
- {0xaa, 0x41, 0x0020}, /* 00,41,20,aa */
- {0xaa, 0x42, 0x002d}, /* 00,42,2d,aa */
- {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
- {0xaa, 0x1c, 0x0050}, /* 00,1c,50,aa */
- {0xaa, 0x11, 0x0081}, /* 00,11,81,aa */
- {0xaa, 0x3b, 0x003a}, /* 00,3b,3A,aa */
- {0xaa, 0x3c, 0x0098}, /* 00,3c,98,aa */
- {0xaa, 0x3d, 0x0030}, /* 00,3d,30,aa */
- {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */
- {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */
- {0xaa, 0x52, 0x00ff}, /* 00,52,FF,aa */
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
- {0xaa, 0x03, 0x0002}, /* 00,03,02,aa */
- {0xaa, 0x51, 0x004e}, /* 00,51,4E,aa */
- {0xaa, 0x52, 0x0041}, /* 00,52,41,aa */
- {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
- {0xaa, 0x50, 0x0010}, /* 00,50,10,aa */
- {0xaa, 0x51, 0x0010}, /* 00,51,10,aa */
- {0xaa, 0x54, 0x0010}, /* 00,54,10,aa */
- {0xaa, 0x55, 0x0010}, /* 00,55,10,aa */
- {0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */
- {0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */
- {}
-};
-
-static const struct usb_action mc501cb_50HZ[] = {
- {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
- {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
- {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */
- {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */
- {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */
- {0xaa, 0x3c, 0x004c}, /* 00,3C,4C,aa */
- {0xaa, 0x3d, 0x001d}, /* 00,3D,1D,aa */
- {0xaa, 0x3e, 0x004c}, /* 00,3E,4C,aa */
- {}
-};
-
-static const struct usb_action mc501cb_50HZScale[] = {
- {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
- {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
- {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */
- {0xaa, 0x37, 0x0098}, /* 00,37,98,aa */
- {0xaa, 0x3b, 0x003a}, /* 00,3B,3A,aa */
- {0xaa, 0x3c, 0x0098}, /* 00,3C,98,aa */
- {0xaa, 0x3d, 0x003a}, /* 00,3D,3A,aa */
- {0xaa, 0x3e, 0x0098}, /* 00,3E,98,aa */
- {}
-};
-
-static const struct usb_action mc501cb_60HZ[] = {
- {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
- {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
- {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
- {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */
- {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */
- {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */
- {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */
- {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */
- {}
-};
-
-static const struct usb_action mc501cb_60HZScale[] = {
- {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
- {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
- {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
- {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */
- {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */
- {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */
- {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */
- {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */
- {}
-};
-
-static const struct usb_action mc501cb_NoFliker[] = {
- {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
- {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
- {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
- {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */
- {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */
- {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */
- {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */
- {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */
- {}
-};
-
-static const struct usb_action mc501cb_NoFlikerScale[] = {
- {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
- {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
- {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
- {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */
- {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */
- {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */
- {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */
- {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */
- {}
-};
-
-/* from zs211.inf */
-static const struct usb_action ov7620_Initial[] = { /* 640x480 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
- {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, /* 00,02,40,cc */
- {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
- {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,06,cc */
- {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, /* 00,83,02,cc */
- {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, /* 00,85,01,cc */
- {0xa0, 0x80, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,80,cc */
- {0xa0, 0x81, ZC3XX_R087_EXPTIMEMID}, /* 00,87,81,cc */
- {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, /* 00,88,10,cc */
- {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,a1,cc */
- {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
- {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
- {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */
- {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
- {0xaa, 0x12, 0x0088}, /* 00,12,88,aa */
- {0xaa, 0x12, 0x0048}, /* 00,12,48,aa */
- {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */
- {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
- {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */
- {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */
- {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */
- {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */
- {0xaa, 0x17, 0x0018}, /* 00,17,18,aa */
- {0xaa, 0x18, 0x00ba}, /* 00,18,ba,aa */
- {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */
- {0xaa, 0x1a, 0x00f1}, /* 00,1a,f1,aa */
- {0xaa, 0x20, 0x0040}, /* 00,20,40,aa */
- {0xaa, 0x24, 0x0088}, /* 00,24,88,aa */
- {0xaa, 0x25, 0x0078}, /* 00,25,78,aa */
- {0xaa, 0x27, 0x00f6}, /* 00,27,f6,aa */
- {0xaa, 0x28, 0x00a0}, /* 00,28,a0,aa */
- {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */
- {0xaa, 0x2a, 0x0083}, /* 00,2a,83,aa */
- {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */
- {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */
- {0xaa, 0x74, 0x0020}, /* 00,74,20,aa */
- {0xaa, 0x61, 0x0068}, /* 00,61,68,aa */
- {0xaa, 0x64, 0x0088}, /* 00,64,88,aa */
- {0xaa, 0x00, 0x0000}, /* 00,00,00,aa */
- {0xaa, 0x06, 0x0080}, /* 00,06,80,aa */
- {0xaa, 0x01, 0x0090}, /* 00,01,90,aa */
- {0xaa, 0x02, 0x0030}, /* 00,02,30,aa */
- {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,77,cc */
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
- {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
- {0xa0, 0x68, ZC3XX_R116_RGAIN}, /* 01,16,68,cc */
- {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */
- {0xa0, 0x40, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,40,cc */
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
- {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */
- {}
-};
-static const struct usb_action ov7620_InitialScale[] = { /* 320x240 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
- {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, /* 00,02,50,cc */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */
- /* mx change? */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
- {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,06,cc */
- {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, /* 00,83,02,cc */
- {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, /* 00,85,01,cc */
- {0xa0, 0x80, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,80,cc */
- {0xa0, 0x81, ZC3XX_R087_EXPTIMEMID}, /* 00,87,81,cc */
- {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, /* 00,88,10,cc */
- {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,a1,cc */
- {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
- {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
- {0xa0, 0xd6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d6,cc */
- /* OV7648 00,9c,d8,cc */
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
- {0xaa, 0x12, 0x0088}, /* 00,12,88,aa */
- {0xaa, 0x12, 0x0048}, /* 00,12,48,aa */
- {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */
- {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
- {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */
- {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */
- {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */
- {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */
- {0xaa, 0x24, 0x0088}, /* 00,24,88,aa */
- {0xaa, 0x25, 0x0078}, /* 00,25,78,aa */
- {0xaa, 0x17, 0x0018}, /* 00,17,18,aa */
- {0xaa, 0x18, 0x00ba}, /* 00,18,ba,aa */
- {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */
- {0xaa, 0x1a, 0x00f2}, /* 00,1a,f2,aa */
- {0xaa, 0x20, 0x0040}, /* 00,20,40,aa */
- {0xaa, 0x27, 0x00f6}, /* 00,27,f6,aa */
- {0xaa, 0x28, 0x00a0}, /* 00,28,a0,aa */
- {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */
- {0xaa, 0x2a, 0x0083}, /* 00,2a,83,aa */
- {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */
- {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */
- {0xaa, 0x74, 0x0020}, /* 00,74,20,aa */
- {0xaa, 0x61, 0x0068}, /* 00,61,68,aa */
- {0xaa, 0x64, 0x0088}, /* 00,64,88,aa */
- {0xaa, 0x00, 0x0000}, /* 00,00,00,aa */
- {0xaa, 0x06, 0x0080}, /* 00,06,80,aa */
- {0xaa, 0x01, 0x0090}, /* 00,01,90,aa */
- {0xaa, 0x02, 0x0030}, /* 00,02,30,aa */
- {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,77,cc */
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
- {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
- {0xa0, 0x68, ZC3XX_R116_RGAIN}, /* 01,16,68,cc */
- {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */
- {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,50,cc */
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
- {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */
- {}
-};
-static const struct usb_action ov7620_50HZ[] = {
- {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
- {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
- {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */
- {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */
- {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
- {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */
- {0xaa, 0x10, 0x0082}, /* 00,10,82,aa */
- {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */
-/* {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, * 00,02,40,cc
- * if mode0 (640x480) */
- {}
-};
-static const struct usb_action ov7620_60HZ[] = {
- {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
- /* (bug in zs211.inf) */
- {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
- {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */
- {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */
- {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
- {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */
- {0xaa, 0x10, 0x0020}, /* 00,10,20,aa */
- {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */
-/* {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, * 00,02,40,cc
- * if mode0 (640x480) */
-/* ?? in gspca v1, it was
- {0xa0, 0x00, 0x0039}, * 00,00,00,dd *
- {0xa1, 0x01, 0x0037}, */
- {}
-};
-static const struct usb_action ov7620_NoFliker[] = {
- {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
- /* (bug in zs211.inf) */
- {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
- {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */
- {0xaa, 0x75, 0x008e}, /* 00,75,8e,aa */
- {0xaa, 0x2d, 0x0001}, /* 00,2d,01,aa */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
- {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,01,cc */
-/* {0xa0, 0x44, ZC3XX_R002_CLOCKSELECT}, * 00,02,44,cc
- * if mode1 (320x240) */
-/* ?? was
- {0xa0, 0x00, 0x0039}, * 00,00,00,dd *
- {0xa1, 0x01, 0x0037}, */
- {}
-};
-
-static const struct usb_action ov7630c_InitialScale[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xaa, 0x12, 0x0080},
- {0xa0, 0x02, ZC3XX_R083_RGAINADDR},
- {0xa0, 0x01, ZC3XX_R085_BGAINADDR},
- {0xa0, 0x90, ZC3XX_R086_EXPTIMEHIGH},
- {0xa0, 0x91, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
- {0xaa, 0x12, 0x0069},
- {0xaa, 0x04, 0x0020},
- {0xaa, 0x06, 0x0050},
- {0xaa, 0x13, 0x0083},
- {0xaa, 0x14, 0x0000},
- {0xaa, 0x15, 0x0024},
- {0xaa, 0x17, 0x0018},
- {0xaa, 0x18, 0x00ba},
- {0xaa, 0x19, 0x0002},
- {0xaa, 0x1a, 0x00f6},
- {0xaa, 0x1b, 0x0002},
- {0xaa, 0x20, 0x00c2},
- {0xaa, 0x24, 0x0060},
- {0xaa, 0x25, 0x0040},
- {0xaa, 0x26, 0x0030},
- {0xaa, 0x27, 0x00ea},
- {0xaa, 0x28, 0x00a0},
- {0xaa, 0x21, 0x0000},
- {0xaa, 0x2a, 0x0081},
- {0xaa, 0x2b, 0x0096},
- {0xaa, 0x2d, 0x0094},
- {0xaa, 0x2f, 0x003d},
- {0xaa, 0x30, 0x0024},
- {0xaa, 0x60, 0x0000},
- {0xaa, 0x61, 0x0040},
- {0xaa, 0x68, 0x007c},
- {0xaa, 0x6f, 0x0015},
- {0xaa, 0x75, 0x0088},
- {0xaa, 0x77, 0x00b5},
- {0xaa, 0x01, 0x0060},
- {0xaa, 0x02, 0x0060},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x60, ZC3XX_R116_RGAIN},
- {0xa0, 0x46, ZC3XX_R118_BGAIN},
- {0xa0, 0x04, ZC3XX_R113_RGB03},
-/* 0x10, */
- {0xa1, 0x01, 0x0002},
- {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf8, ZC3XX_R10B_RGB01},
- {0xa0, 0xf8, ZC3XX_R10C_RGB02},
- {0xa0, 0xf8, ZC3XX_R10D_RGB10},
- {0xa0, 0x50, ZC3XX_R10E_RGB11},
- {0xa0, 0xf8, ZC3XX_R10F_RGB12},
- {0xa0, 0xf8, ZC3XX_R110_RGB20},
- {0xa0, 0xf8, ZC3XX_R111_RGB21},
- {0xa0, 0x50, ZC3XX_R112_RGB22},
- {0xa1, 0x01, 0x0008},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa1, 0x01, 0x01c8},
- {0xa1, 0x01, 0x01c9},
- {0xa1, 0x01, 0x01ca},
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
- {0xa0, 0x01, ZC3XX_R120_GAMMA00}, /* gamma 2 ?*/
- {0xa0, 0x0c, ZC3XX_R121_GAMMA01},
- {0xa0, 0x1f, ZC3XX_R122_GAMMA02},
- {0xa0, 0x3a, ZC3XX_R123_GAMMA03},
- {0xa0, 0x53, ZC3XX_R124_GAMMA04},
- {0xa0, 0x6d, ZC3XX_R125_GAMMA05},
- {0xa0, 0x85, ZC3XX_R126_GAMMA06},
- {0xa0, 0x9c, ZC3XX_R127_GAMMA07},
- {0xa0, 0xb0, ZC3XX_R128_GAMMA08},
- {0xa0, 0xc2, ZC3XX_R129_GAMMA09},
- {0xa0, 0xd1, ZC3XX_R12A_GAMMA0A},
- {0xa0, 0xde, ZC3XX_R12B_GAMMA0B},
- {0xa0, 0xe9, ZC3XX_R12C_GAMMA0C},
- {0xa0, 0xf2, ZC3XX_R12D_GAMMA0D},
- {0xa0, 0xf9, ZC3XX_R12E_GAMMA0E},
- {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
- {0xa0, 0x05, ZC3XX_R130_GAMMA10},
- {0xa0, 0x0f, ZC3XX_R131_GAMMA11},
- {0xa0, 0x16, ZC3XX_R132_GAMMA12},
- {0xa0, 0x1a, ZC3XX_R133_GAMMA13},
- {0xa0, 0x19, ZC3XX_R134_GAMMA14},
- {0xa0, 0x19, ZC3XX_R135_GAMMA15},
- {0xa0, 0x17, ZC3XX_R136_GAMMA16},
- {0xa0, 0x15, ZC3XX_R137_GAMMA17},
- {0xa0, 0x12, ZC3XX_R138_GAMMA18},
- {0xa0, 0x10, ZC3XX_R139_GAMMA19},
- {0xa0, 0x0e, ZC3XX_R13A_GAMMA1A},
- {0xa0, 0x0b, ZC3XX_R13B_GAMMA1B},
- {0xa0, 0x09, ZC3XX_R13C_GAMMA1C},
- {0xa0, 0x08, ZC3XX_R13D_GAMMA1D},
- {0xa0, 0x06, ZC3XX_R13E_GAMMA1E},
- {0xa0, 0x03, ZC3XX_R13F_GAMMA1F},
- {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf8, ZC3XX_R10B_RGB01},
- {0xa0, 0xf8, ZC3XX_R10C_RGB02},
- {0xa0, 0xf8, ZC3XX_R10D_RGB10},
- {0xa0, 0x50, ZC3XX_R10E_RGB11},
- {0xa0, 0xf8, ZC3XX_R10F_RGB12},
- {0xa0, 0xf8, ZC3XX_R110_RGB20},
- {0xa0, 0xf8, ZC3XX_R111_RGB21},
- {0xa0, 0x50, ZC3XX_R112_RGB22},
-
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xaa, 0x10, 0x001b},
- {0xaa, 0x76, 0x0002},
- {0xaa, 0x2a, 0x0081},
- {0xaa, 0x2b, 0x0000},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xb8, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x37, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xaa, 0x13, 0x0083}, /* 40 */
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {}
-};
-
-static const struct usb_action ov7630c_Initial[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
-
- {0xaa, 0x12, 0x0080},
- {0xa0, 0x02, ZC3XX_R083_RGAINADDR},
- {0xa0, 0x01, ZC3XX_R085_BGAINADDR},
- {0xa0, 0x90, ZC3XX_R086_EXPTIMEHIGH},
- {0xa0, 0x91, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW},
- {0xaa, 0x12, 0x0069}, /* i2c */
- {0xaa, 0x04, 0x0020},
- {0xaa, 0x06, 0x0050},
- {0xaa, 0x13, 0x00c3},
- {0xaa, 0x14, 0x0000},
- {0xaa, 0x15, 0x0024},
- {0xaa, 0x19, 0x0003},
- {0xaa, 0x1a, 0x00f6},
- {0xaa, 0x1b, 0x0002},
- {0xaa, 0x20, 0x00c2},
- {0xaa, 0x24, 0x0060},
- {0xaa, 0x25, 0x0040},
- {0xaa, 0x26, 0x0030},
- {0xaa, 0x27, 0x00ea},
- {0xaa, 0x28, 0x00a0},
- {0xaa, 0x21, 0x0000},
- {0xaa, 0x2a, 0x0081},
- {0xaa, 0x2b, 0x0096},
- {0xaa, 0x2d, 0x0084},
- {0xaa, 0x2f, 0x003d},
- {0xaa, 0x30, 0x0024},
- {0xaa, 0x60, 0x0000},
- {0xaa, 0x61, 0x0040},
- {0xaa, 0x68, 0x007c},
- {0xaa, 0x6f, 0x0015},
- {0xaa, 0x75, 0x0088},
- {0xaa, 0x77, 0x00b5},
- {0xaa, 0x01, 0x0060},
- {0xaa, 0x02, 0x0060},
- {0xaa, 0x17, 0x0018},
- {0xaa, 0x18, 0x00ba},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x60, ZC3XX_R116_RGAIN},
- {0xa0, 0x46, ZC3XX_R118_BGAIN},
- {0xa0, 0x04, ZC3XX_R113_RGB03},
-
- {0xa1, 0x01, 0x0002},
- {0xa0, 0x4e, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xfe, ZC3XX_R10B_RGB01},
- {0xa0, 0xf4, ZC3XX_R10C_RGB02},
- {0xa0, 0xf7, ZC3XX_R10D_RGB10},
- {0xa0, 0x4d, ZC3XX_R10E_RGB11},
- {0xa0, 0xfc, ZC3XX_R10F_RGB12},
- {0xa0, 0x00, ZC3XX_R110_RGB20},
- {0xa0, 0xf6, ZC3XX_R111_RGB21},
- {0xa0, 0x4a, ZC3XX_R112_RGB22},
-
- {0xa1, 0x01, 0x0008},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa1, 0x01, 0x01c8},
- {0xa1, 0x01, 0x01c9},
- {0xa1, 0x01, 0x01ca},
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
- {0xa0, 0x16, ZC3XX_R120_GAMMA00}, /* gamma ~4 */
- {0xa0, 0x3a, ZC3XX_R121_GAMMA01},
- {0xa0, 0x5b, ZC3XX_R122_GAMMA02},
- {0xa0, 0x7c, ZC3XX_R123_GAMMA03},
- {0xa0, 0x94, ZC3XX_R124_GAMMA04},
- {0xa0, 0xa9, ZC3XX_R125_GAMMA05},
- {0xa0, 0xbb, ZC3XX_R126_GAMMA06},
- {0xa0, 0xca, ZC3XX_R127_GAMMA07},
- {0xa0, 0xd7, ZC3XX_R128_GAMMA08},
- {0xa0, 0xe1, ZC3XX_R129_GAMMA09},
- {0xa0, 0xea, ZC3XX_R12A_GAMMA0A},
- {0xa0, 0xf1, ZC3XX_R12B_GAMMA0B},
- {0xa0, 0xf7, ZC3XX_R12C_GAMMA0C},
- {0xa0, 0xfc, ZC3XX_R12D_GAMMA0D},
- {0xa0, 0xff, ZC3XX_R12E_GAMMA0E},
- {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
- {0xa0, 0x20, ZC3XX_R130_GAMMA10},
- {0xa0, 0x22, ZC3XX_R131_GAMMA11},
- {0xa0, 0x20, ZC3XX_R132_GAMMA12},
- {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
- {0xa0, 0x16, ZC3XX_R134_GAMMA14},
- {0xa0, 0x13, ZC3XX_R135_GAMMA15},
- {0xa0, 0x10, ZC3XX_R136_GAMMA16},
- {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
- {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
- {0xa0, 0x09, ZC3XX_R139_GAMMA19},
- {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
- {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
- {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
- {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
- {0xa0, 0x00, ZC3XX_R13E_GAMMA1E},
- {0xa0, 0x01, ZC3XX_R13F_GAMMA1F},
- {0xa0, 0x4e, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xfe, ZC3XX_R10B_RGB01},
- {0xa0, 0xf4, ZC3XX_R10C_RGB02},
- {0xa0, 0xf7, ZC3XX_R10D_RGB10},
- {0xa0, 0x4d, ZC3XX_R10E_RGB11},
- {0xa0, 0xfc, ZC3XX_R10F_RGB12},
- {0xa0, 0x00, ZC3XX_R110_RGB20},
- {0xa0, 0xf6, ZC3XX_R111_RGB21},
- {0xa0, 0x4a, ZC3XX_R112_RGB22},
-
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xaa, 0x10, 0x000d},
- {0xaa, 0x76, 0x0002},
- {0xaa, 0x2a, 0x0081},
- {0xaa, 0x2b, 0x0000},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xd8, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x1b, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xaa, 0x13, 0x00c3},
-
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {}
-};
-
-static const struct usb_action pas106b_Initial_com[] = {
-/* Sream and Sensor specific */
- {0xa1, 0x01, 0x0010}, /* CMOSSensorSelect */
-/* System */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* SystemControl */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* SystemControl */
-/* Picture size */
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* ClockSelect */
- {0xa0, 0x03, 0x003a},
- {0xa0, 0x0c, 0x003b},
- {0xa0, 0x04, 0x0038},
- {}
-};
-
-static const struct usb_action pas106b_InitialScale[] = { /* 176x144 */
-/* JPEG control */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
-/* Sream and Sensor specific */
- {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT},
-/* Picture size */
- {0xa0, 0x00, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0xb0, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x00, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0x90, ZC3XX_R006_FRAMEHEIGHTLOW},
-/* System */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
-/* Sream and Sensor specific */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
-/* Sensor Interface */
- {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
-/* Window inside sensor array */
- {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW},
-/* Init the sensor */
- {0xaa, 0x02, 0x0004},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x09, 0x0005},
- {0xaa, 0x0a, 0x0002},
- {0xaa, 0x0b, 0x0002},
- {0xaa, 0x0c, 0x0005},
- {0xaa, 0x0d, 0x0000},
- {0xaa, 0x0e, 0x0002},
- {0xaa, 0x14, 0x0081},
-/* Other registers */
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
-/* Frame retreiving */
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-/* Gains */
- {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN},
-/* Unknown */
- {0xa0, 0x00, 0x01ad},
-/* Sharpness */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
-/* Other registers */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
-/* Auto exposure and white balance */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-/*Dead pixels */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
-/* EEPROM */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
-/* JPEG control */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},
-/* Other registers */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
-/* Auto exposure and white balance */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-/*Dead pixels */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
-/* EEPROM */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
-/* JPEG control */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},
-
- {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf4, ZC3XX_R10B_RGB01},
- {0xa0, 0xf4, ZC3XX_R10C_RGB02},
- {0xa0, 0xf4, ZC3XX_R10D_RGB10},
- {0xa0, 0x58, ZC3XX_R10E_RGB11},
- {0xa0, 0xf4, ZC3XX_R10F_RGB12},
- {0xa0, 0xf4, ZC3XX_R110_RGB20},
- {0xa0, 0xf4, ZC3XX_R111_RGB21},
- {0xa0, 0x58, ZC3XX_R112_RGB22},
-/* Auto correction */
- {0xa0, 0x03, ZC3XX_R181_WINXSTART},
- {0xa0, 0x08, ZC3XX_R182_WINXWIDTH},
- {0xa0, 0x16, ZC3XX_R183_WINXCENTER},
- {0xa0, 0x03, ZC3XX_R184_WINYSTART},
- {0xa0, 0x05, ZC3XX_R185_WINYWIDTH},
- {0xa0, 0x14, ZC3XX_R186_WINYCENTER},
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-/* Auto exposure and white balance */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
-/* sensor on */
- {0xaa, 0x07, 0x00b1},
- {0xaa, 0x05, 0x0003},
- {0xaa, 0x04, 0x0001},
- {0xaa, 0x03, 0x003b},
-/* Gains */
- {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
-/* Auto correction */
- {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-/* Gains */
- {0xa0, 0x40, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x40, ZC3XX_R118_BGAIN},
- {}
-};
-
-static const struct usb_action pas106b_Initial[] = { /* 352x288 */
-/* JPEG control */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
-/* Sream and Sensor specific */
- {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT},
-/* Picture size */
- {0xa0, 0x01, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x60, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0x20, ZC3XX_R006_FRAMEHEIGHTLOW},
-/* System */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
-/* Sream and Sensor specific */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
-/* Sensor Interface */
- {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
-/* Window inside sensor array */
- {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW},
-/* Init the sensor */
- {0xaa, 0x02, 0x0004},
- {0xaa, 0x08, 0x0000},
- {0xaa, 0x09, 0x0005},
- {0xaa, 0x0a, 0x0002},
- {0xaa, 0x0b, 0x0002},
- {0xaa, 0x0c, 0x0005},
- {0xaa, 0x0d, 0x0000},
- {0xaa, 0x0e, 0x0002},
- {0xaa, 0x14, 0x0081},
-/* Other registers */
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
-/* Frame retreiving */
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-/* Gains */
- {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN},
-/* Unknown */
- {0xa0, 0x00, 0x01ad},
-/* Sharpness */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
-/* Other registers */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
-/* Auto exposure and white balance */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x80, ZC3XX_R18D_YTARGET},
-/*Dead pixels */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
-/* EEPROM */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
-/* JPEG control */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},
-/* Other registers */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
-/* Auto exposure and white balance */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-/*Dead pixels */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
-/* EEPROM */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
-/* JPEG control */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},
-
- {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf4, ZC3XX_R10B_RGB01},
- {0xa0, 0xf4, ZC3XX_R10C_RGB02},
- {0xa0, 0xf4, ZC3XX_R10D_RGB10},
- {0xa0, 0x58, ZC3XX_R10E_RGB11},
- {0xa0, 0xf4, ZC3XX_R10F_RGB12},
- {0xa0, 0xf4, ZC3XX_R110_RGB20},
- {0xa0, 0xf4, ZC3XX_R111_RGB21},
- {0xa0, 0x58, ZC3XX_R112_RGB22},
-/* Auto correction */
- {0xa0, 0x03, ZC3XX_R181_WINXSTART},
- {0xa0, 0x08, ZC3XX_R182_WINXWIDTH},
- {0xa0, 0x16, ZC3XX_R183_WINXCENTER},
- {0xa0, 0x03, ZC3XX_R184_WINYSTART},
- {0xa0, 0x05, ZC3XX_R185_WINYWIDTH},
- {0xa0, 0x14, ZC3XX_R186_WINYCENTER},
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-
-/* Auto exposure and white balance */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW},
-
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW},
-
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
-/* sensor on */
- {0xaa, 0x07, 0x00b1},
- {0xaa, 0x05, 0x0003},
- {0xaa, 0x04, 0x0001},
- {0xaa, 0x03, 0x003b},
-/* Gains */
- {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
-/* Auto correction */
- {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-/* Gains */
- {0xa0, 0x40, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x40, ZC3XX_R118_BGAIN},
-
- {0xa0, 0x00, 0x0007}, /* AutoCorrectEnable */
- {0xa0, 0xff, ZC3XX_R018_FRAMELOST}, /* Frame adjust */
- {}
-};
-static const struct usb_action pas106b_50HZ[] = {
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */
- {0xa0, 0x54, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,54,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,87,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x30, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,30,cc */
- {0xaa, 0x03, 0x0021}, /* 00,03,21,aa */
- {0xaa, 0x04, 0x000c}, /* 00,04,0c,aa */
- {0xaa, 0x05, 0x0002}, /* 00,05,02,aa */
- {0xaa, 0x07, 0x001c}, /* 00,07,1c,aa */
- {0xa0, 0x04, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,04,cc */
- {}
-};
-static const struct usb_action pas106b_60HZ[] = {
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */
- {0xa0, 0x2e, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,2e,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x71, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,71,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x30, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,30,cc */
- {0xaa, 0x03, 0x001c}, /* 00,03,1c,aa */
- {0xaa, 0x04, 0x0004}, /* 00,04,04,aa */
- {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */
- {0xaa, 0x07, 0x00c4}, /* 00,07,c4,aa */
- {0xa0, 0x04, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,04,cc */
- {}
-};
-static const struct usb_action pas106b_NoFliker[] = {
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */
- {0xa0, 0x50, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
- {0xaa, 0x03, 0x0013}, /* 00,03,13,aa */
- {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */
- {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */
- {0xaa, 0x07, 0x0030}, /* 00,07,30,aa */
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
- {}
-};
-
-/* from lvWIMv.inf 046d:08a2/:08aa 2007/06/03 */
-static const struct usb_action pas202b_Initial[] = { /* 640x480 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
- {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
- {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,03,cc */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
- {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,03,cc */
- {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */
- {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc */
- {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */
- {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
- {0xaa, 0x02, 0x0002}, /* 00,02,04,aa --> 02 */
- {0xaa, 0x07, 0x0006}, /* 00,07,06,aa */
- {0xaa, 0x08, 0x0002}, /* 00,08,02,aa */
- {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */
- {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */
- {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */
- {0xaa, 0x0c, 0x0006},
- {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */
- {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
- {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */
- {0xaa, 0x13, 0x0063}, /* 00,13,63,aa */
- {0xaa, 0x15, 0x0070}, /* 00,15,70,aa */
- {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
- {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
- {0xa0, 0x70, ZC3XX_R18D_YTARGET}, /* 01,8d,70,cc */
- {}
-};
-static const struct usb_action pas202b_InitialScale[] = { /* 320x240 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
- {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */
- {0xa0, 0x08, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,08,cc */
- {0xa0, 0x02, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,02,cc */
- {0xa0, 0x08, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,08,cc */
- {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,02,cc */
- {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
- {0xaa, 0x02, 0x0002}, /* 00,02,02,aa */
- {0xaa, 0x07, 0x0006}, /* 00,07,06,aa */
- {0xaa, 0x08, 0x0002}, /* 00,08,02,aa */
- {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */
- {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */
- {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */
- {0xaa, 0x0c, 0x0006},
- {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */
- {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
- {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */
- {0xaa, 0x13, 0x0063}, /* 00,13,63,aa */
- {0xaa, 0x15, 0x0070}, /* 00,15,70,aa */
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
- {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
- {0xa0, 0x70, ZC3XX_R18D_YTARGET}, /* 01,8d,70,cc */
- {0xa0, 0xff, ZC3XX_R097_WINYSTARTHIGH},
- {0xa0, 0xfe, ZC3XX_R098_WINYSTARTLOW},
- {}
-};
-static const struct usb_action pas202b_50HZ[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
- {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
- {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
- {0xaa, 0x21, 0x001b},
- {0xaa, 0x03, 0x0044}, /* 00,03,44,aa */
- {0xaa, 0x04, 0x0008},
- {0xaa, 0x05, 0x001b},
- {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
- {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
- {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x4d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,4d,cc */
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x44, ZC3XX_R01D_HSYNC_0}, /* 00,1d,44,cc */
- {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
- {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */
- {0xa0, 0xeb, ZC3XX_R020_HSYNC_3}, /* 00,20,eb,cc */
- {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
- {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
- {}
-};
-static const struct usb_action pas202b_50HZScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
- {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
- {0xaa, 0x20, 0x0004},
- {0xaa, 0x21, 0x003d},
- {0xaa, 0x03, 0x0041}, /* 00,03,41,aa */
- {0xaa, 0x04, 0x0010},
- {0xaa, 0x05, 0x003d},
- {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
- {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
- {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x9b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,9b,cc */
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */
- {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
- {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
- {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
- {}
-};
-static const struct usb_action pas202b_60HZ[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
- {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
- {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
- {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */
- {0xaa, 0x03, 0x0045}, /* 00,03,45,aa */
- {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */
- {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */
- {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
- {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
- {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x40, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,40,cc */
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x45, ZC3XX_R01D_HSYNC_0}, /* 00,1d,45,cc */
- {0xa0, 0x8e, ZC3XX_R01E_HSYNC_1}, /* 00,1e,8e,cc */
- {0xa0, 0xc1, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c1,cc */
- {0xa0, 0xf5, ZC3XX_R020_HSYNC_3}, /* 00,20,f5,cc */
- {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
- {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
- {}
-};
-static const struct usb_action pas202b_60HZScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
- {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
- {0xaa, 0x20, 0x0004},
- {0xaa, 0x21, 0x0008},
- {0xaa, 0x03, 0x0042}, /* 00,03,42,aa */
- {0xaa, 0x04, 0x0010},
- {0xaa, 0x05, 0x0008},
- {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
- {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
- {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x08, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,81,cc */
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x42, ZC3XX_R01D_HSYNC_0}, /* 00,1d,42,cc */
- {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
- {0xa0, 0xaf, ZC3XX_R01F_HSYNC_2}, /* 00,1f,af,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
- {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
- {}
-};
-static const struct usb_action pas202b_NoFliker[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
- {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
- {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
- {0xaa, 0x21, 0x0006},
- {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */
- {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */
- {0xaa, 0x05, 0x0006},
- {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
- {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x06, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */
- {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */
- {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
- {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
- {}
-};
-static const struct usb_action pas202b_NoFlikerScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
- {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
- {0xaa, 0x20, 0x0004},
- {0xaa, 0x21, 0x000c},
- {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */
- {0xaa, 0x04, 0x0010},
- {0xaa, 0x05, 0x000c},
- {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
- {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x0c, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x02, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,02,cc */
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */
- {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */
- {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */
- {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
- {}
-};
-
-/* mt9v111 (mi0360soc) and pb0330 from vm30x.inf 0ac8:301b 07/02/13 */
-static const struct usb_action mt9v111_1_Initial[] = { /* 640x480 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
- {0xdd, 0x00, 0x0200},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xaa, 0x01, 0x0001},
- {0xaa, 0x06, 0x0000},
- {0xaa, 0x08, 0x0483},
- {0xaa, 0x01, 0x0004},
- {0xaa, 0x08, 0x0006},
- {0xaa, 0x02, 0x0011},
- {0xaa, 0x03, 0x01e5}, /*jfm: was 01e7*/
- {0xaa, 0x04, 0x0285}, /*jfm: was 0287*/
- {0xaa, 0x07, 0x3002},
- {0xaa, 0x20, 0x5100},
- {0xaa, 0x35, 0x507f},
- {0xaa, 0x30, 0x0005},
- {0xaa, 0x31, 0x0000},
- {0xaa, 0x58, 0x0078},
- {0xaa, 0x62, 0x0411},
- {0xaa, 0x2b, 0x007f},
- {0xaa, 0x2c, 0x007f}, /*jfm: was 0030*/
- {0xaa, 0x2d, 0x007f}, /*jfm: was 0030*/
- {0xaa, 0x2e, 0x007f}, /*jfm: was 0030*/
- {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x09, 0x01ad}, /*jfm: was 00*/
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0x6c, ZC3XX_R18D_YTARGET},
- {0xa0, 0x61, ZC3XX_R116_RGAIN},
- {0xa0, 0x65, ZC3XX_R118_BGAIN},
- {}
-};
-static const struct usb_action mt9v111_1_InitialScale[] = { /* 320x240 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
- {0xdd, 0x00, 0x0200},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xaa, 0x01, 0x0001},
- {0xaa, 0x06, 0x0000},
- {0xaa, 0x08, 0x0483},
- {0xaa, 0x01, 0x0004},
- {0xaa, 0x08, 0x0006},
- {0xaa, 0x02, 0x0011},
- {0xaa, 0x03, 0x01e7},
- {0xaa, 0x04, 0x0287},
- {0xaa, 0x07, 0x3002},
- {0xaa, 0x20, 0x5100},
- {0xaa, 0x35, 0x007f}, /*jfm: was 0050*/
- {0xaa, 0x30, 0x0005},
- {0xaa, 0x31, 0x0000},
- {0xaa, 0x58, 0x0078},
- {0xaa, 0x62, 0x0411},
- {0xaa, 0x2b, 0x007f}, /*jfm: was 28*/
- {0xaa, 0x2c, 0x007f}, /*jfm: was 30*/
- {0xaa, 0x2d, 0x007f}, /*jfm: was 30*/
- {0xaa, 0x2e, 0x007f}, /*jfm: was 28*/
- {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x09, 0x01ad}, /*jfm: was 00*/
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0x6c, ZC3XX_R18D_YTARGET},
- {0xa0, 0x61, ZC3XX_R116_RGAIN},
- {0xa0, 0x65, ZC3XX_R118_BGAIN},
- {}
-};
-static const struct usb_action mt9v111_1_AE50HZ[] = {
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xbb, 0x00, 0x0562},
- {0xbb, 0x01, 0x09aa},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x9b, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x62, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {}
-};
-static const struct usb_action mt9v111_1_AE50HZScale[] = {
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xbb, 0x00, 0x0509},
- {0xbb, 0x01, 0x0934},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x9a, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {}
-};
-static const struct usb_action mt9v111_1_AE60HZ[] = {
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x05, 0x003d},
- {0xaa, 0x09, 0x016e},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x62, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {}
-};
-static const struct usb_action mt9v111_1_AE60HZScale[] = {
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xbb, 0x00, 0x0509},
- {0xbb, 0x01, 0x0983},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x8f, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {}
-};
-static const struct usb_action mt9v111_1_AENoFliker[] = {
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xbb, 0x00, 0x0509},
- {0xbb, 0x01, 0x0960},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x09, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {}
-};
-static const struct usb_action mt9v111_1_AENoFlikerScale[] = {
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xbb, 0x00, 0x0534},
- {0xbb, 0x02, 0x0960},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x34, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x60, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {}
-};
-/* from usbvm303.inf 0ac8:303b 07/03/25 (3 - tas5130c) */
-static const struct usb_action mt9v111_3_Initial[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
- {0xdd, 0x00, 0x0200},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xaa, 0x01, 0x0001}, /* select IFP/SOC registers */
- {0xaa, 0x06, 0x0000}, /* operating mode control */
- {0xaa, 0x08, 0x0483}, /* output format control */
- /* H red first, V red or blue first,
- * raw Bayer, auto flicker */
- {0xaa, 0x01, 0x0004}, /* select sensor core registers */
- {0xaa, 0x08, 0x0006}, /* row start */
- {0xaa, 0x02, 0x0011}, /* column start */
- {0xaa, 0x03, 0x01e5}, /* window height - 1 */
- {0xaa, 0x04, 0x0285}, /* window width - 1 */
- {0xaa, 0x07, 0x3002}, /* output control */
- {0xaa, 0x20, 0x1100}, /* read mode: bits 8 & 12 (?) */
- {0xaa, 0x35, 0x007f}, /* global gain */
- {0xaa, 0x30, 0x0005},
- {0xaa, 0x31, 0x0000},
- {0xaa, 0x58, 0x0078},
- {0xaa, 0x62, 0x0411},
- {0xaa, 0x2b, 0x007f}, /* green1 gain */
- {0xaa, 0x2c, 0x007f}, /* blue gain */
- {0xaa, 0x2d, 0x007f}, /* red gain */
- {0xaa, 0x2e, 0x007f}, /* green2 gain */
- {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0x80, ZC3XX_R18D_YTARGET},
- {0xa0, 0x61, ZC3XX_R116_RGAIN},
- {0xa0, 0x65, ZC3XX_R118_BGAIN},
- {}
-};
-static const struct usb_action mt9v111_3_InitialScale[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
- {0xdd, 0x00, 0x0200},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xaa, 0x01, 0x0001},
- {0xaa, 0x06, 0x0000},
- {0xaa, 0x08, 0x0483},
- {0xaa, 0x01, 0x0004},
- {0xaa, 0x08, 0x0006},
- {0xaa, 0x02, 0x0011},
- {0xaa, 0x03, 0x01e7},
- {0xaa, 0x04, 0x0287},
- {0xaa, 0x07, 0x3002},
- {0xaa, 0x20, 0x1100},
- {0xaa, 0x35, 0x007f},
- {0xaa, 0x30, 0x0005},
- {0xaa, 0x31, 0x0000},
- {0xaa, 0x58, 0x0078},
- {0xaa, 0x62, 0x0411},
- {0xaa, 0x2b, 0x007f},
- {0xaa, 0x2c, 0x007f},
- {0xaa, 0x2d, 0x007f},
- {0xaa, 0x2e, 0x007f},
- {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0x80, ZC3XX_R18D_YTARGET},
- {0xa0, 0x61, ZC3XX_R116_RGAIN},
- {0xa0, 0x65, ZC3XX_R118_BGAIN},
- {}
-};
-static const struct usb_action mt9v111_3_AE50HZ[] = {
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x05, 0x0009}, /* horizontal blanking */
- {0xaa, 0x09, 0x01ce}, /* shutter width */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x9a, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {}
-};
-static const struct usb_action mt9v111_3_AE50HZScale[] = {
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x05, 0x0009},
- {0xaa, 0x09, 0x01ce},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x9a, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {}
-};
-static const struct usb_action mt9v111_3_AE60HZ[] = {
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x05, 0x0009},
- {0xaa, 0x09, 0x0083},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x8f, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {}
-};
-static const struct usb_action mt9v111_3_AE60HZScale[] = {
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x05, 0x0009},
- {0xaa, 0x09, 0x0083},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x8f, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {}
-};
-static const struct usb_action mt9v111_3_AENoFliker[] = {
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x05, 0x0034},
- {0xaa, 0x09, 0x0260},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x34, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x60, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {}
-};
-static const struct usb_action mt9v111_3_AENoFlikerScale[] = {
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x05, 0x0034},
- {0xaa, 0x09, 0x0260},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x34, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x60, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {}
-};
-
-static const struct usb_action pb0330_Initial[] = { /* 640x480 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xdd, 0x00, 0x0200},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xaa, 0x01, 0x0006},
- {0xaa, 0x02, 0x0011},
- {0xaa, 0x03, 0x01e5}, /*jfm: was 1e7*/
- {0xaa, 0x04, 0x0285}, /*jfm: was 0287*/
- {0xaa, 0x06, 0x0003},
- {0xaa, 0x07, 0x3002},
- {0xaa, 0x20, 0x1100},
- {0xaa, 0x2f, 0xf7b0},
- {0xaa, 0x30, 0x0005},
- {0xaa, 0x31, 0x0000},
- {0xaa, 0x34, 0x0100},
- {0xaa, 0x35, 0x0060},
- {0xaa, 0x3d, 0x068f},
- {0xaa, 0x40, 0x01e0},
- {0xaa, 0x58, 0x0078},
- {0xaa, 0x62, 0x0411},
- {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x09, 0x01ad}, /*jfm: was 00 */
- {0xa0, 0x15, 0x01ae},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /*jfm: was 6c*/
- {}
-};
-static const struct usb_action pb0330_InitialScale[] = { /* 320x240 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
- {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xdd, 0x00, 0x0200},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xaa, 0x01, 0x0006},
- {0xaa, 0x02, 0x0011},
- {0xaa, 0x03, 0x01e7},
- {0xaa, 0x04, 0x0287},
- {0xaa, 0x06, 0x0003},
- {0xaa, 0x07, 0x3002},
- {0xaa, 0x20, 0x1100},
- {0xaa, 0x2f, 0xf7b0},
- {0xaa, 0x30, 0x0005},
- {0xaa, 0x31, 0x0000},
- {0xaa, 0x34, 0x0100},
- {0xaa, 0x35, 0x0060},
- {0xaa, 0x3d, 0x068f},
- {0xaa, 0x40, 0x01e0},
- {0xaa, 0x58, 0x0078},
- {0xaa, 0x62, 0x0411},
- {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x09, 0x01ad},
- {0xa0, 0x15, 0x01ae},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /*jfm: was 6c*/
- {}
-};
-static const struct usb_action pb0330_50HZ[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xbb, 0x00, 0x055c},
- {0xbb, 0x01, 0x09aa},
- {0xbb, 0x00, 0x1001},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xc4, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x5c, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action pb0330_50HZScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xbb, 0x00, 0x0566},
- {0xbb, 0x02, 0x09b2},
- {0xbb, 0x00, 0x1002},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action pb0330_60HZ[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xbb, 0x00, 0x0535},
- {0xbb, 0x01, 0x0974},
- {0xbb, 0x00, 0x1001},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xfe, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x50, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xd0, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action pb0330_60HZScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xbb, 0x00, 0x0535},
- {0xbb, 0x02, 0x096c},
- {0xbb, 0x00, 0x1002},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xc0, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x7c, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x50, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xd0, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action pb0330_NoFliker[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xbb, 0x00, 0x0509},
- {0xbb, 0x02, 0x0940},
- {0xbb, 0x00, 0x1002},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x09, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
- {}
-};
-static const struct usb_action pb0330_NoFlikerScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xbb, 0x00, 0x0535},
- {0xbb, 0x01, 0x0980},
- {0xbb, 0x00, 0x1001},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x60, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
- {}
-};
-
-/* from oem9.inf */
-static const struct usb_action po2030_Initial[] = { /* 640x480 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
- {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
- {0xa0, 0x04, ZC3XX_R080_HBLANKHIGH}, /* 00,80,04,cc */
- {0xa0, 0x05, ZC3XX_R081_HBLANKLOW}, /* 00,81,05,cc */
- {0xa0, 0x16, ZC3XX_R083_RGAINADDR}, /* 00,83,16,cc */
- {0xa0, 0x18, ZC3XX_R085_BGAINADDR}, /* 00,85,18,cc */
- {0xa0, 0x1a, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,1a,cc */
- {0xa0, 0x1b, ZC3XX_R087_EXPTIMEMID}, /* 00,87,1b,cc */
- {0xa0, 0x1c, ZC3XX_R088_EXPTIMELOW}, /* 00,88,1c,cc */
- {0xa0, 0xee, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,ee,cc */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */
- {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
- {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc */
- {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
- {0xaa, 0x09, 0x00ce}, /* 00,09,ce,aa */
- {0xaa, 0x0b, 0x0005}, /* 00,0b,05,aa */
- {0xaa, 0x0d, 0x0054}, /* 00,0d,54,aa */
- {0xaa, 0x0f, 0x00eb}, /* 00,0f,eb,aa */
- {0xaa, 0x87, 0x0000}, /* 00,87,00,aa */
- {0xaa, 0x88, 0x0004}, /* 00,88,04,aa */
- {0xaa, 0x89, 0x0000}, /* 00,89,00,aa */
- {0xaa, 0x8a, 0x0005}, /* 00,8a,05,aa */
- {0xaa, 0x13, 0x0003}, /* 00,13,03,aa */
- {0xaa, 0x16, 0x0040}, /* 00,16,40,aa */
- {0xaa, 0x18, 0x0040}, /* 00,18,40,aa */
- {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
- {0xaa, 0x29, 0x00e8}, /* 00,29,e8,aa */
- {0xaa, 0x45, 0x0045}, /* 00,45,45,aa */
- {0xaa, 0x50, 0x00ed}, /* 00,50,ed,aa */
- {0xaa, 0x51, 0x0025}, /* 00,51,25,aa */
- {0xaa, 0x52, 0x0042}, /* 00,52,42,aa */
- {0xaa, 0x53, 0x002f}, /* 00,53,2f,aa */
- {0xaa, 0x79, 0x0025}, /* 00,79,25,aa */
- {0xaa, 0x7b, 0x0000}, /* 00,7b,00,aa */
- {0xaa, 0x7e, 0x0025}, /* 00,7e,25,aa */
- {0xaa, 0x7f, 0x0025}, /* 00,7f,25,aa */
- {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */
- {0xaa, 0x33, 0x0036}, /* 00,33,36,aa */
- {0xaa, 0x36, 0x0060}, /* 00,36,60,aa */
- {0xaa, 0x37, 0x0008}, /* 00,37,08,aa */
- {0xaa, 0x3b, 0x0031}, /* 00,3b,31,aa */
- {0xaa, 0x44, 0x000f}, /* 00,44,0f,aa */
- {0xaa, 0x58, 0x0002}, /* 00,58,02,aa */
- {0xaa, 0x66, 0x00c0}, /* 00,66,c0,aa */
- {0xaa, 0x67, 0x0044}, /* 00,67,44,aa */
- {0xaa, 0x6b, 0x00a0}, /* 00,6b,a0,aa */
- {0xaa, 0x6c, 0x0054}, /* 00,6c,54,aa */
- {0xaa, 0xd6, 0x0007}, /* 00,d6,07,aa */
- {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,f7,cc */
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
- {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
- {0xa0, 0x7a, ZC3XX_R116_RGAIN}, /* 01,16,7a,cc */
- {0xa0, 0x4a, ZC3XX_R118_BGAIN}, /* 01,18,4a,cc */
- {}
-};
-
-/* from oem9.inf */
-static const struct usb_action po2030_InitialScale[] = { /* 320x240 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
- {0xa0, 0x04, ZC3XX_R080_HBLANKHIGH}, /* 00,80,04,cc */
- {0xa0, 0x05, ZC3XX_R081_HBLANKLOW}, /* 00,81,05,cc */
- {0xa0, 0x16, ZC3XX_R083_RGAINADDR}, /* 00,83,16,cc */
- {0xa0, 0x18, ZC3XX_R085_BGAINADDR}, /* 00,85,18,cc */
- {0xa0, 0x1a, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,1a,cc */
- {0xa0, 0x1b, ZC3XX_R087_EXPTIMEMID}, /* 00,87,1b,cc */
- {0xa0, 0x1c, ZC3XX_R088_EXPTIMELOW}, /* 00,88,1c,cc */
- {0xa0, 0xee, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,ee,cc */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */
- {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc */
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
- {0xaa, 0x09, 0x00cc}, /* 00,09,cc,aa */
- {0xaa, 0x0b, 0x0005}, /* 00,0b,05,aa */
- {0xaa, 0x0d, 0x0058}, /* 00,0d,58,aa */
- {0xaa, 0x0f, 0x00ed}, /* 00,0f,ed,aa */
- {0xaa, 0x87, 0x0000}, /* 00,87,00,aa */
- {0xaa, 0x88, 0x0004}, /* 00,88,04,aa */
- {0xaa, 0x89, 0x0000}, /* 00,89,00,aa */
- {0xaa, 0x8a, 0x0005}, /* 00,8a,05,aa */
- {0xaa, 0x13, 0x0003}, /* 00,13,03,aa */
- {0xaa, 0x16, 0x0040}, /* 00,16,40,aa */
- {0xaa, 0x18, 0x0040}, /* 00,18,40,aa */
- {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
- {0xaa, 0x29, 0x00e8}, /* 00,29,e8,aa */
- {0xaa, 0x45, 0x0045}, /* 00,45,45,aa */
- {0xaa, 0x50, 0x00ed}, /* 00,50,ed,aa */
- {0xaa, 0x51, 0x0025}, /* 00,51,25,aa */
- {0xaa, 0x52, 0x0042}, /* 00,52,42,aa */
- {0xaa, 0x53, 0x002f}, /* 00,53,2f,aa */
- {0xaa, 0x79, 0x0025}, /* 00,79,25,aa */
- {0xaa, 0x7b, 0x0000}, /* 00,7b,00,aa */
- {0xaa, 0x7e, 0x0025}, /* 00,7e,25,aa */
- {0xaa, 0x7f, 0x0025}, /* 00,7f,25,aa */
- {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */
- {0xaa, 0x33, 0x0036}, /* 00,33,36,aa */
- {0xaa, 0x36, 0x0060}, /* 00,36,60,aa */
- {0xaa, 0x37, 0x0008}, /* 00,37,08,aa */
- {0xaa, 0x3b, 0x0031}, /* 00,3b,31,aa */
- {0xaa, 0x44, 0x000f}, /* 00,44,0f,aa */
- {0xaa, 0x58, 0x0002}, /* 00,58,02,aa */
- {0xaa, 0x66, 0x00c0}, /* 00,66,c0,aa */
- {0xaa, 0x67, 0x0044}, /* 00,67,44,aa */
- {0xaa, 0x6b, 0x00a0}, /* 00,6b,a0,aa */
- {0xaa, 0x6c, 0x0054}, /* 00,6c,54,aa */
- {0xaa, 0xd6, 0x0007}, /* 00,d6,07,aa */
- {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,f7,cc */
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
- {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
- {0xa0, 0x7a, ZC3XX_R116_RGAIN}, /* 01,16,7a,cc */
- {0xa0, 0x4a, ZC3XX_R118_BGAIN}, /* 01,18,4a,cc */
- {}
-};
-
-static const struct usb_action po2030_50HZ[] = {
- {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */
- {0xaa, 0x1a, 0x0001}, /* 00,1a,01,aa */
- {0xaa, 0x1b, 0x000a}, /* 00,1b,0a,aa */
- {0xaa, 0x1c, 0x00b0}, /* 00,1c,b0,aa */
- {0xa0, 0x05, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,05,cc */
- {0xa0, 0x35, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,35,cc */
- {0xa0, 0x70, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,70,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x85, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,85,cc */
- {0xa0, 0x58, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,58,cc */
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */
- {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
- {0xa0, 0x22, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,22,cc */
- {0xa0, 0x88, ZC3XX_R18D_YTARGET}, /* 01,8d,88,cc */
- {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc */
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */
- {}
-};
-
-static const struct usb_action po2030_60HZ[] = {
- {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */
- {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
- {0xaa, 0x1b, 0x00de}, /* 00,1b,de,aa */
- {0xaa, 0x1c, 0x0040}, /* 00,1c,40,aa */
- {0xa0, 0x08, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,08,cc */
- {0xa0, 0xae, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,ae,cc */
- {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,80,cc */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x6f, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,6f,cc */
- {0xa0, 0x20, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,20,cc */
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */
- {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
- {0xa0, 0x22, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,22,cc */
- {0xa0, 0x88, ZC3XX_R18D_YTARGET}, /* 01,8d,88,cc */
- /* win: 01,8d,80 */
- {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc */
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */
- {}
-};
-
-static const struct usb_action po2030_NoFliker[] = {
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
- {0xaa, 0x8d, 0x000d}, /* 00,8d,0d,aa */
- {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
- {0xaa, 0x1b, 0x0002}, /* 00,1b,02,aa */
- {0xaa, 0x1c, 0x0078}, /* 00,1c,78,aa */
- {0xaa, 0x46, 0x0000}, /* 00,46,00,aa */
- {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */
- {}
-};
-
-static const struct usb_action tas5130c_InitialScale[] = { /* 320x240 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
-
- {0xa0, 0x04, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x0f, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x04, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x0f, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
- {0xa0, 0x06, ZC3XX_R08D_COMPABILITYMODE},
- {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x70, ZC3XX_R18D_YTARGET},
- {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN},
- {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL},
- {}
-};
-static const struct usb_action tas5130c_Initial[] = { /* 640x480 */
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x05, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x0f, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x05, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x0f, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
- {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW},
- {0xa0, 0x06, ZC3XX_R08D_COMPABILITYMODE},
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x70, ZC3XX_R18D_YTARGET},
- {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN},
- {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL},
- {}
-};
-static const struct usb_action tas5130c_50HZ[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
- {0xaa, 0xa4, 0x0063}, /* 00,a4,63,aa */
- {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
- {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,63,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xfe, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc */
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,d3,cc */
- {0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, /* 00,1e,da,cc */
- {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
- {0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW},
- {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
- {}
-};
-static const struct usb_action tas5130c_50HZScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
- {0xaa, 0xa4, 0x0077}, /* 00,a4,77,aa */
- {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
- {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xd0, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, /* 00,1d,f0,cc */
- {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f4,cc */
- {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
- {0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW},
- {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
- {}
-};
-static const struct usb_action tas5130c_60HZ[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
- {0xaa, 0xa4, 0x0036}, /* 00,a4,36,aa */
- {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
- {0xa0, 0x36, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,36,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x54, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3e,cc */
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xca, ZC3XX_R01D_HSYNC_0}, /* 00,1d,ca,cc */
- {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
- {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
- {0xa0, 0x28, ZC3XX_R0A0_MAXXLOW},
- {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
- {}
-};
-static const struct usb_action tas5130c_60HZScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
- {0xaa, 0xa4, 0x0077}, /* 00,a4,77,aa */
- {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
- {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x09, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x47, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
- {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */
- {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
- {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
- {0xa0, 0x20, ZC3XX_R0A0_MAXXLOW},
- {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
- {}
-};
-static const struct usb_action tas5130c_NoFliker[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
- {0xaa, 0xa4, 0x0040}, /* 00,a4,40,aa */
- {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
- {0xa0, 0x40, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,40,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
- {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */
- {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
- {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */
- {0xa0, 0xf0, ZC3XX_R0A0_MAXXLOW},
- {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
- {}
-};
-
-static const struct usb_action tas5130c_NoFlikerScale[] = {
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
- {0xaa, 0xa4, 0x0090}, /* 00,a4,90,aa */
- {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
- {0xa0, 0x90, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,90,cc */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
- {0xa0, 0x0a, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
- {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
- {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */
- {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
- {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
- {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */
- {0xa0, 0xf0, ZC3XX_R0A0_MAXXLOW},
- {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
- {}
-};
-
-/* from usbvm305.inf 0ac8:305b 07/06/15 (3 - tas5130c) */
-static const struct usb_action gc0303_Initial[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */
- {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc, */
- {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc, */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc, */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc, */
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc, */
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc, */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc, */
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc, */
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc,
- * 6<->8 */
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc,
- * 6<->8 */
- {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */
- {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */
- {0xaa, 0x01, 0x0000},
- {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */
- {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */
- {0xaa, 0x1b, 0x0000},
- {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */
- {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */
- {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */
- {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */
- {0xaa, 0x0a, 0x0002},
- {0xaa, 0x0b, 0x0000},
- {0xaa, 0x0c, 0x0002},
- {0xaa, 0x0d, 0x0000},
- {0xaa, 0x0e, 0x0002},
- {0xaa, 0x0f, 0x0000},
- {0xaa, 0x10, 0x0002},
- {0xaa, 0x11, 0x0000},
- {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */
- {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa, (e6 -> e8) */
- {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */
- {0xaa, 0x19, 0x0088}, /* 00,19,86,aa, */
- {0xaa, 0x20, 0x0020}, /* 00,20,20,aa, */
- {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc, */
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc, */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc, */
- {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc, */
- {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc, */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc, */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */
- {0xa0, 0x58, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */
- {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */
- {0xaa, 0x1b, 0x0000},
- {}
-};
-
-static const struct usb_action gc0303_InitialScale[] = {
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */
- {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */
- {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */
- {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc, */
- {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc, */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc, */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc, */
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc, */
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc, */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc, */
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc, */
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc,
- * 8<->6 */
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc,
- * 8<->6 */
- {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */
- {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */
- {0xaa, 0x01, 0x0000},
- {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */
- {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */
- {0xaa, 0x1b, 0x0000},
- {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */
- {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */
- {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */
- {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */
- {0xaa, 0x0a, 0x0001},
- {0xaa, 0x0b, 0x0000},
- {0xaa, 0x0c, 0x0001},
- {0xaa, 0x0d, 0x0000},
- {0xaa, 0x0e, 0x0001},
- {0xaa, 0x0f, 0x0000},
- {0xaa, 0x10, 0x0001},
- {0xaa, 0x11, 0x0000},
- {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */
- {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa (e6 -> e8) */
- {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */
- {0xaa, 0x19, 0x0088}, /* 00,19,88,aa, */
- {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc, */
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc, */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc, */
- {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc, */
- {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc, */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc, */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */
- {0xa0, 0x58, ZC3XX_R1A8_DIGITALGAIN},
- {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */
- {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */
- {0xaa, 0x1b, 0x0000},
- {}
-};
-static const struct usb_action gc0303_50HZ[] = {
- {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
- {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */
- {0xaa, 0x84, 0x0063},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */
- {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0d,cc, */
- {0xa0, 0xa8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc, */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */
- {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc, */
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */
- {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */
- {0xa0, 0x48, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */
- {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */
- {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */
- {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */
- {0xa0, 0x7f, ZC3XX_R18D_YTARGET},
- {}
-};
-
-static const struct usb_action gc0303_50HZScale[] = {
- {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
- {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */
- {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */
- {0xa0, 0x0d, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0d,cc, */
- {0xa0, 0x50, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc, */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */
- {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,8e,cc, */
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */
- {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */
- {0xa0, 0x48, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */
- {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */
- {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */
- {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */
- {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */
- {0xa0, 0x7f, ZC3XX_R18D_YTARGET},
- {}
-};
-
-static const struct usb_action gc0303_60HZ[] = {
- {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
- {0xaa, 0x83, 0x0000},
- {0xaa, 0x84, 0x003b},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */
- {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,05,cc, */
- {0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,88,cc, */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */
- {0xa0, 0x3b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3b,cc, */
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */
- {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */
- {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */
- {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */
- {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */
- {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */
- {0xa0, 0x80, ZC3XX_R18D_YTARGET},
- {}
-};
-
-static const struct usb_action gc0303_60HZScale[] = {
- {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
- {0xaa, 0x83, 0x0000},
- {0xaa, 0x84, 0x0076},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */
- {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,1,0b,cc, */
- {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,2,10,cc, */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,5,00,cc, */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,6,00,cc, */
- {0xa0, 0x76, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,7,76,cc, */
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,c,0e,cc, */
- {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,f,15,cc, */
- {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,9,10,cc, */
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,a,24,cc, */
- {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,d,62,cc, */
- {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,e,90,cc, */
- {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,f,c8,cc, */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,0,ff,cc, */
- {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,d,58,cc, */
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */
- {0xa0, 0x80, ZC3XX_R18D_YTARGET},
- {}
-};
-
-static const struct usb_action gc0303_NoFliker[] = {
- {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */
- {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
- {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
- {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,0,00,cc, */
- {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */
- {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */
- {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */
- {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */
- {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */
- {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */
- {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */
- {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */
- {}
-};
-
-static const struct usb_action gc0303_NoFlikerScale[] = {
- {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */
- {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
- {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
- {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */
- {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */
- {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */
- {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */
- {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */
- {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */
- {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */
- {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */
- {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */
- {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */
- {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */
- {}
-};
-
-static u8 reg_r(struct gspca_dev *gspca_dev,
- u16 index)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return 0;
- ret = usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- 0xa1,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x01, /* value */
- index, gspca_dev->usb_buf, 1,
- 500);
- if (ret < 0) {
- pr_err("reg_r err %d\n", ret);
- gspca_dev->usb_err = ret;
- return 0;
- }
- return gspca_dev->usb_buf[0];
-}
-
-static void reg_w(struct gspca_dev *gspca_dev,
- u8 value,
- u16 index)
-{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- 0xa0,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, NULL, 0,
- 500);
- if (ret < 0) {
- pr_err("reg_w_i err %d\n", ret);
- gspca_dev->usb_err = ret;
- }
-}
-
-static u16 i2c_read(struct gspca_dev *gspca_dev,
- u8 reg)
-{
- u8 retbyte;
- u16 retval;
-
- if (gspca_dev->usb_err < 0)
- return 0;
- reg_w(gspca_dev, reg, 0x0092);
- reg_w(gspca_dev, 0x02, 0x0090); /* <- read command */
- msleep(20);
- retbyte = reg_r(gspca_dev, 0x0091); /* read status */
- if (retbyte != 0x00)
- pr_err("i2c_r status error %02x\n", retbyte);
- retval = reg_r(gspca_dev, 0x0095); /* read Lowbyte */
- retval |= reg_r(gspca_dev, 0x0096) << 8; /* read Hightbyte */
- return retval;
-}
-
-static u8 i2c_write(struct gspca_dev *gspca_dev,
- u8 reg,
- u8 valL,
- u8 valH)
-{
- u8 retbyte;
-
- if (gspca_dev->usb_err < 0)
- return 0;
- reg_w(gspca_dev, reg, 0x92);
- reg_w(gspca_dev, valL, 0x93);
- reg_w(gspca_dev, valH, 0x94);
- reg_w(gspca_dev, 0x01, 0x90); /* <- write command */
- msleep(1);
- retbyte = reg_r(gspca_dev, 0x0091); /* read status */
- if (retbyte != 0x00)
- pr_err("i2c_w status error %02x\n", retbyte);
- return retbyte;
-}
-
-static void usb_exchange(struct gspca_dev *gspca_dev,
- const struct usb_action *action)
-{
- while (action->req) {
- switch (action->req) {
- case 0xa0: /* write register */
- reg_w(gspca_dev, action->val, action->idx);
- break;
- case 0xa1: /* read status */
- reg_r(gspca_dev, action->idx);
- break;
- case 0xaa:
- i2c_write(gspca_dev,
- action->val, /* reg */
- action->idx & 0xff, /* valL */
- action->idx >> 8); /* valH */
- break;
- case 0xbb:
- i2c_write(gspca_dev,
- action->idx >> 8, /* reg */
- action->idx & 0xff, /* valL */
- action->val); /* valH */
- break;
- default:
-/* case 0xdd: * delay */
- msleep(action->idx);
- break;
- }
- action++;
- msleep(1);
- }
-}
-
-static void setmatrix(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- const u8 *matrix;
- static const u8 adcm2700_matrix[9] =
-/* {0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; */
-/*ms-win*/
- {0x74, 0xed, 0xed, 0xed, 0x74, 0xed, 0xed, 0xed, 0x74};
- static const u8 gc0305_matrix[9] =
- {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50};
- static const u8 ov7620_matrix[9] =
- {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58};
- static const u8 pas202b_matrix[9] =
- {0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f};
- static const u8 po2030_matrix[9] =
- {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60};
- static const u8 tas5130c_matrix[9] =
- {0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68};
- static const u8 gc0303_matrix[9] =
- {0x6c, 0xea, 0xea, 0xea, 0x6c, 0xea, 0xea, 0xea, 0x6c};
- static const u8 *matrix_tb[SENSOR_MAX] = {
- [SENSOR_ADCM2700] = adcm2700_matrix,
- [SENSOR_CS2102] = ov7620_matrix,
- [SENSOR_CS2102K] = NULL,
- [SENSOR_GC0303] = gc0303_matrix,
- [SENSOR_GC0305] = gc0305_matrix,
- [SENSOR_HDCS2020] = NULL,
- [SENSOR_HV7131B] = NULL,
- [SENSOR_HV7131R] = po2030_matrix,
- [SENSOR_ICM105A] = po2030_matrix,
- [SENSOR_MC501CB] = NULL,
- [SENSOR_MT9V111_1] = gc0305_matrix,
- [SENSOR_MT9V111_3] = gc0305_matrix,
- [SENSOR_OV7620] = ov7620_matrix,
- [SENSOR_OV7630C] = NULL,
- [SENSOR_PAS106] = NULL,
- [SENSOR_PAS202B] = pas202b_matrix,
- [SENSOR_PB0330] = gc0305_matrix,
- [SENSOR_PO2030] = po2030_matrix,
- [SENSOR_TAS5130C] = tas5130c_matrix,
- };
-
- matrix = matrix_tb[sd->sensor];
- if (matrix == NULL)
- return; /* matrix already loaded */
- for (i = 0; i < ARRAY_SIZE(ov7620_matrix); i++)
- reg_w(gspca_dev, matrix[i], 0x010a + i);
-}
-
-static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
-{
- static const u8 sharpness_tb[][2] = {
- {0x02, 0x03},
- {0x04, 0x07},
- {0x08, 0x0f},
- {0x10, 0x1e}
- };
-
- reg_w(gspca_dev, sharpness_tb[val][0], 0x01c6);
- reg_r(gspca_dev, 0x01c8);
- reg_r(gspca_dev, 0x01c9);
- reg_r(gspca_dev, 0x01ca);
- reg_w(gspca_dev, sharpness_tb[val][1], 0x01cb);
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev,
- s32 gamma, s32 brightness, s32 contrast)
-{
- const u8 *Tgamma;
- int g, i, adj, gp1, gp2;
- u8 gr[16];
- static const u8 delta_b[16] = /* delta for brightness */
- {0x50, 0x38, 0x2d, 0x28, 0x24, 0x21, 0x1e, 0x1d,
- 0x1d, 0x1b, 0x1b, 0x1b, 0x19, 0x18, 0x18, 0x18};
- static const u8 delta_c[16] = /* delta for contrast */
- {0x2c, 0x1a, 0x12, 0x0c, 0x0a, 0x06, 0x06, 0x06,
- 0x04, 0x06, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02};
- static const u8 gamma_tb[6][16] = {
- {0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f,
- 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff},
- {0x01, 0x0c, 0x1f, 0x3a, 0x53, 0x6d, 0x85, 0x9c,
- 0xb0, 0xc2, 0xd1, 0xde, 0xe9, 0xf2, 0xf9, 0xff},
- {0x04, 0x16, 0x30, 0x4e, 0x68, 0x81, 0x98, 0xac,
- 0xbe, 0xcd, 0xda, 0xe4, 0xed, 0xf5, 0xfb, 0xff},
- {0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
- 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff},
- {0x20, 0x4b, 0x6e, 0x8d, 0xa3, 0xb5, 0xc5, 0xd2,
- 0xdc, 0xe5, 0xec, 0xf2, 0xf6, 0xfa, 0xfd, 0xff},
- {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3,
- 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff},
- };
-
- Tgamma = gamma_tb[gamma - 1];
-
- contrast -= 128; /* -128 / 127 */
- brightness -= 128; /* -128 / 92 */
- adj = 0;
- gp1 = gp2 = 0;
- for (i = 0; i < 16; i++) {
- g = Tgamma[i] + delta_b[i] * brightness / 256
- - delta_c[i] * contrast / 256 - adj / 2;
- if (g > 0xff)
- g = 0xff;
- else if (g < 0)
- g = 0;
- reg_w(gspca_dev, g, 0x0120 + i); /* gamma */
- if (contrast > 0)
- adj--;
- else if (contrast < 0)
- adj++;
- if (i > 1)
- gr[i - 1] = (g - gp2) / 2;
- else if (i != 0)
- gr[0] = gp1 == 0 ? 0 : (g - gp1);
- gp2 = gp1;
- gp1 = g;
- }
- gr[15] = (0xff - gp2) / 2;
- for (i = 0; i < 16; i++)
- reg_w(gspca_dev, gr[i], 0x0130 + i); /* gradient */
-}
-
-static s32 getexposure(struct gspca_dev *gspca_dev)
-{
- return (i2c_read(gspca_dev, 0x25) << 9)
- | (i2c_read(gspca_dev, 0x26) << 1)
- | (i2c_read(gspca_dev, 0x27) >> 7);
-}
-
-static void setexposure(struct gspca_dev *gspca_dev, s32 val)
-{
- i2c_write(gspca_dev, 0x25, val >> 9, 0x00);
- i2c_write(gspca_dev, 0x26, val >> 1, 0x00);
- i2c_write(gspca_dev, 0x27, val << 7, 0x00);
-}
-
-static void setquality(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- jpeg_set_qual(sd->jpeg_hdr, jpeg_qual[sd->reg08 >> 1]);
- reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING);
-}
-
-/* Matches the sensor's internal frame rate to the lighting frequency.
- * Valid frequencies are:
- * 50Hz, for European and Asian lighting (default)
- * 60Hz, for American lighting
- * 0 = No Fliker (for outdoore usage)
- */
-static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i, mode;
- const struct usb_action *zc3_freq;
- static const struct usb_action *freq_tb[SENSOR_MAX][6] = {
- [SENSOR_ADCM2700] =
- {adcm2700_NoFliker, adcm2700_NoFliker,
- adcm2700_50HZ, adcm2700_50HZ,
- adcm2700_60HZ, adcm2700_60HZ},
- [SENSOR_CS2102] =
- {cs2102_NoFliker, cs2102_NoFlikerScale,
- cs2102_50HZ, cs2102_50HZScale,
- cs2102_60HZ, cs2102_60HZScale},
- [SENSOR_CS2102K] =
- {cs2102_NoFliker, cs2102_NoFlikerScale,
- NULL, NULL, /* currently disabled */
- NULL, NULL},
- [SENSOR_GC0303] =
- {gc0303_NoFliker, gc0303_NoFlikerScale,
- gc0303_50HZ, gc0303_50HZScale,
- gc0303_60HZ, gc0303_60HZScale},
- [SENSOR_GC0305] =
- {gc0305_NoFliker, gc0305_NoFliker,
- gc0305_50HZ, gc0305_50HZ,
- gc0305_60HZ, gc0305_60HZ},
- [SENSOR_HDCS2020] =
- {hdcs2020_NoFliker, hdcs2020_NoFliker,
- hdcs2020_50HZ, hdcs2020_50HZ,
- hdcs2020_60HZ, hdcs2020_60HZ},
- [SENSOR_HV7131B] =
- {hv7131b_NoFliker, hv7131b_NoFlikerScale,
- hv7131b_50HZ, hv7131b_50HZScale,
- hv7131b_60HZ, hv7131b_60HZScale},
- [SENSOR_HV7131R] =
- {hv7131r_NoFliker, hv7131r_NoFlikerScale,
- hv7131r_50HZ, hv7131r_50HZScale,
- hv7131r_60HZ, hv7131r_60HZScale},
- [SENSOR_ICM105A] =
- {icm105a_NoFliker, icm105a_NoFlikerScale,
- icm105a_50HZ, icm105a_50HZScale,
- icm105a_60HZ, icm105a_60HZScale},
- [SENSOR_MC501CB] =
- {mc501cb_NoFliker, mc501cb_NoFlikerScale,
- mc501cb_50HZ, mc501cb_50HZScale,
- mc501cb_60HZ, mc501cb_60HZScale},
- [SENSOR_MT9V111_1] =
- {mt9v111_1_AENoFliker, mt9v111_1_AENoFlikerScale,
- mt9v111_1_AE50HZ, mt9v111_1_AE50HZScale,
- mt9v111_1_AE60HZ, mt9v111_1_AE60HZScale},
- [SENSOR_MT9V111_3] =
- {mt9v111_3_AENoFliker, mt9v111_3_AENoFlikerScale,
- mt9v111_3_AE50HZ, mt9v111_3_AE50HZScale,
- mt9v111_3_AE60HZ, mt9v111_3_AE60HZScale},
- [SENSOR_OV7620] =
- {ov7620_NoFliker, ov7620_NoFliker,
- ov7620_50HZ, ov7620_50HZ,
- ov7620_60HZ, ov7620_60HZ},
- [SENSOR_OV7630C] =
- {NULL, NULL,
- NULL, NULL,
- NULL, NULL},
- [SENSOR_PAS106] =
- {pas106b_NoFliker, pas106b_NoFliker,
- pas106b_50HZ, pas106b_50HZ,
- pas106b_60HZ, pas106b_60HZ},
- [SENSOR_PAS202B] =
- {pas202b_NoFliker, pas202b_NoFlikerScale,
- pas202b_50HZ, pas202b_50HZScale,
- pas202b_60HZ, pas202b_60HZScale},
- [SENSOR_PB0330] =
- {pb0330_NoFliker, pb0330_NoFlikerScale,
- pb0330_50HZ, pb0330_50HZScale,
- pb0330_60HZ, pb0330_60HZScale},
- [SENSOR_PO2030] =
- {po2030_NoFliker, po2030_NoFliker,
- po2030_50HZ, po2030_50HZ,
- po2030_60HZ, po2030_60HZ},
- [SENSOR_TAS5130C] =
- {tas5130c_NoFliker, tas5130c_NoFlikerScale,
- tas5130c_50HZ, tas5130c_50HZScale,
- tas5130c_60HZ, tas5130c_60HZScale},
- };
-
- i = val * 2;
- mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
- if (mode)
- i++; /* 320x240 */
- zc3_freq = freq_tb[sd->sensor][i];
- if (zc3_freq == NULL)
- return;
- usb_exchange(gspca_dev, zc3_freq);
- switch (sd->sensor) {
- case SENSOR_GC0305:
- if (mode /* if 320x240 */
- && val == 1) /* and 50Hz */
- reg_w(gspca_dev, 0x85, 0x018d);
- /* win: 0x80, 0x018d */
- break;
- case SENSOR_OV7620:
- if (!mode) { /* if 640x480 */
- if (val != 0) /* and filter */
- reg_w(gspca_dev, 0x40, 0x0002);
- else
- reg_w(gspca_dev, 0x44, 0x0002);
- }
- break;
- case SENSOR_PAS202B:
- reg_w(gspca_dev, 0x00, 0x01a7);
- break;
- }
-}
-
-static void setautogain(struct gspca_dev *gspca_dev, s32 val)
-{
- reg_w(gspca_dev, val ? 0x42 : 0x02, 0x0180);
-}
-
-/*
- * Update the transfer parameters.
- * This function is executed from a work queue.
- */
-static void transfer_update(struct work_struct *work)
-{
- struct sd *sd = container_of(work, struct sd, work);
- struct gspca_dev *gspca_dev = &sd->gspca_dev;
- int change, good;
- u8 reg07, reg11;
-
- /* reg07 gets set to 0 by sd_start before starting us */
- reg07 = 0;
-
- good = 0;
- for (;;) {
- msleep(100);
-
- mutex_lock(&gspca_dev->usb_lock);
-#ifdef CONFIG_PM
- if (gspca_dev->frozen)
- goto err;
-#endif
- if (!gspca_dev->dev || !gspca_dev->streaming)
- goto err;
-
- /* Bit 0 of register 11 indicates FIFO overflow */
- gspca_dev->usb_err = 0;
- reg11 = reg_r(gspca_dev, 0x0011);
- if (gspca_dev->usb_err)
- goto err;
-
- change = reg11 & 0x01;
- if (change) { /* overflow */
- good = 0;
-
- if (reg07 == 0) /* Bit Rate Control not enabled? */
- reg07 = 0x32; /* Allow 98 bytes / unit */
- else if (reg07 > 2)
- reg07 -= 2; /* Decrease allowed bytes / unit */
- else
- change = 0;
- } else { /* no overflow */
- good++;
- if (good >= 10) {
- good = 0;
- if (reg07) { /* BRC enabled? */
- change = 1;
- if (reg07 < 0x32)
- reg07 += 2;
- else
- reg07 = 0;
- }
- }
- }
- if (change) {
- gspca_dev->usb_err = 0;
- reg_w(gspca_dev, reg07, 0x0007);
- if (gspca_dev->usb_err)
- goto err;
- }
- mutex_unlock(&gspca_dev->usb_lock);
- }
- return;
-err:
- mutex_unlock(&gspca_dev->usb_lock);
-}
-
-static void send_unknown(struct gspca_dev *gspca_dev, int sensor)
-{
- reg_w(gspca_dev, 0x01, 0x0000); /* bridge reset */
- switch (sensor) {
- case SENSOR_PAS106:
- reg_w(gspca_dev, 0x03, 0x003a);
- reg_w(gspca_dev, 0x0c, 0x003b);
- reg_w(gspca_dev, 0x08, 0x0038);
- break;
- case SENSOR_ADCM2700:
- case SENSOR_GC0305:
- case SENSOR_OV7620:
- case SENSOR_MT9V111_1:
- case SENSOR_MT9V111_3:
- case SENSOR_PB0330:
- case SENSOR_PO2030:
- reg_w(gspca_dev, 0x0d, 0x003a);
- reg_w(gspca_dev, 0x02, 0x003b);
- reg_w(gspca_dev, 0x00, 0x0038);
- break;
- case SENSOR_HV7131R:
- case SENSOR_PAS202B:
- reg_w(gspca_dev, 0x03, 0x003b);
- reg_w(gspca_dev, 0x0c, 0x003a);
- reg_w(gspca_dev, 0x0b, 0x0039);
- if (sensor == SENSOR_PAS202B)
- reg_w(gspca_dev, 0x0b, 0x0038);
- break;
- }
-}
-
-/* start probe 2 wires */
-static void start_2wr_probe(struct gspca_dev *gspca_dev, int sensor)
-{
- reg_w(gspca_dev, 0x01, 0x0000);
- reg_w(gspca_dev, sensor, 0x0010);
- reg_w(gspca_dev, 0x01, 0x0001);
- reg_w(gspca_dev, 0x03, 0x0012);
- reg_w(gspca_dev, 0x01, 0x0012);
-/* msleep(2); */
-}
-
-static int sif_probe(struct gspca_dev *gspca_dev)
-{
- u16 checkword;
-
- start_2wr_probe(gspca_dev, 0x0f); /* PAS106 */
- reg_w(gspca_dev, 0x08, 0x008d);
- msleep(150);
- checkword = ((i2c_read(gspca_dev, 0x00) & 0x0f) << 4)
- | ((i2c_read(gspca_dev, 0x01) & 0xf0) >> 4);
- PDEBUG(D_PROBE, "probe sif 0x%04x", checkword);
- if (checkword == 0x0007) {
- send_unknown(gspca_dev, SENSOR_PAS106);
- return 0x0f; /* PAS106 */
- }
- return -1;
-}
-
-static int vga_2wr_probe(struct gspca_dev *gspca_dev)
-{
- u16 retword;
-
- start_2wr_probe(gspca_dev, 0x00); /* HV7131B */
- i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retword = i2c_read(gspca_dev, 0x01);
- if (retword != 0)
- return 0x00; /* HV7131B */
-
- start_2wr_probe(gspca_dev, 0x04); /* CS2102 */
- i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retword = i2c_read(gspca_dev, 0x01);
- if (retword != 0)
- return 0x04; /* CS2102 */
-
- start_2wr_probe(gspca_dev, 0x06); /* OmniVision */
- reg_w(gspca_dev, 0x08, 0x008d);
- i2c_write(gspca_dev, 0x11, 0xaa, 0x00);
- retword = i2c_read(gspca_dev, 0x11);
- if (retword != 0) {
- /* (should have returned 0xaa) --> Omnivision? */
- /* reg_r 0x10 -> 0x06 --> */
- goto ov_check;
- }
-
- start_2wr_probe(gspca_dev, 0x08); /* HDCS2020 */
- i2c_write(gspca_dev, 0x1c, 0x00, 0x00);
- i2c_write(gspca_dev, 0x15, 0xaa, 0x00);
- retword = i2c_read(gspca_dev, 0x15);
- if (retword != 0)
- return 0x08; /* HDCS2020 */
-
- start_2wr_probe(gspca_dev, 0x0a); /* PB0330 */
- i2c_write(gspca_dev, 0x07, 0xaa, 0xaa);
- retword = i2c_read(gspca_dev, 0x07);
- if (retword != 0)
- return 0x0a; /* PB0330 */
- retword = i2c_read(gspca_dev, 0x03);
- if (retword != 0)
- return 0x0a; /* PB0330 ?? */
- retword = i2c_read(gspca_dev, 0x04);
- if (retword != 0)
- return 0x0a; /* PB0330 ?? */
-
- start_2wr_probe(gspca_dev, 0x0c); /* ICM105A */
- i2c_write(gspca_dev, 0x01, 0x11, 0x00);
- retword = i2c_read(gspca_dev, 0x01);
- if (retword != 0)
- return 0x0c; /* ICM105A */
-
- start_2wr_probe(gspca_dev, 0x0e); /* PAS202BCB */
- reg_w(gspca_dev, 0x08, 0x008d);
- i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
- msleep(50);
- retword = i2c_read(gspca_dev, 0x03);
- if (retword != 0) {
- send_unknown(gspca_dev, SENSOR_PAS202B);
- return 0x0e; /* PAS202BCB */
- }
-
- start_2wr_probe(gspca_dev, 0x02); /* TAS5130C */
- i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retword = i2c_read(gspca_dev, 0x01);
- if (retword != 0)
- return 0x02; /* TAS5130C */
-ov_check:
- reg_r(gspca_dev, 0x0010); /* ?? */
- reg_r(gspca_dev, 0x0010);
-
- reg_w(gspca_dev, 0x01, 0x0000);
- reg_w(gspca_dev, 0x01, 0x0001);
- reg_w(gspca_dev, 0x06, 0x0010); /* OmniVision */
- reg_w(gspca_dev, 0xa1, 0x008b);
- reg_w(gspca_dev, 0x08, 0x008d);
- msleep(500);
- reg_w(gspca_dev, 0x01, 0x0012);
- i2c_write(gspca_dev, 0x12, 0x80, 0x00); /* sensor reset */
- retword = i2c_read(gspca_dev, 0x0a) << 8;
- retword |= i2c_read(gspca_dev, 0x0b);
- PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", retword);
- switch (retword) {
- case 0x7631: /* OV7630C */
- reg_w(gspca_dev, 0x06, 0x0010);
- break;
- case 0x7620: /* OV7620 */
- case 0x7648: /* OV7648 */
- break;
- default:
- return -1; /* not OmniVision */
- }
- return retword;
-}
-
-struct sensor_by_chipset_revision {
- u16 revision;
- u8 internal_sensor_id;
-};
-static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
- {0xc000, 0x12}, /* TAS5130C */
- {0xc001, 0x13}, /* MT9V111 */
- {0xe001, 0x13},
- {0x8001, 0x13},
- {0x8000, 0x14}, /* CS2102K */
- {0x8400, 0x15}, /* MT9V111 */
- {0xe400, 0x15},
-};
-
-static int vga_3wr_probe(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- u16 retword;
-
-/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
- reg_w(gspca_dev, 0x02, 0x0010);
- reg_r(gspca_dev, 0x0010);
- reg_w(gspca_dev, 0x01, 0x0000);
- reg_w(gspca_dev, 0x00, 0x0010);
- reg_w(gspca_dev, 0x01, 0x0001);
- reg_w(gspca_dev, 0x91, 0x008b);
- reg_w(gspca_dev, 0x03, 0x0012);
- reg_w(gspca_dev, 0x01, 0x0012);
- reg_w(gspca_dev, 0x05, 0x0012);
- retword = i2c_read(gspca_dev, 0x14);
- if (retword != 0)
- return 0x11; /* HV7131R */
- retword = i2c_read(gspca_dev, 0x15);
- if (retword != 0)
- return 0x11; /* HV7131R */
- retword = i2c_read(gspca_dev, 0x16);
- if (retword != 0)
- return 0x11; /* HV7131R */
-
- reg_w(gspca_dev, 0x02, 0x0010);
- retword = reg_r(gspca_dev, 0x000b) << 8;
- retword |= reg_r(gspca_dev, 0x000a);
- PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword);
- reg_r(gspca_dev, 0x0010);
- if ((retword & 0xff00) == 0x6400)
- return 0x02; /* TAS5130C */
- for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
- if (chipset_revision_sensor[i].revision == retword) {
- sd->chip_revision = retword;
- send_unknown(gspca_dev, SENSOR_PB0330);
- return chipset_revision_sensor[i].internal_sensor_id;
- }
- }
-
- reg_w(gspca_dev, 0x01, 0x0000); /* check PB0330 */
- reg_w(gspca_dev, 0x01, 0x0001);
- reg_w(gspca_dev, 0xdd, 0x008b);
- reg_w(gspca_dev, 0x0a, 0x0010);
- reg_w(gspca_dev, 0x03, 0x0012);
- reg_w(gspca_dev, 0x01, 0x0012);
- retword = i2c_read(gspca_dev, 0x00);
- if (retword != 0) {
- PDEBUG(D_PROBE, "probe 3wr vga type 0a");
- return 0x0a; /* PB0330 */
- }
-
- /* probe gc0303 / gc0305 */
- reg_w(gspca_dev, 0x01, 0x0000);
- reg_w(gspca_dev, 0x01, 0x0001);
- reg_w(gspca_dev, 0x98, 0x008b);
- reg_w(gspca_dev, 0x01, 0x0010);
- reg_w(gspca_dev, 0x03, 0x0012);
- msleep(2);
- reg_w(gspca_dev, 0x01, 0x0012);
- retword = i2c_read(gspca_dev, 0x00);
- if (retword != 0) {
- PDEBUG(D_PROBE, "probe 3wr vga type %02x", retword);
- if (retword == 0x0011) /* gc0303 */
- return 0x0303;
- if (retword == 0x0029) /* gc0305 */
- send_unknown(gspca_dev, SENSOR_GC0305);
- return retword;
- }
-
- reg_w(gspca_dev, 0x01, 0x0000); /* check OmniVision */
- reg_w(gspca_dev, 0x01, 0x0001);
- reg_w(gspca_dev, 0xa1, 0x008b);
- reg_w(gspca_dev, 0x08, 0x008d);
- reg_w(gspca_dev, 0x06, 0x0010);
- reg_w(gspca_dev, 0x01, 0x0012);
- reg_w(gspca_dev, 0x05, 0x0012);
- if (i2c_read(gspca_dev, 0x1c) == 0x007f /* OV7610 - manufacturer ID */
- && i2c_read(gspca_dev, 0x1d) == 0x00a2) {
- send_unknown(gspca_dev, SENSOR_OV7620);
- return 0x06; /* OmniVision confirm ? */
- }
-
- reg_w(gspca_dev, 0x01, 0x0000);
- reg_w(gspca_dev, 0x00, 0x0002);
- reg_w(gspca_dev, 0x01, 0x0010);
- reg_w(gspca_dev, 0x01, 0x0001);
- reg_w(gspca_dev, 0xee, 0x008b);
- reg_w(gspca_dev, 0x03, 0x0012);
- reg_w(gspca_dev, 0x01, 0x0012);
- reg_w(gspca_dev, 0x05, 0x0012);
- retword = i2c_read(gspca_dev, 0x00) << 8; /* ID 0 */
- retword |= i2c_read(gspca_dev, 0x01); /* ID 1 */
- PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword);
- if (retword == 0x2030) {
-#ifdef GSPCA_DEBUG
- u8 retbyte;
-
- retbyte = i2c_read(gspca_dev, 0x02); /* revision number */
- PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte);
-#endif
- send_unknown(gspca_dev, SENSOR_PO2030);
- return retword;
- }
-
- reg_w(gspca_dev, 0x01, 0x0000);
- reg_w(gspca_dev, 0x0a, 0x0010);
- reg_w(gspca_dev, 0xd3, 0x008b);
- reg_w(gspca_dev, 0x01, 0x0001);
- reg_w(gspca_dev, 0x03, 0x0012);
- reg_w(gspca_dev, 0x01, 0x0012);
- reg_w(gspca_dev, 0x05, 0x0012);
- reg_w(gspca_dev, 0xd3, 0x008b);
- retword = i2c_read(gspca_dev, 0x01);
- if (retword != 0) {
- PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword);
- return 0x16; /* adcm2700 (6100/6200) */
- }
- return -1;
-}
-
-static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int sensor;
-
- switch (sd->sensor) {
- case SENSOR_MC501CB:
- return -1; /* don't probe */
- case SENSOR_GC0303:
- /* may probe but with no write in reg 0x0010 */
- return -1; /* don't probe */
- case SENSOR_PAS106:
- sensor = sif_probe(gspca_dev);
- if (sensor >= 0)
- return sensor;
- break;
- }
- sensor = vga_2wr_probe(gspca_dev);
- if (sensor >= 0)
- return sensor;
- return vga_3wr_probe(gspca_dev);
-}
-
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (id->idProduct == 0x301b)
- sd->bridge = BRIDGE_ZC301;
- else
- sd->bridge = BRIDGE_ZC303;
-
- /* define some sensors from the vendor/product */
- sd->sensor = id->driver_info;
-
- sd->reg08 = REG08_DEF;
-
- INIT_WORK(&sd->work, transfer_update);
-
- return 0;
-}
-
-static int zcxx_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTOGAIN:
- gspca_dev->usb_err = 0;
- if (ctrl->val && sd->exposure && gspca_dev->streaming)
- sd->exposure->val = getexposure(gspca_dev);
- return gspca_dev->usb_err;
- }
- return -EINVAL;
-}
-
-static int zcxx_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct gspca_dev *gspca_dev =
- container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- struct sd *sd = (struct sd *)gspca_dev;
- int i, qual;
-
- gspca_dev->usb_err = 0;
-
- if (ctrl->id == V4L2_CID_JPEG_COMPRESSION_QUALITY) {
- qual = sd->reg08 >> 1;
-
- for (i = 0; i < ARRAY_SIZE(jpeg_qual); i++) {
- if (ctrl->val <= jpeg_qual[i])
- break;
- }
- if (i > 0 && i == qual && ctrl->val < jpeg_qual[i])
- i--;
-
- /* With high quality settings we need max bandwidth */
- if (i >= 2 && gspca_dev->streaming &&
- !gspca_dev->cam.needs_full_bandwidth)
- return -EBUSY;
-
- sd->reg08 = (i << 1) | 1;
- ctrl->val = jpeg_qual[i];
- }
-
- if (!gspca_dev->streaming)
- return 0;
-
- switch (ctrl->id) {
- /* gamma/brightness/contrast cluster */
- case V4L2_CID_GAMMA:
- setcontrast(gspca_dev, sd->gamma->val,
- sd->brightness->val, sd->contrast->val);
- break;
- /* autogain/exposure cluster */
- case V4L2_CID_AUTOGAIN:
- setautogain(gspca_dev, ctrl->val);
- if (!gspca_dev->usb_err && !ctrl->val && sd->exposure)
- setexposure(gspca_dev, sd->exposure->val);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY:
- setlightfreq(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_SHARPNESS:
- setsharpness(gspca_dev, ctrl->val);
- break;
- case V4L2_CID_JPEG_COMPRESSION_QUALITY:
- setquality(gspca_dev);
- break;
- }
- return gspca_dev->usb_err;
-}
-
-static const struct v4l2_ctrl_ops zcxx_ctrl_ops = {
- .g_volatile_ctrl = zcxx_g_volatile_ctrl,
- .s_ctrl = zcxx_s_ctrl,
-};
-
-static int sd_init_controls(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *)gspca_dev;
- struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
- static const u8 gamma[SENSOR_MAX] = {
- [SENSOR_ADCM2700] = 4,
- [SENSOR_CS2102] = 4,
- [SENSOR_CS2102K] = 5,
- [SENSOR_GC0303] = 3,
- [SENSOR_GC0305] = 4,
- [SENSOR_HDCS2020] = 4,
- [SENSOR_HV7131B] = 4,
- [SENSOR_HV7131R] = 4,
- [SENSOR_ICM105A] = 4,
- [SENSOR_MC501CB] = 4,
- [SENSOR_MT9V111_1] = 4,
- [SENSOR_MT9V111_3] = 4,
- [SENSOR_OV7620] = 3,
- [SENSOR_OV7630C] = 4,
- [SENSOR_PAS106] = 4,
- [SENSOR_PAS202B] = 4,
- [SENSOR_PB0330] = 4,
- [SENSOR_PO2030] = 4,
- [SENSOR_TAS5130C] = 3,
- };
-
- gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 8);
- sd->brightness = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- sd->contrast = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 128);
- sd->gamma = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
- V4L2_CID_GAMMA, 1, 6, 1, gamma[sd->sensor]);
- if (sd->sensor == SENSOR_HV7131R)
- sd->exposure = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
- V4L2_CID_EXPOSURE, 0x30d, 0x493e, 1, 0x927);
- sd->autogain = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- if (sd->sensor != SENSOR_OV7630C)
- sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &zcxx_ctrl_ops,
- V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
- V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
- sd->sharpness = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
- V4L2_CID_SHARPNESS, 0, 3, 1,
- sd->sensor == SENSOR_PO2030 ? 0 : 2);
- sd->jpegqual = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
- V4L2_CID_JPEG_COMPRESSION_QUALITY,
- jpeg_qual[0], jpeg_qual[ARRAY_SIZE(jpeg_qual) - 1], 1,
- jpeg_qual[REG08_DEF >> 1]);
- if (hdl->error) {
- pr_err("Could not initialize controls\n");
- return hdl->error;
- }
- v4l2_ctrl_cluster(3, &sd->gamma);
- if (sd->sensor == SENSOR_HV7131R)
- v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, true);
- return 0;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam;
- int sensor;
- static const u8 mode_tb[SENSOR_MAX] = {
- [SENSOR_ADCM2700] = 2,
- [SENSOR_CS2102] = 1,
- [SENSOR_CS2102K] = 1,
- [SENSOR_GC0303] = 1,
- [SENSOR_GC0305] = 1,
- [SENSOR_HDCS2020] = 1,
- [SENSOR_HV7131B] = 1,
- [SENSOR_HV7131R] = 1,
- [SENSOR_ICM105A] = 1,
- [SENSOR_MC501CB] = 2,
- [SENSOR_MT9V111_1] = 1,
- [SENSOR_MT9V111_3] = 1,
- [SENSOR_OV7620] = 2,
- [SENSOR_OV7630C] = 1,
- [SENSOR_PAS106] = 0,
- [SENSOR_PAS202B] = 1,
- [SENSOR_PB0330] = 1,
- [SENSOR_PO2030] = 1,
- [SENSOR_TAS5130C] = 1,
- };
-
- sensor = zcxx_probeSensor(gspca_dev);
- if (sensor >= 0)
- PDEBUG(D_PROBE, "probe sensor -> %04x", sensor);
- if ((unsigned) force_sensor < SENSOR_MAX) {
- sd->sensor = force_sensor;
- PDEBUG(D_PROBE, "sensor forced to %d", force_sensor);
- } else {
- switch (sensor) {
- case -1:
- switch (sd->sensor) {
- case SENSOR_MC501CB:
- PDEBUG(D_PROBE, "Sensor MC501CB");
- break;
- case SENSOR_GC0303:
- PDEBUG(D_PROBE, "Sensor GC0303");
- break;
- default:
- pr_warn("Unknown sensor - set to TAS5130C\n");
- sd->sensor = SENSOR_TAS5130C;
- }
- break;
- case 0:
- /* check the sensor type */
- sensor = i2c_read(gspca_dev, 0x00);
- PDEBUG(D_PROBE, "Sensor hv7131 type %d", sensor);
- switch (sensor) {
- case 0: /* hv7131b */
- case 1: /* hv7131e */
- PDEBUG(D_PROBE, "Find Sensor HV7131B");
- sd->sensor = SENSOR_HV7131B;
- break;
- default:
-/* case 2: * hv7131r */
- PDEBUG(D_PROBE, "Find Sensor HV7131R");
- sd->sensor = SENSOR_HV7131R;
- break;
- }
- break;
- case 0x02:
- PDEBUG(D_PROBE, "Sensor TAS5130C");
- sd->sensor = SENSOR_TAS5130C;
- break;
- case 0x04:
- PDEBUG(D_PROBE, "Find Sensor CS2102");
- sd->sensor = SENSOR_CS2102;
- break;
- case 0x08:
- PDEBUG(D_PROBE, "Find Sensor HDCS2020");
- sd->sensor = SENSOR_HDCS2020;
- break;
- case 0x0a:
- PDEBUG(D_PROBE,
- "Find Sensor PB0330. Chip revision %x",
- sd->chip_revision);
- sd->sensor = SENSOR_PB0330;
- break;
- case 0x0c:
- PDEBUG(D_PROBE, "Find Sensor ICM105A");
- sd->sensor = SENSOR_ICM105A;
- break;
- case 0x0e:
- PDEBUG(D_PROBE, "Find Sensor PAS202B");
- sd->sensor = SENSOR_PAS202B;
- break;
- case 0x0f:
- PDEBUG(D_PROBE, "Find Sensor PAS106");
- sd->sensor = SENSOR_PAS106;
- break;
- case 0x10:
- case 0x12:
- PDEBUG(D_PROBE, "Find Sensor TAS5130C");
- sd->sensor = SENSOR_TAS5130C;
- break;
- case 0x11:
- PDEBUG(D_PROBE, "Find Sensor HV7131R");
- sd->sensor = SENSOR_HV7131R;
- break;
- case 0x13:
- case 0x15:
- PDEBUG(D_PROBE,
- "Sensor MT9V111. Chip revision %04x",
- sd->chip_revision);
- sd->sensor = sd->bridge == BRIDGE_ZC301
- ? SENSOR_MT9V111_1
- : SENSOR_MT9V111_3;
- break;
- case 0x14:
- PDEBUG(D_PROBE,
- "Find Sensor CS2102K?. Chip revision %x",
- sd->chip_revision);
- sd->sensor = SENSOR_CS2102K;
- break;
- case 0x16:
- PDEBUG(D_PROBE, "Find Sensor ADCM2700");
- sd->sensor = SENSOR_ADCM2700;
- break;
- case 0x29:
- PDEBUG(D_PROBE, "Find Sensor GC0305");
- sd->sensor = SENSOR_GC0305;
- break;
- case 0x0303:
- PDEBUG(D_PROBE, "Sensor GC0303");
- sd->sensor = SENSOR_GC0303;
- break;
- case 0x2030:
- PDEBUG(D_PROBE, "Find Sensor PO2030");
- sd->sensor = SENSOR_PO2030;
- break;
- case 0x7620:
- PDEBUG(D_PROBE, "Find Sensor OV7620");
- sd->sensor = SENSOR_OV7620;
- break;
- case 0x7631:
- PDEBUG(D_PROBE, "Find Sensor OV7630C");
- sd->sensor = SENSOR_OV7630C;
- break;
- case 0x7648:
- PDEBUG(D_PROBE, "Find Sensor OV7648");
- sd->sensor = SENSOR_OV7620; /* same sensor (?) */
- break;
- default:
- pr_err("Unknown sensor %04x\n", sensor);
- return -EINVAL;
- }
- }
- if (sensor < 0x20) {
- if (sensor == -1 || sensor == 0x10 || sensor == 0x12)
- reg_w(gspca_dev, 0x02, 0x0010);
- reg_r(gspca_dev, 0x0010);
- }
-
- cam = &gspca_dev->cam;
- switch (mode_tb[sd->sensor]) {
- case 0:
- cam->cam_mode = sif_mode;
- cam->nmodes = ARRAY_SIZE(sif_mode);
- break;
- case 1:
- cam->cam_mode = vga_mode;
- cam->nmodes = ARRAY_SIZE(vga_mode);
- break;
- default:
-/* case 2: */
- cam->cam_mode = broken_vga_mode;
- cam->nmodes = ARRAY_SIZE(broken_vga_mode);
- break;
- }
-
- /* switch off the led */
- reg_w(gspca_dev, 0x01, 0x0000);
- return gspca_dev->usb_err;
-}
-
-static int sd_pre_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- gspca_dev->cam.needs_full_bandwidth = (sd->reg08 >= 4) ? 1 : 0;
- return 0;
-}
-
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int mode;
- static const struct usb_action *init_tb[SENSOR_MAX][2] = {
- [SENSOR_ADCM2700] =
- {adcm2700_Initial, adcm2700_InitialScale},
- [SENSOR_CS2102] =
- {cs2102_Initial, cs2102_InitialScale},
- [SENSOR_CS2102K] =
- {cs2102K_Initial, cs2102K_InitialScale},
- [SENSOR_GC0303] =
- {gc0303_Initial, gc0303_InitialScale},
- [SENSOR_GC0305] =
- {gc0305_Initial, gc0305_InitialScale},
- [SENSOR_HDCS2020] =
- {hdcs2020_Initial, hdcs2020_InitialScale},
- [SENSOR_HV7131B] =
- {hv7131b_Initial, hv7131b_InitialScale},
- [SENSOR_HV7131R] =
- {hv7131r_Initial, hv7131r_InitialScale},
- [SENSOR_ICM105A] =
- {icm105a_Initial, icm105a_InitialScale},
- [SENSOR_MC501CB] =
- {mc501cb_Initial, mc501cb_InitialScale},
- [SENSOR_MT9V111_1] =
- {mt9v111_1_Initial, mt9v111_1_InitialScale},
- [SENSOR_MT9V111_3] =
- {mt9v111_3_Initial, mt9v111_3_InitialScale},
- [SENSOR_OV7620] =
- {ov7620_Initial, ov7620_InitialScale},
- [SENSOR_OV7630C] =
- {ov7630c_Initial, ov7630c_InitialScale},
- [SENSOR_PAS106] =
- {pas106b_Initial, pas106b_InitialScale},
- [SENSOR_PAS202B] =
- {pas202b_Initial, pas202b_InitialScale},
- [SENSOR_PB0330] =
- {pb0330_Initial, pb0330_InitialScale},
- [SENSOR_PO2030] =
- {po2030_Initial, po2030_InitialScale},
- [SENSOR_TAS5130C] =
- {tas5130c_Initial, tas5130c_InitialScale},
- };
-
- /* create the JPEG header */
- jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
- 0x21); /* JPEG 422 */
-
- mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
- switch (sd->sensor) {
- case SENSOR_HV7131R:
- zcxx_probeSensor(gspca_dev);
- break;
- case SENSOR_PAS106:
- usb_exchange(gspca_dev, pas106b_Initial_com);
- break;
- }
- usb_exchange(gspca_dev, init_tb[sd->sensor][mode]);
-
- switch (sd->sensor) {
- case SENSOR_ADCM2700:
- case SENSOR_GC0305:
- case SENSOR_OV7620:
- case SENSOR_PO2030:
- case SENSOR_TAS5130C:
- case SENSOR_GC0303:
-/* msleep(100); * ?? */
- reg_r(gspca_dev, 0x0002); /* --> 0x40 */
- reg_w(gspca_dev, 0x09, 0x01ad); /* (from win traces) */
- reg_w(gspca_dev, 0x15, 0x01ae);
- if (sd->sensor == SENSOR_TAS5130C)
- break;
- reg_w(gspca_dev, 0x0d, 0x003a);
- reg_w(gspca_dev, 0x02, 0x003b);
- reg_w(gspca_dev, 0x00, 0x0038);
- break;
- case SENSOR_HV7131R:
- case SENSOR_PAS202B:
- reg_w(gspca_dev, 0x03, 0x003b);
- reg_w(gspca_dev, 0x0c, 0x003a);
- reg_w(gspca_dev, 0x0b, 0x0039);
- if (sd->sensor == SENSOR_HV7131R)
- reg_w(gspca_dev, 0x50, ZC3XX_R11D_GLOBALGAIN);
- break;
- }
-
- setmatrix(gspca_dev);
- switch (sd->sensor) {
- case SENSOR_ADCM2700:
- case SENSOR_OV7620:
- reg_r(gspca_dev, 0x0008);
- reg_w(gspca_dev, 0x00, 0x0008);
- break;
- case SENSOR_PAS202B:
- case SENSOR_GC0305:
- case SENSOR_HV7131R:
- case SENSOR_TAS5130C:
- reg_r(gspca_dev, 0x0008);
- /* fall thru */
- case SENSOR_PO2030:
- reg_w(gspca_dev, 0x03, 0x0008);
- break;
- }
- setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness));
-
- /* set the gamma tables when not set */
- switch (sd->sensor) {
- case SENSOR_CS2102K: /* gamma set in xxx_Initial */
- case SENSOR_HDCS2020:
- case SENSOR_OV7630C:
- break;
- default:
- setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma),
- v4l2_ctrl_g_ctrl(sd->brightness),
- v4l2_ctrl_g_ctrl(sd->contrast));
- break;
- }
- setmatrix(gspca_dev); /* one more time? */
- switch (sd->sensor) {
- case SENSOR_OV7620:
- case SENSOR_PAS202B:
- reg_r(gspca_dev, 0x0180); /* from win */
- reg_w(gspca_dev, 0x00, 0x0180);
- break;
- }
- setquality(gspca_dev);
- /* Start with BRC disabled, transfer_update will enable it if needed */
- reg_w(gspca_dev, 0x00, 0x0007);
- if (sd->plfreq)
- setlightfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->plfreq));
-
- switch (sd->sensor) {
- case SENSOR_ADCM2700:
- reg_w(gspca_dev, 0x09, 0x01ad); /* (from win traces) */
- reg_w(gspca_dev, 0x15, 0x01ae);
- reg_w(gspca_dev, 0x02, 0x0180);
- /* ms-win + */
- reg_w(gspca_dev, 0x40, 0x0117);
- break;
- case SENSOR_HV7131R:
- setexposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
- reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN);
- break;
- case SENSOR_GC0305:
- case SENSOR_TAS5130C:
- reg_w(gspca_dev, 0x09, 0x01ad); /* (from win traces) */
- reg_w(gspca_dev, 0x15, 0x01ae);
- /* fall thru */
- case SENSOR_PAS202B:
- case SENSOR_PO2030:
-/* reg_w(gspca_dev, 0x40, ZC3XX_R117_GGAIN); in win traces */
- reg_r(gspca_dev, 0x0180);
- break;
- case SENSOR_OV7620:
- reg_w(gspca_dev, 0x09, 0x01ad);
- reg_w(gspca_dev, 0x15, 0x01ae);
- i2c_read(gspca_dev, 0x13); /*fixme: returns 0xa3 */
- i2c_write(gspca_dev, 0x13, 0xa3, 0x00);
- /*fixme: returned value to send? */
- reg_w(gspca_dev, 0x40, 0x0117);
- reg_r(gspca_dev, 0x0180);
- break;
- }
-
- setautogain(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain));
-
- if (gspca_dev->usb_err < 0)
- return gspca_dev->usb_err;
-
- /* Start the transfer parameters update thread */
- sd->work_thread = create_singlethread_workqueue(KBUILD_MODNAME);
- queue_work(sd->work_thread, &sd->work);
-
- return 0;
-}
-
-/* called on streamoff with alt 0 and on disconnect */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- if (sd->work_thread != NULL) {
- mutex_unlock(&gspca_dev->usb_lock);
- destroy_workqueue(sd->work_thread);
- mutex_lock(&gspca_dev->usb_lock);
- sd->work_thread = NULL;
- }
- if (!gspca_dev->dev)
- return;
- send_unknown(gspca_dev, sd->sensor);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data,
- int len)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- /* check the JPEG end of frame */
- if (len >= 3
- && data[len - 3] == 0xff && data[len - 2] == 0xd9) {
-/*fixme: what does the last byte mean?*/
- gspca_frame_add(gspca_dev, LAST_PACKET,
- data, len - 1);
- return;
- }
-
- /* check the JPEG start of a frame */
- if (data[0] == 0xff && data[1] == 0xd8) {
- /* put the JPEG header in the new frame */
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- sd->jpeg_hdr, JPEG_HDR_SZ);
-
- /* remove the webcam's header:
- * ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp
- * - 'ss ss' is the frame sequence number (BE)
- * - 'ww ww' and 'hh hh' are the window dimensions (BE)
- * - 'pp pp' is the packet sequence number (BE)
- */
- data += 18;
- len -= 18;
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
-}
-
-static int sd_set_jcomp(struct gspca_dev *gspca_dev,
- struct v4l2_jpegcompression *jcomp)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
- if (ret)
- return ret;
- jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
- return 0;
-}
-
-static int sd_get_jcomp(struct gspca_dev *gspca_dev,
- struct v4l2_jpegcompression *jcomp)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- memset(jcomp, 0, sizeof *jcomp);
- jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
- jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
- | V4L2_JPEG_MARKER_DQT;
- return 0;
-}
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
-static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
- u8 *data, /* interrupt packet data */
- int len) /* interrput packet length */
-{
- if (len == 8 && data[4] == 1) {
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
- input_sync(gspca_dev->input_dev);
- input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
- input_sync(gspca_dev->input_dev);
- }
-
- return 0;
-}
-#endif
-
-static const struct sd_desc sd_desc = {
- .name = KBUILD_MODNAME,
- .config = sd_config,
- .init = sd_init,
- .init_controls = sd_init_controls,
- .isoc_init = sd_pre_start,
- .start = sd_start,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
- .get_jcomp = sd_get_jcomp,
- .set_jcomp = sd_set_jcomp,
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- .int_pkt_scan = sd_int_pkt_scan,
-#endif
-};
-
-static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x03f0, 0x1b07)},
- {USB_DEVICE(0x041e, 0x041e)},
- {USB_DEVICE(0x041e, 0x4017)},
- {USB_DEVICE(0x041e, 0x401c), .driver_info = SENSOR_PAS106},
- {USB_DEVICE(0x041e, 0x401e)},
- {USB_DEVICE(0x041e, 0x401f)},
- {USB_DEVICE(0x041e, 0x4022)},
- {USB_DEVICE(0x041e, 0x4029)},
- {USB_DEVICE(0x041e, 0x4034), .driver_info = SENSOR_PAS106},
- {USB_DEVICE(0x041e, 0x4035), .driver_info = SENSOR_PAS106},
- {USB_DEVICE(0x041e, 0x4036)},
- {USB_DEVICE(0x041e, 0x403a)},
- {USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_GC0303},
- {USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_GC0303},
- {USB_DEVICE(0x0458, 0x7007)},
- {USB_DEVICE(0x0458, 0x700c)},
- {USB_DEVICE(0x0458, 0x700f)},
- {USB_DEVICE(0x0461, 0x0a00)},
- {USB_DEVICE(0x046d, 0x089d), .driver_info = SENSOR_MC501CB},
- {USB_DEVICE(0x046d, 0x08a0)},
- {USB_DEVICE(0x046d, 0x08a1)},
- {USB_DEVICE(0x046d, 0x08a2)},
- {USB_DEVICE(0x046d, 0x08a3)},
- {USB_DEVICE(0x046d, 0x08a6)},
- {USB_DEVICE(0x046d, 0x08a7)},
- {USB_DEVICE(0x046d, 0x08a9)},
- {USB_DEVICE(0x046d, 0x08aa)},
- {USB_DEVICE(0x046d, 0x08ac)},
- {USB_DEVICE(0x046d, 0x08ad)},
- {USB_DEVICE(0x046d, 0x08ae)},
- {USB_DEVICE(0x046d, 0x08af)},
- {USB_DEVICE(0x046d, 0x08b9)},
- {USB_DEVICE(0x046d, 0x08d7)},
- {USB_DEVICE(0x046d, 0x08d8)},
- {USB_DEVICE(0x046d, 0x08d9)},
- {USB_DEVICE(0x046d, 0x08da)},
- {USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB},
- {USB_DEVICE(0x0471, 0x0325), .driver_info = SENSOR_PAS106},
- {USB_DEVICE(0x0471, 0x0326), .driver_info = SENSOR_PAS106},
- {USB_DEVICE(0x0471, 0x032d), .driver_info = SENSOR_PAS106},
- {USB_DEVICE(0x0471, 0x032e), .driver_info = SENSOR_PAS106},
- {USB_DEVICE(0x055f, 0xc005)},
- {USB_DEVICE(0x055f, 0xd003)},
- {USB_DEVICE(0x055f, 0xd004)},
- {USB_DEVICE(0x0698, 0x2003)},
- {USB_DEVICE(0x0ac8, 0x0301), .driver_info = SENSOR_PAS106},
- {USB_DEVICE(0x0ac8, 0x0302), .driver_info = SENSOR_PAS106},
- {USB_DEVICE(0x0ac8, 0x301b)},
- {USB_DEVICE(0x0ac8, 0x303b)},
- {USB_DEVICE(0x0ac8, 0x305b)},
- {USB_DEVICE(0x0ac8, 0x307b)},
- {USB_DEVICE(0x10fd, 0x0128)},
- {USB_DEVICE(0x10fd, 0x804d)},
- {USB_DEVICE(0x10fd, 0x8050)},
- {} /* end of entry */
-};
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
-}
-
-/* USB driver */
-static struct usb_driver sd_driver = {
- .name = KBUILD_MODNAME,
- .id_table = device_table,
- .probe = sd_probe,
- .disconnect = gspca_disconnect,
-#ifdef CONFIG_PM
- .suspend = gspca_suspend,
- .resume = gspca_resume,
- .reset_resume = gspca_resume,
-#endif
-};
-
-module_usb_driver(sd_driver);
-
-module_param(force_sensor, int, 0644);
-MODULE_PARM_DESC(force_sensor,
- "Force sensor. Only for experts!!!");
diff --git a/drivers/media/video/hdpvr/Kconfig b/drivers/media/video/hdpvr/Kconfig
deleted file mode 100644
index de247f3c7d0..00000000000
--- a/drivers/media/video/hdpvr/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-
-config VIDEO_HDPVR
- tristate "Hauppauge HD PVR support"
- depends on VIDEO_DEV
- ---help---
- This is a video4linux driver for Hauppauge's HD PVR USB device.
-
- To compile this driver as a module, choose M here: the
- module will be called hdpvr
-
diff --git a/drivers/media/video/hdpvr/Makefile b/drivers/media/video/hdpvr/Makefile
deleted file mode 100644
index 52f057f24e3..00000000000
--- a/drivers/media/video/hdpvr/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-hdpvr-objs := hdpvr-control.o hdpvr-core.o hdpvr-video.o hdpvr-i2c.o
-
-obj-$(CONFIG_VIDEO_HDPVR) += hdpvr.o
-
-ccflags-y += -Idrivers/media/video
-
-ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/hdpvr/hdpvr-control.c b/drivers/media/video/hdpvr/hdpvr-control.c
deleted file mode 100644
index ae8f229d114..00000000000
--- a/drivers/media/video/hdpvr/hdpvr-control.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Hauppauge HD PVR USB driver - video 4 linux 2 interface
- *
- * Copyright (C) 2008 Janne Grunau (j@jannau.net)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-#include <linux/mutex.h>
-
-#include <linux/videodev2.h>
-
-#include <media/v4l2-common.h>
-
-#include "hdpvr.h"
-
-
-int hdpvr_config_call(struct hdpvr_device *dev, uint value, u8 valbuf)
-{
- int ret;
- char request_type = 0x38, snd_request = 0x01;
-
- mutex_lock(&dev->usbc_mutex);
- dev->usbc_buf[0] = valbuf;
- ret = usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- snd_request, 0x00 | request_type,
- value, CTRL_DEFAULT_INDEX,
- dev->usbc_buf, 1, 10000);
-
- mutex_unlock(&dev->usbc_mutex);
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "config call request for value 0x%x returned %d\n", value,
- ret);
-
- return ret < 0 ? ret : 0;
-}
-
-struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev)
-{
- struct hdpvr_video_info *vidinf = NULL;
-#ifdef HDPVR_DEBUG
- char print_buf[15];
-#endif
- int ret;
-
- vidinf = kzalloc(sizeof(struct hdpvr_video_info), GFP_KERNEL);
- if (!vidinf) {
- v4l2_err(&dev->v4l2_dev, "out of memory\n");
- goto err;
- }
-
- mutex_lock(&dev->usbc_mutex);
- ret = usb_control_msg(dev->udev,
- usb_rcvctrlpipe(dev->udev, 0),
- 0x81, 0x80 | 0x38,
- 0x1400, 0x0003,
- dev->usbc_buf, 5,
- 1000);
- if (ret == 5) {
- vidinf->width = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
- vidinf->height = dev->usbc_buf[3] << 8 | dev->usbc_buf[2];
- vidinf->fps = dev->usbc_buf[4];
- }
-
-#ifdef HDPVR_DEBUG
- if (hdpvr_debug & MSG_INFO) {
- hex_dump_to_buffer(dev->usbc_buf, 5, 16, 1, print_buf,
- sizeof(print_buf), 0);
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "get video info returned: %d, %s\n", ret, print_buf);
- }
-#endif
- mutex_unlock(&dev->usbc_mutex);
-
- if (!vidinf->width || !vidinf->height || !vidinf->fps) {
- kfree(vidinf);
- vidinf = NULL;
- }
-err:
- return vidinf;
-}
-
-int get_input_lines_info(struct hdpvr_device *dev)
-{
-#ifdef HDPVR_DEBUG
- char print_buf[9];
-#endif
- int ret, lines;
-
- mutex_lock(&dev->usbc_mutex);
- ret = usb_control_msg(dev->udev,
- usb_rcvctrlpipe(dev->udev, 0),
- 0x81, 0x80 | 0x38,
- 0x1800, 0x0003,
- dev->usbc_buf, 3,
- 1000);
-
-#ifdef HDPVR_DEBUG
- if (hdpvr_debug & MSG_INFO) {
- hex_dump_to_buffer(dev->usbc_buf, 3, 16, 1, print_buf,
- sizeof(print_buf), 0);
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "get input lines info returned: %d, %s\n", ret,
- print_buf);
- }
-#else
- (void)ret; /* suppress compiler warning */
-#endif
- lines = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
- mutex_unlock(&dev->usbc_mutex);
- return lines;
-}
-
-
-int hdpvr_set_bitrate(struct hdpvr_device *dev)
-{
- int ret;
-
- mutex_lock(&dev->usbc_mutex);
- memset(dev->usbc_buf, 0, 4);
- dev->usbc_buf[0] = dev->options.bitrate;
- dev->usbc_buf[2] = dev->options.peak_bitrate;
-
- ret = usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- 0x01, 0x38, CTRL_BITRATE_VALUE,
- CTRL_DEFAULT_INDEX, dev->usbc_buf, 4, 1000);
- mutex_unlock(&dev->usbc_mutex);
-
- return ret;
-}
-
-int hdpvr_set_audio(struct hdpvr_device *dev, u8 input,
- enum v4l2_mpeg_audio_encoding codec)
-{
- int ret = 0;
-
- if (dev->flags & HDPVR_FLAG_AC3_CAP) {
- mutex_lock(&dev->usbc_mutex);
- memset(dev->usbc_buf, 0, 2);
- dev->usbc_buf[0] = input;
- if (codec == V4L2_MPEG_AUDIO_ENCODING_AAC)
- dev->usbc_buf[1] = 0;
- else if (codec == V4L2_MPEG_AUDIO_ENCODING_AC3)
- dev->usbc_buf[1] = 1;
- else {
- mutex_unlock(&dev->usbc_mutex);
- v4l2_err(&dev->v4l2_dev, "invalid audio codec %d\n",
- codec);
- ret = -EINVAL;
- goto error;
- }
-
- ret = usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- 0x01, 0x38, CTRL_AUDIO_INPUT_VALUE,
- CTRL_DEFAULT_INDEX, dev->usbc_buf, 2,
- 1000);
- mutex_unlock(&dev->usbc_mutex);
- if (ret == 2)
- ret = 0;
- } else
- ret = hdpvr_config_call(dev, CTRL_AUDIO_INPUT_VALUE, input);
-error:
- return ret;
-}
-
-int hdpvr_set_options(struct hdpvr_device *dev)
-{
- hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, dev->options.video_std);
-
- hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE,
- dev->options.video_input+1);
-
- hdpvr_set_audio(dev, dev->options.audio_input+1,
- dev->options.audio_codec);
-
- hdpvr_set_bitrate(dev);
- hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
- dev->options.bitrate_mode);
- hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, dev->options.gop_mode);
-
- hdpvr_config_call(dev, CTRL_BRIGHTNESS, dev->options.brightness);
- hdpvr_config_call(dev, CTRL_CONTRAST, dev->options.contrast);
- hdpvr_config_call(dev, CTRL_HUE, dev->options.hue);
- hdpvr_config_call(dev, CTRL_SATURATION, dev->options.saturation);
- hdpvr_config_call(dev, CTRL_SHARPNESS, dev->options.sharpness);
-
- return 0;
-}
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
deleted file mode 100644
index 304f43ef59e..00000000000
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * Hauppauge HD PVR USB driver
- *
- * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2008 Janne Grunau (j@jannau.net)
- * Copyright (C) 2008 John Poet
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/uaccess.h>
-#include <linux/atomic.h>
-#include <linux/usb.h>
-#include <linux/mutex.h>
-#include <linux/i2c.h>
-
-#include <linux/videodev2.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-common.h>
-
-#include "hdpvr.h"
-
-static int video_nr[HDPVR_MAX] = {[0 ... (HDPVR_MAX - 1)] = UNSET};
-module_param_array(video_nr, int, NULL, 0);
-MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)");
-
-/* holds the number of currently registered devices */
-static atomic_t dev_nr = ATOMIC_INIT(-1);
-
-int hdpvr_debug;
-module_param(hdpvr_debug, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(hdpvr_debug, "enable debugging output");
-
-static uint default_video_input = HDPVR_VIDEO_INPUTS;
-module_param(default_video_input, uint, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / "
- "1=S-Video / 2=Composite");
-
-static uint default_audio_input = HDPVR_AUDIO_INPUTS;
-module_param(default_audio_input, uint, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / "
- "1=RCA front / 2=S/PDIF");
-
-static bool boost_audio;
-module_param(boost_audio, bool, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(boost_audio, "boost the audio signal");
-
-
-/* table of devices that work with this driver */
-static struct usb_device_id hdpvr_table[] = {
- { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID) },
- { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) },
- { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) },
- { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID3) },
- { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID4) },
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, hdpvr_table);
-
-
-void hdpvr_delete(struct hdpvr_device *dev)
-{
- hdpvr_free_buffers(dev);
-
- if (dev->video_dev)
- video_device_release(dev->video_dev);
-
- usb_put_dev(dev->udev);
-}
-
-static void challenge(u8 *bytes)
-{
- u64 *i64P, tmp64;
- uint i, idx;
-
- for (idx = 0; idx < 32; ++idx) {
-
- if (idx & 0x3)
- bytes[(idx >> 3) + 3] = bytes[(idx >> 2) & 0x3];
-
- switch (idx & 0x3) {
- case 0x3:
- bytes[2] += bytes[3] * 4 + bytes[4] + bytes[5];
- bytes[4] += bytes[(idx & 0x1) * 2] * 9 + 9;
- break;
- case 0x1:
- bytes[0] *= 8;
- bytes[0] += 7*idx + 4;
- bytes[6] += bytes[3] * 3;
- break;
- case 0x0:
- bytes[3 - (idx >> 3)] = bytes[idx >> 2];
- bytes[5] += bytes[6] * 3;
- for (i = 0; i < 3; i++)
- bytes[3] *= bytes[3] + 1;
- break;
- case 0x2:
- for (i = 0; i < 3; i++)
- bytes[1] *= bytes[6] + 1;
- for (i = 0; i < 3; i++) {
- i64P = (u64 *)bytes;
- tmp64 = le64_to_cpup(i64P);
- tmp64 <<= bytes[7] & 0x0f;
- *i64P += cpu_to_le64(tmp64);
- }
- break;
- }
- }
-}
-
-/* try to init the device like the windows driver */
-static int device_authorization(struct hdpvr_device *dev)
-{
-
- int ret, retval = -ENOMEM;
- char request_type = 0x38, rcv_request = 0x81;
- char *response;
-#ifdef HDPVR_DEBUG
- size_t buf_size = 46;
- char *print_buf = kzalloc(5*buf_size+1, GFP_KERNEL);
- if (!print_buf) {
- v4l2_err(&dev->v4l2_dev, "Out of memory\n");
- return retval;
- }
-#endif
-
- mutex_lock(&dev->usbc_mutex);
- ret = usb_control_msg(dev->udev,
- usb_rcvctrlpipe(dev->udev, 0),
- rcv_request, 0x80 | request_type,
- 0x0400, 0x0003,
- dev->usbc_buf, 46,
- 10000);
- if (ret != 46) {
- v4l2_err(&dev->v4l2_dev,
- "unexpected answer of status request, len %d\n", ret);
- goto unlock;
- }
-#ifdef HDPVR_DEBUG
- else {
- hex_dump_to_buffer(dev->usbc_buf, 46, 16, 1, print_buf,
- 5*buf_size+1, 0);
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "Status request returned, len %d: %s\n",
- ret, print_buf);
- }
-#endif
-
- dev->fw_ver = dev->usbc_buf[1];
-
- v4l2_info(&dev->v4l2_dev, "firmware version 0x%x dated %s\n",
- dev->fw_ver, &dev->usbc_buf[2]);
-
- if (dev->fw_ver > 0x15) {
- dev->options.brightness = 0x80;
- dev->options.contrast = 0x40;
- dev->options.hue = 0xf;
- dev->options.saturation = 0x40;
- dev->options.sharpness = 0x80;
- }
-
- switch (dev->fw_ver) {
- case HDPVR_FIRMWARE_VERSION:
- dev->flags &= ~HDPVR_FLAG_AC3_CAP;
- break;
- case HDPVR_FIRMWARE_VERSION_AC3:
- case HDPVR_FIRMWARE_VERSION_0X12:
- case HDPVR_FIRMWARE_VERSION_0X15:
- dev->flags |= HDPVR_FLAG_AC3_CAP;
- break;
- default:
- v4l2_info(&dev->v4l2_dev, "untested firmware, the driver might"
- " not work.\n");
- if (dev->fw_ver >= HDPVR_FIRMWARE_VERSION_AC3)
- dev->flags |= HDPVR_FLAG_AC3_CAP;
- else
- dev->flags &= ~HDPVR_FLAG_AC3_CAP;
- }
-
- response = dev->usbc_buf+38;
-#ifdef HDPVR_DEBUG
- hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0);
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, "challenge: %s\n",
- print_buf);
-#endif
- challenge(response);
-#ifdef HDPVR_DEBUG
- hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0);
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n",
- print_buf);
-#endif
-
- msleep(100);
- ret = usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- 0xd1, 0x00 | request_type,
- 0x0000, 0x0000,
- response, 8,
- 10000);
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "magic request returned %d\n", ret);
-
- retval = ret != 8;
-unlock:
- mutex_unlock(&dev->usbc_mutex);
- return retval;
-}
-
-static int hdpvr_device_init(struct hdpvr_device *dev)
-{
- int ret;
- u8 *buf;
- struct hdpvr_video_info *vidinf;
-
- if (device_authorization(dev))
- return -EACCES;
-
- /* default options for init */
- hdpvr_set_options(dev);
-
- /* set filter options */
- mutex_lock(&dev->usbc_mutex);
- buf = dev->usbc_buf;
- buf[0] = 0x03; buf[1] = 0x03; buf[2] = 0x00; buf[3] = 0x00;
- ret = usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- 0x01, 0x38,
- CTRL_LOW_PASS_FILTER_VALUE, CTRL_DEFAULT_INDEX,
- buf, 4,
- 1000);
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "control request returned %d\n", ret);
- mutex_unlock(&dev->usbc_mutex);
-
- vidinf = get_video_info(dev);
- if (!vidinf)
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "no valid video signal or device init failed\n");
- else
- kfree(vidinf);
-
- /* enable fan and bling leds */
- mutex_lock(&dev->usbc_mutex);
- buf[0] = 0x1;
- ret = usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- 0xd4, 0x38, 0, 0, buf, 1,
- 1000);
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "control request returned %d\n", ret);
-
- /* boost analog audio */
- buf[0] = boost_audio;
- ret = usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- 0xd5, 0x38, 0, 0, buf, 1,
- 1000);
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "control request returned %d\n", ret);
- mutex_unlock(&dev->usbc_mutex);
-
- dev->status = STATUS_IDLE;
- return 0;
-}
-
-static const struct hdpvr_options hdpvr_default_options = {
- .video_std = HDPVR_60HZ,
- .video_input = HDPVR_COMPONENT,
- .audio_input = HDPVR_RCA_BACK,
- .bitrate = 65, /* 6 mbps */
- .peak_bitrate = 90, /* 9 mbps */
- .bitrate_mode = HDPVR_CONSTANT,
- .gop_mode = HDPVR_SIMPLE_IDR_GOP,
- .audio_codec = V4L2_MPEG_AUDIO_ENCODING_AAC,
- /* original picture controls for firmware version <= 0x15 */
- /* updated in device_authorization() for newer firmware */
- .brightness = 0x86,
- .contrast = 0x80,
- .hue = 0x80,
- .saturation = 0x80,
- .sharpness = 0x80,
-};
-
-static int hdpvr_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- struct hdpvr_device *dev;
- struct usb_host_interface *iface_desc;
- struct usb_endpoint_descriptor *endpoint;
- struct i2c_client *client;
- size_t buffer_size;
- int i;
- int retval = -ENOMEM;
-
- /* allocate memory for our device state and initialize it */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev) {
- dev_err(&interface->dev, "Out of memory\n");
- goto error;
- }
-
- dev->workqueue = 0;
-
- /* register v4l2_device early so it can be used for printks */
- if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
- dev_err(&interface->dev, "v4l2_device_register failed\n");
- goto error;
- }
-
- mutex_init(&dev->io_mutex);
- mutex_init(&dev->i2c_mutex);
- mutex_init(&dev->usbc_mutex);
- dev->usbc_buf = kmalloc(64, GFP_KERNEL);
- if (!dev->usbc_buf) {
- v4l2_err(&dev->v4l2_dev, "Out of memory\n");
- goto error;
- }
-
- init_waitqueue_head(&dev->wait_buffer);
- init_waitqueue_head(&dev->wait_data);
-
- dev->workqueue = create_singlethread_workqueue("hdpvr_buffer");
- if (!dev->workqueue)
- goto error;
-
- /* init video transfer queues */
- INIT_LIST_HEAD(&dev->free_buff_list);
- INIT_LIST_HEAD(&dev->rec_buff_list);
-
- dev->options = hdpvr_default_options;
-
- if (default_video_input < HDPVR_VIDEO_INPUTS)
- dev->options.video_input = default_video_input;
-
- if (default_audio_input < HDPVR_AUDIO_INPUTS) {
- dev->options.audio_input = default_audio_input;
- if (default_audio_input == HDPVR_SPDIF)
- dev->options.audio_codec =
- V4L2_MPEG_AUDIO_ENCODING_AC3;
- }
-
- dev->udev = usb_get_dev(interface_to_usbdev(interface));
-
- /* set up the endpoint information */
- /* use only the first bulk-in and bulk-out endpoints */
- iface_desc = interface->cur_altsetting;
- for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
- endpoint = &iface_desc->endpoint[i].desc;
-
- if (!dev->bulk_in_endpointAddr &&
- usb_endpoint_is_bulk_in(endpoint)) {
- /* USB interface description is buggy, reported max
- * packet size is 512 bytes, windows driver uses 8192 */
- buffer_size = 8192;
- dev->bulk_in_size = buffer_size;
- dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
- }
-
- }
- if (!dev->bulk_in_endpointAddr) {
- v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n");
- goto error;
- }
-
- /* init the device */
- if (hdpvr_device_init(dev)) {
- v4l2_err(&dev->v4l2_dev, "device init failed\n");
- goto error;
- }
-
- mutex_lock(&dev->io_mutex);
- if (hdpvr_alloc_buffers(dev, NUM_BUFFERS)) {
- mutex_unlock(&dev->io_mutex);
- v4l2_err(&dev->v4l2_dev,
- "allocating transfer buffers failed\n");
- goto error;
- }
- mutex_unlock(&dev->io_mutex);
-
- if (hdpvr_register_videodev(dev, &interface->dev,
- video_nr[atomic_inc_return(&dev_nr)])) {
- v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
- goto error;
- }
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- retval = hdpvr_register_i2c_adapter(dev);
- if (retval < 0) {
- v4l2_err(&dev->v4l2_dev, "i2c adapter register failed\n");
- goto error;
- }
-
- client = hdpvr_register_ir_rx_i2c(dev);
- if (!client) {
- v4l2_err(&dev->v4l2_dev, "i2c IR RX device register failed\n");
- goto reg_fail;
- }
-
- client = hdpvr_register_ir_tx_i2c(dev);
- if (!client) {
- v4l2_err(&dev->v4l2_dev, "i2c IR TX device register failed\n");
- goto reg_fail;
- }
-#endif
-
- /* let the user know what node this device is now attached to */
- v4l2_info(&dev->v4l2_dev, "device now attached to %s\n",
- video_device_node_name(dev->video_dev));
- return 0;
-
-reg_fail:
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_adapter(&dev->i2c_adapter);
-#endif
-error:
- if (dev) {
- /* Destroy single thread */
- if (dev->workqueue)
- destroy_workqueue(dev->workqueue);
- /* this frees allocated memory */
- hdpvr_delete(dev);
- }
- return retval;
-}
-
-static void hdpvr_disconnect(struct usb_interface *interface)
-{
- struct hdpvr_device *dev = to_hdpvr_dev(usb_get_intfdata(interface));
-
- v4l2_info(&dev->v4l2_dev, "device %s disconnected\n",
- video_device_node_name(dev->video_dev));
- /* prevent more I/O from starting and stop any ongoing */
- mutex_lock(&dev->io_mutex);
- dev->status = STATUS_DISCONNECTED;
- wake_up_interruptible(&dev->wait_data);
- wake_up_interruptible(&dev->wait_buffer);
- mutex_unlock(&dev->io_mutex);
- v4l2_device_disconnect(&dev->v4l2_dev);
- msleep(100);
- flush_workqueue(dev->workqueue);
- mutex_lock(&dev->io_mutex);
- hdpvr_cancel_queue(dev);
- mutex_unlock(&dev->io_mutex);
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_adapter(&dev->i2c_adapter);
-#endif
- video_unregister_device(dev->video_dev);
- atomic_dec(&dev_nr);
-}
-
-
-static struct usb_driver hdpvr_usb_driver = {
- .name = "hdpvr",
- .probe = hdpvr_probe,
- .disconnect = hdpvr_disconnect,
- .id_table = hdpvr_table,
-};
-
-module_usb_driver(hdpvr_usb_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.2.1");
-MODULE_AUTHOR("Janne Grunau");
-MODULE_DESCRIPTION("Hauppauge HD PVR driver");
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
deleted file mode 100644
index 82e819fa91c..00000000000
--- a/drivers/media/video/hdpvr/hdpvr-i2c.c
+++ /dev/null
@@ -1,231 +0,0 @@
-
-/*
- * Hauppauge HD PVR USB driver
- *
- * Copyright (C) 2008 Janne Grunau (j@jannau.net)
- *
- * IR device registration code is
- * Copyright (C) 2010 Andy Walls <awalls@md.metrocast.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-
-#include "hdpvr.h"
-
-#define CTRL_READ_REQUEST 0xb8
-#define CTRL_WRITE_REQUEST 0x38
-
-#define REQTYPE_I2C_READ 0xb1
-#define REQTYPE_I2C_WRITE 0xb0
-#define REQTYPE_I2C_WRITE_STATT 0xd0
-
-#define Z8F0811_IR_TX_I2C_ADDR 0x70
-#define Z8F0811_IR_RX_I2C_ADDR 0x71
-
-
-struct i2c_client *hdpvr_register_ir_tx_i2c(struct hdpvr_device *dev)
-{
- struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
- struct i2c_board_info hdpvr_ir_tx_i2c_board_info = {
- I2C_BOARD_INFO("ir_tx_z8f0811_hdpvr", Z8F0811_IR_TX_I2C_ADDR),
- };
-
- init_data->name = "HD-PVR";
- hdpvr_ir_tx_i2c_board_info.platform_data = init_data;
-
- return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_tx_i2c_board_info);
-}
-
-struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev)
-{
- struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
- struct i2c_board_info hdpvr_ir_rx_i2c_board_info = {
- I2C_BOARD_INFO("ir_rx_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR),
- };
-
- /* Our default information for ir-kbd-i2c.c to use */
- init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
- init_data->type = RC_TYPE_RC5;
- init_data->name = "HD-PVR";
- init_data->polling_interval = 405; /* ms, duplicated from Windows */
- hdpvr_ir_rx_i2c_board_info.platform_data = init_data;
-
- return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_rx_i2c_board_info);
-}
-
-static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,
- unsigned char addr, char *wdata, int wlen,
- char *data, int len)
-{
- int ret;
-
- if ((len > sizeof(dev->i2c_buf)) || (wlen > sizeof(dev->i2c_buf)))
- return -EINVAL;
-
- if (wlen) {
- memcpy(&dev->i2c_buf, wdata, wlen);
- ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
- REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
- (bus << 8) | addr, 0, &dev->i2c_buf,
- wlen, 1000);
- if (ret < 0)
- return ret;
- }
-
- ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
- REQTYPE_I2C_READ, CTRL_READ_REQUEST,
- (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
-
- if (ret == len) {
- memcpy(data, &dev->i2c_buf, len);
- ret = 0;
- } else if (ret >= 0)
- ret = -EIO;
-
- return ret;
-}
-
-static int hdpvr_i2c_write(struct hdpvr_device *dev, int bus,
- unsigned char addr, char *data, int len)
-{
- int ret;
-
- if (len > sizeof(dev->i2c_buf))
- return -EINVAL;
-
- memcpy(&dev->i2c_buf, data, len);
- ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
- REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
- (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
-
- if (ret < 0)
- return ret;
-
- ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
- REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST,
- 0, 0, &dev->i2c_buf, 2, 1000);
-
- if ((ret == 2) && (dev->i2c_buf[1] == (len - 1)))
- ret = 0;
- else if (ret >= 0)
- ret = -EIO;
-
- return ret;
-}
-
-static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs,
- int num)
-{
- struct hdpvr_device *dev = i2c_get_adapdata(i2c_adapter);
- int retval = 0, addr;
-
- if (num <= 0)
- return 0;
-
- mutex_lock(&dev->i2c_mutex);
-
- addr = msgs[0].addr << 1;
-
- if (num == 1) {
- if (msgs[0].flags & I2C_M_RD)
- retval = hdpvr_i2c_read(dev, 1, addr, NULL, 0,
- msgs[0].buf, msgs[0].len);
- else
- retval = hdpvr_i2c_write(dev, 1, addr, msgs[0].buf,
- msgs[0].len);
- } else if (num == 2) {
- if (msgs[0].addr != msgs[1].addr) {
- v4l2_warn(&dev->v4l2_dev, "refusing 2-phase i2c xfer "
- "with conflicting target addresses\n");
- retval = -EINVAL;
- goto out;
- }
-
- if ((msgs[0].flags & I2C_M_RD) || !(msgs[1].flags & I2C_M_RD)) {
- v4l2_warn(&dev->v4l2_dev, "refusing complex xfer with "
- "r0=%d, r1=%d\n", msgs[0].flags & I2C_M_RD,
- msgs[1].flags & I2C_M_RD);
- retval = -EINVAL;
- goto out;
- }
-
- /*
- * Write followed by atomic read is the only complex xfer that
- * we actually support here.
- */
- retval = hdpvr_i2c_read(dev, 1, addr, msgs[0].buf, msgs[0].len,
- msgs[1].buf, msgs[1].len);
- } else {
- v4l2_warn(&dev->v4l2_dev, "refusing %d-phase i2c xfer\n", num);
- }
-
-out:
- mutex_unlock(&dev->i2c_mutex);
-
- return retval ? retval : num;
-}
-
-static u32 hdpvr_functionality(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static struct i2c_algorithm hdpvr_algo = {
- .master_xfer = hdpvr_transfer,
- .functionality = hdpvr_functionality,
-};
-
-static struct i2c_adapter hdpvr_i2c_adapter_template = {
- .name = "Hauppage HD PVR I2C",
- .owner = THIS_MODULE,
- .algo = &hdpvr_algo,
-};
-
-static int hdpvr_activate_ir(struct hdpvr_device *dev)
-{
- char buffer[2];
-
- mutex_lock(&dev->i2c_mutex);
-
- hdpvr_i2c_read(dev, 0, 0x54, NULL, 0, buffer, 1);
-
- buffer[0] = 0;
- buffer[1] = 0x8;
- hdpvr_i2c_write(dev, 1, 0x54, buffer, 2);
-
- buffer[1] = 0x18;
- hdpvr_i2c_write(dev, 1, 0x54, buffer, 2);
-
- mutex_unlock(&dev->i2c_mutex);
-
- return 0;
-}
-
-int hdpvr_register_i2c_adapter(struct hdpvr_device *dev)
-{
- int retval = -ENOMEM;
-
- hdpvr_activate_ir(dev);
-
- memcpy(&dev->i2c_adapter, &hdpvr_i2c_adapter_template,
- sizeof(struct i2c_adapter));
- dev->i2c_adapter.dev.parent = &dev->udev->dev;
-
- i2c_set_adapdata(&dev->i2c_adapter, dev);
-
- retval = i2c_add_adapter(&dev->i2c_adapter);
-
- return retval;
-}
-
-#endif
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
deleted file mode 100644
index 0e9e156bb2a..00000000000
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ /dev/null
@@ -1,1289 +0,0 @@
-/*
- * Hauppauge HD PVR USB driver - video 4 linux 2 interface
- *
- * Copyright (C) 2008 Janne Grunau (j@jannau.net)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/uaccess.h>
-#include <linux/usb.h>
-#include <linux/mutex.h>
-#include <linux/workqueue.h>
-
-#include <linux/videodev2.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include "hdpvr.h"
-
-#define BULK_URB_TIMEOUT 90 /* 0.09 seconds */
-
-#define print_buffer_status() { \
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, \
- "%s:%d buffer stat: %d free, %d proc\n", \
- __func__, __LINE__, \
- list_size(&dev->free_buff_list), \
- list_size(&dev->rec_buff_list)); }
-
-struct hdpvr_fh {
- struct hdpvr_device *dev;
-};
-
-static uint list_size(struct list_head *list)
-{
- struct list_head *tmp;
- uint count = 0;
-
- list_for_each(tmp, list) {
- count++;
- }
-
- return count;
-}
-
-/*=========================================================================*/
-/* urb callback */
-static void hdpvr_read_bulk_callback(struct urb *urb)
-{
- struct hdpvr_buffer *buf = (struct hdpvr_buffer *)urb->context;
- struct hdpvr_device *dev = buf->dev;
-
- /* marking buffer as received and wake waiting */
- buf->status = BUFSTAT_READY;
- wake_up_interruptible(&dev->wait_data);
-}
-
-/*=========================================================================*/
-/* bufffer bits */
-
-/* function expects dev->io_mutex to be hold by caller */
-int hdpvr_cancel_queue(struct hdpvr_device *dev)
-{
- struct hdpvr_buffer *buf;
-
- list_for_each_entry(buf, &dev->rec_buff_list, buff_list) {
- usb_kill_urb(buf->urb);
- buf->status = BUFSTAT_AVAILABLE;
- }
-
- list_splice_init(&dev->rec_buff_list, dev->free_buff_list.prev);
-
- return 0;
-}
-
-static int hdpvr_free_queue(struct list_head *q)
-{
- struct list_head *tmp;
- struct list_head *p;
- struct hdpvr_buffer *buf;
- struct urb *urb;
-
- for (p = q->next; p != q;) {
- buf = list_entry(p, struct hdpvr_buffer, buff_list);
-
- urb = buf->urb;
- usb_free_coherent(urb->dev, urb->transfer_buffer_length,
- urb->transfer_buffer, urb->transfer_dma);
- usb_free_urb(urb);
- tmp = p->next;
- list_del(p);
- kfree(buf);
- p = tmp;
- }
-
- return 0;
-}
-
-/* function expects dev->io_mutex to be hold by caller */
-int hdpvr_free_buffers(struct hdpvr_device *dev)
-{
- hdpvr_cancel_queue(dev);
-
- hdpvr_free_queue(&dev->free_buff_list);
- hdpvr_free_queue(&dev->rec_buff_list);
-
- return 0;
-}
-
-/* function expects dev->io_mutex to be hold by caller */
-int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
-{
- uint i;
- int retval = -ENOMEM;
- u8 *mem;
- struct hdpvr_buffer *buf;
- struct urb *urb;
-
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "allocating %u buffers\n", count);
-
- for (i = 0; i < count; i++) {
-
- buf = kzalloc(sizeof(struct hdpvr_buffer), GFP_KERNEL);
- if (!buf) {
- v4l2_err(&dev->v4l2_dev, "cannot allocate buffer\n");
- goto exit;
- }
- buf->dev = dev;
-
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n");
- goto exit_urb;
- }
- buf->urb = urb;
-
- mem = usb_alloc_coherent(dev->udev, dev->bulk_in_size, GFP_KERNEL,
- &urb->transfer_dma);
- if (!mem) {
- v4l2_err(&dev->v4l2_dev,
- "cannot allocate usb transfer buffer\n");
- goto exit_urb_buffer;
- }
-
- usb_fill_bulk_urb(buf->urb, dev->udev,
- usb_rcvbulkpipe(dev->udev,
- dev->bulk_in_endpointAddr),
- mem, dev->bulk_in_size,
- hdpvr_read_bulk_callback, buf);
-
- buf->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- buf->status = BUFSTAT_AVAILABLE;
- list_add_tail(&buf->buff_list, &dev->free_buff_list);
- }
- return 0;
-exit_urb_buffer:
- usb_free_urb(urb);
-exit_urb:
- kfree(buf);
-exit:
- hdpvr_free_buffers(dev);
- return retval;
-}
-
-static int hdpvr_submit_buffers(struct hdpvr_device *dev)
-{
- struct hdpvr_buffer *buf;
- struct urb *urb;
- int ret = 0, err_count = 0;
-
- mutex_lock(&dev->io_mutex);
-
- while (dev->status == STATUS_STREAMING &&
- !list_empty(&dev->free_buff_list)) {
-
- buf = list_entry(dev->free_buff_list.next, struct hdpvr_buffer,
- buff_list);
- if (buf->status != BUFSTAT_AVAILABLE) {
- v4l2_err(&dev->v4l2_dev,
- "buffer not marked as available\n");
- ret = -EFAULT;
- goto err;
- }
-
- urb = buf->urb;
- urb->status = 0;
- urb->actual_length = 0;
- ret = usb_submit_urb(urb, GFP_KERNEL);
- if (ret) {
- v4l2_err(&dev->v4l2_dev,
- "usb_submit_urb in %s returned %d\n",
- __func__, ret);
- if (++err_count > 2)
- break;
- continue;
- }
- buf->status = BUFSTAT_INPROGRESS;
- list_move_tail(&buf->buff_list, &dev->rec_buff_list);
- }
-err:
- print_buffer_status();
- mutex_unlock(&dev->io_mutex);
- return ret;
-}
-
-static struct hdpvr_buffer *hdpvr_get_next_buffer(struct hdpvr_device *dev)
-{
- struct hdpvr_buffer *buf;
-
- mutex_lock(&dev->io_mutex);
-
- if (list_empty(&dev->rec_buff_list)) {
- mutex_unlock(&dev->io_mutex);
- return NULL;
- }
-
- buf = list_entry(dev->rec_buff_list.next, struct hdpvr_buffer,
- buff_list);
- mutex_unlock(&dev->io_mutex);
-
- return buf;
-}
-
-static void hdpvr_transmit_buffers(struct work_struct *work)
-{
- struct hdpvr_device *dev = container_of(work, struct hdpvr_device,
- worker);
-
- while (dev->status == STATUS_STREAMING) {
-
- if (hdpvr_submit_buffers(dev)) {
- v4l2_err(&dev->v4l2_dev, "couldn't submit buffers\n");
- goto error;
- }
- if (wait_event_interruptible(dev->wait_buffer,
- !list_empty(&dev->free_buff_list) ||
- dev->status != STATUS_STREAMING))
- goto error;
- }
-
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "transmit worker exited\n");
- return;
-error:
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "transmit buffers errored\n");
- dev->status = STATUS_ERROR;
-}
-
-/* function expects dev->io_mutex to be hold by caller */
-static int hdpvr_start_streaming(struct hdpvr_device *dev)
-{
- int ret;
- struct hdpvr_video_info *vidinf;
-
- if (dev->status == STATUS_STREAMING)
- return 0;
- else if (dev->status != STATUS_IDLE)
- return -EAGAIN;
-
- vidinf = get_video_info(dev);
-
- if (vidinf) {
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
- "video signal: %dx%d@%dhz\n", vidinf->width,
- vidinf->height, vidinf->fps);
- kfree(vidinf);
-
- /* start streaming 2 request */
- ret = usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- 0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
- "encoder start control request returned %d\n", ret);
-
- hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
-
- dev->status = STATUS_STREAMING;
-
- INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
- queue_work(dev->workqueue, &dev->worker);
-
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
- "streaming started\n");
-
- return 0;
- }
- msleep(250);
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "no video signal at input %d\n", dev->options.video_input);
- return -EAGAIN;
-}
-
-
-/* function expects dev->io_mutex to be hold by caller */
-static int hdpvr_stop_streaming(struct hdpvr_device *dev)
-{
- int actual_length;
- uint c = 0;
- u8 *buf;
-
- if (dev->status == STATUS_IDLE)
- return 0;
- else if (dev->status != STATUS_STREAMING)
- return -EAGAIN;
-
- buf = kmalloc(dev->bulk_in_size, GFP_KERNEL);
- if (!buf)
- v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer "
- "for emptying the internal device buffer. "
- "Next capture start will be slow\n");
-
- dev->status = STATUS_SHUTTING_DOWN;
- hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00);
- mutex_unlock(&dev->io_mutex);
-
- wake_up_interruptible(&dev->wait_buffer);
- msleep(50);
-
- flush_workqueue(dev->workqueue);
-
- mutex_lock(&dev->io_mutex);
- /* kill the still outstanding urbs */
- hdpvr_cancel_queue(dev);
-
- /* emptying the device buffer beforeshutting it down */
- while (buf && ++c < 500 &&
- !usb_bulk_msg(dev->udev,
- usb_rcvbulkpipe(dev->udev,
- dev->bulk_in_endpointAddr),
- buf, dev->bulk_in_size, &actual_length,
- BULK_URB_TIMEOUT)) {
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
- "%2d: got %d bytes\n", c, actual_length);
- }
- kfree(buf);
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
- "used %d urbs to empty device buffers\n", c-1);
- msleep(10);
-
- dev->status = STATUS_IDLE;
-
- return 0;
-}
-
-
-/*=======================================================================*/
-/*
- * video 4 linux 2 file operations
- */
-
-static int hdpvr_open(struct file *file)
-{
- struct hdpvr_device *dev;
- struct hdpvr_fh *fh;
- int retval = -ENOMEM;
-
- dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file));
- if (!dev) {
- pr_err("open failing with with ENODEV\n");
- retval = -ENODEV;
- goto err;
- }
-
- fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL);
- if (!fh) {
- v4l2_err(&dev->v4l2_dev, "Out of memory\n");
- goto err;
- }
- /* lock the device to allow correctly handling errors
- * in resumption */
- mutex_lock(&dev->io_mutex);
- dev->open_count++;
- mutex_unlock(&dev->io_mutex);
-
- fh->dev = dev;
-
- /* save our object in the file's private structure */
- file->private_data = fh;
-
- retval = 0;
-err:
- return retval;
-}
-
-static int hdpvr_release(struct file *file)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
-
- if (!dev)
- return -ENODEV;
-
- mutex_lock(&dev->io_mutex);
- if (!(--dev->open_count) && dev->status == STATUS_STREAMING)
- hdpvr_stop_streaming(dev);
-
- mutex_unlock(&dev->io_mutex);
-
- return 0;
-}
-
-/*
- * hdpvr_v4l2_read()
- * will allocate buffers when called for the first time
- */
-static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
- loff_t *pos)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
- struct hdpvr_buffer *buf = NULL;
- struct urb *urb;
- unsigned int ret = 0;
- int rem, cnt;
-
- if (*pos)
- return -ESPIPE;
-
- if (!dev)
- return -ENODEV;
-
- mutex_lock(&dev->io_mutex);
- if (dev->status == STATUS_IDLE) {
- if (hdpvr_start_streaming(dev)) {
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "start_streaming failed\n");
- ret = -EIO;
- msleep(200);
- dev->status = STATUS_IDLE;
- mutex_unlock(&dev->io_mutex);
- goto err;
- }
- print_buffer_status();
- }
- mutex_unlock(&dev->io_mutex);
-
- /* wait for the first buffer */
- if (!(file->f_flags & O_NONBLOCK)) {
- if (wait_event_interruptible(dev->wait_data,
- hdpvr_get_next_buffer(dev)))
- return -ERESTARTSYS;
- }
-
- buf = hdpvr_get_next_buffer(dev);
-
- while (count > 0 && buf) {
-
- if (buf->status != BUFSTAT_READY &&
- dev->status != STATUS_DISCONNECTED) {
- /* return nonblocking */
- if (file->f_flags & O_NONBLOCK) {
- if (!ret)
- ret = -EAGAIN;
- goto err;
- }
-
- if (wait_event_interruptible(dev->wait_data,
- buf->status == BUFSTAT_READY)) {
- ret = -ERESTARTSYS;
- goto err;
- }
- }
-
- if (buf->status != BUFSTAT_READY)
- break;
-
- /* set remaining bytes to copy */
- urb = buf->urb;
- rem = urb->actual_length - buf->pos;
- cnt = rem > count ? count : rem;
-
- if (copy_to_user(buffer, urb->transfer_buffer + buf->pos,
- cnt)) {
- v4l2_err(&dev->v4l2_dev, "read: copy_to_user failed\n");
- if (!ret)
- ret = -EFAULT;
- goto err;
- }
-
- buf->pos += cnt;
- count -= cnt;
- buffer += cnt;
- ret += cnt;
-
- /* finished, take next buffer */
- if (buf->pos == urb->actual_length) {
- mutex_lock(&dev->io_mutex);
- buf->pos = 0;
- buf->status = BUFSTAT_AVAILABLE;
-
- list_move_tail(&buf->buff_list, &dev->free_buff_list);
-
- print_buffer_status();
-
- mutex_unlock(&dev->io_mutex);
-
- wake_up_interruptible(&dev->wait_buffer);
-
- buf = hdpvr_get_next_buffer(dev);
- }
- }
-err:
- if (!ret && !buf)
- ret = -EAGAIN;
- return ret;
-}
-
-static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
-{
- struct hdpvr_buffer *buf = NULL;
- struct hdpvr_fh *fh = filp->private_data;
- struct hdpvr_device *dev = fh->dev;
- unsigned int mask = 0;
-
- mutex_lock(&dev->io_mutex);
-
- if (!video_is_registered(dev->video_dev)) {
- mutex_unlock(&dev->io_mutex);
- return -EIO;
- }
-
- if (dev->status == STATUS_IDLE) {
- if (hdpvr_start_streaming(dev)) {
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
- "start_streaming failed\n");
- dev->status = STATUS_IDLE;
- }
-
- print_buffer_status();
- }
- mutex_unlock(&dev->io_mutex);
-
- buf = hdpvr_get_next_buffer(dev);
- /* only wait if no data is available */
- if (!buf || buf->status != BUFSTAT_READY) {
- poll_wait(filp, &dev->wait_data, wait);
- buf = hdpvr_get_next_buffer(dev);
- }
- if (buf && buf->status == BUFSTAT_READY)
- mask |= POLLIN | POLLRDNORM;
-
- return mask;
-}
-
-
-static const struct v4l2_file_operations hdpvr_fops = {
- .owner = THIS_MODULE,
- .open = hdpvr_open,
- .release = hdpvr_release,
- .read = hdpvr_read,
- .poll = hdpvr_poll,
- .unlocked_ioctl = video_ioctl2,
-};
-
-/*=======================================================================*/
-/*
- * V4L2 ioctl handling
- */
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct hdpvr_device *dev = video_drvdata(file);
-
- strcpy(cap->driver, "hdpvr");
- strcpy(cap->card, "Hauppauge HD PVR");
- usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_AUDIO |
- V4L2_CAP_READWRITE;
- return 0;
-}
-
-static int vidioc_s_std(struct file *file, void *private_data,
- v4l2_std_id *std)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
- u8 std_type = 1;
-
- if (*std & (V4L2_STD_NTSC | V4L2_STD_PAL_60))
- std_type = 0;
-
- return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type);
-}
-
-static const char *iname[] = {
- [HDPVR_COMPONENT] = "Component",
- [HDPVR_SVIDEO] = "S-Video",
- [HDPVR_COMPOSITE] = "Composite",
-};
-
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
- unsigned int n;
-
- n = i->index;
- if (n >= HDPVR_VIDEO_INPUTS)
- return -EINVAL;
-
- i->type = V4L2_INPUT_TYPE_CAMERA;
-
- strncpy(i->name, iname[n], sizeof(i->name) - 1);
- i->name[sizeof(i->name) - 1] = '\0';
-
- i->audioset = 1<<HDPVR_RCA_FRONT | 1<<HDPVR_RCA_BACK | 1<<HDPVR_SPDIF;
-
- i->std = dev->video_dev->tvnorms;
-
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *private_data,
- unsigned int index)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
- int retval;
-
- if (index >= HDPVR_VIDEO_INPUTS)
- return -EINVAL;
-
- if (dev->status != STATUS_IDLE)
- return -EAGAIN;
-
- retval = hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, index+1);
- if (!retval)
- dev->options.video_input = index;
-
- return retval;
-}
-
-static int vidioc_g_input(struct file *file, void *private_data,
- unsigned int *index)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
-
- *index = dev->options.video_input;
- return 0;
-}
-
-
-static const char *audio_iname[] = {
- [HDPVR_RCA_FRONT] = "RCA front",
- [HDPVR_RCA_BACK] = "RCA back",
- [HDPVR_SPDIF] = "SPDIF",
-};
-
-static int vidioc_enumaudio(struct file *file, void *priv,
- struct v4l2_audio *audio)
-{
- unsigned int n;
-
- n = audio->index;
- if (n >= HDPVR_AUDIO_INPUTS)
- return -EINVAL;
-
- audio->capability = V4L2_AUDCAP_STEREO;
-
- strncpy(audio->name, audio_iname[n], sizeof(audio->name) - 1);
- audio->name[sizeof(audio->name) - 1] = '\0';
-
- return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *private_data,
- struct v4l2_audio *audio)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
- int retval;
-
- if (audio->index >= HDPVR_AUDIO_INPUTS)
- return -EINVAL;
-
- if (dev->status != STATUS_IDLE)
- return -EAGAIN;
-
- retval = hdpvr_set_audio(dev, audio->index+1, dev->options.audio_codec);
- if (!retval)
- dev->options.audio_input = audio->index;
-
- return retval;
-}
-
-static int vidioc_g_audio(struct file *file, void *private_data,
- struct v4l2_audio *audio)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
-
- audio->index = dev->options.audio_input;
- audio->capability = V4L2_AUDCAP_STEREO;
- strncpy(audio->name, audio_iname[audio->index], sizeof(audio->name));
- audio->name[sizeof(audio->name) - 1] = '\0';
- return 0;
-}
-
-static const s32 supported_v4l2_ctrls[] = {
- V4L2_CID_BRIGHTNESS,
- V4L2_CID_CONTRAST,
- V4L2_CID_SATURATION,
- V4L2_CID_HUE,
- V4L2_CID_SHARPNESS,
- V4L2_CID_MPEG_AUDIO_ENCODING,
- V4L2_CID_MPEG_VIDEO_ENCODING,
- V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
- V4L2_CID_MPEG_VIDEO_BITRATE,
- V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
-};
-
-static int fill_queryctrl(struct hdpvr_options *opt, struct v4l2_queryctrl *qc,
- int ac3, int fw_ver)
-{
- int err;
-
- if (fw_ver > 0x15) {
- switch (qc->id) {
- case V4L2_CID_BRIGHTNESS:
- return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
- case V4L2_CID_CONTRAST:
- return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x40);
- case V4L2_CID_SATURATION:
- return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x40);
- case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill(qc, 0x0, 0x1e, 1, 0xf);
- case V4L2_CID_SHARPNESS:
- return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
- }
- } else {
- switch (qc->id) {
- case V4L2_CID_BRIGHTNESS:
- return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86);
- case V4L2_CID_CONTRAST:
- return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
- case V4L2_CID_SATURATION:
- return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
- case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
- case V4L2_CID_SHARPNESS:
- return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
- }
- }
-
- switch (qc->id) {
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- return v4l2_ctrl_query_fill(
- qc, V4L2_MPEG_AUDIO_ENCODING_AAC,
- ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3
- : V4L2_MPEG_AUDIO_ENCODING_AAC,
- 1, V4L2_MPEG_AUDIO_ENCODING_AAC);
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- return v4l2_ctrl_query_fill(
- qc, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC);
-
-/* case V4L2_CID_MPEG_VIDEO_? maybe keyframe interval: */
-/* return v4l2_ctrl_query_fill(qc, 0, 128, 128, 0); */
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- return v4l2_ctrl_query_fill(
- qc, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
-
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- return v4l2_ctrl_query_fill(qc, 1000000, 13500000, 100000,
- 6500000);
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- err = v4l2_ctrl_query_fill(qc, 1100000, 20200000, 100000,
- 9000000);
- if (!err && opt->bitrate_mode == HDPVR_CONSTANT)
- qc->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return err;
- default:
- return -EINVAL;
- }
-}
-
-static int vidioc_queryctrl(struct file *file, void *private_data,
- struct v4l2_queryctrl *qc)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
- int i, next;
- u32 id = qc->id;
-
- memset(qc, 0, sizeof(*qc));
-
- next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
- qc->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
-
- for (i = 0; i < ARRAY_SIZE(supported_v4l2_ctrls); i++) {
- if (next) {
- if (qc->id < supported_v4l2_ctrls[i])
- qc->id = supported_v4l2_ctrls[i];
- else
- continue;
- }
-
- if (qc->id == supported_v4l2_ctrls[i])
- return fill_queryctrl(&dev->options, qc,
- dev->flags & HDPVR_FLAG_AC3_CAP,
- dev->fw_ver);
-
- if (qc->id < supported_v4l2_ctrls[i])
- break;
- }
-
- return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *private_data,
- struct v4l2_control *ctrl)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- ctrl->value = dev->options.brightness;
- break;
- case V4L2_CID_CONTRAST:
- ctrl->value = dev->options.contrast;
- break;
- case V4L2_CID_SATURATION:
- ctrl->value = dev->options.saturation;
- break;
- case V4L2_CID_HUE:
- ctrl->value = dev->options.hue;
- break;
- case V4L2_CID_SHARPNESS:
- ctrl->value = dev->options.sharpness;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *private_data,
- struct v4l2_control *ctrl)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
- int retval;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- retval = hdpvr_config_call(dev, CTRL_BRIGHTNESS, ctrl->value);
- if (!retval)
- dev->options.brightness = ctrl->value;
- break;
- case V4L2_CID_CONTRAST:
- retval = hdpvr_config_call(dev, CTRL_CONTRAST, ctrl->value);
- if (!retval)
- dev->options.contrast = ctrl->value;
- break;
- case V4L2_CID_SATURATION:
- retval = hdpvr_config_call(dev, CTRL_SATURATION, ctrl->value);
- if (!retval)
- dev->options.saturation = ctrl->value;
- break;
- case V4L2_CID_HUE:
- retval = hdpvr_config_call(dev, CTRL_HUE, ctrl->value);
- if (!retval)
- dev->options.hue = ctrl->value;
- break;
- case V4L2_CID_SHARPNESS:
- retval = hdpvr_config_call(dev, CTRL_SHARPNESS, ctrl->value);
- if (!retval)
- dev->options.sharpness = ctrl->value;
- break;
- default:
- return -EINVAL;
- }
-
- return retval;
-}
-
-
-static int hdpvr_get_ctrl(struct hdpvr_options *opt,
- struct v4l2_ext_control *ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- ctrl->value = opt->audio_codec;
- break;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC;
- break;
-/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
-/* ctrl->value = (opt->gop_mode & 0x2) ? 0 : 128; */
-/* break; */
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- ctrl->value = opt->bitrate_mode == HDPVR_CONSTANT
- ? V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
- : V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- ctrl->value = opt->bitrate * 100000;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- ctrl->value = opt->peak_bitrate * 100000;
- break;
- case V4L2_CID_MPEG_STREAM_TYPE:
- ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int vidioc_g_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = hdpvr_get_ctrl(&dev->options, ctrl);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
-
- }
-
- return -EINVAL;
-}
-
-
-static int hdpvr_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
-{
- int ret = -EINVAL;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- if (ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AAC ||
- (ac3 && ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AC3))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- if (ctrl->value == V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC)
- ret = 0;
- break;
-/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
-/* if (ctrl->value == 0 || ctrl->value == 128) */
-/* ret = 0; */
-/* break; */
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR ||
- ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- {
- uint bitrate = ctrl->value / 100000;
- if (bitrate >= 10 && bitrate <= 135)
- ret = 0;
- break;
- }
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- {
- uint peak_bitrate = ctrl->value / 100000;
- if (peak_bitrate >= 10 && peak_bitrate <= 202)
- ret = 0;
- break;
- }
- case V4L2_CID_MPEG_STREAM_TYPE:
- if (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)
- ret = 0;
- break;
- default:
- return -EINVAL;
- }
- return ret;
-}
-
-static int vidioc_try_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = hdpvr_try_ctrl(ctrl,
- dev->flags & HDPVR_FLAG_AC3_CAP);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
- }
-
- return -EINVAL;
-}
-
-
-static int hdpvr_set_ctrl(struct hdpvr_device *dev,
- struct v4l2_ext_control *ctrl)
-{
- struct hdpvr_options *opt = &dev->options;
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- if (dev->flags & HDPVR_FLAG_AC3_CAP) {
- opt->audio_codec = ctrl->value;
- ret = hdpvr_set_audio(dev, opt->audio_input,
- opt->audio_codec);
- }
- break;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- break;
-/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
-/* if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */
-/* opt->gop_mode |= 0x2; */
-/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
-/* opt->gop_mode); */
-/* } */
-/* if (ctrl->value == 128 && opt->gop_mode & 0x2) { */
-/* opt->gop_mode &= ~0x2; */
-/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
-/* opt->gop_mode); */
-/* } */
-/* break; */
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR &&
- opt->bitrate_mode != HDPVR_CONSTANT) {
- opt->bitrate_mode = HDPVR_CONSTANT;
- hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
- opt->bitrate_mode);
- }
- if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
- opt->bitrate_mode == HDPVR_CONSTANT) {
- opt->bitrate_mode = HDPVR_VARIABLE_AVERAGE;
- hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
- opt->bitrate_mode);
- }
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE: {
- uint bitrate = ctrl->value / 100000;
-
- opt->bitrate = bitrate;
- if (bitrate >= opt->peak_bitrate)
- opt->peak_bitrate = bitrate+1;
-
- hdpvr_set_bitrate(dev);
- break;
- }
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: {
- uint peak_bitrate = ctrl->value / 100000;
-
- if (opt->bitrate_mode == HDPVR_CONSTANT)
- break;
-
- if (opt->bitrate < peak_bitrate) {
- opt->peak_bitrate = peak_bitrate;
- hdpvr_set_bitrate(dev);
- } else
- ret = -EINVAL;
- break;
- }
- case V4L2_CID_MPEG_STREAM_TYPE:
- break;
- default:
- return -EINVAL;
- }
- return ret;
-}
-
-static int vidioc_s_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = hdpvr_try_ctrl(ctrl,
- dev->flags & HDPVR_FLAG_AC3_CAP);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- err = hdpvr_set_ctrl(dev, ctrl);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
-
- }
-
- return -EINVAL;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data,
- struct v4l2_fmtdesc *f)
-{
-
- if (f->index != 0 || f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- f->flags = V4L2_FMT_FLAG_COMPRESSED;
- strncpy(f->description, "MPEG2-TS with AVC/AAC streams", 32);
- f->pixelformat = V4L2_PIX_FMT_MPEG;
-
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *private_data,
- struct v4l2_format *f)
-{
- struct hdpvr_fh *fh = file->private_data;
- struct hdpvr_device *dev = fh->dev;
- struct hdpvr_video_info *vid_info;
-
- if (!dev)
- return -ENODEV;
-
- vid_info = get_video_info(dev);
- if (!vid_info)
- return -EFAULT;
-
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.width = vid_info->width;
- f->fmt.pix.height = vid_info->height;
- f->fmt.pix.sizeimage = dev->bulk_in_size;
- f->fmt.pix.colorspace = 0;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.field = V4L2_FIELD_ANY;
-
- kfree(vid_info);
- return 0;
-}
-
-static int vidioc_encoder_cmd(struct file *filp, void *priv,
- struct v4l2_encoder_cmd *a)
-{
- struct hdpvr_fh *fh = filp->private_data;
- struct hdpvr_device *dev = fh->dev;
- int res;
-
- mutex_lock(&dev->io_mutex);
-
- memset(&a->raw, 0, sizeof(a->raw));
- switch (a->cmd) {
- case V4L2_ENC_CMD_START:
- a->flags = 0;
- res = hdpvr_start_streaming(dev);
- break;
- case V4L2_ENC_CMD_STOP:
- res = hdpvr_stop_streaming(dev);
- break;
- default:
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "Unsupported encoder cmd %d\n", a->cmd);
- res = -EINVAL;
- }
- mutex_unlock(&dev->io_mutex);
- return res;
-}
-
-static int vidioc_try_encoder_cmd(struct file *filp, void *priv,
- struct v4l2_encoder_cmd *a)
-{
- switch (a->cmd) {
- case V4L2_ENC_CMD_START:
- case V4L2_ENC_CMD_STOP:
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static const struct v4l2_ioctl_ops hdpvr_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_enumaudio = vidioc_enumaudio,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
- .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
- .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_encoder_cmd = vidioc_encoder_cmd,
- .vidioc_try_encoder_cmd = vidioc_try_encoder_cmd,
-};
-
-static void hdpvr_device_release(struct video_device *vdev)
-{
- struct hdpvr_device *dev = video_get_drvdata(vdev);
-
- hdpvr_delete(dev);
- mutex_lock(&dev->io_mutex);
- destroy_workqueue(dev->workqueue);
- mutex_unlock(&dev->io_mutex);
-
- v4l2_device_unregister(&dev->v4l2_dev);
-
- /* deregister I2C adapter */
-#if defined(CONFIG_I2C) || (CONFIG_I2C_MODULE)
- mutex_lock(&dev->i2c_mutex);
- i2c_del_adapter(&dev->i2c_adapter);
- mutex_unlock(&dev->i2c_mutex);
-#endif /* CONFIG_I2C */
-
- kfree(dev->usbc_buf);
- kfree(dev);
-}
-
-static const struct video_device hdpvr_video_template = {
-/* .type = VFL_TYPE_GRABBER, */
-/* .type2 = VID_TYPE_CAPTURE | VID_TYPE_MPEG_ENCODER, */
- .fops = &hdpvr_fops,
- .release = hdpvr_device_release,
- .ioctl_ops = &hdpvr_ioctl_ops,
- .tvnorms =
- V4L2_STD_NTSC | V4L2_STD_SECAM | V4L2_STD_PAL_B |
- V4L2_STD_PAL_G | V4L2_STD_PAL_H | V4L2_STD_PAL_I |
- V4L2_STD_PAL_D | V4L2_STD_PAL_M | V4L2_STD_PAL_N |
- V4L2_STD_PAL_60,
- .current_norm = V4L2_STD_NTSC | V4L2_STD_PAL_M |
- V4L2_STD_PAL_60,
-};
-
-int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
- int devnum)
-{
- /* setup and register video device */
- dev->video_dev = video_device_alloc();
- if (!dev->video_dev) {
- v4l2_err(&dev->v4l2_dev, "video_device_alloc() failed\n");
- goto error;
- }
-
- *(dev->video_dev) = hdpvr_video_template;
- strcpy(dev->video_dev->name, "Hauppauge HD PVR");
- dev->video_dev->parent = parent;
- video_set_drvdata(dev->video_dev, dev);
-
- if (video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum)) {
- v4l2_err(&dev->v4l2_dev, "video_device registration failed\n");
- goto error;
- }
-
- return 0;
-error:
- return -ENOMEM;
-}
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
deleted file mode 100644
index fea3c692699..00000000000
--- a/drivers/media/video/hdpvr/hdpvr.h
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Hauppauge HD PVR USB driver
- *
- * Copyright (C) 2008 Janne Grunau (j@jannau.net)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <linux/workqueue.h>
-#include <linux/videodev2.h>
-
-#include <media/v4l2-device.h>
-#include <media/ir-kbd-i2c.h>
-
-#define HDPVR_MAX 8
-#define HDPVR_I2C_MAX_SIZE 128
-
-/* Define these values to match your devices */
-#define HD_PVR_VENDOR_ID 0x2040
-#define HD_PVR_PRODUCT_ID 0x4900
-#define HD_PVR_PRODUCT_ID1 0x4901
-#define HD_PVR_PRODUCT_ID2 0x4902
-#define HD_PVR_PRODUCT_ID4 0x4903
-#define HD_PVR_PRODUCT_ID3 0x4982
-
-#define UNSET (-1U)
-
-#define NUM_BUFFERS 64
-
-#define HDPVR_FIRMWARE_VERSION 0x08
-#define HDPVR_FIRMWARE_VERSION_AC3 0x0d
-#define HDPVR_FIRMWARE_VERSION_0X12 0x12
-#define HDPVR_FIRMWARE_VERSION_0X15 0x15
-
-/* #define HDPVR_DEBUG */
-
-extern int hdpvr_debug;
-
-#define MSG_INFO 1
-#define MSG_BUFFER 2
-
-struct hdpvr_options {
- u8 video_std;
- u8 video_input;
- u8 audio_input;
- u8 bitrate; /* in 100kbps */
- u8 peak_bitrate; /* in 100kbps */
- u8 bitrate_mode;
- u8 gop_mode;
- enum v4l2_mpeg_audio_encoding audio_codec;
- u8 brightness;
- u8 contrast;
- u8 hue;
- u8 saturation;
- u8 sharpness;
-};
-
-/* Structure to hold all of our device specific stuff */
-struct hdpvr_device {
- /* the v4l device for this device */
- struct video_device *video_dev;
- /* the usb device for this device */
- struct usb_device *udev;
- /* v4l2-device unused */
- struct v4l2_device v4l2_dev;
-
- /* the max packet size of the bulk endpoint */
- size_t bulk_in_size;
- /* the address of the bulk in endpoint */
- __u8 bulk_in_endpointAddr;
-
- /* holds the current device status */
- __u8 status;
- /* count the number of openers */
- uint open_count;
-
- /* holds the cureent set options */
- struct hdpvr_options options;
-
- uint flags;
-
- /* synchronize I/O */
- struct mutex io_mutex;
- /* available buffers */
- struct list_head free_buff_list;
- /* in progress buffers */
- struct list_head rec_buff_list;
- /* waitqueue for buffers */
- wait_queue_head_t wait_buffer;
- /* waitqueue for data */
- wait_queue_head_t wait_data;
- /**/
- struct workqueue_struct *workqueue;
- /**/
- struct work_struct worker;
-
- /* I2C adapter */
- struct i2c_adapter i2c_adapter;
- /* I2C lock */
- struct mutex i2c_mutex;
- /* I2C message buffer space */
- char i2c_buf[HDPVR_I2C_MAX_SIZE];
-
- /* For passing data to ir-kbd-i2c */
- struct IR_i2c_init_data ir_i2c_init_data;
-
- /* usb control transfer buffer and lock */
- struct mutex usbc_mutex;
- u8 *usbc_buf;
- u8 fw_ver;
-};
-
-static inline struct hdpvr_device *to_hdpvr_dev(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct hdpvr_device, v4l2_dev);
-}
-
-
-/* buffer one bulk urb of data */
-struct hdpvr_buffer {
- struct list_head buff_list;
-
- struct urb *urb;
-
- struct hdpvr_device *dev;
-
- uint pos;
-
- __u8 status;
-};
-
-/* */
-
-struct hdpvr_video_info {
- u16 width;
- u16 height;
- u8 fps;
-};
-
-enum {
- STATUS_UNINITIALIZED = 0,
- STATUS_IDLE,
- STATUS_STARTING,
- STATUS_SHUTTING_DOWN,
- STATUS_STREAMING,
- STATUS_ERROR,
- STATUS_DISCONNECTED,
-};
-
-enum {
- HDPVR_FLAG_AC3_CAP = 1,
-};
-
-enum {
- BUFSTAT_UNINITIALIZED = 0,
- BUFSTAT_AVAILABLE,
- BUFSTAT_INPROGRESS,
- BUFSTAT_READY,
-};
-
-#define CTRL_START_STREAMING_VALUE 0x0700
-#define CTRL_STOP_STREAMING_VALUE 0x0800
-#define CTRL_BITRATE_VALUE 0x1000
-#define CTRL_BITRATE_MODE_VALUE 0x1200
-#define CTRL_GOP_MODE_VALUE 0x1300
-#define CTRL_VIDEO_INPUT_VALUE 0x1500
-#define CTRL_VIDEO_STD_TYPE 0x1700
-#define CTRL_AUDIO_INPUT_VALUE 0x2500
-#define CTRL_BRIGHTNESS 0x2900
-#define CTRL_CONTRAST 0x2a00
-#define CTRL_HUE 0x2b00
-#define CTRL_SATURATION 0x2c00
-#define CTRL_SHARPNESS 0x2d00
-#define CTRL_LOW_PASS_FILTER_VALUE 0x3100
-
-#define CTRL_DEFAULT_INDEX 0x0003
-
-
- /* :0 s 38 01 1000 0003 0004 4 = 0a00ca00
- * BITRATE SETTING
- * 1st and 2nd byte (little endian): average bitrate in 100 000 bit/s
- * min: 1 mbit/s, max: 13.5 mbit/s
- * 3rd and 4th byte (little endian): peak bitrate in 100 000 bit/s
- * min: average + 100kbit/s,
- * max: 20.2 mbit/s
- */
-
- /* :0 s 38 01 1200 0003 0001 1 = 02
- * BIT RATE MODE
- * constant = 1, variable (peak) = 2, variable (average) = 3
- */
-
- /* :0 s 38 01 1300 0003 0001 1 = 03
- * GOP MODE (2 bit)
- * low bit 0/1: advanced/simple GOP
- * high bit 0/1: IDR(4/32/128) / no IDR (4/32/0)
- */
-
- /* :0 s 38 01 1700 0003 0001 1 = 00
- * VIDEO STANDARD or FREQUNCY 0 = 60hz, 1 = 50hz
- */
-
- /* :0 s 38 01 3100 0003 0004 4 = 03030000
- * FILTER CONTROL
- * 1st byte luma low pass filter strength,
- * 2nd byte chroma low pass filter strength,
- * 3rd byte MF enable chroma, min=0, max=1
- * 4th byte n
- */
-
-
- /* :0 s 38 b9 0001 0000 0000 0 */
-
-
-
-/* :0 s 38 d3 0000 0000 0001 1 = 00 */
-/* ret = usb_control_msg(dev->udev, */
-/* usb_sndctrlpipe(dev->udev, 0), */
-/* 0xd3, 0x38, */
-/* 0, 0, */
-/* "\0", 1, */
-/* 1000); */
-
-/* info("control request returned %d", ret); */
-/* msleep(5000); */
-
-
- /* :0 s b8 81 1400 0003 0005 5 <
- * :0 0 5 = d0024002 19
- * QUERY FRAME SIZE AND RATE
- * 1st and 2nd byte (little endian): horizontal resolution
- * 3rd and 4th byte (little endian): vertical resolution
- * 5th byte: frame rate
- */
-
- /* :0 s b8 81 1800 0003 0003 3 <
- * :0 0 3 = 030104
- * QUERY SIGNAL AND DETECTED LINES, maybe INPUT
- */
-
-enum hdpvr_video_std {
- HDPVR_60HZ = 0,
- HDPVR_50HZ,
-};
-
-enum hdpvr_video_input {
- HDPVR_COMPONENT = 0,
- HDPVR_SVIDEO,
- HDPVR_COMPOSITE,
- HDPVR_VIDEO_INPUTS
-};
-
-enum hdpvr_audio_inputs {
- HDPVR_RCA_BACK = 0,
- HDPVR_RCA_FRONT,
- HDPVR_SPDIF,
- HDPVR_AUDIO_INPUTS
-};
-
-enum hdpvr_bitrate_mode {
- HDPVR_CONSTANT = 1,
- HDPVR_VARIABLE_PEAK,
- HDPVR_VARIABLE_AVERAGE,
-};
-
-enum hdpvr_gop_mode {
- HDPVR_ADVANCED_IDR_GOP = 0,
- HDPVR_SIMPLE_IDR_GOP,
- HDPVR_ADVANCED_NOIDR_GOP,
- HDPVR_SIMPLE_NOIDR_GOP,
-};
-
-void hdpvr_delete(struct hdpvr_device *dev);
-
-/*========================================================================*/
-/* hardware control functions */
-int hdpvr_set_options(struct hdpvr_device *dev);
-
-int hdpvr_set_bitrate(struct hdpvr_device *dev);
-
-int hdpvr_set_audio(struct hdpvr_device *dev, u8 input,
- enum v4l2_mpeg_audio_encoding codec);
-
-int hdpvr_config_call(struct hdpvr_device *dev, uint value,
- unsigned char valbuf);
-
-struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev);
-
-/* :0 s b8 81 1800 0003 0003 3 < */
-/* :0 0 3 = 0301ff */
-int get_input_lines_info(struct hdpvr_device *dev);
-
-
-/*========================================================================*/
-/* v4l2 registration */
-int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
- int devnumber);
-
-int hdpvr_cancel_queue(struct hdpvr_device *dev);
-
-/*========================================================================*/
-/* i2c adapter registration */
-int hdpvr_register_i2c_adapter(struct hdpvr_device *dev);
-
-struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev);
-struct i2c_client *hdpvr_register_ir_tx_i2c(struct hdpvr_device *dev);
-
-/*========================================================================*/
-/* buffer management */
-int hdpvr_free_buffers(struct hdpvr_device *dev);
-int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count);
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
deleted file mode 100644
index 366434f5647..00000000000
--- a/drivers/media/video/hexium_gemini.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- hexium_gemini.c - v4l2 driver for Hexium Gemini frame grabber cards
-
- Visit http://www.mihu.de/linux/saa7146/ and follow the link
- to "hexium" for further details about this card.
-
- Copyright (C) 2003 Michael Hunold <michael@mihu.de>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define DEBUG_VARIABLE debug
-
-#include <media/saa7146_vv.h>
-#include <linux/module.h>
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "debug verbosity");
-
-/* global variables */
-static int hexium_num;
-
-#define HEXIUM_GEMINI 4
-#define HEXIUM_GEMINI_DUAL 5
-
-#define HEXIUM_INPUTS 9
-static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = {
- { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
-};
-
-#define HEXIUM_AUDIOS 0
-
-struct hexium_data
-{
- s8 adr;
- u8 byte;
-};
-
-#define HEXIUM_GEMINI_V_1_0 1
-#define HEXIUM_GEMINI_DUAL_V_1_0 2
-
-struct hexium
-{
- int type;
-
- struct video_device *video_dev;
- struct i2c_adapter i2c_adapter;
-
- int cur_input; /* current input */
- v4l2_std_id cur_std; /* current standard */
-};
-
-/* Samsung KS0127B decoder default registers */
-static u8 hexium_ks0127b[0x100]={
-/*00*/ 0x00,0x52,0x30,0x40,0x01,0x0C,0x2A,0x10,
-/*08*/ 0x00,0x00,0x00,0x60,0x00,0x00,0x0F,0x06,
-/*10*/ 0x00,0x00,0xE4,0xC0,0x00,0x00,0x00,0x00,
-/*18*/ 0x14,0x9B,0xFE,0xFF,0xFC,0xFF,0x03,0x22,
-/*20*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*28*/ 0x00,0x00,0x00,0x00,0x00,0x2C,0x9B,0x00,
-/*30*/ 0x00,0x00,0x10,0x80,0x80,0x10,0x80,0x80,
-/*38*/ 0x01,0x04,0x00,0x00,0x00,0x29,0xC0,0x00,
-/*40*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*48*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*50*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*58*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*60*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*68*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*70*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*78*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*80*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*88*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*90*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*98*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*A0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*A8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*B0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*B8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*C0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*C8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*D0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*D8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*E0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*E8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*F0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*F8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-};
-
-static struct hexium_data hexium_pal[] = {
- { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
-};
-
-static struct hexium_data hexium_ntsc[] = {
- { 0x01, 0x53 }, { 0x12, 0x04 }, { 0x2D, 0x23 }, { 0x2E, 0x81 }, { -1 , 0xFF }
-};
-
-static struct hexium_data hexium_secam[] = {
- { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
-};
-
-static struct hexium_data hexium_input_select[] = {
- { 0x02, 0x60 },
- { 0x02, 0x64 },
- { 0x02, 0x61 },
- { 0x02, 0x65 },
- { 0x02, 0x62 },
- { 0x02, 0x66 },
- { 0x02, 0x68 },
- { 0x02, 0x69 },
- { 0x02, 0x6A },
-};
-
-/* fixme: h_offset = 0 for Hexium Gemini *Dual*, which
- are currently *not* supported*/
-static struct saa7146_standard hexium_standards[] = {
- {
- .name = "PAL", .id = V4L2_STD_PAL,
- .v_offset = 28, .v_field = 288,
- .h_offset = 1, .h_pixels = 680,
- .v_max_out = 576, .h_max_out = 768,
- }, {
- .name = "NTSC", .id = V4L2_STD_NTSC,
- .v_offset = 28, .v_field = 240,
- .h_offset = 1, .h_pixels = 640,
- .v_max_out = 480, .h_max_out = 640,
- }, {
- .name = "SECAM", .id = V4L2_STD_SECAM,
- .v_offset = 28, .v_field = 288,
- .h_offset = 1, .h_pixels = 720,
- .v_max_out = 576, .h_max_out = 768,
- }
-};
-
-/* bring hardware to a sane state. this has to be done, just in case someone
- wants to capture from this device before it has been properly initialized.
- the capture engine would badly fail, because no valid signal arrives on the
- saa7146, thus leading to timeouts and stuff. */
-static int hexium_init_done(struct saa7146_dev *dev)
-{
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
- union i2c_smbus_data data;
- int i = 0;
-
- DEB_D("hexium_init_done called\n");
-
- /* initialize the helper ics to useful values */
- for (i = 0; i < sizeof(hexium_ks0127b); i++) {
- data.byte = hexium_ks0127b[i];
- if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, i, I2C_SMBUS_BYTE_DATA, &data)) {
- pr_err("hexium_init_done() failed for address 0x%02x\n",
- i);
- }
- }
-
- return 0;
-}
-
-static int hexium_set_input(struct hexium *hexium, int input)
-{
- union i2c_smbus_data data;
-
- DEB_D("\n");
-
- data.byte = hexium_input_select[input].byte;
- if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, hexium_input_select[input].adr, I2C_SMBUS_BYTE_DATA, &data)) {
- return -1;
- }
-
- return 0;
-}
-
-static int hexium_set_standard(struct hexium *hexium, struct hexium_data *vdec)
-{
- union i2c_smbus_data data;
- int i = 0;
-
- DEB_D("\n");
-
- while (vdec[i].adr != -1) {
- data.byte = vdec[i].byte;
- if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, vdec[i].adr, I2C_SMBUS_BYTE_DATA, &data)) {
- pr_err("hexium_init_done: hexium_set_standard() failed for address 0x%02x\n",
- i);
- return -1;
- }
- i++;
- }
- return 0;
-}
-
-static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
-{
- DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index);
-
- if (i->index >= HEXIUM_INPUTS)
- return -EINVAL;
-
- memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-
- DEB_D("v4l2_ioctl: VIDIOC_ENUMINPUT %d\n", i->index);
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
-
- *input = hexium->cur_input;
-
- DEB_D("VIDIOC_G_INPUT: %d\n", *input);
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
-
- DEB_EE("VIDIOC_S_INPUT %d\n", input);
-
- if (input >= HEXIUM_INPUTS)
- return -EINVAL;
-
- hexium->cur_input = input;
- hexium_set_input(hexium, input);
- return 0;
-}
-
-static struct saa7146_ext_vv vv_data;
-
-/* this function only gets called when the probing was successful */
-static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
-{
- struct hexium *hexium;
- int ret;
-
- DEB_EE("\n");
-
- hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
- if (NULL == hexium) {
- pr_err("not enough kernel memory in hexium_attach()\n");
- return -ENOMEM;
- }
- dev->ext_priv = hexium;
-
- /* enable i2c-port pins */
- saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
-
- hexium->i2c_adapter = (struct i2c_adapter) {
- .name = "hexium gemini",
- };
- saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
- if (i2c_add_adapter(&hexium->i2c_adapter) < 0) {
- DEB_S("cannot register i2c-device. skipping.\n");
- kfree(hexium);
- return -EFAULT;
- }
-
- /* set HWControl GPIO number 2 */
- saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
-
- saa7146_write(dev, DD1_INIT, 0x07000700);
- saa7146_write(dev, DD1_STREAM_B, 0x00000000);
- saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-
- /* the rest */
- hexium->cur_input = 0;
- hexium_init_done(dev);
-
- hexium_set_standard(hexium, hexium_pal);
- hexium->cur_std = V4L2_STD_PAL;
-
- hexium_set_input(hexium, 0);
- hexium->cur_input = 0;
-
- saa7146_vv_init(dev, &vv_data);
-
- vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
- vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
- vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
- ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER);
- if (ret < 0) {
- pr_err("cannot register capture v4l2 device. skipping.\n");
- return ret;
- }
-
- pr_info("found 'hexium gemini' frame grabber-%d\n", hexium_num);
- hexium_num++;
-
- return 0;
-}
-
-static int hexium_detach(struct saa7146_dev *dev)
-{
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
-
- DEB_EE("dev:%p\n", dev);
-
- saa7146_unregister_device(&hexium->video_dev, dev);
- saa7146_vv_release(dev);
-
- hexium_num--;
-
- i2c_del_adapter(&hexium->i2c_adapter);
- kfree(hexium);
- return 0;
-}
-
-static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
-{
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
-
- if (V4L2_STD_PAL == std->id) {
- hexium_set_standard(hexium, hexium_pal);
- hexium->cur_std = V4L2_STD_PAL;
- return 0;
- } else if (V4L2_STD_NTSC == std->id) {
- hexium_set_standard(hexium, hexium_ntsc);
- hexium->cur_std = V4L2_STD_NTSC;
- return 0;
- } else if (V4L2_STD_SECAM == std->id) {
- hexium_set_standard(hexium, hexium_secam);
- hexium->cur_std = V4L2_STD_SECAM;
- return 0;
- }
-
- return -1;
-}
-
-static struct saa7146_extension hexium_extension;
-
-static struct saa7146_pci_extension_data hexium_gemini_4bnc = {
- .ext_priv = "Hexium Gemini (4 BNC)",
- .ext = &hexium_extension,
-};
-
-static struct saa7146_pci_extension_data hexium_gemini_dual_4bnc = {
- .ext_priv = "Hexium Gemini Dual (4 BNC)",
- .ext = &hexium_extension,
-};
-
-static struct pci_device_id pci_tbl[] = {
- {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
- .subvendor = 0x17c8,
- .subdevice = 0x2401,
- .driver_data = (unsigned long) &hexium_gemini_4bnc,
- },
- {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
- .subvendor = 0x17c8,
- .subdevice = 0x2402,
- .driver_data = (unsigned long) &hexium_gemini_dual_4bnc,
- },
- {
- .vendor = 0,
- }
-};
-
-MODULE_DEVICE_TABLE(pci, pci_tbl);
-
-static struct saa7146_ext_vv vv_data = {
- .inputs = HEXIUM_INPUTS,
- .capabilities = 0,
- .stds = &hexium_standards[0],
- .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
- .std_callback = &std_callback,
-};
-
-static struct saa7146_extension hexium_extension = {
- .name = "hexium gemini",
- .flags = SAA7146_USE_I2C_IRQ,
-
- .pci_tbl = &pci_tbl[0],
- .module = THIS_MODULE,
-
- .attach = hexium_attach,
- .detach = hexium_detach,
-
- .irq_mask = 0,
- .irq_func = NULL,
-};
-
-static int __init hexium_init_module(void)
-{
- if (0 != saa7146_register_extension(&hexium_extension)) {
- DEB_S("failed to register extension\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-static void __exit hexium_cleanup_module(void)
-{
- saa7146_unregister_extension(&hexium_extension);
-}
-
-module_init(hexium_init_module);
-module_exit(hexium_cleanup_module);
-
-MODULE_DESCRIPTION("video4linux-2 driver for Hexium Gemini frame grabber cards");
-MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
deleted file mode 100644
index a1eb26d1107..00000000000
--- a/drivers/media/video/hexium_orion.c
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- hexium_orion.c - v4l2 driver for the Hexium Orion frame grabber cards
-
- Visit http://www.mihu.de/linux/saa7146/ and follow the link
- to "hexium" for further details about this card.
-
- Copyright (C) 2003 Michael Hunold <michael@mihu.de>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define DEBUG_VARIABLE debug
-
-#include <media/saa7146_vv.h>
-#include <linux/module.h>
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "debug verbosity");
-
-/* global variables */
-static int hexium_num;
-
-#define HEXIUM_HV_PCI6_ORION 1
-#define HEXIUM_ORION_1SVHS_3BNC 2
-#define HEXIUM_ORION_4BNC 3
-
-#define HEXIUM_INPUTS 9
-static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = {
- { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
-};
-
-#define HEXIUM_AUDIOS 0
-
-struct hexium_data
-{
- s8 adr;
- u8 byte;
-};
-
-struct hexium
-{
- int type;
- struct video_device *video_dev;
- struct i2c_adapter i2c_adapter;
-
- int cur_input; /* current input */
-};
-
-/* Philips SAA7110 decoder default registers */
-static u8 hexium_saa7110[53]={
-/*00*/ 0x4C,0x3C,0x0D,0xEF,0xBD,0xF0,0x00,0x00,
-/*08*/ 0xF8,0xF8,0x60,0x60,0x40,0x86,0x18,0x90,
-/*10*/ 0x00,0x2C,0x40,0x46,0x42,0x1A,0xFF,0xDA,
-/*18*/ 0xF0,0x8B,0x00,0x00,0x00,0x00,0x00,0x00,
-/*20*/ 0xD9,0x17,0x40,0x41,0x80,0x41,0x80,0x4F,
-/*28*/ 0xFE,0x01,0x0F,0x0F,0x03,0x01,0x81,0x03,
-/*30*/ 0x44,0x75,0x01,0x8C,0x03
-};
-
-static struct {
- struct hexium_data data[8];
-} hexium_input_select[] = {
-{
- { /* cvbs 1 */
- { 0x06, 0x00 },
- { 0x20, 0xD9 },
- { 0x21, 0x17 }, // 0x16,
- { 0x22, 0x40 },
- { 0x2C, 0x03 },
- { 0x30, 0x44 },
- { 0x31, 0x75 }, // ??
- { 0x21, 0x16 }, // 0x03,
- }
-}, {
- { /* cvbs 2 */
- { 0x06, 0x00 },
- { 0x20, 0x78 },
- { 0x21, 0x07 }, // 0x03,
- { 0x22, 0xD2 },
- { 0x2C, 0x83 },
- { 0x30, 0x60 },
- { 0x31, 0xB5 }, // ?
- { 0x21, 0x03 },
- }
-}, {
- { /* cvbs 3 */
- { 0x06, 0x00 },
- { 0x20, 0xBA },
- { 0x21, 0x07 }, // 0x05,
- { 0x22, 0x91 },
- { 0x2C, 0x03 },
- { 0x30, 0x60 },
- { 0x31, 0xB5 }, // ??
- { 0x21, 0x05 }, // 0x03,
- }
-}, {
- { /* cvbs 4 */
- { 0x06, 0x00 },
- { 0x20, 0xD8 },
- { 0x21, 0x17 }, // 0x16,
- { 0x22, 0x40 },
- { 0x2C, 0x03 },
- { 0x30, 0x44 },
- { 0x31, 0x75 }, // ??
- { 0x21, 0x16 }, // 0x03,
- }
-}, {
- { /* cvbs 5 */
- { 0x06, 0x00 },
- { 0x20, 0xB8 },
- { 0x21, 0x07 }, // 0x05,
- { 0x22, 0x91 },
- { 0x2C, 0x03 },
- { 0x30, 0x60 },
- { 0x31, 0xB5 }, // ??
- { 0x21, 0x05 }, // 0x03,
- }
-}, {
- { /* cvbs 6 */
- { 0x06, 0x00 },
- { 0x20, 0x7C },
- { 0x21, 0x07 }, // 0x03
- { 0x22, 0xD2 },
- { 0x2C, 0x83 },
- { 0x30, 0x60 },
- { 0x31, 0xB5 }, // ??
- { 0x21, 0x03 },
- }
-}, {
- { /* y/c 1 */
- { 0x06, 0x80 },
- { 0x20, 0x59 },
- { 0x21, 0x17 },
- { 0x22, 0x42 },
- { 0x2C, 0xA3 },
- { 0x30, 0x44 },
- { 0x31, 0x75 },
- { 0x21, 0x12 },
- }
-}, {
- { /* y/c 2 */
- { 0x06, 0x80 },
- { 0x20, 0x9A },
- { 0x21, 0x17 },
- { 0x22, 0xB1 },
- { 0x2C, 0x13 },
- { 0x30, 0x60 },
- { 0x31, 0xB5 },
- { 0x21, 0x14 },
- }
-}, {
- { /* y/c 3 */
- { 0x06, 0x80 },
- { 0x20, 0x3C },
- { 0x21, 0x27 },
- { 0x22, 0xC1 },
- { 0x2C, 0x23 },
- { 0x30, 0x44 },
- { 0x31, 0x75 },
- { 0x21, 0x21 },
- }
-}
-};
-
-static struct saa7146_standard hexium_standards[] = {
- {
- .name = "PAL", .id = V4L2_STD_PAL,
- .v_offset = 16, .v_field = 288,
- .h_offset = 1, .h_pixels = 680,
- .v_max_out = 576, .h_max_out = 768,
- }, {
- .name = "NTSC", .id = V4L2_STD_NTSC,
- .v_offset = 16, .v_field = 240,
- .h_offset = 1, .h_pixels = 640,
- .v_max_out = 480, .h_max_out = 640,
- }, {
- .name = "SECAM", .id = V4L2_STD_SECAM,
- .v_offset = 16, .v_field = 288,
- .h_offset = 1, .h_pixels = 720,
- .v_max_out = 576, .h_max_out = 768,
- }
-};
-
-/* this is only called for old HV-PCI6/Orion cards
- without eeprom */
-static int hexium_probe(struct saa7146_dev *dev)
-{
- struct hexium *hexium = NULL;
- union i2c_smbus_data data;
- int err = 0;
-
- DEB_EE("\n");
-
- /* there are no hexium orion cards with revision 0 saa7146s */
- if (0 == dev->revision) {
- return -EFAULT;
- }
-
- hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
- if (NULL == hexium) {
- pr_err("hexium_probe: not enough kernel memory\n");
- return -ENOMEM;
- }
-
- /* enable i2c-port pins */
- saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
-
- saa7146_write(dev, DD1_INIT, 0x01000100);
- saa7146_write(dev, DD1_STREAM_B, 0x00000000);
- saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-
- hexium->i2c_adapter = (struct i2c_adapter) {
- .name = "hexium orion",
- };
- saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
- if (i2c_add_adapter(&hexium->i2c_adapter) < 0) {
- DEB_S("cannot register i2c-device. skipping.\n");
- kfree(hexium);
- return -EFAULT;
- }
-
- /* set SAA7110 control GPIO 0 */
- saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
- /* set HWControl GPIO number 2 */
- saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
-
- mdelay(10);
-
- /* detect newer Hexium Orion cards by subsystem ids */
- if (0x17c8 == dev->pci->subsystem_vendor && 0x0101 == dev->pci->subsystem_device) {
- pr_info("device is a Hexium Orion w/ 1 SVHS + 3 BNC inputs\n");
- /* we store the pointer in our private data field */
- dev->ext_priv = hexium;
- hexium->type = HEXIUM_ORION_1SVHS_3BNC;
- return 0;
- }
-
- if (0x17c8 == dev->pci->subsystem_vendor && 0x2101 == dev->pci->subsystem_device) {
- pr_info("device is a Hexium Orion w/ 4 BNC inputs\n");
- /* we store the pointer in our private data field */
- dev->ext_priv = hexium;
- hexium->type = HEXIUM_ORION_4BNC;
- return 0;
- }
-
- /* check if this is an old hexium Orion card by looking at
- a saa7110 at address 0x4e */
- if (0 == (err = i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, &data))) {
- pr_info("device is a Hexium HV-PCI6/Orion (old)\n");
- /* we store the pointer in our private data field */
- dev->ext_priv = hexium;
- hexium->type = HEXIUM_HV_PCI6_ORION;
- return 0;
- }
-
- i2c_del_adapter(&hexium->i2c_adapter);
- kfree(hexium);
- return -EFAULT;
-}
-
-/* bring hardware to a sane state. this has to be done, just in case someone
- wants to capture from this device before it has been properly initialized.
- the capture engine would badly fail, because no valid signal arrives on the
- saa7146, thus leading to timeouts and stuff. */
-static int hexium_init_done(struct saa7146_dev *dev)
-{
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
- union i2c_smbus_data data;
- int i = 0;
-
- DEB_D("hexium_init_done called\n");
-
- /* initialize the helper ics to useful values */
- for (i = 0; i < sizeof(hexium_saa7110); i++) {
- data.byte = hexium_saa7110[i];
- if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_WRITE, i, I2C_SMBUS_BYTE_DATA, &data)) {
- pr_err("failed for address 0x%02x\n", i);
- }
- }
-
- return 0;
-}
-
-static int hexium_set_input(struct hexium *hexium, int input)
-{
- union i2c_smbus_data data;
- int i = 0;
-
- DEB_D("\n");
-
- for (i = 0; i < 8; i++) {
- int adr = hexium_input_select[input].data[i].adr;
- data.byte = hexium_input_select[input].data[i].byte;
- if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_WRITE, adr, I2C_SMBUS_BYTE_DATA, &data)) {
- return -1;
- }
- pr_debug("%d: 0x%02x => 0x%02x\n", input, adr, data.byte);
- }
-
- return 0;
-}
-
-static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
-{
- DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index);
-
- if (i->index >= HEXIUM_INPUTS)
- return -EINVAL;
-
- memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-
- DEB_D("v4l2_ioctl: VIDIOC_ENUMINPUT %d\n", i->index);
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
-
- *input = hexium->cur_input;
-
- DEB_D("VIDIOC_G_INPUT: %d\n", *input);
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
-
- if (input >= HEXIUM_INPUTS)
- return -EINVAL;
-
- hexium->cur_input = input;
- hexium_set_input(hexium, input);
-
- return 0;
-}
-
-static struct saa7146_ext_vv vv_data;
-
-/* this function only gets called when the probing was successful */
-static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
-{
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
-
- DEB_EE("\n");
-
- saa7146_vv_init(dev, &vv_data);
- vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
- vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
- vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
- if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) {
- pr_err("cannot register capture v4l2 device. skipping.\n");
- return -1;
- }
-
- pr_err("found 'hexium orion' frame grabber-%d\n", hexium_num);
- hexium_num++;
-
- /* the rest */
- hexium->cur_input = 0;
- hexium_init_done(dev);
-
- return 0;
-}
-
-static int hexium_detach(struct saa7146_dev *dev)
-{
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
-
- DEB_EE("dev:%p\n", dev);
-
- saa7146_unregister_device(&hexium->video_dev, dev);
- saa7146_vv_release(dev);
-
- hexium_num--;
-
- i2c_del_adapter(&hexium->i2c_adapter);
- kfree(hexium);
- return 0;
-}
-
-static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
-{
- return 0;
-}
-
-static struct saa7146_extension extension;
-
-static struct saa7146_pci_extension_data hexium_hv_pci6 = {
- .ext_priv = "Hexium HV-PCI6 / Orion",
- .ext = &extension,
-};
-
-static struct saa7146_pci_extension_data hexium_orion_1svhs_3bnc = {
- .ext_priv = "Hexium HV-PCI6 / Orion (1 SVHS/3 BNC)",
- .ext = &extension,
-};
-
-static struct saa7146_pci_extension_data hexium_orion_4bnc = {
- .ext_priv = "Hexium HV-PCI6 / Orion (4 BNC)",
- .ext = &extension,
-};
-
-static struct pci_device_id pci_tbl[] = {
- {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
- .subvendor = 0x0000,
- .subdevice = 0x0000,
- .driver_data = (unsigned long) &hexium_hv_pci6,
- },
- {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
- .subvendor = 0x17c8,
- .subdevice = 0x0101,
- .driver_data = (unsigned long) &hexium_orion_1svhs_3bnc,
- },
- {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
- .subvendor = 0x17c8,
- .subdevice = 0x2101,
- .driver_data = (unsigned long) &hexium_orion_4bnc,
- },
- {
- .vendor = 0,
- }
-};
-
-MODULE_DEVICE_TABLE(pci, pci_tbl);
-
-static struct saa7146_ext_vv vv_data = {
- .inputs = HEXIUM_INPUTS,
- .capabilities = 0,
- .stds = &hexium_standards[0],
- .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
- .std_callback = &std_callback,
-};
-
-static struct saa7146_extension extension = {
- .name = "hexium HV-PCI6 Orion",
- .flags = 0, // SAA7146_USE_I2C_IRQ,
-
- .pci_tbl = &pci_tbl[0],
- .module = THIS_MODULE,
-
- .probe = hexium_probe,
- .attach = hexium_attach,
- .detach = hexium_detach,
-
- .irq_mask = 0,
- .irq_func = NULL,
-};
-
-static int __init hexium_init_module(void)
-{
- if (0 != saa7146_register_extension(&extension)) {
- DEB_S("failed to register extension\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-static void __exit hexium_cleanup_module(void)
-{
- saa7146_unregister_extension(&extension);
-}
-
-module_init(hexium_init_module);
-module_exit(hexium_cleanup_module);
-
-MODULE_DESCRIPTION("video4linux-2 driver for Hexium Orion frame grabber cards");
-MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/imx074.c b/drivers/media/video/imx074.c
deleted file mode 100644
index 351e9bafe8f..00000000000
--- a/drivers/media/video/imx074.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Driver for IMX074 CMOS Image Sensor from Sony
- *
- * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * Partially inspired by the IMX074 driver from the Android / MSM tree
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/module.h>
-
-#include <media/soc_camera.h>
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
-
-/* IMX074 registers */
-
-#define MODE_SELECT 0x0100
-#define IMAGE_ORIENTATION 0x0101
-#define GROUPED_PARAMETER_HOLD 0x0104
-
-/* Integration Time */
-#define COARSE_INTEGRATION_TIME_HI 0x0202
-#define COARSE_INTEGRATION_TIME_LO 0x0203
-/* Gain */
-#define ANALOGUE_GAIN_CODE_GLOBAL_HI 0x0204
-#define ANALOGUE_GAIN_CODE_GLOBAL_LO 0x0205
-
-/* PLL registers */
-#define PRE_PLL_CLK_DIV 0x0305
-#define PLL_MULTIPLIER 0x0307
-#define PLSTATIM 0x302b
-#define VNDMY_ABLMGSHLMT 0x300a
-#define Y_OPBADDR_START_DI 0x3014
-/* mode setting */
-#define FRAME_LENGTH_LINES_HI 0x0340
-#define FRAME_LENGTH_LINES_LO 0x0341
-#define LINE_LENGTH_PCK_HI 0x0342
-#define LINE_LENGTH_PCK_LO 0x0343
-#define YADDR_START 0x0347
-#define YADDR_END 0x034b
-#define X_OUTPUT_SIZE_MSB 0x034c
-#define X_OUTPUT_SIZE_LSB 0x034d
-#define Y_OUTPUT_SIZE_MSB 0x034e
-#define Y_OUTPUT_SIZE_LSB 0x034f
-#define X_EVEN_INC 0x0381
-#define X_ODD_INC 0x0383
-#define Y_EVEN_INC 0x0385
-#define Y_ODD_INC 0x0387
-
-#define HMODEADD 0x3001
-#define VMODEADD 0x3016
-#define VAPPLINE_START 0x3069
-#define VAPPLINE_END 0x306b
-#define SHUTTER 0x3086
-#define HADDAVE 0x30e8
-#define LANESEL 0x3301
-
-/* IMX074 supported geometry */
-#define IMX074_WIDTH 1052
-#define IMX074_HEIGHT 780
-
-/* IMX074 has only one fixed colorspace per pixelcode */
-struct imx074_datafmt {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
-};
-
-struct imx074 {
- struct v4l2_subdev subdev;
- const struct imx074_datafmt *fmt;
-};
-
-static const struct imx074_datafmt imx074_colour_fmts[] = {
- {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
-};
-
-static struct imx074 *to_imx074(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client), struct imx074, subdev);
-}
-
-/* Find a data format by a pixel code in an array */
-static const struct imx074_datafmt *imx074_find_datafmt(enum v4l2_mbus_pixelcode code)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(imx074_colour_fmts); i++)
- if (imx074_colour_fmts[i].code == code)
- return imx074_colour_fmts + i;
-
- return NULL;
-}
-
-static int reg_write(struct i2c_client *client, const u16 addr, const u8 data)
-{
- struct i2c_adapter *adap = client->adapter;
- struct i2c_msg msg;
- unsigned char tx[3];
- int ret;
-
- msg.addr = client->addr;
- msg.buf = tx;
- msg.len = 3;
- msg.flags = 0;
-
- tx[0] = addr >> 8;
- tx[1] = addr & 0xff;
- tx[2] = data;
-
- ret = i2c_transfer(adap, &msg, 1);
-
- mdelay(2);
-
- return ret == 1 ? 0 : -EIO;
-}
-
-static int reg_read(struct i2c_client *client, const u16 addr)
-{
- u8 buf[2] = {addr >> 8, addr & 0xff};
- int ret;
- struct i2c_msg msgs[] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = 2,
- .buf = buf,
- }, {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = 2,
- .buf = buf,
- },
- };
-
- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
- if (ret < 0) {
- dev_warn(&client->dev, "Reading register %x from %x failed\n",
- addr, client->addr);
- return ret;
- }
-
- return buf[0] & 0xff; /* no sign-extension */
-}
-
-static int imx074_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- const struct imx074_datafmt *fmt = imx074_find_datafmt(mf->code);
-
- dev_dbg(sd->v4l2_dev->dev, "%s(%u)\n", __func__, mf->code);
-
- if (!fmt) {
- mf->code = imx074_colour_fmts[0].code;
- mf->colorspace = imx074_colour_fmts[0].colorspace;
- }
-
- mf->width = IMX074_WIDTH;
- mf->height = IMX074_HEIGHT;
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int imx074_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct imx074 *priv = to_imx074(client);
-
- dev_dbg(sd->v4l2_dev->dev, "%s(%u)\n", __func__, mf->code);
-
- /* MIPI CSI could have changed the format, double-check */
- if (!imx074_find_datafmt(mf->code))
- return -EINVAL;
-
- imx074_try_fmt(sd, mf);
-
- priv->fmt = imx074_find_datafmt(mf->code);
-
- return 0;
-}
-
-static int imx074_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct imx074 *priv = to_imx074(client);
-
- const struct imx074_datafmt *fmt = priv->fmt;
-
- mf->code = fmt->code;
- mf->colorspace = fmt->colorspace;
- mf->width = IMX074_WIDTH;
- mf->height = IMX074_HEIGHT;
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int imx074_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct v4l2_rect *rect = &a->c;
-
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- rect->top = 0;
- rect->left = 0;
- rect->width = IMX074_WIDTH;
- rect->height = IMX074_HEIGHT;
-
- return 0;
-}
-
-static int imx074_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = IMX074_WIDTH;
- a->bounds.height = IMX074_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int imx074_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if ((unsigned int)index >= ARRAY_SIZE(imx074_colour_fmts))
- return -EINVAL;
-
- *code = imx074_colour_fmts[index].code;
- return 0;
-}
-
-static int imx074_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- /* MODE_SELECT: stream or standby */
- return reg_write(client, MODE_SELECT, !!enable);
-}
-
-static int imx074_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = V4L2_IDENT_IMX074;
- id->revision = 0;
-
- return 0;
-}
-
-static int imx074_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- cfg->type = V4L2_MBUS_CSI2;
- cfg->flags = V4L2_MBUS_CSI2_2_LANE |
- V4L2_MBUS_CSI2_CHANNEL_0 |
- V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
-
- return 0;
-}
-
-static struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
- .s_stream = imx074_s_stream,
- .s_mbus_fmt = imx074_s_fmt,
- .g_mbus_fmt = imx074_g_fmt,
- .try_mbus_fmt = imx074_try_fmt,
- .enum_mbus_fmt = imx074_enum_fmt,
- .g_crop = imx074_g_crop,
- .cropcap = imx074_cropcap,
- .g_mbus_config = imx074_g_mbus_config,
-};
-
-static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
- .g_chip_ident = imx074_g_chip_ident,
-};
-
-static struct v4l2_subdev_ops imx074_subdev_ops = {
- .core = &imx074_subdev_core_ops,
- .video = &imx074_subdev_video_ops,
-};
-
-static int imx074_video_probe(struct i2c_client *client)
-{
- int ret;
- u16 id;
-
- /* Read sensor Model ID */
- ret = reg_read(client, 0);
- if (ret < 0)
- return ret;
-
- id = ret << 8;
-
- ret = reg_read(client, 1);
- if (ret < 0)
- return ret;
-
- id |= ret;
-
- dev_info(&client->dev, "Chip ID 0x%04x detected\n", id);
-
- if (id != 0x74)
- return -ENODEV;
-
- /* PLL Setting EXTCLK=24MHz, 22.5times */
- reg_write(client, PLL_MULTIPLIER, 0x2D);
- reg_write(client, PRE_PLL_CLK_DIV, 0x02);
- reg_write(client, PLSTATIM, 0x4B);
-
- /* 2-lane mode */
- reg_write(client, 0x3024, 0x00);
-
- reg_write(client, IMAGE_ORIENTATION, 0x00);
-
- /* select RAW mode:
- * 0x08+0x08 = top 8 bits
- * 0x0a+0x08 = compressed 8-bits
- * 0x0a+0x0a = 10 bits
- */
- reg_write(client, 0x0112, 0x08);
- reg_write(client, 0x0113, 0x08);
-
- /* Base setting for High frame mode */
- reg_write(client, VNDMY_ABLMGSHLMT, 0x80);
- reg_write(client, Y_OPBADDR_START_DI, 0x08);
- reg_write(client, 0x3015, 0x37);
- reg_write(client, 0x301C, 0x01);
- reg_write(client, 0x302C, 0x05);
- reg_write(client, 0x3031, 0x26);
- reg_write(client, 0x3041, 0x60);
- reg_write(client, 0x3051, 0x24);
- reg_write(client, 0x3053, 0x34);
- reg_write(client, 0x3057, 0xC0);
- reg_write(client, 0x305C, 0x09);
- reg_write(client, 0x305D, 0x07);
- reg_write(client, 0x3060, 0x30);
- reg_write(client, 0x3065, 0x00);
- reg_write(client, 0x30AA, 0x08);
- reg_write(client, 0x30AB, 0x1C);
- reg_write(client, 0x30B0, 0x32);
- reg_write(client, 0x30B2, 0x83);
- reg_write(client, 0x30D3, 0x04);
- reg_write(client, 0x3106, 0x78);
- reg_write(client, 0x310C, 0x82);
- reg_write(client, 0x3304, 0x05);
- reg_write(client, 0x3305, 0x04);
- reg_write(client, 0x3306, 0x11);
- reg_write(client, 0x3307, 0x02);
- reg_write(client, 0x3308, 0x0C);
- reg_write(client, 0x3309, 0x06);
- reg_write(client, 0x330A, 0x08);
- reg_write(client, 0x330B, 0x04);
- reg_write(client, 0x330C, 0x08);
- reg_write(client, 0x330D, 0x06);
- reg_write(client, 0x330E, 0x01);
- reg_write(client, 0x3381, 0x00);
-
- /* V : 1/2V-addition (1,3), H : 1/2H-averaging (1,3) -> Full HD */
- /* 1608 = 1560 + 48 (black lines) */
- reg_write(client, FRAME_LENGTH_LINES_HI, 0x06);
- reg_write(client, FRAME_LENGTH_LINES_LO, 0x48);
- reg_write(client, YADDR_START, 0x00);
- reg_write(client, YADDR_END, 0x2F);
- /* 0x838 == 2104 */
- reg_write(client, X_OUTPUT_SIZE_MSB, 0x08);
- reg_write(client, X_OUTPUT_SIZE_LSB, 0x38);
- /* 0x618 == 1560 */
- reg_write(client, Y_OUTPUT_SIZE_MSB, 0x06);
- reg_write(client, Y_OUTPUT_SIZE_LSB, 0x18);
- reg_write(client, X_EVEN_INC, 0x01);
- reg_write(client, X_ODD_INC, 0x03);
- reg_write(client, Y_EVEN_INC, 0x01);
- reg_write(client, Y_ODD_INC, 0x03);
- reg_write(client, HMODEADD, 0x00);
- reg_write(client, VMODEADD, 0x16);
- reg_write(client, VAPPLINE_START, 0x24);
- reg_write(client, VAPPLINE_END, 0x53);
- reg_write(client, SHUTTER, 0x00);
- reg_write(client, HADDAVE, 0x80);
-
- reg_write(client, LANESEL, 0x00);
-
- reg_write(client, GROUPED_PARAMETER_HOLD, 0x00); /* off */
-
- return 0;
-}
-
-static int imx074_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct imx074 *priv;
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- int ret;
-
- if (!icl) {
- dev_err(&client->dev, "IMX074: missing platform data!\n");
- return -EINVAL;
- }
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_warn(&adapter->dev,
- "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE\n");
- return -EIO;
- }
-
- priv = kzalloc(sizeof(struct imx074), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- v4l2_i2c_subdev_init(&priv->subdev, client, &imx074_subdev_ops);
-
- priv->fmt = &imx074_colour_fmts[0];
-
- ret = imx074_video_probe(client);
- if (ret < 0) {
- kfree(priv);
- return ret;
- }
-
- return ret;
-}
-
-static int imx074_remove(struct i2c_client *client)
-{
- struct imx074 *priv = to_imx074(client);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- if (icl->free_bus)
- icl->free_bus(icl);
- kfree(priv);
-
- return 0;
-}
-
-static const struct i2c_device_id imx074_id[] = {
- { "imx074", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, imx074_id);
-
-static struct i2c_driver imx074_i2c_driver = {
- .driver = {
- .name = "imx074",
- },
- .probe = imx074_probe,
- .remove = imx074_remove,
- .id_table = imx074_id,
-};
-
-module_i2c_driver(imx074_i2c_driver);
-
-MODULE_DESCRIPTION("Sony IMX074 Camera driver");
-MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c
deleted file mode 100644
index 548236333cc..00000000000
--- a/drivers/media/video/indycam.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * indycam.c - Silicon Graphics IndyCam digital camera driver
- *
- * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
- * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-
-/* IndyCam decodes stream of photons into digital image representation ;-) */
-#include <linux/videodev2.h>
-#include <linux/i2c.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-
-#include "indycam.h"
-
-#define INDYCAM_MODULE_VERSION "0.0.5"
-
-MODULE_DESCRIPTION("SGI IndyCam driver");
-MODULE_VERSION(INDYCAM_MODULE_VERSION);
-MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
-MODULE_LICENSE("GPL");
-
-
-// #define INDYCAM_DEBUG
-
-#ifdef INDYCAM_DEBUG
-#define dprintk(x...) printk("IndyCam: " x);
-#define indycam_regdump(client) indycam_regdump_debug(client)
-#else
-#define dprintk(x...)
-#define indycam_regdump(client)
-#endif
-
-struct indycam {
- struct v4l2_subdev sd;
- u8 version;
-};
-
-static inline struct indycam *to_indycam(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct indycam, sd);
-}
-
-static const u8 initseq[] = {
- INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */
- INDYCAM_SHUTTER_60, /* INDYCAM_SHUTTER */
- INDYCAM_GAIN_DEFAULT, /* INDYCAM_GAIN */
- 0x00, /* INDYCAM_BRIGHTNESS (read-only) */
- INDYCAM_RED_BALANCE_DEFAULT, /* INDYCAM_RED_BALANCE */
- INDYCAM_BLUE_BALANCE_DEFAULT, /* INDYCAM_BLUE_BALANCE */
- INDYCAM_RED_SATURATION_DEFAULT, /* INDYCAM_RED_SATURATION */
- INDYCAM_BLUE_SATURATION_DEFAULT,/* INDYCAM_BLUE_SATURATION */
-};
-
-/* IndyCam register handling */
-
-static int indycam_read_reg(struct v4l2_subdev *sd, u8 reg, u8 *value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
-
- if (reg == INDYCAM_REG_RESET) {
- dprintk("indycam_read_reg(): "
- "skipping write-only register %d\n", reg);
- *value = 0;
- return 0;
- }
-
- ret = i2c_smbus_read_byte_data(client, reg);
-
- if (ret < 0) {
- printk(KERN_ERR "IndyCam: indycam_read_reg(): read failed, "
- "register = 0x%02x\n", reg);
- return ret;
- }
-
- *value = (u8)ret;
-
- return 0;
-}
-
-static int indycam_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int err;
-
- if (reg == INDYCAM_REG_BRIGHTNESS || reg == INDYCAM_REG_VERSION) {
- dprintk("indycam_write_reg(): "
- "skipping read-only register %d\n", reg);
- return 0;
- }
-
- dprintk("Writing Reg %d = 0x%02x\n", reg, value);
- err = i2c_smbus_write_byte_data(client, reg, value);
-
- if (err) {
- printk(KERN_ERR "IndyCam: indycam_write_reg(): write failed, "
- "register = 0x%02x, value = 0x%02x\n", reg, value);
- }
- return err;
-}
-
-static int indycam_write_block(struct v4l2_subdev *sd, u8 reg,
- u8 length, u8 *data)
-{
- int i, err;
-
- for (i = 0; i < length; i++) {
- err = indycam_write_reg(sd, reg + i, data[i]);
- if (err)
- return err;
- }
-
- return 0;
-}
-
-/* Helper functions */
-
-#ifdef INDYCAM_DEBUG
-static void indycam_regdump_debug(struct v4l2_subdev *sd)
-{
- int i;
- u8 val;
-
- for (i = 0; i < 9; i++) {
- indycam_read_reg(sd, i, &val);
- dprintk("Reg %d = 0x%02x\n", i, val);
- }
-}
-#endif
-
-static int indycam_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- struct indycam *camera = to_indycam(sd);
- u8 reg;
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTOGAIN:
- case V4L2_CID_AUTO_WHITE_BALANCE:
- ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, &reg);
- if (ret)
- return -EIO;
- if (ctrl->id == V4L2_CID_AUTOGAIN)
- ctrl->value = (reg & INDYCAM_CONTROL_AGCENA)
- ? 1 : 0;
- else
- ctrl->value = (reg & INDYCAM_CONTROL_AWBCTL)
- ? 1 : 0;
- break;
- case V4L2_CID_EXPOSURE:
- ret = indycam_read_reg(sd, INDYCAM_REG_SHUTTER, &reg);
- if (ret)
- return -EIO;
- ctrl->value = ((s32)reg == 0x00) ? 0xff : ((s32)reg - 1);
- break;
- case V4L2_CID_GAIN:
- ret = indycam_read_reg(sd, INDYCAM_REG_GAIN, &reg);
- if (ret)
- return -EIO;
- ctrl->value = (s32)reg;
- break;
- case V4L2_CID_RED_BALANCE:
- ret = indycam_read_reg(sd, INDYCAM_REG_RED_BALANCE, &reg);
- if (ret)
- return -EIO;
- ctrl->value = (s32)reg;
- break;
- case V4L2_CID_BLUE_BALANCE:
- ret = indycam_read_reg(sd, INDYCAM_REG_BLUE_BALANCE, &reg);
- if (ret)
- return -EIO;
- ctrl->value = (s32)reg;
- break;
- case INDYCAM_CONTROL_RED_SATURATION:
- ret = indycam_read_reg(sd,
- INDYCAM_REG_RED_SATURATION, &reg);
- if (ret)
- return -EIO;
- ctrl->value = (s32)reg;
- break;
- case INDYCAM_CONTROL_BLUE_SATURATION:
- ret = indycam_read_reg(sd,
- INDYCAM_REG_BLUE_SATURATION, &reg);
- if (ret)
- return -EIO;
- ctrl->value = (s32)reg;
- break;
- case V4L2_CID_GAMMA:
- if (camera->version == CAMERA_VERSION_MOOSE) {
- ret = indycam_read_reg(sd,
- INDYCAM_REG_GAMMA, &reg);
- if (ret)
- return -EIO;
- ctrl->value = (s32)reg;
- } else {
- ctrl->value = INDYCAM_GAMMA_DEFAULT;
- }
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int indycam_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- struct indycam *camera = to_indycam(sd);
- u8 reg;
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTOGAIN:
- case V4L2_CID_AUTO_WHITE_BALANCE:
- ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, &reg);
- if (ret)
- break;
-
- if (ctrl->id == V4L2_CID_AUTOGAIN) {
- if (ctrl->value)
- reg |= INDYCAM_CONTROL_AGCENA;
- else
- reg &= ~INDYCAM_CONTROL_AGCENA;
- } else {
- if (ctrl->value)
- reg |= INDYCAM_CONTROL_AWBCTL;
- else
- reg &= ~INDYCAM_CONTROL_AWBCTL;
- }
-
- ret = indycam_write_reg(sd, INDYCAM_REG_CONTROL, reg);
- break;
- case V4L2_CID_EXPOSURE:
- reg = (ctrl->value == 0xff) ? 0x00 : (ctrl->value + 1);
- ret = indycam_write_reg(sd, INDYCAM_REG_SHUTTER, reg);
- break;
- case V4L2_CID_GAIN:
- ret = indycam_write_reg(sd, INDYCAM_REG_GAIN, ctrl->value);
- break;
- case V4L2_CID_RED_BALANCE:
- ret = indycam_write_reg(sd, INDYCAM_REG_RED_BALANCE,
- ctrl->value);
- break;
- case V4L2_CID_BLUE_BALANCE:
- ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_BALANCE,
- ctrl->value);
- break;
- case INDYCAM_CONTROL_RED_SATURATION:
- ret = indycam_write_reg(sd, INDYCAM_REG_RED_SATURATION,
- ctrl->value);
- break;
- case INDYCAM_CONTROL_BLUE_SATURATION:
- ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_SATURATION,
- ctrl->value);
- break;
- case V4L2_CID_GAMMA:
- if (camera->version == CAMERA_VERSION_MOOSE) {
- ret = indycam_write_reg(sd, INDYCAM_REG_GAMMA,
- ctrl->value);
- }
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-/* I2C-interface */
-
-static int indycam_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct indycam *camera = to_indycam(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_INDYCAM,
- camera->version);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops indycam_core_ops = {
- .g_chip_ident = indycam_g_chip_ident,
- .g_ctrl = indycam_g_ctrl,
- .s_ctrl = indycam_s_ctrl,
-};
-
-static const struct v4l2_subdev_ops indycam_ops = {
- .core = &indycam_core_ops,
-};
-
-static int indycam_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int err = 0;
- struct indycam *camera;
- struct v4l2_subdev *sd;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- camera = kzalloc(sizeof(struct indycam), GFP_KERNEL);
- if (!camera)
- return -ENOMEM;
-
- sd = &camera->sd;
- v4l2_i2c_subdev_init(sd, client, &indycam_ops);
-
- camera->version = i2c_smbus_read_byte_data(client,
- INDYCAM_REG_VERSION);
- if (camera->version != CAMERA_VERSION_INDY &&
- camera->version != CAMERA_VERSION_MOOSE) {
- kfree(camera);
- return -ENODEV;
- }
-
- printk(KERN_INFO "IndyCam v%d.%d detected\n",
- INDYCAM_VERSION_MAJOR(camera->version),
- INDYCAM_VERSION_MINOR(camera->version));
-
- indycam_regdump(sd);
-
- // initialize
- err = indycam_write_block(sd, 0, sizeof(initseq), (u8 *)&initseq);
- if (err) {
- printk(KERN_ERR "IndyCam initialization failed\n");
- kfree(camera);
- return -EIO;
- }
-
- indycam_regdump(sd);
-
- // white balance
- err = indycam_write_reg(sd, INDYCAM_REG_CONTROL,
- INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL);
- if (err) {
- printk(KERN_ERR "IndyCam: White balancing camera failed\n");
- kfree(camera);
- return -EIO;
- }
-
- indycam_regdump(sd);
-
- printk(KERN_INFO "IndyCam initialized\n");
-
- return 0;
-}
-
-static int indycam_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(to_indycam(sd));
- return 0;
-}
-
-static const struct i2c_device_id indycam_id[] = {
- { "indycam", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, indycam_id);
-
-static struct i2c_driver indycam_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "indycam",
- },
- .probe = indycam_probe,
- .remove = indycam_remove,
- .id_table = indycam_id,
-};
-
-module_i2c_driver(indycam_driver);
diff --git a/drivers/media/video/indycam.h b/drivers/media/video/indycam.h
deleted file mode 100644
index 881f21c474c..00000000000
--- a/drivers/media/video/indycam.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * indycam.h - Silicon Graphics IndyCam digital camera driver
- *
- * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
- * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _INDYCAM_H_
-#define _INDYCAM_H_
-
-/* I2C address for the Guinness Camera */
-#define INDYCAM_ADDR 0x56
-
-/* Camera version */
-#define CAMERA_VERSION_INDY 0x10 /* v1.0 */
-#define CAMERA_VERSION_MOOSE 0x12 /* v1.2 */
-#define INDYCAM_VERSION_MAJOR(x) (((x) & 0xf0) >> 4)
-#define INDYCAM_VERSION_MINOR(x) ((x) & 0x0f)
-
-/* Register bus addresses */
-#define INDYCAM_REG_CONTROL 0x00
-#define INDYCAM_REG_SHUTTER 0x01
-#define INDYCAM_REG_GAIN 0x02
-#define INDYCAM_REG_BRIGHTNESS 0x03 /* read-only */
-#define INDYCAM_REG_RED_BALANCE 0x04
-#define INDYCAM_REG_BLUE_BALANCE 0x05
-#define INDYCAM_REG_RED_SATURATION 0x06
-#define INDYCAM_REG_BLUE_SATURATION 0x07
-#define INDYCAM_REG_GAMMA 0x08
-#define INDYCAM_REG_VERSION 0x0e /* read-only */
-#define INDYCAM_REG_RESET 0x0f /* write-only */
-
-#define INDYCAM_REG_LED 0x46
-#define INDYCAM_REG_ORIENTATION 0x47
-#define INDYCAM_REG_BUTTON 0x48
-
-/* Field definitions of registers */
-#define INDYCAM_CONTROL_AGCENA (1<<0) /* automatic gain control */
-#define INDYCAM_CONTROL_AWBCTL (1<<1) /* automatic white balance */
- /* 2-3 are reserved */
-#define INDYCAM_CONTROL_EVNFLD (1<<4) /* read-only */
-
-#define INDYCAM_SHUTTER_10000 0x02 /* 1/10000 second */
-#define INDYCAM_SHUTTER_4000 0x04 /* 1/4000 second */
-#define INDYCAM_SHUTTER_2000 0x08 /* 1/2000 second */
-#define INDYCAM_SHUTTER_1000 0x10 /* 1/1000 second */
-#define INDYCAM_SHUTTER_500 0x20 /* 1/500 second */
-#define INDYCAM_SHUTTER_250 0x3f /* 1/250 second */
-#define INDYCAM_SHUTTER_125 0x7e /* 1/125 second */
-#define INDYCAM_SHUTTER_100 0x9e /* 1/100 second */
-#define INDYCAM_SHUTTER_60 0x00 /* 1/60 second */
-
-#define INDYCAM_LED_ACTIVE 0x10
-#define INDYCAM_LED_INACTIVE 0x30
-#define INDYCAM_ORIENTATION_BOTTOM_TO_TOP 0x40
-#define INDYCAM_BUTTON_RELEASED 0x10
-
-/* Values for controls */
-#define INDYCAM_SHUTTER_MIN 0x00
-#define INDYCAM_SHUTTER_MAX 0xff
-#define INDYCAM_GAIN_MIN 0x00
-#define INDYCAM_GAIN_MAX 0xff
-#define INDYCAM_RED_BALANCE_MIN 0x00
-#define INDYCAM_RED_BALANCE_MAX 0xff
-#define INDYCAM_BLUE_BALANCE_MIN 0x00
-#define INDYCAM_BLUE_BALANCE_MAX 0xff
-#define INDYCAM_RED_SATURATION_MIN 0x00
-#define INDYCAM_RED_SATURATION_MAX 0xff
-#define INDYCAM_BLUE_SATURATION_MIN 0x00
-#define INDYCAM_BLUE_SATURATION_MAX 0xff
-#define INDYCAM_GAMMA_MIN 0x00
-#define INDYCAM_GAMMA_MAX 0xff
-
-#define INDYCAM_AGC_DEFAULT 1
-#define INDYCAM_AWB_DEFAULT 0
-#define INDYCAM_SHUTTER_DEFAULT 0xff
-#define INDYCAM_GAIN_DEFAULT 0x80
-#define INDYCAM_RED_BALANCE_DEFAULT 0x18
-#define INDYCAM_BLUE_BALANCE_DEFAULT 0xa4
-#define INDYCAM_RED_SATURATION_DEFAULT 0x80
-#define INDYCAM_BLUE_SATURATION_DEFAULT 0xc0
-#define INDYCAM_GAMMA_DEFAULT 0x80
-
-/* Driver interface definitions */
-
-#define INDYCAM_CONTROL_RED_SATURATION (V4L2_CID_PRIVATE_BASE + 0)
-#define INDYCAM_CONTROL_BLUE_SATURATION (V4L2_CID_PRIVATE_BASE + 1)
-
-#endif
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
deleted file mode 100644
index 04f192a0398..00000000000
--- a/drivers/media/video/ir-kbd-i2c.c
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- *
- * keyboard input driver for i2c IR remote controls
- *
- * Copyright (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
- * modified for PixelView (BT878P+W/FM) by
- * Michal Kochanowicz <mkochano@pld.org.pl>
- * Christoph Bartelmus <lirc@bartelmus.de>
- * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
- * Ulrich Mueller <ulrich.mueller42@web.de>
- * modified for em2820 based USB TV tuners by
- * Markus Rechberger <mrechberger@gmail.com>
- * modified for DViCO Fusion HDTV 5 RT GOLD by
- * Chaogui Zhang <czhang1974@gmail.com>
- * modified for MSI TV@nywhere Plus by
- * Henry Wong <henry@stuffedcow.net>
- * Mark Schultz <n9xmj@yahoo.com>
- * Brian Rogers <brian_rogers@comcast.net>
- * modified for AVerMedia Cardbus by
- * Oldrich Jedlicka <oldium.pro@seznam.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/workqueue.h>
-
-#include <media/rc-core.h>
-#include <media/ir-kbd-i2c.h>
-
-/* ----------------------------------------------------------------------- */
-/* insmod parameters */
-
-static int debug;
-module_param(debug, int, 0644); /* debug level (0,1,2) */
-
-
-#define MODULE_NAME "ir-kbd-i2c"
-#define dprintk(level, fmt, arg...) if (debug >= level) \
- printk(KERN_DEBUG MODULE_NAME ": " fmt , ## arg)
-
-/* ----------------------------------------------------------------------- */
-
-static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
- int size, int offset)
-{
- unsigned char buf[6];
- int start, range, toggle, dev, code, ircode;
-
- /* poll IR chip */
- if (size != i2c_master_recv(ir->c, buf, size))
- return -EIO;
-
- /* split rc5 data block ... */
- start = (buf[offset] >> 7) & 1;
- range = (buf[offset] >> 6) & 1;
- toggle = (buf[offset] >> 5) & 1;
- dev = buf[offset] & 0x1f;
- code = (buf[offset+1] >> 2) & 0x3f;
-
- /* rc5 has two start bits
- * the first bit must be one
- * the second bit defines the command range (1 = 0-63, 0 = 64 - 127)
- */
- if (!start)
- /* no key pressed */
- return 0;
- /*
- * Hauppauge remotes (black/silver) always use
- * specific device ids. If we do not filter the
- * device ids then messages destined for devices
- * such as TVs (id=0) will get through causing
- * mis-fired events.
- *
- * We also filter out invalid key presses which
- * produce annoying debug log entries.
- */
- ircode= (start << 12) | (toggle << 11) | (dev << 6) | code;
- if ((ircode & 0x1fff)==0x1fff)
- /* invalid key press */
- return 0;
-
- if (!range)
- code += 64;
-
- dprintk(1,"ir hauppauge (rc5): s%d r%d t%d dev=%d code=%d\n",
- start, range, toggle, dev, code);
-
- /* return key */
- *ir_key = (dev << 8) | code;
- *ir_raw = ircode;
- return 1;
-}
-
-static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- return get_key_haup_common (ir, ir_key, ir_raw, 3, 0);
-}
-
-static int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- int ret;
- unsigned char buf[1] = { 0 };
-
- /*
- * This is the same apparent "are you ready?" poll command observed
- * watching Windows driver traffic and implemented in lirc_zilog. With
- * this added, we get far saner remote behavior with z8 chips on usb
- * connected devices, even with the default polling interval of 100ms.
- */
- ret = i2c_master_send(ir->c, buf, 1);
- if (ret != 1)
- return (ret < 0) ? ret : -EINVAL;
-
- return get_key_haup_common (ir, ir_key, ir_raw, 6, 3);
-}
-
-static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- unsigned char b;
-
- /* poll IR chip */
- if (1 != i2c_master_recv(ir->c, &b, 1)) {
- dprintk(1,"read error\n");
- return -EIO;
- }
- *ir_key = b;
- *ir_raw = b;
- return 1;
-}
-
-static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- unsigned char buf[4];
-
- /* poll IR chip */
- if (4 != i2c_master_recv(ir->c, buf, 4)) {
- dprintk(1,"read error\n");
- return -EIO;
- }
-
- if(buf[0] !=0 || buf[1] !=0 || buf[2] !=0 || buf[3] != 0)
- dprintk(2, "%s: 0x%2x 0x%2x 0x%2x 0x%2x\n", __func__,
- buf[0], buf[1], buf[2], buf[3]);
-
- /* no key pressed or signal from other ir remote */
- if(buf[0] != 0x1 || buf[1] != 0xfe)
- return 0;
-
- *ir_key = buf[2];
- *ir_raw = (buf[2] << 8) | buf[3];
-
- return 1;
-}
-
-static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- unsigned char b;
-
- /* poll IR chip */
- if (1 != i2c_master_recv(ir->c, &b, 1)) {
- dprintk(1,"read error\n");
- return -EIO;
- }
-
- /* it seems that 0xFE indicates that a button is still hold
- down, while 0xff indicates that no button is hold
- down. 0xfe sequences are sometimes interrupted by 0xFF */
-
- dprintk(2,"key %02x\n", b);
-
- if (b == 0xff)
- return 0;
-
- if (b == 0xfe)
- /* keep old data */
- return 1;
-
- *ir_key = b;
- *ir_raw = b;
- return 1;
-}
-
-static int get_key_avermedia_cardbus(struct IR_i2c *ir,
- u32 *ir_key, u32 *ir_raw)
-{
- unsigned char subaddr, key, keygroup;
- struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0,
- .buf = &subaddr, .len = 1},
- { .addr = ir->c->addr, .flags = I2C_M_RD,
- .buf = &key, .len = 1} };
- subaddr = 0x0d;
- if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
- dprintk(1, "read error\n");
- return -EIO;
- }
-
- if (key == 0xff)
- return 0;
-
- subaddr = 0x0b;
- msg[1].buf = &keygroup;
- if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
- dprintk(1, "read error\n");
- return -EIO;
- }
-
- if (keygroup == 0xff)
- return 0;
-
- dprintk(1, "read key 0x%02x/0x%02x\n", key, keygroup);
- if (keygroup < 2 || keygroup > 3) {
- /* Only a warning */
- dprintk(1, "warning: invalid key group 0x%02x for key 0x%02x\n",
- keygroup, key);
- }
- key |= (keygroup & 1) << 6;
-
- *ir_key = key;
- *ir_raw = key;
- return 1;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int ir_key_poll(struct IR_i2c *ir)
-{
- static u32 ir_key, ir_raw;
- int rc;
-
- dprintk(3, "%s\n", __func__);
- rc = ir->get_key(ir, &ir_key, &ir_raw);
- if (rc < 0) {
- dprintk(2,"error\n");
- return rc;
- }
-
- if (rc) {
- dprintk(1, "%s: keycode = 0x%04x\n", __func__, ir_key);
- rc_keydown(ir->rc, ir_key, 0);
- }
- return 0;
-}
-
-static void ir_work(struct work_struct *work)
-{
- int rc;
- struct IR_i2c *ir = container_of(work, struct IR_i2c, work.work);
-
- rc = ir_key_poll(ir);
- if (rc == -ENODEV) {
- rc_unregister_device(ir->rc);
- ir->rc = NULL;
- return;
- }
-
- schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling_interval));
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
- char *ir_codes = NULL;
- const char *name = NULL;
- u64 rc_type = RC_TYPE_UNKNOWN;
- struct IR_i2c *ir;
- struct rc_dev *rc = NULL;
- struct i2c_adapter *adap = client->adapter;
- unsigned short addr = client->addr;
- int err;
-
- ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
- if (!ir)
- return -ENOMEM;
-
- ir->c = client;
- ir->polling_interval = DEFAULT_POLLING_INTERVAL;
- i2c_set_clientdata(client, ir);
-
- switch(addr) {
- case 0x64:
- name = "Pixelview";
- ir->get_key = get_key_pixelview;
- rc_type = RC_TYPE_OTHER;
- ir_codes = RC_MAP_EMPTY;
- break;
- case 0x18:
- case 0x1f:
- case 0x1a:
- name = "Hauppauge";
- ir->get_key = get_key_haup;
- rc_type = RC_TYPE_RC5;
- ir_codes = RC_MAP_HAUPPAUGE;
- break;
- case 0x30:
- name = "KNC One";
- ir->get_key = get_key_knc1;
- rc_type = RC_TYPE_OTHER;
- ir_codes = RC_MAP_EMPTY;
- break;
- case 0x6b:
- name = "FusionHDTV";
- ir->get_key = get_key_fusionhdtv;
- rc_type = RC_TYPE_RC5;
- ir_codes = RC_MAP_FUSIONHDTV_MCE;
- break;
- case 0x40:
- name = "AVerMedia Cardbus remote";
- ir->get_key = get_key_avermedia_cardbus;
- rc_type = RC_TYPE_OTHER;
- ir_codes = RC_MAP_AVERMEDIA_CARDBUS;
- break;
- case 0x71:
- name = "Hauppauge/Zilog Z8";
- ir->get_key = get_key_haup_xvr;
- rc_type = RC_TYPE_RC5;
- ir_codes = RC_MAP_HAUPPAUGE;
- break;
- }
-
- /* Let the caller override settings */
- if (client->dev.platform_data) {
- const struct IR_i2c_init_data *init_data =
- client->dev.platform_data;
-
- ir_codes = init_data->ir_codes;
- rc = init_data->rc_dev;
-
- name = init_data->name;
- if (init_data->type)
- rc_type = init_data->type;
-
- if (init_data->polling_interval)
- ir->polling_interval = init_data->polling_interval;
-
- switch (init_data->internal_get_key_func) {
- case IR_KBD_GET_KEY_CUSTOM:
- /* The bridge driver provided us its own function */
- ir->get_key = init_data->get_key;
- break;
- case IR_KBD_GET_KEY_PIXELVIEW:
- ir->get_key = get_key_pixelview;
- break;
- case IR_KBD_GET_KEY_HAUP:
- ir->get_key = get_key_haup;
- break;
- case IR_KBD_GET_KEY_KNC1:
- ir->get_key = get_key_knc1;
- break;
- case IR_KBD_GET_KEY_FUSIONHDTV:
- ir->get_key = get_key_fusionhdtv;
- break;
- case IR_KBD_GET_KEY_HAUP_XVR:
- ir->get_key = get_key_haup_xvr;
- break;
- case IR_KBD_GET_KEY_AVERMEDIA_CARDBUS:
- ir->get_key = get_key_avermedia_cardbus;
- break;
- }
- }
-
- if (!rc) {
- /*
- * If platform_data doesn't specify rc_dev, initilize it
- * internally
- */
- rc = rc_allocate_device();
- if (!rc) {
- err = -ENOMEM;
- goto err_out_free;
- }
- }
- ir->rc = rc;
-
- /* Make sure we are all setup before going on */
- if (!name || !ir->get_key || !rc_type || !ir_codes) {
- dprintk(1, ": Unsupported device at address 0x%02x\n",
- addr);
- err = -ENODEV;
- goto err_out_free;
- }
-
- /* Sets name */
- snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name);
- ir->ir_codes = ir_codes;
-
- snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
- dev_name(&adap->dev),
- dev_name(&client->dev));
-
- /*
- * Initialize input_dev fields
- * It doesn't make sense to allow overriding them via platform_data
- */
- rc->input_id.bustype = BUS_I2C;
- rc->input_phys = ir->phys;
- rc->input_name = ir->name;
-
- /*
- * Initialize the other fields of rc_dev
- */
- rc->map_name = ir->ir_codes;
- rc->allowed_protos = rc_type;
- if (!rc->driver_name)
- rc->driver_name = MODULE_NAME;
-
- err = rc_register_device(rc);
- if (err)
- goto err_out_free;
-
- printk(MODULE_NAME ": %s detected at %s [%s]\n",
- ir->name, ir->phys, adap->name);
-
- /* start polling via eventd */
- INIT_DELAYED_WORK(&ir->work, ir_work);
- schedule_delayed_work(&ir->work, 0);
-
- return 0;
-
- err_out_free:
- /* Only frees rc if it were allocated internally */
- rc_free_device(rc);
- kfree(ir);
- return err;
-}
-
-static int ir_remove(struct i2c_client *client)
-{
- struct IR_i2c *ir = i2c_get_clientdata(client);
-
- /* kill outstanding polls */
- cancel_delayed_work_sync(&ir->work);
-
- /* unregister device */
- if (ir->rc)
- rc_unregister_device(ir->rc);
-
- /* free memory */
- kfree(ir);
- return 0;
-}
-
-static const struct i2c_device_id ir_kbd_id[] = {
- /* Generic entry for any IR receiver */
- { "ir_video", 0 },
- /* IR device specific entries should be added here */
- { "ir_rx_z8f0811_haup", 0 },
- { "ir_rx_z8f0811_hdpvr", 0 },
- { }
-};
-
-static struct i2c_driver ir_kbd_driver = {
- .driver = {
- .name = "ir-kbd-i2c",
- },
- .probe = ir_probe,
- .remove = ir_remove,
- .id_table = ir_kbd_id,
-};
-
-module_i2c_driver(ir_kbd_driver);
-
-/* ----------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller");
-MODULE_DESCRIPTION("input driver for i2c IR remote controls");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig
deleted file mode 100644
index 89f65914cc8..00000000000
--- a/drivers/media/video/ivtv/Kconfig
+++ /dev/null
@@ -1,45 +0,0 @@
-config VIDEO_IVTV
- tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support"
- depends on VIDEO_V4L2 && PCI && I2C
- select I2C_ALGOBIT
- depends on RC_CORE
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- select VIDEO_CX2341X
- select VIDEO_CX25840
- select VIDEO_MSP3400
- select VIDEO_SAA711X
- select VIDEO_SAA717X
- select VIDEO_SAA7127
- select VIDEO_CS53L32A
- select VIDEO_M52790
- select VIDEO_WM8775
- select VIDEO_WM8739
- select VIDEO_VP27SMPX
- select VIDEO_UPD64031A
- select VIDEO_UPD64083
- ---help---
- This is a video4linux driver for Conexant cx23416 or cx23415 based
- PCI personal video recorder devices.
-
- This is used in devices such as the Hauppauge PVR-150/250/350/500
- cards. There is a driver homepage at <http://www.ivtvdriver.org>.
-
- To compile this driver as a module, choose M here: the
- module will be called ivtv.
-
-config VIDEO_FB_IVTV
- tristate "Conexant cx23415 framebuffer support"
- depends on VIDEO_IVTV && FB
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- This is a framebuffer driver for the Conexant cx23415 MPEG
- encoder/decoder.
-
- This is used in the Hauppauge PVR-350 card. There is a driver
- homepage at <http://www.ivtvdriver.org>.
-
- To compile this driver as a module, choose M here: the
- module will be called ivtvfb.
diff --git a/drivers/media/video/ivtv/Makefile b/drivers/media/video/ivtv/Makefile
deleted file mode 100644
index 77de8a45b46..00000000000
--- a/drivers/media/video/ivtv/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-ivtv-objs := ivtv-routing.o ivtv-cards.o ivtv-controls.o \
- ivtv-driver.o ivtv-fileops.o ivtv-firmware.o \
- ivtv-gpio.o ivtv-i2c.o ivtv-ioctl.o ivtv-irq.o \
- ivtv-mailbox.o ivtv-queue.o ivtv-streams.o ivtv-udma.o \
- ivtv-vbi.o ivtv-yuv.o
-
-obj-$(CONFIG_VIDEO_IVTV) += ivtv.o
-obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o
-
-ccflags-y += -I$(srctree)/drivers/media/video
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
-ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
-
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
deleted file mode 100644
index 145e4749a69..00000000000
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ /dev/null
@@ -1,1370 +0,0 @@
-/*
- Functions to query card hardware
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-cards.h"
-#include "ivtv-i2c.h"
-
-#include <media/msp3400.h>
-#include <media/m52790.h>
-#include <media/wm8775.h>
-#include <media/cs53l32a.h>
-#include <media/cx25840.h>
-#include <media/upd64031a.h>
-
-#define MSP_TUNER MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, \
- MSP_DSP_IN_TUNER, MSP_DSP_IN_TUNER)
-#define MSP_SCART1 MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, \
- MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
-#define MSP_SCART2 MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, \
- MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
-#define MSP_SCART3 MSP_INPUT(MSP_IN_SCART3, MSP_IN_TUNER1, \
- MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
-#define MSP_MONO MSP_INPUT(MSP_IN_MONO, MSP_IN_TUNER1, \
- MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
-
-#define V4L2_STD_PAL_SECAM (V4L2_STD_PAL|V4L2_STD_SECAM)
-
-/* usual i2c tuner addresses to probe */
-static struct ivtv_card_tuner_i2c ivtv_i2c_std = {
- .radio = { I2C_CLIENT_END },
- .demod = { 0x43, I2C_CLIENT_END },
- .tv = { 0x61, 0x60, I2C_CLIENT_END },
-};
-
-/* as above, but with possible radio tuner */
-static struct ivtv_card_tuner_i2c ivtv_i2c_radio = {
- .radio = { 0x60, I2C_CLIENT_END },
- .demod = { 0x43, I2C_CLIENT_END },
- .tv = { 0x61, I2C_CLIENT_END },
-};
-
-/* using the tda8290+75a combo */
-static struct ivtv_card_tuner_i2c ivtv_i2c_tda8290 = {
- .radio = { I2C_CLIENT_END },
- .demod = { I2C_CLIENT_END },
- .tv = { 0x4b, I2C_CLIENT_END },
-};
-
-/********************** card configuration *******************************/
-
-/* Please add new PCI IDs to: http://pci-ids.ucw.cz/
- This keeps the PCI ID database up to date. Note that the entries
- must be added under vendor 0x4444 (Conexant) as subsystem IDs.
- New vendor IDs should still be added to the vendor ID list. */
-
-/* Hauppauge PVR-250 cards */
-
-/* Note: for Hauppauge cards the tveeprom information is used instead of PCI IDs */
-static const struct ivtv_card ivtv_card_pvr250 = {
- .type = IVTV_CARD_PVR_250,
- .name = "Hauppauge WinTV PVR-250",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115,
- .hw_audio = IVTV_HW_MSP34XX,
- .hw_audio_ctrl = IVTV_HW_MSP34XX,
- .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 |
- IVTV_HW_TVEEPROM | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
- { IVTV_CARD_INPUT_SVIDEO2, 2, IVTV_SAA71XX_SVIDEO1 },
- { IVTV_CARD_INPUT_COMPOSITE2, 2, IVTV_SAA71XX_COMPOSITE1 },
- { IVTV_CARD_INPUT_COMPOSITE3, 1, IVTV_SAA71XX_COMPOSITE5 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, MSP_SCART1 },
- { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 },
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Hauppauge PVR-350 cards */
-
-/* Outputs for Hauppauge PVR350 cards */
-static struct ivtv_card_output ivtv_pvr350_outputs[] = {
- {
- .name = "S-Video + Composite",
- .video_output = 0,
- }, {
- .name = "Composite",
- .video_output = 1,
- }, {
- .name = "S-Video",
- .video_output = 2,
- }, {
- .name = "RGB",
- .video_output = 3,
- }, {
- .name = "YUV C",
- .video_output = 4,
- }, {
- .name = "YUV V",
- .video_output = 5,
- }
-};
-
-static const struct ivtv_card ivtv_card_pvr350 = {
- .type = IVTV_CARD_PVR_350,
- .name = "Hauppauge WinTV PVR-350",
- .v4l2_capabilities = IVTV_CAP_ENCODER | IVTV_CAP_DECODER,
- .video_outputs = ivtv_pvr350_outputs,
- .nof_outputs = ARRAY_SIZE(ivtv_pvr350_outputs),
- .hw_video = IVTV_HW_SAA7115,
- .hw_audio = IVTV_HW_MSP34XX,
- .hw_audio_ctrl = IVTV_HW_MSP34XX,
- .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 |
- IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER |
- IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
- { IVTV_CARD_INPUT_SVIDEO2, 2, IVTV_SAA71XX_SVIDEO1 },
- { IVTV_CARD_INPUT_COMPOSITE2, 2, IVTV_SAA71XX_COMPOSITE1 },
- { IVTV_CARD_INPUT_COMPOSITE3, 1, IVTV_SAA71XX_COMPOSITE5 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, MSP_SCART1 },
- { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 },
- .i2c = &ivtv_i2c_std,
-};
-
-/* PVR-350 V1 boards have a different audio tuner input and use a
- saa7114 instead of a saa7115.
- Note that the info below comes from a pre-production model so it may
- not be correct. Especially the audio behaves strangely (mono only it seems) */
-static const struct ivtv_card ivtv_card_pvr350_v1 = {
- .type = IVTV_CARD_PVR_350_V1,
- .name = "Hauppauge WinTV PVR-350 (V1)",
- .v4l2_capabilities = IVTV_CAP_ENCODER | IVTV_CAP_DECODER,
- .video_outputs = ivtv_pvr350_outputs,
- .nof_outputs = ARRAY_SIZE(ivtv_pvr350_outputs),
- .hw_video = IVTV_HW_SAA7114,
- .hw_audio = IVTV_HW_MSP34XX,
- .hw_audio_ctrl = IVTV_HW_MSP34XX,
- .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7114 |
- IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
- { IVTV_CARD_INPUT_SVIDEO2, 2, IVTV_SAA71XX_SVIDEO1 },
- { IVTV_CARD_INPUT_COMPOSITE2, 2, IVTV_SAA71XX_COMPOSITE1 },
- { IVTV_CARD_INPUT_COMPOSITE3, 1, IVTV_SAA71XX_COMPOSITE5 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, MSP_MONO },
- { IVTV_CARD_INPUT_LINE_IN1, MSP_SCART1 },
- { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 },
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Hauppauge PVR-150/PVR-500 cards */
-
-static const struct ivtv_card ivtv_card_pvr150 = {
- .type = IVTV_CARD_PVR_150,
- .name = "Hauppauge WinTV PVR-150",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_muxer = IVTV_HW_WM8775,
- .hw_all = IVTV_HW_WM8775 | IVTV_HW_CX25840 |
- IVTV_HW_TVEEPROM | IVTV_HW_TUNER |
- IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT |
- IVTV_HW_Z8F0811_IR_HAUP,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE7 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO1 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE3 },
- { IVTV_CARD_INPUT_SVIDEO2, 2, CX25840_SVIDEO2 },
- { IVTV_CARD_INPUT_COMPOSITE2, 2, CX25840_COMPOSITE4 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER,
- CX25840_AUDIO8, WM8775_AIN2 },
- { IVTV_CARD_INPUT_LINE_IN1,
- CX25840_AUDIO_SERIAL, WM8775_AIN2 },
- { IVTV_CARD_INPUT_LINE_IN2,
- CX25840_AUDIO_SERIAL, WM8775_AIN3 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER,
- CX25840_AUDIO_SERIAL, WM8775_AIN4 },
- /* apparently needed for the IR blaster */
- .gpio_init = { .direction = 0x1f01, .initial_value = 0x26f3 },
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* AVerMedia M179 cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_m179[] = {
- { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_AVERMEDIA, 0xa3cf },
- { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_AVERMEDIA, 0xa3ce },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_m179 = {
- .type = IVTV_CARD_M179,
- .name = "AVerMedia M179",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7114,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7114 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- },
- .gpio_init = { .direction = 0xe380, .initial_value = 0x8290 },
- .gpio_audio_input = { .mask = 0x8040, .tuner = 0x8000, .linein = 0x0000 },
- .gpio_audio_mute = { .mask = 0x2000, .mute = 0x2000 },
- .gpio_audio_mode = { .mask = 0x4300, .mono = 0x4000, .stereo = 0x0200,
- .lang1 = 0x0200, .lang2 = 0x0100, .both = 0x0000 },
- .gpio_audio_freq = { .mask = 0x0018, .f32000 = 0x0000,
- .f44100 = 0x0008, .f48000 = 0x0010 },
- .gpio_audio_detect = { .mask = 0x4000, .stereo = 0x0000 },
- .tuners = {
- /* As far as we know all M179 cards use this tuner */
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_NTSC },
- },
- .pci_list = ivtv_pci_m179,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Yuan MPG600/Kuroutoshikou ITVC16-STVLP cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_mpg600[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0xfff3 },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0xffff },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_mpg600 = {
- .type = IVTV_CARD_MPG600,
- .name = "Yuan MPG600, Kuroutoshikou ITVC16-STVLP",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- },
- .gpio_init = { .direction = 0x3080, .initial_value = 0x0004 },
- .gpio_audio_input = { .mask = 0x3000, .tuner = 0x0000, .linein = 0x2000 },
- .gpio_audio_mute = { .mask = 0x0001, .mute = 0x0001 },
- .gpio_audio_mode = { .mask = 0x000e, .mono = 0x0006, .stereo = 0x0004,
- .lang1 = 0x0004, .lang2 = 0x0000, .both = 0x0008 },
- .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 },
- .tuners = {
- /* The PAL tuner is confirmed */
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME },
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
- },
- .pci_list = ivtv_pci_mpg600,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Yuan MPG160/Kuroutoshikou ITVC15-STVLP cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_mpg160[] = {
- { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_YUAN1, 0 },
- { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_IODATA, 0x40a0 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_mpg160 = {
- .type = IVTV_CARD_MPG160,
- .name = "YUAN MPG160, Kuroutoshikou ITVC15-STVLP, I/O Data GV-M2TV/PCI",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7114,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7114 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- },
- .gpio_init = { .direction = 0x7080, .initial_value = 0x400c },
- .gpio_audio_input = { .mask = 0x3000, .tuner = 0x0000, .linein = 0x2000 },
- .gpio_audio_mute = { .mask = 0x0001, .mute = 0x0001 },
- .gpio_audio_mode = { .mask = 0x000e, .mono = 0x0006, .stereo = 0x0004,
- .lang1 = 0x0004, .lang2 = 0x0000, .both = 0x0008 },
- .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 },
- .tuners = {
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME },
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
- },
- .pci_list = ivtv_pci_mpg160,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Yuan PG600/Diamond PVR-550 cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_pg600[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_DIAMONDMM, 0x0070 },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN3, 0x0600 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_pg600 = {
- .type = IVTV_CARD_PG600,
- .name = "Yuan PG600, Diamond PVR-550",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1,
- CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
- },
- .tuners = {
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME },
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
- },
- .pci_list = ivtv_pci_pg600,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Adaptec VideOh! AVC-2410 card */
-
-static const struct ivtv_card_pci_info ivtv_pci_avc2410[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ADAPTEC, 0x0093 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_avc2410 = {
- .type = IVTV_CARD_AVC2410,
- .name = "Adaptec VideOh! AVC-2410",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115,
- .hw_audio = IVTV_HW_MSP34XX,
- .hw_audio_ctrl = IVTV_HW_MSP34XX,
- .hw_muxer = IVTV_HW_CS53L32A,
- .hw_all = IVTV_HW_MSP34XX | IVTV_HW_CS53L32A |
- IVTV_HW_SAA7115 | IVTV_HW_TUNER |
- IVTV_HW_I2C_IR_RX_ADAPTEC,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER,
- MSP_TUNER, CS53L32A_IN0 },
- { IVTV_CARD_INPUT_LINE_IN1,
- MSP_SCART1, CS53L32A_IN2 },
- },
- /* This card has no eeprom and in fact the Windows driver relies
- on the country/region setting of the user to decide which tuner
- is available. */
- .tuners = {
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
- { .std = V4L2_STD_ALL - V4L2_STD_NTSC_M_JP,
- .tuner = TUNER_PHILIPS_FM1236_MK3 },
- { .std = V4L2_STD_NTSC_M_JP, .tuner = TUNER_PHILIPS_FQ1286 },
- },
- .pci_list = ivtv_pci_avc2410,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Adaptec VideOh! AVC-2010 card */
-
-static const struct ivtv_card_pci_info ivtv_pci_avc2010[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ADAPTEC, 0x0092 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_avc2010 = {
- .type = IVTV_CARD_AVC2010,
- .name = "Adaptec VideOh! AVC-2010",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115,
- .hw_audio = IVTV_HW_CS53L32A,
- .hw_audio_ctrl = IVTV_HW_CS53L32A,
- .hw_all = IVTV_HW_CS53L32A | IVTV_HW_SAA7115,
- .video_inputs = {
- { IVTV_CARD_INPUT_SVIDEO1, 0, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 0, IVTV_SAA71XX_COMPOSITE3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_LINE_IN1, CS53L32A_IN2 },
- },
- /* Does not have a tuner */
- .pci_list = ivtv_pci_avc2010,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Nagase Transgear 5000TV card */
-
-static const struct ivtv_card_pci_info ivtv_pci_tg5000tv[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xbfff },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_tg5000tv = {
- .type = IVTV_CARD_TG5000TV,
- .name = "Nagase Transgear 5000TV",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7114 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X |
- IVTV_HW_GPIO,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7114 | IVTV_HW_TUNER |
- IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO2 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO2 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- },
- .gr_config = UPD64031A_VERTICAL_EXTERNAL,
- .gpio_init = { .direction = 0xe080, .initial_value = 0x8000 },
- .gpio_audio_input = { .mask = 0x8080, .tuner = 0x8000, .linein = 0x0080 },
- .gpio_audio_mute = { .mask = 0x6000, .mute = 0x6000 },
- .gpio_audio_mode = { .mask = 0x4300, .mono = 0x4000, .stereo = 0x0200,
- .lang1 = 0x0300, .lang2 = 0x0000, .both = 0x0200 },
- .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000,
- .composite = 0x0010, .svideo = 0x0020 },
- .tuners = {
- { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
- },
- .pci_list = ivtv_pci_tg5000tv,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* AOpen VA2000MAX-SNT6 card */
-
-static const struct ivtv_card_pci_info ivtv_pci_va2000[] = {
- { PCI_DEVICE_ID_IVTV16, 0, 0xff5f },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_va2000 = {
- .type = IVTV_CARD_VA2000MAX_SNT6,
- .name = "AOpen VA2000MAX-SNT6",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115 | IVTV_HW_UPD6408X,
- .hw_audio = IVTV_HW_MSP34XX,
- .hw_audio_ctrl = IVTV_HW_MSP34XX,
- .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 |
- IVTV_HW_UPD6408X | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER },
- },
- .tuners = {
- { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
- },
- .pci_list = ivtv_pci_va2000,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Yuan MPG600GR/Kuroutoshikou CX23416GYC-STVLP cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_cx23416gyc[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0x0600 },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN4, 0x0600 },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_MELCO, 0x0523 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_cx23416gyc = {
- .type = IVTV_CARD_CX23416GYC,
- .name = "Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA717X | IVTV_HW_GPIO |
- IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
- .hw_audio = IVTV_HW_SAA717X,
- .hw_audio_ctrl = IVTV_HW_SAA717X,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA717X | IVTV_HW_TUNER |
- IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO3 |
- IVTV_SAA717X_TUNER_FLAG },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN2 },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN0 },
- },
- .gr_config = UPD64031A_VERTICAL_EXTERNAL,
- .gpio_init = { .direction = 0xf880, .initial_value = 0x8800 },
- .gpio_video_input = { .mask = 0x0020, .tuner = 0x0000,
- .composite = 0x0020, .svideo = 0x0020 },
- .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
- .f44100 = 0x4000, .f48000 = 0x8000 },
- .tuners = {
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
- },
- .pci_list = ivtv_pci_cx23416gyc,
- .i2c = &ivtv_i2c_std,
-};
-
-static const struct ivtv_card ivtv_card_cx23416gyc_nogr = {
- .type = IVTV_CARD_CX23416GYC_NOGR,
- .name = "Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR)",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA717X | IVTV_HW_GPIO | IVTV_HW_UPD6408X,
- .hw_audio = IVTV_HW_SAA717X,
- .hw_audio_ctrl = IVTV_HW_SAA717X,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA717X | IVTV_HW_TUNER |
- IVTV_HW_UPD6408X,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 |
- IVTV_SAA717X_TUNER_FLAG },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN2 },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN0 },
- },
- .gpio_init = { .direction = 0xf880, .initial_value = 0x8800 },
- .gpio_video_input = { .mask = 0x0020, .tuner = 0x0000,
- .composite = 0x0020, .svideo = 0x0020 },
- .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
- .f44100 = 0x4000, .f48000 = 0x8000 },
- .tuners = {
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
- },
- .i2c = &ivtv_i2c_std,
-};
-
-static const struct ivtv_card ivtv_card_cx23416gyc_nogrycs = {
- .type = IVTV_CARD_CX23416GYC_NOGRYCS,
- .name = "Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR/YCS)",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA717X | IVTV_HW_GPIO,
- .hw_audio = IVTV_HW_SAA717X,
- .hw_audio_ctrl = IVTV_HW_SAA717X,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA717X | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 |
- IVTV_SAA717X_TUNER_FLAG },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN2 },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN0 },
- },
- .gpio_init = { .direction = 0xf880, .initial_value = 0x8800 },
- .gpio_video_input = { .mask = 0x0020, .tuner = 0x0000,
- .composite = 0x0020, .svideo = 0x0020 },
- .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
- .f44100 = 0x4000, .f48000 = 0x8000 },
- .tuners = {
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
- },
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* I/O Data GV-MVP/RX & GV-MVP/RX2W (dual tuner) cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_gv_mvprx[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd01e },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd038 }, /* 2W unit #1 */
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd039 }, /* 2W unit #2 */
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_gv_mvprx = {
- .type = IVTV_CARD_GV_MVPRX,
- .name = "I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner)",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_WM8739,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_VP27SMPX |
- IVTV_HW_TUNER | IVTV_HW_WM8739 |
- IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO1 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO2 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- },
- .gpio_init = { .direction = 0xc301, .initial_value = 0x0200 },
- .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 },
- .tuners = {
- /* This card has the Panasonic VP27 tuner */
- { .std = V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 },
- },
- .pci_list = ivtv_pci_gv_mvprx,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* I/O Data GV-MVP/RX2E card */
-
-static const struct ivtv_card_pci_info ivtv_pci_gv_mvprx2e[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd025 },
- {0, 0, 0}
-};
-
-static const struct ivtv_card ivtv_card_gv_mvprx2e = {
- .type = IVTV_CARD_GV_MVPRX2E,
- .name = "I/O Data GV-MVP/RX2E",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_WM8739,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER |
- IVTV_HW_VP27SMPX | IVTV_HW_WM8739,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- },
- .gpio_init = { .direction = 0xc301, .initial_value = 0x0200 },
- .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 },
- .tuners = {
- /* This card has the Panasonic VP27 tuner */
- { .std = V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 },
- },
- .pci_list = ivtv_pci_gv_mvprx2e,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* GotVIEW PCI DVD card */
-
-static const struct ivtv_card_pci_info ivtv_pci_gotview_pci_dvd[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0x0600 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_gotview_pci_dvd = {
- .type = IVTV_CARD_GOTVIEW_PCI_DVD,
- .name = "GotView PCI DVD",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA717X,
- .hw_audio = IVTV_HW_SAA717X,
- .hw_audio_ctrl = IVTV_HW_SAA717X,
- .hw_all = IVTV_HW_SAA717X | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE1 }, /* pin 116 */
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, /* pin 114/109 */
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 }, /* pin 118 */
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN0 },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN2 },
- },
- .gpio_init = { .direction = 0xf000, .initial_value = 0xA000 },
- .tuners = {
- /* This card has a Philips FQ1216ME MK3 tuner */
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
- },
- .pci_list = ivtv_pci_gotview_pci_dvd,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* GotVIEW PCI DVD2 Deluxe card */
-
-static const struct ivtv_card_pci_info ivtv_pci_gotview_pci_dvd2[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_GOTVIEW1, 0x0600 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_gotview_pci_dvd2 = {
- .type = IVTV_CARD_GOTVIEW_PCI_DVD2,
- .name = "GotView PCI DVD2 Deluxe",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_muxer = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1,
- CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, 0 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
- .gpio_init = { .direction = 0x0800, .initial_value = 0 },
- .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 },
- .tuners = {
- /* This card has a Philips FQ1216ME MK5 tuner */
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
- },
- .pci_list = ivtv_pci_gotview_pci_dvd2,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Yuan MPC622 miniPCI card */
-
-static const struct ivtv_card_pci_info ivtv_pci_yuan_mpc622[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN2, 0xd998 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_yuan_mpc622 = {
- .type = IVTV_CARD_YUAN_MPC622,
- .name = "Yuan MPC622",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1,
- CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
- },
- .gpio_init = { .direction = 0x00ff, .initial_value = 0x0002 },
- .tuners = {
- /* This card has the TDA8290/TDA8275 tuner chips */
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_TDA8290 },
- },
- .pci_list = ivtv_pci_yuan_mpc622,
- .i2c = &ivtv_i2c_tda8290,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* DIGITAL COWBOY DCT-MTVP1 card */
-
-static const struct ivtv_card_pci_info ivtv_pci_dctmvtvp1[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xbfff },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_dctmvtvp1 = {
- .type = IVTV_CARD_DCTMTVP1,
- .name = "Digital Cowboy DCT-MTVP1",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X |
- IVTV_HW_GPIO,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER |
- IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO2 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO2 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- },
- .gpio_init = { .direction = 0xe080, .initial_value = 0x8000 },
- .gpio_audio_input = { .mask = 0x8080, .tuner = 0x8000, .linein = 0x0080 },
- .gpio_audio_mute = { .mask = 0x6000, .mute = 0x6000 },
- .gpio_audio_mode = { .mask = 0x4300, .mono = 0x4000, .stereo = 0x0200,
- .lang1 = 0x0300, .lang2 = 0x0000, .both = 0x0200 },
- .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000,
- .composite = 0x0010, .svideo = 0x0020},
- .tuners = {
- { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
- },
- .pci_list = ivtv_pci_dctmvtvp1,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Yuan PG600-2/GotView PCI DVD Lite cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_pg600v2[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN3, 0x0600 },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_GOTVIEW2, 0x0600 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_pg600v2 = {
- .type = IVTV_CARD_PG600V2,
- .name = "Yuan PG600-2, GotView PCI DVD Lite",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
- /* XC2028 support apparently works for the Yuan, it's still
- uncertain whether it also works with the GotView. */
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1,
- CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- .xceive_pin = 12,
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .pci_list = ivtv_pci_pg600v2,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Club3D ZAP-TV1x01 cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_club3d[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN3, 0x0600 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_club3d = {
- .type = IVTV_CARD_CLUB3D,
- .name = "Club3D ZAP-TV1x01",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1,
- CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- .xceive_pin = 12,
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .pci_list = ivtv_pci_club3d,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* AVerTV MCE 116 Plus (M116) card */
-
-static const struct ivtv_card_pci_info ivtv_pci_avertv_mce116[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc439 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_avertv_mce116 = {
- .type = IVTV_CARD_AVERTV_MCE116,
- .name = "AVerTV MCE 116 Plus",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739 |
- IVTV_HW_I2C_IR_RX_AVER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- /* enable line-in */
- .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 },
- .xceive_pin = 10,
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .pci_list = ivtv_pci_avertv_mce116,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* AVerMedia PVR-150 Plus / AVerTV M113 cards with a Daewoo/Partsnic Tuner */
-
-static const struct ivtv_card_pci_info ivtv_pci_aver_pvr150[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc034 }, /* NTSC */
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc035 }, /* NTSC FM */
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_aver_pvr150 = {
- .type = IVTV_CARD_AVER_PVR150PLUS,
- .name = "AVerMedia PVR-150 Plus / AVerTV M113 Partsnic (Daewoo) Tuner",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_muxer = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER |
- IVTV_HW_WM8739 | IVTV_HW_GPIO,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, 0 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
- /* The 74HC4052 Dual 4:1 multiplexer is controlled by 2 GPIO lines */
- .gpio_init = { .direction = 0xc000, .initial_value = 0 },
- .gpio_audio_input = { .mask = 0xc000,
- .tuner = 0x0000,
- .linein = 0x4000,
- .radio = 0x8000 },
- .tuners = {
- /* Subsystem ID's 0xc03[45] have a Partsnic PTI-5NF05 tuner */
- { .std = V4L2_STD_MN, .tuner = TUNER_PARTSNIC_PTI_5NF05 },
- },
- .pci_list = ivtv_pci_aver_pvr150,
- /* Subsystem ID 0xc035 has a TEA5767(?) FM tuner, 0xc034 does not */
- .i2c = &ivtv_i2c_radio,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* AVerMedia UltraTV 1500 MCE (newer non-cx88 version, M113 variant) card */
-
-static const struct ivtv_card_pci_info ivtv_pci_aver_ultra1500mce[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 }, /* NTSC */
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc01b }, /* PAL/SECAM */
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_aver_ultra1500mce = {
- .type = IVTV_CARD_AVER_ULTRA1500MCE,
- .name = "AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner",
- .comment = "For non-NTSC tuners, use the pal= or secam= module options",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_muxer = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER |
- IVTV_HW_WM8739 | IVTV_HW_GPIO,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, 0 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
- /* The 74HC4052 Dual 4:1 multiplexer is controlled by 2 GPIO lines */
- .gpio_init = { .direction = 0xc000, .initial_value = 0 },
- .gpio_audio_input = { .mask = 0xc000,
- .tuner = 0x0000,
- .linein = 0x4000,
- .radio = 0x8000 },
- .tuners = {
- /* The UltraTV 1500 MCE has a Philips FM1236 MK5 TV/FM tuner */
- { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 },
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216MK5 },
- },
- .pci_list = ivtv_pci_aver_ultra1500mce,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* AVerMedia EZMaker PCI Deluxe card */
-
-static const struct ivtv_card_pci_info ivtv_pci_aver_ezmaker[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc03f },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_aver_ezmaker = {
- .type = IVTV_CARD_AVER_EZMAKER,
- .name = "AVerMedia EZMaker PCI Deluxe",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_WM8739,
- .video_inputs = {
- { IVTV_CARD_INPUT_SVIDEO1, 0, CX25840_SVIDEO3 },
- { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 0 },
- },
- .gpio_init = { .direction = 0x4000, .initial_value = 0x4000 },
- /* Does not have a tuner */
- .pci_list = ivtv_pci_aver_ezmaker,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* ASUS Falcon2 */
-
-static const struct ivtv_card_pci_info ivtv_pci_asus_falcon2[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ASUSTEK, 0x4b66 },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ASUSTEK, 0x462e },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ASUSTEK, 0x4b2e },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_asus_falcon2 = {
- .type = IVTV_CARD_ASUS_FALCON2,
- .name = "ASUS Falcon2",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_muxer = IVTV_HW_M52790,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_M52790 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
- { IVTV_CARD_INPUT_COMPOSITE1, 2, CX25840_COMPOSITE2 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, M52790_IN_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL,
- M52790_IN_V2 | M52790_SW1_YCMIX | M52790_SW2_YCMIX },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, M52790_IN_V2 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, M52790_IN_TUNER },
- .tuners = {
- { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 },
- },
- .pci_list = ivtv_pci_asus_falcon2,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* AVerMedia M104 miniPCI card */
-
-static const struct ivtv_card_pci_info ivtv_pci_aver_m104[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc136 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_aver_m104 = {
- .type = IVTV_CARD_AVER_M104,
- .name = "AVerMedia M104",
- .comment = "Not yet supported!\n",
- .v4l2_capabilities = 0, /*IVTV_CAP_ENCODER,*/
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739,
- .video_inputs = {
- { IVTV_CARD_INPUT_SVIDEO1, 0, CX25840_SVIDEO3 },
- { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
- /* enable line-in + reset tuner */
- .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 },
- .xceive_pin = 10,
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .pci_list = ivtv_pci_aver_m104,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Buffalo PC-MV5L/PCI cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_buffalo[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_MELCO, 0x052b },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_buffalo = {
- .type = IVTV_CARD_BUFFALO_MV5L,
- .name = "Buffalo PC-MV5L/PCI",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1,
- CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
- },
- .xceive_pin = 12,
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .pci_list = ivtv_pci_buffalo,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-/* Sony Kikyou */
-
-static const struct ivtv_card_pci_info ivtv_pci_kikyou[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_SONY, 0x813d },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_kikyou = {
- .type = IVTV_CARD_KIKYOU,
- .name = "Sony VAIO Giga Pocket (ENX Kikyou)",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE1 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE1 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- { IVTV_CARD_INPUT_LINE_IN2, IVTV_GPIO_LINE_IN },
- },
- .gpio_init = { .direction = 0x03e1, .initial_value = 0x0320 },
- .gpio_audio_input = { .mask = 0x0060,
- .tuner = 0x0020,
- .linein = 0x0000,
- .radio = 0x0060 },
- .gpio_audio_mute = { .mask = 0x0000,
- .mute = 0x0000 }, /* 0x200? Disable for now. */
- .gpio_audio_mode = { .mask = 0x0080,
- .mono = 0x0000,
- .stereo = 0x0000, /* SAP */
- .lang1 = 0x0080,
- .lang2 = 0x0000,
- .both = 0x0080 },
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_SONY_BTF_PXN01Z },
- },
- .pci_list = ivtv_pci_kikyou,
- .i2c = &ivtv_i2c_std,
-};
-
-
-static const struct ivtv_card *ivtv_card_list[] = {
- &ivtv_card_pvr250,
- &ivtv_card_pvr350,
- &ivtv_card_pvr150,
- &ivtv_card_m179,
- &ivtv_card_mpg600,
- &ivtv_card_mpg160,
- &ivtv_card_pg600,
- &ivtv_card_avc2410,
- &ivtv_card_avc2010,
- &ivtv_card_tg5000tv,
- &ivtv_card_va2000,
- &ivtv_card_cx23416gyc,
- &ivtv_card_gv_mvprx,
- &ivtv_card_gv_mvprx2e,
- &ivtv_card_gotview_pci_dvd,
- &ivtv_card_gotview_pci_dvd2,
- &ivtv_card_yuan_mpc622,
- &ivtv_card_dctmvtvp1,
- &ivtv_card_pg600v2,
- &ivtv_card_club3d,
- &ivtv_card_avertv_mce116,
- &ivtv_card_asus_falcon2,
- &ivtv_card_aver_pvr150,
- &ivtv_card_aver_ezmaker,
- &ivtv_card_aver_m104,
- &ivtv_card_buffalo,
- &ivtv_card_aver_ultra1500mce,
- &ivtv_card_kikyou,
-
- /* Variations of standard cards but with the same PCI IDs.
- These cards must come last in this list. */
- &ivtv_card_pvr350_v1,
- &ivtv_card_cx23416gyc_nogr,
- &ivtv_card_cx23416gyc_nogrycs,
-};
-
-const struct ivtv_card *ivtv_get_card(u16 index)
-{
- if (index >= ARRAY_SIZE(ivtv_card_list))
- return NULL;
- return ivtv_card_list[index];
-}
-
-int ivtv_get_input(struct ivtv *itv, u16 index, struct v4l2_input *input)
-{
- const struct ivtv_card_video_input *card_input = itv->card->video_inputs + index;
- static const char * const input_strs[] = {
- "Tuner 1",
- "S-Video 1",
- "S-Video 2",
- "Composite 1",
- "Composite 2",
- "Composite 3"
- };
-
- if (index >= itv->nof_inputs)
- return -EINVAL;
- input->index = index;
- strlcpy(input->name, input_strs[card_input->video_type - 1],
- sizeof(input->name));
- input->type = (card_input->video_type == IVTV_CARD_INPUT_VID_TUNER ?
- V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA);
- input->audioset = (1 << itv->nof_audio_inputs) - 1;
- input->std = (input->type == V4L2_INPUT_TYPE_TUNER) ?
- itv->tuner_std : V4L2_STD_ALL;
- return 0;
-}
-
-int ivtv_get_output(struct ivtv *itv, u16 index, struct v4l2_output *output)
-{
- const struct ivtv_card_output *card_output = itv->card->video_outputs + index;
-
- if (index >= itv->card->nof_outputs)
- return -EINVAL;
- output->index = index;
- strlcpy(output->name, card_output->name, sizeof(output->name));
- output->type = V4L2_OUTPUT_TYPE_ANALOG;
- output->audioset = 1;
- output->std = V4L2_STD_ALL;
- return 0;
-}
-
-int ivtv_get_audio_input(struct ivtv *itv, u16 index, struct v4l2_audio *audio)
-{
- const struct ivtv_card_audio_input *aud_input = itv->card->audio_inputs + index;
- static const char * const input_strs[] = {
- "Tuner 1",
- "Line In 1",
- "Line In 2"
- };
-
- memset(audio, 0, sizeof(*audio));
- if (index >= itv->nof_audio_inputs)
- return -EINVAL;
- strlcpy(audio->name, input_strs[aud_input->audio_type - 1],
- sizeof(audio->name));
- audio->index = index;
- audio->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
-int ivtv_get_audio_output(struct ivtv *itv, u16 index, struct v4l2_audioout *aud_output)
-{
- memset(aud_output, 0, sizeof(*aud_output));
- if (itv->card->video_outputs == NULL || index != 0)
- return -EINVAL;
- strlcpy(aud_output->name, "A/V Audio Out", sizeof(aud_output->name));
- return 0;
-}
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
deleted file mode 100644
index e6f5c02981f..00000000000
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- Functions to query card hardware
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_CARDS_H
-#define IVTV_CARDS_H
-
-/* Supported cards */
-#define IVTV_CARD_PVR_250 0 /* WinTV PVR 250 */
-#define IVTV_CARD_PVR_350 1 /* encoder, decoder, tv-out */
-#define IVTV_CARD_PVR_150 2 /* WinTV PVR 150 and PVR 500 (really just two
- PVR150s on one PCI board) */
-#define IVTV_CARD_M179 3 /* AVerMedia M179 (encoder only) */
-#define IVTV_CARD_MPG600 4 /* Kuroutoshikou ITVC16-STVLP/YUAN MPG600, encoder only */
-#define IVTV_CARD_MPG160 5 /* Kuroutoshikou ITVC15-STVLP/YUAN MPG160
- cx23415 based, but does not have tv-out */
-#define IVTV_CARD_PG600 6 /* YUAN PG600/DIAMONDMM PVR-550 based on the CX Falcon 2 */
-#define IVTV_CARD_AVC2410 7 /* Adaptec AVC-2410 */
-#define IVTV_CARD_AVC2010 8 /* Adaptec AVD-2010 (No Tuner) */
-#define IVTV_CARD_TG5000TV 9 /* NAGASE TRANSGEAR 5000TV, encoder only */
-#define IVTV_CARD_VA2000MAX_SNT6 10 /* VA2000MAX-STN6 */
-#define IVTV_CARD_CX23416GYC 11 /* Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
-#define IVTV_CARD_GV_MVPRX 12 /* I/O Data GV-MVP/RX, RX2, RX2W */
-#define IVTV_CARD_GV_MVPRX2E 13 /* I/O Data GV-MVP/RX2E */
-#define IVTV_CARD_GOTVIEW_PCI_DVD 14 /* GotView PCI DVD */
-#define IVTV_CARD_GOTVIEW_PCI_DVD2 15 /* GotView PCI DVD2 */
-#define IVTV_CARD_YUAN_MPC622 16 /* Yuan MPC622 miniPCI */
-#define IVTV_CARD_DCTMTVP1 17 /* DIGITAL COWBOY DCT-MTVP1 */
-#define IVTV_CARD_PG600V2 18 /* Yuan PG600V2/GotView PCI DVD Lite */
-#define IVTV_CARD_CLUB3D 19 /* Club3D ZAP-TV1x01 */
-#define IVTV_CARD_AVERTV_MCE116 20 /* AVerTV MCE 116 Plus */
-#define IVTV_CARD_ASUS_FALCON2 21 /* ASUS Falcon2 */
-#define IVTV_CARD_AVER_PVR150PLUS 22 /* AVerMedia PVR-150 Plus */
-#define IVTV_CARD_AVER_EZMAKER 23 /* AVerMedia EZMaker PCI Deluxe */
-#define IVTV_CARD_AVER_M104 24 /* AverMedia M104 miniPCI card */
-#define IVTV_CARD_BUFFALO_MV5L 25 /* Buffalo PC-MV5L/PCI card */
-#define IVTV_CARD_AVER_ULTRA1500MCE 26 /* AVerMedia UltraTV 1500 MCE */
-#define IVTV_CARD_KIKYOU 27 /* Sony VAIO Giga Pocket (ENX Kikyou) */
-#define IVTV_CARD_LAST 27
-
-/* Variants of existing cards but with the same PCI IDs. The driver
- detects these based on other device information.
- These cards must always come last.
- New cards must be inserted above, and the indices of the cards below
- must be adjusted accordingly. */
-
-/* PVR-350 V1 (uses saa7114) */
-#define IVTV_CARD_PVR_350_V1 (IVTV_CARD_LAST+1)
-/* 2 variants of Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
-#define IVTV_CARD_CX23416GYC_NOGR (IVTV_CARD_LAST+2)
-#define IVTV_CARD_CX23416GYC_NOGRYCS (IVTV_CARD_LAST+3)
-
-/* system vendor and device IDs */
-#define PCI_VENDOR_ID_ICOMP 0x4444
-#define PCI_DEVICE_ID_IVTV15 0x0803
-#define PCI_DEVICE_ID_IVTV16 0x0016
-
-/* subsystem vendor ID */
-#define IVTV_PCI_ID_HAUPPAUGE 0x0070
-#define IVTV_PCI_ID_HAUPPAUGE_ALT1 0x0270
-#define IVTV_PCI_ID_HAUPPAUGE_ALT2 0x4070
-#define IVTV_PCI_ID_ADAPTEC 0x9005
-#define IVTV_PCI_ID_ASUSTEK 0x1043
-#define IVTV_PCI_ID_AVERMEDIA 0x1461
-#define IVTV_PCI_ID_YUAN1 0x12ab
-#define IVTV_PCI_ID_YUAN2 0xff01
-#define IVTV_PCI_ID_YUAN3 0xffab
-#define IVTV_PCI_ID_YUAN4 0xfbab
-#define IVTV_PCI_ID_DIAMONDMM 0xff92
-#define IVTV_PCI_ID_IODATA 0x10fc
-#define IVTV_PCI_ID_MELCO 0x1154
-#define IVTV_PCI_ID_GOTVIEW1 0xffac
-#define IVTV_PCI_ID_GOTVIEW2 0xffad
-#define IVTV_PCI_ID_SONY 0x104d
-
-/* hardware flags, no gaps allowed */
-#define IVTV_HW_CX25840 (1 << 0)
-#define IVTV_HW_SAA7115 (1 << 1)
-#define IVTV_HW_SAA7127 (1 << 2)
-#define IVTV_HW_MSP34XX (1 << 3)
-#define IVTV_HW_TUNER (1 << 4)
-#define IVTV_HW_WM8775 (1 << 5)
-#define IVTV_HW_CS53L32A (1 << 6)
-#define IVTV_HW_TVEEPROM (1 << 7)
-#define IVTV_HW_SAA7114 (1 << 8)
-#define IVTV_HW_UPD64031A (1 << 9)
-#define IVTV_HW_UPD6408X (1 << 10)
-#define IVTV_HW_SAA717X (1 << 11)
-#define IVTV_HW_WM8739 (1 << 12)
-#define IVTV_HW_VP27SMPX (1 << 13)
-#define IVTV_HW_M52790 (1 << 14)
-#define IVTV_HW_GPIO (1 << 15)
-#define IVTV_HW_I2C_IR_RX_AVER (1 << 16)
-#define IVTV_HW_I2C_IR_RX_HAUP_EXT (1 << 17) /* External before internal */
-#define IVTV_HW_I2C_IR_RX_HAUP_INT (1 << 18)
-#define IVTV_HW_Z8F0811_IR_TX_HAUP (1 << 19)
-#define IVTV_HW_Z8F0811_IR_RX_HAUP (1 << 20)
-#define IVTV_HW_I2C_IR_RX_ADAPTEC (1 << 21)
-
-#define IVTV_HW_Z8F0811_IR_HAUP (IVTV_HW_Z8F0811_IR_RX_HAUP | \
- IVTV_HW_Z8F0811_IR_TX_HAUP)
-
-#define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114)
-
-#define IVTV_HW_IR_RX_ANY (IVTV_HW_I2C_IR_RX_AVER | \
- IVTV_HW_I2C_IR_RX_HAUP_EXT | \
- IVTV_HW_I2C_IR_RX_HAUP_INT | \
- IVTV_HW_Z8F0811_IR_RX_HAUP | \
- IVTV_HW_I2C_IR_RX_ADAPTEC)
-
-#define IVTV_HW_IR_TX_ANY (IVTV_HW_Z8F0811_IR_TX_HAUP)
-
-#define IVTV_HW_IR_ANY (IVTV_HW_IR_RX_ANY | IVTV_HW_IR_TX_ANY)
-
-/* video inputs */
-#define IVTV_CARD_INPUT_VID_TUNER 1
-#define IVTV_CARD_INPUT_SVIDEO1 2
-#define IVTV_CARD_INPUT_SVIDEO2 3
-#define IVTV_CARD_INPUT_COMPOSITE1 4
-#define IVTV_CARD_INPUT_COMPOSITE2 5
-#define IVTV_CARD_INPUT_COMPOSITE3 6
-
-/* audio inputs */
-#define IVTV_CARD_INPUT_AUD_TUNER 1
-#define IVTV_CARD_INPUT_LINE_IN1 2
-#define IVTV_CARD_INPUT_LINE_IN2 3
-
-#define IVTV_CARD_MAX_VIDEO_INPUTS 6
-#define IVTV_CARD_MAX_AUDIO_INPUTS 3
-#define IVTV_CARD_MAX_TUNERS 3
-
-/* SAA71XX HW inputs */
-#define IVTV_SAA71XX_COMPOSITE0 0
-#define IVTV_SAA71XX_COMPOSITE1 1
-#define IVTV_SAA71XX_COMPOSITE2 2
-#define IVTV_SAA71XX_COMPOSITE3 3
-#define IVTV_SAA71XX_COMPOSITE4 4
-#define IVTV_SAA71XX_COMPOSITE5 5
-#define IVTV_SAA71XX_SVIDEO0 6
-#define IVTV_SAA71XX_SVIDEO1 7
-#define IVTV_SAA71XX_SVIDEO2 8
-#define IVTV_SAA71XX_SVIDEO3 9
-
-/* SAA717X needs to mark the tuner input by ORing with this flag */
-#define IVTV_SAA717X_TUNER_FLAG 0x80
-
-/* Dummy HW input */
-#define IVTV_DUMMY_AUDIO 0
-
-/* GPIO HW inputs */
-#define IVTV_GPIO_TUNER 0
-#define IVTV_GPIO_LINE_IN 1
-
-/* SAA717X HW inputs */
-#define IVTV_SAA717X_IN0 0
-#define IVTV_SAA717X_IN1 1
-#define IVTV_SAA717X_IN2 2
-
-/* V4L2 capability aliases */
-#define IVTV_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
- V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \
- V4L2_CAP_SLICED_VBI_CAPTURE)
-#define IVTV_CAP_DECODER (V4L2_CAP_VIDEO_OUTPUT | \
- V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
-
-struct ivtv_card_video_input {
- u8 video_type; /* video input type */
- u8 audio_index; /* index in ivtv_card_audio_input array */
- u16 video_input; /* hardware video input */
-};
-
-struct ivtv_card_audio_input {
- u8 audio_type; /* audio input type */
- u32 audio_input; /* hardware audio input */
- u16 muxer_input; /* hardware muxer input for boards with a
- multiplexer chip */
-};
-
-struct ivtv_card_output {
- u8 name[32];
- u16 video_output; /* hardware video output */
-};
-
-struct ivtv_card_pci_info {
- u16 device;
- u16 subsystem_vendor;
- u16 subsystem_device;
-};
-
-/* GPIO definitions */
-
-/* The mask is the set of bits used by the operation */
-
-struct ivtv_gpio_init { /* set initial GPIO DIR and OUT values */
- u16 direction; /* DIR setting. Leave to 0 if no init is needed */
- u16 initial_value;
-};
-
-struct ivtv_gpio_video_input { /* select tuner/line in input */
- u16 mask; /* leave to 0 if not supported */
- u16 tuner;
- u16 composite;
- u16 svideo;
-};
-
-struct ivtv_gpio_audio_input { /* select tuner/line in input */
- u16 mask; /* leave to 0 if not supported */
- u16 tuner;
- u16 linein;
- u16 radio;
-};
-
-struct ivtv_gpio_audio_mute {
- u16 mask; /* leave to 0 if not supported */
- u16 mute; /* set this value to mute, 0 to unmute */
-};
-
-struct ivtv_gpio_audio_mode {
- u16 mask; /* leave to 0 if not supported */
- u16 mono; /* set audio to mono */
- u16 stereo; /* set audio to stereo */
- u16 lang1; /* set audio to the first language */
- u16 lang2; /* set audio to the second language */
- u16 both; /* both languages are output */
-};
-
-struct ivtv_gpio_audio_freq {
- u16 mask; /* leave to 0 if not supported */
- u16 f32000;
- u16 f44100;
- u16 f48000;
-};
-
-struct ivtv_gpio_audio_detect {
- u16 mask; /* leave to 0 if not supported */
- u16 stereo; /* if the input matches this value then
- stereo is detected */
-};
-
-struct ivtv_card_tuner {
- v4l2_std_id std; /* standard for which the tuner is suitable */
- int tuner; /* tuner ID (from tuner.h) */
-};
-
-struct ivtv_card_tuner_i2c {
- unsigned short radio[2];/* radio tuner i2c address to probe */
- unsigned short demod[2];/* demodulator i2c address to probe */
- unsigned short tv[4]; /* tv tuner i2c addresses to probe */
-};
-
-/* for card information/parameters */
-struct ivtv_card {
- int type;
- char *name;
- char *comment;
- u32 v4l2_capabilities;
- u32 hw_video; /* hardware used to process video */
- u32 hw_audio; /* hardware used to process audio */
- u32 hw_audio_ctrl; /* hardware used for the V4L2 controls (only 1 dev allowed) */
- u32 hw_muxer; /* hardware used to multiplex audio input */
- u32 hw_all; /* all hardware used by the board */
- struct ivtv_card_video_input video_inputs[IVTV_CARD_MAX_VIDEO_INPUTS];
- struct ivtv_card_audio_input audio_inputs[IVTV_CARD_MAX_AUDIO_INPUTS];
- struct ivtv_card_audio_input radio_input;
- int nof_outputs;
- const struct ivtv_card_output *video_outputs;
- u8 gr_config; /* config byte for the ghost reduction device */
- u8 xceive_pin; /* XCeive tuner GPIO reset pin */
-
- /* GPIO card-specific settings */
- struct ivtv_gpio_init gpio_init;
- struct ivtv_gpio_video_input gpio_video_input;
- struct ivtv_gpio_audio_input gpio_audio_input;
- struct ivtv_gpio_audio_mute gpio_audio_mute;
- struct ivtv_gpio_audio_mode gpio_audio_mode;
- struct ivtv_gpio_audio_freq gpio_audio_freq;
- struct ivtv_gpio_audio_detect gpio_audio_detect;
-
- struct ivtv_card_tuner tuners[IVTV_CARD_MAX_TUNERS];
- struct ivtv_card_tuner_i2c *i2c;
-
- /* list of device and subsystem vendor/devices that
- correspond to this card type. */
- const struct ivtv_card_pci_info *pci_list;
-};
-
-int ivtv_get_input(struct ivtv *itv, u16 index, struct v4l2_input *input);
-int ivtv_get_output(struct ivtv *itv, u16 index, struct v4l2_output *output);
-int ivtv_get_audio_input(struct ivtv *itv, u16 index, struct v4l2_audio *input);
-int ivtv_get_audio_output(struct ivtv *itv, u16 index, struct v4l2_audioout *output);
-const struct ivtv_card *ivtv_get_card(u16 index);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
deleted file mode 100644
index c60424601cb..00000000000
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- ioctl control functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-ioctl.h"
-#include "ivtv-controls.h"
-#include "ivtv-mailbox.h"
-
-static int ivtv_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt)
-{
- struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl);
-
- /* First try to allocate sliced VBI buffers if needed. */
- if (fmt && itv->vbi.sliced_mpeg_data[0] == NULL) {
- int i;
-
- for (i = 0; i < IVTV_VBI_FRAMES; i++) {
- /* Yuck, hardcoded. Needs to be a define */
- itv->vbi.sliced_mpeg_data[i] = kmalloc(2049, GFP_KERNEL);
- if (itv->vbi.sliced_mpeg_data[i] == NULL) {
- while (--i >= 0) {
- kfree(itv->vbi.sliced_mpeg_data[i]);
- itv->vbi.sliced_mpeg_data[i] = NULL;
- }
- return -ENOMEM;
- }
- }
- }
-
- itv->vbi.insert_mpeg = fmt;
-
- if (itv->vbi.insert_mpeg == 0) {
- return 0;
- }
- /* Need sliced data for mpeg insertion */
- if (ivtv_get_service_set(itv->vbi.sliced_in) == 0) {
- if (itv->is_60hz)
- itv->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525;
- else
- itv->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
- ivtv_expand_service_set(itv->vbi.sliced_in, itv->is_50hz);
- }
- return 0;
-}
-
-static int ivtv_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val)
-{
- struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl);
- int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
- struct v4l2_mbus_framefmt fmt;
-
- /* fix videodecoder resolution */
- fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1);
- fmt.height = cxhdl->height;
- fmt.code = V4L2_MBUS_FMT_FIXED;
- v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &fmt);
- return 0;
-}
-
-static int ivtv_s_audio_sampling_freq(struct cx2341x_handler *cxhdl, u32 idx)
-{
- static const u32 freqs[3] = { 44100, 48000, 32000 };
- struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl);
-
- /* The audio clock of the digitizer must match the codec sample
- rate otherwise you get some very strange effects. */
- if (idx < ARRAY_SIZE(freqs))
- ivtv_call_all(itv, audio, s_clock_freq, freqs[idx]);
- return 0;
-}
-
-static int ivtv_s_audio_mode(struct cx2341x_handler *cxhdl, u32 val)
-{
- struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl);
-
- itv->dualwatch_stereo_mode = val;
- return 0;
-}
-
-struct cx2341x_handler_ops ivtv_cxhdl_ops = {
- .s_audio_mode = ivtv_s_audio_mode,
- .s_audio_sampling_freq = ivtv_s_audio_sampling_freq,
- .s_video_encoding = ivtv_s_video_encoding,
- .s_stream_vbi_fmt = ivtv_s_stream_vbi_fmt,
-};
-
-int ivtv_g_pts_frame(struct ivtv *itv, s64 *pts, s64 *frame)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
-
- if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
- *pts = (s64)((u64)itv->last_dec_timing[2] << 32) |
- (u64)itv->last_dec_timing[1];
- *frame = itv->last_dec_timing[0];
- return 0;
- }
- *pts = 0;
- *frame = 0;
- if (atomic_read(&itv->decoding)) {
- if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
- IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
- return -EIO;
- }
- memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
- set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
- *pts = (s64)((u64) data[2] << 32) | (u64) data[1];
- *frame = data[0];
- /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
- }
- return 0;
-}
-
-static int ivtv_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct ivtv *itv = container_of(ctrl->handler, struct ivtv, cxhdl.hdl);
-
- switch (ctrl->id) {
- /* V4L2_CID_MPEG_VIDEO_DEC_PTS and V4L2_CID_MPEG_VIDEO_DEC_FRAME
- control cluster */
- case V4L2_CID_MPEG_VIDEO_DEC_PTS:
- return ivtv_g_pts_frame(itv, &itv->ctrl_pts->val64,
- &itv->ctrl_frame->val64);
- }
- return 0;
-}
-
-static int ivtv_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct ivtv *itv = container_of(ctrl->handler, struct ivtv, cxhdl.hdl);
-
- switch (ctrl->id) {
- /* V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK and MULTILINGUAL_PLAYBACK
- control cluster */
- case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
- itv->audio_stereo_mode = itv->ctrl_audio_playback->val - 1;
- itv->audio_bilingual_mode = itv->ctrl_audio_multilingual_playback->val - 1;
- ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
- break;
- }
- return 0;
-}
-
-const struct v4l2_ctrl_ops ivtv_hdl_out_ops = {
- .s_ctrl = ivtv_s_ctrl,
- .g_volatile_ctrl = ivtv_g_volatile_ctrl,
-};
diff --git a/drivers/media/video/ivtv/ivtv-controls.h b/drivers/media/video/ivtv/ivtv-controls.h
deleted file mode 100644
index 3999e635831..00000000000
--- a/drivers/media/video/ivtv/ivtv-controls.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- ioctl control functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_CONTROLS_H
-#define IVTV_CONTROLS_H
-
-extern struct cx2341x_handler_ops ivtv_cxhdl_ops;
-extern const struct v4l2_ctrl_ops ivtv_hdl_out_ops;
-int ivtv_g_pts_frame(struct ivtv *itv, s64 *pts, s64 *frame);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
deleted file mode 100644
index 5462ce2f60e..00000000000
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ /dev/null
@@ -1,1498 +0,0 @@
-/*
- ivtv driver initialization and card probing
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* Main Driver file for the ivtv project:
- * Driver for the Conexant CX23415/CX23416 chip.
- * Author: Kevin Thayer (nufan_wfk at yahoo.com)
- * License: GPL
- * http://www.ivtvdriver.org
- *
- * -----
- * MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com>
- * and Takeru KOMORIYA<komoriya@paken.org>
- *
- * AVerMedia M179 GPIO info by Chris Pinkham <cpinkham@bc2va.org>
- * using information provided by Jiun-Kuei Jung @ AVerMedia.
- *
- * Kurouto Sikou CX23416GYC-STVLP tested by K.Ohta <alpha292@bremen.or.jp>
- * using information from T.Adachi,Takeru KOMORIYA and others :-)
- *
- * Nagase TRANSGEAR 5000TV, Aopen VA2000MAX-STN6 and I/O data GV-MVP/RX
- * version by T.Adachi. Special thanks Mr.Suzuki
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-version.h"
-#include "ivtv-fileops.h"
-#include "ivtv-i2c.h"
-#include "ivtv-firmware.h"
-#include "ivtv-queue.h"
-#include "ivtv-udma.h"
-#include "ivtv-irq.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-streams.h"
-#include "ivtv-ioctl.h"
-#include "ivtv-cards.h"
-#include "ivtv-vbi.h"
-#include "ivtv-routing.h"
-#include "ivtv-controls.h"
-#include "ivtv-gpio.h"
-#include <linux/dma-mapping.h>
-#include <media/tveeprom.h>
-#include <media/saa7115.h>
-#include <media/v4l2-chip-ident.h>
-#include "tuner-xc2028.h"
-
-/* If you have already X v4l cards, then set this to X. This way
- the device numbers stay matched. Example: you have a WinTV card
- without radio and a PVR-350 with. Normally this would give a
- video1 device together with a radio0 device for the PVR. By
- setting this to 1 you ensure that radio0 is now also radio1. */
-int ivtv_first_minor;
-
-/* add your revision and whatnot here */
-static struct pci_device_id ivtv_pci_tbl[] __devinitdata = {
- {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV15,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV16,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci,ivtv_pci_tbl);
-
-/* ivtv instance counter */
-static atomic_t ivtv_instance = ATOMIC_INIT(0);
-
-/* Parameter declarations */
-static int cardtype[IVTV_MAX_CARDS];
-static int tuner[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1 };
-static int radio[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1 };
-static int i2c_clock_period[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1 };
-
-static unsigned int cardtype_c = 1;
-static unsigned int tuner_c = 1;
-static int radio_c = 1;
-static unsigned int i2c_clock_period_c = 1;
-static char pal[] = "---";
-static char secam[] = "--";
-static char ntsc[] = "-";
-
-/* Buffers */
-
-/* DMA Buffers, Default size in MB allocated */
-#define IVTV_DEFAULT_ENC_MPG_BUFFERS 4
-#define IVTV_DEFAULT_ENC_YUV_BUFFERS 2
-#define IVTV_DEFAULT_ENC_VBI_BUFFERS 1
-/* Exception: size in kB for this stream (MB is overkill) */
-#define IVTV_DEFAULT_ENC_PCM_BUFFERS 320
-#define IVTV_DEFAULT_DEC_MPG_BUFFERS 1
-#define IVTV_DEFAULT_DEC_YUV_BUFFERS 1
-/* Exception: size in kB for this stream (MB is way overkill) */
-#define IVTV_DEFAULT_DEC_VBI_BUFFERS 64
-
-static int enc_mpg_buffers = IVTV_DEFAULT_ENC_MPG_BUFFERS;
-static int enc_yuv_buffers = IVTV_DEFAULT_ENC_YUV_BUFFERS;
-static int enc_vbi_buffers = IVTV_DEFAULT_ENC_VBI_BUFFERS;
-static int enc_pcm_buffers = IVTV_DEFAULT_ENC_PCM_BUFFERS;
-static int dec_mpg_buffers = IVTV_DEFAULT_DEC_MPG_BUFFERS;
-static int dec_yuv_buffers = IVTV_DEFAULT_DEC_YUV_BUFFERS;
-static int dec_vbi_buffers = IVTV_DEFAULT_DEC_VBI_BUFFERS;
-
-static int ivtv_yuv_mode;
-static int ivtv_yuv_threshold = -1;
-static int ivtv_pci_latency = 1;
-
-int ivtv_debug;
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-int ivtv_fw_debug;
-#endif
-
-static int tunertype = -1;
-static int newi2c = -1;
-
-module_param_array(tuner, int, &tuner_c, 0644);
-module_param_array(radio, int, &radio_c, 0644);
-module_param_array(cardtype, int, &cardtype_c, 0644);
-module_param_string(pal, pal, sizeof(pal), 0644);
-module_param_string(secam, secam, sizeof(secam), 0644);
-module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
-module_param_named(debug,ivtv_debug, int, 0644);
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-module_param_named(fw_debug, ivtv_fw_debug, int, 0644);
-#endif
-module_param(ivtv_pci_latency, int, 0644);
-module_param(ivtv_yuv_mode, int, 0644);
-module_param(ivtv_yuv_threshold, int, 0644);
-module_param(ivtv_first_minor, int, 0644);
-
-module_param(enc_mpg_buffers, int, 0644);
-module_param(enc_yuv_buffers, int, 0644);
-module_param(enc_vbi_buffers, int, 0644);
-module_param(enc_pcm_buffers, int, 0644);
-module_param(dec_mpg_buffers, int, 0644);
-module_param(dec_yuv_buffers, int, 0644);
-module_param(dec_vbi_buffers, int, 0644);
-
-module_param(tunertype, int, 0644);
-module_param(newi2c, int, 0644);
-module_param_array(i2c_clock_period, int, &i2c_clock_period_c, 0644);
-
-MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
- "\t\t\tsee tuner.h for values");
-MODULE_PARM_DESC(radio,
- "Enable or disable the radio. Use only if autodetection\n"
- "\t\t\tfails. 0 = disable, 1 = enable");
-MODULE_PARM_DESC(cardtype,
- "Only use this option if your card is not detected properly.\n"
- "\t\tSpecify card type:\n"
- "\t\t\t 1 = WinTV PVR 250\n"
- "\t\t\t 2 = WinTV PVR 350\n"
- "\t\t\t 3 = WinTV PVR-150 or PVR-500\n"
- "\t\t\t 4 = AVerMedia M179\n"
- "\t\t\t 5 = YUAN MPG600/Kuroutoshikou iTVC16-STVLP\n"
- "\t\t\t 6 = YUAN MPG160/Kuroutoshikou iTVC15-STVLP\n"
- "\t\t\t 7 = YUAN PG600/DIAMONDMM PVR-550 (CX Falcon 2)\n"
- "\t\t\t 8 = Adaptec AVC-2410\n"
- "\t\t\t 9 = Adaptec AVC-2010\n"
- "\t\t\t10 = NAGASE TRANSGEAR 5000TV\n"
- "\t\t\t11 = AOpen VA2000MAX-STN6\n"
- "\t\t\t12 = YUAN MPG600GR/Kuroutoshikou CX23416GYC-STVLP\n"
- "\t\t\t13 = I/O Data GV-MVP/RX\n"
- "\t\t\t14 = I/O Data GV-MVP/RX2E\n"
- "\t\t\t15 = GOTVIEW PCI DVD\n"
- "\t\t\t16 = GOTVIEW PCI DVD2 Deluxe\n"
- "\t\t\t17 = Yuan MPC622\n"
- "\t\t\t18 = Digital Cowboy DCT-MTVP1\n"
- "\t\t\t19 = Yuan PG600V2/GotView PCI DVD Lite\n"
- "\t\t\t20 = Club3D ZAP-TV1x01\n"
- "\t\t\t21 = AverTV MCE 116 Plus\n"
- "\t\t\t22 = ASUS Falcon2\n"
- "\t\t\t23 = AverMedia PVR-150 Plus\n"
- "\t\t\t24 = AverMedia EZMaker PCI Deluxe\n"
- "\t\t\t25 = AverMedia M104 (not yet working)\n"
- "\t\t\t26 = Buffalo PC-MV5L/PCI\n"
- "\t\t\t27 = AVerMedia UltraTV 1500 MCE\n"
- "\t\t\t28 = Sony VAIO Giga Pocket (ENX Kikyou)\n"
- "\t\t\t 0 = Autodetect (default)\n"
- "\t\t\t-1 = Ignore this card\n\t\t");
-MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60");
-MODULE_PARM_DESC(secam, "Set SECAM standard: BGH, DK, L, LC");
-MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J (Japan), K (South Korea)");
-MODULE_PARM_DESC(tunertype,
- "Specify tuner type:\n"
- "\t\t\t 0 = tuner for PAL-B/G/H/D/K/I, SECAM-B/G/H/D/K/L/Lc\n"
- "\t\t\t 1 = tuner for NTSC-M/J/K, PAL-M/N/Nc\n"
- "\t\t\t-1 = Autodetect (default)\n");
-MODULE_PARM_DESC(debug,
- "Debug level (bitmask). Default: 0\n"
- "\t\t\t 1/0x0001: warning\n"
- "\t\t\t 2/0x0002: info\n"
- "\t\t\t 4/0x0004: mailbox\n"
- "\t\t\t 8/0x0008: ioctl\n"
- "\t\t\t 16/0x0010: file\n"
- "\t\t\t 32/0x0020: dma\n"
- "\t\t\t 64/0x0040: irq\n"
- "\t\t\t 128/0x0080: decoder\n"
- "\t\t\t 256/0x0100: yuv\n"
- "\t\t\t 512/0x0200: i2c\n"
- "\t\t\t1024/0x0400: high volume\n");
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-MODULE_PARM_DESC(fw_debug,
- "Enable code for debugging firmware problems. Default: 0\n");
-#endif
-MODULE_PARM_DESC(ivtv_pci_latency,
- "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
- "\t\t\tDefault: Yes");
-MODULE_PARM_DESC(ivtv_yuv_mode,
- "Specify the yuv playback mode:\n"
- "\t\t\t0 = interlaced\n\t\t\t1 = progressive\n\t\t\t2 = auto\n"
- "\t\t\tDefault: 0 (interlaced)");
-MODULE_PARM_DESC(ivtv_yuv_threshold,
- "If ivtv_yuv_mode is 2 (auto) then playback content as\n\t\tprogressive if src height <= ivtv_yuvthreshold\n"
- "\t\t\tDefault: 480");
-MODULE_PARM_DESC(enc_mpg_buffers,
- "Encoder MPG Buffers (in MB)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_MPG_BUFFERS));
-MODULE_PARM_DESC(enc_yuv_buffers,
- "Encoder YUV Buffers (in MB)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_YUV_BUFFERS));
-MODULE_PARM_DESC(enc_vbi_buffers,
- "Encoder VBI Buffers (in MB)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_VBI_BUFFERS));
-MODULE_PARM_DESC(enc_pcm_buffers,
- "Encoder PCM buffers (in kB)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_PCM_BUFFERS));
-MODULE_PARM_DESC(dec_mpg_buffers,
- "Decoder MPG buffers (in MB)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_MPG_BUFFERS));
-MODULE_PARM_DESC(dec_yuv_buffers,
- "Decoder YUV buffers (in MB)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_YUV_BUFFERS));
-MODULE_PARM_DESC(dec_vbi_buffers,
- "Decoder VBI buffers (in kB)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_VBI_BUFFERS));
-MODULE_PARM_DESC(newi2c,
- "Use new I2C implementation\n"
- "\t\t\t-1 is autodetect, 0 is off, 1 is on\n"
- "\t\t\tDefault is autodetect");
-MODULE_PARM_DESC(i2c_clock_period,
- "Period of SCL for the I2C bus controlled by the CX23415/6\n"
- "\t\t\tMin: 10 usec (100 kHz), Max: 4500 usec (222 Hz)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_I2C_CLOCK_PERIOD));
-
-MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first card");
-
-MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil");
-MODULE_DESCRIPTION("CX23415/CX23416 driver");
-MODULE_SUPPORTED_DEVICE
- ("CX23415/CX23416 MPEG2 encoder (WinTV PVR-150/250/350/500,\n"
- "\t\t\tYuan MPG series and similar)");
-MODULE_LICENSE("GPL");
-
-MODULE_VERSION(IVTV_VERSION);
-
-void ivtv_clear_irq_mask(struct ivtv *itv, u32 mask)
-{
- itv->irqmask &= ~mask;
- write_reg_sync(itv->irqmask, IVTV_REG_IRQMASK);
-}
-
-void ivtv_set_irq_mask(struct ivtv *itv, u32 mask)
-{
- itv->irqmask |= mask;
- write_reg_sync(itv->irqmask, IVTV_REG_IRQMASK);
-}
-
-int ivtv_set_output_mode(struct ivtv *itv, int mode)
-{
- int old_mode;
-
- spin_lock(&itv->lock);
- old_mode = itv->output_mode;
- if (old_mode == 0)
- itv->output_mode = old_mode = mode;
- spin_unlock(&itv->lock);
- return old_mode;
-}
-
-struct ivtv_stream *ivtv_get_output_stream(struct ivtv *itv)
-{
- switch (itv->output_mode) {
- case OUT_MPG:
- return &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
- case OUT_YUV:
- return &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
- default:
- return NULL;
- }
-}
-
-int ivtv_waitq(wait_queue_head_t *waitq)
-{
- DEFINE_WAIT(wait);
-
- prepare_to_wait(waitq, &wait, TASK_INTERRUPTIBLE);
- schedule();
- finish_wait(waitq, &wait);
- return signal_pending(current) ? -EINTR : 0;
-}
-
-/* Generic utility functions */
-int ivtv_msleep_timeout(unsigned int msecs, int intr)
-{
- int timeout = msecs_to_jiffies(msecs);
-
- do {
- set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
- timeout = schedule_timeout(timeout);
- if (intr) {
- int ret = signal_pending(current);
-
- if (ret)
- return ret;
- }
- } while (timeout);
- return 0;
-}
-
-/* Release ioremapped memory */
-static void ivtv_iounmap(struct ivtv *itv)
-{
- if (itv == NULL)
- return;
-
- /* Release registers memory */
- if (itv->reg_mem != NULL) {
- IVTV_DEBUG_INFO("releasing reg_mem\n");
- iounmap(itv->reg_mem);
- itv->reg_mem = NULL;
- }
- /* Release io memory */
- if (itv->has_cx23415 && itv->dec_mem != NULL) {
- IVTV_DEBUG_INFO("releasing dec_mem\n");
- iounmap(itv->dec_mem);
- }
- itv->dec_mem = NULL;
-
- /* Release io memory */
- if (itv->enc_mem != NULL) {
- IVTV_DEBUG_INFO("releasing enc_mem\n");
- iounmap(itv->enc_mem);
- itv->enc_mem = NULL;
- }
-}
-
-/* Hauppauge card? get values from tveeprom */
-void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv)
-{
- u8 eedata[256];
-
- itv->i2c_client.addr = 0xA0 >> 1;
- tveeprom_read(&itv->i2c_client, eedata, sizeof(eedata));
- tveeprom_hauppauge_analog(&itv->i2c_client, tv, eedata);
-}
-
-static void ivtv_process_eeprom(struct ivtv *itv)
-{
- struct tveeprom tv;
- int pci_slot = PCI_SLOT(itv->pdev->devfn);
-
- ivtv_read_eeprom(itv, &tv);
-
- /* Many thanks to Steven Toth from Hauppauge for providing the
- model numbers */
- switch (tv.model) {
- /* In a few cases the PCI subsystem IDs do not correctly
- identify the card. A better method is to check the
- model number from the eeprom instead. */
- case 30012 ... 30039: /* Low profile PVR250 */
- case 32000 ... 32999:
- case 48000 ... 48099: /* 48??? range are PVR250s with a cx23415 */
- case 48400 ... 48599:
- itv->card = ivtv_get_card(IVTV_CARD_PVR_250);
- break;
- case 48100 ... 48399:
- case 48600 ... 48999:
- itv->card = ivtv_get_card(IVTV_CARD_PVR_350);
- break;
- case 23000 ... 23999: /* PVR500 */
- case 25000 ... 25999: /* Low profile PVR150 */
- case 26000 ... 26999: /* Regular PVR150 */
- itv->card = ivtv_get_card(IVTV_CARD_PVR_150);
- break;
- case 0:
- IVTV_ERR("Invalid EEPROM\n");
- return;
- default:
- IVTV_ERR("Unknown model %d, defaulting to PVR-150\n", tv.model);
- itv->card = ivtv_get_card(IVTV_CARD_PVR_150);
- break;
- }
-
- switch (tv.model) {
- /* Old style PVR350 (with an saa7114) uses this input for
- the tuner. */
- case 48254:
- itv->card = ivtv_get_card(IVTV_CARD_PVR_350_V1);
- break;
- default:
- break;
- }
-
- itv->v4l2_cap = itv->card->v4l2_capabilities;
- itv->card_name = itv->card->name;
- itv->card_i2c = itv->card->i2c;
-
- /* If this is a PVR500 then it should be possible to detect whether it is the
- first or second unit by looking at the subsystem device ID: is bit 4 is
- set, then it is the second unit (according to info from Hauppauge).
-
- However, while this works for most cards, I have seen a few PVR500 cards
- where both units have the same subsystem ID.
-
- So instead I look at the reported 'PCI slot' (which is the slot on the PVR500
- PCI bridge) and if it is 8, then it is assumed to be the first unit, otherwise
- it is the second unit. It is possible that it is a different slot when ivtv is
- used in Xen, in that case I ignore this card here. The worst that can happen
- is that the card presents itself with a non-working radio device.
-
- This detection is needed since the eeprom reports incorrectly that a radio is
- present on the second unit. */
- if (tv.model / 1000 == 23) {
- static const struct ivtv_card_tuner_i2c ivtv_i2c_radio = {
- .radio = { 0x60, I2C_CLIENT_END },
- .demod = { 0x43, I2C_CLIENT_END },
- .tv = { 0x61, I2C_CLIENT_END },
- };
-
- itv->card_name = "WinTV PVR 500";
- itv->card_i2c = &ivtv_i2c_radio;
- if (pci_slot == 8 || pci_slot == 9) {
- int is_first = (pci_slot & 1) == 0;
-
- itv->card_name = is_first ? "WinTV PVR 500 (unit #1)" :
- "WinTV PVR 500 (unit #2)";
- if (!is_first) {
- IVTV_INFO("Correcting tveeprom data: no radio present on second unit\n");
- tv.has_radio = 0;
- }
- }
- }
- IVTV_INFO("Autodetected %s\n", itv->card_name);
-
- switch (tv.tuner_hauppauge_model) {
- case 85:
- case 99:
- case 112:
- itv->pvr150_workaround = 1;
- break;
- default:
- break;
- }
- if (tv.tuner_type == TUNER_ABSENT)
- IVTV_ERR("tveeprom cannot autodetect tuner!\n");
-
- if (itv->options.tuner == -1)
- itv->options.tuner = tv.tuner_type;
- if (itv->options.radio == -1)
- itv->options.radio = (tv.has_radio != 0);
- /* only enable newi2c if an IR blaster is present */
- if (itv->options.newi2c == -1 && tv.has_ir) {
- itv->options.newi2c = (tv.has_ir & 4) ? 1 : 0;
- if (itv->options.newi2c) {
- IVTV_INFO("Reopen i2c bus for IR-blaster support\n");
- exit_ivtv_i2c(itv);
- init_ivtv_i2c(itv);
- }
- }
-
- if (itv->std != 0)
- /* user specified tuner standard */
- return;
-
- /* autodetect tuner standard */
- if (tv.tuner_formats & V4L2_STD_PAL) {
- IVTV_DEBUG_INFO("PAL tuner detected\n");
- itv->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
- } else if (tv.tuner_formats & V4L2_STD_NTSC) {
- IVTV_DEBUG_INFO("NTSC tuner detected\n");
- itv->std |= V4L2_STD_NTSC_M;
- } else if (tv.tuner_formats & V4L2_STD_SECAM) {
- IVTV_DEBUG_INFO("SECAM tuner detected\n");
- itv->std |= V4L2_STD_SECAM_L;
- } else {
- IVTV_INFO("No tuner detected, default to NTSC-M\n");
- itv->std |= V4L2_STD_NTSC_M;
- }
-}
-
-static v4l2_std_id ivtv_parse_std(struct ivtv *itv)
-{
- switch (pal[0]) {
- case '6':
- tunertype = 0;
- return V4L2_STD_PAL_60;
- case 'b':
- case 'B':
- case 'g':
- case 'G':
- case 'h':
- case 'H':
- tunertype = 0;
- return V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
- case 'n':
- case 'N':
- tunertype = 1;
- if (pal[1] == 'c' || pal[1] == 'C')
- return V4L2_STD_PAL_Nc;
- return V4L2_STD_PAL_N;
- case 'i':
- case 'I':
- tunertype = 0;
- return V4L2_STD_PAL_I;
- case 'd':
- case 'D':
- case 'k':
- case 'K':
- tunertype = 0;
- return V4L2_STD_PAL_DK;
- case 'M':
- case 'm':
- tunertype = 1;
- return V4L2_STD_PAL_M;
- case '-':
- break;
- default:
- IVTV_WARN("pal= argument not recognised\n");
- return 0;
- }
-
- switch (secam[0]) {
- case 'b':
- case 'B':
- case 'g':
- case 'G':
- case 'h':
- case 'H':
- tunertype = 0;
- return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
- case 'd':
- case 'D':
- case 'k':
- case 'K':
- tunertype = 0;
- return V4L2_STD_SECAM_DK;
- case 'l':
- case 'L':
- tunertype = 0;
- if (secam[1] == 'C' || secam[1] == 'c')
- return V4L2_STD_SECAM_LC;
- return V4L2_STD_SECAM_L;
- case '-':
- break;
- default:
- IVTV_WARN("secam= argument not recognised\n");
- return 0;
- }
-
- switch (ntsc[0]) {
- case 'm':
- case 'M':
- tunertype = 1;
- return V4L2_STD_NTSC_M;
- case 'j':
- case 'J':
- tunertype = 1;
- return V4L2_STD_NTSC_M_JP;
- case 'k':
- case 'K':
- tunertype = 1;
- return V4L2_STD_NTSC_M_KR;
- case '-':
- break;
- default:
- IVTV_WARN("ntsc= argument not recognised\n");
- return 0;
- }
-
- /* no match found */
- return 0;
-}
-
-static void ivtv_process_options(struct ivtv *itv)
-{
- const char *chipname;
- int i, j;
-
- itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers * 1024;
- itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers * 1024;
- itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers * 1024;
- itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
- itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_MPG] = dec_mpg_buffers * 1024;
- itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_YUV] = dec_yuv_buffers * 1024;
- itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_VBI] = dec_vbi_buffers;
- itv->options.cardtype = cardtype[itv->instance];
- itv->options.tuner = tuner[itv->instance];
- itv->options.radio = radio[itv->instance];
-
- itv->options.i2c_clock_period = i2c_clock_period[itv->instance];
- if (itv->options.i2c_clock_period == -1)
- itv->options.i2c_clock_period = IVTV_DEFAULT_I2C_CLOCK_PERIOD;
- else if (itv->options.i2c_clock_period < 10)
- itv->options.i2c_clock_period = 10;
- else if (itv->options.i2c_clock_period > 4500)
- itv->options.i2c_clock_period = 4500;
-
- itv->options.newi2c = newi2c;
- if (tunertype < -1 || tunertype > 1) {
- IVTV_WARN("Invalid tunertype argument, will autodetect instead\n");
- tunertype = -1;
- }
- itv->std = ivtv_parse_std(itv);
- if (itv->std == 0 && tunertype >= 0)
- itv->std = tunertype ? V4L2_STD_MN : (V4L2_STD_ALL & ~V4L2_STD_MN);
- itv->has_cx23415 = (itv->pdev->device == PCI_DEVICE_ID_IVTV15);
- chipname = itv->has_cx23415 ? "cx23415" : "cx23416";
- if (itv->options.cardtype == -1) {
- IVTV_INFO("Ignore card (detected %s based chip)\n", chipname);
- return;
- }
- if ((itv->card = ivtv_get_card(itv->options.cardtype - 1))) {
- IVTV_INFO("User specified %s card (detected %s based chip)\n",
- itv->card->name, chipname);
- } else if (itv->options.cardtype != 0) {
- IVTV_ERR("Unknown user specified type, trying to autodetect card\n");
- }
- if (itv->card == NULL) {
- if (itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE ||
- itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 ||
- itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) {
- itv->card = ivtv_get_card(itv->has_cx23415 ? IVTV_CARD_PVR_350 : IVTV_CARD_PVR_150);
- IVTV_INFO("Autodetected Hauppauge card (%s based)\n",
- chipname);
- }
- }
- if (itv->card == NULL) {
- for (i = 0; (itv->card = ivtv_get_card(i)); i++) {
- if (itv->card->pci_list == NULL)
- continue;
- for (j = 0; itv->card->pci_list[j].device; j++) {
- if (itv->pdev->device !=
- itv->card->pci_list[j].device)
- continue;
- if (itv->pdev->subsystem_vendor !=
- itv->card->pci_list[j].subsystem_vendor)
- continue;
- if (itv->pdev->subsystem_device !=
- itv->card->pci_list[j].subsystem_device)
- continue;
- IVTV_INFO("Autodetected %s card (%s based)\n",
- itv->card->name, chipname);
- goto done;
- }
- }
- }
-done:
-
- if (itv->card == NULL) {
- itv->card = ivtv_get_card(IVTV_CARD_PVR_150);
- IVTV_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
- itv->pdev->vendor, itv->pdev->device);
- IVTV_ERR(" subsystem vendor/device: [%04x:%04x]\n",
- itv->pdev->subsystem_vendor, itv->pdev->subsystem_device);
- IVTV_ERR(" %s based\n", chipname);
- IVTV_ERR("Defaulting to %s card\n", itv->card->name);
- IVTV_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
- IVTV_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
- IVTV_ERR("Prefix your subject line with [UNKNOWN IVTV CARD].\n");
- }
- itv->v4l2_cap = itv->card->v4l2_capabilities;
- itv->card_name = itv->card->name;
- itv->card_i2c = itv->card->i2c;
-}
-
-/* Precondition: the ivtv structure has been memset to 0. Only
- the dev and num fields have been filled in.
- No assumptions on the card type may be made here (see ivtv_init_struct2
- for that).
- */
-static int __devinit ivtv_init_struct1(struct ivtv *itv)
-{
- struct sched_param param = { .sched_priority = 99 };
-
- itv->base_addr = pci_resource_start(itv->pdev, 0);
- itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */
- itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */
-
- mutex_init(&itv->serialize_lock);
- mutex_init(&itv->i2c_bus_lock);
- mutex_init(&itv->udma.lock);
-
- spin_lock_init(&itv->lock);
- spin_lock_init(&itv->dma_reg_lock);
-
- init_kthread_worker(&itv->irq_worker);
- itv->irq_worker_task = kthread_run(kthread_worker_fn, &itv->irq_worker,
- itv->v4l2_dev.name);
- if (IS_ERR(itv->irq_worker_task)) {
- IVTV_ERR("Could not create ivtv task\n");
- return -1;
- }
- /* must use the FIFO scheduler as it is realtime sensitive */
- sched_setscheduler(itv->irq_worker_task, SCHED_FIFO, &param);
-
- init_kthread_work(&itv->irq_work, ivtv_irq_work_handler);
-
- /* Initial settings */
- itv->cxhdl.port = CX2341X_PORT_MEMORY;
- itv->cxhdl.capabilities = CX2341X_CAP_HAS_SLICED_VBI;
- init_waitqueue_head(&itv->eos_waitq);
- init_waitqueue_head(&itv->event_waitq);
- init_waitqueue_head(&itv->vsync_waitq);
- init_waitqueue_head(&itv->dma_waitq);
- init_timer(&itv->dma_timer);
- itv->dma_timer.function = ivtv_unfinished_dma;
- itv->dma_timer.data = (unsigned long)itv;
-
- itv->cur_dma_stream = -1;
- itv->cur_pio_stream = -1;
-
- /* Ctrls */
- itv->speed = 1000;
-
- /* VBI */
- itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
- itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced;
-
- /* Init the sg table for osd/yuv output */
- sg_init_table(itv->udma.SGlist, IVTV_DMA_SG_OSD_ENT);
-
- /* OSD */
- itv->osd_global_alpha_state = 1;
- itv->osd_global_alpha = 255;
-
- /* YUV */
- atomic_set(&itv->yuv_info.next_dma_frame, -1);
- itv->yuv_info.lace_mode = ivtv_yuv_mode;
- itv->yuv_info.lace_threshold = ivtv_yuv_threshold;
- itv->yuv_info.max_frames_buffered = 3;
- itv->yuv_info.track_osd = 1;
- return 0;
-}
-
-/* Second initialization part. Here the card type has been
- autodetected. */
-static void __devinit ivtv_init_struct2(struct ivtv *itv)
-{
- int i;
-
- for (i = 0; i < IVTV_CARD_MAX_VIDEO_INPUTS; i++)
- if (itv->card->video_inputs[i].video_type == 0)
- break;
- itv->nof_inputs = i;
- for (i = 0; i < IVTV_CARD_MAX_AUDIO_INPUTS; i++)
- if (itv->card->audio_inputs[i].audio_type == 0)
- break;
- itv->nof_audio_inputs = i;
-
- if (itv->card->hw_all & IVTV_HW_CX25840) {
- itv->vbi.sliced_size = 288; /* multiple of 16, real size = 284 */
- } else {
- itv->vbi.sliced_size = 64; /* multiple of 16, real size = 52 */
- }
-
- /* Find tuner input */
- for (i = 0; i < itv->nof_inputs; i++) {
- if (itv->card->video_inputs[i].video_type ==
- IVTV_CARD_INPUT_VID_TUNER)
- break;
- }
- if (i == itv->nof_inputs)
- i = 0;
- itv->active_input = i;
- itv->audio_input = itv->card->video_inputs[i].audio_index;
-}
-
-static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
- const struct pci_device_id *pci_id)
-{
- u16 cmd;
- unsigned char pci_latency;
-
- IVTV_DEBUG_INFO("Enabling pci device\n");
-
- if (pci_enable_device(pdev)) {
- IVTV_ERR("Can't enable device!\n");
- return -EIO;
- }
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
- IVTV_ERR("No suitable DMA available.\n");
- return -EIO;
- }
- if (!request_mem_region(itv->base_addr, IVTV_ENCODER_SIZE, "ivtv encoder")) {
- IVTV_ERR("Cannot request encoder memory region.\n");
- return -EIO;
- }
-
- if (!request_mem_region(itv->base_addr + IVTV_REG_OFFSET,
- IVTV_REG_SIZE, "ivtv registers")) {
- IVTV_ERR("Cannot request register memory region.\n");
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- return -EIO;
- }
-
- if (itv->has_cx23415 &&
- !request_mem_region(itv->base_addr + IVTV_DECODER_OFFSET,
- IVTV_DECODER_SIZE, "ivtv decoder")) {
- IVTV_ERR("Cannot request decoder memory region.\n");
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- return -EIO;
- }
-
- /* Check for bus mastering */
- pci_read_config_word(pdev, PCI_COMMAND, &cmd);
- if (!(cmd & PCI_COMMAND_MASTER)) {
- IVTV_DEBUG_INFO("Attempting to enable Bus Mastering\n");
- pci_set_master(pdev);
- pci_read_config_word(pdev, PCI_COMMAND, &cmd);
- if (!(cmd & PCI_COMMAND_MASTER)) {
- IVTV_ERR("Bus Mastering is not enabled\n");
- return -ENXIO;
- }
- }
- IVTV_DEBUG_INFO("Bus Mastering Enabled.\n");
-
- pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
-
- if (pci_latency < 64 && ivtv_pci_latency) {
- IVTV_INFO("Unreasonably low latency timer, "
- "setting to 64 (was %d)\n", pci_latency);
- pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
- pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
- }
- /* This config space value relates to DMA latencies. The
- default value 0x8080 is too low however and will lead
- to DMA errors. 0xffff is the max value which solves
- these problems. */
- pci_write_config_dword(pdev, 0x40, 0xffff);
-
- IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, "
- "irq: %d, latency: %d, memory: 0x%llx\n",
- pdev->device, pdev->revision, pdev->bus->number,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
- pdev->irq, pci_latency, (u64)itv->base_addr);
-
- return 0;
-}
-
-static void ivtv_load_and_init_modules(struct ivtv *itv)
-{
- u32 hw = itv->card->hw_all;
- unsigned i;
-
- /* check which i2c devices are actually found */
- for (i = 0; i < 32; i++) {
- u32 device = 1 << i;
-
- if (!(device & hw))
- continue;
- if (device == IVTV_HW_GPIO || device == IVTV_HW_TVEEPROM) {
- /* GPIO and TVEEPROM do not use i2c probing */
- itv->hw_flags |= device;
- continue;
- }
- if (ivtv_i2c_register(itv, i) == 0)
- itv->hw_flags |= device;
- }
-
- /* probe for legacy IR controllers that aren't in card definitions */
- if ((itv->hw_flags & IVTV_HW_IR_ANY) == 0)
- ivtv_i2c_new_ir_legacy(itv);
-
- if (itv->card->hw_all & IVTV_HW_CX25840)
- itv->sd_video = ivtv_find_hw(itv, IVTV_HW_CX25840);
- else if (itv->card->hw_all & IVTV_HW_SAA717X)
- itv->sd_video = ivtv_find_hw(itv, IVTV_HW_SAA717X);
- else if (itv->card->hw_all & IVTV_HW_SAA7114)
- itv->sd_video = ivtv_find_hw(itv, IVTV_HW_SAA7114);
- else
- itv->sd_video = ivtv_find_hw(itv, IVTV_HW_SAA7115);
- itv->sd_audio = ivtv_find_hw(itv, itv->card->hw_audio_ctrl);
- itv->sd_muxer = ivtv_find_hw(itv, itv->card->hw_muxer);
-
- hw = itv->hw_flags;
-
- if (itv->card->type == IVTV_CARD_CX23416GYC) {
- /* Several variations of this card exist, detect which card
- type should be used. */
- if ((hw & (IVTV_HW_UPD64031A | IVTV_HW_UPD6408X)) == 0)
- itv->card = ivtv_get_card(IVTV_CARD_CX23416GYC_NOGRYCS);
- else if ((hw & IVTV_HW_UPD64031A) == 0)
- itv->card = ivtv_get_card(IVTV_CARD_CX23416GYC_NOGR);
- }
- else if (itv->card->type == IVTV_CARD_GV_MVPRX ||
- itv->card->type == IVTV_CARD_GV_MVPRX2E) {
- /* The crystal frequency of GVMVPRX is 24.576MHz */
- v4l2_subdev_call(itv->sd_video, video, s_crystal_freq,
- SAA7115_FREQ_24_576_MHZ, SAA7115_FREQ_FL_UCGC);
- }
-
- if (hw & IVTV_HW_CX25840) {
- itv->vbi.raw_decoder_line_size = 1444;
- itv->vbi.raw_decoder_sav_odd_field = 0x20;
- itv->vbi.raw_decoder_sav_even_field = 0x60;
- itv->vbi.sliced_decoder_line_size = 272;
- itv->vbi.sliced_decoder_sav_odd_field = 0xB0;
- itv->vbi.sliced_decoder_sav_even_field = 0xF0;
- }
-
- if (hw & IVTV_HW_SAA711X) {
- struct v4l2_dbg_chip_ident v;
-
- /* determine the exact saa711x model */
- itv->hw_flags &= ~IVTV_HW_SAA711X;
-
- v.match.type = V4L2_CHIP_MATCH_I2C_DRIVER;
- strlcpy(v.match.name, "saa7115", sizeof(v.match.name));
- ivtv_call_hw(itv, IVTV_HW_SAA711X, core, g_chip_ident, &v);
- if (v.ident == V4L2_IDENT_SAA7114) {
- itv->hw_flags |= IVTV_HW_SAA7114;
- /* VBI is not yet supported by the saa7114 driver. */
- itv->v4l2_cap &= ~(V4L2_CAP_SLICED_VBI_CAPTURE|V4L2_CAP_VBI_CAPTURE);
- } else {
- itv->hw_flags |= IVTV_HW_SAA7115;
- }
- itv->vbi.raw_decoder_line_size = 1443;
- itv->vbi.raw_decoder_sav_odd_field = 0x25;
- itv->vbi.raw_decoder_sav_even_field = 0x62;
- itv->vbi.sliced_decoder_line_size = 51;
- itv->vbi.sliced_decoder_sav_odd_field = 0xAB;
- itv->vbi.sliced_decoder_sav_even_field = 0xEC;
- }
-
- if (hw & IVTV_HW_SAA717X) {
- itv->vbi.raw_decoder_line_size = 1443;
- itv->vbi.raw_decoder_sav_odd_field = 0x25;
- itv->vbi.raw_decoder_sav_even_field = 0x62;
- itv->vbi.sliced_decoder_line_size = 51;
- itv->vbi.sliced_decoder_sav_odd_field = 0xAB;
- itv->vbi.sliced_decoder_sav_even_field = 0xEC;
- }
-}
-
-static int __devinit ivtv_probe(struct pci_dev *pdev,
- const struct pci_device_id *pci_id)
-{
- int retval = 0;
- int vbi_buf_size;
- struct ivtv *itv;
-
- itv = kzalloc(sizeof(struct ivtv), GFP_ATOMIC);
- if (itv == NULL)
- return -ENOMEM;
- itv->pdev = pdev;
- itv->instance = v4l2_device_set_name(&itv->v4l2_dev, "ivtv",
- &ivtv_instance);
-
- retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev);
- if (retval) {
- kfree(itv);
- return retval;
- }
- IVTV_INFO("Initializing card %d\n", itv->instance);
-
- ivtv_process_options(itv);
- if (itv->options.cardtype == -1) {
- retval = -ENODEV;
- goto err;
- }
- if (ivtv_init_struct1(itv)) {
- retval = -ENOMEM;
- goto err;
- }
- retval = cx2341x_handler_init(&itv->cxhdl, 50);
- if (retval)
- goto err;
- itv->v4l2_dev.ctrl_handler = &itv->cxhdl.hdl;
- itv->cxhdl.ops = &ivtv_cxhdl_ops;
- itv->cxhdl.priv = itv;
- itv->cxhdl.func = ivtv_api_func;
-
- IVTV_DEBUG_INFO("base addr: 0x%llx\n", (u64)itv->base_addr);
-
- /* PCI Device Setup */
- retval = ivtv_setup_pci(itv, pdev, pci_id);
- if (retval == -EIO)
- goto free_worker;
- if (retval == -ENXIO)
- goto free_mem;
-
- /* map io memory */
- IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n",
- (u64)itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE);
- itv->enc_mem = ioremap_nocache(itv->base_addr + IVTV_ENCODER_OFFSET,
- IVTV_ENCODER_SIZE);
- if (!itv->enc_mem) {
- IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 "
- "encoder memory\n");
- IVTV_ERR("Each capture card with a CX23415/6 needs 8 MB of "
- "vmalloc address space for this window\n");
- IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
- IVTV_ERR("Use the vmalloc= kernel command line option to set "
- "VmallocTotal to a larger value\n");
- retval = -ENOMEM;
- goto free_mem;
- }
-
- if (itv->has_cx23415) {
- IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n",
- (u64)itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
- itv->dec_mem = ioremap_nocache(itv->base_addr + IVTV_DECODER_OFFSET,
- IVTV_DECODER_SIZE);
- if (!itv->dec_mem) {
- IVTV_ERR("ioremap failed. Can't get a window into "
- "CX23415 decoder memory\n");
- IVTV_ERR("Each capture card with a CX23415 needs 8 MB "
- "of vmalloc address space for this window\n");
- IVTV_ERR("Check the output of 'grep Vmalloc "
- "/proc/meminfo'\n");
- IVTV_ERR("Use the vmalloc= kernel command line option "
- "to set VmallocTotal to a larger value\n");
- retval = -ENOMEM;
- goto free_mem;
- }
- }
- else {
- itv->dec_mem = itv->enc_mem;
- }
-
- /* map registers memory */
- IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n",
- (u64)itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- itv->reg_mem =
- ioremap_nocache(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- if (!itv->reg_mem) {
- IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 "
- "register space\n");
- IVTV_ERR("Each capture card with a CX23415/6 needs 64 kB of "
- "vmalloc address space for this window\n");
- IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
- IVTV_ERR("Use the vmalloc= kernel command line option to set "
- "VmallocTotal to a larger value\n");
- retval = -ENOMEM;
- goto free_io;
- }
-
- retval = ivtv_gpio_init(itv);
- if (retval)
- goto free_io;
-
- /* active i2c */
- IVTV_DEBUG_INFO("activating i2c...\n");
- if (init_ivtv_i2c(itv)) {
- IVTV_ERR("Could not initialize i2c\n");
- goto free_io;
- }
-
- if (itv->card->hw_all & IVTV_HW_TVEEPROM) {
- /* Based on the model number the cardtype may be changed.
- The PCI IDs are not always reliable. */
- ivtv_process_eeprom(itv);
- }
- if (itv->card->comment)
- IVTV_INFO("%s", itv->card->comment);
- if (itv->card->v4l2_capabilities == 0) {
- /* card was detected but is not supported */
- retval = -ENODEV;
- goto free_i2c;
- }
-
- if (itv->std == 0) {
- itv->std = V4L2_STD_NTSC_M;
- }
-
- if (itv->options.tuner == -1) {
- int i;
-
- for (i = 0; i < IVTV_CARD_MAX_TUNERS; i++) {
- if ((itv->std & itv->card->tuners[i].std) == 0)
- continue;
- itv->options.tuner = itv->card->tuners[i].tuner;
- break;
- }
- }
- /* if no tuner was found, then pick the first tuner in the card list */
- if (itv->options.tuner == -1 && itv->card->tuners[0].std) {
- itv->std = itv->card->tuners[0].std;
- if (itv->std & V4L2_STD_PAL)
- itv->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
- else if (itv->std & V4L2_STD_NTSC)
- itv->std = V4L2_STD_NTSC_M;
- else if (itv->std & V4L2_STD_SECAM)
- itv->std = V4L2_STD_SECAM_L;
- itv->options.tuner = itv->card->tuners[0].tuner;
- }
- if (itv->options.radio == -1)
- itv->options.radio = (itv->card->radio_input.audio_type != 0);
-
- /* The card is now fully identified, continue with card-specific
- initialization. */
- ivtv_init_struct2(itv);
-
- ivtv_load_and_init_modules(itv);
-
- if (itv->std & V4L2_STD_525_60) {
- itv->is_60hz = 1;
- itv->is_out_60hz = 1;
- } else {
- itv->is_50hz = 1;
- itv->is_out_50hz = 1;
- }
-
- itv->yuv_info.osd_full_w = 720;
- itv->yuv_info.osd_full_h = itv->is_out_50hz ? 576 : 480;
- itv->yuv_info.v4l2_src_w = itv->yuv_info.osd_full_w;
- itv->yuv_info.v4l2_src_h = itv->yuv_info.osd_full_h;
-
- cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
-
- itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_MPG] = 0x08000;
- itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_PCM] = 0x01200;
- itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_MPG] = 0x10000;
- itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_YUV] = 0x10000;
- itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_YUV] = 0x08000;
-
- /* Setup VBI Raw Size. Should be big enough to hold PAL.
- It is possible to switch between PAL and NTSC, so we need to
- take the largest size here. */
- /* 1456 is multiple of 16, real size = 1444 */
- itv->vbi.raw_size = 1456;
- /* We use a buffer size of 1/2 of the total size needed for a
- frame. This is actually very useful, since we now receive
- a field at a time and that makes 'compressing' the raw data
- down to size by stripping off the SAV codes a lot easier.
- Note: having two different buffer sizes prevents standard
- switching on the fly. We need to find a better solution... */
- vbi_buf_size = itv->vbi.raw_size * (itv->is_60hz ? 24 : 36) / 2;
- itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
- itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_VBI] = sizeof(struct v4l2_sliced_vbi_data) * 36;
-
- if (itv->options.radio > 0)
- itv->v4l2_cap |= V4L2_CAP_RADIO;
-
- if (itv->options.tuner > -1) {
- struct tuner_setup setup;
-
- setup.addr = ADDR_UNSET;
- setup.type = itv->options.tuner;
- setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
- if (itv->options.radio > 0)
- setup.mode_mask |= T_RADIO;
- setup.tuner_callback = (setup.type == TUNER_XC2028) ?
- ivtv_reset_tuner_gpio : NULL;
- ivtv_call_all(itv, tuner, s_type_addr, &setup);
- if (setup.type == TUNER_XC2028) {
- static struct xc2028_ctrl ctrl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64,
- };
- struct v4l2_priv_tun_config cfg = {
- .tuner = itv->options.tuner,
- .priv = &ctrl,
- };
- ivtv_call_all(itv, tuner, s_config, &cfg);
- }
- }
-
- /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
- are not. */
- itv->tuner_std = itv->std;
-
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
- struct v4l2_ctrl_handler *hdl = itv->v4l2_dev.ctrl_handler;
-
- itv->ctrl_pts = v4l2_ctrl_new_std(hdl, &ivtv_hdl_out_ops,
- V4L2_CID_MPEG_VIDEO_DEC_PTS, 0, 0, 0, 0);
- itv->ctrl_frame = v4l2_ctrl_new_std(hdl, &ivtv_hdl_out_ops,
- V4L2_CID_MPEG_VIDEO_DEC_FRAME, 0, 0, 0, 0);
- /* Note: V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO is not supported,
- mask that menu item. */
- itv->ctrl_audio_playback =
- v4l2_ctrl_new_std_menu(hdl, &ivtv_hdl_out_ops,
- V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK,
- V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO,
- 1 << V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO,
- V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO);
- itv->ctrl_audio_multilingual_playback =
- v4l2_ctrl_new_std_menu(hdl, &ivtv_hdl_out_ops,
- V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK,
- V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO,
- 1 << V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO,
- V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT);
- if (hdl->error) {
- retval = hdl->error;
- goto free_i2c;
- }
- v4l2_ctrl_cluster(2, &itv->ctrl_pts);
- v4l2_ctrl_cluster(2, &itv->ctrl_audio_playback);
- ivtv_call_all(itv, video, s_std_output, itv->std);
- /* Turn off the output signal. The mpeg decoder is not yet
- active so without this you would get a green image until the
- mpeg decoder becomes active. */
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
- }
-
- /* clear interrupt mask, effectively disabling interrupts */
- ivtv_set_irq_mask(itv, 0xffffffff);
-
- /* Register IRQ */
- retval = request_irq(itv->pdev->irq, ivtv_irq_handler,
- IRQF_SHARED | IRQF_DISABLED, itv->v4l2_dev.name, (void *)itv);
- if (retval) {
- IVTV_ERR("Failed to register irq %d\n", retval);
- goto free_i2c;
- }
-
- retval = ivtv_streams_setup(itv);
- if (retval) {
- IVTV_ERR("Error %d setting up streams\n", retval);
- goto free_irq;
- }
- retval = ivtv_streams_register(itv);
- if (retval) {
- IVTV_ERR("Error %d registering devices\n", retval);
- goto free_streams;
- }
- IVTV_INFO("Initialized card: %s\n", itv->card_name);
- return 0;
-
-free_streams:
- ivtv_streams_cleanup(itv, 1);
-free_irq:
- free_irq(itv->pdev->irq, (void *)itv);
-free_i2c:
- v4l2_ctrl_handler_free(&itv->cxhdl.hdl);
- exit_ivtv_i2c(itv);
-free_io:
- ivtv_iounmap(itv);
-free_mem:
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- if (itv->has_cx23415)
- release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
-free_worker:
- kthread_stop(itv->irq_worker_task);
-err:
- if (retval == 0)
- retval = -ENODEV;
- IVTV_ERR("Error %d on initialization\n", retval);
-
- v4l2_device_unregister(&itv->v4l2_dev);
- kfree(itv);
- return retval;
-}
-
-int ivtv_init_on_first_open(struct ivtv *itv)
-{
- struct v4l2_frequency vf;
- /* Needed to call ioctls later */
- struct ivtv_open_id fh;
- int fw_retry_count = 3;
- int video_input;
-
- fh.itv = itv;
-
- if (test_bit(IVTV_F_I_FAILED, &itv->i_flags))
- return -ENXIO;
-
- if (test_and_set_bit(IVTV_F_I_INITED, &itv->i_flags))
- return 0;
-
- while (--fw_retry_count > 0) {
- /* load firmware */
- if (ivtv_firmware_init(itv) == 0)
- break;
- if (fw_retry_count > 1)
- IVTV_WARN("Retry loading firmware\n");
- }
-
- if (fw_retry_count == 0) {
- set_bit(IVTV_F_I_FAILED, &itv->i_flags);
- return -ENXIO;
- }
-
- /* Try and get firmware versions */
- IVTV_DEBUG_INFO("Getting firmware version..\n");
- ivtv_firmware_versions(itv);
-
- if (itv->card->hw_all & IVTV_HW_CX25840)
- v4l2_subdev_call(itv->sd_video, core, load_fw);
-
- vf.tuner = 0;
- vf.type = V4L2_TUNER_ANALOG_TV;
- vf.frequency = 6400; /* the tuner 'baseline' frequency */
-
- /* Set initial frequency. For PAL/SECAM broadcasts no
- 'default' channel exists AFAIK. */
- if (itv->std == V4L2_STD_NTSC_M_JP) {
- vf.frequency = 1460; /* ch. 1 91250*16/1000 */
- }
- else if (itv->std & V4L2_STD_NTSC_M) {
- vf.frequency = 1076; /* ch. 4 67250*16/1000 */
- }
-
- video_input = itv->active_input;
- itv->active_input++; /* Force update of input */
- ivtv_s_input(NULL, &fh, video_input);
-
- /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
- in one place. */
- itv->std++; /* Force full standard initialization */
- itv->std_out = itv->std;
- ivtv_s_frequency(NULL, &fh, &vf);
-
- if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
- /* Turn on the TV-out: ivtv_init_mpeg_decoder() initializes
- the mpeg decoder so now the saa7127 receives a proper
- signal. */
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
- ivtv_init_mpeg_decoder(itv);
- }
-
- /* On a cx23416 this seems to be able to enable DMA to the chip? */
- if (!itv->has_cx23415)
- write_reg_sync(0x03, IVTV_REG_DMACONTROL);
-
- ivtv_s_std_enc(itv, &itv->tuner_std);
-
- /* Default interrupts enabled. For the PVR350 this includes the
- decoder VSYNC interrupt, which is always on. It is not only used
- during decoding but also by the OSD.
- Some old PVR250 cards had a cx23415, so testing for that is too
- general. Instead test if the card has video output capability. */
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
- ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC);
- ivtv_set_osd_alpha(itv);
- ivtv_s_std_dec(itv, &itv->tuner_std);
- } else {
- ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT);
- }
-
- /* Setup initial controls */
- cx2341x_handler_setup(&itv->cxhdl);
- return 0;
-}
-
-static void ivtv_remove(struct pci_dev *pdev)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
- struct ivtv *itv = to_ivtv(v4l2_dev);
- int i;
-
- IVTV_DEBUG_INFO("Removing card\n");
-
- if (test_bit(IVTV_F_I_INITED, &itv->i_flags)) {
- /* Stop all captures */
- IVTV_DEBUG_INFO("Stopping all streams\n");
- if (atomic_read(&itv->capturing) > 0)
- ivtv_stop_all_captures(itv);
-
- /* Stop all decoding */
- IVTV_DEBUG_INFO("Stopping decoding\n");
-
- /* Turn off the TV-out */
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
- if (atomic_read(&itv->decoding) > 0) {
- int type;
-
- if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
- type = IVTV_DEC_STREAM_TYPE_YUV;
- else
- type = IVTV_DEC_STREAM_TYPE_MPG;
- ivtv_stop_v4l2_decode_stream(&itv->streams[type],
- V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0);
- }
- ivtv_halt_firmware(itv);
- }
-
- /* Interrupts */
- ivtv_set_irq_mask(itv, 0xffffffff);
- del_timer_sync(&itv->dma_timer);
-
- /* Kill irq worker */
- flush_kthread_worker(&itv->irq_worker);
- kthread_stop(itv->irq_worker_task);
-
- ivtv_streams_cleanup(itv, 1);
- ivtv_udma_free(itv);
-
- v4l2_ctrl_handler_free(&itv->cxhdl.hdl);
-
- exit_ivtv_i2c(itv);
-
- free_irq(itv->pdev->irq, (void *)itv);
- ivtv_iounmap(itv);
-
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- if (itv->has_cx23415)
- release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
-
- pci_disable_device(itv->pdev);
- for (i = 0; i < IVTV_VBI_FRAMES; i++)
- kfree(itv->vbi.sliced_mpeg_data[i]);
-
- printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name);
-
- v4l2_device_unregister(&itv->v4l2_dev);
- kfree(itv);
-}
-
-/* define a pci_driver for card detection */
-static struct pci_driver ivtv_pci_driver = {
- .name = "ivtv",
- .id_table = ivtv_pci_tbl,
- .probe = ivtv_probe,
- .remove = ivtv_remove,
-};
-
-static int __init module_start(void)
-{
- printk(KERN_INFO "ivtv: Start initialization, version %s\n", IVTV_VERSION);
-
- /* Validate parameters */
- if (ivtv_first_minor < 0 || ivtv_first_minor >= IVTV_MAX_CARDS) {
- printk(KERN_ERR "ivtv: Exiting, ivtv_first_minor must be between 0 and %d\n",
- IVTV_MAX_CARDS - 1);
- return -1;
- }
-
- if (ivtv_debug < 0 || ivtv_debug > 2047) {
- ivtv_debug = 0;
- printk(KERN_INFO "ivtv: Debug value must be >= 0 and <= 2047\n");
- }
-
- if (pci_register_driver(&ivtv_pci_driver)) {
- printk(KERN_ERR "ivtv: Error detecting PCI card\n");
- return -ENODEV;
- }
- printk(KERN_INFO "ivtv: End initialization\n");
- return 0;
-}
-
-static void __exit module_cleanup(void)
-{
- pci_unregister_driver(&ivtv_pci_driver);
-}
-
-/* Note: These symbols are exported because they are used by the ivtvfb
- framebuffer module and an infrared module for the IR-blaster. */
-EXPORT_SYMBOL(ivtv_set_irq_mask);
-EXPORT_SYMBOL(ivtv_api);
-EXPORT_SYMBOL(ivtv_vapi);
-EXPORT_SYMBOL(ivtv_vapi_result);
-EXPORT_SYMBOL(ivtv_clear_irq_mask);
-EXPORT_SYMBOL(ivtv_debug);
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-EXPORT_SYMBOL(ivtv_fw_debug);
-#endif
-EXPORT_SYMBOL(ivtv_reset_ir_gpio);
-EXPORT_SYMBOL(ivtv_udma_setup);
-EXPORT_SYMBOL(ivtv_udma_unmap);
-EXPORT_SYMBOL(ivtv_udma_alloc);
-EXPORT_SYMBOL(ivtv_udma_prepare);
-EXPORT_SYMBOL(ivtv_init_on_first_open);
-EXPORT_SYMBOL(ivtv_firmware_check);
-
-module_init(module_start);
-module_exit(module_cleanup);
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
deleted file mode 100644
index a7e00f8938f..00000000000
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ /dev/null
@@ -1,839 +0,0 @@
-/*
- ivtv driver internal defines and structures
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_DRIVER_H
-#define IVTV_DRIVER_H
-
-/* Internal header for ivtv project:
- * Driver for the cx23415/6 chip.
- * Author: Kevin Thayer (nufan_wfk at yahoo.com)
- * License: GPL
- * http://www.ivtvdriver.org
- *
- * -----
- * MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com>
- * and Takeru KOMORIYA<komoriya@paken.org>
- *
- * AVerMedia M179 GPIO info by Chris Pinkham <cpinkham@bc2va.org>
- * using information provided by Jiun-Kuei Jung @ AVerMedia.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/list.h>
-#include <linux/unistd.h>
-#include <linux/pagemap.h>
-#include <linux/scatterlist.h>
-#include <linux/kthread.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <asm/uaccess.h>
-#include <asm/byteorder.h>
-
-#include <linux/dvb/video.h>
-#include <linux/dvb/audio.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-fh.h>
-#include <media/tuner.h>
-#include <media/cx2341x.h>
-#include <media/ir-kbd-i2c.h>
-
-#include <linux/ivtv.h>
-
-/* Memory layout */
-#define IVTV_ENCODER_OFFSET 0x00000000
-#define IVTV_ENCODER_SIZE 0x00800000 /* Total size is 0x01000000, but only first half is used */
-#define IVTV_DECODER_OFFSET 0x01000000
-#define IVTV_DECODER_SIZE 0x00800000 /* Total size is 0x01000000, but only first half is used */
-#define IVTV_REG_OFFSET 0x02000000
-#define IVTV_REG_SIZE 0x00010000
-
-/* Maximum ivtv driver instances. Some people have a huge number of
- capture cards, so set this to a high value. */
-#define IVTV_MAX_CARDS 32
-
-#define IVTV_ENC_STREAM_TYPE_MPG 0
-#define IVTV_ENC_STREAM_TYPE_YUV 1
-#define IVTV_ENC_STREAM_TYPE_VBI 2
-#define IVTV_ENC_STREAM_TYPE_PCM 3
-#define IVTV_ENC_STREAM_TYPE_RAD 4
-#define IVTV_DEC_STREAM_TYPE_MPG 5
-#define IVTV_DEC_STREAM_TYPE_VBI 6
-#define IVTV_DEC_STREAM_TYPE_VOUT 7
-#define IVTV_DEC_STREAM_TYPE_YUV 8
-#define IVTV_MAX_STREAMS 9
-
-#define IVTV_DMA_SG_OSD_ENT (2883584/PAGE_SIZE) /* sg entities */
-
-/* DMA Registers */
-#define IVTV_REG_DMAXFER (0x0000)
-#define IVTV_REG_DMASTATUS (0x0004)
-#define IVTV_REG_DECDMAADDR (0x0008)
-#define IVTV_REG_ENCDMAADDR (0x000c)
-#define IVTV_REG_DMACONTROL (0x0010)
-#define IVTV_REG_IRQSTATUS (0x0040)
-#define IVTV_REG_IRQMASK (0x0048)
-
-/* Setup Registers */
-#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8)
-#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC)
-#define IVTV_REG_DEC_SDRAM_REFRESH (0x08F8)
-#define IVTV_REG_DEC_SDRAM_PRECHARGE (0x08FC)
-#define IVTV_REG_VDM (0x2800)
-#define IVTV_REG_AO (0x2D00)
-#define IVTV_REG_BYTEFLUSH (0x2D24)
-#define IVTV_REG_SPU (0x9050)
-#define IVTV_REG_HW_BLOCKS (0x9054)
-#define IVTV_REG_VPU (0x9058)
-#define IVTV_REG_APU (0xA064)
-
-/* Other registers */
-#define IVTV_REG_DEC_LINE_FIELD (0x28C0)
-
-/* debugging */
-extern int ivtv_debug;
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-extern int ivtv_fw_debug;
-#endif
-
-#define IVTV_DBGFLG_WARN (1 << 0)
-#define IVTV_DBGFLG_INFO (1 << 1)
-#define IVTV_DBGFLG_MB (1 << 2)
-#define IVTV_DBGFLG_IOCTL (1 << 3)
-#define IVTV_DBGFLG_FILE (1 << 4)
-#define IVTV_DBGFLG_DMA (1 << 5)
-#define IVTV_DBGFLG_IRQ (1 << 6)
-#define IVTV_DBGFLG_DEC (1 << 7)
-#define IVTV_DBGFLG_YUV (1 << 8)
-#define IVTV_DBGFLG_I2C (1 << 9)
-/* Flag to turn on high volume debugging */
-#define IVTV_DBGFLG_HIGHVOL (1 << 10)
-
-#define IVTV_DEBUG(x, type, fmt, args...) \
- do { \
- if ((x) & ivtv_debug) \
- v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \
- } while (0)
-#define IVTV_DEBUG_WARN(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_WARN, "warn", fmt , ## args)
-#define IVTV_DEBUG_INFO(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_INFO, "info", fmt , ## args)
-#define IVTV_DEBUG_MB(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_MB, "mb", fmt , ## args)
-#define IVTV_DEBUG_DMA(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_DMA, "dma", fmt , ## args)
-#define IVTV_DEBUG_IOCTL(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args)
-#define IVTV_DEBUG_FILE(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_FILE, "file", fmt , ## args)
-#define IVTV_DEBUG_I2C(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_I2C, "i2c", fmt , ## args)
-#define IVTV_DEBUG_IRQ(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_IRQ, "irq", fmt , ## args)
-#define IVTV_DEBUG_DEC(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_DEC, "dec", fmt , ## args)
-#define IVTV_DEBUG_YUV(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
-
-#define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \
- do { \
- if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \
- v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \
- } while (0)
-#define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warn", fmt , ## args)
-#define IVTV_DEBUG_HI_INFO(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info", fmt , ## args)
-#define IVTV_DEBUG_HI_MB(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_MB, "mb", fmt , ## args)
-#define IVTV_DEBUG_HI_DMA(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DMA, "dma", fmt , ## args)
-#define IVTV_DEBUG_HI_IOCTL(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args)
-#define IVTV_DEBUG_HI_FILE(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_FILE, "file", fmt , ## args)
-#define IVTV_DEBUG_HI_I2C(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_I2C, "i2c", fmt , ## args)
-#define IVTV_DEBUG_HI_IRQ(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IRQ, "irq", fmt , ## args)
-#define IVTV_DEBUG_HI_DEC(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DEC, "dec", fmt , ## args)
-#define IVTV_DEBUG_HI_YUV(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
-
-/* Standard kernel messages */
-#define IVTV_ERR(fmt, args...) v4l2_err(&itv->v4l2_dev, fmt , ## args)
-#define IVTV_WARN(fmt, args...) v4l2_warn(&itv->v4l2_dev, fmt , ## args)
-#define IVTV_INFO(fmt, args...) v4l2_info(&itv->v4l2_dev, fmt , ## args)
-
-/* output modes (cx23415 only) */
-#define OUT_NONE 0
-#define OUT_MPG 1
-#define OUT_YUV 2
-#define OUT_UDMA_YUV 3
-#define OUT_PASSTHROUGH 4
-
-#define IVTV_MAX_PGM_INDEX (400)
-
-/* Default I2C SCL period in microseconds */
-#define IVTV_DEFAULT_I2C_CLOCK_PERIOD 20
-
-struct ivtv_options {
- int kilobytes[IVTV_MAX_STREAMS]; /* size in kilobytes of each stream */
- int cardtype; /* force card type on load */
- int tuner; /* set tuner on load */
- int radio; /* enable/disable radio */
- int newi2c; /* new I2C algorithm */
- int i2c_clock_period; /* period of SCL for I2C bus */
-};
-
-/* ivtv-specific mailbox template */
-struct ivtv_mailbox {
- u32 flags;
- u32 cmd;
- u32 retval;
- u32 timeout;
- u32 data[CX2341X_MBOX_MAX_DATA];
-};
-
-struct ivtv_api_cache {
- unsigned long last_jiffies; /* when last command was issued */
- u32 data[CX2341X_MBOX_MAX_DATA]; /* last sent api data */
-};
-
-struct ivtv_mailbox_data {
- volatile struct ivtv_mailbox __iomem *mbox;
- /* Bits 0-2 are for the encoder mailboxes, 0-1 are for the decoder mailboxes.
- If the bit is set, then the corresponding mailbox is in use by the driver. */
- unsigned long busy;
- u8 max_mbox;
-};
-
-/* per-buffer bit flags */
-#define IVTV_F_B_NEED_BUF_SWAP (1 << 0) /* this buffer should be byte swapped */
-
-/* per-stream, s_flags */
-#define IVTV_F_S_DMA_PENDING 0 /* this stream has pending DMA */
-#define IVTV_F_S_DMA_HAS_VBI 1 /* the current DMA request also requests VBI data */
-#define IVTV_F_S_NEEDS_DATA 2 /* this decoding stream needs more data */
-
-#define IVTV_F_S_CLAIMED 3 /* this stream is claimed */
-#define IVTV_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */
-#define IVTV_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
-#define IVTV_F_S_PASSTHROUGH 6 /* this stream is in passthrough mode */
-#define IVTV_F_S_STREAMOFF 7 /* signal end of stream EOS */
-#define IVTV_F_S_APPL_IO 8 /* this stream is used read/written by an application */
-
-#define IVTV_F_S_PIO_PENDING 9 /* this stream has pending PIO */
-#define IVTV_F_S_PIO_HAS_VBI 1 /* the current PIO request also requests VBI data */
-
-/* per-ivtv, i_flags */
-#define IVTV_F_I_DMA 0 /* DMA in progress */
-#define IVTV_F_I_UDMA 1 /* UDMA in progress */
-#define IVTV_F_I_UDMA_PENDING 2 /* UDMA pending */
-#define IVTV_F_I_SPEED_CHANGE 3 /* a speed change is in progress */
-#define IVTV_F_I_EOS 4 /* end of encoder stream reached */
-#define IVTV_F_I_RADIO_USER 5 /* the radio tuner is selected */
-#define IVTV_F_I_DIG_RST 6 /* reset digitizer */
-#define IVTV_F_I_DEC_YUV 7 /* YUV instead of MPG is being decoded */
-#define IVTV_F_I_UPDATE_CC 9 /* CC should be updated */
-#define IVTV_F_I_UPDATE_WSS 10 /* WSS should be updated */
-#define IVTV_F_I_UPDATE_VPS 11 /* VPS should be updated */
-#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */
-#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */
-#define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */
-#define IVTV_F_I_HAVE_WORK 15 /* used in the interrupt handler: there is work to be done */
-#define IVTV_F_I_WORK_HANDLER_VBI 16 /* there is work to be done for VBI */
-#define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */
-#define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */
-#define IVTV_F_I_PIO 19 /* PIO in progress */
-#define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */
-#define IVTV_F_I_INITED 21 /* set after first open */
-#define IVTV_F_I_FAILED 22 /* set if first open failed */
-
-/* Event notifications */
-#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */
-#define IVTV_F_I_EV_VSYNC 29 /* VSYNC event */
-#define IVTV_F_I_EV_VSYNC_FIELD 30 /* VSYNC event field (0 = first, 1 = second field) */
-#define IVTV_F_I_EV_VSYNC_ENABLED 31 /* VSYNC event enabled */
-
-/* Scatter-Gather array element, used in DMA transfers */
-struct ivtv_sg_element {
- __le32 src;
- __le32 dst;
- __le32 size;
-};
-
-struct ivtv_sg_host_element {
- u32 src;
- u32 dst;
- u32 size;
-};
-
-struct ivtv_user_dma {
- struct mutex lock;
- int page_count;
- struct page *map[IVTV_DMA_SG_OSD_ENT];
- /* Needed when dealing with highmem userspace buffers */
- struct page *bouncemap[IVTV_DMA_SG_OSD_ENT];
-
- /* Base Dev SG Array for cx23415/6 */
- struct ivtv_sg_element SGarray[IVTV_DMA_SG_OSD_ENT];
- dma_addr_t SG_handle;
- int SG_length;
-
- /* SG List of Buffers */
- struct scatterlist SGlist[IVTV_DMA_SG_OSD_ENT];
-};
-
-struct ivtv_dma_page_info {
- unsigned long uaddr;
- unsigned long first;
- unsigned long last;
- unsigned int offset;
- unsigned int tail;
- int page_count;
-};
-
-struct ivtv_buffer {
- struct list_head list;
- dma_addr_t dma_handle;
- unsigned short b_flags;
- unsigned short dma_xfer_cnt;
- char *buf;
- u32 bytesused;
- u32 readpos;
-};
-
-struct ivtv_queue {
- struct list_head list; /* the list of buffers in this queue */
- u32 buffers; /* number of buffers in this queue */
- u32 length; /* total number of bytes of available buffer space */
- u32 bytesused; /* total number of bytes used in this queue */
-};
-
-struct ivtv; /* forward reference */
-
-struct ivtv_stream {
- /* These first four fields are always set, even if the stream
- is not actually created. */
- struct video_device *vdev; /* NULL when stream not created */
- struct ivtv *itv; /* for ease of use */
- const char *name; /* name of the stream */
- int type; /* stream type */
- u32 caps; /* V4L2 capabilities */
-
- struct v4l2_fh *fh; /* pointer to the streaming filehandle */
- spinlock_t qlock; /* locks access to the queues */
- unsigned long s_flags; /* status flags, see above */
- int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */
- u32 pending_offset;
- u32 pending_backup;
- u64 pending_pts;
-
- u32 dma_offset;
- u32 dma_backup;
- u64 dma_pts;
-
- int subtype;
- wait_queue_head_t waitq;
- u32 dma_last_offset;
-
- /* Buffer Stats */
- u32 buffers;
- u32 buf_size;
- u32 buffers_stolen;
-
- /* Buffer Queues */
- struct ivtv_queue q_free; /* free buffers */
- struct ivtv_queue q_full; /* full buffers */
- struct ivtv_queue q_io; /* waiting for I/O */
- struct ivtv_queue q_dma; /* waiting for DMA */
- struct ivtv_queue q_predma; /* waiting for DMA */
-
- /* DMA xfer counter, buffers belonging to the same DMA
- xfer will have the same dma_xfer_cnt. */
- u16 dma_xfer_cnt;
-
- /* Base Dev SG Array for cx23415/6 */
- struct ivtv_sg_host_element *sg_pending;
- struct ivtv_sg_host_element *sg_processing;
- struct ivtv_sg_element *sg_dma;
- dma_addr_t sg_handle;
- int sg_pending_size;
- int sg_processing_size;
- int sg_processed;
-
- /* SG List of Buffers */
- struct scatterlist *SGlist;
-};
-
-struct ivtv_open_id {
- struct v4l2_fh fh;
- int type; /* stream type */
- int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */
- struct ivtv *itv;
-};
-
-static inline struct ivtv_open_id *fh2id(struct v4l2_fh *fh)
-{
- return container_of(fh, struct ivtv_open_id, fh);
-}
-
-struct yuv_frame_info
-{
- u32 update;
- s32 src_x;
- s32 src_y;
- u32 src_w;
- u32 src_h;
- s32 dst_x;
- s32 dst_y;
- u32 dst_w;
- u32 dst_h;
- s32 pan_x;
- s32 pan_y;
- u32 vis_w;
- u32 vis_h;
- u32 interlaced_y;
- u32 interlaced_uv;
- s32 tru_x;
- u32 tru_w;
- u32 tru_h;
- u32 offset_y;
- s32 lace_mode;
- u32 sync_field;
- u32 delay;
- u32 interlaced;
-};
-
-#define IVTV_YUV_MODE_INTERLACED 0x00
-#define IVTV_YUV_MODE_PROGRESSIVE 0x01
-#define IVTV_YUV_MODE_AUTO 0x02
-#define IVTV_YUV_MODE_MASK 0x03
-
-#define IVTV_YUV_SYNC_EVEN 0x00
-#define IVTV_YUV_SYNC_ODD 0x04
-#define IVTV_YUV_SYNC_MASK 0x04
-
-#define IVTV_YUV_BUFFERS 8
-
-struct yuv_playback_info
-{
- u32 reg_2834;
- u32 reg_2838;
- u32 reg_283c;
- u32 reg_2840;
- u32 reg_2844;
- u32 reg_2848;
- u32 reg_2854;
- u32 reg_285c;
- u32 reg_2864;
-
- u32 reg_2870;
- u32 reg_2874;
- u32 reg_2890;
- u32 reg_2898;
- u32 reg_289c;
-
- u32 reg_2918;
- u32 reg_291c;
- u32 reg_2920;
- u32 reg_2924;
- u32 reg_2928;
- u32 reg_292c;
- u32 reg_2930;
-
- u32 reg_2934;
-
- u32 reg_2938;
- u32 reg_293c;
- u32 reg_2940;
- u32 reg_2944;
- u32 reg_2948;
- u32 reg_294c;
- u32 reg_2950;
- u32 reg_2954;
- u32 reg_2958;
- u32 reg_295c;
- u32 reg_2960;
- u32 reg_2964;
- u32 reg_2968;
- u32 reg_296c;
-
- u32 reg_2970;
-
- int v_filter_1;
- int v_filter_2;
- int h_filter;
-
- u8 track_osd; /* Should yuv output track the OSD size & position */
-
- u32 osd_x_offset;
- u32 osd_y_offset;
-
- u32 osd_x_pan;
- u32 osd_y_pan;
-
- u32 osd_vis_w;
- u32 osd_vis_h;
-
- u32 osd_full_w;
- u32 osd_full_h;
-
- int decode_height;
-
- int lace_mode;
- int lace_threshold;
- int lace_sync_field;
-
- atomic_t next_dma_frame;
- atomic_t next_fill_frame;
-
- u32 yuv_forced_update;
- int update_frame;
-
- u8 fields_lapsed; /* Counter used when delaying a frame */
-
- struct yuv_frame_info new_frame_info[IVTV_YUV_BUFFERS];
- struct yuv_frame_info old_frame_info;
- struct yuv_frame_info old_frame_info_args;
-
- void *blanking_ptr;
- dma_addr_t blanking_dmaptr;
-
- int stream_size;
-
- u8 draw_frame; /* PVR350 buffer to draw into */
- u8 max_frames_buffered; /* Maximum number of frames to buffer */
-
- struct v4l2_rect main_rect;
- u32 v4l2_src_w;
- u32 v4l2_src_h;
-
- u8 running; /* Have any frames been displayed */
-};
-
-#define IVTV_VBI_FRAMES 32
-
-/* VBI data */
-struct vbi_cc {
- u8 odd[2]; /* two-byte payload of odd field */
- u8 even[2]; /* two-byte payload of even field */;
-};
-
-struct vbi_vps {
- u8 data[5]; /* five-byte VPS payload */
-};
-
-struct vbi_info {
- /* VBI general data, does not change during streaming */
-
- u32 raw_decoder_line_size; /* raw VBI line size from digitizer */
- u8 raw_decoder_sav_odd_field; /* raw VBI Start Active Video digitizer code of odd field */
- u8 raw_decoder_sav_even_field; /* raw VBI Start Active Video digitizer code of even field */
- u32 sliced_decoder_line_size; /* sliced VBI line size from digitizer */
- u8 sliced_decoder_sav_odd_field; /* sliced VBI Start Active Video digitizer code of odd field */
- u8 sliced_decoder_sav_even_field; /* sliced VBI Start Active Video digitizer code of even field */
-
- u32 start[2]; /* start of first VBI line in the odd/even fields */
- u32 count; /* number of VBI lines per field */
- u32 raw_size; /* size of raw VBI line from the digitizer */
- u32 sliced_size; /* size of sliced VBI line from the digitizer */
-
- u32 dec_start; /* start in decoder memory of VBI re-insertion buffers */
- u32 enc_start; /* start in encoder memory of VBI capture buffers */
- u32 enc_size; /* size of VBI capture area */
- int fpi; /* number of VBI frames per interrupt */
-
- struct v4l2_format in; /* current VBI capture format */
- struct v4l2_sliced_vbi_format *sliced_in; /* convenience pointer to sliced struct in vbi.in union */
- int insert_mpeg; /* if non-zero, then embed VBI data in MPEG stream */
-
- /* Raw VBI compatibility hack */
-
- u32 frame; /* frame counter hack needed for backwards compatibility
- of old VBI software */
-
- /* Sliced VBI output data */
-
- struct vbi_cc cc_payload[256]; /* sliced VBI CC payload array: it is an array to
- prevent dropping CC data if they couldn't be
- processed fast enough */
- int cc_payload_idx; /* index in cc_payload */
- u8 cc_missing_cnt; /* counts number of frames without CC for passthrough mode */
- int wss_payload; /* sliced VBI WSS payload */
- u8 wss_missing_cnt; /* counts number of frames without WSS for passthrough mode */
- struct vbi_vps vps_payload; /* sliced VBI VPS payload */
-
- /* Sliced VBI capture data */
-
- struct v4l2_sliced_vbi_data sliced_data[36]; /* sliced VBI storage for VBI encoder stream */
- struct v4l2_sliced_vbi_data sliced_dec_data[36];/* sliced VBI storage for VBI decoder stream */
-
- /* VBI Embedding data */
-
- /* Buffer for VBI data inserted into MPEG stream.
- The first byte is a dummy byte that's never used.
- The next 16 bytes contain the MPEG header for the VBI data,
- the remainder is the actual VBI data.
- The max size accepted by the MPEG VBI reinsertion turns out
- to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes,
- where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is
- a single line header byte and 2 * 18 is the number of VBI lines per frame.
-
- However, it seems that the data must be 1K aligned, so we have to
- pad the data until the 1 or 2 K boundary.
-
- This pointer array will allocate 2049 bytes to store each VBI frame. */
- u8 *sliced_mpeg_data[IVTV_VBI_FRAMES];
- u32 sliced_mpeg_size[IVTV_VBI_FRAMES];
- struct ivtv_buffer sliced_mpeg_buf; /* temporary buffer holding data from sliced_mpeg_data */
- u32 inserted_frame; /* index in sliced_mpeg_size of next sliced data
- to be inserted in the MPEG stream */
-};
-
-/* forward declaration of struct defined in ivtv-cards.h */
-struct ivtv_card;
-
-/* Struct to hold info about ivtv cards */
-struct ivtv {
- /* General fixed card data */
- struct pci_dev *pdev; /* PCI device */
- const struct ivtv_card *card; /* card information */
- const char *card_name; /* full name of the card */
- const struct ivtv_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
- u8 has_cx23415; /* 1 if it is a cx23415 based card, 0 for cx23416 */
- u8 pvr150_workaround; /* 1 if the cx25840 needs to workaround a PVR150 bug */
- u8 nof_inputs; /* number of video inputs */
- u8 nof_audio_inputs; /* number of audio inputs */
- u32 v4l2_cap; /* V4L2 capabilities of card */
- u32 hw_flags; /* hardware description of the board */
- v4l2_std_id tuner_std; /* the norm of the card's tuner (fixed) */
- struct v4l2_subdev *sd_video; /* controlling video decoder subdev */
- struct v4l2_subdev *sd_audio; /* controlling audio subdev */
- struct v4l2_subdev *sd_muxer; /* controlling audio muxer subdev */
- resource_size_t base_addr; /* PCI resource base address */
- volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */
- volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */
- volatile void __iomem *reg_mem; /* pointer to mapped registers */
- struct ivtv_options options; /* user options */
-
- struct v4l2_device v4l2_dev;
- struct cx2341x_handler cxhdl;
- struct {
- /* PTS/Frame count control cluster */
- struct v4l2_ctrl *ctrl_pts;
- struct v4l2_ctrl *ctrl_frame;
- };
- struct {
- /* Audio Playback control cluster */
- struct v4l2_ctrl *ctrl_audio_playback;
- struct v4l2_ctrl *ctrl_audio_multilingual_playback;
- };
- struct v4l2_ctrl_handler hdl_gpio;
- struct v4l2_subdev sd_gpio; /* GPIO sub-device */
- u16 instance;
-
- /* High-level state info */
- unsigned long i_flags; /* global ivtv flags */
- u8 is_50hz; /* 1 if the current capture standard is 50 Hz */
- u8 is_60hz /* 1 if the current capture standard is 60 Hz */;
- u8 is_out_50hz /* 1 if the current TV output standard is 50 Hz */;
- u8 is_out_60hz /* 1 if the current TV output standard is 60 Hz */;
- int output_mode; /* decoder output mode: NONE, MPG, YUV, UDMA YUV, passthrough */
- u32 audio_input; /* current audio input */
- u32 active_input; /* current video input */
- u32 active_output; /* current video output */
- v4l2_std_id std; /* current capture TV standard */
- v4l2_std_id std_out; /* current TV output standard */
- u8 audio_stereo_mode; /* decoder setting how to handle stereo MPEG audio */
- u8 audio_bilingual_mode; /* decoder setting how to handle bilingual MPEG audio */
-
- /* Locking */
- spinlock_t lock; /* lock access to this struct */
- struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
-
- /* Streams */
- int stream_buf_size[IVTV_MAX_STREAMS]; /* stream buffer size */
- struct ivtv_stream streams[IVTV_MAX_STREAMS]; /* stream data */
- atomic_t capturing; /* count number of active capture streams */
- atomic_t decoding; /* count number of active decoding streams */
-
-
- /* Interrupts & DMA */
- u32 irqmask; /* active interrupts */
- u32 irq_rr_idx; /* round-robin stream index */
- struct kthread_worker irq_worker; /* kthread worker for PIO/YUV/VBI actions */
- struct task_struct *irq_worker_task; /* task for irq_worker */
- struct kthread_work irq_work; /* kthread work entry */
- spinlock_t dma_reg_lock; /* lock access to DMA engine registers */
- int cur_dma_stream; /* index of current stream doing DMA (-1 if none) */
- int cur_pio_stream; /* index of current stream doing PIO (-1 if none) */
- u32 dma_data_req_offset; /* store offset in decoder memory of current DMA request */
- u32 dma_data_req_size; /* store size of current DMA request */
- int dma_retries; /* current DMA retry attempt */
- struct ivtv_user_dma udma; /* user based DMA for OSD */
- struct timer_list dma_timer; /* timer used to catch unfinished DMAs */
- u32 last_vsync_field; /* last seen vsync field */
- wait_queue_head_t dma_waitq; /* wake up when the current DMA is finished */
- wait_queue_head_t eos_waitq; /* wake up when EOS arrives */
- wait_queue_head_t event_waitq; /* wake up when the next decoder event arrives */
- wait_queue_head_t vsync_waitq; /* wake up when the next decoder vsync arrives */
-
-
- /* Mailbox */
- struct ivtv_mailbox_data enc_mbox; /* encoder mailboxes */
- struct ivtv_mailbox_data dec_mbox; /* decoder mailboxes */
- struct ivtv_api_cache api_cache[256]; /* cached API commands */
-
-
- /* I2C */
- struct i2c_adapter i2c_adap;
- struct i2c_algo_bit_data i2c_algo;
- struct i2c_client i2c_client;
- int i2c_state; /* i2c bit state */
- struct mutex i2c_bus_lock; /* lock i2c bus */
-
- struct IR_i2c_init_data ir_i2c_init_data;
-
- /* Program Index information */
- u32 pgm_info_offset; /* start of pgm info in encoder memory */
- u32 pgm_info_num; /* number of elements in the pgm cyclic buffer in encoder memory */
- u32 pgm_info_write_idx; /* last index written by the card that was transferred to pgm_info[] */
- u32 pgm_info_read_idx; /* last index in pgm_info read by the application */
- struct v4l2_enc_idx_entry pgm_info[IVTV_MAX_PGM_INDEX]; /* filled from the pgm cyclic buffer on the card */
-
-
- /* Miscellaneous */
- u32 open_id; /* incremented each time an open occurs, is >= 1 */
- int search_pack_header; /* 1 if ivtv_copy_buf_to_user() is scanning for a pack header (0xba) */
- int speed; /* current playback speed setting */
- u8 speed_mute_audio; /* 1 if audio should be muted when fast forward */
- u64 mpg_data_received; /* number of bytes received from the MPEG stream */
- u64 vbi_data_inserted; /* number of VBI bytes inserted into the MPEG stream */
- u32 last_dec_timing[3]; /* cache last retrieved pts/scr/frame values */
- unsigned long dualwatch_jiffies;/* jiffies value of the previous dualwatch check */
- u32 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */
-
-
- /* VBI state info */
- struct vbi_info vbi; /* VBI-specific data */
-
-
- /* YUV playback */
- struct yuv_playback_info yuv_info; /* YUV playback data */
-
-
- /* OSD support */
- unsigned long osd_video_pbase;
- int osd_global_alpha_state; /* 1 = global alpha is on */
- int osd_local_alpha_state; /* 1 = local alpha is on */
- int osd_chroma_key_state; /* 1 = chroma-keying is on */
- u8 osd_global_alpha; /* current global alpha */
- u32 osd_chroma_key; /* current chroma key */
- struct v4l2_rect osd_rect; /* current OSD position and size */
- struct v4l2_rect main_rect; /* current Main window position and size */
- struct osd_info *osd_info; /* ivtvfb private OSD info */
- void (*ivtvfb_restore)(struct ivtv *itv); /* Used for a warm start */
-};
-
-static inline struct ivtv *to_ivtv(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct ivtv, v4l2_dev);
-}
-
-/* Globals */
-extern int ivtv_first_minor;
-
-/*==============Prototypes==================*/
-
-/* Hardware/IRQ */
-void ivtv_set_irq_mask(struct ivtv *itv, u32 mask);
-void ivtv_clear_irq_mask(struct ivtv *itv, u32 mask);
-
-/* try to set output mode, return current mode. */
-int ivtv_set_output_mode(struct ivtv *itv, int mode);
-
-/* return current output stream based on current mode */
-struct ivtv_stream *ivtv_get_output_stream(struct ivtv *itv);
-
-/* Return non-zero if a signal is pending */
-int ivtv_msleep_timeout(unsigned int msecs, int intr);
-
-/* Wait on queue, returns -EINTR if interrupted */
-int ivtv_waitq(wait_queue_head_t *waitq);
-
-/* Read Hauppauge eeprom */
-struct tveeprom; /* forward reference */
-void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv);
-
-/* First-open initialization: load firmware, init cx25840, etc. */
-int ivtv_init_on_first_open(struct ivtv *itv);
-
-/* Test if the current VBI mode is raw (1) or sliced (0) */
-static inline int ivtv_raw_vbi(const struct ivtv *itv)
-{
- return itv->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE;
-}
-
-/* This is a PCI post thing, where if the pci register is not read, then
- the write doesn't always take effect right away. By reading back the
- register any pending PCI writes will be performed (in order), and so
- you can be sure that the writes are guaranteed to be done.
-
- Rarely needed, only in some timing sensitive cases.
- Apparently if this is not done some motherboards seem
- to kill the firmware and get into the broken state until computer is
- rebooted. */
-#define write_sync(val, reg) \
- do { writel(val, reg); readl(reg); } while (0)
-
-#define read_reg(reg) readl(itv->reg_mem + (reg))
-#define write_reg(val, reg) writel(val, itv->reg_mem + (reg))
-#define write_reg_sync(val, reg) \
- do { write_reg(val, reg); read_reg(reg); } while (0)
-
-#define read_enc(addr) readl(itv->enc_mem + (u32)(addr))
-#define write_enc(val, addr) writel(val, itv->enc_mem + (u32)(addr))
-#define write_enc_sync(val, addr) \
- do { write_enc(val, addr); read_enc(addr); } while (0)
-
-#define read_dec(addr) readl(itv->dec_mem + (u32)(addr))
-#define write_dec(val, addr) writel(val, itv->dec_mem + (u32)(addr))
-#define write_dec_sync(val, addr) \
- do { write_dec(val, addr); read_dec(addr); } while (0)
-
-/* Call the specified callback for all subdevs matching hw (if 0, then
- match them all). Ignore any errors. */
-#define ivtv_call_hw(itv, hw, o, f, args...) \
- do { \
- struct v4l2_subdev *__sd; \
- __v4l2_device_call_subdevs_p(&(itv)->v4l2_dev, __sd, \
- !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \
- } while (0)
-
-#define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args)
-
-/* Call the specified callback for all subdevs matching hw (if 0, then
- match them all). If the callback returns an error other than 0 or
- -ENOIOCTLCMD, then return with that error code. */
-#define ivtv_call_hw_err(itv, hw, o, f, args...) \
-({ \
- struct v4l2_subdev *__sd; \
- __v4l2_device_call_subdevs_until_err_p(&(itv)->v4l2_dev, __sd, \
- !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \
-})
-
-#define ivtv_call_all_err(itv, o, f, args...) ivtv_call_hw_err(itv, 0, o, f , ##args)
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
deleted file mode 100644
index 9ff69b5a87e..00000000000
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ /dev/null
@@ -1,1038 +0,0 @@
-/*
- file operation functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-fileops.h"
-#include "ivtv-i2c.h"
-#include "ivtv-queue.h"
-#include "ivtv-udma.h"
-#include "ivtv-irq.h"
-#include "ivtv-vbi.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-routing.h"
-#include "ivtv-streams.h"
-#include "ivtv-yuv.h"
-#include "ivtv-ioctl.h"
-#include "ivtv-cards.h"
-#include "ivtv-firmware.h"
-#include <media/v4l2-event.h>
-#include <media/saa7115.h>
-
-/* This function tries to claim the stream for a specific file descriptor.
- If no one else is using this stream then the stream is claimed and
- associated VBI streams are also automatically claimed.
- Possible error returns: -EBUSY if someone else has claimed
- the stream or 0 on success. */
-static int ivtv_claim_stream(struct ivtv_open_id *id, int type)
-{
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[type];
- struct ivtv_stream *s_vbi;
- int vbi_type;
-
- if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
- /* someone already claimed this stream */
- if (s->fh == &id->fh) {
- /* yes, this file descriptor did. So that's OK. */
- return 0;
- }
- if (s->fh == NULL && (type == IVTV_DEC_STREAM_TYPE_VBI ||
- type == IVTV_ENC_STREAM_TYPE_VBI)) {
- /* VBI is handled already internally, now also assign
- the file descriptor to this stream for external
- reading of the stream. */
- s->fh = &id->fh;
- IVTV_DEBUG_INFO("Start Read VBI\n");
- return 0;
- }
- /* someone else is using this stream already */
- IVTV_DEBUG_INFO("Stream %d is busy\n", type);
- return -EBUSY;
- }
- s->fh = &id->fh;
- if (type == IVTV_DEC_STREAM_TYPE_VBI) {
- /* Enable reinsertion interrupt */
- ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
- }
-
- /* IVTV_DEC_STREAM_TYPE_MPG needs to claim IVTV_DEC_STREAM_TYPE_VBI,
- IVTV_ENC_STREAM_TYPE_MPG needs to claim IVTV_ENC_STREAM_TYPE_VBI
- (provided VBI insertion is on and sliced VBI is selected), for all
- other streams we're done */
- if (type == IVTV_DEC_STREAM_TYPE_MPG) {
- vbi_type = IVTV_DEC_STREAM_TYPE_VBI;
- } else if (type == IVTV_ENC_STREAM_TYPE_MPG &&
- itv->vbi.insert_mpeg && !ivtv_raw_vbi(itv)) {
- vbi_type = IVTV_ENC_STREAM_TYPE_VBI;
- } else {
- return 0;
- }
- s_vbi = &itv->streams[vbi_type];
-
- if (!test_and_set_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags)) {
- /* Enable reinsertion interrupt */
- if (vbi_type == IVTV_DEC_STREAM_TYPE_VBI)
- ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
- }
- /* mark that it is used internally */
- set_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags);
- return 0;
-}
-
-/* This function releases a previously claimed stream. It will take into
- account associated VBI streams. */
-void ivtv_release_stream(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
- struct ivtv_stream *s_vbi;
-
- s->fh = NULL;
- if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) &&
- test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
- /* this stream is still in use internally */
- return;
- }
- if (!test_and_clear_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
- IVTV_DEBUG_WARN("Release stream %s not in use!\n", s->name);
- return;
- }
-
- ivtv_flush_queues(s);
-
- /* disable reinsertion interrupt */
- if (s->type == IVTV_DEC_STREAM_TYPE_VBI)
- ivtv_set_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
-
- /* IVTV_DEC_STREAM_TYPE_MPG needs to release IVTV_DEC_STREAM_TYPE_VBI,
- IVTV_ENC_STREAM_TYPE_MPG needs to release IVTV_ENC_STREAM_TYPE_VBI,
- for all other streams we're done */
- if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
- s_vbi = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];
- else if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
- s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
- else
- return;
-
- /* clear internal use flag */
- if (!test_and_clear_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags)) {
- /* was already cleared */
- return;
- }
- if (s_vbi->fh) {
- /* VBI stream still claimed by a file descriptor */
- return;
- }
- /* disable reinsertion interrupt */
- if (s_vbi->type == IVTV_DEC_STREAM_TYPE_VBI)
- ivtv_set_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
- clear_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags);
- ivtv_flush_queues(s_vbi);
-}
-
-static void ivtv_dualwatch(struct ivtv *itv)
-{
- struct v4l2_tuner vt;
- u32 new_stereo_mode;
- const u32 dual = 0x02;
-
- new_stereo_mode = v4l2_ctrl_g_ctrl(itv->cxhdl.audio_mode);
- memset(&vt, 0, sizeof(vt));
- ivtv_call_all(itv, tuner, g_tuner, &vt);
- if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && (vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
- new_stereo_mode = dual;
-
- if (new_stereo_mode == itv->dualwatch_stereo_mode)
- return;
-
- IVTV_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",
- itv->dualwatch_stereo_mode, new_stereo_mode);
- if (v4l2_ctrl_s_ctrl(itv->cxhdl.audio_mode, new_stereo_mode))
- IVTV_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
-}
-
-static void ivtv_update_pgm_info(struct ivtv *itv)
-{
- u32 wr_idx = (read_enc(itv->pgm_info_offset) - itv->pgm_info_offset - 4) / 24;
- int cnt;
- int i = 0;
-
- if (wr_idx >= itv->pgm_info_num) {
- IVTV_DEBUG_WARN("Invalid PGM index %d (>= %d)\n", wr_idx, itv->pgm_info_num);
- return;
- }
- cnt = (wr_idx + itv->pgm_info_num - itv->pgm_info_write_idx) % itv->pgm_info_num;
- while (i < cnt) {
- int idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
- struct v4l2_enc_idx_entry *e = itv->pgm_info + idx;
- u32 addr = itv->pgm_info_offset + 4 + idx * 24;
- const int mapping[8] = { -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P, -1,
- V4L2_ENC_IDX_FRAME_B, -1, -1, -1 };
- // 1=I, 2=P, 4=B
-
- e->offset = read_enc(addr + 4) + ((u64)read_enc(addr + 8) << 32);
- if (e->offset > itv->mpg_data_received) {
- break;
- }
- e->offset += itv->vbi_data_inserted;
- e->length = read_enc(addr);
- e->pts = read_enc(addr + 16) + ((u64)(read_enc(addr + 20) & 1) << 32);
- e->flags = mapping[read_enc(addr + 12) & 7];
- i++;
- }
- itv->pgm_info_write_idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
-}
-
-static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, int *err)
-{
- struct ivtv *itv = s->itv;
- struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
- struct ivtv_buffer *buf;
- DEFINE_WAIT(wait);
-
- *err = 0;
- while (1) {
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG) {
- /* Process pending program info updates and pending VBI data */
- ivtv_update_pgm_info(itv);
-
- if (time_after(jiffies,
- itv->dualwatch_jiffies +
- msecs_to_jiffies(1000))) {
- itv->dualwatch_jiffies = jiffies;
- ivtv_dualwatch(itv);
- }
-
- if (test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
- !test_bit(IVTV_F_S_APPL_IO, &s_vbi->s_flags)) {
- while ((buf = ivtv_dequeue(s_vbi, &s_vbi->q_full))) {
- /* byteswap and process VBI data */
- ivtv_process_vbi_data(itv, buf, s_vbi->dma_pts, s_vbi->type);
- ivtv_enqueue(s_vbi, buf, &s_vbi->q_free);
- }
- }
- buf = &itv->vbi.sliced_mpeg_buf;
- if (buf->readpos != buf->bytesused) {
- return buf;
- }
- }
-
- /* do we have leftover data? */
- buf = ivtv_dequeue(s, &s->q_io);
- if (buf)
- return buf;
-
- /* do we have new data? */
- buf = ivtv_dequeue(s, &s->q_full);
- if (buf) {
- if ((buf->b_flags & IVTV_F_B_NEED_BUF_SWAP) == 0)
- return buf;
- buf->b_flags &= ~IVTV_F_B_NEED_BUF_SWAP;
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
- /* byteswap MPG data */
- ivtv_buf_swap(buf);
- else if (s->type != IVTV_DEC_STREAM_TYPE_VBI) {
- /* byteswap and process VBI data */
- ivtv_process_vbi_data(itv, buf, s->dma_pts, s->type);
- }
- return buf;
- }
-
- /* return if end of stream */
- if (s->type != IVTV_DEC_STREAM_TYPE_VBI && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
- IVTV_DEBUG_INFO("EOS %s\n", s->name);
- return NULL;
- }
-
- /* return if file was opened with O_NONBLOCK */
- if (non_block) {
- *err = -EAGAIN;
- return NULL;
- }
-
- /* wait for more data to arrive */
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
- /* New buffers might have become available before we were added to the waitqueue */
- if (!s->q_full.buffers)
- schedule();
- finish_wait(&s->waitq, &wait);
- mutex_lock(&itv->serialize_lock);
- if (signal_pending(current)) {
- /* return if a signal was received */
- IVTV_DEBUG_INFO("User stopped %s\n", s->name);
- *err = -EINTR;
- return NULL;
- }
- }
-}
-
-static void ivtv_setup_sliced_vbi_buf(struct ivtv *itv)
-{
- int idx = itv->vbi.inserted_frame % IVTV_VBI_FRAMES;
-
- itv->vbi.sliced_mpeg_buf.buf = itv->vbi.sliced_mpeg_data[idx];
- itv->vbi.sliced_mpeg_buf.bytesused = itv->vbi.sliced_mpeg_size[idx];
- itv->vbi.sliced_mpeg_buf.readpos = 0;
-}
-
-static size_t ivtv_copy_buf_to_user(struct ivtv_stream *s, struct ivtv_buffer *buf,
- char __user *ubuf, size_t ucount)
-{
- struct ivtv *itv = s->itv;
- size_t len = buf->bytesused - buf->readpos;
-
- if (len > ucount) len = ucount;
- if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG &&
- !ivtv_raw_vbi(itv) && buf != &itv->vbi.sliced_mpeg_buf) {
- const char *start = buf->buf + buf->readpos;
- const char *p = start + 1;
- const u8 *q;
- u8 ch = itv->search_pack_header ? 0xba : 0xe0;
- int stuffing, i;
-
- while (start + len > p && (q = memchr(p, 0, start + len - p))) {
- p = q + 1;
- if ((char *)q + 15 >= buf->buf + buf->bytesused ||
- q[1] != 0 || q[2] != 1 || q[3] != ch) {
- continue;
- }
- if (!itv->search_pack_header) {
- if ((q[6] & 0xc0) != 0x80)
- continue;
- if (((q[7] & 0xc0) == 0x80 && (q[9] & 0xf0) == 0x20) ||
- ((q[7] & 0xc0) == 0xc0 && (q[9] & 0xf0) == 0x30)) {
- ch = 0xba;
- itv->search_pack_header = 1;
- p = q + 9;
- }
- continue;
- }
- stuffing = q[13] & 7;
- /* all stuffing bytes must be 0xff */
- for (i = 0; i < stuffing; i++)
- if (q[14 + i] != 0xff)
- break;
- if (i == stuffing && (q[4] & 0xc4) == 0x44 && (q[12] & 3) == 3 &&
- q[14 + stuffing] == 0 && q[15 + stuffing] == 0 &&
- q[16 + stuffing] == 1) {
- itv->search_pack_header = 0;
- len = (char *)q - start;
- ivtv_setup_sliced_vbi_buf(itv);
- break;
- }
- }
- }
- if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {
- IVTV_DEBUG_WARN("copy %zd bytes to user failed for %s\n", len, s->name);
- return -EFAULT;
- }
- /*IVTV_INFO("copied %lld %d %d %d %d %d vbi %d\n", itv->mpg_data_received, len, ucount,
- buf->readpos, buf->bytesused, buf->bytesused - buf->readpos - len,
- buf == &itv->vbi.sliced_mpeg_buf); */
- buf->readpos += len;
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG && buf != &itv->vbi.sliced_mpeg_buf)
- itv->mpg_data_received += len;
- return len;
-}
-
-static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_count, int non_block)
-{
- struct ivtv *itv = s->itv;
- size_t tot_written = 0;
- int single_frame = 0;
-
- if (atomic_read(&itv->capturing) == 0 && s->fh == NULL) {
- /* shouldn't happen */
- IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name);
- return -EIO;
- }
-
- /* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should
- arrive one-by-one, so make sure we never output more than one VBI frame at a time */
- if (s->type == IVTV_DEC_STREAM_TYPE_VBI ||
- (s->type == IVTV_ENC_STREAM_TYPE_VBI && !ivtv_raw_vbi(itv)))
- single_frame = 1;
-
- for (;;) {
- struct ivtv_buffer *buf;
- int rc;
-
- buf = ivtv_get_buffer(s, non_block, &rc);
- /* if there is no data available... */
- if (buf == NULL) {
- /* if we got data, then return that regardless */
- if (tot_written)
- break;
- /* EOS condition */
- if (rc == 0) {
- clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
- clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- ivtv_release_stream(s);
- }
- /* set errno */
- return rc;
- }
- rc = ivtv_copy_buf_to_user(s, buf, ubuf + tot_written, tot_count - tot_written);
- if (buf != &itv->vbi.sliced_mpeg_buf) {
- ivtv_enqueue(s, buf, (buf->readpos == buf->bytesused) ? &s->q_free : &s->q_io);
- }
- else if (buf->readpos == buf->bytesused) {
- int idx = itv->vbi.inserted_frame % IVTV_VBI_FRAMES;
- itv->vbi.sliced_mpeg_size[idx] = 0;
- itv->vbi.inserted_frame++;
- itv->vbi_data_inserted += buf->bytesused;
- }
- if (rc < 0)
- return rc;
- tot_written += rc;
-
- if (tot_written == tot_count || single_frame)
- break;
- }
- return tot_written;
-}
-
-static ssize_t ivtv_read_pos(struct ivtv_stream *s, char __user *ubuf, size_t count,
- loff_t *pos, int non_block)
-{
- ssize_t rc = count ? ivtv_read(s, ubuf, count, non_block) : 0;
- struct ivtv *itv = s->itv;
-
- IVTV_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);
- if (rc > 0)
- pos += rc;
- return rc;
-}
-
-int ivtv_start_capture(struct ivtv_open_id *id)
-{
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
- struct ivtv_stream *s_vbi;
-
- if (s->type == IVTV_ENC_STREAM_TYPE_RAD ||
- s->type == IVTV_DEC_STREAM_TYPE_MPG ||
- s->type == IVTV_DEC_STREAM_TYPE_YUV ||
- s->type == IVTV_DEC_STREAM_TYPE_VOUT) {
- /* you cannot read from these stream types. */
- return -EPERM;
- }
-
- /* Try to claim this stream. */
- if (ivtv_claim_stream(id, s->type))
- return -EBUSY;
-
- /* This stream does not need to start capturing */
- if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
- set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- return 0;
- }
-
- /* If capture is already in progress, then we also have to
- do nothing extra. */
- if (test_bit(IVTV_F_S_STREAMOFF, &s->s_flags) || test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
- set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- return 0;
- }
-
- /* Start VBI capture if required */
- s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG &&
- test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
- !test_and_set_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) {
- /* Note: the IVTV_ENC_STREAM_TYPE_VBI is claimed
- automatically when the MPG stream is claimed.
- We only need to start the VBI capturing. */
- if (ivtv_start_v4l2_encode_stream(s_vbi)) {
- IVTV_DEBUG_WARN("VBI capture start failed\n");
-
- /* Failure, clean up and return an error */
- clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags);
- clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
- /* also releases the associated VBI stream */
- ivtv_release_stream(s);
- return -EIO;
- }
- IVTV_DEBUG_INFO("VBI insertion started\n");
- }
-
- /* Tell the card to start capturing */
- if (!ivtv_start_v4l2_encode_stream(s)) {
- /* We're done */
- set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- /* Resume a possibly paused encoder */
- if (test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
- ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
- return 0;
- }
-
- /* failure, clean up */
- IVTV_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
-
- /* Note: the IVTV_ENC_STREAM_TYPE_VBI is released
- automatically when the MPG stream is released.
- We only need to stop the VBI capturing. */
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG &&
- test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) {
- ivtv_stop_v4l2_encode_stream(s_vbi, 0);
- clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags);
- }
- clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
- ivtv_release_stream(s);
- return -EIO;
-}
-
-ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos)
-{
- struct ivtv_open_id *id = fh2id(filp->private_data);
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
- int rc;
-
- IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
-
- rc = ivtv_start_capture(id);
- if (rc)
- return rc;
- return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
-}
-
-int ivtv_start_decoding(struct ivtv_open_id *id, int speed)
-{
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
- int rc;
-
- if (atomic_read(&itv->decoding) == 0) {
- if (ivtv_claim_stream(id, s->type)) {
- /* someone else is using this stream already */
- IVTV_DEBUG_WARN("start decode, stream already claimed\n");
- return -EBUSY;
- }
- rc = ivtv_start_v4l2_decode_stream(s, 0);
- if (rc < 0) {
- if (rc == -EAGAIN)
- rc = ivtv_start_v4l2_decode_stream(s, 0);
- if (rc < 0)
- return rc;
- }
- }
- if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
- return ivtv_set_speed(itv, speed);
- return 0;
-}
-
-ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
-{
- struct ivtv_open_id *id = fh2id(filp->private_data);
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
- struct yuv_playback_info *yi = &itv->yuv_info;
- struct ivtv_buffer *buf;
- struct ivtv_queue q;
- int bytes_written = 0;
- int mode;
- int rc;
- DEFINE_WAIT(wait);
-
- IVTV_DEBUG_HI_FILE("write %zd bytes to %s\n", count, s->name);
-
- if (s->type != IVTV_DEC_STREAM_TYPE_MPG &&
- s->type != IVTV_DEC_STREAM_TYPE_YUV &&
- s->type != IVTV_DEC_STREAM_TYPE_VOUT)
- /* not decoder streams */
- return -EPERM;
-
- /* Try to claim this stream */
- if (ivtv_claim_stream(id, s->type))
- return -EBUSY;
-
- /* This stream does not need to start any decoding */
- if (s->type == IVTV_DEC_STREAM_TYPE_VOUT) {
- int elems = count / sizeof(struct v4l2_sliced_vbi_data);
-
- set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- return ivtv_write_vbi_from_user(itv,
- (const struct v4l2_sliced_vbi_data __user *)user_buf, elems);
- }
-
- mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV;
-
- if (ivtv_set_output_mode(itv, mode) != mode) {
- ivtv_release_stream(s);
- return -EBUSY;
- }
- ivtv_queue_init(&q);
- set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
-
- /* Start decoder (returns 0 if already started) */
- rc = ivtv_start_decoding(id, itv->speed);
- if (rc) {
- IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
-
- /* failure, clean up */
- clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
- clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- return rc;
- }
-
-retry:
- /* If possible, just DMA the entire frame - Check the data transfer size
- since we may get here before the stream has been fully set-up */
- if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) {
- while (count >= itv->dma_data_req_size) {
- rc = ivtv_yuv_udma_stream_frame(itv, (void __user *)user_buf);
-
- if (rc < 0)
- return rc;
-
- bytes_written += itv->dma_data_req_size;
- user_buf += itv->dma_data_req_size;
- count -= itv->dma_data_req_size;
- }
- if (count == 0) {
- IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused);
- return bytes_written;
- }
- }
-
- for (;;) {
- /* Gather buffers */
- while (q.length - q.bytesused < count && (buf = ivtv_dequeue(s, &s->q_io)))
- ivtv_enqueue(s, buf, &q);
- while (q.length - q.bytesused < count && (buf = ivtv_dequeue(s, &s->q_free))) {
- ivtv_enqueue(s, buf, &q);
- }
- if (q.buffers)
- break;
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
- /* New buffers might have become free before we were added to the waitqueue */
- if (!s->q_free.buffers)
- schedule();
- finish_wait(&s->waitq, &wait);
- mutex_lock(&itv->serialize_lock);
- if (signal_pending(current)) {
- IVTV_DEBUG_INFO("User stopped %s\n", s->name);
- return -EINTR;
- }
- }
-
- /* copy user data into buffers */
- while ((buf = ivtv_dequeue(s, &q))) {
- /* yuv is a pain. Don't copy more data than needed for a single
- frame, otherwise we lose sync with the incoming stream */
- if (s->type == IVTV_DEC_STREAM_TYPE_YUV &&
- yi->stream_size + count > itv->dma_data_req_size)
- rc = ivtv_buf_copy_from_user(s, buf, user_buf,
- itv->dma_data_req_size - yi->stream_size);
- else
- rc = ivtv_buf_copy_from_user(s, buf, user_buf, count);
-
- /* Make sure we really got all the user data */
- if (rc < 0) {
- ivtv_queue_move(s, &q, NULL, &s->q_free, 0);
- return rc;
- }
- user_buf += rc;
- count -= rc;
- bytes_written += rc;
-
- if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
- yi->stream_size += rc;
- /* If we have a complete yuv frame, break loop now */
- if (yi->stream_size == itv->dma_data_req_size) {
- ivtv_enqueue(s, buf, &s->q_full);
- yi->stream_size = 0;
- break;
- }
- }
-
- if (buf->bytesused != s->buf_size) {
- /* incomplete, leave in q_io for next time */
- ivtv_enqueue(s, buf, &s->q_io);
- break;
- }
- /* Byteswap MPEG buffer */
- if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
- ivtv_buf_swap(buf);
- ivtv_enqueue(s, buf, &s->q_full);
- }
-
- if (test_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags)) {
- if (s->q_full.length >= itv->dma_data_req_size) {
- int got_sig;
-
- if (mode == OUT_YUV)
- ivtv_yuv_setup_stream_frame(itv);
-
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
- while (!(got_sig = signal_pending(current)) &&
- test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) {
- schedule();
- }
- finish_wait(&itv->dma_waitq, &wait);
- mutex_lock(&itv->serialize_lock);
- if (got_sig) {
- IVTV_DEBUG_INFO("User interrupted %s\n", s->name);
- return -EINTR;
- }
-
- clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
- ivtv_queue_move(s, &s->q_full, NULL, &s->q_predma, itv->dma_data_req_size);
- ivtv_dma_stream_dec_prepare(s, itv->dma_data_req_offset + IVTV_DECODER_OFFSET, 1);
- }
- }
- /* more user data is available, wait until buffers become free
- to transfer the rest. */
- if (count && !(filp->f_flags & O_NONBLOCK))
- goto retry;
- IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused);
- return bytes_written;
-}
-
-unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
-{
- struct ivtv_open_id *id = fh2id(filp->private_data);
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
- int res = 0;
-
- /* add stream's waitq to the poll list */
- IVTV_DEBUG_HI_FILE("Decoder poll\n");
-
- /* If there are subscribed events, then only use the new event
- API instead of the old video.h based API. */
- if (!list_empty(&id->fh.subscribed)) {
- poll_wait(filp, &id->fh.wait, wait);
- /* Turn off the old-style vsync events */
- clear_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
- if (v4l2_event_pending(&id->fh))
- res = POLLPRI;
- } else {
- /* This is the old-style API which is here only for backwards
- compatibility. */
- poll_wait(filp, &s->waitq, wait);
- set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
- if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) ||
- test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
- res = POLLPRI;
- }
-
- /* Allow write if buffers are available for writing */
- if (s->q_free.buffers)
- res |= POLLOUT | POLLWRNORM;
- return res;
-}
-
-unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table *wait)
-{
- unsigned long req_events = poll_requested_events(wait);
- struct ivtv_open_id *id = fh2id(filp->private_data);
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
- int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
- unsigned res = 0;
-
- /* Start a capture if there is none */
- if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags) &&
- (req_events & (POLLIN | POLLRDNORM))) {
- int rc;
-
- rc = ivtv_start_capture(id);
- if (rc) {
- IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n",
- s->name, rc);
- return POLLERR;
- }
- IVTV_DEBUG_FILE("Encoder poll started capture\n");
- }
-
- /* add stream's waitq to the poll list */
- IVTV_DEBUG_HI_FILE("Encoder poll\n");
- poll_wait(filp, &s->waitq, wait);
- if (v4l2_event_pending(&id->fh))
- res |= POLLPRI;
- else
- poll_wait(filp, &id->fh.wait, wait);
-
- if (s->q_full.length || s->q_io.length)
- return res | POLLIN | POLLRDNORM;
- if (eof)
- return res | POLLHUP;
- return res;
-}
-
-void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end)
-{
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
-
- IVTV_DEBUG_FILE("close() of %s\n", s->name);
-
- /* 'Unclaim' this stream */
-
- /* Stop capturing */
- if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
- struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
-
- IVTV_DEBUG_INFO("close stopping capture\n");
- /* Special case: a running VBI capture for VBI insertion
- in the mpeg stream. Need to stop that too. */
- if (id->type == IVTV_ENC_STREAM_TYPE_MPG &&
- test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags) &&
- !test_bit(IVTV_F_S_APPL_IO, &s_vbi->s_flags)) {
- IVTV_DEBUG_INFO("close stopping embedded VBI capture\n");
- ivtv_stop_v4l2_encode_stream(s_vbi, 0);
- }
- if ((id->type == IVTV_DEC_STREAM_TYPE_VBI ||
- id->type == IVTV_ENC_STREAM_TYPE_VBI) &&
- test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
- /* Also used internally, don't stop capturing */
- s->fh = NULL;
- }
- else {
- ivtv_stop_v4l2_encode_stream(s, gop_end);
- }
- }
- if (!gop_end) {
- clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
- ivtv_release_stream(s);
- }
-}
-
-static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
-{
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
-
- IVTV_DEBUG_FILE("close() of %s\n", s->name);
-
- if (id->type == IVTV_DEC_STREAM_TYPE_YUV &&
- test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) {
- /* Restore registers we've changed & clean up any mess */
- ivtv_yuv_close(itv);
- }
-
- /* Stop decoding */
- if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
- IVTV_DEBUG_INFO("close stopping decode\n");
-
- ivtv_stop_v4l2_decode_stream(s, flags, pts);
- itv->output_mode = OUT_NONE;
- }
- clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
-
- if (itv->output_mode == OUT_UDMA_YUV && id->yuv_frames)
- itv->output_mode = OUT_NONE;
-
- itv->speed = 0;
- clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
- ivtv_release_stream(s);
-}
-
-int ivtv_v4l2_close(struct file *filp)
-{
- struct v4l2_fh *fh = filp->private_data;
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
-
- IVTV_DEBUG_FILE("close %s\n", s->name);
-
- /* Stop radio */
- if (id->type == IVTV_ENC_STREAM_TYPE_RAD &&
- v4l2_fh_is_singular_file(filp)) {
- /* Closing radio device, return to TV mode */
- ivtv_mute(itv);
- /* Mark that the radio is no longer in use */
- clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
- /* Switch tuner to TV */
- ivtv_call_all(itv, core, s_std, itv->std);
- /* Select correct audio input (i.e. TV tuner or Line in) */
- ivtv_audio_set_io(itv);
- if (itv->hw_flags & IVTV_HW_SAA711X) {
- ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,
- SAA7115_FREQ_32_11_MHZ, 0);
- }
- if (atomic_read(&itv->capturing) > 0) {
- /* Undo video mute */
- ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
- v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) |
- (v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8));
- }
- /* Done! Unmute and continue. */
- ivtv_unmute(itv);
- }
-
- v4l2_fh_del(fh);
- v4l2_fh_exit(fh);
-
- /* Easy case first: this stream was never claimed by us */
- if (s->fh != &id->fh) {
- kfree(id);
- return 0;
- }
-
- /* 'Unclaim' this stream */
-
- if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
- struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT];
-
- ivtv_stop_decoding(id, V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0);
-
- /* If all output streams are closed, and if the user doesn't have
- IVTV_DEC_STREAM_TYPE_VOUT open, then disable CC on TV-out. */
- if (itv->output_mode == OUT_NONE && !test_bit(IVTV_F_S_APPL_IO, &s_vout->s_flags)) {
- /* disable CC on TV-out */
- ivtv_disable_cc(itv);
- }
- } else {
- ivtv_stop_capture(id, 0);
- }
- kfree(id);
- return 0;
-}
-
-int ivtv_v4l2_open(struct file *filp)
-{
- struct video_device *vdev = video_devdata(filp);
- struct ivtv_stream *s = video_get_drvdata(vdev);
- struct ivtv *itv = s->itv;
- struct ivtv_open_id *item;
- int res = 0;
-
- IVTV_DEBUG_FILE("open %s\n", s->name);
-
- if (ivtv_init_on_first_open(itv)) {
- IVTV_ERR("Failed to initialize on device %s\n",
- video_device_node_name(vdev));
- return -ENXIO;
- }
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- /* Unless ivtv_fw_debug is set, error out if firmware dead. */
- if (ivtv_fw_debug) {
- IVTV_WARN("Opening %s with dead firmware lockout disabled\n",
- video_device_node_name(vdev));
- IVTV_WARN("Selected firmware errors will be ignored\n");
- } else {
-#else
- if (1) {
-#endif
- res = ivtv_firmware_check(itv, "ivtv_serialized_open");
- if (res == -EAGAIN)
- res = ivtv_firmware_check(itv, "ivtv_serialized_open");
- if (res < 0)
- return -EIO;
- }
-
- if (s->type == IVTV_DEC_STREAM_TYPE_MPG &&
- test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags))
- return -EBUSY;
-
- if (s->type == IVTV_DEC_STREAM_TYPE_YUV &&
- test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_MPG].s_flags))
- return -EBUSY;
-
- if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
- if (read_reg(0x82c) == 0) {
- IVTV_ERR("Tried to open YUV output device but need to send data to mpeg decoder before it can be used\n");
- /* return -ENODEV; */
- }
- ivtv_udma_alloc(itv);
- }
-
- /* Allocate memory */
- item = kzalloc(sizeof(struct ivtv_open_id), GFP_KERNEL);
- if (NULL == item) {
- IVTV_DEBUG_WARN("nomem on v4l2 open\n");
- return -ENOMEM;
- }
- v4l2_fh_init(&item->fh, s->vdev);
- item->itv = itv;
- item->type = s->type;
-
- filp->private_data = &item->fh;
- v4l2_fh_add(&item->fh);
-
- if (item->type == IVTV_ENC_STREAM_TYPE_RAD &&
- v4l2_fh_is_singular_file(filp)) {
- if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
- if (atomic_read(&itv->capturing) > 0) {
- /* switching to radio while capture is
- in progress is not polite */
- v4l2_fh_del(&item->fh);
- v4l2_fh_exit(&item->fh);
- kfree(item);
- return -EBUSY;
- }
- }
- /* Mark that the radio is being used. */
- set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
- /* We have the radio */
- ivtv_mute(itv);
- /* Switch tuner to radio */
- ivtv_call_all(itv, tuner, s_radio);
- /* Select the correct audio input (i.e. radio tuner) */
- ivtv_audio_set_io(itv);
- if (itv->hw_flags & IVTV_HW_SAA711X) {
- ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,
- SAA7115_FREQ_32_11_MHZ, SAA7115_FREQ_FL_APLL);
- }
- /* Done! Unmute and continue. */
- ivtv_unmute(itv);
- }
-
- /* YUV or MPG Decoding Mode? */
- if (s->type == IVTV_DEC_STREAM_TYPE_MPG) {
- clear_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);
- } else if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
- set_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);
- /* For yuv, we need to know the dma size before we start */
- itv->dma_data_req_size =
- 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
- itv->yuv_info.stream_size = 0;
- }
- return 0;
-}
-
-void ivtv_mute(struct ivtv *itv)
-{
- if (atomic_read(&itv->capturing))
- ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 1);
- IVTV_DEBUG_INFO("Mute\n");
-}
-
-void ivtv_unmute(struct ivtv *itv)
-{
- if (atomic_read(&itv->capturing)) {
- ivtv_msleep_timeout(100, 0);
- ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12);
- ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 0);
- }
- IVTV_DEBUG_INFO("Unmute\n");
-}
diff --git a/drivers/media/video/ivtv/ivtv-fileops.h b/drivers/media/video/ivtv/ivtv-fileops.h
deleted file mode 100644
index 049a2923965..00000000000
--- a/drivers/media/video/ivtv/ivtv-fileops.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- file operation functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_FILEOPS_H
-#define IVTV_FILEOPS_H
-
-/* Testing/Debugging */
-int ivtv_v4l2_open(struct file *filp);
-ssize_t ivtv_v4l2_read(struct file *filp, char __user *buf, size_t count,
- loff_t * pos);
-ssize_t ivtv_v4l2_write(struct file *filp, const char __user *buf, size_t count,
- loff_t * pos);
-int ivtv_v4l2_close(struct file *filp);
-unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait);
-unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table * wait);
-int ivtv_start_capture(struct ivtv_open_id *id);
-void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end);
-int ivtv_start_decoding(struct ivtv_open_id *id, int speed);
-void ivtv_mute(struct ivtv *itv);
-void ivtv_unmute(struct ivtv *itv);
-
-/* Utilities */
-
-/* Release a previously claimed stream. */
-void ivtv_release_stream(struct ivtv_stream *s);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c
deleted file mode 100644
index 02c5adebf51..00000000000
--- a/drivers/media/video/ivtv/ivtv-firmware.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- ivtv firmware functions.
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-firmware.h"
-#include "ivtv-yuv.h"
-#include "ivtv-ioctl.h"
-#include "ivtv-cards.h"
-#include <linux/firmware.h>
-#include <media/saa7127.h>
-
-#define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE
-#define IVTV_MASK_VPU_ENABLE15 0xFFFFFFF6
-#define IVTV_MASK_VPU_ENABLE16 0xFFFFFFFB
-#define IVTV_CMD_VDM_STOP 0x00000000
-#define IVTV_CMD_AO_STOP 0x00000005
-#define IVTV_CMD_APU_PING 0x00000000
-#define IVTV_CMD_VPU_STOP15 0xFFFFFFFE
-#define IVTV_CMD_VPU_STOP16 0xFFFFFFEE
-#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
-#define IVTV_CMD_SPU_STOP 0x00000001
-#define IVTV_CMD_SDRAM_PRECHARGE_INIT 0x0000001A
-#define IVTV_CMD_SDRAM_REFRESH_INIT 0x80000640
-#define IVTV_SDRAM_SLEEPTIME 600
-
-#define IVTV_DECODE_INIT_MPEG_FILENAME "v4l-cx2341x-init.mpg"
-#define IVTV_DECODE_INIT_MPEG_SIZE (152*1024)
-
-/* Encoder/decoder firmware sizes */
-#define IVTV_FW_ENC_SIZE (376836)
-#define IVTV_FW_DEC_SIZE (256*1024)
-
-static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv *itv, long size)
-{
- const struct firmware *fw = NULL;
- int retries = 3;
-
-retry:
- if (retries && request_firmware(&fw, fn, &itv->pdev->dev) == 0) {
- int i;
- volatile u32 __iomem *dst = (volatile u32 __iomem *)mem;
- const u32 *src = (const u32 *)fw->data;
-
- if (fw->size != size) {
- /* Due to race conditions in firmware loading (esp. with udev <0.95)
- the wrong file was sometimes loaded. So we check filesizes to
- see if at least the right-sized file was loaded. If not, then we
- retry. */
- IVTV_INFO("Retry: file loaded was not %s (expected size %ld, got %zd)\n", fn, size, fw->size);
- release_firmware(fw);
- retries--;
- goto retry;
- }
- for (i = 0; i < fw->size; i += 4) {
- /* no need for endianness conversion on the ppc */
- __raw_writel(*src, dst);
- dst++;
- src++;
- }
- IVTV_INFO("Loaded %s firmware (%zd bytes)\n", fn, fw->size);
- release_firmware(fw);
- return size;
- }
- IVTV_ERR("Unable to open firmware %s (must be %ld bytes)\n", fn, size);
- IVTV_ERR("Did you put the firmware in the hotplug firmware directory?\n");
- return -ENOMEM;
-}
-
-void ivtv_halt_firmware(struct ivtv *itv)
-{
- IVTV_DEBUG_INFO("Preparing for firmware halt.\n");
- if (itv->has_cx23415 && itv->dec_mbox.mbox)
- ivtv_vapi(itv, CX2341X_DEC_HALT_FW, 0);
- if (itv->enc_mbox.mbox)
- ivtv_vapi(itv, CX2341X_ENC_HALT_FW, 0);
-
- ivtv_msleep_timeout(10, 0);
- itv->enc_mbox.mbox = itv->dec_mbox.mbox = NULL;
-
- IVTV_DEBUG_INFO("Stopping VDM\n");
- write_reg(IVTV_CMD_VDM_STOP, IVTV_REG_VDM);
-
- IVTV_DEBUG_INFO("Stopping AO\n");
- write_reg(IVTV_CMD_AO_STOP, IVTV_REG_AO);
-
- IVTV_DEBUG_INFO("pinging (?) APU\n");
- write_reg(IVTV_CMD_APU_PING, IVTV_REG_APU);
-
- IVTV_DEBUG_INFO("Stopping VPU\n");
- if (!itv->has_cx23415)
- write_reg(IVTV_CMD_VPU_STOP16, IVTV_REG_VPU);
- else
- write_reg(IVTV_CMD_VPU_STOP15, IVTV_REG_VPU);
-
- IVTV_DEBUG_INFO("Resetting Hw Blocks\n");
- write_reg(IVTV_CMD_HW_BLOCKS_RST, IVTV_REG_HW_BLOCKS);
-
- IVTV_DEBUG_INFO("Stopping SPU\n");
- write_reg(IVTV_CMD_SPU_STOP, IVTV_REG_SPU);
-
- ivtv_msleep_timeout(10, 0);
-
- IVTV_DEBUG_INFO("init Encoder SDRAM pre-charge\n");
- write_reg(IVTV_CMD_SDRAM_PRECHARGE_INIT, IVTV_REG_ENC_SDRAM_PRECHARGE);
-
- IVTV_DEBUG_INFO("init Encoder SDRAM refresh to 1us\n");
- write_reg(IVTV_CMD_SDRAM_REFRESH_INIT, IVTV_REG_ENC_SDRAM_REFRESH);
-
- if (itv->has_cx23415) {
- IVTV_DEBUG_INFO("init Decoder SDRAM pre-charge\n");
- write_reg(IVTV_CMD_SDRAM_PRECHARGE_INIT, IVTV_REG_DEC_SDRAM_PRECHARGE);
-
- IVTV_DEBUG_INFO("init Decoder SDRAM refresh to 1us\n");
- write_reg(IVTV_CMD_SDRAM_REFRESH_INIT, IVTV_REG_DEC_SDRAM_REFRESH);
- }
-
- IVTV_DEBUG_INFO("Sleeping for %dms\n", IVTV_SDRAM_SLEEPTIME);
- ivtv_msleep_timeout(IVTV_SDRAM_SLEEPTIME, 0);
-}
-
-void ivtv_firmware_versions(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
-
- /* Encoder */
- ivtv_vapi_result(itv, data, CX2341X_ENC_GET_VERSION, 0);
- IVTV_INFO("Encoder revision: 0x%08x\n", data[0]);
-
- if (data[0] != 0x02060039)
- IVTV_WARN("Recommended firmware version is 0x02060039.\n");
-
- if (itv->has_cx23415) {
- /* Decoder */
- ivtv_vapi_result(itv, data, CX2341X_DEC_GET_VERSION, 0);
- IVTV_INFO("Decoder revision: 0x%08x\n", data[0]);
- }
-}
-
-static int ivtv_firmware_copy(struct ivtv *itv)
-{
- IVTV_DEBUG_INFO("Loading encoder image\n");
- if (load_fw_direct(CX2341X_FIRM_ENC_FILENAME,
- itv->enc_mem, itv, IVTV_FW_ENC_SIZE) != IVTV_FW_ENC_SIZE) {
- IVTV_DEBUG_WARN("failed loading encoder firmware\n");
- return -3;
- }
- if (!itv->has_cx23415)
- return 0;
-
- IVTV_DEBUG_INFO("Loading decoder image\n");
- if (load_fw_direct(CX2341X_FIRM_DEC_FILENAME,
- itv->dec_mem, itv, IVTV_FW_DEC_SIZE) != IVTV_FW_DEC_SIZE) {
- IVTV_DEBUG_WARN("failed loading decoder firmware\n");
- return -1;
- }
- return 0;
-}
-
-static volatile struct ivtv_mailbox __iomem *ivtv_search_mailbox(const volatile u8 __iomem *mem, u32 size)
-{
- int i;
-
- /* mailbox is preceded by a 16 byte 'magic cookie' starting at a 256-byte
- address boundary */
- for (i = 0; i < size; i += 0x100) {
- if (readl(mem + i) == 0x12345678 &&
- readl(mem + i + 4) == 0x34567812 &&
- readl(mem + i + 8) == 0x56781234 &&
- readl(mem + i + 12) == 0x78123456) {
- return (volatile struct ivtv_mailbox __iomem *)(mem + i + 16);
- }
- }
- return NULL;
-}
-
-int ivtv_firmware_init(struct ivtv *itv)
-{
- int err;
-
- ivtv_halt_firmware(itv);
-
- /* load firmware */
- err = ivtv_firmware_copy(itv);
- if (err) {
- IVTV_DEBUG_WARN("Error %d loading firmware\n", err);
- return err;
- }
-
- /* start firmware */
- write_reg(read_reg(IVTV_REG_SPU) & IVTV_MASK_SPU_ENABLE, IVTV_REG_SPU);
- ivtv_msleep_timeout(100, 0);
- if (itv->has_cx23415)
- write_reg(read_reg(IVTV_REG_VPU) & IVTV_MASK_VPU_ENABLE15, IVTV_REG_VPU);
- else
- write_reg(read_reg(IVTV_REG_VPU) & IVTV_MASK_VPU_ENABLE16, IVTV_REG_VPU);
- ivtv_msleep_timeout(100, 0);
-
- /* find mailboxes and ping firmware */
- itv->enc_mbox.mbox = ivtv_search_mailbox(itv->enc_mem, IVTV_ENCODER_SIZE);
- if (itv->enc_mbox.mbox == NULL)
- IVTV_ERR("Encoder mailbox not found\n");
- else if (ivtv_vapi(itv, CX2341X_ENC_PING_FW, 0)) {
- IVTV_ERR("Encoder firmware dead!\n");
- itv->enc_mbox.mbox = NULL;
- }
- if (itv->enc_mbox.mbox == NULL)
- return -ENODEV;
-
- if (!itv->has_cx23415)
- return 0;
-
- itv->dec_mbox.mbox = ivtv_search_mailbox(itv->dec_mem, IVTV_DECODER_SIZE);
- if (itv->dec_mbox.mbox == NULL) {
- IVTV_ERR("Decoder mailbox not found\n");
- } else if (itv->has_cx23415 && ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0)) {
- IVTV_ERR("Decoder firmware dead!\n");
- itv->dec_mbox.mbox = NULL;
- } else {
- /* Firmware okay, so check yuv output filter table */
- ivtv_yuv_filter_check(itv);
- }
- return itv->dec_mbox.mbox ? 0 : -ENODEV;
-}
-
-void ivtv_init_mpeg_decoder(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- long readbytes;
- volatile u8 __iomem *mem_offset;
-
- data[0] = 0;
- data[1] = itv->cxhdl.width; /* YUV source width */
- data[2] = itv->cxhdl.height;
- data[3] = itv->cxhdl.audio_properties; /* Audio settings to use,
- bitmap. see docs. */
- if (ivtv_api(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, data)) {
- IVTV_ERR("ivtv_init_mpeg_decoder failed to set decoder source\n");
- return;
- }
-
- if (ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 1) != 0) {
- IVTV_ERR("ivtv_init_mpeg_decoder failed to start playback\n");
- return;
- }
- ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data);
- mem_offset = itv->dec_mem + data[1];
-
- if ((readbytes = load_fw_direct(IVTV_DECODE_INIT_MPEG_FILENAME,
- mem_offset, itv, IVTV_DECODE_INIT_MPEG_SIZE)) <= 0) {
- IVTV_DEBUG_WARN("failed to read mpeg decoder initialisation file %s\n",
- IVTV_DECODE_INIT_MPEG_FILENAME);
- } else {
- ivtv_vapi(itv, CX2341X_DEC_SCHED_DMA_FROM_HOST, 3, 0, readbytes, 0);
- ivtv_msleep_timeout(100, 0);
- }
- ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 4, 0, 0, 0, 1);
-}
-
-/* Try to restart the card & restore previous settings */
-int ivtv_firmware_restart(struct ivtv *itv)
-{
- int rc = 0;
- v4l2_std_id std;
-
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
- /* Display test image during restart */
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
- SAA7127_INPUT_TYPE_TEST_IMAGE,
- itv->card->video_outputs[itv->active_output].video_output,
- 0);
-
- mutex_lock(&itv->udma.lock);
-
- rc = ivtv_firmware_init(itv);
- if (rc) {
- mutex_unlock(&itv->udma.lock);
- return rc;
- }
-
- /* Allow settings to reload */
- ivtv_mailbox_cache_invalidate(itv);
-
- /* Restore encoder video standard */
- std = itv->std;
- itv->std = 0;
- ivtv_s_std_enc(itv, &std);
-
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
- ivtv_init_mpeg_decoder(itv);
-
- /* Restore decoder video standard */
- std = itv->std_out;
- itv->std_out = 0;
- ivtv_s_std_dec(itv, &std);
-
- /* Restore framebuffer if active */
- if (itv->ivtvfb_restore)
- itv->ivtvfb_restore(itv);
-
- /* Restore alpha settings */
- ivtv_set_osd_alpha(itv);
-
- /* Restore normal output */
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
- SAA7127_INPUT_TYPE_NORMAL,
- itv->card->video_outputs[itv->active_output].video_output,
- 0);
- }
-
- mutex_unlock(&itv->udma.lock);
- return rc;
-}
-
-/* Check firmware running state. The checks fall through
- allowing multiple failures to be logged. */
-int ivtv_firmware_check(struct ivtv *itv, char *where)
-{
- int res = 0;
-
- /* Check encoder is still running */
- if (ivtv_vapi(itv, CX2341X_ENC_PING_FW, 0) < 0) {
- IVTV_WARN("Encoder has died : %s\n", where);
- res = -1;
- }
-
- /* Also check audio. Only check if not in use & encoder is okay */
- if (!res && !atomic_read(&itv->capturing) &&
- (!atomic_read(&itv->decoding) ||
- (atomic_read(&itv->decoding) < 2 && test_bit(IVTV_F_I_DEC_YUV,
- &itv->i_flags)))) {
-
- if (ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12) < 0) {
- IVTV_WARN("Audio has died (Encoder OK) : %s\n", where);
- res = -2;
- }
- }
-
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
- /* Second audio check. Skip if audio already failed */
- if (res != -2 && read_dec(0x100) != read_dec(0x104)) {
- /* Wait & try again to be certain. */
- ivtv_msleep_timeout(14, 0);
- if (read_dec(0x100) != read_dec(0x104)) {
- IVTV_WARN("Audio has died (Decoder) : %s\n",
- where);
- res = -1;
- }
- }
-
- /* Check decoder is still running */
- if (ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0) < 0) {
- IVTV_WARN("Decoder has died : %s\n", where);
- res = -1;
- }
- }
-
- /* If something failed & currently idle, try to reload */
- if (res && !atomic_read(&itv->capturing) &&
- !atomic_read(&itv->decoding)) {
- IVTV_INFO("Detected in %s that firmware had failed - "
- "Reloading\n", where);
- res = ivtv_firmware_restart(itv);
- /*
- * Even if restarted ok, still signal a problem had occurred.
- * The caller can come through this function again to check
- * if things are really ok after the restart.
- */
- if (!res) {
- IVTV_INFO("Firmware restart okay\n");
- res = -EAGAIN;
- } else {
- IVTV_INFO("Firmware restart failed\n");
- }
- } else if (res) {
- res = -EIO;
- }
-
- return res;
-}
diff --git a/drivers/media/video/ivtv/ivtv-firmware.h b/drivers/media/video/ivtv/ivtv-firmware.h
deleted file mode 100644
index 52bb4e5598f..00000000000
--- a/drivers/media/video/ivtv/ivtv-firmware.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- ivtv firmware functions.
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_FIRMWARE_H
-#define IVTV_FIRMWARE_H
-
-int ivtv_firmware_init(struct ivtv *itv);
-void ivtv_firmware_versions(struct ivtv *itv);
-void ivtv_halt_firmware(struct ivtv *itv);
-void ivtv_init_mpeg_decoder(struct ivtv *itv);
-int ivtv_firmware_check(struct ivtv *itv, char *where);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
deleted file mode 100644
index 8f0d0778905..00000000000
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- gpio functions.
- Merging GPIO support into driver:
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-cards.h"
-#include "ivtv-gpio.h"
-#include "tuner-xc2028.h"
-#include <media/tuner.h>
-#include <media/v4l2-ctrls.h>
-
-/*
- * GPIO assignment of Yuan MPG600/MPG160
- *
- * bit 15 14 13 12 | 11 10 9 8 | 7 6 5 4 | 3 2 1 0
- * OUTPUT IN1 IN0 AM3 AM2 AM1 AM0
- * INPUT DM1 DM0
- *
- * IN* : Input selection
- * IN1 IN0
- * 1 1 N/A
- * 1 0 Line
- * 0 1 N/A
- * 0 0 Tuner
- *
- * AM* : Audio Mode
- * AM3 0: Normal 1: Mixed(Sub+Main channel)
- * AM2 0: Subchannel 1: Main channel
- * AM1 0: Stereo 1: Mono
- * AM0 0: Normal 1: Mute
- *
- * DM* : Detected tuner audio Mode
- * DM1 0: Stereo 1: Mono
- * DM0 0: Multiplex 1: Normal
- *
- * GPIO Initial Settings
- * MPG600 MPG160
- * DIR 0x3080 0x7080
- * OUTPUT 0x000C 0x400C
- *
- * Special thanks to Makoto Iguchi <iguchi@tahoo.org> and Mr. Anonymous
- * for analyzing GPIO of MPG160.
- *
- *****************************************************************************
- *
- * GPIO assignment of Avermedia M179 (per information direct from AVerMedia)
- *
- * bit 15 14 13 12 | 11 10 9 8 | 7 6 5 4 | 3 2 1 0
- * OUTPUT IN0 AM0 IN1 AM1 AM2 IN2 BR0 BR1
- * INPUT
- *
- * IN* : Input selection
- * IN0 IN1 IN2
- * * 1 * Mute
- * 0 0 0 Line-In
- * 1 0 0 TV Tuner Audio
- * 0 0 1 FM Audio
- * 1 0 1 Mute
- *
- * AM* : Audio Mode
- * AM0 AM1 AM2
- * 0 0 0 TV Tuner Audio: L_OUT=(L+R)/2, R_OUT=SAP
- * 0 0 1 TV Tuner Audio: L_OUT=R_OUT=SAP (SAP)
- * 0 1 0 TV Tuner Audio: L_OUT=L, R_OUT=R (stereo)
- * 0 1 1 TV Tuner Audio: mute
- * 1 * * TV Tuner Audio: L_OUT=R_OUT=(L+R)/2 (mono)
- *
- * BR* : Audio Sample Rate (BR stands for bitrate for some reason)
- * BR0 BR1
- * 0 0 32 kHz
- * 0 1 44.1 kHz
- * 1 0 48 kHz
- *
- * DM* : Detected tuner audio Mode
- * Unknown currently
- *
- * Special thanks to AVerMedia Technologies, Inc. and Jiun-Kuei Jung at
- * AVerMedia for providing the GPIO information used to add support
- * for the M179 cards.
- */
-
-/********************* GPIO stuffs *********************/
-
-/* GPIO registers */
-#define IVTV_REG_GPIO_IN 0x9008
-#define IVTV_REG_GPIO_OUT 0x900c
-#define IVTV_REG_GPIO_DIR 0x9020
-
-void ivtv_reset_ir_gpio(struct ivtv *itv)
-{
- int curdir, curout;
-
- if (itv->card->type != IVTV_CARD_PVR_150)
- return;
- IVTV_DEBUG_INFO("Resetting PVR150 IR\n");
- curout = read_reg(IVTV_REG_GPIO_OUT);
- curdir = read_reg(IVTV_REG_GPIO_DIR);
- curdir |= 0x80;
- write_reg(curdir, IVTV_REG_GPIO_DIR);
- curout = (curout & ~0xF) | 1;
- write_reg(curout, IVTV_REG_GPIO_OUT);
- /* We could use something else for smaller time */
- schedule_timeout_interruptible(msecs_to_jiffies(1));
- curout |= 2;
- write_reg(curout, IVTV_REG_GPIO_OUT);
- curdir &= ~0x80;
- write_reg(curdir, IVTV_REG_GPIO_DIR);
-}
-
-/* Xceive tuner reset function */
-int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value)
-{
- struct i2c_algo_bit_data *algo = dev;
- struct ivtv *itv = algo->data;
- u32 curout;
-
- if (cmd != XC2028_TUNER_RESET)
- return 0;
- IVTV_DEBUG_INFO("Resetting tuner\n");
- curout = read_reg(IVTV_REG_GPIO_OUT);
- curout &= ~(1 << itv->card->xceive_pin);
- write_reg(curout, IVTV_REG_GPIO_OUT);
- schedule_timeout_interruptible(msecs_to_jiffies(1));
-
- curout |= 1 << itv->card->xceive_pin;
- write_reg(curout, IVTV_REG_GPIO_OUT);
- schedule_timeout_interruptible(msecs_to_jiffies(1));
- return 0;
-}
-
-static inline struct ivtv *sd_to_ivtv(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct ivtv, sd_gpio);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct ivtv, hdl_gpio)->sd_gpio;
-}
-
-static int subdev_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
-{
- struct ivtv *itv = sd_to_ivtv(sd);
- u16 mask, data;
-
- mask = itv->card->gpio_audio_freq.mask;
- switch (freq) {
- case 32000:
- data = itv->card->gpio_audio_freq.f32000;
- break;
- case 44100:
- data = itv->card->gpio_audio_freq.f44100;
- break;
- case 48000:
- default:
- data = itv->card->gpio_audio_freq.f48000;
- break;
- }
- if (mask)
- write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
- return 0;
-}
-
-static int subdev_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct ivtv *itv = sd_to_ivtv(sd);
- u16 mask;
-
- mask = itv->card->gpio_audio_detect.mask;
- if (mask == 0 || (read_reg(IVTV_REG_GPIO_IN) & mask))
- vt->rxsubchans = V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- else
- vt->rxsubchans = V4L2_TUNER_SUB_MONO;
- return 0;
-}
-
-static int subdev_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct ivtv *itv = sd_to_ivtv(sd);
- u16 mask, data;
-
- mask = itv->card->gpio_audio_mode.mask;
- switch (vt->audmode) {
- case V4L2_TUNER_MODE_LANG1:
- data = itv->card->gpio_audio_mode.lang1;
- break;
- case V4L2_TUNER_MODE_LANG2:
- data = itv->card->gpio_audio_mode.lang2;
- break;
- case V4L2_TUNER_MODE_MONO:
- data = itv->card->gpio_audio_mode.mono;
- break;
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1_LANG2:
- default:
- data = itv->card->gpio_audio_mode.stereo;
- break;
- }
- if (mask)
- write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
- return 0;
-}
-
-static int subdev_s_radio(struct v4l2_subdev *sd)
-{
- struct ivtv *itv = sd_to_ivtv(sd);
- u16 mask, data;
-
- mask = itv->card->gpio_audio_input.mask;
- data = itv->card->gpio_audio_input.radio;
- if (mask)
- write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
- return 0;
-}
-
-static int subdev_s_audio_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct ivtv *itv = sd_to_ivtv(sd);
- u16 mask, data;
-
- if (input > 2)
- return -EINVAL;
- mask = itv->card->gpio_audio_input.mask;
- switch (input) {
- case 0:
- data = itv->card->gpio_audio_input.tuner;
- break;
- case 1:
- data = itv->card->gpio_audio_input.linein;
- break;
- case 2:
- default:
- data = itv->card->gpio_audio_input.radio;
- break;
- }
- if (mask)
- write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
- return 0;
-}
-
-static int subdev_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct ivtv *itv = sd_to_ivtv(sd);
- u16 mask, data;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- mask = itv->card->gpio_audio_mute.mask;
- data = ctrl->val ? itv->card->gpio_audio_mute.mute : 0;
- if (mask)
- write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) |
- (data & mask), IVTV_REG_GPIO_OUT);
- return 0;
- }
- return -EINVAL;
-}
-
-
-static int subdev_log_status(struct v4l2_subdev *sd)
-{
- struct ivtv *itv = sd_to_ivtv(sd);
-
- IVTV_INFO("GPIO status: DIR=0x%04x OUT=0x%04x IN=0x%04x\n",
- read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT),
- read_reg(IVTV_REG_GPIO_IN));
- v4l2_ctrl_handler_log_status(&itv->hdl_gpio, sd->name);
- return 0;
-}
-
-static int subdev_s_video_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct ivtv *itv = sd_to_ivtv(sd);
- u16 mask, data;
-
- if (input > 2) /* 0:Tuner 1:Composite 2:S-Video */
- return -EINVAL;
- mask = itv->card->gpio_video_input.mask;
- if (input == 0)
- data = itv->card->gpio_video_input.tuner;
- else if (input == 1)
- data = itv->card->gpio_video_input.composite;
- else
- data = itv->card->gpio_video_input.svideo;
- if (mask)
- write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
- return 0;
-}
-
-static const struct v4l2_ctrl_ops gpio_ctrl_ops = {
- .s_ctrl = subdev_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops subdev_core_ops = {
- .log_status = subdev_log_status,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
-};
-
-static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = {
- .s_radio = subdev_s_radio,
- .g_tuner = subdev_g_tuner,
- .s_tuner = subdev_s_tuner,
-};
-
-static const struct v4l2_subdev_audio_ops subdev_audio_ops = {
- .s_clock_freq = subdev_s_clock_freq,
- .s_routing = subdev_s_audio_routing,
-};
-
-static const struct v4l2_subdev_video_ops subdev_video_ops = {
- .s_routing = subdev_s_video_routing,
-};
-
-static const struct v4l2_subdev_ops subdev_ops = {
- .core = &subdev_core_ops,
- .tuner = &subdev_tuner_ops,
- .audio = &subdev_audio_ops,
- .video = &subdev_video_ops,
-};
-
-int ivtv_gpio_init(struct ivtv *itv)
-{
- u16 pin = 0;
-
- if (itv->card->xceive_pin)
- pin = 1 << itv->card->xceive_pin;
-
- if ((itv->card->gpio_init.direction | pin) == 0)
- return 0;
-
- IVTV_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n",
- read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT));
-
- /* init output data then direction */
- write_reg(itv->card->gpio_init.initial_value | pin, IVTV_REG_GPIO_OUT);
- write_reg(itv->card->gpio_init.direction | pin, IVTV_REG_GPIO_DIR);
- v4l2_subdev_init(&itv->sd_gpio, &subdev_ops);
- snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->v4l2_dev.name);
- itv->sd_gpio.grp_id = IVTV_HW_GPIO;
- v4l2_ctrl_handler_init(&itv->hdl_gpio, 1);
- v4l2_ctrl_new_std(&itv->hdl_gpio, &gpio_ctrl_ops,
- V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
- if (itv->hdl_gpio.error)
- return itv->hdl_gpio.error;
- itv->sd_gpio.ctrl_handler = &itv->hdl_gpio;
- v4l2_ctrl_handler_setup(&itv->hdl_gpio);
- return v4l2_device_register_subdev(&itv->v4l2_dev, &itv->sd_gpio);
-}
diff --git a/drivers/media/video/ivtv/ivtv-gpio.h b/drivers/media/video/ivtv/ivtv-gpio.h
deleted file mode 100644
index 0b5d19c8ecb..00000000000
--- a/drivers/media/video/ivtv/ivtv-gpio.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- gpio functions.
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_GPIO_H
-#define IVTV_GPIO_H
-
-/* GPIO stuff */
-int ivtv_gpio_init(struct ivtv *itv);
-void ivtv_reset_ir_gpio(struct ivtv *itv);
-int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
deleted file mode 100644
index d47f41a0ef6..00000000000
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ /dev/null
@@ -1,760 +0,0 @@
-/*
- I2C functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- This file includes an i2c implementation that was reverse engineered
- from the Hauppauge windows driver. Older ivtv versions used i2c-algo-bit,
- which whilst fine under most circumstances, had trouble with the Zilog
- CPU on the PVR-150 which handles IR functions (occasional inability to
- communicate with the chip until it was reset) and also with the i2c
- bus being completely unreachable when multiple PVR cards were present.
-
- The implementation is very similar to i2c-algo-bit, but there are enough
- subtle differences that the two are hard to merge. The general strategy
- employed by i2c-algo-bit is to use udelay() to implement the timing
- when putting out bits on the scl/sda lines. The general strategy taken
- here is to poll the lines for state changes (see ivtv_waitscl and
- ivtv_waitsda). In addition there are small delays at various locations
- which poll the SCL line 5 times (ivtv_scldelay). I would guess that
- since this is memory mapped I/O that the length of those delays is tied
- to the PCI bus clock. There is some extra code to do with recovery
- and retries. Since it is not known what causes the actual i2c problems
- in the first place, the only goal if one was to attempt to use
- i2c-algo-bit would be to try to make it follow the same code path.
- This would be a lot of work, and I'm also not convinced that it would
- provide a generic benefit to i2c-algo-bit. Therefore consider this
- an engineering solution -- not pretty, but it works.
-
- Some more general comments about what we are doing:
-
- The i2c bus is a 2 wire serial bus, with clock (SCL) and data (SDA)
- lines. To communicate on the bus (as a master, we don't act as a slave),
- we first initiate a start condition (ivtv_start). We then write the
- address of the device that we want to communicate with, along with a flag
- that indicates whether this is a read or a write. The slave then issues
- an ACK signal (ivtv_ack), which tells us that it is ready for reading /
- writing. We then proceed with reading or writing (ivtv_read/ivtv_write),
- and finally issue a stop condition (ivtv_stop) to make the bus available
- to other masters.
-
- There is an additional form of transaction where a write may be
- immediately followed by a read. In this case, there is no intervening
- stop condition. (Only the msp3400 chip uses this method of data transfer).
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-cards.h"
-#include "ivtv-gpio.h"
-#include "ivtv-i2c.h"
-#include <media/cx25840.h>
-
-/* i2c implementation for cx23415/6 chip, ivtv project.
- * Author: Kevin Thayer (nufan_wfk at yahoo.com)
- */
-/* i2c stuff */
-#define IVTV_REG_I2C_SETSCL_OFFSET 0x7000
-#define IVTV_REG_I2C_SETSDA_OFFSET 0x7004
-#define IVTV_REG_I2C_GETSCL_OFFSET 0x7008
-#define IVTV_REG_I2C_GETSDA_OFFSET 0x700c
-
-#define IVTV_CS53L32A_I2C_ADDR 0x11
-#define IVTV_M52790_I2C_ADDR 0x48
-#define IVTV_CX25840_I2C_ADDR 0x44
-#define IVTV_SAA7115_I2C_ADDR 0x21
-#define IVTV_SAA7127_I2C_ADDR 0x44
-#define IVTV_SAA717x_I2C_ADDR 0x21
-#define IVTV_MSP3400_I2C_ADDR 0x40
-#define IVTV_HAUPPAUGE_I2C_ADDR 0x50
-#define IVTV_WM8739_I2C_ADDR 0x1a
-#define IVTV_WM8775_I2C_ADDR 0x1b
-#define IVTV_TEA5767_I2C_ADDR 0x60
-#define IVTV_UPD64031A_I2C_ADDR 0x12
-#define IVTV_UPD64083_I2C_ADDR 0x5c
-#define IVTV_VP27SMPX_I2C_ADDR 0x5b
-#define IVTV_M52790_I2C_ADDR 0x48
-#define IVTV_AVERMEDIA_IR_RX_I2C_ADDR 0x40
-#define IVTV_HAUP_EXT_IR_RX_I2C_ADDR 0x1a
-#define IVTV_HAUP_INT_IR_RX_I2C_ADDR 0x18
-#define IVTV_Z8F0811_IR_TX_I2C_ADDR 0x70
-#define IVTV_Z8F0811_IR_RX_I2C_ADDR 0x71
-#define IVTV_ADAPTEC_IR_ADDR 0x6b
-
-/* This array should match the IVTV_HW_ defines */
-static const u8 hw_addrs[] = {
- IVTV_CX25840_I2C_ADDR,
- IVTV_SAA7115_I2C_ADDR,
- IVTV_SAA7127_I2C_ADDR,
- IVTV_MSP3400_I2C_ADDR,
- 0,
- IVTV_WM8775_I2C_ADDR,
- IVTV_CS53L32A_I2C_ADDR,
- 0,
- IVTV_SAA7115_I2C_ADDR,
- IVTV_UPD64031A_I2C_ADDR,
- IVTV_UPD64083_I2C_ADDR,
- IVTV_SAA717x_I2C_ADDR,
- IVTV_WM8739_I2C_ADDR,
- IVTV_VP27SMPX_I2C_ADDR,
- IVTV_M52790_I2C_ADDR,
- 0, /* IVTV_HW_GPIO dummy driver ID */
- IVTV_AVERMEDIA_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_AVER */
- IVTV_HAUP_EXT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_EXT */
- IVTV_HAUP_INT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_INT */
- IVTV_Z8F0811_IR_TX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_TX_HAUP */
- IVTV_Z8F0811_IR_RX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_RX_HAUP */
- IVTV_ADAPTEC_IR_ADDR, /* IVTV_HW_I2C_IR_RX_ADAPTEC */
-};
-
-/* This array should match the IVTV_HW_ defines */
-static const char * const hw_devicenames[] = {
- "cx25840",
- "saa7115",
- "saa7127_auto", /* saa7127 or saa7129 */
- "msp3400",
- "tuner",
- "wm8775",
- "cs53l32a",
- "tveeprom",
- "saa7114",
- "upd64031a",
- "upd64083",
- "saa717x",
- "wm8739",
- "vp27smpx",
- "m52790",
- "gpio",
- "ir_video", /* IVTV_HW_I2C_IR_RX_AVER */
- "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_EXT */
- "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_INT */
- "ir_tx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_TX_HAUP */
- "ir_rx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_RX_HAUP */
- "ir_video", /* IVTV_HW_I2C_IR_RX_ADAPTEC */
-};
-
-static int get_key_adaptec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- unsigned char keybuf[4];
-
- keybuf[0] = 0x00;
- i2c_master_send(ir->c, keybuf, 1);
- /* poll IR chip */
- if (i2c_master_recv(ir->c, keybuf, sizeof(keybuf)) != sizeof(keybuf)) {
- return 0;
- }
-
- /* key pressed ? */
- if (keybuf[2] == 0xff)
- return 0;
-
- /* remove repeat bit */
- keybuf[2] &= 0x7f;
- keybuf[3] |= 0x80;
-
- *ir_key = keybuf[3] | keybuf[2] << 8 | keybuf[1] << 16 |keybuf[0] << 24;
- *ir_raw = *ir_key;
-
- return 1;
-}
-
-static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
-{
- struct i2c_board_info info;
- struct i2c_adapter *adap = &itv->i2c_adap;
- struct IR_i2c_init_data *init_data = &itv->ir_i2c_init_data;
- unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
-
- /* Only allow one IR transmitter to be registered per board */
- if (hw & IVTV_HW_IR_TX_ANY) {
- if (itv->hw_flags & IVTV_HW_IR_TX_ANY)
- return -1;
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, type, I2C_NAME_SIZE);
- return i2c_new_probed_device(adap, &info, addr_list, NULL)
- == NULL ? -1 : 0;
- }
-
- /* Only allow one IR receiver to be registered per board */
- if (itv->hw_flags & IVTV_HW_IR_RX_ANY)
- return -1;
-
- /* Our default information for ir-kbd-i2c.c to use */
- switch (hw) {
- case IVTV_HW_I2C_IR_RX_AVER:
- init_data->ir_codes = RC_MAP_AVERMEDIA_CARDBUS;
- init_data->internal_get_key_func =
- IR_KBD_GET_KEY_AVERMEDIA_CARDBUS;
- init_data->type = RC_TYPE_OTHER;
- init_data->name = "AVerMedia AVerTV card";
- break;
- case IVTV_HW_I2C_IR_RX_HAUP_EXT:
- case IVTV_HW_I2C_IR_RX_HAUP_INT:
- init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
- init_data->type = RC_TYPE_RC5;
- init_data->name = itv->card_name;
- break;
- case IVTV_HW_Z8F0811_IR_RX_HAUP:
- /* Default to grey remote */
- init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
- init_data->type = RC_TYPE_RC5;
- init_data->name = itv->card_name;
- break;
- case IVTV_HW_I2C_IR_RX_ADAPTEC:
- init_data->get_key = get_key_adaptec;
- init_data->name = itv->card_name;
- /* FIXME: The protocol and RC_MAP needs to be corrected */
- init_data->ir_codes = RC_MAP_EMPTY;
- init_data->type = RC_TYPE_UNKNOWN;
- break;
- }
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- info.platform_data = init_data;
- strlcpy(info.type, type, I2C_NAME_SIZE);
-
- return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
- -1 : 0;
-}
-
-/* Instantiate the IR receiver device using probing -- undesirable */
-struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv)
-{
- struct i2c_board_info info;
- /*
- * The external IR receiver is at i2c address 0x34.
- * The internal IR receiver is at i2c address 0x30.
- *
- * In theory, both can be fitted, and Hauppauge suggests an external
- * overrides an internal. That's why we probe 0x1a (~0x34) first. CB
- *
- * Some of these addresses we probe may collide with other i2c address
- * allocations, so this function must be called after all other i2c
- * devices we care about are registered.
- */
- const unsigned short addr_list[] = {
- 0x1a, /* Hauppauge IR external - collides with WM8739 */
- 0x18, /* Hauppauge IR internal */
- I2C_CLIENT_END
- };
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
- return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list, NULL);
-}
-
-int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
-{
- struct v4l2_subdev *sd;
- struct i2c_adapter *adap = &itv->i2c_adap;
- const char *type = hw_devicenames[idx];
- u32 hw = 1 << idx;
-
- if (idx >= ARRAY_SIZE(hw_addrs))
- return -1;
- if (hw == IVTV_HW_TUNER) {
- /* special tuner handling */
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
- itv->card_i2c->radio);
- if (sd)
- sd->grp_id = 1 << idx;
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
- itv->card_i2c->demod);
- if (sd)
- sd->grp_id = 1 << idx;
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
- itv->card_i2c->tv);
- if (sd)
- sd->grp_id = 1 << idx;
- return sd ? 0 : -1;
- }
-
- if (hw & IVTV_HW_IR_ANY)
- return ivtv_i2c_new_ir(itv, hw, type, hw_addrs[idx]);
-
- /* Is it not an I2C device or one we do not wish to register? */
- if (!hw_addrs[idx])
- return -1;
-
- /* It's an I2C device other than an analog tuner or IR chip */
- if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
- adap, type, 0, I2C_ADDRS(hw_addrs[idx]));
- } else if (hw == IVTV_HW_CX25840) {
- struct cx25840_platform_data pdata;
- struct i2c_board_info cx25840_info = {
- .type = "cx25840",
- .addr = hw_addrs[idx],
- .platform_data = &pdata,
- };
-
- pdata.pvr150_workaround = itv->pvr150_workaround;
- sd = v4l2_i2c_new_subdev_board(&itv->v4l2_dev, adap,
- &cx25840_info, NULL);
- } else {
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
- adap, type, hw_addrs[idx], NULL);
- }
- if (sd)
- sd->grp_id = 1 << idx;
- return sd ? 0 : -1;
-}
-
-struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw)
-{
- struct v4l2_subdev *result = NULL;
- struct v4l2_subdev *sd;
-
- spin_lock(&itv->v4l2_dev.lock);
- v4l2_device_for_each_subdev(sd, &itv->v4l2_dev) {
- if (sd->grp_id == hw) {
- result = sd;
- break;
- }
- }
- spin_unlock(&itv->v4l2_dev.lock);
- return result;
-}
-
-/* Set the serial clock line to the desired state */
-static void ivtv_setscl(struct ivtv *itv, int state)
-{
- /* write them out */
- /* write bits are inverted */
- write_reg(~state, IVTV_REG_I2C_SETSCL_OFFSET);
-}
-
-/* Set the serial data line to the desired state */
-static void ivtv_setsda(struct ivtv *itv, int state)
-{
- /* write them out */
- /* write bits are inverted */
- write_reg(~state & 1, IVTV_REG_I2C_SETSDA_OFFSET);
-}
-
-/* Read the serial clock line */
-static int ivtv_getscl(struct ivtv *itv)
-{
- return read_reg(IVTV_REG_I2C_GETSCL_OFFSET) & 1;
-}
-
-/* Read the serial data line */
-static int ivtv_getsda(struct ivtv *itv)
-{
- return read_reg(IVTV_REG_I2C_GETSDA_OFFSET) & 1;
-}
-
-/* Implement a short delay by polling the serial clock line */
-static void ivtv_scldelay(struct ivtv *itv)
-{
- int i;
-
- for (i = 0; i < 5; ++i)
- ivtv_getscl(itv);
-}
-
-/* Wait for the serial clock line to become set to a specific value */
-static int ivtv_waitscl(struct ivtv *itv, int val)
-{
- int i;
-
- ivtv_scldelay(itv);
- for (i = 0; i < 1000; ++i) {
- if (ivtv_getscl(itv) == val)
- return 1;
- }
- return 0;
-}
-
-/* Wait for the serial data line to become set to a specific value */
-static int ivtv_waitsda(struct ivtv *itv, int val)
-{
- int i;
-
- ivtv_scldelay(itv);
- for (i = 0; i < 1000; ++i) {
- if (ivtv_getsda(itv) == val)
- return 1;
- }
- return 0;
-}
-
-/* Wait for the slave to issue an ACK */
-static int ivtv_ack(struct ivtv *itv)
-{
- int ret = 0;
-
- if (ivtv_getscl(itv) == 1) {
- IVTV_DEBUG_HI_I2C("SCL was high starting an ack\n");
- ivtv_setscl(itv, 0);
- if (!ivtv_waitscl(itv, 0)) {
- IVTV_DEBUG_I2C("Could not set SCL low starting an ack\n");
- return -EREMOTEIO;
- }
- }
- ivtv_setsda(itv, 1);
- ivtv_scldelay(itv);
- ivtv_setscl(itv, 1);
- if (!ivtv_waitsda(itv, 0)) {
- IVTV_DEBUG_I2C("Slave did not ack\n");
- ret = -EREMOTEIO;
- }
- ivtv_setscl(itv, 0);
- if (!ivtv_waitscl(itv, 0)) {
- IVTV_DEBUG_I2C("Failed to set SCL low after ACK\n");
- ret = -EREMOTEIO;
- }
- return ret;
-}
-
-/* Write a single byte to the i2c bus and wait for the slave to ACK */
-static int ivtv_sendbyte(struct ivtv *itv, unsigned char byte)
-{
- int i, bit;
-
- IVTV_DEBUG_HI_I2C("write %x\n",byte);
- for (i = 0; i < 8; ++i, byte<<=1) {
- ivtv_setscl(itv, 0);
- if (!ivtv_waitscl(itv, 0)) {
- IVTV_DEBUG_I2C("Error setting SCL low\n");
- return -EREMOTEIO;
- }
- bit = (byte>>7)&1;
- ivtv_setsda(itv, bit);
- if (!ivtv_waitsda(itv, bit)) {
- IVTV_DEBUG_I2C("Error setting SDA\n");
- return -EREMOTEIO;
- }
- ivtv_setscl(itv, 1);
- if (!ivtv_waitscl(itv, 1)) {
- IVTV_DEBUG_I2C("Slave not ready for bit\n");
- return -EREMOTEIO;
- }
- }
- ivtv_setscl(itv, 0);
- if (!ivtv_waitscl(itv, 0)) {
- IVTV_DEBUG_I2C("Error setting SCL low\n");
- return -EREMOTEIO;
- }
- return ivtv_ack(itv);
-}
-
-/* Read a byte from the i2c bus and send a NACK if applicable (i.e. for the
- final byte) */
-static int ivtv_readbyte(struct ivtv *itv, unsigned char *byte, int nack)
-{
- int i;
-
- *byte = 0;
-
- ivtv_setsda(itv, 1);
- ivtv_scldelay(itv);
- for (i = 0; i < 8; ++i) {
- ivtv_setscl(itv, 0);
- ivtv_scldelay(itv);
- ivtv_setscl(itv, 1);
- if (!ivtv_waitscl(itv, 1)) {
- IVTV_DEBUG_I2C("Error setting SCL high\n");
- return -EREMOTEIO;
- }
- *byte = ((*byte)<<1)|ivtv_getsda(itv);
- }
- ivtv_setscl(itv, 0);
- ivtv_scldelay(itv);
- ivtv_setsda(itv, nack);
- ivtv_scldelay(itv);
- ivtv_setscl(itv, 1);
- ivtv_scldelay(itv);
- ivtv_setscl(itv, 0);
- ivtv_scldelay(itv);
- IVTV_DEBUG_HI_I2C("read %x\n",*byte);
- return 0;
-}
-
-/* Issue a start condition on the i2c bus to alert slaves to prepare for
- an address write */
-static int ivtv_start(struct ivtv *itv)
-{
- int sda;
-
- sda = ivtv_getsda(itv);
- if (sda != 1) {
- IVTV_DEBUG_HI_I2C("SDA was low at start\n");
- ivtv_setsda(itv, 1);
- if (!ivtv_waitsda(itv, 1)) {
- IVTV_DEBUG_I2C("SDA stuck low\n");
- return -EREMOTEIO;
- }
- }
- if (ivtv_getscl(itv) != 1) {
- ivtv_setscl(itv, 1);
- if (!ivtv_waitscl(itv, 1)) {
- IVTV_DEBUG_I2C("SCL stuck low at start\n");
- return -EREMOTEIO;
- }
- }
- ivtv_setsda(itv, 0);
- ivtv_scldelay(itv);
- return 0;
-}
-
-/* Issue a stop condition on the i2c bus to release it */
-static int ivtv_stop(struct ivtv *itv)
-{
- int i;
-
- if (ivtv_getscl(itv) != 0) {
- IVTV_DEBUG_HI_I2C("SCL not low when stopping\n");
- ivtv_setscl(itv, 0);
- if (!ivtv_waitscl(itv, 0)) {
- IVTV_DEBUG_I2C("SCL could not be set low\n");
- }
- }
- ivtv_setsda(itv, 0);
- ivtv_scldelay(itv);
- ivtv_setscl(itv, 1);
- if (!ivtv_waitscl(itv, 1)) {
- IVTV_DEBUG_I2C("SCL could not be set high\n");
- return -EREMOTEIO;
- }
- ivtv_scldelay(itv);
- ivtv_setsda(itv, 1);
- if (!ivtv_waitsda(itv, 1)) {
- IVTV_DEBUG_I2C("resetting I2C\n");
- for (i = 0; i < 16; ++i) {
- ivtv_setscl(itv, 0);
- ivtv_scldelay(itv);
- ivtv_setscl(itv, 1);
- ivtv_scldelay(itv);
- ivtv_setsda(itv, 1);
- }
- ivtv_waitsda(itv, 1);
- return -EREMOTEIO;
- }
- return 0;
-}
-
-/* Write a message to the given i2c slave. do_stop may be 0 to prevent
- issuing the i2c stop condition (when following with a read) */
-static int ivtv_write(struct ivtv *itv, unsigned char addr, unsigned char *data, u32 len, int do_stop)
-{
- int retry, ret = -EREMOTEIO;
- u32 i;
-
- for (retry = 0; ret != 0 && retry < 8; ++retry) {
- ret = ivtv_start(itv);
-
- if (ret == 0) {
- ret = ivtv_sendbyte(itv, addr<<1);
- for (i = 0; ret == 0 && i < len; ++i)
- ret = ivtv_sendbyte(itv, data[i]);
- }
- if (ret != 0 || do_stop) {
- ivtv_stop(itv);
- }
- }
- if (ret)
- IVTV_DEBUG_I2C("i2c write to %x failed\n", addr);
- return ret;
-}
-
-/* Read data from the given i2c slave. A stop condition is always issued. */
-static int ivtv_read(struct ivtv *itv, unsigned char addr, unsigned char *data, u32 len)
-{
- int retry, ret = -EREMOTEIO;
- u32 i;
-
- for (retry = 0; ret != 0 && retry < 8; ++retry) {
- ret = ivtv_start(itv);
- if (ret == 0)
- ret = ivtv_sendbyte(itv, (addr << 1) | 1);
- for (i = 0; ret == 0 && i < len; ++i) {
- ret = ivtv_readbyte(itv, &data[i], i == len - 1);
- }
- ivtv_stop(itv);
- }
- if (ret)
- IVTV_DEBUG_I2C("i2c read from %x failed\n", addr);
- return ret;
-}
-
-/* Kernel i2c transfer implementation. Takes a number of messages to be read
- or written. If a read follows a write, this will occur without an
- intervening stop condition */
-static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
-{
- struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap);
- struct ivtv *itv = to_ivtv(v4l2_dev);
- int retval;
- int i;
-
- mutex_lock(&itv->i2c_bus_lock);
- for (i = retval = 0; retval == 0 && i < num; i++) {
- if (msgs[i].flags & I2C_M_RD)
- retval = ivtv_read(itv, msgs[i].addr, msgs[i].buf, msgs[i].len);
- else {
- /* if followed by a read, don't stop */
- int stop = !(i + 1 < num && msgs[i + 1].flags == I2C_M_RD);
-
- retval = ivtv_write(itv, msgs[i].addr, msgs[i].buf, msgs[i].len, stop);
- }
- }
- mutex_unlock(&itv->i2c_bus_lock);
- return retval ? retval : num;
-}
-
-/* Kernel i2c capabilities */
-static u32 ivtv_functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static struct i2c_algorithm ivtv_algo = {
- .master_xfer = ivtv_xfer,
- .functionality = ivtv_functionality,
-};
-
-/* template for our-bit banger */
-static struct i2c_adapter ivtv_i2c_adap_hw_template = {
- .name = "ivtv i2c driver",
- .algo = &ivtv_algo,
- .algo_data = NULL, /* filled from template */
- .owner = THIS_MODULE,
-};
-
-static void ivtv_setscl_old(void *data, int state)
-{
- struct ivtv *itv = (struct ivtv *)data;
-
- if (state)
- itv->i2c_state |= 0x01;
- else
- itv->i2c_state &= ~0x01;
-
- /* write them out */
- /* write bits are inverted */
- write_reg(~itv->i2c_state, IVTV_REG_I2C_SETSCL_OFFSET);
-}
-
-static void ivtv_setsda_old(void *data, int state)
-{
- struct ivtv *itv = (struct ivtv *)data;
-
- if (state)
- itv->i2c_state |= 0x01;
- else
- itv->i2c_state &= ~0x01;
-
- /* write them out */
- /* write bits are inverted */
- write_reg(~itv->i2c_state, IVTV_REG_I2C_SETSDA_OFFSET);
-}
-
-static int ivtv_getscl_old(void *data)
-{
- struct ivtv *itv = (struct ivtv *)data;
-
- return read_reg(IVTV_REG_I2C_GETSCL_OFFSET) & 1;
-}
-
-static int ivtv_getsda_old(void *data)
-{
- struct ivtv *itv = (struct ivtv *)data;
-
- return read_reg(IVTV_REG_I2C_GETSDA_OFFSET) & 1;
-}
-
-/* template for i2c-bit-algo */
-static struct i2c_adapter ivtv_i2c_adap_template = {
- .name = "ivtv i2c driver",
- .algo = NULL, /* set by i2c-algo-bit */
- .algo_data = NULL, /* filled from template */
- .owner = THIS_MODULE,
-};
-
-#define IVTV_ALGO_BIT_TIMEOUT (2) /* seconds */
-
-static const struct i2c_algo_bit_data ivtv_i2c_algo_template = {
- .setsda = ivtv_setsda_old,
- .setscl = ivtv_setscl_old,
- .getsda = ivtv_getsda_old,
- .getscl = ivtv_getscl_old,
- .udelay = IVTV_DEFAULT_I2C_CLOCK_PERIOD / 2, /* microseconds */
- .timeout = IVTV_ALGO_BIT_TIMEOUT * HZ, /* jiffies */
-};
-
-static struct i2c_client ivtv_i2c_client_template = {
- .name = "ivtv internal",
-};
-
-/* init + register i2c adapter */
-int init_ivtv_i2c(struct ivtv *itv)
-{
- int retval;
-
- IVTV_DEBUG_I2C("i2c init\n");
-
- /* Sanity checks for the I2C hardware arrays. They must be the
- * same size.
- */
- if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs)) {
- IVTV_ERR("Mismatched I2C hardware arrays\n");
- return -ENODEV;
- }
- if (itv->options.newi2c > 0) {
- memcpy(&itv->i2c_adap, &ivtv_i2c_adap_hw_template,
- sizeof(struct i2c_adapter));
- } else {
- memcpy(&itv->i2c_adap, &ivtv_i2c_adap_template,
- sizeof(struct i2c_adapter));
- memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template,
- sizeof(struct i2c_algo_bit_data));
- }
- itv->i2c_algo.udelay = itv->options.i2c_clock_period / 2;
- itv->i2c_algo.data = itv;
- itv->i2c_adap.algo_data = &itv->i2c_algo;
-
- sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d",
- itv->instance);
- i2c_set_adapdata(&itv->i2c_adap, &itv->v4l2_dev);
-
- memcpy(&itv->i2c_client, &ivtv_i2c_client_template,
- sizeof(struct i2c_client));
- itv->i2c_client.adapter = &itv->i2c_adap;
- itv->i2c_adap.dev.parent = &itv->pdev->dev;
-
- IVTV_DEBUG_I2C("setting scl and sda to 1\n");
- ivtv_setscl(itv, 1);
- ivtv_setsda(itv, 1);
-
- if (itv->options.newi2c > 0)
- retval = i2c_add_adapter(&itv->i2c_adap);
- else
- retval = i2c_bit_add_bus(&itv->i2c_adap);
-
- return retval;
-}
-
-void exit_ivtv_i2c(struct ivtv *itv)
-{
- IVTV_DEBUG_I2C("i2c exit\n");
-
- i2c_del_adapter(&itv->i2c_adap);
-}
diff --git a/drivers/media/video/ivtv/ivtv-i2c.h b/drivers/media/video/ivtv/ivtv-i2c.h
deleted file mode 100644
index 7b9ec1cfeb8..00000000000
--- a/drivers/media/video/ivtv/ivtv-i2c.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- I2C functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_I2C_H
-#define IVTV_I2C_H
-
-struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv);
-int ivtv_i2c_register(struct ivtv *itv, unsigned idx);
-struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw);
-
-/* init + register i2c adapter */
-int init_ivtv_i2c(struct ivtv *itv);
-void exit_ivtv_i2c(struct ivtv *itv);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
deleted file mode 100644
index 32a591062d0..00000000000
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ /dev/null
@@ -1,1899 +0,0 @@
-/*
- ioctl system call
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-version.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-i2c.h"
-#include "ivtv-queue.h"
-#include "ivtv-fileops.h"
-#include "ivtv-vbi.h"
-#include "ivtv-routing.h"
-#include "ivtv-streams.h"
-#include "ivtv-yuv.h"
-#include "ivtv-ioctl.h"
-#include "ivtv-gpio.h"
-#include "ivtv-controls.h"
-#include "ivtv-cards.h"
-#include <media/saa7127.h>
-#include <media/tveeprom.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-event.h>
-#include <linux/dvb/audio.h>
-
-u16 ivtv_service2vbi(int type)
-{
- switch (type) {
- case V4L2_SLICED_TELETEXT_B:
- return IVTV_SLICED_TYPE_TELETEXT_B;
- case V4L2_SLICED_CAPTION_525:
- return IVTV_SLICED_TYPE_CAPTION_525;
- case V4L2_SLICED_WSS_625:
- return IVTV_SLICED_TYPE_WSS_625;
- case V4L2_SLICED_VPS:
- return IVTV_SLICED_TYPE_VPS;
- default:
- return 0;
- }
-}
-
-static int valid_service_line(int field, int line, int is_pal)
-{
- return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
- (!is_pal && line >= 10 && line < 22);
-}
-
-static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
-{
- u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
- int i;
-
- set = set & valid_set;
- if (set == 0 || !valid_service_line(field, line, is_pal)) {
- return 0;
- }
- if (!is_pal) {
- if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
- return V4L2_SLICED_CAPTION_525;
- }
- else {
- if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
- return V4L2_SLICED_VPS;
- if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
- return V4L2_SLICED_WSS_625;
- if (line == 23)
- return 0;
- }
- for (i = 0; i < 32; i++) {
- if ((1 << i) & set)
- return 1 << i;
- }
- return 0;
-}
-
-void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
-{
- u16 set = fmt->service_set;
- int f, l;
-
- fmt->service_set = 0;
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
- }
- }
-}
-
-static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
-{
- int f, l;
-
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
- }
- }
-}
-
-u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
-{
- int f, l;
- u16 set = 0;
-
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- set |= fmt->service_lines[f][l];
- }
- }
- return set;
-}
-
-void ivtv_set_osd_alpha(struct ivtv *itv)
-{
- ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3,
- itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state);
- ivtv_vapi(itv, CX2341X_OSD_SET_CHROMA_KEY, 2, itv->osd_chroma_key_state, itv->osd_chroma_key);
-}
-
-int ivtv_set_speed(struct ivtv *itv, int speed)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- int single_step = (speed == 1 || speed == -1);
- DEFINE_WAIT(wait);
-
- if (speed == 0) speed = 1000;
-
- /* No change? */
- if (speed == itv->speed && !single_step)
- return 0;
-
- if (single_step && (speed < 0) == (itv->speed < 0)) {
- /* Single step video and no need to change direction */
- ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
- itv->speed = speed;
- return 0;
- }
- if (single_step)
- /* Need to change direction */
- speed = speed < 0 ? -1000 : 1000;
-
- data[0] = (speed > 1000 || speed < -1000) ? 0x80000000 : 0;
- data[0] |= (speed > 1000 || speed < -1500) ? 0x40000000 : 0;
- data[1] = (speed < 0);
- data[2] = speed < 0 ? 3 : 7;
- data[3] = v4l2_ctrl_g_ctrl(itv->cxhdl.video_b_frames);
- data[4] = (speed == 1500 || speed == 500) ? itv->speed_mute_audio : 0;
- data[5] = 0;
- data[6] = 0;
-
- if (speed == 1500 || speed == -1500) data[0] |= 1;
- else if (speed == 2000 || speed == -2000) data[0] |= 2;
- else if (speed > -1000 && speed < 0) data[0] |= (-1000 / speed);
- else if (speed < 1000 && speed > 0) data[0] |= (1000 / speed);
-
- /* If not decoding, just change speed setting */
- if (atomic_read(&itv->decoding) > 0) {
- int got_sig = 0;
-
- /* Stop all DMA and decoding activity */
- ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0);
-
- /* Wait for any DMA to finish */
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
- while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
- got_sig = signal_pending(current);
- if (got_sig)
- break;
- got_sig = 0;
- schedule();
- }
- finish_wait(&itv->dma_waitq, &wait);
- mutex_lock(&itv->serialize_lock);
- if (got_sig)
- return -EINTR;
-
- /* Change Speed safely */
- ivtv_api(itv, CX2341X_DEC_SET_PLAYBACK_SPEED, 7, data);
- IVTV_DEBUG_INFO("Setting Speed to 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
- }
- if (single_step) {
- speed = (speed < 0) ? -1 : 1;
- ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
- }
- itv->speed = speed;
- return 0;
-}
-
-static int ivtv_validate_speed(int cur_speed, int new_speed)
-{
- int fact = new_speed < 0 ? -1 : 1;
- int s;
-
- if (cur_speed == 0)
- cur_speed = 1000;
- if (new_speed < 0)
- new_speed = -new_speed;
- if (cur_speed < 0)
- cur_speed = -cur_speed;
-
- if (cur_speed <= new_speed) {
- if (new_speed > 1500)
- return fact * 2000;
- if (new_speed > 1000)
- return fact * 1500;
- }
- else {
- if (new_speed >= 2000)
- return fact * 2000;
- if (new_speed >= 1500)
- return fact * 1500;
- if (new_speed >= 1000)
- return fact * 1000;
- }
- if (new_speed == 0)
- return 1000;
- if (new_speed == 1 || new_speed == 1000)
- return fact * new_speed;
-
- s = new_speed;
- new_speed = 1000 / new_speed;
- if (1000 / cur_speed == new_speed)
- new_speed += (cur_speed < s) ? -1 : 1;
- if (new_speed > 60) return 1000 / (fact * 60);
- return 1000 / (fact * new_speed);
-}
-
-static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
- struct v4l2_decoder_cmd *dc, int try)
-{
- struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
-
- switch (dc->cmd) {
- case V4L2_DEC_CMD_START: {
- dc->flags &= V4L2_DEC_CMD_START_MUTE_AUDIO;
- dc->start.speed = ivtv_validate_speed(itv->speed, dc->start.speed);
- if (dc->start.speed < 0)
- dc->start.format = V4L2_DEC_START_FMT_GOP;
- else
- dc->start.format = V4L2_DEC_START_FMT_NONE;
- if (dc->start.speed != 500 && dc->start.speed != 1500)
- dc->flags = dc->start.speed == 1000 ? 0 :
- V4L2_DEC_CMD_START_MUTE_AUDIO;
- if (try) break;
-
- itv->speed_mute_audio = dc->flags & V4L2_DEC_CMD_START_MUTE_AUDIO;
- if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
- return -EBUSY;
- if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
- /* forces ivtv_set_speed to be called */
- itv->speed = 0;
- }
- return ivtv_start_decoding(id, dc->start.speed);
- }
-
- case V4L2_DEC_CMD_STOP:
- dc->flags &= V4L2_DEC_CMD_STOP_IMMEDIATELY | V4L2_DEC_CMD_STOP_TO_BLACK;
- if (dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY)
- dc->stop.pts = 0;
- if (try) break;
- if (atomic_read(&itv->decoding) == 0)
- return 0;
- if (itv->output_mode != OUT_MPG)
- return -EBUSY;
-
- itv->output_mode = OUT_NONE;
- return ivtv_stop_v4l2_decode_stream(s, dc->flags, dc->stop.pts);
-
- case V4L2_DEC_CMD_PAUSE:
- dc->flags &= V4L2_DEC_CMD_PAUSE_TO_BLACK;
- if (try) break;
- if (itv->output_mode != OUT_MPG)
- return -EBUSY;
- if (atomic_read(&itv->decoding) > 0) {
- ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
- (dc->flags & V4L2_DEC_CMD_PAUSE_TO_BLACK) ? 1 : 0);
- set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
- }
- break;
-
- case V4L2_DEC_CMD_RESUME:
- dc->flags = 0;
- if (try) break;
- if (itv->output_mode != OUT_MPG)
- return -EBUSY;
- if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
- int speed = itv->speed;
- itv->speed = 0;
- return ivtv_start_decoding(id, speed);
- }
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
-
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
- if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
- return -EINVAL;
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- if (itv->is_60hz) {
- vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
- vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
- } else {
- vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
- vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
- }
- vbifmt->service_set = ivtv_get_service_set(vbifmt);
- return 0;
-}
-
-static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-
- pixfmt->width = itv->cxhdl.width;
- pixfmt->height = itv->cxhdl.height;
- pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
- pixfmt->field = V4L2_FIELD_INTERLACED;
- pixfmt->priv = 0;
- if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
- pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
- /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
- pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
- pixfmt->bytesperline = 720;
- } else {
- pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
- pixfmt->sizeimage = 128 * 1024;
- pixfmt->bytesperline = 0;
- }
- return 0;
-}
-
-static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
-
- vbifmt->sampling_rate = 27000000;
- vbifmt->offset = 248;
- vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4;
- vbifmt->sample_format = V4L2_PIX_FMT_GREY;
- vbifmt->start[0] = itv->vbi.start[0];
- vbifmt->start[1] = itv->vbi.start[1];
- vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count;
- vbifmt->flags = 0;
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
- return 0;
-}
-
-static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
-
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
-
- if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
- vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
- V4L2_SLICED_VBI_525;
- ivtv_expand_service_set(vbifmt, itv->is_50hz);
- return 0;
- }
-
- v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt);
- vbifmt->service_set = ivtv_get_service_set(vbifmt);
- return 0;
-}
-
-static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- pixfmt->width = itv->main_rect.width;
- pixfmt->height = itv->main_rect.height;
- pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
- pixfmt->field = V4L2_FIELD_INTERLACED;
- pixfmt->priv = 0;
- if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
- switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
- case IVTV_YUV_MODE_INTERLACED:
- pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
- V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
- break;
- case IVTV_YUV_MODE_PROGRESSIVE:
- pixfmt->field = V4L2_FIELD_NONE;
- break;
- default:
- pixfmt->field = V4L2_FIELD_ANY;
- break;
- }
- pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
- pixfmt->bytesperline = 720;
- pixfmt->width = itv->yuv_info.v4l2_src_w;
- pixfmt->height = itv->yuv_info.v4l2_src_h;
- /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
- pixfmt->sizeimage =
- 1080 * ((pixfmt->height + 31) & ~31);
- } else {
- pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
- pixfmt->sizeimage = 128 * 1024;
- pixfmt->bytesperline = 0;
- }
- return 0;
-}
-
-static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- struct v4l2_window *winfmt = &fmt->fmt.win;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- winfmt->chromakey = itv->osd_chroma_key;
- winfmt->global_alpha = itv->osd_global_alpha;
- winfmt->field = V4L2_FIELD_INTERLACED;
- winfmt->clips = NULL;
- winfmt->clipcount = 0;
- winfmt->bitmap = NULL;
- winfmt->w.top = winfmt->w.left = 0;
- winfmt->w.width = itv->osd_rect.width;
- winfmt->w.height = itv->osd_rect.height;
- return 0;
-}
-
-static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
-}
-
-static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- int w = fmt->fmt.pix.width;
- int h = fmt->fmt.pix.height;
- int min_h = 2;
-
- w = min(w, 720);
- w = max(w, 2);
- if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
- /* YUV height must be a multiple of 32 */
- h &= ~0x1f;
- min_h = 32;
- }
- h = min(h, itv->is_50hz ? 576 : 480);
- h = max(h, min_h);
- ivtv_g_fmt_vid_cap(file, fh, fmt);
- fmt->fmt.pix.width = w;
- fmt->fmt.pix.height = h;
- return 0;
-}
-
-static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- return ivtv_g_fmt_vbi_cap(file, fh, fmt);
-}
-
-static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
-
- if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
- return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt);
-
- /* set sliced VBI capture format */
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
-
- if (vbifmt->service_set)
- ivtv_expand_service_set(vbifmt, itv->is_50hz);
- check_service_set(vbifmt, itv->is_50hz);
- vbifmt->service_set = ivtv_get_service_set(vbifmt);
- return 0;
-}
-
-static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv_open_id *id = fh2id(fh);
- s32 w = fmt->fmt.pix.width;
- s32 h = fmt->fmt.pix.height;
- int field = fmt->fmt.pix.field;
- int ret = ivtv_g_fmt_vid_out(file, fh, fmt);
-
- w = min(w, 720);
- w = max(w, 2);
- /* Why can the height be 576 even when the output is NTSC?
-
- Internally the buffers of the PVR350 are always set to 720x576. The
- decoded video frame will always be placed in the top left corner of
- this buffer. For any video which is not 720x576, the buffer will
- then be cropped to remove the unused right and lower areas, with
- the remaining image being scaled by the hardware to fit the display
- area. The video can be scaled both up and down, so a 720x480 video
- can be displayed full-screen on PAL and a 720x576 video can be
- displayed without cropping on NTSC.
-
- Note that the scaling only occurs on the video stream, the osd
- resolution is locked to the broadcast standard and not scaled.
-
- Thanks to Ian Armstrong for this explanation. */
- h = min(h, 576);
- h = max(h, 2);
- if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
- fmt->fmt.pix.field = field;
- fmt->fmt.pix.width = w;
- fmt->fmt.pix.height = h;
- return ret;
-}
-
-static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- u32 chromakey = fmt->fmt.win.chromakey;
- u8 global_alpha = fmt->fmt.win.global_alpha;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- ivtv_g_fmt_vid_out_overlay(file, fh, fmt);
- fmt->fmt.win.chromakey = chromakey;
- fmt->fmt.win.global_alpha = global_alpha;
- return 0;
-}
-
-static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
-}
-
-static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct v4l2_mbus_framefmt mbus_fmt;
- int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
- int w = fmt->fmt.pix.width;
- int h = fmt->fmt.pix.height;
-
- if (ret)
- return ret;
-
- if (itv->cxhdl.width == w && itv->cxhdl.height == h)
- return 0;
-
- if (atomic_read(&itv->capturing) > 0)
- return -EBUSY;
-
- itv->cxhdl.width = w;
- itv->cxhdl.height = h;
- if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
- fmt->fmt.pix.width /= 2;
- mbus_fmt.width = fmt->fmt.pix.width;
- mbus_fmt.height = h;
- mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
- v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt);
- return ivtv_g_fmt_vid_cap(file, fh, fmt);
-}
-
-static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
- return -EBUSY;
- itv->vbi.sliced_in->service_set = 0;
- itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
- v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi);
- return ivtv_g_fmt_vbi_cap(file, fh, fmt);
-}
-
-static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
-
- if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
- return ret;
-
- check_service_set(vbifmt, itv->is_50hz);
- if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
- return -EBUSY;
- itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
- v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt);
- memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
- return 0;
-}
-
-static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct yuv_playback_info *yi = &itv->yuv_info;
- int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
-
- if (ret)
- return ret;
-
- if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
- return 0;
-
- /* Return now if we already have some frame data */
- if (yi->stream_size)
- return -EBUSY;
-
- yi->v4l2_src_w = fmt->fmt.pix.width;
- yi->v4l2_src_h = fmt->fmt.pix.height;
-
- switch (fmt->fmt.pix.field) {
- case V4L2_FIELD_NONE:
- yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
- break;
- case V4L2_FIELD_ANY:
- yi->lace_mode = IVTV_YUV_MODE_AUTO;
- break;
- case V4L2_FIELD_INTERLACED_BT:
- yi->lace_mode =
- IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
- break;
- case V4L2_FIELD_INTERLACED_TB:
- default:
- yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
- break;
- }
- yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
-
- if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
- itv->dma_data_req_size =
- 1080 * ((yi->v4l2_src_h + 31) & ~31);
-
- return 0;
-}
-
-static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
-
- if (ret == 0) {
- itv->osd_chroma_key = fmt->fmt.win.chromakey;
- itv->osd_global_alpha = fmt->fmt.win.global_alpha;
- ivtv_set_osd_alpha(itv);
- }
- return ret;
-}
-
-static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
- if (v4l2_chip_match_host(&chip->match))
- chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
- return 0;
- }
- if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
- chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
- /* TODO: is this correct? */
- return ivtv_call_all_err(itv, core, g_chip_ident, chip);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
-{
- struct v4l2_dbg_register *regs = arg;
- volatile u8 __iomem *reg_start;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
- reg_start = itv->reg_mem - IVTV_REG_OFFSET;
- else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
- regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
- reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
- else if (regs->reg < IVTV_ENCODER_SIZE)
- reg_start = itv->enc_mem;
- else
- return -EINVAL;
-
- regs->size = 4;
- if (cmd == VIDIOC_DBG_G_REGISTER)
- regs->val = readl(regs->reg + reg_start);
- else
- writel(regs->val, regs->reg + reg_start);
- return 0;
-}
-
-static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (v4l2_chip_match_host(&reg->match))
- return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
- /* TODO: subdev errors should not be ignored, this should become a
- subdev helper function. */
- ivtv_call_all(itv, core, g_register, reg);
- return 0;
-}
-
-static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (v4l2_chip_match_host(&reg->match))
- return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
- /* TODO: subdev errors should not be ignored, this should become a
- subdev helper function. */
- ivtv_call_all(itv, core, s_register, reg);
- return 0;
-}
-#endif
-
-static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
-{
- struct ivtv_open_id *id = fh2id(file->private_data);
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
-
- strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
- strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
- snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
- vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
- vcap->device_caps = s->caps;
- return 0;
-}
-
-static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- return ivtv_get_audio_input(itv, vin->index, vin);
-}
-
-static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- vin->index = itv->audio_input;
- return ivtv_get_audio_input(itv, vin->index, vin);
-}
-
-static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (vout->index >= itv->nof_audio_inputs)
- return -EINVAL;
-
- itv->audio_input = vout->index;
- ivtv_audio_set_io(itv);
-
- return 0;
-}
-
-static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- /* set it to defaults from our table */
- return ivtv_get_audio_output(itv, vin->index, vin);
-}
-
-static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- vin->index = 0;
- return ivtv_get_audio_output(itv, vin->index, vin);
-}
-
-static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- return ivtv_get_audio_output(itv, vout->index, vout);
-}
-
-static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- /* set it to defaults from our table */
- return ivtv_get_input(itv, vin->index, vin);
-}
-
-static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- return ivtv_get_output(itv, vout->index, vout);
-}
-
-static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct yuv_playback_info *yi = &itv->yuv_info;
- int streamtype;
-
- streamtype = id->type;
-
- if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
- cropcap->bounds.top = cropcap->bounds.left = 0;
- cropcap->bounds.width = 720;
- if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- cropcap->bounds.height = itv->is_50hz ? 576 : 480;
- cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
- cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
- } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
- if (yi->track_osd) {
- cropcap->bounds.width = yi->osd_full_w;
- cropcap->bounds.height = yi->osd_full_h;
- } else {
- cropcap->bounds.width = 720;
- cropcap->bounds.height =
- itv->is_out_50hz ? 576 : 480;
- }
- cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
- cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
- } else {
- cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
- cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
- cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
- }
- cropcap->defrect = cropcap->bounds;
- return 0;
-}
-
-static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct yuv_playback_info *yi = &itv->yuv_info;
- int streamtype;
-
- streamtype = id->type;
-
- if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
- if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
- yi->main_rect = crop->c;
- return 0;
- } else {
- if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
- crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
- itv->main_rect = crop->c;
- return 0;
- }
- }
- return -EINVAL;
- }
- return -EINVAL;
-}
-
-static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct yuv_playback_info *yi = &itv->yuv_info;
- int streamtype;
-
- streamtype = id->type;
-
- if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
- if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
- crop->c = yi->main_rect;
- else
- crop->c = itv->main_rect;
- return 0;
- }
- return -EINVAL;
-}
-
-static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
-{
- static struct v4l2_fmtdesc formats[] = {
- { 0, 0, 0,
- "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
- { 0, 0, 0, 0 }
- },
- { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
- "MPEG", V4L2_PIX_FMT_MPEG,
- { 0, 0, 0, 0 }
- }
- };
- enum v4l2_buf_type type = fmt->type;
-
- if (fmt->index > 1)
- return -EINVAL;
-
- *fmt = formats[fmt->index];
- fmt->type = type;
- return 0;
-}
-
-static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- static struct v4l2_fmtdesc formats[] = {
- { 0, 0, 0,
- "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
- { 0, 0, 0, 0 }
- },
- { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
- "MPEG", V4L2_PIX_FMT_MPEG,
- { 0, 0, 0, 0 }
- }
- };
- enum v4l2_buf_type type = fmt->type;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
-
- if (fmt->index > 1)
- return -EINVAL;
-
- *fmt = formats[fmt->index];
- fmt->type = type;
-
- return 0;
-}
-
-static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- *i = itv->active_input;
-
- return 0;
-}
-
-int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (inp < 0 || inp >= itv->nof_inputs)
- return -EINVAL;
-
- if (inp == itv->active_input) {
- IVTV_DEBUG_INFO("Input unchanged\n");
- return 0;
- }
-
- if (atomic_read(&itv->capturing) > 0) {
- return -EBUSY;
- }
-
- IVTV_DEBUG_INFO("Changing input from %d to %d\n",
- itv->active_input, inp);
-
- itv->active_input = inp;
- /* Set the audio input to whatever is appropriate for the
- input type. */
- itv->audio_input = itv->card->video_inputs[inp].audio_index;
-
- /* prevent others from messing with the streams until
- we're finished changing inputs. */
- ivtv_mute(itv);
- ivtv_video_set_io(itv);
- ivtv_audio_set_io(itv);
- ivtv_unmute(itv);
-
- return 0;
-}
-
-static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
-
- *i = itv->active_output;
-
- return 0;
-}
-
-static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (outp >= itv->card->nof_outputs)
- return -EINVAL;
-
- if (outp == itv->active_output) {
- IVTV_DEBUG_INFO("Output unchanged\n");
- return 0;
- }
- IVTV_DEBUG_INFO("Changing output from %d to %d\n",
- itv->active_output, outp);
-
- itv->active_output = outp;
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
- SAA7127_INPUT_TYPE_NORMAL,
- itv->card->video_outputs[outp].video_output, 0);
-
- return 0;
-}
-
-static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (vf->tuner != 0)
- return -EINVAL;
-
- ivtv_call_all(itv, tuner, g_frequency, vf);
- return 0;
-}
-
-int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (vf->tuner != 0)
- return -EINVAL;
-
- ivtv_mute(itv);
- IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
- ivtv_call_all(itv, tuner, s_frequency, vf);
- ivtv_unmute(itv);
- return 0;
-}
-
-static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- *std = itv->std;
- return 0;
-}
-
-void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std)
-{
- itv->std = *std;
- itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
- itv->is_50hz = !itv->is_60hz;
- cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
- itv->cxhdl.width = 720;
- itv->cxhdl.height = itv->is_50hz ? 576 : 480;
- itv->vbi.count = itv->is_50hz ? 18 : 12;
- itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
- itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
-
- if (itv->hw_flags & IVTV_HW_CX25840)
- itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
-
- /* Tuner */
- ivtv_call_all(itv, core, s_std, itv->std);
-}
-
-void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- DEFINE_WAIT(wait);
- int f;
-
- /* set display standard */
- itv->std_out = *std;
- itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
- itv->is_out_50hz = !itv->is_out_60hz;
- ivtv_call_all(itv, video, s_std_output, itv->std_out);
-
- /*
- * The next firmware call is time sensitive. Time it to
- * avoid risk of a hard lock, by trying to ensure the call
- * happens within the first 100 lines of the top field.
- * Make 4 attempts to sync to the decoder before giving up.
- */
- mutex_unlock(&itv->serialize_lock);
- for (f = 0; f < 4; f++) {
- prepare_to_wait(&itv->vsync_waitq, &wait,
- TASK_UNINTERRUPTIBLE);
- if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
- break;
- schedule_timeout(msecs_to_jiffies(25));
- }
- finish_wait(&itv->vsync_waitq, &wait);
- mutex_lock(&itv->serialize_lock);
-
- if (f == 4)
- IVTV_WARN("Mode change failed to sync to decoder\n");
-
- ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
- itv->main_rect.left = 0;
- itv->main_rect.top = 0;
- itv->main_rect.width = 720;
- itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
- ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
- 720, itv->main_rect.height, 0, 0);
- yi->main_rect = itv->main_rect;
- if (!itv->osd_info) {
- yi->osd_full_w = 720;
- yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
- }
-}
-
-int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if ((*std & V4L2_STD_ALL) == 0)
- return -EINVAL;
-
- if (*std == itv->std)
- return 0;
-
- if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
- atomic_read(&itv->capturing) > 0 ||
- atomic_read(&itv->decoding) > 0) {
- /* Switching standard would mess with already running
- streams, prevent that by returning EBUSY. */
- return -EBUSY;
- }
-
- IVTV_DEBUG_INFO("Switching standard to %llx.\n",
- (unsigned long long)itv->std);
-
- ivtv_s_std_enc(itv, std);
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
- ivtv_s_std_dec(itv, std);
-
- return 0;
-}
-
-static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
-
- if (vt->index != 0)
- return -EINVAL;
-
- ivtv_call_all(itv, tuner, s_tuner, vt);
-
- return 0;
-}
-
-static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (vt->index != 0)
- return -EINVAL;
-
- ivtv_call_all(itv, tuner, g_tuner, vt);
-
- if (vt->type == V4L2_TUNER_RADIO)
- strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
- else
- strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
- return 0;
-}
-
-static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
- int f, l;
-
- if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- if (valid_service_line(f, l, itv->is_50hz))
- cap->service_lines[f][l] = set;
- }
- }
- } else if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
- if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
- return -EINVAL;
- if (itv->is_60hz) {
- cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
- cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
- } else {
- cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
- cap->service_lines[0][16] = V4L2_SLICED_VPS;
- }
- } else {
- return -EINVAL;
- }
-
- set = 0;
- for (f = 0; f < 2; f++)
- for (l = 0; l < 24; l++)
- set |= cap->service_lines[f][l];
- cap->service_set = set;
- return 0;
-}
-
-static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- struct v4l2_enc_idx_entry *e = idx->entry;
- int entries;
- int i;
-
- entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
- IVTV_MAX_PGM_INDEX;
- if (entries > V4L2_ENC_IDX_ENTRIES)
- entries = V4L2_ENC_IDX_ENTRIES;
- idx->entries = 0;
- for (i = 0; i < entries; i++) {
- *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
- if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
- idx->entries++;
- e++;
- }
- }
- itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
- return 0;
-}
-
-static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
-
-
- switch (enc->cmd) {
- case V4L2_ENC_CMD_START:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
- enc->flags = 0;
- return ivtv_start_capture(id);
-
- case V4L2_ENC_CMD_STOP:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
- enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
- ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
- return 0;
-
- case V4L2_ENC_CMD_PAUSE:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
- enc->flags = 0;
-
- if (!atomic_read(&itv->capturing))
- return -EPERM;
- if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
- return 0;
-
- ivtv_mute(itv);
- ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
- break;
-
- case V4L2_ENC_CMD_RESUME:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
- enc->flags = 0;
-
- if (!atomic_read(&itv->capturing))
- return -EPERM;
-
- if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
- return 0;
-
- ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
- ivtv_unmute(itv);
- break;
- default:
- IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- switch (enc->cmd) {
- case V4L2_ENC_CMD_START:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
- enc->flags = 0;
- return 0;
-
- case V4L2_ENC_CMD_STOP:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
- enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
- return 0;
-
- case V4L2_ENC_CMD_PAUSE:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
- enc->flags = 0;
- return 0;
-
- case V4L2_ENC_CMD_RESUME:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
- enc->flags = 0;
- return 0;
- default:
- IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
- return -EINVAL;
- }
-}
-
-static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct yuv_playback_info *yi = &itv->yuv_info;
-
- int pixfmt;
- static u32 pixel_format[16] = {
- V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
- V4L2_PIX_FMT_RGB565,
- V4L2_PIX_FMT_RGB555,
- V4L2_PIX_FMT_RGB444,
- V4L2_PIX_FMT_RGB32,
- 0,
- 0,
- 0,
- V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
- V4L2_PIX_FMT_YUV565,
- V4L2_PIX_FMT_YUV555,
- V4L2_PIX_FMT_YUV444,
- V4L2_PIX_FMT_YUV32,
- 0,
- 0,
- 0,
- };
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
- return -EINVAL;
- if (!itv->osd_video_pbase)
- return -EINVAL;
-
- fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
- V4L2_FBUF_CAP_GLOBAL_ALPHA;
-
- ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
- data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
- pixfmt = (data[0] >> 3) & 0xf;
-
- fb->fmt.pixelformat = pixel_format[pixfmt];
- fb->fmt.width = itv->osd_rect.width;
- fb->fmt.height = itv->osd_rect.height;
- fb->fmt.field = V4L2_FIELD_INTERLACED;
- fb->fmt.bytesperline = fb->fmt.width;
- fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
- fb->fmt.field = V4L2_FIELD_INTERLACED;
- fb->fmt.priv = 0;
- if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
- fb->fmt.bytesperline *= 2;
- if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
- fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
- fb->fmt.bytesperline *= 2;
- fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
- fb->base = (void *)itv->osd_video_pbase;
- fb->flags = 0;
-
- if (itv->osd_chroma_key_state)
- fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
-
- if (itv->osd_global_alpha_state)
- fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
-
- if (yi->track_osd)
- fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
-
- pixfmt &= 7;
-
- /* no local alpha for RGB565 or unknown formats */
- if (pixfmt == 1 || pixfmt > 4)
- return 0;
-
- /* 16-bit formats have inverted local alpha */
- if (pixfmt == 2 || pixfmt == 3)
- fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
- else
- fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
-
- if (itv->osd_local_alpha_state) {
- /* 16-bit formats have inverted local alpha */
- if (pixfmt == 2 || pixfmt == 3)
- fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
- else
- fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
- }
-
- return 0;
-}
-
-static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct yuv_playback_info *yi = &itv->yuv_info;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
- return -EINVAL;
- if (!itv->osd_video_pbase)
- return -EINVAL;
-
- itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
- itv->osd_local_alpha_state =
- (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
- itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
- ivtv_set_osd_alpha(itv);
- yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
- return ivtv_g_fbuf(file, fh, fb);
-}
-
-static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
- return -EINVAL;
-
- ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
-
- return 0;
-}
-
-static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
-{
- switch (sub->type) {
- case V4L2_EVENT_VSYNC:
- case V4L2_EVENT_EOS:
- return v4l2_event_subscribe(fh, sub, 0, NULL);
- case V4L2_EVENT_CTRL:
- return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
- default:
- return -EINVAL;
- }
-}
-
-static int ivtv_log_status(struct file *file, void *fh)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- u32 data[CX2341X_MBOX_MAX_DATA];
-
- int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
- struct v4l2_input vidin;
- struct v4l2_audio audin;
- int i;
-
- IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
- if (itv->hw_flags & IVTV_HW_TVEEPROM) {
- struct tveeprom tv;
-
- ivtv_read_eeprom(itv, &tv);
- }
- ivtv_call_all(itv, core, log_status);
- ivtv_get_input(itv, itv->active_input, &vidin);
- ivtv_get_audio_input(itv, itv->audio_input, &audin);
- IVTV_INFO("Video Input: %s\n", vidin.name);
- IVTV_INFO("Audio Input: %s%s\n", audin.name,
- (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
- if (has_output) {
- struct v4l2_output vidout;
- struct v4l2_audioout audout;
- int mode = itv->output_mode;
- static const char * const output_modes[5] = {
- "None",
- "MPEG Streaming",
- "YUV Streaming",
- "YUV Frames",
- "Passthrough",
- };
- static const char * const alpha_mode[4] = {
- "None",
- "Global",
- "Local",
- "Global and Local"
- };
- static const char * const pixel_format[16] = {
- "ARGB Indexed",
- "RGB 5:6:5",
- "ARGB 1:5:5:5",
- "ARGB 1:4:4:4",
- "ARGB 8:8:8:8",
- "5",
- "6",
- "7",
- "AYUV Indexed",
- "YUV 5:6:5",
- "AYUV 1:5:5:5",
- "AYUV 1:4:4:4",
- "AYUV 8:8:8:8",
- "13",
- "14",
- "15",
- };
-
- ivtv_get_output(itv, itv->active_output, &vidout);
- ivtv_get_audio_output(itv, 0, &audout);
- IVTV_INFO("Video Output: %s\n", vidout.name);
- if (mode < 0 || mode > OUT_PASSTHROUGH)
- mode = OUT_NONE;
- IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
- ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
- data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
- IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
- data[0] & 1 ? "On" : "Off",
- alpha_mode[(data[0] >> 1) & 0x3],
- pixel_format[(data[0] >> 3) & 0xf]);
- }
- IVTV_INFO("Tuner: %s\n",
- test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
- v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
- IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
- for (i = 0; i < IVTV_MAX_STREAMS; i++) {
- struct ivtv_stream *s = &itv->streams[i];
-
- if (s->vdev == NULL || s->buffers == 0)
- continue;
- IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
- (s->buffers - s->q_free.buffers) * 100 / s->buffers,
- (s->buffers * s->buf_size) / 1024, s->buffers);
- }
-
- IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
- (long long)itv->mpg_data_received,
- (long long)itv->vbi_data_inserted);
- return 0;
-}
-
-static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
-{
- struct ivtv_open_id *id = fh2id(file->private_data);
- struct ivtv *itv = id->itv;
-
- IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd);
- return ivtv_video_command(itv, id, dec, false);
-}
-
-static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
-{
- struct ivtv_open_id *id = fh2id(file->private_data);
- struct ivtv *itv = id->itv;
-
- IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd);
- return ivtv_video_command(itv, id, dec, true);
-}
-
-static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
-{
- struct ivtv_open_id *id = fh2id(filp->private_data);
- struct ivtv *itv = id->itv;
- int nonblocking = filp->f_flags & O_NONBLOCK;
- struct ivtv_stream *s = &itv->streams[id->type];
- unsigned long iarg = (unsigned long)arg;
-
- switch (cmd) {
- case IVTV_IOC_DMA_FRAME: {
- struct ivtv_dma_frame *args = arg;
-
- IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
- if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
- return 0;
- if (ivtv_start_decoding(id, id->type)) {
- return -EBUSY;
- }
- if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
- ivtv_release_stream(s);
- return -EBUSY;
- }
- /* Mark that this file handle started the UDMA_YUV mode */
- id->yuv_frames = 1;
- if (args->y_source == NULL)
- return 0;
- return ivtv_yuv_prep_frame(itv, args);
- }
-
- case IVTV_IOC_PASSTHROUGH_MODE:
- IVTV_DEBUG_IOCTL("IVTV_IOC_PASSTHROUGH_MODE\n");
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- return ivtv_passthrough_mode(itv, *(int *)arg != 0);
-
- case VIDEO_GET_PTS: {
- s64 *pts = arg;
- s64 frame;
-
- IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
- if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
- *pts = s->dma_pts;
- break;
- }
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- return ivtv_g_pts_frame(itv, pts, &frame);
- }
-
- case VIDEO_GET_FRAME_COUNT: {
- s64 *frame = arg;
- s64 pts;
-
- IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
- if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
- *frame = 0;
- break;
- }
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- return ivtv_g_pts_frame(itv, &pts, frame);
- }
-
- case VIDEO_PLAY: {
- struct v4l2_decoder_cmd dc;
-
- IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
- memset(&dc, 0, sizeof(dc));
- dc.cmd = V4L2_DEC_CMD_START;
- return ivtv_video_command(itv, id, &dc, 0);
- }
-
- case VIDEO_STOP: {
- struct v4l2_decoder_cmd dc;
-
- IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
- memset(&dc, 0, sizeof(dc));
- dc.cmd = V4L2_DEC_CMD_STOP;
- dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY;
- return ivtv_video_command(itv, id, &dc, 0);
- }
-
- case VIDEO_FREEZE: {
- struct v4l2_decoder_cmd dc;
-
- IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
- memset(&dc, 0, sizeof(dc));
- dc.cmd = V4L2_DEC_CMD_PAUSE;
- return ivtv_video_command(itv, id, &dc, 0);
- }
-
- case VIDEO_CONTINUE: {
- struct v4l2_decoder_cmd dc;
-
- IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
- memset(&dc, 0, sizeof(dc));
- dc.cmd = V4L2_DEC_CMD_RESUME;
- return ivtv_video_command(itv, id, &dc, 0);
- }
-
- case VIDEO_COMMAND:
- case VIDEO_TRY_COMMAND: {
- /* Note: struct v4l2_decoder_cmd has the same layout as
- struct video_command */
- struct v4l2_decoder_cmd *dc = arg;
- int try = (cmd == VIDEO_TRY_COMMAND);
-
- if (try)
- IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd);
- else
- IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd);
- return ivtv_video_command(itv, id, dc, try);
- }
-
- case VIDEO_GET_EVENT: {
- struct video_event *ev = arg;
- DEFINE_WAIT(wait);
-
- IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- memset(ev, 0, sizeof(*ev));
- set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
-
- while (1) {
- if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
- ev->type = VIDEO_EVENT_DECODER_STOPPED;
- else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
- ev->type = VIDEO_EVENT_VSYNC;
- ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
- VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
- if (itv->output_mode == OUT_UDMA_YUV &&
- (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
- IVTV_YUV_MODE_PROGRESSIVE) {
- ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
- }
- }
- if (ev->type)
- return 0;
- if (nonblocking)
- return -EAGAIN;
- /* Wait for event. Note that serialize_lock is locked,
- so to allow other processes to access the driver while
- we are waiting unlock first and later lock again. */
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
- if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
- !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
- schedule();
- finish_wait(&itv->event_waitq, &wait);
- mutex_lock(&itv->serialize_lock);
- if (signal_pending(current)) {
- /* return if a signal was received */
- IVTV_DEBUG_INFO("User stopped wait for event\n");
- return -EINTR;
- }
- }
- break;
- }
-
- case VIDEO_SELECT_SOURCE:
- IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
-
- case AUDIO_SET_MUTE:
- IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
- itv->speed_mute_audio = iarg;
- return 0;
-
- case AUDIO_CHANNEL_SELECT:
- IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
- if (iarg > AUDIO_STEREO_SWAPPED)
- return -EINVAL;
- return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1);
-
- case AUDIO_BILINGUAL_CHANNEL_SELECT:
- IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
- if (iarg > AUDIO_STEREO_SWAPPED)
- return -EINVAL;
- return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1);
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static long ivtv_default(struct file *file, void *fh, bool valid_prio,
- int cmd, void *arg)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (!valid_prio) {
- switch (cmd) {
- case IVTV_IOC_PASSTHROUGH_MODE:
- case VIDEO_PLAY:
- case VIDEO_STOP:
- case VIDEO_FREEZE:
- case VIDEO_CONTINUE:
- case VIDEO_COMMAND:
- case VIDEO_SELECT_SOURCE:
- case AUDIO_SET_MUTE:
- case AUDIO_CHANNEL_SELECT:
- case AUDIO_BILINGUAL_CHANNEL_SELECT:
- return -EBUSY;
- }
- }
-
- switch (cmd) {
- case VIDIOC_INT_RESET: {
- u32 val = *(u32 *)arg;
-
- if ((val == 0 && itv->options.newi2c) || (val & 0x01))
- ivtv_reset_ir_gpio(itv);
- if (val & 0x02)
- v4l2_subdev_call(itv->sd_video, core, reset, 0);
- break;
- }
-
- case IVTV_IOC_DMA_FRAME:
- case IVTV_IOC_PASSTHROUGH_MODE:
- case VIDEO_GET_PTS:
- case VIDEO_GET_FRAME_COUNT:
- case VIDEO_GET_EVENT:
- case VIDEO_PLAY:
- case VIDEO_STOP:
- case VIDEO_FREEZE:
- case VIDEO_CONTINUE:
- case VIDEO_COMMAND:
- case VIDEO_TRY_COMMAND:
- case VIDEO_SELECT_SOURCE:
- case AUDIO_SET_MUTE:
- case AUDIO_CHANNEL_SELECT:
- case AUDIO_BILINGUAL_CHANNEL_SELECT:
- return ivtv_decoder_ioctls(file, cmd, (void *)arg);
-
- default:
- return -ENOTTY;
- }
- return 0;
-}
-
-static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
- .vidioc_querycap = ivtv_querycap,
- .vidioc_s_audio = ivtv_s_audio,
- .vidioc_g_audio = ivtv_g_audio,
- .vidioc_enumaudio = ivtv_enumaudio,
- .vidioc_s_audout = ivtv_s_audout,
- .vidioc_g_audout = ivtv_g_audout,
- .vidioc_enum_input = ivtv_enum_input,
- .vidioc_enum_output = ivtv_enum_output,
- .vidioc_enumaudout = ivtv_enumaudout,
- .vidioc_cropcap = ivtv_cropcap,
- .vidioc_s_crop = ivtv_s_crop,
- .vidioc_g_crop = ivtv_g_crop,
- .vidioc_g_input = ivtv_g_input,
- .vidioc_s_input = ivtv_s_input,
- .vidioc_g_output = ivtv_g_output,
- .vidioc_s_output = ivtv_s_output,
- .vidioc_g_frequency = ivtv_g_frequency,
- .vidioc_s_frequency = ivtv_s_frequency,
- .vidioc_s_tuner = ivtv_s_tuner,
- .vidioc_g_tuner = ivtv_g_tuner,
- .vidioc_g_enc_index = ivtv_g_enc_index,
- .vidioc_g_fbuf = ivtv_g_fbuf,
- .vidioc_s_fbuf = ivtv_s_fbuf,
- .vidioc_g_std = ivtv_g_std,
- .vidioc_s_std = ivtv_s_std,
- .vidioc_overlay = ivtv_overlay,
- .vidioc_log_status = ivtv_log_status,
- .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
- .vidioc_encoder_cmd = ivtv_encoder_cmd,
- .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
- .vidioc_decoder_cmd = ivtv_decoder_cmd,
- .vidioc_try_decoder_cmd = ivtv_try_decoder_cmd,
- .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
- .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
- .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
- .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
- .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
- .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
- .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
- .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
- .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
- .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
- .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
- .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
- .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
- .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
- .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
- .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
- .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
- .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
- .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
- .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
- .vidioc_g_chip_ident = ivtv_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = ivtv_g_register,
- .vidioc_s_register = ivtv_s_register,
-#endif
- .vidioc_default = ivtv_default,
- .vidioc_subscribe_event = ivtv_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-void ivtv_set_funcs(struct video_device *vdev)
-{
- vdev->ioctl_ops = &ivtv_ioctl_ops;
-}
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.h b/drivers/media/video/ivtv/ivtv-ioctl.h
deleted file mode 100644
index 7c553d16579..00000000000
--- a/drivers/media/video/ivtv/ivtv-ioctl.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- ioctl system call
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_IOCTL_H
-#define IVTV_IOCTL_H
-
-u16 ivtv_service2vbi(int type);
-void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
-u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt);
-void ivtv_set_osd_alpha(struct ivtv *itv);
-int ivtv_set_speed(struct ivtv *itv, int speed);
-void ivtv_set_funcs(struct video_device *vdev);
-void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std);
-void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std);
-int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
-int ivtv_s_input(struct file *file, void *fh, unsigned int inp);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
deleted file mode 100644
index 1b3b9578bf4..00000000000
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ /dev/null
@@ -1,1038 +0,0 @@
-/* interrupt handling
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-queue.h"
-#include "ivtv-udma.h"
-#include "ivtv-irq.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-vbi.h"
-#include "ivtv-yuv.h"
-#include <media/v4l2-event.h>
-
-#define DMA_MAGIC_COOKIE 0x000001fe
-
-static void ivtv_dma_dec_start(struct ivtv_stream *s);
-
-static const int ivtv_stream_map[] = {
- IVTV_ENC_STREAM_TYPE_MPG,
- IVTV_ENC_STREAM_TYPE_YUV,
- IVTV_ENC_STREAM_TYPE_PCM,
- IVTV_ENC_STREAM_TYPE_VBI,
-};
-
-
-static void ivtv_pio_work_handler(struct ivtv *itv)
-{
- struct ivtv_stream *s = &itv->streams[itv->cur_pio_stream];
- struct ivtv_buffer *buf;
- int i = 0;
-
- IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n");
- if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS ||
- s->vdev == NULL || !ivtv_use_pio(s)) {
- itv->cur_pio_stream = -1;
- /* trigger PIO complete user interrupt */
- write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
- return;
- }
- IVTV_DEBUG_HI_DMA("Process PIO %s\n", s->name);
- list_for_each_entry(buf, &s->q_dma.list, list) {
- u32 size = s->sg_processing[i].size & 0x3ffff;
-
- /* Copy the data from the card to the buffer */
- if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
- memcpy_fromio(buf->buf, itv->dec_mem + s->sg_processing[i].src - IVTV_DECODER_OFFSET, size);
- }
- else {
- memcpy_fromio(buf->buf, itv->enc_mem + s->sg_processing[i].src, size);
- }
- i++;
- if (i == s->sg_processing_size)
- break;
- }
- write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
-}
-
-void ivtv_irq_work_handler(struct kthread_work *work)
-{
- struct ivtv *itv = container_of(work, struct ivtv, irq_work);
-
- if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
- ivtv_pio_work_handler(itv);
-
- if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags))
- ivtv_vbi_work_handler(itv);
-
- if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
- ivtv_yuv_work_handler(itv);
-}
-
-/* Determine the required DMA size, setup enough buffers in the predma queue and
- actually copy the data from the card to the buffers in case a PIO transfer is
- required for this stream.
- */
-static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MAX_DATA])
-{
- struct ivtv *itv = s->itv;
- struct ivtv_buffer *buf;
- u32 bytes_needed = 0;
- u32 offset, size;
- u32 UVoffset = 0, UVsize = 0;
- int skip_bufs = s->q_predma.buffers;
- int idx = s->sg_pending_size;
- int rc;
-
- /* sanity checks */
- if (s->vdev == NULL) {
- IVTV_DEBUG_WARN("Stream %s not started\n", s->name);
- return -1;
- }
- if (!test_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
- IVTV_DEBUG_WARN("Stream %s not open\n", s->name);
- return -1;
- }
-
- /* determine offset, size and PTS for the various streams */
- switch (s->type) {
- case IVTV_ENC_STREAM_TYPE_MPG:
- offset = data[1];
- size = data[2];
- s->pending_pts = 0;
- break;
-
- case IVTV_ENC_STREAM_TYPE_YUV:
- offset = data[1];
- size = data[2];
- UVoffset = data[3];
- UVsize = data[4];
- s->pending_pts = ((u64) data[5] << 32) | data[6];
- break;
-
- case IVTV_ENC_STREAM_TYPE_PCM:
- offset = data[1] + 12;
- size = data[2] - 12;
- s->pending_pts = read_dec(offset - 8) |
- ((u64)(read_dec(offset - 12)) << 32);
- if (itv->has_cx23415)
- offset += IVTV_DECODER_OFFSET;
- break;
-
- case IVTV_ENC_STREAM_TYPE_VBI:
- size = itv->vbi.enc_size * itv->vbi.fpi;
- offset = read_enc(itv->vbi.enc_start - 4) + 12;
- if (offset == 12) {
- IVTV_DEBUG_INFO("VBI offset == 0\n");
- return -1;
- }
- s->pending_pts = read_enc(offset - 4) | ((u64)read_enc(offset - 8) << 32);
- break;
-
- case IVTV_DEC_STREAM_TYPE_VBI:
- size = read_dec(itv->vbi.dec_start + 4) + 8;
- offset = read_dec(itv->vbi.dec_start) + itv->vbi.dec_start;
- s->pending_pts = 0;
- offset += IVTV_DECODER_OFFSET;
- break;
- default:
- /* shouldn't happen */
- return -1;
- }
-
- /* if this is the start of the DMA then fill in the magic cookie */
- if (s->sg_pending_size == 0 && ivtv_use_dma(s)) {
- if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM ||
- s->type == IVTV_DEC_STREAM_TYPE_VBI)) {
- s->pending_backup = read_dec(offset - IVTV_DECODER_OFFSET);
- write_dec_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset - IVTV_DECODER_OFFSET);
- }
- else {
- s->pending_backup = read_enc(offset);
- write_enc_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset);
- }
- s->pending_offset = offset;
- }
-
- bytes_needed = size;
- if (s->type == IVTV_ENC_STREAM_TYPE_YUV) {
- /* The size for the Y samples needs to be rounded upwards to a
- multiple of the buf_size. The UV samples then start in the
- next buffer. */
- bytes_needed = s->buf_size * ((bytes_needed + s->buf_size - 1) / s->buf_size);
- bytes_needed += UVsize;
- }
-
- IVTV_DEBUG_HI_DMA("%s %s: 0x%08x bytes at 0x%08x\n",
- ivtv_use_pio(s) ? "PIO" : "DMA", s->name, bytes_needed, offset);
-
- rc = ivtv_queue_move(s, &s->q_free, &s->q_full, &s->q_predma, bytes_needed);
- if (rc < 0) { /* Insufficient buffers */
- IVTV_DEBUG_WARN("Cannot obtain %d bytes for %s data transfer\n",
- bytes_needed, s->name);
- return -1;
- }
- if (rc && !s->buffers_stolen && test_bit(IVTV_F_S_APPL_IO, &s->s_flags)) {
- IVTV_WARN("All %s stream buffers are full. Dropping data.\n", s->name);
- IVTV_WARN("Cause: the application is not reading fast enough.\n");
- }
- s->buffers_stolen = rc;
-
- /* got the buffers, now fill in sg_pending */
- buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list);
- memset(buf->buf, 0, 128);
- list_for_each_entry(buf, &s->q_predma.list, list) {
- if (skip_bufs-- > 0)
- continue;
- s->sg_pending[idx].dst = buf->dma_handle;
- s->sg_pending[idx].src = offset;
- s->sg_pending[idx].size = s->buf_size;
- buf->bytesused = min(size, s->buf_size);
- buf->dma_xfer_cnt = s->dma_xfer_cnt;
-
- s->q_predma.bytesused += buf->bytesused;
- size -= buf->bytesused;
- offset += s->buf_size;
-
- /* Sync SG buffers */
- ivtv_buf_sync_for_device(s, buf);
-
- if (size == 0) { /* YUV */
- /* process the UV section */
- offset = UVoffset;
- size = UVsize;
- }
- idx++;
- }
- s->sg_pending_size = idx;
- return 0;
-}
-
-static void dma_post(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
- struct ivtv_buffer *buf = NULL;
- struct list_head *p;
- u32 offset;
- __le32 *u32buf;
- int x = 0;
-
- IVTV_DEBUG_HI_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA",
- s->name, s->dma_offset);
- list_for_each(p, &s->q_dma.list) {
- buf = list_entry(p, struct ivtv_buffer, list);
- u32buf = (__le32 *)buf->buf;
-
- /* Sync Buffer */
- ivtv_buf_sync_for_cpu(s, buf);
-
- if (x == 0 && ivtv_use_dma(s)) {
- offset = s->dma_last_offset;
- if (u32buf[offset / 4] != DMA_MAGIC_COOKIE)
- {
- for (offset = 0; offset < 64; offset++) {
- if (u32buf[offset] == DMA_MAGIC_COOKIE) {
- break;
- }
- }
- offset *= 4;
- if (offset == 256) {
- IVTV_DEBUG_WARN("%s: Couldn't find start of buffer within the first 256 bytes\n", s->name);
- offset = s->dma_last_offset;
- }
- if (s->dma_last_offset != offset)
- IVTV_DEBUG_WARN("%s: offset %d -> %d\n", s->name, s->dma_last_offset, offset);
- s->dma_last_offset = offset;
- }
- if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM ||
- s->type == IVTV_DEC_STREAM_TYPE_VBI)) {
- write_dec_sync(0, s->dma_offset - IVTV_DECODER_OFFSET);
- }
- else {
- write_enc_sync(0, s->dma_offset);
- }
- if (offset) {
- buf->bytesused -= offset;
- memcpy(buf->buf, buf->buf + offset, buf->bytesused + offset);
- }
- *u32buf = cpu_to_le32(s->dma_backup);
- }
- x++;
- /* flag byteswap ABCD -> DCBA for MPG & VBI data outside irq */
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG ||
- s->type == IVTV_ENC_STREAM_TYPE_VBI)
- buf->b_flags |= IVTV_F_B_NEED_BUF_SWAP;
- }
- if (buf)
- buf->bytesused += s->dma_last_offset;
- if (buf && s->type == IVTV_DEC_STREAM_TYPE_VBI) {
- list_for_each_entry(buf, &s->q_dma.list, list) {
- /* Parse and Groom VBI Data */
- s->q_dma.bytesused -= buf->bytesused;
- ivtv_process_vbi_data(itv, buf, 0, s->type);
- s->q_dma.bytesused += buf->bytesused;
- }
- if (s->fh == NULL) {
- ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
- return;
- }
- }
- ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused);
- if (s->fh)
- wake_up(&s->waitq);
-}
-
-void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock)
-{
- struct ivtv *itv = s->itv;
- struct yuv_playback_info *yi = &itv->yuv_info;
- u8 frame = yi->draw_frame;
- struct yuv_frame_info *f = &yi->new_frame_info[frame];
- struct ivtv_buffer *buf;
- u32 y_size = 720 * ((f->src_h + 31) & ~31);
- u32 uv_offset = offset + IVTV_YUV_BUFFER_UV_OFFSET;
- int y_done = 0;
- int bytes_written = 0;
- unsigned long flags = 0;
- int idx = 0;
-
- IVTV_DEBUG_HI_DMA("DEC PREPARE DMA %s: %08x %08x\n", s->name, s->q_predma.bytesused, offset);
-
- /* Insert buffer block for YUV if needed */
- if (s->type == IVTV_DEC_STREAM_TYPE_YUV && f->offset_y) {
- if (yi->blanking_dmaptr) {
- s->sg_pending[idx].src = yi->blanking_dmaptr;
- s->sg_pending[idx].dst = offset;
- s->sg_pending[idx].size = 720 * 16;
- }
- offset += 720 * 16;
- idx++;
- }
-
- list_for_each_entry(buf, &s->q_predma.list, list) {
- /* YUV UV Offset from Y Buffer */
- if (s->type == IVTV_DEC_STREAM_TYPE_YUV && !y_done &&
- (bytes_written + buf->bytesused) >= y_size) {
- s->sg_pending[idx].src = buf->dma_handle;
- s->sg_pending[idx].dst = offset;
- s->sg_pending[idx].size = y_size - bytes_written;
- offset = uv_offset;
- if (s->sg_pending[idx].size != buf->bytesused) {
- idx++;
- s->sg_pending[idx].src =
- buf->dma_handle + s->sg_pending[idx - 1].size;
- s->sg_pending[idx].dst = offset;
- s->sg_pending[idx].size =
- buf->bytesused - s->sg_pending[idx - 1].size;
- offset += s->sg_pending[idx].size;
- }
- y_done = 1;
- } else {
- s->sg_pending[idx].src = buf->dma_handle;
- s->sg_pending[idx].dst = offset;
- s->sg_pending[idx].size = buf->bytesused;
- offset += buf->bytesused;
- }
- bytes_written += buf->bytesused;
-
- /* Sync SG buffers */
- ivtv_buf_sync_for_device(s, buf);
- idx++;
- }
- s->sg_pending_size = idx;
-
- /* Sync Hardware SG List of buffers */
- ivtv_stream_sync_for_device(s);
- if (lock)
- spin_lock_irqsave(&itv->dma_reg_lock, flags);
- if (!test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
- ivtv_dma_dec_start(s);
- }
- else {
- set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
- }
- if (lock)
- spin_unlock_irqrestore(&itv->dma_reg_lock, flags);
-}
-
-static void ivtv_dma_enc_start_xfer(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
-
- s->sg_dma->src = cpu_to_le32(s->sg_processing[s->sg_processed].src);
- s->sg_dma->dst = cpu_to_le32(s->sg_processing[s->sg_processed].dst);
- s->sg_dma->size = cpu_to_le32(s->sg_processing[s->sg_processed].size | 0x80000000);
- s->sg_processed++;
- /* Sync Hardware SG List of buffers */
- ivtv_stream_sync_for_device(s);
- write_reg(s->sg_handle, IVTV_REG_ENCDMAADDR);
- write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
- itv->dma_timer.expires = jiffies + msecs_to_jiffies(300);
- add_timer(&itv->dma_timer);
-}
-
-static void ivtv_dma_dec_start_xfer(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
-
- s->sg_dma->src = cpu_to_le32(s->sg_processing[s->sg_processed].src);
- s->sg_dma->dst = cpu_to_le32(s->sg_processing[s->sg_processed].dst);
- s->sg_dma->size = cpu_to_le32(s->sg_processing[s->sg_processed].size | 0x80000000);
- s->sg_processed++;
- /* Sync Hardware SG List of buffers */
- ivtv_stream_sync_for_device(s);
- write_reg(s->sg_handle, IVTV_REG_DECDMAADDR);
- write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
- itv->dma_timer.expires = jiffies + msecs_to_jiffies(300);
- add_timer(&itv->dma_timer);
-}
-
-/* start the encoder DMA */
-static void ivtv_dma_enc_start(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
- struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
- int i;
-
- IVTV_DEBUG_HI_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name);
-
- if (s->q_predma.bytesused)
- ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
-
- if (ivtv_use_dma(s))
- s->sg_pending[s->sg_pending_size - 1].size += 256;
-
- /* If this is an MPEG stream, and VBI data is also pending, then append the
- VBI DMA to the MPEG DMA and transfer both sets of data at once.
-
- VBI DMA is a second class citizen compared to MPEG and mixing them together
- will confuse the firmware (the end of a VBI DMA is seen as the end of a
- MPEG DMA, thus effectively dropping an MPEG frame). So instead we make
- sure we only use the MPEG DMA to transfer the VBI DMA if both are in
- use. This way no conflicts occur. */
- clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags);
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->sg_pending_size &&
- s->sg_pending_size + s_vbi->sg_pending_size <= s->buffers) {
- ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused);
- if (ivtv_use_dma(s_vbi))
- s_vbi->sg_pending[s_vbi->sg_pending_size - 1].size += 256;
- for (i = 0; i < s_vbi->sg_pending_size; i++) {
- s->sg_pending[s->sg_pending_size++] = s_vbi->sg_pending[i];
- }
- s_vbi->dma_offset = s_vbi->pending_offset;
- s_vbi->sg_pending_size = 0;
- s_vbi->dma_xfer_cnt++;
- set_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags);
- IVTV_DEBUG_HI_DMA("include DMA for %s\n", s_vbi->name);
- }
-
- s->dma_xfer_cnt++;
- memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_host_element) * s->sg_pending_size);
- s->sg_processing_size = s->sg_pending_size;
- s->sg_pending_size = 0;
- s->sg_processed = 0;
- s->dma_offset = s->pending_offset;
- s->dma_backup = s->pending_backup;
- s->dma_pts = s->pending_pts;
-
- if (ivtv_use_pio(s)) {
- set_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags);
- set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
- set_bit(IVTV_F_I_PIO, &itv->i_flags);
- itv->cur_pio_stream = s->type;
- }
- else {
- itv->dma_retries = 0;
- ivtv_dma_enc_start_xfer(s);
- set_bit(IVTV_F_I_DMA, &itv->i_flags);
- itv->cur_dma_stream = s->type;
- }
-}
-
-static void ivtv_dma_dec_start(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
-
- if (s->q_predma.bytesused)
- ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
- s->dma_xfer_cnt++;
- memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_host_element) * s->sg_pending_size);
- s->sg_processing_size = s->sg_pending_size;
- s->sg_pending_size = 0;
- s->sg_processed = 0;
-
- IVTV_DEBUG_HI_DMA("start DMA for %s\n", s->name);
- itv->dma_retries = 0;
- ivtv_dma_dec_start_xfer(s);
- set_bit(IVTV_F_I_DMA, &itv->i_flags);
- itv->cur_dma_stream = s->type;
-}
-
-static void ivtv_irq_dma_read(struct ivtv *itv)
-{
- struct ivtv_stream *s = NULL;
- struct ivtv_buffer *buf;
- int hw_stream_type = 0;
-
- IVTV_DEBUG_HI_IRQ("DEC DMA READ\n");
-
- del_timer(&itv->dma_timer);
-
- if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && itv->cur_dma_stream < 0)
- return;
-
- if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
- s = &itv->streams[itv->cur_dma_stream];
- ivtv_stream_sync_for_cpu(s);
-
- if (read_reg(IVTV_REG_DMASTATUS) & 0x14) {
- IVTV_DEBUG_WARN("DEC DMA ERROR %x (xfer %d of %d, retry %d)\n",
- read_reg(IVTV_REG_DMASTATUS),
- s->sg_processed, s->sg_processing_size, itv->dma_retries);
- write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
- if (itv->dma_retries == 3) {
- /* Too many retries, give up on this frame */
- itv->dma_retries = 0;
- s->sg_processed = s->sg_processing_size;
- }
- else {
- /* Retry, starting with the first xfer segment.
- Just retrying the current segment is not sufficient. */
- s->sg_processed = 0;
- itv->dma_retries++;
- }
- }
- if (s->sg_processed < s->sg_processing_size) {
- /* DMA next buffer */
- ivtv_dma_dec_start_xfer(s);
- return;
- }
- if (s->type == IVTV_DEC_STREAM_TYPE_YUV)
- hw_stream_type = 2;
- IVTV_DEBUG_HI_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused);
-
- /* For some reason must kick the firmware, like PIO mode,
- I think this tells the firmware we are done and the size
- of the xfer so it can calculate what we need next.
- I think we can do this part ourselves but would have to
- fully calculate xfer info ourselves and not use interrupts
- */
- ivtv_vapi(itv, CX2341X_DEC_SCHED_DMA_FROM_HOST, 3, 0, s->q_dma.bytesused,
- hw_stream_type);
-
- /* Free last DMA call */
- while ((buf = ivtv_dequeue(s, &s->q_dma)) != NULL) {
- ivtv_buf_sync_for_cpu(s, buf);
- ivtv_enqueue(s, buf, &s->q_free);
- }
- wake_up(&s->waitq);
- }
- clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
- clear_bit(IVTV_F_I_DMA, &itv->i_flags);
- itv->cur_dma_stream = -1;
- wake_up(&itv->dma_waitq);
-}
-
-static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct ivtv_stream *s;
-
- ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
- IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream);
-
- del_timer(&itv->dma_timer);
-
- if (itv->cur_dma_stream < 0)
- return;
-
- s = &itv->streams[itv->cur_dma_stream];
- ivtv_stream_sync_for_cpu(s);
-
- if (data[0] & 0x18) {
- IVTV_DEBUG_WARN("ENC DMA ERROR %x (offset %08x, xfer %d of %d, retry %d)\n", data[0],
- s->dma_offset, s->sg_processed, s->sg_processing_size, itv->dma_retries);
- write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
- if (itv->dma_retries == 3) {
- /* Too many retries, give up on this frame */
- itv->dma_retries = 0;
- s->sg_processed = s->sg_processing_size;
- }
- else {
- /* Retry, starting with the first xfer segment.
- Just retrying the current segment is not sufficient. */
- s->sg_processed = 0;
- itv->dma_retries++;
- }
- }
- if (s->sg_processed < s->sg_processing_size) {
- /* DMA next buffer */
- ivtv_dma_enc_start_xfer(s);
- return;
- }
- clear_bit(IVTV_F_I_DMA, &itv->i_flags);
- itv->cur_dma_stream = -1;
- dma_post(s);
- if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
- s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
- dma_post(s);
- }
- s->sg_processing_size = 0;
- s->sg_processed = 0;
- wake_up(&itv->dma_waitq);
-}
-
-static void ivtv_irq_enc_pio_complete(struct ivtv *itv)
-{
- struct ivtv_stream *s;
-
- if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS) {
- itv->cur_pio_stream = -1;
- return;
- }
- s = &itv->streams[itv->cur_pio_stream];
- IVTV_DEBUG_HI_IRQ("ENC PIO COMPLETE %s\n", s->name);
- clear_bit(IVTV_F_I_PIO, &itv->i_flags);
- itv->cur_pio_stream = -1;
- dma_post(s);
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
- ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 0);
- else if (s->type == IVTV_ENC_STREAM_TYPE_YUV)
- ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 1);
- else if (s->type == IVTV_ENC_STREAM_TYPE_PCM)
- ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 2);
- clear_bit(IVTV_F_I_PIO, &itv->i_flags);
- if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
- s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
- dma_post(s);
- }
- wake_up(&itv->dma_waitq);
-}
-
-static void ivtv_irq_dma_err(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- u32 status;
-
- del_timer(&itv->dma_timer);
-
- ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
- status = read_reg(IVTV_REG_DMASTATUS);
- IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1],
- status, itv->cur_dma_stream);
- /*
- * We do *not* write back to the IVTV_REG_DMASTATUS register to
- * clear the error status, if either the encoder write (0x02) or
- * decoder read (0x01) bus master DMA operation do not indicate
- * completed. We can race with the DMA engine, which may have
- * transitioned to completed status *after* we read the register.
- * Setting a IVTV_REG_DMASTATUS flag back to "busy" status, after the
- * DMA engine has completed, will cause the DMA engine to stop working.
- */
- status &= 0x3;
- if (status == 0x3)
- write_reg(status, IVTV_REG_DMASTATUS);
-
- if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) &&
- itv->cur_dma_stream >= 0 && itv->cur_dma_stream < IVTV_MAX_STREAMS) {
- struct ivtv_stream *s = &itv->streams[itv->cur_dma_stream];
-
- if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
- /* retry */
- /*
- * FIXME - handle cases of DMA error similar to
- * encoder below, except conditioned on status & 0x1
- */
- ivtv_dma_dec_start(s);
- return;
- } else {
- if ((status & 0x2) == 0) {
- /*
- * CX2341x Bus Master DMA write is ongoing.
- * Reset the timer and let it complete.
- */
- itv->dma_timer.expires =
- jiffies + msecs_to_jiffies(600);
- add_timer(&itv->dma_timer);
- return;
- }
-
- if (itv->dma_retries < 3) {
- /*
- * CX2341x Bus Master DMA write has ended.
- * Retry the write, starting with the first
- * xfer segment. Just retrying the current
- * segment is not sufficient.
- */
- s->sg_processed = 0;
- itv->dma_retries++;
- ivtv_dma_enc_start_xfer(s);
- return;
- }
- /* Too many retries, give up on this one */
- }
-
- }
- if (test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
- ivtv_udma_start(itv);
- return;
- }
- clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
- clear_bit(IVTV_F_I_DMA, &itv->i_flags);
- itv->cur_dma_stream = -1;
- wake_up(&itv->dma_waitq);
-}
-
-static void ivtv_irq_enc_start_cap(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct ivtv_stream *s;
-
- /* Get DMA destination and size arguments from card */
- ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, 7, data);
- IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]);
-
- if (data[0] > 2 || data[1] == 0 || data[2] == 0) {
- IVTV_DEBUG_WARN("Unknown input: %08x %08x %08x\n",
- data[0], data[1], data[2]);
- return;
- }
- s = &itv->streams[ivtv_stream_map[data[0]]];
- if (!stream_enc_dma_append(s, data)) {
- set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
- }
-}
-
-static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct ivtv_stream *s;
-
- IVTV_DEBUG_HI_IRQ("ENC START VBI CAP\n");
- s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
-
- if (!stream_enc_dma_append(s, data))
- set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
-}
-
-static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];
-
- IVTV_DEBUG_HI_IRQ("DEC VBI REINSERT\n");
- if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) &&
- !stream_enc_dma_append(s, data)) {
- set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags);
- }
-}
-
-static void ivtv_irq_dec_data_req(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct ivtv_stream *s;
-
- /* YUV or MPG */
-
- if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) {
- ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data);
- itv->dma_data_req_size =
- 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
- itv->dma_data_req_offset = data[1];
- if (atomic_read(&itv->yuv_info.next_dma_frame) >= 0)
- ivtv_yuv_frame_complete(itv);
- s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
- }
- else {
- ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 3, data);
- itv->dma_data_req_size = min_t(u32, data[2], 0x10000);
- itv->dma_data_req_offset = data[1];
- s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
- }
- IVTV_DEBUG_HI_IRQ("DEC DATA REQ %s: %d %08x %u\n", s->name, s->q_full.bytesused,
- itv->dma_data_req_offset, itv->dma_data_req_size);
- if (itv->dma_data_req_size == 0 || s->q_full.bytesused < itv->dma_data_req_size) {
- set_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
- }
- else {
- if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
- ivtv_yuv_setup_stream_frame(itv);
- clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
- ivtv_queue_move(s, &s->q_full, NULL, &s->q_predma, itv->dma_data_req_size);
- ivtv_dma_stream_dec_prepare(s, itv->dma_data_req_offset + IVTV_DECODER_OFFSET, 0);
- }
-}
-
-static void ivtv_irq_vsync(struct ivtv *itv)
-{
- /* The vsync interrupt is unusual in that it won't clear until
- * the end of the first line for the current field, at which
- * point it clears itself. This can result in repeated vsync
- * interrupts, or a missed vsync. Read some of the registers
- * to determine the line being displayed and ensure we handle
- * one vsync per frame.
- */
- unsigned int frame = read_reg(IVTV_REG_DEC_LINE_FIELD) & 1;
- struct yuv_playback_info *yi = &itv->yuv_info;
- int last_dma_frame = atomic_read(&yi->next_dma_frame);
- struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame];
-
- if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n");
-
- if (((frame ^ f->sync_field) == 0 &&
- ((itv->last_vsync_field & 1) ^ f->sync_field)) ||
- (frame != (itv->last_vsync_field & 1) && !f->interlaced)) {
- int next_dma_frame = last_dma_frame;
-
- if (!(f->interlaced && f->delay && yi->fields_lapsed < 1)) {
- if (next_dma_frame >= 0 && next_dma_frame != atomic_read(&yi->next_fill_frame)) {
- write_reg(yuv_offset[next_dma_frame] >> 4, 0x82c);
- write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x830);
- write_reg(yuv_offset[next_dma_frame] >> 4, 0x834);
- write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x838);
- next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS;
- atomic_set(&yi->next_dma_frame, next_dma_frame);
- yi->fields_lapsed = -1;
- yi->running = 1;
- }
- }
- }
- if (frame != (itv->last_vsync_field & 1)) {
- static const struct v4l2_event evtop = {
- .type = V4L2_EVENT_VSYNC,
- .u.vsync.field = V4L2_FIELD_TOP,
- };
- static const struct v4l2_event evbottom = {
- .type = V4L2_EVENT_VSYNC,
- .u.vsync.field = V4L2_FIELD_BOTTOM,
- };
- struct ivtv_stream *s = ivtv_get_output_stream(itv);
-
- itv->last_vsync_field += 1;
- if (frame == 0) {
- clear_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
- clear_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags);
- }
- else {
- set_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags);
- }
- if (test_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags)) {
- set_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags);
- wake_up(&itv->event_waitq);
- if (s)
- wake_up(&s->waitq);
- }
- if (s && s->vdev)
- v4l2_event_queue(s->vdev, frame ? &evtop : &evbottom);
- wake_up(&itv->vsync_waitq);
-
- /* Send VBI to saa7127 */
- if (frame && (itv->output_mode == OUT_PASSTHROUGH ||
- test_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags) ||
- test_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags) ||
- test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags))) {
- set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags);
- set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
- }
-
- /* Check if we need to update the yuv registers */
- if (yi->running && (yi->yuv_forced_update || f->update)) {
- if (!f->update) {
- last_dma_frame =
- (u8)(atomic_read(&yi->next_dma_frame) -
- 1) % IVTV_YUV_BUFFERS;
- f = &yi->new_frame_info[last_dma_frame];
- }
-
- if (f->src_w) {
- yi->update_frame = last_dma_frame;
- f->update = 0;
- yi->yuv_forced_update = 0;
- set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags);
- set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
- }
- }
-
- yi->fields_lapsed++;
- }
-}
-
-#define IVTV_IRQ_DMA (IVTV_IRQ_DMA_READ | IVTV_IRQ_ENC_DMA_COMPLETE | IVTV_IRQ_DMA_ERR | IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_VBI_CAP | IVTV_IRQ_DEC_DATA_REQ | IVTV_IRQ_DEC_VBI_RE_INSERT)
-
-irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
-{
- struct ivtv *itv = (struct ivtv *)dev_id;
- u32 combo;
- u32 stat;
- int i;
- u8 vsync_force = 0;
-
- spin_lock(&itv->dma_reg_lock);
- /* get contents of irq status register */
- stat = read_reg(IVTV_REG_IRQSTATUS);
-
- combo = ~itv->irqmask & stat;
-
- /* Clear out IRQ */
- if (combo) write_reg(combo, IVTV_REG_IRQSTATUS);
-
- if (0 == combo) {
- /* The vsync interrupt is unusual and clears itself. If we
- * took too long, we may have missed it. Do some checks
- */
- if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) {
- /* vsync is enabled, see if we're in a new field */
- if ((itv->last_vsync_field & 1) !=
- (read_reg(IVTV_REG_DEC_LINE_FIELD) & 1)) {
- /* New field, looks like we missed it */
- IVTV_DEBUG_YUV("VSync interrupt missed %d\n",
- read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16);
- vsync_force = 1;
- }
- }
-
- if (!vsync_force) {
- /* No Vsync expected, wasn't for us */
- spin_unlock(&itv->dma_reg_lock);
- return IRQ_NONE;
- }
- }
-
- /* Exclude interrupts noted below from the output, otherwise the log is flooded with
- these messages */
- if (combo & ~0xff6d0400)
- IVTV_DEBUG_HI_IRQ("======= valid IRQ bits: 0x%08x ======\n", combo);
-
- if (combo & IVTV_IRQ_DEC_DMA_COMPLETE) {
- IVTV_DEBUG_HI_IRQ("DEC DMA COMPLETE\n");
- }
-
- if (combo & IVTV_IRQ_DMA_READ) {
- ivtv_irq_dma_read(itv);
- }
-
- if (combo & IVTV_IRQ_ENC_DMA_COMPLETE) {
- ivtv_irq_enc_dma_complete(itv);
- }
-
- if (combo & IVTV_IRQ_ENC_PIO_COMPLETE) {
- ivtv_irq_enc_pio_complete(itv);
- }
-
- if (combo & IVTV_IRQ_DMA_ERR) {
- ivtv_irq_dma_err(itv);
- }
-
- if (combo & IVTV_IRQ_ENC_START_CAP) {
- ivtv_irq_enc_start_cap(itv);
- }
-
- if (combo & IVTV_IRQ_ENC_VBI_CAP) {
- ivtv_irq_enc_vbi_cap(itv);
- }
-
- if (combo & IVTV_IRQ_DEC_VBI_RE_INSERT) {
- ivtv_irq_dec_vbi_reinsert(itv);
- }
-
- if (combo & IVTV_IRQ_ENC_EOS) {
- IVTV_DEBUG_IRQ("ENC EOS\n");
- set_bit(IVTV_F_I_EOS, &itv->i_flags);
- wake_up(&itv->eos_waitq);
- }
-
- if (combo & IVTV_IRQ_DEC_DATA_REQ) {
- ivtv_irq_dec_data_req(itv);
- }
-
- /* Decoder Vertical Sync - We can't rely on 'combo', so check if vsync enabled */
- if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) {
- ivtv_irq_vsync(itv);
- }
-
- if (combo & IVTV_IRQ_ENC_VIM_RST) {
- IVTV_DEBUG_IRQ("VIM RST\n");
- /*ivtv_vapi(itv, CX2341X_ENC_REFRESH_INPUT, 0); */
- }
-
- if (combo & IVTV_IRQ_DEC_AUD_MODE_CHG) {
- IVTV_DEBUG_INFO("Stereo mode changed\n");
- }
-
- if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
- itv->irq_rr_idx++;
- for (i = 0; i < IVTV_MAX_STREAMS; i++) {
- int idx = (i + itv->irq_rr_idx) % IVTV_MAX_STREAMS;
- struct ivtv_stream *s = &itv->streams[idx];
-
- if (!test_and_clear_bit(IVTV_F_S_DMA_PENDING, &s->s_flags))
- continue;
- if (s->type >= IVTV_DEC_STREAM_TYPE_MPG)
- ivtv_dma_dec_start(s);
- else
- ivtv_dma_enc_start(s);
- break;
- }
-
- if (i == IVTV_MAX_STREAMS &&
- test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
- ivtv_udma_start(itv);
- }
-
- if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) {
- itv->irq_rr_idx++;
- for (i = 0; i < IVTV_MAX_STREAMS; i++) {
- int idx = (i + itv->irq_rr_idx) % IVTV_MAX_STREAMS;
- struct ivtv_stream *s = &itv->streams[idx];
-
- if (!test_and_clear_bit(IVTV_F_S_PIO_PENDING, &s->s_flags))
- continue;
- if (s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type < IVTV_DEC_STREAM_TYPE_MPG)
- ivtv_dma_enc_start(s);
- break;
- }
- }
-
- if (test_and_clear_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags)) {
- queue_kthread_work(&itv->irq_worker, &itv->irq_work);
- }
-
- spin_unlock(&itv->dma_reg_lock);
-
- /* If we've just handled a 'forced' vsync, it's safest to say it
- * wasn't ours. Another device may have triggered it at just
- * the right time.
- */
- return vsync_force ? IRQ_NONE : IRQ_HANDLED;
-}
-
-void ivtv_unfinished_dma(unsigned long arg)
-{
- struct ivtv *itv = (struct ivtv *)arg;
-
- if (!test_bit(IVTV_F_I_DMA, &itv->i_flags))
- return;
- IVTV_ERR("DMA TIMEOUT %08x %d\n", read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);
-
- write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
- clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
- clear_bit(IVTV_F_I_DMA, &itv->i_flags);
- itv->cur_dma_stream = -1;
- wake_up(&itv->dma_waitq);
-}
diff --git a/drivers/media/video/ivtv/ivtv-irq.h b/drivers/media/video/ivtv/ivtv-irq.h
deleted file mode 100644
index 1e84433737c..00000000000
--- a/drivers/media/video/ivtv/ivtv-irq.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- interrupt handling
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_IRQ_H
-#define IVTV_IRQ_H
-
-#define IVTV_IRQ_ENC_START_CAP (0x1 << 31)
-#define IVTV_IRQ_ENC_EOS (0x1 << 30)
-#define IVTV_IRQ_ENC_VBI_CAP (0x1 << 29)
-#define IVTV_IRQ_ENC_VIM_RST (0x1 << 28)
-#define IVTV_IRQ_ENC_DMA_COMPLETE (0x1 << 27)
-#define IVTV_IRQ_ENC_PIO_COMPLETE (0x1 << 25)
-#define IVTV_IRQ_DEC_AUD_MODE_CHG (0x1 << 24)
-#define IVTV_IRQ_DEC_DATA_REQ (0x1 << 22)
-#define IVTV_IRQ_DEC_DMA_COMPLETE (0x1 << 20)
-#define IVTV_IRQ_DEC_VBI_RE_INSERT (0x1 << 19)
-#define IVTV_IRQ_DMA_ERR (0x1 << 18)
-#define IVTV_IRQ_DMA_WRITE (0x1 << 17)
-#define IVTV_IRQ_DMA_READ (0x1 << 16)
-#define IVTV_IRQ_DEC_VSYNC (0x1 << 10)
-
-/* IRQ Masks */
-#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|\
- IVTV_IRQ_DMA_READ|IVTV_IRQ_ENC_PIO_COMPLETE)
-
-#define IVTV_IRQ_MASK_CAPTURE (IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_EOS)
-#define IVTV_IRQ_MASK_DECODE (IVTV_IRQ_DEC_DATA_REQ|IVTV_IRQ_DEC_AUD_MODE_CHG)
-
-irqreturn_t ivtv_irq_handler(int irq, void *dev_id);
-
-void ivtv_irq_work_handler(struct kthread_work *work);
-void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock);
-void ivtv_unfinished_dma(unsigned long arg);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c
deleted file mode 100644
index e3ce9676378..00000000000
--- a/drivers/media/video/ivtv/ivtv-mailbox.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- mailbox functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <stdarg.h>
-
-#include "ivtv-driver.h"
-#include "ivtv-mailbox.h"
-
-/* Firmware mailbox flags*/
-#define IVTV_MBOX_FIRMWARE_DONE 0x00000004
-#define IVTV_MBOX_DRIVER_DONE 0x00000002
-#define IVTV_MBOX_DRIVER_BUSY 0x00000001
-#define IVTV_MBOX_FREE 0x00000000
-
-/* Firmware mailbox standard timeout */
-#define IVTV_API_STD_TIMEOUT 0x02000000
-
-#define API_CACHE (1 << 0) /* Allow the command to be stored in the cache */
-#define API_RESULT (1 << 1) /* Allow 1 second for this cmd to end */
-#define API_FAST_RESULT (3 << 1) /* Allow 0.1 second for this cmd to end */
-#define API_DMA (1 << 3) /* DMA mailbox, has special handling */
-#define API_HIGH_VOL (1 << 5) /* High volume command (i.e. called during encoding or decoding) */
-#define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */
-#define API_NO_WAIT_RES (1 << 5) /* Command may not wait for the result */
-#define API_NO_POLL (1 << 6) /* Avoid pointless polling */
-
-struct ivtv_api_info {
- int flags; /* Flags, see above */
- const char *name; /* The name of the command */
-};
-
-#define API_ENTRY(x, f) [x] = { (f), #x }
-
-static const struct ivtv_api_info api_info[256] = {
- /* MPEG encoder API */
- API_ENTRY(CX2341X_ENC_PING_FW, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_START_CAPTURE, API_RESULT | API_NO_POLL),
- API_ENTRY(CX2341X_ENC_STOP_CAPTURE, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_PCR_ID, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_FRAME_RATE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_FRAME_SIZE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_BIT_RATE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_GOP_PROPERTIES, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_ASPECT_RATIO, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_MODE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_PROPS, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_CORING_LEVELS, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_VBI_LINE, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_STREAM_TYPE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_OUTPUT_PORT, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_AUDIO_PROPERTIES, API_CACHE),
- API_ENTRY(CX2341X_ENC_HALT_FW, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_GET_VERSION, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_SET_GOP_CLOSURE, API_CACHE),
- API_ENTRY(CX2341X_ENC_GET_SEQ_END, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_PGM_INDEX_INFO, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_SET_VBI_CONFIG, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_DMA_BLOCK_SIZE, API_CACHE),
- API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_10, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_9, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST, API_DMA | API_HIGH_VOL),
- API_ENTRY(CX2341X_ENC_INITIALIZE_INPUT, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_FRAME_DROP_RATE, API_CACHE),
- API_ENTRY(CX2341X_ENC_PAUSE_ENCODER, API_RESULT),
- API_ENTRY(CX2341X_ENC_REFRESH_INPUT, API_NO_WAIT_MB | API_HIGH_VOL),
- API_ENTRY(CX2341X_ENC_SET_COPYRIGHT, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_EVENT_NOTIFICATION, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_NUM_VSYNC_LINES, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_PLACEHOLDER, API_CACHE),
- API_ENTRY(CX2341X_ENC_MUTE_VIDEO, API_RESULT),
- API_ENTRY(CX2341X_ENC_MUTE_AUDIO, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_VERT_CROP_LINE, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_MISC, API_FAST_RESULT),
- /* Obsolete PULLDOWN API command */
- API_ENTRY(0xb1, API_CACHE),
-
- /* MPEG decoder API */
- API_ENTRY(CX2341X_DEC_PING_FW, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_START_PLAYBACK, API_RESULT | API_NO_POLL),
- API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, API_RESULT),
- API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, API_RESULT),
- API_ENTRY(CX2341X_DEC_STEP_VIDEO, API_RESULT),
- API_ENTRY(CX2341X_DEC_SET_DMA_BLOCK_SIZE, API_CACHE),
- API_ENTRY(CX2341X_DEC_GET_XFER_INFO, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_GET_DMA_STATUS, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST, API_DMA | API_HIGH_VOL),
- API_ENTRY(CX2341X_DEC_PAUSE_PLAYBACK, API_RESULT),
- API_ENTRY(CX2341X_DEC_HALT_FW, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_SET_STANDARD, API_CACHE),
- API_ENTRY(CX2341X_DEC_GET_VERSION, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_SET_STREAM_INPUT, API_CACHE),
- API_ENTRY(CX2341X_DEC_GET_TIMING_INFO, API_RESULT /*| API_NO_WAIT_RES*/),
- API_ENTRY(CX2341X_DEC_SET_AUDIO_MODE, API_CACHE),
- API_ENTRY(CX2341X_DEC_SET_EVENT_NOTIFICATION, API_RESULT),
- API_ENTRY(CX2341X_DEC_SET_DISPLAY_BUFFERS, API_CACHE),
- API_ENTRY(CX2341X_DEC_EXTRACT_VBI, API_RESULT),
- API_ENTRY(CX2341X_DEC_SET_DECODER_SOURCE, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_SET_PREBUFFERING, API_CACHE),
-
- /* OSD API */
- API_ENTRY(CX2341X_OSD_GET_FRAMEBUFFER, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_GET_PIXEL_FORMAT, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_PIXEL_FORMAT, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_STATE, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_STATE, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_OSD_COORDS, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_OSD_COORDS, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_SCREEN_COORDS, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_SCREEN_COORDS, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_GLOBAL_ALPHA, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_GLOBAL_ALPHA, API_CACHE),
- API_ENTRY(CX2341X_OSD_SET_BLEND_COORDS, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_FLICKER_STATE, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_FLICKER_STATE, API_CACHE),
- API_ENTRY(CX2341X_OSD_BLT_COPY, API_RESULT),
- API_ENTRY(CX2341X_OSD_BLT_FILL, API_RESULT),
- API_ENTRY(CX2341X_OSD_BLT_TEXT, API_RESULT),
- API_ENTRY(CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, API_CACHE),
- API_ENTRY(CX2341X_OSD_SET_CHROMA_KEY, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_ALPHA_CONTENT_INDEX, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_ALPHA_CONTENT_INDEX, API_CACHE)
-};
-
-static int try_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int mb)
-{
- u32 flags = readl(&mbdata->mbox[mb].flags);
- int is_free = flags == IVTV_MBOX_FREE || (flags & IVTV_MBOX_FIRMWARE_DONE);
-
- /* if the mailbox is free, then try to claim it */
- if (is_free && !test_and_set_bit(mb, &mbdata->busy)) {
- write_sync(IVTV_MBOX_DRIVER_BUSY, &mbdata->mbox[mb].flags);
- return 1;
- }
- return 0;
-}
-
-/* Try to find a free mailbox. Note mailbox 0 is reserved for DMA and so is not
- attempted here. */
-static int get_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int flags)
-{
- unsigned long then = jiffies;
- int i, mb;
- int max_mbox = mbdata->max_mbox;
- int retries = 100;
-
- /* All slow commands use the same mailbox, serializing them and also
- leaving the other mailbox free for simple fast commands. */
- if ((flags & API_FAST_RESULT) == API_RESULT)
- max_mbox = 1;
-
- /* find free non-DMA mailbox */
- for (i = 0; i < retries; i++) {
- for (mb = 1; mb <= max_mbox; mb++)
- if (try_mailbox(itv, mbdata, mb))
- return mb;
-
- /* Sleep before a retry, if not atomic */
- if (!(flags & API_NO_WAIT_MB)) {
- if (time_after(jiffies,
- then + msecs_to_jiffies(10*retries)))
- break;
- ivtv_msleep_timeout(10, 0);
- }
- }
- return -ENODEV;
-}
-
-static void write_mailbox(volatile struct ivtv_mailbox __iomem *mbox, int cmd, int args, u32 data[])
-{
- int i;
-
- write_sync(cmd, &mbox->cmd);
- write_sync(IVTV_API_STD_TIMEOUT, &mbox->timeout);
-
- for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++)
- write_sync(data[i], &mbox->data[i]);
-
- write_sync(IVTV_MBOX_DRIVER_DONE | IVTV_MBOX_DRIVER_BUSY, &mbox->flags);
-}
-
-static void clear_all_mailboxes(struct ivtv *itv, struct ivtv_mailbox_data *mbdata)
-{
- int i;
-
- for (i = 0; i <= mbdata->max_mbox; i++) {
- IVTV_DEBUG_WARN("Clearing mailbox %d: cmd 0x%08x flags 0x%08x\n",
- i, readl(&mbdata->mbox[i].cmd), readl(&mbdata->mbox[i].flags));
- write_sync(0, &mbdata->mbox[i].flags);
- clear_bit(i, &mbdata->busy);
- }
-}
-
-static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[])
-{
- struct ivtv_mailbox_data *mbdata = (cmd >= 128) ? &itv->enc_mbox : &itv->dec_mbox;
- volatile struct ivtv_mailbox __iomem *mbox;
- int api_timeout = msecs_to_jiffies(1000);
- int flags, mb, i;
- unsigned long then;
-
- /* sanity checks */
- if (NULL == mbdata) {
- IVTV_ERR("No mailbox allocated\n");
- return -ENODEV;
- }
- if (args < 0 || args > CX2341X_MBOX_MAX_DATA ||
- cmd < 0 || cmd > 255 || api_info[cmd].name == NULL) {
- IVTV_ERR("Invalid MB call: cmd = 0x%02x, args = %d\n", cmd, args);
- return -EINVAL;
- }
-
- if (api_info[cmd].flags & API_HIGH_VOL) {
- IVTV_DEBUG_HI_MB("MB Call: %s\n", api_info[cmd].name);
- }
- else {
- IVTV_DEBUG_MB("MB Call: %s\n", api_info[cmd].name);
- }
-
- /* clear possibly uninitialized part of data array */
- for (i = args; i < CX2341X_MBOX_MAX_DATA; i++)
- data[i] = 0;
-
- /* If this command was issued within the last 30 minutes and with identical
- data, then just return 0 as there is no need to issue this command again.
- Just an optimization to prevent unnecessary use of mailboxes. */
- if (itv->api_cache[cmd].last_jiffies &&
- time_before(jiffies,
- itv->api_cache[cmd].last_jiffies +
- msecs_to_jiffies(1800000)) &&
- !memcmp(data, itv->api_cache[cmd].data, sizeof(itv->api_cache[cmd].data))) {
- itv->api_cache[cmd].last_jiffies = jiffies;
- return 0;
- }
-
- flags = api_info[cmd].flags;
-
- if (flags & API_DMA) {
- for (i = 0; i < 100; i++) {
- mb = i % (mbdata->max_mbox + 1);
- if (try_mailbox(itv, mbdata, mb)) {
- write_mailbox(&mbdata->mbox[mb], cmd, args, data);
- clear_bit(mb, &mbdata->busy);
- return 0;
- }
- IVTV_DEBUG_WARN("%s: mailbox %d not free %08x\n",
- api_info[cmd].name, mb, readl(&mbdata->mbox[mb].flags));
- }
- IVTV_WARN("Could not find free DMA mailbox for %s\n", api_info[cmd].name);
- clear_all_mailboxes(itv, mbdata);
- return -EBUSY;
- }
-
- if ((flags & API_FAST_RESULT) == API_FAST_RESULT)
- api_timeout = msecs_to_jiffies(100);
-
- mb = get_mailbox(itv, mbdata, flags);
- if (mb < 0) {
- IVTV_DEBUG_WARN("No free mailbox found (%s)\n", api_info[cmd].name);
- clear_all_mailboxes(itv, mbdata);
- return -EBUSY;
- }
- mbox = &mbdata->mbox[mb];
- write_mailbox(mbox, cmd, args, data);
- if (flags & API_CACHE) {
- memcpy(itv->api_cache[cmd].data, data, sizeof(itv->api_cache[cmd].data));
- itv->api_cache[cmd].last_jiffies = jiffies;
- }
- if ((flags & API_RESULT) == 0) {
- clear_bit(mb, &mbdata->busy);
- return 0;
- }
-
- /* Get results */
- then = jiffies;
-
- if (!(flags & API_NO_POLL)) {
- /* First try to poll, then switch to delays */
- for (i = 0; i < 100; i++) {
- if (readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)
- break;
- }
- }
- while (!(readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)) {
- if (time_after(jiffies, then + api_timeout)) {
- IVTV_DEBUG_WARN("Could not get result (%s)\n", api_info[cmd].name);
- /* reset the mailbox, but it is likely too late already */
- write_sync(0, &mbox->flags);
- clear_bit(mb, &mbdata->busy);
- return -EIO;
- }
- if (flags & API_NO_WAIT_RES)
- mdelay(1);
- else
- ivtv_msleep_timeout(1, 0);
- }
- if (time_after(jiffies, then + msecs_to_jiffies(100)))
- IVTV_DEBUG_WARN("%s took %u jiffies\n",
- api_info[cmd].name,
- jiffies_to_msecs(jiffies - then));
-
- for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++)
- data[i] = readl(&mbox->data[i]);
- write_sync(0, &mbox->flags);
- clear_bit(mb, &mbdata->busy);
- return 0;
-}
-
-int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[])
-{
- int res = ivtv_api_call(itv, cmd, args, data);
-
- /* Allow a single retry, probably already too late though.
- If there is no free mailbox then that is usually an indication
- of a more serious problem. */
- return (res == -EBUSY) ? ivtv_api_call(itv, cmd, args, data) : res;
-}
-
-int ivtv_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA])
-{
- return ivtv_api(priv, cmd, in, data);
-}
-
-int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...)
-{
- va_list ap;
- int i;
-
- va_start(ap, args);
- for (i = 0; i < args; i++) {
- data[i] = va_arg(ap, u32);
- }
- va_end(ap);
- return ivtv_api(itv, cmd, args, data);
-}
-
-int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- va_list ap;
- int i;
-
- va_start(ap, args);
- for (i = 0; i < args; i++) {
- data[i] = va_arg(ap, u32);
- }
- va_end(ap);
- return ivtv_api(itv, cmd, args, data);
-}
-
-/* This one is for stuff that can't sleep.. irq handlers, etc.. */
-void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb,
- int argc, u32 data[])
-{
- volatile u32 __iomem *p = mbdata->mbox[mb].data;
- int i;
- for (i = 0; i < argc; i++, p++)
- data[i] = readl(p);
-}
-
-/* Wipe api cache */
-void ivtv_mailbox_cache_invalidate(struct ivtv *itv)
-{
- int i;
- for (i = 0; i < 256; i++)
- itv->api_cache[i].last_jiffies = 0;
-}
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.h b/drivers/media/video/ivtv/ivtv-mailbox.h
deleted file mode 100644
index 2c834d2cb56..00000000000
--- a/drivers/media/video/ivtv/ivtv-mailbox.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- mailbox functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_MAILBOX_H
-#define IVTV_MAILBOX_H
-
-#define IVTV_MBOX_DMA_END 8
-#define IVTV_MBOX_DMA 9
-
-void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb,
- int argc, u32 data[]);
-int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]);
-int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...);
-int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...);
-int ivtv_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]);
-void ivtv_mailbox_cache_invalidate(struct ivtv *itv);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c
deleted file mode 100644
index 7fde36e6d22..00000000000
--- a/drivers/media/video/ivtv/ivtv-queue.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- buffer queues.
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-queue.h"
-
-int ivtv_buf_copy_from_user(struct ivtv_stream *s, struct ivtv_buffer *buf, const char __user *src, int copybytes)
-{
- if (s->buf_size - buf->bytesused < copybytes)
- copybytes = s->buf_size - buf->bytesused;
- if (copy_from_user(buf->buf + buf->bytesused, src, copybytes)) {
- return -EFAULT;
- }
- buf->bytesused += copybytes;
- return copybytes;
-}
-
-void ivtv_buf_swap(struct ivtv_buffer *buf)
-{
- int i;
-
- for (i = 0; i < buf->bytesused; i += 4)
- swab32s((u32 *)(buf->buf + i));
-}
-
-void ivtv_queue_init(struct ivtv_queue *q)
-{
- INIT_LIST_HEAD(&q->list);
- q->buffers = 0;
- q->length = 0;
- q->bytesused = 0;
-}
-
-void ivtv_enqueue(struct ivtv_stream *s, struct ivtv_buffer *buf, struct ivtv_queue *q)
-{
- unsigned long flags;
-
- /* clear the buffer if it is going to be enqueued to the free queue */
- if (q == &s->q_free) {
- buf->bytesused = 0;
- buf->readpos = 0;
- buf->b_flags = 0;
- buf->dma_xfer_cnt = 0;
- }
- spin_lock_irqsave(&s->qlock, flags);
- list_add_tail(&buf->list, &q->list);
- q->buffers++;
- q->length += s->buf_size;
- q->bytesused += buf->bytesused - buf->readpos;
- spin_unlock_irqrestore(&s->qlock, flags);
-}
-
-struct ivtv_buffer *ivtv_dequeue(struct ivtv_stream *s, struct ivtv_queue *q)
-{
- struct ivtv_buffer *buf = NULL;
- unsigned long flags;
-
- spin_lock_irqsave(&s->qlock, flags);
- if (!list_empty(&q->list)) {
- buf = list_entry(q->list.next, struct ivtv_buffer, list);
- list_del_init(q->list.next);
- q->buffers--;
- q->length -= s->buf_size;
- q->bytesused -= buf->bytesused - buf->readpos;
- }
- spin_unlock_irqrestore(&s->qlock, flags);
- return buf;
-}
-
-static void ivtv_queue_move_buf(struct ivtv_stream *s, struct ivtv_queue *from,
- struct ivtv_queue *to, int clear)
-{
- struct ivtv_buffer *buf = list_entry(from->list.next, struct ivtv_buffer, list);
-
- list_move_tail(from->list.next, &to->list);
- from->buffers--;
- from->length -= s->buf_size;
- from->bytesused -= buf->bytesused - buf->readpos;
- /* special handling for q_free */
- if (clear)
- buf->bytesused = buf->readpos = buf->b_flags = buf->dma_xfer_cnt = 0;
- to->buffers++;
- to->length += s->buf_size;
- to->bytesused += buf->bytesused - buf->readpos;
-}
-
-/* Move 'needed_bytes' worth of buffers from queue 'from' into queue 'to'.
- If 'needed_bytes' == 0, then move all buffers from 'from' into 'to'.
- If 'steal' != NULL, then buffers may also taken from that queue if
- needed, but only if 'from' is the free queue.
-
- The buffer is automatically cleared if it goes to the free queue. It is
- also cleared if buffers need to be taken from the 'steal' queue and
- the 'from' queue is the free queue.
-
- When 'from' is q_free, then needed_bytes is compared to the total
- available buffer length, otherwise needed_bytes is compared to the
- bytesused value. For the 'steal' queue the total available buffer
- length is always used.
-
- -ENOMEM is returned if the buffers could not be obtained, 0 if all
- buffers where obtained from the 'from' list and if non-zero then
- the number of stolen buffers is returned. */
-int ivtv_queue_move(struct ivtv_stream *s, struct ivtv_queue *from, struct ivtv_queue *steal,
- struct ivtv_queue *to, int needed_bytes)
-{
- unsigned long flags;
- int rc = 0;
- int from_free = from == &s->q_free;
- int to_free = to == &s->q_free;
- int bytes_available, bytes_steal;
-
- spin_lock_irqsave(&s->qlock, flags);
- if (needed_bytes == 0) {
- from_free = 1;
- needed_bytes = from->length;
- }
-
- bytes_available = from_free ? from->length : from->bytesused;
- bytes_steal = (from_free && steal) ? steal->length : 0;
-
- if (bytes_available + bytes_steal < needed_bytes) {
- spin_unlock_irqrestore(&s->qlock, flags);
- return -ENOMEM;
- }
- while (bytes_available < needed_bytes) {
- struct ivtv_buffer *buf = list_entry(steal->list.prev, struct ivtv_buffer, list);
- u16 dma_xfer_cnt = buf->dma_xfer_cnt;
-
- /* move buffers from the tail of the 'steal' queue to the tail of the
- 'from' queue. Always copy all the buffers with the same dma_xfer_cnt
- value, this ensures that you do not end up with partial frame data
- if one frame is stored in multiple buffers. */
- while (dma_xfer_cnt == buf->dma_xfer_cnt) {
- list_move_tail(steal->list.prev, &from->list);
- rc++;
- steal->buffers--;
- steal->length -= s->buf_size;
- steal->bytesused -= buf->bytesused - buf->readpos;
- buf->bytesused = buf->readpos = buf->b_flags = buf->dma_xfer_cnt = 0;
- from->buffers++;
- from->length += s->buf_size;
- bytes_available += s->buf_size;
- if (list_empty(&steal->list))
- break;
- buf = list_entry(steal->list.prev, struct ivtv_buffer, list);
- }
- }
- if (from_free) {
- u32 old_length = to->length;
-
- while (to->length - old_length < needed_bytes) {
- ivtv_queue_move_buf(s, from, to, 1);
- }
- }
- else {
- u32 old_bytesused = to->bytesused;
-
- while (to->bytesused - old_bytesused < needed_bytes) {
- ivtv_queue_move_buf(s, from, to, to_free);
- }
- }
- spin_unlock_irqrestore(&s->qlock, flags);
- return rc;
-}
-
-void ivtv_flush_queues(struct ivtv_stream *s)
-{
- ivtv_queue_move(s, &s->q_io, NULL, &s->q_free, 0);
- ivtv_queue_move(s, &s->q_full, NULL, &s->q_free, 0);
- ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
- ivtv_queue_move(s, &s->q_predma, NULL, &s->q_free, 0);
-}
-
-int ivtv_stream_alloc(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
- int SGsize = sizeof(struct ivtv_sg_host_element) * s->buffers;
- int i;
-
- if (s->buffers == 0)
- return 0;
-
- IVTV_DEBUG_INFO("Allocate %s%s stream: %d x %d buffers (%dkB total)\n",
- s->dma != PCI_DMA_NONE ? "DMA " : "",
- s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
-
- s->sg_pending = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
- if (s->sg_pending == NULL) {
- IVTV_ERR("Could not allocate sg_pending for %s stream\n", s->name);
- return -ENOMEM;
- }
- s->sg_pending_size = 0;
-
- s->sg_processing = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
- if (s->sg_processing == NULL) {
- IVTV_ERR("Could not allocate sg_processing for %s stream\n", s->name);
- kfree(s->sg_pending);
- s->sg_pending = NULL;
- return -ENOMEM;
- }
- s->sg_processing_size = 0;
-
- s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element),
- GFP_KERNEL|__GFP_NOWARN);
- if (s->sg_dma == NULL) {
- IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name);
- kfree(s->sg_pending);
- s->sg_pending = NULL;
- kfree(s->sg_processing);
- s->sg_processing = NULL;
- return -ENOMEM;
- }
- if (ivtv_might_use_dma(s)) {
- s->sg_handle = pci_map_single(itv->pdev, s->sg_dma,
- sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
- ivtv_stream_sync_for_cpu(s);
- }
-
- /* allocate stream buffers. Initially all buffers are in q_free. */
- for (i = 0; i < s->buffers; i++) {
- struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer),
- GFP_KERNEL|__GFP_NOWARN);
-
- if (buf == NULL)
- break;
- buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL|__GFP_NOWARN);
- if (buf->buf == NULL) {
- kfree(buf);
- break;
- }
- INIT_LIST_HEAD(&buf->list);
- if (ivtv_might_use_dma(s)) {
- buf->dma_handle = pci_map_single(s->itv->pdev,
- buf->buf, s->buf_size + 256, s->dma);
- ivtv_buf_sync_for_cpu(s, buf);
- }
- ivtv_enqueue(s, buf, &s->q_free);
- }
- if (i == s->buffers)
- return 0;
- IVTV_ERR("Couldn't allocate buffers for %s stream\n", s->name);
- ivtv_stream_free(s);
- return -ENOMEM;
-}
-
-void ivtv_stream_free(struct ivtv_stream *s)
-{
- struct ivtv_buffer *buf;
-
- /* move all buffers to q_free */
- ivtv_flush_queues(s);
-
- /* empty q_free */
- while ((buf = ivtv_dequeue(s, &s->q_free))) {
- if (ivtv_might_use_dma(s))
- pci_unmap_single(s->itv->pdev, buf->dma_handle,
- s->buf_size + 256, s->dma);
- kfree(buf->buf);
- kfree(buf);
- }
-
- /* Free SG Array/Lists */
- if (s->sg_dma != NULL) {
- if (s->sg_handle != IVTV_DMA_UNMAPPED) {
- pci_unmap_single(s->itv->pdev, s->sg_handle,
- sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
- s->sg_handle = IVTV_DMA_UNMAPPED;
- }
- kfree(s->sg_pending);
- kfree(s->sg_processing);
- kfree(s->sg_dma);
- s->sg_pending = NULL;
- s->sg_processing = NULL;
- s->sg_dma = NULL;
- s->sg_pending_size = 0;
- s->sg_processing_size = 0;
- }
-}
diff --git a/drivers/media/video/ivtv/ivtv-queue.h b/drivers/media/video/ivtv/ivtv-queue.h
deleted file mode 100644
index 91233839a26..00000000000
--- a/drivers/media/video/ivtv/ivtv-queue.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- buffer queues.
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_QUEUE_H
-#define IVTV_QUEUE_H
-
-#define IVTV_DMA_UNMAPPED ((u32) -1)
-#define SLICED_VBI_PIO 0
-
-/* ivtv_buffer utility functions */
-
-static inline int ivtv_might_use_pio(struct ivtv_stream *s)
-{
- return s->dma == PCI_DMA_NONE || (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI);
-}
-
-static inline int ivtv_use_pio(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
-
- return s->dma == PCI_DMA_NONE ||
- (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set);
-}
-
-static inline int ivtv_might_use_dma(struct ivtv_stream *s)
-{
- return s->dma != PCI_DMA_NONE;
-}
-
-static inline int ivtv_use_dma(struct ivtv_stream *s)
-{
- return !ivtv_use_pio(s);
-}
-
-static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf)
-{
- if (ivtv_use_dma(s))
- pci_dma_sync_single_for_cpu(s->itv->pdev, buf->dma_handle,
- s->buf_size + 256, s->dma);
-}
-
-static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf)
-{
- if (ivtv_use_dma(s))
- pci_dma_sync_single_for_device(s->itv->pdev, buf->dma_handle,
- s->buf_size + 256, s->dma);
-}
-
-int ivtv_buf_copy_from_user(struct ivtv_stream *s, struct ivtv_buffer *buf, const char __user *src, int copybytes);
-void ivtv_buf_swap(struct ivtv_buffer *buf);
-
-/* ivtv_queue utility functions */
-void ivtv_queue_init(struct ivtv_queue *q);
-void ivtv_enqueue(struct ivtv_stream *s, struct ivtv_buffer *buf, struct ivtv_queue *q);
-struct ivtv_buffer *ivtv_dequeue(struct ivtv_stream *s, struct ivtv_queue *q);
-int ivtv_queue_move(struct ivtv_stream *s, struct ivtv_queue *from, struct ivtv_queue *steal,
- struct ivtv_queue *to, int needed_bytes);
-void ivtv_flush_queues(struct ivtv_stream *s);
-
-/* ivtv_stream utility functions */
-int ivtv_stream_alloc(struct ivtv_stream *s);
-void ivtv_stream_free(struct ivtv_stream *s);
-
-static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s)
-{
- if (ivtv_use_dma(s))
- pci_dma_sync_single_for_cpu(s->itv->pdev, s->sg_handle,
- sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
-}
-
-static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s)
-{
- if (ivtv_use_dma(s))
- pci_dma_sync_single_for_device(s->itv->pdev, s->sg_handle,
- sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
-}
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-routing.c b/drivers/media/video/ivtv/ivtv-routing.c
deleted file mode 100644
index 8898c569a1c..00000000000
--- a/drivers/media/video/ivtv/ivtv-routing.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- Audio/video-routing-related ivtv functions.
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-i2c.h"
-#include "ivtv-cards.h"
-#include "ivtv-gpio.h"
-#include "ivtv-routing.h"
-
-#include <media/msp3400.h>
-#include <media/m52790.h>
-#include <media/upd64031a.h>
-#include <media/upd64083.h>
-
-/* Selects the audio input and output according to the current
- settings. */
-void ivtv_audio_set_io(struct ivtv *itv)
-{
- const struct ivtv_card_audio_input *in;
- u32 input, output = 0;
-
- /* Determine which input to use */
- if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags))
- in = &itv->card->radio_input;
- else
- in = &itv->card->audio_inputs[itv->audio_input];
-
- /* handle muxer chips */
- input = in->muxer_input;
- if (itv->card->hw_muxer & IVTV_HW_M52790)
- output = M52790_OUT_STEREO;
- v4l2_subdev_call(itv->sd_muxer, audio, s_routing,
- input, output, 0);
-
- input = in->audio_input;
- output = 0;
- if (itv->card->hw_audio & IVTV_HW_MSP34XX)
- output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
- ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing,
- input, output, 0);
-}
-
-/* Selects the video input and output according to the current
- settings. */
-void ivtv_video_set_io(struct ivtv *itv)
-{
- int inp = itv->active_input;
- u32 input;
- u32 type;
-
- v4l2_subdev_call(itv->sd_video, video, s_routing,
- itv->card->video_inputs[inp].video_input, 0, 0);
-
- type = itv->card->video_inputs[inp].video_type;
-
- if (type == IVTV_CARD_INPUT_VID_TUNER) {
- input = 0; /* Tuner */
- } else if (type < IVTV_CARD_INPUT_COMPOSITE1) {
- input = 2; /* S-Video */
- } else {
- input = 1; /* Composite */
- }
-
- if (itv->card->hw_video & IVTV_HW_GPIO)
- ivtv_call_hw(itv, IVTV_HW_GPIO, video, s_routing,
- input, 0, 0);
-
- if (itv->card->hw_video & IVTV_HW_UPD64031A) {
- if (type == IVTV_CARD_INPUT_VID_TUNER ||
- type >= IVTV_CARD_INPUT_COMPOSITE1) {
- /* Composite: GR on, connect to 3DYCS */
- input = UPD64031A_GR_ON | UPD64031A_3DYCS_COMPOSITE;
- } else {
- /* S-Video: GR bypassed, turn it off */
- input = UPD64031A_GR_OFF | UPD64031A_3DYCS_DISABLE;
- }
- input |= itv->card->gr_config;
-
- ivtv_call_hw(itv, IVTV_HW_UPD64031A, video, s_routing,
- input, 0, 0);
- }
-
- if (itv->card->hw_video & IVTV_HW_UPD6408X) {
- input = UPD64083_YCS_MODE;
- if (type > IVTV_CARD_INPUT_VID_TUNER &&
- type < IVTV_CARD_INPUT_COMPOSITE1) {
- /* S-Video uses YCNR mode and internal Y-ADC, the
- upd64031a is not used. */
- input |= UPD64083_YCNR_MODE;
- }
- else if (itv->card->hw_video & IVTV_HW_UPD64031A) {
- /* Use upd64031a output for tuner and
- composite(CX23416GYC only) inputs */
- if (type == IVTV_CARD_INPUT_VID_TUNER ||
- itv->card->type == IVTV_CARD_CX23416GYC) {
- input |= UPD64083_EXT_Y_ADC;
- }
- }
- ivtv_call_hw(itv, IVTV_HW_UPD6408X, video, s_routing,
- input, 0, 0);
- }
-}
diff --git a/drivers/media/video/ivtv/ivtv-routing.h b/drivers/media/video/ivtv/ivtv-routing.h
deleted file mode 100644
index c72a9731ca0..00000000000
--- a/drivers/media/video/ivtv/ivtv-routing.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- Audio/video-routing-related ivtv functions.
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_ROUTING_H
-#define IVTV_ROUTING_H
-
-void ivtv_audio_set_io(struct ivtv *itv);
-void ivtv_video_set_io(struct ivtv *itv);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
deleted file mode 100644
index 87990c5f091..00000000000
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ /dev/null
@@ -1,1018 +0,0 @@
-/*
- init/start/stop/exit stream functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* License: GPL
- * Author: Kevin Thayer <nufan_wfk at yahoo dot com>
- *
- * This file will hold API related functions, both internal (firmware api)
- * and external (v4l2, etc)
- *
- * -----
- * MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com>
- * and Takeru KOMORIYA<komoriya@paken.org>
- *
- * AVerMedia M179 GPIO info by Chris Pinkham <cpinkham@bc2va.org>
- * using information provided by Jiun-Kuei Jung @ AVerMedia.
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-fileops.h"
-#include "ivtv-queue.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-ioctl.h"
-#include "ivtv-irq.h"
-#include "ivtv-yuv.h"
-#include "ivtv-cards.h"
-#include "ivtv-streams.h"
-#include "ivtv-firmware.h"
-#include <media/v4l2-event.h>
-
-static const struct v4l2_file_operations ivtv_v4l2_enc_fops = {
- .owner = THIS_MODULE,
- .read = ivtv_v4l2_read,
- .write = ivtv_v4l2_write,
- .open = ivtv_v4l2_open,
- .unlocked_ioctl = video_ioctl2,
- .release = ivtv_v4l2_close,
- .poll = ivtv_v4l2_enc_poll,
-};
-
-static const struct v4l2_file_operations ivtv_v4l2_dec_fops = {
- .owner = THIS_MODULE,
- .read = ivtv_v4l2_read,
- .write = ivtv_v4l2_write,
- .open = ivtv_v4l2_open,
- .unlocked_ioctl = video_ioctl2,
- .release = ivtv_v4l2_close,
- .poll = ivtv_v4l2_dec_poll,
-};
-
-#define IVTV_V4L2_DEC_MPG_OFFSET 16 /* offset from 0 to register decoder mpg v4l2 minors on */
-#define IVTV_V4L2_ENC_PCM_OFFSET 24 /* offset from 0 to register pcm v4l2 minors on */
-#define IVTV_V4L2_ENC_YUV_OFFSET 32 /* offset from 0 to register yuv v4l2 minors on */
-#define IVTV_V4L2_DEC_YUV_OFFSET 48 /* offset from 0 to register decoder yuv v4l2 minors on */
-#define IVTV_V4L2_DEC_VBI_OFFSET 8 /* offset from 0 to register decoder vbi input v4l2 minors on */
-#define IVTV_V4L2_DEC_VOUT_OFFSET 16 /* offset from 0 to register vbi output v4l2 minors on */
-
-static struct {
- const char *name;
- int vfl_type;
- int num_offset;
- int dma, pio;
- enum v4l2_buf_type buf_type;
- u32 v4l2_caps;
- const struct v4l2_file_operations *fops;
-} ivtv_stream_info[] = {
- { /* IVTV_ENC_STREAM_TYPE_MPG */
- "encoder MPG",
- VFL_TYPE_GRABBER, 0,
- PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
- V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
- &ivtv_v4l2_enc_fops
- },
- { /* IVTV_ENC_STREAM_TYPE_YUV */
- "encoder YUV",
- VFL_TYPE_GRABBER, IVTV_V4L2_ENC_YUV_OFFSET,
- PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
- V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
- &ivtv_v4l2_enc_fops
- },
- { /* IVTV_ENC_STREAM_TYPE_VBI */
- "encoder VBI",
- VFL_TYPE_VBI, 0,
- PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VBI_CAPTURE,
- V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_TUNER |
- V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
- &ivtv_v4l2_enc_fops
- },
- { /* IVTV_ENC_STREAM_TYPE_PCM */
- "encoder PCM",
- VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET,
- PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_PRIVATE,
- V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
- &ivtv_v4l2_enc_fops
- },
- { /* IVTV_ENC_STREAM_TYPE_RAD */
- "encoder radio",
- VFL_TYPE_RADIO, 0,
- PCI_DMA_NONE, 1, V4L2_BUF_TYPE_PRIVATE,
- V4L2_CAP_RADIO | V4L2_CAP_TUNER,
- &ivtv_v4l2_enc_fops
- },
- { /* IVTV_DEC_STREAM_TYPE_MPG */
- "decoder MPG",
- VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET,
- PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT,
- V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
- &ivtv_v4l2_dec_fops
- },
- { /* IVTV_DEC_STREAM_TYPE_VBI */
- "decoder VBI",
- VFL_TYPE_VBI, IVTV_V4L2_DEC_VBI_OFFSET,
- PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_CAPTURE,
- V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_READWRITE,
- &ivtv_v4l2_enc_fops
- },
- { /* IVTV_DEC_STREAM_TYPE_VOUT */
- "decoder VOUT",
- VFL_TYPE_VBI, IVTV_V4L2_DEC_VOUT_OFFSET,
- PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_OUTPUT,
- V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
- &ivtv_v4l2_dec_fops
- },
- { /* IVTV_DEC_STREAM_TYPE_YUV */
- "decoder YUV",
- VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET,
- PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT,
- V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
- &ivtv_v4l2_dec_fops
- }
-};
-
-static void ivtv_stream_init(struct ivtv *itv, int type)
-{
- struct ivtv_stream *s = &itv->streams[type];
- struct video_device *vdev = s->vdev;
-
- /* we need to keep vdev, so restore it afterwards */
- memset(s, 0, sizeof(*s));
- s->vdev = vdev;
-
- /* initialize ivtv_stream fields */
- s->itv = itv;
- s->type = type;
- s->name = ivtv_stream_info[type].name;
- s->caps = ivtv_stream_info[type].v4l2_caps;
-
- if (ivtv_stream_info[type].pio)
- s->dma = PCI_DMA_NONE;
- else
- s->dma = ivtv_stream_info[type].dma;
- s->buf_size = itv->stream_buf_size[type];
- if (s->buf_size)
- s->buffers = (itv->options.kilobytes[type] * 1024 + s->buf_size - 1) / s->buf_size;
- spin_lock_init(&s->qlock);
- init_waitqueue_head(&s->waitq);
- s->sg_handle = IVTV_DMA_UNMAPPED;
- ivtv_queue_init(&s->q_free);
- ivtv_queue_init(&s->q_full);
- ivtv_queue_init(&s->q_dma);
- ivtv_queue_init(&s->q_predma);
- ivtv_queue_init(&s->q_io);
-}
-
-static int ivtv_prep_dev(struct ivtv *itv, int type)
-{
- struct ivtv_stream *s = &itv->streams[type];
- int num_offset = ivtv_stream_info[type].num_offset;
- int num = itv->instance + ivtv_first_minor + num_offset;
-
- /* These four fields are always initialized. If vdev == NULL, then
- this stream is not in use. In that case no other fields but these
- four can be used. */
- s->vdev = NULL;
- s->itv = itv;
- s->type = type;
- s->name = ivtv_stream_info[type].name;
-
- /* Check whether the radio is supported */
- if (type == IVTV_ENC_STREAM_TYPE_RAD && !(itv->v4l2_cap & V4L2_CAP_RADIO))
- return 0;
- if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return 0;
-
- /* User explicitly selected 0 buffers for these streams, so don't
- create them. */
- if (ivtv_stream_info[type].dma != PCI_DMA_NONE &&
- itv->options.kilobytes[type] == 0) {
- IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name);
- return 0;
- }
-
- ivtv_stream_init(itv, type);
-
- /* allocate and initialize the v4l2 video device structure */
- s->vdev = video_device_alloc();
- if (s->vdev == NULL) {
- IVTV_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name);
- return -ENOMEM;
- }
-
- snprintf(s->vdev->name, sizeof(s->vdev->name), "%s %s",
- itv->v4l2_dev.name, s->name);
-
- s->vdev->num = num;
- s->vdev->v4l2_dev = &itv->v4l2_dev;
- s->vdev->fops = ivtv_stream_info[type].fops;
- s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler;
- s->vdev->release = video_device_release;
- s->vdev->tvnorms = V4L2_STD_ALL;
- s->vdev->lock = &itv->serialize_lock;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &s->vdev->flags);
- set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags);
- ivtv_set_funcs(s->vdev);
- return 0;
-}
-
-/* Initialize v4l2 variables and prepare v4l2 devices */
-int ivtv_streams_setup(struct ivtv *itv)
-{
- int type;
-
- /* Setup V4L2 Devices */
- for (type = 0; type < IVTV_MAX_STREAMS; type++) {
- /* Prepare device */
- if (ivtv_prep_dev(itv, type))
- break;
-
- if (itv->streams[type].vdev == NULL)
- continue;
-
- /* Allocate Stream */
- if (ivtv_stream_alloc(&itv->streams[type]))
- break;
- }
- if (type == IVTV_MAX_STREAMS)
- return 0;
-
- /* One or more streams could not be initialized. Clean 'em all up. */
- ivtv_streams_cleanup(itv, 0);
- return -ENOMEM;
-}
-
-static int ivtv_reg_dev(struct ivtv *itv, int type)
-{
- struct ivtv_stream *s = &itv->streams[type];
- int vfl_type = ivtv_stream_info[type].vfl_type;
- const char *name;
- int num;
-
- if (s->vdev == NULL)
- return 0;
-
- num = s->vdev->num;
- /* card number + user defined offset + device offset */
- if (type != IVTV_ENC_STREAM_TYPE_MPG) {
- struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG];
-
- if (s_mpg->vdev)
- num = s_mpg->vdev->num + ivtv_stream_info[type].num_offset;
- }
- video_set_drvdata(s->vdev, s);
-
- /* Register device. First try the desired minor, then any free one. */
- if (video_register_device_no_warn(s->vdev, vfl_type, num)) {
- IVTV_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
- s->name, num);
- video_device_release(s->vdev);
- s->vdev = NULL;
- return -ENOMEM;
- }
- name = video_device_node_name(s->vdev);
-
- switch (vfl_type) {
- case VFL_TYPE_GRABBER:
- IVTV_INFO("Registered device %s for %s (%d kB)\n",
- name, s->name, itv->options.kilobytes[type]);
- break;
- case VFL_TYPE_RADIO:
- IVTV_INFO("Registered device %s for %s\n",
- name, s->name);
- break;
- case VFL_TYPE_VBI:
- if (itv->options.kilobytes[type])
- IVTV_INFO("Registered device %s for %s (%d kB)\n",
- name, s->name, itv->options.kilobytes[type]);
- else
- IVTV_INFO("Registered device %s for %s\n",
- name, s->name);
- break;
- }
- return 0;
-}
-
-/* Register v4l2 devices */
-int ivtv_streams_register(struct ivtv *itv)
-{
- int type;
- int err = 0;
-
- /* Register V4L2 devices */
- for (type = 0; type < IVTV_MAX_STREAMS; type++)
- err |= ivtv_reg_dev(itv, type);
-
- if (err == 0)
- return 0;
-
- /* One or more streams could not be initialized. Clean 'em all up. */
- ivtv_streams_cleanup(itv, 1);
- return -ENOMEM;
-}
-
-/* Unregister v4l2 devices */
-void ivtv_streams_cleanup(struct ivtv *itv, int unregister)
-{
- int type;
-
- /* Teardown all streams */
- for (type = 0; type < IVTV_MAX_STREAMS; type++) {
- struct video_device *vdev = itv->streams[type].vdev;
-
- itv->streams[type].vdev = NULL;
- if (vdev == NULL)
- continue;
-
- ivtv_stream_free(&itv->streams[type]);
- /* Unregister or release device */
- if (unregister)
- video_unregister_device(vdev);
- else
- video_device_release(vdev);
- }
-}
-
-static void ivtv_vbi_setup(struct ivtv *itv)
-{
- int raw = ivtv_raw_vbi(itv);
- u32 data[CX2341X_MBOX_MAX_DATA];
- int lines;
- int i;
-
- /* Reset VBI */
- ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, 0xffff , 0, 0, 0, 0);
-
- /* setup VBI registers */
- if (raw)
- v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &itv->vbi.in.fmt.vbi);
- else
- v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, &itv->vbi.in.fmt.sliced);
-
- /* determine number of lines and total number of VBI bytes.
- A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1
- The '- 1' byte is probably an unused U or V byte. Or something...
- A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal
- header, 42 data bytes + checksum (to be confirmed) */
- if (raw) {
- lines = itv->vbi.count * 2;
- } else {
- lines = itv->is_60hz ? 24 : 38;
- if (itv->is_60hz && (itv->hw_flags & IVTV_HW_CX25840))
- lines += 2;
- }
-
- itv->vbi.enc_size = lines * (raw ? itv->vbi.raw_size : itv->vbi.sliced_size);
-
- /* Note: sliced vs raw flag doesn't seem to have any effect
- TODO: check mode (0x02) value with older ivtv versions. */
- data[0] = raw | 0x02 | (0xbd << 8);
-
- /* Every X number of frames a VBI interrupt arrives (frames as in 25 or 30 fps) */
- data[1] = 1;
- /* The VBI frames are stored in a ringbuffer with this size (with a VBI frame as unit) */
- data[2] = raw ? 4 : 4 * (itv->vbi.raw_size / itv->vbi.enc_size);
- /* The start/stop codes determine which VBI lines end up in the raw VBI data area.
- The codes are from table 24 in the saa7115 datasheet. Each raw/sliced/video line
- is framed with codes FF0000XX where XX is the SAV/EAV (Start/End of Active Video)
- code. These values for raw VBI are obtained from a driver disassembly. The sliced
- start/stop codes was deduced from this, but they do not appear in the driver.
- Other code pairs that I found are: 0x250E6249/0x13545454 and 0x25256262/0x38137F54.
- However, I have no idea what these values are for. */
- if (itv->hw_flags & IVTV_HW_CX25840) {
- /* Setup VBI for the cx25840 digitizer */
- if (raw) {
- data[3] = 0x20602060;
- data[4] = 0x30703070;
- } else {
- data[3] = 0xB0F0B0F0;
- data[4] = 0xA0E0A0E0;
- }
- /* Lines per frame */
- data[5] = lines;
- /* bytes per line */
- data[6] = (raw ? itv->vbi.raw_size : itv->vbi.sliced_size);
- } else {
- /* Setup VBI for the saa7115 digitizer */
- if (raw) {
- data[3] = 0x25256262;
- data[4] = 0x387F7F7F;
- } else {
- data[3] = 0xABABECEC;
- data[4] = 0xB6F1F1F1;
- }
- /* Lines per frame */
- data[5] = lines;
- /* bytes per line */
- data[6] = itv->vbi.enc_size / lines;
- }
-
- IVTV_DEBUG_INFO(
- "Setup VBI API header 0x%08x pkts %d buffs %d ln %d sz %d\n",
- data[0], data[1], data[2], data[5], data[6]);
-
- ivtv_api(itv, CX2341X_ENC_SET_VBI_CONFIG, 7, data);
-
- /* returns the VBI encoder memory area. */
- itv->vbi.enc_start = data[2];
- itv->vbi.fpi = data[0];
- if (!itv->vbi.fpi)
- itv->vbi.fpi = 1;
-
- IVTV_DEBUG_INFO("Setup VBI start 0x%08x frames %d fpi %d\n",
- itv->vbi.enc_start, data[1], itv->vbi.fpi);
-
- /* select VBI lines.
- Note that the sliced argument seems to have no effect. */
- for (i = 2; i <= 24; i++) {
- int valid;
-
- if (itv->is_60hz) {
- valid = i >= 10 && i < 22;
- } else {
- valid = i >= 6 && i < 24;
- }
- ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, i - 1,
- valid, 0 , 0, 0);
- ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, (i - 1) | 0x80000000,
- valid, 0, 0, 0);
- }
-
- /* Remaining VBI questions:
- - Is it possible to select particular VBI lines only for inclusion in the MPEG
- stream? Currently you can only get the first X lines.
- - Is mixed raw and sliced VBI possible?
- - What's the meaning of the raw/sliced flag?
- - What's the meaning of params 2, 3 & 4 of the Select VBI command? */
-}
-
-int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct ivtv *itv = s->itv;
- int captype = 0, subtype = 0;
- int enable_passthrough = 0;
-
- if (s->vdev == NULL)
- return -EINVAL;
-
- IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name);
-
- switch (s->type) {
- case IVTV_ENC_STREAM_TYPE_MPG:
- captype = 0;
- subtype = 3;
-
- /* Stop Passthrough */
- if (itv->output_mode == OUT_PASSTHROUGH) {
- ivtv_passthrough_mode(itv, 0);
- enable_passthrough = 1;
- }
- itv->mpg_data_received = itv->vbi_data_inserted = 0;
- itv->dualwatch_jiffies = jiffies;
- itv->dualwatch_stereo_mode = v4l2_ctrl_g_ctrl(itv->cxhdl.audio_mode);
- itv->search_pack_header = 0;
- break;
-
- case IVTV_ENC_STREAM_TYPE_YUV:
- if (itv->output_mode == OUT_PASSTHROUGH) {
- captype = 2;
- subtype = 11; /* video+audio+decoder */
- break;
- }
- captype = 1;
- subtype = 1;
- break;
- case IVTV_ENC_STREAM_TYPE_PCM:
- captype = 1;
- subtype = 2;
- break;
- case IVTV_ENC_STREAM_TYPE_VBI:
- captype = 1;
- subtype = 4;
-
- itv->vbi.frame = 0;
- itv->vbi.inserted_frame = 0;
- memset(itv->vbi.sliced_mpeg_size,
- 0, sizeof(itv->vbi.sliced_mpeg_size));
- break;
- default:
- return -EINVAL;
- }
- s->subtype = subtype;
- s->buffers_stolen = 0;
-
- /* Clear Streamoff flags in case left from last capture */
- clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
-
- if (atomic_read(&itv->capturing) == 0) {
- int digitizer;
-
- /* Always use frame based mode. Experiments have demonstrated that byte
- stream based mode results in dropped frames and corruption. Not often,
- but occasionally. Many thanks go to Leonard Orb who spent a lot of
- effort and time trying to trace the cause of the drop outs. */
- /* 1 frame per DMA */
- /*ivtv_vapi(itv, CX2341X_ENC_SET_DMA_BLOCK_SIZE, 2, 128, 0); */
- ivtv_vapi(itv, CX2341X_ENC_SET_DMA_BLOCK_SIZE, 2, 1, 1);
-
- /* Stuff from Windows, we don't know what it is */
- ivtv_vapi(itv, CX2341X_ENC_SET_VERT_CROP_LINE, 1, 0);
- /* According to the docs, this should be correct. However, this is
- untested. I don't dare enable this without having tested it.
- Only very few old cards actually have this hardware combination.
- ivtv_vapi(itv, CX2341X_ENC_SET_VERT_CROP_LINE, 1,
- ((itv->hw_flags & IVTV_HW_SAA7114) && itv->is_60hz) ? 10001 : 0);
- */
- ivtv_vapi(itv, CX2341X_ENC_MISC, 2, 3, !itv->has_cx23415);
- ivtv_vapi(itv, CX2341X_ENC_MISC, 2, 8, 0);
- ivtv_vapi(itv, CX2341X_ENC_MISC, 2, 4, 1);
- ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12);
-
- /* assign placeholder */
- ivtv_vapi(itv, CX2341X_ENC_SET_PLACEHOLDER, 12,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-
- if (itv->card->hw_all & (IVTV_HW_SAA7115 | IVTV_HW_SAA717X))
- digitizer = 0xF1;
- else if (itv->card->hw_all & IVTV_HW_SAA7114)
- digitizer = 0xEF;
- else /* cx25840 */
- digitizer = 0x140;
-
- ivtv_vapi(itv, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, digitizer, digitizer);
-
- /* Setup VBI */
- if (itv->v4l2_cap & V4L2_CAP_VBI_CAPTURE) {
- ivtv_vbi_setup(itv);
- }
-
- /* assign program index info. Mask 7: select I/P/B, Num_req: 400 max */
- ivtv_vapi_result(itv, data, CX2341X_ENC_SET_PGM_INDEX_INFO, 2, 7, 400);
- itv->pgm_info_offset = data[0];
- itv->pgm_info_num = data[1];
- itv->pgm_info_write_idx = 0;
- itv->pgm_info_read_idx = 0;
-
- IVTV_DEBUG_INFO("PGM Index at 0x%08x with %d elements\n",
- itv->pgm_info_offset, itv->pgm_info_num);
-
- /* Setup API for Stream */
- cx2341x_handler_setup(&itv->cxhdl);
-
- /* mute if capturing radio */
- if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags))
- ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
- 1 | (v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8));
- }
-
- /* Vsync Setup */
- if (itv->has_cx23415 && !test_and_set_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) {
- /* event notification (on) */
- ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 1, IVTV_IRQ_ENC_VIM_RST, -1);
- ivtv_clear_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST);
- }
-
- if (atomic_read(&itv->capturing) == 0) {
- /* Clear all Pending Interrupts */
- ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
-
- clear_bit(IVTV_F_I_EOS, &itv->i_flags);
-
- cx2341x_handler_set_busy(&itv->cxhdl, 1);
-
- /* Initialize Digitizer for Capture */
- /* Avoid tinny audio problem - ensure audio clocks are going */
- v4l2_subdev_call(itv->sd_audio, audio, s_stream, 1);
- /* Avoid unpredictable PCI bus hang - disable video clocks */
- v4l2_subdev_call(itv->sd_video, video, s_stream, 0);
- ivtv_msleep_timeout(300, 0);
- ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
- v4l2_subdev_call(itv->sd_video, video, s_stream, 1);
- }
-
- /* begin_capture */
- if (ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, captype, subtype))
- {
- IVTV_DEBUG_WARN( "Error starting capture!\n");
- return -EINVAL;
- }
-
- /* Start Passthrough */
- if (enable_passthrough) {
- ivtv_passthrough_mode(itv, 1);
- }
-
- if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
- ivtv_clear_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP);
- else
- ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
-
- /* you're live! sit back and await interrupts :) */
- atomic_inc(&itv->capturing);
- return 0;
-}
-
-static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct ivtv *itv = s->itv;
- int datatype;
- u16 width;
- u16 height;
-
- if (s->vdev == NULL)
- return -EINVAL;
-
- IVTV_DEBUG_INFO("Setting some initial decoder settings\n");
-
- width = itv->cxhdl.width;
- height = itv->cxhdl.height;
-
- /* set audio mode to left/stereo for dual/stereo mode. */
- ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
-
- /* set number of internal decoder buffers */
- ivtv_vapi(itv, CX2341X_DEC_SET_DISPLAY_BUFFERS, 1, 0);
-
- /* prebuffering */
- ivtv_vapi(itv, CX2341X_DEC_SET_PREBUFFERING, 1, 1);
-
- /* extract from user packets */
- ivtv_vapi_result(itv, data, CX2341X_DEC_EXTRACT_VBI, 1, 1);
- itv->vbi.dec_start = data[0];
-
- IVTV_DEBUG_INFO("Decoder VBI RE-Insert start 0x%08x size 0x%08x\n",
- itv->vbi.dec_start, data[1]);
-
- /* set decoder source settings */
- /* Data type: 0 = mpeg from host,
- 1 = yuv from encoder,
- 2 = yuv_from_host */
- switch (s->type) {
- case IVTV_DEC_STREAM_TYPE_YUV:
- if (itv->output_mode == OUT_PASSTHROUGH) {
- datatype = 1;
- } else {
- /* Fake size to avoid switching video standard */
- datatype = 2;
- width = 720;
- height = itv->is_out_50hz ? 576 : 480;
- }
- IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype);
- break;
- case IVTV_DEC_STREAM_TYPE_MPG:
- default:
- datatype = 0;
- break;
- }
- if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype,
- width, height, itv->cxhdl.audio_properties)) {
- IVTV_DEBUG_WARN("Couldn't initialize decoder source\n");
- }
-
- /* Decoder sometimes dies here, so wait a moment */
- ivtv_msleep_timeout(10, 0);
-
- /* Known failure point for firmware, so check */
- return ivtv_firmware_check(itv, "ivtv_setup_v4l2_decode_stream");
-}
-
-int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset)
-{
- struct ivtv *itv = s->itv;
- int rc;
-
- if (s->vdev == NULL)
- return -EINVAL;
-
- if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags))
- return 0; /* already started */
-
- IVTV_DEBUG_INFO("Starting decode stream %s (gop_offset %d)\n", s->name, gop_offset);
-
- rc = ivtv_setup_v4l2_decode_stream(s);
- if (rc < 0) {
- clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
- return rc;
- }
-
- /* set dma size to 65536 bytes */
- ivtv_vapi(itv, CX2341X_DEC_SET_DMA_BLOCK_SIZE, 1, 65536);
-
- /* Clear Streamoff */
- clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
-
- /* Zero out decoder counters */
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[0]);
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[1]);
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[2]);
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[3]);
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[0]);
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[1]);
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[2]);
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[3]);
-
- /* turn on notification of dual/stereo mode change */
- ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 1, IVTV_IRQ_DEC_AUD_MODE_CHG, -1);
-
- /* start playback */
- ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, gop_offset, 0);
-
- /* Let things settle before we actually start */
- ivtv_msleep_timeout(10, 0);
-
- /* Clear the following Interrupt mask bits for decoding */
- ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_DECODE);
- IVTV_DEBUG_IRQ("IRQ Mask is now: 0x%08x\n", itv->irqmask);
-
- /* you're live! sit back and await interrupts :) */
- atomic_inc(&itv->decoding);
- return 0;
-}
-
-void ivtv_stop_all_captures(struct ivtv *itv)
-{
- int i;
-
- for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) {
- struct ivtv_stream *s = &itv->streams[i];
-
- if (s->vdev == NULL)
- continue;
- if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
- ivtv_stop_v4l2_encode_stream(s, 0);
- }
- }
-}
-
-int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
-{
- struct ivtv *itv = s->itv;
- DECLARE_WAITQUEUE(wait, current);
- int cap_type;
- int stopmode;
-
- if (s->vdev == NULL)
- return -EINVAL;
-
- /* This function assumes that you are allowed to stop the capture
- and that we are actually capturing */
-
- IVTV_DEBUG_INFO("Stop Capture\n");
-
- if (s->type == IVTV_DEC_STREAM_TYPE_VOUT)
- return 0;
- if (atomic_read(&itv->capturing) == 0)
- return 0;
-
- switch (s->type) {
- case IVTV_ENC_STREAM_TYPE_YUV:
- cap_type = 1;
- break;
- case IVTV_ENC_STREAM_TYPE_PCM:
- cap_type = 1;
- break;
- case IVTV_ENC_STREAM_TYPE_VBI:
- cap_type = 1;
- break;
- case IVTV_ENC_STREAM_TYPE_MPG:
- default:
- cap_type = 0;
- break;
- }
-
- /* Stop Capture Mode */
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG && gop_end) {
- stopmode = 0;
- } else {
- stopmode = 1;
- }
-
- /* end_capture */
- /* when: 0 = end of GOP 1 = NOW!, type: 0 = mpeg, subtype: 3 = video+audio */
- ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, s->subtype);
-
- if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) {
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG && gop_end) {
- /* only run these if we're shutting down the last cap */
- unsigned long duration;
- unsigned long then = jiffies;
-
- add_wait_queue(&itv->eos_waitq, &wait);
-
- set_current_state(TASK_INTERRUPTIBLE);
-
- /* wait 2s for EOS interrupt */
- while (!test_bit(IVTV_F_I_EOS, &itv->i_flags) &&
- time_before(jiffies,
- then + msecs_to_jiffies(2000))) {
- schedule_timeout(msecs_to_jiffies(10));
- }
-
- /* To convert jiffies to ms, we must multiply by 1000
- * and divide by HZ. To avoid runtime division, we
- * convert this to multiplication by 1000/HZ.
- * Since integer division truncates, we get the best
- * accuracy if we do a rounding calculation of the constant.
- * Think of the case where HZ is 1024.
- */
- duration = ((1000 + HZ / 2) / HZ) * (jiffies - then);
-
- if (!test_bit(IVTV_F_I_EOS, &itv->i_flags)) {
- IVTV_DEBUG_WARN("%s: EOS interrupt not received! stopping anyway.\n", s->name);
- IVTV_DEBUG_WARN("%s: waited %lu ms.\n", s->name, duration);
- } else {
- IVTV_DEBUG_INFO("%s: EOS took %lu ms to occur.\n", s->name, duration);
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&itv->eos_waitq, &wait);
- set_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
- }
-
- /* Handle any pending interrupts */
- ivtv_msleep_timeout(100, 0);
- }
-
- atomic_dec(&itv->capturing);
-
- /* Clear capture and no-read bits */
- clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
-
- if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
- ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP);
-
- if (atomic_read(&itv->capturing) > 0) {
- return 0;
- }
-
- cx2341x_handler_set_busy(&itv->cxhdl, 0);
-
- /* Set the following Interrupt mask bits for capture */
- ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
- del_timer(&itv->dma_timer);
-
- /* event notification (off) */
- if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) {
- /* type: 0 = refresh */
- /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */
- ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1);
- ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST);
- }
-
- /* Raw-passthrough is implied on start. Make sure it's stopped so
- the encoder will re-initialize when next started */
- ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, 1, 2, 7);
-
- wake_up(&s->waitq);
-
- return 0;
-}
-
-int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
-{
- static const struct v4l2_event ev = {
- .type = V4L2_EVENT_EOS,
- };
- struct ivtv *itv = s->itv;
-
- if (s->vdev == NULL)
- return -EINVAL;
-
- if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG)
- return -EINVAL;
-
- if (!test_bit(IVTV_F_S_STREAMING, &s->s_flags))
- return 0;
-
- IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", (unsigned long long)pts, flags);
-
- /* Stop Decoder */
- if (!(flags & V4L2_DEC_CMD_STOP_IMMEDIATELY) || pts) {
- u32 tmp = 0;
-
- /* Wait until the decoder is no longer running */
- if (pts) {
- ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3,
- 0, (u32)(pts & 0xffffffff), (u32)(pts >> 32));
- }
- while (1) {
- u32 data[CX2341X_MBOX_MAX_DATA];
- ivtv_vapi_result(itv, data, CX2341X_DEC_GET_XFER_INFO, 0);
- if (s->q_full.buffers + s->q_dma.buffers == 0) {
- if (tmp == data[3])
- break;
- tmp = data[3];
- }
- if (ivtv_msleep_timeout(100, 1))
- break;
- }
- }
- ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, flags & V4L2_DEC_CMD_STOP_TO_BLACK, 0, 0);
-
- /* turn off notification of dual/stereo mode change */
- ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_DEC_AUD_MODE_CHG, -1);
-
- ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_DECODE);
- del_timer(&itv->dma_timer);
-
- clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
- clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
- ivtv_flush_queues(s);
-
- /* decoder needs time to settle */
- ivtv_msleep_timeout(40, 0);
-
- /* decrement decoding */
- atomic_dec(&itv->decoding);
-
- set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags);
- wake_up(&itv->event_waitq);
- v4l2_event_queue(s->vdev, &ev);
-
- /* wake up wait queues */
- wake_up(&s->waitq);
-
- return 0;
-}
-
-int ivtv_passthrough_mode(struct ivtv *itv, int enable)
-{
- struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV];
- struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
-
- if (yuv_stream->vdev == NULL || dec_stream->vdev == NULL)
- return -EINVAL;
-
- IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n");
-
- /* Prevent others from starting/stopping streams while we
- initiate/terminate passthrough mode */
- if (enable) {
- if (itv->output_mode == OUT_PASSTHROUGH) {
- return 0;
- }
- if (ivtv_set_output_mode(itv, OUT_PASSTHROUGH) != OUT_PASSTHROUGH)
- return -EBUSY;
-
- /* Fully initialize stream, and then unflag init */
- set_bit(IVTV_F_S_PASSTHROUGH, &dec_stream->s_flags);
- set_bit(IVTV_F_S_STREAMING, &dec_stream->s_flags);
-
- /* Setup YUV Decoder */
- ivtv_setup_v4l2_decode_stream(dec_stream);
-
- /* Start Decoder */
- ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 1);
- atomic_inc(&itv->decoding);
-
- /* Setup capture if not already done */
- if (atomic_read(&itv->capturing) == 0) {
- cx2341x_handler_setup(&itv->cxhdl);
- cx2341x_handler_set_busy(&itv->cxhdl, 1);
- }
-
- /* Start Passthrough Mode */
- ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, 2, 11);
- atomic_inc(&itv->capturing);
- return 0;
- }
-
- if (itv->output_mode != OUT_PASSTHROUGH)
- return 0;
-
- /* Stop Passthrough Mode */
- ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, 1, 2, 11);
- ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, 1, 0, 0);
-
- atomic_dec(&itv->capturing);
- atomic_dec(&itv->decoding);
- clear_bit(IVTV_F_S_PASSTHROUGH, &dec_stream->s_flags);
- clear_bit(IVTV_F_S_STREAMING, &dec_stream->s_flags);
- itv->output_mode = OUT_NONE;
- if (atomic_read(&itv->capturing) == 0)
- cx2341x_handler_set_busy(&itv->cxhdl, 0);
-
- return 0;
-}
diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h
deleted file mode 100644
index a653a513641..00000000000
--- a/drivers/media/video/ivtv/ivtv-streams.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- init/start/stop/exit stream functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_STREAMS_H
-#define IVTV_STREAMS_H
-
-int ivtv_streams_setup(struct ivtv *itv);
-int ivtv_streams_register(struct ivtv *itv);
-void ivtv_streams_cleanup(struct ivtv *itv, int unregister);
-
-/* Capture related */
-int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s);
-int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end);
-int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset);
-int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts);
-
-void ivtv_stop_all_captures(struct ivtv *itv);
-int ivtv_passthrough_mode(struct ivtv *itv, int enable);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
deleted file mode 100644
index 7338cb2d0a3..00000000000
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- User DMA
-
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-udma.h"
-
-void ivtv_udma_get_page_info(struct ivtv_dma_page_info *dma_page, unsigned long first, unsigned long size)
-{
- dma_page->uaddr = first & PAGE_MASK;
- dma_page->offset = first & ~PAGE_MASK;
- dma_page->tail = 1 + ((first+size-1) & ~PAGE_MASK);
- dma_page->first = (first & PAGE_MASK) >> PAGE_SHIFT;
- dma_page->last = ((first+size-1) & PAGE_MASK) >> PAGE_SHIFT;
- dma_page->page_count = dma_page->last - dma_page->first + 1;
- if (dma_page->page_count == 1) dma_page->tail -= dma_page->offset;
-}
-
-int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info *dma_page, int map_offset)
-{
- int i, offset;
- unsigned long flags;
-
- if (map_offset < 0)
- return map_offset;
-
- offset = dma_page->offset;
-
- /* Fill SG Array with new values */
- for (i = 0; i < dma_page->page_count; i++) {
- unsigned int len = (i == dma_page->page_count - 1) ?
- dma_page->tail : PAGE_SIZE - offset;
-
- if (PageHighMem(dma->map[map_offset])) {
- void *src;
-
- if (dma->bouncemap[map_offset] == NULL)
- dma->bouncemap[map_offset] = alloc_page(GFP_KERNEL);
- if (dma->bouncemap[map_offset] == NULL)
- return -1;
- local_irq_save(flags);
- src = kmap_atomic(dma->map[map_offset]) + offset;
- memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len);
- kunmap_atomic(src);
- local_irq_restore(flags);
- sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset], len, offset);
- }
- else {
- sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset], len, offset);
- }
- offset = 0;
- map_offset++;
- }
- return map_offset;
-}
-
-void ivtv_udma_fill_sg_array (struct ivtv_user_dma *dma, u32 buffer_offset, u32 buffer_offset_2, u32 split) {
- int i;
- struct scatterlist *sg;
-
- for (i = 0, sg = dma->SGlist; i < dma->SG_length; i++, sg++) {
- dma->SGarray[i].size = cpu_to_le32(sg_dma_len(sg));
- dma->SGarray[i].src = cpu_to_le32(sg_dma_address(sg));
- dma->SGarray[i].dst = cpu_to_le32(buffer_offset);
- buffer_offset += sg_dma_len(sg);
-
- split -= sg_dma_len(sg);
- if (split == 0)
- buffer_offset = buffer_offset_2;
- }
-}
-
-/* User DMA Buffers */
-void ivtv_udma_alloc(struct ivtv *itv)
-{
- if (itv->udma.SG_handle == 0) {
- /* Map DMA Page Array Buffer */
- itv->udma.SG_handle = pci_map_single(itv->pdev, itv->udma.SGarray,
- sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
- ivtv_udma_sync_for_cpu(itv);
- }
-}
-
-int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
- void __user *userbuf, int size_in_bytes)
-{
- struct ivtv_dma_page_info user_dma;
- struct ivtv_user_dma *dma = &itv->udma;
- int i, err;
-
- IVTV_DEBUG_DMA("ivtv_udma_setup, dst: 0x%08x\n", (unsigned int)ivtv_dest_addr);
-
- /* Still in USE */
- if (dma->SG_length || dma->page_count) {
- IVTV_DEBUG_WARN("ivtv_udma_setup: SG_length %d page_count %d still full?\n",
- dma->SG_length, dma->page_count);
- return -EBUSY;
- }
-
- ivtv_udma_get_page_info(&user_dma, (unsigned long)userbuf, size_in_bytes);
-
- if (user_dma.page_count <= 0) {
- IVTV_DEBUG_WARN("ivtv_udma_setup: Error %d page_count from %d bytes %d offset\n",
- user_dma.page_count, size_in_bytes, user_dma.offset);
- return -EINVAL;
- }
-
- /* Get user pages for DMA Xfer */
- down_read(&current->mm->mmap_sem);
- err = get_user_pages(current, current->mm,
- user_dma.uaddr, user_dma.page_count, 0, 1, dma->map, NULL);
- up_read(&current->mm->mmap_sem);
-
- if (user_dma.page_count != err) {
- IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n",
- err, user_dma.page_count);
- if (err >= 0) {
- for (i = 0; i < err; i++)
- put_page(dma->map[i]);
- return -EINVAL;
- }
- return err;
- }
-
- dma->page_count = user_dma.page_count;
-
- /* Fill SG List with new values */
- if (ivtv_udma_fill_sg_list(dma, &user_dma, 0) < 0) {
- for (i = 0; i < dma->page_count; i++) {
- put_page(dma->map[i]);
- }
- dma->page_count = 0;
- return -ENOMEM;
- }
-
- /* Map SG List */
- dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
-
- /* Fill SG Array with new values */
- ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1);
-
- /* Tag SG Array with Interrupt Bit */
- dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000);
-
- ivtv_udma_sync_for_device(itv);
- return dma->page_count;
-}
-
-void ivtv_udma_unmap(struct ivtv *itv)
-{
- struct ivtv_user_dma *dma = &itv->udma;
- int i;
-
- IVTV_DEBUG_INFO("ivtv_unmap_user_dma\n");
-
- /* Nothing to free */
- if (dma->page_count == 0)
- return;
-
- /* Unmap Scatterlist */
- if (dma->SG_length) {
- pci_unmap_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
- dma->SG_length = 0;
- }
- /* sync DMA */
- ivtv_udma_sync_for_cpu(itv);
-
- /* Release User Pages */
- for (i = 0; i < dma->page_count; i++) {
- put_page(dma->map[i]);
- }
- dma->page_count = 0;
-}
-
-void ivtv_udma_free(struct ivtv *itv)
-{
- int i;
-
- /* Unmap SG Array */
- if (itv->udma.SG_handle) {
- pci_unmap_single(itv->pdev, itv->udma.SG_handle,
- sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
- }
-
- /* Unmap Scatterlist */
- if (itv->udma.SG_length) {
- pci_unmap_sg(itv->pdev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE);
- }
-
- for (i = 0; i < IVTV_DMA_SG_OSD_ENT; i++) {
- if (itv->udma.bouncemap[i])
- __free_page(itv->udma.bouncemap[i]);
- }
-}
-
-void ivtv_udma_start(struct ivtv *itv)
-{
- IVTV_DEBUG_DMA("start UDMA\n");
- write_reg(itv->udma.SG_handle, IVTV_REG_DECDMAADDR);
- write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
- set_bit(IVTV_F_I_DMA, &itv->i_flags);
- set_bit(IVTV_F_I_UDMA, &itv->i_flags);
- clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags);
-}
-
-void ivtv_udma_prepare(struct ivtv *itv)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&itv->dma_reg_lock, flags);
- if (!test_bit(IVTV_F_I_DMA, &itv->i_flags))
- ivtv_udma_start(itv);
- else
- set_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags);
- spin_unlock_irqrestore(&itv->dma_reg_lock, flags);
-}
diff --git a/drivers/media/video/ivtv/ivtv-udma.h b/drivers/media/video/ivtv/ivtv-udma.h
deleted file mode 100644
index ee3c9efb5b7..00000000000
--- a/drivers/media/video/ivtv/ivtv-udma.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2006-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_UDMA_H
-#define IVTV_UDMA_H
-
-/* User DMA functions */
-void ivtv_udma_get_page_info(struct ivtv_dma_page_info *dma_page, unsigned long first, unsigned long size);
-int ivtv_udma_fill_sg_list(struct ivtv_user_dma *dma, struct ivtv_dma_page_info *dma_page, int map_offset);
-void ivtv_udma_fill_sg_array(struct ivtv_user_dma *dma, u32 buffer_offset, u32 buffer_offset_2, u32 split);
-int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
- void __user *userbuf, int size_in_bytes);
-void ivtv_udma_unmap(struct ivtv *itv);
-void ivtv_udma_free(struct ivtv *itv);
-void ivtv_udma_alloc(struct ivtv *itv);
-void ivtv_udma_prepare(struct ivtv *itv);
-void ivtv_udma_start(struct ivtv *itv);
-
-static inline void ivtv_udma_sync_for_device(struct ivtv *itv)
-{
- pci_dma_sync_single_for_device(itv->pdev, itv->udma.SG_handle,
- sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
-}
-
-static inline void ivtv_udma_sync_for_cpu(struct ivtv *itv)
-{
- pci_dma_sync_single_for_cpu(itv->pdev, itv->udma.SG_handle,
- sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
-}
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
deleted file mode 100644
index 293db806d93..00000000000
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- Vertical Blank Interval support functions
- Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-i2c.h"
-#include "ivtv-ioctl.h"
-#include "ivtv-queue.h"
-#include "ivtv-cards.h"
-#include "ivtv-vbi.h"
-
-static void ivtv_set_vps(struct ivtv *itv, int enabled)
-{
- struct v4l2_sliced_vbi_data data;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return;
- data.id = V4L2_SLICED_VPS;
- data.field = 0;
- data.line = enabled ? 16 : 0;
- data.data[2] = itv->vbi.vps_payload.data[0];
- data.data[8] = itv->vbi.vps_payload.data[1];
- data.data[9] = itv->vbi.vps_payload.data[2];
- data.data[10] = itv->vbi.vps_payload.data[3];
- data.data[11] = itv->vbi.vps_payload.data[4];
- ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
-}
-
-static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
-{
- struct v4l2_sliced_vbi_data data;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return;
- data.id = V4L2_SLICED_CAPTION_525;
- data.field = 0;
- data.line = (mode & 1) ? 21 : 0;
- data.data[0] = cc->odd[0];
- data.data[1] = cc->odd[1];
- ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
- data.field = 1;
- data.line = (mode & 2) ? 21 : 0;
- data.data[0] = cc->even[0];
- data.data[1] = cc->even[1];
- ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
-}
-
-static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
-{
- struct v4l2_sliced_vbi_data data;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return;
- /* When using a 50 Hz system, always turn on the
- wide screen signal with 4x3 ratio as the default.
- Turning this signal on and off can confuse certain
- TVs. As far as I can tell there is no reason not to
- transmit this signal. */
- if ((itv->std_out & V4L2_STD_625_50) && !enabled) {
- enabled = 1;
- mode = 0x08; /* 4x3 full format */
- }
- data.id = V4L2_SLICED_WSS_625;
- data.field = 0;
- data.line = enabled ? 23 : 0;
- data.data[0] = mode & 0xff;
- data.data[1] = (mode >> 8) & 0xff;
- ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
-}
-
-static int odd_parity(u8 c)
-{
- c ^= (c >> 4);
- c ^= (c >> 2);
- c ^= (c >> 1);
-
- return c & 1;
-}
-
-static void ivtv_write_vbi_line(struct ivtv *itv,
- const struct v4l2_sliced_vbi_data *d,
- struct vbi_cc *cc, int *found_cc)
-{
- struct vbi_info *vi = &itv->vbi;
-
- if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
- if (d->field) {
- cc->even[0] = d->data[0];
- cc->even[1] = d->data[1];
- } else {
- cc->odd[0] = d->data[0];
- cc->odd[1] = d->data[1];
- }
- *found_cc = 1;
- } else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
- struct vbi_vps vps;
-
- vps.data[0] = d->data[2];
- vps.data[1] = d->data[8];
- vps.data[2] = d->data[9];
- vps.data[3] = d->data[10];
- vps.data[4] = d->data[11];
- if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) {
- vi->vps_payload = vps;
- set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
- }
- } else if (d->id == V4L2_SLICED_WSS_625 &&
- d->line == 23 && d->field == 0) {
- int wss = d->data[0] | d->data[1] << 8;
-
- if (vi->wss_payload != wss) {
- vi->wss_payload = wss;
- set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
- }
- }
-}
-
-static void ivtv_write_vbi_cc_lines(struct ivtv *itv, const struct vbi_cc *cc)
-{
- struct vbi_info *vi = &itv->vbi;
-
- if (vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) {
- memcpy(&vi->cc_payload[vi->cc_payload_idx], cc,
- sizeof(struct vbi_cc));
- vi->cc_payload_idx++;
- set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
- }
-}
-
-static void ivtv_write_vbi(struct ivtv *itv,
- const struct v4l2_sliced_vbi_data *sliced,
- size_t cnt)
-{
- struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
- int found_cc = 0;
- size_t i;
-
- for (i = 0; i < cnt; i++)
- ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc);
-
- if (found_cc)
- ivtv_write_vbi_cc_lines(itv, &cc);
-}
-
-ssize_t
-ivtv_write_vbi_from_user(struct ivtv *itv,
- const struct v4l2_sliced_vbi_data __user *sliced,
- size_t cnt)
-{
- struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
- int found_cc = 0;
- size_t i;
- struct v4l2_sliced_vbi_data d;
- ssize_t ret = cnt * sizeof(struct v4l2_sliced_vbi_data);
-
- for (i = 0; i < cnt; i++) {
- if (copy_from_user(&d, sliced + i,
- sizeof(struct v4l2_sliced_vbi_data))) {
- ret = -EFAULT;
- break;
- }
- ivtv_write_vbi_line(itv, &d, &cc, &found_cc);
- }
-
- if (found_cc)
- ivtv_write_vbi_cc_lines(itv, &cc);
-
- return ret;
-}
-
-static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
-{
- int line = 0;
- int i;
- u32 linemask[2] = { 0, 0 };
- unsigned short size;
- static const u8 mpeg_hdr_data[] = {
- 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
- 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
- 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
- 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
- };
- const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
- int idx = itv->vbi.frame % IVTV_VBI_FRAMES;
- u8 *dst = &itv->vbi.sliced_mpeg_data[idx][0];
-
- for (i = 0; i < lines; i++) {
- int f, l;
-
- if (itv->vbi.sliced_data[i].id == 0)
- continue;
-
- l = itv->vbi.sliced_data[i].line - 6;
- f = itv->vbi.sliced_data[i].field;
- if (f)
- l += 18;
- if (l < 32)
- linemask[0] |= (1 << l);
- else
- linemask[1] |= (1 << (l - 32));
- dst[sd + 12 + line * 43] =
- ivtv_service2vbi(itv->vbi.sliced_data[i].id);
- memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
- line++;
- }
- memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
- if (line == 36) {
- /* All lines are used, so there is no space for the linemask
- (the max size of the VBI data is 36 * 43 + 4 bytes).
- So in this case we use the magic number 'ITV0'. */
- memcpy(dst + sd, "ITV0", 4);
- memcpy(dst + sd + 4, dst + sd + 12, line * 43);
- size = 4 + ((43 * line + 3) & ~3);
- } else {
- memcpy(dst + sd, "itv0", 4);
- cpu_to_le32s(&linemask[0]);
- cpu_to_le32s(&linemask[1]);
- memcpy(dst + sd + 4, &linemask[0], 8);
- size = 12 + ((43 * line + 3) & ~3);
- }
- dst[4+16] = (size + 10) >> 8;
- dst[5+16] = (size + 10) & 0xff;
- dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
- dst[10+16] = (pts_stamp >> 22) & 0xff;
- dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
- dst[12+16] = (pts_stamp >> 7) & 0xff;
- dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
- itv->vbi.sliced_mpeg_size[idx] = sd + size;
-}
-
-static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
-{
- u32 linemask[2];
- int i, l, id2;
- int line = 0;
-
- if (!memcmp(p, "itv0", 4)) {
- memcpy(linemask, p + 4, 8);
- p += 12;
- } else if (!memcmp(p, "ITV0", 4)) {
- linemask[0] = 0xffffffff;
- linemask[1] = 0xf;
- p += 4;
- } else {
- /* unknown VBI data, convert to empty VBI frame */
- linemask[0] = linemask[1] = 0;
- }
- for (i = 0; i < 36; i++) {
- int err = 0;
-
- if (i < 32 && !(linemask[0] & (1 << i)))
- continue;
- if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
- continue;
- id2 = *p & 0xf;
- switch (id2) {
- case IVTV_SLICED_TYPE_TELETEXT_B:
- id2 = V4L2_SLICED_TELETEXT_B;
- break;
- case IVTV_SLICED_TYPE_CAPTION_525:
- id2 = V4L2_SLICED_CAPTION_525;
- err = !odd_parity(p[1]) || !odd_parity(p[2]);
- break;
- case IVTV_SLICED_TYPE_VPS:
- id2 = V4L2_SLICED_VPS;
- break;
- case IVTV_SLICED_TYPE_WSS_625:
- id2 = V4L2_SLICED_WSS_625;
- break;
- default:
- id2 = 0;
- break;
- }
- if (err == 0) {
- l = (i < 18) ? i + 6 : i - 18 + 6;
- itv->vbi.sliced_dec_data[line].line = l;
- itv->vbi.sliced_dec_data[line].field = i >= 18;
- itv->vbi.sliced_dec_data[line].id = id2;
- memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42);
- line++;
- }
- p += 43;
- }
- while (line < 36) {
- itv->vbi.sliced_dec_data[line].id = 0;
- itv->vbi.sliced_dec_data[line].line = 0;
- itv->vbi.sliced_dec_data[line].field = 0;
- line++;
- }
- return line * sizeof(itv->vbi.sliced_dec_data[0]);
-}
-
-/* Compress raw VBI format, removes leading SAV codes and surplus space after the
- field.
- Returns new compressed size. */
-static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
-{
- u32 line_size = itv->vbi.raw_decoder_line_size;
- u32 lines = itv->vbi.count;
- u8 sav1 = itv->vbi.raw_decoder_sav_odd_field;
- u8 sav2 = itv->vbi.raw_decoder_sav_even_field;
- u8 *q = buf;
- u8 *p;
- int i;
-
- for (i = 0; i < lines; i++) {
- p = buf + i * line_size;
-
- /* Look for SAV code */
- if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
- break;
- }
- memcpy(q, p + 4, line_size - 4);
- q += line_size - 4;
- }
- return lines * (line_size - 4);
-}
-
-
-/* Compressed VBI format, all found sliced blocks put next to one another
- Returns new compressed size */
-static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav)
-{
- u32 line_size = itv->vbi.sliced_decoder_line_size;
- struct v4l2_decode_vbi_line vbi;
- int i;
- unsigned lines = 0;
-
- /* find the first valid line */
- for (i = 0; i < size; i++, buf++) {
- if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
- break;
- }
-
- size -= i;
- if (size < line_size) {
- return line;
- }
- for (i = 0; i < size / line_size; i++) {
- u8 *p = buf + i * line_size;
-
- /* Look for SAV code */
- if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
- continue;
- }
- vbi.p = p + 4;
- v4l2_subdev_call(itv->sd_video, vbi, decode_vbi_line, &vbi);
- if (vbi.type && !(lines & (1 << vbi.line))) {
- lines |= 1 << vbi.line;
- itv->vbi.sliced_data[line].id = vbi.type;
- itv->vbi.sliced_data[line].field = vbi.is_second_field;
- itv->vbi.sliced_data[line].line = vbi.line;
- memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42);
- line++;
- }
- }
- return line;
-}
-
-void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
- u64 pts_stamp, int streamtype)
-{
- u8 *p = (u8 *) buf->buf;
- u32 size = buf->bytesused;
- int y;
-
- /* Raw VBI data */
- if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) {
- u8 type;
-
- ivtv_buf_swap(buf);
-
- type = p[3];
-
- size = buf->bytesused = compress_raw_buf(itv, p, size);
-
- /* second field of the frame? */
- if (type == itv->vbi.raw_decoder_sav_even_field) {
- /* Dirty hack needed for backwards
- compatibility of old VBI software. */
- p += size - 4;
- memcpy(p, &itv->vbi.frame, 4);
- itv->vbi.frame++;
- }
- return;
- }
-
- /* Sliced VBI data with data insertion */
- if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
- int lines;
-
- ivtv_buf_swap(buf);
-
- /* first field */
- lines = compress_sliced_buf(itv, 0, p, size / 2,
- itv->vbi.sliced_decoder_sav_odd_field);
- /* second field */
- /* experimentation shows that the second half does not always begin
- at the exact address. So start a bit earlier (hence 32). */
- lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
- itv->vbi.sliced_decoder_sav_even_field);
- /* always return at least one empty line */
- if (lines == 0) {
- itv->vbi.sliced_data[0].id = 0;
- itv->vbi.sliced_data[0].line = 0;
- itv->vbi.sliced_data[0].field = 0;
- lines = 1;
- }
- buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
- memcpy(p, &itv->vbi.sliced_data[0], size);
-
- if (itv->vbi.insert_mpeg) {
- copy_vbi_data(itv, lines, pts_stamp);
- }
- itv->vbi.frame++;
- return;
- }
-
- /* Sliced VBI re-inserted from an MPEG stream */
- if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
- /* If the size is not 4-byte aligned, then the starting address
- for the swapping is also shifted. After swapping the data the
- real start address of the VBI data is exactly 4 bytes after the
- original start. It's a bit fiddly but it works like a charm.
- Non-4-byte alignment happens when an lseek is done on the input
- mpeg file to a non-4-byte aligned position. So on arrival here
- the VBI data is also non-4-byte aligned. */
- int offset = size & 3;
- int cnt;
-
- if (offset) {
- p += 4 - offset;
- }
- /* Swap Buffer */
- for (y = 0; y < size; y += 4) {
- swab32s((u32 *)(p + y));
- }
-
- cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
- memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
- buf->bytesused = cnt;
-
- ivtv_write_vbi(itv, itv->vbi.sliced_dec_data,
- cnt / sizeof(itv->vbi.sliced_dec_data[0]));
- return;
- }
-}
-
-void ivtv_disable_cc(struct ivtv *itv)
-{
- struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
-
- clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
- ivtv_set_cc(itv, 0, &cc);
- itv->vbi.cc_payload_idx = 0;
-}
-
-
-void ivtv_vbi_work_handler(struct ivtv *itv)
-{
- struct vbi_info *vi = &itv->vbi;
- struct v4l2_sliced_vbi_data data;
- struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
-
- /* Lock */
- if (itv->output_mode == OUT_PASSTHROUGH) {
- if (itv->is_50hz) {
- data.id = V4L2_SLICED_WSS_625;
- data.field = 0;
-
- if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
- ivtv_set_wss(itv, 1, data.data[0] & 0xf);
- vi->wss_missing_cnt = 0;
- } else if (vi->wss_missing_cnt == 4) {
- ivtv_set_wss(itv, 1, 0x8); /* 4x3 full format */
- } else {
- vi->wss_missing_cnt++;
- }
- }
- else {
- int mode = 0;
-
- data.id = V4L2_SLICED_CAPTION_525;
- data.field = 0;
- if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
- mode |= 1;
- cc.odd[0] = data.data[0];
- cc.odd[1] = data.data[1];
- }
- data.field = 1;
- if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
- mode |= 2;
- cc.even[0] = data.data[0];
- cc.even[1] = data.data[1];
- }
- if (mode) {
- vi->cc_missing_cnt = 0;
- ivtv_set_cc(itv, mode, &cc);
- } else if (vi->cc_missing_cnt == 4) {
- ivtv_set_cc(itv, 0, &cc);
- } else {
- vi->cc_missing_cnt++;
- }
- }
- return;
- }
-
- if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
- ivtv_set_wss(itv, 1, vi->wss_payload & 0xf);
- }
-
- if (test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
- if (vi->cc_payload_idx == 0) {
- clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
- ivtv_set_cc(itv, 3, &cc);
- }
- while (vi->cc_payload_idx) {
- cc = vi->cc_payload[0];
-
- memcpy(vi->cc_payload, vi->cc_payload + 1,
- sizeof(vi->cc_payload) - sizeof(vi->cc_payload[0]));
- vi->cc_payload_idx--;
- if (vi->cc_payload_idx && cc.odd[0] == 0x80 && cc.odd[1] == 0x80)
- continue;
-
- ivtv_set_cc(itv, 3, &cc);
- break;
- }
- }
-
- if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
- ivtv_set_vps(itv, 1);
- }
-}
diff --git a/drivers/media/video/ivtv/ivtv-vbi.h b/drivers/media/video/ivtv/ivtv-vbi.h
deleted file mode 100644
index 166dd0b75d0..00000000000
--- a/drivers/media/video/ivtv/ivtv-vbi.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- Vertical Blank Interval support functions
- Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_VBI_H
-#define IVTV_VBI_H
-
-ssize_t
-ivtv_write_vbi_from_user(struct ivtv *itv,
- const struct v4l2_sliced_vbi_data __user *sliced,
- size_t count);
-void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
- u64 pts_stamp, int streamtype);
-int ivtv_used_line(struct ivtv *itv, int line, int field);
-void ivtv_disable_cc(struct ivtv *itv);
-void ivtv_set_vbi(unsigned long arg);
-void ivtv_vbi_work_handler(struct ivtv *itv);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-version.h b/drivers/media/video/ivtv/ivtv-version.h
deleted file mode 100644
index a20f346fcad..00000000000
--- a/drivers/media/video/ivtv/ivtv-version.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- ivtv driver version information
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_VERSION_H
-#define IVTV_VERSION_H
-
-#define IVTV_DRIVER_NAME "ivtv"
-#define IVTV_VERSION "1.4.3"
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
deleted file mode 100644
index 2ad65eb2983..00000000000
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ /dev/null
@@ -1,1296 +0,0 @@
-/*
- yuv support
-
- Copyright (C) 2007 Ian Armstrong <ian@iarmst.demon.co.uk>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-udma.h"
-#include "ivtv-yuv.h"
-
-/* YUV buffer offsets */
-const u32 yuv_offset[IVTV_YUV_BUFFERS] = {
- 0x001a8600,
- 0x00240400,
- 0x002d8200,
- 0x00370000,
- 0x00029000,
- 0x000C0E00,
- 0x006B0400,
- 0x00748200
-};
-
-static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
- struct ivtv_dma_frame *args)
-{
- struct ivtv_dma_page_info y_dma;
- struct ivtv_dma_page_info uv_dma;
- struct yuv_playback_info *yi = &itv->yuv_info;
- u8 frame = yi->draw_frame;
- struct yuv_frame_info *f = &yi->new_frame_info[frame];
- int i;
- int y_pages, uv_pages;
- unsigned long y_buffer_offset, uv_buffer_offset;
- int y_decode_height, uv_decode_height, y_size;
-
- y_buffer_offset = IVTV_DECODER_OFFSET + yuv_offset[frame];
- uv_buffer_offset = y_buffer_offset + IVTV_YUV_BUFFER_UV_OFFSET;
-
- y_decode_height = uv_decode_height = f->src_h + f->src_y;
-
- if (f->offset_y)
- y_buffer_offset += 720 * 16;
-
- if (y_decode_height & 15)
- y_decode_height = (y_decode_height + 16) & ~15;
-
- if (uv_decode_height & 31)
- uv_decode_height = (uv_decode_height + 32) & ~31;
-
- y_size = 720 * y_decode_height;
-
- /* Still in USE */
- if (dma->SG_length || dma->page_count) {
- IVTV_DEBUG_WARN
- ("prep_user_dma: SG_length %d page_count %d still full?\n",
- dma->SG_length, dma->page_count);
- return -EBUSY;
- }
-
- ivtv_udma_get_page_info (&y_dma, (unsigned long)args->y_source, 720 * y_decode_height);
- ivtv_udma_get_page_info (&uv_dma, (unsigned long)args->uv_source, 360 * uv_decode_height);
-
- /* Get user pages for DMA Xfer */
- down_read(&current->mm->mmap_sem);
- y_pages = get_user_pages(current, current->mm, y_dma.uaddr, y_dma.page_count, 0, 1, &dma->map[0], NULL);
- uv_pages = 0; /* silence gcc. value is set and consumed only if: */
- if (y_pages == y_dma.page_count) {
- uv_pages = get_user_pages(current, current->mm,
- uv_dma.uaddr, uv_dma.page_count, 0, 1,
- &dma->map[y_pages], NULL);
- }
- up_read(&current->mm->mmap_sem);
-
- if (y_pages != y_dma.page_count || uv_pages != uv_dma.page_count) {
- int rc = -EFAULT;
-
- if (y_pages == y_dma.page_count) {
- IVTV_DEBUG_WARN
- ("failed to map uv user pages, returned %d "
- "expecting %d\n", uv_pages, uv_dma.page_count);
-
- if (uv_pages >= 0) {
- for (i = 0; i < uv_pages; i++)
- put_page(dma->map[y_pages + i]);
- rc = -EFAULT;
- } else {
- rc = uv_pages;
- }
- } else {
- IVTV_DEBUG_WARN
- ("failed to map y user pages, returned %d "
- "expecting %d\n", y_pages, y_dma.page_count);
- }
- if (y_pages >= 0) {
- for (i = 0; i < y_pages; i++)
- put_page(dma->map[i]);
- /*
- * Inherit the -EFAULT from rc's
- * initialization, but allow it to be
- * overriden by uv_pages above if it was an
- * actual errno.
- */
- } else {
- rc = y_pages;
- }
- return rc;
- }
-
- dma->page_count = y_pages + uv_pages;
-
- /* Fill & map SG List */
- if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) {
- IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n");
- for (i = 0; i < dma->page_count; i++) {
- put_page(dma->map[i]);
- }
- dma->page_count = 0;
- return -ENOMEM;
- }
- dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
-
- /* Fill SG Array with new values */
- ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
-
- /* If we've offset the y plane, ensure top area is blanked */
- if (f->offset_y && yi->blanking_dmaptr) {
- dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16);
- dma->SGarray[dma->SG_length].src = cpu_to_le32(yi->blanking_dmaptr);
- dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DECODER_OFFSET + yuv_offset[frame]);
- dma->SG_length++;
- }
-
- /* Tag SG Array with Interrupt Bit */
- dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000);
-
- ivtv_udma_sync_for_device(itv);
- return 0;
-}
-
-/* We rely on a table held in the firmware - Quick check. */
-int ivtv_yuv_filter_check(struct ivtv *itv)
-{
- int i, y, uv;
-
- for (i = 0, y = 16, uv = 4; i < 16; i++, y += 24, uv += 12) {
- if ((read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + y) != i << 16) ||
- (read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + uv) != i << 16)) {
- IVTV_WARN ("YUV filter table not found in firmware.\n");
- return -1;
- }
- }
- return 0;
-}
-
-static void ivtv_yuv_filter(struct ivtv *itv, int h_filter, int v_filter_1, int v_filter_2)
-{
- u32 i, line;
-
- /* If any filter is -1, then don't update it */
- if (h_filter > -1) {
- if (h_filter > 4)
- h_filter = 4;
- i = IVTV_YUV_HORIZONTAL_FILTER_OFFSET + (h_filter * 384);
- for (line = 0; line < 16; line++) {
- write_reg(read_dec(i), 0x02804);
- write_reg(read_dec(i), 0x0281c);
- i += 4;
- write_reg(read_dec(i), 0x02808);
- write_reg(read_dec(i), 0x02820);
- i += 4;
- write_reg(read_dec(i), 0x0280c);
- write_reg(read_dec(i), 0x02824);
- i += 4;
- write_reg(read_dec(i), 0x02810);
- write_reg(read_dec(i), 0x02828);
- i += 4;
- write_reg(read_dec(i), 0x02814);
- write_reg(read_dec(i), 0x0282c);
- i += 8;
- write_reg(0, 0x02818);
- write_reg(0, 0x02830);
- }
- IVTV_DEBUG_YUV("h_filter -> %d\n", h_filter);
- }
-
- if (v_filter_1 > -1) {
- if (v_filter_1 > 4)
- v_filter_1 = 4;
- i = IVTV_YUV_VERTICAL_FILTER_OFFSET + (v_filter_1 * 192);
- for (line = 0; line < 16; line++) {
- write_reg(read_dec(i), 0x02900);
- i += 4;
- write_reg(read_dec(i), 0x02904);
- i += 8;
- write_reg(0, 0x02908);
- }
- IVTV_DEBUG_YUV("v_filter_1 -> %d\n", v_filter_1);
- }
-
- if (v_filter_2 > -1) {
- if (v_filter_2 > 4)
- v_filter_2 = 4;
- i = IVTV_YUV_VERTICAL_FILTER_OFFSET + (v_filter_2 * 192);
- for (line = 0; line < 16; line++) {
- write_reg(read_dec(i), 0x0290c);
- i += 4;
- write_reg(read_dec(i), 0x02910);
- i += 8;
- write_reg(0, 0x02914);
- }
- IVTV_DEBUG_YUV("v_filter_2 -> %d\n", v_filter_2);
- }
-}
-
-static void ivtv_yuv_handle_horizontal(struct ivtv *itv, struct yuv_frame_info *f)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- u32 reg_2834, reg_2838, reg_283c;
- u32 reg_2844, reg_2854, reg_285c;
- u32 reg_2864, reg_2874, reg_2890;
- u32 reg_2870, reg_2870_base, reg_2870_offset;
- int x_cutoff;
- int h_filter;
- u32 master_width;
-
- IVTV_DEBUG_WARN
- ("Adjust to width %d src_w %d dst_w %d src_x %d dst_x %d\n",
- f->tru_w, f->src_w, f->dst_w, f->src_x, f->dst_x);
-
- /* How wide is the src image */
- x_cutoff = f->src_w + f->src_x;
-
- /* Set the display width */
- reg_2834 = f->dst_w;
- reg_2838 = reg_2834;
-
- /* Set the display position */
- reg_2890 = f->dst_x;
-
- /* Index into the image horizontally */
- reg_2870 = 0;
-
- /* 2870 is normally fudged to align video coords with osd coords.
- If running full screen, it causes an unwanted left shift
- Remove the fudge if we almost fill the screen.
- Gradually adjust the offset to avoid the video 'snapping'
- left/right if it gets dragged through this region.
- Only do this if osd is full width. */
- if (f->vis_w == 720) {
- if ((f->tru_x - f->pan_x > -1) && (f->tru_x - f->pan_x <= 40) && (f->dst_w >= 680))
- reg_2870 = 10 - (f->tru_x - f->pan_x) / 4;
- else if ((f->tru_x - f->pan_x < 0) && (f->tru_x - f->pan_x >= -20) && (f->dst_w >= 660))
- reg_2870 = (10 + (f->tru_x - f->pan_x) / 2);
-
- if (f->dst_w >= f->src_w)
- reg_2870 = reg_2870 << 16 | reg_2870;
- else
- reg_2870 = ((reg_2870 & ~1) << 15) | (reg_2870 & ~1);
- }
-
- if (f->dst_w < f->src_w)
- reg_2870 = 0x000d000e - reg_2870;
- else
- reg_2870 = 0x0012000e - reg_2870;
-
- /* We're also using 2870 to shift the image left (src_x & negative dst_x) */
- reg_2870_offset = (f->src_x * ((f->dst_w << 21) / f->src_w)) >> 19;
-
- if (f->dst_w >= f->src_w) {
- x_cutoff &= ~1;
- master_width = (f->src_w * 0x00200000) / (f->dst_w);
- if (master_width * f->dst_w != f->src_w * 0x00200000)
- master_width++;
- reg_2834 = (reg_2834 << 16) | x_cutoff;
- reg_2838 = (reg_2838 << 16) | x_cutoff;
- reg_283c = master_width >> 2;
- reg_2844 = master_width >> 2;
- reg_2854 = master_width;
- reg_285c = master_width >> 1;
- reg_2864 = master_width >> 1;
-
- /* We also need to factor in the scaling
- (src_w - dst_w) / (src_w / 4) */
- if (f->dst_w > f->src_w)
- reg_2870_base = ((f->dst_w - f->src_w)<<16) / (f->src_w <<14);
- else
- reg_2870_base = 0;
-
- reg_2870 += (((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 2) + (reg_2870_base << 17 | reg_2870_base);
- reg_2874 = 0;
- } else if (f->dst_w < f->src_w / 2) {
- master_width = (f->src_w * 0x00080000) / f->dst_w;
- if (master_width * f->dst_w != f->src_w * 0x00080000)
- master_width++;
- reg_2834 = (reg_2834 << 16) | x_cutoff;
- reg_2838 = (reg_2838 << 16) | x_cutoff;
- reg_283c = master_width >> 2;
- reg_2844 = master_width >> 1;
- reg_2854 = master_width;
- reg_285c = master_width >> 1;
- reg_2864 = master_width >> 1;
- reg_2870 += ((reg_2870_offset << 15) & 0xFFFF0000) | reg_2870_offset;
- reg_2870 += (5 - (((f->src_w + f->src_w / 2) - 1) / f->dst_w)) << 16;
- reg_2874 = 0x00000012;
- } else {
- master_width = (f->src_w * 0x00100000) / f->dst_w;
- if (master_width * f->dst_w != f->src_w * 0x00100000)
- master_width++;
- reg_2834 = (reg_2834 << 16) | x_cutoff;
- reg_2838 = (reg_2838 << 16) | x_cutoff;
- reg_283c = master_width >> 2;
- reg_2844 = master_width >> 1;
- reg_2854 = master_width;
- reg_285c = master_width >> 1;
- reg_2864 = master_width >> 1;
- reg_2870 += ((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 1;
- reg_2870 += (5 - (((f->src_w * 3) - 1) / f->dst_w)) << 16;
- reg_2874 = 0x00000001;
- }
-
- /* Select the horizontal filter */
- if (f->src_w == f->dst_w) {
- /* An exact size match uses filter 0 */
- h_filter = 0;
- } else {
- /* Figure out which filter to use */
- h_filter = ((f->src_w << 16) / f->dst_w) >> 15;
- h_filter = (h_filter >> 1) + (h_filter & 1);
- /* Only an exact size match can use filter 0 */
- h_filter += !h_filter;
- }
-
- write_reg(reg_2834, 0x02834);
- write_reg(reg_2838, 0x02838);
- IVTV_DEBUG_YUV("Update reg 0x2834 %08x->%08x 0x2838 %08x->%08x\n",
- yi->reg_2834, reg_2834, yi->reg_2838, reg_2838);
-
- write_reg(reg_283c, 0x0283c);
- write_reg(reg_2844, 0x02844);
-
- IVTV_DEBUG_YUV("Update reg 0x283c %08x->%08x 0x2844 %08x->%08x\n",
- yi->reg_283c, reg_283c, yi->reg_2844, reg_2844);
-
- write_reg(0x00080514, 0x02840);
- write_reg(0x00100514, 0x02848);
- IVTV_DEBUG_YUV("Update reg 0x2840 %08x->%08x 0x2848 %08x->%08x\n",
- yi->reg_2840, 0x00080514, yi->reg_2848, 0x00100514);
-
- write_reg(reg_2854, 0x02854);
- IVTV_DEBUG_YUV("Update reg 0x2854 %08x->%08x \n",
- yi->reg_2854, reg_2854);
-
- write_reg(reg_285c, 0x0285c);
- write_reg(reg_2864, 0x02864);
- IVTV_DEBUG_YUV("Update reg 0x285c %08x->%08x 0x2864 %08x->%08x\n",
- yi->reg_285c, reg_285c, yi->reg_2864, reg_2864);
-
- write_reg(reg_2874, 0x02874);
- IVTV_DEBUG_YUV("Update reg 0x2874 %08x->%08x\n",
- yi->reg_2874, reg_2874);
-
- write_reg(reg_2870, 0x02870);
- IVTV_DEBUG_YUV("Update reg 0x2870 %08x->%08x\n",
- yi->reg_2870, reg_2870);
-
- write_reg(reg_2890, 0x02890);
- IVTV_DEBUG_YUV("Update reg 0x2890 %08x->%08x\n",
- yi->reg_2890, reg_2890);
-
- /* Only update the filter if we really need to */
- if (h_filter != yi->h_filter) {
- ivtv_yuv_filter(itv, h_filter, -1, -1);
- yi->h_filter = h_filter;
- }
-}
-
-static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *f)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- u32 master_height;
- u32 reg_2918, reg_291c, reg_2920, reg_2928;
- u32 reg_2930, reg_2934, reg_293c;
- u32 reg_2940, reg_2944, reg_294c;
- u32 reg_2950, reg_2954, reg_2958, reg_295c;
- u32 reg_2960, reg_2964, reg_2968, reg_296c;
- u32 reg_289c;
- u32 src_major_y, src_minor_y;
- u32 src_major_uv, src_minor_uv;
- u32 reg_2964_base, reg_2968_base;
- int v_filter_1, v_filter_2;
-
- IVTV_DEBUG_WARN
- ("Adjust to height %d src_h %d dst_h %d src_y %d dst_y %d\n",
- f->tru_h, f->src_h, f->dst_h, f->src_y, f->dst_y);
-
- /* What scaling mode is being used... */
- IVTV_DEBUG_YUV("Scaling mode Y: %s\n",
- f->interlaced_y ? "Interlaced" : "Progressive");
-
- IVTV_DEBUG_YUV("Scaling mode UV: %s\n",
- f->interlaced_uv ? "Interlaced" : "Progressive");
-
- /* What is the source video being treated as... */
- IVTV_DEBUG_WARN("Source video: %s\n",
- f->interlaced ? "Interlaced" : "Progressive");
-
- /* We offset into the image using two different index methods, so split
- the y source coord into two parts. */
- if (f->src_y < 8) {
- src_minor_uv = f->src_y;
- src_major_uv = 0;
- } else {
- src_minor_uv = 8;
- src_major_uv = f->src_y - 8;
- }
-
- src_minor_y = src_minor_uv;
- src_major_y = src_major_uv;
-
- if (f->offset_y)
- src_minor_y += 16;
-
- if (f->interlaced_y)
- reg_2918 = (f->dst_h << 16) | (f->src_h + src_minor_y);
- else
- reg_2918 = (f->dst_h << 16) | ((f->src_h + src_minor_y) << 1);
-
- if (f->interlaced_uv)
- reg_291c = (f->dst_h << 16) | ((f->src_h + src_minor_uv) >> 1);
- else
- reg_291c = (f->dst_h << 16) | (f->src_h + src_minor_uv);
-
- reg_2964_base = (src_minor_y * ((f->dst_h << 16) / f->src_h)) >> 14;
- reg_2968_base = (src_minor_uv * ((f->dst_h << 16) / f->src_h)) >> 14;
-
- if (f->dst_h / 2 >= f->src_h && !f->interlaced_y) {
- master_height = (f->src_h * 0x00400000) / f->dst_h;
- if ((f->src_h * 0x00400000) - (master_height * f->dst_h) >= f->dst_h / 2)
- master_height++;
- reg_2920 = master_height >> 2;
- reg_2928 = master_height >> 3;
- reg_2930 = master_height;
- reg_2940 = master_height >> 1;
- reg_2964_base >>= 3;
- reg_2968_base >>= 3;
- reg_296c = 0x00000000;
- } else if (f->dst_h >= f->src_h) {
- master_height = (f->src_h * 0x00400000) / f->dst_h;
- master_height = (master_height >> 1) + (master_height & 1);
- reg_2920 = master_height >> 2;
- reg_2928 = master_height >> 2;
- reg_2930 = master_height;
- reg_2940 = master_height >> 1;
- reg_296c = 0x00000000;
- if (f->interlaced_y) {
- reg_2964_base >>= 3;
- } else {
- reg_296c++;
- reg_2964_base >>= 2;
- }
- if (f->interlaced_uv)
- reg_2928 >>= 1;
- reg_2968_base >>= 3;
- } else if (f->dst_h >= f->src_h / 2) {
- master_height = (f->src_h * 0x00200000) / f->dst_h;
- master_height = (master_height >> 1) + (master_height & 1);
- reg_2920 = master_height >> 2;
- reg_2928 = master_height >> 2;
- reg_2930 = master_height;
- reg_2940 = master_height;
- reg_296c = 0x00000101;
- if (f->interlaced_y) {
- reg_2964_base >>= 2;
- } else {
- reg_296c++;
- reg_2964_base >>= 1;
- }
- if (f->interlaced_uv)
- reg_2928 >>= 1;
- reg_2968_base >>= 2;
- } else {
- master_height = (f->src_h * 0x00100000) / f->dst_h;
- master_height = (master_height >> 1) + (master_height & 1);
- reg_2920 = master_height >> 2;
- reg_2928 = master_height >> 2;
- reg_2930 = master_height;
- reg_2940 = master_height;
- reg_2964_base >>= 1;
- reg_2968_base >>= 2;
- reg_296c = 0x00000102;
- }
-
- /* FIXME These registers change depending on scaled / unscaled output
- We really need to work out what they should be */
- if (f->src_h == f->dst_h) {
- reg_2934 = 0x00020000;
- reg_293c = 0x00100000;
- reg_2944 = 0x00040000;
- reg_294c = 0x000b0000;
- } else {
- reg_2934 = 0x00000FF0;
- reg_293c = 0x00000FF0;
- reg_2944 = 0x00000FF0;
- reg_294c = 0x00000FF0;
- }
-
- /* The first line to be displayed */
- reg_2950 = 0x00010000 + src_major_y;
- if (f->interlaced_y)
- reg_2950 += 0x00010000;
- reg_2954 = reg_2950 + 1;
-
- reg_2958 = 0x00010000 + (src_major_y >> 1);
- if (f->interlaced_uv)
- reg_2958 += 0x00010000;
- reg_295c = reg_2958 + 1;
-
- if (yi->decode_height == 480)
- reg_289c = 0x011e0017;
- else
- reg_289c = 0x01500017;
-
- if (f->dst_y < 0)
- reg_289c = (reg_289c - ((f->dst_y & ~1)<<15))-(f->dst_y >>1);
- else
- reg_289c = (reg_289c + ((f->dst_y & ~1)<<15))+(f->dst_y >>1);
-
- /* How much of the source to decode.
- Take into account the source offset */
- reg_2960 = ((src_minor_y + f->src_h + src_major_y) - 1) |
- (((src_minor_uv + f->src_h + src_major_uv - 1) & ~1) << 15);
-
- /* Calculate correct value for register 2964 */
- if (f->src_h == f->dst_h) {
- reg_2964 = 1;
- } else {
- reg_2964 = 2 + ((f->dst_h << 1) / f->src_h);
- reg_2964 = (reg_2964 >> 1) + (reg_2964 & 1);
- }
- reg_2968 = (reg_2964 << 16) + reg_2964 + (reg_2964 >> 1);
- reg_2964 = (reg_2964 << 16) + reg_2964 + (reg_2964 * 46 / 94);
-
- /* Okay, we've wasted time working out the correct value,
- but if we use it, it fouls the the window alignment.
- Fudge it to what we want... */
- reg_2964 = 0x00010001 + ((reg_2964 & 0x0000FFFF) - (reg_2964 >> 16));
- reg_2968 = 0x00010001 + ((reg_2968 & 0x0000FFFF) - (reg_2968 >> 16));
-
- /* Deviate further from what it should be. I find the flicker headache
- inducing so try to reduce it slightly. Leave 2968 as-is otherwise
- colours foul. */
- if ((reg_2964 != 0x00010001) && (f->dst_h / 2 <= f->src_h))
- reg_2964 = (reg_2964 & 0xFFFF0000) + ((reg_2964 & 0x0000FFFF) / 2);
-
- if (!f->interlaced_y)
- reg_2964 -= 0x00010001;
- if (!f->interlaced_uv)
- reg_2968 -= 0x00010001;
-
- reg_2964 += ((reg_2964_base << 16) | reg_2964_base);
- reg_2968 += ((reg_2968_base << 16) | reg_2968_base);
-
- /* Select the vertical filter */
- if (f->src_h == f->dst_h) {
- /* An exact size match uses filter 0/1 */
- v_filter_1 = 0;
- v_filter_2 = 1;
- } else {
- /* Figure out which filter to use */
- v_filter_1 = ((f->src_h << 16) / f->dst_h) >> 15;
- v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1);
- /* Only an exact size match can use filter 0 */
- v_filter_1 += !v_filter_1;
- v_filter_2 = v_filter_1;
- }
-
- write_reg(reg_2934, 0x02934);
- write_reg(reg_293c, 0x0293c);
- IVTV_DEBUG_YUV("Update reg 0x2934 %08x->%08x 0x293c %08x->%08x\n",
- yi->reg_2934, reg_2934, yi->reg_293c, reg_293c);
- write_reg(reg_2944, 0x02944);
- write_reg(reg_294c, 0x0294c);
- IVTV_DEBUG_YUV("Update reg 0x2944 %08x->%08x 0x294c %08x->%08x\n",
- yi->reg_2944, reg_2944, yi->reg_294c, reg_294c);
-
- /* Ensure 2970 is 0 (does it ever change ?) */
-/* write_reg(0,0x02970); */
-/* IVTV_DEBUG_YUV("Update reg 0x2970 %08x->%08x\n", yi->reg_2970, 0); */
-
- write_reg(reg_2930, 0x02938);
- write_reg(reg_2930, 0x02930);
- IVTV_DEBUG_YUV("Update reg 0x2930 %08x->%08x 0x2938 %08x->%08x\n",
- yi->reg_2930, reg_2930, yi->reg_2938, reg_2930);
-
- write_reg(reg_2928, 0x02928);
- write_reg(reg_2928 + 0x514, 0x0292C);
- IVTV_DEBUG_YUV("Update reg 0x2928 %08x->%08x 0x292c %08x->%08x\n",
- yi->reg_2928, reg_2928, yi->reg_292c, reg_2928 + 0x514);
-
- write_reg(reg_2920, 0x02920);
- write_reg(reg_2920 + 0x514, 0x02924);
- IVTV_DEBUG_YUV("Update reg 0x2920 %08x->%08x 0x2924 %08x->%08x\n",
- yi->reg_2920, reg_2920, yi->reg_2924, reg_2920 + 0x514);
-
- write_reg(reg_2918, 0x02918);
- write_reg(reg_291c, 0x0291C);
- IVTV_DEBUG_YUV("Update reg 0x2918 %08x->%08x 0x291C %08x->%08x\n",
- yi->reg_2918, reg_2918, yi->reg_291c, reg_291c);
-
- write_reg(reg_296c, 0x0296c);
- IVTV_DEBUG_YUV("Update reg 0x296c %08x->%08x\n",
- yi->reg_296c, reg_296c);
-
- write_reg(reg_2940, 0x02948);
- write_reg(reg_2940, 0x02940);
- IVTV_DEBUG_YUV("Update reg 0x2940 %08x->%08x 0x2948 %08x->%08x\n",
- yi->reg_2940, reg_2940, yi->reg_2948, reg_2940);
-
- write_reg(reg_2950, 0x02950);
- write_reg(reg_2954, 0x02954);
- IVTV_DEBUG_YUV("Update reg 0x2950 %08x->%08x 0x2954 %08x->%08x\n",
- yi->reg_2950, reg_2950, yi->reg_2954, reg_2954);
-
- write_reg(reg_2958, 0x02958);
- write_reg(reg_295c, 0x0295C);
- IVTV_DEBUG_YUV("Update reg 0x2958 %08x->%08x 0x295C %08x->%08x\n",
- yi->reg_2958, reg_2958, yi->reg_295c, reg_295c);
-
- write_reg(reg_2960, 0x02960);
- IVTV_DEBUG_YUV("Update reg 0x2960 %08x->%08x \n",
- yi->reg_2960, reg_2960);
-
- write_reg(reg_2964, 0x02964);
- write_reg(reg_2968, 0x02968);
- IVTV_DEBUG_YUV("Update reg 0x2964 %08x->%08x 0x2968 %08x->%08x\n",
- yi->reg_2964, reg_2964, yi->reg_2968, reg_2968);
-
- write_reg(reg_289c, 0x0289c);
- IVTV_DEBUG_YUV("Update reg 0x289c %08x->%08x\n",
- yi->reg_289c, reg_289c);
-
- /* Only update filter 1 if we really need to */
- if (v_filter_1 != yi->v_filter_1) {
- ivtv_yuv_filter(itv, -1, v_filter_1, -1);
- yi->v_filter_1 = v_filter_1;
- }
-
- /* Only update filter 2 if we really need to */
- if (v_filter_2 != yi->v_filter_2) {
- ivtv_yuv_filter(itv, -1, -1, v_filter_2);
- yi->v_filter_2 = v_filter_2;
- }
-}
-
-/* Modify the supplied coordinate information to fit the visible osd area */
-static u32 ivtv_yuv_window_setup(struct ivtv *itv, struct yuv_frame_info *f)
-{
- struct yuv_frame_info *of = &itv->yuv_info.old_frame_info;
- int osd_crop;
- u32 osd_scale;
- u32 yuv_update = 0;
-
- /* Sorry, but no negative coords for src */
- if (f->src_x < 0)
- f->src_x = 0;
- if (f->src_y < 0)
- f->src_y = 0;
-
- /* Can only reduce width down to 1/4 original size */
- if ((osd_crop = f->src_w - 4 * f->dst_w) > 0) {
- f->src_x += osd_crop / 2;
- f->src_w = (f->src_w - osd_crop) & ~3;
- f->dst_w = f->src_w / 4;
- f->dst_w += f->dst_w & 1;
- }
-
- /* Can only reduce height down to 1/4 original size */
- if (f->src_h / f->dst_h >= 2) {
- /* Overflow may be because we're running progressive,
- so force mode switch */
- f->interlaced_y = 1;
- /* Make sure we're still within limits for interlace */
- if ((osd_crop = f->src_h - 4 * f->dst_h) > 0) {
- /* If we reach here we'll have to force the height. */
- f->src_y += osd_crop / 2;
- f->src_h = (f->src_h - osd_crop) & ~3;
- f->dst_h = f->src_h / 4;
- f->dst_h += f->dst_h & 1;
- }
- }
-
- /* If there's nothing to safe to display, we may as well stop now */
- if ((int)f->dst_w <= 2 || (int)f->dst_h <= 2 ||
- (int)f->src_w <= 2 || (int)f->src_h <= 2) {
- return IVTV_YUV_UPDATE_INVALID;
- }
-
- /* Ensure video remains inside OSD area */
- osd_scale = (f->src_h << 16) / f->dst_h;
-
- if ((osd_crop = f->pan_y - f->dst_y) > 0) {
- /* Falls off the upper edge - crop */
- f->src_y += (osd_scale * osd_crop) >> 16;
- f->src_h -= (osd_scale * osd_crop) >> 16;
- f->dst_h -= osd_crop;
- f->dst_y = 0;
- } else {
- f->dst_y -= f->pan_y;
- }
-
- if ((osd_crop = f->dst_h + f->dst_y - f->vis_h) > 0) {
- /* Falls off the lower edge - crop */
- f->dst_h -= osd_crop;
- f->src_h -= (osd_scale * osd_crop) >> 16;
- }
-
- osd_scale = (f->src_w << 16) / f->dst_w;
-
- if ((osd_crop = f->pan_x - f->dst_x) > 0) {
- /* Fall off the left edge - crop */
- f->src_x += (osd_scale * osd_crop) >> 16;
- f->src_w -= (osd_scale * osd_crop) >> 16;
- f->dst_w -= osd_crop;
- f->dst_x = 0;
- } else {
- f->dst_x -= f->pan_x;
- }
-
- if ((osd_crop = f->dst_w + f->dst_x - f->vis_w) > 0) {
- /* Falls off the right edge - crop */
- f->dst_w -= osd_crop;
- f->src_w -= (osd_scale * osd_crop) >> 16;
- }
-
- if (itv->yuv_info.track_osd) {
- /* The OSD can be moved. Track to it */
- f->dst_x += itv->yuv_info.osd_x_offset;
- f->dst_y += itv->yuv_info.osd_y_offset;
- }
-
- /* Width & height for both src & dst must be even.
- Same for coordinates. */
- f->dst_w &= ~1;
- f->dst_x &= ~1;
-
- f->src_w += f->src_x & 1;
- f->src_x &= ~1;
-
- f->src_w &= ~1;
- f->dst_w &= ~1;
-
- f->dst_h &= ~1;
- f->dst_y &= ~1;
-
- f->src_h += f->src_y & 1;
- f->src_y &= ~1;
-
- f->src_h &= ~1;
- f->dst_h &= ~1;
-
- /* Due to rounding, we may have reduced the output size to <1/4 of
- the source. Check again, but this time just resize. Don't change
- source coordinates */
- if (f->dst_w < f->src_w / 4) {
- f->src_w &= ~3;
- f->dst_w = f->src_w / 4;
- f->dst_w += f->dst_w & 1;
- }
- if (f->dst_h < f->src_h / 4) {
- f->src_h &= ~3;
- f->dst_h = f->src_h / 4;
- f->dst_h += f->dst_h & 1;
- }
-
- /* Check again. If there's nothing to safe to display, stop now */
- if ((int)f->dst_w <= 2 || (int)f->dst_h <= 2 ||
- (int)f->src_w <= 2 || (int)f->src_h <= 2) {
- return IVTV_YUV_UPDATE_INVALID;
- }
-
- /* Both x offset & width are linked, so they have to be done together */
- if ((of->dst_w != f->dst_w) || (of->src_w != f->src_w) ||
- (of->dst_x != f->dst_x) || (of->src_x != f->src_x) ||
- (of->pan_x != f->pan_x) || (of->vis_w != f->vis_w)) {
- yuv_update |= IVTV_YUV_UPDATE_HORIZONTAL;
- }
-
- if ((of->src_h != f->src_h) || (of->dst_h != f->dst_h) ||
- (of->dst_y != f->dst_y) || (of->src_y != f->src_y) ||
- (of->pan_y != f->pan_y) || (of->vis_h != f->vis_h) ||
- (of->lace_mode != f->lace_mode) ||
- (of->interlaced_y != f->interlaced_y) ||
- (of->interlaced_uv != f->interlaced_uv)) {
- yuv_update |= IVTV_YUV_UPDATE_VERTICAL;
- }
-
- return yuv_update;
-}
-
-/* Update the scaling register to the requested value */
-void ivtv_yuv_work_handler(struct ivtv *itv)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- struct yuv_frame_info f;
- int frame = yi->update_frame;
- u32 yuv_update;
-
- IVTV_DEBUG_YUV("Update yuv registers for frame %d\n", frame);
- f = yi->new_frame_info[frame];
-
- if (yi->track_osd) {
- /* Snapshot the osd pan info */
- f.pan_x = yi->osd_x_pan;
- f.pan_y = yi->osd_y_pan;
- f.vis_w = yi->osd_vis_w;
- f.vis_h = yi->osd_vis_h;
- } else {
- /* Not tracking the osd, so assume full screen */
- f.pan_x = 0;
- f.pan_y = 0;
- f.vis_w = 720;
- f.vis_h = yi->decode_height;
- }
-
- /* Calculate the display window coordinates. Exit if nothing left */
- if (!(yuv_update = ivtv_yuv_window_setup(itv, &f)))
- return;
-
- if (yuv_update & IVTV_YUV_UPDATE_INVALID) {
- write_reg(0x01008080, 0x2898);
- } else if (yuv_update) {
- write_reg(0x00108080, 0x2898);
-
- if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL)
- ivtv_yuv_handle_horizontal(itv, &f);
-
- if (yuv_update & IVTV_YUV_UPDATE_VERTICAL)
- ivtv_yuv_handle_vertical(itv, &f);
- }
- yi->old_frame_info = f;
-}
-
-static void ivtv_yuv_init(struct ivtv *itv)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
-
- IVTV_DEBUG_YUV("ivtv_yuv_init\n");
-
- /* Take a snapshot of the current register settings */
- yi->reg_2834 = read_reg(0x02834);
- yi->reg_2838 = read_reg(0x02838);
- yi->reg_283c = read_reg(0x0283c);
- yi->reg_2840 = read_reg(0x02840);
- yi->reg_2844 = read_reg(0x02844);
- yi->reg_2848 = read_reg(0x02848);
- yi->reg_2854 = read_reg(0x02854);
- yi->reg_285c = read_reg(0x0285c);
- yi->reg_2864 = read_reg(0x02864);
- yi->reg_2870 = read_reg(0x02870);
- yi->reg_2874 = read_reg(0x02874);
- yi->reg_2898 = read_reg(0x02898);
- yi->reg_2890 = read_reg(0x02890);
-
- yi->reg_289c = read_reg(0x0289c);
- yi->reg_2918 = read_reg(0x02918);
- yi->reg_291c = read_reg(0x0291c);
- yi->reg_2920 = read_reg(0x02920);
- yi->reg_2924 = read_reg(0x02924);
- yi->reg_2928 = read_reg(0x02928);
- yi->reg_292c = read_reg(0x0292c);
- yi->reg_2930 = read_reg(0x02930);
- yi->reg_2934 = read_reg(0x02934);
- yi->reg_2938 = read_reg(0x02938);
- yi->reg_293c = read_reg(0x0293c);
- yi->reg_2940 = read_reg(0x02940);
- yi->reg_2944 = read_reg(0x02944);
- yi->reg_2948 = read_reg(0x02948);
- yi->reg_294c = read_reg(0x0294c);
- yi->reg_2950 = read_reg(0x02950);
- yi->reg_2954 = read_reg(0x02954);
- yi->reg_2958 = read_reg(0x02958);
- yi->reg_295c = read_reg(0x0295c);
- yi->reg_2960 = read_reg(0x02960);
- yi->reg_2964 = read_reg(0x02964);
- yi->reg_2968 = read_reg(0x02968);
- yi->reg_296c = read_reg(0x0296c);
- yi->reg_2970 = read_reg(0x02970);
-
- yi->v_filter_1 = -1;
- yi->v_filter_2 = -1;
- yi->h_filter = -1;
-
- /* Set some valid size info */
- yi->osd_x_offset = read_reg(0x02a04) & 0x00000FFF;
- yi->osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF;
-
- /* Bit 2 of reg 2878 indicates current decoder output format
- 0 : NTSC 1 : PAL */
- if (read_reg(0x2878) & 4)
- yi->decode_height = 576;
- else
- yi->decode_height = 480;
-
- if (!itv->osd_info) {
- yi->osd_vis_w = 720 - yi->osd_x_offset;
- yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
- } else {
- /* If no visible size set, assume full size */
- if (!yi->osd_vis_w)
- yi->osd_vis_w = 720 - yi->osd_x_offset;
-
- if (!yi->osd_vis_h) {
- yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
- } else if (yi->osd_vis_h + yi->osd_y_offset > yi->decode_height) {
- /* If output video standard has changed, requested height may
- not be legal */
- IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
- yi->osd_vis_h + yi->osd_y_offset,
- yi->decode_height);
- yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
- }
- }
-
- /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
- yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
- if (yi->blanking_ptr) {
- yi->blanking_dmaptr = pci_map_single(itv->pdev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
- } else {
- yi->blanking_dmaptr = 0;
- IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
- }
-
- /* Enable YUV decoder output */
- write_reg_sync(0x01, IVTV_REG_VDM);
-
- set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
- atomic_set(&yi->next_dma_frame, 0);
-}
-
-/* Get next available yuv buffer on PVR350 */
-static void ivtv_yuv_next_free(struct ivtv *itv)
-{
- int draw, display;
- struct yuv_playback_info *yi = &itv->yuv_info;
-
- if (atomic_read(&yi->next_dma_frame) == -1)
- ivtv_yuv_init(itv);
-
- draw = atomic_read(&yi->next_fill_frame);
- display = atomic_read(&yi->next_dma_frame);
-
- if (display > draw)
- display -= IVTV_YUV_BUFFERS;
-
- if (draw - display >= yi->max_frames_buffered)
- draw = (u8)(draw - 1) % IVTV_YUV_BUFFERS;
- else
- yi->new_frame_info[draw].update = 0;
-
- yi->draw_frame = draw;
-}
-
-/* Set up frame according to ivtv_dma_frame parameters */
-static void ivtv_yuv_setup_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- u8 frame = yi->draw_frame;
- u8 last_frame = (u8)(frame - 1) % IVTV_YUV_BUFFERS;
- struct yuv_frame_info *nf = &yi->new_frame_info[frame];
- struct yuv_frame_info *of = &yi->new_frame_info[last_frame];
- int lace_threshold = yi->lace_threshold;
-
- /* Preserve old update flag in case we're overwriting a queued frame */
- int update = nf->update;
-
- /* Take a snapshot of the yuv coordinate information */
- nf->src_x = args->src.left;
- nf->src_y = args->src.top;
- nf->src_w = args->src.width;
- nf->src_h = args->src.height;
- nf->dst_x = args->dst.left;
- nf->dst_y = args->dst.top;
- nf->dst_w = args->dst.width;
- nf->dst_h = args->dst.height;
- nf->tru_x = args->dst.left;
- nf->tru_w = args->src_width;
- nf->tru_h = args->src_height;
-
- /* Are we going to offset the Y plane */
- nf->offset_y = (nf->tru_h + nf->src_x < 512 - 16) ? 1 : 0;
-
- nf->update = 0;
- nf->interlaced_y = 0;
- nf->interlaced_uv = 0;
- nf->delay = 0;
- nf->sync_field = 0;
- nf->lace_mode = yi->lace_mode & IVTV_YUV_MODE_MASK;
-
- if (lace_threshold < 0)
- lace_threshold = yi->decode_height - 1;
-
- /* Work out the lace settings */
- switch (nf->lace_mode) {
- case IVTV_YUV_MODE_PROGRESSIVE: /* Progressive mode */
- nf->interlaced = 0;
- if (nf->tru_h < 512 || (nf->tru_h > 576 && nf->tru_h < 1021))
- nf->interlaced_y = 0;
- else
- nf->interlaced_y = 1;
-
- if (nf->tru_h < 1021 && (nf->dst_h >= nf->src_h / 2))
- nf->interlaced_uv = 0;
- else
- nf->interlaced_uv = 1;
- break;
-
- case IVTV_YUV_MODE_AUTO:
- if (nf->tru_h <= lace_threshold || nf->tru_h > 576 || nf->tru_w > 720) {
- nf->interlaced = 0;
- if ((nf->tru_h < 512) ||
- (nf->tru_h > 576 && nf->tru_h < 1021) ||
- (nf->tru_w > 720 && nf->tru_h < 1021))
- nf->interlaced_y = 0;
- else
- nf->interlaced_y = 1;
- if (nf->tru_h < 1021 && (nf->dst_h >= nf->src_h / 2))
- nf->interlaced_uv = 0;
- else
- nf->interlaced_uv = 1;
- } else {
- nf->interlaced = 1;
- nf->interlaced_y = 1;
- nf->interlaced_uv = 1;
- }
- break;
-
- case IVTV_YUV_MODE_INTERLACED: /* Interlace mode */
- default:
- nf->interlaced = 1;
- nf->interlaced_y = 1;
- nf->interlaced_uv = 1;
- break;
- }
-
- if (memcmp(&yi->old_frame_info_args, nf, sizeof(*nf))) {
- yi->old_frame_info_args = *nf;
- nf->update = 1;
- IVTV_DEBUG_YUV("Requesting reg update for frame %d\n", frame);
- }
-
- nf->update |= update;
- nf->sync_field = yi->lace_sync_field;
- nf->delay = nf->sync_field != of->sync_field;
-}
-
-/* Frame is complete & ready for display */
-void ivtv_yuv_frame_complete(struct ivtv *itv)
-{
- atomic_set(&itv->yuv_info.next_fill_frame,
- (itv->yuv_info.draw_frame + 1) % IVTV_YUV_BUFFERS);
-}
-
-static int ivtv_yuv_udma_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
-{
- DEFINE_WAIT(wait);
- int rc = 0;
- int got_sig = 0;
- /* DMA the frame */
- mutex_lock(&itv->udma.lock);
-
- if ((rc = ivtv_yuv_prep_user_dma(itv, &itv->udma, args)) != 0) {
- mutex_unlock(&itv->udma.lock);
- return rc;
- }
-
- ivtv_udma_prepare(itv);
- prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
- /* if no UDMA is pending and no UDMA is in progress, then the DMA
- is finished */
- while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) ||
- test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
- /* don't interrupt if the DMA is in progress but break off
- a still pending DMA. */
- got_sig = signal_pending(current);
- if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
- break;
- got_sig = 0;
- schedule();
- }
- finish_wait(&itv->dma_waitq, &wait);
-
- /* Unmap Last DMA Xfer */
- ivtv_udma_unmap(itv);
-
- if (got_sig) {
- IVTV_DEBUG_INFO("User stopped YUV UDMA\n");
- mutex_unlock(&itv->udma.lock);
- return -EINTR;
- }
-
- ivtv_yuv_frame_complete(itv);
-
- mutex_unlock(&itv->udma.lock);
- return rc;
-}
-
-/* Setup frame according to V4L2 parameters */
-void ivtv_yuv_setup_stream_frame(struct ivtv *itv)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- struct ivtv_dma_frame dma_args;
-
- ivtv_yuv_next_free(itv);
-
- /* Copy V4L2 parameters to an ivtv_dma_frame struct... */
- dma_args.y_source = NULL;
- dma_args.uv_source = NULL;
- dma_args.src.left = 0;
- dma_args.src.top = 0;
- dma_args.src.width = yi->v4l2_src_w;
- dma_args.src.height = yi->v4l2_src_h;
- dma_args.dst = yi->main_rect;
- dma_args.src_width = yi->v4l2_src_w;
- dma_args.src_height = yi->v4l2_src_h;
-
- /* ... and use the same setup routine as ivtv_yuv_prep_frame */
- ivtv_yuv_setup_frame(itv, &dma_args);
-
- if (!itv->dma_data_req_offset)
- itv->dma_data_req_offset = yuv_offset[yi->draw_frame];
-}
-
-/* Attempt to dma a frame from a user buffer */
-int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- struct ivtv_dma_frame dma_args;
- int res;
-
- ivtv_yuv_setup_stream_frame(itv);
-
- /* We only need to supply source addresses for this */
- dma_args.y_source = src;
- dma_args.uv_source = src + 720 * ((yi->v4l2_src_h + 31) & ~31);
- /* Wait for frame DMA. Note that serialize_lock is locked,
- so to allow other processes to access the driver while
- we are waiting unlock first and later lock again. */
- mutex_unlock(&itv->serialize_lock);
- res = ivtv_yuv_udma_frame(itv, &dma_args);
- mutex_lock(&itv->serialize_lock);
- return res;
-}
-
-/* IVTV_IOC_DMA_FRAME ioctl handler */
-int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
-{
- int res;
-
-/* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */
- ivtv_yuv_next_free(itv);
- ivtv_yuv_setup_frame(itv, args);
- /* Wait for frame DMA. Note that serialize_lock is locked,
- so to allow other processes to access the driver while
- we are waiting unlock first and later lock again. */
- mutex_unlock(&itv->serialize_lock);
- res = ivtv_yuv_udma_frame(itv, args);
- mutex_lock(&itv->serialize_lock);
- return res;
-}
-
-void ivtv_yuv_close(struct ivtv *itv)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- int h_filter, v_filter_1, v_filter_2;
-
- IVTV_DEBUG_YUV("ivtv_yuv_close\n");
- mutex_unlock(&itv->serialize_lock);
- ivtv_waitq(&itv->vsync_waitq);
- mutex_lock(&itv->serialize_lock);
-
- yi->running = 0;
- atomic_set(&yi->next_dma_frame, -1);
- atomic_set(&yi->next_fill_frame, 0);
-
- /* Reset registers we have changed so mpeg playback works */
-
- /* If we fully restore this register, the display may remain active.
- Restore, but set one bit to blank the video. Firmware will always
- clear this bit when needed, so not a problem. */
- write_reg(yi->reg_2898 | 0x01000000, 0x2898);
-
- write_reg(yi->reg_2834, 0x02834);
- write_reg(yi->reg_2838, 0x02838);
- write_reg(yi->reg_283c, 0x0283c);
- write_reg(yi->reg_2840, 0x02840);
- write_reg(yi->reg_2844, 0x02844);
- write_reg(yi->reg_2848, 0x02848);
- write_reg(yi->reg_2854, 0x02854);
- write_reg(yi->reg_285c, 0x0285c);
- write_reg(yi->reg_2864, 0x02864);
- write_reg(yi->reg_2870, 0x02870);
- write_reg(yi->reg_2874, 0x02874);
- write_reg(yi->reg_2890, 0x02890);
- write_reg(yi->reg_289c, 0x0289c);
-
- write_reg(yi->reg_2918, 0x02918);
- write_reg(yi->reg_291c, 0x0291c);
- write_reg(yi->reg_2920, 0x02920);
- write_reg(yi->reg_2924, 0x02924);
- write_reg(yi->reg_2928, 0x02928);
- write_reg(yi->reg_292c, 0x0292c);
- write_reg(yi->reg_2930, 0x02930);
- write_reg(yi->reg_2934, 0x02934);
- write_reg(yi->reg_2938, 0x02938);
- write_reg(yi->reg_293c, 0x0293c);
- write_reg(yi->reg_2940, 0x02940);
- write_reg(yi->reg_2944, 0x02944);
- write_reg(yi->reg_2948, 0x02948);
- write_reg(yi->reg_294c, 0x0294c);
- write_reg(yi->reg_2950, 0x02950);
- write_reg(yi->reg_2954, 0x02954);
- write_reg(yi->reg_2958, 0x02958);
- write_reg(yi->reg_295c, 0x0295c);
- write_reg(yi->reg_2960, 0x02960);
- write_reg(yi->reg_2964, 0x02964);
- write_reg(yi->reg_2968, 0x02968);
- write_reg(yi->reg_296c, 0x0296c);
- write_reg(yi->reg_2970, 0x02970);
-
- /* Prepare to restore filters */
-
- /* First the horizontal filter */
- if ((yi->reg_2834 & 0x0000FFFF) == (yi->reg_2834 >> 16)) {
- /* An exact size match uses filter 0 */
- h_filter = 0;
- } else {
- /* Figure out which filter to use */
- h_filter = ((yi->reg_2834 << 16) / (yi->reg_2834 >> 16)) >> 15;
- h_filter = (h_filter >> 1) + (h_filter & 1);
- /* Only an exact size match can use filter 0. */
- h_filter += !h_filter;
- }
-
- /* Now the vertical filter */
- if ((yi->reg_2918 & 0x0000FFFF) == (yi->reg_2918 >> 16)) {
- /* An exact size match uses filter 0/1 */
- v_filter_1 = 0;
- v_filter_2 = 1;
- } else {
- /* Figure out which filter to use */
- v_filter_1 = ((yi->reg_2918 << 16) / (yi->reg_2918 >> 16)) >> 15;
- v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1);
- /* Only an exact size match can use filter 0 */
- v_filter_1 += !v_filter_1;
- v_filter_2 = v_filter_1;
- }
-
- /* Now restore the filters */
- ivtv_yuv_filter(itv, h_filter, v_filter_1, v_filter_2);
-
- /* and clear a few registers */
- write_reg(0, 0x02814);
- write_reg(0, 0x0282c);
- write_reg(0, 0x02904);
- write_reg(0, 0x02910);
-
- /* Release the blanking buffer */
- if (yi->blanking_ptr) {
- kfree(yi->blanking_ptr);
- yi->blanking_ptr = NULL;
- pci_unmap_single(itv->pdev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE);
- }
-
- /* Invalidate the old dimension information */
- yi->old_frame_info.src_w = 0;
- yi->old_frame_info.src_h = 0;
- yi->old_frame_info_args.src_w = 0;
- yi->old_frame_info_args.src_h = 0;
-
- /* All done. */
- clear_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
-}
diff --git a/drivers/media/video/ivtv/ivtv-yuv.h b/drivers/media/video/ivtv/ivtv-yuv.h
deleted file mode 100644
index ca5173fbf00..00000000000
--- a/drivers/media/video/ivtv/ivtv-yuv.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- yuv support
-
- Copyright (C) 2007 Ian Armstrong <ian@iarmst.demon.co.uk>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_YUV_H
-#define IVTV_YUV_H
-
-#define IVTV_YUV_BUFFER_UV_OFFSET 0x65400 /* Offset to UV Buffer */
-
-/* Offset to filter table in firmware */
-#define IVTV_YUV_HORIZONTAL_FILTER_OFFSET 0x025d8
-#define IVTV_YUV_VERTICAL_FILTER_OFFSET 0x03358
-
-#define IVTV_YUV_UPDATE_HORIZONTAL 0x01
-#define IVTV_YUV_UPDATE_VERTICAL 0x02
-#define IVTV_YUV_UPDATE_INVALID 0x04
-
-extern const u32 yuv_offset[IVTV_YUV_BUFFERS];
-
-int ivtv_yuv_filter_check(struct ivtv *itv);
-void ivtv_yuv_setup_stream_frame(struct ivtv *itv);
-int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src);
-void ivtv_yuv_frame_complete(struct ivtv *itv);
-int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args);
-void ivtv_yuv_close(struct ivtv *itv);
-void ivtv_yuv_work_handler(struct ivtv *itv);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
deleted file mode 100644
index 05b94aa8ba3..00000000000
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ /dev/null
@@ -1,1317 +0,0 @@
-/*
- On Screen Display cx23415 Framebuffer driver
-
- This module presents the cx23415 OSD (onscreen display) framebuffer memory
- as a standard Linux /dev/fb style framebuffer device. The framebuffer has
- support for 8, 16 & 32 bpp packed pixel formats with alpha channel. In 16bpp
- mode, there is a choice of a three color depths (12, 15 or 16 bits), but no
- local alpha. The colorspace is selectable between rgb & yuv.
- Depending on the TV standard configured in the ivtv module at load time,
- the initial resolution is either 640x400 (NTSC) or 640x480 (PAL) at 8bpp.
- Video timings are locked to ensure a vertical refresh rate of 50Hz (PAL)
- or 59.94 (NTSC)
-
- Copyright (c) 2003 Matt T. Yourst <yourst@yourst.com>
-
- Derived from drivers/video/vesafb.c
- Portions (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
-
- 2.6 kernel port:
- Copyright (C) 2004 Matthias Badaire
-
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
-
- Copyright (C) 2006 Ian Armstrong <ian@iarmst.demon.co.uk>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/fb.h>
-#include <linux/ivtvfb.h>
-#include <linux/slab.h>
-
-#ifdef CONFIG_MTRR
-#include <asm/mtrr.h>
-#endif
-
-#include "ivtv-driver.h"
-#include "ivtv-cards.h"
-#include "ivtv-i2c.h"
-#include "ivtv-udma.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-firmware.h"
-
-/* card parameters */
-static int ivtvfb_card_id = -1;
-static int ivtvfb_debug = 0;
-static bool osd_laced;
-static int osd_depth;
-static int osd_upper;
-static int osd_left;
-static int osd_yres;
-static int osd_xres;
-
-module_param(ivtvfb_card_id, int, 0444);
-module_param_named(debug,ivtvfb_debug, int, 0644);
-module_param(osd_laced, bool, 0444);
-module_param(osd_depth, int, 0444);
-module_param(osd_upper, int, 0444);
-module_param(osd_left, int, 0444);
-module_param(osd_yres, int, 0444);
-module_param(osd_xres, int, 0444);
-
-MODULE_PARM_DESC(ivtvfb_card_id,
- "Only use framebuffer of the specified ivtv card (0-31)\n"
- "\t\t\tdefault -1: initialize all available framebuffers");
-
-MODULE_PARM_DESC(debug,
- "Debug level (bitmask). Default: errors only\n"
- "\t\t\t(debug = 3 gives full debugging)");
-
-/* Why upper, left, xres, yres, depth, laced ? To match terminology used
- by fbset.
- Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */
-
-MODULE_PARM_DESC(osd_laced,
- "Interlaced mode\n"
- "\t\t\t0=off\n"
- "\t\t\t1=on\n"
- "\t\t\tdefault off");
-
-MODULE_PARM_DESC(osd_depth,
- "Bits per pixel - 8, 16, 32\n"
- "\t\t\tdefault 8");
-
-MODULE_PARM_DESC(osd_upper,
- "Vertical start position\n"
- "\t\t\tdefault 0 (Centered)");
-
-MODULE_PARM_DESC(osd_left,
- "Horizontal start position\n"
- "\t\t\tdefault 0 (Centered)");
-
-MODULE_PARM_DESC(osd_yres,
- "Display height\n"
- "\t\t\tdefault 480 (PAL)\n"
- "\t\t\t 400 (NTSC)");
-
-MODULE_PARM_DESC(osd_xres,
- "Display width\n"
- "\t\t\tdefault 640");
-
-MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil, John Harvey, Ian Armstrong");
-MODULE_LICENSE("GPL");
-
-/* --------------------------------------------------------------------- */
-
-#define IVTVFB_DBGFLG_WARN (1 << 0)
-#define IVTVFB_DBGFLG_INFO (1 << 1)
-
-#define IVTVFB_DEBUG(x, type, fmt, args...) \
- do { \
- if ((x) & ivtvfb_debug) \
- printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->instance , ## args); \
- } while (0)
-#define IVTVFB_DEBUG_WARN(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_WARN, "warning", fmt , ## args)
-#define IVTVFB_DEBUG_INFO(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_INFO, "info", fmt , ## args)
-
-/* Standard kernel messages */
-#define IVTVFB_ERR(fmt, args...) printk(KERN_ERR "ivtvfb%d: " fmt, itv->instance , ## args)
-#define IVTVFB_WARN(fmt, args...) printk(KERN_WARNING "ivtvfb%d: " fmt, itv->instance , ## args)
-#define IVTVFB_INFO(fmt, args...) printk(KERN_INFO "ivtvfb%d: " fmt, itv->instance , ## args)
-
-/* --------------------------------------------------------------------- */
-
-#define IVTV_OSD_MAX_WIDTH 720
-#define IVTV_OSD_MAX_HEIGHT 576
-
-#define IVTV_OSD_BPP_8 0x00
-#define IVTV_OSD_BPP_16_444 0x03
-#define IVTV_OSD_BPP_16_555 0x02
-#define IVTV_OSD_BPP_16_565 0x01
-#define IVTV_OSD_BPP_32 0x04
-
-struct osd_info {
- /* Physical base address */
- unsigned long video_pbase;
- /* Relative base address (relative to start of decoder memory) */
- u32 video_rbase;
- /* Mapped base address */
- volatile char __iomem *video_vbase;
- /* Buffer size */
- u32 video_buffer_size;
-
-#ifdef CONFIG_MTRR
- /* video_base rounded down as required by hardware MTRRs */
- unsigned long fb_start_aligned_physaddr;
- /* video_base rounded up as required by hardware MTRRs */
- unsigned long fb_end_aligned_physaddr;
-#endif
-
- /* Store the buffer offset */
- int set_osd_coords_x;
- int set_osd_coords_y;
-
- /* Current dimensions (NOT VISIBLE SIZE!) */
- int display_width;
- int display_height;
- int display_byte_stride;
-
- /* Current bits per pixel */
- int bits_per_pixel;
- int bytes_per_pixel;
-
- /* Frame buffer stuff */
- struct fb_info ivtvfb_info;
- struct fb_var_screeninfo ivtvfb_defined;
- struct fb_fix_screeninfo ivtvfb_fix;
-
- /* Used for a warm start */
- struct fb_var_screeninfo fbvar_cur;
- int blank_cur;
- u32 palette_cur[256];
- u32 pan_cur;
-};
-
-struct ivtv_osd_coords {
- unsigned long offset;
- unsigned long max_offset;
- int pixel_stride;
- int lines;
- int x;
- int y;
-};
-
-/* --------------------------------------------------------------------- */
-
-/* ivtv API calls for framebuffer related support */
-
-static int ivtvfb_get_framebuffer(struct ivtv *itv, u32 *fbbase,
- u32 *fblength)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- int rc;
-
- ivtv_firmware_check(itv, "ivtvfb_get_framebuffer");
- rc = ivtv_vapi_result(itv, data, CX2341X_OSD_GET_FRAMEBUFFER, 0);
- *fbbase = data[0];
- *fblength = data[1];
- return rc;
-}
-
-static int ivtvfb_get_osd_coords(struct ivtv *itv,
- struct ivtv_osd_coords *osd)
-{
- struct osd_info *oi = itv->osd_info;
- u32 data[CX2341X_MBOX_MAX_DATA];
-
- ivtv_vapi_result(itv, data, CX2341X_OSD_GET_OSD_COORDS, 0);
-
- osd->offset = data[0] - oi->video_rbase;
- osd->max_offset = oi->display_width * oi->display_height * 4;
- osd->pixel_stride = data[1];
- osd->lines = data[2];
- osd->x = data[3];
- osd->y = data[4];
- return 0;
-}
-
-static int ivtvfb_set_osd_coords(struct ivtv *itv, const struct ivtv_osd_coords *osd)
-{
- struct osd_info *oi = itv->osd_info;
-
- oi->display_width = osd->pixel_stride;
- oi->display_byte_stride = osd->pixel_stride * oi->bytes_per_pixel;
- oi->set_osd_coords_x += osd->x;
- oi->set_osd_coords_y = osd->y;
-
- return ivtv_vapi(itv, CX2341X_OSD_SET_OSD_COORDS, 5,
- osd->offset + oi->video_rbase,
- osd->pixel_stride,
- osd->lines, osd->x, osd->y);
-}
-
-static int ivtvfb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window)
-{
- int osd_height_limit = itv->is_out_50hz ? 576 : 480;
-
- /* Only fail if resolution too high, otherwise fudge the start coords. */
- if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH))
- return -EINVAL;
-
- /* Ensure we don't exceed display limits */
- if (ivtv_window->top + ivtv_window->height > osd_height_limit) {
- IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid height setting (%d, %d)\n",
- ivtv_window->top, ivtv_window->height);
- ivtv_window->top = osd_height_limit - ivtv_window->height;
- }
-
- if (ivtv_window->left + ivtv_window->width > IVTV_OSD_MAX_WIDTH) {
- IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid width setting (%d, %d)\n",
- ivtv_window->left, ivtv_window->width);
- ivtv_window->left = IVTV_OSD_MAX_WIDTH - ivtv_window->width;
- }
-
- /* Set the OSD origin */
- write_reg((ivtv_window->top << 16) | ivtv_window->left, 0x02a04);
-
- /* How much to display */
- write_reg(((ivtv_window->top+ivtv_window->height) << 16) | (ivtv_window->left+ivtv_window->width), 0x02a08);
-
- /* Pass this info back the yuv handler */
- itv->yuv_info.osd_vis_w = ivtv_window->width;
- itv->yuv_info.osd_vis_h = ivtv_window->height;
- itv->yuv_info.osd_x_offset = ivtv_window->left;
- itv->yuv_info.osd_y_offset = ivtv_window->top;
-
- return 0;
-}
-
-static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
- unsigned long ivtv_dest_addr, void __user *userbuf,
- int size_in_bytes)
-{
- DEFINE_WAIT(wait);
- int got_sig = 0;
-
- mutex_lock(&itv->udma.lock);
- /* Map User DMA */
- if (ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) {
- mutex_unlock(&itv->udma.lock);
- IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, "
- "Error with get_user_pages: %d bytes, %d pages returned\n",
- size_in_bytes, itv->udma.page_count);
-
- /* get_user_pages must have failed completely */
- return -EIO;
- }
-
- IVTVFB_DEBUG_INFO("ivtvfb_prep_dec_dma_to_device, %d bytes, %d pages\n",
- size_in_bytes, itv->udma.page_count);
-
- ivtv_udma_prepare(itv);
- prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
- /* if no UDMA is pending and no UDMA is in progress, then the DMA
- is finished */
- while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) ||
- test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
- /* don't interrupt if the DMA is in progress but break off
- a still pending DMA. */
- got_sig = signal_pending(current);
- if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
- break;
- got_sig = 0;
- schedule();
- }
- finish_wait(&itv->dma_waitq, &wait);
-
- /* Unmap Last DMA Xfer */
- ivtv_udma_unmap(itv);
- mutex_unlock(&itv->udma.lock);
- if (got_sig) {
- IVTV_DEBUG_INFO("User stopped OSD\n");
- return -EINTR;
- }
-
- return 0;
-}
-
-static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
- unsigned long dest_offset, int count)
-{
- DEFINE_WAIT(wait);
- struct osd_info *oi = itv->osd_info;
-
- /* Nothing to do */
- if (count == 0) {
- IVTVFB_DEBUG_WARN("ivtvfb_prep_frame: Nothing to do. count = 0\n");
- return -EINVAL;
- }
-
- /* Check Total FB Size */
- if ((dest_offset + count) > oi->video_buffer_size) {
- IVTVFB_WARN("ivtvfb_prep_frame: Overflowing the framebuffer %ld, only %d available\n",
- dest_offset + count, oi->video_buffer_size);
- return -E2BIG;
- }
-
- /* Not fatal, but will have undesirable results */
- if ((unsigned long)source & 3)
- IVTVFB_WARN("ivtvfb_prep_frame: Source address not 32 bit aligned (0x%08lx)\n",
- (unsigned long)source);
-
- if (dest_offset & 3)
- IVTVFB_WARN("ivtvfb_prep_frame: Dest offset not 32 bit aligned (%ld)\n", dest_offset);
-
- if (count & 3)
- IVTVFB_WARN("ivtvfb_prep_frame: Count not a multiple of 4 (%d)\n", count);
-
- /* Check Source */
- if (!access_ok(VERIFY_READ, source + dest_offset, count)) {
- IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n",
- (unsigned long)source);
-
- IVTVFB_DEBUG_WARN("access_ok() failed for offset 0x%08lx source 0x%08lx count %d\n",
- dest_offset, (unsigned long)source,
- count);
- return -EINVAL;
- }
-
- /* OSD Address to send DMA to */
- dest_offset += IVTV_DECODER_OFFSET + oi->video_rbase;
-
- /* Fill Buffers */
- return ivtvfb_prep_dec_dma_to_device(itv, dest_offset, source, count);
-}
-
-static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- unsigned long p = *ppos;
- void *dst;
- int err = 0;
- int dma_err;
- unsigned long total_size;
- struct ivtv *itv = (struct ivtv *) info->par;
- unsigned long dma_offset =
- IVTV_DECODER_OFFSET + itv->osd_info->video_rbase;
- unsigned long dma_size;
- u16 lead = 0, tail = 0;
-
- if (info->state != FBINFO_STATE_RUNNING)
- return -EPERM;
-
- total_size = info->screen_size;
-
- if (total_size == 0)
- total_size = info->fix.smem_len;
-
- if (p > total_size)
- return -EFBIG;
-
- if (count > total_size) {
- err = -EFBIG;
- count = total_size;
- }
-
- if (count + p > total_size) {
- if (!err)
- err = -ENOSPC;
- count = total_size - p;
- }
-
- dst = (void __force *) (info->screen_base + p);
-
- if (info->fbops->fb_sync)
- info->fbops->fb_sync(info);
-
- /* If transfer size > threshold and both src/dst
- addresses are aligned, use DMA */
- if (count >= 4096 &&
- ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) {
- /* Odd address = can't DMA. Align */
- if ((unsigned long)dst & 3) {
- lead = 4 - ((unsigned long)dst & 3);
- if (copy_from_user(dst, buf, lead))
- return -EFAULT;
- buf += lead;
- dst += lead;
- }
- /* DMA resolution is 32 bits */
- if ((count - lead) & 3)
- tail = (count - lead) & 3;
- /* DMA the data */
- dma_size = count - lead - tail;
- dma_err = ivtvfb_prep_dec_dma_to_device(itv,
- p + lead + dma_offset, (void __user *)buf, dma_size);
- if (dma_err)
- return dma_err;
- dst += dma_size;
- buf += dma_size;
- /* Copy any leftover data */
- if (tail && copy_from_user(dst, buf, tail))
- return -EFAULT;
- } else if (copy_from_user(dst, buf, count)) {
- return -EFAULT;
- }
-
- if (!err)
- *ppos += count;
-
- return (err) ? err : count;
-}
-
-static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
-{
- DEFINE_WAIT(wait);
- struct ivtv *itv = (struct ivtv *)info->par;
- int rc = 0;
-
- switch (cmd) {
- case FBIOGET_VBLANK: {
- struct fb_vblank vblank;
- u32 trace;
-
- memset(&vblank, 0, sizeof(struct fb_vblank));
-
- vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
- FB_VBLANK_HAVE_VSYNC;
- trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16;
- if (itv->is_out_50hz && trace > 312)
- trace -= 312;
- else if (itv->is_out_60hz && trace > 262)
- trace -= 262;
- if (trace == 1)
- vblank.flags |= FB_VBLANK_VSYNCING;
- vblank.count = itv->last_vsync_field;
- vblank.vcount = trace;
- vblank.hcount = 0;
- if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank)))
- return -EFAULT;
- return 0;
- }
-
- case FBIO_WAITFORVSYNC:
- prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE);
- if (!schedule_timeout(msecs_to_jiffies(50)))
- rc = -ETIMEDOUT;
- finish_wait(&itv->vsync_waitq, &wait);
- return rc;
-
- case IVTVFB_IOC_DMA_FRAME: {
- struct ivtvfb_dma_frame args;
-
- IVTVFB_DEBUG_INFO("IVTVFB_IOC_DMA_FRAME\n");
- if (copy_from_user(&args, (void __user *)arg, sizeof(args)))
- return -EFAULT;
-
- return ivtvfb_prep_frame(itv, cmd, args.source, args.dest_offset, args.count);
- }
-
- default:
- IVTVFB_DEBUG_INFO("Unknown ioctl %08x\n", cmd);
- return -EINVAL;
- }
- return 0;
-}
-
-/* Framebuffer device handling */
-
-static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
-{
- struct osd_info *oi = itv->osd_info;
- struct ivtv_osd_coords ivtv_osd;
- struct v4l2_rect ivtv_window;
- int osd_mode = -1;
-
- IVTVFB_DEBUG_INFO("ivtvfb_set_var\n");
-
- /* Select color space */
- if (var->nonstd) /* YUV */
- write_reg(read_reg(0x02a00) | 0x0002000, 0x02a00);
- else /* RGB */
- write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00);
-
- /* Set the color mode */
- switch (var->bits_per_pixel) {
- case 8:
- osd_mode = IVTV_OSD_BPP_8;
- break;
- case 32:
- osd_mode = IVTV_OSD_BPP_32;
- break;
- case 16:
- switch (var->green.length) {
- case 4:
- osd_mode = IVTV_OSD_BPP_16_444;
- break;
- case 5:
- osd_mode = IVTV_OSD_BPP_16_555;
- break;
- case 6:
- osd_mode = IVTV_OSD_BPP_16_565;
- break;
- default:
- IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
- }
- break;
- default:
- IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
- }
-
- /* Set video mode. Although rare, the display can become scrambled even
- if we don't change mode. Always 'bounce' to osd_mode via mode 0 */
- if (osd_mode != -1) {
- ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0);
- ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode);
- }
-
- oi->bits_per_pixel = var->bits_per_pixel;
- oi->bytes_per_pixel = var->bits_per_pixel / 8;
-
- /* Set the flicker filter */
- switch (var->vmode & FB_VMODE_MASK) {
- case FB_VMODE_NONINTERLACED: /* Filter on */
- ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 1);
- break;
- case FB_VMODE_INTERLACED: /* Filter off */
- ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 0);
- break;
- default:
- IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid video mode\n");
- }
-
- /* Read the current osd info */
- ivtvfb_get_osd_coords(itv, &ivtv_osd);
-
- /* Now set the OSD to the size we want */
- ivtv_osd.pixel_stride = var->xres_virtual;
- ivtv_osd.lines = var->yres_virtual;
- ivtv_osd.x = 0;
- ivtv_osd.y = 0;
- ivtvfb_set_osd_coords(itv, &ivtv_osd);
-
- /* Can't seem to find the right API combo for this.
- Use another function which does what we need through direct register access. */
- ivtv_window.width = var->xres;
- ivtv_window.height = var->yres;
-
- /* Minimum margin cannot be 0, as X won't allow such a mode */
- if (!var->upper_margin)
- var->upper_margin++;
- if (!var->left_margin)
- var->left_margin++;
- ivtv_window.top = var->upper_margin - 1;
- ivtv_window.left = var->left_margin - 1;
-
- ivtvfb_set_display_window(itv, &ivtv_window);
-
- /* Pass screen size back to yuv handler */
- itv->yuv_info.osd_full_w = ivtv_osd.pixel_stride;
- itv->yuv_info.osd_full_h = ivtv_osd.lines;
-
- /* Force update of yuv registers */
- itv->yuv_info.yuv_forced_update = 1;
-
- /* Keep a copy of these settings */
- memcpy(&oi->fbvar_cur, var, sizeof(oi->fbvar_cur));
-
- IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
- var->xres, var->yres,
- var->xres_virtual, var->yres_virtual,
- var->bits_per_pixel);
-
- IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
- var->left_margin, var->upper_margin);
-
- IVTVFB_DEBUG_INFO("Display filter: %s\n",
- (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
- IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
-
- return 0;
-}
-
-static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix)
-{
- struct osd_info *oi = itv->osd_info;
-
- IVTVFB_DEBUG_INFO("ivtvfb_get_fix\n");
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
- strlcpy(fix->id, "cx23415 TV out", sizeof(fix->id));
- fix->smem_start = oi->video_pbase;
- fix->smem_len = oi->video_buffer_size;
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->visual = (oi->bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
- fix->xpanstep = 1;
- fix->ypanstep = 1;
- fix->ywrapstep = 0;
- fix->line_length = oi->display_byte_stride;
- fix->accel = FB_ACCEL_NONE;
- return 0;
-}
-
-/* Check the requested display mode, returning -EINVAL if we can't
- handle it. */
-
-static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
-{
- struct osd_info *oi = itv->osd_info;
- int osd_height_limit;
- u32 pixclock, hlimit, vlimit;
-
- IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
-
- /* Set base references for mode calcs. */
- if (itv->is_out_50hz) {
- pixclock = 84316;
- hlimit = 776;
- vlimit = 591;
- osd_height_limit = 576;
- }
- else {
- pixclock = 83926;
- hlimit = 776;
- vlimit = 495;
- osd_height_limit = 480;
- }
-
- if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) {
- var->transp.offset = 24;
- var->transp.length = 8;
- var->red.offset = 16;
- var->red.length = 8;
- var->green.offset = 8;
- var->green.length = 8;
- var->blue.offset = 0;
- var->blue.length = 8;
- }
- else if (var->bits_per_pixel == 16) {
- /* To find out the true mode, check green length */
- switch (var->green.length) {
- case 4:
- var->red.offset = 8;
- var->red.length = 4;
- var->green.offset = 4;
- var->green.length = 4;
- var->blue.offset = 0;
- var->blue.length = 4;
- var->transp.offset = 12;
- var->transp.length = 1;
- break;
- case 5:
- var->red.offset = 10;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 5;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = 15;
- var->transp.length = 1;
- break;
- default:
- var->red.offset = 11;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 6;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = 0;
- var->transp.length = 0;
- break;
- }
- }
- else {
- IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
- return -EINVAL;
- }
-
- /* Check the resolution */
- if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
- IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
- var->xres, var->yres);
- return -EINVAL;
- }
-
- /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
- if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
- var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
- var->xres_virtual < var->xres ||
- var->yres_virtual < var->yres) {
- IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
- var->xres_virtual, var->yres_virtual);
- return -EINVAL;
- }
-
- /* Some extra checks if in 8 bit mode */
- if (var->bits_per_pixel == 8) {
- /* Width must be a multiple of 4 */
- if (var->xres & 3) {
- IVTVFB_DEBUG_WARN("Invalid resolution for 8bpp: %d\n", var->xres);
- return -EINVAL;
- }
- if (var->xres_virtual & 3) {
- IVTVFB_DEBUG_WARN("Invalid virtual resolution for 8bpp: %d)\n", var->xres_virtual);
- return -EINVAL;
- }
- }
- else if (var->bits_per_pixel == 16) {
- /* Width must be a multiple of 2 */
- if (var->xres & 1) {
- IVTVFB_DEBUG_WARN("Invalid resolution for 16bpp: %d\n", var->xres);
- return -EINVAL;
- }
- if (var->xres_virtual & 1) {
- IVTVFB_DEBUG_WARN("Invalid virtual resolution for 16bpp: %d)\n", var->xres_virtual);
- return -EINVAL;
- }
- }
-
- /* Now check the offsets */
- if (var->xoffset >= var->xres_virtual || var->yoffset >= var->yres_virtual) {
- IVTVFB_DEBUG_WARN("Invalid offset: %d (%d) %d (%d)\n",
- var->xoffset, var->xres_virtual, var->yoffset, var->yres_virtual);
- return -EINVAL;
- }
-
- /* Check pixel format */
- if (var->nonstd > 1) {
- IVTVFB_DEBUG_WARN("Invalid nonstd % d\n", var->nonstd);
- return -EINVAL;
- }
-
- /* Check video mode */
- if (((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) &&
- ((var->vmode & FB_VMODE_MASK) != FB_VMODE_INTERLACED)) {
- IVTVFB_DEBUG_WARN("Invalid video mode: %d\n", var->vmode & FB_VMODE_MASK);
- return -EINVAL;
- }
-
- /* Check the left & upper margins
- If the margins are too large, just center the screen
- (enforcing margins causes too many problems) */
-
- if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1)
- var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2);
-
- if (var->upper_margin + var->yres > (itv->is_out_50hz ? 577 : 481))
- var->upper_margin = 1 + (((itv->is_out_50hz ? 576 : 480) -
- var->yres) / 2);
-
- /* Maintain overall 'size' for a constant refresh rate */
- var->right_margin = hlimit - var->left_margin - var->xres;
- var->lower_margin = vlimit - var->upper_margin - var->yres;
-
- /* Fixed sync times */
- var->hsync_len = 24;
- var->vsync_len = 2;
-
- /* Non-interlaced / interlaced mode is used to switch the OSD filter
- on or off. Adjust the clock timings to maintain a constant
- vertical refresh rate. */
- if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
- var->pixclock = pixclock / 2;
- else
- var->pixclock = pixclock;
-
- itv->osd_rect.width = var->xres;
- itv->osd_rect.height = var->yres;
-
- IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
- var->xres, var->yres,
- var->xres_virtual, var->yres_virtual,
- var->bits_per_pixel);
-
- IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
- var->left_margin, var->upper_margin);
-
- IVTVFB_DEBUG_INFO("Display filter: %s\n",
- (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
- IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
- return 0;
-}
-
-static int ivtvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
- struct ivtv *itv = (struct ivtv *) info->par;
- IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
- return _ivtvfb_check_var(var, itv);
-}
-
-static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
-{
- u32 osd_pan_index;
- struct ivtv *itv = (struct ivtv *) info->par;
-
- if (var->yoffset + info->var.yres > info->var.yres_virtual ||
- var->xoffset + info->var.xres > info->var.xres_virtual)
- return -EINVAL;
-
- osd_pan_index = var->yoffset * info->fix.line_length
- + var->xoffset * info->var.bits_per_pixel / 8;
- write_reg(osd_pan_index, 0x02A0C);
-
- /* Pass this info back the yuv handler */
- itv->yuv_info.osd_x_pan = var->xoffset;
- itv->yuv_info.osd_y_pan = var->yoffset;
- /* Force update of yuv registers */
- itv->yuv_info.yuv_forced_update = 1;
- /* Remember this value */
- itv->osd_info->pan_cur = osd_pan_index;
- return 0;
-}
-
-static int ivtvfb_set_par(struct fb_info *info)
-{
- int rc = 0;
- struct ivtv *itv = (struct ivtv *) info->par;
-
- IVTVFB_DEBUG_INFO("ivtvfb_set_par\n");
-
- rc = ivtvfb_set_var(itv, &info->var);
- ivtvfb_pan_display(&info->var, info);
- ivtvfb_get_fix(itv, &info->fix);
- ivtv_firmware_check(itv, "ivtvfb_set_par");
- return rc;
-}
-
-static int ivtvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info)
-{
- u32 color, *palette;
- struct ivtv *itv = (struct ivtv *)info->par;
-
- if (regno >= info->cmap.len)
- return -EINVAL;
-
- color = ((transp & 0xFF00) << 16) |((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8);
- if (info->var.bits_per_pixel <= 8) {
- write_reg(regno, 0x02a30);
- write_reg(color, 0x02a34);
- itv->osd_info->palette_cur[regno] = color;
- return 0;
- }
- if (regno >= 16)
- return -EINVAL;
-
- palette = info->pseudo_palette;
- if (info->var.bits_per_pixel == 16) {
- switch (info->var.green.length) {
- case 4:
- color = ((red & 0xf000) >> 4) |
- ((green & 0xf000) >> 8) |
- ((blue & 0xf000) >> 12);
- break;
- case 5:
- color = ((red & 0xf800) >> 1) |
- ((green & 0xf800) >> 6) |
- ((blue & 0xf800) >> 11);
- break;
- case 6:
- color = (red & 0xf800 ) |
- ((green & 0xfc00) >> 5) |
- ((blue & 0xf800) >> 11);
- break;
- }
- }
- palette[regno] = color;
- return 0;
-}
-
-/* We don't really support blanking. All this does is enable or
- disable the OSD. */
-static int ivtvfb_blank(int blank_mode, struct fb_info *info)
-{
- struct ivtv *itv = (struct ivtv *)info->par;
-
- IVTVFB_DEBUG_INFO("Set blanking mode : %d\n", blank_mode);
- switch (blank_mode) {
- case FB_BLANK_UNBLANK:
- ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1);
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
- break;
- case FB_BLANK_NORMAL:
- case FB_BLANK_HSYNC_SUSPEND:
- case FB_BLANK_VSYNC_SUSPEND:
- ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
- break;
- case FB_BLANK_POWERDOWN:
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
- ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
- break;
- }
- itv->osd_info->blank_cur = blank_mode;
- return 0;
-}
-
-static struct fb_ops ivtvfb_ops = {
- .owner = THIS_MODULE,
- .fb_write = ivtvfb_write,
- .fb_check_var = ivtvfb_check_var,
- .fb_set_par = ivtvfb_set_par,
- .fb_setcolreg = ivtvfb_setcolreg,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_cursor = NULL,
- .fb_ioctl = ivtvfb_ioctl,
- .fb_pan_display = ivtvfb_pan_display,
- .fb_blank = ivtvfb_blank,
-};
-
-/* Restore hardware after firmware restart */
-static void ivtvfb_restore(struct ivtv *itv)
-{
- struct osd_info *oi = itv->osd_info;
- int i;
-
- ivtvfb_set_var(itv, &oi->fbvar_cur);
- ivtvfb_blank(oi->blank_cur, &oi->ivtvfb_info);
- for (i = 0; i < 256; i++) {
- write_reg(i, 0x02a30);
- write_reg(oi->palette_cur[i], 0x02a34);
- }
- write_reg(oi->pan_cur, 0x02a0c);
-}
-
-/* Initialization */
-
-
-/* Setup our initial video mode */
-static int ivtvfb_init_vidmode(struct ivtv *itv)
-{
- struct osd_info *oi = itv->osd_info;
- struct v4l2_rect start_window;
- int max_height;
-
- /* Color mode */
-
- if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32)
- osd_depth = 8;
- oi->bits_per_pixel = osd_depth;
- oi->bytes_per_pixel = oi->bits_per_pixel / 8;
-
- /* Horizontal size & position */
-
- if (osd_xres > 720)
- osd_xres = 720;
-
- /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */
- if (osd_depth == 8)
- osd_xres &= ~3;
- else if (osd_depth == 16)
- osd_xres &= ~1;
-
- start_window.width = osd_xres ? osd_xres : 640;
-
- /* Check horizontal start (osd_left). */
- if (osd_left && osd_left + start_window.width > 721) {
- IVTVFB_ERR("Invalid osd_left - assuming default\n");
- osd_left = 0;
- }
-
- /* Hardware coords start at 0, user coords start at 1. */
- osd_left--;
-
- start_window.left = osd_left >= 0 ?
- osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
-
- oi->display_byte_stride =
- start_window.width * oi->bytes_per_pixel;
-
- /* Vertical size & position */
-
- max_height = itv->is_out_50hz ? 576 : 480;
-
- if (osd_yres > max_height)
- osd_yres = max_height;
-
- start_window.height = osd_yres ?
- osd_yres : itv->is_out_50hz ? 480 : 400;
-
- /* Check vertical start (osd_upper). */
- if (osd_upper + start_window.height > max_height + 1) {
- IVTVFB_ERR("Invalid osd_upper - assuming default\n");
- osd_upper = 0;
- }
-
- /* Hardware coords start at 0, user coords start at 1. */
- osd_upper--;
-
- start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2);
-
- oi->display_width = start_window.width;
- oi->display_height = start_window.height;
-
- /* Generate a valid fb_var_screeninfo */
-
- oi->ivtvfb_defined.xres = oi->display_width;
- oi->ivtvfb_defined.yres = oi->display_height;
- oi->ivtvfb_defined.xres_virtual = oi->display_width;
- oi->ivtvfb_defined.yres_virtual = oi->display_height;
- oi->ivtvfb_defined.bits_per_pixel = oi->bits_per_pixel;
- oi->ivtvfb_defined.vmode = (osd_laced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED);
- oi->ivtvfb_defined.left_margin = start_window.left + 1;
- oi->ivtvfb_defined.upper_margin = start_window.top + 1;
- oi->ivtvfb_defined.accel_flags = FB_ACCEL_NONE;
- oi->ivtvfb_defined.nonstd = 0;
-
- /* We've filled in the most data, let the usual mode check
- routine fill in the rest. */
- _ivtvfb_check_var(&oi->ivtvfb_defined, itv);
-
- /* Generate valid fb_fix_screeninfo */
-
- ivtvfb_get_fix(itv, &oi->ivtvfb_fix);
-
- /* Generate valid fb_info */
-
- oi->ivtvfb_info.node = -1;
- oi->ivtvfb_info.flags = FBINFO_FLAG_DEFAULT;
- oi->ivtvfb_info.fbops = &ivtvfb_ops;
- oi->ivtvfb_info.par = itv;
- oi->ivtvfb_info.var = oi->ivtvfb_defined;
- oi->ivtvfb_info.fix = oi->ivtvfb_fix;
- oi->ivtvfb_info.screen_base = (u8 __iomem *)oi->video_vbase;
- oi->ivtvfb_info.fbops = &ivtvfb_ops;
-
- /* Supply some monitor specs. Bogus values will do for now */
- oi->ivtvfb_info.monspecs.hfmin = 8000;
- oi->ivtvfb_info.monspecs.hfmax = 70000;
- oi->ivtvfb_info.monspecs.vfmin = 10;
- oi->ivtvfb_info.monspecs.vfmax = 100;
-
- /* Allocate color map */
- if (fb_alloc_cmap(&oi->ivtvfb_info.cmap, 256, 1)) {
- IVTVFB_ERR("abort, unable to alloc cmap\n");
- return -ENOMEM;
- }
-
- /* Allocate the pseudo palette */
- oi->ivtvfb_info.pseudo_palette =
- kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN);
-
- if (!oi->ivtvfb_info.pseudo_palette) {
- IVTVFB_ERR("abort, unable to alloc pseudo palette\n");
- return -ENOMEM;
- }
-
- return 0;
-}
-
-/* Find OSD buffer base & size. Add to mtrr. Zero osd buffer. */
-
-static int ivtvfb_init_io(struct ivtv *itv)
-{
- struct osd_info *oi = itv->osd_info;
-
- mutex_lock(&itv->serialize_lock);
- if (ivtv_init_on_first_open(itv)) {
- mutex_unlock(&itv->serialize_lock);
- IVTVFB_ERR("Failed to initialize ivtv\n");
- return -ENXIO;
- }
- mutex_unlock(&itv->serialize_lock);
-
- if (ivtvfb_get_framebuffer(itv, &oi->video_rbase,
- &oi->video_buffer_size) < 0) {
- IVTVFB_ERR("Firmware failed to respond\n");
- return -EIO;
- }
-
- /* The osd buffer size depends on the number of video buffers allocated
- on the PVR350 itself. For now we'll hardcode the smallest osd buffer
- size to prevent any overlap. */
- oi->video_buffer_size = 1704960;
-
- oi->video_pbase = itv->base_addr + IVTV_DECODER_OFFSET + oi->video_rbase;
- oi->video_vbase = itv->dec_mem + oi->video_rbase;
-
- if (!oi->video_vbase) {
- IVTVFB_ERR("abort, video memory 0x%x @ 0x%lx isn't mapped!\n",
- oi->video_buffer_size, oi->video_pbase);
- return -EIO;
- }
-
- IVTVFB_INFO("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
- oi->video_pbase, oi->video_vbase,
- oi->video_buffer_size / 1024);
-
-#ifdef CONFIG_MTRR
- {
- /* Find the largest power of two that maps the whole buffer */
- int size_shift = 31;
-
- while (!(oi->video_buffer_size & (1 << size_shift))) {
- size_shift--;
- }
- size_shift++;
- oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
- oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
- oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
- oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
- if (mtrr_add(oi->fb_start_aligned_physaddr,
- oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr,
- MTRR_TYPE_WRCOMB, 1) < 0) {
- IVTVFB_INFO("disabled mttr\n");
- oi->fb_start_aligned_physaddr = 0;
- oi->fb_end_aligned_physaddr = 0;
- }
- }
-#endif
-
- /* Blank the entire osd. */
- memset_io(oi->video_vbase, 0, oi->video_buffer_size);
-
- return 0;
-}
-
-/* Release any memory we've grabbed & remove mtrr entry */
-static void ivtvfb_release_buffers (struct ivtv *itv)
-{
- struct osd_info *oi = itv->osd_info;
-
- /* Release cmap */
- if (oi->ivtvfb_info.cmap.len)
- fb_dealloc_cmap(&oi->ivtvfb_info.cmap);
-
- /* Release pseudo palette */
- if (oi->ivtvfb_info.pseudo_palette)
- kfree(oi->ivtvfb_info.pseudo_palette);
-
-#ifdef CONFIG_MTRR
- if (oi->fb_end_aligned_physaddr) {
- mtrr_del(-1, oi->fb_start_aligned_physaddr,
- oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr);
- }
-#endif
-
- kfree(oi);
- itv->osd_info = NULL;
-}
-
-/* Initialize the specified card */
-
-static int ivtvfb_init_card(struct ivtv *itv)
-{
- int rc;
-
- if (itv->osd_info) {
- IVTVFB_ERR("Card %d already initialised\n", ivtvfb_card_id);
- return -EBUSY;
- }
-
- itv->osd_info = kzalloc(sizeof(struct osd_info),
- GFP_ATOMIC|__GFP_NOWARN);
- if (itv->osd_info == NULL) {
- IVTVFB_ERR("Failed to allocate memory for osd_info\n");
- return -ENOMEM;
- }
-
- /* Find & setup the OSD buffer */
- rc = ivtvfb_init_io(itv);
- if (rc) {
- ivtvfb_release_buffers(itv);
- return rc;
- }
-
- /* Set the startup video mode information */
- if ((rc = ivtvfb_init_vidmode(itv))) {
- ivtvfb_release_buffers(itv);
- return rc;
- }
-
- /* Register the framebuffer */
- if (register_framebuffer(&itv->osd_info->ivtvfb_info) < 0) {
- ivtvfb_release_buffers(itv);
- return -EINVAL;
- }
-
- itv->osd_video_pbase = itv->osd_info->video_pbase;
-
- /* Set the card to the requested mode */
- ivtvfb_set_par(&itv->osd_info->ivtvfb_info);
-
- /* Set color 0 to black */
- write_reg(0, 0x02a30);
- write_reg(0, 0x02a34);
-
- /* Enable the osd */
- ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
-
- /* Enable restart */
- itv->ivtvfb_restore = ivtvfb_restore;
-
- /* Allocate DMA */
- ivtv_udma_alloc(itv);
- return 0;
-
-}
-
-static int __init ivtvfb_callback_init(struct device *dev, void *p)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
- struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
-
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
- if (ivtvfb_init_card(itv) == 0) {
- IVTVFB_INFO("Framebuffer registered on %s\n",
- itv->v4l2_dev.name);
- (*(int *)p)++;
- }
- }
- return 0;
-}
-
-static int ivtvfb_callback_cleanup(struct device *dev, void *p)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
- struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
- struct osd_info *oi = itv->osd_info;
-
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
- if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
- IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n",
- itv->instance);
- return 0;
- }
- IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
- itv->ivtvfb_restore = NULL;
- ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);
- ivtvfb_release_buffers(itv);
- itv->osd_video_pbase = 0;
- }
- return 0;
-}
-
-static int __init ivtvfb_init(void)
-{
- struct device_driver *drv;
- int registered = 0;
- int err;
-
- if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
- printk(KERN_ERR "ivtvfb: ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
- IVTV_MAX_CARDS - 1);
- return -EINVAL;
- }
-
- drv = driver_find("ivtv", &pci_bus_type);
- err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init);
- (void)err; /* suppress compiler warning */
- if (!registered) {
- printk(KERN_ERR "ivtvfb: no cards found\n");
- return -ENODEV;
- }
- return 0;
-}
-
-static void ivtvfb_cleanup(void)
-{
- struct device_driver *drv;
- int err;
-
- printk(KERN_INFO "ivtvfb: Unloading framebuffer module\n");
-
- drv = driver_find("ivtv", &pci_bus_type);
- err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup);
- (void)err; /* suppress compiler warning */
-}
-
-module_init(ivtvfb_init);
-module_exit(ivtvfb_cleanup);
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
deleted file mode 100644
index ee7ca2dcca2..00000000000
--- a/drivers/media/video/ks0127.c
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- * Video Capture Driver (Video for Linux 1/2)
- * for the Matrox Marvel G200,G400 and Rainbow Runner-G series
- *
- * This module is an interface to the KS0127 video decoder chip.
- *
- * Copyright (C) 1999 Ryan Drake <stiletto@mediaone.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *****************************************************************************
- *
- * Modified and extended by
- * Mike Bernson <mike@mlb.org>
- * Gerard v.d. Horst
- * Leon van Stuivenberg <l.vanstuivenberg@chello.nl>
- * Gernot Ziegler <gz@lysator.liu.se>
- *
- * Version History:
- * V1.0 Ryan Drake Initial version by Ryan Drake
- * V1.1 Gerard v.d. Horst Added some debugoutput, reset the video-standard
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include "ks0127.h"
-
-MODULE_DESCRIPTION("KS0127 video decoder driver");
-MODULE_AUTHOR("Ryan Drake");
-MODULE_LICENSE("GPL");
-
-/* Addresses */
-#define I2C_KS0127_ADDON 0xD8
-#define I2C_KS0127_ONBOARD 0xDA
-
-
-/* ks0127 control registers */
-#define KS_STAT 0x00
-#define KS_CMDA 0x01
-#define KS_CMDB 0x02
-#define KS_CMDC 0x03
-#define KS_CMDD 0x04
-#define KS_HAVB 0x05
-#define KS_HAVE 0x06
-#define KS_HS1B 0x07
-#define KS_HS1E 0x08
-#define KS_HS2B 0x09
-#define KS_HS2E 0x0a
-#define KS_AGC 0x0b
-#define KS_HXTRA 0x0c
-#define KS_CDEM 0x0d
-#define KS_PORTAB 0x0e
-#define KS_LUMA 0x0f
-#define KS_CON 0x10
-#define KS_BRT 0x11
-#define KS_CHROMA 0x12
-#define KS_CHROMB 0x13
-#define KS_DEMOD 0x14
-#define KS_SAT 0x15
-#define KS_HUE 0x16
-#define KS_VERTIA 0x17
-#define KS_VERTIB 0x18
-#define KS_VERTIC 0x19
-#define KS_HSCLL 0x1a
-#define KS_HSCLH 0x1b
-#define KS_VSCLL 0x1c
-#define KS_VSCLH 0x1d
-#define KS_OFMTA 0x1e
-#define KS_OFMTB 0x1f
-#define KS_VBICTL 0x20
-#define KS_CCDAT2 0x21
-#define KS_CCDAT1 0x22
-#define KS_VBIL30 0x23
-#define KS_VBIL74 0x24
-#define KS_VBIL118 0x25
-#define KS_VBIL1512 0x26
-#define KS_TTFRAM 0x27
-#define KS_TESTA 0x28
-#define KS_UVOFFH 0x29
-#define KS_UVOFFL 0x2a
-#define KS_UGAIN 0x2b
-#define KS_VGAIN 0x2c
-#define KS_VAVB 0x2d
-#define KS_VAVE 0x2e
-#define KS_CTRACK 0x2f
-#define KS_POLCTL 0x30
-#define KS_REFCOD 0x31
-#define KS_INVALY 0x32
-#define KS_INVALU 0x33
-#define KS_INVALV 0x34
-#define KS_UNUSEY 0x35
-#define KS_UNUSEU 0x36
-#define KS_UNUSEV 0x37
-#define KS_USRSAV 0x38
-#define KS_USREAV 0x39
-#define KS_SHS1A 0x3a
-#define KS_SHS1B 0x3b
-#define KS_SHS1C 0x3c
-#define KS_CMDE 0x3d
-#define KS_VSDEL 0x3e
-#define KS_CMDF 0x3f
-#define KS_GAMMA0 0x40
-#define KS_GAMMA1 0x41
-#define KS_GAMMA2 0x42
-#define KS_GAMMA3 0x43
-#define KS_GAMMA4 0x44
-#define KS_GAMMA5 0x45
-#define KS_GAMMA6 0x46
-#define KS_GAMMA7 0x47
-#define KS_GAMMA8 0x48
-#define KS_GAMMA9 0x49
-#define KS_GAMMA10 0x4a
-#define KS_GAMMA11 0x4b
-#define KS_GAMMA12 0x4c
-#define KS_GAMMA13 0x4d
-#define KS_GAMMA14 0x4e
-#define KS_GAMMA15 0x4f
-#define KS_GAMMA16 0x50
-#define KS_GAMMA17 0x51
-#define KS_GAMMA18 0x52
-#define KS_GAMMA19 0x53
-#define KS_GAMMA20 0x54
-#define KS_GAMMA21 0x55
-#define KS_GAMMA22 0x56
-#define KS_GAMMA23 0x57
-#define KS_GAMMA24 0x58
-#define KS_GAMMA25 0x59
-#define KS_GAMMA26 0x5a
-#define KS_GAMMA27 0x5b
-#define KS_GAMMA28 0x5c
-#define KS_GAMMA29 0x5d
-#define KS_GAMMA30 0x5e
-#define KS_GAMMA31 0x5f
-#define KS_GAMMAD0 0x60
-#define KS_GAMMAD1 0x61
-#define KS_GAMMAD2 0x62
-#define KS_GAMMAD3 0x63
-#define KS_GAMMAD4 0x64
-#define KS_GAMMAD5 0x65
-#define KS_GAMMAD6 0x66
-#define KS_GAMMAD7 0x67
-#define KS_GAMMAD8 0x68
-#define KS_GAMMAD9 0x69
-#define KS_GAMMAD10 0x6a
-#define KS_GAMMAD11 0x6b
-#define KS_GAMMAD12 0x6c
-#define KS_GAMMAD13 0x6d
-#define KS_GAMMAD14 0x6e
-#define KS_GAMMAD15 0x6f
-#define KS_GAMMAD16 0x70
-#define KS_GAMMAD17 0x71
-#define KS_GAMMAD18 0x72
-#define KS_GAMMAD19 0x73
-#define KS_GAMMAD20 0x74
-#define KS_GAMMAD21 0x75
-#define KS_GAMMAD22 0x76
-#define KS_GAMMAD23 0x77
-#define KS_GAMMAD24 0x78
-#define KS_GAMMAD25 0x79
-#define KS_GAMMAD26 0x7a
-#define KS_GAMMAD27 0x7b
-#define KS_GAMMAD28 0x7c
-#define KS_GAMMAD29 0x7d
-#define KS_GAMMAD30 0x7e
-#define KS_GAMMAD31 0x7f
-
-
-/****************************************************************************
-* mga_dev : represents one ks0127 chip.
-****************************************************************************/
-
-struct adjust {
- int contrast;
- int bright;
- int hue;
- int ugain;
- int vgain;
-};
-
-struct ks0127 {
- struct v4l2_subdev sd;
- v4l2_std_id norm;
- int ident;
- u8 regs[256];
-};
-
-static inline struct ks0127 *to_ks0127(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct ks0127, sd);
-}
-
-
-static int debug; /* insmod parameter */
-
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug output");
-
-static u8 reg_defaults[64];
-
-static void init_reg_defaults(void)
-{
- static int initialized;
- u8 *table = reg_defaults;
-
- if (initialized)
- return;
- initialized = 1;
-
- table[KS_CMDA] = 0x2c; /* VSE=0, CCIR 601, autodetect standard */
- table[KS_CMDB] = 0x12; /* VALIGN=0, AGC control and input */
- table[KS_CMDC] = 0x00; /* Test options */
- /* clock & input select, write 1 to PORTA */
- table[KS_CMDD] = 0x01;
- table[KS_HAVB] = 0x00; /* HAV Start Control */
- table[KS_HAVE] = 0x00; /* HAV End Control */
- table[KS_HS1B] = 0x10; /* HS1 Start Control */
- table[KS_HS1E] = 0x00; /* HS1 End Control */
- table[KS_HS2B] = 0x00; /* HS2 Start Control */
- table[KS_HS2E] = 0x00; /* HS2 End Control */
- table[KS_AGC] = 0x53; /* Manual setting for AGC */
- table[KS_HXTRA] = 0x00; /* Extra Bits for HAV and HS1/2 */
- table[KS_CDEM] = 0x00; /* Chroma Demodulation Control */
- table[KS_PORTAB] = 0x0f; /* port B is input, port A output GPPORT */
- table[KS_LUMA] = 0x01; /* Luma control */
- table[KS_CON] = 0x00; /* Contrast Control */
- table[KS_BRT] = 0x00; /* Brightness Control */
- table[KS_CHROMA] = 0x2a; /* Chroma control A */
- table[KS_CHROMB] = 0x90; /* Chroma control B */
- table[KS_DEMOD] = 0x00; /* Chroma Demodulation Control & Status */
- table[KS_SAT] = 0x00; /* Color Saturation Control*/
- table[KS_HUE] = 0x00; /* Hue Control */
- table[KS_VERTIA] = 0x00; /* Vertical Processing Control A */
- /* Vertical Processing Control B, luma 1 line delayed */
- table[KS_VERTIB] = 0x12;
- table[KS_VERTIC] = 0x0b; /* Vertical Processing Control C */
- table[KS_HSCLL] = 0x00; /* Horizontal Scaling Ratio Low */
- table[KS_HSCLH] = 0x00; /* Horizontal Scaling Ratio High */
- table[KS_VSCLL] = 0x00; /* Vertical Scaling Ratio Low */
- table[KS_VSCLH] = 0x00; /* Vertical Scaling Ratio High */
- /* 16 bit YCbCr 4:2:2 output; I can't make the bt866 like 8 bit /Sam */
- table[KS_OFMTA] = 0x30;
- table[KS_OFMTB] = 0x00; /* Output Control B */
- /* VBI Decoder Control; 4bit fmt: avoid Y overflow */
- table[KS_VBICTL] = 0x5d;
- table[KS_CCDAT2] = 0x00; /* Read Only register */
- table[KS_CCDAT1] = 0x00; /* Read Only register */
- table[KS_VBIL30] = 0xa8; /* VBI data decoding options */
- table[KS_VBIL74] = 0xaa; /* VBI data decoding options */
- table[KS_VBIL118] = 0x2a; /* VBI data decoding options */
- table[KS_VBIL1512] = 0x00; /* VBI data decoding options */
- table[KS_TTFRAM] = 0x00; /* Teletext frame alignment pattern */
- table[KS_TESTA] = 0x00; /* test register, shouldn't be written */
- table[KS_UVOFFH] = 0x00; /* UV Offset Adjustment High */
- table[KS_UVOFFL] = 0x00; /* UV Offset Adjustment Low */
- table[KS_UGAIN] = 0x00; /* U Component Gain Adjustment */
- table[KS_VGAIN] = 0x00; /* V Component Gain Adjustment */
- table[KS_VAVB] = 0x07; /* VAV Begin */
- table[KS_VAVE] = 0x00; /* VAV End */
- table[KS_CTRACK] = 0x00; /* Chroma Tracking Control */
- table[KS_POLCTL] = 0x41; /* Timing Signal Polarity Control */
- table[KS_REFCOD] = 0x80; /* Reference Code Insertion Control */
- table[KS_INVALY] = 0x10; /* Invalid Y Code */
- table[KS_INVALU] = 0x80; /* Invalid U Code */
- table[KS_INVALV] = 0x80; /* Invalid V Code */
- table[KS_UNUSEY] = 0x10; /* Unused Y Code */
- table[KS_UNUSEU] = 0x80; /* Unused U Code */
- table[KS_UNUSEV] = 0x80; /* Unused V Code */
- table[KS_USRSAV] = 0x00; /* reserved */
- table[KS_USREAV] = 0x00; /* reserved */
- table[KS_SHS1A] = 0x00; /* User Defined SHS1 A */
- /* User Defined SHS1 B, ALT656=1 on 0127B */
- table[KS_SHS1B] = 0x80;
- table[KS_SHS1C] = 0x00; /* User Defined SHS1 C */
- table[KS_CMDE] = 0x00; /* Command Register E */
- table[KS_VSDEL] = 0x00; /* VS Delay Control */
- /* Command Register F, update -immediately- */
- /* (there might come no vsync)*/
- table[KS_CMDF] = 0x02;
-}
-
-
-/* We need to manually read because of a bug in the KS0127 chip.
- *
- * An explanation from kayork@mail.utexas.edu:
- *
- * During I2C reads, the KS0127 only samples for a stop condition
- * during the place where the acknowledge bit should be. Any standard
- * I2C implementation (correctly) throws in another clock transition
- * at the 9th bit, and the KS0127 will not recognize the stop condition
- * and will continue to clock out data.
- *
- * So we have to do the read ourself. Big deal.
- * workaround in i2c-algo-bit
- */
-
-
-static u8 ks0127_read(struct v4l2_subdev *sd, u8 reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- char val = 0;
- struct i2c_msg msgs[] = {
- { client->addr, 0, sizeof(reg), &reg },
- { client->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val }
- };
- int ret;
-
- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
- if (ret != ARRAY_SIZE(msgs))
- v4l2_dbg(1, debug, sd, "read error\n");
-
- return val;
-}
-
-
-static void ks0127_write(struct v4l2_subdev *sd, u8 reg, u8 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ks0127 *ks = to_ks0127(sd);
- char msg[] = { reg, val };
-
- if (i2c_master_send(client, msg, sizeof(msg)) != sizeof(msg))
- v4l2_dbg(1, debug, sd, "write error\n");
-
- ks->regs[reg] = val;
-}
-
-
-/* generic bit-twiddling */
-static void ks0127_and_or(struct v4l2_subdev *sd, u8 reg, u8 and_v, u8 or_v)
-{
- struct ks0127 *ks = to_ks0127(sd);
-
- u8 val = ks->regs[reg];
- val = (val & and_v) | or_v;
- ks0127_write(sd, reg, val);
-}
-
-
-
-/****************************************************************************
-* ks0127 private api
-****************************************************************************/
-static void ks0127_init(struct v4l2_subdev *sd)
-{
- struct ks0127 *ks = to_ks0127(sd);
- u8 *table = reg_defaults;
- int i;
-
- ks->ident = V4L2_IDENT_KS0127;
-
- v4l2_dbg(1, debug, sd, "reset\n");
- msleep(1);
-
- /* initialize all registers to known values */
- /* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */
-
- for (i = 1; i < 33; i++)
- ks0127_write(sd, i, table[i]);
-
- for (i = 35; i < 40; i++)
- ks0127_write(sd, i, table[i]);
-
- for (i = 41; i < 56; i++)
- ks0127_write(sd, i, table[i]);
-
- for (i = 58; i < 64; i++)
- ks0127_write(sd, i, table[i]);
-
-
- if ((ks0127_read(sd, KS_STAT) & 0x80) == 0) {
- ks->ident = V4L2_IDENT_KS0122S;
- v4l2_dbg(1, debug, sd, "ks0122s found\n");
- return;
- }
-
- switch (ks0127_read(sd, KS_CMDE) & 0x0f) {
- case 0:
- v4l2_dbg(1, debug, sd, "ks0127 found\n");
- break;
-
- case 9:
- ks->ident = V4L2_IDENT_KS0127B;
- v4l2_dbg(1, debug, sd, "ks0127B Revision A found\n");
- break;
-
- default:
- v4l2_dbg(1, debug, sd, "unknown revision\n");
- break;
- }
-}
-
-static int ks0127_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct ks0127 *ks = to_ks0127(sd);
-
- switch (input) {
- case KS_INPUT_COMPOSITE_1:
- case KS_INPUT_COMPOSITE_2:
- case KS_INPUT_COMPOSITE_3:
- case KS_INPUT_COMPOSITE_4:
- case KS_INPUT_COMPOSITE_5:
- case KS_INPUT_COMPOSITE_6:
- v4l2_dbg(1, debug, sd,
- "s_routing %d: Composite\n", input);
- /* autodetect 50/60 Hz */
- ks0127_and_or(sd, KS_CMDA, 0xfc, 0x00);
- /* VSE=0 */
- ks0127_and_or(sd, KS_CMDA, ~0x40, 0x00);
- /* set input line */
- ks0127_and_or(sd, KS_CMDB, 0xb0, input);
- /* non-freerunning mode */
- ks0127_and_or(sd, KS_CMDC, 0x70, 0x0a);
- /* analog input */
- ks0127_and_or(sd, KS_CMDD, 0x03, 0x00);
- /* enable chroma demodulation */
- ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x00);
- /* chroma trap, HYBWR=1 */
- ks0127_and_or(sd, KS_LUMA, 0x00,
- (reg_defaults[KS_LUMA])|0x0c);
- /* scaler fullbw, luma comb off */
- ks0127_and_or(sd, KS_VERTIA, 0x08, 0x81);
- /* manual chroma comb .25 .5 .25 */
- ks0127_and_or(sd, KS_VERTIC, 0x0f, 0x90);
-
- /* chroma path delay */
- ks0127_and_or(sd, KS_CHROMB, 0x0f, 0x90);
-
- ks0127_write(sd, KS_UGAIN, reg_defaults[KS_UGAIN]);
- ks0127_write(sd, KS_VGAIN, reg_defaults[KS_VGAIN]);
- ks0127_write(sd, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
- ks0127_write(sd, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
- break;
-
- case KS_INPUT_SVIDEO_1:
- case KS_INPUT_SVIDEO_2:
- case KS_INPUT_SVIDEO_3:
- v4l2_dbg(1, debug, sd,
- "s_routing %d: S-Video\n", input);
- /* autodetect 50/60 Hz */
- ks0127_and_or(sd, KS_CMDA, 0xfc, 0x00);
- /* VSE=0 */
- ks0127_and_or(sd, KS_CMDA, ~0x40, 0x00);
- /* set input line */
- ks0127_and_or(sd, KS_CMDB, 0xb0, input);
- /* non-freerunning mode */
- ks0127_and_or(sd, KS_CMDC, 0x70, 0x0a);
- /* analog input */
- ks0127_and_or(sd, KS_CMDD, 0x03, 0x00);
- /* enable chroma demodulation */
- ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x00);
- ks0127_and_or(sd, KS_LUMA, 0x00,
- reg_defaults[KS_LUMA]);
- /* disable luma comb */
- ks0127_and_or(sd, KS_VERTIA, 0x08,
- (reg_defaults[KS_VERTIA]&0xf0)|0x01);
- ks0127_and_or(sd, KS_VERTIC, 0x0f,
- reg_defaults[KS_VERTIC]&0xf0);
-
- ks0127_and_or(sd, KS_CHROMB, 0x0f,
- reg_defaults[KS_CHROMB]&0xf0);
-
- ks0127_write(sd, KS_UGAIN, reg_defaults[KS_UGAIN]);
- ks0127_write(sd, KS_VGAIN, reg_defaults[KS_VGAIN]);
- ks0127_write(sd, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
- ks0127_write(sd, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
- break;
-
- case KS_INPUT_YUV656:
- v4l2_dbg(1, debug, sd, "s_routing 15: YUV656\n");
- if (ks->norm & V4L2_STD_525_60)
- /* force 60 Hz */
- ks0127_and_or(sd, KS_CMDA, 0xfc, 0x03);
- else
- /* force 50 Hz */
- ks0127_and_or(sd, KS_CMDA, 0xfc, 0x02);
-
- ks0127_and_or(sd, KS_CMDA, 0xff, 0x40); /* VSE=1 */
- /* set input line and VALIGN */
- ks0127_and_or(sd, KS_CMDB, 0xb0, (input | 0x40));
- /* freerunning mode, */
- /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/
- ks0127_and_or(sd, KS_CMDC, 0x70, 0x87);
- /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */
- ks0127_and_or(sd, KS_CMDD, 0x03, 0x08);
- /* disable chroma demodulation */
- ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x30);
- /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */
- ks0127_and_or(sd, KS_LUMA, 0x00, 0x71);
- ks0127_and_or(sd, KS_VERTIC, 0x0f,
- reg_defaults[KS_VERTIC]&0xf0);
-
- /* scaler fullbw, luma comb off */
- ks0127_and_or(sd, KS_VERTIA, 0x08, 0x81);
-
- ks0127_and_or(sd, KS_CHROMB, 0x0f,
- reg_defaults[KS_CHROMB]&0xf0);
-
- ks0127_and_or(sd, KS_CON, 0x00, 0x00);
- ks0127_and_or(sd, KS_BRT, 0x00, 32); /* spec: 34 */
- /* spec: 229 (e5) */
- ks0127_and_or(sd, KS_SAT, 0x00, 0xe8);
- ks0127_and_or(sd, KS_HUE, 0x00, 0);
-
- ks0127_and_or(sd, KS_UGAIN, 0x00, 238);
- ks0127_and_or(sd, KS_VGAIN, 0x00, 0x00);
-
- /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */
- ks0127_and_or(sd, KS_UVOFFH, 0x00, 0x4f);
- ks0127_and_or(sd, KS_UVOFFL, 0x00, 0x00);
- break;
-
- default:
- v4l2_dbg(1, debug, sd,
- "s_routing: Unknown input %d\n", input);
- break;
- }
-
- /* hack: CDMLPF sometimes spontaneously switches on; */
- /* force back off */
- ks0127_write(sd, KS_DEMOD, reg_defaults[KS_DEMOD]);
- return 0;
-}
-
-static int ks0127_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct ks0127 *ks = to_ks0127(sd);
-
- /* Set to automatic SECAM/Fsc mode */
- ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x00);
-
- ks->norm = std;
- if (std & V4L2_STD_NTSC) {
- v4l2_dbg(1, debug, sd,
- "s_std: NTSC_M\n");
- ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x20);
- } else if (std & V4L2_STD_PAL_N) {
- v4l2_dbg(1, debug, sd,
- "s_std: NTSC_N (fixme)\n");
- ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x40);
- } else if (std & V4L2_STD_PAL) {
- v4l2_dbg(1, debug, sd,
- "s_std: PAL_N\n");
- ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x20);
- } else if (std & V4L2_STD_PAL_M) {
- v4l2_dbg(1, debug, sd,
- "s_std: PAL_M (fixme)\n");
- ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x40);
- } else if (std & V4L2_STD_SECAM) {
- v4l2_dbg(1, debug, sd,
- "s_std: SECAM\n");
-
- /* set to secam autodetection */
- ks0127_and_or(sd, KS_CHROMA, 0xdf, 0x20);
- ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x00);
- schedule_timeout_interruptible(HZ/10+1);
-
- /* did it autodetect? */
- if (!(ks0127_read(sd, KS_DEMOD) & 0x40))
- /* force to secam mode */
- ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x0f);
- } else {
- v4l2_dbg(1, debug, sd, "s_std: Unknown norm %llx\n",
- (unsigned long long)std);
- }
- return 0;
-}
-
-static int ks0127_s_stream(struct v4l2_subdev *sd, int enable)
-{
- v4l2_dbg(1, debug, sd, "s_stream(%d)\n", enable);
- if (enable) {
- /* All output pins on */
- ks0127_and_or(sd, KS_OFMTA, 0xcf, 0x30);
- /* Obey the OEN pin */
- ks0127_and_or(sd, KS_CDEM, 0x7f, 0x00);
- } else {
- /* Video output pins off */
- ks0127_and_or(sd, KS_OFMTA, 0xcf, 0x00);
- /* Ignore the OEN pin */
- ks0127_and_or(sd, KS_CDEM, 0x7f, 0x80);
- }
- return 0;
-}
-
-static int ks0127_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
-{
- int stat = V4L2_IN_ST_NO_SIGNAL;
- u8 status;
- v4l2_std_id std = V4L2_STD_ALL;
-
- status = ks0127_read(sd, KS_STAT);
- if (!(status & 0x20)) /* NOVID not set */
- stat = 0;
- if (!(status & 0x01)) /* CLOCK set */
- stat |= V4L2_IN_ST_NO_COLOR;
- if ((status & 0x08)) /* PALDET set */
- std = V4L2_STD_PAL;
- else
- std = V4L2_STD_NTSC;
- if (pstd)
- *pstd = std;
- if (pstatus)
- *pstatus = stat;
- return 0;
-}
-
-static int ks0127_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
-{
- v4l2_dbg(1, debug, sd, "querystd\n");
- return ks0127_status(sd, NULL, std);
-}
-
-static int ks0127_g_input_status(struct v4l2_subdev *sd, u32 *status)
-{
- v4l2_dbg(1, debug, sd, "g_input_status\n");
- return ks0127_status(sd, status, NULL);
-}
-
-static int ks0127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ks0127 *ks = to_ks0127(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, ks->ident, 0);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops ks0127_core_ops = {
- .g_chip_ident = ks0127_g_chip_ident,
- .s_std = ks0127_s_std,
-};
-
-static const struct v4l2_subdev_video_ops ks0127_video_ops = {
- .s_routing = ks0127_s_routing,
- .s_stream = ks0127_s_stream,
- .querystd = ks0127_querystd,
- .g_input_status = ks0127_g_input_status,
-};
-
-static const struct v4l2_subdev_ops ks0127_ops = {
- .core = &ks0127_core_ops,
- .video = &ks0127_video_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-
-static int ks0127_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
- struct ks0127 *ks;
- struct v4l2_subdev *sd;
-
- v4l_info(client, "%s chip found @ 0x%x (%s)\n",
- client->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
- client->addr << 1, client->adapter->name);
-
- ks = kzalloc(sizeof(*ks), GFP_KERNEL);
- if (ks == NULL)
- return -ENOMEM;
- sd = &ks->sd;
- v4l2_i2c_subdev_init(sd, client, &ks0127_ops);
-
- /* power up */
- init_reg_defaults();
- ks0127_write(sd, KS_CMDA, 0x2c);
- mdelay(10);
-
- /* reset the device */
- ks0127_init(sd);
- return 0;
-}
-
-static int ks0127_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- ks0127_write(sd, KS_OFMTA, 0x20); /* tristate */
- ks0127_write(sd, KS_CMDA, 0x2c | 0x80); /* power down */
- kfree(to_ks0127(sd));
- return 0;
-}
-
-static const struct i2c_device_id ks0127_id[] = {
- { "ks0127", 0 },
- { "ks0127b", 0 },
- { "ks0122s", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ks0127_id);
-
-static struct i2c_driver ks0127_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "ks0127",
- },
- .probe = ks0127_probe,
- .remove = ks0127_remove,
- .id_table = ks0127_id,
-};
-
-module_i2c_driver(ks0127_driver);
diff --git a/drivers/media/video/ks0127.h b/drivers/media/video/ks0127.h
deleted file mode 100644
index cb8abd5403b..00000000000
--- a/drivers/media/video/ks0127.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Video Capture Driver ( Video for Linux 1/2 )
- * for the Matrox Marvel G200,G400 and Rainbow Runner-G series
- *
- * This module is an interface to the KS0127 video decoder chip.
- *
- * Copyright (C) 1999 Ryan Drake <stiletto@mediaone.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef KS0127_H
-#define KS0127_H
-
-/* input channels */
-#define KS_INPUT_COMPOSITE_1 0
-#define KS_INPUT_COMPOSITE_2 1
-#define KS_INPUT_COMPOSITE_3 2
-#define KS_INPUT_COMPOSITE_4 4
-#define KS_INPUT_COMPOSITE_5 5
-#define KS_INPUT_COMPOSITE_6 6
-
-#define KS_INPUT_SVIDEO_1 8
-#define KS_INPUT_SVIDEO_2 9
-#define KS_INPUT_SVIDEO_3 10
-
-#define KS_INPUT_YUV656 15
-#define KS_INPUT_COUNT 10
-
-/* output channels */
-#define KS_OUTPUT_YUV656E 0
-#define KS_OUTPUT_EXV 1
-
-/* video standards */
-#define KS_STD_NTSC_N 112 /* 50 Hz NTSC */
-#define KS_STD_PAL_M 113 /* 60 Hz PAL */
-
-#endif /* KS0127_H */
-
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
deleted file mode 100644
index 0991576f4c8..00000000000
--- a/drivers/media/video/m52790.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * m52790 i2c ivtv driver.
- * Copyright (C) 2007 Hans Verkuil
- *
- * A/V source switching Mitsubishi M52790SP/FP
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/m52790.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-
-MODULE_DESCRIPTION("i2c device driver for m52790 A/V switch");
-MODULE_AUTHOR("Hans Verkuil");
-MODULE_LICENSE("GPL");
-
-
-struct m52790_state {
- struct v4l2_subdev sd;
- u16 input;
- u16 output;
-};
-
-static inline struct m52790_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct m52790_state, sd);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int m52790_write(struct v4l2_subdev *sd)
-{
- struct m52790_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- u8 sw1 = (state->input | state->output) & 0xff;
- u8 sw2 = (state->input | state->output) >> 8;
-
- return i2c_smbus_write_byte_data(client, sw1, sw2);
-}
-
-/* Note: audio and video are linked and cannot be switched separately.
- So audio and video routing commands are identical for this chip.
- In theory the video amplifier and audio modes could be handled
- separately for the output, but that seems to be overkill right now.
- The same holds for implementing an audio mute control, this is now
- part of the audio output routing. The normal case is that another
- chip takes care of the actual muting so making it part of the
- output routing seems to be the right thing to do for now. */
-static int m52790_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct m52790_state *state = to_state(sd);
-
- state->input = input;
- state->output = output;
- m52790_write(sd);
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int m52790_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct m52790_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (reg->reg != 0)
- return -EINVAL;
- reg->size = 1;
- reg->val = state->input | state->output;
- return 0;
-}
-
-static int m52790_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct m52790_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (reg->reg != 0)
- return -EINVAL;
- state->input = reg->val & 0x0303;
- state->output = reg->val & ~0x0303;
- m52790_write(sd);
- return 0;
-}
-#endif
-
-static int m52790_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_M52790, 0);
-}
-
-static int m52790_log_status(struct v4l2_subdev *sd)
-{
- struct m52790_state *state = to_state(sd);
-
- v4l2_info(sd, "Switch 1: %02x\n",
- (state->input | state->output) & 0xff);
- v4l2_info(sd, "Switch 2: %02x\n",
- (state->input | state->output) >> 8);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops m52790_core_ops = {
- .log_status = m52790_log_status,
- .g_chip_ident = m52790_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = m52790_g_register,
- .s_register = m52790_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_audio_ops m52790_audio_ops = {
- .s_routing = m52790_s_routing,
-};
-
-static const struct v4l2_subdev_video_ops m52790_video_ops = {
- .s_routing = m52790_s_routing,
-};
-
-static const struct v4l2_subdev_ops m52790_ops = {
- .core = &m52790_core_ops,
- .audio = &m52790_audio_ops,
- .video = &m52790_video_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-/* i2c implementation */
-
-static int m52790_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct m52790_state *state;
- struct v4l2_subdev *sd;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- state = kzalloc(sizeof(struct m52790_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
-
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &m52790_ops);
- state->input = M52790_IN_TUNER;
- state->output = M52790_OUT_STEREO;
- m52790_write(sd);
- return 0;
-}
-
-static int m52790_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(to_state(sd));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id m52790_id[] = {
- { "m52790", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, m52790_id);
-
-static struct i2c_driver m52790_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "m52790",
- },
- .probe = m52790_probe,
- .remove = m52790_remove,
- .id_table = m52790_id,
-};
-
-module_i2c_driver(m52790_driver);
diff --git a/drivers/media/video/m5mols/Kconfig b/drivers/media/video/m5mols/Kconfig
deleted file mode 100644
index dc8c2505907..00000000000
--- a/drivers/media/video/m5mols/Kconfig
+++ /dev/null
@@ -1,6 +0,0 @@
-config VIDEO_M5MOLS
- tristate "Fujitsu M-5MOLS 8MP sensor support"
- depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This driver supports Fujitsu M-5MOLS camera sensor with ISP
diff --git a/drivers/media/video/m5mols/Makefile b/drivers/media/video/m5mols/Makefile
deleted file mode 100644
index 0a44e028edc..00000000000
--- a/drivers/media/video/m5mols/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-m5mols-objs := m5mols_core.o m5mols_controls.o m5mols_capture.o
-
-obj-$(CONFIG_VIDEO_M5MOLS) += m5mols.o
diff --git a/drivers/media/video/m5mols/m5mols.h b/drivers/media/video/m5mols/m5mols.h
deleted file mode 100644
index bb589917b65..00000000000
--- a/drivers/media/video/m5mols/m5mols.h
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Header for M-5MOLS 8M Pixel camera sensor with ISP
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * Author: HeungJun Kim <riverful.kim@samsung.com>
- *
- * Copyright (C) 2009 Samsung Electronics Co., Ltd.
- * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef M5MOLS_H
-#define M5MOLS_H
-
-#include <media/v4l2-subdev.h>
-#include "m5mols_reg.h"
-
-extern int m5mols_debug;
-
-enum m5mols_restype {
- M5MOLS_RESTYPE_MONITOR,
- M5MOLS_RESTYPE_CAPTURE,
- M5MOLS_RESTYPE_MAX,
-};
-
-/**
- * struct m5mols_resolution - structure for the resolution
- * @type: resolution type according to the pixel code
- * @width: width of the resolution
- * @height: height of the resolution
- * @reg: resolution preset register value
- */
-struct m5mols_resolution {
- u8 reg;
- enum m5mols_restype type;
- u16 width;
- u16 height;
-};
-
-/**
- * struct m5mols_exif - structure for the EXIF information of M-5MOLS
- * @exposure_time: exposure time register value
- * @shutter_speed: speed of the shutter register value
- * @aperture: aperture register value
- * @exposure_bias: it calls also EV bias
- * @iso_speed: ISO register value
- * @flash: status register value of the flash
- * @sdr: status register value of the Subject Distance Range
- * @qval: not written exact meaning in document
- */
-struct m5mols_exif {
- u32 exposure_time;
- u32 shutter_speed;
- u32 aperture;
- u32 brightness;
- u32 exposure_bias;
- u16 iso_speed;
- u16 flash;
- u16 sdr;
- u16 qval;
-};
-
-/**
- * struct m5mols_capture - Structure for the capture capability
- * @exif: EXIF information
- * @main: size in bytes of the main image
- * @thumb: size in bytes of the thumb image, if it was accompanied
- * @total: total size in bytes of the produced image
- */
-struct m5mols_capture {
- struct m5mols_exif exif;
- u32 main;
- u32 thumb;
- u32 total;
-};
-
-/**
- * struct m5mols_scenemode - structure for the scenemode capability
- * @metering: metering light register value
- * @ev_bias: EV bias register value
- * @wb_mode: mode which means the WhiteBalance is Auto or Manual
- * @wb_preset: whitebalance preset register value in the Manual mode
- * @chroma_en: register value whether the Chroma capability is enabled or not
- * @chroma_lvl: chroma's level register value
- * @edge_en: register value Whether the Edge capability is enabled or not
- * @edge_lvl: edge's level register value
- * @af_range: Auto Focus's range
- * @fd_mode: Face Detection mode
- * @mcc: Multi-axis Color Conversion which means emotion color
- * @light: status of the Light
- * @flash: status of the Flash
- * @tone: Tone color which means Contrast
- * @iso: ISO register value
- * @capt_mode: Mode of the Image Stabilization while the camera capturing
- * @wdr: Wide Dynamic Range register value
- *
- * The each value according to each scenemode is recommended in the documents.
- */
-struct m5mols_scenemode {
- u8 metering;
- u8 ev_bias;
- u8 wb_mode;
- u8 wb_preset;
- u8 chroma_en;
- u8 chroma_lvl;
- u8 edge_en;
- u8 edge_lvl;
- u8 af_range;
- u8 fd_mode;
- u8 mcc;
- u8 light;
- u8 flash;
- u8 tone;
- u8 iso;
- u8 capt_mode;
- u8 wdr;
-};
-
-/**
- * struct m5mols_version - firmware version information
- * @customer: customer information
- * @project: version of project information according to customer
- * @fw: firmware revision
- * @hw: hardware revision
- * @param: version of the parameter
- * @awb: Auto WhiteBalance algorithm version
- * @str: information about manufacturer and packaging vendor
- * @af: Auto Focus version
- *
- * The register offset starts the customer version at 0x0, and it ends
- * the awb version at 0x09. The customer, project information occupies 1 bytes
- * each. And also the fw, hw, param, awb each requires 2 bytes. The str is
- * unique string associated with firmware's version. It includes information
- * about manufacturer and the vendor of the sensor's packaging. The least
- * significant 2 bytes of the string indicate packaging manufacturer.
- */
-#define VERSION_STRING_SIZE 22
-struct m5mols_version {
- u8 customer;
- u8 project;
- u16 fw;
- u16 hw;
- u16 param;
- u16 awb;
- u8 str[VERSION_STRING_SIZE];
- u8 af;
-};
-
-/**
- * struct m5mols_info - M-5MOLS driver data structure
- * @pdata: platform data
- * @sd: v4l-subdev instance
- * @pad: media pad
- * @ffmt: current fmt according to resolution type
- * @res_type: current resolution type
- * @irq_waitq: waitqueue for the capture
- * @irq_done: set to 1 in the interrupt handler
- * @handle: control handler
- * @auto_exposure: auto/manual exposure control
- * @exposure_bias: exposure compensation control
- * @exposure: manual exposure control
- * @metering: exposure metering control
- * @auto_iso: auto/manual ISO sensitivity control
- * @iso: manual ISO sensitivity control
- * @auto_wb: auto white balance control
- * @lock_3a: 3A lock control
- * @colorfx: color effect control
- * @saturation: saturation control
- * @zoom: zoom control
- * @wdr: wide dynamic range control
- * @stabilization: image stabilization control
- * @jpeg_quality: JPEG compression quality control
- * @ver: information of the version
- * @cap: the capture mode attributes
- * @isp_ready: 1 when the ISP controller has completed booting
- * @power: current sensor's power status
- * @ctrl_sync: 1 when the control handler state is restored in H/W
- * @resolution: register value for current resolution
- * @mode: register value for current operation mode
- * @set_power: optional power callback to the board code
- */
-struct m5mols_info {
- const struct m5mols_platform_data *pdata;
- struct v4l2_subdev sd;
- struct media_pad pad;
- struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX];
- int res_type;
-
- wait_queue_head_t irq_waitq;
- atomic_t irq_done;
-
- struct v4l2_ctrl_handler handle;
- struct {
- /* exposure/exposure bias/auto exposure cluster */
- struct v4l2_ctrl *auto_exposure;
- struct v4l2_ctrl *exposure_bias;
- struct v4l2_ctrl *exposure;
- struct v4l2_ctrl *metering;
- };
- struct {
- /* iso/auto iso cluster */
- struct v4l2_ctrl *auto_iso;
- struct v4l2_ctrl *iso;
- };
- struct v4l2_ctrl *auto_wb;
-
- struct v4l2_ctrl *lock_3a;
- struct v4l2_ctrl *colorfx;
- struct v4l2_ctrl *saturation;
- struct v4l2_ctrl *zoom;
- struct v4l2_ctrl *wdr;
- struct v4l2_ctrl *stabilization;
- struct v4l2_ctrl *jpeg_quality;
-
- struct m5mols_version ver;
- struct m5mols_capture cap;
-
- unsigned int isp_ready:1;
- unsigned int power:1;
- unsigned int ctrl_sync:1;
-
- u8 resolution;
- u8 mode;
-
- int (*set_power)(struct device *dev, int on);
-};
-
-#define is_available_af(__info) (__info->ver.af)
-#define is_code(__code, __type) (__code == m5mols_default_ffmt[__type].code)
-#define is_manufacturer(__info, __manufacturer) \
- (__info->ver.str[0] == __manufacturer[0] && \
- __info->ver.str[1] == __manufacturer[1])
-/*
- * I2C operation of the M-5MOLS
- *
- * The I2C read operation of the M-5MOLS requires 2 messages. The first
- * message sends the information about the command, command category, and total
- * message size. The second message is used to retrieve the data specifed in
- * the first message
- *
- * 1st message 2nd message
- * +-------+---+----------+-----+-------+ +------+------+------+------+
- * | size1 | R | category | cmd | size2 | | d[0] | d[1] | d[2] | d[3] |
- * +-------+---+----------+-----+-------+ +------+------+------+------+
- * - size1: message data size(5 in this case)
- * - size2: desired buffer size of the 2nd message
- * - d[0..3]: according to size2
- *
- * The I2C write operation needs just one message. The message includes
- * category, command, total size, and desired data.
- *
- * 1st message
- * +-------+---+----------+-----+------+------+------+------+
- * | size1 | W | category | cmd | d[0] | d[1] | d[2] | d[3] |
- * +-------+---+----------+-----+------+------+------+------+
- * - d[0..3]: according to size1
- */
-int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg_comb, u8 *val);
-int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg_comb, u16 *val);
-int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg_comb, u32 *val);
-int m5mols_write(struct v4l2_subdev *sd, u32 reg_comb, u32 val);
-
-int m5mols_busy_wait(struct v4l2_subdev *sd, u32 reg, u32 value, u32 mask,
- int timeout);
-
-/* Mask value for busy waiting until M-5MOLS I2C interface is initialized */
-#define M5MOLS_I2C_RDY_WAIT_FL (1 << 16)
-/* ISP state transition timeout, in ms */
-#define M5MOLS_MODE_CHANGE_TIMEOUT 200
-#define M5MOLS_BUSY_WAIT_DEF_TIMEOUT 250
-
-/*
- * Mode operation of the M-5MOLS
- *
- * Changing the mode of the M-5MOLS is needed right executing order.
- * There are three modes(PARAMETER, MONITOR, CAPTURE) which can be changed
- * by user. There are various categories associated with each mode.
- *
- * +============================================================+
- * | mode | category |
- * +============================================================+
- * | FLASH | FLASH(only after Stand-by or Power-on) |
- * | SYSTEM | SYSTEM(only after sensor arm-booting) |
- * | PARAMETER | PARAMETER |
- * | MONITOR | MONITOR(preview), Auto Focus, Face Detection |
- * | CAPTURE | Single CAPTURE, Preview(recording) |
- * +============================================================+
- *
- * The available executing order between each modes are as follows:
- * PARAMETER <---> MONITOR <---> CAPTURE
- */
-int m5mols_set_mode(struct m5mols_info *info, u8 mode);
-
-int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg);
-int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 condition, u32 timeout);
-int m5mols_restore_controls(struct m5mols_info *info);
-int m5mols_start_capture(struct m5mols_info *info);
-int m5mols_do_scenemode(struct m5mols_info *info, u8 mode);
-int m5mols_lock_3a(struct m5mols_info *info, bool lock);
-int m5mols_set_ctrl(struct v4l2_ctrl *ctrl);
-int m5mols_init_controls(struct v4l2_subdev *sd);
-
-/* The firmware function */
-int m5mols_update_fw(struct v4l2_subdev *sd,
- int (*set_power)(struct m5mols_info *, bool));
-
-static inline struct m5mols_info *to_m5mols(struct v4l2_subdev *subdev)
-{
- return container_of(subdev, struct m5mols_info, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- struct m5mols_info *info = container_of(ctrl->handler,
- struct m5mols_info, handle);
- return &info->sd;
-}
-
-static inline void m5mols_set_ctrl_mode(struct v4l2_ctrl *ctrl,
- unsigned int mode)
-{
- ctrl->priv = (void *)mode;
-}
-
-static inline unsigned int m5mols_get_ctrl_mode(struct v4l2_ctrl *ctrl)
-{
- return (unsigned int)ctrl->priv;
-}
-
-#endif /* M5MOLS_H */
diff --git a/drivers/media/video/m5mols/m5mols_capture.c b/drivers/media/video/m5mols/m5mols_capture.c
deleted file mode 100644
index cb243bd278c..00000000000
--- a/drivers/media/video/m5mols/m5mols_capture.c
+++ /dev/null
@@ -1,155 +0,0 @@
-
-/*
- * The Capture code for Fujitsu M-5MOLS ISP
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * Author: HeungJun Kim <riverful.kim@samsung.com>
- *
- * Copyright (C) 2009 Samsung Electronics Co., Ltd.
- * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/regulator/consumer.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include <media/m5mols.h>
-#include <media/s5p_fimc.h>
-
-#include "m5mols.h"
-#include "m5mols_reg.h"
-
-/**
- * m5mols_read_rational - I2C read of a rational number
- *
- * Read numerator and denominator from registers @addr_num and @addr_den
- * respectively and return the division result in @val.
- */
-static int m5mols_read_rational(struct v4l2_subdev *sd, u32 addr_num,
- u32 addr_den, u32 *val)
-{
- u32 num, den;
-
- int ret = m5mols_read_u32(sd, addr_num, &num);
- if (!ret)
- ret = m5mols_read_u32(sd, addr_den, &den);
- if (ret)
- return ret;
- *val = den == 0 ? 0 : num / den;
- return ret;
-}
-
-/**
- * m5mols_capture_info - Gather captured image information
- *
- * For now it gathers only EXIF information and file size.
- */
-static int m5mols_capture_info(struct m5mols_info *info)
-{
- struct m5mols_exif *exif = &info->cap.exif;
- struct v4l2_subdev *sd = &info->sd;
- int ret;
-
- ret = m5mols_read_rational(sd, EXIF_INFO_EXPTIME_NU,
- EXIF_INFO_EXPTIME_DE, &exif->exposure_time);
- if (ret)
- return ret;
- ret = m5mols_read_rational(sd, EXIF_INFO_TV_NU, EXIF_INFO_TV_DE,
- &exif->shutter_speed);
- if (ret)
- return ret;
- ret = m5mols_read_rational(sd, EXIF_INFO_AV_NU, EXIF_INFO_AV_DE,
- &exif->aperture);
- if (ret)
- return ret;
- ret = m5mols_read_rational(sd, EXIF_INFO_BV_NU, EXIF_INFO_BV_DE,
- &exif->brightness);
- if (ret)
- return ret;
- ret = m5mols_read_rational(sd, EXIF_INFO_EBV_NU, EXIF_INFO_EBV_DE,
- &exif->exposure_bias);
- if (ret)
- return ret;
-
- ret = m5mols_read_u16(sd, EXIF_INFO_ISO, &exif->iso_speed);
- if (!ret)
- ret = m5mols_read_u16(sd, EXIF_INFO_FLASH, &exif->flash);
- if (!ret)
- ret = m5mols_read_u16(sd, EXIF_INFO_SDR, &exif->sdr);
- if (!ret)
- ret = m5mols_read_u16(sd, EXIF_INFO_QVAL, &exif->qval);
- if (ret)
- return ret;
-
- if (!ret)
- ret = m5mols_read_u32(sd, CAPC_IMAGE_SIZE, &info->cap.main);
- if (!ret)
- ret = m5mols_read_u32(sd, CAPC_THUMB_SIZE, &info->cap.thumb);
- if (!ret)
- info->cap.total = info->cap.main + info->cap.thumb;
-
- return ret;
-}
-
-int m5mols_start_capture(struct m5mols_info *info)
-{
- struct v4l2_subdev *sd = &info->sd;
- int ret;
-
- /*
- * Synchronize the controls, set the capture frame resolution and color
- * format. The frame capture is initiated during switching from Monitor
- * to Capture mode.
- */
- ret = m5mols_set_mode(info, REG_MONITOR);
- if (!ret)
- ret = m5mols_restore_controls(info);
- if (!ret)
- ret = m5mols_write(sd, CAPP_YUVOUT_MAIN, REG_JPEG);
- if (!ret)
- ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, info->resolution);
- if (!ret)
- ret = m5mols_set_mode(info, REG_CAPTURE);
- if (!ret)
- /* Wait until a frame is captured to ISP internal memory */
- ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
- if (ret)
- return ret;
-
- /*
- * Initiate the captured data transfer to a MIPI-CSI receiver.
- */
- ret = m5mols_write(sd, CAPC_SEL_FRAME, 1);
- if (!ret)
- ret = m5mols_write(sd, CAPC_START, REG_CAP_START_MAIN);
- if (!ret) {
- bool captured = false;
- unsigned int size;
-
- /* Wait for the capture completion interrupt */
- ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
- if (!ret) {
- captured = true;
- ret = m5mols_capture_info(info);
- }
- size = captured ? info->cap.main : 0;
- v4l2_dbg(1, m5mols_debug, sd, "%s: size: %d, thumb.: %d B\n",
- __func__, size, info->cap.thumb);
-
- v4l2_subdev_notify(sd, S5P_FIMC_TX_END_NOTIFY, &size);
- }
-
- return ret;
-}
diff --git a/drivers/media/video/m5mols/m5mols_controls.c b/drivers/media/video/m5mols/m5mols_controls.c
deleted file mode 100644
index fdbc205a296..00000000000
--- a/drivers/media/video/m5mols/m5mols_controls.c
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * Controls for M-5MOLS 8M Pixel camera sensor with ISP
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * Author: HeungJun Kim <riverful.kim@samsung.com>
- *
- * Copyright (C) 2009 Samsung Electronics Co., Ltd.
- * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-ctrls.h>
-
-#include "m5mols.h"
-#include "m5mols_reg.h"
-
-static struct m5mols_scenemode m5mols_default_scenemode[] = {
- [REG_SCENE_NORMAL] = {
- REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
- REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
- REG_AF_NORMAL, REG_FD_OFF,
- REG_MCC_NORMAL, REG_LIGHT_OFF, REG_FLASH_OFF,
- 5, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
- },
- [REG_SCENE_PORTRAIT] = {
- REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
- REG_CHROMA_ON, 3, REG_EDGE_ON, 4,
- REG_AF_NORMAL, BIT_FD_EN | BIT_FD_DRAW_FACE_FRAME,
- REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
- 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
- },
- [REG_SCENE_LANDSCAPE] = {
- REG_AE_ALL, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
- REG_CHROMA_ON, 4, REG_EDGE_ON, 6,
- REG_AF_NORMAL, REG_FD_OFF,
- REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
- 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
- },
- [REG_SCENE_SPORTS] = {
- REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
- REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
- REG_AF_NORMAL, REG_FD_OFF,
- REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
- 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
- },
- [REG_SCENE_PARTY_INDOOR] = {
- REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
- REG_CHROMA_ON, 4, REG_EDGE_ON, 5,
- REG_AF_NORMAL, REG_FD_OFF,
- REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
- 6, REG_ISO_200, REG_CAP_NONE, REG_WDR_OFF,
- },
- [REG_SCENE_BEACH_SNOW] = {
- REG_AE_CENTER, REG_AE_INDEX_10_POS, REG_AWB_AUTO, 0,
- REG_CHROMA_ON, 4, REG_EDGE_ON, 5,
- REG_AF_NORMAL, REG_FD_OFF,
- REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
- 6, REG_ISO_50, REG_CAP_NONE, REG_WDR_OFF,
- },
- [REG_SCENE_SUNSET] = {
- REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_PRESET,
- REG_AWB_DAYLIGHT,
- REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
- REG_AF_NORMAL, REG_FD_OFF,
- REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
- 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
- },
- [REG_SCENE_DAWN_DUSK] = {
- REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_PRESET,
- REG_AWB_FLUORESCENT_1,
- REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
- REG_AF_NORMAL, REG_FD_OFF,
- REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
- 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
- },
- [REG_SCENE_FALL] = {
- REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
- REG_CHROMA_ON, 5, REG_EDGE_ON, 5,
- REG_AF_NORMAL, REG_FD_OFF,
- REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
- 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
- },
- [REG_SCENE_NIGHT] = {
- REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
- REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
- REG_AF_NORMAL, REG_FD_OFF,
- REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
- 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
- },
- [REG_SCENE_AGAINST_LIGHT] = {
- REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
- REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
- REG_AF_NORMAL, REG_FD_OFF,
- REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
- 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
- },
- [REG_SCENE_FIRE] = {
- REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
- REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
- REG_AF_NORMAL, REG_FD_OFF,
- REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
- 6, REG_ISO_50, REG_CAP_NONE, REG_WDR_OFF,
- },
- [REG_SCENE_TEXT] = {
- REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
- REG_CHROMA_ON, 3, REG_EDGE_ON, 7,
- REG_AF_MACRO, REG_FD_OFF,
- REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
- 6, REG_ISO_AUTO, REG_CAP_ANTI_SHAKE, REG_WDR_ON,
- },
- [REG_SCENE_CANDLE] = {
- REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
- REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
- REG_AF_NORMAL, REG_FD_OFF,
- REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
- 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
- },
-};
-
-/**
- * m5mols_do_scenemode() - Change current scenemode
- * @mode: Desired mode of the scenemode
- *
- * WARNING: The execution order is important. Do not change the order.
- */
-int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
-{
- struct v4l2_subdev *sd = &info->sd;
- struct m5mols_scenemode scenemode = m5mols_default_scenemode[mode];
- int ret;
-
- if (mode > REG_SCENE_CANDLE)
- return -EINVAL;
-
- ret = v4l2_ctrl_s_ctrl(info->lock_3a, 0);
- if (!ret)
- ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, mode);
- if (!ret)
- ret = m5mols_write(sd, AE_EV_PRESET_CAPTURE, mode);
- if (!ret)
- ret = m5mols_write(sd, AE_MODE, scenemode.metering);
- if (!ret)
- ret = m5mols_write(sd, AE_INDEX, scenemode.ev_bias);
- if (!ret)
- ret = m5mols_write(sd, AWB_MODE, scenemode.wb_mode);
- if (!ret)
- ret = m5mols_write(sd, AWB_MANUAL, scenemode.wb_preset);
- if (!ret)
- ret = m5mols_write(sd, MON_CHROMA_EN, scenemode.chroma_en);
- if (!ret)
- ret = m5mols_write(sd, MON_CHROMA_LVL, scenemode.chroma_lvl);
- if (!ret)
- ret = m5mols_write(sd, MON_EDGE_EN, scenemode.edge_en);
- if (!ret)
- ret = m5mols_write(sd, MON_EDGE_LVL, scenemode.edge_lvl);
- if (!ret && is_available_af(info))
- ret = m5mols_write(sd, AF_MODE, scenemode.af_range);
- if (!ret && is_available_af(info))
- ret = m5mols_write(sd, FD_CTL, scenemode.fd_mode);
- if (!ret)
- ret = m5mols_write(sd, MON_TONE_CTL, scenemode.tone);
- if (!ret)
- ret = m5mols_write(sd, AE_ISO, scenemode.iso);
- if (!ret)
- ret = m5mols_set_mode(info, REG_CAPTURE);
- if (!ret)
- ret = m5mols_write(sd, CAPP_WDR_EN, scenemode.wdr);
- if (!ret)
- ret = m5mols_write(sd, CAPP_MCC_MODE, scenemode.mcc);
- if (!ret)
- ret = m5mols_write(sd, CAPP_LIGHT_CTRL, scenemode.light);
- if (!ret)
- ret = m5mols_write(sd, CAPP_FLASH_CTRL, scenemode.flash);
- if (!ret)
- ret = m5mols_write(sd, CAPC_MODE, scenemode.capt_mode);
- if (!ret)
- ret = m5mols_set_mode(info, REG_MONITOR);
-
- return ret;
-}
-
-static int m5mols_3a_lock(struct m5mols_info *info, struct v4l2_ctrl *ctrl)
-{
- bool af_lock = ctrl->val & V4L2_LOCK_FOCUS;
- int ret = 0;
-
- if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_EXPOSURE) {
- bool ae_lock = ctrl->val & V4L2_LOCK_EXPOSURE;
-
- ret = m5mols_write(&info->sd, AE_LOCK, ae_lock ?
- REG_AE_LOCK : REG_AE_UNLOCK);
- if (ret)
- return ret;
- }
-
- if (((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_WHITE_BALANCE)
- && info->auto_wb->val) {
- bool awb_lock = ctrl->val & V4L2_LOCK_WHITE_BALANCE;
-
- ret = m5mols_write(&info->sd, AWB_LOCK, awb_lock ?
- REG_AWB_LOCK : REG_AWB_UNLOCK);
- if (ret)
- return ret;
- }
-
- if (!info->ver.af || !af_lock)
- return ret;
-
- if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_FOCUS)
- ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP);
-
- return ret;
-}
-
-static int m5mols_set_metering_mode(struct m5mols_info *info, int mode)
-{
- unsigned int metering;
-
- switch (mode) {
- case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED:
- metering = REG_AE_CENTER;
- break;
- case V4L2_EXPOSURE_METERING_SPOT:
- metering = REG_AE_SPOT;
- break;
- default:
- metering = REG_AE_ALL;
- break;
- }
-
- return m5mols_write(&info->sd, AE_MODE, metering);
-}
-
-static int m5mols_set_exposure(struct m5mols_info *info, int exposure)
-{
- struct v4l2_subdev *sd = &info->sd;
- int ret = 0;
-
- if (exposure == V4L2_EXPOSURE_AUTO) {
- /* Unlock auto exposure */
- info->lock_3a->val &= ~V4L2_LOCK_EXPOSURE;
- m5mols_3a_lock(info, info->lock_3a);
-
- ret = m5mols_set_metering_mode(info, info->metering->val);
- if (ret < 0)
- return ret;
-
- v4l2_dbg(1, m5mols_debug, sd,
- "%s: exposure bias: %#x, metering: %#x\n",
- __func__, info->exposure_bias->val,
- info->metering->val);
-
- return m5mols_write(sd, AE_INDEX, info->exposure_bias->val);
- }
-
- if (exposure == V4L2_EXPOSURE_MANUAL) {
- ret = m5mols_write(sd, AE_MODE, REG_AE_OFF);
- if (ret == 0)
- ret = m5mols_write(sd, AE_MAN_GAIN_MON,
- info->exposure->val);
- if (ret == 0)
- ret = m5mols_write(sd, AE_MAN_GAIN_CAP,
- info->exposure->val);
-
- v4l2_dbg(1, m5mols_debug, sd, "%s: exposure: %#x\n",
- __func__, info->exposure->val);
- }
-
- return ret;
-}
-
-static int m5mols_set_white_balance(struct m5mols_info *info, int val)
-{
- static const unsigned short wb[][2] = {
- { V4L2_WHITE_BALANCE_INCANDESCENT, REG_AWB_INCANDESCENT },
- { V4L2_WHITE_BALANCE_FLUORESCENT, REG_AWB_FLUORESCENT_1 },
- { V4L2_WHITE_BALANCE_FLUORESCENT_H, REG_AWB_FLUORESCENT_2 },
- { V4L2_WHITE_BALANCE_HORIZON, REG_AWB_HORIZON },
- { V4L2_WHITE_BALANCE_DAYLIGHT, REG_AWB_DAYLIGHT },
- { V4L2_WHITE_BALANCE_FLASH, REG_AWB_LEDLIGHT },
- { V4L2_WHITE_BALANCE_CLOUDY, REG_AWB_CLOUDY },
- { V4L2_WHITE_BALANCE_SHADE, REG_AWB_SHADE },
- { V4L2_WHITE_BALANCE_AUTO, REG_AWB_AUTO },
- };
- int i;
- struct v4l2_subdev *sd = &info->sd;
- int ret = -EINVAL;
-
- for (i = 0; i < ARRAY_SIZE(wb); i++) {
- int awb;
- if (wb[i][0] != val)
- continue;
-
- v4l2_dbg(1, m5mols_debug, sd,
- "Setting white balance to: %#x\n", wb[i][0]);
-
- awb = wb[i][0] == V4L2_WHITE_BALANCE_AUTO;
- ret = m5mols_write(sd, AWB_MODE, awb ? REG_AWB_AUTO :
- REG_AWB_PRESET);
- if (ret < 0)
- return ret;
-
- if (!awb)
- ret = m5mols_write(sd, AWB_MANUAL, wb[i][1]);
- }
-
- return ret;
-}
-
-static int m5mols_set_saturation(struct m5mols_info *info, int val)
-{
- int ret = m5mols_write(&info->sd, MON_CHROMA_LVL, val);
- if (ret < 0)
- return ret;
-
- return m5mols_write(&info->sd, MON_CHROMA_EN, REG_CHROMA_ON);
-}
-
-static int m5mols_set_color_effect(struct m5mols_info *info, int val)
-{
- unsigned int m_effect = REG_COLOR_EFFECT_OFF;
- unsigned int p_effect = REG_EFFECT_OFF;
- unsigned int cfix_r = 0, cfix_b = 0;
- struct v4l2_subdev *sd = &info->sd;
- int ret = 0;
-
- switch (val) {
- case V4L2_COLORFX_BW:
- m_effect = REG_COLOR_EFFECT_ON;
- break;
- case V4L2_COLORFX_NEGATIVE:
- p_effect = REG_EFFECT_NEGA;
- break;
- case V4L2_COLORFX_EMBOSS:
- p_effect = REG_EFFECT_EMBOSS;
- break;
- case V4L2_COLORFX_SEPIA:
- m_effect = REG_COLOR_EFFECT_ON;
- cfix_r = REG_CFIXR_SEPIA;
- cfix_b = REG_CFIXB_SEPIA;
- break;
- }
-
- ret = m5mols_write(sd, PARM_EFFECT, p_effect);
- if (!ret)
- ret = m5mols_write(sd, MON_EFFECT, m_effect);
-
- if (ret == 0 && m_effect == REG_COLOR_EFFECT_ON) {
- ret = m5mols_write(sd, MON_CFIXR, cfix_r);
- if (!ret)
- ret = m5mols_write(sd, MON_CFIXB, cfix_b);
- }
-
- v4l2_dbg(1, m5mols_debug, sd,
- "p_effect: %#x, m_effect: %#x, r: %#x, b: %#x (%d)\n",
- p_effect, m_effect, cfix_r, cfix_b, ret);
-
- return ret;
-}
-
-static int m5mols_set_iso(struct m5mols_info *info, int auto_iso)
-{
- u32 iso = auto_iso ? 0 : info->iso->val + 1;
-
- return m5mols_write(&info->sd, AE_ISO, iso);
-}
-
-static int m5mols_set_wdr(struct m5mols_info *info, int wdr)
-{
- int ret;
-
- ret = m5mols_write(&info->sd, MON_TONE_CTL, wdr ? 9 : 5);
- if (ret < 0)
- return ret;
-
- ret = m5mols_set_mode(info, REG_CAPTURE);
- if (ret < 0)
- return ret;
-
- return m5mols_write(&info->sd, CAPP_WDR_EN, wdr);
-}
-
-static int m5mols_set_stabilization(struct m5mols_info *info, int val)
-{
- struct v4l2_subdev *sd = &info->sd;
- unsigned int evp = val ? 0xe : 0x0;
- int ret;
-
- ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, evp);
- if (ret < 0)
- return ret;
-
- return m5mols_write(sd, AE_EV_PRESET_CAPTURE, evp);
-}
-
-static int m5mols_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct m5mols_info *info = to_m5mols(sd);
- int ret = 0;
- u8 status;
-
- v4l2_dbg(1, m5mols_debug, sd, "%s: ctrl: %s (%d)\n",
- __func__, ctrl->name, info->isp_ready);
-
- if (!info->isp_ready)
- return -EBUSY;
-
- switch (ctrl->id) {
- case V4L2_CID_ISO_SENSITIVITY_AUTO:
- ret = m5mols_read_u8(sd, AE_ISO, &status);
- if (ret == 0)
- ctrl->val = !status;
- if (status != REG_ISO_AUTO)
- info->iso->val = status - 1;
- break;
-
- case V4L2_CID_3A_LOCK:
- ctrl->val &= ~0x7;
-
- ret = m5mols_read_u8(sd, AE_LOCK, &status);
- if (ret)
- return ret;
- if (status)
- info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
-
- ret = m5mols_read_u8(sd, AWB_LOCK, &status);
- if (ret)
- return ret;
- if (status)
- info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
-
- ret = m5mols_read_u8(sd, AF_EXECUTE, &status);
- if (!status)
- info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
- break;
- }
-
- return ret;
-}
-
-static int m5mols_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- unsigned int ctrl_mode = m5mols_get_ctrl_mode(ctrl);
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct m5mols_info *info = to_m5mols(sd);
- int last_mode = info->mode;
- int ret = 0;
-
- /*
- * If needed, defer restoring the controls until
- * the device is fully initialized.
- */
- if (!info->isp_ready) {
- info->ctrl_sync = 0;
- return 0;
- }
-
- v4l2_dbg(1, m5mols_debug, sd, "%s: %s, val: %d, priv: %#x\n",
- __func__, ctrl->name, ctrl->val, (int)ctrl->priv);
-
- if (ctrl_mode && ctrl_mode != info->mode) {
- ret = m5mols_set_mode(info, ctrl_mode);
- if (ret < 0)
- return ret;
- }
-
- switch (ctrl->id) {
- case V4L2_CID_3A_LOCK:
- ret = m5mols_3a_lock(info, ctrl);
- break;
-
- case V4L2_CID_ZOOM_ABSOLUTE:
- ret = m5mols_write(sd, MON_ZOOM, ctrl->val);
- break;
-
- case V4L2_CID_EXPOSURE_AUTO:
- ret = m5mols_set_exposure(info, ctrl->val);
- break;
-
- case V4L2_CID_ISO_SENSITIVITY:
- ret = m5mols_set_iso(info, ctrl->val);
- break;
-
- case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
- ret = m5mols_set_white_balance(info, ctrl->val);
- break;
-
- case V4L2_CID_SATURATION:
- ret = m5mols_set_saturation(info, ctrl->val);
- break;
-
- case V4L2_CID_COLORFX:
- ret = m5mols_set_color_effect(info, ctrl->val);
- break;
-
- case V4L2_CID_WIDE_DYNAMIC_RANGE:
- ret = m5mols_set_wdr(info, ctrl->val);
- break;
-
- case V4L2_CID_IMAGE_STABILIZATION:
- ret = m5mols_set_stabilization(info, ctrl->val);
- break;
-
- case V4L2_CID_JPEG_COMPRESSION_QUALITY:
- ret = m5mols_write(sd, CAPP_JPEG_RATIO, ctrl->val);
- break;
- }
-
- if (ret == 0 && info->mode != last_mode)
- ret = m5mols_set_mode(info, last_mode);
-
- return ret;
-}
-
-static const struct v4l2_ctrl_ops m5mols_ctrl_ops = {
- .g_volatile_ctrl = m5mols_g_volatile_ctrl,
- .s_ctrl = m5mols_s_ctrl,
-};
-
-/* Supported manual ISO values */
-static const s64 iso_qmenu[] = {
- /* AE_ISO: 0x01...0x07 (ISO: 50...3200) */
- 50000, 100000, 200000, 400000, 800000, 1600000, 3200000
-};
-
-/* Supported Exposure Bias values, -2.0EV...+2.0EV */
-static const s64 ev_bias_qmenu[] = {
- /* AE_INDEX: 0x00...0x08 */
- -2000, -1500, -1000, -500, 0, 500, 1000, 1500, 2000
-};
-
-int m5mols_init_controls(struct v4l2_subdev *sd)
-{
- struct m5mols_info *info = to_m5mols(sd);
- u16 exposure_max;
- u16 zoom_step;
- int ret;
-
- /* Determine the firmware dependant control range and step values */
- ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &exposure_max);
- if (ret < 0)
- return ret;
-
- zoom_step = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1;
- v4l2_ctrl_handler_init(&info->handle, 20);
-
- info->auto_wb = v4l2_ctrl_new_std_menu(&info->handle,
- &m5mols_ctrl_ops, V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
- 9, ~0x3fe, V4L2_WHITE_BALANCE_AUTO);
-
- /* Exposure control cluster */
- info->auto_exposure = v4l2_ctrl_new_std_menu(&info->handle,
- &m5mols_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
- 1, ~0x03, V4L2_EXPOSURE_AUTO);
-
- info->exposure = v4l2_ctrl_new_std(&info->handle,
- &m5mols_ctrl_ops, V4L2_CID_EXPOSURE,
- 0, exposure_max, 1, exposure_max / 2);
-
- info->exposure_bias = v4l2_ctrl_new_int_menu(&info->handle,
- &m5mols_ctrl_ops, V4L2_CID_AUTO_EXPOSURE_BIAS,
- ARRAY_SIZE(ev_bias_qmenu) - 1,
- ARRAY_SIZE(ev_bias_qmenu)/2 - 1,
- ev_bias_qmenu);
-
- info->metering = v4l2_ctrl_new_std_menu(&info->handle,
- &m5mols_ctrl_ops, V4L2_CID_EXPOSURE_METERING,
- 2, ~0x7, V4L2_EXPOSURE_METERING_AVERAGE);
-
- /* ISO control cluster */
- info->auto_iso = v4l2_ctrl_new_std_menu(&info->handle, &m5mols_ctrl_ops,
- V4L2_CID_ISO_SENSITIVITY_AUTO, 1, ~0x03, 1);
-
- info->iso = v4l2_ctrl_new_int_menu(&info->handle, &m5mols_ctrl_ops,
- V4L2_CID_ISO_SENSITIVITY, ARRAY_SIZE(iso_qmenu) - 1,
- ARRAY_SIZE(iso_qmenu)/2 - 1, iso_qmenu);
-
- info->saturation = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
- V4L2_CID_SATURATION, 1, 5, 1, 3);
-
- info->zoom = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
- V4L2_CID_ZOOM_ABSOLUTE, 1, 70, zoom_step, 1);
-
- info->colorfx = v4l2_ctrl_new_std_menu(&info->handle, &m5mols_ctrl_ops,
- V4L2_CID_COLORFX, 4, 0, V4L2_COLORFX_NONE);
-
- info->wdr = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
- V4L2_CID_WIDE_DYNAMIC_RANGE, 0, 1, 1, 0);
-
- info->stabilization = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
- V4L2_CID_IMAGE_STABILIZATION, 0, 1, 1, 0);
-
- info->jpeg_quality = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
- V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 80);
-
- info->lock_3a = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
- V4L2_CID_3A_LOCK, 0, 0x7, 0, 0);
-
- if (info->handle.error) {
- int ret = info->handle.error;
- v4l2_err(sd, "Failed to initialize controls: %d\n", ret);
- v4l2_ctrl_handler_free(&info->handle);
- return ret;
- }
-
- v4l2_ctrl_auto_cluster(4, &info->auto_exposure, 1, false);
- info->auto_iso->flags |= V4L2_CTRL_FLAG_VOLATILE |
- V4L2_CTRL_FLAG_UPDATE;
- v4l2_ctrl_auto_cluster(2, &info->auto_iso, 0, false);
-
- info->lock_3a->flags |= V4L2_CTRL_FLAG_VOLATILE;
-
- m5mols_set_ctrl_mode(info->auto_exposure, REG_PARAMETER);
- m5mols_set_ctrl_mode(info->auto_wb, REG_PARAMETER);
- m5mols_set_ctrl_mode(info->colorfx, REG_MONITOR);
-
- sd->ctrl_handler = &info->handle;
-
- return 0;
-}
diff --git a/drivers/media/video/m5mols/m5mols_core.c b/drivers/media/video/m5mols/m5mols_core.c
deleted file mode 100644
index ac7d28b6ddf..00000000000
--- a/drivers/media/video/m5mols/m5mols_core.c
+++ /dev/null
@@ -1,990 +0,0 @@
-/*
- * Driver for M-5MOLS 8M Pixel camera sensor with ISP
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * Author: HeungJun Kim <riverful.kim@samsung.com>
- *
- * Copyright (C) 2009 Samsung Electronics Co., Ltd.
- * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/regulator/consumer.h>
-#include <linux/videodev2.h>
-#include <linux/module.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include <media/m5mols.h>
-
-#include "m5mols.h"
-#include "m5mols_reg.h"
-
-int m5mols_debug;
-module_param(m5mols_debug, int, 0644);
-
-#define MODULE_NAME "M5MOLS"
-#define M5MOLS_I2C_CHECK_RETRY 500
-
-/* The regulator consumer names for external voltage regulators */
-static struct regulator_bulk_data supplies[] = {
- {
- .supply = "core", /* ARM core power, 1.2V */
- }, {
- .supply = "dig_18", /* digital power 1, 1.8V */
- }, {
- .supply = "d_sensor", /* sensor power 1, 1.8V */
- }, {
- .supply = "dig_28", /* digital power 2, 2.8V */
- }, {
- .supply = "a_sensor", /* analog power */
- }, {
- .supply = "dig_12", /* digital power 3, 1.2V */
- },
-};
-
-static struct v4l2_mbus_framefmt m5mols_default_ffmt[M5MOLS_RESTYPE_MAX] = {
- [M5MOLS_RESTYPE_MONITOR] = {
- .width = 1920,
- .height = 1080,
- .code = V4L2_MBUS_FMT_VYUY8_2X8,
- .field = V4L2_FIELD_NONE,
- .colorspace = V4L2_COLORSPACE_JPEG,
- },
- [M5MOLS_RESTYPE_CAPTURE] = {
- .width = 1920,
- .height = 1080,
- .code = V4L2_MBUS_FMT_JPEG_1X8,
- .field = V4L2_FIELD_NONE,
- .colorspace = V4L2_COLORSPACE_JPEG,
- },
-};
-#define SIZE_DEFAULT_FFMT ARRAY_SIZE(m5mols_default_ffmt)
-
-static const struct m5mols_resolution m5mols_reg_res[] = {
- { 0x01, M5MOLS_RESTYPE_MONITOR, 128, 96 }, /* SUB-QCIF */
- { 0x03, M5MOLS_RESTYPE_MONITOR, 160, 120 }, /* QQVGA */
- { 0x05, M5MOLS_RESTYPE_MONITOR, 176, 144 }, /* QCIF */
- { 0x06, M5MOLS_RESTYPE_MONITOR, 176, 176 },
- { 0x08, M5MOLS_RESTYPE_MONITOR, 240, 320 }, /* QVGA */
- { 0x09, M5MOLS_RESTYPE_MONITOR, 320, 240 }, /* QVGA */
- { 0x0c, M5MOLS_RESTYPE_MONITOR, 240, 400 }, /* WQVGA */
- { 0x0d, M5MOLS_RESTYPE_MONITOR, 400, 240 }, /* WQVGA */
- { 0x0e, M5MOLS_RESTYPE_MONITOR, 352, 288 }, /* CIF */
- { 0x13, M5MOLS_RESTYPE_MONITOR, 480, 360 },
- { 0x15, M5MOLS_RESTYPE_MONITOR, 640, 360 }, /* qHD */
- { 0x17, M5MOLS_RESTYPE_MONITOR, 640, 480 }, /* VGA */
- { 0x18, M5MOLS_RESTYPE_MONITOR, 720, 480 },
- { 0x1a, M5MOLS_RESTYPE_MONITOR, 800, 480 }, /* WVGA */
- { 0x1f, M5MOLS_RESTYPE_MONITOR, 800, 600 }, /* SVGA */
- { 0x21, M5MOLS_RESTYPE_MONITOR, 1280, 720 }, /* HD */
- { 0x25, M5MOLS_RESTYPE_MONITOR, 1920, 1080 }, /* 1080p */
- { 0x29, M5MOLS_RESTYPE_MONITOR, 3264, 2448 }, /* 2.63fps 8M */
- { 0x39, M5MOLS_RESTYPE_MONITOR, 800, 602 }, /* AHS_MON debug */
-
- { 0x02, M5MOLS_RESTYPE_CAPTURE, 320, 240 }, /* QVGA */
- { 0x04, M5MOLS_RESTYPE_CAPTURE, 400, 240 }, /* WQVGA */
- { 0x07, M5MOLS_RESTYPE_CAPTURE, 480, 360 },
- { 0x08, M5MOLS_RESTYPE_CAPTURE, 640, 360 }, /* qHD */
- { 0x09, M5MOLS_RESTYPE_CAPTURE, 640, 480 }, /* VGA */
- { 0x0a, M5MOLS_RESTYPE_CAPTURE, 800, 480 }, /* WVGA */
- { 0x10, M5MOLS_RESTYPE_CAPTURE, 1280, 720 }, /* HD */
- { 0x14, M5MOLS_RESTYPE_CAPTURE, 1280, 960 }, /* 1M */
- { 0x17, M5MOLS_RESTYPE_CAPTURE, 1600, 1200 }, /* 2M */
- { 0x19, M5MOLS_RESTYPE_CAPTURE, 1920, 1080 }, /* Full-HD */
- { 0x1a, M5MOLS_RESTYPE_CAPTURE, 2048, 1152 }, /* 3Mega */
- { 0x1b, M5MOLS_RESTYPE_CAPTURE, 2048, 1536 },
- { 0x1c, M5MOLS_RESTYPE_CAPTURE, 2560, 1440 }, /* 4Mega */
- { 0x1d, M5MOLS_RESTYPE_CAPTURE, 2560, 1536 },
- { 0x1f, M5MOLS_RESTYPE_CAPTURE, 2560, 1920 }, /* 5Mega */
- { 0x21, M5MOLS_RESTYPE_CAPTURE, 3264, 1836 }, /* 6Mega */
- { 0x22, M5MOLS_RESTYPE_CAPTURE, 3264, 1960 },
- { 0x25, M5MOLS_RESTYPE_CAPTURE, 3264, 2448 }, /* 8Mega */
-};
-
-/**
- * m5mols_swap_byte - an byte array to integer conversion function
- * @size: size in bytes of I2C packet defined in the M-5MOLS datasheet
- *
- * Convert I2C data byte array with performing any required byte
- * reordering to assure proper values for each data type, regardless
- * of the architecture endianness.
- */
-static u32 m5mols_swap_byte(u8 *data, u8 length)
-{
- if (length == 1)
- return *data;
- else if (length == 2)
- return be16_to_cpu(*((u16 *)data));
- else
- return be32_to_cpu(*((u32 *)data));
-}
-
-/**
- * m5mols_read - I2C read function
- * @reg: combination of size, category and command for the I2C packet
- * @size: desired size of I2C packet
- * @val: read value
- *
- * Returns 0 on success, or else negative errno.
- */
-static int m5mols_read(struct v4l2_subdev *sd, u32 size, u32 reg, u32 *val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct m5mols_info *info = to_m5mols(sd);
- u8 rbuf[M5MOLS_I2C_MAX_SIZE + 1];
- u8 category = I2C_CATEGORY(reg);
- u8 cmd = I2C_COMMAND(reg);
- struct i2c_msg msg[2];
- u8 wbuf[5];
- int ret;
-
- if (!client->adapter)
- return -ENODEV;
-
- msg[0].addr = client->addr;
- msg[0].flags = 0;
- msg[0].len = 5;
- msg[0].buf = wbuf;
- wbuf[0] = 5;
- wbuf[1] = M5MOLS_BYTE_READ;
- wbuf[2] = category;
- wbuf[3] = cmd;
- wbuf[4] = size;
-
- msg[1].addr = client->addr;
- msg[1].flags = I2C_M_RD;
- msg[1].len = size + 1;
- msg[1].buf = rbuf;
-
- /* minimum stabilization time */
- usleep_range(200, 200);
-
- ret = i2c_transfer(client->adapter, msg, 2);
-
- if (ret == 2) {
- *val = m5mols_swap_byte(&rbuf[1], size);
- return 0;
- }
-
- if (info->isp_ready)
- v4l2_err(sd, "read failed: size:%d cat:%02x cmd:%02x. %d\n",
- size, category, cmd, ret);
-
- return ret < 0 ? ret : -EIO;
-}
-
-int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg, u8 *val)
-{
- u32 val_32;
- int ret;
-
- if (I2C_SIZE(reg) != 1) {
- v4l2_err(sd, "Wrong data size\n");
- return -EINVAL;
- }
-
- ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
- if (ret)
- return ret;
-
- *val = (u8)val_32;
- return ret;
-}
-
-int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg, u16 *val)
-{
- u32 val_32;
- int ret;
-
- if (I2C_SIZE(reg) != 2) {
- v4l2_err(sd, "Wrong data size\n");
- return -EINVAL;
- }
-
- ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
- if (ret)
- return ret;
-
- *val = (u16)val_32;
- return ret;
-}
-
-int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg, u32 *val)
-{
- if (I2C_SIZE(reg) != 4) {
- v4l2_err(sd, "Wrong data size\n");
- return -EINVAL;
- }
-
- return m5mols_read(sd, I2C_SIZE(reg), reg, val);
-}
-
-/**
- * m5mols_write - I2C command write function
- * @reg: combination of size, category and command for the I2C packet
- * @val: value to write
- *
- * Returns 0 on success, or else negative errno.
- */
-int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct m5mols_info *info = to_m5mols(sd);
- u8 wbuf[M5MOLS_I2C_MAX_SIZE + 4];
- u8 category = I2C_CATEGORY(reg);
- u8 cmd = I2C_COMMAND(reg);
- u8 size = I2C_SIZE(reg);
- u32 *buf = (u32 *)&wbuf[4];
- struct i2c_msg msg[1];
- int ret;
-
- if (!client->adapter)
- return -ENODEV;
-
- if (size != 1 && size != 2 && size != 4) {
- v4l2_err(sd, "Wrong data size\n");
- return -EINVAL;
- }
-
- msg->addr = client->addr;
- msg->flags = 0;
- msg->len = (u16)size + 4;
- msg->buf = wbuf;
- wbuf[0] = size + 4;
- wbuf[1] = M5MOLS_BYTE_WRITE;
- wbuf[2] = category;
- wbuf[3] = cmd;
-
- *buf = m5mols_swap_byte((u8 *)&val, size);
-
- usleep_range(200, 200);
-
- ret = i2c_transfer(client->adapter, msg, 1);
- if (ret == 1)
- return 0;
-
- if (info->isp_ready)
- v4l2_err(sd, "write failed: cat:%02x cmd:%02x ret:%d\n",
- category, cmd, ret);
-
- return ret < 0 ? ret : -EIO;
-}
-
-/**
- * m5mols_busy_wait - Busy waiting with I2C register polling
- * @reg: the I2C_REG() address of an 8-bit status register to check
- * @value: expected status register value
- * @mask: bit mask for the read status register value
- * @timeout: timeout in miliseconds, or -1 for default timeout
- *
- * The @reg register value is ORed with @mask before comparing with @value.
- *
- * Return: 0 if the requested condition became true within less than
- * @timeout ms, or else negative errno.
- */
-int m5mols_busy_wait(struct v4l2_subdev *sd, u32 reg, u32 value, u32 mask,
- int timeout)
-{
- int ms = timeout < 0 ? M5MOLS_BUSY_WAIT_DEF_TIMEOUT : timeout;
- unsigned long end = jiffies + msecs_to_jiffies(ms);
- u8 status;
-
- do {
- int ret = m5mols_read_u8(sd, reg, &status);
-
- if (ret < 0 && !(mask & M5MOLS_I2C_RDY_WAIT_FL))
- return ret;
- if (!ret && (status & mask & 0xff) == (value & 0xff))
- return 0;
- usleep_range(100, 250);
- } while (ms > 0 && time_is_after_jiffies(end));
-
- return -EBUSY;
-}
-
-/**
- * m5mols_enable_interrupt - Clear interrupt pending bits and unmask interrupts
- *
- * Before writing desired interrupt value the INT_FACTOR register should
- * be read to clear pending interrupts.
- */
-int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg)
-{
- struct m5mols_info *info = to_m5mols(sd);
- u8 mask = is_available_af(info) ? REG_INT_AF : 0;
- u8 dummy;
- int ret;
-
- ret = m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &dummy);
- if (!ret)
- ret = m5mols_write(sd, SYSTEM_INT_ENABLE, reg & ~mask);
- return ret;
-}
-
-int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 irq_mask, u32 timeout)
-{
- struct m5mols_info *info = to_m5mols(sd);
-
- int ret = wait_event_interruptible_timeout(info->irq_waitq,
- atomic_add_unless(&info->irq_done, -1, 0),
- msecs_to_jiffies(timeout));
- if (ret <= 0)
- return ret ? ret : -ETIMEDOUT;
-
- return m5mols_busy_wait(sd, SYSTEM_INT_FACTOR, irq_mask,
- M5MOLS_I2C_RDY_WAIT_FL | irq_mask, -1);
-}
-
-/**
- * m5mols_reg_mode - Write the mode and check busy status
- *
- * It always accompanies a little delay changing the M-5MOLS mode, so it is
- * needed checking current busy status to guarantee right mode.
- */
-static int m5mols_reg_mode(struct v4l2_subdev *sd, u8 mode)
-{
- int ret = m5mols_write(sd, SYSTEM_SYSMODE, mode);
- if (ret < 0)
- return ret;
- return m5mols_busy_wait(sd, SYSTEM_SYSMODE, mode, 0xff,
- M5MOLS_MODE_CHANGE_TIMEOUT);
-}
-
-/**
- * m5mols_set_mode - set the M-5MOLS controller mode
- * @mode: the required operation mode
- *
- * The commands of M-5MOLS are grouped into specific modes. Each functionality
- * can be guaranteed only when the sensor is operating in mode which a command
- * belongs to.
- */
-int m5mols_set_mode(struct m5mols_info *info, u8 mode)
-{
- struct v4l2_subdev *sd = &info->sd;
- int ret = -EINVAL;
- u8 reg;
-
- if (mode < REG_PARAMETER || mode > REG_CAPTURE)
- return ret;
-
- ret = m5mols_read_u8(sd, SYSTEM_SYSMODE, &reg);
- if (ret || reg == mode)
- return ret;
-
- switch (reg) {
- case REG_PARAMETER:
- ret = m5mols_reg_mode(sd, REG_MONITOR);
- if (mode == REG_MONITOR)
- break;
- if (!ret)
- ret = m5mols_reg_mode(sd, REG_CAPTURE);
- break;
-
- case REG_MONITOR:
- if (mode == REG_PARAMETER) {
- ret = m5mols_reg_mode(sd, REG_PARAMETER);
- break;
- }
-
- ret = m5mols_reg_mode(sd, REG_CAPTURE);
- break;
-
- case REG_CAPTURE:
- ret = m5mols_reg_mode(sd, REG_MONITOR);
- if (mode == REG_MONITOR)
- break;
- if (!ret)
- ret = m5mols_reg_mode(sd, REG_PARAMETER);
- break;
-
- default:
- v4l2_warn(sd, "Wrong mode: %d\n", mode);
- }
-
- if (!ret)
- info->mode = mode;
-
- return ret;
-}
-
-/**
- * m5mols_get_version - retrieve full revisions information of M-5MOLS
- *
- * The version information includes revisions of hardware and firmware,
- * AutoFocus alghorithm version and the version string.
- */
-static int m5mols_get_version(struct v4l2_subdev *sd)
-{
- struct m5mols_info *info = to_m5mols(sd);
- struct m5mols_version *ver = &info->ver;
- u8 *str = ver->str;
- int i;
- int ret;
-
- ret = m5mols_read_u8(sd, SYSTEM_VER_CUSTOMER, &ver->customer);
- if (!ret)
- ret = m5mols_read_u8(sd, SYSTEM_VER_PROJECT, &ver->project);
- if (!ret)
- ret = m5mols_read_u16(sd, SYSTEM_VER_FIRMWARE, &ver->fw);
- if (!ret)
- ret = m5mols_read_u16(sd, SYSTEM_VER_HARDWARE, &ver->hw);
- if (!ret)
- ret = m5mols_read_u16(sd, SYSTEM_VER_PARAMETER, &ver->param);
- if (!ret)
- ret = m5mols_read_u16(sd, SYSTEM_VER_AWB, &ver->awb);
- if (!ret)
- ret = m5mols_read_u8(sd, AF_VERSION, &ver->af);
- if (ret)
- return ret;
-
- for (i = 0; i < VERSION_STRING_SIZE; i++) {
- ret = m5mols_read_u8(sd, SYSTEM_VER_STRING, &str[i]);
- if (ret)
- return ret;
- }
-
- ver->fw = be16_to_cpu(ver->fw);
- ver->hw = be16_to_cpu(ver->hw);
- ver->param = be16_to_cpu(ver->param);
- ver->awb = be16_to_cpu(ver->awb);
-
- v4l2_info(sd, "Manufacturer\t[%s]\n",
- is_manufacturer(info, REG_SAMSUNG_ELECTRO) ?
- "Samsung Electro-Machanics" :
- is_manufacturer(info, REG_SAMSUNG_OPTICS) ?
- "Samsung Fiber-Optics" :
- is_manufacturer(info, REG_SAMSUNG_TECHWIN) ?
- "Samsung Techwin" : "None");
- v4l2_info(sd, "Customer/Project\t[0x%02x/0x%02x]\n",
- info->ver.customer, info->ver.project);
-
- if (!is_available_af(info))
- v4l2_info(sd, "No support Auto Focus on this firmware\n");
-
- return ret;
-}
-
-/**
- * __find_restype - Lookup M-5MOLS resolution type according to pixel code
- * @code: pixel code
- */
-static enum m5mols_restype __find_restype(enum v4l2_mbus_pixelcode code)
-{
- enum m5mols_restype type = M5MOLS_RESTYPE_MONITOR;
-
- do {
- if (code == m5mols_default_ffmt[type].code)
- return type;
- } while (type++ != SIZE_DEFAULT_FFMT);
-
- return 0;
-}
-
-/**
- * __find_resolution - Lookup preset and type of M-5MOLS's resolution
- * @mf: pixel format to find/negotiate the resolution preset for
- * @type: M-5MOLS resolution type
- * @resolution: M-5MOLS resolution preset register value
- *
- * Find nearest resolution matching resolution preset and adjust mf
- * to supported values.
- */
-static int __find_resolution(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf,
- enum m5mols_restype *type,
- u32 *resolution)
-{
- const struct m5mols_resolution *fsize = &m5mols_reg_res[0];
- const struct m5mols_resolution *match = NULL;
- enum m5mols_restype stype = __find_restype(mf->code);
- int i = ARRAY_SIZE(m5mols_reg_res);
- unsigned int min_err = ~0;
-
- while (i--) {
- int err;
- if (stype == fsize->type) {
- err = abs(fsize->width - mf->width)
- + abs(fsize->height - mf->height);
-
- if (err < min_err) {
- min_err = err;
- match = fsize;
- }
- }
- fsize++;
- }
- if (match) {
- mf->width = match->width;
- mf->height = match->height;
- *resolution = match->reg;
- *type = stype;
- return 0;
- }
-
- return -EINVAL;
-}
-
-static struct v4l2_mbus_framefmt *__find_format(struct m5mols_info *info,
- struct v4l2_subdev_fh *fh,
- enum v4l2_subdev_format_whence which,
- enum m5mols_restype type)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return fh ? v4l2_subdev_get_try_format(fh, 0) : NULL;
-
- return &info->ffmt[type];
-}
-
-static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct m5mols_info *info = to_m5mols(sd);
- struct v4l2_mbus_framefmt *format;
-
- format = __find_format(info, fh, fmt->which, info->res_type);
- if (!format)
- return -EINVAL;
-
- fmt->format = *format;
- return 0;
-}
-
-static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct m5mols_info *info = to_m5mols(sd);
- struct v4l2_mbus_framefmt *format = &fmt->format;
- struct v4l2_mbus_framefmt *sfmt;
- enum m5mols_restype type;
- u32 resolution = 0;
- int ret;
-
- ret = __find_resolution(sd, format, &type, &resolution);
- if (ret < 0)
- return ret;
-
- sfmt = __find_format(info, fh, fmt->which, type);
- if (!sfmt)
- return 0;
-
-
- format->code = m5mols_default_ffmt[type].code;
- format->colorspace = V4L2_COLORSPACE_JPEG;
- format->field = V4L2_FIELD_NONE;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- *sfmt = *format;
- info->resolution = resolution;
- info->res_type = type;
- }
-
- return 0;
-}
-
-static int m5mols_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- if (!code || code->index >= SIZE_DEFAULT_FFMT)
- return -EINVAL;
-
- code->code = m5mols_default_ffmt[code->index].code;
-
- return 0;
-}
-
-static struct v4l2_subdev_pad_ops m5mols_pad_ops = {
- .enum_mbus_code = m5mols_enum_mbus_code,
- .get_fmt = m5mols_get_fmt,
- .set_fmt = m5mols_set_fmt,
-};
-
-/**
- * m5mols_restore_controls - Apply current control values to the registers
- *
- * m5mols_do_scenemode() handles all parameters for which there is yet no
- * individual control. It should be replaced at some point by setting each
- * control individually, in required register set up order.
- */
-int m5mols_restore_controls(struct m5mols_info *info)
-{
- int ret;
-
- if (info->ctrl_sync)
- return 0;
-
- ret = m5mols_do_scenemode(info, REG_SCENE_NORMAL);
- if (ret)
- return ret;
-
- ret = v4l2_ctrl_handler_setup(&info->handle);
- info->ctrl_sync = !ret;
-
- return ret;
-}
-
-/**
- * m5mols_start_monitor - Start the monitor mode
- *
- * Before applying the controls setup the resolution and frame rate
- * in PARAMETER mode, and then switch over to MONITOR mode.
- */
-static int m5mols_start_monitor(struct m5mols_info *info)
-{
- struct v4l2_subdev *sd = &info->sd;
- int ret;
-
- ret = m5mols_set_mode(info, REG_PARAMETER);
- if (!ret)
- ret = m5mols_write(sd, PARM_MON_SIZE, info->resolution);
- if (!ret)
- ret = m5mols_write(sd, PARM_MON_FPS, REG_FPS_30);
- if (!ret)
- ret = m5mols_set_mode(info, REG_MONITOR);
- if (!ret)
- ret = m5mols_restore_controls(info);
-
- return ret;
-}
-
-static int m5mols_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct m5mols_info *info = to_m5mols(sd);
- u32 code = info->ffmt[info->res_type].code;
-
- if (enable) {
- int ret = -EINVAL;
-
- if (is_code(code, M5MOLS_RESTYPE_MONITOR))
- ret = m5mols_start_monitor(info);
- if (is_code(code, M5MOLS_RESTYPE_CAPTURE))
- ret = m5mols_start_capture(info);
-
- return ret;
- }
-
- return m5mols_set_mode(info, REG_PARAMETER);
-}
-
-static const struct v4l2_subdev_video_ops m5mols_video_ops = {
- .s_stream = m5mols_s_stream,
-};
-
-static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
-{
- struct v4l2_subdev *sd = &info->sd;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- const struct m5mols_platform_data *pdata = info->pdata;
- int ret;
-
- if (info->power == enable)
- return 0;
-
- if (enable) {
- if (info->set_power) {
- ret = info->set_power(&client->dev, 1);
- if (ret)
- return ret;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
- if (ret) {
- info->set_power(&client->dev, 0);
- return ret;
- }
-
- gpio_set_value(pdata->gpio_reset, !pdata->reset_polarity);
- info->power = 1;
-
- return ret;
- }
-
- ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
- if (ret)
- return ret;
-
- if (info->set_power)
- info->set_power(&client->dev, 0);
-
- gpio_set_value(pdata->gpio_reset, pdata->reset_polarity);
-
- info->isp_ready = 0;
- info->power = 0;
-
- return ret;
-}
-
-/* m5mols_update_fw - optional firmware update routine */
-int __attribute__ ((weak)) m5mols_update_fw(struct v4l2_subdev *sd,
- int (*set_power)(struct m5mols_info *, bool))
-{
- return 0;
-}
-
-/**
- * m5mols_fw_start - M-5MOLS internal ARM controller initialization
- *
- * Execute the M-5MOLS internal ARM controller initialization sequence.
- * This function should be called after the supply voltage has been
- * applied and before any requests to the device are made.
- */
-static int m5mols_fw_start(struct v4l2_subdev *sd)
-{
- struct m5mols_info *info = to_m5mols(sd);
- int ret;
-
- atomic_set(&info->irq_done, 0);
- /* Wait until I2C slave is initialized in Flash Writer mode */
- ret = m5mols_busy_wait(sd, FLASH_CAM_START, REG_IN_FLASH_MODE,
- M5MOLS_I2C_RDY_WAIT_FL | 0xff, -1);
- if (!ret)
- ret = m5mols_write(sd, FLASH_CAM_START, REG_START_ARM_BOOT);
- if (!ret)
- ret = m5mols_wait_interrupt(sd, REG_INT_MODE, 2000);
- if (ret < 0)
- return ret;
-
- info->isp_ready = 1;
-
- ret = m5mols_get_version(sd);
- if (!ret)
- ret = m5mols_update_fw(sd, m5mols_sensor_power);
- if (ret)
- return ret;
-
- v4l2_dbg(1, m5mols_debug, sd, "Success ARM Booting\n");
-
- ret = m5mols_write(sd, PARM_INTERFACE, REG_INTERFACE_MIPI);
- if (!ret)
- ret = m5mols_enable_interrupt(sd,
- REG_INT_AF | REG_INT_CAPTURE);
-
- return ret;
-}
-
-/**
- * m5mols_s_power - Main sensor power control function
- *
- * To prevent breaking the lens when the sensor is powered off the Soft-Landing
- * algorithm is called where available. The Soft-Landing algorithm availability
- * dependends on the firmware provider.
- */
-static int m5mols_s_power(struct v4l2_subdev *sd, int on)
-{
- struct m5mols_info *info = to_m5mols(sd);
- int ret;
-
- if (on) {
- ret = m5mols_sensor_power(info, true);
- if (!ret)
- ret = m5mols_fw_start(sd);
- return ret;
- }
-
- if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
- ret = m5mols_set_mode(info, REG_MONITOR);
- if (!ret)
- ret = m5mols_write(sd, AF_EXECUTE, REG_AF_STOP);
- if (!ret)
- ret = m5mols_write(sd, AF_MODE, REG_AF_POWEROFF);
- if (!ret)
- ret = m5mols_busy_wait(sd, SYSTEM_STATUS, REG_AF_IDLE,
- 0xff, -1);
- if (ret < 0)
- v4l2_warn(sd, "Soft landing lens failed\n");
- }
-
- ret = m5mols_sensor_power(info, false);
- info->ctrl_sync = 0;
-
- return ret;
-}
-
-static int m5mols_log_status(struct v4l2_subdev *sd)
-{
- struct m5mols_info *info = to_m5mols(sd);
-
- v4l2_ctrl_handler_log_status(&info->handle, sd->name);
-
- return 0;
-}
-
-static const struct v4l2_subdev_core_ops m5mols_core_ops = {
- .s_power = m5mols_s_power,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .log_status = m5mols_log_status,
-};
-
-/*
- * V4L2 subdev internal operations
- */
-static int m5mols_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
-
- *format = m5mols_default_ffmt[0];
- return 0;
-}
-
-static const struct v4l2_subdev_internal_ops m5mols_subdev_internal_ops = {
- .open = m5mols_open,
-};
-
-static const struct v4l2_subdev_ops m5mols_ops = {
- .core = &m5mols_core_ops,
- .pad = &m5mols_pad_ops,
- .video = &m5mols_video_ops,
-};
-
-static irqreturn_t m5mols_irq_handler(int irq, void *data)
-{
- struct m5mols_info *info = to_m5mols(data);
-
- atomic_set(&info->irq_done, 1);
- wake_up_interruptible(&info->irq_waitq);
-
- return IRQ_HANDLED;
-}
-
-static int __devinit m5mols_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- const struct m5mols_platform_data *pdata = client->dev.platform_data;
- struct m5mols_info *info;
- struct v4l2_subdev *sd;
- int ret;
-
- if (pdata == NULL) {
- dev_err(&client->dev, "No platform data\n");
- return -EINVAL;
- }
-
- if (!gpio_is_valid(pdata->gpio_reset)) {
- dev_err(&client->dev, "No valid RESET GPIO specified\n");
- return -EINVAL;
- }
-
- if (!client->irq) {
- dev_err(&client->dev, "Interrupt not assigned\n");
- return -EINVAL;
- }
-
- info = kzalloc(sizeof(struct m5mols_info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- info->pdata = pdata;
- info->set_power = pdata->set_power;
-
- ret = gpio_request(pdata->gpio_reset, "M5MOLS_NRST");
- if (ret) {
- dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
- goto out_free;
- }
- gpio_direction_output(pdata->gpio_reset, pdata->reset_polarity);
-
- ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), supplies);
- if (ret) {
- dev_err(&client->dev, "Failed to get regulators: %d\n", ret);
- goto out_gpio;
- }
-
- sd = &info->sd;
- v4l2_i2c_subdev_init(sd, client, &m5mols_ops);
- strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- sd->internal_ops = &m5mols_subdev_internal_ops;
- info->pad.flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
- if (ret < 0)
- goto out_reg;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-
- init_waitqueue_head(&info->irq_waitq);
- ret = request_irq(client->irq, m5mols_irq_handler,
- IRQF_TRIGGER_RISING, MODULE_NAME, sd);
- if (ret) {
- dev_err(&client->dev, "Interrupt request failed: %d\n", ret);
- goto out_me;
- }
- info->res_type = M5MOLS_RESTYPE_MONITOR;
- info->ffmt[0] = m5mols_default_ffmt[0];
- info->ffmt[1] = m5mols_default_ffmt[1];
-
- ret = m5mols_sensor_power(info, true);
- if (ret)
- goto out_me;
-
- ret = m5mols_fw_start(sd);
- if (!ret)
- ret = m5mols_init_controls(sd);
-
- m5mols_sensor_power(info, false);
- if (!ret)
- return 0;
-out_me:
- media_entity_cleanup(&sd->entity);
-out_reg:
- regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
-out_gpio:
- gpio_free(pdata->gpio_reset);
-out_free:
- kfree(info);
- return ret;
-}
-
-static int __devexit m5mols_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct m5mols_info *info = to_m5mols(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(sd->ctrl_handler);
- free_irq(client->irq, sd);
-
- regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
- gpio_free(info->pdata->gpio_reset);
- media_entity_cleanup(&sd->entity);
- kfree(info);
- return 0;
-}
-
-static const struct i2c_device_id m5mols_id[] = {
- { MODULE_NAME, 0 },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, m5mols_id);
-
-static struct i2c_driver m5mols_i2c_driver = {
- .driver = {
- .name = MODULE_NAME,
- },
- .probe = m5mols_probe,
- .remove = __devexit_p(m5mols_remove),
- .id_table = m5mols_id,
-};
-
-module_i2c_driver(m5mols_i2c_driver);
-
-MODULE_AUTHOR("HeungJun Kim <riverful.kim@samsung.com>");
-MODULE_AUTHOR("Dongsoo Kim <dongsoo45.kim@samsung.com>");
-MODULE_DESCRIPTION("Fujitsu M-5MOLS 8M Pixel camera driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/m5mols/m5mols_reg.h b/drivers/media/video/m5mols/m5mols_reg.h
deleted file mode 100644
index 14d4be72aef..00000000000
--- a/drivers/media/video/m5mols/m5mols_reg.h
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * Register map for M-5MOLS 8M Pixel camera sensor with ISP
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * Author: HeungJun Kim <riverful.kim@samsung.com>
- *
- * Copyright (C) 2009 Samsung Electronics Co., Ltd.
- * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef M5MOLS_REG_H
-#define M5MOLS_REG_H
-
-#define M5MOLS_I2C_MAX_SIZE 4
-#define M5MOLS_BYTE_READ 0x01
-#define M5MOLS_BYTE_WRITE 0x02
-
-#define I2C_CATEGORY(__cat) ((__cat >> 16) & 0xff)
-#define I2C_COMMAND(__comm) ((__comm >> 8) & 0xff)
-#define I2C_SIZE(__reg_s) ((__reg_s) & 0xff)
-#define I2C_REG(__cat, __cmd, __reg_s) ((__cat << 16) | (__cmd << 8) | __reg_s)
-
-/*
- * Category section register
- *
- * The category means set including relevant command of M-5MOLS.
- */
-#define CAT_SYSTEM 0x00
-#define CAT_PARAM 0x01
-#define CAT_MONITOR 0x02
-#define CAT_AE 0x03
-#define CAT_WB 0x06
-#define CAT_EXIF 0x07
-#define CAT_FD 0x09
-#define CAT_LENS 0x0a
-#define CAT_CAPT_PARM 0x0b
-#define CAT_CAPT_CTRL 0x0c
-#define CAT_FLASH 0x0f /* related to FW, revisions, booting */
-
-/*
- * Category 0 - SYSTEM mode
- *
- * The SYSTEM mode in the M-5MOLS means area available to handle with the whole
- * & all-round system of sensor. It deals with version/interrupt/setting mode &
- * even sensor's status. Especially, the M-5MOLS sensor with ISP varies by
- * packaging & manufacturer, even the customer and project code. And the
- * function details may vary among them. The version information helps to
- * determine what methods shall be used in the driver.
- *
- * There is many registers between customer version address and awb one. For
- * more specific contents, see definition if file m5mols.h.
- */
-#define SYSTEM_VER_CUSTOMER I2C_REG(CAT_SYSTEM, 0x00, 1)
-#define SYSTEM_VER_PROJECT I2C_REG(CAT_SYSTEM, 0x01, 1)
-#define SYSTEM_VER_FIRMWARE I2C_REG(CAT_SYSTEM, 0x02, 2)
-#define SYSTEM_VER_HARDWARE I2C_REG(CAT_SYSTEM, 0x04, 2)
-#define SYSTEM_VER_PARAMETER I2C_REG(CAT_SYSTEM, 0x06, 2)
-#define SYSTEM_VER_AWB I2C_REG(CAT_SYSTEM, 0x08, 2)
-
-#define SYSTEM_SYSMODE I2C_REG(CAT_SYSTEM, 0x0b, 1)
-#define REG_SYSINIT 0x00 /* SYSTEM mode */
-#define REG_PARAMETER 0x01 /* PARAMETER mode */
-#define REG_MONITOR 0x02 /* MONITOR mode */
-#define REG_CAPTURE 0x03 /* CAPTURE mode */
-
-#define SYSTEM_CMD(__cmd) I2C_REG(CAT_SYSTEM, cmd, 1)
-#define SYSTEM_VER_STRING I2C_REG(CAT_SYSTEM, 0x0a, 1)
-#define REG_SAMSUNG_ELECTRO "SE" /* Samsung Electro-Mechanics */
-#define REG_SAMSUNG_OPTICS "OP" /* Samsung Fiber-Optics */
-#define REG_SAMSUNG_TECHWIN "TB" /* Samsung Techwin */
-/* SYSTEM mode status */
-#define SYSTEM_STATUS I2C_REG(CAT_SYSTEM, 0x0c, 1)
-
-/* Interrupt pending register */
-#define SYSTEM_INT_FACTOR I2C_REG(CAT_SYSTEM, 0x10, 1)
-/* interrupt enable register */
-#define SYSTEM_INT_ENABLE I2C_REG(CAT_SYSTEM, 0x11, 1)
-#define REG_INT_MODE (1 << 0)
-#define REG_INT_AF (1 << 1)
-#define REG_INT_ZOOM (1 << 2)
-#define REG_INT_CAPTURE (1 << 3)
-#define REG_INT_FRAMESYNC (1 << 4)
-#define REG_INT_FD (1 << 5)
-#define REG_INT_LENS_INIT (1 << 6)
-#define REG_INT_SOUND (1 << 7)
-#define REG_INT_MASK 0x0f
-
-/*
- * category 1 - PARAMETER mode
- *
- * This category supports function of camera features of M-5MOLS. It means we
- * can handle with preview(MONITOR) resolution size/frame per second/interface
- * between the sensor and the Application Processor/even the image effect.
- */
-
-/* Resolution in the MONITOR mode */
-#define PARM_MON_SIZE I2C_REG(CAT_PARAM, 0x01, 1)
-
-/* Frame rate */
-#define PARM_MON_FPS I2C_REG(CAT_PARAM, 0x02, 1)
-#define REG_FPS_30 0x02
-
-/* Video bus between the sensor and a host processor */
-#define PARM_INTERFACE I2C_REG(CAT_PARAM, 0x00, 1)
-#define REG_INTERFACE_MIPI 0x02
-
-/* Image effects */
-#define PARM_EFFECT I2C_REG(CAT_PARAM, 0x0b, 1)
-#define REG_EFFECT_OFF 0x00
-#define REG_EFFECT_NEGA 0x01
-#define REG_EFFECT_EMBOSS 0x06
-#define REG_EFFECT_OUTLINE 0x07
-#define REG_EFFECT_WATERCOLOR 0x08
-
-/*
- * Category 2 - MONITOR mode
- *
- * The MONITOR mode is same as preview mode as we said. The M-5MOLS has another
- * mode named "Preview", but this preview mode is used at the case specific
- * vider-recording mode. This mmode supports only YUYV format. On the other
- * hand, the JPEG & RAW formats is supports by CAPTURE mode. And, there are
- * another options like zoom/color effect(different with effect in PARAMETER
- * mode)/anti hand shaking algorithm.
- */
-
-/* Target digital zoom position */
-#define MON_ZOOM I2C_REG(CAT_MONITOR, 0x01, 1)
-
-/* CR value for color effect */
-#define MON_CFIXR I2C_REG(CAT_MONITOR, 0x0a, 1)
-/* CB value for color effect */
-#define MON_CFIXB I2C_REG(CAT_MONITOR, 0x09, 1)
-#define REG_CFIXB_SEPIA 0xd8
-#define REG_CFIXR_SEPIA 0x18
-
-#define MON_EFFECT I2C_REG(CAT_MONITOR, 0x0b, 1)
-#define REG_COLOR_EFFECT_OFF 0x00
-#define REG_COLOR_EFFECT_ON 0x01
-
-/* Chroma enable */
-#define MON_CHROMA_EN I2C_REG(CAT_MONITOR, 0x10, 1)
-/* Chroma level */
-#define MON_CHROMA_LVL I2C_REG(CAT_MONITOR, 0x0f, 1)
-#define REG_CHROMA_OFF 0x00
-#define REG_CHROMA_ON 0x01
-
-/* Sharpness on/off */
-#define MON_EDGE_EN I2C_REG(CAT_MONITOR, 0x12, 1)
-/* Sharpness level */
-#define MON_EDGE_LVL I2C_REG(CAT_MONITOR, 0x11, 1)
-#define REG_EDGE_OFF 0x00
-#define REG_EDGE_ON 0x01
-
-/* Set color tone (contrast) */
-#define MON_TONE_CTL I2C_REG(CAT_MONITOR, 0x25, 1)
-
-/*
- * Category 3 - Auto Exposure
- *
- * The M-5MOLS exposure capbility is detailed as which is similar to digital
- * camera. This category supports AE locking/various AE mode(range of exposure)
- * /ISO/flickering/EV bias/shutter/meteoring, and anything else. And the
- * maximum/minimum exposure gain value depending on M-5MOLS firmware, may be
- * different. So, this category also provide getting the max/min values. And,
- * each MONITOR and CAPTURE mode has each gain/shutter/max exposure values.
- */
-
-/* Auto Exposure locking */
-#define AE_LOCK I2C_REG(CAT_AE, 0x00, 1)
-#define REG_AE_UNLOCK 0x00
-#define REG_AE_LOCK 0x01
-
-/* Auto Exposure algorithm mode */
-#define AE_MODE I2C_REG(CAT_AE, 0x01, 1)
-#define REG_AE_OFF 0x00 /* AE off */
-#define REG_AE_ALL 0x01 /* calc AE in all block integral */
-#define REG_AE_CENTER 0x03 /* calc AE in center weighted */
-#define REG_AE_SPOT 0x06 /* calc AE in specific spot */
-
-#define AE_ISO I2C_REG(CAT_AE, 0x05, 1)
-#define REG_ISO_AUTO 0x00
-#define REG_ISO_50 0x01
-#define REG_ISO_100 0x02
-#define REG_ISO_200 0x03
-#define REG_ISO_400 0x04
-#define REG_ISO_800 0x05
-
-/* EV (scenemode) preset for MONITOR */
-#define AE_EV_PRESET_MONITOR I2C_REG(CAT_AE, 0x0a, 1)
-/* EV (scenemode) preset for CAPTURE */
-#define AE_EV_PRESET_CAPTURE I2C_REG(CAT_AE, 0x0b, 1)
-#define REG_SCENE_NORMAL 0x00
-#define REG_SCENE_PORTRAIT 0x01
-#define REG_SCENE_LANDSCAPE 0x02
-#define REG_SCENE_SPORTS 0x03
-#define REG_SCENE_PARTY_INDOOR 0x04
-#define REG_SCENE_BEACH_SNOW 0x05
-#define REG_SCENE_SUNSET 0x06
-#define REG_SCENE_DAWN_DUSK 0x07
-#define REG_SCENE_FALL 0x08
-#define REG_SCENE_NIGHT 0x09
-#define REG_SCENE_AGAINST_LIGHT 0x0a
-#define REG_SCENE_FIRE 0x0b
-#define REG_SCENE_TEXT 0x0c
-#define REG_SCENE_CANDLE 0x0d
-
-/* Manual gain in MONITOR mode */
-#define AE_MAN_GAIN_MON I2C_REG(CAT_AE, 0x12, 2)
-/* Maximum gain in MONITOR mode */
-#define AE_MAX_GAIN_MON I2C_REG(CAT_AE, 0x1a, 2)
-/* Manual gain in CAPTURE mode */
-#define AE_MAN_GAIN_CAP I2C_REG(CAT_AE, 0x26, 2)
-
-#define AE_INDEX I2C_REG(CAT_AE, 0x38, 1)
-#define REG_AE_INDEX_20_NEG 0x00
-#define REG_AE_INDEX_15_NEG 0x01
-#define REG_AE_INDEX_10_NEG 0x02
-#define REG_AE_INDEX_05_NEG 0x03
-#define REG_AE_INDEX_00 0x04
-#define REG_AE_INDEX_05_POS 0x05
-#define REG_AE_INDEX_10_POS 0x06
-#define REG_AE_INDEX_15_POS 0x07
-#define REG_AE_INDEX_20_POS 0x08
-
-/*
- * Category 6 - White Balance
- */
-
-/* Auto Whitebalance locking */
-#define AWB_LOCK I2C_REG(CAT_WB, 0x00, 1)
-#define REG_AWB_UNLOCK 0x00
-#define REG_AWB_LOCK 0x01
-
-#define AWB_MODE I2C_REG(CAT_WB, 0x02, 1)
-#define REG_AWB_AUTO 0x01 /* AWB off */
-#define REG_AWB_PRESET 0x02 /* AWB preset */
-
-/* Manual WB (preset) */
-#define AWB_MANUAL I2C_REG(CAT_WB, 0x03, 1)
-#define REG_AWB_INCANDESCENT 0x01
-#define REG_AWB_FLUORESCENT_1 0x02
-#define REG_AWB_FLUORESCENT_2 0x03
-#define REG_AWB_DAYLIGHT 0x04
-#define REG_AWB_CLOUDY 0x05
-#define REG_AWB_SHADE 0x06
-#define REG_AWB_HORIZON 0x07
-#define REG_AWB_LEDLIGHT 0x09
-
-/*
- * Category 7 - EXIF information
- */
-#define EXIF_INFO_EXPTIME_NU I2C_REG(CAT_EXIF, 0x00, 4)
-#define EXIF_INFO_EXPTIME_DE I2C_REG(CAT_EXIF, 0x04, 4)
-#define EXIF_INFO_TV_NU I2C_REG(CAT_EXIF, 0x08, 4)
-#define EXIF_INFO_TV_DE I2C_REG(CAT_EXIF, 0x0c, 4)
-#define EXIF_INFO_AV_NU I2C_REG(CAT_EXIF, 0x10, 4)
-#define EXIF_INFO_AV_DE I2C_REG(CAT_EXIF, 0x14, 4)
-#define EXIF_INFO_BV_NU I2C_REG(CAT_EXIF, 0x18, 4)
-#define EXIF_INFO_BV_DE I2C_REG(CAT_EXIF, 0x1c, 4)
-#define EXIF_INFO_EBV_NU I2C_REG(CAT_EXIF, 0x20, 4)
-#define EXIF_INFO_EBV_DE I2C_REG(CAT_EXIF, 0x24, 4)
-#define EXIF_INFO_ISO I2C_REG(CAT_EXIF, 0x28, 2)
-#define EXIF_INFO_FLASH I2C_REG(CAT_EXIF, 0x2a, 2)
-#define EXIF_INFO_SDR I2C_REG(CAT_EXIF, 0x2c, 2)
-#define EXIF_INFO_QVAL I2C_REG(CAT_EXIF, 0x2e, 2)
-
-/*
- * Category 9 - Face Detection
- */
-#define FD_CTL I2C_REG(CAT_FD, 0x00, 1)
-#define BIT_FD_EN 0
-#define BIT_FD_DRAW_FACE_FRAME 4
-#define BIT_FD_DRAW_SMILE_LVL 6
-#define REG_FD(shift) (1 << shift)
-#define REG_FD_OFF 0x0
-
-/*
- * Category A - Lens Parameter
- */
-#define AF_MODE I2C_REG(CAT_LENS, 0x01, 1)
-#define REG_AF_NORMAL 0x00 /* Normal AF, one time */
-#define REG_AF_MACRO 0x01 /* Macro AF, one time */
-#define REG_AF_POWEROFF 0x07
-
-#define AF_EXECUTE I2C_REG(CAT_LENS, 0x02, 1)
-#define REG_AF_STOP 0x00
-#define REG_AF_EXE_AUTO 0x01
-#define REG_AF_EXE_CAF 0x02
-
-#define AF_STATUS I2C_REG(CAT_LENS, 0x03, 1)
-#define REG_AF_FAIL 0x00
-#define REG_AF_SUCCESS 0x02
-#define REG_AF_IDLE 0x04
-#define REG_AF_BUSY 0x05
-
-#define AF_VERSION I2C_REG(CAT_LENS, 0x0a, 1)
-
-/*
- * Category B - CAPTURE Parameter
- */
-#define CAPP_YUVOUT_MAIN I2C_REG(CAT_CAPT_PARM, 0x00, 1)
-#define REG_YUV422 0x00
-#define REG_BAYER10 0x05
-#define REG_BAYER8 0x06
-#define REG_JPEG 0x10
-
-#define CAPP_MAIN_IMAGE_SIZE I2C_REG(CAT_CAPT_PARM, 0x01, 1)
-#define CAPP_JPEG_RATIO I2C_REG(CAT_CAPT_PARM, 0x17, 1)
-
-#define CAPP_MCC_MODE I2C_REG(CAT_CAPT_PARM, 0x1d, 1)
-#define REG_MCC_OFF 0x00
-#define REG_MCC_NORMAL 0x01
-
-#define CAPP_WDR_EN I2C_REG(CAT_CAPT_PARM, 0x2c, 1)
-#define REG_WDR_OFF 0x00
-#define REG_WDR_ON 0x01
-#define REG_WDR_AUTO 0x02
-
-#define CAPP_LIGHT_CTRL I2C_REG(CAT_CAPT_PARM, 0x40, 1)
-#define REG_LIGHT_OFF 0x00
-#define REG_LIGHT_ON 0x01
-#define REG_LIGHT_AUTO 0x02
-
-#define CAPP_FLASH_CTRL I2C_REG(CAT_CAPT_PARM, 0x41, 1)
-#define REG_FLASH_OFF 0x00
-#define REG_FLASH_ON 0x01
-#define REG_FLASH_AUTO 0x02
-
-/*
- * Category C - CAPTURE Control
- */
-#define CAPC_MODE I2C_REG(CAT_CAPT_CTRL, 0x00, 1)
-#define REG_CAP_NONE 0x00
-#define REG_CAP_ANTI_SHAKE 0x02
-
-/* Select single- or multi-shot capture */
-#define CAPC_SEL_FRAME I2C_REG(CAT_CAPT_CTRL, 0x06, 1)
-
-#define CAPC_START I2C_REG(CAT_CAPT_CTRL, 0x09, 1)
-#define REG_CAP_START_MAIN 0x01
-#define REG_CAP_START_THUMB 0x03
-
-#define CAPC_IMAGE_SIZE I2C_REG(CAT_CAPT_CTRL, 0x0d, 4)
-#define CAPC_THUMB_SIZE I2C_REG(CAT_CAPT_CTRL, 0x11, 4)
-
-/*
- * Category F - Flash
- *
- * This mode provides functions about internal flash stuff and system startup.
- */
-
-/* Starts internal ARM core booting after power-up */
-#define FLASH_CAM_START I2C_REG(CAT_FLASH, 0x12, 1)
-#define REG_START_ARM_BOOT 0x01 /* write value */
-#define REG_IN_FLASH_MODE 0x00 /* read value */
-
-#endif /* M5MOLS_REG_H */
diff --git a/drivers/media/video/marvell-ccic/Kconfig b/drivers/media/video/marvell-ccic/Kconfig
deleted file mode 100644
index bf739e3b339..00000000000
--- a/drivers/media/video/marvell-ccic/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-config VIDEO_CAFE_CCIC
- tristate "Marvell 88ALP01 (Cafe) CMOS Camera Controller support"
- depends on PCI && I2C && VIDEO_V4L2
- select VIDEO_OV7670
- select VIDEOBUF2_VMALLOC
- select VIDEOBUF2_DMA_CONTIG
- ---help---
- This is a video4linux2 driver for the Marvell 88ALP01 integrated
- CMOS camera controller. This is the controller found on first-
- generation OLPC systems.
-
-config VIDEO_MMP_CAMERA
- tristate "Marvell Armada 610 integrated camera controller support"
- depends on ARCH_MMP && I2C && VIDEO_V4L2
- select VIDEO_OV7670
- select I2C_GPIO
- select VIDEOBUF2_DMA_SG
- ---help---
- This is a Video4Linux2 driver for the integrated camera
- controller found on Marvell Armada 610 application
- processors (and likely beyond). This is the controller found
- in OLPC XO 1.75 systems.
-
diff --git a/drivers/media/video/marvell-ccic/Makefile b/drivers/media/video/marvell-ccic/Makefile
deleted file mode 100644
index 05a792c579a..00000000000
--- a/drivers/media/video/marvell-ccic/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
-cafe_ccic-y := cafe-driver.o mcam-core.o
-
-obj-$(CONFIG_VIDEO_MMP_CAMERA) += mmp_camera.o
-mmp_camera-y := mmp-driver.o mcam-core.o
-
diff --git a/drivers/media/video/marvell-ccic/cafe-driver.c b/drivers/media/video/marvell-ccic/cafe-driver.c
deleted file mode 100644
index d030f9beae8..00000000000
--- a/drivers/media/video/marvell-ccic/cafe-driver.c
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
- * A driver for the CMOS camera controller in the Marvell 88ALP01 "cafe"
- * multifunction chip. Currently works with the Omnivision OV7670
- * sensor.
- *
- * The data sheet for this device can be found at:
- * http://www.marvell.com/products/pc_connectivity/88alp01/
- *
- * Copyright 2006-11 One Laptop Per Child Association, Inc.
- * Copyright 2006-11 Jonathan Corbet <corbet@lwn.net>
- *
- * Written by Jonathan Corbet, corbet@lwn.net.
- *
- * v4l2_device/v4l2_subdev conversion by:
- * Copyright (C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This file may be distributed under the terms of the GNU General
- * Public License, version 2.
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <linux/device.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-
-#include "mcam-core.h"
-
-#define CAFE_VERSION 0x000002
-
-
-/*
- * Parameters.
- */
-MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
-MODULE_DESCRIPTION("Marvell 88ALP01 CMOS Camera Controller driver");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("Video");
-
-
-
-
-struct cafe_camera {
- int registered; /* Fully initialized? */
- struct mcam_camera mcam;
- struct pci_dev *pdev;
- wait_queue_head_t smbus_wait; /* Waiting on i2c events */
-};
-
-/*
- * Most of the camera controller registers are defined in mcam-core.h,
- * but the Cafe platform has some additional registers of its own;
- * they are described here.
- */
-
-/*
- * "General purpose register" has a couple of GPIOs used for sensor
- * power and reset on OLPC XO 1.0 systems.
- */
-#define REG_GPR 0xb4
-#define GPR_C1EN 0x00000020 /* Pad 1 (power down) enable */
-#define GPR_C0EN 0x00000010 /* Pad 0 (reset) enable */
-#define GPR_C1 0x00000002 /* Control 1 value */
-/*
- * Control 0 is wired to reset on OLPC machines. For ov7x sensors,
- * it is active low.
- */
-#define GPR_C0 0x00000001 /* Control 0 value */
-
-/*
- * These registers control the SMBUS module for communicating
- * with the sensor.
- */
-#define REG_TWSIC0 0xb8 /* TWSI (smbus) control 0 */
-#define TWSIC0_EN 0x00000001 /* TWSI enable */
-#define TWSIC0_MODE 0x00000002 /* 1 = 16-bit, 0 = 8-bit */
-#define TWSIC0_SID 0x000003fc /* Slave ID */
-/*
- * Subtle trickery: the slave ID field starts with bit 2. But the
- * Linux i2c stack wants to treat the bottommost bit as a separate
- * read/write bit, which is why slave ID's are usually presented
- * >>1. For consistency with that behavior, we shift over three
- * bits instead of two.
- */
-#define TWSIC0_SID_SHIFT 3
-#define TWSIC0_CLKDIV 0x0007fc00 /* Clock divider */
-#define TWSIC0_MASKACK 0x00400000 /* Mask ack from sensor */
-#define TWSIC0_OVMAGIC 0x00800000 /* Make it work on OV sensors */
-
-#define REG_TWSIC1 0xbc /* TWSI control 1 */
-#define TWSIC1_DATA 0x0000ffff /* Data to/from camchip */
-#define TWSIC1_ADDR 0x00ff0000 /* Address (register) */
-#define TWSIC1_ADDR_SHIFT 16
-#define TWSIC1_READ 0x01000000 /* Set for read op */
-#define TWSIC1_WSTAT 0x02000000 /* Write status */
-#define TWSIC1_RVALID 0x04000000 /* Read data valid */
-#define TWSIC1_ERROR 0x08000000 /* Something screwed up */
-
-/*
- * Here's the weird global control registers
- */
-#define REG_GL_CSR 0x3004 /* Control/status register */
-#define GCSR_SRS 0x00000001 /* SW Reset set */
-#define GCSR_SRC 0x00000002 /* SW Reset clear */
-#define GCSR_MRS 0x00000004 /* Master reset set */
-#define GCSR_MRC 0x00000008 /* HW Reset clear */
-#define GCSR_CCIC_EN 0x00004000 /* CCIC Clock enable */
-#define REG_GL_IMASK 0x300c /* Interrupt mask register */
-#define GIMSK_CCIC_EN 0x00000004 /* CCIC Interrupt enable */
-
-#define REG_GL_FCR 0x3038 /* GPIO functional control register */
-#define GFCR_GPIO_ON 0x08 /* Camera GPIO enabled */
-#define REG_GL_GPIOR 0x315c /* GPIO register */
-#define GGPIO_OUT 0x80000 /* GPIO output */
-#define GGPIO_VAL 0x00008 /* Output pin value */
-
-#define REG_LEN (REG_GL_IMASK + 4)
-
-
-/*
- * Debugging and related.
- */
-#define cam_err(cam, fmt, arg...) \
- dev_err(&(cam)->pdev->dev, fmt, ##arg);
-#define cam_warn(cam, fmt, arg...) \
- dev_warn(&(cam)->pdev->dev, fmt, ##arg);
-
-/* -------------------------------------------------------------------- */
-/*
- * The I2C/SMBUS interface to the camera itself starts here. The
- * controller handles SMBUS itself, presenting a relatively simple register
- * interface; all we have to do is to tell it where to route the data.
- */
-#define CAFE_SMBUS_TIMEOUT (HZ) /* generous */
-
-static inline struct cafe_camera *to_cam(struct v4l2_device *dev)
-{
- struct mcam_camera *m = container_of(dev, struct mcam_camera, v4l2_dev);
- return container_of(m, struct cafe_camera, mcam);
-}
-
-
-static int cafe_smbus_write_done(struct mcam_camera *mcam)
-{
- unsigned long flags;
- int c1;
-
- /*
- * We must delay after the interrupt, or the controller gets confused
- * and never does give us good status. Fortunately, we don't do this
- * often.
- */
- udelay(20);
- spin_lock_irqsave(&mcam->dev_lock, flags);
- c1 = mcam_reg_read(mcam, REG_TWSIC1);
- spin_unlock_irqrestore(&mcam->dev_lock, flags);
- return (c1 & (TWSIC1_WSTAT|TWSIC1_ERROR)) != TWSIC1_WSTAT;
-}
-
-static int cafe_smbus_write_data(struct cafe_camera *cam,
- u16 addr, u8 command, u8 value)
-{
- unsigned int rval;
- unsigned long flags;
- struct mcam_camera *mcam = &cam->mcam;
-
- spin_lock_irqsave(&mcam->dev_lock, flags);
- rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID);
- rval |= TWSIC0_OVMAGIC; /* Make OV sensors work */
- /*
- * Marvell sez set clkdiv to all 1's for now.
- */
- rval |= TWSIC0_CLKDIV;
- mcam_reg_write(mcam, REG_TWSIC0, rval);
- (void) mcam_reg_read(mcam, REG_TWSIC1); /* force write */
- rval = value | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR);
- mcam_reg_write(mcam, REG_TWSIC1, rval);
- spin_unlock_irqrestore(&mcam->dev_lock, flags);
-
- /* Unfortunately, reading TWSIC1 too soon after sending a command
- * causes the device to die.
- * Use a busy-wait because we often send a large quantity of small
- * commands at-once; using msleep() would cause a lot of context
- * switches which take longer than 2ms, resulting in a noticeable
- * boot-time and capture-start delays.
- */
- mdelay(2);
-
- /*
- * Another sad fact is that sometimes, commands silently complete but
- * cafe_smbus_write_done() never becomes aware of this.
- * This happens at random and appears to possible occur with any
- * command.
- * We don't understand why this is. We work around this issue
- * with the timeout in the wait below, assuming that all commands
- * complete within the timeout.
- */
- wait_event_timeout(cam->smbus_wait, cafe_smbus_write_done(mcam),
- CAFE_SMBUS_TIMEOUT);
-
- spin_lock_irqsave(&mcam->dev_lock, flags);
- rval = mcam_reg_read(mcam, REG_TWSIC1);
- spin_unlock_irqrestore(&mcam->dev_lock, flags);
-
- if (rval & TWSIC1_WSTAT) {
- cam_err(cam, "SMBUS write (%02x/%02x/%02x) timed out\n", addr,
- command, value);
- return -EIO;
- }
- if (rval & TWSIC1_ERROR) {
- cam_err(cam, "SMBUS write (%02x/%02x/%02x) error\n", addr,
- command, value);
- return -EIO;
- }
- return 0;
-}
-
-
-
-static int cafe_smbus_read_done(struct mcam_camera *mcam)
-{
- unsigned long flags;
- int c1;
-
- /*
- * We must delay after the interrupt, or the controller gets confused
- * and never does give us good status. Fortunately, we don't do this
- * often.
- */
- udelay(20);
- spin_lock_irqsave(&mcam->dev_lock, flags);
- c1 = mcam_reg_read(mcam, REG_TWSIC1);
- spin_unlock_irqrestore(&mcam->dev_lock, flags);
- return c1 & (TWSIC1_RVALID|TWSIC1_ERROR);
-}
-
-
-
-static int cafe_smbus_read_data(struct cafe_camera *cam,
- u16 addr, u8 command, u8 *value)
-{
- unsigned int rval;
- unsigned long flags;
- struct mcam_camera *mcam = &cam->mcam;
-
- spin_lock_irqsave(&mcam->dev_lock, flags);
- rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID);
- rval |= TWSIC0_OVMAGIC; /* Make OV sensors work */
- /*
- * Marvel sez set clkdiv to all 1's for now.
- */
- rval |= TWSIC0_CLKDIV;
- mcam_reg_write(mcam, REG_TWSIC0, rval);
- (void) mcam_reg_read(mcam, REG_TWSIC1); /* force write */
- rval = TWSIC1_READ | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR);
- mcam_reg_write(mcam, REG_TWSIC1, rval);
- spin_unlock_irqrestore(&mcam->dev_lock, flags);
-
- wait_event_timeout(cam->smbus_wait,
- cafe_smbus_read_done(mcam), CAFE_SMBUS_TIMEOUT);
- spin_lock_irqsave(&mcam->dev_lock, flags);
- rval = mcam_reg_read(mcam, REG_TWSIC1);
- spin_unlock_irqrestore(&mcam->dev_lock, flags);
-
- if (rval & TWSIC1_ERROR) {
- cam_err(cam, "SMBUS read (%02x/%02x) error\n", addr, command);
- return -EIO;
- }
- if (!(rval & TWSIC1_RVALID)) {
- cam_err(cam, "SMBUS read (%02x/%02x) timed out\n", addr,
- command);
- return -EIO;
- }
- *value = rval & 0xff;
- return 0;
-}
-
-/*
- * Perform a transfer over SMBUS. This thing is called under
- * the i2c bus lock, so we shouldn't race with ourselves...
- */
-static int cafe_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
- unsigned short flags, char rw, u8 command,
- int size, union i2c_smbus_data *data)
-{
- struct cafe_camera *cam = i2c_get_adapdata(adapter);
- int ret = -EINVAL;
-
- /*
- * This interface would appear to only do byte data ops. OK
- * it can do word too, but the cam chip has no use for that.
- */
- if (size != I2C_SMBUS_BYTE_DATA) {
- cam_err(cam, "funky xfer size %d\n", size);
- return -EINVAL;
- }
-
- if (rw == I2C_SMBUS_WRITE)
- ret = cafe_smbus_write_data(cam, addr, command, data->byte);
- else if (rw == I2C_SMBUS_READ)
- ret = cafe_smbus_read_data(cam, addr, command, &data->byte);
- return ret;
-}
-
-
-static void cafe_smbus_enable_irq(struct cafe_camera *cam)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cam->mcam.dev_lock, flags);
- mcam_reg_set_bit(&cam->mcam, REG_IRQMASK, TWSIIRQS);
- spin_unlock_irqrestore(&cam->mcam.dev_lock, flags);
-}
-
-static u32 cafe_smbus_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_READ_BYTE_DATA |
- I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
-}
-
-static struct i2c_algorithm cafe_smbus_algo = {
- .smbus_xfer = cafe_smbus_xfer,
- .functionality = cafe_smbus_func
-};
-
-static int cafe_smbus_setup(struct cafe_camera *cam)
-{
- struct i2c_adapter *adap;
- int ret;
-
- adap = kzalloc(sizeof(*adap), GFP_KERNEL);
- if (adap == NULL)
- return -ENOMEM;
- cam->mcam.i2c_adapter = adap;
- cafe_smbus_enable_irq(cam);
- adap->owner = THIS_MODULE;
- adap->algo = &cafe_smbus_algo;
- strcpy(adap->name, "cafe_ccic");
- adap->dev.parent = &cam->pdev->dev;
- i2c_set_adapdata(adap, cam);
- ret = i2c_add_adapter(adap);
- if (ret)
- printk(KERN_ERR "Unable to register cafe i2c adapter\n");
- return ret;
-}
-
-static void cafe_smbus_shutdown(struct cafe_camera *cam)
-{
- i2c_del_adapter(cam->mcam.i2c_adapter);
- kfree(cam->mcam.i2c_adapter);
-}
-
-
-/*
- * Controller-level stuff
- */
-
-static void cafe_ctlr_init(struct mcam_camera *mcam)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mcam->dev_lock, flags);
- /*
- * Added magic to bring up the hardware on the B-Test board
- */
- mcam_reg_write(mcam, 0x3038, 0x8);
- mcam_reg_write(mcam, 0x315c, 0x80008);
- /*
- * Go through the dance needed to wake the device up.
- * Note that these registers are global and shared
- * with the NAND and SD devices. Interaction between the
- * three still needs to be examined.
- */
- mcam_reg_write(mcam, REG_GL_CSR, GCSR_SRS|GCSR_MRS); /* Needed? */
- mcam_reg_write(mcam, REG_GL_CSR, GCSR_SRC|GCSR_MRC);
- mcam_reg_write(mcam, REG_GL_CSR, GCSR_SRC|GCSR_MRS);
- /*
- * Here we must wait a bit for the controller to come around.
- */
- spin_unlock_irqrestore(&mcam->dev_lock, flags);
- msleep(5);
- spin_lock_irqsave(&mcam->dev_lock, flags);
-
- mcam_reg_write(mcam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC);
- mcam_reg_set_bit(mcam, REG_GL_IMASK, GIMSK_CCIC_EN);
- /*
- * Mask all interrupts.
- */
- mcam_reg_write(mcam, REG_IRQMASK, 0);
- spin_unlock_irqrestore(&mcam->dev_lock, flags);
-}
-
-
-static void cafe_ctlr_power_up(struct mcam_camera *mcam)
-{
- /*
- * Part one of the sensor dance: turn the global
- * GPIO signal on.
- */
- mcam_reg_write(mcam, REG_GL_FCR, GFCR_GPIO_ON);
- mcam_reg_write(mcam, REG_GL_GPIOR, GGPIO_OUT|GGPIO_VAL);
- /*
- * Put the sensor into operational mode (assumes OLPC-style
- * wiring). Control 0 is reset - set to 1 to operate.
- * Control 1 is power down, set to 0 to operate.
- */
- mcam_reg_write(mcam, REG_GPR, GPR_C1EN|GPR_C0EN); /* pwr up, reset */
- mcam_reg_write(mcam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0);
-}
-
-static void cafe_ctlr_power_down(struct mcam_camera *mcam)
-{
- mcam_reg_write(mcam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C1);
- mcam_reg_write(mcam, REG_GL_FCR, GFCR_GPIO_ON);
- mcam_reg_write(mcam, REG_GL_GPIOR, GGPIO_OUT);
-}
-
-
-
-/*
- * The platform interrupt handler.
- */
-static irqreturn_t cafe_irq(int irq, void *data)
-{
- struct cafe_camera *cam = data;
- struct mcam_camera *mcam = &cam->mcam;
- unsigned int irqs, handled;
-
- spin_lock(&mcam->dev_lock);
- irqs = mcam_reg_read(mcam, REG_IRQSTAT);
- handled = cam->registered && mccic_irq(mcam, irqs);
- if (irqs & TWSIIRQS) {
- mcam_reg_write(mcam, REG_IRQSTAT, TWSIIRQS);
- wake_up(&cam->smbus_wait);
- handled = 1;
- }
- spin_unlock(&mcam->dev_lock);
- return IRQ_RETVAL(handled);
-}
-
-
-/* -------------------------------------------------------------------------- */
-/*
- * PCI interface stuff.
- */
-
-static int cafe_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
-{
- int ret;
- struct cafe_camera *cam;
- struct mcam_camera *mcam;
-
- /*
- * Start putting together one of our big camera structures.
- */
- ret = -ENOMEM;
- cam = kzalloc(sizeof(struct cafe_camera), GFP_KERNEL);
- if (cam == NULL)
- goto out;
- cam->pdev = pdev;
- mcam = &cam->mcam;
- mcam->chip_id = V4L2_IDENT_CAFE;
- spin_lock_init(&mcam->dev_lock);
- init_waitqueue_head(&cam->smbus_wait);
- mcam->plat_power_up = cafe_ctlr_power_up;
- mcam->plat_power_down = cafe_ctlr_power_down;
- mcam->dev = &pdev->dev;
- /*
- * Set the clock speed for the XO 1; I don't believe this
- * driver has ever run anywhere else.
- */
- mcam->clock_speed = 45;
- mcam->use_smbus = 1;
- /*
- * Vmalloc mode for buffers is traditional with this driver.
- * We *might* be able to run DMA_contig, especially on a system
- * with CMA in it.
- */
- mcam->buffer_mode = B_vmalloc;
- /*
- * Get set up on the PCI bus.
- */
- ret = pci_enable_device(pdev);
- if (ret)
- goto out_free;
- pci_set_master(pdev);
-
- ret = -EIO;
- mcam->regs = pci_iomap(pdev, 0, 0);
- if (!mcam->regs) {
- printk(KERN_ERR "Unable to ioremap cafe-ccic regs\n");
- goto out_disable;
- }
- ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam);
- if (ret)
- goto out_iounmap;
-
- /*
- * Initialize the controller and leave it powered up. It will
- * stay that way until the sensor driver shows up.
- */
- cafe_ctlr_init(mcam);
- cafe_ctlr_power_up(mcam);
- /*
- * Set up I2C/SMBUS communications. We have to drop the mutex here
- * because the sensor could attach in this call chain, leading to
- * unsightly deadlocks.
- */
- ret = cafe_smbus_setup(cam);
- if (ret)
- goto out_pdown;
-
- ret = mccic_register(mcam);
- if (ret == 0) {
- cam->registered = 1;
- return 0;
- }
-
- cafe_smbus_shutdown(cam);
-out_pdown:
- cafe_ctlr_power_down(mcam);
- free_irq(pdev->irq, cam);
-out_iounmap:
- pci_iounmap(pdev, mcam->regs);
-out_disable:
- pci_disable_device(pdev);
-out_free:
- kfree(cam);
-out:
- return ret;
-}
-
-
-/*
- * Shut down an initialized device
- */
-static void cafe_shutdown(struct cafe_camera *cam)
-{
- mccic_shutdown(&cam->mcam);
- cafe_smbus_shutdown(cam);
- free_irq(cam->pdev->irq, cam);
- pci_iounmap(cam->pdev, cam->mcam.regs);
-}
-
-
-static void cafe_pci_remove(struct pci_dev *pdev)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
- struct cafe_camera *cam = to_cam(v4l2_dev);
-
- if (cam == NULL) {
- printk(KERN_WARNING "pci_remove on unknown pdev %p\n", pdev);
- return;
- }
- cafe_shutdown(cam);
- kfree(cam);
-}
-
-
-#ifdef CONFIG_PM
-/*
- * Basic power management.
- */
-static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
- struct cafe_camera *cam = to_cam(v4l2_dev);
- int ret;
-
- ret = pci_save_state(pdev);
- if (ret)
- return ret;
- mccic_suspend(&cam->mcam);
- pci_disable_device(pdev);
- return 0;
-}
-
-
-static int cafe_pci_resume(struct pci_dev *pdev)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
- struct cafe_camera *cam = to_cam(v4l2_dev);
- int ret = 0;
-
- pci_restore_state(pdev);
- ret = pci_enable_device(pdev);
-
- if (ret) {
- cam_warn(cam, "Unable to re-enable device on resume!\n");
- return ret;
- }
- cafe_ctlr_init(&cam->mcam);
- return mccic_resume(&cam->mcam);
-}
-
-#endif /* CONFIG_PM */
-
-static struct pci_device_id cafe_ids[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL,
- PCI_DEVICE_ID_MARVELL_88ALP01_CCIC) },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, cafe_ids);
-
-static struct pci_driver cafe_pci_driver = {
- .name = "cafe1000-ccic",
- .id_table = cafe_ids,
- .probe = cafe_pci_probe,
- .remove = cafe_pci_remove,
-#ifdef CONFIG_PM
- .suspend = cafe_pci_suspend,
- .resume = cafe_pci_resume,
-#endif
-};
-
-
-
-
-static int __init cafe_init(void)
-{
- int ret;
-
- printk(KERN_NOTICE "Marvell M88ALP01 'CAFE' Camera Controller version %d\n",
- CAFE_VERSION);
- ret = pci_register_driver(&cafe_pci_driver);
- if (ret) {
- printk(KERN_ERR "Unable to register cafe_ccic driver\n");
- goto out;
- }
- ret = 0;
-
-out:
- return ret;
-}
-
-
-static void __exit cafe_exit(void)
-{
- pci_unregister_driver(&cafe_pci_driver);
-}
-
-module_init(cafe_init);
-module_exit(cafe_exit);
diff --git a/drivers/media/video/marvell-ccic/mcam-core.c b/drivers/media/video/marvell-ccic/mcam-core.c
deleted file mode 100644
index ce2b7b4788d..00000000000
--- a/drivers/media/video/marvell-ccic/mcam-core.c
+++ /dev/null
@@ -1,1878 +0,0 @@
-/*
- * The Marvell camera core. This device appears in a number of settings,
- * so it needs platform-specific support outside of the core.
- *
- * Copyright 2011 Jonathan Corbet corbet@lwn.net
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/wait.h>
-#include <linux/list.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/vmalloc.h>
-#include <linux/io.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/ov7670.h>
-#include <media/videobuf2-vmalloc.h>
-#include <media/videobuf2-dma-contig.h>
-#include <media/videobuf2-dma-sg.h>
-
-#include "mcam-core.h"
-
-/*
- * Basic frame stats - to be deleted shortly
- */
-static int frames;
-static int singles;
-static int delivered;
-
-#ifdef MCAM_MODE_VMALLOC
-/*
- * Internal DMA buffer management. Since the controller cannot do S/G I/O,
- * we must have physically contiguous buffers to bring frames into.
- * These parameters control how many buffers we use, whether we
- * allocate them at load time (better chance of success, but nails down
- * memory) or when somebody tries to use the camera (riskier), and,
- * for load-time allocation, how big they should be.
- *
- * The controller can cycle through three buffers. We could use
- * more by flipping pointers around, but it probably makes little
- * sense.
- */
-
-static bool alloc_bufs_at_read;
-module_param(alloc_bufs_at_read, bool, 0444);
-MODULE_PARM_DESC(alloc_bufs_at_read,
- "Non-zero value causes DMA buffers to be allocated when the "
- "video capture device is read, rather than at module load "
- "time. This saves memory, but decreases the chances of "
- "successfully getting those buffers. This parameter is "
- "only used in the vmalloc buffer mode");
-
-static int n_dma_bufs = 3;
-module_param(n_dma_bufs, uint, 0644);
-MODULE_PARM_DESC(n_dma_bufs,
- "The number of DMA buffers to allocate. Can be either two "
- "(saves memory, makes timing tighter) or three.");
-
-static int dma_buf_size = VGA_WIDTH * VGA_HEIGHT * 2; /* Worst case */
-module_param(dma_buf_size, uint, 0444);
-MODULE_PARM_DESC(dma_buf_size,
- "The size of the allocated DMA buffers. If actual operating "
- "parameters require larger buffers, an attempt to reallocate "
- "will be made.");
-#else /* MCAM_MODE_VMALLOC */
-static const bool alloc_bufs_at_read = 0;
-static const int n_dma_bufs = 3; /* Used by S/G_PARM */
-#endif /* MCAM_MODE_VMALLOC */
-
-static bool flip;
-module_param(flip, bool, 0444);
-MODULE_PARM_DESC(flip,
- "If set, the sensor will be instructed to flip the image "
- "vertically.");
-
-static int buffer_mode = -1;
-module_param(buffer_mode, int, 0444);
-MODULE_PARM_DESC(buffer_mode,
- "Set the buffer mode to be used; default is to go with what "
- "the platform driver asks for. Set to 0 for vmalloc, 1 for "
- "DMA contiguous.");
-
-/*
- * Status flags. Always manipulated with bit operations.
- */
-#define CF_BUF0_VALID 0 /* Buffers valid - first three */
-#define CF_BUF1_VALID 1
-#define CF_BUF2_VALID 2
-#define CF_DMA_ACTIVE 3 /* A frame is incoming */
-#define CF_CONFIG_NEEDED 4 /* Must configure hardware */
-#define CF_SINGLE_BUFFER 5 /* Running with a single buffer */
-#define CF_SG_RESTART 6 /* SG restart needed */
-
-#define sensor_call(cam, o, f, args...) \
- v4l2_subdev_call(cam->sensor, o, f, ##args)
-
-static struct mcam_format_struct {
- __u8 *desc;
- __u32 pixelformat;
- int bpp; /* Bytes per pixel */
- enum v4l2_mbus_pixelcode mbus_code;
-} mcam_formats[] = {
- {
- .desc = "YUYV 4:2:2",
- .pixelformat = V4L2_PIX_FMT_YUYV,
- .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
- .bpp = 2,
- },
- {
- .desc = "RGB 444",
- .pixelformat = V4L2_PIX_FMT_RGB444,
- .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE,
- .bpp = 2,
- },
- {
- .desc = "RGB 565",
- .pixelformat = V4L2_PIX_FMT_RGB565,
- .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE,
- .bpp = 2,
- },
- {
- .desc = "Raw RGB Bayer",
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8,
- .bpp = 1
- },
-};
-#define N_MCAM_FMTS ARRAY_SIZE(mcam_formats)
-
-static struct mcam_format_struct *mcam_find_format(u32 pixelformat)
-{
- unsigned i;
-
- for (i = 0; i < N_MCAM_FMTS; i++)
- if (mcam_formats[i].pixelformat == pixelformat)
- return mcam_formats + i;
- /* Not found? Then return the first format. */
- return mcam_formats;
-}
-
-/*
- * The default format we use until somebody says otherwise.
- */
-static const struct v4l2_pix_format mcam_def_pix_format = {
- .width = VGA_WIDTH,
- .height = VGA_HEIGHT,
- .pixelformat = V4L2_PIX_FMT_YUYV,
- .field = V4L2_FIELD_NONE,
- .bytesperline = VGA_WIDTH*2,
- .sizeimage = VGA_WIDTH*VGA_HEIGHT*2,
-};
-
-static const enum v4l2_mbus_pixelcode mcam_def_mbus_code =
- V4L2_MBUS_FMT_YUYV8_2X8;
-
-
-/*
- * The two-word DMA descriptor format used by the Armada 610 and like. There
- * Is a three-word format as well (set C1_DESC_3WORD) where the third
- * word is a pointer to the next descriptor, but we don't use it. Two-word
- * descriptors have to be contiguous in memory.
- */
-struct mcam_dma_desc {
- u32 dma_addr;
- u32 segment_len;
-};
-
-/*
- * Our buffer type for working with videobuf2. Note that the vb2
- * developers have decreed that struct vb2_buffer must be at the
- * beginning of this structure.
- */
-struct mcam_vb_buffer {
- struct vb2_buffer vb_buf;
- struct list_head queue;
- struct mcam_dma_desc *dma_desc; /* Descriptor virtual address */
- dma_addr_t dma_desc_pa; /* Descriptor physical address */
- int dma_desc_nent; /* Number of mapped descriptors */
-};
-
-static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_buffer *vb)
-{
- return container_of(vb, struct mcam_vb_buffer, vb_buf);
-}
-
-/*
- * Hand a completed buffer back to user space.
- */
-static void mcam_buffer_done(struct mcam_camera *cam, int frame,
- struct vb2_buffer *vbuf)
-{
- vbuf->v4l2_buf.bytesused = cam->pix_format.sizeimage;
- vbuf->v4l2_buf.sequence = cam->buf_seq[frame];
- vb2_set_plane_payload(vbuf, 0, cam->pix_format.sizeimage);
- vb2_buffer_done(vbuf, VB2_BUF_STATE_DONE);
-}
-
-
-
-/*
- * Debugging and related.
- */
-#define cam_err(cam, fmt, arg...) \
- dev_err((cam)->dev, fmt, ##arg);
-#define cam_warn(cam, fmt, arg...) \
- dev_warn((cam)->dev, fmt, ##arg);
-#define cam_dbg(cam, fmt, arg...) \
- dev_dbg((cam)->dev, fmt, ##arg);
-
-
-/*
- * Flag manipulation helpers
- */
-static void mcam_reset_buffers(struct mcam_camera *cam)
-{
- int i;
-
- cam->next_buf = -1;
- for (i = 0; i < cam->nbufs; i++)
- clear_bit(i, &cam->flags);
-}
-
-static inline int mcam_needs_config(struct mcam_camera *cam)
-{
- return test_bit(CF_CONFIG_NEEDED, &cam->flags);
-}
-
-static void mcam_set_config_needed(struct mcam_camera *cam, int needed)
-{
- if (needed)
- set_bit(CF_CONFIG_NEEDED, &cam->flags);
- else
- clear_bit(CF_CONFIG_NEEDED, &cam->flags);
-}
-
-/* ------------------------------------------------------------------- */
-/*
- * Make the controller start grabbing images. Everything must
- * be set up before doing this.
- */
-static void mcam_ctlr_start(struct mcam_camera *cam)
-{
- /* set_bit performs a read, so no other barrier should be
- needed here */
- mcam_reg_set_bit(cam, REG_CTRL0, C0_ENABLE);
-}
-
-static void mcam_ctlr_stop(struct mcam_camera *cam)
-{
- mcam_reg_clear_bit(cam, REG_CTRL0, C0_ENABLE);
-}
-
-/* ------------------------------------------------------------------- */
-
-#ifdef MCAM_MODE_VMALLOC
-/*
- * Code specific to the vmalloc buffer mode.
- */
-
-/*
- * Allocate in-kernel DMA buffers for vmalloc mode.
- */
-static int mcam_alloc_dma_bufs(struct mcam_camera *cam, int loadtime)
-{
- int i;
-
- mcam_set_config_needed(cam, 1);
- if (loadtime)
- cam->dma_buf_size = dma_buf_size;
- else
- cam->dma_buf_size = cam->pix_format.sizeimage;
- if (n_dma_bufs > 3)
- n_dma_bufs = 3;
-
- cam->nbufs = 0;
- for (i = 0; i < n_dma_bufs; i++) {
- cam->dma_bufs[i] = dma_alloc_coherent(cam->dev,
- cam->dma_buf_size, cam->dma_handles + i,
- GFP_KERNEL);
- if (cam->dma_bufs[i] == NULL) {
- cam_warn(cam, "Failed to allocate DMA buffer\n");
- break;
- }
- (cam->nbufs)++;
- }
-
- switch (cam->nbufs) {
- case 1:
- dma_free_coherent(cam->dev, cam->dma_buf_size,
- cam->dma_bufs[0], cam->dma_handles[0]);
- cam->nbufs = 0;
- case 0:
- cam_err(cam, "Insufficient DMA buffers, cannot operate\n");
- return -ENOMEM;
-
- case 2:
- if (n_dma_bufs > 2)
- cam_warn(cam, "Will limp along with only 2 buffers\n");
- break;
- }
- return 0;
-}
-
-static void mcam_free_dma_bufs(struct mcam_camera *cam)
-{
- int i;
-
- for (i = 0; i < cam->nbufs; i++) {
- dma_free_coherent(cam->dev, cam->dma_buf_size,
- cam->dma_bufs[i], cam->dma_handles[i]);
- cam->dma_bufs[i] = NULL;
- }
- cam->nbufs = 0;
-}
-
-
-/*
- * Set up DMA buffers when operating in vmalloc mode
- */
-static void mcam_ctlr_dma_vmalloc(struct mcam_camera *cam)
-{
- /*
- * Store the first two Y buffers (we aren't supporting
- * planar formats for now, so no UV bufs). Then either
- * set the third if it exists, or tell the controller
- * to just use two.
- */
- mcam_reg_write(cam, REG_Y0BAR, cam->dma_handles[0]);
- mcam_reg_write(cam, REG_Y1BAR, cam->dma_handles[1]);
- if (cam->nbufs > 2) {
- mcam_reg_write(cam, REG_Y2BAR, cam->dma_handles[2]);
- mcam_reg_clear_bit(cam, REG_CTRL1, C1_TWOBUFS);
- } else
- mcam_reg_set_bit(cam, REG_CTRL1, C1_TWOBUFS);
- if (cam->chip_id == V4L2_IDENT_CAFE)
- mcam_reg_write(cam, REG_UBAR, 0); /* 32 bits only */
-}
-
-/*
- * Copy data out to user space in the vmalloc case
- */
-static void mcam_frame_tasklet(unsigned long data)
-{
- struct mcam_camera *cam = (struct mcam_camera *) data;
- int i;
- unsigned long flags;
- struct mcam_vb_buffer *buf;
-
- spin_lock_irqsave(&cam->dev_lock, flags);
- for (i = 0; i < cam->nbufs; i++) {
- int bufno = cam->next_buf;
-
- if (cam->state != S_STREAMING || bufno < 0)
- break; /* I/O got stopped */
- if (++(cam->next_buf) >= cam->nbufs)
- cam->next_buf = 0;
- if (!test_bit(bufno, &cam->flags))
- continue;
- if (list_empty(&cam->buffers)) {
- singles++;
- break; /* Leave it valid, hope for better later */
- }
- delivered++;
- clear_bit(bufno, &cam->flags);
- buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer,
- queue);
- list_del_init(&buf->queue);
- /*
- * Drop the lock during the big copy. This *should* be safe...
- */
- spin_unlock_irqrestore(&cam->dev_lock, flags);
- memcpy(vb2_plane_vaddr(&buf->vb_buf, 0), cam->dma_bufs[bufno],
- cam->pix_format.sizeimage);
- mcam_buffer_done(cam, bufno, &buf->vb_buf);
- spin_lock_irqsave(&cam->dev_lock, flags);
- }
- spin_unlock_irqrestore(&cam->dev_lock, flags);
-}
-
-
-/*
- * Make sure our allocated buffers are up to the task.
- */
-static int mcam_check_dma_buffers(struct mcam_camera *cam)
-{
- if (cam->nbufs > 0 && cam->dma_buf_size < cam->pix_format.sizeimage)
- mcam_free_dma_bufs(cam);
- if (cam->nbufs == 0)
- return mcam_alloc_dma_bufs(cam, 0);
- return 0;
-}
-
-static void mcam_vmalloc_done(struct mcam_camera *cam, int frame)
-{
- tasklet_schedule(&cam->s_tasklet);
-}
-
-#else /* MCAM_MODE_VMALLOC */
-
-static inline int mcam_alloc_dma_bufs(struct mcam_camera *cam, int loadtime)
-{
- return 0;
-}
-
-static inline void mcam_free_dma_bufs(struct mcam_camera *cam)
-{
- return;
-}
-
-static inline int mcam_check_dma_buffers(struct mcam_camera *cam)
-{
- return 0;
-}
-
-
-
-#endif /* MCAM_MODE_VMALLOC */
-
-
-#ifdef MCAM_MODE_DMA_CONTIG
-/* ---------------------------------------------------------------------- */
-/*
- * DMA-contiguous code.
- */
-/*
- * Set up a contiguous buffer for the given frame. Here also is where
- * the underrun strategy is set: if there is no buffer available, reuse
- * the buffer from the other BAR and set the CF_SINGLE_BUFFER flag to
- * keep the interrupt handler from giving that buffer back to user
- * space. In this way, we always have a buffer to DMA to and don't
- * have to try to play games stopping and restarting the controller.
- */
-static void mcam_set_contig_buffer(struct mcam_camera *cam, int frame)
-{
- struct mcam_vb_buffer *buf;
- /*
- * If there are no available buffers, go into single mode
- */
- if (list_empty(&cam->buffers)) {
- buf = cam->vb_bufs[frame ^ 0x1];
- cam->vb_bufs[frame] = buf;
- mcam_reg_write(cam, frame == 0 ? REG_Y0BAR : REG_Y1BAR,
- vb2_dma_contig_plane_dma_addr(&buf->vb_buf, 0));
- set_bit(CF_SINGLE_BUFFER, &cam->flags);
- singles++;
- return;
- }
- /*
- * OK, we have a buffer we can use.
- */
- buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, queue);
- list_del_init(&buf->queue);
- mcam_reg_write(cam, frame == 0 ? REG_Y0BAR : REG_Y1BAR,
- vb2_dma_contig_plane_dma_addr(&buf->vb_buf, 0));
- cam->vb_bufs[frame] = buf;
- clear_bit(CF_SINGLE_BUFFER, &cam->flags);
-}
-
-/*
- * Initial B_DMA_contig setup.
- */
-static void mcam_ctlr_dma_contig(struct mcam_camera *cam)
-{
- mcam_reg_set_bit(cam, REG_CTRL1, C1_TWOBUFS);
- cam->nbufs = 2;
- mcam_set_contig_buffer(cam, 0);
- mcam_set_contig_buffer(cam, 1);
-}
-
-/*
- * Frame completion handling.
- */
-static void mcam_dma_contig_done(struct mcam_camera *cam, int frame)
-{
- struct mcam_vb_buffer *buf = cam->vb_bufs[frame];
-
- if (!test_bit(CF_SINGLE_BUFFER, &cam->flags)) {
- delivered++;
- mcam_buffer_done(cam, frame, &buf->vb_buf);
- }
- mcam_set_contig_buffer(cam, frame);
-}
-
-#endif /* MCAM_MODE_DMA_CONTIG */
-
-#ifdef MCAM_MODE_DMA_SG
-/* ---------------------------------------------------------------------- */
-/*
- * Scatter/gather-specific code.
- */
-
-/*
- * Set up the next buffer for S/G I/O; caller should be sure that
- * the controller is stopped and a buffer is available.
- */
-static void mcam_sg_next_buffer(struct mcam_camera *cam)
-{
- struct mcam_vb_buffer *buf;
-
- buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, queue);
- list_del_init(&buf->queue);
- /*
- * Very Bad Not Good Things happen if you don't clear
- * C1_DESC_ENA before making any descriptor changes.
- */
- mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA);
- mcam_reg_write(cam, REG_DMA_DESC_Y, buf->dma_desc_pa);
- mcam_reg_write(cam, REG_DESC_LEN_Y,
- buf->dma_desc_nent*sizeof(struct mcam_dma_desc));
- mcam_reg_write(cam, REG_DESC_LEN_U, 0);
- mcam_reg_write(cam, REG_DESC_LEN_V, 0);
- mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA);
- cam->vb_bufs[0] = buf;
-}
-
-/*
- * Initial B_DMA_sg setup
- */
-static void mcam_ctlr_dma_sg(struct mcam_camera *cam)
-{
- /*
- * The list-empty condition can hit us at resume time
- * if the buffer list was empty when the system was suspended.
- */
- if (list_empty(&cam->buffers)) {
- set_bit(CF_SG_RESTART, &cam->flags);
- return;
- }
-
- mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_3WORD);
- mcam_sg_next_buffer(cam);
- cam->nbufs = 3;
-}
-
-
-/*
- * Frame completion with S/G is trickier. We can't muck with
- * a descriptor chain on the fly, since the controller buffers it
- * internally. So we have to actually stop and restart; Marvell
- * says this is the way to do it.
- *
- * Of course, stopping is easier said than done; experience shows
- * that the controller can start a frame *after* C0_ENABLE has been
- * cleared. So when running in S/G mode, the controller is "stopped"
- * on receipt of the start-of-frame interrupt. That means we can
- * safely change the DMA descriptor array here and restart things
- * (assuming there's another buffer waiting to go).
- */
-static void mcam_dma_sg_done(struct mcam_camera *cam, int frame)
-{
- struct mcam_vb_buffer *buf = cam->vb_bufs[0];
-
- /*
- * If we're no longer supposed to be streaming, don't do anything.
- */
- if (cam->state != S_STREAMING)
- return;
- /*
- * If we have another buffer available, put it in and
- * restart the engine.
- */
- if (!list_empty(&cam->buffers)) {
- mcam_sg_next_buffer(cam);
- mcam_ctlr_start(cam);
- /*
- * Otherwise set CF_SG_RESTART and the controller will
- * be restarted once another buffer shows up.
- */
- } else {
- set_bit(CF_SG_RESTART, &cam->flags);
- singles++;
- cam->vb_bufs[0] = NULL;
- }
- /*
- * Now we can give the completed frame back to user space.
- */
- delivered++;
- mcam_buffer_done(cam, frame, &buf->vb_buf);
-}
-
-
-/*
- * Scatter/gather mode requires stopping the controller between
- * frames so we can put in a new DMA descriptor array. If no new
- * buffer exists at frame completion, the controller is left stopped;
- * this function is charged with gettig things going again.
- */
-static void mcam_sg_restart(struct mcam_camera *cam)
-{
- mcam_ctlr_dma_sg(cam);
- mcam_ctlr_start(cam);
- clear_bit(CF_SG_RESTART, &cam->flags);
-}
-
-#else /* MCAM_MODE_DMA_SG */
-
-static inline void mcam_sg_restart(struct mcam_camera *cam)
-{
- return;
-}
-
-#endif /* MCAM_MODE_DMA_SG */
-
-/* ---------------------------------------------------------------------- */
-/*
- * Buffer-mode-independent controller code.
- */
-
-/*
- * Image format setup
- */
-static void mcam_ctlr_image(struct mcam_camera *cam)
-{
- int imgsz;
- struct v4l2_pix_format *fmt = &cam->pix_format;
-
- imgsz = ((fmt->height << IMGSZ_V_SHIFT) & IMGSZ_V_MASK) |
- (fmt->bytesperline & IMGSZ_H_MASK);
- mcam_reg_write(cam, REG_IMGSIZE, imgsz);
- mcam_reg_write(cam, REG_IMGOFFSET, 0);
- /* YPITCH just drops the last two bits */
- mcam_reg_write_mask(cam, REG_IMGPITCH, fmt->bytesperline,
- IMGP_YP_MASK);
- /*
- * Tell the controller about the image format we are using.
- */
- switch (cam->pix_format.pixelformat) {
- case V4L2_PIX_FMT_YUYV:
- mcam_reg_write_mask(cam, REG_CTRL0,
- C0_DF_YUV|C0_YUV_PACKED|C0_YUVE_YUYV,
- C0_DF_MASK);
- break;
-
- case V4L2_PIX_FMT_RGB444:
- mcam_reg_write_mask(cam, REG_CTRL0,
- C0_DF_RGB|C0_RGBF_444|C0_RGB4_XRGB,
- C0_DF_MASK);
- /* Alpha value? */
- break;
-
- case V4L2_PIX_FMT_RGB565:
- mcam_reg_write_mask(cam, REG_CTRL0,
- C0_DF_RGB|C0_RGBF_565|C0_RGB5_BGGR,
- C0_DF_MASK);
- break;
-
- default:
- cam_err(cam, "Unknown format %x\n", cam->pix_format.pixelformat);
- break;
- }
- /*
- * Make sure it knows we want to use hsync/vsync.
- */
- mcam_reg_write_mask(cam, REG_CTRL0, C0_SIF_HVSYNC,
- C0_SIFM_MASK);
-}
-
-
-/*
- * Configure the controller for operation; caller holds the
- * device mutex.
- */
-static int mcam_ctlr_configure(struct mcam_camera *cam)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cam->dev_lock, flags);
- clear_bit(CF_SG_RESTART, &cam->flags);
- cam->dma_setup(cam);
- mcam_ctlr_image(cam);
- mcam_set_config_needed(cam, 0);
- spin_unlock_irqrestore(&cam->dev_lock, flags);
- return 0;
-}
-
-static void mcam_ctlr_irq_enable(struct mcam_camera *cam)
-{
- /*
- * Clear any pending interrupts, since we do not
- * expect to have I/O active prior to enabling.
- */
- mcam_reg_write(cam, REG_IRQSTAT, FRAMEIRQS);
- mcam_reg_set_bit(cam, REG_IRQMASK, FRAMEIRQS);
-}
-
-static void mcam_ctlr_irq_disable(struct mcam_camera *cam)
-{
- mcam_reg_clear_bit(cam, REG_IRQMASK, FRAMEIRQS);
-}
-
-
-
-static void mcam_ctlr_init(struct mcam_camera *cam)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cam->dev_lock, flags);
- /*
- * Make sure it's not powered down.
- */
- mcam_reg_clear_bit(cam, REG_CTRL1, C1_PWRDWN);
- /*
- * Turn off the enable bit. It sure should be off anyway,
- * but it's good to be sure.
- */
- mcam_reg_clear_bit(cam, REG_CTRL0, C0_ENABLE);
- /*
- * Clock the sensor appropriately. Controller clock should
- * be 48MHz, sensor "typical" value is half that.
- */
- mcam_reg_write_mask(cam, REG_CLKCTRL, 2, CLK_DIV_MASK);
- spin_unlock_irqrestore(&cam->dev_lock, flags);
-}
-
-
-/*
- * Stop the controller, and don't return until we're really sure that no
- * further DMA is going on.
- */
-static void mcam_ctlr_stop_dma(struct mcam_camera *cam)
-{
- unsigned long flags;
-
- /*
- * Theory: stop the camera controller (whether it is operating
- * or not). Delay briefly just in case we race with the SOF
- * interrupt, then wait until no DMA is active.
- */
- spin_lock_irqsave(&cam->dev_lock, flags);
- clear_bit(CF_SG_RESTART, &cam->flags);
- mcam_ctlr_stop(cam);
- cam->state = S_IDLE;
- spin_unlock_irqrestore(&cam->dev_lock, flags);
- /*
- * This is a brutally long sleep, but experience shows that
- * it can take the controller a while to get the message that
- * it needs to stop grabbing frames. In particular, we can
- * sometimes (on mmp) get a frame at the end WITHOUT the
- * start-of-frame indication.
- */
- msleep(150);
- if (test_bit(CF_DMA_ACTIVE, &cam->flags))
- cam_err(cam, "Timeout waiting for DMA to end\n");
- /* This would be bad news - what now? */
- spin_lock_irqsave(&cam->dev_lock, flags);
- mcam_ctlr_irq_disable(cam);
- spin_unlock_irqrestore(&cam->dev_lock, flags);
-}
-
-/*
- * Power up and down.
- */
-static void mcam_ctlr_power_up(struct mcam_camera *cam)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cam->dev_lock, flags);
- cam->plat_power_up(cam);
- mcam_reg_clear_bit(cam, REG_CTRL1, C1_PWRDWN);
- spin_unlock_irqrestore(&cam->dev_lock, flags);
- msleep(5); /* Just to be sure */
-}
-
-static void mcam_ctlr_power_down(struct mcam_camera *cam)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cam->dev_lock, flags);
- /*
- * School of hard knocks department: be sure we do any register
- * twiddling on the controller *before* calling the platform
- * power down routine.
- */
- mcam_reg_set_bit(cam, REG_CTRL1, C1_PWRDWN);
- cam->plat_power_down(cam);
- spin_unlock_irqrestore(&cam->dev_lock, flags);
-}
-
-/* -------------------------------------------------------------------- */
-/*
- * Communications with the sensor.
- */
-
-static int __mcam_cam_reset(struct mcam_camera *cam)
-{
- return sensor_call(cam, core, reset, 0);
-}
-
-/*
- * We have found the sensor on the i2c. Let's try to have a
- * conversation.
- */
-static int mcam_cam_init(struct mcam_camera *cam)
-{
- struct v4l2_dbg_chip_ident chip;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- if (cam->state != S_NOTREADY)
- cam_warn(cam, "Cam init with device in funky state %d",
- cam->state);
- ret = __mcam_cam_reset(cam);
- if (ret)
- goto out;
- chip.ident = V4L2_IDENT_NONE;
- chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR;
- chip.match.addr = cam->sensor_addr;
- ret = sensor_call(cam, core, g_chip_ident, &chip);
- if (ret)
- goto out;
- cam->sensor_type = chip.ident;
- if (cam->sensor_type != V4L2_IDENT_OV7670) {
- cam_err(cam, "Unsupported sensor type 0x%x", cam->sensor_type);
- ret = -EINVAL;
- goto out;
- }
-/* Get/set parameters? */
- ret = 0;
- cam->state = S_IDLE;
-out:
- mcam_ctlr_power_down(cam);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-/*
- * Configure the sensor to match the parameters we have. Caller should
- * hold s_mutex
- */
-static int mcam_cam_set_flip(struct mcam_camera *cam)
-{
- struct v4l2_control ctrl;
-
- memset(&ctrl, 0, sizeof(ctrl));
- ctrl.id = V4L2_CID_VFLIP;
- ctrl.value = flip;
- return sensor_call(cam, core, s_ctrl, &ctrl);
-}
-
-
-static int mcam_cam_configure(struct mcam_camera *cam)
-{
- struct v4l2_mbus_framefmt mbus_fmt;
- int ret;
-
- v4l2_fill_mbus_format(&mbus_fmt, &cam->pix_format, cam->mbus_code);
- ret = sensor_call(cam, core, init, 0);
- if (ret == 0)
- ret = sensor_call(cam, video, s_mbus_fmt, &mbus_fmt);
- /*
- * OV7670 does weird things if flip is set *before* format...
- */
- ret += mcam_cam_set_flip(cam);
- return ret;
-}
-
-/*
- * Get everything ready, and start grabbing frames.
- */
-static int mcam_read_setup(struct mcam_camera *cam)
-{
- int ret;
- unsigned long flags;
-
- /*
- * Configuration. If we still don't have DMA buffers,
- * make one last, desperate attempt.
- */
- if (cam->buffer_mode == B_vmalloc && cam->nbufs == 0 &&
- mcam_alloc_dma_bufs(cam, 0))
- return -ENOMEM;
-
- if (mcam_needs_config(cam)) {
- mcam_cam_configure(cam);
- ret = mcam_ctlr_configure(cam);
- if (ret)
- return ret;
- }
-
- /*
- * Turn it loose.
- */
- spin_lock_irqsave(&cam->dev_lock, flags);
- clear_bit(CF_DMA_ACTIVE, &cam->flags);
- mcam_reset_buffers(cam);
- mcam_ctlr_irq_enable(cam);
- cam->state = S_STREAMING;
- if (!test_bit(CF_SG_RESTART, &cam->flags))
- mcam_ctlr_start(cam);
- spin_unlock_irqrestore(&cam->dev_lock, flags);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-/*
- * Videobuf2 interface code.
- */
-
-static int mcam_vb_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt, unsigned int *nbufs,
- unsigned int *num_planes, unsigned int sizes[],
- void *alloc_ctxs[])
-{
- struct mcam_camera *cam = vb2_get_drv_priv(vq);
- int minbufs = (cam->buffer_mode == B_DMA_contig) ? 3 : 2;
-
- sizes[0] = cam->pix_format.sizeimage;
- *num_planes = 1; /* Someday we have to support planar formats... */
- if (*nbufs < minbufs)
- *nbufs = minbufs;
- if (cam->buffer_mode == B_DMA_contig)
- alloc_ctxs[0] = cam->vb_alloc_ctx;
- return 0;
-}
-
-
-static void mcam_vb_buf_queue(struct vb2_buffer *vb)
-{
- struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
- struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
- unsigned long flags;
- int start;
-
- spin_lock_irqsave(&cam->dev_lock, flags);
- start = (cam->state == S_BUFWAIT) && !list_empty(&cam->buffers);
- list_add(&mvb->queue, &cam->buffers);
- if (cam->state == S_STREAMING && test_bit(CF_SG_RESTART, &cam->flags))
- mcam_sg_restart(cam);
- spin_unlock_irqrestore(&cam->dev_lock, flags);
- if (start)
- mcam_read_setup(cam);
-}
-
-
-/*
- * vb2 uses these to release the mutex when waiting in dqbuf. I'm
- * not actually sure we need to do this (I'm not sure that vb2_dqbuf() needs
- * to be called with the mutex held), but better safe than sorry.
- */
-static void mcam_vb_wait_prepare(struct vb2_queue *vq)
-{
- struct mcam_camera *cam = vb2_get_drv_priv(vq);
-
- mutex_unlock(&cam->s_mutex);
-}
-
-static void mcam_vb_wait_finish(struct vb2_queue *vq)
-{
- struct mcam_camera *cam = vb2_get_drv_priv(vq);
-
- mutex_lock(&cam->s_mutex);
-}
-
-/*
- * These need to be called with the mutex held from vb2
- */
-static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
- struct mcam_camera *cam = vb2_get_drv_priv(vq);
-
- if (cam->state != S_IDLE) {
- INIT_LIST_HEAD(&cam->buffers);
- return -EINVAL;
- }
- cam->sequence = 0;
- /*
- * Videobuf2 sneakily hoards all the buffers and won't
- * give them to us until *after* streaming starts. But
- * we can't actually start streaming until we have a
- * destination. So go into a wait state and hope they
- * give us buffers soon.
- */
- if (cam->buffer_mode != B_vmalloc && list_empty(&cam->buffers)) {
- cam->state = S_BUFWAIT;
- return 0;
- }
- return mcam_read_setup(cam);
-}
-
-static int mcam_vb_stop_streaming(struct vb2_queue *vq)
-{
- struct mcam_camera *cam = vb2_get_drv_priv(vq);
- unsigned long flags;
-
- if (cam->state == S_BUFWAIT) {
- /* They never gave us buffers */
- cam->state = S_IDLE;
- return 0;
- }
- if (cam->state != S_STREAMING)
- return -EINVAL;
- mcam_ctlr_stop_dma(cam);
- /*
- * VB2 reclaims the buffers, so we need to forget
- * about them.
- */
- spin_lock_irqsave(&cam->dev_lock, flags);
- INIT_LIST_HEAD(&cam->buffers);
- spin_unlock_irqrestore(&cam->dev_lock, flags);
- return 0;
-}
-
-
-static const struct vb2_ops mcam_vb2_ops = {
- .queue_setup = mcam_vb_queue_setup,
- .buf_queue = mcam_vb_buf_queue,
- .start_streaming = mcam_vb_start_streaming,
- .stop_streaming = mcam_vb_stop_streaming,
- .wait_prepare = mcam_vb_wait_prepare,
- .wait_finish = mcam_vb_wait_finish,
-};
-
-
-#ifdef MCAM_MODE_DMA_SG
-/*
- * Scatter/gather mode uses all of the above functions plus a
- * few extras to deal with DMA mapping.
- */
-static int mcam_vb_sg_buf_init(struct vb2_buffer *vb)
-{
- struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
- struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
- int ndesc = cam->pix_format.sizeimage/PAGE_SIZE + 1;
-
- mvb->dma_desc = dma_alloc_coherent(cam->dev,
- ndesc * sizeof(struct mcam_dma_desc),
- &mvb->dma_desc_pa, GFP_KERNEL);
- if (mvb->dma_desc == NULL) {
- cam_err(cam, "Unable to get DMA descriptor array\n");
- return -ENOMEM;
- }
- return 0;
-}
-
-static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb)
-{
- struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
- struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0);
- struct mcam_dma_desc *desc = mvb->dma_desc;
- struct scatterlist *sg;
- int i;
-
- mvb->dma_desc_nent = dma_map_sg(cam->dev, sgd->sglist, sgd->num_pages,
- DMA_FROM_DEVICE);
- if (mvb->dma_desc_nent <= 0)
- return -EIO; /* Not sure what's right here */
- for_each_sg(sgd->sglist, sg, mvb->dma_desc_nent, i) {
- desc->dma_addr = sg_dma_address(sg);
- desc->segment_len = sg_dma_len(sg);
- desc++;
- }
- return 0;
-}
-
-static int mcam_vb_sg_buf_finish(struct vb2_buffer *vb)
-{
- struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0);
-
- dma_unmap_sg(cam->dev, sgd->sglist, sgd->num_pages, DMA_FROM_DEVICE);
- return 0;
-}
-
-static void mcam_vb_sg_buf_cleanup(struct vb2_buffer *vb)
-{
- struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
- struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
- int ndesc = cam->pix_format.sizeimage/PAGE_SIZE + 1;
-
- dma_free_coherent(cam->dev, ndesc * sizeof(struct mcam_dma_desc),
- mvb->dma_desc, mvb->dma_desc_pa);
-}
-
-
-static const struct vb2_ops mcam_vb2_sg_ops = {
- .queue_setup = mcam_vb_queue_setup,
- .buf_init = mcam_vb_sg_buf_init,
- .buf_prepare = mcam_vb_sg_buf_prepare,
- .buf_queue = mcam_vb_buf_queue,
- .buf_finish = mcam_vb_sg_buf_finish,
- .buf_cleanup = mcam_vb_sg_buf_cleanup,
- .start_streaming = mcam_vb_start_streaming,
- .stop_streaming = mcam_vb_stop_streaming,
- .wait_prepare = mcam_vb_wait_prepare,
- .wait_finish = mcam_vb_wait_finish,
-};
-
-#endif /* MCAM_MODE_DMA_SG */
-
-static int mcam_setup_vb2(struct mcam_camera *cam)
-{
- struct vb2_queue *vq = &cam->vb_queue;
-
- memset(vq, 0, sizeof(*vq));
- vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- vq->drv_priv = cam;
- INIT_LIST_HEAD(&cam->buffers);
- switch (cam->buffer_mode) {
- case B_DMA_contig:
-#ifdef MCAM_MODE_DMA_CONTIG
- vq->ops = &mcam_vb2_ops;
- vq->mem_ops = &vb2_dma_contig_memops;
- cam->vb_alloc_ctx = vb2_dma_contig_init_ctx(cam->dev);
- vq->io_modes = VB2_MMAP | VB2_USERPTR;
- cam->dma_setup = mcam_ctlr_dma_contig;
- cam->frame_complete = mcam_dma_contig_done;
-#endif
- break;
- case B_DMA_sg:
-#ifdef MCAM_MODE_DMA_SG
- vq->ops = &mcam_vb2_sg_ops;
- vq->mem_ops = &vb2_dma_sg_memops;
- vq->io_modes = VB2_MMAP | VB2_USERPTR;
- cam->dma_setup = mcam_ctlr_dma_sg;
- cam->frame_complete = mcam_dma_sg_done;
-#endif
- break;
- case B_vmalloc:
-#ifdef MCAM_MODE_VMALLOC
- tasklet_init(&cam->s_tasklet, mcam_frame_tasklet,
- (unsigned long) cam);
- vq->ops = &mcam_vb2_ops;
- vq->mem_ops = &vb2_vmalloc_memops;
- vq->buf_struct_size = sizeof(struct mcam_vb_buffer);
- vq->io_modes = VB2_MMAP;
- cam->dma_setup = mcam_ctlr_dma_vmalloc;
- cam->frame_complete = mcam_vmalloc_done;
-#endif
- break;
- }
- return vb2_queue_init(vq);
-}
-
-static void mcam_cleanup_vb2(struct mcam_camera *cam)
-{
- vb2_queue_release(&cam->vb_queue);
-#ifdef MCAM_MODE_DMA_CONTIG
- if (cam->buffer_mode == B_DMA_contig)
- vb2_dma_contig_cleanup_ctx(cam->vb_alloc_ctx);
-#endif
-}
-
-
-/* ---------------------------------------------------------------------- */
-/*
- * The long list of V4L2 ioctl() operations.
- */
-
-static int mcam_vidioc_streamon(struct file *filp, void *priv,
- enum v4l2_buf_type type)
-{
- struct mcam_camera *cam = filp->private_data;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = vb2_streamon(&cam->vb_queue, type);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-
-static int mcam_vidioc_streamoff(struct file *filp, void *priv,
- enum v4l2_buf_type type)
-{
- struct mcam_camera *cam = filp->private_data;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = vb2_streamoff(&cam->vb_queue, type);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-
-static int mcam_vidioc_reqbufs(struct file *filp, void *priv,
- struct v4l2_requestbuffers *req)
-{
- struct mcam_camera *cam = filp->private_data;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = vb2_reqbufs(&cam->vb_queue, req);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-
-static int mcam_vidioc_querybuf(struct file *filp, void *priv,
- struct v4l2_buffer *buf)
-{
- struct mcam_camera *cam = filp->private_data;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = vb2_querybuf(&cam->vb_queue, buf);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-static int mcam_vidioc_qbuf(struct file *filp, void *priv,
- struct v4l2_buffer *buf)
-{
- struct mcam_camera *cam = filp->private_data;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = vb2_qbuf(&cam->vb_queue, buf);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-static int mcam_vidioc_dqbuf(struct file *filp, void *priv,
- struct v4l2_buffer *buf)
-{
- struct mcam_camera *cam = filp->private_data;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = vb2_dqbuf(&cam->vb_queue, buf, filp->f_flags & O_NONBLOCK);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-
-
-static int mcam_vidioc_queryctrl(struct file *filp, void *priv,
- struct v4l2_queryctrl *qc)
-{
- struct mcam_camera *cam = priv;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = sensor_call(cam, core, queryctrl, qc);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-
-static int mcam_vidioc_g_ctrl(struct file *filp, void *priv,
- struct v4l2_control *ctrl)
-{
- struct mcam_camera *cam = priv;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = sensor_call(cam, core, g_ctrl, ctrl);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-
-static int mcam_vidioc_s_ctrl(struct file *filp, void *priv,
- struct v4l2_control *ctrl)
-{
- struct mcam_camera *cam = priv;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = sensor_call(cam, core, s_ctrl, ctrl);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-
-static int mcam_vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- strcpy(cap->driver, "marvell_ccic");
- strcpy(cap->card, "marvell_ccic");
- cap->version = 1;
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
- return 0;
-}
-
-
-static int mcam_vidioc_enum_fmt_vid_cap(struct file *filp,
- void *priv, struct v4l2_fmtdesc *fmt)
-{
- if (fmt->index >= N_MCAM_FMTS)
- return -EINVAL;
- strlcpy(fmt->description, mcam_formats[fmt->index].desc,
- sizeof(fmt->description));
- fmt->pixelformat = mcam_formats[fmt->index].pixelformat;
- return 0;
-}
-
-static int mcam_vidioc_try_fmt_vid_cap(struct file *filp, void *priv,
- struct v4l2_format *fmt)
-{
- struct mcam_camera *cam = priv;
- struct mcam_format_struct *f;
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
- struct v4l2_mbus_framefmt mbus_fmt;
- int ret;
-
- f = mcam_find_format(pix->pixelformat);
- pix->pixelformat = f->pixelformat;
- v4l2_fill_mbus_format(&mbus_fmt, pix, f->mbus_code);
- mutex_lock(&cam->s_mutex);
- ret = sensor_call(cam, video, try_mbus_fmt, &mbus_fmt);
- mutex_unlock(&cam->s_mutex);
- v4l2_fill_pix_format(pix, &mbus_fmt);
- pix->bytesperline = pix->width * f->bpp;
- pix->sizeimage = pix->height * pix->bytesperline;
- return ret;
-}
-
-static int mcam_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
- struct v4l2_format *fmt)
-{
- struct mcam_camera *cam = priv;
- struct mcam_format_struct *f;
- int ret;
-
- /*
- * Can't do anything if the device is not idle
- * Also can't if there are streaming buffers in place.
- */
- if (cam->state != S_IDLE || cam->vb_queue.num_buffers > 0)
- return -EBUSY;
-
- f = mcam_find_format(fmt->fmt.pix.pixelformat);
-
- /*
- * See if the formatting works in principle.
- */
- ret = mcam_vidioc_try_fmt_vid_cap(filp, priv, fmt);
- if (ret)
- return ret;
- /*
- * Now we start to change things for real, so let's do it
- * under lock.
- */
- mutex_lock(&cam->s_mutex);
- cam->pix_format = fmt->fmt.pix;
- cam->mbus_code = f->mbus_code;
-
- /*
- * Make sure we have appropriate DMA buffers.
- */
- if (cam->buffer_mode == B_vmalloc) {
- ret = mcam_check_dma_buffers(cam);
- if (ret)
- goto out;
- }
- mcam_set_config_needed(cam, 1);
-out:
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-/*
- * Return our stored notion of how the camera is/should be configured.
- * The V4l2 spec wants us to be smarter, and actually get this from
- * the camera (and not mess with it at open time). Someday.
- */
-static int mcam_vidioc_g_fmt_vid_cap(struct file *filp, void *priv,
- struct v4l2_format *f)
-{
- struct mcam_camera *cam = priv;
-
- f->fmt.pix = cam->pix_format;
- return 0;
-}
-
-/*
- * We only have one input - the sensor - so minimize the nonsense here.
- */
-static int mcam_vidioc_enum_input(struct file *filp, void *priv,
- struct v4l2_input *input)
-{
- if (input->index != 0)
- return -EINVAL;
-
- input->type = V4L2_INPUT_TYPE_CAMERA;
- input->std = V4L2_STD_ALL; /* Not sure what should go here */
- strcpy(input->name, "Camera");
- return 0;
-}
-
-static int mcam_vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int mcam_vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
- if (i != 0)
- return -EINVAL;
- return 0;
-}
-
-/* from vivi.c */
-static int mcam_vidioc_s_std(struct file *filp, void *priv, v4l2_std_id *a)
-{
- return 0;
-}
-
-/*
- * G/S_PARM. Most of this is done by the sensor, but we are
- * the level which controls the number of read buffers.
- */
-static int mcam_vidioc_g_parm(struct file *filp, void *priv,
- struct v4l2_streamparm *parms)
-{
- struct mcam_camera *cam = priv;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = sensor_call(cam, video, g_parm, parms);
- mutex_unlock(&cam->s_mutex);
- parms->parm.capture.readbuffers = n_dma_bufs;
- return ret;
-}
-
-static int mcam_vidioc_s_parm(struct file *filp, void *priv,
- struct v4l2_streamparm *parms)
-{
- struct mcam_camera *cam = priv;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = sensor_call(cam, video, s_parm, parms);
- mutex_unlock(&cam->s_mutex);
- parms->parm.capture.readbuffers = n_dma_bufs;
- return ret;
-}
-
-static int mcam_vidioc_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct mcam_camera *cam = priv;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (v4l2_chip_match_host(&chip->match)) {
- chip->ident = cam->chip_id;
- return 0;
- }
- return sensor_call(cam, core, g_chip_ident, chip);
-}
-
-static int mcam_vidioc_enum_framesizes(struct file *filp, void *priv,
- struct v4l2_frmsizeenum *sizes)
-{
- struct mcam_camera *cam = priv;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = sensor_call(cam, video, enum_framesizes, sizes);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-static int mcam_vidioc_enum_frameintervals(struct file *filp, void *priv,
- struct v4l2_frmivalenum *interval)
-{
- struct mcam_camera *cam = priv;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = sensor_call(cam, video, enum_frameintervals, interval);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mcam_vidioc_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct mcam_camera *cam = priv;
-
- if (v4l2_chip_match_host(&reg->match)) {
- reg->val = mcam_reg_read(cam, reg->reg);
- reg->size = 4;
- return 0;
- }
- return sensor_call(cam, core, g_register, reg);
-}
-
-static int mcam_vidioc_s_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct mcam_camera *cam = priv;
-
- if (v4l2_chip_match_host(&reg->match)) {
- mcam_reg_write(cam, reg->reg, reg->val);
- return 0;
- }
- return sensor_call(cam, core, s_register, reg);
-}
-#endif
-
-static const struct v4l2_ioctl_ops mcam_v4l_ioctl_ops = {
- .vidioc_querycap = mcam_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = mcam_vidioc_enum_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = mcam_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = mcam_vidioc_s_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = mcam_vidioc_g_fmt_vid_cap,
- .vidioc_enum_input = mcam_vidioc_enum_input,
- .vidioc_g_input = mcam_vidioc_g_input,
- .vidioc_s_input = mcam_vidioc_s_input,
- .vidioc_s_std = mcam_vidioc_s_std,
- .vidioc_reqbufs = mcam_vidioc_reqbufs,
- .vidioc_querybuf = mcam_vidioc_querybuf,
- .vidioc_qbuf = mcam_vidioc_qbuf,
- .vidioc_dqbuf = mcam_vidioc_dqbuf,
- .vidioc_streamon = mcam_vidioc_streamon,
- .vidioc_streamoff = mcam_vidioc_streamoff,
- .vidioc_queryctrl = mcam_vidioc_queryctrl,
- .vidioc_g_ctrl = mcam_vidioc_g_ctrl,
- .vidioc_s_ctrl = mcam_vidioc_s_ctrl,
- .vidioc_g_parm = mcam_vidioc_g_parm,
- .vidioc_s_parm = mcam_vidioc_s_parm,
- .vidioc_enum_framesizes = mcam_vidioc_enum_framesizes,
- .vidioc_enum_frameintervals = mcam_vidioc_enum_frameintervals,
- .vidioc_g_chip_ident = mcam_vidioc_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = mcam_vidioc_g_register,
- .vidioc_s_register = mcam_vidioc_s_register,
-#endif
-};
-
-/* ---------------------------------------------------------------------- */
-/*
- * Our various file operations.
- */
-static int mcam_v4l_open(struct file *filp)
-{
- struct mcam_camera *cam = video_drvdata(filp);
- int ret = 0;
-
- filp->private_data = cam;
-
- frames = singles = delivered = 0;
- mutex_lock(&cam->s_mutex);
- if (cam->users == 0) {
- ret = mcam_setup_vb2(cam);
- if (ret)
- goto out;
- mcam_ctlr_power_up(cam);
- __mcam_cam_reset(cam);
- mcam_set_config_needed(cam, 1);
- }
- (cam->users)++;
-out:
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-
-static int mcam_v4l_release(struct file *filp)
-{
- struct mcam_camera *cam = filp->private_data;
-
- cam_dbg(cam, "Release, %d frames, %d singles, %d delivered\n", frames,
- singles, delivered);
- mutex_lock(&cam->s_mutex);
- (cam->users)--;
- if (cam->users == 0) {
- mcam_ctlr_stop_dma(cam);
- mcam_cleanup_vb2(cam);
- mcam_ctlr_power_down(cam);
- if (cam->buffer_mode == B_vmalloc && alloc_bufs_at_read)
- mcam_free_dma_bufs(cam);
- }
- mutex_unlock(&cam->s_mutex);
- return 0;
-}
-
-static ssize_t mcam_v4l_read(struct file *filp,
- char __user *buffer, size_t len, loff_t *pos)
-{
- struct mcam_camera *cam = filp->private_data;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = vb2_read(&cam->vb_queue, buffer, len, pos,
- filp->f_flags & O_NONBLOCK);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-
-
-static unsigned int mcam_v4l_poll(struct file *filp,
- struct poll_table_struct *pt)
-{
- struct mcam_camera *cam = filp->private_data;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = vb2_poll(&cam->vb_queue, filp, pt);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-
-static int mcam_v4l_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- struct mcam_camera *cam = filp->private_data;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = vb2_mmap(&cam->vb_queue, vma);
- mutex_unlock(&cam->s_mutex);
- return ret;
-}
-
-
-
-static const struct v4l2_file_operations mcam_v4l_fops = {
- .owner = THIS_MODULE,
- .open = mcam_v4l_open,
- .release = mcam_v4l_release,
- .read = mcam_v4l_read,
- .poll = mcam_v4l_poll,
- .mmap = mcam_v4l_mmap,
- .unlocked_ioctl = video_ioctl2,
-};
-
-
-/*
- * This template device holds all of those v4l2 methods; we
- * clone it for specific real devices.
- */
-static struct video_device mcam_v4l_template = {
- .name = "mcam",
- .tvnorms = V4L2_STD_NTSC_M,
- .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */
-
- .fops = &mcam_v4l_fops,
- .ioctl_ops = &mcam_v4l_ioctl_ops,
- .release = video_device_release_empty,
-};
-
-/* ---------------------------------------------------------------------- */
-/*
- * Interrupt handler stuff
- */
-static void mcam_frame_complete(struct mcam_camera *cam, int frame)
-{
- /*
- * Basic frame housekeeping.
- */
- set_bit(frame, &cam->flags);
- clear_bit(CF_DMA_ACTIVE, &cam->flags);
- cam->next_buf = frame;
- cam->buf_seq[frame] = ++(cam->sequence);
- frames++;
- /*
- * "This should never happen"
- */
- if (cam->state != S_STREAMING)
- return;
- /*
- * Process the frame and set up the next one.
- */
- cam->frame_complete(cam, frame);
-}
-
-
-/*
- * The interrupt handler; this needs to be called from the
- * platform irq handler with the lock held.
- */
-int mccic_irq(struct mcam_camera *cam, unsigned int irqs)
-{
- unsigned int frame, handled = 0;
-
- mcam_reg_write(cam, REG_IRQSTAT, FRAMEIRQS); /* Clear'em all */
- /*
- * Handle any frame completions. There really should
- * not be more than one of these, or we have fallen
- * far behind.
- *
- * When running in S/G mode, the frame number lacks any
- * real meaning - there's only one descriptor array - but
- * the controller still picks a different one to signal
- * each time.
- */
- for (frame = 0; frame < cam->nbufs; frame++)
- if (irqs & (IRQ_EOF0 << frame)) {
- mcam_frame_complete(cam, frame);
- handled = 1;
- if (cam->buffer_mode == B_DMA_sg)
- break;
- }
- /*
- * If a frame starts, note that we have DMA active. This
- * code assumes that we won't get multiple frame interrupts
- * at once; may want to rethink that.
- */
- if (irqs & (IRQ_SOF0 | IRQ_SOF1 | IRQ_SOF2)) {
- set_bit(CF_DMA_ACTIVE, &cam->flags);
- handled = 1;
- if (cam->buffer_mode == B_DMA_sg)
- mcam_ctlr_stop(cam);
- }
- return handled;
-}
-
-/* ---------------------------------------------------------------------- */
-/*
- * Registration and such.
- */
-static struct ov7670_config sensor_cfg = {
- /*
- * Exclude QCIF mode, because it only captures a tiny portion
- * of the sensor FOV
- */
- .min_width = 320,
- .min_height = 240,
-};
-
-
-int mccic_register(struct mcam_camera *cam)
-{
- struct i2c_board_info ov7670_info = {
- .type = "ov7670",
- .addr = 0x42 >> 1,
- .platform_data = &sensor_cfg,
- };
- int ret;
-
- /*
- * Validate the requested buffer mode.
- */
- if (buffer_mode >= 0)
- cam->buffer_mode = buffer_mode;
- if (cam->buffer_mode == B_DMA_sg &&
- cam->chip_id == V4L2_IDENT_CAFE) {
- printk(KERN_ERR "marvell-cam: Cafe can't do S/G I/O, "
- "attempting vmalloc mode instead\n");
- cam->buffer_mode = B_vmalloc;
- }
- if (!mcam_buffer_mode_supported(cam->buffer_mode)) {
- printk(KERN_ERR "marvell-cam: buffer mode %d unsupported\n",
- cam->buffer_mode);
- return -EINVAL;
- }
- /*
- * Register with V4L
- */
- ret = v4l2_device_register(cam->dev, &cam->v4l2_dev);
- if (ret)
- return ret;
-
- mutex_init(&cam->s_mutex);
- cam->state = S_NOTREADY;
- mcam_set_config_needed(cam, 1);
- cam->pix_format = mcam_def_pix_format;
- cam->mbus_code = mcam_def_mbus_code;
- INIT_LIST_HEAD(&cam->buffers);
- mcam_ctlr_init(cam);
-
- /*
- * Try to find the sensor.
- */
- sensor_cfg.clock_speed = cam->clock_speed;
- sensor_cfg.use_smbus = cam->use_smbus;
- cam->sensor_addr = ov7670_info.addr;
- cam->sensor = v4l2_i2c_new_subdev_board(&cam->v4l2_dev,
- cam->i2c_adapter, &ov7670_info, NULL);
- if (cam->sensor == NULL) {
- ret = -ENODEV;
- goto out_unregister;
- }
-
- ret = mcam_cam_init(cam);
- if (ret)
- goto out_unregister;
- /*
- * Get the v4l2 setup done.
- */
- mutex_lock(&cam->s_mutex);
- cam->vdev = mcam_v4l_template;
- cam->vdev.debug = 0;
- cam->vdev.v4l2_dev = &cam->v4l2_dev;
- ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);
- if (ret)
- goto out;
- video_set_drvdata(&cam->vdev, cam);
-
- /*
- * If so requested, try to get our DMA buffers now.
- */
- if (cam->buffer_mode == B_vmalloc && !alloc_bufs_at_read) {
- if (mcam_alloc_dma_bufs(cam, 1))
- cam_warn(cam, "Unable to alloc DMA buffers at load"
- " will try again later.");
- }
-
-out:
- mutex_unlock(&cam->s_mutex);
- return ret;
-out_unregister:
- v4l2_device_unregister(&cam->v4l2_dev);
- return ret;
-}
-
-
-void mccic_shutdown(struct mcam_camera *cam)
-{
- /*
- * If we have no users (and we really, really should have no
- * users) the device will already be powered down. Trying to
- * take it down again will wedge the machine, which is frowned
- * upon.
- */
- if (cam->users > 0) {
- cam_warn(cam, "Removing a device with users!\n");
- mcam_ctlr_power_down(cam);
- }
- vb2_queue_release(&cam->vb_queue);
- if (cam->buffer_mode == B_vmalloc)
- mcam_free_dma_bufs(cam);
- video_unregister_device(&cam->vdev);
- v4l2_device_unregister(&cam->v4l2_dev);
-}
-
-/*
- * Power management
- */
-#ifdef CONFIG_PM
-
-void mccic_suspend(struct mcam_camera *cam)
-{
- mutex_lock(&cam->s_mutex);
- if (cam->users > 0) {
- enum mcam_state cstate = cam->state;
-
- mcam_ctlr_stop_dma(cam);
- mcam_ctlr_power_down(cam);
- cam->state = cstate;
- }
- mutex_unlock(&cam->s_mutex);
-}
-
-int mccic_resume(struct mcam_camera *cam)
-{
- int ret = 0;
-
- mutex_lock(&cam->s_mutex);
- if (cam->users > 0) {
- mcam_ctlr_power_up(cam);
- __mcam_cam_reset(cam);
- } else {
- mcam_ctlr_power_down(cam);
- }
- mutex_unlock(&cam->s_mutex);
-
- set_bit(CF_CONFIG_NEEDED, &cam->flags);
- if (cam->state == S_STREAMING) {
- /*
- * If there was a buffer in the DMA engine at suspend
- * time, put it back on the queue or we'll forget about it.
- */
- if (cam->buffer_mode == B_DMA_sg && cam->vb_bufs[0])
- list_add(&cam->vb_bufs[0]->queue, &cam->buffers);
- ret = mcam_read_setup(cam);
- }
- return ret;
-}
-#endif /* CONFIG_PM */
diff --git a/drivers/media/video/marvell-ccic/mcam-core.h b/drivers/media/video/marvell-ccic/mcam-core.h
deleted file mode 100644
index bd6acba9fb3..00000000000
--- a/drivers/media/video/marvell-ccic/mcam-core.h
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Marvell camera core structures.
- *
- * Copyright 2011 Jonathan Corbet corbet@lwn.net
- */
-#ifndef _MCAM_CORE_H
-#define _MCAM_CORE_H
-
-#include <linux/list.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-dev.h>
-#include <media/videobuf2-core.h>
-
-/*
- * Create our own symbols for the supported buffer modes, but, for now,
- * base them entirely on which videobuf2 options have been selected.
- */
-#if defined(CONFIG_VIDEOBUF2_VMALLOC) || defined(CONFIG_VIDEOBUF2_VMALLOC_MODULE)
-#define MCAM_MODE_VMALLOC 1
-#endif
-
-#if defined(CONFIG_VIDEOBUF2_DMA_CONTIG) || defined(CONFIG_VIDEOBUF2_DMA_CONTIG_MODULE)
-#define MCAM_MODE_DMA_CONTIG 1
-#endif
-
-#if defined(CONFIG_VIDEOBUF2_DMA_SG) || defined(CONFIG_VIDEOBUF2_DMA_SG_MODULE)
-#define MCAM_MODE_DMA_SG 1
-#endif
-
-#if !defined(MCAM_MODE_VMALLOC) && !defined(MCAM_MODE_DMA_CONTIG) && \
- !defined(MCAM_MODE_DMA_SG)
-#error One of the videobuf buffer modes must be selected in the config
-#endif
-
-
-enum mcam_state {
- S_NOTREADY, /* Not yet initialized */
- S_IDLE, /* Just hanging around */
- S_FLAKED, /* Some sort of problem */
- S_STREAMING, /* Streaming data */
- S_BUFWAIT /* streaming requested but no buffers yet */
-};
-#define MAX_DMA_BUFS 3
-
-/*
- * Different platforms work best with different buffer modes, so we
- * let the platform pick.
- */
-enum mcam_buffer_mode {
- B_vmalloc = 0,
- B_DMA_contig = 1,
- B_DMA_sg = 2
-};
-
-/*
- * Is a given buffer mode supported by the current kernel configuration?
- */
-static inline int mcam_buffer_mode_supported(enum mcam_buffer_mode mode)
-{
- switch (mode) {
-#ifdef MCAM_MODE_VMALLOC
- case B_vmalloc:
-#endif
-#ifdef MCAM_MODE_DMA_CONTIG
- case B_DMA_contig:
-#endif
-#ifdef MCAM_MODE_DMA_SG
- case B_DMA_sg:
-#endif
- return 1;
- default:
- return 0;
- }
-}
-
-
-/*
- * A description of one of our devices.
- * Locking: controlled by s_mutex. Certain fields, however, require
- * the dev_lock spinlock; they are marked as such by comments.
- * dev_lock is also required for access to device registers.
- */
-struct mcam_camera {
- /*
- * These fields should be set by the platform code prior to
- * calling mcam_register().
- */
- struct i2c_adapter *i2c_adapter;
- unsigned char __iomem *regs;
- spinlock_t dev_lock;
- struct device *dev; /* For messages, dma alloc */
- unsigned int chip_id;
- short int clock_speed; /* Sensor clock speed, default 30 */
- short int use_smbus; /* SMBUS or straight I2c? */
- enum mcam_buffer_mode buffer_mode;
- /*
- * Callbacks from the core to the platform code.
- */
- void (*plat_power_up) (struct mcam_camera *cam);
- void (*plat_power_down) (struct mcam_camera *cam);
-
- /*
- * Everything below here is private to the mcam core and
- * should not be touched by the platform code.
- */
- struct v4l2_device v4l2_dev;
- enum mcam_state state;
- unsigned long flags; /* Buffer status, mainly (dev_lock) */
- int users; /* How many open FDs */
-
- /*
- * Subsystem structures.
- */
- struct video_device vdev;
- struct v4l2_subdev *sensor;
- unsigned short sensor_addr;
-
- /* Videobuf2 stuff */
- struct vb2_queue vb_queue;
- struct list_head buffers; /* Available frames */
-
- unsigned int nbufs; /* How many are alloc'd */
- int next_buf; /* Next to consume (dev_lock) */
-
- /* DMA buffers - vmalloc mode */
-#ifdef MCAM_MODE_VMALLOC
- unsigned int dma_buf_size; /* allocated size */
- void *dma_bufs[MAX_DMA_BUFS]; /* Internal buffer addresses */
- dma_addr_t dma_handles[MAX_DMA_BUFS]; /* Buffer bus addresses */
- struct tasklet_struct s_tasklet;
-#endif
- unsigned int sequence; /* Frame sequence number */
- unsigned int buf_seq[MAX_DMA_BUFS]; /* Sequence for individual bufs */
-
- /* DMA buffers - DMA modes */
- struct mcam_vb_buffer *vb_bufs[MAX_DMA_BUFS];
- struct vb2_alloc_ctx *vb_alloc_ctx;
-
- /* Mode-specific ops, set at open time */
- void (*dma_setup)(struct mcam_camera *cam);
- void (*frame_complete)(struct mcam_camera *cam, int frame);
-
- /* Current operating parameters */
- u32 sensor_type; /* Currently ov7670 only */
- struct v4l2_pix_format pix_format;
- enum v4l2_mbus_pixelcode mbus_code;
-
- /* Locks */
- struct mutex s_mutex; /* Access to this structure */
-};
-
-
-/*
- * Register I/O functions. These are here because the platform code
- * may legitimately need to mess with the register space.
- */
-/*
- * Device register I/O
- */
-static inline void mcam_reg_write(struct mcam_camera *cam, unsigned int reg,
- unsigned int val)
-{
- iowrite32(val, cam->regs + reg);
-}
-
-static inline unsigned int mcam_reg_read(struct mcam_camera *cam,
- unsigned int reg)
-{
- return ioread32(cam->regs + reg);
-}
-
-
-static inline void mcam_reg_write_mask(struct mcam_camera *cam, unsigned int reg,
- unsigned int val, unsigned int mask)
-{
- unsigned int v = mcam_reg_read(cam, reg);
-
- v = (v & ~mask) | (val & mask);
- mcam_reg_write(cam, reg, v);
-}
-
-static inline void mcam_reg_clear_bit(struct mcam_camera *cam,
- unsigned int reg, unsigned int val)
-{
- mcam_reg_write_mask(cam, reg, 0, val);
-}
-
-static inline void mcam_reg_set_bit(struct mcam_camera *cam,
- unsigned int reg, unsigned int val)
-{
- mcam_reg_write_mask(cam, reg, val, val);
-}
-
-/*
- * Functions for use by platform code.
- */
-int mccic_register(struct mcam_camera *cam);
-int mccic_irq(struct mcam_camera *cam, unsigned int irqs);
-void mccic_shutdown(struct mcam_camera *cam);
-#ifdef CONFIG_PM
-void mccic_suspend(struct mcam_camera *cam);
-int mccic_resume(struct mcam_camera *cam);
-#endif
-
-/*
- * Register definitions for the m88alp01 camera interface. Offsets in bytes
- * as given in the spec.
- */
-#define REG_Y0BAR 0x00
-#define REG_Y1BAR 0x04
-#define REG_Y2BAR 0x08
-/* ... */
-
-#define REG_IMGPITCH 0x24 /* Image pitch register */
-#define IMGP_YP_SHFT 2 /* Y pitch params */
-#define IMGP_YP_MASK 0x00003ffc /* Y pitch field */
-#define IMGP_UVP_SHFT 18 /* UV pitch (planar) */
-#define IMGP_UVP_MASK 0x3ffc0000
-#define REG_IRQSTATRAW 0x28 /* RAW IRQ Status */
-#define IRQ_EOF0 0x00000001 /* End of frame 0 */
-#define IRQ_EOF1 0x00000002 /* End of frame 1 */
-#define IRQ_EOF2 0x00000004 /* End of frame 2 */
-#define IRQ_SOF0 0x00000008 /* Start of frame 0 */
-#define IRQ_SOF1 0x00000010 /* Start of frame 1 */
-#define IRQ_SOF2 0x00000020 /* Start of frame 2 */
-#define IRQ_OVERFLOW 0x00000040 /* FIFO overflow */
-#define IRQ_TWSIW 0x00010000 /* TWSI (smbus) write */
-#define IRQ_TWSIR 0x00020000 /* TWSI read */
-#define IRQ_TWSIE 0x00040000 /* TWSI error */
-#define TWSIIRQS (IRQ_TWSIW|IRQ_TWSIR|IRQ_TWSIE)
-#define FRAMEIRQS (IRQ_EOF0|IRQ_EOF1|IRQ_EOF2|IRQ_SOF0|IRQ_SOF1|IRQ_SOF2)
-#define ALLIRQS (TWSIIRQS|FRAMEIRQS|IRQ_OVERFLOW)
-#define REG_IRQMASK 0x2c /* IRQ mask - same bits as IRQSTAT */
-#define REG_IRQSTAT 0x30 /* IRQ status / clear */
-
-#define REG_IMGSIZE 0x34 /* Image size */
-#define IMGSZ_V_MASK 0x1fff0000
-#define IMGSZ_V_SHIFT 16
-#define IMGSZ_H_MASK 0x00003fff
-#define REG_IMGOFFSET 0x38 /* IMage offset */
-
-#define REG_CTRL0 0x3c /* Control 0 */
-#define C0_ENABLE 0x00000001 /* Makes the whole thing go */
-
-/* Mask for all the format bits */
-#define C0_DF_MASK 0x00fffffc /* Bits 2-23 */
-
-/* RGB ordering */
-#define C0_RGB4_RGBX 0x00000000
-#define C0_RGB4_XRGB 0x00000004
-#define C0_RGB4_BGRX 0x00000008
-#define C0_RGB4_XBGR 0x0000000c
-#define C0_RGB5_RGGB 0x00000000
-#define C0_RGB5_GRBG 0x00000004
-#define C0_RGB5_GBRG 0x00000008
-#define C0_RGB5_BGGR 0x0000000c
-
-/* Spec has two fields for DIN and DOUT, but they must match, so
- combine them here. */
-#define C0_DF_YUV 0x00000000 /* Data is YUV */
-#define C0_DF_RGB 0x000000a0 /* ... RGB */
-#define C0_DF_BAYER 0x00000140 /* ... Bayer */
-/* 8-8-8 must be missing from the below - ask */
-#define C0_RGBF_565 0x00000000
-#define C0_RGBF_444 0x00000800
-#define C0_RGB_BGR 0x00001000 /* Blue comes first */
-#define C0_YUV_PLANAR 0x00000000 /* YUV 422 planar format */
-#define C0_YUV_PACKED 0x00008000 /* YUV 422 packed */
-#define C0_YUV_420PL 0x0000a000 /* YUV 420 planar */
-/* Think that 420 packed must be 111 - ask */
-#define C0_YUVE_YUYV 0x00000000 /* Y1CbY0Cr */
-#define C0_YUVE_YVYU 0x00010000 /* Y1CrY0Cb */
-#define C0_YUVE_VYUY 0x00020000 /* CrY1CbY0 */
-#define C0_YUVE_UYVY 0x00030000 /* CbY1CrY0 */
-#define C0_YUVE_XYUV 0x00000000 /* 420: .YUV */
-#define C0_YUVE_XYVU 0x00010000 /* 420: .YVU */
-#define C0_YUVE_XUVY 0x00020000 /* 420: .UVY */
-#define C0_YUVE_XVUY 0x00030000 /* 420: .VUY */
-/* Bayer bits 18,19 if needed */
-#define C0_HPOL_LOW 0x01000000 /* HSYNC polarity active low */
-#define C0_VPOL_LOW 0x02000000 /* VSYNC polarity active low */
-#define C0_VCLK_LOW 0x04000000 /* VCLK on falling edge */
-#define C0_DOWNSCALE 0x08000000 /* Enable downscaler */
-#define C0_SIFM_MASK 0xc0000000 /* SIF mode bits */
-#define C0_SIF_HVSYNC 0x00000000 /* Use H/VSYNC */
-#define CO_SOF_NOSYNC 0x40000000 /* Use inband active signaling */
-
-/* Bits below C1_444ALPHA are not present in Cafe */
-#define REG_CTRL1 0x40 /* Control 1 */
-#define C1_CLKGATE 0x00000001 /* Sensor clock gate */
-#define C1_DESC_ENA 0x00000100 /* DMA descriptor enable */
-#define C1_DESC_3WORD 0x00000200 /* Three-word descriptors used */
-#define C1_444ALPHA 0x00f00000 /* Alpha field in RGB444 */
-#define C1_ALPHA_SHFT 20
-#define C1_DMAB32 0x00000000 /* 32-byte DMA burst */
-#define C1_DMAB16 0x02000000 /* 16-byte DMA burst */
-#define C1_DMAB64 0x04000000 /* 64-byte DMA burst */
-#define C1_DMAB_MASK 0x06000000
-#define C1_TWOBUFS 0x08000000 /* Use only two DMA buffers */
-#define C1_PWRDWN 0x10000000 /* Power down */
-
-#define REG_CLKCTRL 0x88 /* Clock control */
-#define CLK_DIV_MASK 0x0000ffff /* Upper bits RW "reserved" */
-
-/* This appears to be a Cafe-only register */
-#define REG_UBAR 0xc4 /* Upper base address register */
-
-/* Armada 610 DMA descriptor registers */
-#define REG_DMA_DESC_Y 0x200
-#define REG_DMA_DESC_U 0x204
-#define REG_DMA_DESC_V 0x208
-#define REG_DESC_LEN_Y 0x20c /* Lengths are in bytes */
-#define REG_DESC_LEN_U 0x210
-#define REG_DESC_LEN_V 0x214
-
-/*
- * Useful stuff that probably belongs somewhere global.
- */
-#define VGA_WIDTH 640
-#define VGA_HEIGHT 480
-
-#endif /* _MCAM_CORE_H */
diff --git a/drivers/media/video/marvell-ccic/mmp-driver.c b/drivers/media/video/marvell-ccic/mmp-driver.c
deleted file mode 100644
index c4c17fe76c0..00000000000
--- a/drivers/media/video/marvell-ccic/mmp-driver.c
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Support for the camera device found on Marvell MMP processors; known
- * to work with the Armada 610 as used in the OLPC 1.75 system.
- *
- * Copyright 2011 Jonathan Corbet <corbet@lwn.net>
- *
- * This file may be distributed under the terms of the GNU General
- * Public License, version 2.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/i2c-gpio.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/mmp-camera.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/list.h>
-#include <linux/pm.h>
-
-#include "mcam-core.h"
-
-MODULE_ALIAS("platform:mmp-camera");
-MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
-MODULE_LICENSE("GPL");
-
-struct mmp_camera {
- void *power_regs;
- struct platform_device *pdev;
- struct mcam_camera mcam;
- struct list_head devlist;
- int irq;
-};
-
-static inline struct mmp_camera *mcam_to_cam(struct mcam_camera *mcam)
-{
- return container_of(mcam, struct mmp_camera, mcam);
-}
-
-/*
- * A silly little infrastructure so we can keep track of our devices.
- * Chances are that we will never have more than one of them, but
- * the Armada 610 *does* have two controllers...
- */
-
-static LIST_HEAD(mmpcam_devices);
-static struct mutex mmpcam_devices_lock;
-
-static void mmpcam_add_device(struct mmp_camera *cam)
-{
- mutex_lock(&mmpcam_devices_lock);
- list_add(&cam->devlist, &mmpcam_devices);
- mutex_unlock(&mmpcam_devices_lock);
-}
-
-static void mmpcam_remove_device(struct mmp_camera *cam)
-{
- mutex_lock(&mmpcam_devices_lock);
- list_del(&cam->devlist);
- mutex_unlock(&mmpcam_devices_lock);
-}
-
-/*
- * Platform dev remove passes us a platform_device, and there's
- * no handy unused drvdata to stash a backpointer in. So just
- * dig it out of our list.
- */
-static struct mmp_camera *mmpcam_find_device(struct platform_device *pdev)
-{
- struct mmp_camera *cam;
-
- mutex_lock(&mmpcam_devices_lock);
- list_for_each_entry(cam, &mmpcam_devices, devlist) {
- if (cam->pdev == pdev) {
- mutex_unlock(&mmpcam_devices_lock);
- return cam;
- }
- }
- mutex_unlock(&mmpcam_devices_lock);
- return NULL;
-}
-
-
-
-
-/*
- * Power-related registers; this almost certainly belongs
- * somewhere else.
- *
- * ARMADA 610 register manual, sec 7.2.1, p1842.
- */
-#define CPU_SUBSYS_PMU_BASE 0xd4282800
-#define REG_CCIC_DCGCR 0x28 /* CCIC dyn clock gate ctrl reg */
-#define REG_CCIC_CRCR 0x50 /* CCIC clk reset ctrl reg */
-
-/*
- * Power control.
- */
-static void mmpcam_power_up_ctlr(struct mmp_camera *cam)
-{
- iowrite32(0x3f, cam->power_regs + REG_CCIC_DCGCR);
- iowrite32(0x3805b, cam->power_regs + REG_CCIC_CRCR);
- mdelay(1);
-}
-
-static void mmpcam_power_up(struct mcam_camera *mcam)
-{
- struct mmp_camera *cam = mcam_to_cam(mcam);
- struct mmp_camera_platform_data *pdata;
-/*
- * Turn on power and clocks to the controller.
- */
- mmpcam_power_up_ctlr(cam);
-/*
- * Provide power to the sensor.
- */
- mcam_reg_write(mcam, REG_CLKCTRL, 0x60000002);
- pdata = cam->pdev->dev.platform_data;
- gpio_set_value(pdata->sensor_power_gpio, 1);
- mdelay(5);
- mcam_reg_clear_bit(mcam, REG_CTRL1, 0x10000000);
- gpio_set_value(pdata->sensor_reset_gpio, 0); /* reset is active low */
- mdelay(5);
- gpio_set_value(pdata->sensor_reset_gpio, 1); /* reset is active low */
- mdelay(5);
-}
-
-static void mmpcam_power_down(struct mcam_camera *mcam)
-{
- struct mmp_camera *cam = mcam_to_cam(mcam);
- struct mmp_camera_platform_data *pdata;
-/*
- * Turn off clocks and set reset lines
- */
- iowrite32(0, cam->power_regs + REG_CCIC_DCGCR);
- iowrite32(0, cam->power_regs + REG_CCIC_CRCR);
-/*
- * Shut down the sensor.
- */
- pdata = cam->pdev->dev.platform_data;
- gpio_set_value(pdata->sensor_power_gpio, 0);
- gpio_set_value(pdata->sensor_reset_gpio, 0);
-}
-
-
-static irqreturn_t mmpcam_irq(int irq, void *data)
-{
- struct mcam_camera *mcam = data;
- unsigned int irqs, handled;
-
- spin_lock(&mcam->dev_lock);
- irqs = mcam_reg_read(mcam, REG_IRQSTAT);
- handled = mccic_irq(mcam, irqs);
- spin_unlock(&mcam->dev_lock);
- return IRQ_RETVAL(handled);
-}
-
-
-static int mmpcam_probe(struct platform_device *pdev)
-{
- struct mmp_camera *cam;
- struct mcam_camera *mcam;
- struct resource *res;
- struct mmp_camera_platform_data *pdata;
- int ret;
-
- cam = kzalloc(sizeof(*cam), GFP_KERNEL);
- if (cam == NULL)
- return -ENOMEM;
- cam->pdev = pdev;
- INIT_LIST_HEAD(&cam->devlist);
-
- mcam = &cam->mcam;
- mcam->plat_power_up = mmpcam_power_up;
- mcam->plat_power_down = mmpcam_power_down;
- mcam->dev = &pdev->dev;
- mcam->use_smbus = 0;
- mcam->chip_id = V4L2_IDENT_ARMADA610;
- mcam->buffer_mode = B_DMA_sg;
- spin_lock_init(&mcam->dev_lock);
- /*
- * Get our I/O memory.
- */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "no iomem resource!\n");
- ret = -ENODEV;
- goto out_free;
- }
- mcam->regs = ioremap(res->start, resource_size(res));
- if (mcam->regs == NULL) {
- dev_err(&pdev->dev, "MMIO ioremap fail\n");
- ret = -ENODEV;
- goto out_free;
- }
- /*
- * Power/clock memory is elsewhere; get it too. Perhaps this
- * should really be managed outside of this driver?
- */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (res == NULL) {
- dev_err(&pdev->dev, "no power resource!\n");
- ret = -ENODEV;
- goto out_unmap1;
- }
- cam->power_regs = ioremap(res->start, resource_size(res));
- if (cam->power_regs == NULL) {
- dev_err(&pdev->dev, "power MMIO ioremap fail\n");
- ret = -ENODEV;
- goto out_unmap1;
- }
- /*
- * Find the i2c adapter. This assumes, of course, that the
- * i2c bus is already up and functioning.
- */
- pdata = pdev->dev.platform_data;
- mcam->i2c_adapter = platform_get_drvdata(pdata->i2c_device);
- if (mcam->i2c_adapter == NULL) {
- ret = -ENODEV;
- dev_err(&pdev->dev, "No i2c adapter\n");
- goto out_unmap2;
- }
- /*
- * Sensor GPIO pins.
- */
- ret = gpio_request(pdata->sensor_power_gpio, "cam-power");
- if (ret) {
- dev_err(&pdev->dev, "Can't get sensor power gpio %d",
- pdata->sensor_power_gpio);
- goto out_unmap2;
- }
- gpio_direction_output(pdata->sensor_power_gpio, 0);
- ret = gpio_request(pdata->sensor_reset_gpio, "cam-reset");
- if (ret) {
- dev_err(&pdev->dev, "Can't get sensor reset gpio %d",
- pdata->sensor_reset_gpio);
- goto out_gpio;
- }
- gpio_direction_output(pdata->sensor_reset_gpio, 0);
- /*
- * Power the device up and hand it off to the core.
- */
- mmpcam_power_up(mcam);
- ret = mccic_register(mcam);
- if (ret)
- goto out_gpio2;
- /*
- * Finally, set up our IRQ now that the core is ready to
- * deal with it.
- */
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res == NULL) {
- ret = -ENODEV;
- goto out_unregister;
- }
- cam->irq = res->start;
- ret = request_irq(cam->irq, mmpcam_irq, IRQF_SHARED,
- "mmp-camera", mcam);
- if (ret == 0) {
- mmpcam_add_device(cam);
- return 0;
- }
-
-out_unregister:
- mccic_shutdown(mcam);
-out_gpio2:
- mmpcam_power_down(mcam);
- gpio_free(pdata->sensor_reset_gpio);
-out_gpio:
- gpio_free(pdata->sensor_power_gpio);
-out_unmap2:
- iounmap(cam->power_regs);
-out_unmap1:
- iounmap(mcam->regs);
-out_free:
- kfree(cam);
- return ret;
-}
-
-
-static int mmpcam_remove(struct mmp_camera *cam)
-{
- struct mcam_camera *mcam = &cam->mcam;
- struct mmp_camera_platform_data *pdata;
-
- mmpcam_remove_device(cam);
- free_irq(cam->irq, mcam);
- mccic_shutdown(mcam);
- mmpcam_power_down(mcam);
- pdata = cam->pdev->dev.platform_data;
- gpio_free(pdata->sensor_reset_gpio);
- gpio_free(pdata->sensor_power_gpio);
- iounmap(cam->power_regs);
- iounmap(mcam->regs);
- kfree(cam);
- return 0;
-}
-
-static int mmpcam_platform_remove(struct platform_device *pdev)
-{
- struct mmp_camera *cam = mmpcam_find_device(pdev);
-
- if (cam == NULL)
- return -ENODEV;
- return mmpcam_remove(cam);
-}
-
-/*
- * Suspend/resume support.
- */
-#ifdef CONFIG_PM
-
-static int mmpcam_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct mmp_camera *cam = mmpcam_find_device(pdev);
-
- if (state.event != PM_EVENT_SUSPEND)
- return 0;
- mccic_suspend(&cam->mcam);
- return 0;
-}
-
-static int mmpcam_resume(struct platform_device *pdev)
-{
- struct mmp_camera *cam = mmpcam_find_device(pdev);
-
- /*
- * Power up unconditionally just in case the core tries to
- * touch a register even if nothing was active before; trust
- * me, it's better this way.
- */
- mmpcam_power_up_ctlr(cam);
- return mccic_resume(&cam->mcam);
-}
-
-#endif
-
-
-static struct platform_driver mmpcam_driver = {
- .probe = mmpcam_probe,
- .remove = mmpcam_platform_remove,
-#ifdef CONFIG_PM
- .suspend = mmpcam_suspend,
- .resume = mmpcam_resume,
-#endif
- .driver = {
- .name = "mmp-camera",
- .owner = THIS_MODULE
- }
-};
-
-
-static int __init mmpcam_init_module(void)
-{
- mutex_init(&mmpcam_devices_lock);
- return platform_driver_register(&mmpcam_driver);
-}
-
-static void __exit mmpcam_exit_module(void)
-{
- platform_driver_unregister(&mmpcam_driver);
- /*
- * platform_driver_unregister() should have emptied the list
- */
- if (!list_empty(&mmpcam_devices))
- printk(KERN_ERR "mmp_camera leaving devices behind\n");
-}
-
-module_init(mmpcam_init_module);
-module_exit(mmpcam_exit_module);
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c
deleted file mode 100644
index 0b91a5cd38e..00000000000
--- a/drivers/media/video/mem2mem_testdev.c
+++ /dev/null
@@ -1,1120 +0,0 @@
-/*
- * A virtual v4l2-mem2mem example device.
- *
- * This is a virtual device driver for testing mem-to-mem videobuf framework.
- * It simulates a device that uses memory buffers for both source and
- * destination, processes the data and issues an "irq" (simulated by a timer).
- * The device is capable of multi-instance, multi-buffer-per-transaction
- * operation (via the mem2mem framework).
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- * Pawel Osciak, <pawel@osciak.com>
- * Marek Szyprowski, <m.szyprowski@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version
- */
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/timer.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-
-#include <linux/platform_device.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
-#include <media/videobuf2-vmalloc.h>
-
-#define MEM2MEM_TEST_MODULE_NAME "mem2mem-testdev"
-
-MODULE_DESCRIPTION("Virtual device for mem2mem framework testing");
-MODULE_AUTHOR("Pawel Osciak, <pawel@osciak.com>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.1.1");
-
-#define MIN_W 32
-#define MIN_H 32
-#define MAX_W 640
-#define MAX_H 480
-#define DIM_ALIGN_MASK 7 /* 8-byte alignment for line length */
-
-/* Flags that indicate a format can be used for capture/output */
-#define MEM2MEM_CAPTURE (1 << 0)
-#define MEM2MEM_OUTPUT (1 << 1)
-
-#define MEM2MEM_NAME "m2m-testdev"
-
-/* Per queue */
-#define MEM2MEM_DEF_NUM_BUFS VIDEO_MAX_FRAME
-/* In bytes, per queue */
-#define MEM2MEM_VID_MEM_LIMIT (16 * 1024 * 1024)
-
-/* Default transaction time in msec */
-#define MEM2MEM_DEF_TRANSTIME 1000
-/* Default number of buffers per transaction */
-#define MEM2MEM_DEF_TRANSLEN 1
-#define MEM2MEM_COLOR_STEP (0xff >> 4)
-#define MEM2MEM_NUM_TILES 8
-
-/* Flags that indicate processing mode */
-#define MEM2MEM_HFLIP (1 << 0)
-#define MEM2MEM_VFLIP (1 << 1)
-
-#define dprintk(dev, fmt, arg...) \
- v4l2_dbg(1, 1, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
-
-
-void m2mtest_dev_release(struct device *dev)
-{}
-
-static struct platform_device m2mtest_pdev = {
- .name = MEM2MEM_NAME,
- .dev.release = m2mtest_dev_release,
-};
-
-struct m2mtest_fmt {
- char *name;
- u32 fourcc;
- int depth;
- /* Types the format can be used for */
- u32 types;
-};
-
-static struct m2mtest_fmt formats[] = {
- {
- .name = "RGB565 (BE)",
- .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
- .depth = 16,
- /* Both capture and output format */
- .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
- },
- {
- .name = "4:2:2, packed, YUYV",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = 16,
- /* Output-only format */
- .types = MEM2MEM_OUTPUT,
- },
-};
-
-#define NUM_FORMATS ARRAY_SIZE(formats)
-
-/* Per-queue, driver-specific private data */
-struct m2mtest_q_data {
- unsigned int width;
- unsigned int height;
- unsigned int sizeimage;
- struct m2mtest_fmt *fmt;
-};
-
-enum {
- V4L2_M2M_SRC = 0,
- V4L2_M2M_DST = 1,
-};
-
-#define V4L2_CID_TRANS_TIME_MSEC (V4L2_CID_USER_BASE + 0x1000)
-#define V4L2_CID_TRANS_NUM_BUFS (V4L2_CID_USER_BASE + 0x1001)
-
-static struct m2mtest_fmt *find_format(struct v4l2_format *f)
-{
- struct m2mtest_fmt *fmt;
- unsigned int k;
-
- for (k = 0; k < NUM_FORMATS; k++) {
- fmt = &formats[k];
- if (fmt->fourcc == f->fmt.pix.pixelformat)
- break;
- }
-
- if (k == NUM_FORMATS)
- return NULL;
-
- return &formats[k];
-}
-
-struct m2mtest_dev {
- struct v4l2_device v4l2_dev;
- struct video_device *vfd;
-
- atomic_t num_inst;
- struct mutex dev_mutex;
- spinlock_t irqlock;
-
- struct timer_list timer;
-
- struct v4l2_m2m_dev *m2m_dev;
-};
-
-struct m2mtest_ctx {
- struct v4l2_fh fh;
- struct m2mtest_dev *dev;
-
- struct v4l2_ctrl_handler hdl;
-
- /* Processed buffers in this transaction */
- u8 num_processed;
-
- /* Transaction length (i.e. how many buffers per transaction) */
- u32 translen;
- /* Transaction time (i.e. simulated processing time) in milliseconds */
- u32 transtime;
-
- /* Abort requested by m2m */
- int aborting;
-
- /* Processing mode */
- int mode;
-
- enum v4l2_colorspace colorspace;
-
- struct v4l2_m2m_ctx *m2m_ctx;
-
- /* Source and destination queue data */
- struct m2mtest_q_data q_data[2];
-};
-
-static inline struct m2mtest_ctx *file2ctx(struct file *file)
-{
- return container_of(file->private_data, struct m2mtest_ctx, fh);
-}
-
-static struct m2mtest_q_data *get_q_data(struct m2mtest_ctx *ctx,
- enum v4l2_buf_type type)
-{
- switch (type) {
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- return &ctx->q_data[V4L2_M2M_SRC];
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- return &ctx->q_data[V4L2_M2M_DST];
- default:
- BUG();
- }
- return NULL;
-}
-
-
-static int device_process(struct m2mtest_ctx *ctx,
- struct vb2_buffer *in_vb,
- struct vb2_buffer *out_vb)
-{
- struct m2mtest_dev *dev = ctx->dev;
- struct m2mtest_q_data *q_data;
- u8 *p_in, *p_out;
- int x, y, t, w;
- int tile_w, bytes_left;
- int width, height, bytesperline;
-
- q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
-
- width = q_data->width;
- height = q_data->height;
- bytesperline = (q_data->width * q_data->fmt->depth) >> 3;
-
- p_in = vb2_plane_vaddr(in_vb, 0);
- p_out = vb2_plane_vaddr(out_vb, 0);
- if (!p_in || !p_out) {
- v4l2_err(&dev->v4l2_dev,
- "Acquiring kernel pointers to buffers failed\n");
- return -EFAULT;
- }
-
- if (vb2_plane_size(in_vb, 0) > vb2_plane_size(out_vb, 0)) {
- v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n");
- return -EINVAL;
- }
-
- tile_w = (width * (q_data[V4L2_M2M_DST].fmt->depth >> 3))
- / MEM2MEM_NUM_TILES;
- bytes_left = bytesperline - tile_w * MEM2MEM_NUM_TILES;
- w = 0;
-
- switch (ctx->mode) {
- case MEM2MEM_HFLIP | MEM2MEM_VFLIP:
- p_out += bytesperline * height - bytes_left;
- for (y = 0; y < height; ++y) {
- for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
- if (w & 0x1) {
- for (x = 0; x < tile_w; ++x)
- *--p_out = *p_in++ +
- MEM2MEM_COLOR_STEP;
- } else {
- for (x = 0; x < tile_w; ++x)
- *--p_out = *p_in++ -
- MEM2MEM_COLOR_STEP;
- }
- ++w;
- }
- p_in += bytes_left;
- p_out -= bytes_left;
- }
- break;
-
- case MEM2MEM_HFLIP:
- for (y = 0; y < height; ++y) {
- p_out += MEM2MEM_NUM_TILES * tile_w;
- for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
- if (w & 0x01) {
- for (x = 0; x < tile_w; ++x)
- *--p_out = *p_in++ +
- MEM2MEM_COLOR_STEP;
- } else {
- for (x = 0; x < tile_w; ++x)
- *--p_out = *p_in++ -
- MEM2MEM_COLOR_STEP;
- }
- ++w;
- }
- p_in += bytes_left;
- p_out += bytesperline;
- }
- break;
-
- case MEM2MEM_VFLIP:
- p_out += bytesperline * (height - 1);
- for (y = 0; y < height; ++y) {
- for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
- if (w & 0x1) {
- for (x = 0; x < tile_w; ++x)
- *p_out++ = *p_in++ +
- MEM2MEM_COLOR_STEP;
- } else {
- for (x = 0; x < tile_w; ++x)
- *p_out++ = *p_in++ -
- MEM2MEM_COLOR_STEP;
- }
- ++w;
- }
- p_in += bytes_left;
- p_out += bytes_left - 2 * bytesperline;
- }
- break;
-
- default:
- for (y = 0; y < height; ++y) {
- for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
- if (w & 0x1) {
- for (x = 0; x < tile_w; ++x)
- *p_out++ = *p_in++ +
- MEM2MEM_COLOR_STEP;
- } else {
- for (x = 0; x < tile_w; ++x)
- *p_out++ = *p_in++ -
- MEM2MEM_COLOR_STEP;
- }
- ++w;
- }
- p_in += bytes_left;
- p_out += bytes_left;
- }
- }
-
- return 0;
-}
-
-static void schedule_irq(struct m2mtest_dev *dev, int msec_timeout)
-{
- dprintk(dev, "Scheduling a simulated irq\n");
- mod_timer(&dev->timer, jiffies + msecs_to_jiffies(msec_timeout));
-}
-
-/*
- * mem2mem callbacks
- */
-
-/**
- * job_ready() - check whether an instance is ready to be scheduled to run
- */
-static int job_ready(void *priv)
-{
- struct m2mtest_ctx *ctx = priv;
-
- if (v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) < ctx->translen
- || v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < ctx->translen) {
- dprintk(ctx->dev, "Not enough buffers available\n");
- return 0;
- }
-
- return 1;
-}
-
-static void job_abort(void *priv)
-{
- struct m2mtest_ctx *ctx = priv;
-
- /* Will cancel the transaction in the next interrupt handler */
- ctx->aborting = 1;
-}
-
-static void m2mtest_lock(void *priv)
-{
- struct m2mtest_ctx *ctx = priv;
- struct m2mtest_dev *dev = ctx->dev;
- mutex_lock(&dev->dev_mutex);
-}
-
-static void m2mtest_unlock(void *priv)
-{
- struct m2mtest_ctx *ctx = priv;
- struct m2mtest_dev *dev = ctx->dev;
- mutex_unlock(&dev->dev_mutex);
-}
-
-
-/* device_run() - prepares and starts the device
- *
- * This simulates all the immediate preparations required before starting
- * a device. This will be called by the framework when it decides to schedule
- * a particular instance.
- */
-static void device_run(void *priv)
-{
- struct m2mtest_ctx *ctx = priv;
- struct m2mtest_dev *dev = ctx->dev;
- struct vb2_buffer *src_buf, *dst_buf;
-
- src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
- dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
-
- device_process(ctx, src_buf, dst_buf);
-
- /* Run a timer, which simulates a hardware irq */
- schedule_irq(dev, ctx->transtime);
-}
-
-static void device_isr(unsigned long priv)
-{
- struct m2mtest_dev *m2mtest_dev = (struct m2mtest_dev *)priv;
- struct m2mtest_ctx *curr_ctx;
- struct vb2_buffer *src_vb, *dst_vb;
- unsigned long flags;
-
- curr_ctx = v4l2_m2m_get_curr_priv(m2mtest_dev->m2m_dev);
-
- if (NULL == curr_ctx) {
- printk(KERN_ERR
- "Instance released before the end of transaction\n");
- return;
- }
-
- src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
- dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
-
- curr_ctx->num_processed++;
-
- spin_lock_irqsave(&m2mtest_dev->irqlock, flags);
- v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
- v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
- spin_unlock_irqrestore(&m2mtest_dev->irqlock, flags);
-
- if (curr_ctx->num_processed == curr_ctx->translen
- || curr_ctx->aborting) {
- dprintk(curr_ctx->dev, "Finishing transaction\n");
- curr_ctx->num_processed = 0;
- v4l2_m2m_job_finish(m2mtest_dev->m2m_dev, curr_ctx->m2m_ctx);
- } else {
- device_run(curr_ctx);
- }
-}
-
-/*
- * video ioctls
- */
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1);
- strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1);
- strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info));
- cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
- cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
- return 0;
-}
-
-static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
-{
- int i, num;
- struct m2mtest_fmt *fmt;
-
- num = 0;
-
- for (i = 0; i < NUM_FORMATS; ++i) {
- if (formats[i].types & type) {
- /* index-th format of type type found ? */
- if (num == f->index)
- break;
- /* Correct type but haven't reached our index yet,
- * just increment per-type index */
- ++num;
- }
- }
-
- if (i < NUM_FORMATS) {
- /* Format found */
- fmt = &formats[i];
- strncpy(f->description, fmt->name, sizeof(f->description) - 1);
- f->pixelformat = fmt->fourcc;
- return 0;
- }
-
- /* Format not found */
- return -EINVAL;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- return enum_fmt(f, MEM2MEM_CAPTURE);
-}
-
-static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- return enum_fmt(f, MEM2MEM_OUTPUT);
-}
-
-static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
-{
- struct vb2_queue *vq;
- struct m2mtest_q_data *q_data;
-
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
- if (!vq)
- return -EINVAL;
-
- q_data = get_q_data(ctx, f->type);
-
- f->fmt.pix.width = q_data->width;
- f->fmt.pix.height = q_data->height;
- f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.pixelformat = q_data->fmt->fourcc;
- f->fmt.pix.bytesperline = (q_data->width * q_data->fmt->depth) >> 3;
- f->fmt.pix.sizeimage = q_data->sizeimage;
- f->fmt.pix.colorspace = ctx->colorspace;
-
- return 0;
-}
-
-static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- return vidioc_g_fmt(file2ctx(file), f);
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- return vidioc_g_fmt(file2ctx(file), f);
-}
-
-static int vidioc_try_fmt(struct v4l2_format *f, struct m2mtest_fmt *fmt)
-{
- enum v4l2_field field;
-
- field = f->fmt.pix.field;
-
- if (field == V4L2_FIELD_ANY)
- field = V4L2_FIELD_NONE;
- else if (V4L2_FIELD_NONE != field)
- return -EINVAL;
-
- /* V4L2 specification suggests the driver corrects the format struct
- * if any of the dimensions is unsupported */
- f->fmt.pix.field = field;
-
- if (f->fmt.pix.height < MIN_H)
- f->fmt.pix.height = MIN_H;
- else if (f->fmt.pix.height > MAX_H)
- f->fmt.pix.height = MAX_H;
-
- if (f->fmt.pix.width < MIN_W)
- f->fmt.pix.width = MIN_W;
- else if (f->fmt.pix.width > MAX_W)
- f->fmt.pix.width = MAX_W;
-
- f->fmt.pix.width &= ~DIM_ALIGN_MASK;
- f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
- f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
-
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct m2mtest_fmt *fmt;
- struct m2mtest_ctx *ctx = file2ctx(file);
-
- fmt = find_format(f);
- if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
- v4l2_err(&ctx->dev->v4l2_dev,
- "Fourcc format (0x%08x) invalid.\n",
- f->fmt.pix.pixelformat);
- return -EINVAL;
- }
- f->fmt.pix.colorspace = ctx->colorspace;
-
- return vidioc_try_fmt(f, fmt);
-}
-
-static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct m2mtest_fmt *fmt;
- struct m2mtest_ctx *ctx = file2ctx(file);
-
- fmt = find_format(f);
- if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
- v4l2_err(&ctx->dev->v4l2_dev,
- "Fourcc format (0x%08x) invalid.\n",
- f->fmt.pix.pixelformat);
- return -EINVAL;
- }
- if (!f->fmt.pix.colorspace)
- f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
-
- return vidioc_try_fmt(f, fmt);
-}
-
-static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
-{
- struct m2mtest_q_data *q_data;
- struct vb2_queue *vq;
-
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
- if (!vq)
- return -EINVAL;
-
- q_data = get_q_data(ctx, f->type);
- if (!q_data)
- return -EINVAL;
-
- if (vb2_is_busy(vq)) {
- v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
- return -EBUSY;
- }
-
- q_data->fmt = find_format(f);
- q_data->width = f->fmt.pix.width;
- q_data->height = f->fmt.pix.height;
- q_data->sizeimage = q_data->width * q_data->height
- * q_data->fmt->depth >> 3;
-
- dprintk(ctx->dev,
- "Setting format for type %d, wxh: %dx%d, fmt: %d\n",
- f->type, q_data->width, q_data->height, q_data->fmt->fourcc);
-
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- int ret;
-
- ret = vidioc_try_fmt_vid_cap(file, priv, f);
- if (ret)
- return ret;
-
- return vidioc_s_fmt(file2ctx(file), f);
-}
-
-static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct m2mtest_ctx *ctx = file2ctx(file);
- int ret;
-
- ret = vidioc_try_fmt_vid_out(file, priv, f);
- if (ret)
- return ret;
-
- ret = vidioc_s_fmt(file2ctx(file), f);
- if (!ret)
- ctx->colorspace = f->fmt.pix.colorspace;
- return ret;
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct m2mtest_ctx *ctx = file2ctx(file);
-
- return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct m2mtest_ctx *ctx = file2ctx(file);
-
- return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct m2mtest_ctx *ctx = file2ctx(file);
-
- return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct m2mtest_ctx *ctx = file2ctx(file);
-
- return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct m2mtest_ctx *ctx = file2ctx(file);
-
- return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
-}
-
-static int vidioc_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct m2mtest_ctx *ctx = file2ctx(file);
-
- return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
-}
-
-static int m2mtest_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct m2mtest_ctx *ctx =
- container_of(ctrl->handler, struct m2mtest_ctx, hdl);
-
- switch (ctrl->id) {
- case V4L2_CID_HFLIP:
- if (ctrl->val)
- ctx->mode |= MEM2MEM_HFLIP;
- else
- ctx->mode &= ~MEM2MEM_HFLIP;
- break;
-
- case V4L2_CID_VFLIP:
- if (ctrl->val)
- ctx->mode |= MEM2MEM_VFLIP;
- else
- ctx->mode &= ~MEM2MEM_VFLIP;
- break;
-
- case V4L2_CID_TRANS_TIME_MSEC:
- ctx->transtime = ctrl->val;
- break;
-
- case V4L2_CID_TRANS_NUM_BUFS:
- ctx->translen = ctrl->val;
- break;
-
- default:
- v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const struct v4l2_ctrl_ops m2mtest_ctrl_ops = {
- .s_ctrl = m2mtest_s_ctrl,
-};
-
-
-static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
-
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
-
- .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
- .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out,
- .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
- .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
-
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
-
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-
-/*
- * Queue operations
- */
-
-static int m2mtest_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
- unsigned int *nbuffers, unsigned int *nplanes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- struct m2mtest_ctx *ctx = vb2_get_drv_priv(vq);
- struct m2mtest_q_data *q_data;
- unsigned int size, count = *nbuffers;
-
- q_data = get_q_data(ctx, vq->type);
-
- size = q_data->width * q_data->height * q_data->fmt->depth >> 3;
-
- while (size * count > MEM2MEM_VID_MEM_LIMIT)
- (count)--;
-
- *nplanes = 1;
- *nbuffers = count;
- sizes[0] = size;
-
- /*
- * videobuf2-vmalloc allocator is context-less so no need to set
- * alloc_ctxs array.
- */
-
- dprintk(ctx->dev, "get %d buffer(s) of size %d each.\n", count, size);
-
- return 0;
-}
-
-static int m2mtest_buf_prepare(struct vb2_buffer *vb)
-{
- struct m2mtest_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct m2mtest_q_data *q_data;
-
- dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type);
-
- q_data = get_q_data(ctx, vb->vb2_queue->type);
-
- if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
- dprintk(ctx->dev, "%s data will not fit into plane (%lu < %lu)\n",
- __func__, vb2_plane_size(vb, 0), (long)q_data->sizeimage);
- return -EINVAL;
- }
-
- vb2_set_plane_payload(vb, 0, q_data->sizeimage);
-
- return 0;
-}
-
-static void m2mtest_buf_queue(struct vb2_buffer *vb)
-{
- struct m2mtest_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
-}
-
-static void m2mtest_wait_prepare(struct vb2_queue *q)
-{
- struct m2mtest_ctx *ctx = vb2_get_drv_priv(q);
- m2mtest_unlock(ctx);
-}
-
-static void m2mtest_wait_finish(struct vb2_queue *q)
-{
- struct m2mtest_ctx *ctx = vb2_get_drv_priv(q);
- m2mtest_lock(ctx);
-}
-
-static struct vb2_ops m2mtest_qops = {
- .queue_setup = m2mtest_queue_setup,
- .buf_prepare = m2mtest_buf_prepare,
- .buf_queue = m2mtest_buf_queue,
- .wait_prepare = m2mtest_wait_prepare,
- .wait_finish = m2mtest_wait_finish,
-};
-
-static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
-{
- struct m2mtest_ctx *ctx = priv;
- int ret;
-
- memset(src_vq, 0, sizeof(*src_vq));
- src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- src_vq->io_modes = VB2_MMAP;
- src_vq->drv_priv = ctx;
- src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
- src_vq->ops = &m2mtest_qops;
- src_vq->mem_ops = &vb2_vmalloc_memops;
-
- ret = vb2_queue_init(src_vq);
- if (ret)
- return ret;
-
- memset(dst_vq, 0, sizeof(*dst_vq));
- dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- dst_vq->io_modes = VB2_MMAP;
- dst_vq->drv_priv = ctx;
- dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
- dst_vq->ops = &m2mtest_qops;
- dst_vq->mem_ops = &vb2_vmalloc_memops;
-
- return vb2_queue_init(dst_vq);
-}
-
-static const struct v4l2_ctrl_config m2mtest_ctrl_trans_time_msec = {
- .ops = &m2mtest_ctrl_ops,
- .id = V4L2_CID_TRANS_TIME_MSEC,
- .name = "Transaction Time (msec)",
- .type = V4L2_CTRL_TYPE_INTEGER,
- .def = 1001,
- .min = 1,
- .max = 10001,
- .step = 100,
-};
-
-static const struct v4l2_ctrl_config m2mtest_ctrl_trans_num_bufs = {
- .ops = &m2mtest_ctrl_ops,
- .id = V4L2_CID_TRANS_NUM_BUFS,
- .name = "Buffers Per Transaction",
- .type = V4L2_CTRL_TYPE_INTEGER,
- .def = 1,
- .min = 1,
- .max = MEM2MEM_DEF_NUM_BUFS,
- .step = 1,
-};
-
-/*
- * File operations
- */
-static int m2mtest_open(struct file *file)
-{
- struct m2mtest_dev *dev = video_drvdata(file);
- struct m2mtest_ctx *ctx = NULL;
- struct v4l2_ctrl_handler *hdl;
-
- ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- ctx->dev = dev;
- hdl = &ctx->hdl;
- v4l2_ctrl_handler_init(hdl, 4);
- v4l2_ctrl_new_std(hdl, &m2mtest_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(hdl, &m2mtest_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_custom(hdl, &m2mtest_ctrl_trans_time_msec, NULL);
- v4l2_ctrl_new_custom(hdl, &m2mtest_ctrl_trans_num_bufs, NULL);
- if (hdl->error) {
- int err = hdl->error;
-
- v4l2_ctrl_handler_free(hdl);
- return err;
- }
- ctx->fh.ctrl_handler = hdl;
- v4l2_ctrl_handler_setup(hdl);
-
- ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0];
- ctx->q_data[V4L2_M2M_SRC].width = 640;
- ctx->q_data[V4L2_M2M_SRC].height = 480;
- ctx->q_data[V4L2_M2M_SRC].sizeimage =
- ctx->q_data[V4L2_M2M_SRC].width *
- ctx->q_data[V4L2_M2M_SRC].height *
- (ctx->q_data[V4L2_M2M_SRC].fmt->depth >> 3);
- ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
- ctx->colorspace = V4L2_COLORSPACE_REC709;
-
- ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
-
- if (IS_ERR(ctx->m2m_ctx)) {
- int ret = PTR_ERR(ctx->m2m_ctx);
-
- v4l2_ctrl_handler_free(hdl);
- kfree(ctx);
- return ret;
- }
-
- v4l2_fh_add(&ctx->fh);
- atomic_inc(&dev->num_inst);
-
- dprintk(dev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
-
- return 0;
-}
-
-static int m2mtest_release(struct file *file)
-{
- struct m2mtest_dev *dev = video_drvdata(file);
- struct m2mtest_ctx *ctx = file2ctx(file);
-
- dprintk(dev, "Releasing instance %p\n", ctx);
-
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
- v4l2_ctrl_handler_free(&ctx->hdl);
- v4l2_m2m_ctx_release(ctx->m2m_ctx);
- kfree(ctx);
-
- atomic_dec(&dev->num_inst);
-
- return 0;
-}
-
-static unsigned int m2mtest_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct m2mtest_ctx *ctx = file2ctx(file);
-
- return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
-}
-
-static int m2mtest_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct m2mtest_ctx *ctx = file2ctx(file);
-
- return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
-}
-
-static const struct v4l2_file_operations m2mtest_fops = {
- .owner = THIS_MODULE,
- .open = m2mtest_open,
- .release = m2mtest_release,
- .poll = m2mtest_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = m2mtest_mmap,
-};
-
-static struct video_device m2mtest_videodev = {
- .name = MEM2MEM_NAME,
- .fops = &m2mtest_fops,
- .ioctl_ops = &m2mtest_ioctl_ops,
- .minor = -1,
- .release = video_device_release,
-};
-
-static struct v4l2_m2m_ops m2m_ops = {
- .device_run = device_run,
- .job_ready = job_ready,
- .job_abort = job_abort,
- .lock = m2mtest_lock,
- .unlock = m2mtest_unlock,
-};
-
-static int m2mtest_probe(struct platform_device *pdev)
-{
- struct m2mtest_dev *dev;
- struct video_device *vfd;
- int ret;
-
- dev = kzalloc(sizeof *dev, GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
-
- spin_lock_init(&dev->irqlock);
-
- ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
- if (ret)
- goto free_dev;
-
- atomic_set(&dev->num_inst, 0);
- mutex_init(&dev->dev_mutex);
-
- vfd = video_device_alloc();
- if (!vfd) {
- v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
- ret = -ENOMEM;
- goto unreg_dev;
- }
-
- *vfd = m2mtest_videodev;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
- vfd->lock = &dev->dev_mutex;
-
- ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
- if (ret) {
- v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
- goto rel_vdev;
- }
-
- video_set_drvdata(vfd, dev);
- snprintf(vfd->name, sizeof(vfd->name), "%s", m2mtest_videodev.name);
- dev->vfd = vfd;
- v4l2_info(&dev->v4l2_dev, MEM2MEM_TEST_MODULE_NAME
- "Device registered as /dev/video%d\n", vfd->num);
-
- setup_timer(&dev->timer, device_isr, (long)dev);
- platform_set_drvdata(pdev, dev);
-
- dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
- if (IS_ERR(dev->m2m_dev)) {
- v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
- ret = PTR_ERR(dev->m2m_dev);
- goto err_m2m;
- }
-
- return 0;
-
- v4l2_m2m_release(dev->m2m_dev);
-err_m2m:
- video_unregister_device(dev->vfd);
-rel_vdev:
- video_device_release(vfd);
-unreg_dev:
- v4l2_device_unregister(&dev->v4l2_dev);
-free_dev:
- kfree(dev);
-
- return ret;
-}
-
-static int m2mtest_remove(struct platform_device *pdev)
-{
- struct m2mtest_dev *dev =
- (struct m2mtest_dev *)platform_get_drvdata(pdev);
-
- v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME);
- v4l2_m2m_release(dev->m2m_dev);
- del_timer_sync(&dev->timer);
- video_unregister_device(dev->vfd);
- v4l2_device_unregister(&dev->v4l2_dev);
- kfree(dev);
-
- return 0;
-}
-
-static struct platform_driver m2mtest_pdrv = {
- .probe = m2mtest_probe,
- .remove = m2mtest_remove,
- .driver = {
- .name = MEM2MEM_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-static void __exit m2mtest_exit(void)
-{
- platform_driver_unregister(&m2mtest_pdrv);
- platform_device_unregister(&m2mtest_pdev);
-}
-
-static int __init m2mtest_init(void)
-{
- int ret;
-
- ret = platform_device_register(&m2mtest_pdev);
- if (ret)
- return ret;
-
- ret = platform_driver_register(&m2mtest_pdrv);
- if (ret)
- platform_device_unregister(&m2mtest_pdev);
-
- return 0;
-}
-
-module_init(m2mtest_init);
-module_exit(m2mtest_exit);
-
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
deleted file mode 100644
index 7bc775219f9..00000000000
--- a/drivers/media/video/meye.c
+++ /dev/null
@@ -1,1964 +0,0 @@
-/*
- * Motion Eye video4linux driver for Sony Vaio PictureBook
- *
- * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
- *
- * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
- *
- * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
- *
- * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
- *
- * Some parts borrowed from various video4linux drivers, especially
- * bttv-driver.c and zoran.c, see original files for credits.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/gfp.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/vmalloc.h>
-#include <linux/dma-mapping.h>
-
-#include "meye.h"
-#include <linux/meye.h>
-
-MODULE_AUTHOR("Stelian Pop <stelian@popies.net>");
-MODULE_DESCRIPTION("v4l2 driver for the MotionEye camera");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(MEYE_DRIVER_VERSION);
-
-/* number of grab buffers */
-static unsigned int gbuffers = 2;
-module_param(gbuffers, int, 0444);
-MODULE_PARM_DESC(gbuffers, "number of capture buffers, default is 2 (32 max)");
-
-/* size of a grab buffer */
-static unsigned int gbufsize = MEYE_MAX_BUFSIZE;
-module_param(gbufsize, int, 0444);
-MODULE_PARM_DESC(gbufsize, "size of the capture buffers, default is 614400"
- " (will be rounded up to a page multiple)");
-
-/* /dev/videoX registration number */
-static int video_nr = -1;
-module_param(video_nr, int, 0444);
-MODULE_PARM_DESC(video_nr, "video device to register (0=/dev/video0, etc)");
-
-/* driver structure - only one possible */
-static struct meye meye;
-
-/****************************************************************************/
-/* Memory allocation routines (stolen from bttv-driver.c) */
-/****************************************************************************/
-static void *rvmalloc(unsigned long size)
-{
- void *mem;
- unsigned long adr;
-
- size = PAGE_ALIGN(size);
- mem = vmalloc_32(size);
- if (mem) {
- memset(mem, 0, size);
- adr = (unsigned long) mem;
- while (size > 0) {
- SetPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- }
- return mem;
-}
-
-static void rvfree(void * mem, unsigned long size)
-{
- unsigned long adr;
-
- if (mem) {
- adr = (unsigned long) mem;
- while ((long) size > 0) {
- ClearPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- vfree(mem);
- }
-}
-
-/*
- * return a page table pointing to N pages of locked memory
- *
- * NOTE: The meye device expects DMA addresses on 32 bits, we build
- * a table of 1024 entries = 4 bytes * 1024 = 4096 bytes.
- */
-static int ptable_alloc(void)
-{
- u32 *pt;
- int i;
-
- memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
-
- /* give only 32 bit DMA addresses */
- if (dma_set_mask(&meye.mchip_dev->dev, DMA_BIT_MASK(32)))
- return -1;
-
- meye.mchip_ptable_toc = dma_alloc_coherent(&meye.mchip_dev->dev,
- PAGE_SIZE,
- &meye.mchip_dmahandle,
- GFP_KERNEL);
- if (!meye.mchip_ptable_toc) {
- meye.mchip_dmahandle = 0;
- return -1;
- }
-
- pt = meye.mchip_ptable_toc;
- for (i = 0; i < MCHIP_NB_PAGES; i++) {
- dma_addr_t dma;
- meye.mchip_ptable[i] = dma_alloc_coherent(&meye.mchip_dev->dev,
- PAGE_SIZE,
- &dma,
- GFP_KERNEL);
- if (!meye.mchip_ptable[i]) {
- int j;
- pt = meye.mchip_ptable_toc;
- for (j = 0; j < i; ++j) {
- dma = (dma_addr_t) *pt;
- dma_free_coherent(&meye.mchip_dev->dev,
- PAGE_SIZE,
- meye.mchip_ptable[j], dma);
- pt++;
- }
- dma_free_coherent(&meye.mchip_dev->dev,
- PAGE_SIZE,
- meye.mchip_ptable_toc,
- meye.mchip_dmahandle);
- meye.mchip_ptable_toc = NULL;
- meye.mchip_dmahandle = 0;
- return -1;
- }
- *pt = (u32) dma;
- pt++;
- }
- return 0;
-}
-
-static void ptable_free(void)
-{
- u32 *pt;
- int i;
-
- pt = meye.mchip_ptable_toc;
- for (i = 0; i < MCHIP_NB_PAGES; i++) {
- dma_addr_t dma = (dma_addr_t) *pt;
- if (meye.mchip_ptable[i])
- dma_free_coherent(&meye.mchip_dev->dev,
- PAGE_SIZE,
- meye.mchip_ptable[i], dma);
- pt++;
- }
-
- if (meye.mchip_ptable_toc)
- dma_free_coherent(&meye.mchip_dev->dev,
- PAGE_SIZE,
- meye.mchip_ptable_toc,
- meye.mchip_dmahandle);
-
- memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
- meye.mchip_ptable_toc = NULL;
- meye.mchip_dmahandle = 0;
-}
-
-/* copy data from ptable into buf */
-static void ptable_copy(u8 *buf, int start, int size, int pt_pages)
-{
- int i;
-
- for (i = 0; i < (size / PAGE_SIZE) * PAGE_SIZE; i += PAGE_SIZE) {
- memcpy(buf + i, meye.mchip_ptable[start++], PAGE_SIZE);
- if (start >= pt_pages)
- start = 0;
- }
- memcpy(buf + i, meye.mchip_ptable[start], size % PAGE_SIZE);
-}
-
-/****************************************************************************/
-/* JPEG tables at different qualities to load into the VRJ chip */
-/****************************************************************************/
-
-/* return a set of quantisation tables based on a quality from 1 to 10 */
-static u16 *jpeg_quantisation_tables(int *length, int quality)
-{
- static u16 jpeg_tables[][70] = { {
- 0xdbff, 0x4300, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff,
- 0xdbff, 0x4300, 0xff01, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff,
- },
- {
- 0xdbff, 0x4300, 0x5000, 0x3c37, 0x3c46, 0x5032, 0x4146, 0x5a46,
- 0x5055, 0x785f, 0x82c8, 0x6e78, 0x786e, 0xaff5, 0x91b9, 0xffc8,
- 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff,
- 0xdbff, 0x4300, 0x5501, 0x5a5a, 0x6978, 0xeb78, 0x8282, 0xffeb,
- 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff,
- },
- {
- 0xdbff, 0x4300, 0x2800, 0x1e1c, 0x1e23, 0x2819, 0x2123, 0x2d23,
- 0x282b, 0x3c30, 0x4164, 0x373c, 0x3c37, 0x587b, 0x495d, 0x9164,
- 0x9980, 0x8f96, 0x8c80, 0xa08a, 0xe6b4, 0xa0c3, 0xdaaa, 0x8aad,
- 0xc88c, 0xcbff, 0xeeda, 0xfff5, 0xffff, 0xc19b, 0xffff, 0xfaff,
- 0xe6ff, 0xfffd, 0xfff8,
- 0xdbff, 0x4300, 0x2b01, 0x2d2d, 0x353c, 0x763c, 0x4141, 0xf876,
- 0x8ca5, 0xf8a5, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
- 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
- 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
- 0xf8f8, 0xf8f8, 0xfff8,
- },
- {
- 0xdbff, 0x4300, 0x1b00, 0x1412, 0x1417, 0x1b11, 0x1617, 0x1e17,
- 0x1b1c, 0x2820, 0x2b42, 0x2528, 0x2825, 0x3a51, 0x303d, 0x6042,
- 0x6555, 0x5f64, 0x5d55, 0x6a5b, 0x9978, 0x6a81, 0x9071, 0x5b73,
- 0x855d, 0x86b5, 0x9e90, 0xaba3, 0xabad, 0x8067, 0xc9bc, 0xa6ba,
- 0x99c7, 0xaba8, 0xffa4,
- 0xdbff, 0x4300, 0x1c01, 0x1e1e, 0x2328, 0x4e28, 0x2b2b, 0xa44e,
- 0x5d6e, 0xa46e, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
- 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
- 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
- 0xa4a4, 0xa4a4, 0xffa4,
- },
- {
- 0xdbff, 0x4300, 0x1400, 0x0f0e, 0x0f12, 0x140d, 0x1012, 0x1712,
- 0x1415, 0x1e18, 0x2132, 0x1c1e, 0x1e1c, 0x2c3d, 0x242e, 0x4932,
- 0x4c40, 0x474b, 0x4640, 0x5045, 0x735a, 0x5062, 0x6d55, 0x4556,
- 0x6446, 0x6588, 0x776d, 0x817b, 0x8182, 0x604e, 0x978d, 0x7d8c,
- 0x7396, 0x817e, 0xff7c,
- 0xdbff, 0x4300, 0x1501, 0x1717, 0x1a1e, 0x3b1e, 0x2121, 0x7c3b,
- 0x4653, 0x7c53, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
- 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
- 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
- 0x7c7c, 0x7c7c, 0xff7c,
- },
- {
- 0xdbff, 0x4300, 0x1000, 0x0c0b, 0x0c0e, 0x100a, 0x0d0e, 0x120e,
- 0x1011, 0x1813, 0x1a28, 0x1618, 0x1816, 0x2331, 0x1d25, 0x3a28,
- 0x3d33, 0x393c, 0x3833, 0x4037, 0x5c48, 0x404e, 0x5744, 0x3745,
- 0x5038, 0x516d, 0x5f57, 0x6762, 0x6768, 0x4d3e, 0x7971, 0x6470,
- 0x5c78, 0x6765, 0xff63,
- 0xdbff, 0x4300, 0x1101, 0x1212, 0x1518, 0x2f18, 0x1a1a, 0x632f,
- 0x3842, 0x6342, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
- 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
- 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
- 0x6363, 0x6363, 0xff63,
- },
- {
- 0xdbff, 0x4300, 0x0d00, 0x0a09, 0x0a0b, 0x0d08, 0x0a0b, 0x0e0b,
- 0x0d0e, 0x130f, 0x1520, 0x1213, 0x1312, 0x1c27, 0x171e, 0x2e20,
- 0x3129, 0x2e30, 0x2d29, 0x332c, 0x4a3a, 0x333e, 0x4636, 0x2c37,
- 0x402d, 0x4157, 0x4c46, 0x524e, 0x5253, 0x3e32, 0x615a, 0x505a,
- 0x4a60, 0x5251, 0xff4f,
- 0xdbff, 0x4300, 0x0e01, 0x0e0e, 0x1113, 0x2613, 0x1515, 0x4f26,
- 0x2d35, 0x4f35, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
- 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
- 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
- 0x4f4f, 0x4f4f, 0xff4f,
- },
- {
- 0xdbff, 0x4300, 0x0a00, 0x0707, 0x0708, 0x0a06, 0x0808, 0x0b08,
- 0x0a0a, 0x0e0b, 0x1018, 0x0d0e, 0x0e0d, 0x151d, 0x1116, 0x2318,
- 0x251f, 0x2224, 0x221f, 0x2621, 0x372b, 0x262f, 0x3429, 0x2129,
- 0x3022, 0x3141, 0x3934, 0x3e3b, 0x3e3e, 0x2e25, 0x4944, 0x3c43,
- 0x3748, 0x3e3d, 0xff3b,
- 0xdbff, 0x4300, 0x0a01, 0x0b0b, 0x0d0e, 0x1c0e, 0x1010, 0x3b1c,
- 0x2228, 0x3b28, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
- 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
- 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
- 0x3b3b, 0x3b3b, 0xff3b,
- },
- {
- 0xdbff, 0x4300, 0x0600, 0x0504, 0x0506, 0x0604, 0x0506, 0x0706,
- 0x0607, 0x0a08, 0x0a10, 0x090a, 0x0a09, 0x0e14, 0x0c0f, 0x1710,
- 0x1814, 0x1718, 0x1614, 0x1a16, 0x251d, 0x1a1f, 0x231b, 0x161c,
- 0x2016, 0x202c, 0x2623, 0x2927, 0x292a, 0x1f19, 0x302d, 0x282d,
- 0x2530, 0x2928, 0xff28,
- 0xdbff, 0x4300, 0x0701, 0x0707, 0x080a, 0x130a, 0x0a0a, 0x2813,
- 0x161a, 0x281a, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
- 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
- 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
- 0x2828, 0x2828, 0xff28,
- },
- {
- 0xdbff, 0x4300, 0x0300, 0x0202, 0x0203, 0x0302, 0x0303, 0x0403,
- 0x0303, 0x0504, 0x0508, 0x0405, 0x0504, 0x070a, 0x0607, 0x0c08,
- 0x0c0a, 0x0b0c, 0x0b0a, 0x0d0b, 0x120e, 0x0d10, 0x110e, 0x0b0e,
- 0x100b, 0x1016, 0x1311, 0x1514, 0x1515, 0x0f0c, 0x1817, 0x1416,
- 0x1218, 0x1514, 0xff14,
- 0xdbff, 0x4300, 0x0301, 0x0404, 0x0405, 0x0905, 0x0505, 0x1409,
- 0x0b0d, 0x140d, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
- 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
- 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
- 0x1414, 0x1414, 0xff14,
- },
- {
- 0xdbff, 0x4300, 0x0100, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
- 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
- 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
- 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
- 0x0101, 0x0101, 0xff01,
- 0xdbff, 0x4300, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
- 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
- 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
- 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
- 0x0101, 0x0101, 0xff01,
- } };
-
- if (quality < 0 || quality > 10) {
- printk(KERN_WARNING
- "meye: invalid quality level %d - using 8\n", quality);
- quality = 8;
- }
-
- *length = ARRAY_SIZE(jpeg_tables[quality]);
- return jpeg_tables[quality];
-}
-
-/* return a generic set of huffman tables */
-static u16 *jpeg_huffman_tables(int *length)
-{
- static u16 tables[] = {
- 0xC4FF, 0xB500, 0x0010, 0x0102, 0x0303, 0x0402, 0x0503, 0x0405,
- 0x0004, 0x0100, 0x017D, 0x0302, 0x0400, 0x0511, 0x2112, 0x4131,
- 0x1306, 0x6151, 0x2207, 0x1471, 0x8132, 0xA191, 0x2308, 0xB142,
- 0x15C1, 0xD152, 0x24F0, 0x6233, 0x8272, 0x0A09, 0x1716, 0x1918,
- 0x251A, 0x2726, 0x2928, 0x342A, 0x3635, 0x3837, 0x3A39, 0x4443,
- 0x4645, 0x4847, 0x4A49, 0x5453, 0x5655, 0x5857, 0x5A59, 0x6463,
- 0x6665, 0x6867, 0x6A69, 0x7473, 0x7675, 0x7877, 0x7A79, 0x8483,
- 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998, 0xA29A,
- 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6, 0xB9B8,
- 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4, 0xD7D6,
- 0xD9D8, 0xE1DA, 0xE3E2, 0xE5E4, 0xE7E6, 0xE9E8, 0xF1EA, 0xF3F2,
- 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA,
- 0xC4FF, 0xB500, 0x0011, 0x0102, 0x0402, 0x0304, 0x0704, 0x0405,
- 0x0004, 0x0201, 0x0077, 0x0201, 0x1103, 0x0504, 0x3121, 0x1206,
- 0x5141, 0x6107, 0x1371, 0x3222, 0x0881, 0x4214, 0xA191, 0xC1B1,
- 0x2309, 0x5233, 0x15F0, 0x7262, 0x0AD1, 0x2416, 0xE134, 0xF125,
- 0x1817, 0x1A19, 0x2726, 0x2928, 0x352A, 0x3736, 0x3938, 0x433A,
- 0x4544, 0x4746, 0x4948, 0x534A, 0x5554, 0x5756, 0x5958, 0x635A,
- 0x6564, 0x6766, 0x6968, 0x736A, 0x7574, 0x7776, 0x7978, 0x827A,
- 0x8483, 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998,
- 0xA29A, 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6,
- 0xB9B8, 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4,
- 0xD7D6, 0xD9D8, 0xE2DA, 0xE4E3, 0xE6E5, 0xE8E7, 0xEAE9, 0xF3F2,
- 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA,
- 0xC4FF, 0x1F00, 0x0000, 0x0501, 0x0101, 0x0101, 0x0101, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09,
- 0xFF0B,
- 0xC4FF, 0x1F00, 0x0001, 0x0103, 0x0101, 0x0101, 0x0101, 0x0101,
- 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09,
- 0xFF0B
- };
-
- *length = ARRAY_SIZE(tables);
- return tables;
-}
-
-/****************************************************************************/
-/* MCHIP low-level functions */
-/****************************************************************************/
-
-/* returns the horizontal capture size */
-static inline int mchip_hsize(void)
-{
- return meye.params.subsample ? 320 : 640;
-}
-
-/* returns the vertical capture size */
-static inline int mchip_vsize(void)
-{
- return meye.params.subsample ? 240 : 480;
-}
-
-/* waits for a register to be available */
-static void mchip_sync(int reg)
-{
- u32 status;
- int i;
-
- if (reg == MCHIP_MM_FIFO_DATA) {
- for (i = 0; i < MCHIP_REG_TIMEOUT; i++) {
- status = readl(meye.mchip_mmregs +
- MCHIP_MM_FIFO_STATUS);
- if (!(status & MCHIP_MM_FIFO_WAIT)) {
- printk(KERN_WARNING "meye: fifo not ready\n");
- return;
- }
- if (status & MCHIP_MM_FIFO_READY)
- return;
- udelay(1);
- }
- } else if (reg > 0x80) {
- u32 mask = (reg < 0x100) ? MCHIP_HIC_STATUS_MCC_RDY
- : MCHIP_HIC_STATUS_VRJ_RDY;
- for (i = 0; i < MCHIP_REG_TIMEOUT; i++) {
- status = readl(meye.mchip_mmregs + MCHIP_HIC_STATUS);
- if (status & mask)
- return;
- udelay(1);
- }
- } else
- return;
- printk(KERN_WARNING
- "meye: mchip_sync() timeout on reg 0x%x status=0x%x\n",
- reg, status);
-}
-
-/* sets a value into the register */
-static inline void mchip_set(int reg, u32 v)
-{
- mchip_sync(reg);
- writel(v, meye.mchip_mmregs + reg);
-}
-
-/* get the register value */
-static inline u32 mchip_read(int reg)
-{
- mchip_sync(reg);
- return readl(meye.mchip_mmregs + reg);
-}
-
-/* wait for a register to become a particular value */
-static inline int mchip_delay(u32 reg, u32 v)
-{
- int n = 10;
- while (--n && mchip_read(reg) != v)
- udelay(1);
- return n;
-}
-
-/* setup subsampling */
-static void mchip_subsample(void)
-{
- mchip_set(MCHIP_MCC_R_SAMPLING, meye.params.subsample);
- mchip_set(MCHIP_MCC_R_XRANGE, mchip_hsize());
- mchip_set(MCHIP_MCC_R_YRANGE, mchip_vsize());
- mchip_set(MCHIP_MCC_B_XRANGE, mchip_hsize());
- mchip_set(MCHIP_MCC_B_YRANGE, mchip_vsize());
- mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
-}
-
-/* set the framerate into the mchip */
-static void mchip_set_framerate(void)
-{
- mchip_set(MCHIP_HIC_S_RATE, meye.params.framerate);
-}
-
-/* load some huffman and quantisation tables into the VRJ chip ready
- for JPEG compression */
-static void mchip_load_tables(void)
-{
- int i;
- int length;
- u16 *tables;
-
- tables = jpeg_huffman_tables(&length);
- for (i = 0; i < length; i++)
- writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA);
-
- tables = jpeg_quantisation_tables(&length, meye.params.quality);
- for (i = 0; i < length; i++)
- writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA);
-}
-
-/* setup the VRJ parameters in the chip */
-static void mchip_vrj_setup(u8 mode)
-{
- mchip_set(MCHIP_VRJ_BUS_MODE, 5);
- mchip_set(MCHIP_VRJ_SIGNAL_ACTIVE_LEVEL, 0x1f);
- mchip_set(MCHIP_VRJ_PDAT_USE, 1);
- mchip_set(MCHIP_VRJ_IRQ_FLAG, 0xa0);
- mchip_set(MCHIP_VRJ_MODE_SPECIFY, mode);
- mchip_set(MCHIP_VRJ_NUM_LINES, mchip_vsize());
- mchip_set(MCHIP_VRJ_NUM_PIXELS, mchip_hsize());
- mchip_set(MCHIP_VRJ_NUM_COMPONENTS, 0x1b);
- mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_LO, 0xFFFF);
- mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_HI, 0xFFFF);
- mchip_set(MCHIP_VRJ_COMP_DATA_FORMAT, 0xC);
- mchip_set(MCHIP_VRJ_RESTART_INTERVAL, 0);
- mchip_set(MCHIP_VRJ_SOF1, 0x601);
- mchip_set(MCHIP_VRJ_SOF2, 0x1502);
- mchip_set(MCHIP_VRJ_SOF3, 0x1503);
- mchip_set(MCHIP_VRJ_SOF4, 0x1596);
- mchip_set(MCHIP_VRJ_SOS, 0x0ed0);
-
- mchip_load_tables();
-}
-
-/* sets the DMA parameters into the chip */
-static void mchip_dma_setup(dma_addr_t dma_addr)
-{
- int i;
-
- mchip_set(MCHIP_MM_PT_ADDR, (u32)dma_addr);
- for (i = 0; i < 4; i++)
- mchip_set(MCHIP_MM_FIR(i), 0);
- meye.mchip_fnum = 0;
-}
-
-/* setup for DMA transfers - also zeros the framebuffer */
-static int mchip_dma_alloc(void)
-{
- if (!meye.mchip_dmahandle)
- if (ptable_alloc())
- return -1;
- return 0;
-}
-
-/* frees the DMA buffer */
-static void mchip_dma_free(void)
-{
- if (meye.mchip_dmahandle) {
- mchip_dma_setup(0);
- ptable_free();
- }
-}
-
-/* stop any existing HIC action and wait for any dma to complete then
- reset the dma engine */
-static void mchip_hic_stop(void)
-{
- int i, j;
-
- meye.mchip_mode = MCHIP_HIC_MODE_NOOP;
- if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY))
- return;
- for (i = 0; i < 20; ++i) {
- mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP);
- mchip_delay(MCHIP_HIC_CMD, 0);
- for (j = 0; j < 100; ++j) {
- if (mchip_delay(MCHIP_HIC_STATUS,
- MCHIP_HIC_STATUS_IDLE))
- return;
- msleep(1);
- }
- printk(KERN_ERR "meye: need to reset HIC!\n");
-
- mchip_set(MCHIP_HIC_CTL, MCHIP_HIC_CTL_SOFT_RESET);
- msleep(250);
- }
- printk(KERN_ERR "meye: resetting HIC hanged!\n");
-}
-
-/****************************************************************************/
-/* MCHIP frame processing functions */
-/****************************************************************************/
-
-/* get the next ready frame from the dma engine */
-static u32 mchip_get_frame(void)
-{
- u32 v;
-
- v = mchip_read(MCHIP_MM_FIR(meye.mchip_fnum));
- return v;
-}
-
-/* frees the current frame from the dma engine */
-static void mchip_free_frame(void)
-{
- mchip_set(MCHIP_MM_FIR(meye.mchip_fnum), 0);
- meye.mchip_fnum++;
- meye.mchip_fnum %= 4;
-}
-
-/* read one frame from the framebuffer assuming it was captured using
- a uncompressed transfer */
-static void mchip_cont_read_frame(u32 v, u8 *buf, int size)
-{
- int pt_id;
-
- pt_id = (v >> 17) & 0x3FF;
-
- ptable_copy(buf, pt_id, size, MCHIP_NB_PAGES);
-}
-
-/* read a compressed frame from the framebuffer */
-static int mchip_comp_read_frame(u32 v, u8 *buf, int size)
-{
- int pt_start, pt_end, trailer;
- int fsize;
- int i;
-
- pt_start = (v >> 19) & 0xFF;
- pt_end = (v >> 11) & 0xFF;
- trailer = (v >> 1) & 0x3FF;
-
- if (pt_end < pt_start)
- fsize = (MCHIP_NB_PAGES_MJPEG - pt_start) * PAGE_SIZE +
- pt_end * PAGE_SIZE + trailer * 4;
- else
- fsize = (pt_end - pt_start) * PAGE_SIZE + trailer * 4;
-
- if (fsize > size) {
- printk(KERN_WARNING "meye: oversized compressed frame %d\n",
- fsize);
- return -1;
- }
-
- ptable_copy(buf, pt_start, fsize, MCHIP_NB_PAGES_MJPEG);
-
-#ifdef MEYE_JPEG_CORRECTION
-
- /* Some mchip generated jpeg frames are incorrect. In most
- * (all ?) of those cases, the final EOI (0xff 0xd9) marker
- * is not present at the end of the frame.
- *
- * Since adding the final marker is not enough to restore
- * the jpeg integrity, we drop the frame.
- */
-
- for (i = fsize - 1; i > 0 && buf[i] == 0xff; i--) ;
-
- if (i < 2 || buf[i - 1] != 0xff || buf[i] != 0xd9)
- return -1;
-
-#endif
-
- return fsize;
-}
-
-/* take a picture into SDRAM */
-static void mchip_take_picture(void)
-{
- int i;
-
- mchip_hic_stop();
- mchip_subsample();
- mchip_dma_setup(meye.mchip_dmahandle);
-
- mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_CAP);
- mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
-
- mchip_delay(MCHIP_HIC_CMD, 0);
-
- for (i = 0; i < 100; ++i) {
- if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
- break;
- msleep(1);
- }
-}
-
-/* dma a previously taken picture into a buffer */
-static void mchip_get_picture(u8 *buf, int bufsize)
-{
- u32 v;
- int i;
-
- mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_OUT);
- mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
-
- mchip_delay(MCHIP_HIC_CMD, 0);
- for (i = 0; i < 100; ++i) {
- if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
- break;
- msleep(1);
- }
- for (i = 0; i < 4; ++i) {
- v = mchip_get_frame();
- if (v & MCHIP_MM_FIR_RDY) {
- mchip_cont_read_frame(v, buf, bufsize);
- break;
- }
- mchip_free_frame();
- }
-}
-
-/* start continuous dma capture */
-static void mchip_continuous_start(void)
-{
- mchip_hic_stop();
- mchip_subsample();
- mchip_set_framerate();
- mchip_dma_setup(meye.mchip_dmahandle);
-
- meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT;
-
- mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_OUT);
- mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
-
- mchip_delay(MCHIP_HIC_CMD, 0);
-}
-
-/* compress one frame into a buffer */
-static int mchip_compress_frame(u8 *buf, int bufsize)
-{
- u32 v;
- int len = -1, i;
-
- mchip_vrj_setup(0x3f);
- udelay(50);
-
- mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_COMP);
- mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
-
- mchip_delay(MCHIP_HIC_CMD, 0);
- for (i = 0; i < 100; ++i) {
- if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
- break;
- msleep(1);
- }
-
- for (i = 0; i < 4; ++i) {
- v = mchip_get_frame();
- if (v & MCHIP_MM_FIR_RDY) {
- len = mchip_comp_read_frame(v, buf, bufsize);
- break;
- }
- mchip_free_frame();
- }
- return len;
-}
-
-#if 0
-/* uncompress one image into a buffer */
-static int mchip_uncompress_frame(u8 *img, int imgsize, u8 *buf, int bufsize)
-{
- mchip_vrj_setup(0x3f);
- udelay(50);
-
- mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_DECOMP);
- mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
-
- mchip_delay(MCHIP_HIC_CMD, 0);
-
- return mchip_comp_read_frame(buf, bufsize);
-}
-#endif
-
-/* start continuous compressed capture */
-static void mchip_cont_compression_start(void)
-{
- mchip_hic_stop();
- mchip_vrj_setup(0x3f);
- mchip_subsample();
- mchip_set_framerate();
- mchip_dma_setup(meye.mchip_dmahandle);
-
- meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;
-
- mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_COMP);
- mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
-
- mchip_delay(MCHIP_HIC_CMD, 0);
-}
-
-/****************************************************************************/
-/* Interrupt handling */
-/****************************************************************************/
-
-static irqreturn_t meye_irq(int irq, void *dev_id)
-{
- u32 v;
- int reqnr;
- static int sequence;
-
- v = mchip_read(MCHIP_MM_INTA);
-
- if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT &&
- meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
- return IRQ_NONE;
-
-again:
- v = mchip_get_frame();
- if (!(v & MCHIP_MM_FIR_RDY))
- return IRQ_HANDLED;
-
- if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) {
- if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr,
- sizeof(int), &meye.grabq_lock) != sizeof(int)) {
- mchip_free_frame();
- return IRQ_HANDLED;
- }
- mchip_cont_read_frame(v, meye.grab_fbuffer + gbufsize * reqnr,
- mchip_hsize() * mchip_vsize() * 2);
- meye.grab_buffer[reqnr].size = mchip_hsize() * mchip_vsize() * 2;
- meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
- do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
- meye.grab_buffer[reqnr].sequence = sequence++;
- kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr,
- sizeof(int), &meye.doneq_lock);
- wake_up_interruptible(&meye.proc_list);
- } else {
- int size;
- size = mchip_comp_read_frame(v, meye.grab_temp, gbufsize);
- if (size == -1) {
- mchip_free_frame();
- goto again;
- }
- if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr,
- sizeof(int), &meye.grabq_lock) != sizeof(int)) {
- mchip_free_frame();
- goto again;
- }
- memcpy(meye.grab_fbuffer + gbufsize * reqnr, meye.grab_temp,
- size);
- meye.grab_buffer[reqnr].size = size;
- meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
- do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
- meye.grab_buffer[reqnr].sequence = sequence++;
- kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr,
- sizeof(int), &meye.doneq_lock);
- wake_up_interruptible(&meye.proc_list);
- }
- mchip_free_frame();
- goto again;
-}
-
-/****************************************************************************/
-/* video4linux integration */
-/****************************************************************************/
-
-static int meye_open(struct file *file)
-{
- int i;
-
- if (test_and_set_bit(0, &meye.in_use))
- return -EBUSY;
-
- mchip_hic_stop();
-
- if (mchip_dma_alloc()) {
- printk(KERN_ERR "meye: mchip framebuffer allocation failed\n");
- clear_bit(0, &meye.in_use);
- return -ENOBUFS;
- }
-
- for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
- meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
- kfifo_reset(&meye.grabq);
- kfifo_reset(&meye.doneq);
- return 0;
-}
-
-static int meye_release(struct file *file)
-{
- mchip_hic_stop();
- mchip_dma_free();
- clear_bit(0, &meye.in_use);
- return 0;
-}
-
-static int meyeioc_g_params(struct meye_params *p)
-{
- *p = meye.params;
- return 0;
-}
-
-static int meyeioc_s_params(struct meye_params *jp)
-{
- if (jp->subsample > 1)
- return -EINVAL;
-
- if (jp->quality > 10)
- return -EINVAL;
-
- if (jp->sharpness > 63 || jp->agc > 63 || jp->picture > 63)
- return -EINVAL;
-
- if (jp->framerate > 31)
- return -EINVAL;
-
- mutex_lock(&meye.lock);
-
- if (meye.params.subsample != jp->subsample ||
- meye.params.quality != jp->quality)
- mchip_hic_stop(); /* need restart */
-
- meye.params = *jp;
- sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERASHARPNESS,
- meye.params.sharpness);
- sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC,
- meye.params.agc);
- sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE,
- meye.params.picture);
- mutex_unlock(&meye.lock);
-
- return 0;
-}
-
-static int meyeioc_qbuf_capt(int *nb)
-{
- if (!meye.grab_fbuffer)
- return -EINVAL;
-
- if (*nb >= gbuffers)
- return -EINVAL;
-
- if (*nb < 0) {
- /* stop capture */
- mchip_hic_stop();
- return 0;
- }
-
- if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED)
- return -EBUSY;
-
- mutex_lock(&meye.lock);
-
- if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
- mchip_cont_compression_start();
-
- meye.grab_buffer[*nb].state = MEYE_BUF_USING;
- kfifo_in_locked(&meye.grabq, (unsigned char *)nb, sizeof(int),
- &meye.grabq_lock);
- mutex_unlock(&meye.lock);
-
- return 0;
-}
-
-static int meyeioc_sync(struct file *file, void *fh, int *i)
-{
- int unused;
-
- if (*i < 0 || *i >= gbuffers)
- return -EINVAL;
-
- mutex_lock(&meye.lock);
- switch (meye.grab_buffer[*i].state) {
-
- case MEYE_BUF_UNUSED:
- mutex_unlock(&meye.lock);
- return -EINVAL;
- case MEYE_BUF_USING:
- if (file->f_flags & O_NONBLOCK) {
- mutex_unlock(&meye.lock);
- return -EAGAIN;
- }
- if (wait_event_interruptible(meye.proc_list,
- (meye.grab_buffer[*i].state != MEYE_BUF_USING))) {
- mutex_unlock(&meye.lock);
- return -EINTR;
- }
- /* fall through */
- case MEYE_BUF_DONE:
- meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
- if (kfifo_out_locked(&meye.doneq, (unsigned char *)&unused,
- sizeof(int), &meye.doneq_lock) != sizeof(int))
- break;
- }
- *i = meye.grab_buffer[*i].size;
- mutex_unlock(&meye.lock);
- return 0;
-}
-
-static int meyeioc_stillcapt(void)
-{
- if (!meye.grab_fbuffer)
- return -EINVAL;
-
- if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
- return -EBUSY;
-
- mutex_lock(&meye.lock);
- meye.grab_buffer[0].state = MEYE_BUF_USING;
- mchip_take_picture();
-
- mchip_get_picture(meye.grab_fbuffer,
- mchip_hsize() * mchip_vsize() * 2);
-
- meye.grab_buffer[0].state = MEYE_BUF_DONE;
- mutex_unlock(&meye.lock);
-
- return 0;
-}
-
-static int meyeioc_stilljcapt(int *len)
-{
- if (!meye.grab_fbuffer)
- return -EINVAL;
-
- if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
- return -EBUSY;
-
- mutex_lock(&meye.lock);
- meye.grab_buffer[0].state = MEYE_BUF_USING;
- *len = -1;
-
- while (*len == -1) {
- mchip_take_picture();
- *len = mchip_compress_frame(meye.grab_fbuffer, gbufsize);
- }
-
- meye.grab_buffer[0].state = MEYE_BUF_DONE;
- mutex_unlock(&meye.lock);
- return 0;
-}
-
-static int vidioc_querycap(struct file *file, void *fh,
- struct v4l2_capability *cap)
-{
- strcpy(cap->driver, "meye");
- strcpy(cap->card, "meye");
- sprintf(cap->bus_info, "PCI:%s", pci_name(meye.mchip_dev));
-
- cap->version = (MEYE_DRIVER_MAJORVERSION << 8) +
- MEYE_DRIVER_MINORVERSION;
-
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_STREAMING;
-
- return 0;
-}
-
-static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
-{
- if (i->index != 0)
- return -EINVAL;
-
- strcpy(i->name, "Camera");
- i->type = V4L2_INPUT_TYPE_CAMERA;
-
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *fh, unsigned int i)
-{
- if (i != 0)
- return -EINVAL;
-
- return 0;
-}
-
-static int vidioc_queryctrl(struct file *file, void *fh,
- struct v4l2_queryctrl *c)
-{
- switch (c->id) {
-
- case V4L2_CID_BRIGHTNESS:
- c->type = V4L2_CTRL_TYPE_INTEGER;
- strcpy(c->name, "Brightness");
- c->minimum = 0;
- c->maximum = 63;
- c->step = 1;
- c->default_value = 32;
- c->flags = 0;
- break;
- case V4L2_CID_HUE:
- c->type = V4L2_CTRL_TYPE_INTEGER;
- strcpy(c->name, "Hue");
- c->minimum = 0;
- c->maximum = 63;
- c->step = 1;
- c->default_value = 32;
- c->flags = 0;
- break;
- case V4L2_CID_CONTRAST:
- c->type = V4L2_CTRL_TYPE_INTEGER;
- strcpy(c->name, "Contrast");
- c->minimum = 0;
- c->maximum = 63;
- c->step = 1;
- c->default_value = 32;
- c->flags = 0;
- break;
- case V4L2_CID_SATURATION:
- c->type = V4L2_CTRL_TYPE_INTEGER;
- strcpy(c->name, "Saturation");
- c->minimum = 0;
- c->maximum = 63;
- c->step = 1;
- c->default_value = 32;
- c->flags = 0;
- break;
- case V4L2_CID_AGC:
- c->type = V4L2_CTRL_TYPE_INTEGER;
- strcpy(c->name, "Agc");
- c->minimum = 0;
- c->maximum = 63;
- c->step = 1;
- c->default_value = 48;
- c->flags = 0;
- break;
- case V4L2_CID_MEYE_SHARPNESS:
- case V4L2_CID_SHARPNESS:
- c->type = V4L2_CTRL_TYPE_INTEGER;
- strcpy(c->name, "Sharpness");
- c->minimum = 0;
- c->maximum = 63;
- c->step = 1;
- c->default_value = 32;
-
- /* Continue to report legacy private SHARPNESS ctrl but
- * say it is disabled in preference to ctrl in the spec
- */
- c->flags = (c->id == V4L2_CID_SHARPNESS) ? 0 :
- V4L2_CTRL_FLAG_DISABLED;
- break;
- case V4L2_CID_PICTURE:
- c->type = V4L2_CTRL_TYPE_INTEGER;
- strcpy(c->name, "Picture");
- c->minimum = 0;
- c->maximum = 63;
- c->step = 1;
- c->default_value = 0;
- c->flags = 0;
- break;
- case V4L2_CID_JPEGQUAL:
- c->type = V4L2_CTRL_TYPE_INTEGER;
- strcpy(c->name, "JPEG quality");
- c->minimum = 0;
- c->maximum = 10;
- c->step = 1;
- c->default_value = 8;
- c->flags = 0;
- break;
- case V4L2_CID_FRAMERATE:
- c->type = V4L2_CTRL_TYPE_INTEGER;
- strcpy(c->name, "Framerate");
- c->minimum = 0;
- c->maximum = 31;
- c->step = 1;
- c->default_value = 0;
- c->flags = 0;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
-{
- mutex_lock(&meye.lock);
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- sony_pic_camera_command(
- SONY_PIC_COMMAND_SETCAMERABRIGHTNESS, c->value);
- meye.brightness = c->value << 10;
- break;
- case V4L2_CID_HUE:
- sony_pic_camera_command(
- SONY_PIC_COMMAND_SETCAMERAHUE, c->value);
- meye.hue = c->value << 10;
- break;
- case V4L2_CID_CONTRAST:
- sony_pic_camera_command(
- SONY_PIC_COMMAND_SETCAMERACONTRAST, c->value);
- meye.contrast = c->value << 10;
- break;
- case V4L2_CID_SATURATION:
- sony_pic_camera_command(
- SONY_PIC_COMMAND_SETCAMERACOLOR, c->value);
- meye.colour = c->value << 10;
- break;
- case V4L2_CID_AGC:
- sony_pic_camera_command(
- SONY_PIC_COMMAND_SETCAMERAAGC, c->value);
- meye.params.agc = c->value;
- break;
- case V4L2_CID_SHARPNESS:
- case V4L2_CID_MEYE_SHARPNESS:
- sony_pic_camera_command(
- SONY_PIC_COMMAND_SETCAMERASHARPNESS, c->value);
- meye.params.sharpness = c->value;
- break;
- case V4L2_CID_PICTURE:
- sony_pic_camera_command(
- SONY_PIC_COMMAND_SETCAMERAPICTURE, c->value);
- meye.params.picture = c->value;
- break;
- case V4L2_CID_JPEGQUAL:
- meye.params.quality = c->value;
- break;
- case V4L2_CID_FRAMERATE:
- meye.params.framerate = c->value;
- break;
- default:
- mutex_unlock(&meye.lock);
- return -EINVAL;
- }
- mutex_unlock(&meye.lock);
-
- return 0;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
-{
- mutex_lock(&meye.lock);
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- c->value = meye.brightness >> 10;
- break;
- case V4L2_CID_HUE:
- c->value = meye.hue >> 10;
- break;
- case V4L2_CID_CONTRAST:
- c->value = meye.contrast >> 10;
- break;
- case V4L2_CID_SATURATION:
- c->value = meye.colour >> 10;
- break;
- case V4L2_CID_AGC:
- c->value = meye.params.agc;
- break;
- case V4L2_CID_SHARPNESS:
- case V4L2_CID_MEYE_SHARPNESS:
- c->value = meye.params.sharpness;
- break;
- case V4L2_CID_PICTURE:
- c->value = meye.params.picture;
- break;
- case V4L2_CID_JPEGQUAL:
- c->value = meye.params.quality;
- break;
- case V4L2_CID_FRAMERATE:
- c->value = meye.params.framerate;
- break;
- default:
- mutex_unlock(&meye.lock);
- return -EINVAL;
- }
- mutex_unlock(&meye.lock);
-
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_fmtdesc *f)
-{
- if (f->index > 1)
- return -EINVAL;
-
- if (f->index == 0) {
- /* standard YUV 422 capture */
- f->flags = 0;
- strcpy(f->description, "YUV422");
- f->pixelformat = V4L2_PIX_FMT_YUYV;
- } else {
- /* compressed MJPEG capture */
- f->flags = V4L2_FMT_FLAG_COMPRESSED;
- strcpy(f->description, "MJPEG");
- f->pixelformat = V4L2_PIX_FMT_MJPEG;
- }
-
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
- f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
- return -EINVAL;
-
- if (f->fmt.pix.field != V4L2_FIELD_ANY &&
- f->fmt.pix.field != V4L2_FIELD_NONE)
- return -EINVAL;
-
- f->fmt.pix.field = V4L2_FIELD_NONE;
-
- if (f->fmt.pix.width <= 320) {
- f->fmt.pix.width = 320;
- f->fmt.pix.height = 240;
- } else {
- f->fmt.pix.width = 640;
- f->fmt.pix.height = 480;
- }
-
- f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
- f->fmt.pix.sizeimage = f->fmt.pix.height *
- f->fmt.pix.bytesperline;
- f->fmt.pix.colorspace = 0;
- f->fmt.pix.priv = 0;
-
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- switch (meye.mchip_mode) {
- case MCHIP_HIC_MODE_CONT_OUT:
- default:
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
- break;
- case MCHIP_HIC_MODE_CONT_COMP:
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
- break;
- }
-
- f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.width = mchip_hsize();
- f->fmt.pix.height = mchip_vsize();
- f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
- f->fmt.pix.sizeimage = f->fmt.pix.height *
- f->fmt.pix.bytesperline;
-
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
- f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
- return -EINVAL;
-
- if (f->fmt.pix.field != V4L2_FIELD_ANY &&
- f->fmt.pix.field != V4L2_FIELD_NONE)
- return -EINVAL;
-
- f->fmt.pix.field = V4L2_FIELD_NONE;
- mutex_lock(&meye.lock);
-
- if (f->fmt.pix.width <= 320) {
- f->fmt.pix.width = 320;
- f->fmt.pix.height = 240;
- meye.params.subsample = 1;
- } else {
- f->fmt.pix.width = 640;
- f->fmt.pix.height = 480;
- meye.params.subsample = 0;
- }
-
- switch (f->fmt.pix.pixelformat) {
- case V4L2_PIX_FMT_YUYV:
- meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT;
- break;
- case V4L2_PIX_FMT_MJPEG:
- meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;
- break;
- }
-
- mutex_unlock(&meye.lock);
- f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
- f->fmt.pix.sizeimage = f->fmt.pix.height *
- f->fmt.pix.bytesperline;
- f->fmt.pix.colorspace = 0;
- f->fmt.pix.priv = 0;
-
- return 0;
-}
-
-static int vidioc_reqbufs(struct file *file, void *fh,
- struct v4l2_requestbuffers *req)
-{
- int i;
-
- if (req->memory != V4L2_MEMORY_MMAP)
- return -EINVAL;
-
- if (meye.grab_fbuffer && req->count == gbuffers) {
- /* already allocated, no modifications */
- return 0;
- }
-
- mutex_lock(&meye.lock);
- if (meye.grab_fbuffer) {
- for (i = 0; i < gbuffers; i++)
- if (meye.vma_use_count[i]) {
- mutex_unlock(&meye.lock);
- return -EINVAL;
- }
- rvfree(meye.grab_fbuffer, gbuffers * gbufsize);
- meye.grab_fbuffer = NULL;
- }
-
- gbuffers = max(2, min((int)req->count, MEYE_MAX_BUFNBRS));
- req->count = gbuffers;
- meye.grab_fbuffer = rvmalloc(gbuffers * gbufsize);
-
- if (!meye.grab_fbuffer) {
- printk(KERN_ERR "meye: v4l framebuffer allocation"
- " failed\n");
- mutex_unlock(&meye.lock);
- return -ENOMEM;
- }
-
- for (i = 0; i < gbuffers; i++)
- meye.vma_use_count[i] = 0;
-
- mutex_unlock(&meye.lock);
-
- return 0;
-}
-
-static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
-{
- unsigned int index = buf->index;
-
- if (index >= gbuffers)
- return -EINVAL;
-
- buf->bytesused = meye.grab_buffer[index].size;
- buf->flags = V4L2_BUF_FLAG_MAPPED;
-
- if (meye.grab_buffer[index].state == MEYE_BUF_USING)
- buf->flags |= V4L2_BUF_FLAG_QUEUED;
-
- if (meye.grab_buffer[index].state == MEYE_BUF_DONE)
- buf->flags |= V4L2_BUF_FLAG_DONE;
-
- buf->field = V4L2_FIELD_NONE;
- buf->timestamp = meye.grab_buffer[index].timestamp;
- buf->sequence = meye.grab_buffer[index].sequence;
- buf->memory = V4L2_MEMORY_MMAP;
- buf->m.offset = index * gbufsize;
- buf->length = gbufsize;
-
- return 0;
-}
-
-static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
-{
- if (buf->memory != V4L2_MEMORY_MMAP)
- return -EINVAL;
-
- if (buf->index >= gbuffers)
- return -EINVAL;
-
- if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED)
- return -EINVAL;
-
- mutex_lock(&meye.lock);
- buf->flags |= V4L2_BUF_FLAG_QUEUED;
- buf->flags &= ~V4L2_BUF_FLAG_DONE;
- meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
- kfifo_in_locked(&meye.grabq, (unsigned char *)&buf->index,
- sizeof(int), &meye.grabq_lock);
- mutex_unlock(&meye.lock);
-
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
-{
- int reqnr;
-
- if (buf->memory != V4L2_MEMORY_MMAP)
- return -EINVAL;
-
- mutex_lock(&meye.lock);
-
- if (kfifo_len(&meye.doneq) == 0 && file->f_flags & O_NONBLOCK) {
- mutex_unlock(&meye.lock);
- return -EAGAIN;
- }
-
- if (wait_event_interruptible(meye.proc_list,
- kfifo_len(&meye.doneq) != 0) < 0) {
- mutex_unlock(&meye.lock);
- return -EINTR;
- }
-
- if (!kfifo_out_locked(&meye.doneq, (unsigned char *)&reqnr,
- sizeof(int), &meye.doneq_lock)) {
- mutex_unlock(&meye.lock);
- return -EBUSY;
- }
-
- if (meye.grab_buffer[reqnr].state != MEYE_BUF_DONE) {
- mutex_unlock(&meye.lock);
- return -EINVAL;
- }
-
- buf->index = reqnr;
- buf->bytesused = meye.grab_buffer[reqnr].size;
- buf->flags = V4L2_BUF_FLAG_MAPPED;
- buf->field = V4L2_FIELD_NONE;
- buf->timestamp = meye.grab_buffer[reqnr].timestamp;
- buf->sequence = meye.grab_buffer[reqnr].sequence;
- buf->memory = V4L2_MEMORY_MMAP;
- buf->m.offset = reqnr * gbufsize;
- buf->length = gbufsize;
- meye.grab_buffer[reqnr].state = MEYE_BUF_UNUSED;
- mutex_unlock(&meye.lock);
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
-{
- mutex_lock(&meye.lock);
-
- switch (meye.mchip_mode) {
- case MCHIP_HIC_MODE_CONT_OUT:
- mchip_continuous_start();
- break;
- case MCHIP_HIC_MODE_CONT_COMP:
- mchip_cont_compression_start();
- break;
- default:
- mutex_unlock(&meye.lock);
- return -EINVAL;
- }
-
- mutex_unlock(&meye.lock);
-
- return 0;
-}
-
-static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
-{
- mutex_lock(&meye.lock);
- mchip_hic_stop();
- kfifo_reset(&meye.grabq);
- kfifo_reset(&meye.doneq);
-
- for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
- meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
-
- mutex_unlock(&meye.lock);
- return 0;
-}
-
-static long vidioc_default(struct file *file, void *fh, bool valid_prio,
- int cmd, void *arg)
-{
- switch (cmd) {
- case MEYEIOC_G_PARAMS:
- return meyeioc_g_params((struct meye_params *) arg);
-
- case MEYEIOC_S_PARAMS:
- return meyeioc_s_params((struct meye_params *) arg);
-
- case MEYEIOC_QBUF_CAPT:
- return meyeioc_qbuf_capt((int *) arg);
-
- case MEYEIOC_SYNC:
- return meyeioc_sync(file, fh, (int *) arg);
-
- case MEYEIOC_STILLCAPT:
- return meyeioc_stillcapt();
-
- case MEYEIOC_STILLJCAPT:
- return meyeioc_stilljcapt((int *) arg);
-
- default:
- return -ENOTTY;
- }
-
-}
-
-static unsigned int meye_poll(struct file *file, poll_table *wait)
-{
- unsigned int res = 0;
-
- mutex_lock(&meye.lock);
- poll_wait(file, &meye.proc_list, wait);
- if (kfifo_len(&meye.doneq))
- res = POLLIN | POLLRDNORM;
- mutex_unlock(&meye.lock);
- return res;
-}
-
-static void meye_vm_open(struct vm_area_struct *vma)
-{
- long idx = (long)vma->vm_private_data;
- meye.vma_use_count[idx]++;
-}
-
-static void meye_vm_close(struct vm_area_struct *vma)
-{
- long idx = (long)vma->vm_private_data;
- meye.vma_use_count[idx]--;
-}
-
-static const struct vm_operations_struct meye_vm_ops = {
- .open = meye_vm_open,
- .close = meye_vm_close,
-};
-
-static int meye_mmap(struct file *file, struct vm_area_struct *vma)
-{
- unsigned long start = vma->vm_start;
- unsigned long size = vma->vm_end - vma->vm_start;
- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
- unsigned long page, pos;
-
- mutex_lock(&meye.lock);
- if (size > gbuffers * gbufsize) {
- mutex_unlock(&meye.lock);
- return -EINVAL;
- }
- if (!meye.grab_fbuffer) {
- int i;
-
- /* lazy allocation */
- meye.grab_fbuffer = rvmalloc(gbuffers*gbufsize);
- if (!meye.grab_fbuffer) {
- printk(KERN_ERR "meye: v4l framebuffer allocation failed\n");
- mutex_unlock(&meye.lock);
- return -ENOMEM;
- }
- for (i = 0; i < gbuffers; i++)
- meye.vma_use_count[i] = 0;
- }
- pos = (unsigned long)meye.grab_fbuffer + offset;
-
- while (size > 0) {
- page = vmalloc_to_pfn((void *)pos);
- if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
- mutex_unlock(&meye.lock);
- return -EAGAIN;
- }
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- if (size > PAGE_SIZE)
- size -= PAGE_SIZE;
- else
- size = 0;
- }
-
- vma->vm_ops = &meye_vm_ops;
- vma->vm_flags &= ~VM_IO; /* not I/O memory */
- vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
- vma->vm_private_data = (void *) (offset / gbufsize);
- meye_vm_open(vma);
-
- mutex_unlock(&meye.lock);
- return 0;
-}
-
-static const struct v4l2_file_operations meye_fops = {
- .owner = THIS_MODULE,
- .open = meye_open,
- .release = meye_release,
- .mmap = meye_mmap,
- .unlocked_ioctl = video_ioctl2,
- .poll = meye_poll,
-};
-
-static const struct v4l2_ioctl_ops meye_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_default = vidioc_default,
-};
-
-static struct video_device meye_template = {
- .name = "meye",
- .fops = &meye_fops,
- .ioctl_ops = &meye_ioctl_ops,
- .release = video_device_release,
-};
-
-#ifdef CONFIG_PM
-static int meye_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- pci_save_state(pdev);
- meye.pm_mchip_mode = meye.mchip_mode;
- mchip_hic_stop();
- mchip_set(MCHIP_MM_INTA, 0x0);
- return 0;
-}
-
-static int meye_resume(struct pci_dev *pdev)
-{
- pci_restore_state(pdev);
- pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);
-
- mchip_delay(MCHIP_HIC_CMD, 0);
- mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
- msleep(1);
- mchip_set(MCHIP_VRJ_SOFT_RESET, 1);
- msleep(1);
- mchip_set(MCHIP_MM_PCI_MODE, 5);
- msleep(1);
- mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
-
- switch (meye.pm_mchip_mode) {
- case MCHIP_HIC_MODE_CONT_OUT:
- mchip_continuous_start();
- break;
- case MCHIP_HIC_MODE_CONT_COMP:
- mchip_cont_compression_start();
- break;
- }
- return 0;
-}
-#endif
-
-static int __devinit meye_probe(struct pci_dev *pcidev,
- const struct pci_device_id *ent)
-{
- struct v4l2_device *v4l2_dev = &meye.v4l2_dev;
- int ret = -EBUSY;
- unsigned long mchip_adr;
-
- if (meye.mchip_dev != NULL) {
- printk(KERN_ERR "meye: only one device allowed!\n");
- goto outnotdev;
- }
-
- ret = v4l2_device_register(&pcidev->dev, v4l2_dev);
- if (ret < 0) {
- v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
- return ret;
- }
- ret = -ENOMEM;
- meye.mchip_dev = pcidev;
- meye.vdev = video_device_alloc();
- if (!meye.vdev) {
- v4l2_err(v4l2_dev, "video_device_alloc() failed!\n");
- goto outnotdev;
- }
-
- meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE);
- if (!meye.grab_temp) {
- v4l2_err(v4l2_dev, "grab buffer allocation failed\n");
- goto outvmalloc;
- }
-
- spin_lock_init(&meye.grabq_lock);
- if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS,
- GFP_KERNEL)) {
- v4l2_err(v4l2_dev, "fifo allocation failed\n");
- goto outkfifoalloc1;
- }
- spin_lock_init(&meye.doneq_lock);
- if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS,
- GFP_KERNEL)) {
- v4l2_err(v4l2_dev, "fifo allocation failed\n");
- goto outkfifoalloc2;
- }
-
- memcpy(meye.vdev, &meye_template, sizeof(meye_template));
- meye.vdev->v4l2_dev = &meye.v4l2_dev;
-
- ret = -EIO;
- if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) {
- v4l2_err(v4l2_dev, "meye: unable to power on the camera\n");
- v4l2_err(v4l2_dev, "meye: did you enable the camera in "
- "sonypi using the module options ?\n");
- goto outsonypienable;
- }
-
- if ((ret = pci_enable_device(meye.mchip_dev))) {
- v4l2_err(v4l2_dev, "meye: pci_enable_device failed\n");
- goto outenabledev;
- }
-
- mchip_adr = pci_resource_start(meye.mchip_dev,0);
- if (!mchip_adr) {
- v4l2_err(v4l2_dev, "meye: mchip has no device base address\n");
- goto outregions;
- }
- if (!request_mem_region(pci_resource_start(meye.mchip_dev, 0),
- pci_resource_len(meye.mchip_dev, 0),
- "meye")) {
- v4l2_err(v4l2_dev, "meye: request_mem_region failed\n");
- goto outregions;
- }
- meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS);
- if (!meye.mchip_mmregs) {
- v4l2_err(v4l2_dev, "meye: ioremap failed\n");
- goto outremap;
- }
-
- meye.mchip_irq = pcidev->irq;
- if (request_irq(meye.mchip_irq, meye_irq,
- IRQF_DISABLED | IRQF_SHARED, "meye", meye_irq)) {
- v4l2_err(v4l2_dev, "request_irq failed\n");
- goto outreqirq;
- }
-
- pci_write_config_byte(meye.mchip_dev, PCI_CACHE_LINE_SIZE, 8);
- pci_write_config_byte(meye.mchip_dev, PCI_LATENCY_TIMER, 64);
-
- pci_set_master(meye.mchip_dev);
-
- /* Ask the camera to perform a soft reset. */
- pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);
-
- mchip_delay(MCHIP_HIC_CMD, 0);
- mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
-
- msleep(1);
- mchip_set(MCHIP_VRJ_SOFT_RESET, 1);
-
- msleep(1);
- mchip_set(MCHIP_MM_PCI_MODE, 5);
-
- msleep(1);
- mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
-
- mutex_init(&meye.lock);
- init_waitqueue_head(&meye.proc_list);
- meye.brightness = 32 << 10;
- meye.hue = 32 << 10;
- meye.colour = 32 << 10;
- meye.contrast = 32 << 10;
- meye.params.subsample = 0;
- meye.params.quality = 8;
- meye.params.sharpness = 32;
- meye.params.agc = 48;
- meye.params.picture = 0;
- meye.params.framerate = 0;
-
- sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERABRIGHTNESS, 32);
- sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAHUE, 32);
- sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERACOLOR, 32);
- sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERACONTRAST, 32);
- sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERASHARPNESS, 32);
- sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0);
- sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48);
-
- if (video_register_device(meye.vdev, VFL_TYPE_GRABBER,
- video_nr) < 0) {
- v4l2_err(v4l2_dev, "video_register_device failed\n");
- goto outvideoreg;
- }
-
- v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n",
- MEYE_DRIVER_VERSION);
- v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n",
- meye.mchip_dev->revision, mchip_adr, meye.mchip_irq);
-
- return 0;
-
-outvideoreg:
- free_irq(meye.mchip_irq, meye_irq);
-outreqirq:
- iounmap(meye.mchip_mmregs);
-outremap:
- release_mem_region(pci_resource_start(meye.mchip_dev, 0),
- pci_resource_len(meye.mchip_dev, 0));
-outregions:
- pci_disable_device(meye.mchip_dev);
-outenabledev:
- sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0);
-outsonypienable:
- kfifo_free(&meye.doneq);
-outkfifoalloc2:
- kfifo_free(&meye.grabq);
-outkfifoalloc1:
- vfree(meye.grab_temp);
-outvmalloc:
- video_device_release(meye.vdev);
-outnotdev:
- return ret;
-}
-
-static void __devexit meye_remove(struct pci_dev *pcidev)
-{
- video_unregister_device(meye.vdev);
-
- mchip_hic_stop();
-
- mchip_dma_free();
-
- /* disable interrupts */
- mchip_set(MCHIP_MM_INTA, 0x0);
-
- free_irq(meye.mchip_irq, meye_irq);
-
- iounmap(meye.mchip_mmregs);
-
- release_mem_region(pci_resource_start(meye.mchip_dev, 0),
- pci_resource_len(meye.mchip_dev, 0));
-
- pci_disable_device(meye.mchip_dev);
-
- sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0);
-
- kfifo_free(&meye.doneq);
- kfifo_free(&meye.grabq);
-
- vfree(meye.grab_temp);
-
- if (meye.grab_fbuffer) {
- rvfree(meye.grab_fbuffer, gbuffers*gbufsize);
- meye.grab_fbuffer = NULL;
- }
-
- printk(KERN_INFO "meye: removed\n");
-}
-
-static struct pci_device_id meye_pci_tbl[] = {
- { PCI_VDEVICE(KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002), 0 },
- { }
-};
-
-MODULE_DEVICE_TABLE(pci, meye_pci_tbl);
-
-static struct pci_driver meye_driver = {
- .name = "meye",
- .id_table = meye_pci_tbl,
- .probe = meye_probe,
- .remove = __devexit_p(meye_remove),
-#ifdef CONFIG_PM
- .suspend = meye_suspend,
- .resume = meye_resume,
-#endif
-};
-
-static int __init meye_init(void)
-{
- gbuffers = max(2, min((int)gbuffers, MEYE_MAX_BUFNBRS));
- if (gbufsize < 0 || gbufsize > MEYE_MAX_BUFSIZE)
- gbufsize = MEYE_MAX_BUFSIZE;
- gbufsize = PAGE_ALIGN(gbufsize);
- printk(KERN_INFO "meye: using %d buffers with %dk (%dk total) "
- "for capture\n",
- gbuffers,
- gbufsize / 1024, gbuffers * gbufsize / 1024);
- return pci_register_driver(&meye_driver);
-}
-
-static void __exit meye_exit(void)
-{
- pci_unregister_driver(&meye_driver);
-}
-
-module_init(meye_init);
-module_exit(meye_exit);
diff --git a/drivers/media/video/meye.h b/drivers/media/video/meye.h
deleted file mode 100644
index 4bdeb03f164..00000000000
--- a/drivers/media/video/meye.h
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Motion Eye video4linux driver for Sony Vaio PictureBook
- *
- * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
- *
- * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
- *
- * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
- *
- * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
- *
- * Some parts borrowed from various video4linux drivers, especially
- * bttv-driver.c and zoran.c, see original files for credits.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _MEYE_PRIV_H_
-#define _MEYE_PRIV_H_
-
-#define MEYE_DRIVER_MAJORVERSION 1
-#define MEYE_DRIVER_MINORVERSION 14
-
-#define MEYE_DRIVER_VERSION __stringify(MEYE_DRIVER_MAJORVERSION) "." \
- __stringify(MEYE_DRIVER_MINORVERSION)
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kfifo.h>
-
-/****************************************************************************/
-/* Motion JPEG chip registers */
-/****************************************************************************/
-
-/* Motion JPEG chip PCI configuration registers */
-#define MCHIP_PCI_POWER_CSR 0x54
-#define MCHIP_PCI_MCORE_STATUS 0x60 /* see HIC_STATUS */
-#define MCHIP_PCI_HOSTUSEREQ_SET 0x64
-#define MCHIP_PCI_HOSTUSEREQ_CLR 0x68
-#define MCHIP_PCI_LOWPOWER_SET 0x6c
-#define MCHIP_PCI_LOWPOWER_CLR 0x70
-#define MCHIP_PCI_SOFTRESET_SET 0x74
-
-/* Motion JPEG chip memory mapped registers */
-#define MCHIP_MM_REGS 0x200 /* 512 bytes */
-#define MCHIP_REG_TIMEOUT 1000 /* reg access, ~us */
-#define MCHIP_MCC_VRJ_TIMEOUT 1000 /* MCC & VRJ access */
-
-#define MCHIP_MM_PCI_MODE 0x00 /* PCI access mode */
-#define MCHIP_MM_PCI_MODE_RETRY 0x00000001 /* retry mode */
-#define MCHIP_MM_PCI_MODE_MASTER 0x00000002 /* master access */
-#define MCHIP_MM_PCI_MODE_READ_LINE 0x00000004 /* read line */
-
-#define MCHIP_MM_INTA 0x04 /* Int status/mask */
-#define MCHIP_MM_INTA_MCC 0x00000001 /* MCC interrupt */
-#define MCHIP_MM_INTA_VRJ 0x00000002 /* VRJ interrupt */
-#define MCHIP_MM_INTA_HIC_1 0x00000004 /* one frame done */
-#define MCHIP_MM_INTA_HIC_1_MASK 0x00000400 /* 1: enable */
-#define MCHIP_MM_INTA_HIC_END 0x00000008 /* all frames done */
-#define MCHIP_MM_INTA_HIC_END_MASK 0x00000800
-#define MCHIP_MM_INTA_JPEG 0x00000010 /* decompress. error */
-#define MCHIP_MM_INTA_JPEG_MASK 0x00001000
-#define MCHIP_MM_INTA_CAPTURE 0x00000020 /* capture end */
-#define MCHIP_MM_INTA_PCI_ERR 0x00000040 /* PCI error */
-#define MCHIP_MM_INTA_PCI_ERR_MASK 0x00004000
-
-#define MCHIP_MM_PT_ADDR 0x08 /* page table address*/
- /* n*4kB */
-#define MCHIP_NB_PAGES 1024 /* pages for display */
-#define MCHIP_NB_PAGES_MJPEG 256 /* pages for mjpeg */
-
-#define MCHIP_MM_FIR(n) (0x0c+(n)*4) /* Frame info 0-3 */
-#define MCHIP_MM_FIR_RDY 0x00000001 /* frame ready */
-#define MCHIP_MM_FIR_FAILFR_MASK 0xf8000000 /* # of failed frames */
-#define MCHIP_MM_FIR_FAILFR_SHIFT 27
-
- /* continuous comp/decomp mode */
-#define MCHIP_MM_FIR_C_ENDL_MASK 0x000007fe /* end DW [10] */
-#define MCHIP_MM_FIR_C_ENDL_SHIFT 1
-#define MCHIP_MM_FIR_C_ENDP_MASK 0x0007f800 /* end page [8] */
-#define MCHIP_MM_FIR_C_ENDP_SHIFT 11
-#define MCHIP_MM_FIR_C_STARTP_MASK 0x07f80000 /* start page [8] */
-#define MCHIP_MM_FIR_C_STARTP_SHIFT 19
-
- /* continuous picture output mode */
-#define MCHIP_MM_FIR_O_STARTP_MASK 0x7ffe0000 /* start page [10] */
-#define MCHIP_MM_FIR_O_STARTP_SHIFT 17
-
-#define MCHIP_MM_FIFO_DATA 0x1c /* PCI TGT FIFO data */
-#define MCHIP_MM_FIFO_STATUS 0x20 /* PCI TGT FIFO stat */
-#define MCHIP_MM_FIFO_MASK 0x00000003
-#define MCHIP_MM_FIFO_WAIT_OR_READY 0x00000002 /* Bits common to WAIT & READY*/
-#define MCHIP_MM_FIFO_IDLE 0x0 /* HIC idle */
-#define MCHIP_MM_FIFO_IDLE1 0x1 /* idem ??? */
-#define MCHIP_MM_FIFO_WAIT 0x2 /* wait request */
-#define MCHIP_MM_FIFO_READY 0x3 /* data ready */
-
-#define MCHIP_HIC_HOST_USEREQ 0x40 /* host uses MCORE */
-
-#define MCHIP_HIC_TP_BUSY 0x44 /* taking picture */
-
-#define MCHIP_HIC_PIC_SAVED 0x48 /* pic in SDRAM */
-
-#define MCHIP_HIC_LOWPOWER 0x4c /* clock stopped */
-
-#define MCHIP_HIC_CTL 0x50 /* HIC control */
-#define MCHIP_HIC_CTL_SOFT_RESET 0x00000001 /* MCORE reset */
-#define MCHIP_HIC_CTL_MCORE_RDY 0x00000002 /* MCORE ready */
-
-#define MCHIP_HIC_CMD 0x54 /* HIC command */
-#define MCHIP_HIC_CMD_BITS 0x00000003 /* cmd width=[1:0]*/
-#define MCHIP_HIC_CMD_NOOP 0x0
-#define MCHIP_HIC_CMD_START 0x1
-#define MCHIP_HIC_CMD_STOP 0x2
-
-#define MCHIP_HIC_MODE 0x58
-#define MCHIP_HIC_MODE_NOOP 0x0
-#define MCHIP_HIC_MODE_STILL_CAP 0x1 /* still pic capt */
-#define MCHIP_HIC_MODE_DISPLAY 0x2 /* display */
-#define MCHIP_HIC_MODE_STILL_COMP 0x3 /* still pic comp. */
-#define MCHIP_HIC_MODE_STILL_DECOMP 0x4 /* still pic decomp. */
-#define MCHIP_HIC_MODE_CONT_COMP 0x5 /* cont capt+comp */
-#define MCHIP_HIC_MODE_CONT_DECOMP 0x6 /* cont decomp+disp */
-#define MCHIP_HIC_MODE_STILL_OUT 0x7 /* still pic output */
-#define MCHIP_HIC_MODE_CONT_OUT 0x8 /* cont output */
-
-#define MCHIP_HIC_STATUS 0x5c
-#define MCHIP_HIC_STATUS_MCC_RDY 0x00000001 /* MCC reg acc ok */
-#define MCHIP_HIC_STATUS_VRJ_RDY 0x00000002 /* VRJ reg acc ok */
-#define MCHIP_HIC_STATUS_IDLE 0x00000003
-#define MCHIP_HIC_STATUS_CAPDIS 0x00000004 /* cap/disp in prog */
-#define MCHIP_HIC_STATUS_COMPDEC 0x00000008 /* (de)comp in prog */
-#define MCHIP_HIC_STATUS_BUSY 0x00000010 /* HIC busy */
-
-#define MCHIP_HIC_S_RATE 0x60 /* MJPEG # frames */
-
-#define MCHIP_HIC_PCI_VFMT 0x64 /* video format */
-#define MCHIP_HIC_PCI_VFMT_YVYU 0x00000001 /* 0: V Y' U Y */
- /* 1: Y' V Y U */
-
-#define MCHIP_MCC_CMD 0x80 /* MCC commands */
-#define MCHIP_MCC_CMD_INITIAL 0x0 /* idle ? */
-#define MCHIP_MCC_CMD_IIC_START_SET 0x1
-#define MCHIP_MCC_CMD_IIC_END_SET 0x2
-#define MCHIP_MCC_CMD_FM_WRITE 0x3 /* frame memory */
-#define MCHIP_MCC_CMD_FM_READ 0x4
-#define MCHIP_MCC_CMD_FM_STOP 0x5
-#define MCHIP_MCC_CMD_CAPTURE 0x6
-#define MCHIP_MCC_CMD_DISPLAY 0x7
-#define MCHIP_MCC_CMD_END_DISP 0x8
-#define MCHIP_MCC_CMD_STILL_COMP 0x9
-#define MCHIP_MCC_CMD_STILL_DECOMP 0xa
-#define MCHIP_MCC_CMD_STILL_OUTPUT 0xb
-#define MCHIP_MCC_CMD_CONT_OUTPUT 0xc
-#define MCHIP_MCC_CMD_CONT_COMP 0xd
-#define MCHIP_MCC_CMD_CONT_DECOMP 0xe
-#define MCHIP_MCC_CMD_RESET 0xf /* MCC reset */
-
-#define MCHIP_MCC_IIC_WR 0x84
-
-#define MCHIP_MCC_MCC_WR 0x88
-
-#define MCHIP_MCC_MCC_RD 0x8c
-
-#define MCHIP_MCC_STATUS 0x90
-#define MCHIP_MCC_STATUS_CAPT 0x00000001 /* capturing */
-#define MCHIP_MCC_STATUS_DISP 0x00000002 /* displaying */
-#define MCHIP_MCC_STATUS_COMP 0x00000004 /* compressing */
-#define MCHIP_MCC_STATUS_DECOMP 0x00000008 /* decompressing */
-#define MCHIP_MCC_STATUS_MCC_WR 0x00000010 /* register ready */
-#define MCHIP_MCC_STATUS_MCC_RD 0x00000020 /* register ready */
-#define MCHIP_MCC_STATUS_IIC_WR 0x00000040 /* register ready */
-#define MCHIP_MCC_STATUS_OUTPUT 0x00000080 /* output in prog */
-
-#define MCHIP_MCC_SIG_POLARITY 0x94
-#define MCHIP_MCC_SIG_POL_VS_H 0x00000001 /* VS active-high */
-#define MCHIP_MCC_SIG_POL_HS_H 0x00000002 /* HS active-high */
-#define MCHIP_MCC_SIG_POL_DOE_H 0x00000004 /* DOE active-high */
-
-#define MCHIP_MCC_IRQ 0x98
-#define MCHIP_MCC_IRQ_CAPDIS_STRT 0x00000001 /* cap/disp started */
-#define MCHIP_MCC_IRQ_CAPDIS_STRT_MASK 0x00000010
-#define MCHIP_MCC_IRQ_CAPDIS_END 0x00000002 /* cap/disp ended */
-#define MCHIP_MCC_IRQ_CAPDIS_END_MASK 0x00000020
-#define MCHIP_MCC_IRQ_COMPDEC_STRT 0x00000004 /* (de)comp started */
-#define MCHIP_MCC_IRQ_COMPDEC_STRT_MASK 0x00000040
-#define MCHIP_MCC_IRQ_COMPDEC_END 0x00000008 /* (de)comp ended */
-#define MCHIP_MCC_IRQ_COMPDEC_END_MASK 0x00000080
-
-#define MCHIP_MCC_HSTART 0x9c /* video in */
-#define MCHIP_MCC_VSTART 0xa0
-#define MCHIP_MCC_HCOUNT 0xa4
-#define MCHIP_MCC_VCOUNT 0xa8
-#define MCHIP_MCC_R_XBASE 0xac /* capt/disp */
-#define MCHIP_MCC_R_YBASE 0xb0
-#define MCHIP_MCC_R_XRANGE 0xb4
-#define MCHIP_MCC_R_YRANGE 0xb8
-#define MCHIP_MCC_B_XBASE 0xbc /* comp/decomp */
-#define MCHIP_MCC_B_YBASE 0xc0
-#define MCHIP_MCC_B_XRANGE 0xc4
-#define MCHIP_MCC_B_YRANGE 0xc8
-
-#define MCHIP_MCC_R_SAMPLING 0xcc /* 1: 1:4 */
-
-#define MCHIP_VRJ_CMD 0x100 /* VRJ commands */
-
-/* VRJ registers (see table 12.2.4) */
-#define MCHIP_VRJ_COMPRESSED_DATA 0x1b0
-#define MCHIP_VRJ_PIXEL_DATA 0x1b8
-
-#define MCHIP_VRJ_BUS_MODE 0x100
-#define MCHIP_VRJ_SIGNAL_ACTIVE_LEVEL 0x108
-#define MCHIP_VRJ_PDAT_USE 0x110
-#define MCHIP_VRJ_MODE_SPECIFY 0x118
-#define MCHIP_VRJ_LIMIT_COMPRESSED_LO 0x120
-#define MCHIP_VRJ_LIMIT_COMPRESSED_HI 0x124
-#define MCHIP_VRJ_COMP_DATA_FORMAT 0x128
-#define MCHIP_VRJ_TABLE_DATA 0x140
-#define MCHIP_VRJ_RESTART_INTERVAL 0x148
-#define MCHIP_VRJ_NUM_LINES 0x150
-#define MCHIP_VRJ_NUM_PIXELS 0x158
-#define MCHIP_VRJ_NUM_COMPONENTS 0x160
-#define MCHIP_VRJ_SOF1 0x168
-#define MCHIP_VRJ_SOF2 0x170
-#define MCHIP_VRJ_SOF3 0x178
-#define MCHIP_VRJ_SOF4 0x180
-#define MCHIP_VRJ_SOS 0x188
-#define MCHIP_VRJ_SOFT_RESET 0x190
-
-#define MCHIP_VRJ_STATUS 0x1c0
-#define MCHIP_VRJ_STATUS_BUSY 0x00001
-#define MCHIP_VRJ_STATUS_COMP_ACCESS 0x00002
-#define MCHIP_VRJ_STATUS_PIXEL_ACCESS 0x00004
-#define MCHIP_VRJ_STATUS_ERROR 0x00008
-
-#define MCHIP_VRJ_IRQ_FLAG 0x1c8
-#define MCHIP_VRJ_ERROR_REPORT 0x1d8
-
-#define MCHIP_VRJ_START_COMMAND 0x1a0
-
-/****************************************************************************/
-/* Driver definitions. */
-/****************************************************************************/
-
-/* Sony Programmable I/O Controller for accessing the camera commands */
-#include <linux/sony-laptop.h>
-
-/* private API definitions */
-#include <linux/meye.h>
-#include <linux/mutex.h>
-
-
-/* Enable jpg software correction */
-#define MEYE_JPEG_CORRECTION 1
-
-/* Maximum size of a buffer */
-#define MEYE_MAX_BUFSIZE 614400 /* 640 * 480 * 2 */
-
-/* Maximum number of buffers */
-#define MEYE_MAX_BUFNBRS 32
-
-/* State of a buffer */
-#define MEYE_BUF_UNUSED 0 /* not used */
-#define MEYE_BUF_USING 1 /* currently grabbing / playing */
-#define MEYE_BUF_DONE 2 /* done */
-
-/* grab buffer */
-struct meye_grab_buffer {
- int state; /* state of buffer */
- unsigned long size; /* size of jpg frame */
- struct timeval timestamp; /* timestamp */
- unsigned long sequence; /* sequence number */
-};
-
-/* size of kfifos containings buffer indices */
-#define MEYE_QUEUE_SIZE MEYE_MAX_BUFNBRS
-
-/* Motion Eye device structure */
-struct meye {
- struct v4l2_device v4l2_dev; /* Main v4l2_device struct */
- struct pci_dev *mchip_dev; /* pci device */
- u8 mchip_irq; /* irq */
- u8 mchip_mode; /* actual mchip mode: HIC_MODE... */
- u8 mchip_fnum; /* current mchip frame number */
- unsigned char __iomem *mchip_mmregs;/* mchip: memory mapped registers */
- u8 *mchip_ptable[MCHIP_NB_PAGES];/* mchip: ptable */
- void *mchip_ptable_toc; /* mchip: ptable toc */
- dma_addr_t mchip_dmahandle; /* mchip: dma handle to ptable toc */
- unsigned char *grab_fbuffer; /* capture framebuffer */
- unsigned char *grab_temp; /* temporary buffer */
- /* list of buffers */
- struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS];
- int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */
- struct mutex lock; /* mutex for open/mmap... */
- struct kfifo grabq; /* queue for buffers to be grabbed */
- spinlock_t grabq_lock; /* lock protecting the queue */
- struct kfifo doneq; /* queue for grabbed buffers */
- spinlock_t doneq_lock; /* lock protecting the queue */
- wait_queue_head_t proc_list; /* wait queue */
- struct video_device *vdev; /* video device parameters */
- u16 brightness;
- u16 hue;
- u16 contrast;
- u16 colour;
- struct meye_params params; /* additional parameters */
- unsigned long in_use; /* set to 1 if the device is in use */
-#ifdef CONFIG_PM
- u8 pm_mchip_mode; /* old mchip mode */
-#endif
-};
-
-#endif
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
deleted file mode 100644
index aeb22be7dcb..00000000000
--- a/drivers/media/video/msp3400-driver.c
+++ /dev/null
@@ -1,899 +0,0 @@
-/*
- * Programming the mspx4xx sound processor family
- *
- * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
- *
- * what works and what doesn't:
- *
- * AM-Mono
- * Support for Hauppauge cards added (decoding handled by tuner) added by
- * Frederic Crozat <fcrozat@mail.dotcom.fr>
- *
- * FM-Mono
- * should work. The stereo modes are backward compatible to FM-mono,
- * therefore FM-Mono should be allways available.
- *
- * FM-Stereo (B/G, used in germany)
- * should work, with autodetect
- *
- * FM-Stereo (satellite)
- * should work, no autodetect (i.e. default is mono, but you can
- * switch to stereo -- untested)
- *
- * NICAM (B/G, L , used in UK, Scandinavia, Spain and France)
- * should work, with autodetect. Support for NICAM was added by
- * Pekka Pietikainen <pp@netppl.fi>
- *
- * TODO:
- * - better SAT support
- *
- * 980623 Thomas Sailer (sailer@ife.ee.ethz.ch)
- * using soundcore instead of OSS
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/msp3400.h>
-#include <media/tvaudio.h>
-#include "msp3400-driver.h"
-
-/* ---------------------------------------------------------------------- */
-
-MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
-MODULE_AUTHOR("Gerd Knorr");
-MODULE_LICENSE("GPL");
-
-/* module parameters */
-static int opmode = OPMODE_AUTO;
-int msp_debug; /* msp_debug output */
-bool msp_once; /* no continuous stereo monitoring */
-bool msp_amsound; /* hard-wire AM sound at 6.5 Hz (france),
- the autoscan seems work well only with FM... */
-int msp_standard = 1; /* Override auto detect of audio msp_standard,
- if needed. */
-bool msp_dolby;
-
-int msp_stereo_thresh = 0x190; /* a2 threshold for stereo/bilingual
- (msp34xxg only) 0x00a0-0x03c0 */
-
-/* read-only */
-module_param(opmode, int, 0444);
-
-/* read-write */
-module_param_named(once, msp_once, bool, 0644);
-module_param_named(debug, msp_debug, int, 0644);
-module_param_named(stereo_threshold, msp_stereo_thresh, int, 0644);
-module_param_named(standard, msp_standard, int, 0644);
-module_param_named(amsound, msp_amsound, bool, 0644);
-module_param_named(dolby, msp_dolby, bool, 0644);
-
-MODULE_PARM_DESC(opmode, "Forces a MSP3400 opmode. 0=Manual, 1=Autodetect, 2=Autodetect and autoselect");
-MODULE_PARM_DESC(once, "No continuous stereo monitoring");
-MODULE_PARM_DESC(debug, "Enable debug messages [0-3]");
-MODULE_PARM_DESC(stereo_threshold, "Sets signal threshold to activate stereo");
-MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect");
-MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
-MODULE_PARM_DESC(dolby, "Activates Dolby processing");
-
-/* ---------------------------------------------------------------------- */
-
-/* control subaddress */
-#define I2C_MSP_CONTROL 0x00
-/* demodulator unit subaddress */
-#define I2C_MSP_DEM 0x10
-/* DSP unit subaddress */
-#define I2C_MSP_DSP 0x12
-
-
-/* ----------------------------------------------------------------------- */
-/* functions for talking to the MSP3400C Sound processor */
-
-int msp_reset(struct i2c_client *client)
-{
- /* reset and read revision code */
- static u8 reset_off[3] = { I2C_MSP_CONTROL, 0x80, 0x00 };
- static u8 reset_on[3] = { I2C_MSP_CONTROL, 0x00, 0x00 };
- static u8 write[3] = { I2C_MSP_DSP + 1, 0x00, 0x1e };
- u8 read[2];
- struct i2c_msg reset[2] = {
- { client->addr, I2C_M_IGNORE_NAK, 3, reset_off },
- { client->addr, I2C_M_IGNORE_NAK, 3, reset_on },
- };
- struct i2c_msg test[2] = {
- { client->addr, 0, 3, write },
- { client->addr, I2C_M_RD, 2, read },
- };
-
- v4l_dbg(3, msp_debug, client, "msp_reset\n");
- if (i2c_transfer(client->adapter, &reset[0], 1) != 1 ||
- i2c_transfer(client->adapter, &reset[1], 1) != 1 ||
- i2c_transfer(client->adapter, test, 2) != 2) {
- v4l_err(client, "chip reset failed\n");
- return -1;
- }
- return 0;
-}
-
-static int msp_read(struct i2c_client *client, int dev, int addr)
-{
- int err, retval;
- u8 write[3];
- u8 read[2];
- struct i2c_msg msgs[2] = {
- { client->addr, 0, 3, write },
- { client->addr, I2C_M_RD, 2, read }
- };
-
- write[0] = dev + 1;
- write[1] = addr >> 8;
- write[2] = addr & 0xff;
-
- for (err = 0; err < 3; err++) {
- if (i2c_transfer(client->adapter, msgs, 2) == 2)
- break;
- v4l_warn(client, "I/O error #%d (read 0x%02x/0x%02x)\n", err,
- dev, addr);
- schedule_timeout_interruptible(msecs_to_jiffies(10));
- }
- if (err == 3) {
- v4l_warn(client, "resetting chip, sound will go off.\n");
- msp_reset(client);
- return -1;
- }
- retval = read[0] << 8 | read[1];
- v4l_dbg(3, msp_debug, client, "msp_read(0x%x, 0x%x): 0x%x\n",
- dev, addr, retval);
- return retval;
-}
-
-int msp_read_dem(struct i2c_client *client, int addr)
-{
- return msp_read(client, I2C_MSP_DEM, addr);
-}
-
-int msp_read_dsp(struct i2c_client *client, int addr)
-{
- return msp_read(client, I2C_MSP_DSP, addr);
-}
-
-static int msp_write(struct i2c_client *client, int dev, int addr, int val)
-{
- int err;
- u8 buffer[5];
-
- buffer[0] = dev;
- buffer[1] = addr >> 8;
- buffer[2] = addr & 0xff;
- buffer[3] = val >> 8;
- buffer[4] = val & 0xff;
-
- v4l_dbg(3, msp_debug, client, "msp_write(0x%x, 0x%x, 0x%x)\n",
- dev, addr, val);
- for (err = 0; err < 3; err++) {
- if (i2c_master_send(client, buffer, 5) == 5)
- break;
- v4l_warn(client, "I/O error #%d (write 0x%02x/0x%02x)\n", err,
- dev, addr);
- schedule_timeout_interruptible(msecs_to_jiffies(10));
- }
- if (err == 3) {
- v4l_warn(client, "resetting chip, sound will go off.\n");
- msp_reset(client);
- return -1;
- }
- return 0;
-}
-
-int msp_write_dem(struct i2c_client *client, int addr, int val)
-{
- return msp_write(client, I2C_MSP_DEM, addr, val);
-}
-
-int msp_write_dsp(struct i2c_client *client, int addr, int val)
-{
- return msp_write(client, I2C_MSP_DSP, addr, val);
-}
-
-/* ----------------------------------------------------------------------- *
- * bits 9 8 5 - SCART DSP input Select:
- * 0 0 0 - SCART 1 to DSP input (reset position)
- * 0 1 0 - MONO to DSP input
- * 1 0 0 - SCART 2 to DSP input
- * 1 1 1 - Mute DSP input
- *
- * bits 11 10 6 - SCART 1 Output Select:
- * 0 0 0 - undefined (reset position)
- * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS)
- * 1 0 0 - MONO input to SCART 1 Output
- * 1 1 0 - SCART 1 DA to SCART 1 Output
- * 0 0 1 - SCART 2 DA to SCART 1 Output
- * 0 1 1 - SCART 1 Input to SCART 1 Output
- * 1 1 1 - Mute SCART 1 Output
- *
- * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART):
- * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position)
- * 0 1 0 - SCART 1 Input to SCART 2 Output
- * 1 0 0 - MONO input to SCART 2 Output
- * 0 0 1 - SCART 2 DA to SCART 2 Output
- * 0 1 1 - SCART 2 Input to SCART 2 Output
- * 1 1 0 - Mute SCART 2 Output
- *
- * Bits 4 to 0 should be zero.
- * ----------------------------------------------------------------------- */
-
-static int scarts[3][9] = {
- /* MASK IN1 IN2 IN3 IN4 IN1_DA IN2_DA MONO MUTE */
- /* SCART DSP Input select */
- { 0x0320, 0x0000, 0x0200, 0x0300, 0x0020, -1, -1, 0x0100, 0x0320 },
- /* SCART1 Output select */
- { 0x0c40, 0x0440, 0x0400, 0x0000, 0x0840, 0x0c00, 0x0040, 0x0800, 0x0c40 },
- /* SCART2 Output select */
- { 0x3080, 0x1000, 0x1080, 0x2080, 0x3080, 0x0000, 0x0080, 0x2000, 0x3000 },
-};
-
-static char *scart_names[] = {
- "in1", "in2", "in3", "in4", "in1 da", "in2 da", "mono", "mute"
-};
-
-void msp_set_scart(struct i2c_client *client, int in, int out)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
-
- state->in_scart = in;
-
- if (in >= 0 && in <= 7 && out >= 0 && out <= 2) {
- if (-1 == scarts[out][in + 1])
- return;
-
- state->acb &= ~scarts[out][0];
- state->acb |= scarts[out][in + 1];
- } else
- state->acb = 0xf60; /* Mute Input and SCART 1 Output */
-
- v4l_dbg(1, msp_debug, client, "scart switch: %s => %d (ACB=0x%04x)\n",
- scart_names[in], out, state->acb);
- msp_write_dsp(client, 0x13, state->acb);
-
- /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
- if (state->has_i2s_conf)
- msp_write_dem(client, 0x40, state->i2s_mode);
-}
-
-/* ------------------------------------------------------------------------ */
-
-static void msp_wake_thread(struct i2c_client *client)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
-
- if (NULL == state->kthread)
- return;
- state->watch_stereo = 0;
- state->restart = 1;
- wake_up_interruptible(&state->wq);
-}
-
-int msp_sleep(struct msp_state *state, int timeout)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(&state->wq, &wait);
- if (!kthread_should_stop()) {
- if (timeout < 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- } else {
- schedule_timeout_interruptible
- (msecs_to_jiffies(timeout));
- }
- }
-
- remove_wait_queue(&state->wq, &wait);
- try_to_freeze();
- return state->restart;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int msp_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct msp_state *state = ctrl_to_state(ctrl);
- struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
- int val = ctrl->val;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME: {
- /* audio volume cluster */
- int reallymuted = state->muted->val | state->scan_in_progress;
-
- if (!reallymuted)
- val = (val * 0x7f / 65535) << 8;
-
- v4l_dbg(1, msp_debug, client, "mute=%s scanning=%s volume=%d\n",
- state->muted->val ? "on" : "off",
- state->scan_in_progress ? "yes" : "no",
- state->volume->val);
-
- msp_write_dsp(client, 0x0000, val);
- msp_write_dsp(client, 0x0007, reallymuted ? 0x1 : (val | 0x1));
- if (state->has_scart2_out_volume)
- msp_write_dsp(client, 0x0040, reallymuted ? 0x1 : (val | 0x1));
- if (state->has_headphones)
- msp_write_dsp(client, 0x0006, val);
- break;
- }
-
- case V4L2_CID_AUDIO_BASS:
- val = ((val - 32768) * 0x60 / 65535) << 8;
- msp_write_dsp(client, 0x0002, val);
- if (state->has_headphones)
- msp_write_dsp(client, 0x0031, val);
- break;
-
- case V4L2_CID_AUDIO_TREBLE:
- val = ((val - 32768) * 0x60 / 65535) << 8;
- msp_write_dsp(client, 0x0003, val);
- if (state->has_headphones)
- msp_write_dsp(client, 0x0032, val);
- break;
-
- case V4L2_CID_AUDIO_LOUDNESS:
- val = val ? ((5 * 4) << 8) : 0;
- msp_write_dsp(client, 0x0004, val);
- if (state->has_headphones)
- msp_write_dsp(client, 0x0033, val);
- break;
-
- case V4L2_CID_AUDIO_BALANCE:
- val = (u8)((val / 256) - 128);
- msp_write_dsp(client, 0x0001, val << 8);
- if (state->has_headphones)
- msp_write_dsp(client, 0x0030, val << 8);
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-void msp_update_volume(struct msp_state *state)
-{
- /* Force an update of the volume/mute cluster */
- v4l2_ctrl_lock(state->volume);
- state->volume->val = state->volume->cur.val;
- state->muted->val = state->muted->cur.val;
- msp_s_ctrl(state->volume);
- v4l2_ctrl_unlock(state->volume);
-}
-
-/* --- v4l2 ioctls --- */
-static int msp_s_radio(struct v4l2_subdev *sd)
-{
- struct msp_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (state->radio)
- return 0;
- state->radio = 1;
- v4l_dbg(1, msp_debug, client, "switching to radio mode\n");
- state->watch_stereo = 0;
- switch (state->opmode) {
- case OPMODE_MANUAL:
- /* set msp3400 to FM radio mode */
- msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
- msp3400c_set_carrier(client, MSP_CARRIER(10.7),
- MSP_CARRIER(10.7));
- msp_update_volume(state);
- break;
- case OPMODE_AUTODETECT:
- case OPMODE_AUTOSELECT:
- /* the thread will do for us */
- msp_wake_thread(client);
- break;
- }
- return 0;
-}
-
-static int msp_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- /* new channel -- kick audio carrier scan */
- msp_wake_thread(client);
- return 0;
-}
-
-static int msp_querystd(struct v4l2_subdev *sd, v4l2_std_id *id)
-{
- struct msp_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- *id &= state->detected_std;
-
- v4l_dbg(2, msp_debug, client,
- "detected standard: %s(0x%08Lx)\n",
- msp_standard_std_name(state->std), state->detected_std);
-
- return 0;
-}
-
-static int msp_s_std(struct v4l2_subdev *sd, v4l2_std_id id)
-{
- struct msp_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int update = state->radio || state->v4l2_std != id;
-
- state->v4l2_std = id;
- state->radio = 0;
- if (update)
- msp_wake_thread(client);
- return 0;
-}
-
-static int msp_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct msp_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int tuner = (input >> 3) & 1;
- int sc_in = input & 0x7;
- int sc1_out = output & 0xf;
- int sc2_out = (output >> 4) & 0xf;
- u16 val, reg;
- int i;
- int extern_input = 1;
-
- if (state->route_in == input && state->route_out == output)
- return 0;
- state->route_in = input;
- state->route_out = output;
- /* check if the tuner input is used */
- for (i = 0; i < 5; i++) {
- if (((input >> (4 + i * 4)) & 0xf) == 0)
- extern_input = 0;
- }
- state->mode = extern_input ? MSP_MODE_EXTERN : MSP_MODE_AM_DETECT;
- state->rxsubchans = V4L2_TUNER_SUB_STEREO;
- msp_set_scart(client, sc_in, 0);
- msp_set_scart(client, sc1_out, 1);
- msp_set_scart(client, sc2_out, 2);
- msp_set_audmode(client);
- reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb;
- val = msp_read_dem(client, reg);
- msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8));
- /* wake thread when a new input is chosen */
- msp_wake_thread(client);
- return 0;
-}
-
-static int msp_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct msp_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (vt->type != V4L2_TUNER_ANALOG_TV)
- return 0;
- if (!state->radio) {
- if (state->opmode == OPMODE_AUTOSELECT)
- msp_detect_stereo(client);
- vt->rxsubchans = state->rxsubchans;
- }
- vt->audmode = state->audmode;
- vt->capability |= V4L2_TUNER_CAP_STEREO |
- V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
- return 0;
-}
-
-static int msp_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct msp_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (state->radio) /* TODO: add mono/stereo support for radio */
- return 0;
- if (state->audmode == vt->audmode)
- return 0;
- state->audmode = vt->audmode;
- /* only set audmode */
- msp_set_audmode(client);
- return 0;
-}
-
-static int msp_s_i2s_clock_freq(struct v4l2_subdev *sd, u32 freq)
-{
- struct msp_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- v4l_dbg(1, msp_debug, client, "Setting I2S speed to %d\n", freq);
-
- switch (freq) {
- case 1024000:
- state->i2s_mode = 0;
- break;
- case 2048000:
- state->i2s_mode = 1;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int msp_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct msp_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, state->ident,
- (state->rev1 << 16) | state->rev2);
-}
-
-static int msp_log_status(struct v4l2_subdev *sd)
-{
- struct msp_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- const char *p;
- char prefix[V4L2_SUBDEV_NAME_SIZE + 20];
-
- if (state->opmode == OPMODE_AUTOSELECT)
- msp_detect_stereo(client);
- v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n",
- client->name, state->rev1, state->rev2);
- snprintf(prefix, sizeof(prefix), "%s: Audio: ", sd->name);
- v4l2_ctrl_handler_log_status(&state->hdl, prefix);
- switch (state->mode) {
- case MSP_MODE_AM_DETECT: p = "AM (for carrier detect)"; break;
- case MSP_MODE_FM_RADIO: p = "FM Radio"; break;
- case MSP_MODE_FM_TERRA: p = "Terrestrial FM-mono/stereo"; break;
- case MSP_MODE_FM_SAT: p = "Satellite FM-mono"; break;
- case MSP_MODE_FM_NICAM1: p = "NICAM/FM (B/G, D/K)"; break;
- case MSP_MODE_FM_NICAM2: p = "NICAM/FM (I)"; break;
- case MSP_MODE_AM_NICAM: p = "NICAM/AM (L)"; break;
- case MSP_MODE_BTSC: p = "BTSC"; break;
- case MSP_MODE_EXTERN: p = "External input"; break;
- default: p = "unknown"; break;
- }
- if (state->mode == MSP_MODE_EXTERN) {
- v4l_info(client, "Mode: %s\n", p);
- } else if (state->opmode == OPMODE_MANUAL) {
- v4l_info(client, "Mode: %s (%s%s)\n", p,
- (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
- (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
- } else {
- if (state->opmode == OPMODE_AUTODETECT)
- v4l_info(client, "Mode: %s\n", p);
- v4l_info(client, "Standard: %s (%s%s)\n",
- msp_standard_std_name(state->std),
- (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
- (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
- }
- v4l_info(client, "Audmode: 0x%04x\n", state->audmode);
- v4l_info(client, "Routing: 0x%08x (input) 0x%08x (output)\n",
- state->route_in, state->route_out);
- v4l_info(client, "ACB: 0x%04x\n", state->acb);
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int msp_suspend(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- v4l_dbg(1, msp_debug, client, "suspend\n");
- msp_reset(client);
- return 0;
-}
-
-static int msp_resume(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- v4l_dbg(1, msp_debug, client, "resume\n");
- msp_wake_thread(client);
- return 0;
-}
-#endif
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_ctrl_ops msp_ctrl_ops = {
- .s_ctrl = msp_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops msp_core_ops = {
- .log_status = msp_log_status,
- .g_chip_ident = msp_g_chip_ident,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
- .s_std = msp_s_std,
-};
-
-static const struct v4l2_subdev_video_ops msp_video_ops = {
- .querystd = msp_querystd,
-};
-
-static const struct v4l2_subdev_tuner_ops msp_tuner_ops = {
- .s_frequency = msp_s_frequency,
- .g_tuner = msp_g_tuner,
- .s_tuner = msp_s_tuner,
- .s_radio = msp_s_radio,
-};
-
-static const struct v4l2_subdev_audio_ops msp_audio_ops = {
- .s_routing = msp_s_routing,
- .s_i2s_clock_freq = msp_s_i2s_clock_freq,
-};
-
-static const struct v4l2_subdev_ops msp_ops = {
- .core = &msp_core_ops,
- .video = &msp_video_ops,
- .tuner = &msp_tuner_ops,
- .audio = &msp_audio_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
- struct msp_state *state;
- struct v4l2_subdev *sd;
- struct v4l2_ctrl_handler *hdl;
- int (*thread_func)(void *data) = NULL;
- int msp_hard;
- int msp_family;
- int msp_revision;
- int msp_product, msp_prod_hi, msp_prod_lo;
- int msp_rom;
-
- if (!id)
- strlcpy(client->name, "msp3400", sizeof(client->name));
-
- if (msp_reset(client) == -1) {
- v4l_dbg(1, msp_debug, client, "msp3400 not found\n");
- return -ENODEV;
- }
-
- state = kzalloc(sizeof(*state), GFP_KERNEL);
- if (!state)
- return -ENOMEM;
-
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &msp_ops);
-
- state->v4l2_std = V4L2_STD_NTSC;
- state->detected_std = V4L2_STD_ALL;
- state->audmode = V4L2_TUNER_MODE_STEREO;
- state->input = -1;
- state->i2s_mode = 0;
- init_waitqueue_head(&state->wq);
- /* These are the reset input/output positions */
- state->route_in = MSP_INPUT_DEFAULT;
- state->route_out = MSP_OUTPUT_DEFAULT;
-
- state->rev1 = msp_read_dsp(client, 0x1e);
- if (state->rev1 != -1)
- state->rev2 = msp_read_dsp(client, 0x1f);
- v4l_dbg(1, msp_debug, client, "rev1=0x%04x, rev2=0x%04x\n",
- state->rev1, state->rev2);
- if (state->rev1 == -1 || (state->rev1 == 0 && state->rev2 == 0)) {
- v4l_dbg(1, msp_debug, client,
- "not an msp3400 (cannot read chip version)\n");
- kfree(state);
- return -ENODEV;
- }
-
- msp_family = ((state->rev1 >> 4) & 0x0f) + 3;
- msp_product = (state->rev2 >> 8) & 0xff;
- msp_prod_hi = msp_product / 10;
- msp_prod_lo = msp_product % 10;
- msp_revision = (state->rev1 & 0x0f) + '@';
- msp_hard = ((state->rev1 >> 8) & 0xff) + '@';
- msp_rom = state->rev2 & 0x1f;
- /* Rev B=2, C=3, D=4, G=7 */
- state->ident = msp_family * 10000 + 4000 + msp_product * 10 +
- msp_revision - '@';
-
- /* Has NICAM support: all mspx41x and mspx45x products have NICAM */
- state->has_nicam =
- msp_prod_hi == 1 || msp_prod_hi == 5;
- /* Has radio support: was added with revision G */
- state->has_radio =
- msp_revision >= 'G';
- /* Has headphones output: not for stripped down products */
- state->has_headphones =
- msp_prod_lo < 5;
- /* Has scart2 input: not in stripped down products of the '3' family */
- state->has_scart2 =
- msp_family >= 4 || msp_prod_lo < 7;
- /* Has scart3 input: not in stripped down products of the '3' family */
- state->has_scart3 =
- msp_family >= 4 || msp_prod_lo < 5;
- /* Has scart4 input: not in pre D revisions, not in stripped D revs */
- state->has_scart4 =
- msp_family >= 4 || (msp_revision >= 'D' && msp_prod_lo < 5);
- /* Has scart2 output: not in stripped down products of
- * the '3' family */
- state->has_scart2_out =
- msp_family >= 4 || msp_prod_lo < 5;
- /* Has scart2 a volume control? Not in pre-D revisions. */
- state->has_scart2_out_volume =
- msp_revision > 'C' && state->has_scart2_out;
- /* Has a configurable i2s out? */
- state->has_i2s_conf =
- msp_revision >= 'G' && msp_prod_lo < 7;
- /* Has subwoofer output: not in pre-D revs and not in stripped down
- * products */
- state->has_subwoofer =
- msp_revision >= 'D' && msp_prod_lo < 5;
- /* Has soundprocessing (bass/treble/balance/loudness/equalizer):
- * not in stripped down products */
- state->has_sound_processing =
- msp_prod_lo < 7;
- /* Has Virtual Dolby Surround: only in msp34x1 */
- state->has_virtual_dolby_surround =
- msp_revision == 'G' && msp_prod_lo == 1;
- /* Has Virtual Dolby Surround & Dolby Pro Logic: only in msp34x2 */
- state->has_dolby_pro_logic =
- msp_revision == 'G' && msp_prod_lo == 2;
- /* The msp343xG supports BTSC only and cannot do Automatic Standard
- * Detection. */
- state->force_btsc =
- msp_family == 3 && msp_revision == 'G' && msp_prod_hi == 3;
-
- state->opmode = opmode;
- if (state->opmode == OPMODE_AUTO) {
- /* MSP revision G and up have both autodetect and autoselect */
- if (msp_revision >= 'G')
- state->opmode = OPMODE_AUTOSELECT;
- /* MSP revision D and up have autodetect */
- else if (msp_revision >= 'D')
- state->opmode = OPMODE_AUTODETECT;
- else
- state->opmode = OPMODE_MANUAL;
- }
-
- hdl = &state->hdl;
- v4l2_ctrl_handler_init(hdl, 6);
- if (state->has_sound_processing) {
- v4l2_ctrl_new_std(hdl, &msp_ctrl_ops,
- V4L2_CID_AUDIO_BASS, 0, 65535, 65535 / 100, 32768);
- v4l2_ctrl_new_std(hdl, &msp_ctrl_ops,
- V4L2_CID_AUDIO_TREBLE, 0, 65535, 65535 / 100, 32768);
- v4l2_ctrl_new_std(hdl, &msp_ctrl_ops,
- V4L2_CID_AUDIO_LOUDNESS, 0, 1, 1, 0);
- }
- state->volume = v4l2_ctrl_new_std(hdl, &msp_ctrl_ops,
- V4L2_CID_AUDIO_VOLUME, 0, 65535, 65535 / 100, 58880);
- v4l2_ctrl_new_std(hdl, &msp_ctrl_ops,
- V4L2_CID_AUDIO_BALANCE, 0, 65535, 65535 / 100, 32768);
- state->muted = v4l2_ctrl_new_std(hdl, &msp_ctrl_ops,
- V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
- sd->ctrl_handler = hdl;
- if (hdl->error) {
- int err = hdl->error;
-
- v4l2_ctrl_handler_free(hdl);
- kfree(state);
- return err;
- }
-
- v4l2_ctrl_cluster(2, &state->volume);
- v4l2_ctrl_handler_setup(hdl);
-
- /* hello world :-) */
- v4l_info(client, "MSP%d4%02d%c-%c%d found @ 0x%x (%s)\n",
- msp_family, msp_product,
- msp_revision, msp_hard, msp_rom,
- client->addr << 1, client->adapter->name);
- v4l_info(client, "%s ", client->name);
- if (state->has_nicam && state->has_radio)
- printk(KERN_CONT "supports nicam and radio, ");
- else if (state->has_nicam)
- printk(KERN_CONT "supports nicam, ");
- else if (state->has_radio)
- printk(KERN_CONT "supports radio, ");
- printk(KERN_CONT "mode is ");
-
- /* version-specific initialization */
- switch (state->opmode) {
- case OPMODE_MANUAL:
- printk(KERN_CONT "manual");
- thread_func = msp3400c_thread;
- break;
- case OPMODE_AUTODETECT:
- printk(KERN_CONT "autodetect");
- thread_func = msp3410d_thread;
- break;
- case OPMODE_AUTOSELECT:
- printk(KERN_CONT "autodetect and autoselect");
- thread_func = msp34xxg_thread;
- break;
- }
- printk(KERN_CONT "\n");
-
- /* startup control thread if needed */
- if (thread_func) {
- state->kthread = kthread_run(thread_func, client, "msp34xx");
-
- if (IS_ERR(state->kthread))
- v4l_warn(client, "kernel_thread() failed\n");
- msp_wake_thread(client);
- }
- return 0;
-}
-
-static int msp_remove(struct i2c_client *client)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
-
- v4l2_device_unregister_subdev(&state->sd);
- /* shutdown control thread */
- if (state->kthread) {
- state->restart = 1;
- kthread_stop(state->kthread);
- }
- msp_reset(client);
-
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct dev_pm_ops msp3400_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(msp_suspend, msp_resume)
-};
-
-static const struct i2c_device_id msp_id[] = {
- { "msp3400", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, msp_id);
-
-static struct i2c_driver msp_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "msp3400",
- .pm = &msp3400_pm_ops,
- },
- .probe = msp_probe,
- .remove = msp_remove,
- .id_table = msp_id,
-};
-
-module_i2c_driver(msp_driver);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/msp3400-driver.h b/drivers/media/video/msp3400-driver.h
deleted file mode 100644
index fbe5e0715f9..00000000000
--- a/drivers/media/video/msp3400-driver.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- */
-
-#ifndef MSP3400_DRIVER_H
-#define MSP3400_DRIVER_H
-
-#include <media/msp3400.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-
-/* ---------------------------------------------------------------------- */
-
-/* This macro is allowed for *constants* only, gcc must calculate it
- at compile time. Remember -- no floats in kernel mode */
-#define MSP_CARRIER(freq) ((int)((float)(freq / 18.432) * (1 << 24)))
-
-#define MSP_MODE_AM_DETECT 0
-#define MSP_MODE_FM_RADIO 2
-#define MSP_MODE_FM_TERRA 3
-#define MSP_MODE_FM_SAT 4
-#define MSP_MODE_FM_NICAM1 5
-#define MSP_MODE_FM_NICAM2 6
-#define MSP_MODE_AM_NICAM 7
-#define MSP_MODE_BTSC 8
-#define MSP_MODE_EXTERN 9
-
-#define SCART_IN1 0
-#define SCART_IN2 1
-#define SCART_IN3 2
-#define SCART_IN4 3
-#define SCART_IN1_DA 4
-#define SCART_IN2_DA 5
-#define SCART_MONO 6
-#define SCART_MUTE 7
-
-#define SCART_DSP_IN 0
-#define SCART1_OUT 1
-#define SCART2_OUT 2
-
-#define OPMODE_AUTO -1
-#define OPMODE_MANUAL 0
-#define OPMODE_AUTODETECT 1 /* use autodetect (>= msp3410 only) */
-#define OPMODE_AUTOSELECT 2 /* use autodetect & autoselect (>= msp34xxG) */
-
-/* module parameters */
-extern int msp_debug;
-extern bool msp_once;
-extern bool msp_amsound;
-extern int msp_standard;
-extern bool msp_dolby;
-extern int msp_stereo_thresh;
-
-struct msp_state {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- int rev1, rev2;
- int ident;
- u8 has_nicam;
- u8 has_radio;
- u8 has_headphones;
- u8 has_ntsc_jp_d_k3;
- u8 has_scart2;
- u8 has_scart3;
- u8 has_scart4;
- u8 has_scart2_out;
- u8 has_scart2_out_volume;
- u8 has_i2s_conf;
- u8 has_subwoofer;
- u8 has_sound_processing;
- u8 has_virtual_dolby_surround;
- u8 has_dolby_pro_logic;
- u8 force_btsc;
-
- int radio;
- int opmode;
- int std;
- int mode;
- v4l2_std_id v4l2_std, detected_std;
- int nicam_on;
- int acb;
- int in_scart;
- int i2s_mode;
- int main, second; /* sound carrier */
- int input;
- u32 route_in;
- u32 route_out;
-
- /* v4l2 */
- int audmode;
- int rxsubchans;
-
- struct {
- /* volume cluster */
- struct v4l2_ctrl *volume;
- struct v4l2_ctrl *muted;
- };
-
- int scan_in_progress;
-
- /* thread */
- struct task_struct *kthread;
- wait_queue_head_t wq;
- unsigned int restart:1;
- unsigned int watch_stereo:1;
-};
-
-static inline struct msp_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct msp_state, sd);
-}
-
-static inline struct msp_state *ctrl_to_state(struct v4l2_ctrl *ctrl)
-{
- return container_of(ctrl->handler, struct msp_state, hdl);
-}
-
-/* msp3400-driver.c */
-int msp_write_dem(struct i2c_client *client, int addr, int val);
-int msp_write_dsp(struct i2c_client *client, int addr, int val);
-int msp_read_dem(struct i2c_client *client, int addr);
-int msp_read_dsp(struct i2c_client *client, int addr);
-int msp_reset(struct i2c_client *client);
-void msp_set_scart(struct i2c_client *client, int in, int out);
-void msp_update_volume(struct msp_state *state);
-int msp_sleep(struct msp_state *state, int timeout);
-
-/* msp3400-kthreads.c */
-const char *msp_standard_std_name(int std);
-void msp_set_audmode(struct i2c_client *client);
-int msp_detect_stereo(struct i2c_client *client);
-int msp3400c_thread(void *data);
-int msp3410d_thread(void *data);
-int msp34xxg_thread(void *data);
-void msp3400c_set_mode(struct i2c_client *client, int mode);
-void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2);
-
-#endif /* MSP3400_DRIVER_H */
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
deleted file mode 100644
index f8b51714f2f..00000000000
--- a/drivers/media/video/msp3400-kthreads.c
+++ /dev/null
@@ -1,1165 +0,0 @@
-/*
- * Programming the mspx4xx sound processor family
- *
- * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/freezer.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/msp3400.h>
-#include <linux/kthread.h>
-#include <linux/suspend.h>
-#include "msp3400-driver.h"
-
-/* this one uses the automatic sound standard detection of newer msp34xx
- chip versions */
-static struct {
- int retval;
- int main, second;
- char *name;
- v4l2_std_id std;
-} msp_stdlist[] = {
- { 0x0000, 0, 0, "could not detect sound standard", V4L2_STD_ALL },
- { 0x0001, 0, 0, "autodetect start", V4L2_STD_ALL },
- { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72),
- "4.5/4.72 M Dual FM-Stereo", V4L2_STD_MN },
- { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875),
- "5.5/5.74 B/G Dual FM-Stereo", V4L2_STD_BG },
- { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125),
- "6.5/6.25 D/K1 Dual FM-Stereo", V4L2_STD_DK },
- { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875),
- "6.5/6.74 D/K2 Dual FM-Stereo", V4L2_STD_DK },
- { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5),
- "6.5 D/K FM-Mono (HDEV3)", V4L2_STD_DK },
- { 0x0007, MSP_CARRIER(6.5), MSP_CARRIER(5.7421875),
- "6.5/5.74 D/K3 Dual FM-Stereo", V4L2_STD_DK },
- { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85),
- "5.5/5.85 B/G NICAM FM", V4L2_STD_BG },
- { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85),
- "6.5/5.85 L NICAM AM", V4L2_STD_L },
- { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55),
- "6.0/6.55 I NICAM FM", V4L2_STD_PAL_I },
- { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85),
- "6.5/5.85 D/K NICAM FM", V4L2_STD_DK },
- { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85),
- "6.5/5.85 D/K NICAM FM (HDEV2)", V4L2_STD_DK },
- { 0x000d, MSP_CARRIER(6.5), MSP_CARRIER(5.85),
- "6.5/5.85 D/K NICAM FM (HDEV3)", V4L2_STD_DK },
- { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5),
- "4.5 M BTSC-Stereo", V4L2_STD_MTS },
- { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5),
- "4.5 M BTSC-Mono + SAP", V4L2_STD_MTS },
- { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5),
- "4.5 M EIA-J Japan Stereo", V4L2_STD_NTSC_M_JP },
- { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7),
- "10.7 FM-Stereo Radio", V4L2_STD_ALL },
- { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5),
- "6.5 SAT-Mono", V4L2_STD_ALL },
- { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20),
- "7.02/7.20 SAT-Stereo", V4L2_STD_ALL },
- { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2),
- "7.2 SAT ADR", V4L2_STD_ALL },
- { -1, 0, 0, NULL, 0 }, /* EOF */
-};
-
-static struct msp3400c_init_data_dem {
- int fir1[6];
- int fir2[6];
- int cdo1;
- int cdo2;
- int ad_cv;
- int mode_reg;
- int dsp_src;
- int dsp_matrix;
-} msp3400c_init_data[] = {
- { /* AM (for carrier detect / msp3400) */
- {75, 19, 36, 35, 39, 40},
- {75, 19, 36, 35, 39, 40},
- MSP_CARRIER(5.5), MSP_CARRIER(5.5),
- 0x00d0, 0x0500, 0x0020, 0x3000
- }, { /* AM (for carrier detect / msp3410) */
- {-1, -1, -8, 2, 59, 126},
- {-1, -1, -8, 2, 59, 126},
- MSP_CARRIER(5.5), MSP_CARRIER(5.5),
- 0x00d0, 0x0100, 0x0020, 0x3000
- }, { /* FM Radio */
- {-8, -8, 4, 6, 78, 107},
- {-8, -8, 4, 6, 78, 107},
- MSP_CARRIER(10.7), MSP_CARRIER(10.7),
- 0x00d0, 0x0480, 0x0020, 0x3000
- }, { /* Terrestrial FM-mono + FM-stereo */
- {3, 18, 27, 48, 66, 72},
- {3, 18, 27, 48, 66, 72},
- MSP_CARRIER(5.5), MSP_CARRIER(5.5),
- 0x00d0, 0x0480, 0x0030, 0x3000
- }, { /* Sat FM-mono */
- { 1, 9, 14, 24, 33, 37},
- { 3, 18, 27, 48, 66, 72},
- MSP_CARRIER(6.5), MSP_CARRIER(6.5),
- 0x00c6, 0x0480, 0x0000, 0x3000
- }, { /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */
- {-2, -8, -10, 10, 50, 86},
- {3, 18, 27, 48, 66, 72},
- MSP_CARRIER(5.5), MSP_CARRIER(5.5),
- 0x00d0, 0x0040, 0x0120, 0x3000
- }, { /* NICAM/FM -- I (6.0/6.552) */
- {2, 4, -6, -4, 40, 94},
- {3, 18, 27, 48, 66, 72},
- MSP_CARRIER(6.0), MSP_CARRIER(6.0),
- 0x00d0, 0x0040, 0x0120, 0x3000
- }, { /* NICAM/AM -- L (6.5/5.85) */
- {-2, -8, -10, 10, 50, 86},
- {-4, -12, -9, 23, 79, 126},
- MSP_CARRIER(6.5), MSP_CARRIER(6.5),
- 0x00c6, 0x0140, 0x0120, 0x7c00
- },
-};
-
-struct msp3400c_carrier_detect {
- int cdo;
- char *name;
-};
-
-static struct msp3400c_carrier_detect msp3400c_carrier_detect_main[] = {
- /* main carrier */
- { MSP_CARRIER(4.5), "4.5 NTSC" },
- { MSP_CARRIER(5.5), "5.5 PAL B/G" },
- { MSP_CARRIER(6.0), "6.0 PAL I" },
- { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" }
-};
-
-static struct msp3400c_carrier_detect msp3400c_carrier_detect_55[] = {
- /* PAL B/G */
- { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" },
- { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" }
-};
-
-static struct msp3400c_carrier_detect msp3400c_carrier_detect_65[] = {
- /* PAL SAT / SECAM */
- { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" },
- { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" },
- { MSP_CARRIER(6.7421875), "6.74 PAL D/K2 FM-stereo" },
- { MSP_CARRIER(7.02), "7.02 PAL SAT FM-stereo s/b" },
- { MSP_CARRIER(7.20), "7.20 PAL SAT FM-stereo s" },
- { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" },
-};
-
-/* ------------------------------------------------------------------------ */
-
-const char *msp_standard_std_name(int std)
-{
- int i;
-
- for (i = 0; msp_stdlist[i].name != NULL; i++)
- if (msp_stdlist[i].retval == std)
- return msp_stdlist[i].name;
- return "unknown";
-}
-
-static v4l2_std_id msp_standard_std(int std)
-{
- int i;
-
- for (i = 0; msp_stdlist[i].name != NULL; i++)
- if (msp_stdlist[i].retval == std)
- return msp_stdlist[i].std;
- return V4L2_STD_ALL;
-}
-
-static void msp_set_source(struct i2c_client *client, u16 src)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
-
- if (msp_dolby) {
- msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */
- msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */
- } else {
- msp_write_dsp(client, 0x0008, src);
- msp_write_dsp(client, 0x0009, src);
- }
- msp_write_dsp(client, 0x000a, src);
- msp_write_dsp(client, 0x000b, src);
- msp_write_dsp(client, 0x000c, src);
- if (state->has_scart2_out)
- msp_write_dsp(client, 0x0041, src);
-}
-
-void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2)
-{
- msp_write_dem(client, 0x0093, cdo1 & 0xfff);
- msp_write_dem(client, 0x009b, cdo1 >> 12);
- msp_write_dem(client, 0x00a3, cdo2 & 0xfff);
- msp_write_dem(client, 0x00ab, cdo2 >> 12);
- msp_write_dem(client, 0x0056, 0); /* LOAD_REG_1/2 */
-}
-
-void msp3400c_set_mode(struct i2c_client *client, int mode)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
- struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];
- int tuner = (state->route_in >> 3) & 1;
- int i;
-
- v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode);
- state->mode = mode;
- state->rxsubchans = V4L2_TUNER_SUB_MONO;
-
- msp_write_dem(client, 0x00bb, data->ad_cv | (tuner ? 0x100 : 0));
-
- for (i = 5; i >= 0; i--) /* fir 1 */
- msp_write_dem(client, 0x0001, data->fir1[i]);
-
- msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */
- msp_write_dem(client, 0x0005, 0x0040);
- msp_write_dem(client, 0x0005, 0x0000);
- for (i = 5; i >= 0; i--)
- msp_write_dem(client, 0x0005, data->fir2[i]);
-
- msp_write_dem(client, 0x0083, data->mode_reg);
-
- msp3400c_set_carrier(client, data->cdo1, data->cdo2);
-
- msp_set_source(client, data->dsp_src);
- /* set prescales */
-
- /* volume prescale for SCART (AM mono input) */
- msp_write_dsp(client, 0x000d, 0x1900);
- msp_write_dsp(client, 0x000e, data->dsp_matrix);
- if (state->has_nicam) /* nicam prescale */
- msp_write_dsp(client, 0x0010, 0x5a00);
-}
-
-/* Set audio mode. Note that the pre-'G' models do not support BTSC+SAP,
- nor do they support stereo BTSC. */
-static void msp3400c_set_audmode(struct i2c_client *client)
-{
- static char *strmode[] = {
- "mono", "stereo", "lang2", "lang1", "lang1+lang2"
- };
- struct msp_state *state = to_state(i2c_get_clientdata(client));
- char *modestr = (state->audmode >= 0 && state->audmode < 5) ?
- strmode[state->audmode] : "unknown";
- int src = 0; /* channel source: FM/AM, nicam or SCART */
- int audmode = state->audmode;
-
- if (state->opmode == OPMODE_AUTOSELECT) {
- /* this method would break everything, let's make sure
- * it's never called
- */
- v4l_dbg(1, msp_debug, client,
- "set_audmode called with mode=%d instead of set_source (ignored)\n",
- state->audmode);
- return;
- }
-
- /* Note: for the C and D revs no NTSC stereo + SAP is possible as
- the hardware does not support SAP. So the rxsubchans combination
- of STEREO | LANG2 does not occur. */
-
- if (state->mode != MSP_MODE_EXTERN) {
- /* switch to mono if only mono is available */
- if (state->rxsubchans == V4L2_TUNER_SUB_MONO)
- audmode = V4L2_TUNER_MODE_MONO;
- /* if bilingual */
- else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) {
- /* and mono or stereo, then fallback to lang1 */
- if (audmode == V4L2_TUNER_MODE_MONO ||
- audmode == V4L2_TUNER_MODE_STEREO)
- audmode = V4L2_TUNER_MODE_LANG1;
- }
- /* if stereo, and audmode is not mono, then switch to stereo */
- else if (audmode != V4L2_TUNER_MODE_MONO)
- audmode = V4L2_TUNER_MODE_STEREO;
- }
-
- /* switch demodulator */
- switch (state->mode) {
- case MSP_MODE_FM_TERRA:
- v4l_dbg(1, msp_debug, client, "FM set_audmode: %s\n", modestr);
- switch (audmode) {
- case V4L2_TUNER_MODE_STEREO:
- msp_write_dsp(client, 0x000e, 0x3001);
- break;
- case V4L2_TUNER_MODE_MONO:
- case V4L2_TUNER_MODE_LANG1:
- case V4L2_TUNER_MODE_LANG2:
- case V4L2_TUNER_MODE_LANG1_LANG2:
- msp_write_dsp(client, 0x000e, 0x3000);
- break;
- }
- break;
- case MSP_MODE_FM_SAT:
- v4l_dbg(1, msp_debug, client, "SAT set_audmode: %s\n", modestr);
- switch (audmode) {
- case V4L2_TUNER_MODE_MONO:
- msp3400c_set_carrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
- break;
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1_LANG2:
- msp3400c_set_carrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
- break;
- case V4L2_TUNER_MODE_LANG1:
- msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
- break;
- case V4L2_TUNER_MODE_LANG2:
- msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
- break;
- }
- break;
- case MSP_MODE_FM_NICAM1:
- case MSP_MODE_FM_NICAM2:
- case MSP_MODE_AM_NICAM:
- v4l_dbg(1, msp_debug, client,
- "NICAM set_audmode: %s\n", modestr);
- if (state->nicam_on)
- src = 0x0100; /* NICAM */
- break;
- case MSP_MODE_BTSC:
- v4l_dbg(1, msp_debug, client,
- "BTSC set_audmode: %s\n", modestr);
- break;
- case MSP_MODE_EXTERN:
- v4l_dbg(1, msp_debug, client,
- "extern set_audmode: %s\n", modestr);
- src = 0x0200; /* SCART */
- break;
- case MSP_MODE_FM_RADIO:
- v4l_dbg(1, msp_debug, client,
- "FM-Radio set_audmode: %s\n", modestr);
- break;
- default:
- v4l_dbg(1, msp_debug, client, "mono set_audmode\n");
- return;
- }
-
- /* switch audio */
- v4l_dbg(1, msp_debug, client, "set audmode %d\n", audmode);
- switch (audmode) {
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1_LANG2:
- src |= 0x0020;
- break;
- case V4L2_TUNER_MODE_MONO:
- if (state->mode == MSP_MODE_AM_NICAM) {
- v4l_dbg(1, msp_debug, client, "switching to AM mono\n");
- /* AM mono decoding is handled by tuner, not MSP chip */
- /* SCART switching control register */
- msp_set_scart(client, SCART_MONO, 0);
- src = 0x0200;
- break;
- }
- if (state->rxsubchans & V4L2_TUNER_SUB_STEREO)
- src = 0x0030;
- break;
- case V4L2_TUNER_MODE_LANG1:
- break;
- case V4L2_TUNER_MODE_LANG2:
- src |= 0x0010;
- break;
- }
- v4l_dbg(1, msp_debug, client,
- "set_audmode final source/matrix = 0x%x\n", src);
-
- msp_set_source(client, src);
-}
-
-static void msp3400c_print_mode(struct i2c_client *client)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
-
- if (state->main == state->second)
- v4l_dbg(1, msp_debug, client,
- "mono sound carrier: %d.%03d MHz\n",
- state->main / 910000, (state->main / 910) % 1000);
- else
- v4l_dbg(1, msp_debug, client,
- "main sound carrier: %d.%03d MHz\n",
- state->main / 910000, (state->main / 910) % 1000);
- if (state->mode == MSP_MODE_FM_NICAM1 || state->mode == MSP_MODE_FM_NICAM2)
- v4l_dbg(1, msp_debug, client,
- "NICAM/FM carrier : %d.%03d MHz\n",
- state->second / 910000, (state->second/910) % 1000);
- if (state->mode == MSP_MODE_AM_NICAM)
- v4l_dbg(1, msp_debug, client,
- "NICAM/AM carrier : %d.%03d MHz\n",
- state->second / 910000, (state->second / 910) % 1000);
- if (state->mode == MSP_MODE_FM_TERRA && state->main != state->second) {
- v4l_dbg(1, msp_debug, client,
- "FM-stereo carrier : %d.%03d MHz\n",
- state->second / 910000, (state->second / 910) % 1000);
- }
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int msp3400c_detect_stereo(struct i2c_client *client)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
- int val;
- int rxsubchans = state->rxsubchans;
- int newnicam = state->nicam_on;
- int update = 0;
-
- switch (state->mode) {
- case MSP_MODE_FM_TERRA:
- val = msp_read_dsp(client, 0x18);
- if (val > 32767)
- val -= 65536;
- v4l_dbg(2, msp_debug, client,
- "stereo detect register: %d\n", val);
- if (val > 8192) {
- rxsubchans = V4L2_TUNER_SUB_STEREO;
- } else if (val < -4096) {
- rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- } else {
- rxsubchans = V4L2_TUNER_SUB_MONO;
- }
- newnicam = 0;
- break;
- case MSP_MODE_FM_NICAM1:
- case MSP_MODE_FM_NICAM2:
- case MSP_MODE_AM_NICAM:
- val = msp_read_dem(client, 0x23);
- v4l_dbg(2, msp_debug, client, "nicam sync=%d, mode=%d\n",
- val & 1, (val & 0x1e) >> 1);
-
- if (val & 1) {
- /* nicam synced */
- switch ((val & 0x1e) >> 1) {
- case 0:
- case 8:
- rxsubchans = V4L2_TUNER_SUB_STEREO;
- break;
- case 1:
- case 9:
- rxsubchans = V4L2_TUNER_SUB_MONO;
- break;
- case 2:
- case 10:
- rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- break;
- default:
- rxsubchans = V4L2_TUNER_SUB_MONO;
- break;
- }
- newnicam = 1;
- } else {
- newnicam = 0;
- rxsubchans = V4L2_TUNER_SUB_MONO;
- }
- break;
- }
- if (rxsubchans != state->rxsubchans) {
- update = 1;
- v4l_dbg(1, msp_debug, client,
- "watch: rxsubchans %02x => %02x\n",
- state->rxsubchans, rxsubchans);
- state->rxsubchans = rxsubchans;
- }
- if (newnicam != state->nicam_on) {
- update = 1;
- v4l_dbg(1, msp_debug, client, "watch: nicam %d => %d\n",
- state->nicam_on, newnicam);
- state->nicam_on = newnicam;
- }
- return update;
-}
-
-/*
- * A kernel thread for msp3400 control -- we don't want to block the
- * in the ioctl while doing the sound carrier & stereo detect
- */
-/* stereo/multilang monitoring */
-static void watch_stereo(struct i2c_client *client)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
-
- if (msp_detect_stereo(client))
- msp_set_audmode(client);
-
- if (msp_once)
- state->watch_stereo = 0;
-}
-
-int msp3400c_thread(void *data)
-{
- struct i2c_client *client = data;
- struct msp_state *state = to_state(i2c_get_clientdata(client));
- struct msp3400c_carrier_detect *cd;
- int count, max1, max2, val1, val2, val, i;
-
- v4l_dbg(1, msp_debug, client, "msp3400 daemon started\n");
- state->detected_std = V4L2_STD_ALL;
- set_freezable();
- for (;;) {
- v4l_dbg(2, msp_debug, client, "msp3400 thread: sleep\n");
- msp_sleep(state, -1);
- v4l_dbg(2, msp_debug, client, "msp3400 thread: wakeup\n");
-
-restart:
- v4l_dbg(2, msp_debug, client, "thread: restart scan\n");
- state->restart = 0;
- if (kthread_should_stop())
- break;
-
- if (state->radio || MSP_MODE_EXTERN == state->mode) {
- /* no carrier scan, just unmute */
- v4l_dbg(1, msp_debug, client,
- "thread: no carrier scan\n");
- state->scan_in_progress = 0;
- msp_update_volume(state);
- continue;
- }
-
- /* mute audio */
- state->scan_in_progress = 1;
- msp_update_volume(state);
-
- msp3400c_set_mode(client, MSP_MODE_AM_DETECT);
- val1 = val2 = 0;
- max1 = max2 = -1;
- state->watch_stereo = 0;
- state->nicam_on = 0;
-
- /* wait for tuner to settle down after a channel change */
- if (msp_sleep(state, 200))
- goto restart;
-
- /* carrier detect pass #1 -- main carrier */
- cd = msp3400c_carrier_detect_main;
- count = ARRAY_SIZE(msp3400c_carrier_detect_main);
-
- if (msp_amsound && (state->v4l2_std & V4L2_STD_SECAM)) {
- /* autodetect doesn't work well with AM ... */
- max1 = 3;
- count = 0;
- v4l_dbg(1, msp_debug, client, "AM sound override\n");
- }
-
- for (i = 0; i < count; i++) {
- msp3400c_set_carrier(client, cd[i].cdo, cd[i].cdo);
- if (msp_sleep(state, 100))
- goto restart;
- val = msp_read_dsp(client, 0x1b);
- if (val > 32767)
- val -= 65536;
- if (val1 < val)
- val1 = val, max1 = i;
- v4l_dbg(1, msp_debug, client,
- "carrier1 val: %5d / %s\n", val, cd[i].name);
- }
-
- /* carrier detect pass #2 -- second (stereo) carrier */
- switch (max1) {
- case 1: /* 5.5 */
- cd = msp3400c_carrier_detect_55;
- count = ARRAY_SIZE(msp3400c_carrier_detect_55);
- break;
- case 3: /* 6.5 */
- cd = msp3400c_carrier_detect_65;
- count = ARRAY_SIZE(msp3400c_carrier_detect_65);
- break;
- case 0: /* 4.5 */
- case 2: /* 6.0 */
- default:
- cd = NULL;
- count = 0;
- break;
- }
-
- if (msp_amsound && (state->v4l2_std & V4L2_STD_SECAM)) {
- /* autodetect doesn't work well with AM ... */
- cd = NULL;
- count = 0;
- max2 = 0;
- }
- for (i = 0; i < count; i++) {
- msp3400c_set_carrier(client, cd[i].cdo, cd[i].cdo);
- if (msp_sleep(state, 100))
- goto restart;
- val = msp_read_dsp(client, 0x1b);
- if (val > 32767)
- val -= 65536;
- if (val2 < val)
- val2 = val, max2 = i;
- v4l_dbg(1, msp_debug, client,
- "carrier2 val: %5d / %s\n", val, cd[i].name);
- }
-
- /* program the msp3400 according to the results */
- state->main = msp3400c_carrier_detect_main[max1].cdo;
- switch (max1) {
- case 1: /* 5.5 */
- state->detected_std = V4L2_STD_BG | V4L2_STD_PAL_H;
- if (max2 == 0) {
- /* B/G FM-stereo */
- state->second = msp3400c_carrier_detect_55[max2].cdo;
- msp3400c_set_mode(client, MSP_MODE_FM_TERRA);
- state->watch_stereo = 1;
- } else if (max2 == 1 && state->has_nicam) {
- /* B/G NICAM */
- state->second = msp3400c_carrier_detect_55[max2].cdo;
- msp3400c_set_mode(client, MSP_MODE_FM_NICAM1);
- state->nicam_on = 1;
- state->watch_stereo = 1;
- } else {
- goto no_second;
- }
- break;
- case 2: /* 6.0 */
- /* PAL I NICAM */
- state->detected_std = V4L2_STD_PAL_I;
- state->second = MSP_CARRIER(6.552);
- msp3400c_set_mode(client, MSP_MODE_FM_NICAM2);
- state->nicam_on = 1;
- state->watch_stereo = 1;
- break;
- case 3: /* 6.5 */
- if (max2 == 1 || max2 == 2) {
- /* D/K FM-stereo */
- state->second = msp3400c_carrier_detect_65[max2].cdo;
- msp3400c_set_mode(client, MSP_MODE_FM_TERRA);
- state->watch_stereo = 1;
- state->detected_std = V4L2_STD_DK;
- } else if (max2 == 0 && (state->v4l2_std & V4L2_STD_SECAM)) {
- /* L NICAM or AM-mono */
- state->second = msp3400c_carrier_detect_65[max2].cdo;
- msp3400c_set_mode(client, MSP_MODE_AM_NICAM);
- state->watch_stereo = 1;
- state->detected_std = V4L2_STD_L;
- } else if (max2 == 0 && state->has_nicam) {
- /* D/K NICAM */
- state->second = msp3400c_carrier_detect_65[max2].cdo;
- msp3400c_set_mode(client, MSP_MODE_FM_NICAM1);
- state->nicam_on = 1;
- state->watch_stereo = 1;
- state->detected_std = V4L2_STD_DK;
- } else {
- goto no_second;
- }
- break;
- case 0: /* 4.5 */
- state->detected_std = V4L2_STD_MN;
- default:
-no_second:
- state->second = msp3400c_carrier_detect_main[max1].cdo;
- msp3400c_set_mode(client, MSP_MODE_FM_TERRA);
- break;
- }
- msp3400c_set_carrier(client, state->second, state->main);
-
- /* unmute */
- state->scan_in_progress = 0;
- msp3400c_set_audmode(client);
- msp_update_volume(state);
-
- if (msp_debug)
- msp3400c_print_mode(client);
-
- /* monitor tv audio mode, the first time don't wait
- so long to get a quick stereo/bilingual result */
- count = 3;
- while (state->watch_stereo) {
- if (msp_sleep(state, count ? 1000 : 5000))
- goto restart;
- if (count)
- count--;
- watch_stereo(client);
- }
- }
- v4l_dbg(1, msp_debug, client, "thread: exit\n");
- return 0;
-}
-
-
-int msp3410d_thread(void *data)
-{
- struct i2c_client *client = data;
- struct msp_state *state = to_state(i2c_get_clientdata(client));
- int val, i, std, count;
-
- v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n");
- state->detected_std = V4L2_STD_ALL;
- set_freezable();
- for (;;) {
- v4l_dbg(2, msp_debug, client, "msp3410 thread: sleep\n");
- msp_sleep(state, -1);
- v4l_dbg(2, msp_debug, client, "msp3410 thread: wakeup\n");
-
-restart:
- v4l_dbg(2, msp_debug, client, "thread: restart scan\n");
- state->restart = 0;
- if (kthread_should_stop())
- break;
-
- if (state->mode == MSP_MODE_EXTERN) {
- /* no carrier scan needed, just unmute */
- v4l_dbg(1, msp_debug, client,
- "thread: no carrier scan\n");
- state->scan_in_progress = 0;
- msp_update_volume(state);
- continue;
- }
-
- /* mute audio */
- state->scan_in_progress = 1;
- msp_update_volume(state);
-
- /* start autodetect. Note: autodetect is not supported for
- NTSC-M and radio, hence we force the standard in those
- cases. */
- if (state->radio)
- std = 0x40;
- else
- std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1;
- state->watch_stereo = 0;
- state->nicam_on = 0;
-
- /* wait for tuner to settle down after a channel change */
- if (msp_sleep(state, 200))
- goto restart;
-
- if (msp_debug)
- v4l_dbg(2, msp_debug, client,
- "setting standard: %s (0x%04x)\n",
- msp_standard_std_name(std), std);
-
- if (std != 1) {
- /* programmed some specific mode */
- val = std;
- } else {
- /* triggered autodetect */
- msp_write_dem(client, 0x20, std);
- for (;;) {
- if (msp_sleep(state, 100))
- goto restart;
-
- /* check results */
- val = msp_read_dem(client, 0x7e);
- if (val < 0x07ff)
- break;
- v4l_dbg(2, msp_debug, client,
- "detection still in progress\n");
- }
- }
- for (i = 0; msp_stdlist[i].name != NULL; i++)
- if (msp_stdlist[i].retval == val)
- break;
- v4l_dbg(1, msp_debug, client, "current standard: %s (0x%04x)\n",
- msp_standard_std_name(val), val);
- state->main = msp_stdlist[i].main;
- state->second = msp_stdlist[i].second;
- state->std = val;
- state->rxsubchans = V4L2_TUNER_SUB_MONO;
-
- if (msp_amsound && !state->radio &&
- (state->v4l2_std & V4L2_STD_SECAM) && (val != 0x0009)) {
- /* autodetection has failed, let backup */
- v4l_dbg(1, msp_debug, client, "autodetection failed,"
- " switching to backup standard: %s (0x%04x)\n",
- msp_stdlist[8].name ?
- msp_stdlist[8].name : "unknown", val);
- state->std = val = 0x0009;
- msp_write_dem(client, 0x20, val);
- } else {
- state->detected_std = msp_standard_std(state->std);
- }
-
- /* set stereo */
- switch (val) {
- case 0x0008: /* B/G NICAM */
- case 0x000a: /* I NICAM */
- case 0x000b: /* D/K NICAM */
- if (val == 0x000a)
- state->mode = MSP_MODE_FM_NICAM2;
- else
- state->mode = MSP_MODE_FM_NICAM1;
- /* just turn on stereo */
- state->nicam_on = 1;
- state->watch_stereo = 1;
- break;
- case 0x0009:
- state->mode = MSP_MODE_AM_NICAM;
- state->nicam_on = 1;
- state->watch_stereo = 1;
- break;
- case 0x0020: /* BTSC */
- /* The pre-'G' models only have BTSC-mono */
- state->mode = MSP_MODE_BTSC;
- break;
- case 0x0040: /* FM radio */
- state->mode = MSP_MODE_FM_RADIO;
- state->rxsubchans = V4L2_TUNER_SUB_STEREO;
- /* not needed in theory if we have radio, but
- short programming enables carrier mute */
- msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
- msp3400c_set_carrier(client, MSP_CARRIER(10.7),
- MSP_CARRIER(10.7));
- break;
- case 0x0002:
- case 0x0003:
- case 0x0004:
- case 0x0005:
- state->mode = MSP_MODE_FM_TERRA;
- state->watch_stereo = 1;
- break;
- }
-
- /* set various prescales */
- msp_write_dsp(client, 0x0d, 0x1900); /* scart */
- msp_write_dsp(client, 0x0e, 0x3000); /* FM */
- if (state->has_nicam)
- msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
-
- if (state->has_i2s_conf)
- msp_write_dem(client, 0x40, state->i2s_mode);
-
- /* unmute */
- msp3400c_set_audmode(client);
- state->scan_in_progress = 0;
- msp_update_volume(state);
-
- /* monitor tv audio mode, the first time don't wait
- so long to get a quick stereo/bilingual result */
- count = 3;
- while (state->watch_stereo) {
- if (msp_sleep(state, count ? 1000 : 5000))
- goto restart;
- if (count)
- count--;
- watch_stereo(client);
- }
- }
- v4l_dbg(1, msp_debug, client, "thread: exit\n");
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-/* msp34xxG + (autoselect no-thread)
- * this one uses both automatic standard detection and automatic sound
- * select which are available in the newer G versions
- * struct msp: only norm, acb and source are really used in this mode
- */
-
-static int msp34xxg_modus(struct i2c_client *client)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
-
- if (state->radio) {
- v4l_dbg(1, msp_debug, client, "selected radio modus\n");
- return 0x0001;
- }
- if (state->v4l2_std == V4L2_STD_NTSC_M_JP) {
- v4l_dbg(1, msp_debug, client, "selected M (EIA-J) modus\n");
- return 0x4001;
- }
- if (state->v4l2_std == V4L2_STD_NTSC_M_KR) {
- v4l_dbg(1, msp_debug, client, "selected M (A2) modus\n");
- return 0x0001;
- }
- if (state->v4l2_std == V4L2_STD_SECAM_L) {
- v4l_dbg(1, msp_debug, client, "selected SECAM-L modus\n");
- return 0x6001;
- }
- if (state->v4l2_std & V4L2_STD_MN) {
- v4l_dbg(1, msp_debug, client, "selected M (BTSC) modus\n");
- return 0x2001;
- }
- return 0x7001;
-}
-
-static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
- {
- struct msp_state *state = to_state(i2c_get_clientdata(client));
- int source, matrix;
-
- switch (state->audmode) {
- case V4L2_TUNER_MODE_MONO:
- source = 0; /* mono only */
- matrix = 0x30;
- break;
- case V4L2_TUNER_MODE_LANG2:
- source = 4; /* stereo or B */
- matrix = 0x10;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- source = 1; /* stereo or A|B */
- matrix = 0x20;
- break;
- case V4L2_TUNER_MODE_LANG1:
- source = 3; /* stereo or A */
- matrix = 0x00;
- break;
- case V4L2_TUNER_MODE_STEREO:
- default:
- source = 3; /* stereo or A */
- matrix = 0x20;
- break;
- }
-
- if (in == MSP_DSP_IN_TUNER)
- source = (source << 8) | 0x20;
- /* the msp34x2g puts the MAIN_AVC, MAIN and AUX sources in 12, 13, 14
- instead of 11, 12, 13. So we add one for that msp version. */
- else if (in >= MSP_DSP_IN_MAIN_AVC && state->has_dolby_pro_logic)
- source = ((in + 1) << 8) | matrix;
- else
- source = (in << 8) | matrix;
-
- v4l_dbg(1, msp_debug, client,
- "set source to %d (0x%x) for output %02x\n", in, source, reg);
- msp_write_dsp(client, reg, source);
-}
-
-static void msp34xxg_set_sources(struct i2c_client *client)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
- u32 in = state->route_in;
-
- msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf);
- /* quasi-peak detector is set to same input as the loudspeaker (MAIN) */
- msp34xxg_set_source(client, 0x000c, (in >> 4) & 0xf);
- msp34xxg_set_source(client, 0x0009, (in >> 8) & 0xf);
- msp34xxg_set_source(client, 0x000a, (in >> 12) & 0xf);
- if (state->has_scart2_out)
- msp34xxg_set_source(client, 0x0041, (in >> 16) & 0xf);
- msp34xxg_set_source(client, 0x000b, (in >> 20) & 0xf);
-}
-
-/* (re-)initialize the msp34xxg */
-static void msp34xxg_reset(struct i2c_client *client)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
- int tuner = (state->route_in >> 3) & 1;
- int modus;
-
- /* initialize std to 1 (autodetect) to signal that no standard is
- selected yet. */
- state->std = 1;
-
- msp_reset(client);
-
- if (state->has_i2s_conf)
- msp_write_dem(client, 0x40, state->i2s_mode);
-
- /* step-by-step initialisation, as described in the manual */
- modus = msp34xxg_modus(client);
- modus |= tuner ? 0x100 : 0;
- msp_write_dem(client, 0x30, modus);
-
- /* write the dsps that may have an influence on
- standard/audio autodetection right now */
- msp34xxg_set_sources(client);
-
- msp_write_dsp(client, 0x0d, 0x1900); /* scart */
- msp_write_dsp(client, 0x0e, 0x3000); /* FM */
- if (state->has_nicam)
- msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
-
- /* set identification threshold. Personally, I
- * I set it to a higher value than the default
- * of 0x190 to ignore noisy stereo signals.
- * this needs tuning. (recommended range 0x00a0-0x03c0)
- * 0x7f0 = forced mono mode
- *
- * a2 threshold for stereo/bilingual.
- * Note: this register is part of the Manual/Compatibility mode.
- * It is supported by all 'G'-family chips.
- */
- msp_write_dem(client, 0x22, msp_stereo_thresh);
-}
-
-int msp34xxg_thread(void *data)
-{
- struct i2c_client *client = data;
- struct msp_state *state = to_state(i2c_get_clientdata(client));
- int val, i;
-
- v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n");
- state->detected_std = V4L2_STD_ALL;
- set_freezable();
- for (;;) {
- v4l_dbg(2, msp_debug, client, "msp34xxg thread: sleep\n");
- msp_sleep(state, -1);
- v4l_dbg(2, msp_debug, client, "msp34xxg thread: wakeup\n");
-
-restart:
- v4l_dbg(1, msp_debug, client, "thread: restart scan\n");
- state->restart = 0;
- if (kthread_should_stop())
- break;
-
- if (state->mode == MSP_MODE_EXTERN) {
- /* no carrier scan needed, just unmute */
- v4l_dbg(1, msp_debug, client,
- "thread: no carrier scan\n");
- state->scan_in_progress = 0;
- msp_update_volume(state);
- continue;
- }
-
- /* setup the chip*/
- msp34xxg_reset(client);
- state->std = state->radio ? 0x40 :
- (state->force_btsc && msp_standard == 1) ? 32 : msp_standard;
- msp_write_dem(client, 0x20, state->std);
- /* start autodetect */
- if (state->std != 1)
- goto unmute;
-
- /* watch autodetect */
- v4l_dbg(1, msp_debug, client,
- "started autodetect, waiting for result\n");
- for (i = 0; i < 10; i++) {
- if (msp_sleep(state, 100))
- goto restart;
-
- /* check results */
- val = msp_read_dem(client, 0x7e);
- if (val < 0x07ff) {
- state->std = val;
- break;
- }
- v4l_dbg(2, msp_debug, client,
- "detection still in progress\n");
- }
- if (state->std == 1) {
- v4l_dbg(1, msp_debug, client,
- "detection still in progress after 10 tries. giving up.\n");
- continue;
- }
-
-unmute:
- v4l_dbg(1, msp_debug, client,
- "detected standard: %s (0x%04x)\n",
- msp_standard_std_name(state->std), state->std);
- state->detected_std = msp_standard_std(state->std);
-
- if (state->std == 9) {
- /* AM NICAM mode */
- msp_write_dsp(client, 0x0e, 0x7c00);
- }
-
- /* unmute: dispatch sound to scart output, set scart volume */
- msp_update_volume(state);
-
- /* restore ACB */
- if (msp_write_dsp(client, 0x13, state->acb))
- return -1;
-
- /* the periodic stereo/SAP check is only relevant for
- the 0x20 standard (BTSC) */
- if (state->std != 0x20)
- continue;
-
- state->watch_stereo = 1;
-
- /* monitor tv audio mode, the first time don't wait
- in order to get a quick stereo/SAP update */
- watch_stereo(client);
- while (state->watch_stereo) {
- watch_stereo(client);
- if (msp_sleep(state, 5000))
- goto restart;
- }
- }
- v4l_dbg(1, msp_debug, client, "thread: exit\n");
- return 0;
-}
-
-static int msp34xxg_detect_stereo(struct i2c_client *client)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
- int status = msp_read_dem(client, 0x0200);
- int is_bilingual = status & 0x100;
- int is_stereo = status & 0x40;
- int oldrx = state->rxsubchans;
-
- if (state->mode == MSP_MODE_EXTERN)
- return 0;
-
- state->rxsubchans = 0;
- if (is_stereo)
- state->rxsubchans = V4L2_TUNER_SUB_STEREO;
- else
- state->rxsubchans = V4L2_TUNER_SUB_MONO;
- if (is_bilingual) {
- if (state->std == 0x20)
- state->rxsubchans |= V4L2_TUNER_SUB_SAP;
- else
- state->rxsubchans =
- V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- }
- v4l_dbg(1, msp_debug, client,
- "status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
- status, is_stereo, is_bilingual, state->rxsubchans);
- return (oldrx != state->rxsubchans);
-}
-
-static void msp34xxg_set_audmode(struct i2c_client *client)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
-
- if (state->std == 0x20) {
- if ((state->rxsubchans & V4L2_TUNER_SUB_SAP) &&
- (state->audmode == V4L2_TUNER_MODE_LANG1_LANG2 ||
- state->audmode == V4L2_TUNER_MODE_LANG2)) {
- msp_write_dem(client, 0x20, 0x21);
- } else {
- msp_write_dem(client, 0x20, 0x20);
- }
- }
-
- msp34xxg_set_sources(client);
-}
-
-void msp_set_audmode(struct i2c_client *client)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
-
- switch (state->opmode) {
- case OPMODE_MANUAL:
- case OPMODE_AUTODETECT:
- msp3400c_set_audmode(client);
- break;
- case OPMODE_AUTOSELECT:
- msp34xxg_set_audmode(client);
- break;
- }
-}
-
-int msp_detect_stereo(struct i2c_client *client)
-{
- struct msp_state *state = to_state(i2c_get_clientdata(client));
-
- switch (state->opmode) {
- case OPMODE_MANUAL:
- case OPMODE_AUTODETECT:
- return msp3400c_detect_stereo(client);
- case OPMODE_AUTOSELECT:
- return msp34xxg_detect_stereo(client);
- }
- return 0;
-}
-
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
deleted file mode 100644
index 00583f5fd26..00000000000
--- a/drivers/media/video/mt9m001.c
+++ /dev/null
@@ -1,737 +0,0 @@
-/*
- * Driver for MT9M001 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/module.h>
-
-#include <media/soc_camera.h>
-#include <media/soc_mediabus.h>
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-
-/*
- * mt9m001 i2c address 0x5d
- * The platform has to define struct i2c_board_info objects and link to them
- * from struct soc_camera_link
- */
-
-/* mt9m001 selected register addresses */
-#define MT9M001_CHIP_VERSION 0x00
-#define MT9M001_ROW_START 0x01
-#define MT9M001_COLUMN_START 0x02
-#define MT9M001_WINDOW_HEIGHT 0x03
-#define MT9M001_WINDOW_WIDTH 0x04
-#define MT9M001_HORIZONTAL_BLANKING 0x05
-#define MT9M001_VERTICAL_BLANKING 0x06
-#define MT9M001_OUTPUT_CONTROL 0x07
-#define MT9M001_SHUTTER_WIDTH 0x09
-#define MT9M001_FRAME_RESTART 0x0b
-#define MT9M001_SHUTTER_DELAY 0x0c
-#define MT9M001_RESET 0x0d
-#define MT9M001_READ_OPTIONS1 0x1e
-#define MT9M001_READ_OPTIONS2 0x20
-#define MT9M001_GLOBAL_GAIN 0x35
-#define MT9M001_CHIP_ENABLE 0xF1
-
-#define MT9M001_MAX_WIDTH 1280
-#define MT9M001_MAX_HEIGHT 1024
-#define MT9M001_MIN_WIDTH 48
-#define MT9M001_MIN_HEIGHT 32
-#define MT9M001_COLUMN_SKIP 20
-#define MT9M001_ROW_SKIP 12
-
-/* MT9M001 has only one fixed colorspace per pixelcode */
-struct mt9m001_datafmt {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
-};
-
-/* Find a data format by a pixel code in an array */
-static const struct mt9m001_datafmt *mt9m001_find_datafmt(
- enum v4l2_mbus_pixelcode code, const struct mt9m001_datafmt *fmt,
- int n)
-{
- int i;
- for (i = 0; i < n; i++)
- if (fmt[i].code == code)
- return fmt + i;
-
- return NULL;
-}
-
-static const struct mt9m001_datafmt mt9m001_colour_fmts[] = {
- /*
- * Order important: first natively supported,
- * second supported with a GPIO extender
- */
- {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
-};
-
-static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = {
- /* Order important - see above */
- {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
- {V4L2_MBUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG},
-};
-
-struct mt9m001 {
- struct v4l2_subdev subdev;
- struct v4l2_ctrl_handler hdl;
- struct {
- /* exposure/auto-exposure cluster */
- struct v4l2_ctrl *autoexposure;
- struct v4l2_ctrl *exposure;
- };
- struct v4l2_rect rect; /* Sensor window */
- const struct mt9m001_datafmt *fmt;
- const struct mt9m001_datafmt *fmts;
- int num_fmts;
- int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
- unsigned int total_h;
- unsigned short y_skip_top; /* Lines to skip at the top */
-};
-
-static struct mt9m001 *to_mt9m001(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client), struct mt9m001, subdev);
-}
-
-static int reg_read(struct i2c_client *client, const u8 reg)
-{
- return i2c_smbus_read_word_swapped(client, reg);
-}
-
-static int reg_write(struct i2c_client *client, const u8 reg,
- const u16 data)
-{
- return i2c_smbus_write_word_swapped(client, reg, data);
-}
-
-static int reg_set(struct i2c_client *client, const u8 reg,
- const u16 data)
-{
- int ret;
-
- ret = reg_read(client, reg);
- if (ret < 0)
- return ret;
- return reg_write(client, reg, ret | data);
-}
-
-static int reg_clear(struct i2c_client *client, const u8 reg,
- const u16 data)
-{
- int ret;
-
- ret = reg_read(client, reg);
- if (ret < 0)
- return ret;
- return reg_write(client, reg, ret & ~data);
-}
-
-static int mt9m001_init(struct i2c_client *client)
-{
- int ret;
-
- dev_dbg(&client->dev, "%s\n", __func__);
-
- /*
- * We don't know, whether platform provides reset, issue a soft reset
- * too. This returns all registers to their default values.
- */
- ret = reg_write(client, MT9M001_RESET, 1);
- if (!ret)
- ret = reg_write(client, MT9M001_RESET, 0);
-
- /* Disable chip, synchronous option update */
- if (!ret)
- ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
-
- return ret;
-}
-
-static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- /* Switch to master "normal" mode or stop sensor readout */
- if (reg_write(client, MT9M001_OUTPUT_CONTROL, enable ? 2 : 0) < 0)
- return -EIO;
- return 0;
-}
-
-static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9m001 *mt9m001 = to_mt9m001(client);
- struct v4l2_rect rect = a->c;
- int ret;
- const u16 hblank = 9, vblank = 25;
-
- if (mt9m001->fmts == mt9m001_colour_fmts)
- /*
- * Bayer format - even number of rows for simplicity,
- * but let the user play with the top row.
- */
- rect.height = ALIGN(rect.height, 2);
-
- /* Datasheet requirement: see register description */
- rect.width = ALIGN(rect.width, 2);
- rect.left = ALIGN(rect.left, 2);
-
- soc_camera_limit_side(&rect.left, &rect.width,
- MT9M001_COLUMN_SKIP, MT9M001_MIN_WIDTH, MT9M001_MAX_WIDTH);
-
- soc_camera_limit_side(&rect.top, &rect.height,
- MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT);
-
- mt9m001->total_h = rect.height + mt9m001->y_skip_top + vblank;
-
- /* Blanking and start values - default... */
- ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
- if (!ret)
- ret = reg_write(client, MT9M001_VERTICAL_BLANKING, vblank);
-
- /*
- * The caller provides a supported format, as verified per
- * call to .try_mbus_fmt()
- */
- if (!ret)
- ret = reg_write(client, MT9M001_COLUMN_START, rect.left);
- if (!ret)
- ret = reg_write(client, MT9M001_ROW_START, rect.top);
- if (!ret)
- ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect.width - 1);
- if (!ret)
- ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
- rect.height + mt9m001->y_skip_top - 1);
- if (!ret && v4l2_ctrl_g_ctrl(mt9m001->autoexposure) == V4L2_EXPOSURE_AUTO)
- ret = reg_write(client, MT9M001_SHUTTER_WIDTH, mt9m001->total_h);
-
- if (!ret)
- mt9m001->rect = rect;
-
- return ret;
-}
-
-static int mt9m001_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9m001 *mt9m001 = to_mt9m001(client);
-
- a->c = mt9m001->rect;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = MT9M001_COLUMN_SKIP;
- a->bounds.top = MT9M001_ROW_SKIP;
- a->bounds.width = MT9M001_MAX_WIDTH;
- a->bounds.height = MT9M001_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int mt9m001_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9m001 *mt9m001 = to_mt9m001(client);
-
- mf->width = mt9m001->rect.width;
- mf->height = mt9m001->rect.height;
- mf->code = mt9m001->fmt->code;
- mf->colorspace = mt9m001->fmt->colorspace;
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int mt9m001_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9m001 *mt9m001 = to_mt9m001(client);
- struct v4l2_crop a = {
- .c = {
- .left = mt9m001->rect.left,
- .top = mt9m001->rect.top,
- .width = mf->width,
- .height = mf->height,
- },
- };
- int ret;
-
- /* No support for scaling so far, just crop. TODO: use skipping */
- ret = mt9m001_s_crop(sd, &a);
- if (!ret) {
- mf->width = mt9m001->rect.width;
- mf->height = mt9m001->rect.height;
- mt9m001->fmt = mt9m001_find_datafmt(mf->code,
- mt9m001->fmts, mt9m001->num_fmts);
- mf->colorspace = mt9m001->fmt->colorspace;
- }
-
- return ret;
-}
-
-static int mt9m001_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9m001 *mt9m001 = to_mt9m001(client);
- const struct mt9m001_datafmt *fmt;
-
- v4l_bound_align_image(&mf->width, MT9M001_MIN_WIDTH,
- MT9M001_MAX_WIDTH, 1,
- &mf->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top,
- MT9M001_MAX_HEIGHT + mt9m001->y_skip_top, 0, 0);
-
- if (mt9m001->fmts == mt9m001_colour_fmts)
- mf->height = ALIGN(mf->height - 1, 2);
-
- fmt = mt9m001_find_datafmt(mf->code, mt9m001->fmts,
- mt9m001->num_fmts);
- if (!fmt) {
- fmt = mt9m001->fmt;
- mf->code = fmt->code;
- }
-
- mf->colorspace = fmt->colorspace;
-
- return 0;
-}
-
-static int mt9m001_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9m001 *mt9m001 = to_mt9m001(client);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = mt9m001->model;
- id->revision = 0;
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9m001_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
- return -EINVAL;
-
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
- reg->size = 2;
- reg->val = reg_read(client, reg->reg);
-
- if (reg->val > 0xffff)
- return -EIO;
-
- return 0;
-}
-
-static int mt9m001_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
- return -EINVAL;
-
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
- if (reg_write(client, reg->reg, reg->val) < 0)
- return -EIO;
-
- return 0;
-}
-#endif
-
-static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct mt9m001 *mt9m001 = container_of(ctrl->handler,
- struct mt9m001, hdl);
- s32 min, max;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE_AUTO:
- min = mt9m001->exposure->minimum;
- max = mt9m001->exposure->maximum;
- mt9m001->exposure->val =
- (524 + (mt9m001->total_h - 1) * (max - min)) / 1048 + min;
- break;
- }
- return 0;
-}
-
-static int mt9m001_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct mt9m001 *mt9m001 = container_of(ctrl->handler,
- struct mt9m001, hdl);
- struct v4l2_subdev *sd = &mt9m001->subdev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct v4l2_ctrl *exp = mt9m001->exposure;
- int data;
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- if (ctrl->val)
- data = reg_set(client, MT9M001_READ_OPTIONS2, 0x8000);
- else
- data = reg_clear(client, MT9M001_READ_OPTIONS2, 0x8000);
- if (data < 0)
- return -EIO;
- return 0;
-
- case V4L2_CID_GAIN:
- /* See Datasheet Table 7, Gain settings. */
- if (ctrl->val <= ctrl->default_value) {
- /* Pack it into 0..1 step 0.125, register values 0..8 */
- unsigned long range = ctrl->default_value - ctrl->minimum;
- data = ((ctrl->val - ctrl->minimum) * 8 + range / 2) / range;
-
- dev_dbg(&client->dev, "Setting gain %d\n", data);
- data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
- if (data < 0)
- return -EIO;
- } else {
- /* Pack it into 1.125..15 variable step, register values 9..67 */
- /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
- unsigned long range = ctrl->maximum - ctrl->default_value - 1;
- unsigned long gain = ((ctrl->val - ctrl->default_value - 1) *
- 111 + range / 2) / range + 9;
-
- if (gain <= 32)
- data = gain;
- else if (gain <= 64)
- data = ((gain - 32) * 16 + 16) / 32 + 80;
- else
- data = ((gain - 64) * 7 + 28) / 56 + 96;
-
- dev_dbg(&client->dev, "Setting gain from %d to %d\n",
- reg_read(client, MT9M001_GLOBAL_GAIN), data);
- data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
- if (data < 0)
- return -EIO;
- }
- return 0;
-
- case V4L2_CID_EXPOSURE_AUTO:
- if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
- unsigned long range = exp->maximum - exp->minimum;
- unsigned long shutter = ((exp->val - exp->minimum) * 1048 +
- range / 2) / range + 1;
-
- dev_dbg(&client->dev,
- "Setting shutter width from %d to %lu\n",
- reg_read(client, MT9M001_SHUTTER_WIDTH), shutter);
- if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0)
- return -EIO;
- } else {
- const u16 vblank = 25;
-
- mt9m001->total_h = mt9m001->rect.height +
- mt9m001->y_skip_top + vblank;
- if (reg_write(client, MT9M001_SHUTTER_WIDTH, mt9m001->total_h) < 0)
- return -EIO;
- }
- return 0;
- }
- return -EINVAL;
-}
-
-/*
- * Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one
- */
-static int mt9m001_video_probe(struct soc_camera_link *icl,
- struct i2c_client *client)
-{
- struct mt9m001 *mt9m001 = to_mt9m001(client);
- s32 data;
- unsigned long flags;
- int ret;
-
- /* Enable the chip */
- data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
- dev_dbg(&client->dev, "write: %d\n", data);
-
- /* Read out the chip version register */
- data = reg_read(client, MT9M001_CHIP_VERSION);
-
- /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
- switch (data) {
- case 0x8411:
- case 0x8421:
- mt9m001->model = V4L2_IDENT_MT9M001C12ST;
- mt9m001->fmts = mt9m001_colour_fmts;
- break;
- case 0x8431:
- mt9m001->model = V4L2_IDENT_MT9M001C12STM;
- mt9m001->fmts = mt9m001_monochrome_fmts;
- break;
- default:
- dev_err(&client->dev,
- "No MT9M001 chip detected, register read %x\n", data);
- return -ENODEV;
- }
-
- mt9m001->num_fmts = 0;
-
- /*
- * This is a 10bit sensor, so by default we only allow 10bit.
- * The platform may support different bus widths due to
- * different routing of the data lines.
- */
- if (icl->query_bus_param)
- flags = icl->query_bus_param(icl);
- else
- flags = SOCAM_DATAWIDTH_10;
-
- if (flags & SOCAM_DATAWIDTH_10)
- mt9m001->num_fmts++;
- else
- mt9m001->fmts++;
-
- if (flags & SOCAM_DATAWIDTH_8)
- mt9m001->num_fmts++;
-
- mt9m001->fmt = &mt9m001->fmts[0];
-
- dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n", data,
- data == 0x8431 ? "C12STM" : "C12ST");
-
- ret = mt9m001_init(client);
- if (ret < 0)
- dev_err(&client->dev, "Failed to initialise the camera\n");
-
- /* mt9m001_init() has reset the chip, returning registers to defaults */
- return v4l2_ctrl_handler_setup(&mt9m001->hdl);
-}
-
-static void mt9m001_video_remove(struct soc_camera_link *icl)
-{
- if (icl->free_bus)
- icl->free_bus(icl);
-}
-
-static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9m001 *mt9m001 = to_mt9m001(client);
-
- *lines = mt9m001->y_skip_top;
-
- return 0;
-}
-
-static const struct v4l2_ctrl_ops mt9m001_ctrl_ops = {
- .g_volatile_ctrl = mt9m001_g_volatile_ctrl,
- .s_ctrl = mt9m001_s_ctrl,
-};
-
-static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
- .g_chip_ident = mt9m001_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = mt9m001_g_register,
- .s_register = mt9m001_s_register,
-#endif
-};
-
-static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9m001 *mt9m001 = to_mt9m001(client);
-
- if (index >= mt9m001->num_fmts)
- return -EINVAL;
-
- *code = mt9m001->fmts[index].code;
- return 0;
-}
-
-static int mt9m001_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- /* MT9M001 has all capture_format parameters fixed */
- cfg->flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
- V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_MASTER;
- cfg->type = V4L2_MBUS_PARALLEL;
- cfg->flags = soc_camera_apply_board_flags(icl, cfg);
-
- return 0;
-}
-
-static int mt9m001_s_mbus_config(struct v4l2_subdev *sd,
- const struct v4l2_mbus_config *cfg)
-{
- const struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- struct mt9m001 *mt9m001 = to_mt9m001(client);
- unsigned int bps = soc_mbus_get_fmtdesc(mt9m001->fmt->code)->bits_per_sample;
-
- if (icl->set_bus_param)
- return icl->set_bus_param(icl, 1 << (bps - 1));
-
- /*
- * Without board specific bus width settings we only support the
- * sensors native bus width
- */
- return bps == 10 ? 0 : -EINVAL;
-}
-
-static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
- .s_stream = mt9m001_s_stream,
- .s_mbus_fmt = mt9m001_s_fmt,
- .g_mbus_fmt = mt9m001_g_fmt,
- .try_mbus_fmt = mt9m001_try_fmt,
- .s_crop = mt9m001_s_crop,
- .g_crop = mt9m001_g_crop,
- .cropcap = mt9m001_cropcap,
- .enum_mbus_fmt = mt9m001_enum_fmt,
- .g_mbus_config = mt9m001_g_mbus_config,
- .s_mbus_config = mt9m001_s_mbus_config,
-};
-
-static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
- .g_skip_top_lines = mt9m001_g_skip_top_lines,
-};
-
-static struct v4l2_subdev_ops mt9m001_subdev_ops = {
- .core = &mt9m001_subdev_core_ops,
- .video = &mt9m001_subdev_video_ops,
- .sensor = &mt9m001_subdev_sensor_ops,
-};
-
-static int mt9m001_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct mt9m001 *mt9m001;
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- int ret;
-
- if (!icl) {
- dev_err(&client->dev, "MT9M001 driver needs platform data\n");
- return -EINVAL;
- }
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
- dev_warn(&adapter->dev,
- "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
- return -EIO;
- }
-
- mt9m001 = kzalloc(sizeof(struct mt9m001), GFP_KERNEL);
- if (!mt9m001)
- return -ENOMEM;
-
- v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops);
- v4l2_ctrl_handler_init(&mt9m001->hdl, 4);
- v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
- V4L2_CID_GAIN, 0, 127, 1, 64);
- mt9m001->exposure = v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
- V4L2_CID_EXPOSURE, 1, 255, 1, 255);
- /*
- * Simulated autoexposure. If enabled, we calculate shutter width
- * ourselves in the driver based on vertical blanking and frame width
- */
- mt9m001->autoexposure = v4l2_ctrl_new_std_menu(&mt9m001->hdl,
- &mt9m001_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
- V4L2_EXPOSURE_AUTO);
- mt9m001->subdev.ctrl_handler = &mt9m001->hdl;
- if (mt9m001->hdl.error) {
- int err = mt9m001->hdl.error;
-
- kfree(mt9m001);
- return err;
- }
- v4l2_ctrl_auto_cluster(2, &mt9m001->autoexposure,
- V4L2_EXPOSURE_MANUAL, true);
-
- /* Second stage probe - when a capture adapter is there */
- mt9m001->y_skip_top = 0;
- mt9m001->rect.left = MT9M001_COLUMN_SKIP;
- mt9m001->rect.top = MT9M001_ROW_SKIP;
- mt9m001->rect.width = MT9M001_MAX_WIDTH;
- mt9m001->rect.height = MT9M001_MAX_HEIGHT;
-
- ret = mt9m001_video_probe(icl, client);
- if (ret) {
- v4l2_ctrl_handler_free(&mt9m001->hdl);
- kfree(mt9m001);
- }
-
- return ret;
-}
-
-static int mt9m001_remove(struct i2c_client *client)
-{
- struct mt9m001 *mt9m001 = to_mt9m001(client);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- v4l2_device_unregister_subdev(&mt9m001->subdev);
- v4l2_ctrl_handler_free(&mt9m001->hdl);
- mt9m001_video_remove(icl);
- kfree(mt9m001);
-
- return 0;
-}
-
-static const struct i2c_device_id mt9m001_id[] = {
- { "mt9m001", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, mt9m001_id);
-
-static struct i2c_driver mt9m001_i2c_driver = {
- .driver = {
- .name = "mt9m001",
- },
- .probe = mt9m001_probe,
- .remove = mt9m001_remove,
- .id_table = mt9m001_id,
-};
-
-module_i2c_driver(mt9m001_i2c_driver);
-
-MODULE_DESCRIPTION("Micron MT9M001 Camera driver");
-MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/mt9m032.c b/drivers/media/video/mt9m032.c
deleted file mode 100644
index 445359c9611..00000000000
--- a/drivers/media/video/mt9m032.c
+++ /dev/null
@@ -1,878 +0,0 @@
-/*
- * Driver for MT9M032 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2010-2011 Lund Engineering
- * Contact: Gil Lund <gwlund@lundeng.com>
- * Author: Martin Hostettler <martin@neutronstar.dyndns.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/math64.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/v4l2-mediabus.h>
-
-#include <media/media-entity.h>
-#include <media/mt9m032.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-
-#include "aptina-pll.h"
-
-/*
- * width and height include active boundary and black parts
- *
- * column 0- 15 active boundary
- * column 16-1455 image
- * column 1456-1471 active boundary
- * column 1472-1599 black
- *
- * row 0- 51 black
- * row 53- 59 active boundary
- * row 60-1139 image
- * row 1140-1147 active boundary
- * row 1148-1151 black
- */
-
-#define MT9M032_PIXEL_ARRAY_WIDTH 1600
-#define MT9M032_PIXEL_ARRAY_HEIGHT 1152
-
-#define MT9M032_CHIP_VERSION 0x00
-#define MT9M032_CHIP_VERSION_VALUE 0x1402
-#define MT9M032_ROW_START 0x01
-#define MT9M032_ROW_START_MIN 0
-#define MT9M032_ROW_START_MAX 1152
-#define MT9M032_ROW_START_DEF 60
-#define MT9M032_COLUMN_START 0x02
-#define MT9M032_COLUMN_START_MIN 0
-#define MT9M032_COLUMN_START_MAX 1600
-#define MT9M032_COLUMN_START_DEF 16
-#define MT9M032_ROW_SIZE 0x03
-#define MT9M032_ROW_SIZE_MIN 32
-#define MT9M032_ROW_SIZE_MAX 1152
-#define MT9M032_ROW_SIZE_DEF 1080
-#define MT9M032_COLUMN_SIZE 0x04
-#define MT9M032_COLUMN_SIZE_MIN 32
-#define MT9M032_COLUMN_SIZE_MAX 1600
-#define MT9M032_COLUMN_SIZE_DEF 1440
-#define MT9M032_HBLANK 0x05
-#define MT9M032_VBLANK 0x06
-#define MT9M032_VBLANK_MAX 0x7ff
-#define MT9M032_SHUTTER_WIDTH_HIGH 0x08
-#define MT9M032_SHUTTER_WIDTH_LOW 0x09
-#define MT9M032_SHUTTER_WIDTH_MIN 1
-#define MT9M032_SHUTTER_WIDTH_MAX 1048575
-#define MT9M032_SHUTTER_WIDTH_DEF 1943
-#define MT9M032_PIX_CLK_CTRL 0x0a
-#define MT9M032_PIX_CLK_CTRL_INV_PIXCLK 0x8000
-#define MT9M032_RESTART 0x0b
-#define MT9M032_RESET 0x0d
-#define MT9M032_PLL_CONFIG1 0x11
-#define MT9M032_PLL_CONFIG1_OUTDIV_MASK 0x3f
-#define MT9M032_PLL_CONFIG1_MUL_SHIFT 8
-#define MT9M032_READ_MODE1 0x1e
-#define MT9M032_READ_MODE2 0x20
-#define MT9M032_READ_MODE2_VFLIP_SHIFT 15
-#define MT9M032_READ_MODE2_HFLIP_SHIFT 14
-#define MT9M032_READ_MODE2_ROW_BLC 0x40
-#define MT9M032_GAIN_GREEN1 0x2b
-#define MT9M032_GAIN_BLUE 0x2c
-#define MT9M032_GAIN_RED 0x2d
-#define MT9M032_GAIN_GREEN2 0x2e
-
-/* write only */
-#define MT9M032_GAIN_ALL 0x35
-#define MT9M032_GAIN_DIGITAL_MASK 0x7f
-#define MT9M032_GAIN_DIGITAL_SHIFT 8
-#define MT9M032_GAIN_AMUL_SHIFT 6
-#define MT9M032_GAIN_ANALOG_MASK 0x3f
-#define MT9M032_FORMATTER1 0x9e
-#define MT9M032_FORMATTER2 0x9f
-#define MT9M032_FORMATTER2_DOUT_EN 0x1000
-#define MT9M032_FORMATTER2_PIXCLK_EN 0x2000
-
-/*
- * The available MT9M032 datasheet is missing documentation for register 0x10
- * MT9P031 seems to be close enough, so use constants from that datasheet for
- * now.
- * But keep the name MT9P031 to remind us, that this isn't really confirmed
- * for this sensor.
- */
-#define MT9P031_PLL_CONTROL 0x10
-#define MT9P031_PLL_CONTROL_PWROFF 0x0050
-#define MT9P031_PLL_CONTROL_PWRON 0x0051
-#define MT9P031_PLL_CONTROL_USEPLL 0x0052
-#define MT9P031_PLL_CONFIG2 0x11
-#define MT9P031_PLL_CONFIG2_P1_DIV_MASK 0x1f
-
-struct mt9m032 {
- struct v4l2_subdev subdev;
- struct media_pad pad;
- struct mt9m032_platform_data *pdata;
-
- unsigned int pix_clock;
-
- struct v4l2_ctrl_handler ctrls;
- struct {
- struct v4l2_ctrl *hflip;
- struct v4l2_ctrl *vflip;
- };
-
- struct mutex lock; /* Protects streaming, format, interval and crop */
-
- bool streaming;
-
- struct v4l2_mbus_framefmt format;
- struct v4l2_rect crop;
- struct v4l2_fract frame_interval;
-};
-
-#define to_mt9m032(sd) container_of(sd, struct mt9m032, subdev)
-#define to_dev(sensor) \
- (&((struct i2c_client *)v4l2_get_subdevdata(&(sensor)->subdev))->dev)
-
-static int mt9m032_read(struct i2c_client *client, u8 reg)
-{
- return i2c_smbus_read_word_swapped(client, reg);
-}
-
-static int mt9m032_write(struct i2c_client *client, u8 reg, const u16 data)
-{
- return i2c_smbus_write_word_swapped(client, reg, data);
-}
-
-static u32 mt9m032_row_time(struct mt9m032 *sensor, unsigned int width)
-{
- unsigned int effective_width;
- u32 ns;
-
- effective_width = width + 716; /* empirical value */
- ns = div_u64(1000000000ULL * effective_width, sensor->pix_clock);
- dev_dbg(to_dev(sensor), "MT9M032 line time: %u ns\n", ns);
- return ns;
-}
-
-static int mt9m032_update_timing(struct mt9m032 *sensor,
- struct v4l2_fract *interval)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
- struct v4l2_rect *crop = &sensor->crop;
- unsigned int min_vblank;
- unsigned int vblank;
- u32 row_time;
-
- if (!interval)
- interval = &sensor->frame_interval;
-
- row_time = mt9m032_row_time(sensor, crop->width);
-
- vblank = div_u64(1000000000ULL * interval->numerator,
- (u64)row_time * interval->denominator)
- - crop->height;
-
- if (vblank > MT9M032_VBLANK_MAX) {
- /* hardware limits to 11 bit values */
- interval->denominator = 1000;
- interval->numerator =
- div_u64((crop->height + MT9M032_VBLANK_MAX) *
- (u64)row_time * interval->denominator,
- 1000000000ULL);
- vblank = div_u64(1000000000ULL * interval->numerator,
- (u64)row_time * interval->denominator)
- - crop->height;
- }
- /* enforce minimal 1.6ms blanking time. */
- min_vblank = 1600000 / row_time;
- vblank = clamp_t(unsigned int, vblank, min_vblank, MT9M032_VBLANK_MAX);
-
- return mt9m032_write(client, MT9M032_VBLANK, vblank);
-}
-
-static int mt9m032_update_geom_timing(struct mt9m032 *sensor)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
- int ret;
-
- ret = mt9m032_write(client, MT9M032_COLUMN_SIZE,
- sensor->crop.width - 1);
- if (!ret)
- ret = mt9m032_write(client, MT9M032_ROW_SIZE,
- sensor->crop.height - 1);
- if (!ret)
- ret = mt9m032_write(client, MT9M032_COLUMN_START,
- sensor->crop.left);
- if (!ret)
- ret = mt9m032_write(client, MT9M032_ROW_START,
- sensor->crop.top);
- if (!ret)
- ret = mt9m032_update_timing(sensor, NULL);
- return ret;
-}
-
-static int update_formatter2(struct mt9m032 *sensor, bool streaming)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
- u16 reg_val = MT9M032_FORMATTER2_DOUT_EN
- | 0x0070; /* parts reserved! */
- /* possibly for changing to 14-bit mode */
-
- if (streaming)
- reg_val |= MT9M032_FORMATTER2_PIXCLK_EN; /* pixclock enable */
-
- return mt9m032_write(client, MT9M032_FORMATTER2, reg_val);
-}
-
-static int mt9m032_setup_pll(struct mt9m032 *sensor)
-{
- static const struct aptina_pll_limits limits = {
- .ext_clock_min = 8000000,
- .ext_clock_max = 16500000,
- .int_clock_min = 2000000,
- .int_clock_max = 24000000,
- .out_clock_min = 322000000,
- .out_clock_max = 693000000,
- .pix_clock_max = 99000000,
- .n_min = 1,
- .n_max = 64,
- .m_min = 16,
- .m_max = 255,
- .p1_min = 1,
- .p1_max = 128,
- };
-
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
- struct mt9m032_platform_data *pdata = sensor->pdata;
- struct aptina_pll pll;
- int ret;
-
- pll.ext_clock = pdata->ext_clock;
- pll.pix_clock = pdata->pix_clock;
-
- ret = aptina_pll_calculate(&client->dev, &limits, &pll);
- if (ret < 0)
- return ret;
-
- sensor->pix_clock = pdata->pix_clock;
-
- ret = mt9m032_write(client, MT9M032_PLL_CONFIG1,
- (pll.m << MT9M032_PLL_CONFIG1_MUL_SHIFT)
- | (pll.p1 - 1));
- if (!ret)
- ret = mt9m032_write(client, MT9P031_PLL_CONFIG2, pll.n - 1);
- if (!ret)
- ret = mt9m032_write(client, MT9P031_PLL_CONTROL,
- MT9P031_PLL_CONTROL_PWRON |
- MT9P031_PLL_CONTROL_USEPLL);
- if (!ret) /* more reserved, Continuous, Master Mode */
- ret = mt9m032_write(client, MT9M032_READ_MODE1, 0x8006);
- if (!ret) /* Set 14-bit mode, select 7 divider */
- ret = mt9m032_write(client, MT9M032_FORMATTER1, 0x111e);
-
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * Subdev pad operations
- */
-
-static int mt9m032_enum_mbus_code(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- if (code->index != 0)
- return -EINVAL;
-
- code->code = V4L2_MBUS_FMT_Y8_1X8;
- return 0;
-}
-
-static int mt9m032_enum_frame_size(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_frame_size_enum *fse)
-{
- if (fse->index != 0 || fse->code != V4L2_MBUS_FMT_Y8_1X8)
- return -EINVAL;
-
- fse->min_width = MT9M032_COLUMN_SIZE_DEF;
- fse->max_width = MT9M032_COLUMN_SIZE_DEF;
- fse->min_height = MT9M032_ROW_SIZE_DEF;
- fse->max_height = MT9M032_ROW_SIZE_DEF;
-
- return 0;
-}
-
-/**
- * __mt9m032_get_pad_crop() - get crop rect
- * @sensor: pointer to the sensor struct
- * @fh: file handle for getting the try crop rect from
- * @which: select try or active crop rect
- *
- * Returns a pointer the current active or fh relative try crop rect
- */
-static struct v4l2_rect *
-__mt9m032_get_pad_crop(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh,
- enum v4l2_subdev_format_whence which)
-{
- switch (which) {
- case V4L2_SUBDEV_FORMAT_TRY:
- return v4l2_subdev_get_try_crop(fh, 0);
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- return &sensor->crop;
- default:
- return NULL;
- }
-}
-
-/**
- * __mt9m032_get_pad_format() - get format
- * @sensor: pointer to the sensor struct
- * @fh: file handle for getting the try format from
- * @which: select try or active format
- *
- * Returns a pointer the current active or fh relative try format
- */
-static struct v4l2_mbus_framefmt *
-__mt9m032_get_pad_format(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh,
- enum v4l2_subdev_format_whence which)
-{
- switch (which) {
- case V4L2_SUBDEV_FORMAT_TRY:
- return v4l2_subdev_get_try_format(fh, 0);
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- return &sensor->format;
- default:
- return NULL;
- }
-}
-
-static int mt9m032_get_pad_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct mt9m032 *sensor = to_mt9m032(subdev);
-
- mutex_lock(&sensor->lock);
- fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which);
- mutex_unlock(&sensor->lock);
-
- return 0;
-}
-
-static int mt9m032_set_pad_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct mt9m032 *sensor = to_mt9m032(subdev);
- int ret;
-
- mutex_lock(&sensor->lock);
-
- if (sensor->streaming && fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- ret = -EBUSY;
- goto done;
- }
-
- /* Scaling is not supported, the format is thus fixed. */
- fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which);
- ret = 0;
-
-done:
- mutex_unlock(&sensor->lock);
- return ret;
-}
-
-static int mt9m032_get_pad_crop(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_crop *crop)
-{
- struct mt9m032 *sensor = to_mt9m032(subdev);
-
- mutex_lock(&sensor->lock);
- crop->rect = *__mt9m032_get_pad_crop(sensor, fh, crop->which);
- mutex_unlock(&sensor->lock);
-
- return 0;
-}
-
-static int mt9m032_set_pad_crop(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_crop *crop)
-{
- struct mt9m032 *sensor = to_mt9m032(subdev);
- struct v4l2_mbus_framefmt *format;
- struct v4l2_rect *__crop;
- struct v4l2_rect rect;
- int ret = 0;
-
- mutex_lock(&sensor->lock);
-
- if (sensor->streaming && crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- ret = -EBUSY;
- goto done;
- }
-
- /* Clamp the crop rectangle boundaries and align them to a multiple of 2
- * pixels to ensure a GRBG Bayer pattern.
- */
- rect.left = clamp(ALIGN(crop->rect.left, 2), MT9M032_COLUMN_START_MIN,
- MT9M032_COLUMN_START_MAX);
- rect.top = clamp(ALIGN(crop->rect.top, 2), MT9M032_ROW_START_MIN,
- MT9M032_ROW_START_MAX);
- rect.width = clamp(ALIGN(crop->rect.width, 2), MT9M032_COLUMN_SIZE_MIN,
- MT9M032_COLUMN_SIZE_MAX);
- rect.height = clamp(ALIGN(crop->rect.height, 2), MT9M032_ROW_SIZE_MIN,
- MT9M032_ROW_SIZE_MAX);
-
- rect.width = min(rect.width, MT9M032_PIXEL_ARRAY_WIDTH - rect.left);
- rect.height = min(rect.height, MT9M032_PIXEL_ARRAY_HEIGHT - rect.top);
-
- __crop = __mt9m032_get_pad_crop(sensor, fh, crop->which);
-
- if (rect.width != __crop->width || rect.height != __crop->height) {
- /* Reset the output image size if the crop rectangle size has
- * been modified.
- */
- format = __mt9m032_get_pad_format(sensor, fh, crop->which);
- format->width = rect.width;
- format->height = rect.height;
- }
-
- *__crop = rect;
- crop->rect = rect;
-
- if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE)
- ret = mt9m032_update_geom_timing(sensor);
-
-done:
- mutex_unlock(&sensor->lock);
- return ret;
-}
-
-static int mt9m032_get_frame_interval(struct v4l2_subdev *subdev,
- struct v4l2_subdev_frame_interval *fi)
-{
- struct mt9m032 *sensor = to_mt9m032(subdev);
-
- mutex_lock(&sensor->lock);
- memset(fi, 0, sizeof(*fi));
- fi->interval = sensor->frame_interval;
- mutex_unlock(&sensor->lock);
-
- return 0;
-}
-
-static int mt9m032_set_frame_interval(struct v4l2_subdev *subdev,
- struct v4l2_subdev_frame_interval *fi)
-{
- struct mt9m032 *sensor = to_mt9m032(subdev);
- int ret;
-
- mutex_lock(&sensor->lock);
-
- if (sensor->streaming) {
- ret = -EBUSY;
- goto done;
- }
-
- /* Avoid divisions by 0. */
- if (fi->interval.denominator == 0)
- fi->interval.denominator = 1;
-
- ret = mt9m032_update_timing(sensor, &fi->interval);
- if (!ret)
- sensor->frame_interval = fi->interval;
-
-done:
- mutex_unlock(&sensor->lock);
- return ret;
-}
-
-static int mt9m032_s_stream(struct v4l2_subdev *subdev, int streaming)
-{
- struct mt9m032 *sensor = to_mt9m032(subdev);
- int ret;
-
- mutex_lock(&sensor->lock);
- ret = update_formatter2(sensor, streaming);
- if (!ret)
- sensor->streaming = streaming;
- mutex_unlock(&sensor->lock);
-
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev core operations
- */
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9m032_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct mt9m032 *sensor = to_mt9m032(sd);
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
- int val;
-
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
- return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
- val = mt9m032_read(client, reg->reg);
- if (val < 0)
- return -EIO;
-
- reg->size = 2;
- reg->val = val;
-
- return 0;
-}
-
-static int mt9m032_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct mt9m032 *sensor = to_mt9m032(sd);
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
-
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
- return -EINVAL;
-
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
- return mt9m032_write(client, reg->reg, reg->val);
-}
-#endif
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev control operations
- */
-
-static int update_read_mode2(struct mt9m032 *sensor, bool vflip, bool hflip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
- int reg_val = (vflip << MT9M032_READ_MODE2_VFLIP_SHIFT)
- | (hflip << MT9M032_READ_MODE2_HFLIP_SHIFT)
- | MT9M032_READ_MODE2_ROW_BLC
- | 0x0007;
-
- return mt9m032_write(client, MT9M032_READ_MODE2, reg_val);
-}
-
-static int mt9m032_set_gain(struct mt9m032 *sensor, s32 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
- int digital_gain_val; /* in 1/8th (0..127) */
- int analog_mul; /* 0 or 1 */
- int analog_gain_val; /* in 1/16th. (0..63) */
- u16 reg_val;
-
- digital_gain_val = 51; /* from setup example */
-
- if (val < 63) {
- analog_mul = 0;
- analog_gain_val = val;
- } else {
- analog_mul = 1;
- analog_gain_val = val / 2;
- }
-
- /* a_gain = (1 + analog_mul) + (analog_gain_val + 1) / 16 */
- /* overall_gain = a_gain * (1 + digital_gain_val / 8) */
-
- reg_val = ((digital_gain_val & MT9M032_GAIN_DIGITAL_MASK)
- << MT9M032_GAIN_DIGITAL_SHIFT)
- | ((analog_mul & 1) << MT9M032_GAIN_AMUL_SHIFT)
- | (analog_gain_val & MT9M032_GAIN_ANALOG_MASK);
-
- return mt9m032_write(client, MT9M032_GAIN_ALL, reg_val);
-}
-
-static int mt9m032_try_ctrl(struct v4l2_ctrl *ctrl)
-{
- if (ctrl->id == V4L2_CID_GAIN && ctrl->val >= 63) {
- /* round because of multiplier used for values >= 63 */
- ctrl->val &= ~1;
- }
-
- return 0;
-}
-
-static int mt9m032_set_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct mt9m032 *sensor =
- container_of(ctrl->handler, struct mt9m032, ctrls);
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
- int ret;
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- return mt9m032_set_gain(sensor, ctrl->val);
-
- case V4L2_CID_HFLIP:
- /* case V4L2_CID_VFLIP: -- In the same cluster */
- return update_read_mode2(sensor, sensor->vflip->val,
- sensor->hflip->val);
-
- case V4L2_CID_EXPOSURE:
- ret = mt9m032_write(client, MT9M032_SHUTTER_WIDTH_HIGH,
- (ctrl->val >> 16) & 0xffff);
- if (ret < 0)
- return ret;
-
- return mt9m032_write(client, MT9M032_SHUTTER_WIDTH_LOW,
- ctrl->val & 0xffff);
- }
-
- return 0;
-}
-
-static struct v4l2_ctrl_ops mt9m032_ctrl_ops = {
- .s_ctrl = mt9m032_set_ctrl,
- .try_ctrl = mt9m032_try_ctrl,
-};
-
-/* -------------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops mt9m032_core_ops = {
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = mt9m032_g_register,
- .s_register = mt9m032_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_video_ops mt9m032_video_ops = {
- .s_stream = mt9m032_s_stream,
- .g_frame_interval = mt9m032_get_frame_interval,
- .s_frame_interval = mt9m032_set_frame_interval,
-};
-
-static const struct v4l2_subdev_pad_ops mt9m032_pad_ops = {
- .enum_mbus_code = mt9m032_enum_mbus_code,
- .enum_frame_size = mt9m032_enum_frame_size,
- .get_fmt = mt9m032_get_pad_format,
- .set_fmt = mt9m032_set_pad_format,
- .set_crop = mt9m032_set_pad_crop,
- .get_crop = mt9m032_get_pad_crop,
-};
-
-static const struct v4l2_subdev_ops mt9m032_ops = {
- .core = &mt9m032_core_ops,
- .video = &mt9m032_video_ops,
- .pad = &mt9m032_pad_ops,
-};
-
-/* -----------------------------------------------------------------------------
- * Driver initialization and probing
- */
-
-static int mt9m032_probe(struct i2c_client *client,
- const struct i2c_device_id *devid)
-{
- struct mt9m032_platform_data *pdata = client->dev.platform_data;
- struct i2c_adapter *adapter = client->adapter;
- struct mt9m032 *sensor;
- int chip_version;
- int ret;
-
- if (pdata == NULL) {
- dev_err(&client->dev, "No platform data\n");
- return -EINVAL;
- }
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
- dev_warn(&client->dev,
- "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
- return -EIO;
- }
-
- if (!client->dev.platform_data)
- return -ENODEV;
-
- sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
- if (sensor == NULL)
- return -ENOMEM;
-
- mutex_init(&sensor->lock);
-
- sensor->pdata = pdata;
-
- v4l2_i2c_subdev_init(&sensor->subdev, client, &mt9m032_ops);
- sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- chip_version = mt9m032_read(client, MT9M032_CHIP_VERSION);
- if (chip_version != MT9M032_CHIP_VERSION_VALUE) {
- dev_err(&client->dev, "MT9M032 not detected, wrong version "
- "0x%04x\n", chip_version);
- ret = -ENODEV;
- goto error_sensor;
- }
-
- dev_info(&client->dev, "MT9M032 detected at address 0x%02x\n",
- client->addr);
-
- sensor->frame_interval.numerator = 1;
- sensor->frame_interval.denominator = 30;
-
- sensor->crop.left = MT9M032_COLUMN_START_DEF;
- sensor->crop.top = MT9M032_ROW_START_DEF;
- sensor->crop.width = MT9M032_COLUMN_SIZE_DEF;
- sensor->crop.height = MT9M032_ROW_SIZE_DEF;
-
- sensor->format.width = sensor->crop.width;
- sensor->format.height = sensor->crop.height;
- sensor->format.code = V4L2_MBUS_FMT_Y8_1X8;
- sensor->format.field = V4L2_FIELD_NONE;
- sensor->format.colorspace = V4L2_COLORSPACE_SRGB;
-
- v4l2_ctrl_handler_init(&sensor->ctrls, 5);
-
- v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
- V4L2_CID_GAIN, 0, 127, 1, 64);
-
- sensor->hflip = v4l2_ctrl_new_std(&sensor->ctrls,
- &mt9m032_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- sensor->vflip = v4l2_ctrl_new_std(&sensor->ctrls,
- &mt9m032_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
-
- v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
- V4L2_CID_EXPOSURE, MT9M032_SHUTTER_WIDTH_MIN,
- MT9M032_SHUTTER_WIDTH_MAX, 1,
- MT9M032_SHUTTER_WIDTH_DEF);
- v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
- V4L2_CID_PIXEL_RATE, pdata->pix_clock,
- pdata->pix_clock, 1, pdata->pix_clock);
-
- if (sensor->ctrls.error) {
- ret = sensor->ctrls.error;
- dev_err(&client->dev, "control initialization error %d\n", ret);
- goto error_ctrl;
- }
-
- v4l2_ctrl_cluster(2, &sensor->hflip);
-
- sensor->subdev.ctrl_handler = &sensor->ctrls;
- sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad, 0);
- if (ret < 0)
- goto error_ctrl;
-
- ret = mt9m032_write(client, MT9M032_RESET, 1); /* reset on */
- if (ret < 0)
- goto error_entity;
- mt9m032_write(client, MT9M032_RESET, 0); /* reset off */
- if (ret < 0)
- goto error_entity;
-
- ret = mt9m032_setup_pll(sensor);
- if (ret < 0)
- goto error_entity;
- usleep_range(10000, 11000);
-
- ret = v4l2_ctrl_handler_setup(&sensor->ctrls);
- if (ret < 0)
- goto error_entity;
-
- /* SIZE */
- ret = mt9m032_update_geom_timing(sensor);
- if (ret < 0)
- goto error_entity;
-
- ret = mt9m032_write(client, 0x41, 0x0000); /* reserved !!! */
- if (ret < 0)
- goto error_entity;
- ret = mt9m032_write(client, 0x42, 0x0003); /* reserved !!! */
- if (ret < 0)
- goto error_entity;
- ret = mt9m032_write(client, 0x43, 0x0003); /* reserved !!! */
- if (ret < 0)
- goto error_entity;
- ret = mt9m032_write(client, 0x7f, 0x0000); /* reserved !!! */
- if (ret < 0)
- goto error_entity;
- if (sensor->pdata->invert_pixclock) {
- ret = mt9m032_write(client, MT9M032_PIX_CLK_CTRL,
- MT9M032_PIX_CLK_CTRL_INV_PIXCLK);
- if (ret < 0)
- goto error_entity;
- }
-
- ret = mt9m032_write(client, MT9M032_RESTART, 1); /* Restart on */
- if (ret < 0)
- goto error_entity;
- msleep(100);
- ret = mt9m032_write(client, MT9M032_RESTART, 0); /* Restart off */
- if (ret < 0)
- goto error_entity;
- msleep(100);
- ret = update_formatter2(sensor, false);
- if (ret < 0)
- goto error_entity;
-
- return ret;
-
-error_entity:
- media_entity_cleanup(&sensor->subdev.entity);
-error_ctrl:
- v4l2_ctrl_handler_free(&sensor->ctrls);
-error_sensor:
- mutex_destroy(&sensor->lock);
- kfree(sensor);
- return ret;
-}
-
-static int mt9m032_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct mt9m032 *sensor = to_mt9m032(subdev);
-
- v4l2_device_unregister_subdev(subdev);
- v4l2_ctrl_handler_free(&sensor->ctrls);
- media_entity_cleanup(&subdev->entity);
- mutex_destroy(&sensor->lock);
- kfree(sensor);
- return 0;
-}
-
-static const struct i2c_device_id mt9m032_id_table[] = {
- { MT9M032_NAME, 0 },
- { }
-};
-
-MODULE_DEVICE_TABLE(i2c, mt9m032_id_table);
-
-static struct i2c_driver mt9m032_i2c_driver = {
- .driver = {
- .name = MT9M032_NAME,
- },
- .probe = mt9m032_probe,
- .remove = mt9m032_remove,
- .id_table = mt9m032_id_table,
-};
-
-module_i2c_driver(mt9m032_i2c_driver);
-
-MODULE_AUTHOR("Martin Hostettler <martin@neutronstar.dyndns.org>");
-MODULE_DESCRIPTION("MT9M032 camera sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
deleted file mode 100644
index 863d722dda0..00000000000
--- a/drivers/media/video/mt9m111.c
+++ /dev/null
@@ -1,1014 +0,0 @@
-/*
- * Driver for MT9M111/MT9M112/MT9M131 CMOS Image Sensor from Micron/Aptina
- *
- * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/module.h>
-
-#include <media/soc_camera.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
-
-/*
- * MT9M111, MT9M112 and MT9M131:
- * i2c address is 0x48 or 0x5d (depending on SADDR pin)
- * The platform has to define i2c_board_info and call i2c_register_board_info()
- */
-
-/*
- * Sensor core register addresses (0x000..0x0ff)
- */
-#define MT9M111_CHIP_VERSION 0x000
-#define MT9M111_ROW_START 0x001
-#define MT9M111_COLUMN_START 0x002
-#define MT9M111_WINDOW_HEIGHT 0x003
-#define MT9M111_WINDOW_WIDTH 0x004
-#define MT9M111_HORIZONTAL_BLANKING_B 0x005
-#define MT9M111_VERTICAL_BLANKING_B 0x006
-#define MT9M111_HORIZONTAL_BLANKING_A 0x007
-#define MT9M111_VERTICAL_BLANKING_A 0x008
-#define MT9M111_SHUTTER_WIDTH 0x009
-#define MT9M111_ROW_SPEED 0x00a
-#define MT9M111_EXTRA_DELAY 0x00b
-#define MT9M111_SHUTTER_DELAY 0x00c
-#define MT9M111_RESET 0x00d
-#define MT9M111_READ_MODE_B 0x020
-#define MT9M111_READ_MODE_A 0x021
-#define MT9M111_FLASH_CONTROL 0x023
-#define MT9M111_GREEN1_GAIN 0x02b
-#define MT9M111_BLUE_GAIN 0x02c
-#define MT9M111_RED_GAIN 0x02d
-#define MT9M111_GREEN2_GAIN 0x02e
-#define MT9M111_GLOBAL_GAIN 0x02f
-#define MT9M111_CONTEXT_CONTROL 0x0c8
-#define MT9M111_PAGE_MAP 0x0f0
-#define MT9M111_BYTE_WISE_ADDR 0x0f1
-
-#define MT9M111_RESET_SYNC_CHANGES (1 << 15)
-#define MT9M111_RESET_RESTART_BAD_FRAME (1 << 9)
-#define MT9M111_RESET_SHOW_BAD_FRAMES (1 << 8)
-#define MT9M111_RESET_RESET_SOC (1 << 5)
-#define MT9M111_RESET_OUTPUT_DISABLE (1 << 4)
-#define MT9M111_RESET_CHIP_ENABLE (1 << 3)
-#define MT9M111_RESET_ANALOG_STANDBY (1 << 2)
-#define MT9M111_RESET_RESTART_FRAME (1 << 1)
-#define MT9M111_RESET_RESET_MODE (1 << 0)
-
-#define MT9M111_RM_FULL_POWER_RD (0 << 10)
-#define MT9M111_RM_LOW_POWER_RD (1 << 10)
-#define MT9M111_RM_COL_SKIP_4X (1 << 5)
-#define MT9M111_RM_ROW_SKIP_4X (1 << 4)
-#define MT9M111_RM_COL_SKIP_2X (1 << 3)
-#define MT9M111_RM_ROW_SKIP_2X (1 << 2)
-#define MT9M111_RMB_MIRROR_COLS (1 << 1)
-#define MT9M111_RMB_MIRROR_ROWS (1 << 0)
-#define MT9M111_CTXT_CTRL_RESTART (1 << 15)
-#define MT9M111_CTXT_CTRL_DEFECTCOR_B (1 << 12)
-#define MT9M111_CTXT_CTRL_RESIZE_B (1 << 10)
-#define MT9M111_CTXT_CTRL_CTRL2_B (1 << 9)
-#define MT9M111_CTXT_CTRL_GAMMA_B (1 << 8)
-#define MT9M111_CTXT_CTRL_XENON_EN (1 << 7)
-#define MT9M111_CTXT_CTRL_READ_MODE_B (1 << 3)
-#define MT9M111_CTXT_CTRL_LED_FLASH_EN (1 << 2)
-#define MT9M111_CTXT_CTRL_VBLANK_SEL_B (1 << 1)
-#define MT9M111_CTXT_CTRL_HBLANK_SEL_B (1 << 0)
-
-/*
- * Colorpipe register addresses (0x100..0x1ff)
- */
-#define MT9M111_OPER_MODE_CTRL 0x106
-#define MT9M111_OUTPUT_FORMAT_CTRL 0x108
-#define MT9M111_REDUCER_XZOOM_B 0x1a0
-#define MT9M111_REDUCER_XSIZE_B 0x1a1
-#define MT9M111_REDUCER_YZOOM_B 0x1a3
-#define MT9M111_REDUCER_YSIZE_B 0x1a4
-#define MT9M111_REDUCER_XZOOM_A 0x1a6
-#define MT9M111_REDUCER_XSIZE_A 0x1a7
-#define MT9M111_REDUCER_YZOOM_A 0x1a9
-#define MT9M111_REDUCER_YSIZE_A 0x1aa
-
-#define MT9M111_OUTPUT_FORMAT_CTRL2_A 0x13a
-#define MT9M111_OUTPUT_FORMAT_CTRL2_B 0x19b
-
-#define MT9M111_OPMODE_AUTOEXPO_EN (1 << 14)
-#define MT9M111_OPMODE_AUTOWHITEBAL_EN (1 << 1)
-#define MT9M111_OUTFMT_FLIP_BAYER_COL (1 << 9)
-#define MT9M111_OUTFMT_FLIP_BAYER_ROW (1 << 8)
-#define MT9M111_OUTFMT_PROCESSED_BAYER (1 << 14)
-#define MT9M111_OUTFMT_BYPASS_IFP (1 << 10)
-#define MT9M111_OUTFMT_INV_PIX_CLOCK (1 << 9)
-#define MT9M111_OUTFMT_RGB (1 << 8)
-#define MT9M111_OUTFMT_RGB565 (0 << 6)
-#define MT9M111_OUTFMT_RGB555 (1 << 6)
-#define MT9M111_OUTFMT_RGB444x (2 << 6)
-#define MT9M111_OUTFMT_RGBx444 (3 << 6)
-#define MT9M111_OUTFMT_TST_RAMP_OFF (0 << 4)
-#define MT9M111_OUTFMT_TST_RAMP_COL (1 << 4)
-#define MT9M111_OUTFMT_TST_RAMP_ROW (2 << 4)
-#define MT9M111_OUTFMT_TST_RAMP_FRAME (3 << 4)
-#define MT9M111_OUTFMT_SHIFT_3_UP (1 << 3)
-#define MT9M111_OUTFMT_AVG_CHROMA (1 << 2)
-#define MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN (1 << 1)
-#define MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B (1 << 0)
-
-/*
- * Camera control register addresses (0x200..0x2ff not implemented)
- */
-
-#define reg_read(reg) mt9m111_reg_read(client, MT9M111_##reg)
-#define reg_write(reg, val) mt9m111_reg_write(client, MT9M111_##reg, (val))
-#define reg_set(reg, val) mt9m111_reg_set(client, MT9M111_##reg, (val))
-#define reg_clear(reg, val) mt9m111_reg_clear(client, MT9M111_##reg, (val))
-#define reg_mask(reg, val, mask) mt9m111_reg_mask(client, MT9M111_##reg, \
- (val), (mask))
-
-#define MT9M111_MIN_DARK_ROWS 8
-#define MT9M111_MIN_DARK_COLS 26
-#define MT9M111_MAX_HEIGHT 1024
-#define MT9M111_MAX_WIDTH 1280
-
-struct mt9m111_context {
- u16 read_mode;
- u16 blanking_h;
- u16 blanking_v;
- u16 reducer_xzoom;
- u16 reducer_yzoom;
- u16 reducer_xsize;
- u16 reducer_ysize;
- u16 output_fmt_ctrl2;
- u16 control;
-};
-
-static struct mt9m111_context context_a = {
- .read_mode = MT9M111_READ_MODE_A,
- .blanking_h = MT9M111_HORIZONTAL_BLANKING_A,
- .blanking_v = MT9M111_VERTICAL_BLANKING_A,
- .reducer_xzoom = MT9M111_REDUCER_XZOOM_A,
- .reducer_yzoom = MT9M111_REDUCER_YZOOM_A,
- .reducer_xsize = MT9M111_REDUCER_XSIZE_A,
- .reducer_ysize = MT9M111_REDUCER_YSIZE_A,
- .output_fmt_ctrl2 = MT9M111_OUTPUT_FORMAT_CTRL2_A,
- .control = MT9M111_CTXT_CTRL_RESTART,
-};
-
-static struct mt9m111_context context_b = {
- .read_mode = MT9M111_READ_MODE_B,
- .blanking_h = MT9M111_HORIZONTAL_BLANKING_B,
- .blanking_v = MT9M111_VERTICAL_BLANKING_B,
- .reducer_xzoom = MT9M111_REDUCER_XZOOM_B,
- .reducer_yzoom = MT9M111_REDUCER_YZOOM_B,
- .reducer_xsize = MT9M111_REDUCER_XSIZE_B,
- .reducer_ysize = MT9M111_REDUCER_YSIZE_B,
- .output_fmt_ctrl2 = MT9M111_OUTPUT_FORMAT_CTRL2_B,
- .control = MT9M111_CTXT_CTRL_RESTART |
- MT9M111_CTXT_CTRL_DEFECTCOR_B | MT9M111_CTXT_CTRL_RESIZE_B |
- MT9M111_CTXT_CTRL_CTRL2_B | MT9M111_CTXT_CTRL_GAMMA_B |
- MT9M111_CTXT_CTRL_READ_MODE_B | MT9M111_CTXT_CTRL_VBLANK_SEL_B |
- MT9M111_CTXT_CTRL_HBLANK_SEL_B,
-};
-
-/* MT9M111 has only one fixed colorspace per pixelcode */
-struct mt9m111_datafmt {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
-};
-
-static const struct mt9m111_datafmt mt9m111_colour_fmts[] = {
- {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG},
- {V4L2_MBUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG},
- {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},
- {V4L2_MBUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG},
- {V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_BGR565_2X8_LE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_BGR565_2X8_BE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB},
-};
-
-struct mt9m111 {
- struct v4l2_subdev subdev;
- struct v4l2_ctrl_handler hdl;
- struct v4l2_ctrl *gain;
- int model; /* V4L2_IDENT_MT9M111 or V4L2_IDENT_MT9M112 code
- * from v4l2-chip-ident.h */
- struct mt9m111_context *ctx;
- struct v4l2_rect rect; /* cropping rectangle */
- int width; /* output */
- int height; /* sizes */
- struct mutex power_lock; /* lock to protect power_count */
- int power_count;
- const struct mt9m111_datafmt *fmt;
- int lastpage; /* PageMap cache value */
-};
-
-/* Find a data format by a pixel code */
-static const struct mt9m111_datafmt *mt9m111_find_datafmt(struct mt9m111 *mt9m111,
- enum v4l2_mbus_pixelcode code)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(mt9m111_colour_fmts); i++)
- if (mt9m111_colour_fmts[i].code == code)
- return mt9m111_colour_fmts + i;
-
- return mt9m111->fmt;
-}
-
-static struct mt9m111 *to_mt9m111(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client), struct mt9m111, subdev);
-}
-
-static int reg_page_map_set(struct i2c_client *client, const u16 reg)
-{
- int ret;
- u16 page;
- struct mt9m111 *mt9m111 = to_mt9m111(client);
-
- page = (reg >> 8);
- if (page == mt9m111->lastpage)
- return 0;
- if (page > 2)
- return -EINVAL;
-
- ret = i2c_smbus_write_word_swapped(client, MT9M111_PAGE_MAP, page);
- if (!ret)
- mt9m111->lastpage = page;
- return ret;
-}
-
-static int mt9m111_reg_read(struct i2c_client *client, const u16 reg)
-{
- int ret;
-
- ret = reg_page_map_set(client, reg);
- if (!ret)
- ret = i2c_smbus_read_word_swapped(client, reg & 0xff);
-
- dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret);
- return ret;
-}
-
-static int mt9m111_reg_write(struct i2c_client *client, const u16 reg,
- const u16 data)
-{
- int ret;
-
- ret = reg_page_map_set(client, reg);
- if (!ret)
- ret = i2c_smbus_write_word_swapped(client, reg & 0xff, data);
- dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret);
- return ret;
-}
-
-static int mt9m111_reg_set(struct i2c_client *client, const u16 reg,
- const u16 data)
-{
- int ret;
-
- ret = mt9m111_reg_read(client, reg);
- if (ret >= 0)
- ret = mt9m111_reg_write(client, reg, ret | data);
- return ret;
-}
-
-static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg,
- const u16 data)
-{
- int ret;
-
- ret = mt9m111_reg_read(client, reg);
- if (ret >= 0)
- ret = mt9m111_reg_write(client, reg, ret & ~data);
- return ret;
-}
-
-static int mt9m111_reg_mask(struct i2c_client *client, const u16 reg,
- const u16 data, const u16 mask)
-{
- int ret;
-
- ret = mt9m111_reg_read(client, reg);
- if (ret >= 0)
- ret = mt9m111_reg_write(client, reg, (ret & ~mask) | data);
- return ret;
-}
-
-static int mt9m111_set_context(struct mt9m111 *mt9m111,
- struct mt9m111_context *ctx)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
- return reg_write(CONTEXT_CONTROL, ctx->control);
-}
-
-static int mt9m111_setup_rect_ctx(struct mt9m111 *mt9m111,
- struct mt9m111_context *ctx, struct v4l2_rect *rect,
- unsigned int width, unsigned int height)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
- int ret = mt9m111_reg_write(client, ctx->reducer_xzoom, rect->width);
- if (!ret)
- ret = mt9m111_reg_write(client, ctx->reducer_yzoom, rect->height);
- if (!ret)
- ret = mt9m111_reg_write(client, ctx->reducer_xsize, width);
- if (!ret)
- ret = mt9m111_reg_write(client, ctx->reducer_ysize, height);
- return ret;
-}
-
-static int mt9m111_setup_geometry(struct mt9m111 *mt9m111, struct v4l2_rect *rect,
- int width, int height, enum v4l2_mbus_pixelcode code)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
- int ret;
-
- ret = reg_write(COLUMN_START, rect->left);
- if (!ret)
- ret = reg_write(ROW_START, rect->top);
-
- if (!ret)
- ret = reg_write(WINDOW_WIDTH, rect->width);
- if (!ret)
- ret = reg_write(WINDOW_HEIGHT, rect->height);
-
- if (code != V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) {
- /* IFP in use, down-scaling possible */
- if (!ret)
- ret = mt9m111_setup_rect_ctx(mt9m111, &context_b,
- rect, width, height);
- if (!ret)
- ret = mt9m111_setup_rect_ctx(mt9m111, &context_a,
- rect, width, height);
- }
-
- dev_dbg(&client->dev, "%s(%x): %ux%u@%u:%u -> %ux%u = %d\n",
- __func__, code, rect->width, rect->height, rect->left, rect->top,
- width, height, ret);
-
- return ret;
-}
-
-static int mt9m111_enable(struct mt9m111 *mt9m111)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
- return reg_write(RESET, MT9M111_RESET_CHIP_ENABLE);
-}
-
-static int mt9m111_reset(struct mt9m111 *mt9m111)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
- int ret;
-
- ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
- if (!ret)
- ret = reg_set(RESET, MT9M111_RESET_RESET_SOC);
- if (!ret)
- ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE
- | MT9M111_RESET_RESET_SOC);
-
- return ret;
-}
-
-static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct v4l2_rect rect = a->c;
- struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
- int width, height;
- int ret;
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 ||
- mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) {
- /* Bayer format - even size lengths */
- rect.width = ALIGN(rect.width, 2);
- rect.height = ALIGN(rect.height, 2);
- /* Let the user play with the starting pixel */
- }
-
- /* FIXME: the datasheet doesn't specify minimum sizes */
- soc_camera_limit_side(&rect.left, &rect.width,
- MT9M111_MIN_DARK_COLS, 2, MT9M111_MAX_WIDTH);
-
- soc_camera_limit_side(&rect.top, &rect.height,
- MT9M111_MIN_DARK_ROWS, 2, MT9M111_MAX_HEIGHT);
-
- width = min(mt9m111->width, rect.width);
- height = min(mt9m111->height, rect.height);
-
- ret = mt9m111_setup_geometry(mt9m111, &rect, width, height, mt9m111->fmt->code);
- if (!ret) {
- mt9m111->rect = rect;
- mt9m111->width = width;
- mt9m111->height = height;
- }
-
- return ret;
-}
-
-static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
-
- a->c = mt9m111->rect;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- a->bounds.left = MT9M111_MIN_DARK_COLS;
- a->bounds.top = MT9M111_MIN_DARK_ROWS;
- a->bounds.width = MT9M111_MAX_WIDTH;
- a->bounds.height = MT9M111_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int mt9m111_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
-
- mf->width = mt9m111->width;
- mf->height = mt9m111->height;
- mf->code = mt9m111->fmt->code;
- mf->colorspace = mt9m111->fmt->colorspace;
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int mt9m111_set_pixfmt(struct mt9m111 *mt9m111,
- enum v4l2_mbus_pixelcode code)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
- u16 data_outfmt2, mask_outfmt2 = MT9M111_OUTFMT_PROCESSED_BAYER |
- MT9M111_OUTFMT_BYPASS_IFP | MT9M111_OUTFMT_RGB |
- MT9M111_OUTFMT_RGB565 | MT9M111_OUTFMT_RGB555 |
- MT9M111_OUTFMT_RGB444x | MT9M111_OUTFMT_RGBx444 |
- MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN |
- MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B;
- int ret;
-
- switch (code) {
- case V4L2_MBUS_FMT_SBGGR8_1X8:
- data_outfmt2 = MT9M111_OUTFMT_PROCESSED_BAYER |
- MT9M111_OUTFMT_RGB;
- break;
- case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE:
- data_outfmt2 = MT9M111_OUTFMT_BYPASS_IFP | MT9M111_OUTFMT_RGB;
- break;
- case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
- data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555 |
- MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN;
- break;
- case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE:
- data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555;
- break;
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565 |
- MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN;
- break;
- case V4L2_MBUS_FMT_RGB565_2X8_BE:
- data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565;
- break;
- case V4L2_MBUS_FMT_BGR565_2X8_BE:
- data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565 |
- MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B;
- break;
- case V4L2_MBUS_FMT_BGR565_2X8_LE:
- data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565 |
- MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN |
- MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B;
- break;
- case V4L2_MBUS_FMT_UYVY8_2X8:
- data_outfmt2 = 0;
- break;
- case V4L2_MBUS_FMT_VYUY8_2X8:
- data_outfmt2 = MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B;
- break;
- case V4L2_MBUS_FMT_YUYV8_2X8:
- data_outfmt2 = MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN;
- break;
- case V4L2_MBUS_FMT_YVYU8_2X8:
- data_outfmt2 = MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN |
- MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B;
- break;
- default:
- dev_err(&client->dev, "Pixel format not handled: %x\n", code);
- return -EINVAL;
- }
-
- ret = mt9m111_reg_mask(client, context_a.output_fmt_ctrl2,
- data_outfmt2, mask_outfmt2);
- if (!ret)
- ret = mt9m111_reg_mask(client, context_b.output_fmt_ctrl2,
- data_outfmt2, mask_outfmt2);
-
- return ret;
-}
-
-static int mt9m111_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
- const struct mt9m111_datafmt *fmt;
- struct v4l2_rect *rect = &mt9m111->rect;
- bool bayer;
-
- fmt = mt9m111_find_datafmt(mt9m111, mf->code);
-
- bayer = fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 ||
- fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE;
-
- /*
- * With Bayer format enforce even side lengths, but let the user play
- * with the starting pixel
- */
- if (bayer) {
- rect->width = ALIGN(rect->width, 2);
- rect->height = ALIGN(rect->height, 2);
- }
-
- if (fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) {
- /* IFP bypass mode, no scaling */
- mf->width = rect->width;
- mf->height = rect->height;
- } else {
- /* No upscaling */
- if (mf->width > rect->width)
- mf->width = rect->width;
- if (mf->height > rect->height)
- mf->height = rect->height;
- }
-
- dev_dbg(&client->dev, "%s(): %ux%u, code=%x\n", __func__,
- mf->width, mf->height, fmt->code);
-
- mf->code = fmt->code;
- mf->colorspace = fmt->colorspace;
-
- return 0;
-}
-
-static int mt9m111_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- const struct mt9m111_datafmt *fmt;
- struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
- struct v4l2_rect *rect = &mt9m111->rect;
- int ret;
-
- mt9m111_try_fmt(sd, mf);
- fmt = mt9m111_find_datafmt(mt9m111, mf->code);
- /* try_fmt() guarantees fmt != NULL && fmt->code == mf->code */
-
- ret = mt9m111_setup_geometry(mt9m111, rect, mf->width, mf->height, mf->code);
- if (!ret)
- ret = mt9m111_set_pixfmt(mt9m111, mf->code);
- if (!ret) {
- mt9m111->width = mf->width;
- mt9m111->height = mf->height;
- mt9m111->fmt = fmt;
- }
-
- return ret;
-}
-
-static int mt9m111_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = mt9m111->model;
- id->revision = 0;
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9m111_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int val;
-
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
- return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
- val = mt9m111_reg_read(client, reg->reg);
- reg->size = 2;
- reg->val = (u64)val;
-
- if (reg->val > 0xffff)
- return -EIO;
-
- return 0;
-}
-
-static int mt9m111_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
- return -EINVAL;
-
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
- if (mt9m111_reg_write(client, reg->reg, reg->val) < 0)
- return -EIO;
-
- return 0;
-}
-#endif
-
-static int mt9m111_set_flip(struct mt9m111 *mt9m111, int flip, int mask)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
- int ret;
-
- if (flip)
- ret = mt9m111_reg_set(client, mt9m111->ctx->read_mode, mask);
- else
- ret = mt9m111_reg_clear(client, mt9m111->ctx->read_mode, mask);
-
- return ret;
-}
-
-static int mt9m111_get_global_gain(struct mt9m111 *mt9m111)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
- int data;
-
- data = reg_read(GLOBAL_GAIN);
- if (data >= 0)
- return (data & 0x2f) * (1 << ((data >> 10) & 1)) *
- (1 << ((data >> 9) & 1));
- return data;
-}
-
-static int mt9m111_set_global_gain(struct mt9m111 *mt9m111, int gain)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
- u16 val;
-
- if (gain > 63 * 2 * 2)
- return -EINVAL;
-
- if ((gain >= 64 * 2) && (gain < 63 * 2 * 2))
- val = (1 << 10) | (1 << 9) | (gain / 4);
- else if ((gain >= 64) && (gain < 64 * 2))
- val = (1 << 9) | (gain / 2);
- else
- val = gain;
-
- return reg_write(GLOBAL_GAIN, val);
-}
-
-static int mt9m111_set_autoexposure(struct mt9m111 *mt9m111, int on)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
-
- if (on)
- return reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
- return reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
-}
-
-static int mt9m111_set_autowhitebalance(struct mt9m111 *mt9m111, int on)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
-
- if (on)
- return reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
- return reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
-}
-
-static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct mt9m111 *mt9m111 = container_of(ctrl->handler,
- struct mt9m111, hdl);
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- return mt9m111_set_flip(mt9m111, ctrl->val,
- MT9M111_RMB_MIRROR_ROWS);
- case V4L2_CID_HFLIP:
- return mt9m111_set_flip(mt9m111, ctrl->val,
- MT9M111_RMB_MIRROR_COLS);
- case V4L2_CID_GAIN:
- return mt9m111_set_global_gain(mt9m111, ctrl->val);
- case V4L2_CID_EXPOSURE_AUTO:
- return mt9m111_set_autoexposure(mt9m111, ctrl->val);
- case V4L2_CID_AUTO_WHITE_BALANCE:
- return mt9m111_set_autowhitebalance(mt9m111, ctrl->val);
- }
-
- return -EINVAL;
-}
-
-static int mt9m111_suspend(struct mt9m111 *mt9m111)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
- int ret;
-
- v4l2_ctrl_s_ctrl(mt9m111->gain, mt9m111_get_global_gain(mt9m111));
-
- ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
- if (!ret)
- ret = reg_set(RESET, MT9M111_RESET_RESET_SOC |
- MT9M111_RESET_OUTPUT_DISABLE |
- MT9M111_RESET_ANALOG_STANDBY);
- if (!ret)
- ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
-
- return ret;
-}
-
-static void mt9m111_restore_state(struct mt9m111 *mt9m111)
-{
- mt9m111_set_context(mt9m111, mt9m111->ctx);
- mt9m111_set_pixfmt(mt9m111, mt9m111->fmt->code);
- mt9m111_setup_geometry(mt9m111, &mt9m111->rect,
- mt9m111->width, mt9m111->height, mt9m111->fmt->code);
- v4l2_ctrl_handler_setup(&mt9m111->hdl);
-}
-
-static int mt9m111_resume(struct mt9m111 *mt9m111)
-{
- int ret = mt9m111_enable(mt9m111);
- if (!ret)
- ret = mt9m111_reset(mt9m111);
- if (!ret)
- mt9m111_restore_state(mt9m111);
-
- return ret;
-}
-
-static int mt9m111_init(struct mt9m111 *mt9m111)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
- int ret;
-
- /* Default HIGHPOWER context */
- mt9m111->ctx = &context_b;
- ret = mt9m111_enable(mt9m111);
- if (!ret)
- ret = mt9m111_reset(mt9m111);
- if (!ret)
- ret = mt9m111_set_context(mt9m111, mt9m111->ctx);
- if (ret)
- dev_err(&client->dev, "mt9m111 init failed: %d\n", ret);
- return ret;
-}
-
-/*
- * Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one
- */
-static int mt9m111_video_probe(struct i2c_client *client)
-{
- struct mt9m111 *mt9m111 = to_mt9m111(client);
- s32 data;
- int ret;
-
- data = reg_read(CHIP_VERSION);
-
- switch (data) {
- case 0x143a: /* MT9M111 or MT9M131 */
- mt9m111->model = V4L2_IDENT_MT9M111;
- dev_info(&client->dev,
- "Detected a MT9M111/MT9M131 chip ID %x\n", data);
- break;
- case 0x148c: /* MT9M112 */
- mt9m111->model = V4L2_IDENT_MT9M112;
- dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data);
- break;
- default:
- dev_err(&client->dev,
- "No MT9M111/MT9M112/MT9M131 chip detected register read %x\n",
- data);
- return -ENODEV;
- }
-
- ret = mt9m111_init(mt9m111);
- if (ret)
- return ret;
- return v4l2_ctrl_handler_setup(&mt9m111->hdl);
-}
-
-static int mt9m111_s_power(struct v4l2_subdev *sd, int on)
-{
- struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret = 0;
-
- mutex_lock(&mt9m111->power_lock);
-
- /*
- * If the power count is modified from 0 to != 0 or from != 0 to 0,
- * update the power state.
- */
- if (mt9m111->power_count == !on) {
- if (on) {
- ret = mt9m111_resume(mt9m111);
- if (ret) {
- dev_err(&client->dev,
- "Failed to resume the sensor: %d\n", ret);
- goto out;
- }
- } else {
- mt9m111_suspend(mt9m111);
- }
- }
-
- /* Update the power count. */
- mt9m111->power_count += on ? 1 : -1;
- WARN_ON(mt9m111->power_count < 0);
-
-out:
- mutex_unlock(&mt9m111->power_lock);
- return ret;
-}
-
-static const struct v4l2_ctrl_ops mt9m111_ctrl_ops = {
- .s_ctrl = mt9m111_s_ctrl,
-};
-
-static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
- .g_chip_ident = mt9m111_g_chip_ident,
- .s_power = mt9m111_s_power,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = mt9m111_g_register,
- .s_register = mt9m111_s_register,
-#endif
-};
-
-static int mt9m111_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index >= ARRAY_SIZE(mt9m111_colour_fmts))
- return -EINVAL;
-
- *code = mt9m111_colour_fmts[index].code;
- return 0;
-}
-
-static int mt9m111_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
- V4L2_MBUS_DATA_ACTIVE_HIGH;
- cfg->type = V4L2_MBUS_PARALLEL;
- cfg->flags = soc_camera_apply_board_flags(icl, cfg);
-
- return 0;
-}
-
-static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
- .s_mbus_fmt = mt9m111_s_fmt,
- .g_mbus_fmt = mt9m111_g_fmt,
- .try_mbus_fmt = mt9m111_try_fmt,
- .s_crop = mt9m111_s_crop,
- .g_crop = mt9m111_g_crop,
- .cropcap = mt9m111_cropcap,
- .enum_mbus_fmt = mt9m111_enum_fmt,
- .g_mbus_config = mt9m111_g_mbus_config,
-};
-
-static struct v4l2_subdev_ops mt9m111_subdev_ops = {
- .core = &mt9m111_subdev_core_ops,
- .video = &mt9m111_subdev_video_ops,
-};
-
-static int mt9m111_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct mt9m111 *mt9m111;
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- int ret;
-
- if (!icl) {
- dev_err(&client->dev, "mt9m111: driver needs platform data\n");
- return -EINVAL;
- }
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
- dev_warn(&adapter->dev,
- "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
- return -EIO;
- }
-
- mt9m111 = kzalloc(sizeof(struct mt9m111), GFP_KERNEL);
- if (!mt9m111)
- return -ENOMEM;
-
- v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
- v4l2_ctrl_handler_init(&mt9m111->hdl, 5);
- v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
- V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
- mt9m111->gain = v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
- V4L2_CID_GAIN, 0, 63 * 2 * 2, 1, 32);
- v4l2_ctrl_new_std_menu(&mt9m111->hdl,
- &mt9m111_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
- V4L2_EXPOSURE_AUTO);
- mt9m111->subdev.ctrl_handler = &mt9m111->hdl;
- if (mt9m111->hdl.error) {
- int err = mt9m111->hdl.error;
-
- kfree(mt9m111);
- return err;
- }
-
- /* Second stage probe - when a capture adapter is there */
- mt9m111->rect.left = MT9M111_MIN_DARK_COLS;
- mt9m111->rect.top = MT9M111_MIN_DARK_ROWS;
- mt9m111->rect.width = MT9M111_MAX_WIDTH;
- mt9m111->rect.height = MT9M111_MAX_HEIGHT;
- mt9m111->fmt = &mt9m111_colour_fmts[0];
- mt9m111->lastpage = -1;
- mutex_init(&mt9m111->power_lock);
-
- ret = mt9m111_video_probe(client);
- if (ret) {
- v4l2_ctrl_handler_free(&mt9m111->hdl);
- kfree(mt9m111);
- }
-
- return ret;
-}
-
-static int mt9m111_remove(struct i2c_client *client)
-{
- struct mt9m111 *mt9m111 = to_mt9m111(client);
-
- v4l2_device_unregister_subdev(&mt9m111->subdev);
- v4l2_ctrl_handler_free(&mt9m111->hdl);
- kfree(mt9m111);
-
- return 0;
-}
-
-static const struct i2c_device_id mt9m111_id[] = {
- { "mt9m111", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, mt9m111_id);
-
-static struct i2c_driver mt9m111_i2c_driver = {
- .driver = {
- .name = "mt9m111",
- },
- .probe = mt9m111_probe,
- .remove = mt9m111_remove,
- .id_table = mt9m111_id,
-};
-
-module_i2c_driver(mt9m111_i2c_driver);
-
-MODULE_DESCRIPTION("Micron/Aptina MT9M111/MT9M112/MT9M131 Camera driver");
-MODULE_AUTHOR("Robert Jarzmik");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/mt9p031.c b/drivers/media/video/mt9p031.c
deleted file mode 100644
index 3be537ef22d..00000000000
--- a/drivers/media/video/mt9p031.c
+++ /dev/null
@@ -1,1071 +0,0 @@
-/*
- * Driver for MT9P031 CMOS Image Sensor from Aptina
- *
- * Copyright (C) 2011, Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Copyright (C) 2011, Javier Martin <javier.martin@vista-silicon.com>
- * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * Based on the MT9V032 driver and Bastian Hecht's code.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/pm.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-
-#include <media/mt9p031.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-
-#include "aptina-pll.h"
-
-#define MT9P031_PIXEL_ARRAY_WIDTH 2752
-#define MT9P031_PIXEL_ARRAY_HEIGHT 2004
-
-#define MT9P031_CHIP_VERSION 0x00
-#define MT9P031_CHIP_VERSION_VALUE 0x1801
-#define MT9P031_ROW_START 0x01
-#define MT9P031_ROW_START_MIN 0
-#define MT9P031_ROW_START_MAX 2004
-#define MT9P031_ROW_START_DEF 54
-#define MT9P031_COLUMN_START 0x02
-#define MT9P031_COLUMN_START_MIN 0
-#define MT9P031_COLUMN_START_MAX 2750
-#define MT9P031_COLUMN_START_DEF 16
-#define MT9P031_WINDOW_HEIGHT 0x03
-#define MT9P031_WINDOW_HEIGHT_MIN 2
-#define MT9P031_WINDOW_HEIGHT_MAX 2006
-#define MT9P031_WINDOW_HEIGHT_DEF 1944
-#define MT9P031_WINDOW_WIDTH 0x04
-#define MT9P031_WINDOW_WIDTH_MIN 2
-#define MT9P031_WINDOW_WIDTH_MAX 2752
-#define MT9P031_WINDOW_WIDTH_DEF 2592
-#define MT9P031_HORIZONTAL_BLANK 0x05
-#define MT9P031_HORIZONTAL_BLANK_MIN 0
-#define MT9P031_HORIZONTAL_BLANK_MAX 4095
-#define MT9P031_VERTICAL_BLANK 0x06
-#define MT9P031_VERTICAL_BLANK_MIN 0
-#define MT9P031_VERTICAL_BLANK_MAX 4095
-#define MT9P031_VERTICAL_BLANK_DEF 25
-#define MT9P031_OUTPUT_CONTROL 0x07
-#define MT9P031_OUTPUT_CONTROL_CEN 2
-#define MT9P031_OUTPUT_CONTROL_SYN 1
-#define MT9P031_OUTPUT_CONTROL_DEF 0x1f82
-#define MT9P031_SHUTTER_WIDTH_UPPER 0x08
-#define MT9P031_SHUTTER_WIDTH_LOWER 0x09
-#define MT9P031_SHUTTER_WIDTH_MIN 1
-#define MT9P031_SHUTTER_WIDTH_MAX 1048575
-#define MT9P031_SHUTTER_WIDTH_DEF 1943
-#define MT9P031_PLL_CONTROL 0x10
-#define MT9P031_PLL_CONTROL_PWROFF 0x0050
-#define MT9P031_PLL_CONTROL_PWRON 0x0051
-#define MT9P031_PLL_CONTROL_USEPLL 0x0052
-#define MT9P031_PLL_CONFIG_1 0x11
-#define MT9P031_PLL_CONFIG_2 0x12
-#define MT9P031_PIXEL_CLOCK_CONTROL 0x0a
-#define MT9P031_FRAME_RESTART 0x0b
-#define MT9P031_SHUTTER_DELAY 0x0c
-#define MT9P031_RST 0x0d
-#define MT9P031_RST_ENABLE 1
-#define MT9P031_RST_DISABLE 0
-#define MT9P031_READ_MODE_1 0x1e
-#define MT9P031_READ_MODE_2 0x20
-#define MT9P031_READ_MODE_2_ROW_MIR (1 << 15)
-#define MT9P031_READ_MODE_2_COL_MIR (1 << 14)
-#define MT9P031_READ_MODE_2_ROW_BLC (1 << 6)
-#define MT9P031_ROW_ADDRESS_MODE 0x22
-#define MT9P031_COLUMN_ADDRESS_MODE 0x23
-#define MT9P031_GLOBAL_GAIN 0x35
-#define MT9P031_GLOBAL_GAIN_MIN 8
-#define MT9P031_GLOBAL_GAIN_MAX 1024
-#define MT9P031_GLOBAL_GAIN_DEF 8
-#define MT9P031_GLOBAL_GAIN_MULT (1 << 6)
-#define MT9P031_ROW_BLACK_TARGET 0x49
-#define MT9P031_ROW_BLACK_DEF_OFFSET 0x4b
-#define MT9P031_GREEN1_OFFSET 0x60
-#define MT9P031_GREEN2_OFFSET 0x61
-#define MT9P031_BLACK_LEVEL_CALIBRATION 0x62
-#define MT9P031_BLC_MANUAL_BLC (1 << 0)
-#define MT9P031_RED_OFFSET 0x63
-#define MT9P031_BLUE_OFFSET 0x64
-#define MT9P031_TEST_PATTERN 0xa0
-#define MT9P031_TEST_PATTERN_SHIFT 3
-#define MT9P031_TEST_PATTERN_ENABLE (1 << 0)
-#define MT9P031_TEST_PATTERN_DISABLE (0 << 0)
-#define MT9P031_TEST_PATTERN_GREEN 0xa1
-#define MT9P031_TEST_PATTERN_RED 0xa2
-#define MT9P031_TEST_PATTERN_BLUE 0xa3
-
-enum mt9p031_model {
- MT9P031_MODEL_COLOR,
- MT9P031_MODEL_MONOCHROME,
-};
-
-struct mt9p031 {
- struct v4l2_subdev subdev;
- struct media_pad pad;
- struct v4l2_rect crop; /* Sensor window */
- struct v4l2_mbus_framefmt format;
- struct mt9p031_platform_data *pdata;
- struct mutex power_lock; /* lock to protect power_count */
- int power_count;
-
- enum mt9p031_model model;
- struct aptina_pll pll;
- int reset;
-
- struct v4l2_ctrl_handler ctrls;
- struct v4l2_ctrl *blc_auto;
- struct v4l2_ctrl *blc_offset;
-
- /* Registers cache */
- u16 output_control;
- u16 mode2;
-};
-
-static struct mt9p031 *to_mt9p031(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct mt9p031, subdev);
-}
-
-static int mt9p031_read(struct i2c_client *client, u8 reg)
-{
- return i2c_smbus_read_word_swapped(client, reg);
-}
-
-static int mt9p031_write(struct i2c_client *client, u8 reg, u16 data)
-{
- return i2c_smbus_write_word_swapped(client, reg, data);
-}
-
-static int mt9p031_set_output_control(struct mt9p031 *mt9p031, u16 clear,
- u16 set)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
- u16 value = (mt9p031->output_control & ~clear) | set;
- int ret;
-
- ret = mt9p031_write(client, MT9P031_OUTPUT_CONTROL, value);
- if (ret < 0)
- return ret;
-
- mt9p031->output_control = value;
- return 0;
-}
-
-static int mt9p031_set_mode2(struct mt9p031 *mt9p031, u16 clear, u16 set)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
- u16 value = (mt9p031->mode2 & ~clear) | set;
- int ret;
-
- ret = mt9p031_write(client, MT9P031_READ_MODE_2, value);
- if (ret < 0)
- return ret;
-
- mt9p031->mode2 = value;
- return 0;
-}
-
-static int mt9p031_reset(struct mt9p031 *mt9p031)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
- int ret;
-
- /* Disable chip output, synchronous option update */
- ret = mt9p031_write(client, MT9P031_RST, MT9P031_RST_ENABLE);
- if (ret < 0)
- return ret;
- ret = mt9p031_write(client, MT9P031_RST, MT9P031_RST_DISABLE);
- if (ret < 0)
- return ret;
-
- return mt9p031_set_output_control(mt9p031, MT9P031_OUTPUT_CONTROL_CEN,
- 0);
-}
-
-static int mt9p031_pll_setup(struct mt9p031 *mt9p031)
-{
- static const struct aptina_pll_limits limits = {
- .ext_clock_min = 6000000,
- .ext_clock_max = 27000000,
- .int_clock_min = 2000000,
- .int_clock_max = 13500000,
- .out_clock_min = 180000000,
- .out_clock_max = 360000000,
- .pix_clock_max = 96000000,
- .n_min = 1,
- .n_max = 64,
- .m_min = 16,
- .m_max = 255,
- .p1_min = 1,
- .p1_max = 128,
- };
-
- struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
- struct mt9p031_platform_data *pdata = mt9p031->pdata;
-
- mt9p031->pll.ext_clock = pdata->ext_freq;
- mt9p031->pll.pix_clock = pdata->target_freq;
-
- return aptina_pll_calculate(&client->dev, &limits, &mt9p031->pll);
-}
-
-static int mt9p031_pll_enable(struct mt9p031 *mt9p031)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
- int ret;
-
- ret = mt9p031_write(client, MT9P031_PLL_CONTROL,
- MT9P031_PLL_CONTROL_PWRON);
- if (ret < 0)
- return ret;
-
- ret = mt9p031_write(client, MT9P031_PLL_CONFIG_1,
- (mt9p031->pll.m << 8) | (mt9p031->pll.n - 1));
- if (ret < 0)
- return ret;
-
- ret = mt9p031_write(client, MT9P031_PLL_CONFIG_2, mt9p031->pll.p1 - 1);
- if (ret < 0)
- return ret;
-
- usleep_range(1000, 2000);
- ret = mt9p031_write(client, MT9P031_PLL_CONTROL,
- MT9P031_PLL_CONTROL_PWRON |
- MT9P031_PLL_CONTROL_USEPLL);
- return ret;
-}
-
-static inline int mt9p031_pll_disable(struct mt9p031 *mt9p031)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
-
- return mt9p031_write(client, MT9P031_PLL_CONTROL,
- MT9P031_PLL_CONTROL_PWROFF);
-}
-
-static int mt9p031_power_on(struct mt9p031 *mt9p031)
-{
- /* Ensure RESET_BAR is low */
- if (mt9p031->reset != -1) {
- gpio_set_value(mt9p031->reset, 0);
- usleep_range(1000, 2000);
- }
-
- /* Emable clock */
- if (mt9p031->pdata->set_xclk)
- mt9p031->pdata->set_xclk(&mt9p031->subdev,
- mt9p031->pdata->ext_freq);
-
- /* Now RESET_BAR must be high */
- if (mt9p031->reset != -1) {
- gpio_set_value(mt9p031->reset, 1);
- usleep_range(1000, 2000);
- }
-
- return 0;
-}
-
-static void mt9p031_power_off(struct mt9p031 *mt9p031)
-{
- if (mt9p031->reset != -1) {
- gpio_set_value(mt9p031->reset, 0);
- usleep_range(1000, 2000);
- }
-
- if (mt9p031->pdata->set_xclk)
- mt9p031->pdata->set_xclk(&mt9p031->subdev, 0);
-}
-
-static int __mt9p031_set_power(struct mt9p031 *mt9p031, bool on)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
- int ret;
-
- if (!on) {
- mt9p031_power_off(mt9p031);
- return 0;
- }
-
- ret = mt9p031_power_on(mt9p031);
- if (ret < 0)
- return ret;
-
- ret = mt9p031_reset(mt9p031);
- if (ret < 0) {
- dev_err(&client->dev, "Failed to reset the camera\n");
- return ret;
- }
-
- return v4l2_ctrl_handler_setup(&mt9p031->ctrls);
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev video operations
- */
-
-static int mt9p031_set_params(struct mt9p031 *mt9p031)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
- struct v4l2_mbus_framefmt *format = &mt9p031->format;
- const struct v4l2_rect *crop = &mt9p031->crop;
- unsigned int hblank;
- unsigned int vblank;
- unsigned int xskip;
- unsigned int yskip;
- unsigned int xbin;
- unsigned int ybin;
- int ret;
-
- /* Windows position and size.
- *
- * TODO: Make sure the start coordinates and window size match the
- * skipping, binning and mirroring (see description of registers 2 and 4
- * in table 13, and Binning section on page 41).
- */
- ret = mt9p031_write(client, MT9P031_COLUMN_START, crop->left);
- if (ret < 0)
- return ret;
- ret = mt9p031_write(client, MT9P031_ROW_START, crop->top);
- if (ret < 0)
- return ret;
- ret = mt9p031_write(client, MT9P031_WINDOW_WIDTH, crop->width - 1);
- if (ret < 0)
- return ret;
- ret = mt9p031_write(client, MT9P031_WINDOW_HEIGHT, crop->height - 1);
- if (ret < 0)
- return ret;
-
- /* Row and column binning and skipping. Use the maximum binning value
- * compatible with the skipping settings.
- */
- xskip = DIV_ROUND_CLOSEST(crop->width, format->width);
- yskip = DIV_ROUND_CLOSEST(crop->height, format->height);
- xbin = 1 << (ffs(xskip) - 1);
- ybin = 1 << (ffs(yskip) - 1);
-
- ret = mt9p031_write(client, MT9P031_COLUMN_ADDRESS_MODE,
- ((xbin - 1) << 4) | (xskip - 1));
- if (ret < 0)
- return ret;
- ret = mt9p031_write(client, MT9P031_ROW_ADDRESS_MODE,
- ((ybin - 1) << 4) | (yskip - 1));
- if (ret < 0)
- return ret;
-
- /* Blanking - use minimum value for horizontal blanking and default
- * value for vertical blanking.
- */
- hblank = 346 * ybin + 64 + (80 >> max_t(unsigned int, xbin, 3));
- vblank = MT9P031_VERTICAL_BLANK_DEF;
-
- ret = mt9p031_write(client, MT9P031_HORIZONTAL_BLANK, hblank);
- if (ret < 0)
- return ret;
- ret = mt9p031_write(client, MT9P031_VERTICAL_BLANK, vblank);
- if (ret < 0)
- return ret;
-
- return ret;
-}
-
-static int mt9p031_s_stream(struct v4l2_subdev *subdev, int enable)
-{
- struct mt9p031 *mt9p031 = to_mt9p031(subdev);
- int ret;
-
- if (!enable) {
- /* Stop sensor readout */
- ret = mt9p031_set_output_control(mt9p031,
- MT9P031_OUTPUT_CONTROL_CEN, 0);
- if (ret < 0)
- return ret;
-
- return mt9p031_pll_disable(mt9p031);
- }
-
- ret = mt9p031_set_params(mt9p031);
- if (ret < 0)
- return ret;
-
- /* Switch to master "normal" mode */
- ret = mt9p031_set_output_control(mt9p031, 0,
- MT9P031_OUTPUT_CONTROL_CEN);
- if (ret < 0)
- return ret;
-
- return mt9p031_pll_enable(mt9p031);
-}
-
-static int mt9p031_enum_mbus_code(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- struct mt9p031 *mt9p031 = to_mt9p031(subdev);
-
- if (code->pad || code->index)
- return -EINVAL;
-
- code->code = mt9p031->format.code;
- return 0;
-}
-
-static int mt9p031_enum_frame_size(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_frame_size_enum *fse)
-{
- struct mt9p031 *mt9p031 = to_mt9p031(subdev);
-
- if (fse->index >= 8 || fse->code != mt9p031->format.code)
- return -EINVAL;
-
- fse->min_width = MT9P031_WINDOW_WIDTH_DEF
- / min_t(unsigned int, 7, fse->index + 1);
- fse->max_width = fse->min_width;
- fse->min_height = MT9P031_WINDOW_HEIGHT_DEF / (fse->index + 1);
- fse->max_height = fse->min_height;
-
- return 0;
-}
-
-static struct v4l2_mbus_framefmt *
-__mt9p031_get_pad_format(struct mt9p031 *mt9p031, struct v4l2_subdev_fh *fh,
- unsigned int pad, u32 which)
-{
- switch (which) {
- case V4L2_SUBDEV_FORMAT_TRY:
- return v4l2_subdev_get_try_format(fh, pad);
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- return &mt9p031->format;
- default:
- return NULL;
- }
-}
-
-static struct v4l2_rect *
-__mt9p031_get_pad_crop(struct mt9p031 *mt9p031, struct v4l2_subdev_fh *fh,
- unsigned int pad, u32 which)
-{
- switch (which) {
- case V4L2_SUBDEV_FORMAT_TRY:
- return v4l2_subdev_get_try_crop(fh, pad);
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- return &mt9p031->crop;
- default:
- return NULL;
- }
-}
-
-static int mt9p031_get_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct mt9p031 *mt9p031 = to_mt9p031(subdev);
-
- fmt->format = *__mt9p031_get_pad_format(mt9p031, fh, fmt->pad,
- fmt->which);
- return 0;
-}
-
-static int mt9p031_set_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *format)
-{
- struct mt9p031 *mt9p031 = to_mt9p031(subdev);
- struct v4l2_mbus_framefmt *__format;
- struct v4l2_rect *__crop;
- unsigned int width;
- unsigned int height;
- unsigned int hratio;
- unsigned int vratio;
-
- __crop = __mt9p031_get_pad_crop(mt9p031, fh, format->pad,
- format->which);
-
- /* Clamp the width and height to avoid dividing by zero. */
- width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
- max(__crop->width / 7, MT9P031_WINDOW_WIDTH_MIN),
- __crop->width);
- height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
- max(__crop->height / 8, MT9P031_WINDOW_HEIGHT_MIN),
- __crop->height);
-
- hratio = DIV_ROUND_CLOSEST(__crop->width, width);
- vratio = DIV_ROUND_CLOSEST(__crop->height, height);
-
- __format = __mt9p031_get_pad_format(mt9p031, fh, format->pad,
- format->which);
- __format->width = __crop->width / hratio;
- __format->height = __crop->height / vratio;
-
- format->format = *__format;
-
- return 0;
-}
-
-static int mt9p031_get_crop(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_crop *crop)
-{
- struct mt9p031 *mt9p031 = to_mt9p031(subdev);
-
- crop->rect = *__mt9p031_get_pad_crop(mt9p031, fh, crop->pad,
- crop->which);
- return 0;
-}
-
-static int mt9p031_set_crop(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_crop *crop)
-{
- struct mt9p031 *mt9p031 = to_mt9p031(subdev);
- struct v4l2_mbus_framefmt *__format;
- struct v4l2_rect *__crop;
- struct v4l2_rect rect;
-
- /* Clamp the crop rectangle boundaries and align them to a multiple of 2
- * pixels to ensure a GRBG Bayer pattern.
- */
- rect.left = clamp(ALIGN(crop->rect.left, 2), MT9P031_COLUMN_START_MIN,
- MT9P031_COLUMN_START_MAX);
- rect.top = clamp(ALIGN(crop->rect.top, 2), MT9P031_ROW_START_MIN,
- MT9P031_ROW_START_MAX);
- rect.width = clamp(ALIGN(crop->rect.width, 2),
- MT9P031_WINDOW_WIDTH_MIN,
- MT9P031_WINDOW_WIDTH_MAX);
- rect.height = clamp(ALIGN(crop->rect.height, 2),
- MT9P031_WINDOW_HEIGHT_MIN,
- MT9P031_WINDOW_HEIGHT_MAX);
-
- rect.width = min(rect.width, MT9P031_PIXEL_ARRAY_WIDTH - rect.left);
- rect.height = min(rect.height, MT9P031_PIXEL_ARRAY_HEIGHT - rect.top);
-
- __crop = __mt9p031_get_pad_crop(mt9p031, fh, crop->pad, crop->which);
-
- if (rect.width != __crop->width || rect.height != __crop->height) {
- /* Reset the output image size if the crop rectangle size has
- * been modified.
- */
- __format = __mt9p031_get_pad_format(mt9p031, fh, crop->pad,
- crop->which);
- __format->width = rect.width;
- __format->height = rect.height;
- }
-
- *__crop = rect;
- crop->rect = rect;
-
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev control operations
- */
-
-#define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001)
-#define V4L2_CID_BLC_AUTO (V4L2_CID_USER_BASE | 0x1002)
-#define V4L2_CID_BLC_TARGET_LEVEL (V4L2_CID_USER_BASE | 0x1003)
-#define V4L2_CID_BLC_ANALOG_OFFSET (V4L2_CID_USER_BASE | 0x1004)
-#define V4L2_CID_BLC_DIGITAL_OFFSET (V4L2_CID_USER_BASE | 0x1005)
-
-static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct mt9p031 *mt9p031 =
- container_of(ctrl->handler, struct mt9p031, ctrls);
- struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
- u16 data;
- int ret;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- ret = mt9p031_write(client, MT9P031_SHUTTER_WIDTH_UPPER,
- (ctrl->val >> 16) & 0xffff);
- if (ret < 0)
- return ret;
-
- return mt9p031_write(client, MT9P031_SHUTTER_WIDTH_LOWER,
- ctrl->val & 0xffff);
-
- case V4L2_CID_GAIN:
- /* Gain is controlled by 2 analog stages and a digital stage.
- * Valid values for the 3 stages are
- *
- * Stage Min Max Step
- * ------------------------------------------
- * First analog stage x1 x2 1
- * Second analog stage x1 x4 0.125
- * Digital stage x1 x16 0.125
- *
- * To minimize noise, the gain stages should be used in the
- * second analog stage, first analog stage, digital stage order.
- * Gain from a previous stage should be pushed to its maximum
- * value before the next stage is used.
- */
- if (ctrl->val <= 32) {
- data = ctrl->val;
- } else if (ctrl->val <= 64) {
- ctrl->val &= ~1;
- data = (1 << 6) | (ctrl->val >> 1);
- } else {
- ctrl->val &= ~7;
- data = ((ctrl->val - 64) << 5) | (1 << 6) | 32;
- }
-
- return mt9p031_write(client, MT9P031_GLOBAL_GAIN, data);
-
- case V4L2_CID_HFLIP:
- if (ctrl->val)
- return mt9p031_set_mode2(mt9p031,
- 0, MT9P031_READ_MODE_2_COL_MIR);
- else
- return mt9p031_set_mode2(mt9p031,
- MT9P031_READ_MODE_2_COL_MIR, 0);
-
- case V4L2_CID_VFLIP:
- if (ctrl->val)
- return mt9p031_set_mode2(mt9p031,
- 0, MT9P031_READ_MODE_2_ROW_MIR);
- else
- return mt9p031_set_mode2(mt9p031,
- MT9P031_READ_MODE_2_ROW_MIR, 0);
-
- case V4L2_CID_TEST_PATTERN:
- if (!ctrl->val) {
- /* Restore the black level compensation settings. */
- if (mt9p031->blc_auto->cur.val != 0) {
- ret = mt9p031_s_ctrl(mt9p031->blc_auto);
- if (ret < 0)
- return ret;
- }
- if (mt9p031->blc_offset->cur.val != 0) {
- ret = mt9p031_s_ctrl(mt9p031->blc_offset);
- if (ret < 0)
- return ret;
- }
- return mt9p031_write(client, MT9P031_TEST_PATTERN,
- MT9P031_TEST_PATTERN_DISABLE);
- }
-
- ret = mt9p031_write(client, MT9P031_TEST_PATTERN_GREEN, 0x05a0);
- if (ret < 0)
- return ret;
- ret = mt9p031_write(client, MT9P031_TEST_PATTERN_RED, 0x0a50);
- if (ret < 0)
- return ret;
- ret = mt9p031_write(client, MT9P031_TEST_PATTERN_BLUE, 0x0aa0);
- if (ret < 0)
- return ret;
-
- /* Disable digital black level compensation when using a test
- * pattern.
- */
- ret = mt9p031_set_mode2(mt9p031, MT9P031_READ_MODE_2_ROW_BLC,
- 0);
- if (ret < 0)
- return ret;
-
- ret = mt9p031_write(client, MT9P031_ROW_BLACK_DEF_OFFSET, 0);
- if (ret < 0)
- return ret;
-
- return mt9p031_write(client, MT9P031_TEST_PATTERN,
- ((ctrl->val - 1) << MT9P031_TEST_PATTERN_SHIFT)
- | MT9P031_TEST_PATTERN_ENABLE);
-
- case V4L2_CID_BLC_AUTO:
- ret = mt9p031_set_mode2(mt9p031,
- ctrl->val ? 0 : MT9P031_READ_MODE_2_ROW_BLC,
- ctrl->val ? MT9P031_READ_MODE_2_ROW_BLC : 0);
- if (ret < 0)
- return ret;
-
- return mt9p031_write(client, MT9P031_BLACK_LEVEL_CALIBRATION,
- ctrl->val ? 0 : MT9P031_BLC_MANUAL_BLC);
-
- case V4L2_CID_BLC_TARGET_LEVEL:
- return mt9p031_write(client, MT9P031_ROW_BLACK_TARGET,
- ctrl->val);
-
- case V4L2_CID_BLC_ANALOG_OFFSET:
- data = ctrl->val & ((1 << 9) - 1);
-
- ret = mt9p031_write(client, MT9P031_GREEN1_OFFSET, data);
- if (ret < 0)
- return ret;
- ret = mt9p031_write(client, MT9P031_GREEN2_OFFSET, data);
- if (ret < 0)
- return ret;
- ret = mt9p031_write(client, MT9P031_RED_OFFSET, data);
- if (ret < 0)
- return ret;
- return mt9p031_write(client, MT9P031_BLUE_OFFSET, data);
-
- case V4L2_CID_BLC_DIGITAL_OFFSET:
- return mt9p031_write(client, MT9P031_ROW_BLACK_DEF_OFFSET,
- ctrl->val & ((1 << 12) - 1));
- }
-
- return 0;
-}
-
-static struct v4l2_ctrl_ops mt9p031_ctrl_ops = {
- .s_ctrl = mt9p031_s_ctrl,
-};
-
-static const char * const mt9p031_test_pattern_menu[] = {
- "Disabled",
- "Color Field",
- "Horizontal Gradient",
- "Vertical Gradient",
- "Diagonal Gradient",
- "Classic Test Pattern",
- "Walking 1s",
- "Monochrome Horizontal Bars",
- "Monochrome Vertical Bars",
- "Vertical Color Bars",
-};
-
-static const struct v4l2_ctrl_config mt9p031_ctrls[] = {
- {
- .ops = &mt9p031_ctrl_ops,
- .id = V4L2_CID_TEST_PATTERN,
- .type = V4L2_CTRL_TYPE_MENU,
- .name = "Test Pattern",
- .min = 0,
- .max = ARRAY_SIZE(mt9p031_test_pattern_menu) - 1,
- .step = 0,
- .def = 0,
- .flags = 0,
- .menu_skip_mask = 0,
- .qmenu = mt9p031_test_pattern_menu,
- }, {
- .ops = &mt9p031_ctrl_ops,
- .id = V4L2_CID_BLC_AUTO,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "BLC, Auto",
- .min = 0,
- .max = 1,
- .step = 1,
- .def = 1,
- .flags = 0,
- }, {
- .ops = &mt9p031_ctrl_ops,
- .id = V4L2_CID_BLC_TARGET_LEVEL,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "BLC Target Level",
- .min = 0,
- .max = 4095,
- .step = 1,
- .def = 168,
- .flags = 0,
- }, {
- .ops = &mt9p031_ctrl_ops,
- .id = V4L2_CID_BLC_ANALOG_OFFSET,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "BLC Analog Offset",
- .min = -255,
- .max = 255,
- .step = 1,
- .def = 32,
- .flags = 0,
- }, {
- .ops = &mt9p031_ctrl_ops,
- .id = V4L2_CID_BLC_DIGITAL_OFFSET,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "BLC Digital Offset",
- .min = -2048,
- .max = 2047,
- .step = 1,
- .def = 40,
- .flags = 0,
- }
-};
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev core operations
- */
-
-static int mt9p031_set_power(struct v4l2_subdev *subdev, int on)
-{
- struct mt9p031 *mt9p031 = to_mt9p031(subdev);
- int ret = 0;
-
- mutex_lock(&mt9p031->power_lock);
-
- /* If the power count is modified from 0 to != 0 or from != 0 to 0,
- * update the power state.
- */
- if (mt9p031->power_count == !on) {
- ret = __mt9p031_set_power(mt9p031, !!on);
- if (ret < 0)
- goto out;
- }
-
- /* Update the power count. */
- mt9p031->power_count += on ? 1 : -1;
- WARN_ON(mt9p031->power_count < 0);
-
-out:
- mutex_unlock(&mt9p031->power_lock);
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev internal operations
- */
-
-static int mt9p031_registered(struct v4l2_subdev *subdev)
-{
- struct i2c_client *client = v4l2_get_subdevdata(subdev);
- struct mt9p031 *mt9p031 = to_mt9p031(subdev);
- s32 data;
- int ret;
-
- ret = mt9p031_power_on(mt9p031);
- if (ret < 0) {
- dev_err(&client->dev, "MT9P031 power up failed\n");
- return ret;
- }
-
- /* Read out the chip version register */
- data = mt9p031_read(client, MT9P031_CHIP_VERSION);
- if (data != MT9P031_CHIP_VERSION_VALUE) {
- dev_err(&client->dev, "MT9P031 not detected, wrong version "
- "0x%04x\n", data);
- return -ENODEV;
- }
-
- mt9p031_power_off(mt9p031);
-
- dev_info(&client->dev, "MT9P031 detected at address 0x%02x\n",
- client->addr);
-
- return ret;
-}
-
-static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
-{
- struct mt9p031 *mt9p031 = to_mt9p031(subdev);
- struct v4l2_mbus_framefmt *format;
- struct v4l2_rect *crop;
-
- crop = v4l2_subdev_get_try_crop(fh, 0);
- crop->left = MT9P031_COLUMN_START_DEF;
- crop->top = MT9P031_ROW_START_DEF;
- crop->width = MT9P031_WINDOW_WIDTH_DEF;
- crop->height = MT9P031_WINDOW_HEIGHT_DEF;
-
- format = v4l2_subdev_get_try_format(fh, 0);
-
- if (mt9p031->model == MT9P031_MODEL_MONOCHROME)
- format->code = V4L2_MBUS_FMT_Y12_1X12;
- else
- format->code = V4L2_MBUS_FMT_SGRBG12_1X12;
-
- format->width = MT9P031_WINDOW_WIDTH_DEF;
- format->height = MT9P031_WINDOW_HEIGHT_DEF;
- format->field = V4L2_FIELD_NONE;
- format->colorspace = V4L2_COLORSPACE_SRGB;
-
- return mt9p031_set_power(subdev, 1);
-}
-
-static int mt9p031_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
-{
- return mt9p031_set_power(subdev, 0);
-}
-
-static struct v4l2_subdev_core_ops mt9p031_subdev_core_ops = {
- .s_power = mt9p031_set_power,
-};
-
-static struct v4l2_subdev_video_ops mt9p031_subdev_video_ops = {
- .s_stream = mt9p031_s_stream,
-};
-
-static struct v4l2_subdev_pad_ops mt9p031_subdev_pad_ops = {
- .enum_mbus_code = mt9p031_enum_mbus_code,
- .enum_frame_size = mt9p031_enum_frame_size,
- .get_fmt = mt9p031_get_format,
- .set_fmt = mt9p031_set_format,
- .get_crop = mt9p031_get_crop,
- .set_crop = mt9p031_set_crop,
-};
-
-static struct v4l2_subdev_ops mt9p031_subdev_ops = {
- .core = &mt9p031_subdev_core_ops,
- .video = &mt9p031_subdev_video_ops,
- .pad = &mt9p031_subdev_pad_ops,
-};
-
-static const struct v4l2_subdev_internal_ops mt9p031_subdev_internal_ops = {
- .registered = mt9p031_registered,
- .open = mt9p031_open,
- .close = mt9p031_close,
-};
-
-/* -----------------------------------------------------------------------------
- * Driver initialization and probing
- */
-
-static int mt9p031_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct mt9p031_platform_data *pdata = client->dev.platform_data;
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- struct mt9p031 *mt9p031;
- unsigned int i;
- int ret;
-
- if (pdata == NULL) {
- dev_err(&client->dev, "No platform data\n");
- return -EINVAL;
- }
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
- dev_warn(&client->dev,
- "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
- return -EIO;
- }
-
- mt9p031 = kzalloc(sizeof(*mt9p031), GFP_KERNEL);
- if (mt9p031 == NULL)
- return -ENOMEM;
-
- mt9p031->pdata = pdata;
- mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF;
- mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC;
- mt9p031->model = did->driver_data;
- mt9p031->reset = -1;
-
- v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 5);
-
- v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
- V4L2_CID_EXPOSURE, MT9P031_SHUTTER_WIDTH_MIN,
- MT9P031_SHUTTER_WIDTH_MAX, 1,
- MT9P031_SHUTTER_WIDTH_DEF);
- v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
- V4L2_CID_GAIN, MT9P031_GLOBAL_GAIN_MIN,
- MT9P031_GLOBAL_GAIN_MAX, 1, MT9P031_GLOBAL_GAIN_DEF);
- v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
- V4L2_CID_PIXEL_RATE, pdata->target_freq,
- pdata->target_freq, 1, pdata->target_freq);
-
- for (i = 0; i < ARRAY_SIZE(mt9p031_ctrls); ++i)
- v4l2_ctrl_new_custom(&mt9p031->ctrls, &mt9p031_ctrls[i], NULL);
-
- mt9p031->subdev.ctrl_handler = &mt9p031->ctrls;
-
- if (mt9p031->ctrls.error) {
- printk(KERN_INFO "%s: control initialization error %d\n",
- __func__, mt9p031->ctrls.error);
- ret = mt9p031->ctrls.error;
- goto done;
- }
-
- mt9p031->blc_auto = v4l2_ctrl_find(&mt9p031->ctrls, V4L2_CID_BLC_AUTO);
- mt9p031->blc_offset = v4l2_ctrl_find(&mt9p031->ctrls,
- V4L2_CID_BLC_DIGITAL_OFFSET);
-
- mutex_init(&mt9p031->power_lock);
- v4l2_i2c_subdev_init(&mt9p031->subdev, client, &mt9p031_subdev_ops);
- mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops;
-
- mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad, 0);
- if (ret < 0)
- goto done;
-
- mt9p031->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- mt9p031->crop.width = MT9P031_WINDOW_WIDTH_DEF;
- mt9p031->crop.height = MT9P031_WINDOW_HEIGHT_DEF;
- mt9p031->crop.left = MT9P031_COLUMN_START_DEF;
- mt9p031->crop.top = MT9P031_ROW_START_DEF;
-
- if (mt9p031->model == MT9P031_MODEL_MONOCHROME)
- mt9p031->format.code = V4L2_MBUS_FMT_Y12_1X12;
- else
- mt9p031->format.code = V4L2_MBUS_FMT_SGRBG12_1X12;
-
- mt9p031->format.width = MT9P031_WINDOW_WIDTH_DEF;
- mt9p031->format.height = MT9P031_WINDOW_HEIGHT_DEF;
- mt9p031->format.field = V4L2_FIELD_NONE;
- mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB;
-
- if (pdata->reset != -1) {
- ret = gpio_request_one(pdata->reset, GPIOF_OUT_INIT_LOW,
- "mt9p031_rst");
- if (ret < 0)
- goto done;
-
- mt9p031->reset = pdata->reset;
- }
-
- ret = mt9p031_pll_setup(mt9p031);
-
-done:
- if (ret < 0) {
- if (mt9p031->reset != -1)
- gpio_free(mt9p031->reset);
-
- v4l2_ctrl_handler_free(&mt9p031->ctrls);
- media_entity_cleanup(&mt9p031->subdev.entity);
- kfree(mt9p031);
- }
-
- return ret;
-}
-
-static int mt9p031_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct mt9p031 *mt9p031 = to_mt9p031(subdev);
-
- v4l2_ctrl_handler_free(&mt9p031->ctrls);
- v4l2_device_unregister_subdev(subdev);
- media_entity_cleanup(&subdev->entity);
- if (mt9p031->reset != -1)
- gpio_free(mt9p031->reset);
- kfree(mt9p031);
-
- return 0;
-}
-
-static const struct i2c_device_id mt9p031_id[] = {
- { "mt9p031", MT9P031_MODEL_COLOR },
- { "mt9p031m", MT9P031_MODEL_MONOCHROME },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, mt9p031_id);
-
-static struct i2c_driver mt9p031_i2c_driver = {
- .driver = {
- .name = "mt9p031",
- },
- .probe = mt9p031_probe,
- .remove = mt9p031_remove,
- .id_table = mt9p031_id,
-};
-
-module_i2c_driver(mt9p031_i2c_driver);
-
-MODULE_DESCRIPTION("Aptina MT9P031 Camera driver");
-MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/mt9t001.c b/drivers/media/video/mt9t001.c
deleted file mode 100644
index 6d343adf891..00000000000
--- a/drivers/media/video/mt9t001.c
+++ /dev/null
@@ -1,833 +0,0 @@
-/*
- * Driver for MT9T001 CMOS Image Sensor from Aptina (Micron)
- *
- * Copyright (C) 2010-2011, Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- *
- * Based on the MT9M001 driver,
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/i2c.h>
-#include <linux/module.h>
-#include <linux/log2.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/v4l2-mediabus.h>
-
-#include <media/mt9t001.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-
-#define MT9T001_PIXEL_ARRAY_HEIGHT 1568
-#define MT9T001_PIXEL_ARRAY_WIDTH 2112
-
-#define MT9T001_CHIP_VERSION 0x00
-#define MT9T001_CHIP_ID 0x1621
-#define MT9T001_ROW_START 0x01
-#define MT9T001_ROW_START_MIN 0
-#define MT9T001_ROW_START_DEF 20
-#define MT9T001_ROW_START_MAX 1534
-#define MT9T001_COLUMN_START 0x02
-#define MT9T001_COLUMN_START_MIN 0
-#define MT9T001_COLUMN_START_DEF 32
-#define MT9T001_COLUMN_START_MAX 2046
-#define MT9T001_WINDOW_HEIGHT 0x03
-#define MT9T001_WINDOW_HEIGHT_MIN 1
-#define MT9T001_WINDOW_HEIGHT_DEF 1535
-#define MT9T001_WINDOW_HEIGHT_MAX 1567
-#define MT9T001_WINDOW_WIDTH 0x04
-#define MT9T001_WINDOW_WIDTH_MIN 1
-#define MT9T001_WINDOW_WIDTH_DEF 2047
-#define MT9T001_WINDOW_WIDTH_MAX 2111
-#define MT9T001_HORIZONTAL_BLANKING 0x05
-#define MT9T001_HORIZONTAL_BLANKING_MIN 21
-#define MT9T001_HORIZONTAL_BLANKING_MAX 1023
-#define MT9T001_VERTICAL_BLANKING 0x06
-#define MT9T001_VERTICAL_BLANKING_MIN 3
-#define MT9T001_VERTICAL_BLANKING_MAX 1023
-#define MT9T001_OUTPUT_CONTROL 0x07
-#define MT9T001_OUTPUT_CONTROL_SYNC (1 << 0)
-#define MT9T001_OUTPUT_CONTROL_CHIP_ENABLE (1 << 1)
-#define MT9T001_OUTPUT_CONTROL_TEST_DATA (1 << 6)
-#define MT9T001_SHUTTER_WIDTH_HIGH 0x08
-#define MT9T001_SHUTTER_WIDTH_LOW 0x09
-#define MT9T001_SHUTTER_WIDTH_MIN 1
-#define MT9T001_SHUTTER_WIDTH_DEF 1561
-#define MT9T001_SHUTTER_WIDTH_MAX (1024 * 1024)
-#define MT9T001_PIXEL_CLOCK 0x0a
-#define MT9T001_PIXEL_CLOCK_INVERT (1 << 15)
-#define MT9T001_PIXEL_CLOCK_SHIFT_MASK (7 << 8)
-#define MT9T001_PIXEL_CLOCK_SHIFT_SHIFT 8
-#define MT9T001_PIXEL_CLOCK_DIVIDE_MASK (0x7f << 0)
-#define MT9T001_FRAME_RESTART 0x0b
-#define MT9T001_SHUTTER_DELAY 0x0c
-#define MT9T001_SHUTTER_DELAY_MAX 2047
-#define MT9T001_RESET 0x0d
-#define MT9T001_READ_MODE1 0x1e
-#define MT9T001_READ_MODE_SNAPSHOT (1 << 8)
-#define MT9T001_READ_MODE_STROBE_ENABLE (1 << 9)
-#define MT9T001_READ_MODE_STROBE_WIDTH (1 << 10)
-#define MT9T001_READ_MODE_STROBE_OVERRIDE (1 << 11)
-#define MT9T001_READ_MODE2 0x20
-#define MT9T001_READ_MODE_BAD_FRAMES (1 << 0)
-#define MT9T001_READ_MODE_LINE_VALID_CONTINUOUS (1 << 9)
-#define MT9T001_READ_MODE_LINE_VALID_FRAME (1 << 10)
-#define MT9T001_READ_MODE3 0x21
-#define MT9T001_READ_MODE_GLOBAL_RESET (1 << 0)
-#define MT9T001_READ_MODE_GHST_CTL (1 << 1)
-#define MT9T001_ROW_ADDRESS_MODE 0x22
-#define MT9T001_ROW_SKIP_MASK (7 << 0)
-#define MT9T001_ROW_BIN_MASK (3 << 3)
-#define MT9T001_ROW_BIN_SHIFT 3
-#define MT9T001_COLUMN_ADDRESS_MODE 0x23
-#define MT9T001_COLUMN_SKIP_MASK (7 << 0)
-#define MT9T001_COLUMN_BIN_MASK (3 << 3)
-#define MT9T001_COLUMN_BIN_SHIFT 3
-#define MT9T001_GREEN1_GAIN 0x2b
-#define MT9T001_BLUE_GAIN 0x2c
-#define MT9T001_RED_GAIN 0x2d
-#define MT9T001_GREEN2_GAIN 0x2e
-#define MT9T001_TEST_DATA 0x32
-#define MT9T001_GLOBAL_GAIN 0x35
-#define MT9T001_GLOBAL_GAIN_MIN 8
-#define MT9T001_GLOBAL_GAIN_MAX 1024
-#define MT9T001_BLACK_LEVEL 0x49
-#define MT9T001_ROW_BLACK_DEFAULT_OFFSET 0x4b
-#define MT9T001_BLC_DELTA_THRESHOLDS 0x5d
-#define MT9T001_CAL_THRESHOLDS 0x5f
-#define MT9T001_GREEN1_OFFSET 0x60
-#define MT9T001_GREEN2_OFFSET 0x61
-#define MT9T001_BLACK_LEVEL_CALIBRATION 0x62
-#define MT9T001_BLACK_LEVEL_OVERRIDE (1 << 0)
-#define MT9T001_BLACK_LEVEL_DISABLE_OFFSET (1 << 1)
-#define MT9T001_BLACK_LEVEL_RECALCULATE (1 << 12)
-#define MT9T001_BLACK_LEVEL_LOCK_RED_BLUE (1 << 13)
-#define MT9T001_BLACK_LEVEL_LOCK_GREEN (1 << 14)
-#define MT9T001_RED_OFFSET 0x63
-#define MT9T001_BLUE_OFFSET 0x64
-
-struct mt9t001 {
- struct v4l2_subdev subdev;
- struct media_pad pad;
-
- struct v4l2_mbus_framefmt format;
- struct v4l2_rect crop;
-
- struct v4l2_ctrl_handler ctrls;
- struct v4l2_ctrl *gains[4];
-
- u16 output_control;
- u16 black_level;
-};
-
-static inline struct mt9t001 *to_mt9t001(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct mt9t001, subdev);
-}
-
-static int mt9t001_read(struct i2c_client *client, u8 reg)
-{
- return i2c_smbus_read_word_swapped(client, reg);
-}
-
-static int mt9t001_write(struct i2c_client *client, u8 reg, u16 data)
-{
- return i2c_smbus_write_word_swapped(client, reg, data);
-}
-
-static int mt9t001_set_output_control(struct mt9t001 *mt9t001, u16 clear,
- u16 set)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
- u16 value = (mt9t001->output_control & ~clear) | set;
- int ret;
-
- if (value == mt9t001->output_control)
- return 0;
-
- ret = mt9t001_write(client, MT9T001_OUTPUT_CONTROL, value);
- if (ret < 0)
- return ret;
-
- mt9t001->output_control = value;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev video operations
- */
-
-static struct v4l2_mbus_framefmt *
-__mt9t001_get_pad_format(struct mt9t001 *mt9t001, struct v4l2_subdev_fh *fh,
- unsigned int pad, enum v4l2_subdev_format_whence which)
-{
- switch (which) {
- case V4L2_SUBDEV_FORMAT_TRY:
- return v4l2_subdev_get_try_format(fh, pad);
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- return &mt9t001->format;
- default:
- return NULL;
- }
-}
-
-static struct v4l2_rect *
-__mt9t001_get_pad_crop(struct mt9t001 *mt9t001, struct v4l2_subdev_fh *fh,
- unsigned int pad, enum v4l2_subdev_format_whence which)
-{
- switch (which) {
- case V4L2_SUBDEV_FORMAT_TRY:
- return v4l2_subdev_get_try_crop(fh, pad);
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- return &mt9t001->crop;
- default:
- return NULL;
- }
-}
-
-static int mt9t001_s_stream(struct v4l2_subdev *subdev, int enable)
-{
- const u16 mode = MT9T001_OUTPUT_CONTROL_CHIP_ENABLE;
- struct i2c_client *client = v4l2_get_subdevdata(subdev);
- struct mt9t001 *mt9t001 = to_mt9t001(subdev);
- struct v4l2_mbus_framefmt *format = &mt9t001->format;
- struct v4l2_rect *crop = &mt9t001->crop;
- unsigned int hratio;
- unsigned int vratio;
- int ret;
-
- if (!enable)
- return mt9t001_set_output_control(mt9t001, mode, 0);
-
- /* Configure the window size and row/column bin */
- hratio = DIV_ROUND_CLOSEST(crop->width, format->width);
- vratio = DIV_ROUND_CLOSEST(crop->height, format->height);
-
- ret = mt9t001_write(client, MT9T001_ROW_ADDRESS_MODE, hratio - 1);
- if (ret < 0)
- return ret;
-
- ret = mt9t001_write(client, MT9T001_COLUMN_ADDRESS_MODE, vratio - 1);
- if (ret < 0)
- return ret;
-
- ret = mt9t001_write(client, MT9T001_COLUMN_START, crop->left);
- if (ret < 0)
- return ret;
-
- ret = mt9t001_write(client, MT9T001_ROW_START, crop->top);
- if (ret < 0)
- return ret;
-
- ret = mt9t001_write(client, MT9T001_WINDOW_WIDTH, crop->width - 1);
- if (ret < 0)
- return ret;
-
- ret = mt9t001_write(client, MT9T001_WINDOW_HEIGHT, crop->height - 1);
- if (ret < 0)
- return ret;
-
- /* Switch to master "normal" mode */
- return mt9t001_set_output_control(mt9t001, 0, mode);
-}
-
-static int mt9t001_enum_mbus_code(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- if (code->index > 0)
- return -EINVAL;
-
- code->code = V4L2_MBUS_FMT_SGRBG10_1X10;
- return 0;
-}
-
-static int mt9t001_enum_frame_size(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_frame_size_enum *fse)
-{
- if (fse->index >= 8 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10)
- return -EINVAL;
-
- fse->min_width = (MT9T001_WINDOW_WIDTH_DEF + 1) / fse->index;
- fse->max_width = fse->min_width;
- fse->min_height = (MT9T001_WINDOW_HEIGHT_DEF + 1) / fse->index;
- fse->max_height = fse->min_height;
-
- return 0;
-}
-
-static int mt9t001_get_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *format)
-{
- struct mt9t001 *mt9t001 = to_mt9t001(subdev);
-
- format->format = *__mt9t001_get_pad_format(mt9t001, fh, format->pad,
- format->which);
- return 0;
-}
-
-static int mt9t001_set_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *format)
-{
- struct mt9t001 *mt9t001 = to_mt9t001(subdev);
- struct v4l2_mbus_framefmt *__format;
- struct v4l2_rect *__crop;
- unsigned int width;
- unsigned int height;
- unsigned int hratio;
- unsigned int vratio;
-
- __crop = __mt9t001_get_pad_crop(mt9t001, fh, format->pad,
- format->which);
-
- /* Clamp the width and height to avoid dividing by zero. */
- width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
- max(__crop->width / 8, MT9T001_WINDOW_HEIGHT_MIN + 1),
- __crop->width);
- height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
- max(__crop->height / 8, MT9T001_WINDOW_HEIGHT_MIN + 1),
- __crop->height);
-
- hratio = DIV_ROUND_CLOSEST(__crop->width, width);
- vratio = DIV_ROUND_CLOSEST(__crop->height, height);
-
- __format = __mt9t001_get_pad_format(mt9t001, fh, format->pad,
- format->which);
- __format->width = __crop->width / hratio;
- __format->height = __crop->height / vratio;
-
- format->format = *__format;
-
- return 0;
-}
-
-static int mt9t001_get_crop(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_crop *crop)
-{
- struct mt9t001 *mt9t001 = to_mt9t001(subdev);
-
- crop->rect = *__mt9t001_get_pad_crop(mt9t001, fh, crop->pad,
- crop->which);
- return 0;
-}
-
-static int mt9t001_set_crop(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_crop *crop)
-{
- struct mt9t001 *mt9t001 = to_mt9t001(subdev);
- struct v4l2_mbus_framefmt *__format;
- struct v4l2_rect *__crop;
- struct v4l2_rect rect;
-
- /* Clamp the crop rectangle boundaries and align them to a multiple of 2
- * pixels.
- */
- rect.left = clamp(ALIGN(crop->rect.left, 2),
- MT9T001_COLUMN_START_MIN,
- MT9T001_COLUMN_START_MAX);
- rect.top = clamp(ALIGN(crop->rect.top, 2),
- MT9T001_ROW_START_MIN,
- MT9T001_ROW_START_MAX);
- rect.width = clamp(ALIGN(crop->rect.width, 2),
- MT9T001_WINDOW_WIDTH_MIN + 1,
- MT9T001_WINDOW_WIDTH_MAX + 1);
- rect.height = clamp(ALIGN(crop->rect.height, 2),
- MT9T001_WINDOW_HEIGHT_MIN + 1,
- MT9T001_WINDOW_HEIGHT_MAX + 1);
-
- rect.width = min(rect.width, MT9T001_PIXEL_ARRAY_WIDTH - rect.left);
- rect.height = min(rect.height, MT9T001_PIXEL_ARRAY_HEIGHT - rect.top);
-
- __crop = __mt9t001_get_pad_crop(mt9t001, fh, crop->pad, crop->which);
-
- if (rect.width != __crop->width || rect.height != __crop->height) {
- /* Reset the output image size if the crop rectangle size has
- * been modified.
- */
- __format = __mt9t001_get_pad_format(mt9t001, fh, crop->pad,
- crop->which);
- __format->width = rect.width;
- __format->height = rect.height;
- }
-
- *__crop = rect;
- crop->rect = rect;
-
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev control operations
- */
-
-#define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001)
-#define V4L2_CID_BLACK_LEVEL_AUTO (V4L2_CID_USER_BASE | 0x1002)
-#define V4L2_CID_BLACK_LEVEL_OFFSET (V4L2_CID_USER_BASE | 0x1003)
-#define V4L2_CID_BLACK_LEVEL_CALIBRATE (V4L2_CID_USER_BASE | 0x1004)
-
-#define V4L2_CID_GAIN_RED (V4L2_CTRL_CLASS_CAMERA | 0x1001)
-#define V4L2_CID_GAIN_GREEN_RED (V4L2_CTRL_CLASS_CAMERA | 0x1002)
-#define V4L2_CID_GAIN_GREEN_BLUE (V4L2_CTRL_CLASS_CAMERA | 0x1003)
-#define V4L2_CID_GAIN_BLUE (V4L2_CTRL_CLASS_CAMERA | 0x1004)
-
-static u16 mt9t001_gain_value(s32 *gain)
-{
- /* Gain is controlled by 2 analog stages and a digital stage. Valid
- * values for the 3 stages are
- *
- * Stage Min Max Step
- * ------------------------------------------
- * First analog stage x1 x2 1
- * Second analog stage x1 x4 0.125
- * Digital stage x1 x16 0.125
- *
- * To minimize noise, the gain stages should be used in the second
- * analog stage, first analog stage, digital stage order. Gain from a
- * previous stage should be pushed to its maximum value before the next
- * stage is used.
- */
- if (*gain <= 32)
- return *gain;
-
- if (*gain <= 64) {
- *gain &= ~1;
- return (1 << 6) | (*gain >> 1);
- }
-
- *gain &= ~7;
- return ((*gain - 64) << 5) | (1 << 6) | 32;
-}
-
-static int mt9t001_ctrl_freeze(struct mt9t001 *mt9t001, bool freeze)
-{
- return mt9t001_set_output_control(mt9t001,
- freeze ? 0 : MT9T001_OUTPUT_CONTROL_SYNC,
- freeze ? MT9T001_OUTPUT_CONTROL_SYNC : 0);
-}
-
-static int mt9t001_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- static const u8 gains[4] = {
- MT9T001_RED_GAIN, MT9T001_GREEN1_GAIN,
- MT9T001_GREEN2_GAIN, MT9T001_BLUE_GAIN
- };
-
- struct mt9t001 *mt9t001 =
- container_of(ctrl->handler, struct mt9t001, ctrls);
- struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
- unsigned int count;
- unsigned int i;
- u16 value;
- int ret;
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN_RED:
- case V4L2_CID_GAIN_GREEN_RED:
- case V4L2_CID_GAIN_GREEN_BLUE:
- case V4L2_CID_GAIN_BLUE:
-
- /* Disable control updates if more than one control has changed
- * in the cluster.
- */
- for (i = 0, count = 0; i < 4; ++i) {
- struct v4l2_ctrl *gain = mt9t001->gains[i];
-
- if (gain->val != gain->cur.val)
- count++;
- }
-
- if (count > 1) {
- ret = mt9t001_ctrl_freeze(mt9t001, true);
- if (ret < 0)
- return ret;
- }
-
- /* Update the gain controls. */
- for (i = 0; i < 4; ++i) {
- struct v4l2_ctrl *gain = mt9t001->gains[i];
-
- if (gain->val == gain->cur.val)
- continue;
-
- value = mt9t001_gain_value(&gain->val);
- ret = mt9t001_write(client, gains[i], value);
- if (ret < 0) {
- mt9t001_ctrl_freeze(mt9t001, false);
- return ret;
- }
- }
-
- /* Enable control updates. */
- if (count > 1) {
- ret = mt9t001_ctrl_freeze(mt9t001, false);
- if (ret < 0)
- return ret;
- }
-
- break;
-
- case V4L2_CID_EXPOSURE:
- ret = mt9t001_write(client, MT9T001_SHUTTER_WIDTH_LOW,
- ctrl->val & 0xffff);
- if (ret < 0)
- return ret;
-
- return mt9t001_write(client, MT9T001_SHUTTER_WIDTH_HIGH,
- ctrl->val >> 16);
-
- case V4L2_CID_TEST_PATTERN:
- ret = mt9t001_set_output_control(mt9t001,
- ctrl->val ? 0 : MT9T001_OUTPUT_CONTROL_TEST_DATA,
- ctrl->val ? MT9T001_OUTPUT_CONTROL_TEST_DATA : 0);
- if (ret < 0)
- return ret;
-
- return mt9t001_write(client, MT9T001_TEST_DATA, ctrl->val << 2);
-
- case V4L2_CID_BLACK_LEVEL_AUTO:
- value = ctrl->val ? 0 : MT9T001_BLACK_LEVEL_OVERRIDE;
- ret = mt9t001_write(client, MT9T001_BLACK_LEVEL_CALIBRATION,
- value);
- if (ret < 0)
- return ret;
-
- mt9t001->black_level = value;
- break;
-
- case V4L2_CID_BLACK_LEVEL_OFFSET:
- ret = mt9t001_write(client, MT9T001_GREEN1_OFFSET, ctrl->val);
- if (ret < 0)
- return ret;
-
- ret = mt9t001_write(client, MT9T001_GREEN2_OFFSET, ctrl->val);
- if (ret < 0)
- return ret;
-
- ret = mt9t001_write(client, MT9T001_RED_OFFSET, ctrl->val);
- if (ret < 0)
- return ret;
-
- return mt9t001_write(client, MT9T001_BLUE_OFFSET, ctrl->val);
-
- case V4L2_CID_BLACK_LEVEL_CALIBRATE:
- return mt9t001_write(client, MT9T001_BLACK_LEVEL_CALIBRATION,
- MT9T001_BLACK_LEVEL_RECALCULATE |
- mt9t001->black_level);
- }
-
- return 0;
-}
-
-static struct v4l2_ctrl_ops mt9t001_ctrl_ops = {
- .s_ctrl = mt9t001_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config mt9t001_ctrls[] = {
- {
- .ops = &mt9t001_ctrl_ops,
- .id = V4L2_CID_TEST_PATTERN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Test pattern",
- .min = 0,
- .max = 1023,
- .step = 1,
- .def = 0,
- .flags = 0,
- }, {
- .ops = &mt9t001_ctrl_ops,
- .id = V4L2_CID_BLACK_LEVEL_AUTO,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Black Level, Auto",
- .min = 0,
- .max = 1,
- .step = 1,
- .def = 1,
- .flags = 0,
- }, {
- .ops = &mt9t001_ctrl_ops,
- .id = V4L2_CID_BLACK_LEVEL_OFFSET,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Black Level, Offset",
- .min = -256,
- .max = 255,
- .step = 1,
- .def = 32,
- .flags = 0,
- }, {
- .ops = &mt9t001_ctrl_ops,
- .id = V4L2_CID_BLACK_LEVEL_CALIBRATE,
- .type = V4L2_CTRL_TYPE_BUTTON,
- .name = "Black Level, Calibrate",
- .min = 0,
- .max = 0,
- .step = 0,
- .def = 0,
- .flags = V4L2_CTRL_FLAG_WRITE_ONLY,
- },
-};
-
-static const struct v4l2_ctrl_config mt9t001_gains[] = {
- {
- .ops = &mt9t001_ctrl_ops,
- .id = V4L2_CID_GAIN_RED,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain, Red",
- .min = MT9T001_GLOBAL_GAIN_MIN,
- .max = MT9T001_GLOBAL_GAIN_MAX,
- .step = 1,
- .def = MT9T001_GLOBAL_GAIN_MIN,
- .flags = 0,
- }, {
- .ops = &mt9t001_ctrl_ops,
- .id = V4L2_CID_GAIN_GREEN_RED,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain, Green (R)",
- .min = MT9T001_GLOBAL_GAIN_MIN,
- .max = MT9T001_GLOBAL_GAIN_MAX,
- .step = 1,
- .def = MT9T001_GLOBAL_GAIN_MIN,
- .flags = 0,
- }, {
- .ops = &mt9t001_ctrl_ops,
- .id = V4L2_CID_GAIN_GREEN_BLUE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain, Green (B)",
- .min = MT9T001_GLOBAL_GAIN_MIN,
- .max = MT9T001_GLOBAL_GAIN_MAX,
- .step = 1,
- .def = MT9T001_GLOBAL_GAIN_MIN,
- .flags = 0,
- }, {
- .ops = &mt9t001_ctrl_ops,
- .id = V4L2_CID_GAIN_BLUE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain, Blue",
- .min = MT9T001_GLOBAL_GAIN_MIN,
- .max = MT9T001_GLOBAL_GAIN_MAX,
- .step = 1,
- .def = MT9T001_GLOBAL_GAIN_MIN,
- .flags = 0,
- },
-};
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev internal operations
- */
-
-static int mt9t001_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
-{
- struct v4l2_mbus_framefmt *format;
- struct v4l2_rect *crop;
-
- crop = v4l2_subdev_get_try_crop(fh, 0);
- crop->left = MT9T001_COLUMN_START_DEF;
- crop->top = MT9T001_ROW_START_DEF;
- crop->width = MT9T001_WINDOW_WIDTH_DEF + 1;
- crop->height = MT9T001_WINDOW_HEIGHT_DEF + 1;
-
- format = v4l2_subdev_get_try_format(fh, 0);
- format->code = V4L2_MBUS_FMT_SGRBG10_1X10;
- format->width = MT9T001_WINDOW_WIDTH_DEF + 1;
- format->height = MT9T001_WINDOW_HEIGHT_DEF + 1;
- format->field = V4L2_FIELD_NONE;
- format->colorspace = V4L2_COLORSPACE_SRGB;
-
- return 0;
-}
-
-static struct v4l2_subdev_video_ops mt9t001_subdev_video_ops = {
- .s_stream = mt9t001_s_stream,
-};
-
-static struct v4l2_subdev_pad_ops mt9t001_subdev_pad_ops = {
- .enum_mbus_code = mt9t001_enum_mbus_code,
- .enum_frame_size = mt9t001_enum_frame_size,
- .get_fmt = mt9t001_get_format,
- .set_fmt = mt9t001_set_format,
- .get_crop = mt9t001_get_crop,
- .set_crop = mt9t001_set_crop,
-};
-
-static struct v4l2_subdev_ops mt9t001_subdev_ops = {
- .video = &mt9t001_subdev_video_ops,
- .pad = &mt9t001_subdev_pad_ops,
-};
-
-static struct v4l2_subdev_internal_ops mt9t001_subdev_internal_ops = {
- .open = mt9t001_open,
-};
-
-static int mt9t001_video_probe(struct i2c_client *client)
-{
- struct mt9t001_platform_data *pdata = client->dev.platform_data;
- s32 data;
- int ret;
-
- dev_info(&client->dev, "Probing MT9T001 at address 0x%02x\n",
- client->addr);
-
- /* Reset the chip and stop data read out */
- ret = mt9t001_write(client, MT9T001_RESET, 1);
- if (ret < 0)
- return ret;
-
- ret = mt9t001_write(client, MT9T001_RESET, 0);
- if (ret < 0)
- return ret;
-
- ret = mt9t001_write(client, MT9T001_OUTPUT_CONTROL, 0);
- if (ret < 0)
- return ret;
-
- /* Configure the pixel clock polarity */
- if (pdata->clk_pol) {
- ret = mt9t001_write(client, MT9T001_PIXEL_CLOCK,
- MT9T001_PIXEL_CLOCK_INVERT);
- if (ret < 0)
- return ret;
- }
-
- /* Read and check the sensor version */
- data = mt9t001_read(client, MT9T001_CHIP_VERSION);
- if (data != MT9T001_CHIP_ID) {
- dev_err(&client->dev, "MT9T001 not detected, wrong version "
- "0x%04x\n", data);
- return -ENODEV;
- }
-
- dev_info(&client->dev, "MT9T001 detected at address 0x%02x\n",
- client->addr);
-
- return ret;
-}
-
-static int mt9t001_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct mt9t001_platform_data *pdata = client->dev.platform_data;
- struct mt9t001 *mt9t001;
- unsigned int i;
- int ret;
-
- if (pdata == NULL) {
- dev_err(&client->dev, "No platform data\n");
- return -EINVAL;
- }
-
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_WORD_DATA)) {
- dev_warn(&client->adapter->dev,
- "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
- return -EIO;
- }
-
- ret = mt9t001_video_probe(client);
- if (ret < 0)
- return ret;
-
- mt9t001 = kzalloc(sizeof(*mt9t001), GFP_KERNEL);
- if (!mt9t001)
- return -ENOMEM;
-
- v4l2_ctrl_handler_init(&mt9t001->ctrls, ARRAY_SIZE(mt9t001_ctrls) +
- ARRAY_SIZE(mt9t001_gains) + 3);
-
- v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops,
- V4L2_CID_EXPOSURE, MT9T001_SHUTTER_WIDTH_MIN,
- MT9T001_SHUTTER_WIDTH_MAX, 1,
- MT9T001_SHUTTER_WIDTH_DEF);
- v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops,
- V4L2_CID_BLACK_LEVEL, 1, 1, 1, 1);
- v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops,
- V4L2_CID_PIXEL_RATE, pdata->ext_clk, pdata->ext_clk,
- 1, pdata->ext_clk);
-
- for (i = 0; i < ARRAY_SIZE(mt9t001_ctrls); ++i)
- v4l2_ctrl_new_custom(&mt9t001->ctrls, &mt9t001_ctrls[i], NULL);
-
- for (i = 0; i < ARRAY_SIZE(mt9t001_gains); ++i)
- mt9t001->gains[i] = v4l2_ctrl_new_custom(&mt9t001->ctrls,
- &mt9t001_gains[i], NULL);
-
- v4l2_ctrl_cluster(ARRAY_SIZE(mt9t001_gains), mt9t001->gains);
-
- mt9t001->subdev.ctrl_handler = &mt9t001->ctrls;
-
- if (mt9t001->ctrls.error) {
- printk(KERN_INFO "%s: control initialization error %d\n",
- __func__, mt9t001->ctrls.error);
- ret = -EINVAL;
- goto done;
- }
-
- mt9t001->crop.left = MT9T001_COLUMN_START_DEF;
- mt9t001->crop.top = MT9T001_ROW_START_DEF;
- mt9t001->crop.width = MT9T001_WINDOW_WIDTH_DEF + 1;
- mt9t001->crop.height = MT9T001_WINDOW_HEIGHT_DEF + 1;
-
- mt9t001->format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
- mt9t001->format.width = MT9T001_WINDOW_WIDTH_DEF + 1;
- mt9t001->format.height = MT9T001_WINDOW_HEIGHT_DEF + 1;
- mt9t001->format.field = V4L2_FIELD_NONE;
- mt9t001->format.colorspace = V4L2_COLORSPACE_SRGB;
-
- v4l2_i2c_subdev_init(&mt9t001->subdev, client, &mt9t001_subdev_ops);
- mt9t001->subdev.internal_ops = &mt9t001_subdev_internal_ops;
- mt9t001->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- mt9t001->pad.flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_init(&mt9t001->subdev.entity, 1, &mt9t001->pad, 0);
-
-done:
- if (ret < 0) {
- v4l2_ctrl_handler_free(&mt9t001->ctrls);
- media_entity_cleanup(&mt9t001->subdev.entity);
- kfree(mt9t001);
- }
-
- return ret;
-}
-
-static int mt9t001_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct mt9t001 *mt9t001 = to_mt9t001(subdev);
-
- v4l2_ctrl_handler_free(&mt9t001->ctrls);
- v4l2_device_unregister_subdev(subdev);
- media_entity_cleanup(&subdev->entity);
- kfree(mt9t001);
- return 0;
-}
-
-static const struct i2c_device_id mt9t001_id[] = {
- { "mt9t001", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, mt9t001_id);
-
-static struct i2c_driver mt9t001_driver = {
- .driver = {
- .name = "mt9t001",
- },
- .probe = mt9t001_probe,
- .remove = mt9t001_remove,
- .id_table = mt9t001_id,
-};
-
-module_i2c_driver(mt9t001_driver);
-
-MODULE_DESCRIPTION("Aptina (Micron) MT9T001 Camera driver");
-MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
deleted file mode 100644
index 1415074138a..00000000000
--- a/drivers/media/video/mt9t031.c
+++ /dev/null
@@ -1,857 +0,0 @@
-/*
- * Driver for MT9T031 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2008, Guennadi Liakhovetski, DENX Software Engineering <lg@denx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/pm.h>
-#include <linux/slab.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/videodev2.h>
-#include <linux/module.h>
-
-#include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-ctrls.h>
-
-/*
- * ATTENTION: this driver still cannot be used outside of the soc-camera
- * framework because of its PM implementation, using the video_device node.
- * If hardware becomes available for testing, alternative PM approaches shall
- * be considered and tested.
- */
-
-/*
- * mt9t031 i2c address 0x5d
- * The platform has to define i2c_board_info and link to it from
- * struct soc_camera_link
- */
-
-/* mt9t031 selected register addresses */
-#define MT9T031_CHIP_VERSION 0x00
-#define MT9T031_ROW_START 0x01
-#define MT9T031_COLUMN_START 0x02
-#define MT9T031_WINDOW_HEIGHT 0x03
-#define MT9T031_WINDOW_WIDTH 0x04
-#define MT9T031_HORIZONTAL_BLANKING 0x05
-#define MT9T031_VERTICAL_BLANKING 0x06
-#define MT9T031_OUTPUT_CONTROL 0x07
-#define MT9T031_SHUTTER_WIDTH_UPPER 0x08
-#define MT9T031_SHUTTER_WIDTH 0x09
-#define MT9T031_PIXEL_CLOCK_CONTROL 0x0a
-#define MT9T031_FRAME_RESTART 0x0b
-#define MT9T031_SHUTTER_DELAY 0x0c
-#define MT9T031_RESET 0x0d
-#define MT9T031_READ_MODE_1 0x1e
-#define MT9T031_READ_MODE_2 0x20
-#define MT9T031_READ_MODE_3 0x21
-#define MT9T031_ROW_ADDRESS_MODE 0x22
-#define MT9T031_COLUMN_ADDRESS_MODE 0x23
-#define MT9T031_GLOBAL_GAIN 0x35
-#define MT9T031_CHIP_ENABLE 0xF8
-
-#define MT9T031_MAX_HEIGHT 1536
-#define MT9T031_MAX_WIDTH 2048
-#define MT9T031_MIN_HEIGHT 2
-#define MT9T031_MIN_WIDTH 18
-#define MT9T031_HORIZONTAL_BLANK 142
-#define MT9T031_VERTICAL_BLANK 25
-#define MT9T031_COLUMN_SKIP 32
-#define MT9T031_ROW_SKIP 20
-
-struct mt9t031 {
- struct v4l2_subdev subdev;
- struct v4l2_ctrl_handler hdl;
- struct {
- /* exposure/auto-exposure cluster */
- struct v4l2_ctrl *autoexposure;
- struct v4l2_ctrl *exposure;
- };
- struct v4l2_rect rect; /* Sensor window */
- int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
- u16 xskip;
- u16 yskip;
- unsigned int total_h;
- unsigned short y_skip_top; /* Lines to skip at the top */
-};
-
-static struct mt9t031 *to_mt9t031(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client), struct mt9t031, subdev);
-}
-
-static int reg_read(struct i2c_client *client, const u8 reg)
-{
- return i2c_smbus_read_word_swapped(client, reg);
-}
-
-static int reg_write(struct i2c_client *client, const u8 reg,
- const u16 data)
-{
- return i2c_smbus_write_word_swapped(client, reg, data);
-}
-
-static int reg_set(struct i2c_client *client, const u8 reg,
- const u16 data)
-{
- int ret;
-
- ret = reg_read(client, reg);
- if (ret < 0)
- return ret;
- return reg_write(client, reg, ret | data);
-}
-
-static int reg_clear(struct i2c_client *client, const u8 reg,
- const u16 data)
-{
- int ret;
-
- ret = reg_read(client, reg);
- if (ret < 0)
- return ret;
- return reg_write(client, reg, ret & ~data);
-}
-
-static int set_shutter(struct i2c_client *client, const u32 data)
-{
- int ret;
-
- ret = reg_write(client, MT9T031_SHUTTER_WIDTH_UPPER, data >> 16);
-
- if (ret >= 0)
- ret = reg_write(client, MT9T031_SHUTTER_WIDTH, data & 0xffff);
-
- return ret;
-}
-
-static int get_shutter(struct i2c_client *client, u32 *data)
-{
- int ret;
-
- ret = reg_read(client, MT9T031_SHUTTER_WIDTH_UPPER);
- *data = ret << 16;
-
- if (ret >= 0)
- ret = reg_read(client, MT9T031_SHUTTER_WIDTH);
- *data |= ret & 0xffff;
-
- return ret < 0 ? ret : 0;
-}
-
-static int mt9t031_idle(struct i2c_client *client)
-{
- int ret;
-
- /* Disable chip output, synchronous option update */
- ret = reg_write(client, MT9T031_RESET, 1);
- if (ret >= 0)
- ret = reg_write(client, MT9T031_RESET, 0);
- if (ret >= 0)
- ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
-
- return ret >= 0 ? 0 : -EIO;
-}
-
-static int mt9t031_disable(struct i2c_client *client)
-{
- /* Disable the chip */
- reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
-
- return 0;
-}
-
-static int mt9t031_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
-
- if (enable)
- /* Switch to master "normal" mode */
- ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 2);
- else
- /* Stop sensor readout */
- ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
-
- if (ret < 0)
- return -EIO;
-
- return 0;
-}
-
-/* target must be _even_ */
-static u16 mt9t031_skip(s32 *source, s32 target, s32 max)
-{
- unsigned int skip;
-
- if (*source < target + target / 2) {
- *source = target;
- return 1;
- }
-
- skip = min(max, *source + target / 2) / target;
- if (skip > 8)
- skip = 8;
- *source = target * skip;
-
- return skip;
-}
-
-/* rect is the sensor rectangle, the caller guarantees parameter validity */
-static int mt9t031_set_params(struct i2c_client *client,
- struct v4l2_rect *rect, u16 xskip, u16 yskip)
-{
- struct mt9t031 *mt9t031 = to_mt9t031(client);
- int ret;
- u16 xbin, ybin;
- const u16 hblank = MT9T031_HORIZONTAL_BLANK,
- vblank = MT9T031_VERTICAL_BLANK;
-
- xbin = min(xskip, (u16)3);
- ybin = min(yskip, (u16)3);
-
- /*
- * Could just do roundup(rect->left, [xy]bin * 2); but this is cheaper.
- * There is always a valid suitably aligned value. The worst case is
- * xbin = 3, width = 2048. Then we will start at 36, the last read out
- * pixel will be 2083, which is < 2085 - first black pixel.
- *
- * MT9T031 datasheet imposes window left border alignment, depending on
- * the selected xskip. Failing to conform to this requirement produces
- * dark horizontal stripes in the image. However, even obeying to this
- * requirement doesn't eliminate the stripes in all configurations. They
- * appear "locally reproducibly," but can differ between tests under
- * different lighting conditions.
- */
- switch (xbin) {
- case 1:
- rect->left &= ~1;
- break;
- case 2:
- rect->left &= ~3;
- break;
- case 3:
- rect->left = rect->left > roundup(MT9T031_COLUMN_SKIP, 6) ?
- (rect->left / 6) * 6 : roundup(MT9T031_COLUMN_SKIP, 6);
- }
-
- rect->top &= ~1;
-
- dev_dbg(&client->dev, "skip %u:%u, rect %ux%u@%u:%u\n",
- xskip, yskip, rect->width, rect->height, rect->left, rect->top);
-
- /* Disable register update, reconfigure atomically */
- ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 1);
- if (ret < 0)
- return ret;
-
- /* Blanking and start values - default... */
- ret = reg_write(client, MT9T031_HORIZONTAL_BLANKING, hblank);
- if (ret >= 0)
- ret = reg_write(client, MT9T031_VERTICAL_BLANKING, vblank);
-
- if (yskip != mt9t031->yskip || xskip != mt9t031->xskip) {
- /* Binning, skipping */
- if (ret >= 0)
- ret = reg_write(client, MT9T031_COLUMN_ADDRESS_MODE,
- ((xbin - 1) << 4) | (xskip - 1));
- if (ret >= 0)
- ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE,
- ((ybin - 1) << 4) | (yskip - 1));
- }
- dev_dbg(&client->dev, "new physical left %u, top %u\n",
- rect->left, rect->top);
-
- /*
- * The caller provides a supported format, as guaranteed by
- * .try_mbus_fmt(), soc_camera_s_crop() and soc_camera_cropcap()
- */
- if (ret >= 0)
- ret = reg_write(client, MT9T031_COLUMN_START, rect->left);
- if (ret >= 0)
- ret = reg_write(client, MT9T031_ROW_START, rect->top);
- if (ret >= 0)
- ret = reg_write(client, MT9T031_WINDOW_WIDTH, rect->width - 1);
- if (ret >= 0)
- ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
- rect->height + mt9t031->y_skip_top - 1);
- if (ret >= 0 && v4l2_ctrl_g_ctrl(mt9t031->autoexposure) == V4L2_EXPOSURE_AUTO) {
- mt9t031->total_h = rect->height + mt9t031->y_skip_top + vblank;
-
- ret = set_shutter(client, mt9t031->total_h);
- }
-
- /* Re-enable register update, commit all changes */
- if (ret >= 0)
- ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 1);
-
- if (ret >= 0) {
- mt9t031->rect = *rect;
- mt9t031->xskip = xskip;
- mt9t031->yskip = yskip;
- }
-
- return ret < 0 ? ret : 0;
-}
-
-static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct v4l2_rect rect = a->c;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t031 *mt9t031 = to_mt9t031(client);
-
- rect.width = ALIGN(rect.width, 2);
- rect.height = ALIGN(rect.height, 2);
-
- soc_camera_limit_side(&rect.left, &rect.width,
- MT9T031_COLUMN_SKIP, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH);
-
- soc_camera_limit_side(&rect.top, &rect.height,
- MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT);
-
- return mt9t031_set_params(client, &rect, mt9t031->xskip, mt9t031->yskip);
-}
-
-static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t031 *mt9t031 = to_mt9t031(client);
-
- a->c = mt9t031->rect;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = MT9T031_COLUMN_SKIP;
- a->bounds.top = MT9T031_ROW_SKIP;
- a->bounds.width = MT9T031_MAX_WIDTH;
- a->bounds.height = MT9T031_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int mt9t031_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t031 *mt9t031 = to_mt9t031(client);
-
- mf->width = mt9t031->rect.width / mt9t031->xskip;
- mf->height = mt9t031->rect.height / mt9t031->yskip;
- mf->code = V4L2_MBUS_FMT_SBGGR10_1X10;
- mf->colorspace = V4L2_COLORSPACE_SRGB;
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int mt9t031_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t031 *mt9t031 = to_mt9t031(client);
- u16 xskip, yskip;
- struct v4l2_rect rect = mt9t031->rect;
-
- /*
- * try_fmt has put width and height within limits.
- * S_FMT: use binning and skipping for scaling
- */
- xskip = mt9t031_skip(&rect.width, mf->width, MT9T031_MAX_WIDTH);
- yskip = mt9t031_skip(&rect.height, mf->height, MT9T031_MAX_HEIGHT);
-
- mf->code = V4L2_MBUS_FMT_SBGGR10_1X10;
- mf->colorspace = V4L2_COLORSPACE_SRGB;
-
- /* mt9t031_set_params() doesn't change width and height */
- return mt9t031_set_params(client, &rect, xskip, yskip);
-}
-
-/*
- * If a user window larger than sensor window is requested, we'll increase the
- * sensor window.
- */
-static int mt9t031_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- v4l_bound_align_image(
- &mf->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1,
- &mf->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0);
-
- mf->code = V4L2_MBUS_FMT_SBGGR10_1X10;
- mf->colorspace = V4L2_COLORSPACE_SRGB;
-
- return 0;
-}
-
-static int mt9t031_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t031 *mt9t031 = to_mt9t031(client);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = mt9t031->model;
- id->revision = 0;
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9t031_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
- return -EINVAL;
-
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
- reg->val = reg_read(client, reg->reg);
-
- if (reg->val > 0xffff)
- return -EIO;
-
- return 0;
-}
-
-static int mt9t031_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
- return -EINVAL;
-
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
- if (reg_write(client, reg->reg, reg->val) < 0)
- return -EIO;
-
- return 0;
-}
-#endif
-
-static int mt9t031_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct mt9t031 *mt9t031 = container_of(ctrl->handler,
- struct mt9t031, hdl);
- const u32 shutter_max = MT9T031_MAX_HEIGHT + MT9T031_VERTICAL_BLANK;
- s32 min, max;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE_AUTO:
- min = mt9t031->exposure->minimum;
- max = mt9t031->exposure->maximum;
- mt9t031->exposure->val =
- (shutter_max / 2 + (mt9t031->total_h - 1) * (max - min))
- / shutter_max + min;
- break;
- }
- return 0;
-}
-
-static int mt9t031_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct mt9t031 *mt9t031 = container_of(ctrl->handler,
- struct mt9t031, hdl);
- struct v4l2_subdev *sd = &mt9t031->subdev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct v4l2_ctrl *exp = mt9t031->exposure;
- int data;
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- if (ctrl->val)
- data = reg_set(client, MT9T031_READ_MODE_2, 0x8000);
- else
- data = reg_clear(client, MT9T031_READ_MODE_2, 0x8000);
- if (data < 0)
- return -EIO;
- return 0;
- case V4L2_CID_HFLIP:
- if (ctrl->val)
- data = reg_set(client, MT9T031_READ_MODE_2, 0x4000);
- else
- data = reg_clear(client, MT9T031_READ_MODE_2, 0x4000);
- if (data < 0)
- return -EIO;
- return 0;
- case V4L2_CID_GAIN:
- /* See Datasheet Table 7, Gain settings. */
- if (ctrl->val <= ctrl->default_value) {
- /* Pack it into 0..1 step 0.125, register values 0..8 */
- unsigned long range = ctrl->default_value - ctrl->minimum;
- data = ((ctrl->val - ctrl->minimum) * 8 + range / 2) / range;
-
- dev_dbg(&client->dev, "Setting gain %d\n", data);
- data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
- if (data < 0)
- return -EIO;
- } else {
- /* Pack it into 1.125..128 variable step, register values 9..0x7860 */
- /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
- unsigned long range = ctrl->maximum - ctrl->default_value - 1;
- /* calculated gain: map 65..127 to 9..1024 step 0.125 */
- unsigned long gain = ((ctrl->val - ctrl->default_value - 1) *
- 1015 + range / 2) / range + 9;
-
- if (gain <= 32) /* calculated gain 9..32 -> 9..32 */
- data = gain;
- else if (gain <= 64) /* calculated gain 33..64 -> 0x51..0x60 */
- data = ((gain - 32) * 16 + 16) / 32 + 80;
- else
- /* calculated gain 65..1024 -> (1..120) << 8 + 0x60 */
- data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60;
-
- dev_dbg(&client->dev, "Set gain from 0x%x to 0x%x\n",
- reg_read(client, MT9T031_GLOBAL_GAIN), data);
- data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
- if (data < 0)
- return -EIO;
- }
- return 0;
-
- case V4L2_CID_EXPOSURE_AUTO:
- if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
- unsigned int range = exp->maximum - exp->minimum;
- unsigned int shutter = ((exp->val - exp->minimum) * 1048 +
- range / 2) / range + 1;
- u32 old;
-
- get_shutter(client, &old);
- dev_dbg(&client->dev, "Set shutter from %u to %u\n",
- old, shutter);
- if (set_shutter(client, shutter) < 0)
- return -EIO;
- } else {
- const u16 vblank = MT9T031_VERTICAL_BLANK;
- mt9t031->total_h = mt9t031->rect.height +
- mt9t031->y_skip_top + vblank;
-
- if (set_shutter(client, mt9t031->total_h) < 0)
- return -EIO;
- }
- return 0;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * Power Management:
- * This function does nothing for now but must be present for pm to work
- */
-static int mt9t031_runtime_suspend(struct device *dev)
-{
- return 0;
-}
-
-/*
- * Power Management:
- * COLUMN_ADDRESS_MODE and ROW_ADDRESS_MODE are not rewritten if unchanged
- * they are however changed at reset if the platform hook is present
- * thus we rewrite them with the values stored by the driver
- */
-static int mt9t031_runtime_resume(struct device *dev)
-{
- struct video_device *vdev = to_video_device(dev);
- struct v4l2_subdev *sd = soc_camera_vdev_to_subdev(vdev);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t031 *mt9t031 = to_mt9t031(client);
-
- int ret;
- u16 xbin, ybin;
-
- xbin = min(mt9t031->xskip, (u16)3);
- ybin = min(mt9t031->yskip, (u16)3);
-
- ret = reg_write(client, MT9T031_COLUMN_ADDRESS_MODE,
- ((xbin - 1) << 4) | (mt9t031->xskip - 1));
- if (ret < 0)
- return ret;
-
- ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE,
- ((ybin - 1) << 4) | (mt9t031->yskip - 1));
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct dev_pm_ops mt9t031_dev_pm_ops = {
- .runtime_suspend = mt9t031_runtime_suspend,
- .runtime_resume = mt9t031_runtime_resume,
-};
-
-static struct device_type mt9t031_dev_type = {
- .name = "MT9T031",
- .pm = &mt9t031_dev_pm_ops,
-};
-
-static int mt9t031_s_power(struct v4l2_subdev *sd, int on)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct video_device *vdev = soc_camera_i2c_to_vdev(client);
-
- if (on)
- vdev->dev.type = &mt9t031_dev_type;
- else
- vdev->dev.type = NULL;
-
- return 0;
-}
-
-/*
- * Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one
- */
-static int mt9t031_video_probe(struct i2c_client *client)
-{
- struct mt9t031 *mt9t031 = to_mt9t031(client);
- s32 data;
- int ret;
-
- /* Enable the chip */
- data = reg_write(client, MT9T031_CHIP_ENABLE, 1);
- dev_dbg(&client->dev, "write: %d\n", data);
-
- /* Read out the chip version register */
- data = reg_read(client, MT9T031_CHIP_VERSION);
-
- switch (data) {
- case 0x1621:
- mt9t031->model = V4L2_IDENT_MT9T031;
- break;
- default:
- dev_err(&client->dev,
- "No MT9T031 chip detected, register read %x\n", data);
- return -ENODEV;
- }
-
- dev_info(&client->dev, "Detected a MT9T031 chip ID %x\n", data);
-
- ret = mt9t031_idle(client);
- if (ret < 0)
- dev_err(&client->dev, "Failed to initialise the camera\n");
- else
- v4l2_ctrl_handler_setup(&mt9t031->hdl);
-
- return ret;
-}
-
-static int mt9t031_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t031 *mt9t031 = to_mt9t031(client);
-
- *lines = mt9t031->y_skip_top;
-
- return 0;
-}
-
-static const struct v4l2_ctrl_ops mt9t031_ctrl_ops = {
- .g_volatile_ctrl = mt9t031_g_volatile_ctrl,
- .s_ctrl = mt9t031_s_ctrl,
-};
-
-static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
- .g_chip_ident = mt9t031_g_chip_ident,
- .s_power = mt9t031_s_power,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = mt9t031_g_register,
- .s_register = mt9t031_s_register,
-#endif
-};
-
-static int mt9t031_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index)
- return -EINVAL;
-
- *code = V4L2_MBUS_FMT_SBGGR10_1X10;
- return 0;
-}
-
-static int mt9t031_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
- V4L2_MBUS_PCLK_SAMPLE_FALLING | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH;
- cfg->type = V4L2_MBUS_PARALLEL;
- cfg->flags = soc_camera_apply_board_flags(icl, cfg);
-
- return 0;
-}
-
-static int mt9t031_s_mbus_config(struct v4l2_subdev *sd,
- const struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- if (soc_camera_apply_board_flags(icl, cfg) &
- V4L2_MBUS_PCLK_SAMPLE_FALLING)
- return reg_clear(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
- else
- return reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
-}
-
-static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
- .s_stream = mt9t031_s_stream,
- .s_mbus_fmt = mt9t031_s_fmt,
- .g_mbus_fmt = mt9t031_g_fmt,
- .try_mbus_fmt = mt9t031_try_fmt,
- .s_crop = mt9t031_s_crop,
- .g_crop = mt9t031_g_crop,
- .cropcap = mt9t031_cropcap,
- .enum_mbus_fmt = mt9t031_enum_fmt,
- .g_mbus_config = mt9t031_g_mbus_config,
- .s_mbus_config = mt9t031_s_mbus_config,
-};
-
-static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = {
- .g_skip_top_lines = mt9t031_g_skip_top_lines,
-};
-
-static struct v4l2_subdev_ops mt9t031_subdev_ops = {
- .core = &mt9t031_subdev_core_ops,
- .video = &mt9t031_subdev_video_ops,
- .sensor = &mt9t031_subdev_sensor_ops,
-};
-
-static int mt9t031_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct mt9t031 *mt9t031;
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- int ret;
-
- if (!icl) {
- dev_err(&client->dev, "MT9T031 driver needs platform data\n");
- return -EINVAL;
- }
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
- dev_warn(&adapter->dev,
- "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
- return -EIO;
- }
-
- mt9t031 = kzalloc(sizeof(struct mt9t031), GFP_KERNEL);
- if (!mt9t031)
- return -ENOMEM;
-
- v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops);
- v4l2_ctrl_handler_init(&mt9t031->hdl, 5);
- v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
- V4L2_CID_GAIN, 0, 127, 1, 64);
-
- /*
- * Simulated autoexposure. If enabled, we calculate shutter width
- * ourselves in the driver based on vertical blanking and frame width
- */
- mt9t031->autoexposure = v4l2_ctrl_new_std_menu(&mt9t031->hdl,
- &mt9t031_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
- V4L2_EXPOSURE_AUTO);
- mt9t031->exposure = v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
- V4L2_CID_EXPOSURE, 1, 255, 1, 255);
-
- mt9t031->subdev.ctrl_handler = &mt9t031->hdl;
- if (mt9t031->hdl.error) {
- int err = mt9t031->hdl.error;
-
- kfree(mt9t031);
- return err;
- }
- v4l2_ctrl_auto_cluster(2, &mt9t031->autoexposure,
- V4L2_EXPOSURE_MANUAL, true);
-
- mt9t031->y_skip_top = 0;
- mt9t031->rect.left = MT9T031_COLUMN_SKIP;
- mt9t031->rect.top = MT9T031_ROW_SKIP;
- mt9t031->rect.width = MT9T031_MAX_WIDTH;
- mt9t031->rect.height = MT9T031_MAX_HEIGHT;
-
- mt9t031->xskip = 1;
- mt9t031->yskip = 1;
-
- mt9t031_idle(client);
-
- ret = mt9t031_video_probe(client);
-
- mt9t031_disable(client);
-
- if (ret) {
- v4l2_ctrl_handler_free(&mt9t031->hdl);
- kfree(mt9t031);
- }
-
- return ret;
-}
-
-static int mt9t031_remove(struct i2c_client *client)
-{
- struct mt9t031 *mt9t031 = to_mt9t031(client);
-
- v4l2_device_unregister_subdev(&mt9t031->subdev);
- v4l2_ctrl_handler_free(&mt9t031->hdl);
- kfree(mt9t031);
-
- return 0;
-}
-
-static const struct i2c_device_id mt9t031_id[] = {
- { "mt9t031", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, mt9t031_id);
-
-static struct i2c_driver mt9t031_i2c_driver = {
- .driver = {
- .name = "mt9t031",
- },
- .probe = mt9t031_probe,
- .remove = mt9t031_remove,
- .id_table = mt9t031_id,
-};
-
-module_i2c_driver(mt9t031_i2c_driver);
-
-MODULE_DESCRIPTION("Micron MT9T031 Camera driver");
-MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c
deleted file mode 100644
index e1ae46a7ee9..00000000000
--- a/drivers/media/video/mt9t112.c
+++ /dev/null
@@ -1,1125 +0,0 @@
-/*
- * mt9t112 Camera Driver
- *
- * Copyright (C) 2009 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on ov772x driver, mt9m111 driver,
- *
- * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
- * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr>
- * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
- * Copyright (C) 2008 Magnus Damm
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/videodev2.h>
-
-#include <media/mt9t112.h>
-#include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-common.h>
-
-/* you can check PLL/clock info */
-/* #define EXT_CLOCK 24000000 */
-
-/************************************************************************
- macro
-************************************************************************/
-/*
- * frame size
- */
-#define MAX_WIDTH 2048
-#define MAX_HEIGHT 1536
-
-#define VGA_WIDTH 640
-#define VGA_HEIGHT 480
-
-/*
- * macro of read/write
- */
-#define ECHECKER(ret, x) \
- do { \
- (ret) = (x); \
- if ((ret) < 0) \
- return (ret); \
- } while (0)
-
-#define mt9t112_reg_write(ret, client, a, b) \
- ECHECKER(ret, __mt9t112_reg_write(client, a, b))
-#define mt9t112_mcu_write(ret, client, a, b) \
- ECHECKER(ret, __mt9t112_mcu_write(client, a, b))
-
-#define mt9t112_reg_mask_set(ret, client, a, b, c) \
- ECHECKER(ret, __mt9t112_reg_mask_set(client, a, b, c))
-#define mt9t112_mcu_mask_set(ret, client, a, b, c) \
- ECHECKER(ret, __mt9t112_mcu_mask_set(client, a, b, c))
-
-#define mt9t112_reg_read(ret, client, a) \
- ECHECKER(ret, __mt9t112_reg_read(client, a))
-
-/*
- * Logical address
- */
-#define _VAR(id, offset, base) (base | (id & 0x1f) << 10 | (offset & 0x3ff))
-#define VAR(id, offset) _VAR(id, offset, 0x0000)
-#define VAR8(id, offset) _VAR(id, offset, 0x8000)
-
-/************************************************************************
- struct
-************************************************************************/
-struct mt9t112_format {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
- u16 fmt;
- u16 order;
-};
-
-struct mt9t112_priv {
- struct v4l2_subdev subdev;
- struct mt9t112_camera_info *info;
- struct i2c_client *client;
- struct v4l2_rect frame;
- const struct mt9t112_format *format;
- int model;
- u32 flags;
-/* for flags */
-#define INIT_DONE (1 << 0)
-#define PCLK_RISING (1 << 1)
-};
-
-/************************************************************************
- supported format
-************************************************************************/
-
-static const struct mt9t112_format mt9t112_cfmts[] = {
- {
- .code = V4L2_MBUS_FMT_UYVY8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .fmt = 1,
- .order = 0,
- }, {
- .code = V4L2_MBUS_FMT_VYUY8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .fmt = 1,
- .order = 1,
- }, {
- .code = V4L2_MBUS_FMT_YUYV8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .fmt = 1,
- .order = 2,
- }, {
- .code = V4L2_MBUS_FMT_YVYU8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .fmt = 1,
- .order = 3,
- }, {
- .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .fmt = 8,
- .order = 2,
- }, {
- .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .fmt = 4,
- .order = 2,
- },
-};
-
-/************************************************************************
- general function
-************************************************************************/
-static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client),
- struct mt9t112_priv,
- subdev);
-}
-
-static int __mt9t112_reg_read(const struct i2c_client *client, u16 command)
-{
- struct i2c_msg msg[2];
- u8 buf[2];
- int ret;
-
- command = swab16(command);
-
- msg[0].addr = client->addr;
- msg[0].flags = 0;
- msg[0].len = 2;
- msg[0].buf = (u8 *)&command;
-
- msg[1].addr = client->addr;
- msg[1].flags = I2C_M_RD;
- msg[1].len = 2;
- msg[1].buf = buf;
-
- /*
- * if return value of this function is < 0,
- * it mean error.
- * else, under 16bit is valid data.
- */
- ret = i2c_transfer(client->adapter, msg, 2);
- if (ret < 0)
- return ret;
-
- memcpy(&ret, buf, 2);
- return swab16(ret);
-}
-
-static int __mt9t112_reg_write(const struct i2c_client *client,
- u16 command, u16 data)
-{
- struct i2c_msg msg;
- u8 buf[4];
- int ret;
-
- command = swab16(command);
- data = swab16(data);
-
- memcpy(buf + 0, &command, 2);
- memcpy(buf + 2, &data, 2);
-
- msg.addr = client->addr;
- msg.flags = 0;
- msg.len = 4;
- msg.buf = buf;
-
- /*
- * i2c_transfer return message length,
- * but this function should return 0 if correct case
- */
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret >= 0)
- ret = 0;
-
- return ret;
-}
-
-static int __mt9t112_reg_mask_set(const struct i2c_client *client,
- u16 command,
- u16 mask,
- u16 set)
-{
- int val = __mt9t112_reg_read(client, command);
- if (val < 0)
- return val;
-
- val &= ~mask;
- val |= set & mask;
-
- return __mt9t112_reg_write(client, command, val);
-}
-
-/* mcu access */
-static int __mt9t112_mcu_read(const struct i2c_client *client, u16 command)
-{
- int ret;
-
- ret = __mt9t112_reg_write(client, 0x098E, command);
- if (ret < 0)
- return ret;
-
- return __mt9t112_reg_read(client, 0x0990);
-}
-
-static int __mt9t112_mcu_write(const struct i2c_client *client,
- u16 command, u16 data)
-{
- int ret;
-
- ret = __mt9t112_reg_write(client, 0x098E, command);
- if (ret < 0)
- return ret;
-
- return __mt9t112_reg_write(client, 0x0990, data);
-}
-
-static int __mt9t112_mcu_mask_set(const struct i2c_client *client,
- u16 command,
- u16 mask,
- u16 set)
-{
- int val = __mt9t112_mcu_read(client, command);
- if (val < 0)
- return val;
-
- val &= ~mask;
- val |= set & mask;
-
- return __mt9t112_mcu_write(client, command, val);
-}
-
-static int mt9t112_reset(const struct i2c_client *client)
-{
- int ret;
-
- mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0001);
- msleep(1);
- mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0000);
-
- return ret;
-}
-
-#ifndef EXT_CLOCK
-#define CLOCK_INFO(a, b)
-#else
-#define CLOCK_INFO(a, b) mt9t112_clock_info(a, b)
-static int mt9t112_clock_info(const struct i2c_client *client, u32 ext)
-{
- int m, n, p1, p2, p3, p4, p5, p6, p7;
- u32 vco, clk;
- char *enable;
-
- ext /= 1000; /* kbyte order */
-
- mt9t112_reg_read(n, client, 0x0012);
- p1 = n & 0x000f;
- n = n >> 4;
- p2 = n & 0x000f;
- n = n >> 4;
- p3 = n & 0x000f;
-
- mt9t112_reg_read(n, client, 0x002a);
- p4 = n & 0x000f;
- n = n >> 4;
- p5 = n & 0x000f;
- n = n >> 4;
- p6 = n & 0x000f;
-
- mt9t112_reg_read(n, client, 0x002c);
- p7 = n & 0x000f;
-
- mt9t112_reg_read(n, client, 0x0010);
- m = n & 0x00ff;
- n = (n >> 8) & 0x003f;
-
- enable = ((6000 > ext) || (54000 < ext)) ? "X" : "";
- dev_dbg(&client->dev, "EXTCLK : %10u K %s\n", ext, enable);
-
- vco = 2 * m * ext / (n+1);
- enable = ((384000 > vco) || (768000 < vco)) ? "X" : "";
- dev_dbg(&client->dev, "VCO : %10u K %s\n", vco, enable);
-
- clk = vco / (p1+1) / (p2+1);
- enable = (96000 < clk) ? "X" : "";
- dev_dbg(&client->dev, "PIXCLK : %10u K %s\n", clk, enable);
-
- clk = vco / (p3+1);
- enable = (768000 < clk) ? "X" : "";
- dev_dbg(&client->dev, "MIPICLK : %10u K %s\n", clk, enable);
-
- clk = vco / (p6+1);
- enable = (96000 < clk) ? "X" : "";
- dev_dbg(&client->dev, "MCU CLK : %10u K %s\n", clk, enable);
-
- clk = vco / (p5+1);
- enable = (54000 < clk) ? "X" : "";
- dev_dbg(&client->dev, "SOC CLK : %10u K %s\n", clk, enable);
-
- clk = vco / (p4+1);
- enable = (70000 < clk) ? "X" : "";
- dev_dbg(&client->dev, "Sensor CLK : %10u K %s\n", clk, enable);
-
- clk = vco / (p7+1);
- dev_dbg(&client->dev, "External sensor : %10u K\n", clk);
-
- clk = ext / (n+1);
- enable = ((2000 > clk) || (24000 < clk)) ? "X" : "";
- dev_dbg(&client->dev, "PFD : %10u K %s\n", clk, enable);
-
- return 0;
-}
-#endif
-
-static void mt9t112_frame_check(u32 *width, u32 *height, u32 *left, u32 *top)
-{
- soc_camera_limit_side(left, width, 0, 0, MAX_WIDTH);
- soc_camera_limit_side(top, height, 0, 0, MAX_HEIGHT);
-}
-
-static int mt9t112_set_a_frame_size(const struct i2c_client *client,
- u16 width,
- u16 height)
-{
- int ret;
- u16 wstart = (MAX_WIDTH - width) / 2;
- u16 hstart = (MAX_HEIGHT - height) / 2;
-
- /* (Context A) Image Width/Height */
- mt9t112_mcu_write(ret, client, VAR(26, 0), width);
- mt9t112_mcu_write(ret, client, VAR(26, 2), height);
-
- /* (Context A) Output Width/Height */
- mt9t112_mcu_write(ret, client, VAR(18, 43), 8 + width);
- mt9t112_mcu_write(ret, client, VAR(18, 45), 8 + height);
-
- /* (Context A) Start Row/Column */
- mt9t112_mcu_write(ret, client, VAR(18, 2), 4 + hstart);
- mt9t112_mcu_write(ret, client, VAR(18, 4), 4 + wstart);
-
- /* (Context A) End Row/Column */
- mt9t112_mcu_write(ret, client, VAR(18, 6), 11 + height + hstart);
- mt9t112_mcu_write(ret, client, VAR(18, 8), 11 + width + wstart);
-
- mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
-
- return ret;
-}
-
-static int mt9t112_set_pll_dividers(const struct i2c_client *client,
- u8 m, u8 n,
- u8 p1, u8 p2, u8 p3,
- u8 p4, u8 p5, u8 p6,
- u8 p7)
-{
- int ret;
- u16 val;
-
- /* N/M */
- val = (n << 8) |
- (m << 0);
- mt9t112_reg_mask_set(ret, client, 0x0010, 0x3fff, val);
-
- /* P1/P2/P3 */
- val = ((p3 & 0x0F) << 8) |
- ((p2 & 0x0F) << 4) |
- ((p1 & 0x0F) << 0);
- mt9t112_reg_mask_set(ret, client, 0x0012, 0x0fff, val);
-
- /* P4/P5/P6 */
- val = (0x7 << 12) |
- ((p6 & 0x0F) << 8) |
- ((p5 & 0x0F) << 4) |
- ((p4 & 0x0F) << 0);
- mt9t112_reg_mask_set(ret, client, 0x002A, 0x7fff, val);
-
- /* P7 */
- val = (0x1 << 12) |
- ((p7 & 0x0F) << 0);
- mt9t112_reg_mask_set(ret, client, 0x002C, 0x100f, val);
-
- return ret;
-}
-
-static int mt9t112_init_pll(const struct i2c_client *client)
-{
- struct mt9t112_priv *priv = to_mt9t112(client);
- int data, i, ret;
-
- mt9t112_reg_mask_set(ret, client, 0x0014, 0x003, 0x0001);
-
- /* PLL control: BYPASS PLL = 8517 */
- mt9t112_reg_write(ret, client, 0x0014, 0x2145);
-
- /* Replace these registers when new timing parameters are generated */
- mt9t112_set_pll_dividers(client,
- priv->info->divider.m,
- priv->info->divider.n,
- priv->info->divider.p1,
- priv->info->divider.p2,
- priv->info->divider.p3,
- priv->info->divider.p4,
- priv->info->divider.p5,
- priv->info->divider.p6,
- priv->info->divider.p7);
-
- /*
- * TEST_BYPASS on
- * PLL_ENABLE on
- * SEL_LOCK_DET on
- * TEST_BYPASS off
- */
- mt9t112_reg_write(ret, client, 0x0014, 0x2525);
- mt9t112_reg_write(ret, client, 0x0014, 0x2527);
- mt9t112_reg_write(ret, client, 0x0014, 0x3427);
- mt9t112_reg_write(ret, client, 0x0014, 0x3027);
-
- mdelay(10);
-
- /*
- * PLL_BYPASS off
- * Reference clock count
- * I2C Master Clock Divider
- */
- mt9t112_reg_write(ret, client, 0x0014, 0x3046);
- mt9t112_reg_write(ret, client, 0x0016, 0x0400); /* JPEG initialization workaround */
- mt9t112_reg_write(ret, client, 0x0022, 0x0190);
- mt9t112_reg_write(ret, client, 0x3B84, 0x0212);
-
- /* External sensor clock is PLL bypass */
- mt9t112_reg_write(ret, client, 0x002E, 0x0500);
-
- mt9t112_reg_mask_set(ret, client, 0x0018, 0x0002, 0x0002);
- mt9t112_reg_mask_set(ret, client, 0x3B82, 0x0004, 0x0004);
-
- /* MCU disabled */
- mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0x0004);
-
- /* out of standby */
- mt9t112_reg_mask_set(ret, client, 0x0018, 0x0001, 0);
-
- mdelay(50);
-
- /*
- * Standby Workaround
- * Disable Secondary I2C Pads
- */
- mt9t112_reg_write(ret, client, 0x0614, 0x0001);
- mdelay(1);
- mt9t112_reg_write(ret, client, 0x0614, 0x0001);
- mdelay(1);
- mt9t112_reg_write(ret, client, 0x0614, 0x0001);
- mdelay(1);
- mt9t112_reg_write(ret, client, 0x0614, 0x0001);
- mdelay(1);
- mt9t112_reg_write(ret, client, 0x0614, 0x0001);
- mdelay(1);
- mt9t112_reg_write(ret, client, 0x0614, 0x0001);
- mdelay(1);
-
- /* poll to verify out of standby. Must Poll this bit */
- for (i = 0; i < 100; i++) {
- mt9t112_reg_read(data, client, 0x0018);
- if (!(0x4000 & data))
- break;
-
- mdelay(10);
- }
-
- return ret;
-}
-
-static int mt9t112_init_setting(const struct i2c_client *client)
-{
-
- int ret;
-
- /* Adaptive Output Clock (A) */
- mt9t112_mcu_mask_set(ret, client, VAR(26, 160), 0x0040, 0x0000);
-
- /* Read Mode (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 12), 0x0024);
-
- /* Fine Correction (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 15), 0x00CC);
-
- /* Fine IT Min (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 17), 0x01f1);
-
- /* Fine IT Max Margin (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 19), 0x00fF);
-
- /* Base Frame Lines (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 29), 0x032D);
-
- /* Min Line Length (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 31), 0x073a);
-
- /* Line Length (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 37), 0x07d0);
-
- /* Adaptive Output Clock (B) */
- mt9t112_mcu_mask_set(ret, client, VAR(27, 160), 0x0040, 0x0000);
-
- /* Row Start (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 74), 0x004);
-
- /* Column Start (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 76), 0x004);
-
- /* Row End (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 78), 0x60B);
-
- /* Column End (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 80), 0x80B);
-
- /* Fine Correction (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 87), 0x008C);
-
- /* Fine IT Min (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 89), 0x01F1);
-
- /* Fine IT Max Margin (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 91), 0x00FF);
-
- /* Base Frame Lines (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 101), 0x0668);
-
- /* Min Line Length (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 103), 0x0AF0);
-
- /* Line Length (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 109), 0x0AF0);
-
- /*
- * Flicker Dectection registers
- * This section should be replaced whenever new Timing file is generated
- * All the following registers need to be replaced
- * Following registers are generated from Register Wizard but user can
- * modify them. For detail see auto flicker detection tuning
- */
-
- /* FD_FDPERIOD_SELECT */
- mt9t112_mcu_write(ret, client, VAR8(8, 5), 0x01);
-
- /* PRI_B_CONFIG_FD_ALGO_RUN */
- mt9t112_mcu_write(ret, client, VAR(27, 17), 0x0003);
-
- /* PRI_A_CONFIG_FD_ALGO_RUN */
- mt9t112_mcu_write(ret, client, VAR(26, 17), 0x0003);
-
- /*
- * AFD range detection tuning registers
- */
-
- /* search_f1_50 */
- mt9t112_mcu_write(ret, client, VAR8(18, 165), 0x25);
-
- /* search_f2_50 */
- mt9t112_mcu_write(ret, client, VAR8(18, 166), 0x28);
-
- /* search_f1_60 */
- mt9t112_mcu_write(ret, client, VAR8(18, 167), 0x2C);
-
- /* search_f2_60 */
- mt9t112_mcu_write(ret, client, VAR8(18, 168), 0x2F);
-
- /* period_50Hz (A) */
- mt9t112_mcu_write(ret, client, VAR8(18, 68), 0xBA);
-
- /* secret register by aptina */
- /* period_50Hz (A MSB) */
- mt9t112_mcu_write(ret, client, VAR8(18, 303), 0x00);
-
- /* period_60Hz (A) */
- mt9t112_mcu_write(ret, client, VAR8(18, 69), 0x9B);
-
- /* secret register by aptina */
- /* period_60Hz (A MSB) */
- mt9t112_mcu_write(ret, client, VAR8(18, 301), 0x00);
-
- /* period_50Hz (B) */
- mt9t112_mcu_write(ret, client, VAR8(18, 140), 0x82);
-
- /* secret register by aptina */
- /* period_50Hz (B) MSB */
- mt9t112_mcu_write(ret, client, VAR8(18, 304), 0x00);
-
- /* period_60Hz (B) */
- mt9t112_mcu_write(ret, client, VAR8(18, 141), 0x6D);
-
- /* secret register by aptina */
- /* period_60Hz (B) MSB */
- mt9t112_mcu_write(ret, client, VAR8(18, 302), 0x00);
-
- /* FD Mode */
- mt9t112_mcu_write(ret, client, VAR8(8, 2), 0x10);
-
- /* Stat_min */
- mt9t112_mcu_write(ret, client, VAR8(8, 9), 0x02);
-
- /* Stat_max */
- mt9t112_mcu_write(ret, client, VAR8(8, 10), 0x03);
-
- /* Min_amplitude */
- mt9t112_mcu_write(ret, client, VAR8(8, 12), 0x0A);
-
- /* RX FIFO Watermark (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 70), 0x0014);
-
- /* RX FIFO Watermark (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 142), 0x0014);
-
- /* MCLK: 16MHz
- * PCLK: 73MHz
- * CorePixCLK: 36.5 MHz
- */
- mt9t112_mcu_write(ret, client, VAR8(18, 0x0044), 133);
- mt9t112_mcu_write(ret, client, VAR8(18, 0x0045), 110);
- mt9t112_mcu_write(ret, client, VAR8(18, 0x008c), 130);
- mt9t112_mcu_write(ret, client, VAR8(18, 0x008d), 108);
-
- mt9t112_mcu_write(ret, client, VAR8(18, 0x00A5), 27);
- mt9t112_mcu_write(ret, client, VAR8(18, 0x00a6), 30);
- mt9t112_mcu_write(ret, client, VAR8(18, 0x00a7), 32);
- mt9t112_mcu_write(ret, client, VAR8(18, 0x00a8), 35);
-
- return ret;
-}
-
-static int mt9t112_auto_focus_setting(const struct i2c_client *client)
-{
- int ret;
-
- mt9t112_mcu_write(ret, client, VAR(12, 13), 0x000F);
- mt9t112_mcu_write(ret, client, VAR(12, 23), 0x0F0F);
- mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
-
- mt9t112_reg_write(ret, client, 0x0614, 0x0000);
-
- mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x05);
- mt9t112_mcu_write(ret, client, VAR8(12, 2), 0x02);
- mt9t112_mcu_write(ret, client, VAR(12, 3), 0x0002);
- mt9t112_mcu_write(ret, client, VAR(17, 3), 0x8001);
- mt9t112_mcu_write(ret, client, VAR(17, 11), 0x0025);
- mt9t112_mcu_write(ret, client, VAR(17, 13), 0x0193);
- mt9t112_mcu_write(ret, client, VAR8(17, 33), 0x18);
- mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x05);
-
- return ret;
-}
-
-static int mt9t112_auto_focus_trigger(const struct i2c_client *client)
-{
- int ret;
-
- mt9t112_mcu_write(ret, client, VAR8(12, 25), 0x01);
-
- return ret;
-}
-
-static int mt9t112_init_camera(const struct i2c_client *client)
-{
- int ret;
-
- ECHECKER(ret, mt9t112_reset(client));
-
- ECHECKER(ret, mt9t112_init_pll(client));
-
- ECHECKER(ret, mt9t112_init_setting(client));
-
- ECHECKER(ret, mt9t112_auto_focus_setting(client));
-
- mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0);
-
- /* Analog setting B */
- mt9t112_reg_write(ret, client, 0x3084, 0x2409);
- mt9t112_reg_write(ret, client, 0x3092, 0x0A49);
- mt9t112_reg_write(ret, client, 0x3094, 0x4949);
- mt9t112_reg_write(ret, client, 0x3096, 0x4950);
-
- /*
- * Disable adaptive clock
- * PRI_A_CONFIG_JPEG_OB_TX_CONTROL_VAR
- * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR
- */
- mt9t112_mcu_write(ret, client, VAR(26, 160), 0x0A2E);
- mt9t112_mcu_write(ret, client, VAR(27, 160), 0x0A2E);
-
- /* Configure STatus in Status_before_length Format and enable header */
- /* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */
- mt9t112_mcu_write(ret, client, VAR(27, 144), 0x0CB4);
-
- /* Enable JPEG in context B */
- /* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */
- mt9t112_mcu_write(ret, client, VAR8(27, 142), 0x01);
-
- /* Disable Dac_TXLO */
- mt9t112_reg_write(ret, client, 0x316C, 0x350F);
-
- /* Set max slew rates */
- mt9t112_reg_write(ret, client, 0x1E, 0x777);
-
- return ret;
-}
-
-/************************************************************************
- v4l2_subdev_core_ops
-************************************************************************/
-static int mt9t112_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t112_priv *priv = to_mt9t112(client);
-
- id->ident = priv->model;
- id->revision = 0;
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9t112_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
-
- reg->size = 2;
- mt9t112_reg_read(ret, client, reg->reg);
-
- reg->val = (__u64)ret;
-
- return 0;
-}
-
-static int mt9t112_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
-
- mt9t112_reg_write(ret, client, reg->reg, reg->val);
-
- return ret;
-}
-#endif
-
-static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
- .g_chip_ident = mt9t112_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = mt9t112_g_register,
- .s_register = mt9t112_s_register,
-#endif
-};
-
-
-/************************************************************************
- v4l2_subdev_video_ops
-************************************************************************/
-static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t112_priv *priv = to_mt9t112(client);
- int ret = 0;
-
- if (!enable) {
- /* FIXME
- *
- * If user selected large output size,
- * and used it long time,
- * mt9t112 camera will be very warm.
- *
- * But current driver can not stop mt9t112 camera.
- * So, set small size here to solve this problem.
- */
- mt9t112_set_a_frame_size(client, VGA_WIDTH, VGA_HEIGHT);
- return ret;
- }
-
- if (!(priv->flags & INIT_DONE)) {
- u16 param = PCLK_RISING & priv->flags ? 0x0001 : 0x0000;
-
- ECHECKER(ret, mt9t112_init_camera(client));
-
- /* Invert PCLK (Data sampled on falling edge of pixclk) */
- mt9t112_reg_write(ret, client, 0x3C20, param);
-
- mdelay(5);
-
- priv->flags |= INIT_DONE;
- }
-
- mt9t112_mcu_write(ret, client, VAR(26, 7), priv->format->fmt);
- mt9t112_mcu_write(ret, client, VAR(26, 9), priv->format->order);
- mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
-
- mt9t112_set_a_frame_size(client,
- priv->frame.width,
- priv->frame.height);
-
- ECHECKER(ret, mt9t112_auto_focus_trigger(client));
-
- dev_dbg(&client->dev, "format : %d\n", priv->format->code);
- dev_dbg(&client->dev, "size : %d x %d\n",
- priv->frame.width,
- priv->frame.height);
-
- CLOCK_INFO(client, EXT_CLOCK);
-
- return ret;
-}
-
-static int mt9t112_set_params(struct mt9t112_priv *priv,
- const struct v4l2_rect *rect,
- enum v4l2_mbus_pixelcode code)
-{
- int i;
-
- /*
- * get color format
- */
- for (i = 0; i < ARRAY_SIZE(mt9t112_cfmts); i++)
- if (mt9t112_cfmts[i].code == code)
- break;
-
- if (i == ARRAY_SIZE(mt9t112_cfmts))
- return -EINVAL;
-
- priv->frame = *rect;
-
- /*
- * frame size check
- */
- mt9t112_frame_check(&priv->frame.width, &priv->frame.height,
- &priv->frame.left, &priv->frame.top);
-
- priv->format = mt9t112_cfmts + i;
-
- return 0;
-}
-
-static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = MAX_WIDTH;
- a->bounds.height = MAX_HEIGHT;
- a->defrect.left = 0;
- a->defrect.top = 0;
- a->defrect.width = VGA_WIDTH;
- a->defrect.height = VGA_HEIGHT;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t112_priv *priv = to_mt9t112(client);
-
- a->c = priv->frame;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t112_priv *priv = to_mt9t112(client);
- struct v4l2_rect *rect = &a->c;
-
- return mt9t112_set_params(priv, rect, priv->format->code);
-}
-
-static int mt9t112_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t112_priv *priv = to_mt9t112(client);
-
- mf->width = priv->frame.width;
- mf->height = priv->frame.height;
- mf->colorspace = priv->format->colorspace;
- mf->code = priv->format->code;
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int mt9t112_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t112_priv *priv = to_mt9t112(client);
- struct v4l2_rect rect = {
- .width = mf->width,
- .height = mf->height,
- .left = priv->frame.left,
- .top = priv->frame.top,
- };
- int ret;
-
- ret = mt9t112_set_params(priv, &rect, mf->code);
-
- if (!ret)
- mf->colorspace = priv->format->colorspace;
-
- return ret;
-}
-
-static int mt9t112_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- unsigned int top, left;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(mt9t112_cfmts); i++)
- if (mt9t112_cfmts[i].code == mf->code)
- break;
-
- if (i == ARRAY_SIZE(mt9t112_cfmts)) {
- mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- } else {
- mf->colorspace = mt9t112_cfmts[i].colorspace;
- }
-
- mt9t112_frame_check(&mf->width, &mf->height, &left, &top);
-
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index >= ARRAY_SIZE(mt9t112_cfmts))
- return -EINVAL;
-
- *code = mt9t112_cfmts[index].code;
-
- return 0;
-}
-
-static int mt9t112_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH |
- V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING;
- cfg->type = V4L2_MBUS_PARALLEL;
- cfg->flags = soc_camera_apply_board_flags(icl, cfg);
-
- return 0;
-}
-
-static int mt9t112_s_mbus_config(struct v4l2_subdev *sd,
- const struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- struct mt9t112_priv *priv = to_mt9t112(client);
-
- if (soc_camera_apply_board_flags(icl, cfg) & V4L2_MBUS_PCLK_SAMPLE_RISING)
- priv->flags |= PCLK_RISING;
-
- return 0;
-}
-
-static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = {
- .s_stream = mt9t112_s_stream,
- .g_mbus_fmt = mt9t112_g_fmt,
- .s_mbus_fmt = mt9t112_s_fmt,
- .try_mbus_fmt = mt9t112_try_fmt,
- .cropcap = mt9t112_cropcap,
- .g_crop = mt9t112_g_crop,
- .s_crop = mt9t112_s_crop,
- .enum_mbus_fmt = mt9t112_enum_fmt,
- .g_mbus_config = mt9t112_g_mbus_config,
- .s_mbus_config = mt9t112_s_mbus_config,
-};
-
-/************************************************************************
- i2c driver
-************************************************************************/
-static struct v4l2_subdev_ops mt9t112_subdev_ops = {
- .core = &mt9t112_subdev_core_ops,
- .video = &mt9t112_subdev_video_ops,
-};
-
-static int mt9t112_camera_probe(struct i2c_client *client)
-{
- struct mt9t112_priv *priv = to_mt9t112(client);
- const char *devname;
- int chipid;
-
- /*
- * check and show chip ID
- */
- mt9t112_reg_read(chipid, client, 0x0000);
-
- switch (chipid) {
- case 0x2680:
- devname = "mt9t111";
- priv->model = V4L2_IDENT_MT9T111;
- break;
- case 0x2682:
- devname = "mt9t112";
- priv->model = V4L2_IDENT_MT9T112;
- break;
- default:
- dev_err(&client->dev, "Product ID error %04x\n", chipid);
- return -ENODEV;
- }
-
- dev_info(&client->dev, "%s chip ID %04x\n", devname, chipid);
-
- return 0;
-}
-
-static int mt9t112_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct mt9t112_priv *priv;
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- struct v4l2_rect rect = {
- .width = VGA_WIDTH,
- .height = VGA_HEIGHT,
- .left = (MAX_WIDTH - VGA_WIDTH) / 2,
- .top = (MAX_HEIGHT - VGA_HEIGHT) / 2,
- };
- int ret;
-
- if (!icl || !icl->priv) {
- dev_err(&client->dev, "mt9t112: missing platform data!\n");
- return -EINVAL;
- }
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->info = icl->priv;
-
- v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
-
- ret = mt9t112_camera_probe(client);
- if (ret) {
- kfree(priv);
- return ret;
- }
-
- /* Cannot fail: using the default supported pixel code */
- mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8);
-
- return ret;
-}
-
-static int mt9t112_remove(struct i2c_client *client)
-{
- struct mt9t112_priv *priv = to_mt9t112(client);
-
- kfree(priv);
- return 0;
-}
-
-static const struct i2c_device_id mt9t112_id[] = {
- { "mt9t112", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, mt9t112_id);
-
-static struct i2c_driver mt9t112_i2c_driver = {
- .driver = {
- .name = "mt9t112",
- },
- .probe = mt9t112_probe,
- .remove = mt9t112_remove,
- .id_table = mt9t112_id,
-};
-
-module_i2c_driver(mt9t112_i2c_driver);
-
-MODULE_DESCRIPTION("SoC Camera driver for mt9t112");
-MODULE_AUTHOR("Kuninori Morimoto");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c
deleted file mode 100644
index 6bf01ad6276..00000000000
--- a/drivers/media/video/mt9v011.c
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor
- *
- * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com)
- * This code is placed under the terms of the GNU General Public License v2
- */
-
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <asm/div64.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/mt9v011.h>
-
-MODULE_DESCRIPTION("Micron mt9v011 sensor driver");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-2)");
-
-#define R00_MT9V011_CHIP_VERSION 0x00
-#define R01_MT9V011_ROWSTART 0x01
-#define R02_MT9V011_COLSTART 0x02
-#define R03_MT9V011_HEIGHT 0x03
-#define R04_MT9V011_WIDTH 0x04
-#define R05_MT9V011_HBLANK 0x05
-#define R06_MT9V011_VBLANK 0x06
-#define R07_MT9V011_OUT_CTRL 0x07
-#define R09_MT9V011_SHUTTER_WIDTH 0x09
-#define R0A_MT9V011_CLK_SPEED 0x0a
-#define R0B_MT9V011_RESTART 0x0b
-#define R0C_MT9V011_SHUTTER_DELAY 0x0c
-#define R0D_MT9V011_RESET 0x0d
-#define R1E_MT9V011_DIGITAL_ZOOM 0x1e
-#define R20_MT9V011_READ_MODE 0x20
-#define R2B_MT9V011_GREEN_1_GAIN 0x2b
-#define R2C_MT9V011_BLUE_GAIN 0x2c
-#define R2D_MT9V011_RED_GAIN 0x2d
-#define R2E_MT9V011_GREEN_2_GAIN 0x2e
-#define R35_MT9V011_GLOBAL_GAIN 0x35
-#define RF1_MT9V011_CHIP_ENABLE 0xf1
-
-#define MT9V011_VERSION 0x8232
-#define MT9V011_REV_B_VERSION 0x8243
-
-/* supported controls */
-static struct v4l2_queryctrl mt9v011_qctrl[] = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain",
- .minimum = 0,
- .maximum = (1 << 12) - 1 - 0x0020,
- .step = 1,
- .default_value = 0x0020,
- .flags = 0,
- }, {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Exposure",
- .minimum = 0,
- .maximum = 2047,
- .step = 1,
- .default_value = 0x01fc,
- .flags = 0,
- }, {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Red Balance",
- .minimum = -1 << 9,
- .maximum = (1 << 9) - 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- }, {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Blue Balance",
- .minimum = -1 << 9,
- .maximum = (1 << 9) - 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- }, {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- }, {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Vflip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- }, {
- }
-};
-
-struct mt9v011 {
- struct v4l2_subdev sd;
- unsigned width, height;
- unsigned xtal;
- unsigned hflip:1;
- unsigned vflip:1;
-
- u16 global_gain, exposure;
- s16 red_bal, blue_bal;
-};
-
-static inline struct mt9v011 *to_mt9v011(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct mt9v011, sd);
-}
-
-static int mt9v011_read(struct v4l2_subdev *sd, unsigned char addr)
-{
- struct i2c_client *c = v4l2_get_subdevdata(sd);
- __be16 buffer;
- int rc, val;
-
- rc = i2c_master_send(c, &addr, 1);
- if (rc != 1)
- v4l2_dbg(0, debug, sd,
- "i2c i/o error: rc == %d (should be 1)\n", rc);
-
- msleep(10);
-
- rc = i2c_master_recv(c, (char *)&buffer, 2);
- if (rc != 2)
- v4l2_dbg(0, debug, sd,
- "i2c i/o error: rc == %d (should be 2)\n", rc);
-
- val = be16_to_cpu(buffer);
-
- v4l2_dbg(2, debug, sd, "mt9v011: read 0x%02x = 0x%04x\n", addr, val);
-
- return val;
-}
-
-static void mt9v011_write(struct v4l2_subdev *sd, unsigned char addr,
- u16 value)
-{
- struct i2c_client *c = v4l2_get_subdevdata(sd);
- unsigned char buffer[3];
- int rc;
-
- buffer[0] = addr;
- buffer[1] = value >> 8;
- buffer[2] = value & 0xff;
-
- v4l2_dbg(2, debug, sd,
- "mt9v011: writing 0x%02x 0x%04x\n", buffer[0], value);
- rc = i2c_master_send(c, buffer, 3);
- if (rc != 3)
- v4l2_dbg(0, debug, sd,
- "i2c i/o error: rc == %d (should be 3)\n", rc);
-}
-
-
-struct i2c_reg_value {
- unsigned char reg;
- u16 value;
-};
-
-/*
- * Values used at the original driver
- * Some values are marked as Reserved at the datasheet
- */
-static const struct i2c_reg_value mt9v011_init_default[] = {
- { R0D_MT9V011_RESET, 0x0001 },
- { R0D_MT9V011_RESET, 0x0000 },
-
- { R0C_MT9V011_SHUTTER_DELAY, 0x0000 },
- { R09_MT9V011_SHUTTER_WIDTH, 0x1fc },
-
- { R0A_MT9V011_CLK_SPEED, 0x0000 },
- { R1E_MT9V011_DIGITAL_ZOOM, 0x0000 },
-
- { R07_MT9V011_OUT_CTRL, 0x0002 }, /* chip enable */
-};
-
-
-static u16 calc_mt9v011_gain(s16 lineargain)
-{
-
- u16 digitalgain = 0;
- u16 analogmult = 0;
- u16 analoginit = 0;
-
- if (lineargain < 0)
- lineargain = 0;
-
- /* recommended minimum */
- lineargain += 0x0020;
-
- if (lineargain > 2047)
- lineargain = 2047;
-
- if (lineargain > 1023) {
- digitalgain = 3;
- analogmult = 3;
- analoginit = lineargain / 16;
- } else if (lineargain > 511) {
- digitalgain = 1;
- analogmult = 3;
- analoginit = lineargain / 8;
- } else if (lineargain > 255) {
- analogmult = 3;
- analoginit = lineargain / 4;
- } else if (lineargain > 127) {
- analogmult = 1;
- analoginit = lineargain / 2;
- } else
- analoginit = lineargain;
-
- return analoginit + (analogmult << 7) + (digitalgain << 9);
-
-}
-
-static void set_balance(struct v4l2_subdev *sd)
-{
- struct mt9v011 *core = to_mt9v011(sd);
- u16 green_gain, blue_gain, red_gain;
- u16 exposure;
- s16 bal;
-
- exposure = core->exposure;
-
- green_gain = calc_mt9v011_gain(core->global_gain);
-
- bal = core->global_gain;
- bal += (core->blue_bal * core->global_gain / (1 << 7));
- blue_gain = calc_mt9v011_gain(bal);
-
- bal = core->global_gain;
- bal += (core->red_bal * core->global_gain / (1 << 7));
- red_gain = calc_mt9v011_gain(bal);
-
- mt9v011_write(sd, R2B_MT9V011_GREEN_1_GAIN, green_gain);
- mt9v011_write(sd, R2E_MT9V011_GREEN_2_GAIN, green_gain);
- mt9v011_write(sd, R2C_MT9V011_BLUE_GAIN, blue_gain);
- mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain);
- mt9v011_write(sd, R09_MT9V011_SHUTTER_WIDTH, exposure);
-}
-
-static void calc_fps(struct v4l2_subdev *sd, u32 *numerator, u32 *denominator)
-{
- struct mt9v011 *core = to_mt9v011(sd);
- unsigned height, width, hblank, vblank, speed;
- unsigned row_time, t_time;
- u64 frames_per_ms;
- unsigned tmp;
-
- height = mt9v011_read(sd, R03_MT9V011_HEIGHT);
- width = mt9v011_read(sd, R04_MT9V011_WIDTH);
- hblank = mt9v011_read(sd, R05_MT9V011_HBLANK);
- vblank = mt9v011_read(sd, R06_MT9V011_VBLANK);
- speed = mt9v011_read(sd, R0A_MT9V011_CLK_SPEED);
-
- row_time = (width + 113 + hblank) * (speed + 2);
- t_time = row_time * (height + vblank + 1);
-
- frames_per_ms = core->xtal * 1000l;
- do_div(frames_per_ms, t_time);
- tmp = frames_per_ms;
-
- v4l2_dbg(1, debug, sd, "Programmed to %u.%03u fps (%d pixel clcks)\n",
- tmp / 1000, tmp % 1000, t_time);
-
- if (numerator && denominator) {
- *numerator = 1000;
- *denominator = (u32)frames_per_ms;
- }
-}
-
-static u16 calc_speed(struct v4l2_subdev *sd, u32 numerator, u32 denominator)
-{
- struct mt9v011 *core = to_mt9v011(sd);
- unsigned height, width, hblank, vblank;
- unsigned row_time, line_time;
- u64 t_time, speed;
-
- /* Avoid bogus calculus */
- if (!numerator || !denominator)
- return 0;
-
- height = mt9v011_read(sd, R03_MT9V011_HEIGHT);
- width = mt9v011_read(sd, R04_MT9V011_WIDTH);
- hblank = mt9v011_read(sd, R05_MT9V011_HBLANK);
- vblank = mt9v011_read(sd, R06_MT9V011_VBLANK);
-
- row_time = width + 113 + hblank;
- line_time = height + vblank + 1;
-
- t_time = core->xtal * ((u64)numerator);
- /* round to the closest value */
- t_time += denominator / 2;
- do_div(t_time, denominator);
-
- speed = t_time;
- do_div(speed, row_time * line_time);
-
- /* Avoid having a negative value for speed */
- if (speed < 2)
- speed = 0;
- else
- speed -= 2;
-
- /* Avoid speed overflow */
- if (speed > 15)
- return 15;
-
- return (u16)speed;
-}
-
-static void set_res(struct v4l2_subdev *sd)
-{
- struct mt9v011 *core = to_mt9v011(sd);
- unsigned vstart, hstart;
-
- /*
- * The mt9v011 doesn't have scaling. So, in order to select the desired
- * resolution, we're cropping at the middle of the sensor.
- * hblank and vblank should be adjusted, in order to warrant that
- * we'll preserve the line timings for 30 fps, no matter what resolution
- * is selected.
- * NOTE: datasheet says that width (and height) should be filled with
- * width-1. However, this doesn't work, since one pixel per line will
- * be missing.
- */
-
- hstart = 20 + (640 - core->width) / 2;
- mt9v011_write(sd, R02_MT9V011_COLSTART, hstart);
- mt9v011_write(sd, R04_MT9V011_WIDTH, core->width);
- mt9v011_write(sd, R05_MT9V011_HBLANK, 771 - core->width);
-
- vstart = 8 + (480 - core->height) / 2;
- mt9v011_write(sd, R01_MT9V011_ROWSTART, vstart);
- mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height);
- mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height);
-
- calc_fps(sd, NULL, NULL);
-};
-
-static void set_read_mode(struct v4l2_subdev *sd)
-{
- struct mt9v011 *core = to_mt9v011(sd);
- unsigned mode = 0x1000;
-
- if (core->hflip)
- mode |= 0x4000;
-
- if (core->vflip)
- mode |= 0x8000;
-
- mt9v011_write(sd, R20_MT9V011_READ_MODE, mode);
-}
-
-static int mt9v011_reset(struct v4l2_subdev *sd, u32 val)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(mt9v011_init_default); i++)
- mt9v011_write(sd, mt9v011_init_default[i].reg,
- mt9v011_init_default[i].value);
-
- set_balance(sd);
- set_res(sd);
- set_read_mode(sd);
-
- return 0;
-};
-
-static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- struct mt9v011 *core = to_mt9v011(sd);
-
- v4l2_dbg(1, debug, sd, "g_ctrl called\n");
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- ctrl->value = core->global_gain;
- return 0;
- case V4L2_CID_EXPOSURE:
- ctrl->value = core->exposure;
- return 0;
- case V4L2_CID_RED_BALANCE:
- ctrl->value = core->red_bal;
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- ctrl->value = core->blue_bal;
- return 0;
- case V4L2_CID_HFLIP:
- ctrl->value = core->hflip ? 1 : 0;
- return 0;
- case V4L2_CID_VFLIP:
- ctrl->value = core->vflip ? 1 : 0;
- return 0;
- }
- return -EINVAL;
-}
-
-static int mt9v011_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
-{
- int i;
-
- v4l2_dbg(1, debug, sd, "queryctrl called\n");
-
- for (i = 0; i < ARRAY_SIZE(mt9v011_qctrl); i++)
- if (qc->id && qc->id == mt9v011_qctrl[i].id) {
- memcpy(qc, &(mt9v011_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
-
- return -EINVAL;
-}
-
-
-static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- struct mt9v011 *core = to_mt9v011(sd);
- u8 i, n;
- n = ARRAY_SIZE(mt9v011_qctrl);
-
- for (i = 0; i < n; i++) {
- if (ctrl->id != mt9v011_qctrl[i].id)
- continue;
- if (ctrl->value < mt9v011_qctrl[i].minimum ||
- ctrl->value > mt9v011_qctrl[i].maximum)
- return -ERANGE;
- v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n",
- ctrl->id, ctrl->value);
- break;
- }
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- core->global_gain = ctrl->value;
- break;
- case V4L2_CID_EXPOSURE:
- core->exposure = ctrl->value;
- break;
- case V4L2_CID_RED_BALANCE:
- core->red_bal = ctrl->value;
- break;
- case V4L2_CID_BLUE_BALANCE:
- core->blue_bal = ctrl->value;
- break;
- case V4L2_CID_HFLIP:
- core->hflip = ctrl->value;
- set_read_mode(sd);
- return 0;
- case V4L2_CID_VFLIP:
- core->vflip = ctrl->value;
- set_read_mode(sd);
- return 0;
- default:
- return -EINVAL;
- }
-
- set_balance(sd);
-
- return 0;
-}
-
-static int mt9v011_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index > 0)
- return -EINVAL;
-
- *code = V4L2_MBUS_FMT_SGRBG8_1X8;
- return 0;
-}
-
-static int mt9v011_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
-{
- if (fmt->code != V4L2_MBUS_FMT_SGRBG8_1X8)
- return -EINVAL;
-
- v4l_bound_align_image(&fmt->width, 48, 639, 1,
- &fmt->height, 32, 480, 1, 0);
- fmt->field = V4L2_FIELD_NONE;
- fmt->colorspace = V4L2_COLORSPACE_SRGB;
-
- return 0;
-}
-
-static int mt9v011_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
-{
- struct v4l2_captureparm *cp = &parms->parm.capture;
-
- if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- memset(cp, 0, sizeof(struct v4l2_captureparm));
- cp->capability = V4L2_CAP_TIMEPERFRAME;
- calc_fps(sd,
- &cp->timeperframe.numerator,
- &cp->timeperframe.denominator);
-
- return 0;
-}
-
-static int mt9v011_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
-{
- struct v4l2_captureparm *cp = &parms->parm.capture;
- struct v4l2_fract *tpf = &cp->timeperframe;
- u16 speed;
-
- if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (cp->extendedmode != 0)
- return -EINVAL;
-
- speed = calc_speed(sd, tpf->numerator, tpf->denominator);
-
- mt9v011_write(sd, R0A_MT9V011_CLK_SPEED, speed);
- v4l2_dbg(1, debug, sd, "Setting speed to %d\n", speed);
-
- /* Recalculate and update fps info */
- calc_fps(sd, &tpf->numerator, &tpf->denominator);
-
- return 0;
-}
-
-static int mt9v011_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
-{
- struct mt9v011 *core = to_mt9v011(sd);
- int rc;
-
- rc = mt9v011_try_mbus_fmt(sd, fmt);
- if (rc < 0)
- return -EINVAL;
-
- core->width = fmt->width;
- core->height = fmt->height;
-
- set_res(sd);
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9v011_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- reg->val = mt9v011_read(sd, reg->reg & 0xff);
- reg->size = 2;
-
- return 0;
-}
-
-static int mt9v011_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- mt9v011_write(sd, reg->reg & 0xff, reg->val & 0xffff);
-
- return 0;
-}
-#endif
-
-static int mt9v011_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- u16 version;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_MT9V011,
- version);
-}
-
-static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
- .queryctrl = mt9v011_queryctrl,
- .g_ctrl = mt9v011_g_ctrl,
- .s_ctrl = mt9v011_s_ctrl,
- .reset = mt9v011_reset,
- .g_chip_ident = mt9v011_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = mt9v011_g_register,
- .s_register = mt9v011_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_video_ops mt9v011_video_ops = {
- .enum_mbus_fmt = mt9v011_enum_mbus_fmt,
- .try_mbus_fmt = mt9v011_try_mbus_fmt,
- .s_mbus_fmt = mt9v011_s_mbus_fmt,
- .g_parm = mt9v011_g_parm,
- .s_parm = mt9v011_s_parm,
-};
-
-static const struct v4l2_subdev_ops mt9v011_ops = {
- .core = &mt9v011_core_ops,
- .video = &mt9v011_video_ops,
-};
-
-
-/****************************************************************************
- I2C Client & Driver
- ****************************************************************************/
-
-static int mt9v011_probe(struct i2c_client *c,
- const struct i2c_device_id *id)
-{
- u16 version;
- struct mt9v011 *core;
- struct v4l2_subdev *sd;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(c->adapter,
- I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
- return -EIO;
-
- core = kzalloc(sizeof(struct mt9v011), GFP_KERNEL);
- if (!core)
- return -ENOMEM;
-
- sd = &core->sd;
- v4l2_i2c_subdev_init(sd, c, &mt9v011_ops);
-
- /* Check if the sensor is really a MT9V011 */
- version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION);
- if ((version != MT9V011_VERSION) &&
- (version != MT9V011_REV_B_VERSION)) {
- v4l2_info(sd, "*** unknown micron chip detected (0x%04x).\n",
- version);
- kfree(core);
- return -EINVAL;
- }
-
- core->global_gain = 0x0024;
- core->exposure = 0x01fc;
- core->width = 640;
- core->height = 480;
- core->xtal = 27000000; /* Hz */
-
- if (c->dev.platform_data) {
- struct mt9v011_platform_data *pdata = c->dev.platform_data;
-
- core->xtal = pdata->xtal;
- v4l2_dbg(1, debug, sd, "xtal set to %d.%03d MHz\n",
- core->xtal / 1000000, (core->xtal / 1000) % 1000);
- }
-
- v4l_info(c, "chip found @ 0x%02x (%s - chip version 0x%04x)\n",
- c->addr << 1, c->adapter->name, version);
-
- return 0;
-}
-
-static int mt9v011_remove(struct i2c_client *c)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(c);
-
- v4l2_dbg(1, debug, sd,
- "mt9v011.c: removing mt9v011 adapter on address 0x%x\n",
- c->addr << 1);
-
- v4l2_device_unregister_subdev(sd);
- kfree(to_mt9v011(sd));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id mt9v011_id[] = {
- { "mt9v011", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, mt9v011_id);
-
-static struct i2c_driver mt9v011_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "mt9v011",
- },
- .probe = mt9v011_probe,
- .remove = mt9v011_remove,
- .id_table = mt9v011_id,
-};
-
-module_i2c_driver(mt9v011_driver);
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
deleted file mode 100644
index 72479247522..00000000000
--- a/drivers/media/video/mt9v022.c
+++ /dev/null
@@ -1,879 +0,0 @@
-/*
- * Driver for MT9V022 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/log2.h>
-#include <linux/module.h>
-
-#include <media/soc_camera.h>
-#include <media/soc_mediabus.h>
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-
-/*
- * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
- * The platform has to define struct i2c_board_info objects and link to them
- * from struct soc_camera_link
- */
-
-static char *sensor_type;
-module_param(sensor_type, charp, S_IRUGO);
-MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
-
-/* mt9v022 selected register addresses */
-#define MT9V022_CHIP_VERSION 0x00
-#define MT9V022_COLUMN_START 0x01
-#define MT9V022_ROW_START 0x02
-#define MT9V022_WINDOW_HEIGHT 0x03
-#define MT9V022_WINDOW_WIDTH 0x04
-#define MT9V022_HORIZONTAL_BLANKING 0x05
-#define MT9V022_VERTICAL_BLANKING 0x06
-#define MT9V022_CHIP_CONTROL 0x07
-#define MT9V022_SHUTTER_WIDTH1 0x08
-#define MT9V022_SHUTTER_WIDTH2 0x09
-#define MT9V022_SHUTTER_WIDTH_CTRL 0x0a
-#define MT9V022_TOTAL_SHUTTER_WIDTH 0x0b
-#define MT9V022_RESET 0x0c
-#define MT9V022_READ_MODE 0x0d
-#define MT9V022_MONITOR_MODE 0x0e
-#define MT9V022_PIXEL_OPERATION_MODE 0x0f
-#define MT9V022_LED_OUT_CONTROL 0x1b
-#define MT9V022_ADC_MODE_CONTROL 0x1c
-#define MT9V022_ANALOG_GAIN 0x35
-#define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47
-#define MT9V022_PIXCLK_FV_LV 0x74
-#define MT9V022_DIGITAL_TEST_PATTERN 0x7f
-#define MT9V022_AEC_AGC_ENABLE 0xAF
-#define MT9V022_MAX_TOTAL_SHUTTER_WIDTH 0xBD
-
-/* Progressive scan, master, defaults */
-#define MT9V022_CHIP_CONTROL_DEFAULT 0x188
-
-#define MT9V022_MAX_WIDTH 752
-#define MT9V022_MAX_HEIGHT 480
-#define MT9V022_MIN_WIDTH 48
-#define MT9V022_MIN_HEIGHT 32
-#define MT9V022_COLUMN_SKIP 1
-#define MT9V022_ROW_SKIP 4
-
-/* MT9V022 has only one fixed colorspace per pixelcode */
-struct mt9v022_datafmt {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
-};
-
-/* Find a data format by a pixel code in an array */
-static const struct mt9v022_datafmt *mt9v022_find_datafmt(
- enum v4l2_mbus_pixelcode code, const struct mt9v022_datafmt *fmt,
- int n)
-{
- int i;
- for (i = 0; i < n; i++)
- if (fmt[i].code == code)
- return fmt + i;
-
- return NULL;
-}
-
-static const struct mt9v022_datafmt mt9v022_colour_fmts[] = {
- /*
- * Order important: first natively supported,
- * second supported with a GPIO extender
- */
- {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
-};
-
-static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
- /* Order important - see above */
- {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
- {V4L2_MBUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG},
-};
-
-struct mt9v022 {
- struct v4l2_subdev subdev;
- struct v4l2_ctrl_handler hdl;
- struct {
- /* exposure/auto-exposure cluster */
- struct v4l2_ctrl *autoexposure;
- struct v4l2_ctrl *exposure;
- };
- struct {
- /* gain/auto-gain cluster */
- struct v4l2_ctrl *autogain;
- struct v4l2_ctrl *gain;
- };
- struct v4l2_rect rect; /* Sensor window */
- const struct mt9v022_datafmt *fmt;
- const struct mt9v022_datafmt *fmts;
- int num_fmts;
- int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
- u16 chip_control;
- unsigned short y_skip_top; /* Lines to skip at the top */
-};
-
-static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client), struct mt9v022, subdev);
-}
-
-static int reg_read(struct i2c_client *client, const u8 reg)
-{
- return i2c_smbus_read_word_swapped(client, reg);
-}
-
-static int reg_write(struct i2c_client *client, const u8 reg,
- const u16 data)
-{
- return i2c_smbus_write_word_swapped(client, reg, data);
-}
-
-static int reg_set(struct i2c_client *client, const u8 reg,
- const u16 data)
-{
- int ret;
-
- ret = reg_read(client, reg);
- if (ret < 0)
- return ret;
- return reg_write(client, reg, ret | data);
-}
-
-static int reg_clear(struct i2c_client *client, const u8 reg,
- const u16 data)
-{
- int ret;
-
- ret = reg_read(client, reg);
- if (ret < 0)
- return ret;
- return reg_write(client, reg, ret & ~data);
-}
-
-static int mt9v022_init(struct i2c_client *client)
-{
- struct mt9v022 *mt9v022 = to_mt9v022(client);
- int ret;
-
- /*
- * Almost the default mode: master, parallel, simultaneous, and an
- * undocumented bit 0x200, which is present in table 7, but not in 8,
- * plus snapshot mode to disable scan for now
- */
- mt9v022->chip_control |= 0x10;
- ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
- if (!ret)
- ret = reg_write(client, MT9V022_READ_MODE, 0x300);
-
- /* All defaults */
- if (!ret)
- /* AEC, AGC on */
- ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
- if (!ret)
- ret = reg_write(client, MT9V022_ANALOG_GAIN, 16);
- if (!ret)
- ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480);
- if (!ret)
- ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
- if (!ret)
- /* default - auto */
- ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
- if (!ret)
- ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
- if (!ret)
- return v4l2_ctrl_handler_setup(&mt9v022->hdl);
-
- return ret;
-}
-
-static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9v022 *mt9v022 = to_mt9v022(client);
-
- if (enable)
- /* Switch to master "normal" mode */
- mt9v022->chip_control &= ~0x10;
- else
- /* Switch to snapshot mode */
- mt9v022->chip_control |= 0x10;
-
- if (reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control) < 0)
- return -EIO;
- return 0;
-}
-
-static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9v022 *mt9v022 = to_mt9v022(client);
- struct v4l2_rect rect = a->c;
- int ret;
-
- /* Bayer format - even size lengths */
- if (mt9v022->fmts == mt9v022_colour_fmts) {
- rect.width = ALIGN(rect.width, 2);
- rect.height = ALIGN(rect.height, 2);
- /* Let the user play with the starting pixel */
- }
-
- soc_camera_limit_side(&rect.left, &rect.width,
- MT9V022_COLUMN_SKIP, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH);
-
- soc_camera_limit_side(&rect.top, &rect.height,
- MT9V022_ROW_SKIP, MT9V022_MIN_HEIGHT, MT9V022_MAX_HEIGHT);
-
- /* Like in example app. Contradicts the datasheet though */
- ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
- if (ret >= 0) {
- if (ret & 1) /* Autoexposure */
- ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
- rect.height + mt9v022->y_skip_top + 43);
- else
- ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
- rect.height + mt9v022->y_skip_top + 43);
- }
- /* Setup frame format: defaults apart from width and height */
- if (!ret)
- ret = reg_write(client, MT9V022_COLUMN_START, rect.left);
- if (!ret)
- ret = reg_write(client, MT9V022_ROW_START, rect.top);
- if (!ret)
- /*
- * Default 94, Phytec driver says:
- * "width + horizontal blank >= 660"
- */
- ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
- rect.width > 660 - 43 ? 43 :
- 660 - rect.width);
- if (!ret)
- ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45);
- if (!ret)
- ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
- if (!ret)
- ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
- rect.height + mt9v022->y_skip_top);
-
- if (ret < 0)
- return ret;
-
- dev_dbg(&client->dev, "Frame %dx%d pixel\n", rect.width, rect.height);
-
- mt9v022->rect = rect;
-
- return 0;
-}
-
-static int mt9v022_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9v022 *mt9v022 = to_mt9v022(client);
-
- a->c = mt9v022->rect;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = MT9V022_COLUMN_SKIP;
- a->bounds.top = MT9V022_ROW_SKIP;
- a->bounds.width = MT9V022_MAX_WIDTH;
- a->bounds.height = MT9V022_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int mt9v022_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9v022 *mt9v022 = to_mt9v022(client);
-
- mf->width = mt9v022->rect.width;
- mf->height = mt9v022->rect.height;
- mf->code = mt9v022->fmt->code;
- mf->colorspace = mt9v022->fmt->colorspace;
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int mt9v022_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9v022 *mt9v022 = to_mt9v022(client);
- struct v4l2_crop a = {
- .c = {
- .left = mt9v022->rect.left,
- .top = mt9v022->rect.top,
- .width = mf->width,
- .height = mf->height,
- },
- };
- int ret;
-
- /*
- * The caller provides a supported format, as verified per call to
- * .try_mbus_fmt(), datawidth is from our supported format list
- */
- switch (mf->code) {
- case V4L2_MBUS_FMT_Y8_1X8:
- case V4L2_MBUS_FMT_Y10_1X10:
- if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
- return -EINVAL;
- break;
- case V4L2_MBUS_FMT_SBGGR8_1X8:
- case V4L2_MBUS_FMT_SBGGR10_1X10:
- if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
-
- /* No support for scaling on this camera, just crop. */
- ret = mt9v022_s_crop(sd, &a);
- if (!ret) {
- mf->width = mt9v022->rect.width;
- mf->height = mt9v022->rect.height;
- mt9v022->fmt = mt9v022_find_datafmt(mf->code,
- mt9v022->fmts, mt9v022->num_fmts);
- mf->colorspace = mt9v022->fmt->colorspace;
- }
-
- return ret;
-}
-
-static int mt9v022_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9v022 *mt9v022 = to_mt9v022(client);
- const struct mt9v022_datafmt *fmt;
- int align = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 ||
- mf->code == V4L2_MBUS_FMT_SBGGR10_1X10;
-
- v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH,
- MT9V022_MAX_WIDTH, align,
- &mf->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top,
- MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0);
-
- fmt = mt9v022_find_datafmt(mf->code, mt9v022->fmts,
- mt9v022->num_fmts);
- if (!fmt) {
- fmt = mt9v022->fmt;
- mf->code = fmt->code;
- }
-
- mf->colorspace = fmt->colorspace;
-
- return 0;
-}
-
-static int mt9v022_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9v022 *mt9v022 = to_mt9v022(client);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = mt9v022->model;
- id->revision = 0;
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9v022_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
- return -EINVAL;
-
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
- reg->size = 2;
- reg->val = reg_read(client, reg->reg);
-
- if (reg->val > 0xffff)
- return -EIO;
-
- return 0;
-}
-
-static int mt9v022_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
- return -EINVAL;
-
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
- if (reg_write(client, reg->reg, reg->val) < 0)
- return -EIO;
-
- return 0;
-}
-#endif
-
-static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct mt9v022 *mt9v022 = container_of(ctrl->handler,
- struct mt9v022, hdl);
- struct v4l2_subdev *sd = &mt9v022->subdev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct v4l2_ctrl *gain = mt9v022->gain;
- struct v4l2_ctrl *exp = mt9v022->exposure;
- unsigned long range;
- int data;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTOGAIN:
- data = reg_read(client, MT9V022_ANALOG_GAIN);
- if (data < 0)
- return -EIO;
-
- range = gain->maximum - gain->minimum;
- gain->val = ((data - 16) * range + 24) / 48 + gain->minimum;
- return 0;
- case V4L2_CID_EXPOSURE_AUTO:
- data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH);
- if (data < 0)
- return -EIO;
-
- range = exp->maximum - exp->minimum;
- exp->val = ((data - 1) * range + 239) / 479 + exp->minimum;
- return 0;
- }
- return -EINVAL;
-}
-
-static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct mt9v022 *mt9v022 = container_of(ctrl->handler,
- struct mt9v022, hdl);
- struct v4l2_subdev *sd = &mt9v022->subdev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int data;
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- if (ctrl->val)
- data = reg_set(client, MT9V022_READ_MODE, 0x10);
- else
- data = reg_clear(client, MT9V022_READ_MODE, 0x10);
- if (data < 0)
- return -EIO;
- return 0;
- case V4L2_CID_HFLIP:
- if (ctrl->val)
- data = reg_set(client, MT9V022_READ_MODE, 0x20);
- else
- data = reg_clear(client, MT9V022_READ_MODE, 0x20);
- if (data < 0)
- return -EIO;
- return 0;
- case V4L2_CID_AUTOGAIN:
- if (ctrl->val) {
- if (reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
- return -EIO;
- } else {
- struct v4l2_ctrl *gain = mt9v022->gain;
- /* mt9v022 has minimum == default */
- unsigned long range = gain->maximum - gain->minimum;
- /* Valid values 16 to 64, 32 to 64 must be even. */
- unsigned long gain_val = ((gain->val - gain->minimum) *
- 48 + range / 2) / range + 16;
-
- if (gain_val >= 32)
- gain_val &= ~1;
-
- /*
- * The user wants to set gain manually, hope, she
- * knows, what she's doing... Switch AGC off.
- */
- if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
- return -EIO;
-
- dev_dbg(&client->dev, "Setting gain from %d to %lu\n",
- reg_read(client, MT9V022_ANALOG_GAIN), gain_val);
- if (reg_write(client, MT9V022_ANALOG_GAIN, gain_val) < 0)
- return -EIO;
- }
- return 0;
- case V4L2_CID_EXPOSURE_AUTO:
- if (ctrl->val == V4L2_EXPOSURE_AUTO) {
- data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
- } else {
- struct v4l2_ctrl *exp = mt9v022->exposure;
- unsigned long range = exp->maximum - exp->minimum;
- unsigned long shutter = ((exp->val - exp->minimum) *
- 479 + range / 2) / range + 1;
-
- /*
- * The user wants to set shutter width manually, hope,
- * she knows, what she's doing... Switch AEC off.
- */
- data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
- if (data < 0)
- return -EIO;
- dev_dbg(&client->dev, "Shutter width from %d to %lu\n",
- reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
- shutter);
- if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
- shutter) < 0)
- return -EIO;
- }
- return 0;
- }
- return -EINVAL;
-}
-
-/*
- * Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one
- */
-static int mt9v022_video_probe(struct i2c_client *client)
-{
- struct mt9v022 *mt9v022 = to_mt9v022(client);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- s32 data;
- int ret;
- unsigned long flags;
-
- /* Read out the chip version register */
- data = reg_read(client, MT9V022_CHIP_VERSION);
-
- /* must be 0x1311 or 0x1313 */
- if (data != 0x1311 && data != 0x1313) {
- ret = -ENODEV;
- dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n",
- data);
- goto ei2c;
- }
-
- /* Soft reset */
- ret = reg_write(client, MT9V022_RESET, 1);
- if (ret < 0)
- goto ei2c;
- /* 15 clock cycles */
- udelay(200);
- if (reg_read(client, MT9V022_RESET)) {
- dev_err(&client->dev, "Resetting MT9V022 failed!\n");
- if (ret > 0)
- ret = -EIO;
- goto ei2c;
- }
-
- /* Set monochrome or colour sensor type */
- if (sensor_type && (!strcmp("colour", sensor_type) ||
- !strcmp("color", sensor_type))) {
- ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
- mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
- mt9v022->fmts = mt9v022_colour_fmts;
- } else {
- ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
- mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
- mt9v022->fmts = mt9v022_monochrome_fmts;
- }
-
- if (ret < 0)
- goto ei2c;
-
- mt9v022->num_fmts = 0;
-
- /*
- * This is a 10bit sensor, so by default we only allow 10bit.
- * The platform may support different bus widths due to
- * different routing of the data lines.
- */
- if (icl->query_bus_param)
- flags = icl->query_bus_param(icl);
- else
- flags = SOCAM_DATAWIDTH_10;
-
- if (flags & SOCAM_DATAWIDTH_10)
- mt9v022->num_fmts++;
- else
- mt9v022->fmts++;
-
- if (flags & SOCAM_DATAWIDTH_8)
- mt9v022->num_fmts++;
-
- mt9v022->fmt = &mt9v022->fmts[0];
-
- dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
- data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
- "monochrome" : "colour");
-
- ret = mt9v022_init(client);
- if (ret < 0)
- dev_err(&client->dev, "Failed to initialise the camera\n");
-
-ei2c:
- return ret;
-}
-
-static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9v022 *mt9v022 = to_mt9v022(client);
-
- *lines = mt9v022->y_skip_top;
-
- return 0;
-}
-
-static const struct v4l2_ctrl_ops mt9v022_ctrl_ops = {
- .g_volatile_ctrl = mt9v022_g_volatile_ctrl,
- .s_ctrl = mt9v022_s_ctrl,
-};
-
-static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
- .g_chip_ident = mt9v022_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = mt9v022_g_register,
- .s_register = mt9v022_s_register,
-#endif
-};
-
-static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9v022 *mt9v022 = to_mt9v022(client);
-
- if (index >= mt9v022->num_fmts)
- return -EINVAL;
-
- *code = mt9v022->fmts[index].code;
- return 0;
-}
-
-static int mt9v022_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE |
- V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
- V4L2_MBUS_DATA_ACTIVE_HIGH;
- cfg->type = V4L2_MBUS_PARALLEL;
- cfg->flags = soc_camera_apply_board_flags(icl, cfg);
-
- return 0;
-}
-
-static int mt9v022_s_mbus_config(struct v4l2_subdev *sd,
- const struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- struct mt9v022 *mt9v022 = to_mt9v022(client);
- unsigned long flags = soc_camera_apply_board_flags(icl, cfg);
- unsigned int bps = soc_mbus_get_fmtdesc(mt9v022->fmt->code)->bits_per_sample;
- int ret;
- u16 pixclk = 0;
-
- if (icl->set_bus_param) {
- ret = icl->set_bus_param(icl, 1 << (bps - 1));
- if (ret)
- return ret;
- } else if (bps != 10) {
- /*
- * Without board specific bus width settings we only support the
- * sensors native bus width
- */
- return -EINVAL;
- }
-
- if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
- pixclk |= 0x10;
-
- if (!(flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH))
- pixclk |= 0x1;
-
- if (!(flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH))
- pixclk |= 0x2;
-
- ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
- if (ret < 0)
- return ret;
-
- if (!(flags & V4L2_MBUS_MASTER))
- mt9v022->chip_control &= ~0x8;
-
- ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
- if (ret < 0)
- return ret;
-
- dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
- pixclk, mt9v022->chip_control);
-
- return 0;
-}
-
-static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
- .s_stream = mt9v022_s_stream,
- .s_mbus_fmt = mt9v022_s_fmt,
- .g_mbus_fmt = mt9v022_g_fmt,
- .try_mbus_fmt = mt9v022_try_fmt,
- .s_crop = mt9v022_s_crop,
- .g_crop = mt9v022_g_crop,
- .cropcap = mt9v022_cropcap,
- .enum_mbus_fmt = mt9v022_enum_fmt,
- .g_mbus_config = mt9v022_g_mbus_config,
- .s_mbus_config = mt9v022_s_mbus_config,
-};
-
-static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
- .g_skip_top_lines = mt9v022_g_skip_top_lines,
-};
-
-static struct v4l2_subdev_ops mt9v022_subdev_ops = {
- .core = &mt9v022_subdev_core_ops,
- .video = &mt9v022_subdev_video_ops,
- .sensor = &mt9v022_subdev_sensor_ops,
-};
-
-static int mt9v022_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct mt9v022 *mt9v022;
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- int ret;
-
- if (!icl) {
- dev_err(&client->dev, "MT9V022 driver needs platform data\n");
- return -EINVAL;
- }
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
- dev_warn(&adapter->dev,
- "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
- return -EIO;
- }
-
- mt9v022 = kzalloc(sizeof(struct mt9v022), GFP_KERNEL);
- if (!mt9v022)
- return -ENOMEM;
-
- v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
- v4l2_ctrl_handler_init(&mt9v022->hdl, 6);
- v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- mt9v022->autogain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- mt9v022->gain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
- V4L2_CID_GAIN, 0, 127, 1, 64);
-
- /*
- * Simulated autoexposure. If enabled, we calculate shutter width
- * ourselves in the driver based on vertical blanking and frame width
- */
- mt9v022->autoexposure = v4l2_ctrl_new_std_menu(&mt9v022->hdl,
- &mt9v022_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
- V4L2_EXPOSURE_AUTO);
- mt9v022->exposure = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
- V4L2_CID_EXPOSURE, 1, 255, 1, 255);
-
- mt9v022->subdev.ctrl_handler = &mt9v022->hdl;
- if (mt9v022->hdl.error) {
- int err = mt9v022->hdl.error;
-
- kfree(mt9v022);
- return err;
- }
- v4l2_ctrl_auto_cluster(2, &mt9v022->autoexposure,
- V4L2_EXPOSURE_MANUAL, true);
- v4l2_ctrl_auto_cluster(2, &mt9v022->autogain, 0, true);
-
- mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
-
- /*
- * MT9V022 _really_ corrupts the first read out line.
- * TODO: verify on i.MX31
- */
- mt9v022->y_skip_top = 1;
- mt9v022->rect.left = MT9V022_COLUMN_SKIP;
- mt9v022->rect.top = MT9V022_ROW_SKIP;
- mt9v022->rect.width = MT9V022_MAX_WIDTH;
- mt9v022->rect.height = MT9V022_MAX_HEIGHT;
-
- ret = mt9v022_video_probe(client);
- if (ret) {
- v4l2_ctrl_handler_free(&mt9v022->hdl);
- kfree(mt9v022);
- }
-
- return ret;
-}
-
-static int mt9v022_remove(struct i2c_client *client)
-{
- struct mt9v022 *mt9v022 = to_mt9v022(client);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- v4l2_device_unregister_subdev(&mt9v022->subdev);
- if (icl->free_bus)
- icl->free_bus(icl);
- v4l2_ctrl_handler_free(&mt9v022->hdl);
- kfree(mt9v022);
-
- return 0;
-}
-static const struct i2c_device_id mt9v022_id[] = {
- { "mt9v022", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, mt9v022_id);
-
-static struct i2c_driver mt9v022_i2c_driver = {
- .driver = {
- .name = "mt9v022",
- },
- .probe = mt9v022_probe,
- .remove = mt9v022_remove,
- .id_table = mt9v022_id,
-};
-
-module_i2c_driver(mt9v022_i2c_driver);
-
-MODULE_DESCRIPTION("Micron MT9V022 Camera driver");
-MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/mt9v032.c b/drivers/media/video/mt9v032.c
deleted file mode 100644
index 4ba4884c016..00000000000
--- a/drivers/media/video/mt9v032.c
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
- * Driver for MT9V032 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2010, Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- *
- * Based on the MT9M001 driver,
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/module.h>
-
-#include <media/mt9v032.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-
-#define MT9V032_PIXEL_ARRAY_HEIGHT 492
-#define MT9V032_PIXEL_ARRAY_WIDTH 782
-
-#define MT9V032_CHIP_VERSION 0x00
-#define MT9V032_CHIP_ID_REV1 0x1311
-#define MT9V032_CHIP_ID_REV3 0x1313
-#define MT9V032_COLUMN_START 0x01
-#define MT9V032_COLUMN_START_MIN 1
-#define MT9V032_COLUMN_START_DEF 1
-#define MT9V032_COLUMN_START_MAX 752
-#define MT9V032_ROW_START 0x02
-#define MT9V032_ROW_START_MIN 4
-#define MT9V032_ROW_START_DEF 5
-#define MT9V032_ROW_START_MAX 482
-#define MT9V032_WINDOW_HEIGHT 0x03
-#define MT9V032_WINDOW_HEIGHT_MIN 1
-#define MT9V032_WINDOW_HEIGHT_DEF 480
-#define MT9V032_WINDOW_HEIGHT_MAX 480
-#define MT9V032_WINDOW_WIDTH 0x04
-#define MT9V032_WINDOW_WIDTH_MIN 1
-#define MT9V032_WINDOW_WIDTH_DEF 752
-#define MT9V032_WINDOW_WIDTH_MAX 752
-#define MT9V032_HORIZONTAL_BLANKING 0x05
-#define MT9V032_HORIZONTAL_BLANKING_MIN 43
-#define MT9V032_HORIZONTAL_BLANKING_MAX 1023
-#define MT9V032_VERTICAL_BLANKING 0x06
-#define MT9V032_VERTICAL_BLANKING_MIN 4
-#define MT9V032_VERTICAL_BLANKING_MAX 3000
-#define MT9V032_CHIP_CONTROL 0x07
-#define MT9V032_CHIP_CONTROL_MASTER_MODE (1 << 3)
-#define MT9V032_CHIP_CONTROL_DOUT_ENABLE (1 << 7)
-#define MT9V032_CHIP_CONTROL_SEQUENTIAL (1 << 8)
-#define MT9V032_SHUTTER_WIDTH1 0x08
-#define MT9V032_SHUTTER_WIDTH2 0x09
-#define MT9V032_SHUTTER_WIDTH_CONTROL 0x0a
-#define MT9V032_TOTAL_SHUTTER_WIDTH 0x0b
-#define MT9V032_TOTAL_SHUTTER_WIDTH_MIN 1
-#define MT9V032_TOTAL_SHUTTER_WIDTH_DEF 480
-#define MT9V032_TOTAL_SHUTTER_WIDTH_MAX 32767
-#define MT9V032_RESET 0x0c
-#define MT9V032_READ_MODE 0x0d
-#define MT9V032_READ_MODE_ROW_BIN_MASK (3 << 0)
-#define MT9V032_READ_MODE_ROW_BIN_SHIFT 0
-#define MT9V032_READ_MODE_COLUMN_BIN_MASK (3 << 2)
-#define MT9V032_READ_MODE_COLUMN_BIN_SHIFT 2
-#define MT9V032_READ_MODE_ROW_FLIP (1 << 4)
-#define MT9V032_READ_MODE_COLUMN_FLIP (1 << 5)
-#define MT9V032_READ_MODE_DARK_COLUMNS (1 << 6)
-#define MT9V032_READ_MODE_DARK_ROWS (1 << 7)
-#define MT9V032_PIXEL_OPERATION_MODE 0x0f
-#define MT9V032_PIXEL_OPERATION_MODE_COLOR (1 << 2)
-#define MT9V032_PIXEL_OPERATION_MODE_HDR (1 << 6)
-#define MT9V032_ANALOG_GAIN 0x35
-#define MT9V032_ANALOG_GAIN_MIN 16
-#define MT9V032_ANALOG_GAIN_DEF 16
-#define MT9V032_ANALOG_GAIN_MAX 64
-#define MT9V032_MAX_ANALOG_GAIN 0x36
-#define MT9V032_MAX_ANALOG_GAIN_MAX 127
-#define MT9V032_FRAME_DARK_AVERAGE 0x42
-#define MT9V032_DARK_AVG_THRESH 0x46
-#define MT9V032_DARK_AVG_LOW_THRESH_MASK (255 << 0)
-#define MT9V032_DARK_AVG_LOW_THRESH_SHIFT 0
-#define MT9V032_DARK_AVG_HIGH_THRESH_MASK (255 << 8)
-#define MT9V032_DARK_AVG_HIGH_THRESH_SHIFT 8
-#define MT9V032_ROW_NOISE_CORR_CONTROL 0x70
-#define MT9V032_ROW_NOISE_CORR_ENABLE (1 << 5)
-#define MT9V032_ROW_NOISE_CORR_USE_BLK_AVG (1 << 7)
-#define MT9V032_PIXEL_CLOCK 0x74
-#define MT9V032_PIXEL_CLOCK_INV_LINE (1 << 0)
-#define MT9V032_PIXEL_CLOCK_INV_FRAME (1 << 1)
-#define MT9V032_PIXEL_CLOCK_XOR_LINE (1 << 2)
-#define MT9V032_PIXEL_CLOCK_CONT_LINE (1 << 3)
-#define MT9V032_PIXEL_CLOCK_INV_PXL_CLK (1 << 4)
-#define MT9V032_TEST_PATTERN 0x7f
-#define MT9V032_TEST_PATTERN_DATA_MASK (1023 << 0)
-#define MT9V032_TEST_PATTERN_DATA_SHIFT 0
-#define MT9V032_TEST_PATTERN_USE_DATA (1 << 10)
-#define MT9V032_TEST_PATTERN_GRAY_MASK (3 << 11)
-#define MT9V032_TEST_PATTERN_GRAY_NONE (0 << 11)
-#define MT9V032_TEST_PATTERN_GRAY_VERTICAL (1 << 11)
-#define MT9V032_TEST_PATTERN_GRAY_HORIZONTAL (2 << 11)
-#define MT9V032_TEST_PATTERN_GRAY_DIAGONAL (3 << 11)
-#define MT9V032_TEST_PATTERN_ENABLE (1 << 13)
-#define MT9V032_TEST_PATTERN_FLIP (1 << 14)
-#define MT9V032_AEC_AGC_ENABLE 0xaf
-#define MT9V032_AEC_ENABLE (1 << 0)
-#define MT9V032_AGC_ENABLE (1 << 1)
-#define MT9V032_THERMAL_INFO 0xc1
-
-struct mt9v032 {
- struct v4l2_subdev subdev;
- struct media_pad pad;
-
- struct v4l2_mbus_framefmt format;
- struct v4l2_rect crop;
-
- struct v4l2_ctrl_handler ctrls;
-
- struct mutex power_lock;
- int power_count;
-
- struct mt9v032_platform_data *pdata;
- u16 chip_control;
- u16 aec_agc;
-};
-
-static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct mt9v032, subdev);
-}
-
-static int mt9v032_read(struct i2c_client *client, const u8 reg)
-{
- s32 data = i2c_smbus_read_word_swapped(client, reg);
- dev_dbg(&client->dev, "%s: read 0x%04x from 0x%02x\n", __func__,
- data, reg);
- return data;
-}
-
-static int mt9v032_write(struct i2c_client *client, const u8 reg,
- const u16 data)
-{
- dev_dbg(&client->dev, "%s: writing 0x%04x to 0x%02x\n", __func__,
- data, reg);
- return i2c_smbus_write_word_swapped(client, reg, data);
-}
-
-static int mt9v032_set_chip_control(struct mt9v032 *mt9v032, u16 clear, u16 set)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
- u16 value = (mt9v032->chip_control & ~clear) | set;
- int ret;
-
- ret = mt9v032_write(client, MT9V032_CHIP_CONTROL, value);
- if (ret < 0)
- return ret;
-
- mt9v032->chip_control = value;
- return 0;
-}
-
-static int
-mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
- u16 value = mt9v032->aec_agc;
- int ret;
-
- if (enable)
- value |= which;
- else
- value &= ~which;
-
- ret = mt9v032_write(client, MT9V032_AEC_AGC_ENABLE, value);
- if (ret < 0)
- return ret;
-
- mt9v032->aec_agc = value;
- return 0;
-}
-
-static int mt9v032_power_on(struct mt9v032 *mt9v032)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
- int ret;
-
- if (mt9v032->pdata->set_clock) {
- mt9v032->pdata->set_clock(&mt9v032->subdev, 25000000);
- udelay(1);
- }
-
- /* Reset the chip and stop data read out */
- ret = mt9v032_write(client, MT9V032_RESET, 1);
- if (ret < 0)
- return ret;
-
- ret = mt9v032_write(client, MT9V032_RESET, 0);
- if (ret < 0)
- return ret;
-
- return mt9v032_write(client, MT9V032_CHIP_CONTROL, 0);
-}
-
-static void mt9v032_power_off(struct mt9v032 *mt9v032)
-{
- if (mt9v032->pdata->set_clock)
- mt9v032->pdata->set_clock(&mt9v032->subdev, 0);
-}
-
-static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
- int ret;
-
- if (!on) {
- mt9v032_power_off(mt9v032);
- return 0;
- }
-
- ret = mt9v032_power_on(mt9v032);
- if (ret < 0)
- return ret;
-
- /* Configure the pixel clock polarity */
- if (mt9v032->pdata && mt9v032->pdata->clk_pol) {
- ret = mt9v032_write(client, MT9V032_PIXEL_CLOCK,
- MT9V032_PIXEL_CLOCK_INV_PXL_CLK);
- if (ret < 0)
- return ret;
- }
-
- /* Disable the noise correction algorithm and restore the controls. */
- ret = mt9v032_write(client, MT9V032_ROW_NOISE_CORR_CONTROL, 0);
- if (ret < 0)
- return ret;
-
- return v4l2_ctrl_handler_setup(&mt9v032->ctrls);
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev video operations
- */
-
-static struct v4l2_mbus_framefmt *
-__mt9v032_get_pad_format(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh,
- unsigned int pad, enum v4l2_subdev_format_whence which)
-{
- switch (which) {
- case V4L2_SUBDEV_FORMAT_TRY:
- return v4l2_subdev_get_try_format(fh, pad);
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- return &mt9v032->format;
- default:
- return NULL;
- }
-}
-
-static struct v4l2_rect *
-__mt9v032_get_pad_crop(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh,
- unsigned int pad, enum v4l2_subdev_format_whence which)
-{
- switch (which) {
- case V4L2_SUBDEV_FORMAT_TRY:
- return v4l2_subdev_get_try_crop(fh, pad);
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- return &mt9v032->crop;
- default:
- return NULL;
- }
-}
-
-static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable)
-{
- const u16 mode = MT9V032_CHIP_CONTROL_MASTER_MODE
- | MT9V032_CHIP_CONTROL_DOUT_ENABLE
- | MT9V032_CHIP_CONTROL_SEQUENTIAL;
- struct i2c_client *client = v4l2_get_subdevdata(subdev);
- struct mt9v032 *mt9v032 = to_mt9v032(subdev);
- struct v4l2_mbus_framefmt *format = &mt9v032->format;
- struct v4l2_rect *crop = &mt9v032->crop;
- unsigned int hratio;
- unsigned int vratio;
- int ret;
-
- if (!enable)
- return mt9v032_set_chip_control(mt9v032, mode, 0);
-
- /* Configure the window size and row/column bin */
- hratio = DIV_ROUND_CLOSEST(crop->width, format->width);
- vratio = DIV_ROUND_CLOSEST(crop->height, format->height);
-
- ret = mt9v032_write(client, MT9V032_READ_MODE,
- (hratio - 1) << MT9V032_READ_MODE_ROW_BIN_SHIFT |
- (vratio - 1) << MT9V032_READ_MODE_COLUMN_BIN_SHIFT);
- if (ret < 0)
- return ret;
-
- ret = mt9v032_write(client, MT9V032_COLUMN_START, crop->left);
- if (ret < 0)
- return ret;
-
- ret = mt9v032_write(client, MT9V032_ROW_START, crop->top);
- if (ret < 0)
- return ret;
-
- ret = mt9v032_write(client, MT9V032_WINDOW_WIDTH, crop->width);
- if (ret < 0)
- return ret;
-
- ret = mt9v032_write(client, MT9V032_WINDOW_HEIGHT, crop->height);
- if (ret < 0)
- return ret;
-
- ret = mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING,
- max(43, 660 - crop->width));
- if (ret < 0)
- return ret;
-
- /* Switch to master "normal" mode */
- return mt9v032_set_chip_control(mt9v032, 0, mode);
-}
-
-static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- if (code->index > 0)
- return -EINVAL;
-
- code->code = V4L2_MBUS_FMT_SGRBG10_1X10;
- return 0;
-}
-
-static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_frame_size_enum *fse)
-{
- if (fse->index >= 8 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10)
- return -EINVAL;
-
- fse->min_width = MT9V032_WINDOW_WIDTH_DEF / fse->index;
- fse->max_width = fse->min_width;
- fse->min_height = MT9V032_WINDOW_HEIGHT_DEF / fse->index;
- fse->max_height = fse->min_height;
-
- return 0;
-}
-
-static int mt9v032_get_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *format)
-{
- struct mt9v032 *mt9v032 = to_mt9v032(subdev);
-
- format->format = *__mt9v032_get_pad_format(mt9v032, fh, format->pad,
- format->which);
- return 0;
-}
-
-static int mt9v032_set_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *format)
-{
- struct mt9v032 *mt9v032 = to_mt9v032(subdev);
- struct v4l2_mbus_framefmt *__format;
- struct v4l2_rect *__crop;
- unsigned int width;
- unsigned int height;
- unsigned int hratio;
- unsigned int vratio;
-
- __crop = __mt9v032_get_pad_crop(mt9v032, fh, format->pad,
- format->which);
-
- /* Clamp the width and height to avoid dividing by zero. */
- width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
- max(__crop->width / 8, MT9V032_WINDOW_WIDTH_MIN),
- __crop->width);
- height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
- max(__crop->height / 8, MT9V032_WINDOW_HEIGHT_MIN),
- __crop->height);
-
- hratio = DIV_ROUND_CLOSEST(__crop->width, width);
- vratio = DIV_ROUND_CLOSEST(__crop->height, height);
-
- __format = __mt9v032_get_pad_format(mt9v032, fh, format->pad,
- format->which);
- __format->width = __crop->width / hratio;
- __format->height = __crop->height / vratio;
-
- format->format = *__format;
-
- return 0;
-}
-
-static int mt9v032_get_crop(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_crop *crop)
-{
- struct mt9v032 *mt9v032 = to_mt9v032(subdev);
-
- crop->rect = *__mt9v032_get_pad_crop(mt9v032, fh, crop->pad,
- crop->which);
- return 0;
-}
-
-static int mt9v032_set_crop(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_crop *crop)
-{
- struct mt9v032 *mt9v032 = to_mt9v032(subdev);
- struct v4l2_mbus_framefmt *__format;
- struct v4l2_rect *__crop;
- struct v4l2_rect rect;
-
- /* Clamp the crop rectangle boundaries and align them to a non multiple
- * of 2 pixels to ensure a GRBG Bayer pattern.
- */
- rect.left = clamp(ALIGN(crop->rect.left + 1, 2) - 1,
- MT9V032_COLUMN_START_MIN,
- MT9V032_COLUMN_START_MAX);
- rect.top = clamp(ALIGN(crop->rect.top + 1, 2) - 1,
- MT9V032_ROW_START_MIN,
- MT9V032_ROW_START_MAX);
- rect.width = clamp(ALIGN(crop->rect.width, 2),
- MT9V032_WINDOW_WIDTH_MIN,
- MT9V032_WINDOW_WIDTH_MAX);
- rect.height = clamp(ALIGN(crop->rect.height, 2),
- MT9V032_WINDOW_HEIGHT_MIN,
- MT9V032_WINDOW_HEIGHT_MAX);
-
- rect.width = min(rect.width, MT9V032_PIXEL_ARRAY_WIDTH - rect.left);
- rect.height = min(rect.height, MT9V032_PIXEL_ARRAY_HEIGHT - rect.top);
-
- __crop = __mt9v032_get_pad_crop(mt9v032, fh, crop->pad, crop->which);
-
- if (rect.width != __crop->width || rect.height != __crop->height) {
- /* Reset the output image size if the crop rectangle size has
- * been modified.
- */
- __format = __mt9v032_get_pad_format(mt9v032, fh, crop->pad,
- crop->which);
- __format->width = rect.width;
- __format->height = rect.height;
- }
-
- *__crop = rect;
- crop->rect = rect;
-
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev control operations
- */
-
-#define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001)
-
-static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct mt9v032 *mt9v032 =
- container_of(ctrl->handler, struct mt9v032, ctrls);
- struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
- u16 data;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTOGAIN:
- return mt9v032_update_aec_agc(mt9v032, MT9V032_AGC_ENABLE,
- ctrl->val);
-
- case V4L2_CID_GAIN:
- return mt9v032_write(client, MT9V032_ANALOG_GAIN, ctrl->val);
-
- case V4L2_CID_EXPOSURE_AUTO:
- return mt9v032_update_aec_agc(mt9v032, MT9V032_AEC_ENABLE,
- !ctrl->val);
-
- case V4L2_CID_EXPOSURE:
- return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH,
- ctrl->val);
-
- case V4L2_CID_TEST_PATTERN:
- switch (ctrl->val) {
- case 0:
- data = 0;
- break;
- case 1:
- data = MT9V032_TEST_PATTERN_GRAY_VERTICAL
- | MT9V032_TEST_PATTERN_ENABLE;
- break;
- case 2:
- data = MT9V032_TEST_PATTERN_GRAY_HORIZONTAL
- | MT9V032_TEST_PATTERN_ENABLE;
- break;
- case 3:
- data = MT9V032_TEST_PATTERN_GRAY_DIAGONAL
- | MT9V032_TEST_PATTERN_ENABLE;
- break;
- default:
- data = (ctrl->val << MT9V032_TEST_PATTERN_DATA_SHIFT)
- | MT9V032_TEST_PATTERN_USE_DATA
- | MT9V032_TEST_PATTERN_ENABLE
- | MT9V032_TEST_PATTERN_FLIP;
- break;
- }
-
- return mt9v032_write(client, MT9V032_TEST_PATTERN, data);
- }
-
- return 0;
-}
-
-static struct v4l2_ctrl_ops mt9v032_ctrl_ops = {
- .s_ctrl = mt9v032_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config mt9v032_ctrls[] = {
- {
- .ops = &mt9v032_ctrl_ops,
- .id = V4L2_CID_TEST_PATTERN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Test pattern",
- .min = 0,
- .max = 1023,
- .step = 1,
- .def = 0,
- .flags = 0,
- }
-};
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev core operations
- */
-
-static int mt9v032_set_power(struct v4l2_subdev *subdev, int on)
-{
- struct mt9v032 *mt9v032 = to_mt9v032(subdev);
- int ret = 0;
-
- mutex_lock(&mt9v032->power_lock);
-
- /* If the power count is modified from 0 to != 0 or from != 0 to 0,
- * update the power state.
- */
- if (mt9v032->power_count == !on) {
- ret = __mt9v032_set_power(mt9v032, !!on);
- if (ret < 0)
- goto done;
- }
-
- /* Update the power count. */
- mt9v032->power_count += on ? 1 : -1;
- WARN_ON(mt9v032->power_count < 0);
-
-done:
- mutex_unlock(&mt9v032->power_lock);
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev internal operations
- */
-
-static int mt9v032_registered(struct v4l2_subdev *subdev)
-{
- struct i2c_client *client = v4l2_get_subdevdata(subdev);
- struct mt9v032 *mt9v032 = to_mt9v032(subdev);
- s32 data;
- int ret;
-
- dev_info(&client->dev, "Probing MT9V032 at address 0x%02x\n",
- client->addr);
-
- ret = mt9v032_power_on(mt9v032);
- if (ret < 0) {
- dev_err(&client->dev, "MT9V032 power up failed\n");
- return ret;
- }
-
- /* Read and check the sensor version */
- data = mt9v032_read(client, MT9V032_CHIP_VERSION);
- if (data != MT9V032_CHIP_ID_REV1 && data != MT9V032_CHIP_ID_REV3) {
- dev_err(&client->dev, "MT9V032 not detected, wrong version "
- "0x%04x\n", data);
- return -ENODEV;
- }
-
- mt9v032_power_off(mt9v032);
-
- dev_info(&client->dev, "MT9V032 detected at address 0x%02x\n",
- client->addr);
-
- return ret;
-}
-
-static int mt9v032_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
-{
- struct v4l2_mbus_framefmt *format;
- struct v4l2_rect *crop;
-
- crop = v4l2_subdev_get_try_crop(fh, 0);
- crop->left = MT9V032_COLUMN_START_DEF;
- crop->top = MT9V032_ROW_START_DEF;
- crop->width = MT9V032_WINDOW_WIDTH_DEF;
- crop->height = MT9V032_WINDOW_HEIGHT_DEF;
-
- format = v4l2_subdev_get_try_format(fh, 0);
- format->code = V4L2_MBUS_FMT_SGRBG10_1X10;
- format->width = MT9V032_WINDOW_WIDTH_DEF;
- format->height = MT9V032_WINDOW_HEIGHT_DEF;
- format->field = V4L2_FIELD_NONE;
- format->colorspace = V4L2_COLORSPACE_SRGB;
-
- return mt9v032_set_power(subdev, 1);
-}
-
-static int mt9v032_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
-{
- return mt9v032_set_power(subdev, 0);
-}
-
-static struct v4l2_subdev_core_ops mt9v032_subdev_core_ops = {
- .s_power = mt9v032_set_power,
-};
-
-static struct v4l2_subdev_video_ops mt9v032_subdev_video_ops = {
- .s_stream = mt9v032_s_stream,
-};
-
-static struct v4l2_subdev_pad_ops mt9v032_subdev_pad_ops = {
- .enum_mbus_code = mt9v032_enum_mbus_code,
- .enum_frame_size = mt9v032_enum_frame_size,
- .get_fmt = mt9v032_get_format,
- .set_fmt = mt9v032_set_format,
- .get_crop = mt9v032_get_crop,
- .set_crop = mt9v032_set_crop,
-};
-
-static struct v4l2_subdev_ops mt9v032_subdev_ops = {
- .core = &mt9v032_subdev_core_ops,
- .video = &mt9v032_subdev_video_ops,
- .pad = &mt9v032_subdev_pad_ops,
-};
-
-static const struct v4l2_subdev_internal_ops mt9v032_subdev_internal_ops = {
- .registered = mt9v032_registered,
- .open = mt9v032_open,
- .close = mt9v032_close,
-};
-
-/* -----------------------------------------------------------------------------
- * Driver initialization and probing
- */
-
-static int mt9v032_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct mt9v032 *mt9v032;
- unsigned int i;
- int ret;
-
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_WORD_DATA)) {
- dev_warn(&client->adapter->dev,
- "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
- return -EIO;
- }
-
- mt9v032 = kzalloc(sizeof(*mt9v032), GFP_KERNEL);
- if (!mt9v032)
- return -ENOMEM;
-
- mutex_init(&mt9v032->power_lock);
- mt9v032->pdata = client->dev.platform_data;
-
- v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 4);
-
- v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
- V4L2_CID_GAIN, MT9V032_ANALOG_GAIN_MIN,
- MT9V032_ANALOG_GAIN_MAX, 1, MT9V032_ANALOG_GAIN_DEF);
- v4l2_ctrl_new_std_menu(&mt9v032->ctrls, &mt9v032_ctrl_ops,
- V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL, 0,
- V4L2_EXPOSURE_AUTO);
- v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
- V4L2_CID_EXPOSURE, MT9V032_TOTAL_SHUTTER_WIDTH_MIN,
- MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 1,
- MT9V032_TOTAL_SHUTTER_WIDTH_DEF);
-
- for (i = 0; i < ARRAY_SIZE(mt9v032_ctrls); ++i)
- v4l2_ctrl_new_custom(&mt9v032->ctrls, &mt9v032_ctrls[i], NULL);
-
- mt9v032->subdev.ctrl_handler = &mt9v032->ctrls;
-
- if (mt9v032->ctrls.error)
- printk(KERN_INFO "%s: control initialization error %d\n",
- __func__, mt9v032->ctrls.error);
-
- mt9v032->crop.left = MT9V032_COLUMN_START_DEF;
- mt9v032->crop.top = MT9V032_ROW_START_DEF;
- mt9v032->crop.width = MT9V032_WINDOW_WIDTH_DEF;
- mt9v032->crop.height = MT9V032_WINDOW_HEIGHT_DEF;
-
- mt9v032->format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
- mt9v032->format.width = MT9V032_WINDOW_WIDTH_DEF;
- mt9v032->format.height = MT9V032_WINDOW_HEIGHT_DEF;
- mt9v032->format.field = V4L2_FIELD_NONE;
- mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB;
-
- mt9v032->aec_agc = MT9V032_AEC_ENABLE | MT9V032_AGC_ENABLE;
-
- v4l2_i2c_subdev_init(&mt9v032->subdev, client, &mt9v032_subdev_ops);
- mt9v032->subdev.internal_ops = &mt9v032_subdev_internal_ops;
- mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
- if (ret < 0)
- kfree(mt9v032);
-
- return ret;
-}
-
-static int mt9v032_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct mt9v032 *mt9v032 = to_mt9v032(subdev);
-
- v4l2_device_unregister_subdev(subdev);
- media_entity_cleanup(&subdev->entity);
- kfree(mt9v032);
- return 0;
-}
-
-static const struct i2c_device_id mt9v032_id[] = {
- { "mt9v032", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, mt9v032_id);
-
-static struct i2c_driver mt9v032_driver = {
- .driver = {
- .name = "mt9v032",
- },
- .probe = mt9v032_probe,
- .remove = mt9v032_remove,
- .id_table = mt9v032_id,
-};
-
-module_i2c_driver(mt9v032_driver);
-
-MODULE_DESCRIPTION("Aptina MT9V032 Camera driver");
-MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
deleted file mode 100644
index bbe70991d30..00000000000
--- a/drivers/media/video/mx1_camera.c
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- * V4L2 Driver for i.MXL/i.MXL camera (CSI) host
- *
- * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
- * Copyright (C) 2009, Darius Augulis <augulis.darius@gmail.com>
- *
- * Based on PXA SoC camera driver
- * Copyright (C) 2006, Sascha Hauer, Pengutronix
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/videodev2.h>
-
-#include <media/soc_camera.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-dev.h>
-#include <media/videobuf-dma-contig.h>
-#include <media/soc_mediabus.h>
-
-#include <asm/dma.h>
-#include <asm/fiq.h>
-#include <mach/dma-mx1-mx2.h>
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-#include <linux/platform_data/camera-mx1.h>
-
-/*
- * CSI registers
- */
-#define CSICR1 0x00 /* CSI Control Register 1 */
-#define CSISR 0x08 /* CSI Status Register */
-#define CSIRXR 0x10 /* CSI RxFIFO Register */
-
-#define CSICR1_RXFF_LEVEL(x) (((x) & 0x3) << 19)
-#define CSICR1_SOF_POL (1 << 17)
-#define CSICR1_SOF_INTEN (1 << 16)
-#define CSICR1_MCLKDIV(x) (((x) & 0xf) << 12)
-#define CSICR1_MCLKEN (1 << 9)
-#define CSICR1_FCC (1 << 8)
-#define CSICR1_BIG_ENDIAN (1 << 7)
-#define CSICR1_CLR_RXFIFO (1 << 5)
-#define CSICR1_GCLK_MODE (1 << 4)
-#define CSICR1_DATA_POL (1 << 2)
-#define CSICR1_REDGE (1 << 1)
-#define CSICR1_EN (1 << 0)
-
-#define CSISR_SFF_OR_INT (1 << 25)
-#define CSISR_RFF_OR_INT (1 << 24)
-#define CSISR_STATFF_INT (1 << 21)
-#define CSISR_RXFF_INT (1 << 18)
-#define CSISR_SOF_INT (1 << 16)
-#define CSISR_DRDY (1 << 0)
-
-#define DRIVER_VERSION "0.0.2"
-#define DRIVER_NAME "mx1-camera"
-
-#define CSI_IRQ_MASK (CSISR_SFF_OR_INT | CSISR_RFF_OR_INT | \
- CSISR_STATFF_INT | CSISR_RXFF_INT | CSISR_SOF_INT)
-
-#define CSI_BUS_FLAGS (V4L2_MBUS_MASTER | V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | \
- V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
- V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_LOW)
-
-#define MAX_VIDEO_MEM 16 /* Video memory limit in megabytes */
-
-/*
- * Structures
- */
-
-/* buffer for one video frame */
-struct mx1_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
- enum v4l2_mbus_pixelcode code;
- int inwork;
-};
-
-/*
- * i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor
- * Interface. If anyone ever builds hardware to enable more than
- * one camera, they will have to modify this driver too
- */
-struct mx1_camera_dev {
- struct soc_camera_host soc_host;
- struct soc_camera_device *icd;
- struct mx1_camera_pdata *pdata;
- struct mx1_buffer *active;
- struct resource *res;
- struct clk *clk;
- struct list_head capture;
-
- void __iomem *base;
- int dma_chan;
- unsigned int irq;
- unsigned long mclk;
-
- spinlock_t lock;
-};
-
-/*
- * Videobuf operations
- */
-static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
- unsigned int *size)
-{
- struct soc_camera_device *icd = vq->priv_data;
-
- *size = icd->sizeimage;
-
- if (!*count)
- *count = 32;
-
- if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
- *count = (MAX_VIDEO_MEM * 1024 * 1024) / *size;
-
- dev_dbg(icd->parent, "count=%d, size=%d\n", *count, *size);
-
- return 0;
-}
-
-static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf)
-{
- struct soc_camera_device *icd = vq->priv_data;
- struct videobuf_buffer *vb = &buf->vb;
-
- BUG_ON(in_interrupt());
-
- dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
-
- /*
- * This waits until this buffer is out of danger, i.e., until it is no
- * longer in STATE_QUEUED or STATE_ACTIVE
- */
- videobuf_waiton(vq, vb, 0, 0);
- videobuf_dma_contig_free(vq, vb);
-
- vb->state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int mx1_videobuf_prepare(struct videobuf_queue *vq,
- struct videobuf_buffer *vb, enum v4l2_field field)
-{
- struct soc_camera_device *icd = vq->priv_data;
- struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
- int ret;
-
- dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
-
- /* Added list head initialization on alloc */
- WARN_ON(!list_empty(&vb->queue));
-
- BUG_ON(NULL == icd->current_fmt);
-
- /*
- * I think, in buf_prepare you only have to protect global data,
- * the actual buffer is yours
- */
- buf->inwork = 1;
-
- if (buf->code != icd->current_fmt->code ||
- vb->width != icd->user_width ||
- vb->height != icd->user_height ||
- vb->field != field) {
- buf->code = icd->current_fmt->code;
- vb->width = icd->user_width;
- vb->height = icd->user_height;
- vb->field = field;
- vb->state = VIDEOBUF_NEEDS_INIT;
- }
-
- vb->size = icd->sizeimage;
- if (0 != vb->baddr && vb->bsize < vb->size) {
- ret = -EINVAL;
- goto out;
- }
-
- if (vb->state == VIDEOBUF_NEEDS_INIT) {
- ret = videobuf_iolock(vq, vb, NULL);
- if (ret)
- goto fail;
-
- vb->state = VIDEOBUF_PREPARED;
- }
-
- buf->inwork = 0;
-
- return 0;
-
-fail:
- free_buffer(vq, buf);
-out:
- buf->inwork = 0;
- return ret;
-}
-
-static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
-{
- struct videobuf_buffer *vbuf = &pcdev->active->vb;
- struct device *dev = pcdev->icd->parent;
- int ret;
-
- if (unlikely(!pcdev->active)) {
- dev_err(dev, "DMA End IRQ with no active buffer\n");
- return -EFAULT;
- }
-
- /* setup sg list for future DMA */
- ret = imx_dma_setup_single(pcdev->dma_chan,
- videobuf_to_dma_contig(vbuf),
- vbuf->size, pcdev->res->start +
- CSIRXR, DMA_MODE_READ);
- if (unlikely(ret))
- dev_err(dev, "Failed to setup DMA sg list\n");
-
- return ret;
-}
-
-/* Called under spinlock_irqsave(&pcdev->lock, ...) */
-static void mx1_videobuf_queue(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct soc_camera_device *icd = vq->priv_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx1_camera_dev *pcdev = ici->priv;
- struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
-
- dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
-
- list_add_tail(&vb->queue, &pcdev->capture);
-
- vb->state = VIDEOBUF_ACTIVE;
-
- if (!pcdev->active) {
- pcdev->active = buf;
-
- /* setup sg list for future DMA */
- if (!mx1_camera_setup_dma(pcdev)) {
- unsigned int temp;
- /* enable SOF irq */
- temp = __raw_readl(pcdev->base + CSICR1) |
- CSICR1_SOF_INTEN;
- __raw_writel(temp, pcdev->base + CSICR1);
- }
- }
-}
-
-static void mx1_videobuf_release(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
-#ifdef DEBUG
- struct soc_camera_device *icd = vq->priv_data;
- struct device *dev = icd->parent;
-
- dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
-
- switch (vb->state) {
- case VIDEOBUF_ACTIVE:
- dev_dbg(dev, "%s (active)\n", __func__);
- break;
- case VIDEOBUF_QUEUED:
- dev_dbg(dev, "%s (queued)\n", __func__);
- break;
- case VIDEOBUF_PREPARED:
- dev_dbg(dev, "%s (prepared)\n", __func__);
- break;
- default:
- dev_dbg(dev, "%s (unknown)\n", __func__);
- break;
- }
-#endif
-
- free_buffer(vq, buf);
-}
-
-static void mx1_camera_wakeup(struct mx1_camera_dev *pcdev,
- struct videobuf_buffer *vb,
- struct mx1_buffer *buf)
-{
- /* _init is used to debug races, see comment in mx1_camera_reqbufs() */
- list_del_init(&vb->queue);
- vb->state = VIDEOBUF_DONE;
- do_gettimeofday(&vb->ts);
- vb->field_count++;
- wake_up(&vb->done);
-
- if (list_empty(&pcdev->capture)) {
- pcdev->active = NULL;
- return;
- }
-
- pcdev->active = list_entry(pcdev->capture.next,
- struct mx1_buffer, vb.queue);
-
- /* setup sg list for future DMA */
- if (likely(!mx1_camera_setup_dma(pcdev))) {
- unsigned int temp;
-
- /* enable SOF irq */
- temp = __raw_readl(pcdev->base + CSICR1) | CSICR1_SOF_INTEN;
- __raw_writel(temp, pcdev->base + CSICR1);
- }
-}
-
-static void mx1_camera_dma_irq(int channel, void *data)
-{
- struct mx1_camera_dev *pcdev = data;
- struct device *dev = pcdev->icd->parent;
- struct mx1_buffer *buf;
- struct videobuf_buffer *vb;
- unsigned long flags;
-
- spin_lock_irqsave(&pcdev->lock, flags);
-
- imx_dma_disable(channel);
-
- if (unlikely(!pcdev->active)) {
- dev_err(dev, "DMA End IRQ with no active buffer\n");
- goto out;
- }
-
- vb = &pcdev->active->vb;
- buf = container_of(vb, struct mx1_buffer, vb);
- WARN_ON(buf->inwork || list_empty(&vb->queue));
- dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
-
- mx1_camera_wakeup(pcdev, vb, buf);
-out:
- spin_unlock_irqrestore(&pcdev->lock, flags);
-}
-
-static struct videobuf_queue_ops mx1_videobuf_ops = {
- .buf_setup = mx1_videobuf_setup,
- .buf_prepare = mx1_videobuf_prepare,
- .buf_queue = mx1_videobuf_queue,
- .buf_release = mx1_videobuf_release,
-};
-
-static void mx1_camera_init_videobuf(struct videobuf_queue *q,
- struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx1_camera_dev *pcdev = ici->priv;
-
- videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, icd->parent,
- &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_NONE,
- sizeof(struct mx1_buffer), icd, &icd->video_lock);
-}
-
-static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
-{
- unsigned int mclk = pcdev->mclk;
- unsigned long div;
- unsigned long lcdclk;
-
- lcdclk = clk_get_rate(pcdev->clk);
-
- /*
- * We verify platform_mclk_10khz != 0, so if anyone breaks it, here
- * they get a nice Oops
- */
- div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
-
- dev_dbg(pcdev->icd->parent,
- "System clock %lukHz, target freq %dkHz, divisor %lu\n",
- lcdclk / 1000, mclk / 1000, div);
-
- return div;
-}
-
-static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
-{
- unsigned int csicr1 = CSICR1_EN;
-
- dev_dbg(pcdev->icd->parent, "Activate device\n");
-
- clk_prepare_enable(pcdev->clk);
-
- /* enable CSI before doing anything else */
- __raw_writel(csicr1, pcdev->base + CSICR1);
-
- csicr1 |= CSICR1_MCLKEN | CSICR1_FCC | CSICR1_GCLK_MODE;
- csicr1 |= CSICR1_MCLKDIV(mclk_get_divisor(pcdev));
- csicr1 |= CSICR1_RXFF_LEVEL(2); /* 16 words */
-
- __raw_writel(csicr1, pcdev->base + CSICR1);
-}
-
-static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
-{
- dev_dbg(pcdev->icd->parent, "Deactivate device\n");
-
- /* Disable all CSI interface */
- __raw_writel(0x00, pcdev->base + CSICR1);
-
- clk_disable_unprepare(pcdev->clk);
-}
-
-/*
- * The following two functions absolutely depend on the fact, that
- * there can be only one camera on i.MX1/i.MXL camera sensor interface
- */
-static int mx1_camera_add_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx1_camera_dev *pcdev = ici->priv;
-
- if (pcdev->icd)
- return -EBUSY;
-
- dev_info(icd->parent, "MX1 Camera driver attached to camera %d\n",
- icd->devnum);
-
- mx1_camera_activate(pcdev);
-
- pcdev->icd = icd;
-
- return 0;
-}
-
-static void mx1_camera_remove_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx1_camera_dev *pcdev = ici->priv;
- unsigned int csicr1;
-
- BUG_ON(icd != pcdev->icd);
-
- /* disable interrupts */
- csicr1 = __raw_readl(pcdev->base + CSICR1) & ~CSI_IRQ_MASK;
- __raw_writel(csicr1, pcdev->base + CSICR1);
-
- /* Stop DMA engine */
- imx_dma_disable(pcdev->dma_chan);
-
- dev_info(icd->parent, "MX1 Camera driver detached from camera %d\n",
- icd->devnum);
-
- mx1_camera_deactivate(pcdev);
-
- pcdev->icd = NULL;
-}
-
-static int mx1_camera_set_crop(struct soc_camera_device *icd,
- struct v4l2_crop *a)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
- return v4l2_subdev_call(sd, video, s_crop, a);
-}
-
-static int mx1_camera_set_bus_param(struct soc_camera_device *icd)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx1_camera_dev *pcdev = ici->priv;
- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
- unsigned long common_flags;
- unsigned int csicr1;
- int ret;
-
- /* MX1 supports only 8bit buswidth */
- ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
- if (!ret) {
- common_flags = soc_mbus_config_compatible(&cfg, CSI_BUS_FLAGS);
- if (!common_flags) {
- dev_warn(icd->parent,
- "Flags incompatible: camera 0x%x, host 0x%x\n",
- cfg.flags, CSI_BUS_FLAGS);
- return -EINVAL;
- }
- } else if (ret != -ENOIOCTLCMD) {
- return ret;
- } else {
- common_flags = CSI_BUS_FLAGS;
- }
-
- /* Make choises, based on platform choice */
- if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
- (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
- if (!pcdev->pdata ||
- pcdev->pdata->flags & MX1_CAMERA_VSYNC_HIGH)
- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
- else
- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
- }
-
- if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
- (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
- if (!pcdev->pdata ||
- pcdev->pdata->flags & MX1_CAMERA_PCLK_RISING)
- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
- else
- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
- }
-
- if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
- (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
- if (!pcdev->pdata ||
- pcdev->pdata->flags & MX1_CAMERA_DATA_HIGH)
- common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
- else
- common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
- }
-
- cfg.flags = common_flags;
- ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
- if (ret < 0 && ret != -ENOIOCTLCMD) {
- dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
- common_flags, ret);
- return ret;
- }
-
- csicr1 = __raw_readl(pcdev->base + CSICR1);
-
- if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
- csicr1 |= CSICR1_REDGE;
- if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
- csicr1 |= CSICR1_SOF_POL;
- if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
- csicr1 |= CSICR1_DATA_POL;
-
- __raw_writel(csicr1, pcdev->base + CSICR1);
-
- return 0;
-}
-
-static int mx1_camera_set_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- int ret, buswidth;
-
- xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
- if (!xlate) {
- dev_warn(icd->parent, "Format %x not found\n",
- pix->pixelformat);
- return -EINVAL;
- }
-
- buswidth = xlate->host_fmt->bits_per_sample;
- if (buswidth > 8) {
- dev_warn(icd->parent,
- "bits-per-sample %d for format %x unsupported\n",
- buswidth, pix->pixelformat);
- return -EINVAL;
- }
-
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- if (mf.code != xlate->code)
- return -EINVAL;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
- icd->current_fmt = xlate;
-
- return ret;
-}
-
-static int mx1_camera_try_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- int ret;
- /* TODO: limit to mx1 hardware capabilities */
-
- xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
- if (!xlate) {
- dev_warn(icd->parent, "Format %x not found\n",
- pix->pixelformat);
- return -EINVAL;
- }
-
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- /* limit to sensor capabilities */
- ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
-
- return 0;
-}
-
-static int mx1_camera_reqbufs(struct soc_camera_device *icd,
- struct v4l2_requestbuffers *p)
-{
- int i;
-
- /*
- * This is for locking debugging only. I removed spinlocks and now I
- * check whether .prepare is ever called on a linked buffer, or whether
- * a dma IRQ can occur for an in-work or unlinked buffer. Until now
- * it hadn't triggered
- */
- for (i = 0; i < p->count; i++) {
- struct mx1_buffer *buf = container_of(icd->vb_vidq.bufs[i],
- struct mx1_buffer, vb);
- buf->inwork = 0;
- INIT_LIST_HEAD(&buf->vb.queue);
- }
-
- return 0;
-}
-
-static unsigned int mx1_camera_poll(struct file *file, poll_table *pt)
-{
- struct soc_camera_device *icd = file->private_data;
- struct mx1_buffer *buf;
-
- buf = list_entry(icd->vb_vidq.stream.next, struct mx1_buffer,
- vb.stream);
-
- poll_wait(file, &buf->vb.done, pt);
-
- if (buf->vb.state == VIDEOBUF_DONE ||
- buf->vb.state == VIDEOBUF_ERROR)
- return POLLIN | POLLRDNORM;
-
- return 0;
-}
-
-static int mx1_camera_querycap(struct soc_camera_host *ici,
- struct v4l2_capability *cap)
-{
- /* cap->name is set by the friendly caller:-> */
- strlcpy(cap->card, "i.MX1/i.MXL Camera", sizeof(cap->card));
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-
- return 0;
-}
-
-static struct soc_camera_host_ops mx1_soc_camera_host_ops = {
- .owner = THIS_MODULE,
- .add = mx1_camera_add_device,
- .remove = mx1_camera_remove_device,
- .set_bus_param = mx1_camera_set_bus_param,
- .set_crop = mx1_camera_set_crop,
- .set_fmt = mx1_camera_set_fmt,
- .try_fmt = mx1_camera_try_fmt,
- .init_videobuf = mx1_camera_init_videobuf,
- .reqbufs = mx1_camera_reqbufs,
- .poll = mx1_camera_poll,
- .querycap = mx1_camera_querycap,
-};
-
-static struct fiq_handler fh = {
- .name = "csi_sof"
-};
-
-static int __init mx1_camera_probe(struct platform_device *pdev)
-{
- struct mx1_camera_dev *pcdev;
- struct resource *res;
- struct pt_regs regs;
- struct clk *clk;
- void __iomem *base;
- unsigned int irq;
- int err = 0;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- irq = platform_get_irq(pdev, 0);
- if (!res || (int)irq <= 0) {
- err = -ENODEV;
- goto exit;
- }
-
- clk = clk_get(&pdev->dev, "csi_clk");
- if (IS_ERR(clk)) {
- err = PTR_ERR(clk);
- goto exit;
- }
-
- pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
- if (!pcdev) {
- dev_err(&pdev->dev, "Could not allocate pcdev\n");
- err = -ENOMEM;
- goto exit_put_clk;
- }
-
- pcdev->res = res;
- pcdev->clk = clk;
-
- pcdev->pdata = pdev->dev.platform_data;
-
- if (pcdev->pdata)
- pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
-
- if (!pcdev->mclk) {
- dev_warn(&pdev->dev,
- "mclk_10khz == 0! Please, fix your platform data. "
- "Using default 20MHz\n");
- pcdev->mclk = 20000000;
- }
-
- INIT_LIST_HEAD(&pcdev->capture);
- spin_lock_init(&pcdev->lock);
-
- /*
- * Request the regions.
- */
- if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) {
- err = -EBUSY;
- goto exit_kfree;
- }
-
- base = ioremap(res->start, resource_size(res));
- if (!base) {
- err = -ENOMEM;
- goto exit_release;
- }
- pcdev->irq = irq;
- pcdev->base = base;
-
- /* request dma */
- pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH);
- if (pcdev->dma_chan < 0) {
- dev_err(&pdev->dev, "Can't request DMA for MX1 CSI\n");
- err = -EBUSY;
- goto exit_iounmap;
- }
- dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chan);
-
- imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL,
- pcdev);
-
- imx_dma_config_channel(pcdev->dma_chan, IMX_DMA_TYPE_FIFO,
- IMX_DMA_MEMSIZE_32, MX1_DMA_REQ_CSI_R, 0);
- /* burst length : 16 words = 64 bytes */
- imx_dma_config_burstlen(pcdev->dma_chan, 0);
-
- /* request irq */
- err = claim_fiq(&fh);
- if (err) {
- dev_err(&pdev->dev, "Camera interrupt register failed \n");
- goto exit_free_dma;
- }
-
- set_fiq_handler(&mx1_camera_sof_fiq_start, &mx1_camera_sof_fiq_end -
- &mx1_camera_sof_fiq_start);
-
- regs.ARM_r8 = (long)MX1_DMA_DIMR;
- regs.ARM_r9 = (long)MX1_DMA_CCR(pcdev->dma_chan);
- regs.ARM_r10 = (long)pcdev->base + CSICR1;
- regs.ARM_fp = (long)pcdev->base + CSISR;
- regs.ARM_sp = 1 << pcdev->dma_chan;
- set_fiq_regs(&regs);
-
- mxc_set_irq_fiq(irq, 1);
- enable_fiq(irq);
-
- pcdev->soc_host.drv_name = DRIVER_NAME;
- pcdev->soc_host.ops = &mx1_soc_camera_host_ops;
- pcdev->soc_host.priv = pcdev;
- pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
- pcdev->soc_host.nr = pdev->id;
- err = soc_camera_host_register(&pcdev->soc_host);
- if (err)
- goto exit_free_irq;
-
- dev_info(&pdev->dev, "MX1 Camera driver loaded\n");
-
- return 0;
-
-exit_free_irq:
- disable_fiq(irq);
- mxc_set_irq_fiq(irq, 0);
- release_fiq(&fh);
-exit_free_dma:
- imx_dma_free(pcdev->dma_chan);
-exit_iounmap:
- iounmap(base);
-exit_release:
- release_mem_region(res->start, resource_size(res));
-exit_kfree:
- kfree(pcdev);
-exit_put_clk:
- clk_put(clk);
-exit:
- return err;
-}
-
-static int __exit mx1_camera_remove(struct platform_device *pdev)
-{
- struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
- struct mx1_camera_dev *pcdev = container_of(soc_host,
- struct mx1_camera_dev, soc_host);
- struct resource *res;
-
- imx_dma_free(pcdev->dma_chan);
- disable_fiq(pcdev->irq);
- mxc_set_irq_fiq(pcdev->irq, 0);
- release_fiq(&fh);
-
- clk_put(pcdev->clk);
-
- soc_camera_host_unregister(soc_host);
-
- iounmap(pcdev->base);
-
- res = pcdev->res;
- release_mem_region(res->start, resource_size(res));
-
- kfree(pcdev);
-
- dev_info(&pdev->dev, "MX1 Camera driver unloaded\n");
-
- return 0;
-}
-
-static struct platform_driver mx1_camera_driver = {
- .driver = {
- .name = DRIVER_NAME,
- },
- .remove = __exit_p(mx1_camera_remove),
-};
-
-static int __init mx1_camera_init(void)
-{
- return platform_driver_probe(&mx1_camera_driver, mx1_camera_probe);
-}
-
-static void __exit mx1_camera_exit(void)
-{
- return platform_driver_unregister(&mx1_camera_driver);
-}
-
-module_init(mx1_camera_init);
-module_exit(mx1_camera_exit);
-
-MODULE_DESCRIPTION("i.MX1/i.MXL SoC Camera Host driver");
-MODULE_AUTHOR("Paulius Zaleckas <paulius.zaleckas@teltonika.lt>");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
deleted file mode 100644
index 965427f279a..00000000000
--- a/drivers/media/video/mx2_camera.c
+++ /dev/null
@@ -1,1884 +0,0 @@
-/*
- * V4L2 Driver for i.MX27/i.MX25 camera host
- *
- * Copyright (C) 2008, Sascha Hauer, Pengutronix
- * Copyright (C) 2010, Baruch Siach, Orex Computed Radiography
- * Copyright (C) 2012, Javier Martin, Vista Silicon S.L.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/dma-mapping.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/gcd.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/math64.h>
-#include <linux/mm.h>
-#include <linux/moduleparam.h>
-#include <linux/time.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-#include <linux/clk.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-dev.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-contig.h>
-#include <media/soc_camera.h>
-#include <media/soc_mediabus.h>
-
-#include <linux/videodev2.h>
-
-#include <linux/platform_data/camera-mx2.h>
-#include <mach/hardware.h>
-
-#include <asm/dma.h>
-
-#define MX2_CAM_DRV_NAME "mx2-camera"
-#define MX2_CAM_VERSION "0.0.6"
-#define MX2_CAM_DRIVER_DESCRIPTION "i.MX2x_Camera"
-
-/* reset values */
-#define CSICR1_RESET_VAL 0x40000800
-#define CSICR2_RESET_VAL 0x0
-#define CSICR3_RESET_VAL 0x0
-
-/* csi control reg 1 */
-#define CSICR1_SWAP16_EN (1 << 31)
-#define CSICR1_EXT_VSYNC (1 << 30)
-#define CSICR1_EOF_INTEN (1 << 29)
-#define CSICR1_PRP_IF_EN (1 << 28)
-#define CSICR1_CCIR_MODE (1 << 27)
-#define CSICR1_COF_INTEN (1 << 26)
-#define CSICR1_SF_OR_INTEN (1 << 25)
-#define CSICR1_RF_OR_INTEN (1 << 24)
-#define CSICR1_STATFF_LEVEL (3 << 22)
-#define CSICR1_STATFF_INTEN (1 << 21)
-#define CSICR1_RXFF_LEVEL(l) (((l) & 3) << 19) /* MX27 */
-#define CSICR1_FB2_DMA_INTEN (1 << 20) /* MX25 */
-#define CSICR1_FB1_DMA_INTEN (1 << 19) /* MX25 */
-#define CSICR1_RXFF_INTEN (1 << 18)
-#define CSICR1_SOF_POL (1 << 17)
-#define CSICR1_SOF_INTEN (1 << 16)
-#define CSICR1_MCLKDIV(d) (((d) & 0xF) << 12)
-#define CSICR1_HSYNC_POL (1 << 11)
-#define CSICR1_CCIR_EN (1 << 10)
-#define CSICR1_MCLKEN (1 << 9)
-#define CSICR1_FCC (1 << 8)
-#define CSICR1_PACK_DIR (1 << 7)
-#define CSICR1_CLR_STATFIFO (1 << 6)
-#define CSICR1_CLR_RXFIFO (1 << 5)
-#define CSICR1_GCLK_MODE (1 << 4)
-#define CSICR1_INV_DATA (1 << 3)
-#define CSICR1_INV_PCLK (1 << 2)
-#define CSICR1_REDGE (1 << 1)
-#define CSICR1_FMT_MASK (CSICR1_PACK_DIR | CSICR1_SWAP16_EN)
-
-#define SHIFT_STATFF_LEVEL 22
-#define SHIFT_RXFF_LEVEL 19
-#define SHIFT_MCLKDIV 12
-
-/* control reg 3 */
-#define CSICR3_FRMCNT (0xFFFF << 16)
-#define CSICR3_FRMCNT_RST (1 << 15)
-#define CSICR3_DMA_REFLASH_RFF (1 << 14)
-#define CSICR3_DMA_REFLASH_SFF (1 << 13)
-#define CSICR3_DMA_REQ_EN_RFF (1 << 12)
-#define CSICR3_DMA_REQ_EN_SFF (1 << 11)
-#define CSICR3_RXFF_LEVEL(l) (((l) & 7) << 4) /* MX25 */
-#define CSICR3_CSI_SUP (1 << 3)
-#define CSICR3_ZERO_PACK_EN (1 << 2)
-#define CSICR3_ECC_INT_EN (1 << 1)
-#define CSICR3_ECC_AUTO_EN (1 << 0)
-
-#define SHIFT_FRMCNT 16
-
-/* csi status reg */
-#define CSISR_SFF_OR_INT (1 << 25)
-#define CSISR_RFF_OR_INT (1 << 24)
-#define CSISR_STATFF_INT (1 << 21)
-#define CSISR_DMA_TSF_FB2_INT (1 << 20) /* MX25 */
-#define CSISR_DMA_TSF_FB1_INT (1 << 19) /* MX25 */
-#define CSISR_RXFF_INT (1 << 18)
-#define CSISR_EOF_INT (1 << 17)
-#define CSISR_SOF_INT (1 << 16)
-#define CSISR_F2_INT (1 << 15)
-#define CSISR_F1_INT (1 << 14)
-#define CSISR_COF_INT (1 << 13)
-#define CSISR_ECC_INT (1 << 1)
-#define CSISR_DRDY (1 << 0)
-
-#define CSICR1 0x00
-#define CSICR2 0x04
-#define CSISR (cpu_is_mx27() ? 0x08 : 0x18)
-#define CSISTATFIFO 0x0c
-#define CSIRFIFO 0x10
-#define CSIRXCNT 0x14
-#define CSICR3 (cpu_is_mx27() ? 0x1C : 0x08)
-#define CSIDMASA_STATFIFO 0x20
-#define CSIDMATA_STATFIFO 0x24
-#define CSIDMASA_FB1 0x28
-#define CSIDMASA_FB2 0x2c
-#define CSIFBUF_PARA 0x30
-#define CSIIMAG_PARA 0x34
-
-/* EMMA PrP */
-#define PRP_CNTL 0x00
-#define PRP_INTR_CNTL 0x04
-#define PRP_INTRSTATUS 0x08
-#define PRP_SOURCE_Y_PTR 0x0c
-#define PRP_SOURCE_CB_PTR 0x10
-#define PRP_SOURCE_CR_PTR 0x14
-#define PRP_DEST_RGB1_PTR 0x18
-#define PRP_DEST_RGB2_PTR 0x1c
-#define PRP_DEST_Y_PTR 0x20
-#define PRP_DEST_CB_PTR 0x24
-#define PRP_DEST_CR_PTR 0x28
-#define PRP_SRC_FRAME_SIZE 0x2c
-#define PRP_DEST_CH1_LINE_STRIDE 0x30
-#define PRP_SRC_PIXEL_FORMAT_CNTL 0x34
-#define PRP_CH1_PIXEL_FORMAT_CNTL 0x38
-#define PRP_CH1_OUT_IMAGE_SIZE 0x3c
-#define PRP_CH2_OUT_IMAGE_SIZE 0x40
-#define PRP_SRC_LINE_STRIDE 0x44
-#define PRP_CSC_COEF_012 0x48
-#define PRP_CSC_COEF_345 0x4c
-#define PRP_CSC_COEF_678 0x50
-#define PRP_CH1_RZ_HORI_COEF1 0x54
-#define PRP_CH1_RZ_HORI_COEF2 0x58
-#define PRP_CH1_RZ_HORI_VALID 0x5c
-#define PRP_CH1_RZ_VERT_COEF1 0x60
-#define PRP_CH1_RZ_VERT_COEF2 0x64
-#define PRP_CH1_RZ_VERT_VALID 0x68
-#define PRP_CH2_RZ_HORI_COEF1 0x6c
-#define PRP_CH2_RZ_HORI_COEF2 0x70
-#define PRP_CH2_RZ_HORI_VALID 0x74
-#define PRP_CH2_RZ_VERT_COEF1 0x78
-#define PRP_CH2_RZ_VERT_COEF2 0x7c
-#define PRP_CH2_RZ_VERT_VALID 0x80
-
-#define PRP_CNTL_CH1EN (1 << 0)
-#define PRP_CNTL_CH2EN (1 << 1)
-#define PRP_CNTL_CSIEN (1 << 2)
-#define PRP_CNTL_DATA_IN_YUV420 (0 << 3)
-#define PRP_CNTL_DATA_IN_YUV422 (1 << 3)
-#define PRP_CNTL_DATA_IN_RGB16 (2 << 3)
-#define PRP_CNTL_DATA_IN_RGB32 (3 << 3)
-#define PRP_CNTL_CH1_OUT_RGB8 (0 << 5)
-#define PRP_CNTL_CH1_OUT_RGB16 (1 << 5)
-#define PRP_CNTL_CH1_OUT_RGB32 (2 << 5)
-#define PRP_CNTL_CH1_OUT_YUV422 (3 << 5)
-#define PRP_CNTL_CH2_OUT_YUV420 (0 << 7)
-#define PRP_CNTL_CH2_OUT_YUV422 (1 << 7)
-#define PRP_CNTL_CH2_OUT_YUV444 (2 << 7)
-#define PRP_CNTL_CH1_LEN (1 << 9)
-#define PRP_CNTL_CH2_LEN (1 << 10)
-#define PRP_CNTL_SKIP_FRAME (1 << 11)
-#define PRP_CNTL_SWRST (1 << 12)
-#define PRP_CNTL_CLKEN (1 << 13)
-#define PRP_CNTL_WEN (1 << 14)
-#define PRP_CNTL_CH1BYP (1 << 15)
-#define PRP_CNTL_IN_TSKIP(x) ((x) << 16)
-#define PRP_CNTL_CH1_TSKIP(x) ((x) << 19)
-#define PRP_CNTL_CH2_TSKIP(x) ((x) << 22)
-#define PRP_CNTL_INPUT_FIFO_LEVEL(x) ((x) << 25)
-#define PRP_CNTL_RZ_FIFO_LEVEL(x) ((x) << 27)
-#define PRP_CNTL_CH2B1EN (1 << 29)
-#define PRP_CNTL_CH2B2EN (1 << 30)
-#define PRP_CNTL_CH2FEN (1 << 31)
-
-/* IRQ Enable and status register */
-#define PRP_INTR_RDERR (1 << 0)
-#define PRP_INTR_CH1WERR (1 << 1)
-#define PRP_INTR_CH2WERR (1 << 2)
-#define PRP_INTR_CH1FC (1 << 3)
-#define PRP_INTR_CH2FC (1 << 5)
-#define PRP_INTR_LBOVF (1 << 7)
-#define PRP_INTR_CH2OVF (1 << 8)
-
-/* Resizing registers */
-#define PRP_RZ_VALID_TBL_LEN(x) ((x) << 24)
-#define PRP_RZ_VALID_BILINEAR (1 << 31)
-
-#define MAX_VIDEO_MEM 16
-
-#define RESIZE_NUM_MIN 1
-#define RESIZE_NUM_MAX 20
-#define BC_COEF 3
-#define SZ_COEF (1 << BC_COEF)
-
-#define RESIZE_DIR_H 0
-#define RESIZE_DIR_V 1
-
-#define RESIZE_ALGO_BILINEAR 0
-#define RESIZE_ALGO_AVERAGING 1
-
-struct mx2_prp_cfg {
- int channel;
- u32 in_fmt;
- u32 out_fmt;
- u32 src_pixel;
- u32 ch1_pixel;
- u32 irq_flags;
- u32 csicr1;
-};
-
-/* prp resizing parameters */
-struct emma_prp_resize {
- int algo; /* type of algorithm used */
- int len; /* number of coefficients */
- unsigned char s[RESIZE_NUM_MAX]; /* table of coefficients */
-};
-
-/* prp configuration for a client-host fmt pair */
-struct mx2_fmt_cfg {
- enum v4l2_mbus_pixelcode in_fmt;
- u32 out_fmt;
- struct mx2_prp_cfg cfg;
-};
-
-enum mx2_buffer_state {
- MX2_STATE_QUEUED,
- MX2_STATE_ACTIVE,
- MX2_STATE_DONE,
-};
-
-struct mx2_buf_internal {
- struct list_head queue;
- int bufnum;
- bool discard;
-};
-
-/* buffer for one video frame */
-struct mx2_buffer {
- /* common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
- enum mx2_buffer_state state;
- struct mx2_buf_internal internal;
-};
-
-struct mx2_camera_dev {
- struct device *dev;
- struct soc_camera_host soc_host;
- struct soc_camera_device *icd;
- struct clk *clk_csi, *clk_emma_ahb, *clk_emma_ipg;
-
- unsigned int irq_csi, irq_emma;
- void __iomem *base_csi, *base_emma;
- unsigned long base_dma;
-
- struct mx2_camera_platform_data *pdata;
- struct resource *res_csi, *res_emma;
- unsigned long platform_flags;
-
- struct list_head capture;
- struct list_head active_bufs;
- struct list_head discard;
-
- spinlock_t lock;
-
- int dma;
- struct mx2_buffer *active;
- struct mx2_buffer *fb1_active;
- struct mx2_buffer *fb2_active;
-
- u32 csicr1;
-
- struct mx2_buf_internal buf_discard[2];
- void *discard_buffer;
- dma_addr_t discard_buffer_dma;
- size_t discard_size;
- struct mx2_fmt_cfg *emma_prp;
- struct emma_prp_resize resizing[2];
- unsigned int s_width, s_height;
- u32 frame_count;
- struct vb2_alloc_ctx *alloc_ctx;
-};
-
-static struct mx2_buffer *mx2_ibuf_to_buf(struct mx2_buf_internal *int_buf)
-{
- return container_of(int_buf, struct mx2_buffer, internal);
-}
-
-static struct mx2_fmt_cfg mx27_emma_prp_table[] = {
- /*
- * This is a generic configuration which is valid for most
- * prp input-output format combinations.
- * We set the incomming and outgoing pixelformat to a
- * 16 Bit wide format and adjust the bytesperline
- * accordingly. With this configuration the inputdata
- * will not be changed by the emma and could be any type
- * of 16 Bit Pixelformat.
- */
- {
- .in_fmt = 0,
- .out_fmt = 0,
- .cfg = {
- .channel = 1,
- .in_fmt = PRP_CNTL_DATA_IN_RGB16,
- .out_fmt = PRP_CNTL_CH1_OUT_RGB16,
- .src_pixel = 0x2ca00565, /* RGB565 */
- .ch1_pixel = 0x2ca00565, /* RGB565 */
- .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH1WERR |
- PRP_INTR_CH1FC | PRP_INTR_LBOVF,
- .csicr1 = 0,
- }
- },
- {
- .in_fmt = V4L2_MBUS_FMT_YUYV8_2X8,
- .out_fmt = V4L2_PIX_FMT_YUV420,
- .cfg = {
- .channel = 2,
- .in_fmt = PRP_CNTL_DATA_IN_YUV422,
- .out_fmt = PRP_CNTL_CH2_OUT_YUV420,
- .src_pixel = 0x22000888, /* YUV422 (YUYV) */
- .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH2WERR |
- PRP_INTR_CH2FC | PRP_INTR_LBOVF |
- PRP_INTR_CH2OVF,
- .csicr1 = CSICR1_PACK_DIR,
- }
- },
- {
- .in_fmt = V4L2_MBUS_FMT_UYVY8_2X8,
- .out_fmt = V4L2_PIX_FMT_YUV420,
- .cfg = {
- .channel = 2,
- .in_fmt = PRP_CNTL_DATA_IN_YUV422,
- .out_fmt = PRP_CNTL_CH2_OUT_YUV420,
- .src_pixel = 0x22000888, /* YUV422 (YUYV) */
- .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH2WERR |
- PRP_INTR_CH2FC | PRP_INTR_LBOVF |
- PRP_INTR_CH2OVF,
- .csicr1 = CSICR1_SWAP16_EN,
- }
- },
-};
-
-static struct mx2_fmt_cfg *mx27_emma_prp_get_format(
- enum v4l2_mbus_pixelcode in_fmt,
- u32 out_fmt)
-{
- int i;
-
- for (i = 1; i < ARRAY_SIZE(mx27_emma_prp_table); i++)
- if ((mx27_emma_prp_table[i].in_fmt == in_fmt) &&
- (mx27_emma_prp_table[i].out_fmt == out_fmt)) {
- return &mx27_emma_prp_table[i];
- }
- /* If no match return the most generic configuration */
- return &mx27_emma_prp_table[0];
-};
-
-static void mx27_update_emma_buf(struct mx2_camera_dev *pcdev,
- unsigned long phys, int bufnum)
-{
- struct mx2_fmt_cfg *prp = pcdev->emma_prp;
-
- if (prp->cfg.channel == 1) {
- writel(phys, pcdev->base_emma +
- PRP_DEST_RGB1_PTR + 4 * bufnum);
- } else {
- writel(phys, pcdev->base_emma +
- PRP_DEST_Y_PTR - 0x14 * bufnum);
- if (prp->out_fmt == V4L2_PIX_FMT_YUV420) {
- u32 imgsize = pcdev->icd->user_height *
- pcdev->icd->user_width;
-
- writel(phys + imgsize, pcdev->base_emma +
- PRP_DEST_CB_PTR - 0x14 * bufnum);
- writel(phys + ((5 * imgsize) / 4), pcdev->base_emma +
- PRP_DEST_CR_PTR - 0x14 * bufnum);
- }
- }
-}
-
-static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
-{
- unsigned long flags;
-
- clk_disable_unprepare(pcdev->clk_csi);
- writel(0, pcdev->base_csi + CSICR1);
- if (cpu_is_mx27()) {
- writel(0, pcdev->base_emma + PRP_CNTL);
- } else if (cpu_is_mx25()) {
- spin_lock_irqsave(&pcdev->lock, flags);
- pcdev->fb1_active = NULL;
- pcdev->fb2_active = NULL;
- writel(0, pcdev->base_csi + CSIDMASA_FB1);
- writel(0, pcdev->base_csi + CSIDMASA_FB2);
- spin_unlock_irqrestore(&pcdev->lock, flags);
- }
-}
-
-/*
- * The following two functions absolutely depend on the fact, that
- * there can be only one camera on mx2 camera sensor interface
- */
-static int mx2_camera_add_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx2_camera_dev *pcdev = ici->priv;
- int ret;
- u32 csicr1;
-
- if (pcdev->icd)
- return -EBUSY;
-
- ret = clk_prepare_enable(pcdev->clk_csi);
- if (ret < 0)
- return ret;
-
- csicr1 = CSICR1_MCLKEN;
-
- if (cpu_is_mx27()) {
- csicr1 |= CSICR1_PRP_IF_EN | CSICR1_FCC |
- CSICR1_RXFF_LEVEL(0);
- } else if (cpu_is_mx27())
- csicr1 |= CSICR1_SOF_INTEN | CSICR1_RXFF_LEVEL(2);
-
- pcdev->csicr1 = csicr1;
- writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
-
- pcdev->icd = icd;
- pcdev->frame_count = 0;
-
- dev_info(icd->parent, "Camera driver attached to camera %d\n",
- icd->devnum);
-
- return 0;
-}
-
-static void mx2_camera_remove_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx2_camera_dev *pcdev = ici->priv;
-
- BUG_ON(icd != pcdev->icd);
-
- dev_info(icd->parent, "Camera driver detached from camera %d\n",
- icd->devnum);
-
- mx2_camera_deactivate(pcdev);
-
- pcdev->icd = NULL;
-}
-
-static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb,
- int state)
-{
- struct vb2_buffer *vb;
- struct mx2_buffer *buf;
- struct mx2_buffer **fb_active = fb == 1 ? &pcdev->fb1_active :
- &pcdev->fb2_active;
- u32 fb_reg = fb == 1 ? CSIDMASA_FB1 : CSIDMASA_FB2;
- unsigned long flags;
-
- spin_lock_irqsave(&pcdev->lock, flags);
-
- if (*fb_active == NULL)
- goto out;
-
- vb = &(*fb_active)->vb;
- dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__,
- vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
-
- do_gettimeofday(&vb->v4l2_buf.timestamp);
- vb->v4l2_buf.sequence++;
- vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
-
- if (list_empty(&pcdev->capture)) {
- buf = NULL;
- writel(0, pcdev->base_csi + fb_reg);
- } else {
- buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
- internal.queue);
- vb = &buf->vb;
- list_del(&buf->internal.queue);
- buf->state = MX2_STATE_ACTIVE;
- writel(vb2_dma_contig_plane_dma_addr(vb, 0),
- pcdev->base_csi + fb_reg);
- }
-
- *fb_active = buf;
-
-out:
- spin_unlock_irqrestore(&pcdev->lock, flags);
-}
-
-static irqreturn_t mx25_camera_irq(int irq_csi, void *data)
-{
- struct mx2_camera_dev *pcdev = data;
- u32 status = readl(pcdev->base_csi + CSISR);
-
- if (status & CSISR_DMA_TSF_FB1_INT)
- mx25_camera_frame_done(pcdev, 1, MX2_STATE_DONE);
- else if (status & CSISR_DMA_TSF_FB2_INT)
- mx25_camera_frame_done(pcdev, 2, MX2_STATE_DONE);
-
- /* FIXME: handle CSISR_RFF_OR_INT */
-
- writel(status, pcdev->base_csi + CSISR);
-
- return IRQ_HANDLED;
-}
-
-/*
- * Videobuf operations
- */
-static int mx2_videobuf_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
- unsigned int *count, unsigned int *num_planes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx2_camera_dev *pcdev = ici->priv;
-
- dev_dbg(icd->parent, "count=%d, size=%d\n", *count, sizes[0]);
-
- /* TODO: support for VIDIOC_CREATE_BUFS not ready */
- if (fmt != NULL)
- return -ENOTTY;
-
- alloc_ctxs[0] = pcdev->alloc_ctx;
-
- sizes[0] = icd->sizeimage;
-
- if (0 == *count)
- *count = 32;
- if (!*num_planes &&
- sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024)
- *count = (MAX_VIDEO_MEM * 1024 * 1024) / sizes[0];
-
- *num_planes = 1;
-
- return 0;
-}
-
-static int mx2_videobuf_prepare(struct vb2_buffer *vb)
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
- int ret = 0;
-
- dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
- vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
-
-#ifdef DEBUG
- /*
- * This can be useful if you want to see if we actually fill
- * the buffer with something
- */
- memset((void *)vb2_plane_vaddr(vb, 0),
- 0xaa, vb2_get_plane_payload(vb, 0));
-#endif
-
- vb2_set_plane_payload(vb, 0, icd->sizeimage);
- if (vb2_plane_vaddr(vb, 0) &&
- vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
- ret = -EINVAL;
- goto out;
- }
-
- return 0;
-
-out:
- return ret;
-}
-
-static void mx2_videobuf_queue(struct vb2_buffer *vb)
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
- struct soc_camera_host *ici =
- to_soc_camera_host(icd->parent);
- struct mx2_camera_dev *pcdev = ici->priv;
- struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb);
- unsigned long flags;
-
- dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
- vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
-
- spin_lock_irqsave(&pcdev->lock, flags);
-
- buf->state = MX2_STATE_QUEUED;
- list_add_tail(&buf->internal.queue, &pcdev->capture);
-
- if (cpu_is_mx25()) {
- u32 csicr3, dma_inten = 0;
-
- if (pcdev->fb1_active == NULL) {
- writel(vb2_dma_contig_plane_dma_addr(vb, 0),
- pcdev->base_csi + CSIDMASA_FB1);
- pcdev->fb1_active = buf;
- dma_inten = CSICR1_FB1_DMA_INTEN;
- } else if (pcdev->fb2_active == NULL) {
- writel(vb2_dma_contig_plane_dma_addr(vb, 0),
- pcdev->base_csi + CSIDMASA_FB2);
- pcdev->fb2_active = buf;
- dma_inten = CSICR1_FB2_DMA_INTEN;
- }
-
- if (dma_inten) {
- list_del(&buf->internal.queue);
- buf->state = MX2_STATE_ACTIVE;
-
- csicr3 = readl(pcdev->base_csi + CSICR3);
-
- /* Reflash DMA */
- writel(csicr3 | CSICR3_DMA_REFLASH_RFF,
- pcdev->base_csi + CSICR3);
-
- /* clear & enable interrupts */
- writel(dma_inten, pcdev->base_csi + CSISR);
- pcdev->csicr1 |= dma_inten;
- writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
-
- /* enable DMA */
- csicr3 |= CSICR3_DMA_REQ_EN_RFF | CSICR3_RXFF_LEVEL(1);
- writel(csicr3, pcdev->base_csi + CSICR3);
- }
- }
-
- spin_unlock_irqrestore(&pcdev->lock, flags);
-}
-
-static void mx2_videobuf_release(struct vb2_buffer *vb)
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx2_camera_dev *pcdev = ici->priv;
- struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb);
- unsigned long flags;
-
-#ifdef DEBUG
- dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
- vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
-
- switch (buf->state) {
- case MX2_STATE_ACTIVE:
- dev_info(icd->parent, "%s (active)\n", __func__);
- break;
- case MX2_STATE_QUEUED:
- dev_info(icd->parent, "%s (queued)\n", __func__);
- break;
- default:
- dev_info(icd->parent, "%s (unknown) %d\n", __func__,
- buf->state);
- break;
- }
-#endif
-
- /*
- * Terminate only queued but inactive buffers. Active buffers are
- * released when they become inactive after videobuf_waiton().
- *
- * FIXME: implement forced termination of active buffers for mx27 and
- * mx27 eMMA, so that the user won't get stuck in an uninterruptible
- * state. This requires a specific handling for each of the these DMA
- * types.
- */
-
- spin_lock_irqsave(&pcdev->lock, flags);
- if (cpu_is_mx25() && buf->state == MX2_STATE_ACTIVE) {
- if (pcdev->fb1_active == buf) {
- pcdev->csicr1 &= ~CSICR1_FB1_DMA_INTEN;
- writel(0, pcdev->base_csi + CSIDMASA_FB1);
- pcdev->fb1_active = NULL;
- } else if (pcdev->fb2_active == buf) {
- pcdev->csicr1 &= ~CSICR1_FB2_DMA_INTEN;
- writel(0, pcdev->base_csi + CSIDMASA_FB2);
- pcdev->fb2_active = NULL;
- }
- writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
- }
- spin_unlock_irqrestore(&pcdev->lock, flags);
-}
-
-static void mx27_camera_emma_buf_init(struct soc_camera_device *icd,
- int bytesperline)
-{
- struct soc_camera_host *ici =
- to_soc_camera_host(icd->parent);
- struct mx2_camera_dev *pcdev = ici->priv;
- struct mx2_fmt_cfg *prp = pcdev->emma_prp;
-
- writel((pcdev->s_width << 16) | pcdev->s_height,
- pcdev->base_emma + PRP_SRC_FRAME_SIZE);
- writel(prp->cfg.src_pixel,
- pcdev->base_emma + PRP_SRC_PIXEL_FORMAT_CNTL);
- if (prp->cfg.channel == 1) {
- writel((icd->user_width << 16) | icd->user_height,
- pcdev->base_emma + PRP_CH1_OUT_IMAGE_SIZE);
- writel(bytesperline,
- pcdev->base_emma + PRP_DEST_CH1_LINE_STRIDE);
- writel(prp->cfg.ch1_pixel,
- pcdev->base_emma + PRP_CH1_PIXEL_FORMAT_CNTL);
- } else { /* channel 2 */
- writel((icd->user_width << 16) | icd->user_height,
- pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE);
- }
-
- /* Enable interrupts */
- writel(prp->cfg.irq_flags, pcdev->base_emma + PRP_INTR_CNTL);
-}
-
-static void mx2_prp_resize_commit(struct mx2_camera_dev *pcdev)
-{
- int dir;
-
- for (dir = RESIZE_DIR_H; dir <= RESIZE_DIR_V; dir++) {
- unsigned char *s = pcdev->resizing[dir].s;
- int len = pcdev->resizing[dir].len;
- unsigned int coeff[2] = {0, 0};
- unsigned int valid = 0;
- int i;
-
- if (len == 0)
- continue;
-
- for (i = RESIZE_NUM_MAX - 1; i >= 0; i--) {
- int j;
-
- j = i > 9 ? 1 : 0;
- coeff[j] = (coeff[j] << BC_COEF) |
- (s[i] & (SZ_COEF - 1));
-
- if (i == 5 || i == 15)
- coeff[j] <<= 1;
-
- valid = (valid << 1) | (s[i] >> BC_COEF);
- }
-
- valid |= PRP_RZ_VALID_TBL_LEN(len);
-
- if (pcdev->resizing[dir].algo == RESIZE_ALGO_BILINEAR)
- valid |= PRP_RZ_VALID_BILINEAR;
-
- if (pcdev->emma_prp->cfg.channel == 1) {
- if (dir == RESIZE_DIR_H) {
- writel(coeff[0], pcdev->base_emma +
- PRP_CH1_RZ_HORI_COEF1);
- writel(coeff[1], pcdev->base_emma +
- PRP_CH1_RZ_HORI_COEF2);
- writel(valid, pcdev->base_emma +
- PRP_CH1_RZ_HORI_VALID);
- } else {
- writel(coeff[0], pcdev->base_emma +
- PRP_CH1_RZ_VERT_COEF1);
- writel(coeff[1], pcdev->base_emma +
- PRP_CH1_RZ_VERT_COEF2);
- writel(valid, pcdev->base_emma +
- PRP_CH1_RZ_VERT_VALID);
- }
- } else {
- if (dir == RESIZE_DIR_H) {
- writel(coeff[0], pcdev->base_emma +
- PRP_CH2_RZ_HORI_COEF1);
- writel(coeff[1], pcdev->base_emma +
- PRP_CH2_RZ_HORI_COEF2);
- writel(valid, pcdev->base_emma +
- PRP_CH2_RZ_HORI_VALID);
- } else {
- writel(coeff[0], pcdev->base_emma +
- PRP_CH2_RZ_VERT_COEF1);
- writel(coeff[1], pcdev->base_emma +
- PRP_CH2_RZ_VERT_COEF2);
- writel(valid, pcdev->base_emma +
- PRP_CH2_RZ_VERT_VALID);
- }
- }
- }
-}
-
-static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(q);
- struct soc_camera_host *ici =
- to_soc_camera_host(icd->parent);
- struct mx2_camera_dev *pcdev = ici->priv;
- struct mx2_fmt_cfg *prp = pcdev->emma_prp;
- struct vb2_buffer *vb;
- struct mx2_buffer *buf;
- unsigned long phys;
- int bytesperline;
-
- if (cpu_is_mx27()) {
- unsigned long flags;
- if (count < 2)
- return -EINVAL;
-
- spin_lock_irqsave(&pcdev->lock, flags);
-
- buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
- internal.queue);
- buf->internal.bufnum = 0;
- vb = &buf->vb;
- buf->state = MX2_STATE_ACTIVE;
-
- phys = vb2_dma_contig_plane_dma_addr(vb, 0);
- mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum);
- list_move_tail(pcdev->capture.next, &pcdev->active_bufs);
-
- buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
- internal.queue);
- buf->internal.bufnum = 1;
- vb = &buf->vb;
- buf->state = MX2_STATE_ACTIVE;
-
- phys = vb2_dma_contig_plane_dma_addr(vb, 0);
- mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum);
- list_move_tail(pcdev->capture.next, &pcdev->active_bufs);
-
- bytesperline = soc_mbus_bytes_per_line(icd->user_width,
- icd->current_fmt->host_fmt);
- if (bytesperline < 0)
- return bytesperline;
-
- /*
- * I didn't manage to properly enable/disable the prp
- * on a per frame basis during running transfers,
- * thus we allocate a buffer here and use it to
- * discard frames when no buffer is available.
- * Feel free to work on this ;)
- */
- pcdev->discard_size = icd->user_height * bytesperline;
- pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev,
- pcdev->discard_size, &pcdev->discard_buffer_dma,
- GFP_KERNEL);
- if (!pcdev->discard_buffer)
- return -ENOMEM;
-
- pcdev->buf_discard[0].discard = true;
- list_add_tail(&pcdev->buf_discard[0].queue,
- &pcdev->discard);
-
- pcdev->buf_discard[1].discard = true;
- list_add_tail(&pcdev->buf_discard[1].queue,
- &pcdev->discard);
-
- mx2_prp_resize_commit(pcdev);
-
- mx27_camera_emma_buf_init(icd, bytesperline);
-
- if (prp->cfg.channel == 1) {
- writel(PRP_CNTL_CH1EN |
- PRP_CNTL_CSIEN |
- prp->cfg.in_fmt |
- prp->cfg.out_fmt |
- PRP_CNTL_CH1_LEN |
- PRP_CNTL_CH1BYP |
- PRP_CNTL_CH1_TSKIP(0) |
- PRP_CNTL_IN_TSKIP(0),
- pcdev->base_emma + PRP_CNTL);
- } else {
- writel(PRP_CNTL_CH2EN |
- PRP_CNTL_CSIEN |
- prp->cfg.in_fmt |
- prp->cfg.out_fmt |
- PRP_CNTL_CH2_LEN |
- PRP_CNTL_CH2_TSKIP(0) |
- PRP_CNTL_IN_TSKIP(0),
- pcdev->base_emma + PRP_CNTL);
- }
- spin_unlock_irqrestore(&pcdev->lock, flags);
- }
-
- return 0;
-}
-
-static int mx2_stop_streaming(struct vb2_queue *q)
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(q);
- struct soc_camera_host *ici =
- to_soc_camera_host(icd->parent);
- struct mx2_camera_dev *pcdev = ici->priv;
- struct mx2_fmt_cfg *prp = pcdev->emma_prp;
- unsigned long flags;
- void *b;
- u32 cntl;
-
- if (cpu_is_mx27()) {
- spin_lock_irqsave(&pcdev->lock, flags);
-
- cntl = readl(pcdev->base_emma + PRP_CNTL);
- if (prp->cfg.channel == 1) {
- writel(cntl & ~PRP_CNTL_CH1EN,
- pcdev->base_emma + PRP_CNTL);
- } else {
- writel(cntl & ~PRP_CNTL_CH2EN,
- pcdev->base_emma + PRP_CNTL);
- }
- INIT_LIST_HEAD(&pcdev->capture);
- INIT_LIST_HEAD(&pcdev->active_bufs);
- INIT_LIST_HEAD(&pcdev->discard);
-
- b = pcdev->discard_buffer;
- pcdev->discard_buffer = NULL;
-
- spin_unlock_irqrestore(&pcdev->lock, flags);
-
- dma_free_coherent(ici->v4l2_dev.dev,
- pcdev->discard_size, b, pcdev->discard_buffer_dma);
- }
-
- return 0;
-}
-
-static struct vb2_ops mx2_videobuf_ops = {
- .queue_setup = mx2_videobuf_setup,
- .buf_prepare = mx2_videobuf_prepare,
- .buf_queue = mx2_videobuf_queue,
- .buf_cleanup = mx2_videobuf_release,
- .start_streaming = mx2_start_streaming,
- .stop_streaming = mx2_stop_streaming,
-};
-
-static int mx2_camera_init_videobuf(struct vb2_queue *q,
- struct soc_camera_device *icd)
-{
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- q->io_modes = VB2_MMAP | VB2_USERPTR;
- q->drv_priv = icd;
- q->ops = &mx2_videobuf_ops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->buf_struct_size = sizeof(struct mx2_buffer);
-
- return vb2_queue_init(q);
-}
-
-#define MX2_BUS_FLAGS (V4L2_MBUS_MASTER | \
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
- V4L2_MBUS_VSYNC_ACTIVE_LOW | \
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
- V4L2_MBUS_HSYNC_ACTIVE_LOW | \
- V4L2_MBUS_PCLK_SAMPLE_RISING | \
- V4L2_MBUS_PCLK_SAMPLE_FALLING | \
- V4L2_MBUS_DATA_ACTIVE_HIGH | \
- V4L2_MBUS_DATA_ACTIVE_LOW)
-
-static int mx27_camera_emma_prp_reset(struct mx2_camera_dev *pcdev)
-{
- u32 cntl;
- int count = 0;
-
- cntl = readl(pcdev->base_emma + PRP_CNTL);
- writel(PRP_CNTL_SWRST, pcdev->base_emma + PRP_CNTL);
- while (count++ < 100) {
- if (!(readl(pcdev->base_emma + PRP_CNTL) & PRP_CNTL_SWRST))
- return 0;
- barrier();
- udelay(1);
- }
-
- return -ETIMEDOUT;
-}
-
-static int mx2_camera_set_bus_param(struct soc_camera_device *icd)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx2_camera_dev *pcdev = ici->priv;
- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
- unsigned long common_flags;
- int ret;
- int bytesperline;
- u32 csicr1 = pcdev->csicr1;
-
- ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
- if (!ret) {
- common_flags = soc_mbus_config_compatible(&cfg, MX2_BUS_FLAGS);
- if (!common_flags) {
- dev_warn(icd->parent,
- "Flags incompatible: camera 0x%x, host 0x%x\n",
- cfg.flags, MX2_BUS_FLAGS);
- return -EINVAL;
- }
- } else if (ret != -ENOIOCTLCMD) {
- return ret;
- } else {
- common_flags = MX2_BUS_FLAGS;
- }
-
- if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
- (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
- if (pcdev->platform_flags & MX2_CAMERA_HSYNC_HIGH)
- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
- else
- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
- }
-
- if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
- (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
- if (pcdev->platform_flags & MX2_CAMERA_PCLK_SAMPLE_RISING)
- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
- else
- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
- }
-
- cfg.flags = common_flags;
- ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
- if (ret < 0 && ret != -ENOIOCTLCMD) {
- dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
- common_flags, ret);
- return ret;
- }
-
- csicr1 = (csicr1 & ~CSICR1_FMT_MASK) | pcdev->emma_prp->cfg.csicr1;
-
- if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
- csicr1 |= CSICR1_REDGE;
- if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
- csicr1 |= CSICR1_SOF_POL;
- if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
- csicr1 |= CSICR1_HSYNC_POL;
- if (pcdev->platform_flags & MX2_CAMERA_EXT_VSYNC)
- csicr1 |= CSICR1_EXT_VSYNC;
- if (pcdev->platform_flags & MX2_CAMERA_CCIR)
- csicr1 |= CSICR1_CCIR_EN;
- if (pcdev->platform_flags & MX2_CAMERA_CCIR_INTERLACE)
- csicr1 |= CSICR1_CCIR_MODE;
- if (pcdev->platform_flags & MX2_CAMERA_GATED_CLOCK)
- csicr1 |= CSICR1_GCLK_MODE;
- if (pcdev->platform_flags & MX2_CAMERA_INV_DATA)
- csicr1 |= CSICR1_INV_DATA;
-
- pcdev->csicr1 = csicr1;
-
- bytesperline = soc_mbus_bytes_per_line(icd->user_width,
- icd->current_fmt->host_fmt);
- if (bytesperline < 0)
- return bytesperline;
-
- if (cpu_is_mx27()) {
- ret = mx27_camera_emma_prp_reset(pcdev);
- if (ret)
- return ret;
- } else if (cpu_is_mx25()) {
- writel((bytesperline * icd->user_height) >> 2,
- pcdev->base_csi + CSIRXCNT);
- writel((bytesperline << 16) | icd->user_height,
- pcdev->base_csi + CSIIMAG_PARA);
- }
-
- writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
-
- return 0;
-}
-
-static int mx2_camera_set_crop(struct soc_camera_device *icd,
- struct v4l2_crop *a)
-{
- struct v4l2_rect *rect = &a->c;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct v4l2_mbus_framefmt mf;
- int ret;
-
- soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096);
- soc_camera_limit_side(&rect->top, &rect->height, 0, 2, 4096);
-
- ret = v4l2_subdev_call(sd, video, s_crop, a);
- if (ret < 0)
- return ret;
-
- /* The capture device might have changed its output */
- ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- dev_dbg(icd->parent, "Sensor cropped %dx%d\n",
- mf.width, mf.height);
-
- icd->user_width = mf.width;
- icd->user_height = mf.height;
-
- return ret;
-}
-
-static int mx2_camera_get_formats(struct soc_camera_device *icd,
- unsigned int idx,
- struct soc_camera_format_xlate *xlate)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_mbus_pixelfmt *fmt;
- struct device *dev = icd->parent;
- enum v4l2_mbus_pixelcode code;
- int ret, formats = 0;
-
- ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
- if (ret < 0)
- /* no more formats */
- return 0;
-
- fmt = soc_mbus_get_fmtdesc(code);
- if (!fmt) {
- dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
- return 0;
- }
-
- if (code == V4L2_MBUS_FMT_YUYV8_2X8 ||
- code == V4L2_MBUS_FMT_UYVY8_2X8) {
- formats++;
- if (xlate) {
- /*
- * CH2 can output YUV420 which is a standard format in
- * soc_mediabus.c
- */
- xlate->host_fmt =
- soc_mbus_get_fmtdesc(V4L2_MBUS_FMT_YUYV8_1_5X8);
- xlate->code = code;
- dev_dbg(dev, "Providing host format %s for sensor code %d\n",
- xlate->host_fmt->name, code);
- xlate++;
- }
- }
-
- /* Generic pass-trough */
- formats++;
- if (xlate) {
- xlate->host_fmt = fmt;
- xlate->code = code;
- xlate++;
- }
- return formats;
-}
-
-static int mx2_emmaprp_resize(struct mx2_camera_dev *pcdev,
- struct v4l2_mbus_framefmt *mf_in,
- struct v4l2_pix_format *pix_out, bool apply)
-{
- int num, den;
- unsigned long m;
- int i, dir;
-
- for (dir = RESIZE_DIR_H; dir <= RESIZE_DIR_V; dir++) {
- struct emma_prp_resize tmprsz;
- unsigned char *s = tmprsz.s;
- int len = 0;
- int in, out;
-
- if (dir == RESIZE_DIR_H) {
- in = mf_in->width;
- out = pix_out->width;
- } else {
- in = mf_in->height;
- out = pix_out->height;
- }
-
- if (in < out)
- return -EINVAL;
- else if (in == out)
- continue;
-
- /* Calculate ratio */
- m = gcd(in, out);
- num = in / m;
- den = out / m;
- if (num > RESIZE_NUM_MAX)
- return -EINVAL;
-
- if ((num >= 2 * den) && (den == 1) &&
- (num < 9) && (!(num & 0x01))) {
- int sum = 0;
- int j;
-
- /* Average scaling for >= 2:1 ratios */
- /* Support can be added for num >=9 and odd values */
-
- tmprsz.algo = RESIZE_ALGO_AVERAGING;
- len = num;
-
- for (i = 0; i < (len / 2); i++)
- s[i] = 8;
-
- do {
- for (i = 0; i < (len / 2); i++) {
- s[i] = s[i] >> 1;
- sum = 0;
- for (j = 0; j < (len / 2); j++)
- sum += s[j];
- if (sum == 4)
- break;
- }
- } while (sum != 4);
-
- for (i = (len / 2); i < len; i++)
- s[i] = s[len - i - 1];
-
- s[len - 1] |= SZ_COEF;
- } else {
- /* bilinear scaling for < 2:1 ratios */
- int v; /* overflow counter */
- int coeff, nxt; /* table output */
- int in_pos_inc = 2 * den;
- int out_pos = num;
- int out_pos_inc = 2 * num;
- int init_carry = num - den;
- int carry = init_carry;
-
- tmprsz.algo = RESIZE_ALGO_BILINEAR;
- v = den + in_pos_inc;
- do {
- coeff = v - out_pos;
- out_pos += out_pos_inc;
- carry += out_pos_inc;
- for (nxt = 0; v < out_pos; nxt++) {
- v += in_pos_inc;
- carry -= in_pos_inc;
- }
-
- if (len > RESIZE_NUM_MAX)
- return -EINVAL;
-
- coeff = ((coeff << BC_COEF) +
- (in_pos_inc >> 1)) / in_pos_inc;
-
- if (coeff >= (SZ_COEF - 1))
- coeff--;
-
- coeff |= SZ_COEF;
- s[len] = (unsigned char)coeff;
- len++;
-
- for (i = 1; i < nxt; i++) {
- if (len >= RESIZE_NUM_MAX)
- return -EINVAL;
- s[len] = 0;
- len++;
- }
- } while (carry != init_carry);
- }
- tmprsz.len = len;
- if (dir == RESIZE_DIR_H)
- mf_in->width = pix_out->width;
- else
- mf_in->height = pix_out->height;
-
- if (apply)
- memcpy(&pcdev->resizing[dir], &tmprsz, sizeof(tmprsz));
- }
- return 0;
-}
-
-static int mx2_camera_set_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx2_camera_dev *pcdev = ici->priv;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- int ret;
-
- dev_dbg(icd->parent, "%s: requested params: width = %d, height = %d\n",
- __func__, pix->width, pix->height);
-
- xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
- if (!xlate) {
- dev_warn(icd->parent, "Format %x not found\n",
- pix->pixelformat);
- return -EINVAL;
- }
-
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return ret;
-
- /* Store width and height returned by the sensor for resizing */
- pcdev->s_width = mf.width;
- pcdev->s_height = mf.height;
- dev_dbg(icd->parent, "%s: sensor params: width = %d, height = %d\n",
- __func__, pcdev->s_width, pcdev->s_height);
-
- pcdev->emma_prp = mx27_emma_prp_get_format(xlate->code,
- xlate->host_fmt->fourcc);
-
- memset(pcdev->resizing, 0, sizeof(pcdev->resizing));
- if ((mf.width != pix->width || mf.height != pix->height) &&
- pcdev->emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) {
- if (mx2_emmaprp_resize(pcdev, &mf, pix, true) < 0)
- dev_dbg(icd->parent, "%s: can't resize\n", __func__);
- }
-
- if (mf.code != xlate->code)
- return -EINVAL;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
- icd->current_fmt = xlate;
-
- dev_dbg(icd->parent, "%s: returned params: width = %d, height = %d\n",
- __func__, pix->width, pix->height);
-
- return 0;
-}
-
-static int mx2_camera_try_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- __u32 pixfmt = pix->pixelformat;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx2_camera_dev *pcdev = ici->priv;
- unsigned int width_limit;
- int ret;
-
- dev_dbg(icd->parent, "%s: requested params: width = %d, height = %d\n",
- __func__, pix->width, pix->height);
-
- xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
- if (pixfmt && !xlate) {
- dev_warn(icd->parent, "Format %x not found\n", pixfmt);
- return -EINVAL;
- }
-
- /* FIXME: implement MX27 limits */
-
- /* limit to MX25 hardware capabilities */
- if (cpu_is_mx25()) {
- if (xlate->host_fmt->bits_per_sample <= 8)
- width_limit = 0xffff * 4;
- else
- width_limit = 0xffff * 2;
- /* CSIIMAG_PARA limit */
- if (pix->width > width_limit)
- pix->width = width_limit;
- if (pix->height > 0xffff)
- pix->height = 0xffff;
-
- pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
- xlate->host_fmt);
- if (pix->bytesperline < 0)
- return pix->bytesperline;
- pix->sizeimage = soc_mbus_image_size(xlate->host_fmt,
- pix->bytesperline, pix->height);
- /* Check against the CSIRXCNT limit */
- if (pix->sizeimage > 4 * 0x3ffff) {
- /* Adjust geometry, preserve aspect ratio */
- unsigned int new_height = int_sqrt(div_u64(0x3ffffULL *
- 4 * pix->height, pix->bytesperline));
- pix->width = new_height * pix->width / pix->height;
- pix->height = new_height;
- pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
- xlate->host_fmt);
- BUG_ON(pix->bytesperline < 0);
- pix->sizeimage = soc_mbus_image_size(xlate->host_fmt,
- pix->bytesperline, pix->height);
- }
- }
-
- /* limit to sensor capabilities */
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- dev_dbg(icd->parent, "%s: sensor params: width = %d, height = %d\n",
- __func__, pcdev->s_width, pcdev->s_height);
-
- /* If the sensor does not support image size try PrP resizing */
- pcdev->emma_prp = mx27_emma_prp_get_format(xlate->code,
- xlate->host_fmt->fourcc);
-
- memset(pcdev->resizing, 0, sizeof(pcdev->resizing));
- if ((mf.width != pix->width || mf.height != pix->height) &&
- pcdev->emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) {
- if (mx2_emmaprp_resize(pcdev, &mf, pix, false) < 0)
- dev_dbg(icd->parent, "%s: can't resize\n", __func__);
- }
-
- if (mf.field == V4L2_FIELD_ANY)
- mf.field = V4L2_FIELD_NONE;
- /*
- * Driver supports interlaced images provided they have
- * both fields so that they can be processed as if they
- * were progressive.
- */
- if (mf.field != V4L2_FIELD_NONE && !V4L2_FIELD_HAS_BOTH(mf.field)) {
- dev_err(icd->parent, "Field type %d unsupported.\n",
- mf.field);
- return -EINVAL;
- }
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
-
- dev_dbg(icd->parent, "%s: returned params: width = %d, height = %d\n",
- __func__, pix->width, pix->height);
-
- return 0;
-}
-
-static int mx2_camera_querycap(struct soc_camera_host *ici,
- struct v4l2_capability *cap)
-{
- /* cap->name is set by the friendly caller:-> */
- strlcpy(cap->card, MX2_CAM_DRIVER_DESCRIPTION, sizeof(cap->card));
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-
- return 0;
-}
-
-static unsigned int mx2_camera_poll(struct file *file, poll_table *pt)
-{
- struct soc_camera_device *icd = file->private_data;
-
- return vb2_poll(&icd->vb2_vidq, file, pt);
-}
-
-static struct soc_camera_host_ops mx2_soc_camera_host_ops = {
- .owner = THIS_MODULE,
- .add = mx2_camera_add_device,
- .remove = mx2_camera_remove_device,
- .set_fmt = mx2_camera_set_fmt,
- .set_crop = mx2_camera_set_crop,
- .get_formats = mx2_camera_get_formats,
- .try_fmt = mx2_camera_try_fmt,
- .init_videobuf2 = mx2_camera_init_videobuf,
- .poll = mx2_camera_poll,
- .querycap = mx2_camera_querycap,
- .set_bus_param = mx2_camera_set_bus_param,
-};
-
-static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev,
- int bufnum, bool err)
-{
-#ifdef DEBUG
- struct mx2_fmt_cfg *prp = pcdev->emma_prp;
-#endif
- struct mx2_buf_internal *ibuf;
- struct mx2_buffer *buf;
- struct vb2_buffer *vb;
- unsigned long phys;
-
- ibuf = list_first_entry(&pcdev->active_bufs, struct mx2_buf_internal,
- queue);
-
- BUG_ON(ibuf->bufnum != bufnum);
-
- if (ibuf->discard) {
- /*
- * Discard buffer must not be returned to user space.
- * Just return it to the discard queue.
- */
- list_move_tail(pcdev->active_bufs.next, &pcdev->discard);
- } else {
- buf = mx2_ibuf_to_buf(ibuf);
-
- vb = &buf->vb;
-#ifdef DEBUG
- phys = vb2_dma_contig_plane_dma_addr(vb, 0);
- if (prp->cfg.channel == 1) {
- if (readl(pcdev->base_emma + PRP_DEST_RGB1_PTR +
- 4 * bufnum) != phys) {
- dev_err(pcdev->dev, "%lx != %x\n", phys,
- readl(pcdev->base_emma +
- PRP_DEST_RGB1_PTR + 4 * bufnum));
- }
- } else {
- if (readl(pcdev->base_emma + PRP_DEST_Y_PTR -
- 0x14 * bufnum) != phys) {
- dev_err(pcdev->dev, "%lx != %x\n", phys,
- readl(pcdev->base_emma +
- PRP_DEST_Y_PTR - 0x14 * bufnum));
- }
- }
-#endif
- dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__, vb,
- vb2_plane_vaddr(vb, 0),
- vb2_get_plane_payload(vb, 0));
-
- list_del_init(&buf->internal.queue);
- do_gettimeofday(&vb->v4l2_buf.timestamp);
- vb->v4l2_buf.sequence = pcdev->frame_count;
- if (err)
- vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
- else
- vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
- }
-
- pcdev->frame_count++;
-
- if (list_empty(&pcdev->capture)) {
- if (list_empty(&pcdev->discard)) {
- dev_warn(pcdev->dev, "%s: trying to access empty discard list\n",
- __func__);
- return;
- }
-
- ibuf = list_first_entry(&pcdev->discard,
- struct mx2_buf_internal, queue);
- ibuf->bufnum = bufnum;
-
- list_move_tail(pcdev->discard.next, &pcdev->active_bufs);
- mx27_update_emma_buf(pcdev, pcdev->discard_buffer_dma, bufnum);
- return;
- }
-
- buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
- internal.queue);
-
- buf->internal.bufnum = bufnum;
-
- list_move_tail(pcdev->capture.next, &pcdev->active_bufs);
-
- vb = &buf->vb;
- buf->state = MX2_STATE_ACTIVE;
-
- phys = vb2_dma_contig_plane_dma_addr(vb, 0);
- mx27_update_emma_buf(pcdev, phys, bufnum);
-}
-
-static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data)
-{
- struct mx2_camera_dev *pcdev = data;
- unsigned int status = readl(pcdev->base_emma + PRP_INTRSTATUS);
- struct mx2_buf_internal *ibuf;
-
- spin_lock(&pcdev->lock);
-
- if (list_empty(&pcdev->active_bufs)) {
- dev_warn(pcdev->dev, "%s: called while active list is empty\n",
- __func__);
-
- if (!status) {
- spin_unlock(&pcdev->lock);
- return IRQ_NONE;
- }
- }
-
- if (status & (1 << 7)) { /* overflow */
- u32 cntl = readl(pcdev->base_emma + PRP_CNTL);
- writel(cntl & ~(PRP_CNTL_CH1EN | PRP_CNTL_CH2EN),
- pcdev->base_emma + PRP_CNTL);
- writel(cntl, pcdev->base_emma + PRP_CNTL);
-
- ibuf = list_first_entry(&pcdev->active_bufs,
- struct mx2_buf_internal, queue);
- mx27_camera_frame_done_emma(pcdev,
- ibuf->bufnum, true);
-
- status &= ~(1 << 7);
- } else if (((status & (3 << 5)) == (3 << 5)) ||
- ((status & (3 << 3)) == (3 << 3))) {
- /*
- * Both buffers have triggered, process the one we're expecting
- * to first
- */
- ibuf = list_first_entry(&pcdev->active_bufs,
- struct mx2_buf_internal, queue);
- mx27_camera_frame_done_emma(pcdev, ibuf->bufnum, false);
- status &= ~(1 << (6 - ibuf->bufnum)); /* mark processed */
- } else if ((status & (1 << 6)) || (status & (1 << 4))) {
- mx27_camera_frame_done_emma(pcdev, 0, false);
- } else if ((status & (1 << 5)) || (status & (1 << 3))) {
- mx27_camera_frame_done_emma(pcdev, 1, false);
- }
-
- spin_unlock(&pcdev->lock);
- writel(status, pcdev->base_emma + PRP_INTRSTATUS);
-
- return IRQ_HANDLED;
-}
-
-static int __devinit mx27_camera_emma_init(struct mx2_camera_dev *pcdev)
-{
- struct resource *res_emma = pcdev->res_emma;
- int err = 0;
-
- if (!request_mem_region(res_emma->start, resource_size(res_emma),
- MX2_CAM_DRV_NAME)) {
- err = -EBUSY;
- goto out;
- }
-
- pcdev->base_emma = ioremap(res_emma->start, resource_size(res_emma));
- if (!pcdev->base_emma) {
- err = -ENOMEM;
- goto exit_release;
- }
-
- err = request_irq(pcdev->irq_emma, mx27_camera_emma_irq, 0,
- MX2_CAM_DRV_NAME, pcdev);
- if (err) {
- dev_err(pcdev->dev, "Camera EMMA interrupt register failed \n");
- goto exit_iounmap;
- }
-
- pcdev->clk_emma_ipg = clk_get(pcdev->dev, "emma-ipg");
- if (IS_ERR(pcdev->clk_emma_ipg)) {
- err = PTR_ERR(pcdev->clk_emma_ipg);
- goto exit_free_irq;
- }
-
- clk_prepare_enable(pcdev->clk_emma_ipg);
-
- pcdev->clk_emma_ahb = clk_get(pcdev->dev, "emma-ahb");
- if (IS_ERR(pcdev->clk_emma_ahb)) {
- err = PTR_ERR(pcdev->clk_emma_ahb);
- goto exit_clk_emma_ipg_put;
- }
-
- clk_prepare_enable(pcdev->clk_emma_ahb);
-
- err = mx27_camera_emma_prp_reset(pcdev);
- if (err)
- goto exit_clk_emma_ahb_put;
-
- return err;
-
-exit_clk_emma_ahb_put:
- clk_disable_unprepare(pcdev->clk_emma_ahb);
- clk_put(pcdev->clk_emma_ahb);
-exit_clk_emma_ipg_put:
- clk_disable_unprepare(pcdev->clk_emma_ipg);
- clk_put(pcdev->clk_emma_ipg);
-exit_free_irq:
- free_irq(pcdev->irq_emma, pcdev);
-exit_iounmap:
- iounmap(pcdev->base_emma);
-exit_release:
- release_mem_region(res_emma->start, resource_size(res_emma));
-out:
- return err;
-}
-
-static int __devinit mx2_camera_probe(struct platform_device *pdev)
-{
- struct mx2_camera_dev *pcdev;
- struct resource *res_csi, *res_emma;
- void __iomem *base_csi;
- int irq_csi, irq_emma;
- int err = 0;
-
- dev_dbg(&pdev->dev, "initialising\n");
-
- res_csi = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- irq_csi = platform_get_irq(pdev, 0);
- if (res_csi == NULL || irq_csi < 0) {
- dev_err(&pdev->dev, "Missing platform resources data\n");
- err = -ENODEV;
- goto exit;
- }
-
- pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
- if (!pcdev) {
- dev_err(&pdev->dev, "Could not allocate pcdev\n");
- err = -ENOMEM;
- goto exit;
- }
-
- pcdev->clk_csi = clk_get(&pdev->dev, "ahb");
- if (IS_ERR(pcdev->clk_csi)) {
- dev_err(&pdev->dev, "Could not get csi clock\n");
- err = PTR_ERR(pcdev->clk_csi);
- goto exit_kfree;
- }
-
- pcdev->res_csi = res_csi;
- pcdev->pdata = pdev->dev.platform_data;
- if (pcdev->pdata) {
- long rate;
-
- pcdev->platform_flags = pcdev->pdata->flags;
-
- rate = clk_round_rate(pcdev->clk_csi, pcdev->pdata->clk * 2);
- if (rate <= 0) {
- err = -ENODEV;
- goto exit_dma_free;
- }
- err = clk_set_rate(pcdev->clk_csi, rate);
- if (err < 0)
- goto exit_dma_free;
- }
-
- INIT_LIST_HEAD(&pcdev->capture);
- INIT_LIST_HEAD(&pcdev->active_bufs);
- INIT_LIST_HEAD(&pcdev->discard);
- spin_lock_init(&pcdev->lock);
-
- /*
- * Request the regions.
- */
- if (!request_mem_region(res_csi->start, resource_size(res_csi),
- MX2_CAM_DRV_NAME)) {
- err = -EBUSY;
- goto exit_dma_free;
- }
-
- base_csi = ioremap(res_csi->start, resource_size(res_csi));
- if (!base_csi) {
- err = -ENOMEM;
- goto exit_release;
- }
- pcdev->irq_csi = irq_csi;
- pcdev->base_csi = base_csi;
- pcdev->base_dma = res_csi->start;
- pcdev->dev = &pdev->dev;
-
- if (cpu_is_mx25()) {
- err = request_irq(pcdev->irq_csi, mx25_camera_irq, 0,
- MX2_CAM_DRV_NAME, pcdev);
- if (err) {
- dev_err(pcdev->dev, "Camera interrupt register failed \n");
- goto exit_iounmap;
- }
- }
-
- if (cpu_is_mx27()) {
- /* EMMA support */
- res_emma = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- irq_emma = platform_get_irq(pdev, 1);
-
- if (!res_emma || !irq_emma) {
- dev_err(&pdev->dev, "no EMMA resources\n");
- goto exit_free_irq;
- }
-
- pcdev->res_emma = res_emma;
- pcdev->irq_emma = irq_emma;
- if (mx27_camera_emma_init(pcdev))
- goto exit_free_irq;
- }
-
- pcdev->soc_host.drv_name = MX2_CAM_DRV_NAME,
- pcdev->soc_host.ops = &mx2_soc_camera_host_ops,
- pcdev->soc_host.priv = pcdev;
- pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
- pcdev->soc_host.nr = pdev->id;
- if (cpu_is_mx25())
- pcdev->soc_host.capabilities = SOCAM_HOST_CAP_STRIDE;
-
- pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
- if (IS_ERR(pcdev->alloc_ctx)) {
- err = PTR_ERR(pcdev->alloc_ctx);
- goto eallocctx;
- }
- err = soc_camera_host_register(&pcdev->soc_host);
- if (err)
- goto exit_free_emma;
-
- dev_info(&pdev->dev, "MX2 Camera (CSI) driver probed, clock frequency: %ld\n",
- clk_get_rate(pcdev->clk_csi));
-
- return 0;
-
-exit_free_emma:
- vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
-eallocctx:
- if (cpu_is_mx27()) {
- free_irq(pcdev->irq_emma, pcdev);
- clk_disable_unprepare(pcdev->clk_emma_ipg);
- clk_put(pcdev->clk_emma_ipg);
- clk_disable_unprepare(pcdev->clk_emma_ahb);
- clk_put(pcdev->clk_emma_ahb);
- iounmap(pcdev->base_emma);
- release_mem_region(pcdev->res_emma->start, resource_size(pcdev->res_emma));
- }
-exit_free_irq:
- if (cpu_is_mx25())
- free_irq(pcdev->irq_csi, pcdev);
-exit_iounmap:
- iounmap(base_csi);
-exit_release:
- release_mem_region(res_csi->start, resource_size(res_csi));
-exit_dma_free:
- clk_put(pcdev->clk_csi);
-exit_kfree:
- kfree(pcdev);
-exit:
- return err;
-}
-
-static int __devexit mx2_camera_remove(struct platform_device *pdev)
-{
- struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
- struct mx2_camera_dev *pcdev = container_of(soc_host,
- struct mx2_camera_dev, soc_host);
- struct resource *res;
-
- clk_put(pcdev->clk_csi);
- if (cpu_is_mx25())
- free_irq(pcdev->irq_csi, pcdev);
- if (cpu_is_mx27())
- free_irq(pcdev->irq_emma, pcdev);
-
- soc_camera_host_unregister(&pcdev->soc_host);
-
- vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
-
- iounmap(pcdev->base_csi);
-
- if (cpu_is_mx27()) {
- clk_disable_unprepare(pcdev->clk_emma_ipg);
- clk_put(pcdev->clk_emma_ipg);
- clk_disable_unprepare(pcdev->clk_emma_ahb);
- clk_put(pcdev->clk_emma_ahb);
- iounmap(pcdev->base_emma);
- res = pcdev->res_emma;
- release_mem_region(res->start, resource_size(res));
- }
-
- res = pcdev->res_csi;
- release_mem_region(res->start, resource_size(res));
-
- kfree(pcdev);
-
- dev_info(&pdev->dev, "MX2 Camera driver unloaded\n");
-
- return 0;
-}
-
-static struct platform_driver mx2_camera_driver = {
- .driver = {
- .name = MX2_CAM_DRV_NAME,
- },
- .remove = __devexit_p(mx2_camera_remove),
-};
-
-
-static int __init mx2_camera_init(void)
-{
- return platform_driver_probe(&mx2_camera_driver, &mx2_camera_probe);
-}
-
-static void __exit mx2_camera_exit(void)
-{
- return platform_driver_unregister(&mx2_camera_driver);
-}
-
-module_init(mx2_camera_init);
-module_exit(mx2_camera_exit);
-
-MODULE_DESCRIPTION("i.MX27/i.MX25 SoC Camera Host driver");
-MODULE_AUTHOR("Sascha Hauer <sha@pengutronix.de>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(MX2_CAM_VERSION);
diff --git a/drivers/media/video/mx2_emmaprp.c b/drivers/media/video/mx2_emmaprp.c
deleted file mode 100644
index 5f8a6f5b98f..00000000000
--- a/drivers/media/video/mx2_emmaprp.c
+++ /dev/null
@@ -1,1016 +0,0 @@
-/*
- * Support eMMa-PrP through mem2mem framework.
- *
- * eMMa-PrP is a piece of HW that allows fetching buffers
- * from one memory location and do several operations on
- * them such as scaling or format conversion giving, as a result
- * a new processed buffer in another memory location.
- *
- * Based on mem2mem_testdev.c by Pawel Osciak.
- *
- * Copyright (c) 2011 Vista Silicon S.L.
- * Javier Martin <javier.martin@vista-silicon.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version
- */
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-
-#include <linux/platform_device.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-dma-contig.h>
-#include <asm/sizes.h>
-
-#define EMMAPRP_MODULE_NAME "mem2mem-emmaprp"
-
-MODULE_DESCRIPTION("Mem-to-mem device which supports eMMa-PrP present in mx2 SoCs");
-MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.1");
-
-static bool debug;
-module_param(debug, bool, 0644);
-
-#define MIN_W 32
-#define MIN_H 32
-#define MAX_W 2040
-#define MAX_H 2046
-
-#define S_ALIGN 1 /* multiple of 2 */
-#define W_ALIGN_YUV420 3 /* multiple of 8 */
-#define W_ALIGN_OTHERS 2 /* multiple of 4 */
-#define H_ALIGN 1 /* multiple of 2 */
-
-/* Flags that indicate a format can be used for capture/output */
-#define MEM2MEM_CAPTURE (1 << 0)
-#define MEM2MEM_OUTPUT (1 << 1)
-
-#define MEM2MEM_NAME "m2m-emmaprp"
-
-/* In bytes, per queue */
-#define MEM2MEM_VID_MEM_LIMIT SZ_16M
-
-#define dprintk(dev, fmt, arg...) \
- v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
-
-/* EMMA PrP */
-#define PRP_CNTL 0x00
-#define PRP_INTR_CNTL 0x04
-#define PRP_INTRSTATUS 0x08
-#define PRP_SOURCE_Y_PTR 0x0c
-#define PRP_SOURCE_CB_PTR 0x10
-#define PRP_SOURCE_CR_PTR 0x14
-#define PRP_DEST_RGB1_PTR 0x18
-#define PRP_DEST_RGB2_PTR 0x1c
-#define PRP_DEST_Y_PTR 0x20
-#define PRP_DEST_CB_PTR 0x24
-#define PRP_DEST_CR_PTR 0x28
-#define PRP_SRC_FRAME_SIZE 0x2c
-#define PRP_DEST_CH1_LINE_STRIDE 0x30
-#define PRP_SRC_PIXEL_FORMAT_CNTL 0x34
-#define PRP_CH1_PIXEL_FORMAT_CNTL 0x38
-#define PRP_CH1_OUT_IMAGE_SIZE 0x3c
-#define PRP_CH2_OUT_IMAGE_SIZE 0x40
-#define PRP_SRC_LINE_STRIDE 0x44
-#define PRP_CSC_COEF_012 0x48
-#define PRP_CSC_COEF_345 0x4c
-#define PRP_CSC_COEF_678 0x50
-#define PRP_CH1_RZ_HORI_COEF1 0x54
-#define PRP_CH1_RZ_HORI_COEF2 0x58
-#define PRP_CH1_RZ_HORI_VALID 0x5c
-#define PRP_CH1_RZ_VERT_COEF1 0x60
-#define PRP_CH1_RZ_VERT_COEF2 0x64
-#define PRP_CH1_RZ_VERT_VALID 0x68
-#define PRP_CH2_RZ_HORI_COEF1 0x6c
-#define PRP_CH2_RZ_HORI_COEF2 0x70
-#define PRP_CH2_RZ_HORI_VALID 0x74
-#define PRP_CH2_RZ_VERT_COEF1 0x78
-#define PRP_CH2_RZ_VERT_COEF2 0x7c
-#define PRP_CH2_RZ_VERT_VALID 0x80
-
-#define PRP_CNTL_CH1EN (1 << 0)
-#define PRP_CNTL_CH2EN (1 << 1)
-#define PRP_CNTL_CSIEN (1 << 2)
-#define PRP_CNTL_DATA_IN_YUV420 (0 << 3)
-#define PRP_CNTL_DATA_IN_YUV422 (1 << 3)
-#define PRP_CNTL_DATA_IN_RGB16 (2 << 3)
-#define PRP_CNTL_DATA_IN_RGB32 (3 << 3)
-#define PRP_CNTL_CH1_OUT_RGB8 (0 << 5)
-#define PRP_CNTL_CH1_OUT_RGB16 (1 << 5)
-#define PRP_CNTL_CH1_OUT_RGB32 (2 << 5)
-#define PRP_CNTL_CH1_OUT_YUV422 (3 << 5)
-#define PRP_CNTL_CH2_OUT_YUV420 (0 << 7)
-#define PRP_CNTL_CH2_OUT_YUV422 (1 << 7)
-#define PRP_CNTL_CH2_OUT_YUV444 (2 << 7)
-#define PRP_CNTL_CH1_LEN (1 << 9)
-#define PRP_CNTL_CH2_LEN (1 << 10)
-#define PRP_CNTL_SKIP_FRAME (1 << 11)
-#define PRP_CNTL_SWRST (1 << 12)
-#define PRP_CNTL_CLKEN (1 << 13)
-#define PRP_CNTL_WEN (1 << 14)
-#define PRP_CNTL_CH1BYP (1 << 15)
-#define PRP_CNTL_IN_TSKIP(x) ((x) << 16)
-#define PRP_CNTL_CH1_TSKIP(x) ((x) << 19)
-#define PRP_CNTL_CH2_TSKIP(x) ((x) << 22)
-#define PRP_CNTL_INPUT_FIFO_LEVEL(x) ((x) << 25)
-#define PRP_CNTL_RZ_FIFO_LEVEL(x) ((x) << 27)
-#define PRP_CNTL_CH2B1EN (1 << 29)
-#define PRP_CNTL_CH2B2EN (1 << 30)
-#define PRP_CNTL_CH2FEN (1 << 31)
-
-#define PRP_SIZE_HEIGHT(x) (x)
-#define PRP_SIZE_WIDTH(x) ((x) << 16)
-
-/* IRQ Enable and status register */
-#define PRP_INTR_RDERR (1 << 0)
-#define PRP_INTR_CH1WERR (1 << 1)
-#define PRP_INTR_CH2WERR (1 << 2)
-#define PRP_INTR_CH1FC (1 << 3)
-#define PRP_INTR_CH2FC (1 << 5)
-#define PRP_INTR_LBOVF (1 << 7)
-#define PRP_INTR_CH2OVF (1 << 8)
-
-#define PRP_INTR_ST_RDERR (1 << 0)
-#define PRP_INTR_ST_CH1WERR (1 << 1)
-#define PRP_INTR_ST_CH2WERR (1 << 2)
-#define PRP_INTR_ST_CH2B2CI (1 << 3)
-#define PRP_INTR_ST_CH2B1CI (1 << 4)
-#define PRP_INTR_ST_CH1B2CI (1 << 5)
-#define PRP_INTR_ST_CH1B1CI (1 << 6)
-#define PRP_INTR_ST_LBOVF (1 << 7)
-#define PRP_INTR_ST_CH2OVF (1 << 8)
-
-struct emmaprp_fmt {
- char *name;
- u32 fourcc;
- /* Types the format can be used for */
- u32 types;
-};
-
-static struct emmaprp_fmt formats[] = {
- {
- .name = "YUV 4:2:0 Planar",
- .fourcc = V4L2_PIX_FMT_YUV420,
- .types = MEM2MEM_CAPTURE,
- },
- {
- .name = "4:2:2, packed, YUYV",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .types = MEM2MEM_OUTPUT,
- },
-};
-
-/* Per-queue, driver-specific private data */
-struct emmaprp_q_data {
- unsigned int width;
- unsigned int height;
- unsigned int sizeimage;
- struct emmaprp_fmt *fmt;
-};
-
-enum {
- V4L2_M2M_SRC = 0,
- V4L2_M2M_DST = 1,
-};
-
-#define NUM_FORMATS ARRAY_SIZE(formats)
-
-static struct emmaprp_fmt *find_format(struct v4l2_format *f)
-{
- struct emmaprp_fmt *fmt;
- unsigned int k;
-
- for (k = 0; k < NUM_FORMATS; k++) {
- fmt = &formats[k];
- if (fmt->fourcc == f->fmt.pix.pixelformat)
- break;
- }
-
- if (k == NUM_FORMATS)
- return NULL;
-
- return &formats[k];
-}
-
-struct emmaprp_dev {
- struct v4l2_device v4l2_dev;
- struct video_device *vfd;
-
- struct mutex dev_mutex;
- spinlock_t irqlock;
-
- int irq_emma;
- void __iomem *base_emma;
- struct clk *clk_emma;
- struct resource *res_emma;
-
- struct v4l2_m2m_dev *m2m_dev;
- struct vb2_alloc_ctx *alloc_ctx;
-};
-
-struct emmaprp_ctx {
- struct emmaprp_dev *dev;
- /* Abort requested by m2m */
- int aborting;
- struct emmaprp_q_data q_data[2];
- struct v4l2_m2m_ctx *m2m_ctx;
-};
-
-static struct emmaprp_q_data *get_q_data(struct emmaprp_ctx *ctx,
- enum v4l2_buf_type type)
-{
- switch (type) {
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- return &(ctx->q_data[V4L2_M2M_SRC]);
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- return &(ctx->q_data[V4L2_M2M_DST]);
- default:
- BUG();
- }
- return NULL;
-}
-
-/*
- * mem2mem callbacks
- */
-static void emmaprp_job_abort(void *priv)
-{
- struct emmaprp_ctx *ctx = priv;
- struct emmaprp_dev *pcdev = ctx->dev;
-
- ctx->aborting = 1;
-
- dprintk(pcdev, "Aborting task\n");
-
- v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->m2m_ctx);
-}
-
-static void emmaprp_lock(void *priv)
-{
- struct emmaprp_ctx *ctx = priv;
- struct emmaprp_dev *pcdev = ctx->dev;
- mutex_lock(&pcdev->dev_mutex);
-}
-
-static void emmaprp_unlock(void *priv)
-{
- struct emmaprp_ctx *ctx = priv;
- struct emmaprp_dev *pcdev = ctx->dev;
- mutex_unlock(&pcdev->dev_mutex);
-}
-
-static inline void emmaprp_dump_regs(struct emmaprp_dev *pcdev)
-{
- dprintk(pcdev,
- "eMMa-PrP Registers:\n"
- " SOURCE_Y_PTR = 0x%08X\n"
- " SRC_FRAME_SIZE = 0x%08X\n"
- " DEST_Y_PTR = 0x%08X\n"
- " DEST_CR_PTR = 0x%08X\n"
- " DEST_CB_PTR = 0x%08X\n"
- " CH2_OUT_IMAGE_SIZE = 0x%08X\n"
- " CNTL = 0x%08X\n",
- readl(pcdev->base_emma + PRP_SOURCE_Y_PTR),
- readl(pcdev->base_emma + PRP_SRC_FRAME_SIZE),
- readl(pcdev->base_emma + PRP_DEST_Y_PTR),
- readl(pcdev->base_emma + PRP_DEST_CR_PTR),
- readl(pcdev->base_emma + PRP_DEST_CB_PTR),
- readl(pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE),
- readl(pcdev->base_emma + PRP_CNTL));
-}
-
-static void emmaprp_device_run(void *priv)
-{
- struct emmaprp_ctx *ctx = priv;
- struct emmaprp_q_data *s_q_data, *d_q_data;
- struct vb2_buffer *src_buf, *dst_buf;
- struct emmaprp_dev *pcdev = ctx->dev;
- unsigned int s_width, s_height;
- unsigned int d_width, d_height;
- unsigned int d_size;
- dma_addr_t p_in, p_out;
- u32 tmp;
-
- src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
- dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
-
- s_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
- s_width = s_q_data->width;
- s_height = s_q_data->height;
-
- d_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- d_width = d_q_data->width;
- d_height = d_q_data->height;
- d_size = d_width * d_height;
-
- p_in = vb2_dma_contig_plane_dma_addr(src_buf, 0);
- p_out = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
- if (!p_in || !p_out) {
- v4l2_err(&pcdev->v4l2_dev,
- "Acquiring kernel pointers to buffers failed\n");
- return;
- }
-
- /* Input frame parameters */
- writel(p_in, pcdev->base_emma + PRP_SOURCE_Y_PTR);
- writel(PRP_SIZE_WIDTH(s_width) | PRP_SIZE_HEIGHT(s_height),
- pcdev->base_emma + PRP_SRC_FRAME_SIZE);
-
- /* Output frame parameters */
- writel(p_out, pcdev->base_emma + PRP_DEST_Y_PTR);
- writel(p_out + d_size, pcdev->base_emma + PRP_DEST_CB_PTR);
- writel(p_out + d_size + (d_size >> 2),
- pcdev->base_emma + PRP_DEST_CR_PTR);
- writel(PRP_SIZE_WIDTH(d_width) | PRP_SIZE_HEIGHT(d_height),
- pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE);
-
- /* IRQ configuration */
- tmp = readl(pcdev->base_emma + PRP_INTR_CNTL);
- writel(tmp | PRP_INTR_RDERR |
- PRP_INTR_CH2WERR |
- PRP_INTR_CH2FC,
- pcdev->base_emma + PRP_INTR_CNTL);
-
- emmaprp_dump_regs(pcdev);
-
- /* Enable transfer */
- tmp = readl(pcdev->base_emma + PRP_CNTL);
- writel(tmp | PRP_CNTL_CH2_OUT_YUV420 |
- PRP_CNTL_DATA_IN_YUV422 |
- PRP_CNTL_CH2EN,
- pcdev->base_emma + PRP_CNTL);
-}
-
-static irqreturn_t emmaprp_irq(int irq_emma, void *data)
-{
- struct emmaprp_dev *pcdev = data;
- struct emmaprp_ctx *curr_ctx;
- struct vb2_buffer *src_vb, *dst_vb;
- unsigned long flags;
- u32 irqst;
-
- /* Check irq flags and clear irq */
- irqst = readl(pcdev->base_emma + PRP_INTRSTATUS);
- writel(irqst, pcdev->base_emma + PRP_INTRSTATUS);
- dprintk(pcdev, "irqst = 0x%08x\n", irqst);
-
- curr_ctx = v4l2_m2m_get_curr_priv(pcdev->m2m_dev);
- if (curr_ctx == NULL) {
- pr_err("Instance released before the end of transaction\n");
- return IRQ_HANDLED;
- }
-
- if (!curr_ctx->aborting) {
- if ((irqst & PRP_INTR_ST_RDERR) ||
- (irqst & PRP_INTR_ST_CH2WERR)) {
- pr_err("PrP bus error ocurred, this transfer is probably corrupted\n");
- writel(PRP_CNTL_SWRST, pcdev->base_emma + PRP_CNTL);
- } else if (irqst & PRP_INTR_ST_CH2B1CI) { /* buffer ready */
- src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
- dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
-
- spin_lock_irqsave(&pcdev->irqlock, flags);
- v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
- v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
- spin_unlock_irqrestore(&pcdev->irqlock, flags);
- }
- }
-
- v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->m2m_ctx);
- return IRQ_HANDLED;
-}
-
-/*
- * video ioctls
- */
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1);
- strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1);
- /*
- * This is only a mem-to-mem video device. The capture and output
- * device capability flags are left only for backward compatibility
- * and are scheduled for removal.
- */
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
- V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
- return 0;
-}
-
-static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
-{
- int i, num;
- struct emmaprp_fmt *fmt;
-
- num = 0;
-
- for (i = 0; i < NUM_FORMATS; ++i) {
- if (formats[i].types & type) {
- /* index-th format of type type found ? */
- if (num == f->index)
- break;
- /* Correct type but haven't reached our index yet,
- * just increment per-type index */
- ++num;
- }
- }
-
- if (i < NUM_FORMATS) {
- /* Format found */
- fmt = &formats[i];
- strlcpy(f->description, fmt->name, sizeof(f->description) - 1);
- f->pixelformat = fmt->fourcc;
- return 0;
- }
-
- /* Format not found */
- return -EINVAL;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- return enum_fmt(f, MEM2MEM_CAPTURE);
-}
-
-static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- return enum_fmt(f, MEM2MEM_OUTPUT);
-}
-
-static int vidioc_g_fmt(struct emmaprp_ctx *ctx, struct v4l2_format *f)
-{
- struct vb2_queue *vq;
- struct emmaprp_q_data *q_data;
-
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
- if (!vq)
- return -EINVAL;
-
- q_data = get_q_data(ctx, f->type);
-
- f->fmt.pix.width = q_data->width;
- f->fmt.pix.height = q_data->height;
- f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.pixelformat = q_data->fmt->fourcc;
- if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
- f->fmt.pix.bytesperline = q_data->width * 3 / 2;
- else /* YUYV */
- f->fmt.pix.bytesperline = q_data->width * 2;
- f->fmt.pix.sizeimage = q_data->sizeimage;
-
- return 0;
-}
-
-static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- return vidioc_g_fmt(priv, f);
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- return vidioc_g_fmt(priv, f);
-}
-
-static int vidioc_try_fmt(struct v4l2_format *f)
-{
- enum v4l2_field field;
-
-
- if (!find_format(f))
- return -EINVAL;
-
- field = f->fmt.pix.field;
- if (field == V4L2_FIELD_ANY)
- field = V4L2_FIELD_NONE;
- else if (V4L2_FIELD_NONE != field)
- return -EINVAL;
-
- /* V4L2 specification suggests the driver corrects the format struct
- * if any of the dimensions is unsupported */
- f->fmt.pix.field = field;
-
- if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) {
- v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W,
- W_ALIGN_YUV420, &f->fmt.pix.height,
- MIN_H, MAX_H, H_ALIGN, S_ALIGN);
- f->fmt.pix.bytesperline = f->fmt.pix.width * 3 / 2;
- } else {
- v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W,
- W_ALIGN_OTHERS, &f->fmt.pix.height,
- MIN_H, MAX_H, H_ALIGN, S_ALIGN);
- f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
- }
- f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
-
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct emmaprp_fmt *fmt;
- struct emmaprp_ctx *ctx = priv;
-
- fmt = find_format(f);
- if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
- v4l2_err(&ctx->dev->v4l2_dev,
- "Fourcc format (0x%08x) invalid.\n",
- f->fmt.pix.pixelformat);
- return -EINVAL;
- }
-
- return vidioc_try_fmt(f);
-}
-
-static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct emmaprp_fmt *fmt;
- struct emmaprp_ctx *ctx = priv;
-
- fmt = find_format(f);
- if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
- v4l2_err(&ctx->dev->v4l2_dev,
- "Fourcc format (0x%08x) invalid.\n",
- f->fmt.pix.pixelformat);
- return -EINVAL;
- }
-
- return vidioc_try_fmt(f);
-}
-
-static int vidioc_s_fmt(struct emmaprp_ctx *ctx, struct v4l2_format *f)
-{
- struct emmaprp_q_data *q_data;
- struct vb2_queue *vq;
- int ret;
-
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
- if (!vq)
- return -EINVAL;
-
- q_data = get_q_data(ctx, f->type);
- if (!q_data)
- return -EINVAL;
-
- if (vb2_is_busy(vq)) {
- v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
- return -EBUSY;
- }
-
- ret = vidioc_try_fmt(f);
- if (ret)
- return ret;
-
- q_data->fmt = find_format(f);
- q_data->width = f->fmt.pix.width;
- q_data->height = f->fmt.pix.height;
- if (q_data->fmt->fourcc == V4L2_PIX_FMT_YUV420)
- q_data->sizeimage = q_data->width * q_data->height * 3 / 2;
- else /* YUYV */
- q_data->sizeimage = q_data->width * q_data->height * 2;
-
- dprintk(ctx->dev,
- "Setting format for type %d, wxh: %dx%d, fmt: %d\n",
- f->type, q_data->width, q_data->height, q_data->fmt->fourcc);
-
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- int ret;
-
- ret = vidioc_try_fmt_vid_cap(file, priv, f);
- if (ret)
- return ret;
-
- return vidioc_s_fmt(priv, f);
-}
-
-static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- int ret;
-
- ret = vidioc_try_fmt_vid_out(file, priv, f);
- if (ret)
- return ret;
-
- return vidioc_s_fmt(priv, f);
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct emmaprp_ctx *ctx = priv;
-
- return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct emmaprp_ctx *ctx = priv;
-
- return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct emmaprp_ctx *ctx = priv;
-
- return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct emmaprp_ctx *ctx = priv;
-
- return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct emmaprp_ctx *ctx = priv;
-
- return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
-}
-
-static int vidioc_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct emmaprp_ctx *ctx = priv;
-
- return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
-}
-
-static const struct v4l2_ioctl_ops emmaprp_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
-
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
-
- .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
- .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out,
- .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
- .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
-
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
-
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
-};
-
-
-/*
- * Queue operations
- */
-static int emmaprp_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
- unsigned int *nbuffers, unsigned int *nplanes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- struct emmaprp_ctx *ctx = vb2_get_drv_priv(vq);
- struct emmaprp_q_data *q_data;
- unsigned int size, count = *nbuffers;
-
- q_data = get_q_data(ctx, vq->type);
-
- if (q_data->fmt->fourcc == V4L2_PIX_FMT_YUV420)
- size = q_data->width * q_data->height * 3 / 2;
- else
- size = q_data->width * q_data->height * 2;
-
- while (size * count > MEM2MEM_VID_MEM_LIMIT)
- (count)--;
-
- *nplanes = 1;
- *nbuffers = count;
- sizes[0] = size;
-
- alloc_ctxs[0] = ctx->dev->alloc_ctx;
-
- dprintk(ctx->dev, "get %d buffer(s) of size %d each.\n", count, size);
-
- return 0;
-}
-
-static int emmaprp_buf_prepare(struct vb2_buffer *vb)
-{
- struct emmaprp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct emmaprp_q_data *q_data;
-
- dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type);
-
- q_data = get_q_data(ctx, vb->vb2_queue->type);
-
- if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
- dprintk(ctx->dev, "%s data will not fit into plane"
- "(%lu < %lu)\n", __func__,
- vb2_plane_size(vb, 0),
- (long)q_data->sizeimage);
- return -EINVAL;
- }
-
- vb2_set_plane_payload(vb, 0, q_data->sizeimage);
-
- return 0;
-}
-
-static void emmaprp_buf_queue(struct vb2_buffer *vb)
-{
- struct emmaprp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
-}
-
-static struct vb2_ops emmaprp_qops = {
- .queue_setup = emmaprp_queue_setup,
- .buf_prepare = emmaprp_buf_prepare,
- .buf_queue = emmaprp_buf_queue,
-};
-
-static int queue_init(void *priv, struct vb2_queue *src_vq,
- struct vb2_queue *dst_vq)
-{
- struct emmaprp_ctx *ctx = priv;
- int ret;
-
- memset(src_vq, 0, sizeof(*src_vq));
- src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
- src_vq->drv_priv = ctx;
- src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
- src_vq->ops = &emmaprp_qops;
- src_vq->mem_ops = &vb2_dma_contig_memops;
-
- ret = vb2_queue_init(src_vq);
- if (ret)
- return ret;
-
- memset(dst_vq, 0, sizeof(*dst_vq));
- dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
- dst_vq->drv_priv = ctx;
- dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
- dst_vq->ops = &emmaprp_qops;
- dst_vq->mem_ops = &vb2_dma_contig_memops;
-
- return vb2_queue_init(dst_vq);
-}
-
-/*
- * File operations
- */
-static int emmaprp_open(struct file *file)
-{
- struct emmaprp_dev *pcdev = video_drvdata(file);
- struct emmaprp_ctx *ctx;
-
- ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- file->private_data = ctx;
- ctx->dev = pcdev;
-
- ctx->m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init);
-
- if (IS_ERR(ctx->m2m_ctx)) {
- int ret = PTR_ERR(ctx->m2m_ctx);
-
- kfree(ctx);
- return ret;
- }
-
- clk_enable(pcdev->clk_emma);
- ctx->q_data[V4L2_M2M_SRC].fmt = &formats[1];
- ctx->q_data[V4L2_M2M_DST].fmt = &formats[0];
-
- dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
-
- return 0;
-}
-
-static int emmaprp_release(struct file *file)
-{
- struct emmaprp_dev *pcdev = video_drvdata(file);
- struct emmaprp_ctx *ctx = file->private_data;
-
- dprintk(pcdev, "Releasing instance %p\n", ctx);
-
- clk_disable(pcdev->clk_emma);
- v4l2_m2m_ctx_release(ctx->m2m_ctx);
- kfree(ctx);
-
- return 0;
-}
-
-static unsigned int emmaprp_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct emmaprp_ctx *ctx = file->private_data;
-
- return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
-}
-
-static int emmaprp_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct emmaprp_ctx *ctx = file->private_data;
-
- return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
-}
-
-static const struct v4l2_file_operations emmaprp_fops = {
- .owner = THIS_MODULE,
- .open = emmaprp_open,
- .release = emmaprp_release,
- .poll = emmaprp_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = emmaprp_mmap,
-};
-
-static struct video_device emmaprp_videodev = {
- .name = MEM2MEM_NAME,
- .fops = &emmaprp_fops,
- .ioctl_ops = &emmaprp_ioctl_ops,
- .minor = -1,
- .release = video_device_release,
-};
-
-static struct v4l2_m2m_ops m2m_ops = {
- .device_run = emmaprp_device_run,
- .job_abort = emmaprp_job_abort,
- .lock = emmaprp_lock,
- .unlock = emmaprp_unlock,
-};
-
-static int emmaprp_probe(struct platform_device *pdev)
-{
- struct emmaprp_dev *pcdev;
- struct video_device *vfd;
- struct resource *res_emma;
- int irq_emma;
- int ret;
-
- pcdev = kzalloc(sizeof *pcdev, GFP_KERNEL);
- if (!pcdev)
- return -ENOMEM;
-
- spin_lock_init(&pcdev->irqlock);
-
- pcdev->clk_emma = clk_get(&pdev->dev, NULL);
- if (IS_ERR(pcdev->clk_emma)) {
- ret = PTR_ERR(pcdev->clk_emma);
- goto free_dev;
- }
-
- irq_emma = platform_get_irq(pdev, 0);
- res_emma = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (irq_emma < 0 || res_emma == NULL) {
- dev_err(&pdev->dev, "Missing platform resources data\n");
- ret = -ENODEV;
- goto free_clk;
- }
-
- ret = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev);
- if (ret)
- goto free_clk;
-
- mutex_init(&pcdev->dev_mutex);
-
- vfd = video_device_alloc();
- if (!vfd) {
- v4l2_err(&pcdev->v4l2_dev, "Failed to allocate video device\n");
- ret = -ENOMEM;
- goto unreg_dev;
- }
-
- *vfd = emmaprp_videodev;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
- vfd->lock = &pcdev->dev_mutex;
-
- video_set_drvdata(vfd, pcdev);
- snprintf(vfd->name, sizeof(vfd->name), "%s", emmaprp_videodev.name);
- pcdev->vfd = vfd;
- v4l2_info(&pcdev->v4l2_dev, EMMAPRP_MODULE_NAME
- " Device registered as /dev/video%d\n", vfd->num);
-
- platform_set_drvdata(pdev, pcdev);
-
- if (devm_request_mem_region(&pdev->dev, res_emma->start,
- resource_size(res_emma), MEM2MEM_NAME) == NULL)
- goto rel_vdev;
-
- pcdev->base_emma = devm_ioremap(&pdev->dev, res_emma->start,
- resource_size(res_emma));
- if (!pcdev->base_emma)
- goto rel_vdev;
-
- pcdev->irq_emma = irq_emma;
- pcdev->res_emma = res_emma;
-
- if (devm_request_irq(&pdev->dev, pcdev->irq_emma, emmaprp_irq,
- 0, MEM2MEM_NAME, pcdev) < 0)
- goto rel_vdev;
-
- pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
- if (IS_ERR(pcdev->alloc_ctx)) {
- v4l2_err(&pcdev->v4l2_dev, "Failed to alloc vb2 context\n");
- ret = PTR_ERR(pcdev->alloc_ctx);
- goto rel_vdev;
- }
-
- pcdev->m2m_dev = v4l2_m2m_init(&m2m_ops);
- if (IS_ERR(pcdev->m2m_dev)) {
- v4l2_err(&pcdev->v4l2_dev, "Failed to init mem2mem device\n");
- ret = PTR_ERR(pcdev->m2m_dev);
- goto rel_ctx;
- }
-
- ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
- if (ret) {
- v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n");
- goto rel_m2m;
- }
-
- return 0;
-
-
-rel_m2m:
- v4l2_m2m_release(pcdev->m2m_dev);
-rel_ctx:
- vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
-rel_vdev:
- video_device_release(vfd);
-unreg_dev:
- v4l2_device_unregister(&pcdev->v4l2_dev);
-free_clk:
- clk_put(pcdev->clk_emma);
-free_dev:
- kfree(pcdev);
-
- return ret;
-}
-
-static int emmaprp_remove(struct platform_device *pdev)
-{
- struct emmaprp_dev *pcdev = platform_get_drvdata(pdev);
-
- v4l2_info(&pcdev->v4l2_dev, "Removing " EMMAPRP_MODULE_NAME);
-
- video_unregister_device(pcdev->vfd);
- v4l2_m2m_release(pcdev->m2m_dev);
- vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
- v4l2_device_unregister(&pcdev->v4l2_dev);
- clk_put(pcdev->clk_emma);
- kfree(pcdev);
-
- return 0;
-}
-
-static struct platform_driver emmaprp_pdrv = {
- .probe = emmaprp_probe,
- .remove = emmaprp_remove,
- .driver = {
- .name = MEM2MEM_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-static void __exit emmaprp_exit(void)
-{
- platform_driver_unregister(&emmaprp_pdrv);
-}
-
-static int __init emmaprp_init(void)
-{
- return platform_driver_register(&emmaprp_pdrv);
-}
-
-module_init(emmaprp_init);
-module_exit(emmaprp_exit);
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
deleted file mode 100644
index 1481b0d419d..00000000000
--- a/drivers/media/video/mx3_camera.c
+++ /dev/null
@@ -1,1292 +0,0 @@
-/*
- * V4L2 Driver for i.MX3x camera host
- *
- * Copyright (C) 2008
- * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/videodev2.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/vmalloc.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-dev.h>
-#include <media/videobuf2-dma-contig.h>
-#include <media/soc_camera.h>
-#include <media/soc_mediabus.h>
-
-#include <mach/ipu.h>
-#include <linux/platform_data/camera-mx3.h>
-#include <linux/platform_data/dma-imx.h>
-
-#define MX3_CAM_DRV_NAME "mx3-camera"
-
-/* CMOS Sensor Interface Registers */
-#define CSI_REG_START 0x60
-
-#define CSI_SENS_CONF (0x60 - CSI_REG_START)
-#define CSI_SENS_FRM_SIZE (0x64 - CSI_REG_START)
-#define CSI_ACT_FRM_SIZE (0x68 - CSI_REG_START)
-#define CSI_OUT_FRM_CTRL (0x6C - CSI_REG_START)
-#define CSI_TST_CTRL (0x70 - CSI_REG_START)
-#define CSI_CCIR_CODE_1 (0x74 - CSI_REG_START)
-#define CSI_CCIR_CODE_2 (0x78 - CSI_REG_START)
-#define CSI_CCIR_CODE_3 (0x7C - CSI_REG_START)
-#define CSI_FLASH_STROBE_1 (0x80 - CSI_REG_START)
-#define CSI_FLASH_STROBE_2 (0x84 - CSI_REG_START)
-
-#define CSI_SENS_CONF_VSYNC_POL_SHIFT 0
-#define CSI_SENS_CONF_HSYNC_POL_SHIFT 1
-#define CSI_SENS_CONF_DATA_POL_SHIFT 2
-#define CSI_SENS_CONF_PIX_CLK_POL_SHIFT 3
-#define CSI_SENS_CONF_SENS_PRTCL_SHIFT 4
-#define CSI_SENS_CONF_SENS_CLKSRC_SHIFT 7
-#define CSI_SENS_CONF_DATA_FMT_SHIFT 8
-#define CSI_SENS_CONF_DATA_WIDTH_SHIFT 10
-#define CSI_SENS_CONF_EXT_VSYNC_SHIFT 15
-#define CSI_SENS_CONF_DIVRATIO_SHIFT 16
-
-#define CSI_SENS_CONF_DATA_FMT_RGB_YUV444 (0UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
-#define CSI_SENS_CONF_DATA_FMT_YUV422 (2UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
-#define CSI_SENS_CONF_DATA_FMT_BAYER (3UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
-
-#define MAX_VIDEO_MEM 16
-
-struct mx3_camera_buffer {
- /* common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
- struct list_head queue;
-
- /* One descriptot per scatterlist (per frame) */
- struct dma_async_tx_descriptor *txd;
-
- /* We have to "build" a scatterlist ourselves - one element per frame */
- struct scatterlist sg;
-};
-
-/**
- * struct mx3_camera_dev - i.MX3x camera (CSI) object
- * @dev: camera device, to which the coherent buffer is attached
- * @icd: currently attached camera sensor
- * @clk: pointer to clock
- * @base: remapped register base address
- * @pdata: platform data
- * @platform_flags: platform flags
- * @mclk: master clock frequency in Hz
- * @capture: list of capture videobuffers
- * @lock: protects video buffer lists
- * @active: active video buffer
- * @idmac_channel: array of pointers to IPU DMAC DMA channels
- * @soc_host: embedded soc_host object
- */
-struct mx3_camera_dev {
- /*
- * i.MX3x is only supposed to handle one camera on its Camera Sensor
- * Interface. If anyone ever builds hardware to enable more than one
- * camera _simultaneously_, they will have to modify this driver too
- */
- struct soc_camera_device *icd;
- struct clk *clk;
-
- void __iomem *base;
-
- struct mx3_camera_pdata *pdata;
-
- unsigned long platform_flags;
- unsigned long mclk;
- u16 width_flags; /* max 15 bits */
-
- struct list_head capture;
- spinlock_t lock; /* Protects video buffer lists */
- struct mx3_camera_buffer *active;
- size_t buf_total;
- struct vb2_alloc_ctx *alloc_ctx;
- enum v4l2_field field;
- int sequence;
-
- /* IDMAC / dmaengine interface */
- struct idmac_channel *idmac_channel[1]; /* We need one channel */
-
- struct soc_camera_host soc_host;
-};
-
-struct dma_chan_request {
- struct mx3_camera_dev *mx3_cam;
- enum ipu_channel id;
-};
-
-static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg)
-{
- return __raw_readl(mx3->base + reg);
-}
-
-static void csi_reg_write(struct mx3_camera_dev *mx3, u32 value, off_t reg)
-{
- __raw_writel(value, mx3->base + reg);
-}
-
-static struct mx3_camera_buffer *to_mx3_vb(struct vb2_buffer *vb)
-{
- return container_of(vb, struct mx3_camera_buffer, vb);
-}
-
-/* Called from the IPU IDMAC ISR */
-static void mx3_cam_dma_done(void *arg)
-{
- struct idmac_tx_desc *desc = to_tx_desc(arg);
- struct dma_chan *chan = desc->txd.chan;
- struct idmac_channel *ichannel = to_idmac_chan(chan);
- struct mx3_camera_dev *mx3_cam = ichannel->client;
-
- dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n",
- desc->txd.cookie, mx3_cam->active ? sg_dma_address(&mx3_cam->active->sg) : 0);
-
- spin_lock(&mx3_cam->lock);
- if (mx3_cam->active) {
- struct vb2_buffer *vb = &mx3_cam->active->vb;
- struct mx3_camera_buffer *buf = to_mx3_vb(vb);
-
- list_del_init(&buf->queue);
- do_gettimeofday(&vb->v4l2_buf.timestamp);
- vb->v4l2_buf.field = mx3_cam->field;
- vb->v4l2_buf.sequence = mx3_cam->sequence++;
- vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
- }
-
- if (list_empty(&mx3_cam->capture)) {
- mx3_cam->active = NULL;
- spin_unlock(&mx3_cam->lock);
-
- /*
- * stop capture - without further buffers IPU_CHA_BUF0_RDY will
- * not get updated
- */
- return;
- }
-
- mx3_cam->active = list_entry(mx3_cam->capture.next,
- struct mx3_camera_buffer, queue);
- spin_unlock(&mx3_cam->lock);
-}
-
-/*
- * Videobuf operations
- */
-
-/*
- * Calculate the __buffer__ (not data) size and number of buffers.
- */
-static int mx3_videobuf_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
- unsigned int *count, unsigned int *num_planes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx3_camera_dev *mx3_cam = ici->priv;
-
- if (!mx3_cam->idmac_channel[0])
- return -EINVAL;
-
- if (fmt) {
- const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
- fmt->fmt.pix.pixelformat);
- unsigned int bytes_per_line;
- int ret;
-
- if (!xlate)
- return -EINVAL;
-
- ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
- xlate->host_fmt);
- if (ret < 0)
- return ret;
-
- bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret);
-
- ret = soc_mbus_image_size(xlate->host_fmt, bytes_per_line,
- fmt->fmt.pix.height);
- if (ret < 0)
- return ret;
-
- sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret);
- } else {
- /* Called from VIDIOC_REQBUFS or in compatibility mode */
- sizes[0] = icd->sizeimage;
- }
-
- alloc_ctxs[0] = mx3_cam->alloc_ctx;
-
- if (!vq->num_buffers)
- mx3_cam->sequence = 0;
-
- if (!*count)
- *count = 2;
-
- /* If *num_planes != 0, we have already verified *count. */
- if (!*num_planes &&
- sizes[0] * *count + mx3_cam->buf_total > MAX_VIDEO_MEM * 1024 * 1024)
- *count = (MAX_VIDEO_MEM * 1024 * 1024 - mx3_cam->buf_total) /
- sizes[0];
-
- *num_planes = 1;
-
- return 0;
-}
-
-static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc)
-{
- /* Add more formats as need arises and test possibilities appear... */
- switch (fourcc) {
- case V4L2_PIX_FMT_RGB24:
- return IPU_PIX_FMT_RGB24;
- case V4L2_PIX_FMT_UYVY:
- case V4L2_PIX_FMT_RGB565:
- default:
- return IPU_PIX_FMT_GENERIC;
- }
-}
-
-static void mx3_videobuf_queue(struct vb2_buffer *vb)
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx3_camera_dev *mx3_cam = ici->priv;
- struct mx3_camera_buffer *buf = to_mx3_vb(vb);
- struct scatterlist *sg = &buf->sg;
- struct dma_async_tx_descriptor *txd;
- struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
- struct idmac_video_param *video = &ichan->params.video;
- const struct soc_mbus_pixelfmt *host_fmt = icd->current_fmt->host_fmt;
- unsigned long flags;
- dma_cookie_t cookie;
- size_t new_size;
-
- new_size = icd->sizeimage;
-
- if (vb2_plane_size(vb, 0) < new_size) {
- dev_err(icd->parent, "Buffer #%d too small (%lu < %zu)\n",
- vb->v4l2_buf.index, vb2_plane_size(vb, 0), new_size);
- goto error;
- }
-
- if (!buf->txd) {
- sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0);
- sg_dma_len(sg) = new_size;
-
- txd = dmaengine_prep_slave_sg(
- &ichan->dma_chan, sg, 1, DMA_DEV_TO_MEM,
- DMA_PREP_INTERRUPT);
- if (!txd)
- goto error;
-
- txd->callback_param = txd;
- txd->callback = mx3_cam_dma_done;
-
- buf->txd = txd;
- } else {
- txd = buf->txd;
- }
-
- vb2_set_plane_payload(vb, 0, new_size);
-
- /* This is the configuration of one sg-element */
- video->out_pixel_fmt = fourcc_to_ipu_pix(host_fmt->fourcc);
-
- if (video->out_pixel_fmt == IPU_PIX_FMT_GENERIC) {
- /*
- * If the IPU DMA channel is configured to transfer generic
- * 8-bit data, we have to set up the geometry parameters
- * correctly, according to the current pixel format. The DMA
- * horizontal parameters in this case are expressed in bytes,
- * not in pixels.
- */
- video->out_width = icd->bytesperline;
- video->out_height = icd->user_height;
- video->out_stride = icd->bytesperline;
- } else {
- /*
- * For IPU known formats the pixel unit will be managed
- * successfully by the IPU code
- */
- video->out_width = icd->user_width;
- video->out_height = icd->user_height;
- video->out_stride = icd->user_width;
- }
-
-#ifdef DEBUG
- /* helps to see what DMA actually has written */
- if (vb2_plane_vaddr(vb, 0))
- memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
-#endif
-
- spin_lock_irqsave(&mx3_cam->lock, flags);
- list_add_tail(&buf->queue, &mx3_cam->capture);
-
- if (!mx3_cam->active)
- mx3_cam->active = buf;
-
- spin_unlock_irq(&mx3_cam->lock);
-
- cookie = txd->tx_submit(txd);
- dev_dbg(icd->parent, "Submitted cookie %d DMA 0x%08x\n",
- cookie, sg_dma_address(&buf->sg));
-
- if (cookie >= 0)
- return;
-
- spin_lock_irq(&mx3_cam->lock);
-
- /* Submit error */
- list_del_init(&buf->queue);
-
- if (mx3_cam->active == buf)
- mx3_cam->active = NULL;
-
- spin_unlock_irqrestore(&mx3_cam->lock, flags);
-error:
- vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
-}
-
-static void mx3_videobuf_release(struct vb2_buffer *vb)
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx3_camera_dev *mx3_cam = ici->priv;
- struct mx3_camera_buffer *buf = to_mx3_vb(vb);
- struct dma_async_tx_descriptor *txd = buf->txd;
- unsigned long flags;
-
- dev_dbg(icd->parent,
- "Release%s DMA 0x%08x, queue %sempty\n",
- mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg),
- list_empty(&buf->queue) ? "" : "not ");
-
- spin_lock_irqsave(&mx3_cam->lock, flags);
-
- if (mx3_cam->active == buf)
- mx3_cam->active = NULL;
-
- /* Doesn't hurt also if the list is empty */
- list_del_init(&buf->queue);
-
- if (txd) {
- buf->txd = NULL;
- if (mx3_cam->idmac_channel[0])
- async_tx_ack(txd);
- }
-
- spin_unlock_irqrestore(&mx3_cam->lock, flags);
-
- mx3_cam->buf_total -= vb2_plane_size(vb, 0);
-}
-
-static int mx3_videobuf_init(struct vb2_buffer *vb)
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx3_camera_dev *mx3_cam = ici->priv;
- struct mx3_camera_buffer *buf = to_mx3_vb(vb);
-
- if (!buf->txd) {
- /* This is for locking debugging only */
- INIT_LIST_HEAD(&buf->queue);
- sg_init_table(&buf->sg, 1);
-
- mx3_cam->buf_total += vb2_plane_size(vb, 0);
- }
-
- return 0;
-}
-
-static int mx3_stop_streaming(struct vb2_queue *q)
-{
- struct soc_camera_device *icd = soc_camera_from_vb2q(q);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx3_camera_dev *mx3_cam = ici->priv;
- struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
- struct mx3_camera_buffer *buf, *tmp;
- unsigned long flags;
-
- if (ichan) {
- struct dma_chan *chan = &ichan->dma_chan;
- chan->device->device_control(chan, DMA_PAUSE, 0);
- }
-
- spin_lock_irqsave(&mx3_cam->lock, flags);
-
- mx3_cam->active = NULL;
-
- list_for_each_entry_safe(buf, tmp, &mx3_cam->capture, queue) {
- list_del_init(&buf->queue);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- }
-
- spin_unlock_irqrestore(&mx3_cam->lock, flags);
-
- return 0;
-}
-
-static struct vb2_ops mx3_videobuf_ops = {
- .queue_setup = mx3_videobuf_setup,
- .buf_queue = mx3_videobuf_queue,
- .buf_cleanup = mx3_videobuf_release,
- .buf_init = mx3_videobuf_init,
- .wait_prepare = soc_camera_unlock,
- .wait_finish = soc_camera_lock,
- .stop_streaming = mx3_stop_streaming,
-};
-
-static int mx3_camera_init_videobuf(struct vb2_queue *q,
- struct soc_camera_device *icd)
-{
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- q->io_modes = VB2_MMAP | VB2_USERPTR;
- q->drv_priv = icd;
- q->ops = &mx3_videobuf_ops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->buf_struct_size = sizeof(struct mx3_camera_buffer);
-
- return vb2_queue_init(q);
-}
-
-/* First part of ipu_csi_init_interface() */
-static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam,
- struct soc_camera_device *icd)
-{
- u32 conf;
- long rate;
-
- /* Set default size: ipu_csi_set_window_size() */
- csi_reg_write(mx3_cam, (640 - 1) | ((480 - 1) << 16), CSI_ACT_FRM_SIZE);
- /* ...and position to 0:0: ipu_csi_set_window_pos() */
- conf = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
- csi_reg_write(mx3_cam, conf, CSI_OUT_FRM_CTRL);
-
- /* We use only gated clock synchronisation mode so far */
- conf = 0 << CSI_SENS_CONF_SENS_PRTCL_SHIFT;
-
- /* Set generic data, platform-biggest bus-width */
- conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
-
- if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
- conf |= 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
- else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
- conf |= 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
- else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
- conf |= 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
- else/* if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)*/
- conf |= 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
-
- if (mx3_cam->platform_flags & MX3_CAMERA_CLK_SRC)
- conf |= 1 << CSI_SENS_CONF_SENS_CLKSRC_SHIFT;
- if (mx3_cam->platform_flags & MX3_CAMERA_EXT_VSYNC)
- conf |= 1 << CSI_SENS_CONF_EXT_VSYNC_SHIFT;
- if (mx3_cam->platform_flags & MX3_CAMERA_DP)
- conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
- if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
- conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
- if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
- conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
- if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
- conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
-
- /* ipu_csi_init_interface() */
- csi_reg_write(mx3_cam, conf, CSI_SENS_CONF);
-
- clk_prepare_enable(mx3_cam->clk);
- rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
- dev_dbg(icd->parent, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
- if (rate)
- clk_set_rate(mx3_cam->clk, rate);
-}
-
-/* Called with .video_lock held */
-static int mx3_camera_add_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx3_camera_dev *mx3_cam = ici->priv;
-
- if (mx3_cam->icd)
- return -EBUSY;
-
- mx3_camera_activate(mx3_cam, icd);
-
- mx3_cam->buf_total = 0;
- mx3_cam->icd = icd;
-
- dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n",
- icd->devnum);
-
- return 0;
-}
-
-/* Called with .video_lock held */
-static void mx3_camera_remove_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx3_camera_dev *mx3_cam = ici->priv;
- struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
-
- BUG_ON(icd != mx3_cam->icd);
-
- if (*ichan) {
- dma_release_channel(&(*ichan)->dma_chan);
- *ichan = NULL;
- }
-
- clk_disable_unprepare(mx3_cam->clk);
-
- mx3_cam->icd = NULL;
-
- dev_info(icd->parent, "MX3 Camera driver detached from camera %d\n",
- icd->devnum);
-}
-
-static int test_platform_param(struct mx3_camera_dev *mx3_cam,
- unsigned char buswidth, unsigned long *flags)
-{
- /*
- * If requested data width is supported by the platform, use it or any
- * possible lower value - i.MX31 is smart enough to shift bits
- */
- if (buswidth > fls(mx3_cam->width_flags))
- return -EINVAL;
-
- /*
- * Platform specified synchronization and pixel clock polarities are
- * only a recommendation and are only used during probing. MX3x
- * camera interface only works in master mode, i.e., uses HSYNC and
- * VSYNC signals from the sensor
- */
- *flags = V4L2_MBUS_MASTER |
- V4L2_MBUS_HSYNC_ACTIVE_HIGH |
- V4L2_MBUS_HSYNC_ACTIVE_LOW |
- V4L2_MBUS_VSYNC_ACTIVE_HIGH |
- V4L2_MBUS_VSYNC_ACTIVE_LOW |
- V4L2_MBUS_PCLK_SAMPLE_RISING |
- V4L2_MBUS_PCLK_SAMPLE_FALLING |
- V4L2_MBUS_DATA_ACTIVE_HIGH |
- V4L2_MBUS_DATA_ACTIVE_LOW;
-
- return 0;
-}
-
-static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
- const unsigned int depth)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx3_camera_dev *mx3_cam = ici->priv;
- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
- unsigned long bus_flags, common_flags;
- int ret = test_platform_param(mx3_cam, depth, &bus_flags);
-
- dev_dbg(icd->parent, "request bus width %d bit: %d\n", depth, ret);
-
- if (ret < 0)
- return ret;
-
- ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
- if (!ret) {
- common_flags = soc_mbus_config_compatible(&cfg,
- bus_flags);
- if (!common_flags) {
- dev_warn(icd->parent,
- "Flags incompatible: camera 0x%x, host 0x%lx\n",
- cfg.flags, bus_flags);
- return -EINVAL;
- }
- } else if (ret != -ENOIOCTLCMD) {
- return ret;
- }
-
- return 0;
-}
-
-static bool chan_filter(struct dma_chan *chan, void *arg)
-{
- struct dma_chan_request *rq = arg;
- struct mx3_camera_pdata *pdata;
-
- if (!imx_dma_is_ipu(chan))
- return false;
-
- if (!rq)
- return false;
-
- pdata = rq->mx3_cam->soc_host.v4l2_dev.dev->platform_data;
-
- return rq->id == chan->chan_id &&
- pdata->dma_dev == chan->device->dev;
-}
-
-static const struct soc_mbus_pixelfmt mx3_camera_formats[] = {
- {
- .fourcc = V4L2_PIX_FMT_SBGGR8,
- .name = "Bayer BGGR (sRGB) 8 bit",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_NONE,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- }, {
- .fourcc = V4L2_PIX_FMT_GREY,
- .name = "Monochrome 8 bit",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_NONE,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-};
-
-/* This will be corrected as we get more formats */
-static bool mx3_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
-{
- return fmt->packing == SOC_MBUS_PACKING_NONE ||
- (fmt->bits_per_sample == 8 &&
- fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
- (fmt->bits_per_sample > 8 &&
- fmt->packing == SOC_MBUS_PACKING_EXTEND16);
-}
-
-static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
- struct soc_camera_format_xlate *xlate)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct device *dev = icd->parent;
- int formats = 0, ret;
- enum v4l2_mbus_pixelcode code;
- const struct soc_mbus_pixelfmt *fmt;
-
- ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
- if (ret < 0)
- /* No more formats */
- return 0;
-
- fmt = soc_mbus_get_fmtdesc(code);
- if (!fmt) {
- dev_warn(icd->parent,
- "Unsupported format code #%u: %d\n", idx, code);
- return 0;
- }
-
- /* This also checks support for the requested bits-per-sample */
- ret = mx3_camera_try_bus_param(icd, fmt->bits_per_sample);
- if (ret < 0)
- return 0;
-
- switch (code) {
- case V4L2_MBUS_FMT_SBGGR10_1X10:
- formats++;
- if (xlate) {
- xlate->host_fmt = &mx3_camera_formats[0];
- xlate->code = code;
- xlate++;
- dev_dbg(dev, "Providing format %s using code %d\n",
- mx3_camera_formats[0].name, code);
- }
- break;
- case V4L2_MBUS_FMT_Y10_1X10:
- formats++;
- if (xlate) {
- xlate->host_fmt = &mx3_camera_formats[1];
- xlate->code = code;
- xlate++;
- dev_dbg(dev, "Providing format %s using code %d\n",
- mx3_camera_formats[1].name, code);
- }
- break;
- default:
- if (!mx3_camera_packing_supported(fmt))
- return 0;
- }
-
- /* Generic pass-through */
- formats++;
- if (xlate) {
- xlate->host_fmt = fmt;
- xlate->code = code;
- dev_dbg(dev, "Providing format %c%c%c%c in pass-through mode\n",
- (fmt->fourcc >> (0*8)) & 0xFF,
- (fmt->fourcc >> (1*8)) & 0xFF,
- (fmt->fourcc >> (2*8)) & 0xFF,
- (fmt->fourcc >> (3*8)) & 0xFF);
- xlate++;
- }
-
- return formats;
-}
-
-static void configure_geometry(struct mx3_camera_dev *mx3_cam,
- unsigned int width, unsigned int height,
- const struct soc_mbus_pixelfmt *fmt)
-{
- u32 ctrl, width_field, height_field;
-
- if (fourcc_to_ipu_pix(fmt->fourcc) == IPU_PIX_FMT_GENERIC) {
- /*
- * As the CSI will be configured to output BAYER, here
- * the width parameter count the number of samples to
- * capture to complete the whole image width.
- */
- unsigned int num, den;
- int ret = soc_mbus_samples_per_pixel(fmt, &num, &den);
- BUG_ON(ret < 0);
- width = width * num / den;
- }
-
- /* Setup frame size - this cannot be changed on-the-fly... */
- width_field = width - 1;
- height_field = height - 1;
- csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_SENS_FRM_SIZE);
-
- csi_reg_write(mx3_cam, width_field << 16, CSI_FLASH_STROBE_1);
- csi_reg_write(mx3_cam, (height_field << 16) | 0x22, CSI_FLASH_STROBE_2);
-
- csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_ACT_FRM_SIZE);
-
- /* ...and position */
- ctrl = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
- /* Sensor does the cropping */
- csi_reg_write(mx3_cam, ctrl | 0 | (0 << 8), CSI_OUT_FRM_CTRL);
-}
-
-static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
-{
- dma_cap_mask_t mask;
- struct dma_chan *chan;
- struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
- /* We have to use IDMAC_IC_7 for Bayer / generic data */
- struct dma_chan_request rq = {.mx3_cam = mx3_cam,
- .id = IDMAC_IC_7};
-
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
- dma_cap_set(DMA_PRIVATE, mask);
- chan = dma_request_channel(mask, chan_filter, &rq);
- if (!chan)
- return -EBUSY;
-
- *ichan = to_idmac_chan(chan);
- (*ichan)->client = mx3_cam;
-
- return 0;
-}
-
-/*
- * FIXME: learn to use stride != width, then we can keep stride properly aligned
- * and support arbitrary (even) widths.
- */
-static inline void stride_align(__u32 *width)
-{
- if (ALIGN(*width, 8) < 4096)
- *width = ALIGN(*width, 8);
- else
- *width = *width & ~7;
-}
-
-/*
- * As long as we don't implement host-side cropping and scaling, we can use
- * default g_crop and cropcap from soc_camera.c
- */
-static int mx3_camera_set_crop(struct soc_camera_device *icd,
- struct v4l2_crop *a)
-{
- struct v4l2_rect *rect = &a->c;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx3_camera_dev *mx3_cam = ici->priv;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct v4l2_mbus_framefmt mf;
- int ret;
-
- soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096);
- soc_camera_limit_side(&rect->top, &rect->height, 0, 2, 4096);
-
- ret = v4l2_subdev_call(sd, video, s_crop, a);
- if (ret < 0)
- return ret;
-
- /* The capture device might have changed its output sizes */
- ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- if (mf.code != icd->current_fmt->code)
- return -EINVAL;
-
- if (mf.width & 7) {
- /* Ouch! We can only handle 8-byte aligned width... */
- stride_align(&mf.width);
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
- }
-
- if (mf.width != icd->user_width || mf.height != icd->user_height)
- configure_geometry(mx3_cam, mf.width, mf.height,
- icd->current_fmt->host_fmt);
-
- dev_dbg(icd->parent, "Sensor cropped %dx%d\n",
- mf.width, mf.height);
-
- icd->user_width = mf.width;
- icd->user_height = mf.height;
-
- return ret;
-}
-
-static int mx3_camera_set_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx3_camera_dev *mx3_cam = ici->priv;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- int ret;
-
- xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
- if (!xlate) {
- dev_warn(icd->parent, "Format %x not found\n",
- pix->pixelformat);
- return -EINVAL;
- }
-
- stride_align(&pix->width);
- dev_dbg(icd->parent, "Set format %dx%d\n", pix->width, pix->height);
-
- /*
- * Might have to perform a complete interface initialisation like in
- * ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider
- * mxc_v4l2_s_fmt()
- */
-
- configure_geometry(mx3_cam, pix->width, pix->height, xlate->host_fmt);
-
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- if (mf.code != xlate->code)
- return -EINVAL;
-
- if (!mx3_cam->idmac_channel[0]) {
- ret = acquire_dma_channel(mx3_cam);
- if (ret < 0)
- return ret;
- }
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- mx3_cam->field = mf.field;
- pix->colorspace = mf.colorspace;
- icd->current_fmt = xlate;
-
- dev_dbg(icd->parent, "Sensor set %dx%d\n", pix->width, pix->height);
-
- return ret;
-}
-
-static int mx3_camera_try_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- __u32 pixfmt = pix->pixelformat;
- int ret;
-
- xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
- if (pixfmt && !xlate) {
- dev_warn(icd->parent, "Format %x not found\n", pixfmt);
- return -EINVAL;
- }
-
- /* limit to MX3 hardware capabilities */
- if (pix->height > 4096)
- pix->height = 4096;
- if (pix->width > 4096)
- pix->width = 4096;
-
- /* limit to sensor capabilities */
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->colorspace = mf.colorspace;
-
- switch (mf.field) {
- case V4L2_FIELD_ANY:
- pix->field = V4L2_FIELD_NONE;
- break;
- case V4L2_FIELD_NONE:
- break;
- default:
- dev_err(icd->parent, "Field type %d unsupported.\n",
- mf.field);
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int mx3_camera_reqbufs(struct soc_camera_device *icd,
- struct v4l2_requestbuffers *p)
-{
- return 0;
-}
-
-static unsigned int mx3_camera_poll(struct file *file, poll_table *pt)
-{
- struct soc_camera_device *icd = file->private_data;
-
- return vb2_poll(&icd->vb2_vidq, file, pt);
-}
-
-static int mx3_camera_querycap(struct soc_camera_host *ici,
- struct v4l2_capability *cap)
-{
- /* cap->name is set by the firendly caller:-> */
- strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card));
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-
- return 0;
-}
-
-static int mx3_camera_set_bus_param(struct soc_camera_device *icd)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx3_camera_dev *mx3_cam = ici->priv;
- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
- u32 pixfmt = icd->current_fmt->host_fmt->fourcc;
- unsigned long bus_flags, common_flags;
- u32 dw, sens_conf;
- const struct soc_mbus_pixelfmt *fmt;
- int buswidth;
- int ret;
- const struct soc_camera_format_xlate *xlate;
- struct device *dev = icd->parent;
-
- fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
- if (!fmt)
- return -EINVAL;
-
- xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
- if (!xlate) {
- dev_warn(dev, "Format %x not found\n", pixfmt);
- return -EINVAL;
- }
-
- buswidth = fmt->bits_per_sample;
- ret = test_platform_param(mx3_cam, buswidth, &bus_flags);
-
- dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret);
-
- if (ret < 0)
- return ret;
-
- ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
- if (!ret) {
- common_flags = soc_mbus_config_compatible(&cfg,
- bus_flags);
- if (!common_flags) {
- dev_warn(icd->parent,
- "Flags incompatible: camera 0x%x, host 0x%lx\n",
- cfg.flags, bus_flags);
- return -EINVAL;
- }
- } else if (ret != -ENOIOCTLCMD) {
- return ret;
- } else {
- common_flags = bus_flags;
- }
-
- dev_dbg(dev, "Flags cam: 0x%x host: 0x%lx common: 0x%lx\n",
- cfg.flags, bus_flags, common_flags);
-
- /* Make choices, based on platform preferences */
- if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
- (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
- if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
- else
- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
- }
-
- if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
- (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
- if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
- else
- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
- }
-
- if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
- (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
- if (mx3_cam->platform_flags & MX3_CAMERA_DP)
- common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
- else
- common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
- }
-
- if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
- (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
- if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
- else
- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
- }
-
- cfg.flags = common_flags;
- ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
- if (ret < 0 && ret != -ENOIOCTLCMD) {
- dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n",
- common_flags, ret);
- return ret;
- }
-
- /*
- * So far only gated clock mode is supported. Add a line
- * (3 << CSI_SENS_CONF_SENS_PRTCL_SHIFT) |
- * below and select the required mode when supporting other
- * synchronisation protocols.
- */
- sens_conf = csi_reg_read(mx3_cam, CSI_SENS_CONF) &
- ~((1 << CSI_SENS_CONF_VSYNC_POL_SHIFT) |
- (1 << CSI_SENS_CONF_HSYNC_POL_SHIFT) |
- (1 << CSI_SENS_CONF_DATA_POL_SHIFT) |
- (1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT) |
- (3 << CSI_SENS_CONF_DATA_FMT_SHIFT) |
- (3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT));
-
- /* TODO: Support RGB and YUV formats */
-
- /* This has been set in mx3_camera_activate(), but we clear it above */
- sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
-
- if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
- sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
- if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
- sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
- if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
- sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
- if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
- sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
-
- /* Just do what we're asked to do */
- switch (xlate->host_fmt->bits_per_sample) {
- case 4:
- dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
- break;
- case 8:
- dw = 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
- break;
- case 10:
- dw = 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
- break;
- default:
- /*
- * Actually it can only be 15 now, default is just to silence
- * compiler warnings
- */
- case 15:
- dw = 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
- }
-
- csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF);
-
- dev_dbg(dev, "Set SENS_CONF to %x\n", sens_conf | dw);
-
- return 0;
-}
-
-static struct soc_camera_host_ops mx3_soc_camera_host_ops = {
- .owner = THIS_MODULE,
- .add = mx3_camera_add_device,
- .remove = mx3_camera_remove_device,
- .set_crop = mx3_camera_set_crop,
- .set_fmt = mx3_camera_set_fmt,
- .try_fmt = mx3_camera_try_fmt,
- .get_formats = mx3_camera_get_formats,
- .init_videobuf2 = mx3_camera_init_videobuf,
- .reqbufs = mx3_camera_reqbufs,
- .poll = mx3_camera_poll,
- .querycap = mx3_camera_querycap,
- .set_bus_param = mx3_camera_set_bus_param,
-};
-
-static int __devinit mx3_camera_probe(struct platform_device *pdev)
-{
- struct mx3_camera_dev *mx3_cam;
- struct resource *res;
- void __iomem *base;
- int err = 0;
- struct soc_camera_host *soc_host;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- err = -ENODEV;
- goto egetres;
- }
-
- mx3_cam = vzalloc(sizeof(*mx3_cam));
- if (!mx3_cam) {
- dev_err(&pdev->dev, "Could not allocate mx3 camera object\n");
- err = -ENOMEM;
- goto ealloc;
- }
-
- mx3_cam->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(mx3_cam->clk)) {
- err = PTR_ERR(mx3_cam->clk);
- goto eclkget;
- }
-
- mx3_cam->pdata = pdev->dev.platform_data;
- mx3_cam->platform_flags = mx3_cam->pdata->flags;
- if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 |
- MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10 |
- MX3_CAMERA_DATAWIDTH_15))) {
- /*
- * Platform hasn't set available data widths. This is bad.
- * Warn and use a default.
- */
- dev_warn(&pdev->dev, "WARNING! Platform hasn't set available "
- "data widths, using default 8 bit\n");
- mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8;
- }
- if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)
- mx3_cam->width_flags = 1 << 3;
- if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
- mx3_cam->width_flags |= 1 << 7;
- if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
- mx3_cam->width_flags |= 1 << 9;
- if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
- mx3_cam->width_flags |= 1 << 14;
-
- mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000;
- if (!mx3_cam->mclk) {
- dev_warn(&pdev->dev,
- "mclk_10khz == 0! Please, fix your platform data. "
- "Using default 20MHz\n");
- mx3_cam->mclk = 20000000;
- }
-
- /* list of video-buffers */
- INIT_LIST_HEAD(&mx3_cam->capture);
- spin_lock_init(&mx3_cam->lock);
-
- base = ioremap(res->start, resource_size(res));
- if (!base) {
- pr_err("Couldn't map %x@%x\n", resource_size(res), res->start);
- err = -ENOMEM;
- goto eioremap;
- }
-
- mx3_cam->base = base;
-
- soc_host = &mx3_cam->soc_host;
- soc_host->drv_name = MX3_CAM_DRV_NAME;
- soc_host->ops = &mx3_soc_camera_host_ops;
- soc_host->priv = mx3_cam;
- soc_host->v4l2_dev.dev = &pdev->dev;
- soc_host->nr = pdev->id;
-
- mx3_cam->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
- if (IS_ERR(mx3_cam->alloc_ctx)) {
- err = PTR_ERR(mx3_cam->alloc_ctx);
- goto eallocctx;
- }
-
- err = soc_camera_host_register(soc_host);
- if (err)
- goto ecamhostreg;
-
- /* IDMAC interface */
- dmaengine_get();
-
- return 0;
-
-ecamhostreg:
- vb2_dma_contig_cleanup_ctx(mx3_cam->alloc_ctx);
-eallocctx:
- iounmap(base);
-eioremap:
- clk_put(mx3_cam->clk);
-eclkget:
- vfree(mx3_cam);
-ealloc:
-egetres:
- return err;
-}
-
-static int __devexit mx3_camera_remove(struct platform_device *pdev)
-{
- struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
- struct mx3_camera_dev *mx3_cam = container_of(soc_host,
- struct mx3_camera_dev, soc_host);
-
- clk_put(mx3_cam->clk);
-
- soc_camera_host_unregister(soc_host);
-
- iounmap(mx3_cam->base);
-
- /*
- * The channel has either not been allocated,
- * or should have been released
- */
- if (WARN_ON(mx3_cam->idmac_channel[0]))
- dma_release_channel(&mx3_cam->idmac_channel[0]->dma_chan);
-
- vb2_dma_contig_cleanup_ctx(mx3_cam->alloc_ctx);
-
- vfree(mx3_cam);
-
- dmaengine_put();
-
- return 0;
-}
-
-static struct platform_driver mx3_camera_driver = {
- .driver = {
- .name = MX3_CAM_DRV_NAME,
- },
- .probe = mx3_camera_probe,
- .remove = __devexit_p(mx3_camera_remove),
-};
-
-module_platform_driver(mx3_camera_driver);
-
-MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver");
-MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION("0.2.3");
-MODULE_ALIAS("platform:" MX3_CAM_DRV_NAME);
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
deleted file mode 100644
index b520a45cb3f..00000000000
--- a/drivers/media/video/mxb.c
+++ /dev/null
@@ -1,886 +0,0 @@
-/*
- mxb - v4l2 driver for the Multimedia eXtension Board
-
- Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de>
-
- Visit http://www.themm.net/~mihu/linux/saa7146/mxb.html
- for further details about this card.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define DEBUG_VARIABLE debug
-
-#include <media/saa7146_vv.h>
-#include <media/tuner.h>
-#include <media/v4l2-common.h>
-#include <media/saa7115.h>
-#include <linux/module.h>
-
-#include "tea6415c.h"
-#include "tea6420.h"
-
-#define MXB_AUDIOS 6
-
-#define I2C_SAA7111A 0x24
-#define I2C_TDA9840 0x42
-#define I2C_TEA6415C 0x43
-#define I2C_TEA6420_1 0x4c
-#define I2C_TEA6420_2 0x4d
-#define I2C_TUNER 0x60
-
-#define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
-
-/* global variable */
-static int mxb_num;
-
-/* initial frequence the tuner will be tuned to.
- in verden (lower saxony, germany) 4148 is a
- channel called "phoenix" */
-static int freq = 4148;
-module_param(freq, int, 0644);
-MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup");
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
-
-#define MXB_INPUTS 4
-enum { TUNER, AUX1, AUX3, AUX3_YC };
-
-static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
- { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 0x3f, 0,
- V4L2_STD_PAL_BG | V4L2_STD_PAL_I, 0, V4L2_IN_CAP_STD },
- { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0,
- V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0,
- V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
- { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0,
- V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
-};
-
-/* this array holds the information, which port of the saa7146 each
- input actually uses. the mxb uses port 0 for every input */
-static struct {
- int hps_source;
- int hps_sync;
-} input_port_selection[MXB_INPUTS] = {
- { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
- { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
- { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
- { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
-};
-
-/* this array holds the information of the audio source (mxb_audios),
- which has to be switched corresponding to the video source (mxb_channels) */
-static int video_audio_connect[MXB_INPUTS] =
- { 0, 1, 3, 3 };
-
-struct mxb_routing {
- u32 input;
- u32 output;
-};
-
-/* these are the available audio sources, which can switched
- to the line- and cd-output individually */
-static struct v4l2_audio mxb_audios[MXB_AUDIOS] = {
- {
- .index = 0,
- .name = "Tuner",
- .capability = V4L2_AUDCAP_STEREO,
- } , {
- .index = 1,
- .name = "AUX1",
- .capability = V4L2_AUDCAP_STEREO,
- } , {
- .index = 2,
- .name = "AUX2",
- .capability = V4L2_AUDCAP_STEREO,
- } , {
- .index = 3,
- .name = "AUX3",
- .capability = V4L2_AUDCAP_STEREO,
- } , {
- .index = 4,
- .name = "Radio (X9)",
- .capability = V4L2_AUDCAP_STEREO,
- } , {
- .index = 5,
- .name = "CD-ROM (X10)",
- .capability = V4L2_AUDCAP_STEREO,
- }
-};
-
-/* These are the necessary input-output-pins for bringing one audio source
- (see above) to the CD-output. Note that gain is set to 0 in this table. */
-static struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
- { { 1, 1 }, { 1, 1 } }, /* Tuner */
- { { 5, 1 }, { 6, 1 } }, /* AUX 1 */
- { { 4, 1 }, { 6, 1 } }, /* AUX 2 */
- { { 3, 1 }, { 6, 1 } }, /* AUX 3 */
- { { 1, 1 }, { 3, 1 } }, /* Radio */
- { { 1, 1 }, { 2, 1 } }, /* CD-Rom */
- { { 6, 1 }, { 6, 1 } } /* Mute */
-};
-
-/* These are the necessary input-output-pins for bringing one audio source
- (see above) to the line-output. Note that gain is set to 0 in this table. */
-static struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
- { { 2, 3 }, { 1, 2 } },
- { { 5, 3 }, { 6, 2 } },
- { { 4, 3 }, { 6, 2 } },
- { { 3, 3 }, { 6, 2 } },
- { { 2, 3 }, { 3, 2 } },
- { { 2, 3 }, { 2, 2 } },
- { { 6, 3 }, { 6, 2 } } /* Mute */
-};
-
-struct mxb
-{
- struct video_device *video_dev;
- struct video_device *vbi_dev;
-
- struct i2c_adapter i2c_adapter;
-
- struct v4l2_subdev *saa7111a;
- struct v4l2_subdev *tda9840;
- struct v4l2_subdev *tea6415c;
- struct v4l2_subdev *tuner;
- struct v4l2_subdev *tea6420_1;
- struct v4l2_subdev *tea6420_2;
-
- int cur_mode; /* current audio mode (mono, stereo, ...) */
- int cur_input; /* current input */
- int cur_audinput; /* current audio input */
- int cur_mute; /* current mute status */
- struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */
-};
-
-#define saa7111a_call(mxb, o, f, args...) \
- v4l2_subdev_call(mxb->saa7111a, o, f, ##args)
-#define tda9840_call(mxb, o, f, args...) \
- v4l2_subdev_call(mxb->tda9840, o, f, ##args)
-#define tea6415c_call(mxb, o, f, args...) \
- v4l2_subdev_call(mxb->tea6415c, o, f, ##args)
-#define tuner_call(mxb, o, f, args...) \
- v4l2_subdev_call(mxb->tuner, o, f, ##args)
-#define call_all(dev, o, f, args...) \
- v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
-
-static void mxb_update_audmode(struct mxb *mxb)
-{
- struct v4l2_tuner t = {
- .audmode = mxb->cur_mode,
- };
-
- tda9840_call(mxb, tuner, s_tuner, &t);
-}
-
-static inline void tea6420_route(struct mxb *mxb, int idx)
-{
- v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
- TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0);
- v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
- TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0);
- v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
- TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0);
- v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
- TEA6420_line[idx][1].input, TEA6420_line[idx][1].output, 0);
-}
-
-static struct saa7146_extension extension;
-
-static int mxb_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct saa7146_dev *dev = container_of(ctrl->handler,
- struct saa7146_dev, ctrl_handler);
- struct mxb *mxb = dev->ext_priv;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- mxb->cur_mute = ctrl->val;
- /* switch the audio-source */
- tea6420_route(mxb, ctrl->val ? 6 :
- video_audio_connect[mxb->cur_input]);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static const struct v4l2_ctrl_ops mxb_ctrl_ops = {
- .s_ctrl = mxb_s_ctrl,
-};
-
-static int mxb_probe(struct saa7146_dev *dev)
-{
- struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
- struct mxb *mxb = NULL;
-
- v4l2_ctrl_new_std(hdl, &mxb_ctrl_ops,
- V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
- if (hdl->error)
- return hdl->error;
- mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
- if (mxb == NULL) {
- DEB_D("not enough kernel memory\n");
- return -ENOMEM;
- }
-
-
- snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num);
-
- saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
- if (i2c_add_adapter(&mxb->i2c_adapter) < 0) {
- DEB_S("cannot register i2c-device. skipping.\n");
- kfree(mxb);
- return -EFAULT;
- }
-
- mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- "saa7111", I2C_SAA7111A, NULL);
- mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- "tea6420", I2C_TEA6420_1, NULL);
- mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- "tea6420", I2C_TEA6420_2, NULL);
- mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- "tea6415c", I2C_TEA6415C, NULL);
- mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- "tda9840", I2C_TDA9840, NULL);
- mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- "tuner", I2C_TUNER, NULL);
-
- /* check if all devices are present */
- if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
- !mxb->tda9840 || !mxb->saa7111a || !mxb->tuner) {
- pr_err("did not find all i2c devices. aborting\n");
- i2c_del_adapter(&mxb->i2c_adapter);
- kfree(mxb);
- return -ENODEV;
- }
-
- /* all devices are present, probe was successful */
-
- /* we store the pointer in our private data field */
- dev->ext_priv = mxb;
-
- v4l2_ctrl_handler_setup(hdl);
-
- return 0;
-}
-
-/* some init data for the saa7740, the so-called 'sound arena module'.
- there are no specs available, so we simply use some init values */
-static struct {
- int length;
- char data[9];
-} mxb_saa7740_init[] = {
- { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
- { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
- { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
- { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
- { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
- { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
- { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
- { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
- { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
- { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
- { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
- { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
- { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
- { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
- { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
- { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
- { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
- { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
- { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
- { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
- { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
- { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
- { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
- { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
- { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
- { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
- { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
- { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
- { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
- { 3, { 0x48, 0x00, 0x01 } },
- { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
- { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
- { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
- { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
- { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
- { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
- { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
- { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
- { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
- { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
- { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
- { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
- { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
- { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
- { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
- { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
- { 3, { 0x80, 0xb3, 0x0a } },
- {-1, { 0 } }
-};
-
-/* bring hardware to a sane state. this has to be done, just in case someone
- wants to capture from this device before it has been properly initialized.
- the capture engine would badly fail, because no valid signal arrives on the
- saa7146, thus leading to timeouts and stuff. */
-static int mxb_init_done(struct saa7146_dev* dev)
-{
- struct mxb* mxb = (struct mxb*)dev->ext_priv;
- struct i2c_msg msg;
- struct tuner_setup tun_setup;
- v4l2_std_id std = V4L2_STD_PAL_BG;
-
- int i = 0, err = 0;
-
- /* mute audio on tea6420s */
- tea6420_route(mxb, 6);
-
- /* select video mode in saa7111a */
- saa7111a_call(mxb, core, s_std, std);
-
- /* select tuner-output on saa7111a */
- i = 0;
- saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
- SAA7111_FMT_CCIR, 0);
-
- /* select a tuner type */
- tun_setup.mode_mask = T_ANALOG_TV;
- tun_setup.addr = ADDR_UNSET;
- tun_setup.type = TUNER_PHILIPS_PAL;
- tuner_call(mxb, tuner, s_type_addr, &tun_setup);
- /* tune in some frequency on tuner */
- mxb->cur_freq.tuner = 0;
- mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
- mxb->cur_freq.frequency = freq;
- tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
-
- /* set a default video standard */
- /* These two gpio calls set the GPIO pins that control the tda9820 */
- saa7146_write(dev, GPIO_CTRL, 0x00404050);
- saa7111a_call(mxb, core, s_gpio, 1);
- saa7111a_call(mxb, core, s_std, std);
- tuner_call(mxb, core, s_std, std);
-
- /* switch to tuner-channel on tea6415c */
- tea6415c_call(mxb, video, s_routing, 3, 17, 0);
-
- /* select tuner-output on multicable on tea6415c */
- tea6415c_call(mxb, video, s_routing, 3, 13, 0);
-
- /* the rest for mxb */
- mxb->cur_input = 0;
- mxb->cur_audinput = video_audio_connect[mxb->cur_input];
- mxb->cur_mute = 1;
-
- mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
- mxb_update_audmode(mxb);
-
- /* check if the saa7740 (aka 'sound arena module') is present
- on the mxb. if so, we must initialize it. due to lack of
- informations about the saa7740, the values were reverse
- engineered. */
- msg.addr = 0x1b;
- msg.flags = 0;
- msg.len = mxb_saa7740_init[0].length;
- msg.buf = &mxb_saa7740_init[0].data[0];
-
- err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
- if (err == 1) {
- /* the sound arena module is a pos, that's probably the reason
- philips refuses to hand out a datasheet for the saa7740...
- it seems to screw up the i2c bus, so we disable fast irq
- based i2c transactions here and rely on the slow and safe
- polling method ... */
- extension.flags &= ~SAA7146_USE_I2C_IRQ;
- for (i = 1; ; i++) {
- if (-1 == mxb_saa7740_init[i].length)
- break;
-
- msg.len = mxb_saa7740_init[i].length;
- msg.buf = &mxb_saa7740_init[i].data[0];
- err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
- if (err != 1) {
- DEB_D("failed to initialize 'sound arena module'\n");
- goto err;
- }
- }
- pr_info("'sound arena module' detected\n");
- }
-err:
- /* the rest for saa7146: you should definitely set some basic values
- for the input-port handling of the saa7146. */
-
- /* ext->saa has been filled by the core driver */
-
- /* some stuff is done via variables */
- saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source,
- input_port_selection[mxb->cur_input].hps_sync);
-
- /* some stuff is done via direct write to the registers */
-
- /* this is ugly, but because of the fact that this is completely
- hardware dependend, it should be done directly... */
- saa7146_write(dev, DD1_STREAM_B, 0x00000000);
- saa7146_write(dev, DD1_INIT, 0x02000200);
- saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-
- return 0;
-}
-
-/* interrupt-handler. this gets called when irq_mask is != 0.
- it must clear the interrupt-bits in irq_mask it has handled */
-/*
-void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
-{
- struct mxb* mxb = (struct mxb*)dev->ext_priv;
-}
-*/
-
-static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
-{
- DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index);
- if (i->index >= MXB_INPUTS)
- return -EINVAL;
- memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- struct mxb *mxb = (struct mxb *)dev->ext_priv;
- *i = mxb->cur_input;
-
- DEB_EE("VIDIOC_G_INPUT %d\n", *i);
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- struct mxb *mxb = (struct mxb *)dev->ext_priv;
- int err = 0;
- int i = 0;
-
- DEB_EE("VIDIOC_S_INPUT %d\n", input);
-
- if (input >= MXB_INPUTS)
- return -EINVAL;
-
- mxb->cur_input = input;
-
- saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
- input_port_selection[input].hps_sync);
-
- /* prepare switching of tea6415c and saa7111a;
- have a look at the 'background'-file for further informations */
- switch (input) {
- case TUNER:
- i = SAA7115_COMPOSITE0;
-
- err = tea6415c_call(mxb, video, s_routing, 3, 17, 0);
-
- /* connect tuner-output always to multicable */
- if (!err)
- err = tea6415c_call(mxb, video, s_routing, 3, 13, 0);
- break;
- case AUX3_YC:
- /* nothing to be done here. aux3_yc is
- directly connected to the saa711a */
- i = SAA7115_SVIDEO1;
- break;
- case AUX3:
- /* nothing to be done here. aux3 is
- directly connected to the saa711a */
- i = SAA7115_COMPOSITE1;
- break;
- case AUX1:
- i = SAA7115_COMPOSITE0;
- err = tea6415c_call(mxb, video, s_routing, 1, 17, 0);
- break;
- }
-
- if (err)
- return err;
-
- /* switch video in saa7111a */
- if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0))
- pr_err("VIDIOC_S_INPUT: could not address saa7111a\n");
-
- mxb->cur_audinput = video_audio_connect[input];
- /* switch the audio-source only if necessary */
- if (0 == mxb->cur_mute)
- tea6420_route(mxb, mxb->cur_audinput);
- if (mxb->cur_audinput == 0)
- mxb_update_audmode(mxb);
-
- return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- struct mxb *mxb = (struct mxb *)dev->ext_priv;
-
- if (t->index) {
- DEB_D("VIDIOC_G_TUNER: channel %d does not have a tuner attached\n",
- t->index);
- return -EINVAL;
- }
-
- DEB_EE("VIDIOC_G_TUNER: %d\n", t->index);
-
- memset(t, 0, sizeof(*t));
- strlcpy(t->name, "TV Tuner", sizeof(t->name));
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
- V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
- t->audmode = mxb->cur_mode;
- return call_all(dev, tuner, g_tuner, t);
-}
-
-static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- struct mxb *mxb = (struct mxb *)dev->ext_priv;
-
- if (t->index) {
- DEB_D("VIDIOC_S_TUNER: channel %d does not have a tuner attached\n",
- t->index);
- return -EINVAL;
- }
-
- mxb->cur_mode = t->audmode;
- return call_all(dev, tuner, s_tuner, t);
-}
-
-static int vidioc_querystd(struct file *file, void *fh, v4l2_std_id *norm)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-
- return call_all(dev, video, querystd, norm);
-}
-
-static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- struct mxb *mxb = (struct mxb *)dev->ext_priv;
-
- if (f->tuner)
- return -EINVAL;
- *f = mxb->cur_freq;
-
- DEB_EE("VIDIOC_G_FREQ: freq:0x%08x\n", mxb->cur_freq.frequency);
- return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- struct mxb *mxb = (struct mxb *)dev->ext_priv;
- struct saa7146_vv *vv = dev->vv_data;
-
- if (f->tuner)
- return -EINVAL;
-
- if (V4L2_TUNER_ANALOG_TV != f->type)
- return -EINVAL;
-
- DEB_EE("VIDIOC_S_FREQUENCY: freq:0x%08x\n", mxb->cur_freq.frequency);
-
- /* tune in desired frequency */
- tuner_call(mxb, tuner, s_frequency, f);
- /* let the tuner subdev clamp the frequency to the tuner range */
- tuner_call(mxb, tuner, g_frequency, f);
- mxb->cur_freq = *f;
- if (mxb->cur_audinput == 0)
- mxb_update_audmode(mxb);
-
- if (mxb->cur_input)
- return 0;
-
- /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
- spin_lock(&dev->slock);
- vv->vbi_fieldcount = 0;
- spin_unlock(&dev->slock);
-
- return 0;
-}
-
-static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
-{
- if (a->index >= MXB_AUDIOS)
- return -EINVAL;
- *a = mxb_audios[a->index];
- return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- struct mxb *mxb = (struct mxb *)dev->ext_priv;
-
- DEB_EE("VIDIOC_G_AUDIO\n");
- *a = mxb_audios[mxb->cur_audinput];
- return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- struct mxb *mxb = (struct mxb *)dev->ext_priv;
-
- DEB_D("VIDIOC_S_AUDIO %d\n", a->index);
- if (mxb_inputs[mxb->cur_input].audioset & (1 << a->index)) {
- if (mxb->cur_audinput != a->index) {
- mxb->cur_audinput = a->index;
- tea6420_route(mxb, a->index);
- if (mxb->cur_audinput == 0)
- mxb_update_audmode(mxb);
- }
- return 0;
- }
- return -EINVAL;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (v4l2_chip_match_host(&reg->match)) {
- reg->val = saa7146_read(dev, reg->reg);
- reg->size = 4;
- return 0;
- }
- call_all(dev, core, g_register, reg);
- return 0;
-}
-
-static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
-{
- struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (v4l2_chip_match_host(&reg->match)) {
- saa7146_write(dev, reg->reg, reg->val);
- reg->size = 4;
- return 0;
- }
- return call_all(dev, core, s_register, reg);
-}
-#endif
-
-static struct saa7146_ext_vv vv_data;
-
-/* this function only gets called when the probing was successful */
-static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
-{
- struct mxb *mxb;
-
- DEB_EE("dev:%p\n", dev);
-
- saa7146_vv_init(dev, &vv_data);
- if (mxb_probe(dev)) {
- saa7146_vv_release(dev);
- return -1;
- }
- mxb = (struct mxb *)dev->ext_priv;
-
- vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
- vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
- vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
- vv_data.vid_ops.vidioc_querystd = vidioc_querystd;
- vv_data.vid_ops.vidioc_g_tuner = vidioc_g_tuner;
- vv_data.vid_ops.vidioc_s_tuner = vidioc_s_tuner;
- vv_data.vid_ops.vidioc_g_frequency = vidioc_g_frequency;
- vv_data.vid_ops.vidioc_s_frequency = vidioc_s_frequency;
- vv_data.vid_ops.vidioc_enumaudio = vidioc_enumaudio;
- vv_data.vid_ops.vidioc_g_audio = vidioc_g_audio;
- vv_data.vid_ops.vidioc_s_audio = vidioc_s_audio;
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- vv_data.vid_ops.vidioc_g_register = vidioc_g_register;
- vv_data.vid_ops.vidioc_s_register = vidioc_s_register;
-#endif
- if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
- ERR("cannot register capture v4l2 device. skipping.\n");
- saa7146_vv_release(dev);
- return -1;
- }
-
- /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
- if (MXB_BOARD_CAN_DO_VBI(dev)) {
- if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
- ERR("cannot register vbi v4l2 device. skipping.\n");
- }
- }
-
- pr_info("found Multimedia eXtension Board #%d\n", mxb_num);
-
- mxb_num++;
- mxb_init_done(dev);
- return 0;
-}
-
-static int mxb_detach(struct saa7146_dev *dev)
-{
- struct mxb *mxb = (struct mxb *)dev->ext_priv;
-
- DEB_EE("dev:%p\n", dev);
-
- /* mute audio on tea6420s */
- tea6420_route(mxb, 6);
-
- saa7146_unregister_device(&mxb->video_dev,dev);
- if (MXB_BOARD_CAN_DO_VBI(dev))
- saa7146_unregister_device(&mxb->vbi_dev, dev);
- saa7146_vv_release(dev);
-
- mxb_num--;
-
- i2c_del_adapter(&mxb->i2c_adapter);
- kfree(mxb);
-
- return 0;
-}
-
-static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
-{
- struct mxb *mxb = (struct mxb *)dev->ext_priv;
-
- if (V4L2_STD_PAL_I == standard->id) {
- v4l2_std_id std = V4L2_STD_PAL_I;
-
- DEB_D("VIDIOC_S_STD: setting mxb for PAL_I\n");
- /* These two gpio calls set the GPIO pins that control the tda9820 */
- saa7146_write(dev, GPIO_CTRL, 0x00404050);
- saa7111a_call(mxb, core, s_gpio, 0);
- saa7111a_call(mxb, core, s_std, std);
- if (mxb->cur_input == 0)
- tuner_call(mxb, core, s_std, std);
- } else {
- v4l2_std_id std = V4L2_STD_PAL_BG;
-
- if (mxb->cur_input)
- std = standard->id;
- DEB_D("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM\n");
- /* These two gpio calls set the GPIO pins that control the tda9820 */
- saa7146_write(dev, GPIO_CTRL, 0x00404050);
- saa7111a_call(mxb, core, s_gpio, 1);
- saa7111a_call(mxb, core, s_std, std);
- if (mxb->cur_input == 0)
- tuner_call(mxb, core, s_std, std);
- }
- return 0;
-}
-
-static struct saa7146_standard standard[] = {
- {
- .name = "PAL-BG", .id = V4L2_STD_PAL_BG,
- .v_offset = 0x17, .v_field = 288,
- .h_offset = 0x14, .h_pixels = 680,
- .v_max_out = 576, .h_max_out = 768,
- }, {
- .name = "PAL-I", .id = V4L2_STD_PAL_I,
- .v_offset = 0x17, .v_field = 288,
- .h_offset = 0x14, .h_pixels = 680,
- .v_max_out = 576, .h_max_out = 768,
- }, {
- .name = "NTSC", .id = V4L2_STD_NTSC,
- .v_offset = 0x16, .v_field = 240,
- .h_offset = 0x06, .h_pixels = 708,
- .v_max_out = 480, .h_max_out = 640,
- }, {
- .name = "SECAM", .id = V4L2_STD_SECAM,
- .v_offset = 0x14, .v_field = 288,
- .h_offset = 0x14, .h_pixels = 720,
- .v_max_out = 576, .h_max_out = 768,
- }
-};
-
-static struct saa7146_pci_extension_data mxb = {
- .ext_priv = "Multimedia eXtension Board",
- .ext = &extension,
-};
-
-static struct pci_device_id pci_tbl[] = {
- {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
- .subvendor = 0x0000,
- .subdevice = 0x0000,
- .driver_data = (unsigned long)&mxb,
- }, {
- .vendor = 0,
- }
-};
-
-MODULE_DEVICE_TABLE(pci, pci_tbl);
-
-static struct saa7146_ext_vv vv_data = {
- .inputs = MXB_INPUTS,
- .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_AUDIO,
- .stds = &standard[0],
- .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
- .std_callback = &std_callback,
-};
-
-static struct saa7146_extension extension = {
- .name = "Multimedia eXtension Board",
- .flags = SAA7146_USE_I2C_IRQ,
-
- .pci_tbl = &pci_tbl[0],
- .module = THIS_MODULE,
-
- .attach = mxb_attach,
- .detach = mxb_detach,
-
- .irq_mask = 0,
- .irq_func = NULL,
-};
-
-static int __init mxb_init_module(void)
-{
- if (saa7146_register_extension(&extension)) {
- DEB_S("failed to register extension\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-static void __exit mxb_cleanup_module(void)
-{
- saa7146_unregister_extension(&extension);
-}
-
-module_init(mxb_init_module);
-module_exit(mxb_cleanup_module);
-
-MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
-MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/noon010pc30.c b/drivers/media/video/noon010pc30.c
deleted file mode 100644
index 440c12962ba..00000000000
--- a/drivers/media/video/noon010pc30.c
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * Driver for SiliconFile NOON010PC30 CIF (1/11") Image Sensor with ISP
- *
- * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd.
- * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com>
- *
- * Initial register configuration based on a driver authored by
- * HeungJun Kim <riverful.kim@samsung.com>.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/regulator/consumer.h>
-#include <media/noon010pc30.h>
-#include <media/v4l2-chip-ident.h>
-#include <linux/videodev2.h>
-#include <linux/module.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-mediabus.h>
-#include <media/v4l2-subdev.h>
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Enable module debug trace. Set to 1 to enable.");
-
-#define MODULE_NAME "NOON010PC30"
-
-/*
- * Register offsets within a page
- * b15..b8 - page id, b7..b0 - register address
- */
-#define POWER_CTRL_REG 0x0001
-#define PAGEMODE_REG 0x03
-#define DEVICE_ID_REG 0x0004
-#define NOON010PC30_ID 0x86
-#define VDO_CTL_REG(n) (0x0010 + (n))
-#define SYNC_CTL_REG 0x0012
-/* Window size and position */
-#define WIN_ROWH_REG 0x0013
-#define WIN_ROWL_REG 0x0014
-#define WIN_COLH_REG 0x0015
-#define WIN_COLL_REG 0x0016
-#define WIN_HEIGHTH_REG 0x0017
-#define WIN_HEIGHTL_REG 0x0018
-#define WIN_WIDTHH_REG 0x0019
-#define WIN_WIDTHL_REG 0x001A
-#define HBLANKH_REG 0x001B
-#define HBLANKL_REG 0x001C
-#define VSYNCH_REG 0x001D
-#define VSYNCL_REG 0x001E
-/* VSYNC control */
-#define VS_CTL_REG(n) (0x00A1 + (n))
-/* page 1 */
-#define ISP_CTL_REG(n) (0x0110 + (n))
-#define YOFS_REG 0x0119
-#define DARK_YOFS_REG 0x011A
-#define SAT_CTL_REG 0x0120
-#define BSAT_REG 0x0121
-#define RSAT_REG 0x0122
-/* Color correction */
-#define CMC_CTL_REG 0x0130
-#define CMC_OFSGH_REG 0x0133
-#define CMC_OFSGL_REG 0x0135
-#define CMC_SIGN_REG 0x0136
-#define CMC_GOFS_REG 0x0137
-#define CMC_COEF_REG(n) (0x0138 + (n))
-#define CMC_OFS_REG(n) (0x0141 + (n))
-/* Gamma correction */
-#define GMA_CTL_REG 0x0160
-#define GMA_COEF_REG(n) (0x0161 + (n))
-/* Lens Shading */
-#define LENS_CTRL_REG 0x01D0
-#define LENS_XCEN_REG 0x01D1
-#define LENS_YCEN_REG 0x01D2
-#define LENS_RC_REG 0x01D3
-#define LENS_GC_REG 0x01D4
-#define LENS_BC_REG 0x01D5
-#define L_AGON_REG 0x01D6
-#define L_AGOFF_REG 0x01D7
-/* Page 3 - Auto Exposure */
-#define AE_CTL_REG(n) (0x0310 + (n))
-#define AE_CTL9_REG 0x032C
-#define AE_CTL10_REG 0x032D
-#define AE_YLVL_REG 0x031C
-#define AE_YTH_REG(n) (0x031D + (n))
-#define AE_WGT_REG 0x0326
-#define EXP_TIMEH_REG 0x0333
-#define EXP_TIMEM_REG 0x0334
-#define EXP_TIMEL_REG 0x0335
-#define EXP_MMINH_REG 0x0336
-#define EXP_MMINL_REG 0x0337
-#define EXP_MMAXH_REG 0x0338
-#define EXP_MMAXM_REG 0x0339
-#define EXP_MMAXL_REG 0x033A
-/* Page 4 - Auto White Balance */
-#define AWB_CTL_REG(n) (0x0410 + (n))
-#define AWB_ENABE 0x80
-#define AWB_WGHT_REG 0x0419
-#define BGAIN_PAR_REG(n) (0x044F + (n))
-/* Manual white balance, when AWB_CTL2[0]=1 */
-#define MWB_RGAIN_REG 0x0466
-#define MWB_BGAIN_REG 0x0467
-
-/* The token to mark an array end */
-#define REG_TERM 0xFFFF
-
-struct noon010_format {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
- u16 ispctl1_reg;
-};
-
-struct noon010_frmsize {
- u16 width;
- u16 height;
- int vid_ctl1;
-};
-
-static const char * const noon010_supply_name[] = {
- "vdd_core", "vddio", "vdda"
-};
-
-#define NOON010_NUM_SUPPLIES ARRAY_SIZE(noon010_supply_name)
-
-struct noon010_info {
- struct v4l2_subdev sd;
- struct media_pad pad;
- struct v4l2_ctrl_handler hdl;
- struct regulator_bulk_data supply[NOON010_NUM_SUPPLIES];
- u32 gpio_nreset;
- u32 gpio_nstby;
-
- /* Protects the struct members below */
- struct mutex lock;
-
- const struct noon010_format *curr_fmt;
- const struct noon010_frmsize *curr_win;
- unsigned int apply_new_cfg:1;
- unsigned int streaming:1;
- unsigned int hflip:1;
- unsigned int vflip:1;
- unsigned int power:1;
- u8 i2c_reg_page;
-};
-
-struct i2c_regval {
- u16 addr;
- u16 val;
-};
-
-/* Supported resolutions. */
-static const struct noon010_frmsize noon010_sizes[] = {
- {
- .width = 352,
- .height = 288,
- .vid_ctl1 = 0,
- }, {
- .width = 176,
- .height = 144,
- .vid_ctl1 = 0x10,
- }, {
- .width = 88,
- .height = 72,
- .vid_ctl1 = 0x20,
- },
-};
-
-/* Supported pixel formats. */
-static const struct noon010_format noon010_formats[] = {
- {
- .code = V4L2_MBUS_FMT_YUYV8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .ispctl1_reg = 0x03,
- }, {
- .code = V4L2_MBUS_FMT_YVYU8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .ispctl1_reg = 0x02,
- }, {
- .code = V4L2_MBUS_FMT_VYUY8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .ispctl1_reg = 0,
- }, {
- .code = V4L2_MBUS_FMT_UYVY8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .ispctl1_reg = 0x01,
- }, {
- .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .ispctl1_reg = 0x40,
- },
-};
-
-static const struct i2c_regval noon010_base_regs[] = {
- { WIN_COLL_REG, 0x06 }, { HBLANKL_REG, 0x7C },
- /* Color corection and saturation */
- { ISP_CTL_REG(0), 0x30 }, { ISP_CTL_REG(2), 0x30 },
- { YOFS_REG, 0x80 }, { DARK_YOFS_REG, 0x04 },
- { SAT_CTL_REG, 0x1F }, { BSAT_REG, 0x90 },
- { CMC_CTL_REG, 0x0F }, { CMC_OFSGH_REG, 0x3C },
- { CMC_OFSGL_REG, 0x2C }, { CMC_SIGN_REG, 0x3F },
- { CMC_COEF_REG(0), 0x79 }, { CMC_OFS_REG(0), 0x00 },
- { CMC_COEF_REG(1), 0x39 }, { CMC_OFS_REG(1), 0x00 },
- { CMC_COEF_REG(2), 0x00 }, { CMC_OFS_REG(2), 0x00 },
- { CMC_COEF_REG(3), 0x11 }, { CMC_OFS_REG(3), 0x8B },
- { CMC_COEF_REG(4), 0x65 }, { CMC_OFS_REG(4), 0x07 },
- { CMC_COEF_REG(5), 0x14 }, { CMC_OFS_REG(5), 0x04 },
- { CMC_COEF_REG(6), 0x01 }, { CMC_OFS_REG(6), 0x9C },
- { CMC_COEF_REG(7), 0x33 }, { CMC_OFS_REG(7), 0x89 },
- { CMC_COEF_REG(8), 0x74 }, { CMC_OFS_REG(8), 0x25 },
- /* Automatic white balance */
- { AWB_CTL_REG(0), 0x78 }, { AWB_CTL_REG(1), 0x2E },
- { AWB_CTL_REG(2), 0x20 }, { AWB_CTL_REG(3), 0x85 },
- /* Auto exposure */
- { AE_CTL_REG(0), 0xDC }, { AE_CTL_REG(1), 0x81 },
- { AE_CTL_REG(2), 0x30 }, { AE_CTL_REG(3), 0xA5 },
- { AE_CTL_REG(4), 0x40 }, { AE_CTL_REG(5), 0x51 },
- { AE_CTL_REG(6), 0x33 }, { AE_CTL_REG(7), 0x7E },
- { AE_CTL9_REG, 0x00 }, { AE_CTL10_REG, 0x02 },
- { AE_YLVL_REG, 0x44 }, { AE_YTH_REG(0), 0x34 },
- { AE_YTH_REG(1), 0x30 }, { AE_WGT_REG, 0xD5 },
- /* Lens shading compensation */
- { LENS_CTRL_REG, 0x01 }, { LENS_XCEN_REG, 0x80 },
- { LENS_YCEN_REG, 0x70 }, { LENS_RC_REG, 0x53 },
- { LENS_GC_REG, 0x40 }, { LENS_BC_REG, 0x3E },
- { REG_TERM, 0 },
-};
-
-static inline struct noon010_info *to_noon010(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct noon010_info, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct noon010_info, hdl)->sd;
-}
-
-static inline int set_i2c_page(struct noon010_info *info,
- struct i2c_client *client, unsigned int reg)
-{
- u32 page = reg >> 8 & 0xFF;
- int ret = 0;
-
- if (info->i2c_reg_page != page && (reg & 0xFF) != 0x03) {
- ret = i2c_smbus_write_byte_data(client, PAGEMODE_REG, page);
- if (!ret)
- info->i2c_reg_page = page;
- }
- return ret;
-}
-
-static int cam_i2c_read(struct v4l2_subdev *sd, u32 reg_addr)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct noon010_info *info = to_noon010(sd);
- int ret = set_i2c_page(info, client, reg_addr);
-
- if (ret)
- return ret;
- return i2c_smbus_read_byte_data(client, reg_addr & 0xFF);
-}
-
-static int cam_i2c_write(struct v4l2_subdev *sd, u32 reg_addr, u32 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct noon010_info *info = to_noon010(sd);
- int ret = set_i2c_page(info, client, reg_addr);
-
- if (ret)
- return ret;
- return i2c_smbus_write_byte_data(client, reg_addr & 0xFF, val);
-}
-
-static inline int noon010_bulk_write_reg(struct v4l2_subdev *sd,
- const struct i2c_regval *msg)
-{
- while (msg->addr != REG_TERM) {
- int ret = cam_i2c_write(sd, msg->addr, msg->val);
-
- if (ret)
- return ret;
- msg++;
- }
- return 0;
-}
-
-/* Device reset and sleep mode control */
-static int noon010_power_ctrl(struct v4l2_subdev *sd, bool reset, bool sleep)
-{
- struct noon010_info *info = to_noon010(sd);
- u8 reg = sleep ? 0xF1 : 0xF0;
- int ret = 0;
-
- if (reset) {
- ret = cam_i2c_write(sd, POWER_CTRL_REG, reg | 0x02);
- udelay(20);
- }
- if (!ret) {
- ret = cam_i2c_write(sd, POWER_CTRL_REG, reg);
- if (reset && !ret)
- info->i2c_reg_page = -1;
- }
- return ret;
-}
-
-/* Automatic white balance control */
-static int noon010_enable_autowhitebalance(struct v4l2_subdev *sd, int on)
-{
- int ret;
-
- ret = cam_i2c_write(sd, AWB_CTL_REG(1), on ? 0x2E : 0x2F);
- if (!ret)
- ret = cam_i2c_write(sd, AWB_CTL_REG(0), on ? 0xFB : 0x7B);
- return ret;
-}
-
-/* Called with struct noon010_info.lock mutex held */
-static int noon010_set_flip(struct v4l2_subdev *sd, int hflip, int vflip)
-{
- struct noon010_info *info = to_noon010(sd);
- int reg, ret;
-
- reg = cam_i2c_read(sd, VDO_CTL_REG(1));
- if (reg < 0)
- return reg;
-
- reg &= 0x7C;
- if (hflip)
- reg |= 0x01;
- if (vflip)
- reg |= 0x02;
-
- ret = cam_i2c_write(sd, VDO_CTL_REG(1), reg | 0x80);
- if (!ret) {
- info->hflip = hflip;
- info->vflip = vflip;
- }
- return ret;
-}
-
-/* Configure resolution and color format */
-static int noon010_set_params(struct v4l2_subdev *sd)
-{
- struct noon010_info *info = to_noon010(sd);
-
- int ret = cam_i2c_write(sd, VDO_CTL_REG(0),
- info->curr_win->vid_ctl1);
- if (ret)
- return ret;
- return cam_i2c_write(sd, ISP_CTL_REG(0),
- info->curr_fmt->ispctl1_reg);
-}
-
-/* Find nearest matching image pixel size. */
-static int noon010_try_frame_size(struct v4l2_mbus_framefmt *mf,
- const struct noon010_frmsize **size)
-{
- unsigned int min_err = ~0;
- int i = ARRAY_SIZE(noon010_sizes);
- const struct noon010_frmsize *fsize = &noon010_sizes[0],
- *match = NULL;
-
- while (i--) {
- int err = abs(fsize->width - mf->width)
- + abs(fsize->height - mf->height);
-
- if (err < min_err) {
- min_err = err;
- match = fsize;
- }
- fsize++;
- }
- if (match) {
- mf->width = match->width;
- mf->height = match->height;
- if (size)
- *size = match;
- return 0;
- }
- return -EINVAL;
-}
-
-/* Called with info.lock mutex held */
-static int power_enable(struct noon010_info *info)
-{
- int ret;
-
- if (info->power) {
- v4l2_info(&info->sd, "%s: sensor is already on\n", __func__);
- return 0;
- }
-
- if (gpio_is_valid(info->gpio_nstby))
- gpio_set_value(info->gpio_nstby, 0);
-
- if (gpio_is_valid(info->gpio_nreset))
- gpio_set_value(info->gpio_nreset, 0);
-
- ret = regulator_bulk_enable(NOON010_NUM_SUPPLIES, info->supply);
- if (ret)
- return ret;
-
- if (gpio_is_valid(info->gpio_nreset)) {
- msleep(50);
- gpio_set_value(info->gpio_nreset, 1);
- }
- if (gpio_is_valid(info->gpio_nstby)) {
- udelay(1000);
- gpio_set_value(info->gpio_nstby, 1);
- }
- if (gpio_is_valid(info->gpio_nreset)) {
- udelay(1000);
- gpio_set_value(info->gpio_nreset, 0);
- msleep(100);
- gpio_set_value(info->gpio_nreset, 1);
- msleep(20);
- }
- info->power = 1;
-
- v4l2_dbg(1, debug, &info->sd, "%s: sensor is on\n", __func__);
- return 0;
-}
-
-/* Called with info.lock mutex held */
-static int power_disable(struct noon010_info *info)
-{
- int ret;
-
- if (!info->power) {
- v4l2_info(&info->sd, "%s: sensor is already off\n", __func__);
- return 0;
- }
-
- ret = regulator_bulk_disable(NOON010_NUM_SUPPLIES, info->supply);
- if (ret)
- return ret;
-
- if (gpio_is_valid(info->gpio_nstby))
- gpio_set_value(info->gpio_nstby, 0);
-
- if (gpio_is_valid(info->gpio_nreset))
- gpio_set_value(info->gpio_nreset, 0);
-
- info->power = 0;
-
- v4l2_dbg(1, debug, &info->sd, "%s: sensor is off\n", __func__);
-
- return 0;
-}
-
-static int noon010_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct noon010_info *info = to_noon010(sd);
- int ret = 0;
-
- v4l2_dbg(1, debug, sd, "%s: ctrl_id: %d, value: %d\n",
- __func__, ctrl->id, ctrl->val);
-
- mutex_lock(&info->lock);
- /*
- * If the device is not powered up by the host driver do
- * not apply any controls to H/W at this time. Instead
- * the controls will be restored right after power-up.
- */
- if (!info->power)
- goto unlock;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTO_WHITE_BALANCE:
- ret = noon010_enable_autowhitebalance(sd, ctrl->val);
- break;
- case V4L2_CID_BLUE_BALANCE:
- ret = cam_i2c_write(sd, MWB_BGAIN_REG, ctrl->val);
- break;
- case V4L2_CID_RED_BALANCE:
- ret = cam_i2c_write(sd, MWB_RGAIN_REG, ctrl->val);
- break;
- default:
- ret = -EINVAL;
- }
-unlock:
- mutex_unlock(&info->lock);
- return ret;
-}
-
-static int noon010_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- if (code->index >= ARRAY_SIZE(noon010_formats))
- return -EINVAL;
-
- code->code = noon010_formats[code->index].code;
- return 0;
-}
-
-static int noon010_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct noon010_info *info = to_noon010(sd);
- struct v4l2_mbus_framefmt *mf;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- if (fh) {
- mf = v4l2_subdev_get_try_format(fh, 0);
- fmt->format = *mf;
- }
- return 0;
- }
- mf = &fmt->format;
-
- mutex_lock(&info->lock);
- mf->width = info->curr_win->width;
- mf->height = info->curr_win->height;
- mf->code = info->curr_fmt->code;
- mf->colorspace = info->curr_fmt->colorspace;
- mf->field = V4L2_FIELD_NONE;
-
- mutex_unlock(&info->lock);
- return 0;
-}
-
-/* Return nearest media bus frame format. */
-static const struct noon010_format *noon010_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- int i = ARRAY_SIZE(noon010_formats);
-
- while (--i)
- if (mf->code == noon010_formats[i].code)
- break;
- mf->code = noon010_formats[i].code;
-
- return &noon010_formats[i];
-}
-
-static int noon010_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct noon010_info *info = to_noon010(sd);
- const struct noon010_frmsize *size = NULL;
- const struct noon010_format *nf;
- struct v4l2_mbus_framefmt *mf;
- int ret = 0;
-
- nf = noon010_try_fmt(sd, &fmt->format);
- noon010_try_frame_size(&fmt->format, &size);
- fmt->format.colorspace = V4L2_COLORSPACE_JPEG;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- if (fh) {
- mf = v4l2_subdev_get_try_format(fh, 0);
- *mf = fmt->format;
- }
- return 0;
- }
- mutex_lock(&info->lock);
- if (!info->streaming) {
- info->apply_new_cfg = 1;
- info->curr_fmt = nf;
- info->curr_win = size;
- } else {
- ret = -EBUSY;
- }
- mutex_unlock(&info->lock);
- return ret;
-}
-
-/* Called with struct noon010_info.lock mutex held */
-static int noon010_base_config(struct v4l2_subdev *sd)
-{
- int ret = noon010_bulk_write_reg(sd, noon010_base_regs);
- if (!ret)
- ret = noon010_set_params(sd);
- if (!ret)
- ret = noon010_set_flip(sd, 1, 0);
-
- return ret;
-}
-
-static int noon010_s_power(struct v4l2_subdev *sd, int on)
-{
- struct noon010_info *info = to_noon010(sd);
- int ret;
-
- mutex_lock(&info->lock);
- if (on) {
- ret = power_enable(info);
- if (!ret)
- ret = noon010_base_config(sd);
- } else {
- noon010_power_ctrl(sd, false, true);
- ret = power_disable(info);
- }
- mutex_unlock(&info->lock);
-
- /* Restore the controls state */
- if (!ret && on)
- ret = v4l2_ctrl_handler_setup(&info->hdl);
-
- return ret;
-}
-
-static int noon010_s_stream(struct v4l2_subdev *sd, int on)
-{
- struct noon010_info *info = to_noon010(sd);
- int ret = 0;
-
- mutex_lock(&info->lock);
- if (!info->streaming != !on) {
- ret = noon010_power_ctrl(sd, false, !on);
- if (!ret)
- info->streaming = on;
- }
- if (!ret && on && info->apply_new_cfg) {
- ret = noon010_set_params(sd);
- if (!ret)
- info->apply_new_cfg = 0;
- }
- mutex_unlock(&info->lock);
- return ret;
-}
-
-static int noon010_log_status(struct v4l2_subdev *sd)
-{
- struct noon010_info *info = to_noon010(sd);
-
- v4l2_ctrl_handler_log_status(&info->hdl, sd->name);
- return 0;
-}
-
-static int noon010_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(fh, 0);
-
- mf->width = noon010_sizes[0].width;
- mf->height = noon010_sizes[0].height;
- mf->code = noon010_formats[0].code;
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- mf->field = V4L2_FIELD_NONE;
- return 0;
-}
-
-static const struct v4l2_subdev_internal_ops noon010_subdev_internal_ops = {
- .open = noon010_open,
-};
-
-static const struct v4l2_ctrl_ops noon010_ctrl_ops = {
- .s_ctrl = noon010_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops noon010_core_ops = {
- .s_power = noon010_s_power,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .log_status = noon010_log_status,
-};
-
-static struct v4l2_subdev_pad_ops noon010_pad_ops = {
- .enum_mbus_code = noon010_enum_mbus_code,
- .get_fmt = noon010_get_fmt,
- .set_fmt = noon010_set_fmt,
-};
-
-static struct v4l2_subdev_video_ops noon010_video_ops = {
- .s_stream = noon010_s_stream,
-};
-
-static const struct v4l2_subdev_ops noon010_ops = {
- .core = &noon010_core_ops,
- .pad = &noon010_pad_ops,
- .video = &noon010_video_ops,
-};
-
-/* Return 0 if NOON010PC30L sensor type was detected or -ENODEV otherwise. */
-static int noon010_detect(struct i2c_client *client, struct noon010_info *info)
-{
- int ret;
-
- ret = power_enable(info);
- if (ret)
- return ret;
-
- ret = i2c_smbus_read_byte_data(client, DEVICE_ID_REG);
- if (ret < 0)
- dev_err(&client->dev, "I2C read failed: 0x%X\n", ret);
-
- power_disable(info);
-
- return ret == NOON010PC30_ID ? 0 : -ENODEV;
-}
-
-static int noon010_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct noon010_info *info;
- struct v4l2_subdev *sd;
- const struct noon010pc30_platform_data *pdata
- = client->dev.platform_data;
- int ret;
- int i;
-
- if (!pdata) {
- dev_err(&client->dev, "No platform data!\n");
- return -EIO;
- }
-
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- mutex_init(&info->lock);
- sd = &info->sd;
- v4l2_i2c_subdev_init(sd, client, &noon010_ops);
- strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
-
- sd->internal_ops = &noon010_subdev_internal_ops;
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- v4l2_ctrl_handler_init(&info->hdl, 3);
-
- v4l2_ctrl_new_std(&info->hdl, &noon010_ctrl_ops,
- V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
- v4l2_ctrl_new_std(&info->hdl, &noon010_ctrl_ops,
- V4L2_CID_RED_BALANCE, 0, 127, 1, 64);
- v4l2_ctrl_new_std(&info->hdl, &noon010_ctrl_ops,
- V4L2_CID_BLUE_BALANCE, 0, 127, 1, 64);
-
- sd->ctrl_handler = &info->hdl;
-
- ret = info->hdl.error;
- if (ret)
- goto np_err;
-
- info->i2c_reg_page = -1;
- info->gpio_nreset = -EINVAL;
- info->gpio_nstby = -EINVAL;
- info->curr_fmt = &noon010_formats[0];
- info->curr_win = &noon010_sizes[0];
-
- if (gpio_is_valid(pdata->gpio_nreset)) {
- ret = gpio_request(pdata->gpio_nreset, "NOON010PC30 NRST");
- if (ret) {
- dev_err(&client->dev, "GPIO request error: %d\n", ret);
- goto np_err;
- }
- info->gpio_nreset = pdata->gpio_nreset;
- gpio_direction_output(info->gpio_nreset, 0);
- gpio_export(info->gpio_nreset, 0);
- }
-
- if (gpio_is_valid(pdata->gpio_nstby)) {
- ret = gpio_request(pdata->gpio_nstby, "NOON010PC30 NSTBY");
- if (ret) {
- dev_err(&client->dev, "GPIO request error: %d\n", ret);
- goto np_gpio_err;
- }
- info->gpio_nstby = pdata->gpio_nstby;
- gpio_direction_output(info->gpio_nstby, 0);
- gpio_export(info->gpio_nstby, 0);
- }
-
- for (i = 0; i < NOON010_NUM_SUPPLIES; i++)
- info->supply[i].supply = noon010_supply_name[i];
-
- ret = regulator_bulk_get(&client->dev, NOON010_NUM_SUPPLIES,
- info->supply);
- if (ret)
- goto np_reg_err;
-
- info->pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
- if (ret < 0)
- goto np_me_err;
-
- ret = noon010_detect(client, info);
- if (!ret)
- return 0;
-
-np_me_err:
- regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
-np_reg_err:
- if (gpio_is_valid(info->gpio_nstby))
- gpio_free(info->gpio_nstby);
-np_gpio_err:
- if (gpio_is_valid(info->gpio_nreset))
- gpio_free(info->gpio_nreset);
-np_err:
- v4l2_ctrl_handler_free(&info->hdl);
- v4l2_device_unregister_subdev(sd);
- kfree(info);
- return ret;
-}
-
-static int noon010_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct noon010_info *info = to_noon010(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&info->hdl);
-
- regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
-
- if (gpio_is_valid(info->gpio_nreset))
- gpio_free(info->gpio_nreset);
-
- if (gpio_is_valid(info->gpio_nstby))
- gpio_free(info->gpio_nstby);
-
- media_entity_cleanup(&sd->entity);
- kfree(info);
- return 0;
-}
-
-static const struct i2c_device_id noon010_id[] = {
- { MODULE_NAME, 0 },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, noon010_id);
-
-
-static struct i2c_driver noon010_i2c_driver = {
- .driver = {
- .name = MODULE_NAME
- },
- .probe = noon010_probe,
- .remove = noon010_remove,
- .id_table = noon010_id,
-};
-
-module_i2c_driver(noon010_i2c_driver);
-
-MODULE_DESCRIPTION("Siliconfile NOON010PC30 camera driver");
-MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/omap/Kconfig b/drivers/media/video/omap/Kconfig
deleted file mode 100644
index 390ab094f9f..00000000000
--- a/drivers/media/video/omap/Kconfig
+++ /dev/null
@@ -1,14 +0,0 @@
-config VIDEO_OMAP2_VOUT_VRFB
- bool
-
-config VIDEO_OMAP2_VOUT
- tristate "OMAP2/OMAP3 V4L2-Display driver"
- depends on ARCH_OMAP2 || ARCH_OMAP3
- select VIDEOBUF_GEN
- select VIDEOBUF_DMA_CONTIG
- select OMAP2_DSS
- select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3
- select VIDEO_OMAP2_VOUT_VRFB if VIDEO_OMAP2_VOUT && OMAP2_VRFB
- default n
- ---help---
- V4L2 Display driver support for OMAP2/3 based boards.
diff --git a/drivers/media/video/omap/Makefile b/drivers/media/video/omap/Makefile
deleted file mode 100644
index fc410b438f7..00000000000
--- a/drivers/media/video/omap/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for the omap video device drivers.
-#
-
-# OMAP2/3 Display driver
-omap-vout-y := omap_vout.o omap_voutlib.o
-omap-vout-$(CONFIG_VIDEO_OMAP2_VOUT_VRFB) += omap_vout_vrfb.o
-obj-$(CONFIG_VIDEO_OMAP2_VOUT) += omap-vout.o
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
deleted file mode 100644
index 409da0f8e5c..00000000000
--- a/drivers/media/video/omap/omap_vout.c
+++ /dev/null
@@ -1,2290 +0,0 @@
-/*
- * omap_vout.c
- *
- * Copyright (C) 2005-2010 Texas Instruments.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- *
- * Leveraged code from the OMAP2 camera driver
- * Video-for-Linux (Version 2) camera capture driver for
- * the OMAP24xx camera controller.
- *
- * Author: Andy Lowe (source@mvista.com)
- *
- * Copyright (C) 2004 MontaVista Software, Inc.
- * Copyright (C) 2010 Texas Instruments.
- *
- * History:
- * 20-APR-2006 Khasim Modified VRFB based Rotation,
- * The image data is always read from 0 degree
- * view and written
- * to the virtual space of desired rotation angle
- * 4-DEC-2006 Jian Changed to support better memory management
- *
- * 17-Nov-2008 Hardik Changed driver to use video_ioctl2
- *
- * 23-Feb-2010 Vaibhav H Modified to use new DSS2 interface
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/videodev2.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-
-#include <media/videobuf-dma-contig.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-
-#include <plat/cpu.h>
-#include <plat/dma.h>
-#include <plat/vrfb.h>
-#include <video/omapdss.h>
-
-#include "omap_voutlib.h"
-#include "omap_voutdef.h"
-#include "omap_vout_vrfb.h"
-
-MODULE_AUTHOR("Texas Instruments");
-MODULE_DESCRIPTION("OMAP Video for Linux Video out driver");
-MODULE_LICENSE("GPL");
-
-/* Driver Configuration macros */
-#define VOUT_NAME "omap_vout"
-
-enum omap_vout_channels {
- OMAP_VIDEO1,
- OMAP_VIDEO2,
-};
-
-static struct videobuf_queue_ops video_vbq_ops;
-/* Variables configurable through module params*/
-static u32 video1_numbuffers = 3;
-static u32 video2_numbuffers = 3;
-static u32 video1_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
-static u32 video2_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
-static bool vid1_static_vrfb_alloc;
-static bool vid2_static_vrfb_alloc;
-static bool debug;
-
-/* Module parameters */
-module_param(video1_numbuffers, uint, S_IRUGO);
-MODULE_PARM_DESC(video1_numbuffers,
- "Number of buffers to be allocated at init time for Video1 device.");
-
-module_param(video2_numbuffers, uint, S_IRUGO);
-MODULE_PARM_DESC(video2_numbuffers,
- "Number of buffers to be allocated at init time for Video2 device.");
-
-module_param(video1_bufsize, uint, S_IRUGO);
-MODULE_PARM_DESC(video1_bufsize,
- "Size of the buffer to be allocated for video1 device");
-
-module_param(video2_bufsize, uint, S_IRUGO);
-MODULE_PARM_DESC(video2_bufsize,
- "Size of the buffer to be allocated for video2 device");
-
-module_param(vid1_static_vrfb_alloc, bool, S_IRUGO);
-MODULE_PARM_DESC(vid1_static_vrfb_alloc,
- "Static allocation of the VRFB buffer for video1 device");
-
-module_param(vid2_static_vrfb_alloc, bool, S_IRUGO);
-MODULE_PARM_DESC(vid2_static_vrfb_alloc,
- "Static allocation of the VRFB buffer for video2 device");
-
-module_param(debug, bool, S_IRUGO);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-/* list of image formats supported by OMAP2 video pipelines */
-static const struct v4l2_fmtdesc omap_formats[] = {
- {
- /* Note: V4L2 defines RGB565 as:
- *
- * Byte 0 Byte 1
- * g2 g1 g0 r4 r3 r2 r1 r0 b4 b3 b2 b1 b0 g5 g4 g3
- *
- * We interpret RGB565 as:
- *
- * Byte 0 Byte 1
- * g2 g1 g0 b4 b3 b2 b1 b0 r4 r3 r2 r1 r0 g5 g4 g3
- */
- .description = "RGB565, le",
- .pixelformat = V4L2_PIX_FMT_RGB565,
- },
- {
- /* Note: V4L2 defines RGB32 as: RGB-8-8-8-8 we use
- * this for RGB24 unpack mode, the last 8 bits are ignored
- * */
- .description = "RGB32, le",
- .pixelformat = V4L2_PIX_FMT_RGB32,
- },
- {
- /* Note: V4L2 defines RGB24 as: RGB-8-8-8 we use
- * this for RGB24 packed mode
- *
- */
- .description = "RGB24, le",
- .pixelformat = V4L2_PIX_FMT_RGB24,
- },
- {
- .description = "YUYV (YUV 4:2:2), packed",
- .pixelformat = V4L2_PIX_FMT_YUYV,
- },
- {
- .description = "UYVY, packed",
- .pixelformat = V4L2_PIX_FMT_UYVY,
- },
-};
-
-#define NUM_OUTPUT_FORMATS (ARRAY_SIZE(omap_formats))
-
-/*
- * Try format
- */
-static int omap_vout_try_format(struct v4l2_pix_format *pix)
-{
- int ifmt, bpp = 0;
-
- pix->height = clamp(pix->height, (u32)VID_MIN_HEIGHT,
- (u32)VID_MAX_HEIGHT);
- pix->width = clamp(pix->width, (u32)VID_MIN_WIDTH, (u32)VID_MAX_WIDTH);
-
- for (ifmt = 0; ifmt < NUM_OUTPUT_FORMATS; ifmt++) {
- if (pix->pixelformat == omap_formats[ifmt].pixelformat)
- break;
- }
-
- if (ifmt == NUM_OUTPUT_FORMATS)
- ifmt = 0;
-
- pix->pixelformat = omap_formats[ifmt].pixelformat;
- pix->field = V4L2_FIELD_ANY;
- pix->priv = 0;
-
- switch (pix->pixelformat) {
- case V4L2_PIX_FMT_YUYV:
- case V4L2_PIX_FMT_UYVY:
- default:
- pix->colorspace = V4L2_COLORSPACE_JPEG;
- bpp = YUYV_BPP;
- break;
- case V4L2_PIX_FMT_RGB565:
- case V4L2_PIX_FMT_RGB565X:
- pix->colorspace = V4L2_COLORSPACE_SRGB;
- bpp = RGB565_BPP;
- break;
- case V4L2_PIX_FMT_RGB24:
- pix->colorspace = V4L2_COLORSPACE_SRGB;
- bpp = RGB24_BPP;
- break;
- case V4L2_PIX_FMT_RGB32:
- case V4L2_PIX_FMT_BGR32:
- pix->colorspace = V4L2_COLORSPACE_SRGB;
- bpp = RGB32_BPP;
- break;
- }
- pix->bytesperline = pix->width * bpp;
- pix->sizeimage = pix->bytesperline * pix->height;
-
- return bpp;
-}
-
-/*
- * omap_vout_uservirt_to_phys: This inline function is used to convert user
- * space virtual address to physical address.
- */
-static u32 omap_vout_uservirt_to_phys(u32 virtp)
-{
- unsigned long physp = 0;
- struct vm_area_struct *vma;
- struct mm_struct *mm = current->mm;
-
- vma = find_vma(mm, virtp);
- /* For kernel direct-mapped memory, take the easy way */
- if (virtp >= PAGE_OFFSET) {
- physp = virt_to_phys((void *) virtp);
- } else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
- /* this will catch, kernel-allocated, mmaped-to-usermode
- addresses */
- physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
- } else {
- /* otherwise, use get_user_pages() for general userland pages */
- int res, nr_pages = 1;
- struct page *pages;
- down_read(&current->mm->mmap_sem);
-
- res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
- 0, &pages, NULL);
- up_read(&current->mm->mmap_sem);
-
- if (res == nr_pages) {
- physp = __pa(page_address(&pages[0]) +
- (virtp & ~PAGE_MASK));
- } else {
- printk(KERN_WARNING VOUT_NAME
- "get_user_pages failed\n");
- return 0;
- }
- }
-
- return physp;
-}
-
-/*
- * Free the V4L2 buffers
- */
-void omap_vout_free_buffers(struct omap_vout_device *vout)
-{
- int i, numbuffers;
-
- /* Allocate memory for the buffers */
- numbuffers = (vout->vid) ? video2_numbuffers : video1_numbuffers;
- vout->buffer_size = (vout->vid) ? video2_bufsize : video1_bufsize;
-
- for (i = 0; i < numbuffers; i++) {
- omap_vout_free_buffer(vout->buf_virt_addr[i],
- vout->buffer_size);
- vout->buf_phy_addr[i] = 0;
- vout->buf_virt_addr[i] = 0;
- }
-}
-
-/*
- * Convert V4L2 rotation to DSS rotation
- * V4L2 understand 0, 90, 180, 270.
- * Convert to 0, 1, 2 and 3 respectively for DSS
- */
-static int v4l2_rot_to_dss_rot(int v4l2_rotation,
- enum dss_rotation *rotation, bool mirror)
-{
- int ret = 0;
-
- switch (v4l2_rotation) {
- case 90:
- *rotation = dss_rotation_90_degree;
- break;
- case 180:
- *rotation = dss_rotation_180_degree;
- break;
- case 270:
- *rotation = dss_rotation_270_degree;
- break;
- case 0:
- *rotation = dss_rotation_0_degree;
- break;
- default:
- ret = -EINVAL;
- }
- return ret;
-}
-
-static int omap_vout_calculate_offset(struct omap_vout_device *vout)
-{
- struct omapvideo_info *ovid;
- struct v4l2_rect *crop = &vout->crop;
- struct v4l2_pix_format *pix = &vout->pix;
- int *cropped_offset = &vout->cropped_offset;
- int ps = 2, line_length = 0;
-
- ovid = &vout->vid_info;
-
- if (ovid->rotation_type == VOUT_ROT_VRFB) {
- omap_vout_calculate_vrfb_offset(vout);
- } else {
- vout->line_length = line_length = pix->width;
-
- if (V4L2_PIX_FMT_YUYV == pix->pixelformat ||
- V4L2_PIX_FMT_UYVY == pix->pixelformat)
- ps = 2;
- else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat)
- ps = 4;
- else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat)
- ps = 3;
-
- vout->ps = ps;
-
- *cropped_offset = (line_length * ps) *
- crop->top + crop->left * ps;
- }
-
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "%s Offset:%x\n",
- __func__, vout->cropped_offset);
-
- return 0;
-}
-
-/*
- * Convert V4L2 pixel format to DSS pixel format
- */
-static int video_mode_to_dss_mode(struct omap_vout_device *vout)
-{
- struct omap_overlay *ovl;
- struct omapvideo_info *ovid;
- struct v4l2_pix_format *pix = &vout->pix;
- enum omap_color_mode mode;
-
- ovid = &vout->vid_info;
- ovl = ovid->overlays[0];
-
- switch (pix->pixelformat) {
- case 0:
- break;
- case V4L2_PIX_FMT_YUYV:
- mode = OMAP_DSS_COLOR_YUV2;
- break;
- case V4L2_PIX_FMT_UYVY:
- mode = OMAP_DSS_COLOR_UYVY;
- break;
- case V4L2_PIX_FMT_RGB565:
- mode = OMAP_DSS_COLOR_RGB16;
- break;
- case V4L2_PIX_FMT_RGB24:
- mode = OMAP_DSS_COLOR_RGB24P;
- break;
- case V4L2_PIX_FMT_RGB32:
- mode = (ovl->id == OMAP_DSS_VIDEO1) ?
- OMAP_DSS_COLOR_RGB24U : OMAP_DSS_COLOR_ARGB32;
- break;
- case V4L2_PIX_FMT_BGR32:
- mode = OMAP_DSS_COLOR_RGBX32;
- break;
- default:
- mode = -EINVAL;
- }
- return mode;
-}
-
-/*
- * Setup the overlay
- */
-static int omapvid_setup_overlay(struct omap_vout_device *vout,
- struct omap_overlay *ovl, int posx, int posy, int outw,
- int outh, u32 addr)
-{
- int ret = 0;
- struct omap_overlay_info info;
- int cropheight, cropwidth, pixheight, pixwidth;
-
- if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0 &&
- (outw != vout->pix.width || outh != vout->pix.height)) {
- ret = -EINVAL;
- goto setup_ovl_err;
- }
-
- vout->dss_mode = video_mode_to_dss_mode(vout);
- if (vout->dss_mode == -EINVAL) {
- ret = -EINVAL;
- goto setup_ovl_err;
- }
-
- /* Setup the input plane parameters according to
- * rotation value selected.
- */
- if (is_rotation_90_or_270(vout)) {
- cropheight = vout->crop.width;
- cropwidth = vout->crop.height;
- pixheight = vout->pix.width;
- pixwidth = vout->pix.height;
- } else {
- cropheight = vout->crop.height;
- cropwidth = vout->crop.width;
- pixheight = vout->pix.height;
- pixwidth = vout->pix.width;
- }
-
- ovl->get_overlay_info(ovl, &info);
- info.paddr = addr;
- info.width = cropwidth;
- info.height = cropheight;
- info.color_mode = vout->dss_mode;
- info.mirror = vout->mirror;
- info.pos_x = posx;
- info.pos_y = posy;
- info.out_width = outw;
- info.out_height = outh;
- info.global_alpha = vout->win.global_alpha;
- if (!is_rotation_enabled(vout)) {
- info.rotation = 0;
- info.rotation_type = OMAP_DSS_ROT_DMA;
- info.screen_width = pixwidth;
- } else {
- info.rotation = vout->rotation;
- info.rotation_type = OMAP_DSS_ROT_VRFB;
- info.screen_width = 2048;
- }
-
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
- "%s enable=%d addr=%x width=%d\n height=%d color_mode=%d\n"
- "rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n"
- "out_height=%d rotation_type=%d screen_width=%d\n",
- __func__, ovl->is_enabled(ovl), info.paddr, info.width, info.height,
- info.color_mode, info.rotation, info.mirror, info.pos_x,
- info.pos_y, info.out_width, info.out_height, info.rotation_type,
- info.screen_width);
-
- ret = ovl->set_overlay_info(ovl, &info);
- if (ret)
- goto setup_ovl_err;
-
- return 0;
-
-setup_ovl_err:
- v4l2_warn(&vout->vid_dev->v4l2_dev, "setup_overlay failed\n");
- return ret;
-}
-
-/*
- * Initialize the overlay structure
- */
-static int omapvid_init(struct omap_vout_device *vout, u32 addr)
-{
- int ret = 0, i;
- struct v4l2_window *win;
- struct omap_overlay *ovl;
- int posx, posy, outw, outh, temp;
- struct omap_video_timings *timing;
- struct omapvideo_info *ovid = &vout->vid_info;
-
- win = &vout->win;
- for (i = 0; i < ovid->num_overlays; i++) {
- ovl = ovid->overlays[i];
- if (!ovl->manager || !ovl->manager->device)
- return -EINVAL;
-
- timing = &ovl->manager->device->panel.timings;
-
- outw = win->w.width;
- outh = win->w.height;
- switch (vout->rotation) {
- case dss_rotation_90_degree:
- /* Invert the height and width for 90
- * and 270 degree rotation
- */
- temp = outw;
- outw = outh;
- outh = temp;
- posy = (timing->y_res - win->w.width) - win->w.left;
- posx = win->w.top;
- break;
-
- case dss_rotation_180_degree:
- posx = (timing->x_res - win->w.width) - win->w.left;
- posy = (timing->y_res - win->w.height) - win->w.top;
- break;
-
- case dss_rotation_270_degree:
- temp = outw;
- outw = outh;
- outh = temp;
- posy = win->w.left;
- posx = (timing->x_res - win->w.height) - win->w.top;
- break;
-
- default:
- posx = win->w.left;
- posy = win->w.top;
- break;
- }
-
- ret = omapvid_setup_overlay(vout, ovl, posx, posy,
- outw, outh, addr);
- if (ret)
- goto omapvid_init_err;
- }
- return 0;
-
-omapvid_init_err:
- v4l2_warn(&vout->vid_dev->v4l2_dev, "apply_changes failed\n");
- return ret;
-}
-
-/*
- * Apply the changes set the go bit of DSS
- */
-static int omapvid_apply_changes(struct omap_vout_device *vout)
-{
- int i;
- struct omap_overlay *ovl;
- struct omapvideo_info *ovid = &vout->vid_info;
-
- for (i = 0; i < ovid->num_overlays; i++) {
- ovl = ovid->overlays[i];
- if (!ovl->manager || !ovl->manager->device)
- return -EINVAL;
- ovl->manager->apply(ovl->manager);
- }
-
- return 0;
-}
-
-static int omapvid_handle_interlace_display(struct omap_vout_device *vout,
- unsigned int irqstatus, struct timeval timevalue)
-{
- u32 fid;
-
- if (vout->first_int) {
- vout->first_int = 0;
- goto err;
- }
-
- if (irqstatus & DISPC_IRQ_EVSYNC_ODD)
- fid = 1;
- else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN)
- fid = 0;
- else
- goto err;
-
- vout->field_id ^= 1;
- if (fid != vout->field_id) {
- if (fid == 0)
- vout->field_id = fid;
- } else if (0 == fid) {
- if (vout->cur_frm == vout->next_frm)
- goto err;
-
- vout->cur_frm->ts = timevalue;
- vout->cur_frm->state = VIDEOBUF_DONE;
- wake_up_interruptible(&vout->cur_frm->done);
- vout->cur_frm = vout->next_frm;
- } else {
- if (list_empty(&vout->dma_queue) ||
- (vout->cur_frm != vout->next_frm))
- goto err;
- }
-
- return vout->field_id;
-err:
- return 0;
-}
-
-static void omap_vout_isr(void *arg, unsigned int irqstatus)
-{
- int ret, fid, mgr_id;
- u32 addr, irq;
- struct omap_overlay *ovl;
- struct timeval timevalue;
- struct omapvideo_info *ovid;
- struct omap_dss_device *cur_display;
- struct omap_vout_device *vout = (struct omap_vout_device *)arg;
-
- if (!vout->streaming)
- return;
-
- ovid = &vout->vid_info;
- ovl = ovid->overlays[0];
- /* get the display device attached to the overlay */
- if (!ovl->manager || !ovl->manager->device)
- return;
-
- mgr_id = ovl->manager->id;
- cur_display = ovl->manager->device;
-
- spin_lock(&vout->vbq_lock);
- do_gettimeofday(&timevalue);
-
- switch (cur_display->type) {
- case OMAP_DISPLAY_TYPE_DSI:
- case OMAP_DISPLAY_TYPE_DPI:
- if (mgr_id == OMAP_DSS_CHANNEL_LCD)
- irq = DISPC_IRQ_VSYNC;
- else if (mgr_id == OMAP_DSS_CHANNEL_LCD2)
- irq = DISPC_IRQ_VSYNC2;
- else
- goto vout_isr_err;
-
- if (!(irqstatus & irq))
- goto vout_isr_err;
- break;
- case OMAP_DISPLAY_TYPE_VENC:
- fid = omapvid_handle_interlace_display(vout, irqstatus,
- timevalue);
- if (!fid)
- goto vout_isr_err;
- break;
- case OMAP_DISPLAY_TYPE_HDMI:
- if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN))
- goto vout_isr_err;
- break;
- default:
- goto vout_isr_err;
- }
-
- if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
- vout->cur_frm->ts = timevalue;
- vout->cur_frm->state = VIDEOBUF_DONE;
- wake_up_interruptible(&vout->cur_frm->done);
- vout->cur_frm = vout->next_frm;
- }
-
- vout->first_int = 0;
- if (list_empty(&vout->dma_queue))
- goto vout_isr_err;
-
- vout->next_frm = list_entry(vout->dma_queue.next,
- struct videobuf_buffer, queue);
- list_del(&vout->next_frm->queue);
-
- vout->next_frm->state = VIDEOBUF_ACTIVE;
-
- addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i]
- + vout->cropped_offset;
-
- /* First save the configuration in ovelray structure */
- ret = omapvid_init(vout, addr);
- if (ret)
- printk(KERN_ERR VOUT_NAME
- "failed to set overlay info\n");
- /* Enable the pipeline and set the Go bit */
- ret = omapvid_apply_changes(vout);
- if (ret)
- printk(KERN_ERR VOUT_NAME "failed to change mode\n");
-
-vout_isr_err:
- spin_unlock(&vout->vbq_lock);
-}
-
-/* Video buffer call backs */
-
-/*
- * Buffer setup function is called by videobuf layer when REQBUF ioctl is
- * called. This is used to setup buffers and return size and count of
- * buffers allocated. After the call to this buffer, videobuf layer will
- * setup buffer queue depending on the size and count of buffers
- */
-static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
- unsigned int *size)
-{
- int startindex = 0, i, j;
- u32 phy_addr = 0, virt_addr = 0;
- struct omap_vout_device *vout = q->priv_data;
- struct omapvideo_info *ovid = &vout->vid_info;
- int vid_max_buf_size;
-
- if (!vout)
- return -EINVAL;
-
- vid_max_buf_size = vout->vid == OMAP_VIDEO1 ? video1_bufsize :
- video2_bufsize;
-
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
- return -EINVAL;
-
- startindex = (vout->vid == OMAP_VIDEO1) ?
- video1_numbuffers : video2_numbuffers;
- if (V4L2_MEMORY_MMAP == vout->memory && *count < startindex)
- *count = startindex;
-
- if (ovid->rotation_type == VOUT_ROT_VRFB) {
- if (omap_vout_vrfb_buffer_setup(vout, count, startindex))
- return -ENOMEM;
- }
-
- if (V4L2_MEMORY_MMAP != vout->memory)
- return 0;
-
- /* Now allocated the V4L2 buffers */
- *size = PAGE_ALIGN(vout->pix.width * vout->pix.height * vout->bpp);
- startindex = (vout->vid == OMAP_VIDEO1) ?
- video1_numbuffers : video2_numbuffers;
-
- /* Check the size of the buffer */
- if (*size > vid_max_buf_size) {
- v4l2_err(&vout->vid_dev->v4l2_dev,
- "buffer allocation mismatch [%u] [%u]\n",
- *size, vout->buffer_size);
- return -ENOMEM;
- }
-
- for (i = startindex; i < *count; i++) {
- vout->buffer_size = *size;
-
- virt_addr = omap_vout_alloc_buffer(vout->buffer_size,
- &phy_addr);
- if (!virt_addr) {
- if (ovid->rotation_type == VOUT_ROT_NONE) {
- break;
- } else {
- if (!is_rotation_enabled(vout))
- break;
- /* Free the VRFB buffers if no space for V4L2 buffers */
- for (j = i; j < *count; j++) {
- omap_vout_free_buffer(
- vout->smsshado_virt_addr[j],
- vout->smsshado_size);
- vout->smsshado_virt_addr[j] = 0;
- vout->smsshado_phy_addr[j] = 0;
- }
- }
- }
- vout->buf_virt_addr[i] = virt_addr;
- vout->buf_phy_addr[i] = phy_addr;
- }
- *count = vout->buffer_allocated = i;
-
- return 0;
-}
-
-/*
- * Free the V4L2 buffers additionally allocated than default
- * number of buffers
- */
-static void omap_vout_free_extra_buffers(struct omap_vout_device *vout)
-{
- int num_buffers = 0, i;
-
- num_buffers = (vout->vid == OMAP_VIDEO1) ?
- video1_numbuffers : video2_numbuffers;
-
- for (i = num_buffers; i < vout->buffer_allocated; i++) {
- if (vout->buf_virt_addr[i])
- omap_vout_free_buffer(vout->buf_virt_addr[i],
- vout->buffer_size);
-
- vout->buf_virt_addr[i] = 0;
- vout->buf_phy_addr[i] = 0;
- }
- vout->buffer_allocated = num_buffers;
-}
-
-/*
- * This function will be called when VIDIOC_QBUF ioctl is called.
- * It prepare buffers before give out for the display. This function
- * converts user space virtual address into physical address if userptr memory
- * exchange mechanism is used. If rotation is enabled, it copies entire
- * buffer into VRFB memory space before giving it to the DSS.
- */
-static int omap_vout_buffer_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct omap_vout_device *vout = q->priv_data;
- struct omapvideo_info *ovid = &vout->vid_info;
-
- if (VIDEOBUF_NEEDS_INIT == vb->state) {
- vb->width = vout->pix.width;
- vb->height = vout->pix.height;
- vb->size = vb->width * vb->height * vout->bpp;
- vb->field = field;
- }
- vb->state = VIDEOBUF_PREPARED;
- /* if user pointer memory mechanism is used, get the physical
- * address of the buffer
- */
- if (V4L2_MEMORY_USERPTR == vb->memory) {
- if (0 == vb->baddr)
- return -EINVAL;
- /* Physical address */
- vout->queued_buf_addr[vb->i] = (u8 *)
- omap_vout_uservirt_to_phys(vb->baddr);
- } else {
- u32 addr, dma_addr;
- unsigned long size;
-
- addr = (unsigned long) vout->buf_virt_addr[vb->i];
- size = (unsigned long) vb->size;
-
- dma_addr = dma_map_single(vout->vid_dev->v4l2_dev.dev, (void *) addr,
- size, DMA_TO_DEVICE);
- if (dma_mapping_error(vout->vid_dev->v4l2_dev.dev, dma_addr))
- v4l2_err(&vout->vid_dev->v4l2_dev, "dma_map_single failed\n");
-
- vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i];
- }
-
- if (ovid->rotation_type == VOUT_ROT_VRFB)
- return omap_vout_prepare_vrfb(vout, vb);
- else
- return 0;
-}
-
-/*
- * Buffer queue function will be called from the videobuf layer when _QBUF
- * ioctl is called. It is used to enqueue buffer, which is ready to be
- * displayed.
- */
-static void omap_vout_buffer_queue(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- struct omap_vout_device *vout = q->priv_data;
-
- /* Driver is also maintainig a queue. So enqueue buffer in the driver
- * queue */
- list_add_tail(&vb->queue, &vout->dma_queue);
-
- vb->state = VIDEOBUF_QUEUED;
-}
-
-/*
- * Buffer release function is called from videobuf layer to release buffer
- * which are already allocated
- */
-static void omap_vout_buffer_release(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- struct omap_vout_device *vout = q->priv_data;
-
- vb->state = VIDEOBUF_NEEDS_INIT;
-
- if (V4L2_MEMORY_MMAP != vout->memory)
- return;
-}
-
-/*
- * File operations
- */
-static unsigned int omap_vout_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct omap_vout_device *vout = file->private_data;
- struct videobuf_queue *q = &vout->vbq;
-
- return videobuf_poll_stream(file, q, wait);
-}
-
-static void omap_vout_vm_open(struct vm_area_struct *vma)
-{
- struct omap_vout_device *vout = vma->vm_private_data;
-
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
- "vm_open [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
- vout->mmap_count++;
-}
-
-static void omap_vout_vm_close(struct vm_area_struct *vma)
-{
- struct omap_vout_device *vout = vma->vm_private_data;
-
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
- "vm_close [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
- vout->mmap_count--;
-}
-
-static struct vm_operations_struct omap_vout_vm_ops = {
- .open = omap_vout_vm_open,
- .close = omap_vout_vm_close,
-};
-
-static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma)
-{
- int i;
- void *pos;
- unsigned long start = vma->vm_start;
- unsigned long size = (vma->vm_end - vma->vm_start);
- struct omap_vout_device *vout = file->private_data;
- struct videobuf_queue *q = &vout->vbq;
-
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
- " %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n", __func__,
- vma->vm_pgoff, vma->vm_start, vma->vm_end);
-
- /* look for the buffer to map */
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- if (NULL == q->bufs[i])
- continue;
- if (V4L2_MEMORY_MMAP != q->bufs[i]->memory)
- continue;
- if (q->bufs[i]->boff == (vma->vm_pgoff << PAGE_SHIFT))
- break;
- }
-
- if (VIDEO_MAX_FRAME == i) {
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
- "offset invalid [offset=0x%lx]\n",
- (vma->vm_pgoff << PAGE_SHIFT));
- return -EINVAL;
- }
- /* Check the size of the buffer */
- if (size > vout->buffer_size) {
- v4l2_err(&vout->vid_dev->v4l2_dev,
- "insufficient memory [%lu] [%u]\n",
- size, vout->buffer_size);
- return -ENOMEM;
- }
-
- q->bufs[i]->baddr = vma->vm_start;
-
- vma->vm_flags |= VM_RESERVED;
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
- vma->vm_ops = &omap_vout_vm_ops;
- vma->vm_private_data = (void *) vout;
- pos = (void *)vout->buf_virt_addr[i];
- vma->vm_pgoff = virt_to_phys((void *)pos) >> PAGE_SHIFT;
- while (size > 0) {
- unsigned long pfn;
- pfn = virt_to_phys((void *) pos) >> PAGE_SHIFT;
- if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
- return -EAGAIN;
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- vout->mmap_count++;
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
-
- return 0;
-}
-
-static int omap_vout_release(struct file *file)
-{
- unsigned int ret, i;
- struct videobuf_queue *q;
- struct omapvideo_info *ovid;
- struct omap_vout_device *vout = file->private_data;
-
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
- ovid = &vout->vid_info;
-
- if (!vout)
- return 0;
-
- q = &vout->vbq;
- /* Disable all the overlay managers connected with this interface */
- for (i = 0; i < ovid->num_overlays; i++) {
- struct omap_overlay *ovl = ovid->overlays[i];
- if (ovl->manager && ovl->manager->device)
- ovl->disable(ovl);
- }
- /* Turn off the pipeline */
- ret = omapvid_apply_changes(vout);
- if (ret)
- v4l2_warn(&vout->vid_dev->v4l2_dev,
- "Unable to apply changes\n");
-
- /* Free all buffers */
- omap_vout_free_extra_buffers(vout);
-
- /* Free the VRFB buffers only if they are allocated
- * during reqbufs. Don't free if init time allocated
- */
- if (ovid->rotation_type == VOUT_ROT_VRFB) {
- if (!vout->vrfb_static_allocation)
- omap_vout_free_vrfb_buffers(vout);
- }
- videobuf_mmap_free(q);
-
- /* Even if apply changes fails we should continue
- freeing allocated memory */
- if (vout->streaming) {
- u32 mask = 0;
-
- mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN |
- DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_VSYNC2;
- omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
- vout->streaming = 0;
-
- videobuf_streamoff(q);
- videobuf_queue_cancel(q);
- }
-
- if (vout->mmap_count != 0)
- vout->mmap_count = 0;
-
- vout->opened -= 1;
- file->private_data = NULL;
-
- if (vout->buffer_allocated)
- videobuf_mmap_free(q);
-
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
- return ret;
-}
-
-static int omap_vout_open(struct file *file)
-{
- struct videobuf_queue *q;
- struct omap_vout_device *vout = NULL;
-
- vout = video_drvdata(file);
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
-
- if (vout == NULL)
- return -ENODEV;
-
- /* for now, we only support single open */
- if (vout->opened)
- return -EBUSY;
-
- vout->opened += 1;
-
- file->private_data = vout;
- vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-
- q = &vout->vbq;
- video_vbq_ops.buf_setup = omap_vout_buffer_setup;
- video_vbq_ops.buf_prepare = omap_vout_buffer_prepare;
- video_vbq_ops.buf_release = omap_vout_buffer_release;
- video_vbq_ops.buf_queue = omap_vout_buffer_queue;
- spin_lock_init(&vout->vbq_lock);
-
- videobuf_queue_dma_contig_init(q, &video_vbq_ops, q->dev,
- &vout->vbq_lock, vout->type, V4L2_FIELD_NONE,
- sizeof(struct videobuf_buffer), vout, NULL);
-
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
- return 0;
-}
-
-/*
- * V4L2 ioctls
- */
-static int vidioc_querycap(struct file *file, void *fh,
- struct v4l2_capability *cap)
-{
- struct omap_vout_device *vout = fh;
-
- strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
- strlcpy(cap->card, vout->vfd->name, sizeof(cap->card));
- cap->bus_info[0] = '\0';
- cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT |
- V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
-
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_out(struct file *file, void *fh,
- struct v4l2_fmtdesc *fmt)
-{
- int index = fmt->index;
-
- if (index >= NUM_OUTPUT_FORMATS)
- return -EINVAL;
-
- fmt->flags = omap_formats[index].flags;
- strlcpy(fmt->description, omap_formats[index].description,
- sizeof(fmt->description));
- fmt->pixelformat = omap_formats[index].pixelformat;
-
- return 0;
-}
-
-static int vidioc_g_fmt_vid_out(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct omap_vout_device *vout = fh;
-
- f->fmt.pix = vout->pix;
- return 0;
-
-}
-
-static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct omap_overlay *ovl;
- struct omapvideo_info *ovid;
- struct omap_video_timings *timing;
- struct omap_vout_device *vout = fh;
-
- ovid = &vout->vid_info;
- ovl = ovid->overlays[0];
-
- if (!ovl->manager || !ovl->manager->device)
- return -EINVAL;
- /* get the display device attached to the overlay */
- timing = &ovl->manager->device->panel.timings;
-
- vout->fbuf.fmt.height = timing->y_res;
- vout->fbuf.fmt.width = timing->x_res;
-
- omap_vout_try_format(&f->fmt.pix);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- int ret, bpp;
- struct omap_overlay *ovl;
- struct omapvideo_info *ovid;
- struct omap_video_timings *timing;
- struct omap_vout_device *vout = fh;
-
- if (vout->streaming)
- return -EBUSY;
-
- mutex_lock(&vout->lock);
-
- ovid = &vout->vid_info;
- ovl = ovid->overlays[0];
-
- /* get the display device attached to the overlay */
- if (!ovl->manager || !ovl->manager->device) {
- ret = -EINVAL;
- goto s_fmt_vid_out_exit;
- }
- timing = &ovl->manager->device->panel.timings;
-
- /* We dont support RGB24-packed mode if vrfb rotation
- * is enabled*/
- if ((is_rotation_enabled(vout)) &&
- f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
- ret = -EINVAL;
- goto s_fmt_vid_out_exit;
- }
-
- /* get the framebuffer parameters */
-
- if (is_rotation_90_or_270(vout)) {
- vout->fbuf.fmt.height = timing->x_res;
- vout->fbuf.fmt.width = timing->y_res;
- } else {
- vout->fbuf.fmt.height = timing->y_res;
- vout->fbuf.fmt.width = timing->x_res;
- }
-
- /* change to samller size is OK */
-
- bpp = omap_vout_try_format(&f->fmt.pix);
- f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height * bpp;
-
- /* try & set the new output format */
- vout->bpp = bpp;
- vout->pix = f->fmt.pix;
- vout->vrfb_bpp = 1;
-
- /* If YUYV then vrfb bpp is 2, for others its 1 */
- if (V4L2_PIX_FMT_YUYV == vout->pix.pixelformat ||
- V4L2_PIX_FMT_UYVY == vout->pix.pixelformat)
- vout->vrfb_bpp = 2;
-
- /* set default crop and win */
- omap_vout_new_format(&vout->pix, &vout->fbuf, &vout->crop, &vout->win);
-
- /* Save the changes in the overlay strcuture */
- ret = omapvid_init(vout, 0);
- if (ret) {
- v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
- goto s_fmt_vid_out_exit;
- }
-
- ret = 0;
-
-s_fmt_vid_out_exit:
- mutex_unlock(&vout->lock);
- return ret;
-}
-
-static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- int ret = 0;
- struct omap_vout_device *vout = fh;
- struct omap_overlay *ovl;
- struct omapvideo_info *ovid;
- struct v4l2_window *win = &f->fmt.win;
-
- ovid = &vout->vid_info;
- ovl = ovid->overlays[0];
-
- ret = omap_vout_try_window(&vout->fbuf, win);
-
- if (!ret) {
- if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
- win->global_alpha = 255;
- else
- win->global_alpha = f->fmt.win.global_alpha;
- }
-
- return ret;
-}
-
-static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- int ret = 0;
- struct omap_overlay *ovl;
- struct omapvideo_info *ovid;
- struct omap_vout_device *vout = fh;
- struct v4l2_window *win = &f->fmt.win;
-
- mutex_lock(&vout->lock);
- ovid = &vout->vid_info;
- ovl = ovid->overlays[0];
-
- ret = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win);
- if (!ret) {
- /* Video1 plane does not support global alpha on OMAP3 */
- if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
- vout->win.global_alpha = 255;
- else
- vout->win.global_alpha = f->fmt.win.global_alpha;
-
- vout->win.chromakey = f->fmt.win.chromakey;
- }
- mutex_unlock(&vout->lock);
- return ret;
-}
-
-static int vidioc_enum_fmt_vid_overlay(struct file *file, void *fh,
- struct v4l2_fmtdesc *fmt)
-{
- int index = fmt->index;
-
- if (index >= NUM_OUTPUT_FORMATS)
- return -EINVAL;
-
- fmt->flags = omap_formats[index].flags;
- strlcpy(fmt->description, omap_formats[index].description,
- sizeof(fmt->description));
- fmt->pixelformat = omap_formats[index].pixelformat;
- return 0;
-}
-
-static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- u32 key_value = 0;
- struct omap_overlay *ovl;
- struct omapvideo_info *ovid;
- struct omap_vout_device *vout = fh;
- struct omap_overlay_manager_info info;
- struct v4l2_window *win = &f->fmt.win;
-
- ovid = &vout->vid_info;
- ovl = ovid->overlays[0];
-
- win->w = vout->win.w;
- win->field = vout->win.field;
- win->global_alpha = vout->win.global_alpha;
-
- if (ovl->manager && ovl->manager->get_manager_info) {
- ovl->manager->get_manager_info(ovl->manager, &info);
- key_value = info.trans_key;
- }
- win->chromakey = key_value;
- return 0;
-}
-
-static int vidioc_cropcap(struct file *file, void *fh,
- struct v4l2_cropcap *cropcap)
-{
- struct omap_vout_device *vout = fh;
- struct v4l2_pix_format *pix = &vout->pix;
-
- if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
-
- /* Width and height are always even */
- cropcap->bounds.width = pix->width & ~1;
- cropcap->bounds.height = pix->height & ~1;
-
- omap_vout_default_crop(&vout->pix, &vout->fbuf, &cropcap->defrect);
- cropcap->pixelaspect.numerator = 1;
- cropcap->pixelaspect.denominator = 1;
- return 0;
-}
-
-static int vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
-{
- struct omap_vout_device *vout = fh;
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
- crop->c = vout->crop;
- return 0;
-}
-
-static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
-{
- int ret = -EINVAL;
- struct omap_vout_device *vout = fh;
- struct omapvideo_info *ovid;
- struct omap_overlay *ovl;
- struct omap_video_timings *timing;
-
- if (vout->streaming)
- return -EBUSY;
-
- mutex_lock(&vout->lock);
- ovid = &vout->vid_info;
- ovl = ovid->overlays[0];
-
- if (!ovl->manager || !ovl->manager->device) {
- ret = -EINVAL;
- goto s_crop_err;
- }
- /* get the display device attached to the overlay */
- timing = &ovl->manager->device->panel.timings;
-
- if (is_rotation_90_or_270(vout)) {
- vout->fbuf.fmt.height = timing->x_res;
- vout->fbuf.fmt.width = timing->y_res;
- } else {
- vout->fbuf.fmt.height = timing->y_res;
- vout->fbuf.fmt.width = timing->x_res;
- }
-
- if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
- ret = omap_vout_new_crop(&vout->pix, &vout->crop, &vout->win,
- &vout->fbuf, &crop->c);
-
-s_crop_err:
- mutex_unlock(&vout->lock);
- return ret;
-}
-
-static int vidioc_queryctrl(struct file *file, void *fh,
- struct v4l2_queryctrl *ctrl)
-{
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_ROTATE:
- ret = v4l2_ctrl_query_fill(ctrl, 0, 270, 90, 0);
- break;
- case V4L2_CID_BG_COLOR:
- ret = v4l2_ctrl_query_fill(ctrl, 0, 0xFFFFFF, 1, 0);
- break;
- case V4L2_CID_VFLIP:
- ret = v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
- break;
- default:
- ctrl->name[0] = '\0';
- ret = -EINVAL;
- }
- return ret;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *ctrl)
-{
- int ret = 0;
- struct omap_vout_device *vout = fh;
-
- switch (ctrl->id) {
- case V4L2_CID_ROTATE:
- ctrl->value = vout->control[0].value;
- break;
- case V4L2_CID_BG_COLOR:
- {
- struct omap_overlay_manager_info info;
- struct omap_overlay *ovl;
-
- ovl = vout->vid_info.overlays[0];
- if (!ovl->manager || !ovl->manager->get_manager_info) {
- ret = -EINVAL;
- break;
- }
-
- ovl->manager->get_manager_info(ovl->manager, &info);
- ctrl->value = info.default_color;
- break;
- }
- case V4L2_CID_VFLIP:
- ctrl->value = vout->control[2].value;
- break;
- default:
- ret = -EINVAL;
- }
- return ret;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a)
-{
- int ret = 0;
- struct omap_vout_device *vout = fh;
-
- switch (a->id) {
- case V4L2_CID_ROTATE:
- {
- struct omapvideo_info *ovid;
- int rotation = a->value;
-
- ovid = &vout->vid_info;
-
- mutex_lock(&vout->lock);
- if (rotation && ovid->rotation_type == VOUT_ROT_NONE) {
- mutex_unlock(&vout->lock);
- ret = -ERANGE;
- break;
- }
-
- if (rotation && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
- mutex_unlock(&vout->lock);
- ret = -EINVAL;
- break;
- }
-
- if (v4l2_rot_to_dss_rot(rotation, &vout->rotation,
- vout->mirror)) {
- mutex_unlock(&vout->lock);
- ret = -EINVAL;
- break;
- }
-
- vout->control[0].value = rotation;
- mutex_unlock(&vout->lock);
- break;
- }
- case V4L2_CID_BG_COLOR:
- {
- struct omap_overlay *ovl;
- unsigned int color = a->value;
- struct omap_overlay_manager_info info;
-
- ovl = vout->vid_info.overlays[0];
-
- mutex_lock(&vout->lock);
- if (!ovl->manager || !ovl->manager->get_manager_info) {
- mutex_unlock(&vout->lock);
- ret = -EINVAL;
- break;
- }
-
- ovl->manager->get_manager_info(ovl->manager, &info);
- info.default_color = color;
- if (ovl->manager->set_manager_info(ovl->manager, &info)) {
- mutex_unlock(&vout->lock);
- ret = -EINVAL;
- break;
- }
-
- vout->control[1].value = color;
- mutex_unlock(&vout->lock);
- break;
- }
- case V4L2_CID_VFLIP:
- {
- struct omap_overlay *ovl;
- struct omapvideo_info *ovid;
- unsigned int mirror = a->value;
-
- ovid = &vout->vid_info;
- ovl = ovid->overlays[0];
-
- mutex_lock(&vout->lock);
- if (mirror && ovid->rotation_type == VOUT_ROT_NONE) {
- mutex_unlock(&vout->lock);
- ret = -ERANGE;
- break;
- }
-
- if (mirror && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
- mutex_unlock(&vout->lock);
- ret = -EINVAL;
- break;
- }
- vout->mirror = mirror;
- vout->control[2].value = mirror;
- mutex_unlock(&vout->lock);
- break;
- }
- default:
- ret = -EINVAL;
- }
- return ret;
-}
-
-static int vidioc_reqbufs(struct file *file, void *fh,
- struct v4l2_requestbuffers *req)
-{
- int ret = 0;
- unsigned int i, num_buffers = 0;
- struct omap_vout_device *vout = fh;
- struct videobuf_queue *q = &vout->vbq;
-
- if ((req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) || (req->count < 0))
- return -EINVAL;
- /* if memory is not mmp or userptr
- return error */
- if ((V4L2_MEMORY_MMAP != req->memory) &&
- (V4L2_MEMORY_USERPTR != req->memory))
- return -EINVAL;
-
- mutex_lock(&vout->lock);
- /* Cannot be requested when streaming is on */
- if (vout->streaming) {
- ret = -EBUSY;
- goto reqbuf_err;
- }
-
- /* If buffers are already allocated free them */
- if (q->bufs[0] && (V4L2_MEMORY_MMAP == q->bufs[0]->memory)) {
- if (vout->mmap_count) {
- ret = -EBUSY;
- goto reqbuf_err;
- }
- num_buffers = (vout->vid == OMAP_VIDEO1) ?
- video1_numbuffers : video2_numbuffers;
- for (i = num_buffers; i < vout->buffer_allocated; i++) {
- omap_vout_free_buffer(vout->buf_virt_addr[i],
- vout->buffer_size);
- vout->buf_virt_addr[i] = 0;
- vout->buf_phy_addr[i] = 0;
- }
- vout->buffer_allocated = num_buffers;
- videobuf_mmap_free(q);
- } else if (q->bufs[0] && (V4L2_MEMORY_USERPTR == q->bufs[0]->memory)) {
- if (vout->buffer_allocated) {
- videobuf_mmap_free(q);
- for (i = 0; i < vout->buffer_allocated; i++) {
- kfree(q->bufs[i]);
- q->bufs[i] = NULL;
- }
- vout->buffer_allocated = 0;
- }
- }
-
- /*store the memory type in data structure */
- vout->memory = req->memory;
-
- INIT_LIST_HEAD(&vout->dma_queue);
-
- /* call videobuf_reqbufs api */
- ret = videobuf_reqbufs(q, req);
- if (ret < 0)
- goto reqbuf_err;
-
- vout->buffer_allocated = req->count;
-
-reqbuf_err:
- mutex_unlock(&vout->lock);
- return ret;
-}
-
-static int vidioc_querybuf(struct file *file, void *fh,
- struct v4l2_buffer *b)
-{
- struct omap_vout_device *vout = fh;
-
- return videobuf_querybuf(&vout->vbq, b);
-}
-
-static int vidioc_qbuf(struct file *file, void *fh,
- struct v4l2_buffer *buffer)
-{
- struct omap_vout_device *vout = fh;
- struct videobuf_queue *q = &vout->vbq;
-
- if ((V4L2_BUF_TYPE_VIDEO_OUTPUT != buffer->type) ||
- (buffer->index >= vout->buffer_allocated) ||
- (q->bufs[buffer->index]->memory != buffer->memory)) {
- return -EINVAL;
- }
- if (V4L2_MEMORY_USERPTR == buffer->memory) {
- if ((buffer->length < vout->pix.sizeimage) ||
- (0 == buffer->m.userptr)) {
- return -EINVAL;
- }
- }
-
- if ((is_rotation_enabled(vout)) &&
- vout->vrfb_dma_tx.req_status == DMA_CHAN_NOT_ALLOTED) {
- v4l2_warn(&vout->vid_dev->v4l2_dev,
- "DMA Channel not allocated for Rotation\n");
- return -EINVAL;
- }
-
- return videobuf_qbuf(q, buffer);
-}
-
-static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
-{
- struct omap_vout_device *vout = fh;
- struct videobuf_queue *q = &vout->vbq;
-
- int ret;
- u32 addr;
- unsigned long size;
- struct videobuf_buffer *vb;
-
- vb = q->bufs[b->index];
-
- if (!vout->streaming)
- return -EINVAL;
-
- if (file->f_flags & O_NONBLOCK)
- /* Call videobuf_dqbuf for non blocking mode */
- ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1);
- else
- /* Call videobuf_dqbuf for blocking mode */
- ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
-
- addr = (unsigned long) vout->buf_phy_addr[vb->i];
- size = (unsigned long) vb->size;
- dma_unmap_single(vout->vid_dev->v4l2_dev.dev, addr,
- size, DMA_TO_DEVICE);
- return ret;
-}
-
-static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
-{
- int ret = 0, j;
- u32 addr = 0, mask = 0;
- struct omap_vout_device *vout = fh;
- struct videobuf_queue *q = &vout->vbq;
- struct omapvideo_info *ovid = &vout->vid_info;
-
- mutex_lock(&vout->lock);
-
- if (vout->streaming) {
- ret = -EBUSY;
- goto streamon_err;
- }
-
- ret = videobuf_streamon(q);
- if (ret)
- goto streamon_err;
-
- if (list_empty(&vout->dma_queue)) {
- ret = -EIO;
- goto streamon_err1;
- }
-
- /* Get the next frame from the buffer queue */
- vout->next_frm = vout->cur_frm = list_entry(vout->dma_queue.next,
- struct videobuf_buffer, queue);
- /* Remove buffer from the buffer queue */
- list_del(&vout->cur_frm->queue);
- /* Mark state of the current frame to active */
- vout->cur_frm->state = VIDEOBUF_ACTIVE;
- /* Initialize field_id and started member */
- vout->field_id = 0;
-
- /* set flag here. Next QBUF will start DMA */
- vout->streaming = 1;
-
- vout->first_int = 1;
-
- if (omap_vout_calculate_offset(vout)) {
- ret = -EINVAL;
- goto streamon_err1;
- }
- addr = (unsigned long) vout->queued_buf_addr[vout->cur_frm->i]
- + vout->cropped_offset;
-
- mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
- | DISPC_IRQ_VSYNC2;
-
- omap_dispc_register_isr(omap_vout_isr, vout, mask);
-
- for (j = 0; j < ovid->num_overlays; j++) {
- struct omap_overlay *ovl = ovid->overlays[j];
-
- if (ovl->manager && ovl->manager->device) {
- struct omap_overlay_info info;
- ovl->get_overlay_info(ovl, &info);
- info.paddr = addr;
- if (ovl->set_overlay_info(ovl, &info)) {
- ret = -EINVAL;
- goto streamon_err1;
- }
- }
- }
-
- /* First save the configuration in ovelray structure */
- ret = omapvid_init(vout, addr);
- if (ret)
- v4l2_err(&vout->vid_dev->v4l2_dev,
- "failed to set overlay info\n");
- /* Enable the pipeline and set the Go bit */
- ret = omapvid_apply_changes(vout);
- if (ret)
- v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
-
- for (j = 0; j < ovid->num_overlays; j++) {
- struct omap_overlay *ovl = ovid->overlays[j];
-
- if (ovl->manager && ovl->manager->device) {
- ret = ovl->enable(ovl);
- if (ret)
- goto streamon_err1;
- }
- }
-
- ret = 0;
-
-streamon_err1:
- if (ret)
- ret = videobuf_streamoff(q);
-streamon_err:
- mutex_unlock(&vout->lock);
- return ret;
-}
-
-static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
-{
- u32 mask = 0;
- int ret = 0, j;
- struct omap_vout_device *vout = fh;
- struct omapvideo_info *ovid = &vout->vid_info;
-
- if (!vout->streaming)
- return -EINVAL;
-
- vout->streaming = 0;
- mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
- | DISPC_IRQ_VSYNC2;
-
- omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
-
- for (j = 0; j < ovid->num_overlays; j++) {
- struct omap_overlay *ovl = ovid->overlays[j];
-
- if (ovl->manager && ovl->manager->device)
- ovl->disable(ovl);
- }
-
- /* Turn of the pipeline */
- ret = omapvid_apply_changes(vout);
- if (ret)
- v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode in"
- " streamoff\n");
-
- INIT_LIST_HEAD(&vout->dma_queue);
- ret = videobuf_streamoff(&vout->vbq);
-
- return ret;
-}
-
-static int vidioc_s_fbuf(struct file *file, void *fh,
- struct v4l2_framebuffer *a)
-{
- int enable = 0;
- struct omap_overlay *ovl;
- struct omapvideo_info *ovid;
- struct omap_vout_device *vout = fh;
- struct omap_overlay_manager_info info;
- enum omap_dss_trans_key_type key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
-
- ovid = &vout->vid_info;
- ovl = ovid->overlays[0];
-
- /* OMAP DSS doesn't support Source and Destination color
- key together */
- if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) &&
- (a->flags & V4L2_FBUF_FLAG_CHROMAKEY))
- return -EINVAL;
- /* OMAP DSS Doesn't support the Destination color key
- and alpha blending together */
- if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY) &&
- (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA))
- return -EINVAL;
-
- if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY)) {
- vout->fbuf.flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
- key_type = OMAP_DSS_COLOR_KEY_VID_SRC;
- } else
- vout->fbuf.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY;
-
- if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY)) {
- vout->fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
- key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
- } else
- vout->fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY;
-
- if (a->flags & (V4L2_FBUF_FLAG_CHROMAKEY |
- V4L2_FBUF_FLAG_SRC_CHROMAKEY))
- enable = 1;
- else
- enable = 0;
- if (ovl->manager && ovl->manager->get_manager_info &&
- ovl->manager->set_manager_info) {
-
- ovl->manager->get_manager_info(ovl->manager, &info);
- info.trans_enabled = enable;
- info.trans_key_type = key_type;
- info.trans_key = vout->win.chromakey;
-
- if (ovl->manager->set_manager_info(ovl->manager, &info))
- return -EINVAL;
- }
- if (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) {
- vout->fbuf.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
- enable = 1;
- } else {
- vout->fbuf.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA;
- enable = 0;
- }
- if (ovl->manager && ovl->manager->get_manager_info &&
- ovl->manager->set_manager_info) {
- ovl->manager->get_manager_info(ovl->manager, &info);
- /* enable this only if there is no zorder cap */
- if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
- info.partial_alpha_enabled = enable;
- if (ovl->manager->set_manager_info(ovl->manager, &info))
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vidioc_g_fbuf(struct file *file, void *fh,
- struct v4l2_framebuffer *a)
-{
- struct omap_overlay *ovl;
- struct omapvideo_info *ovid;
- struct omap_vout_device *vout = fh;
- struct omap_overlay_manager_info info;
-
- ovid = &vout->vid_info;
- ovl = ovid->overlays[0];
-
- /* The video overlay must stay within the framebuffer and can't be
- positioned independently. */
- a->flags = V4L2_FBUF_FLAG_OVERLAY;
- a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY
- | V4L2_FBUF_CAP_SRC_CHROMAKEY;
-
- if (ovl->manager && ovl->manager->get_manager_info) {
- ovl->manager->get_manager_info(ovl->manager, &info);
- if (info.trans_key_type == OMAP_DSS_COLOR_KEY_VID_SRC)
- a->flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
- if (info.trans_key_type == OMAP_DSS_COLOR_KEY_GFX_DST)
- a->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
- }
- if (ovl->manager && ovl->manager->get_manager_info) {
- ovl->manager->get_manager_info(ovl->manager, &info);
- if (info.partial_alpha_enabled)
- a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
- }
-
- return 0;
-}
-
-static const struct v4l2_ioctl_ops vout_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
- .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out,
- .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
- .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_fbuf = vidioc_s_fbuf,
- .vidioc_g_fbuf = vidioc_g_fbuf,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
- .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
- .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay,
- .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
- .vidioc_cropcap = vidioc_cropcap,
- .vidioc_g_crop = vidioc_g_crop,
- .vidioc_s_crop = vidioc_s_crop,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
-};
-
-static const struct v4l2_file_operations omap_vout_fops = {
- .owner = THIS_MODULE,
- .poll = omap_vout_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = omap_vout_mmap,
- .open = omap_vout_open,
- .release = omap_vout_release,
-};
-
-/* Init functions used during driver initialization */
-/* Initial setup of video_data */
-static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
-{
- struct video_device *vfd;
- struct v4l2_pix_format *pix;
- struct v4l2_control *control;
- struct omap_dss_device *display =
- vout->vid_info.overlays[0]->manager->device;
-
- /* set the default pix */
- pix = &vout->pix;
-
- /* Set the default picture of QVGA */
- pix->width = QQVGA_WIDTH;
- pix->height = QQVGA_HEIGHT;
-
- /* Default pixel format is RGB 5-6-5 */
- pix->pixelformat = V4L2_PIX_FMT_RGB565;
- pix->field = V4L2_FIELD_ANY;
- pix->bytesperline = pix->width * 2;
- pix->sizeimage = pix->bytesperline * pix->height;
- pix->priv = 0;
- pix->colorspace = V4L2_COLORSPACE_JPEG;
-
- vout->bpp = RGB565_BPP;
- vout->fbuf.fmt.width = display->panel.timings.x_res;
- vout->fbuf.fmt.height = display->panel.timings.y_res;
-
- /* Set the data structures for the overlay parameters*/
- vout->win.global_alpha = 255;
- vout->fbuf.flags = 0;
- vout->fbuf.capability = V4L2_FBUF_CAP_LOCAL_ALPHA |
- V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_CHROMAKEY;
- vout->win.chromakey = 0;
-
- omap_vout_new_format(pix, &vout->fbuf, &vout->crop, &vout->win);
-
- /*Initialize the control variables for
- rotation, flipping and background color. */
- control = vout->control;
- control[0].id = V4L2_CID_ROTATE;
- control[0].value = 0;
- vout->rotation = 0;
- vout->mirror = 0;
- vout->control[2].id = V4L2_CID_HFLIP;
- vout->control[2].value = 0;
- if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
- vout->vrfb_bpp = 2;
-
- control[1].id = V4L2_CID_BG_COLOR;
- control[1].value = 0;
-
- /* initialize the video_device struct */
- vfd = vout->vfd = video_device_alloc();
-
- if (!vfd) {
- printk(KERN_ERR VOUT_NAME ": could not allocate"
- " video device struct\n");
- return -ENOMEM;
- }
- vfd->release = video_device_release;
- vfd->ioctl_ops = &vout_ioctl_ops;
-
- strlcpy(vfd->name, VOUT_NAME, sizeof(vfd->name));
-
- vfd->fops = &omap_vout_fops;
- vfd->v4l2_dev = &vout->vid_dev->v4l2_dev;
- mutex_init(&vout->lock);
-
- vfd->minor = -1;
- return 0;
-
-}
-
-/* Setup video buffers */
-static int __init omap_vout_setup_video_bufs(struct platform_device *pdev,
- int vid_num)
-{
- u32 numbuffers;
- int ret = 0, i;
- struct omapvideo_info *ovid;
- struct omap_vout_device *vout;
- struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
- struct omap2video_device *vid_dev =
- container_of(v4l2_dev, struct omap2video_device, v4l2_dev);
-
- vout = vid_dev->vouts[vid_num];
- ovid = &vout->vid_info;
-
- numbuffers = (vid_num == 0) ? video1_numbuffers : video2_numbuffers;
- vout->buffer_size = (vid_num == 0) ? video1_bufsize : video2_bufsize;
- dev_info(&pdev->dev, "Buffer Size = %d\n", vout->buffer_size);
-
- for (i = 0; i < numbuffers; i++) {
- vout->buf_virt_addr[i] =
- omap_vout_alloc_buffer(vout->buffer_size,
- (u32 *) &vout->buf_phy_addr[i]);
- if (!vout->buf_virt_addr[i]) {
- numbuffers = i;
- ret = -ENOMEM;
- goto free_buffers;
- }
- }
-
- vout->cropped_offset = 0;
-
- if (ovid->rotation_type == VOUT_ROT_VRFB) {
- int static_vrfb_allocation = (vid_num == 0) ?
- vid1_static_vrfb_alloc : vid2_static_vrfb_alloc;
- ret = omap_vout_setup_vrfb_bufs(pdev, vid_num,
- static_vrfb_allocation);
- }
-
- return ret;
-
-free_buffers:
- for (i = 0; i < numbuffers; i++) {
- omap_vout_free_buffer(vout->buf_virt_addr[i],
- vout->buffer_size);
- vout->buf_virt_addr[i] = 0;
- vout->buf_phy_addr[i] = 0;
- }
- return ret;
-
-}
-
-/* Create video out devices */
-static int __init omap_vout_create_video_devices(struct platform_device *pdev)
-{
- int ret = 0, k;
- struct omap_vout_device *vout;
- struct video_device *vfd = NULL;
- struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
- struct omap2video_device *vid_dev = container_of(v4l2_dev,
- struct omap2video_device, v4l2_dev);
-
- for (k = 0; k < pdev->num_resources; k++) {
-
- vout = kzalloc(sizeof(struct omap_vout_device), GFP_KERNEL);
- if (!vout) {
- dev_err(&pdev->dev, ": could not allocate memory\n");
- return -ENOMEM;
- }
-
- vout->vid = k;
- vid_dev->vouts[k] = vout;
- vout->vid_dev = vid_dev;
- /* Select video2 if only 1 overlay is controlled by V4L2 */
- if (pdev->num_resources == 1)
- vout->vid_info.overlays[0] = vid_dev->overlays[k + 2];
- else
- /* Else select video1 and video2 one by one. */
- vout->vid_info.overlays[0] = vid_dev->overlays[k + 1];
- vout->vid_info.num_overlays = 1;
- vout->vid_info.id = k + 1;
-
- /* Set VRFB as rotation_type for omap2 and omap3 */
- if (cpu_is_omap24xx() || cpu_is_omap34xx())
- vout->vid_info.rotation_type = VOUT_ROT_VRFB;
-
- /* Setup the default configuration for the video devices
- */
- if (omap_vout_setup_video_data(vout) != 0) {
- ret = -ENOMEM;
- goto error;
- }
-
- /* Allocate default number of buffers for the video streaming
- * and reserve the VRFB space for rotation
- */
- if (omap_vout_setup_video_bufs(pdev, k) != 0) {
- ret = -ENOMEM;
- goto error1;
- }
-
- /* Register the Video device with V4L2
- */
- vfd = vout->vfd;
- if (video_register_device(vfd, VFL_TYPE_GRABBER, -1) < 0) {
- dev_err(&pdev->dev, ": Could not register "
- "Video for Linux device\n");
- vfd->minor = -1;
- ret = -ENODEV;
- goto error2;
- }
- video_set_drvdata(vfd, vout);
-
- /* Configure the overlay structure */
- ret = omapvid_init(vid_dev->vouts[k], 0);
- if (!ret)
- goto success;
-
-error2:
- if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
- omap_vout_release_vrfb(vout);
- omap_vout_free_buffers(vout);
-error1:
- video_device_release(vfd);
-error:
- kfree(vout);
- return ret;
-
-success:
- dev_info(&pdev->dev, ": registered and initialized"
- " video device %d\n", vfd->minor);
- if (k == (pdev->num_resources - 1))
- return 0;
- }
-
- return -ENODEV;
-}
-/* Driver functions */
-static void omap_vout_cleanup_device(struct omap_vout_device *vout)
-{
- struct video_device *vfd;
- struct omapvideo_info *ovid;
-
- if (!vout)
- return;
-
- vfd = vout->vfd;
- ovid = &vout->vid_info;
- if (vfd) {
- if (!video_is_registered(vfd)) {
- /*
- * The device was never registered, so release the
- * video_device struct directly.
- */
- video_device_release(vfd);
- } else {
- /*
- * The unregister function will release the video_device
- * struct as well as unregistering it.
- */
- video_unregister_device(vfd);
- }
- }
- if (ovid->rotation_type == VOUT_ROT_VRFB) {
- omap_vout_release_vrfb(vout);
- /* Free the VRFB buffer if allocated
- * init time
- */
- if (vout->vrfb_static_allocation)
- omap_vout_free_vrfb_buffers(vout);
- }
- omap_vout_free_buffers(vout);
-
- kfree(vout);
-}
-
-static int omap_vout_remove(struct platform_device *pdev)
-{
- int k;
- struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
- struct omap2video_device *vid_dev = container_of(v4l2_dev, struct
- omap2video_device, v4l2_dev);
-
- v4l2_device_unregister(v4l2_dev);
- for (k = 0; k < pdev->num_resources; k++)
- omap_vout_cleanup_device(vid_dev->vouts[k]);
-
- for (k = 0; k < vid_dev->num_displays; k++) {
- if (vid_dev->displays[k]->state != OMAP_DSS_DISPLAY_DISABLED)
- vid_dev->displays[k]->driver->disable(vid_dev->displays[k]);
-
- omap_dss_put_device(vid_dev->displays[k]);
- }
- kfree(vid_dev);
- return 0;
-}
-
-static int __init omap_vout_probe(struct platform_device *pdev)
-{
- int ret = 0, i;
- struct omap_overlay *ovl;
- struct omap_dss_device *dssdev = NULL;
- struct omap_dss_device *def_display;
- struct omap2video_device *vid_dev = NULL;
-
- if (pdev->num_resources == 0) {
- dev_err(&pdev->dev, "probed for an unknown device\n");
- return -ENODEV;
- }
-
- vid_dev = kzalloc(sizeof(struct omap2video_device), GFP_KERNEL);
- if (vid_dev == NULL)
- return -ENOMEM;
-
- vid_dev->num_displays = 0;
- for_each_dss_dev(dssdev) {
- omap_dss_get_device(dssdev);
-
- if (!dssdev->driver) {
- dev_warn(&pdev->dev, "no driver for display: %s\n",
- dssdev->name);
- omap_dss_put_device(dssdev);
- continue;
- }
-
- vid_dev->displays[vid_dev->num_displays++] = dssdev;
- }
-
- if (vid_dev->num_displays == 0) {
- dev_err(&pdev->dev, "no displays\n");
- ret = -EINVAL;
- goto probe_err0;
- }
-
- vid_dev->num_overlays = omap_dss_get_num_overlays();
- for (i = 0; i < vid_dev->num_overlays; i++)
- vid_dev->overlays[i] = omap_dss_get_overlay(i);
-
- vid_dev->num_managers = omap_dss_get_num_overlay_managers();
- for (i = 0; i < vid_dev->num_managers; i++)
- vid_dev->managers[i] = omap_dss_get_overlay_manager(i);
-
- /* Get the Video1 overlay and video2 overlay.
- * Setup the Display attached to that overlays
- */
- for (i = 1; i < vid_dev->num_overlays; i++) {
- ovl = omap_dss_get_overlay(i);
- if (ovl->manager && ovl->manager->device) {
- def_display = ovl->manager->device;
- } else {
- dev_warn(&pdev->dev, "cannot find display\n");
- def_display = NULL;
- }
- if (def_display) {
- struct omap_dss_driver *dssdrv = def_display->driver;
-
- ret = dssdrv->enable(def_display);
- if (ret) {
- /* Here we are not considering a error
- * as display may be enabled by frame
- * buffer driver
- */
- dev_warn(&pdev->dev,
- "'%s' Display already enabled\n",
- def_display->name);
- }
- }
- }
-
- if (v4l2_device_register(&pdev->dev, &vid_dev->v4l2_dev) < 0) {
- dev_err(&pdev->dev, "v4l2_device_register failed\n");
- ret = -ENODEV;
- goto probe_err1;
- }
-
- ret = omap_vout_create_video_devices(pdev);
- if (ret)
- goto probe_err2;
-
- for (i = 0; i < vid_dev->num_displays; i++) {
- struct omap_dss_device *display = vid_dev->displays[i];
-
- if (display->driver->update)
- display->driver->update(display, 0, 0,
- display->panel.timings.x_res,
- display->panel.timings.y_res);
- }
- return 0;
-
-probe_err2:
- v4l2_device_unregister(&vid_dev->v4l2_dev);
-probe_err1:
- for (i = 1; i < vid_dev->num_overlays; i++) {
- def_display = NULL;
- ovl = omap_dss_get_overlay(i);
- if (ovl->manager && ovl->manager->device)
- def_display = ovl->manager->device;
-
- if (def_display && def_display->driver)
- def_display->driver->disable(def_display);
- }
-probe_err0:
- kfree(vid_dev);
- return ret;
-}
-
-static struct platform_driver omap_vout_driver = {
- .driver = {
- .name = VOUT_NAME,
- },
- .remove = omap_vout_remove,
-};
-
-static int __init omap_vout_init(void)
-{
- if (platform_driver_probe(&omap_vout_driver, omap_vout_probe) != 0) {
- printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n");
- return -EINVAL;
- }
- return 0;
-}
-
-static void omap_vout_cleanup(void)
-{
- platform_driver_unregister(&omap_vout_driver);
-}
-
-late_initcall(omap_vout_init);
-module_exit(omap_vout_cleanup);
diff --git a/drivers/media/video/omap/omap_vout_vrfb.c b/drivers/media/video/omap/omap_vout_vrfb.c
deleted file mode 100644
index 4be26abf6ce..00000000000
--- a/drivers/media/video/omap/omap_vout_vrfb.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * omap_vout_vrfb.c
- *
- * Copyright (C) 2010 Texas Instruments.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- *
- */
-
-#include <linux/sched.h>
-#include <linux/platform_device.h>
-#include <linux/videodev2.h>
-
-#include <media/videobuf-dma-contig.h>
-#include <media/v4l2-device.h>
-
-#include <plat/dma.h>
-#include <plat/vrfb.h>
-
-#include "omap_voutdef.h"
-#include "omap_voutlib.h"
-
-/*
- * Function for allocating video buffers
- */
-static int omap_vout_allocate_vrfb_buffers(struct omap_vout_device *vout,
- unsigned int *count, int startindex)
-{
- int i, j;
-
- for (i = 0; i < *count; i++) {
- if (!vout->smsshado_virt_addr[i]) {
- vout->smsshado_virt_addr[i] =
- omap_vout_alloc_buffer(vout->smsshado_size,
- &vout->smsshado_phy_addr[i]);
- }
- if (!vout->smsshado_virt_addr[i] && startindex != -1) {
- if (V4L2_MEMORY_MMAP == vout->memory && i >= startindex)
- break;
- }
- if (!vout->smsshado_virt_addr[i]) {
- for (j = 0; j < i; j++) {
- omap_vout_free_buffer(
- vout->smsshado_virt_addr[j],
- vout->smsshado_size);
- vout->smsshado_virt_addr[j] = 0;
- vout->smsshado_phy_addr[j] = 0;
- }
- *count = 0;
- return -ENOMEM;
- }
- memset((void *) vout->smsshado_virt_addr[i], 0,
- vout->smsshado_size);
- }
- return 0;
-}
-
-/*
- * Wakes up the application once the DMA transfer to VRFB space is completed.
- */
-static void omap_vout_vrfb_dma_tx_callback(int lch, u16 ch_status, void *data)
-{
- struct vid_vrfb_dma *t = (struct vid_vrfb_dma *) data;
-
- t->tx_status = 1;
- wake_up_interruptible(&t->wait);
-}
-
-/*
- * Free VRFB buffers
- */
-void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout)
-{
- int j;
-
- for (j = 0; j < VRFB_NUM_BUFS; j++) {
- omap_vout_free_buffer(vout->smsshado_virt_addr[j],
- vout->smsshado_size);
- vout->smsshado_virt_addr[j] = 0;
- vout->smsshado_phy_addr[j] = 0;
- }
-}
-
-int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
- bool static_vrfb_allocation)
-{
- int ret = 0, i, j;
- struct omap_vout_device *vout;
- struct video_device *vfd;
- int image_width, image_height;
- int vrfb_num_bufs = VRFB_NUM_BUFS;
- struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
- struct omap2video_device *vid_dev =
- container_of(v4l2_dev, struct omap2video_device, v4l2_dev);
-
- vout = vid_dev->vouts[vid_num];
- vfd = vout->vfd;
-
- for (i = 0; i < VRFB_NUM_BUFS; i++) {
- if (omap_vrfb_request_ctx(&vout->vrfb_context[i])) {
- dev_info(&pdev->dev, ": VRFB allocation failed\n");
- for (j = 0; j < i; j++)
- omap_vrfb_release_ctx(&vout->vrfb_context[j]);
- ret = -ENOMEM;
- goto free_buffers;
- }
- }
-
- /* Calculate VRFB memory size */
- /* allocate for worst case size */
- image_width = VID_MAX_WIDTH / TILE_SIZE;
- if (VID_MAX_WIDTH % TILE_SIZE)
- image_width++;
-
- image_width = image_width * TILE_SIZE;
- image_height = VID_MAX_HEIGHT / TILE_SIZE;
-
- if (VID_MAX_HEIGHT % TILE_SIZE)
- image_height++;
-
- image_height = image_height * TILE_SIZE;
- vout->smsshado_size = PAGE_ALIGN(image_width * image_height * 2 * 2);
-
- /*
- * Request and Initialize DMA, for DMA based VRFB transfer
- */
- vout->vrfb_dma_tx.dev_id = OMAP_DMA_NO_DEVICE;
- vout->vrfb_dma_tx.dma_ch = -1;
- vout->vrfb_dma_tx.req_status = DMA_CHAN_ALLOTED;
- ret = omap_request_dma(vout->vrfb_dma_tx.dev_id, "VRFB DMA TX",
- omap_vout_vrfb_dma_tx_callback,
- (void *) &vout->vrfb_dma_tx, &vout->vrfb_dma_tx.dma_ch);
- if (ret < 0) {
- vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
- dev_info(&pdev->dev, ": failed to allocate DMA Channel for"
- " video%d\n", vfd->minor);
- }
- init_waitqueue_head(&vout->vrfb_dma_tx.wait);
-
- /* statically allocated the VRFB buffer is done through
- commands line aruments */
- if (static_vrfb_allocation) {
- if (omap_vout_allocate_vrfb_buffers(vout, &vrfb_num_bufs, -1)) {
- ret = -ENOMEM;
- goto release_vrfb_ctx;
- }
- vout->vrfb_static_allocation = 1;
- }
- return 0;
-
-release_vrfb_ctx:
- for (j = 0; j < VRFB_NUM_BUFS; j++)
- omap_vrfb_release_ctx(&vout->vrfb_context[j]);
-free_buffers:
- omap_vout_free_buffers(vout);
-
- return ret;
-}
-
-/*
- * Release the VRFB context once the module exits
- */
-void omap_vout_release_vrfb(struct omap_vout_device *vout)
-{
- int i;
-
- for (i = 0; i < VRFB_NUM_BUFS; i++)
- omap_vrfb_release_ctx(&vout->vrfb_context[i]);
-
- if (vout->vrfb_dma_tx.req_status == DMA_CHAN_ALLOTED) {
- vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
- omap_free_dma(vout->vrfb_dma_tx.dma_ch);
- }
-}
-
-/*
- * Allocate the buffers for the VRFB space. Data is copied from V4L2
- * buffers to the VRFB buffers using the DMA engine.
- */
-int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
- unsigned int *count, unsigned int startindex)
-{
- int i;
- bool yuv_mode;
-
- if (!is_rotation_enabled(vout))
- return 0;
-
- /* If rotation is enabled, allocate memory for VRFB space also */
- *count = *count > VRFB_NUM_BUFS ? VRFB_NUM_BUFS : *count;
-
- /* Allocate the VRFB buffers only if the buffers are not
- * allocated during init time.
- */
- if (!vout->vrfb_static_allocation)
- if (omap_vout_allocate_vrfb_buffers(vout, count, startindex))
- return -ENOMEM;
-
- if (vout->dss_mode == OMAP_DSS_COLOR_YUV2 ||
- vout->dss_mode == OMAP_DSS_COLOR_UYVY)
- yuv_mode = true;
- else
- yuv_mode = false;
-
- for (i = 0; i < *count; i++)
- omap_vrfb_setup(&vout->vrfb_context[i],
- vout->smsshado_phy_addr[i], vout->pix.width,
- vout->pix.height, vout->bpp, yuv_mode);
-
- return 0;
-}
-
-int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
- struct videobuf_buffer *vb)
-{
- dma_addr_t dmabuf;
- struct vid_vrfb_dma *tx;
- enum dss_rotation rotation;
- u32 dest_frame_index = 0, src_element_index = 0;
- u32 dest_element_index = 0, src_frame_index = 0;
- u32 elem_count = 0, frame_count = 0, pixsize = 2;
-
- if (!is_rotation_enabled(vout))
- return 0;
-
- dmabuf = vout->buf_phy_addr[vb->i];
- /* If rotation is enabled, copy input buffer into VRFB
- * memory space using DMA. We are copying input buffer
- * into VRFB memory space of desired angle and DSS will
- * read image VRFB memory for 0 degree angle
- */
- pixsize = vout->bpp * vout->vrfb_bpp;
- /*
- * DMA transfer in double index mode
- */
-
- /* Frame index */
- dest_frame_index = ((MAX_PIXELS_PER_LINE * pixsize) -
- (vout->pix.width * vout->bpp)) + 1;
-
- /* Source and destination parameters */
- src_element_index = 0;
- src_frame_index = 0;
- dest_element_index = 1;
- /* Number of elements per frame */
- elem_count = vout->pix.width * vout->bpp;
- frame_count = vout->pix.height;
- tx = &vout->vrfb_dma_tx;
- tx->tx_status = 0;
- omap_set_dma_transfer_params(tx->dma_ch, OMAP_DMA_DATA_TYPE_S32,
- (elem_count / 4), frame_count, OMAP_DMA_SYNC_ELEMENT,
- tx->dev_id, 0x0);
- /* src_port required only for OMAP1 */
- omap_set_dma_src_params(tx->dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
- dmabuf, src_element_index, src_frame_index);
- /*set dma source burst mode for VRFB */
- omap_set_dma_src_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
- rotation = calc_rotation(vout);
-
- /* dest_port required only for OMAP1 */
- omap_set_dma_dest_params(tx->dma_ch, 0, OMAP_DMA_AMODE_DOUBLE_IDX,
- vout->vrfb_context[vb->i].paddr[0], dest_element_index,
- dest_frame_index);
- /*set dma dest burst mode for VRFB */
- omap_set_dma_dest_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
- omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE, 0x20, 0);
-
- omap_start_dma(tx->dma_ch);
- interruptible_sleep_on_timeout(&tx->wait, VRFB_TX_TIMEOUT);
-
- if (tx->tx_status == 0) {
- omap_stop_dma(tx->dma_ch);
- return -EINVAL;
- }
- /* Store buffers physical address into an array. Addresses
- * from this array will be used to configure DSS */
- vout->queued_buf_addr[vb->i] = (u8 *)
- vout->vrfb_context[vb->i].paddr[rotation];
- return 0;
-}
-
-/*
- * Calculate the buffer offsets from which the streaming should
- * start. This offset calculation is mainly required because of
- * the VRFB 32 pixels alignment with rotation.
- */
-void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout)
-{
- enum dss_rotation rotation;
- bool mirroring = vout->mirror;
- struct v4l2_rect *crop = &vout->crop;
- struct v4l2_pix_format *pix = &vout->pix;
- int *cropped_offset = &vout->cropped_offset;
- int vr_ps = 1, ps = 2, temp_ps = 2;
- int offset = 0, ctop = 0, cleft = 0, line_length = 0;
-
- rotation = calc_rotation(vout);
-
- if (V4L2_PIX_FMT_YUYV == pix->pixelformat ||
- V4L2_PIX_FMT_UYVY == pix->pixelformat) {
- if (is_rotation_enabled(vout)) {
- /*
- * ps - Actual pixel size for YUYV/UYVY for
- * VRFB/Mirroring is 4 bytes
- * vr_ps - Virtually pixel size for YUYV/UYVY is
- * 2 bytes
- */
- ps = 4;
- vr_ps = 2;
- } else {
- ps = 2; /* otherwise the pixel size is 2 byte */
- }
- } else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat) {
- ps = 4;
- } else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat) {
- ps = 3;
- }
- vout->ps = ps;
- vout->vr_ps = vr_ps;
-
- if (is_rotation_enabled(vout)) {
- line_length = MAX_PIXELS_PER_LINE;
- ctop = (pix->height - crop->height) - crop->top;
- cleft = (pix->width - crop->width) - crop->left;
- } else {
- line_length = pix->width;
- }
- vout->line_length = line_length;
- switch (rotation) {
- case dss_rotation_90_degree:
- offset = vout->vrfb_context[0].yoffset *
- vout->vrfb_context[0].bytespp;
- temp_ps = ps / vr_ps;
- if (mirroring == 0) {
- *cropped_offset = offset + line_length *
- temp_ps * cleft + crop->top * temp_ps;
- } else {
- *cropped_offset = offset + line_length * temp_ps *
- cleft + crop->top * temp_ps + (line_length *
- ((crop->width / (vr_ps)) - 1) * ps);
- }
- break;
- case dss_rotation_180_degree:
- offset = ((MAX_PIXELS_PER_LINE * vout->vrfb_context[0].yoffset *
- vout->vrfb_context[0].bytespp) +
- (vout->vrfb_context[0].xoffset *
- vout->vrfb_context[0].bytespp));
- if (mirroring == 0) {
- *cropped_offset = offset + (line_length * ps * ctop) +
- (cleft / vr_ps) * ps;
-
- } else {
- *cropped_offset = offset + (line_length * ps * ctop) +
- (cleft / vr_ps) * ps + (line_length *
- (crop->height - 1) * ps);
- }
- break;
- case dss_rotation_270_degree:
- offset = MAX_PIXELS_PER_LINE * vout->vrfb_context[0].xoffset *
- vout->vrfb_context[0].bytespp;
- temp_ps = ps / vr_ps;
- if (mirroring == 0) {
- *cropped_offset = offset + line_length *
- temp_ps * crop->left + ctop * ps;
- } else {
- *cropped_offset = offset + line_length *
- temp_ps * crop->left + ctop * ps +
- (line_length * ((crop->width / vr_ps) - 1) *
- ps);
- }
- break;
- case dss_rotation_0_degree:
- if (mirroring == 0) {
- *cropped_offset = (line_length * ps) *
- crop->top + (crop->left / vr_ps) * ps;
- } else {
- *cropped_offset = (line_length * ps) *
- crop->top + (crop->left / vr_ps) * ps +
- (line_length * (crop->height - 1) * ps);
- }
- break;
- default:
- *cropped_offset = (line_length * ps * crop->top) /
- vr_ps + (crop->left * ps) / vr_ps +
- ((crop->width / vr_ps) - 1) * ps;
- break;
- }
-}
diff --git a/drivers/media/video/omap/omap_vout_vrfb.h b/drivers/media/video/omap/omap_vout_vrfb.h
deleted file mode 100644
index ffde741e059..00000000000
--- a/drivers/media/video/omap/omap_vout_vrfb.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * omap_vout_vrfb.h
- *
- * Copyright (C) 2010 Texas Instruments.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- *
- */
-
-#ifndef OMAP_VOUT_VRFB_H
-#define OMAP_VOUT_VRFB_H
-
-#ifdef CONFIG_VIDEO_OMAP2_VOUT_VRFB
-void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout);
-int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
- u32 static_vrfb_allocation);
-void omap_vout_release_vrfb(struct omap_vout_device *vout);
-int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
- unsigned int *count, unsigned int startindex);
-int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
- struct videobuf_buffer *vb);
-void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout);
-#else
-void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout) { }
-int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
- u32 static_vrfb_allocation)
- { return 0; }
-void omap_vout_release_vrfb(struct omap_vout_device *vout) { }
-int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
- unsigned int *count, unsigned int startindex)
- { return 0; }
-int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
- struct videobuf_buffer *vb)
- { return 0; }
-void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout) { }
-#endif
-
-#endif
diff --git a/drivers/media/video/omap/omap_voutdef.h b/drivers/media/video/omap/omap_voutdef.h
deleted file mode 100644
index 27a95d23b91..00000000000
--- a/drivers/media/video/omap/omap_voutdef.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * omap_voutdef.h
- *
- * Copyright (C) 2010 Texas Instruments.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#ifndef OMAP_VOUTDEF_H
-#define OMAP_VOUTDEF_H
-
-#include <video/omapdss.h>
-#include <plat/vrfb.h>
-
-#define YUYV_BPP 2
-#define RGB565_BPP 2
-#define RGB24_BPP 3
-#define RGB32_BPP 4
-#define TILE_SIZE 32
-#define YUYV_VRFB_BPP 2
-#define RGB_VRFB_BPP 1
-#define MAX_CID 3
-#define MAC_VRFB_CTXS 4
-#define MAX_VOUT_DEV 2
-#define MAX_OVLS 3
-#define MAX_DISPLAYS 10
-#define MAX_MANAGERS 3
-
-#define QQVGA_WIDTH 160
-#define QQVGA_HEIGHT 120
-
-/* Max Resolution supported by the driver */
-#define VID_MAX_WIDTH 1280 /* Largest width */
-#define VID_MAX_HEIGHT 720 /* Largest height */
-
-/* Mimimum requirement is 2x2 for DSS */
-#define VID_MIN_WIDTH 2
-#define VID_MIN_HEIGHT 2
-
-/* 2048 x 2048 is max res supported by OMAP display controller */
-#define MAX_PIXELS_PER_LINE 2048
-
-#define VRFB_TX_TIMEOUT 1000
-#define VRFB_NUM_BUFS 4
-
-/* Max buffer size tobe allocated during init */
-#define OMAP_VOUT_MAX_BUF_SIZE (VID_MAX_WIDTH*VID_MAX_HEIGHT*4)
-
-enum dma_channel_state {
- DMA_CHAN_NOT_ALLOTED,
- DMA_CHAN_ALLOTED,
-};
-
-/* Enum for Rotation
- * DSS understands rotation in 0, 1, 2, 3 context
- * while V4L2 driver understands it as 0, 90, 180, 270
- */
-enum dss_rotation {
- dss_rotation_0_degree = 0,
- dss_rotation_90_degree = 1,
- dss_rotation_180_degree = 2,
- dss_rotation_270_degree = 3,
-};
-
-/* Enum for choosing rotation type for vout
- * DSS2 doesn't understand no rotation as an
- * option while V4L2 driver doesn't support
- * rotation in the case where VRFB is not built in
- * the kernel
- */
-enum vout_rotaion_type {
- VOUT_ROT_NONE = 0,
- VOUT_ROT_VRFB = 1,
-};
-
-/*
- * This structure is used to store the DMA transfer parameters
- * for VRFB hidden buffer
- */
-struct vid_vrfb_dma {
- int dev_id;
- int dma_ch;
- int req_status;
- int tx_status;
- wait_queue_head_t wait;
-};
-
-struct omapvideo_info {
- int id;
- int num_overlays;
- struct omap_overlay *overlays[MAX_OVLS];
- enum vout_rotaion_type rotation_type;
-};
-
-struct omap2video_device {
- struct mutex mtx;
-
- int state;
-
- struct v4l2_device v4l2_dev;
- struct omap_vout_device *vouts[MAX_VOUT_DEV];
-
- int num_displays;
- struct omap_dss_device *displays[MAX_DISPLAYS];
- int num_overlays;
- struct omap_overlay *overlays[MAX_OVLS];
- int num_managers;
- struct omap_overlay_manager *managers[MAX_MANAGERS];
-};
-
-/* per-device data structure */
-struct omap_vout_device {
-
- struct omapvideo_info vid_info;
- struct video_device *vfd;
- struct omap2video_device *vid_dev;
- int vid;
- int opened;
-
- /* we don't allow to change image fmt/size once buffer has
- * been allocated
- */
- int buffer_allocated;
- /* allow to reuse previously allocated buffer which is big enough */
- int buffer_size;
- /* keep buffer info across opens */
- unsigned long buf_virt_addr[VIDEO_MAX_FRAME];
- unsigned long buf_phy_addr[VIDEO_MAX_FRAME];
- enum omap_color_mode dss_mode;
-
- /* we don't allow to request new buffer when old buffers are
- * still mmaped
- */
- int mmap_count;
-
- spinlock_t vbq_lock; /* spinlock for videobuf queues */
- unsigned long field_count; /* field counter for videobuf_buffer */
-
- /* non-NULL means streaming is in progress. */
- bool streaming;
-
- struct v4l2_pix_format pix;
- struct v4l2_rect crop;
- struct v4l2_window win;
- struct v4l2_framebuffer fbuf;
-
- /* Lock to protect the shared data structures in ioctl */
- struct mutex lock;
-
- /* V4L2 control structure for different control id */
- struct v4l2_control control[MAX_CID];
- enum dss_rotation rotation;
- bool mirror;
- int flicker_filter;
- /* V4L2 control structure for different control id */
-
- int bpp; /* bytes per pixel */
- int vrfb_bpp; /* bytes per pixel with respect to VRFB */
-
- struct vid_vrfb_dma vrfb_dma_tx;
- unsigned int smsshado_phy_addr[MAC_VRFB_CTXS];
- unsigned int smsshado_virt_addr[MAC_VRFB_CTXS];
- struct vrfb vrfb_context[MAC_VRFB_CTXS];
- bool vrfb_static_allocation;
- unsigned int smsshado_size;
- unsigned char pos;
-
- int ps, vr_ps, line_length, first_int, field_id;
- enum v4l2_memory memory;
- struct videobuf_buffer *cur_frm, *next_frm;
- struct list_head dma_queue;
- u8 *queued_buf_addr[VIDEO_MAX_FRAME];
- u32 cropped_offset;
- s32 tv_field1_offset;
- void *isr_handle;
-
- /* Buffer queue variables */
- struct omap_vout_device *vout;
- enum v4l2_buf_type type;
- struct videobuf_queue vbq;
- int io_allowed;
-
-};
-
-/*
- * Return true if rotation is 90 or 270
- */
-static inline int is_rotation_90_or_270(const struct omap_vout_device *vout)
-{
- return (vout->rotation == dss_rotation_90_degree ||
- vout->rotation == dss_rotation_270_degree);
-}
-
-/*
- * Return true if rotation is enabled
- */
-static inline int is_rotation_enabled(const struct omap_vout_device *vout)
-{
- return vout->rotation || vout->mirror;
-}
-
-/*
- * Reverse the rotation degree if mirroring is enabled
- */
-static inline int calc_rotation(const struct omap_vout_device *vout)
-{
- if (!vout->mirror)
- return vout->rotation;
-
- switch (vout->rotation) {
- case dss_rotation_90_degree:
- return dss_rotation_270_degree;
- case dss_rotation_270_degree:
- return dss_rotation_90_degree;
- case dss_rotation_180_degree:
- return dss_rotation_0_degree;
- default:
- return dss_rotation_180_degree;
- }
-}
-
-void omap_vout_free_buffers(struct omap_vout_device *vout);
-#endif /* ifndef OMAP_VOUTDEF_H */
diff --git a/drivers/media/video/omap/omap_voutlib.c b/drivers/media/video/omap/omap_voutlib.c
deleted file mode 100644
index 115408b9274..00000000000
--- a/drivers/media/video/omap/omap_voutlib.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * omap_voutlib.c
- *
- * Copyright (C) 2005-2010 Texas Instruments.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- *
- * Based on the OMAP2 camera driver
- * Video-for-Linux (Version 2) camera capture driver for
- * the OMAP24xx camera controller.
- *
- * Author: Andy Lowe (source@mvista.com)
- *
- * Copyright (C) 2004 MontaVista Software, Inc.
- * Copyright (C) 2010 Texas Instruments.
- *
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-
-#include <linux/dma-mapping.h>
-
-#include <plat/cpu.h>
-
-#include "omap_voutlib.h"
-
-MODULE_AUTHOR("Texas Instruments");
-MODULE_DESCRIPTION("OMAP Video library");
-MODULE_LICENSE("GPL");
-
-/* Return the default overlay cropping rectangle in crop given the image
- * size in pix and the video display size in fbuf. The default
- * cropping rectangle is the largest rectangle no larger than the capture size
- * that will fit on the display. The default cropping rectangle is centered in
- * the image. All dimensions and offsets are rounded down to even numbers.
- */
-void omap_vout_default_crop(struct v4l2_pix_format *pix,
- struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop)
-{
- crop->width = (pix->width < fbuf->fmt.width) ?
- pix->width : fbuf->fmt.width;
- crop->height = (pix->height < fbuf->fmt.height) ?
- pix->height : fbuf->fmt.height;
- crop->width &= ~1;
- crop->height &= ~1;
- crop->left = ((pix->width - crop->width) >> 1) & ~1;
- crop->top = ((pix->height - crop->height) >> 1) & ~1;
-}
-EXPORT_SYMBOL_GPL(omap_vout_default_crop);
-
-/* Given a new render window in new_win, adjust the window to the
- * nearest supported configuration. The adjusted window parameters are
- * returned in new_win.
- * Returns zero if successful, or -EINVAL if the requested window is
- * impossible and cannot reasonably be adjusted.
- */
-int omap_vout_try_window(struct v4l2_framebuffer *fbuf,
- struct v4l2_window *new_win)
-{
- struct v4l2_rect try_win;
-
- /* make a working copy of the new_win rectangle */
- try_win = new_win->w;
-
- /* adjust the preview window so it fits on the display by clipping any
- * offscreen areas
- */
- if (try_win.left < 0) {
- try_win.width += try_win.left;
- try_win.left = 0;
- }
- if (try_win.top < 0) {
- try_win.height += try_win.top;
- try_win.top = 0;
- }
- try_win.width = (try_win.width < fbuf->fmt.width) ?
- try_win.width : fbuf->fmt.width;
- try_win.height = (try_win.height < fbuf->fmt.height) ?
- try_win.height : fbuf->fmt.height;
- if (try_win.left + try_win.width > fbuf->fmt.width)
- try_win.width = fbuf->fmt.width - try_win.left;
- if (try_win.top + try_win.height > fbuf->fmt.height)
- try_win.height = fbuf->fmt.height - try_win.top;
- try_win.width &= ~1;
- try_win.height &= ~1;
-
- if (try_win.width <= 0 || try_win.height <= 0)
- return -EINVAL;
-
- /* We now have a valid preview window, so go with it */
- new_win->w = try_win;
- new_win->field = V4L2_FIELD_ANY;
- return 0;
-}
-EXPORT_SYMBOL_GPL(omap_vout_try_window);
-
-/* Given a new render window in new_win, adjust the window to the
- * nearest supported configuration. The image cropping window in crop
- * will also be adjusted if necessary. Preference is given to keeping the
- * the window as close to the requested configuration as possible. If
- * successful, new_win, vout->win, and crop are updated.
- * Returns zero if successful, or -EINVAL if the requested preview window is
- * impossible and cannot reasonably be adjusted.
- */
-int omap_vout_new_window(struct v4l2_rect *crop,
- struct v4l2_window *win, struct v4l2_framebuffer *fbuf,
- struct v4l2_window *new_win)
-{
- int err;
-
- err = omap_vout_try_window(fbuf, new_win);
- if (err)
- return err;
-
- /* update our preview window */
- win->w = new_win->w;
- win->field = new_win->field;
- win->chromakey = new_win->chromakey;
-
- /* Adjust the cropping window to allow for resizing limitation */
- if (cpu_is_omap24xx()) {
- /* For 24xx limit is 8x to 1/2x scaling. */
- if ((crop->height/win->w.height) >= 2)
- crop->height = win->w.height * 2;
-
- if ((crop->width/win->w.width) >= 2)
- crop->width = win->w.width * 2;
-
- if (crop->width > 768) {
- /* The OMAP2420 vertical resizing line buffer is 768
- * pixels wide. If the cropped image is wider than
- * 768 pixels then it cannot be vertically resized.
- */
- if (crop->height != win->w.height)
- crop->width = 768;
- }
- } else if (cpu_is_omap34xx()) {
- /* For 34xx limit is 8x to 1/4x scaling. */
- if ((crop->height/win->w.height) >= 4)
- crop->height = win->w.height * 4;
-
- if ((crop->width/win->w.width) >= 4)
- crop->width = win->w.width * 4;
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(omap_vout_new_window);
-
-/* Given a new cropping rectangle in new_crop, adjust the cropping rectangle to
- * the nearest supported configuration. The image render window in win will
- * also be adjusted if necessary. The preview window is adjusted such that the
- * horizontal and vertical rescaling ratios stay constant. If the render
- * window would fall outside the display boundaries, the cropping rectangle
- * will also be adjusted to maintain the rescaling ratios. If successful, crop
- * and win are updated.
- * Returns zero if successful, or -EINVAL if the requested cropping rectangle is
- * impossible and cannot reasonably be adjusted.
- */
-int omap_vout_new_crop(struct v4l2_pix_format *pix,
- struct v4l2_rect *crop, struct v4l2_window *win,
- struct v4l2_framebuffer *fbuf, const struct v4l2_rect *new_crop)
-{
- struct v4l2_rect try_crop;
- unsigned long vresize, hresize;
-
- /* make a working copy of the new_crop rectangle */
- try_crop = *new_crop;
-
- /* adjust the cropping rectangle so it fits in the image */
- if (try_crop.left < 0) {
- try_crop.width += try_crop.left;
- try_crop.left = 0;
- }
- if (try_crop.top < 0) {
- try_crop.height += try_crop.top;
- try_crop.top = 0;
- }
- try_crop.width = (try_crop.width < pix->width) ?
- try_crop.width : pix->width;
- try_crop.height = (try_crop.height < pix->height) ?
- try_crop.height : pix->height;
- if (try_crop.left + try_crop.width > pix->width)
- try_crop.width = pix->width - try_crop.left;
- if (try_crop.top + try_crop.height > pix->height)
- try_crop.height = pix->height - try_crop.top;
-
- try_crop.width &= ~1;
- try_crop.height &= ~1;
-
- if (try_crop.width <= 0 || try_crop.height <= 0)
- return -EINVAL;
-
- if (cpu_is_omap24xx()) {
- if (try_crop.height != win->w.height) {
- /* If we're resizing vertically, we can't support a
- * crop width wider than 768 pixels.
- */
- if (try_crop.width > 768)
- try_crop.width = 768;
- }
- }
- /* vertical resizing */
- vresize = (1024 * try_crop.height) / win->w.height;
- if (cpu_is_omap24xx() && (vresize > 2048))
- vresize = 2048;
- else if (cpu_is_omap34xx() && (vresize > 4096))
- vresize = 4096;
-
- win->w.height = ((1024 * try_crop.height) / vresize) & ~1;
- if (win->w.height == 0)
- win->w.height = 2;
- if (win->w.height + win->w.top > fbuf->fmt.height) {
- /* We made the preview window extend below the bottom of the
- * display, so clip it to the display boundary and resize the
- * cropping height to maintain the vertical resizing ratio.
- */
- win->w.height = (fbuf->fmt.height - win->w.top) & ~1;
- if (try_crop.height == 0)
- try_crop.height = 2;
- }
- /* horizontal resizing */
- hresize = (1024 * try_crop.width) / win->w.width;
- if (cpu_is_omap24xx() && (hresize > 2048))
- hresize = 2048;
- else if (cpu_is_omap34xx() && (hresize > 4096))
- hresize = 4096;
-
- win->w.width = ((1024 * try_crop.width) / hresize) & ~1;
- if (win->w.width == 0)
- win->w.width = 2;
- if (win->w.width + win->w.left > fbuf->fmt.width) {
- /* We made the preview window extend past the right side of the
- * display, so clip it to the display boundary and resize the
- * cropping width to maintain the horizontal resizing ratio.
- */
- win->w.width = (fbuf->fmt.width - win->w.left) & ~1;
- if (try_crop.width == 0)
- try_crop.width = 2;
- }
- if (cpu_is_omap24xx()) {
- if ((try_crop.height/win->w.height) >= 2)
- try_crop.height = win->w.height * 2;
-
- if ((try_crop.width/win->w.width) >= 2)
- try_crop.width = win->w.width * 2;
-
- if (try_crop.width > 768) {
- /* The OMAP2420 vertical resizing line buffer is
- * 768 pixels wide. If the cropped image is wider
- * than 768 pixels then it cannot be vertically resized.
- */
- if (try_crop.height != win->w.height)
- try_crop.width = 768;
- }
- } else if (cpu_is_omap34xx()) {
- if ((try_crop.height/win->w.height) >= 4)
- try_crop.height = win->w.height * 4;
-
- if ((try_crop.width/win->w.width) >= 4)
- try_crop.width = win->w.width * 4;
- }
- /* update our cropping rectangle and we're done */
- *crop = try_crop;
- return 0;
-}
-EXPORT_SYMBOL_GPL(omap_vout_new_crop);
-
-/* Given a new format in pix and fbuf, crop and win
- * structures are initialized to default values. crop
- * is initialized to the largest window size that will fit on the display. The
- * crop window is centered in the image. win is initialized to
- * the same size as crop and is centered on the display.
- * All sizes and offsets are constrained to be even numbers.
- */
-void omap_vout_new_format(struct v4l2_pix_format *pix,
- struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop,
- struct v4l2_window *win)
-{
- /* crop defines the preview source window in the image capture
- * buffer
- */
- omap_vout_default_crop(pix, fbuf, crop);
-
- /* win defines the preview target window on the display */
- win->w.width = crop->width;
- win->w.height = crop->height;
- win->w.left = ((fbuf->fmt.width - win->w.width) >> 1) & ~1;
- win->w.top = ((fbuf->fmt.height - win->w.height) >> 1) & ~1;
-}
-EXPORT_SYMBOL_GPL(omap_vout_new_format);
-
-/*
- * Allocate buffers
- */
-unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr)
-{
- u32 order, size;
- unsigned long virt_addr, addr;
-
- size = PAGE_ALIGN(buf_size);
- order = get_order(size);
- virt_addr = __get_free_pages(GFP_KERNEL, order);
- addr = virt_addr;
-
- if (virt_addr) {
- while (size > 0) {
- SetPageReserved(virt_to_page(addr));
- addr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- }
- *phys_addr = (u32) virt_to_phys((void *) virt_addr);
- return virt_addr;
-}
-
-/*
- * Free buffers
- */
-void omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size)
-{
- u32 order, size;
- unsigned long addr = virtaddr;
-
- size = PAGE_ALIGN(buf_size);
- order = get_order(size);
-
- while (size > 0) {
- ClearPageReserved(virt_to_page(addr));
- addr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- free_pages((unsigned long) virtaddr, order);
-}
diff --git a/drivers/media/video/omap/omap_voutlib.h b/drivers/media/video/omap/omap_voutlib.h
deleted file mode 100644
index e51750a597e..00000000000
--- a/drivers/media/video/omap/omap_voutlib.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * omap_voutlib.h
- *
- * Copyright (C) 2010 Texas Instruments.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- *
- */
-
-#ifndef OMAP_VOUTLIB_H
-#define OMAP_VOUTLIB_H
-
-void omap_vout_default_crop(struct v4l2_pix_format *pix,
- struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop);
-
-int omap_vout_new_crop(struct v4l2_pix_format *pix,
- struct v4l2_rect *crop, struct v4l2_window *win,
- struct v4l2_framebuffer *fbuf,
- const struct v4l2_rect *new_crop);
-
-int omap_vout_try_window(struct v4l2_framebuffer *fbuf,
- struct v4l2_window *new_win);
-
-int omap_vout_new_window(struct v4l2_rect *crop,
- struct v4l2_window *win, struct v4l2_framebuffer *fbuf,
- struct v4l2_window *new_win);
-
-void omap_vout_new_format(struct v4l2_pix_format *pix,
- struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop,
- struct v4l2_window *win);
-unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr);
-void omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size);
-#endif /* #ifndef OMAP_VOUTLIB_H */
-
diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c
deleted file mode 100644
index c7e41145041..00000000000
--- a/drivers/media/video/omap1_camera.c
+++ /dev/null
@@ -1,1723 +0,0 @@
-/*
- * V4L2 SoC Camera driver for OMAP1 Camera Interface
- *
- * Copyright (C) 2010, Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
- *
- * Based on V4L2 Driver for i.MXL/i.MXL camera (CSI) host
- * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
- * Copyright (C) 2009, Darius Augulis <augulis.darius@gmail.com>
- *
- * Based on PXA SoC camera driver
- * Copyright (C) 2006, Sascha Hauer, Pengutronix
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * Hardware specific bits initialy based on former work by Matt Callow
- * drivers/media/video/omap/omap1510cam.c
- * Copyright (C) 2006 Matt Callow
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#include <linux/clk.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <media/omap1_camera.h>
-#include <media/soc_camera.h>
-#include <media/soc_mediabus.h>
-#include <media/videobuf-dma-contig.h>
-#include <media/videobuf-dma-sg.h>
-
-#include <plat/dma.h>
-
-
-#define DRIVER_NAME "omap1-camera"
-#define DRIVER_VERSION "0.0.2"
-
-
-/*
- * ---------------------------------------------------------------------------
- * OMAP1 Camera Interface registers
- * ---------------------------------------------------------------------------
- */
-
-#define REG_CTRLCLOCK 0x00
-#define REG_IT_STATUS 0x04
-#define REG_MODE 0x08
-#define REG_STATUS 0x0C
-#define REG_CAMDATA 0x10
-#define REG_GPIO 0x14
-#define REG_PEAK_COUNTER 0x18
-
-/* CTRLCLOCK bit shifts */
-#define LCLK_EN BIT(7)
-#define DPLL_EN BIT(6)
-#define MCLK_EN BIT(5)
-#define CAMEXCLK_EN BIT(4)
-#define POLCLK BIT(3)
-#define FOSCMOD_SHIFT 0
-#define FOSCMOD_MASK (0x7 << FOSCMOD_SHIFT)
-#define FOSCMOD_12MHz 0x0
-#define FOSCMOD_6MHz 0x2
-#define FOSCMOD_9_6MHz 0x4
-#define FOSCMOD_24MHz 0x5
-#define FOSCMOD_8MHz 0x6
-
-/* IT_STATUS bit shifts */
-#define DATA_TRANSFER BIT(5)
-#define FIFO_FULL BIT(4)
-#define H_DOWN BIT(3)
-#define H_UP BIT(2)
-#define V_DOWN BIT(1)
-#define V_UP BIT(0)
-
-/* MODE bit shifts */
-#define RAZ_FIFO BIT(18)
-#define EN_FIFO_FULL BIT(17)
-#define EN_NIRQ BIT(16)
-#define THRESHOLD_SHIFT 9
-#define THRESHOLD_MASK (0x7f << THRESHOLD_SHIFT)
-#define DMA BIT(8)
-#define EN_H_DOWN BIT(7)
-#define EN_H_UP BIT(6)
-#define EN_V_DOWN BIT(5)
-#define EN_V_UP BIT(4)
-#define ORDERCAMD BIT(3)
-
-#define IRQ_MASK (EN_V_UP | EN_V_DOWN | EN_H_UP | EN_H_DOWN | \
- EN_NIRQ | EN_FIFO_FULL)
-
-/* STATUS bit shifts */
-#define HSTATUS BIT(1)
-#define VSTATUS BIT(0)
-
-/* GPIO bit shifts */
-#define CAM_RST BIT(0)
-
-/* end of OMAP1 Camera Interface registers */
-
-
-#define SOCAM_BUS_FLAGS (V4L2_MBUS_MASTER | \
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
- V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
- V4L2_MBUS_DATA_ACTIVE_HIGH)
-
-
-#define FIFO_SIZE ((THRESHOLD_MASK >> THRESHOLD_SHIFT) + 1)
-#define FIFO_SHIFT __fls(FIFO_SIZE)
-
-#define DMA_BURST_SHIFT (1 + OMAP_DMA_DATA_BURST_4)
-#define DMA_BURST_SIZE (1 << DMA_BURST_SHIFT)
-
-#define DMA_ELEMENT_SHIFT OMAP_DMA_DATA_TYPE_S32
-#define DMA_ELEMENT_SIZE (1 << DMA_ELEMENT_SHIFT)
-
-#define DMA_FRAME_SHIFT_CONTIG (FIFO_SHIFT - 1)
-#define DMA_FRAME_SHIFT_SG DMA_BURST_SHIFT
-
-#define DMA_FRAME_SHIFT(x) ((x) == OMAP1_CAM_DMA_CONTIG ? \
- DMA_FRAME_SHIFT_CONTIG : \
- DMA_FRAME_SHIFT_SG)
-#define DMA_FRAME_SIZE(x) (1 << DMA_FRAME_SHIFT(x))
-#define DMA_SYNC OMAP_DMA_SYNC_FRAME
-#define THRESHOLD_LEVEL DMA_FRAME_SIZE
-
-
-#define MAX_VIDEO_MEM 4 /* arbitrary video memory limit in MB */
-
-
-/*
- * Structures
- */
-
-/* buffer for one video frame */
-struct omap1_cam_buf {
- struct videobuf_buffer vb;
- enum v4l2_mbus_pixelcode code;
- int inwork;
- struct scatterlist *sgbuf;
- int sgcount;
- int bytes_left;
- enum videobuf_state result;
-};
-
-struct omap1_cam_dev {
- struct soc_camera_host soc_host;
- struct soc_camera_device *icd;
- struct clk *clk;
-
- unsigned int irq;
- void __iomem *base;
-
- int dma_ch;
-
- struct omap1_cam_platform_data *pdata;
- struct resource *res;
- unsigned long pflags;
- unsigned long camexclk;
-
- struct list_head capture;
-
- /* lock used to protect videobuf */
- spinlock_t lock;
-
- /* Pointers to DMA buffers */
- struct omap1_cam_buf *active;
- struct omap1_cam_buf *ready;
-
- enum omap1_cam_vb_mode vb_mode;
- int (*mmap_mapper)(struct videobuf_queue *q,
- struct videobuf_buffer *buf,
- struct vm_area_struct *vma);
-
- u32 reg_cache[0];
-};
-
-
-static void cam_write(struct omap1_cam_dev *pcdev, u16 reg, u32 val)
-{
- pcdev->reg_cache[reg / sizeof(u32)] = val;
- __raw_writel(val, pcdev->base + reg);
-}
-
-static u32 cam_read(struct omap1_cam_dev *pcdev, u16 reg, bool from_cache)
-{
- return !from_cache ? __raw_readl(pcdev->base + reg) :
- pcdev->reg_cache[reg / sizeof(u32)];
-}
-
-#define CAM_READ(pcdev, reg) \
- cam_read(pcdev, REG_##reg, false)
-#define CAM_WRITE(pcdev, reg, val) \
- cam_write(pcdev, REG_##reg, val)
-#define CAM_READ_CACHE(pcdev, reg) \
- cam_read(pcdev, REG_##reg, true)
-
-/*
- * Videobuf operations
- */
-static int omap1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
- unsigned int *size)
-{
- struct soc_camera_device *icd = vq->priv_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct omap1_cam_dev *pcdev = ici->priv;
-
- *size = icd->sizeimage;
-
- if (!*count || *count < OMAP1_CAMERA_MIN_BUF_COUNT(pcdev->vb_mode))
- *count = OMAP1_CAMERA_MIN_BUF_COUNT(pcdev->vb_mode);
-
- if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
- *count = (MAX_VIDEO_MEM * 1024 * 1024) / *size;
-
- dev_dbg(icd->parent,
- "%s: count=%d, size=%d\n", __func__, *count, *size);
-
- return 0;
-}
-
-static void free_buffer(struct videobuf_queue *vq, struct omap1_cam_buf *buf,
- enum omap1_cam_vb_mode vb_mode)
-{
- struct videobuf_buffer *vb = &buf->vb;
-
- BUG_ON(in_interrupt());
-
- videobuf_waiton(vq, vb, 0, 0);
-
- if (vb_mode == OMAP1_CAM_DMA_CONTIG) {
- videobuf_dma_contig_free(vq, vb);
- } else {
- struct soc_camera_device *icd = vq->priv_data;
- struct device *dev = icd->parent;
- struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
-
- videobuf_dma_unmap(dev, dma);
- videobuf_dma_free(dma);
- }
-
- vb->state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int omap1_videobuf_prepare(struct videobuf_queue *vq,
- struct videobuf_buffer *vb, enum v4l2_field field)
-{
- struct soc_camera_device *icd = vq->priv_data;
- struct omap1_cam_buf *buf = container_of(vb, struct omap1_cam_buf, vb);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct omap1_cam_dev *pcdev = ici->priv;
- int ret;
-
- WARN_ON(!list_empty(&vb->queue));
-
- BUG_ON(NULL == icd->current_fmt);
-
- buf->inwork = 1;
-
- if (buf->code != icd->current_fmt->code || vb->field != field ||
- vb->width != icd->user_width ||
- vb->height != icd->user_height) {
- buf->code = icd->current_fmt->code;
- vb->width = icd->user_width;
- vb->height = icd->user_height;
- vb->field = field;
- vb->state = VIDEOBUF_NEEDS_INIT;
- }
-
- vb->size = icd->sizeimage;
-
- if (vb->baddr && vb->bsize < vb->size) {
- ret = -EINVAL;
- goto out;
- }
-
- if (vb->state == VIDEOBUF_NEEDS_INIT) {
- ret = videobuf_iolock(vq, vb, NULL);
- if (ret)
- goto fail;
-
- vb->state = VIDEOBUF_PREPARED;
- }
- buf->inwork = 0;
-
- return 0;
-fail:
- free_buffer(vq, buf, pcdev->vb_mode);
-out:
- buf->inwork = 0;
- return ret;
-}
-
-static void set_dma_dest_params(int dma_ch, struct omap1_cam_buf *buf,
- enum omap1_cam_vb_mode vb_mode)
-{
- dma_addr_t dma_addr;
- unsigned int block_size;
-
- if (vb_mode == OMAP1_CAM_DMA_CONTIG) {
- dma_addr = videobuf_to_dma_contig(&buf->vb);
- block_size = buf->vb.size;
- } else {
- if (WARN_ON(!buf->sgbuf)) {
- buf->result = VIDEOBUF_ERROR;
- return;
- }
- dma_addr = sg_dma_address(buf->sgbuf);
- if (WARN_ON(!dma_addr)) {
- buf->sgbuf = NULL;
- buf->result = VIDEOBUF_ERROR;
- return;
- }
- block_size = sg_dma_len(buf->sgbuf);
- if (WARN_ON(!block_size)) {
- buf->sgbuf = NULL;
- buf->result = VIDEOBUF_ERROR;
- return;
- }
- if (unlikely(buf->bytes_left < block_size))
- block_size = buf->bytes_left;
- if (WARN_ON(dma_addr & (DMA_FRAME_SIZE(vb_mode) *
- DMA_ELEMENT_SIZE - 1))) {
- dma_addr = ALIGN(dma_addr, DMA_FRAME_SIZE(vb_mode) *
- DMA_ELEMENT_SIZE);
- block_size &= ~(DMA_FRAME_SIZE(vb_mode) *
- DMA_ELEMENT_SIZE - 1);
- }
- buf->bytes_left -= block_size;
- buf->sgcount++;
- }
-
- omap_set_dma_dest_params(dma_ch,
- OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0);
- omap_set_dma_transfer_params(dma_ch,
- OMAP_DMA_DATA_TYPE_S32, DMA_FRAME_SIZE(vb_mode),
- block_size >> (DMA_FRAME_SHIFT(vb_mode) + DMA_ELEMENT_SHIFT),
- DMA_SYNC, 0, 0);
-}
-
-static struct omap1_cam_buf *prepare_next_vb(struct omap1_cam_dev *pcdev)
-{
- struct omap1_cam_buf *buf;
-
- /*
- * If there is already a buffer pointed out by the pcdev->ready,
- * (re)use it, otherwise try to fetch and configure a new one.
- */
- buf = pcdev->ready;
- if (!buf) {
- if (list_empty(&pcdev->capture))
- return buf;
- buf = list_entry(pcdev->capture.next,
- struct omap1_cam_buf, vb.queue);
- buf->vb.state = VIDEOBUF_ACTIVE;
- pcdev->ready = buf;
- list_del_init(&buf->vb.queue);
- }
-
- if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
- /*
- * In CONTIG mode, we can safely enter next buffer parameters
- * into the DMA programming register set after the DMA
- * has already been activated on the previous buffer
- */
- set_dma_dest_params(pcdev->dma_ch, buf, pcdev->vb_mode);
- } else {
- /*
- * In SG mode, the above is not safe since there are probably
- * a bunch of sgbufs from previous sglist still pending.
- * Instead, mark the sglist fresh for the upcoming
- * try_next_sgbuf().
- */
- buf->sgbuf = NULL;
- }
-
- return buf;
-}
-
-static struct scatterlist *try_next_sgbuf(int dma_ch, struct omap1_cam_buf *buf)
-{
- struct scatterlist *sgbuf;
-
- if (likely(buf->sgbuf)) {
- /* current sglist is active */
- if (unlikely(!buf->bytes_left)) {
- /* indicate sglist complete */
- sgbuf = NULL;
- } else {
- /* process next sgbuf */
- sgbuf = sg_next(buf->sgbuf);
- if (WARN_ON(!sgbuf)) {
- buf->result = VIDEOBUF_ERROR;
- } else if (WARN_ON(!sg_dma_len(sgbuf))) {
- sgbuf = NULL;
- buf->result = VIDEOBUF_ERROR;
- }
- }
- buf->sgbuf = sgbuf;
- } else {
- /* sglist is fresh, initialize it before using */
- struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
-
- sgbuf = dma->sglist;
- if (!(WARN_ON(!sgbuf))) {
- buf->sgbuf = sgbuf;
- buf->sgcount = 0;
- buf->bytes_left = buf->vb.size;
- buf->result = VIDEOBUF_DONE;
- }
- }
- if (sgbuf)
- /*
- * Put our next sgbuf parameters (address, size)
- * into the DMA programming register set.
- */
- set_dma_dest_params(dma_ch, buf, OMAP1_CAM_DMA_SG);
-
- return sgbuf;
-}
-
-static void start_capture(struct omap1_cam_dev *pcdev)
-{
- struct omap1_cam_buf *buf = pcdev->active;
- u32 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
- u32 mode = CAM_READ_CACHE(pcdev, MODE) & ~EN_V_DOWN;
-
- if (WARN_ON(!buf))
- return;
-
- /*
- * Enable start of frame interrupt, which we will use for activating
- * our end of frame watchdog when capture actually starts.
- */
- mode |= EN_V_UP;
-
- if (unlikely(ctrlclock & LCLK_EN))
- /* stop pixel clock before FIFO reset */
- CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
- /* reset FIFO */
- CAM_WRITE(pcdev, MODE, mode | RAZ_FIFO);
-
- omap_start_dma(pcdev->dma_ch);
-
- if (pcdev->vb_mode == OMAP1_CAM_DMA_SG) {
- /*
- * In SG mode, it's a good moment for fetching next sgbuf
- * from the current sglist and, if available, already putting
- * its parameters into the DMA programming register set.
- */
- try_next_sgbuf(pcdev->dma_ch, buf);
- }
-
- /* (re)enable pixel clock */
- CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock | LCLK_EN);
- /* release FIFO reset */
- CAM_WRITE(pcdev, MODE, mode);
-}
-
-static void suspend_capture(struct omap1_cam_dev *pcdev)
-{
- u32 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
-
- CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
- omap_stop_dma(pcdev->dma_ch);
-}
-
-static void disable_capture(struct omap1_cam_dev *pcdev)
-{
- u32 mode = CAM_READ_CACHE(pcdev, MODE);
-
- CAM_WRITE(pcdev, MODE, mode & ~(IRQ_MASK | DMA));
-}
-
-static void omap1_videobuf_queue(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct soc_camera_device *icd = vq->priv_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct omap1_cam_dev *pcdev = ici->priv;
- struct omap1_cam_buf *buf;
- u32 mode;
-
- list_add_tail(&vb->queue, &pcdev->capture);
- vb->state = VIDEOBUF_QUEUED;
-
- if (pcdev->active) {
- /*
- * Capture in progress, so don't touch pcdev->ready even if
- * empty. Since the transfer of the DMA programming register set
- * content to the DMA working register set is done automatically
- * by the DMA hardware, this can pretty well happen while we
- * are keeping the lock here. Leave fetching it from the queue
- * to be done when a next DMA interrupt occures instead.
- */
- return;
- }
-
- WARN_ON(pcdev->ready);
-
- buf = prepare_next_vb(pcdev);
- if (WARN_ON(!buf))
- return;
-
- pcdev->active = buf;
- pcdev->ready = NULL;
-
- dev_dbg(icd->parent,
- "%s: capture not active, setup FIFO, start DMA\n", __func__);
- mode = CAM_READ_CACHE(pcdev, MODE) & ~THRESHOLD_MASK;
- mode |= THRESHOLD_LEVEL(pcdev->vb_mode) << THRESHOLD_SHIFT;
- CAM_WRITE(pcdev, MODE, mode | EN_FIFO_FULL | DMA);
-
- if (pcdev->vb_mode == OMAP1_CAM_DMA_SG) {
- /*
- * In SG mode, the above prepare_next_vb() didn't actually
- * put anything into the DMA programming register set,
- * so we have to do it now, before activating DMA.
- */
- try_next_sgbuf(pcdev->dma_ch, buf);
- }
-
- start_capture(pcdev);
-}
-
-static void omap1_videobuf_release(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct omap1_cam_buf *buf =
- container_of(vb, struct omap1_cam_buf, vb);
- struct soc_camera_device *icd = vq->priv_data;
- struct device *dev = icd->parent;
- struct soc_camera_host *ici = to_soc_camera_host(dev);
- struct omap1_cam_dev *pcdev = ici->priv;
-
- switch (vb->state) {
- case VIDEOBUF_DONE:
- dev_dbg(dev, "%s (done)\n", __func__);
- break;
- case VIDEOBUF_ACTIVE:
- dev_dbg(dev, "%s (active)\n", __func__);
- break;
- case VIDEOBUF_QUEUED:
- dev_dbg(dev, "%s (queued)\n", __func__);
- break;
- case VIDEOBUF_PREPARED:
- dev_dbg(dev, "%s (prepared)\n", __func__);
- break;
- default:
- dev_dbg(dev, "%s (unknown %d)\n", __func__, vb->state);
- break;
- }
-
- free_buffer(vq, buf, pcdev->vb_mode);
-}
-
-static void videobuf_done(struct omap1_cam_dev *pcdev,
- enum videobuf_state result)
-{
- struct omap1_cam_buf *buf = pcdev->active;
- struct videobuf_buffer *vb;
- struct device *dev = pcdev->icd->parent;
-
- if (WARN_ON(!buf)) {
- suspend_capture(pcdev);
- disable_capture(pcdev);
- return;
- }
-
- if (result == VIDEOBUF_ERROR)
- suspend_capture(pcdev);
-
- vb = &buf->vb;
- if (waitqueue_active(&vb->done)) {
- if (!pcdev->ready && result != VIDEOBUF_ERROR) {
- /*
- * No next buffer has been entered into the DMA
- * programming register set on time (could be done only
- * while the previous DMA interurpt was processed, not
- * later), so the last DMA block, be it a whole buffer
- * if in CONTIG or its last sgbuf if in SG mode, is
- * about to be reused by the just autoreinitialized DMA
- * engine, and overwritten with next frame data. Best we
- * can do is stopping the capture as soon as possible,
- * hopefully before the next frame start.
- */
- suspend_capture(pcdev);
- }
- vb->state = result;
- do_gettimeofday(&vb->ts);
- if (result != VIDEOBUF_ERROR)
- vb->field_count++;
- wake_up(&vb->done);
-
- /* shift in next buffer */
- buf = pcdev->ready;
- pcdev->active = buf;
- pcdev->ready = NULL;
-
- if (!buf) {
- /*
- * No next buffer was ready on time (see above), so
- * indicate error condition to force capture restart or
- * stop, depending on next buffer already queued or not.
- */
- result = VIDEOBUF_ERROR;
- prepare_next_vb(pcdev);
-
- buf = pcdev->ready;
- pcdev->active = buf;
- pcdev->ready = NULL;
- }
- } else if (pcdev->ready) {
- /*
- * In both CONTIG and SG mode, the DMA engine has possibly
- * been already autoreinitialized with the preprogrammed
- * pcdev->ready buffer. We can either accept this fact
- * and just swap the buffers, or provoke an error condition
- * and restart capture. The former seems less intrusive.
- */
- dev_dbg(dev, "%s: nobody waiting on videobuf, swap with next\n",
- __func__);
- pcdev->active = pcdev->ready;
-
- if (pcdev->vb_mode == OMAP1_CAM_DMA_SG) {
- /*
- * In SG mode, we have to make sure that the buffer we
- * are putting back into the pcdev->ready is marked
- * fresh.
- */
- buf->sgbuf = NULL;
- }
- pcdev->ready = buf;
-
- buf = pcdev->active;
- } else {
- /*
- * No next buffer has been entered into
- * the DMA programming register set on time.
- */
- if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
- /*
- * In CONTIG mode, the DMA engine has already been
- * reinitialized with the current buffer. Best we can do
- * is not touching it.
- */
- dev_dbg(dev,
- "%s: nobody waiting on videobuf, reuse it\n",
- __func__);
- } else {
- /*
- * In SG mode, the DMA engine has just been
- * autoreinitialized with the last sgbuf from the
- * current list. Restart capture in order to transfer
- * next frame start into the first sgbuf, not the last
- * one.
- */
- if (result != VIDEOBUF_ERROR) {
- suspend_capture(pcdev);
- result = VIDEOBUF_ERROR;
- }
- }
- }
-
- if (!buf) {
- dev_dbg(dev, "%s: no more videobufs, stop capture\n", __func__);
- disable_capture(pcdev);
- return;
- }
-
- if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
- /*
- * In CONTIG mode, the current buffer parameters had already
- * been entered into the DMA programming register set while the
- * buffer was fetched with prepare_next_vb(), they may have also
- * been transferred into the runtime set and already active if
- * the DMA still running.
- */
- } else {
- /* In SG mode, extra steps are required */
- if (result == VIDEOBUF_ERROR)
- /* make sure we (re)use sglist from start on error */
- buf->sgbuf = NULL;
-
- /*
- * In any case, enter the next sgbuf parameters into the DMA
- * programming register set. They will be used either during
- * nearest DMA autoreinitialization or, in case of an error,
- * on DMA startup below.
- */
- try_next_sgbuf(pcdev->dma_ch, buf);
- }
-
- if (result == VIDEOBUF_ERROR) {
- dev_dbg(dev, "%s: videobuf error; reset FIFO, restart DMA\n",
- __func__);
- start_capture(pcdev);
- /*
- * In SG mode, the above also resulted in the next sgbuf
- * parameters being entered into the DMA programming register
- * set, making them ready for next DMA autoreinitialization.
- */
- }
-
- /*
- * Finally, try fetching next buffer.
- * In CONTIG mode, it will also enter it into the DMA programming
- * register set, making it ready for next DMA autoreinitialization.
- */
- prepare_next_vb(pcdev);
-}
-
-static void dma_isr(int channel, unsigned short status, void *data)
-{
- struct omap1_cam_dev *pcdev = data;
- struct omap1_cam_buf *buf = pcdev->active;
- unsigned long flags;
-
- spin_lock_irqsave(&pcdev->lock, flags);
-
- if (WARN_ON(!buf)) {
- suspend_capture(pcdev);
- disable_capture(pcdev);
- goto out;
- }
-
- if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
- /*
- * In CONTIG mode, assume we have just managed to collect the
- * whole frame, hopefully before our end of frame watchdog is
- * triggered. Then, all we have to do is disabling the watchdog
- * for this frame, and calling videobuf_done() with success
- * indicated.
- */
- CAM_WRITE(pcdev, MODE,
- CAM_READ_CACHE(pcdev, MODE) & ~EN_V_DOWN);
- videobuf_done(pcdev, VIDEOBUF_DONE);
- } else {
- /*
- * In SG mode, we have to process every sgbuf from the current
- * sglist, one after another.
- */
- if (buf->sgbuf) {
- /*
- * Current sglist not completed yet, try fetching next
- * sgbuf, hopefully putting it into the DMA programming
- * register set, making it ready for next DMA
- * autoreinitialization.
- */
- try_next_sgbuf(pcdev->dma_ch, buf);
- if (buf->sgbuf)
- goto out;
-
- /*
- * No more sgbufs left in the current sglist. This
- * doesn't mean that the whole videobuffer is already
- * complete, but only that the last sgbuf from the
- * current sglist is about to be filled. It will be
- * ready on next DMA interrupt, signalled with the
- * buf->sgbuf set back to NULL.
- */
- if (buf->result != VIDEOBUF_ERROR) {
- /*
- * Video frame collected without errors so far,
- * we can prepare for collecting a next one
- * as soon as DMA gets autoreinitialized
- * after the current (last) sgbuf is completed.
- */
- buf = prepare_next_vb(pcdev);
- if (!buf)
- goto out;
-
- try_next_sgbuf(pcdev->dma_ch, buf);
- goto out;
- }
- }
- /* end of videobuf */
- videobuf_done(pcdev, buf->result);
- }
-
-out:
- spin_unlock_irqrestore(&pcdev->lock, flags);
-}
-
-static irqreturn_t cam_isr(int irq, void *data)
-{
- struct omap1_cam_dev *pcdev = data;
- struct device *dev = pcdev->icd->parent;
- struct omap1_cam_buf *buf = pcdev->active;
- u32 it_status;
- unsigned long flags;
-
- it_status = CAM_READ(pcdev, IT_STATUS);
- if (!it_status)
- return IRQ_NONE;
-
- spin_lock_irqsave(&pcdev->lock, flags);
-
- if (WARN_ON(!buf)) {
- dev_warn(dev, "%s: unhandled camera interrupt, status == %#x\n",
- __func__, it_status);
- suspend_capture(pcdev);
- disable_capture(pcdev);
- goto out;
- }
-
- if (unlikely(it_status & FIFO_FULL)) {
- dev_warn(dev, "%s: FIFO overflow\n", __func__);
-
- } else if (it_status & V_DOWN) {
- /* end of video frame watchdog */
- if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
- /*
- * In CONTIG mode, the watchdog is disabled with
- * successful DMA end of block interrupt, and reenabled
- * on next frame start. If we get here, there is nothing
- * to check, we must be out of sync.
- */
- } else {
- if (buf->sgcount == 2) {
- /*
- * If exactly 2 sgbufs from the next sglist have
- * been programmed into the DMA engine (the
- * first one already transferred into the DMA
- * runtime register set, the second one still
- * in the programming set), then we are in sync.
- */
- goto out;
- }
- }
- dev_notice(dev, "%s: unexpected end of video frame\n",
- __func__);
-
- } else if (it_status & V_UP) {
- u32 mode;
-
- if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
- /*
- * In CONTIG mode, we need this interrupt every frame
- * in oredr to reenable our end of frame watchdog.
- */
- mode = CAM_READ_CACHE(pcdev, MODE);
- } else {
- /*
- * In SG mode, the below enabled end of frame watchdog
- * is kept on permanently, so we can turn this one shot
- * setup off.
- */
- mode = CAM_READ_CACHE(pcdev, MODE) & ~EN_V_UP;
- }
-
- if (!(mode & EN_V_DOWN)) {
- /* (re)enable end of frame watchdog interrupt */
- mode |= EN_V_DOWN;
- }
- CAM_WRITE(pcdev, MODE, mode);
- goto out;
-
- } else {
- dev_warn(dev, "%s: unhandled camera interrupt, status == %#x\n",
- __func__, it_status);
- goto out;
- }
-
- videobuf_done(pcdev, VIDEOBUF_ERROR);
-out:
- spin_unlock_irqrestore(&pcdev->lock, flags);
- return IRQ_HANDLED;
-}
-
-static struct videobuf_queue_ops omap1_videobuf_ops = {
- .buf_setup = omap1_videobuf_setup,
- .buf_prepare = omap1_videobuf_prepare,
- .buf_queue = omap1_videobuf_queue,
- .buf_release = omap1_videobuf_release,
-};
-
-
-/*
- * SOC Camera host operations
- */
-
-static void sensor_reset(struct omap1_cam_dev *pcdev, bool reset)
-{
- /* apply/release camera sensor reset if requested by platform data */
- if (pcdev->pflags & OMAP1_CAMERA_RST_HIGH)
- CAM_WRITE(pcdev, GPIO, reset);
- else if (pcdev->pflags & OMAP1_CAMERA_RST_LOW)
- CAM_WRITE(pcdev, GPIO, !reset);
-}
-
-/*
- * The following two functions absolutely depend on the fact, that
- * there can be only one camera on OMAP1 camera sensor interface
- */
-static int omap1_cam_add_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct omap1_cam_dev *pcdev = ici->priv;
- u32 ctrlclock;
-
- if (pcdev->icd)
- return -EBUSY;
-
- clk_enable(pcdev->clk);
-
- /* setup sensor clock */
- ctrlclock = CAM_READ(pcdev, CTRLCLOCK);
- ctrlclock &= ~(CAMEXCLK_EN | MCLK_EN | DPLL_EN);
- CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
-
- ctrlclock &= ~FOSCMOD_MASK;
- switch (pcdev->camexclk) {
- case 6000000:
- ctrlclock |= CAMEXCLK_EN | FOSCMOD_6MHz;
- break;
- case 8000000:
- ctrlclock |= CAMEXCLK_EN | FOSCMOD_8MHz | DPLL_EN;
- break;
- case 9600000:
- ctrlclock |= CAMEXCLK_EN | FOSCMOD_9_6MHz | DPLL_EN;
- break;
- case 12000000:
- ctrlclock |= CAMEXCLK_EN | FOSCMOD_12MHz;
- break;
- case 24000000:
- ctrlclock |= CAMEXCLK_EN | FOSCMOD_24MHz | DPLL_EN;
- default:
- break;
- }
- CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~DPLL_EN);
-
- /* enable internal clock */
- ctrlclock |= MCLK_EN;
- CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
-
- sensor_reset(pcdev, false);
-
- pcdev->icd = icd;
-
- dev_dbg(icd->parent, "OMAP1 Camera driver attached to camera %d\n",
- icd->devnum);
- return 0;
-}
-
-static void omap1_cam_remove_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct omap1_cam_dev *pcdev = ici->priv;
- u32 ctrlclock;
-
- BUG_ON(icd != pcdev->icd);
-
- suspend_capture(pcdev);
- disable_capture(pcdev);
-
- sensor_reset(pcdev, true);
-
- /* disable and release system clocks */
- ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
- ctrlclock &= ~(MCLK_EN | DPLL_EN | CAMEXCLK_EN);
- CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
-
- ctrlclock = (ctrlclock & ~FOSCMOD_MASK) | FOSCMOD_12MHz;
- CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
- CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock | MCLK_EN);
-
- CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~MCLK_EN);
-
- clk_disable(pcdev->clk);
-
- pcdev->icd = NULL;
-
- dev_dbg(icd->parent,
- "OMAP1 Camera driver detached from camera %d\n", icd->devnum);
-}
-
-/* Duplicate standard formats based on host capability of byte swapping */
-static const struct soc_mbus_lookup omap1_cam_formats[] = {
-{
- .code = V4L2_MBUS_FMT_UYVY8_2X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_YUYV,
- .name = "YUYV",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_BE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_VYUY8_2X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_YVYU,
- .name = "YVYU",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_BE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_YUYV8_2X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_UYVY,
- .name = "UYVY",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_BE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_YVYU8_2X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_VYUY,
- .name = "VYUY",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_BE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_RGB555,
- .name = "RGB555",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_BE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_RGB555X,
- .name = "RGB555X",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_BE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_RGB565,
- .name = "RGB565",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_BE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_RGB565X,
- .name = "RGB565X",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_BE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-},
-};
-
-static int omap1_cam_get_formats(struct soc_camera_device *icd,
- unsigned int idx, struct soc_camera_format_xlate *xlate)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct device *dev = icd->parent;
- int formats = 0, ret;
- enum v4l2_mbus_pixelcode code;
- const struct soc_mbus_pixelfmt *fmt;
-
- ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
- if (ret < 0)
- /* No more formats */
- return 0;
-
- fmt = soc_mbus_get_fmtdesc(code);
- if (!fmt) {
- dev_warn(dev, "%s: unsupported format code #%d: %d\n", __func__,
- idx, code);
- return 0;
- }
-
- /* Check support for the requested bits-per-sample */
- if (fmt->bits_per_sample != 8)
- return 0;
-
- switch (code) {
- case V4L2_MBUS_FMT_YUYV8_2X8:
- case V4L2_MBUS_FMT_YVYU8_2X8:
- case V4L2_MBUS_FMT_UYVY8_2X8:
- case V4L2_MBUS_FMT_VYUY8_2X8:
- case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE:
- case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
- case V4L2_MBUS_FMT_RGB565_2X8_BE:
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- formats++;
- if (xlate) {
- xlate->host_fmt = soc_mbus_find_fmtdesc(code,
- omap1_cam_formats,
- ARRAY_SIZE(omap1_cam_formats));
- xlate->code = code;
- xlate++;
- dev_dbg(dev,
- "%s: providing format %s as byte swapped code #%d\n",
- __func__, xlate->host_fmt->name, code);
- }
- default:
- if (xlate)
- dev_dbg(dev,
- "%s: providing format %s in pass-through mode\n",
- __func__, fmt->name);
- }
- formats++;
- if (xlate) {
- xlate->host_fmt = fmt;
- xlate->code = code;
- xlate++;
- }
-
- return formats;
-}
-
-static bool is_dma_aligned(s32 bytes_per_line, unsigned int height,
- enum omap1_cam_vb_mode vb_mode)
-{
- int size = bytes_per_line * height;
-
- return IS_ALIGNED(bytes_per_line, DMA_ELEMENT_SIZE) &&
- IS_ALIGNED(size, DMA_FRAME_SIZE(vb_mode) * DMA_ELEMENT_SIZE);
-}
-
-static int dma_align(int *width, int *height,
- const struct soc_mbus_pixelfmt *fmt,
- enum omap1_cam_vb_mode vb_mode, bool enlarge)
-{
- s32 bytes_per_line = soc_mbus_bytes_per_line(*width, fmt);
-
- if (bytes_per_line < 0)
- return bytes_per_line;
-
- if (!is_dma_aligned(bytes_per_line, *height, vb_mode)) {
- unsigned int pxalign = __fls(bytes_per_line / *width);
- unsigned int salign = DMA_FRAME_SHIFT(vb_mode) +
- DMA_ELEMENT_SHIFT - pxalign;
- unsigned int incr = enlarge << salign;
-
- v4l_bound_align_image(width, 1, *width + incr, 0,
- height, 1, *height + incr, 0, salign);
- return 0;
- }
- return 1;
-}
-
-#define subdev_call_with_sense(pcdev, dev, icd, sd, function, args...) \
-({ \
- struct soc_camera_sense sense = { \
- .master_clock = pcdev->camexclk, \
- .pixel_clock_max = 0, \
- }; \
- int __ret; \
- \
- if (pcdev->pdata) \
- sense.pixel_clock_max = pcdev->pdata->lclk_khz_max * 1000; \
- icd->sense = &sense; \
- __ret = v4l2_subdev_call(sd, video, function, ##args); \
- icd->sense = NULL; \
- \
- if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { \
- if (sense.pixel_clock > sense.pixel_clock_max) { \
- dev_err(dev, \
- "%s: pixel clock %lu set by the camera too high!\n", \
- __func__, sense.pixel_clock); \
- __ret = -EINVAL; \
- } \
- } \
- __ret; \
-})
-
-static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev,
- struct soc_camera_device *icd, struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf,
- const struct soc_camera_format_xlate *xlate)
-{
- s32 bytes_per_line;
- int ret = subdev_call_with_sense(pcdev, dev, icd, sd, s_mbus_fmt, mf);
-
- if (ret < 0) {
- dev_err(dev, "%s: s_mbus_fmt failed\n", __func__);
- return ret;
- }
-
- if (mf->code != xlate->code) {
- dev_err(dev, "%s: unexpected pixel code change\n", __func__);
- return -EINVAL;
- }
-
- bytes_per_line = soc_mbus_bytes_per_line(mf->width, xlate->host_fmt);
- if (bytes_per_line < 0) {
- dev_err(dev, "%s: soc_mbus_bytes_per_line() failed\n",
- __func__);
- return bytes_per_line;
- }
-
- if (!is_dma_aligned(bytes_per_line, mf->height, pcdev->vb_mode)) {
- dev_err(dev, "%s: resulting geometry %ux%u not DMA aligned\n",
- __func__, mf->width, mf->height);
- return -EINVAL;
- }
- return 0;
-}
-
-static int omap1_cam_set_crop(struct soc_camera_device *icd,
- struct v4l2_crop *crop)
-{
- struct v4l2_rect *rect = &crop->c;
- const struct soc_camera_format_xlate *xlate = icd->current_fmt;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct device *dev = icd->parent;
- struct soc_camera_host *ici = to_soc_camera_host(dev);
- struct omap1_cam_dev *pcdev = ici->priv;
- struct v4l2_mbus_framefmt mf;
- int ret;
-
- ret = subdev_call_with_sense(pcdev, dev, icd, sd, s_crop, crop);
- if (ret < 0) {
- dev_warn(dev, "%s: failed to crop to %ux%u@%u:%u\n", __func__,
- rect->width, rect->height, rect->left, rect->top);
- return ret;
- }
-
- ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
- if (ret < 0) {
- dev_warn(dev, "%s: failed to fetch current format\n", __func__);
- return ret;
- }
-
- ret = dma_align(&mf.width, &mf.height, xlate->host_fmt, pcdev->vb_mode,
- false);
- if (ret < 0) {
- dev_err(dev, "%s: failed to align %ux%u %s with DMA\n",
- __func__, mf.width, mf.height,
- xlate->host_fmt->name);
- return ret;
- }
-
- if (!ret) {
- /* sensor returned geometry not DMA aligned, trying to fix */
- ret = set_mbus_format(pcdev, dev, icd, sd, &mf, xlate);
- if (ret < 0) {
- dev_err(dev, "%s: failed to set format\n", __func__);
- return ret;
- }
- }
-
- icd->user_width = mf.width;
- icd->user_height = mf.height;
-
- return 0;
-}
-
-static int omap1_cam_set_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- struct device *dev = icd->parent;
- struct soc_camera_host *ici = to_soc_camera_host(dev);
- struct omap1_cam_dev *pcdev = ici->priv;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- int ret;
-
- xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
- if (!xlate) {
- dev_warn(dev, "%s: format %#x not found\n", __func__,
- pix->pixelformat);
- return -EINVAL;
- }
-
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = dma_align(&mf.width, &mf.height, xlate->host_fmt, pcdev->vb_mode,
- true);
- if (ret < 0) {
- dev_err(dev, "%s: failed to align %ux%u %s with DMA\n",
- __func__, pix->width, pix->height,
- xlate->host_fmt->name);
- return ret;
- }
-
- ret = set_mbus_format(pcdev, dev, icd, sd, &mf, xlate);
- if (ret < 0) {
- dev_err(dev, "%s: failed to set format\n", __func__);
- return ret;
- }
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
- icd->current_fmt = xlate;
-
- return 0;
-}
-
-static int omap1_cam_try_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- int ret;
- /* TODO: limit to mx1 hardware capabilities */
-
- xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
- if (!xlate) {
- dev_warn(icd->parent, "Format %#x not found\n",
- pix->pixelformat);
- return -EINVAL;
- }
-
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- /* limit to sensor capabilities */
- ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
-
- return 0;
-}
-
-static bool sg_mode;
-
-/*
- * Local mmap_mapper wrapper,
- * used for detecting videobuf-dma-contig buffer allocation failures
- * and switching to videobuf-dma-sg automatically for future attempts.
- */
-static int omap1_cam_mmap_mapper(struct videobuf_queue *q,
- struct videobuf_buffer *buf,
- struct vm_area_struct *vma)
-{
- struct soc_camera_device *icd = q->priv_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct omap1_cam_dev *pcdev = ici->priv;
- int ret;
-
- ret = pcdev->mmap_mapper(q, buf, vma);
-
- if (ret == -ENOMEM)
- sg_mode = true;
-
- return ret;
-}
-
-static void omap1_cam_init_videobuf(struct videobuf_queue *q,
- struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct omap1_cam_dev *pcdev = ici->priv;
-
- if (!sg_mode)
- videobuf_queue_dma_contig_init(q, &omap1_videobuf_ops,
- icd->parent, &pcdev->lock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
- sizeof(struct omap1_cam_buf), icd, &icd->video_lock);
- else
- videobuf_queue_sg_init(q, &omap1_videobuf_ops,
- icd->parent, &pcdev->lock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
- sizeof(struct omap1_cam_buf), icd, &icd->video_lock);
-
- /* use videobuf mode (auto)selected with the module parameter */
- pcdev->vb_mode = sg_mode ? OMAP1_CAM_DMA_SG : OMAP1_CAM_DMA_CONTIG;
-
- /*
- * Ensure we substitute the videobuf-dma-contig version of the
- * mmap_mapper() callback with our own wrapper, used for switching
- * automatically to videobuf-dma-sg on buffer allocation failure.
- */
- if (!sg_mode && q->int_ops->mmap_mapper != omap1_cam_mmap_mapper) {
- pcdev->mmap_mapper = q->int_ops->mmap_mapper;
- q->int_ops->mmap_mapper = omap1_cam_mmap_mapper;
- }
-}
-
-static int omap1_cam_reqbufs(struct soc_camera_device *icd,
- struct v4l2_requestbuffers *p)
-{
- int i;
-
- /*
- * This is for locking debugging only. I removed spinlocks and now I
- * check whether .prepare is ever called on a linked buffer, or whether
- * a dma IRQ can occur for an in-work or unlinked buffer. Until now
- * it hadn't triggered
- */
- for (i = 0; i < p->count; i++) {
- struct omap1_cam_buf *buf = container_of(icd->vb_vidq.bufs[i],
- struct omap1_cam_buf, vb);
- buf->inwork = 0;
- INIT_LIST_HEAD(&buf->vb.queue);
- }
-
- return 0;
-}
-
-static int omap1_cam_querycap(struct soc_camera_host *ici,
- struct v4l2_capability *cap)
-{
- /* cap->name is set by the friendly caller:-> */
- strlcpy(cap->card, "OMAP1 Camera", sizeof(cap->card));
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-
- return 0;
-}
-
-static int omap1_cam_set_bus_param(struct soc_camera_device *icd)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct device *dev = icd->parent;
- struct soc_camera_host *ici = to_soc_camera_host(dev);
- struct omap1_cam_dev *pcdev = ici->priv;
- u32 pixfmt = icd->current_fmt->host_fmt->fourcc;
- const struct soc_camera_format_xlate *xlate;
- const struct soc_mbus_pixelfmt *fmt;
- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
- unsigned long common_flags;
- u32 ctrlclock, mode;
- int ret;
-
- ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
- if (!ret) {
- common_flags = soc_mbus_config_compatible(&cfg, SOCAM_BUS_FLAGS);
- if (!common_flags) {
- dev_warn(dev,
- "Flags incompatible: camera 0x%x, host 0x%x\n",
- cfg.flags, SOCAM_BUS_FLAGS);
- return -EINVAL;
- }
- } else if (ret != -ENOIOCTLCMD) {
- return ret;
- } else {
- common_flags = SOCAM_BUS_FLAGS;
- }
-
- /* Make choices, possibly based on platform configuration */
- if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
- (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
- if (!pcdev->pdata ||
- pcdev->pdata->flags & OMAP1_CAMERA_LCLK_RISING)
- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
- else
- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
- }
-
- cfg.flags = common_flags;
- ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
- if (ret < 0 && ret != -ENOIOCTLCMD) {
- dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n",
- common_flags, ret);
- return ret;
- }
-
- ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
- if (ctrlclock & LCLK_EN)
- CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
-
- if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) {
- dev_dbg(dev, "CTRLCLOCK_REG |= POLCLK\n");
- ctrlclock |= POLCLK;
- } else {
- dev_dbg(dev, "CTRLCLOCK_REG &= ~POLCLK\n");
- ctrlclock &= ~POLCLK;
- }
- CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
-
- if (ctrlclock & LCLK_EN)
- CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
-
- /* select bus endianess */
- xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
- fmt = xlate->host_fmt;
-
- mode = CAM_READ(pcdev, MODE) & ~(RAZ_FIFO | IRQ_MASK | DMA);
- if (fmt->order == SOC_MBUS_ORDER_LE) {
- dev_dbg(dev, "MODE_REG &= ~ORDERCAMD\n");
- CAM_WRITE(pcdev, MODE, mode & ~ORDERCAMD);
- } else {
- dev_dbg(dev, "MODE_REG |= ORDERCAMD\n");
- CAM_WRITE(pcdev, MODE, mode | ORDERCAMD);
- }
-
- return 0;
-}
-
-static unsigned int omap1_cam_poll(struct file *file, poll_table *pt)
-{
- struct soc_camera_device *icd = file->private_data;
- struct omap1_cam_buf *buf;
-
- buf = list_entry(icd->vb_vidq.stream.next, struct omap1_cam_buf,
- vb.stream);
-
- poll_wait(file, &buf->vb.done, pt);
-
- if (buf->vb.state == VIDEOBUF_DONE ||
- buf->vb.state == VIDEOBUF_ERROR)
- return POLLIN | POLLRDNORM;
-
- return 0;
-}
-
-static struct soc_camera_host_ops omap1_host_ops = {
- .owner = THIS_MODULE,
- .add = omap1_cam_add_device,
- .remove = omap1_cam_remove_device,
- .get_formats = omap1_cam_get_formats,
- .set_crop = omap1_cam_set_crop,
- .set_fmt = omap1_cam_set_fmt,
- .try_fmt = omap1_cam_try_fmt,
- .init_videobuf = omap1_cam_init_videobuf,
- .reqbufs = omap1_cam_reqbufs,
- .querycap = omap1_cam_querycap,
- .set_bus_param = omap1_cam_set_bus_param,
- .poll = omap1_cam_poll,
-};
-
-static int __init omap1_cam_probe(struct platform_device *pdev)
-{
- struct omap1_cam_dev *pcdev;
- struct resource *res;
- struct clk *clk;
- void __iomem *base;
- unsigned int irq;
- int err = 0;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- irq = platform_get_irq(pdev, 0);
- if (!res || (int)irq <= 0) {
- err = -ENODEV;
- goto exit;
- }
-
- clk = clk_get(&pdev->dev, "armper_ck");
- if (IS_ERR(clk)) {
- err = PTR_ERR(clk);
- goto exit;
- }
-
- pcdev = kzalloc(sizeof(*pcdev) + resource_size(res), GFP_KERNEL);
- if (!pcdev) {
- dev_err(&pdev->dev, "Could not allocate pcdev\n");
- err = -ENOMEM;
- goto exit_put_clk;
- }
-
- pcdev->res = res;
- pcdev->clk = clk;
-
- pcdev->pdata = pdev->dev.platform_data;
- if (pcdev->pdata) {
- pcdev->pflags = pcdev->pdata->flags;
- pcdev->camexclk = pcdev->pdata->camexclk_khz * 1000;
- }
-
- switch (pcdev->camexclk) {
- case 6000000:
- case 8000000:
- case 9600000:
- case 12000000:
- case 24000000:
- break;
- default:
- /* pcdev->camexclk != 0 => pcdev->pdata != NULL */
- dev_warn(&pdev->dev,
- "Incorrect sensor clock frequency %ld kHz, "
- "should be one of 0, 6, 8, 9.6, 12 or 24 MHz, "
- "please correct your platform data\n",
- pcdev->pdata->camexclk_khz);
- pcdev->camexclk = 0;
- case 0:
- dev_info(&pdev->dev, "Not providing sensor clock\n");
- }
-
- INIT_LIST_HEAD(&pcdev->capture);
- spin_lock_init(&pcdev->lock);
-
- /*
- * Request the region.
- */
- if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) {
- err = -EBUSY;
- goto exit_kfree;
- }
-
- base = ioremap(res->start, resource_size(res));
- if (!base) {
- err = -ENOMEM;
- goto exit_release;
- }
- pcdev->irq = irq;
- pcdev->base = base;
-
- sensor_reset(pcdev, true);
-
- err = omap_request_dma(OMAP_DMA_CAMERA_IF_RX, DRIVER_NAME,
- dma_isr, (void *)pcdev, &pcdev->dma_ch);
- if (err < 0) {
- dev_err(&pdev->dev, "Can't request DMA for OMAP1 Camera\n");
- err = -EBUSY;
- goto exit_iounmap;
- }
- dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_ch);
-
- /* preconfigure DMA */
- omap_set_dma_src_params(pcdev->dma_ch, OMAP_DMA_PORT_TIPB,
- OMAP_DMA_AMODE_CONSTANT, res->start + REG_CAMDATA,
- 0, 0);
- omap_set_dma_dest_burst_mode(pcdev->dma_ch, OMAP_DMA_DATA_BURST_4);
- /* setup DMA autoinitialization */
- omap_dma_link_lch(pcdev->dma_ch, pcdev->dma_ch);
-
- err = request_irq(pcdev->irq, cam_isr, 0, DRIVER_NAME, pcdev);
- if (err) {
- dev_err(&pdev->dev, "Camera interrupt register failed\n");
- goto exit_free_dma;
- }
-
- pcdev->soc_host.drv_name = DRIVER_NAME;
- pcdev->soc_host.ops = &omap1_host_ops;
- pcdev->soc_host.priv = pcdev;
- pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
- pcdev->soc_host.nr = pdev->id;
-
- err = soc_camera_host_register(&pcdev->soc_host);
- if (err)
- goto exit_free_irq;
-
- dev_info(&pdev->dev, "OMAP1 Camera Interface driver loaded\n");
-
- return 0;
-
-exit_free_irq:
- free_irq(pcdev->irq, pcdev);
-exit_free_dma:
- omap_free_dma(pcdev->dma_ch);
-exit_iounmap:
- iounmap(base);
-exit_release:
- release_mem_region(res->start, resource_size(res));
-exit_kfree:
- kfree(pcdev);
-exit_put_clk:
- clk_put(clk);
-exit:
- return err;
-}
-
-static int __exit omap1_cam_remove(struct platform_device *pdev)
-{
- struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
- struct omap1_cam_dev *pcdev = container_of(soc_host,
- struct omap1_cam_dev, soc_host);
- struct resource *res;
-
- free_irq(pcdev->irq, pcdev);
-
- omap_free_dma(pcdev->dma_ch);
-
- soc_camera_host_unregister(soc_host);
-
- iounmap(pcdev->base);
-
- res = pcdev->res;
- release_mem_region(res->start, resource_size(res));
-
- clk_put(pcdev->clk);
-
- kfree(pcdev);
-
- dev_info(&pdev->dev, "OMAP1 Camera Interface driver unloaded\n");
-
- return 0;
-}
-
-static struct platform_driver omap1_cam_driver = {
- .driver = {
- .name = DRIVER_NAME,
- },
- .probe = omap1_cam_probe,
- .remove = __exit_p(omap1_cam_remove),
-};
-
-module_platform_driver(omap1_cam_driver);
-
-module_param(sg_mode, bool, 0644);
-MODULE_PARM_DESC(sg_mode, "videobuf mode, 0: dma-contig (default), 1: dma-sg");
-
-MODULE_DESCRIPTION("OMAP1 Camera Interface driver");
-MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/media/video/omap24xxcam-dma.c b/drivers/media/video/omap24xxcam-dma.c
deleted file mode 100644
index b5ae170de4a..00000000000
--- a/drivers/media/video/omap24xxcam-dma.c
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- * drivers/media/video/omap24xxcam-dma.c
- *
- * Copyright (C) 2004 MontaVista Software, Inc.
- * Copyright (C) 2004 Texas Instruments.
- * Copyright (C) 2007 Nokia Corporation.
- *
- * Contact: Sakari Ailus <sakari.ailus@nokia.com>
- *
- * Based on code from Andy Lowe <source@mvista.com> and
- * David Cohen <david.cohen@indt.org.br>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/scatterlist.h>
-
-#include "omap24xxcam.h"
-
-/*
- *
- * DMA hardware.
- *
- */
-
-/* Ack all interrupt on CSR and IRQSTATUS_L0 */
-static void omap24xxcam_dmahw_ack_all(void __iomem *base)
-{
- u32 csr;
- int i;
-
- for (i = 0; i < NUM_CAMDMA_CHANNELS; ++i) {
- csr = omap24xxcam_reg_in(base, CAMDMA_CSR(i));
- /* ack interrupt in CSR */
- omap24xxcam_reg_out(base, CAMDMA_CSR(i), csr);
- }
- omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, 0xf);
-}
-
-/* Ack dmach on CSR and IRQSTATUS_L0 */
-static u32 omap24xxcam_dmahw_ack_ch(void __iomem *base, int dmach)
-{
- u32 csr;
-
- csr = omap24xxcam_reg_in(base, CAMDMA_CSR(dmach));
- /* ack interrupt in CSR */
- omap24xxcam_reg_out(base, CAMDMA_CSR(dmach), csr);
- /* ack interrupt in IRQSTATUS */
- omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, (1 << dmach));
-
- return csr;
-}
-
-static int omap24xxcam_dmahw_running(void __iomem *base, int dmach)
-{
- return omap24xxcam_reg_in(base, CAMDMA_CCR(dmach)) & CAMDMA_CCR_ENABLE;
-}
-
-static void omap24xxcam_dmahw_transfer_setup(void __iomem *base, int dmach,
- dma_addr_t start, u32 len)
-{
- omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
- CAMDMA_CCR_SEL_SRC_DST_SYNC
- | CAMDMA_CCR_BS
- | CAMDMA_CCR_DST_AMODE_POST_INC
- | CAMDMA_CCR_SRC_AMODE_POST_INC
- | CAMDMA_CCR_FS
- | CAMDMA_CCR_WR_ACTIVE
- | CAMDMA_CCR_RD_ACTIVE
- | CAMDMA_CCR_SYNCHRO_CAMERA);
- omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(dmach), 0);
- omap24xxcam_reg_out(base, CAMDMA_CEN(dmach), len);
- omap24xxcam_reg_out(base, CAMDMA_CFN(dmach), 1);
- omap24xxcam_reg_out(base, CAMDMA_CSDP(dmach),
- CAMDMA_CSDP_WRITE_MODE_POSTED
- | CAMDMA_CSDP_DST_BURST_EN_32
- | CAMDMA_CSDP_DST_PACKED
- | CAMDMA_CSDP_SRC_BURST_EN_32
- | CAMDMA_CSDP_SRC_PACKED
- | CAMDMA_CSDP_DATA_TYPE_8BITS);
- omap24xxcam_reg_out(base, CAMDMA_CSSA(dmach), 0);
- omap24xxcam_reg_out(base, CAMDMA_CDSA(dmach), start);
- omap24xxcam_reg_out(base, CAMDMA_CSEI(dmach), 0);
- omap24xxcam_reg_out(base, CAMDMA_CSFI(dmach), DMA_THRESHOLD);
- omap24xxcam_reg_out(base, CAMDMA_CDEI(dmach), 0);
- omap24xxcam_reg_out(base, CAMDMA_CDFI(dmach), 0);
- omap24xxcam_reg_out(base, CAMDMA_CSR(dmach),
- CAMDMA_CSR_MISALIGNED_ERR
- | CAMDMA_CSR_SECURE_ERR
- | CAMDMA_CSR_TRANS_ERR
- | CAMDMA_CSR_BLOCK
- | CAMDMA_CSR_DROP);
- omap24xxcam_reg_out(base, CAMDMA_CICR(dmach),
- CAMDMA_CICR_MISALIGNED_ERR_IE
- | CAMDMA_CICR_SECURE_ERR_IE
- | CAMDMA_CICR_TRANS_ERR_IE
- | CAMDMA_CICR_BLOCK_IE
- | CAMDMA_CICR_DROP_IE);
-}
-
-static void omap24xxcam_dmahw_transfer_start(void __iomem *base, int dmach)
-{
- omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
- CAMDMA_CCR_SEL_SRC_DST_SYNC
- | CAMDMA_CCR_BS
- | CAMDMA_CCR_DST_AMODE_POST_INC
- | CAMDMA_CCR_SRC_AMODE_POST_INC
- | CAMDMA_CCR_ENABLE
- | CAMDMA_CCR_FS
- | CAMDMA_CCR_SYNCHRO_CAMERA);
-}
-
-static void omap24xxcam_dmahw_transfer_chain(void __iomem *base, int dmach,
- int free_dmach)
-{
- int prev_dmach, ch;
-
- if (dmach == 0)
- prev_dmach = NUM_CAMDMA_CHANNELS - 1;
- else
- prev_dmach = dmach - 1;
- omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(prev_dmach),
- CAMDMA_CLNK_CTRL_ENABLE_LNK | dmach);
- /* Did we chain the DMA transfer before the previous one
- * finished?
- */
- ch = (dmach + free_dmach) % NUM_CAMDMA_CHANNELS;
- while (!(omap24xxcam_reg_in(base, CAMDMA_CCR(ch))
- & CAMDMA_CCR_ENABLE)) {
- if (ch == dmach) {
- /* The previous transfer has ended and this one
- * hasn't started, so we must not have chained
- * to the previous one in time. We'll have to
- * start it now.
- */
- omap24xxcam_dmahw_transfer_start(base, dmach);
- break;
- } else
- ch = (ch + 1) % NUM_CAMDMA_CHANNELS;
- }
-}
-
-/* Abort all chained DMA transfers. After all transfers have been
- * aborted and the DMA controller is idle, the completion routines for
- * any aborted transfers will be called in sequence. The DMA
- * controller may not be idle after this routine completes, because
- * the completion routines might start new transfers.
- */
-static void omap24xxcam_dmahw_abort_ch(void __iomem *base, int dmach)
-{
- /* mask all interrupts from this channel */
- omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 0);
- /* unlink this channel */
- omap24xxcam_reg_merge(base, CAMDMA_CLNK_CTRL(dmach), 0,
- CAMDMA_CLNK_CTRL_ENABLE_LNK);
- /* disable this channel */
- omap24xxcam_reg_merge(base, CAMDMA_CCR(dmach), 0, CAMDMA_CCR_ENABLE);
-}
-
-static void omap24xxcam_dmahw_init(void __iomem *base)
-{
- omap24xxcam_reg_out(base, CAMDMA_OCP_SYSCONFIG,
- CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY
- | CAMDMA_OCP_SYSCONFIG_SIDLEMODE_FIDLE
- | CAMDMA_OCP_SYSCONFIG_AUTOIDLE);
-
- omap24xxcam_reg_merge(base, CAMDMA_GCR, 0x10,
- CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH);
-
- omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L0, 0xf);
-}
-
-/*
- *
- * Individual DMA channel handling.
- *
- */
-
-/* Start a DMA transfer from the camera to memory.
- * Returns zero if the transfer was successfully started, or non-zero if all
- * DMA channels are already in use or starting is currently inhibited.
- */
-static int omap24xxcam_dma_start(struct omap24xxcam_dma *dma, dma_addr_t start,
- u32 len, dma_callback_t callback, void *arg)
-{
- unsigned long flags;
- int dmach;
-
- spin_lock_irqsave(&dma->lock, flags);
-
- if (!dma->free_dmach || atomic_read(&dma->dma_stop)) {
- spin_unlock_irqrestore(&dma->lock, flags);
- return -EBUSY;
- }
-
- dmach = dma->next_dmach;
-
- dma->ch_state[dmach].callback = callback;
- dma->ch_state[dmach].arg = arg;
-
- omap24xxcam_dmahw_transfer_setup(dma->base, dmach, start, len);
-
- /* We're ready to start the DMA transfer. */
-
- if (dma->free_dmach < NUM_CAMDMA_CHANNELS) {
- /* A transfer is already in progress, so try to chain to it. */
- omap24xxcam_dmahw_transfer_chain(dma->base, dmach,
- dma->free_dmach);
- } else {
- /* No transfer is in progress, so we'll just start this one
- * now.
- */
- omap24xxcam_dmahw_transfer_start(dma->base, dmach);
- }
-
- dma->next_dmach = (dma->next_dmach + 1) % NUM_CAMDMA_CHANNELS;
- dma->free_dmach--;
-
- spin_unlock_irqrestore(&dma->lock, flags);
-
- return 0;
-}
-
-/* Abort all chained DMA transfers. After all transfers have been
- * aborted and the DMA controller is idle, the completion routines for
- * any aborted transfers will be called in sequence. The DMA
- * controller may not be idle after this routine completes, because
- * the completion routines might start new transfers.
- */
-static void omap24xxcam_dma_abort(struct omap24xxcam_dma *dma, u32 csr)
-{
- unsigned long flags;
- int dmach, i, free_dmach;
- dma_callback_t callback;
- void *arg;
-
- spin_lock_irqsave(&dma->lock, flags);
-
- /* stop any DMA transfers in progress */
- dmach = (dma->next_dmach + dma->free_dmach) % NUM_CAMDMA_CHANNELS;
- for (i = 0; i < NUM_CAMDMA_CHANNELS; i++) {
- omap24xxcam_dmahw_abort_ch(dma->base, dmach);
- dmach = (dmach + 1) % NUM_CAMDMA_CHANNELS;
- }
-
- /* We have to be careful here because the callback routine
- * might start a new DMA transfer, and we only want to abort
- * transfers that were started before this routine was called.
- */
- free_dmach = dma->free_dmach;
- while ((dma->free_dmach < NUM_CAMDMA_CHANNELS) &&
- (free_dmach < NUM_CAMDMA_CHANNELS)) {
- dmach = (dma->next_dmach + dma->free_dmach)
- % NUM_CAMDMA_CHANNELS;
- callback = dma->ch_state[dmach].callback;
- arg = dma->ch_state[dmach].arg;
- dma->free_dmach++;
- free_dmach++;
- if (callback) {
- /* leave interrupts disabled during callback */
- spin_unlock(&dma->lock);
- (*callback) (dma, csr, arg);
- spin_lock(&dma->lock);
- }
- }
-
- spin_unlock_irqrestore(&dma->lock, flags);
-}
-
-/* Abort all chained DMA transfers. After all transfers have been
- * aborted and the DMA controller is idle, the completion routines for
- * any aborted transfers will be called in sequence. If the completion
- * routines attempt to start a new DMA transfer it will fail, so the
- * DMA controller will be idle after this routine completes.
- */
-static void omap24xxcam_dma_stop(struct omap24xxcam_dma *dma, u32 csr)
-{
- atomic_inc(&dma->dma_stop);
- omap24xxcam_dma_abort(dma, csr);
- atomic_dec(&dma->dma_stop);
-}
-
-/* Camera DMA interrupt service routine. */
-void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma)
-{
- int dmach;
- dma_callback_t callback;
- void *arg;
- u32 csr;
- const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
- | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
- | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
-
- spin_lock(&dma->lock);
-
- if (dma->free_dmach == NUM_CAMDMA_CHANNELS) {
- /* A camera DMA interrupt occurred while all channels
- * are idle, so we'll acknowledge the interrupt in the
- * IRQSTATUS register and exit.
- */
- omap24xxcam_dmahw_ack_all(dma->base);
- spin_unlock(&dma->lock);
- return;
- }
-
- while (dma->free_dmach < NUM_CAMDMA_CHANNELS) {
- dmach = (dma->next_dmach + dma->free_dmach)
- % NUM_CAMDMA_CHANNELS;
- if (omap24xxcam_dmahw_running(dma->base, dmach)) {
- /* This buffer hasn't finished yet, so we're done. */
- break;
- }
- csr = omap24xxcam_dmahw_ack_ch(dma->base, dmach);
- if (csr & csr_error) {
- /* A DMA error occurred, so stop all DMA
- * transfers in progress.
- */
- spin_unlock(&dma->lock);
- omap24xxcam_dma_stop(dma, csr);
- return;
- } else {
- callback = dma->ch_state[dmach].callback;
- arg = dma->ch_state[dmach].arg;
- dma->free_dmach++;
- if (callback) {
- spin_unlock(&dma->lock);
- (*callback) (dma, csr, arg);
- spin_lock(&dma->lock);
- }
- }
- }
-
- spin_unlock(&dma->lock);
-
- omap24xxcam_sgdma_process(
- container_of(dma, struct omap24xxcam_sgdma, dma));
-}
-
-void omap24xxcam_dma_hwinit(struct omap24xxcam_dma *dma)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dma->lock, flags);
-
- omap24xxcam_dmahw_init(dma->base);
-
- spin_unlock_irqrestore(&dma->lock, flags);
-}
-
-static void omap24xxcam_dma_init(struct omap24xxcam_dma *dma,
- void __iomem *base)
-{
- int ch;
-
- /* group all channels on DMA IRQ0 and unmask irq */
- spin_lock_init(&dma->lock);
- dma->base = base;
- dma->free_dmach = NUM_CAMDMA_CHANNELS;
- dma->next_dmach = 0;
- for (ch = 0; ch < NUM_CAMDMA_CHANNELS; ch++) {
- dma->ch_state[ch].callback = NULL;
- dma->ch_state[ch].arg = NULL;
- }
-}
-
-/*
- *
- * Scatter-gather DMA.
- *
- * High-level DMA construct for transferring whole picture frames to
- * memory that is discontinuous.
- *
- */
-
-/* DMA completion routine for the scatter-gather DMA fragments. */
-static void omap24xxcam_sgdma_callback(struct omap24xxcam_dma *dma, u32 csr,
- void *arg)
-{
- struct omap24xxcam_sgdma *sgdma =
- container_of(dma, struct omap24xxcam_sgdma, dma);
- int sgslot = (int)arg;
- struct sgdma_state *sg_state;
- const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
- | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
- | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
-
- spin_lock(&sgdma->lock);
-
- /* We got an interrupt, we can remove the timer */
- del_timer(&sgdma->reset_timer);
-
- sg_state = sgdma->sg_state + sgslot;
- if (!sg_state->queued_sglist) {
- spin_unlock(&sgdma->lock);
- printk(KERN_ERR "%s: sgdma completed when none queued!\n",
- __func__);
- return;
- }
-
- sg_state->csr |= csr;
- if (!--sg_state->queued_sglist) {
- /* Queue for this sglist is empty, so check to see if we're
- * done.
- */
- if ((sg_state->next_sglist == sg_state->sglen)
- || (sg_state->csr & csr_error)) {
- sgdma_callback_t callback = sg_state->callback;
- void *arg = sg_state->arg;
- u32 sg_csr = sg_state->csr;
- /* All done with this sglist */
- sgdma->free_sgdma++;
- if (callback) {
- spin_unlock(&sgdma->lock);
- (*callback) (sgdma, sg_csr, arg);
- return;
- }
- }
- }
-
- spin_unlock(&sgdma->lock);
-}
-
-/* Start queued scatter-gather DMA transfers. */
-void omap24xxcam_sgdma_process(struct omap24xxcam_sgdma *sgdma)
-{
- unsigned long flags;
- int queued_sgdma, sgslot;
- struct sgdma_state *sg_state;
- const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
- | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
- | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
-
- spin_lock_irqsave(&sgdma->lock, flags);
-
- queued_sgdma = NUM_SG_DMA - sgdma->free_sgdma;
- sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
- while (queued_sgdma > 0) {
- sg_state = sgdma->sg_state + sgslot;
- while ((sg_state->next_sglist < sg_state->sglen) &&
- !(sg_state->csr & csr_error)) {
- const struct scatterlist *sglist;
- unsigned int len;
-
- sglist = sg_state->sglist + sg_state->next_sglist;
- /* try to start the next DMA transfer */
- if (sg_state->next_sglist + 1 == sg_state->sglen) {
- /*
- * On the last sg, we handle the case where
- * cam->img.pix.sizeimage % PAGE_ALIGN != 0
- */
- len = sg_state->len - sg_state->bytes_read;
- } else {
- len = sg_dma_len(sglist);
- }
-
- if (omap24xxcam_dma_start(&sgdma->dma,
- sg_dma_address(sglist),
- len,
- omap24xxcam_sgdma_callback,
- (void *)sgslot)) {
- /* DMA start failed */
- spin_unlock_irqrestore(&sgdma->lock, flags);
- return;
- } else {
- unsigned long expires;
- /* DMA start was successful */
- sg_state->next_sglist++;
- sg_state->bytes_read += len;
- sg_state->queued_sglist++;
-
- /* We start the reset timer */
- expires = jiffies + HZ;
- mod_timer(&sgdma->reset_timer, expires);
- }
- }
- queued_sgdma--;
- sgslot = (sgslot + 1) % NUM_SG_DMA;
- }
-
- spin_unlock_irqrestore(&sgdma->lock, flags);
-}
-
-/*
- * Queue a scatter-gather DMA transfer from the camera to memory.
- * Returns zero if the transfer was successfully queued, or non-zero
- * if all of the scatter-gather slots are already in use.
- */
-int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma,
- const struct scatterlist *sglist, int sglen,
- int len, sgdma_callback_t callback, void *arg)
-{
- unsigned long flags;
- struct sgdma_state *sg_state;
-
- if ((sglen < 0) || ((sglen > 0) && !sglist))
- return -EINVAL;
-
- spin_lock_irqsave(&sgdma->lock, flags);
-
- if (!sgdma->free_sgdma) {
- spin_unlock_irqrestore(&sgdma->lock, flags);
- return -EBUSY;
- }
-
- sg_state = sgdma->sg_state + sgdma->next_sgdma;
-
- sg_state->sglist = sglist;
- sg_state->sglen = sglen;
- sg_state->next_sglist = 0;
- sg_state->bytes_read = 0;
- sg_state->len = len;
- sg_state->queued_sglist = 0;
- sg_state->csr = 0;
- sg_state->callback = callback;
- sg_state->arg = arg;
-
- sgdma->next_sgdma = (sgdma->next_sgdma + 1) % NUM_SG_DMA;
- sgdma->free_sgdma--;
-
- spin_unlock_irqrestore(&sgdma->lock, flags);
-
- omap24xxcam_sgdma_process(sgdma);
-
- return 0;
-}
-
-/* Sync scatter-gather DMA by aborting any DMA transfers currently in progress.
- * Any queued scatter-gather DMA transactions that have not yet been started
- * will remain queued. The DMA controller will be idle after this routine
- * completes. When the scatter-gather queue is restarted, the next
- * scatter-gather DMA transfer will begin at the start of a new transaction.
- */
-void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma)
-{
- unsigned long flags;
- int sgslot;
- struct sgdma_state *sg_state;
- u32 csr = CAMDMA_CSR_TRANS_ERR;
-
- /* stop any DMA transfers in progress */
- omap24xxcam_dma_stop(&sgdma->dma, csr);
-
- spin_lock_irqsave(&sgdma->lock, flags);
-
- if (sgdma->free_sgdma < NUM_SG_DMA) {
- sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
- sg_state = sgdma->sg_state + sgslot;
- if (sg_state->next_sglist != 0) {
- /* This DMA transfer was in progress, so abort it. */
- sgdma_callback_t callback = sg_state->callback;
- void *arg = sg_state->arg;
- sgdma->free_sgdma++;
- if (callback) {
- /* leave interrupts masked */
- spin_unlock(&sgdma->lock);
- (*callback) (sgdma, csr, arg);
- spin_lock(&sgdma->lock);
- }
- }
- }
-
- spin_unlock_irqrestore(&sgdma->lock, flags);
-}
-
-void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma,
- void __iomem *base,
- void (*reset_callback)(unsigned long data),
- unsigned long reset_callback_data)
-{
- int sg;
-
- spin_lock_init(&sgdma->lock);
- sgdma->free_sgdma = NUM_SG_DMA;
- sgdma->next_sgdma = 0;
- for (sg = 0; sg < NUM_SG_DMA; sg++) {
- sgdma->sg_state[sg].sglen = 0;
- sgdma->sg_state[sg].next_sglist = 0;
- sgdma->sg_state[sg].bytes_read = 0;
- sgdma->sg_state[sg].queued_sglist = 0;
- sgdma->sg_state[sg].csr = 0;
- sgdma->sg_state[sg].callback = NULL;
- sgdma->sg_state[sg].arg = NULL;
- }
-
- omap24xxcam_dma_init(&sgdma->dma, base);
- setup_timer(&sgdma->reset_timer, reset_callback, reset_callback_data);
-}
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c
deleted file mode 100644
index 8d7283bbd43..00000000000
--- a/drivers/media/video/omap24xxcam.c
+++ /dev/null
@@ -1,1881 +0,0 @@
-/*
- * drivers/media/video/omap24xxcam.c
- *
- * OMAP 2 camera block driver.
- *
- * Copyright (C) 2004 MontaVista Software, Inc.
- * Copyright (C) 2004 Texas Instruments.
- * Copyright (C) 2007-2008 Nokia Corporation.
- *
- * Contact: Sakari Ailus <sakari.ailus@nokia.com>
- *
- * Based on code from Andy Lowe <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/videodev2.h>
-#include <linux/pci.h> /* needed for videobufs */
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-
-#include "omap24xxcam.h"
-
-#define OMAP24XXCAM_VERSION "0.0.1"
-
-#define RESET_TIMEOUT_NS 10000
-
-static void omap24xxcam_reset(struct omap24xxcam_device *cam);
-static int omap24xxcam_sensor_if_enable(struct omap24xxcam_device *cam);
-static void omap24xxcam_device_unregister(struct v4l2_int_device *s);
-static int omap24xxcam_remove(struct platform_device *pdev);
-
-/* module parameters */
-static int video_nr = -1; /* video device minor (-1 ==> auto assign) */
-/*
- * Maximum amount of memory to use for capture buffers.
- * Default is 4800KB, enough to double-buffer SXGA.
- */
-static int capture_mem = 1280 * 960 * 2 * 2;
-
-static struct v4l2_int_device omap24xxcam;
-
-/*
- *
- * Clocks.
- *
- */
-
-static void omap24xxcam_clock_put(struct omap24xxcam_device *cam)
-{
- if (cam->ick != NULL && !IS_ERR(cam->ick))
- clk_put(cam->ick);
- if (cam->fck != NULL && !IS_ERR(cam->fck))
- clk_put(cam->fck);
-
- cam->ick = cam->fck = NULL;
-}
-
-static int omap24xxcam_clock_get(struct omap24xxcam_device *cam)
-{
- int rval = 0;
-
- cam->fck = clk_get(cam->dev, "fck");
- if (IS_ERR(cam->fck)) {
- dev_err(cam->dev, "can't get camera fck");
- rval = PTR_ERR(cam->fck);
- omap24xxcam_clock_put(cam);
- return rval;
- }
-
- cam->ick = clk_get(cam->dev, "ick");
- if (IS_ERR(cam->ick)) {
- dev_err(cam->dev, "can't get camera ick");
- rval = PTR_ERR(cam->ick);
- omap24xxcam_clock_put(cam);
- }
-
- return rval;
-}
-
-static void omap24xxcam_clock_on(struct omap24xxcam_device *cam)
-{
- clk_enable(cam->fck);
- clk_enable(cam->ick);
-}
-
-static void omap24xxcam_clock_off(struct omap24xxcam_device *cam)
-{
- clk_disable(cam->fck);
- clk_disable(cam->ick);
-}
-
-/*
- *
- * Camera core
- *
- */
-
-/*
- * Set xclk.
- *
- * To disable xclk, use value zero.
- */
-static void omap24xxcam_core_xclk_set(const struct omap24xxcam_device *cam,
- u32 xclk)
-{
- if (xclk) {
- u32 divisor = CAM_MCLK / xclk;
-
- if (divisor == 1)
- omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET,
- CC_CTRL_XCLK,
- CC_CTRL_XCLK_DIV_BYPASS);
- else
- omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET,
- CC_CTRL_XCLK, divisor);
- } else
- omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET,
- CC_CTRL_XCLK, CC_CTRL_XCLK_DIV_STABLE_LOW);
-}
-
-static void omap24xxcam_core_hwinit(const struct omap24xxcam_device *cam)
-{
- /*
- * Setting the camera core AUTOIDLE bit causes problems with frame
- * synchronization, so we will clear the AUTOIDLE bit instead.
- */
- omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_SYSCONFIG,
- CC_SYSCONFIG_AUTOIDLE);
-
- /* program the camera interface DMA packet size */
- omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL_DMA,
- CC_CTRL_DMA_EN | (DMA_THRESHOLD / 4 - 1));
-
- /* enable camera core error interrupts */
- omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_IRQENABLE,
- CC_IRQENABLE_FW_ERR_IRQ
- | CC_IRQENABLE_FSC_ERR_IRQ
- | CC_IRQENABLE_SSC_ERR_IRQ
- | CC_IRQENABLE_FIFO_OF_IRQ);
-}
-
-/*
- * Enable the camera core.
- *
- * Data transfer to the camera DMA starts from next starting frame.
- */
-static void omap24xxcam_core_enable(const struct omap24xxcam_device *cam)
-{
-
- omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL,
- cam->cc_ctrl);
-}
-
-/*
- * Disable camera core.
- *
- * The data transfer will be stopped immediately (CC_CTRL_CC_RST). The
- * core internal state machines will be reset. Use
- * CC_CTRL_CC_FRAME_TRIG instead if you want to transfer the current
- * frame completely.
- */
-static void omap24xxcam_core_disable(const struct omap24xxcam_device *cam)
-{
- omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL,
- CC_CTRL_CC_RST);
-}
-
-/* Interrupt service routine for camera core interrupts. */
-static void omap24xxcam_core_isr(struct omap24xxcam_device *cam)
-{
- u32 cc_irqstatus;
- const u32 cc_irqstatus_err =
- CC_IRQSTATUS_FW_ERR_IRQ
- | CC_IRQSTATUS_FSC_ERR_IRQ
- | CC_IRQSTATUS_SSC_ERR_IRQ
- | CC_IRQSTATUS_FIFO_UF_IRQ
- | CC_IRQSTATUS_FIFO_OF_IRQ;
-
- cc_irqstatus = omap24xxcam_reg_in(cam->mmio_base + CC_REG_OFFSET,
- CC_IRQSTATUS);
- omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_IRQSTATUS,
- cc_irqstatus);
-
- if (cc_irqstatus & cc_irqstatus_err
- && !atomic_read(&cam->in_reset)) {
- dev_dbg(cam->dev, "resetting camera, cc_irqstatus 0x%x\n",
- cc_irqstatus);
- omap24xxcam_reset(cam);
- }
-}
-
-/*
- *
- * videobuf_buffer handling.
- *
- * Memory for mmapped videobuf_buffers is not allocated
- * conventionally, but by several kmalloc allocations and then
- * creating the scatterlist on our own. User-space buffers are handled
- * normally.
- *
- */
-
-/*
- * Free the memory-mapped buffer memory allocated for a
- * videobuf_buffer and the associated scatterlist.
- */
-static void omap24xxcam_vbq_free_mmap_buffer(struct videobuf_buffer *vb)
-{
- struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
- size_t alloc_size;
- struct page *page;
- int i;
-
- if (dma->sglist == NULL)
- return;
-
- i = dma->sglen;
- while (i) {
- i--;
- alloc_size = sg_dma_len(&dma->sglist[i]);
- page = sg_page(&dma->sglist[i]);
- do {
- ClearPageReserved(page++);
- } while (alloc_size -= PAGE_SIZE);
- __free_pages(sg_page(&dma->sglist[i]),
- get_order(sg_dma_len(&dma->sglist[i])));
- }
-
- kfree(dma->sglist);
- dma->sglist = NULL;
-}
-
-/* Release all memory related to the videobuf_queue. */
-static void omap24xxcam_vbq_free_mmap_buffers(struct videobuf_queue *vbq)
-{
- int i;
-
- mutex_lock(&vbq->vb_lock);
-
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- if (NULL == vbq->bufs[i])
- continue;
- if (V4L2_MEMORY_MMAP != vbq->bufs[i]->memory)
- continue;
- vbq->ops->buf_release(vbq, vbq->bufs[i]);
- omap24xxcam_vbq_free_mmap_buffer(vbq->bufs[i]);
- kfree(vbq->bufs[i]);
- vbq->bufs[i] = NULL;
- }
-
- mutex_unlock(&vbq->vb_lock);
-
- videobuf_mmap_free(vbq);
-}
-
-/*
- * Allocate physically as contiguous as possible buffer for video
- * frame and allocate and build DMA scatter-gather list for it.
- */
-static int omap24xxcam_vbq_alloc_mmap_buffer(struct videobuf_buffer *vb)
-{
- unsigned int order;
- size_t alloc_size, size = vb->bsize; /* vb->bsize is page aligned */
- struct page *page;
- int max_pages, err = 0, i = 0;
- struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
-
- /*
- * allocate maximum size scatter-gather list. Note this is
- * overhead. We may not use as many entries as we allocate
- */
- max_pages = vb->bsize >> PAGE_SHIFT;
- dma->sglist = kcalloc(max_pages, sizeof(*dma->sglist), GFP_KERNEL);
- if (dma->sglist == NULL) {
- err = -ENOMEM;
- goto out;
- }
-
- while (size) {
- order = get_order(size);
- /*
- * do not over-allocate even if we would get larger
- * contiguous chunk that way
- */
- if ((PAGE_SIZE << order) > size)
- order--;
-
- /* try to allocate as many contiguous pages as possible */
- page = alloc_pages(GFP_KERNEL, order);
- /* if allocation fails, try to allocate smaller amount */
- while (page == NULL) {
- order--;
- page = alloc_pages(GFP_KERNEL, order);
- if (page == NULL && !order) {
- err = -ENOMEM;
- goto out;
- }
- }
- size -= (PAGE_SIZE << order);
-
- /* append allocated chunk of pages into scatter-gather list */
- sg_set_page(&dma->sglist[i], page, PAGE_SIZE << order, 0);
- dma->sglen++;
- i++;
-
- alloc_size = (PAGE_SIZE << order);
-
- /* clear pages before giving them to user space */
- memset(page_address(page), 0, alloc_size);
-
- /* mark allocated pages reserved */
- do {
- SetPageReserved(page++);
- } while (alloc_size -= PAGE_SIZE);
- }
- /*
- * REVISIT: not fully correct to assign nr_pages == sglen but
- * video-buf is passing nr_pages for e.g. unmap_sg calls
- */
- dma->nr_pages = dma->sglen;
- dma->direction = PCI_DMA_FROMDEVICE;
-
- return 0;
-
-out:
- omap24xxcam_vbq_free_mmap_buffer(vb);
- return err;
-}
-
-static int omap24xxcam_vbq_alloc_mmap_buffers(struct videobuf_queue *vbq,
- unsigned int count)
-{
- int i, err = 0;
- struct omap24xxcam_fh *fh =
- container_of(vbq, struct omap24xxcam_fh, vbq);
-
- mutex_lock(&vbq->vb_lock);
-
- for (i = 0; i < count; i++) {
- err = omap24xxcam_vbq_alloc_mmap_buffer(vbq->bufs[i]);
- if (err)
- goto out;
- dev_dbg(fh->cam->dev, "sglen is %d for buffer %d\n",
- videobuf_to_dma(vbq->bufs[i])->sglen, i);
- }
-
- mutex_unlock(&vbq->vb_lock);
-
- return 0;
-out:
- while (i) {
- i--;
- omap24xxcam_vbq_free_mmap_buffer(vbq->bufs[i]);
- }
-
- mutex_unlock(&vbq->vb_lock);
-
- return err;
-}
-
-/*
- * This routine is called from interrupt context when a scatter-gather DMA
- * transfer of a videobuf_buffer completes.
- */
-static void omap24xxcam_vbq_complete(struct omap24xxcam_sgdma *sgdma,
- u32 csr, void *arg)
-{
- struct omap24xxcam_device *cam =
- container_of(sgdma, struct omap24xxcam_device, sgdma);
- struct omap24xxcam_fh *fh = cam->streaming->private_data;
- struct videobuf_buffer *vb = (struct videobuf_buffer *)arg;
- const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
- | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
- | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
- unsigned long flags;
-
- spin_lock_irqsave(&cam->core_enable_disable_lock, flags);
- if (--cam->sgdma_in_queue == 0)
- omap24xxcam_core_disable(cam);
- spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
-
- do_gettimeofday(&vb->ts);
- vb->field_count = atomic_add_return(2, &fh->field_count);
- if (csr & csr_error) {
- vb->state = VIDEOBUF_ERROR;
- if (!atomic_read(&fh->cam->in_reset)) {
- dev_dbg(cam->dev, "resetting camera, csr 0x%x\n", csr);
- omap24xxcam_reset(cam);
- }
- } else
- vb->state = VIDEOBUF_DONE;
- wake_up(&vb->done);
-}
-
-static void omap24xxcam_vbq_release(struct videobuf_queue *vbq,
- struct videobuf_buffer *vb)
-{
- struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
-
- /* wait for buffer, especially to get out of the sgdma queue */
- videobuf_waiton(vbq, vb, 0, 0);
- if (vb->memory == V4L2_MEMORY_MMAP) {
- dma_unmap_sg(vbq->dev, dma->sglist, dma->sglen,
- dma->direction);
- dma->direction = DMA_NONE;
- } else {
- videobuf_dma_unmap(vbq->dev, videobuf_to_dma(vb));
- videobuf_dma_free(videobuf_to_dma(vb));
- }
-
- vb->state = VIDEOBUF_NEEDS_INIT;
-}
-
-/*
- * Limit the number of available kernel image capture buffers based on the
- * number requested, the currently selected image size, and the maximum
- * amount of memory permitted for kernel capture buffers.
- */
-static int omap24xxcam_vbq_setup(struct videobuf_queue *vbq, unsigned int *cnt,
- unsigned int *size)
-{
- struct omap24xxcam_fh *fh = vbq->priv_data;
-
- if (*cnt <= 0)
- *cnt = VIDEO_MAX_FRAME; /* supply a default number of buffers */
-
- if (*cnt > VIDEO_MAX_FRAME)
- *cnt = VIDEO_MAX_FRAME;
-
- *size = fh->pix.sizeimage;
-
- /* accessing fh->cam->capture_mem is ok, it's constant */
- if (*size * *cnt > fh->cam->capture_mem)
- *cnt = fh->cam->capture_mem / *size;
-
- return 0;
-}
-
-static int omap24xxcam_dma_iolock(struct videobuf_queue *vbq,
- struct videobuf_dmabuf *dma)
-{
- int err = 0;
-
- dma->direction = PCI_DMA_FROMDEVICE;
- if (!dma_map_sg(vbq->dev, dma->sglist, dma->sglen, dma->direction)) {
- kfree(dma->sglist);
- dma->sglist = NULL;
- dma->sglen = 0;
- err = -EIO;
- }
-
- return err;
-}
-
-static int omap24xxcam_vbq_prepare(struct videobuf_queue *vbq,
- struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct omap24xxcam_fh *fh = vbq->priv_data;
- int err = 0;
-
- /*
- * Accessing pix here is okay since it's constant while
- * streaming is on (and we only get called then).
- */
- if (vb->baddr) {
- /* This is a userspace buffer. */
- if (fh->pix.sizeimage > vb->bsize) {
- /* The buffer isn't big enough. */
- err = -EINVAL;
- } else
- vb->size = fh->pix.sizeimage;
- } else {
- if (vb->state != VIDEOBUF_NEEDS_INIT) {
- /*
- * We have a kernel bounce buffer that has
- * already been allocated.
- */
- if (fh->pix.sizeimage > vb->size) {
- /*
- * The image size has been changed to
- * a larger size since this buffer was
- * allocated, so we need to free and
- * reallocate it.
- */
- omap24xxcam_vbq_release(vbq, vb);
- vb->size = fh->pix.sizeimage;
- }
- } else {
- /* We need to allocate a new kernel bounce buffer. */
- vb->size = fh->pix.sizeimage;
- }
- }
-
- if (err)
- return err;
-
- vb->width = fh->pix.width;
- vb->height = fh->pix.height;
- vb->field = field;
-
- if (vb->state == VIDEOBUF_NEEDS_INIT) {
- if (vb->memory == V4L2_MEMORY_MMAP)
- /*
- * we have built the scatter-gather list by ourself so
- * do the scatter-gather mapping as well
- */
- err = omap24xxcam_dma_iolock(vbq, videobuf_to_dma(vb));
- else
- err = videobuf_iolock(vbq, vb, NULL);
- }
-
- if (!err)
- vb->state = VIDEOBUF_PREPARED;
- else
- omap24xxcam_vbq_release(vbq, vb);
-
- return err;
-}
-
-static void omap24xxcam_vbq_queue(struct videobuf_queue *vbq,
- struct videobuf_buffer *vb)
-{
- struct omap24xxcam_fh *fh = vbq->priv_data;
- struct omap24xxcam_device *cam = fh->cam;
- enum videobuf_state state = vb->state;
- unsigned long flags;
- int err;
-
- /*
- * FIXME: We're marking the buffer active since we have no
- * pretty way of marking it active exactly when the
- * scatter-gather transfer starts.
- */
- vb->state = VIDEOBUF_ACTIVE;
-
- err = omap24xxcam_sgdma_queue(&fh->cam->sgdma,
- videobuf_to_dma(vb)->sglist,
- videobuf_to_dma(vb)->sglen, vb->size,
- omap24xxcam_vbq_complete, vb);
-
- if (!err) {
- spin_lock_irqsave(&cam->core_enable_disable_lock, flags);
- if (++cam->sgdma_in_queue == 1
- && !atomic_read(&cam->in_reset))
- omap24xxcam_core_enable(cam);
- spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
- } else {
- /*
- * Oops. We're not supposed to get any errors here.
- * The only way we could get an error is if we ran out
- * of scatter-gather DMA slots, but we are supposed to
- * have at least as many scatter-gather DMA slots as
- * video buffers so that can't happen.
- */
- dev_err(cam->dev, "failed to queue a video buffer for dma!\n");
- dev_err(cam->dev, "likely a bug in the driver!\n");
- vb->state = state;
- }
-}
-
-static struct videobuf_queue_ops omap24xxcam_vbq_ops = {
- .buf_setup = omap24xxcam_vbq_setup,
- .buf_prepare = omap24xxcam_vbq_prepare,
- .buf_queue = omap24xxcam_vbq_queue,
- .buf_release = omap24xxcam_vbq_release,
-};
-
-/*
- *
- * OMAP main camera system
- *
- */
-
-/*
- * Reset camera block to power-on state.
- */
-static void omap24xxcam_poweron_reset(struct omap24xxcam_device *cam)
-{
- int max_loop = RESET_TIMEOUT_NS;
-
- /* Reset whole camera subsystem */
- omap24xxcam_reg_out(cam->mmio_base,
- CAM_SYSCONFIG,
- CAM_SYSCONFIG_SOFTRESET);
-
- /* Wait till it's finished */
- while (!(omap24xxcam_reg_in(cam->mmio_base, CAM_SYSSTATUS)
- & CAM_SYSSTATUS_RESETDONE)
- && --max_loop) {
- ndelay(1);
- }
-
- if (!(omap24xxcam_reg_in(cam->mmio_base, CAM_SYSSTATUS)
- & CAM_SYSSTATUS_RESETDONE))
- dev_err(cam->dev, "camera soft reset timeout\n");
-}
-
-/*
- * (Re)initialise the camera block.
- */
-static void omap24xxcam_hwinit(struct omap24xxcam_device *cam)
-{
- omap24xxcam_poweron_reset(cam);
-
- /* set the camera subsystem autoidle bit */
- omap24xxcam_reg_out(cam->mmio_base, CAM_SYSCONFIG,
- CAM_SYSCONFIG_AUTOIDLE);
-
- /* set the camera MMU autoidle bit */
- omap24xxcam_reg_out(cam->mmio_base,
- CAMMMU_REG_OFFSET + CAMMMU_SYSCONFIG,
- CAMMMU_SYSCONFIG_AUTOIDLE);
-
- omap24xxcam_core_hwinit(cam);
-
- omap24xxcam_dma_hwinit(&cam->sgdma.dma);
-}
-
-/*
- * Callback for dma transfer stalling.
- */
-static void omap24xxcam_stalled_dma_reset(unsigned long data)
-{
- struct omap24xxcam_device *cam = (struct omap24xxcam_device *)data;
-
- if (!atomic_read(&cam->in_reset)) {
- dev_dbg(cam->dev, "dma stalled, resetting camera\n");
- omap24xxcam_reset(cam);
- }
-}
-
-/*
- * Stop capture. Mark we're doing a reset, stop DMA transfers and
- * core. (No new scatter-gather transfers will be queued whilst
- * in_reset is non-zero.)
- *
- * If omap24xxcam_capture_stop is called from several places at
- * once, only the first call will have an effect. Similarly, the last
- * call omap24xxcam_streaming_cont will have effect.
- *
- * Serialisation is ensured by using cam->core_enable_disable_lock.
- */
-static void omap24xxcam_capture_stop(struct omap24xxcam_device *cam)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cam->core_enable_disable_lock, flags);
-
- if (atomic_inc_return(&cam->in_reset) != 1) {
- spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
- return;
- }
-
- omap24xxcam_core_disable(cam);
-
- spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
-
- omap24xxcam_sgdma_sync(&cam->sgdma);
-}
-
-/*
- * Reset and continue streaming.
- *
- * Note: Resetting the camera FIFO via the CC_RST bit in the CC_CTRL
- * register is supposed to be sufficient to recover from a camera
- * interface error, but it doesn't seem to be enough. If we only do
- * that then subsequent image captures are out of sync by either one
- * or two times DMA_THRESHOLD bytes. Resetting and re-initializing the
- * entire camera subsystem prevents the problem with frame
- * synchronization.
- */
-static void omap24xxcam_capture_cont(struct omap24xxcam_device *cam)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cam->core_enable_disable_lock, flags);
-
- if (atomic_read(&cam->in_reset) != 1)
- goto out;
-
- omap24xxcam_hwinit(cam);
-
- omap24xxcam_sensor_if_enable(cam);
-
- omap24xxcam_sgdma_process(&cam->sgdma);
-
- if (cam->sgdma_in_queue)
- omap24xxcam_core_enable(cam);
-
-out:
- atomic_dec(&cam->in_reset);
- spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
-}
-
-static ssize_t
-omap24xxcam_streaming_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct omap24xxcam_device *cam = dev_get_drvdata(dev);
-
- return sprintf(buf, "%s\n", cam->streaming ? "active" : "inactive");
-}
-static DEVICE_ATTR(streaming, S_IRUGO, omap24xxcam_streaming_show, NULL);
-
-/*
- * Stop capture and restart it. I.e. reset the camera during use.
- */
-static void omap24xxcam_reset(struct omap24xxcam_device *cam)
-{
- omap24xxcam_capture_stop(cam);
- omap24xxcam_capture_cont(cam);
-}
-
-/*
- * The main interrupt handler.
- */
-static irqreturn_t omap24xxcam_isr(int irq, void *arg)
-{
- struct omap24xxcam_device *cam = (struct omap24xxcam_device *)arg;
- u32 irqstatus;
- unsigned int irqhandled = 0;
-
- irqstatus = omap24xxcam_reg_in(cam->mmio_base, CAM_IRQSTATUS);
-
- if (irqstatus &
- (CAM_IRQSTATUS_DMA_IRQ2 | CAM_IRQSTATUS_DMA_IRQ1
- | CAM_IRQSTATUS_DMA_IRQ0)) {
- omap24xxcam_dma_isr(&cam->sgdma.dma);
- irqhandled = 1;
- }
- if (irqstatus & CAM_IRQSTATUS_CC_IRQ) {
- omap24xxcam_core_isr(cam);
- irqhandled = 1;
- }
- if (irqstatus & CAM_IRQSTATUS_MMU_IRQ)
- dev_err(cam->dev, "unhandled camera MMU interrupt!\n");
-
- return IRQ_RETVAL(irqhandled);
-}
-
-/*
- *
- * Sensor handling.
- *
- */
-
-/*
- * Enable the external sensor interface. Try to negotiate interface
- * parameters with the sensor and start using the new ones. The calls
- * to sensor_if_enable and sensor_if_disable need not to be balanced.
- */
-static int omap24xxcam_sensor_if_enable(struct omap24xxcam_device *cam)
-{
- int rval;
- struct v4l2_ifparm p;
-
- rval = vidioc_int_g_ifparm(cam->sdev, &p);
- if (rval) {
- dev_err(cam->dev, "vidioc_int_g_ifparm failed with %d\n", rval);
- return rval;
- }
-
- cam->if_type = p.if_type;
-
- cam->cc_ctrl = CC_CTRL_CC_EN;
-
- switch (p.if_type) {
- case V4L2_IF_TYPE_BT656:
- if (p.u.bt656.frame_start_on_rising_vs)
- cam->cc_ctrl |= CC_CTRL_NOBT_SYNCHRO;
- if (p.u.bt656.bt_sync_correct)
- cam->cc_ctrl |= CC_CTRL_BT_CORRECT;
- if (p.u.bt656.swap)
- cam->cc_ctrl |= CC_CTRL_PAR_ORDERCAM;
- if (p.u.bt656.latch_clk_inv)
- cam->cc_ctrl |= CC_CTRL_PAR_CLK_POL;
- if (p.u.bt656.nobt_hs_inv)
- cam->cc_ctrl |= CC_CTRL_NOBT_HS_POL;
- if (p.u.bt656.nobt_vs_inv)
- cam->cc_ctrl |= CC_CTRL_NOBT_VS_POL;
-
- switch (p.u.bt656.mode) {
- case V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT:
- cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT8;
- break;
- case V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT:
- cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT10;
- break;
- case V4L2_IF_TYPE_BT656_MODE_NOBT_12BIT:
- cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT12;
- break;
- case V4L2_IF_TYPE_BT656_MODE_BT_8BIT:
- cam->cc_ctrl |= CC_CTRL_PAR_MODE_BT8;
- break;
- case V4L2_IF_TYPE_BT656_MODE_BT_10BIT:
- cam->cc_ctrl |= CC_CTRL_PAR_MODE_BT10;
- break;
- default:
- dev_err(cam->dev,
- "bt656 interface mode %d not supported\n",
- p.u.bt656.mode);
- return -EINVAL;
- }
- /*
- * The clock rate that the sensor wants has changed.
- * We have to adjust the xclk from OMAP 2 side to
- * match the sensor's wish as closely as possible.
- */
- if (p.u.bt656.clock_curr != cam->if_u.bt656.xclk) {
- u32 xclk = p.u.bt656.clock_curr;
- u32 divisor;
-
- if (xclk == 0)
- return -EINVAL;
-
- if (xclk > CAM_MCLK)
- xclk = CAM_MCLK;
-
- divisor = CAM_MCLK / xclk;
- if (divisor * xclk < CAM_MCLK)
- divisor++;
- if (CAM_MCLK / divisor < p.u.bt656.clock_min
- && divisor > 1)
- divisor--;
- if (divisor > 30)
- divisor = 30;
-
- xclk = CAM_MCLK / divisor;
-
- if (xclk < p.u.bt656.clock_min
- || xclk > p.u.bt656.clock_max)
- return -EINVAL;
-
- cam->if_u.bt656.xclk = xclk;
- }
- omap24xxcam_core_xclk_set(cam, cam->if_u.bt656.xclk);
- break;
- default:
- /* FIXME: how about other interfaces? */
- dev_err(cam->dev, "interface type %d not supported\n",
- p.if_type);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void omap24xxcam_sensor_if_disable(const struct omap24xxcam_device *cam)
-{
- switch (cam->if_type) {
- case V4L2_IF_TYPE_BT656:
- omap24xxcam_core_xclk_set(cam, 0);
- break;
- }
-}
-
-/*
- * Initialise the sensor hardware.
- */
-static int omap24xxcam_sensor_init(struct omap24xxcam_device *cam)
-{
- int err = 0;
- struct v4l2_int_device *sdev = cam->sdev;
-
- omap24xxcam_clock_on(cam);
- err = omap24xxcam_sensor_if_enable(cam);
- if (err) {
- dev_err(cam->dev, "sensor interface could not be enabled at "
- "initialisation, %d\n", err);
- cam->sdev = NULL;
- goto out;
- }
-
- /* power up sensor during sensor initialization */
- vidioc_int_s_power(sdev, 1);
-
- err = vidioc_int_dev_init(sdev);
- if (err) {
- dev_err(cam->dev, "cannot initialize sensor, error %d\n", err);
- /* Sensor init failed --- it's nonexistent to us! */
- cam->sdev = NULL;
- goto out;
- }
-
- dev_info(cam->dev, "sensor is %s\n", sdev->name);
-
-out:
- omap24xxcam_sensor_if_disable(cam);
- omap24xxcam_clock_off(cam);
-
- vidioc_int_s_power(sdev, 0);
-
- return err;
-}
-
-static void omap24xxcam_sensor_exit(struct omap24xxcam_device *cam)
-{
- if (cam->sdev)
- vidioc_int_dev_exit(cam->sdev);
-}
-
-static void omap24xxcam_sensor_disable(struct omap24xxcam_device *cam)
-{
- omap24xxcam_sensor_if_disable(cam);
- omap24xxcam_clock_off(cam);
- vidioc_int_s_power(cam->sdev, 0);
-}
-
-/*
- * Power-up and configure camera sensor. It's ready for capturing now.
- */
-static int omap24xxcam_sensor_enable(struct omap24xxcam_device *cam)
-{
- int rval;
-
- omap24xxcam_clock_on(cam);
-
- omap24xxcam_sensor_if_enable(cam);
-
- rval = vidioc_int_s_power(cam->sdev, 1);
- if (rval)
- goto out;
-
- rval = vidioc_int_init(cam->sdev);
- if (rval)
- goto out;
-
- return 0;
-
-out:
- omap24xxcam_sensor_disable(cam);
-
- return rval;
-}
-
-static void omap24xxcam_sensor_reset_work(struct work_struct *work)
-{
- struct omap24xxcam_device *cam =
- container_of(work, struct omap24xxcam_device,
- sensor_reset_work);
-
- if (atomic_read(&cam->reset_disable))
- return;
-
- omap24xxcam_capture_stop(cam);
-
- if (vidioc_int_reset(cam->sdev) == 0) {
- vidioc_int_init(cam->sdev);
- } else {
- /* Can't reset it by vidioc_int_reset. */
- omap24xxcam_sensor_disable(cam);
- omap24xxcam_sensor_enable(cam);
- }
-
- omap24xxcam_capture_cont(cam);
-}
-
-/*
- *
- * IOCTL interface.
- *
- */
-
-static int vidioc_querycap(struct file *file, void *fh,
- struct v4l2_capability *cap)
-{
- struct omap24xxcam_fh *ofh = fh;
- struct omap24xxcam_device *cam = ofh->cam;
-
- strlcpy(cap->driver, CAM_NAME, sizeof(cap->driver));
- strlcpy(cap->card, cam->vfd->name, sizeof(cap->card));
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_fmtdesc *f)
-{
- struct omap24xxcam_fh *ofh = fh;
- struct omap24xxcam_device *cam = ofh->cam;
- int rval;
-
- rval = vidioc_int_enum_fmt_cap(cam->sdev, f);
-
- return rval;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct omap24xxcam_fh *ofh = fh;
- struct omap24xxcam_device *cam = ofh->cam;
- int rval;
-
- mutex_lock(&cam->mutex);
- rval = vidioc_int_g_fmt_cap(cam->sdev, f);
- mutex_unlock(&cam->mutex);
-
- return rval;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct omap24xxcam_fh *ofh = fh;
- struct omap24xxcam_device *cam = ofh->cam;
- int rval;
-
- mutex_lock(&cam->mutex);
- if (cam->streaming) {
- rval = -EBUSY;
- goto out;
- }
-
- rval = vidioc_int_s_fmt_cap(cam->sdev, f);
-
-out:
- mutex_unlock(&cam->mutex);
-
- if (!rval) {
- mutex_lock(&ofh->vbq.vb_lock);
- ofh->pix = f->fmt.pix;
- mutex_unlock(&ofh->vbq.vb_lock);
- }
-
- memset(f, 0, sizeof(*f));
- vidioc_g_fmt_vid_cap(file, fh, f);
-
- return rval;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct omap24xxcam_fh *ofh = fh;
- struct omap24xxcam_device *cam = ofh->cam;
- int rval;
-
- mutex_lock(&cam->mutex);
- rval = vidioc_int_try_fmt_cap(cam->sdev, f);
- mutex_unlock(&cam->mutex);
-
- return rval;
-}
-
-static int vidioc_reqbufs(struct file *file, void *fh,
- struct v4l2_requestbuffers *b)
-{
- struct omap24xxcam_fh *ofh = fh;
- struct omap24xxcam_device *cam = ofh->cam;
- int rval;
-
- mutex_lock(&cam->mutex);
- if (cam->streaming) {
- mutex_unlock(&cam->mutex);
- return -EBUSY;
- }
-
- omap24xxcam_vbq_free_mmap_buffers(&ofh->vbq);
- mutex_unlock(&cam->mutex);
-
- rval = videobuf_reqbufs(&ofh->vbq, b);
-
- /*
- * Either videobuf_reqbufs failed or the buffers are not
- * memory-mapped (which would need special attention).
- */
- if (rval < 0 || b->memory != V4L2_MEMORY_MMAP)
- goto out;
-
- rval = omap24xxcam_vbq_alloc_mmap_buffers(&ofh->vbq, rval);
- if (rval)
- omap24xxcam_vbq_free_mmap_buffers(&ofh->vbq);
-
-out:
- return rval;
-}
-
-static int vidioc_querybuf(struct file *file, void *fh,
- struct v4l2_buffer *b)
-{
- struct omap24xxcam_fh *ofh = fh;
-
- return videobuf_querybuf(&ofh->vbq, b);
-}
-
-static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
-{
- struct omap24xxcam_fh *ofh = fh;
-
- return videobuf_qbuf(&ofh->vbq, b);
-}
-
-static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
-{
- struct omap24xxcam_fh *ofh = fh;
- struct omap24xxcam_device *cam = ofh->cam;
- struct videobuf_buffer *vb;
- int rval;
-
-videobuf_dqbuf_again:
- rval = videobuf_dqbuf(&ofh->vbq, b, file->f_flags & O_NONBLOCK);
- if (rval)
- goto out;
-
- vb = ofh->vbq.bufs[b->index];
-
- mutex_lock(&cam->mutex);
- /* _needs_reset returns -EIO if reset is required. */
- rval = vidioc_int_g_needs_reset(cam->sdev, (void *)vb->baddr);
- mutex_unlock(&cam->mutex);
- if (rval == -EIO)
- schedule_work(&cam->sensor_reset_work);
- else
- rval = 0;
-
-out:
- /*
- * This is a hack. We don't want to show -EIO to the user
- * space. Requeue the buffer and try again if we're not doing
- * this in non-blocking mode.
- */
- if (rval == -EIO) {
- videobuf_qbuf(&ofh->vbq, b);
- if (!(file->f_flags & O_NONBLOCK))
- goto videobuf_dqbuf_again;
- /*
- * We don't have a videobuf_buffer now --- maybe next
- * time...
- */
- rval = -EAGAIN;
- }
-
- return rval;
-}
-
-static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
-{
- struct omap24xxcam_fh *ofh = fh;
- struct omap24xxcam_device *cam = ofh->cam;
- int rval;
-
- mutex_lock(&cam->mutex);
- if (cam->streaming) {
- rval = -EBUSY;
- goto out;
- }
-
- rval = omap24xxcam_sensor_if_enable(cam);
- if (rval) {
- dev_dbg(cam->dev, "vidioc_int_g_ifparm failed\n");
- goto out;
- }
-
- rval = videobuf_streamon(&ofh->vbq);
- if (!rval) {
- cam->streaming = file;
- sysfs_notify(&cam->dev->kobj, NULL, "streaming");
- }
-
-out:
- mutex_unlock(&cam->mutex);
-
- return rval;
-}
-
-static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
-{
- struct omap24xxcam_fh *ofh = fh;
- struct omap24xxcam_device *cam = ofh->cam;
- struct videobuf_queue *q = &ofh->vbq;
- int rval;
-
- atomic_inc(&cam->reset_disable);
-
- flush_work(&cam->sensor_reset_work);
-
- rval = videobuf_streamoff(q);
- if (!rval) {
- mutex_lock(&cam->mutex);
- cam->streaming = NULL;
- mutex_unlock(&cam->mutex);
- sysfs_notify(&cam->dev->kobj, NULL, "streaming");
- }
-
- atomic_dec(&cam->reset_disable);
-
- return rval;
-}
-
-static int vidioc_enum_input(struct file *file, void *fh,
- struct v4l2_input *inp)
-{
- if (inp->index > 0)
- return -EINVAL;
-
- strlcpy(inp->name, "camera", sizeof(inp->name));
- inp->type = V4L2_INPUT_TYPE_CAMERA;
-
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
-{
- *i = 0;
-
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *fh, unsigned int i)
-{
- if (i > 0)
- return -EINVAL;
-
- return 0;
-}
-
-static int vidioc_queryctrl(struct file *file, void *fh,
- struct v4l2_queryctrl *a)
-{
- struct omap24xxcam_fh *ofh = fh;
- struct omap24xxcam_device *cam = ofh->cam;
- int rval;
-
- rval = vidioc_int_queryctrl(cam->sdev, a);
-
- return rval;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *fh,
- struct v4l2_control *a)
-{
- struct omap24xxcam_fh *ofh = fh;
- struct omap24xxcam_device *cam = ofh->cam;
- int rval;
-
- mutex_lock(&cam->mutex);
- rval = vidioc_int_g_ctrl(cam->sdev, a);
- mutex_unlock(&cam->mutex);
-
- return rval;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *fh,
- struct v4l2_control *a)
-{
- struct omap24xxcam_fh *ofh = fh;
- struct omap24xxcam_device *cam = ofh->cam;
- int rval;
-
- mutex_lock(&cam->mutex);
- rval = vidioc_int_s_ctrl(cam->sdev, a);
- mutex_unlock(&cam->mutex);
-
- return rval;
-}
-
-static int vidioc_g_parm(struct file *file, void *fh,
- struct v4l2_streamparm *a) {
- struct omap24xxcam_fh *ofh = fh;
- struct omap24xxcam_device *cam = ofh->cam;
- int rval;
-
- mutex_lock(&cam->mutex);
- rval = vidioc_int_g_parm(cam->sdev, a);
- mutex_unlock(&cam->mutex);
-
- return rval;
-}
-
-static int vidioc_s_parm(struct file *file, void *fh,
- struct v4l2_streamparm *a)
-{
- struct omap24xxcam_fh *ofh = fh;
- struct omap24xxcam_device *cam = ofh->cam;
- struct v4l2_streamparm old_streamparm;
- int rval;
-
- mutex_lock(&cam->mutex);
- if (cam->streaming) {
- rval = -EBUSY;
- goto out;
- }
-
- old_streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- rval = vidioc_int_g_parm(cam->sdev, &old_streamparm);
- if (rval)
- goto out;
-
- rval = vidioc_int_s_parm(cam->sdev, a);
- if (rval)
- goto out;
-
- rval = omap24xxcam_sensor_if_enable(cam);
- /*
- * Revert to old streaming parameters if enabling sensor
- * interface with the new ones failed.
- */
- if (rval)
- vidioc_int_s_parm(cam->sdev, &old_streamparm);
-
-out:
- mutex_unlock(&cam->mutex);
-
- return rval;
-}
-
-/*
- *
- * File operations.
- *
- */
-
-static unsigned int omap24xxcam_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct omap24xxcam_fh *fh = file->private_data;
- struct omap24xxcam_device *cam = fh->cam;
- struct videobuf_buffer *vb;
-
- mutex_lock(&cam->mutex);
- if (cam->streaming != file) {
- mutex_unlock(&cam->mutex);
- return POLLERR;
- }
- mutex_unlock(&cam->mutex);
-
- mutex_lock(&fh->vbq.vb_lock);
- if (list_empty(&fh->vbq.stream)) {
- mutex_unlock(&fh->vbq.vb_lock);
- return POLLERR;
- }
- vb = list_entry(fh->vbq.stream.next, struct videobuf_buffer, stream);
- mutex_unlock(&fh->vbq.vb_lock);
-
- poll_wait(file, &vb->done, wait);
-
- if (vb->state == VIDEOBUF_DONE || vb->state == VIDEOBUF_ERROR)
- return POLLIN | POLLRDNORM;
-
- return 0;
-}
-
-static int omap24xxcam_mmap_buffers(struct file *file,
- struct vm_area_struct *vma)
-{
- struct omap24xxcam_fh *fh = file->private_data;
- struct omap24xxcam_device *cam = fh->cam;
- struct videobuf_queue *vbq = &fh->vbq;
- unsigned int first, last, size, i, j;
- int err = 0;
-
- mutex_lock(&cam->mutex);
- if (cam->streaming) {
- mutex_unlock(&cam->mutex);
- return -EBUSY;
- }
- mutex_unlock(&cam->mutex);
- mutex_lock(&vbq->vb_lock);
-
- /* look for first buffer to map */
- for (first = 0; first < VIDEO_MAX_FRAME; first++) {
- if (NULL == vbq->bufs[first])
- continue;
- if (V4L2_MEMORY_MMAP != vbq->bufs[first]->memory)
- continue;
- if (vbq->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT))
- break;
- }
-
- /* look for last buffer to map */
- for (size = 0, last = first; last < VIDEO_MAX_FRAME; last++) {
- if (NULL == vbq->bufs[last])
- continue;
- if (V4L2_MEMORY_MMAP != vbq->bufs[last]->memory)
- continue;
- size += vbq->bufs[last]->bsize;
- if (size == (vma->vm_end - vma->vm_start))
- break;
- }
-
- size = 0;
- for (i = first; i <= last && i < VIDEO_MAX_FRAME; i++) {
- struct videobuf_dmabuf *dma = videobuf_to_dma(vbq->bufs[i]);
-
- for (j = 0; j < dma->sglen; j++) {
- err = remap_pfn_range(
- vma, vma->vm_start + size,
- page_to_pfn(sg_page(&dma->sglist[j])),
- sg_dma_len(&dma->sglist[j]), vma->vm_page_prot);
- if (err)
- goto out;
- size += sg_dma_len(&dma->sglist[j]);
- }
- }
-
-out:
- mutex_unlock(&vbq->vb_lock);
-
- return err;
-}
-
-static int omap24xxcam_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct omap24xxcam_fh *fh = file->private_data;
- int rval;
-
- /* let the video-buf mapper check arguments and set-up structures */
- rval = videobuf_mmap_mapper(&fh->vbq, vma);
- if (rval)
- return rval;
-
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- /* do mapping to our allocated buffers */
- rval = omap24xxcam_mmap_buffers(file, vma);
- /*
- * In case of error, free vma->vm_private_data allocated by
- * videobuf_mmap_mapper.
- */
- if (rval)
- kfree(vma->vm_private_data);
-
- return rval;
-}
-
-static int omap24xxcam_open(struct file *file)
-{
- struct omap24xxcam_device *cam = omap24xxcam.priv;
- struct omap24xxcam_fh *fh;
- struct v4l2_format format;
-
- if (!cam || !cam->vfd)
- return -ENODEV;
-
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (fh == NULL)
- return -ENOMEM;
-
- mutex_lock(&cam->mutex);
- if (cam->sdev == NULL || !try_module_get(cam->sdev->module)) {
- mutex_unlock(&cam->mutex);
- goto out_try_module_get;
- }
-
- if (atomic_inc_return(&cam->users) == 1) {
- omap24xxcam_hwinit(cam);
- if (omap24xxcam_sensor_enable(cam)) {
- mutex_unlock(&cam->mutex);
- goto out_omap24xxcam_sensor_enable;
- }
- }
- mutex_unlock(&cam->mutex);
-
- fh->cam = cam;
- mutex_lock(&cam->mutex);
- vidioc_int_g_fmt_cap(cam->sdev, &format);
- mutex_unlock(&cam->mutex);
- /* FIXME: how about fh->pix when there are more users? */
- fh->pix = format.fmt.pix;
-
- file->private_data = fh;
-
- spin_lock_init(&fh->vbq_lock);
-
- videobuf_queue_sg_init(&fh->vbq, &omap24xxcam_vbq_ops, NULL,
- &fh->vbq_lock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_NONE,
- sizeof(struct videobuf_buffer), fh, NULL);
-
- return 0;
-
-out_omap24xxcam_sensor_enable:
- omap24xxcam_poweron_reset(cam);
- module_put(cam->sdev->module);
-
-out_try_module_get:
- kfree(fh);
-
- return -ENODEV;
-}
-
-static int omap24xxcam_release(struct file *file)
-{
- struct omap24xxcam_fh *fh = file->private_data;
- struct omap24xxcam_device *cam = fh->cam;
-
- atomic_inc(&cam->reset_disable);
-
- flush_work(&cam->sensor_reset_work);
-
- /* stop streaming capture */
- videobuf_streamoff(&fh->vbq);
-
- mutex_lock(&cam->mutex);
- if (cam->streaming == file) {
- cam->streaming = NULL;
- mutex_unlock(&cam->mutex);
- sysfs_notify(&cam->dev->kobj, NULL, "streaming");
- } else {
- mutex_unlock(&cam->mutex);
- }
-
- atomic_dec(&cam->reset_disable);
-
- omap24xxcam_vbq_free_mmap_buffers(&fh->vbq);
-
- /*
- * Make sure the reset work we might have scheduled is not
- * pending! It may be run *only* if we have users. (And it may
- * not be scheduled anymore since streaming is already
- * disabled.)
- */
- flush_work(&cam->sensor_reset_work);
-
- mutex_lock(&cam->mutex);
- if (atomic_dec_return(&cam->users) == 0) {
- omap24xxcam_sensor_disable(cam);
- omap24xxcam_poweron_reset(cam);
- }
- mutex_unlock(&cam->mutex);
-
- file->private_data = NULL;
-
- module_put(cam->sdev->module);
- kfree(fh);
-
- return 0;
-}
-
-static struct v4l2_file_operations omap24xxcam_fops = {
- .ioctl = video_ioctl2,
- .poll = omap24xxcam_poll,
- .mmap = omap24xxcam_mmap,
- .open = omap24xxcam_open,
- .release = omap24xxcam_release,
-};
-
-/*
- *
- * Power management.
- *
- */
-
-#ifdef CONFIG_PM
-static int omap24xxcam_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct omap24xxcam_device *cam = platform_get_drvdata(pdev);
-
- if (atomic_read(&cam->users) == 0)
- return 0;
-
- if (!atomic_read(&cam->reset_disable))
- omap24xxcam_capture_stop(cam);
-
- omap24xxcam_sensor_disable(cam);
- omap24xxcam_poweron_reset(cam);
-
- return 0;
-}
-
-static int omap24xxcam_resume(struct platform_device *pdev)
-{
- struct omap24xxcam_device *cam = platform_get_drvdata(pdev);
-
- if (atomic_read(&cam->users) == 0)
- return 0;
-
- omap24xxcam_hwinit(cam);
- omap24xxcam_sensor_enable(cam);
-
- if (!atomic_read(&cam->reset_disable))
- omap24xxcam_capture_cont(cam);
-
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static const struct v4l2_ioctl_ops omap24xxcam_ioctl_fops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_g_parm = vidioc_g_parm,
- .vidioc_s_parm = vidioc_s_parm,
-};
-
-/*
- *
- * Camera device (i.e. /dev/video).
- *
- */
-
-static int omap24xxcam_device_register(struct v4l2_int_device *s)
-{
- struct omap24xxcam_device *cam = s->u.slave->master->priv;
- struct video_device *vfd;
- int rval;
-
- /* We already have a slave. */
- if (cam->sdev)
- return -EBUSY;
-
- cam->sdev = s;
-
- if (device_create_file(cam->dev, &dev_attr_streaming) != 0) {
- dev_err(cam->dev, "could not register sysfs entry\n");
- rval = -EBUSY;
- goto err;
- }
-
- /* initialize the video_device struct */
- vfd = cam->vfd = video_device_alloc();
- if (!vfd) {
- dev_err(cam->dev, "could not allocate video device struct\n");
- rval = -ENOMEM;
- goto err;
- }
- vfd->release = video_device_release;
-
- vfd->parent = cam->dev;
-
- strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name));
- vfd->fops = &omap24xxcam_fops;
- vfd->ioctl_ops = &omap24xxcam_ioctl_fops;
-
- omap24xxcam_hwinit(cam);
-
- rval = omap24xxcam_sensor_init(cam);
- if (rval)
- goto err;
-
- if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0) {
- dev_err(cam->dev, "could not register V4L device\n");
- rval = -EBUSY;
- goto err;
- }
-
- omap24xxcam_poweron_reset(cam);
-
- dev_info(cam->dev, "registered device %s\n",
- video_device_node_name(vfd));
-
- return 0;
-
-err:
- omap24xxcam_device_unregister(s);
-
- return rval;
-}
-
-static void omap24xxcam_device_unregister(struct v4l2_int_device *s)
-{
- struct omap24xxcam_device *cam = s->u.slave->master->priv;
-
- omap24xxcam_sensor_exit(cam);
-
- if (cam->vfd) {
- if (!video_is_registered(cam->vfd)) {
- /*
- * The device was never registered, so release the
- * video_device struct directly.
- */
- video_device_release(cam->vfd);
- } else {
- /*
- * The unregister function will release the
- * video_device struct as well as
- * unregistering it.
- */
- video_unregister_device(cam->vfd);
- }
- cam->vfd = NULL;
- }
-
- device_remove_file(cam->dev, &dev_attr_streaming);
-
- cam->sdev = NULL;
-}
-
-static struct v4l2_int_master omap24xxcam_master = {
- .attach = omap24xxcam_device_register,
- .detach = omap24xxcam_device_unregister,
-};
-
-static struct v4l2_int_device omap24xxcam = {
- .module = THIS_MODULE,
- .name = CAM_NAME,
- .type = v4l2_int_type_master,
- .u = {
- .master = &omap24xxcam_master
- },
-};
-
-/*
- *
- * Driver initialisation and deinitialisation.
- *
- */
-
-static int __devinit omap24xxcam_probe(struct platform_device *pdev)
-{
- struct omap24xxcam_device *cam;
- struct resource *mem;
- int irq;
-
- cam = kzalloc(sizeof(*cam), GFP_KERNEL);
- if (!cam) {
- dev_err(&pdev->dev, "could not allocate memory\n");
- goto err;
- }
-
- platform_set_drvdata(pdev, cam);
-
- cam->dev = &pdev->dev;
-
- /*
- * Impose a lower limit on the amount of memory allocated for
- * capture. We require at least enough memory to double-buffer
- * QVGA (300KB).
- */
- if (capture_mem < 320 * 240 * 2 * 2)
- capture_mem = 320 * 240 * 2 * 2;
- cam->capture_mem = capture_mem;
-
- /* request the mem region for the camera registers */
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- dev_err(cam->dev, "no mem resource?\n");
- goto err;
- }
- if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) {
- dev_err(cam->dev,
- "cannot reserve camera register I/O region\n");
- goto err;
- }
- cam->mmio_base_phys = mem->start;
- cam->mmio_size = resource_size(mem);
-
- /* map the region */
- cam->mmio_base = ioremap_nocache(cam->mmio_base_phys, cam->mmio_size);
- if (!cam->mmio_base) {
- dev_err(cam->dev, "cannot map camera register I/O region\n");
- goto err;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq <= 0) {
- dev_err(cam->dev, "no irq for camera?\n");
- goto err;
- }
-
- /* install the interrupt service routine */
- if (request_irq(irq, omap24xxcam_isr, 0, CAM_NAME, cam)) {
- dev_err(cam->dev,
- "could not install interrupt service routine\n");
- goto err;
- }
- cam->irq = irq;
-
- if (omap24xxcam_clock_get(cam))
- goto err;
-
- INIT_WORK(&cam->sensor_reset_work, omap24xxcam_sensor_reset_work);
-
- mutex_init(&cam->mutex);
- spin_lock_init(&cam->core_enable_disable_lock);
-
- omap24xxcam_sgdma_init(&cam->sgdma,
- cam->mmio_base + CAMDMA_REG_OFFSET,
- omap24xxcam_stalled_dma_reset,
- (unsigned long)cam);
-
- omap24xxcam.priv = cam;
-
- if (v4l2_int_device_register(&omap24xxcam))
- goto err;
-
- return 0;
-
-err:
- omap24xxcam_remove(pdev);
- return -ENODEV;
-}
-
-static int omap24xxcam_remove(struct platform_device *pdev)
-{
- struct omap24xxcam_device *cam = platform_get_drvdata(pdev);
-
- if (!cam)
- return 0;
-
- if (omap24xxcam.priv != NULL)
- v4l2_int_device_unregister(&omap24xxcam);
- omap24xxcam.priv = NULL;
-
- omap24xxcam_clock_put(cam);
-
- if (cam->irq) {
- free_irq(cam->irq, cam);
- cam->irq = 0;
- }
-
- if (cam->mmio_base) {
- iounmap((void *)cam->mmio_base);
- cam->mmio_base = 0;
- }
-
- if (cam->mmio_base_phys) {
- release_mem_region(cam->mmio_base_phys, cam->mmio_size);
- cam->mmio_base_phys = 0;
- }
-
- kfree(cam);
-
- return 0;
-}
-
-static struct platform_driver omap24xxcam_driver = {
- .probe = omap24xxcam_probe,
- .remove = omap24xxcam_remove,
-#ifdef CONFIG_PM
- .suspend = omap24xxcam_suspend,
- .resume = omap24xxcam_resume,
-#endif
- .driver = {
- .name = CAM_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(omap24xxcam_driver);
-
-MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>");
-MODULE_DESCRIPTION("OMAP24xx Video for Linux camera driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(OMAP24XXCAM_VERSION);
-module_param(video_nr, int, 0);
-MODULE_PARM_DESC(video_nr,
- "Minor number for video device (-1 ==> auto assign)");
-module_param(capture_mem, int, 0);
-MODULE_PARM_DESC(capture_mem, "Maximum amount of memory for capture "
- "buffers (default 4800kiB)");
diff --git a/drivers/media/video/omap24xxcam.h b/drivers/media/video/omap24xxcam.h
deleted file mode 100644
index d59727afe89..00000000000
--- a/drivers/media/video/omap24xxcam.h
+++ /dev/null
@@ -1,593 +0,0 @@
-/*
- * drivers/media/video/omap24xxcam.h
- *
- * Copyright (C) 2004 MontaVista Software, Inc.
- * Copyright (C) 2004 Texas Instruments.
- * Copyright (C) 2007 Nokia Corporation.
- *
- * Contact: Sakari Ailus <sakari.ailus@nokia.com>
- *
- * Based on code from Andy Lowe <source@mvista.com>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef OMAP24XXCAM_H
-#define OMAP24XXCAM_H
-
-#include <media/videobuf-dma-sg.h>
-#include <media/v4l2-int-device.h>
-
-/*
- *
- * General driver related definitions.
- *
- */
-
-#define CAM_NAME "omap24xxcam"
-
-#define CAM_MCLK 96000000
-
-/* number of bytes transferred per DMA request */
-#define DMA_THRESHOLD 32
-
-/*
- * NUM_CAMDMA_CHANNELS is the number of logical channels provided by
- * the camera DMA controller.
- */
-#define NUM_CAMDMA_CHANNELS 4
-
-/*
- * NUM_SG_DMA is the number of scatter-gather DMA transfers that can
- * be queued. (We don't have any overlay sglists now.)
- */
-#define NUM_SG_DMA (VIDEO_MAX_FRAME)
-
-/*
- *
- * Register definitions.
- *
- */
-
-/* subsystem register block offsets */
-#define CC_REG_OFFSET 0x00000400
-#define CAMDMA_REG_OFFSET 0x00000800
-#define CAMMMU_REG_OFFSET 0x00000C00
-
-/* define camera subsystem register offsets */
-#define CAM_REVISION 0x000
-#define CAM_SYSCONFIG 0x010
-#define CAM_SYSSTATUS 0x014
-#define CAM_IRQSTATUS 0x018
-#define CAM_GPO 0x040
-#define CAM_GPI 0x050
-
-/* define camera core register offsets */
-#define CC_REVISION 0x000
-#define CC_SYSCONFIG 0x010
-#define CC_SYSSTATUS 0x014
-#define CC_IRQSTATUS 0x018
-#define CC_IRQENABLE 0x01C
-#define CC_CTRL 0x040
-#define CC_CTRL_DMA 0x044
-#define CC_CTRL_XCLK 0x048
-#define CC_FIFODATA 0x04C
-#define CC_TEST 0x050
-#define CC_GENPAR 0x054
-#define CC_CCPFSCR 0x058
-#define CC_CCPFECR 0x05C
-#define CC_CCPLSCR 0x060
-#define CC_CCPLECR 0x064
-#define CC_CCPDFR 0x068
-
-/* define camera dma register offsets */
-#define CAMDMA_REVISION 0x000
-#define CAMDMA_IRQSTATUS_L0 0x008
-#define CAMDMA_IRQSTATUS_L1 0x00C
-#define CAMDMA_IRQSTATUS_L2 0x010
-#define CAMDMA_IRQSTATUS_L3 0x014
-#define CAMDMA_IRQENABLE_L0 0x018
-#define CAMDMA_IRQENABLE_L1 0x01C
-#define CAMDMA_IRQENABLE_L2 0x020
-#define CAMDMA_IRQENABLE_L3 0x024
-#define CAMDMA_SYSSTATUS 0x028
-#define CAMDMA_OCP_SYSCONFIG 0x02C
-#define CAMDMA_CAPS_0 0x064
-#define CAMDMA_CAPS_2 0x06C
-#define CAMDMA_CAPS_3 0x070
-#define CAMDMA_CAPS_4 0x074
-#define CAMDMA_GCR 0x078
-#define CAMDMA_CCR(n) (0x080 + (n)*0x60)
-#define CAMDMA_CLNK_CTRL(n) (0x084 + (n)*0x60)
-#define CAMDMA_CICR(n) (0x088 + (n)*0x60)
-#define CAMDMA_CSR(n) (0x08C + (n)*0x60)
-#define CAMDMA_CSDP(n) (0x090 + (n)*0x60)
-#define CAMDMA_CEN(n) (0x094 + (n)*0x60)
-#define CAMDMA_CFN(n) (0x098 + (n)*0x60)
-#define CAMDMA_CSSA(n) (0x09C + (n)*0x60)
-#define CAMDMA_CDSA(n) (0x0A0 + (n)*0x60)
-#define CAMDMA_CSEI(n) (0x0A4 + (n)*0x60)
-#define CAMDMA_CSFI(n) (0x0A8 + (n)*0x60)
-#define CAMDMA_CDEI(n) (0x0AC + (n)*0x60)
-#define CAMDMA_CDFI(n) (0x0B0 + (n)*0x60)
-#define CAMDMA_CSAC(n) (0x0B4 + (n)*0x60)
-#define CAMDMA_CDAC(n) (0x0B8 + (n)*0x60)
-#define CAMDMA_CCEN(n) (0x0BC + (n)*0x60)
-#define CAMDMA_CCFN(n) (0x0C0 + (n)*0x60)
-#define CAMDMA_COLOR(n) (0x0C4 + (n)*0x60)
-
-/* define camera mmu register offsets */
-#define CAMMMU_REVISION 0x000
-#define CAMMMU_SYSCONFIG 0x010
-#define CAMMMU_SYSSTATUS 0x014
-#define CAMMMU_IRQSTATUS 0x018
-#define CAMMMU_IRQENABLE 0x01C
-#define CAMMMU_WALKING_ST 0x040
-#define CAMMMU_CNTL 0x044
-#define CAMMMU_FAULT_AD 0x048
-#define CAMMMU_TTB 0x04C
-#define CAMMMU_LOCK 0x050
-#define CAMMMU_LD_TLB 0x054
-#define CAMMMU_CAM 0x058
-#define CAMMMU_RAM 0x05C
-#define CAMMMU_GFLUSH 0x060
-#define CAMMMU_FLUSH_ENTRY 0x064
-#define CAMMMU_READ_CAM 0x068
-#define CAMMMU_READ_RAM 0x06C
-#define CAMMMU_EMU_FAULT_AD 0x070
-
-/* Define bit fields within selected registers */
-#define CAM_REVISION_MAJOR (15 << 4)
-#define CAM_REVISION_MAJOR_SHIFT 4
-#define CAM_REVISION_MINOR (15 << 0)
-#define CAM_REVISION_MINOR_SHIFT 0
-
-#define CAM_SYSCONFIG_SOFTRESET (1 << 1)
-#define CAM_SYSCONFIG_AUTOIDLE (1 << 0)
-
-#define CAM_SYSSTATUS_RESETDONE (1 << 0)
-
-#define CAM_IRQSTATUS_CC_IRQ (1 << 4)
-#define CAM_IRQSTATUS_MMU_IRQ (1 << 3)
-#define CAM_IRQSTATUS_DMA_IRQ2 (1 << 2)
-#define CAM_IRQSTATUS_DMA_IRQ1 (1 << 1)
-#define CAM_IRQSTATUS_DMA_IRQ0 (1 << 0)
-
-#define CAM_GPO_CAM_S_P_EN (1 << 1)
-#define CAM_GPO_CAM_CCP_MODE (1 << 0)
-
-#define CAM_GPI_CC_DMA_REQ1 (1 << 24)
-#define CAP_GPI_CC_DMA_REQ0 (1 << 23)
-#define CAP_GPI_CAM_MSTANDBY (1 << 21)
-#define CAP_GPI_CAM_WAIT (1 << 20)
-#define CAP_GPI_CAM_S_DATA (1 << 17)
-#define CAP_GPI_CAM_S_CLK (1 << 16)
-#define CAP_GPI_CAM_P_DATA (0xFFF << 3)
-#define CAP_GPI_CAM_P_DATA_SHIFT 3
-#define CAP_GPI_CAM_P_VS (1 << 2)
-#define CAP_GPI_CAM_P_HS (1 << 1)
-#define CAP_GPI_CAM_P_CLK (1 << 0)
-
-#define CC_REVISION_MAJOR (15 << 4)
-#define CC_REVISION_MAJOR_SHIFT 4
-#define CC_REVISION_MINOR (15 << 0)
-#define CC_REVISION_MINOR_SHIFT 0
-
-#define CC_SYSCONFIG_SIDLEMODE (3 << 3)
-#define CC_SYSCONFIG_SIDLEMODE_FIDLE (0 << 3)
-#define CC_SYSCONFIG_SIDLEMODE_NIDLE (1 << 3)
-#define CC_SYSCONFIG_SOFTRESET (1 << 1)
-#define CC_SYSCONFIG_AUTOIDLE (1 << 0)
-
-#define CC_SYSSTATUS_RESETDONE (1 << 0)
-
-#define CC_IRQSTATUS_FS_IRQ (1 << 19)
-#define CC_IRQSTATUS_LE_IRQ (1 << 18)
-#define CC_IRQSTATUS_LS_IRQ (1 << 17)
-#define CC_IRQSTATUS_FE_IRQ (1 << 16)
-#define CC_IRQSTATUS_FW_ERR_IRQ (1 << 10)
-#define CC_IRQSTATUS_FSC_ERR_IRQ (1 << 9)
-#define CC_IRQSTATUS_SSC_ERR_IRQ (1 << 8)
-#define CC_IRQSTATUS_FIFO_NOEMPTY_IRQ (1 << 4)
-#define CC_IRQSTATUS_FIFO_FULL_IRQ (1 << 3)
-#define CC_IRQSTATUS_FIFO_THR_IRQ (1 << 2)
-#define CC_IRQSTATUS_FIFO_OF_IRQ (1 << 1)
-#define CC_IRQSTATUS_FIFO_UF_IRQ (1 << 0)
-
-#define CC_IRQENABLE_FS_IRQ (1 << 19)
-#define CC_IRQENABLE_LE_IRQ (1 << 18)
-#define CC_IRQENABLE_LS_IRQ (1 << 17)
-#define CC_IRQENABLE_FE_IRQ (1 << 16)
-#define CC_IRQENABLE_FW_ERR_IRQ (1 << 10)
-#define CC_IRQENABLE_FSC_ERR_IRQ (1 << 9)
-#define CC_IRQENABLE_SSC_ERR_IRQ (1 << 8)
-#define CC_IRQENABLE_FIFO_NOEMPTY_IRQ (1 << 4)
-#define CC_IRQENABLE_FIFO_FULL_IRQ (1 << 3)
-#define CC_IRQENABLE_FIFO_THR_IRQ (1 << 2)
-#define CC_IRQENABLE_FIFO_OF_IRQ (1 << 1)
-#define CC_IRQENABLE_FIFO_UF_IRQ (1 << 0)
-
-#define CC_CTRL_CC_ONE_SHOT (1 << 20)
-#define CC_CTRL_CC_IF_SYNCHRO (1 << 19)
-#define CC_CTRL_CC_RST (1 << 18)
-#define CC_CTRL_CC_FRAME_TRIG (1 << 17)
-#define CC_CTRL_CC_EN (1 << 16)
-#define CC_CTRL_NOBT_SYNCHRO (1 << 13)
-#define CC_CTRL_BT_CORRECT (1 << 12)
-#define CC_CTRL_PAR_ORDERCAM (1 << 11)
-#define CC_CTRL_PAR_CLK_POL (1 << 10)
-#define CC_CTRL_NOBT_HS_POL (1 << 9)
-#define CC_CTRL_NOBT_VS_POL (1 << 8)
-#define CC_CTRL_PAR_MODE (7 << 1)
-#define CC_CTRL_PAR_MODE_SHIFT 1
-#define CC_CTRL_PAR_MODE_NOBT8 (0 << 1)
-#define CC_CTRL_PAR_MODE_NOBT10 (1 << 1)
-#define CC_CTRL_PAR_MODE_NOBT12 (2 << 1)
-#define CC_CTRL_PAR_MODE_BT8 (4 << 1)
-#define CC_CTRL_PAR_MODE_BT10 (5 << 1)
-#define CC_CTRL_PAR_MODE_FIFOTEST (7 << 1)
-#define CC_CTRL_CCP_MODE (1 << 0)
-
-#define CC_CTRL_DMA_EN (1 << 8)
-#define CC_CTRL_DMA_FIFO_THRESHOLD (0x7F << 0)
-#define CC_CTRL_DMA_FIFO_THRESHOLD_SHIFT 0
-
-#define CC_CTRL_XCLK_DIV (0x1F << 0)
-#define CC_CTRL_XCLK_DIV_SHIFT 0
-#define CC_CTRL_XCLK_DIV_STABLE_LOW (0 << 0)
-#define CC_CTRL_XCLK_DIV_STABLE_HIGH (1 << 0)
-#define CC_CTRL_XCLK_DIV_BYPASS (31 << 0)
-
-#define CC_TEST_FIFO_RD_POINTER (0xFF << 24)
-#define CC_TEST_FIFO_RD_POINTER_SHIFT 24
-#define CC_TEST_FIFO_WR_POINTER (0xFF << 16)
-#define CC_TEST_FIFO_WR_POINTER_SHIFT 16
-#define CC_TEST_FIFO_LEVEL (0xFF << 8)
-#define CC_TEST_FIFO_LEVEL_SHIFT 8
-#define CC_TEST_FIFO_LEVEL_PEAK (0xFF << 0)
-#define CC_TEST_FIFO_LEVEL_PEAK_SHIFT 0
-
-#define CC_GENPAR_FIFO_DEPTH (7 << 0)
-#define CC_GENPAR_FIFO_DEPTH_SHIFT 0
-
-#define CC_CCPDFR_ALPHA (0xFF << 8)
-#define CC_CCPDFR_ALPHA_SHIFT 8
-#define CC_CCPDFR_DATAFORMAT (15 << 0)
-#define CC_CCPDFR_DATAFORMAT_SHIFT 0
-#define CC_CCPDFR_DATAFORMAT_YUV422BE (0 << 0)
-#define CC_CCPDFR_DATAFORMAT_YUV422 (1 << 0)
-#define CC_CCPDFR_DATAFORMAT_YUV420 (2 << 0)
-#define CC_CCPDFR_DATAFORMAT_RGB444 (4 << 0)
-#define CC_CCPDFR_DATAFORMAT_RGB565 (5 << 0)
-#define CC_CCPDFR_DATAFORMAT_RGB888NDE (6 << 0)
-#define CC_CCPDFR_DATAFORMAT_RGB888 (7 << 0)
-#define CC_CCPDFR_DATAFORMAT_RAW8NDE (8 << 0)
-#define CC_CCPDFR_DATAFORMAT_RAW8 (9 << 0)
-#define CC_CCPDFR_DATAFORMAT_RAW10NDE (10 << 0)
-#define CC_CCPDFR_DATAFORMAT_RAW10 (11 << 0)
-#define CC_CCPDFR_DATAFORMAT_RAW12NDE (12 << 0)
-#define CC_CCPDFR_DATAFORMAT_RAW12 (13 << 0)
-#define CC_CCPDFR_DATAFORMAT_JPEG8 (15 << 0)
-
-#define CAMDMA_REVISION_MAJOR (15 << 4)
-#define CAMDMA_REVISION_MAJOR_SHIFT 4
-#define CAMDMA_REVISION_MINOR (15 << 0)
-#define CAMDMA_REVISION_MINOR_SHIFT 0
-
-#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE (3 << 12)
-#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY (0 << 12)
-#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_NSTANDBY (1 << 12)
-#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_SSTANDBY (2 << 12)
-#define CAMDMA_OCP_SYSCONFIG_FUNC_CLOCK (1 << 9)
-#define CAMDMA_OCP_SYSCONFIG_OCP_CLOCK (1 << 8)
-#define CAMDMA_OCP_SYSCONFIG_EMUFREE (1 << 5)
-#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE (3 << 3)
-#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_FIDLE (0 << 3)
-#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_NIDLE (1 << 3)
-#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_SIDLE (2 << 3)
-#define CAMDMA_OCP_SYSCONFIG_SOFTRESET (1 << 1)
-#define CAMDMA_OCP_SYSCONFIG_AUTOIDLE (1 << 0)
-
-#define CAMDMA_SYSSTATUS_RESETDONE (1 << 0)
-
-#define CAMDMA_GCR_ARBITRATION_RATE (0xFF << 16)
-#define CAMDMA_GCR_ARBITRATION_RATE_SHIFT 16
-#define CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH (0xFF << 0)
-#define CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH_SHIFT 0
-
-#define CAMDMA_CCR_SEL_SRC_DST_SYNC (1 << 24)
-#define CAMDMA_CCR_PREFETCH (1 << 23)
-#define CAMDMA_CCR_SUPERVISOR (1 << 22)
-#define CAMDMA_CCR_SECURE (1 << 21)
-#define CAMDMA_CCR_BS (1 << 18)
-#define CAMDMA_CCR_TRANSPARENT_COPY_ENABLE (1 << 17)
-#define CAMDMA_CCR_CONSTANT_FILL_ENABLE (1 << 16)
-#define CAMDMA_CCR_DST_AMODE (3 << 14)
-#define CAMDMA_CCR_DST_AMODE_CONST_ADDR (0 << 14)
-#define CAMDMA_CCR_DST_AMODE_POST_INC (1 << 14)
-#define CAMDMA_CCR_DST_AMODE_SGL_IDX (2 << 14)
-#define CAMDMA_CCR_DST_AMODE_DBL_IDX (3 << 14)
-#define CAMDMA_CCR_SRC_AMODE (3 << 12)
-#define CAMDMA_CCR_SRC_AMODE_CONST_ADDR (0 << 12)
-#define CAMDMA_CCR_SRC_AMODE_POST_INC (1 << 12)
-#define CAMDMA_CCR_SRC_AMODE_SGL_IDX (2 << 12)
-#define CAMDMA_CCR_SRC_AMODE_DBL_IDX (3 << 12)
-#define CAMDMA_CCR_WR_ACTIVE (1 << 10)
-#define CAMDMA_CCR_RD_ACTIVE (1 << 9)
-#define CAMDMA_CCR_SUSPEND_SENSITIVE (1 << 8)
-#define CAMDMA_CCR_ENABLE (1 << 7)
-#define CAMDMA_CCR_PRIO (1 << 6)
-#define CAMDMA_CCR_FS (1 << 5)
-#define CAMDMA_CCR_SYNCHRO ((3 << 19) | (31 << 0))
-#define CAMDMA_CCR_SYNCHRO_CAMERA 0x01
-
-#define CAMDMA_CLNK_CTRL_ENABLE_LNK (1 << 15)
-#define CAMDMA_CLNK_CTRL_NEXTLCH_ID (0x1F << 0)
-#define CAMDMA_CLNK_CTRL_NEXTLCH_ID_SHIFT 0
-
-#define CAMDMA_CICR_MISALIGNED_ERR_IE (1 << 11)
-#define CAMDMA_CICR_SUPERVISOR_ERR_IE (1 << 10)
-#define CAMDMA_CICR_SECURE_ERR_IE (1 << 9)
-#define CAMDMA_CICR_TRANS_ERR_IE (1 << 8)
-#define CAMDMA_CICR_PACKET_IE (1 << 7)
-#define CAMDMA_CICR_BLOCK_IE (1 << 5)
-#define CAMDMA_CICR_LAST_IE (1 << 4)
-#define CAMDMA_CICR_FRAME_IE (1 << 3)
-#define CAMDMA_CICR_HALF_IE (1 << 2)
-#define CAMDMA_CICR_DROP_IE (1 << 1)
-
-#define CAMDMA_CSR_MISALIGNED_ERR (1 << 11)
-#define CAMDMA_CSR_SUPERVISOR_ERR (1 << 10)
-#define CAMDMA_CSR_SECURE_ERR (1 << 9)
-#define CAMDMA_CSR_TRANS_ERR (1 << 8)
-#define CAMDMA_CSR_PACKET (1 << 7)
-#define CAMDMA_CSR_SYNC (1 << 6)
-#define CAMDMA_CSR_BLOCK (1 << 5)
-#define CAMDMA_CSR_LAST (1 << 4)
-#define CAMDMA_CSR_FRAME (1 << 3)
-#define CAMDMA_CSR_HALF (1 << 2)
-#define CAMDMA_CSR_DROP (1 << 1)
-
-#define CAMDMA_CSDP_SRC_ENDIANNESS (1 << 21)
-#define CAMDMA_CSDP_SRC_ENDIANNESS_LOCK (1 << 20)
-#define CAMDMA_CSDP_DST_ENDIANNESS (1 << 19)
-#define CAMDMA_CSDP_DST_ENDIANNESS_LOCK (1 << 18)
-#define CAMDMA_CSDP_WRITE_MODE (3 << 16)
-#define CAMDMA_CSDP_WRITE_MODE_WRNP (0 << 16)
-#define CAMDMA_CSDP_WRITE_MODE_POSTED (1 << 16)
-#define CAMDMA_CSDP_WRITE_MODE_POSTED_LAST_WRNP (2 << 16)
-#define CAMDMA_CSDP_DST_BURST_EN (3 << 14)
-#define CAMDMA_CSDP_DST_BURST_EN_1 (0 << 14)
-#define CAMDMA_CSDP_DST_BURST_EN_16 (1 << 14)
-#define CAMDMA_CSDP_DST_BURST_EN_32 (2 << 14)
-#define CAMDMA_CSDP_DST_BURST_EN_64 (3 << 14)
-#define CAMDMA_CSDP_DST_PACKED (1 << 13)
-#define CAMDMA_CSDP_WR_ADD_TRSLT (15 << 9)
-#define CAMDMA_CSDP_WR_ADD_TRSLT_ENABLE_MREQADD (3 << 9)
-#define CAMDMA_CSDP_SRC_BURST_EN (3 << 7)
-#define CAMDMA_CSDP_SRC_BURST_EN_1 (0 << 7)
-#define CAMDMA_CSDP_SRC_BURST_EN_16 (1 << 7)
-#define CAMDMA_CSDP_SRC_BURST_EN_32 (2 << 7)
-#define CAMDMA_CSDP_SRC_BURST_EN_64 (3 << 7)
-#define CAMDMA_CSDP_SRC_PACKED (1 << 6)
-#define CAMDMA_CSDP_RD_ADD_TRSLT (15 << 2)
-#define CAMDMA_CSDP_RD_ADD_TRSLT_ENABLE_MREQADD (3 << 2)
-#define CAMDMA_CSDP_DATA_TYPE (3 << 0)
-#define CAMDMA_CSDP_DATA_TYPE_8BITS (0 << 0)
-#define CAMDMA_CSDP_DATA_TYPE_16BITS (1 << 0)
-#define CAMDMA_CSDP_DATA_TYPE_32BITS (2 << 0)
-
-#define CAMMMU_SYSCONFIG_AUTOIDLE (1 << 0)
-
-/*
- *
- * Declarations.
- *
- */
-
-/* forward declarations */
-struct omap24xxcam_sgdma;
-struct omap24xxcam_dma;
-
-typedef void (*sgdma_callback_t)(struct omap24xxcam_sgdma *cam,
- u32 status, void *arg);
-typedef void (*dma_callback_t)(struct omap24xxcam_dma *cam,
- u32 status, void *arg);
-
-struct channel_state {
- dma_callback_t callback;
- void *arg;
-};
-
-/* sgdma state for each of the possible videobuf_buffers + 2 overlays */
-struct sgdma_state {
- const struct scatterlist *sglist;
- int sglen; /* number of sglist entries */
- int next_sglist; /* index of next sglist entry to process */
- unsigned int bytes_read; /* number of bytes read */
- unsigned int len; /* total length of sglist (excluding
- * bytes due to page alignment) */
- int queued_sglist; /* number of sglist entries queued for DMA */
- u32 csr; /* DMA return code */
- sgdma_callback_t callback;
- void *arg;
-};
-
-/* physical DMA channel management */
-struct omap24xxcam_dma {
- spinlock_t lock; /* Lock for the whole structure. */
-
- void __iomem *base; /* base address for dma controller */
-
- /* While dma_stop!=0, an attempt to start a new DMA transfer will
- * fail.
- */
- atomic_t dma_stop;
- int free_dmach; /* number of dma channels free */
- int next_dmach; /* index of next dma channel to use */
- struct channel_state ch_state[NUM_CAMDMA_CHANNELS];
-};
-
-/* scatter-gather DMA (scatterlist stuff) management */
-struct omap24xxcam_sgdma {
- struct omap24xxcam_dma dma;
-
- spinlock_t lock; /* Lock for the fields below. */
- int free_sgdma; /* number of free sg dma slots */
- int next_sgdma; /* index of next sg dma slot to use */
- struct sgdma_state sg_state[NUM_SG_DMA];
-
- /* Reset timer data */
- struct timer_list reset_timer;
-};
-
-/* per-device data structure */
-struct omap24xxcam_device {
- /*** mutex ***/
- /*
- * mutex serialises access to this structure. Also camera
- * opening and releasing is synchronised by this.
- */
- struct mutex mutex;
-
- /*** general driver state information ***/
- atomic_t users;
- /*
- * Lock to serialise core enabling and disabling and access to
- * sgdma_in_queue.
- */
- spinlock_t core_enable_disable_lock;
- /*
- * Number or sgdma requests in scatter-gather queue, protected
- * by the lock above.
- */
- int sgdma_in_queue;
- /*
- * Sensor interface parameters: interface type, CC_CTRL
- * register value and interface specific data.
- */
- int if_type;
- union {
- struct parallel {
- u32 xclk;
- } bt656;
- } if_u;
- u32 cc_ctrl;
-
- /*** subsystem structures ***/
- struct omap24xxcam_sgdma sgdma;
-
- /*** hardware resources ***/
- unsigned int irq;
- void __iomem *mmio_base;
- unsigned long mmio_base_phys;
- unsigned long mmio_size;
-
- /*** interfaces and device ***/
- struct v4l2_int_device *sdev;
- struct device *dev;
- struct video_device *vfd;
-
- /*** camera and sensor reset related stuff ***/
- struct work_struct sensor_reset_work;
- /*
- * We're in the middle of a reset. Don't enable core if this
- * is non-zero! This exists to help decisionmaking in a case
- * where videobuf_qbuf is called while we are in the middle of
- * a reset.
- */
- atomic_t in_reset;
- /*
- * Non-zero if we don't want any resets for now. Used to
- * prevent reset work to run when we're about to stop
- * streaming.
- */
- atomic_t reset_disable;
-
- /*** video device parameters ***/
- int capture_mem;
-
- /*** camera module clocks ***/
- struct clk *fck;
- struct clk *ick;
-
- /*** capture data ***/
- /* file handle, if streaming is on */
- struct file *streaming;
-};
-
-/* Per-file handle data. */
-struct omap24xxcam_fh {
- spinlock_t vbq_lock; /* spinlock for the videobuf queue */
- struct videobuf_queue vbq;
- struct v4l2_pix_format pix; /* serialise pix by vbq->lock */
- atomic_t field_count; /* field counter for videobuf_buffer */
- /* accessing cam here doesn't need serialisation: it's constant */
- struct omap24xxcam_device *cam;
-};
-
-/*
- *
- * Register I/O functions.
- *
- */
-
-static inline u32 omap24xxcam_reg_in(u32 __iomem *base, u32 offset)
-{
- return readl(base + offset);
-}
-
-static inline u32 omap24xxcam_reg_out(u32 __iomem *base, u32 offset,
- u32 val)
-{
- writel(val, base + offset);
- return val;
-}
-
-static inline u32 omap24xxcam_reg_merge(u32 __iomem *base, u32 offset,
- u32 val, u32 mask)
-{
- u32 __iomem *addr = base + offset;
- u32 new_val = (readl(addr) & ~mask) | (val & mask);
-
- writel(new_val, addr);
- return new_val;
-}
-
-/*
- *
- * Function prototypes.
- *
- */
-
-/* dma prototypes */
-
-void omap24xxcam_dma_hwinit(struct omap24xxcam_dma *dma);
-void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma);
-
-/* sgdma prototypes */
-
-void omap24xxcam_sgdma_process(struct omap24xxcam_sgdma *sgdma);
-int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma,
- const struct scatterlist *sglist, int sglen,
- int len, sgdma_callback_t callback, void *arg);
-void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma);
-void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma,
- void __iomem *base,
- void (*reset_callback)(unsigned long data),
- unsigned long reset_callback_data);
-void omap24xxcam_sgdma_exit(struct omap24xxcam_sgdma *sgdma);
-
-#endif
diff --git a/drivers/media/video/omap3isp/Makefile b/drivers/media/video/omap3isp/Makefile
deleted file mode 100644
index e8847e79e31..00000000000
--- a/drivers/media/video/omap3isp/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# Makefile for OMAP3 ISP driver
-
-ccflags-$(CONFIG_VIDEO_OMAP3_DEBUG) += -DDEBUG
-
-omap3-isp-objs += \
- isp.o ispqueue.o ispvideo.o \
- ispcsiphy.o ispccp2.o ispcsi2.o \
- ispccdc.o isppreview.o ispresizer.o \
- ispstat.o isph3a_aewb.o isph3a_af.o isphist.o
-
-obj-$(CONFIG_VIDEO_OMAP3) += omap3-isp.o
diff --git a/drivers/media/video/omap3isp/cfa_coef_table.h b/drivers/media/video/omap3isp/cfa_coef_table.h
deleted file mode 100644
index c60df0ed075..00000000000
--- a/drivers/media/video/omap3isp/cfa_coef_table.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * cfa_coef_table.h
- *
- * TI OMAP3 ISP - CFA coefficients table
- *
- * Copyright (C) 2009-2010 Nokia Corporation
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
-248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
-247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
-244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
-248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
-247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
-244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
-248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
-247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
- 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
- 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
- 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
- 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
- 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
- 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
- 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
- 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
- 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
- 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
- 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
- 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
- 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
- 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
- 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
- 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
- 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
- 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
-244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
-248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
-250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248,
-244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
-248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
-250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248,
-244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
-248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
-250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248
diff --git a/drivers/media/video/omap3isp/gamma_table.h b/drivers/media/video/omap3isp/gamma_table.h
deleted file mode 100644
index 78deebf7d96..00000000000
--- a/drivers/media/video/omap3isp/gamma_table.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * gamma_table.h
- *
- * TI OMAP3 ISP - Default gamma table for all components
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
- 0, 0, 1, 2, 3, 3, 4, 5, 6, 8, 10, 12, 14, 16, 18, 20,
- 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 36, 37, 39, 40, 41, 42,
- 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 62, 63, 63, 64, 65, 66, 66, 67, 68, 69, 69, 70,
- 71, 72, 72, 73, 74, 75, 75, 76, 77, 78, 78, 79, 80, 81, 81, 82,
- 83, 84, 84, 85, 86, 87, 88, 88, 89, 90, 91, 91, 92, 93, 94, 94,
- 95, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 103, 104, 104,
-105, 106, 107, 108, 108, 109, 110, 111, 111, 112, 113, 114, 114, 115, 116, 117,
-117, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125,
-126, 126, 127, 127, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133,
-134, 134, 135, 135, 136, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141,
-142, 142, 143, 143, 144, 144, 145, 145, 146, 146, 147, 147, 148, 148, 149, 149,
-150, 150, 151, 151, 152, 152, 153, 153, 153, 153, 154, 154, 154, 154, 155, 155,
-156, 156, 157, 157, 158, 158, 158, 159, 159, 159, 160, 160, 160, 161, 161, 162,
-162, 163, 163, 164, 164, 164, 164, 165, 165, 165, 165, 166, 166, 167, 167, 168,
-168, 169, 169, 170, 170, 170, 170, 171, 171, 171, 171, 172, 172, 173, 173, 174,
-174, 175, 175, 176, 176, 176, 176, 177, 177, 177, 177, 178, 178, 178, 178, 179,
-179, 179, 179, 180, 180, 180, 180, 181, 181, 181, 181, 182, 182, 182, 182, 183,
-183, 183, 183, 184, 184, 184, 184, 185, 185, 185, 185, 186, 186, 186, 186, 187,
-187, 187, 187, 188, 188, 188, 188, 189, 189, 189, 189, 190, 190, 190, 190, 191,
-191, 191, 191, 192, 192, 192, 192, 193, 193, 193, 193, 194, 194, 194, 194, 195,
-195, 195, 195, 196, 196, 196, 196, 197, 197, 197, 197, 198, 198, 198, 198, 199,
-199, 199, 199, 200, 200, 200, 200, 201, 201, 201, 201, 202, 202, 202, 203, 203,
-203, 203, 204, 204, 204, 204, 205, 205, 205, 205, 206, 206, 206, 206, 207, 207,
-207, 207, 208, 208, 208, 208, 209, 209, 209, 209, 210, 210, 210, 210, 210, 210,
-210, 210, 210, 210, 210, 210, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
-211, 212, 212, 212, 212, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213,
-213, 214, 214, 214, 214, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
-216, 216, 216, 216, 217, 217, 217, 217, 218, 218, 218, 218, 219, 219, 219, 219,
-219, 219, 219, 219, 219, 219, 219, 219, 220, 220, 220, 220, 221, 221, 221, 221,
-221, 221, 221, 221, 221, 221, 221, 222, 222, 222, 222, 223, 223, 223, 223, 223,
-223, 223, 223, 223, 223, 223, 223, 224, 224, 224, 224, 225, 225, 225, 225, 225,
-225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 226, 226,
-226, 226, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 228, 228,
-228, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 230, 230, 230,
-230, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 232, 232, 232,
-232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
-233, 233, 233, 233, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 235,
-235, 235, 235, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236,
-236, 236, 236, 236, 236, 236, 237, 237, 237, 237, 238, 238, 238, 238, 238, 238,
-238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
-238, 238, 238, 238, 238, 239, 239, 239, 239, 240, 240, 240, 240, 240, 240, 240,
-240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
-240, 240, 240, 240, 241, 241, 241, 241, 242, 242, 242, 242, 242, 242, 242, 242,
-242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242,
-242, 242, 243, 243, 243, 243, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244,
-244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244,
-244, 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
-246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
-246, 246, 246, 246, 246, 246, 246, 247, 247, 247, 247, 248, 248, 248, 248, 248,
-248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
-248, 248, 248, 248, 248, 248, 249, 249, 249, 249, 250, 250, 250, 250, 250, 250,
-250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
-250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
-250, 250, 250, 250, 251, 251, 251, 251, 252, 252, 252, 252, 252, 252, 252, 252,
-252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
-252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
-252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
-252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 253, 253,
-253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
-253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
-253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
-253, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c
deleted file mode 100644
index 43e61fe5df5..00000000000
--- a/drivers/media/video/omap3isp/isp.c
+++ /dev/null
@@ -1,2232 +0,0 @@
-/*
- * isp.c
- *
- * TI OMAP3 ISP - Core
- *
- * Copyright (C) 2006-2010 Nokia Corporation
- * Copyright (C) 2007-2009 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * Contributors:
- * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- * David Cohen <dacohen@gmail.com>
- * Stanimir Varbanov <svarbanov@mm-sol.com>
- * Vimarsh Zutshi <vimarsh.zutshi@gmail.com>
- * Tuukka Toivonen <tuukkat76@gmail.com>
- * Sergio Aguirre <saaguirre@ti.com>
- * Antti Koskipaa <akoskipa@gmail.com>
- * Ivan T. Ivanov <iivanov@mm-sol.com>
- * RaniSuneela <r-m@ti.com>
- * Atanas Filipov <afilipov@mm-sol.com>
- * Gjorgji Rosikopulos <grosikopulos@mm-sol.com>
- * Hiroshi DOYU <hiroshi.doyu@nokia.com>
- * Nayden Kanchev <nkanchev@mm-sol.com>
- * Phil Carmody <ext-phil.2.carmody@nokia.com>
- * Artem Bityutskiy <artem.bityutskiy@nokia.com>
- * Dominic Curran <dcurran@ti.com>
- * Ilkka Myllyperkio <ilkka.myllyperkio@sofica.fi>
- * Pallavi Kulkarni <p-kulkarni@ti.com>
- * Vaibhav Hiremath <hvaibhav@ti.com>
- * Mohit Jalori <mjalori@ti.com>
- * Sameer Venkatraman <sameerv@ti.com>
- * Senthilvadivu Guruswamy <svadivu@ti.com>
- * Thara Gopinath <thara@ti.com>
- * Toni Leinonen <toni.leinonen@nokia.com>
- * Troy Laramy <t-laramy@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <asm/cacheflush.h>
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/vmalloc.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-
-#include <plat/cpu.h>
-
-#include "isp.h"
-#include "ispreg.h"
-#include "ispccdc.h"
-#include "isppreview.h"
-#include "ispresizer.h"
-#include "ispcsi2.h"
-#include "ispccp2.h"
-#include "isph3a.h"
-#include "isphist.h"
-
-static unsigned int autoidle;
-module_param(autoidle, int, 0444);
-MODULE_PARM_DESC(autoidle, "Enable OMAP3ISP AUTOIDLE support");
-
-static void isp_save_ctx(struct isp_device *isp);
-
-static void isp_restore_ctx(struct isp_device *isp);
-
-static const struct isp_res_mapping isp_res_maps[] = {
- {
- .isp_rev = ISP_REVISION_2_0,
- .map = 1 << OMAP3_ISP_IOMEM_MAIN |
- 1 << OMAP3_ISP_IOMEM_CCP2 |
- 1 << OMAP3_ISP_IOMEM_CCDC |
- 1 << OMAP3_ISP_IOMEM_HIST |
- 1 << OMAP3_ISP_IOMEM_H3A |
- 1 << OMAP3_ISP_IOMEM_PREV |
- 1 << OMAP3_ISP_IOMEM_RESZ |
- 1 << OMAP3_ISP_IOMEM_SBL |
- 1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 |
- 1 << OMAP3_ISP_IOMEM_CSIPHY2,
- },
- {
- .isp_rev = ISP_REVISION_15_0,
- .map = 1 << OMAP3_ISP_IOMEM_MAIN |
- 1 << OMAP3_ISP_IOMEM_CCP2 |
- 1 << OMAP3_ISP_IOMEM_CCDC |
- 1 << OMAP3_ISP_IOMEM_HIST |
- 1 << OMAP3_ISP_IOMEM_H3A |
- 1 << OMAP3_ISP_IOMEM_PREV |
- 1 << OMAP3_ISP_IOMEM_RESZ |
- 1 << OMAP3_ISP_IOMEM_SBL |
- 1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 |
- 1 << OMAP3_ISP_IOMEM_CSIPHY2 |
- 1 << OMAP3_ISP_IOMEM_CSI2A_REGS2 |
- 1 << OMAP3_ISP_IOMEM_CSI2C_REGS1 |
- 1 << OMAP3_ISP_IOMEM_CSIPHY1 |
- 1 << OMAP3_ISP_IOMEM_CSI2C_REGS2,
- },
-};
-
-/* Structure for saving/restoring ISP module registers */
-static struct isp_reg isp_reg_list[] = {
- {OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG, 0},
- {OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, 0},
- {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, 0},
- {0, ISP_TOK_TERM, 0}
-};
-
-/*
- * omap3isp_flush - Post pending L3 bus writes by doing a register readback
- * @isp: OMAP3 ISP device
- *
- * In order to force posting of pending writes, we need to write and
- * readback the same register, in this case the revision register.
- *
- * See this link for reference:
- * http://www.mail-archive.com/linux-omap@vger.kernel.org/msg08149.html
- */
-void omap3isp_flush(struct isp_device *isp)
-{
- isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);
- isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);
-}
-
-/*
- * isp_enable_interrupts - Enable ISP interrupts.
- * @isp: OMAP3 ISP device
- */
-static void isp_enable_interrupts(struct isp_device *isp)
-{
- static const u32 irq = IRQ0ENABLE_CSIA_IRQ
- | IRQ0ENABLE_CSIB_IRQ
- | IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ
- | IRQ0ENABLE_CCDC_LSC_DONE_IRQ
- | IRQ0ENABLE_CCDC_VD0_IRQ
- | IRQ0ENABLE_CCDC_VD1_IRQ
- | IRQ0ENABLE_HS_VS_IRQ
- | IRQ0ENABLE_HIST_DONE_IRQ
- | IRQ0ENABLE_H3A_AWB_DONE_IRQ
- | IRQ0ENABLE_H3A_AF_DONE_IRQ
- | IRQ0ENABLE_PRV_DONE_IRQ
- | IRQ0ENABLE_RSZ_DONE_IRQ;
-
- isp_reg_writel(isp, irq, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
- isp_reg_writel(isp, irq, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE);
-}
-
-/*
- * isp_disable_interrupts - Disable ISP interrupts.
- * @isp: OMAP3 ISP device
- */
-static void isp_disable_interrupts(struct isp_device *isp)
-{
- isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE);
-}
-
-/**
- * isp_set_xclk - Configures the specified cam_xclk to the desired frequency.
- * @isp: OMAP3 ISP device
- * @xclk: Desired frequency of the clock in Hz. 0 = stable low, 1 is stable high
- * @xclksel: XCLK to configure (0 = A, 1 = B).
- *
- * Configures the specified MCLK divisor in the ISP timing control register
- * (TCTRL_CTRL) to generate the desired xclk clock value.
- *
- * Divisor = cam_mclk_hz / xclk
- *
- * Returns the final frequency that is actually being generated
- **/
-static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel)
-{
- u32 divisor;
- u32 currentxclk;
- unsigned long mclk_hz;
-
- if (!omap3isp_get(isp))
- return 0;
-
- mclk_hz = clk_get_rate(isp->clock[ISP_CLK_CAM_MCLK]);
-
- if (xclk >= mclk_hz) {
- divisor = ISPTCTRL_CTRL_DIV_BYPASS;
- currentxclk = mclk_hz;
- } else if (xclk >= 2) {
- divisor = mclk_hz / xclk;
- if (divisor >= ISPTCTRL_CTRL_DIV_BYPASS)
- divisor = ISPTCTRL_CTRL_DIV_BYPASS - 1;
- currentxclk = mclk_hz / divisor;
- } else {
- divisor = xclk;
- currentxclk = 0;
- }
-
- switch (xclksel) {
- case ISP_XCLK_A:
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL,
- ISPTCTRL_CTRL_DIVA_MASK,
- divisor << ISPTCTRL_CTRL_DIVA_SHIFT);
- dev_dbg(isp->dev, "isp_set_xclk(): cam_xclka set to %d Hz\n",
- currentxclk);
- break;
- case ISP_XCLK_B:
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL,
- ISPTCTRL_CTRL_DIVB_MASK,
- divisor << ISPTCTRL_CTRL_DIVB_SHIFT);
- dev_dbg(isp->dev, "isp_set_xclk(): cam_xclkb set to %d Hz\n",
- currentxclk);
- break;
- case ISP_XCLK_NONE:
- default:
- omap3isp_put(isp);
- dev_dbg(isp->dev, "ISP_ERR: isp_set_xclk(): Invalid requested "
- "xclk. Must be 0 (A) or 1 (B).\n");
- return -EINVAL;
- }
-
- /* Do we go from stable whatever to clock? */
- if (divisor >= 2 && isp->xclk_divisor[xclksel - 1] < 2)
- omap3isp_get(isp);
- /* Stopping the clock. */
- else if (divisor < 2 && isp->xclk_divisor[xclksel - 1] >= 2)
- omap3isp_put(isp);
-
- isp->xclk_divisor[xclksel - 1] = divisor;
-
- omap3isp_put(isp);
-
- return currentxclk;
-}
-
-/*
- * isp_power_settings - Sysconfig settings, for Power Management.
- * @isp: OMAP3 ISP device
- * @idle: Consider idle state.
- *
- * Sets the power settings for the ISP, and SBL bus.
- */
-static void isp_power_settings(struct isp_device *isp, int idle)
-{
- isp_reg_writel(isp,
- ((idle ? ISP_SYSCONFIG_MIDLEMODE_SMARTSTANDBY :
- ISP_SYSCONFIG_MIDLEMODE_FORCESTANDBY) <<
- ISP_SYSCONFIG_MIDLEMODE_SHIFT) |
- ((isp->revision == ISP_REVISION_15_0) ?
- ISP_SYSCONFIG_AUTOIDLE : 0),
- OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG);
-
- if (isp->autoidle)
- isp_reg_writel(isp, ISPCTRL_SBL_AUTOIDLE, OMAP3_ISP_IOMEM_MAIN,
- ISP_CTRL);
-}
-
-/*
- * Configure the bridge and lane shifter. Valid inputs are
- *
- * CCDC_INPUT_PARALLEL: Parallel interface
- * CCDC_INPUT_CSI2A: CSI2a receiver
- * CCDC_INPUT_CCP2B: CCP2b receiver
- * CCDC_INPUT_CSI2C: CSI2c receiver
- *
- * The bridge and lane shifter are configured according to the selected input
- * and the ISP platform data.
- */
-void omap3isp_configure_bridge(struct isp_device *isp,
- enum ccdc_input_entity input,
- const struct isp_parallel_platform_data *pdata,
- unsigned int shift)
-{
- u32 ispctrl_val;
-
- ispctrl_val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);
- ispctrl_val &= ~ISPCTRL_SHIFT_MASK;
- ispctrl_val &= ~ISPCTRL_PAR_CLK_POL_INV;
- ispctrl_val &= ~ISPCTRL_PAR_SER_CLK_SEL_MASK;
- ispctrl_val &= ~ISPCTRL_PAR_BRIDGE_MASK;
-
- switch (input) {
- case CCDC_INPUT_PARALLEL:
- ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL;
- ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;
- ispctrl_val |= pdata->bridge << ISPCTRL_PAR_BRIDGE_SHIFT;
- shift += pdata->data_lane_shift * 2;
- break;
-
- case CCDC_INPUT_CSI2A:
- ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIA;
- break;
-
- case CCDC_INPUT_CCP2B:
- ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIB;
- break;
-
- case CCDC_INPUT_CSI2C:
- ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIC;
- break;
-
- default:
- return;
- }
-
- ispctrl_val |= ((shift/2) << ISPCTRL_SHIFT_SHIFT) & ISPCTRL_SHIFT_MASK;
-
- ispctrl_val &= ~ISPCTRL_SYNC_DETECT_MASK;
- ispctrl_val |= ISPCTRL_SYNC_DETECT_VSRISE;
-
- isp_reg_writel(isp, ispctrl_val, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);
-}
-
-void omap3isp_hist_dma_done(struct isp_device *isp)
-{
- if (omap3isp_ccdc_busy(&isp->isp_ccdc) ||
- omap3isp_stat_pcr_busy(&isp->isp_hist)) {
- /* Histogram cannot be enabled in this frame anymore */
- atomic_set(&isp->isp_hist.buf_err, 1);
- dev_dbg(isp->dev, "hist: Out of synchronization with "
- "CCDC. Ignoring next buffer.\n");
- }
-}
-
-static inline void isp_isr_dbg(struct isp_device *isp, u32 irqstatus)
-{
- static const char *name[] = {
- "CSIA_IRQ",
- "res1",
- "res2",
- "CSIB_LCM_IRQ",
- "CSIB_IRQ",
- "res5",
- "res6",
- "res7",
- "CCDC_VD0_IRQ",
- "CCDC_VD1_IRQ",
- "CCDC_VD2_IRQ",
- "CCDC_ERR_IRQ",
- "H3A_AF_DONE_IRQ",
- "H3A_AWB_DONE_IRQ",
- "res14",
- "res15",
- "HIST_DONE_IRQ",
- "CCDC_LSC_DONE",
- "CCDC_LSC_PREFETCH_COMPLETED",
- "CCDC_LSC_PREFETCH_ERROR",
- "PRV_DONE_IRQ",
- "CBUFF_IRQ",
- "res22",
- "res23",
- "RSZ_DONE_IRQ",
- "OVF_IRQ",
- "res26",
- "res27",
- "MMU_ERR_IRQ",
- "OCP_ERR_IRQ",
- "SEC_ERR_IRQ",
- "HS_VS_IRQ",
- };
- int i;
-
- dev_dbg(isp->dev, "ISP IRQ: ");
-
- for (i = 0; i < ARRAY_SIZE(name); i++) {
- if ((1 << i) & irqstatus)
- printk(KERN_CONT "%s ", name[i]);
- }
- printk(KERN_CONT "\n");
-}
-
-static void isp_isr_sbl(struct isp_device *isp)
-{
- struct device *dev = isp->dev;
- struct isp_pipeline *pipe;
- u32 sbl_pcr;
-
- /*
- * Handle shared buffer logic overflows for video buffers.
- * ISPSBL_PCR_CCDCPRV_2_RSZ_OVF can be safely ignored.
- */
- sbl_pcr = isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_PCR);
- isp_reg_writel(isp, sbl_pcr, OMAP3_ISP_IOMEM_SBL, ISPSBL_PCR);
- sbl_pcr &= ~ISPSBL_PCR_CCDCPRV_2_RSZ_OVF;
-
- if (sbl_pcr)
- dev_dbg(dev, "SBL overflow (PCR = 0x%08x)\n", sbl_pcr);
-
- if (sbl_pcr & ISPSBL_PCR_CSIB_WBL_OVF) {
- pipe = to_isp_pipeline(&isp->isp_ccp2.subdev.entity);
- if (pipe != NULL)
- pipe->error = true;
- }
-
- if (sbl_pcr & ISPSBL_PCR_CSIA_WBL_OVF) {
- pipe = to_isp_pipeline(&isp->isp_csi2a.subdev.entity);
- if (pipe != NULL)
- pipe->error = true;
- }
-
- if (sbl_pcr & ISPSBL_PCR_CCDC_WBL_OVF) {
- pipe = to_isp_pipeline(&isp->isp_ccdc.subdev.entity);
- if (pipe != NULL)
- pipe->error = true;
- }
-
- if (sbl_pcr & ISPSBL_PCR_PRV_WBL_OVF) {
- pipe = to_isp_pipeline(&isp->isp_prev.subdev.entity);
- if (pipe != NULL)
- pipe->error = true;
- }
-
- if (sbl_pcr & (ISPSBL_PCR_RSZ1_WBL_OVF
- | ISPSBL_PCR_RSZ2_WBL_OVF
- | ISPSBL_PCR_RSZ3_WBL_OVF
- | ISPSBL_PCR_RSZ4_WBL_OVF)) {
- pipe = to_isp_pipeline(&isp->isp_res.subdev.entity);
- if (pipe != NULL)
- pipe->error = true;
- }
-
- if (sbl_pcr & ISPSBL_PCR_H3A_AF_WBL_OVF)
- omap3isp_stat_sbl_overflow(&isp->isp_af);
-
- if (sbl_pcr & ISPSBL_PCR_H3A_AEAWB_WBL_OVF)
- omap3isp_stat_sbl_overflow(&isp->isp_aewb);
-}
-
-/*
- * isp_isr - Interrupt Service Routine for Camera ISP module.
- * @irq: Not used currently.
- * @_isp: Pointer to the OMAP3 ISP device
- *
- * Handles the corresponding callback if plugged in.
- *
- * Returns IRQ_HANDLED when IRQ was correctly handled, or IRQ_NONE when the
- * IRQ wasn't handled.
- */
-static irqreturn_t isp_isr(int irq, void *_isp)
-{
- static const u32 ccdc_events = IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ |
- IRQ0STATUS_CCDC_LSC_DONE_IRQ |
- IRQ0STATUS_CCDC_VD0_IRQ |
- IRQ0STATUS_CCDC_VD1_IRQ |
- IRQ0STATUS_HS_VS_IRQ;
- struct isp_device *isp = _isp;
- u32 irqstatus;
-
- irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
- isp_reg_writel(isp, irqstatus, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
-
- isp_isr_sbl(isp);
-
- if (irqstatus & IRQ0STATUS_CSIA_IRQ)
- omap3isp_csi2_isr(&isp->isp_csi2a);
-
- if (irqstatus & IRQ0STATUS_CSIB_IRQ)
- omap3isp_ccp2_isr(&isp->isp_ccp2);
-
- if (irqstatus & IRQ0STATUS_CCDC_VD0_IRQ) {
- if (isp->isp_ccdc.output & CCDC_OUTPUT_PREVIEW)
- omap3isp_preview_isr_frame_sync(&isp->isp_prev);
- if (isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER)
- omap3isp_resizer_isr_frame_sync(&isp->isp_res);
- omap3isp_stat_isr_frame_sync(&isp->isp_aewb);
- omap3isp_stat_isr_frame_sync(&isp->isp_af);
- omap3isp_stat_isr_frame_sync(&isp->isp_hist);
- }
-
- if (irqstatus & ccdc_events)
- omap3isp_ccdc_isr(&isp->isp_ccdc, irqstatus & ccdc_events);
-
- if (irqstatus & IRQ0STATUS_PRV_DONE_IRQ) {
- if (isp->isp_prev.output & PREVIEW_OUTPUT_RESIZER)
- omap3isp_resizer_isr_frame_sync(&isp->isp_res);
- omap3isp_preview_isr(&isp->isp_prev);
- }
-
- if (irqstatus & IRQ0STATUS_RSZ_DONE_IRQ)
- omap3isp_resizer_isr(&isp->isp_res);
-
- if (irqstatus & IRQ0STATUS_H3A_AWB_DONE_IRQ)
- omap3isp_stat_isr(&isp->isp_aewb);
-
- if (irqstatus & IRQ0STATUS_H3A_AF_DONE_IRQ)
- omap3isp_stat_isr(&isp->isp_af);
-
- if (irqstatus & IRQ0STATUS_HIST_DONE_IRQ)
- omap3isp_stat_isr(&isp->isp_hist);
-
- omap3isp_flush(isp);
-
-#if defined(DEBUG) && defined(ISP_ISR_DEBUG)
- isp_isr_dbg(isp, irqstatus);
-#endif
-
- return IRQ_HANDLED;
-}
-
-/* -----------------------------------------------------------------------------
- * Pipeline power management
- *
- * Entities must be powered up when part of a pipeline that contains at least
- * one open video device node.
- *
- * To achieve this use the entity use_count field to track the number of users.
- * For entities corresponding to video device nodes the use_count field stores
- * the users count of the node. For entities corresponding to subdevs the
- * use_count field stores the total number of users of all video device nodes
- * in the pipeline.
- *
- * The omap3isp_pipeline_pm_use() function must be called in the open() and
- * close() handlers of video device nodes. It increments or decrements the use
- * count of all subdev entities in the pipeline.
- *
- * To react to link management on powered pipelines, the link setup notification
- * callback updates the use count of all entities in the source and sink sides
- * of the link.
- */
-
-/*
- * isp_pipeline_pm_use_count - Count the number of users of a pipeline
- * @entity: The entity
- *
- * Return the total number of users of all video device nodes in the pipeline.
- */
-static int isp_pipeline_pm_use_count(struct media_entity *entity)
-{
- struct media_entity_graph graph;
- int use = 0;
-
- media_entity_graph_walk_start(&graph, entity);
-
- while ((entity = media_entity_graph_walk_next(&graph))) {
- if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
- use += entity->use_count;
- }
-
- return use;
-}
-
-/*
- * isp_pipeline_pm_power_one - Apply power change to an entity
- * @entity: The entity
- * @change: Use count change
- *
- * Change the entity use count by @change. If the entity is a subdev update its
- * power state by calling the core::s_power operation when the use count goes
- * from 0 to != 0 or from != 0 to 0.
- *
- * Return 0 on success or a negative error code on failure.
- */
-static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)
-{
- struct v4l2_subdev *subdev;
- int ret;
-
- subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV
- ? media_entity_to_v4l2_subdev(entity) : NULL;
-
- if (entity->use_count == 0 && change > 0 && subdev != NULL) {
- ret = v4l2_subdev_call(subdev, core, s_power, 1);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return ret;
- }
-
- entity->use_count += change;
- WARN_ON(entity->use_count < 0);
-
- if (entity->use_count == 0 && change < 0 && subdev != NULL)
- v4l2_subdev_call(subdev, core, s_power, 0);
-
- return 0;
-}
-
-/*
- * isp_pipeline_pm_power - Apply power change to all entities in a pipeline
- * @entity: The entity
- * @change: Use count change
- *
- * Walk the pipeline to update the use count and the power state of all non-node
- * entities.
- *
- * Return 0 on success or a negative error code on failure.
- */
-static int isp_pipeline_pm_power(struct media_entity *entity, int change)
-{
- struct media_entity_graph graph;
- struct media_entity *first = entity;
- int ret = 0;
-
- if (!change)
- return 0;
-
- media_entity_graph_walk_start(&graph, entity);
-
- while (!ret && (entity = media_entity_graph_walk_next(&graph)))
- if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
- ret = isp_pipeline_pm_power_one(entity, change);
-
- if (!ret)
- return 0;
-
- media_entity_graph_walk_start(&graph, first);
-
- while ((first = media_entity_graph_walk_next(&graph))
- && first != entity)
- if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE)
- isp_pipeline_pm_power_one(first, -change);
-
- return ret;
-}
-
-/*
- * omap3isp_pipeline_pm_use - Update the use count of an entity
- * @entity: The entity
- * @use: Use (1) or stop using (0) the entity
- *
- * Update the use count of all entities in the pipeline and power entities on or
- * off accordingly.
- *
- * Return 0 on success or a negative error code on failure. Powering entities
- * off is assumed to never fail. No failure can occur when the use parameter is
- * set to 0.
- */
-int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
-{
- int change = use ? 1 : -1;
- int ret;
-
- mutex_lock(&entity->parent->graph_mutex);
-
- /* Apply use count to node. */
- entity->use_count += change;
- WARN_ON(entity->use_count < 0);
-
- /* Apply power change to connected non-nodes. */
- ret = isp_pipeline_pm_power(entity, change);
- if (ret < 0)
- entity->use_count -= change;
-
- mutex_unlock(&entity->parent->graph_mutex);
-
- return ret;
-}
-
-/*
- * isp_pipeline_link_notify - Link management notification callback
- * @source: Pad at the start of the link
- * @sink: Pad at the end of the link
- * @flags: New link flags that will be applied
- *
- * React to link management on powered pipelines by updating the use count of
- * all entities in the source and sink sides of the link. Entities are powered
- * on or off accordingly.
- *
- * Return 0 on success or a negative error code on failure. Powering entities
- * off is assumed to never fail. This function will not fail for disconnection
- * events.
- */
-static int isp_pipeline_link_notify(struct media_pad *source,
- struct media_pad *sink, u32 flags)
-{
- int source_use = isp_pipeline_pm_use_count(source->entity);
- int sink_use = isp_pipeline_pm_use_count(sink->entity);
- int ret;
-
- if (!(flags & MEDIA_LNK_FL_ENABLED)) {
- /* Powering off entities is assumed to never fail. */
- isp_pipeline_pm_power(source->entity, -sink_use);
- isp_pipeline_pm_power(sink->entity, -source_use);
- return 0;
- }
-
- ret = isp_pipeline_pm_power(source->entity, sink_use);
- if (ret < 0)
- return ret;
-
- ret = isp_pipeline_pm_power(sink->entity, source_use);
- if (ret < 0)
- isp_pipeline_pm_power(source->entity, -sink_use);
-
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * Pipeline stream management
- */
-
-/*
- * isp_pipeline_enable - Enable streaming on a pipeline
- * @pipe: ISP pipeline
- * @mode: Stream mode (single shot or continuous)
- *
- * Walk the entities chain starting at the pipeline output video node and start
- * all modules in the chain in the given mode.
- *
- * Return 0 if successful, or the return value of the failed video::s_stream
- * operation otherwise.
- */
-static int isp_pipeline_enable(struct isp_pipeline *pipe,
- enum isp_pipeline_stream_state mode)
-{
- struct isp_device *isp = pipe->output->isp;
- struct media_entity *entity;
- struct media_pad *pad;
- struct v4l2_subdev *subdev;
- unsigned long flags;
- int ret;
-
- /* If the preview engine crashed it might not respond to read/write
- * operations on the L4 bus. This would result in a bus fault and a
- * kernel oops. Refuse to start streaming in that case. This check must
- * be performed before the loop below to avoid starting entities if the
- * pipeline won't start anyway (those entities would then likely fail to
- * stop, making the problem worse).
- */
- if ((pipe->entities & isp->crashed) &
- (1U << isp->isp_prev.subdev.entity.id))
- return -EIO;
-
- spin_lock_irqsave(&pipe->lock, flags);
- pipe->state &= ~(ISP_PIPELINE_IDLE_INPUT | ISP_PIPELINE_IDLE_OUTPUT);
- spin_unlock_irqrestore(&pipe->lock, flags);
-
- pipe->do_propagation = false;
-
- entity = &pipe->output->video.entity;
- while (1) {
- pad = &entity->pads[0];
- if (!(pad->flags & MEDIA_PAD_FL_SINK))
- break;
-
- pad = media_entity_remote_source(pad);
- if (pad == NULL ||
- media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
- break;
-
- entity = pad->entity;
- subdev = media_entity_to_v4l2_subdev(entity);
-
- ret = v4l2_subdev_call(subdev, video, s_stream, mode);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return ret;
-
- if (subdev == &isp->isp_ccdc.subdev) {
- v4l2_subdev_call(&isp->isp_aewb.subdev, video,
- s_stream, mode);
- v4l2_subdev_call(&isp->isp_af.subdev, video,
- s_stream, mode);
- v4l2_subdev_call(&isp->isp_hist.subdev, video,
- s_stream, mode);
- pipe->do_propagation = true;
- }
- }
-
- return 0;
-}
-
-static int isp_pipeline_wait_resizer(struct isp_device *isp)
-{
- return omap3isp_resizer_busy(&isp->isp_res);
-}
-
-static int isp_pipeline_wait_preview(struct isp_device *isp)
-{
- return omap3isp_preview_busy(&isp->isp_prev);
-}
-
-static int isp_pipeline_wait_ccdc(struct isp_device *isp)
-{
- return omap3isp_stat_busy(&isp->isp_af)
- || omap3isp_stat_busy(&isp->isp_aewb)
- || omap3isp_stat_busy(&isp->isp_hist)
- || omap3isp_ccdc_busy(&isp->isp_ccdc);
-}
-
-#define ISP_STOP_TIMEOUT msecs_to_jiffies(1000)
-
-static int isp_pipeline_wait(struct isp_device *isp,
- int(*busy)(struct isp_device *isp))
-{
- unsigned long timeout = jiffies + ISP_STOP_TIMEOUT;
-
- while (!time_after(jiffies, timeout)) {
- if (!busy(isp))
- return 0;
- }
-
- return 1;
-}
-
-/*
- * isp_pipeline_disable - Disable streaming on a pipeline
- * @pipe: ISP pipeline
- *
- * Walk the entities chain starting at the pipeline output video node and stop
- * all modules in the chain. Wait synchronously for the modules to be stopped if
- * necessary.
- *
- * Return 0 if all modules have been properly stopped, or -ETIMEDOUT if a module
- * can't be stopped (in which case a software reset of the ISP is probably
- * necessary).
- */
-static int isp_pipeline_disable(struct isp_pipeline *pipe)
-{
- struct isp_device *isp = pipe->output->isp;
- struct media_entity *entity;
- struct media_pad *pad;
- struct v4l2_subdev *subdev;
- int failure = 0;
- int ret;
-
- /*
- * We need to stop all the modules after CCDC first or they'll
- * never stop since they may not get a full frame from CCDC.
- */
- entity = &pipe->output->video.entity;
- while (1) {
- pad = &entity->pads[0];
- if (!(pad->flags & MEDIA_PAD_FL_SINK))
- break;
-
- pad = media_entity_remote_source(pad);
- if (pad == NULL ||
- media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
- break;
-
- entity = pad->entity;
- subdev = media_entity_to_v4l2_subdev(entity);
-
- if (subdev == &isp->isp_ccdc.subdev) {
- v4l2_subdev_call(&isp->isp_aewb.subdev,
- video, s_stream, 0);
- v4l2_subdev_call(&isp->isp_af.subdev,
- video, s_stream, 0);
- v4l2_subdev_call(&isp->isp_hist.subdev,
- video, s_stream, 0);
- }
-
- v4l2_subdev_call(subdev, video, s_stream, 0);
-
- if (subdev == &isp->isp_res.subdev)
- ret = isp_pipeline_wait(isp, isp_pipeline_wait_resizer);
- else if (subdev == &isp->isp_prev.subdev)
- ret = isp_pipeline_wait(isp, isp_pipeline_wait_preview);
- else if (subdev == &isp->isp_ccdc.subdev)
- ret = isp_pipeline_wait(isp, isp_pipeline_wait_ccdc);
- else
- ret = 0;
-
- if (ret) {
- dev_info(isp->dev, "Unable to stop %s\n", subdev->name);
- /* If the entity failed to stopped, assume it has
- * crashed. Mark it as such, the ISP will be reset when
- * applications will release it.
- */
- isp->crashed |= 1U << subdev->entity.id;
- failure = -ETIMEDOUT;
- }
- }
-
- return failure;
-}
-
-/*
- * omap3isp_pipeline_set_stream - Enable/disable streaming on a pipeline
- * @pipe: ISP pipeline
- * @state: Stream state (stopped, single shot or continuous)
- *
- * Set the pipeline to the given stream state. Pipelines can be started in
- * single-shot or continuous mode.
- *
- * Return 0 if successful, or the return value of the failed video::s_stream
- * operation otherwise. The pipeline state is not updated when the operation
- * fails, except when stopping the pipeline.
- */
-int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
- enum isp_pipeline_stream_state state)
-{
- int ret;
-
- if (state == ISP_PIPELINE_STREAM_STOPPED)
- ret = isp_pipeline_disable(pipe);
- else
- ret = isp_pipeline_enable(pipe, state);
-
- if (ret == 0 || state == ISP_PIPELINE_STREAM_STOPPED)
- pipe->stream_state = state;
-
- return ret;
-}
-
-/*
- * isp_pipeline_resume - Resume streaming on a pipeline
- * @pipe: ISP pipeline
- *
- * Resume video output and input and re-enable pipeline.
- */
-static void isp_pipeline_resume(struct isp_pipeline *pipe)
-{
- int singleshot = pipe->stream_state == ISP_PIPELINE_STREAM_SINGLESHOT;
-
- omap3isp_video_resume(pipe->output, !singleshot);
- if (singleshot)
- omap3isp_video_resume(pipe->input, 0);
- isp_pipeline_enable(pipe, pipe->stream_state);
-}
-
-/*
- * isp_pipeline_suspend - Suspend streaming on a pipeline
- * @pipe: ISP pipeline
- *
- * Suspend pipeline.
- */
-static void isp_pipeline_suspend(struct isp_pipeline *pipe)
-{
- isp_pipeline_disable(pipe);
-}
-
-/*
- * isp_pipeline_is_last - Verify if entity has an enabled link to the output
- * video node
- * @me: ISP module's media entity
- *
- * Returns 1 if the entity has an enabled link to the output video node or 0
- * otherwise. It's true only while pipeline can have no more than one output
- * node.
- */
-static int isp_pipeline_is_last(struct media_entity *me)
-{
- struct isp_pipeline *pipe;
- struct media_pad *pad;
-
- if (!me->pipe)
- return 0;
- pipe = to_isp_pipeline(me);
- if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED)
- return 0;
- pad = media_entity_remote_source(&pipe->output->pad);
- return pad->entity == me;
-}
-
-/*
- * isp_suspend_module_pipeline - Suspend pipeline to which belongs the module
- * @me: ISP module's media entity
- *
- * Suspend the whole pipeline if module's entity has an enabled link to the
- * output video node. It works only while pipeline can have no more than one
- * output node.
- */
-static void isp_suspend_module_pipeline(struct media_entity *me)
-{
- if (isp_pipeline_is_last(me))
- isp_pipeline_suspend(to_isp_pipeline(me));
-}
-
-/*
- * isp_resume_module_pipeline - Resume pipeline to which belongs the module
- * @me: ISP module's media entity
- *
- * Resume the whole pipeline if module's entity has an enabled link to the
- * output video node. It works only while pipeline can have no more than one
- * output node.
- */
-static void isp_resume_module_pipeline(struct media_entity *me)
-{
- if (isp_pipeline_is_last(me))
- isp_pipeline_resume(to_isp_pipeline(me));
-}
-
-/*
- * isp_suspend_modules - Suspend ISP submodules.
- * @isp: OMAP3 ISP device
- *
- * Returns 0 if suspend left in idle state all the submodules properly,
- * or returns 1 if a general Reset is required to suspend the submodules.
- */
-static int isp_suspend_modules(struct isp_device *isp)
-{
- unsigned long timeout;
-
- omap3isp_stat_suspend(&isp->isp_aewb);
- omap3isp_stat_suspend(&isp->isp_af);
- omap3isp_stat_suspend(&isp->isp_hist);
- isp_suspend_module_pipeline(&isp->isp_res.subdev.entity);
- isp_suspend_module_pipeline(&isp->isp_prev.subdev.entity);
- isp_suspend_module_pipeline(&isp->isp_ccdc.subdev.entity);
- isp_suspend_module_pipeline(&isp->isp_csi2a.subdev.entity);
- isp_suspend_module_pipeline(&isp->isp_ccp2.subdev.entity);
-
- timeout = jiffies + ISP_STOP_TIMEOUT;
- while (omap3isp_stat_busy(&isp->isp_af)
- || omap3isp_stat_busy(&isp->isp_aewb)
- || omap3isp_stat_busy(&isp->isp_hist)
- || omap3isp_preview_busy(&isp->isp_prev)
- || omap3isp_resizer_busy(&isp->isp_res)
- || omap3isp_ccdc_busy(&isp->isp_ccdc)) {
- if (time_after(jiffies, timeout)) {
- dev_info(isp->dev, "can't stop modules.\n");
- return 1;
- }
- msleep(1);
- }
-
- return 0;
-}
-
-/*
- * isp_resume_modules - Resume ISP submodules.
- * @isp: OMAP3 ISP device
- */
-static void isp_resume_modules(struct isp_device *isp)
-{
- omap3isp_stat_resume(&isp->isp_aewb);
- omap3isp_stat_resume(&isp->isp_af);
- omap3isp_stat_resume(&isp->isp_hist);
- isp_resume_module_pipeline(&isp->isp_res.subdev.entity);
- isp_resume_module_pipeline(&isp->isp_prev.subdev.entity);
- isp_resume_module_pipeline(&isp->isp_ccdc.subdev.entity);
- isp_resume_module_pipeline(&isp->isp_csi2a.subdev.entity);
- isp_resume_module_pipeline(&isp->isp_ccp2.subdev.entity);
-}
-
-/*
- * isp_reset - Reset ISP with a timeout wait for idle.
- * @isp: OMAP3 ISP device
- */
-static int isp_reset(struct isp_device *isp)
-{
- unsigned long timeout = 0;
-
- isp_reg_writel(isp,
- isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG)
- | ISP_SYSCONFIG_SOFTRESET,
- OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG);
- while (!(isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN,
- ISP_SYSSTATUS) & 0x1)) {
- if (timeout++ > 10000) {
- dev_alert(isp->dev, "cannot reset ISP\n");
- return -ETIMEDOUT;
- }
- udelay(1);
- }
-
- isp->crashed = 0;
- return 0;
-}
-
-/*
- * isp_save_context - Saves the values of the ISP module registers.
- * @isp: OMAP3 ISP device
- * @reg_list: Structure containing pairs of register address and value to
- * modify on OMAP.
- */
-static void
-isp_save_context(struct isp_device *isp, struct isp_reg *reg_list)
-{
- struct isp_reg *next = reg_list;
-
- for (; next->reg != ISP_TOK_TERM; next++)
- next->val = isp_reg_readl(isp, next->mmio_range, next->reg);
-}
-
-/*
- * isp_restore_context - Restores the values of the ISP module registers.
- * @isp: OMAP3 ISP device
- * @reg_list: Structure containing pairs of register address and value to
- * modify on OMAP.
- */
-static void
-isp_restore_context(struct isp_device *isp, struct isp_reg *reg_list)
-{
- struct isp_reg *next = reg_list;
-
- for (; next->reg != ISP_TOK_TERM; next++)
- isp_reg_writel(isp, next->val, next->mmio_range, next->reg);
-}
-
-/*
- * isp_save_ctx - Saves ISP, CCDC, HIST, H3A, PREV, RESZ & MMU context.
- * @isp: OMAP3 ISP device
- *
- * Routine for saving the context of each module in the ISP.
- * CCDC, HIST, H3A, PREV, RESZ and MMU.
- */
-static void isp_save_ctx(struct isp_device *isp)
-{
- isp_save_context(isp, isp_reg_list);
- omap_iommu_save_ctx(isp->dev);
-}
-
-/*
- * isp_restore_ctx - Restores ISP, CCDC, HIST, H3A, PREV, RESZ & MMU context.
- * @isp: OMAP3 ISP device
- *
- * Routine for restoring the context of each module in the ISP.
- * CCDC, HIST, H3A, PREV, RESZ and MMU.
- */
-static void isp_restore_ctx(struct isp_device *isp)
-{
- isp_restore_context(isp, isp_reg_list);
- omap_iommu_restore_ctx(isp->dev);
- omap3isp_ccdc_restore_context(isp);
- omap3isp_preview_restore_context(isp);
-}
-
-/* -----------------------------------------------------------------------------
- * SBL resources management
- */
-#define OMAP3_ISP_SBL_READ (OMAP3_ISP_SBL_CSI1_READ | \
- OMAP3_ISP_SBL_CCDC_LSC_READ | \
- OMAP3_ISP_SBL_PREVIEW_READ | \
- OMAP3_ISP_SBL_RESIZER_READ)
-#define OMAP3_ISP_SBL_WRITE (OMAP3_ISP_SBL_CSI1_WRITE | \
- OMAP3_ISP_SBL_CSI2A_WRITE | \
- OMAP3_ISP_SBL_CSI2C_WRITE | \
- OMAP3_ISP_SBL_CCDC_WRITE | \
- OMAP3_ISP_SBL_PREVIEW_WRITE)
-
-void omap3isp_sbl_enable(struct isp_device *isp, enum isp_sbl_resource res)
-{
- u32 sbl = 0;
-
- isp->sbl_resources |= res;
-
- if (isp->sbl_resources & OMAP3_ISP_SBL_CSI1_READ)
- sbl |= ISPCTRL_SBL_SHARED_RPORTA;
-
- if (isp->sbl_resources & OMAP3_ISP_SBL_CCDC_LSC_READ)
- sbl |= ISPCTRL_SBL_SHARED_RPORTB;
-
- if (isp->sbl_resources & OMAP3_ISP_SBL_CSI2C_WRITE)
- sbl |= ISPCTRL_SBL_SHARED_WPORTC;
-
- if (isp->sbl_resources & OMAP3_ISP_SBL_RESIZER_WRITE)
- sbl |= ISPCTRL_SBL_WR0_RAM_EN;
-
- if (isp->sbl_resources & OMAP3_ISP_SBL_WRITE)
- sbl |= ISPCTRL_SBL_WR1_RAM_EN;
-
- if (isp->sbl_resources & OMAP3_ISP_SBL_READ)
- sbl |= ISPCTRL_SBL_RD_RAM_EN;
-
- isp_reg_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, sbl);
-}
-
-void omap3isp_sbl_disable(struct isp_device *isp, enum isp_sbl_resource res)
-{
- u32 sbl = 0;
-
- isp->sbl_resources &= ~res;
-
- if (!(isp->sbl_resources & OMAP3_ISP_SBL_CSI1_READ))
- sbl |= ISPCTRL_SBL_SHARED_RPORTA;
-
- if (!(isp->sbl_resources & OMAP3_ISP_SBL_CCDC_LSC_READ))
- sbl |= ISPCTRL_SBL_SHARED_RPORTB;
-
- if (!(isp->sbl_resources & OMAP3_ISP_SBL_CSI2C_WRITE))
- sbl |= ISPCTRL_SBL_SHARED_WPORTC;
-
- if (!(isp->sbl_resources & OMAP3_ISP_SBL_RESIZER_WRITE))
- sbl |= ISPCTRL_SBL_WR0_RAM_EN;
-
- if (!(isp->sbl_resources & OMAP3_ISP_SBL_WRITE))
- sbl |= ISPCTRL_SBL_WR1_RAM_EN;
-
- if (!(isp->sbl_resources & OMAP3_ISP_SBL_READ))
- sbl |= ISPCTRL_SBL_RD_RAM_EN;
-
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, sbl);
-}
-
-/*
- * isp_module_sync_idle - Helper to sync module with its idle state
- * @me: ISP submodule's media entity
- * @wait: ISP submodule's wait queue for streamoff/interrupt synchronization
- * @stopping: flag which tells module wants to stop
- *
- * This function checks if ISP submodule needs to wait for next interrupt. If
- * yes, makes the caller to sleep while waiting for such event.
- */
-int omap3isp_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
- atomic_t *stopping)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(me);
-
- if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED ||
- (pipe->stream_state == ISP_PIPELINE_STREAM_SINGLESHOT &&
- !isp_pipeline_ready(pipe)))
- return 0;
-
- /*
- * atomic_set() doesn't include memory barrier on ARM platform for SMP
- * scenario. We'll call it here to avoid race conditions.
- */
- atomic_set(stopping, 1);
- smp_mb();
-
- /*
- * If module is the last one, it's writing to memory. In this case,
- * it's necessary to check if the module is already paused due to
- * DMA queue underrun or if it has to wait for next interrupt to be
- * idle.
- * If it isn't the last one, the function won't sleep but *stopping
- * will still be set to warn next submodule caller's interrupt the
- * module wants to be idle.
- */
- if (isp_pipeline_is_last(me)) {
- struct isp_video *video = pipe->output;
- unsigned long flags;
- spin_lock_irqsave(&video->queue->irqlock, flags);
- if (video->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) {
- spin_unlock_irqrestore(&video->queue->irqlock, flags);
- atomic_set(stopping, 0);
- smp_mb();
- return 0;
- }
- spin_unlock_irqrestore(&video->queue->irqlock, flags);
- if (!wait_event_timeout(*wait, !atomic_read(stopping),
- msecs_to_jiffies(1000))) {
- atomic_set(stopping, 0);
- smp_mb();
- return -ETIMEDOUT;
- }
- }
-
- return 0;
-}
-
-/*
- * omap3isp_module_sync_is_stopped - Helper to verify if module was stopping
- * @wait: ISP submodule's wait queue for streamoff/interrupt synchronization
- * @stopping: flag which tells module wants to stop
- *
- * This function checks if ISP submodule was stopping. In case of yes, it
- * notices the caller by setting stopping to 0 and waking up the wait queue.
- * Returns 1 if it was stopping or 0 otherwise.
- */
-int omap3isp_module_sync_is_stopping(wait_queue_head_t *wait,
- atomic_t *stopping)
-{
- if (atomic_cmpxchg(stopping, 1, 0)) {
- wake_up(wait);
- return 1;
- }
-
- return 0;
-}
-
-/* --------------------------------------------------------------------------
- * Clock management
- */
-
-#define ISPCTRL_CLKS_MASK (ISPCTRL_H3A_CLK_EN | \
- ISPCTRL_HIST_CLK_EN | \
- ISPCTRL_RSZ_CLK_EN | \
- (ISPCTRL_CCDC_CLK_EN | ISPCTRL_CCDC_RAM_EN) | \
- (ISPCTRL_PREV_CLK_EN | ISPCTRL_PREV_RAM_EN))
-
-static void __isp_subclk_update(struct isp_device *isp)
-{
- u32 clk = 0;
-
- if (isp->subclk_resources & OMAP3_ISP_SUBCLK_H3A)
- clk |= ISPCTRL_H3A_CLK_EN;
-
- if (isp->subclk_resources & OMAP3_ISP_SUBCLK_HIST)
- clk |= ISPCTRL_HIST_CLK_EN;
-
- if (isp->subclk_resources & OMAP3_ISP_SUBCLK_RESIZER)
- clk |= ISPCTRL_RSZ_CLK_EN;
-
- /* NOTE: For CCDC & Preview submodules, we need to affect internal
- * RAM as well.
- */
- if (isp->subclk_resources & OMAP3_ISP_SUBCLK_CCDC)
- clk |= ISPCTRL_CCDC_CLK_EN | ISPCTRL_CCDC_RAM_EN;
-
- if (isp->subclk_resources & OMAP3_ISP_SUBCLK_PREVIEW)
- clk |= ISPCTRL_PREV_CLK_EN | ISPCTRL_PREV_RAM_EN;
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
- ISPCTRL_CLKS_MASK, clk);
-}
-
-void omap3isp_subclk_enable(struct isp_device *isp,
- enum isp_subclk_resource res)
-{
- isp->subclk_resources |= res;
-
- __isp_subclk_update(isp);
-}
-
-void omap3isp_subclk_disable(struct isp_device *isp,
- enum isp_subclk_resource res)
-{
- isp->subclk_resources &= ~res;
-
- __isp_subclk_update(isp);
-}
-
-/*
- * isp_enable_clocks - Enable ISP clocks
- * @isp: OMAP3 ISP device
- *
- * Return 0 if successful, or clk_enable return value if any of tthem fails.
- */
-static int isp_enable_clocks(struct isp_device *isp)
-{
- int r;
- unsigned long rate;
- int divisor;
-
- /*
- * cam_mclk clock chain:
- * dpll4 -> dpll4_m5 -> dpll4_m5x2 -> cam_mclk
- *
- * In OMAP3630 dpll4_m5x2 != 2 x dpll4_m5 but both are
- * set to the same value. Hence the rate set for dpll4_m5
- * has to be twice of what is set on OMAP3430 to get
- * the required value for cam_mclk
- */
- if (cpu_is_omap3630())
- divisor = 1;
- else
- divisor = 2;
-
- r = clk_enable(isp->clock[ISP_CLK_CAM_ICK]);
- if (r) {
- dev_err(isp->dev, "clk_enable cam_ick failed\n");
- goto out_clk_enable_ick;
- }
- r = clk_set_rate(isp->clock[ISP_CLK_DPLL4_M5_CK],
- CM_CAM_MCLK_HZ/divisor);
- if (r) {
- dev_err(isp->dev, "clk_set_rate for dpll4_m5_ck failed\n");
- goto out_clk_enable_mclk;
- }
- r = clk_enable(isp->clock[ISP_CLK_CAM_MCLK]);
- if (r) {
- dev_err(isp->dev, "clk_enable cam_mclk failed\n");
- goto out_clk_enable_mclk;
- }
- rate = clk_get_rate(isp->clock[ISP_CLK_CAM_MCLK]);
- if (rate != CM_CAM_MCLK_HZ)
- dev_warn(isp->dev, "unexpected cam_mclk rate:\n"
- " expected : %d\n"
- " actual : %ld\n", CM_CAM_MCLK_HZ, rate);
- r = clk_enable(isp->clock[ISP_CLK_CSI2_FCK]);
- if (r) {
- dev_err(isp->dev, "clk_enable csi2_fck failed\n");
- goto out_clk_enable_csi2_fclk;
- }
- return 0;
-
-out_clk_enable_csi2_fclk:
- clk_disable(isp->clock[ISP_CLK_CAM_MCLK]);
-out_clk_enable_mclk:
- clk_disable(isp->clock[ISP_CLK_CAM_ICK]);
-out_clk_enable_ick:
- return r;
-}
-
-/*
- * isp_disable_clocks - Disable ISP clocks
- * @isp: OMAP3 ISP device
- */
-static void isp_disable_clocks(struct isp_device *isp)
-{
- clk_disable(isp->clock[ISP_CLK_CAM_ICK]);
- clk_disable(isp->clock[ISP_CLK_CAM_MCLK]);
- clk_disable(isp->clock[ISP_CLK_CSI2_FCK]);
-}
-
-static const char *isp_clocks[] = {
- "cam_ick",
- "cam_mclk",
- "dpll4_m5_ck",
- "csi2_96m_fck",
- "l3_ick",
-};
-
-static void isp_put_clocks(struct isp_device *isp)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(isp_clocks); ++i) {
- if (isp->clock[i]) {
- clk_put(isp->clock[i]);
- isp->clock[i] = NULL;
- }
- }
-}
-
-static int isp_get_clocks(struct isp_device *isp)
-{
- struct clk *clk;
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(isp_clocks); ++i) {
- clk = clk_get(isp->dev, isp_clocks[i]);
- if (IS_ERR(clk)) {
- dev_err(isp->dev, "clk_get %s failed\n", isp_clocks[i]);
- isp_put_clocks(isp);
- return PTR_ERR(clk);
- }
-
- isp->clock[i] = clk;
- }
-
- return 0;
-}
-
-/*
- * omap3isp_get - Acquire the ISP resource.
- *
- * Initializes the clocks for the first acquire.
- *
- * Increment the reference count on the ISP. If the first reference is taken,
- * enable clocks and power-up all submodules.
- *
- * Return a pointer to the ISP device structure, or NULL if an error occurred.
- */
-struct isp_device *omap3isp_get(struct isp_device *isp)
-{
- struct isp_device *__isp = isp;
-
- if (isp == NULL)
- return NULL;
-
- mutex_lock(&isp->isp_mutex);
- if (isp->ref_count > 0)
- goto out;
-
- if (isp_enable_clocks(isp) < 0) {
- __isp = NULL;
- goto out;
- }
-
- /* We don't want to restore context before saving it! */
- if (isp->has_context)
- isp_restore_ctx(isp);
- else
- isp->has_context = 1;
-
- isp_enable_interrupts(isp);
-
-out:
- if (__isp != NULL)
- isp->ref_count++;
- mutex_unlock(&isp->isp_mutex);
-
- return __isp;
-}
-
-/*
- * omap3isp_put - Release the ISP
- *
- * Decrement the reference count on the ISP. If the last reference is released,
- * power-down all submodules, disable clocks and free temporary buffers.
- */
-void omap3isp_put(struct isp_device *isp)
-{
- if (isp == NULL)
- return;
-
- mutex_lock(&isp->isp_mutex);
- BUG_ON(isp->ref_count == 0);
- if (--isp->ref_count == 0) {
- isp_disable_interrupts(isp);
- if (isp->domain)
- isp_save_ctx(isp);
- /* Reset the ISP if an entity has failed to stop. This is the
- * only way to recover from such conditions.
- */
- if (isp->crashed)
- isp_reset(isp);
- isp_disable_clocks(isp);
- }
- mutex_unlock(&isp->isp_mutex);
-}
-
-/* --------------------------------------------------------------------------
- * Platform device driver
- */
-
-/*
- * omap3isp_print_status - Prints the values of the ISP Control Module registers
- * @isp: OMAP3 ISP device
- */
-#define ISP_PRINT_REGISTER(isp, name)\
- dev_dbg(isp->dev, "###ISP " #name "=0x%08x\n", \
- isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_##name))
-#define SBL_PRINT_REGISTER(isp, name)\
- dev_dbg(isp->dev, "###SBL " #name "=0x%08x\n", \
- isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_##name))
-
-void omap3isp_print_status(struct isp_device *isp)
-{
- dev_dbg(isp->dev, "-------------ISP Register dump--------------\n");
-
- ISP_PRINT_REGISTER(isp, SYSCONFIG);
- ISP_PRINT_REGISTER(isp, SYSSTATUS);
- ISP_PRINT_REGISTER(isp, IRQ0ENABLE);
- ISP_PRINT_REGISTER(isp, IRQ0STATUS);
- ISP_PRINT_REGISTER(isp, TCTRL_GRESET_LENGTH);
- ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_REPLAY);
- ISP_PRINT_REGISTER(isp, CTRL);
- ISP_PRINT_REGISTER(isp, TCTRL_CTRL);
- ISP_PRINT_REGISTER(isp, TCTRL_FRAME);
- ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_DELAY);
- ISP_PRINT_REGISTER(isp, TCTRL_STRB_DELAY);
- ISP_PRINT_REGISTER(isp, TCTRL_SHUT_DELAY);
- ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_LENGTH);
- ISP_PRINT_REGISTER(isp, TCTRL_STRB_LENGTH);
- ISP_PRINT_REGISTER(isp, TCTRL_SHUT_LENGTH);
-
- SBL_PRINT_REGISTER(isp, PCR);
- SBL_PRINT_REGISTER(isp, SDR_REQ_EXP);
-
- dev_dbg(isp->dev, "--------------------------------------------\n");
-}
-
-#ifdef CONFIG_PM
-
-/*
- * Power management support.
- *
- * As the ISP can't properly handle an input video stream interruption on a non
- * frame boundary, the ISP pipelines need to be stopped before sensors get
- * suspended. However, as suspending the sensors can require a running clock,
- * which can be provided by the ISP, the ISP can't be completely suspended
- * before the sensor.
- *
- * To solve this problem power management support is split into prepare/complete
- * and suspend/resume operations. The pipelines are stopped in prepare() and the
- * ISP clocks get disabled in suspend(). Similarly, the clocks are reenabled in
- * resume(), and the the pipelines are restarted in complete().
- *
- * TODO: PM dependencies between the ISP and sensors are not modeled explicitly
- * yet.
- */
-static int isp_pm_prepare(struct device *dev)
-{
- struct isp_device *isp = dev_get_drvdata(dev);
- int reset;
-
- WARN_ON(mutex_is_locked(&isp->isp_mutex));
-
- if (isp->ref_count == 0)
- return 0;
-
- reset = isp_suspend_modules(isp);
- isp_disable_interrupts(isp);
- isp_save_ctx(isp);
- if (reset)
- isp_reset(isp);
-
- return 0;
-}
-
-static int isp_pm_suspend(struct device *dev)
-{
- struct isp_device *isp = dev_get_drvdata(dev);
-
- WARN_ON(mutex_is_locked(&isp->isp_mutex));
-
- if (isp->ref_count)
- isp_disable_clocks(isp);
-
- return 0;
-}
-
-static int isp_pm_resume(struct device *dev)
-{
- struct isp_device *isp = dev_get_drvdata(dev);
-
- if (isp->ref_count == 0)
- return 0;
-
- return isp_enable_clocks(isp);
-}
-
-static void isp_pm_complete(struct device *dev)
-{
- struct isp_device *isp = dev_get_drvdata(dev);
-
- if (isp->ref_count == 0)
- return;
-
- isp_restore_ctx(isp);
- isp_enable_interrupts(isp);
- isp_resume_modules(isp);
-}
-
-#else
-
-#define isp_pm_prepare NULL
-#define isp_pm_suspend NULL
-#define isp_pm_resume NULL
-#define isp_pm_complete NULL
-
-#endif /* CONFIG_PM */
-
-static void isp_unregister_entities(struct isp_device *isp)
-{
- omap3isp_csi2_unregister_entities(&isp->isp_csi2a);
- omap3isp_ccp2_unregister_entities(&isp->isp_ccp2);
- omap3isp_ccdc_unregister_entities(&isp->isp_ccdc);
- omap3isp_preview_unregister_entities(&isp->isp_prev);
- omap3isp_resizer_unregister_entities(&isp->isp_res);
- omap3isp_stat_unregister_entities(&isp->isp_aewb);
- omap3isp_stat_unregister_entities(&isp->isp_af);
- omap3isp_stat_unregister_entities(&isp->isp_hist);
-
- v4l2_device_unregister(&isp->v4l2_dev);
- media_device_unregister(&isp->media_dev);
-}
-
-/*
- * isp_register_subdev_group - Register a group of subdevices
- * @isp: OMAP3 ISP device
- * @board_info: I2C subdevs board information array
- *
- * Register all I2C subdevices in the board_info array. The array must be
- * terminated by a NULL entry, and the first entry must be the sensor.
- *
- * Return a pointer to the sensor media entity if it has been successfully
- * registered, or NULL otherwise.
- */
-static struct v4l2_subdev *
-isp_register_subdev_group(struct isp_device *isp,
- struct isp_subdev_i2c_board_info *board_info)
-{
- struct v4l2_subdev *sensor = NULL;
- unsigned int first;
-
- if (board_info->board_info == NULL)
- return NULL;
-
- for (first = 1; board_info->board_info; ++board_info, first = 0) {
- struct v4l2_subdev *subdev;
- struct i2c_adapter *adapter;
-
- adapter = i2c_get_adapter(board_info->i2c_adapter_id);
- if (adapter == NULL) {
- printk(KERN_ERR "%s: Unable to get I2C adapter %d for "
- "device %s\n", __func__,
- board_info->i2c_adapter_id,
- board_info->board_info->type);
- continue;
- }
-
- subdev = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter,
- board_info->board_info, NULL);
- if (subdev == NULL) {
- printk(KERN_ERR "%s: Unable to register subdev %s\n",
- __func__, board_info->board_info->type);
- continue;
- }
-
- if (first)
- sensor = subdev;
- }
-
- return sensor;
-}
-
-static int isp_register_entities(struct isp_device *isp)
-{
- struct isp_platform_data *pdata = isp->pdata;
- struct isp_v4l2_subdevs_group *subdevs;
- int ret;
-
- isp->media_dev.dev = isp->dev;
- strlcpy(isp->media_dev.model, "TI OMAP3 ISP",
- sizeof(isp->media_dev.model));
- isp->media_dev.hw_revision = isp->revision;
- isp->media_dev.link_notify = isp_pipeline_link_notify;
- ret = media_device_register(&isp->media_dev);
- if (ret < 0) {
- printk(KERN_ERR "%s: Media device registration failed (%d)\n",
- __func__, ret);
- return ret;
- }
-
- isp->v4l2_dev.mdev = &isp->media_dev;
- ret = v4l2_device_register(isp->dev, &isp->v4l2_dev);
- if (ret < 0) {
- printk(KERN_ERR "%s: V4L2 device registration failed (%d)\n",
- __func__, ret);
- goto done;
- }
-
- /* Register internal entities */
- ret = omap3isp_ccp2_register_entities(&isp->isp_ccp2, &isp->v4l2_dev);
- if (ret < 0)
- goto done;
-
- ret = omap3isp_csi2_register_entities(&isp->isp_csi2a, &isp->v4l2_dev);
- if (ret < 0)
- goto done;
-
- ret = omap3isp_ccdc_register_entities(&isp->isp_ccdc, &isp->v4l2_dev);
- if (ret < 0)
- goto done;
-
- ret = omap3isp_preview_register_entities(&isp->isp_prev,
- &isp->v4l2_dev);
- if (ret < 0)
- goto done;
-
- ret = omap3isp_resizer_register_entities(&isp->isp_res, &isp->v4l2_dev);
- if (ret < 0)
- goto done;
-
- ret = omap3isp_stat_register_entities(&isp->isp_aewb, &isp->v4l2_dev);
- if (ret < 0)
- goto done;
-
- ret = omap3isp_stat_register_entities(&isp->isp_af, &isp->v4l2_dev);
- if (ret < 0)
- goto done;
-
- ret = omap3isp_stat_register_entities(&isp->isp_hist, &isp->v4l2_dev);
- if (ret < 0)
- goto done;
-
- /* Register external entities */
- for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) {
- struct v4l2_subdev *sensor;
- struct media_entity *input;
- unsigned int flags;
- unsigned int pad;
-
- sensor = isp_register_subdev_group(isp, subdevs->subdevs);
- if (sensor == NULL)
- continue;
-
- sensor->host_priv = subdevs;
-
- /* Connect the sensor to the correct interface module. Parallel
- * sensors are connected directly to the CCDC, while serial
- * sensors are connected to the CSI2a, CCP2b or CSI2c receiver
- * through CSIPHY1 or CSIPHY2.
- */
- switch (subdevs->interface) {
- case ISP_INTERFACE_PARALLEL:
- input = &isp->isp_ccdc.subdev.entity;
- pad = CCDC_PAD_SINK;
- flags = 0;
- break;
-
- case ISP_INTERFACE_CSI2A_PHY2:
- input = &isp->isp_csi2a.subdev.entity;
- pad = CSI2_PAD_SINK;
- flags = MEDIA_LNK_FL_IMMUTABLE
- | MEDIA_LNK_FL_ENABLED;
- break;
-
- case ISP_INTERFACE_CCP2B_PHY1:
- case ISP_INTERFACE_CCP2B_PHY2:
- input = &isp->isp_ccp2.subdev.entity;
- pad = CCP2_PAD_SINK;
- flags = 0;
- break;
-
- case ISP_INTERFACE_CSI2C_PHY1:
- input = &isp->isp_csi2c.subdev.entity;
- pad = CSI2_PAD_SINK;
- flags = MEDIA_LNK_FL_IMMUTABLE
- | MEDIA_LNK_FL_ENABLED;
- break;
-
- default:
- printk(KERN_ERR "%s: invalid interface type %u\n",
- __func__, subdevs->interface);
- ret = -EINVAL;
- goto done;
- }
-
- ret = media_entity_create_link(&sensor->entity, 0, input, pad,
- flags);
- if (ret < 0)
- goto done;
- }
-
- ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
-
-done:
- if (ret < 0)
- isp_unregister_entities(isp);
-
- return ret;
-}
-
-static void isp_cleanup_modules(struct isp_device *isp)
-{
- omap3isp_h3a_aewb_cleanup(isp);
- omap3isp_h3a_af_cleanup(isp);
- omap3isp_hist_cleanup(isp);
- omap3isp_resizer_cleanup(isp);
- omap3isp_preview_cleanup(isp);
- omap3isp_ccdc_cleanup(isp);
- omap3isp_ccp2_cleanup(isp);
- omap3isp_csi2_cleanup(isp);
-}
-
-static int isp_initialize_modules(struct isp_device *isp)
-{
- int ret;
-
- ret = omap3isp_csiphy_init(isp);
- if (ret < 0) {
- dev_err(isp->dev, "CSI PHY initialization failed\n");
- goto error_csiphy;
- }
-
- ret = omap3isp_csi2_init(isp);
- if (ret < 0) {
- dev_err(isp->dev, "CSI2 initialization failed\n");
- goto error_csi2;
- }
-
- ret = omap3isp_ccp2_init(isp);
- if (ret < 0) {
- dev_err(isp->dev, "CCP2 initialization failed\n");
- goto error_ccp2;
- }
-
- ret = omap3isp_ccdc_init(isp);
- if (ret < 0) {
- dev_err(isp->dev, "CCDC initialization failed\n");
- goto error_ccdc;
- }
-
- ret = omap3isp_preview_init(isp);
- if (ret < 0) {
- dev_err(isp->dev, "Preview initialization failed\n");
- goto error_preview;
- }
-
- ret = omap3isp_resizer_init(isp);
- if (ret < 0) {
- dev_err(isp->dev, "Resizer initialization failed\n");
- goto error_resizer;
- }
-
- ret = omap3isp_hist_init(isp);
- if (ret < 0) {
- dev_err(isp->dev, "Histogram initialization failed\n");
- goto error_hist;
- }
-
- ret = omap3isp_h3a_aewb_init(isp);
- if (ret < 0) {
- dev_err(isp->dev, "H3A AEWB initialization failed\n");
- goto error_h3a_aewb;
- }
-
- ret = omap3isp_h3a_af_init(isp);
- if (ret < 0) {
- dev_err(isp->dev, "H3A AF initialization failed\n");
- goto error_h3a_af;
- }
-
- /* Connect the submodules. */
- ret = media_entity_create_link(
- &isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,
- &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
- if (ret < 0)
- goto error_link;
-
- ret = media_entity_create_link(
- &isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE,
- &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
- if (ret < 0)
- goto error_link;
-
- ret = media_entity_create_link(
- &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
- &isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);
- if (ret < 0)
- goto error_link;
-
- ret = media_entity_create_link(
- &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,
- &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
- if (ret < 0)
- goto error_link;
-
- ret = media_entity_create_link(
- &isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,
- &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
- if (ret < 0)
- goto error_link;
-
- ret = media_entity_create_link(
- &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
- &isp->isp_aewb.subdev.entity, 0,
- MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
- if (ret < 0)
- goto error_link;
-
- ret = media_entity_create_link(
- &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
- &isp->isp_af.subdev.entity, 0,
- MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
- if (ret < 0)
- goto error_link;
-
- ret = media_entity_create_link(
- &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
- &isp->isp_hist.subdev.entity, 0,
- MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
- if (ret < 0)
- goto error_link;
-
- return 0;
-
-error_link:
- omap3isp_h3a_af_cleanup(isp);
-error_h3a_af:
- omap3isp_h3a_aewb_cleanup(isp);
-error_h3a_aewb:
- omap3isp_hist_cleanup(isp);
-error_hist:
- omap3isp_resizer_cleanup(isp);
-error_resizer:
- omap3isp_preview_cleanup(isp);
-error_preview:
- omap3isp_ccdc_cleanup(isp);
-error_ccdc:
- omap3isp_ccp2_cleanup(isp);
-error_ccp2:
- omap3isp_csi2_cleanup(isp);
-error_csi2:
-error_csiphy:
- return ret;
-}
-
-/*
- * isp_remove - Remove ISP platform device
- * @pdev: Pointer to ISP platform device
- *
- * Always returns 0.
- */
-static int __devexit isp_remove(struct platform_device *pdev)
-{
- struct isp_device *isp = platform_get_drvdata(pdev);
- int i;
-
- isp_unregister_entities(isp);
- isp_cleanup_modules(isp);
-
- omap3isp_get(isp);
- iommu_detach_device(isp->domain, &pdev->dev);
- iommu_domain_free(isp->domain);
- isp->domain = NULL;
- omap3isp_put(isp);
-
- free_irq(isp->irq_num, isp);
- isp_put_clocks(isp);
-
- for (i = 0; i < OMAP3_ISP_IOMEM_LAST; i++) {
- if (isp->mmio_base[i]) {
- iounmap(isp->mmio_base[i]);
- isp->mmio_base[i] = NULL;
- }
-
- if (isp->mmio_base_phys[i]) {
- release_mem_region(isp->mmio_base_phys[i],
- isp->mmio_size[i]);
- isp->mmio_base_phys[i] = 0;
- }
- }
-
- regulator_put(isp->isp_csiphy1.vdd);
- regulator_put(isp->isp_csiphy2.vdd);
- kfree(isp);
-
- return 0;
-}
-
-static int isp_map_mem_resource(struct platform_device *pdev,
- struct isp_device *isp,
- enum isp_mem_resources res)
-{
- struct resource *mem;
-
- /* request the mem region for the camera registers */
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, res);
- if (!mem) {
- dev_err(isp->dev, "no mem resource?\n");
- return -ENODEV;
- }
-
- if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) {
- dev_err(isp->dev,
- "cannot reserve camera register I/O region\n");
- return -ENODEV;
- }
- isp->mmio_base_phys[res] = mem->start;
- isp->mmio_size[res] = resource_size(mem);
-
- /* map the region */
- isp->mmio_base[res] = ioremap_nocache(isp->mmio_base_phys[res],
- isp->mmio_size[res]);
- if (!isp->mmio_base[res]) {
- dev_err(isp->dev, "cannot map camera register I/O region\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-/*
- * isp_probe - Probe ISP platform device
- * @pdev: Pointer to ISP platform device
- *
- * Returns 0 if successful,
- * -ENOMEM if no memory available,
- * -ENODEV if no platform device resources found
- * or no space for remapping registers,
- * -EINVAL if couldn't install ISR,
- * or clk_get return error value.
- */
-static int __devinit isp_probe(struct platform_device *pdev)
-{
- struct isp_platform_data *pdata = pdev->dev.platform_data;
- struct isp_device *isp;
- int ret;
- int i, m;
-
- if (pdata == NULL)
- return -EINVAL;
-
- isp = kzalloc(sizeof(*isp), GFP_KERNEL);
- if (!isp) {
- dev_err(&pdev->dev, "could not allocate memory\n");
- return -ENOMEM;
- }
-
- isp->autoidle = autoidle;
- isp->platform_cb.set_xclk = isp_set_xclk;
-
- mutex_init(&isp->isp_mutex);
- spin_lock_init(&isp->stat_lock);
-
- isp->dev = &pdev->dev;
- isp->pdata = pdata;
- isp->ref_count = 0;
-
- isp->raw_dmamask = DMA_BIT_MASK(32);
- isp->dev->dma_mask = &isp->raw_dmamask;
- isp->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- platform_set_drvdata(pdev, isp);
-
- /* Regulators */
- isp->isp_csiphy1.vdd = regulator_get(&pdev->dev, "VDD_CSIPHY1");
- isp->isp_csiphy2.vdd = regulator_get(&pdev->dev, "VDD_CSIPHY2");
-
- /* Clocks */
- ret = isp_map_mem_resource(pdev, isp, OMAP3_ISP_IOMEM_MAIN);
- if (ret < 0)
- goto error;
-
- ret = isp_get_clocks(isp);
- if (ret < 0)
- goto error;
-
- if (omap3isp_get(isp) == NULL)
- goto error;
-
- ret = isp_reset(isp);
- if (ret < 0)
- goto error_isp;
-
- /* Memory resources */
- isp->revision = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);
- dev_info(isp->dev, "Revision %d.%d found\n",
- (isp->revision & 0xf0) >> 4, isp->revision & 0x0f);
-
- for (m = 0; m < ARRAY_SIZE(isp_res_maps); m++)
- if (isp->revision == isp_res_maps[m].isp_rev)
- break;
-
- if (m == ARRAY_SIZE(isp_res_maps)) {
- dev_err(isp->dev, "No resource map found for ISP rev %d.%d\n",
- (isp->revision & 0xf0) >> 4, isp->revision & 0xf);
- ret = -ENODEV;
- goto error_isp;
- }
-
- for (i = 1; i < OMAP3_ISP_IOMEM_LAST; i++) {
- if (isp_res_maps[m].map & 1 << i) {
- ret = isp_map_mem_resource(pdev, isp, i);
- if (ret)
- goto error_isp;
- }
- }
-
- isp->domain = iommu_domain_alloc(pdev->dev.bus);
- if (!isp->domain) {
- dev_err(isp->dev, "can't alloc iommu domain\n");
- ret = -ENOMEM;
- goto error_isp;
- }
-
- ret = iommu_attach_device(isp->domain, &pdev->dev);
- if (ret) {
- dev_err(&pdev->dev, "can't attach iommu device: %d\n", ret);
- goto free_domain;
- }
-
- /* Interrupt */
- isp->irq_num = platform_get_irq(pdev, 0);
- if (isp->irq_num <= 0) {
- dev_err(isp->dev, "No IRQ resource\n");
- ret = -ENODEV;
- goto detach_dev;
- }
-
- if (request_irq(isp->irq_num, isp_isr, IRQF_SHARED, "OMAP3 ISP", isp)) {
- dev_err(isp->dev, "Unable to request IRQ\n");
- ret = -EINVAL;
- goto detach_dev;
- }
-
- /* Entities */
- ret = isp_initialize_modules(isp);
- if (ret < 0)
- goto error_irq;
-
- ret = isp_register_entities(isp);
- if (ret < 0)
- goto error_modules;
-
- isp_power_settings(isp, 1);
- omap3isp_put(isp);
-
- return 0;
-
-error_modules:
- isp_cleanup_modules(isp);
-error_irq:
- free_irq(isp->irq_num, isp);
-detach_dev:
- iommu_detach_device(isp->domain, &pdev->dev);
-free_domain:
- iommu_domain_free(isp->domain);
-error_isp:
- omap3isp_put(isp);
-error:
- isp_put_clocks(isp);
-
- for (i = 0; i < OMAP3_ISP_IOMEM_LAST; i++) {
- if (isp->mmio_base[i]) {
- iounmap(isp->mmio_base[i]);
- isp->mmio_base[i] = NULL;
- }
-
- if (isp->mmio_base_phys[i]) {
- release_mem_region(isp->mmio_base_phys[i],
- isp->mmio_size[i]);
- isp->mmio_base_phys[i] = 0;
- }
- }
- regulator_put(isp->isp_csiphy2.vdd);
- regulator_put(isp->isp_csiphy1.vdd);
- platform_set_drvdata(pdev, NULL);
-
- mutex_destroy(&isp->isp_mutex);
- kfree(isp);
-
- return ret;
-}
-
-static const struct dev_pm_ops omap3isp_pm_ops = {
- .prepare = isp_pm_prepare,
- .suspend = isp_pm_suspend,
- .resume = isp_pm_resume,
- .complete = isp_pm_complete,
-};
-
-static struct platform_device_id omap3isp_id_table[] = {
- { "omap3isp", 0 },
- { },
-};
-MODULE_DEVICE_TABLE(platform, omap3isp_id_table);
-
-static struct platform_driver omap3isp_driver = {
- .probe = isp_probe,
- .remove = __devexit_p(isp_remove),
- .id_table = omap3isp_id_table,
- .driver = {
- .owner = THIS_MODULE,
- .name = "omap3isp",
- .pm = &omap3isp_pm_ops,
- },
-};
-
-module_platform_driver(omap3isp_driver);
-
-MODULE_AUTHOR("Nokia Corporation");
-MODULE_DESCRIPTION("TI OMAP3 ISP driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(ISP_VIDEO_DRIVER_VERSION);
diff --git a/drivers/media/video/omap3isp/isp.h b/drivers/media/video/omap3isp/isp.h
deleted file mode 100644
index fc7af3e32ef..00000000000
--- a/drivers/media/video/omap3isp/isp.h
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * isp.h
- *
- * TI OMAP3 ISP - Core
- *
- * Copyright (C) 2009-2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef OMAP3_ISP_CORE_H
-#define OMAP3_ISP_CORE_H
-
-#include <media/omap3isp.h>
-#include <media/v4l2-device.h>
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/wait.h>
-#include <linux/iommu.h>
-#include <plat/iommu.h>
-#include <plat/iovmm.h>
-
-#include "ispstat.h"
-#include "ispccdc.h"
-#include "ispreg.h"
-#include "ispresizer.h"
-#include "isppreview.h"
-#include "ispcsiphy.h"
-#include "ispcsi2.h"
-#include "ispccp2.h"
-
-#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
-
-#define ISP_TOK_TERM 0xFFFFFFFF /*
- * terminating token for ISP
- * modules reg list
- */
-#define to_isp_device(ptr_module) \
- container_of(ptr_module, struct isp_device, isp_##ptr_module)
-#define to_device(ptr_module) \
- (to_isp_device(ptr_module)->dev)
-
-enum isp_mem_resources {
- OMAP3_ISP_IOMEM_MAIN,
- OMAP3_ISP_IOMEM_CCP2,
- OMAP3_ISP_IOMEM_CCDC,
- OMAP3_ISP_IOMEM_HIST,
- OMAP3_ISP_IOMEM_H3A,
- OMAP3_ISP_IOMEM_PREV,
- OMAP3_ISP_IOMEM_RESZ,
- OMAP3_ISP_IOMEM_SBL,
- OMAP3_ISP_IOMEM_CSI2A_REGS1,
- OMAP3_ISP_IOMEM_CSIPHY2,
- OMAP3_ISP_IOMEM_CSI2A_REGS2,
- OMAP3_ISP_IOMEM_CSI2C_REGS1,
- OMAP3_ISP_IOMEM_CSIPHY1,
- OMAP3_ISP_IOMEM_CSI2C_REGS2,
- OMAP3_ISP_IOMEM_LAST
-};
-
-enum isp_sbl_resource {
- OMAP3_ISP_SBL_CSI1_READ = 0x1,
- OMAP3_ISP_SBL_CSI1_WRITE = 0x2,
- OMAP3_ISP_SBL_CSI2A_WRITE = 0x4,
- OMAP3_ISP_SBL_CSI2C_WRITE = 0x8,
- OMAP3_ISP_SBL_CCDC_LSC_READ = 0x10,
- OMAP3_ISP_SBL_CCDC_WRITE = 0x20,
- OMAP3_ISP_SBL_PREVIEW_READ = 0x40,
- OMAP3_ISP_SBL_PREVIEW_WRITE = 0x80,
- OMAP3_ISP_SBL_RESIZER_READ = 0x100,
- OMAP3_ISP_SBL_RESIZER_WRITE = 0x200,
-};
-
-enum isp_subclk_resource {
- OMAP3_ISP_SUBCLK_CCDC = (1 << 0),
- OMAP3_ISP_SUBCLK_H3A = (1 << 1),
- OMAP3_ISP_SUBCLK_HIST = (1 << 2),
- OMAP3_ISP_SUBCLK_PREVIEW = (1 << 3),
- OMAP3_ISP_SUBCLK_RESIZER = (1 << 4),
-};
-
-/* ISP: OMAP 34xx ES 1.0 */
-#define ISP_REVISION_1_0 0x10
-/* ISP2: OMAP 34xx ES 2.0, 2.1 and 3.0 */
-#define ISP_REVISION_2_0 0x20
-/* ISP2P: OMAP 36xx */
-#define ISP_REVISION_15_0 0xF0
-
-/*
- * struct isp_res_mapping - Map ISP io resources to ISP revision.
- * @isp_rev: ISP_REVISION_x_x
- * @map: bitmap for enum isp_mem_resources
- */
-struct isp_res_mapping {
- u32 isp_rev;
- u32 map;
-};
-
-/*
- * struct isp_reg - Structure for ISP register values.
- * @reg: 32-bit Register address.
- * @val: 32-bit Register value.
- */
-struct isp_reg {
- enum isp_mem_resources mmio_range;
- u32 reg;
- u32 val;
-};
-
-struct isp_platform_callback {
- u32 (*set_xclk)(struct isp_device *isp, u32 xclk, u8 xclksel);
- int (*csiphy_config)(struct isp_csiphy *phy,
- struct isp_csiphy_dphy_cfg *dphy,
- struct isp_csiphy_lanes_cfg *lanes);
-};
-
-/*
- * struct isp_device - ISP device structure.
- * @dev: Device pointer specific to the OMAP3 ISP.
- * @revision: Stores current ISP module revision.
- * @irq_num: Currently used IRQ number.
- * @mmio_base: Array with kernel base addresses for ioremapped ISP register
- * regions.
- * @mmio_base_phys: Array with physical L4 bus addresses for ISP register
- * regions.
- * @mmio_size: Array with ISP register regions size in bytes.
- * @raw_dmamask: Raw DMA mask
- * @stat_lock: Spinlock for handling statistics
- * @isp_mutex: Mutex for serializing requests to ISP.
- * @crashed: Bitmask of crashed entities (indexed by entity ID)
- * @has_context: Context has been saved at least once and can be restored.
- * @ref_count: Reference count for handling multiple ISP requests.
- * @cam_ick: Pointer to camera interface clock structure.
- * @cam_mclk: Pointer to camera functional clock structure.
- * @dpll4_m5_ck: Pointer to DPLL4 M5 clock structure.
- * @csi2_fck: Pointer to camera CSI2 complexIO clock structure.
- * @l3_ick: Pointer to OMAP3 L3 bus interface clock.
- * @irq: Currently attached ISP ISR callbacks information structure.
- * @isp_af: Pointer to current settings for ISP AutoFocus SCM.
- * @isp_hist: Pointer to current settings for ISP Histogram SCM.
- * @isp_h3a: Pointer to current settings for ISP Auto Exposure and
- * White Balance SCM.
- * @isp_res: Pointer to current settings for ISP Resizer.
- * @isp_prev: Pointer to current settings for ISP Preview.
- * @isp_ccdc: Pointer to current settings for ISP CCDC.
- * @iommu: Pointer to requested IOMMU instance for ISP.
- * @platform_cb: ISP driver callback function pointers for platform code
- *
- * This structure is used to store the OMAP ISP Information.
- */
-struct isp_device {
- struct v4l2_device v4l2_dev;
- struct media_device media_dev;
- struct device *dev;
- u32 revision;
-
- /* platform HW resources */
- struct isp_platform_data *pdata;
- unsigned int irq_num;
-
- void __iomem *mmio_base[OMAP3_ISP_IOMEM_LAST];
- unsigned long mmio_base_phys[OMAP3_ISP_IOMEM_LAST];
- resource_size_t mmio_size[OMAP3_ISP_IOMEM_LAST];
-
- u64 raw_dmamask;
-
- /* ISP Obj */
- spinlock_t stat_lock; /* common lock for statistic drivers */
- struct mutex isp_mutex; /* For handling ref_count field */
- u32 crashed;
- int has_context;
- int ref_count;
- unsigned int autoidle;
- u32 xclk_divisor[2]; /* Two clocks, a and b. */
-#define ISP_CLK_CAM_ICK 0
-#define ISP_CLK_CAM_MCLK 1
-#define ISP_CLK_DPLL4_M5_CK 2
-#define ISP_CLK_CSI2_FCK 3
-#define ISP_CLK_L3_ICK 4
- struct clk *clock[5];
-
- /* ISP modules */
- struct ispstat isp_af;
- struct ispstat isp_aewb;
- struct ispstat isp_hist;
- struct isp_res_device isp_res;
- struct isp_prev_device isp_prev;
- struct isp_ccdc_device isp_ccdc;
- struct isp_csi2_device isp_csi2a;
- struct isp_csi2_device isp_csi2c;
- struct isp_ccp2_device isp_ccp2;
- struct isp_csiphy isp_csiphy1;
- struct isp_csiphy isp_csiphy2;
-
- unsigned int sbl_resources;
- unsigned int subclk_resources;
-
- struct iommu_domain *domain;
-
- struct isp_platform_callback platform_cb;
-};
-
-#define v4l2_dev_to_isp_device(dev) \
- container_of(dev, struct isp_device, v4l2_dev)
-
-void omap3isp_hist_dma_done(struct isp_device *isp);
-
-void omap3isp_flush(struct isp_device *isp);
-
-int omap3isp_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
- atomic_t *stopping);
-
-int omap3isp_module_sync_is_stopping(wait_queue_head_t *wait,
- atomic_t *stopping);
-
-int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
- enum isp_pipeline_stream_state state);
-void omap3isp_configure_bridge(struct isp_device *isp,
- enum ccdc_input_entity input,
- const struct isp_parallel_platform_data *pdata,
- unsigned int shift);
-
-struct isp_device *omap3isp_get(struct isp_device *isp);
-void omap3isp_put(struct isp_device *isp);
-
-void omap3isp_print_status(struct isp_device *isp);
-
-void omap3isp_sbl_enable(struct isp_device *isp, enum isp_sbl_resource res);
-void omap3isp_sbl_disable(struct isp_device *isp, enum isp_sbl_resource res);
-
-void omap3isp_subclk_enable(struct isp_device *isp,
- enum isp_subclk_resource res);
-void omap3isp_subclk_disable(struct isp_device *isp,
- enum isp_subclk_resource res);
-
-int omap3isp_pipeline_pm_use(struct media_entity *entity, int use);
-
-int omap3isp_register_entities(struct platform_device *pdev,
- struct v4l2_device *v4l2_dev);
-void omap3isp_unregister_entities(struct platform_device *pdev);
-
-/*
- * isp_reg_readl - Read value of an OMAP3 ISP register
- * @dev: Device pointer specific to the OMAP3 ISP.
- * @isp_mmio_range: Range to which the register offset refers to.
- * @reg_offset: Register offset to read from.
- *
- * Returns an unsigned 32 bit value with the required register contents.
- */
-static inline
-u32 isp_reg_readl(struct isp_device *isp, enum isp_mem_resources isp_mmio_range,
- u32 reg_offset)
-{
- return __raw_readl(isp->mmio_base[isp_mmio_range] + reg_offset);
-}
-
-/*
- * isp_reg_writel - Write value to an OMAP3 ISP register
- * @dev: Device pointer specific to the OMAP3 ISP.
- * @reg_value: 32 bit value to write to the register.
- * @isp_mmio_range: Range to which the register offset refers to.
- * @reg_offset: Register offset to write into.
- */
-static inline
-void isp_reg_writel(struct isp_device *isp, u32 reg_value,
- enum isp_mem_resources isp_mmio_range, u32 reg_offset)
-{
- __raw_writel(reg_value, isp->mmio_base[isp_mmio_range] + reg_offset);
-}
-
-/*
- * isp_reg_and - Clear individual bits in an OMAP3 ISP register
- * @dev: Device pointer specific to the OMAP3 ISP.
- * @mmio_range: Range to which the register offset refers to.
- * @reg: Register offset to work on.
- * @clr_bits: 32 bit value which would be cleared in the register.
- */
-static inline
-void isp_reg_clr(struct isp_device *isp, enum isp_mem_resources mmio_range,
- u32 reg, u32 clr_bits)
-{
- u32 v = isp_reg_readl(isp, mmio_range, reg);
-
- isp_reg_writel(isp, v & ~clr_bits, mmio_range, reg);
-}
-
-/*
- * isp_reg_set - Set individual bits in an OMAP3 ISP register
- * @dev: Device pointer specific to the OMAP3 ISP.
- * @mmio_range: Range to which the register offset refers to.
- * @reg: Register offset to work on.
- * @set_bits: 32 bit value which would be set in the register.
- */
-static inline
-void isp_reg_set(struct isp_device *isp, enum isp_mem_resources mmio_range,
- u32 reg, u32 set_bits)
-{
- u32 v = isp_reg_readl(isp, mmio_range, reg);
-
- isp_reg_writel(isp, v | set_bits, mmio_range, reg);
-}
-
-/*
- * isp_reg_clr_set - Clear and set invidial bits in an OMAP3 ISP register
- * @dev: Device pointer specific to the OMAP3 ISP.
- * @mmio_range: Range to which the register offset refers to.
- * @reg: Register offset to work on.
- * @clr_bits: 32 bit value which would be cleared in the register.
- * @set_bits: 32 bit value which would be set in the register.
- *
- * The clear operation is done first, and then the set operation.
- */
-static inline
-void isp_reg_clr_set(struct isp_device *isp, enum isp_mem_resources mmio_range,
- u32 reg, u32 clr_bits, u32 set_bits)
-{
- u32 v = isp_reg_readl(isp, mmio_range, reg);
-
- isp_reg_writel(isp, (v & ~clr_bits) | set_bits, mmio_range, reg);
-}
-
-static inline enum v4l2_buf_type
-isp_pad_buffer_type(const struct v4l2_subdev *subdev, int pad)
-{
- if (pad >= subdev->entity.num_pads)
- return 0;
-
- if (subdev->entity.pads[pad].flags & MEDIA_PAD_FL_SINK)
- return V4L2_BUF_TYPE_VIDEO_OUTPUT;
- else
- return V4L2_BUF_TYPE_VIDEO_CAPTURE;
-}
-
-#endif /* OMAP3_ISP_CORE_H */
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c
deleted file mode 100644
index f1220d3d497..00000000000
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ /dev/null
@@ -1,2535 +0,0 @@
-/*
- * ispccdc.c
- *
- * TI OMAP3 ISP - CCDC module
- *
- * Copyright (C) 2009-2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/module.h>
-#include <linux/uaccess.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <media/v4l2-event.h>
-
-#include "isp.h"
-#include "ispreg.h"
-#include "ispccdc.h"
-
-#define CCDC_MIN_WIDTH 32
-#define CCDC_MIN_HEIGHT 32
-
-static struct v4l2_mbus_framefmt *
-__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
- unsigned int pad, enum v4l2_subdev_format_whence which);
-
-static const unsigned int ccdc_fmts[] = {
- V4L2_MBUS_FMT_Y8_1X8,
- V4L2_MBUS_FMT_Y10_1X10,
- V4L2_MBUS_FMT_Y12_1X12,
- V4L2_MBUS_FMT_SGRBG8_1X8,
- V4L2_MBUS_FMT_SRGGB8_1X8,
- V4L2_MBUS_FMT_SBGGR8_1X8,
- V4L2_MBUS_FMT_SGBRG8_1X8,
- V4L2_MBUS_FMT_SGRBG10_1X10,
- V4L2_MBUS_FMT_SRGGB10_1X10,
- V4L2_MBUS_FMT_SBGGR10_1X10,
- V4L2_MBUS_FMT_SGBRG10_1X10,
- V4L2_MBUS_FMT_SGRBG12_1X12,
- V4L2_MBUS_FMT_SRGGB12_1X12,
- V4L2_MBUS_FMT_SBGGR12_1X12,
- V4L2_MBUS_FMT_SGBRG12_1X12,
-};
-
-/*
- * ccdc_print_status - Print current CCDC Module register values.
- * @ccdc: Pointer to ISP CCDC device.
- *
- * Also prints other debug information stored in the CCDC module.
- */
-#define CCDC_PRINT_REGISTER(isp, name)\
- dev_dbg(isp->dev, "###CCDC " #name "=0x%08x\n", \
- isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_##name))
-
-static void ccdc_print_status(struct isp_ccdc_device *ccdc)
-{
- struct isp_device *isp = to_isp_device(ccdc);
-
- dev_dbg(isp->dev, "-------------CCDC Register dump-------------\n");
-
- CCDC_PRINT_REGISTER(isp, PCR);
- CCDC_PRINT_REGISTER(isp, SYN_MODE);
- CCDC_PRINT_REGISTER(isp, HD_VD_WID);
- CCDC_PRINT_REGISTER(isp, PIX_LINES);
- CCDC_PRINT_REGISTER(isp, HORZ_INFO);
- CCDC_PRINT_REGISTER(isp, VERT_START);
- CCDC_PRINT_REGISTER(isp, VERT_LINES);
- CCDC_PRINT_REGISTER(isp, CULLING);
- CCDC_PRINT_REGISTER(isp, HSIZE_OFF);
- CCDC_PRINT_REGISTER(isp, SDOFST);
- CCDC_PRINT_REGISTER(isp, SDR_ADDR);
- CCDC_PRINT_REGISTER(isp, CLAMP);
- CCDC_PRINT_REGISTER(isp, DCSUB);
- CCDC_PRINT_REGISTER(isp, COLPTN);
- CCDC_PRINT_REGISTER(isp, BLKCMP);
- CCDC_PRINT_REGISTER(isp, FPC);
- CCDC_PRINT_REGISTER(isp, FPC_ADDR);
- CCDC_PRINT_REGISTER(isp, VDINT);
- CCDC_PRINT_REGISTER(isp, ALAW);
- CCDC_PRINT_REGISTER(isp, REC656IF);
- CCDC_PRINT_REGISTER(isp, CFG);
- CCDC_PRINT_REGISTER(isp, FMTCFG);
- CCDC_PRINT_REGISTER(isp, FMT_HORZ);
- CCDC_PRINT_REGISTER(isp, FMT_VERT);
- CCDC_PRINT_REGISTER(isp, PRGEVEN0);
- CCDC_PRINT_REGISTER(isp, PRGEVEN1);
- CCDC_PRINT_REGISTER(isp, PRGODD0);
- CCDC_PRINT_REGISTER(isp, PRGODD1);
- CCDC_PRINT_REGISTER(isp, VP_OUT);
- CCDC_PRINT_REGISTER(isp, LSC_CONFIG);
- CCDC_PRINT_REGISTER(isp, LSC_INITIAL);
- CCDC_PRINT_REGISTER(isp, LSC_TABLE_BASE);
- CCDC_PRINT_REGISTER(isp, LSC_TABLE_OFFSET);
-
- dev_dbg(isp->dev, "--------------------------------------------\n");
-}
-
-/*
- * omap3isp_ccdc_busy - Get busy state of the CCDC.
- * @ccdc: Pointer to ISP CCDC device.
- */
-int omap3isp_ccdc_busy(struct isp_ccdc_device *ccdc)
-{
- struct isp_device *isp = to_isp_device(ccdc);
-
- return isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR) &
- ISPCCDC_PCR_BUSY;
-}
-
-/* -----------------------------------------------------------------------------
- * Lens Shading Compensation
- */
-
-/*
- * ccdc_lsc_validate_config - Check that LSC configuration is valid.
- * @ccdc: Pointer to ISP CCDC device.
- * @lsc_cfg: the LSC configuration to check.
- *
- * Returns 0 if the LSC configuration is valid, or -EINVAL if invalid.
- */
-static int ccdc_lsc_validate_config(struct isp_ccdc_device *ccdc,
- struct omap3isp_ccdc_lsc_config *lsc_cfg)
-{
- struct isp_device *isp = to_isp_device(ccdc);
- struct v4l2_mbus_framefmt *format;
- unsigned int paxel_width, paxel_height;
- unsigned int paxel_shift_x, paxel_shift_y;
- unsigned int min_width, min_height, min_size;
- unsigned int input_width, input_height;
-
- paxel_shift_x = lsc_cfg->gain_mode_m;
- paxel_shift_y = lsc_cfg->gain_mode_n;
-
- if ((paxel_shift_x < 2) || (paxel_shift_x > 6) ||
- (paxel_shift_y < 2) || (paxel_shift_y > 6)) {
- dev_dbg(isp->dev, "CCDC: LSC: Invalid paxel size\n");
- return -EINVAL;
- }
-
- if (lsc_cfg->offset & 3) {
- dev_dbg(isp->dev, "CCDC: LSC: Offset must be a multiple of "
- "4\n");
- return -EINVAL;
- }
-
- if ((lsc_cfg->initial_x & 1) || (lsc_cfg->initial_y & 1)) {
- dev_dbg(isp->dev, "CCDC: LSC: initial_x and y must be even\n");
- return -EINVAL;
- }
-
- format = __ccdc_get_format(ccdc, NULL, CCDC_PAD_SINK,
- V4L2_SUBDEV_FORMAT_ACTIVE);
- input_width = format->width;
- input_height = format->height;
-
- /* Calculate minimum bytesize for validation */
- paxel_width = 1 << paxel_shift_x;
- min_width = ((input_width + lsc_cfg->initial_x + paxel_width - 1)
- >> paxel_shift_x) + 1;
-
- paxel_height = 1 << paxel_shift_y;
- min_height = ((input_height + lsc_cfg->initial_y + paxel_height - 1)
- >> paxel_shift_y) + 1;
-
- min_size = 4 * min_width * min_height;
- if (min_size > lsc_cfg->size) {
- dev_dbg(isp->dev, "CCDC: LSC: too small table\n");
- return -EINVAL;
- }
- if (lsc_cfg->offset < (min_width * 4)) {
- dev_dbg(isp->dev, "CCDC: LSC: Offset is too small\n");
- return -EINVAL;
- }
- if ((lsc_cfg->size / lsc_cfg->offset) < min_height) {
- dev_dbg(isp->dev, "CCDC: LSC: Wrong size/offset combination\n");
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * ccdc_lsc_program_table - Program Lens Shading Compensation table address.
- * @ccdc: Pointer to ISP CCDC device.
- */
-static void ccdc_lsc_program_table(struct isp_ccdc_device *ccdc, u32 addr)
-{
- isp_reg_writel(to_isp_device(ccdc), addr,
- OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_TABLE_BASE);
-}
-
-/*
- * ccdc_lsc_setup_regs - Configures the lens shading compensation module
- * @ccdc: Pointer to ISP CCDC device.
- */
-static void ccdc_lsc_setup_regs(struct isp_ccdc_device *ccdc,
- struct omap3isp_ccdc_lsc_config *cfg)
-{
- struct isp_device *isp = to_isp_device(ccdc);
- int reg;
-
- isp_reg_writel(isp, cfg->offset, OMAP3_ISP_IOMEM_CCDC,
- ISPCCDC_LSC_TABLE_OFFSET);
-
- reg = 0;
- reg |= cfg->gain_mode_n << ISPCCDC_LSC_GAIN_MODE_N_SHIFT;
- reg |= cfg->gain_mode_m << ISPCCDC_LSC_GAIN_MODE_M_SHIFT;
- reg |= cfg->gain_format << ISPCCDC_LSC_GAIN_FORMAT_SHIFT;
- isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG);
-
- reg = 0;
- reg &= ~ISPCCDC_LSC_INITIAL_X_MASK;
- reg |= cfg->initial_x << ISPCCDC_LSC_INITIAL_X_SHIFT;
- reg &= ~ISPCCDC_LSC_INITIAL_Y_MASK;
- reg |= cfg->initial_y << ISPCCDC_LSC_INITIAL_Y_SHIFT;
- isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_CCDC,
- ISPCCDC_LSC_INITIAL);
-}
-
-static int ccdc_lsc_wait_prefetch(struct isp_ccdc_device *ccdc)
-{
- struct isp_device *isp = to_isp_device(ccdc);
- unsigned int wait;
-
- isp_reg_writel(isp, IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ,
- OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
-
- /* timeout 1 ms */
- for (wait = 0; wait < 1000; wait++) {
- if (isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS) &
- IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ) {
- isp_reg_writel(isp, IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ,
- OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
- return 0;
- }
-
- rmb();
- udelay(1);
- }
-
- return -ETIMEDOUT;
-}
-
-/*
- * __ccdc_lsc_enable - Enables/Disables the Lens Shading Compensation module.
- * @ccdc: Pointer to ISP CCDC device.
- * @enable: 0 Disables LSC, 1 Enables LSC.
- */
-static int __ccdc_lsc_enable(struct isp_ccdc_device *ccdc, int enable)
-{
- struct isp_device *isp = to_isp_device(ccdc);
- const struct v4l2_mbus_framefmt *format =
- __ccdc_get_format(ccdc, NULL, CCDC_PAD_SINK,
- V4L2_SUBDEV_FORMAT_ACTIVE);
-
- if ((format->code != V4L2_MBUS_FMT_SGRBG10_1X10) &&
- (format->code != V4L2_MBUS_FMT_SRGGB10_1X10) &&
- (format->code != V4L2_MBUS_FMT_SBGGR10_1X10) &&
- (format->code != V4L2_MBUS_FMT_SGBRG10_1X10))
- return -EINVAL;
-
- if (enable)
- omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_LSC_READ);
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG,
- ISPCCDC_LSC_ENABLE, enable ? ISPCCDC_LSC_ENABLE : 0);
-
- if (enable) {
- if (ccdc_lsc_wait_prefetch(ccdc) < 0) {
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC,
- ISPCCDC_LSC_CONFIG, ISPCCDC_LSC_ENABLE);
- ccdc->lsc.state = LSC_STATE_STOPPED;
- dev_warn(to_device(ccdc), "LSC prefecth timeout\n");
- return -ETIMEDOUT;
- }
- ccdc->lsc.state = LSC_STATE_RUNNING;
- } else {
- ccdc->lsc.state = LSC_STATE_STOPPING;
- }
-
- return 0;
-}
-
-static int ccdc_lsc_busy(struct isp_ccdc_device *ccdc)
-{
- struct isp_device *isp = to_isp_device(ccdc);
-
- return isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG) &
- ISPCCDC_LSC_BUSY;
-}
-
-/* __ccdc_lsc_configure - Apply a new configuration to the LSC engine
- * @ccdc: Pointer to ISP CCDC device
- * @req: New configuration request
- *
- * context: in_interrupt()
- */
-static int __ccdc_lsc_configure(struct isp_ccdc_device *ccdc,
- struct ispccdc_lsc_config_req *req)
-{
- if (!req->enable)
- return -EINVAL;
-
- if (ccdc_lsc_validate_config(ccdc, &req->config) < 0) {
- dev_dbg(to_device(ccdc), "Discard LSC configuration\n");
- return -EINVAL;
- }
-
- if (ccdc_lsc_busy(ccdc))
- return -EBUSY;
-
- ccdc_lsc_setup_regs(ccdc, &req->config);
- ccdc_lsc_program_table(ccdc, req->table);
- return 0;
-}
-
-/*
- * ccdc_lsc_error_handler - Handle LSC prefetch error scenario.
- * @ccdc: Pointer to ISP CCDC device.
- *
- * Disables LSC, and defers enablement to shadow registers update time.
- */
-static void ccdc_lsc_error_handler(struct isp_ccdc_device *ccdc)
-{
- struct isp_device *isp = to_isp_device(ccdc);
- /*
- * From OMAP3 TRM: When this event is pending, the module
- * goes into transparent mode (output =input). Normal
- * operation can be resumed at the start of the next frame
- * after:
- * 1) Clearing this event
- * 2) Disabling the LSC module
- * 3) Enabling it
- */
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG,
- ISPCCDC_LSC_ENABLE);
- ccdc->lsc.state = LSC_STATE_STOPPED;
-}
-
-static void ccdc_lsc_free_request(struct isp_ccdc_device *ccdc,
- struct ispccdc_lsc_config_req *req)
-{
- struct isp_device *isp = to_isp_device(ccdc);
-
- if (req == NULL)
- return;
-
- if (req->iovm)
- dma_unmap_sg(isp->dev, req->iovm->sgt->sgl,
- req->iovm->sgt->nents, DMA_TO_DEVICE);
- if (req->table)
- omap_iommu_vfree(isp->domain, isp->dev, req->table);
- kfree(req);
-}
-
-static void ccdc_lsc_free_queue(struct isp_ccdc_device *ccdc,
- struct list_head *queue)
-{
- struct ispccdc_lsc_config_req *req, *n;
- unsigned long flags;
-
- spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
- list_for_each_entry_safe(req, n, queue, list) {
- list_del(&req->list);
- spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
- ccdc_lsc_free_request(ccdc, req);
- spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
- }
- spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
-}
-
-static void ccdc_lsc_free_table_work(struct work_struct *work)
-{
- struct isp_ccdc_device *ccdc;
- struct ispccdc_lsc *lsc;
-
- lsc = container_of(work, struct ispccdc_lsc, table_work);
- ccdc = container_of(lsc, struct isp_ccdc_device, lsc);
-
- ccdc_lsc_free_queue(ccdc, &lsc->free_queue);
-}
-
-/*
- * ccdc_lsc_config - Configure the LSC module from a userspace request
- *
- * Store the request LSC configuration in the LSC engine request pointer. The
- * configuration will be applied to the hardware when the CCDC will be enabled,
- * or at the next LSC interrupt if the CCDC is already running.
- */
-static int ccdc_lsc_config(struct isp_ccdc_device *ccdc,
- struct omap3isp_ccdc_update_config *config)
-{
- struct isp_device *isp = to_isp_device(ccdc);
- struct ispccdc_lsc_config_req *req;
- unsigned long flags;
- void *table;
- u16 update;
- int ret;
-
- update = config->update &
- (OMAP3ISP_CCDC_CONFIG_LSC | OMAP3ISP_CCDC_TBL_LSC);
- if (!update)
- return 0;
-
- if (update != (OMAP3ISP_CCDC_CONFIG_LSC | OMAP3ISP_CCDC_TBL_LSC)) {
- dev_dbg(to_device(ccdc), "%s: Both LSC configuration and table "
- "need to be supplied\n", __func__);
- return -EINVAL;
- }
-
- req = kzalloc(sizeof(*req), GFP_KERNEL);
- if (req == NULL)
- return -ENOMEM;
-
- if (config->flag & OMAP3ISP_CCDC_CONFIG_LSC) {
- if (copy_from_user(&req->config, config->lsc_cfg,
- sizeof(req->config))) {
- ret = -EFAULT;
- goto done;
- }
-
- req->enable = 1;
-
- req->table = omap_iommu_vmalloc(isp->domain, isp->dev, 0,
- req->config.size, IOMMU_FLAG);
- if (IS_ERR_VALUE(req->table)) {
- req->table = 0;
- ret = -ENOMEM;
- goto done;
- }
-
- req->iovm = omap_find_iovm_area(isp->dev, req->table);
- if (req->iovm == NULL) {
- ret = -ENOMEM;
- goto done;
- }
-
- if (!dma_map_sg(isp->dev, req->iovm->sgt->sgl,
- req->iovm->sgt->nents, DMA_TO_DEVICE)) {
- ret = -ENOMEM;
- req->iovm = NULL;
- goto done;
- }
-
- dma_sync_sg_for_cpu(isp->dev, req->iovm->sgt->sgl,
- req->iovm->sgt->nents, DMA_TO_DEVICE);
-
- table = omap_da_to_va(isp->dev, req->table);
- if (copy_from_user(table, config->lsc, req->config.size)) {
- ret = -EFAULT;
- goto done;
- }
-
- dma_sync_sg_for_device(isp->dev, req->iovm->sgt->sgl,
- req->iovm->sgt->nents, DMA_TO_DEVICE);
- }
-
- spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
- if (ccdc->lsc.request) {
- list_add_tail(&ccdc->lsc.request->list, &ccdc->lsc.free_queue);
- schedule_work(&ccdc->lsc.table_work);
- }
- ccdc->lsc.request = req;
- spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
-
- ret = 0;
-
-done:
- if (ret < 0)
- ccdc_lsc_free_request(ccdc, req);
-
- return ret;
-}
-
-static inline int ccdc_lsc_is_configured(struct isp_ccdc_device *ccdc)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
- if (ccdc->lsc.active) {
- spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
- return 1;
- }
- spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
- return 0;
-}
-
-static int ccdc_lsc_enable(struct isp_ccdc_device *ccdc)
-{
- struct ispccdc_lsc *lsc = &ccdc->lsc;
-
- if (lsc->state != LSC_STATE_STOPPED)
- return -EINVAL;
-
- if (lsc->active) {
- list_add_tail(&lsc->active->list, &lsc->free_queue);
- lsc->active = NULL;
- }
-
- if (__ccdc_lsc_configure(ccdc, lsc->request) < 0) {
- omap3isp_sbl_disable(to_isp_device(ccdc),
- OMAP3_ISP_SBL_CCDC_LSC_READ);
- list_add_tail(&lsc->request->list, &lsc->free_queue);
- lsc->request = NULL;
- goto done;
- }
-
- lsc->active = lsc->request;
- lsc->request = NULL;
- __ccdc_lsc_enable(ccdc, 1);
-
-done:
- if (!list_empty(&lsc->free_queue))
- schedule_work(&lsc->table_work);
-
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Parameters configuration
- */
-
-/*
- * ccdc_configure_clamp - Configure optical-black or digital clamping
- * @ccdc: Pointer to ISP CCDC device.
- *
- * The CCDC performs either optical-black or digital clamp. Configure and enable
- * the selected clamp method.
- */
-static void ccdc_configure_clamp(struct isp_ccdc_device *ccdc)
-{
- struct isp_device *isp = to_isp_device(ccdc);
- u32 clamp;
-
- if (ccdc->obclamp) {
- clamp = ccdc->clamp.obgain << ISPCCDC_CLAMP_OBGAIN_SHIFT;
- clamp |= ccdc->clamp.oblen << ISPCCDC_CLAMP_OBSLEN_SHIFT;
- clamp |= ccdc->clamp.oblines << ISPCCDC_CLAMP_OBSLN_SHIFT;
- clamp |= ccdc->clamp.obstpixel << ISPCCDC_CLAMP_OBST_SHIFT;
- isp_reg_writel(isp, clamp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CLAMP);
- } else {
- isp_reg_writel(isp, ccdc->clamp.dcsubval,
- OMAP3_ISP_IOMEM_CCDC, ISPCCDC_DCSUB);
- }
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CLAMP,
- ISPCCDC_CLAMP_CLAMPEN,
- ccdc->obclamp ? ISPCCDC_CLAMP_CLAMPEN : 0);
-}
-
-/*
- * ccdc_configure_fpc - Configure Faulty Pixel Correction
- * @ccdc: Pointer to ISP CCDC device.
- */
-static void ccdc_configure_fpc(struct isp_ccdc_device *ccdc)
-{
- struct isp_device *isp = to_isp_device(ccdc);
-
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC, ISPCCDC_FPC_FPCEN);
-
- if (!ccdc->fpc_en)
- return;
-
- isp_reg_writel(isp, ccdc->fpc.fpcaddr, OMAP3_ISP_IOMEM_CCDC,
- ISPCCDC_FPC_ADDR);
- /* The FPNUM field must be set before enabling FPC. */
- isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT),
- OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC);
- isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT) |
- ISPCCDC_FPC_FPCEN, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC);
-}
-
-/*
- * ccdc_configure_black_comp - Configure Black Level Compensation.
- * @ccdc: Pointer to ISP CCDC device.
- */
-static void ccdc_configure_black_comp(struct isp_ccdc_device *ccdc)
-{
- struct isp_device *isp = to_isp_device(ccdc);
- u32 blcomp;
-
- blcomp = ccdc->blcomp.b_mg << ISPCCDC_BLKCMP_B_MG_SHIFT;
- blcomp |= ccdc->blcomp.gb_g << ISPCCDC_BLKCMP_GB_G_SHIFT;
- blcomp |= ccdc->blcomp.gr_cy << ISPCCDC_BLKCMP_GR_CY_SHIFT;
- blcomp |= ccdc->blcomp.r_ye << ISPCCDC_BLKCMP_R_YE_SHIFT;
-
- isp_reg_writel(isp, blcomp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_BLKCMP);
-}
-
-/*
- * ccdc_configure_lpf - Configure Low-Pass Filter (LPF).
- * @ccdc: Pointer to ISP CCDC device.
- */
-static void ccdc_configure_lpf(struct isp_ccdc_device *ccdc)
-{
- struct isp_device *isp = to_isp_device(ccdc);
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE,
- ISPCCDC_SYN_MODE_LPF,
- ccdc->lpf ? ISPCCDC_SYN_MODE_LPF : 0);
-}
-
-/*
- * ccdc_configure_alaw - Configure A-law compression.
- * @ccdc: Pointer to ISP CCDC device.
- */
-static void ccdc_configure_alaw(struct isp_ccdc_device *ccdc)
-{
- struct isp_device *isp = to_isp_device(ccdc);
- u32 alaw = 0;
-
- switch (ccdc->syncif.datsz) {
- case 8:
- return;
-
- case 10:
- alaw = ISPCCDC_ALAW_GWDI_9_0;
- break;
- case 11:
- alaw = ISPCCDC_ALAW_GWDI_10_1;
- break;
- case 12:
- alaw = ISPCCDC_ALAW_GWDI_11_2;
- break;
- case 13:
- alaw = ISPCCDC_ALAW_GWDI_12_3;
- break;
- }
-
- if (ccdc->alaw)
- alaw |= ISPCCDC_ALAW_CCDTBL;
-
- isp_reg_writel(isp, alaw, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_ALAW);
-}
-
-/*
- * ccdc_config_imgattr - Configure sensor image specific attributes.
- * @ccdc: Pointer to ISP CCDC device.
- * @colptn: Color pattern of the sensor.
- */
-static void ccdc_config_imgattr(struct isp_ccdc_device *ccdc, u32 colptn)
-{
- struct isp_device *isp = to_isp_device(ccdc);
-
- isp_reg_writel(isp, colptn, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_COLPTN);
-}
-
-/*
- * ccdc_config - Set CCDC configuration from userspace
- * @ccdc: Pointer to ISP CCDC device.
- * @userspace_add: Structure containing CCDC configuration sent from userspace.
- *
- * Returns 0 if successful, -EINVAL if the pointer to the configuration
- * structure is null, or the copy_from_user function fails to copy user space
- * memory to kernel space memory.
- */
-static int ccdc_config(struct isp_ccdc_device *ccdc,
- struct omap3isp_ccdc_update_config *ccdc_struct)
-{
- struct isp_device *isp = to_isp_device(ccdc);
- unsigned long flags;
-
- spin_lock_irqsave(&ccdc->lock, flags);
- ccdc->shadow_update = 1;
- spin_unlock_irqrestore(&ccdc->lock, flags);
-
- if (OMAP3ISP_CCDC_ALAW & ccdc_struct->update) {
- ccdc->alaw = !!(OMAP3ISP_CCDC_ALAW & ccdc_struct->flag);
- ccdc->update |= OMAP3ISP_CCDC_ALAW;
- }
-
- if (OMAP3ISP_CCDC_LPF & ccdc_struct->update) {
- ccdc->lpf = !!(OMAP3ISP_CCDC_LPF & ccdc_struct->flag);
- ccdc->update |= OMAP3ISP_CCDC_LPF;
- }
-
- if (OMAP3ISP_CCDC_BLCLAMP & ccdc_struct->update) {
- if (copy_from_user(&ccdc->clamp, ccdc_struct->bclamp,
- sizeof(ccdc->clamp))) {
- ccdc->shadow_update = 0;
- return -EFAULT;
- }
-
- ccdc->obclamp = !!(OMAP3ISP_CCDC_BLCLAMP & ccdc_struct->flag);
- ccdc->update |= OMAP3ISP_CCDC_BLCLAMP;
- }
-
- if (OMAP3ISP_CCDC_BCOMP & ccdc_struct->update) {
- if (copy_from_user(&ccdc->blcomp, ccdc_struct->blcomp,
- sizeof(ccdc->blcomp))) {
- ccdc->shadow_update = 0;
- return -EFAULT;
- }
-
- ccdc->update |= OMAP3ISP_CCDC_BCOMP;
- }
-
- ccdc->shadow_update = 0;
-
- if (OMAP3ISP_CCDC_FPC & ccdc_struct->update) {
- u32 table_old = 0;
- u32 table_new;
- u32 size;
-
- if (ccdc->state != ISP_PIPELINE_STREAM_STOPPED)
- return -EBUSY;
-
- ccdc->fpc_en = !!(OMAP3ISP_CCDC_FPC & ccdc_struct->flag);
-
- if (ccdc->fpc_en) {
- if (copy_from_user(&ccdc->fpc, ccdc_struct->fpc,
- sizeof(ccdc->fpc)))
- return -EFAULT;
-
- /*
- * table_new must be 64-bytes aligned, but it's
- * already done by omap_iommu_vmalloc().
- */
- size = ccdc->fpc.fpnum * 4;
- table_new = omap_iommu_vmalloc(isp->domain, isp->dev,
- 0, size, IOMMU_FLAG);
- if (IS_ERR_VALUE(table_new))
- return -ENOMEM;
-
- if (copy_from_user(omap_da_to_va(isp->dev, table_new),
- (__force void __user *)
- ccdc->fpc.fpcaddr, size)) {
- omap_iommu_vfree(isp->domain, isp->dev,
- table_new);
- return -EFAULT;
- }
-
- table_old = ccdc->fpc.fpcaddr;
- ccdc->fpc.fpcaddr = table_new;
- }
-
- ccdc_configure_fpc(ccdc);
- if (table_old != 0)
- omap_iommu_vfree(isp->domain, isp->dev, table_old);
- }
-
- return ccdc_lsc_config(ccdc, ccdc_struct);
-}
-
-static void ccdc_apply_controls(struct isp_ccdc_device *ccdc)
-{
- if (ccdc->update & OMAP3ISP_CCDC_ALAW) {
- ccdc_configure_alaw(ccdc);
- ccdc->update &= ~OMAP3ISP_CCDC_ALAW;
- }
-
- if (ccdc->update & OMAP3ISP_CCDC_LPF) {
- ccdc_configure_lpf(ccdc);
- ccdc->update &= ~OMAP3ISP_CCDC_LPF;
- }
-
- if (ccdc->update & OMAP3ISP_CCDC_BLCLAMP) {
- ccdc_configure_clamp(ccdc);
- ccdc->update &= ~OMAP3ISP_CCDC_BLCLAMP;
- }
-
- if (ccdc->update & OMAP3ISP_CCDC_BCOMP) {
- ccdc_configure_black_comp(ccdc);
- ccdc->update &= ~OMAP3ISP_CCDC_BCOMP;
- }
-}
-
-/*
- * omap3isp_ccdc_restore_context - Restore values of the CCDC module registers
- * @dev: Pointer to ISP device
- */
-void omap3isp_ccdc_restore_context(struct isp_device *isp)
-{
- struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
-
- isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, ISPCCDC_CFG_VDLC);
-
- ccdc->update = OMAP3ISP_CCDC_ALAW | OMAP3ISP_CCDC_LPF
- | OMAP3ISP_CCDC_BLCLAMP | OMAP3ISP_CCDC_BCOMP;
- ccdc_apply_controls(ccdc);
- ccdc_configure_fpc(ccdc);
-}
-
-/* -----------------------------------------------------------------------------
- * Format- and pipeline-related configuration helpers
- */
-
-/*
- * ccdc_config_vp - Configure the Video Port.
- * @ccdc: Pointer to ISP CCDC device.
- */
-static void ccdc_config_vp(struct isp_ccdc_device *ccdc)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
- struct isp_device *isp = to_isp_device(ccdc);
- unsigned long l3_ick = pipe->l3_ick;
- unsigned int max_div = isp->revision == ISP_REVISION_15_0 ? 64 : 8;
- unsigned int div = 0;
- u32 fmtcfg_vp;
-
- fmtcfg_vp = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG)
- & ~(ISPCCDC_FMTCFG_VPIN_MASK | ISPCCDC_FMTCFG_VPIF_FRQ_MASK);
-
- switch (ccdc->syncif.datsz) {
- case 8:
- case 10:
- fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_9_0;
- break;
- case 11:
- fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_10_1;
- break;
- case 12:
- fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_11_2;
- break;
- case 13:
- fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_12_3;
- break;
- };
-
- if (pipe->input)
- div = DIV_ROUND_UP(l3_ick, pipe->max_rate);
- else if (pipe->external_rate)
- div = l3_ick / pipe->external_rate;
-
- div = clamp(div, 2U, max_div);
- fmtcfg_vp |= (div - 2) << ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT;
-
- isp_reg_writel(isp, fmtcfg_vp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG);
-}
-
-/*
- * ccdc_enable_vp - Enable Video Port.
- * @ccdc: Pointer to ISP CCDC device.
- * @enable: 0 Disables VP, 1 Enables VP
- *
- * This is needed for outputting image to Preview, H3A and HIST ISP submodules.
- */
-static void ccdc_enable_vp(struct isp_ccdc_device *ccdc, u8 enable)
-{
- struct isp_device *isp = to_isp_device(ccdc);
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG,
- ISPCCDC_FMTCFG_VPEN, enable ? ISPCCDC_FMTCFG_VPEN : 0);
-}
-
-/*
- * ccdc_config_outlineoffset - Configure memory saving output line offset
- * @ccdc: Pointer to ISP CCDC device.
- * @offset: Address offset to start a new line. Must be twice the
- * Output width and aligned on 32 byte boundary
- * @oddeven: Specifies the odd/even line pattern to be chosen to store the
- * output.
- * @numlines: Set the value 0-3 for +1-4lines, 4-7 for -1-4lines.
- *
- * - Configures the output line offset when stored in memory
- * - Sets the odd/even line pattern to store the output
- * (EVENEVEN (1), ODDEVEN (2), EVENODD (3), ODDODD (4))
- * - Configures the number of even and odd line fields in case of rearranging
- * the lines.
- */
-static void ccdc_config_outlineoffset(struct isp_ccdc_device *ccdc,
- u32 offset, u8 oddeven, u8 numlines)
-{
- struct isp_device *isp = to_isp_device(ccdc);
-
- isp_reg_writel(isp, offset & 0xffff,
- OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HSIZE_OFF);
-
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
- ISPCCDC_SDOFST_FINV);
-
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
- ISPCCDC_SDOFST_FOFST_4L);
-
- switch (oddeven) {
- case EVENEVEN:
- isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
- (numlines & 0x7) << ISPCCDC_SDOFST_LOFST0_SHIFT);
- break;
- case ODDEVEN:
- isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
- (numlines & 0x7) << ISPCCDC_SDOFST_LOFST1_SHIFT);
- break;
- case EVENODD:
- isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
- (numlines & 0x7) << ISPCCDC_SDOFST_LOFST2_SHIFT);
- break;
- case ODDODD:
- isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
- (numlines & 0x7) << ISPCCDC_SDOFST_LOFST3_SHIFT);
- break;
- default:
- break;
- }
-}
-
-/*
- * ccdc_set_outaddr - Set memory address to save output image
- * @ccdc: Pointer to ISP CCDC device.
- * @addr: ISP MMU Mapped 32-bit memory address aligned on 32 byte boundary.
- *
- * Sets the memory address where the output will be saved.
- */
-static void ccdc_set_outaddr(struct isp_ccdc_device *ccdc, u32 addr)
-{
- struct isp_device *isp = to_isp_device(ccdc);
-
- isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR);
-}
-
-/*
- * omap3isp_ccdc_max_rate - Calculate maximum input data rate based on the input
- * @ccdc: Pointer to ISP CCDC device.
- * @max_rate: Maximum calculated data rate.
- *
- * Returns in *max_rate less value between calculated and passed
- */
-void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
- unsigned int *max_rate)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
- unsigned int rate;
-
- if (pipe == NULL)
- return;
-
- /*
- * TRM says that for parallel sensors the maximum data rate
- * should be 90% form L3/2 clock, otherwise just L3/2.
- */
- if (ccdc->input == CCDC_INPUT_PARALLEL)
- rate = pipe->l3_ick / 2 * 9 / 10;
- else
- rate = pipe->l3_ick / 2;
-
- *max_rate = min(*max_rate, rate);
-}
-
-/*
- * ccdc_config_sync_if - Set CCDC sync interface configuration
- * @ccdc: Pointer to ISP CCDC device.
- * @syncif: Structure containing the sync parameters like field state, CCDC in
- * master/slave mode, raw/yuv data, polarity of data, field, hs, vs
- * signals.
- */
-static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
- struct ispccdc_syncif *syncif)
-{
- struct isp_device *isp = to_isp_device(ccdc);
- u32 syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC,
- ISPCCDC_SYN_MODE);
-
- syn_mode |= ISPCCDC_SYN_MODE_VDHDEN;
-
- if (syncif->fldstat)
- syn_mode |= ISPCCDC_SYN_MODE_FLDSTAT;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_FLDSTAT;
-
- syn_mode &= ~ISPCCDC_SYN_MODE_DATSIZ_MASK;
- switch (syncif->datsz) {
- case 8:
- syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_8;
- break;
- case 10:
- syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_10;
- break;
- case 11:
- syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_11;
- break;
- case 12:
- syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_12;
- break;
- };
-
- if (syncif->fldmode)
- syn_mode |= ISPCCDC_SYN_MODE_FLDMODE;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_FLDMODE;
-
- if (syncif->datapol)
- syn_mode |= ISPCCDC_SYN_MODE_DATAPOL;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_DATAPOL;
-
- if (syncif->fldpol)
- syn_mode |= ISPCCDC_SYN_MODE_FLDPOL;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_FLDPOL;
-
- if (syncif->hdpol)
- syn_mode |= ISPCCDC_SYN_MODE_HDPOL;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_HDPOL;
-
- if (syncif->vdpol)
- syn_mode |= ISPCCDC_SYN_MODE_VDPOL;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_VDPOL;
-
- if (syncif->ccdc_mastermode) {
- syn_mode |= ISPCCDC_SYN_MODE_FLDOUT | ISPCCDC_SYN_MODE_VDHDOUT;
- isp_reg_writel(isp,
- syncif->hs_width << ISPCCDC_HD_VD_WID_HDW_SHIFT
- | syncif->vs_width << ISPCCDC_HD_VD_WID_VDW_SHIFT,
- OMAP3_ISP_IOMEM_CCDC,
- ISPCCDC_HD_VD_WID);
-
- isp_reg_writel(isp,
- syncif->ppln << ISPCCDC_PIX_LINES_PPLN_SHIFT
- | syncif->hlprf << ISPCCDC_PIX_LINES_HLPRF_SHIFT,
- OMAP3_ISP_IOMEM_CCDC,
- ISPCCDC_PIX_LINES);
- } else
- syn_mode &= ~(ISPCCDC_SYN_MODE_FLDOUT |
- ISPCCDC_SYN_MODE_VDHDOUT);
-
- isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
-
- if (!syncif->bt_r656_en)
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_REC656IF,
- ISPCCDC_REC656IF_R656ON);
-}
-
-/* CCDC formats descriptions */
-static const u32 ccdc_sgrbg_pattern =
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
-
-static const u32 ccdc_srggb_pattern =
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
-
-static const u32 ccdc_sbggr_pattern =
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
-
-static const u32 ccdc_sgbrg_pattern =
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
- ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
- ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
- ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
- ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
-
-static void ccdc_configure(struct isp_ccdc_device *ccdc)
-{
- struct isp_device *isp = to_isp_device(ccdc);
- struct isp_parallel_platform_data *pdata = NULL;
- struct v4l2_subdev *sensor;
- struct v4l2_mbus_framefmt *format;
- const struct v4l2_rect *crop;
- const struct isp_format_info *fmt_info;
- struct v4l2_subdev_format fmt_src;
- unsigned int depth_out;
- unsigned int depth_in = 0;
- struct media_pad *pad;
- unsigned long flags;
- unsigned int shift;
- u32 syn_mode;
- u32 ccdc_pattern;
-
- pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]);
- sensor = media_entity_to_v4l2_subdev(pad->entity);
- if (ccdc->input == CCDC_INPUT_PARALLEL)
- pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv)
- ->bus.parallel;
-
- /* Compute shift value for lane shifter to configure the bridge. */
- fmt_src.pad = pad->index;
- fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- if (!v4l2_subdev_call(sensor, pad, get_fmt, NULL, &fmt_src)) {
- fmt_info = omap3isp_video_format_info(fmt_src.format.code);
- depth_in = fmt_info->bpp;
- }
-
- fmt_info = omap3isp_video_format_info
- (isp->isp_ccdc.formats[CCDC_PAD_SINK].code);
- depth_out = fmt_info->bpp;
-
- shift = depth_in - depth_out;
- omap3isp_configure_bridge(isp, ccdc->input, pdata, shift);
-
- ccdc->syncif.datsz = depth_out;
- ccdc->syncif.hdpol = pdata ? pdata->hs_pol : 0;
- ccdc->syncif.vdpol = pdata ? pdata->vs_pol : 0;
- ccdc_config_sync_if(ccdc, &ccdc->syncif);
-
- /* CCDC_PAD_SINK */
- format = &ccdc->formats[CCDC_PAD_SINK];
-
- syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
-
- /* Use the raw, unprocessed data when writing to memory. The H3A and
- * histogram modules are still fed with lens shading corrected data.
- */
- syn_mode &= ~ISPCCDC_SYN_MODE_VP2SDR;
-
- if (ccdc->output & CCDC_OUTPUT_MEMORY)
- syn_mode |= ISPCCDC_SYN_MODE_WEN;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_WEN;
-
- if (ccdc->output & CCDC_OUTPUT_RESIZER)
- syn_mode |= ISPCCDC_SYN_MODE_SDR2RSZ;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ;
-
- /* Use PACK8 mode for 1byte per pixel formats. */
- if (omap3isp_video_format_info(format->code)->bpp <= 8)
- syn_mode |= ISPCCDC_SYN_MODE_PACK8;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_PACK8;
-
- isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
-
- /* Mosaic filter */
- switch (format->code) {
- case V4L2_MBUS_FMT_SRGGB10_1X10:
- case V4L2_MBUS_FMT_SRGGB12_1X12:
- ccdc_pattern = ccdc_srggb_pattern;
- break;
- case V4L2_MBUS_FMT_SBGGR10_1X10:
- case V4L2_MBUS_FMT_SBGGR12_1X12:
- ccdc_pattern = ccdc_sbggr_pattern;
- break;
- case V4L2_MBUS_FMT_SGBRG10_1X10:
- case V4L2_MBUS_FMT_SGBRG12_1X12:
- ccdc_pattern = ccdc_sgbrg_pattern;
- break;
- default:
- /* Use GRBG */
- ccdc_pattern = ccdc_sgrbg_pattern;
- break;
- }
- ccdc_config_imgattr(ccdc, ccdc_pattern);
-
- /* Generate VD0 on the last line of the image and VD1 on the
- * 2/3 height line.
- */
- isp_reg_writel(isp, ((format->height - 2) << ISPCCDC_VDINT_0_SHIFT) |
- ((format->height * 2 / 3) << ISPCCDC_VDINT_1_SHIFT),
- OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VDINT);
-
- /* CCDC_PAD_SOURCE_OF */
- crop = &ccdc->crop;
-
- isp_reg_writel(isp, (crop->left << ISPCCDC_HORZ_INFO_SPH_SHIFT) |
- ((crop->width - 1) << ISPCCDC_HORZ_INFO_NPH_SHIFT),
- OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO);
- isp_reg_writel(isp, crop->top << ISPCCDC_VERT_START_SLV0_SHIFT,
- OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_START);
- isp_reg_writel(isp, (crop->height - 1)
- << ISPCCDC_VERT_LINES_NLV_SHIFT,
- OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_LINES);
-
- ccdc_config_outlineoffset(ccdc, ccdc->video_out.bpl_value, 0, 0);
-
- /* CCDC_PAD_SOURCE_VP */
- format = &ccdc->formats[CCDC_PAD_SOURCE_VP];
-
- isp_reg_writel(isp, (0 << ISPCCDC_FMT_HORZ_FMTSPH_SHIFT) |
- (format->width << ISPCCDC_FMT_HORZ_FMTLNH_SHIFT),
- OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_HORZ);
- isp_reg_writel(isp, (0 << ISPCCDC_FMT_VERT_FMTSLV_SHIFT) |
- ((format->height + 1) << ISPCCDC_FMT_VERT_FMTLNV_SHIFT),
- OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_VERT);
-
- isp_reg_writel(isp, (format->width << ISPCCDC_VP_OUT_HORZ_NUM_SHIFT) |
- (format->height << ISPCCDC_VP_OUT_VERT_NUM_SHIFT),
- OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VP_OUT);
-
- spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
- if (ccdc->lsc.request == NULL)
- goto unlock;
-
- WARN_ON(ccdc->lsc.active);
-
- /* Get last good LSC configuration. If it is not supported for
- * the current active resolution discard it.
- */
- if (ccdc->lsc.active == NULL &&
- __ccdc_lsc_configure(ccdc, ccdc->lsc.request) == 0) {
- ccdc->lsc.active = ccdc->lsc.request;
- } else {
- list_add_tail(&ccdc->lsc.request->list, &ccdc->lsc.free_queue);
- schedule_work(&ccdc->lsc.table_work);
- }
-
- ccdc->lsc.request = NULL;
-
-unlock:
- spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
-
- ccdc_apply_controls(ccdc);
-}
-
-static void __ccdc_enable(struct isp_ccdc_device *ccdc, int enable)
-{
- struct isp_device *isp = to_isp_device(ccdc);
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR,
- ISPCCDC_PCR_EN, enable ? ISPCCDC_PCR_EN : 0);
-}
-
-static int ccdc_disable(struct isp_ccdc_device *ccdc)
-{
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&ccdc->lock, flags);
- if (ccdc->state == ISP_PIPELINE_STREAM_CONTINUOUS)
- ccdc->stopping = CCDC_STOP_REQUEST;
- spin_unlock_irqrestore(&ccdc->lock, flags);
-
- ret = wait_event_timeout(ccdc->wait,
- ccdc->stopping == CCDC_STOP_FINISHED,
- msecs_to_jiffies(2000));
- if (ret == 0) {
- ret = -ETIMEDOUT;
- dev_warn(to_device(ccdc), "CCDC stop timeout!\n");
- }
-
- omap3isp_sbl_disable(to_isp_device(ccdc), OMAP3_ISP_SBL_CCDC_LSC_READ);
-
- mutex_lock(&ccdc->ioctl_lock);
- ccdc_lsc_free_request(ccdc, ccdc->lsc.request);
- ccdc->lsc.request = ccdc->lsc.active;
- ccdc->lsc.active = NULL;
- cancel_work_sync(&ccdc->lsc.table_work);
- ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue);
- mutex_unlock(&ccdc->ioctl_lock);
-
- ccdc->stopping = CCDC_STOP_NOT_REQUESTED;
-
- return ret > 0 ? 0 : ret;
-}
-
-static void ccdc_enable(struct isp_ccdc_device *ccdc)
-{
- if (ccdc_lsc_is_configured(ccdc))
- __ccdc_lsc_enable(ccdc, 1);
- __ccdc_enable(ccdc, 1);
-}
-
-/* -----------------------------------------------------------------------------
- * Interrupt handling
- */
-
-/*
- * ccdc_sbl_busy - Poll idle state of CCDC and related SBL memory write bits
- * @ccdc: Pointer to ISP CCDC device.
- *
- * Returns zero if the CCDC is idle and the image has been written to
- * memory, too.
- */
-static int ccdc_sbl_busy(struct isp_ccdc_device *ccdc)
-{
- struct isp_device *isp = to_isp_device(ccdc);
-
- return omap3isp_ccdc_busy(ccdc)
- | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_0) &
- ISPSBL_CCDC_WR_0_DATA_READY)
- | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_1) &
- ISPSBL_CCDC_WR_0_DATA_READY)
- | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_2) &
- ISPSBL_CCDC_WR_0_DATA_READY)
- | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_3) &
- ISPSBL_CCDC_WR_0_DATA_READY);
-}
-
-/*
- * ccdc_sbl_wait_idle - Wait until the CCDC and related SBL are idle
- * @ccdc: Pointer to ISP CCDC device.
- * @max_wait: Max retry count in us for wait for idle/busy transition.
- */
-static int ccdc_sbl_wait_idle(struct isp_ccdc_device *ccdc,
- unsigned int max_wait)
-{
- unsigned int wait = 0;
-
- if (max_wait == 0)
- max_wait = 10000; /* 10 ms */
-
- for (wait = 0; wait <= max_wait; wait++) {
- if (!ccdc_sbl_busy(ccdc))
- return 0;
-
- rmb();
- udelay(1);
- }
-
- return -EBUSY;
-}
-
-/* __ccdc_handle_stopping - Handle CCDC and/or LSC stopping sequence
- * @ccdc: Pointer to ISP CCDC device.
- * @event: Pointing which event trigger handler
- *
- * Return 1 when the event and stopping request combination is satisfied,
- * zero otherwise.
- */
-static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event)
-{
- int rval = 0;
-
- switch ((ccdc->stopping & 3) | event) {
- case CCDC_STOP_REQUEST | CCDC_EVENT_VD1:
- if (ccdc->lsc.state != LSC_STATE_STOPPED)
- __ccdc_lsc_enable(ccdc, 0);
- __ccdc_enable(ccdc, 0);
- ccdc->stopping = CCDC_STOP_EXECUTED;
- return 1;
-
- case CCDC_STOP_EXECUTED | CCDC_EVENT_VD0:
- ccdc->stopping |= CCDC_STOP_CCDC_FINISHED;
- if (ccdc->lsc.state == LSC_STATE_STOPPED)
- ccdc->stopping |= CCDC_STOP_LSC_FINISHED;
- rval = 1;
- break;
-
- case CCDC_STOP_EXECUTED | CCDC_EVENT_LSC_DONE:
- ccdc->stopping |= CCDC_STOP_LSC_FINISHED;
- rval = 1;
- break;
-
- case CCDC_STOP_EXECUTED | CCDC_EVENT_VD1:
- return 1;
- }
-
- if (ccdc->stopping == CCDC_STOP_FINISHED) {
- wake_up(&ccdc->wait);
- rval = 1;
- }
-
- return rval;
-}
-
-static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
- struct video_device *vdev = ccdc->subdev.devnode;
- struct v4l2_event event;
-
- /* Frame number propagation */
- atomic_inc(&pipe->frame_number);
-
- memset(&event, 0, sizeof(event));
- event.type = V4L2_EVENT_FRAME_SYNC;
- event.u.frame_sync.frame_sequence = atomic_read(&pipe->frame_number);
-
- v4l2_event_queue(vdev, &event);
-}
-
-/*
- * ccdc_lsc_isr - Handle LSC events
- * @ccdc: Pointer to ISP CCDC device.
- * @events: LSC events
- */
-static void ccdc_lsc_isr(struct isp_ccdc_device *ccdc, u32 events)
-{
- unsigned long flags;
-
- if (events & IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ) {
- struct isp_pipeline *pipe =
- to_isp_pipeline(&ccdc->subdev.entity);
-
- ccdc_lsc_error_handler(ccdc);
- pipe->error = true;
- dev_dbg(to_device(ccdc), "lsc prefetch error\n");
- }
-
- if (!(events & IRQ0STATUS_CCDC_LSC_DONE_IRQ))
- return;
-
- /* LSC_DONE interrupt occur, there are two cases
- * 1. stopping for reconfiguration
- * 2. stopping because of STREAM OFF command
- */
- spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
-
- if (ccdc->lsc.state == LSC_STATE_STOPPING)
- ccdc->lsc.state = LSC_STATE_STOPPED;
-
- if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_LSC_DONE))
- goto done;
-
- if (ccdc->lsc.state != LSC_STATE_RECONFIG)
- goto done;
-
- /* LSC is in STOPPING state, change to the new state */
- ccdc->lsc.state = LSC_STATE_STOPPED;
-
- /* This is an exception. Start of frame and LSC_DONE interrupt
- * have been received on the same time. Skip this event and wait
- * for better times.
- */
- if (events & IRQ0STATUS_HS_VS_IRQ)
- goto done;
-
- /* The LSC engine is stopped at this point. Enable it if there's a
- * pending request.
- */
- if (ccdc->lsc.request == NULL)
- goto done;
-
- ccdc_lsc_enable(ccdc);
-
-done:
- spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
-}
-
-static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
- struct isp_device *isp = to_isp_device(ccdc);
- struct isp_buffer *buffer;
- int restart = 0;
-
- /* The CCDC generates VD0 interrupts even when disabled (the datasheet
- * doesn't explicitly state if that's supposed to happen or not, so it
- * can be considered as a hardware bug or as a feature, but we have to
- * deal with it anyway). Disabling the CCDC when no buffer is available
- * would thus not be enough, we need to handle the situation explicitly.
- */
- if (list_empty(&ccdc->video_out.dmaqueue))
- goto done;
-
- /* We're in continuous mode, and memory writes were disabled due to a
- * buffer underrun. Reenable them now that we have a buffer. The buffer
- * address has been set in ccdc_video_queue.
- */
- if (ccdc->state == ISP_PIPELINE_STREAM_CONTINUOUS && ccdc->underrun) {
- restart = 1;
- ccdc->underrun = 0;
- goto done;
- }
-
- if (ccdc_sbl_wait_idle(ccdc, 1000)) {
- dev_info(isp->dev, "CCDC won't become idle!\n");
- goto done;
- }
-
- buffer = omap3isp_video_buffer_next(&ccdc->video_out);
- if (buffer != NULL) {
- ccdc_set_outaddr(ccdc, buffer->isp_addr);
- restart = 1;
- }
-
- pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
-
- if (ccdc->state == ISP_PIPELINE_STREAM_SINGLESHOT &&
- isp_pipeline_ready(pipe))
- omap3isp_pipeline_set_stream(pipe,
- ISP_PIPELINE_STREAM_SINGLESHOT);
-
-done:
- return restart;
-}
-
-/*
- * ccdc_vd0_isr - Handle VD0 event
- * @ccdc: Pointer to ISP CCDC device.
- *
- * Executes LSC deferred enablement before next frame starts.
- */
-static void ccdc_vd0_isr(struct isp_ccdc_device *ccdc)
-{
- unsigned long flags;
- int restart = 0;
-
- if (ccdc->output & CCDC_OUTPUT_MEMORY)
- restart = ccdc_isr_buffer(ccdc);
-
- spin_lock_irqsave(&ccdc->lock, flags);
- if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_VD0)) {
- spin_unlock_irqrestore(&ccdc->lock, flags);
- return;
- }
-
- if (!ccdc->shadow_update)
- ccdc_apply_controls(ccdc);
- spin_unlock_irqrestore(&ccdc->lock, flags);
-
- if (restart)
- ccdc_enable(ccdc);
-}
-
-/*
- * ccdc_vd1_isr - Handle VD1 event
- * @ccdc: Pointer to ISP CCDC device.
- */
-static void ccdc_vd1_isr(struct isp_ccdc_device *ccdc)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
-
- /*
- * Depending on the CCDC pipeline state, CCDC stopping should be
- * handled differently. In SINGLESHOT we emulate an internal CCDC
- * stopping because the CCDC hw works only in continuous mode.
- * When CONTINUOUS pipeline state is used and the CCDC writes it's
- * data to memory the CCDC and LSC are stopped immediately but
- * without change the CCDC stopping state machine. The CCDC
- * stopping state machine should be used only when user request
- * for stopping is received (SINGLESHOT is an exeption).
- */
- switch (ccdc->state) {
- case ISP_PIPELINE_STREAM_SINGLESHOT:
- ccdc->stopping = CCDC_STOP_REQUEST;
- break;
-
- case ISP_PIPELINE_STREAM_CONTINUOUS:
- if (ccdc->output & CCDC_OUTPUT_MEMORY) {
- if (ccdc->lsc.state != LSC_STATE_STOPPED)
- __ccdc_lsc_enable(ccdc, 0);
- __ccdc_enable(ccdc, 0);
- }
- break;
-
- case ISP_PIPELINE_STREAM_STOPPED:
- break;
- }
-
- if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_VD1))
- goto done;
-
- if (ccdc->lsc.request == NULL)
- goto done;
-
- /*
- * LSC need to be reconfigured. Stop it here and on next LSC_DONE IRQ
- * do the appropriate changes in registers
- */
- if (ccdc->lsc.state == LSC_STATE_RUNNING) {
- __ccdc_lsc_enable(ccdc, 0);
- ccdc->lsc.state = LSC_STATE_RECONFIG;
- goto done;
- }
-
- /* LSC has been in STOPPED state, enable it */
- if (ccdc->lsc.state == LSC_STATE_STOPPED)
- ccdc_lsc_enable(ccdc);
-
-done:
- spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
-}
-
-/*
- * omap3isp_ccdc_isr - Configure CCDC during interframe time.
- * @ccdc: Pointer to ISP CCDC device.
- * @events: CCDC events
- */
-int omap3isp_ccdc_isr(struct isp_ccdc_device *ccdc, u32 events)
-{
- if (ccdc->state == ISP_PIPELINE_STREAM_STOPPED)
- return 0;
-
- if (events & IRQ0STATUS_CCDC_VD1_IRQ)
- ccdc_vd1_isr(ccdc);
-
- ccdc_lsc_isr(ccdc, events);
-
- if (events & IRQ0STATUS_CCDC_VD0_IRQ)
- ccdc_vd0_isr(ccdc);
-
- if (events & IRQ0STATUS_HS_VS_IRQ)
- ccdc_hs_vs_isr(ccdc);
-
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * ISP video operations
- */
-
-static int ccdc_video_queue(struct isp_video *video, struct isp_buffer *buffer)
-{
- struct isp_ccdc_device *ccdc = &video->isp->isp_ccdc;
-
- if (!(ccdc->output & CCDC_OUTPUT_MEMORY))
- return -ENODEV;
-
- ccdc_set_outaddr(ccdc, buffer->isp_addr);
-
- /* We now have a buffer queued on the output, restart the pipeline
- * on the next CCDC interrupt if running in continuous mode (or when
- * starting the stream).
- */
- ccdc->underrun = 1;
-
- return 0;
-}
-
-static const struct isp_video_operations ccdc_video_ops = {
- .queue = ccdc_video_queue,
-};
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev operations
- */
-
-/*
- * ccdc_ioctl - CCDC module private ioctl's
- * @sd: ISP CCDC V4L2 subdevice
- * @cmd: ioctl command
- * @arg: ioctl argument
- *
- * Return 0 on success or a negative error code otherwise.
- */
-static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
- struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
- int ret;
-
- switch (cmd) {
- case VIDIOC_OMAP3ISP_CCDC_CFG:
- mutex_lock(&ccdc->ioctl_lock);
- ret = ccdc_config(ccdc, arg);
- mutex_unlock(&ccdc->ioctl_lock);
- break;
-
- default:
- return -ENOIOCTLCMD;
- }
-
- return ret;
-}
-
-static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
-{
- if (sub->type != V4L2_EVENT_FRAME_SYNC)
- return -EINVAL;
-
- /* line number is zero at frame start */
- if (sub->id != 0)
- return -EINVAL;
-
- return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
-}
-
-static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
-{
- return v4l2_event_unsubscribe(fh, sub);
-}
-
-/*
- * ccdc_set_stream - Enable/Disable streaming on the CCDC module
- * @sd: ISP CCDC V4L2 subdevice
- * @enable: Enable/disable stream
- *
- * When writing to memory, the CCDC hardware can't be enabled without a memory
- * buffer to write to. As the s_stream operation is called in response to a
- * STREAMON call without any buffer queued yet, just update the enabled field
- * and return immediately. The CCDC will be enabled in ccdc_isr_buffer().
- *
- * When not writing to memory enable the CCDC immediately.
- */
-static int ccdc_set_stream(struct v4l2_subdev *sd, int enable)
-{
- struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
- struct isp_device *isp = to_isp_device(ccdc);
- int ret = 0;
-
- if (ccdc->state == ISP_PIPELINE_STREAM_STOPPED) {
- if (enable == ISP_PIPELINE_STREAM_STOPPED)
- return 0;
-
- omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_CCDC);
- isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG,
- ISPCCDC_CFG_VDLC);
-
- ccdc_configure(ccdc);
-
- /* TODO: Don't configure the video port if all of its output
- * links are inactive.
- */
- ccdc_config_vp(ccdc);
- ccdc_enable_vp(ccdc, 1);
- ccdc_print_status(ccdc);
- }
-
- switch (enable) {
- case ISP_PIPELINE_STREAM_CONTINUOUS:
- if (ccdc->output & CCDC_OUTPUT_MEMORY)
- omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
-
- if (ccdc->underrun || !(ccdc->output & CCDC_OUTPUT_MEMORY))
- ccdc_enable(ccdc);
-
- ccdc->underrun = 0;
- break;
-
- case ISP_PIPELINE_STREAM_SINGLESHOT:
- if (ccdc->output & CCDC_OUTPUT_MEMORY &&
- ccdc->state != ISP_PIPELINE_STREAM_SINGLESHOT)
- omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
-
- ccdc_enable(ccdc);
- break;
-
- case ISP_PIPELINE_STREAM_STOPPED:
- ret = ccdc_disable(ccdc);
- if (ccdc->output & CCDC_OUTPUT_MEMORY)
- omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
- omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_CCDC);
- ccdc->underrun = 0;
- break;
- }
-
- ccdc->state = enable;
- return ret;
-}
-
-static struct v4l2_mbus_framefmt *
-__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
- unsigned int pad, enum v4l2_subdev_format_whence which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_format(fh, pad);
- else
- return &ccdc->formats[pad];
-}
-
-static struct v4l2_rect *
-__ccdc_get_crop(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
- enum v4l2_subdev_format_whence which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_crop(fh, CCDC_PAD_SOURCE_OF);
- else
- return &ccdc->crop;
-}
-
-/*
- * ccdc_try_format - Try video format on a pad
- * @ccdc: ISP CCDC device
- * @fh : V4L2 subdev file handle
- * @pad: Pad number
- * @fmt: Format
- */
-static void
-ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
- unsigned int pad, struct v4l2_mbus_framefmt *fmt,
- enum v4l2_subdev_format_whence which)
-{
- struct v4l2_mbus_framefmt *format;
- const struct isp_format_info *info;
- unsigned int width = fmt->width;
- unsigned int height = fmt->height;
- struct v4l2_rect *crop;
- unsigned int i;
-
- switch (pad) {
- case CCDC_PAD_SINK:
- /* TODO: If the CCDC output formatter pad is connected directly
- * to the resizer, only YUV formats can be used.
- */
- for (i = 0; i < ARRAY_SIZE(ccdc_fmts); i++) {
- if (fmt->code == ccdc_fmts[i])
- break;
- }
-
- /* If not found, use SGRBG10 as default */
- if (i >= ARRAY_SIZE(ccdc_fmts))
- fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
-
- /* Clamp the input size. */
- fmt->width = clamp_t(u32, width, 32, 4096);
- fmt->height = clamp_t(u32, height, 32, 4096);
- break;
-
- case CCDC_PAD_SOURCE_OF:
- format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
- memcpy(fmt, format, sizeof(*fmt));
-
- /* Hardcode the output size to the crop rectangle size. */
- crop = __ccdc_get_crop(ccdc, fh, which);
- fmt->width = crop->width;
- fmt->height = crop->height;
- break;
-
- case CCDC_PAD_SOURCE_VP:
- format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
- memcpy(fmt, format, sizeof(*fmt));
-
- /* The video port interface truncates the data to 10 bits. */
- info = omap3isp_video_format_info(fmt->code);
- fmt->code = info->truncated;
-
- /* The number of lines that can be clocked out from the video
- * port output must be at least one line less than the number
- * of input lines.
- */
- fmt->width = clamp_t(u32, width, 32, fmt->width);
- fmt->height = clamp_t(u32, height, 32, fmt->height - 1);
- break;
- }
-
- /* Data is written to memory unpacked, each 10-bit or 12-bit pixel is
- * stored on 2 bytes.
- */
- fmt->colorspace = V4L2_COLORSPACE_SRGB;
- fmt->field = V4L2_FIELD_NONE;
-}
-
-/*
- * ccdc_try_crop - Validate a crop rectangle
- * @ccdc: ISP CCDC device
- * @sink: format on the sink pad
- * @crop: crop rectangle to be validated
- */
-static void ccdc_try_crop(struct isp_ccdc_device *ccdc,
- const struct v4l2_mbus_framefmt *sink,
- struct v4l2_rect *crop)
-{
- const struct isp_format_info *info;
- unsigned int max_width;
-
- /* For Bayer formats, restrict left/top and width/height to even values
- * to keep the Bayer pattern.
- */
- info = omap3isp_video_format_info(sink->code);
- if (info->flavor != V4L2_MBUS_FMT_Y8_1X8) {
- crop->left &= ~1;
- crop->top &= ~1;
- }
-
- crop->left = clamp_t(u32, crop->left, 0, sink->width - CCDC_MIN_WIDTH);
- crop->top = clamp_t(u32, crop->top, 0, sink->height - CCDC_MIN_HEIGHT);
-
- /* The data formatter truncates the number of horizontal output pixels
- * to a multiple of 16. To avoid clipping data, allow callers to request
- * an output size bigger than the input size up to the nearest multiple
- * of 16.
- */
- max_width = (sink->width - crop->left + 15) & ~15;
- crop->width = clamp_t(u32, crop->width, CCDC_MIN_WIDTH, max_width)
- & ~15;
- crop->height = clamp_t(u32, crop->height, CCDC_MIN_HEIGHT,
- sink->height - crop->top);
-
- /* Odd width/height values don't make sense for Bayer formats. */
- if (info->flavor != V4L2_MBUS_FMT_Y8_1X8) {
- crop->width &= ~1;
- crop->height &= ~1;
- }
-}
-
-/*
- * ccdc_enum_mbus_code - Handle pixel format enumeration
- * @sd : pointer to v4l2 subdev structure
- * @fh : V4L2 subdev file handle
- * @code : pointer to v4l2_subdev_mbus_code_enum structure
- * return -EINVAL or zero on success
- */
-static int ccdc_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
-
- switch (code->pad) {
- case CCDC_PAD_SINK:
- if (code->index >= ARRAY_SIZE(ccdc_fmts))
- return -EINVAL;
-
- code->code = ccdc_fmts[code->index];
- break;
-
- case CCDC_PAD_SOURCE_OF:
- case CCDC_PAD_SOURCE_VP:
- /* No format conversion inside CCDC */
- if (code->index != 0)
- return -EINVAL;
-
- format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK,
- V4L2_SUBDEV_FORMAT_TRY);
-
- code->code = format->code;
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int ccdc_enum_frame_size(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_frame_size_enum *fse)
-{
- struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt format;
-
- if (fse->index != 0)
- return -EINVAL;
-
- format.code = fse->code;
- format.width = 1;
- format.height = 1;
- ccdc_try_format(ccdc, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
- fse->min_width = format.width;
- fse->min_height = format.height;
-
- if (format.code != fse->code)
- return -EINVAL;
-
- format.code = fse->code;
- format.width = -1;
- format.height = -1;
- ccdc_try_format(ccdc, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
- fse->max_width = format.width;
- fse->max_height = format.height;
-
- return 0;
-}
-
-/*
- * ccdc_get_selection - Retrieve a selection rectangle on a pad
- * @sd: ISP CCDC V4L2 subdevice
- * @fh: V4L2 subdev file handle
- * @sel: Selection rectangle
- *
- * The only supported rectangles are the crop rectangles on the output formatter
- * source pad.
- *
- * Return 0 on success or a negative error code otherwise.
- */
-static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
-
- if (sel->pad != CCDC_PAD_SOURCE_OF)
- return -EINVAL;
-
- switch (sel->target) {
- case V4L2_SEL_TGT_CROP_BOUNDS:
- sel->r.left = 0;
- sel->r.top = 0;
- sel->r.width = INT_MAX;
- sel->r.height = INT_MAX;
-
- format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, sel->which);
- ccdc_try_crop(ccdc, format, &sel->r);
- break;
-
- case V4L2_SEL_TGT_CROP:
- sel->r = *__ccdc_get_crop(ccdc, fh, sel->which);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * ccdc_set_selection - Set a selection rectangle on a pad
- * @sd: ISP CCDC V4L2 subdevice
- * @fh: V4L2 subdev file handle
- * @sel: Selection rectangle
- *
- * The only supported rectangle is the actual crop rectangle on the output
- * formatter source pad.
- *
- * Return 0 on success or a negative error code otherwise.
- */
-static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
-
- if (sel->target != V4L2_SEL_TGT_CROP ||
- sel->pad != CCDC_PAD_SOURCE_OF)
- return -EINVAL;
-
- /* The crop rectangle can't be changed while streaming. */
- if (ccdc->state != ISP_PIPELINE_STREAM_STOPPED)
- return -EBUSY;
-
- /* Modifying the crop rectangle always changes the format on the source
- * pad. If the KEEP_CONFIG flag is set, just return the current crop
- * rectangle.
- */
- if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) {
- sel->r = *__ccdc_get_crop(ccdc, fh, sel->which);
- return 0;
- }
-
- format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, sel->which);
- ccdc_try_crop(ccdc, format, &sel->r);
- *__ccdc_get_crop(ccdc, fh, sel->which) = sel->r;
-
- /* Update the source format. */
- format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF, sel->which);
- ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_OF, format, sel->which);
-
- return 0;
-}
-
-/*
- * ccdc_get_format - Retrieve the video format on a pad
- * @sd : ISP CCDC V4L2 subdevice
- * @fh : V4L2 subdev file handle
- * @fmt: Format
- *
- * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
- * to the format type.
- */
-static int ccdc_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
-
- format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which);
- if (format == NULL)
- return -EINVAL;
-
- fmt->format = *format;
- return 0;
-}
-
-/*
- * ccdc_set_format - Set the video format on a pad
- * @sd : ISP CCDC V4L2 subdevice
- * @fh : V4L2 subdev file handle
- * @fmt: Format
- *
- * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
- * to the format type.
- */
-static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
- struct v4l2_rect *crop;
-
- format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which);
- if (format == NULL)
- return -EINVAL;
-
- ccdc_try_format(ccdc, fh, fmt->pad, &fmt->format, fmt->which);
- *format = fmt->format;
-
- /* Propagate the format from sink to source */
- if (fmt->pad == CCDC_PAD_SINK) {
- /* Reset the crop rectangle. */
- crop = __ccdc_get_crop(ccdc, fh, fmt->which);
- crop->left = 0;
- crop->top = 0;
- crop->width = fmt->format.width;
- crop->height = fmt->format.height;
-
- ccdc_try_crop(ccdc, &fmt->format, crop);
-
- /* Update the source formats. */
- format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF,
- fmt->which);
- *format = fmt->format;
- ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_OF, format,
- fmt->which);
-
- format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_VP,
- fmt->which);
- *format = fmt->format;
- ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_VP, format,
- fmt->which);
- }
-
- return 0;
-}
-
-/*
- * Decide whether desired output pixel code can be obtained with
- * the lane shifter by shifting the input pixel code.
- * @in: input pixelcode to shifter
- * @out: output pixelcode from shifter
- * @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0]
- *
- * return true if the combination is possible
- * return false otherwise
- */
-static bool ccdc_is_shiftable(enum v4l2_mbus_pixelcode in,
- enum v4l2_mbus_pixelcode out,
- unsigned int additional_shift)
-{
- const struct isp_format_info *in_info, *out_info;
-
- if (in == out)
- return true;
-
- in_info = omap3isp_video_format_info(in);
- out_info = omap3isp_video_format_info(out);
-
- if ((in_info->flavor == 0) || (out_info->flavor == 0))
- return false;
-
- if (in_info->flavor != out_info->flavor)
- return false;
-
- return in_info->bpp - out_info->bpp + additional_shift <= 6;
-}
-
-static int ccdc_link_validate(struct v4l2_subdev *sd,
- struct media_link *link,
- struct v4l2_subdev_format *source_fmt,
- struct v4l2_subdev_format *sink_fmt)
-{
- struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
- unsigned long parallel_shift;
-
- /* Check if the two ends match */
- if (source_fmt->format.width != sink_fmt->format.width ||
- source_fmt->format.height != sink_fmt->format.height)
- return -EPIPE;
-
- /* We've got a parallel sensor here. */
- if (ccdc->input == CCDC_INPUT_PARALLEL) {
- struct isp_parallel_platform_data *pdata =
- &((struct isp_v4l2_subdevs_group *)
- media_entity_to_v4l2_subdev(link->source->entity)
- ->host_priv)->bus.parallel;
- parallel_shift = pdata->data_lane_shift * 2;
- } else {
- parallel_shift = 0;
- }
-
- /* Lane shifter may be used to drop bits on CCDC sink pad */
- if (!ccdc_is_shiftable(source_fmt->format.code,
- sink_fmt->format.code, parallel_shift))
- return -EPIPE;
-
- return 0;
-}
-
-/*
- * ccdc_init_formats - Initialize formats on all pads
- * @sd: ISP CCDC V4L2 subdevice
- * @fh: V4L2 subdev file handle
- *
- * Initialize all pad formats with default values. If fh is not NULL, try
- * formats are initialized on the file handle. Otherwise active formats are
- * initialized on the device.
- */
-static int ccdc_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- struct v4l2_subdev_format format;
-
- memset(&format, 0, sizeof(format));
- format.pad = CCDC_PAD_SINK;
- format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
- format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
- format.format.width = 4096;
- format.format.height = 4096;
- ccdc_set_format(sd, fh, &format);
-
- return 0;
-}
-
-/* V4L2 subdev core operations */
-static const struct v4l2_subdev_core_ops ccdc_v4l2_core_ops = {
- .ioctl = ccdc_ioctl,
- .subscribe_event = ccdc_subscribe_event,
- .unsubscribe_event = ccdc_unsubscribe_event,
-};
-
-/* V4L2 subdev video operations */
-static const struct v4l2_subdev_video_ops ccdc_v4l2_video_ops = {
- .s_stream = ccdc_set_stream,
-};
-
-/* V4L2 subdev pad operations */
-static const struct v4l2_subdev_pad_ops ccdc_v4l2_pad_ops = {
- .enum_mbus_code = ccdc_enum_mbus_code,
- .enum_frame_size = ccdc_enum_frame_size,
- .get_fmt = ccdc_get_format,
- .set_fmt = ccdc_set_format,
- .get_selection = ccdc_get_selection,
- .set_selection = ccdc_set_selection,
- .link_validate = ccdc_link_validate,
-};
-
-/* V4L2 subdev operations */
-static const struct v4l2_subdev_ops ccdc_v4l2_ops = {
- .core = &ccdc_v4l2_core_ops,
- .video = &ccdc_v4l2_video_ops,
- .pad = &ccdc_v4l2_pad_ops,
-};
-
-/* V4L2 subdev internal operations */
-static const struct v4l2_subdev_internal_ops ccdc_v4l2_internal_ops = {
- .open = ccdc_init_formats,
-};
-
-/* -----------------------------------------------------------------------------
- * Media entity operations
- */
-
-/*
- * ccdc_link_setup - Setup CCDC connections
- * @entity: CCDC media entity
- * @local: Pad at the local end of the link
- * @remote: Pad at the remote end of the link
- * @flags: Link flags
- *
- * return -EINVAL or zero on success
- */
-static int ccdc_link_setup(struct media_entity *entity,
- const struct media_pad *local,
- const struct media_pad *remote, u32 flags)
-{
- struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
- struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
- struct isp_device *isp = to_isp_device(ccdc);
-
- switch (local->index | media_entity_type(remote->entity)) {
- case CCDC_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
- /* Read from the sensor (parallel interface), CCP2, CSI2a or
- * CSI2c.
- */
- if (!(flags & MEDIA_LNK_FL_ENABLED)) {
- ccdc->input = CCDC_INPUT_NONE;
- break;
- }
-
- if (ccdc->input != CCDC_INPUT_NONE)
- return -EBUSY;
-
- if (remote->entity == &isp->isp_ccp2.subdev.entity)
- ccdc->input = CCDC_INPUT_CCP2B;
- else if (remote->entity == &isp->isp_csi2a.subdev.entity)
- ccdc->input = CCDC_INPUT_CSI2A;
- else if (remote->entity == &isp->isp_csi2c.subdev.entity)
- ccdc->input = CCDC_INPUT_CSI2C;
- else
- ccdc->input = CCDC_INPUT_PARALLEL;
-
- break;
-
- /*
- * The ISP core doesn't support pipelines with multiple video outputs.
- * Revisit this when it will be implemented, and return -EBUSY for now.
- */
-
- case CCDC_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV:
- /* Write to preview engine, histogram and H3A. When none of
- * those links are active, the video port can be disabled.
- */
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (ccdc->output & ~CCDC_OUTPUT_PREVIEW)
- return -EBUSY;
- ccdc->output |= CCDC_OUTPUT_PREVIEW;
- } else {
- ccdc->output &= ~CCDC_OUTPUT_PREVIEW;
- }
- break;
-
- case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_DEVNODE:
- /* Write to memory */
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (ccdc->output & ~CCDC_OUTPUT_MEMORY)
- return -EBUSY;
- ccdc->output |= CCDC_OUTPUT_MEMORY;
- } else {
- ccdc->output &= ~CCDC_OUTPUT_MEMORY;
- }
- break;
-
- case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_V4L2_SUBDEV:
- /* Write to resizer */
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (ccdc->output & ~CCDC_OUTPUT_RESIZER)
- return -EBUSY;
- ccdc->output |= CCDC_OUTPUT_RESIZER;
- } else {
- ccdc->output &= ~CCDC_OUTPUT_RESIZER;
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* media operations */
-static const struct media_entity_operations ccdc_media_ops = {
- .link_setup = ccdc_link_setup,
- .link_validate = v4l2_subdev_link_validate,
-};
-
-void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
-{
- v4l2_device_unregister_subdev(&ccdc->subdev);
- omap3isp_video_unregister(&ccdc->video_out);
-}
-
-int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
- struct v4l2_device *vdev)
-{
- int ret;
-
- /* Register the subdev and video node. */
- ret = v4l2_device_register_subdev(vdev, &ccdc->subdev);
- if (ret < 0)
- goto error;
-
- ret = omap3isp_video_register(&ccdc->video_out, vdev);
- if (ret < 0)
- goto error;
-
- return 0;
-
-error:
- omap3isp_ccdc_unregister_entities(ccdc);
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * ISP CCDC initialisation and cleanup
- */
-
-/*
- * ccdc_init_entities - Initialize V4L2 subdev and media entity
- * @ccdc: ISP CCDC module
- *
- * Return 0 on success and a negative error code on failure.
- */
-static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
-{
- struct v4l2_subdev *sd = &ccdc->subdev;
- struct media_pad *pads = ccdc->pads;
- struct media_entity *me = &sd->entity;
- int ret;
-
- ccdc->input = CCDC_INPUT_NONE;
-
- v4l2_subdev_init(sd, &ccdc_v4l2_ops);
- sd->internal_ops = &ccdc_v4l2_internal_ops;
- strlcpy(sd->name, "OMAP3 ISP CCDC", sizeof(sd->name));
- sd->grp_id = 1 << 16; /* group ID for isp subdevs */
- v4l2_set_subdevdata(sd, ccdc);
- sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- pads[CCDC_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- pads[CCDC_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
- pads[CCDC_PAD_SOURCE_OF].flags = MEDIA_PAD_FL_SOURCE;
-
- me->ops = &ccdc_media_ops;
- ret = media_entity_init(me, CCDC_PADS_NUM, pads, 0);
- if (ret < 0)
- return ret;
-
- ccdc_init_formats(sd, NULL);
-
- ccdc->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- ccdc->video_out.ops = &ccdc_video_ops;
- ccdc->video_out.isp = to_isp_device(ccdc);
- ccdc->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
- ccdc->video_out.bpl_alignment = 32;
-
- ret = omap3isp_video_init(&ccdc->video_out, "CCDC");
- if (ret < 0)
- goto error_video;
-
- /* Connect the CCDC subdev to the video node. */
- ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
- &ccdc->video_out.video.entity, 0, 0);
- if (ret < 0)
- goto error_link;
-
- return 0;
-
-error_link:
- omap3isp_video_cleanup(&ccdc->video_out);
-error_video:
- media_entity_cleanup(me);
- return ret;
-}
-
-/*
- * omap3isp_ccdc_init - CCDC module initialization.
- * @dev: Device pointer specific to the OMAP3 ISP.
- *
- * TODO: Get the initialisation values from platform data.
- *
- * Return 0 on success or a negative error code otherwise.
- */
-int omap3isp_ccdc_init(struct isp_device *isp)
-{
- struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
- int ret;
-
- spin_lock_init(&ccdc->lock);
- init_waitqueue_head(&ccdc->wait);
- mutex_init(&ccdc->ioctl_lock);
-
- ccdc->stopping = CCDC_STOP_NOT_REQUESTED;
-
- INIT_WORK(&ccdc->lsc.table_work, ccdc_lsc_free_table_work);
- ccdc->lsc.state = LSC_STATE_STOPPED;
- INIT_LIST_HEAD(&ccdc->lsc.free_queue);
- spin_lock_init(&ccdc->lsc.req_lock);
-
- ccdc->syncif.ccdc_mastermode = 0;
- ccdc->syncif.datapol = 0;
- ccdc->syncif.datsz = 0;
- ccdc->syncif.fldmode = 0;
- ccdc->syncif.fldout = 0;
- ccdc->syncif.fldpol = 0;
- ccdc->syncif.fldstat = 0;
-
- ccdc->clamp.oblen = 0;
- ccdc->clamp.dcsubval = 0;
-
- ccdc->update = OMAP3ISP_CCDC_BLCLAMP;
- ccdc_apply_controls(ccdc);
-
- ret = ccdc_init_entities(ccdc);
- if (ret < 0) {
- mutex_destroy(&ccdc->ioctl_lock);
- return ret;
- }
-
- return 0;
-}
-
-/*
- * omap3isp_ccdc_cleanup - CCDC module cleanup.
- * @dev: Device pointer specific to the OMAP3 ISP.
- */
-void omap3isp_ccdc_cleanup(struct isp_device *isp)
-{
- struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
-
- omap3isp_video_cleanup(&ccdc->video_out);
- media_entity_cleanup(&ccdc->subdev.entity);
-
- /* Free LSC requests. As the CCDC is stopped there's no active request,
- * so only the pending request and the free queue need to be handled.
- */
- ccdc_lsc_free_request(ccdc, ccdc->lsc.request);
- cancel_work_sync(&ccdc->lsc.table_work);
- ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue);
-
- if (ccdc->fpc.fpcaddr != 0)
- omap_iommu_vfree(isp->domain, isp->dev, ccdc->fpc.fpcaddr);
-
- mutex_destroy(&ccdc->ioctl_lock);
-}
diff --git a/drivers/media/video/omap3isp/ispccdc.h b/drivers/media/video/omap3isp/ispccdc.h
deleted file mode 100644
index 890f6b3a68f..00000000000
--- a/drivers/media/video/omap3isp/ispccdc.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * ispccdc.h
- *
- * TI OMAP3 ISP - CCDC module
- *
- * Copyright (C) 2009-2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef OMAP3_ISP_CCDC_H
-#define OMAP3_ISP_CCDC_H
-
-#include <linux/omap3isp.h>
-#include <linux/workqueue.h>
-
-#include "ispvideo.h"
-
-enum ccdc_input_entity {
- CCDC_INPUT_NONE,
- CCDC_INPUT_PARALLEL,
- CCDC_INPUT_CSI2A,
- CCDC_INPUT_CCP2B,
- CCDC_INPUT_CSI2C
-};
-
-#define CCDC_OUTPUT_MEMORY (1 << 0)
-#define CCDC_OUTPUT_PREVIEW (1 << 1)
-#define CCDC_OUTPUT_RESIZER (1 << 2)
-
-#define OMAP3ISP_CCDC_NEVENTS 16
-
-/*
- * struct ispccdc_syncif - Structure for Sync Interface between sensor and CCDC
- * @ccdc_mastermode: Master mode. 1 - Master, 0 - Slave.
- * @fldstat: Field state. 0 - Odd Field, 1 - Even Field.
- * @datsz: Data size.
- * @fldmode: 0 - Progressive, 1 - Interlaced.
- * @datapol: 0 - Positive, 1 - Negative.
- * @fldpol: 0 - Positive, 1 - Negative.
- * @hdpol: 0 - Positive, 1 - Negative.
- * @vdpol: 0 - Positive, 1 - Negative.
- * @fldout: 0 - Input, 1 - Output.
- * @hs_width: Width of the Horizontal Sync pulse, used for HS/VS Output.
- * @vs_width: Width of the Vertical Sync pulse, used for HS/VS Output.
- * @ppln: Number of pixels per line, used for HS/VS Output.
- * @hlprf: Number of half lines per frame, used for HS/VS Output.
- * @bt_r656_en: 1 - Enable ITU-R BT656 mode, 0 - Sync mode.
- */
-struct ispccdc_syncif {
- u8 ccdc_mastermode;
- u8 fldstat;
- u8 datsz;
- u8 fldmode;
- u8 datapol;
- u8 fldpol;
- u8 hdpol;
- u8 vdpol;
- u8 fldout;
- u8 hs_width;
- u8 vs_width;
- u8 ppln;
- u8 hlprf;
- u8 bt_r656_en;
-};
-
-enum ispccdc_lsc_state {
- LSC_STATE_STOPPED = 0,
- LSC_STATE_STOPPING = 1,
- LSC_STATE_RUNNING = 2,
- LSC_STATE_RECONFIG = 3,
-};
-
-struct ispccdc_lsc_config_req {
- struct list_head list;
- struct omap3isp_ccdc_lsc_config config;
- unsigned char enable;
- u32 table;
- struct iovm_struct *iovm;
-};
-
-/*
- * ispccdc_lsc - CCDC LSC parameters
- * @update_config: Set when user changes config
- * @request_enable: Whether LSC is requested to be enabled
- * @config: LSC config set by user
- * @update_table: Set when user provides a new LSC table to table_new
- * @table_new: LSC table set by user, ISP address
- * @table_inuse: LSC table currently in use, ISP address
- */
-struct ispccdc_lsc {
- enum ispccdc_lsc_state state;
- struct work_struct table_work;
-
- /* LSC queue of configurations */
- spinlock_t req_lock;
- struct ispccdc_lsc_config_req *request; /* requested configuration */
- struct ispccdc_lsc_config_req *active; /* active configuration */
- struct list_head free_queue; /* configurations for freeing */
-};
-
-#define CCDC_STOP_NOT_REQUESTED 0x00
-#define CCDC_STOP_REQUEST 0x01
-#define CCDC_STOP_EXECUTED (0x02 | CCDC_STOP_REQUEST)
-#define CCDC_STOP_CCDC_FINISHED 0x04
-#define CCDC_STOP_LSC_FINISHED 0x08
-#define CCDC_STOP_FINISHED \
- (CCDC_STOP_EXECUTED | CCDC_STOP_CCDC_FINISHED | CCDC_STOP_LSC_FINISHED)
-
-#define CCDC_EVENT_VD1 0x10
-#define CCDC_EVENT_VD0 0x20
-#define CCDC_EVENT_LSC_DONE 0x40
-
-/* Sink and source CCDC pads */
-#define CCDC_PAD_SINK 0
-#define CCDC_PAD_SOURCE_OF 1
-#define CCDC_PAD_SOURCE_VP 2
-#define CCDC_PADS_NUM 3
-
-/*
- * struct isp_ccdc_device - Structure for the CCDC module to store its own
- * information
- * @subdev: V4L2 subdevice
- * @pads: Sink and source media entity pads
- * @formats: Active video formats
- * @crop: Active crop rectangle on the OF source pad
- * @input: Active input
- * @output: Active outputs
- * @video_out: Output video node
- * @alaw: A-law compression enabled (1) or disabled (0)
- * @lpf: Low pass filter enabled (1) or disabled (0)
- * @obclamp: Optical-black clamp enabled (1) or disabled (0)
- * @fpc_en: Faulty pixels correction enabled (1) or disabled (0)
- * @blcomp: Black level compensation configuration
- * @clamp: Optical-black or digital clamp configuration
- * @fpc: Faulty pixels correction configuration
- * @lsc: Lens shading compensation configuration
- * @update: Bitmask of controls to update during the next interrupt
- * @shadow_update: Controls update in progress by userspace
- * @syncif: Interface synchronization configuration
- * @underrun: A buffer underrun occurred and a new buffer has been queued
- * @state: Streaming state
- * @lock: Serializes shadow_update with interrupt handler
- * @wait: Wait queue used to stop the module
- * @stopping: Stopping state
- * @ioctl_lock: Serializes ioctl calls and LSC requests freeing
- */
-struct isp_ccdc_device {
- struct v4l2_subdev subdev;
- struct media_pad pads[CCDC_PADS_NUM];
- struct v4l2_mbus_framefmt formats[CCDC_PADS_NUM];
- struct v4l2_rect crop;
-
- enum ccdc_input_entity input;
- unsigned int output;
- struct isp_video video_out;
-
- unsigned int alaw:1,
- lpf:1,
- obclamp:1,
- fpc_en:1;
- struct omap3isp_ccdc_blcomp blcomp;
- struct omap3isp_ccdc_bclamp clamp;
- struct omap3isp_ccdc_fpc fpc;
- struct ispccdc_lsc lsc;
- unsigned int update;
- unsigned int shadow_update;
-
- struct ispccdc_syncif syncif;
-
- unsigned int underrun:1;
- enum isp_pipeline_stream_state state;
- spinlock_t lock;
- wait_queue_head_t wait;
- unsigned int stopping;
- struct mutex ioctl_lock;
-};
-
-struct isp_device;
-
-int omap3isp_ccdc_init(struct isp_device *isp);
-void omap3isp_ccdc_cleanup(struct isp_device *isp);
-int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
- struct v4l2_device *vdev);
-void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc);
-
-int omap3isp_ccdc_busy(struct isp_ccdc_device *isp_ccdc);
-int omap3isp_ccdc_isr(struct isp_ccdc_device *isp_ccdc, u32 events);
-void omap3isp_ccdc_restore_context(struct isp_device *isp);
-void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
- unsigned int *max_rate);
-
-#endif /* OMAP3_ISP_CCDC_H */
diff --git a/drivers/media/video/omap3isp/ispccp2.c b/drivers/media/video/omap3isp/ispccp2.c
deleted file mode 100644
index 85f0de85f37..00000000000
--- a/drivers/media/video/omap3isp/ispccp2.c
+++ /dev/null
@@ -1,1171 +0,0 @@
-/*
- * ispccp2.c
- *
- * TI OMAP3 ISP - CCP2 module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2010 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-#include <linux/regulator/consumer.h>
-
-#include "isp.h"
-#include "ispreg.h"
-#include "ispccp2.h"
-
-/* Number of LCX channels */
-#define CCP2_LCx_CHANS_NUM 3
-/* Max/Min size for CCP2 video port */
-#define ISPCCP2_DAT_START_MIN 0
-#define ISPCCP2_DAT_START_MAX 4095
-#define ISPCCP2_DAT_SIZE_MIN 0
-#define ISPCCP2_DAT_SIZE_MAX 4095
-#define ISPCCP2_VPCLK_FRACDIV 65536
-#define ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP 0x12
-#define ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP 0x16
-/* Max/Min size for CCP2 memory channel */
-#define ISPCCP2_LCM_HSIZE_COUNT_MIN 16
-#define ISPCCP2_LCM_HSIZE_COUNT_MAX 8191
-#define ISPCCP2_LCM_HSIZE_SKIP_MIN 0
-#define ISPCCP2_LCM_HSIZE_SKIP_MAX 8191
-#define ISPCCP2_LCM_VSIZE_MIN 1
-#define ISPCCP2_LCM_VSIZE_MAX 8191
-#define ISPCCP2_LCM_HWORDS_MIN 1
-#define ISPCCP2_LCM_HWORDS_MAX 4095
-#define ISPCCP2_LCM_CTRL_BURST_SIZE_32X 5
-#define ISPCCP2_LCM_CTRL_READ_THROTTLE_FULL 0
-#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_DPCM10 2
-#define ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW8 2
-#define ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW10 3
-#define ISPCCP2_LCM_CTRL_DST_FORMAT_RAW10 3
-#define ISPCCP2_LCM_CTRL_DST_PORT_VP 0
-#define ISPCCP2_LCM_CTRL_DST_PORT_MEM 1
-
-/* Set only the required bits */
-#define BIT_SET(var, shift, mask, val) \
- do { \
- var = ((var) & ~((mask) << (shift))) \
- | ((val) << (shift)); \
- } while (0)
-
-/*
- * ccp2_print_status - Print current CCP2 module register values.
- */
-#define CCP2_PRINT_REGISTER(isp, name)\
- dev_dbg(isp->dev, "###CCP2 " #name "=0x%08x\n", \
- isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_##name))
-
-static void ccp2_print_status(struct isp_ccp2_device *ccp2)
-{
- struct isp_device *isp = to_isp_device(ccp2);
-
- dev_dbg(isp->dev, "-------------CCP2 Register dump-------------\n");
-
- CCP2_PRINT_REGISTER(isp, SYSCONFIG);
- CCP2_PRINT_REGISTER(isp, SYSSTATUS);
- CCP2_PRINT_REGISTER(isp, LC01_IRQENABLE);
- CCP2_PRINT_REGISTER(isp, LC01_IRQSTATUS);
- CCP2_PRINT_REGISTER(isp, LC23_IRQENABLE);
- CCP2_PRINT_REGISTER(isp, LC23_IRQSTATUS);
- CCP2_PRINT_REGISTER(isp, LCM_IRQENABLE);
- CCP2_PRINT_REGISTER(isp, LCM_IRQSTATUS);
- CCP2_PRINT_REGISTER(isp, CTRL);
- CCP2_PRINT_REGISTER(isp, LCx_CTRL(0));
- CCP2_PRINT_REGISTER(isp, LCx_CODE(0));
- CCP2_PRINT_REGISTER(isp, LCx_STAT_START(0));
- CCP2_PRINT_REGISTER(isp, LCx_STAT_SIZE(0));
- CCP2_PRINT_REGISTER(isp, LCx_SOF_ADDR(0));
- CCP2_PRINT_REGISTER(isp, LCx_EOF_ADDR(0));
- CCP2_PRINT_REGISTER(isp, LCx_DAT_START(0));
- CCP2_PRINT_REGISTER(isp, LCx_DAT_SIZE(0));
- CCP2_PRINT_REGISTER(isp, LCx_DAT_PING_ADDR(0));
- CCP2_PRINT_REGISTER(isp, LCx_DAT_PONG_ADDR(0));
- CCP2_PRINT_REGISTER(isp, LCx_DAT_OFST(0));
- CCP2_PRINT_REGISTER(isp, LCM_CTRL);
- CCP2_PRINT_REGISTER(isp, LCM_VSIZE);
- CCP2_PRINT_REGISTER(isp, LCM_HSIZE);
- CCP2_PRINT_REGISTER(isp, LCM_PREFETCH);
- CCP2_PRINT_REGISTER(isp, LCM_SRC_ADDR);
- CCP2_PRINT_REGISTER(isp, LCM_SRC_OFST);
- CCP2_PRINT_REGISTER(isp, LCM_DST_ADDR);
- CCP2_PRINT_REGISTER(isp, LCM_DST_OFST);
-
- dev_dbg(isp->dev, "--------------------------------------------\n");
-}
-
-/*
- * ccp2_reset - Reset the CCP2
- * @ccp2: pointer to ISP CCP2 device
- */
-static void ccp2_reset(struct isp_ccp2_device *ccp2)
-{
- struct isp_device *isp = to_isp_device(ccp2);
- int i = 0;
-
- /* Reset the CSI1/CCP2B and wait for reset to complete */
- isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG,
- ISPCCP2_SYSCONFIG_SOFT_RESET);
- while (!(isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSSTATUS) &
- ISPCCP2_SYSSTATUS_RESET_DONE)) {
- udelay(10);
- if (i++ > 10) { /* try read 10 times */
- dev_warn(isp->dev,
- "omap3_isp: timeout waiting for ccp2 reset\n");
- break;
- }
- }
-}
-
-/*
- * ccp2_pwr_cfg - Configure the power mode settings
- * @ccp2: pointer to ISP CCP2 device
- */
-static void ccp2_pwr_cfg(struct isp_ccp2_device *ccp2)
-{
- struct isp_device *isp = to_isp_device(ccp2);
-
- isp_reg_writel(isp, ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SMART |
- ((isp->revision == ISP_REVISION_15_0 && isp->autoidle) ?
- ISPCCP2_SYSCONFIG_AUTO_IDLE : 0),
- OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG);
-}
-
-/*
- * ccp2_if_enable - Enable CCP2 interface.
- * @ccp2: pointer to ISP CCP2 device
- * @enable: enable/disable flag
- */
-static void ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
-{
- struct isp_device *isp = to_isp_device(ccp2);
- int i;
-
- if (enable && ccp2->vdds_csib)
- regulator_enable(ccp2->vdds_csib);
-
- /* Enable/Disable all the LCx channels */
- for (i = 0; i < CCP2_LCx_CHANS_NUM; i++)
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(i),
- ISPCCP2_LCx_CTRL_CHAN_EN,
- enable ? ISPCCP2_LCx_CTRL_CHAN_EN : 0);
-
- /* Enable/Disable ccp2 interface in ccp2 mode */
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
- ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN,
- enable ? (ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN) : 0);
-
- if (!enable && ccp2->vdds_csib)
- regulator_disable(ccp2->vdds_csib);
-}
-
-/*
- * ccp2_mem_enable - Enable CCP2 memory interface.
- * @ccp2: pointer to ISP CCP2 device
- * @enable: enable/disable flag
- */
-static void ccp2_mem_enable(struct isp_ccp2_device *ccp2, u8 enable)
-{
- struct isp_device *isp = to_isp_device(ccp2);
-
- if (enable)
- ccp2_if_enable(ccp2, 0);
-
- /* Enable/Disable ccp2 interface in ccp2 mode */
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
- ISPCCP2_CTRL_MODE, enable ? ISPCCP2_CTRL_MODE : 0);
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_CTRL,
- ISPCCP2_LCM_CTRL_CHAN_EN,
- enable ? ISPCCP2_LCM_CTRL_CHAN_EN : 0);
-}
-
-/*
- * ccp2_phyif_config - Initialize CCP2 phy interface config
- * @ccp2: Pointer to ISP CCP2 device
- * @config: CCP2 platform data
- *
- * Configure the CCP2 physical interface module from platform data.
- *
- * Returns -EIO if strobe is chosen in CSI1 mode, or 0 on success.
- */
-static int ccp2_phyif_config(struct isp_ccp2_device *ccp2,
- const struct isp_ccp2_platform_data *pdata)
-{
- struct isp_device *isp = to_isp_device(ccp2);
- u32 val;
-
- /* CCP2B mode */
- val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL) |
- ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE;
- /* Data/strobe physical layer */
- BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK,
- pdata->phy_layer);
- BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK,
- pdata->strobe_clk_pol);
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
-
- val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
- if (!(val & ISPCCP2_CTRL_MODE)) {
- if (pdata->ccp2_mode == ISP_CCP2_MODE_CCP2)
- dev_warn(isp->dev, "OMAP3 CCP2 bus not available\n");
- if (pdata->phy_layer == ISP_CCP2_PHY_DATA_STROBE)
- /* Strobe mode requires CCP2 */
- return -EIO;
- }
-
- return 0;
-}
-
-/*
- * ccp2_vp_config - Initialize CCP2 video port interface.
- * @ccp2: Pointer to ISP CCP2 device
- * @vpclk_div: Video port divisor
- *
- * Configure the CCP2 video port with the given clock divisor. The valid divisor
- * values depend on the ISP revision:
- *
- * - revision 1.0 and 2.0 1 to 4
- * - revision 15.0 1 to 65536
- *
- * The exact divisor value used might differ from the requested value, as ISP
- * revision 15.0 represent the divisor by 65536 divided by an integer.
- */
-static void ccp2_vp_config(struct isp_ccp2_device *ccp2,
- unsigned int vpclk_div)
-{
- struct isp_device *isp = to_isp_device(ccp2);
- u32 val;
-
- /* ISPCCP2_CTRL Video port */
- val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
- val |= ISPCCP2_CTRL_VP_ONLY_EN; /* Disable the memory write port */
-
- if (isp->revision == ISP_REVISION_15_0) {
- vpclk_div = clamp_t(unsigned int, vpclk_div, 1, 65536);
- vpclk_div = min(ISPCCP2_VPCLK_FRACDIV / vpclk_div, 65535U);
- BIT_SET(val, ISPCCP2_CTRL_VPCLK_DIV_SHIFT,
- ISPCCP2_CTRL_VPCLK_DIV_MASK, vpclk_div);
- } else {
- vpclk_div = clamp_t(unsigned int, vpclk_div, 1, 4);
- BIT_SET(val, ISPCCP2_CTRL_VP_OUT_CTRL_SHIFT,
- ISPCCP2_CTRL_VP_OUT_CTRL_MASK, vpclk_div - 1);
- }
-
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
-}
-
-/*
- * ccp2_lcx_config - Initialize CCP2 logical channel interface.
- * @ccp2: Pointer to ISP CCP2 device
- * @config: Pointer to ISP LCx config structure.
- *
- * This will analyze the parameters passed by the interface config
- * and configure CSI1/CCP2 logical channel
- *
- */
-static void ccp2_lcx_config(struct isp_ccp2_device *ccp2,
- struct isp_interface_lcx_config *config)
-{
- struct isp_device *isp = to_isp_device(ccp2);
- u32 val, format;
-
- switch (config->format) {
- case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8:
- format = ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP;
- break;
- case V4L2_MBUS_FMT_SGRBG10_1X10:
- default:
- format = ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP; /* RAW10+VP */
- break;
- }
- /* ISPCCP2_LCx_CTRL logical channel #0 */
- val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(0))
- | (ISPCCP2_LCx_CTRL_REGION_EN); /* Region */
-
- if (isp->revision == ISP_REVISION_15_0) {
- /* CRC */
- BIT_SET(val, ISPCCP2_LCx_CTRL_CRC_SHIFT_15_0,
- ISPCCP2_LCx_CTRL_CRC_MASK,
- config->crc);
- /* Format = RAW10+VP or RAW8+DPCM10+VP*/
- BIT_SET(val, ISPCCP2_LCx_CTRL_FORMAT_SHIFT_15_0,
- ISPCCP2_LCx_CTRL_FORMAT_MASK_15_0, format);
- } else {
- BIT_SET(val, ISPCCP2_LCx_CTRL_CRC_SHIFT,
- ISPCCP2_LCx_CTRL_CRC_MASK,
- config->crc);
-
- BIT_SET(val, ISPCCP2_LCx_CTRL_FORMAT_SHIFT,
- ISPCCP2_LCx_CTRL_FORMAT_MASK, format);
- }
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(0));
-
- /* ISPCCP2_DAT_START for logical channel #0 */
- isp_reg_writel(isp, config->data_start << ISPCCP2_LCx_DAT_SHIFT,
- OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_DAT_START(0));
-
- /* ISPCCP2_DAT_SIZE for logical channel #0 */
- isp_reg_writel(isp, config->data_size << ISPCCP2_LCx_DAT_SHIFT,
- OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_DAT_SIZE(0));
-
- /* Enable error IRQs for logical channel #0 */
- val = ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ |
- ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ |
- ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ |
- ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ |
- ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ |
- ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ;
-
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LC01_IRQSTATUS);
- isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LC01_IRQENABLE, val);
-}
-
-/*
- * ccp2_if_configure - Configure ccp2 with data from sensor
- * @ccp2: Pointer to ISP CCP2 device
- *
- * Return 0 on success or a negative error code
- */
-static int ccp2_if_configure(struct isp_ccp2_device *ccp2)
-{
- const struct isp_v4l2_subdevs_group *pdata;
- struct v4l2_mbus_framefmt *format;
- struct media_pad *pad;
- struct v4l2_subdev *sensor;
- u32 lines = 0;
- int ret;
-
- ccp2_pwr_cfg(ccp2);
-
- pad = media_entity_remote_source(&ccp2->pads[CCP2_PAD_SINK]);
- sensor = media_entity_to_v4l2_subdev(pad->entity);
- pdata = sensor->host_priv;
-
- ret = ccp2_phyif_config(ccp2, &pdata->bus.ccp2);
- if (ret < 0)
- return ret;
-
- ccp2_vp_config(ccp2, pdata->bus.ccp2.vpclk_div + 1);
-
- v4l2_subdev_call(sensor, sensor, g_skip_top_lines, &lines);
-
- format = &ccp2->formats[CCP2_PAD_SINK];
-
- ccp2->if_cfg.data_start = lines;
- ccp2->if_cfg.crc = pdata->bus.ccp2.crc;
- ccp2->if_cfg.format = format->code;
- ccp2->if_cfg.data_size = format->height;
-
- ccp2_lcx_config(ccp2, &ccp2->if_cfg);
-
- return 0;
-}
-
-static int ccp2_adjust_bandwidth(struct isp_ccp2_device *ccp2)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
- struct isp_device *isp = to_isp_device(ccp2);
- const struct v4l2_mbus_framefmt *ofmt = &ccp2->formats[CCP2_PAD_SOURCE];
- unsigned long l3_ick = pipe->l3_ick;
- struct v4l2_fract *timeperframe;
- unsigned int vpclk_div = 2;
- unsigned int value;
- u64 bound;
- u64 area;
-
- /* Compute the minimum clock divisor, based on the pipeline maximum
- * data rate. This is an absolute lower bound if we don't want SBL
- * overflows, so round the value up.
- */
- vpclk_div = max_t(unsigned int, DIV_ROUND_UP(l3_ick, pipe->max_rate),
- vpclk_div);
-
- /* Compute the maximum clock divisor, based on the requested frame rate.
- * This is a soft lower bound to achieve a frame rate equal or higher
- * than the requested value, so round the value down.
- */
- timeperframe = &pipe->max_timeperframe;
-
- if (timeperframe->numerator) {
- area = ofmt->width * ofmt->height;
- bound = div_u64(area * timeperframe->denominator,
- timeperframe->numerator);
- value = min_t(u64, bound, l3_ick);
- vpclk_div = max_t(unsigned int, l3_ick / value, vpclk_div);
- }
-
- dev_dbg(isp->dev, "%s: minimum clock divisor = %u\n", __func__,
- vpclk_div);
-
- return vpclk_div;
-}
-
-/*
- * ccp2_mem_configure - Initialize CCP2 memory input/output interface
- * @ccp2: Pointer to ISP CCP2 device
- * @config: Pointer to ISP mem interface config structure
- *
- * This will analyze the parameters passed by the interface config
- * structure, and configure the respective registers for proper
- * CSI1/CCP2 memory input.
- */
-static void ccp2_mem_configure(struct isp_ccp2_device *ccp2,
- struct isp_interface_mem_config *config)
-{
- struct isp_device *isp = to_isp_device(ccp2);
- u32 sink_pixcode = ccp2->formats[CCP2_PAD_SINK].code;
- u32 source_pixcode = ccp2->formats[CCP2_PAD_SOURCE].code;
- unsigned int dpcm_decompress = 0;
- u32 val, hwords;
-
- if (sink_pixcode != source_pixcode &&
- sink_pixcode == V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8)
- dpcm_decompress = 1;
-
- ccp2_pwr_cfg(ccp2);
-
- /* Hsize, Skip */
- isp_reg_writel(isp, ISPCCP2_LCM_HSIZE_SKIP_MIN |
- (config->hsize_count << ISPCCP2_LCM_HSIZE_SHIFT),
- OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_HSIZE);
-
- /* Vsize, no. of lines */
- isp_reg_writel(isp, config->vsize_count << ISPCCP2_LCM_VSIZE_SHIFT,
- OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_VSIZE);
-
- if (ccp2->video_in.bpl_padding == 0)
- config->src_ofst = 0;
- else
- config->src_ofst = ccp2->video_in.bpl_value;
-
- isp_reg_writel(isp, config->src_ofst, OMAP3_ISP_IOMEM_CCP2,
- ISPCCP2_LCM_SRC_OFST);
-
- /* Source and Destination formats */
- val = ISPCCP2_LCM_CTRL_DST_FORMAT_RAW10 <<
- ISPCCP2_LCM_CTRL_DST_FORMAT_SHIFT;
-
- if (dpcm_decompress) {
- /* source format is RAW8 */
- val |= ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW8 <<
- ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT;
-
- /* RAW8 + DPCM10 - simple predictor */
- val |= ISPCCP2_LCM_CTRL_SRC_DPCM_PRED;
-
- /* enable source DPCM decompression */
- val |= ISPCCP2_LCM_CTRL_SRC_DECOMPR_DPCM10 <<
- ISPCCP2_LCM_CTRL_SRC_DECOMPR_SHIFT;
- } else {
- /* source format is RAW10 */
- val |= ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW10 <<
- ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT;
- }
-
- /* Burst size to 32x64 */
- val |= ISPCCP2_LCM_CTRL_BURST_SIZE_32X <<
- ISPCCP2_LCM_CTRL_BURST_SIZE_SHIFT;
-
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_CTRL);
-
- /* Prefetch setup */
- if (dpcm_decompress)
- hwords = (ISPCCP2_LCM_HSIZE_SKIP_MIN +
- config->hsize_count) >> 3;
- else
- hwords = (ISPCCP2_LCM_HSIZE_SKIP_MIN +
- config->hsize_count) >> 2;
-
- isp_reg_writel(isp, hwords << ISPCCP2_LCM_PREFETCH_SHIFT,
- OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_PREFETCH);
-
- /* Video port */
- isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
- ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE);
- ccp2_vp_config(ccp2, ccp2_adjust_bandwidth(ccp2));
-
- /* Clear LCM interrupts */
- isp_reg_writel(isp, ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ |
- ISPCCP2_LCM_IRQSTATUS_EOF_IRQ,
- OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQSTATUS);
-
- /* Enable LCM interupts */
- isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQENABLE,
- ISPCCP2_LCM_IRQSTATUS_EOF_IRQ |
- ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ);
-}
-
-/*
- * ccp2_set_inaddr - Sets memory address of input frame.
- * @ccp2: Pointer to ISP CCP2 device
- * @addr: 32bit memory address aligned on 32byte boundary.
- *
- * Configures the memory address from which the input frame is to be read.
- */
-static void ccp2_set_inaddr(struct isp_ccp2_device *ccp2, u32 addr)
-{
- struct isp_device *isp = to_isp_device(ccp2);
-
- isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_SRC_ADDR);
-}
-
-/* -----------------------------------------------------------------------------
- * Interrupt handling
- */
-
-static void ccp2_isr_buffer(struct isp_ccp2_device *ccp2)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
- struct isp_buffer *buffer;
-
- buffer = omap3isp_video_buffer_next(&ccp2->video_in);
- if (buffer != NULL)
- ccp2_set_inaddr(ccp2, buffer->isp_addr);
-
- pipe->state |= ISP_PIPELINE_IDLE_INPUT;
-
- if (ccp2->state == ISP_PIPELINE_STREAM_SINGLESHOT) {
- if (isp_pipeline_ready(pipe))
- omap3isp_pipeline_set_stream(pipe,
- ISP_PIPELINE_STREAM_SINGLESHOT);
- }
-}
-
-/*
- * omap3isp_ccp2_isr - Handle ISP CCP2 interrupts
- * @ccp2: Pointer to ISP CCP2 device
- *
- * This will handle the CCP2 interrupts
- */
-void omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
- struct isp_device *isp = to_isp_device(ccp2);
- static const u32 ISPCCP2_LC01_ERROR =
- ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ |
- ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ |
- ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ |
- ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ |
- ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ |
- ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ;
- u32 lcx_irqstatus, lcm_irqstatus;
-
- /* First clear the interrupts */
- lcx_irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2,
- ISPCCP2_LC01_IRQSTATUS);
- isp_reg_writel(isp, lcx_irqstatus, OMAP3_ISP_IOMEM_CCP2,
- ISPCCP2_LC01_IRQSTATUS);
-
- lcm_irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2,
- ISPCCP2_LCM_IRQSTATUS);
- isp_reg_writel(isp, lcm_irqstatus, OMAP3_ISP_IOMEM_CCP2,
- ISPCCP2_LCM_IRQSTATUS);
- /* Errors */
- if (lcx_irqstatus & ISPCCP2_LC01_ERROR) {
- pipe->error = true;
- dev_dbg(isp->dev, "CCP2 err:%x\n", lcx_irqstatus);
- return;
- }
-
- if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ) {
- pipe->error = true;
- dev_dbg(isp->dev, "CCP2 OCP err:%x\n", lcm_irqstatus);
- }
-
- if (omap3isp_module_sync_is_stopping(&ccp2->wait, &ccp2->stopping))
- return;
-
- /* Handle queued buffers on frame end interrupts */
- if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_EOF_IRQ)
- ccp2_isr_buffer(ccp2);
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev operations
- */
-
-static const unsigned int ccp2_fmts[] = {
- V4L2_MBUS_FMT_SGRBG10_1X10,
- V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
-};
-
-/*
- * __ccp2_get_format - helper function for getting ccp2 format
- * @ccp2 : Pointer to ISP CCP2 device
- * @fh : V4L2 subdev file handle
- * @pad : pad number
- * @which : wanted subdev format
- * return format structure or NULL on error
- */
-static struct v4l2_mbus_framefmt *
-__ccp2_get_format(struct isp_ccp2_device *ccp2, struct v4l2_subdev_fh *fh,
- unsigned int pad, enum v4l2_subdev_format_whence which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_format(fh, pad);
- else
- return &ccp2->formats[pad];
-}
-
-/*
- * ccp2_try_format - Handle try format by pad subdev method
- * @ccp2 : Pointer to ISP CCP2 device
- * @fh : V4L2 subdev file handle
- * @pad : pad num
- * @fmt : pointer to v4l2 mbus format structure
- * @which : wanted subdev format
- */
-static void ccp2_try_format(struct isp_ccp2_device *ccp2,
- struct v4l2_subdev_fh *fh, unsigned int pad,
- struct v4l2_mbus_framefmt *fmt,
- enum v4l2_subdev_format_whence which)
-{
- struct v4l2_mbus_framefmt *format;
-
- switch (pad) {
- case CCP2_PAD_SINK:
- if (fmt->code != V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8)
- fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
-
- if (ccp2->input == CCP2_INPUT_SENSOR) {
- fmt->width = clamp_t(u32, fmt->width,
- ISPCCP2_DAT_START_MIN,
- ISPCCP2_DAT_START_MAX);
- fmt->height = clamp_t(u32, fmt->height,
- ISPCCP2_DAT_SIZE_MIN,
- ISPCCP2_DAT_SIZE_MAX);
- } else if (ccp2->input == CCP2_INPUT_MEMORY) {
- fmt->width = clamp_t(u32, fmt->width,
- ISPCCP2_LCM_HSIZE_COUNT_MIN,
- ISPCCP2_LCM_HSIZE_COUNT_MAX);
- fmt->height = clamp_t(u32, fmt->height,
- ISPCCP2_LCM_VSIZE_MIN,
- ISPCCP2_LCM_VSIZE_MAX);
- }
- break;
-
- case CCP2_PAD_SOURCE:
- /* Source format - copy sink format and change pixel code
- * to SGRBG10_1X10 as we don't support CCP2 write to memory.
- * When CCP2 write to memory feature will be added this
- * should be changed properly.
- */
- format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK, which);
- memcpy(fmt, format, sizeof(*fmt));
- fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
- break;
- }
-
- fmt->field = V4L2_FIELD_NONE;
- fmt->colorspace = V4L2_COLORSPACE_SRGB;
-}
-
-/*
- * ccp2_enum_mbus_code - Handle pixel format enumeration
- * @sd : pointer to v4l2 subdev structure
- * @fh : V4L2 subdev file handle
- * @code : pointer to v4l2_subdev_mbus_code_enum structure
- * return -EINVAL or zero on success
- */
-static int ccp2_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
-
- if (code->pad == CCP2_PAD_SINK) {
- if (code->index >= ARRAY_SIZE(ccp2_fmts))
- return -EINVAL;
-
- code->code = ccp2_fmts[code->index];
- } else {
- if (code->index != 0)
- return -EINVAL;
-
- format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK,
- V4L2_SUBDEV_FORMAT_TRY);
- code->code = format->code;
- }
-
- return 0;
-}
-
-static int ccp2_enum_frame_size(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_frame_size_enum *fse)
-{
- struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt format;
-
- if (fse->index != 0)
- return -EINVAL;
-
- format.code = fse->code;
- format.width = 1;
- format.height = 1;
- ccp2_try_format(ccp2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
- fse->min_width = format.width;
- fse->min_height = format.height;
-
- if (format.code != fse->code)
- return -EINVAL;
-
- format.code = fse->code;
- format.width = -1;
- format.height = -1;
- ccp2_try_format(ccp2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
- fse->max_width = format.width;
- fse->max_height = format.height;
-
- return 0;
-}
-
-/*
- * ccp2_get_format - Handle get format by pads subdev method
- * @sd : pointer to v4l2 subdev structure
- * @fh : V4L2 subdev file handle
- * @fmt : pointer to v4l2 subdev format structure
- * return -EINVAL or zero on success
- */
-static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
-
- format = __ccp2_get_format(ccp2, fh, fmt->pad, fmt->which);
- if (format == NULL)
- return -EINVAL;
-
- fmt->format = *format;
- return 0;
-}
-
-/*
- * ccp2_set_format - Handle set format by pads subdev method
- * @sd : pointer to v4l2 subdev structure
- * @fh : V4L2 subdev file handle
- * @fmt : pointer to v4l2 subdev format structure
- * returns zero
- */
-static int ccp2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
-
- format = __ccp2_get_format(ccp2, fh, fmt->pad, fmt->which);
- if (format == NULL)
- return -EINVAL;
-
- ccp2_try_format(ccp2, fh, fmt->pad, &fmt->format, fmt->which);
- *format = fmt->format;
-
- /* Propagate the format from sink to source */
- if (fmt->pad == CCP2_PAD_SINK) {
- format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SOURCE,
- fmt->which);
- *format = fmt->format;
- ccp2_try_format(ccp2, fh, CCP2_PAD_SOURCE, format, fmt->which);
- }
-
- return 0;
-}
-
-/*
- * ccp2_init_formats - Initialize formats on all pads
- * @sd: ISP CCP2 V4L2 subdevice
- * @fh: V4L2 subdev file handle
- *
- * Initialize all pad formats with default values. If fh is not NULL, try
- * formats are initialized on the file handle. Otherwise active formats are
- * initialized on the device.
- */
-static int ccp2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- struct v4l2_subdev_format format;
-
- memset(&format, 0, sizeof(format));
- format.pad = CCP2_PAD_SINK;
- format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
- format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
- format.format.width = 4096;
- format.format.height = 4096;
- ccp2_set_format(sd, fh, &format);
-
- return 0;
-}
-
-/*
- * ccp2_s_stream - Enable/Disable streaming on ccp2 subdev
- * @sd : pointer to v4l2 subdev structure
- * @enable: 1 == Enable, 0 == Disable
- * return zero
- */
-static int ccp2_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
- struct isp_device *isp = to_isp_device(ccp2);
- struct device *dev = to_device(ccp2);
- int ret;
-
- if (ccp2->state == ISP_PIPELINE_STREAM_STOPPED) {
- if (enable == ISP_PIPELINE_STREAM_STOPPED)
- return 0;
- atomic_set(&ccp2->stopping, 0);
- }
-
- switch (enable) {
- case ISP_PIPELINE_STREAM_CONTINUOUS:
- if (ccp2->phy) {
- ret = omap3isp_csiphy_acquire(ccp2->phy);
- if (ret < 0)
- return ret;
- }
-
- ccp2_if_configure(ccp2);
- ccp2_print_status(ccp2);
-
- /* Enable CSI1/CCP2 interface */
- ccp2_if_enable(ccp2, 1);
- break;
-
- case ISP_PIPELINE_STREAM_SINGLESHOT:
- if (ccp2->state != ISP_PIPELINE_STREAM_SINGLESHOT) {
- struct v4l2_mbus_framefmt *format;
-
- format = &ccp2->formats[CCP2_PAD_SINK];
-
- ccp2->mem_cfg.hsize_count = format->width;
- ccp2->mem_cfg.vsize_count = format->height;
- ccp2->mem_cfg.src_ofst = 0;
-
- ccp2_mem_configure(ccp2, &ccp2->mem_cfg);
- omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI1_READ);
- ccp2_print_status(ccp2);
- }
- ccp2_mem_enable(ccp2, 1);
- break;
-
- case ISP_PIPELINE_STREAM_STOPPED:
- if (omap3isp_module_sync_idle(&sd->entity, &ccp2->wait,
- &ccp2->stopping))
- dev_dbg(dev, "%s: module stop timeout.\n", sd->name);
- if (ccp2->input == CCP2_INPUT_MEMORY) {
- ccp2_mem_enable(ccp2, 0);
- omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CSI1_READ);
- } else if (ccp2->input == CCP2_INPUT_SENSOR) {
- /* Disable CSI1/CCP2 interface */
- ccp2_if_enable(ccp2, 0);
- if (ccp2->phy)
- omap3isp_csiphy_release(ccp2->phy);
- }
- break;
- }
-
- ccp2->state = enable;
- return 0;
-}
-
-/* subdev video operations */
-static const struct v4l2_subdev_video_ops ccp2_sd_video_ops = {
- .s_stream = ccp2_s_stream,
-};
-
-/* subdev pad operations */
-static const struct v4l2_subdev_pad_ops ccp2_sd_pad_ops = {
- .enum_mbus_code = ccp2_enum_mbus_code,
- .enum_frame_size = ccp2_enum_frame_size,
- .get_fmt = ccp2_get_format,
- .set_fmt = ccp2_set_format,
-};
-
-/* subdev operations */
-static const struct v4l2_subdev_ops ccp2_sd_ops = {
- .video = &ccp2_sd_video_ops,
- .pad = &ccp2_sd_pad_ops,
-};
-
-/* subdev internal operations */
-static const struct v4l2_subdev_internal_ops ccp2_sd_internal_ops = {
- .open = ccp2_init_formats,
-};
-
-/* --------------------------------------------------------------------------
- * ISP ccp2 video device node
- */
-
-/*
- * ccp2_video_queue - Queue video buffer.
- * @video : Pointer to isp video structure
- * @buffer: Pointer to isp_buffer structure
- * return -EIO or zero on success
- */
-static int ccp2_video_queue(struct isp_video *video, struct isp_buffer *buffer)
-{
- struct isp_ccp2_device *ccp2 = &video->isp->isp_ccp2;
-
- ccp2_set_inaddr(ccp2, buffer->isp_addr);
- return 0;
-}
-
-static const struct isp_video_operations ccp2_video_ops = {
- .queue = ccp2_video_queue,
-};
-
-/* -----------------------------------------------------------------------------
- * Media entity operations
- */
-
-/*
- * ccp2_link_setup - Setup ccp2 connections.
- * @entity : Pointer to media entity structure
- * @local : Pointer to local pad array
- * @remote : Pointer to remote pad array
- * @flags : Link flags
- * return -EINVAL on error or zero on success
- */
-static int ccp2_link_setup(struct media_entity *entity,
- const struct media_pad *local,
- const struct media_pad *remote, u32 flags)
-{
- struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
- struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
-
- switch (local->index | media_entity_type(remote->entity)) {
- case CCP2_PAD_SINK | MEDIA_ENT_T_DEVNODE:
- /* read from memory */
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (ccp2->input == CCP2_INPUT_SENSOR)
- return -EBUSY;
- ccp2->input = CCP2_INPUT_MEMORY;
- } else {
- if (ccp2->input == CCP2_INPUT_MEMORY)
- ccp2->input = CCP2_INPUT_NONE;
- }
- break;
-
- case CCP2_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
- /* read from sensor/phy */
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (ccp2->input == CCP2_INPUT_MEMORY)
- return -EBUSY;
- ccp2->input = CCP2_INPUT_SENSOR;
- } else {
- if (ccp2->input == CCP2_INPUT_SENSOR)
- ccp2->input = CCP2_INPUT_NONE;
- } break;
-
- case CCP2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
- /* write to video port/ccdc */
- if (flags & MEDIA_LNK_FL_ENABLED)
- ccp2->output = CCP2_OUTPUT_CCDC;
- else
- ccp2->output = CCP2_OUTPUT_NONE;
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* media operations */
-static const struct media_entity_operations ccp2_media_ops = {
- .link_setup = ccp2_link_setup,
- .link_validate = v4l2_subdev_link_validate,
-};
-
-/*
- * omap3isp_ccp2_unregister_entities - Unregister media entities: subdev
- * @ccp2: Pointer to ISP CCP2 device
- */
-void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2)
-{
- v4l2_device_unregister_subdev(&ccp2->subdev);
- omap3isp_video_unregister(&ccp2->video_in);
-}
-
-/*
- * omap3isp_ccp2_register_entities - Register the subdev media entity
- * @ccp2: Pointer to ISP CCP2 device
- * @vdev: Pointer to v4l device
- * return negative error code or zero on success
- */
-
-int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
- struct v4l2_device *vdev)
-{
- int ret;
-
- /* Register the subdev and video nodes. */
- ret = v4l2_device_register_subdev(vdev, &ccp2->subdev);
- if (ret < 0)
- goto error;
-
- ret = omap3isp_video_register(&ccp2->video_in, vdev);
- if (ret < 0)
- goto error;
-
- return 0;
-
-error:
- omap3isp_ccp2_unregister_entities(ccp2);
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * ISP ccp2 initialisation and cleanup
- */
-
-/*
- * ccp2_init_entities - Initialize ccp2 subdev and media entity.
- * @ccp2: Pointer to ISP CCP2 device
- * return negative error code or zero on success
- */
-static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
-{
- struct v4l2_subdev *sd = &ccp2->subdev;
- struct media_pad *pads = ccp2->pads;
- struct media_entity *me = &sd->entity;
- int ret;
-
- ccp2->input = CCP2_INPUT_NONE;
- ccp2->output = CCP2_OUTPUT_NONE;
-
- v4l2_subdev_init(sd, &ccp2_sd_ops);
- sd->internal_ops = &ccp2_sd_internal_ops;
- strlcpy(sd->name, "OMAP3 ISP CCP2", sizeof(sd->name));
- sd->grp_id = 1 << 16; /* group ID for isp subdevs */
- v4l2_set_subdevdata(sd, ccp2);
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- pads[CCP2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
-
- me->ops = &ccp2_media_ops;
- ret = media_entity_init(me, CCP2_PADS_NUM, pads, 0);
- if (ret < 0)
- return ret;
-
- ccp2_init_formats(sd, NULL);
-
- /*
- * The CCP2 has weird line alignment requirements, possibly caused by
- * DPCM8 decompression. Line length for data read from memory must be a
- * multiple of 128 bits (16 bytes) in continuous mode (when no padding
- * is present at end of lines). Additionally, if padding is used, the
- * padded line length must be a multiple of 32 bytes. To simplify the
- * implementation we use a fixed 32 bytes alignment regardless of the
- * input format and width. If strict 128 bits alignment support is
- * required ispvideo will need to be made aware of this special dual
- * alignement requirements.
- */
- ccp2->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- ccp2->video_in.bpl_alignment = 32;
- ccp2->video_in.bpl_max = 0xffffffe0;
- ccp2->video_in.isp = to_isp_device(ccp2);
- ccp2->video_in.ops = &ccp2_video_ops;
- ccp2->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
-
- ret = omap3isp_video_init(&ccp2->video_in, "CCP2");
- if (ret < 0)
- goto error_video;
-
- /* Connect the video node to the ccp2 subdev. */
- ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
- &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
- if (ret < 0)
- goto error_link;
-
- return 0;
-
-error_link:
- omap3isp_video_cleanup(&ccp2->video_in);
-error_video:
- media_entity_cleanup(&ccp2->subdev.entity);
- return ret;
-}
-
-/*
- * omap3isp_ccp2_init - CCP2 initialization.
- * @isp : Pointer to ISP device
- * return negative error code or zero on success
- */
-int omap3isp_ccp2_init(struct isp_device *isp)
-{
- struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;
- int ret;
-
- init_waitqueue_head(&ccp2->wait);
-
- /*
- * On the OMAP34xx the CSI1 receiver is operated in the CSIb IO
- * complex, which is powered by vdds_csib power rail. Hence the
- * request for the regulator.
- *
- * On the OMAP36xx, the CCP2 uses the CSI PHY1 or PHY2, shared with
- * the CSI2c or CSI2a receivers. The PHY then needs to be explicitly
- * configured.
- *
- * TODO: Don't hardcode the usage of PHY1 (shared with CSI2c).
- */
- if (isp->revision == ISP_REVISION_2_0) {
- ccp2->vdds_csib = regulator_get(isp->dev, "vdds_csib");
- if (IS_ERR(ccp2->vdds_csib)) {
- dev_dbg(isp->dev,
- "Could not get regulator vdds_csib\n");
- ccp2->vdds_csib = NULL;
- }
- } else if (isp->revision == ISP_REVISION_15_0) {
- ccp2->phy = &isp->isp_csiphy1;
- }
-
- ret = ccp2_init_entities(ccp2);
- if (ret < 0) {
- regulator_put(ccp2->vdds_csib);
- return ret;
- }
-
- ccp2_reset(ccp2);
- return 0;
-}
-
-/*
- * omap3isp_ccp2_cleanup - CCP2 un-initialization
- * @isp : Pointer to ISP device
- */
-void omap3isp_ccp2_cleanup(struct isp_device *isp)
-{
- struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;
-
- omap3isp_video_cleanup(&ccp2->video_in);
- media_entity_cleanup(&ccp2->subdev.entity);
-
- regulator_put(ccp2->vdds_csib);
-}
diff --git a/drivers/media/video/omap3isp/ispccp2.h b/drivers/media/video/omap3isp/ispccp2.h
deleted file mode 100644
index 76d65f4576e..00000000000
--- a/drivers/media/video/omap3isp/ispccp2.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * ispccp2.h
- *
- * TI OMAP3 ISP - CCP2 module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2010 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef OMAP3_ISP_CCP2_H
-#define OMAP3_ISP_CCP2_H
-
-#include <linux/videodev2.h>
-
-struct isp_device;
-struct isp_csiphy;
-
-/* Sink and source ccp2 pads */
-#define CCP2_PAD_SINK 0
-#define CCP2_PAD_SOURCE 1
-#define CCP2_PADS_NUM 2
-
-/* CCP2 input media entity */
-enum ccp2_input_entity {
- CCP2_INPUT_NONE,
- CCP2_INPUT_SENSOR,
- CCP2_INPUT_MEMORY,
-};
-
-/* CCP2 output media entity */
-enum ccp2_output_entity {
- CCP2_OUTPUT_NONE,
- CCP2_OUTPUT_CCDC,
- CCP2_OUTPUT_MEMORY,
-};
-
-
-/* Logical channel configuration */
-struct isp_interface_lcx_config {
- int crc;
- u32 data_start;
- u32 data_size;
- u32 format;
-};
-
-/* Memory channel configuration */
-struct isp_interface_mem_config {
- u32 dst_port;
- u32 vsize_count;
- u32 hsize_count;
- u32 src_ofst;
- u32 dst_ofst;
-};
-
-/* CCP2 device */
-struct isp_ccp2_device {
- struct v4l2_subdev subdev;
- struct v4l2_mbus_framefmt formats[CCP2_PADS_NUM];
- struct media_pad pads[CCP2_PADS_NUM];
-
- enum ccp2_input_entity input;
- enum ccp2_output_entity output;
- struct isp_interface_lcx_config if_cfg;
- struct isp_interface_mem_config mem_cfg;
- struct isp_video video_in;
- struct isp_csiphy *phy;
- struct regulator *vdds_csib;
- enum isp_pipeline_stream_state state;
- wait_queue_head_t wait;
- atomic_t stopping;
-};
-
-/* Function declarations */
-int omap3isp_ccp2_init(struct isp_device *isp);
-void omap3isp_ccp2_cleanup(struct isp_device *isp);
-int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
- struct v4l2_device *vdev);
-void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2);
-void omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2);
-
-#endif /* OMAP3_ISP_CCP2_H */
diff --git a/drivers/media/video/omap3isp/ispcsi2.c b/drivers/media/video/omap3isp/ispcsi2.c
deleted file mode 100644
index a1724362b6d..00000000000
--- a/drivers/media/video/omap3isp/ispcsi2.c
+++ /dev/null
@@ -1,1305 +0,0 @@
-/*
- * ispcsi2.c
- *
- * TI OMAP3 ISP - CSI2 module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-#include <linux/delay.h>
-#include <media/v4l2-common.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/mm.h>
-
-#include "isp.h"
-#include "ispreg.h"
-#include "ispcsi2.h"
-
-/*
- * csi2_if_enable - Enable CSI2 Receiver interface.
- * @enable: enable flag
- *
- */
-static void csi2_if_enable(struct isp_device *isp,
- struct isp_csi2_device *csi2, u8 enable)
-{
- struct isp_csi2_ctrl_cfg *currctrl = &csi2->ctrl;
-
- isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_CTRL, ISPCSI2_CTRL_IF_EN,
- enable ? ISPCSI2_CTRL_IF_EN : 0);
-
- currctrl->if_enable = enable;
-}
-
-/*
- * csi2_recv_config - CSI2 receiver module configuration.
- * @currctrl: isp_csi2_ctrl_cfg structure
- *
- */
-static void csi2_recv_config(struct isp_device *isp,
- struct isp_csi2_device *csi2,
- struct isp_csi2_ctrl_cfg *currctrl)
-{
- u32 reg;
-
- reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTRL);
-
- if (currctrl->frame_mode)
- reg |= ISPCSI2_CTRL_FRAME;
- else
- reg &= ~ISPCSI2_CTRL_FRAME;
-
- if (currctrl->vp_clk_enable)
- reg |= ISPCSI2_CTRL_VP_CLK_EN;
- else
- reg &= ~ISPCSI2_CTRL_VP_CLK_EN;
-
- if (currctrl->vp_only_enable)
- reg |= ISPCSI2_CTRL_VP_ONLY_EN;
- else
- reg &= ~ISPCSI2_CTRL_VP_ONLY_EN;
-
- reg &= ~ISPCSI2_CTRL_VP_OUT_CTRL_MASK;
- reg |= currctrl->vp_out_ctrl << ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT;
-
- if (currctrl->ecc_enable)
- reg |= ISPCSI2_CTRL_ECC_EN;
- else
- reg &= ~ISPCSI2_CTRL_ECC_EN;
-
- isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTRL);
-}
-
-static const unsigned int csi2_input_fmts[] = {
- V4L2_MBUS_FMT_SGRBG10_1X10,
- V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
- V4L2_MBUS_FMT_SRGGB10_1X10,
- V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8,
- V4L2_MBUS_FMT_SBGGR10_1X10,
- V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8,
- V4L2_MBUS_FMT_SGBRG10_1X10,
- V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8,
-};
-
-/* To set the format on the CSI2 requires a mapping function that takes
- * the following inputs:
- * - 2 different formats (at this time)
- * - 2 destinations (mem, vp+mem) (vp only handled separately)
- * - 2 decompression options (on, off)
- * - 2 isp revisions (certain format must be handled differently on OMAP3630)
- * Output should be CSI2 frame format code
- * Array indices as follows: [format][dest][decompr][is_3630]
- * Not all combinations are valid. 0 means invalid.
- */
-static const u16 __csi2_fmt_map[2][2][2][2] = {
- /* RAW10 formats */
- {
- /* Output to memory */
- {
- /* No DPCM decompression */
- { CSI2_PIX_FMT_RAW10_EXP16, CSI2_PIX_FMT_RAW10_EXP16 },
- /* DPCM decompression */
- { 0, 0 },
- },
- /* Output to both */
- {
- /* No DPCM decompression */
- { CSI2_PIX_FMT_RAW10_EXP16_VP,
- CSI2_PIX_FMT_RAW10_EXP16_VP },
- /* DPCM decompression */
- { 0, 0 },
- },
- },
- /* RAW10 DPCM8 formats */
- {
- /* Output to memory */
- {
- /* No DPCM decompression */
- { CSI2_PIX_FMT_RAW8, CSI2_USERDEF_8BIT_DATA1 },
- /* DPCM decompression */
- { CSI2_PIX_FMT_RAW8_DPCM10_EXP16,
- CSI2_USERDEF_8BIT_DATA1_DPCM10 },
- },
- /* Output to both */
- {
- /* No DPCM decompression */
- { CSI2_PIX_FMT_RAW8_VP,
- CSI2_PIX_FMT_RAW8_VP },
- /* DPCM decompression */
- { CSI2_PIX_FMT_RAW8_DPCM10_VP,
- CSI2_USERDEF_8BIT_DATA1_DPCM10_VP },
- },
- },
-};
-
-/*
- * csi2_ctx_map_format - Map CSI2 sink media bus format to CSI2 format ID
- * @csi2: ISP CSI2 device
- *
- * Returns CSI2 physical format id
- */
-static u16 csi2_ctx_map_format(struct isp_csi2_device *csi2)
-{
- const struct v4l2_mbus_framefmt *fmt = &csi2->formats[CSI2_PAD_SINK];
- int fmtidx, destidx, is_3630;
-
- switch (fmt->code) {
- case V4L2_MBUS_FMT_SGRBG10_1X10:
- case V4L2_MBUS_FMT_SRGGB10_1X10:
- case V4L2_MBUS_FMT_SBGGR10_1X10:
- case V4L2_MBUS_FMT_SGBRG10_1X10:
- fmtidx = 0;
- break;
- case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8:
- case V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8:
- case V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8:
- case V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8:
- fmtidx = 1;
- break;
- default:
- WARN(1, KERN_ERR "CSI2: pixel format %08x unsupported!\n",
- fmt->code);
- return 0;
- }
-
- if (!(csi2->output & CSI2_OUTPUT_CCDC) &&
- !(csi2->output & CSI2_OUTPUT_MEMORY)) {
- /* Neither output enabled is a valid combination */
- return CSI2_PIX_FMT_OTHERS;
- }
-
- /* If we need to skip frames at the beginning of the stream disable the
- * video port to avoid sending the skipped frames to the CCDC.
- */
- destidx = csi2->frame_skip ? 0 : !!(csi2->output & CSI2_OUTPUT_CCDC);
- is_3630 = csi2->isp->revision == ISP_REVISION_15_0;
-
- return __csi2_fmt_map[fmtidx][destidx][csi2->dpcm_decompress][is_3630];
-}
-
-/*
- * csi2_set_outaddr - Set memory address to save output image
- * @csi2: Pointer to ISP CSI2a device.
- * @addr: ISP MMU Mapped 32-bit memory address aligned on 32 byte boundary.
- *
- * Sets the memory address where the output will be saved.
- *
- * Returns 0 if successful, or -EINVAL if the address is not in the 32 byte
- * boundary.
- */
-static void csi2_set_outaddr(struct isp_csi2_device *csi2, u32 addr)
-{
- struct isp_device *isp = csi2->isp;
- struct isp_csi2_ctx_cfg *ctx = &csi2->contexts[0];
-
- ctx->ping_addr = addr;
- ctx->pong_addr = addr;
- isp_reg_writel(isp, ctx->ping_addr,
- csi2->regs1, ISPCSI2_CTX_DAT_PING_ADDR(ctx->ctxnum));
- isp_reg_writel(isp, ctx->pong_addr,
- csi2->regs1, ISPCSI2_CTX_DAT_PONG_ADDR(ctx->ctxnum));
-}
-
-/*
- * is_usr_def_mapping - Checks whether USER_DEF_MAPPING should
- * be enabled by CSI2.
- * @format_id: mapped format id
- *
- */
-static inline int is_usr_def_mapping(u32 format_id)
-{
- return (format_id & 0x40) ? 1 : 0;
-}
-
-/*
- * csi2_ctx_enable - Enable specified CSI2 context
- * @ctxnum: Context number, valid between 0 and 7 values.
- * @enable: enable
- *
- */
-static void csi2_ctx_enable(struct isp_device *isp,
- struct isp_csi2_device *csi2, u8 ctxnum, u8 enable)
-{
- struct isp_csi2_ctx_cfg *ctx = &csi2->contexts[ctxnum];
- unsigned int skip = 0;
- u32 reg;
-
- reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL1(ctxnum));
-
- if (enable) {
- if (csi2->frame_skip)
- skip = csi2->frame_skip;
- else if (csi2->output & CSI2_OUTPUT_MEMORY)
- skip = 1;
-
- reg &= ~ISPCSI2_CTX_CTRL1_COUNT_MASK;
- reg |= ISPCSI2_CTX_CTRL1_COUNT_UNLOCK
- | (skip << ISPCSI2_CTX_CTRL1_COUNT_SHIFT)
- | ISPCSI2_CTX_CTRL1_CTX_EN;
- } else {
- reg &= ~ISPCSI2_CTX_CTRL1_CTX_EN;
- }
-
- isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL1(ctxnum));
- ctx->enabled = enable;
-}
-
-/*
- * csi2_ctx_config - CSI2 context configuration.
- * @ctx: context configuration
- *
- */
-static void csi2_ctx_config(struct isp_device *isp,
- struct isp_csi2_device *csi2,
- struct isp_csi2_ctx_cfg *ctx)
-{
- u32 reg;
-
- /* Set up CSI2_CTx_CTRL1 */
- reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL1(ctx->ctxnum));
-
- if (ctx->eof_enabled)
- reg |= ISPCSI2_CTX_CTRL1_EOF_EN;
- else
- reg &= ~ISPCSI2_CTX_CTRL1_EOF_EN;
-
- if (ctx->eol_enabled)
- reg |= ISPCSI2_CTX_CTRL1_EOL_EN;
- else
- reg &= ~ISPCSI2_CTX_CTRL1_EOL_EN;
-
- if (ctx->checksum_enabled)
- reg |= ISPCSI2_CTX_CTRL1_CS_EN;
- else
- reg &= ~ISPCSI2_CTX_CTRL1_CS_EN;
-
- isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL1(ctx->ctxnum));
-
- /* Set up CSI2_CTx_CTRL2 */
- reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL2(ctx->ctxnum));
-
- reg &= ~(ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK);
- reg |= ctx->virtual_id << ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT;
-
- reg &= ~(ISPCSI2_CTX_CTRL2_FORMAT_MASK);
- reg |= ctx->format_id << ISPCSI2_CTX_CTRL2_FORMAT_SHIFT;
-
- if (ctx->dpcm_decompress) {
- if (ctx->dpcm_predictor)
- reg |= ISPCSI2_CTX_CTRL2_DPCM_PRED;
- else
- reg &= ~ISPCSI2_CTX_CTRL2_DPCM_PRED;
- }
-
- if (is_usr_def_mapping(ctx->format_id)) {
- reg &= ~ISPCSI2_CTX_CTRL2_USER_DEF_MAP_MASK;
- reg |= 2 << ISPCSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT;
- }
-
- isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL2(ctx->ctxnum));
-
- /* Set up CSI2_CTx_CTRL3 */
- reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL3(ctx->ctxnum));
- reg &= ~(ISPCSI2_CTX_CTRL3_ALPHA_MASK);
- reg |= (ctx->alpha << ISPCSI2_CTX_CTRL3_ALPHA_SHIFT);
-
- isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL3(ctx->ctxnum));
-
- /* Set up CSI2_CTx_DAT_OFST */
- reg = isp_reg_readl(isp, csi2->regs1,
- ISPCSI2_CTX_DAT_OFST(ctx->ctxnum));
- reg &= ~ISPCSI2_CTX_DAT_OFST_OFST_MASK;
- reg |= ctx->data_offset << ISPCSI2_CTX_DAT_OFST_OFST_SHIFT;
- isp_reg_writel(isp, reg, csi2->regs1,
- ISPCSI2_CTX_DAT_OFST(ctx->ctxnum));
-
- isp_reg_writel(isp, ctx->ping_addr,
- csi2->regs1, ISPCSI2_CTX_DAT_PING_ADDR(ctx->ctxnum));
-
- isp_reg_writel(isp, ctx->pong_addr,
- csi2->regs1, ISPCSI2_CTX_DAT_PONG_ADDR(ctx->ctxnum));
-}
-
-/*
- * csi2_timing_config - CSI2 timing configuration.
- * @timing: csi2_timing_cfg structure
- */
-static void csi2_timing_config(struct isp_device *isp,
- struct isp_csi2_device *csi2,
- struct isp_csi2_timing_cfg *timing)
-{
- u32 reg;
-
- reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_TIMING);
-
- if (timing->force_rx_mode)
- reg |= ISPCSI2_TIMING_FORCE_RX_MODE_IO(timing->ionum);
- else
- reg &= ~ISPCSI2_TIMING_FORCE_RX_MODE_IO(timing->ionum);
-
- if (timing->stop_state_16x)
- reg |= ISPCSI2_TIMING_STOP_STATE_X16_IO(timing->ionum);
- else
- reg &= ~ISPCSI2_TIMING_STOP_STATE_X16_IO(timing->ionum);
-
- if (timing->stop_state_4x)
- reg |= ISPCSI2_TIMING_STOP_STATE_X4_IO(timing->ionum);
- else
- reg &= ~ISPCSI2_TIMING_STOP_STATE_X4_IO(timing->ionum);
-
- reg &= ~ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(timing->ionum);
- reg |= timing->stop_state_counter <<
- ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(timing->ionum);
-
- isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_TIMING);
-}
-
-/*
- * csi2_irq_ctx_set - Enables CSI2 Context IRQs.
- * @enable: Enable/disable CSI2 Context interrupts
- */
-static void csi2_irq_ctx_set(struct isp_device *isp,
- struct isp_csi2_device *csi2, int enable)
-{
- int i;
-
- for (i = 0; i < 8; i++) {
- isp_reg_writel(isp, ISPCSI2_CTX_IRQSTATUS_FE_IRQ, csi2->regs1,
- ISPCSI2_CTX_IRQSTATUS(i));
- if (enable)
- isp_reg_set(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i),
- ISPCSI2_CTX_IRQSTATUS_FE_IRQ);
- else
- isp_reg_clr(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i),
- ISPCSI2_CTX_IRQSTATUS_FE_IRQ);
- }
-}
-
-/*
- * csi2_irq_complexio1_set - Enables CSI2 ComplexIO IRQs.
- * @enable: Enable/disable CSI2 ComplexIO #1 interrupts
- */
-static void csi2_irq_complexio1_set(struct isp_device *isp,
- struct isp_csi2_device *csi2, int enable)
-{
- u32 reg;
- reg = ISPCSI2_PHY_IRQENABLE_STATEALLULPMEXIT |
- ISPCSI2_PHY_IRQENABLE_STATEALLULPMENTER |
- ISPCSI2_PHY_IRQENABLE_STATEULPM5 |
- ISPCSI2_PHY_IRQENABLE_ERRCONTROL5 |
- ISPCSI2_PHY_IRQENABLE_ERRESC5 |
- ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS5 |
- ISPCSI2_PHY_IRQENABLE_ERRSOTHS5 |
- ISPCSI2_PHY_IRQENABLE_STATEULPM4 |
- ISPCSI2_PHY_IRQENABLE_ERRCONTROL4 |
- ISPCSI2_PHY_IRQENABLE_ERRESC4 |
- ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS4 |
- ISPCSI2_PHY_IRQENABLE_ERRSOTHS4 |
- ISPCSI2_PHY_IRQENABLE_STATEULPM3 |
- ISPCSI2_PHY_IRQENABLE_ERRCONTROL3 |
- ISPCSI2_PHY_IRQENABLE_ERRESC3 |
- ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS3 |
- ISPCSI2_PHY_IRQENABLE_ERRSOTHS3 |
- ISPCSI2_PHY_IRQENABLE_STATEULPM2 |
- ISPCSI2_PHY_IRQENABLE_ERRCONTROL2 |
- ISPCSI2_PHY_IRQENABLE_ERRESC2 |
- ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS2 |
- ISPCSI2_PHY_IRQENABLE_ERRSOTHS2 |
- ISPCSI2_PHY_IRQENABLE_STATEULPM1 |
- ISPCSI2_PHY_IRQENABLE_ERRCONTROL1 |
- ISPCSI2_PHY_IRQENABLE_ERRESC1 |
- ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS1 |
- ISPCSI2_PHY_IRQENABLE_ERRSOTHS1;
- isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_PHY_IRQSTATUS);
- if (enable)
- reg |= isp_reg_readl(isp, csi2->regs1, ISPCSI2_PHY_IRQENABLE);
- else
- reg = 0;
- isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_PHY_IRQENABLE);
-}
-
-/*
- * csi2_irq_status_set - Enables CSI2 Status IRQs.
- * @enable: Enable/disable CSI2 Status interrupts
- */
-static void csi2_irq_status_set(struct isp_device *isp,
- struct isp_csi2_device *csi2, int enable)
-{
- u32 reg;
- reg = ISPCSI2_IRQSTATUS_OCP_ERR_IRQ |
- ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ |
- ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ |
- ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ |
- ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ |
- ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ |
- ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ |
- ISPCSI2_IRQSTATUS_CONTEXT(0);
- isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_IRQSTATUS);
- if (enable)
- reg |= isp_reg_readl(isp, csi2->regs1, ISPCSI2_IRQENABLE);
- else
- reg = 0;
-
- isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_IRQENABLE);
-}
-
-/*
- * omap3isp_csi2_reset - Resets the CSI2 module.
- *
- * Must be called with the phy lock held.
- *
- * Returns 0 if successful, or -EBUSY if power command didn't respond.
- */
-int omap3isp_csi2_reset(struct isp_csi2_device *csi2)
-{
- struct isp_device *isp = csi2->isp;
- u8 soft_reset_retries = 0;
- u32 reg;
- int i;
-
- if (!csi2->available)
- return -ENODEV;
-
- if (csi2->phy->phy_in_use)
- return -EBUSY;
-
- isp_reg_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
- ISPCSI2_SYSCONFIG_SOFT_RESET);
-
- do {
- reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_SYSSTATUS) &
- ISPCSI2_SYSSTATUS_RESET_DONE;
- if (reg == ISPCSI2_SYSSTATUS_RESET_DONE)
- break;
- soft_reset_retries++;
- if (soft_reset_retries < 5)
- udelay(100);
- } while (soft_reset_retries < 5);
-
- if (soft_reset_retries == 5) {
- printk(KERN_ERR "CSI2: Soft reset try count exceeded!\n");
- return -EBUSY;
- }
-
- if (isp->revision == ISP_REVISION_15_0)
- isp_reg_set(isp, csi2->regs1, ISPCSI2_PHY_CFG,
- ISPCSI2_PHY_CFG_RESET_CTRL);
-
- i = 100;
- do {
- reg = isp_reg_readl(isp, csi2->phy->phy_regs, ISPCSIPHY_REG1)
- & ISPCSIPHY_REG1_RESET_DONE_CTRLCLK;
- if (reg == ISPCSIPHY_REG1_RESET_DONE_CTRLCLK)
- break;
- udelay(100);
- } while (--i > 0);
-
- if (i == 0) {
- printk(KERN_ERR
- "CSI2: Reset for CSI2_96M_FCLK domain Failed!\n");
- return -EBUSY;
- }
-
- if (isp->autoidle)
- isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
- ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK |
- ISPCSI2_SYSCONFIG_AUTO_IDLE,
- ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SMART |
- ((isp->revision == ISP_REVISION_15_0) ?
- ISPCSI2_SYSCONFIG_AUTO_IDLE : 0));
- else
- isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
- ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK |
- ISPCSI2_SYSCONFIG_AUTO_IDLE,
- ISPCSI2_SYSCONFIG_MSTANDBY_MODE_NO);
-
- return 0;
-}
-
-static int csi2_configure(struct isp_csi2_device *csi2)
-{
- const struct isp_v4l2_subdevs_group *pdata;
- struct isp_device *isp = csi2->isp;
- struct isp_csi2_timing_cfg *timing = &csi2->timing[0];
- struct v4l2_subdev *sensor;
- struct media_pad *pad;
-
- /*
- * CSI2 fields that can be updated while the context has
- * been enabled or the interface has been enabled are not
- * updated dynamically currently. So we do not allow to
- * reconfigure if either has been enabled
- */
- if (csi2->contexts[0].enabled || csi2->ctrl.if_enable)
- return -EBUSY;
-
- pad = media_entity_remote_source(&csi2->pads[CSI2_PAD_SINK]);
- sensor = media_entity_to_v4l2_subdev(pad->entity);
- pdata = sensor->host_priv;
-
- csi2->frame_skip = 0;
- v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip);
-
- csi2->ctrl.vp_out_ctrl = pdata->bus.csi2.vpclk_div;
- csi2->ctrl.frame_mode = ISP_CSI2_FRAME_IMMEDIATE;
- csi2->ctrl.ecc_enable = pdata->bus.csi2.crc;
-
- timing->ionum = 1;
- timing->force_rx_mode = 1;
- timing->stop_state_16x = 1;
- timing->stop_state_4x = 1;
- timing->stop_state_counter = 0x1FF;
-
- /*
- * The CSI2 receiver can't do any format conversion except DPCM
- * decompression, so every set_format call configures both pads
- * and enables DPCM decompression as a special case:
- */
- if (csi2->formats[CSI2_PAD_SINK].code !=
- csi2->formats[CSI2_PAD_SOURCE].code)
- csi2->dpcm_decompress = true;
- else
- csi2->dpcm_decompress = false;
-
- csi2->contexts[0].format_id = csi2_ctx_map_format(csi2);
-
- if (csi2->video_out.bpl_padding == 0)
- csi2->contexts[0].data_offset = 0;
- else
- csi2->contexts[0].data_offset = csi2->video_out.bpl_value;
-
- /*
- * Enable end of frame and end of line signals generation for
- * context 0. These signals are generated from CSI2 receiver to
- * qualify the last pixel of a frame and the last pixel of a line.
- * Without enabling the signals CSI2 receiver writes data to memory
- * beyond buffer size and/or data line offset is not handled correctly.
- */
- csi2->contexts[0].eof_enabled = 1;
- csi2->contexts[0].eol_enabled = 1;
-
- csi2_irq_complexio1_set(isp, csi2, 1);
- csi2_irq_ctx_set(isp, csi2, 1);
- csi2_irq_status_set(isp, csi2, 1);
-
- /* Set configuration (timings, format and links) */
- csi2_timing_config(isp, csi2, timing);
- csi2_recv_config(isp, csi2, &csi2->ctrl);
- csi2_ctx_config(isp, csi2, &csi2->contexts[0]);
-
- return 0;
-}
-
-/*
- * csi2_print_status - Prints CSI2 debug information.
- */
-#define CSI2_PRINT_REGISTER(isp, regs, name)\
- dev_dbg(isp->dev, "###CSI2 " #name "=0x%08x\n", \
- isp_reg_readl(isp, regs, ISPCSI2_##name))
-
-static void csi2_print_status(struct isp_csi2_device *csi2)
-{
- struct isp_device *isp = csi2->isp;
-
- if (!csi2->available)
- return;
-
- dev_dbg(isp->dev, "-------------CSI2 Register dump-------------\n");
-
- CSI2_PRINT_REGISTER(isp, csi2->regs1, SYSCONFIG);
- CSI2_PRINT_REGISTER(isp, csi2->regs1, SYSSTATUS);
- CSI2_PRINT_REGISTER(isp, csi2->regs1, IRQENABLE);
- CSI2_PRINT_REGISTER(isp, csi2->regs1, IRQSTATUS);
- CSI2_PRINT_REGISTER(isp, csi2->regs1, CTRL);
- CSI2_PRINT_REGISTER(isp, csi2->regs1, DBG_H);
- CSI2_PRINT_REGISTER(isp, csi2->regs1, GNQ);
- CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_CFG);
- CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_IRQSTATUS);
- CSI2_PRINT_REGISTER(isp, csi2->regs1, SHORT_PACKET);
- CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_IRQENABLE);
- CSI2_PRINT_REGISTER(isp, csi2->regs1, DBG_P);
- CSI2_PRINT_REGISTER(isp, csi2->regs1, TIMING);
- CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL1(0));
- CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL2(0));
- CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_OFST(0));
- CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_PING_ADDR(0));
- CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_PONG_ADDR(0));
- CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_IRQENABLE(0));
- CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_IRQSTATUS(0));
- CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL3(0));
-
- dev_dbg(isp->dev, "--------------------------------------------\n");
-}
-
-/* -----------------------------------------------------------------------------
- * Interrupt handling
- */
-
-/*
- * csi2_isr_buffer - Does buffer handling at end-of-frame
- * when writing to memory.
- */
-static void csi2_isr_buffer(struct isp_csi2_device *csi2)
-{
- struct isp_device *isp = csi2->isp;
- struct isp_buffer *buffer;
-
- csi2_ctx_enable(isp, csi2, 0, 0);
-
- buffer = omap3isp_video_buffer_next(&csi2->video_out);
-
- /*
- * Let video queue operation restart engine if there is an underrun
- * condition.
- */
- if (buffer == NULL)
- return;
-
- csi2_set_outaddr(csi2, buffer->isp_addr);
- csi2_ctx_enable(isp, csi2, 0, 1);
-}
-
-static void csi2_isr_ctx(struct isp_csi2_device *csi2,
- struct isp_csi2_ctx_cfg *ctx)
-{
- struct isp_device *isp = csi2->isp;
- unsigned int n = ctx->ctxnum;
- u32 status;
-
- status = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_IRQSTATUS(n));
- isp_reg_writel(isp, status, csi2->regs1, ISPCSI2_CTX_IRQSTATUS(n));
-
- if (!(status & ISPCSI2_CTX_IRQSTATUS_FE_IRQ))
- return;
-
- /* Skip interrupts until we reach the frame skip count. The CSI2 will be
- * automatically disabled, as the frame skip count has been programmed
- * in the CSI2_CTx_CTRL1::COUNT field, so reenable it.
- *
- * It would have been nice to rely on the FRAME_NUMBER interrupt instead
- * but it turned out that the interrupt is only generated when the CSI2
- * writes to memory (the CSI2_CTx_CTRL1::COUNT field is decreased
- * correctly and reaches 0 when data is forwarded to the video port only
- * but no interrupt arrives). Maybe a CSI2 hardware bug.
- */
- if (csi2->frame_skip) {
- csi2->frame_skip--;
- if (csi2->frame_skip == 0) {
- ctx->format_id = csi2_ctx_map_format(csi2);
- csi2_ctx_config(isp, csi2, ctx);
- csi2_ctx_enable(isp, csi2, n, 1);
- }
- return;
- }
-
- if (csi2->output & CSI2_OUTPUT_MEMORY)
- csi2_isr_buffer(csi2);
-}
-
-/*
- * omap3isp_csi2_isr - CSI2 interrupt handling.
- */
-void omap3isp_csi2_isr(struct isp_csi2_device *csi2)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity);
- u32 csi2_irqstatus, cpxio1_irqstatus;
- struct isp_device *isp = csi2->isp;
-
- if (!csi2->available)
- return;
-
- csi2_irqstatus = isp_reg_readl(isp, csi2->regs1, ISPCSI2_IRQSTATUS);
- isp_reg_writel(isp, csi2_irqstatus, csi2->regs1, ISPCSI2_IRQSTATUS);
-
- /* Failure Cases */
- if (csi2_irqstatus & ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ) {
- cpxio1_irqstatus = isp_reg_readl(isp, csi2->regs1,
- ISPCSI2_PHY_IRQSTATUS);
- isp_reg_writel(isp, cpxio1_irqstatus,
- csi2->regs1, ISPCSI2_PHY_IRQSTATUS);
- dev_dbg(isp->dev, "CSI2: ComplexIO Error IRQ "
- "%x\n", cpxio1_irqstatus);
- pipe->error = true;
- }
-
- if (csi2_irqstatus & (ISPCSI2_IRQSTATUS_OCP_ERR_IRQ |
- ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ |
- ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ |
- ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ |
- ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ)) {
- dev_dbg(isp->dev, "CSI2 Err:"
- " OCP:%d,"
- " Short_pack:%d,"
- " ECC:%d,"
- " CPXIO2:%d,"
- " FIFO_OVF:%d,"
- "\n",
- (csi2_irqstatus &
- ISPCSI2_IRQSTATUS_OCP_ERR_IRQ) ? 1 : 0,
- (csi2_irqstatus &
- ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ) ? 1 : 0,
- (csi2_irqstatus &
- ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ) ? 1 : 0,
- (csi2_irqstatus &
- ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ) ? 1 : 0,
- (csi2_irqstatus &
- ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ) ? 1 : 0);
- pipe->error = true;
- }
-
- if (omap3isp_module_sync_is_stopping(&csi2->wait, &csi2->stopping))
- return;
-
- /* Successful cases */
- if (csi2_irqstatus & ISPCSI2_IRQSTATUS_CONTEXT(0))
- csi2_isr_ctx(csi2, &csi2->contexts[0]);
-
- if (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ)
- dev_dbg(isp->dev, "CSI2: ECC correction done\n");
-}
-
-/* -----------------------------------------------------------------------------
- * ISP video operations
- */
-
-/*
- * csi2_queue - Queues the first buffer when using memory output
- * @video: The video node
- * @buffer: buffer to queue
- */
-static int csi2_queue(struct isp_video *video, struct isp_buffer *buffer)
-{
- struct isp_device *isp = video->isp;
- struct isp_csi2_device *csi2 = &isp->isp_csi2a;
-
- csi2_set_outaddr(csi2, buffer->isp_addr);
-
- /*
- * If streaming was enabled before there was a buffer queued
- * or underrun happened in the ISR, the hardware was not enabled
- * and DMA queue flag ISP_VIDEO_DMAQUEUE_UNDERRUN is still set.
- * Enable it now.
- */
- if (csi2->video_out.dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) {
- /* Enable / disable context 0 and IRQs */
- csi2_if_enable(isp, csi2, 1);
- csi2_ctx_enable(isp, csi2, 0, 1);
- isp_video_dmaqueue_flags_clr(&csi2->video_out);
- }
-
- return 0;
-}
-
-static const struct isp_video_operations csi2_ispvideo_ops = {
- .queue = csi2_queue,
-};
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev operations
- */
-
-static struct v4l2_mbus_framefmt *
-__csi2_get_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh,
- unsigned int pad, enum v4l2_subdev_format_whence which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_format(fh, pad);
- else
- return &csi2->formats[pad];
-}
-
-static void
-csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh,
- unsigned int pad, struct v4l2_mbus_framefmt *fmt,
- enum v4l2_subdev_format_whence which)
-{
- enum v4l2_mbus_pixelcode pixelcode;
- struct v4l2_mbus_framefmt *format;
- const struct isp_format_info *info;
- unsigned int i;
-
- switch (pad) {
- case CSI2_PAD_SINK:
- /* Clamp the width and height to valid range (1-8191). */
- for (i = 0; i < ARRAY_SIZE(csi2_input_fmts); i++) {
- if (fmt->code == csi2_input_fmts[i])
- break;
- }
-
- /* If not found, use SGRBG10 as default */
- if (i >= ARRAY_SIZE(csi2_input_fmts))
- fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
-
- fmt->width = clamp_t(u32, fmt->width, 1, 8191);
- fmt->height = clamp_t(u32, fmt->height, 1, 8191);
- break;
-
- case CSI2_PAD_SOURCE:
- /* Source format same as sink format, except for DPCM
- * compression.
- */
- pixelcode = fmt->code;
- format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK, which);
- memcpy(fmt, format, sizeof(*fmt));
-
- /*
- * Only Allow DPCM decompression, and check that the
- * pattern is preserved
- */
- info = omap3isp_video_format_info(fmt->code);
- if (info->uncompressed == pixelcode)
- fmt->code = pixelcode;
- break;
- }
-
- /* RGB, non-interlaced */
- fmt->colorspace = V4L2_COLORSPACE_SRGB;
- fmt->field = V4L2_FIELD_NONE;
-}
-
-/*
- * csi2_enum_mbus_code - Handle pixel format enumeration
- * @sd : pointer to v4l2 subdev structure
- * @fh : V4L2 subdev file handle
- * @code : pointer to v4l2_subdev_mbus_code_enum structure
- * return -EINVAL or zero on success
- */
-static int csi2_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
- const struct isp_format_info *info;
-
- if (code->pad == CSI2_PAD_SINK) {
- if (code->index >= ARRAY_SIZE(csi2_input_fmts))
- return -EINVAL;
-
- code->code = csi2_input_fmts[code->index];
- } else {
- format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK,
- V4L2_SUBDEV_FORMAT_TRY);
- switch (code->index) {
- case 0:
- /* Passthrough sink pad code */
- code->code = format->code;
- break;
- case 1:
- /* Uncompressed code */
- info = omap3isp_video_format_info(format->code);
- if (info->uncompressed == format->code)
- return -EINVAL;
-
- code->code = info->uncompressed;
- break;
- default:
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int csi2_enum_frame_size(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_frame_size_enum *fse)
-{
- struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt format;
-
- if (fse->index != 0)
- return -EINVAL;
-
- format.code = fse->code;
- format.width = 1;
- format.height = 1;
- csi2_try_format(csi2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
- fse->min_width = format.width;
- fse->min_height = format.height;
-
- if (format.code != fse->code)
- return -EINVAL;
-
- format.code = fse->code;
- format.width = -1;
- format.height = -1;
- csi2_try_format(csi2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
- fse->max_width = format.width;
- fse->max_height = format.height;
-
- return 0;
-}
-
-/*
- * csi2_get_format - Handle get format by pads subdev method
- * @sd : pointer to v4l2 subdev structure
- * @fh : V4L2 subdev file handle
- * @fmt: pointer to v4l2 subdev format structure
- * return -EINVAL or zero on success
- */
-static int csi2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
-
- format = __csi2_get_format(csi2, fh, fmt->pad, fmt->which);
- if (format == NULL)
- return -EINVAL;
-
- fmt->format = *format;
- return 0;
-}
-
-/*
- * csi2_set_format - Handle set format by pads subdev method
- * @sd : pointer to v4l2 subdev structure
- * @fh : V4L2 subdev file handle
- * @fmt: pointer to v4l2 subdev format structure
- * return -EINVAL or zero on success
- */
-static int csi2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
-
- format = __csi2_get_format(csi2, fh, fmt->pad, fmt->which);
- if (format == NULL)
- return -EINVAL;
-
- csi2_try_format(csi2, fh, fmt->pad, &fmt->format, fmt->which);
- *format = fmt->format;
-
- /* Propagate the format from sink to source */
- if (fmt->pad == CSI2_PAD_SINK) {
- format = __csi2_get_format(csi2, fh, CSI2_PAD_SOURCE,
- fmt->which);
- *format = fmt->format;
- csi2_try_format(csi2, fh, CSI2_PAD_SOURCE, format, fmt->which);
- }
-
- return 0;
-}
-
-/*
- * csi2_init_formats - Initialize formats on all pads
- * @sd: ISP CSI2 V4L2 subdevice
- * @fh: V4L2 subdev file handle
- *
- * Initialize all pad formats with default values. If fh is not NULL, try
- * formats are initialized on the file handle. Otherwise active formats are
- * initialized on the device.
- */
-static int csi2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- struct v4l2_subdev_format format;
-
- memset(&format, 0, sizeof(format));
- format.pad = CSI2_PAD_SINK;
- format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
- format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
- format.format.width = 4096;
- format.format.height = 4096;
- csi2_set_format(sd, fh, &format);
-
- return 0;
-}
-
-/*
- * csi2_set_stream - Enable/Disable streaming on the CSI2 module
- * @sd: ISP CSI2 V4L2 subdevice
- * @enable: ISP pipeline stream state
- *
- * Return 0 on success or a negative error code otherwise.
- */
-static int csi2_set_stream(struct v4l2_subdev *sd, int enable)
-{
- struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
- struct isp_device *isp = csi2->isp;
- struct isp_video *video_out = &csi2->video_out;
-
- switch (enable) {
- case ISP_PIPELINE_STREAM_CONTINUOUS:
- if (omap3isp_csiphy_acquire(csi2->phy) < 0)
- return -ENODEV;
- if (csi2->output & CSI2_OUTPUT_MEMORY)
- omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI2A_WRITE);
- csi2_configure(csi2);
- csi2_print_status(csi2);
-
- /*
- * When outputting to memory with no buffer available, let the
- * buffer queue handler start the hardware. A DMA queue flag
- * ISP_VIDEO_DMAQUEUE_QUEUED will be set as soon as there is
- * a buffer available.
- */
- if (csi2->output & CSI2_OUTPUT_MEMORY &&
- !(video_out->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED))
- break;
- /* Enable context 0 and IRQs */
- atomic_set(&csi2->stopping, 0);
- csi2_ctx_enable(isp, csi2, 0, 1);
- csi2_if_enable(isp, csi2, 1);
- isp_video_dmaqueue_flags_clr(video_out);
- break;
-
- case ISP_PIPELINE_STREAM_STOPPED:
- if (csi2->state == ISP_PIPELINE_STREAM_STOPPED)
- return 0;
- if (omap3isp_module_sync_idle(&sd->entity, &csi2->wait,
- &csi2->stopping))
- dev_dbg(isp->dev, "%s: module stop timeout.\n",
- sd->name);
- csi2_ctx_enable(isp, csi2, 0, 0);
- csi2_if_enable(isp, csi2, 0);
- csi2_irq_ctx_set(isp, csi2, 0);
- omap3isp_csiphy_release(csi2->phy);
- isp_video_dmaqueue_flags_clr(video_out);
- omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CSI2A_WRITE);
- break;
- }
-
- csi2->state = enable;
- return 0;
-}
-
-/* subdev video operations */
-static const struct v4l2_subdev_video_ops csi2_video_ops = {
- .s_stream = csi2_set_stream,
-};
-
-/* subdev pad operations */
-static const struct v4l2_subdev_pad_ops csi2_pad_ops = {
- .enum_mbus_code = csi2_enum_mbus_code,
- .enum_frame_size = csi2_enum_frame_size,
- .get_fmt = csi2_get_format,
- .set_fmt = csi2_set_format,
-};
-
-/* subdev operations */
-static const struct v4l2_subdev_ops csi2_ops = {
- .video = &csi2_video_ops,
- .pad = &csi2_pad_ops,
-};
-
-/* subdev internal operations */
-static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
- .open = csi2_init_formats,
-};
-
-/* -----------------------------------------------------------------------------
- * Media entity operations
- */
-
-/*
- * csi2_link_setup - Setup CSI2 connections.
- * @entity : Pointer to media entity structure
- * @local : Pointer to local pad array
- * @remote : Pointer to remote pad array
- * @flags : Link flags
- * return -EINVAL or zero on success
- */
-static int csi2_link_setup(struct media_entity *entity,
- const struct media_pad *local,
- const struct media_pad *remote, u32 flags)
-{
- struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
- struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
- struct isp_csi2_ctrl_cfg *ctrl = &csi2->ctrl;
-
- /*
- * The ISP core doesn't support pipelines with multiple video outputs.
- * Revisit this when it will be implemented, and return -EBUSY for now.
- */
-
- switch (local->index | media_entity_type(remote->entity)) {
- case CSI2_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (csi2->output & ~CSI2_OUTPUT_MEMORY)
- return -EBUSY;
- csi2->output |= CSI2_OUTPUT_MEMORY;
- } else {
- csi2->output &= ~CSI2_OUTPUT_MEMORY;
- }
- break;
-
- case CSI2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (csi2->output & ~CSI2_OUTPUT_CCDC)
- return -EBUSY;
- csi2->output |= CSI2_OUTPUT_CCDC;
- } else {
- csi2->output &= ~CSI2_OUTPUT_CCDC;
- }
- break;
-
- default:
- /* Link from camera to CSI2 is fixed... */
- return -EINVAL;
- }
-
- ctrl->vp_only_enable =
- (csi2->output & CSI2_OUTPUT_MEMORY) ? false : true;
- ctrl->vp_clk_enable = !!(csi2->output & CSI2_OUTPUT_CCDC);
-
- return 0;
-}
-
-/* media operations */
-static const struct media_entity_operations csi2_media_ops = {
- .link_setup = csi2_link_setup,
- .link_validate = v4l2_subdev_link_validate,
-};
-
-void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2)
-{
- v4l2_device_unregister_subdev(&csi2->subdev);
- omap3isp_video_unregister(&csi2->video_out);
-}
-
-int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2,
- struct v4l2_device *vdev)
-{
- int ret;
-
- /* Register the subdev and video nodes. */
- ret = v4l2_device_register_subdev(vdev, &csi2->subdev);
- if (ret < 0)
- goto error;
-
- ret = omap3isp_video_register(&csi2->video_out, vdev);
- if (ret < 0)
- goto error;
-
- return 0;
-
-error:
- omap3isp_csi2_unregister_entities(csi2);
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * ISP CSI2 initialisation and cleanup
- */
-
-/*
- * csi2_init_entities - Initialize subdev and media entity.
- * @csi2: Pointer to csi2 structure.
- * return -ENOMEM or zero on success
- */
-static int csi2_init_entities(struct isp_csi2_device *csi2)
-{
- struct v4l2_subdev *sd = &csi2->subdev;
- struct media_pad *pads = csi2->pads;
- struct media_entity *me = &sd->entity;
- int ret;
-
- v4l2_subdev_init(sd, &csi2_ops);
- sd->internal_ops = &csi2_internal_ops;
- strlcpy(sd->name, "OMAP3 ISP CSI2a", sizeof(sd->name));
-
- sd->grp_id = 1 << 16; /* group ID for isp subdevs */
- v4l2_set_subdevdata(sd, csi2);
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- pads[CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
- pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
-
- me->ops = &csi2_media_ops;
- ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0);
- if (ret < 0)
- return ret;
-
- csi2_init_formats(sd, NULL);
-
- /* Video device node */
- csi2->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- csi2->video_out.ops = &csi2_ispvideo_ops;
- csi2->video_out.bpl_alignment = 32;
- csi2->video_out.bpl_zero_padding = 1;
- csi2->video_out.bpl_max = 0x1ffe0;
- csi2->video_out.isp = csi2->isp;
- csi2->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
-
- ret = omap3isp_video_init(&csi2->video_out, "CSI2a");
- if (ret < 0)
- goto error_video;
-
- /* Connect the CSI2 subdev to the video node. */
- ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
- &csi2->video_out.video.entity, 0, 0);
- if (ret < 0)
- goto error_link;
-
- return 0;
-
-error_link:
- omap3isp_video_cleanup(&csi2->video_out);
-error_video:
- media_entity_cleanup(&csi2->subdev.entity);
- return ret;
-}
-
-/*
- * omap3isp_csi2_init - Routine for module driver init
- */
-int omap3isp_csi2_init(struct isp_device *isp)
-{
- struct isp_csi2_device *csi2a = &isp->isp_csi2a;
- struct isp_csi2_device *csi2c = &isp->isp_csi2c;
- int ret;
-
- csi2a->isp = isp;
- csi2a->available = 1;
- csi2a->regs1 = OMAP3_ISP_IOMEM_CSI2A_REGS1;
- csi2a->regs2 = OMAP3_ISP_IOMEM_CSI2A_REGS2;
- csi2a->phy = &isp->isp_csiphy2;
- csi2a->state = ISP_PIPELINE_STREAM_STOPPED;
- init_waitqueue_head(&csi2a->wait);
-
- ret = csi2_init_entities(csi2a);
- if (ret < 0)
- return ret;
-
- if (isp->revision == ISP_REVISION_15_0) {
- csi2c->isp = isp;
- csi2c->available = 1;
- csi2c->regs1 = OMAP3_ISP_IOMEM_CSI2C_REGS1;
- csi2c->regs2 = OMAP3_ISP_IOMEM_CSI2C_REGS2;
- csi2c->phy = &isp->isp_csiphy1;
- csi2c->state = ISP_PIPELINE_STREAM_STOPPED;
- init_waitqueue_head(&csi2c->wait);
- }
-
- return 0;
-}
-
-/*
- * omap3isp_csi2_cleanup - Routine for module driver cleanup
- */
-void omap3isp_csi2_cleanup(struct isp_device *isp)
-{
- struct isp_csi2_device *csi2a = &isp->isp_csi2a;
-
- omap3isp_video_cleanup(&csi2a->video_out);
- media_entity_cleanup(&csi2a->subdev.entity);
-}
diff --git a/drivers/media/video/omap3isp/ispcsi2.h b/drivers/media/video/omap3isp/ispcsi2.h
deleted file mode 100644
index c57729b7e86..00000000000
--- a/drivers/media/video/omap3isp/ispcsi2.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * ispcsi2.h
- *
- * TI OMAP3 ISP - CSI2 module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef OMAP3_ISP_CSI2_H
-#define OMAP3_ISP_CSI2_H
-
-#include <linux/types.h>
-#include <linux/videodev2.h>
-
-struct isp_csiphy;
-
-/* This is not an exhaustive list */
-enum isp_csi2_pix_formats {
- CSI2_PIX_FMT_OTHERS = 0,
- CSI2_PIX_FMT_YUV422_8BIT = 0x1e,
- CSI2_PIX_FMT_YUV422_8BIT_VP = 0x9e,
- CSI2_PIX_FMT_RAW10_EXP16 = 0xab,
- CSI2_PIX_FMT_RAW10_EXP16_VP = 0x12f,
- CSI2_PIX_FMT_RAW8 = 0x2a,
- CSI2_PIX_FMT_RAW8_DPCM10_EXP16 = 0x2aa,
- CSI2_PIX_FMT_RAW8_DPCM10_VP = 0x32a,
- CSI2_PIX_FMT_RAW8_VP = 0x12a,
- CSI2_USERDEF_8BIT_DATA1_DPCM10_VP = 0x340,
- CSI2_USERDEF_8BIT_DATA1_DPCM10 = 0x2c0,
- CSI2_USERDEF_8BIT_DATA1 = 0x40,
-};
-
-enum isp_csi2_irqevents {
- OCP_ERR_IRQ = 0x4000,
- SHORT_PACKET_IRQ = 0x2000,
- ECC_CORRECTION_IRQ = 0x1000,
- ECC_NO_CORRECTION_IRQ = 0x800,
- COMPLEXIO2_ERR_IRQ = 0x400,
- COMPLEXIO1_ERR_IRQ = 0x200,
- FIFO_OVF_IRQ = 0x100,
- CONTEXT7 = 0x80,
- CONTEXT6 = 0x40,
- CONTEXT5 = 0x20,
- CONTEXT4 = 0x10,
- CONTEXT3 = 0x8,
- CONTEXT2 = 0x4,
- CONTEXT1 = 0x2,
- CONTEXT0 = 0x1,
-};
-
-enum isp_csi2_ctx_irqevents {
- CTX_ECC_CORRECTION = 0x100,
- CTX_LINE_NUMBER = 0x80,
- CTX_FRAME_NUMBER = 0x40,
- CTX_CS = 0x20,
- CTX_LE = 0x8,
- CTX_LS = 0x4,
- CTX_FE = 0x2,
- CTX_FS = 0x1,
-};
-
-enum isp_csi2_frame_mode {
- ISP_CSI2_FRAME_IMMEDIATE,
- ISP_CSI2_FRAME_AFTERFEC,
-};
-
-#define ISP_CSI2_MAX_CTX_NUM 7
-
-struct isp_csi2_ctx_cfg {
- u8 ctxnum; /* context number 0 - 7 */
- u8 dpcm_decompress;
-
- /* Fields in CSI2_CTx_CTRL2 - locked by CSI2_CTx_CTRL1.CTX_EN */
- u8 virtual_id;
- u16 format_id; /* as in CSI2_CTx_CTRL2[9:0] */
- u8 dpcm_predictor; /* 1: simple, 0: advanced */
-
- /* Fields in CSI2_CTx_CTRL1/3 - Shadowed */
- u16 alpha;
- u16 data_offset;
- u32 ping_addr;
- u32 pong_addr;
- u8 eof_enabled;
- u8 eol_enabled;
- u8 checksum_enabled;
- u8 enabled;
-};
-
-struct isp_csi2_timing_cfg {
- u8 ionum; /* IO1 or IO2 as in CSI2_TIMING */
- unsigned force_rx_mode:1;
- unsigned stop_state_16x:1;
- unsigned stop_state_4x:1;
- u16 stop_state_counter;
-};
-
-struct isp_csi2_ctrl_cfg {
- bool vp_clk_enable;
- bool vp_only_enable;
- u8 vp_out_ctrl;
- enum isp_csi2_frame_mode frame_mode;
- bool ecc_enable;
- bool if_enable;
-};
-
-#define CSI2_PAD_SINK 0
-#define CSI2_PAD_SOURCE 1
-#define CSI2_PADS_NUM 2
-
-#define CSI2_OUTPUT_CCDC (1 << 0)
-#define CSI2_OUTPUT_MEMORY (1 << 1)
-
-struct isp_csi2_device {
- struct v4l2_subdev subdev;
- struct media_pad pads[CSI2_PADS_NUM];
- struct v4l2_mbus_framefmt formats[CSI2_PADS_NUM];
-
- struct isp_video video_out;
- struct isp_device *isp;
-
- u8 available; /* Is the IP present on the silicon? */
-
- /* mem resources - enums as defined in enum isp_mem_resources */
- u8 regs1;
- u8 regs2;
-
- u32 output; /* output to CCDC, memory or both? */
- bool dpcm_decompress;
- unsigned int frame_skip;
-
- struct isp_csiphy *phy;
- struct isp_csi2_ctx_cfg contexts[ISP_CSI2_MAX_CTX_NUM + 1];
- struct isp_csi2_timing_cfg timing[2];
- struct isp_csi2_ctrl_cfg ctrl;
- enum isp_pipeline_stream_state state;
- wait_queue_head_t wait;
- atomic_t stopping;
-};
-
-void omap3isp_csi2_isr(struct isp_csi2_device *csi2);
-int omap3isp_csi2_reset(struct isp_csi2_device *csi2);
-int omap3isp_csi2_init(struct isp_device *isp);
-void omap3isp_csi2_cleanup(struct isp_device *isp);
-void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2);
-int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2,
- struct v4l2_device *vdev);
-#endif /* OMAP3_ISP_CSI2_H */
diff --git a/drivers/media/video/omap3isp/ispcsiphy.c b/drivers/media/video/omap3isp/ispcsiphy.c
deleted file mode 100644
index 348f67ebbbc..00000000000
--- a/drivers/media/video/omap3isp/ispcsiphy.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * ispcsiphy.c
- *
- * TI OMAP3 ISP - CSI PHY module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/regulator/consumer.h>
-
-#include "isp.h"
-#include "ispreg.h"
-#include "ispcsiphy.h"
-
-/*
- * csiphy_lanes_config - Configuration of CSIPHY lanes.
- *
- * Updates HW configuration.
- * Called with phy->mutex taken.
- */
-static void csiphy_lanes_config(struct isp_csiphy *phy)
-{
- unsigned int i;
- u32 reg;
-
- reg = isp_reg_readl(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG);
-
- for (i = 0; i < phy->num_data_lanes; i++) {
- reg &= ~(ISPCSI2_PHY_CFG_DATA_POL_MASK(i + 1) |
- ISPCSI2_PHY_CFG_DATA_POSITION_MASK(i + 1));
- reg |= (phy->lanes.data[i].pol <<
- ISPCSI2_PHY_CFG_DATA_POL_SHIFT(i + 1));
- reg |= (phy->lanes.data[i].pos <<
- ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(i + 1));
- }
-
- reg &= ~(ISPCSI2_PHY_CFG_CLOCK_POL_MASK |
- ISPCSI2_PHY_CFG_CLOCK_POSITION_MASK);
- reg |= phy->lanes.clk.pol << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT;
- reg |= phy->lanes.clk.pos << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT;
-
- isp_reg_writel(phy->isp, reg, phy->cfg_regs, ISPCSI2_PHY_CFG);
-}
-
-/*
- * csiphy_power_autoswitch_enable
- * @enable: Sets or clears the autoswitch function enable flag.
- */
-static void csiphy_power_autoswitch_enable(struct isp_csiphy *phy, bool enable)
-{
- isp_reg_clr_set(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG,
- ISPCSI2_PHY_CFG_PWR_AUTO,
- enable ? ISPCSI2_PHY_CFG_PWR_AUTO : 0);
-}
-
-/*
- * csiphy_set_power
- * @power: Power state to be set.
- *
- * Returns 0 if successful, or -EBUSY if the retry count is exceeded.
- */
-static int csiphy_set_power(struct isp_csiphy *phy, u32 power)
-{
- u32 reg;
- u8 retry_count;
-
- isp_reg_clr_set(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG,
- ISPCSI2_PHY_CFG_PWR_CMD_MASK, power);
-
- retry_count = 0;
- do {
- udelay(50);
- reg = isp_reg_readl(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG) &
- ISPCSI2_PHY_CFG_PWR_STATUS_MASK;
-
- if (reg != power >> 2)
- retry_count++;
-
- } while ((reg != power >> 2) && (retry_count < 100));
-
- if (retry_count == 100) {
- printk(KERN_ERR "CSI2 CIO set power failed!\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-/*
- * csiphy_dphy_config - Configure CSI2 D-PHY parameters.
- *
- * Called with phy->mutex taken.
- */
-static void csiphy_dphy_config(struct isp_csiphy *phy)
-{
- u32 reg;
-
- /* Set up ISPCSIPHY_REG0 */
- reg = isp_reg_readl(phy->isp, phy->phy_regs, ISPCSIPHY_REG0);
-
- reg &= ~(ISPCSIPHY_REG0_THS_TERM_MASK |
- ISPCSIPHY_REG0_THS_SETTLE_MASK);
- reg |= phy->dphy.ths_term << ISPCSIPHY_REG0_THS_TERM_SHIFT;
- reg |= phy->dphy.ths_settle << ISPCSIPHY_REG0_THS_SETTLE_SHIFT;
-
- isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG0);
-
- /* Set up ISPCSIPHY_REG1 */
- reg = isp_reg_readl(phy->isp, phy->phy_regs, ISPCSIPHY_REG1);
-
- reg &= ~(ISPCSIPHY_REG1_TCLK_TERM_MASK |
- ISPCSIPHY_REG1_TCLK_MISS_MASK |
- ISPCSIPHY_REG1_TCLK_SETTLE_MASK);
- reg |= phy->dphy.tclk_term << ISPCSIPHY_REG1_TCLK_TERM_SHIFT;
- reg |= phy->dphy.tclk_miss << ISPCSIPHY_REG1_TCLK_MISS_SHIFT;
- reg |= phy->dphy.tclk_settle << ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT;
-
- isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG1);
-}
-
-static int csiphy_config(struct isp_csiphy *phy,
- struct isp_csiphy_dphy_cfg *dphy,
- struct isp_csiphy_lanes_cfg *lanes)
-{
- unsigned int used_lanes = 0;
- unsigned int i;
-
- /* Clock and data lanes verification */
- for (i = 0; i < phy->num_data_lanes; i++) {
- if (lanes->data[i].pol > 1 || lanes->data[i].pos > 3)
- return -EINVAL;
-
- if (used_lanes & (1 << lanes->data[i].pos))
- return -EINVAL;
-
- used_lanes |= 1 << lanes->data[i].pos;
- }
-
- if (lanes->clk.pol > 1 || lanes->clk.pos > 3)
- return -EINVAL;
-
- if (lanes->clk.pos == 0 || used_lanes & (1 << lanes->clk.pos))
- return -EINVAL;
-
- mutex_lock(&phy->mutex);
- phy->dphy = *dphy;
- phy->lanes = *lanes;
- mutex_unlock(&phy->mutex);
-
- return 0;
-}
-
-int omap3isp_csiphy_acquire(struct isp_csiphy *phy)
-{
- int rval;
-
- if (phy->vdd == NULL) {
- dev_err(phy->isp->dev, "Power regulator for CSI PHY not "
- "available\n");
- return -ENODEV;
- }
-
- mutex_lock(&phy->mutex);
-
- rval = regulator_enable(phy->vdd);
- if (rval < 0)
- goto done;
-
- rval = omap3isp_csi2_reset(phy->csi2);
- if (rval < 0)
- goto done;
-
- csiphy_dphy_config(phy);
- csiphy_lanes_config(phy);
-
- rval = csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_ON);
- if (rval) {
- regulator_disable(phy->vdd);
- goto done;
- }
-
- csiphy_power_autoswitch_enable(phy, true);
- phy->phy_in_use = 1;
-
-done:
- mutex_unlock(&phy->mutex);
- return rval;
-}
-
-void omap3isp_csiphy_release(struct isp_csiphy *phy)
-{
- mutex_lock(&phy->mutex);
- if (phy->phy_in_use) {
- csiphy_power_autoswitch_enable(phy, false);
- csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF);
- regulator_disable(phy->vdd);
- phy->phy_in_use = 0;
- }
- mutex_unlock(&phy->mutex);
-}
-
-/*
- * omap3isp_csiphy_init - Initialize the CSI PHY frontends
- */
-int omap3isp_csiphy_init(struct isp_device *isp)
-{
- struct isp_csiphy *phy1 = &isp->isp_csiphy1;
- struct isp_csiphy *phy2 = &isp->isp_csiphy2;
-
- isp->platform_cb.csiphy_config = csiphy_config;
-
- phy2->isp = isp;
- phy2->csi2 = &isp->isp_csi2a;
- phy2->num_data_lanes = ISP_CSIPHY2_NUM_DATA_LANES;
- phy2->cfg_regs = OMAP3_ISP_IOMEM_CSI2A_REGS1;
- phy2->phy_regs = OMAP3_ISP_IOMEM_CSIPHY2;
- mutex_init(&phy2->mutex);
-
- if (isp->revision == ISP_REVISION_15_0) {
- phy1->isp = isp;
- phy1->csi2 = &isp->isp_csi2c;
- phy1->num_data_lanes = ISP_CSIPHY1_NUM_DATA_LANES;
- phy1->cfg_regs = OMAP3_ISP_IOMEM_CSI2C_REGS1;
- phy1->phy_regs = OMAP3_ISP_IOMEM_CSIPHY1;
- mutex_init(&phy1->mutex);
- }
-
- return 0;
-}
diff --git a/drivers/media/video/omap3isp/ispcsiphy.h b/drivers/media/video/omap3isp/ispcsiphy.h
deleted file mode 100644
index e93a661e65d..00000000000
--- a/drivers/media/video/omap3isp/ispcsiphy.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * ispcsiphy.h
- *
- * TI OMAP3 ISP - CSI PHY module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef OMAP3_ISP_CSI_PHY_H
-#define OMAP3_ISP_CSI_PHY_H
-
-#include <media/omap3isp.h>
-
-struct isp_csi2_device;
-struct regulator;
-
-struct isp_csiphy_dphy_cfg {
- u8 ths_term;
- u8 ths_settle;
- u8 tclk_term;
- unsigned tclk_miss:1;
- u8 tclk_settle;
-};
-
-struct isp_csiphy {
- struct isp_device *isp;
- struct mutex mutex; /* serialize csiphy configuration */
- u8 phy_in_use;
- struct isp_csi2_device *csi2;
- struct regulator *vdd;
-
- /* mem resources - enums as defined in enum isp_mem_resources */
- unsigned int cfg_regs;
- unsigned int phy_regs;
-
- u8 num_data_lanes; /* number of CSI2 Data Lanes supported */
- struct isp_csiphy_lanes_cfg lanes;
- struct isp_csiphy_dphy_cfg dphy;
-};
-
-int omap3isp_csiphy_acquire(struct isp_csiphy *phy);
-void omap3isp_csiphy_release(struct isp_csiphy *phy);
-int omap3isp_csiphy_init(struct isp_device *isp);
-
-#endif /* OMAP3_ISP_CSI_PHY_H */
diff --git a/drivers/media/video/omap3isp/isph3a.h b/drivers/media/video/omap3isp/isph3a.h
deleted file mode 100644
index fb09fd4ca75..00000000000
--- a/drivers/media/video/omap3isp/isph3a.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * isph3a.h
- *
- * TI OMAP3 ISP - H3A AF module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: David Cohen <dacohen@gmail.com>
- * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef OMAP3_ISP_H3A_H
-#define OMAP3_ISP_H3A_H
-
-#include <linux/omap3isp.h>
-
-/*
- * ----------
- * -H3A AEWB-
- * ----------
- */
-
-#define AEWB_PACKET_SIZE 16
-#define AEWB_SATURATION_LIMIT 0x3ff
-
-/* Flags for changed registers */
-#define PCR_CHNG (1 << 0)
-#define AEWWIN1_CHNG (1 << 1)
-#define AEWINSTART_CHNG (1 << 2)
-#define AEWINBLK_CHNG (1 << 3)
-#define AEWSUBWIN_CHNG (1 << 4)
-#define PRV_WBDGAIN_CHNG (1 << 5)
-#define PRV_WBGAIN_CHNG (1 << 6)
-
-/* ISPH3A REGISTERS bits */
-#define ISPH3A_PCR_AF_EN (1 << 0)
-#define ISPH3A_PCR_AF_ALAW_EN (1 << 1)
-#define ISPH3A_PCR_AF_MED_EN (1 << 2)
-#define ISPH3A_PCR_AF_BUSY (1 << 15)
-#define ISPH3A_PCR_AEW_EN (1 << 16)
-#define ISPH3A_PCR_AEW_ALAW_EN (1 << 17)
-#define ISPH3A_PCR_AEW_BUSY (1 << 18)
-#define ISPH3A_PCR_AEW_MASK (ISPH3A_PCR_AEW_ALAW_EN | \
- ISPH3A_PCR_AEW_AVE2LMT_MASK)
-
-/*
- * --------
- * -H3A AF-
- * --------
- */
-
-/* Peripheral Revision */
-#define AFPID 0x0
-
-#define AFCOEF_OFFSET 0x00000004 /* COEF base address */
-
-/* PCR fields */
-#define AF_BUSYAF (1 << 15)
-#define AF_FVMODE (1 << 14)
-#define AF_RGBPOS (0x7 << 11)
-#define AF_MED_TH (0xFF << 3)
-#define AF_MED_EN (1 << 2)
-#define AF_ALAW_EN (1 << 1)
-#define AF_EN (1 << 0)
-#define AF_PCR_MASK (AF_FVMODE | AF_RGBPOS | AF_MED_TH | \
- AF_MED_EN | AF_ALAW_EN)
-
-/* AFPAX1 fields */
-#define AF_PAXW (0x7F << 16)
-#define AF_PAXH 0x7F
-
-/* AFPAX2 fields */
-#define AF_AFINCV (0xF << 13)
-#define AF_PAXVC (0x7F << 6)
-#define AF_PAXHC 0x3F
-
-/* AFPAXSTART fields */
-#define AF_PAXSH (0xFFF<<16)
-#define AF_PAXSV 0xFFF
-
-/* COEFFICIENT MASK */
-#define AF_COEF_MASK0 0xFFF
-#define AF_COEF_MASK1 (0xFFF<<16)
-
-/* BIT SHIFTS */
-#define AF_RGBPOS_SHIFT 11
-#define AF_MED_TH_SHIFT 3
-#define AF_PAXW_SHIFT 16
-#define AF_LINE_INCR_SHIFT 13
-#define AF_VT_COUNT_SHIFT 6
-#define AF_HZ_START_SHIFT 16
-#define AF_COEF_SHIFT 16
-
-/* Init and cleanup functions */
-int omap3isp_h3a_aewb_init(struct isp_device *isp);
-int omap3isp_h3a_af_init(struct isp_device *isp);
-
-void omap3isp_h3a_aewb_cleanup(struct isp_device *isp);
-void omap3isp_h3a_af_cleanup(struct isp_device *isp);
-
-#endif /* OMAP3_ISP_H3A_H */
diff --git a/drivers/media/video/omap3isp/isph3a_aewb.c b/drivers/media/video/omap3isp/isph3a_aewb.c
deleted file mode 100644
index a3c76bf1817..00000000000
--- a/drivers/media/video/omap3isp/isph3a_aewb.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * isph3a.c
- *
- * TI OMAP3 ISP - H3A module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: David Cohen <dacohen@gmail.com>
- * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-#include "isp.h"
-#include "isph3a.h"
-#include "ispstat.h"
-
-/*
- * h3a_aewb_update_regs - Helper function to update h3a registers.
- */
-static void h3a_aewb_setup_regs(struct ispstat *aewb, void *priv)
-{
- struct omap3isp_h3a_aewb_config *conf = priv;
- u32 pcr;
- u32 win1;
- u32 start;
- u32 blk;
- u32 subwin;
-
- if (aewb->state == ISPSTAT_DISABLED)
- return;
-
- isp_reg_writel(aewb->isp, aewb->active_buf->iommu_addr,
- OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWBUFST);
-
- if (!aewb->update)
- return;
-
- /* Converting config metadata into reg values */
- pcr = conf->saturation_limit << ISPH3A_PCR_AEW_AVE2LMT_SHIFT;
- pcr |= !!conf->alaw_enable << ISPH3A_PCR_AEW_ALAW_EN_SHIFT;
-
- win1 = ((conf->win_height >> 1) - 1) << ISPH3A_AEWWIN1_WINH_SHIFT;
- win1 |= ((conf->win_width >> 1) - 1) << ISPH3A_AEWWIN1_WINW_SHIFT;
- win1 |= (conf->ver_win_count - 1) << ISPH3A_AEWWIN1_WINVC_SHIFT;
- win1 |= (conf->hor_win_count - 1) << ISPH3A_AEWWIN1_WINHC_SHIFT;
-
- start = conf->hor_win_start << ISPH3A_AEWINSTART_WINSH_SHIFT;
- start |= conf->ver_win_start << ISPH3A_AEWINSTART_WINSV_SHIFT;
-
- blk = conf->blk_ver_win_start << ISPH3A_AEWINBLK_WINSV_SHIFT;
- blk |= ((conf->blk_win_height >> 1) - 1) << ISPH3A_AEWINBLK_WINH_SHIFT;
-
- subwin = ((conf->subsample_ver_inc >> 1) - 1) <<
- ISPH3A_AEWSUBWIN_AEWINCV_SHIFT;
- subwin |= ((conf->subsample_hor_inc >> 1) - 1) <<
- ISPH3A_AEWSUBWIN_AEWINCH_SHIFT;
-
- isp_reg_writel(aewb->isp, win1, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWWIN1);
- isp_reg_writel(aewb->isp, start, OMAP3_ISP_IOMEM_H3A,
- ISPH3A_AEWINSTART);
- isp_reg_writel(aewb->isp, blk, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWINBLK);
- isp_reg_writel(aewb->isp, subwin, OMAP3_ISP_IOMEM_H3A,
- ISPH3A_AEWSUBWIN);
- isp_reg_clr_set(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
- ISPH3A_PCR_AEW_MASK, pcr);
-
- aewb->update = 0;
- aewb->config_counter += aewb->inc_config;
- aewb->inc_config = 0;
- aewb->buf_size = conf->buf_size;
-}
-
-static void h3a_aewb_enable(struct ispstat *aewb, int enable)
-{
- if (enable) {
- isp_reg_set(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
- ISPH3A_PCR_AEW_EN);
- /* This bit is already set if AF is enabled */
- if (aewb->isp->isp_af.state != ISPSTAT_ENABLED)
- isp_reg_set(aewb->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
- ISPCTRL_H3A_CLK_EN);
- } else {
- isp_reg_clr(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
- ISPH3A_PCR_AEW_EN);
- /* This bit can't be cleared if AF is enabled */
- if (aewb->isp->isp_af.state != ISPSTAT_ENABLED)
- isp_reg_clr(aewb->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
- ISPCTRL_H3A_CLK_EN);
- }
-}
-
-static int h3a_aewb_busy(struct ispstat *aewb)
-{
- return isp_reg_readl(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR)
- & ISPH3A_PCR_BUSYAEAWB;
-}
-
-static u32 h3a_aewb_get_buf_size(struct omap3isp_h3a_aewb_config *conf)
-{
- /* Number of configured windows + extra row for black data */
- u32 win_count = (conf->ver_win_count + 1) * conf->hor_win_count;
-
- /*
- * Unsaturated block counts for each 8 windows.
- * 1 extra for the last (win_count % 8) windows if win_count is not
- * divisible by 8.
- */
- win_count += (win_count + 7) / 8;
-
- return win_count * AEWB_PACKET_SIZE;
-}
-
-static int h3a_aewb_validate_params(struct ispstat *aewb, void *new_conf)
-{
- struct omap3isp_h3a_aewb_config *user_cfg = new_conf;
- u32 buf_size;
-
- if (unlikely(user_cfg->saturation_limit >
- OMAP3ISP_AEWB_MAX_SATURATION_LIM))
- return -EINVAL;
-
- if (unlikely(user_cfg->win_height < OMAP3ISP_AEWB_MIN_WIN_H ||
- user_cfg->win_height > OMAP3ISP_AEWB_MAX_WIN_H ||
- user_cfg->win_height & 0x01))
- return -EINVAL;
-
- if (unlikely(user_cfg->win_width < OMAP3ISP_AEWB_MIN_WIN_W ||
- user_cfg->win_width > OMAP3ISP_AEWB_MAX_WIN_W ||
- user_cfg->win_width & 0x01))
- return -EINVAL;
-
- if (unlikely(user_cfg->ver_win_count < OMAP3ISP_AEWB_MIN_WINVC ||
- user_cfg->ver_win_count > OMAP3ISP_AEWB_MAX_WINVC))
- return -EINVAL;
-
- if (unlikely(user_cfg->hor_win_count < OMAP3ISP_AEWB_MIN_WINHC ||
- user_cfg->hor_win_count > OMAP3ISP_AEWB_MAX_WINHC))
- return -EINVAL;
-
- if (unlikely(user_cfg->ver_win_start > OMAP3ISP_AEWB_MAX_WINSTART))
- return -EINVAL;
-
- if (unlikely(user_cfg->hor_win_start > OMAP3ISP_AEWB_MAX_WINSTART))
- return -EINVAL;
-
- if (unlikely(user_cfg->blk_ver_win_start > OMAP3ISP_AEWB_MAX_WINSTART))
- return -EINVAL;
-
- if (unlikely(user_cfg->blk_win_height < OMAP3ISP_AEWB_MIN_WIN_H ||
- user_cfg->blk_win_height > OMAP3ISP_AEWB_MAX_WIN_H ||
- user_cfg->blk_win_height & 0x01))
- return -EINVAL;
-
- if (unlikely(user_cfg->subsample_ver_inc < OMAP3ISP_AEWB_MIN_SUB_INC ||
- user_cfg->subsample_ver_inc > OMAP3ISP_AEWB_MAX_SUB_INC ||
- user_cfg->subsample_ver_inc & 0x01))
- return -EINVAL;
-
- if (unlikely(user_cfg->subsample_hor_inc < OMAP3ISP_AEWB_MIN_SUB_INC ||
- user_cfg->subsample_hor_inc > OMAP3ISP_AEWB_MAX_SUB_INC ||
- user_cfg->subsample_hor_inc & 0x01))
- return -EINVAL;
-
- buf_size = h3a_aewb_get_buf_size(user_cfg);
- if (buf_size > user_cfg->buf_size)
- user_cfg->buf_size = buf_size;
- else if (user_cfg->buf_size > OMAP3ISP_AEWB_MAX_BUF_SIZE)
- user_cfg->buf_size = OMAP3ISP_AEWB_MAX_BUF_SIZE;
-
- return 0;
-}
-
-/*
- * h3a_aewb_set_params - Helper function to check & store user given params.
- * @new_conf: Pointer to AE and AWB parameters struct.
- *
- * As most of them are busy-lock registers, need to wait until AEW_BUSY = 0 to
- * program them during ISR.
- */
-static void h3a_aewb_set_params(struct ispstat *aewb, void *new_conf)
-{
- struct omap3isp_h3a_aewb_config *user_cfg = new_conf;
- struct omap3isp_h3a_aewb_config *cur_cfg = aewb->priv;
- int update = 0;
-
- if (cur_cfg->saturation_limit != user_cfg->saturation_limit) {
- cur_cfg->saturation_limit = user_cfg->saturation_limit;
- update = 1;
- }
- if (cur_cfg->alaw_enable != user_cfg->alaw_enable) {
- cur_cfg->alaw_enable = user_cfg->alaw_enable;
- update = 1;
- }
- if (cur_cfg->win_height != user_cfg->win_height) {
- cur_cfg->win_height = user_cfg->win_height;
- update = 1;
- }
- if (cur_cfg->win_width != user_cfg->win_width) {
- cur_cfg->win_width = user_cfg->win_width;
- update = 1;
- }
- if (cur_cfg->ver_win_count != user_cfg->ver_win_count) {
- cur_cfg->ver_win_count = user_cfg->ver_win_count;
- update = 1;
- }
- if (cur_cfg->hor_win_count != user_cfg->hor_win_count) {
- cur_cfg->hor_win_count = user_cfg->hor_win_count;
- update = 1;
- }
- if (cur_cfg->ver_win_start != user_cfg->ver_win_start) {
- cur_cfg->ver_win_start = user_cfg->ver_win_start;
- update = 1;
- }
- if (cur_cfg->hor_win_start != user_cfg->hor_win_start) {
- cur_cfg->hor_win_start = user_cfg->hor_win_start;
- update = 1;
- }
- if (cur_cfg->blk_ver_win_start != user_cfg->blk_ver_win_start) {
- cur_cfg->blk_ver_win_start = user_cfg->blk_ver_win_start;
- update = 1;
- }
- if (cur_cfg->blk_win_height != user_cfg->blk_win_height) {
- cur_cfg->blk_win_height = user_cfg->blk_win_height;
- update = 1;
- }
- if (cur_cfg->subsample_ver_inc != user_cfg->subsample_ver_inc) {
- cur_cfg->subsample_ver_inc = user_cfg->subsample_ver_inc;
- update = 1;
- }
- if (cur_cfg->subsample_hor_inc != user_cfg->subsample_hor_inc) {
- cur_cfg->subsample_hor_inc = user_cfg->subsample_hor_inc;
- update = 1;
- }
-
- if (update || !aewb->configured) {
- aewb->inc_config++;
- aewb->update = 1;
- cur_cfg->buf_size = h3a_aewb_get_buf_size(cur_cfg);
- }
-}
-
-static long h3a_aewb_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
- struct ispstat *stat = v4l2_get_subdevdata(sd);
-
- switch (cmd) {
- case VIDIOC_OMAP3ISP_AEWB_CFG:
- return omap3isp_stat_config(stat, arg);
- case VIDIOC_OMAP3ISP_STAT_REQ:
- return omap3isp_stat_request_statistics(stat, arg);
- case VIDIOC_OMAP3ISP_STAT_EN: {
- unsigned long *en = arg;
- return omap3isp_stat_enable(stat, !!*en);
- }
- }
-
- return -ENOIOCTLCMD;
-}
-
-static const struct ispstat_ops h3a_aewb_ops = {
- .validate_params = h3a_aewb_validate_params,
- .set_params = h3a_aewb_set_params,
- .setup_regs = h3a_aewb_setup_regs,
- .enable = h3a_aewb_enable,
- .busy = h3a_aewb_busy,
-};
-
-static const struct v4l2_subdev_core_ops h3a_aewb_subdev_core_ops = {
- .ioctl = h3a_aewb_ioctl,
- .subscribe_event = omap3isp_stat_subscribe_event,
- .unsubscribe_event = omap3isp_stat_unsubscribe_event,
-};
-
-static const struct v4l2_subdev_video_ops h3a_aewb_subdev_video_ops = {
- .s_stream = omap3isp_stat_s_stream,
-};
-
-static const struct v4l2_subdev_ops h3a_aewb_subdev_ops = {
- .core = &h3a_aewb_subdev_core_ops,
- .video = &h3a_aewb_subdev_video_ops,
-};
-
-/*
- * omap3isp_h3a_aewb_init - Module Initialisation.
- */
-int omap3isp_h3a_aewb_init(struct isp_device *isp)
-{
- struct ispstat *aewb = &isp->isp_aewb;
- struct omap3isp_h3a_aewb_config *aewb_cfg;
- struct omap3isp_h3a_aewb_config *aewb_recover_cfg;
- int ret;
-
- aewb_cfg = kzalloc(sizeof(*aewb_cfg), GFP_KERNEL);
- if (!aewb_cfg)
- return -ENOMEM;
-
- memset(aewb, 0, sizeof(*aewb));
- aewb->ops = &h3a_aewb_ops;
- aewb->priv = aewb_cfg;
- aewb->dma_ch = -1;
- aewb->event_type = V4L2_EVENT_OMAP3ISP_AEWB;
- aewb->isp = isp;
-
- /* Set recover state configuration */
- aewb_recover_cfg = kzalloc(sizeof(*aewb_recover_cfg), GFP_KERNEL);
- if (!aewb_recover_cfg) {
- dev_err(aewb->isp->dev, "AEWB: cannot allocate memory for "
- "recover configuration.\n");
- ret = -ENOMEM;
- goto err_recover_alloc;
- }
-
- aewb_recover_cfg->saturation_limit = OMAP3ISP_AEWB_MAX_SATURATION_LIM;
- aewb_recover_cfg->win_height = OMAP3ISP_AEWB_MIN_WIN_H;
- aewb_recover_cfg->win_width = OMAP3ISP_AEWB_MIN_WIN_W;
- aewb_recover_cfg->ver_win_count = OMAP3ISP_AEWB_MIN_WINVC;
- aewb_recover_cfg->hor_win_count = OMAP3ISP_AEWB_MIN_WINHC;
- aewb_recover_cfg->blk_ver_win_start = aewb_recover_cfg->ver_win_start +
- aewb_recover_cfg->win_height * aewb_recover_cfg->ver_win_count;
- aewb_recover_cfg->blk_win_height = OMAP3ISP_AEWB_MIN_WIN_H;
- aewb_recover_cfg->subsample_ver_inc = OMAP3ISP_AEWB_MIN_SUB_INC;
- aewb_recover_cfg->subsample_hor_inc = OMAP3ISP_AEWB_MIN_SUB_INC;
-
- if (h3a_aewb_validate_params(aewb, aewb_recover_cfg)) {
- dev_err(aewb->isp->dev, "AEWB: recover configuration is "
- "invalid.\n");
- ret = -EINVAL;
- goto err_conf;
- }
-
- aewb_recover_cfg->buf_size = h3a_aewb_get_buf_size(aewb_recover_cfg);
- aewb->recover_priv = aewb_recover_cfg;
-
- ret = omap3isp_stat_init(aewb, "AEWB", &h3a_aewb_subdev_ops);
- if (ret)
- goto err_conf;
-
- return 0;
-
-err_conf:
- kfree(aewb_recover_cfg);
-err_recover_alloc:
- kfree(aewb_cfg);
-
- return ret;
-}
-
-/*
- * omap3isp_h3a_aewb_cleanup - Module exit.
- */
-void omap3isp_h3a_aewb_cleanup(struct isp_device *isp)
-{
- kfree(isp->isp_aewb.priv);
- kfree(isp->isp_aewb.recover_priv);
- omap3isp_stat_cleanup(&isp->isp_aewb);
-}
diff --git a/drivers/media/video/omap3isp/isph3a_af.c b/drivers/media/video/omap3isp/isph3a_af.c
deleted file mode 100644
index 58e0bc41489..00000000000
--- a/drivers/media/video/omap3isp/isph3a_af.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * isph3a_af.c
- *
- * TI OMAP3 ISP - H3A AF module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: David Cohen <dacohen@gmail.com>
- * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-/* Linux specific include files */
-#include <linux/device.h>
-#include <linux/slab.h>
-
-#include "isp.h"
-#include "isph3a.h"
-#include "ispstat.h"
-
-#define IS_OUT_OF_BOUNDS(value, min, max) \
- (((value) < (min)) || ((value) > (max)))
-
-static void h3a_af_setup_regs(struct ispstat *af, void *priv)
-{
- struct omap3isp_h3a_af_config *conf = priv;
- u32 pcr;
- u32 pax1;
- u32 pax2;
- u32 paxstart;
- u32 coef;
- u32 base_coef_set0;
- u32 base_coef_set1;
- int index;
-
- if (af->state == ISPSTAT_DISABLED)
- return;
-
- isp_reg_writel(af->isp, af->active_buf->iommu_addr, OMAP3_ISP_IOMEM_H3A,
- ISPH3A_AFBUFST);
-
- if (!af->update)
- return;
-
- /* Configure Hardware Registers */
- pax1 = ((conf->paxel.width >> 1) - 1) << AF_PAXW_SHIFT;
- /* Set height in AFPAX1 */
- pax1 |= (conf->paxel.height >> 1) - 1;
- isp_reg_writel(af->isp, pax1, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX1);
-
- /* Configure AFPAX2 Register */
- /* Set Line Increment in AFPAX2 Register */
- pax2 = ((conf->paxel.line_inc >> 1) - 1) << AF_LINE_INCR_SHIFT;
- /* Set Vertical Count */
- pax2 |= (conf->paxel.v_cnt - 1) << AF_VT_COUNT_SHIFT;
- /* Set Horizontal Count */
- pax2 |= (conf->paxel.h_cnt - 1);
- isp_reg_writel(af->isp, pax2, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX2);
-
- /* Configure PAXSTART Register */
- /*Configure Horizontal Start */
- paxstart = conf->paxel.h_start << AF_HZ_START_SHIFT;
- /* Configure Vertical Start */
- paxstart |= conf->paxel.v_start;
- isp_reg_writel(af->isp, paxstart, OMAP3_ISP_IOMEM_H3A,
- ISPH3A_AFPAXSTART);
-
- /*SetIIRSH Register */
- isp_reg_writel(af->isp, conf->iir.h_start,
- OMAP3_ISP_IOMEM_H3A, ISPH3A_AFIIRSH);
-
- base_coef_set0 = ISPH3A_AFCOEF010;
- base_coef_set1 = ISPH3A_AFCOEF110;
- for (index = 0; index <= 8; index += 2) {
- /*Set IIR Filter0 Coefficients */
- coef = 0;
- coef |= conf->iir.coeff_set0[index];
- coef |= conf->iir.coeff_set0[index + 1] <<
- AF_COEF_SHIFT;
- isp_reg_writel(af->isp, coef, OMAP3_ISP_IOMEM_H3A,
- base_coef_set0);
- base_coef_set0 += AFCOEF_OFFSET;
-
- /*Set IIR Filter1 Coefficients */
- coef = 0;
- coef |= conf->iir.coeff_set1[index];
- coef |= conf->iir.coeff_set1[index + 1] <<
- AF_COEF_SHIFT;
- isp_reg_writel(af->isp, coef, OMAP3_ISP_IOMEM_H3A,
- base_coef_set1);
- base_coef_set1 += AFCOEF_OFFSET;
- }
- /* set AFCOEF0010 Register */
- isp_reg_writel(af->isp, conf->iir.coeff_set0[10],
- OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF0010);
- /* set AFCOEF1010 Register */
- isp_reg_writel(af->isp, conf->iir.coeff_set1[10],
- OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF1010);
-
- /* PCR Register */
- /* Set RGB Position */
- pcr = conf->rgb_pos << AF_RGBPOS_SHIFT;
- /* Set Accumulator Mode */
- if (conf->fvmode == OMAP3ISP_AF_MODE_PEAK)
- pcr |= AF_FVMODE;
- /* Set A-law */
- if (conf->alaw_enable)
- pcr |= AF_ALAW_EN;
- /* HMF Configurations */
- if (conf->hmf.enable) {
- /* Enable HMF */
- pcr |= AF_MED_EN;
- /* Set Median Threshold */
- pcr |= conf->hmf.threshold << AF_MED_TH_SHIFT;
- }
- /* Set PCR Register */
- isp_reg_clr_set(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
- AF_PCR_MASK, pcr);
-
- af->update = 0;
- af->config_counter += af->inc_config;
- af->inc_config = 0;
- af->buf_size = conf->buf_size;
-}
-
-static void h3a_af_enable(struct ispstat *af, int enable)
-{
- if (enable) {
- isp_reg_set(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
- ISPH3A_PCR_AF_EN);
- /* This bit is already set if AEWB is enabled */
- if (af->isp->isp_aewb.state != ISPSTAT_ENABLED)
- isp_reg_set(af->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
- ISPCTRL_H3A_CLK_EN);
- } else {
- isp_reg_clr(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
- ISPH3A_PCR_AF_EN);
- /* This bit can't be cleared if AEWB is enabled */
- if (af->isp->isp_aewb.state != ISPSTAT_ENABLED)
- isp_reg_clr(af->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
- ISPCTRL_H3A_CLK_EN);
- }
-}
-
-static int h3a_af_busy(struct ispstat *af)
-{
- return isp_reg_readl(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR)
- & ISPH3A_PCR_BUSYAF;
-}
-
-static u32 h3a_af_get_buf_size(struct omap3isp_h3a_af_config *conf)
-{
- return conf->paxel.h_cnt * conf->paxel.v_cnt * OMAP3ISP_AF_PAXEL_SIZE;
-}
-
-/* Function to check paxel parameters */
-static int h3a_af_validate_params(struct ispstat *af, void *new_conf)
-{
- struct omap3isp_h3a_af_config *user_cfg = new_conf;
- struct omap3isp_h3a_af_paxel *paxel_cfg = &user_cfg->paxel;
- struct omap3isp_h3a_af_iir *iir_cfg = &user_cfg->iir;
- int index;
- u32 buf_size;
-
- /* Check horizontal Count */
- if (IS_OUT_OF_BOUNDS(paxel_cfg->h_cnt,
- OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MIN,
- OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MAX))
- return -EINVAL;
-
- /* Check Vertical Count */
- if (IS_OUT_OF_BOUNDS(paxel_cfg->v_cnt,
- OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MIN,
- OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MAX))
- return -EINVAL;
-
- if (IS_OUT_OF_BOUNDS(paxel_cfg->height, OMAP3ISP_AF_PAXEL_HEIGHT_MIN,
- OMAP3ISP_AF_PAXEL_HEIGHT_MAX) ||
- paxel_cfg->height % 2)
- return -EINVAL;
-
- /* Check width */
- if (IS_OUT_OF_BOUNDS(paxel_cfg->width, OMAP3ISP_AF_PAXEL_WIDTH_MIN,
- OMAP3ISP_AF_PAXEL_WIDTH_MAX) ||
- paxel_cfg->width % 2)
- return -EINVAL;
-
- /* Check Line Increment */
- if (IS_OUT_OF_BOUNDS(paxel_cfg->line_inc,
- OMAP3ISP_AF_PAXEL_INCREMENT_MIN,
- OMAP3ISP_AF_PAXEL_INCREMENT_MAX) ||
- paxel_cfg->line_inc % 2)
- return -EINVAL;
-
- /* Check Horizontal Start */
- if ((paxel_cfg->h_start < iir_cfg->h_start) ||
- IS_OUT_OF_BOUNDS(paxel_cfg->h_start,
- OMAP3ISP_AF_PAXEL_HZSTART_MIN,
- OMAP3ISP_AF_PAXEL_HZSTART_MAX))
- return -EINVAL;
-
- /* Check IIR */
- for (index = 0; index < OMAP3ISP_AF_NUM_COEF; index++) {
- if ((iir_cfg->coeff_set0[index]) > OMAP3ISP_AF_COEF_MAX)
- return -EINVAL;
-
- if ((iir_cfg->coeff_set1[index]) > OMAP3ISP_AF_COEF_MAX)
- return -EINVAL;
- }
-
- if (IS_OUT_OF_BOUNDS(iir_cfg->h_start, OMAP3ISP_AF_IIRSH_MIN,
- OMAP3ISP_AF_IIRSH_MAX))
- return -EINVAL;
-
- /* Hack: If paxel size is 12, the 10th AF window may be corrupted */
- if ((paxel_cfg->h_cnt * paxel_cfg->v_cnt > 9) &&
- (paxel_cfg->width * paxel_cfg->height == 12))
- return -EINVAL;
-
- buf_size = h3a_af_get_buf_size(user_cfg);
- if (buf_size > user_cfg->buf_size)
- /* User buf_size request wasn't enough */
- user_cfg->buf_size = buf_size;
- else if (user_cfg->buf_size > OMAP3ISP_AF_MAX_BUF_SIZE)
- user_cfg->buf_size = OMAP3ISP_AF_MAX_BUF_SIZE;
-
- return 0;
-}
-
-/* Update local parameters */
-static void h3a_af_set_params(struct ispstat *af, void *new_conf)
-{
- struct omap3isp_h3a_af_config *user_cfg = new_conf;
- struct omap3isp_h3a_af_config *cur_cfg = af->priv;
- int update = 0;
- int index;
-
- /* alaw */
- if (cur_cfg->alaw_enable != user_cfg->alaw_enable) {
- update = 1;
- goto out;
- }
-
- /* hmf */
- if (cur_cfg->hmf.enable != user_cfg->hmf.enable) {
- update = 1;
- goto out;
- }
- if (cur_cfg->hmf.threshold != user_cfg->hmf.threshold) {
- update = 1;
- goto out;
- }
-
- /* rgbpos */
- if (cur_cfg->rgb_pos != user_cfg->rgb_pos) {
- update = 1;
- goto out;
- }
-
- /* iir */
- if (cur_cfg->iir.h_start != user_cfg->iir.h_start) {
- update = 1;
- goto out;
- }
- for (index = 0; index < OMAP3ISP_AF_NUM_COEF; index++) {
- if (cur_cfg->iir.coeff_set0[index] !=
- user_cfg->iir.coeff_set0[index]) {
- update = 1;
- goto out;
- }
- if (cur_cfg->iir.coeff_set1[index] !=
- user_cfg->iir.coeff_set1[index]) {
- update = 1;
- goto out;
- }
- }
-
- /* paxel */
- if ((cur_cfg->paxel.width != user_cfg->paxel.width) ||
- (cur_cfg->paxel.height != user_cfg->paxel.height) ||
- (cur_cfg->paxel.h_start != user_cfg->paxel.h_start) ||
- (cur_cfg->paxel.v_start != user_cfg->paxel.v_start) ||
- (cur_cfg->paxel.h_cnt != user_cfg->paxel.h_cnt) ||
- (cur_cfg->paxel.v_cnt != user_cfg->paxel.v_cnt) ||
- (cur_cfg->paxel.line_inc != user_cfg->paxel.line_inc)) {
- update = 1;
- goto out;
- }
-
- /* af_mode */
- if (cur_cfg->fvmode != user_cfg->fvmode)
- update = 1;
-
-out:
- if (update || !af->configured) {
- memcpy(cur_cfg, user_cfg, sizeof(*cur_cfg));
- af->inc_config++;
- af->update = 1;
- /*
- * User might be asked for a bigger buffer than necessary for
- * this configuration. In order to return the right amount of
- * data during buffer request, let's calculate the size here
- * instead of stick with user_cfg->buf_size.
- */
- cur_cfg->buf_size = h3a_af_get_buf_size(cur_cfg);
- }
-}
-
-static long h3a_af_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
- struct ispstat *stat = v4l2_get_subdevdata(sd);
-
- switch (cmd) {
- case VIDIOC_OMAP3ISP_AF_CFG:
- return omap3isp_stat_config(stat, arg);
- case VIDIOC_OMAP3ISP_STAT_REQ:
- return omap3isp_stat_request_statistics(stat, arg);
- case VIDIOC_OMAP3ISP_STAT_EN: {
- int *en = arg;
- return omap3isp_stat_enable(stat, !!*en);
- }
- }
-
- return -ENOIOCTLCMD;
-
-}
-
-static const struct ispstat_ops h3a_af_ops = {
- .validate_params = h3a_af_validate_params,
- .set_params = h3a_af_set_params,
- .setup_regs = h3a_af_setup_regs,
- .enable = h3a_af_enable,
- .busy = h3a_af_busy,
-};
-
-static const struct v4l2_subdev_core_ops h3a_af_subdev_core_ops = {
- .ioctl = h3a_af_ioctl,
- .subscribe_event = omap3isp_stat_subscribe_event,
- .unsubscribe_event = omap3isp_stat_unsubscribe_event,
-};
-
-static const struct v4l2_subdev_video_ops h3a_af_subdev_video_ops = {
- .s_stream = omap3isp_stat_s_stream,
-};
-
-static const struct v4l2_subdev_ops h3a_af_subdev_ops = {
- .core = &h3a_af_subdev_core_ops,
- .video = &h3a_af_subdev_video_ops,
-};
-
-/* Function to register the AF character device driver. */
-int omap3isp_h3a_af_init(struct isp_device *isp)
-{
- struct ispstat *af = &isp->isp_af;
- struct omap3isp_h3a_af_config *af_cfg;
- struct omap3isp_h3a_af_config *af_recover_cfg;
- int ret;
-
- af_cfg = kzalloc(sizeof(*af_cfg), GFP_KERNEL);
- if (af_cfg == NULL)
- return -ENOMEM;
-
- memset(af, 0, sizeof(*af));
- af->ops = &h3a_af_ops;
- af->priv = af_cfg;
- af->dma_ch = -1;
- af->event_type = V4L2_EVENT_OMAP3ISP_AF;
- af->isp = isp;
-
- /* Set recover state configuration */
- af_recover_cfg = kzalloc(sizeof(*af_recover_cfg), GFP_KERNEL);
- if (!af_recover_cfg) {
- dev_err(af->isp->dev, "AF: cannot allocate memory for recover "
- "configuration.\n");
- ret = -ENOMEM;
- goto err_recover_alloc;
- }
-
- af_recover_cfg->paxel.h_start = OMAP3ISP_AF_PAXEL_HZSTART_MIN;
- af_recover_cfg->paxel.width = OMAP3ISP_AF_PAXEL_WIDTH_MIN;
- af_recover_cfg->paxel.height = OMAP3ISP_AF_PAXEL_HEIGHT_MIN;
- af_recover_cfg->paxel.h_cnt = OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MIN;
- af_recover_cfg->paxel.v_cnt = OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MIN;
- af_recover_cfg->paxel.line_inc = OMAP3ISP_AF_PAXEL_INCREMENT_MIN;
- if (h3a_af_validate_params(af, af_recover_cfg)) {
- dev_err(af->isp->dev, "AF: recover configuration is "
- "invalid.\n");
- ret = -EINVAL;
- goto err_conf;
- }
-
- af_recover_cfg->buf_size = h3a_af_get_buf_size(af_recover_cfg);
- af->recover_priv = af_recover_cfg;
-
- ret = omap3isp_stat_init(af, "AF", &h3a_af_subdev_ops);
- if (ret)
- goto err_conf;
-
- return 0;
-
-err_conf:
- kfree(af_recover_cfg);
-err_recover_alloc:
- kfree(af_cfg);
-
- return ret;
-}
-
-void omap3isp_h3a_af_cleanup(struct isp_device *isp)
-{
- kfree(isp->isp_af.priv);
- kfree(isp->isp_af.recover_priv);
- omap3isp_stat_cleanup(&isp->isp_af);
-}
diff --git a/drivers/media/video/omap3isp/isphist.c b/drivers/media/video/omap3isp/isphist.c
deleted file mode 100644
index 1163907bcdd..00000000000
--- a/drivers/media/video/omap3isp/isphist.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * isphist.c
- *
- * TI OMAP3 ISP - Histogram module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: David Cohen <dacohen@gmail.com>
- * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/device.h>
-
-#include "isp.h"
-#include "ispreg.h"
-#include "isphist.h"
-
-#define HIST_CONFIG_DMA 1
-
-#define HIST_USING_DMA(hist) ((hist)->dma_ch >= 0)
-
-/*
- * hist_reset_mem - clear Histogram memory before start stats engine.
- */
-static void hist_reset_mem(struct ispstat *hist)
-{
- struct isp_device *isp = hist->isp;
- struct omap3isp_hist_config *conf = hist->priv;
- unsigned int i;
-
- isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
-
- /*
- * By setting it, the histogram internal buffer is being cleared at the
- * same time it's being read. This bit must be cleared afterwards.
- */
- isp_reg_set(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);
-
- /*
- * We'll clear 4 words at each iteration for optimization. It avoids
- * 3/4 of the jumps. We also know HIST_MEM_SIZE is divisible by 4.
- */
- for (i = OMAP3ISP_HIST_MEM_SIZE / 4; i > 0; i--) {
- isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
- isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
- isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
- isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
- }
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);
-
- hist->wait_acc_frames = conf->num_acc_frames;
-}
-
-static void hist_dma_config(struct ispstat *hist)
-{
- hist->dma_config.data_type = OMAP_DMA_DATA_TYPE_S32;
- hist->dma_config.sync_mode = OMAP_DMA_SYNC_ELEMENT;
- hist->dma_config.frame_count = 1;
- hist->dma_config.src_amode = OMAP_DMA_AMODE_CONSTANT;
- hist->dma_config.src_start = OMAP3ISP_HIST_REG_BASE + ISPHIST_DATA;
- hist->dma_config.dst_amode = OMAP_DMA_AMODE_POST_INC;
- hist->dma_config.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
-}
-
-/*
- * hist_setup_regs - Helper function to update Histogram registers.
- */
-static void hist_setup_regs(struct ispstat *hist, void *priv)
-{
- struct isp_device *isp = hist->isp;
- struct omap3isp_hist_config *conf = priv;
- int c;
- u32 cnt;
- u32 wb_gain;
- u32 reg_hor[OMAP3ISP_HIST_MAX_REGIONS];
- u32 reg_ver[OMAP3ISP_HIST_MAX_REGIONS];
-
- if (!hist->update || hist->state == ISPSTAT_DISABLED ||
- hist->state == ISPSTAT_DISABLING)
- return;
-
- cnt = conf->cfa << ISPHIST_CNT_CFA_SHIFT;
-
- wb_gain = conf->wg[0] << ISPHIST_WB_GAIN_WG00_SHIFT;
- wb_gain |= conf->wg[1] << ISPHIST_WB_GAIN_WG01_SHIFT;
- wb_gain |= conf->wg[2] << ISPHIST_WB_GAIN_WG02_SHIFT;
- if (conf->cfa == OMAP3ISP_HIST_CFA_BAYER)
- wb_gain |= conf->wg[3] << ISPHIST_WB_GAIN_WG03_SHIFT;
-
- /* Regions size and position */
- for (c = 0; c < OMAP3ISP_HIST_MAX_REGIONS; c++) {
- if (c < conf->num_regions) {
- reg_hor[c] = conf->region[c].h_start <<
- ISPHIST_REG_START_SHIFT;
- reg_hor[c] = conf->region[c].h_end <<
- ISPHIST_REG_END_SHIFT;
- reg_ver[c] = conf->region[c].v_start <<
- ISPHIST_REG_START_SHIFT;
- reg_ver[c] = conf->region[c].v_end <<
- ISPHIST_REG_END_SHIFT;
- } else {
- reg_hor[c] = 0;
- reg_ver[c] = 0;
- }
- }
-
- cnt |= conf->hist_bins << ISPHIST_CNT_BINS_SHIFT;
- switch (conf->hist_bins) {
- case OMAP3ISP_HIST_BINS_256:
- cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 8) <<
- ISPHIST_CNT_SHIFT_SHIFT;
- break;
- case OMAP3ISP_HIST_BINS_128:
- cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 7) <<
- ISPHIST_CNT_SHIFT_SHIFT;
- break;
- case OMAP3ISP_HIST_BINS_64:
- cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 6) <<
- ISPHIST_CNT_SHIFT_SHIFT;
- break;
- default: /* OMAP3ISP_HIST_BINS_32 */
- cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 5) <<
- ISPHIST_CNT_SHIFT_SHIFT;
- break;
- }
-
- hist_reset_mem(hist);
-
- isp_reg_writel(isp, cnt, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT);
- isp_reg_writel(isp, wb_gain, OMAP3_ISP_IOMEM_HIST, ISPHIST_WB_GAIN);
- isp_reg_writel(isp, reg_hor[0], OMAP3_ISP_IOMEM_HIST, ISPHIST_R0_HORZ);
- isp_reg_writel(isp, reg_ver[0], OMAP3_ISP_IOMEM_HIST, ISPHIST_R0_VERT);
- isp_reg_writel(isp, reg_hor[1], OMAP3_ISP_IOMEM_HIST, ISPHIST_R1_HORZ);
- isp_reg_writel(isp, reg_ver[1], OMAP3_ISP_IOMEM_HIST, ISPHIST_R1_VERT);
- isp_reg_writel(isp, reg_hor[2], OMAP3_ISP_IOMEM_HIST, ISPHIST_R2_HORZ);
- isp_reg_writel(isp, reg_ver[2], OMAP3_ISP_IOMEM_HIST, ISPHIST_R2_VERT);
- isp_reg_writel(isp, reg_hor[3], OMAP3_ISP_IOMEM_HIST, ISPHIST_R3_HORZ);
- isp_reg_writel(isp, reg_ver[3], OMAP3_ISP_IOMEM_HIST, ISPHIST_R3_VERT);
-
- hist->update = 0;
- hist->config_counter += hist->inc_config;
- hist->inc_config = 0;
- hist->buf_size = conf->buf_size;
-}
-
-static void hist_enable(struct ispstat *hist, int enable)
-{
- if (enable) {
- isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR,
- ISPHIST_PCR_ENABLE);
- isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
- ISPCTRL_HIST_CLK_EN);
- } else {
- isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR,
- ISPHIST_PCR_ENABLE);
- isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
- ISPCTRL_HIST_CLK_EN);
- }
-}
-
-static int hist_busy(struct ispstat *hist)
-{
- return isp_reg_readl(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR)
- & ISPHIST_PCR_BUSY;
-}
-
-static void hist_dma_cb(int lch, u16 ch_status, void *data)
-{
- struct ispstat *hist = data;
-
- if (ch_status & ~OMAP_DMA_BLOCK_IRQ) {
- dev_dbg(hist->isp->dev, "hist: DMA error. status = 0x%04x\n",
- ch_status);
- omap_stop_dma(lch);
- hist_reset_mem(hist);
- atomic_set(&hist->buf_err, 1);
- }
- isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
- ISPHIST_CNT_CLEAR);
-
- omap3isp_stat_dma_isr(hist);
- if (hist->state != ISPSTAT_DISABLED)
- omap3isp_hist_dma_done(hist->isp);
-}
-
-static int hist_buf_dma(struct ispstat *hist)
-{
- dma_addr_t dma_addr = hist->active_buf->dma_addr;
-
- if (unlikely(!dma_addr)) {
- dev_dbg(hist->isp->dev, "hist: invalid DMA buffer address\n");
- hist_reset_mem(hist);
- return STAT_NO_BUF;
- }
-
- isp_reg_writel(hist->isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
- isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
- ISPHIST_CNT_CLEAR);
- omap3isp_flush(hist->isp);
- hist->dma_config.dst_start = dma_addr;
- hist->dma_config.elem_count = hist->buf_size / sizeof(u32);
- omap_set_dma_params(hist->dma_ch, &hist->dma_config);
-
- omap_start_dma(hist->dma_ch);
-
- return STAT_BUF_WAITING_DMA;
-}
-
-static int hist_buf_pio(struct ispstat *hist)
-{
- struct isp_device *isp = hist->isp;
- u32 *buf = hist->active_buf->virt_addr;
- unsigned int i;
-
- if (!buf) {
- dev_dbg(isp->dev, "hist: invalid PIO buffer address\n");
- hist_reset_mem(hist);
- return STAT_NO_BUF;
- }
-
- isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
-
- /*
- * By setting it, the histogram internal buffer is being cleared at the
- * same time it's being read. This bit must be cleared just after all
- * data is acquired.
- */
- isp_reg_set(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);
-
- /*
- * We'll read 4 times a 4-bytes-word at each iteration for
- * optimization. It avoids 3/4 of the jumps. We also know buf_size is
- * divisible by 16.
- */
- for (i = hist->buf_size / 16; i > 0; i--) {
- *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
- *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
- *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
- *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
- }
- isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
- ISPHIST_CNT_CLEAR);
-
- return STAT_BUF_DONE;
-}
-
-/*
- * hist_buf_process - Callback from ISP driver for HIST interrupt.
- */
-static int hist_buf_process(struct ispstat *hist)
-{
- struct omap3isp_hist_config *user_cfg = hist->priv;
- int ret;
-
- if (atomic_read(&hist->buf_err) || hist->state != ISPSTAT_ENABLED) {
- hist_reset_mem(hist);
- return STAT_NO_BUF;
- }
-
- if (--(hist->wait_acc_frames))
- return STAT_NO_BUF;
-
- if (HIST_USING_DMA(hist))
- ret = hist_buf_dma(hist);
- else
- ret = hist_buf_pio(hist);
-
- hist->wait_acc_frames = user_cfg->num_acc_frames;
-
- return ret;
-}
-
-static u32 hist_get_buf_size(struct omap3isp_hist_config *conf)
-{
- return OMAP3ISP_HIST_MEM_SIZE_BINS(conf->hist_bins) * conf->num_regions;
-}
-
-/*
- * hist_validate_params - Helper function to check user given params.
- * @user_cfg: Pointer to user configuration structure.
- *
- * Returns 0 on success configuration.
- */
-static int hist_validate_params(struct ispstat *hist, void *new_conf)
-{
- struct omap3isp_hist_config *user_cfg = new_conf;
- int c;
- u32 buf_size;
-
- if (user_cfg->cfa > OMAP3ISP_HIST_CFA_FOVEONX3)
- return -EINVAL;
-
- /* Regions size and position */
-
- if ((user_cfg->num_regions < OMAP3ISP_HIST_MIN_REGIONS) ||
- (user_cfg->num_regions > OMAP3ISP_HIST_MAX_REGIONS))
- return -EINVAL;
-
- /* Regions */
- for (c = 0; c < user_cfg->num_regions; c++) {
- if (user_cfg->region[c].h_start & ~ISPHIST_REG_START_END_MASK)
- return -EINVAL;
- if (user_cfg->region[c].h_end & ~ISPHIST_REG_START_END_MASK)
- return -EINVAL;
- if (user_cfg->region[c].v_start & ~ISPHIST_REG_START_END_MASK)
- return -EINVAL;
- if (user_cfg->region[c].v_end & ~ISPHIST_REG_START_END_MASK)
- return -EINVAL;
- if (user_cfg->region[c].h_start > user_cfg->region[c].h_end)
- return -EINVAL;
- if (user_cfg->region[c].v_start > user_cfg->region[c].v_end)
- return -EINVAL;
- }
-
- switch (user_cfg->num_regions) {
- case 1:
- if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_256)
- return -EINVAL;
- break;
- case 2:
- if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_128)
- return -EINVAL;
- break;
- default: /* 3 or 4 */
- if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_64)
- return -EINVAL;
- break;
- }
-
- buf_size = hist_get_buf_size(user_cfg);
- if (buf_size > user_cfg->buf_size)
- /* User's buf_size request wasn't enoght */
- user_cfg->buf_size = buf_size;
- else if (user_cfg->buf_size > OMAP3ISP_HIST_MAX_BUF_SIZE)
- user_cfg->buf_size = OMAP3ISP_HIST_MAX_BUF_SIZE;
-
- return 0;
-}
-
-static int hist_comp_params(struct ispstat *hist,
- struct omap3isp_hist_config *user_cfg)
-{
- struct omap3isp_hist_config *cur_cfg = hist->priv;
- int c;
-
- if (cur_cfg->cfa != user_cfg->cfa)
- return 1;
-
- if (cur_cfg->num_acc_frames != user_cfg->num_acc_frames)
- return 1;
-
- if (cur_cfg->hist_bins != user_cfg->hist_bins)
- return 1;
-
- for (c = 0; c < OMAP3ISP_HIST_MAX_WG; c++) {
- if (c == 3 && user_cfg->cfa == OMAP3ISP_HIST_CFA_FOVEONX3)
- break;
- else if (cur_cfg->wg[c] != user_cfg->wg[c])
- return 1;
- }
-
- if (cur_cfg->num_regions != user_cfg->num_regions)
- return 1;
-
- /* Regions */
- for (c = 0; c < user_cfg->num_regions; c++) {
- if (cur_cfg->region[c].h_start != user_cfg->region[c].h_start)
- return 1;
- if (cur_cfg->region[c].h_end != user_cfg->region[c].h_end)
- return 1;
- if (cur_cfg->region[c].v_start != user_cfg->region[c].v_start)
- return 1;
- if (cur_cfg->region[c].v_end != user_cfg->region[c].v_end)
- return 1;
- }
-
- return 0;
-}
-
-/*
- * hist_update_params - Helper function to check and store user given params.
- * @new_conf: Pointer to user configuration structure.
- */
-static void hist_set_params(struct ispstat *hist, void *new_conf)
-{
- struct omap3isp_hist_config *user_cfg = new_conf;
- struct omap3isp_hist_config *cur_cfg = hist->priv;
-
- if (!hist->configured || hist_comp_params(hist, user_cfg)) {
- memcpy(cur_cfg, user_cfg, sizeof(*user_cfg));
- if (user_cfg->num_acc_frames == 0)
- user_cfg->num_acc_frames = 1;
- hist->inc_config++;
- hist->update = 1;
- /*
- * User might be asked for a bigger buffer than necessary for
- * this configuration. In order to return the right amount of
- * data during buffer request, let's calculate the size here
- * instead of stick with user_cfg->buf_size.
- */
- cur_cfg->buf_size = hist_get_buf_size(cur_cfg);
-
- }
-}
-
-static long hist_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
- struct ispstat *stat = v4l2_get_subdevdata(sd);
-
- switch (cmd) {
- case VIDIOC_OMAP3ISP_HIST_CFG:
- return omap3isp_stat_config(stat, arg);
- case VIDIOC_OMAP3ISP_STAT_REQ:
- return omap3isp_stat_request_statistics(stat, arg);
- case VIDIOC_OMAP3ISP_STAT_EN: {
- int *en = arg;
- return omap3isp_stat_enable(stat, !!*en);
- }
- }
-
- return -ENOIOCTLCMD;
-
-}
-
-static const struct ispstat_ops hist_ops = {
- .validate_params = hist_validate_params,
- .set_params = hist_set_params,
- .setup_regs = hist_setup_regs,
- .enable = hist_enable,
- .busy = hist_busy,
- .buf_process = hist_buf_process,
-};
-
-static const struct v4l2_subdev_core_ops hist_subdev_core_ops = {
- .ioctl = hist_ioctl,
- .subscribe_event = omap3isp_stat_subscribe_event,
- .unsubscribe_event = omap3isp_stat_unsubscribe_event,
-};
-
-static const struct v4l2_subdev_video_ops hist_subdev_video_ops = {
- .s_stream = omap3isp_stat_s_stream,
-};
-
-static const struct v4l2_subdev_ops hist_subdev_ops = {
- .core = &hist_subdev_core_ops,
- .video = &hist_subdev_video_ops,
-};
-
-/*
- * omap3isp_hist_init - Module Initialization.
- */
-int omap3isp_hist_init(struct isp_device *isp)
-{
- struct ispstat *hist = &isp->isp_hist;
- struct omap3isp_hist_config *hist_cfg;
- int ret = -1;
-
- hist_cfg = kzalloc(sizeof(*hist_cfg), GFP_KERNEL);
- if (hist_cfg == NULL)
- return -ENOMEM;
-
- memset(hist, 0, sizeof(*hist));
- if (HIST_CONFIG_DMA)
- ret = omap_request_dma(OMAP24XX_DMA_NO_DEVICE, "DMA_ISP_HIST",
- hist_dma_cb, hist, &hist->dma_ch);
- if (ret) {
- if (HIST_CONFIG_DMA)
- dev_warn(isp->dev, "hist: DMA request channel failed. "
- "Using PIO only.\n");
- hist->dma_ch = -1;
- } else {
- dev_dbg(isp->dev, "hist: DMA channel = %d\n", hist->dma_ch);
- hist_dma_config(hist);
- omap_enable_dma_irq(hist->dma_ch, OMAP_DMA_BLOCK_IRQ);
- }
-
- hist->ops = &hist_ops;
- hist->priv = hist_cfg;
- hist->event_type = V4L2_EVENT_OMAP3ISP_HIST;
- hist->isp = isp;
-
- ret = omap3isp_stat_init(hist, "histogram", &hist_subdev_ops);
- if (ret) {
- kfree(hist_cfg);
- if (HIST_USING_DMA(hist))
- omap_free_dma(hist->dma_ch);
- }
-
- return ret;
-}
-
-/*
- * omap3isp_hist_cleanup - Module cleanup.
- */
-void omap3isp_hist_cleanup(struct isp_device *isp)
-{
- if (HIST_USING_DMA(&isp->isp_hist))
- omap_free_dma(isp->isp_hist.dma_ch);
- kfree(isp->isp_hist.priv);
- omap3isp_stat_cleanup(&isp->isp_hist);
-}
diff --git a/drivers/media/video/omap3isp/isphist.h b/drivers/media/video/omap3isp/isphist.h
deleted file mode 100644
index 0b2a38ec94c..00000000000
--- a/drivers/media/video/omap3isp/isphist.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * isphist.h
- *
- * TI OMAP3 ISP - Histogram module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: David Cohen <dacohen@gmail.com>
- * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef OMAP3_ISP_HIST_H
-#define OMAP3_ISP_HIST_H
-
-#include <linux/omap3isp.h>
-
-#define ISPHIST_IN_BIT_WIDTH_CCDC 10
-
-struct isp_device;
-
-int omap3isp_hist_init(struct isp_device *isp);
-void omap3isp_hist_cleanup(struct isp_device *isp);
-
-#endif /* OMAP3_ISP_HIST */
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c
deleted file mode 100644
index 53f5a703e31..00000000000
--- a/drivers/media/video/omap3isp/isppreview.c
+++ /dev/null
@@ -1,2369 +0,0 @@
-/*
- * isppreview.c
- *
- * TI OMAP3 ISP driver - Preview module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/device.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-
-#include "isp.h"
-#include "ispreg.h"
-#include "isppreview.h"
-
-/* Default values in Office Fluorescent Light for RGBtoRGB Blending */
-static struct omap3isp_prev_rgbtorgb flr_rgb2rgb = {
- { /* RGB-RGB Matrix */
- {0x01E2, 0x0F30, 0x0FEE},
- {0x0F9B, 0x01AC, 0x0FB9},
- {0x0FE0, 0x0EC0, 0x0260}
- }, /* RGB Offset */
- {0x0000, 0x0000, 0x0000}
-};
-
-/* Default values in Office Fluorescent Light for RGB to YUV Conversion*/
-static struct omap3isp_prev_csc flr_prev_csc = {
- { /* CSC Coef Matrix */
- {66, 129, 25},
- {-38, -75, 112},
- {112, -94 , -18}
- }, /* CSC Offset */
- {0x0, 0x0, 0x0}
-};
-
-/* Default values in Office Fluorescent Light for CFA Gradient*/
-#define FLR_CFA_GRADTHRS_HORZ 0x28
-#define FLR_CFA_GRADTHRS_VERT 0x28
-
-/* Default values in Office Fluorescent Light for Chroma Suppression*/
-#define FLR_CSUP_GAIN 0x0D
-#define FLR_CSUP_THRES 0xEB
-
-/* Default values in Office Fluorescent Light for Noise Filter*/
-#define FLR_NF_STRGTH 0x03
-
-/* Default values for White Balance */
-#define FLR_WBAL_DGAIN 0x100
-#define FLR_WBAL_COEF 0x20
-
-/* Default values in Office Fluorescent Light for Black Adjustment*/
-#define FLR_BLKADJ_BLUE 0x0
-#define FLR_BLKADJ_GREEN 0x0
-#define FLR_BLKADJ_RED 0x0
-
-#define DEF_DETECT_CORRECT_VAL 0xe
-
-/*
- * Margins and image size limits.
- *
- * The preview engine crops several rows and columns internally depending on
- * which filters are enabled. To avoid format changes when the filters are
- * enabled or disabled (which would prevent them from being turned on or off
- * during streaming), the driver assumes all the filters are enabled when
- * computing sink crop and source format limits.
- *
- * If a filter is disabled, additional cropping is automatically added at the
- * preview engine input by the driver to avoid overflow at line and frame end.
- * This is completely transparent for applications.
- *
- * Median filter 4 pixels
- * Noise filter,
- * Faulty pixels correction 4 pixels, 4 lines
- * CFA filter 4 pixels, 4 lines in Bayer mode
- * 2 lines in other modes
- * Color suppression 2 pixels
- * or luma enhancement
- * -------------------------------------------------------------
- * Maximum total 14 pixels, 8 lines
- *
- * The color suppression and luma enhancement filters are applied after bayer to
- * YUV conversion. They thus can crop one pixel on the left and one pixel on the
- * right side of the image without changing the color pattern. When both those
- * filters are disabled, the driver must crop the two pixels on the same side of
- * the image to avoid changing the bayer pattern. The left margin is thus set to
- * 8 pixels and the right margin to 6 pixels.
- */
-
-#define PREV_MARGIN_LEFT 8
-#define PREV_MARGIN_RIGHT 6
-#define PREV_MARGIN_TOP 4
-#define PREV_MARGIN_BOTTOM 4
-
-#define PREV_MIN_IN_WIDTH 64
-#define PREV_MIN_IN_HEIGHT 8
-#define PREV_MAX_IN_HEIGHT 16384
-
-#define PREV_MIN_OUT_WIDTH 0
-#define PREV_MIN_OUT_HEIGHT 0
-#define PREV_MAX_OUT_WIDTH_REV_1 1280
-#define PREV_MAX_OUT_WIDTH_REV_2 3300
-#define PREV_MAX_OUT_WIDTH_REV_15 4096
-
-/*
- * Coeficient Tables for the submodules in Preview.
- * Array is initialised with the values from.the tables text file.
- */
-
-/*
- * CFA Filter Coefficient Table
- *
- */
-static u32 cfa_coef_table[] = {
-#include "cfa_coef_table.h"
-};
-
-/*
- * Default Gamma Correction Table - All components
- */
-static u32 gamma_table[] = {
-#include "gamma_table.h"
-};
-
-/*
- * Noise Filter Threshold table
- */
-static u32 noise_filter_table[] = {
-#include "noise_filter_table.h"
-};
-
-/*
- * Luminance Enhancement Table
- */
-static u32 luma_enhance_table[] = {
-#include "luma_enhance_table.h"
-};
-
-/*
- * preview_enable_invalaw - Enable/Disable Inverse A-Law module in Preview.
- * @enable: 1 - Reverse the A-Law done in CCDC.
- */
-static void
-preview_enable_invalaw(struct isp_prev_device *prev, u8 enable)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- if (enable)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW);
-}
-
-/*
- * preview_enable_drkframe_capture - Enable/Disable of the darkframe capture.
- * @prev -
- * @enable: 1 - Enable, 0 - Disable
- *
- * NOTE: PRV_WSDR_ADDR and PRV_WADD_OFFSET must be set also
- * The process is applied for each captured frame.
- */
-static void
-preview_enable_drkframe_capture(struct isp_prev_device *prev, u8 enable)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- if (enable)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_DRKFCAP);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_DRKFCAP);
-}
-
-/*
- * preview_enable_drkframe - Enable/Disable of the darkframe subtract.
- * @enable: 1 - Acquires memory bandwidth since the pixels in each frame is
- * subtracted with the pixels in the current frame.
- *
- * The process is applied for each captured frame.
- */
-static void
-preview_enable_drkframe(struct isp_prev_device *prev, u8 enable)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- if (enable)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_DRKFEN);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_DRKFEN);
-}
-
-/*
- * preview_config_drkf_shadcomp - Configures shift value in shading comp.
- * @scomp_shtval: 3bit value of shift used in shading compensation.
- */
-static void
-preview_config_drkf_shadcomp(struct isp_prev_device *prev,
- const void *scomp_shtval)
-{
- struct isp_device *isp = to_isp_device(prev);
- const u32 *shtval = scomp_shtval;
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_SCOMP_SFT_MASK,
- *shtval << ISPPRV_PCR_SCOMP_SFT_SHIFT);
-}
-
-/*
- * preview_enable_hmed - Enables/Disables of the Horizontal Median Filter.
- * @enable: 1 - Enables Horizontal Median Filter.
- */
-static void
-preview_enable_hmed(struct isp_prev_device *prev, u8 enable)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- if (enable)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_HMEDEN);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_HMEDEN);
-}
-
-/*
- * preview_config_hmed - Configures the Horizontal Median Filter.
- * @prev_hmed: Structure containing the odd and even distance between the
- * pixels in the image along with the filter threshold.
- */
-static void
-preview_config_hmed(struct isp_prev_device *prev, const void *prev_hmed)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_hmed *hmed = prev_hmed;
-
- isp_reg_writel(isp, (hmed->odddist == 1 ? 0 : ISPPRV_HMED_ODDDIST) |
- (hmed->evendist == 1 ? 0 : ISPPRV_HMED_EVENDIST) |
- (hmed->thres << ISPPRV_HMED_THRESHOLD_SHIFT),
- OMAP3_ISP_IOMEM_PREV, ISPPRV_HMED);
-}
-
-/*
- * preview_config_noisefilter - Configures the Noise Filter.
- * @prev_nf: Structure containing the noisefilter table, strength to be used
- * for the noise filter and the defect correction enable flag.
- */
-static void
-preview_config_noisefilter(struct isp_prev_device *prev, const void *prev_nf)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_nf *nf = prev_nf;
- unsigned int i;
-
- isp_reg_writel(isp, nf->spread, OMAP3_ISP_IOMEM_PREV, ISPPRV_NF);
- isp_reg_writel(isp, ISPPRV_NF_TABLE_ADDR,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
- for (i = 0; i < OMAP3ISP_PREV_NF_TBL_SIZE; i++) {
- isp_reg_writel(isp, nf->table[i],
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
- }
-}
-
-/*
- * preview_config_dcor - Configures the defect correction
- * @prev_dcor: Structure containing the defect correct thresholds
- */
-static void
-preview_config_dcor(struct isp_prev_device *prev, const void *prev_dcor)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_dcor *dcor = prev_dcor;
-
- isp_reg_writel(isp, dcor->detect_correct[0],
- OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR0);
- isp_reg_writel(isp, dcor->detect_correct[1],
- OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR1);
- isp_reg_writel(isp, dcor->detect_correct[2],
- OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR2);
- isp_reg_writel(isp, dcor->detect_correct[3],
- OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR3);
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_DCCOUP,
- dcor->couplet_mode_en ? ISPPRV_PCR_DCCOUP : 0);
-}
-
-/*
- * preview_config_cfa - Configures the CFA Interpolation parameters.
- * @prev_cfa: Structure containing the CFA interpolation table, CFA format
- * in the image, vertical and horizontal gradient threshold.
- */
-static void
-preview_config_cfa(struct isp_prev_device *prev, const void *prev_cfa)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_cfa *cfa = prev_cfa;
- unsigned int i;
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_CFAFMT_MASK,
- cfa->format << ISPPRV_PCR_CFAFMT_SHIFT);
-
- isp_reg_writel(isp,
- (cfa->gradthrs_vert << ISPPRV_CFA_GRADTH_VER_SHIFT) |
- (cfa->gradthrs_horz << ISPPRV_CFA_GRADTH_HOR_SHIFT),
- OMAP3_ISP_IOMEM_PREV, ISPPRV_CFA);
-
- isp_reg_writel(isp, ISPPRV_CFA_TABLE_ADDR,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
-
- for (i = 0; i < OMAP3ISP_PREV_CFA_TBL_SIZE; i++) {
- isp_reg_writel(isp, cfa->table[i],
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
- }
-}
-
-/*
- * preview_config_gammacorrn - Configures the Gamma Correction table values
- * @gtable: Structure containing the table for red, blue, green gamma table.
- */
-static void
-preview_config_gammacorrn(struct isp_prev_device *prev, const void *gtable)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_gtables *gt = gtable;
- unsigned int i;
-
- isp_reg_writel(isp, ISPPRV_REDGAMMA_TABLE_ADDR,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
- for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
- isp_reg_writel(isp, gt->red[i], OMAP3_ISP_IOMEM_PREV,
- ISPPRV_SET_TBL_DATA);
-
- isp_reg_writel(isp, ISPPRV_GREENGAMMA_TABLE_ADDR,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
- for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
- isp_reg_writel(isp, gt->green[i], OMAP3_ISP_IOMEM_PREV,
- ISPPRV_SET_TBL_DATA);
-
- isp_reg_writel(isp, ISPPRV_BLUEGAMMA_TABLE_ADDR,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
- for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
- isp_reg_writel(isp, gt->blue[i], OMAP3_ISP_IOMEM_PREV,
- ISPPRV_SET_TBL_DATA);
-}
-
-/*
- * preview_config_luma_enhancement - Sets the Luminance Enhancement table.
- * @ytable: Structure containing the table for Luminance Enhancement table.
- */
-static void
-preview_config_luma_enhancement(struct isp_prev_device *prev,
- const void *ytable)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_luma *yt = ytable;
- unsigned int i;
-
- isp_reg_writel(isp, ISPPRV_YENH_TABLE_ADDR,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
- for (i = 0; i < OMAP3ISP_PREV_YENH_TBL_SIZE; i++) {
- isp_reg_writel(isp, yt->table[i],
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
- }
-}
-
-/*
- * preview_config_chroma_suppression - Configures the Chroma Suppression.
- * @csup: Structure containing the threshold value for suppression
- * and the hypass filter enable flag.
- */
-static void
-preview_config_chroma_suppression(struct isp_prev_device *prev,
- const void *csup)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_csup *cs = csup;
-
- isp_reg_writel(isp,
- cs->gain | (cs->thres << ISPPRV_CSUP_THRES_SHIFT) |
- (cs->hypf_en << ISPPRV_CSUP_HPYF_SHIFT),
- OMAP3_ISP_IOMEM_PREV, ISPPRV_CSUP);
-}
-
-/*
- * preview_enable_noisefilter - Enables/Disables the Noise Filter.
- * @enable: 1 - Enables the Noise Filter.
- */
-static void
-preview_enable_noisefilter(struct isp_prev_device *prev, u8 enable)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- if (enable)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_NFEN);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_NFEN);
-}
-
-/*
- * preview_enable_dcor - Enables/Disables the defect correction.
- * @enable: 1 - Enables the defect correction.
- */
-static void
-preview_enable_dcor(struct isp_prev_device *prev, u8 enable)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- if (enable)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_DCOREN);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_DCOREN);
-}
-
-/*
- * preview_enable_gammabypass - Enables/Disables the GammaByPass
- * @enable: 1 - Bypasses Gamma - 10bit input is cropped to 8MSB.
- * 0 - Goes through Gamma Correction. input and output is 10bit.
- */
-static void
-preview_enable_gammabypass(struct isp_prev_device *prev, u8 enable)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- if (enable)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_GAMMA_BYPASS);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_GAMMA_BYPASS);
-}
-
-/*
- * preview_enable_luma_enhancement - Enables/Disables Luminance Enhancement
- * @enable: 1 - Enable the Luminance Enhancement.
- */
-static void
-preview_enable_luma_enhancement(struct isp_prev_device *prev, u8 enable)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- if (enable)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_YNENHEN);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_YNENHEN);
-}
-
-/*
- * preview_enable_chroma_suppression - Enables/Disables Chrominance Suppr.
- * @enable: 1 - Enable the Chrominance Suppression.
- */
-static void
-preview_enable_chroma_suppression(struct isp_prev_device *prev, u8 enable)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- if (enable)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_SUPEN);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_SUPEN);
-}
-
-/*
- * preview_config_whitebalance - Configures the White Balance parameters.
- * @prev_wbal: Structure containing the digital gain and white balance
- * coefficient.
- *
- * Coefficient matrix always with default values.
- */
-static void
-preview_config_whitebalance(struct isp_prev_device *prev, const void *prev_wbal)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_wbal *wbal = prev_wbal;
- u32 val;
-
- isp_reg_writel(isp, wbal->dgain, OMAP3_ISP_IOMEM_PREV, ISPPRV_WB_DGAIN);
-
- val = wbal->coef0 << ISPPRV_WBGAIN_COEF0_SHIFT;
- val |= wbal->coef1 << ISPPRV_WBGAIN_COEF1_SHIFT;
- val |= wbal->coef2 << ISPPRV_WBGAIN_COEF2_SHIFT;
- val |= wbal->coef3 << ISPPRV_WBGAIN_COEF3_SHIFT;
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_WBGAIN);
-
- isp_reg_writel(isp,
- ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N0_0_SHIFT |
- ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N0_1_SHIFT |
- ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N0_2_SHIFT |
- ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N0_3_SHIFT |
- ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N1_0_SHIFT |
- ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N1_1_SHIFT |
- ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N1_2_SHIFT |
- ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N1_3_SHIFT |
- ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N2_0_SHIFT |
- ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N2_1_SHIFT |
- ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N2_2_SHIFT |
- ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N2_3_SHIFT |
- ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N3_0_SHIFT |
- ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N3_1_SHIFT |
- ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N3_2_SHIFT |
- ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N3_3_SHIFT,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_WBSEL);
-}
-
-/*
- * preview_config_blkadj - Configures the Black Adjustment parameters.
- * @prev_blkadj: Structure containing the black adjustment towards red, green,
- * blue.
- */
-static void
-preview_config_blkadj(struct isp_prev_device *prev, const void *prev_blkadj)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_blkadj *blkadj = prev_blkadj;
-
- isp_reg_writel(isp, (blkadj->blue << ISPPRV_BLKADJOFF_B_SHIFT) |
- (blkadj->green << ISPPRV_BLKADJOFF_G_SHIFT) |
- (blkadj->red << ISPPRV_BLKADJOFF_R_SHIFT),
- OMAP3_ISP_IOMEM_PREV, ISPPRV_BLKADJOFF);
-}
-
-/*
- * preview_config_rgb_blending - Configures the RGB-RGB Blending matrix.
- * @rgb2rgb: Structure containing the rgb to rgb blending matrix and the rgb
- * offset.
- */
-static void
-preview_config_rgb_blending(struct isp_prev_device *prev, const void *rgb2rgb)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_rgbtorgb *rgbrgb = rgb2rgb;
- u32 val;
-
- val = (rgbrgb->matrix[0][0] & 0xfff) << ISPPRV_RGB_MAT1_MTX_RR_SHIFT;
- val |= (rgbrgb->matrix[0][1] & 0xfff) << ISPPRV_RGB_MAT1_MTX_GR_SHIFT;
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT1);
-
- val = (rgbrgb->matrix[0][2] & 0xfff) << ISPPRV_RGB_MAT2_MTX_BR_SHIFT;
- val |= (rgbrgb->matrix[1][0] & 0xfff) << ISPPRV_RGB_MAT2_MTX_RG_SHIFT;
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT2);
-
- val = (rgbrgb->matrix[1][1] & 0xfff) << ISPPRV_RGB_MAT3_MTX_GG_SHIFT;
- val |= (rgbrgb->matrix[1][2] & 0xfff) << ISPPRV_RGB_MAT3_MTX_BG_SHIFT;
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT3);
-
- val = (rgbrgb->matrix[2][0] & 0xfff) << ISPPRV_RGB_MAT4_MTX_RB_SHIFT;
- val |= (rgbrgb->matrix[2][1] & 0xfff) << ISPPRV_RGB_MAT4_MTX_GB_SHIFT;
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT4);
-
- val = (rgbrgb->matrix[2][2] & 0xfff) << ISPPRV_RGB_MAT5_MTX_BB_SHIFT;
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT5);
-
- val = (rgbrgb->offset[0] & 0x3ff) << ISPPRV_RGB_OFF1_MTX_OFFR_SHIFT;
- val |= (rgbrgb->offset[1] & 0x3ff) << ISPPRV_RGB_OFF1_MTX_OFFG_SHIFT;
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_OFF1);
-
- val = (rgbrgb->offset[2] & 0x3ff) << ISPPRV_RGB_OFF2_MTX_OFFB_SHIFT;
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_OFF2);
-}
-
-/*
- * Configures the color space conversion (RGB toYCbYCr) matrix
- * @prev_csc: Structure containing the RGB to YCbYCr matrix and the
- * YCbCr offset.
- */
-static void
-preview_config_csc(struct isp_prev_device *prev, const void *prev_csc)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_csc *csc = prev_csc;
- u32 val;
-
- val = (csc->matrix[0][0] & 0x3ff) << ISPPRV_CSC0_RY_SHIFT;
- val |= (csc->matrix[0][1] & 0x3ff) << ISPPRV_CSC0_GY_SHIFT;
- val |= (csc->matrix[0][2] & 0x3ff) << ISPPRV_CSC0_BY_SHIFT;
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC0);
-
- val = (csc->matrix[1][0] & 0x3ff) << ISPPRV_CSC1_RCB_SHIFT;
- val |= (csc->matrix[1][1] & 0x3ff) << ISPPRV_CSC1_GCB_SHIFT;
- val |= (csc->matrix[1][2] & 0x3ff) << ISPPRV_CSC1_BCB_SHIFT;
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC1);
-
- val = (csc->matrix[2][0] & 0x3ff) << ISPPRV_CSC2_RCR_SHIFT;
- val |= (csc->matrix[2][1] & 0x3ff) << ISPPRV_CSC2_GCR_SHIFT;
- val |= (csc->matrix[2][2] & 0x3ff) << ISPPRV_CSC2_BCR_SHIFT;
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC2);
-
- val = (csc->offset[0] & 0xff) << ISPPRV_CSC_OFFSET_Y_SHIFT;
- val |= (csc->offset[1] & 0xff) << ISPPRV_CSC_OFFSET_CB_SHIFT;
- val |= (csc->offset[2] & 0xff) << ISPPRV_CSC_OFFSET_CR_SHIFT;
- isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC_OFFSET);
-}
-
-/*
- * preview_update_contrast - Updates the contrast.
- * @contrast: Pointer to hold the current programmed contrast value.
- *
- * Value should be programmed before enabling the module.
- */
-static void
-preview_update_contrast(struct isp_prev_device *prev, u8 contrast)
-{
- struct prev_params *params;
- unsigned long flags;
-
- spin_lock_irqsave(&prev->params.lock, flags);
- params = (prev->params.active & OMAP3ISP_PREV_CONTRAST)
- ? &prev->params.params[0] : &prev->params.params[1];
-
- if (params->contrast != (contrast * ISPPRV_CONTRAST_UNITS)) {
- params->contrast = contrast * ISPPRV_CONTRAST_UNITS;
- params->update |= OMAP3ISP_PREV_CONTRAST;
- }
- spin_unlock_irqrestore(&prev->params.lock, flags);
-}
-
-/*
- * preview_config_contrast - Configures the Contrast.
- * @params: Contrast value (u8 pointer, U8Q0 format).
- *
- * Value should be programmed before enabling the module.
- */
-static void
-preview_config_contrast(struct isp_prev_device *prev, const void *params)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT,
- 0xff << ISPPRV_CNT_BRT_CNT_SHIFT,
- *(u8 *)params << ISPPRV_CNT_BRT_CNT_SHIFT);
-}
-
-/*
- * preview_update_brightness - Updates the brightness in preview module.
- * @brightness: Pointer to hold the current programmed brightness value.
- *
- */
-static void
-preview_update_brightness(struct isp_prev_device *prev, u8 brightness)
-{
- struct prev_params *params;
- unsigned long flags;
-
- spin_lock_irqsave(&prev->params.lock, flags);
- params = (prev->params.active & OMAP3ISP_PREV_BRIGHTNESS)
- ? &prev->params.params[0] : &prev->params.params[1];
-
- if (params->brightness != (brightness * ISPPRV_BRIGHT_UNITS)) {
- params->brightness = brightness * ISPPRV_BRIGHT_UNITS;
- params->update |= OMAP3ISP_PREV_BRIGHTNESS;
- }
- spin_unlock_irqrestore(&prev->params.lock, flags);
-}
-
-/*
- * preview_config_brightness - Configures the brightness.
- * @params: Brightness value (u8 pointer, U8Q0 format).
- */
-static void
-preview_config_brightness(struct isp_prev_device *prev, const void *params)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT,
- 0xff << ISPPRV_CNT_BRT_BRT_SHIFT,
- *(u8 *)params << ISPPRV_CNT_BRT_BRT_SHIFT);
-}
-
-/*
- * preview_config_yc_range - Configures the max and min Y and C values.
- * @yclimit: Structure containing the range of Y and C values.
- */
-static void
-preview_config_yc_range(struct isp_prev_device *prev, const void *yclimit)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_yclimit *yc = yclimit;
-
- isp_reg_writel(isp,
- yc->maxC << ISPPRV_SETUP_YC_MAXC_SHIFT |
- yc->maxY << ISPPRV_SETUP_YC_MAXY_SHIFT |
- yc->minC << ISPPRV_SETUP_YC_MINC_SHIFT |
- yc->minY << ISPPRV_SETUP_YC_MINY_SHIFT,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SETUP_YC);
-}
-
-static u32
-preview_params_lock(struct isp_prev_device *prev, u32 update, bool shadow)
-{
- u32 active = prev->params.active;
-
- if (shadow) {
- /* Mark all shadow parameters we are going to touch as busy. */
- prev->params.params[0].busy |= ~active & update;
- prev->params.params[1].busy |= active & update;
- } else {
- /* Mark all active parameters we are going to touch as busy. */
- update = (prev->params.params[0].update & active)
- | (prev->params.params[1].update & ~active);
-
- prev->params.params[0].busy |= active & update;
- prev->params.params[1].busy |= ~active & update;
- }
-
- return update;
-}
-
-static void
-preview_params_unlock(struct isp_prev_device *prev, u32 update, bool shadow)
-{
- u32 active = prev->params.active;
-
- if (shadow) {
- /* Set the update flag for shadow parameters that have been
- * updated and clear the busy flag for all shadow parameters.
- */
- prev->params.params[0].update |= (~active & update);
- prev->params.params[1].update |= (active & update);
- prev->params.params[0].busy &= active;
- prev->params.params[1].busy &= ~active;
- } else {
- /* Clear the update flag for active parameters that have been
- * applied and the busy flag for all active parameters.
- */
- prev->params.params[0].update &= ~(active & update);
- prev->params.params[1].update &= ~(~active & update);
- prev->params.params[0].busy &= ~active;
- prev->params.params[1].busy &= active;
- }
-}
-
-static void preview_params_switch(struct isp_prev_device *prev)
-{
- u32 to_switch;
-
- /* Switch active parameters with updated shadow parameters when the
- * shadow parameter has been updated and neither the active not the
- * shadow parameter is busy.
- */
- to_switch = (prev->params.params[0].update & ~prev->params.active)
- | (prev->params.params[1].update & prev->params.active);
- to_switch &= ~(prev->params.params[0].busy |
- prev->params.params[1].busy);
- if (to_switch == 0)
- return;
-
- prev->params.active ^= to_switch;
-
- /* Remove the update flag for the shadow copy of parameters we have
- * switched.
- */
- prev->params.params[0].update &= ~(~prev->params.active & to_switch);
- prev->params.params[1].update &= ~(prev->params.active & to_switch);
-}
-
-/* preview parameters update structure */
-struct preview_update {
- void (*config)(struct isp_prev_device *, const void *);
- void (*enable)(struct isp_prev_device *, u8);
- unsigned int param_offset;
- unsigned int param_size;
- unsigned int config_offset;
- bool skip;
-};
-
-/* Keep the array indexed by the OMAP3ISP_PREV_* bit number. */
-static const struct preview_update update_attrs[] = {
- /* OMAP3ISP_PREV_LUMAENH */ {
- preview_config_luma_enhancement,
- preview_enable_luma_enhancement,
- offsetof(struct prev_params, luma),
- FIELD_SIZEOF(struct prev_params, luma),
- offsetof(struct omap3isp_prev_update_config, luma),
- }, /* OMAP3ISP_PREV_INVALAW */ {
- NULL,
- preview_enable_invalaw,
- }, /* OMAP3ISP_PREV_HRZ_MED */ {
- preview_config_hmed,
- preview_enable_hmed,
- offsetof(struct prev_params, hmed),
- FIELD_SIZEOF(struct prev_params, hmed),
- offsetof(struct omap3isp_prev_update_config, hmed),
- }, /* OMAP3ISP_PREV_CFA */ {
- preview_config_cfa,
- NULL,
- offsetof(struct prev_params, cfa),
- FIELD_SIZEOF(struct prev_params, cfa),
- offsetof(struct omap3isp_prev_update_config, cfa),
- }, /* OMAP3ISP_PREV_CHROMA_SUPP */ {
- preview_config_chroma_suppression,
- preview_enable_chroma_suppression,
- offsetof(struct prev_params, csup),
- FIELD_SIZEOF(struct prev_params, csup),
- offsetof(struct omap3isp_prev_update_config, csup),
- }, /* OMAP3ISP_PREV_WB */ {
- preview_config_whitebalance,
- NULL,
- offsetof(struct prev_params, wbal),
- FIELD_SIZEOF(struct prev_params, wbal),
- offsetof(struct omap3isp_prev_update_config, wbal),
- }, /* OMAP3ISP_PREV_BLKADJ */ {
- preview_config_blkadj,
- NULL,
- offsetof(struct prev_params, blkadj),
- FIELD_SIZEOF(struct prev_params, blkadj),
- offsetof(struct omap3isp_prev_update_config, blkadj),
- }, /* OMAP3ISP_PREV_RGB2RGB */ {
- preview_config_rgb_blending,
- NULL,
- offsetof(struct prev_params, rgb2rgb),
- FIELD_SIZEOF(struct prev_params, rgb2rgb),
- offsetof(struct omap3isp_prev_update_config, rgb2rgb),
- }, /* OMAP3ISP_PREV_COLOR_CONV */ {
- preview_config_csc,
- NULL,
- offsetof(struct prev_params, csc),
- FIELD_SIZEOF(struct prev_params, csc),
- offsetof(struct omap3isp_prev_update_config, csc),
- }, /* OMAP3ISP_PREV_YC_LIMIT */ {
- preview_config_yc_range,
- NULL,
- offsetof(struct prev_params, yclimit),
- FIELD_SIZEOF(struct prev_params, yclimit),
- offsetof(struct omap3isp_prev_update_config, yclimit),
- }, /* OMAP3ISP_PREV_DEFECT_COR */ {
- preview_config_dcor,
- preview_enable_dcor,
- offsetof(struct prev_params, dcor),
- FIELD_SIZEOF(struct prev_params, dcor),
- offsetof(struct omap3isp_prev_update_config, dcor),
- }, /* OMAP3ISP_PREV_GAMMABYPASS */ {
- NULL,
- preview_enable_gammabypass,
- }, /* OMAP3ISP_PREV_DRK_FRM_CAPTURE */ {
- NULL,
- preview_enable_drkframe_capture,
- }, /* OMAP3ISP_PREV_DRK_FRM_SUBTRACT */ {
- NULL,
- preview_enable_drkframe,
- }, /* OMAP3ISP_PREV_LENS_SHADING */ {
- preview_config_drkf_shadcomp,
- preview_enable_drkframe,
- }, /* OMAP3ISP_PREV_NF */ {
- preview_config_noisefilter,
- preview_enable_noisefilter,
- offsetof(struct prev_params, nf),
- FIELD_SIZEOF(struct prev_params, nf),
- offsetof(struct omap3isp_prev_update_config, nf),
- }, /* OMAP3ISP_PREV_GAMMA */ {
- preview_config_gammacorrn,
- NULL,
- offsetof(struct prev_params, gamma),
- FIELD_SIZEOF(struct prev_params, gamma),
- offsetof(struct omap3isp_prev_update_config, gamma),
- }, /* OMAP3ISP_PREV_CONTRAST */ {
- preview_config_contrast,
- NULL,
- offsetof(struct prev_params, contrast),
- 0, 0, true,
- }, /* OMAP3ISP_PREV_BRIGHTNESS */ {
- preview_config_brightness,
- NULL,
- offsetof(struct prev_params, brightness),
- 0, 0, true,
- },
-};
-
-/*
- * preview_config - Copy and update local structure with userspace preview
- * configuration.
- * @prev: ISP preview engine
- * @cfg: Configuration
- *
- * Return zero if success or -EFAULT if the configuration can't be copied from
- * userspace.
- */
-static int preview_config(struct isp_prev_device *prev,
- struct omap3isp_prev_update_config *cfg)
-{
- unsigned long flags;
- unsigned int i;
- int rval = 0;
- u32 update;
- u32 active;
-
- if (cfg->update == 0)
- return 0;
-
- /* Mark the shadow parameters we're going to update as busy. */
- spin_lock_irqsave(&prev->params.lock, flags);
- preview_params_lock(prev, cfg->update, true);
- active = prev->params.active;
- spin_unlock_irqrestore(&prev->params.lock, flags);
-
- update = 0;
-
- for (i = 0; i < ARRAY_SIZE(update_attrs); i++) {
- const struct preview_update *attr = &update_attrs[i];
- struct prev_params *params;
- unsigned int bit = 1 << i;
-
- if (attr->skip || !(cfg->update & bit))
- continue;
-
- params = &prev->params.params[!!(active & bit)];
-
- if (cfg->flag & bit) {
- void __user *from = *(void * __user *)
- ((void *)cfg + attr->config_offset);
- void *to = (void *)params + attr->param_offset;
- size_t size = attr->param_size;
-
- if (to && from && size) {
- if (copy_from_user(to, from, size)) {
- rval = -EFAULT;
- break;
- }
- }
- params->features |= bit;
- } else {
- params->features &= ~bit;
- }
-
- update |= bit;
- }
-
- spin_lock_irqsave(&prev->params.lock, flags);
- preview_params_unlock(prev, update, true);
- preview_params_switch(prev);
- spin_unlock_irqrestore(&prev->params.lock, flags);
-
- return rval;
-}
-
-/*
- * preview_setup_hw - Setup preview registers and/or internal memory
- * @prev: pointer to preview private structure
- * @update: Bitmask of parameters to setup
- * @active: Bitmask of parameters active in set 0
- * Note: can be called from interrupt context
- * Return none
- */
-static void preview_setup_hw(struct isp_prev_device *prev, u32 update,
- u32 active)
-{
- unsigned int i;
- u32 features;
-
- if (update == 0)
- return;
-
- features = (prev->params.params[0].features & active)
- | (prev->params.params[1].features & ~active);
-
- for (i = 0; i < ARRAY_SIZE(update_attrs); i++) {
- const struct preview_update *attr = &update_attrs[i];
- struct prev_params *params;
- unsigned int bit = 1 << i;
- void *param_ptr;
-
- if (!(update & bit))
- continue;
-
- params = &prev->params.params[!(active & bit)];
-
- if (params->features & bit) {
- if (attr->config) {
- param_ptr = (void *)params + attr->param_offset;
- attr->config(prev, param_ptr);
- }
- if (attr->enable)
- attr->enable(prev, 1);
- } else {
- if (attr->enable)
- attr->enable(prev, 0);
- }
- }
-}
-
-/*
- * preview_config_ycpos - Configure byte layout of YUV image.
- * @mode: Indicates the required byte layout.
- */
-static void
-preview_config_ycpos(struct isp_prev_device *prev,
- enum v4l2_mbus_pixelcode pixelcode)
-{
- struct isp_device *isp = to_isp_device(prev);
- enum preview_ycpos_mode mode;
-
- switch (pixelcode) {
- case V4L2_MBUS_FMT_YUYV8_1X16:
- mode = YCPOS_CrYCbY;
- break;
- case V4L2_MBUS_FMT_UYVY8_1X16:
- mode = YCPOS_YCrYCb;
- break;
- default:
- return;
- }
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_YCPOS_CrYCbY,
- mode << ISPPRV_PCR_YCPOS_SHIFT);
-}
-
-/*
- * preview_config_averager - Enable / disable / configure averager
- * @average: Average value to be configured.
- */
-static void preview_config_averager(struct isp_prev_device *prev, u8 average)
-{
- struct isp_device *isp = to_isp_device(prev);
- struct prev_params *params;
- int reg = 0;
-
- params = (prev->params.active & OMAP3ISP_PREV_CFA)
- ? &prev->params.params[0] : &prev->params.params[1];
-
- if (params->cfa.format == OMAP3ISP_CFAFMT_BAYER)
- reg = ISPPRV_AVE_EVENDIST_2 << ISPPRV_AVE_EVENDIST_SHIFT |
- ISPPRV_AVE_ODDDIST_2 << ISPPRV_AVE_ODDDIST_SHIFT |
- average;
- else if (params->cfa.format == OMAP3ISP_CFAFMT_RGBFOVEON)
- reg = ISPPRV_AVE_EVENDIST_3 << ISPPRV_AVE_EVENDIST_SHIFT |
- ISPPRV_AVE_ODDDIST_3 << ISPPRV_AVE_ODDDIST_SHIFT |
- average;
- isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_PREV, ISPPRV_AVE);
-}
-
-/*
- * preview_config_input_format - Configure the input format
- * @prev: The preview engine
- * @format: Format on the preview engine sink pad
- *
- * Enable CFA interpolation for Bayer formats and disable it for greyscale
- * formats.
- */
-static void preview_config_input_format(struct isp_prev_device *prev,
- const struct v4l2_mbus_framefmt *format)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- if (format->code != V4L2_MBUS_FMT_Y10_1X10)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_CFAEN);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_CFAEN);
-}
-
-/*
- * preview_config_input_size - Configure the input frame size
- *
- * The preview engine crops several rows and columns internally depending on
- * which processing blocks are enabled. The driver assumes all those blocks are
- * enabled when reporting source pad formats to userspace. If this assumption is
- * not true, rows and columns must be manually cropped at the preview engine
- * input to avoid overflows at the end of lines and frames.
- *
- * See the explanation at the PREV_MARGIN_* definitions for more details.
- */
-static void preview_config_input_size(struct isp_prev_device *prev, u32 active)
-{
- const struct v4l2_mbus_framefmt *format = &prev->formats[PREV_PAD_SINK];
- struct isp_device *isp = to_isp_device(prev);
- unsigned int sph = prev->crop.left;
- unsigned int eph = prev->crop.left + prev->crop.width - 1;
- unsigned int slv = prev->crop.top;
- unsigned int elv = prev->crop.top + prev->crop.height - 1;
- u32 features;
-
- if (format->code != V4L2_MBUS_FMT_Y10_1X10) {
- sph -= 2;
- eph += 2;
- slv -= 2;
- elv += 2;
- }
-
- features = (prev->params.params[0].features & active)
- | (prev->params.params[1].features & ~active);
-
- if (features & (OMAP3ISP_PREV_DEFECT_COR | OMAP3ISP_PREV_NF)) {
- sph -= 2;
- eph += 2;
- slv -= 2;
- elv += 2;
- }
- if (features & OMAP3ISP_PREV_HRZ_MED) {
- sph -= 2;
- eph += 2;
- }
- if (features & (OMAP3ISP_PREV_CHROMA_SUPP | OMAP3ISP_PREV_LUMAENH))
- sph -= 2;
-
- isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_HORZ_INFO);
- isp_reg_writel(isp, (slv << ISPPRV_VERT_INFO_SLV_SHIFT) | elv,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_VERT_INFO);
-}
-
-/*
- * preview_config_inlineoffset - Configures the Read address line offset.
- * @prev: Preview module
- * @offset: Line offset
- *
- * According to the TRM, the line offset must be aligned on a 32 bytes boundary.
- * However, a hardware bug requires the memory start address to be aligned on a
- * 64 bytes boundary, so the offset probably should be aligned on 64 bytes as
- * well.
- */
-static void
-preview_config_inlineoffset(struct isp_prev_device *prev, u32 offset)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- isp_reg_writel(isp, offset & 0xffff, OMAP3_ISP_IOMEM_PREV,
- ISPPRV_RADR_OFFSET);
-}
-
-/*
- * preview_set_inaddr - Sets memory address of input frame.
- * @addr: 32bit memory address aligned on 32byte boundary.
- *
- * Configures the memory address from which the input frame is to be read.
- */
-static void preview_set_inaddr(struct isp_prev_device *prev, u32 addr)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_PREV, ISPPRV_RSDR_ADDR);
-}
-
-/*
- * preview_config_outlineoffset - Configures the Write address line offset.
- * @offset: Line Offset for the preview output.
- *
- * The offset must be a multiple of 32 bytes.
- */
-static void preview_config_outlineoffset(struct isp_prev_device *prev,
- u32 offset)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- isp_reg_writel(isp, offset & 0xffff, OMAP3_ISP_IOMEM_PREV,
- ISPPRV_WADD_OFFSET);
-}
-
-/*
- * preview_set_outaddr - Sets the memory address to store output frame
- * @addr: 32bit memory address aligned on 32byte boundary.
- *
- * Configures the memory address to which the output frame is written.
- */
-static void preview_set_outaddr(struct isp_prev_device *prev, u32 addr)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_PREV, ISPPRV_WSDR_ADDR);
-}
-
-static void preview_adjust_bandwidth(struct isp_prev_device *prev)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(&prev->subdev.entity);
- struct isp_device *isp = to_isp_device(prev);
- const struct v4l2_mbus_framefmt *ifmt = &prev->formats[PREV_PAD_SINK];
- unsigned long l3_ick = pipe->l3_ick;
- struct v4l2_fract *timeperframe;
- unsigned int cycles_per_frame;
- unsigned int requests_per_frame;
- unsigned int cycles_per_request;
- unsigned int minimum;
- unsigned int maximum;
- unsigned int value;
-
- if (prev->input != PREVIEW_INPUT_MEMORY) {
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
- ISPSBL_SDR_REQ_PRV_EXP_MASK);
- return;
- }
-
- /* Compute the minimum number of cycles per request, based on the
- * pipeline maximum data rate. This is an absolute lower bound if we
- * don't want SBL overflows, so round the value up.
- */
- cycles_per_request = div_u64((u64)l3_ick / 2 * 256 + pipe->max_rate - 1,
- pipe->max_rate);
- minimum = DIV_ROUND_UP(cycles_per_request, 32);
-
- /* Compute the maximum number of cycles per request, based on the
- * requested frame rate. This is a soft upper bound to achieve a frame
- * rate equal or higher than the requested value, so round the value
- * down.
- */
- timeperframe = &pipe->max_timeperframe;
-
- requests_per_frame = DIV_ROUND_UP(ifmt->width * 2, 256) * ifmt->height;
- cycles_per_frame = div_u64((u64)l3_ick * timeperframe->numerator,
- timeperframe->denominator);
- cycles_per_request = cycles_per_frame / requests_per_frame;
-
- maximum = cycles_per_request / 32;
-
- value = max(minimum, maximum);
-
- dev_dbg(isp->dev, "%s: cycles per request = %u\n", __func__, value);
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
- ISPSBL_SDR_REQ_PRV_EXP_MASK,
- value << ISPSBL_SDR_REQ_PRV_EXP_SHIFT);
-}
-
-/*
- * omap3isp_preview_busy - Gets busy state of preview module.
- */
-int omap3isp_preview_busy(struct isp_prev_device *prev)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- return isp_reg_readl(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR)
- & ISPPRV_PCR_BUSY;
-}
-
-/*
- * omap3isp_preview_restore_context - Restores the values of preview registers
- */
-void omap3isp_preview_restore_context(struct isp_device *isp)
-{
- struct isp_prev_device *prev = &isp->isp_prev;
- const u32 update = OMAP3ISP_PREV_FEATURES_END - 1;
-
- prev->params.params[0].update = prev->params.active & update;
- prev->params.params[1].update = ~prev->params.active & update;
-
- preview_setup_hw(prev, update, prev->params.active);
-
- prev->params.params[0].update = 0;
- prev->params.params[1].update = 0;
-}
-
-/*
- * preview_print_status - Dump preview module registers to the kernel log
- */
-#define PREV_PRINT_REGISTER(isp, name)\
- dev_dbg(isp->dev, "###PRV " #name "=0x%08x\n", \
- isp_reg_readl(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_##name))
-
-static void preview_print_status(struct isp_prev_device *prev)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- dev_dbg(isp->dev, "-------------Preview Register dump----------\n");
-
- PREV_PRINT_REGISTER(isp, PCR);
- PREV_PRINT_REGISTER(isp, HORZ_INFO);
- PREV_PRINT_REGISTER(isp, VERT_INFO);
- PREV_PRINT_REGISTER(isp, RSDR_ADDR);
- PREV_PRINT_REGISTER(isp, RADR_OFFSET);
- PREV_PRINT_REGISTER(isp, DSDR_ADDR);
- PREV_PRINT_REGISTER(isp, DRKF_OFFSET);
- PREV_PRINT_REGISTER(isp, WSDR_ADDR);
- PREV_PRINT_REGISTER(isp, WADD_OFFSET);
- PREV_PRINT_REGISTER(isp, AVE);
- PREV_PRINT_REGISTER(isp, HMED);
- PREV_PRINT_REGISTER(isp, NF);
- PREV_PRINT_REGISTER(isp, WB_DGAIN);
- PREV_PRINT_REGISTER(isp, WBGAIN);
- PREV_PRINT_REGISTER(isp, WBSEL);
- PREV_PRINT_REGISTER(isp, CFA);
- PREV_PRINT_REGISTER(isp, BLKADJOFF);
- PREV_PRINT_REGISTER(isp, RGB_MAT1);
- PREV_PRINT_REGISTER(isp, RGB_MAT2);
- PREV_PRINT_REGISTER(isp, RGB_MAT3);
- PREV_PRINT_REGISTER(isp, RGB_MAT4);
- PREV_PRINT_REGISTER(isp, RGB_MAT5);
- PREV_PRINT_REGISTER(isp, RGB_OFF1);
- PREV_PRINT_REGISTER(isp, RGB_OFF2);
- PREV_PRINT_REGISTER(isp, CSC0);
- PREV_PRINT_REGISTER(isp, CSC1);
- PREV_PRINT_REGISTER(isp, CSC2);
- PREV_PRINT_REGISTER(isp, CSC_OFFSET);
- PREV_PRINT_REGISTER(isp, CNT_BRT);
- PREV_PRINT_REGISTER(isp, CSUP);
- PREV_PRINT_REGISTER(isp, SETUP_YC);
- PREV_PRINT_REGISTER(isp, SET_TBL_ADDR);
- PREV_PRINT_REGISTER(isp, CDC_THR0);
- PREV_PRINT_REGISTER(isp, CDC_THR1);
- PREV_PRINT_REGISTER(isp, CDC_THR2);
- PREV_PRINT_REGISTER(isp, CDC_THR3);
-
- dev_dbg(isp->dev, "--------------------------------------------\n");
-}
-
-/*
- * preview_init_params - init image processing parameters.
- * @prev: pointer to previewer private structure
- */
-static void preview_init_params(struct isp_prev_device *prev)
-{
- struct prev_params *params;
- unsigned int i;
-
- spin_lock_init(&prev->params.lock);
-
- prev->params.active = ~0;
- prev->params.params[0].busy = 0;
- prev->params.params[0].update = OMAP3ISP_PREV_FEATURES_END - 1;
- prev->params.params[1].busy = 0;
- prev->params.params[1].update = 0;
-
- params = &prev->params.params[0];
-
- /* Init values */
- params->contrast = ISPPRV_CONTRAST_DEF * ISPPRV_CONTRAST_UNITS;
- params->brightness = ISPPRV_BRIGHT_DEF * ISPPRV_BRIGHT_UNITS;
- params->cfa.format = OMAP3ISP_CFAFMT_BAYER;
- memcpy(params->cfa.table, cfa_coef_table,
- sizeof(params->cfa.table));
- params->cfa.gradthrs_horz = FLR_CFA_GRADTHRS_HORZ;
- params->cfa.gradthrs_vert = FLR_CFA_GRADTHRS_VERT;
- params->csup.gain = FLR_CSUP_GAIN;
- params->csup.thres = FLR_CSUP_THRES;
- params->csup.hypf_en = 0;
- memcpy(params->luma.table, luma_enhance_table,
- sizeof(params->luma.table));
- params->nf.spread = FLR_NF_STRGTH;
- memcpy(params->nf.table, noise_filter_table, sizeof(params->nf.table));
- params->dcor.couplet_mode_en = 1;
- for (i = 0; i < OMAP3ISP_PREV_DETECT_CORRECT_CHANNELS; i++)
- params->dcor.detect_correct[i] = DEF_DETECT_CORRECT_VAL;
- memcpy(params->gamma.blue, gamma_table, sizeof(params->gamma.blue));
- memcpy(params->gamma.green, gamma_table, sizeof(params->gamma.green));
- memcpy(params->gamma.red, gamma_table, sizeof(params->gamma.red));
- params->wbal.dgain = FLR_WBAL_DGAIN;
- params->wbal.coef0 = FLR_WBAL_COEF;
- params->wbal.coef1 = FLR_WBAL_COEF;
- params->wbal.coef2 = FLR_WBAL_COEF;
- params->wbal.coef3 = FLR_WBAL_COEF;
- params->blkadj.red = FLR_BLKADJ_RED;
- params->blkadj.green = FLR_BLKADJ_GREEN;
- params->blkadj.blue = FLR_BLKADJ_BLUE;
- params->rgb2rgb = flr_rgb2rgb;
- params->csc = flr_prev_csc;
- params->yclimit.minC = ISPPRV_YC_MIN;
- params->yclimit.maxC = ISPPRV_YC_MAX;
- params->yclimit.minY = ISPPRV_YC_MIN;
- params->yclimit.maxY = ISPPRV_YC_MAX;
-
- params->features = OMAP3ISP_PREV_CFA | OMAP3ISP_PREV_DEFECT_COR
- | OMAP3ISP_PREV_NF | OMAP3ISP_PREV_GAMMA
- | OMAP3ISP_PREV_BLKADJ | OMAP3ISP_PREV_YC_LIMIT
- | OMAP3ISP_PREV_RGB2RGB | OMAP3ISP_PREV_COLOR_CONV
- | OMAP3ISP_PREV_WB | OMAP3ISP_PREV_BRIGHTNESS
- | OMAP3ISP_PREV_CONTRAST;
-}
-
-/*
- * preview_max_out_width - Handle previewer hardware ouput limitations
- * @isp_revision : ISP revision
- * returns maximum width output for current isp revision
- */
-static unsigned int preview_max_out_width(struct isp_prev_device *prev)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- switch (isp->revision) {
- case ISP_REVISION_1_0:
- return PREV_MAX_OUT_WIDTH_REV_1;
-
- case ISP_REVISION_2_0:
- default:
- return PREV_MAX_OUT_WIDTH_REV_2;
-
- case ISP_REVISION_15_0:
- return PREV_MAX_OUT_WIDTH_REV_15;
- }
-}
-
-static void preview_configure(struct isp_prev_device *prev)
-{
- struct isp_device *isp = to_isp_device(prev);
- struct v4l2_mbus_framefmt *format;
- unsigned long flags;
- u32 update;
- u32 active;
-
- spin_lock_irqsave(&prev->params.lock, flags);
- /* Mark all active parameters we are going to touch as busy. */
- update = preview_params_lock(prev, 0, false);
- active = prev->params.active;
- spin_unlock_irqrestore(&prev->params.lock, flags);
-
- preview_setup_hw(prev, update, active);
-
- if (prev->output & PREVIEW_OUTPUT_MEMORY)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_SDRPORT);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_SDRPORT);
-
- if (prev->output & PREVIEW_OUTPUT_RESIZER)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_RSZPORT);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_RSZPORT);
-
- /* PREV_PAD_SINK */
- format = &prev->formats[PREV_PAD_SINK];
-
- preview_adjust_bandwidth(prev);
-
- preview_config_input_format(prev, format);
- preview_config_input_size(prev, active);
-
- if (prev->input == PREVIEW_INPUT_CCDC)
- preview_config_inlineoffset(prev, 0);
- else
- preview_config_inlineoffset(prev,
- ALIGN(format->width, 0x20) * 2);
-
- /* PREV_PAD_SOURCE */
- format = &prev->formats[PREV_PAD_SOURCE];
-
- if (prev->output & PREVIEW_OUTPUT_MEMORY)
- preview_config_outlineoffset(prev,
- ALIGN(format->width, 0x10) * 2);
-
- preview_config_averager(prev, 0);
- preview_config_ycpos(prev, format->code);
-
- spin_lock_irqsave(&prev->params.lock, flags);
- preview_params_unlock(prev, update, false);
- spin_unlock_irqrestore(&prev->params.lock, flags);
-}
-
-/* -----------------------------------------------------------------------------
- * Interrupt handling
- */
-
-static void preview_enable_oneshot(struct isp_prev_device *prev)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- /* The PCR.SOURCE bit is automatically reset to 0 when the PCR.ENABLE
- * bit is set. As the preview engine is used in single-shot mode, we
- * need to set PCR.SOURCE before enabling the preview engine.
- */
- if (prev->input == PREVIEW_INPUT_MEMORY)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_SOURCE);
-
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_EN | ISPPRV_PCR_ONESHOT);
-}
-
-void omap3isp_preview_isr_frame_sync(struct isp_prev_device *prev)
-{
- /*
- * If ISP_VIDEO_DMAQUEUE_QUEUED is set, DMA queue had an underrun
- * condition, the module was paused and now we have a buffer queued
- * on the output again. Restart the pipeline if running in continuous
- * mode.
- */
- if (prev->state == ISP_PIPELINE_STREAM_CONTINUOUS &&
- prev->video_out.dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED) {
- preview_enable_oneshot(prev);
- isp_video_dmaqueue_flags_clr(&prev->video_out);
- }
-}
-
-static void preview_isr_buffer(struct isp_prev_device *prev)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(&prev->subdev.entity);
- struct isp_buffer *buffer;
- int restart = 0;
-
- if (prev->input == PREVIEW_INPUT_MEMORY) {
- buffer = omap3isp_video_buffer_next(&prev->video_in);
- if (buffer != NULL)
- preview_set_inaddr(prev, buffer->isp_addr);
- pipe->state |= ISP_PIPELINE_IDLE_INPUT;
- }
-
- if (prev->output & PREVIEW_OUTPUT_MEMORY) {
- buffer = omap3isp_video_buffer_next(&prev->video_out);
- if (buffer != NULL) {
- preview_set_outaddr(prev, buffer->isp_addr);
- restart = 1;
- }
- pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
- }
-
- switch (prev->state) {
- case ISP_PIPELINE_STREAM_SINGLESHOT:
- if (isp_pipeline_ready(pipe))
- omap3isp_pipeline_set_stream(pipe,
- ISP_PIPELINE_STREAM_SINGLESHOT);
- break;
-
- case ISP_PIPELINE_STREAM_CONTINUOUS:
- /* If an underrun occurs, the video queue operation handler will
- * restart the preview engine. Otherwise restart it immediately.
- */
- if (restart)
- preview_enable_oneshot(prev);
- break;
-
- case ISP_PIPELINE_STREAM_STOPPED:
- default:
- return;
- }
-}
-
-/*
- * omap3isp_preview_isr - ISP preview engine interrupt handler
- *
- * Manage the preview engine video buffers and configure shadowed registers.
- */
-void omap3isp_preview_isr(struct isp_prev_device *prev)
-{
- unsigned long flags;
- u32 update;
- u32 active;
-
- if (omap3isp_module_sync_is_stopping(&prev->wait, &prev->stopping))
- return;
-
- spin_lock_irqsave(&prev->params.lock, flags);
- preview_params_switch(prev);
- update = preview_params_lock(prev, 0, false);
- active = prev->params.active;
- spin_unlock_irqrestore(&prev->params.lock, flags);
-
- preview_setup_hw(prev, update, active);
- preview_config_input_size(prev, active);
-
- if (prev->input == PREVIEW_INPUT_MEMORY ||
- prev->output & PREVIEW_OUTPUT_MEMORY)
- preview_isr_buffer(prev);
- else if (prev->state == ISP_PIPELINE_STREAM_CONTINUOUS)
- preview_enable_oneshot(prev);
-
- spin_lock_irqsave(&prev->params.lock, flags);
- preview_params_unlock(prev, update, false);
- spin_unlock_irqrestore(&prev->params.lock, flags);
-}
-
-/* -----------------------------------------------------------------------------
- * ISP video operations
- */
-
-static int preview_video_queue(struct isp_video *video,
- struct isp_buffer *buffer)
-{
- struct isp_prev_device *prev = &video->isp->isp_prev;
-
- if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
- preview_set_inaddr(prev, buffer->isp_addr);
-
- if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- preview_set_outaddr(prev, buffer->isp_addr);
-
- return 0;
-}
-
-static const struct isp_video_operations preview_video_ops = {
- .queue = preview_video_queue,
-};
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev operations
- */
-
-/*
- * preview_s_ctrl - Handle set control subdev method
- * @ctrl: pointer to v4l2 control structure
- */
-static int preview_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct isp_prev_device *prev =
- container_of(ctrl->handler, struct isp_prev_device, ctrls);
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- preview_update_brightness(prev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- preview_update_contrast(prev, ctrl->val);
- break;
- }
-
- return 0;
-}
-
-static const struct v4l2_ctrl_ops preview_ctrl_ops = {
- .s_ctrl = preview_s_ctrl,
-};
-
-/*
- * preview_ioctl - Handle preview module private ioctl's
- * @prev: pointer to preview context structure
- * @cmd: configuration command
- * @arg: configuration argument
- * return -EINVAL or zero on success
- */
-static long preview_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
- struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
-
- switch (cmd) {
- case VIDIOC_OMAP3ISP_PRV_CFG:
- return preview_config(prev, arg);
-
- default:
- return -ENOIOCTLCMD;
- }
-}
-
-/*
- * preview_set_stream - Enable/Disable streaming on preview subdev
- * @sd : pointer to v4l2 subdev structure
- * @enable: 1 == Enable, 0 == Disable
- * return -EINVAL or zero on success
- */
-static int preview_set_stream(struct v4l2_subdev *sd, int enable)
-{
- struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
- struct isp_video *video_out = &prev->video_out;
- struct isp_device *isp = to_isp_device(prev);
- struct device *dev = to_device(prev);
-
- if (prev->state == ISP_PIPELINE_STREAM_STOPPED) {
- if (enable == ISP_PIPELINE_STREAM_STOPPED)
- return 0;
-
- omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_PREVIEW);
- preview_configure(prev);
- atomic_set(&prev->stopping, 0);
- preview_print_status(prev);
- }
-
- switch (enable) {
- case ISP_PIPELINE_STREAM_CONTINUOUS:
- if (prev->output & PREVIEW_OUTPUT_MEMORY)
- omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE);
-
- if (video_out->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED ||
- !(prev->output & PREVIEW_OUTPUT_MEMORY))
- preview_enable_oneshot(prev);
-
- isp_video_dmaqueue_flags_clr(video_out);
- break;
-
- case ISP_PIPELINE_STREAM_SINGLESHOT:
- if (prev->input == PREVIEW_INPUT_MEMORY)
- omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_PREVIEW_READ);
- if (prev->output & PREVIEW_OUTPUT_MEMORY)
- omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE);
-
- preview_enable_oneshot(prev);
- break;
-
- case ISP_PIPELINE_STREAM_STOPPED:
- if (omap3isp_module_sync_idle(&sd->entity, &prev->wait,
- &prev->stopping))
- dev_dbg(dev, "%s: stop timeout.\n", sd->name);
- omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_READ);
- omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE);
- omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_PREVIEW);
- isp_video_dmaqueue_flags_clr(video_out);
- break;
- }
-
- prev->state = enable;
- return 0;
-}
-
-static struct v4l2_mbus_framefmt *
-__preview_get_format(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh,
- unsigned int pad, enum v4l2_subdev_format_whence which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_format(fh, pad);
- else
- return &prev->formats[pad];
-}
-
-static struct v4l2_rect *
-__preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh,
- enum v4l2_subdev_format_whence which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_crop(fh, PREV_PAD_SINK);
- else
- return &prev->crop;
-}
-
-/* previewer format descriptions */
-static const unsigned int preview_input_fmts[] = {
- V4L2_MBUS_FMT_Y10_1X10,
- V4L2_MBUS_FMT_SGRBG10_1X10,
- V4L2_MBUS_FMT_SRGGB10_1X10,
- V4L2_MBUS_FMT_SBGGR10_1X10,
- V4L2_MBUS_FMT_SGBRG10_1X10,
-};
-
-static const unsigned int preview_output_fmts[] = {
- V4L2_MBUS_FMT_UYVY8_1X16,
- V4L2_MBUS_FMT_YUYV8_1X16,
-};
-
-/*
- * preview_try_format - Validate a format
- * @prev: ISP preview engine
- * @fh: V4L2 subdev file handle
- * @pad: pad number
- * @fmt: format to be validated
- * @which: try/active format selector
- *
- * Validate and adjust the given format for the given pad based on the preview
- * engine limits and the format and crop rectangles on other pads.
- */
-static void preview_try_format(struct isp_prev_device *prev,
- struct v4l2_subdev_fh *fh, unsigned int pad,
- struct v4l2_mbus_framefmt *fmt,
- enum v4l2_subdev_format_whence which)
-{
- enum v4l2_mbus_pixelcode pixelcode;
- struct v4l2_rect *crop;
- unsigned int i;
-
- switch (pad) {
- case PREV_PAD_SINK:
- /* When reading data from the CCDC, the input size has already
- * been mangled by the CCDC output pad so it can be accepted
- * as-is.
- *
- * When reading data from memory, clamp the requested width and
- * height. The TRM doesn't specify a minimum input height, make
- * sure we got enough lines to enable the noise filter and color
- * filter array interpolation.
- */
- if (prev->input == PREVIEW_INPUT_MEMORY) {
- fmt->width = clamp_t(u32, fmt->width, PREV_MIN_IN_WIDTH,
- preview_max_out_width(prev));
- fmt->height = clamp_t(u32, fmt->height,
- PREV_MIN_IN_HEIGHT,
- PREV_MAX_IN_HEIGHT);
- }
-
- fmt->colorspace = V4L2_COLORSPACE_SRGB;
-
- for (i = 0; i < ARRAY_SIZE(preview_input_fmts); i++) {
- if (fmt->code == preview_input_fmts[i])
- break;
- }
-
- /* If not found, use SGRBG10 as default */
- if (i >= ARRAY_SIZE(preview_input_fmts))
- fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
- break;
-
- case PREV_PAD_SOURCE:
- pixelcode = fmt->code;
- *fmt = *__preview_get_format(prev, fh, PREV_PAD_SINK, which);
-
- switch (pixelcode) {
- case V4L2_MBUS_FMT_YUYV8_1X16:
- case V4L2_MBUS_FMT_UYVY8_1X16:
- fmt->code = pixelcode;
- break;
-
- default:
- fmt->code = V4L2_MBUS_FMT_YUYV8_1X16;
- break;
- }
-
- /* The preview module output size is configurable through the
- * averager (horizontal scaling by 1/1, 1/2, 1/4 or 1/8). This
- * is not supported yet, hardcode the output size to the crop
- * rectangle size.
- */
- crop = __preview_get_crop(prev, fh, which);
- fmt->width = crop->width;
- fmt->height = crop->height;
-
- fmt->colorspace = V4L2_COLORSPACE_JPEG;
- break;
- }
-
- fmt->field = V4L2_FIELD_NONE;
-}
-
-/*
- * preview_try_crop - Validate a crop rectangle
- * @prev: ISP preview engine
- * @sink: format on the sink pad
- * @crop: crop rectangle to be validated
- *
- * The preview engine crops lines and columns for its internal operation,
- * depending on which filters are enabled. Enforce minimum crop margins to
- * handle that transparently for userspace.
- *
- * See the explanation at the PREV_MARGIN_* definitions for more details.
- */
-static void preview_try_crop(struct isp_prev_device *prev,
- const struct v4l2_mbus_framefmt *sink,
- struct v4l2_rect *crop)
-{
- unsigned int left = PREV_MARGIN_LEFT;
- unsigned int right = sink->width - PREV_MARGIN_RIGHT;
- unsigned int top = PREV_MARGIN_TOP;
- unsigned int bottom = sink->height - PREV_MARGIN_BOTTOM;
-
- /* When processing data on-the-fly from the CCDC, at least 2 pixels must
- * be cropped from the left and right sides of the image. As we don't
- * know which filters will be enabled, increase the left and right
- * margins by two.
- */
- if (prev->input == PREVIEW_INPUT_CCDC) {
- left += 2;
- right -= 2;
- }
-
- /* Restrict left/top to even values to keep the Bayer pattern. */
- crop->left &= ~1;
- crop->top &= ~1;
-
- crop->left = clamp_t(u32, crop->left, left, right - PREV_MIN_OUT_WIDTH);
- crop->top = clamp_t(u32, crop->top, top, bottom - PREV_MIN_OUT_HEIGHT);
- crop->width = clamp_t(u32, crop->width, PREV_MIN_OUT_WIDTH,
- right - crop->left);
- crop->height = clamp_t(u32, crop->height, PREV_MIN_OUT_HEIGHT,
- bottom - crop->top);
-}
-
-/*
- * preview_enum_mbus_code - Handle pixel format enumeration
- * @sd : pointer to v4l2 subdev structure
- * @fh : V4L2 subdev file handle
- * @code : pointer to v4l2_subdev_mbus_code_enum structure
- * return -EINVAL or zero on success
- */
-static int preview_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- switch (code->pad) {
- case PREV_PAD_SINK:
- if (code->index >= ARRAY_SIZE(preview_input_fmts))
- return -EINVAL;
-
- code->code = preview_input_fmts[code->index];
- break;
- case PREV_PAD_SOURCE:
- if (code->index >= ARRAY_SIZE(preview_output_fmts))
- return -EINVAL;
-
- code->code = preview_output_fmts[code->index];
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int preview_enum_frame_size(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_frame_size_enum *fse)
-{
- struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt format;
-
- if (fse->index != 0)
- return -EINVAL;
-
- format.code = fse->code;
- format.width = 1;
- format.height = 1;
- preview_try_format(prev, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
- fse->min_width = format.width;
- fse->min_height = format.height;
-
- if (format.code != fse->code)
- return -EINVAL;
-
- format.code = fse->code;
- format.width = -1;
- format.height = -1;
- preview_try_format(prev, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
- fse->max_width = format.width;
- fse->max_height = format.height;
-
- return 0;
-}
-
-/*
- * preview_get_selection - Retrieve a selection rectangle on a pad
- * @sd: ISP preview V4L2 subdevice
- * @fh: V4L2 subdev file handle
- * @sel: Selection rectangle
- *
- * The only supported rectangles are the crop rectangles on the sink pad.
- *
- * Return 0 on success or a negative error code otherwise.
- */
-static int preview_get_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
-
- if (sel->pad != PREV_PAD_SINK)
- return -EINVAL;
-
- switch (sel->target) {
- case V4L2_SEL_TGT_CROP_BOUNDS:
- sel->r.left = 0;
- sel->r.top = 0;
- sel->r.width = INT_MAX;
- sel->r.height = INT_MAX;
-
- format = __preview_get_format(prev, fh, PREV_PAD_SINK,
- sel->which);
- preview_try_crop(prev, format, &sel->r);
- break;
-
- case V4L2_SEL_TGT_CROP:
- sel->r = *__preview_get_crop(prev, fh, sel->which);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * preview_set_selection - Set a selection rectangle on a pad
- * @sd: ISP preview V4L2 subdevice
- * @fh: V4L2 subdev file handle
- * @sel: Selection rectangle
- *
- * The only supported rectangle is the actual crop rectangle on the sink pad.
- *
- * Return 0 on success or a negative error code otherwise.
- */
-static int preview_set_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
-
- if (sel->target != V4L2_SEL_TGT_CROP ||
- sel->pad != PREV_PAD_SINK)
- return -EINVAL;
-
- /* The crop rectangle can't be changed while streaming. */
- if (prev->state != ISP_PIPELINE_STREAM_STOPPED)
- return -EBUSY;
-
- /* Modifying the crop rectangle always changes the format on the source
- * pad. If the KEEP_CONFIG flag is set, just return the current crop
- * rectangle.
- */
- if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) {
- sel->r = *__preview_get_crop(prev, fh, sel->which);
- return 0;
- }
-
- format = __preview_get_format(prev, fh, PREV_PAD_SINK, sel->which);
- preview_try_crop(prev, format, &sel->r);
- *__preview_get_crop(prev, fh, sel->which) = sel->r;
-
- /* Update the source format. */
- format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, sel->which);
- preview_try_format(prev, fh, PREV_PAD_SOURCE, format, sel->which);
-
- return 0;
-}
-
-/*
- * preview_get_format - Handle get format by pads subdev method
- * @sd : pointer to v4l2 subdev structure
- * @fh : V4L2 subdev file handle
- * @fmt: pointer to v4l2 subdev format structure
- * return -EINVAL or zero on success
- */
-static int preview_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
-
- format = __preview_get_format(prev, fh, fmt->pad, fmt->which);
- if (format == NULL)
- return -EINVAL;
-
- fmt->format = *format;
- return 0;
-}
-
-/*
- * preview_set_format - Handle set format by pads subdev method
- * @sd : pointer to v4l2 subdev structure
- * @fh : V4L2 subdev file handle
- * @fmt: pointer to v4l2 subdev format structure
- * return -EINVAL or zero on success
- */
-static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
- struct v4l2_rect *crop;
-
- format = __preview_get_format(prev, fh, fmt->pad, fmt->which);
- if (format == NULL)
- return -EINVAL;
-
- preview_try_format(prev, fh, fmt->pad, &fmt->format, fmt->which);
- *format = fmt->format;
-
- /* Propagate the format from sink to source */
- if (fmt->pad == PREV_PAD_SINK) {
- /* Reset the crop rectangle. */
- crop = __preview_get_crop(prev, fh, fmt->which);
- crop->left = 0;
- crop->top = 0;
- crop->width = fmt->format.width;
- crop->height = fmt->format.height;
-
- preview_try_crop(prev, &fmt->format, crop);
-
- /* Update the source format. */
- format = __preview_get_format(prev, fh, PREV_PAD_SOURCE,
- fmt->which);
- preview_try_format(prev, fh, PREV_PAD_SOURCE, format,
- fmt->which);
- }
-
- return 0;
-}
-
-/*
- * preview_init_formats - Initialize formats on all pads
- * @sd: ISP preview V4L2 subdevice
- * @fh: V4L2 subdev file handle
- *
- * Initialize all pad formats with default values. If fh is not NULL, try
- * formats are initialized on the file handle. Otherwise active formats are
- * initialized on the device.
- */
-static int preview_init_formats(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh)
-{
- struct v4l2_subdev_format format;
-
- memset(&format, 0, sizeof(format));
- format.pad = PREV_PAD_SINK;
- format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
- format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
- format.format.width = 4096;
- format.format.height = 4096;
- preview_set_format(sd, fh, &format);
-
- return 0;
-}
-
-/* subdev core operations */
-static const struct v4l2_subdev_core_ops preview_v4l2_core_ops = {
- .ioctl = preview_ioctl,
-};
-
-/* subdev video operations */
-static const struct v4l2_subdev_video_ops preview_v4l2_video_ops = {
- .s_stream = preview_set_stream,
-};
-
-/* subdev pad operations */
-static const struct v4l2_subdev_pad_ops preview_v4l2_pad_ops = {
- .enum_mbus_code = preview_enum_mbus_code,
- .enum_frame_size = preview_enum_frame_size,
- .get_fmt = preview_get_format,
- .set_fmt = preview_set_format,
- .get_selection = preview_get_selection,
- .set_selection = preview_set_selection,
-};
-
-/* subdev operations */
-static const struct v4l2_subdev_ops preview_v4l2_ops = {
- .core = &preview_v4l2_core_ops,
- .video = &preview_v4l2_video_ops,
- .pad = &preview_v4l2_pad_ops,
-};
-
-/* subdev internal operations */
-static const struct v4l2_subdev_internal_ops preview_v4l2_internal_ops = {
- .open = preview_init_formats,
-};
-
-/* -----------------------------------------------------------------------------
- * Media entity operations
- */
-
-/*
- * preview_link_setup - Setup previewer connections.
- * @entity : Pointer to media entity structure
- * @local : Pointer to local pad array
- * @remote : Pointer to remote pad array
- * @flags : Link flags
- * return -EINVAL or zero on success
- */
-static int preview_link_setup(struct media_entity *entity,
- const struct media_pad *local,
- const struct media_pad *remote, u32 flags)
-{
- struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
- struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
-
- switch (local->index | media_entity_type(remote->entity)) {
- case PREV_PAD_SINK | MEDIA_ENT_T_DEVNODE:
- /* read from memory */
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (prev->input == PREVIEW_INPUT_CCDC)
- return -EBUSY;
- prev->input = PREVIEW_INPUT_MEMORY;
- } else {
- if (prev->input == PREVIEW_INPUT_MEMORY)
- prev->input = PREVIEW_INPUT_NONE;
- }
- break;
-
- case PREV_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
- /* read from ccdc */
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (prev->input == PREVIEW_INPUT_MEMORY)
- return -EBUSY;
- prev->input = PREVIEW_INPUT_CCDC;
- } else {
- if (prev->input == PREVIEW_INPUT_CCDC)
- prev->input = PREVIEW_INPUT_NONE;
- }
- break;
-
- /*
- * The ISP core doesn't support pipelines with multiple video outputs.
- * Revisit this when it will be implemented, and return -EBUSY for now.
- */
-
- case PREV_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
- /* write to memory */
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (prev->output & ~PREVIEW_OUTPUT_MEMORY)
- return -EBUSY;
- prev->output |= PREVIEW_OUTPUT_MEMORY;
- } else {
- prev->output &= ~PREVIEW_OUTPUT_MEMORY;
- }
- break;
-
- case PREV_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
- /* write to resizer */
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (prev->output & ~PREVIEW_OUTPUT_RESIZER)
- return -EBUSY;
- prev->output |= PREVIEW_OUTPUT_RESIZER;
- } else {
- prev->output &= ~PREVIEW_OUTPUT_RESIZER;
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* media operations */
-static const struct media_entity_operations preview_media_ops = {
- .link_setup = preview_link_setup,
- .link_validate = v4l2_subdev_link_validate,
-};
-
-void omap3isp_preview_unregister_entities(struct isp_prev_device *prev)
-{
- v4l2_device_unregister_subdev(&prev->subdev);
- omap3isp_video_unregister(&prev->video_in);
- omap3isp_video_unregister(&prev->video_out);
-}
-
-int omap3isp_preview_register_entities(struct isp_prev_device *prev,
- struct v4l2_device *vdev)
-{
- int ret;
-
- /* Register the subdev and video nodes. */
- ret = v4l2_device_register_subdev(vdev, &prev->subdev);
- if (ret < 0)
- goto error;
-
- ret = omap3isp_video_register(&prev->video_in, vdev);
- if (ret < 0)
- goto error;
-
- ret = omap3isp_video_register(&prev->video_out, vdev);
- if (ret < 0)
- goto error;
-
- return 0;
-
-error:
- omap3isp_preview_unregister_entities(prev);
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * ISP previewer initialisation and cleanup
- */
-
-/*
- * preview_init_entities - Initialize subdev and media entity.
- * @prev : Pointer to preview structure
- * return -ENOMEM or zero on success
- */
-static int preview_init_entities(struct isp_prev_device *prev)
-{
- struct v4l2_subdev *sd = &prev->subdev;
- struct media_pad *pads = prev->pads;
- struct media_entity *me = &sd->entity;
- int ret;
-
- prev->input = PREVIEW_INPUT_NONE;
-
- v4l2_subdev_init(sd, &preview_v4l2_ops);
- sd->internal_ops = &preview_v4l2_internal_ops;
- strlcpy(sd->name, "OMAP3 ISP preview", sizeof(sd->name));
- sd->grp_id = 1 << 16; /* group ID for isp subdevs */
- v4l2_set_subdevdata(sd, prev);
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- v4l2_ctrl_handler_init(&prev->ctrls, 2);
- v4l2_ctrl_new_std(&prev->ctrls, &preview_ctrl_ops, V4L2_CID_BRIGHTNESS,
- ISPPRV_BRIGHT_LOW, ISPPRV_BRIGHT_HIGH,
- ISPPRV_BRIGHT_STEP, ISPPRV_BRIGHT_DEF);
- v4l2_ctrl_new_std(&prev->ctrls, &preview_ctrl_ops, V4L2_CID_CONTRAST,
- ISPPRV_CONTRAST_LOW, ISPPRV_CONTRAST_HIGH,
- ISPPRV_CONTRAST_STEP, ISPPRV_CONTRAST_DEF);
- v4l2_ctrl_handler_setup(&prev->ctrls);
- sd->ctrl_handler = &prev->ctrls;
-
- pads[PREV_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- pads[PREV_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
-
- me->ops = &preview_media_ops;
- ret = media_entity_init(me, PREV_PADS_NUM, pads, 0);
- if (ret < 0)
- return ret;
-
- preview_init_formats(sd, NULL);
-
- /* According to the OMAP34xx TRM, video buffers need to be aligned on a
- * 32 bytes boundary. However, an undocumented hardware bug requires a
- * 64 bytes boundary at the preview engine input.
- */
- prev->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- prev->video_in.ops = &preview_video_ops;
- prev->video_in.isp = to_isp_device(prev);
- prev->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
- prev->video_in.bpl_alignment = 64;
- prev->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- prev->video_out.ops = &preview_video_ops;
- prev->video_out.isp = to_isp_device(prev);
- prev->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
- prev->video_out.bpl_alignment = 32;
-
- ret = omap3isp_video_init(&prev->video_in, "preview");
- if (ret < 0)
- goto error_video_in;
-
- ret = omap3isp_video_init(&prev->video_out, "preview");
- if (ret < 0)
- goto error_video_out;
-
- /* Connect the video nodes to the previewer subdev. */
- ret = media_entity_create_link(&prev->video_in.video.entity, 0,
- &prev->subdev.entity, PREV_PAD_SINK, 0);
- if (ret < 0)
- goto error_link;
-
- ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
- &prev->video_out.video.entity, 0, 0);
- if (ret < 0)
- goto error_link;
-
- return 0;
-
-error_link:
- omap3isp_video_cleanup(&prev->video_out);
-error_video_out:
- omap3isp_video_cleanup(&prev->video_in);
-error_video_in:
- media_entity_cleanup(&prev->subdev.entity);
- return ret;
-}
-
-/*
- * omap3isp_preview_init - Previewer initialization.
- * @dev : Pointer to ISP device
- * return -ENOMEM or zero on success
- */
-int omap3isp_preview_init(struct isp_device *isp)
-{
- struct isp_prev_device *prev = &isp->isp_prev;
-
- init_waitqueue_head(&prev->wait);
-
- preview_init_params(prev);
-
- return preview_init_entities(prev);
-}
-
-void omap3isp_preview_cleanup(struct isp_device *isp)
-{
- struct isp_prev_device *prev = &isp->isp_prev;
-
- v4l2_ctrl_handler_free(&prev->ctrls);
- omap3isp_video_cleanup(&prev->video_in);
- omap3isp_video_cleanup(&prev->video_out);
- media_entity_cleanup(&prev->subdev.entity);
-}
diff --git a/drivers/media/video/omap3isp/isppreview.h b/drivers/media/video/omap3isp/isppreview.h
deleted file mode 100644
index 6663ab64e4b..00000000000
--- a/drivers/media/video/omap3isp/isppreview.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * isppreview.h
- *
- * TI OMAP3 ISP - Preview module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef OMAP3_ISP_PREVIEW_H
-#define OMAP3_ISP_PREVIEW_H
-
-#include <linux/omap3isp.h>
-#include <linux/types.h>
-#include <media/v4l2-ctrls.h>
-
-#include "ispvideo.h"
-
-#define ISPPRV_BRIGHT_STEP 0x1
-#define ISPPRV_BRIGHT_DEF 0x0
-#define ISPPRV_BRIGHT_LOW 0x0
-#define ISPPRV_BRIGHT_HIGH 0xFF
-#define ISPPRV_BRIGHT_UNITS 0x1
-
-#define ISPPRV_CONTRAST_STEP 0x1
-#define ISPPRV_CONTRAST_DEF 0x10
-#define ISPPRV_CONTRAST_LOW 0x0
-#define ISPPRV_CONTRAST_HIGH 0xFF
-#define ISPPRV_CONTRAST_UNITS 0x1
-
-/* Additional features not listed in linux/omap3isp.h */
-#define OMAP3ISP_PREV_CONTRAST (1 << 17)
-#define OMAP3ISP_PREV_BRIGHTNESS (1 << 18)
-#define OMAP3ISP_PREV_FEATURES_END (1 << 19)
-
-enum preview_input_entity {
- PREVIEW_INPUT_NONE,
- PREVIEW_INPUT_CCDC,
- PREVIEW_INPUT_MEMORY,
-};
-
-#define PREVIEW_OUTPUT_RESIZER (1 << 1)
-#define PREVIEW_OUTPUT_MEMORY (1 << 2)
-
-/* Configure byte layout of YUV image */
-enum preview_ycpos_mode {
- YCPOS_YCrYCb = 0,
- YCPOS_YCbYCr = 1,
- YCPOS_CbYCrY = 2,
- YCPOS_CrYCbY = 3
-};
-
-/*
- * struct prev_params - Structure for all configuration
- * @busy: Bitmask of busy parameters (being updated or used)
- * @update: Bitmask of the parameters to be updated
- * @features: Set of features enabled.
- * @cfa: CFA coefficients.
- * @csup: Chroma suppression coefficients.
- * @luma: Luma enhancement coefficients.
- * @nf: Noise filter coefficients.
- * @dcor: Noise filter coefficients.
- * @gamma: Gamma coefficients.
- * @wbal: White Balance parameters.
- * @blkadj: Black adjustment parameters.
- * @rgb2rgb: RGB blending parameters.
- * @csc: Color space conversion (RGB to YCbCr) parameters.
- * @hmed: Horizontal median filter.
- * @yclimit: YC limits parameters.
- * @contrast: Contrast.
- * @brightness: Brightness.
- */
-struct prev_params {
- u32 busy;
- u32 update;
- u32 features;
- struct omap3isp_prev_cfa cfa;
- struct omap3isp_prev_csup csup;
- struct omap3isp_prev_luma luma;
- struct omap3isp_prev_nf nf;
- struct omap3isp_prev_dcor dcor;
- struct omap3isp_prev_gtables gamma;
- struct omap3isp_prev_wbal wbal;
- struct omap3isp_prev_blkadj blkadj;
- struct omap3isp_prev_rgbtorgb rgb2rgb;
- struct omap3isp_prev_csc csc;
- struct omap3isp_prev_hmed hmed;
- struct omap3isp_prev_yclimit yclimit;
- u8 contrast;
- u8 brightness;
-};
-
-/* Sink and source previewer pads */
-#define PREV_PAD_SINK 0
-#define PREV_PAD_SOURCE 1
-#define PREV_PADS_NUM 2
-
-/*
- * struct isp_prev_device - Structure for storing ISP Preview module information
- * @subdev: V4L2 subdevice
- * @pads: Media entity pads
- * @formats: Active formats at the subdev pad
- * @crop: Active crop rectangle
- * @input: Module currently connected to the input pad
- * @output: Bitmask of the active output
- * @video_in: Input video entity
- * @video_out: Output video entity
- * @params.params : Active and shadow parameters sets
- * @params.active: Bitmask of parameters active in set 0
- * @params.lock: Parameters lock, protects params.active and params.shadow
- * @underrun: Whether the preview entity has queued buffers on the output
- * @state: Current preview pipeline state
- *
- * This structure is used to store the OMAP ISP Preview module Information.
- */
-struct isp_prev_device {
- struct v4l2_subdev subdev;
- struct media_pad pads[PREV_PADS_NUM];
- struct v4l2_mbus_framefmt formats[PREV_PADS_NUM];
- struct v4l2_rect crop;
-
- struct v4l2_ctrl_handler ctrls;
-
- enum preview_input_entity input;
- unsigned int output;
- struct isp_video video_in;
- struct isp_video video_out;
-
- struct {
- struct prev_params params[2];
- u32 active;
- spinlock_t lock;
- } params;
-
- enum isp_pipeline_stream_state state;
- wait_queue_head_t wait;
- atomic_t stopping;
-};
-
-struct isp_device;
-
-int omap3isp_preview_init(struct isp_device *isp);
-void omap3isp_preview_cleanup(struct isp_device *isp);
-
-int omap3isp_preview_register_entities(struct isp_prev_device *prv,
- struct v4l2_device *vdev);
-void omap3isp_preview_unregister_entities(struct isp_prev_device *prv);
-
-void omap3isp_preview_isr_frame_sync(struct isp_prev_device *prev);
-void omap3isp_preview_isr(struct isp_prev_device *prev);
-
-int omap3isp_preview_busy(struct isp_prev_device *isp_prev);
-
-void omap3isp_preview_restore_context(struct isp_device *isp);
-
-#endif /* OMAP3_ISP_PREVIEW_H */
diff --git a/drivers/media/video/omap3isp/ispqueue.c b/drivers/media/video/omap3isp/ispqueue.c
deleted file mode 100644
index 9bebb1e57aa..00000000000
--- a/drivers/media/video/omap3isp/ispqueue.c
+++ /dev/null
@@ -1,1157 +0,0 @@
-/*
- * ispqueue.c
- *
- * TI OMAP3 ISP - Video buffers queue handling
- *
- * Copyright (C) 2010 Nokia Corporation
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <asm/cacheflush.h>
-#include <linux/dma-mapping.h>
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-#include <linux/poll.h>
-#include <linux/scatterlist.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-
-#include "ispqueue.h"
-
-/* -----------------------------------------------------------------------------
- * Video buffers management
- */
-
-/*
- * isp_video_buffer_cache_sync - Keep the buffers coherent between CPU and ISP
- *
- * The typical operation required here is Cache Invalidation across
- * the (user space) buffer address range. And this _must_ be done
- * at QBUF stage (and *only* at QBUF).
- *
- * We try to use optimal cache invalidation function:
- * - dmac_map_area:
- * - used when the number of pages are _low_.
- * - it becomes quite slow as the number of pages increase.
- * - for 648x492 viewfinder (150 pages) it takes 1.3 ms.
- * - for 5 Mpix buffer (2491 pages) it takes between 25-50 ms.
- *
- * - flush_cache_all:
- * - used when the number of pages are _high_.
- * - time taken in the range of 500-900 us.
- * - has a higher penalty but, as whole dcache + icache is invalidated
- */
-/*
- * FIXME: dmac_inv_range crashes randomly on the user space buffer
- * address. Fall back to flush_cache_all for now.
- */
-#define ISP_CACHE_FLUSH_PAGES_MAX 0
-
-static void isp_video_buffer_cache_sync(struct isp_video_buffer *buf)
-{
- if (buf->skip_cache)
- return;
-
- if (buf->vbuf.m.userptr == 0 || buf->npages == 0 ||
- buf->npages > ISP_CACHE_FLUSH_PAGES_MAX)
- flush_cache_all();
- else {
- dmac_map_area((void *)buf->vbuf.m.userptr, buf->vbuf.length,
- DMA_FROM_DEVICE);
- outer_inv_range(buf->vbuf.m.userptr,
- buf->vbuf.m.userptr + buf->vbuf.length);
- }
-}
-
-/*
- * isp_video_buffer_lock_vma - Prevent VMAs from being unmapped
- *
- * Lock the VMAs underlying the given buffer into memory. This avoids the
- * userspace buffer mapping from being swapped out, making VIPT cache handling
- * easier.
- *
- * Note that the pages will not be freed as the buffers have been locked to
- * memory using by a call to get_user_pages(), but the userspace mapping could
- * still disappear if the VMAs are not locked. This is caused by the memory
- * management code trying to be as lock-less as possible, which results in the
- * userspace mapping manager not finding out that the pages are locked under
- * some conditions.
- */
-static int isp_video_buffer_lock_vma(struct isp_video_buffer *buf, int lock)
-{
- struct vm_area_struct *vma;
- unsigned long start;
- unsigned long end;
- int ret = 0;
-
- if (buf->vbuf.memory == V4L2_MEMORY_MMAP)
- return 0;
-
- /* We can be called from workqueue context if the current task dies to
- * unlock the VMAs. In that case there's no current memory management
- * context so unlocking can't be performed, but the VMAs have been or
- * are getting destroyed anyway so it doesn't really matter.
- */
- if (!current || !current->mm)
- return lock ? -EINVAL : 0;
-
- start = buf->vbuf.m.userptr;
- end = buf->vbuf.m.userptr + buf->vbuf.length - 1;
-
- down_write(&current->mm->mmap_sem);
- spin_lock(&current->mm->page_table_lock);
-
- do {
- vma = find_vma(current->mm, start);
- if (vma == NULL) {
- ret = -EFAULT;
- goto out;
- }
-
- if (lock)
- vma->vm_flags |= VM_LOCKED;
- else
- vma->vm_flags &= ~VM_LOCKED;
-
- start = vma->vm_end + 1;
- } while (vma->vm_end < end);
-
- if (lock)
- buf->vm_flags |= VM_LOCKED;
- else
- buf->vm_flags &= ~VM_LOCKED;
-
-out:
- spin_unlock(&current->mm->page_table_lock);
- up_write(&current->mm->mmap_sem);
- return ret;
-}
-
-/*
- * isp_video_buffer_sglist_kernel - Build a scatter list for a vmalloc'ed buffer
- *
- * Iterate over the vmalloc'ed area and create a scatter list entry for every
- * page.
- */
-static int isp_video_buffer_sglist_kernel(struct isp_video_buffer *buf)
-{
- struct scatterlist *sglist;
- unsigned int npages;
- unsigned int i;
- void *addr;
-
- addr = buf->vaddr;
- npages = PAGE_ALIGN(buf->vbuf.length) >> PAGE_SHIFT;
-
- sglist = vmalloc(npages * sizeof(*sglist));
- if (sglist == NULL)
- return -ENOMEM;
-
- sg_init_table(sglist, npages);
-
- for (i = 0; i < npages; ++i, addr += PAGE_SIZE) {
- struct page *page = vmalloc_to_page(addr);
-
- if (page == NULL || PageHighMem(page)) {
- vfree(sglist);
- return -EINVAL;
- }
-
- sg_set_page(&sglist[i], page, PAGE_SIZE, 0);
- }
-
- buf->sglen = npages;
- buf->sglist = sglist;
-
- return 0;
-}
-
-/*
- * isp_video_buffer_sglist_user - Build a scatter list for a userspace buffer
- *
- * Walk the buffer pages list and create a 1:1 mapping to a scatter list.
- */
-static int isp_video_buffer_sglist_user(struct isp_video_buffer *buf)
-{
- struct scatterlist *sglist;
- unsigned int offset = buf->offset;
- unsigned int i;
-
- sglist = vmalloc(buf->npages * sizeof(*sglist));
- if (sglist == NULL)
- return -ENOMEM;
-
- sg_init_table(sglist, buf->npages);
-
- for (i = 0; i < buf->npages; ++i) {
- if (PageHighMem(buf->pages[i])) {
- vfree(sglist);
- return -EINVAL;
- }
-
- sg_set_page(&sglist[i], buf->pages[i], PAGE_SIZE - offset,
- offset);
- offset = 0;
- }
-
- buf->sglen = buf->npages;
- buf->sglist = sglist;
-
- return 0;
-}
-
-/*
- * isp_video_buffer_sglist_pfnmap - Build a scatter list for a VM_PFNMAP buffer
- *
- * Create a scatter list of physically contiguous pages starting at the buffer
- * memory physical address.
- */
-static int isp_video_buffer_sglist_pfnmap(struct isp_video_buffer *buf)
-{
- struct scatterlist *sglist;
- unsigned int offset = buf->offset;
- unsigned long pfn = buf->paddr >> PAGE_SHIFT;
- unsigned int i;
-
- sglist = vmalloc(buf->npages * sizeof(*sglist));
- if (sglist == NULL)
- return -ENOMEM;
-
- sg_init_table(sglist, buf->npages);
-
- for (i = 0; i < buf->npages; ++i, ++pfn) {
- sg_set_page(&sglist[i], pfn_to_page(pfn), PAGE_SIZE - offset,
- offset);
- /* PFNMAP buffers will not get DMA-mapped, set the DMA address
- * manually.
- */
- sg_dma_address(&sglist[i]) = (pfn << PAGE_SHIFT) + offset;
- offset = 0;
- }
-
- buf->sglen = buf->npages;
- buf->sglist = sglist;
-
- return 0;
-}
-
-/*
- * isp_video_buffer_cleanup - Release pages for a userspace VMA.
- *
- * Release pages locked by a call isp_video_buffer_prepare_user and free the
- * pages table.
- */
-static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
-{
- enum dma_data_direction direction;
- unsigned int i;
-
- if (buf->queue->ops->buffer_cleanup)
- buf->queue->ops->buffer_cleanup(buf);
-
- if (!(buf->vm_flags & VM_PFNMAP)) {
- direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
- ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
- dma_unmap_sg(buf->queue->dev, buf->sglist, buf->sglen,
- direction);
- }
-
- vfree(buf->sglist);
- buf->sglist = NULL;
- buf->sglen = 0;
-
- if (buf->pages != NULL) {
- isp_video_buffer_lock_vma(buf, 0);
-
- for (i = 0; i < buf->npages; ++i)
- page_cache_release(buf->pages[i]);
-
- vfree(buf->pages);
- buf->pages = NULL;
- }
-
- buf->npages = 0;
- buf->skip_cache = false;
-}
-
-/*
- * isp_video_buffer_prepare_user - Pin userspace VMA pages to memory.
- *
- * This function creates a list of pages for a userspace VMA. The number of
- * pages is first computed based on the buffer size, and pages are then
- * retrieved by a call to get_user_pages.
- *
- * Pages are pinned to memory by get_user_pages, making them available for DMA
- * transfers. However, due to memory management optimization, it seems the
- * get_user_pages doesn't guarantee that the pinned pages will not be written
- * to swap and removed from the userspace mapping(s). When this happens, a page
- * fault can be generated when accessing those unmapped pages.
- *
- * If the fault is triggered by a page table walk caused by VIPT cache
- * management operations, the page fault handler might oops if the MM semaphore
- * is held, as it can't handle kernel page faults in that case. To fix that, a
- * fixup entry needs to be added to the cache management code, or the userspace
- * VMA must be locked to avoid removing pages from the userspace mapping in the
- * first place.
- *
- * If the number of pages retrieved is smaller than the number required by the
- * buffer size, the function returns -EFAULT.
- */
-static int isp_video_buffer_prepare_user(struct isp_video_buffer *buf)
-{
- unsigned long data;
- unsigned int first;
- unsigned int last;
- int ret;
-
- data = buf->vbuf.m.userptr;
- first = (data & PAGE_MASK) >> PAGE_SHIFT;
- last = ((data + buf->vbuf.length - 1) & PAGE_MASK) >> PAGE_SHIFT;
-
- buf->offset = data & ~PAGE_MASK;
- buf->npages = last - first + 1;
- buf->pages = vmalloc(buf->npages * sizeof(buf->pages[0]));
- if (buf->pages == NULL)
- return -ENOMEM;
-
- down_read(&current->mm->mmap_sem);
- ret = get_user_pages(current, current->mm, data & PAGE_MASK,
- buf->npages,
- buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
- buf->pages, NULL);
- up_read(&current->mm->mmap_sem);
-
- if (ret != buf->npages) {
- buf->npages = ret < 0 ? 0 : ret;
- isp_video_buffer_cleanup(buf);
- return -EFAULT;
- }
-
- ret = isp_video_buffer_lock_vma(buf, 1);
- if (ret < 0)
- isp_video_buffer_cleanup(buf);
-
- return ret;
-}
-
-/*
- * isp_video_buffer_prepare_pfnmap - Validate a VM_PFNMAP userspace buffer
- *
- * Userspace VM_PFNMAP buffers are supported only if they are contiguous in
- * memory and if they span a single VMA.
- *
- * Return 0 if the buffer is valid, or -EFAULT otherwise.
- */
-static int isp_video_buffer_prepare_pfnmap(struct isp_video_buffer *buf)
-{
- struct vm_area_struct *vma;
- unsigned long prev_pfn;
- unsigned long this_pfn;
- unsigned long start;
- unsigned long end;
- dma_addr_t pa;
- int ret = -EFAULT;
-
- start = buf->vbuf.m.userptr;
- end = buf->vbuf.m.userptr + buf->vbuf.length - 1;
-
- buf->offset = start & ~PAGE_MASK;
- buf->npages = (end >> PAGE_SHIFT) - (start >> PAGE_SHIFT) + 1;
- buf->pages = NULL;
-
- down_read(&current->mm->mmap_sem);
- vma = find_vma(current->mm, start);
- if (vma == NULL || vma->vm_end < end)
- goto done;
-
- for (prev_pfn = 0; start <= end; start += PAGE_SIZE) {
- ret = follow_pfn(vma, start, &this_pfn);
- if (ret)
- goto done;
-
- if (prev_pfn == 0)
- pa = this_pfn << PAGE_SHIFT;
- else if (this_pfn != prev_pfn + 1) {
- ret = -EFAULT;
- goto done;
- }
-
- prev_pfn = this_pfn;
- }
-
- buf->paddr = pa + buf->offset;
- ret = 0;
-
-done:
- up_read(&current->mm->mmap_sem);
- return ret;
-}
-
-/*
- * isp_video_buffer_prepare_vm_flags - Get VMA flags for a userspace address
- *
- * This function locates the VMAs for the buffer's userspace address and checks
- * that their flags match. The only flag that we need to care for at the moment
- * is VM_PFNMAP.
- *
- * The buffer vm_flags field is set to the first VMA flags.
- *
- * Return -EFAULT if no VMA can be found for part of the buffer, or if the VMAs
- * have incompatible flags.
- */
-static int isp_video_buffer_prepare_vm_flags(struct isp_video_buffer *buf)
-{
- struct vm_area_struct *vma;
- pgprot_t vm_page_prot;
- unsigned long start;
- unsigned long end;
- int ret = -EFAULT;
-
- start = buf->vbuf.m.userptr;
- end = buf->vbuf.m.userptr + buf->vbuf.length - 1;
-
- down_read(&current->mm->mmap_sem);
-
- do {
- vma = find_vma(current->mm, start);
- if (vma == NULL)
- goto done;
-
- if (start == buf->vbuf.m.userptr) {
- buf->vm_flags = vma->vm_flags;
- vm_page_prot = vma->vm_page_prot;
- }
-
- if ((buf->vm_flags ^ vma->vm_flags) & VM_PFNMAP)
- goto done;
-
- if (vm_page_prot != vma->vm_page_prot)
- goto done;
-
- start = vma->vm_end + 1;
- } while (vma->vm_end < end);
-
- /* Skip cache management to enhance performances for non-cached or
- * write-combining buffers.
- */
- if (vm_page_prot == pgprot_noncached(vm_page_prot) ||
- vm_page_prot == pgprot_writecombine(vm_page_prot))
- buf->skip_cache = true;
-
- ret = 0;
-
-done:
- up_read(&current->mm->mmap_sem);
- return ret;
-}
-
-/*
- * isp_video_buffer_prepare - Make a buffer ready for operation
- *
- * Preparing a buffer involves:
- *
- * - validating VMAs (userspace buffers only)
- * - locking pages and VMAs into memory (userspace buffers only)
- * - building page and scatter-gather lists
- * - mapping buffers for DMA operation
- * - performing driver-specific preparation
- *
- * The function must be called in userspace context with a valid mm context
- * (this excludes cleanup paths such as sys_close when the userspace process
- * segfaults).
- */
-static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
-{
- enum dma_data_direction direction;
- int ret;
-
- switch (buf->vbuf.memory) {
- case V4L2_MEMORY_MMAP:
- ret = isp_video_buffer_sglist_kernel(buf);
- break;
-
- case V4L2_MEMORY_USERPTR:
- ret = isp_video_buffer_prepare_vm_flags(buf);
- if (ret < 0)
- return ret;
-
- if (buf->vm_flags & VM_PFNMAP) {
- ret = isp_video_buffer_prepare_pfnmap(buf);
- if (ret < 0)
- return ret;
-
- ret = isp_video_buffer_sglist_pfnmap(buf);
- } else {
- ret = isp_video_buffer_prepare_user(buf);
- if (ret < 0)
- return ret;
-
- ret = isp_video_buffer_sglist_user(buf);
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- if (ret < 0)
- goto done;
-
- if (!(buf->vm_flags & VM_PFNMAP)) {
- direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
- ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
- ret = dma_map_sg(buf->queue->dev, buf->sglist, buf->sglen,
- direction);
- if (ret != buf->sglen) {
- ret = -EFAULT;
- goto done;
- }
- }
-
- if (buf->queue->ops->buffer_prepare)
- ret = buf->queue->ops->buffer_prepare(buf);
-
-done:
- if (ret < 0) {
- isp_video_buffer_cleanup(buf);
- return ret;
- }
-
- return ret;
-}
-
-/*
- * isp_video_queue_query - Query the status of a given buffer
- *
- * Locking: must be called with the queue lock held.
- */
-static void isp_video_buffer_query(struct isp_video_buffer *buf,
- struct v4l2_buffer *vbuf)
-{
- memcpy(vbuf, &buf->vbuf, sizeof(*vbuf));
-
- if (buf->vma_use_count)
- vbuf->flags |= V4L2_BUF_FLAG_MAPPED;
-
- switch (buf->state) {
- case ISP_BUF_STATE_ERROR:
- vbuf->flags |= V4L2_BUF_FLAG_ERROR;
- case ISP_BUF_STATE_DONE:
- vbuf->flags |= V4L2_BUF_FLAG_DONE;
- case ISP_BUF_STATE_QUEUED:
- case ISP_BUF_STATE_ACTIVE:
- vbuf->flags |= V4L2_BUF_FLAG_QUEUED;
- break;
- case ISP_BUF_STATE_IDLE:
- default:
- break;
- }
-}
-
-/*
- * isp_video_buffer_wait - Wait for a buffer to be ready
- *
- * In non-blocking mode, return immediately with 0 if the buffer is ready or
- * -EAGAIN if the buffer is in the QUEUED or ACTIVE state.
- *
- * In blocking mode, wait (interruptibly but with no timeout) on the buffer wait
- * queue using the same condition.
- */
-static int isp_video_buffer_wait(struct isp_video_buffer *buf, int nonblocking)
-{
- if (nonblocking) {
- return (buf->state != ISP_BUF_STATE_QUEUED &&
- buf->state != ISP_BUF_STATE_ACTIVE)
- ? 0 : -EAGAIN;
- }
-
- return wait_event_interruptible(buf->wait,
- buf->state != ISP_BUF_STATE_QUEUED &&
- buf->state != ISP_BUF_STATE_ACTIVE);
-}
-
-/* -----------------------------------------------------------------------------
- * Queue management
- */
-
-/*
- * isp_video_queue_free - Free video buffers memory
- *
- * Buffers can only be freed if the queue isn't streaming and if no buffer is
- * mapped to userspace. Return -EBUSY if those conditions aren't statisfied.
- *
- * This function must be called with the queue lock held.
- */
-static int isp_video_queue_free(struct isp_video_queue *queue)
-{
- unsigned int i;
-
- if (queue->streaming)
- return -EBUSY;
-
- for (i = 0; i < queue->count; ++i) {
- if (queue->buffers[i]->vma_use_count != 0)
- return -EBUSY;
- }
-
- for (i = 0; i < queue->count; ++i) {
- struct isp_video_buffer *buf = queue->buffers[i];
-
- isp_video_buffer_cleanup(buf);
-
- vfree(buf->vaddr);
- buf->vaddr = NULL;
-
- kfree(buf);
- queue->buffers[i] = NULL;
- }
-
- INIT_LIST_HEAD(&queue->queue);
- queue->count = 0;
- return 0;
-}
-
-/*
- * isp_video_queue_alloc - Allocate video buffers memory
- *
- * This function must be called with the queue lock held.
- */
-static int isp_video_queue_alloc(struct isp_video_queue *queue,
- unsigned int nbuffers,
- unsigned int size, enum v4l2_memory memory)
-{
- struct isp_video_buffer *buf;
- unsigned int i;
- void *mem;
- int ret;
-
- /* Start by freeing the buffers. */
- ret = isp_video_queue_free(queue);
- if (ret < 0)
- return ret;
-
- /* Bail out of no buffers should be allocated. */
- if (nbuffers == 0)
- return 0;
-
- /* Initialize the allocated buffers. */
- for (i = 0; i < nbuffers; ++i) {
- buf = kzalloc(queue->bufsize, GFP_KERNEL);
- if (buf == NULL)
- break;
-
- if (memory == V4L2_MEMORY_MMAP) {
- /* Allocate video buffers memory for mmap mode. Align
- * the size to the page size.
- */
- mem = vmalloc_32_user(PAGE_ALIGN(size));
- if (mem == NULL) {
- kfree(buf);
- break;
- }
-
- buf->vbuf.m.offset = i * PAGE_ALIGN(size);
- buf->vaddr = mem;
- }
-
- buf->vbuf.index = i;
- buf->vbuf.length = size;
- buf->vbuf.type = queue->type;
- buf->vbuf.field = V4L2_FIELD_NONE;
- buf->vbuf.memory = memory;
-
- buf->queue = queue;
- init_waitqueue_head(&buf->wait);
-
- queue->buffers[i] = buf;
- }
-
- if (i == 0)
- return -ENOMEM;
-
- queue->count = i;
- return nbuffers;
-}
-
-/**
- * omap3isp_video_queue_cleanup - Clean up the video buffers queue
- * @queue: Video buffers queue
- *
- * Free all allocated resources and clean up the video buffers queue. The queue
- * must not be busy (no ongoing video stream) and buffers must have been
- * unmapped.
- *
- * Return 0 on success or -EBUSY if the queue is busy or buffers haven't been
- * unmapped.
- */
-int omap3isp_video_queue_cleanup(struct isp_video_queue *queue)
-{
- return isp_video_queue_free(queue);
-}
-
-/**
- * omap3isp_video_queue_init - Initialize the video buffers queue
- * @queue: Video buffers queue
- * @type: V4L2 buffer type (capture or output)
- * @ops: Driver-specific queue operations
- * @dev: Device used for DMA operations
- * @bufsize: Size of the driver-specific buffer structure
- *
- * Initialize the video buffers queue with the supplied parameters.
- *
- * The queue type must be one of V4L2_BUF_TYPE_VIDEO_CAPTURE or
- * V4L2_BUF_TYPE_VIDEO_OUTPUT. Other buffer types are not supported yet.
- *
- * Buffer objects will be allocated using the given buffer size to allow room
- * for driver-specific fields. Driver-specific buffer structures must start
- * with a struct isp_video_buffer field. Drivers with no driver-specific buffer
- * structure must pass the size of the isp_video_buffer structure in the bufsize
- * parameter.
- *
- * Return 0 on success.
- */
-int omap3isp_video_queue_init(struct isp_video_queue *queue,
- enum v4l2_buf_type type,
- const struct isp_video_queue_operations *ops,
- struct device *dev, unsigned int bufsize)
-{
- INIT_LIST_HEAD(&queue->queue);
- mutex_init(&queue->lock);
- spin_lock_init(&queue->irqlock);
-
- queue->type = type;
- queue->ops = ops;
- queue->dev = dev;
- queue->bufsize = bufsize;
-
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 operations
- */
-
-/**
- * omap3isp_video_queue_reqbufs - Allocate video buffers memory
- *
- * This function is intended to be used as a VIDIOC_REQBUFS ioctl handler. It
- * allocated video buffer objects and, for MMAP buffers, buffer memory.
- *
- * If the number of buffers is 0, all buffers are freed and the function returns
- * without performing any allocation.
- *
- * If the number of buffers is not 0, currently allocated buffers (if any) are
- * freed and the requested number of buffers are allocated. Depending on
- * driver-specific requirements and on memory availability, a number of buffer
- * smaller or bigger than requested can be allocated. This isn't considered as
- * an error.
- *
- * Return 0 on success or one of the following error codes:
- *
- * -EINVAL if the buffer type or index are invalid
- * -EBUSY if the queue is busy (streaming or buffers mapped)
- * -ENOMEM if the buffers can't be allocated due to an out-of-memory condition
- */
-int omap3isp_video_queue_reqbufs(struct isp_video_queue *queue,
- struct v4l2_requestbuffers *rb)
-{
- unsigned int nbuffers = rb->count;
- unsigned int size;
- int ret;
-
- if (rb->type != queue->type)
- return -EINVAL;
-
- queue->ops->queue_prepare(queue, &nbuffers, &size);
- if (size == 0)
- return -EINVAL;
-
- nbuffers = min_t(unsigned int, nbuffers, ISP_VIDEO_MAX_BUFFERS);
-
- mutex_lock(&queue->lock);
-
- ret = isp_video_queue_alloc(queue, nbuffers, size, rb->memory);
- if (ret < 0)
- goto done;
-
- rb->count = ret;
- ret = 0;
-
-done:
- mutex_unlock(&queue->lock);
- return ret;
-}
-
-/**
- * omap3isp_video_queue_querybuf - Query the status of a buffer in a queue
- *
- * This function is intended to be used as a VIDIOC_QUERYBUF ioctl handler. It
- * returns the status of a given video buffer.
- *
- * Return 0 on success or -EINVAL if the buffer type or index are invalid.
- */
-int omap3isp_video_queue_querybuf(struct isp_video_queue *queue,
- struct v4l2_buffer *vbuf)
-{
- struct isp_video_buffer *buf;
- int ret = 0;
-
- if (vbuf->type != queue->type)
- return -EINVAL;
-
- mutex_lock(&queue->lock);
-
- if (vbuf->index >= queue->count) {
- ret = -EINVAL;
- goto done;
- }
-
- buf = queue->buffers[vbuf->index];
- isp_video_buffer_query(buf, vbuf);
-
-done:
- mutex_unlock(&queue->lock);
- return ret;
-}
-
-/**
- * omap3isp_video_queue_qbuf - Queue a buffer
- *
- * This function is intended to be used as a VIDIOC_QBUF ioctl handler.
- *
- * The v4l2_buffer structure passed from userspace is first sanity tested. If
- * sane, the buffer is then processed and added to the main queue and, if the
- * queue is streaming, to the IRQ queue.
- *
- * Before being enqueued, USERPTR buffers are checked for address changes. If
- * the buffer has a different userspace address, the old memory area is unlocked
- * and the new memory area is locked.
- */
-int omap3isp_video_queue_qbuf(struct isp_video_queue *queue,
- struct v4l2_buffer *vbuf)
-{
- struct isp_video_buffer *buf;
- unsigned long flags;
- int ret = -EINVAL;
-
- if (vbuf->type != queue->type)
- goto done;
-
- mutex_lock(&queue->lock);
-
- if (vbuf->index >= queue->count)
- goto done;
-
- buf = queue->buffers[vbuf->index];
-
- if (vbuf->memory != buf->vbuf.memory)
- goto done;
-
- if (buf->state != ISP_BUF_STATE_IDLE)
- goto done;
-
- if (vbuf->memory == V4L2_MEMORY_USERPTR &&
- vbuf->length < buf->vbuf.length)
- goto done;
-
- if (vbuf->memory == V4L2_MEMORY_USERPTR &&
- vbuf->m.userptr != buf->vbuf.m.userptr) {
- isp_video_buffer_cleanup(buf);
- buf->vbuf.m.userptr = vbuf->m.userptr;
- buf->prepared = 0;
- }
-
- if (!buf->prepared) {
- ret = isp_video_buffer_prepare(buf);
- if (ret < 0)
- goto done;
- buf->prepared = 1;
- }
-
- isp_video_buffer_cache_sync(buf);
-
- buf->state = ISP_BUF_STATE_QUEUED;
- list_add_tail(&buf->stream, &queue->queue);
-
- if (queue->streaming) {
- spin_lock_irqsave(&queue->irqlock, flags);
- queue->ops->buffer_queue(buf);
- spin_unlock_irqrestore(&queue->irqlock, flags);
- }
-
- ret = 0;
-
-done:
- mutex_unlock(&queue->lock);
- return ret;
-}
-
-/**
- * omap3isp_video_queue_dqbuf - Dequeue a buffer
- *
- * This function is intended to be used as a VIDIOC_DQBUF ioctl handler.
- *
- * The v4l2_buffer structure passed from userspace is first sanity tested. If
- * sane, the buffer is then processed and added to the main queue and, if the
- * queue is streaming, to the IRQ queue.
- *
- * Before being enqueued, USERPTR buffers are checked for address changes. If
- * the buffer has a different userspace address, the old memory area is unlocked
- * and the new memory area is locked.
- */
-int omap3isp_video_queue_dqbuf(struct isp_video_queue *queue,
- struct v4l2_buffer *vbuf, int nonblocking)
-{
- struct isp_video_buffer *buf;
- int ret;
-
- if (vbuf->type != queue->type)
- return -EINVAL;
-
- mutex_lock(&queue->lock);
-
- if (list_empty(&queue->queue)) {
- ret = -EINVAL;
- goto done;
- }
-
- buf = list_first_entry(&queue->queue, struct isp_video_buffer, stream);
- ret = isp_video_buffer_wait(buf, nonblocking);
- if (ret < 0)
- goto done;
-
- list_del(&buf->stream);
-
- isp_video_buffer_query(buf, vbuf);
- buf->state = ISP_BUF_STATE_IDLE;
- vbuf->flags &= ~V4L2_BUF_FLAG_QUEUED;
-
-done:
- mutex_unlock(&queue->lock);
- return ret;
-}
-
-/**
- * omap3isp_video_queue_streamon - Start streaming
- *
- * This function is intended to be used as a VIDIOC_STREAMON ioctl handler. It
- * starts streaming on the queue and calls the buffer_queue operation for all
- * queued buffers.
- *
- * Return 0 on success.
- */
-int omap3isp_video_queue_streamon(struct isp_video_queue *queue)
-{
- struct isp_video_buffer *buf;
- unsigned long flags;
-
- mutex_lock(&queue->lock);
-
- if (queue->streaming)
- goto done;
-
- queue->streaming = 1;
-
- spin_lock_irqsave(&queue->irqlock, flags);
- list_for_each_entry(buf, &queue->queue, stream)
- queue->ops->buffer_queue(buf);
- spin_unlock_irqrestore(&queue->irqlock, flags);
-
-done:
- mutex_unlock(&queue->lock);
- return 0;
-}
-
-/**
- * omap3isp_video_queue_streamoff - Stop streaming
- *
- * This function is intended to be used as a VIDIOC_STREAMOFF ioctl handler. It
- * stops streaming on the queue and wakes up all the buffers.
- *
- * Drivers must stop the hardware and synchronize with interrupt handlers and/or
- * delayed works before calling this function to make sure no buffer will be
- * touched by the driver and/or hardware.
- */
-void omap3isp_video_queue_streamoff(struct isp_video_queue *queue)
-{
- struct isp_video_buffer *buf;
- unsigned long flags;
- unsigned int i;
-
- mutex_lock(&queue->lock);
-
- if (!queue->streaming)
- goto done;
-
- queue->streaming = 0;
-
- spin_lock_irqsave(&queue->irqlock, flags);
- for (i = 0; i < queue->count; ++i) {
- buf = queue->buffers[i];
-
- if (buf->state == ISP_BUF_STATE_ACTIVE)
- wake_up(&buf->wait);
-
- buf->state = ISP_BUF_STATE_IDLE;
- }
- spin_unlock_irqrestore(&queue->irqlock, flags);
-
- INIT_LIST_HEAD(&queue->queue);
-
-done:
- mutex_unlock(&queue->lock);
-}
-
-/**
- * omap3isp_video_queue_discard_done - Discard all buffers marked as DONE
- *
- * This function is intended to be used with suspend/resume operations. It
- * discards all 'done' buffers as they would be too old to be requested after
- * resume.
- *
- * Drivers must stop the hardware and synchronize with interrupt handlers and/or
- * delayed works before calling this function to make sure no buffer will be
- * touched by the driver and/or hardware.
- */
-void omap3isp_video_queue_discard_done(struct isp_video_queue *queue)
-{
- struct isp_video_buffer *buf;
- unsigned int i;
-
- mutex_lock(&queue->lock);
-
- if (!queue->streaming)
- goto done;
-
- for (i = 0; i < queue->count; ++i) {
- buf = queue->buffers[i];
-
- if (buf->state == ISP_BUF_STATE_DONE)
- buf->state = ISP_BUF_STATE_ERROR;
- }
-
-done:
- mutex_unlock(&queue->lock);
-}
-
-static void isp_video_queue_vm_open(struct vm_area_struct *vma)
-{
- struct isp_video_buffer *buf = vma->vm_private_data;
-
- buf->vma_use_count++;
-}
-
-static void isp_video_queue_vm_close(struct vm_area_struct *vma)
-{
- struct isp_video_buffer *buf = vma->vm_private_data;
-
- buf->vma_use_count--;
-}
-
-static const struct vm_operations_struct isp_video_queue_vm_ops = {
- .open = isp_video_queue_vm_open,
- .close = isp_video_queue_vm_close,
-};
-
-/**
- * omap3isp_video_queue_mmap - Map buffers to userspace
- *
- * This function is intended to be used as an mmap() file operation handler. It
- * maps a buffer to userspace based on the VMA offset.
- *
- * Only buffers of memory type MMAP are supported.
- */
-int omap3isp_video_queue_mmap(struct isp_video_queue *queue,
- struct vm_area_struct *vma)
-{
- struct isp_video_buffer *uninitialized_var(buf);
- unsigned long size;
- unsigned int i;
- int ret = 0;
-
- mutex_lock(&queue->lock);
-
- for (i = 0; i < queue->count; ++i) {
- buf = queue->buffers[i];
- if ((buf->vbuf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
- break;
- }
-
- if (i == queue->count) {
- ret = -EINVAL;
- goto done;
- }
-
- size = vma->vm_end - vma->vm_start;
-
- if (buf->vbuf.memory != V4L2_MEMORY_MMAP ||
- size != PAGE_ALIGN(buf->vbuf.length)) {
- ret = -EINVAL;
- goto done;
- }
-
- ret = remap_vmalloc_range(vma, buf->vaddr, 0);
- if (ret < 0)
- goto done;
-
- vma->vm_ops = &isp_video_queue_vm_ops;
- vma->vm_private_data = buf;
- isp_video_queue_vm_open(vma);
-
-done:
- mutex_unlock(&queue->lock);
- return ret;
-}
-
-/**
- * omap3isp_video_queue_poll - Poll video queue state
- *
- * This function is intended to be used as a poll() file operation handler. It
- * polls the state of the video buffer at the front of the queue and returns an
- * events mask.
- *
- * If no buffer is present at the front of the queue, POLLERR is returned.
- */
-unsigned int omap3isp_video_queue_poll(struct isp_video_queue *queue,
- struct file *file, poll_table *wait)
-{
- struct isp_video_buffer *buf;
- unsigned int mask = 0;
-
- mutex_lock(&queue->lock);
- if (list_empty(&queue->queue)) {
- mask |= POLLERR;
- goto done;
- }
- buf = list_first_entry(&queue->queue, struct isp_video_buffer, stream);
-
- poll_wait(file, &buf->wait, wait);
- if (buf->state == ISP_BUF_STATE_DONE ||
- buf->state == ISP_BUF_STATE_ERROR) {
- if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- mask |= POLLIN | POLLRDNORM;
- else
- mask |= POLLOUT | POLLWRNORM;
- }
-
-done:
- mutex_unlock(&queue->lock);
- return mask;
-}
diff --git a/drivers/media/video/omap3isp/ispqueue.h b/drivers/media/video/omap3isp/ispqueue.h
deleted file mode 100644
index 908dfd712e8..00000000000
--- a/drivers/media/video/omap3isp/ispqueue.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * ispqueue.h
- *
- * TI OMAP3 ISP - Video buffers queue handling
- *
- * Copyright (C) 2010 Nokia Corporation
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef OMAP3_ISP_QUEUE_H
-#define OMAP3_ISP_QUEUE_H
-
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/videodev2.h>
-#include <linux/wait.h>
-
-struct isp_video_queue;
-struct page;
-struct scatterlist;
-
-#define ISP_VIDEO_MAX_BUFFERS 16
-
-/**
- * enum isp_video_buffer_state - ISP video buffer state
- * @ISP_BUF_STATE_IDLE: The buffer is under userspace control (dequeued
- * or not queued yet).
- * @ISP_BUF_STATE_QUEUED: The buffer has been queued but isn't used by the
- * device yet.
- * @ISP_BUF_STATE_ACTIVE: The buffer is in use for an active video transfer.
- * @ISP_BUF_STATE_ERROR: The device is done with the buffer and an error
- * occurred. For capture device the buffer likely contains corrupted data or
- * no data at all.
- * @ISP_BUF_STATE_DONE: The device is done with the buffer and no error occurred.
- * For capture devices the buffer contains valid data.
- */
-enum isp_video_buffer_state {
- ISP_BUF_STATE_IDLE,
- ISP_BUF_STATE_QUEUED,
- ISP_BUF_STATE_ACTIVE,
- ISP_BUF_STATE_ERROR,
- ISP_BUF_STATE_DONE,
-};
-
-/**
- * struct isp_video_buffer - ISP video buffer
- * @vma_use_count: Number of times the buffer is mmap'ed to userspace
- * @stream: List head for insertion into main queue
- * @queue: ISP buffers queue this buffer belongs to
- * @prepared: Whether the buffer has been prepared
- * @skip_cache: Whether to skip cache management operations for this buffer
- * @vaddr: Memory virtual address (for kernel buffers)
- * @vm_flags: Buffer VMA flags (for userspace buffers)
- * @offset: Offset inside the first page (for userspace buffers)
- * @npages: Number of pages (for userspace buffers)
- * @pages: Pages table (for userspace non-VM_PFNMAP buffers)
- * @paddr: Memory physical address (for userspace VM_PFNMAP buffers)
- * @sglen: Number of elements in the scatter list (for non-VM_PFNMAP buffers)
- * @sglist: Scatter list (for non-VM_PFNMAP buffers)
- * @vbuf: V4L2 buffer
- * @irqlist: List head for insertion into IRQ queue
- * @state: Current buffer state
- * @wait: Wait queue to signal buffer completion
- */
-struct isp_video_buffer {
- unsigned long vma_use_count;
- struct list_head stream;
- struct isp_video_queue *queue;
- unsigned int prepared:1;
- bool skip_cache;
-
- /* For kernel buffers. */
- void *vaddr;
-
- /* For userspace buffers. */
- vm_flags_t vm_flags;
- unsigned long offset;
- unsigned int npages;
- struct page **pages;
- dma_addr_t paddr;
-
- /* For all buffers except VM_PFNMAP. */
- unsigned int sglen;
- struct scatterlist *sglist;
-
- /* Touched by the interrupt handler. */
- struct v4l2_buffer vbuf;
- struct list_head irqlist;
- enum isp_video_buffer_state state;
- wait_queue_head_t wait;
-};
-
-#define to_isp_video_buffer(vb) container_of(vb, struct isp_video_buffer, vb)
-
-/**
- * struct isp_video_queue_operations - Driver-specific operations
- * @queue_prepare: Called before allocating buffers. Drivers should clamp the
- * number of buffers according to their requirements, and must return the
- * buffer size in bytes.
- * @buffer_prepare: Called the first time a buffer is queued, or after changing
- * the userspace memory address for a USERPTR buffer, with the queue lock
- * held. Drivers should perform device-specific buffer preparation (such as
- * mapping the buffer memory in an IOMMU). This operation is optional.
- * @buffer_queue: Called when a buffer is being added to the queue with the
- * queue irqlock spinlock held.
- * @buffer_cleanup: Called before freeing buffers, or before changing the
- * userspace memory address for a USERPTR buffer, with the queue lock held.
- * Drivers must perform cleanup operations required to undo the
- * buffer_prepare call. This operation is optional.
- */
-struct isp_video_queue_operations {
- void (*queue_prepare)(struct isp_video_queue *queue,
- unsigned int *nbuffers, unsigned int *size);
- int (*buffer_prepare)(struct isp_video_buffer *buf);
- void (*buffer_queue)(struct isp_video_buffer *buf);
- void (*buffer_cleanup)(struct isp_video_buffer *buf);
-};
-
-/**
- * struct isp_video_queue - ISP video buffers queue
- * @type: Type of video buffers handled by this queue
- * @ops: Queue operations
- * @dev: Device used for DMA operations
- * @bufsize: Size of a driver-specific buffer object
- * @count: Number of currently allocated buffers
- * @buffers: ISP video buffers
- * @lock: Mutex to protect access to the buffers, main queue and state
- * @irqlock: Spinlock to protect access to the IRQ queue
- * @streaming: Queue state, indicates whether the queue is streaming
- * @queue: List of all queued buffers
- */
-struct isp_video_queue {
- enum v4l2_buf_type type;
- const struct isp_video_queue_operations *ops;
- struct device *dev;
- unsigned int bufsize;
-
- unsigned int count;
- struct isp_video_buffer *buffers[ISP_VIDEO_MAX_BUFFERS];
- struct mutex lock;
- spinlock_t irqlock;
-
- unsigned int streaming:1;
-
- struct list_head queue;
-};
-
-int omap3isp_video_queue_cleanup(struct isp_video_queue *queue);
-int omap3isp_video_queue_init(struct isp_video_queue *queue,
- enum v4l2_buf_type type,
- const struct isp_video_queue_operations *ops,
- struct device *dev, unsigned int bufsize);
-
-int omap3isp_video_queue_reqbufs(struct isp_video_queue *queue,
- struct v4l2_requestbuffers *rb);
-int omap3isp_video_queue_querybuf(struct isp_video_queue *queue,
- struct v4l2_buffer *vbuf);
-int omap3isp_video_queue_qbuf(struct isp_video_queue *queue,
- struct v4l2_buffer *vbuf);
-int omap3isp_video_queue_dqbuf(struct isp_video_queue *queue,
- struct v4l2_buffer *vbuf, int nonblocking);
-int omap3isp_video_queue_streamon(struct isp_video_queue *queue);
-void omap3isp_video_queue_streamoff(struct isp_video_queue *queue);
-void omap3isp_video_queue_discard_done(struct isp_video_queue *queue);
-int omap3isp_video_queue_mmap(struct isp_video_queue *queue,
- struct vm_area_struct *vma);
-unsigned int omap3isp_video_queue_poll(struct isp_video_queue *queue,
- struct file *file, poll_table *wait);
-
-#endif /* OMAP3_ISP_QUEUE_H */
diff --git a/drivers/media/video/omap3isp/ispreg.h b/drivers/media/video/omap3isp/ispreg.h
deleted file mode 100644
index 084ea77d65a..00000000000
--- a/drivers/media/video/omap3isp/ispreg.h
+++ /dev/null
@@ -1,1586 +0,0 @@
-/*
- * ispreg.h
- *
- * TI OMAP3 ISP - Registers definitions
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef OMAP3_ISP_REG_H
-#define OMAP3_ISP_REG_H
-
-#include <plat/omap34xx.h>
-
-
-#define CM_CAM_MCLK_HZ 172800000 /* Hz */
-
-/* ISP Submodules offset */
-
-#define OMAP3ISP_REG_BASE OMAP3430_ISP_BASE
-#define OMAP3ISP_REG(offset) (OMAP3ISP_REG_BASE + (offset))
-
-#define OMAP3ISP_CCP2_REG_OFFSET 0x0400
-#define OMAP3ISP_CCP2_REG_BASE (OMAP3ISP_REG_BASE + \
- OMAP3ISP_CCP2_REG_OFFSET)
-#define OMAP3ISP_CCP2_REG(offset) (OMAP3ISP_CCP2_REG_BASE + (offset))
-
-#define OMAP3ISP_CCDC_REG_OFFSET 0x0600
-#define OMAP3ISP_CCDC_REG_BASE (OMAP3ISP_REG_BASE + \
- OMAP3ISP_CCDC_REG_OFFSET)
-#define OMAP3ISP_CCDC_REG(offset) (OMAP3ISP_CCDC_REG_BASE + (offset))
-
-#define OMAP3ISP_HIST_REG_OFFSET 0x0A00
-#define OMAP3ISP_HIST_REG_BASE (OMAP3ISP_REG_BASE + \
- OMAP3ISP_HIST_REG_OFFSET)
-#define OMAP3ISP_HIST_REG(offset) (OMAP3ISP_HIST_REG_BASE + (offset))
-
-#define OMAP3ISP_H3A_REG_OFFSET 0x0C00
-#define OMAP3ISP_H3A_REG_BASE (OMAP3ISP_REG_BASE + \
- OMAP3ISP_H3A_REG_OFFSET)
-#define OMAP3ISP_H3A_REG(offset) (OMAP3ISP_H3A_REG_BASE + (offset))
-
-#define OMAP3ISP_PREV_REG_OFFSET 0x0E00
-#define OMAP3ISP_PREV_REG_BASE (OMAP3ISP_REG_BASE + \
- OMAP3ISP_PREV_REG_OFFSET)
-#define OMAP3ISP_PREV_REG(offset) (OMAP3ISP_PREV_REG_BASE + (offset))
-
-#define OMAP3ISP_RESZ_REG_OFFSET 0x1000
-#define OMAP3ISP_RESZ_REG_BASE (OMAP3ISP_REG_BASE + \
- OMAP3ISP_RESZ_REG_OFFSET)
-#define OMAP3ISP_RESZ_REG(offset) (OMAP3ISP_RESZ_REG_BASE + (offset))
-
-#define OMAP3ISP_SBL_REG_OFFSET 0x1200
-#define OMAP3ISP_SBL_REG_BASE (OMAP3ISP_REG_BASE + \
- OMAP3ISP_SBL_REG_OFFSET)
-#define OMAP3ISP_SBL_REG(offset) (OMAP3ISP_SBL_REG_BASE + (offset))
-
-#define OMAP3ISP_CSI2A_REGS1_REG_OFFSET 0x1800
-#define OMAP3ISP_CSI2A_REGS1_REG_BASE (OMAP3ISP_REG_BASE + \
- OMAP3ISP_CSI2A_REGS1_REG_OFFSET)
-#define OMAP3ISP_CSI2A_REGS1_REG(offset) \
- (OMAP3ISP_CSI2A_REGS1_REG_BASE + (offset))
-
-#define OMAP3ISP_CSIPHY2_REG_OFFSET 0x1970
-#define OMAP3ISP_CSIPHY2_REG_BASE (OMAP3ISP_REG_BASE + \
- OMAP3ISP_CSIPHY2_REG_OFFSET)
-#define OMAP3ISP_CSIPHY2_REG(offset) (OMAP3ISP_CSIPHY2_REG_BASE + (offset))
-
-#define OMAP3ISP_CSI2A_REGS2_REG_OFFSET 0x19C0
-#define OMAP3ISP_CSI2A_REGS2_REG_BASE (OMAP3ISP_REG_BASE + \
- OMAP3ISP_CSI2A_REGS2_REG_OFFSET)
-#define OMAP3ISP_CSI2A_REGS2_REG(offset) \
- (OMAP3ISP_CSI2A_REGS2_REG_BASE + (offset))
-
-#define OMAP3ISP_CSI2C_REGS1_REG_OFFSET 0x1C00
-#define OMAP3ISP_CSI2C_REGS1_REG_BASE (OMAP3ISP_REG_BASE + \
- OMAP3ISP_CSI2C_REGS1_REG_OFFSET)
-#define OMAP3ISP_CSI2C_REGS1_REG(offset) \
- (OMAP3ISP_CSI2C_REGS1_REG_BASE + (offset))
-
-#define OMAP3ISP_CSIPHY1_REG_OFFSET 0x1D70
-#define OMAP3ISP_CSIPHY1_REG_BASE (OMAP3ISP_REG_BASE + \
- OMAP3ISP_CSIPHY1_REG_OFFSET)
-#define OMAP3ISP_CSIPHY1_REG(offset) (OMAP3ISP_CSIPHY1_REG_BASE + (offset))
-
-#define OMAP3ISP_CSI2C_REGS2_REG_OFFSET 0x1DC0
-#define OMAP3ISP_CSI2C_REGS2_REG_BASE (OMAP3ISP_REG_BASE + \
- OMAP3ISP_CSI2C_REGS2_REG_OFFSET)
-#define OMAP3ISP_CSI2C_REGS2_REG(offset) \
- (OMAP3ISP_CSI2C_REGS2_REG_BASE + (offset))
-
-/* ISP module register offset */
-
-#define ISP_REVISION (0x000)
-#define ISP_SYSCONFIG (0x004)
-#define ISP_SYSSTATUS (0x008)
-#define ISP_IRQ0ENABLE (0x00C)
-#define ISP_IRQ0STATUS (0x010)
-#define ISP_IRQ1ENABLE (0x014)
-#define ISP_IRQ1STATUS (0x018)
-#define ISP_TCTRL_GRESET_LENGTH (0x030)
-#define ISP_TCTRL_PSTRB_REPLAY (0x034)
-#define ISP_CTRL (0x040)
-#define ISP_SECURE (0x044)
-#define ISP_TCTRL_CTRL (0x050)
-#define ISP_TCTRL_FRAME (0x054)
-#define ISP_TCTRL_PSTRB_DELAY (0x058)
-#define ISP_TCTRL_STRB_DELAY (0x05C)
-#define ISP_TCTRL_SHUT_DELAY (0x060)
-#define ISP_TCTRL_PSTRB_LENGTH (0x064)
-#define ISP_TCTRL_STRB_LENGTH (0x068)
-#define ISP_TCTRL_SHUT_LENGTH (0x06C)
-#define ISP_PING_PONG_ADDR (0x070)
-#define ISP_PING_PONG_MEM_RANGE (0x074)
-#define ISP_PING_PONG_BUF_SIZE (0x078)
-
-/* CCP2 receiver registers */
-
-#define ISPCCP2_REVISION (0x000)
-#define ISPCCP2_SYSCONFIG (0x004)
-#define ISPCCP2_SYSCONFIG_SOFT_RESET (1 << 1)
-#define ISPCCP2_SYSCONFIG_AUTO_IDLE 0x1
-#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT 12
-#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_FORCE \
- (0x0 << ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
-#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_NO \
- (0x1 << ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
-#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SMART \
- (0x2 << ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
-#define ISPCCP2_SYSSTATUS (0x008)
-#define ISPCCP2_SYSSTATUS_RESET_DONE (1 << 0)
-#define ISPCCP2_LC01_IRQENABLE (0x00C)
-#define ISPCCP2_LC01_IRQSTATUS (0x010)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ (1 << 11)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_LE_IRQ (1 << 10)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_LS_IRQ (1 << 9)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_FE_IRQ (1 << 8)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_COUNT_IRQ (1 << 7)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ (1 << 5)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ (1 << 4)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ (1 << 3)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ (1 << 2)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ (1 << 1)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ (1 << 0)
-
-#define ISPCCP2_LC23_IRQENABLE (0x014)
-#define ISPCCP2_LC23_IRQSTATUS (0x018)
-#define ISPCCP2_LCM_IRQENABLE (0x02C)
-#define ISPCCP2_LCM_IRQSTATUS_EOF_IRQ (1 << 0)
-#define ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ (1 << 1)
-#define ISPCCP2_LCM_IRQSTATUS (0x030)
-#define ISPCCP2_CTRL (0x040)
-#define ISPCCP2_CTRL_IF_EN (1 << 0)
-#define ISPCCP2_CTRL_PHY_SEL (1 << 1)
-#define ISPCCP2_CTRL_PHY_SEL_CLOCK (0 << 1)
-#define ISPCCP2_CTRL_PHY_SEL_STROBE (1 << 1)
-#define ISPCCP2_CTRL_PHY_SEL_MASK 0x1
-#define ISPCCP2_CTRL_PHY_SEL_SHIFT 1
-#define ISPCCP2_CTRL_IO_OUT_SEL (1 << 2)
-#define ISPCCP2_CTRL_MODE (1 << 4)
-#define ISPCCP2_CTRL_VP_CLK_FORCE_ON (1 << 9)
-#define ISPCCP2_CTRL_INV (1 << 10)
-#define ISPCCP2_CTRL_INV_MASK 0x1
-#define ISPCCP2_CTRL_INV_SHIFT 10
-#define ISPCCP2_CTRL_VP_ONLY_EN (1 << 11)
-#define ISPCCP2_CTRL_VP_CLK_POL (1 << 12)
-#define ISPCCP2_CTRL_VPCLK_DIV_SHIFT 15
-#define ISPCCP2_CTRL_VPCLK_DIV_MASK 0x1ffff /* [31:15] */
-#define ISPCCP2_CTRL_VP_OUT_CTRL_SHIFT 8 /* 3430 bits */
-#define ISPCCP2_CTRL_VP_OUT_CTRL_MASK 0x3 /* 3430 bits */
-#define ISPCCP2_DBG (0x044)
-#define ISPCCP2_GNQ (0x048)
-#define ISPCCP2_LCx_CTRL(x) ((0x050)+0x30*(x))
-#define ISPCCP2_LCx_CTRL_CHAN_EN (1 << 0)
-#define ISPCCP2_LCx_CTRL_CRC_EN (1 << 19)
-#define ISPCCP2_LCx_CTRL_CRC_MASK 0x1
-#define ISPCCP2_LCx_CTRL_CRC_SHIFT 2
-#define ISPCCP2_LCx_CTRL_CRC_SHIFT_15_0 19
-#define ISPCCP2_LCx_CTRL_REGION_EN (1 << 1)
-#define ISPCCP2_LCx_CTRL_REGION_MASK 0x1
-#define ISPCCP2_LCx_CTRL_REGION_SHIFT 1
-#define ISPCCP2_LCx_CTRL_FORMAT_MASK_15_0 0x3f
-#define ISPCCP2_LCx_CTRL_FORMAT_SHIFT_15_0 0x2
-#define ISPCCP2_LCx_CTRL_FORMAT_MASK 0x1f
-#define ISPCCP2_LCx_CTRL_FORMAT_SHIFT 0x3
-#define ISPCCP2_LCx_CODE(x) ((0x054)+0x30*(x))
-#define ISPCCP2_LCx_STAT_START(x) ((0x058)+0x30*(x))
-#define ISPCCP2_LCx_STAT_SIZE(x) ((0x05C)+0x30*(x))
-#define ISPCCP2_LCx_SOF_ADDR(x) ((0x060)+0x30*(x))
-#define ISPCCP2_LCx_EOF_ADDR(x) ((0x064)+0x30*(x))
-#define ISPCCP2_LCx_DAT_START(x) ((0x068)+0x30*(x))
-#define ISPCCP2_LCx_DAT_SIZE(x) ((0x06C)+0x30*(x))
-#define ISPCCP2_LCx_DAT_MASK 0xFFF
-#define ISPCCP2_LCx_DAT_SHIFT 16
-#define ISPCCP2_LCx_DAT_PING_ADDR(x) ((0x070)+0x30*(x))
-#define ISPCCP2_LCx_DAT_PONG_ADDR(x) ((0x074)+0x30*(x))
-#define ISPCCP2_LCx_DAT_OFST(x) ((0x078)+0x30*(x))
-#define ISPCCP2_LCM_CTRL (0x1D0)
-#define ISPCCP2_LCM_CTRL_CHAN_EN (1 << 0)
-#define ISPCCP2_LCM_CTRL_DST_PORT (1 << 2)
-#define ISPCCP2_LCM_CTRL_DST_PORT_SHIFT 2
-#define ISPCCP2_LCM_CTRL_READ_THROTTLE_SHIFT 3
-#define ISPCCP2_LCM_CTRL_READ_THROTTLE_MASK 0x11
-#define ISPCCP2_LCM_CTRL_BURST_SIZE_SHIFT 5
-#define ISPCCP2_LCM_CTRL_BURST_SIZE_MASK 0x7
-#define ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT 16
-#define ISPCCP2_LCM_CTRL_SRC_FORMAT_MASK 0x7
-#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_SHIFT 20
-#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_MASK 0x3
-#define ISPCCP2_LCM_CTRL_SRC_DPCM_PRED (1 << 22)
-#define ISPCCP2_LCM_CTRL_SRC_PACK (1 << 23)
-#define ISPCCP2_LCM_CTRL_DST_FORMAT_SHIFT 24
-#define ISPCCP2_LCM_CTRL_DST_FORMAT_MASK 0x7
-#define ISPCCP2_LCM_VSIZE (0x1D4)
-#define ISPCCP2_LCM_VSIZE_SHIFT 16
-#define ISPCCP2_LCM_HSIZE (0x1D8)
-#define ISPCCP2_LCM_HSIZE_SHIFT 16
-#define ISPCCP2_LCM_PREFETCH (0x1DC)
-#define ISPCCP2_LCM_PREFETCH_SHIFT 3
-#define ISPCCP2_LCM_SRC_ADDR (0x1E0)
-#define ISPCCP2_LCM_SRC_OFST (0x1E4)
-#define ISPCCP2_LCM_DST_ADDR (0x1E8)
-#define ISPCCP2_LCM_DST_OFST (0x1EC)
-
-/* CCDC module register offset */
-
-#define ISPCCDC_PID (0x000)
-#define ISPCCDC_PCR (0x004)
-#define ISPCCDC_SYN_MODE (0x008)
-#define ISPCCDC_HD_VD_WID (0x00C)
-#define ISPCCDC_PIX_LINES (0x010)
-#define ISPCCDC_HORZ_INFO (0x014)
-#define ISPCCDC_VERT_START (0x018)
-#define ISPCCDC_VERT_LINES (0x01C)
-#define ISPCCDC_CULLING (0x020)
-#define ISPCCDC_HSIZE_OFF (0x024)
-#define ISPCCDC_SDOFST (0x028)
-#define ISPCCDC_SDR_ADDR (0x02C)
-#define ISPCCDC_CLAMP (0x030)
-#define ISPCCDC_DCSUB (0x034)
-#define ISPCCDC_COLPTN (0x038)
-#define ISPCCDC_BLKCMP (0x03C)
-#define ISPCCDC_FPC (0x040)
-#define ISPCCDC_FPC_ADDR (0x044)
-#define ISPCCDC_VDINT (0x048)
-#define ISPCCDC_ALAW (0x04C)
-#define ISPCCDC_REC656IF (0x050)
-#define ISPCCDC_CFG (0x054)
-#define ISPCCDC_FMTCFG (0x058)
-#define ISPCCDC_FMT_HORZ (0x05C)
-#define ISPCCDC_FMT_VERT (0x060)
-#define ISPCCDC_FMT_ADDR0 (0x064)
-#define ISPCCDC_FMT_ADDR1 (0x068)
-#define ISPCCDC_FMT_ADDR2 (0x06C)
-#define ISPCCDC_FMT_ADDR3 (0x070)
-#define ISPCCDC_FMT_ADDR4 (0x074)
-#define ISPCCDC_FMT_ADDR5 (0x078)
-#define ISPCCDC_FMT_ADDR6 (0x07C)
-#define ISPCCDC_FMT_ADDR7 (0x080)
-#define ISPCCDC_PRGEVEN0 (0x084)
-#define ISPCCDC_PRGEVEN1 (0x088)
-#define ISPCCDC_PRGODD0 (0x08C)
-#define ISPCCDC_PRGODD1 (0x090)
-#define ISPCCDC_VP_OUT (0x094)
-
-#define ISPCCDC_LSC_CONFIG (0x098)
-#define ISPCCDC_LSC_INITIAL (0x09C)
-#define ISPCCDC_LSC_TABLE_BASE (0x0A0)
-#define ISPCCDC_LSC_TABLE_OFFSET (0x0A4)
-
-/* SBL */
-#define ISPSBL_PCR 0x4
-#define ISPSBL_PCR_H3A_AEAWB_WBL_OVF (1 << 16)
-#define ISPSBL_PCR_H3A_AF_WBL_OVF (1 << 17)
-#define ISPSBL_PCR_RSZ4_WBL_OVF (1 << 18)
-#define ISPSBL_PCR_RSZ3_WBL_OVF (1 << 19)
-#define ISPSBL_PCR_RSZ2_WBL_OVF (1 << 20)
-#define ISPSBL_PCR_RSZ1_WBL_OVF (1 << 21)
-#define ISPSBL_PCR_PRV_WBL_OVF (1 << 22)
-#define ISPSBL_PCR_CCDC_WBL_OVF (1 << 23)
-#define ISPSBL_PCR_CCDCPRV_2_RSZ_OVF (1 << 24)
-#define ISPSBL_PCR_CSIA_WBL_OVF (1 << 25)
-#define ISPSBL_PCR_CSIB_WBL_OVF (1 << 26)
-#define ISPSBL_CCDC_WR_0 (0x028)
-#define ISPSBL_CCDC_WR_0_DATA_READY (1 << 21)
-#define ISPSBL_CCDC_WR_1 (0x02C)
-#define ISPSBL_CCDC_WR_2 (0x030)
-#define ISPSBL_CCDC_WR_3 (0x034)
-
-#define ISPSBL_SDR_REQ_EXP 0xF8
-#define ISPSBL_SDR_REQ_HIST_EXP_SHIFT 0
-#define ISPSBL_SDR_REQ_HIST_EXP_MASK (0x3FF)
-#define ISPSBL_SDR_REQ_RSZ_EXP_SHIFT 10
-#define ISPSBL_SDR_REQ_RSZ_EXP_MASK (0x3FF << ISPSBL_SDR_REQ_RSZ_EXP_SHIFT)
-#define ISPSBL_SDR_REQ_PRV_EXP_SHIFT 20
-#define ISPSBL_SDR_REQ_PRV_EXP_MASK (0x3FF << ISPSBL_SDR_REQ_PRV_EXP_SHIFT)
-
-/* Histogram registers */
-#define ISPHIST_PID (0x000)
-#define ISPHIST_PCR (0x004)
-#define ISPHIST_CNT (0x008)
-#define ISPHIST_WB_GAIN (0x00C)
-#define ISPHIST_R0_HORZ (0x010)
-#define ISPHIST_R0_VERT (0x014)
-#define ISPHIST_R1_HORZ (0x018)
-#define ISPHIST_R1_VERT (0x01C)
-#define ISPHIST_R2_HORZ (0x020)
-#define ISPHIST_R2_VERT (0x024)
-#define ISPHIST_R3_HORZ (0x028)
-#define ISPHIST_R3_VERT (0x02C)
-#define ISPHIST_ADDR (0x030)
-#define ISPHIST_DATA (0x034)
-#define ISPHIST_RADD (0x038)
-#define ISPHIST_RADD_OFF (0x03C)
-#define ISPHIST_H_V_INFO (0x040)
-
-/* H3A module registers */
-#define ISPH3A_PID (0x000)
-#define ISPH3A_PCR (0x004)
-#define ISPH3A_AEWWIN1 (0x04C)
-#define ISPH3A_AEWINSTART (0x050)
-#define ISPH3A_AEWINBLK (0x054)
-#define ISPH3A_AEWSUBWIN (0x058)
-#define ISPH3A_AEWBUFST (0x05C)
-#define ISPH3A_AFPAX1 (0x008)
-#define ISPH3A_AFPAX2 (0x00C)
-#define ISPH3A_AFPAXSTART (0x010)
-#define ISPH3A_AFIIRSH (0x014)
-#define ISPH3A_AFBUFST (0x018)
-#define ISPH3A_AFCOEF010 (0x01C)
-#define ISPH3A_AFCOEF032 (0x020)
-#define ISPH3A_AFCOEF054 (0x024)
-#define ISPH3A_AFCOEF076 (0x028)
-#define ISPH3A_AFCOEF098 (0x02C)
-#define ISPH3A_AFCOEF0010 (0x030)
-#define ISPH3A_AFCOEF110 (0x034)
-#define ISPH3A_AFCOEF132 (0x038)
-#define ISPH3A_AFCOEF154 (0x03C)
-#define ISPH3A_AFCOEF176 (0x040)
-#define ISPH3A_AFCOEF198 (0x044)
-#define ISPH3A_AFCOEF1010 (0x048)
-
-#define ISPPRV_PCR (0x004)
-#define ISPPRV_HORZ_INFO (0x008)
-#define ISPPRV_VERT_INFO (0x00C)
-#define ISPPRV_RSDR_ADDR (0x010)
-#define ISPPRV_RADR_OFFSET (0x014)
-#define ISPPRV_DSDR_ADDR (0x018)
-#define ISPPRV_DRKF_OFFSET (0x01C)
-#define ISPPRV_WSDR_ADDR (0x020)
-#define ISPPRV_WADD_OFFSET (0x024)
-#define ISPPRV_AVE (0x028)
-#define ISPPRV_HMED (0x02C)
-#define ISPPRV_NF (0x030)
-#define ISPPRV_WB_DGAIN (0x034)
-#define ISPPRV_WBGAIN (0x038)
-#define ISPPRV_WBSEL (0x03C)
-#define ISPPRV_CFA (0x040)
-#define ISPPRV_BLKADJOFF (0x044)
-#define ISPPRV_RGB_MAT1 (0x048)
-#define ISPPRV_RGB_MAT2 (0x04C)
-#define ISPPRV_RGB_MAT3 (0x050)
-#define ISPPRV_RGB_MAT4 (0x054)
-#define ISPPRV_RGB_MAT5 (0x058)
-#define ISPPRV_RGB_OFF1 (0x05C)
-#define ISPPRV_RGB_OFF2 (0x060)
-#define ISPPRV_CSC0 (0x064)
-#define ISPPRV_CSC1 (0x068)
-#define ISPPRV_CSC2 (0x06C)
-#define ISPPRV_CSC_OFFSET (0x070)
-#define ISPPRV_CNT_BRT (0x074)
-#define ISPPRV_CSUP (0x078)
-#define ISPPRV_SETUP_YC (0x07C)
-#define ISPPRV_SET_TBL_ADDR (0x080)
-#define ISPPRV_SET_TBL_DATA (0x084)
-#define ISPPRV_CDC_THR0 (0x090)
-#define ISPPRV_CDC_THR1 (ISPPRV_CDC_THR0 + (0x4))
-#define ISPPRV_CDC_THR2 (ISPPRV_CDC_THR0 + (0x4) * 2)
-#define ISPPRV_CDC_THR3 (ISPPRV_CDC_THR0 + (0x4) * 3)
-
-#define ISPPRV_REDGAMMA_TABLE_ADDR 0x0000
-#define ISPPRV_GREENGAMMA_TABLE_ADDR 0x0400
-#define ISPPRV_BLUEGAMMA_TABLE_ADDR 0x0800
-#define ISPPRV_NF_TABLE_ADDR 0x0C00
-#define ISPPRV_YENH_TABLE_ADDR 0x1000
-#define ISPPRV_CFA_TABLE_ADDR 0x1400
-
-#define ISPRSZ_MIN_OUTPUT 64
-#define ISPRSZ_MAX_OUTPUT 3312
-
-/* Resizer module register offset */
-#define ISPRSZ_PID (0x000)
-#define ISPRSZ_PCR (0x004)
-#define ISPRSZ_CNT (0x008)
-#define ISPRSZ_OUT_SIZE (0x00C)
-#define ISPRSZ_IN_START (0x010)
-#define ISPRSZ_IN_SIZE (0x014)
-#define ISPRSZ_SDR_INADD (0x018)
-#define ISPRSZ_SDR_INOFF (0x01C)
-#define ISPRSZ_SDR_OUTADD (0x020)
-#define ISPRSZ_SDR_OUTOFF (0x024)
-#define ISPRSZ_HFILT10 (0x028)
-#define ISPRSZ_HFILT32 (0x02C)
-#define ISPRSZ_HFILT54 (0x030)
-#define ISPRSZ_HFILT76 (0x034)
-#define ISPRSZ_HFILT98 (0x038)
-#define ISPRSZ_HFILT1110 (0x03C)
-#define ISPRSZ_HFILT1312 (0x040)
-#define ISPRSZ_HFILT1514 (0x044)
-#define ISPRSZ_HFILT1716 (0x048)
-#define ISPRSZ_HFILT1918 (0x04C)
-#define ISPRSZ_HFILT2120 (0x050)
-#define ISPRSZ_HFILT2322 (0x054)
-#define ISPRSZ_HFILT2524 (0x058)
-#define ISPRSZ_HFILT2726 (0x05C)
-#define ISPRSZ_HFILT2928 (0x060)
-#define ISPRSZ_HFILT3130 (0x064)
-#define ISPRSZ_VFILT10 (0x068)
-#define ISPRSZ_VFILT32 (0x06C)
-#define ISPRSZ_VFILT54 (0x070)
-#define ISPRSZ_VFILT76 (0x074)
-#define ISPRSZ_VFILT98 (0x078)
-#define ISPRSZ_VFILT1110 (0x07C)
-#define ISPRSZ_VFILT1312 (0x080)
-#define ISPRSZ_VFILT1514 (0x084)
-#define ISPRSZ_VFILT1716 (0x088)
-#define ISPRSZ_VFILT1918 (0x08C)
-#define ISPRSZ_VFILT2120 (0x090)
-#define ISPRSZ_VFILT2322 (0x094)
-#define ISPRSZ_VFILT2524 (0x098)
-#define ISPRSZ_VFILT2726 (0x09C)
-#define ISPRSZ_VFILT2928 (0x0A0)
-#define ISPRSZ_VFILT3130 (0x0A4)
-#define ISPRSZ_YENH (0x0A8)
-
-#define ISP_INT_CLR 0xFF113F11
-#define ISPPRV_PCR_EN 1
-#define ISPPRV_PCR_BUSY (1 << 1)
-#define ISPPRV_PCR_SOURCE (1 << 2)
-#define ISPPRV_PCR_ONESHOT (1 << 3)
-#define ISPPRV_PCR_WIDTH (1 << 4)
-#define ISPPRV_PCR_INVALAW (1 << 5)
-#define ISPPRV_PCR_DRKFEN (1 << 6)
-#define ISPPRV_PCR_DRKFCAP (1 << 7)
-#define ISPPRV_PCR_HMEDEN (1 << 8)
-#define ISPPRV_PCR_NFEN (1 << 9)
-#define ISPPRV_PCR_CFAEN (1 << 10)
-#define ISPPRV_PCR_CFAFMT_SHIFT 11
-#define ISPPRV_PCR_CFAFMT_MASK 0x7800
-#define ISPPRV_PCR_CFAFMT_BAYER (0 << 11)
-#define ISPPRV_PCR_CFAFMT_SONYVGA (1 << 11)
-#define ISPPRV_PCR_CFAFMT_RGBFOVEON (2 << 11)
-#define ISPPRV_PCR_CFAFMT_DNSPL (3 << 11)
-#define ISPPRV_PCR_CFAFMT_HONEYCOMB (4 << 11)
-#define ISPPRV_PCR_CFAFMT_RRGGBBFOVEON (5 << 11)
-#define ISPPRV_PCR_YNENHEN (1 << 15)
-#define ISPPRV_PCR_SUPEN (1 << 16)
-#define ISPPRV_PCR_YCPOS_SHIFT 17
-#define ISPPRV_PCR_YCPOS_YCrYCb (0 << 17)
-#define ISPPRV_PCR_YCPOS_YCbYCr (1 << 17)
-#define ISPPRV_PCR_YCPOS_CbYCrY (2 << 17)
-#define ISPPRV_PCR_YCPOS_CrYCbY (3 << 17)
-#define ISPPRV_PCR_RSZPORT (1 << 19)
-#define ISPPRV_PCR_SDRPORT (1 << 20)
-#define ISPPRV_PCR_SCOMP_EN (1 << 21)
-#define ISPPRV_PCR_SCOMP_SFT_SHIFT (22)
-#define ISPPRV_PCR_SCOMP_SFT_MASK (7 << 22)
-#define ISPPRV_PCR_GAMMA_BYPASS (1 << 26)
-#define ISPPRV_PCR_DCOREN (1 << 27)
-#define ISPPRV_PCR_DCCOUP (1 << 28)
-#define ISPPRV_PCR_DRK_FAIL (1 << 31)
-
-#define ISPPRV_HORZ_INFO_EPH_SHIFT 0
-#define ISPPRV_HORZ_INFO_EPH_MASK 0x3fff
-#define ISPPRV_HORZ_INFO_SPH_SHIFT 16
-#define ISPPRV_HORZ_INFO_SPH_MASK 0x3fff0
-
-#define ISPPRV_VERT_INFO_ELV_SHIFT 0
-#define ISPPRV_VERT_INFO_ELV_MASK 0x3fff
-#define ISPPRV_VERT_INFO_SLV_SHIFT 16
-#define ISPPRV_VERT_INFO_SLV_MASK 0x3fff0
-
-#define ISPPRV_AVE_EVENDIST_SHIFT 2
-#define ISPPRV_AVE_EVENDIST_1 0x0
-#define ISPPRV_AVE_EVENDIST_2 0x1
-#define ISPPRV_AVE_EVENDIST_3 0x2
-#define ISPPRV_AVE_EVENDIST_4 0x3
-#define ISPPRV_AVE_ODDDIST_SHIFT 4
-#define ISPPRV_AVE_ODDDIST_1 0x0
-#define ISPPRV_AVE_ODDDIST_2 0x1
-#define ISPPRV_AVE_ODDDIST_3 0x2
-#define ISPPRV_AVE_ODDDIST_4 0x3
-
-#define ISPPRV_HMED_THRESHOLD_SHIFT 0
-#define ISPPRV_HMED_EVENDIST (1 << 8)
-#define ISPPRV_HMED_ODDDIST (1 << 9)
-
-#define ISPPRV_WBGAIN_COEF0_SHIFT 0
-#define ISPPRV_WBGAIN_COEF1_SHIFT 8
-#define ISPPRV_WBGAIN_COEF2_SHIFT 16
-#define ISPPRV_WBGAIN_COEF3_SHIFT 24
-
-#define ISPPRV_WBSEL_COEF0 0x0
-#define ISPPRV_WBSEL_COEF1 0x1
-#define ISPPRV_WBSEL_COEF2 0x2
-#define ISPPRV_WBSEL_COEF3 0x3
-
-#define ISPPRV_WBSEL_N0_0_SHIFT 0
-#define ISPPRV_WBSEL_N0_1_SHIFT 2
-#define ISPPRV_WBSEL_N0_2_SHIFT 4
-#define ISPPRV_WBSEL_N0_3_SHIFT 6
-#define ISPPRV_WBSEL_N1_0_SHIFT 8
-#define ISPPRV_WBSEL_N1_1_SHIFT 10
-#define ISPPRV_WBSEL_N1_2_SHIFT 12
-#define ISPPRV_WBSEL_N1_3_SHIFT 14
-#define ISPPRV_WBSEL_N2_0_SHIFT 16
-#define ISPPRV_WBSEL_N2_1_SHIFT 18
-#define ISPPRV_WBSEL_N2_2_SHIFT 20
-#define ISPPRV_WBSEL_N2_3_SHIFT 22
-#define ISPPRV_WBSEL_N3_0_SHIFT 24
-#define ISPPRV_WBSEL_N3_1_SHIFT 26
-#define ISPPRV_WBSEL_N3_2_SHIFT 28
-#define ISPPRV_WBSEL_N3_3_SHIFT 30
-
-#define ISPPRV_CFA_GRADTH_HOR_SHIFT 0
-#define ISPPRV_CFA_GRADTH_VER_SHIFT 8
-
-#define ISPPRV_BLKADJOFF_B_SHIFT 0
-#define ISPPRV_BLKADJOFF_G_SHIFT 8
-#define ISPPRV_BLKADJOFF_R_SHIFT 16
-
-#define ISPPRV_RGB_MAT1_MTX_RR_SHIFT 0
-#define ISPPRV_RGB_MAT1_MTX_GR_SHIFT 16
-
-#define ISPPRV_RGB_MAT2_MTX_BR_SHIFT 0
-#define ISPPRV_RGB_MAT2_MTX_RG_SHIFT 16
-
-#define ISPPRV_RGB_MAT3_MTX_GG_SHIFT 0
-#define ISPPRV_RGB_MAT3_MTX_BG_SHIFT 16
-
-#define ISPPRV_RGB_MAT4_MTX_RB_SHIFT 0
-#define ISPPRV_RGB_MAT4_MTX_GB_SHIFT 16
-
-#define ISPPRV_RGB_MAT5_MTX_BB_SHIFT 0
-
-#define ISPPRV_RGB_OFF1_MTX_OFFG_SHIFT 0
-#define ISPPRV_RGB_OFF1_MTX_OFFR_SHIFT 16
-
-#define ISPPRV_RGB_OFF2_MTX_OFFB_SHIFT 0
-
-#define ISPPRV_CSC0_RY_SHIFT 0
-#define ISPPRV_CSC0_GY_SHIFT 10
-#define ISPPRV_CSC0_BY_SHIFT 20
-
-#define ISPPRV_CSC1_RCB_SHIFT 0
-#define ISPPRV_CSC1_GCB_SHIFT 10
-#define ISPPRV_CSC1_BCB_SHIFT 20
-
-#define ISPPRV_CSC2_RCR_SHIFT 0
-#define ISPPRV_CSC2_GCR_SHIFT 10
-#define ISPPRV_CSC2_BCR_SHIFT 20
-
-#define ISPPRV_CSC_OFFSET_CR_SHIFT 0
-#define ISPPRV_CSC_OFFSET_CB_SHIFT 8
-#define ISPPRV_CSC_OFFSET_Y_SHIFT 16
-
-#define ISPPRV_CNT_BRT_BRT_SHIFT 0
-#define ISPPRV_CNT_BRT_CNT_SHIFT 8
-
-#define ISPPRV_CONTRAST_MAX 0x10
-#define ISPPRV_CONTRAST_MIN 0xFF
-#define ISPPRV_BRIGHT_MIN 0x00
-#define ISPPRV_BRIGHT_MAX 0xFF
-
-#define ISPPRV_CSUP_CSUPG_SHIFT 0
-#define ISPPRV_CSUP_THRES_SHIFT 8
-#define ISPPRV_CSUP_HPYF_SHIFT 16
-
-#define ISPPRV_SETUP_YC_MINC_SHIFT 0
-#define ISPPRV_SETUP_YC_MAXC_SHIFT 8
-#define ISPPRV_SETUP_YC_MINY_SHIFT 16
-#define ISPPRV_SETUP_YC_MAXY_SHIFT 24
-#define ISPPRV_YC_MAX 0xFF
-#define ISPPRV_YC_MIN 0x0
-
-/* Define bit fields within selected registers */
-#define ISP_REVISION_SHIFT 0
-
-#define ISP_SYSCONFIG_AUTOIDLE (1 << 0)
-#define ISP_SYSCONFIG_SOFTRESET (1 << 1)
-#define ISP_SYSCONFIG_MIDLEMODE_SHIFT 12
-#define ISP_SYSCONFIG_MIDLEMODE_FORCESTANDBY 0x0
-#define ISP_SYSCONFIG_MIDLEMODE_NOSTANBY 0x1
-#define ISP_SYSCONFIG_MIDLEMODE_SMARTSTANDBY 0x2
-
-#define ISP_SYSSTATUS_RESETDONE 0
-
-#define IRQ0ENABLE_CSIA_IRQ (1 << 0)
-#define IRQ0ENABLE_CSIC_IRQ (1 << 1)
-#define IRQ0ENABLE_CCP2_LCM_IRQ (1 << 3)
-#define IRQ0ENABLE_CCP2_LC0_IRQ (1 << 4)
-#define IRQ0ENABLE_CCP2_LC1_IRQ (1 << 5)
-#define IRQ0ENABLE_CCP2_LC2_IRQ (1 << 6)
-#define IRQ0ENABLE_CCP2_LC3_IRQ (1 << 7)
-#define IRQ0ENABLE_CSIB_IRQ (IRQ0ENABLE_CCP2_LCM_IRQ | \
- IRQ0ENABLE_CCP2_LC0_IRQ | \
- IRQ0ENABLE_CCP2_LC1_IRQ | \
- IRQ0ENABLE_CCP2_LC2_IRQ | \
- IRQ0ENABLE_CCP2_LC3_IRQ)
-
-#define IRQ0ENABLE_CCDC_VD0_IRQ (1 << 8)
-#define IRQ0ENABLE_CCDC_VD1_IRQ (1 << 9)
-#define IRQ0ENABLE_CCDC_VD2_IRQ (1 << 10)
-#define IRQ0ENABLE_CCDC_ERR_IRQ (1 << 11)
-#define IRQ0ENABLE_H3A_AF_DONE_IRQ (1 << 12)
-#define IRQ0ENABLE_H3A_AWB_DONE_IRQ (1 << 13)
-#define IRQ0ENABLE_HIST_DONE_IRQ (1 << 16)
-#define IRQ0ENABLE_CCDC_LSC_DONE_IRQ (1 << 17)
-#define IRQ0ENABLE_CCDC_LSC_PREF_COMP_IRQ (1 << 18)
-#define IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ (1 << 19)
-#define IRQ0ENABLE_PRV_DONE_IRQ (1 << 20)
-#define IRQ0ENABLE_RSZ_DONE_IRQ (1 << 24)
-#define IRQ0ENABLE_OVF_IRQ (1 << 25)
-#define IRQ0ENABLE_PING_IRQ (1 << 26)
-#define IRQ0ENABLE_PONG_IRQ (1 << 27)
-#define IRQ0ENABLE_MMU_ERR_IRQ (1 << 28)
-#define IRQ0ENABLE_OCP_ERR_IRQ (1 << 29)
-#define IRQ0ENABLE_SEC_ERR_IRQ (1 << 30)
-#define IRQ0ENABLE_HS_VS_IRQ (1 << 31)
-
-#define IRQ0STATUS_CSIA_IRQ (1 << 0)
-#define IRQ0STATUS_CSI2C_IRQ (1 << 1)
-#define IRQ0STATUS_CCP2_LCM_IRQ (1 << 3)
-#define IRQ0STATUS_CCP2_LC0_IRQ (1 << 4)
-#define IRQ0STATUS_CSIB_IRQ (IRQ0STATUS_CCP2_LCM_IRQ | \
- IRQ0STATUS_CCP2_LC0_IRQ)
-
-#define IRQ0STATUS_CSIB_LC1_IRQ (1 << 5)
-#define IRQ0STATUS_CSIB_LC2_IRQ (1 << 6)
-#define IRQ0STATUS_CSIB_LC3_IRQ (1 << 7)
-#define IRQ0STATUS_CCDC_VD0_IRQ (1 << 8)
-#define IRQ0STATUS_CCDC_VD1_IRQ (1 << 9)
-#define IRQ0STATUS_CCDC_VD2_IRQ (1 << 10)
-#define IRQ0STATUS_CCDC_ERR_IRQ (1 << 11)
-#define IRQ0STATUS_H3A_AF_DONE_IRQ (1 << 12)
-#define IRQ0STATUS_H3A_AWB_DONE_IRQ (1 << 13)
-#define IRQ0STATUS_HIST_DONE_IRQ (1 << 16)
-#define IRQ0STATUS_CCDC_LSC_DONE_IRQ (1 << 17)
-#define IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ (1 << 18)
-#define IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ (1 << 19)
-#define IRQ0STATUS_PRV_DONE_IRQ (1 << 20)
-#define IRQ0STATUS_RSZ_DONE_IRQ (1 << 24)
-#define IRQ0STATUS_OVF_IRQ (1 << 25)
-#define IRQ0STATUS_PING_IRQ (1 << 26)
-#define IRQ0STATUS_PONG_IRQ (1 << 27)
-#define IRQ0STATUS_MMU_ERR_IRQ (1 << 28)
-#define IRQ0STATUS_OCP_ERR_IRQ (1 << 29)
-#define IRQ0STATUS_SEC_ERR_IRQ (1 << 30)
-#define IRQ0STATUS_HS_VS_IRQ (1 << 31)
-
-#define TCTRL_GRESET_LEN 0
-
-#define TCTRL_PSTRB_REPLAY_DELAY 0
-#define TCTRL_PSTRB_REPLAY_COUNTER_SHIFT 25
-
-#define ISPCTRL_PAR_SER_CLK_SEL_PARALLEL 0x0
-#define ISPCTRL_PAR_SER_CLK_SEL_CSIA 0x1
-#define ISPCTRL_PAR_SER_CLK_SEL_CSIB 0x2
-#define ISPCTRL_PAR_SER_CLK_SEL_CSIC 0x3
-#define ISPCTRL_PAR_SER_CLK_SEL_MASK 0x3
-
-#define ISPCTRL_PAR_BRIDGE_SHIFT 2
-#define ISPCTRL_PAR_BRIDGE_DISABLE (0x0 << 2)
-#define ISPCTRL_PAR_BRIDGE_LENDIAN (0x2 << 2)
-#define ISPCTRL_PAR_BRIDGE_BENDIAN (0x3 << 2)
-#define ISPCTRL_PAR_BRIDGE_MASK (0x3 << 2)
-
-#define ISPCTRL_PAR_CLK_POL_SHIFT 4
-#define ISPCTRL_PAR_CLK_POL_INV (1 << 4)
-#define ISPCTRL_PING_PONG_EN (1 << 5)
-#define ISPCTRL_SHIFT_SHIFT 6
-#define ISPCTRL_SHIFT_0 (0x0 << 6)
-#define ISPCTRL_SHIFT_2 (0x1 << 6)
-#define ISPCTRL_SHIFT_4 (0x2 << 6)
-#define ISPCTRL_SHIFT_MASK (0x3 << 6)
-
-#define ISPCTRL_CCDC_CLK_EN (1 << 8)
-#define ISPCTRL_SCMP_CLK_EN (1 << 9)
-#define ISPCTRL_H3A_CLK_EN (1 << 10)
-#define ISPCTRL_HIST_CLK_EN (1 << 11)
-#define ISPCTRL_PREV_CLK_EN (1 << 12)
-#define ISPCTRL_RSZ_CLK_EN (1 << 13)
-#define ISPCTRL_SYNC_DETECT_SHIFT 14
-#define ISPCTRL_SYNC_DETECT_HSFALL (0x0 << ISPCTRL_SYNC_DETECT_SHIFT)
-#define ISPCTRL_SYNC_DETECT_HSRISE (0x1 << ISPCTRL_SYNC_DETECT_SHIFT)
-#define ISPCTRL_SYNC_DETECT_VSFALL (0x2 << ISPCTRL_SYNC_DETECT_SHIFT)
-#define ISPCTRL_SYNC_DETECT_VSRISE (0x3 << ISPCTRL_SYNC_DETECT_SHIFT)
-#define ISPCTRL_SYNC_DETECT_MASK (0x3 << ISPCTRL_SYNC_DETECT_SHIFT)
-
-#define ISPCTRL_CCDC_RAM_EN (1 << 16)
-#define ISPCTRL_PREV_RAM_EN (1 << 17)
-#define ISPCTRL_SBL_RD_RAM_EN (1 << 18)
-#define ISPCTRL_SBL_WR1_RAM_EN (1 << 19)
-#define ISPCTRL_SBL_WR0_RAM_EN (1 << 20)
-#define ISPCTRL_SBL_AUTOIDLE (1 << 21)
-#define ISPCTRL_SBL_SHARED_WPORTC (1 << 26)
-#define ISPCTRL_SBL_SHARED_RPORTA (1 << 27)
-#define ISPCTRL_SBL_SHARED_RPORTB (1 << 28)
-#define ISPCTRL_JPEG_FLUSH (1 << 30)
-#define ISPCTRL_CCDC_FLUSH (1 << 31)
-
-#define ISPSECURE_SECUREMODE 0
-
-#define ISPTCTRL_CTRL_DIV_LOW 0x0
-#define ISPTCTRL_CTRL_DIV_HIGH 0x1
-#define ISPTCTRL_CTRL_DIV_BYPASS 0x1F
-
-#define ISPTCTRL_CTRL_DIVA_SHIFT 0
-#define ISPTCTRL_CTRL_DIVA_MASK (0x1F << ISPTCTRL_CTRL_DIVA_SHIFT)
-
-#define ISPTCTRL_CTRL_DIVB_SHIFT 5
-#define ISPTCTRL_CTRL_DIVB_MASK (0x1F << ISPTCTRL_CTRL_DIVB_SHIFT)
-
-#define ISPTCTRL_CTRL_DIVC_SHIFT 10
-#define ISPTCTRL_CTRL_DIVC_NOCLOCK (0x0 << 10)
-
-#define ISPTCTRL_CTRL_SHUTEN (1 << 21)
-#define ISPTCTRL_CTRL_PSTRBEN (1 << 22)
-#define ISPTCTRL_CTRL_STRBEN (1 << 23)
-#define ISPTCTRL_CTRL_SHUTPOL (1 << 24)
-#define ISPTCTRL_CTRL_STRBPSTRBPOL (1 << 26)
-
-#define ISPTCTRL_CTRL_INSEL_SHIFT 27
-#define ISPTCTRL_CTRL_INSEL_PARALLEL (0x0 << 27)
-#define ISPTCTRL_CTRL_INSEL_CSIA (0x1 << 27)
-#define ISPTCTRL_CTRL_INSEL_CSIB (0x2 << 27)
-
-#define ISPTCTRL_CTRL_GRESETEn (1 << 29)
-#define ISPTCTRL_CTRL_GRESETPOL (1 << 30)
-#define ISPTCTRL_CTRL_GRESETDIR (1 << 31)
-
-#define ISPTCTRL_FRAME_SHUT_SHIFT 0
-#define ISPTCTRL_FRAME_PSTRB_SHIFT 6
-#define ISPTCTRL_FRAME_STRB_SHIFT 12
-
-#define ISPCCDC_PID_PREV_SHIFT 0
-#define ISPCCDC_PID_CID_SHIFT 8
-#define ISPCCDC_PID_TID_SHIFT 16
-
-#define ISPCCDC_PCR_EN 1
-#define ISPCCDC_PCR_BUSY (1 << 1)
-
-#define ISPCCDC_SYN_MODE_VDHDOUT 0x1
-#define ISPCCDC_SYN_MODE_FLDOUT (1 << 1)
-#define ISPCCDC_SYN_MODE_VDPOL (1 << 2)
-#define ISPCCDC_SYN_MODE_HDPOL (1 << 3)
-#define ISPCCDC_SYN_MODE_FLDPOL (1 << 4)
-#define ISPCCDC_SYN_MODE_EXWEN (1 << 5)
-#define ISPCCDC_SYN_MODE_DATAPOL (1 << 6)
-#define ISPCCDC_SYN_MODE_FLDMODE (1 << 7)
-#define ISPCCDC_SYN_MODE_DATSIZ_MASK (0x7 << 8)
-#define ISPCCDC_SYN_MODE_DATSIZ_8_16 (0x0 << 8)
-#define ISPCCDC_SYN_MODE_DATSIZ_12 (0x4 << 8)
-#define ISPCCDC_SYN_MODE_DATSIZ_11 (0x5 << 8)
-#define ISPCCDC_SYN_MODE_DATSIZ_10 (0x6 << 8)
-#define ISPCCDC_SYN_MODE_DATSIZ_8 (0x7 << 8)
-#define ISPCCDC_SYN_MODE_PACK8 (1 << 11)
-#define ISPCCDC_SYN_MODE_INPMOD_MASK (3 << 12)
-#define ISPCCDC_SYN_MODE_INPMOD_RAW (0 << 12)
-#define ISPCCDC_SYN_MODE_INPMOD_YCBCR16 (1 << 12)
-#define ISPCCDC_SYN_MODE_INPMOD_YCBCR8 (2 << 12)
-#define ISPCCDC_SYN_MODE_LPF (1 << 14)
-#define ISPCCDC_SYN_MODE_FLDSTAT (1 << 15)
-#define ISPCCDC_SYN_MODE_VDHDEN (1 << 16)
-#define ISPCCDC_SYN_MODE_WEN (1 << 17)
-#define ISPCCDC_SYN_MODE_VP2SDR (1 << 18)
-#define ISPCCDC_SYN_MODE_SDR2RSZ (1 << 19)
-
-#define ISPCCDC_HD_VD_WID_VDW_SHIFT 0
-#define ISPCCDC_HD_VD_WID_HDW_SHIFT 16
-
-#define ISPCCDC_PIX_LINES_HLPRF_SHIFT 0
-#define ISPCCDC_PIX_LINES_PPLN_SHIFT 16
-
-#define ISPCCDC_HORZ_INFO_NPH_SHIFT 0
-#define ISPCCDC_HORZ_INFO_NPH_MASK 0x00007fff
-#define ISPCCDC_HORZ_INFO_SPH_SHIFT 16
-#define ISPCCDC_HORZ_INFO_SPH_MASK 0x7fff0000
-
-#define ISPCCDC_VERT_START_SLV1_SHIFT 0
-#define ISPCCDC_VERT_START_SLV0_SHIFT 16
-#define ISPCCDC_VERT_START_SLV0_MASK 0x7fff0000
-
-#define ISPCCDC_VERT_LINES_NLV_SHIFT 0
-#define ISPCCDC_VERT_LINES_NLV_MASK 0x00007fff
-
-#define ISPCCDC_CULLING_CULV_SHIFT 0
-#define ISPCCDC_CULLING_CULHODD_SHIFT 16
-#define ISPCCDC_CULLING_CULHEVN_SHIFT 24
-
-#define ISPCCDC_HSIZE_OFF_SHIFT 0
-
-#define ISPCCDC_SDOFST_FINV (1 << 14)
-#define ISPCCDC_SDOFST_FOFST_1L 0
-#define ISPCCDC_SDOFST_FOFST_4L (3 << 12)
-#define ISPCCDC_SDOFST_LOFST3_SHIFT 0
-#define ISPCCDC_SDOFST_LOFST2_SHIFT 3
-#define ISPCCDC_SDOFST_LOFST1_SHIFT 6
-#define ISPCCDC_SDOFST_LOFST0_SHIFT 9
-#define EVENEVEN 1
-#define ODDEVEN 2
-#define EVENODD 3
-#define ODDODD 4
-
-#define ISPCCDC_CLAMP_OBGAIN_SHIFT 0
-#define ISPCCDC_CLAMP_OBST_SHIFT 10
-#define ISPCCDC_CLAMP_OBSLN_SHIFT 25
-#define ISPCCDC_CLAMP_OBSLEN_SHIFT 28
-#define ISPCCDC_CLAMP_CLAMPEN (1 << 31)
-
-#define ISPCCDC_COLPTN_R_Ye 0x0
-#define ISPCCDC_COLPTN_Gr_Cy 0x1
-#define ISPCCDC_COLPTN_Gb_G 0x2
-#define ISPCCDC_COLPTN_B_Mg 0x3
-#define ISPCCDC_COLPTN_CP0PLC0_SHIFT 0
-#define ISPCCDC_COLPTN_CP0PLC1_SHIFT 2
-#define ISPCCDC_COLPTN_CP0PLC2_SHIFT 4
-#define ISPCCDC_COLPTN_CP0PLC3_SHIFT 6
-#define ISPCCDC_COLPTN_CP1PLC0_SHIFT 8
-#define ISPCCDC_COLPTN_CP1PLC1_SHIFT 10
-#define ISPCCDC_COLPTN_CP1PLC2_SHIFT 12
-#define ISPCCDC_COLPTN_CP1PLC3_SHIFT 14
-#define ISPCCDC_COLPTN_CP2PLC0_SHIFT 16
-#define ISPCCDC_COLPTN_CP2PLC1_SHIFT 18
-#define ISPCCDC_COLPTN_CP2PLC2_SHIFT 20
-#define ISPCCDC_COLPTN_CP2PLC3_SHIFT 22
-#define ISPCCDC_COLPTN_CP3PLC0_SHIFT 24
-#define ISPCCDC_COLPTN_CP3PLC1_SHIFT 26
-#define ISPCCDC_COLPTN_CP3PLC2_SHIFT 28
-#define ISPCCDC_COLPTN_CP3PLC3_SHIFT 30
-
-#define ISPCCDC_BLKCMP_B_MG_SHIFT 0
-#define ISPCCDC_BLKCMP_GB_G_SHIFT 8
-#define ISPCCDC_BLKCMP_GR_CY_SHIFT 16
-#define ISPCCDC_BLKCMP_R_YE_SHIFT 24
-
-#define ISPCCDC_FPC_FPNUM_SHIFT 0
-#define ISPCCDC_FPC_FPCEN (1 << 15)
-#define ISPCCDC_FPC_FPERR (1 << 16)
-
-#define ISPCCDC_VDINT_1_SHIFT 0
-#define ISPCCDC_VDINT_1_MASK 0x00007fff
-#define ISPCCDC_VDINT_0_SHIFT 16
-#define ISPCCDC_VDINT_0_MASK 0x7fff0000
-
-#define ISPCCDC_ALAW_GWDI_12_3 (0x3 << 0)
-#define ISPCCDC_ALAW_GWDI_11_2 (0x4 << 0)
-#define ISPCCDC_ALAW_GWDI_10_1 (0x5 << 0)
-#define ISPCCDC_ALAW_GWDI_9_0 (0x6 << 0)
-#define ISPCCDC_ALAW_CCDTBL (1 << 3)
-
-#define ISPCCDC_REC656IF_R656ON 1
-#define ISPCCDC_REC656IF_ECCFVH (1 << 1)
-
-#define ISPCCDC_CFG_BW656 (1 << 5)
-#define ISPCCDC_CFG_FIDMD_SHIFT 6
-#define ISPCCDC_CFG_WENLOG (1 << 8)
-#define ISPCCDC_CFG_WENLOG_AND (0 << 8)
-#define ISPCCDC_CFG_WENLOG_OR (1 << 8)
-#define ISPCCDC_CFG_Y8POS (1 << 11)
-#define ISPCCDC_CFG_BSWD (1 << 12)
-#define ISPCCDC_CFG_MSBINVI (1 << 13)
-#define ISPCCDC_CFG_VDLC (1 << 15)
-
-#define ISPCCDC_FMTCFG_FMTEN 0x1
-#define ISPCCDC_FMTCFG_LNALT (1 << 1)
-#define ISPCCDC_FMTCFG_LNUM_SHIFT 2
-#define ISPCCDC_FMTCFG_PLEN_ODD_SHIFT 4
-#define ISPCCDC_FMTCFG_PLEN_EVEN_SHIFT 8
-#define ISPCCDC_FMTCFG_VPIN_MASK 0x00007000
-#define ISPCCDC_FMTCFG_VPIN_12_3 (0x3 << 12)
-#define ISPCCDC_FMTCFG_VPIN_11_2 (0x4 << 12)
-#define ISPCCDC_FMTCFG_VPIN_10_1 (0x5 << 12)
-#define ISPCCDC_FMTCFG_VPIN_9_0 (0x6 << 12)
-#define ISPCCDC_FMTCFG_VPEN (1 << 15)
-
-#define ISPCCDC_FMTCFG_VPIF_FRQ_MASK 0x003f0000
-#define ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT 16
-#define ISPCCDC_FMTCFG_VPIF_FRQ_BY2 (0x0 << 16)
-#define ISPCCDC_FMTCFG_VPIF_FRQ_BY3 (0x1 << 16)
-#define ISPCCDC_FMTCFG_VPIF_FRQ_BY4 (0x2 << 16)
-#define ISPCCDC_FMTCFG_VPIF_FRQ_BY5 (0x3 << 16)
-#define ISPCCDC_FMTCFG_VPIF_FRQ_BY6 (0x4 << 16)
-
-#define ISPCCDC_FMT_HORZ_FMTLNH_SHIFT 0
-#define ISPCCDC_FMT_HORZ_FMTSPH_SHIFT 16
-
-#define ISPCCDC_FMT_VERT_FMTLNV_SHIFT 0
-#define ISPCCDC_FMT_VERT_FMTSLV_SHIFT 16
-
-#define ISPCCDC_FMT_HORZ_FMTSPH_MASK 0x1fff0000
-#define ISPCCDC_FMT_HORZ_FMTLNH_MASK 0x00001fff
-
-#define ISPCCDC_FMT_VERT_FMTSLV_MASK 0x1fff0000
-#define ISPCCDC_FMT_VERT_FMTLNV_MASK 0x00001fff
-
-#define ISPCCDC_VP_OUT_HORZ_ST_SHIFT 0
-#define ISPCCDC_VP_OUT_HORZ_NUM_SHIFT 4
-#define ISPCCDC_VP_OUT_VERT_NUM_SHIFT 17
-
-#define ISPRSZ_PID_PREV_SHIFT 0
-#define ISPRSZ_PID_CID_SHIFT 8
-#define ISPRSZ_PID_TID_SHIFT 16
-
-#define ISPRSZ_PCR_ENABLE (1 << 0)
-#define ISPRSZ_PCR_BUSY (1 << 1)
-#define ISPRSZ_PCR_ONESHOT (1 << 2)
-
-#define ISPRSZ_CNT_HRSZ_SHIFT 0
-#define ISPRSZ_CNT_HRSZ_MASK \
- (0x3FF << ISPRSZ_CNT_HRSZ_SHIFT)
-#define ISPRSZ_CNT_VRSZ_SHIFT 10
-#define ISPRSZ_CNT_VRSZ_MASK \
- (0x3FF << ISPRSZ_CNT_VRSZ_SHIFT)
-#define ISPRSZ_CNT_HSTPH_SHIFT 20
-#define ISPRSZ_CNT_HSTPH_MASK (0x7 << ISPRSZ_CNT_HSTPH_SHIFT)
-#define ISPRSZ_CNT_VSTPH_SHIFT 23
-#define ISPRSZ_CNT_VSTPH_MASK (0x7 << ISPRSZ_CNT_VSTPH_SHIFT)
-#define ISPRSZ_CNT_YCPOS (1 << 26)
-#define ISPRSZ_CNT_INPTYP (1 << 27)
-#define ISPRSZ_CNT_INPSRC (1 << 28)
-#define ISPRSZ_CNT_CBILIN (1 << 29)
-
-#define ISPRSZ_OUT_SIZE_HORZ_SHIFT 0
-#define ISPRSZ_OUT_SIZE_HORZ_MASK \
- (0xFFF << ISPRSZ_OUT_SIZE_HORZ_SHIFT)
-#define ISPRSZ_OUT_SIZE_VERT_SHIFT 16
-#define ISPRSZ_OUT_SIZE_VERT_MASK \
- (0xFFF << ISPRSZ_OUT_SIZE_VERT_SHIFT)
-
-#define ISPRSZ_IN_START_HORZ_ST_SHIFT 0
-#define ISPRSZ_IN_START_HORZ_ST_MASK \
- (0x1FFF << ISPRSZ_IN_START_HORZ_ST_SHIFT)
-#define ISPRSZ_IN_START_VERT_ST_SHIFT 16
-#define ISPRSZ_IN_START_VERT_ST_MASK \
- (0x1FFF << ISPRSZ_IN_START_VERT_ST_SHIFT)
-
-#define ISPRSZ_IN_SIZE_HORZ_SHIFT 0
-#define ISPRSZ_IN_SIZE_HORZ_MASK \
- (0x1FFF << ISPRSZ_IN_SIZE_HORZ_SHIFT)
-#define ISPRSZ_IN_SIZE_VERT_SHIFT 16
-#define ISPRSZ_IN_SIZE_VERT_MASK \
- (0x1FFF << ISPRSZ_IN_SIZE_VERT_SHIFT)
-
-#define ISPRSZ_SDR_INADD_ADDR_SHIFT 0
-#define ISPRSZ_SDR_INADD_ADDR_MASK 0xFFFFFFFF
-
-#define ISPRSZ_SDR_INOFF_OFFSET_SHIFT 0
-#define ISPRSZ_SDR_INOFF_OFFSET_MASK \
- (0xFFFF << ISPRSZ_SDR_INOFF_OFFSET_SHIFT)
-
-#define ISPRSZ_SDR_OUTADD_ADDR_SHIFT 0
-#define ISPRSZ_SDR_OUTADD_ADDR_MASK 0xFFFFFFFF
-
-
-#define ISPRSZ_SDR_OUTOFF_OFFSET_SHIFT 0
-#define ISPRSZ_SDR_OUTOFF_OFFSET_MASK \
- (0xFFFF << ISPRSZ_SDR_OUTOFF_OFFSET_SHIFT)
-
-#define ISPRSZ_HFILT_COEF0_SHIFT 0
-#define ISPRSZ_HFILT_COEF0_MASK \
- (0x3FF << ISPRSZ_HFILT_COEF0_SHIFT)
-#define ISPRSZ_HFILT_COEF1_SHIFT 16
-#define ISPRSZ_HFILT_COEF1_MASK \
- (0x3FF << ISPRSZ_HFILT_COEF1_SHIFT)
-
-#define ISPRSZ_HFILT32_COEF2_SHIFT 0
-#define ISPRSZ_HFILT32_COEF2_MASK 0x3FF
-#define ISPRSZ_HFILT32_COEF3_SHIFT 16
-#define ISPRSZ_HFILT32_COEF3_MASK 0x3FF0000
-
-#define ISPRSZ_HFILT54_COEF4_SHIFT 0
-#define ISPRSZ_HFILT54_COEF4_MASK 0x3FF
-#define ISPRSZ_HFILT54_COEF5_SHIFT 16
-#define ISPRSZ_HFILT54_COEF5_MASK 0x3FF0000
-
-#define ISPRSZ_HFILT76_COEFF6_SHIFT 0
-#define ISPRSZ_HFILT76_COEFF6_MASK 0x3FF
-#define ISPRSZ_HFILT76_COEFF7_SHIFT 16
-#define ISPRSZ_HFILT76_COEFF7_MASK 0x3FF0000
-
-#define ISPRSZ_HFILT98_COEFF8_SHIFT 0
-#define ISPRSZ_HFILT98_COEFF8_MASK 0x3FF
-#define ISPRSZ_HFILT98_COEFF9_SHIFT 16
-#define ISPRSZ_HFILT98_COEFF9_MASK 0x3FF0000
-
-#define ISPRSZ_HFILT1110_COEF10_SHIFT 0
-#define ISPRSZ_HFILT1110_COEF10_MASK 0x3FF
-#define ISPRSZ_HFILT1110_COEF11_SHIFT 16
-#define ISPRSZ_HFILT1110_COEF11_MASK 0x3FF0000
-
-#define ISPRSZ_HFILT1312_COEFF12_SHIFT 0
-#define ISPRSZ_HFILT1312_COEFF12_MASK 0x3FF
-#define ISPRSZ_HFILT1312_COEFF13_SHIFT 16
-#define ISPRSZ_HFILT1312_COEFF13_MASK 0x3FF0000
-
-#define ISPRSZ_HFILT1514_COEFF14_SHIFT 0
-#define ISPRSZ_HFILT1514_COEFF14_MASK 0x3FF
-#define ISPRSZ_HFILT1514_COEFF15_SHIFT 16
-#define ISPRSZ_HFILT1514_COEFF15_MASK 0x3FF0000
-
-#define ISPRSZ_HFILT1716_COEF16_SHIFT 0
-#define ISPRSZ_HFILT1716_COEF16_MASK 0x3FF
-#define ISPRSZ_HFILT1716_COEF17_SHIFT 16
-#define ISPRSZ_HFILT1716_COEF17_MASK 0x3FF0000
-
-#define ISPRSZ_HFILT1918_COEF18_SHIFT 0
-#define ISPRSZ_HFILT1918_COEF18_MASK 0x3FF
-#define ISPRSZ_HFILT1918_COEF19_SHIFT 16
-#define ISPRSZ_HFILT1918_COEF19_MASK 0x3FF0000
-
-#define ISPRSZ_HFILT2120_COEF20_SHIFT 0
-#define ISPRSZ_HFILT2120_COEF20_MASK 0x3FF
-#define ISPRSZ_HFILT2120_COEF21_SHIFT 16
-#define ISPRSZ_HFILT2120_COEF21_MASK 0x3FF0000
-
-#define ISPRSZ_HFILT2322_COEF22_SHIFT 0
-#define ISPRSZ_HFILT2322_COEF22_MASK 0x3FF
-#define ISPRSZ_HFILT2322_COEF23_SHIFT 16
-#define ISPRSZ_HFILT2322_COEF23_MASK 0x3FF0000
-
-#define ISPRSZ_HFILT2524_COEF24_SHIFT 0
-#define ISPRSZ_HFILT2524_COEF24_MASK 0x3FF
-#define ISPRSZ_HFILT2524_COEF25_SHIFT 16
-#define ISPRSZ_HFILT2524_COEF25_MASK 0x3FF0000
-
-#define ISPRSZ_HFILT2726_COEF26_SHIFT 0
-#define ISPRSZ_HFILT2726_COEF26_MASK 0x3FF
-#define ISPRSZ_HFILT2726_COEF27_SHIFT 16
-#define ISPRSZ_HFILT2726_COEF27_MASK 0x3FF0000
-
-#define ISPRSZ_HFILT2928_COEF28_SHIFT 0
-#define ISPRSZ_HFILT2928_COEF28_MASK 0x3FF
-#define ISPRSZ_HFILT2928_COEF29_SHIFT 16
-#define ISPRSZ_HFILT2928_COEF29_MASK 0x3FF0000
-
-#define ISPRSZ_HFILT3130_COEF30_SHIFT 0
-#define ISPRSZ_HFILT3130_COEF30_MASK 0x3FF
-#define ISPRSZ_HFILT3130_COEF31_SHIFT 16
-#define ISPRSZ_HFILT3130_COEF31_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT_COEF0_SHIFT 0
-#define ISPRSZ_VFILT_COEF0_MASK \
- (0x3FF << ISPRSZ_VFILT_COEF0_SHIFT)
-#define ISPRSZ_VFILT_COEF1_SHIFT 16
-#define ISPRSZ_VFILT_COEF1_MASK \
- (0x3FF << ISPRSZ_VFILT_COEF1_SHIFT)
-
-#define ISPRSZ_VFILT10_COEF0_SHIFT 0
-#define ISPRSZ_VFILT10_COEF0_MASK 0x3FF
-#define ISPRSZ_VFILT10_COEF1_SHIFT 16
-#define ISPRSZ_VFILT10_COEF1_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT32_COEF2_SHIFT 0
-#define ISPRSZ_VFILT32_COEF2_MASK 0x3FF
-#define ISPRSZ_VFILT32_COEF3_SHIFT 16
-#define ISPRSZ_VFILT32_COEF3_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT54_COEF4_SHIFT 0
-#define ISPRSZ_VFILT54_COEF4_MASK 0x3FF
-#define ISPRSZ_VFILT54_COEF5_SHIFT 16
-#define ISPRSZ_VFILT54_COEF5_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT76_COEFF6_SHIFT 0
-#define ISPRSZ_VFILT76_COEFF6_MASK 0x3FF
-#define ISPRSZ_VFILT76_COEFF7_SHIFT 16
-#define ISPRSZ_VFILT76_COEFF7_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT98_COEFF8_SHIFT 0
-#define ISPRSZ_VFILT98_COEFF8_MASK 0x3FF
-#define ISPRSZ_VFILT98_COEFF9_SHIFT 16
-#define ISPRSZ_VFILT98_COEFF9_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT1110_COEF10_SHIFT 0
-#define ISPRSZ_VFILT1110_COEF10_MASK 0x3FF
-#define ISPRSZ_VFILT1110_COEF11_SHIFT 16
-#define ISPRSZ_VFILT1110_COEF11_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT1312_COEFF12_SHIFT 0
-#define ISPRSZ_VFILT1312_COEFF12_MASK 0x3FF
-#define ISPRSZ_VFILT1312_COEFF13_SHIFT 16
-#define ISPRSZ_VFILT1312_COEFF13_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT1514_COEFF14_SHIFT 0
-#define ISPRSZ_VFILT1514_COEFF14_MASK 0x3FF
-#define ISPRSZ_VFILT1514_COEFF15_SHIFT 16
-#define ISPRSZ_VFILT1514_COEFF15_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT1716_COEF16_SHIFT 0
-#define ISPRSZ_VFILT1716_COEF16_MASK 0x3FF
-#define ISPRSZ_VFILT1716_COEF17_SHIFT 16
-#define ISPRSZ_VFILT1716_COEF17_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT1918_COEF18_SHIFT 0
-#define ISPRSZ_VFILT1918_COEF18_MASK 0x3FF
-#define ISPRSZ_VFILT1918_COEF19_SHIFT 16
-#define ISPRSZ_VFILT1918_COEF19_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT2120_COEF20_SHIFT 0
-#define ISPRSZ_VFILT2120_COEF20_MASK 0x3FF
-#define ISPRSZ_VFILT2120_COEF21_SHIFT 16
-#define ISPRSZ_VFILT2120_COEF21_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT2322_COEF22_SHIFT 0
-#define ISPRSZ_VFILT2322_COEF22_MASK 0x3FF
-#define ISPRSZ_VFILT2322_COEF23_SHIFT 16
-#define ISPRSZ_VFILT2322_COEF23_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT2524_COEF24_SHIFT 0
-#define ISPRSZ_VFILT2524_COEF24_MASK 0x3FF
-#define ISPRSZ_VFILT2524_COEF25_SHIFT 16
-#define ISPRSZ_VFILT2524_COEF25_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT2726_COEF26_SHIFT 0
-#define ISPRSZ_VFILT2726_COEF26_MASK 0x3FF
-#define ISPRSZ_VFILT2726_COEF27_SHIFT 16
-#define ISPRSZ_VFILT2726_COEF27_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT2928_COEF28_SHIFT 0
-#define ISPRSZ_VFILT2928_COEF28_MASK 0x3FF
-#define ISPRSZ_VFILT2928_COEF29_SHIFT 16
-#define ISPRSZ_VFILT2928_COEF29_MASK 0x3FF0000
-
-#define ISPRSZ_VFILT3130_COEF30_SHIFT 0
-#define ISPRSZ_VFILT3130_COEF30_MASK 0x3FF
-#define ISPRSZ_VFILT3130_COEF31_SHIFT 16
-#define ISPRSZ_VFILT3130_COEF31_MASK 0x3FF0000
-
-#define ISPRSZ_YENH_CORE_SHIFT 0
-#define ISPRSZ_YENH_CORE_MASK \
- (0xFF << ISPRSZ_YENH_CORE_SHIFT)
-#define ISPRSZ_YENH_SLOP_SHIFT 8
-#define ISPRSZ_YENH_SLOP_MASK \
- (0xF << ISPRSZ_YENH_SLOP_SHIFT)
-#define ISPRSZ_YENH_GAIN_SHIFT 12
-#define ISPRSZ_YENH_GAIN_MASK \
- (0xF << ISPRSZ_YENH_GAIN_SHIFT)
-#define ISPRSZ_YENH_ALGO_SHIFT 16
-#define ISPRSZ_YENH_ALGO_MASK \
- (0x3 << ISPRSZ_YENH_ALGO_SHIFT)
-
-#define ISPH3A_PCR_AEW_ALAW_EN_SHIFT 1
-#define ISPH3A_PCR_AF_MED_TH_SHIFT 3
-#define ISPH3A_PCR_AF_RGBPOS_SHIFT 11
-#define ISPH3A_PCR_AEW_AVE2LMT_SHIFT 22
-#define ISPH3A_PCR_AEW_AVE2LMT_MASK 0xFFC00000
-#define ISPH3A_PCR_BUSYAF (1 << 15)
-#define ISPH3A_PCR_BUSYAEAWB (1 << 18)
-
-#define ISPH3A_AEWWIN1_WINHC_SHIFT 0
-#define ISPH3A_AEWWIN1_WINHC_MASK 0x3F
-#define ISPH3A_AEWWIN1_WINVC_SHIFT 6
-#define ISPH3A_AEWWIN1_WINVC_MASK 0x1FC0
-#define ISPH3A_AEWWIN1_WINW_SHIFT 13
-#define ISPH3A_AEWWIN1_WINW_MASK 0xFE000
-#define ISPH3A_AEWWIN1_WINH_SHIFT 24
-#define ISPH3A_AEWWIN1_WINH_MASK 0x7F000000
-
-#define ISPH3A_AEWINSTART_WINSH_SHIFT 0
-#define ISPH3A_AEWINSTART_WINSH_MASK 0x0FFF
-#define ISPH3A_AEWINSTART_WINSV_SHIFT 16
-#define ISPH3A_AEWINSTART_WINSV_MASK 0x0FFF0000
-
-#define ISPH3A_AEWINBLK_WINH_SHIFT 0
-#define ISPH3A_AEWINBLK_WINH_MASK 0x7F
-#define ISPH3A_AEWINBLK_WINSV_SHIFT 16
-#define ISPH3A_AEWINBLK_WINSV_MASK 0x0FFF0000
-
-#define ISPH3A_AEWSUBWIN_AEWINCH_SHIFT 0
-#define ISPH3A_AEWSUBWIN_AEWINCH_MASK 0x0F
-#define ISPH3A_AEWSUBWIN_AEWINCV_SHIFT 8
-#define ISPH3A_AEWSUBWIN_AEWINCV_MASK 0x0F00
-
-#define ISPHIST_PCR_ENABLE_SHIFT 0
-#define ISPHIST_PCR_ENABLE_MASK 0x01
-#define ISPHIST_PCR_ENABLE (1 << ISPHIST_PCR_ENABLE_SHIFT)
-#define ISPHIST_PCR_BUSY 0x02
-
-#define ISPHIST_CNT_DATASIZE_SHIFT 8
-#define ISPHIST_CNT_DATASIZE_MASK 0x0100
-#define ISPHIST_CNT_CLEAR_SHIFT 7
-#define ISPHIST_CNT_CLEAR_MASK 0x080
-#define ISPHIST_CNT_CLEAR (1 << ISPHIST_CNT_CLEAR_SHIFT)
-#define ISPHIST_CNT_CFA_SHIFT 6
-#define ISPHIST_CNT_CFA_MASK 0x040
-#define ISPHIST_CNT_BINS_SHIFT 4
-#define ISPHIST_CNT_BINS_MASK 0x030
-#define ISPHIST_CNT_SOURCE_SHIFT 3
-#define ISPHIST_CNT_SOURCE_MASK 0x08
-#define ISPHIST_CNT_SHIFT_SHIFT 0
-#define ISPHIST_CNT_SHIFT_MASK 0x07
-
-#define ISPHIST_WB_GAIN_WG00_SHIFT 24
-#define ISPHIST_WB_GAIN_WG00_MASK 0xFF000000
-#define ISPHIST_WB_GAIN_WG01_SHIFT 16
-#define ISPHIST_WB_GAIN_WG01_MASK 0xFF0000
-#define ISPHIST_WB_GAIN_WG02_SHIFT 8
-#define ISPHIST_WB_GAIN_WG02_MASK 0xFF00
-#define ISPHIST_WB_GAIN_WG03_SHIFT 0
-#define ISPHIST_WB_GAIN_WG03_MASK 0xFF
-
-#define ISPHIST_REG_START_END_MASK 0x3FFF
-#define ISPHIST_REG_START_SHIFT 16
-#define ISPHIST_REG_END_SHIFT 0
-#define ISPHIST_REG_START_MASK (ISPHIST_REG_START_END_MASK << \
- ISPHIST_REG_START_SHIFT)
-#define ISPHIST_REG_END_MASK (ISPHIST_REG_START_END_MASK << \
- ISPHIST_REG_END_SHIFT)
-
-#define ISPHIST_REG_MASK (ISPHIST_REG_START_MASK | \
- ISPHIST_REG_END_MASK)
-
-#define ISPHIST_ADDR_SHIFT 0
-#define ISPHIST_ADDR_MASK 0x3FF
-
-#define ISPHIST_DATA_SHIFT 0
-#define ISPHIST_DATA_MASK 0xFFFFF
-
-#define ISPHIST_RADD_SHIFT 0
-#define ISPHIST_RADD_MASK 0xFFFFFFFF
-
-#define ISPHIST_RADD_OFF_SHIFT 0
-#define ISPHIST_RADD_OFF_MASK 0xFFFF
-
-#define ISPHIST_HV_INFO_HSIZE_SHIFT 16
-#define ISPHIST_HV_INFO_HSIZE_MASK 0x3FFF0000
-#define ISPHIST_HV_INFO_VSIZE_SHIFT 0
-#define ISPHIST_HV_INFO_VSIZE_MASK 0x3FFF
-
-#define ISPHIST_HV_INFO_MASK 0x3FFF3FFF
-
-#define ISPCCDC_LSC_ENABLE 1
-#define ISPCCDC_LSC_BUSY (1 << 7)
-#define ISPCCDC_LSC_GAIN_MODE_N_MASK 0x700
-#define ISPCCDC_LSC_GAIN_MODE_N_SHIFT 8
-#define ISPCCDC_LSC_GAIN_MODE_M_MASK 0x3800
-#define ISPCCDC_LSC_GAIN_MODE_M_SHIFT 12
-#define ISPCCDC_LSC_GAIN_FORMAT_MASK 0xE
-#define ISPCCDC_LSC_GAIN_FORMAT_SHIFT 1
-#define ISPCCDC_LSC_AFTER_REFORMATTER_MASK (1<<6)
-
-#define ISPCCDC_LSC_INITIAL_X_MASK 0x3F
-#define ISPCCDC_LSC_INITIAL_X_SHIFT 0
-#define ISPCCDC_LSC_INITIAL_Y_MASK 0x3F0000
-#define ISPCCDC_LSC_INITIAL_Y_SHIFT 16
-
-/* -----------------------------------------------------------------------------
- * CSI2 receiver registers (ES2.0)
- */
-
-#define ISPCSI2_REVISION (0x000)
-#define ISPCSI2_SYSCONFIG (0x010)
-#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT 12
-#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK \
- (0x3 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
-#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_FORCE \
- (0x0 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
-#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_NO \
- (0x1 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
-#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SMART \
- (0x2 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
-#define ISPCSI2_SYSCONFIG_SOFT_RESET (1 << 1)
-#define ISPCSI2_SYSCONFIG_AUTO_IDLE (1 << 0)
-
-#define ISPCSI2_SYSSTATUS (0x014)
-#define ISPCSI2_SYSSTATUS_RESET_DONE (1 << 0)
-
-#define ISPCSI2_IRQSTATUS (0x018)
-#define ISPCSI2_IRQSTATUS_OCP_ERR_IRQ (1 << 14)
-#define ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ (1 << 13)
-#define ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ (1 << 12)
-#define ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ (1 << 11)
-#define ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ (1 << 10)
-#define ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ (1 << 9)
-#define ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ (1 << 8)
-#define ISPCSI2_IRQSTATUS_CONTEXT(n) (1 << (n))
-
-#define ISPCSI2_IRQENABLE (0x01c)
-#define ISPCSI2_CTRL (0x040)
-#define ISPCSI2_CTRL_VP_CLK_EN (1 << 15)
-#define ISPCSI2_CTRL_VP_ONLY_EN (1 << 11)
-#define ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT 8
-#define ISPCSI2_CTRL_VP_OUT_CTRL_MASK \
- (3 << ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT)
-#define ISPCSI2_CTRL_DBG_EN (1 << 7)
-#define ISPCSI2_CTRL_BURST_SIZE_SHIFT 5
-#define ISPCSI2_CTRL_BURST_SIZE_MASK \
- (3 << ISPCSI2_CTRL_BURST_SIZE_SHIFT)
-#define ISPCSI2_CTRL_FRAME (1 << 3)
-#define ISPCSI2_CTRL_ECC_EN (1 << 2)
-#define ISPCSI2_CTRL_SECURE (1 << 1)
-#define ISPCSI2_CTRL_IF_EN (1 << 0)
-
-#define ISPCSI2_DBG_H (0x044)
-#define ISPCSI2_GNQ (0x048)
-#define ISPCSI2_PHY_CFG (0x050)
-#define ISPCSI2_PHY_CFG_RESET_CTRL (1 << 30)
-#define ISPCSI2_PHY_CFG_RESET_DONE (1 << 29)
-#define ISPCSI2_PHY_CFG_PWR_CMD_SHIFT 27
-#define ISPCSI2_PHY_CFG_PWR_CMD_MASK \
- (0x3 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
-#define ISPCSI2_PHY_CFG_PWR_CMD_OFF \
- (0x0 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
-#define ISPCSI2_PHY_CFG_PWR_CMD_ON \
- (0x1 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
-#define ISPCSI2_PHY_CFG_PWR_CMD_ULPW \
- (0x2 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
-#define ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT 25
-#define ISPCSI2_PHY_CFG_PWR_STATUS_MASK \
- (0x3 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
-#define ISPCSI2_PHY_CFG_PWR_STATUS_OFF \
- (0x0 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
-#define ISPCSI2_PHY_CFG_PWR_STATUS_ON \
- (0x1 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
-#define ISPCSI2_PHY_CFG_PWR_STATUS_ULPW \
- (0x2 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
-#define ISPCSI2_PHY_CFG_PWR_AUTO (1 << 24)
-
-#define ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n) (3 + ((n) * 4))
-#define ISPCSI2_PHY_CFG_DATA_POL_MASK(n) \
- (0x1 << ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n))
-#define ISPCSI2_PHY_CFG_DATA_POL_PN(n) \
- (0x0 << ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n))
-#define ISPCSI2_PHY_CFG_DATA_POL_NP(n) \
- (0x1 << ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n))
-
-#define ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n) ((n) * 4)
-#define ISPCSI2_PHY_CFG_DATA_POSITION_MASK(n) \
- (0x7 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
-#define ISPCSI2_PHY_CFG_DATA_POSITION_NC(n) \
- (0x0 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
-#define ISPCSI2_PHY_CFG_DATA_POSITION_1(n) \
- (0x1 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
-#define ISPCSI2_PHY_CFG_DATA_POSITION_2(n) \
- (0x2 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
-#define ISPCSI2_PHY_CFG_DATA_POSITION_3(n) \
- (0x3 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
-#define ISPCSI2_PHY_CFG_DATA_POSITION_4(n) \
- (0x4 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
-#define ISPCSI2_PHY_CFG_DATA_POSITION_5(n) \
- (0x5 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
-
-#define ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT 3
-#define ISPCSI2_PHY_CFG_CLOCK_POL_MASK \
- (0x1 << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT)
-#define ISPCSI2_PHY_CFG_CLOCK_POL_PN \
- (0x0 << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT)
-#define ISPCSI2_PHY_CFG_CLOCK_POL_NP \
- (0x1 << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT)
-
-#define ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT 0
-#define ISPCSI2_PHY_CFG_CLOCK_POSITION_MASK \
- (0x7 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
-#define ISPCSI2_PHY_CFG_CLOCK_POSITION_1 \
- (0x1 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
-#define ISPCSI2_PHY_CFG_CLOCK_POSITION_2 \
- (0x2 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
-#define ISPCSI2_PHY_CFG_CLOCK_POSITION_3 \
- (0x3 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
-#define ISPCSI2_PHY_CFG_CLOCK_POSITION_4 \
- (0x4 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
-#define ISPCSI2_PHY_CFG_CLOCK_POSITION_5 \
- (0x5 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
-
-#define ISPCSI2_PHY_IRQSTATUS (0x054)
-#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMEXIT (1 << 26)
-#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMENTER (1 << 25)
-#define ISPCSI2_PHY_IRQSTATUS_STATEULPM5 (1 << 24)
-#define ISPCSI2_PHY_IRQSTATUS_STATEULPM4 (1 << 23)
-#define ISPCSI2_PHY_IRQSTATUS_STATEULPM3 (1 << 22)
-#define ISPCSI2_PHY_IRQSTATUS_STATEULPM2 (1 << 21)
-#define ISPCSI2_PHY_IRQSTATUS_STATEULPM1 (1 << 20)
-#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL5 (1 << 19)
-#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL4 (1 << 18)
-#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL3 (1 << 17)
-#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL2 (1 << 16)
-#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL1 (1 << 15)
-#define ISPCSI2_PHY_IRQSTATUS_ERRESC5 (1 << 14)
-#define ISPCSI2_PHY_IRQSTATUS_ERRESC4 (1 << 13)
-#define ISPCSI2_PHY_IRQSTATUS_ERRESC3 (1 << 12)
-#define ISPCSI2_PHY_IRQSTATUS_ERRESC2 (1 << 11)
-#define ISPCSI2_PHY_IRQSTATUS_ERRESC1 (1 << 10)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS5 (1 << 9)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS4 (1 << 8)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS3 (1 << 7)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS2 (1 << 6)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS1 (1 << 5)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS5 (1 << 4)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS4 (1 << 3)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS3 (1 << 2)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS2 (1 << 1)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS1 1
-
-#define ISPCSI2_SHORT_PACKET (0x05c)
-#define ISPCSI2_PHY_IRQENABLE (0x060)
-#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMEXIT (1 << 26)
-#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMENTER (1 << 25)
-#define ISPCSI2_PHY_IRQENABLE_STATEULPM5 (1 << 24)
-#define ISPCSI2_PHY_IRQENABLE_STATEULPM4 (1 << 23)
-#define ISPCSI2_PHY_IRQENABLE_STATEULPM3 (1 << 22)
-#define ISPCSI2_PHY_IRQENABLE_STATEULPM2 (1 << 21)
-#define ISPCSI2_PHY_IRQENABLE_STATEULPM1 (1 << 20)
-#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL5 (1 << 19)
-#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL4 (1 << 18)
-#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL3 (1 << 17)
-#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL2 (1 << 16)
-#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL1 (1 << 15)
-#define ISPCSI2_PHY_IRQENABLE_ERRESC5 (1 << 14)
-#define ISPCSI2_PHY_IRQENABLE_ERRESC4 (1 << 13)
-#define ISPCSI2_PHY_IRQENABLE_ERRESC3 (1 << 12)
-#define ISPCSI2_PHY_IRQENABLE_ERRESC2 (1 << 11)
-#define ISPCSI2_PHY_IRQENABLE_ERRESC1 (1 << 10)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS5 (1 << 9)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS4 (1 << 8)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS3 (1 << 7)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS2 (1 << 6)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS1 (1 << 5)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS5 (1 << 4)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS4 (1 << 3)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS3 (1 << 2)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS2 (1 << 1)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS1 (1 << 0)
-
-#define ISPCSI2_DBG_P (0x068)
-#define ISPCSI2_TIMING (0x06c)
-#define ISPCSI2_TIMING_FORCE_RX_MODE_IO(n) (1 << ((16 * ((n) - 1)) + 15))
-#define ISPCSI2_TIMING_STOP_STATE_X16_IO(n) (1 << ((16 * ((n) - 1)) + 14))
-#define ISPCSI2_TIMING_STOP_STATE_X4_IO(n) (1 << ((16 * ((n) - 1)) + 13))
-#define ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(n) (16 * ((n) - 1))
-#define ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(n) \
- (0x1fff << ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(n))
-
-#define ISPCSI2_CTX_CTRL1(n) ((0x070) + 0x20 * (n))
-#define ISPCSI2_CTX_CTRL1_COUNT_SHIFT 8
-#define ISPCSI2_CTX_CTRL1_COUNT_MASK \
- (0xff << ISPCSI2_CTX_CTRL1_COUNT_SHIFT)
-#define ISPCSI2_CTX_CTRL1_EOF_EN (1 << 7)
-#define ISPCSI2_CTX_CTRL1_EOL_EN (1 << 6)
-#define ISPCSI2_CTX_CTRL1_CS_EN (1 << 5)
-#define ISPCSI2_CTX_CTRL1_COUNT_UNLOCK (1 << 4)
-#define ISPCSI2_CTX_CTRL1_PING_PONG (1 << 3)
-#define ISPCSI2_CTX_CTRL1_CTX_EN (1 << 0)
-
-#define ISPCSI2_CTX_CTRL2(n) ((0x074) + 0x20 * (n))
-#define ISPCSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT 13
-#define ISPCSI2_CTX_CTRL2_USER_DEF_MAP_MASK \
- (0x3 << ISPCSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT)
-#define ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT 11
-#define ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK \
- (0x3 << ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT)
-#define ISPCSI2_CTX_CTRL2_DPCM_PRED (1 << 10)
-#define ISPCSI2_CTX_CTRL2_FORMAT_SHIFT 0
-#define ISPCSI2_CTX_CTRL2_FORMAT_MASK \
- (0x3ff << ISPCSI2_CTX_CTRL2_FORMAT_SHIFT)
-#define ISPCSI2_CTX_CTRL2_FRAME_SHIFT 16
-#define ISPCSI2_CTX_CTRL2_FRAME_MASK \
- (0xffff << ISPCSI2_CTX_CTRL2_FRAME_SHIFT)
-
-#define ISPCSI2_CTX_DAT_OFST(n) ((0x078) + 0x20 * (n))
-#define ISPCSI2_CTX_DAT_OFST_OFST_SHIFT 0
-#define ISPCSI2_CTX_DAT_OFST_OFST_MASK \
- (0x1ffe0 << ISPCSI2_CTX_DAT_OFST_OFST_SHIFT)
-
-#define ISPCSI2_CTX_DAT_PING_ADDR(n) ((0x07c) + 0x20 * (n))
-#define ISPCSI2_CTX_DAT_PONG_ADDR(n) ((0x080) + 0x20 * (n))
-#define ISPCSI2_CTX_IRQENABLE(n) ((0x084) + 0x20 * (n))
-#define ISPCSI2_CTX_IRQENABLE_ECC_CORRECTION_IRQ (1 << 8)
-#define ISPCSI2_CTX_IRQENABLE_LINE_NUMBER_IRQ (1 << 7)
-#define ISPCSI2_CTX_IRQENABLE_FRAME_NUMBER_IRQ (1 << 6)
-#define ISPCSI2_CTX_IRQENABLE_CS_IRQ (1 << 5)
-#define ISPCSI2_CTX_IRQENABLE_LE_IRQ (1 << 3)
-#define ISPCSI2_CTX_IRQENABLE_LS_IRQ (1 << 2)
-#define ISPCSI2_CTX_IRQENABLE_FE_IRQ (1 << 1)
-#define ISPCSI2_CTX_IRQENABLE_FS_IRQ (1 << 0)
-
-#define ISPCSI2_CTX_IRQSTATUS(n) ((0x088) + 0x20 * (n))
-#define ISPCSI2_CTX_IRQSTATUS_ECC_CORRECTION_IRQ (1 << 8)
-#define ISPCSI2_CTX_IRQSTATUS_LINE_NUMBER_IRQ (1 << 7)
-#define ISPCSI2_CTX_IRQSTATUS_FRAME_NUMBER_IRQ (1 << 6)
-#define ISPCSI2_CTX_IRQSTATUS_CS_IRQ (1 << 5)
-#define ISPCSI2_CTX_IRQSTATUS_LE_IRQ (1 << 3)
-#define ISPCSI2_CTX_IRQSTATUS_LS_IRQ (1 << 2)
-#define ISPCSI2_CTX_IRQSTATUS_FE_IRQ (1 << 1)
-#define ISPCSI2_CTX_IRQSTATUS_FS_IRQ (1 << 0)
-
-#define ISPCSI2_CTX_CTRL3(n) ((0x08c) + 0x20 * (n))
-#define ISPCSI2_CTX_CTRL3_ALPHA_SHIFT 5
-#define ISPCSI2_CTX_CTRL3_ALPHA_MASK \
- (0x3fff << ISPCSI2_CTX_CTRL3_ALPHA_SHIFT)
-
-/* This instance is for OMAP3630 only */
-#define ISPCSI2_CTX_TRANSCODEH(n) (0x000 + 0x8 * (n))
-#define ISPCSI2_CTX_TRANSCODEH_HCOUNT_SHIFT 16
-#define ISPCSI2_CTX_TRANSCODEH_HCOUNT_MASK \
- (0x1fff << ISPCSI2_CTX_TRANSCODEH_HCOUNT_SHIFT)
-#define ISPCSI2_CTX_TRANSCODEH_HSKIP_SHIFT 0
-#define ISPCSI2_CTX_TRANSCODEH_HSKIP_MASK \
- (0x1fff << ISPCSI2_CTX_TRANSCODEH_HCOUNT_SHIFT)
-#define ISPCSI2_CTX_TRANSCODEV(n) (0x004 + 0x8 * (n))
-#define ISPCSI2_CTX_TRANSCODEV_VCOUNT_SHIFT 16
-#define ISPCSI2_CTX_TRANSCODEV_VCOUNT_MASK \
- (0x1fff << ISPCSI2_CTX_TRANSCODEV_VCOUNT_SHIFT)
-#define ISPCSI2_CTX_TRANSCODEV_VSKIP_SHIFT 0
-#define ISPCSI2_CTX_TRANSCODEV_VSKIP_MASK \
- (0x1fff << ISPCSI2_CTX_TRANSCODEV_VCOUNT_SHIFT)
-
-/* -----------------------------------------------------------------------------
- * CSI PHY registers
- */
-
-#define ISPCSIPHY_REG0 (0x000)
-#define ISPCSIPHY_REG0_THS_TERM_SHIFT 8
-#define ISPCSIPHY_REG0_THS_TERM_MASK \
- (0xff << ISPCSIPHY_REG0_THS_TERM_SHIFT)
-#define ISPCSIPHY_REG0_THS_SETTLE_SHIFT 0
-#define ISPCSIPHY_REG0_THS_SETTLE_MASK \
- (0xff << ISPCSIPHY_REG0_THS_SETTLE_SHIFT)
-
-#define ISPCSIPHY_REG1 (0x004)
-#define ISPCSIPHY_REG1_RESET_DONE_CTRLCLK (1 << 29)
-/* This field is for OMAP3630 only */
-#define ISPCSIPHY_REG1_CLOCK_MISS_DETECTOR_STATUS (1 << 25)
-#define ISPCSIPHY_REG1_TCLK_TERM_SHIFT 18
-#define ISPCSIPHY_REG1_TCLK_TERM_MASK \
- (0x7f << ISPCSIPHY_REG1_TCLK_TERM_SHIFT)
-#define ISPCSIPHY_REG1_DPHY_HS_SYNC_PATTERN_SHIFT 10
-#define ISPCSIPHY_REG1_DPHY_HS_SYNC_PATTERN_MASK \
- (0xff << ISPCSIPHY_REG1_DPHY_HS_SYNC_PATTERN)
-/* This field is for OMAP3430 only */
-#define ISPCSIPHY_REG1_TCLK_MISS_SHIFT 8
-#define ISPCSIPHY_REG1_TCLK_MISS_MASK \
- (0x3 << ISPCSIPHY_REG1_TCLK_MISS_SHIFT)
-/* This field is for OMAP3630 only */
-#define ISPCSIPHY_REG1_CTRLCLK_DIV_FACTOR_SHIFT 8
-#define ISPCSIPHY_REG1_CTRLCLK_DIV_FACTOR_MASK \
- (0x3 << ISPCSIPHY_REG1_CTRLCLK_DIV_FACTOR_SHIFT)
-#define ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT 0
-#define ISPCSIPHY_REG1_TCLK_SETTLE_MASK \
- (0xff << ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT)
-
-/* This register is for OMAP3630 only */
-#define ISPCSIPHY_REG2 (0x008)
-#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC0_SHIFT 30
-#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC0_MASK \
- (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC0_SHIFT)
-#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC1_SHIFT 28
-#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC1_MASK \
- (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC1_SHIFT)
-#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC2_SHIFT 26
-#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC2_MASK \
- (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC2_SHIFT)
-#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC3_SHIFT 24
-#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC3_MASK \
- (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC3_SHIFT)
-#define ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_SHIFT 0
-#define ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_MASK \
- (0x7fffff << ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_SHIFT)
-
-#endif /* OMAP3_ISP_REG_H */
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c
deleted file mode 100644
index ae17d917f77..00000000000
--- a/drivers/media/video/omap3isp/ispresizer.c
+++ /dev/null
@@ -1,1776 +0,0 @@
-/*
- * ispresizer.c
- *
- * TI OMAP3 ISP - Resizer module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/device.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-
-#include "isp.h"
-#include "ispreg.h"
-#include "ispresizer.h"
-
-/*
- * Resizer Constants
- */
-#define MIN_RESIZE_VALUE 64
-#define MID_RESIZE_VALUE 512
-#define MAX_RESIZE_VALUE 1024
-
-#define MIN_IN_WIDTH 32
-#define MIN_IN_HEIGHT 32
-#define MAX_IN_WIDTH_MEMORY_MODE 4095
-#define MAX_IN_WIDTH_ONTHEFLY_MODE_ES1 1280
-#define MAX_IN_WIDTH_ONTHEFLY_MODE_ES2 4095
-#define MAX_IN_HEIGHT 4095
-
-#define MIN_OUT_WIDTH 16
-#define MIN_OUT_HEIGHT 2
-#define MAX_OUT_HEIGHT 4095
-
-/*
- * Resizer Use Constraints
- * "TRM ES3.1, table 12-46"
- */
-#define MAX_4TAP_OUT_WIDTH_ES1 1280
-#define MAX_7TAP_OUT_WIDTH_ES1 640
-#define MAX_4TAP_OUT_WIDTH_ES2 3312
-#define MAX_7TAP_OUT_WIDTH_ES2 1650
-#define MAX_4TAP_OUT_WIDTH_3630 4096
-#define MAX_7TAP_OUT_WIDTH_3630 2048
-
-/*
- * Constants for ratio calculation
- */
-#define RESIZE_DIVISOR 256
-#define DEFAULT_PHASE 1
-
-/*
- * Default (and only) configuration of filter coefficients.
- * 7-tap mode is for scale factors 0.25x to 0.5x.
- * 4-tap mode is for scale factors 0.5x to 4.0x.
- * There shouldn't be any reason to recalculate these, EVER.
- */
-static const struct isprsz_coef filter_coefs = {
- /* For 8-phase 4-tap horizontal filter: */
- {
- 0x0000, 0x0100, 0x0000, 0x0000,
- 0x03FA, 0x00F6, 0x0010, 0x0000,
- 0x03F9, 0x00DB, 0x002C, 0x0000,
- 0x03FB, 0x00B3, 0x0053, 0x03FF,
- 0x03FD, 0x0082, 0x0084, 0x03FD,
- 0x03FF, 0x0053, 0x00B3, 0x03FB,
- 0x0000, 0x002C, 0x00DB, 0x03F9,
- 0x0000, 0x0010, 0x00F6, 0x03FA
- },
- /* For 8-phase 4-tap vertical filter: */
- {
- 0x0000, 0x0100, 0x0000, 0x0000,
- 0x03FA, 0x00F6, 0x0010, 0x0000,
- 0x03F9, 0x00DB, 0x002C, 0x0000,
- 0x03FB, 0x00B3, 0x0053, 0x03FF,
- 0x03FD, 0x0082, 0x0084, 0x03FD,
- 0x03FF, 0x0053, 0x00B3, 0x03FB,
- 0x0000, 0x002C, 0x00DB, 0x03F9,
- 0x0000, 0x0010, 0x00F6, 0x03FA
- },
- /* For 4-phase 7-tap horizontal filter: */
- #define DUMMY 0
- {
- 0x0004, 0x0023, 0x005A, 0x0058, 0x0023, 0x0004, 0x0000, DUMMY,
- 0x0002, 0x0018, 0x004d, 0x0060, 0x0031, 0x0008, 0x0000, DUMMY,
- 0x0001, 0x000f, 0x003f, 0x0062, 0x003f, 0x000f, 0x0001, DUMMY,
- 0x0000, 0x0008, 0x0031, 0x0060, 0x004d, 0x0018, 0x0002, DUMMY
- },
- /* For 4-phase 7-tap vertical filter: */
- {
- 0x0004, 0x0023, 0x005A, 0x0058, 0x0023, 0x0004, 0x0000, DUMMY,
- 0x0002, 0x0018, 0x004d, 0x0060, 0x0031, 0x0008, 0x0000, DUMMY,
- 0x0001, 0x000f, 0x003f, 0x0062, 0x003f, 0x000f, 0x0001, DUMMY,
- 0x0000, 0x0008, 0x0031, 0x0060, 0x004d, 0x0018, 0x0002, DUMMY
- }
- /*
- * The dummy padding is required in 7-tap mode because of how the
- * registers are arranged physically.
- */
- #undef DUMMY
-};
-
-/*
- * __resizer_get_format - helper function for getting resizer format
- * @res : pointer to resizer private structure
- * @pad : pad number
- * @fh : V4L2 subdev file handle
- * @which : wanted subdev format
- * return zero
- */
-static struct v4l2_mbus_framefmt *
-__resizer_get_format(struct isp_res_device *res, struct v4l2_subdev_fh *fh,
- unsigned int pad, enum v4l2_subdev_format_whence which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_format(fh, pad);
- else
- return &res->formats[pad];
-}
-
-/*
- * __resizer_get_crop - helper function for getting resizer crop rectangle
- * @res : pointer to resizer private structure
- * @fh : V4L2 subdev file handle
- * @which : wanted subdev crop rectangle
- */
-static struct v4l2_rect *
-__resizer_get_crop(struct isp_res_device *res, struct v4l2_subdev_fh *fh,
- enum v4l2_subdev_format_whence which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_crop(fh, RESZ_PAD_SINK);
- else
- return &res->crop.request;
-}
-
-/*
- * resizer_set_filters - Set resizer filters
- * @res: Device context.
- * @h_coeff: horizontal coefficient
- * @v_coeff: vertical coefficient
- * Return none
- */
-static void resizer_set_filters(struct isp_res_device *res, const u16 *h_coeff,
- const u16 *v_coeff)
-{
- struct isp_device *isp = to_isp_device(res);
- u32 startaddr_h, startaddr_v, tmp_h, tmp_v;
- int i;
-
- startaddr_h = ISPRSZ_HFILT10;
- startaddr_v = ISPRSZ_VFILT10;
-
- for (i = 0; i < COEFF_CNT; i += 2) {
- tmp_h = h_coeff[i] |
- (h_coeff[i + 1] << ISPRSZ_HFILT_COEF1_SHIFT);
- tmp_v = v_coeff[i] |
- (v_coeff[i + 1] << ISPRSZ_VFILT_COEF1_SHIFT);
- isp_reg_writel(isp, tmp_h, OMAP3_ISP_IOMEM_RESZ, startaddr_h);
- isp_reg_writel(isp, tmp_v, OMAP3_ISP_IOMEM_RESZ, startaddr_v);
- startaddr_h += 4;
- startaddr_v += 4;
- }
-}
-
-/*
- * resizer_set_bilinear - Chrominance horizontal algorithm select
- * @res: Device context.
- * @type: Filtering interpolation type.
- *
- * Filtering that is same as luminance processing is
- * intended only for downsampling, and bilinear interpolation
- * is intended only for upsampling.
- */
-static void resizer_set_bilinear(struct isp_res_device *res,
- enum resizer_chroma_algo type)
-{
- struct isp_device *isp = to_isp_device(res);
-
- if (type == RSZ_BILINEAR)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
- ISPRSZ_CNT_CBILIN);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
- ISPRSZ_CNT_CBILIN);
-}
-
-/*
- * resizer_set_ycpos - Luminance and chrominance order
- * @res: Device context.
- * @order: order type.
- */
-static void resizer_set_ycpos(struct isp_res_device *res,
- enum v4l2_mbus_pixelcode pixelcode)
-{
- struct isp_device *isp = to_isp_device(res);
-
- switch (pixelcode) {
- case V4L2_MBUS_FMT_YUYV8_1X16:
- isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
- ISPRSZ_CNT_YCPOS);
- break;
- case V4L2_MBUS_FMT_UYVY8_1X16:
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
- ISPRSZ_CNT_YCPOS);
- break;
- default:
- return;
- }
-}
-
-/*
- * resizer_set_phase - Setup horizontal and vertical starting phase
- * @res: Device context.
- * @h_phase: horizontal phase parameters.
- * @v_phase: vertical phase parameters.
- *
- * Horizontal and vertical phase range is 0 to 7
- */
-static void resizer_set_phase(struct isp_res_device *res, u32 h_phase,
- u32 v_phase)
-{
- struct isp_device *isp = to_isp_device(res);
- u32 rgval = 0;
-
- rgval = isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT) &
- ~(ISPRSZ_CNT_HSTPH_MASK | ISPRSZ_CNT_VSTPH_MASK);
- rgval |= (h_phase << ISPRSZ_CNT_HSTPH_SHIFT) & ISPRSZ_CNT_HSTPH_MASK;
- rgval |= (v_phase << ISPRSZ_CNT_VSTPH_SHIFT) & ISPRSZ_CNT_VSTPH_MASK;
-
- isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT);
-}
-
-/*
- * resizer_set_luma - Setup luminance enhancer parameters
- * @res: Device context.
- * @luma: Structure for luminance enhancer parameters.
- *
- * Algorithm select:
- * 0x0: Disable
- * 0x1: [-1 2 -1]/2 high-pass filter
- * 0x2: [-1 -2 6 -2 -1]/4 high-pass filter
- *
- * Maximum gain:
- * The data is coded in U4Q4 representation.
- *
- * Slope:
- * The data is coded in U4Q4 representation.
- *
- * Coring offset:
- * The data is coded in U8Q0 representation.
- *
- * The new luminance value is computed as:
- * Y += HPF(Y) x max(GAIN, (HPF(Y) - CORE) x SLOP + 8) >> 4.
- */
-static void resizer_set_luma(struct isp_res_device *res,
- struct resizer_luma_yenh *luma)
-{
- struct isp_device *isp = to_isp_device(res);
- u32 rgval = 0;
-
- rgval = (luma->algo << ISPRSZ_YENH_ALGO_SHIFT)
- & ISPRSZ_YENH_ALGO_MASK;
- rgval |= (luma->gain << ISPRSZ_YENH_GAIN_SHIFT)
- & ISPRSZ_YENH_GAIN_MASK;
- rgval |= (luma->slope << ISPRSZ_YENH_SLOP_SHIFT)
- & ISPRSZ_YENH_SLOP_MASK;
- rgval |= (luma->core << ISPRSZ_YENH_CORE_SHIFT)
- & ISPRSZ_YENH_CORE_MASK;
-
- isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_YENH);
-}
-
-/*
- * resizer_set_source - Input source select
- * @res: Device context.
- * @source: Input source type
- *
- * If this field is set to RESIZER_INPUT_VP, the resizer input is fed from
- * Preview/CCDC engine, otherwise from memory.
- */
-static void resizer_set_source(struct isp_res_device *res,
- enum resizer_input_entity source)
-{
- struct isp_device *isp = to_isp_device(res);
-
- if (source == RESIZER_INPUT_MEMORY)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
- ISPRSZ_CNT_INPSRC);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
- ISPRSZ_CNT_INPSRC);
-}
-
-/*
- * resizer_set_ratio - Setup horizontal and vertical resizing value
- * @res: Device context.
- * @ratio: Structure for ratio parameters.
- *
- * Resizing range from 64 to 1024
- */
-static void resizer_set_ratio(struct isp_res_device *res,
- const struct resizer_ratio *ratio)
-{
- struct isp_device *isp = to_isp_device(res);
- const u16 *h_filter, *v_filter;
- u32 rgval = 0;
-
- rgval = isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT) &
- ~(ISPRSZ_CNT_HRSZ_MASK | ISPRSZ_CNT_VRSZ_MASK);
- rgval |= ((ratio->horz - 1) << ISPRSZ_CNT_HRSZ_SHIFT)
- & ISPRSZ_CNT_HRSZ_MASK;
- rgval |= ((ratio->vert - 1) << ISPRSZ_CNT_VRSZ_SHIFT)
- & ISPRSZ_CNT_VRSZ_MASK;
- isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT);
-
- /* prepare horizontal filter coefficients */
- if (ratio->horz > MID_RESIZE_VALUE)
- h_filter = &filter_coefs.h_filter_coef_7tap[0];
- else
- h_filter = &filter_coefs.h_filter_coef_4tap[0];
-
- /* prepare vertical filter coefficients */
- if (ratio->vert > MID_RESIZE_VALUE)
- v_filter = &filter_coefs.v_filter_coef_7tap[0];
- else
- v_filter = &filter_coefs.v_filter_coef_4tap[0];
-
- resizer_set_filters(res, h_filter, v_filter);
-}
-
-/*
- * resizer_set_dst_size - Setup the output height and width
- * @res: Device context.
- * @width: Output width.
- * @height: Output height.
- *
- * Width :
- * The value must be EVEN.
- *
- * Height:
- * The number of bytes written to SDRAM must be
- * a multiple of 16-bytes if the vertical resizing factor
- * is greater than 1x (upsizing)
- */
-static void resizer_set_output_size(struct isp_res_device *res,
- u32 width, u32 height)
-{
- struct isp_device *isp = to_isp_device(res);
- u32 rgval = 0;
-
- dev_dbg(isp->dev, "Output size[w/h]: %dx%d\n", width, height);
- rgval = (width << ISPRSZ_OUT_SIZE_HORZ_SHIFT)
- & ISPRSZ_OUT_SIZE_HORZ_MASK;
- rgval |= (height << ISPRSZ_OUT_SIZE_VERT_SHIFT)
- & ISPRSZ_OUT_SIZE_VERT_MASK;
- isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_OUT_SIZE);
-}
-
-/*
- * resizer_set_output_offset - Setup memory offset for the output lines.
- * @res: Device context.
- * @offset: Memory offset.
- *
- * The 5 LSBs are forced to be zeros by the hardware to align on a 32-byte
- * boundary; the 5 LSBs are read-only. For optimal use of SDRAM bandwidth,
- * the SDRAM line offset must be set on a 256-byte boundary
- */
-static void resizer_set_output_offset(struct isp_res_device *res, u32 offset)
-{
- struct isp_device *isp = to_isp_device(res);
-
- isp_reg_writel(isp, offset, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_OUTOFF);
-}
-
-/*
- * resizer_set_start - Setup vertical and horizontal start position
- * @res: Device context.
- * @left: Horizontal start position.
- * @top: Vertical start position.
- *
- * Vertical start line:
- * This field makes sense only when the resizer obtains its input
- * from the preview engine/CCDC
- *
- * Horizontal start pixel:
- * Pixels are coded on 16 bits for YUV and 8 bits for color separate data.
- * When the resizer gets its input from SDRAM, this field must be set
- * to <= 15 for YUV 16-bit data and <= 31 for 8-bit color separate data
- */
-static void resizer_set_start(struct isp_res_device *res, u32 left, u32 top)
-{
- struct isp_device *isp = to_isp_device(res);
- u32 rgval = 0;
-
- rgval = (left << ISPRSZ_IN_START_HORZ_ST_SHIFT)
- & ISPRSZ_IN_START_HORZ_ST_MASK;
- rgval |= (top << ISPRSZ_IN_START_VERT_ST_SHIFT)
- & ISPRSZ_IN_START_VERT_ST_MASK;
-
- isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_IN_START);
-}
-
-/*
- * resizer_set_input_size - Setup the input size
- * @res: Device context.
- * @width: The range is 0 to 4095 pixels
- * @height: The range is 0 to 4095 lines
- */
-static void resizer_set_input_size(struct isp_res_device *res,
- u32 width, u32 height)
-{
- struct isp_device *isp = to_isp_device(res);
- u32 rgval = 0;
-
- dev_dbg(isp->dev, "Input size[w/h]: %dx%d\n", width, height);
-
- rgval = (width << ISPRSZ_IN_SIZE_HORZ_SHIFT)
- & ISPRSZ_IN_SIZE_HORZ_MASK;
- rgval |= (height << ISPRSZ_IN_SIZE_VERT_SHIFT)
- & ISPRSZ_IN_SIZE_VERT_MASK;
-
- isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_IN_SIZE);
-}
-
-/*
- * resizer_set_src_offs - Setup the memory offset for the input lines
- * @res: Device context.
- * @offset: Memory offset.
- *
- * The 5 LSBs are forced to be zeros by the hardware to align on a 32-byte
- * boundary; the 5 LSBs are read-only. This field must be programmed to be
- * 0x0 if the resizer input is from preview engine/CCDC.
- */
-static void resizer_set_input_offset(struct isp_res_device *res, u32 offset)
-{
- struct isp_device *isp = to_isp_device(res);
-
- isp_reg_writel(isp, offset, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INOFF);
-}
-
-/*
- * resizer_set_intype - Input type select
- * @res: Device context.
- * @type: Pixel format type.
- */
-static void resizer_set_intype(struct isp_res_device *res,
- enum resizer_colors_type type)
-{
- struct isp_device *isp = to_isp_device(res);
-
- if (type == RSZ_COLOR8)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
- ISPRSZ_CNT_INPTYP);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
- ISPRSZ_CNT_INPTYP);
-}
-
-/*
- * __resizer_set_inaddr - Helper function for set input address
- * @res : pointer to resizer private data structure
- * @addr: input address
- * return none
- */
-static void __resizer_set_inaddr(struct isp_res_device *res, u32 addr)
-{
- struct isp_device *isp = to_isp_device(res);
-
- isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INADD);
-}
-
-/*
- * The data rate at the horizontal resizer output must not exceed half the
- * functional clock or 100 MP/s, whichever is lower. According to the TRM
- * there's no similar requirement for the vertical resizer output. However
- * experience showed that vertical upscaling by 4 leads to SBL overflows (with
- * data rates at the resizer output exceeding 300 MP/s). Limiting the resizer
- * output data rate to the functional clock or 200 MP/s, whichever is lower,
- * seems to get rid of SBL overflows.
- *
- * The maximum data rate at the output of the horizontal resizer can thus be
- * computed with
- *
- * max intermediate rate <= L3 clock * input height / output height
- * max intermediate rate <= L3 clock / 2
- *
- * The maximum data rate at the resizer input is then
- *
- * max input rate <= max intermediate rate * input width / output width
- *
- * where the input width and height are the resizer input crop rectangle size.
- * The TRM doesn't clearly explain if that's a maximum instant data rate or a
- * maximum average data rate.
- */
-void omap3isp_resizer_max_rate(struct isp_res_device *res,
- unsigned int *max_rate)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(&res->subdev.entity);
- const struct v4l2_mbus_framefmt *ofmt = &res->formats[RESZ_PAD_SOURCE];
- unsigned long limit = min(pipe->l3_ick, 200000000UL);
- unsigned long clock;
-
- clock = div_u64((u64)limit * res->crop.active.height, ofmt->height);
- clock = min(clock, limit / 2);
- *max_rate = div_u64((u64)clock * res->crop.active.width, ofmt->width);
-}
-
-/*
- * When the resizer processes images from memory, the driver must slow down read
- * requests on the input to at least comply with the internal data rate
- * requirements. If the application real-time requirements can cope with slower
- * processing, the resizer can be slowed down even more to put less pressure on
- * the overall system.
- *
- * When the resizer processes images on the fly (either from the CCDC or the
- * preview module), the same data rate requirements apply but they can't be
- * enforced at the resizer level. The image input module (sensor, CCP2 or
- * preview module) must not provide image data faster than the resizer can
- * process.
- *
- * For live image pipelines, the data rate is set by the frame format, size and
- * rate. The sensor output frame rate must not exceed the maximum resizer data
- * rate.
- *
- * The resizer slows down read requests by inserting wait cycles in the SBL
- * requests. The maximum number of 256-byte requests per second can be computed
- * as (the data rate is multiplied by 2 to convert from pixels per second to
- * bytes per second)
- *
- * request per second = data rate * 2 / 256
- * cycles per request = cycles per second / requests per second
- *
- * The number of cycles per second is controlled by the L3 clock, leading to
- *
- * cycles per request = L3 frequency / 2 * 256 / data rate
- */
-static void resizer_adjust_bandwidth(struct isp_res_device *res)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(&res->subdev.entity);
- struct isp_device *isp = to_isp_device(res);
- unsigned long l3_ick = pipe->l3_ick;
- struct v4l2_fract *timeperframe;
- unsigned int cycles_per_frame;
- unsigned int requests_per_frame;
- unsigned int cycles_per_request;
- unsigned int granularity;
- unsigned int minimum;
- unsigned int maximum;
- unsigned int value;
-
- if (res->input != RESIZER_INPUT_MEMORY) {
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
- ISPSBL_SDR_REQ_RSZ_EXP_MASK);
- return;
- }
-
- switch (isp->revision) {
- case ISP_REVISION_1_0:
- case ISP_REVISION_2_0:
- default:
- granularity = 1024;
- break;
-
- case ISP_REVISION_15_0:
- granularity = 32;
- break;
- }
-
- /* Compute the minimum number of cycles per request, based on the
- * pipeline maximum data rate. This is an absolute lower bound if we
- * don't want SBL overflows, so round the value up.
- */
- cycles_per_request = div_u64((u64)l3_ick / 2 * 256 + pipe->max_rate - 1,
- pipe->max_rate);
- minimum = DIV_ROUND_UP(cycles_per_request, granularity);
-
- /* Compute the maximum number of cycles per request, based on the
- * requested frame rate. This is a soft upper bound to achieve a frame
- * rate equal or higher than the requested value, so round the value
- * down.
- */
- timeperframe = &pipe->max_timeperframe;
-
- requests_per_frame = DIV_ROUND_UP(res->crop.active.width * 2, 256)
- * res->crop.active.height;
- cycles_per_frame = div_u64((u64)l3_ick * timeperframe->numerator,
- timeperframe->denominator);
- cycles_per_request = cycles_per_frame / requests_per_frame;
-
- maximum = cycles_per_request / granularity;
-
- value = max(minimum, maximum);
-
- dev_dbg(isp->dev, "%s: cycles per request = %u\n", __func__, value);
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
- ISPSBL_SDR_REQ_RSZ_EXP_MASK,
- value << ISPSBL_SDR_REQ_RSZ_EXP_SHIFT);
-}
-
-/*
- * omap3isp_resizer_busy - Checks if ISP resizer is busy.
- *
- * Returns busy field from ISPRSZ_PCR register.
- */
-int omap3isp_resizer_busy(struct isp_res_device *res)
-{
- struct isp_device *isp = to_isp_device(res);
-
- return isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR) &
- ISPRSZ_PCR_BUSY;
-}
-
-/*
- * resizer_set_inaddr - Sets the memory address of the input frame.
- * @addr: 32bit memory address aligned on 32byte boundary.
- */
-static void resizer_set_inaddr(struct isp_res_device *res, u32 addr)
-{
- res->addr_base = addr;
-
- /* This will handle crop settings in stream off state */
- if (res->crop_offset)
- addr += res->crop_offset & ~0x1f;
-
- __resizer_set_inaddr(res, addr);
-}
-
-/*
- * Configures the memory address to which the output frame is written.
- * @addr: 32bit memory address aligned on 32byte boundary.
- * Note: For SBL efficiency reasons the address should be on a 256-byte
- * boundary.
- */
-static void resizer_set_outaddr(struct isp_res_device *res, u32 addr)
-{
- struct isp_device *isp = to_isp_device(res);
-
- /*
- * Set output address. This needs to be in its own function
- * because it changes often.
- */
- isp_reg_writel(isp, addr << ISPRSZ_SDR_OUTADD_ADDR_SHIFT,
- OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_OUTADD);
-}
-
-/*
- * resizer_print_status - Prints the values of the resizer module registers.
- */
-#define RSZ_PRINT_REGISTER(isp, name)\
- dev_dbg(isp->dev, "###RSZ " #name "=0x%08x\n", \
- isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_##name))
-
-static void resizer_print_status(struct isp_res_device *res)
-{
- struct isp_device *isp = to_isp_device(res);
-
- dev_dbg(isp->dev, "-------------Resizer Register dump----------\n");
-
- RSZ_PRINT_REGISTER(isp, PCR);
- RSZ_PRINT_REGISTER(isp, CNT);
- RSZ_PRINT_REGISTER(isp, OUT_SIZE);
- RSZ_PRINT_REGISTER(isp, IN_START);
- RSZ_PRINT_REGISTER(isp, IN_SIZE);
- RSZ_PRINT_REGISTER(isp, SDR_INADD);
- RSZ_PRINT_REGISTER(isp, SDR_INOFF);
- RSZ_PRINT_REGISTER(isp, SDR_OUTADD);
- RSZ_PRINT_REGISTER(isp, SDR_OUTOFF);
- RSZ_PRINT_REGISTER(isp, YENH);
-
- dev_dbg(isp->dev, "--------------------------------------------\n");
-}
-
-/*
- * resizer_calc_ratios - Helper function for calculate resizer ratios
- * @res: pointer to resizer private data structure
- * @input: input frame size
- * @output: output frame size
- * @ratio : return calculated ratios
- * return none
- *
- * The resizer uses a polyphase sample rate converter. The upsampling filter
- * has a fixed number of phases that depend on the resizing ratio. As the ratio
- * computation depends on the number of phases, we need to compute a first
- * approximation and then refine it.
- *
- * The input/output/ratio relationship is given by the OMAP34xx TRM:
- *
- * - 8-phase, 4-tap mode (RSZ = 64 ~ 512)
- * iw = (32 * sph + (ow - 1) * hrsz + 16) >> 8 + 7
- * ih = (32 * spv + (oh - 1) * vrsz + 16) >> 8 + 4
- * - 4-phase, 7-tap mode (RSZ = 513 ~ 1024)
- * iw = (64 * sph + (ow - 1) * hrsz + 32) >> 8 + 7
- * ih = (64 * spv + (oh - 1) * vrsz + 32) >> 8 + 7
- *
- * iw and ih are the input width and height after cropping. Those equations need
- * to be satisfied exactly for the resizer to work correctly.
- *
- * The equations can't be easily reverted, as the >> 8 operation is not linear.
- * In addition, not all input sizes can be achieved for a given output size. To
- * get the highest input size lower than or equal to the requested input size,
- * we need to compute the highest resizing ratio that satisfies the following
- * inequality (taking the 4-tap mode width equation as an example)
- *
- * iw >= (32 * sph + (ow - 1) * hrsz + 16) >> 8 - 7
- *
- * (where iw is the requested input width) which can be rewritten as
- *
- * iw - 7 >= (32 * sph + (ow - 1) * hrsz + 16) >> 8
- * (iw - 7) << 8 >= 32 * sph + (ow - 1) * hrsz + 16 - b
- * ((iw - 7) << 8) + b >= 32 * sph + (ow - 1) * hrsz + 16
- *
- * where b is the value of the 8 least significant bits of the right hand side
- * expression of the last inequality. The highest resizing ratio value will be
- * achieved when b is equal to its maximum value of 255. That resizing ratio
- * value will still satisfy the original inequality, as b will disappear when
- * the expression will be shifted right by 8.
- *
- * The reverted the equations thus become
- *
- * - 8-phase, 4-tap mode
- * hrsz = ((iw - 7) * 256 + 255 - 16 - 32 * sph) / (ow - 1)
- * vrsz = ((ih - 4) * 256 + 255 - 16 - 32 * spv) / (oh - 1)
- * - 4-phase, 7-tap mode
- * hrsz = ((iw - 7) * 256 + 255 - 32 - 64 * sph) / (ow - 1)
- * vrsz = ((ih - 7) * 256 + 255 - 32 - 64 * spv) / (oh - 1)
- *
- * The ratios are integer values, and are rounded down to ensure that the
- * cropped input size is not bigger than the uncropped input size.
- *
- * As the number of phases/taps, used to select the correct equations to compute
- * the ratio, depends on the ratio, we start with the 4-tap mode equations to
- * compute an approximation of the ratio, and switch to the 7-tap mode equations
- * if the approximation is higher than the ratio threshold.
- *
- * As the 7-tap mode equations will return a ratio smaller than or equal to the
- * 4-tap mode equations, the resulting ratio could become lower than or equal to
- * the ratio threshold. This 'equations loop' isn't an issue as long as the
- * correct equations are used to compute the final input size. Starting with the
- * 4-tap mode equations ensure that, in case of values resulting in a 'ratio
- * loop', the smallest of the ratio values will be used, never exceeding the
- * requested input size.
- *
- * We first clamp the output size according to the hardware capabilitie to avoid
- * auto-cropping the input more than required to satisfy the TRM equations. The
- * minimum output size is achieved with a scaling factor of 1024. It is thus
- * computed using the 7-tap equations.
- *
- * min ow = ((iw - 7) * 256 - 32 - 64 * sph) / 1024 + 1
- * min oh = ((ih - 7) * 256 - 32 - 64 * spv) / 1024 + 1
- *
- * Similarly, the maximum output size is achieved with a scaling factor of 64
- * and computed using the 4-tap equations.
- *
- * max ow = ((iw - 7) * 256 + 255 - 16 - 32 * sph) / 64 + 1
- * max oh = ((ih - 4) * 256 + 255 - 16 - 32 * spv) / 64 + 1
- *
- * The additional +255 term compensates for the round down operation performed
- * by the TRM equations when shifting the value right by 8 bits.
- *
- * We then compute and clamp the ratios (x1/4 ~ x4). Clamping the output size to
- * the maximum value guarantees that the ratio value will never be smaller than
- * the minimum, but it could still slightly exceed the maximum. Clamping the
- * ratio will thus result in a resizing factor slightly larger than the
- * requested value.
- *
- * To accommodate that, and make sure the TRM equations are satisfied exactly, we
- * compute the input crop rectangle as the last step.
- *
- * As if the situation wasn't complex enough, the maximum output width depends
- * on the vertical resizing ratio. Fortunately, the output height doesn't
- * depend on the horizontal resizing ratio. We can then start by computing the
- * output height and the vertical ratio, and then move to computing the output
- * width and the horizontal ratio.
- */
-static void resizer_calc_ratios(struct isp_res_device *res,
- struct v4l2_rect *input,
- struct v4l2_mbus_framefmt *output,
- struct resizer_ratio *ratio)
-{
- struct isp_device *isp = to_isp_device(res);
- const unsigned int spv = DEFAULT_PHASE;
- const unsigned int sph = DEFAULT_PHASE;
- unsigned int upscaled_width;
- unsigned int upscaled_height;
- unsigned int min_width;
- unsigned int min_height;
- unsigned int max_width;
- unsigned int max_height;
- unsigned int width_alignment;
- unsigned int width;
- unsigned int height;
-
- /*
- * Clamp the output height based on the hardware capabilities and
- * compute the vertical resizing ratio.
- */
- min_height = ((input->height - 7) * 256 - 32 - 64 * spv) / 1024 + 1;
- min_height = max_t(unsigned int, min_height, MIN_OUT_HEIGHT);
- max_height = ((input->height - 4) * 256 + 255 - 16 - 32 * spv) / 64 + 1;
- max_height = min_t(unsigned int, max_height, MAX_OUT_HEIGHT);
- output->height = clamp(output->height, min_height, max_height);
-
- ratio->vert = ((input->height - 4) * 256 + 255 - 16 - 32 * spv)
- / (output->height - 1);
- if (ratio->vert > MID_RESIZE_VALUE)
- ratio->vert = ((input->height - 7) * 256 + 255 - 32 - 64 * spv)
- / (output->height - 1);
- ratio->vert = clamp_t(unsigned int, ratio->vert,
- MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
-
- if (ratio->vert <= MID_RESIZE_VALUE) {
- upscaled_height = (output->height - 1) * ratio->vert
- + 32 * spv + 16;
- height = (upscaled_height >> 8) + 4;
- } else {
- upscaled_height = (output->height - 1) * ratio->vert
- + 64 * spv + 32;
- height = (upscaled_height >> 8) + 7;
- }
-
- /*
- * Compute the minimum and maximum output widths based on the hardware
- * capabilities. The maximum depends on the vertical resizing ratio.
- */
- min_width = ((input->width - 7) * 256 - 32 - 64 * sph) / 1024 + 1;
- min_width = max_t(unsigned int, min_width, MIN_OUT_WIDTH);
-
- if (ratio->vert <= MID_RESIZE_VALUE) {
- switch (isp->revision) {
- case ISP_REVISION_1_0:
- max_width = MAX_4TAP_OUT_WIDTH_ES1;
- break;
-
- case ISP_REVISION_2_0:
- default:
- max_width = MAX_4TAP_OUT_WIDTH_ES2;
- break;
-
- case ISP_REVISION_15_0:
- max_width = MAX_4TAP_OUT_WIDTH_3630;
- break;
- }
- } else {
- switch (isp->revision) {
- case ISP_REVISION_1_0:
- max_width = MAX_7TAP_OUT_WIDTH_ES1;
- break;
-
- case ISP_REVISION_2_0:
- default:
- max_width = MAX_7TAP_OUT_WIDTH_ES2;
- break;
-
- case ISP_REVISION_15_0:
- max_width = MAX_7TAP_OUT_WIDTH_3630;
- break;
- }
- }
- max_width = min(((input->width - 7) * 256 + 255 - 16 - 32 * sph) / 64
- + 1, max_width);
-
- /*
- * The output width must be even, and must be a multiple of 16 bytes
- * when upscaling vertically. Clamp the output width to the valid range.
- * Take the alignment into account (the maximum width in 7-tap mode on
- * ES2 isn't a multiple of 8) and align the result up to make sure it
- * won't be smaller than the minimum.
- */
- width_alignment = ratio->vert < 256 ? 8 : 2;
- output->width = clamp(output->width, min_width,
- max_width & ~(width_alignment - 1));
- output->width = ALIGN(output->width, width_alignment);
-
- ratio->horz = ((input->width - 7) * 256 + 255 - 16 - 32 * sph)
- / (output->width - 1);
- if (ratio->horz > MID_RESIZE_VALUE)
- ratio->horz = ((input->width - 7) * 256 + 255 - 32 - 64 * sph)
- / (output->width - 1);
- ratio->horz = clamp_t(unsigned int, ratio->horz,
- MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
-
- if (ratio->horz <= MID_RESIZE_VALUE) {
- upscaled_width = (output->width - 1) * ratio->horz
- + 32 * sph + 16;
- width = (upscaled_width >> 8) + 7;
- } else {
- upscaled_width = (output->width - 1) * ratio->horz
- + 64 * sph + 32;
- width = (upscaled_width >> 8) + 7;
- }
-
- /* Center the new crop rectangle. */
- input->left += (input->width - width) / 2;
- input->top += (input->height - height) / 2;
- input->width = width;
- input->height = height;
-}
-
-/*
- * resizer_set_crop_params - Setup hardware with cropping parameters
- * @res : resizer private structure
- * @crop_rect : current crop rectangle
- * @ratio : resizer ratios
- * return none
- */
-static void resizer_set_crop_params(struct isp_res_device *res,
- const struct v4l2_mbus_framefmt *input,
- const struct v4l2_mbus_framefmt *output)
-{
- resizer_set_ratio(res, &res->ratio);
-
- /* Set chrominance horizontal algorithm */
- if (res->ratio.horz >= RESIZE_DIVISOR)
- resizer_set_bilinear(res, RSZ_THE_SAME);
- else
- resizer_set_bilinear(res, RSZ_BILINEAR);
-
- resizer_adjust_bandwidth(res);
-
- if (res->input == RESIZER_INPUT_MEMORY) {
- /* Calculate additional offset for crop */
- res->crop_offset = (res->crop.active.top * input->width +
- res->crop.active.left) * 2;
- /*
- * Write lowest 4 bits of horizontal pixel offset (in pixels),
- * vertical start must be 0.
- */
- resizer_set_start(res, (res->crop_offset / 2) & 0xf, 0);
-
- /*
- * Set start (read) address for cropping, in bytes.
- * Lowest 5 bits must be zero.
- */
- __resizer_set_inaddr(res,
- res->addr_base + (res->crop_offset & ~0x1f));
- } else {
- /*
- * Set vertical start line and horizontal starting pixel.
- * If the input is from CCDC/PREV, horizontal start field is
- * in bytes (twice number of pixels).
- */
- resizer_set_start(res, res->crop.active.left * 2,
- res->crop.active.top);
- /* Input address and offset must be 0 for preview/ccdc input */
- __resizer_set_inaddr(res, 0);
- resizer_set_input_offset(res, 0);
- }
-
- /* Set the input size */
- resizer_set_input_size(res, res->crop.active.width,
- res->crop.active.height);
-}
-
-static void resizer_configure(struct isp_res_device *res)
-{
- struct v4l2_mbus_framefmt *informat, *outformat;
- struct resizer_luma_yenh luma = {0, 0, 0, 0};
-
- resizer_set_source(res, res->input);
-
- informat = &res->formats[RESZ_PAD_SINK];
- outformat = &res->formats[RESZ_PAD_SOURCE];
-
- /* RESZ_PAD_SINK */
- if (res->input == RESIZER_INPUT_VP)
- resizer_set_input_offset(res, 0);
- else
- resizer_set_input_offset(res, ALIGN(informat->width, 0x10) * 2);
-
- /* YUV422 interleaved, default phase, no luma enhancement */
- resizer_set_intype(res, RSZ_YUV422);
- resizer_set_ycpos(res, informat->code);
- resizer_set_phase(res, DEFAULT_PHASE, DEFAULT_PHASE);
- resizer_set_luma(res, &luma);
-
- /* RESZ_PAD_SOURCE */
- resizer_set_output_offset(res, ALIGN(outformat->width * 2, 32));
- resizer_set_output_size(res, outformat->width, outformat->height);
-
- resizer_set_crop_params(res, informat, outformat);
-}
-
-/* -----------------------------------------------------------------------------
- * Interrupt handling
- */
-
-static void resizer_enable_oneshot(struct isp_res_device *res)
-{
- struct isp_device *isp = to_isp_device(res);
-
- isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR,
- ISPRSZ_PCR_ENABLE | ISPRSZ_PCR_ONESHOT);
-}
-
-void omap3isp_resizer_isr_frame_sync(struct isp_res_device *res)
-{
- /*
- * If ISP_VIDEO_DMAQUEUE_QUEUED is set, DMA queue had an underrun
- * condition, the module was paused and now we have a buffer queued
- * on the output again. Restart the pipeline if running in continuous
- * mode.
- */
- if (res->state == ISP_PIPELINE_STREAM_CONTINUOUS &&
- res->video_out.dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED) {
- resizer_enable_oneshot(res);
- isp_video_dmaqueue_flags_clr(&res->video_out);
- }
-}
-
-static void resizer_isr_buffer(struct isp_res_device *res)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(&res->subdev.entity);
- struct isp_buffer *buffer;
- int restart = 0;
-
- if (res->state == ISP_PIPELINE_STREAM_STOPPED)
- return;
-
- /* Complete the output buffer and, if reading from memory, the input
- * buffer.
- */
- buffer = omap3isp_video_buffer_next(&res->video_out);
- if (buffer != NULL) {
- resizer_set_outaddr(res, buffer->isp_addr);
- restart = 1;
- }
-
- pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
-
- if (res->input == RESIZER_INPUT_MEMORY) {
- buffer = omap3isp_video_buffer_next(&res->video_in);
- if (buffer != NULL)
- resizer_set_inaddr(res, buffer->isp_addr);
- pipe->state |= ISP_PIPELINE_IDLE_INPUT;
- }
-
- if (res->state == ISP_PIPELINE_STREAM_SINGLESHOT) {
- if (isp_pipeline_ready(pipe))
- omap3isp_pipeline_set_stream(pipe,
- ISP_PIPELINE_STREAM_SINGLESHOT);
- } else {
- /* If an underrun occurs, the video queue operation handler will
- * restart the resizer. Otherwise restart it immediately.
- */
- if (restart)
- resizer_enable_oneshot(res);
- }
-}
-
-/*
- * omap3isp_resizer_isr - ISP resizer interrupt handler
- *
- * Manage the resizer video buffers and configure shadowed and busy-locked
- * registers.
- */
-void omap3isp_resizer_isr(struct isp_res_device *res)
-{
- struct v4l2_mbus_framefmt *informat, *outformat;
-
- if (omap3isp_module_sync_is_stopping(&res->wait, &res->stopping))
- return;
-
- if (res->applycrop) {
- outformat = __resizer_get_format(res, NULL, RESZ_PAD_SOURCE,
- V4L2_SUBDEV_FORMAT_ACTIVE);
- informat = __resizer_get_format(res, NULL, RESZ_PAD_SINK,
- V4L2_SUBDEV_FORMAT_ACTIVE);
- resizer_set_crop_params(res, informat, outformat);
- res->applycrop = 0;
- }
-
- resizer_isr_buffer(res);
-}
-
-/* -----------------------------------------------------------------------------
- * ISP video operations
- */
-
-static int resizer_video_queue(struct isp_video *video,
- struct isp_buffer *buffer)
-{
- struct isp_res_device *res = &video->isp->isp_res;
-
- if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
- resizer_set_inaddr(res, buffer->isp_addr);
-
- /*
- * We now have a buffer queued on the output. Despite what the
- * TRM says, the resizer can't be restarted immediately.
- * Enabling it in one shot mode in the middle of a frame (or at
- * least asynchronously to the frame) results in the output
- * being shifted randomly left/right and up/down, as if the
- * hardware didn't synchronize itself to the beginning of the
- * frame correctly.
- *
- * Restart the resizer on the next sync interrupt if running in
- * continuous mode or when starting the stream.
- */
- if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- resizer_set_outaddr(res, buffer->isp_addr);
-
- return 0;
-}
-
-static const struct isp_video_operations resizer_video_ops = {
- .queue = resizer_video_queue,
-};
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev operations
- */
-
-/*
- * resizer_set_stream - Enable/Disable streaming on resizer subdev
- * @sd: ISP resizer V4L2 subdev
- * @enable: 1 == Enable, 0 == Disable
- *
- * The resizer hardware can't be enabled without a memory buffer to write to.
- * As the s_stream operation is called in response to a STREAMON call without
- * any buffer queued yet, just update the state field and return immediately.
- * The resizer will be enabled in resizer_video_queue().
- */
-static int resizer_set_stream(struct v4l2_subdev *sd, int enable)
-{
- struct isp_res_device *res = v4l2_get_subdevdata(sd);
- struct isp_video *video_out = &res->video_out;
- struct isp_device *isp = to_isp_device(res);
- struct device *dev = to_device(res);
-
- if (res->state == ISP_PIPELINE_STREAM_STOPPED) {
- if (enable == ISP_PIPELINE_STREAM_STOPPED)
- return 0;
-
- omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_RESIZER);
- resizer_configure(res);
- resizer_print_status(res);
- }
-
- switch (enable) {
- case ISP_PIPELINE_STREAM_CONTINUOUS:
- omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_RESIZER_WRITE);
- if (video_out->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED) {
- resizer_enable_oneshot(res);
- isp_video_dmaqueue_flags_clr(video_out);
- }
- break;
-
- case ISP_PIPELINE_STREAM_SINGLESHOT:
- if (res->input == RESIZER_INPUT_MEMORY)
- omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_RESIZER_READ);
- omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_RESIZER_WRITE);
-
- resizer_enable_oneshot(res);
- break;
-
- case ISP_PIPELINE_STREAM_STOPPED:
- if (omap3isp_module_sync_idle(&sd->entity, &res->wait,
- &res->stopping))
- dev_dbg(dev, "%s: module stop timeout.\n", sd->name);
- omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_RESIZER_READ |
- OMAP3_ISP_SBL_RESIZER_WRITE);
- omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_RESIZER);
- isp_video_dmaqueue_flags_clr(video_out);
- break;
- }
-
- res->state = enable;
- return 0;
-}
-
-/*
- * resizer_try_crop - mangles crop parameters.
- */
-static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink,
- const struct v4l2_mbus_framefmt *source,
- struct v4l2_rect *crop)
-{
- const unsigned int spv = DEFAULT_PHASE;
- const unsigned int sph = DEFAULT_PHASE;
-
- /* Crop rectangle is constrained by the output size so that zoom ratio
- * cannot exceed +/-4.0.
- */
- unsigned int min_width =
- ((32 * sph + (source->width - 1) * 64 + 16) >> 8) + 7;
- unsigned int min_height =
- ((32 * spv + (source->height - 1) * 64 + 16) >> 8) + 4;
- unsigned int max_width =
- ((64 * sph + (source->width - 1) * 1024 + 32) >> 8) + 7;
- unsigned int max_height =
- ((64 * spv + (source->height - 1) * 1024 + 32) >> 8) + 7;
-
- crop->width = clamp_t(u32, crop->width, min_width, max_width);
- crop->height = clamp_t(u32, crop->height, min_height, max_height);
-
- /* Crop can not go beyond of the input rectangle */
- crop->left = clamp_t(u32, crop->left, 0, sink->width - MIN_IN_WIDTH);
- crop->width = clamp_t(u32, crop->width, MIN_IN_WIDTH,
- sink->width - crop->left);
- crop->top = clamp_t(u32, crop->top, 0, sink->height - MIN_IN_HEIGHT);
- crop->height = clamp_t(u32, crop->height, MIN_IN_HEIGHT,
- sink->height - crop->top);
-}
-
-/*
- * resizer_get_selection - Retrieve a selection rectangle on a pad
- * @sd: ISP resizer V4L2 subdevice
- * @fh: V4L2 subdev file handle
- * @sel: Selection rectangle
- *
- * The only supported rectangles are the crop rectangles on the sink pad.
- *
- * Return 0 on success or a negative error code otherwise.
- */
-static int resizer_get_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct isp_res_device *res = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format_source;
- struct v4l2_mbus_framefmt *format_sink;
- struct resizer_ratio ratio;
-
- if (sel->pad != RESZ_PAD_SINK)
- return -EINVAL;
-
- format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK,
- sel->which);
- format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE,
- sel->which);
-
- switch (sel->target) {
- case V4L2_SEL_TGT_CROP_BOUNDS:
- sel->r.left = 0;
- sel->r.top = 0;
- sel->r.width = INT_MAX;
- sel->r.height = INT_MAX;
-
- resizer_try_crop(format_sink, format_source, &sel->r);
- resizer_calc_ratios(res, &sel->r, format_source, &ratio);
- break;
-
- case V4L2_SEL_TGT_CROP:
- sel->r = *__resizer_get_crop(res, fh, sel->which);
- resizer_calc_ratios(res, &sel->r, format_source, &ratio);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * resizer_set_selection - Set a selection rectangle on a pad
- * @sd: ISP resizer V4L2 subdevice
- * @fh: V4L2 subdev file handle
- * @sel: Selection rectangle
- *
- * The only supported rectangle is the actual crop rectangle on the sink pad.
- *
- * FIXME: This function currently behaves as if the KEEP_CONFIG selection flag
- * was always set.
- *
- * Return 0 on success or a negative error code otherwise.
- */
-static int resizer_set_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct isp_res_device *res = v4l2_get_subdevdata(sd);
- struct isp_device *isp = to_isp_device(res);
- struct v4l2_mbus_framefmt *format_sink, *format_source;
- struct resizer_ratio ratio;
-
- if (sel->target != V4L2_SEL_TGT_CROP ||
- sel->pad != RESZ_PAD_SINK)
- return -EINVAL;
-
- format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK,
- sel->which);
- format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE,
- sel->which);
-
- dev_dbg(isp->dev, "%s: L=%d,T=%d,W=%d,H=%d,which=%d\n", __func__,
- sel->r.left, sel->r.top, sel->r.width, sel->r.height,
- sel->which);
-
- dev_dbg(isp->dev, "%s: input=%dx%d, output=%dx%d\n", __func__,
- format_sink->width, format_sink->height,
- format_source->width, format_source->height);
-
- /* Clamp the crop rectangle to the bounds, and then mangle it further to
- * fulfill the TRM equations. Store the clamped but otherwise unmangled
- * rectangle to avoid cropping the input multiple times: when an
- * application sets the output format, the current crop rectangle is
- * mangled during crop rectangle computation, which would lead to a new,
- * smaller input crop rectangle every time the output size is set if we
- * stored the mangled rectangle.
- */
- resizer_try_crop(format_sink, format_source, &sel->r);
- *__resizer_get_crop(res, fh, sel->which) = sel->r;
- resizer_calc_ratios(res, &sel->r, format_source, &ratio);
-
- if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
- return 0;
-
- res->ratio = ratio;
- res->crop.active = sel->r;
-
- /*
- * set_selection can be called while streaming is on. In this case the
- * crop values will be set in the next IRQ.
- */
- if (res->state != ISP_PIPELINE_STREAM_STOPPED)
- res->applycrop = 1;
-
- return 0;
-}
-
-/* resizer pixel formats */
-static const unsigned int resizer_formats[] = {
- V4L2_MBUS_FMT_UYVY8_1X16,
- V4L2_MBUS_FMT_YUYV8_1X16,
-};
-
-static unsigned int resizer_max_in_width(struct isp_res_device *res)
-{
- struct isp_device *isp = to_isp_device(res);
-
- if (res->input == RESIZER_INPUT_MEMORY) {
- return MAX_IN_WIDTH_MEMORY_MODE;
- } else {
- if (isp->revision == ISP_REVISION_1_0)
- return MAX_IN_WIDTH_ONTHEFLY_MODE_ES1;
- else
- return MAX_IN_WIDTH_ONTHEFLY_MODE_ES2;
- }
-}
-
-/*
- * resizer_try_format - Handle try format by pad subdev method
- * @res : ISP resizer device
- * @fh : V4L2 subdev file handle
- * @pad : pad num
- * @fmt : pointer to v4l2 format structure
- * @which : wanted subdev format
- */
-static void resizer_try_format(struct isp_res_device *res,
- struct v4l2_subdev_fh *fh, unsigned int pad,
- struct v4l2_mbus_framefmt *fmt,
- enum v4l2_subdev_format_whence which)
-{
- struct v4l2_mbus_framefmt *format;
- struct resizer_ratio ratio;
- struct v4l2_rect crop;
-
- switch (pad) {
- case RESZ_PAD_SINK:
- if (fmt->code != V4L2_MBUS_FMT_YUYV8_1X16 &&
- fmt->code != V4L2_MBUS_FMT_UYVY8_1X16)
- fmt->code = V4L2_MBUS_FMT_YUYV8_1X16;
-
- fmt->width = clamp_t(u32, fmt->width, MIN_IN_WIDTH,
- resizer_max_in_width(res));
- fmt->height = clamp_t(u32, fmt->height, MIN_IN_HEIGHT,
- MAX_IN_HEIGHT);
- break;
-
- case RESZ_PAD_SOURCE:
- format = __resizer_get_format(res, fh, RESZ_PAD_SINK, which);
- fmt->code = format->code;
-
- crop = *__resizer_get_crop(res, fh, which);
- resizer_calc_ratios(res, &crop, fmt, &ratio);
- break;
- }
-
- fmt->colorspace = V4L2_COLORSPACE_JPEG;
- fmt->field = V4L2_FIELD_NONE;
-}
-
-/*
- * resizer_enum_mbus_code - Handle pixel format enumeration
- * @sd : pointer to v4l2 subdev structure
- * @fh : V4L2 subdev file handle
- * @code : pointer to v4l2_subdev_mbus_code_enum structure
- * return -EINVAL or zero on success
- */
-static int resizer_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- struct isp_res_device *res = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
-
- if (code->pad == RESZ_PAD_SINK) {
- if (code->index >= ARRAY_SIZE(resizer_formats))
- return -EINVAL;
-
- code->code = resizer_formats[code->index];
- } else {
- if (code->index != 0)
- return -EINVAL;
-
- format = __resizer_get_format(res, fh, RESZ_PAD_SINK,
- V4L2_SUBDEV_FORMAT_TRY);
- code->code = format->code;
- }
-
- return 0;
-}
-
-static int resizer_enum_frame_size(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_frame_size_enum *fse)
-{
- struct isp_res_device *res = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt format;
-
- if (fse->index != 0)
- return -EINVAL;
-
- format.code = fse->code;
- format.width = 1;
- format.height = 1;
- resizer_try_format(res, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
- fse->min_width = format.width;
- fse->min_height = format.height;
-
- if (format.code != fse->code)
- return -EINVAL;
-
- format.code = fse->code;
- format.width = -1;
- format.height = -1;
- resizer_try_format(res, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
- fse->max_width = format.width;
- fse->max_height = format.height;
-
- return 0;
-}
-
-/*
- * resizer_get_format - Handle get format by pads subdev method
- * @sd : pointer to v4l2 subdev structure
- * @fh : V4L2 subdev file handle
- * @fmt : pointer to v4l2 subdev format structure
- * return -EINVAL or zero on success
- */
-static int resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct isp_res_device *res = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
-
- format = __resizer_get_format(res, fh, fmt->pad, fmt->which);
- if (format == NULL)
- return -EINVAL;
-
- fmt->format = *format;
- return 0;
-}
-
-/*
- * resizer_set_format - Handle set format by pads subdev method
- * @sd : pointer to v4l2 subdev structure
- * @fh : V4L2 subdev file handle
- * @fmt : pointer to v4l2 subdev format structure
- * return -EINVAL or zero on success
- */
-static int resizer_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct isp_res_device *res = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *format;
- struct v4l2_rect *crop;
-
- format = __resizer_get_format(res, fh, fmt->pad, fmt->which);
- if (format == NULL)
- return -EINVAL;
-
- resizer_try_format(res, fh, fmt->pad, &fmt->format, fmt->which);
- *format = fmt->format;
-
- if (fmt->pad == RESZ_PAD_SINK) {
- /* reset crop rectangle */
- crop = __resizer_get_crop(res, fh, fmt->which);
- crop->left = 0;
- crop->top = 0;
- crop->width = fmt->format.width;
- crop->height = fmt->format.height;
-
- /* Propagate the format from sink to source */
- format = __resizer_get_format(res, fh, RESZ_PAD_SOURCE,
- fmt->which);
- *format = fmt->format;
- resizer_try_format(res, fh, RESZ_PAD_SOURCE, format,
- fmt->which);
- }
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- /* Compute and store the active crop rectangle and resizer
- * ratios. format already points to the source pad active
- * format.
- */
- res->crop.active = res->crop.request;
- resizer_calc_ratios(res, &res->crop.active, format,
- &res->ratio);
- }
-
- return 0;
-}
-
-/*
- * resizer_init_formats - Initialize formats on all pads
- * @sd: ISP resizer V4L2 subdevice
- * @fh: V4L2 subdev file handle
- *
- * Initialize all pad formats with default values. If fh is not NULL, try
- * formats are initialized on the file handle. Otherwise active formats are
- * initialized on the device.
- */
-static int resizer_init_formats(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh)
-{
- struct v4l2_subdev_format format;
-
- memset(&format, 0, sizeof(format));
- format.pad = RESZ_PAD_SINK;
- format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
- format.format.code = V4L2_MBUS_FMT_YUYV8_1X16;
- format.format.width = 4096;
- format.format.height = 4096;
- resizer_set_format(sd, fh, &format);
-
- return 0;
-}
-
-/* subdev video operations */
-static const struct v4l2_subdev_video_ops resizer_v4l2_video_ops = {
- .s_stream = resizer_set_stream,
-};
-
-/* subdev pad operations */
-static const struct v4l2_subdev_pad_ops resizer_v4l2_pad_ops = {
- .enum_mbus_code = resizer_enum_mbus_code,
- .enum_frame_size = resizer_enum_frame_size,
- .get_fmt = resizer_get_format,
- .set_fmt = resizer_set_format,
- .get_selection = resizer_get_selection,
- .set_selection = resizer_set_selection,
-};
-
-/* subdev operations */
-static const struct v4l2_subdev_ops resizer_v4l2_ops = {
- .video = &resizer_v4l2_video_ops,
- .pad = &resizer_v4l2_pad_ops,
-};
-
-/* subdev internal operations */
-static const struct v4l2_subdev_internal_ops resizer_v4l2_internal_ops = {
- .open = resizer_init_formats,
-};
-
-/* -----------------------------------------------------------------------------
- * Media entity operations
- */
-
-/*
- * resizer_link_setup - Setup resizer connections.
- * @entity : Pointer to media entity structure
- * @local : Pointer to local pad array
- * @remote : Pointer to remote pad array
- * @flags : Link flags
- * return -EINVAL or zero on success
- */
-static int resizer_link_setup(struct media_entity *entity,
- const struct media_pad *local,
- const struct media_pad *remote, u32 flags)
-{
- struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
- struct isp_res_device *res = v4l2_get_subdevdata(sd);
-
- switch (local->index | media_entity_type(remote->entity)) {
- case RESZ_PAD_SINK | MEDIA_ENT_T_DEVNODE:
- /* read from memory */
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (res->input == RESIZER_INPUT_VP)
- return -EBUSY;
- res->input = RESIZER_INPUT_MEMORY;
- } else {
- if (res->input == RESIZER_INPUT_MEMORY)
- res->input = RESIZER_INPUT_NONE;
- }
- break;
-
- case RESZ_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
- /* read from ccdc or previewer */
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (res->input == RESIZER_INPUT_MEMORY)
- return -EBUSY;
- res->input = RESIZER_INPUT_VP;
- } else {
- if (res->input == RESIZER_INPUT_VP)
- res->input = RESIZER_INPUT_NONE;
- }
- break;
-
- case RESZ_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
- /* resizer always write to memory */
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* media operations */
-static const struct media_entity_operations resizer_media_ops = {
- .link_setup = resizer_link_setup,
- .link_validate = v4l2_subdev_link_validate,
-};
-
-void omap3isp_resizer_unregister_entities(struct isp_res_device *res)
-{
- v4l2_device_unregister_subdev(&res->subdev);
- omap3isp_video_unregister(&res->video_in);
- omap3isp_video_unregister(&res->video_out);
-}
-
-int omap3isp_resizer_register_entities(struct isp_res_device *res,
- struct v4l2_device *vdev)
-{
- int ret;
-
- /* Register the subdev and video nodes. */
- ret = v4l2_device_register_subdev(vdev, &res->subdev);
- if (ret < 0)
- goto error;
-
- ret = omap3isp_video_register(&res->video_in, vdev);
- if (ret < 0)
- goto error;
-
- ret = omap3isp_video_register(&res->video_out, vdev);
- if (ret < 0)
- goto error;
-
- return 0;
-
-error:
- omap3isp_resizer_unregister_entities(res);
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * ISP resizer initialization and cleanup
- */
-
-/*
- * resizer_init_entities - Initialize resizer subdev and media entity.
- * @res : Pointer to resizer device structure
- * return -ENOMEM or zero on success
- */
-static int resizer_init_entities(struct isp_res_device *res)
-{
- struct v4l2_subdev *sd = &res->subdev;
- struct media_pad *pads = res->pads;
- struct media_entity *me = &sd->entity;
- int ret;
-
- res->input = RESIZER_INPUT_NONE;
-
- v4l2_subdev_init(sd, &resizer_v4l2_ops);
- sd->internal_ops = &resizer_v4l2_internal_ops;
- strlcpy(sd->name, "OMAP3 ISP resizer", sizeof(sd->name));
- sd->grp_id = 1 << 16; /* group ID for isp subdevs */
- v4l2_set_subdevdata(sd, res);
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- pads[RESZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- pads[RESZ_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
-
- me->ops = &resizer_media_ops;
- ret = media_entity_init(me, RESZ_PADS_NUM, pads, 0);
- if (ret < 0)
- return ret;
-
- resizer_init_formats(sd, NULL);
-
- res->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- res->video_in.ops = &resizer_video_ops;
- res->video_in.isp = to_isp_device(res);
- res->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
- res->video_in.bpl_alignment = 32;
- res->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- res->video_out.ops = &resizer_video_ops;
- res->video_out.isp = to_isp_device(res);
- res->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
- res->video_out.bpl_alignment = 32;
-
- ret = omap3isp_video_init(&res->video_in, "resizer");
- if (ret < 0)
- goto error_video_in;
-
- ret = omap3isp_video_init(&res->video_out, "resizer");
- if (ret < 0)
- goto error_video_out;
-
- /* Connect the video nodes to the resizer subdev. */
- ret = media_entity_create_link(&res->video_in.video.entity, 0,
- &res->subdev.entity, RESZ_PAD_SINK, 0);
- if (ret < 0)
- goto error_link;
-
- ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
- &res->video_out.video.entity, 0, 0);
- if (ret < 0)
- goto error_link;
-
- return 0;
-
-error_link:
- omap3isp_video_cleanup(&res->video_out);
-error_video_out:
- omap3isp_video_cleanup(&res->video_in);
-error_video_in:
- media_entity_cleanup(&res->subdev.entity);
- return ret;
-}
-
-/*
- * isp_resizer_init - Resizer initialization.
- * @isp : Pointer to ISP device
- * return -ENOMEM or zero on success
- */
-int omap3isp_resizer_init(struct isp_device *isp)
-{
- struct isp_res_device *res = &isp->isp_res;
-
- init_waitqueue_head(&res->wait);
- atomic_set(&res->stopping, 0);
- return resizer_init_entities(res);
-}
-
-void omap3isp_resizer_cleanup(struct isp_device *isp)
-{
- struct isp_res_device *res = &isp->isp_res;
-
- omap3isp_video_cleanup(&res->video_in);
- omap3isp_video_cleanup(&res->video_out);
- media_entity_cleanup(&res->subdev.entity);
-}
diff --git a/drivers/media/video/omap3isp/ispresizer.h b/drivers/media/video/omap3isp/ispresizer.h
deleted file mode 100644
index 70c1c0e1bbd..00000000000
--- a/drivers/media/video/omap3isp/ispresizer.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * ispresizer.h
- *
- * TI OMAP3 ISP - Resizer module
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef OMAP3_ISP_RESIZER_H
-#define OMAP3_ISP_RESIZER_H
-
-#include <linux/types.h>
-
-/*
- * Constants for filter coefficents count
- */
-#define COEFF_CNT 32
-
-/*
- * struct isprsz_coef - Structure for resizer filter coeffcients.
- * @h_filter_coef_4tap: Horizontal filter coefficients for 8-phase/4-tap
- * mode (.5x-4x)
- * @v_filter_coef_4tap: Vertical filter coefficients for 8-phase/4-tap
- * mode (.5x-4x)
- * @h_filter_coef_7tap: Horizontal filter coefficients for 4-phase/7-tap
- * mode (.25x-.5x)
- * @v_filter_coef_7tap: Vertical filter coefficients for 4-phase/7-tap
- * mode (.25x-.5x)
- */
-struct isprsz_coef {
- u16 h_filter_coef_4tap[32];
- u16 v_filter_coef_4tap[32];
- /* Every 8th value is a dummy value in the following arrays: */
- u16 h_filter_coef_7tap[32];
- u16 v_filter_coef_7tap[32];
-};
-
-/* Chrominance horizontal algorithm */
-enum resizer_chroma_algo {
- RSZ_THE_SAME = 0, /* Chrominance the same as Luminance */
- RSZ_BILINEAR = 1, /* Chrominance uses bilinear interpolation */
-};
-
-/* Resizer input type select */
-enum resizer_colors_type {
- RSZ_YUV422 = 0, /* YUV422 color is interleaved */
- RSZ_COLOR8 = 1, /* Color separate data on 8 bits */
-};
-
-/*
- * Structure for horizontal and vertical resizing value
- */
-struct resizer_ratio {
- u32 horz;
- u32 vert;
-};
-
-/*
- * Structure for luminance enhancer parameters.
- */
-struct resizer_luma_yenh {
- u8 algo; /* algorithm select. */
- u8 gain; /* maximum gain. */
- u8 slope; /* slope. */
- u8 core; /* core offset. */
-};
-
-enum resizer_input_entity {
- RESIZER_INPUT_NONE,
- RESIZER_INPUT_VP, /* input video port - prev or ccdc */
- RESIZER_INPUT_MEMORY,
-};
-
-/* Sink and source resizer pads */
-#define RESZ_PAD_SINK 0
-#define RESZ_PAD_SOURCE 1
-#define RESZ_PADS_NUM 2
-
-/*
- * struct isp_res_device - OMAP3 ISP resizer module
- * @crop.request: Crop rectangle requested by the user
- * @crop.active: Active crop rectangle (based on hardware requirements)
- */
-struct isp_res_device {
- struct v4l2_subdev subdev;
- struct media_pad pads[RESZ_PADS_NUM];
- struct v4l2_mbus_framefmt formats[RESZ_PADS_NUM];
-
- enum resizer_input_entity input;
- struct isp_video video_in;
- struct isp_video video_out;
-
- u32 addr_base; /* stored source buffer address in memory mode */
- u32 crop_offset; /* additional offset for crop in memory mode */
- struct resizer_ratio ratio;
- int pm_state;
- unsigned int applycrop:1;
- enum isp_pipeline_stream_state state;
- wait_queue_head_t wait;
- atomic_t stopping;
-
- struct {
- struct v4l2_rect request;
- struct v4l2_rect active;
- } crop;
-};
-
-struct isp_device;
-
-int omap3isp_resizer_init(struct isp_device *isp);
-void omap3isp_resizer_cleanup(struct isp_device *isp);
-
-int omap3isp_resizer_register_entities(struct isp_res_device *res,
- struct v4l2_device *vdev);
-void omap3isp_resizer_unregister_entities(struct isp_res_device *res);
-void omap3isp_resizer_isr_frame_sync(struct isp_res_device *res);
-void omap3isp_resizer_isr(struct isp_res_device *isp_res);
-
-void omap3isp_resizer_max_rate(struct isp_res_device *res,
- unsigned int *max_rate);
-
-void omap3isp_resizer_suspend(struct isp_res_device *isp_res);
-
-void omap3isp_resizer_resume(struct isp_res_device *isp_res);
-
-int omap3isp_resizer_busy(struct isp_res_device *isp_res);
-
-#endif /* OMAP3_ISP_RESIZER_H */
diff --git a/drivers/media/video/omap3isp/ispstat.c b/drivers/media/video/omap3isp/ispstat.c
deleted file mode 100644
index b8640be692f..00000000000
--- a/drivers/media/video/omap3isp/ispstat.c
+++ /dev/null
@@ -1,1102 +0,0 @@
-/*
- * ispstat.c
- *
- * TI OMAP3 ISP - Statistics core
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc
- *
- * Contacts: David Cohen <dacohen@gmail.com>
- * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-#include "isp.h"
-
-#define IS_COHERENT_BUF(stat) ((stat)->dma_ch >= 0)
-
-/*
- * MAGIC_SIZE must always be the greatest common divisor of
- * AEWB_PACKET_SIZE and AF_PAXEL_SIZE.
- */
-#define MAGIC_SIZE 16
-#define MAGIC_NUM 0x55
-
-/* HACK: AF module seems to be writing one more paxel data than it should. */
-#define AF_EXTRA_DATA OMAP3ISP_AF_PAXEL_SIZE
-
-/*
- * HACK: H3A modules go to an invalid state after have a SBL overflow. It makes
- * the next buffer to start to be written in the same point where the overflow
- * occurred instead of the configured address. The only known way to make it to
- * go back to a valid state is having a valid buffer processing. Of course it
- * requires at least a doubled buffer size to avoid an access to invalid memory
- * region. But it does not fix everything. It may happen more than one
- * consecutive SBL overflows. In that case, it might be unpredictable how many
- * buffers the allocated memory should fit. For that case, a recover
- * configuration was created. It produces the minimum buffer size for each H3A
- * module and decrease the change for more SBL overflows. This recover state
- * will be enabled every time a SBL overflow occur. As the output buffer size
- * isn't big, it's possible to have an extra size able to fit many recover
- * buffers making it extreamily unlikely to have an access to invalid memory
- * region.
- */
-#define NUM_H3A_RECOVER_BUFS 10
-
-/*
- * HACK: Because of HW issues the generic layer sometimes need to have
- * different behaviour for different statistic modules.
- */
-#define IS_H3A_AF(stat) ((stat) == &(stat)->isp->isp_af)
-#define IS_H3A_AEWB(stat) ((stat) == &(stat)->isp->isp_aewb)
-#define IS_H3A(stat) (IS_H3A_AF(stat) || IS_H3A_AEWB(stat))
-
-static void __isp_stat_buf_sync_magic(struct ispstat *stat,
- struct ispstat_buffer *buf,
- u32 buf_size, enum dma_data_direction dir,
- void (*dma_sync)(struct device *,
- dma_addr_t, unsigned long, size_t,
- enum dma_data_direction))
-{
- struct device *dev = stat->isp->dev;
- struct page *pg;
- dma_addr_t dma_addr;
- u32 offset;
-
- /* Initial magic words */
- pg = vmalloc_to_page(buf->virt_addr);
- dma_addr = pfn_to_dma(dev, page_to_pfn(pg));
- dma_sync(dev, dma_addr, 0, MAGIC_SIZE, dir);
-
- /* Final magic words */
- pg = vmalloc_to_page(buf->virt_addr + buf_size);
- dma_addr = pfn_to_dma(dev, page_to_pfn(pg));
- offset = ((u32)buf->virt_addr + buf_size) & ~PAGE_MASK;
- dma_sync(dev, dma_addr, offset, MAGIC_SIZE, dir);
-}
-
-static void isp_stat_buf_sync_magic_for_device(struct ispstat *stat,
- struct ispstat_buffer *buf,
- u32 buf_size,
- enum dma_data_direction dir)
-{
- if (IS_COHERENT_BUF(stat))
- return;
-
- __isp_stat_buf_sync_magic(stat, buf, buf_size, dir,
- dma_sync_single_range_for_device);
-}
-
-static void isp_stat_buf_sync_magic_for_cpu(struct ispstat *stat,
- struct ispstat_buffer *buf,
- u32 buf_size,
- enum dma_data_direction dir)
-{
- if (IS_COHERENT_BUF(stat))
- return;
-
- __isp_stat_buf_sync_magic(stat, buf, buf_size, dir,
- dma_sync_single_range_for_cpu);
-}
-
-static int isp_stat_buf_check_magic(struct ispstat *stat,
- struct ispstat_buffer *buf)
-{
- const u32 buf_size = IS_H3A_AF(stat) ?
- buf->buf_size + AF_EXTRA_DATA : buf->buf_size;
- u8 *w;
- u8 *end;
- int ret = -EINVAL;
-
- isp_stat_buf_sync_magic_for_cpu(stat, buf, buf_size, DMA_FROM_DEVICE);
-
- /* Checking initial magic numbers. They shouldn't be here anymore. */
- for (w = buf->virt_addr, end = w + MAGIC_SIZE; w < end; w++)
- if (likely(*w != MAGIC_NUM))
- ret = 0;
-
- if (ret) {
- dev_dbg(stat->isp->dev, "%s: beginning magic check does not "
- "match.\n", stat->subdev.name);
- return ret;
- }
-
- /* Checking magic numbers at the end. They must be still here. */
- for (w = buf->virt_addr + buf_size, end = w + MAGIC_SIZE;
- w < end; w++) {
- if (unlikely(*w != MAGIC_NUM)) {
- dev_dbg(stat->isp->dev, "%s: endding magic check does "
- "not match.\n", stat->subdev.name);
- return -EINVAL;
- }
- }
-
- isp_stat_buf_sync_magic_for_device(stat, buf, buf_size,
- DMA_FROM_DEVICE);
-
- return 0;
-}
-
-static void isp_stat_buf_insert_magic(struct ispstat *stat,
- struct ispstat_buffer *buf)
-{
- const u32 buf_size = IS_H3A_AF(stat) ?
- stat->buf_size + AF_EXTRA_DATA : stat->buf_size;
-
- isp_stat_buf_sync_magic_for_cpu(stat, buf, buf_size, DMA_FROM_DEVICE);
-
- /*
- * Inserting MAGIC_NUM at the beginning and end of the buffer.
- * buf->buf_size is set only after the buffer is queued. For now the
- * right buf_size for the current configuration is pointed by
- * stat->buf_size.
- */
- memset(buf->virt_addr, MAGIC_NUM, MAGIC_SIZE);
- memset(buf->virt_addr + buf_size, MAGIC_NUM, MAGIC_SIZE);
-
- isp_stat_buf_sync_magic_for_device(stat, buf, buf_size,
- DMA_BIDIRECTIONAL);
-}
-
-static void isp_stat_buf_sync_for_device(struct ispstat *stat,
- struct ispstat_buffer *buf)
-{
- if (IS_COHERENT_BUF(stat))
- return;
-
- dma_sync_sg_for_device(stat->isp->dev, buf->iovm->sgt->sgl,
- buf->iovm->sgt->nents, DMA_FROM_DEVICE);
-}
-
-static void isp_stat_buf_sync_for_cpu(struct ispstat *stat,
- struct ispstat_buffer *buf)
-{
- if (IS_COHERENT_BUF(stat))
- return;
-
- dma_sync_sg_for_cpu(stat->isp->dev, buf->iovm->sgt->sgl,
- buf->iovm->sgt->nents, DMA_FROM_DEVICE);
-}
-
-static void isp_stat_buf_clear(struct ispstat *stat)
-{
- int i;
-
- for (i = 0; i < STAT_MAX_BUFS; i++)
- stat->buf[i].empty = 1;
-}
-
-static struct ispstat_buffer *
-__isp_stat_buf_find(struct ispstat *stat, int look_empty)
-{
- struct ispstat_buffer *found = NULL;
- int i;
-
- for (i = 0; i < STAT_MAX_BUFS; i++) {
- struct ispstat_buffer *curr = &stat->buf[i];
-
- /*
- * Don't select the buffer which is being copied to
- * userspace or used by the module.
- */
- if (curr == stat->locked_buf || curr == stat->active_buf)
- continue;
-
- /* Don't select uninitialised buffers if it's not required */
- if (!look_empty && curr->empty)
- continue;
-
- /* Pick uninitialised buffer over anything else if look_empty */
- if (curr->empty) {
- found = curr;
- break;
- }
-
- /* Choose the oldest buffer */
- if (!found ||
- (s32)curr->frame_number - (s32)found->frame_number < 0)
- found = curr;
- }
-
- return found;
-}
-
-static inline struct ispstat_buffer *
-isp_stat_buf_find_oldest(struct ispstat *stat)
-{
- return __isp_stat_buf_find(stat, 0);
-}
-
-static inline struct ispstat_buffer *
-isp_stat_buf_find_oldest_or_empty(struct ispstat *stat)
-{
- return __isp_stat_buf_find(stat, 1);
-}
-
-static int isp_stat_buf_queue(struct ispstat *stat)
-{
- if (!stat->active_buf)
- return STAT_NO_BUF;
-
- do_gettimeofday(&stat->active_buf->ts);
-
- stat->active_buf->buf_size = stat->buf_size;
- if (isp_stat_buf_check_magic(stat, stat->active_buf)) {
- dev_dbg(stat->isp->dev, "%s: data wasn't properly written.\n",
- stat->subdev.name);
- return STAT_NO_BUF;
- }
- stat->active_buf->config_counter = stat->config_counter;
- stat->active_buf->frame_number = stat->frame_number;
- stat->active_buf->empty = 0;
- stat->active_buf = NULL;
-
- return STAT_BUF_DONE;
-}
-
-/* Get next free buffer to write the statistics to and mark it active. */
-static void isp_stat_buf_next(struct ispstat *stat)
-{
- if (unlikely(stat->active_buf))
- /* Overwriting unused active buffer */
- dev_dbg(stat->isp->dev, "%s: new buffer requested without "
- "queuing active one.\n",
- stat->subdev.name);
- else
- stat->active_buf = isp_stat_buf_find_oldest_or_empty(stat);
-}
-
-static void isp_stat_buf_release(struct ispstat *stat)
-{
- unsigned long flags;
-
- isp_stat_buf_sync_for_device(stat, stat->locked_buf);
- spin_lock_irqsave(&stat->isp->stat_lock, flags);
- stat->locked_buf = NULL;
- spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
-}
-
-/* Get buffer to userspace. */
-static struct ispstat_buffer *isp_stat_buf_get(struct ispstat *stat,
- struct omap3isp_stat_data *data)
-{
- int rval = 0;
- unsigned long flags;
- struct ispstat_buffer *buf;
-
- spin_lock_irqsave(&stat->isp->stat_lock, flags);
-
- while (1) {
- buf = isp_stat_buf_find_oldest(stat);
- if (!buf) {
- spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
- dev_dbg(stat->isp->dev, "%s: cannot find a buffer.\n",
- stat->subdev.name);
- return ERR_PTR(-EBUSY);
- }
- if (isp_stat_buf_check_magic(stat, buf)) {
- dev_dbg(stat->isp->dev, "%s: current buffer has "
- "corrupted data\n.", stat->subdev.name);
- /* Mark empty because it doesn't have valid data. */
- buf->empty = 1;
- } else {
- /* Buffer isn't corrupted. */
- break;
- }
- }
-
- stat->locked_buf = buf;
-
- spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
-
- if (buf->buf_size > data->buf_size) {
- dev_warn(stat->isp->dev, "%s: userspace's buffer size is "
- "not enough.\n", stat->subdev.name);
- isp_stat_buf_release(stat);
- return ERR_PTR(-EINVAL);
- }
-
- isp_stat_buf_sync_for_cpu(stat, buf);
-
- rval = copy_to_user(data->buf,
- buf->virt_addr,
- buf->buf_size);
-
- if (rval) {
- dev_info(stat->isp->dev,
- "%s: failed copying %d bytes of stat data\n",
- stat->subdev.name, rval);
- buf = ERR_PTR(-EFAULT);
- isp_stat_buf_release(stat);
- }
-
- return buf;
-}
-
-static void isp_stat_bufs_free(struct ispstat *stat)
-{
- struct isp_device *isp = stat->isp;
- int i;
-
- for (i = 0; i < STAT_MAX_BUFS; i++) {
- struct ispstat_buffer *buf = &stat->buf[i];
-
- if (!IS_COHERENT_BUF(stat)) {
- if (IS_ERR_OR_NULL((void *)buf->iommu_addr))
- continue;
- if (buf->iovm)
- dma_unmap_sg(isp->dev, buf->iovm->sgt->sgl,
- buf->iovm->sgt->nents,
- DMA_FROM_DEVICE);
- omap_iommu_vfree(isp->domain, isp->dev,
- buf->iommu_addr);
- } else {
- if (!buf->virt_addr)
- continue;
- dma_free_coherent(stat->isp->dev, stat->buf_alloc_size,
- buf->virt_addr, buf->dma_addr);
- }
- buf->iommu_addr = 0;
- buf->iovm = NULL;
- buf->dma_addr = 0;
- buf->virt_addr = NULL;
- buf->empty = 1;
- }
-
- dev_dbg(stat->isp->dev, "%s: all buffers were freed.\n",
- stat->subdev.name);
-
- stat->buf_alloc_size = 0;
- stat->active_buf = NULL;
-}
-
-static int isp_stat_bufs_alloc_iommu(struct ispstat *stat, unsigned int size)
-{
- struct isp_device *isp = stat->isp;
- int i;
-
- stat->buf_alloc_size = size;
-
- for (i = 0; i < STAT_MAX_BUFS; i++) {
- struct ispstat_buffer *buf = &stat->buf[i];
- struct iovm_struct *iovm;
-
- WARN_ON(buf->dma_addr);
- buf->iommu_addr = omap_iommu_vmalloc(isp->domain, isp->dev, 0,
- size, IOMMU_FLAG);
- if (IS_ERR((void *)buf->iommu_addr)) {
- dev_err(stat->isp->dev,
- "%s: Can't acquire memory for "
- "buffer %d\n", stat->subdev.name, i);
- isp_stat_bufs_free(stat);
- return -ENOMEM;
- }
-
- iovm = omap_find_iovm_area(isp->dev, buf->iommu_addr);
- if (!iovm ||
- !dma_map_sg(isp->dev, iovm->sgt->sgl, iovm->sgt->nents,
- DMA_FROM_DEVICE)) {
- isp_stat_bufs_free(stat);
- return -ENOMEM;
- }
- buf->iovm = iovm;
-
- buf->virt_addr = omap_da_to_va(stat->isp->dev,
- (u32)buf->iommu_addr);
- buf->empty = 1;
- dev_dbg(stat->isp->dev, "%s: buffer[%d] allocated."
- "iommu_addr=0x%08lx virt_addr=0x%08lx",
- stat->subdev.name, i, buf->iommu_addr,
- (unsigned long)buf->virt_addr);
- }
-
- return 0;
-}
-
-static int isp_stat_bufs_alloc_dma(struct ispstat *stat, unsigned int size)
-{
- int i;
-
- stat->buf_alloc_size = size;
-
- for (i = 0; i < STAT_MAX_BUFS; i++) {
- struct ispstat_buffer *buf = &stat->buf[i];
-
- WARN_ON(buf->iommu_addr);
- buf->virt_addr = dma_alloc_coherent(stat->isp->dev, size,
- &buf->dma_addr, GFP_KERNEL | GFP_DMA);
-
- if (!buf->virt_addr || !buf->dma_addr) {
- dev_info(stat->isp->dev,
- "%s: Can't acquire memory for "
- "DMA buffer %d\n", stat->subdev.name, i);
- isp_stat_bufs_free(stat);
- return -ENOMEM;
- }
- buf->empty = 1;
-
- dev_dbg(stat->isp->dev, "%s: buffer[%d] allocated."
- "dma_addr=0x%08lx virt_addr=0x%08lx\n",
- stat->subdev.name, i, (unsigned long)buf->dma_addr,
- (unsigned long)buf->virt_addr);
- }
-
- return 0;
-}
-
-static int isp_stat_bufs_alloc(struct ispstat *stat, u32 size)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&stat->isp->stat_lock, flags);
-
- BUG_ON(stat->locked_buf != NULL);
-
- /* Are the old buffers big enough? */
- if (stat->buf_alloc_size >= size) {
- spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
- return 0;
- }
-
- if (stat->state != ISPSTAT_DISABLED || stat->buf_processing) {
- dev_info(stat->isp->dev,
- "%s: trying to allocate memory when busy\n",
- stat->subdev.name);
- spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
- return -EBUSY;
- }
-
- spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
-
- isp_stat_bufs_free(stat);
-
- if (IS_COHERENT_BUF(stat))
- return isp_stat_bufs_alloc_dma(stat, size);
- else
- return isp_stat_bufs_alloc_iommu(stat, size);
-}
-
-static void isp_stat_queue_event(struct ispstat *stat, int err)
-{
- struct video_device *vdev = stat->subdev.devnode;
- struct v4l2_event event;
- struct omap3isp_stat_event_status *status = (void *)event.u.data;
-
- memset(&event, 0, sizeof(event));
- if (!err) {
- status->frame_number = stat->frame_number;
- status->config_counter = stat->config_counter;
- } else {
- status->buf_err = 1;
- }
- event.type = stat->event_type;
- v4l2_event_queue(vdev, &event);
-}
-
-
-/*
- * omap3isp_stat_request_statistics - Request statistics.
- * @data: Pointer to return statistics data.
- *
- * Returns 0 if successful.
- */
-int omap3isp_stat_request_statistics(struct ispstat *stat,
- struct omap3isp_stat_data *data)
-{
- struct ispstat_buffer *buf;
-
- if (stat->state != ISPSTAT_ENABLED) {
- dev_dbg(stat->isp->dev, "%s: engine not enabled.\n",
- stat->subdev.name);
- return -EINVAL;
- }
-
- mutex_lock(&stat->ioctl_lock);
- buf = isp_stat_buf_get(stat, data);
- if (IS_ERR(buf)) {
- mutex_unlock(&stat->ioctl_lock);
- return PTR_ERR(buf);
- }
-
- data->ts = buf->ts;
- data->config_counter = buf->config_counter;
- data->frame_number = buf->frame_number;
- data->buf_size = buf->buf_size;
-
- buf->empty = 1;
- isp_stat_buf_release(stat);
- mutex_unlock(&stat->ioctl_lock);
-
- return 0;
-}
-
-/*
- * omap3isp_stat_config - Receives new statistic engine configuration.
- * @new_conf: Pointer to config structure.
- *
- * Returns 0 if successful, -EINVAL if new_conf pointer is NULL, -ENOMEM if
- * was unable to allocate memory for the buffer, or other errors if parameters
- * are invalid.
- */
-int omap3isp_stat_config(struct ispstat *stat, void *new_conf)
-{
- int ret;
- unsigned long irqflags;
- struct ispstat_generic_config *user_cfg = new_conf;
- u32 buf_size = user_cfg->buf_size;
-
- if (!new_conf) {
- dev_dbg(stat->isp->dev, "%s: configuration is NULL\n",
- stat->subdev.name);
- return -EINVAL;
- }
-
- mutex_lock(&stat->ioctl_lock);
-
- dev_dbg(stat->isp->dev, "%s: configuring module with buffer "
- "size=0x%08lx\n", stat->subdev.name, (unsigned long)buf_size);
-
- ret = stat->ops->validate_params(stat, new_conf);
- if (ret) {
- mutex_unlock(&stat->ioctl_lock);
- dev_dbg(stat->isp->dev, "%s: configuration values are "
- "invalid.\n", stat->subdev.name);
- return ret;
- }
-
- if (buf_size != user_cfg->buf_size)
- dev_dbg(stat->isp->dev, "%s: driver has corrected buffer size "
- "request to 0x%08lx\n", stat->subdev.name,
- (unsigned long)user_cfg->buf_size);
-
- /*
- * Hack: H3A modules may need a doubled buffer size to avoid access
- * to a invalid memory address after a SBL overflow.
- * The buffer size is always PAGE_ALIGNED.
- * Hack 2: MAGIC_SIZE is added to buf_size so a magic word can be
- * inserted at the end to data integrity check purpose.
- * Hack 3: AF module writes one paxel data more than it should, so
- * the buffer allocation must consider it to avoid invalid memory
- * access.
- * Hack 4: H3A need to allocate extra space for the recover state.
- */
- if (IS_H3A(stat)) {
- buf_size = user_cfg->buf_size * 2 + MAGIC_SIZE;
- if (IS_H3A_AF(stat))
- /*
- * Adding one extra paxel data size for each recover
- * buffer + 2 regular ones.
- */
- buf_size += AF_EXTRA_DATA * (NUM_H3A_RECOVER_BUFS + 2);
- if (stat->recover_priv) {
- struct ispstat_generic_config *recover_cfg =
- stat->recover_priv;
- buf_size += recover_cfg->buf_size *
- NUM_H3A_RECOVER_BUFS;
- }
- buf_size = PAGE_ALIGN(buf_size);
- } else { /* Histogram */
- buf_size = PAGE_ALIGN(user_cfg->buf_size + MAGIC_SIZE);
- }
-
- ret = isp_stat_bufs_alloc(stat, buf_size);
- if (ret) {
- mutex_unlock(&stat->ioctl_lock);
- return ret;
- }
-
- spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
- stat->ops->set_params(stat, new_conf);
- spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
-
- /*
- * Returning the right future config_counter for this setup, so
- * userspace can *know* when it has been applied.
- */
- user_cfg->config_counter = stat->config_counter + stat->inc_config;
-
- /* Module has a valid configuration. */
- stat->configured = 1;
- dev_dbg(stat->isp->dev, "%s: module has been successfully "
- "configured.\n", stat->subdev.name);
-
- mutex_unlock(&stat->ioctl_lock);
-
- return 0;
-}
-
-/*
- * isp_stat_buf_process - Process statistic buffers.
- * @buf_state: points out if buffer is ready to be processed. It's necessary
- * because histogram needs to copy the data from internal memory
- * before be able to process the buffer.
- */
-static int isp_stat_buf_process(struct ispstat *stat, int buf_state)
-{
- int ret = STAT_NO_BUF;
-
- if (!atomic_add_unless(&stat->buf_err, -1, 0) &&
- buf_state == STAT_BUF_DONE && stat->state == ISPSTAT_ENABLED) {
- ret = isp_stat_buf_queue(stat);
- isp_stat_buf_next(stat);
- }
-
- return ret;
-}
-
-int omap3isp_stat_pcr_busy(struct ispstat *stat)
-{
- return stat->ops->busy(stat);
-}
-
-int omap3isp_stat_busy(struct ispstat *stat)
-{
- return omap3isp_stat_pcr_busy(stat) | stat->buf_processing |
- (stat->state != ISPSTAT_DISABLED);
-}
-
-/*
- * isp_stat_pcr_enable - Disables/Enables statistic engines.
- * @pcr_enable: 0/1 - Disables/Enables the engine.
- *
- * Must be called from ISP driver when the module is idle and synchronized
- * with CCDC.
- */
-static void isp_stat_pcr_enable(struct ispstat *stat, u8 pcr_enable)
-{
- if ((stat->state != ISPSTAT_ENABLING &&
- stat->state != ISPSTAT_ENABLED) && pcr_enable)
- /* Userspace has disabled the module. Aborting. */
- return;
-
- stat->ops->enable(stat, pcr_enable);
- if (stat->state == ISPSTAT_DISABLING && !pcr_enable)
- stat->state = ISPSTAT_DISABLED;
- else if (stat->state == ISPSTAT_ENABLING && pcr_enable)
- stat->state = ISPSTAT_ENABLED;
-}
-
-void omap3isp_stat_suspend(struct ispstat *stat)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&stat->isp->stat_lock, flags);
-
- if (stat->state != ISPSTAT_DISABLED)
- stat->ops->enable(stat, 0);
- if (stat->state == ISPSTAT_ENABLED)
- stat->state = ISPSTAT_SUSPENDED;
-
- spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
-}
-
-void omap3isp_stat_resume(struct ispstat *stat)
-{
- /* Module will be re-enabled with its pipeline */
- if (stat->state == ISPSTAT_SUSPENDED)
- stat->state = ISPSTAT_ENABLING;
-}
-
-static void isp_stat_try_enable(struct ispstat *stat)
-{
- unsigned long irqflags;
-
- if (stat->priv == NULL)
- /* driver wasn't initialised */
- return;
-
- spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
- if (stat->state == ISPSTAT_ENABLING && !stat->buf_processing &&
- stat->buf_alloc_size) {
- /*
- * Userspace's requested to enable the engine but it wasn't yet.
- * Let's do that now.
- */
- stat->update = 1;
- isp_stat_buf_next(stat);
- stat->ops->setup_regs(stat, stat->priv);
- isp_stat_buf_insert_magic(stat, stat->active_buf);
-
- /*
- * H3A module has some hw issues which forces the driver to
- * ignore next buffers even if it was disabled in the meantime.
- * On the other hand, Histogram shouldn't ignore buffers anymore
- * if it's being enabled.
- */
- if (!IS_H3A(stat))
- atomic_set(&stat->buf_err, 0);
-
- isp_stat_pcr_enable(stat, 1);
- spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
- dev_dbg(stat->isp->dev, "%s: module is enabled.\n",
- stat->subdev.name);
- } else {
- spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
- }
-}
-
-void omap3isp_stat_isr_frame_sync(struct ispstat *stat)
-{
- isp_stat_try_enable(stat);
-}
-
-void omap3isp_stat_sbl_overflow(struct ispstat *stat)
-{
- unsigned long irqflags;
-
- spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
- /*
- * Due to a H3A hw issue which prevents the next buffer to start from
- * the correct memory address, 2 buffers must be ignored.
- */
- atomic_set(&stat->buf_err, 2);
-
- /*
- * If more than one SBL overflow happen in a row, H3A module may access
- * invalid memory region.
- * stat->sbl_ovl_recover is set to tell to the driver to temporarily use
- * a soft configuration which helps to avoid consecutive overflows.
- */
- if (stat->recover_priv)
- stat->sbl_ovl_recover = 1;
- spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
-}
-
-/*
- * omap3isp_stat_enable - Disable/Enable statistic engine as soon as possible
- * @enable: 0/1 - Disables/Enables the engine.
- *
- * Client should configure all the module registers before this.
- * This function can be called from a userspace request.
- */
-int omap3isp_stat_enable(struct ispstat *stat, u8 enable)
-{
- unsigned long irqflags;
-
- dev_dbg(stat->isp->dev, "%s: user wants to %s module.\n",
- stat->subdev.name, enable ? "enable" : "disable");
-
- /* Prevent enabling while configuring */
- mutex_lock(&stat->ioctl_lock);
-
- spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
-
- if (!stat->configured && enable) {
- spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
- mutex_unlock(&stat->ioctl_lock);
- dev_dbg(stat->isp->dev, "%s: cannot enable module as it's "
- "never been successfully configured so far.\n",
- stat->subdev.name);
- return -EINVAL;
- }
-
- if (enable) {
- if (stat->state == ISPSTAT_DISABLING)
- /* Previous disabling request wasn't done yet */
- stat->state = ISPSTAT_ENABLED;
- else if (stat->state == ISPSTAT_DISABLED)
- /* Module is now being enabled */
- stat->state = ISPSTAT_ENABLING;
- } else {
- if (stat->state == ISPSTAT_ENABLING) {
- /* Previous enabling request wasn't done yet */
- stat->state = ISPSTAT_DISABLED;
- } else if (stat->state == ISPSTAT_ENABLED) {
- /* Module is now being disabled */
- stat->state = ISPSTAT_DISABLING;
- isp_stat_buf_clear(stat);
- }
- }
-
- spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
- mutex_unlock(&stat->ioctl_lock);
-
- return 0;
-}
-
-int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable)
-{
- struct ispstat *stat = v4l2_get_subdevdata(subdev);
-
- if (enable) {
- /*
- * Only set enable PCR bit if the module was previously
- * enabled through ioct.
- */
- isp_stat_try_enable(stat);
- } else {
- unsigned long flags;
- /* Disable PCR bit and config enable field */
- omap3isp_stat_enable(stat, 0);
- spin_lock_irqsave(&stat->isp->stat_lock, flags);
- stat->ops->enable(stat, 0);
- spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
-
- /*
- * If module isn't busy, a new interrupt may come or not to
- * set the state to DISABLED. As Histogram needs to read its
- * internal memory to clear it, let interrupt handler
- * responsible of changing state to DISABLED. If the last
- * interrupt is coming, it's still safe as the handler will
- * ignore the second time when state is already set to DISABLED.
- * It's necessary to synchronize Histogram with streamoff, once
- * the module may be considered idle before last SDMA transfer
- * starts if we return here.
- */
- if (!omap3isp_stat_pcr_busy(stat))
- omap3isp_stat_isr(stat);
-
- dev_dbg(stat->isp->dev, "%s: module is being disabled\n",
- stat->subdev.name);
- }
-
- return 0;
-}
-
-/*
- * __stat_isr - Interrupt handler for statistic drivers
- */
-static void __stat_isr(struct ispstat *stat, int from_dma)
-{
- int ret = STAT_BUF_DONE;
- int buf_processing;
- unsigned long irqflags;
- struct isp_pipeline *pipe;
-
- /*
- * stat->buf_processing must be set before disable module. It's
- * necessary to not inform too early the buffers aren't busy in case
- * of SDMA is going to be used.
- */
- spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
- if (stat->state == ISPSTAT_DISABLED) {
- spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
- return;
- }
- buf_processing = stat->buf_processing;
- stat->buf_processing = 1;
- stat->ops->enable(stat, 0);
-
- if (buf_processing && !from_dma) {
- if (stat->state == ISPSTAT_ENABLED) {
- spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
- dev_err(stat->isp->dev,
- "%s: interrupt occurred when module was still "
- "processing a buffer.\n", stat->subdev.name);
- ret = STAT_NO_BUF;
- goto out;
- } else {
- /*
- * Interrupt handler was called from streamoff when
- * the module wasn't busy anymore to ensure it is being
- * disabled after process last buffer. If such buffer
- * processing has already started, no need to do
- * anything else.
- */
- spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
- return;
- }
- }
- spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
-
- /* If it's busy we can't process this buffer anymore */
- if (!omap3isp_stat_pcr_busy(stat)) {
- if (!from_dma && stat->ops->buf_process)
- /* Module still need to copy data to buffer. */
- ret = stat->ops->buf_process(stat);
- if (ret == STAT_BUF_WAITING_DMA)
- /* Buffer is not ready yet */
- return;
-
- spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
-
- /*
- * Histogram needs to read its internal memory to clear it
- * before be disabled. For that reason, common statistic layer
- * can return only after call stat's buf_process() operator.
- */
- if (stat->state == ISPSTAT_DISABLING) {
- stat->state = ISPSTAT_DISABLED;
- spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
- stat->buf_processing = 0;
- return;
- }
- pipe = to_isp_pipeline(&stat->subdev.entity);
- stat->frame_number = atomic_read(&pipe->frame_number);
-
- /*
- * Before this point, 'ret' stores the buffer's status if it's
- * ready to be processed. Afterwards, it holds the status if
- * it was processed successfully.
- */
- ret = isp_stat_buf_process(stat, ret);
-
- if (likely(!stat->sbl_ovl_recover)) {
- stat->ops->setup_regs(stat, stat->priv);
- } else {
- /*
- * Using recover config to increase the chance to have
- * a good buffer processing and make the H3A module to
- * go back to a valid state.
- */
- stat->update = 1;
- stat->ops->setup_regs(stat, stat->recover_priv);
- stat->sbl_ovl_recover = 0;
-
- /*
- * Set 'update' in case of the module needs to use
- * regular configuration after next buffer.
- */
- stat->update = 1;
- }
-
- isp_stat_buf_insert_magic(stat, stat->active_buf);
-
- /*
- * Hack: H3A modules may access invalid memory address or send
- * corrupted data to userspace if more than 1 SBL overflow
- * happens in a row without re-writing its buffer's start memory
- * address in the meantime. Such situation is avoided if the
- * module is not immediately re-enabled when the ISR misses the
- * timing to process the buffer and to setup the registers.
- * Because of that, pcr_enable(1) was moved to inside this 'if'
- * block. But the next interruption will still happen as during
- * pcr_enable(0) the module was busy.
- */
- isp_stat_pcr_enable(stat, 1);
- spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
- } else {
- /*
- * If a SBL overflow occurs and the H3A driver misses the timing
- * to process the buffer, stat->buf_err is set and won't be
- * cleared now. So the next buffer will be correctly ignored.
- * It's necessary due to a hw issue which makes the next H3A
- * buffer to start from the memory address where the previous
- * one stopped, instead of start where it was configured to.
- * Do not "stat->buf_err = 0" here.
- */
-
- if (stat->ops->buf_process)
- /*
- * Driver may need to erase current data prior to
- * process a new buffer. If it misses the timing, the
- * next buffer might be wrong. So should be ignored.
- * It happens only for Histogram.
- */
- atomic_set(&stat->buf_err, 1);
-
- ret = STAT_NO_BUF;
- dev_dbg(stat->isp->dev, "%s: cannot process buffer, "
- "device is busy.\n", stat->subdev.name);
- }
-
-out:
- stat->buf_processing = 0;
- isp_stat_queue_event(stat, ret != STAT_BUF_DONE);
-}
-
-void omap3isp_stat_isr(struct ispstat *stat)
-{
- __stat_isr(stat, 0);
-}
-
-void omap3isp_stat_dma_isr(struct ispstat *stat)
-{
- __stat_isr(stat, 1);
-}
-
-int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
- struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
-{
- struct ispstat *stat = v4l2_get_subdevdata(subdev);
-
- if (sub->type != stat->event_type)
- return -EINVAL;
-
- return v4l2_event_subscribe(fh, sub, STAT_NEVENTS, NULL);
-}
-
-int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
- struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
-{
- return v4l2_event_unsubscribe(fh, sub);
-}
-
-void omap3isp_stat_unregister_entities(struct ispstat *stat)
-{
- v4l2_device_unregister_subdev(&stat->subdev);
-}
-
-int omap3isp_stat_register_entities(struct ispstat *stat,
- struct v4l2_device *vdev)
-{
- return v4l2_device_register_subdev(vdev, &stat->subdev);
-}
-
-static int isp_stat_init_entities(struct ispstat *stat, const char *name,
- const struct v4l2_subdev_ops *sd_ops)
-{
- struct v4l2_subdev *subdev = &stat->subdev;
- struct media_entity *me = &subdev->entity;
-
- v4l2_subdev_init(subdev, sd_ops);
- snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "OMAP3 ISP %s", name);
- subdev->grp_id = 1 << 16; /* group ID for isp subdevs */
- subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
- v4l2_set_subdevdata(subdev, stat);
-
- stat->pad.flags = MEDIA_PAD_FL_SINK;
- me->ops = NULL;
-
- return media_entity_init(me, 1, &stat->pad, 0);
-}
-
-int omap3isp_stat_init(struct ispstat *stat, const char *name,
- const struct v4l2_subdev_ops *sd_ops)
-{
- int ret;
-
- stat->buf = kcalloc(STAT_MAX_BUFS, sizeof(*stat->buf), GFP_KERNEL);
- if (!stat->buf)
- return -ENOMEM;
-
- isp_stat_buf_clear(stat);
- mutex_init(&stat->ioctl_lock);
- atomic_set(&stat->buf_err, 0);
-
- ret = isp_stat_init_entities(stat, name, sd_ops);
- if (ret < 0) {
- mutex_destroy(&stat->ioctl_lock);
- kfree(stat->buf);
- }
-
- return ret;
-}
-
-void omap3isp_stat_cleanup(struct ispstat *stat)
-{
- media_entity_cleanup(&stat->subdev.entity);
- mutex_destroy(&stat->ioctl_lock);
- isp_stat_bufs_free(stat);
- kfree(stat->buf);
-}
diff --git a/drivers/media/video/omap3isp/ispstat.h b/drivers/media/video/omap3isp/ispstat.h
deleted file mode 100644
index 9b7c8654dc8..00000000000
--- a/drivers/media/video/omap3isp/ispstat.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * ispstat.h
- *
- * TI OMAP3 ISP - Statistics core
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc
- *
- * Contacts: David Cohen <dacohen@gmail.com>
- * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef OMAP3_ISP_STAT_H
-#define OMAP3_ISP_STAT_H
-
-#include <linux/types.h>
-#include <linux/omap3isp.h>
-#include <plat/dma.h>
-#include <media/v4l2-event.h>
-
-#include "isp.h"
-#include "ispvideo.h"
-
-#define STAT_MAX_BUFS 5
-#define STAT_NEVENTS 8
-
-#define STAT_BUF_DONE 0 /* Buffer is ready */
-#define STAT_NO_BUF 1 /* An error has occurred */
-#define STAT_BUF_WAITING_DMA 2 /* Histogram only: DMA is running */
-
-struct ispstat;
-
-struct ispstat_buffer {
- unsigned long iommu_addr;
- struct iovm_struct *iovm;
- void *virt_addr;
- dma_addr_t dma_addr;
- struct timeval ts;
- u32 buf_size;
- u32 frame_number;
- u16 config_counter;
- u8 empty;
-};
-
-struct ispstat_ops {
- /*
- * Validate new params configuration.
- * new_conf->buf_size value must be changed to the exact buffer size
- * necessary for the new configuration if it's smaller.
- */
- int (*validate_params)(struct ispstat *stat, void *new_conf);
-
- /*
- * Save new params configuration.
- * stat->priv->buf_size value must be set to the exact buffer size for
- * the new configuration.
- * stat->update is set to 1 if new configuration is different than
- * current one.
- */
- void (*set_params)(struct ispstat *stat, void *new_conf);
-
- /* Apply stored configuration. */
- void (*setup_regs)(struct ispstat *stat, void *priv);
-
- /* Enable/Disable module. */
- void (*enable)(struct ispstat *stat, int enable);
-
- /* Verify is module is busy. */
- int (*busy)(struct ispstat *stat);
-
- /* Used for specific operations during generic buf process task. */
- int (*buf_process)(struct ispstat *stat);
-};
-
-enum ispstat_state_t {
- ISPSTAT_DISABLED = 0,
- ISPSTAT_DISABLING,
- ISPSTAT_ENABLED,
- ISPSTAT_ENABLING,
- ISPSTAT_SUSPENDED,
-};
-
-struct ispstat {
- struct v4l2_subdev subdev;
- struct media_pad pad; /* sink pad */
-
- /* Control */
- unsigned configured:1;
- unsigned update:1;
- unsigned buf_processing:1;
- unsigned sbl_ovl_recover:1;
- u8 inc_config;
- atomic_t buf_err;
- enum ispstat_state_t state; /* enabling/disabling state */
- struct omap_dma_channel_params dma_config;
- struct isp_device *isp;
- void *priv; /* pointer to priv config struct */
- void *recover_priv; /* pointer to recover priv configuration */
- struct mutex ioctl_lock; /* serialize private ioctl */
-
- const struct ispstat_ops *ops;
-
- /* Buffer */
- u8 wait_acc_frames;
- u16 config_counter;
- u32 frame_number;
- u32 buf_size;
- u32 buf_alloc_size;
- int dma_ch;
- unsigned long event_type;
- struct ispstat_buffer *buf;
- struct ispstat_buffer *active_buf;
- struct ispstat_buffer *locked_buf;
-};
-
-struct ispstat_generic_config {
- /*
- * Fields must be in the same order as in:
- * - omap3isp_h3a_aewb_config
- * - omap3isp_h3a_af_config
- * - omap3isp_hist_config
- */
- u32 buf_size;
- u16 config_counter;
-};
-
-int omap3isp_stat_config(struct ispstat *stat, void *new_conf);
-int omap3isp_stat_request_statistics(struct ispstat *stat,
- struct omap3isp_stat_data *data);
-int omap3isp_stat_init(struct ispstat *stat, const char *name,
- const struct v4l2_subdev_ops *sd_ops);
-void omap3isp_stat_cleanup(struct ispstat *stat);
-int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
- struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub);
-int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
- struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub);
-int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable);
-
-int omap3isp_stat_busy(struct ispstat *stat);
-int omap3isp_stat_pcr_busy(struct ispstat *stat);
-void omap3isp_stat_suspend(struct ispstat *stat);
-void omap3isp_stat_resume(struct ispstat *stat);
-int omap3isp_stat_enable(struct ispstat *stat, u8 enable);
-void omap3isp_stat_sbl_overflow(struct ispstat *stat);
-void omap3isp_stat_isr(struct ispstat *stat);
-void omap3isp_stat_isr_frame_sync(struct ispstat *stat);
-void omap3isp_stat_dma_isr(struct ispstat *stat);
-int omap3isp_stat_register_entities(struct ispstat *stat,
- struct v4l2_device *vdev);
-void omap3isp_stat_unregister_entities(struct ispstat *stat);
-
-#endif /* OMAP3_ISP_STAT_H */
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c
deleted file mode 100644
index b37379d39cd..00000000000
--- a/drivers/media/video/omap3isp/ispvideo.c
+++ /dev/null
@@ -1,1392 +0,0 @@
-/*
- * ispvideo.c
- *
- * TI OMAP3 ISP - Generic video node
- *
- * Copyright (C) 2009-2010 Nokia Corporation
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <asm/cacheflush.h>
-#include <linux/clk.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/pagemap.h>
-#include <linux/scatterlist.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-ioctl.h>
-#include <plat/iommu.h>
-#include <plat/iovmm.h>
-#include <plat/omap-pm.h>
-
-#include "ispvideo.h"
-#include "isp.h"
-
-
-/* -----------------------------------------------------------------------------
- * Helper functions
- */
-
-/*
- * NOTE: When adding new media bus codes, always remember to add
- * corresponding in-memory formats to the table below!!!
- */
-static struct isp_format_info formats[] = {
- { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
- V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
- V4L2_PIX_FMT_GREY, 8, },
- { V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10,
- V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y8_1X8,
- V4L2_PIX_FMT_Y10, 10, },
- { V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10,
- V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y8_1X8,
- V4L2_PIX_FMT_Y12, 12, },
- { V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8,
- V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8,
- V4L2_PIX_FMT_SBGGR8, 8, },
- { V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8,
- V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8,
- V4L2_PIX_FMT_SGBRG8, 8, },
- { V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8,
- V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8,
- V4L2_PIX_FMT_SGRBG8, 8, },
- { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
- V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
- V4L2_PIX_FMT_SRGGB8, 8, },
- { V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8,
- V4L2_MBUS_FMT_SBGGR10_1X10, 0,
- V4L2_PIX_FMT_SBGGR10DPCM8, 8, },
- { V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8,
- V4L2_MBUS_FMT_SGBRG10_1X10, 0,
- V4L2_PIX_FMT_SGBRG10DPCM8, 8, },
- { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
- V4L2_MBUS_FMT_SGRBG10_1X10, 0,
- V4L2_PIX_FMT_SGRBG10DPCM8, 8, },
- { V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8,
- V4L2_MBUS_FMT_SRGGB10_1X10, 0,
- V4L2_PIX_FMT_SRGGB10DPCM8, 8, },
- { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10,
- V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8,
- V4L2_PIX_FMT_SBGGR10, 10, },
- { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10,
- V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG8_1X8,
- V4L2_PIX_FMT_SGBRG10, 10, },
- { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10,
- V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG8_1X8,
- V4L2_PIX_FMT_SGRBG10, 10, },
- { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10,
- V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB8_1X8,
- V4L2_PIX_FMT_SRGGB10, 10, },
- { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10,
- V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR8_1X8,
- V4L2_PIX_FMT_SBGGR12, 12, },
- { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10,
- V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG8_1X8,
- V4L2_PIX_FMT_SGBRG12, 12, },
- { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10,
- V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG8_1X8,
- V4L2_PIX_FMT_SGRBG12, 12, },
- { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10,
- V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB8_1X8,
- V4L2_PIX_FMT_SRGGB12, 12, },
- { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16,
- V4L2_MBUS_FMT_UYVY8_1X16, 0,
- V4L2_PIX_FMT_UYVY, 16, },
- { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16,
- V4L2_MBUS_FMT_YUYV8_1X16, 0,
- V4L2_PIX_FMT_YUYV, 16, },
-};
-
-const struct isp_format_info *
-omap3isp_video_format_info(enum v4l2_mbus_pixelcode code)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(formats); ++i) {
- if (formats[i].code == code)
- return &formats[i];
- }
-
- return NULL;
-}
-
-/*
- * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format
- * @video: ISP video instance
- * @mbus: v4l2_mbus_framefmt format (input)
- * @pix: v4l2_pix_format format (output)
- *
- * Fill the output pix structure with information from the input mbus format.
- * The bytesperline and sizeimage fields are computed from the requested bytes
- * per line value in the pix format and information from the video instance.
- *
- * Return the number of padding bytes at end of line.
- */
-static unsigned int isp_video_mbus_to_pix(const struct isp_video *video,
- const struct v4l2_mbus_framefmt *mbus,
- struct v4l2_pix_format *pix)
-{
- unsigned int bpl = pix->bytesperline;
- unsigned int min_bpl;
- unsigned int i;
-
- memset(pix, 0, sizeof(*pix));
- pix->width = mbus->width;
- pix->height = mbus->height;
-
- for (i = 0; i < ARRAY_SIZE(formats); ++i) {
- if (formats[i].code == mbus->code)
- break;
- }
-
- if (WARN_ON(i == ARRAY_SIZE(formats)))
- return 0;
-
- min_bpl = pix->width * ALIGN(formats[i].bpp, 8) / 8;
-
- /* Clamp the requested bytes per line value. If the maximum bytes per
- * line value is zero, the module doesn't support user configurable line
- * sizes. Override the requested value with the minimum in that case.
- */
- if (video->bpl_max)
- bpl = clamp(bpl, min_bpl, video->bpl_max);
- else
- bpl = min_bpl;
-
- if (!video->bpl_zero_padding || bpl != min_bpl)
- bpl = ALIGN(bpl, video->bpl_alignment);
-
- pix->pixelformat = formats[i].pixelformat;
- pix->bytesperline = bpl;
- pix->sizeimage = pix->bytesperline * pix->height;
- pix->colorspace = mbus->colorspace;
- pix->field = mbus->field;
-
- return bpl - min_bpl;
-}
-
-static void isp_video_pix_to_mbus(const struct v4l2_pix_format *pix,
- struct v4l2_mbus_framefmt *mbus)
-{
- unsigned int i;
-
- memset(mbus, 0, sizeof(*mbus));
- mbus->width = pix->width;
- mbus->height = pix->height;
-
- /* Skip the last format in the loop so that it will be selected if no
- * match is found.
- */
- for (i = 0; i < ARRAY_SIZE(formats) - 1; ++i) {
- if (formats[i].pixelformat == pix->pixelformat)
- break;
- }
-
- mbus->code = formats[i].code;
- mbus->colorspace = pix->colorspace;
- mbus->field = pix->field;
-}
-
-static struct v4l2_subdev *
-isp_video_remote_subdev(struct isp_video *video, u32 *pad)
-{
- struct media_pad *remote;
-
- remote = media_entity_remote_source(&video->pad);
-
- if (remote == NULL ||
- media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
- return NULL;
-
- if (pad)
- *pad = remote->index;
-
- return media_entity_to_v4l2_subdev(remote->entity);
-}
-
-/* Return a pointer to the ISP video instance at the far end of the pipeline. */
-static int isp_video_get_graph_data(struct isp_video *video,
- struct isp_pipeline *pipe)
-{
- struct media_entity_graph graph;
- struct media_entity *entity = &video->video.entity;
- struct media_device *mdev = entity->parent;
- struct isp_video *far_end = NULL;
-
- mutex_lock(&mdev->graph_mutex);
- media_entity_graph_walk_start(&graph, entity);
-
- while ((entity = media_entity_graph_walk_next(&graph))) {
- struct isp_video *__video;
-
- pipe->entities |= 1 << entity->id;
-
- if (far_end != NULL)
- continue;
-
- if (entity == &video->video.entity)
- continue;
-
- if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
- continue;
-
- __video = to_isp_video(media_entity_to_video_device(entity));
- if (__video->type != video->type)
- far_end = __video;
- }
-
- mutex_unlock(&mdev->graph_mutex);
-
- if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- pipe->input = far_end;
- pipe->output = video;
- } else {
- if (far_end == NULL)
- return -EPIPE;
-
- pipe->input = video;
- pipe->output = far_end;
- }
-
- return 0;
-}
-
-/*
- * Validate a pipeline by checking both ends of all links for format
- * discrepancies.
- *
- * Compute the minimum time per frame value as the maximum of time per frame
- * limits reported by every block in the pipeline.
- *
- * Return 0 if all formats match, or -EPIPE if at least one link is found with
- * different formats on its two ends or if the pipeline doesn't start with a
- * video source (either a subdev with no input pad, or a non-subdev entity).
- */
-static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
-{
- struct isp_device *isp = pipe->output->isp;
- struct media_pad *pad;
- struct v4l2_subdev *subdev;
-
- subdev = isp_video_remote_subdev(pipe->output, NULL);
- if (subdev == NULL)
- return -EPIPE;
-
- while (1) {
- /* Retrieve the sink format */
- pad = &subdev->entity.pads[0];
- if (!(pad->flags & MEDIA_PAD_FL_SINK))
- break;
-
- /* Update the maximum frame rate */
- if (subdev == &isp->isp_res.subdev)
- omap3isp_resizer_max_rate(&isp->isp_res,
- &pipe->max_rate);
-
- /* Retrieve the source format. Return an error if no source
- * entity can be found, and stop checking the pipeline if the
- * source entity isn't a subdev.
- */
- pad = media_entity_remote_source(pad);
- if (pad == NULL)
- return -EPIPE;
-
- if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
- break;
-
- subdev = media_entity_to_v4l2_subdev(pad->entity);
- }
-
- return 0;
-}
-
-static int
-__isp_video_get_format(struct isp_video *video, struct v4l2_format *format)
-{
- struct v4l2_subdev_format fmt;
- struct v4l2_subdev *subdev;
- u32 pad;
- int ret;
-
- subdev = isp_video_remote_subdev(video, &pad);
- if (subdev == NULL)
- return -EINVAL;
-
- mutex_lock(&video->mutex);
-
- fmt.pad = pad;
- fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
- if (ret == -ENOIOCTLCMD)
- ret = -EINVAL;
-
- mutex_unlock(&video->mutex);
-
- if (ret)
- return ret;
-
- format->type = video->type;
- return isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
-}
-
-static int
-isp_video_check_format(struct isp_video *video, struct isp_video_fh *vfh)
-{
- struct v4l2_format format;
- int ret;
-
- memcpy(&format, &vfh->format, sizeof(format));
- ret = __isp_video_get_format(video, &format);
- if (ret < 0)
- return ret;
-
- if (vfh->format.fmt.pix.pixelformat != format.fmt.pix.pixelformat ||
- vfh->format.fmt.pix.height != format.fmt.pix.height ||
- vfh->format.fmt.pix.width != format.fmt.pix.width ||
- vfh->format.fmt.pix.bytesperline != format.fmt.pix.bytesperline ||
- vfh->format.fmt.pix.sizeimage != format.fmt.pix.sizeimage)
- return -EINVAL;
-
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * IOMMU management
- */
-
-#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
-
-/*
- * ispmmu_vmap - Wrapper for Virtual memory mapping of a scatter gather list
- * @dev: Device pointer specific to the OMAP3 ISP.
- * @sglist: Pointer to source Scatter gather list to allocate.
- * @sglen: Number of elements of the scatter-gatter list.
- *
- * Returns a resulting mapped device address by the ISP MMU, or -ENOMEM if
- * we ran out of memory.
- */
-static dma_addr_t
-ispmmu_vmap(struct isp_device *isp, const struct scatterlist *sglist, int sglen)
-{
- struct sg_table *sgt;
- u32 da;
-
- sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
- if (sgt == NULL)
- return -ENOMEM;
-
- sgt->sgl = (struct scatterlist *)sglist;
- sgt->nents = sglen;
- sgt->orig_nents = sglen;
-
- da = omap_iommu_vmap(isp->domain, isp->dev, 0, sgt, IOMMU_FLAG);
- if (IS_ERR_VALUE(da))
- kfree(sgt);
-
- return da;
-}
-
-/*
- * ispmmu_vunmap - Unmap a device address from the ISP MMU
- * @dev: Device pointer specific to the OMAP3 ISP.
- * @da: Device address generated from a ispmmu_vmap call.
- */
-static void ispmmu_vunmap(struct isp_device *isp, dma_addr_t da)
-{
- struct sg_table *sgt;
-
- sgt = omap_iommu_vunmap(isp->domain, isp->dev, (u32)da);
- kfree(sgt);
-}
-
-/* -----------------------------------------------------------------------------
- * Video queue operations
- */
-
-static void isp_video_queue_prepare(struct isp_video_queue *queue,
- unsigned int *nbuffers, unsigned int *size)
-{
- struct isp_video_fh *vfh =
- container_of(queue, struct isp_video_fh, queue);
- struct isp_video *video = vfh->video;
-
- *size = vfh->format.fmt.pix.sizeimage;
- if (*size == 0)
- return;
-
- *nbuffers = min(*nbuffers, video->capture_mem / PAGE_ALIGN(*size));
-}
-
-static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
-{
- struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
- struct isp_buffer *buffer = to_isp_buffer(buf);
- struct isp_video *video = vfh->video;
-
- if (buffer->isp_addr) {
- ispmmu_vunmap(video->isp, buffer->isp_addr);
- buffer->isp_addr = 0;
- }
-}
-
-static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
-{
- struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
- struct isp_buffer *buffer = to_isp_buffer(buf);
- struct isp_video *video = vfh->video;
- unsigned long addr;
-
- addr = ispmmu_vmap(video->isp, buf->sglist, buf->sglen);
- if (IS_ERR_VALUE(addr))
- return -EIO;
-
- if (!IS_ALIGNED(addr, 32)) {
- dev_dbg(video->isp->dev, "Buffer address must be "
- "aligned to 32 bytes boundary.\n");
- ispmmu_vunmap(video->isp, buffer->isp_addr);
- return -EINVAL;
- }
-
- buf->vbuf.bytesused = vfh->format.fmt.pix.sizeimage;
- buffer->isp_addr = addr;
- return 0;
-}
-
-/*
- * isp_video_buffer_queue - Add buffer to streaming queue
- * @buf: Video buffer
- *
- * In memory-to-memory mode, start streaming on the pipeline if buffers are
- * queued on both the input and the output, if the pipeline isn't already busy.
- * If the pipeline is busy, it will be restarted in the output module interrupt
- * handler.
- */
-static void isp_video_buffer_queue(struct isp_video_buffer *buf)
-{
- struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
- struct isp_buffer *buffer = to_isp_buffer(buf);
- struct isp_video *video = vfh->video;
- struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
- enum isp_pipeline_state state;
- unsigned long flags;
- unsigned int empty;
- unsigned int start;
-
- empty = list_empty(&video->dmaqueue);
- list_add_tail(&buffer->buffer.irqlist, &video->dmaqueue);
-
- if (empty) {
- if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- state = ISP_PIPELINE_QUEUE_OUTPUT;
- else
- state = ISP_PIPELINE_QUEUE_INPUT;
-
- spin_lock_irqsave(&pipe->lock, flags);
- pipe->state |= state;
- video->ops->queue(video, buffer);
- video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;
-
- start = isp_pipeline_ready(pipe);
- if (start)
- pipe->state |= ISP_PIPELINE_STREAM;
- spin_unlock_irqrestore(&pipe->lock, flags);
-
- if (start)
- omap3isp_pipeline_set_stream(pipe,
- ISP_PIPELINE_STREAM_SINGLESHOT);
- }
-}
-
-static const struct isp_video_queue_operations isp_video_queue_ops = {
- .queue_prepare = &isp_video_queue_prepare,
- .buffer_prepare = &isp_video_buffer_prepare,
- .buffer_queue = &isp_video_buffer_queue,
- .buffer_cleanup = &isp_video_buffer_cleanup,
-};
-
-/*
- * omap3isp_video_buffer_next - Complete the current buffer and return the next
- * @video: ISP video object
- *
- * Remove the current video buffer from the DMA queue and fill its timestamp,
- * field count and state fields before waking up its completion handler.
- *
- * For capture video nodes the buffer state is set to ISP_BUF_STATE_DONE if no
- * error has been flagged in the pipeline, or to ISP_BUF_STATE_ERROR otherwise.
- * For video output nodes the buffer state is always set to ISP_BUF_STATE_DONE.
- *
- * The DMA queue is expected to contain at least one buffer.
- *
- * Return a pointer to the next buffer in the DMA queue, or NULL if the queue is
- * empty.
- */
-struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
-{
- struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
- struct isp_video_queue *queue = video->queue;
- enum isp_pipeline_state state;
- struct isp_video_buffer *buf;
- unsigned long flags;
- struct timespec ts;
-
- spin_lock_irqsave(&queue->irqlock, flags);
- if (WARN_ON(list_empty(&video->dmaqueue))) {
- spin_unlock_irqrestore(&queue->irqlock, flags);
- return NULL;
- }
-
- buf = list_first_entry(&video->dmaqueue, struct isp_video_buffer,
- irqlist);
- list_del(&buf->irqlist);
- spin_unlock_irqrestore(&queue->irqlock, flags);
-
- ktime_get_ts(&ts);
- buf->vbuf.timestamp.tv_sec = ts.tv_sec;
- buf->vbuf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
-
- /* Do frame number propagation only if this is the output video node.
- * Frame number either comes from the CSI receivers or it gets
- * incremented here if H3A is not active.
- * Note: There is no guarantee that the output buffer will finish
- * first, so the input number might lag behind by 1 in some cases.
- */
- if (video == pipe->output && !pipe->do_propagation)
- buf->vbuf.sequence = atomic_inc_return(&pipe->frame_number);
- else
- buf->vbuf.sequence = atomic_read(&pipe->frame_number);
-
- /* Report pipeline errors to userspace on the capture device side. */
- if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->error) {
- buf->state = ISP_BUF_STATE_ERROR;
- pipe->error = false;
- } else {
- buf->state = ISP_BUF_STATE_DONE;
- }
-
- wake_up(&buf->wait);
-
- if (list_empty(&video->dmaqueue)) {
- if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- state = ISP_PIPELINE_QUEUE_OUTPUT
- | ISP_PIPELINE_STREAM;
- else
- state = ISP_PIPELINE_QUEUE_INPUT
- | ISP_PIPELINE_STREAM;
-
- spin_lock_irqsave(&pipe->lock, flags);
- pipe->state &= ~state;
- if (video->pipe.stream_state == ISP_PIPELINE_STREAM_CONTINUOUS)
- video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
- spin_unlock_irqrestore(&pipe->lock, flags);
- return NULL;
- }
-
- if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->input != NULL) {
- spin_lock_irqsave(&pipe->lock, flags);
- pipe->state &= ~ISP_PIPELINE_STREAM;
- spin_unlock_irqrestore(&pipe->lock, flags);
- }
-
- buf = list_first_entry(&video->dmaqueue, struct isp_video_buffer,
- irqlist);
- buf->state = ISP_BUF_STATE_ACTIVE;
- return to_isp_buffer(buf);
-}
-
-/*
- * omap3isp_video_resume - Perform resume operation on the buffers
- * @video: ISP video object
- * @continuous: Pipeline is in single shot mode if 0 or continuous mode otherwise
- *
- * This function is intended to be used on suspend/resume scenario. It
- * requests video queue layer to discard buffers marked as DONE if it's in
- * continuous mode and requests ISP modules to queue again the ACTIVE buffer
- * if there's any.
- */
-void omap3isp_video_resume(struct isp_video *video, int continuous)
-{
- struct isp_buffer *buf = NULL;
-
- if (continuous && video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- omap3isp_video_queue_discard_done(video->queue);
-
- if (!list_empty(&video->dmaqueue)) {
- buf = list_first_entry(&video->dmaqueue,
- struct isp_buffer, buffer.irqlist);
- video->ops->queue(video, buf);
- video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;
- } else {
- if (continuous)
- video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 ioctls
- */
-
-static int
-isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
-{
- struct isp_video *video = video_drvdata(file);
-
- strlcpy(cap->driver, ISP_VIDEO_DRIVER_NAME, sizeof(cap->driver));
- strlcpy(cap->card, video->video.name, sizeof(cap->card));
- strlcpy(cap->bus_info, "media", sizeof(cap->bus_info));
-
- if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
- else
- cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
-
- return 0;
-}
-
-static int
-isp_video_get_format(struct file *file, void *fh, struct v4l2_format *format)
-{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
- struct isp_video *video = video_drvdata(file);
-
- if (format->type != video->type)
- return -EINVAL;
-
- mutex_lock(&video->mutex);
- *format = vfh->format;
- mutex_unlock(&video->mutex);
-
- return 0;
-}
-
-static int
-isp_video_set_format(struct file *file, void *fh, struct v4l2_format *format)
-{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
- struct isp_video *video = video_drvdata(file);
- struct v4l2_mbus_framefmt fmt;
-
- if (format->type != video->type)
- return -EINVAL;
-
- mutex_lock(&video->mutex);
-
- /* Fill the bytesperline and sizeimage fields by converting to media bus
- * format and back to pixel format.
- */
- isp_video_pix_to_mbus(&format->fmt.pix, &fmt);
- isp_video_mbus_to_pix(video, &fmt, &format->fmt.pix);
-
- vfh->format = *format;
-
- mutex_unlock(&video->mutex);
- return 0;
-}
-
-static int
-isp_video_try_format(struct file *file, void *fh, struct v4l2_format *format)
-{
- struct isp_video *video = video_drvdata(file);
- struct v4l2_subdev_format fmt;
- struct v4l2_subdev *subdev;
- u32 pad;
- int ret;
-
- if (format->type != video->type)
- return -EINVAL;
-
- subdev = isp_video_remote_subdev(video, &pad);
- if (subdev == NULL)
- return -EINVAL;
-
- isp_video_pix_to_mbus(&format->fmt.pix, &fmt.format);
-
- fmt.pad = pad;
- fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
- if (ret)
- return ret == -ENOIOCTLCMD ? -EINVAL : ret;
-
- isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
- return 0;
-}
-
-static int
-isp_video_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
-{
- struct isp_video *video = video_drvdata(file);
- struct v4l2_subdev *subdev;
- int ret;
-
- subdev = isp_video_remote_subdev(video, NULL);
- if (subdev == NULL)
- return -EINVAL;
-
- mutex_lock(&video->mutex);
- ret = v4l2_subdev_call(subdev, video, cropcap, cropcap);
- mutex_unlock(&video->mutex);
-
- return ret == -ENOIOCTLCMD ? -EINVAL : ret;
-}
-
-static int
-isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop)
-{
- struct isp_video *video = video_drvdata(file);
- struct v4l2_subdev_format format;
- struct v4l2_subdev *subdev;
- u32 pad;
- int ret;
-
- subdev = isp_video_remote_subdev(video, &pad);
- if (subdev == NULL)
- return -EINVAL;
-
- /* Try the get crop operation first and fallback to get format if not
- * implemented.
- */
- ret = v4l2_subdev_call(subdev, video, g_crop, crop);
- if (ret != -ENOIOCTLCMD)
- return ret;
-
- format.pad = pad;
- format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &format);
- if (ret < 0)
- return ret == -ENOIOCTLCMD ? -EINVAL : ret;
-
- crop->c.left = 0;
- crop->c.top = 0;
- crop->c.width = format.format.width;
- crop->c.height = format.format.height;
-
- return 0;
-}
-
-static int
-isp_video_set_crop(struct file *file, void *fh, struct v4l2_crop *crop)
-{
- struct isp_video *video = video_drvdata(file);
- struct v4l2_subdev *subdev;
- int ret;
-
- subdev = isp_video_remote_subdev(video, NULL);
- if (subdev == NULL)
- return -EINVAL;
-
- mutex_lock(&video->mutex);
- ret = v4l2_subdev_call(subdev, video, s_crop, crop);
- mutex_unlock(&video->mutex);
-
- return ret == -ENOIOCTLCMD ? -EINVAL : ret;
-}
-
-static int
-isp_video_get_param(struct file *file, void *fh, struct v4l2_streamparm *a)
-{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
- struct isp_video *video = video_drvdata(file);
-
- if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
- video->type != a->type)
- return -EINVAL;
-
- memset(a, 0, sizeof(*a));
- a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
- a->parm.output.timeperframe = vfh->timeperframe;
-
- return 0;
-}
-
-static int
-isp_video_set_param(struct file *file, void *fh, struct v4l2_streamparm *a)
-{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
- struct isp_video *video = video_drvdata(file);
-
- if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
- video->type != a->type)
- return -EINVAL;
-
- if (a->parm.output.timeperframe.denominator == 0)
- a->parm.output.timeperframe.denominator = 1;
-
- vfh->timeperframe = a->parm.output.timeperframe;
-
- return 0;
-}
-
-static int
-isp_video_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
-{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
-
- return omap3isp_video_queue_reqbufs(&vfh->queue, rb);
-}
-
-static int
-isp_video_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
-{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
-
- return omap3isp_video_queue_querybuf(&vfh->queue, b);
-}
-
-static int
-isp_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
-{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
-
- return omap3isp_video_queue_qbuf(&vfh->queue, b);
-}
-
-static int
-isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
-{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
-
- return omap3isp_video_queue_dqbuf(&vfh->queue, b,
- file->f_flags & O_NONBLOCK);
-}
-
-static int isp_video_check_external_subdevs(struct isp_video *video,
- struct isp_pipeline *pipe)
-{
- struct isp_device *isp = video->isp;
- struct media_entity *ents[] = {
- &isp->isp_csi2a.subdev.entity,
- &isp->isp_csi2c.subdev.entity,
- &isp->isp_ccp2.subdev.entity,
- &isp->isp_ccdc.subdev.entity
- };
- struct media_pad *source_pad;
- struct media_entity *source = NULL;
- struct media_entity *sink;
- struct v4l2_subdev_format fmt;
- struct v4l2_ext_controls ctrls;
- struct v4l2_ext_control ctrl;
- unsigned int i;
- int ret = 0;
-
- for (i = 0; i < ARRAY_SIZE(ents); i++) {
- /* Is the entity part of the pipeline? */
- if (!(pipe->entities & (1 << ents[i]->id)))
- continue;
-
- /* ISP entities have always sink pad == 0. Find source. */
- source_pad = media_entity_remote_source(&ents[i]->pads[0]);
- if (source_pad == NULL)
- continue;
-
- source = source_pad->entity;
- sink = ents[i];
- break;
- }
-
- if (!source) {
- dev_warn(isp->dev, "can't find source, failing now\n");
- return ret;
- }
-
- if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
- return 0;
-
- pipe->external = media_entity_to_v4l2_subdev(source);
-
- fmt.pad = source_pad->index;
- fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(sink),
- pad, get_fmt, NULL, &fmt);
- if (unlikely(ret < 0)) {
- dev_warn(isp->dev, "get_fmt returned null!\n");
- return ret;
- }
-
- pipe->external_bpp = omap3isp_video_format_info(fmt.format.code)->bpp;
-
- memset(&ctrls, 0, sizeof(ctrls));
- memset(&ctrl, 0, sizeof(ctrl));
-
- ctrl.id = V4L2_CID_PIXEL_RATE;
-
- ctrls.count = 1;
- ctrls.controls = &ctrl;
-
- ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
- if (ret < 0) {
- dev_warn(isp->dev, "no pixel rate control in subdev %s\n",
- pipe->external->name);
- return ret;
- }
-
- pipe->external_rate = ctrl.value64;
-
- if (pipe->entities & (1 << isp->isp_ccdc.subdev.entity.id)) {
- unsigned int rate = UINT_MAX;
- /*
- * Check that maximum allowed CCDC pixel rate isn't
- * exceeded by the pixel rate.
- */
- omap3isp_ccdc_max_rate(&isp->isp_ccdc, &rate);
- if (pipe->external_rate > rate)
- return -ENOSPC;
- }
-
- return 0;
-}
-
-/*
- * Stream management
- *
- * Every ISP pipeline has a single input and a single output. The input can be
- * either a sensor or a video node. The output is always a video node.
- *
- * As every pipeline has an output video node, the ISP video objects at the
- * pipeline output stores the pipeline state. It tracks the streaming state of
- * both the input and output, as well as the availability of buffers.
- *
- * In sensor-to-memory mode, frames are always available at the pipeline input.
- * Starting the sensor usually requires I2C transfers and must be done in
- * interruptible context. The pipeline is started and stopped synchronously
- * to the stream on/off commands. All modules in the pipeline will get their
- * subdev set stream handler called. The module at the end of the pipeline must
- * delay starting the hardware until buffers are available at its output.
- *
- * In memory-to-memory mode, starting/stopping the stream requires
- * synchronization between the input and output. ISP modules can't be stopped
- * in the middle of a frame, and at least some of the modules seem to become
- * busy as soon as they're started, even if they don't receive a frame start
- * event. For that reason frames need to be processed in single-shot mode. The
- * driver needs to wait until a frame is completely processed and written to
- * memory before restarting the pipeline for the next frame. Pipelined
- * processing might be possible but requires more testing.
- *
- * Stream start must be delayed until buffers are available at both the input
- * and output. The pipeline must be started in the videobuf queue callback with
- * the buffers queue spinlock held. The modules subdev set stream operation must
- * not sleep.
- */
-static int
-isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
-{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
- struct isp_video *video = video_drvdata(file);
- enum isp_pipeline_state state;
- struct isp_pipeline *pipe;
- unsigned long flags;
- int ret;
-
- if (type != video->type)
- return -EINVAL;
-
- mutex_lock(&video->stream_lock);
-
- if (video->streaming) {
- mutex_unlock(&video->stream_lock);
- return -EBUSY;
- }
-
- /* Start streaming on the pipeline. No link touching an entity in the
- * pipeline can be activated or deactivated once streaming is started.
- */
- pipe = video->video.entity.pipe
- ? to_isp_pipeline(&video->video.entity) : &video->pipe;
-
- pipe->entities = 0;
-
- if (video->isp->pdata->set_constraints)
- video->isp->pdata->set_constraints(video->isp, true);
- pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
- pipe->max_rate = pipe->l3_ick;
-
- ret = media_entity_pipeline_start(&video->video.entity, &pipe->pipe);
- if (ret < 0)
- goto err_pipeline_start;
-
- /* Verify that the currently configured format matches the output of
- * the connected subdev.
- */
- ret = isp_video_check_format(video, vfh);
- if (ret < 0)
- goto err_check_format;
-
- video->bpl_padding = ret;
- video->bpl_value = vfh->format.fmt.pix.bytesperline;
-
- ret = isp_video_get_graph_data(video, pipe);
- if (ret < 0)
- goto err_check_format;
-
- if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
- else
- state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
-
- ret = isp_video_check_external_subdevs(video, pipe);
- if (ret < 0)
- goto err_check_format;
-
- /* Validate the pipeline and update its state. */
- ret = isp_video_validate_pipeline(pipe);
- if (ret < 0)
- goto err_check_format;
-
- pipe->error = false;
-
- spin_lock_irqsave(&pipe->lock, flags);
- pipe->state &= ~ISP_PIPELINE_STREAM;
- pipe->state |= state;
- spin_unlock_irqrestore(&pipe->lock, flags);
-
- /* Set the maximum time per frame as the value requested by userspace.
- * This is a soft limit that can be overridden if the hardware doesn't
- * support the request limit.
- */
- if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
- pipe->max_timeperframe = vfh->timeperframe;
-
- video->queue = &vfh->queue;
- INIT_LIST_HEAD(&video->dmaqueue);
- atomic_set(&pipe->frame_number, -1);
-
- ret = omap3isp_video_queue_streamon(&vfh->queue);
- if (ret < 0)
- goto err_check_format;
-
- /* In sensor-to-memory mode, the stream can be started synchronously
- * to the stream on command. In memory-to-memory mode, it will be
- * started when buffers are queued on both the input and output.
- */
- if (pipe->input == NULL) {
- ret = omap3isp_pipeline_set_stream(pipe,
- ISP_PIPELINE_STREAM_CONTINUOUS);
- if (ret < 0)
- goto err_set_stream;
- spin_lock_irqsave(&video->queue->irqlock, flags);
- if (list_empty(&video->dmaqueue))
- video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
- spin_unlock_irqrestore(&video->queue->irqlock, flags);
- }
-
- video->streaming = 1;
-
- mutex_unlock(&video->stream_lock);
- return 0;
-
-err_set_stream:
- omap3isp_video_queue_streamoff(&vfh->queue);
-err_check_format:
- media_entity_pipeline_stop(&video->video.entity);
-err_pipeline_start:
- if (video->isp->pdata->set_constraints)
- video->isp->pdata->set_constraints(video->isp, false);
- /* The DMA queue must be emptied here, otherwise CCDC interrupts that
- * will get triggered the next time the CCDC is powered up will try to
- * access buffers that might have been freed but still present in the
- * DMA queue. This can easily get triggered if the above
- * omap3isp_pipeline_set_stream() call fails on a system with a
- * free-running sensor.
- */
- INIT_LIST_HEAD(&video->dmaqueue);
- video->queue = NULL;
-
- mutex_unlock(&video->stream_lock);
- return ret;
-}
-
-static int
-isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
-{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
- struct isp_video *video = video_drvdata(file);
- struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
- enum isp_pipeline_state state;
- unsigned int streaming;
- unsigned long flags;
-
- if (type != video->type)
- return -EINVAL;
-
- mutex_lock(&video->stream_lock);
-
- /* Make sure we're not streaming yet. */
- mutex_lock(&vfh->queue.lock);
- streaming = vfh->queue.streaming;
- mutex_unlock(&vfh->queue.lock);
-
- if (!streaming)
- goto done;
-
- /* Update the pipeline state. */
- if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- state = ISP_PIPELINE_STREAM_OUTPUT
- | ISP_PIPELINE_QUEUE_OUTPUT;
- else
- state = ISP_PIPELINE_STREAM_INPUT
- | ISP_PIPELINE_QUEUE_INPUT;
-
- spin_lock_irqsave(&pipe->lock, flags);
- pipe->state &= ~state;
- spin_unlock_irqrestore(&pipe->lock, flags);
-
- /* Stop the stream. */
- omap3isp_pipeline_set_stream(pipe, ISP_PIPELINE_STREAM_STOPPED);
- omap3isp_video_queue_streamoff(&vfh->queue);
- video->queue = NULL;
- video->streaming = 0;
-
- if (video->isp->pdata->set_constraints)
- video->isp->pdata->set_constraints(video->isp, false);
- media_entity_pipeline_stop(&video->video.entity);
-
-done:
- mutex_unlock(&video->stream_lock);
- return 0;
-}
-
-static int
-isp_video_enum_input(struct file *file, void *fh, struct v4l2_input *input)
-{
- if (input->index > 0)
- return -EINVAL;
-
- strlcpy(input->name, "camera", sizeof(input->name));
- input->type = V4L2_INPUT_TYPE_CAMERA;
-
- return 0;
-}
-
-static int
-isp_video_g_input(struct file *file, void *fh, unsigned int *input)
-{
- *input = 0;
-
- return 0;
-}
-
-static int
-isp_video_s_input(struct file *file, void *fh, unsigned int input)
-{
- return input == 0 ? 0 : -EINVAL;
-}
-
-static const struct v4l2_ioctl_ops isp_video_ioctl_ops = {
- .vidioc_querycap = isp_video_querycap,
- .vidioc_g_fmt_vid_cap = isp_video_get_format,
- .vidioc_s_fmt_vid_cap = isp_video_set_format,
- .vidioc_try_fmt_vid_cap = isp_video_try_format,
- .vidioc_g_fmt_vid_out = isp_video_get_format,
- .vidioc_s_fmt_vid_out = isp_video_set_format,
- .vidioc_try_fmt_vid_out = isp_video_try_format,
- .vidioc_cropcap = isp_video_cropcap,
- .vidioc_g_crop = isp_video_get_crop,
- .vidioc_s_crop = isp_video_set_crop,
- .vidioc_g_parm = isp_video_get_param,
- .vidioc_s_parm = isp_video_set_param,
- .vidioc_reqbufs = isp_video_reqbufs,
- .vidioc_querybuf = isp_video_querybuf,
- .vidioc_qbuf = isp_video_qbuf,
- .vidioc_dqbuf = isp_video_dqbuf,
- .vidioc_streamon = isp_video_streamon,
- .vidioc_streamoff = isp_video_streamoff,
- .vidioc_enum_input = isp_video_enum_input,
- .vidioc_g_input = isp_video_g_input,
- .vidioc_s_input = isp_video_s_input,
-};
-
-/* -----------------------------------------------------------------------------
- * V4L2 file operations
- */
-
-static int isp_video_open(struct file *file)
-{
- struct isp_video *video = video_drvdata(file);
- struct isp_video_fh *handle;
- int ret = 0;
-
- handle = kzalloc(sizeof(*handle), GFP_KERNEL);
- if (handle == NULL)
- return -ENOMEM;
-
- v4l2_fh_init(&handle->vfh, &video->video);
- v4l2_fh_add(&handle->vfh);
-
- /* If this is the first user, initialise the pipeline. */
- if (omap3isp_get(video->isp) == NULL) {
- ret = -EBUSY;
- goto done;
- }
-
- ret = omap3isp_pipeline_pm_use(&video->video.entity, 1);
- if (ret < 0) {
- omap3isp_put(video->isp);
- goto done;
- }
-
- omap3isp_video_queue_init(&handle->queue, video->type,
- &isp_video_queue_ops, video->isp->dev,
- sizeof(struct isp_buffer));
-
- memset(&handle->format, 0, sizeof(handle->format));
- handle->format.type = video->type;
- handle->timeperframe.denominator = 1;
-
- handle->video = video;
- file->private_data = &handle->vfh;
-
-done:
- if (ret < 0) {
- v4l2_fh_del(&handle->vfh);
- kfree(handle);
- }
-
- return ret;
-}
-
-static int isp_video_release(struct file *file)
-{
- struct isp_video *video = video_drvdata(file);
- struct v4l2_fh *vfh = file->private_data;
- struct isp_video_fh *handle = to_isp_video_fh(vfh);
-
- /* Disable streaming and free the buffers queue resources. */
- isp_video_streamoff(file, vfh, video->type);
-
- mutex_lock(&handle->queue.lock);
- omap3isp_video_queue_cleanup(&handle->queue);
- mutex_unlock(&handle->queue.lock);
-
- omap3isp_pipeline_pm_use(&video->video.entity, 0);
-
- /* Release the file handle. */
- v4l2_fh_del(vfh);
- kfree(handle);
- file->private_data = NULL;
-
- omap3isp_put(video->isp);
-
- return 0;
-}
-
-static unsigned int isp_video_poll(struct file *file, poll_table *wait)
-{
- struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
- struct isp_video_queue *queue = &vfh->queue;
-
- return omap3isp_video_queue_poll(queue, file, wait);
-}
-
-static int isp_video_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
-
- return omap3isp_video_queue_mmap(&vfh->queue, vma);
-}
-
-static struct v4l2_file_operations isp_video_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = video_ioctl2,
- .open = isp_video_open,
- .release = isp_video_release,
- .poll = isp_video_poll,
- .mmap = isp_video_mmap,
-};
-
-/* -----------------------------------------------------------------------------
- * ISP video core
- */
-
-static const struct isp_video_operations isp_video_dummy_ops = {
-};
-
-int omap3isp_video_init(struct isp_video *video, const char *name)
-{
- const char *direction;
- int ret;
-
- switch (video->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- direction = "output";
- video->pad.flags = MEDIA_PAD_FL_SINK;
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- direction = "input";
- video->pad.flags = MEDIA_PAD_FL_SOURCE;
- break;
-
- default:
- return -EINVAL;
- }
-
- ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
- if (ret < 0)
- return ret;
-
- mutex_init(&video->mutex);
- atomic_set(&video->active, 0);
-
- spin_lock_init(&video->pipe.lock);
- mutex_init(&video->stream_lock);
-
- /* Initialize the video device. */
- if (video->ops == NULL)
- video->ops = &isp_video_dummy_ops;
-
- video->video.fops = &isp_video_fops;
- snprintf(video->video.name, sizeof(video->video.name),
- "OMAP3 ISP %s %s", name, direction);
- video->video.vfl_type = VFL_TYPE_GRABBER;
- video->video.release = video_device_release_empty;
- video->video.ioctl_ops = &isp_video_ioctl_ops;
- video->pipe.stream_state = ISP_PIPELINE_STREAM_STOPPED;
-
- video_set_drvdata(&video->video, video);
-
- return 0;
-}
-
-void omap3isp_video_cleanup(struct isp_video *video)
-{
- media_entity_cleanup(&video->video.entity);
- mutex_destroy(&video->stream_lock);
- mutex_destroy(&video->mutex);
-}
-
-int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev)
-{
- int ret;
-
- video->video.v4l2_dev = vdev;
-
- ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1);
- if (ret < 0)
- printk(KERN_ERR "%s: could not register video device (%d)\n",
- __func__, ret);
-
- return ret;
-}
-
-void omap3isp_video_unregister(struct isp_video *video)
-{
- if (video_is_registered(&video->video))
- video_unregister_device(&video->video);
-}
diff --git a/drivers/media/video/omap3isp/ispvideo.h b/drivers/media/video/omap3isp/ispvideo.h
deleted file mode 100644
index 5acc909500e..00000000000
--- a/drivers/media/video/omap3isp/ispvideo.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * ispvideo.h
- *
- * TI OMAP3 ISP - Generic video node
- *
- * Copyright (C) 2009-2010 Nokia Corporation
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef OMAP3_ISP_VIDEO_H
-#define OMAP3_ISP_VIDEO_H
-
-#include <linux/v4l2-mediabus.h>
-#include <media/media-entity.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-fh.h>
-
-#include "ispqueue.h"
-
-#define ISP_VIDEO_DRIVER_NAME "ispvideo"
-#define ISP_VIDEO_DRIVER_VERSION "0.0.2"
-
-struct isp_device;
-struct isp_video;
-struct v4l2_mbus_framefmt;
-struct v4l2_pix_format;
-
-/*
- * struct isp_format_info - ISP media bus format information
- * @code: V4L2 media bus format code
- * @truncated: V4L2 media bus format code for the same format truncated to 10
- * bits. Identical to @code if the format is 10 bits wide or less.
- * @uncompressed: V4L2 media bus format code for the corresponding uncompressed
- * format. Identical to @code if the format is not DPCM compressed.
- * @flavor: V4L2 media bus format code for the same pixel layout but
- * shifted to be 8 bits per pixel. =0 if format is not shiftable.
- * @pixelformat: V4L2 pixel format FCC identifier
- * @bpp: Bits per pixel
- */
-struct isp_format_info {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_mbus_pixelcode truncated;
- enum v4l2_mbus_pixelcode uncompressed;
- enum v4l2_mbus_pixelcode flavor;
- u32 pixelformat;
- unsigned int bpp;
-};
-
-enum isp_pipeline_stream_state {
- ISP_PIPELINE_STREAM_STOPPED = 0,
- ISP_PIPELINE_STREAM_CONTINUOUS = 1,
- ISP_PIPELINE_STREAM_SINGLESHOT = 2,
-};
-
-enum isp_pipeline_state {
- /* The stream has been started on the input video node. */
- ISP_PIPELINE_STREAM_INPUT = 1,
- /* The stream has been started on the output video node. */
- ISP_PIPELINE_STREAM_OUTPUT = 2,
- /* At least one buffer is queued on the input video node. */
- ISP_PIPELINE_QUEUE_INPUT = 4,
- /* At least one buffer is queued on the output video node. */
- ISP_PIPELINE_QUEUE_OUTPUT = 8,
- /* The input entity is idle, ready to be started. */
- ISP_PIPELINE_IDLE_INPUT = 16,
- /* The output entity is idle, ready to be started. */
- ISP_PIPELINE_IDLE_OUTPUT = 32,
- /* The pipeline is currently streaming. */
- ISP_PIPELINE_STREAM = 64,
-};
-
-/*
- * struct isp_pipeline - An ISP hardware pipeline
- * @error: A hardware error occurred during capture
- * @entities: Bitmask of entities in the pipeline (indexed by entity ID)
- */
-struct isp_pipeline {
- struct media_pipeline pipe;
- spinlock_t lock; /* Pipeline state and queue flags */
- unsigned int state;
- enum isp_pipeline_stream_state stream_state;
- struct isp_video *input;
- struct isp_video *output;
- u32 entities;
- unsigned long l3_ick;
- unsigned int max_rate;
- atomic_t frame_number;
- bool do_propagation; /* of frame number */
- bool error;
- struct v4l2_fract max_timeperframe;
- struct v4l2_subdev *external;
- unsigned int external_rate;
- unsigned int external_bpp;
-};
-
-#define to_isp_pipeline(__e) \
- container_of((__e)->pipe, struct isp_pipeline, pipe)
-
-static inline int isp_pipeline_ready(struct isp_pipeline *pipe)
-{
- return pipe->state == (ISP_PIPELINE_STREAM_INPUT |
- ISP_PIPELINE_STREAM_OUTPUT |
- ISP_PIPELINE_QUEUE_INPUT |
- ISP_PIPELINE_QUEUE_OUTPUT |
- ISP_PIPELINE_IDLE_INPUT |
- ISP_PIPELINE_IDLE_OUTPUT);
-}
-
-/*
- * struct isp_buffer - ISP buffer
- * @buffer: ISP video buffer
- * @isp_addr: MMU mapped address (a.k.a. device address) of the buffer.
- */
-struct isp_buffer {
- struct isp_video_buffer buffer;
- dma_addr_t isp_addr;
-};
-
-#define to_isp_buffer(buf) container_of(buf, struct isp_buffer, buffer)
-
-enum isp_video_dmaqueue_flags {
- /* Set if DMA queue becomes empty when ISP_PIPELINE_STREAM_CONTINUOUS */
- ISP_VIDEO_DMAQUEUE_UNDERRUN = (1 << 0),
- /* Set when queuing buffer to an empty DMA queue */
- ISP_VIDEO_DMAQUEUE_QUEUED = (1 << 1),
-};
-
-#define isp_video_dmaqueue_flags_clr(video) \
- ({ (video)->dmaqueue_flags = 0; })
-
-/*
- * struct isp_video_operations - ISP video operations
- * @queue: Resume streaming when a buffer is queued. Called on VIDIOC_QBUF
- * if there was no buffer previously queued.
- */
-struct isp_video_operations {
- int(*queue)(struct isp_video *video, struct isp_buffer *buffer);
-};
-
-struct isp_video {
- struct video_device video;
- enum v4l2_buf_type type;
- struct media_pad pad;
-
- struct mutex mutex; /* format and crop settings */
- atomic_t active;
-
- struct isp_device *isp;
-
- unsigned int capture_mem;
- unsigned int bpl_alignment; /* alignment value */
- unsigned int bpl_zero_padding; /* whether the alignment is optional */
- unsigned int bpl_max; /* maximum bytes per line value */
- unsigned int bpl_value; /* bytes per line value */
- unsigned int bpl_padding; /* padding at end of line */
-
- /* Entity video node streaming */
- unsigned int streaming:1;
-
- /* Pipeline state */
- struct isp_pipeline pipe;
- struct mutex stream_lock; /* pipeline and stream states */
-
- /* Video buffers queue */
- struct isp_video_queue *queue;
- struct list_head dmaqueue;
- enum isp_video_dmaqueue_flags dmaqueue_flags;
-
- const struct isp_video_operations *ops;
-};
-
-#define to_isp_video(vdev) container_of(vdev, struct isp_video, video)
-
-struct isp_video_fh {
- struct v4l2_fh vfh;
- struct isp_video *video;
- struct isp_video_queue queue;
- struct v4l2_format format;
- struct v4l2_fract timeperframe;
-};
-
-#define to_isp_video_fh(fh) container_of(fh, struct isp_video_fh, vfh)
-#define isp_video_queue_to_isp_video_fh(q) \
- container_of(q, struct isp_video_fh, queue)
-
-int omap3isp_video_init(struct isp_video *video, const char *name);
-void omap3isp_video_cleanup(struct isp_video *video);
-int omap3isp_video_register(struct isp_video *video,
- struct v4l2_device *vdev);
-void omap3isp_video_unregister(struct isp_video *video);
-struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video);
-void omap3isp_video_resume(struct isp_video *video, int continuous);
-struct media_pad *omap3isp_video_remote_pad(struct isp_video *video);
-
-const struct isp_format_info *
-omap3isp_video_format_info(enum v4l2_mbus_pixelcode code);
-
-#endif /* OMAP3_ISP_VIDEO_H */
diff --git a/drivers/media/video/omap3isp/luma_enhance_table.h b/drivers/media/video/omap3isp/luma_enhance_table.h
deleted file mode 100644
index 098b45e2280..00000000000
--- a/drivers/media/video/omap3isp/luma_enhance_table.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * luma_enhance_table.h
- *
- * TI OMAP3 ISP - Luminance enhancement table
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552,
-1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552,
-1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552,
-1047552, 1047552, 1047552, 1047552, 1048575, 1047551, 1046527, 1045503,
-1044479, 1043455, 1042431, 1041407, 1040383, 1039359, 1038335, 1037311,
-1036287, 1035263, 1034239, 1033215, 1032191, 1031167, 1030143, 1028096,
-1028096, 1028096, 1028096, 1028096, 1028096, 1028096, 1028096, 1028096,
-1028096, 1028100, 1032196, 1036292, 1040388, 1044484, 0, 0,
- 0, 5, 5125, 10245, 15365, 20485, 25605, 30720,
- 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720,
- 30720, 30720, 31743, 30719, 29695, 28671, 27647, 26623,
- 25599, 24575, 23551, 22527, 21503, 20479, 19455, 18431,
- 17407, 16383, 15359, 14335, 13311, 12287, 11263, 10239,
- 9215, 8191, 7167, 6143, 5119, 4095, 3071, 1024,
- 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
- 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024
diff --git a/drivers/media/video/omap3isp/noise_filter_table.h b/drivers/media/video/omap3isp/noise_filter_table.h
deleted file mode 100644
index d50451a4a24..00000000000
--- a/drivers/media/video/omap3isp/noise_filter_table.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * noise_filter_table.h
- *
- * TI OMAP3 ISP - Noise filter table
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
-31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31
diff --git a/drivers/media/video/ov2640.c b/drivers/media/video/ov2640.c
deleted file mode 100644
index 7c44d1fe3c8..00000000000
--- a/drivers/media/video/ov2640.c
+++ /dev/null
@@ -1,1108 +0,0 @@
-/*
- * ov2640 Camera Driver
- *
- * Copyright (C) 2010 Alberto Panizzo <maramaopercheseimorto@gmail.com>
- *
- * Based on ov772x, ov9640 drivers and previous non merged implementations.
- *
- * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright (C) 2006, OmniVision
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/videodev2.h>
-
-#include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-ctrls.h>
-
-#define VAL_SET(x, mask, rshift, lshift) \
- ((((x) >> rshift) & mask) << lshift)
-/*
- * DSP registers
- * register offset for BANK_SEL == BANK_SEL_DSP
- */
-#define R_BYPASS 0x05 /* Bypass DSP */
-#define R_BYPASS_DSP_BYPAS 0x01 /* Bypass DSP, sensor out directly */
-#define R_BYPASS_USE_DSP 0x00 /* Use the internal DSP */
-#define QS 0x44 /* Quantization Scale Factor */
-#define CTRLI 0x50
-#define CTRLI_LP_DP 0x80
-#define CTRLI_ROUND 0x40
-#define CTRLI_V_DIV_SET(x) VAL_SET(x, 0x3, 0, 3)
-#define CTRLI_H_DIV_SET(x) VAL_SET(x, 0x3, 0, 0)
-#define HSIZE 0x51 /* H_SIZE[7:0] (real/4) */
-#define HSIZE_SET(x) VAL_SET(x, 0xFF, 2, 0)
-#define VSIZE 0x52 /* V_SIZE[7:0] (real/4) */
-#define VSIZE_SET(x) VAL_SET(x, 0xFF, 2, 0)
-#define XOFFL 0x53 /* OFFSET_X[7:0] */
-#define XOFFL_SET(x) VAL_SET(x, 0xFF, 0, 0)
-#define YOFFL 0x54 /* OFFSET_Y[7:0] */
-#define YOFFL_SET(x) VAL_SET(x, 0xFF, 0, 0)
-#define VHYX 0x55 /* Offset and size completion */
-#define VHYX_VSIZE_SET(x) VAL_SET(x, 0x1, (8+2), 7)
-#define VHYX_HSIZE_SET(x) VAL_SET(x, 0x1, (8+2), 3)
-#define VHYX_YOFF_SET(x) VAL_SET(x, 0x3, 8, 4)
-#define VHYX_XOFF_SET(x) VAL_SET(x, 0x3, 8, 0)
-#define DPRP 0x56
-#define TEST 0x57 /* Horizontal size completion */
-#define TEST_HSIZE_SET(x) VAL_SET(x, 0x1, (9+2), 7)
-#define ZMOW 0x5A /* Zoom: Out Width OUTW[7:0] (real/4) */
-#define ZMOW_OUTW_SET(x) VAL_SET(x, 0xFF, 2, 0)
-#define ZMOH 0x5B /* Zoom: Out Height OUTH[7:0] (real/4) */
-#define ZMOH_OUTH_SET(x) VAL_SET(x, 0xFF, 2, 0)
-#define ZMHH 0x5C /* Zoom: Speed and H&W completion */
-#define ZMHH_ZSPEED_SET(x) VAL_SET(x, 0x0F, 0, 4)
-#define ZMHH_OUTH_SET(x) VAL_SET(x, 0x1, (8+2), 2)
-#define ZMHH_OUTW_SET(x) VAL_SET(x, 0x3, (8+2), 0)
-#define BPADDR 0x7C /* SDE Indirect Register Access: Address */
-#define BPDATA 0x7D /* SDE Indirect Register Access: Data */
-#define CTRL2 0x86 /* DSP Module enable 2 */
-#define CTRL2_DCW_EN 0x20
-#define CTRL2_SDE_EN 0x10
-#define CTRL2_UV_ADJ_EN 0x08
-#define CTRL2_UV_AVG_EN 0x04
-#define CTRL2_CMX_EN 0x01
-#define CTRL3 0x87 /* DSP Module enable 3 */
-#define CTRL3_BPC_EN 0x80
-#define CTRL3_WPC_EN 0x40
-#define SIZEL 0x8C /* Image Size Completion */
-#define SIZEL_HSIZE8_11_SET(x) VAL_SET(x, 0x1, 11, 6)
-#define SIZEL_HSIZE8_SET(x) VAL_SET(x, 0x7, 0, 3)
-#define SIZEL_VSIZE8_SET(x) VAL_SET(x, 0x7, 0, 0)
-#define HSIZE8 0xC0 /* Image Horizontal Size HSIZE[10:3] */
-#define HSIZE8_SET(x) VAL_SET(x, 0xFF, 3, 0)
-#define VSIZE8 0xC1 /* Image Vertical Size VSIZE[10:3] */
-#define VSIZE8_SET(x) VAL_SET(x, 0xFF, 3, 0)
-#define CTRL0 0xC2 /* DSP Module enable 0 */
-#define CTRL0_AEC_EN 0x80
-#define CTRL0_AEC_SEL 0x40
-#define CTRL0_STAT_SEL 0x20
-#define CTRL0_VFIRST 0x10
-#define CTRL0_YUV422 0x08
-#define CTRL0_YUV_EN 0x04
-#define CTRL0_RGB_EN 0x02
-#define CTRL0_RAW_EN 0x01
-#define CTRL1 0xC3 /* DSP Module enable 1 */
-#define CTRL1_CIP 0x80
-#define CTRL1_DMY 0x40
-#define CTRL1_RAW_GMA 0x20
-#define CTRL1_DG 0x10
-#define CTRL1_AWB 0x08
-#define CTRL1_AWB_GAIN 0x04
-#define CTRL1_LENC 0x02
-#define CTRL1_PRE 0x01
-#define R_DVP_SP 0xD3 /* DVP output speed control */
-#define R_DVP_SP_AUTO_MODE 0x80
-#define R_DVP_SP_DVP_MASK 0x3F /* DVP PCLK = sysclk (48)/[6:0] (YUV0);
- * = sysclk (48)/(2*[6:0]) (RAW);*/
-#define IMAGE_MODE 0xDA /* Image Output Format Select */
-#define IMAGE_MODE_Y8_DVP_EN 0x40
-#define IMAGE_MODE_JPEG_EN 0x10
-#define IMAGE_MODE_YUV422 0x00
-#define IMAGE_MODE_RAW10 0x04 /* (DVP) */
-#define IMAGE_MODE_RGB565 0x08
-#define IMAGE_MODE_HREF_VSYNC 0x02 /* HREF timing select in DVP JPEG output
- * mode (0 for HREF is same as sensor) */
-#define IMAGE_MODE_LBYTE_FIRST 0x01 /* Byte swap enable for DVP
- * 1: Low byte first UYVY (C2[4] =0)
- * VYUY (C2[4] =1)
- * 0: High byte first YUYV (C2[4]=0)
- * YVYU (C2[4] = 1) */
-#define RESET 0xE0 /* Reset */
-#define RESET_MICROC 0x40
-#define RESET_SCCB 0x20
-#define RESET_JPEG 0x10
-#define RESET_DVP 0x04
-#define RESET_IPU 0x02
-#define RESET_CIF 0x01
-#define REGED 0xED /* Register ED */
-#define REGED_CLK_OUT_DIS 0x10
-#define MS_SP 0xF0 /* SCCB Master Speed */
-#define SS_ID 0xF7 /* SCCB Slave ID */
-#define SS_CTRL 0xF8 /* SCCB Slave Control */
-#define SS_CTRL_ADD_AUTO_INC 0x20
-#define SS_CTRL_EN 0x08
-#define SS_CTRL_DELAY_CLK 0x04
-#define SS_CTRL_ACC_EN 0x02
-#define SS_CTRL_SEN_PASS_THR 0x01
-#define MC_BIST 0xF9 /* Microcontroller misc register */
-#define MC_BIST_RESET 0x80 /* Microcontroller Reset */
-#define MC_BIST_BOOT_ROM_SEL 0x40
-#define MC_BIST_12KB_SEL 0x20
-#define MC_BIST_12KB_MASK 0x30
-#define MC_BIST_512KB_SEL 0x08
-#define MC_BIST_512KB_MASK 0x0C
-#define MC_BIST_BUSY_BIT_R 0x02
-#define MC_BIST_MC_RES_ONE_SH_W 0x02
-#define MC_BIST_LAUNCH 0x01
-#define BANK_SEL 0xFF /* Register Bank Select */
-#define BANK_SEL_DSP 0x00
-#define BANK_SEL_SENS 0x01
-
-/*
- * Sensor registers
- * register offset for BANK_SEL == BANK_SEL_SENS
- */
-#define GAIN 0x00 /* AGC - Gain control gain setting */
-#define COM1 0x03 /* Common control 1 */
-#define COM1_1_DUMMY_FR 0x40
-#define COM1_3_DUMMY_FR 0x80
-#define COM1_7_DUMMY_FR 0xC0
-#define COM1_VWIN_LSB_UXGA 0x0F
-#define COM1_VWIN_LSB_SVGA 0x0A
-#define COM1_VWIN_LSB_CIF 0x06
-#define REG04 0x04 /* Register 04 */
-#define REG04_DEF 0x20 /* Always set */
-#define REG04_HFLIP_IMG 0x80 /* Horizontal mirror image ON/OFF */
-#define REG04_VFLIP_IMG 0x40 /* Vertical flip image ON/OFF */
-#define REG04_VREF_EN 0x10
-#define REG04_HREF_EN 0x08
-#define REG04_AEC_SET(x) VAL_SET(x, 0x3, 0, 0)
-#define REG08 0x08 /* Frame Exposure One-pin Control Pre-charge Row Num */
-#define COM2 0x09 /* Common control 2 */
-#define COM2_SOFT_SLEEP_MODE 0x10 /* Soft sleep mode */
- /* Output drive capability */
-#define COM2_OCAP_Nx_SET(N) (((N) - 1) & 0x03) /* N = [1x .. 4x] */
-#define PID 0x0A /* Product ID Number MSB */
-#define VER 0x0B /* Product ID Number LSB */
-#define COM3 0x0C /* Common control 3 */
-#define COM3_BAND_50H 0x04 /* 0 For Banding at 60H */
-#define COM3_BAND_AUTO 0x02 /* Auto Banding */
-#define COM3_SING_FR_SNAPSH 0x01 /* 0 For enable live video output after the
- * snapshot sequence*/
-#define AEC 0x10 /* AEC[9:2] Exposure Value */
-#define CLKRC 0x11 /* Internal clock */
-#define CLKRC_EN 0x80
-#define CLKRC_DIV_SET(x) (((x) - 1) & 0x1F) /* CLK = XVCLK/(x) */
-#define COM7 0x12 /* Common control 7 */
-#define COM7_SRST 0x80 /* Initiates system reset. All registers are
- * set to factory default values after which
- * the chip resumes normal operation */
-#define COM7_RES_UXGA 0x00 /* Resolution selectors for UXGA */
-#define COM7_RES_SVGA 0x40 /* SVGA */
-#define COM7_RES_CIF 0x20 /* CIF */
-#define COM7_ZOOM_EN 0x04 /* Enable Zoom mode */
-#define COM7_COLOR_BAR_TEST 0x02 /* Enable Color Bar Test Pattern */
-#define COM8 0x13 /* Common control 8 */
-#define COM8_DEF 0xC0 /* Banding filter ON/OFF */
-#define COM8_BNDF_EN 0x20 /* Banding filter ON/OFF */
-#define COM8_AGC_EN 0x04 /* AGC Auto/Manual control selection */
-#define COM8_AEC_EN 0x01 /* Auto/Manual Exposure control */
-#define COM9 0x14 /* Common control 9
- * Automatic gain ceiling - maximum AGC value [7:5]*/
-#define COM9_AGC_GAIN_2x 0x00 /* 000 : 2x */
-#define COM9_AGC_GAIN_4x 0x20 /* 001 : 4x */
-#define COM9_AGC_GAIN_8x 0x40 /* 010 : 8x */
-#define COM9_AGC_GAIN_16x 0x60 /* 011 : 16x */
-#define COM9_AGC_GAIN_32x 0x80 /* 100 : 32x */
-#define COM9_AGC_GAIN_64x 0xA0 /* 101 : 64x */
-#define COM9_AGC_GAIN_128x 0xC0 /* 110 : 128x */
-#define COM10 0x15 /* Common control 10 */
-#define COM10_PCLK_HREF 0x20 /* PCLK output qualified by HREF */
-#define COM10_PCLK_RISE 0x10 /* Data is updated at the rising edge of
- * PCLK (user can latch data at the next
- * falling edge of PCLK).
- * 0 otherwise. */
-#define COM10_HREF_INV 0x08 /* Invert HREF polarity:
- * HREF negative for valid data*/
-#define COM10_VSINC_INV 0x02 /* Invert VSYNC polarity */
-#define HSTART 0x17 /* Horizontal Window start MSB 8 bit */
-#define HEND 0x18 /* Horizontal Window end MSB 8 bit */
-#define VSTART 0x19 /* Vertical Window start MSB 8 bit */
-#define VEND 0x1A /* Vertical Window end MSB 8 bit */
-#define MIDH 0x1C /* Manufacturer ID byte - high */
-#define MIDL 0x1D /* Manufacturer ID byte - low */
-#define AEW 0x24 /* AGC/AEC - Stable operating region (upper limit) */
-#define AEB 0x25 /* AGC/AEC - Stable operating region (lower limit) */
-#define VV 0x26 /* AGC/AEC Fast mode operating region */
-#define VV_HIGH_TH_SET(x) VAL_SET(x, 0xF, 0, 4)
-#define VV_LOW_TH_SET(x) VAL_SET(x, 0xF, 0, 0)
-#define REG2A 0x2A /* Dummy pixel insert MSB */
-#define FRARL 0x2B /* Dummy pixel insert LSB */
-#define ADDVFL 0x2D /* LSB of insert dummy lines in Vertical direction */
-#define ADDVFH 0x2E /* MSB of insert dummy lines in Vertical direction */
-#define YAVG 0x2F /* Y/G Channel Average value */
-#define REG32 0x32 /* Common Control 32 */
-#define REG32_PCLK_DIV_2 0x80 /* PCLK freq divided by 2 */
-#define REG32_PCLK_DIV_4 0xC0 /* PCLK freq divided by 4 */
-#define ARCOM2 0x34 /* Zoom: Horizontal start point */
-#define REG45 0x45 /* Register 45 */
-#define FLL 0x46 /* Frame Length Adjustment LSBs */
-#define FLH 0x47 /* Frame Length Adjustment MSBs */
-#define COM19 0x48 /* Zoom: Vertical start point */
-#define ZOOMS 0x49 /* Zoom: Vertical start point */
-#define COM22 0x4B /* Flash light control */
-#define COM25 0x4E /* For Banding operations */
-#define BD50 0x4F /* 50Hz Banding AEC 8 LSBs */
-#define BD60 0x50 /* 60Hz Banding AEC 8 LSBs */
-#define REG5D 0x5D /* AVGsel[7:0], 16-zone average weight option */
-#define REG5E 0x5E /* AVGsel[15:8], 16-zone average weight option */
-#define REG5F 0x5F /* AVGsel[23:16], 16-zone average weight option */
-#define REG60 0x60 /* AVGsel[31:24], 16-zone average weight option */
-#define HISTO_LOW 0x61 /* Histogram Algorithm Low Level */
-#define HISTO_HIGH 0x62 /* Histogram Algorithm High Level */
-
-/*
- * ID
- */
-#define MANUFACTURER_ID 0x7FA2
-#define PID_OV2640 0x2642
-#define VERSION(pid, ver) ((pid << 8) | (ver & 0xFF))
-
-/*
- * Struct
- */
-struct regval_list {
- u8 reg_num;
- u8 value;
-};
-
-/* Supported resolutions */
-enum ov2640_width {
- W_QCIF = 176,
- W_QVGA = 320,
- W_CIF = 352,
- W_VGA = 640,
- W_SVGA = 800,
- W_XGA = 1024,
- W_SXGA = 1280,
- W_UXGA = 1600,
-};
-
-enum ov2640_height {
- H_QCIF = 144,
- H_QVGA = 240,
- H_CIF = 288,
- H_VGA = 480,
- H_SVGA = 600,
- H_XGA = 768,
- H_SXGA = 1024,
- H_UXGA = 1200,
-};
-
-struct ov2640_win_size {
- char *name;
- enum ov2640_width width;
- enum ov2640_height height;
- const struct regval_list *regs;
-};
-
-
-struct ov2640_priv {
- struct v4l2_subdev subdev;
- struct v4l2_ctrl_handler hdl;
- enum v4l2_mbus_pixelcode cfmt_code;
- const struct ov2640_win_size *win;
- int model;
-};
-
-/*
- * Registers settings
- */
-
-#define ENDMARKER { 0xff, 0xff }
-
-static const struct regval_list ov2640_init_regs[] = {
- { BANK_SEL, BANK_SEL_DSP },
- { 0x2c, 0xff },
- { 0x2e, 0xdf },
- { BANK_SEL, BANK_SEL_SENS },
- { 0x3c, 0x32 },
- { CLKRC, CLKRC_DIV_SET(1) },
- { COM2, COM2_OCAP_Nx_SET(3) },
- { REG04, REG04_DEF | REG04_HREF_EN },
- { COM8, COM8_DEF | COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN },
- { COM9, COM9_AGC_GAIN_8x | 0x08},
- { 0x2c, 0x0c },
- { 0x33, 0x78 },
- { 0x3a, 0x33 },
- { 0x3b, 0xfb },
- { 0x3e, 0x00 },
- { 0x43, 0x11 },
- { 0x16, 0x10 },
- { 0x39, 0x02 },
- { 0x35, 0x88 },
- { 0x22, 0x0a },
- { 0x37, 0x40 },
- { 0x23, 0x00 },
- { ARCOM2, 0xa0 },
- { 0x06, 0x02 },
- { 0x06, 0x88 },
- { 0x07, 0xc0 },
- { 0x0d, 0xb7 },
- { 0x0e, 0x01 },
- { 0x4c, 0x00 },
- { 0x4a, 0x81 },
- { 0x21, 0x99 },
- { AEW, 0x40 },
- { AEB, 0x38 },
- { VV, VV_HIGH_TH_SET(0x08) | VV_LOW_TH_SET(0x02) },
- { 0x5c, 0x00 },
- { 0x63, 0x00 },
- { FLL, 0x22 },
- { COM3, 0x38 | COM3_BAND_AUTO },
- { REG5D, 0x55 },
- { REG5E, 0x7d },
- { REG5F, 0x7d },
- { REG60, 0x55 },
- { HISTO_LOW, 0x70 },
- { HISTO_HIGH, 0x80 },
- { 0x7c, 0x05 },
- { 0x20, 0x80 },
- { 0x28, 0x30 },
- { 0x6c, 0x00 },
- { 0x6d, 0x80 },
- { 0x6e, 0x00 },
- { 0x70, 0x02 },
- { 0x71, 0x94 },
- { 0x73, 0xc1 },
- { 0x3d, 0x34 },
- { COM7, COM7_RES_UXGA | COM7_ZOOM_EN },
- { 0x5a, 0x57 },
- { BD50, 0xbb },
- { BD60, 0x9c },
- { BANK_SEL, BANK_SEL_DSP },
- { 0xe5, 0x7f },
- { MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL },
- { 0x41, 0x24 },
- { RESET, RESET_JPEG | RESET_DVP },
- { 0x76, 0xff },
- { 0x33, 0xa0 },
- { 0x42, 0x20 },
- { 0x43, 0x18 },
- { 0x4c, 0x00 },
- { CTRL3, CTRL3_BPC_EN | CTRL3_WPC_EN | 0x10 },
- { 0x88, 0x3f },
- { 0xd7, 0x03 },
- { 0xd9, 0x10 },
- { R_DVP_SP , R_DVP_SP_AUTO_MODE | 0x2 },
- { 0xc8, 0x08 },
- { 0xc9, 0x80 },
- { BPADDR, 0x00 },
- { BPDATA, 0x00 },
- { BPADDR, 0x03 },
- { BPDATA, 0x48 },
- { BPDATA, 0x48 },
- { BPADDR, 0x08 },
- { BPDATA, 0x20 },
- { BPDATA, 0x10 },
- { BPDATA, 0x0e },
- { 0x90, 0x00 },
- { 0x91, 0x0e },
- { 0x91, 0x1a },
- { 0x91, 0x31 },
- { 0x91, 0x5a },
- { 0x91, 0x69 },
- { 0x91, 0x75 },
- { 0x91, 0x7e },
- { 0x91, 0x88 },
- { 0x91, 0x8f },
- { 0x91, 0x96 },
- { 0x91, 0xa3 },
- { 0x91, 0xaf },
- { 0x91, 0xc4 },
- { 0x91, 0xd7 },
- { 0x91, 0xe8 },
- { 0x91, 0x20 },
- { 0x92, 0x00 },
- { 0x93, 0x06 },
- { 0x93, 0xe3 },
- { 0x93, 0x03 },
- { 0x93, 0x03 },
- { 0x93, 0x00 },
- { 0x93, 0x02 },
- { 0x93, 0x00 },
- { 0x93, 0x00 },
- { 0x93, 0x00 },
- { 0x93, 0x00 },
- { 0x93, 0x00 },
- { 0x93, 0x00 },
- { 0x93, 0x00 },
- { 0x96, 0x00 },
- { 0x97, 0x08 },
- { 0x97, 0x19 },
- { 0x97, 0x02 },
- { 0x97, 0x0c },
- { 0x97, 0x24 },
- { 0x97, 0x30 },
- { 0x97, 0x28 },
- { 0x97, 0x26 },
- { 0x97, 0x02 },
- { 0x97, 0x98 },
- { 0x97, 0x80 },
- { 0x97, 0x00 },
- { 0x97, 0x00 },
- { 0xa4, 0x00 },
- { 0xa8, 0x00 },
- { 0xc5, 0x11 },
- { 0xc6, 0x51 },
- { 0xbf, 0x80 },
- { 0xc7, 0x10 },
- { 0xb6, 0x66 },
- { 0xb8, 0xA5 },
- { 0xb7, 0x64 },
- { 0xb9, 0x7C },
- { 0xb3, 0xaf },
- { 0xb4, 0x97 },
- { 0xb5, 0xFF },
- { 0xb0, 0xC5 },
- { 0xb1, 0x94 },
- { 0xb2, 0x0f },
- { 0xc4, 0x5c },
- { 0xa6, 0x00 },
- { 0xa7, 0x20 },
- { 0xa7, 0xd8 },
- { 0xa7, 0x1b },
- { 0xa7, 0x31 },
- { 0xa7, 0x00 },
- { 0xa7, 0x18 },
- { 0xa7, 0x20 },
- { 0xa7, 0xd8 },
- { 0xa7, 0x19 },
- { 0xa7, 0x31 },
- { 0xa7, 0x00 },
- { 0xa7, 0x18 },
- { 0xa7, 0x20 },
- { 0xa7, 0xd8 },
- { 0xa7, 0x19 },
- { 0xa7, 0x31 },
- { 0xa7, 0x00 },
- { 0xa7, 0x18 },
- { 0x7f, 0x00 },
- { 0xe5, 0x1f },
- { 0xe1, 0x77 },
- { 0xdd, 0x7f },
- { CTRL0, CTRL0_YUV422 | CTRL0_YUV_EN | CTRL0_RGB_EN },
- ENDMARKER,
-};
-
-/*
- * Register settings for window size
- * The preamble, setup the internal DSP to input an UXGA (1600x1200) image.
- * Then the different zooming configurations will setup the output image size.
- */
-static const struct regval_list ov2640_size_change_preamble_regs[] = {
- { BANK_SEL, BANK_SEL_DSP },
- { RESET, RESET_DVP },
- { HSIZE8, HSIZE8_SET(W_UXGA) },
- { VSIZE8, VSIZE8_SET(H_UXGA) },
- { CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN |
- CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN },
- { HSIZE, HSIZE_SET(W_UXGA) },
- { VSIZE, VSIZE_SET(H_UXGA) },
- { XOFFL, XOFFL_SET(0) },
- { YOFFL, YOFFL_SET(0) },
- { VHYX, VHYX_HSIZE_SET(W_UXGA) | VHYX_VSIZE_SET(H_UXGA) |
- VHYX_XOFF_SET(0) | VHYX_YOFF_SET(0)},
- { TEST, TEST_HSIZE_SET(W_UXGA) },
- ENDMARKER,
-};
-
-#define PER_SIZE_REG_SEQ(x, y, v_div, h_div, pclk_div) \
- { CTRLI, CTRLI_LP_DP | CTRLI_V_DIV_SET(v_div) | \
- CTRLI_H_DIV_SET(h_div)}, \
- { ZMOW, ZMOW_OUTW_SET(x) }, \
- { ZMOH, ZMOH_OUTH_SET(y) }, \
- { ZMHH, ZMHH_OUTW_SET(x) | ZMHH_OUTH_SET(y) }, \
- { R_DVP_SP, pclk_div }, \
- { RESET, 0x00}
-
-static const struct regval_list ov2640_qcif_regs[] = {
- PER_SIZE_REG_SEQ(W_QCIF, H_QCIF, 3, 3, 4),
- ENDMARKER,
-};
-
-static const struct regval_list ov2640_qvga_regs[] = {
- PER_SIZE_REG_SEQ(W_QVGA, H_QVGA, 2, 2, 4),
- ENDMARKER,
-};
-
-static const struct regval_list ov2640_cif_regs[] = {
- PER_SIZE_REG_SEQ(W_CIF, H_CIF, 2, 2, 8),
- ENDMARKER,
-};
-
-static const struct regval_list ov2640_vga_regs[] = {
- PER_SIZE_REG_SEQ(W_VGA, H_VGA, 0, 0, 2),
- ENDMARKER,
-};
-
-static const struct regval_list ov2640_svga_regs[] = {
- PER_SIZE_REG_SEQ(W_SVGA, H_SVGA, 1, 1, 2),
- ENDMARKER,
-};
-
-static const struct regval_list ov2640_xga_regs[] = {
- PER_SIZE_REG_SEQ(W_XGA, H_XGA, 0, 0, 2),
- { CTRLI, 0x00},
- ENDMARKER,
-};
-
-static const struct regval_list ov2640_sxga_regs[] = {
- PER_SIZE_REG_SEQ(W_SXGA, H_SXGA, 0, 0, 2),
- { CTRLI, 0x00},
- { R_DVP_SP, 2 | R_DVP_SP_AUTO_MODE },
- ENDMARKER,
-};
-
-static const struct regval_list ov2640_uxga_regs[] = {
- PER_SIZE_REG_SEQ(W_UXGA, H_UXGA, 0, 0, 0),
- { CTRLI, 0x00},
- { R_DVP_SP, 0 | R_DVP_SP_AUTO_MODE },
- ENDMARKER,
-};
-
-#define OV2640_SIZE(n, w, h, r) \
- {.name = n, .width = w , .height = h, .regs = r }
-
-static const struct ov2640_win_size ov2640_supported_win_sizes[] = {
- OV2640_SIZE("QCIF", W_QCIF, H_QCIF, ov2640_qcif_regs),
- OV2640_SIZE("QVGA", W_QVGA, H_QVGA, ov2640_qvga_regs),
- OV2640_SIZE("CIF", W_CIF, H_CIF, ov2640_cif_regs),
- OV2640_SIZE("VGA", W_VGA, H_VGA, ov2640_vga_regs),
- OV2640_SIZE("SVGA", W_SVGA, H_SVGA, ov2640_svga_regs),
- OV2640_SIZE("XGA", W_XGA, H_XGA, ov2640_xga_regs),
- OV2640_SIZE("SXGA", W_SXGA, H_SXGA, ov2640_sxga_regs),
- OV2640_SIZE("UXGA", W_UXGA, H_UXGA, ov2640_uxga_regs),
-};
-
-/*
- * Register settings for pixel formats
- */
-static const struct regval_list ov2640_format_change_preamble_regs[] = {
- { BANK_SEL, BANK_SEL_DSP },
- { R_BYPASS, R_BYPASS_USE_DSP },
- ENDMARKER,
-};
-
-static const struct regval_list ov2640_yuv422_regs[] = {
- { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_YUV422 },
- { 0xD7, 0x01 },
- { 0x33, 0xa0 },
- { 0xe1, 0x67 },
- { RESET, 0x00 },
- { R_BYPASS, R_BYPASS_USE_DSP },
- ENDMARKER,
-};
-
-static const struct regval_list ov2640_rgb565_regs[] = {
- { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_RGB565 },
- { 0xd7, 0x03 },
- { RESET, 0x00 },
- { R_BYPASS, R_BYPASS_USE_DSP },
- ENDMARKER,
-};
-
-static enum v4l2_mbus_pixelcode ov2640_codes[] = {
- V4L2_MBUS_FMT_UYVY8_2X8,
- V4L2_MBUS_FMT_RGB565_2X8_LE,
-};
-
-/*
- * General functions
- */
-static struct ov2640_priv *to_ov2640(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client), struct ov2640_priv,
- subdev);
-}
-
-static int ov2640_write_array(struct i2c_client *client,
- const struct regval_list *vals)
-{
- int ret;
-
- while ((vals->reg_num != 0xff) || (vals->value != 0xff)) {
- ret = i2c_smbus_write_byte_data(client,
- vals->reg_num, vals->value);
- dev_vdbg(&client->dev, "array: 0x%02x, 0x%02x",
- vals->reg_num, vals->value);
-
- if (ret < 0)
- return ret;
- vals++;
- }
- return 0;
-}
-
-static int ov2640_mask_set(struct i2c_client *client,
- u8 reg, u8 mask, u8 set)
-{
- s32 val = i2c_smbus_read_byte_data(client, reg);
- if (val < 0)
- return val;
-
- val &= ~mask;
- val |= set & mask;
-
- dev_vdbg(&client->dev, "masks: 0x%02x, 0x%02x", reg, val);
-
- return i2c_smbus_write_byte_data(client, reg, val);
-}
-
-static int ov2640_reset(struct i2c_client *client)
-{
- int ret;
- const struct regval_list reset_seq[] = {
- {BANK_SEL, BANK_SEL_SENS},
- {COM7, COM7_SRST},
- ENDMARKER,
- };
-
- ret = ov2640_write_array(client, reset_seq);
- if (ret)
- goto err;
-
- msleep(5);
-err:
- dev_dbg(&client->dev, "%s: (ret %d)", __func__, ret);
- return ret;
-}
-
-/*
- * soc_camera_ops functions
- */
-static int ov2640_s_stream(struct v4l2_subdev *sd, int enable)
-{
- return 0;
-}
-
-static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd =
- &container_of(ctrl->handler, struct ov2640_priv, hdl)->subdev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 val;
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- val = ctrl->val ? REG04_VFLIP_IMG : 0x00;
- return ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
- case V4L2_CID_HFLIP:
- val = ctrl->val ? REG04_HFLIP_IMG : 0x00;
- return ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
- }
-
- return -EINVAL;
-}
-
-static int ov2640_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov2640_priv *priv = to_ov2640(client);
-
- id->ident = priv->model;
- id->revision = 0;
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ov2640_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
-
- reg->size = 1;
- if (reg->reg > 0xff)
- return -EINVAL;
-
- ret = i2c_smbus_read_byte_data(client, reg->reg);
- if (ret < 0)
- return ret;
-
- reg->val = ret;
-
- return 0;
-}
-
-static int ov2640_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->reg > 0xff ||
- reg->val > 0xff)
- return -EINVAL;
-
- return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
-}
-#endif
-
-/* Select the nearest higher resolution for capture */
-static const struct ov2640_win_size *ov2640_select_win(u32 *width, u32 *height)
-{
- int i, default_size = ARRAY_SIZE(ov2640_supported_win_sizes) - 1;
-
- for (i = 0; i < ARRAY_SIZE(ov2640_supported_win_sizes); i++) {
- if (ov2640_supported_win_sizes[i].width >= *width &&
- ov2640_supported_win_sizes[i].height >= *height) {
- *width = ov2640_supported_win_sizes[i].width;
- *height = ov2640_supported_win_sizes[i].height;
- return &ov2640_supported_win_sizes[i];
- }
- }
-
- *width = ov2640_supported_win_sizes[default_size].width;
- *height = ov2640_supported_win_sizes[default_size].height;
- return &ov2640_supported_win_sizes[default_size];
-}
-
-static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height,
- enum v4l2_mbus_pixelcode code)
-{
- struct ov2640_priv *priv = to_ov2640(client);
- const struct regval_list *selected_cfmt_regs;
- int ret;
-
- /* select win */
- priv->win = ov2640_select_win(width, height);
-
- /* select format */
- priv->cfmt_code = 0;
- switch (code) {
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- dev_dbg(&client->dev, "%s: Selected cfmt RGB565", __func__);
- selected_cfmt_regs = ov2640_rgb565_regs;
- break;
- default:
- case V4L2_MBUS_FMT_UYVY8_2X8:
- dev_dbg(&client->dev, "%s: Selected cfmt YUV422", __func__);
- selected_cfmt_regs = ov2640_yuv422_regs;
- }
-
- /* reset hardware */
- ov2640_reset(client);
-
- /* initialize the sensor with default data */
- dev_dbg(&client->dev, "%s: Init default", __func__);
- ret = ov2640_write_array(client, ov2640_init_regs);
- if (ret < 0)
- goto err;
-
- /* select preamble */
- dev_dbg(&client->dev, "%s: Set size to %s", __func__, priv->win->name);
- ret = ov2640_write_array(client, ov2640_size_change_preamble_regs);
- if (ret < 0)
- goto err;
-
- /* set size win */
- ret = ov2640_write_array(client, priv->win->regs);
- if (ret < 0)
- goto err;
-
- /* cfmt preamble */
- dev_dbg(&client->dev, "%s: Set cfmt", __func__);
- ret = ov2640_write_array(client, ov2640_format_change_preamble_regs);
- if (ret < 0)
- goto err;
-
- /* set cfmt */
- ret = ov2640_write_array(client, selected_cfmt_regs);
- if (ret < 0)
- goto err;
-
- priv->cfmt_code = code;
- *width = priv->win->width;
- *height = priv->win->height;
-
- return 0;
-
-err:
- dev_err(&client->dev, "%s: Error %d", __func__, ret);
- ov2640_reset(client);
- priv->win = NULL;
-
- return ret;
-}
-
-static int ov2640_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov2640_priv *priv = to_ov2640(client);
-
- if (!priv->win) {
- u32 width = W_SVGA, height = H_SVGA;
- priv->win = ov2640_select_win(&width, &height);
- priv->cfmt_code = V4L2_MBUS_FMT_UYVY8_2X8;
- }
-
- mf->width = priv->win->width;
- mf->height = priv->win->height;
- mf->code = priv->cfmt_code;
-
- switch (mf->code) {
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- mf->colorspace = V4L2_COLORSPACE_SRGB;
- break;
- default:
- case V4L2_MBUS_FMT_UYVY8_2X8:
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- }
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int ov2640_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
-
-
- switch (mf->code) {
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- mf->colorspace = V4L2_COLORSPACE_SRGB;
- break;
- default:
- mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
- case V4L2_MBUS_FMT_UYVY8_2X8:
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- }
-
- ret = ov2640_set_params(client, &mf->width, &mf->height, mf->code);
-
- return ret;
-}
-
-static int ov2640_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- const struct ov2640_win_size *win;
-
- /*
- * select suitable win
- */
- win = ov2640_select_win(&mf->width, &mf->height);
-
- mf->field = V4L2_FIELD_NONE;
-
- switch (mf->code) {
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- mf->colorspace = V4L2_COLORSPACE_SRGB;
- break;
- default:
- mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
- case V4L2_MBUS_FMT_UYVY8_2X8:
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- }
-
- return 0;
-}
-
-static int ov2640_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index >= ARRAY_SIZE(ov2640_codes))
- return -EINVAL;
-
- *code = ov2640_codes[index];
- return 0;
-}
-
-static int ov2640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- a->c.left = 0;
- a->c.top = 0;
- a->c.width = W_UXGA;
- a->c.height = H_UXGA;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = W_UXGA;
- a->bounds.height = H_UXGA;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int ov2640_video_probe(struct i2c_client *client)
-{
- struct ov2640_priv *priv = to_ov2640(client);
- u8 pid, ver, midh, midl;
- const char *devname;
- int ret;
-
- /*
- * check and show product ID and manufacturer ID
- */
- i2c_smbus_write_byte_data(client, BANK_SEL, BANK_SEL_SENS);
- pid = i2c_smbus_read_byte_data(client, PID);
- ver = i2c_smbus_read_byte_data(client, VER);
- midh = i2c_smbus_read_byte_data(client, MIDH);
- midl = i2c_smbus_read_byte_data(client, MIDL);
-
- switch (VERSION(pid, ver)) {
- case PID_OV2640:
- devname = "ov2640";
- priv->model = V4L2_IDENT_OV2640;
- break;
- default:
- dev_err(&client->dev,
- "Product ID error %x:%x\n", pid, ver);
- ret = -ENODEV;
- goto err;
- }
-
- dev_info(&client->dev,
- "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
- devname, pid, ver, midh, midl);
-
- return v4l2_ctrl_handler_setup(&priv->hdl);
-
-err:
- return ret;
-}
-
-static const struct v4l2_ctrl_ops ov2640_ctrl_ops = {
- .s_ctrl = ov2640_s_ctrl,
-};
-
-static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
- .g_chip_ident = ov2640_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = ov2640_g_register,
- .s_register = ov2640_s_register,
-#endif
-};
-
-static int ov2640_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
- V4L2_MBUS_DATA_ACTIVE_HIGH;
- cfg->type = V4L2_MBUS_PARALLEL;
- cfg->flags = soc_camera_apply_board_flags(icl, cfg);
-
- return 0;
-}
-
-static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
- .s_stream = ov2640_s_stream,
- .g_mbus_fmt = ov2640_g_fmt,
- .s_mbus_fmt = ov2640_s_fmt,
- .try_mbus_fmt = ov2640_try_fmt,
- .cropcap = ov2640_cropcap,
- .g_crop = ov2640_g_crop,
- .enum_mbus_fmt = ov2640_enum_fmt,
- .g_mbus_config = ov2640_g_mbus_config,
-};
-
-static struct v4l2_subdev_ops ov2640_subdev_ops = {
- .core = &ov2640_subdev_core_ops,
- .video = &ov2640_subdev_video_ops,
-};
-
-/*
- * i2c_driver functions
- */
-static int ov2640_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct ov2640_priv *priv;
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- int ret;
-
- if (!icl) {
- dev_err(&adapter->dev,
- "OV2640: Missing platform_data for driver\n");
- return -EINVAL;
- }
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_err(&adapter->dev,
- "OV2640: I2C-Adapter doesn't support SMBUS\n");
- return -EIO;
- }
-
- priv = kzalloc(sizeof(struct ov2640_priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&adapter->dev,
- "Failed to allocate memory for private data!\n");
- return -ENOMEM;
- }
-
- v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops);
- v4l2_ctrl_handler_init(&priv->hdl, 2);
- v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- priv->subdev.ctrl_handler = &priv->hdl;
- if (priv->hdl.error) {
- int err = priv->hdl.error;
-
- kfree(priv);
- return err;
- }
-
- ret = ov2640_video_probe(client);
- if (ret) {
- v4l2_ctrl_handler_free(&priv->hdl);
- kfree(priv);
- } else {
- dev_info(&adapter->dev, "OV2640 Probed\n");
- }
-
- return ret;
-}
-
-static int ov2640_remove(struct i2c_client *client)
-{
- struct ov2640_priv *priv = to_ov2640(client);
-
- v4l2_device_unregister_subdev(&priv->subdev);
- v4l2_ctrl_handler_free(&priv->hdl);
- kfree(priv);
- return 0;
-}
-
-static const struct i2c_device_id ov2640_id[] = {
- { "ov2640", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ov2640_id);
-
-static struct i2c_driver ov2640_i2c_driver = {
- .driver = {
- .name = "ov2640",
- },
- .probe = ov2640_probe,
- .remove = ov2640_remove,
- .id_table = ov2640_id,
-};
-
-module_i2c_driver(ov2640_i2c_driver);
-
-MODULE_DESCRIPTION("SoC Camera driver for Omni Vision 2640 sensor");
-MODULE_AUTHOR("Alberto Panizzo");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/ov5642.c b/drivers/media/video/ov5642.c
deleted file mode 100644
index 0bc93313d37..00000000000
--- a/drivers/media/video/ov5642.c
+++ /dev/null
@@ -1,1073 +0,0 @@
-/*
- * Driver for OV5642 CMOS Image Sensor from Omnivision
- *
- * Copyright (C) 2011, Bastian Hecht <hechtb@gmail.com>
- *
- * Based on Sony IMX074 Camera Driver
- * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * Based on Omnivision OV7670 Camera Driver
- * Copyright (C) 2006-7 Jonathan Corbet <corbet@lwn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/bitops.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/module.h>
-#include <linux/v4l2-mediabus.h>
-
-#include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-subdev.h>
-
-/* OV5642 registers */
-#define REG_CHIP_ID_HIGH 0x300a
-#define REG_CHIP_ID_LOW 0x300b
-
-#define REG_WINDOW_START_X_HIGH 0x3800
-#define REG_WINDOW_START_X_LOW 0x3801
-#define REG_WINDOW_START_Y_HIGH 0x3802
-#define REG_WINDOW_START_Y_LOW 0x3803
-#define REG_WINDOW_WIDTH_HIGH 0x3804
-#define REG_WINDOW_WIDTH_LOW 0x3805
-#define REG_WINDOW_HEIGHT_HIGH 0x3806
-#define REG_WINDOW_HEIGHT_LOW 0x3807
-#define REG_OUT_WIDTH_HIGH 0x3808
-#define REG_OUT_WIDTH_LOW 0x3809
-#define REG_OUT_HEIGHT_HIGH 0x380a
-#define REG_OUT_HEIGHT_LOW 0x380b
-#define REG_OUT_TOTAL_WIDTH_HIGH 0x380c
-#define REG_OUT_TOTAL_WIDTH_LOW 0x380d
-#define REG_OUT_TOTAL_HEIGHT_HIGH 0x380e
-#define REG_OUT_TOTAL_HEIGHT_LOW 0x380f
-#define REG_OUTPUT_FORMAT 0x4300
-#define REG_ISP_CTRL_01 0x5001
-#define REG_AVG_WINDOW_END_X_HIGH 0x5682
-#define REG_AVG_WINDOW_END_X_LOW 0x5683
-#define REG_AVG_WINDOW_END_Y_HIGH 0x5686
-#define REG_AVG_WINDOW_END_Y_LOW 0x5687
-
-/* active pixel array size */
-#define OV5642_SENSOR_SIZE_X 2592
-#define OV5642_SENSOR_SIZE_Y 1944
-
-/*
- * About OV5642 resolution, cropping and binning:
- * This sensor supports it all, at least in the feature description.
- * Unfortunately, no combination of appropriate registers settings could make
- * the chip work the intended way. As it works with predefined register lists,
- * some undocumented registers are presumably changed there to achieve their
- * goals.
- * This driver currently only works for resolutions up to 720 lines with a
- * 1:1 scale. Hopefully these restrictions will be removed in the future.
- */
-#define OV5642_MAX_WIDTH OV5642_SENSOR_SIZE_X
-#define OV5642_MAX_HEIGHT 720
-
-/* default sizes */
-#define OV5642_DEFAULT_WIDTH 1280
-#define OV5642_DEFAULT_HEIGHT OV5642_MAX_HEIGHT
-
-/* minimum extra blanking */
-#define BLANKING_EXTRA_WIDTH 500
-#define BLANKING_EXTRA_HEIGHT 20
-
-/*
- * the sensor's autoexposure is buggy when setting total_height low.
- * It tries to expose longer than 1 frame period without taking care of it
- * and this leads to weird output. So we set 1000 lines as minimum.
- */
-#define BLANKING_MIN_HEIGHT 1000
-
-struct regval_list {
- u16 reg_num;
- u8 value;
-};
-
-static struct regval_list ov5642_default_regs_init[] = {
- { 0x3103, 0x93 },
- { 0x3008, 0x82 },
- { 0x3017, 0x7f },
- { 0x3018, 0xfc },
- { 0x3810, 0xc2 },
- { 0x3615, 0xf0 },
- { 0x3000, 0x0 },
- { 0x3001, 0x0 },
- { 0x3002, 0x0 },
- { 0x3003, 0x0 },
- { 0x3004, 0xff },
- { 0x3030, 0x2b },
- { 0x3011, 0x8 },
- { 0x3010, 0x10 },
- { 0x3604, 0x60 },
- { 0x3622, 0x60 },
- { 0x3621, 0x9 },
- { 0x3709, 0x0 },
- { 0x4000, 0x21 },
- { 0x401d, 0x22 },
- { 0x3600, 0x54 },
- { 0x3605, 0x4 },
- { 0x3606, 0x3f },
- { 0x3c01, 0x80 },
- { 0x300d, 0x22 },
- { 0x3623, 0x22 },
- { 0x5000, 0x4f },
- { 0x5020, 0x4 },
- { 0x5181, 0x79 },
- { 0x5182, 0x0 },
- { 0x5185, 0x22 },
- { 0x5197, 0x1 },
- { 0x5500, 0xa },
- { 0x5504, 0x0 },
- { 0x5505, 0x7f },
- { 0x5080, 0x8 },
- { 0x300e, 0x18 },
- { 0x4610, 0x0 },
- { 0x471d, 0x5 },
- { 0x4708, 0x6 },
- { 0x370c, 0xa0 },
- { 0x5687, 0x94 },
- { 0x501f, 0x0 },
- { 0x5000, 0x4f },
- { 0x5001, 0xcf },
- { 0x4300, 0x30 },
- { 0x4300, 0x30 },
- { 0x460b, 0x35 },
- { 0x471d, 0x0 },
- { 0x3002, 0xc },
- { 0x3002, 0x0 },
- { 0x4713, 0x3 },
- { 0x471c, 0x50 },
- { 0x4721, 0x2 },
- { 0x4402, 0x90 },
- { 0x460c, 0x22 },
- { 0x3815, 0x44 },
- { 0x3503, 0x7 },
- { 0x3501, 0x73 },
- { 0x3502, 0x80 },
- { 0x350b, 0x0 },
- { 0x3818, 0xc8 },
- { 0x3824, 0x11 },
- { 0x3a00, 0x78 },
- { 0x3a1a, 0x4 },
- { 0x3a13, 0x30 },
- { 0x3a18, 0x0 },
- { 0x3a19, 0x7c },
- { 0x3a08, 0x12 },
- { 0x3a09, 0xc0 },
- { 0x3a0a, 0xf },
- { 0x3a0b, 0xa0 },
- { 0x350c, 0x7 },
- { 0x350d, 0xd0 },
- { 0x3a0d, 0x8 },
- { 0x3a0e, 0x6 },
- { 0x3500, 0x0 },
- { 0x3501, 0x0 },
- { 0x3502, 0x0 },
- { 0x350a, 0x0 },
- { 0x350b, 0x0 },
- { 0x3503, 0x0 },
- { 0x3a0f, 0x3c },
- { 0x3a10, 0x32 },
- { 0x3a1b, 0x3c },
- { 0x3a1e, 0x32 },
- { 0x3a11, 0x80 },
- { 0x3a1f, 0x20 },
- { 0x3030, 0x2b },
- { 0x3a02, 0x0 },
- { 0x3a03, 0x7d },
- { 0x3a04, 0x0 },
- { 0x3a14, 0x0 },
- { 0x3a15, 0x7d },
- { 0x3a16, 0x0 },
- { 0x3a00, 0x78 },
- { 0x3a08, 0x9 },
- { 0x3a09, 0x60 },
- { 0x3a0a, 0x7 },
- { 0x3a0b, 0xd0 },
- { 0x3a0d, 0x10 },
- { 0x3a0e, 0xd },
- { 0x4407, 0x4 },
- { 0x5193, 0x70 },
- { 0x589b, 0x0 },
- { 0x589a, 0xc0 },
- { 0x401e, 0x20 },
- { 0x4001, 0x42 },
- { 0x401c, 0x6 },
- { 0x3825, 0xac },
- { 0x3827, 0xc },
- { 0x528a, 0x1 },
- { 0x528b, 0x4 },
- { 0x528c, 0x8 },
- { 0x528d, 0x10 },
- { 0x528e, 0x20 },
- { 0x528f, 0x28 },
- { 0x5290, 0x30 },
- { 0x5292, 0x0 },
- { 0x5293, 0x1 },
- { 0x5294, 0x0 },
- { 0x5295, 0x4 },
- { 0x5296, 0x0 },
- { 0x5297, 0x8 },
- { 0x5298, 0x0 },
- { 0x5299, 0x10 },
- { 0x529a, 0x0 },
- { 0x529b, 0x20 },
- { 0x529c, 0x0 },
- { 0x529d, 0x28 },
- { 0x529e, 0x0 },
- { 0x529f, 0x30 },
- { 0x5282, 0x0 },
- { 0x5300, 0x0 },
- { 0x5301, 0x20 },
- { 0x5302, 0x0 },
- { 0x5303, 0x7c },
- { 0x530c, 0x0 },
- { 0x530d, 0xc },
- { 0x530e, 0x20 },
- { 0x530f, 0x80 },
- { 0x5310, 0x20 },
- { 0x5311, 0x80 },
- { 0x5308, 0x20 },
- { 0x5309, 0x40 },
- { 0x5304, 0x0 },
- { 0x5305, 0x30 },
- { 0x5306, 0x0 },
- { 0x5307, 0x80 },
- { 0x5314, 0x8 },
- { 0x5315, 0x20 },
- { 0x5319, 0x30 },
- { 0x5316, 0x10 },
- { 0x5317, 0x0 },
- { 0x5318, 0x2 },
- { 0x5380, 0x1 },
- { 0x5381, 0x0 },
- { 0x5382, 0x0 },
- { 0x5383, 0x4e },
- { 0x5384, 0x0 },
- { 0x5385, 0xf },
- { 0x5386, 0x0 },
- { 0x5387, 0x0 },
- { 0x5388, 0x1 },
- { 0x5389, 0x15 },
- { 0x538a, 0x0 },
- { 0x538b, 0x31 },
- { 0x538c, 0x0 },
- { 0x538d, 0x0 },
- { 0x538e, 0x0 },
- { 0x538f, 0xf },
- { 0x5390, 0x0 },
- { 0x5391, 0xab },
- { 0x5392, 0x0 },
- { 0x5393, 0xa2 },
- { 0x5394, 0x8 },
- { 0x5480, 0x14 },
- { 0x5481, 0x21 },
- { 0x5482, 0x36 },
- { 0x5483, 0x57 },
- { 0x5484, 0x65 },
- { 0x5485, 0x71 },
- { 0x5486, 0x7d },
- { 0x5487, 0x87 },
- { 0x5488, 0x91 },
- { 0x5489, 0x9a },
- { 0x548a, 0xaa },
- { 0x548b, 0xb8 },
- { 0x548c, 0xcd },
- { 0x548d, 0xdd },
- { 0x548e, 0xea },
- { 0x548f, 0x1d },
- { 0x5490, 0x5 },
- { 0x5491, 0x0 },
- { 0x5492, 0x4 },
- { 0x5493, 0x20 },
- { 0x5494, 0x3 },
- { 0x5495, 0x60 },
- { 0x5496, 0x2 },
- { 0x5497, 0xb8 },
- { 0x5498, 0x2 },
- { 0x5499, 0x86 },
- { 0x549a, 0x2 },
- { 0x549b, 0x5b },
- { 0x549c, 0x2 },
- { 0x549d, 0x3b },
- { 0x549e, 0x2 },
- { 0x549f, 0x1c },
- { 0x54a0, 0x2 },
- { 0x54a1, 0x4 },
- { 0x54a2, 0x1 },
- { 0x54a3, 0xed },
- { 0x54a4, 0x1 },
- { 0x54a5, 0xc5 },
- { 0x54a6, 0x1 },
- { 0x54a7, 0xa5 },
- { 0x54a8, 0x1 },
- { 0x54a9, 0x6c },
- { 0x54aa, 0x1 },
- { 0x54ab, 0x41 },
- { 0x54ac, 0x1 },
- { 0x54ad, 0x20 },
- { 0x54ae, 0x0 },
- { 0x54af, 0x16 },
- { 0x54b0, 0x1 },
- { 0x54b1, 0x20 },
- { 0x54b2, 0x0 },
- { 0x54b3, 0x10 },
- { 0x54b4, 0x0 },
- { 0x54b5, 0xf0 },
- { 0x54b6, 0x0 },
- { 0x54b7, 0xdf },
- { 0x5402, 0x3f },
- { 0x5403, 0x0 },
- { 0x3406, 0x0 },
- { 0x5180, 0xff },
- { 0x5181, 0x52 },
- { 0x5182, 0x11 },
- { 0x5183, 0x14 },
- { 0x5184, 0x25 },
- { 0x5185, 0x24 },
- { 0x5186, 0x6 },
- { 0x5187, 0x8 },
- { 0x5188, 0x8 },
- { 0x5189, 0x7c },
- { 0x518a, 0x60 },
- { 0x518b, 0xb2 },
- { 0x518c, 0xb2 },
- { 0x518d, 0x44 },
- { 0x518e, 0x3d },
- { 0x518f, 0x58 },
- { 0x5190, 0x46 },
- { 0x5191, 0xf8 },
- { 0x5192, 0x4 },
- { 0x5193, 0x70 },
- { 0x5194, 0xf0 },
- { 0x5195, 0xf0 },
- { 0x5196, 0x3 },
- { 0x5197, 0x1 },
- { 0x5198, 0x4 },
- { 0x5199, 0x12 },
- { 0x519a, 0x4 },
- { 0x519b, 0x0 },
- { 0x519c, 0x6 },
- { 0x519d, 0x82 },
- { 0x519e, 0x0 },
- { 0x5025, 0x80 },
- { 0x3a0f, 0x38 },
- { 0x3a10, 0x30 },
- { 0x3a1b, 0x3a },
- { 0x3a1e, 0x2e },
- { 0x3a11, 0x60 },
- { 0x3a1f, 0x10 },
- { 0x5688, 0xa6 },
- { 0x5689, 0x6a },
- { 0x568a, 0xea },
- { 0x568b, 0xae },
- { 0x568c, 0xa6 },
- { 0x568d, 0x6a },
- { 0x568e, 0x62 },
- { 0x568f, 0x26 },
- { 0x5583, 0x40 },
- { 0x5584, 0x40 },
- { 0x5580, 0x2 },
- { 0x5000, 0xcf },
- { 0x5800, 0x27 },
- { 0x5801, 0x19 },
- { 0x5802, 0x12 },
- { 0x5803, 0xf },
- { 0x5804, 0x10 },
- { 0x5805, 0x15 },
- { 0x5806, 0x1e },
- { 0x5807, 0x2f },
- { 0x5808, 0x15 },
- { 0x5809, 0xd },
- { 0x580a, 0xa },
- { 0x580b, 0x9 },
- { 0x580c, 0xa },
- { 0x580d, 0xc },
- { 0x580e, 0x12 },
- { 0x580f, 0x19 },
- { 0x5810, 0xb },
- { 0x5811, 0x7 },
- { 0x5812, 0x4 },
- { 0x5813, 0x3 },
- { 0x5814, 0x3 },
- { 0x5815, 0x6 },
- { 0x5816, 0xa },
- { 0x5817, 0xf },
- { 0x5818, 0xa },
- { 0x5819, 0x5 },
- { 0x581a, 0x1 },
- { 0x581b, 0x0 },
- { 0x581c, 0x0 },
- { 0x581d, 0x3 },
- { 0x581e, 0x8 },
- { 0x581f, 0xc },
- { 0x5820, 0xa },
- { 0x5821, 0x5 },
- { 0x5822, 0x1 },
- { 0x5823, 0x0 },
- { 0x5824, 0x0 },
- { 0x5825, 0x3 },
- { 0x5826, 0x8 },
- { 0x5827, 0xc },
- { 0x5828, 0xe },
- { 0x5829, 0x8 },
- { 0x582a, 0x6 },
- { 0x582b, 0x4 },
- { 0x582c, 0x5 },
- { 0x582d, 0x7 },
- { 0x582e, 0xb },
- { 0x582f, 0x12 },
- { 0x5830, 0x18 },
- { 0x5831, 0x10 },
- { 0x5832, 0xc },
- { 0x5833, 0xa },
- { 0x5834, 0xb },
- { 0x5835, 0xe },
- { 0x5836, 0x15 },
- { 0x5837, 0x19 },
- { 0x5838, 0x32 },
- { 0x5839, 0x1f },
- { 0x583a, 0x18 },
- { 0x583b, 0x16 },
- { 0x583c, 0x17 },
- { 0x583d, 0x1e },
- { 0x583e, 0x26 },
- { 0x583f, 0x53 },
- { 0x5840, 0x10 },
- { 0x5841, 0xf },
- { 0x5842, 0xd },
- { 0x5843, 0xc },
- { 0x5844, 0xe },
- { 0x5845, 0x9 },
- { 0x5846, 0x11 },
- { 0x5847, 0x10 },
- { 0x5848, 0x10 },
- { 0x5849, 0x10 },
- { 0x584a, 0x10 },
- { 0x584b, 0xe },
- { 0x584c, 0x10 },
- { 0x584d, 0x10 },
- { 0x584e, 0x11 },
- { 0x584f, 0x10 },
- { 0x5850, 0xf },
- { 0x5851, 0xc },
- { 0x5852, 0xf },
- { 0x5853, 0x10 },
- { 0x5854, 0x10 },
- { 0x5855, 0xf },
- { 0x5856, 0xe },
- { 0x5857, 0xb },
- { 0x5858, 0x10 },
- { 0x5859, 0xd },
- { 0x585a, 0xd },
- { 0x585b, 0xc },
- { 0x585c, 0xc },
- { 0x585d, 0xc },
- { 0x585e, 0xb },
- { 0x585f, 0xc },
- { 0x5860, 0xc },
- { 0x5861, 0xc },
- { 0x5862, 0xd },
- { 0x5863, 0x8 },
- { 0x5864, 0x11 },
- { 0x5865, 0x18 },
- { 0x5866, 0x18 },
- { 0x5867, 0x19 },
- { 0x5868, 0x17 },
- { 0x5869, 0x19 },
- { 0x586a, 0x16 },
- { 0x586b, 0x13 },
- { 0x586c, 0x13 },
- { 0x586d, 0x12 },
- { 0x586e, 0x13 },
- { 0x586f, 0x16 },
- { 0x5870, 0x14 },
- { 0x5871, 0x12 },
- { 0x5872, 0x10 },
- { 0x5873, 0x11 },
- { 0x5874, 0x11 },
- { 0x5875, 0x16 },
- { 0x5876, 0x14 },
- { 0x5877, 0x11 },
- { 0x5878, 0x10 },
- { 0x5879, 0xf },
- { 0x587a, 0x10 },
- { 0x587b, 0x14 },
- { 0x587c, 0x13 },
- { 0x587d, 0x12 },
- { 0x587e, 0x11 },
- { 0x587f, 0x11 },
- { 0x5880, 0x12 },
- { 0x5881, 0x15 },
- { 0x5882, 0x14 },
- { 0x5883, 0x15 },
- { 0x5884, 0x15 },
- { 0x5885, 0x15 },
- { 0x5886, 0x13 },
- { 0x5887, 0x17 },
- { 0x3710, 0x10 },
- { 0x3632, 0x51 },
- { 0x3702, 0x10 },
- { 0x3703, 0xb2 },
- { 0x3704, 0x18 },
- { 0x370b, 0x40 },
- { 0x370d, 0x3 },
- { 0x3631, 0x1 },
- { 0x3632, 0x52 },
- { 0x3606, 0x24 },
- { 0x3620, 0x96 },
- { 0x5785, 0x7 },
- { 0x3a13, 0x30 },
- { 0x3600, 0x52 },
- { 0x3604, 0x48 },
- { 0x3606, 0x1b },
- { 0x370d, 0xb },
- { 0x370f, 0xc0 },
- { 0x3709, 0x1 },
- { 0x3823, 0x0 },
- { 0x5007, 0x0 },
- { 0x5009, 0x0 },
- { 0x5011, 0x0 },
- { 0x5013, 0x0 },
- { 0x519e, 0x0 },
- { 0x5086, 0x0 },
- { 0x5087, 0x0 },
- { 0x5088, 0x0 },
- { 0x5089, 0x0 },
- { 0x302b, 0x0 },
- { 0x3503, 0x7 },
- { 0x3011, 0x8 },
- { 0x350c, 0x2 },
- { 0x350d, 0xe4 },
- { 0x3621, 0xc9 },
- { 0x370a, 0x81 },
- { 0xffff, 0xff },
-};
-
-static struct regval_list ov5642_default_regs_finalise[] = {
- { 0x3810, 0xc2 },
- { 0x3818, 0xc9 },
- { 0x381c, 0x10 },
- { 0x381d, 0xa0 },
- { 0x381e, 0x5 },
- { 0x381f, 0xb0 },
- { 0x3820, 0x0 },
- { 0x3821, 0x0 },
- { 0x3824, 0x11 },
- { 0x3a08, 0x1b },
- { 0x3a09, 0xc0 },
- { 0x3a0a, 0x17 },
- { 0x3a0b, 0x20 },
- { 0x3a0d, 0x2 },
- { 0x3a0e, 0x1 },
- { 0x401c, 0x4 },
- { 0x5682, 0x5 },
- { 0x5683, 0x0 },
- { 0x5686, 0x2 },
- { 0x5687, 0xcc },
- { 0x5001, 0x4f },
- { 0x589b, 0x6 },
- { 0x589a, 0xc5 },
- { 0x3503, 0x0 },
- { 0x460c, 0x20 },
- { 0x460b, 0x37 },
- { 0x471c, 0xd0 },
- { 0x471d, 0x5 },
- { 0x3815, 0x1 },
- { 0x3818, 0xc1 },
- { 0x501f, 0x0 },
- { 0x5002, 0xe0 },
- { 0x4300, 0x32 }, /* UYVY */
- { 0x3002, 0x1c },
- { 0x4800, 0x14 },
- { 0x4801, 0xf },
- { 0x3007, 0x3b },
- { 0x300e, 0x4 },
- { 0x4803, 0x50 },
- { 0x3815, 0x1 },
- { 0x4713, 0x2 },
- { 0x4842, 0x1 },
- { 0x300f, 0xe },
- { 0x3003, 0x3 },
- { 0x3003, 0x1 },
- { 0xffff, 0xff },
-};
-
-struct ov5642_datafmt {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
-};
-
-struct ov5642 {
- struct v4l2_subdev subdev;
- const struct ov5642_datafmt *fmt;
- struct v4l2_rect crop_rect;
-
- /* blanking information */
- int total_width;
- int total_height;
-};
-
-static const struct ov5642_datafmt ov5642_colour_fmts[] = {
- {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},
-};
-
-static struct ov5642 *to_ov5642(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client), struct ov5642, subdev);
-}
-
-/* Find a data format by a pixel code in an array */
-static const struct ov5642_datafmt
- *ov5642_find_datafmt(enum v4l2_mbus_pixelcode code)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ov5642_colour_fmts); i++)
- if (ov5642_colour_fmts[i].code == code)
- return ov5642_colour_fmts + i;
-
- return NULL;
-}
-
-static int reg_read(struct i2c_client *client, u16 reg, u8 *val)
-{
- int ret;
- /* We have 16-bit i2c addresses - care for endianess */
- unsigned char data[2] = { reg >> 8, reg & 0xff };
-
- ret = i2c_master_send(client, data, 2);
- if (ret < 2) {
- dev_err(&client->dev, "%s: i2c read error, reg: %x\n",
- __func__, reg);
- return ret < 0 ? ret : -EIO;
- }
-
- ret = i2c_master_recv(client, val, 1);
- if (ret < 1) {
- dev_err(&client->dev, "%s: i2c read error, reg: %x\n",
- __func__, reg);
- return ret < 0 ? ret : -EIO;
- }
- return 0;
-}
-
-static int reg_write(struct i2c_client *client, u16 reg, u8 val)
-{
- int ret;
- unsigned char data[3] = { reg >> 8, reg & 0xff, val };
-
- ret = i2c_master_send(client, data, 3);
- if (ret < 3) {
- dev_err(&client->dev, "%s: i2c write error, reg: %x\n",
- __func__, reg);
- return ret < 0 ? ret : -EIO;
- }
-
- return 0;
-}
-
-/*
- * convenience function to write 16 bit register values that are split up
- * into two consecutive high and low parts
- */
-static int reg_write16(struct i2c_client *client, u16 reg, u16 val16)
-{
- int ret;
-
- ret = reg_write(client, reg, val16 >> 8);
- if (ret)
- return ret;
- return reg_write(client, reg + 1, val16 & 0x00ff);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ov5642_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
- u8 val;
-
- if (reg->reg & ~0xffff)
- return -EINVAL;
-
- reg->size = 1;
-
- ret = reg_read(client, reg->reg, &val);
- if (!ret)
- reg->val = (__u64)val;
-
- return ret;
-}
-
-static int ov5642_set_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->reg & ~0xffff || reg->val & ~0xff)
- return -EINVAL;
-
- return reg_write(client, reg->reg, reg->val);
-}
-#endif
-
-static int ov5642_write_array(struct i2c_client *client,
- struct regval_list *vals)
-{
- while (vals->reg_num != 0xffff || vals->value != 0xff) {
- int ret = reg_write(client, vals->reg_num, vals->value);
- if (ret < 0)
- return ret;
- vals++;
- }
- dev_dbg(&client->dev, "Register list loaded\n");
- return 0;
-}
-
-static int ov5642_set_resolution(struct v4l2_subdev *sd)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov5642 *priv = to_ov5642(client);
- int width = priv->crop_rect.width;
- int height = priv->crop_rect.height;
- int total_width = priv->total_width;
- int total_height = priv->total_height;
- int start_x = (OV5642_SENSOR_SIZE_X - width) / 2;
- int start_y = (OV5642_SENSOR_SIZE_Y - height) / 2;
- int ret;
-
- /*
- * This should set the starting point for cropping.
- * Doesn't work so far.
- */
- ret = reg_write16(client, REG_WINDOW_START_X_HIGH, start_x);
- if (!ret)
- ret = reg_write16(client, REG_WINDOW_START_Y_HIGH, start_y);
- if (!ret) {
- priv->crop_rect.left = start_x;
- priv->crop_rect.top = start_y;
- }
-
- if (!ret)
- ret = reg_write16(client, REG_WINDOW_WIDTH_HIGH, width);
- if (!ret)
- ret = reg_write16(client, REG_WINDOW_HEIGHT_HIGH, height);
- if (ret)
- return ret;
- priv->crop_rect.width = width;
- priv->crop_rect.height = height;
-
- /* Set the output window size. Only 1:1 scale is supported so far. */
- ret = reg_write16(client, REG_OUT_WIDTH_HIGH, width);
- if (!ret)
- ret = reg_write16(client, REG_OUT_HEIGHT_HIGH, height);
-
- /* Total width = output size + blanking */
- if (!ret)
- ret = reg_write16(client, REG_OUT_TOTAL_WIDTH_HIGH, total_width);
- if (!ret)
- ret = reg_write16(client, REG_OUT_TOTAL_HEIGHT_HIGH, total_height);
-
- /* Sets the window for AWB calculations */
- if (!ret)
- ret = reg_write16(client, REG_AVG_WINDOW_END_X_HIGH, width);
- if (!ret)
- ret = reg_write16(client, REG_AVG_WINDOW_END_Y_HIGH, height);
-
- return ret;
-}
-
-static int ov5642_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov5642 *priv = to_ov5642(client);
- const struct ov5642_datafmt *fmt = ov5642_find_datafmt(mf->code);
-
- mf->width = priv->crop_rect.width;
- mf->height = priv->crop_rect.height;
-
- if (!fmt) {
- mf->code = ov5642_colour_fmts[0].code;
- mf->colorspace = ov5642_colour_fmts[0].colorspace;
- }
-
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int ov5642_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov5642 *priv = to_ov5642(client);
-
- /* MIPI CSI could have changed the format, double-check */
- if (!ov5642_find_datafmt(mf->code))
- return -EINVAL;
-
- ov5642_try_fmt(sd, mf);
- priv->fmt = ov5642_find_datafmt(mf->code);
-
- return 0;
-}
-
-static int ov5642_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov5642 *priv = to_ov5642(client);
-
- const struct ov5642_datafmt *fmt = priv->fmt;
-
- mf->code = fmt->code;
- mf->colorspace = fmt->colorspace;
- mf->width = priv->crop_rect.width;
- mf->height = priv->crop_rect.height;
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int ov5642_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index >= ARRAY_SIZE(ov5642_colour_fmts))
- return -EINVAL;
-
- *code = ov5642_colour_fmts[index].code;
- return 0;
-}
-
-static int ov5642_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = V4L2_IDENT_OV5642;
- id->revision = 0;
-
- return 0;
-}
-
-static int ov5642_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov5642 *priv = to_ov5642(client);
- struct v4l2_rect *rect = &a->c;
- int ret;
-
- v4l_bound_align_image(&rect->width, 48, OV5642_MAX_WIDTH, 1,
- &rect->height, 32, OV5642_MAX_HEIGHT, 1, 0);
-
- priv->crop_rect.width = rect->width;
- priv->crop_rect.height = rect->height;
- priv->total_width = rect->width + BLANKING_EXTRA_WIDTH;
- priv->total_height = max_t(int, rect->height +
- BLANKING_EXTRA_HEIGHT,
- BLANKING_MIN_HEIGHT);
- priv->crop_rect.width = rect->width;
- priv->crop_rect.height = rect->height;
-
- ret = ov5642_write_array(client, ov5642_default_regs_init);
- if (!ret)
- ret = ov5642_set_resolution(sd);
- if (!ret)
- ret = ov5642_write_array(client, ov5642_default_regs_finalise);
-
- return ret;
-}
-
-static int ov5642_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov5642 *priv = to_ov5642(client);
- struct v4l2_rect *rect = &a->c;
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- *rect = priv->crop_rect;
-
- return 0;
-}
-
-static int ov5642_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = OV5642_MAX_WIDTH;
- a->bounds.height = OV5642_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int ov5642_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- cfg->type = V4L2_MBUS_CSI2;
- cfg->flags = V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
- V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
-
- return 0;
-}
-
-static int ov5642_s_power(struct v4l2_subdev *sd, int on)
-{
- struct i2c_client *client;
- int ret;
-
- if (!on)
- return 0;
-
- client = v4l2_get_subdevdata(sd);
- ret = ov5642_write_array(client, ov5642_default_regs_init);
- if (!ret)
- ret = ov5642_set_resolution(sd);
- if (!ret)
- ret = ov5642_write_array(client, ov5642_default_regs_finalise);
-
- return ret;
-}
-
-static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = {
- .s_mbus_fmt = ov5642_s_fmt,
- .g_mbus_fmt = ov5642_g_fmt,
- .try_mbus_fmt = ov5642_try_fmt,
- .enum_mbus_fmt = ov5642_enum_fmt,
- .s_crop = ov5642_s_crop,
- .g_crop = ov5642_g_crop,
- .cropcap = ov5642_cropcap,
- .g_mbus_config = ov5642_g_mbus_config,
-};
-
-static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = {
- .s_power = ov5642_s_power,
- .g_chip_ident = ov5642_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = ov5642_get_register,
- .s_register = ov5642_set_register,
-#endif
-};
-
-static struct v4l2_subdev_ops ov5642_subdev_ops = {
- .core = &ov5642_subdev_core_ops,
- .video = &ov5642_subdev_video_ops,
-};
-
-static int ov5642_video_probe(struct i2c_client *client)
-{
- int ret;
- u8 id_high, id_low;
- u16 id;
-
- /* Read sensor Model ID */
- ret = reg_read(client, REG_CHIP_ID_HIGH, &id_high);
- if (ret < 0)
- return ret;
-
- id = id_high << 8;
-
- ret = reg_read(client, REG_CHIP_ID_LOW, &id_low);
- if (ret < 0)
- return ret;
-
- id |= id_low;
-
- dev_info(&client->dev, "Chip ID 0x%04x detected\n", id);
-
- if (id != 0x5642)
- return -ENODEV;
-
- return 0;
-}
-
-static int ov5642_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct ov5642 *priv;
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- int ret;
-
- if (!icl) {
- dev_err(&client->dev, "OV5642: missing platform data!\n");
- return -EINVAL;
- }
-
- priv = kzalloc(sizeof(struct ov5642), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- v4l2_i2c_subdev_init(&priv->subdev, client, &ov5642_subdev_ops);
-
- priv->fmt = &ov5642_colour_fmts[0];
-
- priv->crop_rect.width = OV5642_DEFAULT_WIDTH;
- priv->crop_rect.height = OV5642_DEFAULT_HEIGHT;
- priv->crop_rect.left = (OV5642_MAX_WIDTH - OV5642_DEFAULT_WIDTH) / 2;
- priv->crop_rect.top = (OV5642_MAX_HEIGHT - OV5642_DEFAULT_HEIGHT) / 2;
- priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH;
- priv->total_height = BLANKING_MIN_HEIGHT;
-
- ret = ov5642_video_probe(client);
- if (ret < 0)
- goto error;
-
- return 0;
-
-error:
- kfree(priv);
- return ret;
-}
-
-static int ov5642_remove(struct i2c_client *client)
-{
- struct ov5642 *priv = to_ov5642(client);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- if (icl->free_bus)
- icl->free_bus(icl);
- kfree(priv);
-
- return 0;
-}
-
-static const struct i2c_device_id ov5642_id[] = {
- { "ov5642", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ov5642_id);
-
-static struct i2c_driver ov5642_i2c_driver = {
- .driver = {
- .name = "ov5642",
- },
- .probe = ov5642_probe,
- .remove = ov5642_remove,
- .id_table = ov5642_id,
-};
-
-module_i2c_driver(ov5642_i2c_driver);
-
-MODULE_DESCRIPTION("Omnivision OV5642 Camera driver");
-MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c
deleted file mode 100644
index 3e028b1970d..00000000000
--- a/drivers/media/video/ov6650.c
+++ /dev/null
@@ -1,1053 +0,0 @@
-/*
- * V4L2 SoC Camera driver for OmniVision OV6650 Camera Sensor
- *
- * Copyright (C) 2010 Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
- *
- * Based on OmniVision OV96xx Camera Driver
- * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
- *
- * Based on ov772x camera driver:
- * Copyright (C) 2008 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on ov7670 and soc_camera_platform driver,
- * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
- * Copyright (C) 2008 Magnus Damm
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * Hardware specific bits initialy based on former work by Matt Callow
- * drivers/media/video/omap/sensor_ov6650.c
- * Copyright (C) 2006 Matt Callow
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/bitops.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/module.h>
-
-#include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-
-/* Register definitions */
-#define REG_GAIN 0x00 /* range 00 - 3F */
-#define REG_BLUE 0x01
-#define REG_RED 0x02
-#define REG_SAT 0x03 /* [7:4] saturation [0:3] reserved */
-#define REG_HUE 0x04 /* [7:6] rsrvd [5] hue en [4:0] hue */
-
-#define REG_BRT 0x06
-
-#define REG_PIDH 0x0a
-#define REG_PIDL 0x0b
-
-#define REG_AECH 0x10
-#define REG_CLKRC 0x11 /* Data Format and Internal Clock */
- /* [7:6] Input system clock (MHz)*/
- /* 00=8, 01=12, 10=16, 11=24 */
- /* [5:0]: Internal Clock Pre-Scaler */
-#define REG_COMA 0x12 /* [7] Reset */
-#define REG_COMB 0x13
-#define REG_COMC 0x14
-#define REG_COMD 0x15
-#define REG_COML 0x16
-#define REG_HSTRT 0x17
-#define REG_HSTOP 0x18
-#define REG_VSTRT 0x19
-#define REG_VSTOP 0x1a
-#define REG_PSHFT 0x1b
-#define REG_MIDH 0x1c
-#define REG_MIDL 0x1d
-#define REG_HSYNS 0x1e
-#define REG_HSYNE 0x1f
-#define REG_COME 0x20
-#define REG_YOFF 0x21
-#define REG_UOFF 0x22
-#define REG_VOFF 0x23
-#define REG_AEW 0x24
-#define REG_AEB 0x25
-#define REG_COMF 0x26
-#define REG_COMG 0x27
-#define REG_COMH 0x28
-#define REG_COMI 0x29
-
-#define REG_FRARL 0x2b
-#define REG_COMJ 0x2c
-#define REG_COMK 0x2d
-#define REG_AVGY 0x2e
-#define REG_REF0 0x2f
-#define REG_REF1 0x30
-#define REG_REF2 0x31
-#define REG_FRAJH 0x32
-#define REG_FRAJL 0x33
-#define REG_FACT 0x34
-#define REG_L1AEC 0x35
-#define REG_AVGU 0x36
-#define REG_AVGV 0x37
-
-#define REG_SPCB 0x60
-#define REG_SPCC 0x61
-#define REG_GAM1 0x62
-#define REG_GAM2 0x63
-#define REG_GAM3 0x64
-#define REG_SPCD 0x65
-
-#define REG_SPCE 0x68
-#define REG_ADCL 0x69
-
-#define REG_RMCO 0x6c
-#define REG_GMCO 0x6d
-#define REG_BMCO 0x6e
-
-
-/* Register bits, values, etc. */
-#define OV6650_PIDH 0x66 /* high byte of product ID number */
-#define OV6650_PIDL 0x50 /* low byte of product ID number */
-#define OV6650_MIDH 0x7F /* high byte of mfg ID */
-#define OV6650_MIDL 0xA2 /* low byte of mfg ID */
-
-#define DEF_GAIN 0x00
-#define DEF_BLUE 0x80
-#define DEF_RED 0x80
-
-#define SAT_SHIFT 4
-#define SAT_MASK (0xf << SAT_SHIFT)
-#define SET_SAT(x) (((x) << SAT_SHIFT) & SAT_MASK)
-
-#define HUE_EN BIT(5)
-#define HUE_MASK 0x1f
-#define DEF_HUE 0x10
-#define SET_HUE(x) (HUE_EN | ((x) & HUE_MASK))
-
-#define DEF_AECH 0x4D
-
-#define CLKRC_6MHz 0x00
-#define CLKRC_12MHz 0x40
-#define CLKRC_16MHz 0x80
-#define CLKRC_24MHz 0xc0
-#define CLKRC_DIV_MASK 0x3f
-#define GET_CLKRC_DIV(x) (((x) & CLKRC_DIV_MASK) + 1)
-
-#define COMA_RESET BIT(7)
-#define COMA_QCIF BIT(5)
-#define COMA_RAW_RGB BIT(4)
-#define COMA_RGB BIT(3)
-#define COMA_BW BIT(2)
-#define COMA_WORD_SWAP BIT(1)
-#define COMA_BYTE_SWAP BIT(0)
-#define DEF_COMA 0x00
-
-#define COMB_FLIP_V BIT(7)
-#define COMB_FLIP_H BIT(5)
-#define COMB_BAND_FILTER BIT(4)
-#define COMB_AWB BIT(2)
-#define COMB_AGC BIT(1)
-#define COMB_AEC BIT(0)
-#define DEF_COMB 0x5f
-
-#define COML_ONE_CHANNEL BIT(7)
-
-#define DEF_HSTRT 0x24
-#define DEF_HSTOP 0xd4
-#define DEF_VSTRT 0x04
-#define DEF_VSTOP 0x94
-
-#define COMF_HREF_LOW BIT(4)
-
-#define COMJ_PCLK_RISING BIT(4)
-#define COMJ_VSYNC_HIGH BIT(0)
-
-/* supported resolutions */
-#define W_QCIF (DEF_HSTOP - DEF_HSTRT)
-#define W_CIF (W_QCIF << 1)
-#define H_QCIF (DEF_VSTOP - DEF_VSTRT)
-#define H_CIF (H_QCIF << 1)
-
-#define FRAME_RATE_MAX 30
-
-
-struct ov6650_reg {
- u8 reg;
- u8 val;
-};
-
-struct ov6650 {
- struct v4l2_subdev subdev;
- struct v4l2_ctrl_handler hdl;
- struct {
- /* exposure/autoexposure cluster */
- struct v4l2_ctrl *autoexposure;
- struct v4l2_ctrl *exposure;
- };
- struct {
- /* gain/autogain cluster */
- struct v4l2_ctrl *autogain;
- struct v4l2_ctrl *gain;
- };
- struct {
- /* blue/red/autowhitebalance cluster */
- struct v4l2_ctrl *autowb;
- struct v4l2_ctrl *blue;
- struct v4l2_ctrl *red;
- };
- bool half_scale; /* scale down output by 2 */
- struct v4l2_rect rect; /* sensor cropping window */
- unsigned long pclk_limit; /* from host */
- unsigned long pclk_max; /* from resolution and format */
- struct v4l2_fract tpf; /* as requested with s_parm */
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
-};
-
-
-static enum v4l2_mbus_pixelcode ov6650_codes[] = {
- V4L2_MBUS_FMT_YUYV8_2X8,
- V4L2_MBUS_FMT_UYVY8_2X8,
- V4L2_MBUS_FMT_YVYU8_2X8,
- V4L2_MBUS_FMT_VYUY8_2X8,
- V4L2_MBUS_FMT_SBGGR8_1X8,
- V4L2_MBUS_FMT_Y8_1X8,
-};
-
-/* read a register */
-static int ov6650_reg_read(struct i2c_client *client, u8 reg, u8 *val)
-{
- int ret;
- u8 data = reg;
- struct i2c_msg msg = {
- .addr = client->addr,
- .flags = 0,
- .len = 1,
- .buf = &data,
- };
-
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret < 0)
- goto err;
-
- msg.flags = I2C_M_RD;
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret < 0)
- goto err;
-
- *val = data;
- return 0;
-
-err:
- dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg);
- return ret;
-}
-
-/* write a register */
-static int ov6650_reg_write(struct i2c_client *client, u8 reg, u8 val)
-{
- int ret;
- unsigned char data[2] = { reg, val };
- struct i2c_msg msg = {
- .addr = client->addr,
- .flags = 0,
- .len = 2,
- .buf = data,
- };
-
- ret = i2c_transfer(client->adapter, &msg, 1);
- udelay(100);
-
- if (ret < 0) {
- dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg);
- return ret;
- }
- return 0;
-}
-
-
-/* Read a register, alter its bits, write it back */
-static int ov6650_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 mask)
-{
- u8 val;
- int ret;
-
- ret = ov6650_reg_read(client, reg, &val);
- if (ret) {
- dev_err(&client->dev,
- "[Read]-Modify-Write of register 0x%02x failed!\n",
- reg);
- return ret;
- }
-
- val &= ~mask;
- val |= set;
-
- ret = ov6650_reg_write(client, reg, val);
- if (ret)
- dev_err(&client->dev,
- "Read-Modify-[Write] of register 0x%02x failed!\n",
- reg);
-
- return ret;
-}
-
-static struct ov6650 *to_ov6650(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client), struct ov6650, subdev);
-}
-
-/* Start/Stop streaming from the device */
-static int ov6650_s_stream(struct v4l2_subdev *sd, int enable)
-{
- return 0;
-}
-
-/* Get status of additional camera capabilities */
-static int ov6550_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct ov6650 *priv = container_of(ctrl->handler, struct ov6650, hdl);
- struct v4l2_subdev *sd = &priv->subdev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- uint8_t reg, reg2;
- int ret;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTOGAIN:
- ret = ov6650_reg_read(client, REG_GAIN, &reg);
- if (!ret)
- priv->gain->val = reg;
- return ret;
- case V4L2_CID_AUTO_WHITE_BALANCE:
- ret = ov6650_reg_read(client, REG_BLUE, &reg);
- if (!ret)
- ret = ov6650_reg_read(client, REG_RED, &reg2);
- if (!ret) {
- priv->blue->val = reg;
- priv->red->val = reg2;
- }
- return ret;
- case V4L2_CID_EXPOSURE_AUTO:
- ret = ov6650_reg_read(client, REG_AECH, &reg);
- if (!ret)
- priv->exposure->val = reg;
- return ret;
- }
- return -EINVAL;
-}
-
-/* Set status of additional camera capabilities */
-static int ov6550_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct ov6650 *priv = container_of(ctrl->handler, struct ov6650, hdl);
- struct v4l2_subdev *sd = &priv->subdev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTOGAIN:
- ret = ov6650_reg_rmw(client, REG_COMB,
- ctrl->val ? COMB_AGC : 0, COMB_AGC);
- if (!ret && !ctrl->val)
- ret = ov6650_reg_write(client, REG_GAIN, priv->gain->val);
- return ret;
- case V4L2_CID_AUTO_WHITE_BALANCE:
- ret = ov6650_reg_rmw(client, REG_COMB,
- ctrl->val ? COMB_AWB : 0, COMB_AWB);
- if (!ret && !ctrl->val) {
- ret = ov6650_reg_write(client, REG_BLUE, priv->blue->val);
- if (!ret)
- ret = ov6650_reg_write(client, REG_RED,
- priv->red->val);
- }
- return ret;
- case V4L2_CID_SATURATION:
- return ov6650_reg_rmw(client, REG_SAT, SET_SAT(ctrl->val),
- SAT_MASK);
- case V4L2_CID_HUE:
- return ov6650_reg_rmw(client, REG_HUE, SET_HUE(ctrl->val),
- HUE_MASK);
- case V4L2_CID_BRIGHTNESS:
- return ov6650_reg_write(client, REG_BRT, ctrl->val);
- case V4L2_CID_EXPOSURE_AUTO:
- ret = ov6650_reg_rmw(client, REG_COMB, ctrl->val ==
- V4L2_EXPOSURE_AUTO ? COMB_AEC : 0, COMB_AEC);
- if (!ret && ctrl->val == V4L2_EXPOSURE_MANUAL)
- ret = ov6650_reg_write(client, REG_AECH,
- priv->exposure->val);
- return ret;
- case V4L2_CID_GAMMA:
- return ov6650_reg_write(client, REG_GAM1, ctrl->val);
- case V4L2_CID_VFLIP:
- return ov6650_reg_rmw(client, REG_COMB,
- ctrl->val ? COMB_FLIP_V : 0, COMB_FLIP_V);
- case V4L2_CID_HFLIP:
- return ov6650_reg_rmw(client, REG_COMB,
- ctrl->val ? COMB_FLIP_H : 0, COMB_FLIP_H);
- }
-
- return -EINVAL;
-}
-
-/* Get chip identification */
-static int ov6650_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- id->ident = V4L2_IDENT_OV6650;
- id->revision = 0;
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ov6650_get_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
- u8 val;
-
- if (reg->reg & ~0xff)
- return -EINVAL;
-
- reg->size = 1;
-
- ret = ov6650_reg_read(client, reg->reg, &val);
- if (!ret)
- reg->val = (__u64)val;
-
- return ret;
-}
-
-static int ov6650_set_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->reg & ~0xff || reg->val & ~0xff)
- return -EINVAL;
-
- return ov6650_reg_write(client, reg->reg, reg->val);
-}
-#endif
-
-static int ov6650_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
-
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->c = priv->rect;
-
- return 0;
-}
-
-static int ov6650_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
- struct v4l2_rect *rect = &a->c;
- int ret;
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- rect->left = ALIGN(rect->left, 2);
- rect->width = ALIGN(rect->width, 2);
- rect->top = ALIGN(rect->top, 2);
- rect->height = ALIGN(rect->height, 2);
- soc_camera_limit_side(&rect->left, &rect->width,
- DEF_HSTRT << 1, 2, W_CIF);
- soc_camera_limit_side(&rect->top, &rect->height,
- DEF_VSTRT << 1, 2, H_CIF);
-
- ret = ov6650_reg_write(client, REG_HSTRT, rect->left >> 1);
- if (!ret) {
- priv->rect.left = rect->left;
- ret = ov6650_reg_write(client, REG_HSTOP,
- (rect->left + rect->width) >> 1);
- }
- if (!ret) {
- priv->rect.width = rect->width;
- ret = ov6650_reg_write(client, REG_VSTRT, rect->top >> 1);
- }
- if (!ret) {
- priv->rect.top = rect->top;
- ret = ov6650_reg_write(client, REG_VSTOP,
- (rect->top + rect->height) >> 1);
- }
- if (!ret)
- priv->rect.height = rect->height;
-
- return ret;
-}
-
-static int ov6650_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- a->bounds.left = DEF_HSTRT << 1;
- a->bounds.top = DEF_VSTRT << 1;
- a->bounds.width = W_CIF;
- a->bounds.height = H_CIF;
- a->defrect = a->bounds;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int ov6650_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
-
- mf->width = priv->rect.width >> priv->half_scale;
- mf->height = priv->rect.height >> priv->half_scale;
- mf->code = priv->code;
- mf->colorspace = priv->colorspace;
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static bool is_unscaled_ok(int width, int height, struct v4l2_rect *rect)
-{
- return width > rect->width >> 1 || height > rect->height >> 1;
-}
-
-static u8 to_clkrc(struct v4l2_fract *timeperframe,
- unsigned long pclk_limit, unsigned long pclk_max)
-{
- unsigned long pclk;
-
- if (timeperframe->numerator && timeperframe->denominator)
- pclk = pclk_max * timeperframe->denominator /
- (FRAME_RATE_MAX * timeperframe->numerator);
- else
- pclk = pclk_max;
-
- if (pclk_limit && pclk_limit < pclk)
- pclk = pclk_limit;
-
- return (pclk_max - 1) / pclk;
-}
-
-/* set the format we will capture in */
-static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd);
- struct soc_camera_sense *sense = icd->sense;
- struct ov6650 *priv = to_ov6650(client);
- bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect);
- struct v4l2_crop a = {
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- .c = {
- .left = priv->rect.left + (priv->rect.width >> 1) -
- (mf->width >> (1 - half_scale)),
- .top = priv->rect.top + (priv->rect.height >> 1) -
- (mf->height >> (1 - half_scale)),
- .width = mf->width << half_scale,
- .height = mf->height << half_scale,
- },
- };
- enum v4l2_mbus_pixelcode code = mf->code;
- unsigned long mclk, pclk;
- u8 coma_set = 0, coma_mask = 0, coml_set, coml_mask, clkrc;
- int ret;
-
- /* select color matrix configuration for given color encoding */
- switch (code) {
- case V4L2_MBUS_FMT_Y8_1X8:
- dev_dbg(&client->dev, "pixel format GREY8_1X8\n");
- coma_mask |= COMA_RGB | COMA_WORD_SWAP | COMA_BYTE_SWAP;
- coma_set |= COMA_BW;
- break;
- case V4L2_MBUS_FMT_YUYV8_2X8:
- dev_dbg(&client->dev, "pixel format YUYV8_2X8_LE\n");
- coma_mask |= COMA_RGB | COMA_BW | COMA_BYTE_SWAP;
- coma_set |= COMA_WORD_SWAP;
- break;
- case V4L2_MBUS_FMT_YVYU8_2X8:
- dev_dbg(&client->dev, "pixel format YVYU8_2X8_LE (untested)\n");
- coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP |
- COMA_BYTE_SWAP;
- break;
- case V4L2_MBUS_FMT_UYVY8_2X8:
- dev_dbg(&client->dev, "pixel format YUYV8_2X8_BE\n");
- if (half_scale) {
- coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP;
- coma_set |= COMA_BYTE_SWAP;
- } else {
- coma_mask |= COMA_RGB | COMA_BW;
- coma_set |= COMA_BYTE_SWAP | COMA_WORD_SWAP;
- }
- break;
- case V4L2_MBUS_FMT_VYUY8_2X8:
- dev_dbg(&client->dev, "pixel format YVYU8_2X8_BE (untested)\n");
- if (half_scale) {
- coma_mask |= COMA_RGB | COMA_BW;
- coma_set |= COMA_BYTE_SWAP | COMA_WORD_SWAP;
- } else {
- coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP;
- coma_set |= COMA_BYTE_SWAP;
- }
- break;
- case V4L2_MBUS_FMT_SBGGR8_1X8:
- dev_dbg(&client->dev, "pixel format SBGGR8_1X8 (untested)\n");
- coma_mask |= COMA_BW | COMA_BYTE_SWAP | COMA_WORD_SWAP;
- coma_set |= COMA_RAW_RGB | COMA_RGB;
- break;
- default:
- dev_err(&client->dev, "Pixel format not handled: 0x%x\n", code);
- return -EINVAL;
- }
- priv->code = code;
-
- if (code == V4L2_MBUS_FMT_Y8_1X8 ||
- code == V4L2_MBUS_FMT_SBGGR8_1X8) {
- coml_mask = COML_ONE_CHANNEL;
- coml_set = 0;
- priv->pclk_max = 4000000;
- } else {
- coml_mask = 0;
- coml_set = COML_ONE_CHANNEL;
- priv->pclk_max = 8000000;
- }
-
- if (code == V4L2_MBUS_FMT_SBGGR8_1X8)
- priv->colorspace = V4L2_COLORSPACE_SRGB;
- else if (code != 0)
- priv->colorspace = V4L2_COLORSPACE_JPEG;
-
- if (half_scale) {
- dev_dbg(&client->dev, "max resolution: QCIF\n");
- coma_set |= COMA_QCIF;
- priv->pclk_max /= 2;
- } else {
- dev_dbg(&client->dev, "max resolution: CIF\n");
- coma_mask |= COMA_QCIF;
- }
- priv->half_scale = half_scale;
-
- if (sense) {
- if (sense->master_clock == 8000000) {
- dev_dbg(&client->dev, "8MHz input clock\n");
- clkrc = CLKRC_6MHz;
- } else if (sense->master_clock == 12000000) {
- dev_dbg(&client->dev, "12MHz input clock\n");
- clkrc = CLKRC_12MHz;
- } else if (sense->master_clock == 16000000) {
- dev_dbg(&client->dev, "16MHz input clock\n");
- clkrc = CLKRC_16MHz;
- } else if (sense->master_clock == 24000000) {
- dev_dbg(&client->dev, "24MHz input clock\n");
- clkrc = CLKRC_24MHz;
- } else {
- dev_err(&client->dev,
- "unsupported input clock, check platform data\n");
- return -EINVAL;
- }
- mclk = sense->master_clock;
- priv->pclk_limit = sense->pixel_clock_max;
- } else {
- clkrc = CLKRC_24MHz;
- mclk = 24000000;
- priv->pclk_limit = 0;
- dev_dbg(&client->dev, "using default 24MHz input clock\n");
- }
-
- clkrc |= to_clkrc(&priv->tpf, priv->pclk_limit, priv->pclk_max);
-
- pclk = priv->pclk_max / GET_CLKRC_DIV(clkrc);
- dev_dbg(&client->dev, "pixel clock divider: %ld.%ld\n",
- mclk / pclk, 10 * mclk % pclk / pclk);
-
- ret = ov6650_s_crop(sd, &a);
- if (!ret)
- ret = ov6650_reg_rmw(client, REG_COMA, coma_set, coma_mask);
- if (!ret)
- ret = ov6650_reg_write(client, REG_CLKRC, clkrc);
- if (!ret)
- ret = ov6650_reg_rmw(client, REG_COML, coml_set, coml_mask);
-
- if (!ret) {
- mf->colorspace = priv->colorspace;
- mf->width = priv->rect.width >> half_scale;
- mf->height = priv->rect.height >> half_scale;
- }
-
- return ret;
-}
-
-static int ov6650_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
-
- if (is_unscaled_ok(mf->width, mf->height, &priv->rect))
- v4l_bound_align_image(&mf->width, 2, W_CIF, 1,
- &mf->height, 2, H_CIF, 1, 0);
-
- mf->field = V4L2_FIELD_NONE;
-
- switch (mf->code) {
- case V4L2_MBUS_FMT_Y10_1X10:
- mf->code = V4L2_MBUS_FMT_Y8_1X8;
- case V4L2_MBUS_FMT_Y8_1X8:
- case V4L2_MBUS_FMT_YVYU8_2X8:
- case V4L2_MBUS_FMT_YUYV8_2X8:
- case V4L2_MBUS_FMT_VYUY8_2X8:
- case V4L2_MBUS_FMT_UYVY8_2X8:
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- break;
- default:
- mf->code = V4L2_MBUS_FMT_SBGGR8_1X8;
- case V4L2_MBUS_FMT_SBGGR8_1X8:
- mf->colorspace = V4L2_COLORSPACE_SRGB;
- break;
- }
-
- return 0;
-}
-
-static int ov6650_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index >= ARRAY_SIZE(ov6650_codes))
- return -EINVAL;
-
- *code = ov6650_codes[index];
- return 0;
-}
-
-static int ov6650_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
- struct v4l2_captureparm *cp = &parms->parm.capture;
-
- if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- memset(cp, 0, sizeof(*cp));
- cp->capability = V4L2_CAP_TIMEPERFRAME;
- cp->timeperframe.numerator = GET_CLKRC_DIV(to_clkrc(&priv->tpf,
- priv->pclk_limit, priv->pclk_max));
- cp->timeperframe.denominator = FRAME_RATE_MAX;
-
- dev_dbg(&client->dev, "Frame interval: %u/%u s\n",
- cp->timeperframe.numerator, cp->timeperframe.denominator);
-
- return 0;
-}
-
-static int ov6650_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
- struct v4l2_captureparm *cp = &parms->parm.capture;
- struct v4l2_fract *tpf = &cp->timeperframe;
- int div, ret;
- u8 clkrc;
-
- if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (cp->extendedmode != 0)
- return -EINVAL;
-
- if (tpf->numerator == 0 || tpf->denominator == 0)
- div = 1; /* Reset to full rate */
- else
- div = (tpf->numerator * FRAME_RATE_MAX) / tpf->denominator;
-
- if (div == 0)
- div = 1;
- else if (div > GET_CLKRC_DIV(CLKRC_DIV_MASK))
- div = GET_CLKRC_DIV(CLKRC_DIV_MASK);
-
- /*
- * Keep result to be used as tpf limit
- * for subseqent clock divider calculations
- */
- priv->tpf.numerator = div;
- priv->tpf.denominator = FRAME_RATE_MAX;
-
- clkrc = to_clkrc(&priv->tpf, priv->pclk_limit, priv->pclk_max);
-
- ret = ov6650_reg_rmw(client, REG_CLKRC, clkrc, CLKRC_DIV_MASK);
- if (!ret) {
- tpf->numerator = GET_CLKRC_DIV(clkrc);
- tpf->denominator = FRAME_RATE_MAX;
- }
-
- return ret;
-}
-
-/* Soft reset the camera. This has nothing to do with the RESET pin! */
-static int ov6650_reset(struct i2c_client *client)
-{
- int ret;
-
- dev_dbg(&client->dev, "reset\n");
-
- ret = ov6650_reg_rmw(client, REG_COMA, COMA_RESET, 0);
- if (ret)
- dev_err(&client->dev,
- "An error occurred while entering soft reset!\n");
-
- return ret;
-}
-
-/* program default register values */
-static int ov6650_prog_dflt(struct i2c_client *client)
-{
- int ret;
-
- dev_dbg(&client->dev, "initializing\n");
-
- ret = ov6650_reg_write(client, REG_COMA, 0); /* ~COMA_RESET */
- if (!ret)
- ret = ov6650_reg_rmw(client, REG_COMB, 0, COMB_BAND_FILTER);
-
- return ret;
-}
-
-static int ov6650_video_probe(struct i2c_client *client)
-{
- u8 pidh, pidl, midh, midl;
- int ret = 0;
-
- /*
- * check and show product ID and manufacturer ID
- */
- ret = ov6650_reg_read(client, REG_PIDH, &pidh);
- if (!ret)
- ret = ov6650_reg_read(client, REG_PIDL, &pidl);
- if (!ret)
- ret = ov6650_reg_read(client, REG_MIDH, &midh);
- if (!ret)
- ret = ov6650_reg_read(client, REG_MIDL, &midl);
-
- if (ret)
- return ret;
-
- if ((pidh != OV6650_PIDH) || (pidl != OV6650_PIDL)) {
- dev_err(&client->dev, "Product ID error 0x%02x:0x%02x\n",
- pidh, pidl);
- return -ENODEV;
- }
-
- dev_info(&client->dev,
- "ov6650 Product ID 0x%02x:0x%02x Manufacturer ID 0x%02x:0x%02x\n",
- pidh, pidl, midh, midl);
-
- ret = ov6650_reset(client);
- if (!ret)
- ret = ov6650_prog_dflt(client);
-
- return ret;
-}
-
-static const struct v4l2_ctrl_ops ov6550_ctrl_ops = {
- .g_volatile_ctrl = ov6550_g_volatile_ctrl,
- .s_ctrl = ov6550_s_ctrl,
-};
-
-static struct v4l2_subdev_core_ops ov6650_core_ops = {
- .g_chip_ident = ov6650_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = ov6650_get_register,
- .s_register = ov6650_set_register,
-#endif
-};
-
-/* Request bus settings on camera side */
-static int ov6650_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- cfg->flags = V4L2_MBUS_MASTER |
- V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
- V4L2_MBUS_DATA_ACTIVE_HIGH;
- cfg->type = V4L2_MBUS_PARALLEL;
- cfg->flags = soc_camera_apply_board_flags(icl, cfg);
-
- return 0;
-}
-
-/* Alter bus settings on camera side */
-static int ov6650_s_mbus_config(struct v4l2_subdev *sd,
- const struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- unsigned long flags = soc_camera_apply_board_flags(icl, cfg);
- int ret;
-
- if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
- ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0);
- else
- ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING);
- if (ret)
- return ret;
-
- if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
- ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0);
- else
- ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW);
- if (ret)
- return ret;
-
- if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
- ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0);
- else
- ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH);
-
- return ret;
-}
-
-static struct v4l2_subdev_video_ops ov6650_video_ops = {
- .s_stream = ov6650_s_stream,
- .g_mbus_fmt = ov6650_g_fmt,
- .s_mbus_fmt = ov6650_s_fmt,
- .try_mbus_fmt = ov6650_try_fmt,
- .enum_mbus_fmt = ov6650_enum_fmt,
- .cropcap = ov6650_cropcap,
- .g_crop = ov6650_g_crop,
- .s_crop = ov6650_s_crop,
- .g_parm = ov6650_g_parm,
- .s_parm = ov6650_s_parm,
- .g_mbus_config = ov6650_g_mbus_config,
- .s_mbus_config = ov6650_s_mbus_config,
-};
-
-static struct v4l2_subdev_ops ov6650_subdev_ops = {
- .core = &ov6650_core_ops,
- .video = &ov6650_video_ops,
-};
-
-/*
- * i2c_driver function
- */
-static int ov6650_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct ov6650 *priv;
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- int ret;
-
- if (!icl) {
- dev_err(&client->dev, "Missing platform_data for driver\n");
- return -EINVAL;
- }
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&client->dev,
- "Failed to allocate memory for private data!\n");
- return -ENOMEM;
- }
-
- v4l2_i2c_subdev_init(&priv->subdev, client, &ov6650_subdev_ops);
- v4l2_ctrl_handler_init(&priv->hdl, 13);
- v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- priv->autogain = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- priv->gain = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_GAIN, 0, 0x3f, 1, DEF_GAIN);
- priv->autowb = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
- priv->blue = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_BLUE_BALANCE, 0, 0xff, 1, DEF_BLUE);
- priv->red = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_RED_BALANCE, 0, 0xff, 1, DEF_RED);
- v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_SATURATION, 0, 0xf, 1, 0x8);
- v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_HUE, 0, HUE_MASK, 1, DEF_HUE);
- v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 0xff, 1, 0x80);
- priv->autoexposure = v4l2_ctrl_new_std_menu(&priv->hdl,
- &ov6550_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
- V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
- priv->exposure = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 0xff, 1, DEF_AECH);
- v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_GAMMA, 0, 0xff, 1, 0x12);
-
- priv->subdev.ctrl_handler = &priv->hdl;
- if (priv->hdl.error) {
- int err = priv->hdl.error;
-
- kfree(priv);
- return err;
- }
- v4l2_ctrl_auto_cluster(2, &priv->autogain, 0, true);
- v4l2_ctrl_auto_cluster(3, &priv->autowb, 0, true);
- v4l2_ctrl_auto_cluster(2, &priv->autoexposure,
- V4L2_EXPOSURE_MANUAL, true);
-
- priv->rect.left = DEF_HSTRT << 1;
- priv->rect.top = DEF_VSTRT << 1;
- priv->rect.width = W_CIF;
- priv->rect.height = H_CIF;
- priv->half_scale = false;
- priv->code = V4L2_MBUS_FMT_YUYV8_2X8;
- priv->colorspace = V4L2_COLORSPACE_JPEG;
-
- ret = ov6650_video_probe(client);
- if (!ret)
- ret = v4l2_ctrl_handler_setup(&priv->hdl);
-
- if (ret) {
- v4l2_ctrl_handler_free(&priv->hdl);
- kfree(priv);
- }
-
- return ret;
-}
-
-static int ov6650_remove(struct i2c_client *client)
-{
- struct ov6650 *priv = to_ov6650(client);
-
- v4l2_device_unregister_subdev(&priv->subdev);
- v4l2_ctrl_handler_free(&priv->hdl);
- kfree(priv);
- return 0;
-}
-
-static const struct i2c_device_id ov6650_id[] = {
- { "ov6650", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ov6650_id);
-
-static struct i2c_driver ov6650_i2c_driver = {
- .driver = {
- .name = "ov6650",
- },
- .probe = ov6650_probe,
- .remove = ov6650_remove,
- .id_table = ov6650_id,
-};
-
-module_i2c_driver(ov6650_i2c_driver);
-
-MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV6650");
-MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
deleted file mode 100644
index e7c82b29751..00000000000
--- a/drivers/media/video/ov7670.c
+++ /dev/null
@@ -1,1586 +0,0 @@
-/*
- * A V4L2 driver for OmniVision OV7670 cameras.
- *
- * Copyright 2006 One Laptop Per Child Association, Inc. Written
- * by Jonathan Corbet with substantial inspiration from Mark
- * McClelland's ovcamchip code.
- *
- * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
- *
- * This file may be distributed under the terms of the GNU General
- * Public License, version 2.
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-mediabus.h>
-#include <media/ov7670.h>
-
-MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
-MODULE_DESCRIPTION("A low-level driver for OmniVision ov7670 sensors");
-MODULE_LICENSE("GPL");
-
-static bool debug;
-module_param(debug, bool, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-/*
- * Basic window sizes. These probably belong somewhere more globally
- * useful.
- */
-#define VGA_WIDTH 640
-#define VGA_HEIGHT 480
-#define QVGA_WIDTH 320
-#define QVGA_HEIGHT 240
-#define CIF_WIDTH 352
-#define CIF_HEIGHT 288
-#define QCIF_WIDTH 176
-#define QCIF_HEIGHT 144
-
-/*
- * The 7670 sits on i2c with ID 0x42
- */
-#define OV7670_I2C_ADDR 0x42
-
-/* Registers */
-#define REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
-#define REG_BLUE 0x01 /* blue gain */
-#define REG_RED 0x02 /* red gain */
-#define REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
-#define REG_COM1 0x04 /* Control 1 */
-#define COM1_CCIR656 0x40 /* CCIR656 enable */
-#define REG_BAVE 0x05 /* U/B Average level */
-#define REG_GbAVE 0x06 /* Y/Gb Average level */
-#define REG_AECHH 0x07 /* AEC MS 5 bits */
-#define REG_RAVE 0x08 /* V/R Average level */
-#define REG_COM2 0x09 /* Control 2 */
-#define COM2_SSLEEP 0x10 /* Soft sleep mode */
-#define REG_PID 0x0a /* Product ID MSB */
-#define REG_VER 0x0b /* Product ID LSB */
-#define REG_COM3 0x0c /* Control 3 */
-#define COM3_SWAP 0x40 /* Byte swap */
-#define COM3_SCALEEN 0x08 /* Enable scaling */
-#define COM3_DCWEN 0x04 /* Enable downsamp/crop/window */
-#define REG_COM4 0x0d /* Control 4 */
-#define REG_COM5 0x0e /* All "reserved" */
-#define REG_COM6 0x0f /* Control 6 */
-#define REG_AECH 0x10 /* More bits of AEC value */
-#define REG_CLKRC 0x11 /* Clocl control */
-#define CLK_EXT 0x40 /* Use external clock directly */
-#define CLK_SCALE 0x3f /* Mask for internal clock scale */
-#define REG_COM7 0x12 /* Control 7 */
-#define COM7_RESET 0x80 /* Register reset */
-#define COM7_FMT_MASK 0x38
-#define COM7_FMT_VGA 0x00
-#define COM7_FMT_CIF 0x20 /* CIF format */
-#define COM7_FMT_QVGA 0x10 /* QVGA format */
-#define COM7_FMT_QCIF 0x08 /* QCIF format */
-#define COM7_RGB 0x04 /* bits 0 and 2 - RGB format */
-#define COM7_YUV 0x00 /* YUV */
-#define COM7_BAYER 0x01 /* Bayer format */
-#define COM7_PBAYER 0x05 /* "Processed bayer" */
-#define REG_COM8 0x13 /* Control 8 */
-#define COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
-#define COM8_AECSTEP 0x40 /* Unlimited AEC step size */
-#define COM8_BFILT 0x20 /* Band filter enable */
-#define COM8_AGC 0x04 /* Auto gain enable */
-#define COM8_AWB 0x02 /* White balance enable */
-#define COM8_AEC 0x01 /* Auto exposure enable */
-#define REG_COM9 0x14 /* Control 9 - gain ceiling */
-#define REG_COM10 0x15 /* Control 10 */
-#define COM10_HSYNC 0x40 /* HSYNC instead of HREF */
-#define COM10_PCLK_HB 0x20 /* Suppress PCLK on horiz blank */
-#define COM10_HREF_REV 0x08 /* Reverse HREF */
-#define COM10_VS_LEAD 0x04 /* VSYNC on clock leading edge */
-#define COM10_VS_NEG 0x02 /* VSYNC negative */
-#define COM10_HS_NEG 0x01 /* HSYNC negative */
-#define REG_HSTART 0x17 /* Horiz start high bits */
-#define REG_HSTOP 0x18 /* Horiz stop high bits */
-#define REG_VSTART 0x19 /* Vert start high bits */
-#define REG_VSTOP 0x1a /* Vert stop high bits */
-#define REG_PSHFT 0x1b /* Pixel delay after HREF */
-#define REG_MIDH 0x1c /* Manuf. ID high */
-#define REG_MIDL 0x1d /* Manuf. ID low */
-#define REG_MVFP 0x1e /* Mirror / vflip */
-#define MVFP_MIRROR 0x20 /* Mirror image */
-#define MVFP_FLIP 0x10 /* Vertical flip */
-
-#define REG_AEW 0x24 /* AGC upper limit */
-#define REG_AEB 0x25 /* AGC lower limit */
-#define REG_VPT 0x26 /* AGC/AEC fast mode op region */
-#define REG_HSYST 0x30 /* HSYNC rising edge delay */
-#define REG_HSYEN 0x31 /* HSYNC falling edge delay */
-#define REG_HREF 0x32 /* HREF pieces */
-#define REG_TSLB 0x3a /* lots of stuff */
-#define TSLB_YLAST 0x04 /* UYVY or VYUY - see com13 */
-#define REG_COM11 0x3b /* Control 11 */
-#define COM11_NIGHT 0x80 /* NIght mode enable */
-#define COM11_NMFR 0x60 /* Two bit NM frame rate */
-#define COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
-#define COM11_50HZ 0x08 /* Manual 50Hz select */
-#define COM11_EXP 0x02
-#define REG_COM12 0x3c /* Control 12 */
-#define COM12_HREF 0x80 /* HREF always */
-#define REG_COM13 0x3d /* Control 13 */
-#define COM13_GAMMA 0x80 /* Gamma enable */
-#define COM13_UVSAT 0x40 /* UV saturation auto adjustment */
-#define COM13_UVSWAP 0x01 /* V before U - w/TSLB */
-#define REG_COM14 0x3e /* Control 14 */
-#define COM14_DCWEN 0x10 /* DCW/PCLK-scale enable */
-#define REG_EDGE 0x3f /* Edge enhancement factor */
-#define REG_COM15 0x40 /* Control 15 */
-#define COM15_R10F0 0x00 /* Data range 10 to F0 */
-#define COM15_R01FE 0x80 /* 01 to FE */
-#define COM15_R00FF 0xc0 /* 00 to FF */
-#define COM15_RGB565 0x10 /* RGB565 output */
-#define COM15_RGB555 0x30 /* RGB555 output */
-#define REG_COM16 0x41 /* Control 16 */
-#define COM16_AWBGAIN 0x08 /* AWB gain enable */
-#define REG_COM17 0x42 /* Control 17 */
-#define COM17_AECWIN 0xc0 /* AEC window - must match COM4 */
-#define COM17_CBAR 0x08 /* DSP Color bar */
-
-/*
- * This matrix defines how the colors are generated, must be
- * tweaked to adjust hue and saturation.
- *
- * Order: v-red, v-green, v-blue, u-red, u-green, u-blue
- *
- * They are nine-bit signed quantities, with the sign bit
- * stored in 0x58. Sign for v-red is bit 0, and up from there.
- */
-#define REG_CMATRIX_BASE 0x4f
-#define CMATRIX_LEN 6
-#define REG_CMATRIX_SIGN 0x58
-
-
-#define REG_BRIGHT 0x55 /* Brightness */
-#define REG_CONTRAS 0x56 /* Contrast control */
-
-#define REG_GFIX 0x69 /* Fix gain control */
-
-#define REG_REG76 0x76 /* OV's name */
-#define R76_BLKPCOR 0x80 /* Black pixel correction enable */
-#define R76_WHTPCOR 0x40 /* White pixel correction enable */
-
-#define REG_RGB444 0x8c /* RGB 444 control */
-#define R444_ENABLE 0x02 /* Turn on RGB444, overrides 5x5 */
-#define R444_RGBX 0x01 /* Empty nibble at end */
-
-#define REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */
-#define REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
-
-#define REG_BD50MAX 0xa5 /* 50hz banding step limit */
-#define REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
-#define REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
-#define REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
-#define REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
-#define REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
-#define REG_BD60MAX 0xab /* 60hz banding step limit */
-
-
-/*
- * Information we maintain about a known sensor.
- */
-struct ov7670_format_struct; /* coming later */
-struct ov7670_info {
- struct v4l2_subdev sd;
- struct ov7670_format_struct *fmt; /* Current format */
- unsigned char sat; /* Saturation value */
- int hue; /* Hue value */
- int min_width; /* Filter out smaller sizes */
- int min_height; /* Filter out smaller sizes */
- int clock_speed; /* External clock speed (MHz) */
- u8 clkrc; /* Clock divider value */
- bool use_smbus; /* Use smbus I/O instead of I2C */
-};
-
-static inline struct ov7670_info *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct ov7670_info, sd);
-}
-
-
-
-/*
- * The default register settings, as obtained from OmniVision. There
- * is really no making sense of most of these - lots of "reserved" values
- * and such.
- *
- * These settings give VGA YUYV.
- */
-
-struct regval_list {
- unsigned char reg_num;
- unsigned char value;
-};
-
-static struct regval_list ov7670_default_regs[] = {
- { REG_COM7, COM7_RESET },
-/*
- * Clock scale: 3 = 15fps
- * 2 = 20fps
- * 1 = 30fps
- */
- { REG_CLKRC, 0x1 }, /* OV: clock scale (30 fps) */
- { REG_TSLB, 0x04 }, /* OV */
- { REG_COM7, 0 }, /* VGA */
- /*
- * Set the hardware window. These values from OV don't entirely
- * make sense - hstop is less than hstart. But they work...
- */
- { REG_HSTART, 0x13 }, { REG_HSTOP, 0x01 },
- { REG_HREF, 0xb6 }, { REG_VSTART, 0x02 },
- { REG_VSTOP, 0x7a }, { REG_VREF, 0x0a },
-
- { REG_COM3, 0 }, { REG_COM14, 0 },
- /* Mystery scaling numbers */
- { 0x70, 0x3a }, { 0x71, 0x35 },
- { 0x72, 0x11 }, { 0x73, 0xf0 },
- { 0xa2, 0x02 }, { REG_COM10, 0x0 },
-
- /* Gamma curve values */
- { 0x7a, 0x20 }, { 0x7b, 0x10 },
- { 0x7c, 0x1e }, { 0x7d, 0x35 },
- { 0x7e, 0x5a }, { 0x7f, 0x69 },
- { 0x80, 0x76 }, { 0x81, 0x80 },
- { 0x82, 0x88 }, { 0x83, 0x8f },
- { 0x84, 0x96 }, { 0x85, 0xa3 },
- { 0x86, 0xaf }, { 0x87, 0xc4 },
- { 0x88, 0xd7 }, { 0x89, 0xe8 },
-
- /* AGC and AEC parameters. Note we start by disabling those features,
- then turn them only after tweaking the values. */
- { REG_COM8, COM8_FASTAEC | COM8_AECSTEP | COM8_BFILT },
- { REG_GAIN, 0 }, { REG_AECH, 0 },
- { REG_COM4, 0x40 }, /* magic reserved bit */
- { REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
- { REG_BD50MAX, 0x05 }, { REG_BD60MAX, 0x07 },
- { REG_AEW, 0x95 }, { REG_AEB, 0x33 },
- { REG_VPT, 0xe3 }, { REG_HAECC1, 0x78 },
- { REG_HAECC2, 0x68 }, { 0xa1, 0x03 }, /* magic */
- { REG_HAECC3, 0xd8 }, { REG_HAECC4, 0xd8 },
- { REG_HAECC5, 0xf0 }, { REG_HAECC6, 0x90 },
- { REG_HAECC7, 0x94 },
- { REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC },
-
- /* Almost all of these are magic "reserved" values. */
- { REG_COM5, 0x61 }, { REG_COM6, 0x4b },
- { 0x16, 0x02 }, { REG_MVFP, 0x07 },
- { 0x21, 0x02 }, { 0x22, 0x91 },
- { 0x29, 0x07 }, { 0x33, 0x0b },
- { 0x35, 0x0b }, { 0x37, 0x1d },
- { 0x38, 0x71 }, { 0x39, 0x2a },
- { REG_COM12, 0x78 }, { 0x4d, 0x40 },
- { 0x4e, 0x20 }, { REG_GFIX, 0 },
- { 0x6b, 0x4a }, { 0x74, 0x10 },
- { 0x8d, 0x4f }, { 0x8e, 0 },
- { 0x8f, 0 }, { 0x90, 0 },
- { 0x91, 0 }, { 0x96, 0 },
- { 0x9a, 0 }, { 0xb0, 0x84 },
- { 0xb1, 0x0c }, { 0xb2, 0x0e },
- { 0xb3, 0x82 }, { 0xb8, 0x0a },
-
- /* More reserved magic, some of which tweaks white balance */
- { 0x43, 0x0a }, { 0x44, 0xf0 },
- { 0x45, 0x34 }, { 0x46, 0x58 },
- { 0x47, 0x28 }, { 0x48, 0x3a },
- { 0x59, 0x88 }, { 0x5a, 0x88 },
- { 0x5b, 0x44 }, { 0x5c, 0x67 },
- { 0x5d, 0x49 }, { 0x5e, 0x0e },
- { 0x6c, 0x0a }, { 0x6d, 0x55 },
- { 0x6e, 0x11 }, { 0x6f, 0x9f }, /* "9e for advance AWB" */
- { 0x6a, 0x40 }, { REG_BLUE, 0x40 },
- { REG_RED, 0x60 },
- { REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC|COM8_AWB },
-
- /* Matrix coefficients */
- { 0x4f, 0x80 }, { 0x50, 0x80 },
- { 0x51, 0 }, { 0x52, 0x22 },
- { 0x53, 0x5e }, { 0x54, 0x80 },
- { 0x58, 0x9e },
-
- { REG_COM16, COM16_AWBGAIN }, { REG_EDGE, 0 },
- { 0x75, 0x05 }, { 0x76, 0xe1 },
- { 0x4c, 0 }, { 0x77, 0x01 },
- { REG_COM13, 0xc3 }, { 0x4b, 0x09 },
- { 0xc9, 0x60 }, { REG_COM16, 0x38 },
- { 0x56, 0x40 },
-
- { 0x34, 0x11 }, { REG_COM11, COM11_EXP|COM11_HZAUTO },
- { 0xa4, 0x88 }, { 0x96, 0 },
- { 0x97, 0x30 }, { 0x98, 0x20 },
- { 0x99, 0x30 }, { 0x9a, 0x84 },
- { 0x9b, 0x29 }, { 0x9c, 0x03 },
- { 0x9d, 0x4c }, { 0x9e, 0x3f },
- { 0x78, 0x04 },
-
- /* Extra-weird stuff. Some sort of multiplexor register */
- { 0x79, 0x01 }, { 0xc8, 0xf0 },
- { 0x79, 0x0f }, { 0xc8, 0x00 },
- { 0x79, 0x10 }, { 0xc8, 0x7e },
- { 0x79, 0x0a }, { 0xc8, 0x80 },
- { 0x79, 0x0b }, { 0xc8, 0x01 },
- { 0x79, 0x0c }, { 0xc8, 0x0f },
- { 0x79, 0x0d }, { 0xc8, 0x20 },
- { 0x79, 0x09 }, { 0xc8, 0x80 },
- { 0x79, 0x02 }, { 0xc8, 0xc0 },
- { 0x79, 0x03 }, { 0xc8, 0x40 },
- { 0x79, 0x05 }, { 0xc8, 0x30 },
- { 0x79, 0x26 },
-
- { 0xff, 0xff }, /* END MARKER */
-};
-
-
-/*
- * Here we'll try to encapsulate the changes for just the output
- * video format.
- *
- * RGB656 and YUV422 come from OV; RGB444 is homebrewed.
- *
- * IMPORTANT RULE: the first entry must be for COM7, see ov7670_s_fmt for why.
- */
-
-
-static struct regval_list ov7670_fmt_yuv422[] = {
- { REG_COM7, 0x0 }, /* Selects YUV mode */
- { REG_RGB444, 0 }, /* No RGB444 please */
- { REG_COM1, 0 }, /* CCIR601 */
- { REG_COM15, COM15_R00FF },
- { REG_COM9, 0x18 }, /* 4x gain ceiling; 0x8 is reserved bit */
- { 0x4f, 0x80 }, /* "matrix coefficient 1" */
- { 0x50, 0x80 }, /* "matrix coefficient 2" */
- { 0x51, 0 }, /* vb */
- { 0x52, 0x22 }, /* "matrix coefficient 4" */
- { 0x53, 0x5e }, /* "matrix coefficient 5" */
- { 0x54, 0x80 }, /* "matrix coefficient 6" */
- { REG_COM13, COM13_GAMMA|COM13_UVSAT },
- { 0xff, 0xff },
-};
-
-static struct regval_list ov7670_fmt_rgb565[] = {
- { REG_COM7, COM7_RGB }, /* Selects RGB mode */
- { REG_RGB444, 0 }, /* No RGB444 please */
- { REG_COM1, 0x0 }, /* CCIR601 */
- { REG_COM15, COM15_RGB565 },
- { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */
- { 0x4f, 0xb3 }, /* "matrix coefficient 1" */
- { 0x50, 0xb3 }, /* "matrix coefficient 2" */
- { 0x51, 0 }, /* vb */
- { 0x52, 0x3d }, /* "matrix coefficient 4" */
- { 0x53, 0xa7 }, /* "matrix coefficient 5" */
- { 0x54, 0xe4 }, /* "matrix coefficient 6" */
- { REG_COM13, COM13_GAMMA|COM13_UVSAT },
- { 0xff, 0xff },
-};
-
-static struct regval_list ov7670_fmt_rgb444[] = {
- { REG_COM7, COM7_RGB }, /* Selects RGB mode */
- { REG_RGB444, R444_ENABLE }, /* Enable xxxxrrrr ggggbbbb */
- { REG_COM1, 0x0 }, /* CCIR601 */
- { REG_COM15, COM15_R01FE|COM15_RGB565 }, /* Data range needed? */
- { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */
- { 0x4f, 0xb3 }, /* "matrix coefficient 1" */
- { 0x50, 0xb3 }, /* "matrix coefficient 2" */
- { 0x51, 0 }, /* vb */
- { 0x52, 0x3d }, /* "matrix coefficient 4" */
- { 0x53, 0xa7 }, /* "matrix coefficient 5" */
- { 0x54, 0xe4 }, /* "matrix coefficient 6" */
- { REG_COM13, COM13_GAMMA|COM13_UVSAT|0x2 }, /* Magic rsvd bit */
- { 0xff, 0xff },
-};
-
-static struct regval_list ov7670_fmt_raw[] = {
- { REG_COM7, COM7_BAYER },
- { REG_COM13, 0x08 }, /* No gamma, magic rsvd bit */
- { REG_COM16, 0x3d }, /* Edge enhancement, denoise */
- { REG_REG76, 0xe1 }, /* Pix correction, magic rsvd */
- { 0xff, 0xff },
-};
-
-
-
-/*
- * Low-level register I/O.
- *
- * Note that there are two versions of these. On the XO 1, the
- * i2c controller only does SMBUS, so that's what we use. The
- * ov7670 is not really an SMBUS device, though, so the communication
- * is not always entirely reliable.
- */
-static int ov7670_read_smbus(struct v4l2_subdev *sd, unsigned char reg,
- unsigned char *value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
-
- ret = i2c_smbus_read_byte_data(client, reg);
- if (ret >= 0) {
- *value = (unsigned char)ret;
- ret = 0;
- }
- return ret;
-}
-
-
-static int ov7670_write_smbus(struct v4l2_subdev *sd, unsigned char reg,
- unsigned char value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret = i2c_smbus_write_byte_data(client, reg, value);
-
- if (reg == REG_COM7 && (value & COM7_RESET))
- msleep(5); /* Wait for reset to run */
- return ret;
-}
-
-/*
- * On most platforms, we'd rather do straight i2c I/O.
- */
-static int ov7670_read_i2c(struct v4l2_subdev *sd, unsigned char reg,
- unsigned char *value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 data = reg;
- struct i2c_msg msg;
- int ret;
-
- /*
- * Send out the register address...
- */
- msg.addr = client->addr;
- msg.flags = 0;
- msg.len = 1;
- msg.buf = &data;
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret < 0) {
- printk(KERN_ERR "Error %d on register write\n", ret);
- return ret;
- }
- /*
- * ...then read back the result.
- */
- msg.flags = I2C_M_RD;
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret >= 0) {
- *value = data;
- ret = 0;
- }
- return ret;
-}
-
-
-static int ov7670_write_i2c(struct v4l2_subdev *sd, unsigned char reg,
- unsigned char value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct i2c_msg msg;
- unsigned char data[2] = { reg, value };
- int ret;
-
- msg.addr = client->addr;
- msg.flags = 0;
- msg.len = 2;
- msg.buf = data;
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret > 0)
- ret = 0;
- if (reg == REG_COM7 && (value & COM7_RESET))
- msleep(5); /* Wait for reset to run */
- return ret;
-}
-
-static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg,
- unsigned char *value)
-{
- struct ov7670_info *info = to_state(sd);
- if (info->use_smbus)
- return ov7670_read_smbus(sd, reg, value);
- else
- return ov7670_read_i2c(sd, reg, value);
-}
-
-static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg,
- unsigned char value)
-{
- struct ov7670_info *info = to_state(sd);
- if (info->use_smbus)
- return ov7670_write_smbus(sd, reg, value);
- else
- return ov7670_write_i2c(sd, reg, value);
-}
-
-/*
- * Write a list of register settings; ff/ff stops the process.
- */
-static int ov7670_write_array(struct v4l2_subdev *sd, struct regval_list *vals)
-{
- while (vals->reg_num != 0xff || vals->value != 0xff) {
- int ret = ov7670_write(sd, vals->reg_num, vals->value);
- if (ret < 0)
- return ret;
- vals++;
- }
- return 0;
-}
-
-
-/*
- * Stuff that knows about the sensor.
- */
-static int ov7670_reset(struct v4l2_subdev *sd, u32 val)
-{
- ov7670_write(sd, REG_COM7, COM7_RESET);
- msleep(1);
- return 0;
-}
-
-
-static int ov7670_init(struct v4l2_subdev *sd, u32 val)
-{
- return ov7670_write_array(sd, ov7670_default_regs);
-}
-
-
-
-static int ov7670_detect(struct v4l2_subdev *sd)
-{
- unsigned char v;
- int ret;
-
- ret = ov7670_init(sd, 0);
- if (ret < 0)
- return ret;
- ret = ov7670_read(sd, REG_MIDH, &v);
- if (ret < 0)
- return ret;
- if (v != 0x7f) /* OV manuf. id. */
- return -ENODEV;
- ret = ov7670_read(sd, REG_MIDL, &v);
- if (ret < 0)
- return ret;
- if (v != 0xa2)
- return -ENODEV;
- /*
- * OK, we know we have an OmniVision chip...but which one?
- */
- ret = ov7670_read(sd, REG_PID, &v);
- if (ret < 0)
- return ret;
- if (v != 0x76) /* PID + VER = 0x76 / 0x73 */
- return -ENODEV;
- ret = ov7670_read(sd, REG_VER, &v);
- if (ret < 0)
- return ret;
- if (v != 0x73) /* PID + VER = 0x76 / 0x73 */
- return -ENODEV;
- return 0;
-}
-
-
-/*
- * Store information about the video data format. The color matrix
- * is deeply tied into the format, so keep the relevant values here.
- * The magic matrix numbers come from OmniVision.
- */
-static struct ov7670_format_struct {
- enum v4l2_mbus_pixelcode mbus_code;
- enum v4l2_colorspace colorspace;
- struct regval_list *regs;
- int cmatrix[CMATRIX_LEN];
-} ov7670_formats[] = {
- {
- .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .regs = ov7670_fmt_yuv422,
- .cmatrix = { 128, -128, 0, -34, -94, 128 },
- },
- {
- .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .regs = ov7670_fmt_rgb444,
- .cmatrix = { 179, -179, 0, -61, -176, 228 },
- },
- {
- .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .regs = ov7670_fmt_rgb565,
- .cmatrix = { 179, -179, 0, -61, -176, 228 },
- },
- {
- .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .regs = ov7670_fmt_raw,
- .cmatrix = { 0, 0, 0, 0, 0, 0 },
- },
-};
-#define N_OV7670_FMTS ARRAY_SIZE(ov7670_formats)
-
-
-/*
- * Then there is the issue of window sizes. Try to capture the info here.
- */
-
-/*
- * QCIF mode is done (by OV) in a very strange way - it actually looks like
- * VGA with weird scaling options - they do *not* use the canned QCIF mode
- * which is allegedly provided by the sensor. So here's the weird register
- * settings.
- */
-static struct regval_list ov7670_qcif_regs[] = {
- { REG_COM3, COM3_SCALEEN|COM3_DCWEN },
- { REG_COM3, COM3_DCWEN },
- { REG_COM14, COM14_DCWEN | 0x01},
- { 0x73, 0xf1 },
- { 0xa2, 0x52 },
- { 0x7b, 0x1c },
- { 0x7c, 0x28 },
- { 0x7d, 0x3c },
- { 0x7f, 0x69 },
- { REG_COM9, 0x38 },
- { 0xa1, 0x0b },
- { 0x74, 0x19 },
- { 0x9a, 0x80 },
- { 0x43, 0x14 },
- { REG_COM13, 0xc0 },
- { 0xff, 0xff },
-};
-
-static struct ov7670_win_size {
- int width;
- int height;
- unsigned char com7_bit;
- int hstart; /* Start/stop values for the camera. Note */
- int hstop; /* that they do not always make complete */
- int vstart; /* sense to humans, but evidently the sensor */
- int vstop; /* will do the right thing... */
- struct regval_list *regs; /* Regs to tweak */
-/* h/vref stuff */
-} ov7670_win_sizes[] = {
- /* VGA */
- {
- .width = VGA_WIDTH,
- .height = VGA_HEIGHT,
- .com7_bit = COM7_FMT_VGA,
- .hstart = 158, /* These values from */
- .hstop = 14, /* Omnivision */
- .vstart = 10,
- .vstop = 490,
- .regs = NULL,
- },
- /* CIF */
- {
- .width = CIF_WIDTH,
- .height = CIF_HEIGHT,
- .com7_bit = COM7_FMT_CIF,
- .hstart = 170, /* Empirically determined */
- .hstop = 90,
- .vstart = 14,
- .vstop = 494,
- .regs = NULL,
- },
- /* QVGA */
- {
- .width = QVGA_WIDTH,
- .height = QVGA_HEIGHT,
- .com7_bit = COM7_FMT_QVGA,
- .hstart = 168, /* Empirically determined */
- .hstop = 24,
- .vstart = 12,
- .vstop = 492,
- .regs = NULL,
- },
- /* QCIF */
- {
- .width = QCIF_WIDTH,
- .height = QCIF_HEIGHT,
- .com7_bit = COM7_FMT_VGA, /* see comment above */
- .hstart = 456, /* Empirically determined */
- .hstop = 24,
- .vstart = 14,
- .vstop = 494,
- .regs = ov7670_qcif_regs,
- },
-};
-
-#define N_WIN_SIZES (ARRAY_SIZE(ov7670_win_sizes))
-
-
-/*
- * Store a set of start/stop values into the camera.
- */
-static int ov7670_set_hw(struct v4l2_subdev *sd, int hstart, int hstop,
- int vstart, int vstop)
-{
- int ret;
- unsigned char v;
-/*
- * Horizontal: 11 bits, top 8 live in hstart and hstop. Bottom 3 of
- * hstart are in href[2:0], bottom 3 of hstop in href[5:3]. There is
- * a mystery "edge offset" value in the top two bits of href.
- */
- ret = ov7670_write(sd, REG_HSTART, (hstart >> 3) & 0xff);
- ret += ov7670_write(sd, REG_HSTOP, (hstop >> 3) & 0xff);
- ret += ov7670_read(sd, REG_HREF, &v);
- v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x7);
- msleep(10);
- ret += ov7670_write(sd, REG_HREF, v);
-/*
- * Vertical: similar arrangement, but only 10 bits.
- */
- ret += ov7670_write(sd, REG_VSTART, (vstart >> 2) & 0xff);
- ret += ov7670_write(sd, REG_VSTOP, (vstop >> 2) & 0xff);
- ret += ov7670_read(sd, REG_VREF, &v);
- v = (v & 0xf0) | ((vstop & 0x3) << 2) | (vstart & 0x3);
- msleep(10);
- ret += ov7670_write(sd, REG_VREF, v);
- return ret;
-}
-
-
-static int ov7670_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index >= N_OV7670_FMTS)
- return -EINVAL;
-
- *code = ov7670_formats[index].mbus_code;
- return 0;
-}
-
-static int ov7670_try_fmt_internal(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *fmt,
- struct ov7670_format_struct **ret_fmt,
- struct ov7670_win_size **ret_wsize)
-{
- int index;
- struct ov7670_win_size *wsize;
-
- for (index = 0; index < N_OV7670_FMTS; index++)
- if (ov7670_formats[index].mbus_code == fmt->code)
- break;
- if (index >= N_OV7670_FMTS) {
- /* default to first format */
- index = 0;
- fmt->code = ov7670_formats[0].mbus_code;
- }
- if (ret_fmt != NULL)
- *ret_fmt = ov7670_formats + index;
- /*
- * Fields: the OV devices claim to be progressive.
- */
- fmt->field = V4L2_FIELD_NONE;
- /*
- * Round requested image size down to the nearest
- * we support, but not below the smallest.
- */
- for (wsize = ov7670_win_sizes; wsize < ov7670_win_sizes + N_WIN_SIZES;
- wsize++)
- if (fmt->width >= wsize->width && fmt->height >= wsize->height)
- break;
- if (wsize >= ov7670_win_sizes + N_WIN_SIZES)
- wsize--; /* Take the smallest one */
- if (ret_wsize != NULL)
- *ret_wsize = wsize;
- /*
- * Note the size we'll actually handle.
- */
- fmt->width = wsize->width;
- fmt->height = wsize->height;
- fmt->colorspace = ov7670_formats[index].colorspace;
- return 0;
-}
-
-static int ov7670_try_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *fmt)
-{
- return ov7670_try_fmt_internal(sd, fmt, NULL, NULL);
-}
-
-/*
- * Set a format.
- */
-static int ov7670_s_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *fmt)
-{
- struct ov7670_format_struct *ovfmt;
- struct ov7670_win_size *wsize;
- struct ov7670_info *info = to_state(sd);
- unsigned char com7;
- int ret;
-
- ret = ov7670_try_fmt_internal(sd, fmt, &ovfmt, &wsize);
-
- if (ret)
- return ret;
- /*
- * COM7 is a pain in the ass, it doesn't like to be read then
- * quickly written afterward. But we have everything we need
- * to set it absolutely here, as long as the format-specific
- * register sets list it first.
- */
- com7 = ovfmt->regs[0].value;
- com7 |= wsize->com7_bit;
- ov7670_write(sd, REG_COM7, com7);
- /*
- * Now write the rest of the array. Also store start/stops
- */
- ov7670_write_array(sd, ovfmt->regs + 1);
- ov7670_set_hw(sd, wsize->hstart, wsize->hstop, wsize->vstart,
- wsize->vstop);
- ret = 0;
- if (wsize->regs)
- ret = ov7670_write_array(sd, wsize->regs);
- info->fmt = ovfmt;
-
- /*
- * If we're running RGB565, we must rewrite clkrc after setting
- * the other parameters or the image looks poor. If we're *not*
- * doing RGB565, we must not rewrite clkrc or the image looks
- * *really* poor.
- *
- * (Update) Now that we retain clkrc state, we should be able
- * to write it unconditionally, and that will make the frame
- * rate persistent too.
- */
- if (ret == 0)
- ret = ov7670_write(sd, REG_CLKRC, info->clkrc);
- return 0;
-}
-
-/*
- * Implement G/S_PARM. There is a "high quality" mode we could try
- * to do someday; for now, we just do the frame rate tweak.
- */
-static int ov7670_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
-{
- struct v4l2_captureparm *cp = &parms->parm.capture;
- struct ov7670_info *info = to_state(sd);
-
- if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- memset(cp, 0, sizeof(struct v4l2_captureparm));
- cp->capability = V4L2_CAP_TIMEPERFRAME;
- cp->timeperframe.numerator = 1;
- cp->timeperframe.denominator = info->clock_speed;
- if ((info->clkrc & CLK_EXT) == 0 && (info->clkrc & CLK_SCALE) > 1)
- cp->timeperframe.denominator /= (info->clkrc & CLK_SCALE);
- return 0;
-}
-
-static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
-{
- struct v4l2_captureparm *cp = &parms->parm.capture;
- struct v4l2_fract *tpf = &cp->timeperframe;
- struct ov7670_info *info = to_state(sd);
- int div;
-
- if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (cp->extendedmode != 0)
- return -EINVAL;
-
- if (tpf->numerator == 0 || tpf->denominator == 0)
- div = 1; /* Reset to full rate */
- else
- div = (tpf->numerator * info->clock_speed) / tpf->denominator;
- if (div == 0)
- div = 1;
- else if (div > CLK_SCALE)
- div = CLK_SCALE;
- info->clkrc = (info->clkrc & 0x80) | div;
- tpf->numerator = 1;
- tpf->denominator = info->clock_speed / div;
- return ov7670_write(sd, REG_CLKRC, info->clkrc);
-}
-
-
-/*
- * Frame intervals. Since frame rates are controlled with the clock
- * divider, we can only do 30/n for integer n values. So no continuous
- * or stepwise options. Here we just pick a handful of logical values.
- */
-
-static int ov7670_frame_rates[] = { 30, 15, 10, 5, 1 };
-
-static int ov7670_enum_frameintervals(struct v4l2_subdev *sd,
- struct v4l2_frmivalenum *interval)
-{
- if (interval->index >= ARRAY_SIZE(ov7670_frame_rates))
- return -EINVAL;
- interval->type = V4L2_FRMIVAL_TYPE_DISCRETE;
- interval->discrete.numerator = 1;
- interval->discrete.denominator = ov7670_frame_rates[interval->index];
- return 0;
-}
-
-/*
- * Frame size enumeration
- */
-static int ov7670_enum_framesizes(struct v4l2_subdev *sd,
- struct v4l2_frmsizeenum *fsize)
-{
- struct ov7670_info *info = to_state(sd);
- int i;
- int num_valid = -1;
- __u32 index = fsize->index;
-
- /*
- * If a minimum width/height was requested, filter out the capture
- * windows that fall outside that.
- */
- for (i = 0; i < N_WIN_SIZES; i++) {
- struct ov7670_win_size *win = &ov7670_win_sizes[index];
- if (info->min_width && win->width < info->min_width)
- continue;
- if (info->min_height && win->height < info->min_height)
- continue;
- if (index == ++num_valid) {
- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fsize->discrete.width = win->width;
- fsize->discrete.height = win->height;
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-/*
- * Code for dealing with controls.
- */
-
-static int ov7670_store_cmatrix(struct v4l2_subdev *sd,
- int matrix[CMATRIX_LEN])
-{
- int i, ret;
- unsigned char signbits = 0;
-
- /*
- * Weird crap seems to exist in the upper part of
- * the sign bits register, so let's preserve it.
- */
- ret = ov7670_read(sd, REG_CMATRIX_SIGN, &signbits);
- signbits &= 0xc0;
-
- for (i = 0; i < CMATRIX_LEN; i++) {
- unsigned char raw;
-
- if (matrix[i] < 0) {
- signbits |= (1 << i);
- if (matrix[i] < -255)
- raw = 0xff;
- else
- raw = (-1 * matrix[i]) & 0xff;
- }
- else {
- if (matrix[i] > 255)
- raw = 0xff;
- else
- raw = matrix[i] & 0xff;
- }
- ret += ov7670_write(sd, REG_CMATRIX_BASE + i, raw);
- }
- ret += ov7670_write(sd, REG_CMATRIX_SIGN, signbits);
- return ret;
-}
-
-
-/*
- * Hue also requires messing with the color matrix. It also requires
- * trig functions, which tend not to be well supported in the kernel.
- * So here is a simple table of sine values, 0-90 degrees, in steps
- * of five degrees. Values are multiplied by 1000.
- *
- * The following naive approximate trig functions require an argument
- * carefully limited to -180 <= theta <= 180.
- */
-#define SIN_STEP 5
-static const int ov7670_sin_table[] = {
- 0, 87, 173, 258, 342, 422,
- 499, 573, 642, 707, 766, 819,
- 866, 906, 939, 965, 984, 996,
- 1000
-};
-
-static int ov7670_sine(int theta)
-{
- int chs = 1;
- int sine;
-
- if (theta < 0) {
- theta = -theta;
- chs = -1;
- }
- if (theta <= 90)
- sine = ov7670_sin_table[theta/SIN_STEP];
- else {
- theta -= 90;
- sine = 1000 - ov7670_sin_table[theta/SIN_STEP];
- }
- return sine*chs;
-}
-
-static int ov7670_cosine(int theta)
-{
- theta = 90 - theta;
- if (theta > 180)
- theta -= 360;
- else if (theta < -180)
- theta += 360;
- return ov7670_sine(theta);
-}
-
-
-
-
-static void ov7670_calc_cmatrix(struct ov7670_info *info,
- int matrix[CMATRIX_LEN])
-{
- int i;
- /*
- * Apply the current saturation setting first.
- */
- for (i = 0; i < CMATRIX_LEN; i++)
- matrix[i] = (info->fmt->cmatrix[i]*info->sat) >> 7;
- /*
- * Then, if need be, rotate the hue value.
- */
- if (info->hue != 0) {
- int sinth, costh, tmpmatrix[CMATRIX_LEN];
-
- memcpy(tmpmatrix, matrix, CMATRIX_LEN*sizeof(int));
- sinth = ov7670_sine(info->hue);
- costh = ov7670_cosine(info->hue);
-
- matrix[0] = (matrix[3]*sinth + matrix[0]*costh)/1000;
- matrix[1] = (matrix[4]*sinth + matrix[1]*costh)/1000;
- matrix[2] = (matrix[5]*sinth + matrix[2]*costh)/1000;
- matrix[3] = (matrix[3]*costh - matrix[0]*sinth)/1000;
- matrix[4] = (matrix[4]*costh - matrix[1]*sinth)/1000;
- matrix[5] = (matrix[5]*costh - matrix[2]*sinth)/1000;
- }
-}
-
-
-
-static int ov7670_s_sat(struct v4l2_subdev *sd, int value)
-{
- struct ov7670_info *info = to_state(sd);
- int matrix[CMATRIX_LEN];
- int ret;
-
- info->sat = value;
- ov7670_calc_cmatrix(info, matrix);
- ret = ov7670_store_cmatrix(sd, matrix);
- return ret;
-}
-
-static int ov7670_g_sat(struct v4l2_subdev *sd, __s32 *value)
-{
- struct ov7670_info *info = to_state(sd);
-
- *value = info->sat;
- return 0;
-}
-
-static int ov7670_s_hue(struct v4l2_subdev *sd, int value)
-{
- struct ov7670_info *info = to_state(sd);
- int matrix[CMATRIX_LEN];
- int ret;
-
- if (value < -180 || value > 180)
- return -EINVAL;
- info->hue = value;
- ov7670_calc_cmatrix(info, matrix);
- ret = ov7670_store_cmatrix(sd, matrix);
- return ret;
-}
-
-
-static int ov7670_g_hue(struct v4l2_subdev *sd, __s32 *value)
-{
- struct ov7670_info *info = to_state(sd);
-
- *value = info->hue;
- return 0;
-}
-
-
-/*
- * Some weird registers seem to store values in a sign/magnitude format!
- */
-static unsigned char ov7670_sm_to_abs(unsigned char v)
-{
- if ((v & 0x80) == 0)
- return v + 128;
- return 128 - (v & 0x7f);
-}
-
-
-static unsigned char ov7670_abs_to_sm(unsigned char v)
-{
- if (v > 127)
- return v & 0x7f;
- return (128 - v) | 0x80;
-}
-
-static int ov7670_s_brightness(struct v4l2_subdev *sd, int value)
-{
- unsigned char com8 = 0, v;
- int ret;
-
- ov7670_read(sd, REG_COM8, &com8);
- com8 &= ~COM8_AEC;
- ov7670_write(sd, REG_COM8, com8);
- v = ov7670_abs_to_sm(value);
- ret = ov7670_write(sd, REG_BRIGHT, v);
- return ret;
-}
-
-static int ov7670_g_brightness(struct v4l2_subdev *sd, __s32 *value)
-{
- unsigned char v = 0;
- int ret = ov7670_read(sd, REG_BRIGHT, &v);
-
- *value = ov7670_sm_to_abs(v);
- return ret;
-}
-
-static int ov7670_s_contrast(struct v4l2_subdev *sd, int value)
-{
- return ov7670_write(sd, REG_CONTRAS, (unsigned char) value);
-}
-
-static int ov7670_g_contrast(struct v4l2_subdev *sd, __s32 *value)
-{
- unsigned char v = 0;
- int ret = ov7670_read(sd, REG_CONTRAS, &v);
-
- *value = v;
- return ret;
-}
-
-static int ov7670_g_hflip(struct v4l2_subdev *sd, __s32 *value)
-{
- int ret;
- unsigned char v = 0;
-
- ret = ov7670_read(sd, REG_MVFP, &v);
- *value = (v & MVFP_MIRROR) == MVFP_MIRROR;
- return ret;
-}
-
-
-static int ov7670_s_hflip(struct v4l2_subdev *sd, int value)
-{
- unsigned char v = 0;
- int ret;
-
- ret = ov7670_read(sd, REG_MVFP, &v);
- if (value)
- v |= MVFP_MIRROR;
- else
- v &= ~MVFP_MIRROR;
- msleep(10); /* FIXME */
- ret += ov7670_write(sd, REG_MVFP, v);
- return ret;
-}
-
-
-
-static int ov7670_g_vflip(struct v4l2_subdev *sd, __s32 *value)
-{
- int ret;
- unsigned char v = 0;
-
- ret = ov7670_read(sd, REG_MVFP, &v);
- *value = (v & MVFP_FLIP) == MVFP_FLIP;
- return ret;
-}
-
-
-static int ov7670_s_vflip(struct v4l2_subdev *sd, int value)
-{
- unsigned char v = 0;
- int ret;
-
- ret = ov7670_read(sd, REG_MVFP, &v);
- if (value)
- v |= MVFP_FLIP;
- else
- v &= ~MVFP_FLIP;
- msleep(10); /* FIXME */
- ret += ov7670_write(sd, REG_MVFP, v);
- return ret;
-}
-
-/*
- * GAIN is split between REG_GAIN and REG_VREF[7:6]. If one believes
- * the data sheet, the VREF parts should be the most significant, but
- * experience shows otherwise. There seems to be little value in
- * messing with the VREF bits, so we leave them alone.
- */
-static int ov7670_g_gain(struct v4l2_subdev *sd, __s32 *value)
-{
- int ret;
- unsigned char gain;
-
- ret = ov7670_read(sd, REG_GAIN, &gain);
- *value = gain;
- return ret;
-}
-
-static int ov7670_s_gain(struct v4l2_subdev *sd, int value)
-{
- int ret;
- unsigned char com8;
-
- ret = ov7670_write(sd, REG_GAIN, value & 0xff);
- /* Have to turn off AGC as well */
- if (ret == 0) {
- ret = ov7670_read(sd, REG_COM8, &com8);
- ret = ov7670_write(sd, REG_COM8, com8 & ~COM8_AGC);
- }
- return ret;
-}
-
-/*
- * Tweak autogain.
- */
-static int ov7670_g_autogain(struct v4l2_subdev *sd, __s32 *value)
-{
- int ret;
- unsigned char com8;
-
- ret = ov7670_read(sd, REG_COM8, &com8);
- *value = (com8 & COM8_AGC) != 0;
- return ret;
-}
-
-static int ov7670_s_autogain(struct v4l2_subdev *sd, int value)
-{
- int ret;
- unsigned char com8;
-
- ret = ov7670_read(sd, REG_COM8, &com8);
- if (ret == 0) {
- if (value)
- com8 |= COM8_AGC;
- else
- com8 &= ~COM8_AGC;
- ret = ov7670_write(sd, REG_COM8, com8);
- }
- return ret;
-}
-
-/*
- * Exposure is spread all over the place: top 6 bits in AECHH, middle
- * 8 in AECH, and two stashed in COM1 just for the hell of it.
- */
-static int ov7670_g_exp(struct v4l2_subdev *sd, __s32 *value)
-{
- int ret;
- unsigned char com1, aech, aechh;
-
- ret = ov7670_read(sd, REG_COM1, &com1) +
- ov7670_read(sd, REG_AECH, &aech) +
- ov7670_read(sd, REG_AECHH, &aechh);
- *value = ((aechh & 0x3f) << 10) | (aech << 2) | (com1 & 0x03);
- return ret;
-}
-
-static int ov7670_s_exp(struct v4l2_subdev *sd, int value)
-{
- int ret;
- unsigned char com1, com8, aech, aechh;
-
- ret = ov7670_read(sd, REG_COM1, &com1) +
- ov7670_read(sd, REG_COM8, &com8);
- ov7670_read(sd, REG_AECHH, &aechh);
- if (ret)
- return ret;
-
- com1 = (com1 & 0xfc) | (value & 0x03);
- aech = (value >> 2) & 0xff;
- aechh = (aechh & 0xc0) | ((value >> 10) & 0x3f);
- ret = ov7670_write(sd, REG_COM1, com1) +
- ov7670_write(sd, REG_AECH, aech) +
- ov7670_write(sd, REG_AECHH, aechh);
- /* Have to turn off AEC as well */
- if (ret == 0)
- ret = ov7670_write(sd, REG_COM8, com8 & ~COM8_AEC);
- return ret;
-}
-
-/*
- * Tweak autoexposure.
- */
-static int ov7670_g_autoexp(struct v4l2_subdev *sd, __s32 *value)
-{
- int ret;
- unsigned char com8;
- enum v4l2_exposure_auto_type *atype = (enum v4l2_exposure_auto_type *) value;
-
- ret = ov7670_read(sd, REG_COM8, &com8);
- if (com8 & COM8_AEC)
- *atype = V4L2_EXPOSURE_AUTO;
- else
- *atype = V4L2_EXPOSURE_MANUAL;
- return ret;
-}
-
-static int ov7670_s_autoexp(struct v4l2_subdev *sd,
- enum v4l2_exposure_auto_type value)
-{
- int ret;
- unsigned char com8;
-
- ret = ov7670_read(sd, REG_COM8, &com8);
- if (ret == 0) {
- if (value == V4L2_EXPOSURE_AUTO)
- com8 |= COM8_AEC;
- else
- com8 &= ~COM8_AEC;
- ret = ov7670_write(sd, REG_COM8, com8);
- }
- return ret;
-}
-
-
-
-static int ov7670_queryctrl(struct v4l2_subdev *sd,
- struct v4l2_queryctrl *qc)
-{
- /* Fill in min, max, step and default value for these controls. */
- switch (qc->id) {
- case V4L2_CID_BRIGHTNESS:
- return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
- case V4L2_CID_CONTRAST:
- return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
- case V4L2_CID_VFLIP:
- case V4L2_CID_HFLIP:
- return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
- case V4L2_CID_SATURATION:
- return v4l2_ctrl_query_fill(qc, 0, 256, 1, 128);
- case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill(qc, -180, 180, 5, 0);
- case V4L2_CID_GAIN:
- return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
- case V4L2_CID_AUTOGAIN:
- return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
- case V4L2_CID_EXPOSURE:
- return v4l2_ctrl_query_fill(qc, 0, 65535, 1, 500);
- case V4L2_CID_EXPOSURE_AUTO:
- return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
- }
- return -EINVAL;
-}
-
-static int ov7670_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- return ov7670_g_brightness(sd, &ctrl->value);
- case V4L2_CID_CONTRAST:
- return ov7670_g_contrast(sd, &ctrl->value);
- case V4L2_CID_SATURATION:
- return ov7670_g_sat(sd, &ctrl->value);
- case V4L2_CID_HUE:
- return ov7670_g_hue(sd, &ctrl->value);
- case V4L2_CID_VFLIP:
- return ov7670_g_vflip(sd, &ctrl->value);
- case V4L2_CID_HFLIP:
- return ov7670_g_hflip(sd, &ctrl->value);
- case V4L2_CID_GAIN:
- return ov7670_g_gain(sd, &ctrl->value);
- case V4L2_CID_AUTOGAIN:
- return ov7670_g_autogain(sd, &ctrl->value);
- case V4L2_CID_EXPOSURE:
- return ov7670_g_exp(sd, &ctrl->value);
- case V4L2_CID_EXPOSURE_AUTO:
- return ov7670_g_autoexp(sd, &ctrl->value);
- }
- return -EINVAL;
-}
-
-static int ov7670_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- return ov7670_s_brightness(sd, ctrl->value);
- case V4L2_CID_CONTRAST:
- return ov7670_s_contrast(sd, ctrl->value);
- case V4L2_CID_SATURATION:
- return ov7670_s_sat(sd, ctrl->value);
- case V4L2_CID_HUE:
- return ov7670_s_hue(sd, ctrl->value);
- case V4L2_CID_VFLIP:
- return ov7670_s_vflip(sd, ctrl->value);
- case V4L2_CID_HFLIP:
- return ov7670_s_hflip(sd, ctrl->value);
- case V4L2_CID_GAIN:
- return ov7670_s_gain(sd, ctrl->value);
- case V4L2_CID_AUTOGAIN:
- return ov7670_s_autogain(sd, ctrl->value);
- case V4L2_CID_EXPOSURE:
- return ov7670_s_exp(sd, ctrl->value);
- case V4L2_CID_EXPOSURE_AUTO:
- return ov7670_s_autoexp(sd,
- (enum v4l2_exposure_auto_type) ctrl->value);
- }
- return -EINVAL;
-}
-
-static int ov7670_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV7670, 0);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ov7670_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- unsigned char val = 0;
- int ret;
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- ret = ov7670_read(sd, reg->reg & 0xff, &val);
- reg->val = val;
- reg->size = 1;
- return ret;
-}
-
-static int ov7670_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- ov7670_write(sd, reg->reg & 0xff, reg->val & 0xff);
- return 0;
-}
-#endif
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops ov7670_core_ops = {
- .g_chip_ident = ov7670_g_chip_ident,
- .g_ctrl = ov7670_g_ctrl,
- .s_ctrl = ov7670_s_ctrl,
- .queryctrl = ov7670_queryctrl,
- .reset = ov7670_reset,
- .init = ov7670_init,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = ov7670_g_register,
- .s_register = ov7670_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_video_ops ov7670_video_ops = {
- .enum_mbus_fmt = ov7670_enum_mbus_fmt,
- .try_mbus_fmt = ov7670_try_mbus_fmt,
- .s_mbus_fmt = ov7670_s_mbus_fmt,
- .s_parm = ov7670_s_parm,
- .g_parm = ov7670_g_parm,
- .enum_frameintervals = ov7670_enum_frameintervals,
- .enum_framesizes = ov7670_enum_framesizes,
-};
-
-static const struct v4l2_subdev_ops ov7670_ops = {
- .core = &ov7670_core_ops,
- .video = &ov7670_video_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int ov7670_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct v4l2_subdev *sd;
- struct ov7670_info *info;
- int ret;
-
- info = kzalloc(sizeof(struct ov7670_info), GFP_KERNEL);
- if (info == NULL)
- return -ENOMEM;
- sd = &info->sd;
- v4l2_i2c_subdev_init(sd, client, &ov7670_ops);
-
- info->clock_speed = 30; /* default: a guess */
- if (client->dev.platform_data) {
- struct ov7670_config *config = client->dev.platform_data;
-
- /*
- * Must apply configuration before initializing device, because it
- * selects I/O method.
- */
- info->min_width = config->min_width;
- info->min_height = config->min_height;
- info->use_smbus = config->use_smbus;
-
- if (config->clock_speed)
- info->clock_speed = config->clock_speed;
- }
-
- /* Make sure it's an ov7670 */
- ret = ov7670_detect(sd);
- if (ret) {
- v4l_dbg(1, debug, client,
- "chip found @ 0x%x (%s) is not an ov7670 chip.\n",
- client->addr << 1, client->adapter->name);
- kfree(info);
- return ret;
- }
- v4l_info(client, "chip found @ 0x%02x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- info->fmt = &ov7670_formats[0];
- info->sat = 128; /* Review this */
- info->clkrc = info->clock_speed / 30;
- return 0;
-}
-
-
-static int ov7670_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(to_state(sd));
- return 0;
-}
-
-static const struct i2c_device_id ov7670_id[] = {
- { "ov7670", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ov7670_id);
-
-static struct i2c_driver ov7670_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "ov7670",
- },
- .probe = ov7670_probe,
- .remove = ov7670_remove,
- .id_table = ov7670_id,
-};
-
-module_i2c_driver(ov7670_driver);
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
deleted file mode 100644
index 6d79b89b860..00000000000
--- a/drivers/media/video/ov772x.c
+++ /dev/null
@@ -1,1126 +0,0 @@
-/*
- * ov772x Camera Driver
- *
- * Copyright (C) 2008 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on ov7670 and soc_camera_platform driver,
- *
- * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
- * Copyright (C) 2008 Magnus Damm
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/videodev2.h>
-
-#include <media/ov772x.h>
-#include <media/soc_camera.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-subdev.h>
-
-/*
- * register offset
- */
-#define GAIN 0x00 /* AGC - Gain control gain setting */
-#define BLUE 0x01 /* AWB - Blue channel gain setting */
-#define RED 0x02 /* AWB - Red channel gain setting */
-#define GREEN 0x03 /* AWB - Green channel gain setting */
-#define COM1 0x04 /* Common control 1 */
-#define BAVG 0x05 /* U/B Average Level */
-#define GAVG 0x06 /* Y/Gb Average Level */
-#define RAVG 0x07 /* V/R Average Level */
-#define AECH 0x08 /* Exposure Value - AEC MSBs */
-#define COM2 0x09 /* Common control 2 */
-#define PID 0x0A /* Product ID Number MSB */
-#define VER 0x0B /* Product ID Number LSB */
-#define COM3 0x0C /* Common control 3 */
-#define COM4 0x0D /* Common control 4 */
-#define COM5 0x0E /* Common control 5 */
-#define COM6 0x0F /* Common control 6 */
-#define AEC 0x10 /* Exposure Value */
-#define CLKRC 0x11 /* Internal clock */
-#define COM7 0x12 /* Common control 7 */
-#define COM8 0x13 /* Common control 8 */
-#define COM9 0x14 /* Common control 9 */
-#define COM10 0x15 /* Common control 10 */
-#define REG16 0x16 /* Register 16 */
-#define HSTART 0x17 /* Horizontal sensor size */
-#define HSIZE 0x18 /* Horizontal frame (HREF column) end high 8-bit */
-#define VSTART 0x19 /* Vertical frame (row) start high 8-bit */
-#define VSIZE 0x1A /* Vertical sensor size */
-#define PSHFT 0x1B /* Data format - pixel delay select */
-#define MIDH 0x1C /* Manufacturer ID byte - high */
-#define MIDL 0x1D /* Manufacturer ID byte - low */
-#define LAEC 0x1F /* Fine AEC value */
-#define COM11 0x20 /* Common control 11 */
-#define BDBASE 0x22 /* Banding filter Minimum AEC value */
-#define DBSTEP 0x23 /* Banding filter Maximum Setp */
-#define AEW 0x24 /* AGC/AEC - Stable operating region (upper limit) */
-#define AEB 0x25 /* AGC/AEC - Stable operating region (lower limit) */
-#define VPT 0x26 /* AGC/AEC Fast mode operating region */
-#define REG28 0x28 /* Register 28 */
-#define HOUTSIZE 0x29 /* Horizontal data output size MSBs */
-#define EXHCH 0x2A /* Dummy pixel insert MSB */
-#define EXHCL 0x2B /* Dummy pixel insert LSB */
-#define VOUTSIZE 0x2C /* Vertical data output size MSBs */
-#define ADVFL 0x2D /* LSB of insert dummy lines in Vertical direction */
-#define ADVFH 0x2E /* MSG of insert dummy lines in Vertical direction */
-#define YAVE 0x2F /* Y/G Channel Average value */
-#define LUMHTH 0x30 /* Histogram AEC/AGC Luminance high level threshold */
-#define LUMLTH 0x31 /* Histogram AEC/AGC Luminance low level threshold */
-#define HREF 0x32 /* Image start and size control */
-#define DM_LNL 0x33 /* Dummy line low 8 bits */
-#define DM_LNH 0x34 /* Dummy line high 8 bits */
-#define ADOFF_B 0x35 /* AD offset compensation value for B channel */
-#define ADOFF_R 0x36 /* AD offset compensation value for R channel */
-#define ADOFF_GB 0x37 /* AD offset compensation value for Gb channel */
-#define ADOFF_GR 0x38 /* AD offset compensation value for Gr channel */
-#define OFF_B 0x39 /* Analog process B channel offset value */
-#define OFF_R 0x3A /* Analog process R channel offset value */
-#define OFF_GB 0x3B /* Analog process Gb channel offset value */
-#define OFF_GR 0x3C /* Analog process Gr channel offset value */
-#define COM12 0x3D /* Common control 12 */
-#define COM13 0x3E /* Common control 13 */
-#define COM14 0x3F /* Common control 14 */
-#define COM15 0x40 /* Common control 15*/
-#define COM16 0x41 /* Common control 16 */
-#define TGT_B 0x42 /* BLC blue channel target value */
-#define TGT_R 0x43 /* BLC red channel target value */
-#define TGT_GB 0x44 /* BLC Gb channel target value */
-#define TGT_GR 0x45 /* BLC Gr channel target value */
-/* for ov7720 */
-#define LCC0 0x46 /* Lens correction control 0 */
-#define LCC1 0x47 /* Lens correction option 1 - X coordinate */
-#define LCC2 0x48 /* Lens correction option 2 - Y coordinate */
-#define LCC3 0x49 /* Lens correction option 3 */
-#define LCC4 0x4A /* Lens correction option 4 - radius of the circular */
-#define LCC5 0x4B /* Lens correction option 5 */
-#define LCC6 0x4C /* Lens correction option 6 */
-/* for ov7725 */
-#define LC_CTR 0x46 /* Lens correction control */
-#define LC_XC 0x47 /* X coordinate of lens correction center relative */
-#define LC_YC 0x48 /* Y coordinate of lens correction center relative */
-#define LC_COEF 0x49 /* Lens correction coefficient */
-#define LC_RADI 0x4A /* Lens correction radius */
-#define LC_COEFB 0x4B /* Lens B channel compensation coefficient */
-#define LC_COEFR 0x4C /* Lens R channel compensation coefficient */
-
-#define FIXGAIN 0x4D /* Analog fix gain amplifer */
-#define AREF0 0x4E /* Sensor reference control */
-#define AREF1 0x4F /* Sensor reference current control */
-#define AREF2 0x50 /* Analog reference control */
-#define AREF3 0x51 /* ADC reference control */
-#define AREF4 0x52 /* ADC reference control */
-#define AREF5 0x53 /* ADC reference control */
-#define AREF6 0x54 /* Analog reference control */
-#define AREF7 0x55 /* Analog reference control */
-#define UFIX 0x60 /* U channel fixed value output */
-#define VFIX 0x61 /* V channel fixed value output */
-#define AWBB_BLK 0x62 /* AWB option for advanced AWB */
-#define AWB_CTRL0 0x63 /* AWB control byte 0 */
-#define DSP_CTRL1 0x64 /* DSP control byte 1 */
-#define DSP_CTRL2 0x65 /* DSP control byte 2 */
-#define DSP_CTRL3 0x66 /* DSP control byte 3 */
-#define DSP_CTRL4 0x67 /* DSP control byte 4 */
-#define AWB_BIAS 0x68 /* AWB BLC level clip */
-#define AWB_CTRL1 0x69 /* AWB control 1 */
-#define AWB_CTRL2 0x6A /* AWB control 2 */
-#define AWB_CTRL3 0x6B /* AWB control 3 */
-#define AWB_CTRL4 0x6C /* AWB control 4 */
-#define AWB_CTRL5 0x6D /* AWB control 5 */
-#define AWB_CTRL6 0x6E /* AWB control 6 */
-#define AWB_CTRL7 0x6F /* AWB control 7 */
-#define AWB_CTRL8 0x70 /* AWB control 8 */
-#define AWB_CTRL9 0x71 /* AWB control 9 */
-#define AWB_CTRL10 0x72 /* AWB control 10 */
-#define AWB_CTRL11 0x73 /* AWB control 11 */
-#define AWB_CTRL12 0x74 /* AWB control 12 */
-#define AWB_CTRL13 0x75 /* AWB control 13 */
-#define AWB_CTRL14 0x76 /* AWB control 14 */
-#define AWB_CTRL15 0x77 /* AWB control 15 */
-#define AWB_CTRL16 0x78 /* AWB control 16 */
-#define AWB_CTRL17 0x79 /* AWB control 17 */
-#define AWB_CTRL18 0x7A /* AWB control 18 */
-#define AWB_CTRL19 0x7B /* AWB control 19 */
-#define AWB_CTRL20 0x7C /* AWB control 20 */
-#define AWB_CTRL21 0x7D /* AWB control 21 */
-#define GAM1 0x7E /* Gamma Curve 1st segment input end point */
-#define GAM2 0x7F /* Gamma Curve 2nd segment input end point */
-#define GAM3 0x80 /* Gamma Curve 3rd segment input end point */
-#define GAM4 0x81 /* Gamma Curve 4th segment input end point */
-#define GAM5 0x82 /* Gamma Curve 5th segment input end point */
-#define GAM6 0x83 /* Gamma Curve 6th segment input end point */
-#define GAM7 0x84 /* Gamma Curve 7th segment input end point */
-#define GAM8 0x85 /* Gamma Curve 8th segment input end point */
-#define GAM9 0x86 /* Gamma Curve 9th segment input end point */
-#define GAM10 0x87 /* Gamma Curve 10th segment input end point */
-#define GAM11 0x88 /* Gamma Curve 11th segment input end point */
-#define GAM12 0x89 /* Gamma Curve 12th segment input end point */
-#define GAM13 0x8A /* Gamma Curve 13th segment input end point */
-#define GAM14 0x8B /* Gamma Curve 14th segment input end point */
-#define GAM15 0x8C /* Gamma Curve 15th segment input end point */
-#define SLOP 0x8D /* Gamma curve highest segment slope */
-#define DNSTH 0x8E /* De-noise threshold */
-#define EDGE_STRNGT 0x8F /* Edge strength control when manual mode */
-#define EDGE_TRSHLD 0x90 /* Edge threshold control when manual mode */
-#define DNSOFF 0x91 /* Auto De-noise threshold control */
-#define EDGE_UPPER 0x92 /* Edge strength upper limit when Auto mode */
-#define EDGE_LOWER 0x93 /* Edge strength lower limit when Auto mode */
-#define MTX1 0x94 /* Matrix coefficient 1 */
-#define MTX2 0x95 /* Matrix coefficient 2 */
-#define MTX3 0x96 /* Matrix coefficient 3 */
-#define MTX4 0x97 /* Matrix coefficient 4 */
-#define MTX5 0x98 /* Matrix coefficient 5 */
-#define MTX6 0x99 /* Matrix coefficient 6 */
-#define MTX_CTRL 0x9A /* Matrix control */
-#define BRIGHT 0x9B /* Brightness control */
-#define CNTRST 0x9C /* Contrast contrast */
-#define CNTRST_CTRL 0x9D /* Contrast contrast center */
-#define UVAD_J0 0x9E /* Auto UV adjust contrast 0 */
-#define UVAD_J1 0x9F /* Auto UV adjust contrast 1 */
-#define SCAL0 0xA0 /* Scaling control 0 */
-#define SCAL1 0xA1 /* Scaling control 1 */
-#define SCAL2 0xA2 /* Scaling control 2 */
-#define FIFODLYM 0xA3 /* FIFO manual mode delay control */
-#define FIFODLYA 0xA4 /* FIFO auto mode delay control */
-#define SDE 0xA6 /* Special digital effect control */
-#define USAT 0xA7 /* U component saturation control */
-#define VSAT 0xA8 /* V component saturation control */
-/* for ov7720 */
-#define HUE0 0xA9 /* Hue control 0 */
-#define HUE1 0xAA /* Hue control 1 */
-/* for ov7725 */
-#define HUECOS 0xA9 /* Cosine value */
-#define HUESIN 0xAA /* Sine value */
-
-#define SIGN 0xAB /* Sign bit for Hue and contrast */
-#define DSPAUTO 0xAC /* DSP auto function ON/OFF control */
-
-/*
- * register detail
- */
-
-/* COM2 */
-#define SOFT_SLEEP_MODE 0x10 /* Soft sleep mode */
- /* Output drive capability */
-#define OCAP_1x 0x00 /* 1x */
-#define OCAP_2x 0x01 /* 2x */
-#define OCAP_3x 0x02 /* 3x */
-#define OCAP_4x 0x03 /* 4x */
-
-/* COM3 */
-#define SWAP_MASK (SWAP_RGB | SWAP_YUV | SWAP_ML)
-#define IMG_MASK (VFLIP_IMG | HFLIP_IMG)
-
-#define VFLIP_IMG 0x80 /* Vertical flip image ON/OFF selection */
-#define HFLIP_IMG 0x40 /* Horizontal mirror image ON/OFF selection */
-#define SWAP_RGB 0x20 /* Swap B/R output sequence in RGB mode */
-#define SWAP_YUV 0x10 /* Swap Y/UV output sequence in YUV mode */
-#define SWAP_ML 0x08 /* Swap output MSB/LSB */
- /* Tri-state option for output clock */
-#define NOTRI_CLOCK 0x04 /* 0: Tri-state at this period */
- /* 1: No tri-state at this period */
- /* Tri-state option for output data */
-#define NOTRI_DATA 0x02 /* 0: Tri-state at this period */
- /* 1: No tri-state at this period */
-#define SCOLOR_TEST 0x01 /* Sensor color bar test pattern */
-
-/* COM4 */
- /* PLL frequency control */
-#define PLL_BYPASS 0x00 /* 00: Bypass PLL */
-#define PLL_4x 0x40 /* 01: PLL 4x */
-#define PLL_6x 0x80 /* 10: PLL 6x */
-#define PLL_8x 0xc0 /* 11: PLL 8x */
- /* AEC evaluate window */
-#define AEC_FULL 0x00 /* 00: Full window */
-#define AEC_1p2 0x10 /* 01: 1/2 window */
-#define AEC_1p4 0x20 /* 10: 1/4 window */
-#define AEC_2p3 0x30 /* 11: Low 2/3 window */
-
-/* COM5 */
-#define AFR_ON_OFF 0x80 /* Auto frame rate control ON/OFF selection */
-#define AFR_SPPED 0x40 /* Auto frame rate control speed selection */
- /* Auto frame rate max rate control */
-#define AFR_NO_RATE 0x00 /* No reduction of frame rate */
-#define AFR_1p2 0x10 /* Max reduction to 1/2 frame rate */
-#define AFR_1p4 0x20 /* Max reduction to 1/4 frame rate */
-#define AFR_1p8 0x30 /* Max reduction to 1/8 frame rate */
- /* Auto frame rate active point control */
-#define AF_2x 0x00 /* Add frame when AGC reaches 2x gain */
-#define AF_4x 0x04 /* Add frame when AGC reaches 4x gain */
-#define AF_8x 0x08 /* Add frame when AGC reaches 8x gain */
-#define AF_16x 0x0c /* Add frame when AGC reaches 16x gain */
- /* AEC max step control */
-#define AEC_NO_LIMIT 0x01 /* 0 : AEC incease step has limit */
- /* 1 : No limit to AEC increase step */
-
-/* COM7 */
- /* SCCB Register Reset */
-#define SCCB_RESET 0x80 /* 0 : No change */
- /* 1 : Resets all registers to default */
- /* Resolution selection */
-#define SLCT_MASK 0x40 /* Mask of VGA or QVGA */
-#define SLCT_VGA 0x00 /* 0 : VGA */
-#define SLCT_QVGA 0x40 /* 1 : QVGA */
-#define ITU656_ON_OFF 0x20 /* ITU656 protocol ON/OFF selection */
- /* RGB output format control */
-#define FMT_MASK 0x0c /* Mask of color format */
-#define FMT_GBR422 0x00 /* 00 : GBR 4:2:2 */
-#define FMT_RGB565 0x04 /* 01 : RGB 565 */
-#define FMT_RGB555 0x08 /* 10 : RGB 555 */
-#define FMT_RGB444 0x0c /* 11 : RGB 444 */
- /* Output format control */
-#define OFMT_MASK 0x03 /* Mask of output format */
-#define OFMT_YUV 0x00 /* 00 : YUV */
-#define OFMT_P_BRAW 0x01 /* 01 : Processed Bayer RAW */
-#define OFMT_RGB 0x02 /* 10 : RGB */
-#define OFMT_BRAW 0x03 /* 11 : Bayer RAW */
-
-/* COM8 */
-#define FAST_ALGO 0x80 /* Enable fast AGC/AEC algorithm */
- /* AEC Setp size limit */
-#define UNLMT_STEP 0x40 /* 0 : Step size is limited */
- /* 1 : Unlimited step size */
-#define BNDF_ON_OFF 0x20 /* Banding filter ON/OFF */
-#define AEC_BND 0x10 /* Enable AEC below banding value */
-#define AEC_ON_OFF 0x08 /* Fine AEC ON/OFF control */
-#define AGC_ON 0x04 /* AGC Enable */
-#define AWB_ON 0x02 /* AWB Enable */
-#define AEC_ON 0x01 /* AEC Enable */
-
-/* COM9 */
-#define BASE_AECAGC 0x80 /* Histogram or average based AEC/AGC */
- /* Automatic gain ceiling - maximum AGC value */
-#define GAIN_2x 0x00 /* 000 : 2x */
-#define GAIN_4x 0x10 /* 001 : 4x */
-#define GAIN_8x 0x20 /* 010 : 8x */
-#define GAIN_16x 0x30 /* 011 : 16x */
-#define GAIN_32x 0x40 /* 100 : 32x */
-#define GAIN_64x 0x50 /* 101 : 64x */
-#define GAIN_128x 0x60 /* 110 : 128x */
-#define DROP_VSYNC 0x04 /* Drop VSYNC output of corrupt frame */
-#define DROP_HREF 0x02 /* Drop HREF output of corrupt frame */
-
-/* COM11 */
-#define SGLF_ON_OFF 0x02 /* Single frame ON/OFF selection */
-#define SGLF_TRIG 0x01 /* Single frame transfer trigger */
-
-/* EXHCH */
-#define VSIZE_LSB 0x04 /* Vertical data output size LSB */
-
-/* DSP_CTRL1 */
-#define FIFO_ON 0x80 /* FIFO enable/disable selection */
-#define UV_ON_OFF 0x40 /* UV adjust function ON/OFF selection */
-#define YUV444_2_422 0x20 /* YUV444 to 422 UV channel option selection */
-#define CLR_MTRX_ON_OFF 0x10 /* Color matrix ON/OFF selection */
-#define INTPLT_ON_OFF 0x08 /* Interpolation ON/OFF selection */
-#define GMM_ON_OFF 0x04 /* Gamma function ON/OFF selection */
-#define AUTO_BLK_ON_OFF 0x02 /* Black defect auto correction ON/OFF */
-#define AUTO_WHT_ON_OFF 0x01 /* White define auto correction ON/OFF */
-
-/* DSP_CTRL3 */
-#define UV_MASK 0x80 /* UV output sequence option */
-#define UV_ON 0x80 /* ON */
-#define UV_OFF 0x00 /* OFF */
-#define CBAR_MASK 0x20 /* DSP Color bar mask */
-#define CBAR_ON 0x20 /* ON */
-#define CBAR_OFF 0x00 /* OFF */
-
-/* HSTART */
-#define HST_VGA 0x23
-#define HST_QVGA 0x3F
-
-/* HSIZE */
-#define HSZ_VGA 0xA0
-#define HSZ_QVGA 0x50
-
-/* VSTART */
-#define VST_VGA 0x07
-#define VST_QVGA 0x03
-
-/* VSIZE */
-#define VSZ_VGA 0xF0
-#define VSZ_QVGA 0x78
-
-/* HOUTSIZE */
-#define HOSZ_VGA 0xA0
-#define HOSZ_QVGA 0x50
-
-/* VOUTSIZE */
-#define VOSZ_VGA 0xF0
-#define VOSZ_QVGA 0x78
-
-/* DSPAUTO (DSP Auto Function ON/OFF Control) */
-#define AWB_ACTRL 0x80 /* AWB auto threshold control */
-#define DENOISE_ACTRL 0x40 /* De-noise auto threshold control */
-#define EDGE_ACTRL 0x20 /* Edge enhancement auto strength control */
-#define UV_ACTRL 0x10 /* UV adjust auto slope control */
-#define SCAL0_ACTRL 0x08 /* Auto scaling factor control */
-#define SCAL1_2_ACTRL 0x04 /* Auto scaling factor control */
-
-/*
- * ID
- */
-#define OV7720 0x7720
-#define OV7725 0x7721
-#define VERSION(pid, ver) ((pid<<8)|(ver&0xFF))
-
-/*
- * struct
- */
-struct regval_list {
- unsigned char reg_num;
- unsigned char value;
-};
-
-struct ov772x_color_format {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
- u8 dsp3;
- u8 com3;
- u8 com7;
-};
-
-struct ov772x_win_size {
- char *name;
- __u32 width;
- __u32 height;
- unsigned char com7_bit;
- const struct regval_list *regs;
-};
-
-struct ov772x_priv {
- struct v4l2_subdev subdev;
- struct v4l2_ctrl_handler hdl;
- struct ov772x_camera_info *info;
- const struct ov772x_color_format *cfmt;
- const struct ov772x_win_size *win;
- int model;
- unsigned short flag_vflip:1;
- unsigned short flag_hflip:1;
- /* band_filter = COM8[5] ? 256 - BDBASE : 0 */
- unsigned short band_filter;
-};
-
-#define ENDMARKER { 0xff, 0xff }
-
-/*
- * register setting for window size
- */
-static const struct regval_list ov772x_qvga_regs[] = {
- { HSTART, HST_QVGA },
- { HSIZE, HSZ_QVGA },
- { VSTART, VST_QVGA },
- { VSIZE, VSZ_QVGA },
- { HOUTSIZE, HOSZ_QVGA },
- { VOUTSIZE, VOSZ_QVGA },
- ENDMARKER,
-};
-
-static const struct regval_list ov772x_vga_regs[] = {
- { HSTART, HST_VGA },
- { HSIZE, HSZ_VGA },
- { VSTART, VST_VGA },
- { VSIZE, VSZ_VGA },
- { HOUTSIZE, HOSZ_VGA },
- { VOUTSIZE, VOSZ_VGA },
- ENDMARKER,
-};
-
-/*
- * supported color format list
- */
-static const struct ov772x_color_format ov772x_cfmts[] = {
- {
- .code = V4L2_MBUS_FMT_YUYV8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .dsp3 = 0x0,
- .com3 = SWAP_YUV,
- .com7 = OFMT_YUV,
- },
- {
- .code = V4L2_MBUS_FMT_YVYU8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .dsp3 = UV_ON,
- .com3 = SWAP_YUV,
- .com7 = OFMT_YUV,
- },
- {
- .code = V4L2_MBUS_FMT_UYVY8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .dsp3 = 0x0,
- .com3 = 0x0,
- .com7 = OFMT_YUV,
- },
- {
- .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .dsp3 = 0x0,
- .com3 = SWAP_RGB,
- .com7 = FMT_RGB555 | OFMT_RGB,
- },
- {
- .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .dsp3 = 0x0,
- .com3 = 0x0,
- .com7 = FMT_RGB555 | OFMT_RGB,
- },
- {
- .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .dsp3 = 0x0,
- .com3 = SWAP_RGB,
- .com7 = FMT_RGB565 | OFMT_RGB,
- },
- {
- .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .dsp3 = 0x0,
- .com3 = 0x0,
- .com7 = FMT_RGB565 | OFMT_RGB,
- },
-};
-
-
-/*
- * window size list
- */
-#define VGA_WIDTH 640
-#define VGA_HEIGHT 480
-#define QVGA_WIDTH 320
-#define QVGA_HEIGHT 240
-#define MAX_WIDTH VGA_WIDTH
-#define MAX_HEIGHT VGA_HEIGHT
-
-static const struct ov772x_win_size ov772x_win_vga = {
- .name = "VGA",
- .width = VGA_WIDTH,
- .height = VGA_HEIGHT,
- .com7_bit = SLCT_VGA,
- .regs = ov772x_vga_regs,
-};
-
-static const struct ov772x_win_size ov772x_win_qvga = {
- .name = "QVGA",
- .width = QVGA_WIDTH,
- .height = QVGA_HEIGHT,
- .com7_bit = SLCT_QVGA,
- .regs = ov772x_qvga_regs,
-};
-
-/*
- * general function
- */
-
-static struct ov772x_priv *to_ov772x(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client), struct ov772x_priv,
- subdev);
-}
-
-static int ov772x_write_array(struct i2c_client *client,
- const struct regval_list *vals)
-{
- while (vals->reg_num != 0xff) {
- int ret = i2c_smbus_write_byte_data(client,
- vals->reg_num,
- vals->value);
- if (ret < 0)
- return ret;
- vals++;
- }
- return 0;
-}
-
-static int ov772x_mask_set(struct i2c_client *client,
- u8 command,
- u8 mask,
- u8 set)
-{
- s32 val = i2c_smbus_read_byte_data(client, command);
- if (val < 0)
- return val;
-
- val &= ~mask;
- val |= set & mask;
-
- return i2c_smbus_write_byte_data(client, command, val);
-}
-
-static int ov772x_reset(struct i2c_client *client)
-{
- int ret = i2c_smbus_write_byte_data(client, COM7, SCCB_RESET);
- msleep(1);
- return ret;
-}
-
-/*
- * soc_camera_ops function
- */
-
-static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
-
- if (!enable) {
- ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
- return 0;
- }
-
- if (!priv->win || !priv->cfmt) {
- dev_err(&client->dev, "norm or win select error\n");
- return -EPERM;
- }
-
- ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);
-
- dev_dbg(&client->dev, "format %d, win %s\n",
- priv->cfmt->code, priv->win->name);
-
- return 0;
-}
-
-static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct ov772x_priv *priv = container_of(ctrl->handler,
- struct ov772x_priv, hdl);
- struct v4l2_subdev *sd = &priv->subdev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret = 0;
- u8 val;
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- val = ctrl->val ? VFLIP_IMG : 0x00;
- priv->flag_vflip = ctrl->val;
- if (priv->info->flags & OV772X_FLAG_VFLIP)
- val ^= VFLIP_IMG;
- return ov772x_mask_set(client, COM3, VFLIP_IMG, val);
- case V4L2_CID_HFLIP:
- val = ctrl->val ? HFLIP_IMG : 0x00;
- priv->flag_hflip = ctrl->val;
- if (priv->info->flags & OV772X_FLAG_HFLIP)
- val ^= HFLIP_IMG;
- return ov772x_mask_set(client, COM3, HFLIP_IMG, val);
- case V4L2_CID_BAND_STOP_FILTER:
- if (!ctrl->val) {
- /* Switch the filter off, it is on now */
- ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff);
- if (!ret)
- ret = ov772x_mask_set(client, COM8,
- BNDF_ON_OFF, 0);
- } else {
- /* Switch the filter on, set AEC low limit */
- val = 256 - ctrl->val;
- ret = ov772x_mask_set(client, COM8,
- BNDF_ON_OFF, BNDF_ON_OFF);
- if (!ret)
- ret = ov772x_mask_set(client, BDBASE,
- 0xff, val);
- }
- if (!ret)
- priv->band_filter = ctrl->val;
- return ret;
- }
-
- return -EINVAL;
-}
-
-static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
-
- id->ident = priv->model;
- id->revision = 0;
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ov772x_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
-
- reg->size = 1;
- if (reg->reg > 0xff)
- return -EINVAL;
-
- ret = i2c_smbus_read_byte_data(client, reg->reg);
- if (ret < 0)
- return ret;
-
- reg->val = (__u64)ret;
-
- return 0;
-}
-
-static int ov772x_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->reg > 0xff ||
- reg->val > 0xff)
- return -EINVAL;
-
- return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
-}
-#endif
-
-static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
-{
- __u32 diff;
- const struct ov772x_win_size *win;
-
- /* default is QVGA */
- diff = abs(width - ov772x_win_qvga.width) +
- abs(height - ov772x_win_qvga.height);
- win = &ov772x_win_qvga;
-
- /* VGA */
- if (diff >
- abs(width - ov772x_win_vga.width) +
- abs(height - ov772x_win_vga.height))
- win = &ov772x_win_vga;
-
- return win;
-}
-
-static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
- enum v4l2_mbus_pixelcode code)
-{
- struct ov772x_priv *priv = to_ov772x(client);
- int ret = -EINVAL;
- u8 val;
- int i;
-
- /*
- * select format
- */
- priv->cfmt = NULL;
- for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
- if (code == ov772x_cfmts[i].code) {
- priv->cfmt = ov772x_cfmts + i;
- break;
- }
- }
- if (!priv->cfmt)
- goto ov772x_set_fmt_error;
-
- /*
- * select win
- */
- priv->win = ov772x_select_win(*width, *height);
-
- /*
- * reset hardware
- */
- ov772x_reset(client);
-
- /*
- * Edge Ctrl
- */
- if (priv->info->edgectrl.strength & OV772X_MANUAL_EDGE_CTRL) {
-
- /*
- * Manual Edge Control Mode
- *
- * Edge auto strength bit is set by default.
- * Remove it when manual mode.
- */
-
- ret = ov772x_mask_set(client, DSPAUTO, EDGE_ACTRL, 0x00);
- if (ret < 0)
- goto ov772x_set_fmt_error;
-
- ret = ov772x_mask_set(client,
- EDGE_TRSHLD, OV772X_EDGE_THRESHOLD_MASK,
- priv->info->edgectrl.threshold);
- if (ret < 0)
- goto ov772x_set_fmt_error;
-
- ret = ov772x_mask_set(client,
- EDGE_STRNGT, OV772X_EDGE_STRENGTH_MASK,
- priv->info->edgectrl.strength);
- if (ret < 0)
- goto ov772x_set_fmt_error;
-
- } else if (priv->info->edgectrl.upper > priv->info->edgectrl.lower) {
- /*
- * Auto Edge Control Mode
- *
- * set upper and lower limit
- */
- ret = ov772x_mask_set(client,
- EDGE_UPPER, OV772X_EDGE_UPPER_MASK,
- priv->info->edgectrl.upper);
- if (ret < 0)
- goto ov772x_set_fmt_error;
-
- ret = ov772x_mask_set(client,
- EDGE_LOWER, OV772X_EDGE_LOWER_MASK,
- priv->info->edgectrl.lower);
- if (ret < 0)
- goto ov772x_set_fmt_error;
- }
-
- /*
- * set size format
- */
- ret = ov772x_write_array(client, priv->win->regs);
- if (ret < 0)
- goto ov772x_set_fmt_error;
-
- /*
- * set DSP_CTRL3
- */
- val = priv->cfmt->dsp3;
- if (val) {
- ret = ov772x_mask_set(client,
- DSP_CTRL3, UV_MASK, val);
- if (ret < 0)
- goto ov772x_set_fmt_error;
- }
-
- /*
- * set COM3
- */
- val = priv->cfmt->com3;
- if (priv->info->flags & OV772X_FLAG_VFLIP)
- val |= VFLIP_IMG;
- if (priv->info->flags & OV772X_FLAG_HFLIP)
- val |= HFLIP_IMG;
- if (priv->flag_vflip)
- val ^= VFLIP_IMG;
- if (priv->flag_hflip)
- val ^= HFLIP_IMG;
-
- ret = ov772x_mask_set(client,
- COM3, SWAP_MASK | IMG_MASK, val);
- if (ret < 0)
- goto ov772x_set_fmt_error;
-
- /*
- * set COM7
- */
- val = priv->win->com7_bit | priv->cfmt->com7;
- ret = ov772x_mask_set(client,
- COM7, SLCT_MASK | FMT_MASK | OFMT_MASK,
- val);
- if (ret < 0)
- goto ov772x_set_fmt_error;
-
- /*
- * set COM8
- */
- if (priv->band_filter) {
- ret = ov772x_mask_set(client, COM8, BNDF_ON_OFF, 1);
- if (!ret)
- ret = ov772x_mask_set(client, BDBASE,
- 0xff, 256 - priv->band_filter);
- if (ret < 0)
- goto ov772x_set_fmt_error;
- }
-
- *width = priv->win->width;
- *height = priv->win->height;
-
- return ret;
-
-ov772x_set_fmt_error:
-
- ov772x_reset(client);
- priv->win = NULL;
- priv->cfmt = NULL;
-
- return ret;
-}
-
-static int ov772x_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- a->c.left = 0;
- a->c.top = 0;
- a->c.width = VGA_WIDTH;
- a->c.height = VGA_HEIGHT;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = VGA_WIDTH;
- a->bounds.height = VGA_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int ov772x_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
-
- if (!priv->win || !priv->cfmt) {
- priv->cfmt = &ov772x_cfmts[0];
- priv->win = ov772x_select_win(VGA_WIDTH, VGA_HEIGHT);
- }
-
- mf->width = priv->win->width;
- mf->height = priv->win->height;
- mf->code = priv->cfmt->code;
- mf->colorspace = priv->cfmt->colorspace;
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int ov772x_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
- int ret = ov772x_set_params(client, &mf->width, &mf->height,
- mf->code);
-
- if (!ret)
- mf->colorspace = priv->cfmt->colorspace;
-
- return ret;
-}
-
-static int ov772x_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
- const struct ov772x_win_size *win;
- int i;
-
- /*
- * select suitable win
- */
- win = ov772x_select_win(mf->width, mf->height);
-
- mf->width = win->width;
- mf->height = win->height;
- mf->field = V4L2_FIELD_NONE;
-
- for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++)
- if (mf->code == ov772x_cfmts[i].code)
- break;
-
- if (i == ARRAY_SIZE(ov772x_cfmts)) {
- /* Unsupported format requested. Propose either */
- if (priv->cfmt) {
- /* the current one or */
- mf->colorspace = priv->cfmt->colorspace;
- mf->code = priv->cfmt->code;
- } else {
- /* the default one */
- mf->colorspace = ov772x_cfmts[0].colorspace;
- mf->code = ov772x_cfmts[0].code;
- }
- } else {
- /* Also return the colorspace */
- mf->colorspace = ov772x_cfmts[i].colorspace;
- }
-
- return 0;
-}
-
-static int ov772x_video_probe(struct i2c_client *client)
-{
- struct ov772x_priv *priv = to_ov772x(client);
- u8 pid, ver;
- const char *devname;
-
- /*
- * check and show product ID and manufacturer ID
- */
- pid = i2c_smbus_read_byte_data(client, PID);
- ver = i2c_smbus_read_byte_data(client, VER);
-
- switch (VERSION(pid, ver)) {
- case OV7720:
- devname = "ov7720";
- priv->model = V4L2_IDENT_OV7720;
- break;
- case OV7725:
- devname = "ov7725";
- priv->model = V4L2_IDENT_OV7725;
- break;
- default:
- dev_err(&client->dev,
- "Product ID error %x:%x\n", pid, ver);
- return -ENODEV;
- }
-
- dev_info(&client->dev,
- "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
- devname,
- pid,
- ver,
- i2c_smbus_read_byte_data(client, MIDH),
- i2c_smbus_read_byte_data(client, MIDL));
- return v4l2_ctrl_handler_setup(&priv->hdl);
-}
-
-static const struct v4l2_ctrl_ops ov772x_ctrl_ops = {
- .s_ctrl = ov772x_s_ctrl,
-};
-
-static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
- .g_chip_ident = ov772x_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = ov772x_g_register,
- .s_register = ov772x_s_register,
-#endif
-};
-
-static int ov772x_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index >= ARRAY_SIZE(ov772x_cfmts))
- return -EINVAL;
-
- *code = ov772x_cfmts[index].code;
- return 0;
-}
-
-static int ov772x_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
- V4L2_MBUS_DATA_ACTIVE_HIGH;
- cfg->type = V4L2_MBUS_PARALLEL;
- cfg->flags = soc_camera_apply_board_flags(icl, cfg);
-
- return 0;
-}
-
-static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
- .s_stream = ov772x_s_stream,
- .g_mbus_fmt = ov772x_g_fmt,
- .s_mbus_fmt = ov772x_s_fmt,
- .try_mbus_fmt = ov772x_try_fmt,
- .cropcap = ov772x_cropcap,
- .g_crop = ov772x_g_crop,
- .enum_mbus_fmt = ov772x_enum_fmt,
- .g_mbus_config = ov772x_g_mbus_config,
-};
-
-static struct v4l2_subdev_ops ov772x_subdev_ops = {
- .core = &ov772x_subdev_core_ops,
- .video = &ov772x_subdev_video_ops,
-};
-
-/*
- * i2c_driver function
- */
-
-static int ov772x_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct ov772x_priv *priv;
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- int ret;
-
- if (!icl || !icl->priv) {
- dev_err(&client->dev, "OV772X: missing platform data!\n");
- return -EINVAL;
- }
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_err(&adapter->dev,
- "I2C-Adapter doesn't support "
- "I2C_FUNC_SMBUS_BYTE_DATA\n");
- return -EIO;
- }
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->info = icl->priv;
-
- v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
- v4l2_ctrl_handler_init(&priv->hdl, 3);
- v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
- V4L2_CID_BAND_STOP_FILTER, 0, 256, 1, 0);
- priv->subdev.ctrl_handler = &priv->hdl;
- if (priv->hdl.error) {
- int err = priv->hdl.error;
-
- kfree(priv);
- return err;
- }
-
- ret = ov772x_video_probe(client);
- if (ret) {
- v4l2_ctrl_handler_free(&priv->hdl);
- kfree(priv);
- }
-
- return ret;
-}
-
-static int ov772x_remove(struct i2c_client *client)
-{
- struct ov772x_priv *priv = to_ov772x(client);
-
- v4l2_device_unregister_subdev(&priv->subdev);
- v4l2_ctrl_handler_free(&priv->hdl);
- kfree(priv);
- return 0;
-}
-
-static const struct i2c_device_id ov772x_id[] = {
- { "ov772x", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ov772x_id);
-
-static struct i2c_driver ov772x_i2c_driver = {
- .driver = {
- .name = "ov772x",
- },
- .probe = ov772x_probe,
- .remove = ov772x_remove,
- .id_table = ov772x_id,
-};
-
-module_i2c_driver(ov772x_i2c_driver);
-
-MODULE_DESCRIPTION("SoC Camera driver for ov772x");
-MODULE_AUTHOR("Kuninori Morimoto");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c
deleted file mode 100644
index 9ed4ba4236c..00000000000
--- a/drivers/media/video/ov9640.c
+++ /dev/null
@@ -1,746 +0,0 @@
-/*
- * OmniVision OV96xx Camera Driver
- *
- * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
- *
- * Based on ov772x camera driver:
- *
- * Copyright (C) 2008 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on ov7670 and soc_camera_platform driver,
- *
- * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
- * Copyright (C) 2008 Magnus Damm
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/videodev2.h>
-
-#include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ctrls.h>
-
-#include "ov9640.h"
-
-#define to_ov9640_sensor(sd) container_of(sd, struct ov9640_priv, subdev)
-
-/* default register setup */
-static const struct ov9640_reg ov9640_regs_dflt[] = {
- { OV9640_COM5, OV9640_COM5_SYSCLK | OV9640_COM5_LONGEXP },
- { OV9640_COM6, OV9640_COM6_OPT_BLC | OV9640_COM6_ADBLC_BIAS |
- OV9640_COM6_FMT_RST | OV9640_COM6_ADBLC_OPTEN },
- { OV9640_PSHFT, OV9640_PSHFT_VAL(0x01) },
- { OV9640_ACOM, OV9640_ACOM_2X_ANALOG | OV9640_ACOM_RSVD },
- { OV9640_TSLB, OV9640_TSLB_YUYV_UYVY },
- { OV9640_COM16, OV9640_COM16_RB_AVG },
-
- /* Gamma curve P */
- { 0x6c, 0x40 }, { 0x6d, 0x30 }, { 0x6e, 0x4b }, { 0x6f, 0x60 },
- { 0x70, 0x70 }, { 0x71, 0x70 }, { 0x72, 0x70 }, { 0x73, 0x70 },
- { 0x74, 0x60 }, { 0x75, 0x60 }, { 0x76, 0x50 }, { 0x77, 0x48 },
- { 0x78, 0x3a }, { 0x79, 0x2e }, { 0x7a, 0x28 }, { 0x7b, 0x22 },
-
- /* Gamma curve T */
- { 0x7c, 0x04 }, { 0x7d, 0x07 }, { 0x7e, 0x10 }, { 0x7f, 0x28 },
- { 0x80, 0x36 }, { 0x81, 0x44 }, { 0x82, 0x52 }, { 0x83, 0x60 },
- { 0x84, 0x6c }, { 0x85, 0x78 }, { 0x86, 0x8c }, { 0x87, 0x9e },
- { 0x88, 0xbb }, { 0x89, 0xd2 }, { 0x8a, 0xe6 },
-};
-
-/* Configurations
- * NOTE: for YUV, alter the following registers:
- * COM12 |= OV9640_COM12_YUV_AVG
- *
- * for RGB, alter the following registers:
- * COM7 |= OV9640_COM7_RGB
- * COM13 |= OV9640_COM13_RGB_AVG
- * COM15 |= proper RGB color encoding mode
- */
-static const struct ov9640_reg ov9640_regs_qqcif[] = {
- { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x0f) },
- { OV9640_COM1, OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
- { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
- { OV9640_COM7, OV9640_COM7_QCIF },
- { OV9640_COM12, OV9640_COM12_RSVD },
- { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
- { OV9640_COM15, OV9640_COM15_OR_10F0 },
-};
-
-static const struct ov9640_reg ov9640_regs_qqvga[] = {
- { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
- { OV9640_COM1, OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
- { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
- { OV9640_COM7, OV9640_COM7_QVGA },
- { OV9640_COM12, OV9640_COM12_RSVD },
- { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
- { OV9640_COM15, OV9640_COM15_OR_10F0 },
-};
-
-static const struct ov9640_reg ov9640_regs_qcif[] = {
- { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
- { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
- { OV9640_COM7, OV9640_COM7_QCIF },
- { OV9640_COM12, OV9640_COM12_RSVD },
- { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
- { OV9640_COM15, OV9640_COM15_OR_10F0 },
-};
-
-static const struct ov9640_reg ov9640_regs_qvga[] = {
- { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
- { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
- { OV9640_COM7, OV9640_COM7_QVGA },
- { OV9640_COM12, OV9640_COM12_RSVD },
- { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
- { OV9640_COM15, OV9640_COM15_OR_10F0 },
-};
-
-static const struct ov9640_reg ov9640_regs_cif[] = {
- { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
- { OV9640_COM3, OV9640_COM3_VP },
- { OV9640_COM7, OV9640_COM7_CIF },
- { OV9640_COM12, OV9640_COM12_RSVD },
- { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
- { OV9640_COM15, OV9640_COM15_OR_10F0 },
-};
-
-static const struct ov9640_reg ov9640_regs_vga[] = {
- { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
- { OV9640_COM3, OV9640_COM3_VP },
- { OV9640_COM7, OV9640_COM7_VGA },
- { OV9640_COM12, OV9640_COM12_RSVD },
- { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
- { OV9640_COM15, OV9640_COM15_OR_10F0 },
-};
-
-static const struct ov9640_reg ov9640_regs_sxga[] = {
- { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
- { OV9640_COM3, OV9640_COM3_VP },
- { OV9640_COM7, 0 },
- { OV9640_COM12, OV9640_COM12_RSVD },
- { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
- { OV9640_COM15, OV9640_COM15_OR_10F0 },
-};
-
-static const struct ov9640_reg ov9640_regs_yuv[] = {
- { OV9640_MTX1, 0x58 },
- { OV9640_MTX2, 0x48 },
- { OV9640_MTX3, 0x10 },
- { OV9640_MTX4, 0x28 },
- { OV9640_MTX5, 0x48 },
- { OV9640_MTX6, 0x70 },
- { OV9640_MTX7, 0x40 },
- { OV9640_MTX8, 0x40 },
- { OV9640_MTX9, 0x40 },
- { OV9640_MTXS, 0x0f },
-};
-
-static const struct ov9640_reg ov9640_regs_rgb[] = {
- { OV9640_MTX1, 0x71 },
- { OV9640_MTX2, 0x3e },
- { OV9640_MTX3, 0x0c },
- { OV9640_MTX4, 0x33 },
- { OV9640_MTX5, 0x72 },
- { OV9640_MTX6, 0x00 },
- { OV9640_MTX7, 0x2b },
- { OV9640_MTX8, 0x66 },
- { OV9640_MTX9, 0xd2 },
- { OV9640_MTXS, 0x65 },
-};
-
-static enum v4l2_mbus_pixelcode ov9640_codes[] = {
- V4L2_MBUS_FMT_UYVY8_2X8,
- V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
- V4L2_MBUS_FMT_RGB565_2X8_LE,
-};
-
-/* read a register */
-static int ov9640_reg_read(struct i2c_client *client, u8 reg, u8 *val)
-{
- int ret;
- u8 data = reg;
- struct i2c_msg msg = {
- .addr = client->addr,
- .flags = 0,
- .len = 1,
- .buf = &data,
- };
-
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret < 0)
- goto err;
-
- msg.flags = I2C_M_RD;
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret < 0)
- goto err;
-
- *val = data;
- return 0;
-
-err:
- dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg);
- return ret;
-}
-
-/* write a register */
-static int ov9640_reg_write(struct i2c_client *client, u8 reg, u8 val)
-{
- int ret;
- u8 _val;
- unsigned char data[2] = { reg, val };
- struct i2c_msg msg = {
- .addr = client->addr,
- .flags = 0,
- .len = 2,
- .buf = data,
- };
-
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret < 0) {
- dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg);
- return ret;
- }
-
- /* we have to read the register back ... no idea why, maybe HW bug */
- ret = ov9640_reg_read(client, reg, &_val);
- if (ret)
- dev_err(&client->dev,
- "Failed reading back register 0x%02x!\n", reg);
-
- return 0;
-}
-
-
-/* Read a register, alter its bits, write it back */
-static int ov9640_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 unset)
-{
- u8 val;
- int ret;
-
- ret = ov9640_reg_read(client, reg, &val);
- if (ret) {
- dev_err(&client->dev,
- "[Read]-Modify-Write of register %02x failed!\n", reg);
- return val;
- }
-
- val |= set;
- val &= ~unset;
-
- ret = ov9640_reg_write(client, reg, val);
- if (ret)
- dev_err(&client->dev,
- "Read-Modify-[Write] of register %02x failed!\n", reg);
-
- return ret;
-}
-
-/* Soft reset the camera. This has nothing to do with the RESET pin! */
-static int ov9640_reset(struct i2c_client *client)
-{
- int ret;
-
- ret = ov9640_reg_write(client, OV9640_COM7, OV9640_COM7_SCCB_RESET);
- if (ret)
- dev_err(&client->dev,
- "An error occurred while entering soft reset!\n");
-
- return ret;
-}
-
-/* Start/Stop streaming from the device */
-static int ov9640_s_stream(struct v4l2_subdev *sd, int enable)
-{
- return 0;
-}
-
-/* Set status of additional camera capabilities */
-static int ov9640_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct ov9640_priv *priv = container_of(ctrl->handler, struct ov9640_priv, hdl);
- struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- if (ctrl->val)
- return ov9640_reg_rmw(client, OV9640_MVFP,
- OV9640_MVFP_V, 0);
- return ov9640_reg_rmw(client, OV9640_MVFP, 0, OV9640_MVFP_V);
- case V4L2_CID_HFLIP:
- if (ctrl->val)
- return ov9640_reg_rmw(client, OV9640_MVFP,
- OV9640_MVFP_H, 0);
- return ov9640_reg_rmw(client, OV9640_MVFP, 0, OV9640_MVFP_H);
- }
- return -EINVAL;
-}
-
-/* Get chip identification */
-static int ov9640_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct ov9640_priv *priv = to_ov9640_sensor(sd);
-
- id->ident = priv->model;
- id->revision = priv->revision;
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ov9640_get_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
- u8 val;
-
- if (reg->reg & ~0xff)
- return -EINVAL;
-
- reg->size = 1;
-
- ret = ov9640_reg_read(client, reg->reg, &val);
- if (ret)
- return ret;
-
- reg->val = (__u64)val;
-
- return 0;
-}
-
-static int ov9640_set_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->reg & ~0xff || reg->val & ~0xff)
- return -EINVAL;
-
- return ov9640_reg_write(client, reg->reg, reg->val);
-}
-#endif
-
-/* select nearest higher resolution for capture */
-static void ov9640_res_roundup(u32 *width, u32 *height)
-{
- int i;
- enum { QQCIF, QQVGA, QCIF, QVGA, CIF, VGA, SXGA };
- int res_x[] = { 88, 160, 176, 320, 352, 640, 1280 };
- int res_y[] = { 72, 120, 144, 240, 288, 480, 960 };
-
- for (i = 0; i < ARRAY_SIZE(res_x); i++) {
- if (res_x[i] >= *width && res_y[i] >= *height) {
- *width = res_x[i];
- *height = res_y[i];
- return;
- }
- }
-
- *width = res_x[SXGA];
- *height = res_y[SXGA];
-}
-
-/* Prepare necessary register changes depending on color encoding */
-static void ov9640_alter_regs(enum v4l2_mbus_pixelcode code,
- struct ov9640_reg_alt *alt)
-{
- switch (code) {
- default:
- case V4L2_MBUS_FMT_UYVY8_2X8:
- alt->com12 = OV9640_COM12_YUV_AVG;
- alt->com13 = OV9640_COM13_Y_DELAY_EN |
- OV9640_COM13_YUV_DLY(0x01);
- break;
- case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
- alt->com7 = OV9640_COM7_RGB;
- alt->com13 = OV9640_COM13_RGB_AVG;
- alt->com15 = OV9640_COM15_RGB_555;
- break;
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- alt->com7 = OV9640_COM7_RGB;
- alt->com13 = OV9640_COM13_RGB_AVG;
- alt->com15 = OV9640_COM15_RGB_565;
- break;
- };
-}
-
-/* Setup registers according to resolution and color encoding */
-static int ov9640_write_regs(struct i2c_client *client, u32 width,
- enum v4l2_mbus_pixelcode code, struct ov9640_reg_alt *alts)
-{
- const struct ov9640_reg *ov9640_regs, *matrix_regs;
- int ov9640_regs_len, matrix_regs_len;
- int i, ret;
- u8 val;
-
- /* select register configuration for given resolution */
- switch (width) {
- case W_QQCIF:
- ov9640_regs = ov9640_regs_qqcif;
- ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qqcif);
- break;
- case W_QQVGA:
- ov9640_regs = ov9640_regs_qqvga;
- ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qqvga);
- break;
- case W_QCIF:
- ov9640_regs = ov9640_regs_qcif;
- ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qcif);
- break;
- case W_QVGA:
- ov9640_regs = ov9640_regs_qvga;
- ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qvga);
- break;
- case W_CIF:
- ov9640_regs = ov9640_regs_cif;
- ov9640_regs_len = ARRAY_SIZE(ov9640_regs_cif);
- break;
- case W_VGA:
- ov9640_regs = ov9640_regs_vga;
- ov9640_regs_len = ARRAY_SIZE(ov9640_regs_vga);
- break;
- case W_SXGA:
- ov9640_regs = ov9640_regs_sxga;
- ov9640_regs_len = ARRAY_SIZE(ov9640_regs_sxga);
- break;
- default:
- dev_err(&client->dev, "Failed to select resolution!\n");
- return -EINVAL;
- }
-
- /* select color matrix configuration for given color encoding */
- if (code == V4L2_MBUS_FMT_UYVY8_2X8) {
- matrix_regs = ov9640_regs_yuv;
- matrix_regs_len = ARRAY_SIZE(ov9640_regs_yuv);
- } else {
- matrix_regs = ov9640_regs_rgb;
- matrix_regs_len = ARRAY_SIZE(ov9640_regs_rgb);
- }
-
- /* write register settings into the module */
- for (i = 0; i < ov9640_regs_len; i++) {
- val = ov9640_regs[i].val;
-
- switch (ov9640_regs[i].reg) {
- case OV9640_COM7:
- val |= alts->com7;
- break;
- case OV9640_COM12:
- val |= alts->com12;
- break;
- case OV9640_COM13:
- val |= alts->com13;
- break;
- case OV9640_COM15:
- val |= alts->com15;
- break;
- }
-
- ret = ov9640_reg_write(client, ov9640_regs[i].reg, val);
- if (ret)
- return ret;
- }
-
- /* write color matrix configuration into the module */
- for (i = 0; i < matrix_regs_len; i++) {
- ret = ov9640_reg_write(client, matrix_regs[i].reg,
- matrix_regs[i].val);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-/* program default register values */
-static int ov9640_prog_dflt(struct i2c_client *client)
-{
- int i, ret;
-
- for (i = 0; i < ARRAY_SIZE(ov9640_regs_dflt); i++) {
- ret = ov9640_reg_write(client, ov9640_regs_dflt[i].reg,
- ov9640_regs_dflt[i].val);
- if (ret)
- return ret;
- }
-
- /* wait for the changes to actually happen, 140ms are not enough yet */
- mdelay(150);
-
- return 0;
-}
-
-/* set the format we will capture in */
-static int ov9640_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov9640_reg_alt alts = {0};
- enum v4l2_colorspace cspace;
- enum v4l2_mbus_pixelcode code = mf->code;
- int ret;
-
- ov9640_res_roundup(&mf->width, &mf->height);
- ov9640_alter_regs(mf->code, &alts);
-
- ov9640_reset(client);
-
- ret = ov9640_prog_dflt(client);
- if (ret)
- return ret;
-
- switch (code) {
- case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- cspace = V4L2_COLORSPACE_SRGB;
- break;
- default:
- code = V4L2_MBUS_FMT_UYVY8_2X8;
- case V4L2_MBUS_FMT_UYVY8_2X8:
- cspace = V4L2_COLORSPACE_JPEG;
- }
-
- ret = ov9640_write_regs(client, mf->width, code, &alts);
- if (!ret) {
- mf->code = code;
- mf->colorspace = cspace;
- }
-
- return ret;
-}
-
-static int ov9640_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- ov9640_res_roundup(&mf->width, &mf->height);
-
- mf->field = V4L2_FIELD_NONE;
-
- switch (mf->code) {
- case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- mf->colorspace = V4L2_COLORSPACE_SRGB;
- break;
- default:
- mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
- case V4L2_MBUS_FMT_UYVY8_2X8:
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- }
-
- return 0;
-}
-
-static int ov9640_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index >= ARRAY_SIZE(ov9640_codes))
- return -EINVAL;
-
- *code = ov9640_codes[index];
- return 0;
-}
-
-static int ov9640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- a->c.left = 0;
- a->c.top = 0;
- a->c.width = W_SXGA;
- a->c.height = H_SXGA;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = W_SXGA;
- a->bounds.height = H_SXGA;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int ov9640_video_probe(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct ov9640_priv *priv = to_ov9640_sensor(sd);
- u8 pid, ver, midh, midl;
- const char *devname;
- int ret = 0;
-
- /*
- * check and show product ID and manufacturer ID
- */
-
- ret = ov9640_reg_read(client, OV9640_PID, &pid);
- if (!ret)
- ret = ov9640_reg_read(client, OV9640_VER, &ver);
- if (!ret)
- ret = ov9640_reg_read(client, OV9640_MIDH, &midh);
- if (!ret)
- ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
- if (ret)
- return ret;
-
- switch (VERSION(pid, ver)) {
- case OV9640_V2:
- devname = "ov9640";
- priv->model = V4L2_IDENT_OV9640;
- priv->revision = 2;
- break;
- case OV9640_V3:
- devname = "ov9640";
- priv->model = V4L2_IDENT_OV9640;
- priv->revision = 3;
- break;
- default:
- dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
- return -ENODEV;
- }
-
- dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
- devname, pid, ver, midh, midl);
-
- return v4l2_ctrl_handler_setup(&priv->hdl);
-}
-
-static const struct v4l2_ctrl_ops ov9640_ctrl_ops = {
- .s_ctrl = ov9640_s_ctrl,
-};
-
-static struct v4l2_subdev_core_ops ov9640_core_ops = {
- .g_chip_ident = ov9640_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = ov9640_get_register,
- .s_register = ov9640_set_register,
-#endif
-
-};
-
-/* Request bus settings on camera side */
-static int ov9640_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
- V4L2_MBUS_DATA_ACTIVE_HIGH;
- cfg->type = V4L2_MBUS_PARALLEL;
- cfg->flags = soc_camera_apply_board_flags(icl, cfg);
-
- return 0;
-}
-
-static struct v4l2_subdev_video_ops ov9640_video_ops = {
- .s_stream = ov9640_s_stream,
- .s_mbus_fmt = ov9640_s_fmt,
- .try_mbus_fmt = ov9640_try_fmt,
- .enum_mbus_fmt = ov9640_enum_fmt,
- .cropcap = ov9640_cropcap,
- .g_crop = ov9640_g_crop,
- .g_mbus_config = ov9640_g_mbus_config,
-};
-
-static struct v4l2_subdev_ops ov9640_subdev_ops = {
- .core = &ov9640_core_ops,
- .video = &ov9640_video_ops,
-};
-
-/*
- * i2c_driver function
- */
-static int ov9640_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct ov9640_priv *priv;
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- int ret;
-
- if (!icl) {
- dev_err(&client->dev, "Missing platform_data for driver\n");
- return -EINVAL;
- }
-
- priv = kzalloc(sizeof(struct ov9640_priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&client->dev,
- "Failed to allocate memory for private data!\n");
- return -ENOMEM;
- }
-
- v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops);
-
- v4l2_ctrl_handler_init(&priv->hdl, 2);
- v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- priv->subdev.ctrl_handler = &priv->hdl;
- if (priv->hdl.error) {
- int err = priv->hdl.error;
-
- kfree(priv);
- return err;
- }
-
- ret = ov9640_video_probe(client);
-
- if (ret) {
- v4l2_ctrl_handler_free(&priv->hdl);
- kfree(priv);
- }
-
- return ret;
-}
-
-static int ov9640_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct ov9640_priv *priv = to_ov9640_sensor(sd);
-
- v4l2_device_unregister_subdev(&priv->subdev);
- v4l2_ctrl_handler_free(&priv->hdl);
- kfree(priv);
- return 0;
-}
-
-static const struct i2c_device_id ov9640_id[] = {
- { "ov9640", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ov9640_id);
-
-static struct i2c_driver ov9640_i2c_driver = {
- .driver = {
- .name = "ov9640",
- },
- .probe = ov9640_probe,
- .remove = ov9640_remove,
- .id_table = ov9640_id,
-};
-
-module_i2c_driver(ov9640_i2c_driver);
-
-MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV96xx");
-MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/ov9640.h b/drivers/media/video/ov9640.h
deleted file mode 100644
index 6b33a972c83..00000000000
--- a/drivers/media/video/ov9640.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * OmniVision OV96xx Camera Header File
- *
- * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __DRIVERS_MEDIA_VIDEO_OV9640_H__
-#define __DRIVERS_MEDIA_VIDEO_OV9640_H__
-
-/* Register definitions */
-#define OV9640_GAIN 0x00
-#define OV9640_BLUE 0x01
-#define OV9640_RED 0x02
-#define OV9640_VFER 0x03
-#define OV9640_COM1 0x04
-#define OV9640_BAVE 0x05
-#define OV9640_GEAVE 0x06
-#define OV9640_RSID 0x07
-#define OV9640_RAVE 0x08
-#define OV9640_COM2 0x09
-#define OV9640_PID 0x0a
-#define OV9640_VER 0x0b
-#define OV9640_COM3 0x0c
-#define OV9640_COM4 0x0d
-#define OV9640_COM5 0x0e
-#define OV9640_COM6 0x0f
-#define OV9640_AECH 0x10
-#define OV9640_CLKRC 0x11
-#define OV9640_COM7 0x12
-#define OV9640_COM8 0x13
-#define OV9640_COM9 0x14
-#define OV9640_COM10 0x15
-/* 0x16 - RESERVED */
-#define OV9640_HSTART 0x17
-#define OV9640_HSTOP 0x18
-#define OV9640_VSTART 0x19
-#define OV9640_VSTOP 0x1a
-#define OV9640_PSHFT 0x1b
-#define OV9640_MIDH 0x1c
-#define OV9640_MIDL 0x1d
-#define OV9640_MVFP 0x1e
-#define OV9640_LAEC 0x1f
-#define OV9640_BOS 0x20
-#define OV9640_GBOS 0x21
-#define OV9640_GROS 0x22
-#define OV9640_ROS 0x23
-#define OV9640_AEW 0x24
-#define OV9640_AEB 0x25
-#define OV9640_VPT 0x26
-#define OV9640_BBIAS 0x27
-#define OV9640_GBBIAS 0x28
-/* 0x29 - RESERVED */
-#define OV9640_EXHCH 0x2a
-#define OV9640_EXHCL 0x2b
-#define OV9640_RBIAS 0x2c
-#define OV9640_ADVFL 0x2d
-#define OV9640_ADVFH 0x2e
-#define OV9640_YAVE 0x2f
-#define OV9640_HSYST 0x30
-#define OV9640_HSYEN 0x31
-#define OV9640_HREF 0x32
-#define OV9640_CHLF 0x33
-#define OV9640_ARBLM 0x34
-/* 0x35..0x36 - RESERVED */
-#define OV9640_ADC 0x37
-#define OV9640_ACOM 0x38
-#define OV9640_OFON 0x39
-#define OV9640_TSLB 0x3a
-#define OV9640_COM11 0x3b
-#define OV9640_COM12 0x3c
-#define OV9640_COM13 0x3d
-#define OV9640_COM14 0x3e
-#define OV9640_EDGE 0x3f
-#define OV9640_COM15 0x40
-#define OV9640_COM16 0x41
-#define OV9640_COM17 0x42
-/* 0x43..0x4e - RESERVED */
-#define OV9640_MTX1 0x4f
-#define OV9640_MTX2 0x50
-#define OV9640_MTX3 0x51
-#define OV9640_MTX4 0x52
-#define OV9640_MTX5 0x53
-#define OV9640_MTX6 0x54
-#define OV9640_MTX7 0x55
-#define OV9640_MTX8 0x56
-#define OV9640_MTX9 0x57
-#define OV9640_MTXS 0x58
-/* 0x59..0x61 - RESERVED */
-#define OV9640_LCC1 0x62
-#define OV9640_LCC2 0x63
-#define OV9640_LCC3 0x64
-#define OV9640_LCC4 0x65
-#define OV9640_LCC5 0x66
-#define OV9640_MANU 0x67
-#define OV9640_MANV 0x68
-#define OV9640_HV 0x69
-#define OV9640_MBD 0x6a
-#define OV9640_DBLV 0x6b
-#define OV9640_GSP 0x6c /* ... till 0x7b */
-#define OV9640_GST 0x7c /* ... till 0x8a */
-
-#define OV9640_CLKRC_DPLL_EN 0x80
-#define OV9640_CLKRC_DIRECT 0x40
-#define OV9640_CLKRC_DIV(x) ((x) & 0x3f)
-
-#define OV9640_PSHFT_VAL(x) ((x) & 0xff)
-
-#define OV9640_ACOM_2X_ANALOG 0x80
-#define OV9640_ACOM_RSVD 0x12
-
-#define OV9640_MVFP_V 0x10
-#define OV9640_MVFP_H 0x20
-
-#define OV9640_COM1_HREF_NOSKIP 0x00
-#define OV9640_COM1_HREF_2SKIP 0x04
-#define OV9640_COM1_HREF_3SKIP 0x08
-#define OV9640_COM1_QQFMT 0x20
-
-#define OV9640_COM2_SSM 0x10
-
-#define OV9640_COM3_VP 0x04
-
-#define OV9640_COM4_QQ_VP 0x80
-#define OV9640_COM4_RSVD 0x40
-
-#define OV9640_COM5_SYSCLK 0x80
-#define OV9640_COM5_LONGEXP 0x01
-
-#define OV9640_COM6_OPT_BLC 0x40
-#define OV9640_COM6_ADBLC_BIAS 0x08
-#define OV9640_COM6_FMT_RST 0x82
-#define OV9640_COM6_ADBLC_OPTEN 0x01
-
-#define OV9640_COM7_RAW_RGB 0x01
-#define OV9640_COM7_RGB 0x04
-#define OV9640_COM7_QCIF 0x08
-#define OV9640_COM7_QVGA 0x10
-#define OV9640_COM7_CIF 0x20
-#define OV9640_COM7_VGA 0x40
-#define OV9640_COM7_SCCB_RESET 0x80
-
-#define OV9640_TSLB_YVYU_YUYV 0x04
-#define OV9640_TSLB_YUYV_UYVY 0x08
-
-#define OV9640_COM12_YUV_AVG 0x04
-#define OV9640_COM12_RSVD 0x40
-
-#define OV9640_COM13_GAMMA_NONE 0x00
-#define OV9640_COM13_GAMMA_Y 0x40
-#define OV9640_COM13_GAMMA_RAW 0x80
-#define OV9640_COM13_RGB_AVG 0x20
-#define OV9640_COM13_MATRIX_EN 0x10
-#define OV9640_COM13_Y_DELAY_EN 0x08
-#define OV9640_COM13_YUV_DLY(x) ((x) & 0x07)
-
-#define OV9640_COM15_OR_00FF 0x00
-#define OV9640_COM15_OR_01FE 0x40
-#define OV9640_COM15_OR_10F0 0xc0
-#define OV9640_COM15_RGB_NORM 0x00
-#define OV9640_COM15_RGB_565 0x10
-#define OV9640_COM15_RGB_555 0x30
-
-#define OV9640_COM16_RB_AVG 0x01
-
-/* IDs */
-#define OV9640_V2 0x9648
-#define OV9640_V3 0x9649
-#define VERSION(pid, ver) (((pid) << 8) | ((ver) & 0xFF))
-
-/* supported resolutions */
-enum {
- W_QQCIF = 88,
- W_QQVGA = 160,
- W_QCIF = 176,
- W_QVGA = 320,
- W_CIF = 352,
- W_VGA = 640,
- W_SXGA = 1280
-};
-#define H_SXGA 960
-
-/* Misc. structures */
-struct ov9640_reg_alt {
- u8 com7;
- u8 com12;
- u8 com13;
- u8 com15;
-};
-
-struct ov9640_reg {
- u8 reg;
- u8 val;
-};
-
-struct ov9640_priv {
- struct v4l2_subdev subdev;
- struct v4l2_ctrl_handler hdl;
-
- int model;
- int revision;
-};
-
-#endif /* __DRIVERS_MEDIA_VIDEO_OV9640_H__ */
diff --git a/drivers/media/video/ov9740.c b/drivers/media/video/ov9740.c
deleted file mode 100644
index 3eb07c22516..00000000000
--- a/drivers/media/video/ov9740.c
+++ /dev/null
@@ -1,1005 +0,0 @@
-/*
- * OmniVision OV9740 Camera Driver
- *
- * Copyright (C) 2011 NVIDIA Corporation
- *
- * Based on ov9640 camera driver.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/v4l2-mediabus.h>
-
-#include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-
-#define to_ov9740(sd) container_of(sd, struct ov9740_priv, subdev)
-
-/* General Status Registers */
-#define OV9740_MODEL_ID_HI 0x0000
-#define OV9740_MODEL_ID_LO 0x0001
-#define OV9740_REVISION_NUMBER 0x0002
-#define OV9740_MANUFACTURER_ID 0x0003
-#define OV9740_SMIA_VERSION 0x0004
-
-/* General Setup Registers */
-#define OV9740_MODE_SELECT 0x0100
-#define OV9740_IMAGE_ORT 0x0101
-#define OV9740_SOFTWARE_RESET 0x0103
-#define OV9740_GRP_PARAM_HOLD 0x0104
-#define OV9740_MSK_CORRUP_FM 0x0105
-
-/* Timing Setting */
-#define OV9740_FRM_LENGTH_LN_HI 0x0340 /* VTS */
-#define OV9740_FRM_LENGTH_LN_LO 0x0341 /* VTS */
-#define OV9740_LN_LENGTH_PCK_HI 0x0342 /* HTS */
-#define OV9740_LN_LENGTH_PCK_LO 0x0343 /* HTS */
-#define OV9740_X_ADDR_START_HI 0x0344
-#define OV9740_X_ADDR_START_LO 0x0345
-#define OV9740_Y_ADDR_START_HI 0x0346
-#define OV9740_Y_ADDR_START_LO 0x0347
-#define OV9740_X_ADDR_END_HI 0x0348
-#define OV9740_X_ADDR_END_LO 0x0349
-#define OV9740_Y_ADDR_END_HI 0x034a
-#define OV9740_Y_ADDR_END_LO 0x034b
-#define OV9740_X_OUTPUT_SIZE_HI 0x034c
-#define OV9740_X_OUTPUT_SIZE_LO 0x034d
-#define OV9740_Y_OUTPUT_SIZE_HI 0x034e
-#define OV9740_Y_OUTPUT_SIZE_LO 0x034f
-
-/* IO Control Registers */
-#define OV9740_IO_CREL00 0x3002
-#define OV9740_IO_CREL01 0x3004
-#define OV9740_IO_CREL02 0x3005
-#define OV9740_IO_OUTPUT_SEL01 0x3026
-#define OV9740_IO_OUTPUT_SEL02 0x3027
-
-/* AWB Registers */
-#define OV9740_AWB_MANUAL_CTRL 0x3406
-
-/* Analog Control Registers */
-#define OV9740_ANALOG_CTRL01 0x3601
-#define OV9740_ANALOG_CTRL02 0x3602
-#define OV9740_ANALOG_CTRL03 0x3603
-#define OV9740_ANALOG_CTRL04 0x3604
-#define OV9740_ANALOG_CTRL10 0x3610
-#define OV9740_ANALOG_CTRL12 0x3612
-#define OV9740_ANALOG_CTRL15 0x3615
-#define OV9740_ANALOG_CTRL20 0x3620
-#define OV9740_ANALOG_CTRL21 0x3621
-#define OV9740_ANALOG_CTRL22 0x3622
-#define OV9740_ANALOG_CTRL30 0x3630
-#define OV9740_ANALOG_CTRL31 0x3631
-#define OV9740_ANALOG_CTRL32 0x3632
-#define OV9740_ANALOG_CTRL33 0x3633
-
-/* Sensor Control */
-#define OV9740_SENSOR_CTRL03 0x3703
-#define OV9740_SENSOR_CTRL04 0x3704
-#define OV9740_SENSOR_CTRL05 0x3705
-#define OV9740_SENSOR_CTRL07 0x3707
-
-/* Timing Control */
-#define OV9740_TIMING_CTRL17 0x3817
-#define OV9740_TIMING_CTRL19 0x3819
-#define OV9740_TIMING_CTRL33 0x3833
-#define OV9740_TIMING_CTRL35 0x3835
-
-/* Banding Filter */
-#define OV9740_AEC_MAXEXPO_60_H 0x3a02
-#define OV9740_AEC_MAXEXPO_60_L 0x3a03
-#define OV9740_AEC_B50_STEP_HI 0x3a08
-#define OV9740_AEC_B50_STEP_LO 0x3a09
-#define OV9740_AEC_B60_STEP_HI 0x3a0a
-#define OV9740_AEC_B60_STEP_LO 0x3a0b
-#define OV9740_AEC_CTRL0D 0x3a0d
-#define OV9740_AEC_CTRL0E 0x3a0e
-#define OV9740_AEC_MAXEXPO_50_H 0x3a14
-#define OV9740_AEC_MAXEXPO_50_L 0x3a15
-
-/* AEC/AGC Control */
-#define OV9740_AEC_ENABLE 0x3503
-#define OV9740_GAIN_CEILING_01 0x3a18
-#define OV9740_GAIN_CEILING_02 0x3a19
-#define OV9740_AEC_HI_THRESHOLD 0x3a11
-#define OV9740_AEC_3A1A 0x3a1a
-#define OV9740_AEC_CTRL1B_WPT2 0x3a1b
-#define OV9740_AEC_CTRL0F_WPT 0x3a0f
-#define OV9740_AEC_CTRL10_BPT 0x3a10
-#define OV9740_AEC_CTRL1E_BPT2 0x3a1e
-#define OV9740_AEC_LO_THRESHOLD 0x3a1f
-
-/* BLC Control */
-#define OV9740_BLC_AUTO_ENABLE 0x4002
-#define OV9740_BLC_MODE 0x4005
-
-/* VFIFO */
-#define OV9740_VFIFO_READ_START_HI 0x4608
-#define OV9740_VFIFO_READ_START_LO 0x4609
-
-/* DVP Control */
-#define OV9740_DVP_VSYNC_CTRL02 0x4702
-#define OV9740_DVP_VSYNC_MODE 0x4704
-#define OV9740_DVP_VSYNC_CTRL06 0x4706
-
-/* PLL Setting */
-#define OV9740_PLL_MODE_CTRL01 0x3104
-#define OV9740_PRE_PLL_CLK_DIV 0x0305
-#define OV9740_PLL_MULTIPLIER 0x0307
-#define OV9740_VT_SYS_CLK_DIV 0x0303
-#define OV9740_VT_PIX_CLK_DIV 0x0301
-#define OV9740_PLL_CTRL3010 0x3010
-#define OV9740_VFIFO_CTRL00 0x460e
-
-/* ISP Control */
-#define OV9740_ISP_CTRL00 0x5000
-#define OV9740_ISP_CTRL01 0x5001
-#define OV9740_ISP_CTRL03 0x5003
-#define OV9740_ISP_CTRL05 0x5005
-#define OV9740_ISP_CTRL12 0x5012
-#define OV9740_ISP_CTRL19 0x5019
-#define OV9740_ISP_CTRL1A 0x501a
-#define OV9740_ISP_CTRL1E 0x501e
-#define OV9740_ISP_CTRL1F 0x501f
-#define OV9740_ISP_CTRL20 0x5020
-#define OV9740_ISP_CTRL21 0x5021
-
-/* AWB */
-#define OV9740_AWB_CTRL00 0x5180
-#define OV9740_AWB_CTRL01 0x5181
-#define OV9740_AWB_CTRL02 0x5182
-#define OV9740_AWB_CTRL03 0x5183
-#define OV9740_AWB_ADV_CTRL01 0x5184
-#define OV9740_AWB_ADV_CTRL02 0x5185
-#define OV9740_AWB_ADV_CTRL03 0x5186
-#define OV9740_AWB_ADV_CTRL04 0x5187
-#define OV9740_AWB_ADV_CTRL05 0x5188
-#define OV9740_AWB_ADV_CTRL06 0x5189
-#define OV9740_AWB_ADV_CTRL07 0x518a
-#define OV9740_AWB_ADV_CTRL08 0x518b
-#define OV9740_AWB_ADV_CTRL09 0x518c
-#define OV9740_AWB_ADV_CTRL10 0x518d
-#define OV9740_AWB_ADV_CTRL11 0x518e
-#define OV9740_AWB_CTRL0F 0x518f
-#define OV9740_AWB_CTRL10 0x5190
-#define OV9740_AWB_CTRL11 0x5191
-#define OV9740_AWB_CTRL12 0x5192
-#define OV9740_AWB_CTRL13 0x5193
-#define OV9740_AWB_CTRL14 0x5194
-
-/* MIPI Control */
-#define OV9740_MIPI_CTRL00 0x4800
-#define OV9740_MIPI_3837 0x3837
-#define OV9740_MIPI_CTRL01 0x4801
-#define OV9740_MIPI_CTRL03 0x4803
-#define OV9740_MIPI_CTRL05 0x4805
-#define OV9740_VFIFO_RD_CTRL 0x4601
-#define OV9740_MIPI_CTRL_3012 0x3012
-#define OV9740_SC_CMMM_MIPI_CTR 0x3014
-
-#define OV9740_MAX_WIDTH 1280
-#define OV9740_MAX_HEIGHT 720
-
-/* Misc. structures */
-struct ov9740_reg {
- u16 reg;
- u8 val;
-};
-
-struct ov9740_priv {
- struct v4l2_subdev subdev;
- struct v4l2_ctrl_handler hdl;
-
- int ident;
- u16 model;
- u8 revision;
- u8 manid;
- u8 smiaver;
-
- bool flag_vflip;
- bool flag_hflip;
-
- /* For suspend/resume. */
- struct v4l2_mbus_framefmt current_mf;
- bool current_enable;
-};
-
-static const struct ov9740_reg ov9740_defaults[] = {
- /* Software Reset */
- { OV9740_SOFTWARE_RESET, 0x01 },
-
- /* Banding Filter */
- { OV9740_AEC_B50_STEP_HI, 0x00 },
- { OV9740_AEC_B50_STEP_LO, 0xe8 },
- { OV9740_AEC_CTRL0E, 0x03 },
- { OV9740_AEC_MAXEXPO_50_H, 0x15 },
- { OV9740_AEC_MAXEXPO_50_L, 0xc6 },
- { OV9740_AEC_B60_STEP_HI, 0x00 },
- { OV9740_AEC_B60_STEP_LO, 0xc0 },
- { OV9740_AEC_CTRL0D, 0x04 },
- { OV9740_AEC_MAXEXPO_60_H, 0x18 },
- { OV9740_AEC_MAXEXPO_60_L, 0x20 },
-
- /* LC */
- { 0x5842, 0x02 }, { 0x5843, 0x5e }, { 0x5844, 0x04 }, { 0x5845, 0x32 },
- { 0x5846, 0x03 }, { 0x5847, 0x29 }, { 0x5848, 0x02 }, { 0x5849, 0xcc },
-
- /* Un-documented OV9740 registers */
- { 0x5800, 0x29 }, { 0x5801, 0x25 }, { 0x5802, 0x20 }, { 0x5803, 0x21 },
- { 0x5804, 0x26 }, { 0x5805, 0x2e }, { 0x5806, 0x11 }, { 0x5807, 0x0c },
- { 0x5808, 0x09 }, { 0x5809, 0x0a }, { 0x580a, 0x0e }, { 0x580b, 0x16 },
- { 0x580c, 0x06 }, { 0x580d, 0x02 }, { 0x580e, 0x00 }, { 0x580f, 0x00 },
- { 0x5810, 0x04 }, { 0x5811, 0x0a }, { 0x5812, 0x05 }, { 0x5813, 0x02 },
- { 0x5814, 0x00 }, { 0x5815, 0x00 }, { 0x5816, 0x03 }, { 0x5817, 0x09 },
- { 0x5818, 0x0f }, { 0x5819, 0x0a }, { 0x581a, 0x07 }, { 0x581b, 0x08 },
- { 0x581c, 0x0b }, { 0x581d, 0x14 }, { 0x581e, 0x28 }, { 0x581f, 0x23 },
- { 0x5820, 0x1d }, { 0x5821, 0x1e }, { 0x5822, 0x24 }, { 0x5823, 0x2a },
- { 0x5824, 0x4f }, { 0x5825, 0x6f }, { 0x5826, 0x5f }, { 0x5827, 0x7f },
- { 0x5828, 0x9f }, { 0x5829, 0x5f }, { 0x582a, 0x8f }, { 0x582b, 0x9e },
- { 0x582c, 0x8f }, { 0x582d, 0x9f }, { 0x582e, 0x4f }, { 0x582f, 0x87 },
- { 0x5830, 0x86 }, { 0x5831, 0x97 }, { 0x5832, 0xae }, { 0x5833, 0x3f },
- { 0x5834, 0x8e }, { 0x5835, 0x7c }, { 0x5836, 0x7e }, { 0x5837, 0xaf },
- { 0x5838, 0x8f }, { 0x5839, 0x8f }, { 0x583a, 0x9f }, { 0x583b, 0x7f },
- { 0x583c, 0x5f },
-
- /* Y Gamma */
- { 0x5480, 0x07 }, { 0x5481, 0x18 }, { 0x5482, 0x2c }, { 0x5483, 0x4e },
- { 0x5484, 0x5e }, { 0x5485, 0x6b }, { 0x5486, 0x77 }, { 0x5487, 0x82 },
- { 0x5488, 0x8c }, { 0x5489, 0x95 }, { 0x548a, 0xa4 }, { 0x548b, 0xb1 },
- { 0x548c, 0xc6 }, { 0x548d, 0xd8 }, { 0x548e, 0xe9 },
-
- /* UV Gamma */
- { 0x5490, 0x0f }, { 0x5491, 0xff }, { 0x5492, 0x0d }, { 0x5493, 0x05 },
- { 0x5494, 0x07 }, { 0x5495, 0x1a }, { 0x5496, 0x04 }, { 0x5497, 0x01 },
- { 0x5498, 0x03 }, { 0x5499, 0x53 }, { 0x549a, 0x02 }, { 0x549b, 0xeb },
- { 0x549c, 0x02 }, { 0x549d, 0xa0 }, { 0x549e, 0x02 }, { 0x549f, 0x67 },
- { 0x54a0, 0x02 }, { 0x54a1, 0x3b }, { 0x54a2, 0x02 }, { 0x54a3, 0x18 },
- { 0x54a4, 0x01 }, { 0x54a5, 0xe7 }, { 0x54a6, 0x01 }, { 0x54a7, 0xc3 },
- { 0x54a8, 0x01 }, { 0x54a9, 0x94 }, { 0x54aa, 0x01 }, { 0x54ab, 0x72 },
- { 0x54ac, 0x01 }, { 0x54ad, 0x57 },
-
- /* AWB */
- { OV9740_AWB_CTRL00, 0xf0 },
- { OV9740_AWB_CTRL01, 0x00 },
- { OV9740_AWB_CTRL02, 0x41 },
- { OV9740_AWB_CTRL03, 0x42 },
- { OV9740_AWB_ADV_CTRL01, 0x8a },
- { OV9740_AWB_ADV_CTRL02, 0x61 },
- { OV9740_AWB_ADV_CTRL03, 0xce },
- { OV9740_AWB_ADV_CTRL04, 0xa8 },
- { OV9740_AWB_ADV_CTRL05, 0x17 },
- { OV9740_AWB_ADV_CTRL06, 0x1f },
- { OV9740_AWB_ADV_CTRL07, 0x27 },
- { OV9740_AWB_ADV_CTRL08, 0x41 },
- { OV9740_AWB_ADV_CTRL09, 0x34 },
- { OV9740_AWB_ADV_CTRL10, 0xf0 },
- { OV9740_AWB_ADV_CTRL11, 0x10 },
- { OV9740_AWB_CTRL0F, 0xff },
- { OV9740_AWB_CTRL10, 0x00 },
- { OV9740_AWB_CTRL11, 0xff },
- { OV9740_AWB_CTRL12, 0x00 },
- { OV9740_AWB_CTRL13, 0xff },
- { OV9740_AWB_CTRL14, 0x00 },
-
- /* CIP */
- { 0x530d, 0x12 },
-
- /* CMX */
- { 0x5380, 0x01 }, { 0x5381, 0x00 }, { 0x5382, 0x00 }, { 0x5383, 0x17 },
- { 0x5384, 0x00 }, { 0x5385, 0x01 }, { 0x5386, 0x00 }, { 0x5387, 0x00 },
- { 0x5388, 0x00 }, { 0x5389, 0xe0 }, { 0x538a, 0x00 }, { 0x538b, 0x20 },
- { 0x538c, 0x00 }, { 0x538d, 0x00 }, { 0x538e, 0x00 }, { 0x538f, 0x16 },
- { 0x5390, 0x00 }, { 0x5391, 0x9c }, { 0x5392, 0x00 }, { 0x5393, 0xa0 },
- { 0x5394, 0x18 },
-
- /* 50/60 Detection */
- { 0x3c0a, 0x9c }, { 0x3c0b, 0x3f },
-
- /* Output Select */
- { OV9740_IO_OUTPUT_SEL01, 0x00 },
- { OV9740_IO_OUTPUT_SEL02, 0x00 },
- { OV9740_IO_CREL00, 0x00 },
- { OV9740_IO_CREL01, 0x00 },
- { OV9740_IO_CREL02, 0x00 },
-
- /* AWB Control */
- { OV9740_AWB_MANUAL_CTRL, 0x00 },
-
- /* Analog Control */
- { OV9740_ANALOG_CTRL03, 0xaa },
- { OV9740_ANALOG_CTRL32, 0x2f },
- { OV9740_ANALOG_CTRL20, 0x66 },
- { OV9740_ANALOG_CTRL21, 0xc0 },
- { OV9740_ANALOG_CTRL31, 0x52 },
- { OV9740_ANALOG_CTRL33, 0x50 },
- { OV9740_ANALOG_CTRL30, 0xca },
- { OV9740_ANALOG_CTRL04, 0x0c },
- { OV9740_ANALOG_CTRL01, 0x40 },
- { OV9740_ANALOG_CTRL02, 0x16 },
- { OV9740_ANALOG_CTRL10, 0xa1 },
- { OV9740_ANALOG_CTRL12, 0x24 },
- { OV9740_ANALOG_CTRL22, 0x9f },
- { OV9740_ANALOG_CTRL15, 0xf0 },
-
- /* Sensor Control */
- { OV9740_SENSOR_CTRL03, 0x42 },
- { OV9740_SENSOR_CTRL04, 0x10 },
- { OV9740_SENSOR_CTRL05, 0x45 },
- { OV9740_SENSOR_CTRL07, 0x14 },
-
- /* Timing Control */
- { OV9740_TIMING_CTRL33, 0x04 },
- { OV9740_TIMING_CTRL35, 0x02 },
- { OV9740_TIMING_CTRL19, 0x6e },
- { OV9740_TIMING_CTRL17, 0x94 },
-
- /* AEC/AGC Control */
- { OV9740_AEC_ENABLE, 0x10 },
- { OV9740_GAIN_CEILING_01, 0x00 },
- { OV9740_GAIN_CEILING_02, 0x7f },
- { OV9740_AEC_HI_THRESHOLD, 0xa0 },
- { OV9740_AEC_3A1A, 0x05 },
- { OV9740_AEC_CTRL1B_WPT2, 0x50 },
- { OV9740_AEC_CTRL0F_WPT, 0x50 },
- { OV9740_AEC_CTRL10_BPT, 0x4c },
- { OV9740_AEC_CTRL1E_BPT2, 0x4c },
- { OV9740_AEC_LO_THRESHOLD, 0x26 },
-
- /* BLC Control */
- { OV9740_BLC_AUTO_ENABLE, 0x45 },
- { OV9740_BLC_MODE, 0x18 },
-
- /* DVP Control */
- { OV9740_DVP_VSYNC_CTRL02, 0x04 },
- { OV9740_DVP_VSYNC_MODE, 0x00 },
- { OV9740_DVP_VSYNC_CTRL06, 0x08 },
-
- /* PLL Setting */
- { OV9740_PLL_MODE_CTRL01, 0x20 },
- { OV9740_PRE_PLL_CLK_DIV, 0x03 },
- { OV9740_PLL_MULTIPLIER, 0x4c },
- { OV9740_VT_SYS_CLK_DIV, 0x01 },
- { OV9740_VT_PIX_CLK_DIV, 0x08 },
- { OV9740_PLL_CTRL3010, 0x01 },
- { OV9740_VFIFO_CTRL00, 0x82 },
-
- /* Timing Setting */
- /* VTS */
- { OV9740_FRM_LENGTH_LN_HI, 0x03 },
- { OV9740_FRM_LENGTH_LN_LO, 0x07 },
- /* HTS */
- { OV9740_LN_LENGTH_PCK_HI, 0x06 },
- { OV9740_LN_LENGTH_PCK_LO, 0x62 },
-
- /* MIPI Control */
- { OV9740_MIPI_CTRL00, 0x44 }, /* 0x64 for discontinuous clk */
- { OV9740_MIPI_3837, 0x01 },
- { OV9740_MIPI_CTRL01, 0x0f },
- { OV9740_MIPI_CTRL03, 0x05 },
- { OV9740_MIPI_CTRL05, 0x10 },
- { OV9740_VFIFO_RD_CTRL, 0x16 },
- { OV9740_MIPI_CTRL_3012, 0x70 },
- { OV9740_SC_CMMM_MIPI_CTR, 0x01 },
-
- /* YUYV order */
- { OV9740_ISP_CTRL19, 0x02 },
-};
-
-static enum v4l2_mbus_pixelcode ov9740_codes[] = {
- V4L2_MBUS_FMT_YUYV8_2X8,
-};
-
-/* read a register */
-static int ov9740_reg_read(struct i2c_client *client, u16 reg, u8 *val)
-{
- int ret;
- struct i2c_msg msg[] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = 2,
- .buf = (u8 *)&reg,
- },
- {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = 1,
- .buf = val,
- },
- };
-
- reg = swab16(reg);
-
- ret = i2c_transfer(client->adapter, msg, 2);
- if (ret < 0) {
- dev_err(&client->dev, "Failed reading register 0x%04x!\n", reg);
- return ret;
- }
-
- return 0;
-}
-
-/* write a register */
-static int ov9740_reg_write(struct i2c_client *client, u16 reg, u8 val)
-{
- struct i2c_msg msg;
- struct {
- u16 reg;
- u8 val;
- } __packed buf;
- int ret;
-
- reg = swab16(reg);
-
- buf.reg = reg;
- buf.val = val;
-
- msg.addr = client->addr;
- msg.flags = 0;
- msg.len = 3;
- msg.buf = (u8 *)&buf;
-
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret < 0) {
- dev_err(&client->dev, "Failed writing register 0x%04x!\n", reg);
- return ret;
- }
-
- return 0;
-}
-
-
-/* Read a register, alter its bits, write it back */
-static int ov9740_reg_rmw(struct i2c_client *client, u16 reg, u8 set, u8 unset)
-{
- u8 val;
- int ret;
-
- ret = ov9740_reg_read(client, reg, &val);
- if (ret < 0) {
- dev_err(&client->dev,
- "[Read]-Modify-Write of register 0x%04x failed!\n",
- reg);
- return ret;
- }
-
- val |= set;
- val &= ~unset;
-
- ret = ov9740_reg_write(client, reg, val);
- if (ret < 0) {
- dev_err(&client->dev,
- "Read-Modify-[Write] of register 0x%04x failed!\n",
- reg);
- return ret;
- }
-
- return 0;
-}
-
-static int ov9740_reg_write_array(struct i2c_client *client,
- const struct ov9740_reg *regarray,
- int regarraylen)
-{
- int i;
- int ret;
-
- for (i = 0; i < regarraylen; i++) {
- ret = ov9740_reg_write(client,
- regarray[i].reg, regarray[i].val);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-/* Start/Stop streaming from the device */
-static int ov9740_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov9740_priv *priv = to_ov9740(sd);
- int ret;
-
- /* Program orientation register. */
- if (priv->flag_vflip)
- ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0x2, 0);
- else
- ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0, 0x2);
- if (ret < 0)
- return ret;
-
- if (priv->flag_hflip)
- ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0x1, 0);
- else
- ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0, 0x1);
- if (ret < 0)
- return ret;
-
- if (enable) {
- dev_dbg(&client->dev, "Enabling Streaming\n");
- /* Start Streaming */
- ret = ov9740_reg_write(client, OV9740_MODE_SELECT, 0x01);
-
- } else {
- dev_dbg(&client->dev, "Disabling Streaming\n");
- /* Software Reset */
- ret = ov9740_reg_write(client, OV9740_SOFTWARE_RESET, 0x01);
- if (!ret)
- /* Setting Streaming to Standby */
- ret = ov9740_reg_write(client, OV9740_MODE_SELECT,
- 0x00);
- }
-
- priv->current_enable = enable;
-
- return ret;
-}
-
-/* select nearest higher resolution for capture */
-static void ov9740_res_roundup(u32 *width, u32 *height)
-{
- /* Width must be a multiple of 4 pixels. */
- *width = ALIGN(*width, 4);
-
- /* Max resolution is 1280x720 (720p). */
- if (*width > OV9740_MAX_WIDTH)
- *width = OV9740_MAX_WIDTH;
-
- if (*height > OV9740_MAX_HEIGHT)
- *height = OV9740_MAX_HEIGHT;
-}
-
-/* Setup registers according to resolution and color encoding */
-static int ov9740_set_res(struct i2c_client *client, u32 width, u32 height)
-{
- u32 x_start;
- u32 y_start;
- u32 x_end;
- u32 y_end;
- bool scaling = 0;
- u32 scale_input_x;
- u32 scale_input_y;
- int ret;
-
- if ((width != OV9740_MAX_WIDTH) || (height != OV9740_MAX_HEIGHT))
- scaling = 1;
-
- /*
- * Try to use as much of the sensor area as possible when supporting
- * smaller resolutions. Depending on the aspect ratio of the
- * chosen resolution, we can either use the full width of the sensor,
- * or the full height of the sensor (or both if the aspect ratio is
- * the same as 1280x720.
- */
- if ((OV9740_MAX_WIDTH * height) > (OV9740_MAX_HEIGHT * width)) {
- scale_input_x = (OV9740_MAX_HEIGHT * width) / height;
- scale_input_y = OV9740_MAX_HEIGHT;
- } else {
- scale_input_x = OV9740_MAX_WIDTH;
- scale_input_y = (OV9740_MAX_WIDTH * height) / width;
- }
-
- /* These describe the area of the sensor to use. */
- x_start = (OV9740_MAX_WIDTH - scale_input_x) / 2;
- y_start = (OV9740_MAX_HEIGHT - scale_input_y) / 2;
- x_end = x_start + scale_input_x - 1;
- y_end = y_start + scale_input_y - 1;
-
- ret = ov9740_reg_write(client, OV9740_X_ADDR_START_HI, x_start >> 8);
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_X_ADDR_START_LO, x_start & 0xff);
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_Y_ADDR_START_HI, y_start >> 8);
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_Y_ADDR_START_LO, y_start & 0xff);
- if (ret)
- goto done;
-
- ret = ov9740_reg_write(client, OV9740_X_ADDR_END_HI, x_end >> 8);
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_X_ADDR_END_LO, x_end & 0xff);
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_Y_ADDR_END_HI, y_end >> 8);
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_Y_ADDR_END_LO, y_end & 0xff);
- if (ret)
- goto done;
-
- ret = ov9740_reg_write(client, OV9740_X_OUTPUT_SIZE_HI, width >> 8);
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_X_OUTPUT_SIZE_LO, width & 0xff);
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_Y_OUTPUT_SIZE_HI, height >> 8);
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_Y_OUTPUT_SIZE_LO, height & 0xff);
- if (ret)
- goto done;
-
- ret = ov9740_reg_write(client, OV9740_ISP_CTRL1E, scale_input_x >> 8);
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_ISP_CTRL1F, scale_input_x & 0xff);
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_ISP_CTRL20, scale_input_y >> 8);
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_ISP_CTRL21, scale_input_y & 0xff);
- if (ret)
- goto done;
-
- ret = ov9740_reg_write(client, OV9740_VFIFO_READ_START_HI,
- (scale_input_x - width) >> 8);
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_VFIFO_READ_START_LO,
- (scale_input_x - width) & 0xff);
- if (ret)
- goto done;
-
- ret = ov9740_reg_write(client, OV9740_ISP_CTRL00, 0xff);
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_ISP_CTRL01, 0xef |
- (scaling << 4));
- if (ret)
- goto done;
- ret = ov9740_reg_write(client, OV9740_ISP_CTRL03, 0xff);
-
-done:
- return ret;
-}
-
-/* set the format we will capture in */
-static int ov9740_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov9740_priv *priv = to_ov9740(sd);
- enum v4l2_colorspace cspace;
- enum v4l2_mbus_pixelcode code = mf->code;
- int ret;
-
- ov9740_res_roundup(&mf->width, &mf->height);
-
- switch (code) {
- case V4L2_MBUS_FMT_YUYV8_2X8:
- cspace = V4L2_COLORSPACE_SRGB;
- break;
- default:
- return -EINVAL;
- }
-
- ret = ov9740_reg_write_array(client, ov9740_defaults,
- ARRAY_SIZE(ov9740_defaults));
- if (ret < 0)
- return ret;
-
- ret = ov9740_set_res(client, mf->width, mf->height);
- if (ret < 0)
- return ret;
-
- mf->code = code;
- mf->colorspace = cspace;
-
- memcpy(&priv->current_mf, mf, sizeof(struct v4l2_mbus_framefmt));
-
- return ret;
-}
-
-static int ov9740_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- ov9740_res_roundup(&mf->width, &mf->height);
-
- mf->field = V4L2_FIELD_NONE;
- mf->code = V4L2_MBUS_FMT_YUYV8_2X8;
- mf->colorspace = V4L2_COLORSPACE_SRGB;
-
- return 0;
-}
-
-static int ov9740_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index >= ARRAY_SIZE(ov9740_codes))
- return -EINVAL;
-
- *code = ov9740_codes[index];
-
- return 0;
-}
-
-static int ov9740_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = OV9740_MAX_WIDTH;
- a->bounds.height = OV9740_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int ov9740_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- a->c.left = 0;
- a->c.top = 0;
- a->c.width = OV9740_MAX_WIDTH;
- a->c.height = OV9740_MAX_HEIGHT;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-/* Set status of additional camera capabilities */
-static int ov9740_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct ov9740_priv *priv =
- container_of(ctrl->handler, struct ov9740_priv, hdl);
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- priv->flag_vflip = ctrl->val;
- break;
- case V4L2_CID_HFLIP:
- priv->flag_hflip = ctrl->val;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* Get chip identification */
-static int ov9740_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct ov9740_priv *priv = to_ov9740(sd);
-
- id->ident = priv->ident;
- id->revision = priv->revision;
-
- return 0;
-}
-
-static int ov9740_s_power(struct v4l2_subdev *sd, int on)
-{
- struct ov9740_priv *priv = to_ov9740(sd);
-
- if (!priv->current_enable)
- return 0;
-
- if (on) {
- ov9740_s_fmt(sd, &priv->current_mf);
- ov9740_s_stream(sd, priv->current_enable);
- } else {
- ov9740_s_stream(sd, 0);
- priv->current_enable = true;
- }
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ov9740_get_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
- u8 val;
-
- if (reg->reg & ~0xffff)
- return -EINVAL;
-
- reg->size = 2;
-
- ret = ov9740_reg_read(client, reg->reg, &val);
- if (ret)
- return ret;
-
- reg->val = (__u64)val;
-
- return ret;
-}
-
-static int ov9740_set_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->reg & ~0xffff || reg->val & ~0xff)
- return -EINVAL;
-
- return ov9740_reg_write(client, reg->reg, reg->val);
-}
-#endif
-
-static int ov9740_video_probe(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct ov9740_priv *priv = to_ov9740(sd);
- u8 modelhi, modello;
- int ret;
-
- /*
- * check and show product ID and manufacturer ID
- */
- ret = ov9740_reg_read(client, OV9740_MODEL_ID_HI, &modelhi);
- if (ret < 0)
- goto err;
-
- ret = ov9740_reg_read(client, OV9740_MODEL_ID_LO, &modello);
- if (ret < 0)
- goto err;
-
- priv->model = (modelhi << 8) | modello;
-
- ret = ov9740_reg_read(client, OV9740_REVISION_NUMBER, &priv->revision);
- if (ret < 0)
- goto err;
-
- ret = ov9740_reg_read(client, OV9740_MANUFACTURER_ID, &priv->manid);
- if (ret < 0)
- goto err;
-
- ret = ov9740_reg_read(client, OV9740_SMIA_VERSION, &priv->smiaver);
- if (ret < 0)
- goto err;
-
- if (priv->model != 0x9740) {
- ret = -ENODEV;
- goto err;
- }
-
- priv->ident = V4L2_IDENT_OV9740;
-
- dev_info(&client->dev, "ov9740 Model ID 0x%04x, Revision 0x%02x, "
- "Manufacturer 0x%02x, SMIA Version 0x%02x\n",
- priv->model, priv->revision, priv->manid, priv->smiaver);
-
-err:
- return ret;
-}
-
-/* Request bus settings on camera side */
-static int ov9740_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
- V4L2_MBUS_DATA_ACTIVE_HIGH;
- cfg->type = V4L2_MBUS_PARALLEL;
- cfg->flags = soc_camera_apply_board_flags(icl, cfg);
-
- return 0;
-}
-
-static struct v4l2_subdev_video_ops ov9740_video_ops = {
- .s_stream = ov9740_s_stream,
- .s_mbus_fmt = ov9740_s_fmt,
- .try_mbus_fmt = ov9740_try_fmt,
- .enum_mbus_fmt = ov9740_enum_fmt,
- .cropcap = ov9740_cropcap,
- .g_crop = ov9740_g_crop,
- .g_mbus_config = ov9740_g_mbus_config,
-};
-
-static struct v4l2_subdev_core_ops ov9740_core_ops = {
- .g_chip_ident = ov9740_g_chip_ident,
- .s_power = ov9740_s_power,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = ov9740_get_register,
- .s_register = ov9740_set_register,
-#endif
-};
-
-static struct v4l2_subdev_ops ov9740_subdev_ops = {
- .core = &ov9740_core_ops,
- .video = &ov9740_video_ops,
-};
-
-static const struct v4l2_ctrl_ops ov9740_ctrl_ops = {
- .s_ctrl = ov9740_s_ctrl,
-};
-
-/*
- * i2c_driver function
- */
-static int ov9740_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct ov9740_priv *priv;
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- int ret;
-
- if (!icl) {
- dev_err(&client->dev, "Missing platform_data for driver\n");
- return -EINVAL;
- }
-
- priv = kzalloc(sizeof(struct ov9740_priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&client->dev, "Failed to allocate private data!\n");
- return -ENOMEM;
- }
-
- v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops);
- v4l2_ctrl_handler_init(&priv->hdl, 13);
- v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- priv->subdev.ctrl_handler = &priv->hdl;
- if (priv->hdl.error) {
- int err = priv->hdl.error;
-
- kfree(priv);
- return err;
- }
-
- ret = ov9740_video_probe(client);
- if (!ret)
- ret = v4l2_ctrl_handler_setup(&priv->hdl);
- if (ret < 0) {
- v4l2_ctrl_handler_free(&priv->hdl);
- kfree(priv);
- }
-
- return ret;
-}
-
-static int ov9740_remove(struct i2c_client *client)
-{
- struct ov9740_priv *priv = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(&priv->subdev);
- v4l2_ctrl_handler_free(&priv->hdl);
- kfree(priv);
- return 0;
-}
-
-static const struct i2c_device_id ov9740_id[] = {
- { "ov9740", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ov9740_id);
-
-static struct i2c_driver ov9740_i2c_driver = {
- .driver = {
- .name = "ov9740",
- },
- .probe = ov9740_probe,
- .remove = ov9740_remove,
- .id_table = ov9740_id,
-};
-
-module_i2c_driver(ov9740_i2c_driver);
-
-MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV9740");
-MODULE_AUTHOR("Andrew Chew <achew@nvidia.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
deleted file mode 100644
index 77f9c92186f..00000000000
--- a/drivers/media/video/pms.c
+++ /dev/null
@@ -1,1152 +0,0 @@
-/*
- * Media Vision Pro Movie Studio
- * or
- * "all you need is an I2C bus some RAM and a prayer"
- *
- * This draws heavily on code
- *
- * (c) Wolfgang Koehler, wolf@first.gmd.de, Dec. 1994
- * Kiefernring 15
- * 14478 Potsdam, Germany
- *
- * Most of this code is directly derived from his userspace driver.
- * His driver works so send any reports to alan@lxorguk.ukuu.org.uk
- * unless the userspace driver also doesn't work for you...
- *
- * Changes:
- * 25-11-2009 Hans Verkuil <hverkuil@xs4all.nl>
- * - converted to version 2 of the V4L API.
- * 08/07/2003 Daniele Bellucci <bellucda@tiscali.it>
- * - pms_capture: report back -EFAULT
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-#include <linux/isa.h>
-#include <asm/io.h>
-
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-device.h>
-
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.5");
-
-#define MOTOROLA 1
-#define PHILIPS2 2 /* SAA7191 */
-#define PHILIPS1 3
-#define MVVMEMORYWIDTH 0x40 /* 512 bytes */
-
-struct i2c_info {
- u8 slave;
- u8 sub;
- u8 data;
- u8 hits;
-};
-
-struct pms {
- struct v4l2_device v4l2_dev;
- struct video_device vdev;
- struct v4l2_ctrl_handler hdl;
- int height;
- int width;
- int depth;
- int input;
- struct mutex lock;
- int i2c_count;
- struct i2c_info i2cinfo[64];
-
- int decoder;
- int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */
- v4l2_std_id std;
- int io;
- int data;
- void __iomem *mem;
-};
-
-/*
- * I/O ports and Shared Memory
- */
-
-static int io_port = 0x250;
-module_param(io_port, int, 0);
-
-static int mem_base = 0xc8000;
-module_param(mem_base, int, 0);
-
-static int video_nr = -1;
-module_param(video_nr, int, 0);
-
-
-static inline void mvv_write(struct pms *dev, u8 index, u8 value)
-{
- outw(index | (value << 8), dev->io);
-}
-
-static inline u8 mvv_read(struct pms *dev, u8 index)
-{
- outb(index, dev->io);
- return inb(dev->data);
-}
-
-static int pms_i2c_stat(struct pms *dev, u8 slave)
-{
- int counter = 0;
- int i;
-
- outb(0x28, dev->io);
-
- while ((inb(dev->data) & 0x01) == 0)
- if (counter++ == 256)
- break;
-
- while ((inb(dev->data) & 0x01) != 0)
- if (counter++ == 256)
- break;
-
- outb(slave, dev->io);
-
- counter = 0;
- while ((inb(dev->data) & 0x01) == 0)
- if (counter++ == 256)
- break;
-
- while ((inb(dev->data) & 0x01) != 0)
- if (counter++ == 256)
- break;
-
- for (i = 0; i < 12; i++) {
- char st = inb(dev->data);
-
- if ((st & 2) != 0)
- return -1;
- if ((st & 1) == 0)
- break;
- }
- outb(0x29, dev->io);
- return inb(dev->data);
-}
-
-static int pms_i2c_write(struct pms *dev, u16 slave, u16 sub, u16 data)
-{
- int skip = 0;
- int count;
- int i;
-
- for (i = 0; i < dev->i2c_count; i++) {
- if ((dev->i2cinfo[i].slave == slave) &&
- (dev->i2cinfo[i].sub == sub)) {
- if (dev->i2cinfo[i].data == data)
- skip = 1;
- dev->i2cinfo[i].data = data;
- i = dev->i2c_count + 1;
- }
- }
-
- if (i == dev->i2c_count && dev->i2c_count < 64) {
- dev->i2cinfo[dev->i2c_count].slave = slave;
- dev->i2cinfo[dev->i2c_count].sub = sub;
- dev->i2cinfo[dev->i2c_count].data = data;
- dev->i2c_count++;
- }
-
- if (skip)
- return 0;
-
- mvv_write(dev, 0x29, sub);
- mvv_write(dev, 0x2A, data);
- mvv_write(dev, 0x28, slave);
-
- outb(0x28, dev->io);
-
- count = 0;
- while ((inb(dev->data) & 1) == 0)
- if (count > 255)
- break;
- while ((inb(dev->data) & 1) != 0)
- if (count > 255)
- break;
-
- count = inb(dev->data);
-
- if (count & 2)
- return -1;
- return count;
-}
-
-static int pms_i2c_read(struct pms *dev, int slave, int sub)
-{
- int i;
-
- for (i = 0; i < dev->i2c_count; i++) {
- if (dev->i2cinfo[i].slave == slave && dev->i2cinfo[i].sub == sub)
- return dev->i2cinfo[i].data;
- }
- return 0;
-}
-
-
-static void pms_i2c_andor(struct pms *dev, int slave, int sub, int and, int or)
-{
- u8 tmp;
-
- tmp = pms_i2c_read(dev, slave, sub);
- tmp = (tmp & and) | or;
- pms_i2c_write(dev, slave, sub, tmp);
-}
-
-/*
- * Control functions
- */
-
-
-static void pms_videosource(struct pms *dev, short source)
-{
- switch (dev->decoder) {
- case MOTOROLA:
- break;
- case PHILIPS2:
- pms_i2c_andor(dev, 0x8a, 0x06, 0x7f, source ? 0x80 : 0);
- break;
- case PHILIPS1:
- break;
- }
- mvv_write(dev, 0x2E, 0x31);
- /* Was: mvv_write(dev, 0x2E, source ? 0x31 : 0x30);
- But could not make this work correctly. Only Composite input
- worked for me. */
-}
-
-static void pms_hue(struct pms *dev, short hue)
-{
- switch (dev->decoder) {
- case MOTOROLA:
- pms_i2c_write(dev, 0x8a, 0x00, hue);
- break;
- case PHILIPS2:
- pms_i2c_write(dev, 0x8a, 0x07, hue);
- break;
- case PHILIPS1:
- pms_i2c_write(dev, 0x42, 0x07, hue);
- break;
- }
-}
-
-static void pms_saturation(struct pms *dev, short sat)
-{
- switch (dev->decoder) {
- case MOTOROLA:
- pms_i2c_write(dev, 0x8a, 0x00, sat);
- break;
- case PHILIPS1:
- pms_i2c_write(dev, 0x42, 0x12, sat);
- break;
- }
-}
-
-
-static void pms_contrast(struct pms *dev, short contrast)
-{
- switch (dev->decoder) {
- case MOTOROLA:
- pms_i2c_write(dev, 0x8a, 0x00, contrast);
- break;
- case PHILIPS1:
- pms_i2c_write(dev, 0x42, 0x13, contrast);
- break;
- }
-}
-
-static void pms_brightness(struct pms *dev, short brightness)
-{
- switch (dev->decoder) {
- case MOTOROLA:
- pms_i2c_write(dev, 0x8a, 0x00, brightness);
- pms_i2c_write(dev, 0x8a, 0x00, brightness);
- pms_i2c_write(dev, 0x8a, 0x00, brightness);
- break;
- case PHILIPS1:
- pms_i2c_write(dev, 0x42, 0x19, brightness);
- break;
- }
-}
-
-
-static void pms_format(struct pms *dev, short format)
-{
- int target;
-
- dev->standard = format;
-
- if (dev->decoder == PHILIPS1)
- target = 0x42;
- else if (dev->decoder == PHILIPS2)
- target = 0x8a;
- else
- return;
-
- switch (format) {
- case 0: /* Auto */
- pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
- pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x80);
- break;
- case 1: /* NTSC */
- pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
- pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x40);
- break;
- case 2: /* PAL */
- pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
- pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
- break;
- case 3: /* SECAM */
- pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x01);
- pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
- break;
- }
-}
-
-#ifdef FOR_FUTURE_EXPANSION
-
-/*
- * These features of the PMS card are not currently exposes. They
- * could become a private v4l ioctl for PMSCONFIG or somesuch if
- * people need it. We also don't yet use the PMS interrupt.
- */
-
-static void pms_hstart(struct pms *dev, short start)
-{
- switch (dev->decoder) {
- case PHILIPS1:
- pms_i2c_write(dev, 0x8a, 0x05, start);
- pms_i2c_write(dev, 0x8a, 0x18, start);
- break;
- case PHILIPS2:
- pms_i2c_write(dev, 0x42, 0x05, start);
- pms_i2c_write(dev, 0x42, 0x18, start);
- break;
- }
-}
-
-/*
- * Bandpass filters
- */
-
-static void pms_bandpass(struct pms *dev, short pass)
-{
- if (dev->decoder == PHILIPS2)
- pms_i2c_andor(dev, 0x8a, 0x06, 0xcf, (pass & 0x03) << 4);
- else if (dev->decoder == PHILIPS1)
- pms_i2c_andor(dev, 0x42, 0x06, 0xcf, (pass & 0x03) << 4);
-}
-
-static void pms_antisnow(struct pms *dev, short snow)
-{
- if (dev->decoder == PHILIPS2)
- pms_i2c_andor(dev, 0x8a, 0x06, 0xf3, (snow & 0x03) << 2);
- else if (dev->decoder == PHILIPS1)
- pms_i2c_andor(dev, 0x42, 0x06, 0xf3, (snow & 0x03) << 2);
-}
-
-static void pms_sharpness(struct pms *dev, short sharp)
-{
- if (dev->decoder == PHILIPS2)
- pms_i2c_andor(dev, 0x8a, 0x06, 0xfc, sharp & 0x03);
- else if (dev->decoder == PHILIPS1)
- pms_i2c_andor(dev, 0x42, 0x06, 0xfc, sharp & 0x03);
-}
-
-static void pms_chromaagc(struct pms *dev, short agc)
-{
- if (dev->decoder == PHILIPS2)
- pms_i2c_andor(dev, 0x8a, 0x0c, 0x9f, (agc & 0x03) << 5);
- else if (dev->decoder == PHILIPS1)
- pms_i2c_andor(dev, 0x42, 0x0c, 0x9f, (agc & 0x03) << 5);
-}
-
-static void pms_vertnoise(struct pms *dev, short noise)
-{
- if (dev->decoder == PHILIPS2)
- pms_i2c_andor(dev, 0x8a, 0x10, 0xfc, noise & 3);
- else if (dev->decoder == PHILIPS1)
- pms_i2c_andor(dev, 0x42, 0x10, 0xfc, noise & 3);
-}
-
-static void pms_forcecolour(struct pms *dev, short colour)
-{
- if (dev->decoder == PHILIPS2)
- pms_i2c_andor(dev, 0x8a, 0x0c, 0x7f, (colour & 1) << 7);
- else if (dev->decoder == PHILIPS1)
- pms_i2c_andor(dev, 0x42, 0x0c, 0x7, (colour & 1) << 7);
-}
-
-static void pms_antigamma(struct pms *dev, short gamma)
-{
- if (dev->decoder == PHILIPS2)
- pms_i2c_andor(dev, 0xb8, 0x00, 0x7f, (gamma & 1) << 7);
- else if (dev->decoder == PHILIPS1)
- pms_i2c_andor(dev, 0x42, 0x20, 0x7, (gamma & 1) << 7);
-}
-
-static void pms_prefilter(struct pms *dev, short filter)
-{
- if (dev->decoder == PHILIPS2)
- pms_i2c_andor(dev, 0x8a, 0x06, 0xbf, (filter & 1) << 6);
- else if (dev->decoder == PHILIPS1)
- pms_i2c_andor(dev, 0x42, 0x06, 0xbf, (filter & 1) << 6);
-}
-
-static void pms_hfilter(struct pms *dev, short filter)
-{
- if (dev->decoder == PHILIPS2)
- pms_i2c_andor(dev, 0xb8, 0x04, 0x1f, (filter & 7) << 5);
- else if (dev->decoder == PHILIPS1)
- pms_i2c_andor(dev, 0x42, 0x24, 0x1f, (filter & 7) << 5);
-}
-
-static void pms_vfilter(struct pms *dev, short filter)
-{
- if (dev->decoder == PHILIPS2)
- pms_i2c_andor(dev, 0xb8, 0x08, 0x9f, (filter & 3) << 5);
- else if (dev->decoder == PHILIPS1)
- pms_i2c_andor(dev, 0x42, 0x28, 0x9f, (filter & 3) << 5);
-}
-
-static void pms_killcolour(struct pms *dev, short colour)
-{
- if (dev->decoder == PHILIPS2) {
- pms_i2c_andor(dev, 0x8a, 0x08, 0x07, (colour & 0x1f) << 3);
- pms_i2c_andor(dev, 0x8a, 0x09, 0x07, (colour & 0x1f) << 3);
- } else if (dev->decoder == PHILIPS1) {
- pms_i2c_andor(dev, 0x42, 0x08, 0x07, (colour & 0x1f) << 3);
- pms_i2c_andor(dev, 0x42, 0x09, 0x07, (colour & 0x1f) << 3);
- }
-}
-
-static void pms_chromagain(struct pms *dev, short chroma)
-{
- if (dev->decoder == PHILIPS2)
- pms_i2c_write(dev, 0x8a, 0x11, chroma);
- else if (dev->decoder == PHILIPS1)
- pms_i2c_write(dev, 0x42, 0x11, chroma);
-}
-
-
-static void pms_spacialcompl(struct pms *dev, short data)
-{
- mvv_write(dev, 0x3b, data);
-}
-
-static void pms_spacialcomph(struct pms *dev, short data)
-{
- mvv_write(dev, 0x3a, data);
-}
-
-static void pms_vstart(struct pms *dev, short start)
-{
- mvv_write(dev, 0x16, start);
- mvv_write(dev, 0x17, (start >> 8) & 0x01);
-}
-
-#endif
-
-static void pms_secamcross(struct pms *dev, short cross)
-{
- if (dev->decoder == PHILIPS2)
- pms_i2c_andor(dev, 0x8a, 0x0f, 0xdf, (cross & 1) << 5);
- else if (dev->decoder == PHILIPS1)
- pms_i2c_andor(dev, 0x42, 0x0f, 0xdf, (cross & 1) << 5);
-}
-
-
-static void pms_swsense(struct pms *dev, short sense)
-{
- if (dev->decoder == PHILIPS2) {
- pms_i2c_write(dev, 0x8a, 0x0a, sense);
- pms_i2c_write(dev, 0x8a, 0x0b, sense);
- } else if (dev->decoder == PHILIPS1) {
- pms_i2c_write(dev, 0x42, 0x0a, sense);
- pms_i2c_write(dev, 0x42, 0x0b, sense);
- }
-}
-
-
-static void pms_framerate(struct pms *dev, short frr)
-{
- int fps = (dev->std & V4L2_STD_525_60) ? 30 : 25;
-
- if (frr == 0)
- return;
- fps = fps/frr;
- mvv_write(dev, 0x14, 0x80 | fps);
- mvv_write(dev, 0x15, 1);
-}
-
-static void pms_vert(struct pms *dev, u8 deciden, u8 decinum)
-{
- mvv_write(dev, 0x1c, deciden); /* Denominator */
- mvv_write(dev, 0x1d, decinum); /* Numerator */
-}
-
-/*
- * Turn 16bit ratios into best small ratio the chipset can grok
- */
-
-static void pms_vertdeci(struct pms *dev, unsigned short decinum, unsigned short deciden)
-{
- /* Knock it down by / 5 once */
- if (decinum % 5 == 0) {
- deciden /= 5;
- decinum /= 5;
- }
- /*
- * 3's
- */
- while (decinum % 3 == 0 && deciden % 3 == 0) {
- deciden /= 3;
- decinum /= 3;
- }
- /*
- * 2's
- */
- while (decinum % 2 == 0 && deciden % 2 == 0) {
- decinum /= 2;
- deciden /= 2;
- }
- /*
- * Fudgyify
- */
- while (deciden > 32) {
- deciden /= 2;
- decinum = (decinum + 1) / 2;
- }
- if (deciden == 32)
- deciden--;
- pms_vert(dev, deciden, decinum);
-}
-
-static void pms_horzdeci(struct pms *dev, short decinum, short deciden)
-{
- if (decinum <= 512) {
- if (decinum % 5 == 0) {
- decinum /= 5;
- deciden /= 5;
- }
- } else {
- decinum = 512;
- deciden = 640; /* 768 would be ideal */
- }
-
- while (((decinum | deciden) & 1) == 0) {
- decinum >>= 1;
- deciden >>= 1;
- }
- while (deciden > 32) {
- deciden >>= 1;
- decinum = (decinum + 1) >> 1;
- }
- if (deciden == 32)
- deciden--;
-
- mvv_write(dev, 0x24, 0x80 | deciden);
- mvv_write(dev, 0x25, decinum);
-}
-
-static void pms_resolution(struct pms *dev, short width, short height)
-{
- int fg_height;
-
- fg_height = height;
- if (fg_height > 280)
- fg_height = 280;
-
- mvv_write(dev, 0x18, fg_height);
- mvv_write(dev, 0x19, fg_height >> 8);
-
- if (dev->std & V4L2_STD_525_60) {
- mvv_write(dev, 0x1a, 0xfc);
- mvv_write(dev, 0x1b, 0x00);
- if (height > fg_height)
- pms_vertdeci(dev, 240, 240);
- else
- pms_vertdeci(dev, fg_height, 240);
- } else {
- mvv_write(dev, 0x1a, 0x1a);
- mvv_write(dev, 0x1b, 0x01);
- if (fg_height > 256)
- pms_vertdeci(dev, 270, 270);
- else
- pms_vertdeci(dev, fg_height, 270);
- }
- mvv_write(dev, 0x12, 0);
- mvv_write(dev, 0x13, MVVMEMORYWIDTH);
- mvv_write(dev, 0x42, 0x00);
- mvv_write(dev, 0x43, 0x00);
- mvv_write(dev, 0x44, MVVMEMORYWIDTH);
-
- mvv_write(dev, 0x22, width + 8);
- mvv_write(dev, 0x23, (width + 8) >> 8);
-
- if (dev->std & V4L2_STD_525_60)
- pms_horzdeci(dev, width, 640);
- else
- pms_horzdeci(dev, width + 8, 768);
-
- mvv_write(dev, 0x30, mvv_read(dev, 0x30) & 0xfe);
- mvv_write(dev, 0x08, mvv_read(dev, 0x08) | 0x01);
- mvv_write(dev, 0x01, mvv_read(dev, 0x01) & 0xfd);
- mvv_write(dev, 0x32, 0x00);
- mvv_write(dev, 0x33, MVVMEMORYWIDTH);
-}
-
-
-/*
- * Set Input
- */
-
-static void pms_vcrinput(struct pms *dev, short input)
-{
- if (dev->decoder == PHILIPS2)
- pms_i2c_andor(dev, 0x8a, 0x0d, 0x7f, (input & 1) << 7);
- else if (dev->decoder == PHILIPS1)
- pms_i2c_andor(dev, 0x42, 0x0d, 0x7f, (input & 1) << 7);
-}
-
-
-static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
-{
- int y;
- int dw = 2 * dev->width;
- char tmp[dw + 32]; /* using a temp buffer is faster than direct */
- int cnt = 0;
- int len = 0;
- unsigned char r8 = 0x5; /* value for reg8 */
-
- if (rgb555)
- r8 |= 0x20; /* else use untranslated rgb = 565 */
- mvv_write(dev, 0x08, r8); /* capture rgb555/565, init DRAM, PC enable */
-
-/* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
-
- for (y = 0; y < dev->height; y++) {
- writeb(0, dev->mem); /* synchronisiert neue Zeile */
-
- /*
- * This is in truth a fifo, be very careful as if you
- * forgot this odd things will occur 8)
- */
-
- memcpy_fromio(tmp, dev->mem, dw + 32); /* discard 16 word */
- cnt -= dev->height;
- while (cnt <= 0) {
- /*
- * Don't copy too far
- */
- int dt = dw;
- if (dt + len > count)
- dt = count - len;
- cnt += dev->height;
- if (copy_to_user(buf, tmp + 32, dt))
- return len ? len : -EFAULT;
- buf += dt;
- len += dt;
- }
- }
- return len;
-}
-
-
-/*
- * Video4linux interfacing
- */
-
-static int pms_querycap(struct file *file, void *priv,
- struct v4l2_capability *vcap)
-{
- struct pms *dev = video_drvdata(file);
-
- strlcpy(vcap->driver, dev->v4l2_dev.name, sizeof(vcap->driver));
- strlcpy(vcap->card, "Mediavision PMS", sizeof(vcap->card));
- snprintf(vcap->bus_info, sizeof(vcap->bus_info),
- "ISA:%s", dev->v4l2_dev.name);
- vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
- vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
- return 0;
-}
-
-static int pms_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
-{
- static const char *inputs[4] = {
- "Composite",
- "S-Video",
- "Composite (VCR)",
- "S-Video (VCR)"
- };
-
- if (vin->index > 3)
- return -EINVAL;
- strlcpy(vin->name, inputs[vin->index], sizeof(vin->name));
- vin->type = V4L2_INPUT_TYPE_CAMERA;
- vin->audioset = 0;
- vin->tuner = 0;
- vin->std = V4L2_STD_ALL;
- vin->status = 0;
- return 0;
-}
-
-static int pms_g_input(struct file *file, void *fh, unsigned int *inp)
-{
- struct pms *dev = video_drvdata(file);
-
- *inp = dev->input;
- return 0;
-}
-
-static int pms_s_input(struct file *file, void *fh, unsigned int inp)
-{
- struct pms *dev = video_drvdata(file);
-
- if (inp > 3)
- return -EINVAL;
-
- dev->input = inp;
- pms_videosource(dev, inp & 1);
- pms_vcrinput(dev, inp >> 1);
- return 0;
-}
-
-static int pms_g_std(struct file *file, void *fh, v4l2_std_id *std)
-{
- struct pms *dev = video_drvdata(file);
-
- *std = dev->std;
- return 0;
-}
-
-static int pms_s_std(struct file *file, void *fh, v4l2_std_id *std)
-{
- struct pms *dev = video_drvdata(file);
- int ret = 0;
-
- dev->std = *std;
- if (dev->std & V4L2_STD_NTSC) {
- pms_framerate(dev, 30);
- pms_secamcross(dev, 0);
- pms_format(dev, 1);
- } else if (dev->std & V4L2_STD_PAL) {
- pms_framerate(dev, 25);
- pms_secamcross(dev, 0);
- pms_format(dev, 2);
- } else if (dev->std & V4L2_STD_SECAM) {
- pms_framerate(dev, 25);
- pms_secamcross(dev, 1);
- pms_format(dev, 2);
- } else {
- ret = -EINVAL;
- }
- /*
- switch (v->mode) {
- case VIDEO_MODE_AUTO:
- pms_framerate(dev, 25);
- pms_secamcross(dev, 0);
- pms_format(dev, 0);
- break;
- }*/
- return ret;
-}
-
-static int pms_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct pms *dev = container_of(ctrl->handler, struct pms, hdl);
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- pms_brightness(dev, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- pms_contrast(dev, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- pms_saturation(dev, ctrl->val);
- break;
- case V4L2_CID_HUE:
- pms_hue(dev, ctrl->val);
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
-static int pms_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct pms *dev = video_drvdata(file);
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
-
- pix->width = dev->width;
- pix->height = dev->height;
- pix->pixelformat = dev->width == 15 ?
- V4L2_PIX_FMT_RGB555 : V4L2_PIX_FMT_RGB565;
- pix->field = V4L2_FIELD_NONE;
- pix->bytesperline = 2 * dev->width;
- pix->sizeimage = 2 * dev->width * dev->height;
- /* Just a guess */
- pix->colorspace = V4L2_COLORSPACE_SRGB;
- return 0;
-}
-
-static int pms_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
-
- if (pix->height < 16 || pix->height > 480)
- return -EINVAL;
- if (pix->width < 16 || pix->width > 640)
- return -EINVAL;
- if (pix->pixelformat != V4L2_PIX_FMT_RGB555 &&
- pix->pixelformat != V4L2_PIX_FMT_RGB565)
- return -EINVAL;
- pix->field = V4L2_FIELD_NONE;
- pix->bytesperline = 2 * pix->width;
- pix->sizeimage = 2 * pix->width * pix->height;
- /* Just a guess */
- pix->colorspace = V4L2_COLORSPACE_SRGB;
- return 0;
-}
-
-static int pms_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct pms *dev = video_drvdata(file);
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
- int ret = pms_try_fmt_vid_cap(file, fh, fmt);
-
- if (ret)
- return ret;
- dev->width = pix->width;
- dev->height = pix->height;
- dev->depth = (pix->pixelformat == V4L2_PIX_FMT_RGB555) ? 15 : 16;
- pms_resolution(dev, dev->width, dev->height);
- /* Ok we figured out what to use from our wide choice */
- return 0;
-}
-
-static int pms_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
-{
- static struct v4l2_fmtdesc formats[] = {
- { 0, 0, 0,
- "RGB 5:5:5", V4L2_PIX_FMT_RGB555,
- { 0, 0, 0, 0 }
- },
- { 1, 0, 0,
- "RGB 5:6:5", V4L2_PIX_FMT_RGB565,
- { 0, 0, 0, 0 }
- },
- };
- enum v4l2_buf_type type = fmt->type;
-
- if (fmt->index > 1)
- return -EINVAL;
-
- *fmt = formats[fmt->index];
- fmt->type = type;
- return 0;
-}
-
-static ssize_t pms_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct pms *dev = video_drvdata(file);
- int len;
-
- len = pms_capture(dev, buf, (dev->depth == 15), count);
- return len;
-}
-
-static unsigned int pms_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct v4l2_fh *fh = file->private_data;
- unsigned int res = POLLIN | POLLRDNORM;
-
- if (v4l2_event_pending(fh))
- res |= POLLPRI;
- poll_wait(file, &fh->wait, wait);
- return res;
-}
-
-static const struct v4l2_file_operations pms_fops = {
- .owner = THIS_MODULE,
- .open = v4l2_fh_open,
- .release = v4l2_fh_release,
- .poll = pms_poll,
- .unlocked_ioctl = video_ioctl2,
- .read = pms_read,
-};
-
-static const struct v4l2_ioctl_ops pms_ioctl_ops = {
- .vidioc_querycap = pms_querycap,
- .vidioc_g_input = pms_g_input,
- .vidioc_s_input = pms_s_input,
- .vidioc_enum_input = pms_enum_input,
- .vidioc_g_std = pms_g_std,
- .vidioc_s_std = pms_s_std,
- .vidioc_enum_fmt_vid_cap = pms_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = pms_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = pms_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = pms_try_fmt_vid_cap,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-/*
- * Probe for and initialise the Mediavision PMS
- */
-
-static int init_mediavision(struct pms *dev)
-{
- int idec, decst;
- int i;
- static const unsigned char i2c_defs[] = {
- 0x4c, 0x30, 0x00, 0xe8,
- 0xb6, 0xe2, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x78, 0x98,
- 0x00, 0x00, 0x00, 0x00,
- 0x34, 0x0a, 0xf4, 0xce,
- 0xe4
- };
-
- dev->mem = ioremap(mem_base, 0x800);
- if (!dev->mem)
- return -ENOMEM;
-
- if (!request_region(0x9a01, 1, "Mediavision PMS config")) {
- printk(KERN_WARNING "mediavision: unable to detect: 0x9a01 in use.\n");
- iounmap(dev->mem);
- return -EBUSY;
- }
- if (!request_region(dev->io, 3, "Mediavision PMS")) {
- printk(KERN_WARNING "mediavision: I/O port %d in use.\n", dev->io);
- release_region(0x9a01, 1);
- iounmap(dev->mem);
- return -EBUSY;
- }
- outb(0xb8, 0x9a01); /* Unlock */
- outb(dev->io >> 4, 0x9a01); /* Set IO port */
-
-
- decst = pms_i2c_stat(dev, 0x43);
-
- if (decst != -1)
- idec = 2;
- else if (pms_i2c_stat(dev, 0xb9) != -1)
- idec = 3;
- else if (pms_i2c_stat(dev, 0x8b) != -1)
- idec = 1;
- else
- idec = 0;
-
- printk(KERN_INFO "PMS type is %d\n", idec);
- if (idec == 0) {
- release_region(dev->io, 3);
- release_region(0x9a01, 1);
- iounmap(dev->mem);
- return -ENODEV;
- }
-
- /*
- * Ok we have a PMS of some sort
- */
-
- mvv_write(dev, 0x04, mem_base >> 12); /* Set the memory area */
-
- /* Ok now load the defaults */
-
- for (i = 0; i < 0x19; i++) {
- if (i2c_defs[i] == 0xff)
- pms_i2c_andor(dev, 0x8a, i, 0x07, 0x00);
- else
- pms_i2c_write(dev, 0x8a, i, i2c_defs[i]);
- }
-
- pms_i2c_write(dev, 0xb8, 0x00, 0x12);
- pms_i2c_write(dev, 0xb8, 0x04, 0x00);
- pms_i2c_write(dev, 0xb8, 0x07, 0x00);
- pms_i2c_write(dev, 0xb8, 0x08, 0x00);
- pms_i2c_write(dev, 0xb8, 0x09, 0xff);
- pms_i2c_write(dev, 0xb8, 0x0a, 0x00);
- pms_i2c_write(dev, 0xb8, 0x0b, 0x10);
- pms_i2c_write(dev, 0xb8, 0x10, 0x03);
-
- mvv_write(dev, 0x01, 0x00);
- mvv_write(dev, 0x05, 0xa0);
- mvv_write(dev, 0x08, 0x25);
- mvv_write(dev, 0x09, 0x00);
- mvv_write(dev, 0x0a, 0x20 | MVVMEMORYWIDTH);
-
- mvv_write(dev, 0x10, 0x02);
- mvv_write(dev, 0x1e, 0x0c);
- mvv_write(dev, 0x1f, 0x03);
- mvv_write(dev, 0x26, 0x06);
-
- mvv_write(dev, 0x2b, 0x00);
- mvv_write(dev, 0x2c, 0x20);
- mvv_write(dev, 0x2d, 0x00);
- mvv_write(dev, 0x2f, 0x70);
- mvv_write(dev, 0x32, 0x00);
- mvv_write(dev, 0x33, MVVMEMORYWIDTH);
- mvv_write(dev, 0x34, 0x00);
- mvv_write(dev, 0x35, 0x00);
- mvv_write(dev, 0x3a, 0x80);
- mvv_write(dev, 0x3b, 0x10);
- mvv_write(dev, 0x20, 0x00);
- mvv_write(dev, 0x21, 0x00);
- mvv_write(dev, 0x30, 0x22);
- return 0;
-}
-
-/*
- * Initialization and module stuff
- */
-
-#ifndef MODULE
-static int enable;
-module_param(enable, int, 0);
-#endif
-
-static const struct v4l2_ctrl_ops pms_ctrl_ops = {
- .s_ctrl = pms_s_ctrl,
-};
-
-static int pms_probe(struct device *pdev, unsigned int card)
-{
- struct pms *dev;
- struct v4l2_device *v4l2_dev;
- struct v4l2_ctrl_handler *hdl;
- int res;
-
-#ifndef MODULE
- if (!enable) {
- pr_err("PMS: not enabled, use pms.enable=1 to probe\n");
- return -ENODEV;
- }
-#endif
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL)
- return -ENOMEM;
-
- dev->decoder = PHILIPS2;
- dev->io = io_port;
- dev->data = io_port + 1;
- v4l2_dev = &dev->v4l2_dev;
- hdl = &dev->hdl;
-
- res = v4l2_device_register(pdev, v4l2_dev);
- if (res < 0) {
- v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
- goto free_dev;
- }
- v4l2_info(v4l2_dev, "Mediavision Pro Movie Studio driver 0.05\n");
-
- res = init_mediavision(dev);
- if (res) {
- v4l2_err(v4l2_dev, "Board not found.\n");
- goto free_io;
- }
-
- v4l2_ctrl_handler_init(hdl, 4);
- v4l2_ctrl_new_std(hdl, &pms_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 139);
- v4l2_ctrl_new_std(hdl, &pms_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 70);
- v4l2_ctrl_new_std(hdl, &pms_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, 64);
- v4l2_ctrl_new_std(hdl, &pms_ctrl_ops,
- V4L2_CID_HUE, 0, 255, 1, 0);
- if (hdl->error) {
- res = hdl->error;
- goto free_hdl;
- }
-
- mutex_init(&dev->lock);
- strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
- dev->vdev.v4l2_dev = v4l2_dev;
- dev->vdev.ctrl_handler = hdl;
- dev->vdev.fops = &pms_fops;
- dev->vdev.ioctl_ops = &pms_ioctl_ops;
- dev->vdev.release = video_device_release_empty;
- dev->vdev.lock = &dev->lock;
- dev->vdev.tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
- set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags);
- video_set_drvdata(&dev->vdev, dev);
- dev->std = V4L2_STD_NTSC_M;
- dev->height = 240;
- dev->width = 320;
- dev->depth = 16;
- pms_swsense(dev, 75);
- pms_resolution(dev, 320, 240);
- pms_videosource(dev, 0);
- pms_vcrinput(dev, 0);
- v4l2_ctrl_handler_setup(hdl);
- res = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr);
- if (res >= 0)
- return 0;
-
-free_hdl:
- v4l2_ctrl_handler_free(hdl);
- v4l2_device_unregister(&dev->v4l2_dev);
-free_io:
- release_region(dev->io, 3);
- release_region(0x9a01, 1);
- iounmap(dev->mem);
-free_dev:
- kfree(dev);
- return res;
-}
-
-static int pms_remove(struct device *pdev, unsigned int card)
-{
- struct pms *dev = dev_get_drvdata(pdev);
-
- video_unregister_device(&dev->vdev);
- v4l2_ctrl_handler_free(&dev->hdl);
- release_region(dev->io, 3);
- release_region(0x9a01, 1);
- iounmap(dev->mem);
- return 0;
-}
-
-static struct isa_driver pms_driver = {
- .probe = pms_probe,
- .remove = pms_remove,
- .driver = {
- .name = "pms",
- },
-};
-
-static int __init pms_init(void)
-{
- return isa_register_driver(&pms_driver, 1);
-}
-
-static void __exit pms_exit(void)
-{
- isa_unregister_driver(&pms_driver);
-}
-
-module_init(pms_init);
-module_exit(pms_exit);
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
deleted file mode 100644
index 25e412ecad2..00000000000
--- a/drivers/media/video/pvrusb2/Kconfig
+++ /dev/null
@@ -1,65 +0,0 @@
-config VIDEO_PVRUSB2
- tristate "Hauppauge WinTV-PVR USB2 support"
- depends on VIDEO_V4L2 && I2C
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- select VIDEO_CX2341X
- select VIDEO_SAA711X
- select VIDEO_CX25840
- select VIDEO_MSP3400
- select VIDEO_WM8775
- select VIDEO_CS53L32A
- ---help---
- This is a video4linux driver for Conexant 23416 based
- usb2 personal video recorder devices.
-
- To compile this driver as a module, choose M here: the
- module will be called pvrusb2
-
-config VIDEO_PVRUSB2_SYSFS
- bool "pvrusb2 sysfs support (EXPERIMENTAL)"
- default y
- depends on VIDEO_PVRUSB2 && SYSFS && EXPERIMENTAL
- ---help---
- This option enables the operation of a sysfs based
- interface for query and control of the pvrusb2 driver.
-
- This is not generally needed for v4l applications,
- although certain applications are optimized to take
- advantage of this feature.
-
- If you are in doubt, say Y.
-
- Note: This feature is experimental and subject to change.
-
-config VIDEO_PVRUSB2_DVB
- bool "pvrusb2 ATSC/DVB support (EXPERIMENTAL)"
- default y
- depends on VIDEO_PVRUSB2 && DVB_CORE && EXPERIMENTAL
- select DVB_LGDT330X if !DVB_FE_CUSTOMISE
- select DVB_S5H1409 if !DVB_FE_CUSTOMISE
- select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select DVB_TDA10048 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
- ---help---
-
- This option enables a DVB interface for the pvrusb2 driver.
- If your device does not support digital television, this
- feature will have no affect on the driver's operation.
-
- If you are in doubt, say Y.
-
-config VIDEO_PVRUSB2_DEBUGIFC
- bool "pvrusb2 debug interface"
- depends on VIDEO_PVRUSB2_SYSFS
- ---help---
- This option enables the inclusion of a debug interface
- in the pvrusb2 driver, hosted through sysfs.
-
- You do not need to select this option unless you plan
- on debugging the driver or performing a manual firmware
- extraction.
-
- If you are in doubt, say N.
diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/video/pvrusb2/Makefile
deleted file mode 100644
index c17f37d964a..00000000000
--- a/drivers/media/video/pvrusb2/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o
-obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o
-obj-pvrusb2-dvb-$(CONFIG_VIDEO_PVRUSB2_DVB) := pvrusb2-dvb.o
-
-pvrusb2-objs := pvrusb2-i2c-core.o \
- pvrusb2-audio.o \
- pvrusb2-encoder.o pvrusb2-video-v4l.o \
- pvrusb2-eeprom.o \
- pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \
- pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \
- pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \
- pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \
- pvrusb2-cs53l32a.o \
- $(obj-pvrusb2-dvb-y) \
- $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y)
-
-obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
-
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
deleted file mode 100644
index cc06d5e4adc..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "pvrusb2-audio.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include <linux/videodev2.h>
-#include <media/msp3400.h>
-#include <media/v4l2-common.h>
-
-
-struct routing_scheme {
- const int *def;
- unsigned int cnt;
-};
-
-static const int routing_scheme0[] = {
- [PVR2_CVAL_INPUT_TV] = MSP_INPUT_DEFAULT,
- [PVR2_CVAL_INPUT_RADIO] = MSP_INPUT(MSP_IN_SCART2,
- MSP_IN_TUNER1,
- MSP_DSP_IN_SCART,
- MSP_DSP_IN_SCART),
- [PVR2_CVAL_INPUT_COMPOSITE] = MSP_INPUT(MSP_IN_SCART1,
- MSP_IN_TUNER1,
- MSP_DSP_IN_SCART,
- MSP_DSP_IN_SCART),
- [PVR2_CVAL_INPUT_SVIDEO] = MSP_INPUT(MSP_IN_SCART1,
- MSP_IN_TUNER1,
- MSP_DSP_IN_SCART,
- MSP_DSP_IN_SCART),
-};
-
-static const struct routing_scheme routing_def0 = {
- .def = routing_scheme0,
- .cnt = ARRAY_SIZE(routing_scheme0),
-};
-
-static const struct routing_scheme *routing_schemes[] = {
- [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
-};
-
-void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
-{
- if (hdw->input_dirty || hdw->force_dirty) {
- const struct routing_scheme *sp;
- unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
- u32 input;
-
- pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo");
- sp = (sid < ARRAY_SIZE(routing_schemes)) ?
- routing_schemes[sid] : NULL;
-
- if ((sp != NULL) &&
- (hdw->input_val >= 0) &&
- (hdw->input_val < sp->cnt)) {
- input = sp->def[hdw->input_val];
- } else {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "*** WARNING *** subdev msp3400 set_input:"
- " Invalid routing scheme (%u)"
- " and/or input (%d)",
- sid, hdw->input_val);
- return;
- }
- sd->ops->audio->s_routing(sd, input,
- MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0);
- }
-}
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.h b/drivers/media/video/pvrusb2/pvrusb2-audio.h
deleted file mode 100644
index e3e63d75089..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef __PVRUSB2_AUDIO_H
-#define __PVRUSB2_AUDIO_H
-
-#include "pvrusb2-hdw-internal.h"
-void pvr2_msp3400_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
-#endif /* __PVRUSB2_AUDIO_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.c b/drivers/media/video/pvrusb2/pvrusb2-context.c
deleted file mode 100644
index 7c19ff72e6b..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-context.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "pvrusb2-context.h"
-#include "pvrusb2-io.h"
-#include "pvrusb2-ioread.h"
-#include "pvrusb2-hdw.h"
-#include "pvrusb2-debug.h"
-#include <linux/wait.h>
-#include <linux/kthread.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-static struct pvr2_context *pvr2_context_exist_first;
-static struct pvr2_context *pvr2_context_exist_last;
-static struct pvr2_context *pvr2_context_notify_first;
-static struct pvr2_context *pvr2_context_notify_last;
-static DEFINE_MUTEX(pvr2_context_mutex);
-static DECLARE_WAIT_QUEUE_HEAD(pvr2_context_sync_data);
-static DECLARE_WAIT_QUEUE_HEAD(pvr2_context_cleanup_data);
-static int pvr2_context_cleanup_flag;
-static int pvr2_context_cleaned_flag;
-static struct task_struct *pvr2_context_thread_ptr;
-
-
-static void pvr2_context_set_notify(struct pvr2_context *mp, int fl)
-{
- int signal_flag = 0;
- mutex_lock(&pvr2_context_mutex);
- if (fl) {
- if (!mp->notify_flag) {
- signal_flag = (pvr2_context_notify_first == NULL);
- mp->notify_prev = pvr2_context_notify_last;
- mp->notify_next = NULL;
- pvr2_context_notify_last = mp;
- if (mp->notify_prev) {
- mp->notify_prev->notify_next = mp;
- } else {
- pvr2_context_notify_first = mp;
- }
- mp->notify_flag = !0;
- }
- } else {
- if (mp->notify_flag) {
- mp->notify_flag = 0;
- if (mp->notify_next) {
- mp->notify_next->notify_prev = mp->notify_prev;
- } else {
- pvr2_context_notify_last = mp->notify_prev;
- }
- if (mp->notify_prev) {
- mp->notify_prev->notify_next = mp->notify_next;
- } else {
- pvr2_context_notify_first = mp->notify_next;
- }
- }
- }
- mutex_unlock(&pvr2_context_mutex);
- if (signal_flag) wake_up(&pvr2_context_sync_data);
-}
-
-
-static void pvr2_context_destroy(struct pvr2_context *mp)
-{
- pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context %p (destroy)",mp);
- if (mp->hdw) pvr2_hdw_destroy(mp->hdw);
- pvr2_context_set_notify(mp, 0);
- mutex_lock(&pvr2_context_mutex);
- if (mp->exist_next) {
- mp->exist_next->exist_prev = mp->exist_prev;
- } else {
- pvr2_context_exist_last = mp->exist_prev;
- }
- if (mp->exist_prev) {
- mp->exist_prev->exist_next = mp->exist_next;
- } else {
- pvr2_context_exist_first = mp->exist_next;
- }
- if (!pvr2_context_exist_first) {
- /* Trigger wakeup on control thread in case it is waiting
- for an exit condition. */
- wake_up(&pvr2_context_sync_data);
- }
- mutex_unlock(&pvr2_context_mutex);
- kfree(mp);
-}
-
-
-static void pvr2_context_notify(struct pvr2_context *mp)
-{
- pvr2_context_set_notify(mp,!0);
-}
-
-
-static void pvr2_context_check(struct pvr2_context *mp)
-{
- struct pvr2_channel *ch1, *ch2;
- pvr2_trace(PVR2_TRACE_CTXT,
- "pvr2_context %p (notify)", mp);
- if (!mp->initialized_flag && !mp->disconnect_flag) {
- mp->initialized_flag = !0;
- pvr2_trace(PVR2_TRACE_CTXT,
- "pvr2_context %p (initialize)", mp);
- /* Finish hardware initialization */
- if (pvr2_hdw_initialize(mp->hdw,
- (void (*)(void *))pvr2_context_notify,
- mp)) {
- mp->video_stream.stream =
- pvr2_hdw_get_video_stream(mp->hdw);
- /* Trigger interface initialization. By doing this
- here initialization runs in our own safe and
- cozy thread context. */
- if (mp->setup_func) mp->setup_func(mp);
- } else {
- pvr2_trace(PVR2_TRACE_CTXT,
- "pvr2_context %p (thread skipping setup)",
- mp);
- /* Even though initialization did not succeed,
- we're still going to continue anyway. We need
- to do this in order to await the expected
- disconnect (which we will detect in the normal
- course of operation). */
- }
- }
-
- for (ch1 = mp->mc_first; ch1; ch1 = ch2) {
- ch2 = ch1->mc_next;
- if (ch1->check_func) ch1->check_func(ch1);
- }
-
- if (mp->disconnect_flag && !mp->mc_first) {
- /* Go away... */
- pvr2_context_destroy(mp);
- return;
- }
-}
-
-
-static int pvr2_context_shutok(void)
-{
- return pvr2_context_cleanup_flag && (pvr2_context_exist_first == NULL);
-}
-
-
-static int pvr2_context_thread_func(void *foo)
-{
- struct pvr2_context *mp;
-
- pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context thread start");
-
- do {
- while ((mp = pvr2_context_notify_first) != NULL) {
- pvr2_context_set_notify(mp, 0);
- pvr2_context_check(mp);
- }
- wait_event_interruptible(
- pvr2_context_sync_data,
- ((pvr2_context_notify_first != NULL) ||
- pvr2_context_shutok()));
- } while (!pvr2_context_shutok());
-
- pvr2_context_cleaned_flag = !0;
- wake_up(&pvr2_context_cleanup_data);
-
- pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context thread cleaned up");
-
- wait_event_interruptible(
- pvr2_context_sync_data,
- kthread_should_stop());
-
- pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context thread end");
-
- return 0;
-}
-
-
-int pvr2_context_global_init(void)
-{
- pvr2_context_thread_ptr = kthread_run(pvr2_context_thread_func,
- NULL,
- "pvrusb2-context");
- return (pvr2_context_thread_ptr ? 0 : -ENOMEM);
-}
-
-
-void pvr2_context_global_done(void)
-{
- pvr2_context_cleanup_flag = !0;
- wake_up(&pvr2_context_sync_data);
- wait_event_interruptible(
- pvr2_context_cleanup_data,
- pvr2_context_cleaned_flag);
- kthread_stop(pvr2_context_thread_ptr);
-}
-
-
-struct pvr2_context *pvr2_context_create(
- struct usb_interface *intf,
- const struct usb_device_id *devid,
- void (*setup_func)(struct pvr2_context *))
-{
- struct pvr2_context *mp = NULL;
- mp = kzalloc(sizeof(*mp),GFP_KERNEL);
- if (!mp) goto done;
- pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context %p (create)",mp);
- mp->setup_func = setup_func;
- mutex_init(&mp->mutex);
- mutex_lock(&pvr2_context_mutex);
- mp->exist_prev = pvr2_context_exist_last;
- mp->exist_next = NULL;
- pvr2_context_exist_last = mp;
- if (mp->exist_prev) {
- mp->exist_prev->exist_next = mp;
- } else {
- pvr2_context_exist_first = mp;
- }
- mutex_unlock(&pvr2_context_mutex);
- mp->hdw = pvr2_hdw_create(intf,devid);
- if (!mp->hdw) {
- pvr2_context_destroy(mp);
- mp = NULL;
- goto done;
- }
- pvr2_context_set_notify(mp, !0);
- done:
- return mp;
-}
-
-
-static void pvr2_context_reset_input_limits(struct pvr2_context *mp)
-{
- unsigned int tmsk,mmsk;
- struct pvr2_channel *cp;
- struct pvr2_hdw *hdw = mp->hdw;
- mmsk = pvr2_hdw_get_input_available(hdw);
- tmsk = mmsk;
- for (cp = mp->mc_first; cp; cp = cp->mc_next) {
- if (!cp->input_mask) continue;
- tmsk &= cp->input_mask;
- }
- pvr2_hdw_set_input_allowed(hdw,mmsk,tmsk);
- pvr2_hdw_commit_ctl(hdw);
-}
-
-
-static void pvr2_context_enter(struct pvr2_context *mp)
-{
- mutex_lock(&mp->mutex);
-}
-
-
-static void pvr2_context_exit(struct pvr2_context *mp)
-{
- int destroy_flag = 0;
- if (!(mp->mc_first || !mp->disconnect_flag)) {
- destroy_flag = !0;
- }
- mutex_unlock(&mp->mutex);
- if (destroy_flag) pvr2_context_notify(mp);
-}
-
-
-void pvr2_context_disconnect(struct pvr2_context *mp)
-{
- pvr2_hdw_disconnect(mp->hdw);
- mp->disconnect_flag = !0;
- pvr2_context_notify(mp);
-}
-
-
-void pvr2_channel_init(struct pvr2_channel *cp,struct pvr2_context *mp)
-{
- pvr2_context_enter(mp);
- cp->hdw = mp->hdw;
- cp->mc_head = mp;
- cp->mc_next = NULL;
- cp->mc_prev = mp->mc_last;
- if (mp->mc_last) {
- mp->mc_last->mc_next = cp;
- } else {
- mp->mc_first = cp;
- }
- mp->mc_last = cp;
- pvr2_context_exit(mp);
-}
-
-
-static void pvr2_channel_disclaim_stream(struct pvr2_channel *cp)
-{
- if (!cp->stream) return;
- pvr2_stream_kill(cp->stream->stream);
- cp->stream->user = NULL;
- cp->stream = NULL;
-}
-
-
-void pvr2_channel_done(struct pvr2_channel *cp)
-{
- struct pvr2_context *mp = cp->mc_head;
- pvr2_context_enter(mp);
- cp->input_mask = 0;
- pvr2_channel_disclaim_stream(cp);
- pvr2_context_reset_input_limits(mp);
- if (cp->mc_next) {
- cp->mc_next->mc_prev = cp->mc_prev;
- } else {
- mp->mc_last = cp->mc_prev;
- }
- if (cp->mc_prev) {
- cp->mc_prev->mc_next = cp->mc_next;
- } else {
- mp->mc_first = cp->mc_next;
- }
- cp->hdw = NULL;
- pvr2_context_exit(mp);
-}
-
-
-int pvr2_channel_limit_inputs(struct pvr2_channel *cp,unsigned int cmsk)
-{
- unsigned int tmsk,mmsk;
- int ret = 0;
- struct pvr2_channel *p2;
- struct pvr2_hdw *hdw = cp->hdw;
-
- mmsk = pvr2_hdw_get_input_available(hdw);
- cmsk &= mmsk;
- if (cmsk == cp->input_mask) {
- /* No change; nothing to do */
- return 0;
- }
-
- pvr2_context_enter(cp->mc_head);
- do {
- if (!cmsk) {
- cp->input_mask = 0;
- pvr2_context_reset_input_limits(cp->mc_head);
- break;
- }
- tmsk = mmsk;
- for (p2 = cp->mc_head->mc_first; p2; p2 = p2->mc_next) {
- if (p2 == cp) continue;
- if (!p2->input_mask) continue;
- tmsk &= p2->input_mask;
- }
- if (!(tmsk & cmsk)) {
- ret = -EPERM;
- break;
- }
- tmsk &= cmsk;
- if ((ret = pvr2_hdw_set_input_allowed(hdw,mmsk,tmsk)) != 0) {
- /* Internal failure changing allowed list; probably
- should not happen, but react if it does. */
- break;
- }
- cp->input_mask = cmsk;
- pvr2_hdw_commit_ctl(hdw);
- } while (0);
- pvr2_context_exit(cp->mc_head);
- return ret;
-}
-
-
-unsigned int pvr2_channel_get_limited_inputs(struct pvr2_channel *cp)
-{
- return cp->input_mask;
-}
-
-
-int pvr2_channel_claim_stream(struct pvr2_channel *cp,
- struct pvr2_context_stream *sp)
-{
- int code = 0;
- pvr2_context_enter(cp->mc_head); do {
- if (sp == cp->stream) break;
- if (sp && sp->user) {
- code = -EBUSY;
- break;
- }
- pvr2_channel_disclaim_stream(cp);
- if (!sp) break;
- sp->user = cp;
- cp->stream = sp;
- } while (0); pvr2_context_exit(cp->mc_head);
- return code;
-}
-
-
-// This is the marker for the real beginning of a legitimate mpeg2 stream.
-static char stream_sync_key[] = {
- 0x00, 0x00, 0x01, 0xba,
-};
-
-struct pvr2_ioread *pvr2_channel_create_mpeg_stream(
- struct pvr2_context_stream *sp)
-{
- struct pvr2_ioread *cp;
- cp = pvr2_ioread_create();
- if (!cp) return NULL;
- pvr2_ioread_setup(cp,sp->stream);
- pvr2_ioread_set_sync_key(cp,stream_sync_key,sizeof(stream_sync_key));
- return cp;
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.h b/drivers/media/video/pvrusb2/pvrusb2-context.h
deleted file mode 100644
index d657e53bbfa..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-context.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __PVRUSB2_CONTEXT_H
-#define __PVRUSB2_CONTEXT_H
-
-#include <linux/mutex.h>
-#include <linux/usb.h>
-#include <linux/workqueue.h>
-
-struct pvr2_hdw; /* hardware interface - defined elsewhere */
-struct pvr2_stream; /* stream interface - defined elsewhere */
-
-struct pvr2_context; /* All central state */
-struct pvr2_channel; /* One I/O pathway to a user */
-struct pvr2_context_stream; /* Wrapper for a stream */
-struct pvr2_ioread; /* Low level stream structure */
-
-struct pvr2_context_stream {
- struct pvr2_channel *user;
- struct pvr2_stream *stream;
-};
-
-struct pvr2_context {
- struct pvr2_channel *mc_first;
- struct pvr2_channel *mc_last;
- struct pvr2_context *exist_next;
- struct pvr2_context *exist_prev;
- struct pvr2_context *notify_next;
- struct pvr2_context *notify_prev;
- struct pvr2_hdw *hdw;
- struct pvr2_context_stream video_stream;
- struct mutex mutex;
- int notify_flag;
- int initialized_flag;
- int disconnect_flag;
-
- /* Called after pvr2_context initialization is complete */
- void (*setup_func)(struct pvr2_context *);
-
-};
-
-struct pvr2_channel {
- struct pvr2_context *mc_head;
- struct pvr2_channel *mc_next;
- struct pvr2_channel *mc_prev;
- struct pvr2_context_stream *stream;
- struct pvr2_hdw *hdw;
- unsigned int input_mask;
- void (*check_func)(struct pvr2_channel *);
-};
-
-struct pvr2_context *pvr2_context_create(struct usb_interface *intf,
- const struct usb_device_id *devid,
- void (*setup_func)(struct pvr2_context *));
-void pvr2_context_disconnect(struct pvr2_context *);
-
-void pvr2_channel_init(struct pvr2_channel *,struct pvr2_context *);
-void pvr2_channel_done(struct pvr2_channel *);
-int pvr2_channel_limit_inputs(struct pvr2_channel *,unsigned int);
-unsigned int pvr2_channel_get_limited_inputs(struct pvr2_channel *);
-int pvr2_channel_claim_stream(struct pvr2_channel *,
- struct pvr2_context_stream *);
-struct pvr2_ioread *pvr2_channel_create_mpeg_stream(
- struct pvr2_context_stream *);
-
-int pvr2_context_global_init(void);
-void pvr2_context_global_done(void);
-
-#endif /* __PVRUSB2_CONTEXT_H */
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
deleted file mode 100644
index 88320900dbd..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
-
- This source file is specifically designed to interface with the
- v4l-dvb cs53l32a module.
-
-*/
-
-#include "pvrusb2-cs53l32a.h"
-
-
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <linux/errno.h>
-
-struct routing_scheme {
- const int *def;
- unsigned int cnt;
-};
-
-
-static const int routing_scheme1[] = {
- [PVR2_CVAL_INPUT_TV] = 2, /* 1 or 2 seems to work here */
- [PVR2_CVAL_INPUT_RADIO] = 2,
- [PVR2_CVAL_INPUT_COMPOSITE] = 0,
- [PVR2_CVAL_INPUT_SVIDEO] = 0,
-};
-
-static const struct routing_scheme routing_def1 = {
- .def = routing_scheme1,
- .cnt = ARRAY_SIZE(routing_scheme1),
-};
-
-static const struct routing_scheme *routing_schemes[] = {
- [PVR2_ROUTING_SCHEME_ONAIR] = &routing_def1,
-};
-
-
-void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
-{
- if (hdw->input_dirty || hdw->force_dirty) {
- const struct routing_scheme *sp;
- unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
- u32 input;
- pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
- hdw->input_val);
- sp = (sid < ARRAY_SIZE(routing_schemes)) ?
- routing_schemes[sid] : NULL;
- if ((sp == NULL) ||
- (hdw->input_val < 0) ||
- (hdw->input_val >= sp->cnt)) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "*** WARNING *** subdev v4l2 set_input:"
- " Invalid routing scheme (%u)"
- " and/or input (%d)",
- sid, hdw->input_val);
- return;
- }
- input = sp->def[hdw->input_val];
- sd->ops->audio->s_routing(sd, input, 0, 0);
- }
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h
deleted file mode 100644
index 53ba548b72a..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef __PVRUSB2_CS53L32A_H
-#define __PVRUSB2_CS53L32A_H
-
-/*
-
- This module connects the pvrusb2 driver to the I2C chip level
- driver which handles device video processing. This interface is
- used internally by the driver; higher level code should only
- interact through the interface provided by pvrusb2-hdw.h.
-
-*/
-
-
-#include "pvrusb2-hdw-internal.h"
-void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
-
-#endif /* __PVRUSB2_AUDIO_CS53L32A_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
deleted file mode 100644
index 7d5a7139a45..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "pvrusb2-ctrl.h"
-#include "pvrusb2-hdw-internal.h"
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mutex.h>
-
-
-static int pvr2_ctrl_range_check(struct pvr2_ctrl *cptr,int val)
-{
- if (cptr->info->check_value) {
- if (!cptr->info->check_value(cptr,val)) return -ERANGE;
- } else if (cptr->info->type == pvr2_ctl_enum) {
- if (val < 0) return -ERANGE;
- if (val >= cptr->info->def.type_enum.count) return -ERANGE;
- } else {
- int lim;
- lim = cptr->info->def.type_int.min_value;
- if (cptr->info->get_min_value) {
- cptr->info->get_min_value(cptr,&lim);
- }
- if (val < lim) return -ERANGE;
- lim = cptr->info->def.type_int.max_value;
- if (cptr->info->get_max_value) {
- cptr->info->get_max_value(cptr,&lim);
- }
- if (val > lim) return -ERANGE;
- }
- return 0;
-}
-
-
-/* Set the given control. */
-int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val)
-{
- return pvr2_ctrl_set_mask_value(cptr,~0,val);
-}
-
-
-/* Set/clear specific bits of the given control. */
-int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val)
-{
- int ret = 0;
- if (!cptr) return -EINVAL;
- LOCK_TAKE(cptr->hdw->big_lock); do {
- if (cptr->info->set_value) {
- if (cptr->info->type == pvr2_ctl_bitmask) {
- mask &= cptr->info->def.type_bitmask.valid_bits;
- } else if ((cptr->info->type == pvr2_ctl_int)||
- (cptr->info->type == pvr2_ctl_enum)) {
- ret = pvr2_ctrl_range_check(cptr,val);
- if (ret < 0) break;
- } else if (cptr->info->type != pvr2_ctl_bool) {
- break;
- }
- ret = cptr->info->set_value(cptr,mask,val);
- } else {
- ret = -EPERM;
- }
- } while(0); LOCK_GIVE(cptr->hdw->big_lock);
- return ret;
-}
-
-
-/* Get the current value of the given control. */
-int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr,int *valptr)
-{
- int ret = 0;
- if (!cptr) return -EINVAL;
- LOCK_TAKE(cptr->hdw->big_lock); do {
- ret = cptr->info->get_value(cptr,valptr);
- } while(0); LOCK_GIVE(cptr->hdw->big_lock);
- return ret;
-}
-
-
-/* Retrieve control's type */
-enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *cptr)
-{
- if (!cptr) return pvr2_ctl_int;
- return cptr->info->type;
-}
-
-
-/* Retrieve control's maximum value (int type) */
-int pvr2_ctrl_get_max(struct pvr2_ctrl *cptr)
-{
- int ret = 0;
- if (!cptr) return 0;
- LOCK_TAKE(cptr->hdw->big_lock); do {
- if (cptr->info->get_max_value) {
- cptr->info->get_max_value(cptr,&ret);
- } else if (cptr->info->type == pvr2_ctl_int) {
- ret = cptr->info->def.type_int.max_value;
- }
- } while(0); LOCK_GIVE(cptr->hdw->big_lock);
- return ret;
-}
-
-
-/* Retrieve control's minimum value (int type) */
-int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr)
-{
- int ret = 0;
- if (!cptr) return 0;
- LOCK_TAKE(cptr->hdw->big_lock); do {
- if (cptr->info->get_min_value) {
- cptr->info->get_min_value(cptr,&ret);
- } else if (cptr->info->type == pvr2_ctl_int) {
- ret = cptr->info->def.type_int.min_value;
- }
- } while(0); LOCK_GIVE(cptr->hdw->big_lock);
- return ret;
-}
-
-
-/* Retrieve control's default value (any type) */
-int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr, int *valptr)
-{
- int ret = 0;
- if (!cptr) return -EINVAL;
- LOCK_TAKE(cptr->hdw->big_lock); do {
- if (cptr->info->get_def_value) {
- ret = cptr->info->get_def_value(cptr, valptr);
- } else {
- *valptr = cptr->info->default_value;
- }
- } while(0); LOCK_GIVE(cptr->hdw->big_lock);
- return ret;
-}
-
-
-/* Retrieve control's enumeration count (enum only) */
-int pvr2_ctrl_get_cnt(struct pvr2_ctrl *cptr)
-{
- int ret = 0;
- if (!cptr) return 0;
- LOCK_TAKE(cptr->hdw->big_lock); do {
- if (cptr->info->type == pvr2_ctl_enum) {
- ret = cptr->info->def.type_enum.count;
- }
- } while(0); LOCK_GIVE(cptr->hdw->big_lock);
- return ret;
-}
-
-
-/* Retrieve control's valid mask bits (bit mask only) */
-int pvr2_ctrl_get_mask(struct pvr2_ctrl *cptr)
-{
- int ret = 0;
- if (!cptr) return 0;
- LOCK_TAKE(cptr->hdw->big_lock); do {
- if (cptr->info->type == pvr2_ctl_bitmask) {
- ret = cptr->info->def.type_bitmask.valid_bits;
- }
- } while(0); LOCK_GIVE(cptr->hdw->big_lock);
- return ret;
-}
-
-
-/* Retrieve the control's name */
-const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr)
-{
- if (!cptr) return NULL;
- return cptr->info->name;
-}
-
-
-/* Retrieve the control's desc */
-const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr)
-{
- if (!cptr) return NULL;
- return cptr->info->desc;
-}
-
-
-/* Retrieve a control enumeration or bit mask value */
-int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val,
- char *bptr,unsigned int bmax,
- unsigned int *blen)
-{
- int ret = -EINVAL;
- if (!cptr) return 0;
- *blen = 0;
- LOCK_TAKE(cptr->hdw->big_lock); do {
- if (cptr->info->type == pvr2_ctl_enum) {
- const char * const *names;
- names = cptr->info->def.type_enum.value_names;
- if (pvr2_ctrl_range_check(cptr,val) == 0) {
- if (names[val]) {
- *blen = scnprintf(
- bptr,bmax,"%s",
- names[val]);
- } else {
- *blen = 0;
- }
- ret = 0;
- }
- } else if (cptr->info->type == pvr2_ctl_bitmask) {
- const char **names;
- unsigned int idx;
- int msk;
- names = cptr->info->def.type_bitmask.bit_names;
- val &= cptr->info->def.type_bitmask.valid_bits;
- for (idx = 0, msk = 1; val; idx++, msk <<= 1) {
- if (val & msk) {
- *blen = scnprintf(bptr,bmax,"%s",
- names[idx]);
- ret = 0;
- break;
- }
- }
- }
- } while(0); LOCK_GIVE(cptr->hdw->big_lock);
- return ret;
-}
-
-
-/* Return V4L ID for this control or zero if none */
-int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *cptr)
-{
- if (!cptr) return 0;
- return cptr->info->v4l_id;
-}
-
-
-unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *cptr)
-{
- unsigned int flags = 0;
-
- if (cptr->info->get_v4lflags) {
- flags = cptr->info->get_v4lflags(cptr);
- }
-
- if (cptr->info->set_value) {
- flags &= ~V4L2_CTRL_FLAG_READ_ONLY;
- } else {
- flags |= V4L2_CTRL_FLAG_READ_ONLY;
- }
-
- return flags;
-}
-
-
-/* Return true if control is writable */
-int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr)
-{
- if (!cptr) return 0;
- return cptr->info->set_value != NULL;
-}
-
-
-/* Return true if control has custom symbolic representation */
-int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *cptr)
-{
- if (!cptr) return 0;
- if (!cptr->info->val_to_sym) return 0;
- if (!cptr->info->sym_to_val) return 0;
- return !0;
-}
-
-
-/* Convert a given mask/val to a custom symbolic value */
-int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *cptr,
- int mask,int val,
- char *buf,unsigned int maxlen,
- unsigned int *len)
-{
- if (!cptr) return -EINVAL;
- if (!cptr->info->val_to_sym) return -EINVAL;
- return cptr->info->val_to_sym(cptr,mask,val,buf,maxlen,len);
-}
-
-
-/* Convert a symbolic value to a mask/value pair */
-int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *cptr,
- const char *buf,unsigned int len,
- int *maskptr,int *valptr)
-{
- if (!cptr) return -EINVAL;
- if (!cptr->info->sym_to_val) return -EINVAL;
- return cptr->info->sym_to_val(cptr,buf,len,maskptr,valptr);
-}
-
-
-static unsigned int gen_bitmask_string(int msk,int val,int msk_only,
- const char **names,
- char *ptr,unsigned int len)
-{
- unsigned int idx;
- long sm,um;
- int spcFl;
- unsigned int uc,cnt;
- const char *idStr;
-
- spcFl = 0;
- uc = 0;
- um = 0;
- for (idx = 0, sm = 1; msk; idx++, sm <<= 1) {
- if (sm & msk) {
- msk &= ~sm;
- idStr = names[idx];
- if (idStr) {
- cnt = scnprintf(ptr,len,"%s%s%s",
- (spcFl ? " " : ""),
- (msk_only ? "" :
- ((val & sm) ? "+" : "-")),
- idStr);
- ptr += cnt; len -= cnt; uc += cnt;
- spcFl = !0;
- } else {
- um |= sm;
- }
- }
- }
- if (um) {
- if (msk_only) {
- cnt = scnprintf(ptr,len,"%s0x%lx",
- (spcFl ? " " : ""),
- um);
- ptr += cnt; len -= cnt; uc += cnt;
- spcFl = !0;
- } else if (um & val) {
- cnt = scnprintf(ptr,len,"%s+0x%lx",
- (spcFl ? " " : ""),
- um & val);
- ptr += cnt; len -= cnt; uc += cnt;
- spcFl = !0;
- } else if (um & ~val) {
- cnt = scnprintf(ptr,len,"%s+0x%lx",
- (spcFl ? " " : ""),
- um & ~val);
- ptr += cnt; len -= cnt; uc += cnt;
- spcFl = !0;
- }
- }
- return uc;
-}
-
-
-static const char *boolNames[] = {
- "false",
- "true",
- "no",
- "yes",
-};
-
-
-static int parse_token(const char *ptr,unsigned int len,
- int *valptr,
- const char * const *names, unsigned int namecnt)
-{
- char buf[33];
- unsigned int slen;
- unsigned int idx;
- int negfl;
- char *p2;
- *valptr = 0;
- if (!names) namecnt = 0;
- for (idx = 0; idx < namecnt; idx++) {
- if (!names[idx]) continue;
- slen = strlen(names[idx]);
- if (slen != len) continue;
- if (memcmp(names[idx],ptr,slen)) continue;
- *valptr = idx;
- return 0;
- }
- negfl = 0;
- if ((*ptr == '-') || (*ptr == '+')) {
- negfl = (*ptr == '-');
- ptr++; len--;
- }
- if (len >= sizeof(buf)) return -EINVAL;
- memcpy(buf,ptr,len);
- buf[len] = 0;
- *valptr = simple_strtol(buf,&p2,0);
- if (negfl) *valptr = -(*valptr);
- if (*p2) return -EINVAL;
- return 1;
-}
-
-
-static int parse_mtoken(const char *ptr,unsigned int len,
- int *valptr,
- const char **names,int valid_bits)
-{
- char buf[33];
- unsigned int slen;
- unsigned int idx;
- char *p2;
- int msk;
- *valptr = 0;
- for (idx = 0, msk = 1; valid_bits; idx++, msk <<= 1) {
- if (!(msk & valid_bits)) continue;
- valid_bits &= ~msk;
- if (!names[idx]) continue;
- slen = strlen(names[idx]);
- if (slen != len) continue;
- if (memcmp(names[idx],ptr,slen)) continue;
- *valptr = msk;
- return 0;
- }
- if (len >= sizeof(buf)) return -EINVAL;
- memcpy(buf,ptr,len);
- buf[len] = 0;
- *valptr = simple_strtol(buf,&p2,0);
- if (*p2) return -EINVAL;
- return 0;
-}
-
-
-static int parse_tlist(const char *ptr,unsigned int len,
- int *maskptr,int *valptr,
- const char **names,int valid_bits)
-{
- unsigned int cnt;
- int mask,val,kv,mode,ret;
- mask = 0;
- val = 0;
- ret = 0;
- while (len) {
- cnt = 0;
- while ((cnt < len) &&
- ((ptr[cnt] <= 32) ||
- (ptr[cnt] >= 127))) cnt++;
- ptr += cnt;
- len -= cnt;
- mode = 0;
- if ((*ptr == '-') || (*ptr == '+')) {
- mode = (*ptr == '-') ? -1 : 1;
- ptr++;
- len--;
- }
- cnt = 0;
- while (cnt < len) {
- if (ptr[cnt] <= 32) break;
- if (ptr[cnt] >= 127) break;
- cnt++;
- }
- if (!cnt) break;
- if (parse_mtoken(ptr,cnt,&kv,names,valid_bits)) {
- ret = -EINVAL;
- break;
- }
- ptr += cnt;
- len -= cnt;
- switch (mode) {
- case 0:
- mask = valid_bits;
- val |= kv;
- break;
- case -1:
- mask |= kv;
- val &= ~kv;
- break;
- case 1:
- mask |= kv;
- val |= kv;
- break;
- default:
- break;
- }
- }
- *maskptr = mask;
- *valptr = val;
- return ret;
-}
-
-
-/* Convert a symbolic value to a mask/value pair */
-int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
- const char *ptr,unsigned int len,
- int *maskptr,int *valptr)
-{
- int ret = -EINVAL;
- unsigned int cnt;
-
- *maskptr = 0;
- *valptr = 0;
-
- cnt = 0;
- while ((cnt < len) && ((ptr[cnt] <= 32) || (ptr[cnt] >= 127))) cnt++;
- len -= cnt; ptr += cnt;
- cnt = 0;
- while ((cnt < len) && ((ptr[len-(cnt+1)] <= 32) ||
- (ptr[len-(cnt+1)] >= 127))) cnt++;
- len -= cnt;
-
- if (!len) return -EINVAL;
-
- LOCK_TAKE(cptr->hdw->big_lock); do {
- if (cptr->info->type == pvr2_ctl_int) {
- ret = parse_token(ptr,len,valptr,NULL,0);
- if (ret >= 0) {
- ret = pvr2_ctrl_range_check(cptr,*valptr);
- }
- *maskptr = ~0;
- } else if (cptr->info->type == pvr2_ctl_bool) {
- ret = parse_token(ptr,len,valptr,boolNames,
- ARRAY_SIZE(boolNames));
- if (ret == 1) {
- *valptr = *valptr ? !0 : 0;
- } else if (ret == 0) {
- *valptr = (*valptr & 1) ? !0 : 0;
- }
- *maskptr = 1;
- } else if (cptr->info->type == pvr2_ctl_enum) {
- ret = parse_token(
- ptr,len,valptr,
- cptr->info->def.type_enum.value_names,
- cptr->info->def.type_enum.count);
- if (ret >= 0) {
- ret = pvr2_ctrl_range_check(cptr,*valptr);
- }
- *maskptr = ~0;
- } else if (cptr->info->type == pvr2_ctl_bitmask) {
- ret = parse_tlist(
- ptr,len,maskptr,valptr,
- cptr->info->def.type_bitmask.bit_names,
- cptr->info->def.type_bitmask.valid_bits);
- }
- } while(0); LOCK_GIVE(cptr->hdw->big_lock);
- return ret;
-}
-
-
-/* Convert a given mask/val to a symbolic value */
-int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr,
- int mask,int val,
- char *buf,unsigned int maxlen,
- unsigned int *len)
-{
- int ret = -EINVAL;
-
- *len = 0;
- if (cptr->info->type == pvr2_ctl_int) {
- *len = scnprintf(buf,maxlen,"%d",val);
- ret = 0;
- } else if (cptr->info->type == pvr2_ctl_bool) {
- *len = scnprintf(buf,maxlen,"%s",val ? "true" : "false");
- ret = 0;
- } else if (cptr->info->type == pvr2_ctl_enum) {
- const char * const *names;
- names = cptr->info->def.type_enum.value_names;
- if ((val >= 0) &&
- (val < cptr->info->def.type_enum.count)) {
- if (names[val]) {
- *len = scnprintf(
- buf,maxlen,"%s",
- names[val]);
- } else {
- *len = 0;
- }
- ret = 0;
- }
- } else if (cptr->info->type == pvr2_ctl_bitmask) {
- *len = gen_bitmask_string(
- val & mask & cptr->info->def.type_bitmask.valid_bits,
- ~0,!0,
- cptr->info->def.type_bitmask.bit_names,
- buf,maxlen);
- }
- return ret;
-}
-
-
-/* Convert a given mask/val to a symbolic value */
-int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *cptr,
- int mask,int val,
- char *buf,unsigned int maxlen,
- unsigned int *len)
-{
- int ret;
- LOCK_TAKE(cptr->hdw->big_lock); do {
- ret = pvr2_ctrl_value_to_sym_internal(cptr,mask,val,
- buf,maxlen,len);
- } while(0); LOCK_GIVE(cptr->hdw->big_lock);
- return ret;
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h
deleted file mode 100644
index 794ff90121c..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __PVRUSB2_CTRL_H
-#define __PVRUSB2_CTRL_H
-
-struct pvr2_ctrl;
-
-enum pvr2_ctl_type {
- pvr2_ctl_int = 0,
- pvr2_ctl_enum = 1,
- pvr2_ctl_bitmask = 2,
- pvr2_ctl_bool = 3,
-};
-
-
-/* Set the given control. */
-int pvr2_ctrl_set_value(struct pvr2_ctrl *,int val);
-
-/* Set/clear specific bits of the given control. */
-int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *,int mask,int val);
-
-/* Get the current value of the given control. */
-int pvr2_ctrl_get_value(struct pvr2_ctrl *,int *valptr);
-
-/* Retrieve control's type */
-enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *);
-
-/* Retrieve control's maximum value (int type) */
-int pvr2_ctrl_get_max(struct pvr2_ctrl *);
-
-/* Retrieve control's minimum value (int type) */
-int pvr2_ctrl_get_min(struct pvr2_ctrl *);
-
-/* Retrieve control's default value (any type) */
-int pvr2_ctrl_get_def(struct pvr2_ctrl *, int *valptr);
-
-/* Retrieve control's enumeration count (enum only) */
-int pvr2_ctrl_get_cnt(struct pvr2_ctrl *);
-
-/* Retrieve control's valid mask bits (bit mask only) */
-int pvr2_ctrl_get_mask(struct pvr2_ctrl *);
-
-/* Retrieve the control's name */
-const char *pvr2_ctrl_get_name(struct pvr2_ctrl *);
-
-/* Retrieve the control's desc */
-const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *);
-
-/* Retrieve a control enumeration or bit mask value */
-int pvr2_ctrl_get_valname(struct pvr2_ctrl *,int,char *,unsigned int,
- unsigned int *);
-
-/* Return true if control is writable */
-int pvr2_ctrl_is_writable(struct pvr2_ctrl *);
-
-/* Return V4L flags value for control (or zero if there is no v4l control
- actually under this control) */
-unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *);
-
-/* Return V4L ID for this control or zero if none */
-int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *);
-
-/* Return true if control has custom symbolic representation */
-int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *);
-
-/* Convert a given mask/val to a custom symbolic value */
-int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *,
- int mask,int val,
- char *buf,unsigned int maxlen,
- unsigned int *len);
-
-/* Convert a symbolic value to a mask/value pair */
-int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *,
- const char *buf,unsigned int len,
- int *maskptr,int *valptr);
-
-/* Convert a given mask/val to a symbolic value */
-int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *,
- int mask,int val,
- char *buf,unsigned int maxlen,
- unsigned int *len);
-
-/* Convert a symbolic value to a mask/value pair */
-int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *,
- const char *buf,unsigned int len,
- int *maskptr,int *valptr);
-
-/* Convert a given mask/val to a symbolic value - must already be
- inside of critical region. */
-int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *,
- int mask,int val,
- char *buf,unsigned int maxlen,
- unsigned int *len);
-
-#endif /* __PVRUSB2_CTRL_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
deleted file mode 100644
index c514d0b9ffd..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
-
- This source file is specifically designed to interface with the
- cx2584x, in kernels 2.6.16 or newer.
-
-*/
-
-#include "pvrusb2-cx2584x-v4l.h"
-#include "pvrusb2-video-v4l.h"
-
-
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include <media/cx25840.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <linux/errno.h>
-
-
-struct routing_scheme_item {
- int vid;
- int aud;
-};
-
-struct routing_scheme {
- const struct routing_scheme_item *def;
- unsigned int cnt;
-};
-
-static const struct routing_scheme_item routing_scheme0[] = {
- [PVR2_CVAL_INPUT_TV] = {
- .vid = CX25840_COMPOSITE7,
- .aud = CX25840_AUDIO8,
- },
- [PVR2_CVAL_INPUT_RADIO] = { /* Treat the same as composite */
- .vid = CX25840_COMPOSITE3,
- .aud = CX25840_AUDIO_SERIAL,
- },
- [PVR2_CVAL_INPUT_COMPOSITE] = {
- .vid = CX25840_COMPOSITE3,
- .aud = CX25840_AUDIO_SERIAL,
- },
- [PVR2_CVAL_INPUT_SVIDEO] = {
- .vid = CX25840_SVIDEO1,
- .aud = CX25840_AUDIO_SERIAL,
- },
-};
-
-static const struct routing_scheme routing_def0 = {
- .def = routing_scheme0,
- .cnt = ARRAY_SIZE(routing_scheme0),
-};
-
-/* Specific to gotview device */
-static const struct routing_scheme_item routing_schemegv[] = {
- [PVR2_CVAL_INPUT_TV] = {
- .vid = CX25840_COMPOSITE2,
- .aud = CX25840_AUDIO5,
- },
- [PVR2_CVAL_INPUT_RADIO] = {
- /* line-in is used for radio and composite. A GPIO is
- used to switch between the two choices. */
- .vid = CX25840_COMPOSITE1,
- .aud = CX25840_AUDIO_SERIAL,
- },
- [PVR2_CVAL_INPUT_COMPOSITE] = {
- .vid = CX25840_COMPOSITE1,
- .aud = CX25840_AUDIO_SERIAL,
- },
- [PVR2_CVAL_INPUT_SVIDEO] = {
- .vid = (CX25840_SVIDEO_LUMA3|CX25840_SVIDEO_CHROMA4),
- .aud = CX25840_AUDIO_SERIAL,
- },
-};
-
-static const struct routing_scheme routing_defgv = {
- .def = routing_schemegv,
- .cnt = ARRAY_SIZE(routing_schemegv),
-};
-
-/* Specific to grabster av400 device */
-static const struct routing_scheme_item routing_schemeav400[] = {
- [PVR2_CVAL_INPUT_COMPOSITE] = {
- .vid = CX25840_COMPOSITE1,
- .aud = CX25840_AUDIO_SERIAL,
- },
- [PVR2_CVAL_INPUT_SVIDEO] = {
- .vid = (CX25840_SVIDEO_LUMA2|CX25840_SVIDEO_CHROMA4),
- .aud = CX25840_AUDIO_SERIAL,
- },
-};
-
-static const struct routing_scheme routing_defav400 = {
- .def = routing_schemeav400,
- .cnt = ARRAY_SIZE(routing_schemeav400),
-};
-
-static const struct routing_scheme *routing_schemes[] = {
- [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
- [PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
- [PVR2_ROUTING_SCHEME_AV400] = &routing_defav400,
-};
-
-void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
-{
- pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update...");
- if (hdw->input_dirty || hdw->force_dirty) {
- enum cx25840_video_input vid_input;
- enum cx25840_audio_input aud_input;
- const struct routing_scheme *sp;
- unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
-
- sp = (sid < ARRAY_SIZE(routing_schemes)) ?
- routing_schemes[sid] : NULL;
- if ((sp == NULL) ||
- (hdw->input_val < 0) ||
- (hdw->input_val >= sp->cnt)) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "*** WARNING *** subdev cx2584x set_input:"
- " Invalid routing scheme (%u)"
- " and/or input (%d)",
- sid, hdw->input_val);
- return;
- }
- vid_input = sp->def[hdw->input_val].vid;
- aud_input = sp->def[hdw->input_val].aud;
- pvr2_trace(PVR2_TRACE_CHIPS,
- "subdev cx2584x set_input vid=0x%x aud=0x%x",
- vid_input, aud_input);
- sd->ops->video->s_routing(sd, (u32)vid_input, 0, 0);
- sd->ops->audio->s_routing(sd, (u32)aud_input, 0, 0);
- }
-}
-
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
deleted file mode 100644
index e35c2322a08..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef __PVRUSB2_CX2584X_V4L_H
-#define __PVRUSB2_CX2584X_V4L_H
-
-/*
-
- This module connects the pvrusb2 driver to the I2C chip level
- driver which handles combined device audio & video processing.
- This interface is used internally by the driver; higher level code
- should only interact through the interface provided by
- pvrusb2-hdw.h.
-
-*/
-
-
-
-#include "pvrusb2-hdw-internal.h"
-
-void pvr2_cx25840_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd);
-
-
-#endif /* __PVRUSB2_CX2584X_V4L_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debug.h b/drivers/media/video/pvrusb2/pvrusb2-debug.h
deleted file mode 100644
index be79249f862..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-debug.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __PVRUSB2_DEBUG_H
-#define __PVRUSB2_DEBUG_H
-
-extern int pvrusb2_debug;
-
-#define pvr2_trace(msk, fmt, arg...) do {if(msk & pvrusb2_debug) printk(KERN_INFO "pvrusb2: " fmt "\n", ##arg); } while (0)
-
-/* These are listed in *rough* order of decreasing usefulness and
- increasing noise level. */
-#define PVR2_TRACE_INFO (1 << 0) /* Normal messages */
-#define PVR2_TRACE_ERROR_LEGS (1 << 1) /* error messages */
-#define PVR2_TRACE_TOLERANCE (1 << 2) /* track tolerance-affected errors */
-#define PVR2_TRACE_TRAP (1 << 3) /* Trap & report app misbehavior */
-#define PVR2_TRACE_STD (1 << 4) /* Log video standard stuff */
-#define PVR2_TRACE_INIT (1 << 5) /* misc initialization steps */
-#define PVR2_TRACE_START_STOP (1 << 6) /* Streaming start / stop */
-#define PVR2_TRACE_CTL (1 << 7) /* commit of control changes */
-#define PVR2_TRACE_STATE (1 << 8) /* Device state changes */
-#define PVR2_TRACE_STBITS (1 << 9) /* Individual bit state changes */
-#define PVR2_TRACE_EEPROM (1 << 10) /* eeprom parsing / report */
-#define PVR2_TRACE_STRUCT (1 << 11) /* internal struct creation */
-#define PVR2_TRACE_OPEN_CLOSE (1 << 12) /* application open / close */
-#define PVR2_TRACE_CTXT (1 << 13) /* Main context tracking */
-#define PVR2_TRACE_SYSFS (1 << 14) /* Sysfs driven I/O */
-#define PVR2_TRACE_FIRMWARE (1 << 15) /* firmware upload actions */
-#define PVR2_TRACE_CHIPS (1 << 16) /* chip broadcast operation */
-#define PVR2_TRACE_I2C (1 << 17) /* I2C related stuff */
-#define PVR2_TRACE_I2C_CMD (1 << 18) /* Software commands to I2C modules */
-#define PVR2_TRACE_I2C_CORE (1 << 19) /* I2C core debugging */
-#define PVR2_TRACE_I2C_TRAF (1 << 20) /* I2C traffic through the adapter */
-#define PVR2_TRACE_V4LIOCTL (1 << 21) /* v4l ioctl details */
-#define PVR2_TRACE_ENCODER (1 << 22) /* mpeg2 encoder operation */
-#define PVR2_TRACE_BUF_POOL (1 << 23) /* Track buffer pool management */
-#define PVR2_TRACE_BUF_FLOW (1 << 24) /* Track buffer flow in system */
-#define PVR2_TRACE_DATA_FLOW (1 << 25) /* Track data flow */
-#define PVR2_TRACE_DEBUGIFC (1 << 26) /* Debug interface actions */
-#define PVR2_TRACE_GPIO (1 << 27) /* GPIO state bit changes */
-#define PVR2_TRACE_DVB_FEED (1 << 28) /* DVB transport feed debug */
-
-
-#endif /* __PVRUSB2_HDW_INTERNAL_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
deleted file mode 100644
index 4279ebb811a..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/string.h>
-#include "pvrusb2-debugifc.h"
-#include "pvrusb2-hdw.h"
-#include "pvrusb2-debug.h"
-
-struct debugifc_mask_item {
- const char *name;
- unsigned long msk;
-};
-
-
-static unsigned int debugifc_count_whitespace(const char *buf,
- unsigned int count)
-{
- unsigned int scnt;
- char ch;
-
- for (scnt = 0; scnt < count; scnt++) {
- ch = buf[scnt];
- if (ch == ' ') continue;
- if (ch == '\t') continue;
- if (ch == '\n') continue;
- break;
- }
- return scnt;
-}
-
-
-static unsigned int debugifc_count_nonwhitespace(const char *buf,
- unsigned int count)
-{
- unsigned int scnt;
- char ch;
-
- for (scnt = 0; scnt < count; scnt++) {
- ch = buf[scnt];
- if (ch == ' ') break;
- if (ch == '\t') break;
- if (ch == '\n') break;
- }
- return scnt;
-}
-
-
-static unsigned int debugifc_isolate_word(const char *buf,unsigned int count,
- const char **wstrPtr,
- unsigned int *wlenPtr)
-{
- const char *wptr;
- unsigned int consume_cnt = 0;
- unsigned int wlen;
- unsigned int scnt;
-
- wptr = NULL;
- wlen = 0;
- scnt = debugifc_count_whitespace(buf,count);
- consume_cnt += scnt; count -= scnt; buf += scnt;
- if (!count) goto done;
-
- scnt = debugifc_count_nonwhitespace(buf,count);
- if (!scnt) goto done;
- wptr = buf;
- wlen = scnt;
- consume_cnt += scnt; count -= scnt; buf += scnt;
-
- done:
- *wstrPtr = wptr;
- *wlenPtr = wlen;
- return consume_cnt;
-}
-
-
-static int debugifc_parse_unsigned_number(const char *buf,unsigned int count,
- u32 *num_ptr)
-{
- u32 result = 0;
- int radix = 10;
- if ((count >= 2) && (buf[0] == '0') &&
- ((buf[1] == 'x') || (buf[1] == 'X'))) {
- radix = 16;
- count -= 2;
- buf += 2;
- } else if ((count >= 1) && (buf[0] == '0')) {
- radix = 8;
- }
-
- while (count--) {
- int val = hex_to_bin(*buf++);
- if (val < 0 || val >= radix)
- return -EINVAL;
- result *= radix;
- result += val;
- }
- *num_ptr = result;
- return 0;
-}
-
-
-static int debugifc_match_keyword(const char *buf,unsigned int count,
- const char *keyword)
-{
- unsigned int kl;
- if (!keyword) return 0;
- kl = strlen(keyword);
- if (kl != count) return 0;
- return !memcmp(buf,keyword,kl);
-}
-
-
-int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt)
-{
- int bcnt = 0;
- int ccnt;
- ccnt = scnprintf(buf, acnt, "Driver hardware description: %s\n",
- pvr2_hdw_get_desc(hdw));
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
- ccnt = scnprintf(buf,acnt,"Driver state info:\n");
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
- ccnt = pvr2_hdw_state_report(hdw,buf,acnt);
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
-
- return bcnt;
-}
-
-
-int pvr2_debugifc_print_status(struct pvr2_hdw *hdw,
- char *buf,unsigned int acnt)
-{
- int bcnt = 0;
- int ccnt;
- int ret;
- u32 gpio_dir,gpio_in,gpio_out;
- struct pvr2_stream_stats stats;
- struct pvr2_stream *sp;
-
- ret = pvr2_hdw_is_hsm(hdw);
- ccnt = scnprintf(buf,acnt,"USB link speed: %s\n",
- (ret < 0 ? "FAIL" : (ret ? "high" : "full")));
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
-
- gpio_dir = 0; gpio_in = 0; gpio_out = 0;
- pvr2_hdw_gpio_get_dir(hdw,&gpio_dir);
- pvr2_hdw_gpio_get_out(hdw,&gpio_out);
- pvr2_hdw_gpio_get_in(hdw,&gpio_in);
- ccnt = scnprintf(buf,acnt,"GPIO state: dir=0x%x in=0x%x out=0x%x\n",
- gpio_dir,gpio_in,gpio_out);
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
-
- ccnt = scnprintf(buf,acnt,"Streaming is %s\n",
- pvr2_hdw_get_streaming(hdw) ? "on" : "off");
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
-
-
- sp = pvr2_hdw_get_video_stream(hdw);
- if (sp) {
- pvr2_stream_get_stats(sp, &stats, 0);
- ccnt = scnprintf(
- buf,acnt,
- "Bytes streamed=%u"
- " URBs: queued=%u idle=%u ready=%u"
- " processed=%u failed=%u\n",
- stats.bytes_processed,
- stats.buffers_in_queue,
- stats.buffers_in_idle,
- stats.buffers_in_ready,
- stats.buffers_processed,
- stats.buffers_failed);
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
- }
-
- return bcnt;
-}
-
-
-static int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf,
- unsigned int count)
-{
- const char *wptr;
- unsigned int wlen;
- unsigned int scnt;
-
- scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
- if (!scnt) return 0;
- count -= scnt; buf += scnt;
- if (!wptr) return 0;
-
- pvr2_trace(PVR2_TRACE_DEBUGIFC,"debugifc cmd: \"%.*s\"",wlen,wptr);
- if (debugifc_match_keyword(wptr,wlen,"reset")) {
- scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
- if (!scnt) return -EINVAL;
- count -= scnt; buf += scnt;
- if (!wptr) return -EINVAL;
- if (debugifc_match_keyword(wptr,wlen,"cpu")) {
- pvr2_hdw_cpureset_assert(hdw,!0);
- pvr2_hdw_cpureset_assert(hdw,0);
- return 0;
- } else if (debugifc_match_keyword(wptr,wlen,"bus")) {
- pvr2_hdw_device_reset(hdw);
- } else if (debugifc_match_keyword(wptr,wlen,"soft")) {
- return pvr2_hdw_cmd_powerup(hdw);
- } else if (debugifc_match_keyword(wptr,wlen,"deep")) {
- return pvr2_hdw_cmd_deep_reset(hdw);
- } else if (debugifc_match_keyword(wptr,wlen,"firmware")) {
- return pvr2_upload_firmware2(hdw);
- } else if (debugifc_match_keyword(wptr,wlen,"decoder")) {
- return pvr2_hdw_cmd_decoder_reset(hdw);
- } else if (debugifc_match_keyword(wptr,wlen,"worker")) {
- return pvr2_hdw_untrip(hdw);
- } else if (debugifc_match_keyword(wptr,wlen,"usbstats")) {
- pvr2_stream_get_stats(pvr2_hdw_get_video_stream(hdw),
- NULL, !0);
- return 0;
- }
- return -EINVAL;
- } else if (debugifc_match_keyword(wptr,wlen,"cpufw")) {
- scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
- if (!scnt) return -EINVAL;
- count -= scnt; buf += scnt;
- if (!wptr) return -EINVAL;
- if (debugifc_match_keyword(wptr,wlen,"fetch")) {
- scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
- if (scnt && wptr) {
- count -= scnt; buf += scnt;
- if (debugifc_match_keyword(wptr, wlen,
- "prom")) {
- pvr2_hdw_cpufw_set_enabled(hdw, 2, !0);
- } else if (debugifc_match_keyword(wptr, wlen,
- "ram8k")) {
- pvr2_hdw_cpufw_set_enabled(hdw, 0, !0);
- } else if (debugifc_match_keyword(wptr, wlen,
- "ram16k")) {
- pvr2_hdw_cpufw_set_enabled(hdw, 1, !0);
- } else {
- return -EINVAL;
- }
- }
- pvr2_hdw_cpufw_set_enabled(hdw,0,!0);
- return 0;
- } else if (debugifc_match_keyword(wptr,wlen,"done")) {
- pvr2_hdw_cpufw_set_enabled(hdw,0,0);
- return 0;
- } else {
- return -EINVAL;
- }
- } else if (debugifc_match_keyword(wptr,wlen,"gpio")) {
- int dir_fl = 0;
- int ret;
- u32 msk,val;
- scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
- if (!scnt) return -EINVAL;
- count -= scnt; buf += scnt;
- if (!wptr) return -EINVAL;
- if (debugifc_match_keyword(wptr,wlen,"dir")) {
- dir_fl = !0;
- } else if (!debugifc_match_keyword(wptr,wlen,"out")) {
- return -EINVAL;
- }
- scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
- if (!scnt) return -EINVAL;
- count -= scnt; buf += scnt;
- if (!wptr) return -EINVAL;
- ret = debugifc_parse_unsigned_number(wptr,wlen,&msk);
- if (ret) return ret;
- scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
- if (wptr) {
- ret = debugifc_parse_unsigned_number(wptr,wlen,&val);
- if (ret) return ret;
- } else {
- val = msk;
- msk = 0xffffffff;
- }
- if (dir_fl) {
- ret = pvr2_hdw_gpio_chg_dir(hdw,msk,val);
- } else {
- ret = pvr2_hdw_gpio_chg_out(hdw,msk,val);
- }
- return ret;
- }
- pvr2_trace(PVR2_TRACE_DEBUGIFC,
- "debugifc failed to recognize cmd: \"%.*s\"",wlen,wptr);
- return -EINVAL;
-}
-
-
-int pvr2_debugifc_docmd(struct pvr2_hdw *hdw,const char *buf,
- unsigned int count)
-{
- unsigned int bcnt = 0;
- int ret;
-
- while (count) {
- for (bcnt = 0; bcnt < count; bcnt++) {
- if (buf[bcnt] == '\n') break;
- }
-
- ret = pvr2_debugifc_do1cmd(hdw,buf,bcnt);
- if (ret < 0) return ret;
- if (bcnt < count) bcnt++;
- buf += bcnt;
- count -= bcnt;
- }
-
- return 0;
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
deleted file mode 100644
index 2f8d46761cd..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __PVRUSB2_DEBUGIFC_H
-#define __PVRUSB2_DEBUGIFC_H
-
-struct pvr2_hdw;
-
-/* Print general status of driver. This will also trigger a probe of
- the USB link. Unlike print_info(), this one synchronizes with the
- driver so the information should be self-consistent (but it will
- hang if the driver is wedged). */
-int pvr2_debugifc_print_info(struct pvr2_hdw *,
- char *buf_ptr, unsigned int buf_size);
-
-/* Non-intrusively print some useful debugging info from inside the
- driver. This should work even if the driver appears to be
- wedged. */
-int pvr2_debugifc_print_status(struct pvr2_hdw *,
- char *buf_ptr,unsigned int buf_size);
-
-/* Parse a string command into a driver action. */
-int pvr2_debugifc_docmd(struct pvr2_hdw *,
- const char *buf_ptr,unsigned int buf_size);
-
-#endif /* __PVRUSB2_DEBUGIFC_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
deleted file mode 100644
index d8c898278e8..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ /dev/null
@@ -1,569 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2007 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
-
-This source file should encompass ALL per-device type information for the
-driver. To define a new device, add elements to the pvr2_device_table and
-pvr2_device_desc structures.
-
-*/
-
-#include "pvrusb2-devattr.h"
-#include <linux/usb.h>
-#include <linux/module.h>
-/* This is needed in order to pull in tuner type ids... */
-#include <linux/i2c.h>
-#include <media/tuner.h>
-#ifdef CONFIG_VIDEO_PVRUSB2_DVB
-#include "pvrusb2-hdw-internal.h"
-#include "lgdt330x.h"
-#include "s5h1409.h"
-#include "s5h1411.h"
-#include "tda10048.h"
-#include "tda18271.h"
-#include "tda8290.h"
-#include "tuner-simple.h"
-#endif
-
-
-/*------------------------------------------------------------------------*/
-/* Hauppauge PVR-USB2 Model 29xxx */
-
-static const struct pvr2_device_client_desc pvr2_cli_29xxx[] = {
- { .module_id = PVR2_CLIENT_ID_SAA7115 },
- { .module_id = PVR2_CLIENT_ID_MSP3400 },
- { .module_id = PVR2_CLIENT_ID_TUNER },
- { .module_id = PVR2_CLIENT_ID_DEMOD },
-};
-
-static const char *pvr2_fw1_names_29xxx[] = {
- "v4l-pvrusb2-29xxx-01.fw",
-};
-
-static const struct pvr2_device_desc pvr2_device_29xxx = {
- .description = "WinTV PVR USB2 Model 29xxx",
- .shortname = "29xxx",
- .client_table.lst = pvr2_cli_29xxx,
- .client_table.cnt = ARRAY_SIZE(pvr2_cli_29xxx),
- .fx2_firmware.lst = pvr2_fw1_names_29xxx,
- .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_29xxx),
- .flag_has_hauppauge_rom = !0,
- .flag_has_analogtuner = !0,
- .flag_has_fmradio = !0,
- .flag_has_composite = !0,
- .flag_has_svideo = !0,
- .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
- .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
- .ir_scheme = PVR2_IR_SCHEME_29XXX,
-};
-
-
-
-/*------------------------------------------------------------------------*/
-/* Hauppauge PVR-USB2 Model 24xxx */
-
-static const struct pvr2_device_client_desc pvr2_cli_24xxx[] = {
- { .module_id = PVR2_CLIENT_ID_CX25840 },
- { .module_id = PVR2_CLIENT_ID_TUNER },
- { .module_id = PVR2_CLIENT_ID_WM8775 },
- { .module_id = PVR2_CLIENT_ID_DEMOD },
-};
-
-static const char *pvr2_fw1_names_24xxx[] = {
- "v4l-pvrusb2-24xxx-01.fw",
-};
-
-static const struct pvr2_device_desc pvr2_device_24xxx = {
- .description = "WinTV PVR USB2 Model 24xxx",
- .shortname = "24xxx",
- .client_table.lst = pvr2_cli_24xxx,
- .client_table.cnt = ARRAY_SIZE(pvr2_cli_24xxx),
- .fx2_firmware.lst = pvr2_fw1_names_24xxx,
- .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_24xxx),
- .flag_has_cx25840 = !0,
- .flag_has_wm8775 = !0,
- .flag_has_hauppauge_rom = !0,
- .flag_has_analogtuner = !0,
- .flag_has_fmradio = !0,
- .flag_has_composite = !0,
- .flag_has_svideo = !0,
- .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
- .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
- .ir_scheme = PVR2_IR_SCHEME_24XXX,
-};
-
-
-
-/*------------------------------------------------------------------------*/
-/* GOTVIEW USB2.0 DVD2 */
-
-static const struct pvr2_device_client_desc pvr2_cli_gotview_2[] = {
- { .module_id = PVR2_CLIENT_ID_CX25840 },
- { .module_id = PVR2_CLIENT_ID_TUNER },
- { .module_id = PVR2_CLIENT_ID_DEMOD },
-};
-
-static const struct pvr2_device_desc pvr2_device_gotview_2 = {
- .description = "Gotview USB 2.0 DVD 2",
- .shortname = "gv2",
- .client_table.lst = pvr2_cli_gotview_2,
- .client_table.cnt = ARRAY_SIZE(pvr2_cli_gotview_2),
- .flag_has_cx25840 = !0,
- .default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .flag_has_analogtuner = !0,
- .flag_has_fmradio = !0,
- .flag_has_composite = !0,
- .flag_has_svideo = !0,
- .signal_routing_scheme = PVR2_ROUTING_SCHEME_GOTVIEW,
-};
-
-
-
-/*------------------------------------------------------------------------*/
-/* GOTVIEW USB2.0 DVD Deluxe */
-
-/* (same module list as gotview_2) */
-
-static const struct pvr2_device_desc pvr2_device_gotview_2d = {
- .description = "Gotview USB 2.0 DVD Deluxe",
- .shortname = "gv2d",
- .client_table.lst = pvr2_cli_gotview_2,
- .client_table.cnt = ARRAY_SIZE(pvr2_cli_gotview_2),
- .flag_has_cx25840 = !0,
- .default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .flag_has_analogtuner = !0,
- .flag_has_composite = !0,
- .flag_has_svideo = !0,
- .signal_routing_scheme = PVR2_ROUTING_SCHEME_GOTVIEW,
-};
-
-
-
-/*------------------------------------------------------------------------*/
-/* Terratec Grabster AV400 */
-
-static const struct pvr2_device_client_desc pvr2_cli_av400[] = {
- { .module_id = PVR2_CLIENT_ID_CX25840 },
-};
-
-static const struct pvr2_device_desc pvr2_device_av400 = {
- .description = "Terratec Grabster AV400",
- .shortname = "av400",
- .flag_is_experimental = 1,
- .client_table.lst = pvr2_cli_av400,
- .client_table.cnt = ARRAY_SIZE(pvr2_cli_av400),
- .flag_has_cx25840 = !0,
- .flag_has_analogtuner = 0,
- .flag_has_composite = !0,
- .flag_has_svideo = !0,
- .signal_routing_scheme = PVR2_ROUTING_SCHEME_AV400,
-};
-
-
-
-/*------------------------------------------------------------------------*/
-/* OnAir Creator */
-
-#ifdef CONFIG_VIDEO_PVRUSB2_DVB
-static struct lgdt330x_config pvr2_lgdt3303_config = {
- .demod_address = 0x0e,
- .demod_chip = LGDT3303,
- .clock_polarity_flip = 1,
-};
-
-static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap)
-{
- adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config,
- &adap->channel.hdw->i2c_adap);
- if (adap->fe)
- return 0;
-
- return -EIO;
-}
-
-static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap)
-{
- dvb_attach(simple_tuner_attach, adap->fe,
- &adap->channel.hdw->i2c_adap, 0x61,
- TUNER_LG_TDVS_H06XF);
-
- return 0;
-}
-
-static const struct pvr2_dvb_props pvr2_onair_creator_fe_props = {
- .frontend_attach = pvr2_lgdt3303_attach,
- .tuner_attach = pvr2_lgh06xf_attach,
-};
-#endif
-
-static const struct pvr2_device_client_desc pvr2_cli_onair_creator[] = {
- { .module_id = PVR2_CLIENT_ID_SAA7115 },
- { .module_id = PVR2_CLIENT_ID_CS53L32A },
- { .module_id = PVR2_CLIENT_ID_TUNER },
-};
-
-static const struct pvr2_device_desc pvr2_device_onair_creator = {
- .description = "OnAir Creator Hybrid USB tuner",
- .shortname = "oac",
- .client_table.lst = pvr2_cli_onair_creator,
- .client_table.cnt = ARRAY_SIZE(pvr2_cli_onair_creator),
- .default_tuner_type = TUNER_LG_TDVS_H06XF,
- .flag_has_analogtuner = !0,
- .flag_has_composite = !0,
- .flag_has_svideo = !0,
- .flag_digital_requires_cx23416 = !0,
- .signal_routing_scheme = PVR2_ROUTING_SCHEME_ONAIR,
- .digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR,
- .default_std_mask = V4L2_STD_NTSC_M,
-#ifdef CONFIG_VIDEO_PVRUSB2_DVB
- .dvb_props = &pvr2_onair_creator_fe_props,
-#endif
-};
-
-
-
-/*------------------------------------------------------------------------*/
-/* OnAir USB 2.0 */
-
-#ifdef CONFIG_VIDEO_PVRUSB2_DVB
-static struct lgdt330x_config pvr2_lgdt3302_config = {
- .demod_address = 0x0e,
- .demod_chip = LGDT3302,
-};
-
-static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap)
-{
- adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config,
- &adap->channel.hdw->i2c_adap);
- if (adap->fe)
- return 0;
-
- return -EIO;
-}
-
-static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap)
-{
- dvb_attach(simple_tuner_attach, adap->fe,
- &adap->channel.hdw->i2c_adap, 0x61,
- TUNER_PHILIPS_FCV1236D);
-
- return 0;
-}
-
-static const struct pvr2_dvb_props pvr2_onair_usb2_fe_props = {
- .frontend_attach = pvr2_lgdt3302_attach,
- .tuner_attach = pvr2_fcv1236d_attach,
-};
-#endif
-
-static const struct pvr2_device_client_desc pvr2_cli_onair_usb2[] = {
- { .module_id = PVR2_CLIENT_ID_SAA7115 },
- { .module_id = PVR2_CLIENT_ID_CS53L32A },
- { .module_id = PVR2_CLIENT_ID_TUNER },
-};
-
-static const struct pvr2_device_desc pvr2_device_onair_usb2 = {
- .description = "OnAir USB2 Hybrid USB tuner",
- .shortname = "oa2",
- .client_table.lst = pvr2_cli_onair_usb2,
- .client_table.cnt = ARRAY_SIZE(pvr2_cli_onair_usb2),
- .default_tuner_type = TUNER_PHILIPS_FCV1236D,
- .flag_has_analogtuner = !0,
- .flag_has_composite = !0,
- .flag_has_svideo = !0,
- .flag_digital_requires_cx23416 = !0,
- .signal_routing_scheme = PVR2_ROUTING_SCHEME_ONAIR,
- .digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR,
- .default_std_mask = V4L2_STD_NTSC_M,
-#ifdef CONFIG_VIDEO_PVRUSB2_DVB
- .dvb_props = &pvr2_onair_usb2_fe_props,
-#endif
-};
-
-
-
-/*------------------------------------------------------------------------*/
-/* Hauppauge PVR-USB2 Model 73xxx */
-
-#ifdef CONFIG_VIDEO_PVRUSB2_DVB
-static struct tda10048_config hauppauge_tda10048_config = {
- .demod_address = 0x10 >> 1,
- .output_mode = TDA10048_PARALLEL_OUTPUT,
- .fwbulkwritelen = TDA10048_BULKWRITE_50,
- .inversion = TDA10048_INVERSION_ON,
- .dtv6_if_freq_khz = TDA10048_IF_3300,
- .dtv7_if_freq_khz = TDA10048_IF_3800,
- .dtv8_if_freq_khz = TDA10048_IF_4300,
- .clk_freq_khz = TDA10048_CLK_16000,
- .disable_gate_access = 1,
-};
-
-static struct tda829x_config tda829x_no_probe = {
- .probe_tuner = TDA829X_DONT_PROBE,
-};
-
-static struct tda18271_std_map hauppauge_tda18271_dvbt_std_map = {
- .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
- .if_lvl = 1, .rfagc_top = 0x37, },
- .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5,
- .if_lvl = 1, .rfagc_top = 0x37, },
- .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6,
- .if_lvl = 1, .rfagc_top = 0x37, },
-};
-
-static struct tda18271_config hauppauge_tda18271_dvb_config = {
- .std_map = &hauppauge_tda18271_dvbt_std_map,
- .gate = TDA18271_GATE_ANALOG,
- .output_opt = TDA18271_OUTPUT_LT_OFF,
-};
-
-static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
-{
- adap->fe = dvb_attach(tda10048_attach, &hauppauge_tda10048_config,
- &adap->channel.hdw->i2c_adap);
- if (adap->fe)
- return 0;
-
- return -EIO;
-}
-
-static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
-{
- dvb_attach(tda829x_attach, adap->fe,
- &adap->channel.hdw->i2c_adap, 0x42,
- &tda829x_no_probe);
- dvb_attach(tda18271_attach, adap->fe, 0x60,
- &adap->channel.hdw->i2c_adap,
- &hauppauge_tda18271_dvb_config);
-
- return 0;
-}
-
-static const struct pvr2_dvb_props pvr2_73xxx_dvb_props = {
- .frontend_attach = pvr2_tda10048_attach,
- .tuner_attach = pvr2_73xxx_tda18271_8295_attach,
-};
-#endif
-
-static const struct pvr2_device_client_desc pvr2_cli_73xxx[] = {
- { .module_id = PVR2_CLIENT_ID_CX25840 },
- { .module_id = PVR2_CLIENT_ID_TUNER,
- .i2c_address_list = "\x42"},
-};
-
-static const char *pvr2_fw1_names_73xxx[] = {
- "v4l-pvrusb2-73xxx-01.fw",
-};
-
-static const struct pvr2_device_desc pvr2_device_73xxx = {
- .description = "WinTV HVR-1900 Model 73xxx",
- .shortname = "73xxx",
- .client_table.lst = pvr2_cli_73xxx,
- .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
- .fx2_firmware.lst = pvr2_fw1_names_73xxx,
- .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_73xxx),
- .flag_has_cx25840 = !0,
- .flag_has_hauppauge_rom = !0,
- .flag_has_analogtuner = !0,
- .flag_has_composite = !0,
- .flag_has_svideo = !0,
- .flag_fx2_16kb = !0,
- .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
- .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
- .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
- .ir_scheme = PVR2_IR_SCHEME_ZILOG,
-#ifdef CONFIG_VIDEO_PVRUSB2_DVB
- .dvb_props = &pvr2_73xxx_dvb_props,
-#endif
-};
-
-
-
-/*------------------------------------------------------------------------*/
-/* Hauppauge PVR-USB2 Model 75xxx */
-
-#ifdef CONFIG_VIDEO_PVRUSB2_DVB
-static struct s5h1409_config pvr2_s5h1409_config = {
- .demod_address = 0x32 >> 1,
- .output_mode = S5H1409_PARALLEL_OUTPUT,
- .gpio = S5H1409_GPIO_OFF,
- .qam_if = 4000,
- .inversion = S5H1409_INVERSION_ON,
- .status_mode = S5H1409_DEMODLOCKING,
-};
-
-static struct s5h1411_config pvr2_s5h1411_config = {
- .output_mode = S5H1411_PARALLEL_OUTPUT,
- .gpio = S5H1411_GPIO_OFF,
- .vsb_if = S5H1411_IF_44000,
- .qam_if = S5H1411_IF_4000,
- .inversion = S5H1411_INVERSION_ON,
- .status_mode = S5H1411_DEMODLOCKING,
-};
-
-static struct tda18271_std_map hauppauge_tda18271_std_map = {
- .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3,
- .if_lvl = 6, .rfagc_top = 0x37, },
- .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
- .if_lvl = 6, .rfagc_top = 0x37, },
-};
-
-static struct tda18271_config hauppauge_tda18271_config = {
- .std_map = &hauppauge_tda18271_std_map,
- .gate = TDA18271_GATE_ANALOG,
- .output_opt = TDA18271_OUTPUT_LT_OFF,
-};
-
-static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
-{
- adap->fe = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config,
- &adap->channel.hdw->i2c_adap);
- if (adap->fe)
- return 0;
-
- return -EIO;
-}
-
-static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap)
-{
- adap->fe = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config,
- &adap->channel.hdw->i2c_adap);
- if (adap->fe)
- return 0;
-
- return -EIO;
-}
-
-static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
-{
- dvb_attach(tda829x_attach, adap->fe,
- &adap->channel.hdw->i2c_adap, 0x42,
- &tda829x_no_probe);
- dvb_attach(tda18271_attach, adap->fe, 0x60,
- &adap->channel.hdw->i2c_adap,
- &hauppauge_tda18271_config);
-
- return 0;
-}
-
-static const struct pvr2_dvb_props pvr2_750xx_dvb_props = {
- .frontend_attach = pvr2_s5h1409_attach,
- .tuner_attach = pvr2_tda18271_8295_attach,
-};
-
-static const struct pvr2_dvb_props pvr2_751xx_dvb_props = {
- .frontend_attach = pvr2_s5h1411_attach,
- .tuner_attach = pvr2_tda18271_8295_attach,
-};
-#endif
-
-static const char *pvr2_fw1_names_75xxx[] = {
- "v4l-pvrusb2-73xxx-01.fw",
-};
-
-static const struct pvr2_device_desc pvr2_device_750xx = {
- .description = "WinTV HVR-1950 Model 750xx",
- .shortname = "750xx",
- .client_table.lst = pvr2_cli_73xxx,
- .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
- .fx2_firmware.lst = pvr2_fw1_names_75xxx,
- .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx),
- .flag_has_cx25840 = !0,
- .flag_has_hauppauge_rom = !0,
- .flag_has_analogtuner = !0,
- .flag_has_composite = !0,
- .flag_has_svideo = !0,
- .flag_fx2_16kb = !0,
- .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
- .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
- .default_std_mask = V4L2_STD_NTSC_M,
- .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
- .ir_scheme = PVR2_IR_SCHEME_ZILOG,
-#ifdef CONFIG_VIDEO_PVRUSB2_DVB
- .dvb_props = &pvr2_750xx_dvb_props,
-#endif
-};
-
-static const struct pvr2_device_desc pvr2_device_751xx = {
- .description = "WinTV HVR-1950 Model 751xx",
- .shortname = "751xx",
- .client_table.lst = pvr2_cli_73xxx,
- .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
- .fx2_firmware.lst = pvr2_fw1_names_75xxx,
- .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx),
- .flag_has_cx25840 = !0,
- .flag_has_hauppauge_rom = !0,
- .flag_has_analogtuner = !0,
- .flag_has_composite = !0,
- .flag_has_svideo = !0,
- .flag_fx2_16kb = !0,
- .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
- .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
- .default_std_mask = V4L2_STD_NTSC_M,
- .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
- .ir_scheme = PVR2_IR_SCHEME_ZILOG,
-#ifdef CONFIG_VIDEO_PVRUSB2_DVB
- .dvb_props = &pvr2_751xx_dvb_props,
-#endif
-};
-
-
-
-/*------------------------------------------------------------------------*/
-
-struct usb_device_id pvr2_device_table[] = {
- { USB_DEVICE(0x2040, 0x2900),
- .driver_info = (kernel_ulong_t)&pvr2_device_29xxx},
- { USB_DEVICE(0x2040, 0x2950), /* Logically identical to 2900 */
- .driver_info = (kernel_ulong_t)&pvr2_device_29xxx},
- { USB_DEVICE(0x2040, 0x2400),
- .driver_info = (kernel_ulong_t)&pvr2_device_24xxx},
- { USB_DEVICE(0x1164, 0x0622),
- .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2},
- { USB_DEVICE(0x1164, 0x0602),
- .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2d},
- { USB_DEVICE(0x11ba, 0x1003),
- .driver_info = (kernel_ulong_t)&pvr2_device_onair_creator},
- { USB_DEVICE(0x11ba, 0x1001),
- .driver_info = (kernel_ulong_t)&pvr2_device_onair_usb2},
- { USB_DEVICE(0x2040, 0x7300),
- .driver_info = (kernel_ulong_t)&pvr2_device_73xxx},
- { USB_DEVICE(0x2040, 0x7500),
- .driver_info = (kernel_ulong_t)&pvr2_device_750xx},
- { USB_DEVICE(0x2040, 0x7501),
- .driver_info = (kernel_ulong_t)&pvr2_device_751xx},
- { USB_DEVICE(0x0ccd, 0x0039),
- .driver_info = (kernel_ulong_t)&pvr2_device_av400},
- { }
-};
-
-MODULE_DEVICE_TABLE(usb, pvr2_device_table);
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
deleted file mode 100644
index 273c8d4b385..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __PVRUSB2_DEVATTR_H
-#define __PVRUSB2_DEVATTR_H
-
-#include <linux/mod_devicetable.h>
-#include <linux/videodev2.h>
-#ifdef CONFIG_VIDEO_PVRUSB2_DVB
-#include "pvrusb2-dvb.h"
-#endif
-
-/*
-
- This header defines structures used to describe attributes of a device.
-
-*/
-
-
-#define PVR2_CLIENT_ID_NULL 0
-#define PVR2_CLIENT_ID_MSP3400 1
-#define PVR2_CLIENT_ID_CX25840 2
-#define PVR2_CLIENT_ID_SAA7115 3
-#define PVR2_CLIENT_ID_TUNER 4
-#define PVR2_CLIENT_ID_CS53L32A 5
-#define PVR2_CLIENT_ID_WM8775 6
-#define PVR2_CLIENT_ID_DEMOD 7
-
-struct pvr2_device_client_desc {
- /* One ovr PVR2_CLIENT_ID_xxxx */
- unsigned char module_id;
-
- /* Null-terminated array of I2C addresses to try in order
- initialize the module. It's safe to make this null terminated
- since we're never going to encounter an i2c device with an
- address of zero. If this is a null pointer or zero-length,
- then no I2C addresses have been specified, in which case we'll
- try some compiled in defaults for now. */
- unsigned char *i2c_address_list;
-};
-
-struct pvr2_device_client_table {
- const struct pvr2_device_client_desc *lst;
- unsigned char cnt;
-};
-
-
-struct pvr2_string_table {
- const char **lst;
- unsigned int cnt;
-};
-
-#define PVR2_ROUTING_SCHEME_HAUPPAUGE 0
-#define PVR2_ROUTING_SCHEME_GOTVIEW 1
-#define PVR2_ROUTING_SCHEME_ONAIR 2
-#define PVR2_ROUTING_SCHEME_AV400 3
-
-#define PVR2_DIGITAL_SCHEME_NONE 0
-#define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
-#define PVR2_DIGITAL_SCHEME_ONAIR 2
-
-#define PVR2_LED_SCHEME_NONE 0
-#define PVR2_LED_SCHEME_HAUPPAUGE 1
-
-#define PVR2_IR_SCHEME_NONE 0
-#define PVR2_IR_SCHEME_24XXX 1 /* FX2-controlled IR */
-#define PVR2_IR_SCHEME_ZILOG 2 /* HVR-1950 style (must be taken out of reset) */
-#define PVR2_IR_SCHEME_24XXX_MCE 3 /* 24xxx MCE device */
-#define PVR2_IR_SCHEME_29XXX 4 /* Original 29xxx device */
-
-/* This describes a particular hardware type (except for the USB device ID
- which must live in a separate structure due to environmental
- constraints). See the top of pvrusb2-hdw.c for where this is
- instantiated. */
-struct pvr2_device_desc {
- /* Single line text description of hardware */
- const char *description;
-
- /* Single token identifier for hardware */
- const char *shortname;
-
- /* List of additional client modules we need to load */
- struct pvr2_string_table client_modules;
-
- /* List of defined client modules we need to load */
- struct pvr2_device_client_table client_table;
-
- /* List of FX2 firmware file names we should search; if empty then
- FX2 firmware check / load is skipped and we assume the device
- was initialized from internal ROM. */
- struct pvr2_string_table fx2_firmware;
-
-#ifdef CONFIG_VIDEO_PVRUSB2_DVB
- /* callback functions to handle attachment of digital tuner & demod */
- const struct pvr2_dvb_props *dvb_props;
-
-#endif
- /* Initial standard bits to use for this device, if not zero.
- Anything set here is also implied as an available standard.
- Note: This is ignored if overridden on the module load line via
- the video_std module option. */
- v4l2_std_id default_std_mask;
-
- /* V4L tuner type ID to use with this device (only used if the
- driver could not discover the type any other way). */
- int default_tuner_type;
-
- /* Signal routing scheme used by device, contains one of
- PVR2_ROUTING_SCHEME_XXX. Schemes have to be defined as we
- encounter them. This is an arbitrary integer scheme id; its
- meaning is contained entirely within the driver and is
- interpreted by logic which must send commands to the chip-level
- drivers (search for things which touch this field). */
- unsigned char signal_routing_scheme;
-
- /* Indicates scheme for controlling device's LED (if any). The
- driver will turn on the LED when streaming is underway. This
- contains one of PVR2_LED_SCHEME_XXX. */
- unsigned char led_scheme;
-
- /* Control scheme to use if there is a digital tuner. This
- contains one of PVR2_DIGITAL_SCHEME_XXX. This is an arbitrary
- integer scheme id; its meaning is contained entirely within the
- driver and is interpreted by logic which must control the
- streaming pathway (search for things which touch this field). */
- unsigned char digital_control_scheme;
-
- /* If set, we don't bother trying to load cx23416 firmware. */
- unsigned int flag_skip_cx23416_firmware:1;
-
- /* If set, the encoder must be healthy in order for digital mode to
- work (otherwise we assume that digital streaming will work even
- if we fail to locate firmware for the encoder). If the device
- doesn't support digital streaming then this flag has no
- effect. */
- unsigned int flag_digital_requires_cx23416:1;
-
- /* Device has a hauppauge eeprom which we can interrogate. */
- unsigned int flag_has_hauppauge_rom:1;
-
- /* Device does not require a powerup command to be issued. */
- unsigned int flag_no_powerup:1;
-
- /* Device has a cx25840 - this enables special additional logic to
- handle it. */
- unsigned int flag_has_cx25840:1;
-
- /* Device has a wm8775 - this enables special additional logic to
- ensure that it is found. */
- unsigned int flag_has_wm8775:1;
-
- /* Indicate IR scheme of hardware. If not set, then it is assumed
- that IR can work without any help from the driver. */
- unsigned int ir_scheme:3;
-
- /* These bits define which kinds of sources the device can handle.
- Note: Digital tuner presence is inferred by the
- digital_control_scheme enumeration. */
- unsigned int flag_has_fmradio:1; /* Has FM radio receiver */
- unsigned int flag_has_analogtuner:1; /* Has analog tuner */
- unsigned int flag_has_composite:1; /* Has composite input */
- unsigned int flag_has_svideo:1; /* Has s-video input */
- unsigned int flag_fx2_16kb:1; /* 16KB FX2 firmware OK here */
-
- /* If this driver is considered experimental, i.e. not all aspects
- are working correctly and/or it is untested, mark that fact
- with this flag. */
- unsigned int flag_is_experimental:1;
-};
-
-extern struct usb_device_id pvr2_device_table[];
-
-#endif /* __PVRUSB2_HDW_INTERNAL_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
deleted file mode 100644
index 8c95793433e..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-dvb.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * pvrusb2-dvb.c - linux-dvb api interface to the pvrusb2 driver.
- *
- * Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include "dvbdev.h"
-#include "pvrusb2-debug.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-hdw.h"
-#include "pvrusb2-io.h"
-#include "pvrusb2-dvb.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter *adap)
-{
- int ret;
- unsigned int count;
- struct pvr2_buffer *bp;
- struct pvr2_stream *stream;
-
- pvr2_trace(PVR2_TRACE_DVB_FEED, "dvb feed thread started");
- set_freezable();
-
- stream = adap->channel.stream->stream;
-
- for (;;) {
- if (kthread_should_stop()) break;
-
- /* Not sure about this... */
- try_to_freeze();
-
- bp = pvr2_stream_get_ready_buffer(stream);
- if (bp != NULL) {
- count = pvr2_buffer_get_count(bp);
- if (count) {
- dvb_dmx_swfilter(
- &adap->demux,
- adap->buffer_storage[
- pvr2_buffer_get_id(bp)],
- count);
- } else {
- ret = pvr2_buffer_get_status(bp);
- if (ret < 0) break;
- }
- ret = pvr2_buffer_queue(bp);
- if (ret < 0) break;
-
- /* Since we know we did something to a buffer,
- just go back and try again. No point in
- blocking unless we really ran out of
- buffers to process. */
- continue;
- }
-
-
- /* Wait until more buffers become available or we're
- told not to wait any longer. */
- ret = wait_event_interruptible(
- adap->buffer_wait_data,
- (pvr2_stream_get_ready_count(stream) > 0) ||
- kthread_should_stop());
- if (ret < 0) break;
- }
-
- /* If we get here and ret is < 0, then an error has occurred.
- Probably would be a good idea to communicate that to DVB core... */
-
- pvr2_trace(PVR2_TRACE_DVB_FEED, "dvb feed thread stopped");
-
- return 0;
-}
-
-static int pvr2_dvb_feed_thread(void *data)
-{
- int stat = pvr2_dvb_feed_func(data);
- /* from videobuf-dvb.c: */
- while (!kthread_should_stop()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- }
- return stat;
-}
-
-static void pvr2_dvb_notify(struct pvr2_dvb_adapter *adap)
-{
- wake_up(&adap->buffer_wait_data);
-}
-
-static void pvr2_dvb_stream_end(struct pvr2_dvb_adapter *adap)
-{
- unsigned int idx;
- struct pvr2_stream *stream;
-
- if (adap->thread) {
- kthread_stop(adap->thread);
- adap->thread = NULL;
- }
-
- if (adap->channel.stream) {
- stream = adap->channel.stream->stream;
- } else {
- stream = NULL;
- }
- if (stream) {
- pvr2_hdw_set_streaming(adap->channel.hdw, 0);
- pvr2_stream_set_callback(stream, NULL, NULL);
- pvr2_stream_kill(stream);
- pvr2_stream_set_buffer_count(stream, 0);
- pvr2_channel_claim_stream(&adap->channel, NULL);
- }
-
- if (adap->stream_run) {
- for (idx = 0; idx < PVR2_DVB_BUFFER_COUNT; idx++) {
- if (!(adap->buffer_storage[idx])) continue;
- kfree(adap->buffer_storage[idx]);
- adap->buffer_storage[idx] = NULL;
- }
- adap->stream_run = 0;
- }
-}
-
-static int pvr2_dvb_stream_do_start(struct pvr2_dvb_adapter *adap)
-{
- struct pvr2_context *pvr = adap->channel.mc_head;
- unsigned int idx;
- int ret;
- struct pvr2_buffer *bp;
- struct pvr2_stream *stream = NULL;
-
- if (adap->stream_run) return -EIO;
-
- ret = pvr2_channel_claim_stream(&adap->channel, &pvr->video_stream);
- /* somebody else already has the stream */
- if (ret < 0) return ret;
-
- stream = adap->channel.stream->stream;
-
- for (idx = 0; idx < PVR2_DVB_BUFFER_COUNT; idx++) {
- adap->buffer_storage[idx] = kmalloc(PVR2_DVB_BUFFER_SIZE,
- GFP_KERNEL);
- if (!(adap->buffer_storage[idx])) return -ENOMEM;
- }
-
- pvr2_stream_set_callback(pvr->video_stream.stream,
- (pvr2_stream_callback) pvr2_dvb_notify, adap);
-
- ret = pvr2_stream_set_buffer_count(stream, PVR2_DVB_BUFFER_COUNT);
- if (ret < 0) return ret;
-
- for (idx = 0; idx < PVR2_DVB_BUFFER_COUNT; idx++) {
- bp = pvr2_stream_get_buffer(stream, idx);
- pvr2_buffer_set_buffer(bp,
- adap->buffer_storage[idx],
- PVR2_DVB_BUFFER_SIZE);
- }
-
- ret = pvr2_hdw_set_streaming(adap->channel.hdw, 1);
- if (ret < 0) return ret;
-
- while ((bp = pvr2_stream_get_idle_buffer(stream)) != NULL) {
- ret = pvr2_buffer_queue(bp);
- if (ret < 0) return ret;
- }
-
- adap->thread = kthread_run(pvr2_dvb_feed_thread, adap, "pvrusb2-dvb");
-
- if (IS_ERR(adap->thread)) {
- ret = PTR_ERR(adap->thread);
- adap->thread = NULL;
- return ret;
- }
-
- adap->stream_run = !0;
-
- return 0;
-}
-
-static int pvr2_dvb_stream_start(struct pvr2_dvb_adapter *adap)
-{
- int ret = pvr2_dvb_stream_do_start(adap);
- if (ret < 0) pvr2_dvb_stream_end(adap);
- return ret;
-}
-
-static int pvr2_dvb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
-{
- struct pvr2_dvb_adapter *adap = dvbdmxfeed->demux->priv;
- int ret = 0;
-
- if (adap == NULL) return -ENODEV;
-
- mutex_lock(&adap->lock);
- do {
- if (onoff) {
- if (!adap->feedcount) {
- pvr2_trace(PVR2_TRACE_DVB_FEED,
- "start feeding demux");
- ret = pvr2_dvb_stream_start(adap);
- if (ret < 0) break;
- }
- (adap->feedcount)++;
- } else if (adap->feedcount > 0) {
- (adap->feedcount)--;
- if (!adap->feedcount) {
- pvr2_trace(PVR2_TRACE_DVB_FEED,
- "stop feeding demux");
- pvr2_dvb_stream_end(adap);
- }
- }
- } while (0);
- mutex_unlock(&adap->lock);
-
- return ret;
-}
-
-static int pvr2_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
- pvr2_trace(PVR2_TRACE_DVB_FEED, "start pid: 0x%04x", dvbdmxfeed->pid);
- return pvr2_dvb_ctrl_feed(dvbdmxfeed, 1);
-}
-
-static int pvr2_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
- pvr2_trace(PVR2_TRACE_DVB_FEED, "stop pid: 0x%04x", dvbdmxfeed->pid);
- return pvr2_dvb_ctrl_feed(dvbdmxfeed, 0);
-}
-
-static int pvr2_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
-{
- struct pvr2_dvb_adapter *adap = fe->dvb->priv;
- return pvr2_channel_limit_inputs(
- &adap->channel,
- (acquire ? (1 << PVR2_CVAL_INPUT_DTV) : 0));
-}
-
-static int pvr2_dvb_adapter_init(struct pvr2_dvb_adapter *adap)
-{
- int ret;
-
- ret = dvb_register_adapter(&adap->dvb_adap, "pvrusb2-dvb",
- THIS_MODULE/*&hdw->usb_dev->owner*/,
- &adap->channel.hdw->usb_dev->dev,
- adapter_nr);
- if (ret < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "dvb_register_adapter failed: error %d", ret);
- goto err;
- }
- adap->dvb_adap.priv = adap;
-
- adap->demux.dmx.capabilities = DMX_TS_FILTERING |
- DMX_SECTION_FILTERING |
- DMX_MEMORY_BASED_FILTERING;
- adap->demux.priv = adap;
- adap->demux.filternum = 256;
- adap->demux.feednum = 256;
- adap->demux.start_feed = pvr2_dvb_start_feed;
- adap->demux.stop_feed = pvr2_dvb_stop_feed;
- adap->demux.write_to_decoder = NULL;
-
- ret = dvb_dmx_init(&adap->demux);
- if (ret < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "dvb_dmx_init failed: error %d", ret);
- goto err_dmx;
- }
-
- adap->dmxdev.filternum = adap->demux.filternum;
- adap->dmxdev.demux = &adap->demux.dmx;
- adap->dmxdev.capabilities = 0;
-
- ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
- if (ret < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "dvb_dmxdev_init failed: error %d", ret);
- goto err_dmx_dev;
- }
-
- dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
-
- return 0;
-
-err_dmx_dev:
- dvb_dmx_release(&adap->demux);
-err_dmx:
- dvb_unregister_adapter(&adap->dvb_adap);
-err:
- return ret;
-}
-
-static int pvr2_dvb_adapter_exit(struct pvr2_dvb_adapter *adap)
-{
- pvr2_trace(PVR2_TRACE_INFO, "unregistering DVB devices");
- dvb_net_release(&adap->dvb_net);
- adap->demux.dmx.close(&adap->demux.dmx);
- dvb_dmxdev_release(&adap->dmxdev);
- dvb_dmx_release(&adap->demux);
- dvb_unregister_adapter(&adap->dvb_adap);
- return 0;
-}
-
-static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
-{
- struct pvr2_hdw *hdw = adap->channel.hdw;
- const struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props;
- int ret = 0;
-
- if (dvb_props == NULL) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS, "fe_props not defined!");
- return -EINVAL;
- }
-
- ret = pvr2_channel_limit_inputs(
- &adap->channel,
- (1 << PVR2_CVAL_INPUT_DTV));
- if (ret) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "failed to grab control of dtv input (code=%d)",
- ret);
- return ret;
- }
-
- if (dvb_props->frontend_attach == NULL) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "frontend_attach not defined!");
- ret = -EINVAL;
- goto done;
- }
-
- if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) {
-
- if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "frontend registration failed!");
- dvb_frontend_detach(adap->fe);
- adap->fe = NULL;
- ret = -ENODEV;
- goto done;
- }
-
- if (dvb_props->tuner_attach)
- dvb_props->tuner_attach(adap);
-
- if (adap->fe->ops.analog_ops.standby)
- adap->fe->ops.analog_ops.standby(adap->fe);
-
- /* Ensure all frontends negotiate bus access */
- adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
-
- } else {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "no frontend was attached!");
- ret = -ENODEV;
- return ret;
- }
-
- done:
- pvr2_channel_limit_inputs(&adap->channel, 0);
- return ret;
-}
-
-static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
-{
- if (adap->fe != NULL) {
- dvb_unregister_frontend(adap->fe);
- dvb_frontend_detach(adap->fe);
- }
- return 0;
-}
-
-static void pvr2_dvb_destroy(struct pvr2_dvb_adapter *adap)
-{
- pvr2_dvb_stream_end(adap);
- pvr2_dvb_frontend_exit(adap);
- pvr2_dvb_adapter_exit(adap);
- pvr2_channel_done(&adap->channel);
- kfree(adap);
-}
-
-static void pvr2_dvb_internal_check(struct pvr2_channel *chp)
-{
- struct pvr2_dvb_adapter *adap;
- adap = container_of(chp, struct pvr2_dvb_adapter, channel);
- if (!adap->channel.mc_head->disconnect_flag) return;
- pvr2_dvb_destroy(adap);
-}
-
-struct pvr2_dvb_adapter *pvr2_dvb_create(struct pvr2_context *pvr)
-{
- int ret = 0;
- struct pvr2_dvb_adapter *adap;
- if (!pvr->hdw->hdw_desc->dvb_props) {
- /* Device lacks a digital interface so don't set up
- the DVB side of the driver either. For now. */
- return NULL;
- }
- adap = kzalloc(sizeof(*adap), GFP_KERNEL);
- if (!adap) return adap;
- pvr2_channel_init(&adap->channel, pvr);
- adap->channel.check_func = pvr2_dvb_internal_check;
- init_waitqueue_head(&adap->buffer_wait_data);
- mutex_init(&adap->lock);
- ret = pvr2_dvb_adapter_init(adap);
- if (ret < 0) goto fail1;
- ret = pvr2_dvb_frontend_init(adap);
- if (ret < 0) goto fail2;
- return adap;
-
-fail2:
- pvr2_dvb_adapter_exit(adap);
-fail1:
- pvr2_channel_done(&adap->channel);
- return NULL;
-}
-
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.h b/drivers/media/video/pvrusb2/pvrusb2-dvb.h
deleted file mode 100644
index 884ff916a35..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-dvb.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef __PVRUSB2_DVB_H__
-#define __PVRUSB2_DVB_H__
-
-#include "dvb_frontend.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "dmxdev.h"
-#include "pvrusb2-context.h"
-
-#define PVR2_DVB_BUFFER_COUNT 32
-#define PVR2_DVB_BUFFER_SIZE PAGE_ALIGN(0x4000)
-
-struct pvr2_dvb_adapter {
- struct pvr2_channel channel;
-
- struct dvb_adapter dvb_adap;
- struct dmxdev dmxdev;
- struct dvb_demux demux;
- struct dvb_net dvb_net;
- struct dvb_frontend *fe;
-
- int feedcount;
- int max_feed_count;
-
- struct task_struct *thread;
- struct mutex lock;
-
- unsigned int stream_run:1;
-
- wait_queue_head_t buffer_wait_data;
- char *buffer_storage[PVR2_DVB_BUFFER_COUNT];
-};
-
-struct pvr2_dvb_props {
- int (*frontend_attach) (struct pvr2_dvb_adapter *);
- int (*tuner_attach) (struct pvr2_dvb_adapter *);
-};
-
-struct pvr2_dvb_adapter *pvr2_dvb_create(struct pvr2_context *pvr);
-
-#endif /* __PVRUSB2_DVB_H__ */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
deleted file mode 100644
index 9515f3a68f8..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/slab.h>
-#include "pvrusb2-eeprom.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-
-#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__)
-
-
-
-/*
-
- Read and analyze data in the eeprom. Use tveeprom to figure out
- the packet structure, since this is another Hauppauge device and
- internally it has a family resemblance to ivtv-type devices
-
-*/
-
-#include <media/tveeprom.h>
-
-/* We seem to only be interested in the last 128 bytes of the EEPROM */
-#define EEPROM_SIZE 128
-
-/* Grab EEPROM contents, needed for direct method. */
-static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw)
-{
- struct i2c_msg msg[2];
- u8 *eeprom;
- u8 iadd[2];
- u8 addr;
- u16 eepromSize;
- unsigned int offs;
- int ret;
- int mode16 = 0;
- unsigned pcnt,tcnt;
- eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL);
- if (!eeprom) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Failed to allocate memory"
- " required to read eeprom");
- return NULL;
- }
-
- trace_eeprom("Value for eeprom addr from controller was 0x%x",
- hdw->eeprom_addr);
- addr = hdw->eeprom_addr;
- /* Seems that if the high bit is set, then the *real* eeprom
- address is shifted right now bit position (noticed this in
- newer PVR USB2 hardware) */
- if (addr & 0x80) addr >>= 1;
-
- /* FX2 documentation states that a 16bit-addressed eeprom is
- expected if the I2C address is an odd number (yeah, this is
- strange but it's what they do) */
- mode16 = (addr & 1);
- eepromSize = (mode16 ? 4096 : 256);
- trace_eeprom("Examining %d byte eeprom at location 0x%x"
- " using %d bit addressing",eepromSize,addr,
- mode16 ? 16 : 8);
-
- msg[0].addr = addr;
- msg[0].flags = 0;
- msg[0].len = mode16 ? 2 : 1;
- msg[0].buf = iadd;
- msg[1].addr = addr;
- msg[1].flags = I2C_M_RD;
-
- /* We have to do the actual eeprom data fetch ourselves, because
- (1) we're only fetching part of the eeprom, and (2) if we were
- getting the whole thing our I2C driver can't grab it in one
- pass - which is what tveeprom is otherwise going to attempt */
- memset(eeprom,0,EEPROM_SIZE);
- for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
- pcnt = 16;
- if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
- offs = tcnt + (eepromSize - EEPROM_SIZE);
- if (mode16) {
- iadd[0] = offs >> 8;
- iadd[1] = offs;
- } else {
- iadd[0] = offs;
- }
- msg[1].len = pcnt;
- msg[1].buf = eeprom+tcnt;
- if ((ret = i2c_transfer(&hdw->i2c_adap,
- msg,ARRAY_SIZE(msg))) != 2) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "eeprom fetch set offs err=%d",ret);
- kfree(eeprom);
- return NULL;
- }
- }
- return eeprom;
-}
-
-
-/* Directly call eeprom analysis function within tveeprom. */
-int pvr2_eeprom_analyze(struct pvr2_hdw *hdw)
-{
- u8 *eeprom;
- struct tveeprom tvdata;
-
- memset(&tvdata,0,sizeof(tvdata));
-
- eeprom = pvr2_eeprom_fetch(hdw);
- if (!eeprom) return -EINVAL;
-
- {
- struct i2c_client fake_client;
- /* Newer version expects a useless client interface */
- fake_client.addr = hdw->eeprom_addr;
- fake_client.adapter = &hdw->i2c_adap;
- tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom);
- }
-
- trace_eeprom("eeprom assumed v4l tveeprom module");
- trace_eeprom("eeprom direct call results:");
- trace_eeprom("has_radio=%d",tvdata.has_radio);
- trace_eeprom("tuner_type=%d",tvdata.tuner_type);
- trace_eeprom("tuner_formats=0x%x",tvdata.tuner_formats);
- trace_eeprom("audio_processor=%d",tvdata.audio_processor);
- trace_eeprom("model=%d",tvdata.model);
- trace_eeprom("revision=%d",tvdata.revision);
- trace_eeprom("serial_number=%d",tvdata.serial_number);
- trace_eeprom("rev_str=%s",tvdata.rev_str);
- hdw->tuner_type = tvdata.tuner_type;
- hdw->tuner_updated = !0;
- hdw->serial_number = tvdata.serial_number;
- hdw->std_mask_eeprom = tvdata.tuner_formats;
-
- kfree(eeprom);
-
- return 0;
-}
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.h b/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
deleted file mode 100644
index cca3216f94c..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef __PVRUSB2_EEPROM_H
-#define __PVRUSB2_EEPROM_H
-
-struct pvr2_hdw;
-
-int pvr2_eeprom_analyze(struct pvr2_hdw *);
-
-#endif /* __PVRUSB2_EEPROM_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
deleted file mode 100644
index e046fdaec5a..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/device.h> // for linux/firmware.h
-#include <linux/firmware.h>
-#include "pvrusb2-util.h"
-#include "pvrusb2-encoder.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include "pvrusb2-fx2-cmd.h"
-
-
-
-/* Firmware mailbox flags - definitions found from ivtv */
-#define IVTV_MBOX_FIRMWARE_DONE 0x00000004
-#define IVTV_MBOX_DRIVER_DONE 0x00000002
-#define IVTV_MBOX_DRIVER_BUSY 0x00000001
-
-#define MBOX_BASE 0x44
-
-
-static int pvr2_encoder_write_words(struct pvr2_hdw *hdw,
- unsigned int offs,
- const u32 *data, unsigned int dlen)
-{
- unsigned int idx,addr;
- unsigned int bAddr;
- int ret;
- unsigned int chunkCnt;
-
- /*
-
- Format: First byte must be 0x01. Remaining 32 bit words are
- spread out into chunks of 7 bytes each, with the first 4 bytes
- being the data word (little endian), and the next 3 bytes
- being the address where that data word is to be written (big
- endian). Repeat request for additional words, with offset
- adjusted accordingly.
-
- */
- while (dlen) {
- chunkCnt = 8;
- if (chunkCnt > dlen) chunkCnt = dlen;
- memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer));
- bAddr = 0;
- hdw->cmd_buffer[bAddr++] = FX2CMD_MEM_WRITE_DWORD;
- for (idx = 0; idx < chunkCnt; idx++) {
- addr = idx + offs;
- hdw->cmd_buffer[bAddr+6] = (addr & 0xffu);
- hdw->cmd_buffer[bAddr+5] = ((addr>>8) & 0xffu);
- hdw->cmd_buffer[bAddr+4] = ((addr>>16) & 0xffu);
- PVR2_DECOMPOSE_LE(hdw->cmd_buffer, bAddr,data[idx]);
- bAddr += 7;
- }
- ret = pvr2_send_request(hdw,
- hdw->cmd_buffer,1+(chunkCnt*7),
- NULL,0);
- if (ret) return ret;
- data += chunkCnt;
- dlen -= chunkCnt;
- offs += chunkCnt;
- }
-
- return 0;
-}
-
-
-static int pvr2_encoder_read_words(struct pvr2_hdw *hdw,
- unsigned int offs,
- u32 *data, unsigned int dlen)
-{
- unsigned int idx;
- int ret;
- unsigned int chunkCnt;
-
- /*
-
- Format: First byte must be 0x02 (status check) or 0x28 (read
- back block of 32 bit words). Next 6 bytes must be zero,
- followed by a single byte of MBOX_BASE+offset for portion to
- be read. Returned data is packed set of 32 bits words that
- were read.
-
- */
-
- while (dlen) {
- chunkCnt = 16;
- if (chunkCnt > dlen) chunkCnt = dlen;
- if (chunkCnt < 16) chunkCnt = 1;
- hdw->cmd_buffer[0] =
- ((chunkCnt == 1) ?
- FX2CMD_MEM_READ_DWORD : FX2CMD_MEM_READ_64BYTES);
- hdw->cmd_buffer[1] = 0;
- hdw->cmd_buffer[2] = 0;
- hdw->cmd_buffer[3] = 0;
- hdw->cmd_buffer[4] = 0;
- hdw->cmd_buffer[5] = ((offs>>16) & 0xffu);
- hdw->cmd_buffer[6] = ((offs>>8) & 0xffu);
- hdw->cmd_buffer[7] = (offs & 0xffu);
- ret = pvr2_send_request(hdw,
- hdw->cmd_buffer,8,
- hdw->cmd_buffer,
- (chunkCnt == 1 ? 4 : 16 * 4));
- if (ret) return ret;
-
- for (idx = 0; idx < chunkCnt; idx++) {
- data[idx] = PVR2_COMPOSE_LE(hdw->cmd_buffer,idx*4);
- }
- data += chunkCnt;
- dlen -= chunkCnt;
- offs += chunkCnt;
- }
-
- return 0;
-}
-
-
-/* This prototype is set up to be compatible with the
- cx2341x_mbox_func prototype in cx2341x.h, which should be in
- kernels 2.6.18 or later. We do this so that we can enable
- cx2341x.ko to write to our encoder (by handing it a pointer to this
- function). For earlier kernels this doesn't really matter. */
-static int pvr2_encoder_cmd(void *ctxt,
- u32 cmd,
- int arg_cnt_send,
- int arg_cnt_recv,
- u32 *argp)
-{
- unsigned int poll_count;
- unsigned int try_count = 0;
- int retry_flag;
- int ret = 0;
- unsigned int idx;
- /* These sizes look to be limited by the FX2 firmware implementation */
- u32 wrData[16];
- u32 rdData[16];
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)ctxt;
-
-
- /*
-
- The encoder seems to speak entirely using blocks 32 bit words.
- In ivtv driver terms, this is a mailbox at MBOX_BASE which we
- populate with data and watch what the hardware does with it.
- The first word is a set of flags used to control the
- transaction, the second word is the command to execute, the
- third byte is zero (ivtv driver suggests that this is some
- kind of return value), and the fourth byte is a specified
- timeout (windows driver always uses 0x00060000 except for one
- case when it is zero). All successive words are the argument
- words for the command.
-
- First, write out the entire set of words, with the first word
- being zero.
-
- Next, write out just the first word again, but set it to
- IVTV_MBOX_DRIVER_DONE | IVTV_DRIVER_BUSY this time (which
- probably means "go").
-
- Next, read back the return count words. Check the first word,
- which should have IVTV_MBOX_FIRMWARE_DONE set. If however
- that bit is not set, then the command isn't done so repeat the
- read until it is set.
-
- Finally, write out just the first word again, but set it to
- 0x0 this time (which probably means "idle").
-
- */
-
- if (arg_cnt_send > (ARRAY_SIZE(wrData) - 4)) {
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Failed to write cx23416 command"
- " - too many input arguments"
- " (was given %u limit %lu)",
- arg_cnt_send, (long unsigned) ARRAY_SIZE(wrData) - 4);
- return -EINVAL;
- }
-
- if (arg_cnt_recv > (ARRAY_SIZE(rdData) - 4)) {
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Failed to write cx23416 command"
- " - too many return arguments"
- " (was given %u limit %lu)",
- arg_cnt_recv, (long unsigned) ARRAY_SIZE(rdData) - 4);
- return -EINVAL;
- }
-
-
- LOCK_TAKE(hdw->ctl_lock); do {
-
- if (!hdw->state_encoder_ok) {
- ret = -EIO;
- break;
- }
-
- retry_flag = 0;
- try_count++;
- ret = 0;
- wrData[0] = 0;
- wrData[1] = cmd;
- wrData[2] = 0;
- wrData[3] = 0x00060000;
- for (idx = 0; idx < arg_cnt_send; idx++) {
- wrData[idx+4] = argp[idx];
- }
- for (; idx < ARRAY_SIZE(wrData) - 4; idx++) {
- wrData[idx+4] = 0;
- }
-
- ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,idx);
- if (ret) break;
- wrData[0] = IVTV_MBOX_DRIVER_DONE|IVTV_MBOX_DRIVER_BUSY;
- ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,1);
- if (ret) break;
- poll_count = 0;
- while (1) {
- poll_count++;
- ret = pvr2_encoder_read_words(hdw,MBOX_BASE,rdData,
- arg_cnt_recv+4);
- if (ret) {
- break;
- }
- if (rdData[0] & IVTV_MBOX_FIRMWARE_DONE) {
- break;
- }
- if (rdData[0] && (poll_count < 1000)) continue;
- if (!rdData[0]) {
- retry_flag = !0;
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Encoder timed out waiting for us"
- "; arranging to retry");
- } else {
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "***WARNING*** device's encoder"
- " appears to be stuck"
- " (status=0x%08x)",rdData[0]);
- }
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Encoder command: 0x%02x",cmd);
- for (idx = 4; idx < arg_cnt_send; idx++) {
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Encoder arg%d: 0x%08x",
- idx-3,wrData[idx]);
- }
- ret = -EBUSY;
- break;
- }
- if (retry_flag) {
- if (try_count < 20) continue;
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Too many retries...");
- ret = -EBUSY;
- }
- if (ret) {
- del_timer_sync(&hdw->encoder_run_timer);
- hdw->state_encoder_ok = 0;
- pvr2_trace(PVR2_TRACE_STBITS,
- "State bit %s <-- %s",
- "state_encoder_ok",
- (hdw->state_encoder_ok ? "true" : "false"));
- if (hdw->state_encoder_runok) {
- hdw->state_encoder_runok = 0;
- pvr2_trace(PVR2_TRACE_STBITS,
- "State bit %s <-- %s",
- "state_encoder_runok",
- (hdw->state_encoder_runok ?
- "true" : "false"));
- }
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Giving up on command."
- " This is normally recovered via a firmware"
- " reload and re-initialization; concern"
- " is only warranted if this happens repeatedly"
- " and rapidly.");
- break;
- }
- wrData[0] = 0x7;
- for (idx = 0; idx < arg_cnt_recv; idx++) {
- argp[idx] = rdData[idx+4];
- }
-
- wrData[0] = 0x0;
- ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,1);
- if (ret) break;
-
- } while(0); LOCK_GIVE(hdw->ctl_lock);
-
- return ret;
-}
-
-
-static int pvr2_encoder_vcmd(struct pvr2_hdw *hdw, int cmd,
- int args, ...)
-{
- va_list vl;
- unsigned int idx;
- u32 data[12];
-
- if (args > ARRAY_SIZE(data)) {
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Failed to write cx23416 command"
- " - too many arguments"
- " (was given %u limit %lu)",
- args, (long unsigned) ARRAY_SIZE(data));
- return -EINVAL;
- }
-
- va_start(vl, args);
- for (idx = 0; idx < args; idx++) {
- data[idx] = va_arg(vl, u32);
- }
- va_end(vl);
-
- return pvr2_encoder_cmd(hdw,cmd,args,0,data);
-}
-
-
-/* This implements some extra setup for the encoder that seems to be
- specific to the PVR USB2 hardware. */
-static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
-{
- int ret = 0;
- int encMisc3Arg = 0;
-
-#if 0
- /* This inexplicable bit happens in the Hauppauge windows
- driver (for both 24xxx and 29xxx devices). However I
- currently see no difference in behavior with or without
- this stuff. Leave this here as a note of its existence,
- but don't use it. */
- LOCK_TAKE(hdw->ctl_lock); do {
- u32 dat[1];
- dat[0] = 0x80000640;
- pvr2_encoder_write_words(hdw,0x01fe,dat,1);
- pvr2_encoder_write_words(hdw,0x023e,dat,1);
- } while(0); LOCK_GIVE(hdw->ctl_lock);
-#endif
-
- /* Mike Isely <isely@pobox.com> 26-Jan-2006 The windows driver
- sends the following list of ENC_MISC commands (for both
- 24xxx and 29xxx devices). Meanings are not entirely clear,
- however without the ENC_MISC(3,1) command then we risk
- random perpetual video corruption whenever the video input
- breaks up for a moment (like when switching channels). */
-
-
-#if 0
- /* This ENC_MISC(5,0) command seems to hurt 29xxx sync
- performance on channel changes, but is not a problem on
- 24xxx devices. */
- ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 5,0,0,0);
-#endif
-
- /* This ENC_MISC(3,encMisc3Arg) command is critical - without
- it there will eventually be video corruption. Also, the
- saa7115 case is strange - the Windows driver is passing 1
- regardless of device type but if we have 1 for saa7115
- devices the video turns sluggish. */
- if (hdw->hdw_desc->flag_has_cx25840) {
- encMisc3Arg = 1;
- } else {
- encMisc3Arg = 0;
- }
- ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 3,
- encMisc3Arg,0,0);
-
- ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 8,0,0,0);
-
-#if 0
- /* This ENC_MISC(4,1) command is poisonous, so it is commented
- out. But I'm leaving it here anyway to document its
- existence in the Windows driver. The effect of this
- command is that apps displaying the stream become sluggish
- with stuttering video. */
- ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 4,1,0,0);
-#endif
-
- ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 0,3,0,0);
- ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4,15,0,0,0);
-
- /* prevent the PTSs from slowly drifting away in the generated
- MPEG stream */
- ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC, 2, 4, 1);
-
- return ret;
-}
-
-int pvr2_encoder_adjust(struct pvr2_hdw *hdw)
-{
- int ret;
- ret = cx2341x_update(hdw,pvr2_encoder_cmd,
- (hdw->enc_cur_valid ? &hdw->enc_cur_state : NULL),
- &hdw->enc_ctl_state);
- if (ret) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Error from cx2341x module code=%d",ret);
- } else {
- memcpy(&hdw->enc_cur_state,&hdw->enc_ctl_state,
- sizeof(struct cx2341x_mpeg_params));
- hdw->enc_cur_valid = !0;
- }
- return ret;
-}
-
-
-int pvr2_encoder_configure(struct pvr2_hdw *hdw)
-{
- int ret;
- int val;
- pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure"
- " (cx2341x module)");
- hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING;
- hdw->enc_ctl_state.width = hdw->res_hor_val;
- hdw->enc_ctl_state.height = hdw->res_ver_val;
- hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & V4L2_STD_525_60) ?
- 0 : 1);
-
- ret = 0;
-
- ret |= pvr2_encoder_prep_config(hdw);
-
- /* saa7115: 0xf0 */
- val = 0xf0;
- if (hdw->hdw_desc->flag_has_cx25840) {
- /* ivtv cx25840: 0x140 */
- val = 0x140;
- }
-
- if (!ret) ret = pvr2_encoder_vcmd(
- hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2,
- val, val);
-
- /* setup firmware to notify us about some events (don't know why...) */
- if (!ret) ret = pvr2_encoder_vcmd(
- hdw,CX2341X_ENC_SET_EVENT_NOTIFICATION, 4,
- 0, 0, 0x10000000, 0xffffffff);
-
- if (!ret) ret = pvr2_encoder_vcmd(
- hdw,CX2341X_ENC_SET_VBI_LINE, 5,
- 0xffffffff,0,0,0,0);
-
- if (ret) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Failed to configure cx23416");
- return ret;
- }
-
- ret = pvr2_encoder_adjust(hdw);
- if (ret) return ret;
-
- ret = pvr2_encoder_vcmd(
- hdw, CX2341X_ENC_INITIALIZE_INPUT, 0);
-
- if (ret) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Failed to initialize cx23416 video input");
- return ret;
- }
-
- return 0;
-}
-
-
-int pvr2_encoder_start(struct pvr2_hdw *hdw)
-{
- int status;
-
- /* unmask some interrupts */
- pvr2_write_register(hdw, 0x0048, 0xbfffffff);
-
- pvr2_encoder_vcmd(hdw,CX2341X_ENC_MUTE_VIDEO,1,
- hdw->input_val == PVR2_CVAL_INPUT_RADIO ? 1 : 0);
-
- switch (hdw->active_stream_type) {
- case pvr2_config_vbi:
- status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
- 0x01,0x14);
- break;
- case pvr2_config_mpeg:
- status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
- 0,0x13);
- break;
- default: /* Unhandled cases for now */
- status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
- 0,0x13);
- break;
- }
- return status;
-}
-
-int pvr2_encoder_stop(struct pvr2_hdw *hdw)
-{
- int status;
-
- /* mask all interrupts */
- pvr2_write_register(hdw, 0x0048, 0xffffffff);
-
- switch (hdw->active_stream_type) {
- case pvr2_config_vbi:
- status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
- 0x01,0x01,0x14);
- break;
- case pvr2_config_mpeg:
- status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
- 0x01,0,0x13);
- break;
- default: /* Unhandled cases for now */
- status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
- 0x01,0,0x13);
- break;
- }
-
- return status;
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.h b/drivers/media/video/pvrusb2/pvrusb2-encoder.h
deleted file mode 100644
index 232fefbcd1a..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef __PVRUSB2_ENCODER_H
-#define __PVRUSB2_ENCODER_H
-
-struct pvr2_hdw;
-
-int pvr2_encoder_adjust(struct pvr2_hdw *);
-int pvr2_encoder_configure(struct pvr2_hdw *);
-int pvr2_encoder_start(struct pvr2_hdw *);
-int pvr2_encoder_stop(struct pvr2_hdw *);
-
-#endif /* __PVRUSB2_ENCODER_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h
deleted file mode 100644
index 614755ea2ea..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2007 Michael Krufky <mkrufky@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef _PVRUSB2_FX2_CMD_H_
-#define _PVRUSB2_FX2_CMD_H_
-
-#define FX2CMD_MEM_WRITE_DWORD 0x01u
-#define FX2CMD_MEM_READ_DWORD 0x02u
-
-#define FX2CMD_HCW_ZILOG_RESET 0x10u /* 1=reset 0=release */
-
-#define FX2CMD_MEM_READ_64BYTES 0x28u
-
-#define FX2CMD_REG_WRITE 0x04u
-#define FX2CMD_REG_READ 0x05u
-#define FX2CMD_MEMSEL 0x06u
-
-#define FX2CMD_I2C_WRITE 0x08u
-#define FX2CMD_I2C_READ 0x09u
-
-#define FX2CMD_GET_USB_SPEED 0x0bu
-
-#define FX2CMD_STREAMING_ON 0x36u
-#define FX2CMD_STREAMING_OFF 0x37u
-
-#define FX2CMD_FWPOST1 0x52u
-
-#define FX2CMD_POWER_OFF 0xdcu
-#define FX2CMD_POWER_ON 0xdeu
-
-#define FX2CMD_DEEP_RESET 0xddu
-
-#define FX2CMD_GET_EEPROM_ADDR 0xebu
-#define FX2CMD_GET_IR_CODE 0xecu
-
-#define FX2CMD_HCW_DEMOD_RESETIN 0xf0u
-#define FX2CMD_HCW_DTV_STREAMING_ON 0xf1u
-#define FX2CMD_HCW_DTV_STREAMING_OFF 0xf2u
-
-#define FX2CMD_ONAIR_DTV_STREAMING_ON 0xa0u
-#define FX2CMD_ONAIR_DTV_STREAMING_OFF 0xa1u
-#define FX2CMD_ONAIR_DTV_POWER_ON 0xa2u
-#define FX2CMD_ONAIR_DTV_POWER_OFF 0xa3u
-
-#endif /* _PVRUSB2_FX2_CMD_H_ */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
deleted file mode 100644
index 036952f2a3c..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __PVRUSB2_HDW_INTERNAL_H
-#define __PVRUSB2_HDW_INTERNAL_H
-
-/*
-
- This header sets up all the internal structures and definitions needed to
- track and coordinate the driver's interaction with the hardware. ONLY
- source files which actually implement part of that whole circus should be
- including this header. Higher levels, like the external layers to the
- various public APIs (V4L, sysfs, etc) should NOT ever include this
- private, internal header. This means that pvrusb2-hdw, pvrusb2-encoder,
- etc will include this, but pvrusb2-v4l should not.
-
-*/
-
-#include <linux/videodev2.h>
-#include <linux/i2c.h>
-#include <linux/workqueue.h>
-#include <linux/mutex.h>
-#include "pvrusb2-hdw.h"
-#include "pvrusb2-io.h"
-#include <media/v4l2-device.h>
-#include <media/cx2341x.h>
-#include <media/ir-kbd-i2c.h>
-#include "pvrusb2-devattr.h"
-
-/* Legal values for PVR2_CID_HSM */
-#define PVR2_CVAL_HSM_FAIL 0
-#define PVR2_CVAL_HSM_FULL 1
-#define PVR2_CVAL_HSM_HIGH 2
-
-#define PVR2_VID_ENDPOINT 0x84
-#define PVR2_UNK_ENDPOINT 0x86 /* maybe raw yuv ? */
-#define PVR2_VBI_ENDPOINT 0x88
-
-#define PVR2_CTL_BUFFSIZE 64
-
-#define FREQTABLE_SIZE 500
-
-#define LOCK_TAKE(x) do { mutex_lock(&x##_mutex); x##_held = !0; } while (0)
-#define LOCK_GIVE(x) do { x##_held = 0; mutex_unlock(&x##_mutex); } while (0)
-
-typedef int (*pvr2_ctlf_is_dirty)(struct pvr2_ctrl *);
-typedef void (*pvr2_ctlf_clear_dirty)(struct pvr2_ctrl *);
-typedef int (*pvr2_ctlf_check_value)(struct pvr2_ctrl *,int);
-typedef int (*pvr2_ctlf_get_value)(struct pvr2_ctrl *,int *);
-typedef int (*pvr2_ctlf_set_value)(struct pvr2_ctrl *,int msk,int val);
-typedef int (*pvr2_ctlf_val_to_sym)(struct pvr2_ctrl *,int msk,int val,
- char *,unsigned int,unsigned int *);
-typedef int (*pvr2_ctlf_sym_to_val)(struct pvr2_ctrl *,
- const char *,unsigned int,
- int *mskp,int *valp);
-typedef unsigned int (*pvr2_ctlf_get_v4lflags)(struct pvr2_ctrl *);
-
-/* This structure describes a specific control. A table of these is set up
- in pvrusb2-hdw.c. */
-struct pvr2_ctl_info {
- /* Control's name suitable for use as an identifier */
- const char *name;
-
- /* Short description of control */
- const char *desc;
-
- /* Control's implementation */
- pvr2_ctlf_get_value get_value; /* Get its value */
- pvr2_ctlf_get_value get_def_value; /* Get its default value */
- pvr2_ctlf_get_value get_min_value; /* Get minimum allowed value */
- pvr2_ctlf_get_value get_max_value; /* Get maximum allowed value */
- pvr2_ctlf_set_value set_value; /* Set its value */
- pvr2_ctlf_check_value check_value; /* Check that value is valid */
- pvr2_ctlf_val_to_sym val_to_sym; /* Custom convert value->symbol */
- pvr2_ctlf_sym_to_val sym_to_val; /* Custom convert symbol->value */
- pvr2_ctlf_is_dirty is_dirty; /* Return true if dirty */
- pvr2_ctlf_clear_dirty clear_dirty; /* Clear dirty state */
- pvr2_ctlf_get_v4lflags get_v4lflags;/* Retrieve v4l flags */
-
- /* Control's type (int, enum, bitmask) */
- enum pvr2_ctl_type type;
-
- /* Associated V4L control ID, if any */
- int v4l_id;
-
- /* Associated driver internal ID, if any */
- int internal_id;
-
- /* Don't implicitly initialize this control's value */
- int skip_init;
-
- /* Starting value for this control */
- int default_value;
-
- /* Type-specific control information */
- union {
- struct { /* Integer control */
- long min_value; /* lower limit */
- long max_value; /* upper limit */
- } type_int;
- struct { /* enumerated control */
- unsigned int count; /* enum value count */
- const char * const *value_names; /* symbol names */
- } type_enum;
- struct { /* bitmask control */
- unsigned int valid_bits; /* bits in use */
- const char **bit_names; /* symbol name/bit */
- } type_bitmask;
- } def;
-};
-
-
-/* Same as pvr2_ctl_info, but includes storage for the control description */
-#define PVR2_CTLD_INFO_DESC_SIZE 32
-struct pvr2_ctld_info {
- struct pvr2_ctl_info info;
- char desc[PVR2_CTLD_INFO_DESC_SIZE];
-};
-
-struct pvr2_ctrl {
- const struct pvr2_ctl_info *info;
- struct pvr2_hdw *hdw;
-};
-
-
-
-/* Disposition of firmware1 loading situation */
-#define FW1_STATE_UNKNOWN 0
-#define FW1_STATE_MISSING 1
-#define FW1_STATE_FAILED 2
-#define FW1_STATE_RELOAD 3
-#define FW1_STATE_OK 4
-
-/* What state the device is in if it is a hybrid */
-#define PVR2_PATHWAY_UNKNOWN 0
-#define PVR2_PATHWAY_ANALOG 1
-#define PVR2_PATHWAY_DIGITAL 2
-
-typedef int (*pvr2_i2c_func)(struct pvr2_hdw *,u8,u8 *,u16,u8 *, u16);
-#define PVR2_I2C_FUNC_CNT 128
-
-/* This structure contains all state data directly needed to
- manipulate the hardware (as opposed to complying with a kernel
- interface) */
-struct pvr2_hdw {
- /* Underlying USB device handle */
- struct usb_device *usb_dev;
- struct usb_interface *usb_intf;
-
- /* Our handle into the v4l2 sub-device architecture */
- struct v4l2_device v4l2_dev;
- /* Device description, anything that must adjust behavior based on
- device specific info will use information held here. */
- const struct pvr2_device_desc *hdw_desc;
-
- /* Kernel worker thread handling */
- struct workqueue_struct *workqueue;
- struct work_struct workpoll; /* Update driver state */
-
- /* Video spigot */
- struct pvr2_stream *vid_stream;
-
- /* Mutex for all hardware state control */
- struct mutex big_lock_mutex;
- int big_lock_held; /* For debugging */
-
- /* This is a simple string which identifies the instance of this
- driver. It is unique within the set of existing devices, but
- there is no attempt to keep the name consistent with the same
- physical device each time. */
- char name[32];
-
- /* This is a simple string which identifies the physical device
- instance itself - if possible. (If not possible, then it is
- based on the specific driver instance, similar to name above.)
- The idea here is that userspace might hopefully be able to use
- this recognize specific tuners. It will encode a serial number,
- if available. */
- char identifier[32];
-
- /* I2C stuff */
- struct i2c_adapter i2c_adap;
- struct i2c_algorithm i2c_algo;
- pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT];
- int i2c_cx25840_hack_state;
- int i2c_linked;
-
- /* IR related */
- unsigned int ir_scheme_active; /* IR scheme as seen from the outside */
- struct IR_i2c_init_data ir_init_data; /* params passed to IR modules */
-
- /* Frequency table */
- unsigned int freqTable[FREQTABLE_SIZE];
- unsigned int freqProgSlot;
-
- /* Stuff for handling low level control interaction with device */
- struct mutex ctl_lock_mutex;
- int ctl_lock_held; /* For debugging */
- struct urb *ctl_write_urb;
- struct urb *ctl_read_urb;
- unsigned char *ctl_write_buffer;
- unsigned char *ctl_read_buffer;
- int ctl_write_pend_flag;
- int ctl_read_pend_flag;
- int ctl_timeout_flag;
- struct completion ctl_done;
- unsigned char cmd_buffer[PVR2_CTL_BUFFSIZE];
- int cmd_debug_state; // Low level command debugging info
- unsigned char cmd_debug_code; //
- unsigned int cmd_debug_write_len; //
- unsigned int cmd_debug_read_len; //
-
- /* Bits of state that describe what is going on with various parts
- of the driver. */
- int state_pathway_ok; /* Pathway config is ok */
- int state_encoder_ok; /* Encoder is operational */
- int state_encoder_run; /* Encoder is running */
- int state_encoder_config; /* Encoder is configured */
- int state_encoder_waitok; /* Encoder pre-wait done */
- int state_encoder_runok; /* Encoder has run for >= .25 sec */
- int state_decoder_run; /* Decoder is running */
- int state_decoder_ready; /* Decoder is stabilized & streamable */
- int state_usbstream_run; /* FX2 is streaming */
- int state_decoder_quiescent; /* Decoder idle for minimal interval */
- int state_pipeline_config; /* Pipeline is configured */
- int state_pipeline_req; /* Somebody wants to stream */
- int state_pipeline_pause; /* Pipeline must be paused */
- int state_pipeline_idle; /* Pipeline not running */
-
- /* This is the master state of the driver. It is the combined
- result of other bits of state. Examining this will indicate the
- overall state of the driver. Values here are one of
- PVR2_STATE_xxxx */
- unsigned int master_state;
-
- /* True if device led is currently on */
- int led_on;
-
- /* True if states must be re-evaluated */
- int state_stale;
-
- void (*state_func)(void *);
- void *state_data;
-
- /* Timer for measuring required decoder settling time before we're
- allowed to fire it up again. */
- struct timer_list quiescent_timer;
-
- /* Timer for measuring decoder stabilization time, which is the
- amount of time we need to let the decoder run before we can
- trust its output (otherwise the encoder might see garbage and
- then fail to start correctly). */
- struct timer_list decoder_stabilization_timer;
-
- /* Timer for measuring encoder pre-wait time */
- struct timer_list encoder_wait_timer;
-
- /* Timer for measuring encoder minimum run time */
- struct timer_list encoder_run_timer;
-
- /* Place to block while waiting for state changes */
- wait_queue_head_t state_wait_data;
-
-
- int force_dirty; /* consider all controls dirty if true */
- int flag_ok; /* device in known good state */
- int flag_modulefail; /* true if at least one module failed to load */
- int flag_disconnected; /* flag_ok == 0 due to disconnect */
- int flag_init_ok; /* true if structure is fully initialized */
- int fw1_state; /* current situation with fw1 */
- int pathway_state; /* one of PVR2_PATHWAY_xxx */
- int flag_decoder_missed;/* We've noticed missing decoder */
- int flag_tripped; /* Indicates overall failure to start */
-
- unsigned int decoder_client_id;
-
- // CPU firmware info (used to help find / save firmware data)
- char *fw_buffer;
- unsigned int fw_size;
- int fw_cpu_flag; /* True if we are dealing with the CPU */
-
- /* Tuner / frequency control stuff */
- unsigned int tuner_type;
- int tuner_updated;
- unsigned int freqValTelevision; /* Current freq for tv mode */
- unsigned int freqValRadio; /* Current freq for radio mode */
- unsigned int freqSlotTelevision; /* Current slot for tv mode */
- unsigned int freqSlotRadio; /* Current slot for radio mode */
- unsigned int freqSelector; /* 0=radio 1=television */
- int freqDirty;
-
- /* Current tuner info - this information is polled from the I2C bus */
- struct v4l2_tuner tuner_signal_info;
- int tuner_signal_stale;
-
- /* Cropping capability info */
- struct v4l2_cropcap cropcap_info;
- int cropcap_stale;
-
- /* Video standard handling */
- v4l2_std_id std_mask_eeprom; // Hardware supported selections
- v4l2_std_id std_mask_avail; // Which standards we may select from
- v4l2_std_id std_mask_cur; // Currently selected standard(s)
- int std_enum_cur; // selected standard enumeration value
- int std_dirty; // True if std_mask_cur has changed
- struct pvr2_ctl_info std_info_enum;
- struct pvr2_ctl_info std_info_avail;
- struct pvr2_ctl_info std_info_cur;
- struct pvr2_ctl_info std_info_detect;
-
- // Generated string names, one per actual V4L2 standard
- const char *std_mask_ptrs[32];
- char std_mask_names[32][16];
-
- int unit_number; /* ID for driver instance */
- unsigned long serial_number; /* ID for hardware itself */
-
- char bus_info[32]; /* Bus location info */
-
- /* Minor numbers used by v4l logic (yes, this is a hack, as there
- should be no v4l junk here). Probably a better way to do this. */
- int v4l_minor_number_video;
- int v4l_minor_number_vbi;
- int v4l_minor_number_radio;
-
- /* Bit mask of PVR2_CVAL_INPUT choices which are valid for the hardware */
- unsigned int input_avail_mask;
- /* Bit mask of PVR2_CVAL_INPUT choices which are currently allowed */
- unsigned int input_allowed_mask;
-
- /* Location of eeprom or a negative number if none */
- int eeprom_addr;
-
- enum pvr2_config active_stream_type;
- enum pvr2_config desired_stream_type;
-
- /* Control state needed for cx2341x module */
- struct cx2341x_mpeg_params enc_cur_state;
- struct cx2341x_mpeg_params enc_ctl_state;
- /* True if an encoder attribute has changed */
- int enc_stale;
- /* True if an unsafe encoder attribute has changed */
- int enc_unsafe_stale;
- /* True if enc_cur_state is valid */
- int enc_cur_valid;
-
- /* Control state */
-#define VCREATE_DATA(lab) int lab##_val; int lab##_dirty
- VCREATE_DATA(brightness);
- VCREATE_DATA(contrast);
- VCREATE_DATA(saturation);
- VCREATE_DATA(hue);
- VCREATE_DATA(volume);
- VCREATE_DATA(balance);
- VCREATE_DATA(bass);
- VCREATE_DATA(treble);
- VCREATE_DATA(mute);
- VCREATE_DATA(cropl);
- VCREATE_DATA(cropt);
- VCREATE_DATA(cropw);
- VCREATE_DATA(croph);
- VCREATE_DATA(input);
- VCREATE_DATA(audiomode);
- VCREATE_DATA(res_hor);
- VCREATE_DATA(res_ver);
- VCREATE_DATA(srate);
-#undef VCREATE_DATA
-
- struct pvr2_ctld_info *mpeg_ctrl_info;
-
- struct pvr2_ctrl *controls;
- unsigned int control_cnt;
-};
-
-/* This function gets the current frequency */
-unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *);
-
-void pvr2_hdw_status_poll(struct pvr2_hdw *);
-
-#endif /* __PVRUSB2_HDW_INTERNAL_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
deleted file mode 100644
index fb828ba1dbb..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ /dev/null
@@ -1,5202 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/tuner.h>
-#include "pvrusb2.h"
-#include "pvrusb2-std.h"
-#include "pvrusb2-util.h"
-#include "pvrusb2-hdw.h"
-#include "pvrusb2-i2c-core.h"
-#include "pvrusb2-eeprom.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-encoder.h"
-#include "pvrusb2-debug.h"
-#include "pvrusb2-fx2-cmd.h"
-#include "pvrusb2-wm8775.h"
-#include "pvrusb2-video-v4l.h"
-#include "pvrusb2-cx2584x-v4l.h"
-#include "pvrusb2-cs53l32a.h"
-#include "pvrusb2-audio.h"
-
-#define TV_MIN_FREQ 55250000L
-#define TV_MAX_FREQ 850000000L
-
-/* This defines a minimum interval that the decoder must remain quiet
- before we are allowed to start it running. */
-#define TIME_MSEC_DECODER_WAIT 50
-
-/* This defines a minimum interval that the decoder must be allowed to run
- before we can safely begin using its streaming output. */
-#define TIME_MSEC_DECODER_STABILIZATION_WAIT 300
-
-/* This defines a minimum interval that the encoder must remain quiet
- before we are allowed to configure it. */
-#define TIME_MSEC_ENCODER_WAIT 50
-
-/* This defines the minimum interval that the encoder must successfully run
- before we consider that the encoder has run at least once since its
- firmware has been loaded. This measurement is in important for cases
- where we can't do something until we know that the encoder has been run
- at least once. */
-#define TIME_MSEC_ENCODER_OK 250
-
-static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
-static DEFINE_MUTEX(pvr2_unit_mtx);
-
-static int ctlchg;
-static int procreload;
-static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 };
-static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
-static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
-static int init_pause_msec;
-
-module_param(ctlchg, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value");
-module_param(init_pause_msec, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay");
-module_param(procreload, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(procreload,
- "Attempt init failure recovery with firmware reload");
-module_param_array(tuner, int, NULL, 0444);
-MODULE_PARM_DESC(tuner,"specify installed tuner type");
-module_param_array(video_std, int, NULL, 0444);
-MODULE_PARM_DESC(video_std,"specify initial video standard");
-module_param_array(tolerance, int, NULL, 0444);
-MODULE_PARM_DESC(tolerance,"specify stream error tolerance");
-
-/* US Broadcast channel 3 (61.25 MHz), to help with testing */
-static int default_tv_freq = 61250000L;
-/* 104.3 MHz, a usable FM station for my area */
-static int default_radio_freq = 104300000L;
-
-module_param_named(tv_freq, default_tv_freq, int, 0444);
-MODULE_PARM_DESC(tv_freq, "specify initial television frequency");
-module_param_named(radio_freq, default_radio_freq, int, 0444);
-MODULE_PARM_DESC(radio_freq, "specify initial radio frequency");
-
-#define PVR2_CTL_WRITE_ENDPOINT 0x01
-#define PVR2_CTL_READ_ENDPOINT 0x81
-
-#define PVR2_GPIO_IN 0x9008
-#define PVR2_GPIO_OUT 0x900c
-#define PVR2_GPIO_DIR 0x9020
-
-#define trace_firmware(...) pvr2_trace(PVR2_TRACE_FIRMWARE,__VA_ARGS__)
-
-#define PVR2_FIRMWARE_ENDPOINT 0x02
-
-/* size of a firmware chunk */
-#define FIRMWARE_CHUNK_SIZE 0x2000
-
-typedef void (*pvr2_subdev_update_func)(struct pvr2_hdw *,
- struct v4l2_subdev *);
-
-static const pvr2_subdev_update_func pvr2_module_update_functions[] = {
- [PVR2_CLIENT_ID_WM8775] = pvr2_wm8775_subdev_update,
- [PVR2_CLIENT_ID_SAA7115] = pvr2_saa7115_subdev_update,
- [PVR2_CLIENT_ID_MSP3400] = pvr2_msp3400_subdev_update,
- [PVR2_CLIENT_ID_CX25840] = pvr2_cx25840_subdev_update,
- [PVR2_CLIENT_ID_CS53L32A] = pvr2_cs53l32a_subdev_update,
-};
-
-static const char *module_names[] = {
- [PVR2_CLIENT_ID_MSP3400] = "msp3400",
- [PVR2_CLIENT_ID_CX25840] = "cx25840",
- [PVR2_CLIENT_ID_SAA7115] = "saa7115",
- [PVR2_CLIENT_ID_TUNER] = "tuner",
- [PVR2_CLIENT_ID_DEMOD] = "tuner",
- [PVR2_CLIENT_ID_CS53L32A] = "cs53l32a",
- [PVR2_CLIENT_ID_WM8775] = "wm8775",
-};
-
-
-static const unsigned char *module_i2c_addresses[] = {
- [PVR2_CLIENT_ID_TUNER] = "\x60\x61\x62\x63",
- [PVR2_CLIENT_ID_DEMOD] = "\x43",
- [PVR2_CLIENT_ID_MSP3400] = "\x40",
- [PVR2_CLIENT_ID_SAA7115] = "\x21",
- [PVR2_CLIENT_ID_WM8775] = "\x1b",
- [PVR2_CLIENT_ID_CX25840] = "\x44",
- [PVR2_CLIENT_ID_CS53L32A] = "\x11",
-};
-
-
-static const char *ir_scheme_names[] = {
- [PVR2_IR_SCHEME_NONE] = "none",
- [PVR2_IR_SCHEME_29XXX] = "29xxx",
- [PVR2_IR_SCHEME_24XXX] = "24xxx (29xxx emulation)",
- [PVR2_IR_SCHEME_24XXX_MCE] = "24xxx (MCE device)",
- [PVR2_IR_SCHEME_ZILOG] = "Zilog",
-};
-
-
-/* Define the list of additional controls we'll dynamically construct based
- on query of the cx2341x module. */
-struct pvr2_mpeg_ids {
- const char *strid;
- int id;
-};
-static const struct pvr2_mpeg_ids mpeg_ids[] = {
- {
- .strid = "audio_layer",
- .id = V4L2_CID_MPEG_AUDIO_ENCODING,
- },{
- .strid = "audio_bitrate",
- .id = V4L2_CID_MPEG_AUDIO_L2_BITRATE,
- },{
- /* Already using audio_mode elsewhere :-( */
- .strid = "mpeg_audio_mode",
- .id = V4L2_CID_MPEG_AUDIO_MODE,
- },{
- .strid = "mpeg_audio_mode_extension",
- .id = V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
- },{
- .strid = "audio_emphasis",
- .id = V4L2_CID_MPEG_AUDIO_EMPHASIS,
- },{
- .strid = "audio_crc",
- .id = V4L2_CID_MPEG_AUDIO_CRC,
- },{
- .strid = "video_aspect",
- .id = V4L2_CID_MPEG_VIDEO_ASPECT,
- },{
- .strid = "video_b_frames",
- .id = V4L2_CID_MPEG_VIDEO_B_FRAMES,
- },{
- .strid = "video_gop_size",
- .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,
- },{
- .strid = "video_gop_closure",
- .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
- },{
- .strid = "video_bitrate_mode",
- .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
- },{
- .strid = "video_bitrate",
- .id = V4L2_CID_MPEG_VIDEO_BITRATE,
- },{
- .strid = "video_bitrate_peak",
- .id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
- },{
- .strid = "video_temporal_decimation",
- .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
- },{
- .strid = "stream_type",
- .id = V4L2_CID_MPEG_STREAM_TYPE,
- },{
- .strid = "video_spatial_filter_mode",
- .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
- },{
- .strid = "video_spatial_filter",
- .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
- },{
- .strid = "video_luma_spatial_filter_type",
- .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
- },{
- .strid = "video_chroma_spatial_filter_type",
- .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
- },{
- .strid = "video_temporal_filter_mode",
- .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
- },{
- .strid = "video_temporal_filter",
- .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
- },{
- .strid = "video_median_filter_type",
- .id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
- },{
- .strid = "video_luma_median_filter_top",
- .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
- },{
- .strid = "video_luma_median_filter_bottom",
- .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
- },{
- .strid = "video_chroma_median_filter_top",
- .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
- },{
- .strid = "video_chroma_median_filter_bottom",
- .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
- }
-};
-#define MPEGDEF_COUNT ARRAY_SIZE(mpeg_ids)
-
-
-static const char *control_values_srate[] = {
- [V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100] = "44.1 kHz",
- [V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000] = "48 kHz",
- [V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000] = "32 kHz",
-};
-
-
-
-static const char *control_values_input[] = {
- [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/
- [PVR2_CVAL_INPUT_DTV] = "dtv",
- [PVR2_CVAL_INPUT_RADIO] = "radio",
- [PVR2_CVAL_INPUT_SVIDEO] = "s-video",
- [PVR2_CVAL_INPUT_COMPOSITE] = "composite",
-};
-
-
-static const char *control_values_audiomode[] = {
- [V4L2_TUNER_MODE_MONO] = "Mono",
- [V4L2_TUNER_MODE_STEREO] = "Stereo",
- [V4L2_TUNER_MODE_LANG1] = "Lang1",
- [V4L2_TUNER_MODE_LANG2] = "Lang2",
- [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2",
-};
-
-
-static const char *control_values_hsm[] = {
- [PVR2_CVAL_HSM_FAIL] = "Fail",
- [PVR2_CVAL_HSM_HIGH] = "High",
- [PVR2_CVAL_HSM_FULL] = "Full",
-};
-
-
-static const char *pvr2_state_names[] = {
- [PVR2_STATE_NONE] = "none",
- [PVR2_STATE_DEAD] = "dead",
- [PVR2_STATE_COLD] = "cold",
- [PVR2_STATE_WARM] = "warm",
- [PVR2_STATE_ERROR] = "error",
- [PVR2_STATE_READY] = "ready",
- [PVR2_STATE_RUN] = "run",
-};
-
-
-struct pvr2_fx2cmd_descdef {
- unsigned char id;
- unsigned char *desc;
-};
-
-static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = {
- {FX2CMD_MEM_WRITE_DWORD, "write encoder dword"},
- {FX2CMD_MEM_READ_DWORD, "read encoder dword"},
- {FX2CMD_HCW_ZILOG_RESET, "zilog IR reset control"},
- {FX2CMD_MEM_READ_64BYTES, "read encoder 64bytes"},
- {FX2CMD_REG_WRITE, "write encoder register"},
- {FX2CMD_REG_READ, "read encoder register"},
- {FX2CMD_MEMSEL, "encoder memsel"},
- {FX2CMD_I2C_WRITE, "i2c write"},
- {FX2CMD_I2C_READ, "i2c read"},
- {FX2CMD_GET_USB_SPEED, "get USB speed"},
- {FX2CMD_STREAMING_ON, "stream on"},
- {FX2CMD_STREAMING_OFF, "stream off"},
- {FX2CMD_FWPOST1, "fwpost1"},
- {FX2CMD_POWER_OFF, "power off"},
- {FX2CMD_POWER_ON, "power on"},
- {FX2CMD_DEEP_RESET, "deep reset"},
- {FX2CMD_GET_EEPROM_ADDR, "get rom addr"},
- {FX2CMD_GET_IR_CODE, "get IR code"},
- {FX2CMD_HCW_DEMOD_RESETIN, "hcw demod resetin"},
- {FX2CMD_HCW_DTV_STREAMING_ON, "hcw dtv stream on"},
- {FX2CMD_HCW_DTV_STREAMING_OFF, "hcw dtv stream off"},
- {FX2CMD_ONAIR_DTV_STREAMING_ON, "onair dtv stream on"},
- {FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"},
- {FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"},
- {FX2CMD_ONAIR_DTV_POWER_OFF, "onair dtv power off"},
-};
-
-
-static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v);
-static void pvr2_hdw_state_sched(struct pvr2_hdw *);
-static int pvr2_hdw_state_eval(struct pvr2_hdw *);
-static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long);
-static void pvr2_hdw_worker_poll(struct work_struct *work);
-static int pvr2_hdw_wait(struct pvr2_hdw *,int state);
-static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *);
-static void pvr2_hdw_state_log_state(struct pvr2_hdw *);
-static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
-static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw);
-static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
-static void pvr2_hdw_quiescent_timeout(unsigned long);
-static void pvr2_hdw_decoder_stabilization_timeout(unsigned long);
-static void pvr2_hdw_encoder_wait_timeout(unsigned long);
-static void pvr2_hdw_encoder_run_timeout(unsigned long);
-static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32);
-static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
- unsigned int timeout,int probe_fl,
- void *write_data,unsigned int write_len,
- void *read_data,unsigned int read_len);
-static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw);
-static v4l2_std_id pvr2_hdw_get_detected_std(struct pvr2_hdw *hdw);
-
-static void trace_stbit(const char *name,int val)
-{
- pvr2_trace(PVR2_TRACE_STBITS,
- "State bit %s <-- %s",
- name,(val ? "true" : "false"));
-}
-
-static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
-{
- struct pvr2_hdw *hdw = cptr->hdw;
- if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
- *vp = hdw->freqTable[hdw->freqProgSlot-1];
- } else {
- *vp = 0;
- }
- return 0;
-}
-
-static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v)
-{
- struct pvr2_hdw *hdw = cptr->hdw;
- unsigned int slotId = hdw->freqProgSlot;
- if ((slotId > 0) && (slotId <= FREQTABLE_SIZE)) {
- hdw->freqTable[slotId-1] = v;
- /* Handle side effects correctly - if we're tuned to this
- slot, then forgot the slot id relation since the stored
- frequency has been changed. */
- if (hdw->freqSelector) {
- if (hdw->freqSlotRadio == slotId) {
- hdw->freqSlotRadio = 0;
- }
- } else {
- if (hdw->freqSlotTelevision == slotId) {
- hdw->freqSlotTelevision = 0;
- }
- }
- }
- return 0;
-}
-
-static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp)
-{
- *vp = cptr->hdw->freqProgSlot;
- return 0;
-}
-
-static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v)
-{
- struct pvr2_hdw *hdw = cptr->hdw;
- if ((v >= 0) && (v <= FREQTABLE_SIZE)) {
- hdw->freqProgSlot = v;
- }
- return 0;
-}
-
-static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp)
-{
- struct pvr2_hdw *hdw = cptr->hdw;
- *vp = hdw->freqSelector ? hdw->freqSlotRadio : hdw->freqSlotTelevision;
- return 0;
-}
-
-static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int slotId)
-{
- unsigned freq = 0;
- struct pvr2_hdw *hdw = cptr->hdw;
- if ((slotId < 0) || (slotId > FREQTABLE_SIZE)) return 0;
- if (slotId > 0) {
- freq = hdw->freqTable[slotId-1];
- if (!freq) return 0;
- pvr2_hdw_set_cur_freq(hdw,freq);
- }
- if (hdw->freqSelector) {
- hdw->freqSlotRadio = slotId;
- } else {
- hdw->freqSlotTelevision = slotId;
- }
- return 0;
-}
-
-static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp)
-{
- *vp = pvr2_hdw_get_cur_freq(cptr->hdw);
- return 0;
-}
-
-static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr)
-{
- return cptr->hdw->freqDirty != 0;
-}
-
-static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr)
-{
- cptr->hdw->freqDirty = 0;
-}
-
-static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
-{
- pvr2_hdw_set_cur_freq(cptr->hdw,v);
- return 0;
-}
-
-static int ctrl_cropl_min_get(struct pvr2_ctrl *cptr, int *left)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- *left = cap->bounds.left;
- return 0;
-}
-
-static int ctrl_cropl_max_get(struct pvr2_ctrl *cptr, int *left)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- *left = cap->bounds.left;
- if (cap->bounds.width > cptr->hdw->cropw_val) {
- *left += cap->bounds.width - cptr->hdw->cropw_val;
- }
- return 0;
-}
-
-static int ctrl_cropt_min_get(struct pvr2_ctrl *cptr, int *top)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- *top = cap->bounds.top;
- return 0;
-}
-
-static int ctrl_cropt_max_get(struct pvr2_ctrl *cptr, int *top)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- *top = cap->bounds.top;
- if (cap->bounds.height > cptr->hdw->croph_val) {
- *top += cap->bounds.height - cptr->hdw->croph_val;
- }
- return 0;
-}
-
-static int ctrl_cropw_max_get(struct pvr2_ctrl *cptr, int *width)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat, bleftend, cleft;
-
- stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- bleftend = cap->bounds.left+cap->bounds.width;
- cleft = cptr->hdw->cropl_val;
-
- *width = cleft < bleftend ? bleftend-cleft : 0;
- return 0;
-}
-
-static int ctrl_croph_max_get(struct pvr2_ctrl *cptr, int *height)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat, btopend, ctop;
-
- stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- btopend = cap->bounds.top+cap->bounds.height;
- ctop = cptr->hdw->cropt_val;
-
- *height = ctop < btopend ? btopend-ctop : 0;
- return 0;
-}
-
-static int ctrl_get_cropcapbl(struct pvr2_ctrl *cptr, int *val)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- *val = cap->bounds.left;
- return 0;
-}
-
-static int ctrl_get_cropcapbt(struct pvr2_ctrl *cptr, int *val)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- *val = cap->bounds.top;
- return 0;
-}
-
-static int ctrl_get_cropcapbw(struct pvr2_ctrl *cptr, int *val)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- *val = cap->bounds.width;
- return 0;
-}
-
-static int ctrl_get_cropcapbh(struct pvr2_ctrl *cptr, int *val)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- *val = cap->bounds.height;
- return 0;
-}
-
-static int ctrl_get_cropcapdl(struct pvr2_ctrl *cptr, int *val)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- *val = cap->defrect.left;
- return 0;
-}
-
-static int ctrl_get_cropcapdt(struct pvr2_ctrl *cptr, int *val)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- *val = cap->defrect.top;
- return 0;
-}
-
-static int ctrl_get_cropcapdw(struct pvr2_ctrl *cptr, int *val)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- *val = cap->defrect.width;
- return 0;
-}
-
-static int ctrl_get_cropcapdh(struct pvr2_ctrl *cptr, int *val)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- *val = cap->defrect.height;
- return 0;
-}
-
-static int ctrl_get_cropcappan(struct pvr2_ctrl *cptr, int *val)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- *val = cap->pixelaspect.numerator;
- return 0;
-}
-
-static int ctrl_get_cropcappad(struct pvr2_ctrl *cptr, int *val)
-{
- struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
- int stat = pvr2_hdw_check_cropcap(cptr->hdw);
- if (stat != 0) {
- return stat;
- }
- *val = cap->pixelaspect.denominator;
- return 0;
-}
-
-static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp)
-{
- /* Actual maximum depends on the video standard in effect. */
- if (cptr->hdw->std_mask_cur & V4L2_STD_525_60) {
- *vp = 480;
- } else {
- *vp = 576;
- }
- return 0;
-}
-
-static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp)
-{
- /* Actual minimum depends on device digitizer type. */
- if (cptr->hdw->hdw_desc->flag_has_cx25840) {
- *vp = 75;
- } else {
- *vp = 17;
- }
- return 0;
-}
-
-static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp)
-{
- *vp = cptr->hdw->input_val;
- return 0;
-}
-
-static int ctrl_check_input(struct pvr2_ctrl *cptr,int v)
-{
- return ((1 << v) & cptr->hdw->input_allowed_mask) != 0;
-}
-
-static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v)
-{
- return pvr2_hdw_set_input(cptr->hdw,v);
-}
-
-static int ctrl_isdirty_input(struct pvr2_ctrl *cptr)
-{
- return cptr->hdw->input_dirty != 0;
-}
-
-static void ctrl_cleardirty_input(struct pvr2_ctrl *cptr)
-{
- cptr->hdw->input_dirty = 0;
-}
-
-
-static int ctrl_freq_max_get(struct pvr2_ctrl *cptr, int *vp)
-{
- unsigned long fv;
- struct pvr2_hdw *hdw = cptr->hdw;
- if (hdw->tuner_signal_stale) {
- pvr2_hdw_status_poll(hdw);
- }
- fv = hdw->tuner_signal_info.rangehigh;
- if (!fv) {
- /* Safety fallback */
- *vp = TV_MAX_FREQ;
- return 0;
- }
- if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
- fv = (fv * 125) / 2;
- } else {
- fv = fv * 62500;
- }
- *vp = fv;
- return 0;
-}
-
-static int ctrl_freq_min_get(struct pvr2_ctrl *cptr, int *vp)
-{
- unsigned long fv;
- struct pvr2_hdw *hdw = cptr->hdw;
- if (hdw->tuner_signal_stale) {
- pvr2_hdw_status_poll(hdw);
- }
- fv = hdw->tuner_signal_info.rangelow;
- if (!fv) {
- /* Safety fallback */
- *vp = TV_MIN_FREQ;
- return 0;
- }
- if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
- fv = (fv * 125) / 2;
- } else {
- fv = fv * 62500;
- }
- *vp = fv;
- return 0;
-}
-
-static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
-{
- return cptr->hdw->enc_stale != 0;
-}
-
-static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr)
-{
- cptr->hdw->enc_stale = 0;
- cptr->hdw->enc_unsafe_stale = 0;
-}
-
-static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp)
-{
- int ret;
- struct v4l2_ext_controls cs;
- struct v4l2_ext_control c1;
- memset(&cs,0,sizeof(cs));
- memset(&c1,0,sizeof(c1));
- cs.controls = &c1;
- cs.count = 1;
- c1.id = cptr->info->v4l_id;
- ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state, 0, &cs,
- VIDIOC_G_EXT_CTRLS);
- if (ret) return ret;
- *vp = c1.value;
- return 0;
-}
-
-static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v)
-{
- int ret;
- struct pvr2_hdw *hdw = cptr->hdw;
- struct v4l2_ext_controls cs;
- struct v4l2_ext_control c1;
- memset(&cs,0,sizeof(cs));
- memset(&c1,0,sizeof(c1));
- cs.controls = &c1;
- cs.count = 1;
- c1.id = cptr->info->v4l_id;
- c1.value = v;
- ret = cx2341x_ext_ctrls(&hdw->enc_ctl_state,
- hdw->state_encoder_run, &cs,
- VIDIOC_S_EXT_CTRLS);
- if (ret == -EBUSY) {
- /* Oops. cx2341x is telling us it's not safe to change
- this control while we're capturing. Make a note of this
- fact so that the pipeline will be stopped the next time
- controls are committed. Then go on ahead and store this
- change anyway. */
- ret = cx2341x_ext_ctrls(&hdw->enc_ctl_state,
- 0, &cs,
- VIDIOC_S_EXT_CTRLS);
- if (!ret) hdw->enc_unsafe_stale = !0;
- }
- if (ret) return ret;
- hdw->enc_stale = !0;
- return 0;
-}
-
-static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr)
-{
- struct v4l2_queryctrl qctrl;
- struct pvr2_ctl_info *info;
- qctrl.id = cptr->info->v4l_id;
- cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl);
- /* Strip out the const so we can adjust a function pointer. It's
- OK to do this here because we know this is a dynamically created
- control, so the underlying storage for the info pointer is (a)
- private to us, and (b) not in read-only storage. Either we do
- this or we significantly complicate the underlying control
- implementation. */
- info = (struct pvr2_ctl_info *)(cptr->info);
- if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
- if (info->set_value) {
- info->set_value = NULL;
- }
- } else {
- if (!(info->set_value)) {
- info->set_value = ctrl_cx2341x_set;
- }
- }
- return qctrl.flags;
-}
-
-static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp)
-{
- *vp = cptr->hdw->state_pipeline_req;
- return 0;
-}
-
-static int ctrl_masterstate_get(struct pvr2_ctrl *cptr,int *vp)
-{
- *vp = cptr->hdw->master_state;
- return 0;
-}
-
-static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
-{
- int result = pvr2_hdw_is_hsm(cptr->hdw);
- *vp = PVR2_CVAL_HSM_FULL;
- if (result < 0) *vp = PVR2_CVAL_HSM_FAIL;
- if (result) *vp = PVR2_CVAL_HSM_HIGH;
- return 0;
-}
-
-static int ctrl_stddetect_get(struct pvr2_ctrl *cptr, int *vp)
-{
- *vp = pvr2_hdw_get_detected_std(cptr->hdw);
- return 0;
-}
-
-static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
-{
- *vp = cptr->hdw->std_mask_avail;
- return 0;
-}
-
-static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
-{
- struct pvr2_hdw *hdw = cptr->hdw;
- v4l2_std_id ns;
- ns = hdw->std_mask_avail;
- ns = (ns & ~m) | (v & m);
- if (ns == hdw->std_mask_avail) return 0;
- hdw->std_mask_avail = ns;
- hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
- return 0;
-}
-
-static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val,
- char *bufPtr,unsigned int bufSize,
- unsigned int *len)
-{
- *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val);
- return 0;
-}
-
-static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr,
- const char *bufPtr,unsigned int bufSize,
- int *mskp,int *valp)
-{
- int ret;
- v4l2_std_id id;
- ret = pvr2_std_str_to_id(&id,bufPtr,bufSize);
- if (ret < 0) return ret;
- if (mskp) *mskp = id;
- if (valp) *valp = id;
- return 0;
-}
-
-static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp)
-{
- *vp = cptr->hdw->std_mask_cur;
- return 0;
-}
-
-static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
-{
- struct pvr2_hdw *hdw = cptr->hdw;
- v4l2_std_id ns;
- ns = hdw->std_mask_cur;
- ns = (ns & ~m) | (v & m);
- if (ns == hdw->std_mask_cur) return 0;
- hdw->std_mask_cur = ns;
- hdw->std_dirty = !0;
- return 0;
-}
-
-static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr)
-{
- return cptr->hdw->std_dirty != 0;
-}
-
-static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
-{
- cptr->hdw->std_dirty = 0;
-}
-
-static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
-{
- struct pvr2_hdw *hdw = cptr->hdw;
- pvr2_hdw_status_poll(hdw);
- *vp = hdw->tuner_signal_info.signal;
- return 0;
-}
-
-static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp)
-{
- int val = 0;
- unsigned int subchan;
- struct pvr2_hdw *hdw = cptr->hdw;
- pvr2_hdw_status_poll(hdw);
- subchan = hdw->tuner_signal_info.rxsubchans;
- if (subchan & V4L2_TUNER_SUB_MONO) {
- val |= (1 << V4L2_TUNER_MODE_MONO);
- }
- if (subchan & V4L2_TUNER_SUB_STEREO) {
- val |= (1 << V4L2_TUNER_MODE_STEREO);
- }
- if (subchan & V4L2_TUNER_SUB_LANG1) {
- val |= (1 << V4L2_TUNER_MODE_LANG1);
- }
- if (subchan & V4L2_TUNER_SUB_LANG2) {
- val |= (1 << V4L2_TUNER_MODE_LANG2);
- }
- *vp = val;
- return 0;
-}
-
-
-#define DEFINT(vmin,vmax) \
- .type = pvr2_ctl_int, \
- .def.type_int.min_value = vmin, \
- .def.type_int.max_value = vmax
-
-#define DEFENUM(tab) \
- .type = pvr2_ctl_enum, \
- .def.type_enum.count = ARRAY_SIZE(tab), \
- .def.type_enum.value_names = tab
-
-#define DEFBOOL \
- .type = pvr2_ctl_bool
-
-#define DEFMASK(msk,tab) \
- .type = pvr2_ctl_bitmask, \
- .def.type_bitmask.valid_bits = msk, \
- .def.type_bitmask.bit_names = tab
-
-#define DEFREF(vname) \
- .set_value = ctrl_set_##vname, \
- .get_value = ctrl_get_##vname, \
- .is_dirty = ctrl_isdirty_##vname, \
- .clear_dirty = ctrl_cleardirty_##vname
-
-
-#define VCREATE_FUNCS(vname) \
-static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \
-{*vp = cptr->hdw->vname##_val; return 0;} \
-static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \
-{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \
-static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \
-{return cptr->hdw->vname##_dirty != 0;} \
-static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \
-{cptr->hdw->vname##_dirty = 0;}
-
-VCREATE_FUNCS(brightness)
-VCREATE_FUNCS(contrast)
-VCREATE_FUNCS(saturation)
-VCREATE_FUNCS(hue)
-VCREATE_FUNCS(volume)
-VCREATE_FUNCS(balance)
-VCREATE_FUNCS(bass)
-VCREATE_FUNCS(treble)
-VCREATE_FUNCS(mute)
-VCREATE_FUNCS(cropl)
-VCREATE_FUNCS(cropt)
-VCREATE_FUNCS(cropw)
-VCREATE_FUNCS(croph)
-VCREATE_FUNCS(audiomode)
-VCREATE_FUNCS(res_hor)
-VCREATE_FUNCS(res_ver)
-VCREATE_FUNCS(srate)
-
-/* Table definition of all controls which can be manipulated */
-static const struct pvr2_ctl_info control_defs[] = {
- {
- .v4l_id = V4L2_CID_BRIGHTNESS,
- .desc = "Brightness",
- .name = "brightness",
- .default_value = 128,
- DEFREF(brightness),
- DEFINT(0,255),
- },{
- .v4l_id = V4L2_CID_CONTRAST,
- .desc = "Contrast",
- .name = "contrast",
- .default_value = 68,
- DEFREF(contrast),
- DEFINT(0,127),
- },{
- .v4l_id = V4L2_CID_SATURATION,
- .desc = "Saturation",
- .name = "saturation",
- .default_value = 64,
- DEFREF(saturation),
- DEFINT(0,127),
- },{
- .v4l_id = V4L2_CID_HUE,
- .desc = "Hue",
- .name = "hue",
- .default_value = 0,
- DEFREF(hue),
- DEFINT(-128,127),
- },{
- .v4l_id = V4L2_CID_AUDIO_VOLUME,
- .desc = "Volume",
- .name = "volume",
- .default_value = 62000,
- DEFREF(volume),
- DEFINT(0,65535),
- },{
- .v4l_id = V4L2_CID_AUDIO_BALANCE,
- .desc = "Balance",
- .name = "balance",
- .default_value = 0,
- DEFREF(balance),
- DEFINT(-32768,32767),
- },{
- .v4l_id = V4L2_CID_AUDIO_BASS,
- .desc = "Bass",
- .name = "bass",
- .default_value = 0,
- DEFREF(bass),
- DEFINT(-32768,32767),
- },{
- .v4l_id = V4L2_CID_AUDIO_TREBLE,
- .desc = "Treble",
- .name = "treble",
- .default_value = 0,
- DEFREF(treble),
- DEFINT(-32768,32767),
- },{
- .v4l_id = V4L2_CID_AUDIO_MUTE,
- .desc = "Mute",
- .name = "mute",
- .default_value = 0,
- DEFREF(mute),
- DEFBOOL,
- }, {
- .desc = "Capture crop left margin",
- .name = "crop_left",
- .internal_id = PVR2_CID_CROPL,
- .default_value = 0,
- DEFREF(cropl),
- DEFINT(-129, 340),
- .get_min_value = ctrl_cropl_min_get,
- .get_max_value = ctrl_cropl_max_get,
- .get_def_value = ctrl_get_cropcapdl,
- }, {
- .desc = "Capture crop top margin",
- .name = "crop_top",
- .internal_id = PVR2_CID_CROPT,
- .default_value = 0,
- DEFREF(cropt),
- DEFINT(-35, 544),
- .get_min_value = ctrl_cropt_min_get,
- .get_max_value = ctrl_cropt_max_get,
- .get_def_value = ctrl_get_cropcapdt,
- }, {
- .desc = "Capture crop width",
- .name = "crop_width",
- .internal_id = PVR2_CID_CROPW,
- .default_value = 720,
- DEFREF(cropw),
- DEFINT(0, 864),
- .get_max_value = ctrl_cropw_max_get,
- .get_def_value = ctrl_get_cropcapdw,
- }, {
- .desc = "Capture crop height",
- .name = "crop_height",
- .internal_id = PVR2_CID_CROPH,
- .default_value = 480,
- DEFREF(croph),
- DEFINT(0, 576),
- .get_max_value = ctrl_croph_max_get,
- .get_def_value = ctrl_get_cropcapdh,
- }, {
- .desc = "Capture capability pixel aspect numerator",
- .name = "cropcap_pixel_numerator",
- .internal_id = PVR2_CID_CROPCAPPAN,
- .get_value = ctrl_get_cropcappan,
- }, {
- .desc = "Capture capability pixel aspect denominator",
- .name = "cropcap_pixel_denominator",
- .internal_id = PVR2_CID_CROPCAPPAD,
- .get_value = ctrl_get_cropcappad,
- }, {
- .desc = "Capture capability bounds top",
- .name = "cropcap_bounds_top",
- .internal_id = PVR2_CID_CROPCAPBT,
- .get_value = ctrl_get_cropcapbt,
- }, {
- .desc = "Capture capability bounds left",
- .name = "cropcap_bounds_left",
- .internal_id = PVR2_CID_CROPCAPBL,
- .get_value = ctrl_get_cropcapbl,
- }, {
- .desc = "Capture capability bounds width",
- .name = "cropcap_bounds_width",
- .internal_id = PVR2_CID_CROPCAPBW,
- .get_value = ctrl_get_cropcapbw,
- }, {
- .desc = "Capture capability bounds height",
- .name = "cropcap_bounds_height",
- .internal_id = PVR2_CID_CROPCAPBH,
- .get_value = ctrl_get_cropcapbh,
- },{
- .desc = "Video Source",
- .name = "input",
- .internal_id = PVR2_CID_INPUT,
- .default_value = PVR2_CVAL_INPUT_TV,
- .check_value = ctrl_check_input,
- DEFREF(input),
- DEFENUM(control_values_input),
- },{
- .desc = "Audio Mode",
- .name = "audio_mode",
- .internal_id = PVR2_CID_AUDIOMODE,
- .default_value = V4L2_TUNER_MODE_STEREO,
- DEFREF(audiomode),
- DEFENUM(control_values_audiomode),
- },{
- .desc = "Horizontal capture resolution",
- .name = "resolution_hor",
- .internal_id = PVR2_CID_HRES,
- .default_value = 720,
- DEFREF(res_hor),
- DEFINT(19,720),
- },{
- .desc = "Vertical capture resolution",
- .name = "resolution_ver",
- .internal_id = PVR2_CID_VRES,
- .default_value = 480,
- DEFREF(res_ver),
- DEFINT(17,576),
- /* Hook in check for video standard and adjust maximum
- depending on the standard. */
- .get_max_value = ctrl_vres_max_get,
- .get_min_value = ctrl_vres_min_get,
- },{
- .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
- .default_value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
- .desc = "Audio Sampling Frequency",
- .name = "srate",
- DEFREF(srate),
- DEFENUM(control_values_srate),
- },{
- .desc = "Tuner Frequency (Hz)",
- .name = "frequency",
- .internal_id = PVR2_CID_FREQUENCY,
- .default_value = 0,
- .set_value = ctrl_freq_set,
- .get_value = ctrl_freq_get,
- .is_dirty = ctrl_freq_is_dirty,
- .clear_dirty = ctrl_freq_clear_dirty,
- DEFINT(0,0),
- /* Hook in check for input value (tv/radio) and adjust
- max/min values accordingly */
- .get_max_value = ctrl_freq_max_get,
- .get_min_value = ctrl_freq_min_get,
- },{
- .desc = "Channel",
- .name = "channel",
- .set_value = ctrl_channel_set,
- .get_value = ctrl_channel_get,
- DEFINT(0,FREQTABLE_SIZE),
- },{
- .desc = "Channel Program Frequency",
- .name = "freq_table_value",
- .set_value = ctrl_channelfreq_set,
- .get_value = ctrl_channelfreq_get,
- DEFINT(0,0),
- /* Hook in check for input value (tv/radio) and adjust
- max/min values accordingly */
- .get_max_value = ctrl_freq_max_get,
- .get_min_value = ctrl_freq_min_get,
- },{
- .desc = "Channel Program ID",
- .name = "freq_table_channel",
- .set_value = ctrl_channelprog_set,
- .get_value = ctrl_channelprog_get,
- DEFINT(0,FREQTABLE_SIZE),
- },{
- .desc = "Streaming Enabled",
- .name = "streaming_enabled",
- .get_value = ctrl_streamingenabled_get,
- DEFBOOL,
- },{
- .desc = "USB Speed",
- .name = "usb_speed",
- .get_value = ctrl_hsm_get,
- DEFENUM(control_values_hsm),
- },{
- .desc = "Master State",
- .name = "master_state",
- .get_value = ctrl_masterstate_get,
- DEFENUM(pvr2_state_names),
- },{
- .desc = "Signal Present",
- .name = "signal_present",
- .get_value = ctrl_signal_get,
- DEFINT(0,65535),
- },{
- .desc = "Audio Modes Present",
- .name = "audio_modes_present",
- .get_value = ctrl_audio_modes_present_get,
- /* For this type we "borrow" the V4L2_TUNER_MODE enum from
- v4l. Nothing outside of this module cares about this,
- but I reuse it in order to also reuse the
- control_values_audiomode string table. */
- DEFMASK(((1 << V4L2_TUNER_MODE_MONO)|
- (1 << V4L2_TUNER_MODE_STEREO)|
- (1 << V4L2_TUNER_MODE_LANG1)|
- (1 << V4L2_TUNER_MODE_LANG2)),
- control_values_audiomode),
- },{
- .desc = "Video Standards Available Mask",
- .name = "video_standard_mask_available",
- .internal_id = PVR2_CID_STDAVAIL,
- .skip_init = !0,
- .get_value = ctrl_stdavail_get,
- .set_value = ctrl_stdavail_set,
- .val_to_sym = ctrl_std_val_to_sym,
- .sym_to_val = ctrl_std_sym_to_val,
- .type = pvr2_ctl_bitmask,
- },{
- .desc = "Video Standards In Use Mask",
- .name = "video_standard_mask_active",
- .internal_id = PVR2_CID_STDCUR,
- .skip_init = !0,
- .get_value = ctrl_stdcur_get,
- .set_value = ctrl_stdcur_set,
- .is_dirty = ctrl_stdcur_is_dirty,
- .clear_dirty = ctrl_stdcur_clear_dirty,
- .val_to_sym = ctrl_std_val_to_sym,
- .sym_to_val = ctrl_std_sym_to_val,
- .type = pvr2_ctl_bitmask,
- },{
- .desc = "Video Standards Detected Mask",
- .name = "video_standard_mask_detected",
- .internal_id = PVR2_CID_STDDETECT,
- .skip_init = !0,
- .get_value = ctrl_stddetect_get,
- .val_to_sym = ctrl_std_val_to_sym,
- .sym_to_val = ctrl_std_sym_to_val,
- .type = pvr2_ctl_bitmask,
- }
-};
-
-#define CTRLDEF_COUNT ARRAY_SIZE(control_defs)
-
-
-const char *pvr2_config_get_name(enum pvr2_config cfg)
-{
- switch (cfg) {
- case pvr2_config_empty: return "empty";
- case pvr2_config_mpeg: return "mpeg";
- case pvr2_config_vbi: return "vbi";
- case pvr2_config_pcm: return "pcm";
- case pvr2_config_rawvideo: return "raw video";
- }
- return "<unknown>";
-}
-
-
-struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw)
-{
- return hdw->usb_dev;
-}
-
-
-unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
-{
- return hdw->serial_number;
-}
-
-
-const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *hdw)
-{
- return hdw->bus_info;
-}
-
-
-const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *hdw)
-{
- return hdw->identifier;
-}
-
-
-unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
-{
- return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
-}
-
-/* Set the currently tuned frequency and account for all possible
- driver-core side effects of this action. */
-static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *hdw,unsigned long val)
-{
- if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
- if (hdw->freqSelector) {
- /* Swing over to radio frequency selection */
- hdw->freqSelector = 0;
- hdw->freqDirty = !0;
- }
- if (hdw->freqValRadio != val) {
- hdw->freqValRadio = val;
- hdw->freqSlotRadio = 0;
- hdw->freqDirty = !0;
- }
- } else {
- if (!(hdw->freqSelector)) {
- /* Swing over to television frequency selection */
- hdw->freqSelector = 1;
- hdw->freqDirty = !0;
- }
- if (hdw->freqValTelevision != val) {
- hdw->freqValTelevision = val;
- hdw->freqSlotTelevision = 0;
- hdw->freqDirty = !0;
- }
- }
-}
-
-int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw)
-{
- return hdw->unit_number;
-}
-
-
-/* Attempt to locate one of the given set of files. Messages are logged
- appropriate to what has been found. The return value will be 0 or
- greater on success (it will be the index of the file name found) and
- fw_entry will be filled in. Otherwise a negative error is returned on
- failure. If the return value is -ENOENT then no viable firmware file
- could be located. */
-static int pvr2_locate_firmware(struct pvr2_hdw *hdw,
- const struct firmware **fw_entry,
- const char *fwtypename,
- unsigned int fwcount,
- const char *fwnames[])
-{
- unsigned int idx;
- int ret = -EINVAL;
- for (idx = 0; idx < fwcount; idx++) {
- ret = request_firmware(fw_entry,
- fwnames[idx],
- &hdw->usb_dev->dev);
- if (!ret) {
- trace_firmware("Located %s firmware: %s;"
- " uploading...",
- fwtypename,
- fwnames[idx]);
- return idx;
- }
- if (ret == -ENOENT) continue;
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "request_firmware fatal error with code=%d",ret);
- return ret;
- }
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "***WARNING***"
- " Device %s firmware"
- " seems to be missing.",
- fwtypename);
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Did you install the pvrusb2 firmware files"
- " in their proper location?");
- if (fwcount == 1) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "request_firmware unable to locate %s file %s",
- fwtypename,fwnames[0]);
- } else {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "request_firmware unable to locate"
- " one of the following %s files:",
- fwtypename);
- for (idx = 0; idx < fwcount; idx++) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "request_firmware: Failed to find %s",
- fwnames[idx]);
- }
- }
- return ret;
-}
-
-
-/*
- * pvr2_upload_firmware1().
- *
- * Send the 8051 firmware to the device. After the upload, arrange for
- * device to re-enumerate.
- *
- * NOTE : the pointer to the firmware data given by request_firmware()
- * is not suitable for an usb transaction.
- *
- */
-static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
-{
- const struct firmware *fw_entry = NULL;
- void *fw_ptr;
- unsigned int pipe;
- unsigned int fwsize;
- int ret;
- u16 address;
-
- if (!hdw->hdw_desc->fx2_firmware.cnt) {
- hdw->fw1_state = FW1_STATE_OK;
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Connected device type defines"
- " no firmware to upload; ignoring firmware");
- return -ENOTTY;
- }
-
- hdw->fw1_state = FW1_STATE_FAILED; // default result
-
- trace_firmware("pvr2_upload_firmware1");
-
- ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller",
- hdw->hdw_desc->fx2_firmware.cnt,
- hdw->hdw_desc->fx2_firmware.lst);
- if (ret < 0) {
- if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING;
- return ret;
- }
-
- usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
-
- pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
- fwsize = fw_entry->size;
-
- if ((fwsize != 0x2000) &&
- (!(hdw->hdw_desc->flag_fx2_16kb && (fwsize == 0x4000)))) {
- if (hdw->hdw_desc->flag_fx2_16kb) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Wrong fx2 firmware size"
- " (expected 8192 or 16384, got %u)",
- fwsize);
- } else {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Wrong fx2 firmware size"
- " (expected 8192, got %u)",
- fwsize);
- }
- release_firmware(fw_entry);
- return -ENOMEM;
- }
-
- fw_ptr = kmalloc(0x800, GFP_KERNEL);
- if (fw_ptr == NULL){
- release_firmware(fw_entry);
- return -ENOMEM;
- }
-
- /* We have to hold the CPU during firmware upload. */
- pvr2_hdw_cpureset_assert(hdw,1);
-
- /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes
- chunk. */
-
- ret = 0;
- for (address = 0; address < fwsize; address += 0x800) {
- memcpy(fw_ptr, fw_entry->data + address, 0x800);
- ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
- 0, fw_ptr, 0x800, HZ);
- }
-
- trace_firmware("Upload done, releasing device's CPU");
-
- /* Now release the CPU. It will disconnect and reconnect later. */
- pvr2_hdw_cpureset_assert(hdw,0);
-
- kfree(fw_ptr);
- release_firmware(fw_entry);
-
- trace_firmware("Upload done (%d bytes sent)",ret);
-
- /* We should have written fwsize bytes */
- if (ret == fwsize) {
- hdw->fw1_state = FW1_STATE_RELOAD;
- return 0;
- }
-
- return -EIO;
-}
-
-
-/*
- * pvr2_upload_firmware2()
- *
- * This uploads encoder firmware on endpoint 2.
- *
- */
-
-int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
-{
- const struct firmware *fw_entry = NULL;
- void *fw_ptr;
- unsigned int pipe, fw_len, fw_done, bcnt, icnt;
- int actual_length;
- int ret = 0;
- int fwidx;
- static const char *fw_files[] = {
- CX2341X_FIRM_ENC_FILENAME,
- };
-
- if (hdw->hdw_desc->flag_skip_cx23416_firmware) {
- return 0;
- }
-
- trace_firmware("pvr2_upload_firmware2");
-
- ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder",
- ARRAY_SIZE(fw_files), fw_files);
- if (ret < 0) return ret;
- fwidx = ret;
- ret = 0;
- /* Since we're about to completely reinitialize the encoder,
- invalidate our cached copy of its configuration state. Next
- time we configure the encoder, then we'll fully configure it. */
- hdw->enc_cur_valid = 0;
-
- /* Encoder is about to be reset so note that as far as we're
- concerned now, the encoder has never been run. */
- del_timer_sync(&hdw->encoder_run_timer);
- if (hdw->state_encoder_runok) {
- hdw->state_encoder_runok = 0;
- trace_stbit("state_encoder_runok",hdw->state_encoder_runok);
- }
-
- /* First prepare firmware loading */
- ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
- ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
- ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
- ret |= pvr2_hdw_cmd_deep_reset(hdw);
- ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/
- ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/
- ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
- ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/
- ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/
- ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/
- ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/
- ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/
- ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/
- ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/
- ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/
- ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
- ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_FWPOST1);
- ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16));
-
- if (ret) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "firmware2 upload prep failed, ret=%d",ret);
- release_firmware(fw_entry);
- goto done;
- }
-
- /* Now send firmware */
-
- fw_len = fw_entry->size;
-
- if (fw_len % sizeof(u32)) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "size of %s firmware"
- " must be a multiple of %zu bytes",
- fw_files[fwidx],sizeof(u32));
- release_firmware(fw_entry);
- ret = -EINVAL;
- goto done;
- }
-
- fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
- if (fw_ptr == NULL){
- release_firmware(fw_entry);
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "failed to allocate memory for firmware2 upload");
- ret = -ENOMEM;
- goto done;
- }
-
- pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
-
- fw_done = 0;
- for (fw_done = 0; fw_done < fw_len;) {
- bcnt = fw_len - fw_done;
- if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE;
- memcpy(fw_ptr, fw_entry->data + fw_done, bcnt);
- /* Usbsnoop log shows that we must swap bytes... */
- /* Some background info: The data being swapped here is a
- firmware image destined for the mpeg encoder chip that
- lives at the other end of a USB endpoint. The encoder
- chip always talks in 32 bit chunks and its storage is
- organized into 32 bit words. However from the file
- system to the encoder chip everything is purely a byte
- stream. The firmware file's contents are always 32 bit
- swapped from what the encoder expects. Thus the need
- always exists to swap the bytes regardless of the endian
- type of the host processor and therefore swab32() makes
- the most sense. */
- for (icnt = 0; icnt < bcnt/4 ; icnt++)
- ((u32 *)fw_ptr)[icnt] = swab32(((u32 *)fw_ptr)[icnt]);
-
- ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt,
- &actual_length, HZ);
- ret |= (actual_length != bcnt);
- if (ret) break;
- fw_done += bcnt;
- }
-
- trace_firmware("upload of %s : %i / %i ",
- fw_files[fwidx],fw_done,fw_len);
-
- kfree(fw_ptr);
- release_firmware(fw_entry);
-
- if (ret) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "firmware2 upload transfer failure");
- goto done;
- }
-
- /* Finish upload */
-
- ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
- ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
- ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16));
-
- if (ret) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "firmware2 upload post-proc failure");
- }
-
- done:
- if (hdw->hdw_desc->signal_routing_scheme ==
- PVR2_ROUTING_SCHEME_GOTVIEW) {
- /* Ensure that GPIO 11 is set to output for GOTVIEW
- hardware. */
- pvr2_hdw_gpio_chg_dir(hdw,(1 << 11),~0);
- }
- return ret;
-}
-
-
-static const char *pvr2_get_state_name(unsigned int st)
-{
- if (st < ARRAY_SIZE(pvr2_state_names)) {
- return pvr2_state_names[st];
- }
- return "???";
-}
-
-static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl)
-{
- /* Even though we really only care about the video decoder chip at
- this point, we'll broadcast stream on/off to all sub-devices
- anyway, just in case somebody else wants to hear the
- command... */
- pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 stream=%s",
- (enablefl ? "on" : "off"));
- v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_stream, enablefl);
- v4l2_device_call_all(&hdw->v4l2_dev, 0, audio, s_stream, enablefl);
- if (hdw->decoder_client_id) {
- /* We get here if the encoder has been noticed. Otherwise
- we'll issue a warning to the user (which should
- normally never happen). */
- return 0;
- }
- if (!hdw->flag_decoder_missed) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "WARNING: No decoder present");
- hdw->flag_decoder_missed = !0;
- trace_stbit("flag_decoder_missed",
- hdw->flag_decoder_missed);
- }
- return -EIO;
-}
-
-
-int pvr2_hdw_get_state(struct pvr2_hdw *hdw)
-{
- return hdw->master_state;
-}
-
-
-static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *hdw)
-{
- if (!hdw->flag_tripped) return 0;
- hdw->flag_tripped = 0;
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Clearing driver error statuss");
- return !0;
-}
-
-
-int pvr2_hdw_untrip(struct pvr2_hdw *hdw)
-{
- int fl;
- LOCK_TAKE(hdw->big_lock); do {
- fl = pvr2_hdw_untrip_unlocked(hdw);
- } while (0); LOCK_GIVE(hdw->big_lock);
- if (fl) pvr2_hdw_state_sched(hdw);
- return 0;
-}
-
-
-
-
-int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw)
-{
- return hdw->state_pipeline_req != 0;
-}
-
-
-int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag)
-{
- int ret,st;
- LOCK_TAKE(hdw->big_lock); do {
- pvr2_hdw_untrip_unlocked(hdw);
- if ((!enable_flag) != !(hdw->state_pipeline_req)) {
- hdw->state_pipeline_req = enable_flag != 0;
- pvr2_trace(PVR2_TRACE_START_STOP,
- "/*--TRACE_STREAM--*/ %s",
- enable_flag ? "enable" : "disable");
- }
- pvr2_hdw_state_sched(hdw);
- } while (0); LOCK_GIVE(hdw->big_lock);
- if ((ret = pvr2_hdw_wait(hdw,0)) < 0) return ret;
- if (enable_flag) {
- while ((st = hdw->master_state) != PVR2_STATE_RUN) {
- if (st != PVR2_STATE_READY) return -EIO;
- if ((ret = pvr2_hdw_wait(hdw,st)) < 0) return ret;
- }
- }
- return 0;
-}
-
-
-int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config)
-{
- int fl;
- LOCK_TAKE(hdw->big_lock);
- if ((fl = (hdw->desired_stream_type != config)) != 0) {
- hdw->desired_stream_type = config;
- hdw->state_pipeline_config = 0;
- trace_stbit("state_pipeline_config",
- hdw->state_pipeline_config);
- pvr2_hdw_state_sched(hdw);
- }
- LOCK_GIVE(hdw->big_lock);
- if (fl) return 0;
- return pvr2_hdw_wait(hdw,0);
-}
-
-
-static int get_default_tuner_type(struct pvr2_hdw *hdw)
-{
- int unit_number = hdw->unit_number;
- int tp = -1;
- if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
- tp = tuner[unit_number];
- }
- if (tp < 0) return -EINVAL;
- hdw->tuner_type = tp;
- hdw->tuner_updated = !0;
- return 0;
-}
-
-
-static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw)
-{
- int unit_number = hdw->unit_number;
- int tp = 0;
- if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
- tp = video_std[unit_number];
- if (tp) return tp;
- }
- return 0;
-}
-
-
-static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw)
-{
- int unit_number = hdw->unit_number;
- int tp = 0;
- if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
- tp = tolerance[unit_number];
- }
- return tp;
-}
-
-
-static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
-{
- /* Try a harmless request to fetch the eeprom's address over
- endpoint 1. See what happens. Only the full FX2 image can
- respond to this. If this probe fails then likely the FX2
- firmware needs be loaded. */
- int result;
- LOCK_TAKE(hdw->ctl_lock); do {
- hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
- result = pvr2_send_request_ex(hdw,HZ*1,!0,
- hdw->cmd_buffer,1,
- hdw->cmd_buffer,1);
- if (result < 0) break;
- } while(0); LOCK_GIVE(hdw->ctl_lock);
- if (result) {
- pvr2_trace(PVR2_TRACE_INIT,
- "Probe of device endpoint 1 result status %d",
- result);
- } else {
- pvr2_trace(PVR2_TRACE_INIT,
- "Probe of device endpoint 1 succeeded");
- }
- return result == 0;
-}
-
-struct pvr2_std_hack {
- v4l2_std_id pat; /* Pattern to match */
- v4l2_std_id msk; /* Which bits we care about */
- v4l2_std_id std; /* What additional standards or default to set */
-};
-
-/* This data structure labels specific combinations of standards from
- tveeprom that we'll try to recognize. If we recognize one, then assume
- a specified default standard to use. This is here because tveeprom only
- tells us about available standards not the intended default standard (if
- any) for the device in question. We guess the default based on what has
- been reported as available. Note that this is only for guessing a
- default - which can always be overridden explicitly - and if the user
- has otherwise named a default then that default will always be used in
- place of this table. */
-static const struct pvr2_std_hack std_eeprom_maps[] = {
- { /* PAL(B/G) */
- .pat = V4L2_STD_B|V4L2_STD_GH,
- .std = V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_PAL_G,
- },
- { /* NTSC(M) */
- .pat = V4L2_STD_MN,
- .std = V4L2_STD_NTSC_M,
- },
- { /* PAL(I) */
- .pat = V4L2_STD_PAL_I,
- .std = V4L2_STD_PAL_I,
- },
- { /* SECAM(L/L') */
- .pat = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC,
- .std = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC,
- },
- { /* PAL(D/D1/K) */
- .pat = V4L2_STD_DK,
- .std = V4L2_STD_PAL_D|V4L2_STD_PAL_D1|V4L2_STD_PAL_K,
- },
-};
-
-static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
-{
- char buf[40];
- unsigned int bcnt;
- v4l2_std_id std1,std2,std3;
-
- std1 = get_default_standard(hdw);
- std3 = std1 ? 0 : hdw->hdw_desc->default_std_mask;
-
- bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
- pvr2_trace(PVR2_TRACE_STD,
- "Supported video standard(s) reported available"
- " in hardware: %.*s",
- bcnt,buf);
-
- hdw->std_mask_avail = hdw->std_mask_eeprom;
-
- std2 = (std1|std3) & ~hdw->std_mask_avail;
- if (std2) {
- bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
- pvr2_trace(PVR2_TRACE_STD,
- "Expanding supported video standards"
- " to include: %.*s",
- bcnt,buf);
- hdw->std_mask_avail |= std2;
- }
-
- hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
-
- if (std1) {
- bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
- pvr2_trace(PVR2_TRACE_STD,
- "Initial video standard forced to %.*s",
- bcnt,buf);
- hdw->std_mask_cur = std1;
- hdw->std_dirty = !0;
- return;
- }
- if (std3) {
- bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std3);
- pvr2_trace(PVR2_TRACE_STD,
- "Initial video standard"
- " (determined by device type): %.*s",bcnt,buf);
- hdw->std_mask_cur = std3;
- hdw->std_dirty = !0;
- return;
- }
-
- {
- unsigned int idx;
- for (idx = 0; idx < ARRAY_SIZE(std_eeprom_maps); idx++) {
- if (std_eeprom_maps[idx].msk ?
- ((std_eeprom_maps[idx].pat ^
- hdw->std_mask_eeprom) &
- std_eeprom_maps[idx].msk) :
- (std_eeprom_maps[idx].pat !=
- hdw->std_mask_eeprom)) continue;
- bcnt = pvr2_std_id_to_str(buf,sizeof(buf),
- std_eeprom_maps[idx].std);
- pvr2_trace(PVR2_TRACE_STD,
- "Initial video standard guessed as %.*s",
- bcnt,buf);
- hdw->std_mask_cur = std_eeprom_maps[idx].std;
- hdw->std_dirty = !0;
- return;
- }
- }
-
-}
-
-
-static unsigned int pvr2_copy_i2c_addr_list(
- unsigned short *dst, const unsigned char *src,
- unsigned int dst_max)
-{
- unsigned int cnt = 0;
- if (!src) return 0;
- while (src[cnt] && (cnt + 1) < dst_max) {
- dst[cnt] = src[cnt];
- cnt++;
- }
- dst[cnt] = I2C_CLIENT_END;
- return cnt;
-}
-
-
-static void pvr2_hdw_cx25840_vbi_hack(struct pvr2_hdw *hdw)
-{
- /*
- Mike Isely <isely@pobox.com> 19-Nov-2006 - This bit of nuttiness
- for cx25840 causes that module to correctly set up its video
- scaling. This is really a problem in the cx25840 module itself,
- but we work around it here. The problem has not been seen in
- ivtv because there VBI is supported and set up. We don't do VBI
- here (at least not yet) and thus we never attempted to even set
- it up.
- */
- struct v4l2_format fmt;
- if (hdw->decoder_client_id != PVR2_CLIENT_ID_CX25840) {
- /* We're not using a cx25840 so don't enable the hack */
- return;
- }
-
- pvr2_trace(PVR2_TRACE_INIT,
- "Module ID %u:"
- " Executing cx25840 VBI hack",
- hdw->decoder_client_id);
- memset(&fmt, 0, sizeof(fmt));
- fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
- fmt.fmt.sliced.service_lines[0][21] = V4L2_SLICED_CAPTION_525;
- fmt.fmt.sliced.service_lines[1][21] = V4L2_SLICED_CAPTION_525;
- v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
- vbi, s_sliced_fmt, &fmt.fmt.sliced);
-}
-
-
-static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
- const struct pvr2_device_client_desc *cd)
-{
- const char *fname;
- unsigned char mid;
- struct v4l2_subdev *sd;
- unsigned int i2ccnt;
- const unsigned char *p;
- /* Arbitrary count - max # i2c addresses we will probe */
- unsigned short i2caddr[25];
-
- mid = cd->module_id;
- fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL;
- if (!fname) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Module ID %u for device %s has no name?"
- " The driver might have a configuration problem.",
- mid,
- hdw->hdw_desc->description);
- return -EINVAL;
- }
- pvr2_trace(PVR2_TRACE_INIT,
- "Module ID %u (%s) for device %s being loaded...",
- mid, fname,
- hdw->hdw_desc->description);
-
- i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, cd->i2c_address_list,
- ARRAY_SIZE(i2caddr));
- if (!i2ccnt && ((p = (mid < ARRAY_SIZE(module_i2c_addresses)) ?
- module_i2c_addresses[mid] : NULL) != NULL)) {
- /* Second chance: Try default i2c address list */
- i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, p,
- ARRAY_SIZE(i2caddr));
- if (i2ccnt) {
- pvr2_trace(PVR2_TRACE_INIT,
- "Module ID %u:"
- " Using default i2c address list",
- mid);
- }
- }
-
- if (!i2ccnt) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Module ID %u (%s) for device %s:"
- " No i2c addresses."
- " The driver might have a configuration problem.",
- mid, fname, hdw->hdw_desc->description);
- return -EINVAL;
- }
-
- if (i2ccnt == 1) {
- pvr2_trace(PVR2_TRACE_INIT,
- "Module ID %u:"
- " Setting up with specified i2c address 0x%x",
- mid, i2caddr[0]);
- sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
- fname, i2caddr[0], NULL);
- } else {
- pvr2_trace(PVR2_TRACE_INIT,
- "Module ID %u:"
- " Setting up with address probe list",
- mid);
- sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
- fname, 0, i2caddr);
- }
-
- if (!sd) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Module ID %u (%s) for device %s failed to load."
- " Possible missing sub-device kernel module or"
- " initialization failure within module.",
- mid, fname, hdw->hdw_desc->description);
- return -EIO;
- }
-
- /* Tag this sub-device instance with the module ID we know about.
- In other places we'll use that tag to determine if the instance
- requires special handling. */
- sd->grp_id = mid;
-
- pvr2_trace(PVR2_TRACE_INFO, "Attached sub-driver %s", fname);
-
-
- /* client-specific setup... */
- switch (mid) {
- case PVR2_CLIENT_ID_CX25840:
- case PVR2_CLIENT_ID_SAA7115:
- hdw->decoder_client_id = mid;
- break;
- default: break;
- }
-
- return 0;
-}
-
-
-static void pvr2_hdw_load_modules(struct pvr2_hdw *hdw)
-{
- unsigned int idx;
- const struct pvr2_string_table *cm;
- const struct pvr2_device_client_table *ct;
- int okFl = !0;
-
- cm = &hdw->hdw_desc->client_modules;
- for (idx = 0; idx < cm->cnt; idx++) {
- request_module(cm->lst[idx]);
- }
-
- ct = &hdw->hdw_desc->client_table;
- for (idx = 0; idx < ct->cnt; idx++) {
- if (pvr2_hdw_load_subdev(hdw, &ct->lst[idx]) < 0) okFl = 0;
- }
- if (!okFl) {
- hdw->flag_modulefail = !0;
- pvr2_hdw_render_useless(hdw);
- }
-}
-
-
-static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
-{
- int ret;
- unsigned int idx;
- struct pvr2_ctrl *cptr;
- int reloadFl = 0;
- if (hdw->hdw_desc->fx2_firmware.cnt) {
- if (!reloadFl) {
- reloadFl =
- (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
- == 0);
- if (reloadFl) {
- pvr2_trace(PVR2_TRACE_INIT,
- "USB endpoint config looks strange"
- "; possibly firmware needs to be"
- " loaded");
- }
- }
- if (!reloadFl) {
- reloadFl = !pvr2_hdw_check_firmware(hdw);
- if (reloadFl) {
- pvr2_trace(PVR2_TRACE_INIT,
- "Check for FX2 firmware failed"
- "; possibly firmware needs to be"
- " loaded");
- }
- }
- if (reloadFl) {
- if (pvr2_upload_firmware1(hdw) != 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Failure uploading firmware1");
- }
- return;
- }
- }
- hdw->fw1_state = FW1_STATE_OK;
-
- if (!pvr2_hdw_dev_ok(hdw)) return;
-
- hdw->force_dirty = !0;
-
- if (!hdw->hdw_desc->flag_no_powerup) {
- pvr2_hdw_cmd_powerup(hdw);
- if (!pvr2_hdw_dev_ok(hdw)) return;
- }
-
- /* Take the IR chip out of reset, if appropriate */
- if (hdw->ir_scheme_active == PVR2_IR_SCHEME_ZILOG) {
- pvr2_issue_simple_cmd(hdw,
- FX2CMD_HCW_ZILOG_RESET |
- (1 << 8) |
- ((0) << 16));
- }
-
- // This step MUST happen after the earlier powerup step.
- pvr2_i2c_core_init(hdw);
- if (!pvr2_hdw_dev_ok(hdw)) return;
-
- pvr2_hdw_load_modules(hdw);
- if (!pvr2_hdw_dev_ok(hdw)) return;
-
- v4l2_device_call_all(&hdw->v4l2_dev, 0, core, load_fw);
-
- for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
- cptr = hdw->controls + idx;
- if (cptr->info->skip_init) continue;
- if (!cptr->info->set_value) continue;
- cptr->info->set_value(cptr,~0,cptr->info->default_value);
- }
-
- pvr2_hdw_cx25840_vbi_hack(hdw);
-
- /* Set up special default values for the television and radio
- frequencies here. It's not really important what these defaults
- are, but I set them to something usable in the Chicago area just
- to make driver testing a little easier. */
-
- hdw->freqValTelevision = default_tv_freq;
- hdw->freqValRadio = default_radio_freq;
-
- // Do not use pvr2_reset_ctl_endpoints() here. It is not
- // thread-safe against the normal pvr2_send_request() mechanism.
- // (We should make it thread safe).
-
- if (hdw->hdw_desc->flag_has_hauppauge_rom) {
- ret = pvr2_hdw_get_eeprom_addr(hdw);
- if (!pvr2_hdw_dev_ok(hdw)) return;
- if (ret < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Unable to determine location of eeprom,"
- " skipping");
- } else {
- hdw->eeprom_addr = ret;
- pvr2_eeprom_analyze(hdw);
- if (!pvr2_hdw_dev_ok(hdw)) return;
- }
- } else {
- hdw->tuner_type = hdw->hdw_desc->default_tuner_type;
- hdw->tuner_updated = !0;
- hdw->std_mask_eeprom = V4L2_STD_ALL;
- }
-
- if (hdw->serial_number) {
- idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
- "sn-%lu", hdw->serial_number);
- } else if (hdw->unit_number >= 0) {
- idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
- "unit-%c",
- hdw->unit_number + 'a');
- } else {
- idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
- "unit-??");
- }
- hdw->identifier[idx] = 0;
-
- pvr2_hdw_setup_std(hdw);
-
- if (!get_default_tuner_type(hdw)) {
- pvr2_trace(PVR2_TRACE_INIT,
- "pvr2_hdw_setup: Tuner type overridden to %d",
- hdw->tuner_type);
- }
-
-
- if (!pvr2_hdw_dev_ok(hdw)) return;
-
- if (hdw->hdw_desc->signal_routing_scheme ==
- PVR2_ROUTING_SCHEME_GOTVIEW) {
- /* Ensure that GPIO 11 is set to output for GOTVIEW
- hardware. */
- pvr2_hdw_gpio_chg_dir(hdw,(1 << 11),~0);
- }
-
- pvr2_hdw_commit_setup(hdw);
-
- hdw->vid_stream = pvr2_stream_create();
- if (!pvr2_hdw_dev_ok(hdw)) return;
- pvr2_trace(PVR2_TRACE_INIT,
- "pvr2_hdw_setup: video stream is %p",hdw->vid_stream);
- if (hdw->vid_stream) {
- idx = get_default_error_tolerance(hdw);
- if (idx) {
- pvr2_trace(PVR2_TRACE_INIT,
- "pvr2_hdw_setup: video stream %p"
- " setting tolerance %u",
- hdw->vid_stream,idx);
- }
- pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev,
- PVR2_VID_ENDPOINT,idx);
- }
-
- if (!pvr2_hdw_dev_ok(hdw)) return;
-
- hdw->flag_init_ok = !0;
-
- pvr2_hdw_state_sched(hdw);
-}
-
-
-/* Set up the structure and attempt to put the device into a usable state.
- This can be a time-consuming operation, which is why it is not done
- internally as part of the create() step. */
-static void pvr2_hdw_setup(struct pvr2_hdw *hdw)
-{
- pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw);
- do {
- pvr2_hdw_setup_low(hdw);
- pvr2_trace(PVR2_TRACE_INIT,
- "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d",
- hdw,pvr2_hdw_dev_ok(hdw),hdw->flag_init_ok);
- if (pvr2_hdw_dev_ok(hdw)) {
- if (hdw->flag_init_ok) {
- pvr2_trace(
- PVR2_TRACE_INFO,
- "Device initialization"
- " completed successfully.");
- break;
- }
- if (hdw->fw1_state == FW1_STATE_RELOAD) {
- pvr2_trace(
- PVR2_TRACE_INFO,
- "Device microcontroller firmware"
- " (re)loaded; it should now reset"
- " and reconnect.");
- break;
- }
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Device initialization was not successful.");
- if (hdw->fw1_state == FW1_STATE_MISSING) {
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Giving up since device"
- " microcontroller firmware"
- " appears to be missing.");
- break;
- }
- }
- if (hdw->flag_modulefail) {
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "***WARNING*** pvrusb2 driver initialization"
- " failed due to the failure of one or more"
- " sub-device kernel modules.");
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "You need to resolve the failing condition"
- " before this driver can function. There"
- " should be some earlier messages giving more"
- " information about the problem.");
- break;
- }
- if (procreload) {
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Attempting pvrusb2 recovery by reloading"
- " primary firmware.");
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "If this works, device should disconnect"
- " and reconnect in a sane state.");
- hdw->fw1_state = FW1_STATE_UNKNOWN;
- pvr2_upload_firmware1(hdw);
- } else {
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "***WARNING*** pvrusb2 device hardware"
- " appears to be jammed"
- " and I can't clear it.");
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "You might need to power cycle"
- " the pvrusb2 device"
- " in order to recover.");
- }
- } while (0);
- pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw);
-}
-
-
-/* Perform second stage initialization. Set callback pointer first so that
- we can avoid a possible initialization race (if the kernel thread runs
- before the callback has been set). */
-int pvr2_hdw_initialize(struct pvr2_hdw *hdw,
- void (*callback_func)(void *),
- void *callback_data)
-{
- LOCK_TAKE(hdw->big_lock); do {
- if (hdw->flag_disconnected) {
- /* Handle a race here: If we're already
- disconnected by this point, then give up. If we
- get past this then we'll remain connected for
- the duration of initialization since the entire
- initialization sequence is now protected by the
- big_lock. */
- break;
- }
- hdw->state_data = callback_data;
- hdw->state_func = callback_func;
- pvr2_hdw_setup(hdw);
- } while (0); LOCK_GIVE(hdw->big_lock);
- return hdw->flag_init_ok;
-}
-
-
-/* Create, set up, and return a structure for interacting with the
- underlying hardware. */
-struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
- const struct usb_device_id *devid)
-{
- unsigned int idx,cnt1,cnt2,m;
- struct pvr2_hdw *hdw = NULL;
- int valid_std_mask;
- struct pvr2_ctrl *cptr;
- struct usb_device *usb_dev;
- const struct pvr2_device_desc *hdw_desc;
- __u8 ifnum;
- struct v4l2_queryctrl qctrl;
- struct pvr2_ctl_info *ciptr;
-
- usb_dev = interface_to_usbdev(intf);
-
- hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info);
-
- if (hdw_desc == NULL) {
- pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_create:"
- " No device description pointer,"
- " unable to continue.");
- pvr2_trace(PVR2_TRACE_INIT, "If you have a new device type,"
- " please contact Mike Isely <isely@pobox.com>"
- " to get it included in the driver\n");
- goto fail;
- }
-
- hdw = kzalloc(sizeof(*hdw),GFP_KERNEL);
- pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
- hdw,hdw_desc->description);
- pvr2_trace(PVR2_TRACE_INFO, "Hardware description: %s",
- hdw_desc->description);
- if (hdw_desc->flag_is_experimental) {
- pvr2_trace(PVR2_TRACE_INFO, "**********");
- pvr2_trace(PVR2_TRACE_INFO,
- "WARNING: Support for this device (%s) is"
- " experimental.", hdw_desc->description);
- pvr2_trace(PVR2_TRACE_INFO,
- "Important functionality might not be"
- " entirely working.");
- pvr2_trace(PVR2_TRACE_INFO,
- "Please consider contacting the driver author to"
- " help with further stabilization of the driver.");
- pvr2_trace(PVR2_TRACE_INFO, "**********");
- }
- if (!hdw) goto fail;
-
- init_timer(&hdw->quiescent_timer);
- hdw->quiescent_timer.data = (unsigned long)hdw;
- hdw->quiescent_timer.function = pvr2_hdw_quiescent_timeout;
-
- init_timer(&hdw->decoder_stabilization_timer);
- hdw->decoder_stabilization_timer.data = (unsigned long)hdw;
- hdw->decoder_stabilization_timer.function =
- pvr2_hdw_decoder_stabilization_timeout;
-
- init_timer(&hdw->encoder_wait_timer);
- hdw->encoder_wait_timer.data = (unsigned long)hdw;
- hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout;
-
- init_timer(&hdw->encoder_run_timer);
- hdw->encoder_run_timer.data = (unsigned long)hdw;
- hdw->encoder_run_timer.function = pvr2_hdw_encoder_run_timeout;
-
- hdw->master_state = PVR2_STATE_DEAD;
-
- init_waitqueue_head(&hdw->state_wait_data);
-
- hdw->tuner_signal_stale = !0;
- cx2341x_fill_defaults(&hdw->enc_ctl_state);
-
- /* Calculate which inputs are OK */
- m = 0;
- if (hdw_desc->flag_has_analogtuner) m |= 1 << PVR2_CVAL_INPUT_TV;
- if (hdw_desc->digital_control_scheme != PVR2_DIGITAL_SCHEME_NONE) {
- m |= 1 << PVR2_CVAL_INPUT_DTV;
- }
- if (hdw_desc->flag_has_svideo) m |= 1 << PVR2_CVAL_INPUT_SVIDEO;
- if (hdw_desc->flag_has_composite) m |= 1 << PVR2_CVAL_INPUT_COMPOSITE;
- if (hdw_desc->flag_has_fmradio) m |= 1 << PVR2_CVAL_INPUT_RADIO;
- hdw->input_avail_mask = m;
- hdw->input_allowed_mask = hdw->input_avail_mask;
-
- /* If not a hybrid device, pathway_state never changes. So
- initialize it here to what it should forever be. */
- if (!(hdw->input_avail_mask & (1 << PVR2_CVAL_INPUT_DTV))) {
- hdw->pathway_state = PVR2_PATHWAY_ANALOG;
- } else if (!(hdw->input_avail_mask & (1 << PVR2_CVAL_INPUT_TV))) {
- hdw->pathway_state = PVR2_PATHWAY_DIGITAL;
- }
-
- hdw->control_cnt = CTRLDEF_COUNT;
- hdw->control_cnt += MPEGDEF_COUNT;
- hdw->controls = kzalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt,
- GFP_KERNEL);
- if (!hdw->controls) goto fail;
- hdw->hdw_desc = hdw_desc;
- hdw->ir_scheme_active = hdw->hdw_desc->ir_scheme;
- for (idx = 0; idx < hdw->control_cnt; idx++) {
- cptr = hdw->controls + idx;
- cptr->hdw = hdw;
- }
- for (idx = 0; idx < 32; idx++) {
- hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx];
- }
- for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
- cptr = hdw->controls + idx;
- cptr->info = control_defs+idx;
- }
-
- /* Ensure that default input choice is a valid one. */
- m = hdw->input_avail_mask;
- if (m) for (idx = 0; idx < (sizeof(m) << 3); idx++) {
- if (!((1 << idx) & m)) continue;
- hdw->input_val = idx;
- break;
- }
-
- /* Define and configure additional controls from cx2341x module. */
- hdw->mpeg_ctrl_info = kcalloc(MPEGDEF_COUNT,
- sizeof(*(hdw->mpeg_ctrl_info)),
- GFP_KERNEL);
- if (!hdw->mpeg_ctrl_info) goto fail;
- for (idx = 0; idx < MPEGDEF_COUNT; idx++) {
- cptr = hdw->controls + idx + CTRLDEF_COUNT;
- ciptr = &(hdw->mpeg_ctrl_info[idx].info);
- ciptr->desc = hdw->mpeg_ctrl_info[idx].desc;
- ciptr->name = mpeg_ids[idx].strid;
- ciptr->v4l_id = mpeg_ids[idx].id;
- ciptr->skip_init = !0;
- ciptr->get_value = ctrl_cx2341x_get;
- ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags;
- ciptr->is_dirty = ctrl_cx2341x_is_dirty;
- if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty;
- qctrl.id = ciptr->v4l_id;
- cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl);
- if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) {
- ciptr->set_value = ctrl_cx2341x_set;
- }
- strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name,
- PVR2_CTLD_INFO_DESC_SIZE);
- hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0;
- ciptr->default_value = qctrl.default_value;
- switch (qctrl.type) {
- default:
- case V4L2_CTRL_TYPE_INTEGER:
- ciptr->type = pvr2_ctl_int;
- ciptr->def.type_int.min_value = qctrl.minimum;
- ciptr->def.type_int.max_value = qctrl.maximum;
- break;
- case V4L2_CTRL_TYPE_BOOLEAN:
- ciptr->type = pvr2_ctl_bool;
- break;
- case V4L2_CTRL_TYPE_MENU:
- ciptr->type = pvr2_ctl_enum;
- ciptr->def.type_enum.value_names =
- cx2341x_ctrl_get_menu(&hdw->enc_ctl_state,
- ciptr->v4l_id);
- for (cnt1 = 0;
- ciptr->def.type_enum.value_names[cnt1] != NULL;
- cnt1++) { }
- ciptr->def.type_enum.count = cnt1;
- break;
- }
- cptr->info = ciptr;
- }
-
- // Initialize control data regarding video standard masks
- valid_std_mask = pvr2_std_get_usable();
- for (idx = 0; idx < 32; idx++) {
- if (!(valid_std_mask & (1 << idx))) continue;
- cnt1 = pvr2_std_id_to_str(
- hdw->std_mask_names[idx],
- sizeof(hdw->std_mask_names[idx])-1,
- 1 << idx);
- hdw->std_mask_names[idx][cnt1] = 0;
- }
- cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
- if (cptr) {
- memcpy(&hdw->std_info_avail,cptr->info,
- sizeof(hdw->std_info_avail));
- cptr->info = &hdw->std_info_avail;
- hdw->std_info_avail.def.type_bitmask.bit_names =
- hdw->std_mask_ptrs;
- hdw->std_info_avail.def.type_bitmask.valid_bits =
- valid_std_mask;
- }
- cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR);
- if (cptr) {
- memcpy(&hdw->std_info_cur,cptr->info,
- sizeof(hdw->std_info_cur));
- cptr->info = &hdw->std_info_cur;
- hdw->std_info_cur.def.type_bitmask.bit_names =
- hdw->std_mask_ptrs;
- hdw->std_info_cur.def.type_bitmask.valid_bits =
- valid_std_mask;
- }
- cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDDETECT);
- if (cptr) {
- memcpy(&hdw->std_info_detect,cptr->info,
- sizeof(hdw->std_info_detect));
- cptr->info = &hdw->std_info_detect;
- hdw->std_info_detect.def.type_bitmask.bit_names =
- hdw->std_mask_ptrs;
- hdw->std_info_detect.def.type_bitmask.valid_bits =
- valid_std_mask;
- }
-
- hdw->cropcap_stale = !0;
- hdw->eeprom_addr = -1;
- hdw->unit_number = -1;
- hdw->v4l_minor_number_video = -1;
- hdw->v4l_minor_number_vbi = -1;
- hdw->v4l_minor_number_radio = -1;
- hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
- if (!hdw->ctl_write_buffer) goto fail;
- hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
- if (!hdw->ctl_read_buffer) goto fail;
- hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL);
- if (!hdw->ctl_write_urb) goto fail;
- hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
- if (!hdw->ctl_read_urb) goto fail;
-
- if (v4l2_device_register(&intf->dev, &hdw->v4l2_dev) != 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Error registering with v4l core, giving up");
- goto fail;
- }
- mutex_lock(&pvr2_unit_mtx); do {
- for (idx = 0; idx < PVR_NUM; idx++) {
- if (unit_pointers[idx]) continue;
- hdw->unit_number = idx;
- unit_pointers[idx] = hdw;
- break;
- }
- } while (0); mutex_unlock(&pvr2_unit_mtx);
-
- cnt1 = 0;
- cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
- cnt1 += cnt2;
- if (hdw->unit_number >= 0) {
- cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c",
- ('a' + hdw->unit_number));
- cnt1 += cnt2;
- }
- if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1;
- hdw->name[cnt1] = 0;
-
- hdw->workqueue = create_singlethread_workqueue(hdw->name);
- INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll);
-
- pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
- hdw->unit_number,hdw->name);
-
- hdw->tuner_type = -1;
- hdw->flag_ok = !0;
-
- hdw->usb_intf = intf;
- hdw->usb_dev = usb_dev;
-
- usb_make_path(hdw->usb_dev, hdw->bus_info, sizeof(hdw->bus_info));
-
- ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
- usb_set_interface(hdw->usb_dev,ifnum,0);
-
- mutex_init(&hdw->ctl_lock_mutex);
- mutex_init(&hdw->big_lock_mutex);
-
- return hdw;
- fail:
- if (hdw) {
- del_timer_sync(&hdw->quiescent_timer);
- del_timer_sync(&hdw->decoder_stabilization_timer);
- del_timer_sync(&hdw->encoder_run_timer);
- del_timer_sync(&hdw->encoder_wait_timer);
- if (hdw->workqueue) {
- flush_workqueue(hdw->workqueue);
- destroy_workqueue(hdw->workqueue);
- hdw->workqueue = NULL;
- }
- usb_free_urb(hdw->ctl_read_urb);
- usb_free_urb(hdw->ctl_write_urb);
- kfree(hdw->ctl_read_buffer);
- kfree(hdw->ctl_write_buffer);
- kfree(hdw->controls);
- kfree(hdw->mpeg_ctrl_info);
- kfree(hdw);
- }
- return NULL;
-}
-
-
-/* Remove _all_ associations between this driver and the underlying USB
- layer. */
-static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
-{
- if (hdw->flag_disconnected) return;
- pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw);
- if (hdw->ctl_read_urb) {
- usb_kill_urb(hdw->ctl_read_urb);
- usb_free_urb(hdw->ctl_read_urb);
- hdw->ctl_read_urb = NULL;
- }
- if (hdw->ctl_write_urb) {
- usb_kill_urb(hdw->ctl_write_urb);
- usb_free_urb(hdw->ctl_write_urb);
- hdw->ctl_write_urb = NULL;
- }
- if (hdw->ctl_read_buffer) {
- kfree(hdw->ctl_read_buffer);
- hdw->ctl_read_buffer = NULL;
- }
- if (hdw->ctl_write_buffer) {
- kfree(hdw->ctl_write_buffer);
- hdw->ctl_write_buffer = NULL;
- }
- hdw->flag_disconnected = !0;
- /* If we don't do this, then there will be a dangling struct device
- reference to our disappearing device persisting inside the V4L
- core... */
- v4l2_device_disconnect(&hdw->v4l2_dev);
- hdw->usb_dev = NULL;
- hdw->usb_intf = NULL;
- pvr2_hdw_render_useless(hdw);
-}
-
-
-/* Destroy hardware interaction structure */
-void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
-{
- if (!hdw) return;
- pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
- if (hdw->workqueue) {
- flush_workqueue(hdw->workqueue);
- destroy_workqueue(hdw->workqueue);
- hdw->workqueue = NULL;
- }
- del_timer_sync(&hdw->quiescent_timer);
- del_timer_sync(&hdw->decoder_stabilization_timer);
- del_timer_sync(&hdw->encoder_run_timer);
- del_timer_sync(&hdw->encoder_wait_timer);
- if (hdw->fw_buffer) {
- kfree(hdw->fw_buffer);
- hdw->fw_buffer = NULL;
- }
- if (hdw->vid_stream) {
- pvr2_stream_destroy(hdw->vid_stream);
- hdw->vid_stream = NULL;
- }
- pvr2_i2c_core_done(hdw);
- v4l2_device_unregister(&hdw->v4l2_dev);
- pvr2_hdw_remove_usb_stuff(hdw);
- mutex_lock(&pvr2_unit_mtx); do {
- if ((hdw->unit_number >= 0) &&
- (hdw->unit_number < PVR_NUM) &&
- (unit_pointers[hdw->unit_number] == hdw)) {
- unit_pointers[hdw->unit_number] = NULL;
- }
- } while (0); mutex_unlock(&pvr2_unit_mtx);
- kfree(hdw->controls);
- kfree(hdw->mpeg_ctrl_info);
- kfree(hdw);
-}
-
-
-int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw)
-{
- return (hdw && hdw->flag_ok);
-}
-
-
-/* Called when hardware has been unplugged */
-void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
-{
- pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
- LOCK_TAKE(hdw->big_lock);
- LOCK_TAKE(hdw->ctl_lock);
- pvr2_hdw_remove_usb_stuff(hdw);
- LOCK_GIVE(hdw->ctl_lock);
- LOCK_GIVE(hdw->big_lock);
-}
-
-
-/* Get the number of defined controls */
-unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
-{
- return hdw->control_cnt;
-}
-
-
-/* Retrieve a control handle given its index (0..count-1) */
-struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
- unsigned int idx)
-{
- if (idx >= hdw->control_cnt) return NULL;
- return hdw->controls + idx;
-}
-
-
-/* Retrieve a control handle given its index (0..count-1) */
-struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw,
- unsigned int ctl_id)
-{
- struct pvr2_ctrl *cptr;
- unsigned int idx;
- int i;
-
- /* This could be made a lot more efficient, but for now... */
- for (idx = 0; idx < hdw->control_cnt; idx++) {
- cptr = hdw->controls + idx;
- i = cptr->info->internal_id;
- if (i && (i == ctl_id)) return cptr;
- }
- return NULL;
-}
-
-
-/* Given a V4L ID, retrieve the control structure associated with it. */
-struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id)
-{
- struct pvr2_ctrl *cptr;
- unsigned int idx;
- int i;
-
- /* This could be made a lot more efficient, but for now... */
- for (idx = 0; idx < hdw->control_cnt; idx++) {
- cptr = hdw->controls + idx;
- i = cptr->info->v4l_id;
- if (i && (i == ctl_id)) return cptr;
- }
- return NULL;
-}
-
-
-/* Given a V4L ID for its immediate predecessor, retrieve the control
- structure associated with it. */
-struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw,
- unsigned int ctl_id)
-{
- struct pvr2_ctrl *cptr,*cp2;
- unsigned int idx;
- int i;
-
- /* This could be made a lot more efficient, but for now... */
- cp2 = NULL;
- for (idx = 0; idx < hdw->control_cnt; idx++) {
- cptr = hdw->controls + idx;
- i = cptr->info->v4l_id;
- if (!i) continue;
- if (i <= ctl_id) continue;
- if (cp2 && (cp2->info->v4l_id < i)) continue;
- cp2 = cptr;
- }
- return cp2;
- return NULL;
-}
-
-
-static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
-{
- switch (tp) {
- case pvr2_ctl_int: return "integer";
- case pvr2_ctl_enum: return "enum";
- case pvr2_ctl_bool: return "boolean";
- case pvr2_ctl_bitmask: return "bitmask";
- }
- return "";
-}
-
-
-static void pvr2_subdev_set_control(struct pvr2_hdw *hdw, int id,
- const char *name, int val)
-{
- struct v4l2_control ctrl;
- pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 %s=%d", name, val);
- memset(&ctrl, 0, sizeof(ctrl));
- ctrl.id = id;
- ctrl.value = val;
- v4l2_device_call_all(&hdw->v4l2_dev, 0, core, s_ctrl, &ctrl);
-}
-
-#define PVR2_SUBDEV_SET_CONTROL(hdw, id, lab) \
- if ((hdw)->lab##_dirty || (hdw)->force_dirty) { \
- pvr2_subdev_set_control(hdw, id, #lab, (hdw)->lab##_val); \
- }
-
-v4l2_std_id pvr2_hdw_get_detected_std(struct pvr2_hdw *hdw)
-{
- v4l2_std_id std;
- std = (v4l2_std_id)hdw->std_mask_avail;
- v4l2_device_call_all(&hdw->v4l2_dev, 0,
- video, querystd, &std);
- return std;
-}
-
-/* Execute whatever commands are required to update the state of all the
- sub-devices so that they match our current control values. */
-static void pvr2_subdev_update(struct pvr2_hdw *hdw)
-{
- struct v4l2_subdev *sd;
- unsigned int id;
- pvr2_subdev_update_func fp;
-
- pvr2_trace(PVR2_TRACE_CHIPS, "subdev update...");
-
- if (hdw->tuner_updated || hdw->force_dirty) {
- struct tuner_setup setup;
- pvr2_trace(PVR2_TRACE_CHIPS, "subdev tuner set_type(%d)",
- hdw->tuner_type);
- if (((int)(hdw->tuner_type)) >= 0) {
- memset(&setup, 0, sizeof(setup));
- setup.addr = ADDR_UNSET;
- setup.type = hdw->tuner_type;
- setup.mode_mask = T_RADIO | T_ANALOG_TV;
- v4l2_device_call_all(&hdw->v4l2_dev, 0,
- tuner, s_type_addr, &setup);
- }
- }
-
- if (hdw->input_dirty || hdw->std_dirty || hdw->force_dirty) {
- pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_standard");
- if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
- v4l2_device_call_all(&hdw->v4l2_dev, 0,
- tuner, s_radio);
- } else {
- v4l2_std_id vs;
- vs = hdw->std_mask_cur;
- v4l2_device_call_all(&hdw->v4l2_dev, 0,
- core, s_std, vs);
- pvr2_hdw_cx25840_vbi_hack(hdw);
- }
- hdw->tuner_signal_stale = !0;
- hdw->cropcap_stale = !0;
- }
-
- PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_BRIGHTNESS, brightness);
- PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_CONTRAST, contrast);
- PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_SATURATION, saturation);
- PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_HUE, hue);
- PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_MUTE, mute);
- PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_VOLUME, volume);
- PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BALANCE, balance);
- PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BASS, bass);
- PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_TREBLE, treble);
-
- if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) {
- struct v4l2_tuner vt;
- memset(&vt, 0, sizeof(vt));
- vt.type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
- V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- vt.audmode = hdw->audiomode_val;
- v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt);
- }
-
- if (hdw->freqDirty || hdw->force_dirty) {
- unsigned long fv;
- struct v4l2_frequency freq;
- fv = pvr2_hdw_get_cur_freq(hdw);
- pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_freq(%lu)", fv);
- if (hdw->tuner_signal_stale) pvr2_hdw_status_poll(hdw);
- memset(&freq, 0, sizeof(freq));
- if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
- /* ((fv * 1000) / 62500) */
- freq.frequency = (fv * 2) / 125;
- } else {
- freq.frequency = fv / 62500;
- }
- /* tuner-core currently doesn't seem to care about this, but
- let's set it anyway for completeness. */
- if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
- freq.type = V4L2_TUNER_RADIO;
- } else {
- freq.type = V4L2_TUNER_ANALOG_TV;
- }
- freq.tuner = 0;
- v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner,
- s_frequency, &freq);
- }
-
- if (hdw->res_hor_dirty || hdw->res_ver_dirty || hdw->force_dirty) {
- struct v4l2_mbus_framefmt fmt;
- memset(&fmt, 0, sizeof(fmt));
- fmt.width = hdw->res_hor_val;
- fmt.height = hdw->res_ver_val;
- fmt.code = V4L2_MBUS_FMT_FIXED;
- pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)",
- fmt.width, fmt.height);
- v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_mbus_fmt, &fmt);
- }
-
- if (hdw->srate_dirty || hdw->force_dirty) {
- u32 val;
- pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_audio %d",
- hdw->srate_val);
- switch (hdw->srate_val) {
- default:
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
- val = 48000;
- break;
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
- val = 44100;
- break;
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
- val = 32000;
- break;
- }
- v4l2_device_call_all(&hdw->v4l2_dev, 0,
- audio, s_clock_freq, val);
- }
-
- /* Unable to set crop parameters; there is apparently no equivalent
- for VIDIOC_S_CROP */
-
- v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
- id = sd->grp_id;
- if (id >= ARRAY_SIZE(pvr2_module_update_functions)) continue;
- fp = pvr2_module_update_functions[id];
- if (!fp) continue;
- (*fp)(hdw, sd);
- }
-
- if (hdw->tuner_signal_stale || hdw->cropcap_stale) {
- pvr2_hdw_status_poll(hdw);
- }
-}
-
-
-/* Figure out if we need to commit control changes. If so, mark internal
- state flags to indicate this fact and return true. Otherwise do nothing
- else and return false. */
-static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw)
-{
- unsigned int idx;
- struct pvr2_ctrl *cptr;
- int value;
- int commit_flag = hdw->force_dirty;
- char buf[100];
- unsigned int bcnt,ccnt;
-
- for (idx = 0; idx < hdw->control_cnt; idx++) {
- cptr = hdw->controls + idx;
- if (!cptr->info->is_dirty) continue;
- if (!cptr->info->is_dirty(cptr)) continue;
- commit_flag = !0;
-
- if (!(pvrusb2_debug & PVR2_TRACE_CTL)) continue;
- bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ",
- cptr->info->name);
- value = 0;
- cptr->info->get_value(cptr,&value);
- pvr2_ctrl_value_to_sym_internal(cptr,~0,value,
- buf+bcnt,
- sizeof(buf)-bcnt,&ccnt);
- bcnt += ccnt;
- bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>",
- get_ctrl_typename(cptr->info->type));
- pvr2_trace(PVR2_TRACE_CTL,
- "/*--TRACE_COMMIT--*/ %.*s",
- bcnt,buf);
- }
-
- if (!commit_flag) {
- /* Nothing has changed */
- return 0;
- }
-
- hdw->state_pipeline_config = 0;
- trace_stbit("state_pipeline_config",hdw->state_pipeline_config);
- pvr2_hdw_state_sched(hdw);
-
- return !0;
-}
-
-
-/* Perform all operations needed to commit all control changes. This must
- be performed in synchronization with the pipeline state and is thus
- expected to be called as part of the driver's worker thread. Return
- true if commit successful, otherwise return false to indicate that
- commit isn't possible at this time. */
-static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
-{
- unsigned int idx;
- struct pvr2_ctrl *cptr;
- int disruptive_change;
-
- if (hdw->input_dirty && hdw->state_pathway_ok &&
- (((hdw->input_val == PVR2_CVAL_INPUT_DTV) ?
- PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG) !=
- hdw->pathway_state)) {
- /* Change of mode being asked for... */
- hdw->state_pathway_ok = 0;
- trace_stbit("state_pathway_ok", hdw->state_pathway_ok);
- }
- if (!hdw->state_pathway_ok) {
- /* Can't commit anything until pathway is ok. */
- return 0;
- }
-
- /* Handle some required side effects when the video standard is
- changed.... */
- if (hdw->std_dirty) {
- int nvres;
- int gop_size;
- if (hdw->std_mask_cur & V4L2_STD_525_60) {
- nvres = 480;
- gop_size = 15;
- } else {
- nvres = 576;
- gop_size = 12;
- }
- /* Rewrite the vertical resolution to be appropriate to the
- video standard that has been selected. */
- if (nvres != hdw->res_ver_val) {
- hdw->res_ver_val = nvres;
- hdw->res_ver_dirty = !0;
- }
- /* Rewrite the GOP size to be appropriate to the video
- standard that has been selected. */
- if (gop_size != hdw->enc_ctl_state.video_gop_size) {
- struct v4l2_ext_controls cs;
- struct v4l2_ext_control c1;
- memset(&cs, 0, sizeof(cs));
- memset(&c1, 0, sizeof(c1));
- cs.controls = &c1;
- cs.count = 1;
- c1.id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
- c1.value = gop_size;
- cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,
- VIDIOC_S_EXT_CTRLS);
- }
- }
-
- /* The broadcast decoder can only scale down, so if
- * res_*_dirty && crop window < output format ==> enlarge crop.
- *
- * The mpeg encoder receives fields of res_hor_val dots and
- * res_ver_val halflines. Limits: hor<=720, ver<=576.
- */
- if (hdw->res_hor_dirty && hdw->cropw_val < hdw->res_hor_val) {
- hdw->cropw_val = hdw->res_hor_val;
- hdw->cropw_dirty = !0;
- } else if (hdw->cropw_dirty) {
- hdw->res_hor_dirty = !0; /* must rescale */
- hdw->res_hor_val = min(720, hdw->cropw_val);
- }
- if (hdw->res_ver_dirty && hdw->croph_val < hdw->res_ver_val) {
- hdw->croph_val = hdw->res_ver_val;
- hdw->croph_dirty = !0;
- } else if (hdw->croph_dirty) {
- int nvres = hdw->std_mask_cur & V4L2_STD_525_60 ? 480 : 576;
- hdw->res_ver_dirty = !0;
- hdw->res_ver_val = min(nvres, hdw->croph_val);
- }
-
- /* If any of the below has changed, then we can't do the update
- while the pipeline is running. Pipeline must be paused first
- and decoder -> encoder connection be made quiescent before we
- can proceed. */
- disruptive_change =
- (hdw->std_dirty ||
- hdw->enc_unsafe_stale ||
- hdw->srate_dirty ||
- hdw->res_ver_dirty ||
- hdw->res_hor_dirty ||
- hdw->cropw_dirty ||
- hdw->croph_dirty ||
- hdw->input_dirty ||
- (hdw->active_stream_type != hdw->desired_stream_type));
- if (disruptive_change && !hdw->state_pipeline_idle) {
- /* Pipeline is not idle; we can't proceed. Arrange to
- cause pipeline to stop so that we can try this again
- later.... */
- hdw->state_pipeline_pause = !0;
- return 0;
- }
-
- if (hdw->srate_dirty) {
- /* Write new sample rate into control structure since
- * the master copy is stale. We must track srate
- * separate from the mpeg control structure because
- * other logic also uses this value. */
- struct v4l2_ext_controls cs;
- struct v4l2_ext_control c1;
- memset(&cs,0,sizeof(cs));
- memset(&c1,0,sizeof(c1));
- cs.controls = &c1;
- cs.count = 1;
- c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
- c1.value = hdw->srate_val;
- cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS);
- }
-
- if (hdw->active_stream_type != hdw->desired_stream_type) {
- /* Handle any side effects of stream config here */
- hdw->active_stream_type = hdw->desired_stream_type;
- }
-
- if (hdw->hdw_desc->signal_routing_scheme ==
- PVR2_ROUTING_SCHEME_GOTVIEW) {
- u32 b;
- /* Handle GOTVIEW audio switching */
- pvr2_hdw_gpio_get_out(hdw,&b);
- if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
- /* Set GPIO 11 */
- pvr2_hdw_gpio_chg_out(hdw,(1 << 11),~0);
- } else {
- /* Clear GPIO 11 */
- pvr2_hdw_gpio_chg_out(hdw,(1 << 11),0);
- }
- }
-
- /* Check and update state for all sub-devices. */
- pvr2_subdev_update(hdw);
-
- hdw->tuner_updated = 0;
- hdw->force_dirty = 0;
- for (idx = 0; idx < hdw->control_cnt; idx++) {
- cptr = hdw->controls + idx;
- if (!cptr->info->clear_dirty) continue;
- cptr->info->clear_dirty(cptr);
- }
-
- if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) &&
- hdw->state_encoder_run) {
- /* If encoder isn't running or it can't be touched, then
- this will get worked out later when we start the
- encoder. */
- if (pvr2_encoder_adjust(hdw) < 0) return !0;
- }
-
- hdw->state_pipeline_config = !0;
- /* Hardware state may have changed in a way to cause the cropping
- capabilities to have changed. So mark it stale, which will
- cause a later re-fetch. */
- trace_stbit("state_pipeline_config",hdw->state_pipeline_config);
- return !0;
-}
-
-
-int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
-{
- int fl;
- LOCK_TAKE(hdw->big_lock);
- fl = pvr2_hdw_commit_setup(hdw);
- LOCK_GIVE(hdw->big_lock);
- if (!fl) return 0;
- return pvr2_hdw_wait(hdw,0);
-}
-
-
-static void pvr2_hdw_worker_poll(struct work_struct *work)
-{
- int fl = 0;
- struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,workpoll);
- LOCK_TAKE(hdw->big_lock); do {
- fl = pvr2_hdw_state_eval(hdw);
- } while (0); LOCK_GIVE(hdw->big_lock);
- if (fl && hdw->state_func) {
- hdw->state_func(hdw->state_data);
- }
-}
-
-
-static int pvr2_hdw_wait(struct pvr2_hdw *hdw,int state)
-{
- return wait_event_interruptible(
- hdw->state_wait_data,
- (hdw->state_stale == 0) &&
- (!state || (hdw->master_state != state)));
-}
-
-
-/* Return name for this driver instance */
-const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
-{
- return hdw->name;
-}
-
-
-const char *pvr2_hdw_get_desc(struct pvr2_hdw *hdw)
-{
- return hdw->hdw_desc->description;
-}
-
-
-const char *pvr2_hdw_get_type(struct pvr2_hdw *hdw)
-{
- return hdw->hdw_desc->shortname;
-}
-
-
-int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
-{
- int result;
- LOCK_TAKE(hdw->ctl_lock); do {
- hdw->cmd_buffer[0] = FX2CMD_GET_USB_SPEED;
- result = pvr2_send_request(hdw,
- hdw->cmd_buffer,1,
- hdw->cmd_buffer,1);
- if (result < 0) break;
- result = (hdw->cmd_buffer[0] != 0);
- } while(0); LOCK_GIVE(hdw->ctl_lock);
- return result;
-}
-
-
-/* Execute poll of tuner status */
-void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw)
-{
- LOCK_TAKE(hdw->big_lock); do {
- pvr2_hdw_status_poll(hdw);
- } while (0); LOCK_GIVE(hdw->big_lock);
-}
-
-
-static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw)
-{
- if (!hdw->cropcap_stale) {
- return 0;
- }
- pvr2_hdw_status_poll(hdw);
- if (hdw->cropcap_stale) {
- return -EIO;
- }
- return 0;
-}
-
-
-/* Return information about cropping capabilities */
-int pvr2_hdw_get_cropcap(struct pvr2_hdw *hdw, struct v4l2_cropcap *pp)
-{
- int stat = 0;
- LOCK_TAKE(hdw->big_lock);
- stat = pvr2_hdw_check_cropcap(hdw);
- if (!stat) {
- memcpy(pp, &hdw->cropcap_info, sizeof(hdw->cropcap_info));
- }
- LOCK_GIVE(hdw->big_lock);
- return stat;
-}
-
-
-/* Return information about the tuner */
-int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp)
-{
- LOCK_TAKE(hdw->big_lock); do {
- if (hdw->tuner_signal_stale) {
- pvr2_hdw_status_poll(hdw);
- }
- memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner));
- } while (0); LOCK_GIVE(hdw->big_lock);
- return 0;
-}
-
-
-/* Get handle to video output stream */
-struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
-{
- return hp->vid_stream;
-}
-
-
-void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
-{
- int nr = pvr2_hdw_get_unit_number(hdw);
- LOCK_TAKE(hdw->big_lock); do {
- printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
- v4l2_device_call_all(&hdw->v4l2_dev, 0, core, log_status);
- pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
- cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
- pvr2_hdw_state_log_state(hdw);
- printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
- } while (0); LOCK_GIVE(hdw->big_lock);
-}
-
-
-/* Grab EEPROM contents, needed for direct method. */
-#define EEPROM_SIZE 8192
-#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__)
-static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw)
-{
- struct i2c_msg msg[2];
- u8 *eeprom;
- u8 iadd[2];
- u8 addr;
- u16 eepromSize;
- unsigned int offs;
- int ret;
- int mode16 = 0;
- unsigned pcnt,tcnt;
- eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL);
- if (!eeprom) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Failed to allocate memory"
- " required to read eeprom");
- return NULL;
- }
-
- trace_eeprom("Value for eeprom addr from controller was 0x%x",
- hdw->eeprom_addr);
- addr = hdw->eeprom_addr;
- /* Seems that if the high bit is set, then the *real* eeprom
- address is shifted right now bit position (noticed this in
- newer PVR USB2 hardware) */
- if (addr & 0x80) addr >>= 1;
-
- /* FX2 documentation states that a 16bit-addressed eeprom is
- expected if the I2C address is an odd number (yeah, this is
- strange but it's what they do) */
- mode16 = (addr & 1);
- eepromSize = (mode16 ? EEPROM_SIZE : 256);
- trace_eeprom("Examining %d byte eeprom at location 0x%x"
- " using %d bit addressing",eepromSize,addr,
- mode16 ? 16 : 8);
-
- msg[0].addr = addr;
- msg[0].flags = 0;
- msg[0].len = mode16 ? 2 : 1;
- msg[0].buf = iadd;
- msg[1].addr = addr;
- msg[1].flags = I2C_M_RD;
-
- /* We have to do the actual eeprom data fetch ourselves, because
- (1) we're only fetching part of the eeprom, and (2) if we were
- getting the whole thing our I2C driver can't grab it in one
- pass - which is what tveeprom is otherwise going to attempt */
- memset(eeprom,0,EEPROM_SIZE);
- for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
- pcnt = 16;
- if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
- offs = tcnt + (eepromSize - EEPROM_SIZE);
- if (mode16) {
- iadd[0] = offs >> 8;
- iadd[1] = offs;
- } else {
- iadd[0] = offs;
- }
- msg[1].len = pcnt;
- msg[1].buf = eeprom+tcnt;
- if ((ret = i2c_transfer(&hdw->i2c_adap,
- msg,ARRAY_SIZE(msg))) != 2) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "eeprom fetch set offs err=%d",ret);
- kfree(eeprom);
- return NULL;
- }
- }
- return eeprom;
-}
-
-
-void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
- int mode,
- int enable_flag)
-{
- int ret;
- u16 address;
- unsigned int pipe;
- LOCK_TAKE(hdw->big_lock); do {
- if ((hdw->fw_buffer == NULL) == !enable_flag) break;
-
- if (!enable_flag) {
- pvr2_trace(PVR2_TRACE_FIRMWARE,
- "Cleaning up after CPU firmware fetch");
- kfree(hdw->fw_buffer);
- hdw->fw_buffer = NULL;
- hdw->fw_size = 0;
- if (hdw->fw_cpu_flag) {
- /* Now release the CPU. It will disconnect
- and reconnect later. */
- pvr2_hdw_cpureset_assert(hdw,0);
- }
- break;
- }
-
- hdw->fw_cpu_flag = (mode != 2);
- if (hdw->fw_cpu_flag) {
- hdw->fw_size = (mode == 1) ? 0x4000 : 0x2000;
- pvr2_trace(PVR2_TRACE_FIRMWARE,
- "Preparing to suck out CPU firmware"
- " (size=%u)", hdw->fw_size);
- hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL);
- if (!hdw->fw_buffer) {
- hdw->fw_size = 0;
- break;
- }
-
- /* We have to hold the CPU during firmware upload. */
- pvr2_hdw_cpureset_assert(hdw,1);
-
- /* download the firmware from address 0000-1fff in 2048
- (=0x800) bytes chunk. */
-
- pvr2_trace(PVR2_TRACE_FIRMWARE,
- "Grabbing CPU firmware");
- pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
- for(address = 0; address < hdw->fw_size;
- address += 0x800) {
- ret = usb_control_msg(hdw->usb_dev,pipe,
- 0xa0,0xc0,
- address,0,
- hdw->fw_buffer+address,
- 0x800,HZ);
- if (ret < 0) break;
- }
-
- pvr2_trace(PVR2_TRACE_FIRMWARE,
- "Done grabbing CPU firmware");
- } else {
- pvr2_trace(PVR2_TRACE_FIRMWARE,
- "Sucking down EEPROM contents");
- hdw->fw_buffer = pvr2_full_eeprom_fetch(hdw);
- if (!hdw->fw_buffer) {
- pvr2_trace(PVR2_TRACE_FIRMWARE,
- "EEPROM content suck failed.");
- break;
- }
- hdw->fw_size = EEPROM_SIZE;
- pvr2_trace(PVR2_TRACE_FIRMWARE,
- "Done sucking down EEPROM contents");
- }
-
- } while (0); LOCK_GIVE(hdw->big_lock);
-}
-
-
-/* Return true if we're in a mode for retrieval CPU firmware */
-int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
-{
- return hdw->fw_buffer != NULL;
-}
-
-
-int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
- char *buf,unsigned int cnt)
-{
- int ret = -EINVAL;
- LOCK_TAKE(hdw->big_lock); do {
- if (!buf) break;
- if (!cnt) break;
-
- if (!hdw->fw_buffer) {
- ret = -EIO;
- break;
- }
-
- if (offs >= hdw->fw_size) {
- pvr2_trace(PVR2_TRACE_FIRMWARE,
- "Read firmware data offs=%d EOF",
- offs);
- ret = 0;
- break;
- }
-
- if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs;
-
- memcpy(buf,hdw->fw_buffer+offs,cnt);
-
- pvr2_trace(PVR2_TRACE_FIRMWARE,
- "Read firmware data offs=%d cnt=%d",
- offs,cnt);
- ret = cnt;
- } while (0); LOCK_GIVE(hdw->big_lock);
-
- return ret;
-}
-
-
-int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw,
- enum pvr2_v4l_type index)
-{
- switch (index) {
- case pvr2_v4l_type_video: return hdw->v4l_minor_number_video;
- case pvr2_v4l_type_vbi: return hdw->v4l_minor_number_vbi;
- case pvr2_v4l_type_radio: return hdw->v4l_minor_number_radio;
- default: return -1;
- }
-}
-
-
-/* Store a v4l minor device number */
-void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,
- enum pvr2_v4l_type index,int v)
-{
- switch (index) {
- case pvr2_v4l_type_video: hdw->v4l_minor_number_video = v;
- case pvr2_v4l_type_vbi: hdw->v4l_minor_number_vbi = v;
- case pvr2_v4l_type_radio: hdw->v4l_minor_number_radio = v;
- default: break;
- }
-}
-
-
-static void pvr2_ctl_write_complete(struct urb *urb)
-{
- struct pvr2_hdw *hdw = urb->context;
- hdw->ctl_write_pend_flag = 0;
- if (hdw->ctl_read_pend_flag) return;
- complete(&hdw->ctl_done);
-}
-
-
-static void pvr2_ctl_read_complete(struct urb *urb)
-{
- struct pvr2_hdw *hdw = urb->context;
- hdw->ctl_read_pend_flag = 0;
- if (hdw->ctl_write_pend_flag) return;
- complete(&hdw->ctl_done);
-}
-
-
-static void pvr2_ctl_timeout(unsigned long data)
-{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
- if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
- hdw->ctl_timeout_flag = !0;
- if (hdw->ctl_write_pend_flag)
- usb_unlink_urb(hdw->ctl_write_urb);
- if (hdw->ctl_read_pend_flag)
- usb_unlink_urb(hdw->ctl_read_urb);
- }
-}
-
-
-/* Issue a command and get a response from the device. This extended
- version includes a probe flag (which if set means that device errors
- should not be logged or treated as fatal) and a timeout in jiffies.
- This can be used to non-lethally probe the health of endpoint 1. */
-static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
- unsigned int timeout,int probe_fl,
- void *write_data,unsigned int write_len,
- void *read_data,unsigned int read_len)
-{
- unsigned int idx;
- int status = 0;
- struct timer_list timer;
- if (!hdw->ctl_lock_held) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Attempted to execute control transfer"
- " without lock!!");
- return -EDEADLK;
- }
- if (!hdw->flag_ok && !probe_fl) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Attempted to execute control transfer"
- " when device not ok");
- return -EIO;
- }
- if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) {
- if (!probe_fl) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Attempted to execute control transfer"
- " when USB is disconnected");
- }
- return -ENOTTY;
- }
-
- /* Ensure that we have sane parameters */
- if (!write_data) write_len = 0;
- if (!read_data) read_len = 0;
- if (write_len > PVR2_CTL_BUFFSIZE) {
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Attempted to execute %d byte"
- " control-write transfer (limit=%d)",
- write_len,PVR2_CTL_BUFFSIZE);
- return -EINVAL;
- }
- if (read_len > PVR2_CTL_BUFFSIZE) {
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Attempted to execute %d byte"
- " control-read transfer (limit=%d)",
- write_len,PVR2_CTL_BUFFSIZE);
- return -EINVAL;
- }
- if ((!write_len) && (!read_len)) {
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Attempted to execute null control transfer?");
- return -EINVAL;
- }
-
-
- hdw->cmd_debug_state = 1;
- if (write_len) {
- hdw->cmd_debug_code = ((unsigned char *)write_data)[0];
- } else {
- hdw->cmd_debug_code = 0;
- }
- hdw->cmd_debug_write_len = write_len;
- hdw->cmd_debug_read_len = read_len;
-
- /* Initialize common stuff */
- init_completion(&hdw->ctl_done);
- hdw->ctl_timeout_flag = 0;
- hdw->ctl_write_pend_flag = 0;
- hdw->ctl_read_pend_flag = 0;
- init_timer(&timer);
- timer.expires = jiffies + timeout;
- timer.data = (unsigned long)hdw;
- timer.function = pvr2_ctl_timeout;
-
- if (write_len) {
- hdw->cmd_debug_state = 2;
- /* Transfer write data to internal buffer */
- for (idx = 0; idx < write_len; idx++) {
- hdw->ctl_write_buffer[idx] =
- ((unsigned char *)write_data)[idx];
- }
- /* Initiate a write request */
- usb_fill_bulk_urb(hdw->ctl_write_urb,
- hdw->usb_dev,
- usb_sndbulkpipe(hdw->usb_dev,
- PVR2_CTL_WRITE_ENDPOINT),
- hdw->ctl_write_buffer,
- write_len,
- pvr2_ctl_write_complete,
- hdw);
- hdw->ctl_write_urb->actual_length = 0;
- hdw->ctl_write_pend_flag = !0;
- status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
- if (status < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Failed to submit write-control"
- " URB status=%d",status);
- hdw->ctl_write_pend_flag = 0;
- goto done;
- }
- }
-
- if (read_len) {
- hdw->cmd_debug_state = 3;
- memset(hdw->ctl_read_buffer,0x43,read_len);
- /* Initiate a read request */
- usb_fill_bulk_urb(hdw->ctl_read_urb,
- hdw->usb_dev,
- usb_rcvbulkpipe(hdw->usb_dev,
- PVR2_CTL_READ_ENDPOINT),
- hdw->ctl_read_buffer,
- read_len,
- pvr2_ctl_read_complete,
- hdw);
- hdw->ctl_read_urb->actual_length = 0;
- hdw->ctl_read_pend_flag = !0;
- status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
- if (status < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Failed to submit read-control"
- " URB status=%d",status);
- hdw->ctl_read_pend_flag = 0;
- goto done;
- }
- }
-
- /* Start timer */
- add_timer(&timer);
-
- /* Now wait for all I/O to complete */
- hdw->cmd_debug_state = 4;
- while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
- wait_for_completion(&hdw->ctl_done);
- }
- hdw->cmd_debug_state = 5;
-
- /* Stop timer */
- del_timer_sync(&timer);
-
- hdw->cmd_debug_state = 6;
- status = 0;
-
- if (hdw->ctl_timeout_flag) {
- status = -ETIMEDOUT;
- if (!probe_fl) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Timed out control-write");
- }
- goto done;
- }
-
- if (write_len) {
- /* Validate results of write request */
- if ((hdw->ctl_write_urb->status != 0) &&
- (hdw->ctl_write_urb->status != -ENOENT) &&
- (hdw->ctl_write_urb->status != -ESHUTDOWN) &&
- (hdw->ctl_write_urb->status != -ECONNRESET)) {
- /* USB subsystem is reporting some kind of failure
- on the write */
- status = hdw->ctl_write_urb->status;
- if (!probe_fl) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "control-write URB failure,"
- " status=%d",
- status);
- }
- goto done;
- }
- if (hdw->ctl_write_urb->actual_length < write_len) {
- /* Failed to write enough data */
- status = -EIO;
- if (!probe_fl) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "control-write URB short,"
- " expected=%d got=%d",
- write_len,
- hdw->ctl_write_urb->actual_length);
- }
- goto done;
- }
- }
- if (read_len) {
- /* Validate results of read request */
- if ((hdw->ctl_read_urb->status != 0) &&
- (hdw->ctl_read_urb->status != -ENOENT) &&
- (hdw->ctl_read_urb->status != -ESHUTDOWN) &&
- (hdw->ctl_read_urb->status != -ECONNRESET)) {
- /* USB subsystem is reporting some kind of failure
- on the read */
- status = hdw->ctl_read_urb->status;
- if (!probe_fl) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "control-read URB failure,"
- " status=%d",
- status);
- }
- goto done;
- }
- if (hdw->ctl_read_urb->actual_length < read_len) {
- /* Failed to read enough data */
- status = -EIO;
- if (!probe_fl) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "control-read URB short,"
- " expected=%d got=%d",
- read_len,
- hdw->ctl_read_urb->actual_length);
- }
- goto done;
- }
- /* Transfer retrieved data out from internal buffer */
- for (idx = 0; idx < read_len; idx++) {
- ((unsigned char *)read_data)[idx] =
- hdw->ctl_read_buffer[idx];
- }
- }
-
- done:
-
- hdw->cmd_debug_state = 0;
- if ((status < 0) && (!probe_fl)) {
- pvr2_hdw_render_useless(hdw);
- }
- return status;
-}
-
-
-int pvr2_send_request(struct pvr2_hdw *hdw,
- void *write_data,unsigned int write_len,
- void *read_data,unsigned int read_len)
-{
- return pvr2_send_request_ex(hdw,HZ*4,0,
- write_data,write_len,
- read_data,read_len);
-}
-
-
-static int pvr2_issue_simple_cmd(struct pvr2_hdw *hdw,u32 cmdcode)
-{
- int ret;
- unsigned int cnt = 1;
- unsigned int args = 0;
- LOCK_TAKE(hdw->ctl_lock);
- hdw->cmd_buffer[0] = cmdcode & 0xffu;
- args = (cmdcode >> 8) & 0xffu;
- args = (args > 2) ? 2 : args;
- if (args) {
- cnt += args;
- hdw->cmd_buffer[1] = (cmdcode >> 16) & 0xffu;
- if (args > 1) {
- hdw->cmd_buffer[2] = (cmdcode >> 24) & 0xffu;
- }
- }
- if (pvrusb2_debug & PVR2_TRACE_INIT) {
- unsigned int idx;
- unsigned int ccnt,bcnt;
- char tbuf[50];
- cmdcode &= 0xffu;
- bcnt = 0;
- ccnt = scnprintf(tbuf+bcnt,
- sizeof(tbuf)-bcnt,
- "Sending FX2 command 0x%x",cmdcode);
- bcnt += ccnt;
- for (idx = 0; idx < ARRAY_SIZE(pvr2_fx2cmd_desc); idx++) {
- if (pvr2_fx2cmd_desc[idx].id == cmdcode) {
- ccnt = scnprintf(tbuf+bcnt,
- sizeof(tbuf)-bcnt,
- " \"%s\"",
- pvr2_fx2cmd_desc[idx].desc);
- bcnt += ccnt;
- break;
- }
- }
- if (args) {
- ccnt = scnprintf(tbuf+bcnt,
- sizeof(tbuf)-bcnt,
- " (%u",hdw->cmd_buffer[1]);
- bcnt += ccnt;
- if (args > 1) {
- ccnt = scnprintf(tbuf+bcnt,
- sizeof(tbuf)-bcnt,
- ",%u",hdw->cmd_buffer[2]);
- bcnt += ccnt;
- }
- ccnt = scnprintf(tbuf+bcnt,
- sizeof(tbuf)-bcnt,
- ")");
- bcnt += ccnt;
- }
- pvr2_trace(PVR2_TRACE_INIT,"%.*s",bcnt,tbuf);
- }
- ret = pvr2_send_request(hdw,hdw->cmd_buffer,cnt,NULL,0);
- LOCK_GIVE(hdw->ctl_lock);
- return ret;
-}
-
-
-int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
-{
- int ret;
-
- LOCK_TAKE(hdw->ctl_lock);
-
- hdw->cmd_buffer[0] = FX2CMD_REG_WRITE; /* write register prefix */
- PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
- hdw->cmd_buffer[5] = 0;
- hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
- hdw->cmd_buffer[7] = reg & 0xff;
-
-
- ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0);
-
- LOCK_GIVE(hdw->ctl_lock);
-
- return ret;
-}
-
-
-static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
-{
- int ret = 0;
-
- LOCK_TAKE(hdw->ctl_lock);
-
- hdw->cmd_buffer[0] = FX2CMD_REG_READ; /* read register prefix */
- hdw->cmd_buffer[1] = 0;
- hdw->cmd_buffer[2] = 0;
- hdw->cmd_buffer[3] = 0;
- hdw->cmd_buffer[4] = 0;
- hdw->cmd_buffer[5] = 0;
- hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
- hdw->cmd_buffer[7] = reg & 0xff;
-
- ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
- *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
-
- LOCK_GIVE(hdw->ctl_lock);
-
- return ret;
-}
-
-
-void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
-{
- if (!hdw->flag_ok) return;
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Device being rendered inoperable");
- if (hdw->vid_stream) {
- pvr2_stream_setup(hdw->vid_stream,NULL,0,0);
- }
- hdw->flag_ok = 0;
- trace_stbit("flag_ok",hdw->flag_ok);
- pvr2_hdw_state_sched(hdw);
-}
-
-
-void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
-{
- int ret;
- pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
- ret = usb_lock_device_for_reset(hdw->usb_dev,NULL);
- if (ret == 0) {
- ret = usb_reset_device(hdw->usb_dev);
- usb_unlock_device(hdw->usb_dev);
- } else {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Failed to lock USB device ret=%d",ret);
- }
- if (init_pause_msec) {
- pvr2_trace(PVR2_TRACE_INFO,
- "Waiting %u msec for hardware to settle",
- init_pause_msec);
- msleep(init_pause_msec);
- }
-
-}
-
-
-void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
-{
- char *da;
- unsigned int pipe;
- int ret;
-
- if (!hdw->usb_dev) return;
-
- da = kmalloc(16, GFP_KERNEL);
-
- if (da == NULL) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Unable to allocate memory to control CPU reset");
- return;
- }
-
- pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
-
- da[0] = val ? 0x01 : 0x00;
-
- /* Write the CPUCS register on the 8051. The lsb of the register
- is the reset bit; a 1 asserts reset while a 0 clears it. */
- pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
- ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
- if (ret < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "cpureset_assert(%d) error=%d",val,ret);
- pvr2_hdw_render_useless(hdw);
- }
-
- kfree(da);
-}
-
-
-int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
-{
- return pvr2_issue_simple_cmd(hdw,FX2CMD_DEEP_RESET);
-}
-
-
-int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
-{
- return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_ON);
-}
-
-
-int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *hdw)
-{
- return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_OFF);
-}
-
-
-int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
-{
- pvr2_trace(PVR2_TRACE_INIT,
- "Requesting decoder reset");
- if (hdw->decoder_client_id) {
- v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
- core, reset, 0);
- pvr2_hdw_cx25840_vbi_hack(hdw);
- return 0;
- }
- pvr2_trace(PVR2_TRACE_INIT,
- "Unable to reset decoder: nothing attached");
- return -ENOTTY;
-}
-
-
-static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff)
-{
- hdw->flag_ok = !0;
- return pvr2_issue_simple_cmd(hdw,
- FX2CMD_HCW_DEMOD_RESETIN |
- (1 << 8) |
- ((onoff ? 1 : 0) << 16));
-}
-
-
-static int pvr2_hdw_cmd_onair_fe_power_ctrl(struct pvr2_hdw *hdw, int onoff)
-{
- hdw->flag_ok = !0;
- return pvr2_issue_simple_cmd(hdw,(onoff ?
- FX2CMD_ONAIR_DTV_POWER_ON :
- FX2CMD_ONAIR_DTV_POWER_OFF));
-}
-
-
-static int pvr2_hdw_cmd_onair_digital_path_ctrl(struct pvr2_hdw *hdw,
- int onoff)
-{
- return pvr2_issue_simple_cmd(hdw,(onoff ?
- FX2CMD_ONAIR_DTV_STREAMING_ON :
- FX2CMD_ONAIR_DTV_STREAMING_OFF));
-}
-
-
-static void pvr2_hdw_cmd_modeswitch(struct pvr2_hdw *hdw,int digitalFl)
-{
- int cmode;
- /* Compare digital/analog desired setting with current setting. If
- they don't match, fix it... */
- cmode = (digitalFl ? PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG);
- if (cmode == hdw->pathway_state) {
- /* They match; nothing to do */
- return;
- }
-
- switch (hdw->hdw_desc->digital_control_scheme) {
- case PVR2_DIGITAL_SCHEME_HAUPPAUGE:
- pvr2_hdw_cmd_hcw_demod_reset(hdw,digitalFl);
- if (cmode == PVR2_PATHWAY_ANALOG) {
- /* If moving to analog mode, also force the decoder
- to reset. If no decoder is attached, then it's
- ok to ignore this because if/when the decoder
- attaches, it will reset itself at that time. */
- pvr2_hdw_cmd_decoder_reset(hdw);
- }
- break;
- case PVR2_DIGITAL_SCHEME_ONAIR:
- /* Supposedly we should always have the power on whether in
- digital or analog mode. But for now do what appears to
- work... */
- pvr2_hdw_cmd_onair_fe_power_ctrl(hdw,digitalFl);
- break;
- default: break;
- }
-
- pvr2_hdw_untrip_unlocked(hdw);
- hdw->pathway_state = cmode;
-}
-
-
-static void pvr2_led_ctrl_hauppauge(struct pvr2_hdw *hdw, int onoff)
-{
- /* change some GPIO data
- *
- * note: bit d7 of dir appears to control the LED,
- * so we shut it off here.
- *
- */
- if (onoff) {
- pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000481);
- } else {
- pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000401);
- }
- pvr2_hdw_gpio_chg_out(hdw, 0xffffffff, 0x00000000);
-}
-
-
-typedef void (*led_method_func)(struct pvr2_hdw *,int);
-
-static led_method_func led_methods[] = {
- [PVR2_LED_SCHEME_HAUPPAUGE] = pvr2_led_ctrl_hauppauge,
-};
-
-
-/* Toggle LED */
-static void pvr2_led_ctrl(struct pvr2_hdw *hdw,int onoff)
-{
- unsigned int scheme_id;
- led_method_func fp;
-
- if ((!onoff) == (!hdw->led_on)) return;
-
- hdw->led_on = onoff != 0;
-
- scheme_id = hdw->hdw_desc->led_scheme;
- if (scheme_id < ARRAY_SIZE(led_methods)) {
- fp = led_methods[scheme_id];
- } else {
- fp = NULL;
- }
-
- if (fp) (*fp)(hdw,onoff);
-}
-
-
-/* Stop / start video stream transport */
-static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
-{
- int ret;
-
- /* If we're in analog mode, then just issue the usual analog
- command. */
- if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
- return pvr2_issue_simple_cmd(hdw,
- (runFl ?
- FX2CMD_STREAMING_ON :
- FX2CMD_STREAMING_OFF));
- /*Note: Not reached */
- }
-
- if (hdw->pathway_state != PVR2_PATHWAY_DIGITAL) {
- /* Whoops, we don't know what mode we're in... */
- return -EINVAL;
- }
-
- /* To get here we have to be in digital mode. The mechanism here
- is unfortunately different for different vendors. So we switch
- on the device's digital scheme attribute in order to figure out
- what to do. */
- switch (hdw->hdw_desc->digital_control_scheme) {
- case PVR2_DIGITAL_SCHEME_HAUPPAUGE:
- return pvr2_issue_simple_cmd(hdw,
- (runFl ?
- FX2CMD_HCW_DTV_STREAMING_ON :
- FX2CMD_HCW_DTV_STREAMING_OFF));
- case PVR2_DIGITAL_SCHEME_ONAIR:
- ret = pvr2_issue_simple_cmd(hdw,
- (runFl ?
- FX2CMD_STREAMING_ON :
- FX2CMD_STREAMING_OFF));
- if (ret) return ret;
- return pvr2_hdw_cmd_onair_digital_path_ctrl(hdw,runFl);
- default:
- return -EINVAL;
- }
-}
-
-
-/* Evaluate whether or not state_pathway_ok can change */
-static int state_eval_pathway_ok(struct pvr2_hdw *hdw)
-{
- if (hdw->state_pathway_ok) {
- /* Nothing to do if pathway is already ok */
- return 0;
- }
- if (!hdw->state_pipeline_idle) {
- /* Not allowed to change anything if pipeline is not idle */
- return 0;
- }
- pvr2_hdw_cmd_modeswitch(hdw,hdw->input_val == PVR2_CVAL_INPUT_DTV);
- hdw->state_pathway_ok = !0;
- trace_stbit("state_pathway_ok",hdw->state_pathway_ok);
- return !0;
-}
-
-
-/* Evaluate whether or not state_encoder_ok can change */
-static int state_eval_encoder_ok(struct pvr2_hdw *hdw)
-{
- if (hdw->state_encoder_ok) return 0;
- if (hdw->flag_tripped) return 0;
- if (hdw->state_encoder_run) return 0;
- if (hdw->state_encoder_config) return 0;
- if (hdw->state_decoder_run) return 0;
- if (hdw->state_usbstream_run) return 0;
- if (hdw->pathway_state == PVR2_PATHWAY_DIGITAL) {
- if (!hdw->hdw_desc->flag_digital_requires_cx23416) return 0;
- } else if (hdw->pathway_state != PVR2_PATHWAY_ANALOG) {
- return 0;
- }
-
- if (pvr2_upload_firmware2(hdw) < 0) {
- hdw->flag_tripped = !0;
- trace_stbit("flag_tripped",hdw->flag_tripped);
- return !0;
- }
- hdw->state_encoder_ok = !0;
- trace_stbit("state_encoder_ok",hdw->state_encoder_ok);
- return !0;
-}
-
-
-/* Evaluate whether or not state_encoder_config can change */
-static int state_eval_encoder_config(struct pvr2_hdw *hdw)
-{
- if (hdw->state_encoder_config) {
- if (hdw->state_encoder_ok) {
- if (hdw->state_pipeline_req &&
- !hdw->state_pipeline_pause) return 0;
- }
- hdw->state_encoder_config = 0;
- hdw->state_encoder_waitok = 0;
- trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok);
- /* paranoia - solve race if timer just completed */
- del_timer_sync(&hdw->encoder_wait_timer);
- } else {
- if (!hdw->state_pathway_ok ||
- (hdw->pathway_state != PVR2_PATHWAY_ANALOG) ||
- !hdw->state_encoder_ok ||
- !hdw->state_pipeline_idle ||
- hdw->state_pipeline_pause ||
- !hdw->state_pipeline_req ||
- !hdw->state_pipeline_config) {
- /* We must reset the enforced wait interval if
- anything has happened that might have disturbed
- the encoder. This should be a rare case. */
- if (timer_pending(&hdw->encoder_wait_timer)) {
- del_timer_sync(&hdw->encoder_wait_timer);
- }
- if (hdw->state_encoder_waitok) {
- /* Must clear the state - therefore we did
- something to a state bit and must also
- return true. */
- hdw->state_encoder_waitok = 0;
- trace_stbit("state_encoder_waitok",
- hdw->state_encoder_waitok);
- return !0;
- }
- return 0;
- }
- if (!hdw->state_encoder_waitok) {
- if (!timer_pending(&hdw->encoder_wait_timer)) {
- /* waitok flag wasn't set and timer isn't
- running. Check flag once more to avoid
- a race then start the timer. This is
- the point when we measure out a minimal
- quiet interval before doing something to
- the encoder. */
- if (!hdw->state_encoder_waitok) {
- hdw->encoder_wait_timer.expires =
- jiffies +
- (HZ * TIME_MSEC_ENCODER_WAIT
- / 1000);
- add_timer(&hdw->encoder_wait_timer);
- }
- }
- /* We can't continue until we know we have been
- quiet for the interval measured by this
- timer. */
- return 0;
- }
- pvr2_encoder_configure(hdw);
- if (hdw->state_encoder_ok) hdw->state_encoder_config = !0;
- }
- trace_stbit("state_encoder_config",hdw->state_encoder_config);
- return !0;
-}
-
-
-/* Return true if the encoder should not be running. */
-static int state_check_disable_encoder_run(struct pvr2_hdw *hdw)
-{
- if (!hdw->state_encoder_ok) {
- /* Encoder isn't healthy at the moment, so stop it. */
- return !0;
- }
- if (!hdw->state_pathway_ok) {
- /* Mode is not understood at the moment (i.e. it wants to
- change), so encoder must be stopped. */
- return !0;
- }
-
- switch (hdw->pathway_state) {
- case PVR2_PATHWAY_ANALOG:
- if (!hdw->state_decoder_run) {
- /* We're in analog mode and the decoder is not
- running; thus the encoder should be stopped as
- well. */
- return !0;
- }
- break;
- case PVR2_PATHWAY_DIGITAL:
- if (hdw->state_encoder_runok) {
- /* This is a funny case. We're in digital mode so
- really the encoder should be stopped. However
- if it really is running, only kill it after
- runok has been set. This gives a chance for the
- onair quirk to function (encoder must run
- briefly first, at least once, before onair
- digital streaming can work). */
- return !0;
- }
- break;
- default:
- /* Unknown mode; so encoder should be stopped. */
- return !0;
- }
-
- /* If we get here, we haven't found a reason to stop the
- encoder. */
- return 0;
-}
-
-
-/* Return true if the encoder should be running. */
-static int state_check_enable_encoder_run(struct pvr2_hdw *hdw)
-{
- if (!hdw->state_encoder_ok) {
- /* Don't run the encoder if it isn't healthy... */
- return 0;
- }
- if (!hdw->state_pathway_ok) {
- /* Don't run the encoder if we don't (yet) know what mode
- we need to be in... */
- return 0;
- }
-
- switch (hdw->pathway_state) {
- case PVR2_PATHWAY_ANALOG:
- if (hdw->state_decoder_run && hdw->state_decoder_ready) {
- /* In analog mode, if the decoder is running, then
- run the encoder. */
- return !0;
- }
- break;
- case PVR2_PATHWAY_DIGITAL:
- if ((hdw->hdw_desc->digital_control_scheme ==
- PVR2_DIGITAL_SCHEME_ONAIR) &&
- !hdw->state_encoder_runok) {
- /* This is a quirk. OnAir hardware won't stream
- digital until the encoder has been run at least
- once, for a minimal period of time (empiricially
- measured to be 1/4 second). So if we're on
- OnAir hardware and the encoder has never been
- run at all, then start the encoder. Normal
- state machine logic in the driver will
- automatically handle the remaining bits. */
- return !0;
- }
- break;
- default:
- /* For completeness (unknown mode; encoder won't run ever) */
- break;
- }
- /* If we get here, then we haven't found any reason to run the
- encoder, so don't run it. */
- return 0;
-}
-
-
-/* Evaluate whether or not state_encoder_run can change */
-static int state_eval_encoder_run(struct pvr2_hdw *hdw)
-{
- if (hdw->state_encoder_run) {
- if (!state_check_disable_encoder_run(hdw)) return 0;
- if (hdw->state_encoder_ok) {
- del_timer_sync(&hdw->encoder_run_timer);
- if (pvr2_encoder_stop(hdw) < 0) return !0;
- }
- hdw->state_encoder_run = 0;
- } else {
- if (!state_check_enable_encoder_run(hdw)) return 0;
- if (pvr2_encoder_start(hdw) < 0) return !0;
- hdw->state_encoder_run = !0;
- if (!hdw->state_encoder_runok) {
- hdw->encoder_run_timer.expires =
- jiffies + (HZ * TIME_MSEC_ENCODER_OK / 1000);
- add_timer(&hdw->encoder_run_timer);
- }
- }
- trace_stbit("state_encoder_run",hdw->state_encoder_run);
- return !0;
-}
-
-
-/* Timeout function for quiescent timer. */
-static void pvr2_hdw_quiescent_timeout(unsigned long data)
-{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
- hdw->state_decoder_quiescent = !0;
- trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent);
- hdw->state_stale = !0;
- queue_work(hdw->workqueue,&hdw->workpoll);
-}
-
-
-/* Timeout function for decoder stabilization timer. */
-static void pvr2_hdw_decoder_stabilization_timeout(unsigned long data)
-{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
- hdw->state_decoder_ready = !0;
- trace_stbit("state_decoder_ready", hdw->state_decoder_ready);
- hdw->state_stale = !0;
- queue_work(hdw->workqueue, &hdw->workpoll);
-}
-
-
-/* Timeout function for encoder wait timer. */
-static void pvr2_hdw_encoder_wait_timeout(unsigned long data)
-{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
- hdw->state_encoder_waitok = !0;
- trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok);
- hdw->state_stale = !0;
- queue_work(hdw->workqueue,&hdw->workpoll);
-}
-
-
-/* Timeout function for encoder run timer. */
-static void pvr2_hdw_encoder_run_timeout(unsigned long data)
-{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
- if (!hdw->state_encoder_runok) {
- hdw->state_encoder_runok = !0;
- trace_stbit("state_encoder_runok",hdw->state_encoder_runok);
- hdw->state_stale = !0;
- queue_work(hdw->workqueue,&hdw->workpoll);
- }
-}
-
-
-/* Evaluate whether or not state_decoder_run can change */
-static int state_eval_decoder_run(struct pvr2_hdw *hdw)
-{
- if (hdw->state_decoder_run) {
- if (hdw->state_encoder_ok) {
- if (hdw->state_pipeline_req &&
- !hdw->state_pipeline_pause &&
- hdw->state_pathway_ok) return 0;
- }
- if (!hdw->flag_decoder_missed) {
- pvr2_decoder_enable(hdw,0);
- }
- hdw->state_decoder_quiescent = 0;
- hdw->state_decoder_run = 0;
- /* paranoia - solve race if timer(s) just completed */
- del_timer_sync(&hdw->quiescent_timer);
- /* Kill the stabilization timer, in case we're killing the
- encoder before the previous stabilization interval has
- been properly timed. */
- del_timer_sync(&hdw->decoder_stabilization_timer);
- hdw->state_decoder_ready = 0;
- } else {
- if (!hdw->state_decoder_quiescent) {
- if (!timer_pending(&hdw->quiescent_timer)) {
- /* We don't do something about the
- quiescent timer until right here because
- we also want to catch cases where the
- decoder was already not running (like
- after initialization) as opposed to
- knowing that we had just stopped it.
- The second flag check is here to cover a
- race - the timer could have run and set
- this flag just after the previous check
- but before we did the pending check. */
- if (!hdw->state_decoder_quiescent) {
- hdw->quiescent_timer.expires =
- jiffies +
- (HZ * TIME_MSEC_DECODER_WAIT
- / 1000);
- add_timer(&hdw->quiescent_timer);
- }
- }
- /* Don't allow decoder to start again until it has
- been quiesced first. This little detail should
- hopefully further stabilize the encoder. */
- return 0;
- }
- if (!hdw->state_pathway_ok ||
- (hdw->pathway_state != PVR2_PATHWAY_ANALOG) ||
- !hdw->state_pipeline_req ||
- hdw->state_pipeline_pause ||
- !hdw->state_pipeline_config ||
- !hdw->state_encoder_config ||
- !hdw->state_encoder_ok) return 0;
- del_timer_sync(&hdw->quiescent_timer);
- if (hdw->flag_decoder_missed) return 0;
- if (pvr2_decoder_enable(hdw,!0) < 0) return 0;
- hdw->state_decoder_quiescent = 0;
- hdw->state_decoder_ready = 0;
- hdw->state_decoder_run = !0;
- if (hdw->decoder_client_id == PVR2_CLIENT_ID_SAA7115) {
- hdw->decoder_stabilization_timer.expires =
- jiffies +
- (HZ * TIME_MSEC_DECODER_STABILIZATION_WAIT /
- 1000);
- add_timer(&hdw->decoder_stabilization_timer);
- } else {
- hdw->state_decoder_ready = !0;
- }
- }
- trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent);
- trace_stbit("state_decoder_run",hdw->state_decoder_run);
- trace_stbit("state_decoder_ready", hdw->state_decoder_ready);
- return !0;
-}
-
-
-/* Evaluate whether or not state_usbstream_run can change */
-static int state_eval_usbstream_run(struct pvr2_hdw *hdw)
-{
- if (hdw->state_usbstream_run) {
- int fl = !0;
- if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
- fl = (hdw->state_encoder_ok &&
- hdw->state_encoder_run);
- } else if ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) &&
- (hdw->hdw_desc->flag_digital_requires_cx23416)) {
- fl = hdw->state_encoder_ok;
- }
- if (fl &&
- hdw->state_pipeline_req &&
- !hdw->state_pipeline_pause &&
- hdw->state_pathway_ok) {
- return 0;
- }
- pvr2_hdw_cmd_usbstream(hdw,0);
- hdw->state_usbstream_run = 0;
- } else {
- if (!hdw->state_pipeline_req ||
- hdw->state_pipeline_pause ||
- !hdw->state_pathway_ok) return 0;
- if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
- if (!hdw->state_encoder_ok ||
- !hdw->state_encoder_run) return 0;
- } else if ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) &&
- (hdw->hdw_desc->flag_digital_requires_cx23416)) {
- if (!hdw->state_encoder_ok) return 0;
- if (hdw->state_encoder_run) return 0;
- if (hdw->hdw_desc->digital_control_scheme ==
- PVR2_DIGITAL_SCHEME_ONAIR) {
- /* OnAir digital receivers won't stream
- unless the analog encoder has run first.
- Why? I have no idea. But don't even
- try until we know the analog side is
- known to have run. */
- if (!hdw->state_encoder_runok) return 0;
- }
- }
- if (pvr2_hdw_cmd_usbstream(hdw,!0) < 0) return 0;
- hdw->state_usbstream_run = !0;
- }
- trace_stbit("state_usbstream_run",hdw->state_usbstream_run);
- return !0;
-}
-
-
-/* Attempt to configure pipeline, if needed */
-static int state_eval_pipeline_config(struct pvr2_hdw *hdw)
-{
- if (hdw->state_pipeline_config ||
- hdw->state_pipeline_pause) return 0;
- pvr2_hdw_commit_execute(hdw);
- return !0;
-}
-
-
-/* Update pipeline idle and pipeline pause tracking states based on other
- inputs. This must be called whenever the other relevant inputs have
- changed. */
-static int state_update_pipeline_state(struct pvr2_hdw *hdw)
-{
- unsigned int st;
- int updatedFl = 0;
- /* Update pipeline state */
- st = !(hdw->state_encoder_run ||
- hdw->state_decoder_run ||
- hdw->state_usbstream_run ||
- (!hdw->state_decoder_quiescent));
- if (!st != !hdw->state_pipeline_idle) {
- hdw->state_pipeline_idle = st;
- updatedFl = !0;
- }
- if (hdw->state_pipeline_idle && hdw->state_pipeline_pause) {
- hdw->state_pipeline_pause = 0;
- updatedFl = !0;
- }
- return updatedFl;
-}
-
-
-typedef int (*state_eval_func)(struct pvr2_hdw *);
-
-/* Set of functions to be run to evaluate various states in the driver. */
-static const state_eval_func eval_funcs[] = {
- state_eval_pathway_ok,
- state_eval_pipeline_config,
- state_eval_encoder_ok,
- state_eval_encoder_config,
- state_eval_decoder_run,
- state_eval_encoder_run,
- state_eval_usbstream_run,
-};
-
-
-/* Process various states and return true if we did anything interesting. */
-static int pvr2_hdw_state_update(struct pvr2_hdw *hdw)
-{
- unsigned int i;
- int state_updated = 0;
- int check_flag;
-
- if (!hdw->state_stale) return 0;
- if ((hdw->fw1_state != FW1_STATE_OK) ||
- !hdw->flag_ok) {
- hdw->state_stale = 0;
- return !0;
- }
- /* This loop is the heart of the entire driver. It keeps trying to
- evaluate various bits of driver state until nothing changes for
- one full iteration. Each "bit of state" tracks some global
- aspect of the driver, e.g. whether decoder should run, if
- pipeline is configured, usb streaming is on, etc. We separately
- evaluate each of those questions based on other driver state to
- arrive at the correct running configuration. */
- do {
- check_flag = 0;
- state_update_pipeline_state(hdw);
- /* Iterate over each bit of state */
- for (i = 0; (i<ARRAY_SIZE(eval_funcs)) && hdw->flag_ok; i++) {
- if ((*eval_funcs[i])(hdw)) {
- check_flag = !0;
- state_updated = !0;
- state_update_pipeline_state(hdw);
- }
- }
- } while (check_flag && hdw->flag_ok);
- hdw->state_stale = 0;
- trace_stbit("state_stale",hdw->state_stale);
- return state_updated;
-}
-
-
-static unsigned int print_input_mask(unsigned int msk,
- char *buf,unsigned int acnt)
-{
- unsigned int idx,ccnt;
- unsigned int tcnt = 0;
- for (idx = 0; idx < ARRAY_SIZE(control_values_input); idx++) {
- if (!((1 << idx) & msk)) continue;
- ccnt = scnprintf(buf+tcnt,
- acnt-tcnt,
- "%s%s",
- (tcnt ? ", " : ""),
- control_values_input[idx]);
- tcnt += ccnt;
- }
- return tcnt;
-}
-
-
-static const char *pvr2_pathway_state_name(int id)
-{
- switch (id) {
- case PVR2_PATHWAY_ANALOG: return "analog";
- case PVR2_PATHWAY_DIGITAL: return "digital";
- default: return "unknown";
- }
-}
-
-
-static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
- char *buf,unsigned int acnt)
-{
- switch (which) {
- case 0:
- return scnprintf(
- buf,acnt,
- "driver:%s%s%s%s%s <mode=%s>",
- (hdw->flag_ok ? " <ok>" : " <fail>"),
- (hdw->flag_init_ok ? " <init>" : " <uninitialized>"),
- (hdw->flag_disconnected ? " <disconnected>" :
- " <connected>"),
- (hdw->flag_tripped ? " <tripped>" : ""),
- (hdw->flag_decoder_missed ? " <no decoder>" : ""),
- pvr2_pathway_state_name(hdw->pathway_state));
-
- case 1:
- return scnprintf(
- buf,acnt,
- "pipeline:%s%s%s%s",
- (hdw->state_pipeline_idle ? " <idle>" : ""),
- (hdw->state_pipeline_config ?
- " <configok>" : " <stale>"),
- (hdw->state_pipeline_req ? " <req>" : ""),
- (hdw->state_pipeline_pause ? " <pause>" : ""));
- case 2:
- return scnprintf(
- buf,acnt,
- "worker:%s%s%s%s%s%s%s",
- (hdw->state_decoder_run ?
- (hdw->state_decoder_ready ?
- "<decode:run>" : " <decode:start>") :
- (hdw->state_decoder_quiescent ?
- "" : " <decode:stop>")),
- (hdw->state_decoder_quiescent ?
- " <decode:quiescent>" : ""),
- (hdw->state_encoder_ok ?
- "" : " <encode:init>"),
- (hdw->state_encoder_run ?
- (hdw->state_encoder_runok ?
- " <encode:run>" :
- " <encode:firstrun>") :
- (hdw->state_encoder_runok ?
- " <encode:stop>" :
- " <encode:virgin>")),
- (hdw->state_encoder_config ?
- " <encode:configok>" :
- (hdw->state_encoder_waitok ?
- "" : " <encode:waitok>")),
- (hdw->state_usbstream_run ?
- " <usb:run>" : " <usb:stop>"),
- (hdw->state_pathway_ok ?
- " <pathway:ok>" : ""));
- case 3:
- return scnprintf(
- buf,acnt,
- "state: %s",
- pvr2_get_state_name(hdw->master_state));
- case 4: {
- unsigned int tcnt = 0;
- unsigned int ccnt;
-
- ccnt = scnprintf(buf,
- acnt,
- "Hardware supported inputs: ");
- tcnt += ccnt;
- tcnt += print_input_mask(hdw->input_avail_mask,
- buf+tcnt,
- acnt-tcnt);
- if (hdw->input_avail_mask != hdw->input_allowed_mask) {
- ccnt = scnprintf(buf+tcnt,
- acnt-tcnt,
- "; allowed inputs: ");
- tcnt += ccnt;
- tcnt += print_input_mask(hdw->input_allowed_mask,
- buf+tcnt,
- acnt-tcnt);
- }
- return tcnt;
- }
- case 5: {
- struct pvr2_stream_stats stats;
- if (!hdw->vid_stream) break;
- pvr2_stream_get_stats(hdw->vid_stream,
- &stats,
- 0);
- return scnprintf(
- buf,acnt,
- "Bytes streamed=%u"
- " URBs: queued=%u idle=%u ready=%u"
- " processed=%u failed=%u",
- stats.bytes_processed,
- stats.buffers_in_queue,
- stats.buffers_in_idle,
- stats.buffers_in_ready,
- stats.buffers_processed,
- stats.buffers_failed);
- }
- case 6: {
- unsigned int id = hdw->ir_scheme_active;
- return scnprintf(buf, acnt, "ir scheme: id=%d %s", id,
- (id >= ARRAY_SIZE(ir_scheme_names) ?
- "?" : ir_scheme_names[id]));
- }
- default: break;
- }
- return 0;
-}
-
-
-/* Generate report containing info about attached sub-devices and attached
- i2c clients, including an indication of which attached i2c clients are
- actually sub-devices. */
-static unsigned int pvr2_hdw_report_clients(struct pvr2_hdw *hdw,
- char *buf, unsigned int acnt)
-{
- struct v4l2_subdev *sd;
- unsigned int tcnt = 0;
- unsigned int ccnt;
- struct i2c_client *client;
- const char *p;
- unsigned int id;
-
- ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers and I2C clients:\n");
- tcnt += ccnt;
- v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
- id = sd->grp_id;
- p = NULL;
- if (id < ARRAY_SIZE(module_names)) p = module_names[id];
- if (p) {
- ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s:", p);
- tcnt += ccnt;
- } else {
- ccnt = scnprintf(buf + tcnt, acnt - tcnt,
- " (unknown id=%u):", id);
- tcnt += ccnt;
- }
- client = v4l2_get_subdevdata(sd);
- if (client) {
- ccnt = scnprintf(buf + tcnt, acnt - tcnt,
- " %s @ %02x\n", client->name,
- client->addr);
- tcnt += ccnt;
- } else {
- ccnt = scnprintf(buf + tcnt, acnt - tcnt,
- " no i2c client\n");
- tcnt += ccnt;
- }
- }
- return tcnt;
-}
-
-
-unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
- char *buf,unsigned int acnt)
-{
- unsigned int bcnt,ccnt,idx;
- bcnt = 0;
- LOCK_TAKE(hdw->big_lock);
- for (idx = 0; ; idx++) {
- ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,acnt);
- if (!ccnt) break;
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
- if (!acnt) break;
- buf[0] = '\n'; ccnt = 1;
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
- }
- ccnt = pvr2_hdw_report_clients(hdw, buf, acnt);
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
- LOCK_GIVE(hdw->big_lock);
- return bcnt;
-}
-
-
-static void pvr2_hdw_state_log_state(struct pvr2_hdw *hdw)
-{
- char buf[256];
- unsigned int idx, ccnt;
- unsigned int lcnt, ucnt;
-
- for (idx = 0; ; idx++) {
- ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,sizeof(buf));
- if (!ccnt) break;
- printk(KERN_INFO "%s %.*s\n",hdw->name,ccnt,buf);
- }
- ccnt = pvr2_hdw_report_clients(hdw, buf, sizeof(buf));
- ucnt = 0;
- while (ucnt < ccnt) {
- lcnt = 0;
- while ((lcnt + ucnt < ccnt) && (buf[lcnt + ucnt] != '\n')) {
- lcnt++;
- }
- printk(KERN_INFO "%s %.*s\n", hdw->name, lcnt, buf + ucnt);
- ucnt += lcnt + 1;
- }
-}
-
-
-/* Evaluate and update the driver's current state, taking various actions
- as appropriate for the update. */
-static int pvr2_hdw_state_eval(struct pvr2_hdw *hdw)
-{
- unsigned int st;
- int state_updated = 0;
- int callback_flag = 0;
- int analog_mode;
-
- pvr2_trace(PVR2_TRACE_STBITS,
- "Drive state check START");
- if (pvrusb2_debug & PVR2_TRACE_STBITS) {
- pvr2_hdw_state_log_state(hdw);
- }
-
- /* Process all state and get back over disposition */
- state_updated = pvr2_hdw_state_update(hdw);
-
- analog_mode = (hdw->pathway_state != PVR2_PATHWAY_DIGITAL);
-
- /* Update master state based upon all other states. */
- if (!hdw->flag_ok) {
- st = PVR2_STATE_DEAD;
- } else if (hdw->fw1_state != FW1_STATE_OK) {
- st = PVR2_STATE_COLD;
- } else if ((analog_mode ||
- hdw->hdw_desc->flag_digital_requires_cx23416) &&
- !hdw->state_encoder_ok) {
- st = PVR2_STATE_WARM;
- } else if (hdw->flag_tripped ||
- (analog_mode && hdw->flag_decoder_missed)) {
- st = PVR2_STATE_ERROR;
- } else if (hdw->state_usbstream_run &&
- (!analog_mode ||
- (hdw->state_encoder_run && hdw->state_decoder_run))) {
- st = PVR2_STATE_RUN;
- } else {
- st = PVR2_STATE_READY;
- }
- if (hdw->master_state != st) {
- pvr2_trace(PVR2_TRACE_STATE,
- "Device state change from %s to %s",
- pvr2_get_state_name(hdw->master_state),
- pvr2_get_state_name(st));
- pvr2_led_ctrl(hdw,st == PVR2_STATE_RUN);
- hdw->master_state = st;
- state_updated = !0;
- callback_flag = !0;
- }
- if (state_updated) {
- /* Trigger anyone waiting on any state changes here. */
- wake_up(&hdw->state_wait_data);
- }
-
- if (pvrusb2_debug & PVR2_TRACE_STBITS) {
- pvr2_hdw_state_log_state(hdw);
- }
- pvr2_trace(PVR2_TRACE_STBITS,
- "Drive state check DONE callback=%d",callback_flag);
-
- return callback_flag;
-}
-
-
-/* Cause kernel thread to check / update driver state */
-static void pvr2_hdw_state_sched(struct pvr2_hdw *hdw)
-{
- if (hdw->state_stale) return;
- hdw->state_stale = !0;
- trace_stbit("state_stale",hdw->state_stale);
- queue_work(hdw->workqueue,&hdw->workpoll);
-}
-
-
-int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
-{
- return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
-}
-
-
-int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
-{
- return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
-}
-
-
-int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
-{
- return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
-}
-
-
-int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
-{
- u32 cval,nval;
- int ret;
- if (~msk) {
- ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval);
- if (ret) return ret;
- nval = (cval & ~msk) | (val & msk);
- pvr2_trace(PVR2_TRACE_GPIO,
- "GPIO direction changing 0x%x:0x%x"
- " from 0x%x to 0x%x",
- msk,val,cval,nval);
- } else {
- nval = val;
- pvr2_trace(PVR2_TRACE_GPIO,
- "GPIO direction changing to 0x%x",nval);
- }
- return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
-}
-
-
-int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
-{
- u32 cval,nval;
- int ret;
- if (~msk) {
- ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval);
- if (ret) return ret;
- nval = (cval & ~msk) | (val & msk);
- pvr2_trace(PVR2_TRACE_GPIO,
- "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
- msk,val,cval,nval);
- } else {
- nval = val;
- pvr2_trace(PVR2_TRACE_GPIO,
- "GPIO output changing to 0x%x",nval);
- }
- return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
-}
-
-
-void pvr2_hdw_status_poll(struct pvr2_hdw *hdw)
-{
- struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
- memset(vtp, 0, sizeof(*vtp));
- vtp->type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
- V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- hdw->tuner_signal_stale = 0;
- /* Note: There apparently is no replacement for VIDIOC_CROPCAP
- using v4l2-subdev - therefore we can't support that AT ALL right
- now. (Of course, no sub-drivers seem to implement it either.
- But now it's a a chicken and egg problem...) */
- v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, g_tuner, vtp);
- pvr2_trace(PVR2_TRACE_CHIPS, "subdev status poll"
- " type=%u strength=%u audio=0x%x cap=0x%x"
- " low=%u hi=%u",
- vtp->type,
- vtp->signal, vtp->rxsubchans, vtp->capability,
- vtp->rangelow, vtp->rangehigh);
-
- /* We have to do this to avoid getting into constant polling if
- there's nobody to answer a poll of cropcap info. */
- hdw->cropcap_stale = 0;
-}
-
-
-unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *hdw)
-{
- return hdw->input_avail_mask;
-}
-
-
-unsigned int pvr2_hdw_get_input_allowed(struct pvr2_hdw *hdw)
-{
- return hdw->input_allowed_mask;
-}
-
-
-static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v)
-{
- if (hdw->input_val != v) {
- hdw->input_val = v;
- hdw->input_dirty = !0;
- }
-
- /* Handle side effects - if we switch to a mode that needs the RF
- tuner, then select the right frequency choice as well and mark
- it dirty. */
- if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
- hdw->freqSelector = 0;
- hdw->freqDirty = !0;
- } else if ((hdw->input_val == PVR2_CVAL_INPUT_TV) ||
- (hdw->input_val == PVR2_CVAL_INPUT_DTV)) {
- hdw->freqSelector = 1;
- hdw->freqDirty = !0;
- }
- return 0;
-}
-
-
-int pvr2_hdw_set_input_allowed(struct pvr2_hdw *hdw,
- unsigned int change_mask,
- unsigned int change_val)
-{
- int ret = 0;
- unsigned int nv,m,idx;
- LOCK_TAKE(hdw->big_lock);
- do {
- nv = hdw->input_allowed_mask & ~change_mask;
- nv |= (change_val & change_mask);
- nv &= hdw->input_avail_mask;
- if (!nv) {
- /* No legal modes left; return error instead. */
- ret = -EPERM;
- break;
- }
- hdw->input_allowed_mask = nv;
- if ((1 << hdw->input_val) & hdw->input_allowed_mask) {
- /* Current mode is still in the allowed mask, so
- we're done. */
- break;
- }
- /* Select and switch to a mode that is still in the allowed
- mask */
- if (!hdw->input_allowed_mask) {
- /* Nothing legal; give up */
- break;
- }
- m = hdw->input_allowed_mask;
- for (idx = 0; idx < (sizeof(m) << 3); idx++) {
- if (!((1 << idx) & m)) continue;
- pvr2_hdw_set_input(hdw,idx);
- break;
- }
- } while (0);
- LOCK_GIVE(hdw->big_lock);
- return ret;
-}
-
-
-/* Find I2C address of eeprom */
-static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
-{
- int result;
- LOCK_TAKE(hdw->ctl_lock); do {
- hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
- result = pvr2_send_request(hdw,
- hdw->cmd_buffer,1,
- hdw->cmd_buffer,1);
- if (result < 0) break;
- result = hdw->cmd_buffer[0];
- } while(0); LOCK_GIVE(hdw->ctl_lock);
- return result;
-}
-
-
-int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
- struct v4l2_dbg_match *match, u64 reg_id,
- int setFl, u64 *val_ptr)
-{
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- struct v4l2_dbg_register req;
- int stat = 0;
- int okFl = 0;
-
- if (!capable(CAP_SYS_ADMIN)) return -EPERM;
-
- req.match = *match;
- req.reg = reg_id;
- if (setFl) req.val = *val_ptr;
- /* It would be nice to know if a sub-device answered the request */
- v4l2_device_call_all(&hdw->v4l2_dev, 0, core, g_register, &req);
- if (!setFl) *val_ptr = req.val;
- if (okFl) {
- return stat;
- }
- return -EINVAL;
-#else
- return -ENOSYS;
-#endif
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
deleted file mode 100644
index 8060fc666ee..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __PVRUSB2_HDW_H
-#define __PVRUSB2_HDW_H
-
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include "pvrusb2-io.h"
-#include "pvrusb2-ctrl.h"
-
-
-/* Private internal control ids, look these up with
- pvr2_hdw_get_ctrl_by_id() - these are NOT visible in V4L */
-#define PVR2_CID_STDCUR 2
-#define PVR2_CID_STDAVAIL 3
-#define PVR2_CID_INPUT 4
-#define PVR2_CID_AUDIOMODE 5
-#define PVR2_CID_FREQUENCY 6
-#define PVR2_CID_HRES 7
-#define PVR2_CID_VRES 8
-#define PVR2_CID_CROPL 9
-#define PVR2_CID_CROPT 10
-#define PVR2_CID_CROPW 11
-#define PVR2_CID_CROPH 12
-#define PVR2_CID_CROPCAPPAN 13
-#define PVR2_CID_CROPCAPPAD 14
-#define PVR2_CID_CROPCAPBL 15
-#define PVR2_CID_CROPCAPBT 16
-#define PVR2_CID_CROPCAPBW 17
-#define PVR2_CID_CROPCAPBH 18
-#define PVR2_CID_STDDETECT 19
-
-/* Legal values for the INPUT state variable */
-#define PVR2_CVAL_INPUT_TV 0
-#define PVR2_CVAL_INPUT_DTV 1
-#define PVR2_CVAL_INPUT_COMPOSITE 2
-#define PVR2_CVAL_INPUT_SVIDEO 3
-#define PVR2_CVAL_INPUT_RADIO 4
-
-enum pvr2_config {
- pvr2_config_empty, /* No configuration */
- pvr2_config_mpeg, /* Encoded / compressed video */
- pvr2_config_vbi, /* Standard vbi info */
- pvr2_config_pcm, /* Audio raw pcm stream */
- pvr2_config_rawvideo, /* Video raw frames */
-};
-
-enum pvr2_v4l_type {
- pvr2_v4l_type_video,
- pvr2_v4l_type_vbi,
- pvr2_v4l_type_radio,
-};
-
-/* Major states that we can be in:
- *
- * DEAD - Device is in an unusable state and cannot be recovered. This
- * can happen if we completely lose the ability to communicate with it
- * (but it might still on the bus). In this state there's nothing we can
- * do; it must be replugged in order to recover.
- *
- * COLD - Device is in an unusable state, needs microcontroller firmware.
- *
- * WARM - We can communicate with the device and the proper
- * microcontroller firmware is running, but other device initialization is
- * still needed (e.g. encoder firmware).
- *
- * ERROR - A problem prevents capture operation (e.g. encoder firmware
- * missing).
- *
- * READY - Device is operational, but not streaming.
- *
- * RUN - Device is streaming.
- *
- */
-#define PVR2_STATE_NONE 0
-#define PVR2_STATE_DEAD 1
-#define PVR2_STATE_COLD 2
-#define PVR2_STATE_WARM 3
-#define PVR2_STATE_ERROR 4
-#define PVR2_STATE_READY 5
-#define PVR2_STATE_RUN 6
-
-/* Translate configuration enum to a string label */
-const char *pvr2_config_get_name(enum pvr2_config);
-
-struct pvr2_hdw;
-
-/* Create and return a structure for interacting with the underlying
- hardware */
-struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
- const struct usb_device_id *devid);
-
-/* Perform second stage initialization, passing in a notification callback
- for when the master state changes. */
-int pvr2_hdw_initialize(struct pvr2_hdw *,
- void (*callback_func)(void *),
- void *callback_data);
-
-/* Destroy hardware interaction structure */
-void pvr2_hdw_destroy(struct pvr2_hdw *);
-
-/* Return true if in the ready (normal) state */
-int pvr2_hdw_dev_ok(struct pvr2_hdw *);
-
-/* Return small integer number [1..N] for logical instance number of this
- device. This is useful for indexing array-valued module parameters. */
-int pvr2_hdw_get_unit_number(struct pvr2_hdw *);
-
-/* Get pointer to underlying USB device */
-struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *);
-
-/* Retrieve serial number of device */
-unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *);
-
-/* Retrieve bus location info of device */
-const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *);
-
-/* Retrieve per-instance string identifier for this specific device */
-const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *);
-
-/* Called when hardware has been unplugged */
-void pvr2_hdw_disconnect(struct pvr2_hdw *);
-
-/* Get the number of defined controls */
-unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *);
-
-/* Retrieve a control handle given its index (0..count-1) */
-struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *,unsigned int);
-
-/* Retrieve a control handle given its internal ID (if any) */
-struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *,unsigned int);
-
-/* Retrieve a control handle given its V4L ID (if any) */
-struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *,unsigned int ctl_id);
-
-/* Retrieve a control handle given its immediate predecessor V4L ID (if any) */
-struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *,
- unsigned int ctl_id);
-
-/* Commit all control changes made up to this point */
-int pvr2_hdw_commit_ctl(struct pvr2_hdw *);
-
-/* Return a bit mask of valid input selections for this device. Mask bits
- * will be according to PVR_CVAL_INPUT_xxxx definitions. */
-unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *);
-
-/* Return a bit mask of allowed input selections for this device. Mask bits
- * will be according to PVR_CVAL_INPUT_xxxx definitions. */
-unsigned int pvr2_hdw_get_input_allowed(struct pvr2_hdw *);
-
-/* Change the set of allowed input selections for this device. Both
- change_mask and change_valu are mask bits according to
- PVR_CVAL_INPUT_xxxx definitions. The change_mask parameter indicate
- which settings are being changed and the change_val parameter indicates
- whether corresponding settings are being set or cleared. */
-int pvr2_hdw_set_input_allowed(struct pvr2_hdw *,
- unsigned int change_mask,
- unsigned int change_val);
-
-/* Return name for this driver instance */
-const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *);
-
-/* Mark tuner status stale so that it will be re-fetched */
-void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *);
-
-/* Return information about the tuner */
-int pvr2_hdw_get_tuner_status(struct pvr2_hdw *,struct v4l2_tuner *);
-
-/* Return information about cropping capabilities */
-int pvr2_hdw_get_cropcap(struct pvr2_hdw *, struct v4l2_cropcap *);
-
-/* Query device and see if it thinks it is on a high-speed USB link */
-int pvr2_hdw_is_hsm(struct pvr2_hdw *);
-
-/* Return a string token representative of the hardware type */
-const char *pvr2_hdw_get_type(struct pvr2_hdw *);
-
-/* Return a single line description of the hardware type */
-const char *pvr2_hdw_get_desc(struct pvr2_hdw *);
-
-/* Turn streaming on/off */
-int pvr2_hdw_set_streaming(struct pvr2_hdw *,int);
-
-/* Find out if streaming is on */
-int pvr2_hdw_get_streaming(struct pvr2_hdw *);
-
-/* Retrieve driver overall state */
-int pvr2_hdw_get_state(struct pvr2_hdw *);
-
-/* Configure the type of stream to generate */
-int pvr2_hdw_set_stream_type(struct pvr2_hdw *, enum pvr2_config);
-
-/* Get handle to video output stream */
-struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *);
-
-/* Enable / disable retrieval of CPU firmware or prom contents. This must
- be enabled before pvr2_hdw_cpufw_get() will function. Note that doing
- this may prevent the device from running (and leaving this mode may
- imply a device reset). */
-void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *,
- int mode, /* 0=8KB FX2, 1=16KB FX2, 2=PROM */
- int enable_flag);
-
-/* Return true if we're in a mode for retrieval CPU firmware */
-int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *);
-
-/* Retrieve a piece of the CPU's firmware at the given offset. Return
- value is the number of bytes retrieved or zero if we're past the end or
- an error otherwise (e.g. if firmware retrieval is not enabled). */
-int pvr2_hdw_cpufw_get(struct pvr2_hdw *,unsigned int offs,
- char *buf,unsigned int cnt);
-
-/* Retrieve a previously stored v4l minor device number */
-int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *,enum pvr2_v4l_type index);
-
-/* Store a v4l minor device number */
-void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,
- enum pvr2_v4l_type index,int);
-
-/* Direct read/write access to chip's registers:
- match - specify criteria to identify target chip (this is a v4l dbg struct)
- reg_id - register number to access
- setFl - true to set the register, false to read it
- val_ptr - storage location for source / result. */
-int pvr2_hdw_register_access(struct pvr2_hdw *,
- struct v4l2_dbg_match *match, u64 reg_id,
- int setFl, u64 *val_ptr);
-
-/* The following entry points are all lower level things you normally don't
- want to worry about. */
-
-/* Issue a command and get a response from the device. LOTS of higher
- level stuff is built on this. */
-int pvr2_send_request(struct pvr2_hdw *,
- void *write_ptr,unsigned int write_len,
- void *read_ptr,unsigned int read_len);
-
-/* Slightly higher level device communication functions. */
-int pvr2_write_register(struct pvr2_hdw *, u16, u32);
-
-/* Call if for any reason we can't talk to the hardware anymore - this will
- cause the driver to stop flailing on the device. */
-void pvr2_hdw_render_useless(struct pvr2_hdw *);
-
-/* Set / clear 8051's reset bit */
-void pvr2_hdw_cpureset_assert(struct pvr2_hdw *,int);
-
-/* Execute a USB-commanded device reset */
-void pvr2_hdw_device_reset(struct pvr2_hdw *);
-
-/* Reset worker's error trapping circuit breaker */
-int pvr2_hdw_untrip(struct pvr2_hdw *);
-
-/* Execute hard reset command (after this point it's likely that the
- encoder will have to be reconfigured). This also clears the "useless"
- state. */
-int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *);
-
-/* Execute simple reset command */
-int pvr2_hdw_cmd_powerup(struct pvr2_hdw *);
-
-/* suspend */
-int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *);
-
-/* Order decoder to reset */
-int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *);
-
-/* Direct manipulation of GPIO bits */
-int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *);
-int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *);
-int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *);
-int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val);
-int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val);
-
-/* This data structure is specifically for the next function... */
-struct pvr2_hdw_debug_info {
- int big_lock_held;
- int ctl_lock_held;
- int flag_disconnected;
- int flag_init_ok;
- int flag_ok;
- int fw1_state;
- int flag_decoder_missed;
- int flag_tripped;
- int state_encoder_ok;
- int state_encoder_run;
- int state_decoder_run;
- int state_decoder_ready;
- int state_usbstream_run;
- int state_decoder_quiescent;
- int state_pipeline_config;
- int state_pipeline_req;
- int state_pipeline_pause;
- int state_pipeline_idle;
- int cmd_debug_state;
- int cmd_debug_write_len;
- int cmd_debug_read_len;
- int cmd_debug_write_pend;
- int cmd_debug_read_pend;
- int cmd_debug_timeout;
- int cmd_debug_rstatus;
- int cmd_debug_wstatus;
- unsigned char cmd_code;
-};
-
-/* Non-intrusively retrieve internal state info - this is useful for
- diagnosing lockups. Note that this operation is completed without any
- kind of locking and so it is not atomic and may yield inconsistent
- results. This is *purely* a debugging aid. */
-void pvr2_hdw_get_debug_info_unlocked(const struct pvr2_hdw *hdw,
- struct pvr2_hdw_debug_info *);
-
-/* Intrusively retrieve internal state info - this is useful for
- diagnosing overall driver state. This operation synchronizes against
- the overall driver mutex - so if there are locking problems this will
- likely hang! This is *purely* a debugging aid. */
-void pvr2_hdw_get_debug_info_locked(struct pvr2_hdw *hdw,
- struct pvr2_hdw_debug_info *);
-
-/* Report out several lines of text that describes driver internal state.
- Results are written into the passed-in buffer. */
-unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
- char *buf_ptr,unsigned int buf_size);
-
-/* Cause modules to log their state once */
-void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw);
-
-/* Cause encoder firmware to be uploaded into the device. This is normally
- done autonomously, but the interface is exported here because it is also
- a debugging aid. */
-int pvr2_upload_firmware2(struct pvr2_hdw *hdw);
-
-#endif /* __PVRUSB2_HDW_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
deleted file mode 100644
index 885ce11f222..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ /dev/null
@@ -1,698 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/i2c.h>
-#include <linux/module.h>
-#include <media/ir-kbd-i2c.h>
-#include "pvrusb2-i2c-core.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include "pvrusb2-fx2-cmd.h"
-#include "pvrusb2.h"
-
-#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
-
-/*
-
- This module attempts to implement a compliant I2C adapter for the pvrusb2
- device.
-
-*/
-
-static unsigned int i2c_scan;
-module_param(i2c_scan, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
-
-static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
-module_param_array(ir_mode, int, NULL, 0444);
-MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
-
-static int pvr2_disable_ir_video;
-module_param_named(disable_autoload_ir_video, pvr2_disable_ir_video,
- int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(disable_autoload_ir_video,
- "1=do not try to autoload ir_video IR receiver");
-
-static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */
- u8 i2c_addr, /* I2C address we're talking to */
- u8 *data, /* Data to write */
- u16 length) /* Size of data to write */
-{
- /* Return value - default 0 means success */
- int ret;
-
-
- if (!data) length = 0;
- if (length > (sizeof(hdw->cmd_buffer) - 3)) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Killing an I2C write to %u that is too large"
- " (desired=%u limit=%u)",
- i2c_addr,
- length,(unsigned int)(sizeof(hdw->cmd_buffer) - 3));
- return -ENOTSUPP;
- }
-
- LOCK_TAKE(hdw->ctl_lock);
-
- /* Clear the command buffer (likely to be paranoia) */
- memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer));
-
- /* Set up command buffer for an I2C write */
- hdw->cmd_buffer[0] = FX2CMD_I2C_WRITE; /* write prefix */
- hdw->cmd_buffer[1] = i2c_addr; /* i2c addr of chip */
- hdw->cmd_buffer[2] = length; /* length of what follows */
- if (length) memcpy(hdw->cmd_buffer + 3, data, length);
-
- /* Do the operation */
- ret = pvr2_send_request(hdw,
- hdw->cmd_buffer,
- length + 3,
- hdw->cmd_buffer,
- 1);
- if (!ret) {
- if (hdw->cmd_buffer[0] != 8) {
- ret = -EIO;
- if (hdw->cmd_buffer[0] != 7) {
- trace_i2c("unexpected status"
- " from i2_write[%d]: %d",
- i2c_addr,hdw->cmd_buffer[0]);
- }
- }
- }
-
- LOCK_GIVE(hdw->ctl_lock);
-
- return ret;
-}
-
-static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */
- u8 i2c_addr, /* I2C address we're talking to */
- u8 *data, /* Data to write */
- u16 dlen, /* Size of data to write */
- u8 *res, /* Where to put data we read */
- u16 rlen) /* Amount of data to read */
-{
- /* Return value - default 0 means success */
- int ret;
-
-
- if (!data) dlen = 0;
- if (dlen > (sizeof(hdw->cmd_buffer) - 4)) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Killing an I2C read to %u that has wlen too large"
- " (desired=%u limit=%u)",
- i2c_addr,
- dlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 4));
- return -ENOTSUPP;
- }
- if (res && (rlen > (sizeof(hdw->cmd_buffer) - 1))) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Killing an I2C read to %u that has rlen too large"
- " (desired=%u limit=%u)",
- i2c_addr,
- rlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 1));
- return -ENOTSUPP;
- }
-
- LOCK_TAKE(hdw->ctl_lock);
-
- /* Clear the command buffer (likely to be paranoia) */
- memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer));
-
- /* Set up command buffer for an I2C write followed by a read */
- hdw->cmd_buffer[0] = FX2CMD_I2C_READ; /* read prefix */
- hdw->cmd_buffer[1] = dlen; /* arg length */
- hdw->cmd_buffer[2] = rlen; /* answer length. Device will send one
- more byte (status). */
- hdw->cmd_buffer[3] = i2c_addr; /* i2c addr of chip */
- if (dlen) memcpy(hdw->cmd_buffer + 4, data, dlen);
-
- /* Do the operation */
- ret = pvr2_send_request(hdw,
- hdw->cmd_buffer,
- 4 + dlen,
- hdw->cmd_buffer,
- rlen + 1);
- if (!ret) {
- if (hdw->cmd_buffer[0] != 8) {
- ret = -EIO;
- if (hdw->cmd_buffer[0] != 7) {
- trace_i2c("unexpected status"
- " from i2_read[%d]: %d",
- i2c_addr,hdw->cmd_buffer[0]);
- }
- }
- }
-
- /* Copy back the result */
- if (res && rlen) {
- if (ret) {
- /* Error, just blank out the return buffer */
- memset(res, 0, rlen);
- } else {
- memcpy(res, hdw->cmd_buffer + 1, rlen);
- }
- }
-
- LOCK_GIVE(hdw->ctl_lock);
-
- return ret;
-}
-
-/* This is the common low level entry point for doing I2C operations to the
- hardware. */
-static int pvr2_i2c_basic_op(struct pvr2_hdw *hdw,
- u8 i2c_addr,
- u8 *wdata,
- u16 wlen,
- u8 *rdata,
- u16 rlen)
-{
- if (!rdata) rlen = 0;
- if (!wdata) wlen = 0;
- if (rlen || !wlen) {
- return pvr2_i2c_read(hdw,i2c_addr,wdata,wlen,rdata,rlen);
- } else {
- return pvr2_i2c_write(hdw,i2c_addr,wdata,wlen);
- }
-}
-
-
-/* This is a special entry point for cases of I2C transaction attempts to
- the IR receiver. The implementation here simulates the IR receiver by
- issuing a command to the FX2 firmware and using that response to return
- what the real I2C receiver would have returned. We use this for 24xxx
- devices, where the IR receiver chip has been removed and replaced with
- FX2 related logic. */
-static int i2c_24xxx_ir(struct pvr2_hdw *hdw,
- u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
-{
- u8 dat[4];
- unsigned int stat;
-
- if (!(rlen || wlen)) {
- /* This is a probe attempt. Just let it succeed. */
- return 0;
- }
-
- /* We don't understand this kind of transaction */
- if ((wlen != 0) || (rlen == 0)) return -EIO;
-
- if (rlen < 3) {
- /* Mike Isely <isely@pobox.com> Appears to be a probe
- attempt from lirc. Just fill in zeroes and return. If
- we try instead to do the full transaction here, then bad
- things seem to happen within the lirc driver module
- (version 0.8.0-7 sources from Debian, when run under
- vanilla 2.6.17.6 kernel) - and I don't have the patience
- to chase it down. */
- if (rlen > 0) rdata[0] = 0;
- if (rlen > 1) rdata[1] = 0;
- return 0;
- }
-
- /* Issue a command to the FX2 to read the IR receiver. */
- LOCK_TAKE(hdw->ctl_lock); do {
- hdw->cmd_buffer[0] = FX2CMD_GET_IR_CODE;
- stat = pvr2_send_request(hdw,
- hdw->cmd_buffer,1,
- hdw->cmd_buffer,4);
- dat[0] = hdw->cmd_buffer[0];
- dat[1] = hdw->cmd_buffer[1];
- dat[2] = hdw->cmd_buffer[2];
- dat[3] = hdw->cmd_buffer[3];
- } while (0); LOCK_GIVE(hdw->ctl_lock);
-
- /* Give up if that operation failed. */
- if (stat != 0) return stat;
-
- /* Mangle the results into something that looks like the real IR
- receiver. */
- rdata[2] = 0xc1;
- if (dat[0] != 1) {
- /* No code received. */
- rdata[0] = 0;
- rdata[1] = 0;
- } else {
- u16 val;
- /* Mash the FX2 firmware-provided IR code into something
- that the normal i2c chip-level driver expects. */
- val = dat[1];
- val <<= 8;
- val |= dat[2];
- val >>= 1;
- val &= ~0x0003;
- val |= 0x8000;
- rdata[0] = (val >> 8) & 0xffu;
- rdata[1] = val & 0xffu;
- }
-
- return 0;
-}
-
-/* This is a special entry point that is entered if an I2C operation is
- attempted to a wm8775 chip on model 24xxx hardware. Autodetect of this
- part doesn't work, but we know it is really there. So let's look for
- the autodetect attempt and just return success if we see that. */
-static int i2c_hack_wm8775(struct pvr2_hdw *hdw,
- u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
-{
- if (!(rlen || wlen)) {
- // This is a probe attempt. Just let it succeed.
- return 0;
- }
- return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
-}
-
-/* This is an entry point designed to always fail any attempt to perform a
- transfer. We use this to cause certain I2C addresses to not be
- probed. */
-static int i2c_black_hole(struct pvr2_hdw *hdw,
- u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
-{
- return -EIO;
-}
-
-/* This is a special entry point that is entered if an I2C operation is
- attempted to a cx25840 chip on model 24xxx hardware. This chip can
- sometimes wedge itself. Worse still, when this happens msp3400 can
- falsely detect this part and then the system gets hosed up after msp3400
- gets confused and dies. What we want to do here is try to keep msp3400
- away and also try to notice if the chip is wedged and send a warning to
- the system log. */
-static int i2c_hack_cx25840(struct pvr2_hdw *hdw,
- u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
-{
- int ret;
- unsigned int subaddr;
- u8 wbuf[2];
- int state = hdw->i2c_cx25840_hack_state;
-
- if (!(rlen || wlen)) {
- // Probe attempt - always just succeed and don't bother the
- // hardware (this helps to make the state machine further
- // down somewhat easier).
- return 0;
- }
-
- if (state == 3) {
- return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
- }
-
- /* We're looking for the exact pattern where the revision register
- is being read. The cx25840 module will always look at the
- revision register first. Any other pattern of access therefore
- has to be a probe attempt from somebody else so we'll reject it.
- Normally we could just let each client just probe the part
- anyway, but when the cx25840 is wedged, msp3400 will get a false
- positive and that just screws things up... */
-
- if (wlen == 0) {
- switch (state) {
- case 1: subaddr = 0x0100; break;
- case 2: subaddr = 0x0101; break;
- default: goto fail;
- }
- } else if (wlen == 2) {
- subaddr = (wdata[0] << 8) | wdata[1];
- switch (subaddr) {
- case 0x0100: state = 1; break;
- case 0x0101: state = 2; break;
- default: goto fail;
- }
- } else {
- goto fail;
- }
- if (!rlen) goto success;
- state = 0;
- if (rlen != 1) goto fail;
-
- /* If we get to here then we have a legitimate read for one of the
- two revision bytes, so pass it through. */
- wbuf[0] = subaddr >> 8;
- wbuf[1] = subaddr;
- ret = pvr2_i2c_basic_op(hdw,i2c_addr,wbuf,2,rdata,rlen);
-
- if ((ret != 0) || (*rdata == 0x04) || (*rdata == 0x0a)) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "WARNING: Detected a wedged cx25840 chip;"
- " the device will not work.");
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "WARNING: Try power cycling the pvrusb2 device.");
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "WARNING: Disabling further access to the device"
- " to prevent other foul-ups.");
- // This blocks all further communication with the part.
- hdw->i2c_func[0x44] = NULL;
- pvr2_hdw_render_useless(hdw);
- goto fail;
- }
-
- /* Success! */
- pvr2_trace(PVR2_TRACE_CHIPS,"cx25840 appears to be OK.");
- state = 3;
-
- success:
- hdw->i2c_cx25840_hack_state = state;
- return 0;
-
- fail:
- hdw->i2c_cx25840_hack_state = state;
- return -EIO;
-}
-
-/* This is a very, very limited I2C adapter implementation. We can only
- support what we actually know will work on the device... */
-static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg msgs[],
- int num)
-{
- int ret = -ENOTSUPP;
- pvr2_i2c_func funcp = NULL;
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)(i2c_adap->algo_data);
-
- if (!num) {
- ret = -EINVAL;
- goto done;
- }
- if (msgs[0].addr < PVR2_I2C_FUNC_CNT) {
- funcp = hdw->i2c_func[msgs[0].addr];
- }
- if (!funcp) {
- ret = -EIO;
- goto done;
- }
-
- if (num == 1) {
- if (msgs[0].flags & I2C_M_RD) {
- /* Simple read */
- u16 tcnt,bcnt,offs;
- if (!msgs[0].len) {
- /* Length == 0 read. This is a probe. */
- if (funcp(hdw,msgs[0].addr,NULL,0,NULL,0)) {
- ret = -EIO;
- goto done;
- }
- ret = 1;
- goto done;
- }
- /* If the read is short enough we'll do the whole
- thing atomically. Otherwise we have no choice
- but to break apart the reads. */
- tcnt = msgs[0].len;
- offs = 0;
- while (tcnt) {
- bcnt = tcnt;
- if (bcnt > sizeof(hdw->cmd_buffer)-1) {
- bcnt = sizeof(hdw->cmd_buffer)-1;
- }
- if (funcp(hdw,msgs[0].addr,NULL,0,
- msgs[0].buf+offs,bcnt)) {
- ret = -EIO;
- goto done;
- }
- offs += bcnt;
- tcnt -= bcnt;
- }
- ret = 1;
- goto done;
- } else {
- /* Simple write */
- ret = 1;
- if (funcp(hdw,msgs[0].addr,
- msgs[0].buf,msgs[0].len,NULL,0)) {
- ret = -EIO;
- }
- goto done;
- }
- } else if (num == 2) {
- if (msgs[0].addr != msgs[1].addr) {
- trace_i2c("i2c refusing 2 phase transfer with"
- " conflicting target addresses");
- ret = -ENOTSUPP;
- goto done;
- }
- if ((!((msgs[0].flags & I2C_M_RD))) &&
- (msgs[1].flags & I2C_M_RD)) {
- u16 tcnt,bcnt,wcnt,offs;
- /* Write followed by atomic read. If the read
- portion is short enough we'll do the whole thing
- atomically. Otherwise we have no choice but to
- break apart the reads. */
- tcnt = msgs[1].len;
- wcnt = msgs[0].len;
- offs = 0;
- while (tcnt || wcnt) {
- bcnt = tcnt;
- if (bcnt > sizeof(hdw->cmd_buffer)-1) {
- bcnt = sizeof(hdw->cmd_buffer)-1;
- }
- if (funcp(hdw,msgs[0].addr,
- msgs[0].buf,wcnt,
- msgs[1].buf+offs,bcnt)) {
- ret = -EIO;
- goto done;
- }
- offs += bcnt;
- tcnt -= bcnt;
- wcnt = 0;
- }
- ret = 2;
- goto done;
- } else {
- trace_i2c("i2c refusing complex transfer"
- " read0=%d read1=%d",
- (msgs[0].flags & I2C_M_RD),
- (msgs[1].flags & I2C_M_RD));
- }
- } else {
- trace_i2c("i2c refusing %d phase transfer",num);
- }
-
- done:
- if (pvrusb2_debug & PVR2_TRACE_I2C_TRAF) {
- unsigned int idx,offs,cnt;
- for (idx = 0; idx < num; idx++) {
- cnt = msgs[idx].len;
- printk(KERN_INFO
- "pvrusb2 i2c xfer %u/%u:"
- " addr=0x%x len=%d %s",
- idx+1,num,
- msgs[idx].addr,
- cnt,
- (msgs[idx].flags & I2C_M_RD ?
- "read" : "write"));
- if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) {
- if (cnt > 8) cnt = 8;
- printk(" [");
- for (offs = 0; offs < (cnt>8?8:cnt); offs++) {
- if (offs) printk(" ");
- printk("%02x",msgs[idx].buf[offs]);
- }
- if (offs < cnt) printk(" ...");
- printk("]");
- }
- if (idx+1 == num) {
- printk(" result=%d",ret);
- }
- printk("\n");
- }
- if (!num) {
- printk(KERN_INFO
- "pvrusb2 i2c xfer null transfer result=%d\n",
- ret);
- }
- }
- return ret;
-}
-
-static u32 pvr2_i2c_functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm pvr2_i2c_algo_template = {
- .master_xfer = pvr2_i2c_xfer,
- .functionality = pvr2_i2c_functionality,
-};
-
-static struct i2c_adapter pvr2_i2c_adap_template = {
- .owner = THIS_MODULE,
- .class = 0,
-};
-
-
-/* Return true if device exists at given address */
-static int do_i2c_probe(struct pvr2_hdw *hdw, int addr)
-{
- struct i2c_msg msg[1];
- int rc;
- msg[0].addr = 0;
- msg[0].flags = I2C_M_RD;
- msg[0].len = 0;
- msg[0].buf = NULL;
- msg[0].addr = addr;
- rc = i2c_transfer(&hdw->i2c_adap, msg, ARRAY_SIZE(msg));
- return rc == 1;
-}
-
-static void do_i2c_scan(struct pvr2_hdw *hdw)
-{
- int i;
- printk(KERN_INFO "%s: i2c scan beginning\n", hdw->name);
- for (i = 0; i < 128; i++) {
- if (do_i2c_probe(hdw, i)) {
- printk(KERN_INFO "%s: i2c scan: found device @ 0x%x\n",
- hdw->name, i);
- }
- }
- printk(KERN_INFO "%s: i2c scan done.\n", hdw->name);
-}
-
-static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
-{
- struct i2c_board_info info;
- struct IR_i2c_init_data *init_data = &hdw->ir_init_data;
- if (pvr2_disable_ir_video) {
- pvr2_trace(PVR2_TRACE_INFO,
- "Automatic binding of ir_video has been disabled.");
- return;
- }
- memset(&info, 0, sizeof(struct i2c_board_info));
- switch (hdw->ir_scheme_active) {
- case PVR2_IR_SCHEME_24XXX: /* FX2-controlled IR */
- case PVR2_IR_SCHEME_29XXX: /* Original 29xxx device */
- init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
- init_data->type = RC_TYPE_RC5;
- init_data->name = hdw->hdw_desc->description;
- init_data->polling_interval = 100; /* ms From ir-kbd-i2c */
- /* IR Receiver */
- info.addr = 0x18;
- info.platform_data = init_data;
- strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
- pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.",
- info.type, info.addr);
- i2c_new_device(&hdw->i2c_adap, &info);
- break;
- case PVR2_IR_SCHEME_ZILOG: /* HVR-1950 style */
- case PVR2_IR_SCHEME_24XXX_MCE: /* 24xxx MCE device */
- init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
- init_data->type = RC_TYPE_RC5;
- init_data->name = hdw->hdw_desc->description;
- /* IR Receiver */
- info.addr = 0x71;
- info.platform_data = init_data;
- strlcpy(info.type, "ir_rx_z8f0811_haup", I2C_NAME_SIZE);
- pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.",
- info.type, info.addr);
- i2c_new_device(&hdw->i2c_adap, &info);
- /* IR Trasmitter */
- info.addr = 0x70;
- info.platform_data = init_data;
- strlcpy(info.type, "ir_tx_z8f0811_haup", I2C_NAME_SIZE);
- pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.",
- info.type, info.addr);
- i2c_new_device(&hdw->i2c_adap, &info);
- break;
- default:
- /* The device either doesn't support I2C-based IR or we
- don't know (yet) how to operate IR on the device. */
- break;
- }
-}
-
-void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
-{
- unsigned int idx;
-
- /* The default action for all possible I2C addresses is just to do
- the transfer normally. */
- for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) {
- hdw->i2c_func[idx] = pvr2_i2c_basic_op;
- }
-
- /* However, deal with various special cases for 24xxx hardware. */
- if (ir_mode[hdw->unit_number] == 0) {
- printk(KERN_INFO "%s: IR disabled\n",hdw->name);
- hdw->i2c_func[0x18] = i2c_black_hole;
- } else if (ir_mode[hdw->unit_number] == 1) {
- if (hdw->ir_scheme_active == PVR2_IR_SCHEME_24XXX) {
- /* Set up translation so that our IR looks like a
- 29xxx device */
- hdw->i2c_func[0x18] = i2c_24xxx_ir;
- }
- }
- if (hdw->hdw_desc->flag_has_cx25840) {
- hdw->i2c_func[0x44] = i2c_hack_cx25840;
- }
- if (hdw->hdw_desc->flag_has_wm8775) {
- hdw->i2c_func[0x1b] = i2c_hack_wm8775;
- }
-
- // Configure the adapter and set up everything else related to it.
- memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap));
- memcpy(&hdw->i2c_algo,&pvr2_i2c_algo_template,sizeof(hdw->i2c_algo));
- strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name));
- hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev;
- hdw->i2c_adap.algo = &hdw->i2c_algo;
- hdw->i2c_adap.algo_data = hdw;
- hdw->i2c_linked = !0;
- i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev);
- i2c_add_adapter(&hdw->i2c_adap);
- if (hdw->i2c_func[0x18] == i2c_24xxx_ir) {
- /* Probe for a different type of IR receiver on this
- device. This is really the only way to differentiate
- older 24xxx devices from 24xxx variants that include an
- IR blaster. If the IR blaster is present, the IR
- receiver is part of that chip and thus we must disable
- the emulated IR receiver. */
- if (do_i2c_probe(hdw, 0x71)) {
- pvr2_trace(PVR2_TRACE_INFO,
- "Device has newer IR hardware;"
- " disabling unneeded virtual IR device");
- hdw->i2c_func[0x18] = NULL;
- /* Remember that this is a different device... */
- hdw->ir_scheme_active = PVR2_IR_SCHEME_24XXX_MCE;
- }
- }
- if (i2c_scan) do_i2c_scan(hdw);
-
- pvr2_i2c_register_ir(hdw);
-}
-
-void pvr2_i2c_core_done(struct pvr2_hdw *hdw)
-{
- if (hdw->i2c_linked) {
- i2c_del_adapter(&hdw->i2c_adap);
- hdw->i2c_linked = 0;
- }
-}
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
deleted file mode 100644
index 6a75769200b..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __PVRUSB2_I2C_CORE_H
-#define __PVRUSB2_I2C_CORE_H
-
-struct pvr2_hdw;
-
-void pvr2_i2c_core_init(struct pvr2_hdw *);
-void pvr2_i2c_core_done(struct pvr2_hdw *);
-
-
-#endif /* __PVRUSB2_I2C_ADAPTER_H */
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.c b/drivers/media/video/pvrusb2/pvrusb2-io.c
deleted file mode 100644
index 20b6ae0bb40..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-io.c
+++ /dev/null
@@ -1,695 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "pvrusb2-io.h"
-#include "pvrusb2-debug.h"
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-static const char *pvr2_buffer_state_decode(enum pvr2_buffer_state);
-
-#define BUFFER_SIG 0x47653271
-
-// #define SANITY_CHECK_BUFFERS
-
-
-#ifdef SANITY_CHECK_BUFFERS
-#define BUFFER_CHECK(bp) do { \
- if ((bp)->signature != BUFFER_SIG) { \
- pvr2_trace(PVR2_TRACE_ERROR_LEGS, \
- "Buffer %p is bad at %s:%d", \
- (bp),__FILE__,__LINE__); \
- pvr2_buffer_describe(bp,"BadSig"); \
- BUG(); \
- } \
-} while (0)
-#else
-#define BUFFER_CHECK(bp) do {} while(0)
-#endif
-
-struct pvr2_stream {
- /* Buffers queued for reading */
- struct list_head queued_list;
- unsigned int q_count;
- unsigned int q_bcount;
- /* Buffers with retrieved data */
- struct list_head ready_list;
- unsigned int r_count;
- unsigned int r_bcount;
- /* Buffers available for use */
- struct list_head idle_list;
- unsigned int i_count;
- unsigned int i_bcount;
- /* Pointers to all buffers */
- struct pvr2_buffer **buffers;
- /* Array size of buffers */
- unsigned int buffer_slot_count;
- /* Total buffers actually in circulation */
- unsigned int buffer_total_count;
- /* Designed number of buffers to be in circulation */
- unsigned int buffer_target_count;
- /* Executed when ready list become non-empty */
- pvr2_stream_callback callback_func;
- void *callback_data;
- /* Context for transfer endpoint */
- struct usb_device *dev;
- int endpoint;
- /* Overhead for mutex enforcement */
- spinlock_t list_lock;
- struct mutex mutex;
- /* Tracking state for tolerating errors */
- unsigned int fail_count;
- unsigned int fail_tolerance;
-
- unsigned int buffers_processed;
- unsigned int buffers_failed;
- unsigned int bytes_processed;
-};
-
-struct pvr2_buffer {
- int id;
- int signature;
- enum pvr2_buffer_state state;
- void *ptr; /* Pointer to storage area */
- unsigned int max_count; /* Size of storage area */
- unsigned int used_count; /* Amount of valid data in storage area */
- int status; /* Transfer result status */
- struct pvr2_stream *stream;
- struct list_head list_overhead;
- struct urb *purb;
-};
-
-static const char *pvr2_buffer_state_decode(enum pvr2_buffer_state st)
-{
- switch (st) {
- case pvr2_buffer_state_none: return "none";
- case pvr2_buffer_state_idle: return "idle";
- case pvr2_buffer_state_queued: return "queued";
- case pvr2_buffer_state_ready: return "ready";
- }
- return "unknown";
-}
-
-#ifdef SANITY_CHECK_BUFFERS
-static void pvr2_buffer_describe(struct pvr2_buffer *bp,const char *msg)
-{
- pvr2_trace(PVR2_TRACE_INFO,
- "buffer%s%s %p state=%s id=%d status=%d"
- " stream=%p purb=%p sig=0x%x",
- (msg ? " " : ""),
- (msg ? msg : ""),
- bp,
- (bp ? pvr2_buffer_state_decode(bp->state) : "(invalid)"),
- (bp ? bp->id : 0),
- (bp ? bp->status : 0),
- (bp ? bp->stream : NULL),
- (bp ? bp->purb : NULL),
- (bp ? bp->signature : 0));
-}
-#endif /* SANITY_CHECK_BUFFERS */
-
-static void pvr2_buffer_remove(struct pvr2_buffer *bp)
-{
- unsigned int *cnt;
- unsigned int *bcnt;
- unsigned int ccnt;
- struct pvr2_stream *sp = bp->stream;
- switch (bp->state) {
- case pvr2_buffer_state_idle:
- cnt = &sp->i_count;
- bcnt = &sp->i_bcount;
- ccnt = bp->max_count;
- break;
- case pvr2_buffer_state_queued:
- cnt = &sp->q_count;
- bcnt = &sp->q_bcount;
- ccnt = bp->max_count;
- break;
- case pvr2_buffer_state_ready:
- cnt = &sp->r_count;
- bcnt = &sp->r_bcount;
- ccnt = bp->used_count;
- break;
- default:
- return;
- }
- list_del_init(&bp->list_overhead);
- (*cnt)--;
- (*bcnt) -= ccnt;
- pvr2_trace(PVR2_TRACE_BUF_FLOW,
- "/*---TRACE_FLOW---*/"
- " bufferPool %8s dec cap=%07d cnt=%02d",
- pvr2_buffer_state_decode(bp->state),*bcnt,*cnt);
- bp->state = pvr2_buffer_state_none;
-}
-
-static void pvr2_buffer_set_none(struct pvr2_buffer *bp)
-{
- unsigned long irq_flags;
- struct pvr2_stream *sp;
- BUFFER_CHECK(bp);
- sp = bp->stream;
- pvr2_trace(PVR2_TRACE_BUF_FLOW,
- "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
- bp,
- pvr2_buffer_state_decode(bp->state),
- pvr2_buffer_state_decode(pvr2_buffer_state_none));
- spin_lock_irqsave(&sp->list_lock,irq_flags);
- pvr2_buffer_remove(bp);
- spin_unlock_irqrestore(&sp->list_lock,irq_flags);
-}
-
-static int pvr2_buffer_set_ready(struct pvr2_buffer *bp)
-{
- int fl;
- unsigned long irq_flags;
- struct pvr2_stream *sp;
- BUFFER_CHECK(bp);
- sp = bp->stream;
- pvr2_trace(PVR2_TRACE_BUF_FLOW,
- "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
- bp,
- pvr2_buffer_state_decode(bp->state),
- pvr2_buffer_state_decode(pvr2_buffer_state_ready));
- spin_lock_irqsave(&sp->list_lock,irq_flags);
- fl = (sp->r_count == 0);
- pvr2_buffer_remove(bp);
- list_add_tail(&bp->list_overhead,&sp->ready_list);
- bp->state = pvr2_buffer_state_ready;
- (sp->r_count)++;
- sp->r_bcount += bp->used_count;
- pvr2_trace(PVR2_TRACE_BUF_FLOW,
- "/*---TRACE_FLOW---*/"
- " bufferPool %8s inc cap=%07d cnt=%02d",
- pvr2_buffer_state_decode(bp->state),
- sp->r_bcount,sp->r_count);
- spin_unlock_irqrestore(&sp->list_lock,irq_flags);
- return fl;
-}
-
-static void pvr2_buffer_set_idle(struct pvr2_buffer *bp)
-{
- unsigned long irq_flags;
- struct pvr2_stream *sp;
- BUFFER_CHECK(bp);
- sp = bp->stream;
- pvr2_trace(PVR2_TRACE_BUF_FLOW,
- "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
- bp,
- pvr2_buffer_state_decode(bp->state),
- pvr2_buffer_state_decode(pvr2_buffer_state_idle));
- spin_lock_irqsave(&sp->list_lock,irq_flags);
- pvr2_buffer_remove(bp);
- list_add_tail(&bp->list_overhead,&sp->idle_list);
- bp->state = pvr2_buffer_state_idle;
- (sp->i_count)++;
- sp->i_bcount += bp->max_count;
- pvr2_trace(PVR2_TRACE_BUF_FLOW,
- "/*---TRACE_FLOW---*/"
- " bufferPool %8s inc cap=%07d cnt=%02d",
- pvr2_buffer_state_decode(bp->state),
- sp->i_bcount,sp->i_count);
- spin_unlock_irqrestore(&sp->list_lock,irq_flags);
-}
-
-static void pvr2_buffer_set_queued(struct pvr2_buffer *bp)
-{
- unsigned long irq_flags;
- struct pvr2_stream *sp;
- BUFFER_CHECK(bp);
- sp = bp->stream;
- pvr2_trace(PVR2_TRACE_BUF_FLOW,
- "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
- bp,
- pvr2_buffer_state_decode(bp->state),
- pvr2_buffer_state_decode(pvr2_buffer_state_queued));
- spin_lock_irqsave(&sp->list_lock,irq_flags);
- pvr2_buffer_remove(bp);
- list_add_tail(&bp->list_overhead,&sp->queued_list);
- bp->state = pvr2_buffer_state_queued;
- (sp->q_count)++;
- sp->q_bcount += bp->max_count;
- pvr2_trace(PVR2_TRACE_BUF_FLOW,
- "/*---TRACE_FLOW---*/"
- " bufferPool %8s inc cap=%07d cnt=%02d",
- pvr2_buffer_state_decode(bp->state),
- sp->q_bcount,sp->q_count);
- spin_unlock_irqrestore(&sp->list_lock,irq_flags);
-}
-
-static void pvr2_buffer_wipe(struct pvr2_buffer *bp)
-{
- if (bp->state == pvr2_buffer_state_queued) {
- usb_kill_urb(bp->purb);
- }
-}
-
-static int pvr2_buffer_init(struct pvr2_buffer *bp,
- struct pvr2_stream *sp,
- unsigned int id)
-{
- memset(bp,0,sizeof(*bp));
- bp->signature = BUFFER_SIG;
- bp->id = id;
- pvr2_trace(PVR2_TRACE_BUF_POOL,
- "/*---TRACE_FLOW---*/ bufferInit %p stream=%p",bp,sp);
- bp->stream = sp;
- bp->state = pvr2_buffer_state_none;
- INIT_LIST_HEAD(&bp->list_overhead);
- bp->purb = usb_alloc_urb(0,GFP_KERNEL);
- if (! bp->purb) return -ENOMEM;
-#ifdef SANITY_CHECK_BUFFERS
- pvr2_buffer_describe(bp,"create");
-#endif
- return 0;
-}
-
-static void pvr2_buffer_done(struct pvr2_buffer *bp)
-{
-#ifdef SANITY_CHECK_BUFFERS
- pvr2_buffer_describe(bp,"delete");
-#endif
- pvr2_buffer_wipe(bp);
- pvr2_buffer_set_none(bp);
- bp->signature = 0;
- bp->stream = NULL;
- usb_free_urb(bp->purb);
- pvr2_trace(PVR2_TRACE_BUF_POOL,"/*---TRACE_FLOW---*/"
- " bufferDone %p",bp);
-}
-
-static int pvr2_stream_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
-{
- int ret;
- unsigned int scnt;
-
- /* Allocate buffers pointer array in multiples of 32 entries */
- if (cnt == sp->buffer_total_count) return 0;
-
- pvr2_trace(PVR2_TRACE_BUF_POOL,
- "/*---TRACE_FLOW---*/ poolResize "
- " stream=%p cur=%d adj=%+d",
- sp,
- sp->buffer_total_count,
- cnt-sp->buffer_total_count);
-
- scnt = cnt & ~0x1f;
- if (cnt > scnt) scnt += 0x20;
-
- if (cnt > sp->buffer_total_count) {
- if (scnt > sp->buffer_slot_count) {
- struct pvr2_buffer **nb;
- nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL);
- if (!nb) return -ENOMEM;
- if (sp->buffer_slot_count) {
- memcpy(nb,sp->buffers,
- sp->buffer_slot_count * sizeof(*nb));
- kfree(sp->buffers);
- }
- sp->buffers = nb;
- sp->buffer_slot_count = scnt;
- }
- while (sp->buffer_total_count < cnt) {
- struct pvr2_buffer *bp;
- bp = kmalloc(sizeof(*bp),GFP_KERNEL);
- if (!bp) return -ENOMEM;
- ret = pvr2_buffer_init(bp,sp,sp->buffer_total_count);
- if (ret) {
- kfree(bp);
- return -ENOMEM;
- }
- sp->buffers[sp->buffer_total_count] = bp;
- (sp->buffer_total_count)++;
- pvr2_buffer_set_idle(bp);
- }
- } else {
- while (sp->buffer_total_count > cnt) {
- struct pvr2_buffer *bp;
- bp = sp->buffers[sp->buffer_total_count - 1];
- /* Paranoia */
- sp->buffers[sp->buffer_total_count - 1] = NULL;
- (sp->buffer_total_count)--;
- pvr2_buffer_done(bp);
- kfree(bp);
- }
- if (scnt < sp->buffer_slot_count) {
- struct pvr2_buffer **nb = NULL;
- if (scnt) {
- nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL);
- if (!nb) return -ENOMEM;
- memcpy(nb,sp->buffers,scnt * sizeof(*nb));
- }
- kfree(sp->buffers);
- sp->buffers = nb;
- sp->buffer_slot_count = scnt;
- }
- }
- return 0;
-}
-
-static int pvr2_stream_achieve_buffer_count(struct pvr2_stream *sp)
-{
- struct pvr2_buffer *bp;
- unsigned int cnt;
-
- if (sp->buffer_total_count == sp->buffer_target_count) return 0;
-
- pvr2_trace(PVR2_TRACE_BUF_POOL,
- "/*---TRACE_FLOW---*/"
- " poolCheck stream=%p cur=%d tgt=%d",
- sp,sp->buffer_total_count,sp->buffer_target_count);
-
- if (sp->buffer_total_count < sp->buffer_target_count) {
- return pvr2_stream_buffer_count(sp,sp->buffer_target_count);
- }
-
- cnt = 0;
- while ((sp->buffer_total_count - cnt) > sp->buffer_target_count) {
- bp = sp->buffers[sp->buffer_total_count - (cnt + 1)];
- if (bp->state != pvr2_buffer_state_idle) break;
- cnt++;
- }
- if (cnt) {
- pvr2_stream_buffer_count(sp,sp->buffer_total_count - cnt);
- }
-
- return 0;
-}
-
-static void pvr2_stream_internal_flush(struct pvr2_stream *sp)
-{
- struct list_head *lp;
- struct pvr2_buffer *bp1;
- while ((lp = sp->queued_list.next) != &sp->queued_list) {
- bp1 = list_entry(lp,struct pvr2_buffer,list_overhead);
- pvr2_buffer_wipe(bp1);
- /* At this point, we should be guaranteed that no
- completion callback may happen on this buffer. But it's
- possible that it might have completed after we noticed
- it but before we wiped it. So double check its status
- here first. */
- if (bp1->state != pvr2_buffer_state_queued) continue;
- pvr2_buffer_set_idle(bp1);
- }
- if (sp->buffer_total_count != sp->buffer_target_count) {
- pvr2_stream_achieve_buffer_count(sp);
- }
-}
-
-static void pvr2_stream_init(struct pvr2_stream *sp)
-{
- spin_lock_init(&sp->list_lock);
- mutex_init(&sp->mutex);
- INIT_LIST_HEAD(&sp->queued_list);
- INIT_LIST_HEAD(&sp->ready_list);
- INIT_LIST_HEAD(&sp->idle_list);
-}
-
-static void pvr2_stream_done(struct pvr2_stream *sp)
-{
- mutex_lock(&sp->mutex); do {
- pvr2_stream_internal_flush(sp);
- pvr2_stream_buffer_count(sp,0);
- } while (0); mutex_unlock(&sp->mutex);
-}
-
-static void buffer_complete(struct urb *urb)
-{
- struct pvr2_buffer *bp = urb->context;
- struct pvr2_stream *sp;
- unsigned long irq_flags;
- BUFFER_CHECK(bp);
- sp = bp->stream;
- bp->used_count = 0;
- bp->status = 0;
- pvr2_trace(PVR2_TRACE_BUF_FLOW,
- "/*---TRACE_FLOW---*/ bufferComplete %p stat=%d cnt=%d",
- bp,urb->status,urb->actual_length);
- spin_lock_irqsave(&sp->list_lock,irq_flags);
- if ((!(urb->status)) ||
- (urb->status == -ENOENT) ||
- (urb->status == -ECONNRESET) ||
- (urb->status == -ESHUTDOWN)) {
- (sp->buffers_processed)++;
- sp->bytes_processed += urb->actual_length;
- bp->used_count = urb->actual_length;
- if (sp->fail_count) {
- pvr2_trace(PVR2_TRACE_TOLERANCE,
- "stream %p transfer ok"
- " - fail count reset",sp);
- sp->fail_count = 0;
- }
- } else if (sp->fail_count < sp->fail_tolerance) {
- // We can tolerate this error, because we're below the
- // threshold...
- (sp->fail_count)++;
- (sp->buffers_failed)++;
- pvr2_trace(PVR2_TRACE_TOLERANCE,
- "stream %p ignoring error %d"
- " - fail count increased to %u",
- sp,urb->status,sp->fail_count);
- } else {
- (sp->buffers_failed)++;
- bp->status = urb->status;
- }
- spin_unlock_irqrestore(&sp->list_lock,irq_flags);
- pvr2_buffer_set_ready(bp);
- if (sp && sp->callback_func) {
- sp->callback_func(sp->callback_data);
- }
-}
-
-struct pvr2_stream *pvr2_stream_create(void)
-{
- struct pvr2_stream *sp;
- sp = kzalloc(sizeof(*sp),GFP_KERNEL);
- if (!sp) return sp;
- pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_create: sp=%p",sp);
- pvr2_stream_init(sp);
- return sp;
-}
-
-void pvr2_stream_destroy(struct pvr2_stream *sp)
-{
- if (!sp) return;
- pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_destroy: sp=%p",sp);
- pvr2_stream_done(sp);
- kfree(sp);
-}
-
-void pvr2_stream_setup(struct pvr2_stream *sp,
- struct usb_device *dev,
- int endpoint,
- unsigned int tolerance)
-{
- mutex_lock(&sp->mutex); do {
- pvr2_stream_internal_flush(sp);
- sp->dev = dev;
- sp->endpoint = endpoint;
- sp->fail_tolerance = tolerance;
- } while(0); mutex_unlock(&sp->mutex);
-}
-
-void pvr2_stream_set_callback(struct pvr2_stream *sp,
- pvr2_stream_callback func,
- void *data)
-{
- unsigned long irq_flags;
- mutex_lock(&sp->mutex); do {
- spin_lock_irqsave(&sp->list_lock,irq_flags);
- sp->callback_data = data;
- sp->callback_func = func;
- spin_unlock_irqrestore(&sp->list_lock,irq_flags);
- } while(0); mutex_unlock(&sp->mutex);
-}
-
-void pvr2_stream_get_stats(struct pvr2_stream *sp,
- struct pvr2_stream_stats *stats,
- int zero_counts)
-{
- unsigned long irq_flags;
- spin_lock_irqsave(&sp->list_lock,irq_flags);
- if (stats) {
- stats->buffers_in_queue = sp->q_count;
- stats->buffers_in_idle = sp->i_count;
- stats->buffers_in_ready = sp->r_count;
- stats->buffers_processed = sp->buffers_processed;
- stats->buffers_failed = sp->buffers_failed;
- stats->bytes_processed = sp->bytes_processed;
- }
- if (zero_counts) {
- sp->buffers_processed = 0;
- sp->buffers_failed = 0;
- sp->bytes_processed = 0;
- }
- spin_unlock_irqrestore(&sp->list_lock,irq_flags);
-}
-
-/* Query / set the nominal buffer count */
-int pvr2_stream_get_buffer_count(struct pvr2_stream *sp)
-{
- return sp->buffer_target_count;
-}
-
-int pvr2_stream_set_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
-{
- int ret;
- if (sp->buffer_target_count == cnt) return 0;
- mutex_lock(&sp->mutex); do {
- sp->buffer_target_count = cnt;
- ret = pvr2_stream_achieve_buffer_count(sp);
- } while(0); mutex_unlock(&sp->mutex);
- return ret;
-}
-
-struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *sp)
-{
- struct list_head *lp = sp->idle_list.next;
- if (lp == &sp->idle_list) return NULL;
- return list_entry(lp,struct pvr2_buffer,list_overhead);
-}
-
-struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *sp)
-{
- struct list_head *lp = sp->ready_list.next;
- if (lp == &sp->ready_list) return NULL;
- return list_entry(lp,struct pvr2_buffer,list_overhead);
-}
-
-struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id)
-{
- if (id < 0) return NULL;
- if (id >= sp->buffer_total_count) return NULL;
- return sp->buffers[id];
-}
-
-int pvr2_stream_get_ready_count(struct pvr2_stream *sp)
-{
- return sp->r_count;
-}
-
-void pvr2_stream_kill(struct pvr2_stream *sp)
-{
- struct pvr2_buffer *bp;
- mutex_lock(&sp->mutex); do {
- pvr2_stream_internal_flush(sp);
- while ((bp = pvr2_stream_get_ready_buffer(sp)) != NULL) {
- pvr2_buffer_set_idle(bp);
- }
- if (sp->buffer_total_count != sp->buffer_target_count) {
- pvr2_stream_achieve_buffer_count(sp);
- }
- } while(0); mutex_unlock(&sp->mutex);
-}
-
-int pvr2_buffer_queue(struct pvr2_buffer *bp)
-{
-#undef SEED_BUFFER
-#ifdef SEED_BUFFER
- unsigned int idx;
- unsigned int val;
-#endif
- int ret = 0;
- struct pvr2_stream *sp;
- if (!bp) return -EINVAL;
- sp = bp->stream;
- mutex_lock(&sp->mutex); do {
- pvr2_buffer_wipe(bp);
- if (!sp->dev) {
- ret = -EIO;
- break;
- }
- pvr2_buffer_set_queued(bp);
-#ifdef SEED_BUFFER
- for (idx = 0; idx < (bp->max_count) / 4; idx++) {
- val = bp->id << 24;
- val |= idx;
- ((unsigned int *)(bp->ptr))[idx] = val;
- }
-#endif
- bp->status = -EINPROGRESS;
- usb_fill_bulk_urb(bp->purb, // struct urb *urb
- sp->dev, // struct usb_device *dev
- // endpoint (below)
- usb_rcvbulkpipe(sp->dev,sp->endpoint),
- bp->ptr, // void *transfer_buffer
- bp->max_count, // int buffer_length
- buffer_complete,
- bp);
- usb_submit_urb(bp->purb,GFP_KERNEL);
- } while(0); mutex_unlock(&sp->mutex);
- return ret;
-}
-
-int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt)
-{
- int ret = 0;
- unsigned long irq_flags;
- struct pvr2_stream *sp;
- if (!bp) return -EINVAL;
- sp = bp->stream;
- mutex_lock(&sp->mutex); do {
- spin_lock_irqsave(&sp->list_lock,irq_flags);
- if (bp->state != pvr2_buffer_state_idle) {
- ret = -EPERM;
- } else {
- bp->ptr = ptr;
- bp->stream->i_bcount -= bp->max_count;
- bp->max_count = cnt;
- bp->stream->i_bcount += bp->max_count;
- pvr2_trace(PVR2_TRACE_BUF_FLOW,
- "/*---TRACE_FLOW---*/ bufferPool "
- " %8s cap cap=%07d cnt=%02d",
- pvr2_buffer_state_decode(
- pvr2_buffer_state_idle),
- bp->stream->i_bcount,bp->stream->i_count);
- }
- spin_unlock_irqrestore(&sp->list_lock,irq_flags);
- } while(0); mutex_unlock(&sp->mutex);
- return ret;
-}
-
-unsigned int pvr2_buffer_get_count(struct pvr2_buffer *bp)
-{
- return bp->used_count;
-}
-
-int pvr2_buffer_get_status(struct pvr2_buffer *bp)
-{
- return bp->status;
-}
-
-int pvr2_buffer_get_id(struct pvr2_buffer *bp)
-{
- return bp->id;
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.h b/drivers/media/video/pvrusb2/pvrusb2-io.h
deleted file mode 100644
index afb7e87c039..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-io.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __PVRUSB2_IO_H
-#define __PVRUSB2_IO_H
-
-#include <linux/usb.h>
-#include <linux/list.h>
-
-typedef void (*pvr2_stream_callback)(void *);
-
-enum pvr2_buffer_state {
- pvr2_buffer_state_none = 0, // Not on any list
- pvr2_buffer_state_idle = 1, // Buffer is ready to be used again
- pvr2_buffer_state_queued = 2, // Buffer has been queued for filling
- pvr2_buffer_state_ready = 3, // Buffer has data available
-};
-
-struct pvr2_stream;
-struct pvr2_buffer;
-
-struct pvr2_stream_stats {
- unsigned int buffers_in_queue;
- unsigned int buffers_in_idle;
- unsigned int buffers_in_ready;
- unsigned int buffers_processed;
- unsigned int buffers_failed;
- unsigned int bytes_processed;
-};
-
-/* Initialize / tear down stream structure */
-struct pvr2_stream *pvr2_stream_create(void);
-void pvr2_stream_destroy(struct pvr2_stream *);
-void pvr2_stream_setup(struct pvr2_stream *,
- struct usb_device *dev,int endpoint,
- unsigned int tolerance);
-void pvr2_stream_set_callback(struct pvr2_stream *,
- pvr2_stream_callback func,
- void *data);
-void pvr2_stream_get_stats(struct pvr2_stream *,
- struct pvr2_stream_stats *,
- int zero_counts);
-
-/* Query / set the nominal buffer count */
-int pvr2_stream_get_buffer_count(struct pvr2_stream *);
-int pvr2_stream_set_buffer_count(struct pvr2_stream *,unsigned int);
-
-/* Get a pointer to a buffer that is either idle, ready, or is specified
- named. */
-struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *);
-struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *);
-struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id);
-
-/* Find out how many buffers are idle or ready */
-int pvr2_stream_get_ready_count(struct pvr2_stream *);
-
-
-/* Kill all pending buffers and throw away any ready buffers as well */
-void pvr2_stream_kill(struct pvr2_stream *);
-
-/* Set up the actual storage for a buffer */
-int pvr2_buffer_set_buffer(struct pvr2_buffer *,void *ptr,unsigned int cnt);
-
-/* Find out size of data in the given ready buffer */
-unsigned int pvr2_buffer_get_count(struct pvr2_buffer *);
-
-/* Retrieve completion code for given ready buffer */
-int pvr2_buffer_get_status(struct pvr2_buffer *);
-
-/* Retrieve ID of given buffer */
-int pvr2_buffer_get_id(struct pvr2_buffer *);
-
-/* Start reading into given buffer (kill it if needed) */
-int pvr2_buffer_queue(struct pvr2_buffer *);
-
-#endif /* __PVRUSB2_IO_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/drivers/media/video/pvrusb2/pvrusb2-ioread.c
deleted file mode 100644
index bba6115c9ae..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-ioread.c
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "pvrusb2-ioread.h"
-#include "pvrusb2-debug.h"
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <asm/uaccess.h>
-
-#define BUFFER_COUNT 32
-#define BUFFER_SIZE PAGE_ALIGN(0x4000)
-
-struct pvr2_ioread {
- struct pvr2_stream *stream;
- char *buffer_storage[BUFFER_COUNT];
- char *sync_key_ptr;
- unsigned int sync_key_len;
- unsigned int sync_buf_offs;
- unsigned int sync_state;
- unsigned int sync_trashed_count;
- int enabled; // Streaming is on
- int spigot_open; // OK to pass data to client
- int stream_running; // Passing data to client now
-
- /* State relevant to current buffer being read */
- struct pvr2_buffer *c_buf;
- char *c_data_ptr;
- unsigned int c_data_len;
- unsigned int c_data_offs;
- struct mutex mutex;
-};
-
-static int pvr2_ioread_init(struct pvr2_ioread *cp)
-{
- unsigned int idx;
-
- cp->stream = NULL;
- mutex_init(&cp->mutex);
-
- for (idx = 0; idx < BUFFER_COUNT; idx++) {
- cp->buffer_storage[idx] = kmalloc(BUFFER_SIZE,GFP_KERNEL);
- if (!(cp->buffer_storage[idx])) break;
- }
-
- if (idx < BUFFER_COUNT) {
- // An allocation appears to have failed
- for (idx = 0; idx < BUFFER_COUNT; idx++) {
- if (!(cp->buffer_storage[idx])) continue;
- kfree(cp->buffer_storage[idx]);
- }
- return -ENOMEM;
- }
- return 0;
-}
-
-static void pvr2_ioread_done(struct pvr2_ioread *cp)
-{
- unsigned int idx;
-
- pvr2_ioread_setup(cp,NULL);
- for (idx = 0; idx < BUFFER_COUNT; idx++) {
- if (!(cp->buffer_storage[idx])) continue;
- kfree(cp->buffer_storage[idx]);
- }
-}
-
-struct pvr2_ioread *pvr2_ioread_create(void)
-{
- struct pvr2_ioread *cp;
- cp = kzalloc(sizeof(*cp),GFP_KERNEL);
- if (!cp) return NULL;
- pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_create id=%p",cp);
- if (pvr2_ioread_init(cp) < 0) {
- kfree(cp);
- return NULL;
- }
- return cp;
-}
-
-void pvr2_ioread_destroy(struct pvr2_ioread *cp)
-{
- if (!cp) return;
- pvr2_ioread_done(cp);
- pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_destroy id=%p",cp);
- if (cp->sync_key_ptr) {
- kfree(cp->sync_key_ptr);
- cp->sync_key_ptr = NULL;
- }
- kfree(cp);
-}
-
-void pvr2_ioread_set_sync_key(struct pvr2_ioread *cp,
- const char *sync_key_ptr,
- unsigned int sync_key_len)
-{
- if (!cp) return;
-
- if (!sync_key_ptr) sync_key_len = 0;
- if ((sync_key_len == cp->sync_key_len) &&
- ((!sync_key_len) ||
- (!memcmp(sync_key_ptr,cp->sync_key_ptr,sync_key_len)))) return;
-
- if (sync_key_len != cp->sync_key_len) {
- if (cp->sync_key_ptr) {
- kfree(cp->sync_key_ptr);
- cp->sync_key_ptr = NULL;
- }
- cp->sync_key_len = 0;
- if (sync_key_len) {
- cp->sync_key_ptr = kmalloc(sync_key_len,GFP_KERNEL);
- if (cp->sync_key_ptr) {
- cp->sync_key_len = sync_key_len;
- }
- }
- }
- if (!cp->sync_key_len) return;
- memcpy(cp->sync_key_ptr,sync_key_ptr,cp->sync_key_len);
-}
-
-static void pvr2_ioread_stop(struct pvr2_ioread *cp)
-{
- if (!(cp->enabled)) return;
- pvr2_trace(PVR2_TRACE_START_STOP,
- "/*---TRACE_READ---*/ pvr2_ioread_stop id=%p",cp);
- pvr2_stream_kill(cp->stream);
- cp->c_buf = NULL;
- cp->c_data_ptr = NULL;
- cp->c_data_len = 0;
- cp->c_data_offs = 0;
- cp->enabled = 0;
- cp->stream_running = 0;
- cp->spigot_open = 0;
- if (cp->sync_state) {
- pvr2_trace(PVR2_TRACE_DATA_FLOW,
- "/*---TRACE_READ---*/ sync_state <== 0");
- cp->sync_state = 0;
- }
-}
-
-static int pvr2_ioread_start(struct pvr2_ioread *cp)
-{
- int stat;
- struct pvr2_buffer *bp;
- if (cp->enabled) return 0;
- if (!(cp->stream)) return 0;
- pvr2_trace(PVR2_TRACE_START_STOP,
- "/*---TRACE_READ---*/ pvr2_ioread_start id=%p",cp);
- while ((bp = pvr2_stream_get_idle_buffer(cp->stream)) != NULL) {
- stat = pvr2_buffer_queue(bp);
- if (stat < 0) {
- pvr2_trace(PVR2_TRACE_DATA_FLOW,
- "/*---TRACE_READ---*/"
- " pvr2_ioread_start id=%p"
- " error=%d",
- cp,stat);
- pvr2_ioread_stop(cp);
- return stat;
- }
- }
- cp->enabled = !0;
- cp->c_buf = NULL;
- cp->c_data_ptr = NULL;
- cp->c_data_len = 0;
- cp->c_data_offs = 0;
- cp->stream_running = 0;
- if (cp->sync_key_len) {
- pvr2_trace(PVR2_TRACE_DATA_FLOW,
- "/*---TRACE_READ---*/ sync_state <== 1");
- cp->sync_state = 1;
- cp->sync_trashed_count = 0;
- cp->sync_buf_offs = 0;
- }
- cp->spigot_open = 0;
- return 0;
-}
-
-struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *cp)
-{
- return cp->stream;
-}
-
-int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp)
-{
- int ret;
- unsigned int idx;
- struct pvr2_buffer *bp;
-
- mutex_lock(&cp->mutex); do {
- if (cp->stream) {
- pvr2_trace(PVR2_TRACE_START_STOP,
- "/*---TRACE_READ---*/"
- " pvr2_ioread_setup (tear-down) id=%p",cp);
- pvr2_ioread_stop(cp);
- pvr2_stream_kill(cp->stream);
- if (pvr2_stream_get_buffer_count(cp->stream)) {
- pvr2_stream_set_buffer_count(cp->stream,0);
- }
- cp->stream = NULL;
- }
- if (sp) {
- pvr2_trace(PVR2_TRACE_START_STOP,
- "/*---TRACE_READ---*/"
- " pvr2_ioread_setup (setup) id=%p",cp);
- pvr2_stream_kill(sp);
- ret = pvr2_stream_set_buffer_count(sp,BUFFER_COUNT);
- if (ret < 0) {
- mutex_unlock(&cp->mutex);
- return ret;
- }
- for (idx = 0; idx < BUFFER_COUNT; idx++) {
- bp = pvr2_stream_get_buffer(sp,idx);
- pvr2_buffer_set_buffer(bp,
- cp->buffer_storage[idx],
- BUFFER_SIZE);
- }
- cp->stream = sp;
- }
- } while (0); mutex_unlock(&cp->mutex);
-
- return 0;
-}
-
-int pvr2_ioread_set_enabled(struct pvr2_ioread *cp,int fl)
-{
- int ret = 0;
- if ((!fl) == (!(cp->enabled))) return ret;
-
- mutex_lock(&cp->mutex); do {
- if (fl) {
- ret = pvr2_ioread_start(cp);
- } else {
- pvr2_ioread_stop(cp);
- }
- } while (0); mutex_unlock(&cp->mutex);
- return ret;
-}
-
-static int pvr2_ioread_get_buffer(struct pvr2_ioread *cp)
-{
- int stat;
-
- while (cp->c_data_len <= cp->c_data_offs) {
- if (cp->c_buf) {
- // Flush out current buffer first.
- stat = pvr2_buffer_queue(cp->c_buf);
- if (stat < 0) {
- // Streaming error...
- pvr2_trace(PVR2_TRACE_DATA_FLOW,
- "/*---TRACE_READ---*/"
- " pvr2_ioread_read id=%p"
- " queue_error=%d",
- cp,stat);
- pvr2_ioread_stop(cp);
- return 0;
- }
- cp->c_buf = NULL;
- cp->c_data_ptr = NULL;
- cp->c_data_len = 0;
- cp->c_data_offs = 0;
- }
- // Now get a freshly filled buffer.
- cp->c_buf = pvr2_stream_get_ready_buffer(cp->stream);
- if (!cp->c_buf) break; // Nothing ready; done.
- cp->c_data_len = pvr2_buffer_get_count(cp->c_buf);
- if (!cp->c_data_len) {
- // Nothing transferred. Was there an error?
- stat = pvr2_buffer_get_status(cp->c_buf);
- if (stat < 0) {
- // Streaming error...
- pvr2_trace(PVR2_TRACE_DATA_FLOW,
- "/*---TRACE_READ---*/"
- " pvr2_ioread_read id=%p"
- " buffer_error=%d",
- cp,stat);
- pvr2_ioread_stop(cp);
- // Give up.
- return 0;
- }
- // Start over...
- continue;
- }
- cp->c_data_offs = 0;
- cp->c_data_ptr = cp->buffer_storage[
- pvr2_buffer_get_id(cp->c_buf)];
- }
- return !0;
-}
-
-static void pvr2_ioread_filter(struct pvr2_ioread *cp)
-{
- unsigned int idx;
- if (!cp->enabled) return;
- if (cp->sync_state != 1) return;
-
- // Search the stream for our synchronization key. This is made
- // complicated by the fact that in order to be honest with
- // ourselves here we must search across buffer boundaries...
- mutex_lock(&cp->mutex); while (1) {
- // Ensure we have a buffer
- if (!pvr2_ioread_get_buffer(cp)) break;
- if (!cp->c_data_len) break;
-
- // Now walk the buffer contents until we match the key or
- // run out of buffer data.
- for (idx = cp->c_data_offs; idx < cp->c_data_len; idx++) {
- if (cp->sync_buf_offs >= cp->sync_key_len) break;
- if (cp->c_data_ptr[idx] ==
- cp->sync_key_ptr[cp->sync_buf_offs]) {
- // Found the next key byte
- (cp->sync_buf_offs)++;
- } else {
- // Whoops, mismatched. Start key over...
- cp->sync_buf_offs = 0;
- }
- }
-
- // Consume what we've walked through
- cp->c_data_offs += idx;
- cp->sync_trashed_count += idx;
-
- // If we've found the key, then update state and get out.
- if (cp->sync_buf_offs >= cp->sync_key_len) {
- cp->sync_trashed_count -= cp->sync_key_len;
- pvr2_trace(PVR2_TRACE_DATA_FLOW,
- "/*---TRACE_READ---*/"
- " sync_state <== 2 (skipped %u bytes)",
- cp->sync_trashed_count);
- cp->sync_state = 2;
- cp->sync_buf_offs = 0;
- break;
- }
-
- if (cp->c_data_offs < cp->c_data_len) {
- // Sanity check - should NEVER get here
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "ERROR: pvr2_ioread filter sync problem"
- " len=%u offs=%u",
- cp->c_data_len,cp->c_data_offs);
- // Get out so we don't get stuck in an infinite
- // loop.
- break;
- }
-
- continue; // (for clarity)
- } mutex_unlock(&cp->mutex);
-}
-
-int pvr2_ioread_avail(struct pvr2_ioread *cp)
-{
- int ret;
- if (!(cp->enabled)) {
- // Stream is not enabled; so this is an I/O error
- return -EIO;
- }
-
- if (cp->sync_state == 1) {
- pvr2_ioread_filter(cp);
- if (cp->sync_state == 1) return -EAGAIN;
- }
-
- ret = 0;
- if (cp->stream_running) {
- if (!pvr2_stream_get_ready_count(cp->stream)) {
- // No data available at all right now.
- ret = -EAGAIN;
- }
- } else {
- if (pvr2_stream_get_ready_count(cp->stream) < BUFFER_COUNT/2) {
- // Haven't buffered up enough yet; try again later
- ret = -EAGAIN;
- }
- }
-
- if ((!(cp->spigot_open)) != (!(ret == 0))) {
- cp->spigot_open = (ret == 0);
- pvr2_trace(PVR2_TRACE_DATA_FLOW,
- "/*---TRACE_READ---*/ data is %s",
- cp->spigot_open ? "available" : "pending");
- }
-
- return ret;
-}
-
-int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt)
-{
- unsigned int copied_cnt;
- unsigned int bcnt;
- const char *src;
- int stat;
- int ret = 0;
- unsigned int req_cnt = cnt;
-
- if (!cnt) {
- pvr2_trace(PVR2_TRACE_TRAP,
- "/*---TRACE_READ---*/ pvr2_ioread_read id=%p"
- " ZERO Request? Returning zero.",cp);
- return 0;
- }
-
- stat = pvr2_ioread_avail(cp);
- if (stat < 0) return stat;
-
- cp->stream_running = !0;
-
- mutex_lock(&cp->mutex); do {
-
- // Suck data out of the buffers and copy to the user
- copied_cnt = 0;
- if (!buf) cnt = 0;
- while (1) {
- if (!pvr2_ioread_get_buffer(cp)) {
- ret = -EIO;
- break;
- }
-
- if (!cnt) break;
-
- if (cp->sync_state == 2) {
- // We're repeating the sync key data into
- // the stream.
- src = cp->sync_key_ptr + cp->sync_buf_offs;
- bcnt = cp->sync_key_len - cp->sync_buf_offs;
- } else {
- // Normal buffer copy
- src = cp->c_data_ptr + cp->c_data_offs;
- bcnt = cp->c_data_len - cp->c_data_offs;
- }
-
- if (!bcnt) break;
-
- // Don't run past user's buffer
- if (bcnt > cnt) bcnt = cnt;
-
- if (copy_to_user(buf,src,bcnt)) {
- // User supplied a bad pointer?
- // Give up - this *will* cause data
- // to be lost.
- ret = -EFAULT;
- break;
- }
- cnt -= bcnt;
- buf += bcnt;
- copied_cnt += bcnt;
-
- if (cp->sync_state == 2) {
- // Update offset inside sync key that we're
- // repeating back out.
- cp->sync_buf_offs += bcnt;
- if (cp->sync_buf_offs >= cp->sync_key_len) {
- // Consumed entire key; switch mode
- // to normal.
- pvr2_trace(PVR2_TRACE_DATA_FLOW,
- "/*---TRACE_READ---*/"
- " sync_state <== 0");
- cp->sync_state = 0;
- }
- } else {
- // Update buffer offset.
- cp->c_data_offs += bcnt;
- }
- }
-
- } while (0); mutex_unlock(&cp->mutex);
-
- if (!ret) {
- if (copied_cnt) {
- // If anything was copied, return that count
- ret = copied_cnt;
- } else {
- // Nothing copied; suggest to caller that another
- // attempt should be tried again later
- ret = -EAGAIN;
- }
- }
-
- pvr2_trace(PVR2_TRACE_DATA_FLOW,
- "/*---TRACE_READ---*/ pvr2_ioread_read"
- " id=%p request=%d result=%d",
- cp,req_cnt,ret);
- return ret;
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.h b/drivers/media/video/pvrusb2/pvrusb2-ioread.h
deleted file mode 100644
index 100e0780e1a..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-ioread.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __PVRUSB2_IOREAD_H
-#define __PVRUSB2_IOREAD_H
-
-#include "pvrusb2-io.h"
-
-struct pvr2_ioread;
-
-struct pvr2_ioread *pvr2_ioread_create(void);
-void pvr2_ioread_destroy(struct pvr2_ioread *);
-int pvr2_ioread_setup(struct pvr2_ioread *,struct pvr2_stream *);
-struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *);
-void pvr2_ioread_set_sync_key(struct pvr2_ioread *,
- const char *sync_key_ptr,
- unsigned int sync_key_len);
-int pvr2_ioread_set_enabled(struct pvr2_ioread *,int fl);
-int pvr2_ioread_read(struct pvr2_ioread *,void __user *buf,unsigned int cnt);
-int pvr2_ioread_avail(struct pvr2_ioread *);
-
-#endif /* __PVRUSB2_IOREAD_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
deleted file mode 100644
index c1d9bb61cd7..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-
-#include "pvrusb2-hdw.h"
-#include "pvrusb2-devattr.h"
-#include "pvrusb2-context.h"
-#include "pvrusb2-debug.h"
-#include "pvrusb2-v4l2.h"
-#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
-#include "pvrusb2-sysfs.h"
-#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
-
-#define DRIVER_AUTHOR "Mike Isely <isely@pobox.com>"
-#define DRIVER_DESC "Hauppauge WinTV-PVR-USB2 MPEG2 Encoder/Tuner"
-#define DRIVER_VERSION "V4L in-tree version"
-
-#define DEFAULT_DEBUG_MASK (PVR2_TRACE_ERROR_LEGS| \
- PVR2_TRACE_INFO| \
- PVR2_TRACE_STD| \
- PVR2_TRACE_TOLERANCE| \
- PVR2_TRACE_TRAP| \
- 0)
-
-int pvrusb2_debug = DEFAULT_DEBUG_MASK;
-
-module_param_named(debug,pvrusb2_debug,int,S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug trace mask");
-
-#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
-static struct pvr2_sysfs_class *class_ptr = NULL;
-#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
-
-static void pvr_setup_attach(struct pvr2_context *pvr)
-{
- /* Create association with v4l layer */
- pvr2_v4l2_create(pvr);
-#ifdef CONFIG_VIDEO_PVRUSB2_DVB
- /* Create association with dvb layer */
- pvr2_dvb_create(pvr);
-#endif
-#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
- pvr2_sysfs_create(pvr,class_ptr);
-#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
-}
-
-static int pvr_probe(struct usb_interface *intf,
- const struct usb_device_id *devid)
-{
- struct pvr2_context *pvr;
-
- /* Create underlying hardware interface */
- pvr = pvr2_context_create(intf,devid,pvr_setup_attach);
- if (!pvr) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Failed to create hdw handler");
- return -ENOMEM;
- }
-
- pvr2_trace(PVR2_TRACE_INIT,"pvr_probe(pvr=%p)",pvr);
-
- usb_set_intfdata(intf, pvr);
-
- return 0;
-}
-
-/*
- * pvr_disconnect()
- *
- */
-static void pvr_disconnect(struct usb_interface *intf)
-{
- struct pvr2_context *pvr = usb_get_intfdata(intf);
-
- pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) BEGIN",pvr);
-
- usb_set_intfdata (intf, NULL);
- pvr2_context_disconnect(pvr);
-
- pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) DONE",pvr);
-
-}
-
-static struct usb_driver pvr_driver = {
- .name = "pvrusb2",
- .id_table = pvr2_device_table,
- .probe = pvr_probe,
- .disconnect = pvr_disconnect
-};
-
-/*
- * pvr_init() / pvr_exit()
- *
- * This code is run to initialize/exit the driver.
- *
- */
-static int __init pvr_init(void)
-{
- int ret;
-
- pvr2_trace(PVR2_TRACE_INIT,"pvr_init");
-
- ret = pvr2_context_global_init();
- if (ret != 0) {
- pvr2_trace(PVR2_TRACE_INIT,"pvr_init failure code=%d",ret);
- return ret;
- }
-
-#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
- class_ptr = pvr2_sysfs_class_create();
-#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
-
- ret = usb_register(&pvr_driver);
-
- if (ret == 0)
- printk(KERN_INFO "pvrusb2: " DRIVER_VERSION ":"
- DRIVER_DESC "\n");
- if (pvrusb2_debug)
- printk(KERN_INFO "pvrusb2: Debug mask is %d (0x%x)\n",
- pvrusb2_debug,pvrusb2_debug);
-
- pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete");
-
- return ret;
-}
-
-static void __exit pvr_exit(void)
-{
- pvr2_trace(PVR2_TRACE_INIT,"pvr_exit");
-
- usb_deregister(&pvr_driver);
-
- pvr2_context_global_done();
-
-#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
- pvr2_sysfs_class_destroy(class_ptr);
-#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
-
- pvr2_trace(PVR2_TRACE_INIT,"pvr_exit complete");
-}
-
-module_init(pvr_init);
-module_exit(pvr_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.9.1");
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.c b/drivers/media/video/pvrusb2/pvrusb2-std.c
deleted file mode 100644
index 453627b0783..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-std.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "pvrusb2-std.h"
-#include "pvrusb2-debug.h"
-#include <asm/string.h>
-#include <linux/slab.h>
-
-struct std_name {
- const char *name;
- v4l2_std_id id;
-};
-
-
-#define CSTD_PAL \
- (V4L2_STD_PAL_B| \
- V4L2_STD_PAL_B1| \
- V4L2_STD_PAL_G| \
- V4L2_STD_PAL_H| \
- V4L2_STD_PAL_I| \
- V4L2_STD_PAL_D| \
- V4L2_STD_PAL_D1| \
- V4L2_STD_PAL_K| \
- V4L2_STD_PAL_M| \
- V4L2_STD_PAL_N| \
- V4L2_STD_PAL_Nc| \
- V4L2_STD_PAL_60)
-
-#define CSTD_NTSC \
- (V4L2_STD_NTSC_M| \
- V4L2_STD_NTSC_M_JP| \
- V4L2_STD_NTSC_M_KR| \
- V4L2_STD_NTSC_443)
-
-#define CSTD_ATSC \
- (V4L2_STD_ATSC_8_VSB| \
- V4L2_STD_ATSC_16_VSB)
-
-#define CSTD_SECAM \
- (V4L2_STD_SECAM_B| \
- V4L2_STD_SECAM_D| \
- V4L2_STD_SECAM_G| \
- V4L2_STD_SECAM_H| \
- V4L2_STD_SECAM_K| \
- V4L2_STD_SECAM_K1| \
- V4L2_STD_SECAM_L| \
- V4L2_STD_SECAM_LC)
-
-#define TSTD_B (V4L2_STD_PAL_B|V4L2_STD_SECAM_B)
-#define TSTD_B1 (V4L2_STD_PAL_B1)
-#define TSTD_D (V4L2_STD_PAL_D|V4L2_STD_SECAM_D)
-#define TSTD_D1 (V4L2_STD_PAL_D1)
-#define TSTD_G (V4L2_STD_PAL_G|V4L2_STD_SECAM_G)
-#define TSTD_H (V4L2_STD_PAL_H|V4L2_STD_SECAM_H)
-#define TSTD_I (V4L2_STD_PAL_I)
-#define TSTD_K (V4L2_STD_PAL_K|V4L2_STD_SECAM_K)
-#define TSTD_K1 (V4L2_STD_SECAM_K1)
-#define TSTD_L (V4L2_STD_SECAM_L)
-#define TSTD_M (V4L2_STD_PAL_M|V4L2_STD_NTSC_M)
-#define TSTD_N (V4L2_STD_PAL_N)
-#define TSTD_Nc (V4L2_STD_PAL_Nc)
-#define TSTD_60 (V4L2_STD_PAL_60)
-
-#define CSTD_ALL (CSTD_PAL|CSTD_NTSC|CSTD_ATSC|CSTD_SECAM)
-
-/* Mapping of standard bits to color system */
-static const struct std_name std_groups[] = {
- {"PAL",CSTD_PAL},
- {"NTSC",CSTD_NTSC},
- {"SECAM",CSTD_SECAM},
- {"ATSC",CSTD_ATSC},
-};
-
-/* Mapping of standard bits to modulation system */
-static const struct std_name std_items[] = {
- {"B",TSTD_B},
- {"B1",TSTD_B1},
- {"D",TSTD_D},
- {"D1",TSTD_D1},
- {"G",TSTD_G},
- {"H",TSTD_H},
- {"I",TSTD_I},
- {"K",TSTD_K},
- {"K1",TSTD_K1},
- {"L",TSTD_L},
- {"LC",V4L2_STD_SECAM_LC},
- {"M",TSTD_M},
- {"Mj",V4L2_STD_NTSC_M_JP},
- {"443",V4L2_STD_NTSC_443},
- {"Mk",V4L2_STD_NTSC_M_KR},
- {"N",TSTD_N},
- {"Nc",TSTD_Nc},
- {"60",TSTD_60},
- {"8VSB",V4L2_STD_ATSC_8_VSB},
- {"16VSB",V4L2_STD_ATSC_16_VSB},
-};
-
-
-// Search an array of std_name structures and return a pointer to the
-// element with the matching name.
-static const struct std_name *find_std_name(const struct std_name *arrPtr,
- unsigned int arrSize,
- const char *bufPtr,
- unsigned int bufSize)
-{
- unsigned int idx;
- const struct std_name *p;
- for (idx = 0; idx < arrSize; idx++) {
- p = arrPtr + idx;
- if (strlen(p->name) != bufSize) continue;
- if (!memcmp(bufPtr,p->name,bufSize)) return p;
- }
- return NULL;
-}
-
-
-int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr,
- unsigned int bufSize)
-{
- v4l2_std_id id = 0;
- v4l2_std_id cmsk = 0;
- v4l2_std_id t;
- int mMode = 0;
- unsigned int cnt;
- char ch;
- const struct std_name *sp;
-
- while (bufSize) {
- if (!mMode) {
- cnt = 0;
- while ((cnt < bufSize) && (bufPtr[cnt] != '-')) cnt++;
- if (cnt >= bufSize) return 0; // No more characters
- sp = find_std_name(std_groups, ARRAY_SIZE(std_groups),
- bufPtr,cnt);
- if (!sp) return 0; // Illegal color system name
- cnt++;
- bufPtr += cnt;
- bufSize -= cnt;
- mMode = !0;
- cmsk = sp->id;
- continue;
- }
- cnt = 0;
- while (cnt < bufSize) {
- ch = bufPtr[cnt];
- if (ch == ';') {
- mMode = 0;
- break;
- }
- if (ch == '/') break;
- cnt++;
- }
- sp = find_std_name(std_items, ARRAY_SIZE(std_items),
- bufPtr,cnt);
- if (!sp) return 0; // Illegal modulation system ID
- t = sp->id & cmsk;
- if (!t) return 0; // Specific color + modulation system illegal
- id |= t;
- if (cnt < bufSize) cnt++;
- bufPtr += cnt;
- bufSize -= cnt;
- }
-
- if (idPtr) *idPtr = id;
- return !0;
-}
-
-
-unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize,
- v4l2_std_id id)
-{
- unsigned int idx1,idx2;
- const struct std_name *ip,*gp;
- int gfl,cfl;
- unsigned int c1,c2;
- cfl = 0;
- c1 = 0;
- for (idx1 = 0; idx1 < ARRAY_SIZE(std_groups); idx1++) {
- gp = std_groups + idx1;
- gfl = 0;
- for (idx2 = 0; idx2 < ARRAY_SIZE(std_items); idx2++) {
- ip = std_items + idx2;
- if (!(gp->id & ip->id & id)) continue;
- if (!gfl) {
- if (cfl) {
- c2 = scnprintf(bufPtr,bufSize,";");
- c1 += c2;
- bufSize -= c2;
- bufPtr += c2;
- }
- cfl = !0;
- c2 = scnprintf(bufPtr,bufSize,
- "%s-",gp->name);
- gfl = !0;
- } else {
- c2 = scnprintf(bufPtr,bufSize,"/");
- }
- c1 += c2;
- bufSize -= c2;
- bufPtr += c2;
- c2 = scnprintf(bufPtr,bufSize,
- ip->name);
- c1 += c2;
- bufSize -= c2;
- bufPtr += c2;
- }
- }
- return c1;
-}
-
-
-// Template data for possible enumerated video standards. Here we group
-// standards which share common frame rates and resolution.
-static struct v4l2_standard generic_standards[] = {
- {
- .id = (TSTD_B|TSTD_B1|
- TSTD_D|TSTD_D1|
- TSTD_G|
- TSTD_H|
- TSTD_I|
- TSTD_K|TSTD_K1|
- TSTD_L|
- V4L2_STD_SECAM_LC |
- TSTD_N|TSTD_Nc),
- .frameperiod =
- {
- .numerator = 1,
- .denominator= 25
- },
- .framelines = 625,
- .reserved = {0,0,0,0}
- }, {
- .id = (TSTD_M|
- V4L2_STD_NTSC_M_JP|
- V4L2_STD_NTSC_M_KR),
- .frameperiod =
- {
- .numerator = 1001,
- .denominator= 30000
- },
- .framelines = 525,
- .reserved = {0,0,0,0}
- }, { // This is a total wild guess
- .id = (TSTD_60),
- .frameperiod =
- {
- .numerator = 1001,
- .denominator= 30000
- },
- .framelines = 525,
- .reserved = {0,0,0,0}
- }, { // This is total wild guess
- .id = V4L2_STD_NTSC_443,
- .frameperiod =
- {
- .numerator = 1001,
- .denominator= 30000
- },
- .framelines = 525,
- .reserved = {0,0,0,0}
- }
-};
-
-static struct v4l2_standard *match_std(v4l2_std_id id)
-{
- unsigned int idx;
- for (idx = 0; idx < ARRAY_SIZE(generic_standards); idx++) {
- if (generic_standards[idx].id & id) {
- return generic_standards + idx;
- }
- }
- return NULL;
-}
-
-static int pvr2_std_fill(struct v4l2_standard *std,v4l2_std_id id)
-{
- struct v4l2_standard *template;
- int idx;
- unsigned int bcnt;
- template = match_std(id);
- if (!template) return 0;
- idx = std->index;
- memcpy(std,template,sizeof(*template));
- std->index = idx;
- std->id = id;
- bcnt = pvr2_std_id_to_str(std->name,sizeof(std->name)-1,id);
- std->name[bcnt] = 0;
- pvr2_trace(PVR2_TRACE_STD,"Set up standard idx=%u name=%s",
- std->index,std->name);
- return !0;
-}
-
-/* These are special cases of combined standards that we should enumerate
- separately if the component pieces are present. */
-static v4l2_std_id std_mixes[] = {
- V4L2_STD_PAL_B | V4L2_STD_PAL_G,
- V4L2_STD_PAL_D | V4L2_STD_PAL_K,
- V4L2_STD_SECAM_B | V4L2_STD_SECAM_G,
- V4L2_STD_SECAM_D | V4L2_STD_SECAM_K,
-};
-
-struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr,
- v4l2_std_id id)
-{
- unsigned int std_cnt = 0;
- unsigned int idx,bcnt,idx2;
- v4l2_std_id idmsk,cmsk,fmsk;
- struct v4l2_standard *stddefs;
-
- if (pvrusb2_debug & PVR2_TRACE_STD) {
- char buf[100];
- bcnt = pvr2_std_id_to_str(buf,sizeof(buf),id);
- pvr2_trace(
- PVR2_TRACE_STD,"Mapping standards mask=0x%x (%.*s)",
- (int)id,bcnt,buf);
- }
-
- *countptr = 0;
- std_cnt = 0;
- fmsk = 0;
- for (idmsk = 1, cmsk = id; cmsk; idmsk <<= 1) {
- if (!(idmsk & cmsk)) continue;
- cmsk &= ~idmsk;
- if (match_std(idmsk)) {
- std_cnt++;
- continue;
- }
- fmsk |= idmsk;
- }
-
- for (idx2 = 0; idx2 < ARRAY_SIZE(std_mixes); idx2++) {
- if ((id & std_mixes[idx2]) == std_mixes[idx2]) std_cnt++;
- }
-
- /* Don't complain about ATSC standard values */
- fmsk &= ~CSTD_ATSC;
-
- if (fmsk) {
- char buf[100];
- bcnt = pvr2_std_id_to_str(buf,sizeof(buf),fmsk);
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "WARNING:"
- " Failed to classify the following standard(s): %.*s",
- bcnt,buf);
- }
-
- pvr2_trace(PVR2_TRACE_STD,"Setting up %u unique standard(s)",
- std_cnt);
- if (!std_cnt) return NULL; // paranoia
-
- stddefs = kzalloc(sizeof(struct v4l2_standard) * std_cnt,
- GFP_KERNEL);
- if (!stddefs)
- return NULL;
-
- for (idx = 0; idx < std_cnt; idx++)
- stddefs[idx].index = idx;
-
- idx = 0;
-
- /* Enumerate potential special cases */
- for (idx2 = 0; (idx2 < ARRAY_SIZE(std_mixes)) && (idx < std_cnt);
- idx2++) {
- if (!(id & std_mixes[idx2])) continue;
- if (pvr2_std_fill(stddefs+idx,std_mixes[idx2])) idx++;
- }
- /* Now enumerate individual pieces */
- for (idmsk = 1, cmsk = id; cmsk && (idx < std_cnt); idmsk <<= 1) {
- if (!(idmsk & cmsk)) continue;
- cmsk &= ~idmsk;
- if (!pvr2_std_fill(stddefs+idx,idmsk)) continue;
- idx++;
- }
-
- *countptr = std_cnt;
- return stddefs;
-}
-
-v4l2_std_id pvr2_std_get_usable(void)
-{
- return CSTD_ALL;
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.h b/drivers/media/video/pvrusb2/pvrusb2-std.h
deleted file mode 100644
index a35c53d0b32..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-std.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __PVRUSB2_STD_H
-#define __PVRUSB2_STD_H
-
-#include <linux/videodev2.h>
-
-// Convert string describing one or more video standards into a mask of V4L
-// standard bits. Return true if conversion succeeds otherwise return
-// false. String is expected to be of the form: C1-x/y;C2-a/b where C1 and
-// C2 are color system names (e.g. "PAL", "NTSC") and x, y, a, and b are
-// modulation schemes (e.g. "M", "B", "G", etc).
-int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr,
- unsigned int bufSize);
-
-// Convert any arbitrary set of video standard bits into an unambiguous
-// readable string. Return value is the number of bytes consumed in the
-// buffer. The formatted string is of a form that can be parsed by our
-// sibling std_std_to_id() function.
-unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize,
- v4l2_std_id id);
-
-// Create an array of suitable v4l2_standard structures given a bit mask of
-// video standards to support. The array is allocated from the heap, and
-// the number of elements is returned in the first argument.
-struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr,
- v4l2_std_id id);
-
-// Return mask of which video standard bits are valid
-v4l2_std_id pvr2_std_get_usable(void);
-
-#endif /* __PVRUSB2_STD_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
deleted file mode 100644
index 6ef1335b285..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ /dev/null
@@ -1,861 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/string.h>
-#include <linux/slab.h>
-#include "pvrusb2-sysfs.h"
-#include "pvrusb2-hdw.h"
-#include "pvrusb2-debug.h"
-#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
-#include "pvrusb2-debugifc.h"
-#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
-
-#define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__)
-
-struct pvr2_sysfs {
- struct pvr2_channel channel;
- struct device *class_dev;
-#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
- struct pvr2_sysfs_debugifc *debugifc;
-#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
- struct pvr2_sysfs_ctl_item *item_first;
- struct pvr2_sysfs_ctl_item *item_last;
- struct device_attribute attr_v4l_minor_number;
- struct device_attribute attr_v4l_radio_minor_number;
- struct device_attribute attr_unit_number;
- struct device_attribute attr_bus_info;
- struct device_attribute attr_hdw_name;
- struct device_attribute attr_hdw_desc;
- int v4l_minor_number_created_ok;
- int v4l_radio_minor_number_created_ok;
- int unit_number_created_ok;
- int bus_info_created_ok;
- int hdw_name_created_ok;
- int hdw_desc_created_ok;
-};
-
-#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
-struct pvr2_sysfs_debugifc {
- struct device_attribute attr_debugcmd;
- struct device_attribute attr_debuginfo;
- int debugcmd_created_ok;
- int debuginfo_created_ok;
-};
-#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
-
-struct pvr2_sysfs_ctl_item {
- struct device_attribute attr_name;
- struct device_attribute attr_type;
- struct device_attribute attr_min;
- struct device_attribute attr_max;
- struct device_attribute attr_def;
- struct device_attribute attr_enum;
- struct device_attribute attr_bits;
- struct device_attribute attr_val;
- struct device_attribute attr_custom;
- struct pvr2_ctrl *cptr;
- int ctl_id;
- struct pvr2_sysfs *chptr;
- struct pvr2_sysfs_ctl_item *item_next;
- struct attribute *attr_gen[8];
- struct attribute_group grp;
- int created_ok;
- char name[80];
-};
-
-struct pvr2_sysfs_class {
- struct class class;
-};
-
-static ssize_t show_name(struct device *class_dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct pvr2_sysfs_ctl_item *cip;
- const char *name;
- cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_name);
- name = pvr2_ctrl_get_desc(cip->cptr);
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",
- cip->chptr, cip->ctl_id, name);
- if (!name) return -EINVAL;
- return scnprintf(buf, PAGE_SIZE, "%s\n", name);
-}
-
-static ssize_t show_type(struct device *class_dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct pvr2_sysfs_ctl_item *cip;
- const char *name;
- enum pvr2_ctl_type tp;
- cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_type);
- tp = pvr2_ctrl_get_type(cip->cptr);
- switch (tp) {
- case pvr2_ctl_int: name = "integer"; break;
- case pvr2_ctl_enum: name = "enum"; break;
- case pvr2_ctl_bitmask: name = "bitmask"; break;
- case pvr2_ctl_bool: name = "boolean"; break;
- default: name = "?"; break;
- }
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",
- cip->chptr, cip->ctl_id, name);
- if (!name) return -EINVAL;
- return scnprintf(buf, PAGE_SIZE, "%s\n", name);
-}
-
-static ssize_t show_min(struct device *class_dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct pvr2_sysfs_ctl_item *cip;
- long val;
- cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_min);
- val = pvr2_ctrl_get_min(cip->cptr);
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",
- cip->chptr, cip->ctl_id, val);
- return scnprintf(buf, PAGE_SIZE, "%ld\n", val);
-}
-
-static ssize_t show_max(struct device *class_dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct pvr2_sysfs_ctl_item *cip;
- long val;
- cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_max);
- val = pvr2_ctrl_get_max(cip->cptr);
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",
- cip->chptr, cip->ctl_id, val);
- return scnprintf(buf, PAGE_SIZE, "%ld\n", val);
-}
-
-static ssize_t show_def(struct device *class_dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct pvr2_sysfs_ctl_item *cip;
- int val;
- int ret;
- unsigned int cnt = 0;
- cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_def);
- ret = pvr2_ctrl_get_def(cip->cptr, &val);
- if (ret < 0) return ret;
- ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val,
- buf, PAGE_SIZE - 1, &cnt);
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %.*s (%d)",
- cip->chptr, cip->ctl_id, cnt, buf, val);
- buf[cnt] = '\n';
- return cnt + 1;
-}
-
-static ssize_t show_val_norm(struct device *class_dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct pvr2_sysfs_ctl_item *cip;
- int val;
- int ret;
- unsigned int cnt = 0;
- cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val);
- ret = pvr2_ctrl_get_value(cip->cptr, &val);
- if (ret < 0) return ret;
- ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val,
- buf, PAGE_SIZE - 1, &cnt);
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
- cip->chptr, cip->ctl_id, cnt, buf, val);
- buf[cnt] = '\n';
- return cnt+1;
-}
-
-static ssize_t show_val_custom(struct device *class_dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct pvr2_sysfs_ctl_item *cip;
- int val;
- int ret;
- unsigned int cnt = 0;
- cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom);
- ret = pvr2_ctrl_get_value(cip->cptr, &val);
- if (ret < 0) return ret;
- ret = pvr2_ctrl_custom_value_to_sym(cip->cptr, ~0, val,
- buf, PAGE_SIZE - 1, &cnt);
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
- cip->chptr, cip->ctl_id, cnt, buf, val);
- buf[cnt] = '\n';
- return cnt+1;
-}
-
-static ssize_t show_enum(struct device *class_dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct pvr2_sysfs_ctl_item *cip;
- long val;
- unsigned int bcnt, ccnt, ecnt;
- cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_enum);
- ecnt = pvr2_ctrl_get_cnt(cip->cptr);
- bcnt = 0;
- for (val = 0; val < ecnt; val++) {
- pvr2_ctrl_get_valname(cip->cptr, val, buf + bcnt,
- PAGE_SIZE - bcnt, &ccnt);
- if (!ccnt) continue;
- bcnt += ccnt;
- if (bcnt >= PAGE_SIZE) break;
- buf[bcnt] = '\n';
- bcnt++;
- }
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",
- cip->chptr, cip->ctl_id);
- return bcnt;
-}
-
-static ssize_t show_bits(struct device *class_dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct pvr2_sysfs_ctl_item *cip;
- int valid_bits, msk;
- unsigned int bcnt, ccnt;
- cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_bits);
- valid_bits = pvr2_ctrl_get_mask(cip->cptr);
- bcnt = 0;
- for (msk = 1; valid_bits; msk <<= 1) {
- if (!(msk & valid_bits)) continue;
- valid_bits &= ~msk;
- pvr2_ctrl_get_valname(cip->cptr, msk, buf + bcnt,
- PAGE_SIZE - bcnt, &ccnt);
- bcnt += ccnt;
- if (bcnt >= PAGE_SIZE) break;
- buf[bcnt] = '\n';
- bcnt++;
- }
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",
- cip->chptr, cip->ctl_id);
- return bcnt;
-}
-
-static int store_val_any(struct pvr2_sysfs_ctl_item *cip, int customfl,
- const char *buf,unsigned int count)
-{
- int ret;
- int mask,val;
- if (customfl) {
- ret = pvr2_ctrl_custom_sym_to_value(cip->cptr, buf, count,
- &mask, &val);
- } else {
- ret = pvr2_ctrl_sym_to_value(cip->cptr, buf, count,
- &mask, &val);
- }
- if (ret < 0) return ret;
- ret = pvr2_ctrl_set_mask_value(cip->cptr, mask, val);
- pvr2_hdw_commit_ctl(cip->chptr->channel.hdw);
- return ret;
-}
-
-static ssize_t store_val_norm(struct device *class_dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct pvr2_sysfs_ctl_item *cip;
- int ret;
- cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val);
- pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"",
- cip->chptr, cip->ctl_id, (int)count, buf);
- ret = store_val_any(cip, 0, buf, count);
- if (!ret) ret = count;
- return ret;
-}
-
-static ssize_t store_val_custom(struct device *class_dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct pvr2_sysfs_ctl_item *cip;
- int ret;
- cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom);
- pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"",
- cip->chptr, cip->ctl_id, (int)count, buf);
- ret = store_val_any(cip, 1, buf, count);
- if (!ret) ret = count;
- return ret;
-}
-
-static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
-{
- struct pvr2_sysfs_ctl_item *cip;
- struct pvr2_ctrl *cptr;
- unsigned int cnt,acnt;
- int ret;
-
- cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id);
- if (!cptr) return;
-
- cip = kzalloc(sizeof(*cip),GFP_KERNEL);
- if (!cip) return;
- pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip);
-
- cip->cptr = cptr;
- cip->ctl_id = ctl_id;
-
- cip->chptr = sfp;
- cip->item_next = NULL;
- if (sfp->item_last) {
- sfp->item_last->item_next = cip;
- } else {
- sfp->item_first = cip;
- }
- sfp->item_last = cip;
-
- sysfs_attr_init(&cip->attr_name.attr);
- cip->attr_name.attr.name = "name";
- cip->attr_name.attr.mode = S_IRUGO;
- cip->attr_name.show = show_name;
-
- sysfs_attr_init(&cip->attr_type.attr);
- cip->attr_type.attr.name = "type";
- cip->attr_type.attr.mode = S_IRUGO;
- cip->attr_type.show = show_type;
-
- sysfs_attr_init(&cip->attr_min.attr);
- cip->attr_min.attr.name = "min_val";
- cip->attr_min.attr.mode = S_IRUGO;
- cip->attr_min.show = show_min;
-
- sysfs_attr_init(&cip->attr_max.attr);
- cip->attr_max.attr.name = "max_val";
- cip->attr_max.attr.mode = S_IRUGO;
- cip->attr_max.show = show_max;
-
- sysfs_attr_init(&cip->attr_def.attr);
- cip->attr_def.attr.name = "def_val";
- cip->attr_def.attr.mode = S_IRUGO;
- cip->attr_def.show = show_def;
-
- sysfs_attr_init(&cip->attr_val.attr);
- cip->attr_val.attr.name = "cur_val";
- cip->attr_val.attr.mode = S_IRUGO;
-
- sysfs_attr_init(&cip->attr_custom.attr);
- cip->attr_custom.attr.name = "custom_val";
- cip->attr_custom.attr.mode = S_IRUGO;
-
- sysfs_attr_init(&cip->attr_enum.attr);
- cip->attr_enum.attr.name = "enum_val";
- cip->attr_enum.attr.mode = S_IRUGO;
- cip->attr_enum.show = show_enum;
-
- sysfs_attr_init(&cip->attr_bits.attr);
- cip->attr_bits.attr.name = "bit_val";
- cip->attr_bits.attr.mode = S_IRUGO;
- cip->attr_bits.show = show_bits;
-
- if (pvr2_ctrl_is_writable(cptr)) {
- cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP;
- cip->attr_custom.attr.mode |= S_IWUSR|S_IWGRP;
- }
-
- acnt = 0;
- cip->attr_gen[acnt++] = &cip->attr_name.attr;
- cip->attr_gen[acnt++] = &cip->attr_type.attr;
- cip->attr_gen[acnt++] = &cip->attr_val.attr;
- cip->attr_gen[acnt++] = &cip->attr_def.attr;
- cip->attr_val.show = show_val_norm;
- cip->attr_val.store = store_val_norm;
- if (pvr2_ctrl_has_custom_symbols(cptr)) {
- cip->attr_gen[acnt++] = &cip->attr_custom.attr;
- cip->attr_custom.show = show_val_custom;
- cip->attr_custom.store = store_val_custom;
- }
- switch (pvr2_ctrl_get_type(cptr)) {
- case pvr2_ctl_enum:
- // Control is an enumeration
- cip->attr_gen[acnt++] = &cip->attr_enum.attr;
- break;
- case pvr2_ctl_int:
- // Control is an integer
- cip->attr_gen[acnt++] = &cip->attr_min.attr;
- cip->attr_gen[acnt++] = &cip->attr_max.attr;
- break;
- case pvr2_ctl_bitmask:
- // Control is an bitmask
- cip->attr_gen[acnt++] = &cip->attr_bits.attr;
- break;
- default: break;
- }
-
- cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s",
- pvr2_ctrl_get_name(cptr));
- cip->name[cnt] = 0;
- cip->grp.name = cip->name;
- cip->grp.attrs = cip->attr_gen;
-
- ret = sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
- if (ret) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "sysfs_create_group error: %d",
- ret);
- return;
- }
- cip->created_ok = !0;
-}
-
-#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
-static ssize_t debuginfo_show(struct device *, struct device_attribute *,
- char *);
-static ssize_t debugcmd_show(struct device *, struct device_attribute *,
- char *);
-static ssize_t debugcmd_store(struct device *, struct device_attribute *,
- const char *, size_t count);
-
-static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
-{
- struct pvr2_sysfs_debugifc *dip;
- int ret;
-
- dip = kzalloc(sizeof(*dip),GFP_KERNEL);
- if (!dip) return;
- sysfs_attr_init(&dip->attr_debugcmd.attr);
- dip->attr_debugcmd.attr.name = "debugcmd";
- dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
- dip->attr_debugcmd.show = debugcmd_show;
- dip->attr_debugcmd.store = debugcmd_store;
- sysfs_attr_init(&dip->attr_debuginfo.attr);
- dip->attr_debuginfo.attr.name = "debuginfo";
- dip->attr_debuginfo.attr.mode = S_IRUGO;
- dip->attr_debuginfo.show = debuginfo_show;
- sfp->debugifc = dip;
- ret = device_create_file(sfp->class_dev,&dip->attr_debugcmd);
- if (ret < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "device_create_file error: %d",
- ret);
- } else {
- dip->debugcmd_created_ok = !0;
- }
- ret = device_create_file(sfp->class_dev,&dip->attr_debuginfo);
- if (ret < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "device_create_file error: %d",
- ret);
- } else {
- dip->debuginfo_created_ok = !0;
- }
-}
-
-
-static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp)
-{
- if (!sfp->debugifc) return;
- if (sfp->debugifc->debuginfo_created_ok) {
- device_remove_file(sfp->class_dev,
- &sfp->debugifc->attr_debuginfo);
- }
- if (sfp->debugifc->debugcmd_created_ok) {
- device_remove_file(sfp->class_dev,
- &sfp->debugifc->attr_debugcmd);
- }
- kfree(sfp->debugifc);
- sfp->debugifc = NULL;
-}
-#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
-
-
-static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp)
-{
- unsigned int idx,cnt;
- cnt = pvr2_hdw_get_ctrl_count(sfp->channel.hdw);
- for (idx = 0; idx < cnt; idx++) {
- pvr2_sysfs_add_control(sfp,idx);
- }
-}
-
-
-static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp)
-{
- struct pvr2_sysfs_ctl_item *cip1,*cip2;
- for (cip1 = sfp->item_first; cip1; cip1 = cip2) {
- cip2 = cip1->item_next;
- if (cip1->created_ok) {
- sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp);
- }
- pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1);
- kfree(cip1);
- }
-}
-
-
-static void pvr2_sysfs_class_release(struct class *class)
-{
- struct pvr2_sysfs_class *clp;
- clp = container_of(class,struct pvr2_sysfs_class,class);
- pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp);
- kfree(clp);
-}
-
-
-static void pvr2_sysfs_release(struct device *class_dev)
-{
- pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev);
- kfree(class_dev);
-}
-
-
-static void class_dev_destroy(struct pvr2_sysfs *sfp)
-{
- struct device *dev;
- if (!sfp->class_dev) return;
-#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
- pvr2_sysfs_tear_down_debugifc(sfp);
-#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
- pvr2_sysfs_tear_down_controls(sfp);
- if (sfp->hdw_desc_created_ok) {
- device_remove_file(sfp->class_dev,
- &sfp->attr_hdw_desc);
- }
- if (sfp->hdw_name_created_ok) {
- device_remove_file(sfp->class_dev,
- &sfp->attr_hdw_name);
- }
- if (sfp->bus_info_created_ok) {
- device_remove_file(sfp->class_dev,
- &sfp->attr_bus_info);
- }
- if (sfp->v4l_minor_number_created_ok) {
- device_remove_file(sfp->class_dev,
- &sfp->attr_v4l_minor_number);
- }
- if (sfp->v4l_radio_minor_number_created_ok) {
- device_remove_file(sfp->class_dev,
- &sfp->attr_v4l_radio_minor_number);
- }
- if (sfp->unit_number_created_ok) {
- device_remove_file(sfp->class_dev,
- &sfp->attr_unit_number);
- }
- pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
- dev_set_drvdata(sfp->class_dev, NULL);
- dev = sfp->class_dev->parent;
- sfp->class_dev->parent = NULL;
- put_device(dev);
- device_unregister(sfp->class_dev);
- sfp->class_dev = NULL;
-}
-
-
-static ssize_t v4l_minor_number_show(struct device *class_dev,
- struct device_attribute *attr, char *buf)
-{
- struct pvr2_sysfs *sfp;
- sfp = dev_get_drvdata(class_dev);
- if (!sfp) return -EINVAL;
- return scnprintf(buf,PAGE_SIZE,"%d\n",
- pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
- pvr2_v4l_type_video));
-}
-
-
-static ssize_t bus_info_show(struct device *class_dev,
- struct device_attribute *attr, char *buf)
-{
- struct pvr2_sysfs *sfp;
- sfp = dev_get_drvdata(class_dev);
- if (!sfp) return -EINVAL;
- return scnprintf(buf,PAGE_SIZE,"%s\n",
- pvr2_hdw_get_bus_info(sfp->channel.hdw));
-}
-
-
-static ssize_t hdw_name_show(struct device *class_dev,
- struct device_attribute *attr, char *buf)
-{
- struct pvr2_sysfs *sfp;
- sfp = dev_get_drvdata(class_dev);
- if (!sfp) return -EINVAL;
- return scnprintf(buf,PAGE_SIZE,"%s\n",
- pvr2_hdw_get_type(sfp->channel.hdw));
-}
-
-
-static ssize_t hdw_desc_show(struct device *class_dev,
- struct device_attribute *attr, char *buf)
-{
- struct pvr2_sysfs *sfp;
- sfp = dev_get_drvdata(class_dev);
- if (!sfp) return -EINVAL;
- return scnprintf(buf,PAGE_SIZE,"%s\n",
- pvr2_hdw_get_desc(sfp->channel.hdw));
-}
-
-
-static ssize_t v4l_radio_minor_number_show(struct device *class_dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct pvr2_sysfs *sfp;
- sfp = dev_get_drvdata(class_dev);
- if (!sfp) return -EINVAL;
- return scnprintf(buf,PAGE_SIZE,"%d\n",
- pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
- pvr2_v4l_type_radio));
-}
-
-
-static ssize_t unit_number_show(struct device *class_dev,
- struct device_attribute *attr, char *buf)
-{
- struct pvr2_sysfs *sfp;
- sfp = dev_get_drvdata(class_dev);
- if (!sfp) return -EINVAL;
- return scnprintf(buf,PAGE_SIZE,"%d\n",
- pvr2_hdw_get_unit_number(sfp->channel.hdw));
-}
-
-
-static void class_dev_create(struct pvr2_sysfs *sfp,
- struct pvr2_sysfs_class *class_ptr)
-{
- struct usb_device *usb_dev;
- struct device *class_dev;
- int ret;
-
- usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw);
- if (!usb_dev) return;
- class_dev = kzalloc(sizeof(*class_dev),GFP_KERNEL);
- if (!class_dev) return;
-
- pvr2_sysfs_trace("Creating class_dev id=%p",class_dev);
-
- class_dev->class = &class_ptr->class;
-
- dev_set_name(class_dev, "%s",
- pvr2_hdw_get_device_identifier(sfp->channel.hdw));
-
- class_dev->parent = get_device(&usb_dev->dev);
-
- sfp->class_dev = class_dev;
- dev_set_drvdata(class_dev, sfp);
- ret = device_register(class_dev);
- if (ret) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "device_register failed");
- put_device(class_dev);
- return;
- }
-
- sysfs_attr_init(&sfp->attr_v4l_minor_number.attr);
- sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
- sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
- sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
- sfp->attr_v4l_minor_number.store = NULL;
- ret = device_create_file(sfp->class_dev,
- &sfp->attr_v4l_minor_number);
- if (ret < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "device_create_file error: %d",
- ret);
- } else {
- sfp->v4l_minor_number_created_ok = !0;
- }
-
- sysfs_attr_init(&sfp->attr_v4l_radio_minor_number.attr);
- sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number";
- sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO;
- sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show;
- sfp->attr_v4l_radio_minor_number.store = NULL;
- ret = device_create_file(sfp->class_dev,
- &sfp->attr_v4l_radio_minor_number);
- if (ret < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "device_create_file error: %d",
- ret);
- } else {
- sfp->v4l_radio_minor_number_created_ok = !0;
- }
-
- sysfs_attr_init(&sfp->attr_unit_number.attr);
- sfp->attr_unit_number.attr.name = "unit_number";
- sfp->attr_unit_number.attr.mode = S_IRUGO;
- sfp->attr_unit_number.show = unit_number_show;
- sfp->attr_unit_number.store = NULL;
- ret = device_create_file(sfp->class_dev,&sfp->attr_unit_number);
- if (ret < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "device_create_file error: %d",
- ret);
- } else {
- sfp->unit_number_created_ok = !0;
- }
-
- sysfs_attr_init(&sfp->attr_bus_info.attr);
- sfp->attr_bus_info.attr.name = "bus_info_str";
- sfp->attr_bus_info.attr.mode = S_IRUGO;
- sfp->attr_bus_info.show = bus_info_show;
- sfp->attr_bus_info.store = NULL;
- ret = device_create_file(sfp->class_dev,
- &sfp->attr_bus_info);
- if (ret < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "device_create_file error: %d",
- ret);
- } else {
- sfp->bus_info_created_ok = !0;
- }
-
- sysfs_attr_init(&sfp->attr_hdw_name.attr);
- sfp->attr_hdw_name.attr.name = "device_hardware_type";
- sfp->attr_hdw_name.attr.mode = S_IRUGO;
- sfp->attr_hdw_name.show = hdw_name_show;
- sfp->attr_hdw_name.store = NULL;
- ret = device_create_file(sfp->class_dev,
- &sfp->attr_hdw_name);
- if (ret < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "device_create_file error: %d",
- ret);
- } else {
- sfp->hdw_name_created_ok = !0;
- }
-
- sysfs_attr_init(&sfp->attr_hdw_desc.attr);
- sfp->attr_hdw_desc.attr.name = "device_hardware_description";
- sfp->attr_hdw_desc.attr.mode = S_IRUGO;
- sfp->attr_hdw_desc.show = hdw_desc_show;
- sfp->attr_hdw_desc.store = NULL;
- ret = device_create_file(sfp->class_dev,
- &sfp->attr_hdw_desc);
- if (ret < 0) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "device_create_file error: %d",
- ret);
- } else {
- sfp->hdw_desc_created_ok = !0;
- }
-
- pvr2_sysfs_add_controls(sfp);
-#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
- pvr2_sysfs_add_debugifc(sfp);
-#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
-}
-
-
-static void pvr2_sysfs_internal_check(struct pvr2_channel *chp)
-{
- struct pvr2_sysfs *sfp;
- sfp = container_of(chp,struct pvr2_sysfs,channel);
- if (!sfp->channel.mc_head->disconnect_flag) return;
- pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_sysfs id=%p",sfp);
- class_dev_destroy(sfp);
- pvr2_channel_done(&sfp->channel);
- kfree(sfp);
-}
-
-
-struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp,
- struct pvr2_sysfs_class *class_ptr)
-{
- struct pvr2_sysfs *sfp;
- sfp = kzalloc(sizeof(*sfp),GFP_KERNEL);
- if (!sfp) return sfp;
- pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_sysfs id=%p",sfp);
- pvr2_channel_init(&sfp->channel,mp);
- sfp->channel.check_func = pvr2_sysfs_internal_check;
-
- class_dev_create(sfp,class_ptr);
- return sfp;
-}
-
-
-
-struct pvr2_sysfs_class *pvr2_sysfs_class_create(void)
-{
- struct pvr2_sysfs_class *clp;
- clp = kzalloc(sizeof(*clp),GFP_KERNEL);
- if (!clp) return clp;
- pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p",
- clp);
- clp->class.name = "pvrusb2";
- clp->class.class_release = pvr2_sysfs_class_release;
- clp->class.dev_release = pvr2_sysfs_release;
- if (class_register(&clp->class)) {
- pvr2_sysfs_trace(
- "Registration failed for pvr2_sysfs_class id=%p",clp);
- kfree(clp);
- clp = NULL;
- }
- return clp;
-}
-
-
-void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp)
-{
- pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp);
- class_unregister(&clp->class);
-}
-
-
-#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
-static ssize_t debuginfo_show(struct device *class_dev,
- struct device_attribute *attr, char *buf)
-{
- struct pvr2_sysfs *sfp;
- sfp = dev_get_drvdata(class_dev);
- if (!sfp) return -EINVAL;
- pvr2_hdw_trigger_module_log(sfp->channel.hdw);
- return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE);
-}
-
-
-static ssize_t debugcmd_show(struct device *class_dev,
- struct device_attribute *attr, char *buf)
-{
- struct pvr2_sysfs *sfp;
- sfp = dev_get_drvdata(class_dev);
- if (!sfp) return -EINVAL;
- return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE);
-}
-
-
-static ssize_t debugcmd_store(struct device *class_dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct pvr2_sysfs *sfp;
- int ret;
-
- sfp = dev_get_drvdata(class_dev);
- if (!sfp) return -EINVAL;
-
- ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count);
- if (ret < 0) return ret;
- return count;
-}
-#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.h b/drivers/media/video/pvrusb2/pvrusb2-sysfs.h
deleted file mode 100644
index 6d875bfe799..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __PVRUSB2_SYSFS_H
-#define __PVRUSB2_SYSFS_H
-
-#include <linux/list.h>
-#include <linux/sysfs.h>
-#include "pvrusb2-context.h"
-
-struct pvr2_sysfs;
-struct pvr2_sysfs_class;
-
-struct pvr2_sysfs_class *pvr2_sysfs_class_create(void);
-void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *);
-
-struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *,
- struct pvr2_sysfs_class *);
-
-#endif /* __PVRUSB2_SYSFS_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-util.h b/drivers/media/video/pvrusb2/pvrusb2-util.h
deleted file mode 100644
index 92b75544ee2..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-util.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __PVRUSB2_UTIL_H
-#define __PVRUSB2_UTIL_H
-
-#define PVR2_DECOMPOSE_LE(t,i,d) \
- do { \
- (t)[i] = (d) & 0xff;\
- (t)[i+1] = ((d) >> 8) & 0xff;\
- (t)[i+2] = ((d) >> 16) & 0xff;\
- (t)[i+3] = ((d) >> 24) & 0xff;\
- } while(0)
-
-#define PVR2_DECOMPOSE_BE(t,i,d) \
- do { \
- (t)[i+3] = (d) & 0xff;\
- (t)[i+2] = ((d) >> 8) & 0xff;\
- (t)[i+1] = ((d) >> 16) & 0xff;\
- (t)[i] = ((d) >> 24) & 0xff;\
- } while(0)
-
-#define PVR2_COMPOSE_LE(t,i) \
- ((((u32)((t)[i+3])) << 24) | \
- (((u32)((t)[i+2])) << 16) | \
- (((u32)((t)[i+1])) << 8) | \
- ((u32)((t)[i])))
-
-#define PVR2_COMPOSE_BE(t,i) \
- ((((u32)((t)[i])) << 24) | \
- (((u32)((t)[i+1])) << 16) | \
- (((u32)((t)[i+2])) << 8) | \
- ((u32)((t)[i+3])))
-
-
-#endif /* __PVRUSB2_UTIL_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
deleted file mode 100644
index f344aed32a9..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ /dev/null
@@ -1,1413 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/version.h>
-#include "pvrusb2-context.h"
-#include "pvrusb2-hdw.h"
-#include "pvrusb2.h"
-#include "pvrusb2-debug.h"
-#include "pvrusb2-v4l2.h"
-#include "pvrusb2-ioread.h"
-#include <linux/videodev2.h>
-#include <linux/module.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-
-struct pvr2_v4l2_dev;
-struct pvr2_v4l2_fh;
-struct pvr2_v4l2;
-
-struct pvr2_v4l2_dev {
- struct video_device devbase; /* MUST be first! */
- struct pvr2_v4l2 *v4lp;
- struct pvr2_context_stream *stream;
- /* Information about this device: */
- enum pvr2_config config; /* Expected stream format */
- int v4l_type; /* V4L defined type for this device node */
- enum pvr2_v4l_type minor_type; /* pvr2-understood minor device type */
-};
-
-struct pvr2_v4l2_fh {
- struct pvr2_channel channel;
- struct pvr2_v4l2_dev *pdi;
- enum v4l2_priority prio;
- struct pvr2_ioread *rhp;
- struct file *file;
- struct pvr2_v4l2 *vhead;
- struct pvr2_v4l2_fh *vnext;
- struct pvr2_v4l2_fh *vprev;
- wait_queue_head_t wait_data;
- int fw_mode_flag;
- /* Map contiguous ordinal value to input id */
- unsigned char *input_map;
- unsigned int input_cnt;
-};
-
-struct pvr2_v4l2 {
- struct pvr2_channel channel;
- struct pvr2_v4l2_fh *vfirst;
- struct pvr2_v4l2_fh *vlast;
-
- struct v4l2_prio_state prio;
-
- /* streams - Note that these must be separately, individually,
- * allocated pointers. This is because the v4l core is going to
- * manage their deletion - separately, individually... */
- struct pvr2_v4l2_dev *dev_video;
- struct pvr2_v4l2_dev *dev_radio;
-};
-
-static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
-module_param_array(video_nr, int, NULL, 0444);
-MODULE_PARM_DESC(video_nr, "Offset for device's video dev minor");
-static int radio_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
-module_param_array(radio_nr, int, NULL, 0444);
-MODULE_PARM_DESC(radio_nr, "Offset for device's radio dev minor");
-static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
-module_param_array(vbi_nr, int, NULL, 0444);
-MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor");
-
-static struct v4l2_capability pvr_capability ={
- .driver = "pvrusb2",
- .card = "Hauppauge WinTV pvr-usb2",
- .bus_info = "usb",
- .version = LINUX_VERSION_CODE,
- .capabilities = (V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
- V4L2_CAP_READWRITE),
-};
-
-static struct v4l2_fmtdesc pvr_fmtdesc [] = {
- {
- .index = 0,
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- .flags = V4L2_FMT_FLAG_COMPRESSED,
- .description = "MPEG1/2",
- // This should really be V4L2_PIX_FMT_MPEG, but xawtv
- // breaks when I do that.
- .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
- }
-};
-
-#define PVR_FORMAT_PIX 0
-#define PVR_FORMAT_VBI 1
-
-static struct v4l2_format pvr_format [] = {
- [PVR_FORMAT_PIX] = {
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- .fmt = {
- .pix = {
- .width = 720,
- .height = 576,
- // This should really be V4L2_PIX_FMT_MPEG,
- // but xawtv breaks when I do that.
- .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
- .field = V4L2_FIELD_INTERLACED,
- .bytesperline = 0, // doesn't make sense
- // here
- //FIXME : Don't know what to put here...
- .sizeimage = (32*1024),
- .colorspace = 0, // doesn't make sense here
- .priv = 0
- }
- }
- },
- [PVR_FORMAT_VBI] = {
- .type = V4L2_BUF_TYPE_VBI_CAPTURE,
- .fmt = {
- .vbi = {
- .sampling_rate = 27000000,
- .offset = 248,
- .samples_per_line = 1443,
- .sample_format = V4L2_PIX_FMT_GREY,
- .start = { 0, 0 },
- .count = { 0, 0 },
- .flags = 0,
- }
- }
- }
-};
-
-
-
-/*
- * This is part of Video 4 Linux API. These procedures handle ioctl() calls.
- */
-static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
-
- memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability));
- strlcpy(cap->bus_info, pvr2_hdw_get_bus_info(hdw),
- sizeof(cap->bus_info));
- strlcpy(cap->card, pvr2_hdw_get_desc(hdw), sizeof(cap->card));
- return 0;
-}
-
-static int pvr2_g_priority(struct file *file, void *priv, enum v4l2_priority *p)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_v4l2 *vp = fh->vhead;
-
- *p = v4l2_prio_max(&vp->prio);
- return 0;
-}
-
-static int pvr2_s_priority(struct file *file, void *priv, enum v4l2_priority prio)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_v4l2 *vp = fh->vhead;
-
- return v4l2_prio_change(&vp->prio, &fh->prio, prio);
-}
-
-static int pvr2_g_std(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- int val = 0;
- int ret;
-
- ret = pvr2_ctrl_get_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDCUR), &val);
- *std = val;
- return ret;
-}
-
-int pvr2_s_std(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
-
- return pvr2_ctrl_set_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDCUR), *std);
-}
-
-static int pvr2_querystd(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- int val = 0;
- int ret;
-
- ret = pvr2_ctrl_get_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDDETECT), &val);
- *std = val;
- return ret;
-}
-
-static int pvr2_enum_input(struct file *file, void *priv, struct v4l2_input *vi)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- struct pvr2_ctrl *cptr;
- struct v4l2_input tmp;
- unsigned int cnt;
- int val;
-
- cptr = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
-
- memset(&tmp, 0, sizeof(tmp));
- tmp.index = vi->index;
- if (vi->index >= fh->input_cnt)
- return -EINVAL;
- val = fh->input_map[vi->index];
- switch (val) {
- case PVR2_CVAL_INPUT_TV:
- case PVR2_CVAL_INPUT_DTV:
- case PVR2_CVAL_INPUT_RADIO:
- tmp.type = V4L2_INPUT_TYPE_TUNER;
- break;
- case PVR2_CVAL_INPUT_SVIDEO:
- case PVR2_CVAL_INPUT_COMPOSITE:
- tmp.type = V4L2_INPUT_TYPE_CAMERA;
- break;
- default:
- return -EINVAL;
- }
-
- cnt = 0;
- pvr2_ctrl_get_valname(cptr, val,
- tmp.name, sizeof(tmp.name) - 1, &cnt);
- tmp.name[cnt] = 0;
-
- /* Don't bother with audioset, since this driver currently
- always switches the audio whenever the video is
- switched. */
-
- /* Handling std is a tougher problem. It doesn't make
- sense in cases where a device might be multi-standard.
- We could just copy out the current value for the
- standard, but it can change over time. For now just
- leave it zero. */
- *vi = tmp;
- return 0;
-}
-
-static int pvr2_g_input(struct file *file, void *priv, unsigned int *i)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- unsigned int idx;
- struct pvr2_ctrl *cptr;
- int val;
- int ret;
-
- cptr = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
- val = 0;
- ret = pvr2_ctrl_get_value(cptr, &val);
- *i = 0;
- for (idx = 0; idx < fh->input_cnt; idx++) {
- if (fh->input_map[idx] == val) {
- *i = idx;
- break;
- }
- }
- return ret;
-}
-
-static int pvr2_s_input(struct file *file, void *priv, unsigned int inp)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
-
- if (inp >= fh->input_cnt)
- return -EINVAL;
- return pvr2_ctrl_set_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT),
- fh->input_map[inp]);
-}
-
-static int pvr2_enumaudio(struct file *file, void *priv, struct v4l2_audio *vin)
-{
- /* pkt: FIXME: We are returning one "fake" input here
- which could very well be called "whatever_we_like".
- This is for apps that want to see an audio input
- just to feel comfortable, as well as to test if
- it can do stereo or sth. There is actually no guarantee
- that the actual audio input cannot change behind the app's
- back, but most applications should not mind that either.
-
- Hopefully, mplayer people will work with us on this (this
- whole mess is to support mplayer pvr://), or Hans will come
- up with a more standard way to say "we have inputs but we
- don 't want you to change them independent of video" which
- will sort this mess.
- */
-
- if (vin->index > 0)
- return -EINVAL;
- strncpy(vin->name, "PVRUSB2 Audio", 14);
- vin->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
-static int pvr2_g_audio(struct file *file, void *priv, struct v4l2_audio *vin)
-{
- /* pkt: FIXME: see above comment (VIDIOC_ENUMAUDIO) */
- vin->index = 0;
- strncpy(vin->name, "PVRUSB2 Audio", 14);
- vin->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
-static int pvr2_s_audio(struct file *file, void *priv, struct v4l2_audio *vout)
-{
- if (vout->index)
- return -EINVAL;
- return 0;
-}
-
-static int pvr2_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
-
- if (vt->index != 0)
- return -EINVAL; /* Only answer for the 1st tuner */
-
- pvr2_hdw_execute_tuner_poll(hdw);
- return pvr2_hdw_get_tuner_status(hdw, vt);
-}
-
-static int pvr2_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
-
- if (vt->index != 0)
- return -EINVAL;
-
- return pvr2_ctrl_set_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_AUDIOMODE),
- vt->audmode);
-}
-
-int pvr2_s_frequency(struct file *file, void *priv, struct v4l2_frequency *vf)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- unsigned long fv;
- struct v4l2_tuner vt;
- int cur_input;
- struct pvr2_ctrl *ctrlp;
- int ret;
-
- ret = pvr2_hdw_get_tuner_status(hdw, &vt);
- if (ret != 0)
- return ret;
- ctrlp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
- ret = pvr2_ctrl_get_value(ctrlp, &cur_input);
- if (ret != 0)
- return ret;
- if (vf->type == V4L2_TUNER_RADIO) {
- if (cur_input != PVR2_CVAL_INPUT_RADIO)
- pvr2_ctrl_set_value(ctrlp, PVR2_CVAL_INPUT_RADIO);
- } else {
- if (cur_input == PVR2_CVAL_INPUT_RADIO)
- pvr2_ctrl_set_value(ctrlp, PVR2_CVAL_INPUT_TV);
- }
- fv = vf->frequency;
- if (vt.capability & V4L2_TUNER_CAP_LOW)
- fv = (fv * 125) / 2;
- else
- fv = fv * 62500;
- return pvr2_ctrl_set_value(
- pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),fv);
-}
-
-static int pvr2_g_frequency(struct file *file, void *priv, struct v4l2_frequency *vf)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- int val = 0;
- int cur_input;
- struct v4l2_tuner vt;
- int ret;
-
- ret = pvr2_hdw_get_tuner_status(hdw, &vt);
- if (ret != 0)
- return ret;
- ret = pvr2_ctrl_get_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_FREQUENCY),
- &val);
- if (ret != 0)
- return ret;
- pvr2_ctrl_get_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT),
- &cur_input);
- if (cur_input == PVR2_CVAL_INPUT_RADIO)
- vf->type = V4L2_TUNER_RADIO;
- else
- vf->type = V4L2_TUNER_ANALOG_TV;
- if (vt.capability & V4L2_TUNER_CAP_LOW)
- val = (val * 2) / 125;
- else
- val /= 62500;
- vf->frequency = val;
- return 0;
-}
-
-static int pvr2_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *fd)
-{
- /* Only one format is supported : mpeg.*/
- if (fd->index != 0)
- return -EINVAL;
-
- memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc));
- return 0;
-}
-
-static int pvr2_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- int val;
-
- memcpy(vf, &pvr_format[PVR_FORMAT_PIX], sizeof(struct v4l2_format));
- val = 0;
- pvr2_ctrl_get_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES),
- &val);
- vf->fmt.pix.width = val;
- val = 0;
- pvr2_ctrl_get_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES),
- &val);
- vf->fmt.pix.height = val;
- return 0;
-}
-
-static int pvr2_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- int lmin, lmax, ldef;
- struct pvr2_ctrl *hcp, *vcp;
- int h = vf->fmt.pix.height;
- int w = vf->fmt.pix.width;
-
- hcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES);
- vcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES);
-
- lmin = pvr2_ctrl_get_min(hcp);
- lmax = pvr2_ctrl_get_max(hcp);
- pvr2_ctrl_get_def(hcp, &ldef);
- if (w == -1)
- w = ldef;
- else if (w < lmin)
- w = lmin;
- else if (w > lmax)
- w = lmax;
- lmin = pvr2_ctrl_get_min(vcp);
- lmax = pvr2_ctrl_get_max(vcp);
- pvr2_ctrl_get_def(vcp, &ldef);
- if (h == -1)
- h = ldef;
- else if (h < lmin)
- h = lmin;
- else if (h > lmax)
- h = lmax;
-
- memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
- sizeof(struct v4l2_format));
- vf->fmt.pix.width = w;
- vf->fmt.pix.height = h;
- return 0;
-}
-
-static int pvr2_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- struct pvr2_ctrl *hcp, *vcp;
- int ret = pvr2_try_fmt_vid_cap(file, fh, vf);
-
- if (ret)
- return ret;
- hcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES);
- vcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES);
- pvr2_ctrl_set_value(hcp, vf->fmt.pix.width);
- pvr2_ctrl_set_value(vcp, vf->fmt.pix.height);
- return 0;
-}
-
-static int pvr2_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- struct pvr2_v4l2_dev *pdi = fh->pdi;
- int ret;
-
- if (!fh->pdi->stream) {
- /* No stream defined for this node. This means
- that we're not currently allowed to stream from
- this node. */
- return -EPERM;
- }
- ret = pvr2_hdw_set_stream_type(hdw, pdi->config);
- if (ret < 0)
- return ret;
- return pvr2_hdw_set_streaming(hdw, !0);
-}
-
-static int pvr2_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
-
- if (!fh->pdi->stream) {
- /* No stream defined for this node. This means
- that we're not currently allowed to stream from
- this node. */
- return -EPERM;
- }
- return pvr2_hdw_set_streaming(hdw, 0);
-}
-
-static int pvr2_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *vc)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- struct pvr2_ctrl *cptr;
- int val;
-
- if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) {
- cptr = pvr2_hdw_get_ctrl_nextv4l(
- hdw, (vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL));
- if (cptr)
- vc->id = pvr2_ctrl_get_v4lid(cptr);
- } else {
- cptr = pvr2_hdw_get_ctrl_v4l(hdw, vc->id);
- }
- if (!cptr) {
- pvr2_trace(PVR2_TRACE_V4LIOCTL,
- "QUERYCTRL id=0x%x not implemented here",
- vc->id);
- return -EINVAL;
- }
-
- pvr2_trace(PVR2_TRACE_V4LIOCTL,
- "QUERYCTRL id=0x%x mapping name=%s (%s)",
- vc->id, pvr2_ctrl_get_name(cptr),
- pvr2_ctrl_get_desc(cptr));
- strlcpy(vc->name, pvr2_ctrl_get_desc(cptr), sizeof(vc->name));
- vc->flags = pvr2_ctrl_get_v4lflags(cptr);
- pvr2_ctrl_get_def(cptr, &val);
- vc->default_value = val;
- switch (pvr2_ctrl_get_type(cptr)) {
- case pvr2_ctl_enum:
- vc->type = V4L2_CTRL_TYPE_MENU;
- vc->minimum = 0;
- vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1;
- vc->step = 1;
- break;
- case pvr2_ctl_bool:
- vc->type = V4L2_CTRL_TYPE_BOOLEAN;
- vc->minimum = 0;
- vc->maximum = 1;
- vc->step = 1;
- break;
- case pvr2_ctl_int:
- vc->type = V4L2_CTRL_TYPE_INTEGER;
- vc->minimum = pvr2_ctrl_get_min(cptr);
- vc->maximum = pvr2_ctrl_get_max(cptr);
- vc->step = 1;
- break;
- default:
- pvr2_trace(PVR2_TRACE_V4LIOCTL,
- "QUERYCTRL id=0x%x name=%s not mappable",
- vc->id, pvr2_ctrl_get_name(cptr));
- return -EINVAL;
- }
- return 0;
-}
-
-static int pvr2_querymenu(struct file *file, void *priv, struct v4l2_querymenu *vm)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- unsigned int cnt = 0;
- int ret;
-
- ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw, vm->id),
- vm->index,
- vm->name, sizeof(vm->name) - 1,
- &cnt);
- vm->name[cnt] = 0;
- return ret;
-}
-
-static int pvr2_g_ctrl(struct file *file, void *priv, struct v4l2_control *vc)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- int val = 0;
- int ret;
-
- ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw, vc->id),
- &val);
- vc->value = val;
- return ret;
-}
-
-static int pvr2_s_ctrl(struct file *file, void *priv, struct v4l2_control *vc)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
-
- return pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw, vc->id),
- vc->value);
-}
-
-static int pvr2_g_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctls)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- struct v4l2_ext_control *ctrl;
- unsigned int idx;
- int val;
- int ret;
-
- ret = 0;
- for (idx = 0; idx < ctls->count; idx++) {
- ctrl = ctls->controls + idx;
- ret = pvr2_ctrl_get_value(
- pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id), &val);
- if (ret) {
- ctls->error_idx = idx;
- return ret;
- }
- /* Ensure that if read as a 64 bit value, the user
- will still get a hopefully sane value */
- ctrl->value64 = 0;
- ctrl->value = val;
- }
- return 0;
-}
-
-static int pvr2_s_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctls)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- struct v4l2_ext_control *ctrl;
- unsigned int idx;
- int ret;
-
- ret = 0;
- for (idx = 0; idx < ctls->count; idx++) {
- ctrl = ctls->controls + idx;
- ret = pvr2_ctrl_set_value(
- pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id),
- ctrl->value);
- if (ret) {
- ctls->error_idx = idx;
- return ret;
- }
- }
- return 0;
-}
-
-static int pvr2_try_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctls)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- struct v4l2_ext_control *ctrl;
- struct pvr2_ctrl *pctl;
- unsigned int idx;
-
- /* For the moment just validate that the requested control
- actually exists. */
- for (idx = 0; idx < ctls->count; idx++) {
- ctrl = ctls->controls + idx;
- pctl = pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id);
- if (!pctl) {
- ctls->error_idx = idx;
- return -EINVAL;
- }
- }
- return 0;
-}
-
-static int pvr2_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cap)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- int ret;
-
- if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- ret = pvr2_hdw_get_cropcap(hdw, cap);
- cap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* paranoia */
- return ret;
-}
-
-static int pvr2_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- int val = 0;
- int ret;
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- ret = pvr2_ctrl_get_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), &val);
- if (ret != 0)
- return -EINVAL;
- crop->c.left = val;
- ret = pvr2_ctrl_get_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), &val);
- if (ret != 0)
- return -EINVAL;
- crop->c.top = val;
- ret = pvr2_ctrl_get_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), &val);
- if (ret != 0)
- return -EINVAL;
- crop->c.width = val;
- ret = pvr2_ctrl_get_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), &val);
- if (ret != 0)
- return -EINVAL;
- crop->c.height = val;
- return 0;
-}
-
-static int pvr2_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- int ret;
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- ret = pvr2_ctrl_set_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL),
- crop->c.left);
- if (ret != 0)
- return -EINVAL;
- ret = pvr2_ctrl_set_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT),
- crop->c.top);
- if (ret != 0)
- return -EINVAL;
- ret = pvr2_ctrl_set_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW),
- crop->c.width);
- if (ret != 0)
- return -EINVAL;
- ret = pvr2_ctrl_set_value(
- pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH),
- crop->c.height);
- if (ret != 0)
- return -EINVAL;
- return 0;
-}
-
-static int pvr2_log_status(struct file *file, void *priv)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
-
- pvr2_hdw_trigger_module_log(hdw);
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int pvr2_g_register(struct file *file, void *priv, struct v4l2_dbg_register *req)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- u64 val;
- int ret;
-
- ret = pvr2_hdw_register_access(
- hdw, &req->match, req->reg,
- 0, &val);
- req->val = val;
- return ret;
-}
-
-static int pvr2_s_register(struct file *file, void *priv, struct v4l2_dbg_register *req)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- u64 val;
- int ret;
-
- val = req->val;
- ret = pvr2_hdw_register_access(
- hdw, &req->match, req->reg,
- 1, &val);
- return ret;
-}
-#endif
-
-static const struct v4l2_ioctl_ops pvr2_ioctl_ops = {
- .vidioc_querycap = pvr2_querycap,
- .vidioc_g_priority = pvr2_g_priority,
- .vidioc_s_priority = pvr2_s_priority,
- .vidioc_s_audio = pvr2_s_audio,
- .vidioc_g_audio = pvr2_g_audio,
- .vidioc_enumaudio = pvr2_enumaudio,
- .vidioc_enum_input = pvr2_enum_input,
- .vidioc_cropcap = pvr2_cropcap,
- .vidioc_s_crop = pvr2_s_crop,
- .vidioc_g_crop = pvr2_g_crop,
- .vidioc_g_input = pvr2_g_input,
- .vidioc_s_input = pvr2_s_input,
- .vidioc_g_frequency = pvr2_g_frequency,
- .vidioc_s_frequency = pvr2_s_frequency,
- .vidioc_s_tuner = pvr2_s_tuner,
- .vidioc_g_tuner = pvr2_g_tuner,
- .vidioc_g_std = pvr2_g_std,
- .vidioc_s_std = pvr2_s_std,
- .vidioc_querystd = pvr2_querystd,
- .vidioc_log_status = pvr2_log_status,
- .vidioc_enum_fmt_vid_cap = pvr2_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = pvr2_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = pvr2_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = pvr2_try_fmt_vid_cap,
- .vidioc_streamon = pvr2_streamon,
- .vidioc_streamoff = pvr2_streamoff,
- .vidioc_queryctrl = pvr2_queryctrl,
- .vidioc_querymenu = pvr2_querymenu,
- .vidioc_g_ctrl = pvr2_g_ctrl,
- .vidioc_s_ctrl = pvr2_s_ctrl,
- .vidioc_g_ext_ctrls = pvr2_g_ext_ctrls,
- .vidioc_s_ext_ctrls = pvr2_s_ext_ctrls,
- .vidioc_try_ext_ctrls = pvr2_try_ext_ctrls,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = pvr2_g_register,
- .vidioc_s_register = pvr2_s_register,
-#endif
-};
-
-static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
-{
- struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw;
- enum pvr2_config cfg = dip->config;
- char msg[80];
- unsigned int mcnt;
-
- /* Construct the unregistration message *before* we actually
- perform the unregistration step. By doing it this way we don't
- have to worry about potentially touching deleted resources. */
- mcnt = scnprintf(msg, sizeof(msg) - 1,
- "pvrusb2: unregistered device %s [%s]",
- video_device_node_name(&dip->devbase),
- pvr2_config_get_name(cfg));
- msg[mcnt] = 0;
-
- pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1);
-
- /* Paranoia */
- dip->v4lp = NULL;
- dip->stream = NULL;
-
- /* Actual deallocation happens later when all internal references
- are gone. */
- video_unregister_device(&dip->devbase);
-
- printk(KERN_INFO "%s\n", msg);
-
-}
-
-
-static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip)
-{
- if (!dip) return;
- if (!dip->devbase.parent) return;
- dip->devbase.parent = NULL;
- device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE);
-}
-
-
-static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
-{
- if (vp->dev_video) {
- pvr2_v4l2_dev_destroy(vp->dev_video);
- vp->dev_video = NULL;
- }
- if (vp->dev_radio) {
- pvr2_v4l2_dev_destroy(vp->dev_radio);
- vp->dev_radio = NULL;
- }
-
- pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
- pvr2_channel_done(&vp->channel);
- kfree(vp);
-}
-
-
-static void pvr2_video_device_release(struct video_device *vdev)
-{
- struct pvr2_v4l2_dev *dev;
- dev = container_of(vdev,struct pvr2_v4l2_dev,devbase);
- kfree(dev);
-}
-
-
-static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
-{
- struct pvr2_v4l2 *vp;
- vp = container_of(chp,struct pvr2_v4l2,channel);
- if (!vp->channel.mc_head->disconnect_flag) return;
- pvr2_v4l2_dev_disassociate_parent(vp->dev_video);
- pvr2_v4l2_dev_disassociate_parent(vp->dev_radio);
- if (vp->vfirst) return;
- pvr2_v4l2_destroy_no_lock(vp);
-}
-
-
-static long pvr2_v4l2_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
-
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_v4l2 *vp = fh->vhead;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- long ret = -EINVAL;
-
- if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL)
- v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw), cmd);
-
- if (!pvr2_hdw_dev_ok(hdw)) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "ioctl failed - bad or no context");
- return -EFAULT;
- }
-
- /* check priority */
- switch (cmd) {
- case VIDIOC_S_CTRL:
- case VIDIOC_S_STD:
- case VIDIOC_S_INPUT:
- case VIDIOC_S_TUNER:
- case VIDIOC_S_FREQUENCY:
- ret = v4l2_prio_check(&vp->prio, fh->prio);
- if (ret)
- return ret;
- }
-
- ret = video_ioctl2(file, cmd, arg);
-
- pvr2_hdw_commit_ctl(hdw);
-
- if (ret < 0) {
- if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
- pvr2_trace(PVR2_TRACE_V4LIOCTL,
- "pvr2_v4l2_do_ioctl failure, ret=%ld", ret);
- } else {
- if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
- pvr2_trace(PVR2_TRACE_V4LIOCTL,
- "pvr2_v4l2_do_ioctl failure, ret=%ld"
- " command was:", ret);
- v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw),
- cmd);
- }
- }
- } else {
- pvr2_trace(PVR2_TRACE_V4LIOCTL,
- "pvr2_v4l2_do_ioctl complete, ret=%ld (0x%lx)",
- ret, ret);
- }
- return ret;
-
-}
-
-
-static int pvr2_v4l2_release(struct file *file)
-{
- struct pvr2_v4l2_fh *fhp = file->private_data;
- struct pvr2_v4l2 *vp = fhp->vhead;
- struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw;
-
- pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release");
-
- if (fhp->rhp) {
- struct pvr2_stream *sp;
- pvr2_hdw_set_streaming(hdw,0);
- sp = pvr2_ioread_get_stream(fhp->rhp);
- if (sp) pvr2_stream_set_callback(sp,NULL,NULL);
- pvr2_ioread_destroy(fhp->rhp);
- fhp->rhp = NULL;
- }
-
- v4l2_prio_close(&vp->prio, fhp->prio);
- file->private_data = NULL;
-
- if (fhp->vnext) {
- fhp->vnext->vprev = fhp->vprev;
- } else {
- vp->vlast = fhp->vprev;
- }
- if (fhp->vprev) {
- fhp->vprev->vnext = fhp->vnext;
- } else {
- vp->vfirst = fhp->vnext;
- }
- fhp->vnext = NULL;
- fhp->vprev = NULL;
- fhp->vhead = NULL;
- pvr2_channel_done(&fhp->channel);
- pvr2_trace(PVR2_TRACE_STRUCT,
- "Destroying pvr_v4l2_fh id=%p",fhp);
- if (fhp->input_map) {
- kfree(fhp->input_map);
- fhp->input_map = NULL;
- }
- kfree(fhp);
- if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) {
- pvr2_v4l2_destroy_no_lock(vp);
- }
- return 0;
-}
-
-
-static int pvr2_v4l2_open(struct file *file)
-{
- struct pvr2_v4l2_dev *dip; /* Our own context pointer */
- struct pvr2_v4l2_fh *fhp;
- struct pvr2_v4l2 *vp;
- struct pvr2_hdw *hdw;
- unsigned int input_mask = 0;
- unsigned int input_cnt,idx;
- int ret = 0;
-
- dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase);
-
- vp = dip->v4lp;
- hdw = vp->channel.hdw;
-
- pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open");
-
- if (!pvr2_hdw_dev_ok(hdw)) {
- pvr2_trace(PVR2_TRACE_OPEN_CLOSE,
- "pvr2_v4l2_open: hardware not ready");
- return -EIO;
- }
-
- fhp = kzalloc(sizeof(*fhp),GFP_KERNEL);
- if (!fhp) {
- return -ENOMEM;
- }
-
- init_waitqueue_head(&fhp->wait_data);
- fhp->pdi = dip;
-
- pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
- pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
-
- if (dip->v4l_type == VFL_TYPE_RADIO) {
- /* Opening device as a radio, legal input selection subset
- is just the radio. */
- input_mask = (1 << PVR2_CVAL_INPUT_RADIO);
- } else {
- /* Opening the main V4L device, legal input selection
- subset includes all analog inputs. */
- input_mask = ((1 << PVR2_CVAL_INPUT_RADIO) |
- (1 << PVR2_CVAL_INPUT_TV) |
- (1 << PVR2_CVAL_INPUT_COMPOSITE) |
- (1 << PVR2_CVAL_INPUT_SVIDEO));
- }
- ret = pvr2_channel_limit_inputs(&fhp->channel,input_mask);
- if (ret) {
- pvr2_channel_done(&fhp->channel);
- pvr2_trace(PVR2_TRACE_STRUCT,
- "Destroying pvr_v4l2_fh id=%p (input mask error)",
- fhp);
-
- kfree(fhp);
- return ret;
- }
-
- input_mask &= pvr2_hdw_get_input_available(hdw);
- input_cnt = 0;
- for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
- if (input_mask & (1 << idx)) input_cnt++;
- }
- fhp->input_cnt = input_cnt;
- fhp->input_map = kzalloc(input_cnt,GFP_KERNEL);
- if (!fhp->input_map) {
- pvr2_channel_done(&fhp->channel);
- pvr2_trace(PVR2_TRACE_STRUCT,
- "Destroying pvr_v4l2_fh id=%p (input map failure)",
- fhp);
- kfree(fhp);
- return -ENOMEM;
- }
- input_cnt = 0;
- for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
- if (!(input_mask & (1 << idx))) continue;
- fhp->input_map[input_cnt++] = idx;
- }
-
- fhp->vnext = NULL;
- fhp->vprev = vp->vlast;
- if (vp->vlast) {
- vp->vlast->vnext = fhp;
- } else {
- vp->vfirst = fhp;
- }
- vp->vlast = fhp;
- fhp->vhead = vp;
-
- fhp->file = file;
- file->private_data = fhp;
- v4l2_prio_open(&vp->prio, &fhp->prio);
-
- fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
-
- return 0;
-}
-
-
-static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
-{
- wake_up(&fhp->wait_data);
-}
-
-static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
-{
- int ret;
- struct pvr2_stream *sp;
- struct pvr2_hdw *hdw;
- if (fh->rhp) return 0;
-
- if (!fh->pdi->stream) {
- /* No stream defined for this node. This means that we're
- not currently allowed to stream from this node. */
- return -EPERM;
- }
-
- /* First read() attempt. Try to claim the stream and start
- it... */
- if ((ret = pvr2_channel_claim_stream(&fh->channel,
- fh->pdi->stream)) != 0) {
- /* Someone else must already have it */
- return ret;
- }
-
- fh->rhp = pvr2_channel_create_mpeg_stream(fh->pdi->stream);
- if (!fh->rhp) {
- pvr2_channel_claim_stream(&fh->channel,NULL);
- return -ENOMEM;
- }
-
- hdw = fh->channel.mc_head->hdw;
- sp = fh->pdi->stream->stream;
- pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
- pvr2_hdw_set_stream_type(hdw,fh->pdi->config);
- if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret;
- return pvr2_ioread_set_enabled(fh->rhp,!0);
-}
-
-
-static ssize_t pvr2_v4l2_read(struct file *file,
- char __user *buff, size_t count, loff_t *ppos)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- int ret;
-
- if (fh->fw_mode_flag) {
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- char *tbuf;
- int c1,c2;
- int tcnt = 0;
- unsigned int offs = *ppos;
-
- tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL);
- if (!tbuf) return -ENOMEM;
-
- while (count) {
- c1 = count;
- if (c1 > PAGE_SIZE) c1 = PAGE_SIZE;
- c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1);
- if (c2 < 0) {
- tcnt = c2;
- break;
- }
- if (!c2) break;
- if (copy_to_user(buff,tbuf,c2)) {
- tcnt = -EFAULT;
- break;
- }
- offs += c2;
- tcnt += c2;
- buff += c2;
- count -= c2;
- *ppos += c2;
- }
- kfree(tbuf);
- return tcnt;
- }
-
- if (!fh->rhp) {
- ret = pvr2_v4l2_iosetup(fh);
- if (ret) {
- return ret;
- }
- }
-
- for (;;) {
- ret = pvr2_ioread_read(fh->rhp,buff,count);
- if (ret >= 0) break;
- if (ret != -EAGAIN) break;
- if (file->f_flags & O_NONBLOCK) break;
- /* Doing blocking I/O. Wait here. */
- ret = wait_event_interruptible(
- fh->wait_data,
- pvr2_ioread_avail(fh->rhp) >= 0);
- if (ret < 0) break;
- }
-
- return ret;
-}
-
-
-static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait)
-{
- unsigned int mask = 0;
- struct pvr2_v4l2_fh *fh = file->private_data;
- int ret;
-
- if (fh->fw_mode_flag) {
- mask |= POLLIN | POLLRDNORM;
- return mask;
- }
-
- if (!fh->rhp) {
- ret = pvr2_v4l2_iosetup(fh);
- if (ret) return POLLERR;
- }
-
- poll_wait(file,&fh->wait_data,wait);
-
- if (pvr2_ioread_avail(fh->rhp) >= 0) {
- mask |= POLLIN | POLLRDNORM;
- }
-
- return mask;
-}
-
-
-static const struct v4l2_file_operations vdev_fops = {
- .owner = THIS_MODULE,
- .open = pvr2_v4l2_open,
- .release = pvr2_v4l2_release,
- .read = pvr2_v4l2_read,
- .ioctl = pvr2_v4l2_ioctl,
- .poll = pvr2_v4l2_poll,
-};
-
-
-static struct video_device vdev_template = {
- .fops = &vdev_fops,
-};
-
-
-static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
- struct pvr2_v4l2 *vp,
- int v4l_type)
-{
- struct usb_device *usbdev;
- int mindevnum;
- int unit_number;
- struct pvr2_hdw *hdw;
- int *nr_ptr = NULL;
- dip->v4lp = vp;
-
- hdw = vp->channel.mc_head->hdw;
- usbdev = pvr2_hdw_get_dev(hdw);
- dip->v4l_type = v4l_type;
- switch (v4l_type) {
- case VFL_TYPE_GRABBER:
- dip->stream = &vp->channel.mc_head->video_stream;
- dip->config = pvr2_config_mpeg;
- dip->minor_type = pvr2_v4l_type_video;
- nr_ptr = video_nr;
- if (!dip->stream) {
- pr_err(KBUILD_MODNAME
- ": Failed to set up pvrusb2 v4l video dev"
- " due to missing stream instance\n");
- return;
- }
- break;
- case VFL_TYPE_VBI:
- dip->config = pvr2_config_vbi;
- dip->minor_type = pvr2_v4l_type_vbi;
- nr_ptr = vbi_nr;
- break;
- case VFL_TYPE_RADIO:
- dip->stream = &vp->channel.mc_head->video_stream;
- dip->config = pvr2_config_mpeg;
- dip->minor_type = pvr2_v4l_type_radio;
- nr_ptr = radio_nr;
- break;
- default:
- /* Bail out (this should be impossible) */
- pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev"
- " due to unrecognized config\n");
- return;
- }
-
- memcpy(&dip->devbase,&vdev_template,sizeof(vdev_template));
- dip->devbase.release = pvr2_video_device_release;
- dip->devbase.ioctl_ops = &pvr2_ioctl_ops;
- {
- int val;
- pvr2_ctrl_get_value(
- pvr2_hdw_get_ctrl_by_id(hdw,
- PVR2_CID_STDAVAIL), &val);
- dip->devbase.tvnorms = (v4l2_std_id)val;
- }
-
- mindevnum = -1;
- unit_number = pvr2_hdw_get_unit_number(hdw);
- if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
- mindevnum = nr_ptr[unit_number];
- }
- dip->devbase.parent = &usbdev->dev;
- if ((video_register_device(&dip->devbase,
- dip->v4l_type, mindevnum) < 0) &&
- (video_register_device(&dip->devbase,
- dip->v4l_type, -1) < 0)) {
- pr_err(KBUILD_MODNAME
- ": Failed to register pvrusb2 v4l device\n");
- }
-
- printk(KERN_INFO "pvrusb2: registered device %s [%s]\n",
- video_device_node_name(&dip->devbase),
- pvr2_config_get_name(dip->config));
-
- pvr2_hdw_v4l_store_minor_number(hdw,
- dip->minor_type,dip->devbase.minor);
-}
-
-
-struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
-{
- struct pvr2_v4l2 *vp;
-
- vp = kzalloc(sizeof(*vp),GFP_KERNEL);
- if (!vp) return vp;
- pvr2_channel_init(&vp->channel,mnp);
- pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
-
- vp->channel.check_func = pvr2_v4l2_internal_check;
-
- /* register streams */
- vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL);
- if (!vp->dev_video) goto fail;
- pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_GRABBER);
- if (pvr2_hdw_get_input_available(vp->channel.mc_head->hdw) &
- (1 << PVR2_CVAL_INPUT_RADIO)) {
- vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL);
- if (!vp->dev_radio) goto fail;
- pvr2_v4l2_dev_init(vp->dev_radio,vp,VFL_TYPE_RADIO);
- }
-
- return vp;
- fail:
- pvr2_trace(PVR2_TRACE_STRUCT,"Failure creating pvr2_v4l2 id=%p",vp);
- pvr2_v4l2_destroy_no_lock(vp);
- return NULL;
-}
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-v4l2.h
deleted file mode 100644
index 34c011a7b10..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __PVRUSB2_V4L2_H
-#define __PVRUSB2_V4L2_H
-
-#include "pvrusb2-context.h"
-
-struct pvr2_v4l2;
-
-struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *);
-
-#endif /* __PVRUSB2_V4L2_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
deleted file mode 100644
index 2e205c99eb9..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
-
- This source file is specifically designed to interface with the
- saa711x support that is available in the v4l available starting
- with linux 2.6.15.
-
-*/
-
-#include "pvrusb2-video-v4l.h"
-
-
-
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/saa7115.h>
-#include <linux/errno.h>
-
-struct routing_scheme {
- const int *def;
- unsigned int cnt;
-};
-
-
-static const int routing_scheme0[] = {
- [PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4,
- /* In radio mode, we mute the video, but point at one
- spot just to stay consistent */
- [PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5,
- [PVR2_CVAL_INPUT_COMPOSITE] = SAA7115_COMPOSITE5,
- [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2,
-};
-
-static const struct routing_scheme routing_def0 = {
- .def = routing_scheme0,
- .cnt = ARRAY_SIZE(routing_scheme0),
-};
-
-static const int routing_scheme1[] = {
- [PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4,
- [PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5,
- [PVR2_CVAL_INPUT_COMPOSITE] = SAA7115_COMPOSITE3,
- [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2, /* or SVIDEO0, it seems */
-};
-
-static const struct routing_scheme routing_def1 = {
- .def = routing_scheme1,
- .cnt = ARRAY_SIZE(routing_scheme1),
-};
-
-static const struct routing_scheme *routing_schemes[] = {
- [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
- [PVR2_ROUTING_SCHEME_ONAIR] = &routing_def1,
-};
-
-void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
-{
- if (hdw->input_dirty || hdw->force_dirty) {
- const struct routing_scheme *sp;
- unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
- u32 input;
-
- pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
- hdw->input_val);
-
- sp = (sid < ARRAY_SIZE(routing_schemes)) ?
- routing_schemes[sid] : NULL;
- if ((sp == NULL) ||
- (hdw->input_val < 0) ||
- (hdw->input_val >= sp->cnt)) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "*** WARNING *** subdev v4l2 set_input:"
- " Invalid routing scheme (%u)"
- " and/or input (%d)",
- sid, hdw->input_val);
- return;
- }
- input = sp->def[hdw->input_val];
- sd->ops->video->s_routing(sd, input, 0, 0);
- }
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
deleted file mode 100644
index 3b0bd5db602..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef __PVRUSB2_VIDEO_V4L_H
-#define __PVRUSB2_VIDEO_V4L_H
-
-/*
-
- This module connects the pvrusb2 driver to the I2C chip level
- driver which handles device video processing. This interface is
- used internally by the driver; higher level code should only
- interact through the interface provided by pvrusb2-hdw.h.
-
-*/
-
-
-#include "pvrusb2-hdw-internal.h"
-void pvr2_saa7115_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
-
-#endif /* __PVRUSB2_VIDEO_V4L_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
deleted file mode 100644
index 3ac8d751a5c..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
-
- This source file is specifically designed to interface with the
- wm8775.
-
-*/
-
-#include "pvrusb2-wm8775.h"
-
-
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <linux/errno.h>
-
-void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
-{
- if (hdw->input_dirty || hdw->force_dirty) {
- u32 input;
-
- switch (hdw->input_val) {
- case PVR2_CVAL_INPUT_RADIO:
- input = 1;
- break;
- default:
- /* All other cases just use the second input */
- input = 2;
- break;
- }
- pvr2_trace(PVR2_TRACE_CHIPS, "subdev wm8775"
- " set_input(val=%d route=0x%x)",
- hdw->input_val, input);
-
- sd->ops->audio->s_routing(sd, input, 0, 0);
- }
-}
-
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
deleted file mode 100644
index 0577bc7246f..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef __PVRUSB2_WM8775_H
-#define __PVRUSB2_WM8775_H
-
-/*
-
- This module connects the pvrusb2 driver to the I2C chip level
- driver which performs analog -> digital audio conversion for
- external audio inputs. This interface is used internally by the
- driver; higher level code should only interact through the
- interface provided by pvrusb2-hdw.h.
-
-*/
-
-
-
-#include "pvrusb2-hdw-internal.h"
-
-void pvr2_wm8775_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd);
-
-
-#endif /* __PVRUSB2_WM8775_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2.h b/drivers/media/video/pvrusb2/pvrusb2.h
deleted file mode 100644
index 240de9b3566..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef __PVRUSB2_H
-#define __PVRUSB2_H
-
-/* Maximum number of pvrusb2 instances we can track at once. You
- might want to increase this - however the driver operation will not
- be impaired if it is too small. Instead additional units just
- won't have an ID assigned and it might not be possible to specify
- module parameters for those extra units. */
-#define PVR_NUM 20
-
-#endif /* __PVRUSB2_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig
deleted file mode 100644
index d63d0a85003..00000000000
--- a/drivers/media/video/pwc/Kconfig
+++ /dev/null
@@ -1,48 +0,0 @@
-config USB_PWC
- tristate "USB Philips Cameras"
- depends on VIDEO_V4L2
- select VIDEOBUF2_VMALLOC
- ---help---
- Say Y or M here if you want to use one of these Philips & OEM
- webcams:
- * Philips PCA645, PCA646
- * Philips PCVC675, PCVC680, PCVC690
- * Philips PCVC720/40, PCVC730, PCVC740, PCVC750
- * Philips SPC900NC
- * Askey VC010
- * Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro'
- and 'Orbit'/'Sphere'
- * Samsung MPC-C10, MPC-C30
- * Creative Webcam 5, Pro Ex
- * SOTEC Afina Eye
- * Visionite VCS-UC300, VCS-UM100
-
- The PCA635, PCVC665 and PCVC720/20 are not supported by this driver
- and never will be, but the 665 and 720/20 are supported by other
- drivers.
-
- Some newer logitech webcams are not handled by this driver but by the
- Usb Video Class driver (linux-uvc).
-
- The built-in microphone is enabled by selecting USB Audio support.
-
- To compile this driver as a module, choose M here: the
- module will be called pwc.
-
-config USB_PWC_DEBUG
- bool "USB Philips Cameras verbose debug"
- depends on USB_PWC
- help
- Say Y here in order to have the pwc driver generate verbose debugging
- messages.
- A special module options 'trace' is used to control the verbosity.
-
-config USB_PWC_INPUT_EVDEV
- bool "USB Philips Cameras input events device support"
- default y
- depends on USB_PWC && (USB_PWC=INPUT || INPUT=y)
- ---help---
- This option makes USB Philips cameras register the snapshot button as
- an input device to report button events.
-
- If you are in doubt, say Y.
diff --git a/drivers/media/video/pwc/Makefile b/drivers/media/video/pwc/Makefile
deleted file mode 100644
index f5c8ec261e8..00000000000
--- a/drivers/media/video/pwc/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-v4l.o pwc-uncompress.o
-pwc-objs += pwc-dec1.o pwc-dec23.o pwc-kiara.o pwc-timon.o
-
-obj-$(CONFIG_USB_PWC) += pwc.o
diff --git a/drivers/media/video/pwc/philips.txt b/drivers/media/video/pwc/philips.txt
deleted file mode 100644
index d38dd791511..00000000000
--- a/drivers/media/video/pwc/philips.txt
+++ /dev/null
@@ -1,236 +0,0 @@
-This file contains some additional information for the Philips and OEM webcams.
-E-mail: webcam@smcc.demon.nl Last updated: 2004-01-19
-Site: http://www.smcc.demon.nl/webcam/
-
-As of this moment, the following cameras are supported:
- * Philips PCA645
- * Philips PCA646
- * Philips PCVC675
- * Philips PCVC680
- * Philips PCVC690
- * Philips PCVC720/40
- * Philips PCVC730
- * Philips PCVC740
- * Philips PCVC750
- * Askey VC010
- * Creative Labs Webcam 5
- * Creative Labs Webcam Pro Ex
- * Logitech QuickCam 3000 Pro
- * Logitech QuickCam 4000 Pro
- * Logitech QuickCam Notebook Pro
- * Logitech QuickCam Zoom
- * Logitech QuickCam Orbit
- * Logitech QuickCam Sphere
- * Samsung MPC-C10
- * Samsung MPC-C30
- * Sotec Afina Eye
- * AME CU-001
- * Visionite VCS-UM100
- * Visionite VCS-UC300
-
-The main webpage for the Philips driver is at the address above. It contains
-a lot of extra information, a FAQ, and the binary plugin 'PWCX'. This plugin
-contains decompression routines that allow you to use higher image sizes and
-framerates; in addition the webcam uses less bandwidth on the USB bus (handy
-if you want to run more than 1 camera simultaneously). These routines fall
-under a NDA, and may therefore not be distributed as source; however, its use
-is completely optional.
-
-You can build this code either into your kernel, or as a module. I recommend
-the latter, since it makes troubleshooting a lot easier. The built-in
-microphone is supported through the USB Audio class.
-
-When you load the module you can set some default settings for the
-camera; some programs depend on a particular image-size or -format and
-don't know how to set it properly in the driver. The options are:
-
-size
- Can be one of 'sqcif', 'qsif', 'qcif', 'sif', 'cif' or
- 'vga', for an image size of resp. 128x96, 160x120, 176x144,
- 320x240, 352x288 and 640x480 (of course, only for those cameras that
- support these resolutions).
-
-fps
- Specifies the desired framerate. Is an integer in the range of 4-30.
-
-fbufs
- This parameter specifies the number of internal buffers to use for storing
- frames from the cam. This will help if the process that reads images from
- the cam is a bit slow or momentarily busy. However, on slow machines it
- only introduces lag, so choose carefully. The default is 3, which is
- reasonable. You can set it between 2 and 5.
-
-mbufs
- This is an integer between 1 and 10. It will tell the module the number of
- buffers to reserve for mmap(), VIDIOCCGMBUF, VIDIOCMCAPTURE and friends.
- The default is 2, which is adequate for most applications (double
- buffering).
-
- Should you experience a lot of 'Dumping frame...' messages during
- grabbing with a tool that uses mmap(), you might want to increase if.
- However, it doesn't really buffer images, it just gives you a bit more
- slack when your program is behind. But you need a multi-threaded or
- forked program to really take advantage of these buffers.
-
- The absolute maximum is 10, but don't set it too high! Every buffer takes
- up 460 KB of RAM, so unless you have a lot of memory setting this to
- something more than 4 is an absolute waste. This memory is only
- allocated during open(), so nothing is wasted when the camera is not in
- use.
-
-power_save
- When power_save is enabled (set to 1), the module will try to shut down
- the cam on close() and re-activate on open(). This will save power and
- turn off the LED. Not all cameras support this though (the 645 and 646
- don't have power saving at all), and some models don't work either (they
- will shut down, but never wake up). Consider this experimental. By
- default this option is disabled.
-
-compression (only useful with the plugin)
- With this option you can control the compression factor that the camera
- uses to squeeze the image through the USB bus. You can set the
- parameter between 0 and 3:
- 0 = prefer uncompressed images; if the requested mode is not available
- in an uncompressed format, the driver will silently switch to low
- compression.
- 1 = low compression.
- 2 = medium compression.
- 3 = high compression.
-
- High compression takes less bandwidth of course, but it could also
- introduce some unwanted artefacts. The default is 2, medium compression.
- See the FAQ on the website for an overview of which modes require
- compression.
-
- The compression parameter does not apply to the 645 and 646 cameras
- and OEM models derived from those (only a few). Most cams honour this
- parameter.
-
-leds
- This settings takes 2 integers, that define the on/off time for the LED
- (in milliseconds). One of the interesting things that you can do with
- this is let the LED blink while the camera is in use. This:
-
- leds=500,500
-
- will blink the LED once every second. But with:
-
- leds=0,0
-
- the LED never goes on, making it suitable for silent surveillance.
-
- By default the camera's LED is on solid while in use, and turned off
- when the camera is not used anymore.
-
- This parameter works only with the ToUCam range of cameras (720, 730, 740,
- 750) and OEMs. For other cameras this command is silently ignored, and
- the LED cannot be controlled.
-
- Finally: this parameters does not take effect UNTIL the first time you
- open the camera device. Until then, the LED remains on.
-
-dev_hint
- A long standing problem with USB devices is their dynamic nature: you
- never know what device a camera gets assigned; it depends on module load
- order, the hub configuration, the order in which devices are plugged in,
- and the phase of the moon (i.e. it can be random). With this option you
- can give the driver a hint as to what video device node (/dev/videoX) it
- should use with a specific camera. This is also handy if you have two
- cameras of the same model.
-
- A camera is specified by its type (the number from the camera model,
- like PCA645, PCVC750VC, etc) and optionally the serial number (visible
- in /proc/bus/usb/devices). A hint consists of a string with the following
- format:
-
- [type[.serialnumber]:]node
-
- The square brackets mean that both the type and the serialnumber are
- optional, but a serialnumber cannot be specified without a type (which
- would be rather pointless). The serialnumber is separated from the type
- by a '.'; the node number by a ':'.
-
- This somewhat cryptic syntax is best explained by a few examples:
-
- dev_hint=3,5 The first detected cam gets assigned
- /dev/video3, the second /dev/video5. Any
- other cameras will get the first free
- available slot (see below).
-
- dev_hint=645:1,680:2 The PCA645 camera will get /dev/video1,
- and a PCVC680 /dev/video2.
-
- dev_hint=645.0123:3,645.4567:0 The PCA645 camera with serialnumber
- 0123 goes to /dev/video3, the same
- camera model with the 4567 serial
- gets /dev/video0.
-
- dev_hint=750:1,4,5,6 The PCVC750 camera will get /dev/video1, the
- next 3 Philips cams will use /dev/video4
- through /dev/video6.
-
- Some points worth knowing:
- - Serialnumbers are case sensitive and must be written full, including
- leading zeroes (it's treated as a string).
- - If a device node is already occupied, registration will fail and
- the webcam is not available.
- - You can have up to 64 video devices; be sure to make enough device
- nodes in /dev if you want to spread the numbers.
- After /dev/video9 comes /dev/video10 (not /dev/videoA).
- - If a camera does not match any dev_hint, it will simply get assigned
- the first available device node, just as it used to be.
-
-trace
- In order to better detect problems, it is now possible to turn on a
- 'trace' of some of the calls the module makes; it logs all items in your
- kernel log at debug level.
-
- The trace variable is a bitmask; each bit represents a certain feature.
- If you want to trace something, look up the bit value(s) in the table
- below, add the values together and supply that to the trace variable.
-
- Value Value Description Default
- (dec) (hex)
- 1 0x1 Module initialization; this will log messages On
- while loading and unloading the module
-
- 2 0x2 probe() and disconnect() traces On
-
- 4 0x4 Trace open() and close() calls Off
-
- 8 0x8 read(), mmap() and associated ioctl() calls Off
-
- 16 0x10 Memory allocation of buffers, etc. Off
-
- 32 0x20 Showing underflow, overflow and Dumping frame On
- messages
-
- 64 0x40 Show viewport and image sizes Off
-
- 128 0x80 PWCX debugging Off
-
- For example, to trace the open() & read() functions, sum 8 + 4 = 12,
- so you would supply trace=12 during insmod or modprobe. If
- you want to turn the initialization and probing tracing off, set trace=0.
- The default value for trace is 35 (0x23).
-
-
-
-Example:
-
- # modprobe pwc size=cif fps=15 power_save=1
-
-The fbufs, mbufs and trace parameters are global and apply to all connected
-cameras. Each camera has its own set of buffers.
-
-size and fps only specify defaults when you open() the device; this is to
-accommodate some tools that don't set the size. You can change these
-settings after open() with the Video4Linux ioctl() calls. The default of
-defaults is QCIF size at 10 fps.
-
-The compression parameter is semiglobal; it sets the initial compression
-preference for all camera's, but this parameter can be set per camera with
-the VIDIOCPWCSCQUAL ioctl() call.
-
-All parameters are optional.
-
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
deleted file mode 100644
index 1f506fde97d..00000000000
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ /dev/null
@@ -1,553 +0,0 @@
-/* Driver for Philips webcam
- Functions that send various control messages to the webcam, including
- video modes.
- (C) 1999-2003 Nemosoft Unv.
- (C) 2004-2006 Luc Saillard (luc@saillard.org)
- (C) 2011 Hans de Goede <hdegoede@redhat.com>
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
- The decompression routines have been implemented by reverse-engineering the
- Nemosoft binary pwcx module. Caveat emptor.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-/*
- Changes
- 2001/08/03 Alvarado Added methods for changing white balance and
- red/green gains
- */
-
-/* Control functions for the cam; brightness, contrast, video mode, etc. */
-
-#ifdef __KERNEL__
-#include <asm/uaccess.h>
-#endif
-#include <asm/errno.h>
-
-#include "pwc.h"
-#include "pwc-kiara.h"
-#include "pwc-timon.h"
-#include "pwc-dec1.h"
-#include "pwc-dec23.h"
-
-/* Selectors for status controls used only in this file */
-#define GET_STATUS_B00 0x0B00
-#define SENSOR_TYPE_FORMATTER1 0x0C00
-#define GET_STATUS_3000 0x3000
-#define READ_RAW_Y_MEAN_FORMATTER 0x3100
-#define SET_POWER_SAVE_MODE_FORMATTER 0x3200
-#define MIRROR_IMAGE_FORMATTER 0x3300
-#define LED_FORMATTER 0x3400
-#define LOWLIGHT 0x3500
-#define GET_STATUS_3600 0x3600
-#define SENSOR_TYPE_FORMATTER2 0x3700
-#define GET_STATUS_3800 0x3800
-#define GET_STATUS_4000 0x4000
-#define GET_STATUS_4100 0x4100 /* Get */
-#define CTL_STATUS_4200 0x4200 /* [GS] 1 */
-
-/* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */
-#define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100
-
-static const char *size2name[PSZ_MAX] =
-{
- "subQCIF",
- "QSIF",
- "QCIF",
- "SIF",
- "CIF",
- "VGA",
-};
-
-/********/
-
-/* Entries for the Nala (645/646) camera; the Nala doesn't have compression
- preferences, so you either get compressed or non-compressed streams.
-
- An alternate value of 0 means this mode is not available at all.
- */
-
-#define PWC_FPS_MAX_NALA 8
-
-struct Nala_table_entry {
- char alternate; /* USB alternate setting */
- int compressed; /* Compressed yes/no */
-
- unsigned char mode[3]; /* precomputed mode table */
-};
-
-static unsigned int Nala_fps_vector[PWC_FPS_MAX_NALA] = { 4, 5, 7, 10, 12, 15, 20, 24 };
-
-static struct Nala_table_entry Nala_table[PSZ_MAX][PWC_FPS_MAX_NALA] =
-{
-#include "pwc-nala.h"
-};
-
-/****************************************************************************/
-
-static int recv_control_msg(struct pwc_device *pdev,
- u8 request, u16 value, int recv_count)
-{
- int rc;
-
- rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
- request,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, pdev->vcinterface,
- pdev->ctrl_buf, recv_count, USB_CTRL_GET_TIMEOUT);
- if (rc < 0)
- PWC_ERROR("recv_control_msg error %d req %02x val %04x\n",
- rc, request, value);
- return rc;
-}
-
-static inline int send_video_command(struct pwc_device *pdev,
- int index, const unsigned char *buf, int buflen)
-{
- int rc;
-
- memcpy(pdev->ctrl_buf, buf, buflen);
-
- rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
- SET_EP_STREAM_CTL,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- VIDEO_OUTPUT_CONTROL_FORMATTER, index,
- pdev->ctrl_buf, buflen, USB_CTRL_SET_TIMEOUT);
- if (rc >= 0)
- memcpy(pdev->cmd_buf, buf, buflen);
- else
- PWC_ERROR("send_video_command error %d\n", rc);
-
- return rc;
-}
-
-int send_control_msg(struct pwc_device *pdev,
- u8 request, u16 value, void *buf, int buflen)
-{
- return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
- request,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, pdev->vcinterface,
- buf, buflen, USB_CTRL_SET_TIMEOUT);
-}
-
-static int set_video_mode_Nala(struct pwc_device *pdev, int size, int pixfmt,
- int frames, int *compression, int send_to_cam)
-{
- int fps, ret = 0;
- struct Nala_table_entry *pEntry;
- int frames2frames[31] =
- { /* closest match of framerate */
- 0, 0, 0, 0, 4, /* 0-4 */
- 5, 5, 7, 7, 10, /* 5-9 */
- 10, 10, 12, 12, 15, /* 10-14 */
- 15, 15, 15, 20, 20, /* 15-19 */
- 20, 20, 20, 24, 24, /* 20-24 */
- 24, 24, 24, 24, 24, /* 25-29 */
- 24 /* 30 */
- };
- int frames2table[31] =
- { 0, 0, 0, 0, 0, /* 0-4 */
- 1, 1, 1, 2, 2, /* 5-9 */
- 3, 3, 4, 4, 4, /* 10-14 */
- 5, 5, 5, 5, 5, /* 15-19 */
- 6, 6, 6, 6, 7, /* 20-24 */
- 7, 7, 7, 7, 7, /* 25-29 */
- 7 /* 30 */
- };
-
- if (size < 0 || size > PSZ_CIF)
- return -EINVAL;
- if (frames < 4)
- frames = 4;
- else if (frames > 25)
- frames = 25;
- frames = frames2frames[frames];
- fps = frames2table[frames];
- pEntry = &Nala_table[size][fps];
- if (pEntry->alternate == 0)
- return -EINVAL;
-
- if (send_to_cam)
- ret = send_video_command(pdev, pdev->vendpoint,
- pEntry->mode, 3);
- if (ret < 0)
- return ret;
-
- if (pEntry->compressed && pixfmt == V4L2_PIX_FMT_YUV420)
- pwc_dec1_init(pdev, pEntry->mode);
-
- /* Set various parameters */
- pdev->pixfmt = pixfmt;
- pdev->vframes = frames;
- pdev->valternate = pEntry->alternate;
- pdev->width = pwc_image_sizes[size][0];
- pdev->height = pwc_image_sizes[size][1];
- pdev->frame_size = (pdev->width * pdev->height * 3) / 2;
- if (pEntry->compressed) {
- if (pdev->release < 5) { /* 4 fold compression */
- pdev->vbandlength = 528;
- pdev->frame_size /= 4;
- }
- else {
- pdev->vbandlength = 704;
- pdev->frame_size /= 3;
- }
- }
- else
- pdev->vbandlength = 0;
-
- /* Let pwc-if.c:isoc_init know we don't support higher compression */
- *compression = 3;
-
- return 0;
-}
-
-
-static int set_video_mode_Timon(struct pwc_device *pdev, int size, int pixfmt,
- int frames, int *compression, int send_to_cam)
-{
- const struct Timon_table_entry *pChoose;
- int fps, ret = 0;
-
- if (size >= PSZ_MAX || *compression < 0 || *compression > 3)
- return -EINVAL;
- if (frames < 5)
- frames = 5;
- else if (size == PSZ_VGA && frames > 15)
- frames = 15;
- else if (frames > 30)
- frames = 30;
- fps = (frames / 5) - 1;
-
- /* Find a supported framerate with progressively higher compression */
- pChoose = NULL;
- while (*compression <= 3) {
- pChoose = &Timon_table[size][fps][*compression];
- if (pChoose->alternate != 0)
- break;
- (*compression)++;
- }
- if (pChoose == NULL || pChoose->alternate == 0)
- return -ENOENT; /* Not supported. */
-
- if (send_to_cam)
- ret = send_video_command(pdev, pdev->vendpoint,
- pChoose->mode, 13);
- if (ret < 0)
- return ret;
-
- if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420)
- pwc_dec23_init(pdev, pChoose->mode);
-
- /* Set various parameters */
- pdev->pixfmt = pixfmt;
- pdev->vframes = (fps + 1) * 5;
- pdev->valternate = pChoose->alternate;
- pdev->width = pwc_image_sizes[size][0];
- pdev->height = pwc_image_sizes[size][1];
- pdev->vbandlength = pChoose->bandlength;
- if (pChoose->bandlength > 0)
- pdev->frame_size = (pChoose->bandlength * pdev->height) / 4;
- else
- pdev->frame_size = (pdev->width * pdev->height * 12) / 8;
- return 0;
-}
-
-
-static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int pixfmt,
- int frames, int *compression, int send_to_cam)
-{
- const struct Kiara_table_entry *pChoose = NULL;
- int fps, ret = 0;
-
- if (size >= PSZ_MAX || *compression < 0 || *compression > 3)
- return -EINVAL;
- if (frames < 5)
- frames = 5;
- else if (size == PSZ_VGA && frames > 15)
- frames = 15;
- else if (frames > 30)
- frames = 30;
- fps = (frames / 5) - 1;
-
- /* Find a supported framerate with progressively higher compression */
- while (*compression <= 3) {
- pChoose = &Kiara_table[size][fps][*compression];
- if (pChoose->alternate != 0)
- break;
- (*compression)++;
- }
- if (pChoose == NULL || pChoose->alternate == 0)
- return -ENOENT; /* Not supported. */
-
- /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */
- if (send_to_cam)
- ret = send_video_command(pdev, 4, pChoose->mode, 12);
- if (ret < 0)
- return ret;
-
- if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420)
- pwc_dec23_init(pdev, pChoose->mode);
-
- /* All set and go */
- pdev->pixfmt = pixfmt;
- pdev->vframes = (fps + 1) * 5;
- pdev->valternate = pChoose->alternate;
- pdev->width = pwc_image_sizes[size][0];
- pdev->height = pwc_image_sizes[size][1];
- pdev->vbandlength = pChoose->bandlength;
- if (pdev->vbandlength > 0)
- pdev->frame_size = (pdev->vbandlength * pdev->height) / 4;
- else
- pdev->frame_size = (pdev->width * pdev->height * 12) / 8;
- PWC_TRACE("frame_size=%d, vframes=%d, vsize=%d, vbandlength=%d\n",
- pdev->frame_size, pdev->vframes, size, pdev->vbandlength);
- return 0;
-}
-
-int pwc_set_video_mode(struct pwc_device *pdev, int width, int height,
- int pixfmt, int frames, int *compression, int send_to_cam)
-{
- int ret, size;
-
- PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n",
- width, height, frames, pixfmt);
- size = pwc_get_size(pdev, width, height);
- PWC_TRACE("decode_size = %d.\n", size);
-
- if (DEVICE_USE_CODEC1(pdev->type)) {
- ret = set_video_mode_Nala(pdev, size, pixfmt, frames,
- compression, send_to_cam);
- } else if (DEVICE_USE_CODEC3(pdev->type)) {
- ret = set_video_mode_Kiara(pdev, size, pixfmt, frames,
- compression, send_to_cam);
- } else {
- ret = set_video_mode_Timon(pdev, size, pixfmt, frames,
- compression, send_to_cam);
- }
- if (ret < 0) {
- PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
- return ret;
- }
- pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size;
- PWC_DEBUG_SIZE("Set resolution to %dx%d\n", pdev->width, pdev->height);
- return 0;
-}
-
-static unsigned int pwc_get_fps_Nala(struct pwc_device *pdev, unsigned int index, unsigned int size)
-{
- unsigned int i;
-
- for (i = 0; i < PWC_FPS_MAX_NALA; i++) {
- if (Nala_table[size][i].alternate) {
- if (index--==0) return Nala_fps_vector[i];
- }
- }
- return 0;
-}
-
-static unsigned int pwc_get_fps_Kiara(struct pwc_device *pdev, unsigned int index, unsigned int size)
-{
- unsigned int i;
-
- for (i = 0; i < PWC_FPS_MAX_KIARA; i++) {
- if (Kiara_table[size][i][3].alternate) {
- if (index--==0) return Kiara_fps_vector[i];
- }
- }
- return 0;
-}
-
-static unsigned int pwc_get_fps_Timon(struct pwc_device *pdev, unsigned int index, unsigned int size)
-{
- unsigned int i;
-
- for (i=0; i < PWC_FPS_MAX_TIMON; i++) {
- if (Timon_table[size][i][3].alternate) {
- if (index--==0) return Timon_fps_vector[i];
- }
- }
- return 0;
-}
-
-unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size)
-{
- unsigned int ret;
-
- if (DEVICE_USE_CODEC1(pdev->type)) {
- ret = pwc_get_fps_Nala(pdev, index, size);
-
- } else if (DEVICE_USE_CODEC3(pdev->type)) {
- ret = pwc_get_fps_Kiara(pdev, index, size);
-
- } else {
- ret = pwc_get_fps_Timon(pdev, index, size);
- }
-
- return ret;
-}
-
-int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
-{
- int ret;
-
- ret = recv_control_msg(pdev, request, value, 1);
- if (ret < 0)
- return ret;
-
- *data = pdev->ctrl_buf[0];
- return 0;
-}
-
-int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data)
-{
- int ret;
-
- pdev->ctrl_buf[0] = data;
- ret = send_control_msg(pdev, request, value, pdev->ctrl_buf, 1);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
-{
- int ret;
-
- ret = recv_control_msg(pdev, request, value, 1);
- if (ret < 0)
- return ret;
-
- *data = ((s8 *)pdev->ctrl_buf)[0];
- return 0;
-}
-
-int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
-{
- int ret;
-
- ret = recv_control_msg(pdev, request, value, 2);
- if (ret < 0)
- return ret;
-
- *data = (pdev->ctrl_buf[1] << 8) | pdev->ctrl_buf[0];
- return 0;
-}
-
-int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data)
-{
- int ret;
-
- pdev->ctrl_buf[0] = data & 0xff;
- pdev->ctrl_buf[1] = data >> 8;
- ret = send_control_msg(pdev, request, value, pdev->ctrl_buf, 2);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int pwc_button_ctrl(struct pwc_device *pdev, u16 value)
-{
- int ret;
-
- ret = send_control_msg(pdev, SET_STATUS_CTL, value, NULL, 0);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-/* POWER */
-void pwc_camera_power(struct pwc_device *pdev, int power)
-{
- int r;
-
- if (!pdev->power_save)
- return;
-
- if (pdev->type < 675 || (pdev->type < 730 && pdev->release < 6))
- return; /* Not supported by Nala or Timon < release 6 */
-
- if (power)
- pdev->ctrl_buf[0] = 0x00; /* active */
- else
- pdev->ctrl_buf[0] = 0xFF; /* power save */
- r = send_control_msg(pdev, SET_STATUS_CTL,
- SET_POWER_SAVE_MODE_FORMATTER, pdev->ctrl_buf, 1);
- if (r < 0)
- PWC_ERROR("Failed to power %s camera (%d)\n",
- power ? "on" : "off", r);
-}
-
-int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
-{
- int r;
-
- if (pdev->type < 730)
- return 0;
- on_value /= 100;
- off_value /= 100;
- if (on_value < 0)
- on_value = 0;
- if (on_value > 0xff)
- on_value = 0xff;
- if (off_value < 0)
- off_value = 0;
- if (off_value > 0xff)
- off_value = 0xff;
-
- pdev->ctrl_buf[0] = on_value;
- pdev->ctrl_buf[1] = off_value;
-
- r = send_control_msg(pdev,
- SET_STATUS_CTL, LED_FORMATTER, pdev->ctrl_buf, 2);
- if (r < 0)
- PWC_ERROR("Failed to set LED on/off time (%d)\n", r);
-
- return r;
-}
-
-#ifdef CONFIG_USB_PWC_DEBUG
-int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
-{
- int ret = -1, request;
-
- if (pdev->type < 675)
- request = SENSOR_TYPE_FORMATTER1;
- else if (pdev->type < 730)
- return -1; /* The Vesta series doesn't have this call */
- else
- request = SENSOR_TYPE_FORMATTER2;
-
- ret = recv_control_msg(pdev, GET_STATUS_CTL, request, 1);
- if (ret < 0)
- return ret;
- if (pdev->type < 675)
- *sensor = pdev->ctrl_buf[0] | 0x100;
- else
- *sensor = pdev->ctrl_buf[0];
- return 0;
-}
-#endif
diff --git a/drivers/media/video/pwc/pwc-dec1.c b/drivers/media/video/pwc/pwc-dec1.c
deleted file mode 100644
index e899036aadf..00000000000
--- a/drivers/media/video/pwc/pwc-dec1.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Linux driver for Philips webcam
- Decompression for chipset version 1
- (C) 2004-2006 Luc Saillard (luc@saillard.org)
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
- The decompression routines have been implemented by reverse-engineering the
- Nemosoft binary pwcx module. Caveat emptor.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-#include "pwc.h"
-
-void pwc_dec1_init(struct pwc_device *pdev, const unsigned char *cmd)
-{
- struct pwc_dec1_private *pdec = &pdev->dec1;
-
- pdec->version = pdev->release;
-}
diff --git a/drivers/media/video/pwc/pwc-dec1.h b/drivers/media/video/pwc/pwc-dec1.h
deleted file mode 100644
index c565ef8f52f..00000000000
--- a/drivers/media/video/pwc/pwc-dec1.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Linux driver for Philips webcam
- (C) 2004-2006 Luc Saillard (luc@saillard.org)
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
- The decompression routines have been implemented by reverse-engineering the
- Nemosoft binary pwcx module. Caveat emptor.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#ifndef PWC_DEC1_H
-#define PWC_DEC1_H
-
-#include <linux/mutex.h>
-
-struct pwc_device;
-
-struct pwc_dec1_private
-{
- int version;
-};
-
-void pwc_dec1_init(struct pwc_device *pdev, const unsigned char *cmd);
-
-#endif
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c
deleted file mode 100644
index 3792fedff95..00000000000
--- a/drivers/media/video/pwc/pwc-dec23.c
+++ /dev/null
@@ -1,691 +0,0 @@
-/* Linux driver for Philips webcam
- Decompression for chipset version 2 et 3
- (C) 2004-2006 Luc Saillard (luc@saillard.org)
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
- The decompression routines have been implemented by reverse-engineering the
- Nemosoft binary pwcx module. Caveat emptor.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*/
-
-#include "pwc-timon.h"
-#include "pwc-kiara.h"
-#include "pwc-dec23.h"
-
-#include <linux/string.h>
-#include <linux/slab.h>
-
-/*
- * USE_LOOKUP_TABLE_TO_CLAMP
- * 0: use a C version of this tests: { a<0?0:(a>255?255:a) }
- * 1: use a faster lookup table for cpu with a big cache (intel)
- */
-#define USE_LOOKUP_TABLE_TO_CLAMP 1
-/*
- * UNROLL_LOOP_FOR_COPYING_BLOCK
- * 0: use a loop for a smaller code (but little slower)
- * 1: when unrolling the loop, gcc produces some faster code (perhaps only
- * valid for intel processor class). Activating this option, automaticaly
- * activate USE_LOOKUP_TABLE_TO_CLAMP
- */
-#define UNROLL_LOOP_FOR_COPY 1
-#if UNROLL_LOOP_FOR_COPY
-# undef USE_LOOKUP_TABLE_TO_CLAMP
-# define USE_LOOKUP_TABLE_TO_CLAMP 1
-#endif
-
-static void build_subblock_pattern(struct pwc_dec23_private *pdec)
-{
- static const unsigned int initial_values[12] = {
- -0x526500, -0x221200, 0x221200, 0x526500,
- -0x3de200, 0x3de200,
- -0x6db480, -0x2d5d00, 0x2d5d00, 0x6db480,
- -0x12c200, 0x12c200
-
- };
- static const unsigned int values_derivated[12] = {
- 0xa4ca, 0x4424, -0x4424, -0xa4ca,
- 0x7bc4, -0x7bc4,
- 0xdb69, 0x5aba, -0x5aba, -0xdb69,
- 0x2584, -0x2584
- };
- unsigned int temp_values[12];
- int i, j;
-
- memcpy(temp_values, initial_values, sizeof(initial_values));
- for (i = 0; i < 256; i++) {
- for (j = 0; j < 12; j++) {
- pdec->table_subblock[i][j] = temp_values[j];
- temp_values[j] += values_derivated[j];
- }
- }
-}
-
-static void build_bit_powermask_table(struct pwc_dec23_private *pdec)
-{
- unsigned char *p;
- unsigned int bit, byte, mask, val;
- unsigned int bitpower = 1;
-
- for (bit = 0; bit < 8; bit++) {
- mask = bitpower - 1;
- p = pdec->table_bitpowermask[bit];
- for (byte = 0; byte < 256; byte++) {
- val = (byte & mask);
- if (byte & bitpower)
- val = -val;
- *p++ = val;
- }
- bitpower<<=1;
- }
-}
-
-
-static void build_table_color(const unsigned int romtable[16][8],
- unsigned char p0004[16][1024],
- unsigned char p8004[16][256])
-{
- int compression_mode, j, k, bit, pw;
- unsigned char *p0, *p8;
- const unsigned int *r;
-
- /* We have 16 compressions tables */
- for (compression_mode = 0; compression_mode < 16; compression_mode++) {
- p0 = p0004[compression_mode];
- p8 = p8004[compression_mode];
- r = romtable[compression_mode];
-
- for (j = 0; j < 8; j++, r++, p0 += 128) {
-
- for (k = 0; k < 16; k++) {
- if (k == 0)
- bit = 1;
- else if (k >= 1 && k < 3)
- bit = (r[0] >> 15) & 7;
- else if (k >= 3 && k < 6)
- bit = (r[0] >> 12) & 7;
- else if (k >= 6 && k < 10)
- bit = (r[0] >> 9) & 7;
- else if (k >= 10 && k < 13)
- bit = (r[0] >> 6) & 7;
- else if (k >= 13 && k < 15)
- bit = (r[0] >> 3) & 7;
- else
- bit = (r[0]) & 7;
- if (k == 0)
- *p8++ = 8;
- else
- *p8++ = j - bit;
- *p8++ = bit;
-
- pw = 1 << bit;
- p0[k + 0x00] = (1 * pw) + 0x80;
- p0[k + 0x10] = (2 * pw) + 0x80;
- p0[k + 0x20] = (3 * pw) + 0x80;
- p0[k + 0x30] = (4 * pw) + 0x80;
- p0[k + 0x40] = (-1 * pw) + 0x80;
- p0[k + 0x50] = (-2 * pw) + 0x80;
- p0[k + 0x60] = (-3 * pw) + 0x80;
- p0[k + 0x70] = (-4 * pw) + 0x80;
- } /* end of for (k=0; k<16; k++, p8++) */
- } /* end of for (j=0; j<8; j++ , table++) */
- } /* end of foreach compression_mode */
-}
-
-/*
- *
- */
-static void fill_table_dc00_d800(struct pwc_dec23_private *pdec)
-{
-#define SCALEBITS 15
-#define ONE_HALF (1UL << (SCALEBITS - 1))
- int i;
- unsigned int offset1 = ONE_HALF;
- unsigned int offset2 = 0x0000;
-
- for (i=0; i<256; i++) {
- pdec->table_dc00[i] = offset1 & ~(ONE_HALF);
- pdec->table_d800[i] = offset2;
-
- offset1 += 0x7bc4;
- offset2 += 0x7bc4;
- }
-}
-
-/*
- * To decode the stream:
- * if look_bits(2) == 0: # op == 2 in the lookup table
- * skip_bits(2)
- * end of the stream
- * elif look_bits(3) == 7: # op == 1 in the lookup table
- * skip_bits(3)
- * yyyy = get_bits(4)
- * xxxx = get_bits(8)
- * else: # op == 0 in the lookup table
- * skip_bits(x)
- *
- * For speedup processing, we build a lookup table and we takes the first 6 bits.
- *
- * struct {
- * unsigned char op; // operation to execute
- * unsigned char bits; // bits use to perform operation
- * unsigned char offset1; // offset to add to access in the table_0004 % 16
- * unsigned char offset2; // offset to add to access in the table_0004
- * }
- *
- * How to build this table ?
- * op == 2 when (i%4)==0
- * op == 1 when (i%8)==7
- * op == 0 otherwise
- *
- */
-static const unsigned char hash_table_ops[64*4] = {
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x00,
- 0x00, 0x04, 0x01, 0x10,
- 0x00, 0x06, 0x01, 0x30,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x40,
- 0x00, 0x05, 0x01, 0x20,
- 0x01, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x00,
- 0x00, 0x04, 0x01, 0x50,
- 0x00, 0x05, 0x02, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x40,
- 0x00, 0x05, 0x03, 0x00,
- 0x01, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x00,
- 0x00, 0x04, 0x01, 0x10,
- 0x00, 0x06, 0x02, 0x10,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x40,
- 0x00, 0x05, 0x01, 0x60,
- 0x01, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x00,
- 0x00, 0x04, 0x01, 0x50,
- 0x00, 0x05, 0x02, 0x40,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x40,
- 0x00, 0x05, 0x03, 0x40,
- 0x01, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x00,
- 0x00, 0x04, 0x01, 0x10,
- 0x00, 0x06, 0x01, 0x70,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x40,
- 0x00, 0x05, 0x01, 0x20,
- 0x01, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x00,
- 0x00, 0x04, 0x01, 0x50,
- 0x00, 0x05, 0x02, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x40,
- 0x00, 0x05, 0x03, 0x00,
- 0x01, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x00,
- 0x00, 0x04, 0x01, 0x10,
- 0x00, 0x06, 0x02, 0x50,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x40,
- 0x00, 0x05, 0x01, 0x60,
- 0x01, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x00,
- 0x00, 0x04, 0x01, 0x50,
- 0x00, 0x05, 0x02, 0x40,
- 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x01, 0x40,
- 0x00, 0x05, 0x03, 0x40,
- 0x01, 0x00, 0x00, 0x00
-};
-
-/*
- *
- */
-static const unsigned int MulIdx[16][16] = {
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
- {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,},
- {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,},
- {4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,},
- {6, 7, 8, 9, 7, 10, 11, 8, 8, 11, 10, 7, 9, 8, 7, 6,},
- {4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,},
- {1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,},
- {0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,},
- {0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,},
- {1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,},
- {7, 10, 11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8, 11, 10, 7,},
- {4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,},
- {7, 9, 6, 8, 10, 8, 7, 11, 11, 7, 8, 10, 8, 6, 9, 7,},
- {1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,},
- {1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,},
- {10, 8, 7, 11, 8, 6, 9, 7, 7, 9, 6, 8, 11, 7, 8, 10}
-};
-
-#if USE_LOOKUP_TABLE_TO_CLAMP
-#define MAX_OUTER_CROP_VALUE (512)
-static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE];
-#define CLAMP(x) (pwc_crop_table[MAX_OUTER_CROP_VALUE+(x)])
-#else
-#define CLAMP(x) ((x)>255?255:((x)<0?0:x))
-#endif
-
-
-/* If the type or the command change, we rebuild the lookup table */
-void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd)
-{
- int flags, version, shift, i;
- struct pwc_dec23_private *pdec = &pdev->dec23;
-
- mutex_init(&pdec->lock);
-
- if (pdec->last_cmd_valid && pdec->last_cmd == cmd[2])
- return;
-
- if (DEVICE_USE_CODEC3(pdev->type)) {
- flags = cmd[2] & 0x18;
- if (flags == 8)
- pdec->nbits = 7; /* More bits, mean more bits to encode the stream, but better quality */
- else if (flags == 0x10)
- pdec->nbits = 8;
- else
- pdec->nbits = 6;
-
- version = cmd[2] >> 5;
- build_table_color(KiaraRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
- build_table_color(KiaraRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
-
- } else {
-
- flags = cmd[2] & 6;
- if (flags == 2)
- pdec->nbits = 7;
- else if (flags == 4)
- pdec->nbits = 8;
- else
- pdec->nbits = 6;
-
- version = cmd[2] >> 3;
- build_table_color(TimonRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
- build_table_color(TimonRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
- }
-
- /* Informations can be coded on a variable number of bits but never less than 8 */
- shift = 8 - pdec->nbits;
- pdec->scalebits = SCALEBITS - shift;
- pdec->nbitsmask = 0xFF >> shift;
-
- fill_table_dc00_d800(pdec);
- build_subblock_pattern(pdec);
- build_bit_powermask_table(pdec);
-
-#if USE_LOOKUP_TABLE_TO_CLAMP
- /* Build the static table to clamp value [0-255] */
- for (i=0;i<MAX_OUTER_CROP_VALUE;i++)
- pwc_crop_table[i] = 0;
- for (i=0; i<256; i++)
- pwc_crop_table[MAX_OUTER_CROP_VALUE+i] = i;
- for (i=0; i<MAX_OUTER_CROP_VALUE; i++)
- pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255;
-#endif
-
- pdec->last_cmd = cmd[2];
- pdec->last_cmd_valid = 1;
-}
-
-/*
- * Copy the 4x4 image block to Y plane buffer
- */
-static void copy_image_block_Y(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
-{
-#if UNROLL_LOOP_FOR_COPY
- const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
- const int *c = src;
- unsigned char *d = dst;
-
- *d++ = cm[c[0] >> scalebits];
- *d++ = cm[c[1] >> scalebits];
- *d++ = cm[c[2] >> scalebits];
- *d++ = cm[c[3] >> scalebits];
-
- d = dst + bytes_per_line;
- *d++ = cm[c[4] >> scalebits];
- *d++ = cm[c[5] >> scalebits];
- *d++ = cm[c[6] >> scalebits];
- *d++ = cm[c[7] >> scalebits];
-
- d = dst + bytes_per_line*2;
- *d++ = cm[c[8] >> scalebits];
- *d++ = cm[c[9] >> scalebits];
- *d++ = cm[c[10] >> scalebits];
- *d++ = cm[c[11] >> scalebits];
-
- d = dst + bytes_per_line*3;
- *d++ = cm[c[12] >> scalebits];
- *d++ = cm[c[13] >> scalebits];
- *d++ = cm[c[14] >> scalebits];
- *d++ = cm[c[15] >> scalebits];
-#else
- int i;
- const int *c = src;
- unsigned char *d = dst;
- for (i = 0; i < 4; i++, c++)
- *d++ = CLAMP((*c) >> scalebits);
-
- d = dst + bytes_per_line;
- for (i = 0; i < 4; i++, c++)
- *d++ = CLAMP((*c) >> scalebits);
-
- d = dst + bytes_per_line*2;
- for (i = 0; i < 4; i++, c++)
- *d++ = CLAMP((*c) >> scalebits);
-
- d = dst + bytes_per_line*3;
- for (i = 0; i < 4; i++, c++)
- *d++ = CLAMP((*c) >> scalebits);
-#endif
-}
-
-/*
- * Copy the 4x4 image block to a CrCb plane buffer
- *
- */
-static void copy_image_block_CrCb(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
-{
-#if UNROLL_LOOP_FOR_COPY
- /* Unroll all loops */
- const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
- const int *c = src;
- unsigned char *d = dst;
-
- *d++ = cm[c[0] >> scalebits];
- *d++ = cm[c[4] >> scalebits];
- *d++ = cm[c[1] >> scalebits];
- *d++ = cm[c[5] >> scalebits];
- *d++ = cm[c[2] >> scalebits];
- *d++ = cm[c[6] >> scalebits];
- *d++ = cm[c[3] >> scalebits];
- *d++ = cm[c[7] >> scalebits];
-
- d = dst + bytes_per_line;
- *d++ = cm[c[12] >> scalebits];
- *d++ = cm[c[8] >> scalebits];
- *d++ = cm[c[13] >> scalebits];
- *d++ = cm[c[9] >> scalebits];
- *d++ = cm[c[14] >> scalebits];
- *d++ = cm[c[10] >> scalebits];
- *d++ = cm[c[15] >> scalebits];
- *d++ = cm[c[11] >> scalebits];
-#else
- int i;
- const int *c1 = src;
- const int *c2 = src + 4;
- unsigned char *d = dst;
-
- for (i = 0; i < 4; i++, c1++, c2++) {
- *d++ = CLAMP((*c1) >> scalebits);
- *d++ = CLAMP((*c2) >> scalebits);
- }
- c1 = src + 12;
- d = dst + bytes_per_line;
- for (i = 0; i < 4; i++, c1++, c2++) {
- *d++ = CLAMP((*c1) >> scalebits);
- *d++ = CLAMP((*c2) >> scalebits);
- }
-#endif
-}
-
-/*
- * To manage the stream, we keep bits in a 32 bits register.
- * fill_nbits(n): fill the reservoir with at least n bits
- * skip_bits(n): discard n bits from the reservoir
- * get_bits(n): fill the reservoir, returns the first n bits and discard the
- * bits from the reservoir.
- * __get_nbits(n): faster version of get_bits(n), but asumes that the reservoir
- * contains at least n bits. bits returned is discarded.
- */
-#define fill_nbits(pdec, nbits_wanted) do { \
- while (pdec->nbits_in_reservoir<(nbits_wanted)) \
- { \
- pdec->reservoir |= (*(pdec->stream)++) << (pdec->nbits_in_reservoir); \
- pdec->nbits_in_reservoir += 8; \
- } \
-} while(0);
-
-#define skip_nbits(pdec, nbits_to_skip) do { \
- pdec->reservoir >>= (nbits_to_skip); \
- pdec->nbits_in_reservoir -= (nbits_to_skip); \
-} while(0);
-
-#define get_nbits(pdec, nbits_wanted, result) do { \
- fill_nbits(pdec, nbits_wanted); \
- result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
- skip_nbits(pdec, nbits_wanted); \
-} while(0);
-
-#define __get_nbits(pdec, nbits_wanted, result) do { \
- result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
- skip_nbits(pdec, nbits_wanted); \
-} while(0);
-
-#define look_nbits(pdec, nbits_wanted) \
- ((pdec->reservoir) & ((1U<<(nbits_wanted))-1))
-
-/*
- * Decode a 4x4 pixel block
- */
-static void decode_block(struct pwc_dec23_private *pdec,
- const unsigned char *ptable0004,
- const unsigned char *ptable8004)
-{
- unsigned int primary_color;
- unsigned int channel_v, offset1, op;
- int i;
-
- fill_nbits(pdec, 16);
- __get_nbits(pdec, pdec->nbits, primary_color);
-
- if (look_nbits(pdec,2) == 0) {
- skip_nbits(pdec, 2);
- /* Very simple, the color is the same for all pixels of the square */
- for (i = 0; i < 16; i++)
- pdec->temp_colors[i] = pdec->table_dc00[primary_color];
-
- return;
- }
-
- /* This block is encoded with small pattern */
- for (i = 0; i < 16; i++)
- pdec->temp_colors[i] = pdec->table_d800[primary_color];
-
- __get_nbits(pdec, 3, channel_v);
- channel_v = ((channel_v & 1) << 2) | (channel_v & 2) | ((channel_v & 4) >> 2);
-
- ptable0004 += (channel_v * 128);
- ptable8004 += (channel_v * 32);
-
- offset1 = 0;
- do
- {
- unsigned int htable_idx, rows = 0;
- const unsigned int *block;
-
- /* [ zzzz y x x ]
- * xx == 00 :=> end of the block def, remove the two bits from the stream
- * yxx == 111
- * yxx == any other value
- *
- */
- fill_nbits(pdec, 16);
- htable_idx = look_nbits(pdec, 6);
- op = hash_table_ops[htable_idx * 4];
-
- if (op == 2) {
- skip_nbits(pdec, 2);
-
- } else if (op == 1) {
- /* 15bits [ xxxx xxxx yyyy 111 ]
- * yyy => offset in the table8004
- * xxx => offset in the tabled004 (tree)
- */
- unsigned int mask, shift;
- unsigned int nbits, col1;
- unsigned int yyyy;
-
- skip_nbits(pdec, 3);
- /* offset1 += yyyy */
- __get_nbits(pdec, 4, yyyy);
- offset1 += 1 + yyyy;
- offset1 &= 0x0F;
- nbits = ptable8004[offset1 * 2];
-
- /* col1 = xxxx xxxx */
- __get_nbits(pdec, nbits+1, col1);
-
- /* Bit mask table */
- mask = pdec->table_bitpowermask[nbits][col1];
- shift = ptable8004[offset1 * 2 + 1];
- rows = ((mask << shift) + 0x80) & 0xFF;
-
- block = pdec->table_subblock[rows];
- for (i = 0; i < 16; i++)
- pdec->temp_colors[i] += block[MulIdx[offset1][i]];
-
- } else {
- /* op == 0
- * offset1 is coded on 3 bits
- */
- unsigned int shift;
-
- offset1 += hash_table_ops [htable_idx * 4 + 2];
- offset1 &= 0x0F;
-
- rows = ptable0004[offset1 + hash_table_ops [htable_idx * 4 + 3]];
- block = pdec->table_subblock[rows];
- for (i = 0; i < 16; i++)
- pdec->temp_colors[i] += block[MulIdx[offset1][i]];
-
- shift = hash_table_ops[htable_idx * 4 + 1];
- skip_nbits(pdec, shift);
- }
-
- } while (op != 2);
-
-}
-
-static void DecompressBand23(struct pwc_dec23_private *pdec,
- const unsigned char *rawyuv,
- unsigned char *planar_y,
- unsigned char *planar_u,
- unsigned char *planar_v,
- unsigned int compressed_image_width,
- unsigned int real_image_width)
-{
- int compression_index, nblocks;
- const unsigned char *ptable0004;
- const unsigned char *ptable8004;
-
- pdec->reservoir = 0;
- pdec->nbits_in_reservoir = 0;
- pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */
-
- get_nbits(pdec, 4, compression_index);
-
- /* pass 1: uncompress Y component */
- nblocks = compressed_image_width / 4;
-
- ptable0004 = pdec->table_0004_pass1[compression_index];
- ptable8004 = pdec->table_8004_pass1[compression_index];
-
- /* Each block decode a square of 4x4 */
- while (nblocks) {
- decode_block(pdec, ptable0004, ptable8004);
- copy_image_block_Y(pdec->temp_colors, planar_y, real_image_width, pdec->scalebits);
- planar_y += 4;
- nblocks--;
- }
-
- /* pass 2: uncompress UV component */
- nblocks = compressed_image_width / 8;
-
- ptable0004 = pdec->table_0004_pass2[compression_index];
- ptable8004 = pdec->table_8004_pass2[compression_index];
-
- /* Each block decode a square of 4x4 */
- while (nblocks) {
- decode_block(pdec, ptable0004, ptable8004);
- copy_image_block_CrCb(pdec->temp_colors, planar_u, real_image_width/2, pdec->scalebits);
-
- decode_block(pdec, ptable0004, ptable8004);
- copy_image_block_CrCb(pdec->temp_colors, planar_v, real_image_width/2, pdec->scalebits);
-
- planar_v += 8;
- planar_u += 8;
- nblocks -= 2;
- }
-
-}
-
-/**
- *
- * Uncompress a pwc23 buffer.
- *
- * src: raw data
- * dst: image output
- */
-void pwc_dec23_decompress(struct pwc_device *pdev,
- const void *src,
- void *dst)
-{
- int bandlines_left, bytes_per_block;
- struct pwc_dec23_private *pdec = &pdev->dec23;
-
- /* YUV420P image format */
- unsigned char *pout_planar_y;
- unsigned char *pout_planar_u;
- unsigned char *pout_planar_v;
- unsigned int plane_size;
-
- mutex_lock(&pdec->lock);
-
- bandlines_left = pdev->height / 4;
- bytes_per_block = pdev->width * 4;
- plane_size = pdev->height * pdev->width;
-
- pout_planar_y = dst;
- pout_planar_u = dst + plane_size;
- pout_planar_v = dst + plane_size + plane_size / 4;
-
- while (bandlines_left--) {
- DecompressBand23(pdec, src,
- pout_planar_y, pout_planar_u, pout_planar_v,
- pdev->width, pdev->width);
- src += pdev->vbandlength;
- pout_planar_y += bytes_per_block;
- pout_planar_u += pdev->width;
- pout_planar_v += pdev->width;
- }
- mutex_unlock(&pdec->lock);
-}
diff --git a/drivers/media/video/pwc/pwc-dec23.h b/drivers/media/video/pwc/pwc-dec23.h
deleted file mode 100644
index c655b1c1e6a..00000000000
--- a/drivers/media/video/pwc/pwc-dec23.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Linux driver for Philips webcam
- (C) 2004-2006 Luc Saillard (luc@saillard.org)
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
- The decompression routines have been implemented by reverse-engineering the
- Nemosoft binary pwcx module. Caveat emptor.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#ifndef PWC_DEC23_H
-#define PWC_DEC23_H
-
-struct pwc_device;
-
-struct pwc_dec23_private
-{
- struct mutex lock;
-
- unsigned char last_cmd, last_cmd_valid;
-
- unsigned int scalebits;
- unsigned int nbitsmask, nbits; /* Number of bits of a color in the compressed stream */
-
- unsigned int reservoir;
- unsigned int nbits_in_reservoir;
-
- const unsigned char *stream;
- int temp_colors[16];
-
- unsigned char table_0004_pass1[16][1024];
- unsigned char table_0004_pass2[16][1024];
- unsigned char table_8004_pass1[16][256];
- unsigned char table_8004_pass2[16][256];
- unsigned int table_subblock[256][12];
-
- unsigned char table_bitpowermask[8][256];
- unsigned int table_d800[256];
- unsigned int table_dc00[256];
-
-};
-
-void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd);
-void pwc_dec23_decompress(struct pwc_device *pdev,
- const void *src,
- void *dst);
-#endif
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
deleted file mode 100644
index de7c7ba99ef..00000000000
--- a/drivers/media/video/pwc/pwc-if.c
+++ /dev/null
@@ -1,1165 +0,0 @@
-/* Linux driver for Philips webcam
- USB and Video4Linux interface part.
- (C) 1999-2004 Nemosoft Unv.
- (C) 2004-2006 Luc Saillard (luc@saillard.org)
- (C) 2011 Hans de Goede <hdegoede@redhat.com>
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
- The decompression routines have been implemented by reverse-engineering the
- Nemosoft binary pwcx module. Caveat emptor.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*/
-
-/*
- This code forms the interface between the USB layers and the Philips
- specific stuff. Some adanved stuff of the driver falls under an
- NDA, signed between me and Philips B.V., Eindhoven, the Netherlands, and
- is thus not distributed in source form. The binary pwcx.o module
- contains the code that falls under the NDA.
-
- In case you're wondering: 'pwc' stands for "Philips WebCam", but
- I really didn't want to type 'philips_web_cam' every time (I'm lazy as
- any Linux kernel hacker, but I don't like uncomprehensible abbreviations
- without explanation).
-
- Oh yes, convention: to disctinguish between all the various pointers to
- device-structures, I use these names for the pointer variables:
- udev: struct usb_device *
- vdev: struct video_device (member of pwc_dev)
- pdev: struct pwc_devive *
-*/
-
-/* Contributors:
- - Alvarado: adding whitebalance code
- - Alistar Moire: QuickCam 3000 Pro device/product ID
- - Tony Hoyle: Creative Labs Webcam 5 device/product ID
- - Mark Burazin: solving hang in VIDIOCSYNC when camera gets unplugged
- - Jk Fang: Sotec Afina Eye ID
- - Xavier Roche: QuickCam Pro 4000 ID
- - Jens Knudsen: QuickCam Zoom ID
- - J. Debert: QuickCam for Notebooks ID
- - Pham Thanh Nam: webcam snapshot button as an event input device
-*/
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/poll.h>
-#include <linux/slab.h>
-#ifdef CONFIG_USB_PWC_INPUT_EVDEV
-#include <linux/usb/input.h>
-#endif
-#include <linux/vmalloc.h>
-#include <asm/io.h>
-#include <linux/kernel.h> /* simple_strtol() */
-
-#include "pwc.h"
-#include "pwc-kiara.h"
-#include "pwc-timon.h"
-#include "pwc-dec23.h"
-#include "pwc-dec1.h"
-
-/* Function prototypes and driver templates */
-
-/* hotplug device table support */
-static const struct usb_device_id pwc_device_table [] = {
- { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */
- { USB_DEVICE(0x0471, 0x0303) },
- { USB_DEVICE(0x0471, 0x0304) },
- { USB_DEVICE(0x0471, 0x0307) },
- { USB_DEVICE(0x0471, 0x0308) },
- { USB_DEVICE(0x0471, 0x030C) },
- { USB_DEVICE(0x0471, 0x0310) },
- { USB_DEVICE(0x0471, 0x0311) }, /* Philips ToUcam PRO II */
- { USB_DEVICE(0x0471, 0x0312) },
- { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */
- { USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */
- { USB_DEVICE(0x069A, 0x0001) }, /* Askey */
- { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */
- { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */
- { USB_DEVICE(0x046D, 0x08B2) }, /* Logitech QuickCam Pro 4000 */
- { USB_DEVICE(0x046D, 0x08B3) }, /* Logitech QuickCam Zoom (old model) */
- { USB_DEVICE(0x046D, 0x08B4) }, /* Logitech QuickCam Zoom (new model) */
- { USB_DEVICE(0x046D, 0x08B5) }, /* Logitech QuickCam Orbit/Sphere */
- { USB_DEVICE(0x046D, 0x08B6) }, /* Cisco VT Camera */
- { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech ViewPort AV 100 */
- { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */
- { USB_DEVICE(0x055D, 0x9000) }, /* Samsung MPC-C10 */
- { USB_DEVICE(0x055D, 0x9001) }, /* Samsung MPC-C30 */
- { USB_DEVICE(0x055D, 0x9002) }, /* Samsung SNC-35E (Ver3.0) */
- { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */
- { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */
- { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */
- { USB_DEVICE(0x06BE, 0x8116) }, /* new Afina Eye */
- { USB_DEVICE(0x0d81, 0x1910) }, /* Visionite */
- { USB_DEVICE(0x0d81, 0x1900) },
- { }
-};
-MODULE_DEVICE_TABLE(usb, pwc_device_table);
-
-static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id);
-static void usb_pwc_disconnect(struct usb_interface *intf);
-static void pwc_isoc_cleanup(struct pwc_device *pdev);
-
-static struct usb_driver pwc_driver = {
- .name = "Philips webcam", /* name */
- .id_table = pwc_device_table,
- .probe = usb_pwc_probe, /* probe() */
- .disconnect = usb_pwc_disconnect, /* disconnect() */
-};
-
-#define MAX_DEV_HINTS 20
-#define MAX_ISOC_ERRORS 20
-
-#ifdef CONFIG_USB_PWC_DEBUG
- int pwc_trace = PWC_DEBUG_LEVEL;
-#endif
-static int power_save = -1;
-static int leds[2] = { 100, 0 };
-
-/***/
-
-static const struct v4l2_file_operations pwc_fops = {
- .owner = THIS_MODULE,
- .open = v4l2_fh_open,
- .release = vb2_fop_release,
- .read = vb2_fop_read,
- .poll = vb2_fop_poll,
- .mmap = vb2_fop_mmap,
- .unlocked_ioctl = video_ioctl2,
-};
-static struct video_device pwc_template = {
- .name = "Philips Webcam", /* Filled in later */
- .release = video_device_release_empty,
- .fops = &pwc_fops,
- .ioctl_ops = &pwc_ioctl_ops,
-};
-
-/***************************************************************************/
-/* Private functions */
-
-struct pwc_frame_buf *pwc_get_next_fill_buf(struct pwc_device *pdev)
-{
- unsigned long flags = 0;
- struct pwc_frame_buf *buf = NULL;
-
- spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
- if (list_empty(&pdev->queued_bufs))
- goto leave;
-
- buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf, list);
- list_del(&buf->list);
-leave:
- spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
- return buf;
-}
-
-static void pwc_snapshot_button(struct pwc_device *pdev, int down)
-{
- if (down) {
- PWC_TRACE("Snapshot button pressed.\n");
- } else {
- PWC_TRACE("Snapshot button released.\n");
- }
-
-#ifdef CONFIG_USB_PWC_INPUT_EVDEV
- if (pdev->button_dev) {
- input_report_key(pdev->button_dev, KEY_CAMERA, down);
- input_sync(pdev->button_dev);
- }
-#endif
-}
-
-static void pwc_frame_complete(struct pwc_device *pdev)
-{
- struct pwc_frame_buf *fbuf = pdev->fill_buf;
-
- /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus
- frames on the USB wire after an exposure change. This conditition is
- however detected in the cam and a bit is set in the header.
- */
- if (pdev->type == 730) {
- unsigned char *ptr = (unsigned char *)fbuf->data;
-
- if (ptr[1] == 1 && ptr[0] & 0x10) {
- PWC_TRACE("Hyundai CMOS sensor bug. Dropping frame.\n");
- pdev->drop_frames += 2;
- }
- if ((ptr[0] ^ pdev->vmirror) & 0x01) {
- pwc_snapshot_button(pdev, ptr[0] & 0x01);
- }
- if ((ptr[0] ^ pdev->vmirror) & 0x02) {
- if (ptr[0] & 0x02)
- PWC_TRACE("Image is mirrored.\n");
- else
- PWC_TRACE("Image is normal.\n");
- }
- pdev->vmirror = ptr[0] & 0x03;
- /* Sometimes the trailer of the 730 is still sent as a 4 byte packet
- after a short frame; this condition is filtered out specifically. A 4 byte
- frame doesn't make sense anyway.
- So we get either this sequence:
- drop_bit set -> 4 byte frame -> short frame -> good frame
- Or this one:
- drop_bit set -> short frame -> good frame
- So we drop either 3 or 2 frames in all!
- */
- if (fbuf->filled == 4)
- pdev->drop_frames++;
- } else if (pdev->type == 740 || pdev->type == 720) {
- unsigned char *ptr = (unsigned char *)fbuf->data;
- if ((ptr[0] ^ pdev->vmirror) & 0x01) {
- pwc_snapshot_button(pdev, ptr[0] & 0x01);
- }
- pdev->vmirror = ptr[0] & 0x03;
- }
-
- /* In case we were instructed to drop the frame, do so silently. */
- if (pdev->drop_frames > 0) {
- pdev->drop_frames--;
- } else {
- /* Check for underflow first */
- if (fbuf->filled < pdev->frame_total_size) {
- PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);"
- " discarded.\n", fbuf->filled);
- } else {
- fbuf->vb.v4l2_buf.field = V4L2_FIELD_NONE;
- fbuf->vb.v4l2_buf.sequence = pdev->vframe_count;
- vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
- pdev->fill_buf = NULL;
- pdev->vsync = 0;
- }
- } /* !drop_frames */
- pdev->vframe_count++;
-}
-
-/* This gets called for the Isochronous pipe (video). This is done in
- * interrupt time, so it has to be fast, not crash, and not stall. Neat.
- */
-static void pwc_isoc_handler(struct urb *urb)
-{
- struct pwc_device *pdev = (struct pwc_device *)urb->context;
- int i, fst, flen;
- unsigned char *iso_buf = NULL;
-
- if (urb->status == -ENOENT || urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN) {
- PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a");
- return;
- }
-
- if (pdev->fill_buf == NULL)
- pdev->fill_buf = pwc_get_next_fill_buf(pdev);
-
- if (urb->status != 0) {
- const char *errmsg;
-
- errmsg = "Unknown";
- switch(urb->status) {
- case -ENOSR: errmsg = "Buffer error (overrun)"; break;
- case -EPIPE: errmsg = "Stalled (device not responding)"; break;
- case -EOVERFLOW: errmsg = "Babble (bad cable?)"; break;
- case -EPROTO: errmsg = "Bit-stuff error (bad cable?)"; break;
- case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break;
- case -ETIME: errmsg = "Device does not respond"; break;
- }
- PWC_ERROR("pwc_isoc_handler() called with status %d [%s].\n",
- urb->status, errmsg);
- /* Give up after a number of contiguous errors */
- if (++pdev->visoc_errors > MAX_ISOC_ERRORS)
- {
- PWC_ERROR("Too many ISOC errors, bailing out.\n");
- if (pdev->fill_buf) {
- vb2_buffer_done(&pdev->fill_buf->vb,
- VB2_BUF_STATE_ERROR);
- pdev->fill_buf = NULL;
- }
- }
- pdev->vsync = 0; /* Drop the current frame */
- goto handler_end;
- }
-
- /* Reset ISOC error counter. We did get here, after all. */
- pdev->visoc_errors = 0;
-
- /* vsync: 0 = don't copy data
- 1 = sync-hunt
- 2 = synched
- */
- /* Compact data */
- for (i = 0; i < urb->number_of_packets; i++) {
- fst = urb->iso_frame_desc[i].status;
- flen = urb->iso_frame_desc[i].actual_length;
- iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
- if (fst != 0) {
- PWC_ERROR("Iso frame %d has error %d\n", i, fst);
- continue;
- }
- if (flen > 0 && pdev->vsync) {
- struct pwc_frame_buf *fbuf = pdev->fill_buf;
-
- if (pdev->vsync == 1) {
- do_gettimeofday(&fbuf->vb.v4l2_buf.timestamp);
- pdev->vsync = 2;
- }
-
- if (flen + fbuf->filled > pdev->frame_total_size) {
- PWC_ERROR("Frame overflow (%d > %d)\n",
- flen + fbuf->filled,
- pdev->frame_total_size);
- pdev->vsync = 0; /* Let's wait for an EOF */
- } else {
- memcpy(fbuf->data + fbuf->filled, iso_buf,
- flen);
- fbuf->filled += flen;
- }
- }
- if (flen < pdev->vlast_packet_size) {
- /* Shorter packet... end of frame */
- if (pdev->vsync == 2)
- pwc_frame_complete(pdev);
- if (pdev->fill_buf == NULL)
- pdev->fill_buf = pwc_get_next_fill_buf(pdev);
- if (pdev->fill_buf) {
- pdev->fill_buf->filled = 0;
- pdev->vsync = 1;
- }
- }
- pdev->vlast_packet_size = flen;
- }
-
-handler_end:
- i = usb_submit_urb(urb, GFP_ATOMIC);
- if (i != 0)
- PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i);
-}
-
-/* Both v4l2_lock and vb_queue_lock should be locked when calling this */
-static int pwc_isoc_init(struct pwc_device *pdev)
-{
- struct usb_device *udev;
- struct urb *urb;
- int i, j, ret;
- struct usb_interface *intf;
- struct usb_host_interface *idesc = NULL;
- int compression = 0; /* 0..3 = uncompressed..high */
-
- pdev->vsync = 0;
- pdev->vlast_packet_size = 0;
- pdev->fill_buf = NULL;
- pdev->vframe_count = 0;
- pdev->visoc_errors = 0;
- udev = pdev->udev;
-
-retry:
- /* We first try with low compression and then retry with a higher
- compression setting if there is not enough bandwidth. */
- ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt,
- pdev->vframes, &compression, 1);
-
- /* Get the current alternate interface, adjust packet size */
- intf = usb_ifnum_to_if(udev, 0);
- if (intf)
- idesc = usb_altnum_to_altsetting(intf, pdev->valternate);
- if (!idesc)
- return -EIO;
-
- /* Search video endpoint */
- pdev->vmax_packet_size = -1;
- for (i = 0; i < idesc->desc.bNumEndpoints; i++) {
- if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) {
- pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize);
- break;
- }
- }
-
- if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
- PWC_ERROR("Failed to find packet size for video endpoint in current alternate setting.\n");
- return -ENFILE; /* Odd error, that should be noticeable */
- }
-
- /* Set alternate interface */
- PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate);
- ret = usb_set_interface(pdev->udev, 0, pdev->valternate);
- if (ret == -ENOSPC && compression < 3) {
- compression++;
- goto retry;
- }
- if (ret < 0)
- return ret;
-
- /* Allocate and init Isochronuous urbs */
- for (i = 0; i < MAX_ISO_BUFS; i++) {
- urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
- if (urb == NULL) {
- PWC_ERROR("Failed to allocate urb %d\n", i);
- pwc_isoc_cleanup(pdev);
- return -ENOMEM;
- }
- pdev->urbs[i] = urb;
- PWC_DEBUG_MEMORY("Allocated URB at 0x%p\n", urb);
-
- urb->interval = 1; // devik
- urb->dev = udev;
- urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint);
- urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
- urb->transfer_buffer = usb_alloc_coherent(udev,
- ISO_BUFFER_SIZE,
- GFP_KERNEL,
- &urb->transfer_dma);
- if (urb->transfer_buffer == NULL) {
- PWC_ERROR("Failed to allocate urb buffer %d\n", i);
- pwc_isoc_cleanup(pdev);
- return -ENOMEM;
- }
- urb->transfer_buffer_length = ISO_BUFFER_SIZE;
- urb->complete = pwc_isoc_handler;
- urb->context = pdev;
- urb->start_frame = 0;
- urb->number_of_packets = ISO_FRAMES_PER_DESC;
- for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
- urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE;
- urb->iso_frame_desc[j].length = pdev->vmax_packet_size;
- }
- }
-
- /* link */
- for (i = 0; i < MAX_ISO_BUFS; i++) {
- ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL);
- if (ret == -ENOSPC && compression < 3) {
- compression++;
- pwc_isoc_cleanup(pdev);
- goto retry;
- }
- if (ret) {
- PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
- pwc_isoc_cleanup(pdev);
- return ret;
- }
- PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->urbs[i]);
- }
-
- /* All is done... */
- PWC_DEBUG_OPEN("<< pwc_isoc_init()\n");
- return 0;
-}
-
-static void pwc_iso_stop(struct pwc_device *pdev)
-{
- int i;
-
- /* Unlinking ISOC buffers one by one */
- for (i = 0; i < MAX_ISO_BUFS; i++) {
- if (pdev->urbs[i]) {
- PWC_DEBUG_MEMORY("Unlinking URB %p\n", pdev->urbs[i]);
- usb_kill_urb(pdev->urbs[i]);
- }
- }
-}
-
-static void pwc_iso_free(struct pwc_device *pdev)
-{
- int i;
-
- /* Freeing ISOC buffers one by one */
- for (i = 0; i < MAX_ISO_BUFS; i++) {
- if (pdev->urbs[i]) {
- PWC_DEBUG_MEMORY("Freeing URB\n");
- if (pdev->urbs[i]->transfer_buffer) {
- usb_free_coherent(pdev->udev,
- pdev->urbs[i]->transfer_buffer_length,
- pdev->urbs[i]->transfer_buffer,
- pdev->urbs[i]->transfer_dma);
- }
- usb_free_urb(pdev->urbs[i]);
- pdev->urbs[i] = NULL;
- }
- }
-}
-
-/* Both v4l2_lock and vb_queue_lock should be locked when calling this */
-static void pwc_isoc_cleanup(struct pwc_device *pdev)
-{
- PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n");
-
- pwc_iso_stop(pdev);
- pwc_iso_free(pdev);
- usb_set_interface(pdev->udev, 0, 0);
-
- PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n");
-}
-
-/* Must be called with vb_queue_lock hold */
-static void pwc_cleanup_queued_bufs(struct pwc_device *pdev)
-{
- unsigned long flags = 0;
-
- spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
- while (!list_empty(&pdev->queued_bufs)) {
- struct pwc_frame_buf *buf;
-
- buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf,
- list);
- list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- }
- spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
-}
-
-#ifdef CONFIG_USB_PWC_DEBUG
-static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
-{
- switch(sensor_type) {
- case 0x00:
- return "Hyundai CMOS sensor";
- case 0x20:
- return "Sony CCD sensor + TDA8787";
- case 0x2E:
- return "Sony CCD sensor + Exas 98L59";
- case 0x2F:
- return "Sony CCD sensor + ADI 9804";
- case 0x30:
- return "Sharp CCD sensor + TDA8787";
- case 0x3E:
- return "Sharp CCD sensor + Exas 98L59";
- case 0x3F:
- return "Sharp CCD sensor + ADI 9804";
- case 0x40:
- return "UPA 1021 sensor";
- case 0x100:
- return "VGA sensor";
- case 0x101:
- return "PAL MR sensor";
- default:
- return "unknown type of sensor";
- }
-}
-#endif
-
-/***************************************************************************/
-/* Video4Linux functions */
-
-static void pwc_video_release(struct v4l2_device *v)
-{
- struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
-
- v4l2_ctrl_handler_free(&pdev->ctrl_handler);
- v4l2_device_unregister(&pdev->v4l2_dev);
- kfree(pdev->ctrl_buf);
- kfree(pdev);
-}
-
-/***************************************************************************/
-/* Videobuf2 operations */
-
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
- unsigned int *nbuffers, unsigned int *nplanes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- struct pwc_device *pdev = vb2_get_drv_priv(vq);
- int size;
-
- if (*nbuffers < MIN_FRAMES)
- *nbuffers = MIN_FRAMES;
- else if (*nbuffers > MAX_FRAMES)
- *nbuffers = MAX_FRAMES;
-
- *nplanes = 1;
-
- size = pwc_get_size(pdev, MAX_WIDTH, MAX_HEIGHT);
- sizes[0] = PAGE_ALIGN(pwc_image_sizes[size][0] *
- pwc_image_sizes[size][1] * 3 / 2);
-
- return 0;
-}
-
-static int buffer_init(struct vb2_buffer *vb)
-{
- struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
-
- /* need vmalloc since frame buffer > 128K */
- buf->data = vzalloc(PWC_FRAME_SIZE);
- if (buf->data == NULL)
- return -ENOMEM;
-
- return 0;
-}
-
-static int buffer_prepare(struct vb2_buffer *vb)
-{
- struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
-
- /* Don't allow queing new buffers after device disconnection */
- if (!pdev->udev)
- return -ENODEV;
-
- return 0;
-}
-
-static int buffer_finish(struct vb2_buffer *vb)
-{
- struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
- struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
-
- /*
- * Application has called dqbuf and is getting back a buffer we've
- * filled, take the pwc data we've stored in buf->data and decompress
- * it into a usable format, storing the result in the vb2_buffer
- */
- return pwc_decompress(pdev, buf);
-}
-
-static void buffer_cleanup(struct vb2_buffer *vb)
-{
- struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
-
- vfree(buf->data);
-}
-
-static void buffer_queue(struct vb2_buffer *vb)
-{
- struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
- struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
- unsigned long flags = 0;
-
- /* Check the device has not disconnected between prep and queuing */
- if (!pdev->udev) {
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- return;
- }
-
- spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
- list_add_tail(&buf->list, &pdev->queued_bufs);
- spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
-}
-
-static int start_streaming(struct vb2_queue *vq, unsigned int count)
-{
- struct pwc_device *pdev = vb2_get_drv_priv(vq);
- int r;
-
- if (!pdev->udev)
- return -ENODEV;
-
- if (mutex_lock_interruptible(&pdev->v4l2_lock))
- return -ERESTARTSYS;
- /* Turn on camera and set LEDS on */
- pwc_camera_power(pdev, 1);
- pwc_set_leds(pdev, leds[0], leds[1]);
-
- r = pwc_isoc_init(pdev);
- if (r) {
- /* If we failed turn camera and LEDS back off */
- pwc_set_leds(pdev, 0, 0);
- pwc_camera_power(pdev, 0);
- /* And cleanup any queued bufs!! */
- pwc_cleanup_queued_bufs(pdev);
- }
- mutex_unlock(&pdev->v4l2_lock);
-
- return r;
-}
-
-static int stop_streaming(struct vb2_queue *vq)
-{
- struct pwc_device *pdev = vb2_get_drv_priv(vq);
-
- if (mutex_lock_interruptible(&pdev->v4l2_lock))
- return -ERESTARTSYS;
- if (pdev->udev) {
- pwc_set_leds(pdev, 0, 0);
- pwc_camera_power(pdev, 0);
- pwc_isoc_cleanup(pdev);
- }
-
- pwc_cleanup_queued_bufs(pdev);
- mutex_unlock(&pdev->v4l2_lock);
-
- return 0;
-}
-
-static struct vb2_ops pwc_vb_queue_ops = {
- .queue_setup = queue_setup,
- .buf_init = buffer_init,
- .buf_prepare = buffer_prepare,
- .buf_finish = buffer_finish,
- .buf_cleanup = buffer_cleanup,
- .buf_queue = buffer_queue,
- .start_streaming = start_streaming,
- .stop_streaming = stop_streaming,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
-};
-
-/***************************************************************************/
-/* USB functions */
-
-/* This function gets called when a new device is plugged in or the usb core
- * is loaded.
- */
-
-static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct pwc_device *pdev = NULL;
- int vendor_id, product_id, type_id;
- int rc;
- int features = 0;
- int compression = 0;
- int my_power_save = power_save;
- char serial_number[30], *name;
-
- vendor_id = le16_to_cpu(udev->descriptor.idVendor);
- product_id = le16_to_cpu(udev->descriptor.idProduct);
-
- /* Check if we can handle this device */
- PWC_DEBUG_PROBE("probe() called [%04X %04X], if %d\n",
- vendor_id, product_id,
- intf->altsetting->desc.bInterfaceNumber);
-
- /* the interfaces are probed one by one. We are only interested in the
- video interface (0) now.
- Interface 1 is the Audio Control, and interface 2 Audio itself.
- */
- if (intf->altsetting->desc.bInterfaceNumber > 0)
- return -ENODEV;
-
- if (vendor_id == 0x0471) {
- switch (product_id) {
- case 0x0302:
- PWC_INFO("Philips PCA645VC USB webcam detected.\n");
- name = "Philips 645 webcam";
- type_id = 645;
- break;
- case 0x0303:
- PWC_INFO("Philips PCA646VC USB webcam detected.\n");
- name = "Philips 646 webcam";
- type_id = 646;
- break;
- case 0x0304:
- PWC_INFO("Askey VC010 type 2 USB webcam detected.\n");
- name = "Askey VC010 webcam";
- type_id = 646;
- break;
- case 0x0307:
- PWC_INFO("Philips PCVC675K (Vesta) USB webcam detected.\n");
- name = "Philips 675 webcam";
- type_id = 675;
- break;
- case 0x0308:
- PWC_INFO("Philips PCVC680K (Vesta Pro) USB webcam detected.\n");
- name = "Philips 680 webcam";
- type_id = 680;
- break;
- case 0x030C:
- PWC_INFO("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n");
- name = "Philips 690 webcam";
- type_id = 690;
- break;
- case 0x0310:
- PWC_INFO("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n");
- name = "Philips 730 webcam";
- type_id = 730;
- break;
- case 0x0311:
- PWC_INFO("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n");
- name = "Philips 740 webcam";
- type_id = 740;
- break;
- case 0x0312:
- PWC_INFO("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n");
- name = "Philips 750 webcam";
- type_id = 750;
- break;
- case 0x0313:
- PWC_INFO("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n");
- name = "Philips 720K/40 webcam";
- type_id = 720;
- break;
- case 0x0329:
- PWC_INFO("Philips SPC 900NC USB webcam detected.\n");
- name = "Philips SPC 900NC webcam";
- type_id = 740;
- break;
- default:
- return -ENODEV;
- break;
- }
- }
- else if (vendor_id == 0x069A) {
- switch(product_id) {
- case 0x0001:
- PWC_INFO("Askey VC010 type 1 USB webcam detected.\n");
- name = "Askey VC010 webcam";
- type_id = 645;
- break;
- default:
- return -ENODEV;
- break;
- }
- }
- else if (vendor_id == 0x046d) {
- switch(product_id) {
- case 0x08b0:
- PWC_INFO("Logitech QuickCam Pro 3000 USB webcam detected.\n");
- name = "Logitech QuickCam Pro 3000";
- type_id = 740; /* CCD sensor */
- break;
- case 0x08b1:
- PWC_INFO("Logitech QuickCam Notebook Pro USB webcam detected.\n");
- name = "Logitech QuickCam Notebook Pro";
- type_id = 740; /* CCD sensor */
- break;
- case 0x08b2:
- PWC_INFO("Logitech QuickCam 4000 Pro USB webcam detected.\n");
- name = "Logitech QuickCam Pro 4000";
- type_id = 740; /* CCD sensor */
- if (my_power_save == -1)
- my_power_save = 1;
- break;
- case 0x08b3:
- PWC_INFO("Logitech QuickCam Zoom USB webcam detected.\n");
- name = "Logitech QuickCam Zoom";
- type_id = 740; /* CCD sensor */
- break;
- case 0x08B4:
- PWC_INFO("Logitech QuickCam Zoom (new model) USB webcam detected.\n");
- name = "Logitech QuickCam Zoom";
- type_id = 740; /* CCD sensor */
- if (my_power_save == -1)
- my_power_save = 1;
- break;
- case 0x08b5:
- PWC_INFO("Logitech QuickCam Orbit/Sphere USB webcam detected.\n");
- name = "Logitech QuickCam Orbit";
- type_id = 740; /* CCD sensor */
- if (my_power_save == -1)
- my_power_save = 1;
- features |= FEATURE_MOTOR_PANTILT;
- break;
- case 0x08b6:
- PWC_INFO("Logitech/Cisco VT Camera webcam detected.\n");
- name = "Cisco VT Camera";
- type_id = 740; /* CCD sensor */
- break;
- case 0x08b7:
- PWC_INFO("Logitech ViewPort AV 100 webcam detected.\n");
- name = "Logitech ViewPort AV 100";
- type_id = 740; /* CCD sensor */
- break;
- case 0x08b8: /* Where this released? */
- PWC_INFO("Logitech QuickCam detected (reserved ID).\n");
- name = "Logitech QuickCam (res.)";
- type_id = 730; /* Assuming CMOS */
- break;
- default:
- return -ENODEV;
- break;
- }
- }
- else if (vendor_id == 0x055d) {
- /* I don't know the difference between the C10 and the C30;
- I suppose the difference is the sensor, but both cameras
- work equally well with a type_id of 675
- */
- switch(product_id) {
- case 0x9000:
- PWC_INFO("Samsung MPC-C10 USB webcam detected.\n");
- name = "Samsung MPC-C10";
- type_id = 675;
- break;
- case 0x9001:
- PWC_INFO("Samsung MPC-C30 USB webcam detected.\n");
- name = "Samsung MPC-C30";
- type_id = 675;
- break;
- case 0x9002:
- PWC_INFO("Samsung SNC-35E (v3.0) USB webcam detected.\n");
- name = "Samsung MPC-C30";
- type_id = 740;
- break;
- default:
- return -ENODEV;
- break;
- }
- }
- else if (vendor_id == 0x041e) {
- switch(product_id) {
- case 0x400c:
- PWC_INFO("Creative Labs Webcam 5 detected.\n");
- name = "Creative Labs Webcam 5";
- type_id = 730;
- if (my_power_save == -1)
- my_power_save = 1;
- break;
- case 0x4011:
- PWC_INFO("Creative Labs Webcam Pro Ex detected.\n");
- name = "Creative Labs Webcam Pro Ex";
- type_id = 740;
- break;
- default:
- return -ENODEV;
- break;
- }
- }
- else if (vendor_id == 0x04cc) {
- switch(product_id) {
- case 0x8116:
- PWC_INFO("Sotec Afina Eye USB webcam detected.\n");
- name = "Sotec Afina Eye";
- type_id = 730;
- break;
- default:
- return -ENODEV;
- break;
- }
- }
- else if (vendor_id == 0x06be) {
- switch(product_id) {
- case 0x8116:
- /* This is essentially the same cam as the Sotec Afina Eye */
- PWC_INFO("AME Co. Afina Eye USB webcam detected.\n");
- name = "AME Co. Afina Eye";
- type_id = 750;
- break;
- default:
- return -ENODEV;
- break;
- }
-
- }
- else if (vendor_id == 0x0d81) {
- switch(product_id) {
- case 0x1900:
- PWC_INFO("Visionite VCS-UC300 USB webcam detected.\n");
- name = "Visionite VCS-UC300";
- type_id = 740; /* CCD sensor */
- break;
- case 0x1910:
- PWC_INFO("Visionite VCS-UM100 USB webcam detected.\n");
- name = "Visionite VCS-UM100";
- type_id = 730; /* CMOS sensor */
- break;
- default:
- return -ENODEV;
- break;
- }
- }
- else
- return -ENODEV; /* Not any of the know types; but the list keeps growing. */
-
- if (my_power_save == -1)
- my_power_save = 0;
-
- memset(serial_number, 0, 30);
- usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
- PWC_DEBUG_PROBE("Device serial number is %s\n", serial_number);
-
- if (udev->descriptor.bNumConfigurations > 1)
- PWC_WARNING("Warning: more than 1 configuration available.\n");
-
- /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */
- pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL);
- if (pdev == NULL) {
- PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
- return -ENOMEM;
- }
- pdev->type = type_id;
- pdev->features = features;
- pwc_construct(pdev); /* set min/max sizes correct */
-
- mutex_init(&pdev->v4l2_lock);
- mutex_init(&pdev->vb_queue_lock);
- spin_lock_init(&pdev->queued_bufs_lock);
- INIT_LIST_HEAD(&pdev->queued_bufs);
-
- pdev->udev = udev;
- pdev->power_save = my_power_save;
-
- /* Init videobuf2 queue structure */
- memset(&pdev->vb_queue, 0, sizeof(pdev->vb_queue));
- pdev->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- pdev->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
- pdev->vb_queue.drv_priv = pdev;
- pdev->vb_queue.buf_struct_size = sizeof(struct pwc_frame_buf);
- pdev->vb_queue.ops = &pwc_vb_queue_ops;
- pdev->vb_queue.mem_ops = &vb2_vmalloc_memops;
- vb2_queue_init(&pdev->vb_queue);
-
- /* Init video_device structure */
- memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template));
- strcpy(pdev->vdev.name, name);
- pdev->vdev.queue = &pdev->vb_queue;
- pdev->vdev.queue->lock = &pdev->vb_queue_lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &pdev->vdev.flags);
- video_set_drvdata(&pdev->vdev, pdev);
-
- pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
- PWC_DEBUG_PROBE("Release: %04x\n", pdev->release);
-
- /* Allocate USB command buffers */
- pdev->ctrl_buf = kmalloc(sizeof(pdev->cmd_buf), GFP_KERNEL);
- if (!pdev->ctrl_buf) {
- PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
- rc = -ENOMEM;
- goto err_free_mem;
- }
-
-#ifdef CONFIG_USB_PWC_DEBUG
- /* Query sensor type */
- if (pwc_get_cmos_sensor(pdev, &rc) >= 0) {
- PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n",
- pdev->vdev.name,
- pwc_sensor_type_to_string(rc), rc);
- }
-#endif
-
- /* Set the leds off */
- pwc_set_leds(pdev, 0, 0);
-
- /* Setup intial videomode */
- rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT,
- V4L2_PIX_FMT_YUV420, 30, &compression, 1);
- if (rc)
- goto err_free_mem;
-
- /* Register controls (and read default values from camera */
- rc = pwc_init_controls(pdev);
- if (rc) {
- PWC_ERROR("Failed to register v4l2 controls (%d).\n", rc);
- goto err_free_mem;
- }
-
- /* And powerdown the camera until streaming starts */
- pwc_camera_power(pdev, 0);
-
- /* Register the v4l2_device structure */
- pdev->v4l2_dev.release = pwc_video_release;
- rc = v4l2_device_register(&intf->dev, &pdev->v4l2_dev);
- if (rc) {
- PWC_ERROR("Failed to register v4l2-device (%d).\n", rc);
- goto err_free_controls;
- }
-
- pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler;
- pdev->vdev.v4l2_dev = &pdev->v4l2_dev;
- pdev->vdev.lock = &pdev->v4l2_lock;
-
- rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1);
- if (rc < 0) {
- PWC_ERROR("Failed to register as video device (%d).\n", rc);
- goto err_unregister_v4l2_dev;
- }
- PWC_INFO("Registered as %s.\n", video_device_node_name(&pdev->vdev));
-
-#ifdef CONFIG_USB_PWC_INPUT_EVDEV
- /* register webcam snapshot button input device */
- pdev->button_dev = input_allocate_device();
- if (!pdev->button_dev) {
- PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
- rc = -ENOMEM;
- goto err_video_unreg;
- }
-
- usb_make_path(udev, pdev->button_phys, sizeof(pdev->button_phys));
- strlcat(pdev->button_phys, "/input0", sizeof(pdev->button_phys));
-
- pdev->button_dev->name = "PWC snapshot button";
- pdev->button_dev->phys = pdev->button_phys;
- usb_to_input_id(pdev->udev, &pdev->button_dev->id);
- pdev->button_dev->dev.parent = &pdev->udev->dev;
- pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
- pdev->button_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
-
- rc = input_register_device(pdev->button_dev);
- if (rc) {
- input_free_device(pdev->button_dev);
- pdev->button_dev = NULL;
- goto err_video_unreg;
- }
-#endif
-
- return 0;
-
-err_video_unreg:
- video_unregister_device(&pdev->vdev);
-err_unregister_v4l2_dev:
- v4l2_device_unregister(&pdev->v4l2_dev);
-err_free_controls:
- v4l2_ctrl_handler_free(&pdev->ctrl_handler);
-err_free_mem:
- kfree(pdev->ctrl_buf);
- kfree(pdev);
- return rc;
-}
-
-/* The user yanked out the cable... */
-static void usb_pwc_disconnect(struct usb_interface *intf)
-{
- struct v4l2_device *v = usb_get_intfdata(intf);
- struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
-
- mutex_lock(&pdev->vb_queue_lock);
- mutex_lock(&pdev->v4l2_lock);
- /* No need to keep the urbs around after disconnection */
- if (pdev->vb_queue.streaming)
- pwc_isoc_cleanup(pdev);
- pdev->udev = NULL;
- pwc_cleanup_queued_bufs(pdev);
-
- v4l2_device_disconnect(&pdev->v4l2_dev);
- video_unregister_device(&pdev->vdev);
- mutex_unlock(&pdev->v4l2_lock);
- mutex_unlock(pdev->vb_queue.lock);
-
-#ifdef CONFIG_USB_PWC_INPUT_EVDEV
- if (pdev->button_dev)
- input_unregister_device(pdev->button_dev);
-#endif
-
- v4l2_device_put(&pdev->v4l2_dev);
-}
-
-
-/*
- * Initialization code & module stuff
- */
-
-static unsigned int leds_nargs;
-
-#ifdef CONFIG_USB_PWC_DEBUG
-module_param_named(trace, pwc_trace, int, 0644);
-#endif
-module_param(power_save, int, 0644);
-module_param_array(leds, int, &leds_nargs, 0444);
-
-#ifdef CONFIG_USB_PWC_DEBUG
-MODULE_PARM_DESC(trace, "For debugging purposes");
-#endif
-MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off");
-MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
-
-MODULE_DESCRIPTION("Philips & OEM USB webcam driver");
-MODULE_AUTHOR("Luc Saillard <luc@saillard.org>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("pwcx");
-MODULE_VERSION( PWC_VERSION );
-
-module_usb_driver(pwc_driver);
diff --git a/drivers/media/video/pwc/pwc-kiara.c b/drivers/media/video/pwc/pwc-kiara.c
deleted file mode 100644
index e5f4fd81712..00000000000
--- a/drivers/media/video/pwc/pwc-kiara.c
+++ /dev/null
@@ -1,892 +0,0 @@
-/* Linux driver for Philips webcam
- (C) 2004-2006 Luc Saillard (luc@saillard.org)
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
- The decompression routines have been implemented by reverse-engineering the
- Nemosoft binary pwcx module. Caveat emptor.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-
-/* This tables contains entries for the 730/740/750 (Kiara) camera, with
- 4 different qualities (no compression, low, medium, high).
- It lists the bandwidth requirements for said mode by its alternate interface
- number. An alternate of 0 means that the mode is unavailable.
-
- There are 6 * 4 * 4 entries:
- 6 different resolutions subqcif, qsif, qcif, sif, cif, vga
- 6 framerates: 5, 10, 15, 20, 25, 30
- 4 compression modi: none, low, medium, high
-
- When an uncompressed mode is not available, the next available compressed mode
- will be chosen (unless the decompressor is absent). Sometimes there are only
- 1 or 2 compressed modes available; in that case entries are duplicated.
-*/
-
-
-#include "pwc-kiara.h"
-
-const unsigned int Kiara_fps_vector[PWC_FPS_MAX_KIARA] = { 5, 10, 15, 20, 25, 30 };
-
-const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] =
-{
- /* SQCIF */
- {
- /* 5 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 10 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 15 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 20 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 25 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 30 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- },
- /* QSIF */
- {
- /* 5 fps */
- {
- {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
- {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
- {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
- {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
- },
- /* 10 fps */
- {
- {2, 291, 0, {0x1C, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0x01, 0x80}},
- {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
- {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
- {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
- },
- /* 15 fps */
- {
- {3, 437, 0, {0x1B, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x01, 0x80}},
- {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
- {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
- {1, 192, 420, {0x13, 0xF4, 0x30, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
- },
- /* 20 fps */
- {
- {4, 589, 0, {0x1A, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4D, 0x02, 0x80}},
- {3, 448, 730, {0x12, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xC0, 0x01, 0x80}},
- {2, 292, 476, {0x12, 0xF4, 0x30, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0x01, 0x80}},
- {1, 192, 312, {0x12, 0xF4, 0x50, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
- },
- /* 25 fps */
- {
- {5, 703, 0, {0x19, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x02, 0x80}},
- {3, 447, 610, {0x11, 0xF4, 0x30, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x28, 0xBF, 0x01, 0x80}},
- {2, 292, 398, {0x11, 0xF4, 0x50, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x28, 0x24, 0x01, 0x80}},
- {1, 193, 262, {0x11, 0xF4, 0x50, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x28, 0xC1, 0x00, 0x80}},
- },
- /* 30 fps */
- {
- {8, 874, 0, {0x18, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x6A, 0x03, 0x80}},
- {5, 704, 730, {0x10, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x28, 0xC0, 0x02, 0x80}},
- {3, 448, 492, {0x10, 0xF4, 0x30, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x28, 0xC0, 0x01, 0x80}},
- {2, 292, 320, {0x10, 0xF4, 0x50, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x28, 0x24, 0x01, 0x80}},
- },
- },
- /* QCIF */
- {
- /* 5 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 10 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 15 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 20 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 25 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 30 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- },
- /* SIF */
- {
- /* 5 fps */
- {
- {4, 582, 0, {0x0D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x02, 0x80}},
- {3, 387, 1276, {0x05, 0xF4, 0x30, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x01, 0x80}},
- {2, 291, 960, {0x05, 0xF4, 0x30, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0x01, 0x80}},
- {1, 191, 630, {0x05, 0xF4, 0x50, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x18, 0xBF, 0x00, 0x80}},
- },
- /* 10 fps */
- {
- {0, },
- {6, 775, 1278, {0x04, 0xF4, 0x30, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x03, 0x80}},
- {3, 447, 736, {0x04, 0xF4, 0x30, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x28, 0xBF, 0x01, 0x80}},
- {2, 292, 480, {0x04, 0xF4, 0x70, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x28, 0x24, 0x01, 0x80}},
- },
- /* 15 fps */
- {
- {0, },
- {9, 955, 1050, {0x03, 0xF4, 0x30, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x03, 0x80}},
- {4, 592, 650, {0x03, 0xF4, 0x30, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x50, 0x02, 0x80}},
- {3, 448, 492, {0x03, 0xF4, 0x50, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x38, 0xC0, 0x01, 0x80}},
- },
- /* 20 fps */
- {
- {0, },
- {9, 958, 782, {0x02, 0xF4, 0x30, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x03, 0x80}},
- {5, 703, 574, {0x02, 0xF4, 0x50, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x02, 0x80}},
- {3, 446, 364, {0x02, 0xF4, 0x90, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x38, 0xBE, 0x01, 0x80}},
- },
- /* 25 fps */
- {
- {0, },
- {9, 958, 654, {0x01, 0xF4, 0x30, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x03, 0x80}},
- {6, 776, 530, {0x01, 0xF4, 0x50, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x03, 0x80}},
- {4, 592, 404, {0x01, 0xF4, 0x70, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x48, 0x50, 0x02, 0x80}},
- },
- /* 30 fps */
- {
- {0, },
- {9, 957, 526, {0x00, 0xF4, 0x50, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x03, 0x80}},
- {6, 775, 426, {0x00, 0xF4, 0x70, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x03, 0x80}},
- {4, 590, 324, {0x00, 0x7A, 0x88, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x50, 0x4E, 0x02, 0x80}},
- },
- },
- /* CIF */
- {
- /* 5 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 10 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 15 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 20 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 25 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 30 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- },
- /* VGA */
- {
- /* 5 fps */
- {
- {0, },
- {6, 773, 1272, {0x25, 0xF4, 0x30, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}},
- {4, 592, 976, {0x25, 0xF4, 0x50, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x02, 0x80}},
- {3, 448, 738, {0x25, 0xF4, 0x90, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x01, 0x80}},
- },
- /* 10 fps */
- {
- {0, },
- {9, 956, 788, {0x24, 0xF4, 0x70, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x03, 0x80}},
- {6, 776, 640, {0x24, 0xF4, 0xB0, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x03, 0x80}},
- {4, 592, 488, {0x24, 0x7A, 0xE8, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x02, 0x80}},
- },
- /* 15 fps */
- {
- {0, },
- {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
- {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
- {8, 895, 492, {0x23, 0x7A, 0xE8, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x03, 0x80}},
- },
- /* 20 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 25 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 30 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- },
-};
-
-
-/*
- * Rom table for kiara chips
- *
- * 32 roms tables (one for each resolution ?)
- * 2 tables per roms (one for each passes) (Y, and U&V)
- * 128 bytes per passes
- */
-
-const unsigned int KiaraRomTable [8][2][16][8] =
-{
- { /* version 0 */
- { /* version 0, passes 0 */
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000001,0x00000001},
- {0x00000000,0x00000000,0x00000009,0x00000009,
- 0x00000009,0x00000009,0x00000009,0x00000009},
- {0x00000000,0x00000000,0x00000009,0x00000049,
- 0x00000049,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000249,0x0000024a,0x00000049},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000249,0x00000249,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00000049,0x00000249,
- 0x00000249,0x0000124a,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00000049,0x00000249,
- 0x0000124a,0x00009252,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00009252,0x00009292,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x00009292,0x00009292,0x00009493,0x000124db},
- {0x00000000,0x00000000,0x00000249,0x0000924a,
- 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
- {0x00000000,0x00000000,0x00001249,0x00009252,
- 0x0000a493,0x000124db,0x000124db,0x000126dc},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x000124db,0x000126dc,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000124db,0x000136e4,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 0, passes 1 */
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000},
- {0x00000000,0x00000000,0x00000001,0x00000009,
- 0x00000009,0x00000009,0x00000009,0x00000001},
- {0x00000000,0x00000000,0x00000009,0x00000009,
- 0x00000049,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000249,0x00000249,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00000049,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x00001252},
- {0x00000000,0x00000000,0x00000049,0x00001249,
- 0x0000124a,0x0000124a,0x00001252,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x00009252,0x00009252,0x00009292,0x00009493},
- {0x00000000,0x00000000,0x00000249,0x0000924a,
- 0x00009292,0x00009292,0x00009292,0x00009493},
- {0x00000000,0x00000000,0x00000249,0x00009292,
- 0x00009492,0x00009493,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x0000a493,0x000124db,0x000126dc,0x000126dc},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x00009252,0x00009493,
- 0x000126dc,0x000126dc,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000136e4,0x000136e4,0x0001b725,0x0001b724},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 1 */
- { /* version 1, passes 0 */
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000001},
- {0x00000000,0x00000000,0x00000009,0x00000009,
- 0x00000009,0x00000009,0x00000009,0x00000009},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000249,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00000049,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x00001252},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x0000124a,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x0000124a,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x0000124a,0x00009252,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x00009252,0x00009292,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x00009252,0x00009292,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00000249,0x0000924a,
- 0x00009252,0x00009493,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00000249,0x0000924a,
- 0x00009292,0x00009493,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00000249,0x00009252,
- 0x00009492,0x00009493,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x000124db,0x000124db,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000126dc,0x000126dc,0x000126dc},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 1, passes 1 */
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000},
- {0x00000000,0x00000000,0x00000049,0x00000009,
- 0x00000049,0x00000009,0x00000001,0x00000000},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000049,0x00000000},
- {0x00000000,0x00000000,0x00000249,0x00000049,
- 0x00000249,0x00000049,0x0000024a,0x00000001},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x00000001},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x00000001},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x00000009},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x0000124a,0x0000024a,0x00000009},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x0000124a,0x0000024a,0x00000009},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x00009252,0x00001252,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x00009292,0x00001252,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x00009292,0x00001252,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00001252,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009292,0x00009292,0x00001252,0x0000024a},
- {0x00000000,0x00000000,0x0000924a,0x0000924a,
- 0x00009492,0x00009493,0x00009292,0x00001252},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 2 */
- { /* version 2, passes 0 */
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x0000124a,0x00001252,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x00009252,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x0000124a,0x00009292,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x00009252,0x00009493,0x00009493,0x0000a49b},
- {0x00000000,0x00000000,0x00000249,0x0000924a,
- 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009292,0x00009493,0x0000a49b,0x000124db},
- {0x00000000,0x00000000,0x00001249,0x00009252,
- 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x000124db,0x000124db,0x000126dc},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x0000a493,0x000124db,0x000126dc,0x000126dc},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x000136e4},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000136e4,0x000136e4,0x0001b724},
- {0x00000000,0x00000000,0x00009252,0x000124db,
- 0x000126dc,0x0001b724,0x0001b725,0x0001b925},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 2, passes 1 */
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00000249,
- 0x0000124a,0x0000124a,0x00001252,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x0000124a,0x00009292,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00009292,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x0000a49b,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009292,0x00009493,0x0000a49b,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009292,0x00009493,0x0000a49b,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009492,0x0000a49b,0x0000a49b,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00009252,
- 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x00009252,0x0000a49b,
- 0x0001249b,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 3 */
- { /* version 3, passes 0 */
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x0000124a,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x000124db,0x000126dc,0x000126dc},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x000126dc},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000126dc,0x000136e4,0x0001b724},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000136e4,0x0001b725,0x0001b724},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000136e4,0x0001b725,0x0001b925},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 3, passes 1 */
- {0x00000000,0x00000000,0x00001249,0x00000249,
- 0x0000124a,0x0000124a,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00009292,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009492,0x00009493,0x0000a49b,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00009252,
- 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x0000a49b,0x000126dc,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00009492,0x0000a49b,
- 0x000136e4,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x0001b724,0x0001b724,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 4 */
- { /* version 4, passes 0 */
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00000249,0x00000049,
- 0x00000249,0x00000249,0x0000024a,0x00000049},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x00009252,0x00001252,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00009493,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009292,0x00009493,0x00009493,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000124db,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0001249b,0x000126dc,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00009252,0x00009493,
- 0x000124db,0x000136e4,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00009252,0x0000a49b,
- 0x000124db,0x000136e4,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x00009492,0x0000a49b,
- 0x000126dc,0x0001b724,0x0001b725,0x0001b724},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 4, passes 1 */
- {0x00000000,0x00000000,0x00000249,0x00000049,
- 0x00000009,0x00000009,0x00000009,0x00000009},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000049,0x00000049,0x00000009,0x00000009},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x00000249,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x0000124a,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x0000124a,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009252,0x0000124a,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x00009252,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x00009292,0x00009292,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x00009292,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x00009493,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00009252,0x000124db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 5 */
- { /* version 5, passes 0 */
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x00000249,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00009292,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x0000a49b,0x000124db,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x0001b724,0x0001b725,0x000136e4},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
- {0x00000000,0x00000000,0x00009492,0x0000a49b,
- 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 5, passes 1 */
- {0x00000000,0x00000000,0x00001249,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x0000124a,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009252,0x00009252,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x0000a49b,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x0000a49b,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x0000a49b,0x00009292,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000124db,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000124db,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000126dc,0x000126dc,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00009292,0x000124db,
- 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00009492,0x000126db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 6 */
- { /* version 6, passes 0 */
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
- {0x00000000,0x00000000,0x00009492,0x0000a49b,
- 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
- {0x00000000,0x00000000,0x00012492,0x000126db,
- 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 6, passes 1 */
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x0000124a,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x00009252,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x00009292,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x0000a49b,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000124db,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000126dc,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00009492,0x000126db,
- 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00009492,0x000126db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00009492,0x000126db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 7 */
- { /* version 7, passes 0 */
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x0000a49b,
- 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x000136e4,0x0001b725,0x000124db},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
- {0x00000000,0x00000000,0x00009292,0x000124db,
- 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
- {0x00000000,0x00000000,0x00012492,0x000136db,
- 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 7, passes 1 */
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x0000124a,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x00009492,0x00009292,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x0000a49b,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000126dc,0x000124db,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000136e4,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000136db,
- 0x0001b724,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000136db,
- 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00009292,0x000136db,
- 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00009492,0x000136db,
- 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00012492,0x0001b6db,
- 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- }
-};
-
diff --git a/drivers/media/video/pwc/pwc-kiara.h b/drivers/media/video/pwc/pwc-kiara.h
deleted file mode 100644
index 8e02b7ac213..00000000000
--- a/drivers/media/video/pwc/pwc-kiara.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Linux driver for Philips webcam
- (C) 2004-2006 Luc Saillard (luc@saillard.org)
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
- The decompression routines have been implemented by reverse-engineering the
- Nemosoft binary pwcx module. Caveat emptor.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-/* Entries for the Kiara (730/740/750) camera */
-
-#ifndef PWC_KIARA_H
-#define PWC_KIARA_H
-
-#include "pwc.h"
-
-#define PWC_FPS_MAX_KIARA 6
-
-struct Kiara_table_entry
-{
- char alternate; /* USB alternate interface */
- unsigned short packetsize; /* Normal packet size */
- unsigned short bandlength; /* Bandlength when decompressing */
- unsigned char mode[12]; /* precomputed mode settings for cam */
-};
-
-extern const struct Kiara_table_entry Kiara_table[PSZ_MAX][PWC_FPS_MAX_KIARA][4];
-extern const unsigned int KiaraRomTable[8][2][16][8];
-extern const unsigned int Kiara_fps_vector[PWC_FPS_MAX_KIARA];
-
-#endif
-
-
diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/video/pwc/pwc-misc.c
deleted file mode 100644
index 9be5adffa87..00000000000
--- a/drivers/media/video/pwc/pwc-misc.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Linux driver for Philips webcam
- Various miscellaneous functions and tables.
- (C) 1999-2003 Nemosoft Unv.
- (C) 2004-2006 Luc Saillard (luc@saillard.org)
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
- The decompression routines have been implemented by reverse-engineering the
- Nemosoft binary pwcx module. Caveat emptor.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-
-#include "pwc.h"
-
-const int pwc_image_sizes[PSZ_MAX][2] =
-{
- { 128, 96 }, /* sqcif */
- { 160, 120 }, /* qsif */
- { 176, 144 }, /* qcif */
- { 320, 240 }, /* sif */
- { 352, 288 }, /* cif */
- { 640, 480 }, /* vga */
-};
-
-/* x,y -> PSZ_ */
-int pwc_get_size(struct pwc_device *pdev, int width, int height)
-{
- int i;
-
- /* Find the largest size supported by the camera that fits into the
- requested size. */
- for (i = PSZ_MAX - 1; i >= 0; i--) {
- if (!(pdev->image_mask & (1 << i)))
- continue;
-
- if (pwc_image_sizes[i][0] <= width &&
- pwc_image_sizes[i][1] <= height)
- return i;
- }
-
- /* No mode found, return the smallest mode we have */
- for (i = 0; i < PSZ_MAX; i++) {
- if (pdev->image_mask & (1 << i))
- return i;
- }
-
- /* Never reached there always is atleast one supported mode */
- return 0;
-}
-
-/* initialize variables depending on type and decompressor */
-void pwc_construct(struct pwc_device *pdev)
-{
- if (DEVICE_USE_CODEC1(pdev->type)) {
-
- pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
- pdev->vcinterface = 2;
- pdev->vendpoint = 4;
- pdev->frame_header_size = 0;
- pdev->frame_trailer_size = 0;
-
- } else if (DEVICE_USE_CODEC3(pdev->type)) {
-
- pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
- pdev->vcinterface = 3;
- pdev->vendpoint = 5;
- pdev->frame_header_size = TOUCAM_HEADER_SIZE;
- pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE;
-
- } else /* if (DEVICE_USE_CODEC2(pdev->type)) */ {
-
- pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
- pdev->vcinterface = 3;
- pdev->vendpoint = 4;
- pdev->frame_header_size = 0;
- pdev->frame_trailer_size = 0;
- }
-}
diff --git a/drivers/media/video/pwc/pwc-nala.h b/drivers/media/video/pwc/pwc-nala.h
deleted file mode 100644
index 168c73ef75d..00000000000
--- a/drivers/media/video/pwc/pwc-nala.h
+++ /dev/null
@@ -1,66 +0,0 @@
- /* SQCIF */
- {
- {0, 0, {0x04, 0x01, 0x03}},
- {8, 0, {0x05, 0x01, 0x03}},
- {7, 0, {0x08, 0x01, 0x03}},
- {7, 0, {0x0A, 0x01, 0x03}},
- {6, 0, {0x0C, 0x01, 0x03}},
- {5, 0, {0x0F, 0x01, 0x03}},
- {4, 0, {0x14, 0x01, 0x03}},
- {3, 0, {0x18, 0x01, 0x03}},
- },
- /* QSIF */
- {
- {0},
- {0},
- {0},
- {0},
- {0},
- {0},
- {0},
- {0},
- },
- /* QCIF */
- {
- {0, 0, {0x04, 0x01, 0x02}},
- {8, 0, {0x05, 0x01, 0x02}},
- {7, 0, {0x08, 0x01, 0x02}},
- {6, 0, {0x0A, 0x01, 0x02}},
- {5, 0, {0x0C, 0x01, 0x02}},
- {4, 0, {0x0F, 0x01, 0x02}},
- {1, 0, {0x14, 0x01, 0x02}},
- {1, 0, {0x18, 0x01, 0x02}},
- },
- /* SIF */
- {
- {0},
- {0},
- {0},
- {0},
- {0},
- {0},
- {0},
- {0},
- },
- /* CIF */
- {
- {4, 0, {0x04, 0x01, 0x01}},
- {7, 1, {0x05, 0x03, 0x01}},
- {6, 1, {0x08, 0x03, 0x01}},
- {4, 1, {0x0A, 0x03, 0x01}},
- {3, 1, {0x0C, 0x03, 0x01}},
- {2, 1, {0x0F, 0x03, 0x01}},
- {0},
- {0},
- },
- /* VGA */
- {
- {0},
- {0},
- {0},
- {0},
- {0},
- {0},
- {0},
- {0},
- },
diff --git a/drivers/media/video/pwc/pwc-timon.c b/drivers/media/video/pwc/pwc-timon.c
deleted file mode 100644
index c56c174b161..00000000000
--- a/drivers/media/video/pwc/pwc-timon.c
+++ /dev/null
@@ -1,1448 +0,0 @@
-/* Linux driver for Philips webcam
- (C) 2004-2006 Luc Saillard (luc@saillard.org)
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
- The decompression routines have been implemented by reverse-engineering the
- Nemosoft binary pwcx module. Caveat emptor.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-
-/* This tables contains entries for the 675/680/690 (Timon) camera, with
- 4 different qualities (no compression, low, medium, high).
- It lists the bandwidth requirements for said mode by its alternate interface
- number. An alternate of 0 means that the mode is unavailable.
-
- There are 6 * 4 * 4 entries:
- 6 different resolutions subqcif, qsif, qcif, sif, cif, vga
- 6 framerates: 5, 10, 15, 20, 25, 30
- 4 compression modi: none, low, medium, high
-
- When an uncompressed mode is not available, the next available compressed mode
- will be chosen (unless the decompressor is absent). Sometimes there are only
- 1 or 2 compressed modes available; in that case entries are duplicated.
-*/
-
-#include "pwc-timon.h"
-
-const unsigned int Timon_fps_vector[PWC_FPS_MAX_TIMON] = { 5, 10, 15, 20, 25, 30 };
-
-const struct Timon_table_entry Timon_table[PSZ_MAX][PWC_FPS_MAX_TIMON][4] =
-{
- /* SQCIF */
- {
- /* 5 fps */
- {
- {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
- {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
- {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
- {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
- },
- /* 10 fps */
- {
- {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
- {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
- {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
- {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
- },
- /* 15 fps */
- {
- {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
- {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
- {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
- {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
- },
- /* 20 fps */
- {
- {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
- {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
- {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
- {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
- },
- /* 25 fps */
- {
- {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
- {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
- {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
- {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
- },
- /* 30 fps */
- {
- {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
- {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
- {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
- {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
- },
- },
- /* QSIF */
- {
- /* 5 fps */
- {
- {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
- {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
- {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
- {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
- },
- /* 10 fps */
- {
- {2, 291, 0, {0x2C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0xA1, 0xC0, 0x02}},
- {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
- {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
- {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
- },
- /* 15 fps */
- {
- {3, 437, 0, {0x2B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x6D, 0xC0, 0x02}},
- {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
- {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
- {1, 191, 420, {0x2B, 0xF4, 0x0D, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
- },
- /* 20 fps */
- {
- {4, 588, 0, {0x2A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4C, 0x52, 0xC0, 0x02}},
- {3, 447, 730, {0x2A, 0xF4, 0x05, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
- {2, 292, 476, {0x2A, 0xF4, 0x0D, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
- {1, 192, 312, {0x2A, 0xF4, 0x1D, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}},
- },
- /* 25 fps */
- {
- {5, 703, 0, {0x29, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x42, 0xC0, 0x02}},
- {3, 447, 610, {0x29, 0xF4, 0x05, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
- {2, 292, 398, {0x29, 0xF4, 0x0D, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
- {1, 192, 262, {0x29, 0xF4, 0x25, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}},
- },
- /* 30 fps */
- {
- {8, 873, 0, {0x28, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x69, 0x37, 0xC0, 0x02}},
- {5, 704, 774, {0x28, 0xF4, 0x05, 0x18, 0x21, 0x17, 0x59, 0x0F, 0x18, 0xC0, 0x42, 0xC0, 0x02}},
- {3, 448, 492, {0x28, 0xF4, 0x05, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x18, 0xC0, 0x69, 0xC0, 0x02}},
- {2, 291, 320, {0x28, 0xF4, 0x1D, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}},
- },
- },
- /* QCIF */
- {
- /* 5 fps */
- {
- {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
- {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
- {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
- {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
- },
- /* 10 fps */
- {
- {3, 385, 0, {0x0C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x81, 0x79, 0xC0, 0x02}},
- {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
- {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
- {1, 194, 532, {0x0C, 0xF4, 0x05, 0x10, 0x9A, 0x0F, 0xBE, 0x1B, 0x08, 0xC2, 0xF0, 0xC0, 0x02}},
- },
- /* 15 fps */
- {
- {4, 577, 0, {0x0B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x41, 0x52, 0xC0, 0x02}},
- {3, 447, 818, {0x0B, 0xF4, 0x05, 0x19, 0x89, 0x18, 0xAD, 0x0F, 0x10, 0xBF, 0x69, 0xC0, 0x02}},
- {2, 292, 534, {0x0B, 0xF4, 0x05, 0x10, 0xA3, 0x0F, 0xC7, 0x19, 0x10, 0x24, 0xA1, 0xC0, 0x02}},
- {1, 195, 356, {0x0B, 0xF4, 0x15, 0x0B, 0x11, 0x0A, 0x35, 0x1E, 0x10, 0xC3, 0xF0, 0xC0, 0x02}},
- },
- /* 20 fps */
- {
- {6, 776, 0, {0x0A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x08, 0x3F, 0xC0, 0x02}},
- {4, 591, 804, {0x0A, 0xF4, 0x05, 0x19, 0x1E, 0x18, 0x42, 0x0F, 0x18, 0x4F, 0x4E, 0xC0, 0x02}},
- {3, 447, 608, {0x0A, 0xF4, 0x05, 0x12, 0xFD, 0x12, 0x21, 0x15, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
- {2, 291, 396, {0x0A, 0xF4, 0x15, 0x0C, 0x5E, 0x0B, 0x82, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}},
- },
- /* 25 fps */
- {
- {9, 928, 0, {0x09, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xA0, 0x33, 0xC0, 0x02}},
- {5, 703, 800, {0x09, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x10, 0x18, 0xBF, 0x42, 0xC0, 0x02}},
- {3, 447, 508, {0x09, 0xF4, 0x0D, 0x0F, 0xD2, 0x0E, 0xF6, 0x1B, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
- {2, 292, 332, {0x09, 0xF4, 0x1D, 0x0A, 0x5A, 0x09, 0x7E, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
- },
- /* 30 fps */
- {
- {0, },
- {9, 956, 876, {0x08, 0xF4, 0x05, 0x1B, 0x58, 0x1A, 0x7C, 0x0E, 0x20, 0xBC, 0x33, 0x10, 0x02}},
- {4, 592, 542, {0x08, 0xF4, 0x05, 0x10, 0xE4, 0x10, 0x08, 0x17, 0x20, 0x50, 0x4E, 0x10, 0x02}},
- {2, 291, 266, {0x08, 0xF4, 0x25, 0x08, 0x48, 0x07, 0x6C, 0x1E, 0x20, 0x23, 0xA1, 0x10, 0x02}},
- },
- },
- /* SIF */
- {
- /* 5 fps */
- {
- {4, 582, 0, {0x35, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x52, 0x60, 0x02}},
- {3, 387, 1276, {0x35, 0xF4, 0x05, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x79, 0x60, 0x02}},
- {2, 291, 960, {0x35, 0xF4, 0x0D, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0xA1, 0x60, 0x02}},
- {1, 191, 630, {0x35, 0xF4, 0x1D, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x08, 0xBF, 0xF4, 0x60, 0x02}},
- },
- /* 10 fps */
- {
- {0, },
- {6, 775, 1278, {0x34, 0xF4, 0x05, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x3F, 0x10, 0x02}},
- {3, 447, 736, {0x34, 0xF4, 0x15, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x18, 0xBF, 0x69, 0x10, 0x02}},
- {2, 291, 480, {0x34, 0xF4, 0x2D, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x18, 0x23, 0xA1, 0x10, 0x02}},
- },
- /* 15 fps */
- {
- {0, },
- {9, 955, 1050, {0x33, 0xF4, 0x05, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x33, 0x10, 0x02}},
- {4, 591, 650, {0x33, 0xF4, 0x15, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x4F, 0x4E, 0x10, 0x02}},
- {3, 448, 492, {0x33, 0xF4, 0x25, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x28, 0xC0, 0x69, 0x10, 0x02}},
- },
- /* 20 fps */
- {
- {0, },
- {9, 958, 782, {0x32, 0xF4, 0x0D, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x33, 0xD0, 0x02}},
- {5, 703, 574, {0x32, 0xF4, 0x1D, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x42, 0xD0, 0x02}},
- {3, 446, 364, {0x32, 0xF4, 0x3D, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x30, 0xBE, 0x69, 0xD0, 0x02}},
- },
- /* 25 fps */
- {
- {0, },
- {9, 958, 654, {0x31, 0xF4, 0x15, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x33, 0x90, 0x02}},
- {6, 776, 530, {0x31, 0xF4, 0x25, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x3F, 0x90, 0x02}},
- {4, 592, 404, {0x31, 0xF4, 0x35, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x38, 0x50, 0x4E, 0x90, 0x02}},
- },
- /* 30 fps */
- {
- {0, },
- {9, 957, 526, {0x30, 0xF4, 0x25, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x33, 0x60, 0x02}},
- {6, 775, 426, {0x30, 0xF4, 0x35, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x3F, 0x60, 0x02}},
- {4, 590, 324, {0x30, 0x7A, 0x4B, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x40, 0x4E, 0x52, 0x60, 0x02}},
- },
- },
- /* CIF */
- {
- /* 5 fps */
- {
- {6, 771, 0, {0x15, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x3F, 0x80, 0x02}},
- {4, 465, 1278, {0x15, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x03, 0x18, 0xD1, 0x65, 0x80, 0x02}},
- {2, 291, 800, {0x15, 0xF4, 0x15, 0x18, 0xF4, 0x17, 0x3C, 0x05, 0x18, 0x23, 0xA1, 0x80, 0x02}},
- {1, 193, 528, {0x15, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x18, 0xC1, 0xF4, 0x80, 0x02}},
- },
- /* 10 fps */
- {
- {0, },
- {9, 932, 1278, {0x14, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x04, 0x30, 0xA4, 0x33, 0x10, 0x02}},
- {4, 591, 812, {0x14, 0xF4, 0x15, 0x19, 0x56, 0x17, 0x9E, 0x06, 0x28, 0x4F, 0x4E, 0x10, 0x02}},
- {2, 291, 400, {0x14, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x28, 0x23, 0xA1, 0x10, 0x02}},
- },
- /* 15 fps */
- {
- {0, },
- {9, 956, 876, {0x13, 0xF4, 0x0D, 0x1B, 0x58, 0x19, 0xA0, 0x05, 0x38, 0xBC, 0x33, 0x60, 0x02}},
- {5, 703, 644, {0x13, 0xF4, 0x1D, 0x14, 0x1C, 0x12, 0x64, 0x08, 0x38, 0xBF, 0x42, 0x60, 0x02}},
- {3, 448, 410, {0x13, 0xF4, 0x3D, 0x0C, 0xC4, 0x0B, 0x0C, 0x0E, 0x38, 0xC0, 0x69, 0x60, 0x02}},
- },
- /* 20 fps */
- {
- {0, },
- {9, 956, 650, {0x12, 0xF4, 0x1D, 0x14, 0x4A, 0x12, 0x92, 0x09, 0x48, 0xBC, 0x33, 0x10, 0x03}},
- {6, 776, 528, {0x12, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x40, 0x08, 0x3F, 0x10, 0x03}},
- {4, 591, 402, {0x12, 0xF4, 0x3D, 0x0C, 0x8F, 0x0A, 0xD7, 0x0E, 0x40, 0x4F, 0x4E, 0x10, 0x03}},
- },
- /* 25 fps */
- {
- {0, },
- {9, 956, 544, {0x11, 0xF4, 0x25, 0x10, 0xF4, 0x0F, 0x3C, 0x0A, 0x48, 0xBC, 0x33, 0xC0, 0x02}},
- {7, 840, 478, {0x11, 0xF4, 0x2D, 0x0E, 0xEB, 0x0D, 0x33, 0x0B, 0x48, 0x48, 0x3B, 0xC0, 0x02}},
- {5, 703, 400, {0x11, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x48, 0xBF, 0x42, 0xC0, 0x02}},
- },
- /* 30 fps */
- {
- {0, },
- {9, 956, 438, {0x10, 0xF4, 0x35, 0x0D, 0xAC, 0x0B, 0xF4, 0x0D, 0x50, 0xBC, 0x33, 0x10, 0x02}},
- {7, 838, 384, {0x10, 0xF4, 0x45, 0x0B, 0xFD, 0x0A, 0x45, 0x0F, 0x50, 0x46, 0x3B, 0x10, 0x02}},
- {6, 773, 354, {0x10, 0x7A, 0x4B, 0x0B, 0x0C, 0x09, 0x80, 0x10, 0x50, 0x05, 0x3F, 0x10, 0x02}},
- },
- },
- /* VGA */
- {
- /* 5 fps */
- {
- {0, },
- {6, 773, 1272, {0x1D, 0xF4, 0x15, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x3F, 0x10, 0x02}},
- {4, 592, 976, {0x1D, 0xF4, 0x25, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x4E, 0x10, 0x02}},
- {3, 448, 738, {0x1D, 0xF4, 0x3D, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x69, 0x10, 0x02}},
- },
- /* 10 fps */
- {
- {0, },
- {9, 956, 788, {0x1C, 0xF4, 0x35, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x33, 0x10, 0x02}},
- {6, 776, 640, {0x1C, 0x7A, 0x53, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x3F, 0x10, 0x02}},
- {4, 592, 488, {0x1C, 0x7A, 0x6B, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x4E, 0x10, 0x02}},
- },
- /* 15 fps */
- {
- {0, },
- {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}},
- {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}},
- {8, 895, 492, {0x1B, 0x7A, 0x6B, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x37, 0x80, 0x02}},
- },
- /* 20 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 25 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- /* 30 fps */
- {
- {0, },
- {0, },
- {0, },
- {0, },
- },
- },
-};
-
-/*
- * 16 versions:
- * 2 tables (one for Y, and one for U&V)
- * 16 levels of details per tables
- * 8 blocs
- */
-
-const unsigned int TimonRomTable [16][2][16][8] =
-{
- { /* version 0 */
- { /* version 0, passes 0 */
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000001},
- {0x00000000,0x00000000,0x00000001,0x00000001,
- 0x00000001,0x00000001,0x00000001,0x00000001},
- {0x00000000,0x00000000,0x00000001,0x00000001,
- 0x00000001,0x00000009,0x00000009,0x00000009},
- {0x00000000,0x00000000,0x00000009,0x00000001,
- 0x00000009,0x00000009,0x00000009,0x00000009},
- {0x00000000,0x00000000,0x00000009,0x00000009,
- 0x00000009,0x00000009,0x00000049,0x00000009},
- {0x00000000,0x00000000,0x00000009,0x00000009,
- 0x00000009,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00000009,0x00000009,
- 0x00000049,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00000009,0x00000049,
- 0x00000049,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000249,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000249,0x00000249,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000249,0x00000249,0x00001252,0x0000024a},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000249,0x0000124a,0x00001252,0x0000024a},
- {0x00000000,0x00000000,0x00000049,0x00000249,
- 0x00000249,0x0000124a,0x00001252,0x0000024a},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x0000124a,0x00009252,0x00009292,0x00001252},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 0, passes 1 */
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000},
- {0x00000000,0x00000000,0x00000001,0x00000001,
- 0x00000001,0x00000001,0x00000000,0x00000000},
- {0x00000000,0x00000000,0x00000009,0x00000001,
- 0x00000001,0x00000009,0x00000000,0x00000000},
- {0x00000000,0x00000000,0x00000009,0x00000009,
- 0x00000009,0x00000009,0x00000000,0x00000000},
- {0x00000000,0x00000000,0x00000009,0x00000009,
- 0x00000009,0x00000009,0x00000001,0x00000000},
- {0x00000000,0x00000000,0x00000049,0x00000009,
- 0x00000009,0x00000049,0x00000001,0x00000001},
- {0x00000000,0x00000000,0x00000049,0x00000009,
- 0x00000009,0x00000049,0x00000001,0x00000001},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000009,0x00000001},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000009,0x00000001},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000009,0x00000001},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000009,0x00000009},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000249,0x00000049,0x00000009},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000249,0x00000049,0x00000009},
- {0x00000000,0x00000000,0x00000249,0x00000049,
- 0x00000249,0x00000249,0x00000049,0x00000009},
- {0x00000000,0x00000000,0x00001249,0x00000249,
- 0x0000124a,0x0000124a,0x0000024a,0x00000049},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 1 */
- { /* version 1, passes 0 */
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000001},
- {0x00000000,0x00000000,0x00000001,0x00000001,
- 0x00000001,0x00000009,0x00000009,0x00000009},
- {0x00000000,0x00000000,0x00000009,0x00000009,
- 0x00000009,0x00000009,0x00000009,0x00000009},
- {0x00000000,0x00000000,0x00000009,0x00000009,
- 0x00000009,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00000009,0x00000049,
- 0x00000049,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000249,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000249,0x00000249,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00000049,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x00001252},
- {0x00000000,0x00000000,0x00000049,0x00000249,
- 0x00000249,0x0000124a,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x00000049,0x00000249,
- 0x0000124a,0x0000124a,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x0000124a,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x0000124a,0x00009252,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x00009252,0x00009252,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x0000924a,
- 0x00009292,0x00009493,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x00009252,
- 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 1, passes 1 */
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000},
- {0x00000000,0x00000000,0x00000009,0x00000009,
- 0x00000009,0x00000001,0x00000001,0x00000000},
- {0x00000000,0x00000000,0x00000009,0x00000009,
- 0x00000009,0x00000009,0x00000001,0x00000000},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000009,0x00000001,0x00000000},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000001,0x00000001},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000009,0x00000001},
- {0x00000000,0x00000000,0x00000249,0x00000049,
- 0x00000049,0x00000249,0x00000009,0x00000001},
- {0x00000000,0x00000000,0x00000249,0x00000049,
- 0x00000249,0x00000249,0x00000009,0x00000009},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x00000249,0x00000049,0x00000009},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x0000124a,0x00000049,0x00000009},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x0000124a,0x00000049,0x00000009},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x0000124a,0x0000024a,0x00000049},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x0000124a,0x0000024a,0x00000049},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x0000124a,0x0000024a,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009252,0x00001252,0x0000024a},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 2 */
- { /* version 2, passes 0 */
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000001},
- {0x00000000,0x00000000,0x00000009,0x00000009,
- 0x00000009,0x00000009,0x00000009,0x00000009},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000249,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00000049,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x00001252},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x0000124a,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x0000124a,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x0000124a,0x00009252,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x00009252,0x00009292,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x00009252,0x00009292,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00000249,0x0000924a,
- 0x00009252,0x00009493,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00000249,0x0000924a,
- 0x00009292,0x00009493,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00000249,0x00009252,
- 0x00009492,0x00009493,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x000124db,0x000124db,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000126dc,0x000126dc,0x000126dc},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 2, passes 1 */
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000},
- {0x00000000,0x00000000,0x00000049,0x00000009,
- 0x00000049,0x00000009,0x00000001,0x00000000},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000049,0x00000000},
- {0x00000000,0x00000000,0x00000249,0x00000049,
- 0x00000249,0x00000049,0x0000024a,0x00000001},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x00000001},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x00000001},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x00000009},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x0000124a,0x0000024a,0x00000009},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x0000124a,0x0000024a,0x00000009},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x00009252,0x00001252,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x00009292,0x00001252,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x00009292,0x00001252,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00001252,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009292,0x00009292,0x00001252,0x0000024a},
- {0x00000000,0x00000000,0x0000924a,0x0000924a,
- 0x00009492,0x00009493,0x00009292,0x00001252},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 3 */
- { /* version 3, passes 0 */
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000001},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00000049,0x00000249,
- 0x00000249,0x00000249,0x00001252,0x0000024a},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x0000124a,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x00009252,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x0000124a,0x00009292,0x00009292,0x00009493},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x00009252,0x00009292,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x00009292,0x00009493,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00000249,0x00009252,
- 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00001249,0x00009252,
- 0x00009292,0x0000a49b,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00001249,0x00009252,
- 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x0000a49b,0x000124db,0x000124db},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x0000a493,0x0000a49b,0x000124db,0x000124db},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0001249b,0x000126dc,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000136e4,0x0001b725,0x000136e4},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 3, passes 1 */
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000},
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000001,0x00000000},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x00000249,0x00000049,0x00000001},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x0000124a,0x00001252,0x00000001},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x0000124a,0x00001252,0x00000009},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x0000124a,0x00009252,0x00009292,0x00000009},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x00009252,0x00009292,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009252,0x00009292,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009493,0x00009292,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009493,0x00009292,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009493,0x00009493,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009292,0x00009493,0x00009493,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009492,0x00009493,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009252,
- 0x00009492,0x0000a49b,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x00009292,
- 0x0000a493,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 4 */
- { /* version 4, passes 0 */
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x0000124a,0x00001252,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x00009252,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x0000124a,0x00009292,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x00009252,0x00009493,0x00009493,0x0000a49b},
- {0x00000000,0x00000000,0x00000249,0x0000924a,
- 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009292,0x00009493,0x0000a49b,0x000124db},
- {0x00000000,0x00000000,0x00001249,0x00009252,
- 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x000124db,0x000124db,0x000126dc},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x0000a493,0x000124db,0x000126dc,0x000126dc},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x000136e4},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000136e4,0x000136e4,0x0001b724},
- {0x00000000,0x00000000,0x00009252,0x000124db,
- 0x000126dc,0x0001b724,0x0001b725,0x0001b925},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 4, passes 1 */
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00000249,
- 0x0000124a,0x0000124a,0x00001252,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x0000124a,0x00009292,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00009292,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x0000a49b,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009292,0x00009493,0x0000a49b,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009292,0x00009493,0x0000a49b,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009492,0x0000a49b,0x0000a49b,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00009252,
- 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x00009252,0x0000a49b,
- 0x0001249b,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 5 */
- { /* version 5, passes 0 */
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x0000124a,0x00001252,0x00009292},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x0000124a,0x00009292,0x00009292,0x00009493},
- {0x00000000,0x00000000,0x00000249,0x0000924a,
- 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x0000a49b,0x000124db,0x000124db},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x0000a493,0x000124db,0x000124db,0x000126dc},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x000126dc},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0001249b,0x000126dc,0x0001b725,0x0001b724},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000126dc,0x0001b725,0x0001b724},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b724,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 5, passes 1 */
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x00000249,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x0000124a,0x00001252,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009292,0x00009493,0x00009493,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009292,0x00009493,0x00009493,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009292,0x00009493,0x0000a49b,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009492,0x00009493,0x000124db,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x00009493,0x000124db,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x0000a49b,0x000124db,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x0000a49b,0x000124db,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000124db,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x000124db,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x000124db,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00009252,0x000124db,
- 0x000126dc,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 6 */
- { /* version 6, passes 0 */
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x0000124a,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x000124db,0x000126dc,0x000126dc},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x000126dc},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000126dc,0x000136e4,0x0001b724},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000136e4,0x0001b725,0x0001b724},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000136e4,0x0001b725,0x0001b925},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 6, passes 1 */
- {0x00000000,0x00000000,0x00001249,0x00000249,
- 0x0000124a,0x0000124a,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00009292,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009492,0x00009493,0x0000a49b,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00009252,
- 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x0000a49b,0x000126dc,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00009492,0x0000a49b,
- 0x000136e4,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x0001b724,0x0001b724,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 7 */
- { /* version 7, passes 0 */
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009292,0x00009493,0x0000a49b,0x000124db},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x0000a493,0x0000a49b,0x000124db,0x000126dc},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x000136e4},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x00001249,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000136e4,0x0001b725,0x0001b724},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x000136e4,0x0001b725,0x0001b925},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x00009292,0x000124db,
- 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b724,0x0001c96e,0x0002496e},
- {0x00000000,0x00000000,0x00009492,0x000126db,
- 0x000136e4,0x0001b925,0x0001c96e,0x0002496e},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b724,0x0002496d,0x00025bb6,0x00025bbf},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 7, passes 1 */
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009492,0x00009493,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x0000a49b,0x000124db,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x000124db,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x000124db,0x000136e4,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x000124db,0x000136e4,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000124db,0x000136e4,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x000136e4,0x000136e4,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x000136e4,0x000136e4,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000136e4,0x000136e4,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x000136e4,0x0001b724,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00012492,0x000126db,
- 0x0001b724,0x0001b925,0x0001b725,0x000136e4},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 8 */
- { /* version 8, passes 0 */
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009292,0x00009493,0x0000a49b,0x000124db},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x0000a493,0x000124db,0x000126dc,0x000126dc},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x000136e4},
- {0x00000000,0x00000000,0x00001249,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000136e4,0x0001b725,0x0001b724},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x000136e4,0x0001b725,0x0001b925},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
- {0x00000000,0x00000000,0x00009252,0x000124db,
- 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
- {0x00000000,0x00000000,0x00009292,0x000124db,
- 0x000126dc,0x0001b925,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b925,0x00024b76,0x00024b77},
- {0x00000000,0x00000000,0x00009492,0x000126db,
- 0x000136e4,0x0001b925,0x00024b76,0x00025bbf},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x000136e4,0x0001c92d,0x00024b76,0x00025bbf},
- {0x00000000,0x00000000,0x00012492,0x000136db,
- 0x0001b724,0x00024b6d,0x0002ddb6,0x0002efff},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 8, passes 1 */
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009493,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x0000a49b,0x000124db,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x000124db,0x000136e4,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x000126dc,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x00009292,0x000124db,
- 0x000136e4,0x0001b724,0x0001b725,0x000136e4},
- {0x00000000,0x00000000,0x00009492,0x000126db,
- 0x000136e4,0x0001b925,0x0001b725,0x0001b724},
- {0x00000000,0x00000000,0x00009492,0x000126db,
- 0x000136e4,0x0001b925,0x0001b725,0x0001b724},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b724,0x0002496d,0x0001b92d,0x0001b925},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 9 */
- { /* version 9, passes 0 */
- {0x00000000,0x00000000,0x00000049,0x00000049,
- 0x00000049,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00000249,0x00000049,
- 0x00000249,0x00000249,0x0000024a,0x00000049},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x0000124a,0x00009252,0x00001252,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00009493,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009292,0x00009493,0x00009493,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000124db,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0001249b,0x000126dc,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00009252,0x00009493,
- 0x000124db,0x000136e4,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00009252,0x0000a49b,
- 0x000124db,0x000136e4,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x00009492,0x0000a49b,
- 0x000126dc,0x0001b724,0x0001b725,0x0001b724},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 9, passes 1 */
- {0x00000000,0x00000000,0x00000249,0x00000049,
- 0x00000009,0x00000009,0x00000009,0x00000009},
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000049,0x00000049,0x00000009,0x00000009},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x00000249,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x0000124a,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x0000124a,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009252,0x0000124a,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x00009252,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x00009292,0x00009292,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x00009292,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x00009493,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00009252,0x000124db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 10 */
- { /* version 10, passes 0 */
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00000249,0x00001249,
- 0x00009252,0x00009292,0x00009292,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00009292,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009492,0x00009493,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x000124db,0x000124db,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000124db,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0001249b,0x000126dc,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000126dc,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00009252,0x0000a49b,
- 0x000124db,0x000136e4,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x00009492,0x0000a49b,
- 0x000126dc,0x0001b724,0x0001b92d,0x0001b724},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000126dc,0x0001b925,0x0001b92d,0x0001b925},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x000136e4,0x0002496d,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 10, passes 1 */
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000049,0x00000049,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x00000249,0x00000049,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x00009252,0x0000024a,0x00000049},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009493,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00009252,
- 0x00009492,0x00009493,0x00001252,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x00009493,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x00009492,0x00009493,0x00009292,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x00009493,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x0000a49b,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x0000a49b,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00009252,0x000126db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 11 */
- { /* version 11, passes 0 */
- {0x00000000,0x00000000,0x00000249,0x00000249,
- 0x00000249,0x00000249,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00009292,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x0000a49b,0x000124db,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x0001b724,0x0001b725,0x000136e4},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
- {0x00000000,0x00000000,0x00009492,0x0000a49b,
- 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 11, passes 1 */
- {0x00000000,0x00000000,0x00001249,0x00000249,
- 0x00000249,0x00000249,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x0000124a,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009252,0x00009252,0x0000024a,0x0000024a},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x0000a49b,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x0000a49b,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x0000a49b,0x00009292,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000124db,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000124db,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000126dc,0x000126dc,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00009292,0x000124db,
- 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00009492,0x000126db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 12 */
- { /* version 12, passes 0 */
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
- {0x00000000,0x00000000,0x00009492,0x0000a49b,
- 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
- {0x00000000,0x00000000,0x00012492,0x000126db,
- 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 12, passes 1 */
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x0000124a,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x00001249,0x00009292,
- 0x00009492,0x00009252,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x00009292,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x0000a49b,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000124db,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000124db,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000126dc,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00009492,0x000126db,
- 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00009492,0x000126db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00009492,0x000126db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 13 */
- { /* version 13, passes 0 */
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x00009252,0x00009292,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x000124db,0x000126dc,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x0000a49b,
- 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x000136e4,0x0001b725,0x000124db},
- {0x00000000,0x00000000,0x00009292,0x0000a49b,
- 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
- {0x00000000,0x00000000,0x00009292,0x000124db,
- 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
- {0x00000000,0x00000000,0x00012492,0x000136db,
- 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 13, passes 1 */
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x0000124a,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x00009492,0x00009292,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x0000a49b,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000126dc,0x000124db,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000136e4,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000136db,
- 0x0001b724,0x000124db,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000136db,
- 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00009292,0x000136db,
- 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x00009492,0x000136db,
- 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00012492,0x0001b6db,
- 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 14 */
- { /* version 14, passes 0 */
- {0x00000000,0x00000000,0x00001249,0x0000924a,
- 0x00009292,0x00009493,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00001249,0x0000a49b,
- 0x0000a493,0x000124db,0x000126dc,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000126dc,0x000136e4,0x0001b725,0x000124db},
- {0x00000000,0x00000000,0x00009292,0x000124db,
- 0x000126dc,0x0001b724,0x0001b92d,0x000126dc},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b724,0x0001b92d,0x000126dc},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001c92d,0x0001c96e,0x000136e4},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x0001b724,0x0001c92d,0x00024b76,0x0001b925},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b924,0x0002496d,0x00024b76,0x00024b77},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b924,0x00024b6d,0x0002ddb6,0x00025bbf},
- {0x00000000,0x00000000,0x00012492,0x0001b6db,
- 0x00024924,0x0002db6d,0x00036db6,0x0002efff},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 14, passes 1 */
- {0x00000000,0x00000000,0x00001249,0x00001249,
- 0x0000124a,0x0000124a,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x00009493,
- 0x0000a493,0x00009292,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x0000a49b,0x00001252,0x00001252},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000136e4,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000136e4,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000136e4,0x000136e4,0x00009493,0x00009292},
- {0x00000000,0x00000000,0x00009492,0x000136db,
- 0x0001b724,0x000136e4,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x00009492,0x000136db,
- 0x0001b724,0x000136e4,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x00009492,0x000136db,
- 0x0001b724,0x000136e4,0x0000a49b,0x00009493},
- {0x00000000,0x00000000,0x00009492,0x000136db,
- 0x0001b724,0x000136e4,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b724,0x000136e4,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b724,0x000136e4,0x000124db,0x0000a49b},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b724,0x000136e4,0x000126dc,0x000124db},
- {0x00000000,0x00000000,0x00012492,0x0001b6db,
- 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- },
- { /* version 15 */
- { /* version 15, passes 0 */
- {0x00000000,0x00000000,0x00001249,0x00009493,
- 0x0000a493,0x0000a49b,0x000124db,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0001249b,0x000126dc,0x000136e4,0x000124db},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000136e4,0x0001b724,0x0001b92d,0x000126dc},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x000136e4,0x0001b925,0x0001c96e,0x000136e4},
- {0x00000000,0x00000000,0x00009492,0x000124db,
- 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
- {0x00000000,0x00000000,0x0000a492,0x000124db,
- 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
- {0x00000000,0x00000000,0x0000a492,0x000126db,
- 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001b924,0x0002496d,0x00024b76,0x0002496e},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001c924,0x00024b6d,0x00025bb6,0x00024b77},
- {0x00000000,0x00000000,0x00012492,0x000136db,
- 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
- {0x00000000,0x00000000,0x00012492,0x0001b6db,
- 0x00024924,0x0002db6d,0x00036db6,0x0002efff},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- },
- { /* version 15, passes 1 */
- {0x00000000,0x00000000,0x0000924a,0x0000924a,
- 0x00009292,0x00009292,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x0000a49b,
- 0x0000a493,0x000124db,0x00009292,0x00009292},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000124db,0x0001b724,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000126dc,0x0001b724,0x00009493,0x00009493},
- {0x00000000,0x00000000,0x0000924a,0x000124db,
- 0x000136e4,0x0001b724,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00009292,0x000136db,
- 0x0001b724,0x0001b724,0x0000a49b,0x0000a49b},
- {0x00000000,0x00000000,0x00009492,0x000136db,
- 0x0001c924,0x0001b724,0x000124db,0x000124db},
- {0x00000000,0x00000000,0x00009492,0x000136db,
- 0x0001c924,0x0001b724,0x000124db,0x000124db},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001c924,0x0001b724,0x000126dc,0x000126dc},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001c924,0x0001b925,0x000126dc,0x000126dc},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001c924,0x0001b925,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001c924,0x0001b925,0x000136e4,0x000136e4},
- {0x00000000,0x00000000,0x0000a492,0x000136db,
- 0x0001c924,0x0001b925,0x0001b725,0x0001b724},
- {0x00000000,0x00000000,0x00012492,0x000136db,
- 0x0001c924,0x0001b925,0x0001b725,0x0001b724},
- {0x00000000,0x00000000,0x00012492,0x0001b6db,
- 0x00024924,0x0002496d,0x0001b92d,0x0001b925},
- {0x00000000,0x00000000,0x00000000,0x00000000,
- 0x00000000,0x00000000,0x00000000,0x00000000}
- }
- }
-};
diff --git a/drivers/media/video/pwc/pwc-timon.h b/drivers/media/video/pwc/pwc-timon.h
deleted file mode 100644
index 270c5b9010f..00000000000
--- a/drivers/media/video/pwc/pwc-timon.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Linux driver for Philips webcam
- (C) 2004-2006 Luc Saillard (luc@saillard.org)
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
- The decompression routines have been implemented by reverse-engineering the
- Nemosoft binary pwcx module. Caveat emptor.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-
-
-/* This tables contains entries for the 675/680/690 (Timon) camera, with
- 4 different qualities (no compression, low, medium, high).
- It lists the bandwidth requirements for said mode by its alternate interface
- number. An alternate of 0 means that the mode is unavailable.
-
- There are 6 * 4 * 4 entries:
- 6 different resolutions subqcif, qsif, qcif, sif, cif, vga
- 6 framerates: 5, 10, 15, 20, 25, 30
- 4 compression modi: none, low, medium, high
-
- When an uncompressed mode is not available, the next available compressed mode
- will be chosen (unless the decompressor is absent). Sometimes there are only
- 1 or 2 compressed modes available; in that case entries are duplicated.
-*/
-
-#ifndef PWC_TIMON_H
-#define PWC_TIMON_H
-
-#include "pwc.h"
-
-#define PWC_FPS_MAX_TIMON 6
-
-struct Timon_table_entry
-{
- char alternate; /* USB alternate interface */
- unsigned short packetsize; /* Normal packet size */
- unsigned short bandlength; /* Bandlength when decompressing */
- unsigned char mode[13]; /* precomputed mode settings for cam */
-};
-
-extern const struct Timon_table_entry Timon_table[PSZ_MAX][PWC_FPS_MAX_TIMON][4];
-extern const unsigned int TimonRomTable [16][2][16][8];
-extern const unsigned int Timon_fps_vector[PWC_FPS_MAX_TIMON];
-
-#endif
-
-
diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/video/pwc/pwc-uncompress.c
deleted file mode 100644
index b65903fbcf0..00000000000
--- a/drivers/media/video/pwc/pwc-uncompress.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* Linux driver for Philips webcam
- Decompression frontend.
- (C) 1999-2003 Nemosoft Unv.
- (C) 2004-2006 Luc Saillard (luc@saillard.org)
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
- The decompression routines have been implemented by reverse-engineering the
- Nemosoft binary pwcx module. Caveat emptor.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- vim: set ts=8:
-*/
-
-#include <asm/current.h>
-#include <asm/types.h>
-
-#include "pwc.h"
-#include "pwc-dec1.h"
-#include "pwc-dec23.h"
-
-int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf)
-{
- int n, line, col;
- void *yuv, *image;
- u16 *src;
- u16 *dsty, *dstu, *dstv;
-
- image = vb2_plane_vaddr(&fbuf->vb, 0);
-
- yuv = fbuf->data + pdev->frame_header_size; /* Skip header */
-
- /* Raw format; that's easy... */
- if (pdev->pixfmt != V4L2_PIX_FMT_YUV420)
- {
- struct pwc_raw_frame *raw_frame = image;
- raw_frame->type = cpu_to_le16(pdev->type);
- raw_frame->vbandlength = cpu_to_le16(pdev->vbandlength);
- /* cmd_buf is always 4 bytes, but sometimes, only the
- * first 3 bytes is filled (Nala case). We can
- * determine this using the type of the webcam */
- memcpy(raw_frame->cmd, pdev->cmd_buf, 4);
- memcpy(raw_frame+1, yuv, pdev->frame_size);
- vb2_set_plane_payload(&fbuf->vb, 0,
- pdev->frame_size + sizeof(struct pwc_raw_frame));
- return 0;
- }
-
- vb2_set_plane_payload(&fbuf->vb, 0,
- pdev->width * pdev->height * 3 / 2);
-
- if (pdev->vbandlength == 0) {
- /* Uncompressed mode.
- *
- * We do some byte shuffling here to go from the
- * native format to YUV420P.
- */
- src = (u16 *)yuv;
- n = pdev->width * pdev->height;
- dsty = (u16 *)(image);
- dstu = (u16 *)(image + n);
- dstv = (u16 *)(image + n + n / 4);
-
- for (line = 0; line < pdev->height; line++) {
- for (col = 0; col < pdev->width; col += 4) {
- *dsty++ = *src++;
- *dsty++ = *src++;
- if (line & 1)
- *dstv++ = *src++;
- else
- *dstu++ = *src++;
- }
- }
-
- return 0;
- }
-
- /*
- * Compressed;
- * the decompressor routines will write the data in planar format
- * immediately.
- */
- if (DEVICE_USE_CODEC1(pdev->type)) {
-
- /* TODO & FIXME */
- PWC_ERROR("This chipset is not supported for now\n");
- return -ENXIO; /* No such device or address: missing decompressor */
-
- } else {
- pwc_dec23_decompress(pdev, yuv, image);
- }
- return 0;
-}
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
deleted file mode 100644
index 545e9bbdeed..00000000000
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ /dev/null
@@ -1,1053 +0,0 @@
-/* Linux driver for Philips webcam
- USB and Video4Linux interface part.
- (C) 1999-2004 Nemosoft Unv.
- (C) 2004-2006 Luc Saillard (luc@saillard.org)
- (C) 2011 Hans de Goede <hdegoede@redhat.com>
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
- The decompression routines have been implemented by reverse-engineering the
- Nemosoft binary pwcx module. Caveat emptor.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*/
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/poll.h>
-#include <linux/vmalloc.h>
-#include <linux/jiffies.h>
-#include <asm/io.h>
-
-#include "pwc.h"
-
-#define PWC_CID_CUSTOM(ctrl) ((V4L2_CID_USER_BASE | 0xf000) + custom_ ## ctrl)
-
-static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl);
-static int pwc_s_ctrl(struct v4l2_ctrl *ctrl);
-
-static const struct v4l2_ctrl_ops pwc_ctrl_ops = {
- .g_volatile_ctrl = pwc_g_volatile_ctrl,
- .s_ctrl = pwc_s_ctrl,
-};
-
-enum { awb_indoor, awb_outdoor, awb_fl, awb_manual, awb_auto };
-enum { custom_autocontour, custom_contour, custom_noise_reduction,
- custom_awb_speed, custom_awb_delay,
- custom_save_user, custom_restore_user, custom_restore_factory };
-
-const char * const pwc_auto_whitebal_qmenu[] = {
- "Indoor (Incandescant Lighting) Mode",
- "Outdoor (Sunlight) Mode",
- "Indoor (Fluorescent Lighting) Mode",
- "Manual Mode",
- "Auto Mode",
- NULL
-};
-
-static const struct v4l2_ctrl_config pwc_auto_white_balance_cfg = {
- .ops = &pwc_ctrl_ops,
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_MENU,
- .max = awb_auto,
- .qmenu = pwc_auto_whitebal_qmenu,
-};
-
-static const struct v4l2_ctrl_config pwc_autocontour_cfg = {
- .ops = &pwc_ctrl_ops,
- .id = PWC_CID_CUSTOM(autocontour),
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Auto contour",
- .min = 0,
- .max = 1,
- .step = 1,
-};
-
-static const struct v4l2_ctrl_config pwc_contour_cfg = {
- .ops = &pwc_ctrl_ops,
- .id = PWC_CID_CUSTOM(contour),
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contour",
- .flags = V4L2_CTRL_FLAG_SLIDER,
- .min = 0,
- .max = 63,
- .step = 1,
-};
-
-static const struct v4l2_ctrl_config pwc_backlight_cfg = {
- .ops = &pwc_ctrl_ops,
- .id = V4L2_CID_BACKLIGHT_COMPENSATION,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .min = 0,
- .max = 1,
- .step = 1,
-};
-
-static const struct v4l2_ctrl_config pwc_flicker_cfg = {
- .ops = &pwc_ctrl_ops,
- .id = V4L2_CID_BAND_STOP_FILTER,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .min = 0,
- .max = 1,
- .step = 1,
-};
-
-static const struct v4l2_ctrl_config pwc_noise_reduction_cfg = {
- .ops = &pwc_ctrl_ops,
- .id = PWC_CID_CUSTOM(noise_reduction),
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Dynamic Noise Reduction",
- .min = 0,
- .max = 3,
- .step = 1,
-};
-
-static const struct v4l2_ctrl_config pwc_save_user_cfg = {
- .ops = &pwc_ctrl_ops,
- .id = PWC_CID_CUSTOM(save_user),
- .type = V4L2_CTRL_TYPE_BUTTON,
- .name = "Save User Settings",
-};
-
-static const struct v4l2_ctrl_config pwc_restore_user_cfg = {
- .ops = &pwc_ctrl_ops,
- .id = PWC_CID_CUSTOM(restore_user),
- .type = V4L2_CTRL_TYPE_BUTTON,
- .name = "Restore User Settings",
-};
-
-static const struct v4l2_ctrl_config pwc_restore_factory_cfg = {
- .ops = &pwc_ctrl_ops,
- .id = PWC_CID_CUSTOM(restore_factory),
- .type = V4L2_CTRL_TYPE_BUTTON,
- .name = "Restore Factory Settings",
-};
-
-static const struct v4l2_ctrl_config pwc_awb_speed_cfg = {
- .ops = &pwc_ctrl_ops,
- .id = PWC_CID_CUSTOM(awb_speed),
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Auto White Balance Speed",
- .min = 1,
- .max = 32,
- .step = 1,
-};
-
-static const struct v4l2_ctrl_config pwc_awb_delay_cfg = {
- .ops = &pwc_ctrl_ops,
- .id = PWC_CID_CUSTOM(awb_delay),
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Auto White Balance Delay",
- .min = 0,
- .max = 63,
- .step = 1,
-};
-
-int pwc_init_controls(struct pwc_device *pdev)
-{
- struct v4l2_ctrl_handler *hdl;
- struct v4l2_ctrl_config cfg;
- int r, def;
-
- hdl = &pdev->ctrl_handler;
- r = v4l2_ctrl_handler_init(hdl, 20);
- if (r)
- return r;
-
- /* Brightness, contrast, saturation, gamma */
- r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, BRIGHTNESS_FORMATTER, &def);
- if (r || def > 127)
- def = 63;
- pdev->brightness = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 127, 1, def);
-
- r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, CONTRAST_FORMATTER, &def);
- if (r || def > 63)
- def = 31;
- pdev->contrast = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 63, 1, def);
-
- if (pdev->type >= 675) {
- if (pdev->type < 730)
- pdev->saturation_fmt = SATURATION_MODE_FORMATTER2;
- else
- pdev->saturation_fmt = SATURATION_MODE_FORMATTER1;
- r = pwc_get_s8_ctrl(pdev, GET_CHROM_CTL, pdev->saturation_fmt,
- &def);
- if (r || def < -100 || def > 100)
- def = 0;
- pdev->saturation = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
- V4L2_CID_SATURATION, -100, 100, 1, def);
- }
-
- r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, GAMMA_FORMATTER, &def);
- if (r || def > 31)
- def = 15;
- pdev->gamma = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
- V4L2_CID_GAMMA, 0, 31, 1, def);
-
- /* auto white balance, red gain, blue gain */
- r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL, WB_MODE_FORMATTER, &def);
- if (r || def > awb_auto)
- def = awb_auto;
- cfg = pwc_auto_white_balance_cfg;
- cfg.name = v4l2_ctrl_get_name(cfg.id);
- cfg.def = def;
- pdev->auto_white_balance = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
- /* check auto controls to avoid NULL deref in v4l2_ctrl_auto_cluster */
- if (!pdev->auto_white_balance)
- return hdl->error;
-
- r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL,
- PRESET_MANUAL_RED_GAIN_FORMATTER, &def);
- if (r)
- def = 127;
- pdev->red_balance = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
- V4L2_CID_RED_BALANCE, 0, 255, 1, def);
-
- r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL,
- PRESET_MANUAL_BLUE_GAIN_FORMATTER, &def);
- if (r)
- def = 127;
- pdev->blue_balance = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
- V4L2_CID_BLUE_BALANCE, 0, 255, 1, def);
-
- v4l2_ctrl_auto_cluster(3, &pdev->auto_white_balance, awb_manual, true);
-
- /* autogain, gain */
- r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, AGC_MODE_FORMATTER, &def);
- if (r || (def != 0 && def != 0xff))
- def = 0;
- /* Note a register value if 0 means auto gain is on */
- pdev->autogain = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, def == 0);
- if (!pdev->autogain)
- return hdl->error;
-
- r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, PRESET_AGC_FORMATTER, &def);
- if (r || def > 63)
- def = 31;
- pdev->gain = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
- V4L2_CID_GAIN, 0, 63, 1, def);
-
- /* auto exposure, exposure */
- if (DEVICE_USE_CODEC2(pdev->type)) {
- r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, SHUTTER_MODE_FORMATTER,
- &def);
- if (r || (def != 0 && def != 0xff))
- def = 0;
- /*
- * def = 0 auto, def = ff manual
- * menu idx 0 = auto, idx 1 = manual
- */
- pdev->exposure_auto = v4l2_ctrl_new_std_menu(hdl,
- &pwc_ctrl_ops,
- V4L2_CID_EXPOSURE_AUTO,
- 1, 0, def != 0);
- if (!pdev->exposure_auto)
- return hdl->error;
-
- /* GET_LUM_CTL, PRESET_SHUTTER_FORMATTER is unreliable */
- r = pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
- READ_SHUTTER_FORMATTER, &def);
- if (r || def > 655)
- def = 655;
- pdev->exposure = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 655, 1, def);
- /* CODEC2: separate auto gain & auto exposure */
- v4l2_ctrl_auto_cluster(2, &pdev->autogain, 0, true);
- v4l2_ctrl_auto_cluster(2, &pdev->exposure_auto,
- V4L2_EXPOSURE_MANUAL, true);
- } else if (DEVICE_USE_CODEC3(pdev->type)) {
- /* GET_LUM_CTL, PRESET_SHUTTER_FORMATTER is unreliable */
- r = pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
- READ_SHUTTER_FORMATTER, &def);
- if (r || def > 255)
- def = 255;
- pdev->exposure = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 255, 1, def);
- /* CODEC3: both gain and exposure controlled by autogain */
- pdev->autogain_expo_cluster[0] = pdev->autogain;
- pdev->autogain_expo_cluster[1] = pdev->gain;
- pdev->autogain_expo_cluster[2] = pdev->exposure;
- v4l2_ctrl_auto_cluster(3, pdev->autogain_expo_cluster,
- 0, true);
- }
-
- /* color / bw setting */
- r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL, COLOUR_MODE_FORMATTER,
- &def);
- if (r || (def != 0 && def != 0xff))
- def = 0xff;
- /* def = 0 bw, def = ff color, menu idx 0 = color, idx 1 = bw */
- pdev->colorfx = v4l2_ctrl_new_std_menu(hdl, &pwc_ctrl_ops,
- V4L2_CID_COLORFX, 1, 0, def == 0);
-
- /* autocontour, contour */
- r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &def);
- if (r || (def != 0 && def != 0xff))
- def = 0;
- cfg = pwc_autocontour_cfg;
- cfg.def = def == 0;
- pdev->autocontour = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
- if (!pdev->autocontour)
- return hdl->error;
-
- r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, &def);
- if (r || def > 63)
- def = 31;
- cfg = pwc_contour_cfg;
- cfg.def = def;
- pdev->contour = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
-
- v4l2_ctrl_auto_cluster(2, &pdev->autocontour, 0, false);
-
- /* backlight */
- r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL,
- BACK_LIGHT_COMPENSATION_FORMATTER, &def);
- if (r || (def != 0 && def != 0xff))
- def = 0;
- cfg = pwc_backlight_cfg;
- cfg.name = v4l2_ctrl_get_name(cfg.id);
- cfg.def = def == 0;
- pdev->backlight = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
-
- /* flikker rediction */
- r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL,
- FLICKERLESS_MODE_FORMATTER, &def);
- if (r || (def != 0 && def != 0xff))
- def = 0;
- cfg = pwc_flicker_cfg;
- cfg.name = v4l2_ctrl_get_name(cfg.id);
- cfg.def = def == 0;
- pdev->flicker = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
-
- /* Dynamic noise reduction */
- r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL,
- DYNAMIC_NOISE_CONTROL_FORMATTER, &def);
- if (r || def > 3)
- def = 2;
- cfg = pwc_noise_reduction_cfg;
- cfg.def = def;
- pdev->noise_reduction = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
-
- /* Save / Restore User / Factory Settings */
- pdev->save_user = v4l2_ctrl_new_custom(hdl, &pwc_save_user_cfg, NULL);
- pdev->restore_user = v4l2_ctrl_new_custom(hdl, &pwc_restore_user_cfg,
- NULL);
- if (pdev->restore_user)
- pdev->restore_user->flags |= V4L2_CTRL_FLAG_UPDATE;
- pdev->restore_factory = v4l2_ctrl_new_custom(hdl,
- &pwc_restore_factory_cfg,
- NULL);
- if (pdev->restore_factory)
- pdev->restore_factory->flags |= V4L2_CTRL_FLAG_UPDATE;
-
- /* Auto White Balance speed & delay */
- r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL,
- AWB_CONTROL_SPEED_FORMATTER, &def);
- if (r || def < 1 || def > 32)
- def = 1;
- cfg = pwc_awb_speed_cfg;
- cfg.def = def;
- pdev->awb_speed = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
-
- r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL,
- AWB_CONTROL_DELAY_FORMATTER, &def);
- if (r || def > 63)
- def = 0;
- cfg = pwc_awb_delay_cfg;
- cfg.def = def;
- pdev->awb_delay = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
-
- if (!(pdev->features & FEATURE_MOTOR_PANTILT))
- return hdl->error;
-
- /* Motor pan / tilt / reset */
- pdev->motor_pan = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
- V4L2_CID_PAN_RELATIVE, -4480, 4480, 64, 0);
- if (!pdev->motor_pan)
- return hdl->error;
- pdev->motor_tilt = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
- V4L2_CID_TILT_RELATIVE, -1920, 1920, 64, 0);
- pdev->motor_pan_reset = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
- V4L2_CID_PAN_RESET, 0, 0, 0, 0);
- pdev->motor_tilt_reset = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
- V4L2_CID_TILT_RESET, 0, 0, 0, 0);
- v4l2_ctrl_cluster(4, &pdev->motor_pan);
-
- return hdl->error;
-}
-
-static void pwc_vidioc_fill_fmt(struct v4l2_format *f,
- int width, int height, u32 pixfmt)
-{
- memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
- f->fmt.pix.width = width;
- f->fmt.pix.height = height;
- f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.pixelformat = pixfmt;
- f->fmt.pix.bytesperline = f->fmt.pix.width;
- f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.width * 3 / 2;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
- PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() "
- "width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n",
- f->fmt.pix.width,
- f->fmt.pix.height,
- f->fmt.pix.bytesperline,
- f->fmt.pix.sizeimage,
- (f->fmt.pix.pixelformat)&255,
- (f->fmt.pix.pixelformat>>8)&255,
- (f->fmt.pix.pixelformat>>16)&255,
- (f->fmt.pix.pixelformat>>24)&255);
-}
-
-/* ioctl(VIDIOC_TRY_FMT) */
-static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f)
-{
- int size;
-
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- PWC_DEBUG_IOCTL("Bad video type must be V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
- return -EINVAL;
- }
-
- switch (f->fmt.pix.pixelformat) {
- case V4L2_PIX_FMT_YUV420:
- break;
- case V4L2_PIX_FMT_PWC1:
- if (DEVICE_USE_CODEC23(pdev->type)) {
- PWC_DEBUG_IOCTL("codec1 is only supported for old pwc webcam\n");
- return -EINVAL;
- }
- break;
- case V4L2_PIX_FMT_PWC2:
- if (DEVICE_USE_CODEC1(pdev->type)) {
- PWC_DEBUG_IOCTL("codec23 is only supported for new pwc webcam\n");
- return -EINVAL;
- }
- break;
- default:
- PWC_DEBUG_IOCTL("Unsupported pixel format\n");
- return -EINVAL;
-
- }
-
- size = pwc_get_size(pdev, f->fmt.pix.width, f->fmt.pix.height);
- pwc_vidioc_fill_fmt(f,
- pwc_image_sizes[size][0],
- pwc_image_sizes[size][1],
- f->fmt.pix.pixelformat);
-
- return 0;
-}
-
-/* ioctl(VIDIOC_SET_FMT) */
-
-static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
-{
- struct pwc_device *pdev = video_drvdata(file);
- int ret, pixelformat, compression = 0;
-
- ret = pwc_vidioc_try_fmt(pdev, f);
- if (ret < 0)
- return ret;
-
- if (vb2_is_busy(&pdev->vb_queue))
- return -EBUSY;
-
- pixelformat = f->fmt.pix.pixelformat;
-
- PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d "
- "format=%c%c%c%c\n",
- f->fmt.pix.width, f->fmt.pix.height, pdev->vframes,
- (pixelformat)&255,
- (pixelformat>>8)&255,
- (pixelformat>>16)&255,
- (pixelformat>>24)&255);
-
- ret = pwc_set_video_mode(pdev, f->fmt.pix.width, f->fmt.pix.height,
- pixelformat, 30, &compression, 0);
-
- PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret);
-
- pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt);
- return ret;
-}
-
-static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
-{
- struct pwc_device *pdev = video_drvdata(file);
-
- strcpy(cap->driver, PWC_NAME);
- strlcpy(cap->card, pdev->vdev.name, sizeof(cap->card));
- usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info));
- cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
- V4L2_CAP_READWRITE;
- cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
- return 0;
-}
-
-static int pwc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
-{
- if (i->index) /* Only one INPUT is supported */
- return -EINVAL;
-
- strlcpy(i->name, "Camera", sizeof(i->name));
- i->type = V4L2_INPUT_TYPE_CAMERA;
- return 0;
-}
-
-static int pwc_g_input(struct file *file, void *fh, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int pwc_s_input(struct file *file, void *fh, unsigned int i)
-{
- return i ? -EINVAL : 0;
-}
-
-static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct pwc_device *pdev =
- container_of(ctrl->handler, struct pwc_device, ctrl_handler);
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTO_WHITE_BALANCE:
- if (pdev->color_bal_valid &&
- (pdev->auto_white_balance->val != awb_auto ||
- time_before(jiffies,
- pdev->last_color_bal_update + HZ / 4))) {
- pdev->red_balance->val = pdev->last_red_balance;
- pdev->blue_balance->val = pdev->last_blue_balance;
- break;
- }
- ret = pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
- READ_RED_GAIN_FORMATTER,
- &pdev->red_balance->val);
- if (ret)
- break;
- ret = pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
- READ_BLUE_GAIN_FORMATTER,
- &pdev->blue_balance->val);
- if (ret)
- break;
- pdev->last_red_balance = pdev->red_balance->val;
- pdev->last_blue_balance = pdev->blue_balance->val;
- pdev->last_color_bal_update = jiffies;
- pdev->color_bal_valid = true;
- break;
- case V4L2_CID_AUTOGAIN:
- if (pdev->gain_valid && time_before(jiffies,
- pdev->last_gain_update + HZ / 4)) {
- pdev->gain->val = pdev->last_gain;
- break;
- }
- ret = pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
- READ_AGC_FORMATTER, &pdev->gain->val);
- if (ret)
- break;
- pdev->last_gain = pdev->gain->val;
- pdev->last_gain_update = jiffies;
- pdev->gain_valid = true;
- if (!DEVICE_USE_CODEC3(pdev->type))
- break;
- /* Fall through for CODEC3 where autogain also controls expo */
- case V4L2_CID_EXPOSURE_AUTO:
- if (pdev->exposure_valid && time_before(jiffies,
- pdev->last_exposure_update + HZ / 4)) {
- pdev->exposure->val = pdev->last_exposure;
- break;
- }
- ret = pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
- READ_SHUTTER_FORMATTER,
- &pdev->exposure->val);
- if (ret)
- break;
- pdev->last_exposure = pdev->exposure->val;
- pdev->last_exposure_update = jiffies;
- pdev->exposure_valid = true;
- break;
- default:
- ret = -EINVAL;
- }
-
- if (ret)
- PWC_ERROR("g_ctrl %s error %d\n", ctrl->name, ret);
-
- return ret;
-}
-
-static int pwc_set_awb(struct pwc_device *pdev)
-{
- int ret;
-
- if (pdev->auto_white_balance->is_new) {
- ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
- WB_MODE_FORMATTER,
- pdev->auto_white_balance->val);
- if (ret)
- return ret;
-
- if (pdev->auto_white_balance->val != awb_manual)
- pdev->color_bal_valid = false; /* Force cache update */
-
- /*
- * If this is a preset, update our red / blue balance values
- * so that events get generated for the new preset values
- */
- if (pdev->auto_white_balance->val == awb_indoor ||
- pdev->auto_white_balance->val == awb_outdoor ||
- pdev->auto_white_balance->val == awb_fl)
- pwc_g_volatile_ctrl(pdev->auto_white_balance);
- }
- if (pdev->auto_white_balance->val != awb_manual)
- return 0;
-
- if (pdev->red_balance->is_new) {
- ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
- PRESET_MANUAL_RED_GAIN_FORMATTER,
- pdev->red_balance->val);
- if (ret)
- return ret;
- }
-
- if (pdev->blue_balance->is_new) {
- ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
- PRESET_MANUAL_BLUE_GAIN_FORMATTER,
- pdev->blue_balance->val);
- if (ret)
- return ret;
- }
- return 0;
-}
-
-/* For CODEC2 models which have separate autogain and auto exposure */
-static int pwc_set_autogain(struct pwc_device *pdev)
-{
- int ret;
-
- if (pdev->autogain->is_new) {
- ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
- AGC_MODE_FORMATTER,
- pdev->autogain->val ? 0 : 0xff);
- if (ret)
- return ret;
-
- if (pdev->autogain->val)
- pdev->gain_valid = false; /* Force cache update */
- }
-
- if (pdev->autogain->val)
- return 0;
-
- if (pdev->gain->is_new) {
- ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
- PRESET_AGC_FORMATTER,
- pdev->gain->val);
- if (ret)
- return ret;
- }
- return 0;
-}
-
-/* For CODEC2 models which have separate autogain and auto exposure */
-static int pwc_set_exposure_auto(struct pwc_device *pdev)
-{
- int ret;
- int is_auto = pdev->exposure_auto->val == V4L2_EXPOSURE_AUTO;
-
- if (pdev->exposure_auto->is_new) {
- ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
- SHUTTER_MODE_FORMATTER,
- is_auto ? 0 : 0xff);
- if (ret)
- return ret;
-
- if (is_auto)
- pdev->exposure_valid = false; /* Force cache update */
- }
-
- if (is_auto)
- return 0;
-
- if (pdev->exposure->is_new) {
- ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL,
- PRESET_SHUTTER_FORMATTER,
- pdev->exposure->val);
- if (ret)
- return ret;
- }
- return 0;
-}
-
-/* For CODEC3 models which have autogain controlling both gain and exposure */
-static int pwc_set_autogain_expo(struct pwc_device *pdev)
-{
- int ret;
-
- if (pdev->autogain->is_new) {
- ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
- AGC_MODE_FORMATTER,
- pdev->autogain->val ? 0 : 0xff);
- if (ret)
- return ret;
-
- if (pdev->autogain->val) {
- pdev->gain_valid = false; /* Force cache update */
- pdev->exposure_valid = false; /* Force cache update */
- }
- }
-
- if (pdev->autogain->val)
- return 0;
-
- if (pdev->gain->is_new) {
- ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
- PRESET_AGC_FORMATTER,
- pdev->gain->val);
- if (ret)
- return ret;
- }
-
- if (pdev->exposure->is_new) {
- ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL,
- PRESET_SHUTTER_FORMATTER,
- pdev->exposure->val);
- if (ret)
- return ret;
- }
- return 0;
-}
-
-static int pwc_set_motor(struct pwc_device *pdev)
-{
- int ret;
-
- pdev->ctrl_buf[0] = 0;
- if (pdev->motor_pan_reset->is_new)
- pdev->ctrl_buf[0] |= 0x01;
- if (pdev->motor_tilt_reset->is_new)
- pdev->ctrl_buf[0] |= 0x02;
- if (pdev->motor_pan_reset->is_new || pdev->motor_tilt_reset->is_new) {
- ret = send_control_msg(pdev, SET_MPT_CTL,
- PT_RESET_CONTROL_FORMATTER,
- pdev->ctrl_buf, 1);
- if (ret < 0)
- return ret;
- }
-
- memset(pdev->ctrl_buf, 0, 4);
- if (pdev->motor_pan->is_new) {
- pdev->ctrl_buf[0] = pdev->motor_pan->val & 0xFF;
- pdev->ctrl_buf[1] = (pdev->motor_pan->val >> 8);
- }
- if (pdev->motor_tilt->is_new) {
- pdev->ctrl_buf[2] = pdev->motor_tilt->val & 0xFF;
- pdev->ctrl_buf[3] = (pdev->motor_tilt->val >> 8);
- }
- if (pdev->motor_pan->is_new || pdev->motor_tilt->is_new) {
- ret = send_control_msg(pdev, SET_MPT_CTL,
- PT_RELATIVE_CONTROL_FORMATTER,
- pdev->ctrl_buf, 4);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-static int pwc_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct pwc_device *pdev =
- container_of(ctrl->handler, struct pwc_device, ctrl_handler);
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
- BRIGHTNESS_FORMATTER, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
- CONTRAST_FORMATTER, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- ret = pwc_set_s8_ctrl(pdev, SET_CHROM_CTL,
- pdev->saturation_fmt, ctrl->val);
- break;
- case V4L2_CID_GAMMA:
- ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
- GAMMA_FORMATTER, ctrl->val);
- break;
- case V4L2_CID_AUTO_WHITE_BALANCE:
- ret = pwc_set_awb(pdev);
- break;
- case V4L2_CID_AUTOGAIN:
- if (DEVICE_USE_CODEC2(pdev->type))
- ret = pwc_set_autogain(pdev);
- else if (DEVICE_USE_CODEC3(pdev->type))
- ret = pwc_set_autogain_expo(pdev);
- else
- ret = -EINVAL;
- break;
- case V4L2_CID_EXPOSURE_AUTO:
- if (DEVICE_USE_CODEC2(pdev->type))
- ret = pwc_set_exposure_auto(pdev);
- else
- ret = -EINVAL;
- break;
- case V4L2_CID_COLORFX:
- ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
- COLOUR_MODE_FORMATTER,
- ctrl->val ? 0 : 0xff);
- break;
- case PWC_CID_CUSTOM(autocontour):
- if (pdev->autocontour->is_new) {
- ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
- AUTO_CONTOUR_FORMATTER,
- pdev->autocontour->val ? 0 : 0xff);
- }
- if (ret == 0 && pdev->contour->is_new) {
- ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
- PRESET_CONTOUR_FORMATTER,
- pdev->contour->val);
- }
- break;
- case V4L2_CID_BACKLIGHT_COMPENSATION:
- ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
- BACK_LIGHT_COMPENSATION_FORMATTER,
- ctrl->val ? 0 : 0xff);
- break;
- case V4L2_CID_BAND_STOP_FILTER:
- ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
- FLICKERLESS_MODE_FORMATTER,
- ctrl->val ? 0 : 0xff);
- break;
- case PWC_CID_CUSTOM(noise_reduction):
- ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
- DYNAMIC_NOISE_CONTROL_FORMATTER,
- ctrl->val);
- break;
- case PWC_CID_CUSTOM(save_user):
- ret = pwc_button_ctrl(pdev, SAVE_USER_DEFAULTS_FORMATTER);
- break;
- case PWC_CID_CUSTOM(restore_user):
- ret = pwc_button_ctrl(pdev, RESTORE_USER_DEFAULTS_FORMATTER);
- break;
- case PWC_CID_CUSTOM(restore_factory):
- ret = pwc_button_ctrl(pdev,
- RESTORE_FACTORY_DEFAULTS_FORMATTER);
- break;
- case PWC_CID_CUSTOM(awb_speed):
- ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
- AWB_CONTROL_SPEED_FORMATTER,
- ctrl->val);
- break;
- case PWC_CID_CUSTOM(awb_delay):
- ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
- AWB_CONTROL_DELAY_FORMATTER,
- ctrl->val);
- break;
- case V4L2_CID_PAN_RELATIVE:
- ret = pwc_set_motor(pdev);
- break;
- default:
- ret = -EINVAL;
- }
-
- if (ret)
- PWC_ERROR("s_ctrl %s error %d\n", ctrl->name, ret);
-
- return ret;
-}
-
-static int pwc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
-{
- struct pwc_device *pdev = video_drvdata(file);
-
- /* We only support two format: the raw format, and YUV */
- switch (f->index) {
- case 0:
- /* RAW format */
- f->pixelformat = pdev->type <= 646 ? V4L2_PIX_FMT_PWC1 : V4L2_PIX_FMT_PWC2;
- f->flags = V4L2_FMT_FLAG_COMPRESSED;
- strlcpy(f->description, "Raw Philips Webcam", sizeof(f->description));
- break;
- case 1:
- f->pixelformat = V4L2_PIX_FMT_YUV420;
- strlcpy(f->description, "4:2:0, planar, Y-Cb-Cr", sizeof(f->description));
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int pwc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
-{
- struct pwc_device *pdev = video_drvdata(file);
-
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",
- pdev->width, pdev->height);
- pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt);
- return 0;
-}
-
-static int pwc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
-{
- struct pwc_device *pdev = video_drvdata(file);
-
- return pwc_vidioc_try_fmt(pdev, f);
-}
-
-static int pwc_enum_framesizes(struct file *file, void *fh,
- struct v4l2_frmsizeenum *fsize)
-{
- struct pwc_device *pdev = video_drvdata(file);
- unsigned int i = 0, index = fsize->index;
-
- if (fsize->pixel_format == V4L2_PIX_FMT_YUV420 ||
- (fsize->pixel_format == V4L2_PIX_FMT_PWC1 &&
- DEVICE_USE_CODEC1(pdev->type)) ||
- (fsize->pixel_format == V4L2_PIX_FMT_PWC2 &&
- DEVICE_USE_CODEC23(pdev->type))) {
- for (i = 0; i < PSZ_MAX; i++) {
- if (!(pdev->image_mask & (1UL << i)))
- continue;
- if (!index--) {
- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fsize->discrete.width = pwc_image_sizes[i][0];
- fsize->discrete.height = pwc_image_sizes[i][1];
- return 0;
- }
- }
- }
- return -EINVAL;
-}
-
-static int pwc_enum_frameintervals(struct file *file, void *fh,
- struct v4l2_frmivalenum *fival)
-{
- struct pwc_device *pdev = video_drvdata(file);
- int size = -1;
- unsigned int i;
-
- for (i = 0; i < PSZ_MAX; i++) {
- if (pwc_image_sizes[i][0] == fival->width &&
- pwc_image_sizes[i][1] == fival->height) {
- size = i;
- break;
- }
- }
-
- /* TODO: Support raw format */
- if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420)
- return -EINVAL;
-
- i = pwc_get_fps(pdev, fival->index, size);
- if (!i)
- return -EINVAL;
-
- fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
- fival->discrete.numerator = 1;
- fival->discrete.denominator = i;
-
- return 0;
-}
-
-static int pwc_g_parm(struct file *file, void *fh,
- struct v4l2_streamparm *parm)
-{
- struct pwc_device *pdev = video_drvdata(file);
-
- if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- memset(parm, 0, sizeof(*parm));
-
- parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- parm->parm.capture.readbuffers = MIN_FRAMES;
- parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
- parm->parm.capture.timeperframe.denominator = pdev->vframes;
- parm->parm.capture.timeperframe.numerator = 1;
-
- return 0;
-}
-
-static int pwc_s_parm(struct file *file, void *fh,
- struct v4l2_streamparm *parm)
-{
- struct pwc_device *pdev = video_drvdata(file);
- int compression = 0;
- int ret, fps;
-
- if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- /* If timeperframe == 0, then reset the framerate to the nominal value.
- We pick a high framerate here, and let pwc_set_video_mode() figure
- out the best match. */
- if (parm->parm.capture.timeperframe.numerator == 0 ||
- parm->parm.capture.timeperframe.denominator == 0)
- fps = 30;
- else
- fps = parm->parm.capture.timeperframe.denominator /
- parm->parm.capture.timeperframe.numerator;
-
- if (vb2_is_busy(&pdev->vb_queue))
- return -EBUSY;
-
- ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt,
- fps, &compression, 0);
-
- pwc_g_parm(file, fh, parm);
-
- return ret;
-}
-
-const struct v4l2_ioctl_ops pwc_ioctl_ops = {
- .vidioc_querycap = pwc_querycap,
- .vidioc_enum_input = pwc_enum_input,
- .vidioc_g_input = pwc_g_input,
- .vidioc_s_input = pwc_s_input,
- .vidioc_enum_fmt_vid_cap = pwc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = pwc_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = pwc_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = pwc_try_fmt_vid_cap,
- .vidioc_reqbufs = vb2_ioctl_reqbufs,
- .vidioc_querybuf = vb2_ioctl_querybuf,
- .vidioc_qbuf = vb2_ioctl_qbuf,
- .vidioc_dqbuf = vb2_ioctl_dqbuf,
- .vidioc_streamon = vb2_ioctl_streamon,
- .vidioc_streamoff = vb2_ioctl_streamoff,
- .vidioc_log_status = v4l2_ctrl_log_status,
- .vidioc_enum_framesizes = pwc_enum_framesizes,
- .vidioc_enum_frameintervals = pwc_enum_frameintervals,
- .vidioc_g_parm = pwc_g_parm,
- .vidioc_s_parm = pwc_s_parm,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
deleted file mode 100644
index 7a6a0d39c2c..00000000000
--- a/drivers/media/video/pwc/pwc.h
+++ /dev/null
@@ -1,393 +0,0 @@
-/* (C) 1999-2003 Nemosoft Unv.
- (C) 2004-2006 Luc Saillard (luc@saillard.org)
-
- NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
- driver and thus may have bugs that are not present in the original version.
- Please send bug reports and support requests to <luc@saillard.org>.
- The decompression routines have been implemented by reverse-engineering the
- Nemosoft binary pwcx module. Caveat emptor.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#ifndef PWC_H
-#define PWC_H
-
-#include <linux/module.h>
-#include <linux/usb.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <linux/mutex.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <asm/errno.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-#include <media/videobuf2-vmalloc.h>
-#ifdef CONFIG_USB_PWC_INPUT_EVDEV
-#include <linux/input.h>
-#endif
-#include "pwc-dec1.h"
-#include "pwc-dec23.h"
-
-/* Version block */
-#define PWC_VERSION "10.0.15"
-#define PWC_NAME "pwc"
-#define PFX PWC_NAME ": "
-
-
-/* Trace certain actions in the driver */
-#define PWC_DEBUG_LEVEL_MODULE (1<<0)
-#define PWC_DEBUG_LEVEL_PROBE (1<<1)
-#define PWC_DEBUG_LEVEL_OPEN (1<<2)
-#define PWC_DEBUG_LEVEL_READ (1<<3)
-#define PWC_DEBUG_LEVEL_MEMORY (1<<4)
-#define PWC_DEBUG_LEVEL_FLOW (1<<5)
-#define PWC_DEBUG_LEVEL_SIZE (1<<6)
-#define PWC_DEBUG_LEVEL_IOCTL (1<<7)
-#define PWC_DEBUG_LEVEL_TRACE (1<<8)
-
-#define PWC_DEBUG_MODULE(fmt, args...) PWC_DEBUG(MODULE, fmt, ##args)
-#define PWC_DEBUG_PROBE(fmt, args...) PWC_DEBUG(PROBE, fmt, ##args)
-#define PWC_DEBUG_OPEN(fmt, args...) PWC_DEBUG(OPEN, fmt, ##args)
-#define PWC_DEBUG_READ(fmt, args...) PWC_DEBUG(READ, fmt, ##args)
-#define PWC_DEBUG_MEMORY(fmt, args...) PWC_DEBUG(MEMORY, fmt, ##args)
-#define PWC_DEBUG_FLOW(fmt, args...) PWC_DEBUG(FLOW, fmt, ##args)
-#define PWC_DEBUG_SIZE(fmt, args...) PWC_DEBUG(SIZE, fmt, ##args)
-#define PWC_DEBUG_IOCTL(fmt, args...) PWC_DEBUG(IOCTL, fmt, ##args)
-#define PWC_DEBUG_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
-
-
-#ifdef CONFIG_USB_PWC_DEBUG
-
-#define PWC_DEBUG_LEVEL (PWC_DEBUG_LEVEL_MODULE)
-
-#define PWC_DEBUG(level, fmt, args...) do {\
- if ((PWC_DEBUG_LEVEL_ ##level) & pwc_trace) \
- printk(KERN_DEBUG PFX fmt, ##args); \
- } while (0)
-
-#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
-#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
-#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args)
-#define PWC_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
-
-#else /* if ! CONFIG_USB_PWC_DEBUG */
-
-#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
-#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
-#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args)
-#define PWC_TRACE(fmt, args...) do { } while(0)
-#define PWC_DEBUG(level, fmt, args...) do { } while(0)
-
-#define pwc_trace 0
-
-#endif
-
-/* Defines for ToUCam cameras */
-#define TOUCAM_HEADER_SIZE 8
-#define TOUCAM_TRAILER_SIZE 4
-
-#define FEATURE_MOTOR_PANTILT 0x0001
-#define FEATURE_CODEC1 0x0002
-#define FEATURE_CODEC2 0x0004
-
-#define MAX_WIDTH 640
-#define MAX_HEIGHT 480
-
-/* Ignore errors in the first N frames, to allow for startup delays */
-#define FRAME_LOWMARK 5
-
-/* Size and number of buffers for the ISO pipe. */
-#define MAX_ISO_BUFS 3
-#define ISO_FRAMES_PER_DESC 10
-#define ISO_MAX_FRAME_SIZE 960
-#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
-
-/* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */
-#define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
-
-/* Absolute minimum and maximum number of buffers available for mmap() */
-#define MIN_FRAMES 2
-#define MAX_FRAMES 16
-
-/* Some macros to quickly find the type of a webcam */
-#define DEVICE_USE_CODEC1(x) ((x)<675)
-#define DEVICE_USE_CODEC2(x) ((x)>=675 && (x)<700)
-#define DEVICE_USE_CODEC3(x) ((x)>=700)
-#define DEVICE_USE_CODEC23(x) ((x)>=675)
-
-/* Request types: video */
-#define SET_LUM_CTL 0x01
-#define GET_LUM_CTL 0x02
-#define SET_CHROM_CTL 0x03
-#define GET_CHROM_CTL 0x04
-#define SET_STATUS_CTL 0x05
-#define GET_STATUS_CTL 0x06
-#define SET_EP_STREAM_CTL 0x07
-#define GET_EP_STREAM_CTL 0x08
-#define GET_XX_CTL 0x09
-#define SET_XX_CTL 0x0A
-#define GET_XY_CTL 0x0B
-#define SET_XY_CTL 0x0C
-#define SET_MPT_CTL 0x0D
-#define GET_MPT_CTL 0x0E
-
-/* Selectors for the Luminance controls [GS]ET_LUM_CTL */
-#define AGC_MODE_FORMATTER 0x2000
-#define PRESET_AGC_FORMATTER 0x2100
-#define SHUTTER_MODE_FORMATTER 0x2200
-#define PRESET_SHUTTER_FORMATTER 0x2300
-#define PRESET_CONTOUR_FORMATTER 0x2400
-#define AUTO_CONTOUR_FORMATTER 0x2500
-#define BACK_LIGHT_COMPENSATION_FORMATTER 0x2600
-#define CONTRAST_FORMATTER 0x2700
-#define DYNAMIC_NOISE_CONTROL_FORMATTER 0x2800
-#define FLICKERLESS_MODE_FORMATTER 0x2900
-#define AE_CONTROL_SPEED 0x2A00
-#define BRIGHTNESS_FORMATTER 0x2B00
-#define GAMMA_FORMATTER 0x2C00
-
-/* Selectors for the Chrominance controls [GS]ET_CHROM_CTL */
-#define WB_MODE_FORMATTER 0x1000
-#define AWB_CONTROL_SPEED_FORMATTER 0x1100
-#define AWB_CONTROL_DELAY_FORMATTER 0x1200
-#define PRESET_MANUAL_RED_GAIN_FORMATTER 0x1300
-#define PRESET_MANUAL_BLUE_GAIN_FORMATTER 0x1400
-#define COLOUR_MODE_FORMATTER 0x1500
-#define SATURATION_MODE_FORMATTER1 0x1600
-#define SATURATION_MODE_FORMATTER2 0x1700
-
-/* Selectors for the Status controls [GS]ET_STATUS_CTL */
-#define SAVE_USER_DEFAULTS_FORMATTER 0x0200
-#define RESTORE_USER_DEFAULTS_FORMATTER 0x0300
-#define RESTORE_FACTORY_DEFAULTS_FORMATTER 0x0400
-#define READ_AGC_FORMATTER 0x0500
-#define READ_SHUTTER_FORMATTER 0x0600
-#define READ_RED_GAIN_FORMATTER 0x0700
-#define READ_BLUE_GAIN_FORMATTER 0x0800
-
-/* Formatters for the motorized pan & tilt [GS]ET_MPT_CTL */
-#define PT_RELATIVE_CONTROL_FORMATTER 0x01
-#define PT_RESET_CONTROL_FORMATTER 0x02
-#define PT_STATUS_FORMATTER 0x03
-
-/* Enumeration of image sizes */
-#define PSZ_SQCIF 0x00
-#define PSZ_QSIF 0x01
-#define PSZ_QCIF 0x02
-#define PSZ_SIF 0x03
-#define PSZ_CIF 0x04
-#define PSZ_VGA 0x05
-#define PSZ_MAX 6
-
-struct pwc_raw_frame {
- __le16 type; /* type of the webcam */
- __le16 vbandlength; /* Size of 4 lines compressed (used by the
- decompressor) */
- __u8 cmd[4]; /* the four byte of the command (in case of
- nala, only the first 3 bytes is filled) */
- __u8 rawframe[0]; /* frame_size = H / 4 * vbandlength */
-} __packed;
-
-/* intermediate buffers with raw data from the USB cam */
-struct pwc_frame_buf
-{
- struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
- struct list_head list;
- void *data;
- int filled; /* number of bytes filled */
-};
-
-struct pwc_device
-{
- struct video_device vdev;
- struct v4l2_device v4l2_dev;
-
- /* videobuf2 queue and queued buffers list */
- struct vb2_queue vb_queue;
- struct list_head queued_bufs;
- spinlock_t queued_bufs_lock; /* Protects queued_bufs */
-
- /* Note if taking both locks v4l2_lock must always be locked first! */
- struct mutex v4l2_lock; /* Protects everything else */
- struct mutex vb_queue_lock; /* Protects vb_queue and capt_file */
-
- /* Pointer to our usb_device, will be NULL after unplug */
- struct usb_device *udev; /* Both mutexes most be hold when setting! */
-
- /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */
- int type;
- int release; /* release number */
- int features; /* feature bits */
-
- /*** Video data ***/
- int vendpoint; /* video isoc endpoint */
- int vcinterface; /* video control interface */
- int valternate; /* alternate interface needed */
- int vframes; /* frames-per-second */
- int pixfmt; /* pixelformat: V4L2_PIX_FMT_YUV420 or _PWCX */
- int vframe_count; /* received frames */
- int vmax_packet_size; /* USB maxpacket size */
- int vlast_packet_size; /* for frame synchronisation */
- int visoc_errors; /* number of contiguous ISOC errors */
- int vbandlength; /* compressed band length; 0 is uncompressed */
- char vsync; /* used by isoc handler */
- char vmirror; /* for ToUCaM series */
- char power_save; /* Do powersaving for this cam */
-
- unsigned char cmd_buf[13];
- unsigned char *ctrl_buf;
-
- struct urb *urbs[MAX_ISO_BUFS];
-
- /*
- * Frame currently being filled, this only gets touched by the
- * isoc urb complete handler, and by stream start / stop since
- * start / stop touch it before / after starting / killing the urbs
- * no locking is needed around this
- */
- struct pwc_frame_buf *fill_buf;
-
- int frame_header_size, frame_trailer_size;
- int frame_size;
- int frame_total_size; /* including header & trailer */
- int drop_frames;
-
- union { /* private data for decompression engine */
- struct pwc_dec1_private dec1;
- struct pwc_dec23_private dec23;
- };
-
- /*
- * We have an 'image' and a 'view', where 'image' is the fixed-size img
- * as delivered by the camera, and 'view' is the size requested by the
- * program. The camera image is centered in this viewport, laced with
- * a gray or black border. view_min <= image <= view <= view_max;
- */
- int image_mask; /* supported sizes */
- int width, height; /* current resolution */
-
-#ifdef CONFIG_USB_PWC_INPUT_EVDEV
- struct input_dev *button_dev; /* webcam snapshot button input */
- char button_phys[64];
-#endif
-
- /* controls */
- struct v4l2_ctrl_handler ctrl_handler;
- u16 saturation_fmt;
- struct v4l2_ctrl *brightness;
- struct v4l2_ctrl *contrast;
- struct v4l2_ctrl *saturation;
- struct v4l2_ctrl *gamma;
- struct {
- /* awb / red-blue balance cluster */
- struct v4l2_ctrl *auto_white_balance;
- struct v4l2_ctrl *red_balance;
- struct v4l2_ctrl *blue_balance;
- /* usb ctrl transfers are slow, so we cache things */
- int color_bal_valid;
- unsigned long last_color_bal_update; /* In jiffies */
- s32 last_red_balance;
- s32 last_blue_balance;
- };
- struct {
- /* autogain / gain cluster */
- struct v4l2_ctrl *autogain;
- struct v4l2_ctrl *gain;
- int gain_valid;
- unsigned long last_gain_update; /* In jiffies */
- s32 last_gain;
- };
- struct {
- /* exposure_auto / exposure cluster */
- struct v4l2_ctrl *exposure_auto;
- struct v4l2_ctrl *exposure;
- int exposure_valid;
- unsigned long last_exposure_update; /* In jiffies */
- s32 last_exposure;
- };
- struct v4l2_ctrl *colorfx;
- struct {
- /* autocontour/contour cluster */
- struct v4l2_ctrl *autocontour;
- struct v4l2_ctrl *contour;
- };
- struct v4l2_ctrl *backlight;
- struct v4l2_ctrl *flicker;
- struct v4l2_ctrl *noise_reduction;
- struct v4l2_ctrl *save_user;
- struct v4l2_ctrl *restore_user;
- struct v4l2_ctrl *restore_factory;
- struct v4l2_ctrl *awb_speed;
- struct v4l2_ctrl *awb_delay;
- struct {
- /* motor control cluster */
- struct v4l2_ctrl *motor_pan;
- struct v4l2_ctrl *motor_tilt;
- struct v4l2_ctrl *motor_pan_reset;
- struct v4l2_ctrl *motor_tilt_reset;
- };
- /* CODEC3 models have both gain and exposure controlled by autogain */
- struct v4l2_ctrl *autogain_expo_cluster[3];
-};
-
-/* Global variables */
-#ifdef CONFIG_USB_PWC_DEBUG
-extern int pwc_trace;
-#endif
-
-/** Functions in pwc-misc.c */
-/* sizes in pixels */
-extern const int pwc_image_sizes[PSZ_MAX][2];
-
-int pwc_get_size(struct pwc_device *pdev, int width, int height);
-void pwc_construct(struct pwc_device *pdev);
-
-/** Functions in pwc-ctrl.c */
-/* Request a certain video mode. Returns < 0 if not possible */
-extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height,
- int pixfmt, int frames, int *compression, int send_to_cam);
-extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size);
-extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
-extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);
-extern int send_control_msg(struct pwc_device *pdev,
- u8 request, u16 value, void *buf, int buflen);
-
-/* Control get / set helpers */
-int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data);
-int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data);
-int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data);
-#define pwc_set_s8_ctrl pwc_set_u8_ctrl
-int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *dat);
-int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data);
-int pwc_button_ctrl(struct pwc_device *pdev, u16 value);
-int pwc_init_controls(struct pwc_device *pdev);
-
-/* Power down or up the camera; not supported by all models */
-extern void pwc_camera_power(struct pwc_device *pdev, int power);
-
-extern const struct v4l2_ioctl_ops pwc_ioctl_ops;
-
-/** pwc-uncompress.c */
-/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */
-int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf);
-
-#endif
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
deleted file mode 100644
index 1e3776d08da..00000000000
--- a/drivers/media/video/pxa_camera.c
+++ /dev/null
@@ -1,1852 +0,0 @@
-/*
- * V4L2 Driver for PXA camera host
- *
- * Copyright (C) 2006, Sascha Hauer, Pengutronix
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/moduleparam.h>
-#include <linux/time.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-dev.h>
-#include <media/videobuf-dma-sg.h>
-#include <media/soc_camera.h>
-#include <media/soc_mediabus.h>
-
-#include <linux/videodev2.h>
-
-#include <mach/dma.h>
-#include <linux/platform_data/camera-pxa.h>
-
-#define PXA_CAM_VERSION "0.0.6"
-#define PXA_CAM_DRV_NAME "pxa27x-camera"
-
-/* Camera Interface */
-#define CICR0 0x0000
-#define CICR1 0x0004
-#define CICR2 0x0008
-#define CICR3 0x000C
-#define CICR4 0x0010
-#define CISR 0x0014
-#define CIFR 0x0018
-#define CITOR 0x001C
-#define CIBR0 0x0028
-#define CIBR1 0x0030
-#define CIBR2 0x0038
-
-#define CICR0_DMAEN (1 << 31) /* DMA request enable */
-#define CICR0_PAR_EN (1 << 30) /* Parity enable */
-#define CICR0_SL_CAP_EN (1 << 29) /* Capture enable for slave mode */
-#define CICR0_ENB (1 << 28) /* Camera interface enable */
-#define CICR0_DIS (1 << 27) /* Camera interface disable */
-#define CICR0_SIM (0x7 << 24) /* Sensor interface mode mask */
-#define CICR0_TOM (1 << 9) /* Time-out mask */
-#define CICR0_RDAVM (1 << 8) /* Receive-data-available mask */
-#define CICR0_FEM (1 << 7) /* FIFO-empty mask */
-#define CICR0_EOLM (1 << 6) /* End-of-line mask */
-#define CICR0_PERRM (1 << 5) /* Parity-error mask */
-#define CICR0_QDM (1 << 4) /* Quick-disable mask */
-#define CICR0_CDM (1 << 3) /* Disable-done mask */
-#define CICR0_SOFM (1 << 2) /* Start-of-frame mask */
-#define CICR0_EOFM (1 << 1) /* End-of-frame mask */
-#define CICR0_FOM (1 << 0) /* FIFO-overrun mask */
-
-#define CICR1_TBIT (1 << 31) /* Transparency bit */
-#define CICR1_RGBT_CONV (0x3 << 29) /* RGBT conversion mask */
-#define CICR1_PPL (0x7ff << 15) /* Pixels per line mask */
-#define CICR1_RGB_CONV (0x7 << 12) /* RGB conversion mask */
-#define CICR1_RGB_F (1 << 11) /* RGB format */
-#define CICR1_YCBCR_F (1 << 10) /* YCbCr format */
-#define CICR1_RGB_BPP (0x7 << 7) /* RGB bis per pixel mask */
-#define CICR1_RAW_BPP (0x3 << 5) /* Raw bis per pixel mask */
-#define CICR1_COLOR_SP (0x3 << 3) /* Color space mask */
-#define CICR1_DW (0x7 << 0) /* Data width mask */
-
-#define CICR2_BLW (0xff << 24) /* Beginning-of-line pixel clock
- wait count mask */
-#define CICR2_ELW (0xff << 16) /* End-of-line pixel clock
- wait count mask */
-#define CICR2_HSW (0x3f << 10) /* Horizontal sync pulse width mask */
-#define CICR2_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock
- wait count mask */
-#define CICR2_FSW (0x7 << 0) /* Frame stabilization
- wait count mask */
-
-#define CICR3_BFW (0xff << 24) /* Beginning-of-frame line clock
- wait count mask */
-#define CICR3_EFW (0xff << 16) /* End-of-frame line clock
- wait count mask */
-#define CICR3_VSW (0x3f << 10) /* Vertical sync pulse width mask */
-#define CICR3_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock
- wait count mask */
-#define CICR3_LPF (0x7ff << 0) /* Lines per frame mask */
-
-#define CICR4_MCLK_DLY (0x3 << 24) /* MCLK Data Capture Delay mask */
-#define CICR4_PCLK_EN (1 << 23) /* Pixel clock enable */
-#define CICR4_PCP (1 << 22) /* Pixel clock polarity */
-#define CICR4_HSP (1 << 21) /* Horizontal sync polarity */
-#define CICR4_VSP (1 << 20) /* Vertical sync polarity */
-#define CICR4_MCLK_EN (1 << 19) /* MCLK enable */
-#define CICR4_FR_RATE (0x7 << 8) /* Frame rate mask */
-#define CICR4_DIV (0xff << 0) /* Clock divisor mask */
-
-#define CISR_FTO (1 << 15) /* FIFO time-out */
-#define CISR_RDAV_2 (1 << 14) /* Channel 2 receive data available */
-#define CISR_RDAV_1 (1 << 13) /* Channel 1 receive data available */
-#define CISR_RDAV_0 (1 << 12) /* Channel 0 receive data available */
-#define CISR_FEMPTY_2 (1 << 11) /* Channel 2 FIFO empty */
-#define CISR_FEMPTY_1 (1 << 10) /* Channel 1 FIFO empty */
-#define CISR_FEMPTY_0 (1 << 9) /* Channel 0 FIFO empty */
-#define CISR_EOL (1 << 8) /* End of line */
-#define CISR_PAR_ERR (1 << 7) /* Parity error */
-#define CISR_CQD (1 << 6) /* Camera interface quick disable */
-#define CISR_CDD (1 << 5) /* Camera interface disable done */
-#define CISR_SOF (1 << 4) /* Start of frame */
-#define CISR_EOF (1 << 3) /* End of frame */
-#define CISR_IFO_2 (1 << 2) /* FIFO overrun for Channel 2 */
-#define CISR_IFO_1 (1 << 1) /* FIFO overrun for Channel 1 */
-#define CISR_IFO_0 (1 << 0) /* FIFO overrun for Channel 0 */
-
-#define CIFR_FLVL2 (0x7f << 23) /* FIFO 2 level mask */
-#define CIFR_FLVL1 (0x7f << 16) /* FIFO 1 level mask */
-#define CIFR_FLVL0 (0xff << 8) /* FIFO 0 level mask */
-#define CIFR_THL_0 (0x3 << 4) /* Threshold Level for Channel 0 FIFO */
-#define CIFR_RESET_F (1 << 3) /* Reset input FIFOs */
-#define CIFR_FEN2 (1 << 2) /* FIFO enable for channel 2 */
-#define CIFR_FEN1 (1 << 1) /* FIFO enable for channel 1 */
-#define CIFR_FEN0 (1 << 0) /* FIFO enable for channel 0 */
-
-#define CICR0_SIM_MP (0 << 24)
-#define CICR0_SIM_SP (1 << 24)
-#define CICR0_SIM_MS (2 << 24)
-#define CICR0_SIM_EP (3 << 24)
-#define CICR0_SIM_ES (4 << 24)
-
-#define CICR1_DW_VAL(x) ((x) & CICR1_DW) /* Data bus width */
-#define CICR1_PPL_VAL(x) (((x) << 15) & CICR1_PPL) /* Pixels per line */
-#define CICR1_COLOR_SP_VAL(x) (((x) << 3) & CICR1_COLOR_SP) /* color space */
-#define CICR1_RGB_BPP_VAL(x) (((x) << 7) & CICR1_RGB_BPP) /* bpp for rgb */
-#define CICR1_RGBT_CONV_VAL(x) (((x) << 29) & CICR1_RGBT_CONV) /* rgbt conv */
-
-#define CICR2_BLW_VAL(x) (((x) << 24) & CICR2_BLW) /* Beginning-of-line pixel clock wait count */
-#define CICR2_ELW_VAL(x) (((x) << 16) & CICR2_ELW) /* End-of-line pixel clock wait count */
-#define CICR2_HSW_VAL(x) (((x) << 10) & CICR2_HSW) /* Horizontal sync pulse width */
-#define CICR2_BFPW_VAL(x) (((x) << 3) & CICR2_BFPW) /* Beginning-of-frame pixel clock wait count */
-#define CICR2_FSW_VAL(x) (((x) << 0) & CICR2_FSW) /* Frame stabilization wait count */
-
-#define CICR3_BFW_VAL(x) (((x) << 24) & CICR3_BFW) /* Beginning-of-frame line clock wait count */
-#define CICR3_EFW_VAL(x) (((x) << 16) & CICR3_EFW) /* End-of-frame line clock wait count */
-#define CICR3_VSW_VAL(x) (((x) << 11) & CICR3_VSW) /* Vertical sync pulse width */
-#define CICR3_LPF_VAL(x) (((x) << 0) & CICR3_LPF) /* Lines per frame */
-
-#define CICR0_IRQ_MASK (CICR0_TOM | CICR0_RDAVM | CICR0_FEM | CICR0_EOLM | \
- CICR0_PERRM | CICR0_QDM | CICR0_CDM | CICR0_SOFM | \
- CICR0_EOFM | CICR0_FOM)
-
-/*
- * Structures
- */
-enum pxa_camera_active_dma {
- DMA_Y = 0x1,
- DMA_U = 0x2,
- DMA_V = 0x4,
-};
-
-/* descriptor needed for the PXA DMA engine */
-struct pxa_cam_dma {
- dma_addr_t sg_dma;
- struct pxa_dma_desc *sg_cpu;
- size_t sg_size;
- int sglen;
-};
-
-/* buffer for one video frame */
-struct pxa_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
- enum v4l2_mbus_pixelcode code;
- /* our descriptor lists for Y, U and V channels */
- struct pxa_cam_dma dmas[3];
- int inwork;
- enum pxa_camera_active_dma active_dma;
-};
-
-struct pxa_camera_dev {
- struct soc_camera_host soc_host;
- /*
- * PXA27x is only supposed to handle one camera on its Quick Capture
- * interface. If anyone ever builds hardware to enable more than
- * one camera, they will have to modify this driver too
- */
- struct soc_camera_device *icd;
- struct clk *clk;
-
- unsigned int irq;
- void __iomem *base;
-
- int channels;
- unsigned int dma_chans[3];
-
- struct pxacamera_platform_data *pdata;
- struct resource *res;
- unsigned long platform_flags;
- unsigned long ciclk;
- unsigned long mclk;
- u32 mclk_divisor;
- u16 width_flags; /* max 10 bits */
-
- struct list_head capture;
-
- spinlock_t lock;
-
- struct pxa_buffer *active;
- struct pxa_dma_desc *sg_tail[3];
-
- u32 save_cicr[5];
-};
-
-struct pxa_cam {
- unsigned long flags;
-};
-
-static const char *pxa_cam_driver_description = "PXA_Camera";
-
-static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
-
-/*
- * Videobuf operations
- */
-static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
- unsigned int *size)
-{
- struct soc_camera_device *icd = vq->priv_data;
-
- dev_dbg(icd->parent, "count=%d, size=%d\n", *count, *size);
-
- *size = icd->sizeimage;
-
- if (0 == *count)
- *count = 32;
- if (*size * *count > vid_limit * 1024 * 1024)
- *count = (vid_limit * 1024 * 1024) / *size;
-
- return 0;
-}
-
-static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
-{
- struct soc_camera_device *icd = vq->priv_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
- int i;
-
- BUG_ON(in_interrupt());
-
- dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- &buf->vb, buf->vb.baddr, buf->vb.bsize);
-
- /*
- * This waits until this buffer is out of danger, i.e., until it is no
- * longer in STATE_QUEUED or STATE_ACTIVE
- */
- videobuf_waiton(vq, &buf->vb, 0, 0);
- videobuf_dma_unmap(vq->dev, dma);
- videobuf_dma_free(dma);
-
- for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
- if (buf->dmas[i].sg_cpu)
- dma_free_coherent(ici->v4l2_dev.dev,
- buf->dmas[i].sg_size,
- buf->dmas[i].sg_cpu,
- buf->dmas[i].sg_dma);
- buf->dmas[i].sg_cpu = NULL;
- }
-
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int calculate_dma_sglen(struct scatterlist *sglist, int sglen,
- int sg_first_ofs, int size)
-{
- int i, offset, dma_len, xfer_len;
- struct scatterlist *sg;
-
- offset = sg_first_ofs;
- for_each_sg(sglist, sg, sglen, i) {
- dma_len = sg_dma_len(sg);
-
- /* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */
- xfer_len = roundup(min(dma_len - offset, size), 8);
-
- size = max(0, size - xfer_len);
- offset = 0;
- if (size == 0)
- break;
- }
-
- BUG_ON(size != 0);
- return i + 1;
-}
-
-/**
- * pxa_init_dma_channel - init dma descriptors
- * @pcdev: pxa camera device
- * @buf: pxa buffer to find pxa dma channel
- * @dma: dma video buffer
- * @channel: dma channel (0 => 'Y', 1 => 'U', 2 => 'V')
- * @cibr: camera Receive Buffer Register
- * @size: bytes to transfer
- * @sg_first: first element of sg_list
- * @sg_first_ofs: offset in first element of sg_list
- *
- * Prepares the pxa dma descriptors to transfer one camera channel.
- * Beware sg_first and sg_first_ofs are both input and output parameters.
- *
- * Returns 0 or -ENOMEM if no coherent memory is available
- */
-static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
- struct pxa_buffer *buf,
- struct videobuf_dmabuf *dma, int channel,
- int cibr, int size,
- struct scatterlist **sg_first, int *sg_first_ofs)
-{
- struct pxa_cam_dma *pxa_dma = &buf->dmas[channel];
- struct device *dev = pcdev->soc_host.v4l2_dev.dev;
- struct scatterlist *sg;
- int i, offset, sglen;
- int dma_len = 0, xfer_len = 0;
-
- if (pxa_dma->sg_cpu)
- dma_free_coherent(dev, pxa_dma->sg_size,
- pxa_dma->sg_cpu, pxa_dma->sg_dma);
-
- sglen = calculate_dma_sglen(*sg_first, dma->sglen,
- *sg_first_ofs, size);
-
- pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc);
- pxa_dma->sg_cpu = dma_alloc_coherent(dev, pxa_dma->sg_size,
- &pxa_dma->sg_dma, GFP_KERNEL);
- if (!pxa_dma->sg_cpu)
- return -ENOMEM;
-
- pxa_dma->sglen = sglen;
- offset = *sg_first_ofs;
-
- dev_dbg(dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
- *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma);
-
-
- for_each_sg(*sg_first, sg, sglen, i) {
- dma_len = sg_dma_len(sg);
-
- /* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */
- xfer_len = roundup(min(dma_len - offset, size), 8);
-
- size = max(0, size - xfer_len);
-
- pxa_dma->sg_cpu[i].dsadr = pcdev->res->start + cibr;
- pxa_dma->sg_cpu[i].dtadr = sg_dma_address(sg) + offset;
- pxa_dma->sg_cpu[i].dcmd =
- DCMD_FLOWSRC | DCMD_BURST8 | DCMD_INCTRGADDR | xfer_len;
-#ifdef DEBUG
- if (!i)
- pxa_dma->sg_cpu[i].dcmd |= DCMD_STARTIRQEN;
-#endif
- pxa_dma->sg_cpu[i].ddadr =
- pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc);
-
- dev_vdbg(dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
- pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc),
- sg_dma_address(sg) + offset, xfer_len);
- offset = 0;
-
- if (size == 0)
- break;
- }
-
- pxa_dma->sg_cpu[sglen].ddadr = DDADR_STOP;
- pxa_dma->sg_cpu[sglen].dcmd = DCMD_FLOWSRC | DCMD_BURST8 | DCMD_ENDIRQEN;
-
- /*
- * Handle 1 special case :
- * - in 3 planes (YUV422P format), we might finish with xfer_len equal
- * to dma_len (end on PAGE boundary). In this case, the sg element
- * for next plane should be the next after the last used to store the
- * last scatter gather RAM page
- */
- if (xfer_len >= dma_len) {
- *sg_first_ofs = xfer_len - dma_len;
- *sg_first = sg_next(sg);
- } else {
- *sg_first_ofs = xfer_len;
- *sg_first = sg;
- }
-
- return 0;
-}
-
-static void pxa_videobuf_set_actdma(struct pxa_camera_dev *pcdev,
- struct pxa_buffer *buf)
-{
- buf->active_dma = DMA_Y;
- if (pcdev->channels == 3)
- buf->active_dma |= DMA_U | DMA_V;
-}
-
-/*
- * Please check the DMA prepared buffer structure in :
- * Documentation/video4linux/pxa_camera.txt
- * Please check also in pxa_camera_check_link_miss() to understand why DMA chain
- * modification while DMA chain is running will work anyway.
- */
-static int pxa_videobuf_prepare(struct videobuf_queue *vq,
- struct videobuf_buffer *vb, enum v4l2_field field)
-{
- struct soc_camera_device *icd = vq->priv_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct pxa_camera_dev *pcdev = ici->priv;
- struct device *dev = pcdev->soc_host.v4l2_dev.dev;
- struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
- int ret;
- int size_y, size_u = 0, size_v = 0;
-
- dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
-
- /* Added list head initialization on alloc */
- WARN_ON(!list_empty(&vb->queue));
-
-#ifdef DEBUG
- /*
- * This can be useful if you want to see if we actually fill
- * the buffer with something
- */
- memset((void *)vb->baddr, 0xaa, vb->bsize);
-#endif
-
- BUG_ON(NULL == icd->current_fmt);
-
- /*
- * I think, in buf_prepare you only have to protect global data,
- * the actual buffer is yours
- */
- buf->inwork = 1;
-
- if (buf->code != icd->current_fmt->code ||
- vb->width != icd->user_width ||
- vb->height != icd->user_height ||
- vb->field != field) {
- buf->code = icd->current_fmt->code;
- vb->width = icd->user_width;
- vb->height = icd->user_height;
- vb->field = field;
- vb->state = VIDEOBUF_NEEDS_INIT;
- }
-
- vb->size = icd->sizeimage;
- if (0 != vb->baddr && vb->bsize < vb->size) {
- ret = -EINVAL;
- goto out;
- }
-
- if (vb->state == VIDEOBUF_NEEDS_INIT) {
- int size = vb->size;
- int next_ofs = 0;
- struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
- struct scatterlist *sg;
-
- ret = videobuf_iolock(vq, vb, NULL);
- if (ret)
- goto fail;
-
- if (pcdev->channels == 3) {
- size_y = size / 2;
- size_u = size_v = size / 4;
- } else {
- size_y = size;
- }
-
- sg = dma->sglist;
-
- /* init DMA for Y channel */
- ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y,
- &sg, &next_ofs);
- if (ret) {
- dev_err(dev, "DMA initialization for Y/RGB failed\n");
- goto fail;
- }
-
- /* init DMA for U channel */
- if (size_u)
- ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1,
- size_u, &sg, &next_ofs);
- if (ret) {
- dev_err(dev, "DMA initialization for U failed\n");
- goto fail_u;
- }
-
- /* init DMA for V channel */
- if (size_v)
- ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2,
- size_v, &sg, &next_ofs);
- if (ret) {
- dev_err(dev, "DMA initialization for V failed\n");
- goto fail_v;
- }
-
- vb->state = VIDEOBUF_PREPARED;
- }
-
- buf->inwork = 0;
- pxa_videobuf_set_actdma(pcdev, buf);
-
- return 0;
-
-fail_v:
- dma_free_coherent(dev, buf->dmas[1].sg_size,
- buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma);
-fail_u:
- dma_free_coherent(dev, buf->dmas[0].sg_size,
- buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma);
-fail:
- free_buffer(vq, buf);
-out:
- buf->inwork = 0;
- return ret;
-}
-
-/**
- * pxa_dma_start_channels - start DMA channel for active buffer
- * @pcdev: pxa camera device
- *
- * Initialize DMA channels to the beginning of the active video buffer, and
- * start these channels.
- */
-static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev)
-{
- int i;
- struct pxa_buffer *active;
-
- active = pcdev->active;
-
- for (i = 0; i < pcdev->channels; i++) {
- dev_dbg(pcdev->soc_host.v4l2_dev.dev,
- "%s (channel=%d) ddadr=%08x\n", __func__,
- i, active->dmas[i].sg_dma);
- DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma;
- DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
- }
-}
-
-static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev)
-{
- int i;
-
- for (i = 0; i < pcdev->channels; i++) {
- dev_dbg(pcdev->soc_host.v4l2_dev.dev,
- "%s (channel=%d)\n", __func__, i);
- DCSR(pcdev->dma_chans[i]) = 0;
- }
-}
-
-static void pxa_dma_add_tail_buf(struct pxa_camera_dev *pcdev,
- struct pxa_buffer *buf)
-{
- int i;
- struct pxa_dma_desc *buf_last_desc;
-
- for (i = 0; i < pcdev->channels; i++) {
- buf_last_desc = buf->dmas[i].sg_cpu + buf->dmas[i].sglen;
- buf_last_desc->ddadr = DDADR_STOP;
-
- if (pcdev->sg_tail[i])
- /* Link the new buffer to the old tail */
- pcdev->sg_tail[i]->ddadr = buf->dmas[i].sg_dma;
-
- /* Update the channel tail */
- pcdev->sg_tail[i] = buf_last_desc;
- }
-}
-
-/**
- * pxa_camera_start_capture - start video capturing
- * @pcdev: camera device
- *
- * Launch capturing. DMA channels should not be active yet. They should get
- * activated at the end of frame interrupt, to capture only whole frames, and
- * never begin the capture of a partial frame.
- */
-static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
-{
- unsigned long cicr0;
-
- dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s\n", __func__);
- /* Enable End-Of-Frame Interrupt */
- cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_ENB;
- cicr0 &= ~CICR0_EOFM;
- __raw_writel(cicr0, pcdev->base + CICR0);
-}
-
-static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev)
-{
- unsigned long cicr0;
-
- pxa_dma_stop_channels(pcdev);
-
- cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB;
- __raw_writel(cicr0, pcdev->base + CICR0);
-
- pcdev->active = NULL;
- dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s\n", __func__);
-}
-
-/* Called under spinlock_irqsave(&pcdev->lock, ...) */
-static void pxa_videobuf_queue(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct soc_camera_device *icd = vq->priv_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct pxa_camera_dev *pcdev = ici->priv;
- struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
-
- dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d active=%p\n",
- __func__, vb, vb->baddr, vb->bsize, pcdev->active);
-
- list_add_tail(&vb->queue, &pcdev->capture);
-
- vb->state = VIDEOBUF_ACTIVE;
- pxa_dma_add_tail_buf(pcdev, buf);
-
- if (!pcdev->active)
- pxa_camera_start_capture(pcdev);
-}
-
-static void pxa_videobuf_release(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
-#ifdef DEBUG
- struct soc_camera_device *icd = vq->priv_data;
- struct device *dev = icd->parent;
-
- dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
-
- switch (vb->state) {
- case VIDEOBUF_ACTIVE:
- dev_dbg(dev, "%s (active)\n", __func__);
- break;
- case VIDEOBUF_QUEUED:
- dev_dbg(dev, "%s (queued)\n", __func__);
- break;
- case VIDEOBUF_PREPARED:
- dev_dbg(dev, "%s (prepared)\n", __func__);
- break;
- default:
- dev_dbg(dev, "%s (unknown)\n", __func__);
- break;
- }
-#endif
-
- free_buffer(vq, buf);
-}
-
-static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
- struct videobuf_buffer *vb,
- struct pxa_buffer *buf)
-{
- int i;
-
- /* _init is used to debug races, see comment in pxa_camera_reqbufs() */
- list_del_init(&vb->queue);
- vb->state = VIDEOBUF_DONE;
- do_gettimeofday(&vb->ts);
- vb->field_count++;
- wake_up(&vb->done);
- dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s dequeud buffer (vb=0x%p)\n",
- __func__, vb);
-
- if (list_empty(&pcdev->capture)) {
- pxa_camera_stop_capture(pcdev);
- for (i = 0; i < pcdev->channels; i++)
- pcdev->sg_tail[i] = NULL;
- return;
- }
-
- pcdev->active = list_entry(pcdev->capture.next,
- struct pxa_buffer, vb.queue);
-}
-
-/**
- * pxa_camera_check_link_miss - check missed DMA linking
- * @pcdev: camera device
- *
- * The DMA chaining is done with DMA running. This means a tiny temporal window
- * remains, where a buffer is queued on the chain, while the chain is already
- * stopped. This means the tailed buffer would never be transferred by DMA.
- * This function restarts the capture for this corner case, where :
- * - DADR() == DADDR_STOP
- * - a videobuffer is queued on the pcdev->capture list
- *
- * Please check the "DMA hot chaining timeslice issue" in
- * Documentation/video4linux/pxa_camera.txt
- *
- * Context: should only be called within the dma irq handler
- */
-static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
-{
- int i, is_dma_stopped = 1;
-
- for (i = 0; i < pcdev->channels; i++)
- if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP)
- is_dma_stopped = 0;
- dev_dbg(pcdev->soc_host.v4l2_dev.dev,
- "%s : top queued buffer=%p, dma_stopped=%d\n",
- __func__, pcdev->active, is_dma_stopped);
- if (pcdev->active && is_dma_stopped)
- pxa_camera_start_capture(pcdev);
-}
-
-static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
- enum pxa_camera_active_dma act_dma)
-{
- struct device *dev = pcdev->soc_host.v4l2_dev.dev;
- struct pxa_buffer *buf;
- unsigned long flags;
- u32 status, camera_status, overrun;
- struct videobuf_buffer *vb;
-
- spin_lock_irqsave(&pcdev->lock, flags);
-
- status = DCSR(channel);
- DCSR(channel) = status;
-
- camera_status = __raw_readl(pcdev->base + CISR);
- overrun = CISR_IFO_0;
- if (pcdev->channels == 3)
- overrun |= CISR_IFO_1 | CISR_IFO_2;
-
- if (status & DCSR_BUSERR) {
- dev_err(dev, "DMA Bus Error IRQ!\n");
- goto out;
- }
-
- if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) {
- dev_err(dev, "Unknown DMA IRQ source, status: 0x%08x\n",
- status);
- goto out;
- }
-
- /*
- * pcdev->active should not be NULL in DMA irq handler.
- *
- * But there is one corner case : if capture was stopped due to an
- * overrun of channel 1, and at that same channel 2 was completed.
- *
- * When handling the overrun in DMA irq for channel 1, we'll stop the
- * capture and restart it (and thus set pcdev->active to NULL). But the
- * DMA irq handler will already be pending for channel 2. So on entering
- * the DMA irq handler for channel 2 there will be no active buffer, yet
- * that is normal.
- */
- if (!pcdev->active)
- goto out;
-
- vb = &pcdev->active->vb;
- buf = container_of(vb, struct pxa_buffer, vb);
- WARN_ON(buf->inwork || list_empty(&vb->queue));
-
- dev_dbg(dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
- __func__, channel, status & DCSR_STARTINTR ? "SOF " : "",
- status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel));
-
- if (status & DCSR_ENDINTR) {
- /*
- * It's normal if the last frame creates an overrun, as there
- * are no more DMA descriptors to fetch from QCI fifos
- */
- if (camera_status & overrun &&
- !list_is_last(pcdev->capture.next, &pcdev->capture)) {
- dev_dbg(dev, "FIFO overrun! CISR: %x\n",
- camera_status);
- pxa_camera_stop_capture(pcdev);
- pxa_camera_start_capture(pcdev);
- goto out;
- }
- buf->active_dma &= ~act_dma;
- if (!buf->active_dma) {
- pxa_camera_wakeup(pcdev, vb, buf);
- pxa_camera_check_link_miss(pcdev);
- }
- }
-
-out:
- spin_unlock_irqrestore(&pcdev->lock, flags);
-}
-
-static void pxa_camera_dma_irq_y(int channel, void *data)
-{
- struct pxa_camera_dev *pcdev = data;
- pxa_camera_dma_irq(channel, pcdev, DMA_Y);
-}
-
-static void pxa_camera_dma_irq_u(int channel, void *data)
-{
- struct pxa_camera_dev *pcdev = data;
- pxa_camera_dma_irq(channel, pcdev, DMA_U);
-}
-
-static void pxa_camera_dma_irq_v(int channel, void *data)
-{
- struct pxa_camera_dev *pcdev = data;
- pxa_camera_dma_irq(channel, pcdev, DMA_V);
-}
-
-static struct videobuf_queue_ops pxa_videobuf_ops = {
- .buf_setup = pxa_videobuf_setup,
- .buf_prepare = pxa_videobuf_prepare,
- .buf_queue = pxa_videobuf_queue,
- .buf_release = pxa_videobuf_release,
-};
-
-static void pxa_camera_init_videobuf(struct videobuf_queue *q,
- struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct pxa_camera_dev *pcdev = ici->priv;
-
- /*
- * We must pass NULL as dev pointer, then all pci_* dma operations
- * transform to normal dma_* ones.
- */
- videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
- sizeof(struct pxa_buffer), icd, &icd->video_lock);
-}
-
-static u32 mclk_get_divisor(struct platform_device *pdev,
- struct pxa_camera_dev *pcdev)
-{
- unsigned long mclk = pcdev->mclk;
- struct device *dev = &pdev->dev;
- u32 div;
- unsigned long lcdclk;
-
- lcdclk = clk_get_rate(pcdev->clk);
- pcdev->ciclk = lcdclk;
-
- /* mclk <= ciclk / 4 (27.4.2) */
- if (mclk > lcdclk / 4) {
- mclk = lcdclk / 4;
- dev_warn(dev, "Limiting master clock to %lu\n", mclk);
- }
-
- /* We verify mclk != 0, so if anyone breaks it, here comes their Oops */
- div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
-
- /* If we're not supplying MCLK, leave it at 0 */
- if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
- pcdev->mclk = lcdclk / (2 * (div + 1));
-
- dev_dbg(dev, "LCD clock %luHz, target freq %luHz, divisor %u\n",
- lcdclk, mclk, div);
-
- return div;
-}
-
-static void recalculate_fifo_timeout(struct pxa_camera_dev *pcdev,
- unsigned long pclk)
-{
- /* We want a timeout > 1 pixel time, not ">=" */
- u32 ciclk_per_pixel = pcdev->ciclk / pclk + 1;
-
- __raw_writel(ciclk_per_pixel, pcdev->base + CITOR);
-}
-
-static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
-{
- u32 cicr4 = 0;
-
- /* disable all interrupts */
- __raw_writel(0x3ff, pcdev->base + CICR0);
-
- if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
- cicr4 |= CICR4_PCLK_EN;
- if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
- cicr4 |= CICR4_MCLK_EN;
- if (pcdev->platform_flags & PXA_CAMERA_PCP)
- cicr4 |= CICR4_PCP;
- if (pcdev->platform_flags & PXA_CAMERA_HSP)
- cicr4 |= CICR4_HSP;
- if (pcdev->platform_flags & PXA_CAMERA_VSP)
- cicr4 |= CICR4_VSP;
-
- __raw_writel(pcdev->mclk_divisor | cicr4, pcdev->base + CICR4);
-
- if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
- /* Initialise the timeout under the assumption pclk = mclk */
- recalculate_fifo_timeout(pcdev, pcdev->mclk);
- else
- /* "Safe default" - 13MHz */
- recalculate_fifo_timeout(pcdev, 13000000);
-
- clk_prepare_enable(pcdev->clk);
-}
-
-static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
-{
- clk_disable_unprepare(pcdev->clk);
-}
-
-static irqreturn_t pxa_camera_irq(int irq, void *data)
-{
- struct pxa_camera_dev *pcdev = data;
- unsigned long status, cifr, cicr0;
- struct pxa_buffer *buf;
- struct videobuf_buffer *vb;
-
- status = __raw_readl(pcdev->base + CISR);
- dev_dbg(pcdev->soc_host.v4l2_dev.dev,
- "Camera interrupt status 0x%lx\n", status);
-
- if (!status)
- return IRQ_NONE;
-
- __raw_writel(status, pcdev->base + CISR);
-
- if (status & CISR_EOF) {
- /* Reset the FIFOs */
- cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
- __raw_writel(cifr, pcdev->base + CIFR);
-
- pcdev->active = list_first_entry(&pcdev->capture,
- struct pxa_buffer, vb.queue);
- vb = &pcdev->active->vb;
- buf = container_of(vb, struct pxa_buffer, vb);
- pxa_videobuf_set_actdma(pcdev, buf);
-
- pxa_dma_start_channels(pcdev);
-
- cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_EOFM;
- __raw_writel(cicr0, pcdev->base + CICR0);
- }
-
- return IRQ_HANDLED;
-}
-
-/*
- * The following two functions absolutely depend on the fact, that
- * there can be only one camera on PXA quick capture interface
- * Called with .video_lock held
- */
-static int pxa_camera_add_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct pxa_camera_dev *pcdev = ici->priv;
-
- if (pcdev->icd)
- return -EBUSY;
-
- pxa_camera_activate(pcdev);
-
- pcdev->icd = icd;
-
- dev_info(icd->parent, "PXA Camera driver attached to camera %d\n",
- icd->devnum);
-
- return 0;
-}
-
-/* Called with .video_lock held */
-static void pxa_camera_remove_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct pxa_camera_dev *pcdev = ici->priv;
-
- BUG_ON(icd != pcdev->icd);
-
- dev_info(icd->parent, "PXA Camera driver detached from camera %d\n",
- icd->devnum);
-
- /* disable capture, disable interrupts */
- __raw_writel(0x3ff, pcdev->base + CICR0);
-
- /* Stop DMA engine */
- DCSR(pcdev->dma_chans[0]) = 0;
- DCSR(pcdev->dma_chans[1]) = 0;
- DCSR(pcdev->dma_chans[2]) = 0;
-
- pxa_camera_deactivate(pcdev);
-
- pcdev->icd = NULL;
-}
-
-static int test_platform_param(struct pxa_camera_dev *pcdev,
- unsigned char buswidth, unsigned long *flags)
-{
- /*
- * Platform specified synchronization and pixel clock polarities are
- * only a recommendation and are only used during probing. The PXA270
- * quick capture interface supports both.
- */
- *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ?
- V4L2_MBUS_MASTER : V4L2_MBUS_SLAVE) |
- V4L2_MBUS_HSYNC_ACTIVE_HIGH |
- V4L2_MBUS_HSYNC_ACTIVE_LOW |
- V4L2_MBUS_VSYNC_ACTIVE_HIGH |
- V4L2_MBUS_VSYNC_ACTIVE_LOW |
- V4L2_MBUS_DATA_ACTIVE_HIGH |
- V4L2_MBUS_PCLK_SAMPLE_RISING |
- V4L2_MBUS_PCLK_SAMPLE_FALLING;
-
- /* If requested data width is supported by the platform, use it */
- if ((1 << (buswidth - 1)) & pcdev->width_flags)
- return 0;
-
- return -EINVAL;
-}
-
-static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
- unsigned long flags, __u32 pixfmt)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct pxa_camera_dev *pcdev = ici->priv;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- unsigned long dw, bpp;
- u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0, y_skip_top;
- int ret = v4l2_subdev_call(sd, sensor, g_skip_top_lines, &y_skip_top);
-
- if (ret < 0)
- y_skip_top = 0;
-
- /*
- * Datawidth is now guaranteed to be equal to one of the three values.
- * We fix bit-per-pixel equal to data-width...
- */
- switch (icd->current_fmt->host_fmt->bits_per_sample) {
- case 10:
- dw = 4;
- bpp = 0x40;
- break;
- case 9:
- dw = 3;
- bpp = 0x20;
- break;
- default:
- /*
- * Actually it can only be 8 now,
- * default is just to silence compiler warnings
- */
- case 8:
- dw = 2;
- bpp = 0;
- }
-
- if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
- cicr4 |= CICR4_PCLK_EN;
- if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
- cicr4 |= CICR4_MCLK_EN;
- if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
- cicr4 |= CICR4_PCP;
- if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
- cicr4 |= CICR4_HSP;
- if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
- cicr4 |= CICR4_VSP;
-
- cicr0 = __raw_readl(pcdev->base + CICR0);
- if (cicr0 & CICR0_ENB)
- __raw_writel(cicr0 & ~CICR0_ENB, pcdev->base + CICR0);
-
- cicr1 = CICR1_PPL_VAL(icd->user_width - 1) | bpp | dw;
-
- switch (pixfmt) {
- case V4L2_PIX_FMT_YUV422P:
- pcdev->channels = 3;
- cicr1 |= CICR1_YCBCR_F;
- /*
- * Normally, pxa bus wants as input UYVY format. We allow all
- * reorderings of the YUV422 format, as no processing is done,
- * and the YUV stream is just passed through without any
- * transformation. Note that UYVY is the only format that
- * should be used if pxa framebuffer Overlay2 is used.
- */
- case V4L2_PIX_FMT_UYVY:
- case V4L2_PIX_FMT_VYUY:
- case V4L2_PIX_FMT_YUYV:
- case V4L2_PIX_FMT_YVYU:
- cicr1 |= CICR1_COLOR_SP_VAL(2);
- break;
- case V4L2_PIX_FMT_RGB555:
- cicr1 |= CICR1_RGB_BPP_VAL(1) | CICR1_RGBT_CONV_VAL(2) |
- CICR1_TBIT | CICR1_COLOR_SP_VAL(1);
- break;
- case V4L2_PIX_FMT_RGB565:
- cicr1 |= CICR1_COLOR_SP_VAL(1) | CICR1_RGB_BPP_VAL(2);
- break;
- }
-
- cicr2 = 0;
- cicr3 = CICR3_LPF_VAL(icd->user_height - 1) |
- CICR3_BFW_VAL(min((u32)255, y_skip_top));
- cicr4 |= pcdev->mclk_divisor;
-
- __raw_writel(cicr1, pcdev->base + CICR1);
- __raw_writel(cicr2, pcdev->base + CICR2);
- __raw_writel(cicr3, pcdev->base + CICR3);
- __raw_writel(cicr4, pcdev->base + CICR4);
-
- /* CIF interrupts are not used, only DMA */
- cicr0 = (cicr0 & CICR0_ENB) | (pcdev->platform_flags & PXA_CAMERA_MASTER ?
- CICR0_SIM_MP : (CICR0_SL_CAP_EN | CICR0_SIM_SP));
- cicr0 |= CICR0_DMAEN | CICR0_IRQ_MASK;
- __raw_writel(cicr0, pcdev->base + CICR0);
-}
-
-static int pxa_camera_set_bus_param(struct soc_camera_device *icd)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct pxa_camera_dev *pcdev = ici->priv;
- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
- u32 pixfmt = icd->current_fmt->host_fmt->fourcc;
- unsigned long bus_flags, common_flags;
- int ret;
- struct pxa_cam *cam = icd->host_priv;
-
- ret = test_platform_param(pcdev, icd->current_fmt->host_fmt->bits_per_sample,
- &bus_flags);
- if (ret < 0)
- return ret;
-
- ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
- if (!ret) {
- common_flags = soc_mbus_config_compatible(&cfg,
- bus_flags);
- if (!common_flags) {
- dev_warn(icd->parent,
- "Flags incompatible: camera 0x%x, host 0x%lx\n",
- cfg.flags, bus_flags);
- return -EINVAL;
- }
- } else if (ret != -ENOIOCTLCMD) {
- return ret;
- } else {
- common_flags = bus_flags;
- }
-
- pcdev->channels = 1;
-
- /* Make choises, based on platform preferences */
- if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
- (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
- if (pcdev->platform_flags & PXA_CAMERA_HSP)
- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
- else
- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
- }
-
- if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
- (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
- if (pcdev->platform_flags & PXA_CAMERA_VSP)
- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
- else
- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
- }
-
- if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
- (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
- if (pcdev->platform_flags & PXA_CAMERA_PCP)
- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
- else
- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
- }
-
- cfg.flags = common_flags;
- ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
- if (ret < 0 && ret != -ENOIOCTLCMD) {
- dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
- common_flags, ret);
- return ret;
- }
-
- cam->flags = common_flags;
-
- pxa_camera_setup_cicr(icd, common_flags, pixfmt);
-
- return 0;
-}
-
-static int pxa_camera_try_bus_param(struct soc_camera_device *icd,
- unsigned char buswidth)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct pxa_camera_dev *pcdev = ici->priv;
- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
- unsigned long bus_flags, common_flags;
- int ret = test_platform_param(pcdev, buswidth, &bus_flags);
-
- if (ret < 0)
- return ret;
-
- ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
- if (!ret) {
- common_flags = soc_mbus_config_compatible(&cfg,
- bus_flags);
- if (!common_flags) {
- dev_warn(icd->parent,
- "Flags incompatible: camera 0x%x, host 0x%lx\n",
- cfg.flags, bus_flags);
- return -EINVAL;
- }
- } else if (ret == -ENOIOCTLCMD) {
- ret = 0;
- }
-
- return ret;
-}
-
-static const struct soc_mbus_pixelfmt pxa_camera_formats[] = {
- {
- .fourcc = V4L2_PIX_FMT_YUV422P,
- .name = "Planar YUV422 16 bit",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PLANAR_2Y_U_V,
- },
-};
-
-/* This will be corrected as we get more formats */
-static bool pxa_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
-{
- return fmt->packing == SOC_MBUS_PACKING_NONE ||
- (fmt->bits_per_sample == 8 &&
- fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
- (fmt->bits_per_sample > 8 &&
- fmt->packing == SOC_MBUS_PACKING_EXTEND16);
-}
-
-static int pxa_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
- struct soc_camera_format_xlate *xlate)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct device *dev = icd->parent;
- int formats = 0, ret;
- struct pxa_cam *cam;
- enum v4l2_mbus_pixelcode code;
- const struct soc_mbus_pixelfmt *fmt;
-
- ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
- if (ret < 0)
- /* No more formats */
- return 0;
-
- fmt = soc_mbus_get_fmtdesc(code);
- if (!fmt) {
- dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
- return 0;
- }
-
- /* This also checks support for the requested bits-per-sample */
- ret = pxa_camera_try_bus_param(icd, fmt->bits_per_sample);
- if (ret < 0)
- return 0;
-
- if (!icd->host_priv) {
- cam = kzalloc(sizeof(*cam), GFP_KERNEL);
- if (!cam)
- return -ENOMEM;
-
- icd->host_priv = cam;
- } else {
- cam = icd->host_priv;
- }
-
- switch (code) {
- case V4L2_MBUS_FMT_UYVY8_2X8:
- formats++;
- if (xlate) {
- xlate->host_fmt = &pxa_camera_formats[0];
- xlate->code = code;
- xlate++;
- dev_dbg(dev, "Providing format %s using code %d\n",
- pxa_camera_formats[0].name, code);
- }
- case V4L2_MBUS_FMT_VYUY8_2X8:
- case V4L2_MBUS_FMT_YUYV8_2X8:
- case V4L2_MBUS_FMT_YVYU8_2X8:
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
- if (xlate)
- dev_dbg(dev, "Providing format %s packed\n",
- fmt->name);
- break;
- default:
- if (!pxa_camera_packing_supported(fmt))
- return 0;
- if (xlate)
- dev_dbg(dev,
- "Providing format %s in pass-through mode\n",
- fmt->name);
- }
-
- /* Generic pass-through */
- formats++;
- if (xlate) {
- xlate->host_fmt = fmt;
- xlate->code = code;
- xlate++;
- }
-
- return formats;
-}
-
-static void pxa_camera_put_formats(struct soc_camera_device *icd)
-{
- kfree(icd->host_priv);
- icd->host_priv = NULL;
-}
-
-static int pxa_camera_check_frame(u32 width, u32 height)
-{
- /* limit to pxa hardware capabilities */
- return height < 32 || height > 2048 || width < 48 || width > 2048 ||
- (width & 0x01);
-}
-
-static int pxa_camera_set_crop(struct soc_camera_device *icd,
- struct v4l2_crop *a)
-{
- struct v4l2_rect *rect = &a->c;
- struct device *dev = icd->parent;
- struct soc_camera_host *ici = to_soc_camera_host(dev);
- struct pxa_camera_dev *pcdev = ici->priv;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct soc_camera_sense sense = {
- .master_clock = pcdev->mclk,
- .pixel_clock_max = pcdev->ciclk / 4,
- };
- struct v4l2_mbus_framefmt mf;
- struct pxa_cam *cam = icd->host_priv;
- u32 fourcc = icd->current_fmt->host_fmt->fourcc;
- int ret;
-
- /* If PCLK is used to latch data from the sensor, check sense */
- if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
- icd->sense = &sense;
-
- ret = v4l2_subdev_call(sd, video, s_crop, a);
-
- icd->sense = NULL;
-
- if (ret < 0) {
- dev_warn(dev, "Failed to crop to %ux%u@%u:%u\n",
- rect->width, rect->height, rect->left, rect->top);
- return ret;
- }
-
- ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- if (pxa_camera_check_frame(mf.width, mf.height)) {
- /*
- * Camera cropping produced a frame beyond our capabilities.
- * FIXME: just extract a subframe, that we can process.
- */
- v4l_bound_align_image(&mf.width, 48, 2048, 1,
- &mf.height, 32, 2048, 0,
- fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0);
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- if (pxa_camera_check_frame(mf.width, mf.height)) {
- dev_warn(icd->parent,
- "Inconsistent state. Use S_FMT to repair\n");
- return -EINVAL;
- }
- }
-
- if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
- if (sense.pixel_clock > sense.pixel_clock_max) {
- dev_err(dev,
- "pixel clock %lu set by the camera too high!",
- sense.pixel_clock);
- return -EIO;
- }
- recalculate_fifo_timeout(pcdev, sense.pixel_clock);
- }
-
- icd->user_width = mf.width;
- icd->user_height = mf.height;
-
- pxa_camera_setup_cicr(icd, cam->flags, fourcc);
-
- return ret;
-}
-
-static int pxa_camera_set_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct device *dev = icd->parent;
- struct soc_camera_host *ici = to_soc_camera_host(dev);
- struct pxa_camera_dev *pcdev = ici->priv;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate = NULL;
- struct soc_camera_sense sense = {
- .master_clock = pcdev->mclk,
- .pixel_clock_max = pcdev->ciclk / 4,
- };
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- int ret;
-
- xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
- if (!xlate) {
- dev_warn(dev, "Format %x not found\n", pix->pixelformat);
- return -EINVAL;
- }
-
- /* If PCLK is used to latch data from the sensor, check sense */
- if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
- /* The caller holds a mutex. */
- icd->sense = &sense;
-
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
-
- if (mf.code != xlate->code)
- return -EINVAL;
-
- icd->sense = NULL;
-
- if (ret < 0) {
- dev_warn(dev, "Failed to configure for format %x\n",
- pix->pixelformat);
- } else if (pxa_camera_check_frame(mf.width, mf.height)) {
- dev_warn(dev,
- "Camera driver produced an unsupported frame %dx%d\n",
- mf.width, mf.height);
- ret = -EINVAL;
- } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
- if (sense.pixel_clock > sense.pixel_clock_max) {
- dev_err(dev,
- "pixel clock %lu set by the camera too high!",
- sense.pixel_clock);
- return -EIO;
- }
- recalculate_fifo_timeout(pcdev, sense.pixel_clock);
- }
-
- if (ret < 0)
- return ret;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
- icd->current_fmt = xlate;
-
- return ret;
-}
-
-static int pxa_camera_try_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- __u32 pixfmt = pix->pixelformat;
- int ret;
-
- xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
- if (!xlate) {
- dev_warn(icd->parent, "Format %x not found\n", pixfmt);
- return -EINVAL;
- }
-
- /*
- * Limit to pxa hardware capabilities. YUV422P planar format requires
- * images size to be a multiple of 16 bytes. If not, zeros will be
- * inserted between Y and U planes, and U and V planes, which violates
- * the YUV422P standard.
- */
- v4l_bound_align_image(&pix->width, 48, 2048, 1,
- &pix->height, 32, 2048, 0,
- pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0);
-
- /* limit to sensor capabilities */
- mf.width = pix->width;
- mf.height = pix->height;
- /* Only progressive video supported so far */
- mf.field = V4L2_FIELD_NONE;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->colorspace = mf.colorspace;
-
- switch (mf.field) {
- case V4L2_FIELD_ANY:
- case V4L2_FIELD_NONE:
- pix->field = V4L2_FIELD_NONE;
- break;
- default:
- /* TODO: support interlaced at least in pass-through mode */
- dev_err(icd->parent, "Field type %d unsupported.\n",
- mf.field);
- return -EINVAL;
- }
-
- return ret;
-}
-
-static int pxa_camera_reqbufs(struct soc_camera_device *icd,
- struct v4l2_requestbuffers *p)
-{
- int i;
-
- /*
- * This is for locking debugging only. I removed spinlocks and now I
- * check whether .prepare is ever called on a linked buffer, or whether
- * a dma IRQ can occur for an in-work or unlinked buffer. Until now
- * it hadn't triggered
- */
- for (i = 0; i < p->count; i++) {
- struct pxa_buffer *buf = container_of(icd->vb_vidq.bufs[i],
- struct pxa_buffer, vb);
- buf->inwork = 0;
- INIT_LIST_HEAD(&buf->vb.queue);
- }
-
- return 0;
-}
-
-static unsigned int pxa_camera_poll(struct file *file, poll_table *pt)
-{
- struct soc_camera_device *icd = file->private_data;
- struct pxa_buffer *buf;
-
- buf = list_entry(icd->vb_vidq.stream.next, struct pxa_buffer,
- vb.stream);
-
- poll_wait(file, &buf->vb.done, pt);
-
- if (buf->vb.state == VIDEOBUF_DONE ||
- buf->vb.state == VIDEOBUF_ERROR)
- return POLLIN|POLLRDNORM;
-
- return 0;
-}
-
-static int pxa_camera_querycap(struct soc_camera_host *ici,
- struct v4l2_capability *cap)
-{
- /* cap->name is set by the firendly caller:-> */
- strlcpy(cap->card, pxa_cam_driver_description, sizeof(cap->card));
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-
- return 0;
-}
-
-static int pxa_camera_suspend(struct device *dev)
-{
- struct soc_camera_host *ici = to_soc_camera_host(dev);
- struct pxa_camera_dev *pcdev = ici->priv;
- int i = 0, ret = 0;
-
- pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR0);
- pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR1);
- pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR2);
- pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR3);
- pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR4);
-
- if (pcdev->icd) {
- struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->icd);
- ret = v4l2_subdev_call(sd, core, s_power, 0);
- if (ret == -ENOIOCTLCMD)
- ret = 0;
- }
-
- return ret;
-}
-
-static int pxa_camera_resume(struct device *dev)
-{
- struct soc_camera_host *ici = to_soc_camera_host(dev);
- struct pxa_camera_dev *pcdev = ici->priv;
- int i = 0, ret = 0;
-
- DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD;
- DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD;
- DRCMR(70) = pcdev->dma_chans[2] | DRCMR_MAPVLD;
-
- __raw_writel(pcdev->save_cicr[i++] & ~CICR0_ENB, pcdev->base + CICR0);
- __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR1);
- __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR2);
- __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR3);
- __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR4);
-
- if (pcdev->icd) {
- struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->icd);
- ret = v4l2_subdev_call(sd, core, s_power, 1);
- if (ret == -ENOIOCTLCMD)
- ret = 0;
- }
-
- /* Restart frame capture if active buffer exists */
- if (!ret && pcdev->active)
- pxa_camera_start_capture(pcdev);
-
- return ret;
-}
-
-static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
- .owner = THIS_MODULE,
- .add = pxa_camera_add_device,
- .remove = pxa_camera_remove_device,
- .set_crop = pxa_camera_set_crop,
- .get_formats = pxa_camera_get_formats,
- .put_formats = pxa_camera_put_formats,
- .set_fmt = pxa_camera_set_fmt,
- .try_fmt = pxa_camera_try_fmt,
- .init_videobuf = pxa_camera_init_videobuf,
- .reqbufs = pxa_camera_reqbufs,
- .poll = pxa_camera_poll,
- .querycap = pxa_camera_querycap,
- .set_bus_param = pxa_camera_set_bus_param,
-};
-
-static int __devinit pxa_camera_probe(struct platform_device *pdev)
-{
- struct pxa_camera_dev *pcdev;
- struct resource *res;
- void __iomem *base;
- int irq;
- int err = 0;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- irq = platform_get_irq(pdev, 0);
- if (!res || irq < 0) {
- err = -ENODEV;
- goto exit;
- }
-
- pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
- if (!pcdev) {
- dev_err(&pdev->dev, "Could not allocate pcdev\n");
- err = -ENOMEM;
- goto exit;
- }
-
- pcdev->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(pcdev->clk)) {
- err = PTR_ERR(pcdev->clk);
- goto exit_kfree;
- }
-
- pcdev->res = res;
-
- pcdev->pdata = pdev->dev.platform_data;
- pcdev->platform_flags = pcdev->pdata->flags;
- if (!(pcdev->platform_flags & (PXA_CAMERA_DATAWIDTH_8 |
- PXA_CAMERA_DATAWIDTH_9 | PXA_CAMERA_DATAWIDTH_10))) {
- /*
- * Platform hasn't set available data widths. This is bad.
- * Warn and use a default.
- */
- dev_warn(&pdev->dev, "WARNING! Platform hasn't set available "
- "data widths, using default 10 bit\n");
- pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10;
- }
- if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8)
- pcdev->width_flags = 1 << 7;
- if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9)
- pcdev->width_flags |= 1 << 8;
- if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10)
- pcdev->width_flags |= 1 << 9;
- pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
- if (!pcdev->mclk) {
- dev_warn(&pdev->dev,
- "mclk == 0! Please, fix your platform data. "
- "Using default 20MHz\n");
- pcdev->mclk = 20000000;
- }
-
- pcdev->mclk_divisor = mclk_get_divisor(pdev, pcdev);
-
- INIT_LIST_HEAD(&pcdev->capture);
- spin_lock_init(&pcdev->lock);
-
- /*
- * Request the regions.
- */
- if (!request_mem_region(res->start, resource_size(res),
- PXA_CAM_DRV_NAME)) {
- err = -EBUSY;
- goto exit_clk;
- }
-
- base = ioremap(res->start, resource_size(res));
- if (!base) {
- err = -ENOMEM;
- goto exit_release;
- }
- pcdev->irq = irq;
- pcdev->base = base;
-
- /* request dma */
- err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH,
- pxa_camera_dma_irq_y, pcdev);
- if (err < 0) {
- dev_err(&pdev->dev, "Can't request DMA for Y\n");
- goto exit_iounmap;
- }
- pcdev->dma_chans[0] = err;
- dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]);
-
- err = pxa_request_dma("CI_U", DMA_PRIO_HIGH,
- pxa_camera_dma_irq_u, pcdev);
- if (err < 0) {
- dev_err(&pdev->dev, "Can't request DMA for U\n");
- goto exit_free_dma_y;
- }
- pcdev->dma_chans[1] = err;
- dev_dbg(&pdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]);
-
- err = pxa_request_dma("CI_V", DMA_PRIO_HIGH,
- pxa_camera_dma_irq_v, pcdev);
- if (err < 0) {
- dev_err(&pdev->dev, "Can't request DMA for V\n");
- goto exit_free_dma_u;
- }
- pcdev->dma_chans[2] = err;
- dev_dbg(&pdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]);
-
- DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD;
- DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD;
- DRCMR(70) = pcdev->dma_chans[2] | DRCMR_MAPVLD;
-
- /* request irq */
- err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME,
- pcdev);
- if (err) {
- dev_err(&pdev->dev, "Camera interrupt register failed \n");
- goto exit_free_dma;
- }
-
- pcdev->soc_host.drv_name = PXA_CAM_DRV_NAME;
- pcdev->soc_host.ops = &pxa_soc_camera_host_ops;
- pcdev->soc_host.priv = pcdev;
- pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
- pcdev->soc_host.nr = pdev->id;
-
- err = soc_camera_host_register(&pcdev->soc_host);
- if (err)
- goto exit_free_irq;
-
- return 0;
-
-exit_free_irq:
- free_irq(pcdev->irq, pcdev);
-exit_free_dma:
- pxa_free_dma(pcdev->dma_chans[2]);
-exit_free_dma_u:
- pxa_free_dma(pcdev->dma_chans[1]);
-exit_free_dma_y:
- pxa_free_dma(pcdev->dma_chans[0]);
-exit_iounmap:
- iounmap(base);
-exit_release:
- release_mem_region(res->start, resource_size(res));
-exit_clk:
- clk_put(pcdev->clk);
-exit_kfree:
- kfree(pcdev);
-exit:
- return err;
-}
-
-static int __devexit pxa_camera_remove(struct platform_device *pdev)
-{
- struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
- struct pxa_camera_dev *pcdev = container_of(soc_host,
- struct pxa_camera_dev, soc_host);
- struct resource *res;
-
- clk_put(pcdev->clk);
-
- pxa_free_dma(pcdev->dma_chans[0]);
- pxa_free_dma(pcdev->dma_chans[1]);
- pxa_free_dma(pcdev->dma_chans[2]);
- free_irq(pcdev->irq, pcdev);
-
- soc_camera_host_unregister(soc_host);
-
- iounmap(pcdev->base);
-
- res = pcdev->res;
- release_mem_region(res->start, resource_size(res));
-
- kfree(pcdev);
-
- dev_info(&pdev->dev, "PXA Camera driver unloaded\n");
-
- return 0;
-}
-
-static struct dev_pm_ops pxa_camera_pm = {
- .suspend = pxa_camera_suspend,
- .resume = pxa_camera_resume,
-};
-
-static struct platform_driver pxa_camera_driver = {
- .driver = {
- .name = PXA_CAM_DRV_NAME,
- .pm = &pxa_camera_pm,
- },
- .probe = pxa_camera_probe,
- .remove = __devexit_p(pxa_camera_remove),
-};
-
-module_platform_driver(pxa_camera_driver);
-
-MODULE_DESCRIPTION("PXA27x SoC Camera Host driver");
-MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(PXA_CAM_VERSION);
-MODULE_ALIAS("platform:" PXA_CAM_DRV_NAME);
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c
deleted file mode 100644
index f6419b22c25..00000000000
--- a/drivers/media/video/rj54n1cb0c.c
+++ /dev/null
@@ -1,1414 +0,0 @@
-/*
- * Driver for RJ54N1CB0C CMOS Image Sensor from Sharp
- *
- * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/videodev2.h>
-#include <linux/module.h>
-
-#include <media/rj54n1cb0c.h>
-#include <media/soc_camera.h>
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-
-#define RJ54N1_DEV_CODE 0x0400
-#define RJ54N1_DEV_CODE2 0x0401
-#define RJ54N1_OUT_SEL 0x0403
-#define RJ54N1_XY_OUTPUT_SIZE_S_H 0x0404
-#define RJ54N1_X_OUTPUT_SIZE_S_L 0x0405
-#define RJ54N1_Y_OUTPUT_SIZE_S_L 0x0406
-#define RJ54N1_XY_OUTPUT_SIZE_P_H 0x0407
-#define RJ54N1_X_OUTPUT_SIZE_P_L 0x0408
-#define RJ54N1_Y_OUTPUT_SIZE_P_L 0x0409
-#define RJ54N1_LINE_LENGTH_PCK_S_H 0x040a
-#define RJ54N1_LINE_LENGTH_PCK_S_L 0x040b
-#define RJ54N1_LINE_LENGTH_PCK_P_H 0x040c
-#define RJ54N1_LINE_LENGTH_PCK_P_L 0x040d
-#define RJ54N1_RESIZE_N 0x040e
-#define RJ54N1_RESIZE_N_STEP 0x040f
-#define RJ54N1_RESIZE_STEP 0x0410
-#define RJ54N1_RESIZE_HOLD_H 0x0411
-#define RJ54N1_RESIZE_HOLD_L 0x0412
-#define RJ54N1_H_OBEN_OFS 0x0413
-#define RJ54N1_V_OBEN_OFS 0x0414
-#define RJ54N1_RESIZE_CONTROL 0x0415
-#define RJ54N1_STILL_CONTROL 0x0417
-#define RJ54N1_INC_USE_SEL_H 0x0425
-#define RJ54N1_INC_USE_SEL_L 0x0426
-#define RJ54N1_MIRROR_STILL_MODE 0x0427
-#define RJ54N1_INIT_START 0x0428
-#define RJ54N1_SCALE_1_2_LEV 0x0429
-#define RJ54N1_SCALE_4_LEV 0x042a
-#define RJ54N1_Y_GAIN 0x04d8
-#define RJ54N1_APT_GAIN_UP 0x04fa
-#define RJ54N1_RA_SEL_UL 0x0530
-#define RJ54N1_BYTE_SWAP 0x0531
-#define RJ54N1_OUT_SIGPO 0x053b
-#define RJ54N1_WB_SEL_WEIGHT_I 0x054e
-#define RJ54N1_BIT8_WB 0x0569
-#define RJ54N1_HCAPS_WB 0x056a
-#define RJ54N1_VCAPS_WB 0x056b
-#define RJ54N1_HCAPE_WB 0x056c
-#define RJ54N1_VCAPE_WB 0x056d
-#define RJ54N1_EXPOSURE_CONTROL 0x058c
-#define RJ54N1_FRAME_LENGTH_S_H 0x0595
-#define RJ54N1_FRAME_LENGTH_S_L 0x0596
-#define RJ54N1_FRAME_LENGTH_P_H 0x0597
-#define RJ54N1_FRAME_LENGTH_P_L 0x0598
-#define RJ54N1_PEAK_H 0x05b7
-#define RJ54N1_PEAK_50 0x05b8
-#define RJ54N1_PEAK_60 0x05b9
-#define RJ54N1_PEAK_DIFF 0x05ba
-#define RJ54N1_IOC 0x05ef
-#define RJ54N1_TG_BYPASS 0x0700
-#define RJ54N1_PLL_L 0x0701
-#define RJ54N1_PLL_N 0x0702
-#define RJ54N1_PLL_EN 0x0704
-#define RJ54N1_RATIO_TG 0x0706
-#define RJ54N1_RATIO_T 0x0707
-#define RJ54N1_RATIO_R 0x0708
-#define RJ54N1_RAMP_TGCLK_EN 0x0709
-#define RJ54N1_OCLK_DSP 0x0710
-#define RJ54N1_RATIO_OP 0x0711
-#define RJ54N1_RATIO_O 0x0712
-#define RJ54N1_OCLK_SEL_EN 0x0713
-#define RJ54N1_CLK_RST 0x0717
-#define RJ54N1_RESET_STANDBY 0x0718
-#define RJ54N1_FWFLG 0x07fe
-
-#define E_EXCLK (1 << 7)
-#define SOFT_STDBY (1 << 4)
-#define SEN_RSTX (1 << 2)
-#define TG_RSTX (1 << 1)
-#define DSP_RSTX (1 << 0)
-
-#define RESIZE_HOLD_SEL (1 << 2)
-#define RESIZE_GO (1 << 1)
-
-/*
- * When cropping, the camera automatically centers the cropped region, there
- * doesn't seem to be a way to specify an explicit location of the rectangle.
- */
-#define RJ54N1_COLUMN_SKIP 0
-#define RJ54N1_ROW_SKIP 0
-#define RJ54N1_MAX_WIDTH 1600
-#define RJ54N1_MAX_HEIGHT 1200
-
-#define PLL_L 2
-#define PLL_N 0x31
-
-/* I2C addresses: 0x50, 0x51, 0x60, 0x61 */
-
-/* RJ54N1CB0C has only one fixed colorspace per pixelcode */
-struct rj54n1_datafmt {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
-};
-
-/* Find a data format by a pixel code in an array */
-static const struct rj54n1_datafmt *rj54n1_find_datafmt(
- enum v4l2_mbus_pixelcode code, const struct rj54n1_datafmt *fmt,
- int n)
-{
- int i;
- for (i = 0; i < n; i++)
- if (fmt[i].code == code)
- return fmt + i;
-
- return NULL;
-}
-
-static const struct rj54n1_datafmt rj54n1_colour_fmts[] = {
- {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG},
- {V4L2_MBUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG},
- {V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
-};
-
-struct rj54n1_clock_div {
- u8 ratio_tg; /* can be 0 or an odd number */
- u8 ratio_t;
- u8 ratio_r;
- u8 ratio_op;
- u8 ratio_o;
-};
-
-struct rj54n1 {
- struct v4l2_subdev subdev;
- struct v4l2_ctrl_handler hdl;
- struct rj54n1_clock_div clk_div;
- const struct rj54n1_datafmt *fmt;
- struct v4l2_rect rect; /* Sensor window */
- unsigned int tgclk_mhz;
- bool auto_wb;
- unsigned short width; /* Output window */
- unsigned short height;
- unsigned short resize; /* Sensor * 1024 / resize = Output */
- unsigned short scale;
- u8 bank;
-};
-
-struct rj54n1_reg_val {
- u16 reg;
- u8 val;
-};
-
-static const struct rj54n1_reg_val bank_4[] = {
- {0x417, 0},
- {0x42c, 0},
- {0x42d, 0xf0},
- {0x42e, 0},
- {0x42f, 0x50},
- {0x430, 0xf5},
- {0x431, 0x16},
- {0x432, 0x20},
- {0x433, 0},
- {0x434, 0xc8},
- {0x43c, 8},
- {0x43e, 0x90},
- {0x445, 0x83},
- {0x4ba, 0x58},
- {0x4bb, 4},
- {0x4bc, 0x20},
- {0x4db, 4},
- {0x4fe, 2},
-};
-
-static const struct rj54n1_reg_val bank_5[] = {
- {0x514, 0},
- {0x516, 0},
- {0x518, 0},
- {0x51a, 0},
- {0x51d, 0xff},
- {0x56f, 0x28},
- {0x575, 0x40},
- {0x5bc, 0x48},
- {0x5c1, 6},
- {0x5e5, 0x11},
- {0x5e6, 0x43},
- {0x5e7, 0x33},
- {0x5e8, 0x21},
- {0x5e9, 0x30},
- {0x5ea, 0x0},
- {0x5eb, 0xa5},
- {0x5ec, 0xff},
- {0x5fe, 2},
-};
-
-static const struct rj54n1_reg_val bank_7[] = {
- {0x70a, 0},
- {0x714, 0xff},
- {0x715, 0xff},
- {0x716, 0x1f},
- {0x7FE, 2},
-};
-
-static const struct rj54n1_reg_val bank_8[] = {
- {0x800, 0x00},
- {0x801, 0x01},
- {0x802, 0x61},
- {0x805, 0x00},
- {0x806, 0x00},
- {0x807, 0x00},
- {0x808, 0x00},
- {0x809, 0x01},
- {0x80A, 0x61},
- {0x80B, 0x00},
- {0x80C, 0x01},
- {0x80D, 0x00},
- {0x80E, 0x00},
- {0x80F, 0x00},
- {0x810, 0x00},
- {0x811, 0x01},
- {0x812, 0x61},
- {0x813, 0x00},
- {0x814, 0x11},
- {0x815, 0x00},
- {0x816, 0x41},
- {0x817, 0x00},
- {0x818, 0x51},
- {0x819, 0x01},
- {0x81A, 0x1F},
- {0x81B, 0x00},
- {0x81C, 0x01},
- {0x81D, 0x00},
- {0x81E, 0x11},
- {0x81F, 0x00},
- {0x820, 0x41},
- {0x821, 0x00},
- {0x822, 0x51},
- {0x823, 0x00},
- {0x824, 0x00},
- {0x825, 0x00},
- {0x826, 0x47},
- {0x827, 0x01},
- {0x828, 0x4F},
- {0x829, 0x00},
- {0x82A, 0x00},
- {0x82B, 0x00},
- {0x82C, 0x30},
- {0x82D, 0x00},
- {0x82E, 0x40},
- {0x82F, 0x00},
- {0x830, 0xB3},
- {0x831, 0x00},
- {0x832, 0xE3},
- {0x833, 0x00},
- {0x834, 0x00},
- {0x835, 0x00},
- {0x836, 0x00},
- {0x837, 0x00},
- {0x838, 0x00},
- {0x839, 0x01},
- {0x83A, 0x61},
- {0x83B, 0x00},
- {0x83C, 0x01},
- {0x83D, 0x00},
- {0x83E, 0x00},
- {0x83F, 0x00},
- {0x840, 0x00},
- {0x841, 0x01},
- {0x842, 0x61},
- {0x843, 0x00},
- {0x844, 0x1D},
- {0x845, 0x00},
- {0x846, 0x00},
- {0x847, 0x00},
- {0x848, 0x00},
- {0x849, 0x01},
- {0x84A, 0x1F},
- {0x84B, 0x00},
- {0x84C, 0x05},
- {0x84D, 0x00},
- {0x84E, 0x19},
- {0x84F, 0x01},
- {0x850, 0x21},
- {0x851, 0x01},
- {0x852, 0x5D},
- {0x853, 0x00},
- {0x854, 0x00},
- {0x855, 0x00},
- {0x856, 0x19},
- {0x857, 0x01},
- {0x858, 0x21},
- {0x859, 0x00},
- {0x85A, 0x00},
- {0x85B, 0x00},
- {0x85C, 0x00},
- {0x85D, 0x00},
- {0x85E, 0x00},
- {0x85F, 0x00},
- {0x860, 0xB3},
- {0x861, 0x00},
- {0x862, 0xE3},
- {0x863, 0x00},
- {0x864, 0x00},
- {0x865, 0x00},
- {0x866, 0x00},
- {0x867, 0x00},
- {0x868, 0x00},
- {0x869, 0xE2},
- {0x86A, 0x00},
- {0x86B, 0x01},
- {0x86C, 0x06},
- {0x86D, 0x00},
- {0x86E, 0x00},
- {0x86F, 0x00},
- {0x870, 0x60},
- {0x871, 0x8C},
- {0x872, 0x10},
- {0x873, 0x00},
- {0x874, 0xE0},
- {0x875, 0x00},
- {0x876, 0x27},
- {0x877, 0x01},
- {0x878, 0x00},
- {0x879, 0x00},
- {0x87A, 0x00},
- {0x87B, 0x03},
- {0x87C, 0x00},
- {0x87D, 0x00},
- {0x87E, 0x00},
- {0x87F, 0x00},
- {0x880, 0x00},
- {0x881, 0x00},
- {0x882, 0x00},
- {0x883, 0x00},
- {0x884, 0x00},
- {0x885, 0x00},
- {0x886, 0xF8},
- {0x887, 0x00},
- {0x888, 0x03},
- {0x889, 0x00},
- {0x88A, 0x64},
- {0x88B, 0x00},
- {0x88C, 0x03},
- {0x88D, 0x00},
- {0x88E, 0xB1},
- {0x88F, 0x00},
- {0x890, 0x03},
- {0x891, 0x01},
- {0x892, 0x1D},
- {0x893, 0x00},
- {0x894, 0x03},
- {0x895, 0x01},
- {0x896, 0x4B},
- {0x897, 0x00},
- {0x898, 0xE5},
- {0x899, 0x00},
- {0x89A, 0x01},
- {0x89B, 0x00},
- {0x89C, 0x01},
- {0x89D, 0x04},
- {0x89E, 0xC8},
- {0x89F, 0x00},
- {0x8A0, 0x01},
- {0x8A1, 0x01},
- {0x8A2, 0x61},
- {0x8A3, 0x00},
- {0x8A4, 0x01},
- {0x8A5, 0x00},
- {0x8A6, 0x00},
- {0x8A7, 0x00},
- {0x8A8, 0x00},
- {0x8A9, 0x00},
- {0x8AA, 0x7F},
- {0x8AB, 0x03},
- {0x8AC, 0x00},
- {0x8AD, 0x00},
- {0x8AE, 0x00},
- {0x8AF, 0x00},
- {0x8B0, 0x00},
- {0x8B1, 0x00},
- {0x8B6, 0x00},
- {0x8B7, 0x01},
- {0x8B8, 0x00},
- {0x8B9, 0x00},
- {0x8BA, 0x02},
- {0x8BB, 0x00},
- {0x8BC, 0xFF},
- {0x8BD, 0x00},
- {0x8FE, 2},
-};
-
-static const struct rj54n1_reg_val bank_10[] = {
- {0x10bf, 0x69}
-};
-
-/* Clock dividers - these are default register values, divider = register + 1 */
-static const struct rj54n1_clock_div clk_div = {
- .ratio_tg = 3 /* default: 5 */,
- .ratio_t = 4 /* default: 1 */,
- .ratio_r = 4 /* default: 0 */,
- .ratio_op = 1 /* default: 5 */,
- .ratio_o = 9 /* default: 0 */,
-};
-
-static struct rj54n1 *to_rj54n1(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client), struct rj54n1, subdev);
-}
-
-static int reg_read(struct i2c_client *client, const u16 reg)
-{
- struct rj54n1 *rj54n1 = to_rj54n1(client);
- int ret;
-
- /* set bank */
- if (rj54n1->bank != reg >> 8) {
- dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8);
- ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8);
- if (ret < 0)
- return ret;
- rj54n1->bank = reg >> 8;
- }
- return i2c_smbus_read_byte_data(client, reg & 0xff);
-}
-
-static int reg_write(struct i2c_client *client, const u16 reg,
- const u8 data)
-{
- struct rj54n1 *rj54n1 = to_rj54n1(client);
- int ret;
-
- /* set bank */
- if (rj54n1->bank != reg >> 8) {
- dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8);
- ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8);
- if (ret < 0)
- return ret;
- rj54n1->bank = reg >> 8;
- }
- dev_dbg(&client->dev, "[0x%x] = 0x%x\n", reg & 0xff, data);
- return i2c_smbus_write_byte_data(client, reg & 0xff, data);
-}
-
-static int reg_set(struct i2c_client *client, const u16 reg,
- const u8 data, const u8 mask)
-{
- int ret;
-
- ret = reg_read(client, reg);
- if (ret < 0)
- return ret;
- return reg_write(client, reg, (ret & ~mask) | (data & mask));
-}
-
-static int reg_write_multiple(struct i2c_client *client,
- const struct rj54n1_reg_val *rv, const int n)
-{
- int i, ret;
-
- for (i = 0; i < n; i++) {
- ret = reg_write(client, rv->reg, rv->val);
- if (ret < 0)
- return ret;
- rv++;
- }
-
- return 0;
-}
-
-static int rj54n1_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index >= ARRAY_SIZE(rj54n1_colour_fmts))
- return -EINVAL;
-
- *code = rj54n1_colour_fmts[index].code;
- return 0;
-}
-
-static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- /* Switch between preview and still shot modes */
- return reg_set(client, RJ54N1_STILL_CONTROL, (!enable) << 7, 0x80);
-}
-
-static int rj54n1_set_rect(struct i2c_client *client,
- u16 reg_x, u16 reg_y, u16 reg_xy,
- u32 width, u32 height)
-{
- int ret;
-
- ret = reg_write(client, reg_xy,
- ((width >> 4) & 0x70) |
- ((height >> 8) & 7));
-
- if (!ret)
- ret = reg_write(client, reg_x, width & 0xff);
- if (!ret)
- ret = reg_write(client, reg_y, height & 0xff);
-
- return ret;
-}
-
-/*
- * Some commands, specifically certain initialisation sequences, require
- * a commit operation.
- */
-static int rj54n1_commit(struct i2c_client *client)
-{
- int ret = reg_write(client, RJ54N1_INIT_START, 1);
- msleep(10);
- if (!ret)
- ret = reg_write(client, RJ54N1_INIT_START, 0);
- return ret;
-}
-
-static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h,
- s32 *out_w, s32 *out_h);
-
-static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct rj54n1 *rj54n1 = to_rj54n1(client);
- struct v4l2_rect *rect = &a->c;
- int dummy = 0, output_w, output_h,
- input_w = rect->width, input_h = rect->height;
- int ret;
-
- /* arbitrary minimum width and height, edges unimportant */
- soc_camera_limit_side(&dummy, &input_w,
- RJ54N1_COLUMN_SKIP, 8, RJ54N1_MAX_WIDTH);
-
- soc_camera_limit_side(&dummy, &input_h,
- RJ54N1_ROW_SKIP, 8, RJ54N1_MAX_HEIGHT);
-
- output_w = (input_w * 1024 + rj54n1->resize / 2) / rj54n1->resize;
- output_h = (input_h * 1024 + rj54n1->resize / 2) / rj54n1->resize;
-
- dev_dbg(&client->dev, "Scaling for %dx%d : %u = %dx%d\n",
- input_w, input_h, rj54n1->resize, output_w, output_h);
-
- ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h);
- if (ret < 0)
- return ret;
-
- rj54n1->width = output_w;
- rj54n1->height = output_h;
- rj54n1->resize = ret;
- rj54n1->rect.width = input_w;
- rj54n1->rect.height = input_h;
-
- return 0;
-}
-
-static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct rj54n1 *rj54n1 = to_rj54n1(client);
-
- a->c = rj54n1->rect;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = RJ54N1_COLUMN_SKIP;
- a->bounds.top = RJ54N1_ROW_SKIP;
- a->bounds.width = RJ54N1_MAX_WIDTH;
- a->bounds.height = RJ54N1_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int rj54n1_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct rj54n1 *rj54n1 = to_rj54n1(client);
-
- mf->code = rj54n1->fmt->code;
- mf->colorspace = rj54n1->fmt->colorspace;
- mf->field = V4L2_FIELD_NONE;
- mf->width = rj54n1->width;
- mf->height = rj54n1->height;
-
- return 0;
-}
-
-/*
- * The actual geometry configuration routine. It scales the input window into
- * the output one, updates the window sizes and returns an error or the resize
- * coefficient on success. Note: we only use the "Fixed Scaling" on this camera.
- */
-static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h,
- s32 *out_w, s32 *out_h)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct rj54n1 *rj54n1 = to_rj54n1(client);
- unsigned int skip, resize, input_w = *in_w, input_h = *in_h,
- output_w = *out_w, output_h = *out_h;
- u16 inc_sel, wb_bit8, wb_left, wb_right, wb_top, wb_bottom;
- unsigned int peak, peak_50, peak_60;
- int ret;
-
- /*
- * We have a problem with crops, where the window is larger than 512x384
- * and output window is larger than a half of the input one. In this
- * case we have to either reduce the input window to equal or below
- * 512x384 or the output window to equal or below 1/2 of the input.
- */
- if (output_w > max(512U, input_w / 2)) {
- if (2 * output_w > RJ54N1_MAX_WIDTH) {
- input_w = RJ54N1_MAX_WIDTH;
- output_w = RJ54N1_MAX_WIDTH / 2;
- } else {
- input_w = output_w * 2;
- }
-
- dev_dbg(&client->dev, "Adjusted output width: in %u, out %u\n",
- input_w, output_w);
- }
-
- if (output_h > max(384U, input_h / 2)) {
- if (2 * output_h > RJ54N1_MAX_HEIGHT) {
- input_h = RJ54N1_MAX_HEIGHT;
- output_h = RJ54N1_MAX_HEIGHT / 2;
- } else {
- input_h = output_h * 2;
- }
-
- dev_dbg(&client->dev, "Adjusted output height: in %u, out %u\n",
- input_h, output_h);
- }
-
- /* Idea: use the read mode for snapshots, handle separate geometries */
- ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_S_L,
- RJ54N1_Y_OUTPUT_SIZE_S_L,
- RJ54N1_XY_OUTPUT_SIZE_S_H, output_w, output_h);
- if (!ret)
- ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_P_L,
- RJ54N1_Y_OUTPUT_SIZE_P_L,
- RJ54N1_XY_OUTPUT_SIZE_P_H, output_w, output_h);
-
- if (ret < 0)
- return ret;
-
- if (output_w > input_w && output_h > input_h) {
- input_w = output_w;
- input_h = output_h;
-
- resize = 1024;
- } else {
- unsigned int resize_x, resize_y;
- resize_x = (input_w * 1024 + output_w / 2) / output_w;
- resize_y = (input_h * 1024 + output_h / 2) / output_h;
-
- /* We want max(resize_x, resize_y), check if it still fits */
- if (resize_x > resize_y &&
- (output_h * resize_x + 512) / 1024 > RJ54N1_MAX_HEIGHT)
- resize = (RJ54N1_MAX_HEIGHT * 1024 + output_h / 2) /
- output_h;
- else if (resize_y > resize_x &&
- (output_w * resize_y + 512) / 1024 > RJ54N1_MAX_WIDTH)
- resize = (RJ54N1_MAX_WIDTH * 1024 + output_w / 2) /
- output_w;
- else
- resize = max(resize_x, resize_y);
-
- /* Prohibited value ranges */
- switch (resize) {
- case 2040 ... 2047:
- resize = 2039;
- break;
- case 4080 ... 4095:
- resize = 4079;
- break;
- case 8160 ... 8191:
- resize = 8159;
- break;
- case 16320 ... 16384:
- resize = 16319;
- }
- }
-
- /* Set scaling */
- ret = reg_write(client, RJ54N1_RESIZE_HOLD_L, resize & 0xff);
- if (!ret)
- ret = reg_write(client, RJ54N1_RESIZE_HOLD_H, resize >> 8);
-
- if (ret < 0)
- return ret;
-
- /*
- * Configure a skipping bitmask. The sensor will select a skipping value
- * among set bits automatically. This is very unclear in the datasheet
- * too. I was told, in this register one enables all skipping values,
- * that are required for a specific resize, and the camera selects
- * automatically, which ones to use. But it is unclear how to identify,
- * which cropping values are needed. Secondly, why don't we just set all
- * bits and let the camera choose? Would it increase processing time and
- * reduce the framerate? Using 0xfffc for INC_USE_SEL doesn't seem to
- * improve the image quality or stability for larger frames (see comment
- * above), but I didn't check the framerate.
- */
- skip = min(resize / 1024, 15U);
-
- inc_sel = 1 << skip;
-
- if (inc_sel <= 2)
- inc_sel = 0xc;
- else if (resize & 1023 && skip < 15)
- inc_sel |= 1 << (skip + 1);
-
- ret = reg_write(client, RJ54N1_INC_USE_SEL_L, inc_sel & 0xfc);
- if (!ret)
- ret = reg_write(client, RJ54N1_INC_USE_SEL_H, inc_sel >> 8);
-
- if (!rj54n1->auto_wb) {
- /* Auto white balance window */
- wb_left = output_w / 16;
- wb_right = (3 * output_w / 4 - 3) / 4;
- wb_top = output_h / 16;
- wb_bottom = (3 * output_h / 4 - 3) / 4;
- wb_bit8 = ((wb_left >> 2) & 0x40) | ((wb_top >> 4) & 0x10) |
- ((wb_right >> 6) & 4) | ((wb_bottom >> 8) & 1);
-
- if (!ret)
- ret = reg_write(client, RJ54N1_BIT8_WB, wb_bit8);
- if (!ret)
- ret = reg_write(client, RJ54N1_HCAPS_WB, wb_left);
- if (!ret)
- ret = reg_write(client, RJ54N1_VCAPS_WB, wb_top);
- if (!ret)
- ret = reg_write(client, RJ54N1_HCAPE_WB, wb_right);
- if (!ret)
- ret = reg_write(client, RJ54N1_VCAPE_WB, wb_bottom);
- }
-
- /* Antiflicker */
- peak = 12 * RJ54N1_MAX_WIDTH * (1 << 14) * resize / rj54n1->tgclk_mhz /
- 10000;
- peak_50 = peak / 6;
- peak_60 = peak / 5;
-
- if (!ret)
- ret = reg_write(client, RJ54N1_PEAK_H,
- ((peak_50 >> 4) & 0xf0) | (peak_60 >> 8));
- if (!ret)
- ret = reg_write(client, RJ54N1_PEAK_50, peak_50);
- if (!ret)
- ret = reg_write(client, RJ54N1_PEAK_60, peak_60);
- if (!ret)
- ret = reg_write(client, RJ54N1_PEAK_DIFF, peak / 150);
-
- /* Start resizing */
- if (!ret)
- ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
- RESIZE_HOLD_SEL | RESIZE_GO | 1);
-
- if (ret < 0)
- return ret;
-
- /* Constant taken from manufacturer's example */
- msleep(230);
-
- ret = reg_write(client, RJ54N1_RESIZE_CONTROL, RESIZE_HOLD_SEL | 1);
- if (ret < 0)
- return ret;
-
- *in_w = (output_w * resize + 512) / 1024;
- *in_h = (output_h * resize + 512) / 1024;
- *out_w = output_w;
- *out_h = output_h;
-
- dev_dbg(&client->dev, "Scaled for %dx%d : %u = %ux%u, skip %u\n",
- *in_w, *in_h, resize, output_w, output_h, skip);
-
- return resize;
-}
-
-static int rj54n1_set_clock(struct i2c_client *client)
-{
- struct rj54n1 *rj54n1 = to_rj54n1(client);
- int ret;
-
- /* Enable external clock */
- ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK | SOFT_STDBY);
- /* Leave stand-by. Note: use this when implementing suspend / resume */
- if (!ret)
- ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK);
-
- if (!ret)
- ret = reg_write(client, RJ54N1_PLL_L, PLL_L);
- if (!ret)
- ret = reg_write(client, RJ54N1_PLL_N, PLL_N);
-
- /* TGCLK dividers */
- if (!ret)
- ret = reg_write(client, RJ54N1_RATIO_TG,
- rj54n1->clk_div.ratio_tg);
- if (!ret)
- ret = reg_write(client, RJ54N1_RATIO_T,
- rj54n1->clk_div.ratio_t);
- if (!ret)
- ret = reg_write(client, RJ54N1_RATIO_R,
- rj54n1->clk_div.ratio_r);
-
- /* Enable TGCLK & RAMP */
- if (!ret)
- ret = reg_write(client, RJ54N1_RAMP_TGCLK_EN, 3);
-
- /* Disable clock output */
- if (!ret)
- ret = reg_write(client, RJ54N1_OCLK_DSP, 0);
-
- /* Set divisors */
- if (!ret)
- ret = reg_write(client, RJ54N1_RATIO_OP,
- rj54n1->clk_div.ratio_op);
- if (!ret)
- ret = reg_write(client, RJ54N1_RATIO_O,
- rj54n1->clk_div.ratio_o);
-
- /* Enable OCLK */
- if (!ret)
- ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1);
-
- /* Use PLL for Timing Generator, write 2 to reserved bits */
- if (!ret)
- ret = reg_write(client, RJ54N1_TG_BYPASS, 2);
-
- /* Take sensor out of reset */
- if (!ret)
- ret = reg_write(client, RJ54N1_RESET_STANDBY,
- E_EXCLK | SEN_RSTX);
- /* Enable PLL */
- if (!ret)
- ret = reg_write(client, RJ54N1_PLL_EN, 1);
-
- /* Wait for PLL to stabilise */
- msleep(10);
-
- /* Enable clock to frequency divider */
- if (!ret)
- ret = reg_write(client, RJ54N1_CLK_RST, 1);
-
- if (!ret)
- ret = reg_read(client, RJ54N1_CLK_RST);
- if (ret != 1) {
- dev_err(&client->dev,
- "Resetting RJ54N1CB0C clock failed: %d!\n", ret);
- return -EIO;
- }
-
- /* Start the PLL */
- ret = reg_set(client, RJ54N1_OCLK_DSP, 1, 1);
-
- /* Enable OCLK */
- if (!ret)
- ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1);
-
- return ret;
-}
-
-static int rj54n1_reg_init(struct i2c_client *client)
-{
- struct rj54n1 *rj54n1 = to_rj54n1(client);
- int ret = rj54n1_set_clock(client);
-
- if (!ret)
- ret = reg_write_multiple(client, bank_7, ARRAY_SIZE(bank_7));
- if (!ret)
- ret = reg_write_multiple(client, bank_10, ARRAY_SIZE(bank_10));
-
- /* Set binning divisors */
- if (!ret)
- ret = reg_write(client, RJ54N1_SCALE_1_2_LEV, 3 | (7 << 4));
- if (!ret)
- ret = reg_write(client, RJ54N1_SCALE_4_LEV, 0xf);
-
- /* Switch to fixed resize mode */
- if (!ret)
- ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
- RESIZE_HOLD_SEL | 1);
-
- /* Set gain */
- if (!ret)
- ret = reg_write(client, RJ54N1_Y_GAIN, 0x84);
-
- /*
- * Mirror the image back: default is upside down and left-to-right...
- * Set manual preview / still shot switching
- */
- if (!ret)
- ret = reg_write(client, RJ54N1_MIRROR_STILL_MODE, 0x27);
-
- if (!ret)
- ret = reg_write_multiple(client, bank_4, ARRAY_SIZE(bank_4));
-
- /* Auto exposure area */
- if (!ret)
- ret = reg_write(client, RJ54N1_EXPOSURE_CONTROL, 0x80);
- /* Check current auto WB config */
- if (!ret)
- ret = reg_read(client, RJ54N1_WB_SEL_WEIGHT_I);
- if (ret >= 0) {
- rj54n1->auto_wb = ret & 0x80;
- ret = reg_write_multiple(client, bank_5, ARRAY_SIZE(bank_5));
- }
- if (!ret)
- ret = reg_write_multiple(client, bank_8, ARRAY_SIZE(bank_8));
-
- if (!ret)
- ret = reg_write(client, RJ54N1_RESET_STANDBY,
- E_EXCLK | DSP_RSTX | SEN_RSTX);
-
- /* Commit init */
- if (!ret)
- ret = rj54n1_commit(client);
-
- /* Take DSP, TG, sensor out of reset */
- if (!ret)
- ret = reg_write(client, RJ54N1_RESET_STANDBY,
- E_EXCLK | DSP_RSTX | TG_RSTX | SEN_RSTX);
-
- /* Start register update? Same register as 0x?FE in many bank_* sets */
- if (!ret)
- ret = reg_write(client, RJ54N1_FWFLG, 2);
-
- /* Constant taken from manufacturer's example */
- msleep(700);
-
- return ret;
-}
-
-static int rj54n1_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct rj54n1 *rj54n1 = to_rj54n1(client);
- const struct rj54n1_datafmt *fmt;
- int align = mf->code == V4L2_MBUS_FMT_SBGGR10_1X10 ||
- mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE ||
- mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE ||
- mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE ||
- mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE;
-
- dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n",
- __func__, mf->code, mf->width, mf->height);
-
- fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts,
- ARRAY_SIZE(rj54n1_colour_fmts));
- if (!fmt) {
- fmt = rj54n1->fmt;
- mf->code = fmt->code;
- }
-
- mf->field = V4L2_FIELD_NONE;
- mf->colorspace = fmt->colorspace;
-
- v4l_bound_align_image(&mf->width, 112, RJ54N1_MAX_WIDTH, align,
- &mf->height, 84, RJ54N1_MAX_HEIGHT, align, 0);
-
- return 0;
-}
-
-static int rj54n1_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct rj54n1 *rj54n1 = to_rj54n1(client);
- const struct rj54n1_datafmt *fmt;
- int output_w, output_h, max_w, max_h,
- input_w = rj54n1->rect.width, input_h = rj54n1->rect.height;
- int ret;
-
- /*
- * The host driver can call us without .try_fmt(), so, we have to take
- * care ourseleves
- */
- rj54n1_try_fmt(sd, mf);
-
- /*
- * Verify if the sensor has just been powered on. TODO: replace this
- * with proper PM, when a suitable API is available.
- */
- ret = reg_read(client, RJ54N1_RESET_STANDBY);
- if (ret < 0)
- return ret;
-
- if (!(ret & E_EXCLK)) {
- ret = rj54n1_reg_init(client);
- if (ret < 0)
- return ret;
- }
-
- dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n",
- __func__, mf->code, mf->width, mf->height);
-
- /* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */
- switch (mf->code) {
- case V4L2_MBUS_FMT_YUYV8_2X8:
- ret = reg_write(client, RJ54N1_OUT_SEL, 0);
- if (!ret)
- ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
- break;
- case V4L2_MBUS_FMT_YVYU8_2X8:
- ret = reg_write(client, RJ54N1_OUT_SEL, 0);
- if (!ret)
- ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
- break;
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- ret = reg_write(client, RJ54N1_OUT_SEL, 0x11);
- if (!ret)
- ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
- break;
- case V4L2_MBUS_FMT_RGB565_2X8_BE:
- ret = reg_write(client, RJ54N1_OUT_SEL, 0x11);
- if (!ret)
- ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
- break;
- case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE:
- ret = reg_write(client, RJ54N1_OUT_SEL, 4);
- if (!ret)
- ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
- if (!ret)
- ret = reg_write(client, RJ54N1_RA_SEL_UL, 0);
- break;
- case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE:
- ret = reg_write(client, RJ54N1_OUT_SEL, 4);
- if (!ret)
- ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
- if (!ret)
- ret = reg_write(client, RJ54N1_RA_SEL_UL, 8);
- break;
- case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE:
- ret = reg_write(client, RJ54N1_OUT_SEL, 4);
- if (!ret)
- ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
- if (!ret)
- ret = reg_write(client, RJ54N1_RA_SEL_UL, 0);
- break;
- case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE:
- ret = reg_write(client, RJ54N1_OUT_SEL, 4);
- if (!ret)
- ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
- if (!ret)
- ret = reg_write(client, RJ54N1_RA_SEL_UL, 8);
- break;
- case V4L2_MBUS_FMT_SBGGR10_1X10:
- ret = reg_write(client, RJ54N1_OUT_SEL, 5);
- break;
- default:
- ret = -EINVAL;
- }
-
- /* Special case: a raw mode with 10 bits of data per clock tick */
- if (!ret)
- ret = reg_set(client, RJ54N1_OCLK_SEL_EN,
- (mf->code == V4L2_MBUS_FMT_SBGGR10_1X10) << 1, 2);
-
- if (ret < 0)
- return ret;
-
- /* Supported scales 1:1 >= scale > 1:16 */
- max_w = mf->width * (16 * 1024 - 1) / 1024;
- if (input_w > max_w)
- input_w = max_w;
- max_h = mf->height * (16 * 1024 - 1) / 1024;
- if (input_h > max_h)
- input_h = max_h;
-
- output_w = mf->width;
- output_h = mf->height;
-
- ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h);
- if (ret < 0)
- return ret;
-
- fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts,
- ARRAY_SIZE(rj54n1_colour_fmts));
-
- rj54n1->fmt = fmt;
- rj54n1->resize = ret;
- rj54n1->rect.width = input_w;
- rj54n1->rect.height = input_h;
- rj54n1->width = output_w;
- rj54n1->height = output_h;
-
- mf->width = output_w;
- mf->height = output_h;
- mf->field = V4L2_FIELD_NONE;
- mf->colorspace = fmt->colorspace;
-
- return 0;
-}
-
-static int rj54n1_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = V4L2_IDENT_RJ54N1CB0C;
- id->revision = 0;
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int rj54n1_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
- reg->reg < 0x400 || reg->reg > 0x1fff)
- /* Registers > 0x0800 are only available from Sharp support */
- return -EINVAL;
-
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
- reg->size = 1;
- reg->val = reg_read(client, reg->reg);
-
- if (reg->val > 0xff)
- return -EIO;
-
- return 0;
-}
-
-static int rj54n1_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
- reg->reg < 0x400 || reg->reg > 0x1fff)
- /* Registers >= 0x0800 are only available from Sharp support */
- return -EINVAL;
-
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
- if (reg_write(client, reg->reg, reg->val) < 0)
- return -EIO;
-
- return 0;
-}
-#endif
-
-static int rj54n1_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct rj54n1 *rj54n1 = container_of(ctrl->handler, struct rj54n1, hdl);
- struct v4l2_subdev *sd = &rj54n1->subdev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int data;
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- if (ctrl->val)
- data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1);
- else
- data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1);
- if (data < 0)
- return -EIO;
- return 0;
- case V4L2_CID_HFLIP:
- if (ctrl->val)
- data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2);
- else
- data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2);
- if (data < 0)
- return -EIO;
- return 0;
- case V4L2_CID_GAIN:
- if (reg_write(client, RJ54N1_Y_GAIN, ctrl->val * 2) < 0)
- return -EIO;
- return 0;
- case V4L2_CID_AUTO_WHITE_BALANCE:
- /* Auto WB area - whole image */
- if (reg_set(client, RJ54N1_WB_SEL_WEIGHT_I, ctrl->val << 7,
- 0x80) < 0)
- return -EIO;
- rj54n1->auto_wb = ctrl->val;
- return 0;
- }
-
- return -EINVAL;
-}
-
-static const struct v4l2_ctrl_ops rj54n1_ctrl_ops = {
- .s_ctrl = rj54n1_s_ctrl,
-};
-
-static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
- .g_chip_ident = rj54n1_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = rj54n1_g_register,
- .s_register = rj54n1_s_register,
-#endif
-};
-
-static int rj54n1_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- cfg->flags =
- V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
- V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH |
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH;
- cfg->type = V4L2_MBUS_PARALLEL;
- cfg->flags = soc_camera_apply_board_flags(icl, cfg);
-
- return 0;
-}
-
-static int rj54n1_s_mbus_config(struct v4l2_subdev *sd,
- const struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */
- if (soc_camera_apply_board_flags(icl, cfg) &
- V4L2_MBUS_PCLK_SAMPLE_RISING)
- return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4);
- else
- return reg_write(client, RJ54N1_OUT_SIGPO, 0);
-}
-
-static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
- .s_stream = rj54n1_s_stream,
- .s_mbus_fmt = rj54n1_s_fmt,
- .g_mbus_fmt = rj54n1_g_fmt,
- .try_mbus_fmt = rj54n1_try_fmt,
- .enum_mbus_fmt = rj54n1_enum_fmt,
- .g_crop = rj54n1_g_crop,
- .s_crop = rj54n1_s_crop,
- .cropcap = rj54n1_cropcap,
- .g_mbus_config = rj54n1_g_mbus_config,
- .s_mbus_config = rj54n1_s_mbus_config,
-};
-
-static struct v4l2_subdev_ops rj54n1_subdev_ops = {
- .core = &rj54n1_subdev_core_ops,
- .video = &rj54n1_subdev_video_ops,
-};
-
-/*
- * Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one
- */
-static int rj54n1_video_probe(struct i2c_client *client,
- struct rj54n1_pdata *priv)
-{
- int data1, data2;
- int ret;
-
- /* Read out the chip version register */
- data1 = reg_read(client, RJ54N1_DEV_CODE);
- data2 = reg_read(client, RJ54N1_DEV_CODE2);
-
- if (data1 != 0x51 || data2 != 0x10) {
- ret = -ENODEV;
- dev_info(&client->dev, "No RJ54N1CB0C found, read 0x%x:0x%x\n",
- data1, data2);
- goto ei2c;
- }
-
- /* Configure IOCTL polarity from the platform data: 0 or 1 << 7. */
- ret = reg_write(client, RJ54N1_IOC, priv->ioctl_high << 7);
- if (ret < 0)
- goto ei2c;
-
- dev_info(&client->dev, "Detected a RJ54N1CB0C chip ID 0x%x:0x%x\n",
- data1, data2);
-
-ei2c:
- return ret;
-}
-
-static int rj54n1_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct rj54n1 *rj54n1;
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- struct rj54n1_pdata *rj54n1_priv;
- int ret;
-
- if (!icl || !icl->priv) {
- dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n");
- return -EINVAL;
- }
-
- rj54n1_priv = icl->priv;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_warn(&adapter->dev,
- "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE\n");
- return -EIO;
- }
-
- rj54n1 = kzalloc(sizeof(struct rj54n1), GFP_KERNEL);
- if (!rj54n1)
- return -ENOMEM;
-
- v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops);
- v4l2_ctrl_handler_init(&rj54n1->hdl, 4);
- v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
- V4L2_CID_GAIN, 0, 127, 1, 66);
- v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
- V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
- rj54n1->subdev.ctrl_handler = &rj54n1->hdl;
- if (rj54n1->hdl.error) {
- int err = rj54n1->hdl.error;
-
- kfree(rj54n1);
- return err;
- }
-
- rj54n1->clk_div = clk_div;
- rj54n1->rect.left = RJ54N1_COLUMN_SKIP;
- rj54n1->rect.top = RJ54N1_ROW_SKIP;
- rj54n1->rect.width = RJ54N1_MAX_WIDTH;
- rj54n1->rect.height = RJ54N1_MAX_HEIGHT;
- rj54n1->width = RJ54N1_MAX_WIDTH;
- rj54n1->height = RJ54N1_MAX_HEIGHT;
- rj54n1->fmt = &rj54n1_colour_fmts[0];
- rj54n1->resize = 1024;
- rj54n1->tgclk_mhz = (rj54n1_priv->mclk_freq / PLL_L * PLL_N) /
- (clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1);
-
- ret = rj54n1_video_probe(client, rj54n1_priv);
- if (ret < 0) {
- v4l2_ctrl_handler_free(&rj54n1->hdl);
- kfree(rj54n1);
- return ret;
- }
- return v4l2_ctrl_handler_setup(&rj54n1->hdl);
-}
-
-static int rj54n1_remove(struct i2c_client *client)
-{
- struct rj54n1 *rj54n1 = to_rj54n1(client);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- v4l2_device_unregister_subdev(&rj54n1->subdev);
- if (icl->free_bus)
- icl->free_bus(icl);
- v4l2_ctrl_handler_free(&rj54n1->hdl);
- kfree(rj54n1);
-
- return 0;
-}
-
-static const struct i2c_device_id rj54n1_id[] = {
- { "rj54n1cb0c", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, rj54n1_id);
-
-static struct i2c_driver rj54n1_i2c_driver = {
- .driver = {
- .name = "rj54n1cb0c",
- },
- .probe = rj54n1_probe,
- .remove = rj54n1_remove,
- .id_table = rj54n1_id,
-};
-
-module_i2c_driver(rj54n1_i2c_driver);
-
-MODULE_DESCRIPTION("Sharp RJ54N1CB0C Camera driver");
-MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
deleted file mode 100644
index 95007dda0c9..00000000000
--- a/drivers/media/video/s2255drv.c
+++ /dev/null
@@ -1,2689 +0,0 @@
-/*
- * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
- *
- * Copyright (C) 2007-2010 by Sensoray Company Inc.
- * Dean Anderson
- *
- * Some video buffer code based on vivi driver:
- *
- * Sensoray 2255 device supports 4 simultaneous channels.
- * The channels are not "crossbar" inputs, they are physically
- * attached to separate video decoders.
- *
- * Because of USB2.0 bandwidth limitations. There is only a
- * certain amount of data which may be transferred at one time.
- *
- * Example maximum bandwidth utilization:
- *
- * -full size, color mode YUYV or YUV422P: 2 channels at once
- * -full or half size Grey scale: all 4 channels at once
- * -half size, color mode YUYV or YUV422P: all 4 channels at once
- * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
- * at once.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/kernel.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/mm.h>
-#include <media/videobuf-vmalloc.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <linux/vmalloc.h>
-#include <linux/usb.h>
-
-#define S2255_VERSION "1.22.1"
-#define FIRMWARE_FILE_NAME "f2255usb.bin"
-
-/* default JPEG quality */
-#define S2255_DEF_JPEG_QUAL 50
-/* vendor request in */
-#define S2255_VR_IN 0
-/* vendor request out */
-#define S2255_VR_OUT 1
-/* firmware query */
-#define S2255_VR_FW 0x30
-/* USB endpoint number for configuring the device */
-#define S2255_CONFIG_EP 2
-/* maximum time for DSP to start responding after last FW word loaded(ms) */
-#define S2255_DSP_BOOTTIME 800
-/* maximum time to wait for firmware to load (ms) */
-#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
-#define S2255_DEF_BUFS 16
-#define S2255_SETMODE_TIMEOUT 500
-#define S2255_VIDSTATUS_TIMEOUT 350
-#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
-#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
-#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
-#define S2255_RESPONSE_FW cpu_to_le32(0x10)
-#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
-#define S2255_USB_XFER_SIZE (16 * 1024)
-#define MAX_CHANNELS 4
-#define SYS_FRAMES 4
-/* maximum size is PAL full size plus room for the marker header(s) */
-#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
-#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
-#define LINE_SZ_4CIFS_NTSC 640
-#define LINE_SZ_2CIFS_NTSC 640
-#define LINE_SZ_1CIFS_NTSC 320
-#define LINE_SZ_4CIFS_PAL 704
-#define LINE_SZ_2CIFS_PAL 704
-#define LINE_SZ_1CIFS_PAL 352
-#define NUM_LINES_4CIFS_NTSC 240
-#define NUM_LINES_2CIFS_NTSC 240
-#define NUM_LINES_1CIFS_NTSC 240
-#define NUM_LINES_4CIFS_PAL 288
-#define NUM_LINES_2CIFS_PAL 288
-#define NUM_LINES_1CIFS_PAL 288
-#define LINE_SZ_DEF 640
-#define NUM_LINES_DEF 240
-
-
-/* predefined settings */
-#define FORMAT_NTSC 1
-#define FORMAT_PAL 2
-
-#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
-#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
-#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
-/* SCALE_4CIFSI is the 2 fields interpolated into one */
-#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
-
-#define COLOR_YUVPL 1 /* YUV planar */
-#define COLOR_YUVPK 2 /* YUV packed */
-#define COLOR_Y8 4 /* monochrome */
-#define COLOR_JPG 5 /* JPEG */
-
-#define MASK_COLOR 0x000000ff
-#define MASK_JPG_QUALITY 0x0000ff00
-#define MASK_INPUT_TYPE 0x000f0000
-/* frame decimation. */
-#define FDEC_1 1 /* capture every frame. default */
-#define FDEC_2 2 /* capture every 2nd frame */
-#define FDEC_3 3 /* capture every 3rd frame */
-#define FDEC_5 5 /* capture every 5th frame */
-
-/*-------------------------------------------------------
- * Default mode parameters.
- *-------------------------------------------------------*/
-#define DEF_SCALE SCALE_4CIFS
-#define DEF_COLOR COLOR_YUVPL
-#define DEF_FDEC FDEC_1
-#define DEF_BRIGHT 0
-#define DEF_CONTRAST 0x5c
-#define DEF_SATURATION 0x80
-#define DEF_HUE 0
-
-/* usb config commands */
-#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
-#define CMD_2255 0xc2255000
-#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
-#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
-#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
-#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
-
-struct s2255_mode {
- u32 format; /* input video format (NTSC, PAL) */
- u32 scale; /* output video scale */
- u32 color; /* output video color format */
- u32 fdec; /* frame decimation */
- u32 bright; /* brightness */
- u32 contrast; /* contrast */
- u32 saturation; /* saturation */
- u32 hue; /* hue (NTSC only)*/
- u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
- u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
- u32 restart; /* if DSP requires restart */
-};
-
-
-#define S2255_READ_IDLE 0
-#define S2255_READ_FRAME 1
-
-/* frame structure */
-struct s2255_framei {
- unsigned long size;
- unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
- void *lpvbits; /* image data */
- unsigned long cur_size; /* current data copied to it */
-};
-
-/* image buffer structure */
-struct s2255_bufferi {
- unsigned long dwFrames; /* number of frames in buffer */
- struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
-};
-
-#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
- DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
- DEF_HUE, 0, DEF_USB_BLOCK, 0}
-
-struct s2255_dmaqueue {
- struct list_head active;
- struct s2255_dev *dev;
-};
-
-/* for firmware loading, fw_state */
-#define S2255_FW_NOTLOADED 0
-#define S2255_FW_LOADED_DSPWAIT 1
-#define S2255_FW_SUCCESS 2
-#define S2255_FW_FAILED 3
-#define S2255_FW_DISCONNECTING 4
-#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
-/* 2255 read states */
-#define S2255_READ_IDLE 0
-#define S2255_READ_FRAME 1
-struct s2255_fw {
- int fw_loaded;
- int fw_size;
- struct urb *fw_urb;
- atomic_t fw_state;
- void *pfw_data;
- wait_queue_head_t wait_fw;
- const struct firmware *fw;
-};
-
-struct s2255_pipeinfo {
- u32 max_transfer_size;
- u32 cur_transfer_size;
- u8 *transfer_buffer;
- u32 state;
- void *stream_urb;
- void *dev; /* back pointer to s2255_dev struct*/
- u32 err_count;
- u32 idx;
-};
-
-struct s2255_fmt; /*forward declaration */
-struct s2255_dev;
-
-struct s2255_channel {
- struct video_device vdev;
- int resources;
- struct s2255_dmaqueue vidq;
- struct s2255_bufferi buffer;
- struct s2255_mode mode;
- /* jpeg compression */
- struct v4l2_jpegcompression jc;
- /* capture parameters (for high quality mode full size) */
- struct v4l2_captureparm cap_parm;
- int cur_frame;
- int last_frame;
-
- int b_acquire;
- /* allocated image size */
- unsigned long req_image_size;
- /* received packet size */
- unsigned long pkt_size;
- int bad_payload;
- unsigned long frame_count;
- /* if JPEG image */
- int jpg_size;
- /* if channel configured to default state */
- int configured;
- wait_queue_head_t wait_setmode;
- int setmode_ready;
- /* video status items */
- int vidstatus;
- wait_queue_head_t wait_vidstatus;
- int vidstatus_ready;
- unsigned int width;
- unsigned int height;
- const struct s2255_fmt *fmt;
- int idx; /* channel number on device, 0-3 */
-};
-
-
-struct s2255_dev {
- struct s2255_channel channel[MAX_CHANNELS];
- struct v4l2_device v4l2_dev;
- atomic_t num_channels;
- int frames;
- struct mutex lock; /* channels[].vdev.lock */
- struct mutex open_lock;
- struct usb_device *udev;
- struct usb_interface *interface;
- u8 read_endpoint;
- struct timer_list timer;
- struct s2255_fw *fw_data;
- struct s2255_pipeinfo pipe;
- u32 cc; /* current channel */
- int frame_ready;
- int chn_ready;
- spinlock_t slock;
- /* dsp firmware version (f2255usb.bin) */
- int dsp_fw_ver;
- u16 pid; /* product id */
-};
-
-static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
-}
-
-struct s2255_fmt {
- char *name;
- u32 fourcc;
- int depth;
-};
-
-/* buffer for one video frame */
-struct s2255_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
- const struct s2255_fmt *fmt;
-};
-
-struct s2255_fh {
- struct s2255_dev *dev;
- struct videobuf_queue vb_vidq;
- enum v4l2_buf_type type;
- struct s2255_channel *channel;
- int resources;
-};
-
-/* current cypress EEPROM firmware version */
-#define S2255_CUR_USB_FWVER ((3 << 8) | 12)
-/* current DSP FW version */
-#define S2255_CUR_DSP_FWVER 10104
-/* Need DSP version 5+ for video status feature */
-#define S2255_MIN_DSP_STATUS 5
-#define S2255_MIN_DSP_COLORFILTER 8
-#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
-
-/* private V4L2 controls */
-
-/*
- * The following chart displays how COLORFILTER should be set
- * =========================================================
- * = fourcc = COLORFILTER =
- * = ===============================
- * = = 0 = 1 =
- * =========================================================
- * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
- * = = s-video or = composite =
- * = = B/W camera = input =
- * =========================================================
- * = other = color, svideo = color, =
- * = = = composite =
- * =========================================================
- *
- * Notes:
- * channels 0-3 on 2255 are composite
- * channels 0-1 on 2257 are composite, 2-3 are s-video
- * If COLORFILTER is 0 with a composite color camera connected,
- * the output will appear monochrome but hatching
- * will occur.
- * COLORFILTER is different from "color killer" and "color effects"
- * for reasons above.
- */
-#define S2255_V4L2_YC_ON 1
-#define S2255_V4L2_YC_OFF 0
-#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
-
-/* frame prefix size (sent once every frame) */
-#define PREFIX_SIZE 512
-
-/* Channels on box are in reverse order */
-static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
-
-static int debug;
-static int *s2255_debug = &debug;
-
-static int s2255_start_readpipe(struct s2255_dev *dev);
-static void s2255_stop_readpipe(struct s2255_dev *dev);
-static int s2255_start_acquire(struct s2255_channel *channel);
-static int s2255_stop_acquire(struct s2255_channel *channel);
-static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
- int jpgsize);
-static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
-static int s2255_board_shutdown(struct s2255_dev *dev);
-static void s2255_fwload_start(struct s2255_dev *dev, int reset);
-static void s2255_destroy(struct s2255_dev *dev);
-static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
- u16 index, u16 value, void *buf,
- s32 buf_len, int bOut);
-
-/* dev_err macro with driver name */
-#define S2255_DRIVER_NAME "s2255"
-#define s2255_dev_err(dev, fmt, arg...) \
- dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
-
-#define dprintk(level, fmt, arg...) \
- do { \
- if (*s2255_debug >= (level)) { \
- printk(KERN_DEBUG S2255_DRIVER_NAME \
- ": " fmt, ##arg); \
- } \
- } while (0)
-
-static struct usb_driver s2255_driver;
-
-/* Declare static vars that will be used as parameters */
-static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
-
-/* start video number */
-static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
-
-/* Enable jpeg capture. */
-static int jpeg_enable = 1;
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
-module_param(vid_limit, int, 0644);
-MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
-module_param(video_nr, int, 0644);
-MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
-module_param(jpeg_enable, int, 0644);
-MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
-
-/* USB device table */
-#define USB_SENSORAY_VID 0x1943
-static struct usb_device_id s2255_table[] = {
- {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
- {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, s2255_table);
-
-#define BUFFER_TIMEOUT msecs_to_jiffies(400)
-
-/* image formats. */
-/* JPEG formats must be defined last to support jpeg_enable parameter */
-static const struct s2255_fmt formats[] = {
- {
- .name = "4:2:2, planar, YUV422P",
- .fourcc = V4L2_PIX_FMT_YUV422P,
- .depth = 16
-
- }, {
- .name = "4:2:2, packed, YUYV",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = 16
-
- }, {
- .name = "4:2:2, packed, UYVY",
- .fourcc = V4L2_PIX_FMT_UYVY,
- .depth = 16
- }, {
- .name = "8bpp GREY",
- .fourcc = V4L2_PIX_FMT_GREY,
- .depth = 8
- }, {
- .name = "JPG",
- .fourcc = V4L2_PIX_FMT_JPEG,
- .depth = 24
- }, {
- .name = "MJPG",
- .fourcc = V4L2_PIX_FMT_MJPEG,
- .depth = 24
- }
-};
-
-static int norm_maxw(struct video_device *vdev)
-{
- return (vdev->current_norm & V4L2_STD_NTSC) ?
- LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
-}
-
-static int norm_maxh(struct video_device *vdev)
-{
- return (vdev->current_norm & V4L2_STD_NTSC) ?
- (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
-}
-
-static int norm_minw(struct video_device *vdev)
-{
- return (vdev->current_norm & V4L2_STD_NTSC) ?
- LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
-}
-
-static int norm_minh(struct video_device *vdev)
-{
- return (vdev->current_norm & V4L2_STD_NTSC) ?
- (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
-}
-
-
-/*
- * TODO: fixme: move YUV reordering to hardware
- * converts 2255 planar format to yuyv or uyvy
- */
-static void planar422p_to_yuv_packed(const unsigned char *in,
- unsigned char *out,
- int width, int height,
- int fmt)
-{
- unsigned char *pY;
- unsigned char *pCb;
- unsigned char *pCr;
- unsigned long size = height * width;
- unsigned int i;
- pY = (unsigned char *)in;
- pCr = (unsigned char *)in + height * width;
- pCb = (unsigned char *)in + height * width + (height * width / 2);
- for (i = 0; i < size * 2; i += 4) {
- out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
- out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
- out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
- out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
- }
- return;
-}
-
-static void s2255_reset_dsppower(struct s2255_dev *dev)
-{
- s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
- msleep(10);
- s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
- msleep(600);
- s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
- return;
-}
-
-/* kickstarts the firmware loading. from probe
- */
-static void s2255_timer(unsigned long user_data)
-{
- struct s2255_fw *data = (struct s2255_fw *)user_data;
- dprintk(100, "%s\n", __func__);
- if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
- printk(KERN_ERR "s2255: can't submit urb\n");
- atomic_set(&data->fw_state, S2255_FW_FAILED);
- /* wake up anything waiting for the firmware */
- wake_up(&data->wait_fw);
- return;
- }
-}
-
-
-/* this loads the firmware asynchronously.
- Originally this was done synchroously in probe.
- But it is better to load it asynchronously here than block
- inside the probe function. Blocking inside probe affects boot time.
- FW loading is triggered by the timer in the probe function
-*/
-static void s2255_fwchunk_complete(struct urb *urb)
-{
- struct s2255_fw *data = urb->context;
- struct usb_device *udev = urb->dev;
- int len;
- dprintk(100, "%s: udev %p urb %p", __func__, udev, urb);
- if (urb->status) {
- dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
- atomic_set(&data->fw_state, S2255_FW_FAILED);
- /* wake up anything waiting for the firmware */
- wake_up(&data->wait_fw);
- return;
- }
- if (data->fw_urb == NULL) {
- s2255_dev_err(&udev->dev, "disconnected\n");
- atomic_set(&data->fw_state, S2255_FW_FAILED);
- /* wake up anything waiting for the firmware */
- wake_up(&data->wait_fw);
- return;
- }
-#define CHUNK_SIZE 512
- /* all USB transfers must be done with continuous kernel memory.
- can't allocate more than 128k in current linux kernel, so
- upload the firmware in chunks
- */
- if (data->fw_loaded < data->fw_size) {
- len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
- data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
-
- if (len < CHUNK_SIZE)
- memset(data->pfw_data, 0, CHUNK_SIZE);
-
- dprintk(100, "completed len %d, loaded %d \n", len,
- data->fw_loaded);
-
- memcpy(data->pfw_data,
- (char *) data->fw->data + data->fw_loaded, len);
-
- usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
- data->pfw_data, CHUNK_SIZE,
- s2255_fwchunk_complete, data);
- if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
- dev_err(&udev->dev, "failed submit URB\n");
- atomic_set(&data->fw_state, S2255_FW_FAILED);
- /* wake up anything waiting for the firmware */
- wake_up(&data->wait_fw);
- return;
- }
- data->fw_loaded += len;
- } else {
- atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
- dprintk(100, "%s: firmware upload complete\n", __func__);
- }
- return;
-
-}
-
-static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
-{
- struct s2255_dmaqueue *dma_q = &channel->vidq;
- struct s2255_buffer *buf;
- struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
- unsigned long flags = 0;
- int rc = 0;
- spin_lock_irqsave(&dev->slock, flags);
- if (list_empty(&dma_q->active)) {
- dprintk(1, "No active queue to serve\n");
- rc = -1;
- goto unlock;
- }
- buf = list_entry(dma_q->active.next,
- struct s2255_buffer, vb.queue);
- list_del(&buf->vb.queue);
- do_gettimeofday(&buf->vb.ts);
- s2255_fillbuff(channel, buf, jpgsize);
- wake_up(&buf->vb.done);
- dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
-unlock:
- spin_unlock_irqrestore(&dev->slock, flags);
- return rc;
-}
-
-static const struct s2255_fmt *format_by_fourcc(int fourcc)
-{
- unsigned int i;
- for (i = 0; i < ARRAY_SIZE(formats); i++) {
- if (-1 == formats[i].fourcc)
- continue;
- if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
- (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
- continue;
- if (formats[i].fourcc == fourcc)
- return formats + i;
- }
- return NULL;
-}
-
-/* video buffer vmalloc implementation based partly on VIVI driver which is
- * Copyright (c) 2006 by
- * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
- * Ted Walther <ted--a.t--enumera.com>
- * John Sokol <sokol--a.t--videotechnology.com>
- * http://v4l.videotechnology.com/
- *
- */
-static void s2255_fillbuff(struct s2255_channel *channel,
- struct s2255_buffer *buf, int jpgsize)
-{
- int pos = 0;
- struct timeval ts;
- const char *tmpbuf;
- char *vbuf = videobuf_to_vmalloc(&buf->vb);
- unsigned long last_frame;
-
- if (!vbuf)
- return;
- last_frame = channel->last_frame;
- if (last_frame != -1) {
- tmpbuf =
- (const char *)channel->buffer.frame[last_frame].lpvbits;
- switch (buf->fmt->fourcc) {
- case V4L2_PIX_FMT_YUYV:
- case V4L2_PIX_FMT_UYVY:
- planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
- vbuf, buf->vb.width,
- buf->vb.height,
- buf->fmt->fourcc);
- break;
- case V4L2_PIX_FMT_GREY:
- memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
- break;
- case V4L2_PIX_FMT_JPEG:
- case V4L2_PIX_FMT_MJPEG:
- buf->vb.size = jpgsize;
- memcpy(vbuf, tmpbuf, buf->vb.size);
- break;
- case V4L2_PIX_FMT_YUV422P:
- memcpy(vbuf, tmpbuf,
- buf->vb.width * buf->vb.height * 2);
- break;
- default:
- printk(KERN_DEBUG "s2255: unknown format?\n");
- }
- channel->last_frame = -1;
- } else {
- printk(KERN_ERR "s2255: =======no frame\n");
- return;
-
- }
- dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
- (unsigned long)vbuf, pos);
- /* tell v4l buffer was filled */
-
- buf->vb.field_count = channel->frame_count * 2;
- do_gettimeofday(&ts);
- buf->vb.ts = ts;
- buf->vb.state = VIDEOBUF_DONE;
-}
-
-
-/* ------------------------------------------------------------------
- Videobuf operations
- ------------------------------------------------------------------*/
-
-static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
- unsigned int *size)
-{
- struct s2255_fh *fh = vq->priv_data;
- struct s2255_channel *channel = fh->channel;
- *size = channel->width * channel->height * (channel->fmt->depth >> 3);
-
- if (0 == *count)
- *count = S2255_DEF_BUFS;
-
- if (*size * *count > vid_limit * 1024 * 1024)
- *count = (vid_limit * 1024 * 1024) / *size;
-
- return 0;
-}
-
-static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
-{
- dprintk(4, "%s\n", __func__);
-
- videobuf_vmalloc_free(&buf->vb);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct s2255_fh *fh = vq->priv_data;
- struct s2255_channel *channel = fh->channel;
- struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
- int rc;
- int w = channel->width;
- int h = channel->height;
- dprintk(4, "%s, field=%d\n", __func__, field);
- if (channel->fmt == NULL)
- return -EINVAL;
-
- if ((w < norm_minw(&channel->vdev)) ||
- (w > norm_maxw(&channel->vdev)) ||
- (h < norm_minh(&channel->vdev)) ||
- (h > norm_maxh(&channel->vdev))) {
- dprintk(4, "invalid buffer prepare\n");
- return -EINVAL;
- }
- buf->vb.size = w * h * (channel->fmt->depth >> 3);
- if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
- dprintk(4, "invalid buffer prepare\n");
- return -EINVAL;
- }
-
- buf->fmt = channel->fmt;
- buf->vb.width = w;
- buf->vb.height = h;
- buf->vb.field = field;
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- rc = videobuf_iolock(vq, &buf->vb, NULL);
- if (rc < 0)
- goto fail;
- }
-
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-fail:
- free_buffer(vq, buf);
- return rc;
-}
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
- struct s2255_fh *fh = vq->priv_data;
- struct s2255_channel *channel = fh->channel;
- struct s2255_dmaqueue *vidq = &channel->vidq;
- dprintk(1, "%s\n", __func__);
- buf->vb.state = VIDEOBUF_QUEUED;
- list_add_tail(&buf->vb.queue, &vidq->active);
-}
-
-static void buffer_release(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
- struct s2255_fh *fh = vq->priv_data;
- dprintk(4, "%s %d\n", __func__, fh->channel->idx);
- free_buffer(vq, buf);
-}
-
-static struct videobuf_queue_ops s2255_video_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-
-static int res_get(struct s2255_fh *fh)
-{
- struct s2255_channel *channel = fh->channel;
- /* is it free? */
- if (channel->resources)
- return 0; /* no, someone else uses it */
- /* it's free, grab it */
- channel->resources = 1;
- fh->resources = 1;
- dprintk(1, "s2255: res: get\n");
- return 1;
-}
-
-static int res_locked(struct s2255_fh *fh)
-{
- return fh->channel->resources;
-}
-
-static int res_check(struct s2255_fh *fh)
-{
- return fh->resources;
-}
-
-
-static void res_free(struct s2255_fh *fh)
-{
- struct s2255_channel *channel = fh->channel;
- channel->resources = 0;
- fh->resources = 0;
- dprintk(1, "res: put\n");
-}
-
-static int vidioc_querymenu(struct file *file, void *priv,
- struct v4l2_querymenu *qmenu)
-{
- static const char *colorfilter[] = {
- "Off",
- "On",
- NULL
- };
- if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
- int i;
- const char **menu_items = colorfilter;
- for (i = 0; i < qmenu->index && menu_items[i]; i++)
- ; /* do nothing (from v4l2-common.c) */
- if (menu_items[i] == NULL || menu_items[i][0] == '\0')
- return -EINVAL;
- strlcpy(qmenu->name, menu_items[qmenu->index],
- sizeof(qmenu->name));
- return 0;
- }
- return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct s2255_fh *fh = file->private_data;
- struct s2255_dev *dev = fh->dev;
- strlcpy(cap->driver, "s2255", sizeof(cap->driver));
- strlcpy(cap->card, "s2255", sizeof(cap->card));
- usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- int index = f->index;
-
- if (index >= ARRAY_SIZE(formats))
- return -EINVAL;
- if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
- (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
- return -EINVAL;
- dprintk(4, "name %s\n", formats[index].name);
- strlcpy(f->description, formats[index].name, sizeof(f->description));
- f->pixelformat = formats[index].fourcc;
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct s2255_fh *fh = priv;
- struct s2255_channel *channel = fh->channel;
-
- f->fmt.pix.width = channel->width;
- f->fmt.pix.height = channel->height;
- f->fmt.pix.field = fh->vb_vidq.field;
- f->fmt.pix.pixelformat = channel->fmt->fourcc;
- f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
- f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- const struct s2255_fmt *fmt;
- enum v4l2_field field;
- int b_any_field = 0;
- struct s2255_fh *fh = priv;
- struct s2255_channel *channel = fh->channel;
- int is_ntsc;
- is_ntsc =
- (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
-
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
-
- if (fmt == NULL)
- return -EINVAL;
-
- field = f->fmt.pix.field;
- if (field == V4L2_FIELD_ANY)
- b_any_field = 1;
-
- dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n",
- __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
- if (is_ntsc) {
- /* NTSC */
- if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
- f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
- if (b_any_field) {
- field = V4L2_FIELD_SEQ_TB;
- } else if (!((field == V4L2_FIELD_INTERLACED) ||
- (field == V4L2_FIELD_SEQ_TB) ||
- (field == V4L2_FIELD_INTERLACED_TB))) {
- dprintk(1, "unsupported field setting\n");
- return -EINVAL;
- }
- } else {
- f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
- if (b_any_field) {
- field = V4L2_FIELD_TOP;
- } else if (!((field == V4L2_FIELD_TOP) ||
- (field == V4L2_FIELD_BOTTOM))) {
- dprintk(1, "unsupported field setting\n");
- return -EINVAL;
- }
-
- }
- if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
- f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
- else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
- f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
- else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
- f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
- else
- f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
- } else {
- /* PAL */
- if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
- f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
- if (b_any_field) {
- field = V4L2_FIELD_SEQ_TB;
- } else if (!((field == V4L2_FIELD_INTERLACED) ||
- (field == V4L2_FIELD_SEQ_TB) ||
- (field == V4L2_FIELD_INTERLACED_TB))) {
- dprintk(1, "unsupported field setting\n");
- return -EINVAL;
- }
- } else {
- f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
- if (b_any_field) {
- field = V4L2_FIELD_TOP;
- } else if (!((field == V4L2_FIELD_TOP) ||
- (field == V4L2_FIELD_BOTTOM))) {
- dprintk(1, "unsupported field setting\n");
- return -EINVAL;
- }
- }
- if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
- f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
- field = V4L2_FIELD_SEQ_TB;
- } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
- f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
- field = V4L2_FIELD_TOP;
- } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
- f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
- field = V4L2_FIELD_TOP;
- } else {
- f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
- field = V4L2_FIELD_TOP;
- }
- }
- f->fmt.pix.field = field;
- f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
- f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
- dprintk(50, "%s: set width %d height %d field %d\n", __func__,
- f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct s2255_fh *fh = priv;
- struct s2255_channel *channel = fh->channel;
- const struct s2255_fmt *fmt;
- struct videobuf_queue *q = &fh->vb_vidq;
- struct s2255_mode mode;
- int ret;
-
- ret = vidioc_try_fmt_vid_cap(file, fh, f);
-
- if (ret < 0)
- return ret;
-
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
-
- if (fmt == NULL)
- return -EINVAL;
-
- mutex_lock(&q->vb_lock);
-
- if (videobuf_queue_is_busy(&fh->vb_vidq)) {
- dprintk(1, "queue busy\n");
- ret = -EBUSY;
- goto out_s_fmt;
- }
-
- if (res_locked(fh)) {
- dprintk(1, "%s: channel busy\n", __func__);
- ret = -EBUSY;
- goto out_s_fmt;
- }
- mode = channel->mode;
- channel->fmt = fmt;
- channel->width = f->fmt.pix.width;
- channel->height = f->fmt.pix.height;
- fh->vb_vidq.field = f->fmt.pix.field;
- fh->type = f->type;
- if (channel->width > norm_minw(&channel->vdev)) {
- if (channel->height > norm_minh(&channel->vdev)) {
- if (channel->cap_parm.capturemode &
- V4L2_MODE_HIGHQUALITY)
- mode.scale = SCALE_4CIFSI;
- else
- mode.scale = SCALE_4CIFS;
- } else
- mode.scale = SCALE_2CIFS;
-
- } else {
- mode.scale = SCALE_1CIFS;
- }
- /* color mode */
- switch (channel->fmt->fourcc) {
- case V4L2_PIX_FMT_GREY:
- mode.color &= ~MASK_COLOR;
- mode.color |= COLOR_Y8;
- break;
- case V4L2_PIX_FMT_JPEG:
- case V4L2_PIX_FMT_MJPEG:
- mode.color &= ~MASK_COLOR;
- mode.color |= COLOR_JPG;
- mode.color |= (channel->jc.quality << 8);
- break;
- case V4L2_PIX_FMT_YUV422P:
- mode.color &= ~MASK_COLOR;
- mode.color |= COLOR_YUVPL;
- break;
- case V4L2_PIX_FMT_YUYV:
- case V4L2_PIX_FMT_UYVY:
- default:
- mode.color &= ~MASK_COLOR;
- mode.color |= COLOR_YUVPK;
- break;
- }
- if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
- mode.restart = 1;
- else if (mode.scale != channel->mode.scale)
- mode.restart = 1;
- else if (mode.format != channel->mode.format)
- mode.restart = 1;
- channel->mode = mode;
- (void) s2255_set_mode(channel, &mode);
- ret = 0;
-out_s_fmt:
- mutex_unlock(&q->vb_lock);
- return ret;
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- int rc;
- struct s2255_fh *fh = priv;
- rc = videobuf_reqbufs(&fh->vb_vidq, p);
- return rc;
-}
-
-static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- int rc;
- struct s2255_fh *fh = priv;
- rc = videobuf_querybuf(&fh->vb_vidq, p);
- return rc;
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- int rc;
- struct s2255_fh *fh = priv;
- rc = videobuf_qbuf(&fh->vb_vidq, p);
- return rc;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- int rc;
- struct s2255_fh *fh = priv;
- rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
- return rc;
-}
-
-/* write to the configuration pipe, synchronously */
-static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
- int size)
-{
- int pipe;
- int done;
- long retval = -1;
- if (udev) {
- pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
- retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
- }
- return retval;
-}
-
-static u32 get_transfer_size(struct s2255_mode *mode)
-{
- int linesPerFrame = LINE_SZ_DEF;
- int pixelsPerLine = NUM_LINES_DEF;
- u32 outImageSize;
- u32 usbInSize;
- unsigned int mask_mult;
-
- if (mode == NULL)
- return 0;
-
- if (mode->format == FORMAT_NTSC) {
- switch (mode->scale) {
- case SCALE_4CIFS:
- case SCALE_4CIFSI:
- linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
- pixelsPerLine = LINE_SZ_4CIFS_NTSC;
- break;
- case SCALE_2CIFS:
- linesPerFrame = NUM_LINES_2CIFS_NTSC;
- pixelsPerLine = LINE_SZ_2CIFS_NTSC;
- break;
- case SCALE_1CIFS:
- linesPerFrame = NUM_LINES_1CIFS_NTSC;
- pixelsPerLine = LINE_SZ_1CIFS_NTSC;
- break;
- default:
- break;
- }
- } else if (mode->format == FORMAT_PAL) {
- switch (mode->scale) {
- case SCALE_4CIFS:
- case SCALE_4CIFSI:
- linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
- pixelsPerLine = LINE_SZ_4CIFS_PAL;
- break;
- case SCALE_2CIFS:
- linesPerFrame = NUM_LINES_2CIFS_PAL;
- pixelsPerLine = LINE_SZ_2CIFS_PAL;
- break;
- case SCALE_1CIFS:
- linesPerFrame = NUM_LINES_1CIFS_PAL;
- pixelsPerLine = LINE_SZ_1CIFS_PAL;
- break;
- default:
- break;
- }
- }
- outImageSize = linesPerFrame * pixelsPerLine;
- if ((mode->color & MASK_COLOR) != COLOR_Y8) {
- /* 2 bytes/pixel if not monochrome */
- outImageSize *= 2;
- }
-
- /* total bytes to send including prefix and 4K padding;
- must be a multiple of USB_READ_SIZE */
- usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
- mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
- /* if size not a multiple of USB_READ_SIZE */
- if (usbInSize & ~mask_mult)
- usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
- return usbInSize;
-}
-
-static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
-{
- struct device *dev = &sdev->udev->dev;
- dev_info(dev, "------------------------------------------------\n");
- dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
- dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
- dev_info(dev, "bright: 0x%x\n", mode->bright);
- dev_info(dev, "------------------------------------------------\n");
-}
-
-/*
- * set mode is the function which controls the DSP.
- * the restart parameter in struct s2255_mode should be set whenever
- * the image size could change via color format, video system or image
- * size.
- * When the restart parameter is set, we sleep for ONE frame to allow the
- * DSP time to get the new frame
- */
-static int s2255_set_mode(struct s2255_channel *channel,
- struct s2255_mode *mode)
-{
- int res;
- __le32 *buffer;
- unsigned long chn_rev;
- struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
- chn_rev = G_chnmap[channel->idx];
- dprintk(3, "%s channel: %d\n", __func__, channel->idx);
- /* if JPEG, set the quality */
- if ((mode->color & MASK_COLOR) == COLOR_JPG) {
- mode->color &= ~MASK_COLOR;
- mode->color |= COLOR_JPG;
- mode->color &= ~MASK_JPG_QUALITY;
- mode->color |= (channel->jc.quality << 8);
- }
- /* save the mode */
- channel->mode = *mode;
- channel->req_image_size = get_transfer_size(mode);
- dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
- buffer = kzalloc(512, GFP_KERNEL);
- if (buffer == NULL) {
- dev_err(&dev->udev->dev, "out of mem\n");
- return -ENOMEM;
- }
- /* set the mode */
- buffer[0] = IN_DATA_TOKEN;
- buffer[1] = (__le32) cpu_to_le32(chn_rev);
- buffer[2] = CMD_SET_MODE;
- memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
- channel->setmode_ready = 0;
- res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
- if (debug)
- s2255_print_cfg(dev, mode);
- kfree(buffer);
- /* wait at least 3 frames before continuing */
- if (mode->restart) {
- wait_event_timeout(channel->wait_setmode,
- (channel->setmode_ready != 0),
- msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
- if (channel->setmode_ready != 1) {
- printk(KERN_DEBUG "s2255: no set mode response\n");
- res = -EFAULT;
- }
- }
- /* clear the restart flag */
- channel->mode.restart = 0;
- dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
- return res;
-}
-
-static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
-{
- int res;
- __le32 *buffer;
- u32 chn_rev;
- struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
- chn_rev = G_chnmap[channel->idx];
- dprintk(4, "%s chan %d\n", __func__, channel->idx);
- buffer = kzalloc(512, GFP_KERNEL);
- if (buffer == NULL) {
- dev_err(&dev->udev->dev, "out of mem\n");
- return -ENOMEM;
- }
- /* form the get vid status command */
- buffer[0] = IN_DATA_TOKEN;
- buffer[1] = (__le32) cpu_to_le32(chn_rev);
- buffer[2] = CMD_STATUS;
- *pstatus = 0;
- channel->vidstatus_ready = 0;
- res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
- kfree(buffer);
- wait_event_timeout(channel->wait_vidstatus,
- (channel->vidstatus_ready != 0),
- msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
- if (channel->vidstatus_ready != 1) {
- printk(KERN_DEBUG "s2255: no vidstatus response\n");
- res = -EFAULT;
- }
- *pstatus = channel->vidstatus;
- dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
- return res;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- int res;
- struct s2255_fh *fh = priv;
- struct s2255_dev *dev = fh->dev;
- struct s2255_channel *channel = fh->channel;
- int j;
- dprintk(4, "%s\n", __func__);
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- dev_err(&dev->udev->dev, "invalid fh type0\n");
- return -EINVAL;
- }
- if (i != fh->type) {
- dev_err(&dev->udev->dev, "invalid fh type1\n");
- return -EINVAL;
- }
-
- if (!res_get(fh)) {
- s2255_dev_err(&dev->udev->dev, "stream busy\n");
- return -EBUSY;
- }
- channel->last_frame = -1;
- channel->bad_payload = 0;
- channel->cur_frame = 0;
- channel->frame_count = 0;
- for (j = 0; j < SYS_FRAMES; j++) {
- channel->buffer.frame[j].ulState = S2255_READ_IDLE;
- channel->buffer.frame[j].cur_size = 0;
- }
- res = videobuf_streamon(&fh->vb_vidq);
- if (res == 0) {
- s2255_start_acquire(channel);
- channel->b_acquire = 1;
- } else
- res_free(fh);
-
- return res;
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct s2255_fh *fh = priv;
- dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- printk(KERN_ERR "invalid fh type0\n");
- return -EINVAL;
- }
- if (i != fh->type) {
- printk(KERN_ERR "invalid type i\n");
- return -EINVAL;
- }
- s2255_stop_acquire(fh->channel);
- videobuf_streamoff(&fh->vb_vidq);
- res_free(fh);
- return 0;
-}
-
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
-{
- struct s2255_fh *fh = priv;
- struct s2255_mode mode;
- struct videobuf_queue *q = &fh->vb_vidq;
- int ret = 0;
- mutex_lock(&q->vb_lock);
- if (videobuf_queue_is_busy(q)) {
- dprintk(1, "queue busy\n");
- ret = -EBUSY;
- goto out_s_std;
- }
- if (res_locked(fh)) {
- dprintk(1, "can't change standard after started\n");
- ret = -EBUSY;
- goto out_s_std;
- }
- mode = fh->channel->mode;
- if (*i & V4L2_STD_NTSC) {
- dprintk(4, "%s NTSC\n", __func__);
- /* if changing format, reset frame decimation/intervals */
- if (mode.format != FORMAT_NTSC) {
- mode.restart = 1;
- mode.format = FORMAT_NTSC;
- mode.fdec = FDEC_1;
- }
- } else if (*i & V4L2_STD_PAL) {
- dprintk(4, "%s PAL\n", __func__);
- if (mode.format != FORMAT_PAL) {
- mode.restart = 1;
- mode.format = FORMAT_PAL;
- mode.fdec = FDEC_1;
- }
- } else {
- ret = -EINVAL;
- }
- if (mode.restart)
- s2255_set_mode(fh->channel, &mode);
-out_s_std:
- mutex_unlock(&q->vb_lock);
- return ret;
-}
-
-/* Sensoray 2255 is a multiple channel capture device.
- It does not have a "crossbar" of inputs.
- We use one V4L device per channel. The user must
- be aware that certain combinations are not allowed.
- For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
- at once in color(you can do full fps on 4 channels with greyscale.
-*/
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *inp)
-{
- struct s2255_fh *fh = priv;
- struct s2255_dev *dev = fh->dev;
- struct s2255_channel *channel = fh->channel;
- u32 status = 0;
- if (inp->index != 0)
- return -EINVAL;
- inp->type = V4L2_INPUT_TYPE_CAMERA;
- inp->std = S2255_NORMS;
- inp->status = 0;
- if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
- int rc;
- rc = s2255_cmd_status(fh->channel, &status);
- dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
- if (rc == 0)
- inp->status = (status & 0x01) ? 0
- : V4L2_IN_ST_NO_SIGNAL;
- }
- switch (dev->pid) {
- case 0x2255:
- default:
- strlcpy(inp->name, "Composite", sizeof(inp->name));
- break;
- case 0x2257:
- strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
- sizeof(inp->name));
- break;
- }
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- if (i > 0)
- return -EINVAL;
- return 0;
-}
-
-/* --- controls ---------------------------------------------- */
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qc)
-{
- struct s2255_fh *fh = priv;
- struct s2255_channel *channel = fh->channel;
- struct s2255_dev *dev = fh->dev;
- switch (qc->id) {
- case V4L2_CID_BRIGHTNESS:
- v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
- break;
- case V4L2_CID_CONTRAST:
- v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
- break;
- case V4L2_CID_SATURATION:
- v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
- break;
- case V4L2_CID_HUE:
- v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
- break;
- case V4L2_CID_PRIVATE_COLORFILTER:
- if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
- return -EINVAL;
- if ((dev->pid == 0x2257) && (channel->idx > 1))
- return -EINVAL;
- strlcpy(qc->name, "Color Filter", sizeof(qc->name));
- qc->type = V4L2_CTRL_TYPE_MENU;
- qc->minimum = 0;
- qc->maximum = 1;
- qc->step = 1;
- qc->default_value = 1;
- qc->flags = 0;
- break;
- default:
- return -EINVAL;
- }
- dprintk(4, "%s, id %d\n", __func__, qc->id);
- return 0;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct s2255_fh *fh = priv;
- struct s2255_dev *dev = fh->dev;
- struct s2255_channel *channel = fh->channel;
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- ctrl->value = channel->mode.bright;
- break;
- case V4L2_CID_CONTRAST:
- ctrl->value = channel->mode.contrast;
- break;
- case V4L2_CID_SATURATION:
- ctrl->value = channel->mode.saturation;
- break;
- case V4L2_CID_HUE:
- ctrl->value = channel->mode.hue;
- break;
- case V4L2_CID_PRIVATE_COLORFILTER:
- if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
- return -EINVAL;
- if ((dev->pid == 0x2257) && (channel->idx > 1))
- return -EINVAL;
- ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16);
- break;
- default:
- return -EINVAL;
- }
- dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct s2255_fh *fh = priv;
- struct s2255_channel *channel = fh->channel;
- struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
- struct s2255_mode mode;
- mode = channel->mode;
- dprintk(4, "%s\n", __func__);
- /* update the mode to the corresponding value */
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- mode.bright = ctrl->value;
- break;
- case V4L2_CID_CONTRAST:
- mode.contrast = ctrl->value;
- break;
- case V4L2_CID_HUE:
- mode.hue = ctrl->value;
- break;
- case V4L2_CID_SATURATION:
- mode.saturation = ctrl->value;
- break;
- case V4L2_CID_PRIVATE_COLORFILTER:
- if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
- return -EINVAL;
- if ((dev->pid == 0x2257) && (channel->idx > 1))
- return -EINVAL;
- mode.color &= ~MASK_INPUT_TYPE;
- mode.color |= ((ctrl->value ? 0 : 1) << 16);
- break;
- default:
- return -EINVAL;
- }
- mode.restart = 0;
- /* set mode here. Note: stream does not need restarted.
- some V4L programs restart stream unnecessarily
- after a s_crtl.
- */
- s2255_set_mode(fh->channel, &mode);
- return 0;
-}
-
-static int vidioc_g_jpegcomp(struct file *file, void *priv,
- struct v4l2_jpegcompression *jc)
-{
- struct s2255_fh *fh = priv;
- struct s2255_channel *channel = fh->channel;
- *jc = channel->jc;
- dprintk(2, "%s: quality %d\n", __func__, jc->quality);
- return 0;
-}
-
-static int vidioc_s_jpegcomp(struct file *file, void *priv,
- struct v4l2_jpegcompression *jc)
-{
- struct s2255_fh *fh = priv;
- struct s2255_channel *channel = fh->channel;
- if (jc->quality < 0 || jc->quality > 100)
- return -EINVAL;
- channel->jc.quality = jc->quality;
- dprintk(2, "%s: quality %d\n", __func__, jc->quality);
- return 0;
-}
-
-static int vidioc_g_parm(struct file *file, void *priv,
- struct v4l2_streamparm *sp)
-{
- struct s2255_fh *fh = priv;
- __u32 def_num, def_dem;
- struct s2255_channel *channel = fh->channel;
- if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- memset(sp, 0, sizeof(struct v4l2_streamparm));
- sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
- sp->parm.capture.capturemode = channel->cap_parm.capturemode;
- def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
- def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
- sp->parm.capture.timeperframe.denominator = def_dem;
- switch (channel->mode.fdec) {
- default:
- case FDEC_1:
- sp->parm.capture.timeperframe.numerator = def_num;
- break;
- case FDEC_2:
- sp->parm.capture.timeperframe.numerator = def_num * 2;
- break;
- case FDEC_3:
- sp->parm.capture.timeperframe.numerator = def_num * 3;
- break;
- case FDEC_5:
- sp->parm.capture.timeperframe.numerator = def_num * 5;
- break;
- }
- dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
- sp->parm.capture.capturemode,
- sp->parm.capture.timeperframe.numerator,
- sp->parm.capture.timeperframe.denominator);
- return 0;
-}
-
-static int vidioc_s_parm(struct file *file, void *priv,
- struct v4l2_streamparm *sp)
-{
- struct s2255_fh *fh = priv;
- struct s2255_channel *channel = fh->channel;
- struct s2255_mode mode;
- int fdec = FDEC_1;
- __u32 def_num, def_dem;
- if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- mode = channel->mode;
- /* high quality capture mode requires a stream restart */
- if (channel->cap_parm.capturemode
- != sp->parm.capture.capturemode && res_locked(fh))
- return -EBUSY;
- def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
- def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
- if (def_dem != sp->parm.capture.timeperframe.denominator)
- sp->parm.capture.timeperframe.numerator = def_num;
- else if (sp->parm.capture.timeperframe.numerator <= def_num)
- sp->parm.capture.timeperframe.numerator = def_num;
- else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
- sp->parm.capture.timeperframe.numerator = def_num * 2;
- fdec = FDEC_2;
- } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
- sp->parm.capture.timeperframe.numerator = def_num * 3;
- fdec = FDEC_3;
- } else {
- sp->parm.capture.timeperframe.numerator = def_num * 5;
- fdec = FDEC_5;
- }
- mode.fdec = fdec;
- sp->parm.capture.timeperframe.denominator = def_dem;
- s2255_set_mode(channel, &mode);
- dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
- __func__,
- sp->parm.capture.capturemode,
- sp->parm.capture.timeperframe.numerator,
- sp->parm.capture.timeperframe.denominator, fdec);
- return 0;
-}
-
-static int vidioc_enum_frameintervals(struct file *file, void *priv,
- struct v4l2_frmivalenum *fe)
-{
- int is_ntsc = 0;
-#define NUM_FRAME_ENUMS 4
- int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
- if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
- return -EINVAL;
- switch (fe->width) {
- case 640:
- if (fe->height != 240 && fe->height != 480)
- return -EINVAL;
- is_ntsc = 1;
- break;
- case 320:
- if (fe->height != 240)
- return -EINVAL;
- is_ntsc = 1;
- break;
- case 704:
- if (fe->height != 288 && fe->height != 576)
- return -EINVAL;
- break;
- case 352:
- if (fe->height != 288)
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
- fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
- fe->discrete.denominator = is_ntsc ? 30000 : 25000;
- fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
- dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
- fe->discrete.denominator);
- return 0;
-}
-
-static int s2255_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct s2255_channel *channel = video_drvdata(file);
- struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
- struct s2255_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- int state;
- dprintk(1, "s2255: open called (dev=%s)\n",
- video_device_node_name(vdev));
- /*
- * open lock necessary to prevent multiple instances
- * of v4l-conf (or other programs) from simultaneously
- * reloading firmware.
- */
- mutex_lock(&dev->open_lock);
- state = atomic_read(&dev->fw_data->fw_state);
- switch (state) {
- case S2255_FW_DISCONNECTING:
- mutex_unlock(&dev->open_lock);
- return -ENODEV;
- case S2255_FW_FAILED:
- s2255_dev_err(&dev->udev->dev,
- "firmware load failed. retrying.\n");
- s2255_fwload_start(dev, 1);
- wait_event_timeout(dev->fw_data->wait_fw,
- ((atomic_read(&dev->fw_data->fw_state)
- == S2255_FW_SUCCESS) ||
- (atomic_read(&dev->fw_data->fw_state)
- == S2255_FW_DISCONNECTING)),
- msecs_to_jiffies(S2255_LOAD_TIMEOUT));
- /* state may have changed, re-read */
- state = atomic_read(&dev->fw_data->fw_state);
- break;
- case S2255_FW_NOTLOADED:
- case S2255_FW_LOADED_DSPWAIT:
- /* give S2255_LOAD_TIMEOUT time for firmware to load in case
- driver loaded and then device immediately opened */
- printk(KERN_INFO "%s waiting for firmware load\n", __func__);
- wait_event_timeout(dev->fw_data->wait_fw,
- ((atomic_read(&dev->fw_data->fw_state)
- == S2255_FW_SUCCESS) ||
- (atomic_read(&dev->fw_data->fw_state)
- == S2255_FW_DISCONNECTING)),
- msecs_to_jiffies(S2255_LOAD_TIMEOUT));
- /* state may have changed, re-read */
- state = atomic_read(&dev->fw_data->fw_state);
- break;
- case S2255_FW_SUCCESS:
- default:
- break;
- }
- /* state may have changed in above switch statement */
- switch (state) {
- case S2255_FW_SUCCESS:
- break;
- case S2255_FW_FAILED:
- printk(KERN_INFO "2255 firmware load failed.\n");
- mutex_unlock(&dev->open_lock);
- return -ENODEV;
- case S2255_FW_DISCONNECTING:
- printk(KERN_INFO "%s: disconnecting\n", __func__);
- mutex_unlock(&dev->open_lock);
- return -ENODEV;
- case S2255_FW_LOADED_DSPWAIT:
- case S2255_FW_NOTLOADED:
- printk(KERN_INFO "%s: firmware not loaded yet"
- "please try again later\n",
- __func__);
- /*
- * Timeout on firmware load means device unusable.
- * Set firmware failure state.
- * On next s2255_open the firmware will be reloaded.
- */
- atomic_set(&dev->fw_data->fw_state,
- S2255_FW_FAILED);
- mutex_unlock(&dev->open_lock);
- return -EAGAIN;
- default:
- printk(KERN_INFO "%s: unknown state\n", __func__);
- mutex_unlock(&dev->open_lock);
- return -EFAULT;
- }
- mutex_unlock(&dev->open_lock);
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
- file->private_data = fh;
- fh->dev = dev;
- fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fh->channel = channel;
- if (!channel->configured) {
- /* configure channel to default state */
- channel->fmt = &formats[0];
- s2255_set_mode(channel, &channel->mode);
- channel->configured = 1;
- }
- dprintk(1, "%s: dev=%s type=%s\n", __func__,
- video_device_node_name(vdev), v4l2_type_names[type]);
- dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
- (unsigned long)fh, (unsigned long)dev,
- (unsigned long)&channel->vidq);
- dprintk(4, "%s: list_empty active=%d\n", __func__,
- list_empty(&channel->vidq.active));
- videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
- NULL, &dev->slock,
- fh->type,
- V4L2_FIELD_INTERLACED,
- sizeof(struct s2255_buffer),
- fh, vdev->lock);
- return 0;
-}
-
-
-static unsigned int s2255_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct s2255_fh *fh = file->private_data;
- int rc;
- dprintk(100, "%s\n", __func__);
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
- return POLLERR;
- rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
- return rc;
-}
-
-static void s2255_destroy(struct s2255_dev *dev)
-{
- /* board shutdown stops the read pipe if it is running */
- s2255_board_shutdown(dev);
- /* make sure firmware still not trying to load */
- del_timer(&dev->timer); /* only started in .probe and .open */
- if (dev->fw_data->fw_urb) {
- usb_kill_urb(dev->fw_data->fw_urb);
- usb_free_urb(dev->fw_data->fw_urb);
- dev->fw_data->fw_urb = NULL;
- }
- release_firmware(dev->fw_data->fw);
- kfree(dev->fw_data->pfw_data);
- kfree(dev->fw_data);
- /* reset the DSP so firmware can be reloaded next time */
- s2255_reset_dsppower(dev);
- mutex_destroy(&dev->open_lock);
- mutex_destroy(&dev->lock);
- usb_put_dev(dev->udev);
- v4l2_device_unregister(&dev->v4l2_dev);
- dprintk(1, "%s", __func__);
- kfree(dev);
-}
-
-static int s2255_release(struct file *file)
-{
- struct s2255_fh *fh = file->private_data;
- struct s2255_dev *dev = fh->dev;
- struct video_device *vdev = video_devdata(file);
- struct s2255_channel *channel = fh->channel;
- if (!dev)
- return -ENODEV;
- /* turn off stream */
- if (res_check(fh)) {
- if (channel->b_acquire)
- s2255_stop_acquire(fh->channel);
- videobuf_streamoff(&fh->vb_vidq);
- res_free(fh);
- }
- videobuf_mmap_free(&fh->vb_vidq);
- dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
- kfree(fh);
- return 0;
-}
-
-static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
-{
- struct s2255_fh *fh = file->private_data;
- int ret;
-
- if (!fh)
- return -ENODEV;
- dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
- ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
- dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
- (unsigned long)vma->vm_start,
- (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
- return ret;
-}
-
-static const struct v4l2_file_operations s2255_fops_v4l = {
- .owner = THIS_MODULE,
- .open = s2255_open,
- .release = s2255_release,
- .poll = s2255_poll,
- .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
- .mmap = s2255_mmap_v4l,
-};
-
-static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
- .vidioc_querymenu = vidioc_querymenu,
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
- .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
- .vidioc_s_parm = vidioc_s_parm,
- .vidioc_g_parm = vidioc_g_parm,
- .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
-};
-
-static void s2255_video_device_release(struct video_device *vdev)
-{
- struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
- dprintk(4, "%s, chnls: %d \n", __func__,
- atomic_read(&dev->num_channels));
- if (atomic_dec_and_test(&dev->num_channels))
- s2255_destroy(dev);
- return;
-}
-
-static struct video_device template = {
- .name = "s2255v",
- .fops = &s2255_fops_v4l,
- .ioctl_ops = &s2255_ioctl_ops,
- .release = s2255_video_device_release,
- .tvnorms = S2255_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
-
-static int s2255_probe_v4l(struct s2255_dev *dev)
-{
- int ret;
- int i;
- int cur_nr = video_nr;
- struct s2255_channel *channel;
- ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
- if (ret)
- return ret;
- /* initialize all video 4 linux */
- /* register 4 video devices */
- for (i = 0; i < MAX_CHANNELS; i++) {
- channel = &dev->channel[i];
- INIT_LIST_HEAD(&channel->vidq.active);
- channel->vidq.dev = dev;
- /* register 4 video devices */
- channel->vdev = template;
- channel->vdev.lock = &dev->lock;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &channel->vdev.flags);
- channel->vdev.v4l2_dev = &dev->v4l2_dev;
- video_set_drvdata(&channel->vdev, channel);
- if (video_nr == -1)
- ret = video_register_device(&channel->vdev,
- VFL_TYPE_GRABBER,
- video_nr);
- else
- ret = video_register_device(&channel->vdev,
- VFL_TYPE_GRABBER,
- cur_nr + i);
-
- if (ret) {
- dev_err(&dev->udev->dev,
- "failed to register video device!\n");
- break;
- }
- atomic_inc(&dev->num_channels);
- v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
- video_device_node_name(&channel->vdev));
-
- }
- printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %s\n",
- S2255_VERSION);
- /* if no channels registered, return error and probe will fail*/
- if (atomic_read(&dev->num_channels) == 0) {
- v4l2_device_unregister(&dev->v4l2_dev);
- return ret;
- }
- if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
- printk(KERN_WARNING "s2255: Not all channels available.\n");
- return 0;
-}
-
-/* this function moves the usb stream read pipe data
- * into the system buffers.
- * returns 0 on success, EAGAIN if more data to process( call this
- * function again).
- *
- * Received frame structure:
- * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
- * bytes 4-7: channel: 0-3
- * bytes 8-11: payload size: size of the frame
- * bytes 12-payloadsize+12: frame data
- */
-static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
-{
- char *pdest;
- u32 offset = 0;
- int bframe = 0;
- char *psrc;
- unsigned long copy_size;
- unsigned long size;
- s32 idx = -1;
- struct s2255_framei *frm;
- unsigned char *pdata;
- struct s2255_channel *channel;
- dprintk(100, "buffer to user\n");
- channel = &dev->channel[dev->cc];
- idx = channel->cur_frame;
- frm = &channel->buffer.frame[idx];
- if (frm->ulState == S2255_READ_IDLE) {
- int jj;
- unsigned int cc;
- __le32 *pdword; /*data from dsp is little endian */
- int payload;
- /* search for marker codes */
- pdata = (unsigned char *)pipe_info->transfer_buffer;
- pdword = (__le32 *)pdata;
- for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
- switch (*pdword) {
- case S2255_MARKER_FRAME:
- dprintk(4, "found frame marker at offset:"
- " %d [%x %x]\n", jj, pdata[0],
- pdata[1]);
- offset = jj + PREFIX_SIZE;
- bframe = 1;
- cc = le32_to_cpu(pdword[1]);
- if (cc >= MAX_CHANNELS) {
- printk(KERN_ERR
- "bad channel\n");
- return -EINVAL;
- }
- /* reverse it */
- dev->cc = G_chnmap[cc];
- channel = &dev->channel[dev->cc];
- payload = le32_to_cpu(pdword[3]);
- if (payload > channel->req_image_size) {
- channel->bad_payload++;
- /* discard the bad frame */
- return -EINVAL;
- }
- channel->pkt_size = payload;
- channel->jpg_size = le32_to_cpu(pdword[4]);
- break;
- case S2255_MARKER_RESPONSE:
-
- pdata += DEF_USB_BLOCK;
- jj += DEF_USB_BLOCK;
- if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS)
- break;
- cc = G_chnmap[le32_to_cpu(pdword[1])];
- if (cc >= MAX_CHANNELS)
- break;
- channel = &dev->channel[cc];
- switch (pdword[2]) {
- case S2255_RESPONSE_SETMODE:
- /* check if channel valid */
- /* set mode ready */
- channel->setmode_ready = 1;
- wake_up(&channel->wait_setmode);
- dprintk(5, "setmode ready %d\n", cc);
- break;
- case S2255_RESPONSE_FW:
- dev->chn_ready |= (1 << cc);
- if ((dev->chn_ready & 0x0f) != 0x0f)
- break;
- /* all channels ready */
- printk(KERN_INFO "s2255: fw loaded\n");
- atomic_set(&dev->fw_data->fw_state,
- S2255_FW_SUCCESS);
- wake_up(&dev->fw_data->wait_fw);
- break;
- case S2255_RESPONSE_STATUS:
- channel->vidstatus = le32_to_cpu(pdword[3]);
- channel->vidstatus_ready = 1;
- wake_up(&channel->wait_vidstatus);
- dprintk(5, "got vidstatus %x chan %d\n",
- le32_to_cpu(pdword[3]), cc);
- break;
- default:
- printk(KERN_INFO "s2255 unknown resp\n");
- }
- default:
- pdata++;
- break;
- }
- if (bframe)
- break;
- } /* for */
- if (!bframe)
- return -EINVAL;
- }
- channel = &dev->channel[dev->cc];
- idx = channel->cur_frame;
- frm = &channel->buffer.frame[idx];
- /* search done. now find out if should be acquiring on this channel */
- if (!channel->b_acquire) {
- /* we found a frame, but this channel is turned off */
- frm->ulState = S2255_READ_IDLE;
- return -EINVAL;
- }
-
- if (frm->ulState == S2255_READ_IDLE) {
- frm->ulState = S2255_READ_FRAME;
- frm->cur_size = 0;
- }
-
- /* skip the marker 512 bytes (and offset if out of sync) */
- psrc = (u8 *)pipe_info->transfer_buffer + offset;
-
-
- if (frm->lpvbits == NULL) {
- dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
- frm, dev, dev->cc, idx);
- return -ENOMEM;
- }
-
- pdest = frm->lpvbits + frm->cur_size;
-
- copy_size = (pipe_info->cur_transfer_size - offset);
-
- size = channel->pkt_size - PREFIX_SIZE;
-
- /* sanity check on pdest */
- if ((copy_size + frm->cur_size) < channel->req_image_size)
- memcpy(pdest, psrc, copy_size);
-
- frm->cur_size += copy_size;
- dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
-
- if (frm->cur_size >= size) {
- dprintk(2, "****************[%d]Buffer[%d]full*************\n",
- dev->cc, idx);
- channel->last_frame = channel->cur_frame;
- channel->cur_frame++;
- /* end of system frame ring buffer, start at zero */
- if ((channel->cur_frame == SYS_FRAMES) ||
- (channel->cur_frame == channel->buffer.dwFrames))
- channel->cur_frame = 0;
- /* frame ready */
- if (channel->b_acquire)
- s2255_got_frame(channel, channel->jpg_size);
- channel->frame_count++;
- frm->ulState = S2255_READ_IDLE;
- frm->cur_size = 0;
-
- }
- /* done successfully */
- return 0;
-}
-
-static void s2255_read_video_callback(struct s2255_dev *dev,
- struct s2255_pipeinfo *pipe_info)
-{
- int res;
- dprintk(50, "callback read video \n");
-
- if (dev->cc >= MAX_CHANNELS) {
- dev->cc = 0;
- dev_err(&dev->udev->dev, "invalid channel\n");
- return;
- }
- /* otherwise copy to the system buffers */
- res = save_frame(dev, pipe_info);
- if (res != 0)
- dprintk(4, "s2255: read callback failed\n");
-
- dprintk(50, "callback read video done\n");
- return;
-}
-
-static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
- u16 Index, u16 Value, void *TransferBuffer,
- s32 TransferBufferLength, int bOut)
-{
- int r;
- if (!bOut) {
- r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
- Request,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE |
- USB_DIR_IN,
- Value, Index, TransferBuffer,
- TransferBufferLength, HZ * 5);
- } else {
- r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
- Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- Value, Index, TransferBuffer,
- TransferBufferLength, HZ * 5);
- }
- return r;
-}
-
-/*
- * retrieve FX2 firmware version. future use.
- * @param dev pointer to device extension
- * @return -1 for fail, else returns firmware version as an int(16 bits)
- */
-static int s2255_get_fx2fw(struct s2255_dev *dev)
-{
- int fw;
- int ret;
- unsigned char transBuffer[64];
- ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
- S2255_VR_IN);
- if (ret < 0)
- dprintk(2, "get fw error: %x\n", ret);
- fw = transBuffer[0] + (transBuffer[1] << 8);
- dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
- return fw;
-}
-
-/*
- * Create the system ring buffer to copy frames into from the
- * usb read pipe.
- */
-static int s2255_create_sys_buffers(struct s2255_channel *channel)
-{
- unsigned long i;
- unsigned long reqsize;
- dprintk(1, "create sys buffers\n");
- channel->buffer.dwFrames = SYS_FRAMES;
- /* always allocate maximum size(PAL) for system buffers */
- reqsize = SYS_FRAMES_MAXSIZE;
-
- if (reqsize > SYS_FRAMES_MAXSIZE)
- reqsize = SYS_FRAMES_MAXSIZE;
-
- for (i = 0; i < SYS_FRAMES; i++) {
- /* allocate the frames */
- channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
- dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n",
- &channel->buffer.frame[i], channel->idx, i,
- channel->buffer.frame[i].lpvbits);
- channel->buffer.frame[i].size = reqsize;
- if (channel->buffer.frame[i].lpvbits == NULL) {
- printk(KERN_INFO "out of memory. using less frames\n");
- channel->buffer.dwFrames = i;
- break;
- }
- }
-
- /* make sure internal states are set */
- for (i = 0; i < SYS_FRAMES; i++) {
- channel->buffer.frame[i].ulState = 0;
- channel->buffer.frame[i].cur_size = 0;
- }
-
- channel->cur_frame = 0;
- channel->last_frame = -1;
- return 0;
-}
-
-static int s2255_release_sys_buffers(struct s2255_channel *channel)
-{
- unsigned long i;
- dprintk(1, "release sys buffers\n");
- for (i = 0; i < SYS_FRAMES; i++) {
- if (channel->buffer.frame[i].lpvbits) {
- dprintk(1, "vfree %p\n",
- channel->buffer.frame[i].lpvbits);
- vfree(channel->buffer.frame[i].lpvbits);
- }
- channel->buffer.frame[i].lpvbits = NULL;
- }
- return 0;
-}
-
-static int s2255_board_init(struct s2255_dev *dev)
-{
- struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
- int fw_ver;
- int j;
- struct s2255_pipeinfo *pipe = &dev->pipe;
- dprintk(4, "board init: %p", dev);
- memset(pipe, 0, sizeof(*pipe));
- pipe->dev = dev;
- pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
- pipe->max_transfer_size = S2255_USB_XFER_SIZE;
-
- pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
- GFP_KERNEL);
- if (pipe->transfer_buffer == NULL) {
- dprintk(1, "out of memory!\n");
- return -ENOMEM;
- }
- /* query the firmware */
- fw_ver = s2255_get_fx2fw(dev);
-
- printk(KERN_INFO "s2255: usb firmware version %d.%d\n",
- (fw_ver >> 8) & 0xff,
- fw_ver & 0xff);
-
- if (fw_ver < S2255_CUR_USB_FWVER)
- printk(KERN_INFO "s2255: newer USB firmware available\n");
-
- for (j = 0; j < MAX_CHANNELS; j++) {
- struct s2255_channel *channel = &dev->channel[j];
- channel->b_acquire = 0;
- channel->mode = mode_def;
- if (dev->pid == 0x2257 && j > 1)
- channel->mode.color |= (1 << 16);
- channel->jc.quality = S2255_DEF_JPEG_QUAL;
- channel->width = LINE_SZ_4CIFS_NTSC;
- channel->height = NUM_LINES_4CIFS_NTSC * 2;
- channel->fmt = &formats[0];
- channel->mode.restart = 1;
- channel->req_image_size = get_transfer_size(&mode_def);
- channel->frame_count = 0;
- /* create the system buffers */
- s2255_create_sys_buffers(channel);
- }
- /* start read pipe */
- s2255_start_readpipe(dev);
- dprintk(1, "%s: success\n", __func__);
- return 0;
-}
-
-static int s2255_board_shutdown(struct s2255_dev *dev)
-{
- u32 i;
- dprintk(1, "%s: dev: %p", __func__, dev);
-
- for (i = 0; i < MAX_CHANNELS; i++) {
- if (dev->channel[i].b_acquire)
- s2255_stop_acquire(&dev->channel[i]);
- }
- s2255_stop_readpipe(dev);
- for (i = 0; i < MAX_CHANNELS; i++)
- s2255_release_sys_buffers(&dev->channel[i]);
- /* release transfer buffer */
- kfree(dev->pipe.transfer_buffer);
- return 0;
-}
-
-static void read_pipe_completion(struct urb *purb)
-{
- struct s2255_pipeinfo *pipe_info;
- struct s2255_dev *dev;
- int status;
- int pipe;
- pipe_info = purb->context;
- dprintk(100, "%s: urb:%p, status %d\n", __func__, purb,
- purb->status);
- if (pipe_info == NULL) {
- dev_err(&purb->dev->dev, "no context!\n");
- return;
- }
-
- dev = pipe_info->dev;
- if (dev == NULL) {
- dev_err(&purb->dev->dev, "no context!\n");
- return;
- }
- status = purb->status;
- /* if shutting down, do not resubmit, exit immediately */
- if (status == -ESHUTDOWN) {
- dprintk(2, "%s: err shutdown\n", __func__);
- pipe_info->err_count++;
- return;
- }
-
- if (pipe_info->state == 0) {
- dprintk(2, "%s: exiting USB pipe", __func__);
- return;
- }
-
- if (status == 0)
- s2255_read_video_callback(dev, pipe_info);
- else {
- pipe_info->err_count++;
- dprintk(1, "%s: failed URB %d\n", __func__, status);
- }
-
- pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
- /* reuse urb */
- usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
- pipe,
- pipe_info->transfer_buffer,
- pipe_info->cur_transfer_size,
- read_pipe_completion, pipe_info);
-
- if (pipe_info->state != 0) {
- if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) {
- dev_err(&dev->udev->dev, "error submitting urb\n");
- }
- } else {
- dprintk(2, "%s :complete state 0\n", __func__);
- }
- return;
-}
-
-static int s2255_start_readpipe(struct s2255_dev *dev)
-{
- int pipe;
- int retval;
- struct s2255_pipeinfo *pipe_info = &dev->pipe;
- pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
- dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint);
- pipe_info->state = 1;
- pipe_info->err_count = 0;
- pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!pipe_info->stream_urb) {
- dev_err(&dev->udev->dev,
- "ReadStream: Unable to alloc URB\n");
- return -ENOMEM;
- }
- /* transfer buffer allocated in board_init */
- usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
- pipe,
- pipe_info->transfer_buffer,
- pipe_info->cur_transfer_size,
- read_pipe_completion, pipe_info);
- retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
- if (retval) {
- printk(KERN_ERR "s2255: start read pipe failed\n");
- return retval;
- }
- return 0;
-}
-
-/* starts acquisition process */
-static int s2255_start_acquire(struct s2255_channel *channel)
-{
- unsigned char *buffer;
- int res;
- unsigned long chn_rev;
- int j;
- struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
- chn_rev = G_chnmap[channel->idx];
- buffer = kzalloc(512, GFP_KERNEL);
- if (buffer == NULL) {
- dev_err(&dev->udev->dev, "out of mem\n");
- return -ENOMEM;
- }
-
- channel->last_frame = -1;
- channel->bad_payload = 0;
- channel->cur_frame = 0;
- for (j = 0; j < SYS_FRAMES; j++) {
- channel->buffer.frame[j].ulState = 0;
- channel->buffer.frame[j].cur_size = 0;
- }
-
- /* send the start command */
- *(__le32 *) buffer = IN_DATA_TOKEN;
- *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
- *((__le32 *) buffer + 2) = CMD_START;
- res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
- if (res != 0)
- dev_err(&dev->udev->dev, "CMD_START error\n");
-
- dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res);
- kfree(buffer);
- return 0;
-}
-
-static int s2255_stop_acquire(struct s2255_channel *channel)
-{
- unsigned char *buffer;
- int res;
- unsigned long chn_rev;
- struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
- chn_rev = G_chnmap[channel->idx];
- buffer = kzalloc(512, GFP_KERNEL);
- if (buffer == NULL) {
- dev_err(&dev->udev->dev, "out of mem\n");
- return -ENOMEM;
- }
- /* send the stop command */
- *(__le32 *) buffer = IN_DATA_TOKEN;
- *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
- *((__le32 *) buffer + 2) = CMD_STOP;
- res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
- if (res != 0)
- dev_err(&dev->udev->dev, "CMD_STOP error\n");
- kfree(buffer);
- channel->b_acquire = 0;
- dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
- return res;
-}
-
-static void s2255_stop_readpipe(struct s2255_dev *dev)
-{
- struct s2255_pipeinfo *pipe = &dev->pipe;
-
- pipe->state = 0;
- if (pipe->stream_urb) {
- /* cancel urb */
- usb_kill_urb(pipe->stream_urb);
- usb_free_urb(pipe->stream_urb);
- pipe->stream_urb = NULL;
- }
- dprintk(4, "%s", __func__);
- return;
-}
-
-static void s2255_fwload_start(struct s2255_dev *dev, int reset)
-{
- if (reset)
- s2255_reset_dsppower(dev);
- dev->fw_data->fw_size = dev->fw_data->fw->size;
- atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
- memcpy(dev->fw_data->pfw_data,
- dev->fw_data->fw->data, CHUNK_SIZE);
- dev->fw_data->fw_loaded = CHUNK_SIZE;
- usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
- usb_sndbulkpipe(dev->udev, 2),
- dev->fw_data->pfw_data,
- CHUNK_SIZE, s2255_fwchunk_complete,
- dev->fw_data);
- mod_timer(&dev->timer, jiffies + HZ);
-}
-
-/* standard usb probe function */
-static int s2255_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- struct s2255_dev *dev = NULL;
- struct usb_host_interface *iface_desc;
- struct usb_endpoint_descriptor *endpoint;
- int i;
- int retval = -ENOMEM;
- __le32 *pdata;
- int fw_size;
- dprintk(2, "%s\n", __func__);
- /* allocate memory for our device state and initialize it to zero */
- dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
- if (dev == NULL) {
- s2255_dev_err(&interface->dev, "out of memory\n");
- return -ENOMEM;
- }
- atomic_set(&dev->num_channels, 0);
- dev->pid = id->idProduct;
- dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
- if (!dev->fw_data)
- goto errorFWDATA1;
- mutex_init(&dev->lock);
- mutex_init(&dev->open_lock);
- /* grab usb_device and save it */
- dev->udev = usb_get_dev(interface_to_usbdev(interface));
- if (dev->udev == NULL) {
- dev_err(&interface->dev, "null usb device\n");
- retval = -ENODEV;
- goto errorUDEV;
- }
- dprintk(1, "dev: %p, udev %p interface %p\n", dev,
- dev->udev, interface);
- dev->interface = interface;
- /* set up the endpoint information */
- iface_desc = interface->cur_altsetting;
- dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
- for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
- endpoint = &iface_desc->endpoint[i].desc;
- if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
- /* we found the bulk in endpoint */
- dev->read_endpoint = endpoint->bEndpointAddress;
- }
- }
-
- if (!dev->read_endpoint) {
- dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
- goto errorEP;
- }
- init_timer(&dev->timer);
- dev->timer.function = s2255_timer;
- dev->timer.data = (unsigned long)dev->fw_data;
- init_waitqueue_head(&dev->fw_data->wait_fw);
- for (i = 0; i < MAX_CHANNELS; i++) {
- struct s2255_channel *channel = &dev->channel[i];
- dev->channel[i].idx = i;
- init_waitqueue_head(&channel->wait_setmode);
- init_waitqueue_head(&channel->wait_vidstatus);
- }
-
- dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->fw_data->fw_urb) {
- dev_err(&interface->dev, "out of memory!\n");
- goto errorFWURB;
- }
-
- dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
- if (!dev->fw_data->pfw_data) {
- dev_err(&interface->dev, "out of memory!\n");
- goto errorFWDATA2;
- }
- /* load the first chunk */
- if (request_firmware(&dev->fw_data->fw,
- FIRMWARE_FILE_NAME, &dev->udev->dev)) {
- printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
- goto errorREQFW;
- }
- /* check the firmware is valid */
- fw_size = dev->fw_data->fw->size;
- pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
-
- if (*pdata != S2255_FW_MARKER) {
- printk(KERN_INFO "Firmware invalid.\n");
- retval = -ENODEV;
- goto errorFWMARKER;
- } else {
- /* make sure firmware is the latest */
- __le32 *pRel;
- pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
- printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
- dev->dsp_fw_ver = le32_to_cpu(*pRel);
- if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
- printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
- if (dev->pid == 0x2257 &&
- dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
- printk(KERN_WARNING "s2255: 2257 requires firmware %d"
- " or above.\n", S2255_MIN_DSP_COLORFILTER);
- }
- usb_reset_device(dev->udev);
- /* load 2255 board specific */
- retval = s2255_board_init(dev);
- if (retval)
- goto errorBOARDINIT;
- spin_lock_init(&dev->slock);
- s2255_fwload_start(dev, 0);
- /* loads v4l specific */
- retval = s2255_probe_v4l(dev);
- if (retval)
- goto errorBOARDINIT;
- dev_info(&interface->dev, "Sensoray 2255 detected\n");
- return 0;
-errorBOARDINIT:
- s2255_board_shutdown(dev);
-errorFWMARKER:
- release_firmware(dev->fw_data->fw);
-errorREQFW:
- kfree(dev->fw_data->pfw_data);
-errorFWDATA2:
- usb_free_urb(dev->fw_data->fw_urb);
-errorFWURB:
- del_timer(&dev->timer);
-errorEP:
- usb_put_dev(dev->udev);
-errorUDEV:
- kfree(dev->fw_data);
- mutex_destroy(&dev->open_lock);
- mutex_destroy(&dev->lock);
-errorFWDATA1:
- kfree(dev);
- printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
- return retval;
-}
-
-/* disconnect routine. when board is removed physically or with rmmod */
-static void s2255_disconnect(struct usb_interface *interface)
-{
- struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
- int i;
- int channels = atomic_read(&dev->num_channels);
- mutex_lock(&dev->lock);
- v4l2_device_disconnect(&dev->v4l2_dev);
- mutex_unlock(&dev->lock);
- /*see comments in the uvc_driver.c usb disconnect function */
- atomic_inc(&dev->num_channels);
- /* unregister each video device. */
- for (i = 0; i < channels; i++)
- video_unregister_device(&dev->channel[i].vdev);
- /* wake up any of our timers */
- atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
- wake_up(&dev->fw_data->wait_fw);
- for (i = 0; i < MAX_CHANNELS; i++) {
- dev->channel[i].setmode_ready = 1;
- wake_up(&dev->channel[i].wait_setmode);
- dev->channel[i].vidstatus_ready = 1;
- wake_up(&dev->channel[i].wait_vidstatus);
- }
- if (atomic_dec_and_test(&dev->num_channels))
- s2255_destroy(dev);
- dev_info(&interface->dev, "%s\n", __func__);
-}
-
-static struct usb_driver s2255_driver = {
- .name = S2255_DRIVER_NAME,
- .probe = s2255_probe,
- .disconnect = s2255_disconnect,
- .id_table = s2255_table,
-};
-
-module_usb_driver(s2255_driver);
-
-MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
-MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(S2255_VERSION);
-MODULE_FIRMWARE(FIRMWARE_FILE_NAME);
diff --git a/drivers/media/video/s5k6aa.c b/drivers/media/video/s5k6aa.c
deleted file mode 100644
index 6625e46a463..00000000000
--- a/drivers/media/video/s5k6aa.c
+++ /dev/null
@@ -1,1670 +0,0 @@
-/*
- * Driver for Samsung S5K6AAFX SXGA 1/6" 1.3M CMOS Image Sensor
- * with embedded SoC ISP.
- *
- * Copyright (C) 2011, Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- *
- * Based on a driver authored by Dongsoo Nathaniel Kim.
- * Copyright (C) 2009, Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/media.h>
-#include <linux/module.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-
-#include <media/media-entity.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-mediabus.h>
-#include <media/s5k6aa.h>
-
-static int debug;
-module_param(debug, int, 0644);
-
-#define DRIVER_NAME "S5K6AA"
-
-/* The token to indicate array termination */
-#define S5K6AA_TERM 0xffff
-#define S5K6AA_OUT_WIDTH_DEF 640
-#define S5K6AA_OUT_HEIGHT_DEF 480
-#define S5K6AA_WIN_WIDTH_MAX 1280
-#define S5K6AA_WIN_HEIGHT_MAX 1024
-#define S5K6AA_WIN_WIDTH_MIN 8
-#define S5K6AA_WIN_HEIGHT_MIN 8
-
-/*
- * H/W register Interface (0xD0000000 - 0xD0000FFF)
- */
-#define AHB_MSB_ADDR_PTR 0xfcfc
-#define GEN_REG_OFFSH 0xd000
-#define REG_CMDWR_ADDRH 0x0028
-#define REG_CMDWR_ADDRL 0x002a
-#define REG_CMDRD_ADDRH 0x002c
-#define REG_CMDRD_ADDRL 0x002e
-#define REG_CMDBUF0_ADDR 0x0f12
-#define REG_CMDBUF1_ADDR 0x0f10
-
-/*
- * Host S/W Register interface (0x70000000 - 0x70002000)
- * The value of the two most significant address bytes is 0x7000,
- * (HOST_SWIF_OFFS_H). The register addresses below specify 2 LSBs.
- */
-#define HOST_SWIF_OFFSH 0x7000
-
-/* Initialization parameters */
-/* Master clock frequency in KHz */
-#define REG_I_INCLK_FREQ_L 0x01b8
-#define REG_I_INCLK_FREQ_H 0x01ba
-#define MIN_MCLK_FREQ_KHZ 6000U
-#define MAX_MCLK_FREQ_KHZ 27000U
-#define REG_I_USE_NPVI_CLOCKS 0x01c6
-#define REG_I_USE_NMIPI_CLOCKS 0x01c8
-
-/* Clock configurations, n = 0..2. REG_I_* frequency unit is 4 kHz. */
-#define REG_I_OPCLK_4KHZ(n) ((n) * 6 + 0x01cc)
-#define REG_I_MIN_OUTRATE_4KHZ(n) ((n) * 6 + 0x01ce)
-#define REG_I_MAX_OUTRATE_4KHZ(n) ((n) * 6 + 0x01d0)
-#define SYS_PLL_OUT_FREQ (48000000 / 4000)
-#define PCLK_FREQ_MIN (24000000 / 4000)
-#define PCLK_FREQ_MAX (48000000 / 4000)
-#define REG_I_INIT_PARAMS_UPDATED 0x01e0
-#define REG_I_ERROR_INFO 0x01e2
-
-/* General purpose parameters */
-#define REG_USER_BRIGHTNESS 0x01e4
-#define REG_USER_CONTRAST 0x01e6
-#define REG_USER_SATURATION 0x01e8
-#define REG_USER_SHARPBLUR 0x01ea
-
-#define REG_G_SPEC_EFFECTS 0x01ee
-#define REG_G_ENABLE_PREV 0x01f0
-#define REG_G_ENABLE_PREV_CHG 0x01f2
-#define REG_G_NEW_CFG_SYNC 0x01f8
-#define REG_G_PREVZOOM_IN_WIDTH 0x020a
-#define REG_G_PREVZOOM_IN_HEIGHT 0x020c
-#define REG_G_PREVZOOM_IN_XOFFS 0x020e
-#define REG_G_PREVZOOM_IN_YOFFS 0x0210
-#define REG_G_INPUTS_CHANGE_REQ 0x021a
-#define REG_G_ACTIVE_PREV_CFG 0x021c
-#define REG_G_PREV_CFG_CHG 0x021e
-#define REG_G_PREV_OPEN_AFTER_CH 0x0220
-#define REG_G_PREV_CFG_ERROR 0x0222
-
-/* Preview control section. n = 0...4. */
-#define PREG(n, x) ((n) * 0x26 + x)
-#define REG_P_OUT_WIDTH(n) PREG(n, 0x0242)
-#define REG_P_OUT_HEIGHT(n) PREG(n, 0x0244)
-#define REG_P_FMT(n) PREG(n, 0x0246)
-#define REG_P_MAX_OUT_RATE(n) PREG(n, 0x0248)
-#define REG_P_MIN_OUT_RATE(n) PREG(n, 0x024a)
-#define REG_P_PVI_MASK(n) PREG(n, 0x024c)
-#define REG_P_CLK_INDEX(n) PREG(n, 0x024e)
-#define REG_P_FR_RATE_TYPE(n) PREG(n, 0x0250)
-#define FR_RATE_DYNAMIC 0
-#define FR_RATE_FIXED 1
-#define FR_RATE_FIXED_ACCURATE 2
-#define REG_P_FR_RATE_Q_TYPE(n) PREG(n, 0x0252)
-#define FR_RATE_Q_BEST_FRRATE 1 /* Binning enabled */
-#define FR_RATE_Q_BEST_QUALITY 2 /* Binning disabled */
-/* Frame period in 0.1 ms units */
-#define REG_P_MAX_FR_TIME(n) PREG(n, 0x0254)
-#define REG_P_MIN_FR_TIME(n) PREG(n, 0x0256)
-/* Conversion to REG_P_[MAX/MIN]_FR_TIME value; __t: time in us */
-#define US_TO_FR_TIME(__t) ((__t) / 100)
-#define S5K6AA_MIN_FR_TIME 33300 /* us */
-#define S5K6AA_MAX_FR_TIME 650000 /* us */
-#define S5K6AA_MAX_HIGHRES_FR_TIME 666 /* x100 us */
-/* The below 5 registers are for "device correction" values */
-#define REG_P_COLORTEMP(n) PREG(n, 0x025e)
-#define REG_P_PREV_MIRROR(n) PREG(n, 0x0262)
-
-/* Extended image property controls */
-/* Exposure time in 10 us units */
-#define REG_SF_USR_EXPOSURE_L 0x03c6
-#define REG_SF_USR_EXPOSURE_H 0x03c8
-#define REG_SF_USR_EXPOSURE_CHG 0x03ca
-#define REG_SF_USR_TOT_GAIN 0x03cc
-#define REG_SF_USR_TOT_GAIN_CHG 0x03ce
-#define REG_SF_RGAIN 0x03d0
-#define REG_SF_RGAIN_CHG 0x03d2
-#define REG_SF_GGAIN 0x03d4
-#define REG_SF_GGAIN_CHG 0x03d6
-#define REG_SF_BGAIN 0x03d8
-#define REG_SF_BGAIN_CHG 0x03da
-#define REG_SF_FLICKER_QUANT 0x03dc
-#define REG_SF_FLICKER_QUANT_CHG 0x03de
-
-/* Output interface (parallel/MIPI) setup */
-#define REG_OIF_EN_MIPI_LANES 0x03fa
-#define REG_OIF_EN_PACKETS 0x03fc
-#define REG_OIF_CFG_CHG 0x03fe
-
-/* Auto-algorithms enable mask */
-#define REG_DBG_AUTOALG_EN 0x0400
-#define AALG_ALL_EN_MASK (1 << 0)
-#define AALG_AE_EN_MASK (1 << 1)
-#define AALG_DIVLEI_EN_MASK (1 << 2)
-#define AALG_WB_EN_MASK (1 << 3)
-#define AALG_FLICKER_EN_MASK (1 << 5)
-#define AALG_FIT_EN_MASK (1 << 6)
-#define AALG_WRHW_EN_MASK (1 << 7)
-
-/* Firmware revision information */
-#define REG_FW_APIVER 0x012e
-#define S5K6AAFX_FW_APIVER 0x0001
-#define REG_FW_REVISION 0x0130
-
-/* For now we use only one user configuration register set */
-#define S5K6AA_MAX_PRESETS 1
-
-static const char * const s5k6aa_supply_names[] = {
- "vdd_core", /* Digital core supply 1.5V (1.4V to 1.6V) */
- "vdda", /* Analog power supply 2.8V (2.6V to 3.0V) */
- "vdd_reg", /* Regulator input power 1.8V (1.7V to 1.9V)
- or 2.8V (2.6V to 3.0) */
- "vddio", /* I/O supply 1.8V (1.65V to 1.95V)
- or 2.8V (2.5V to 3.1V) */
-};
-#define S5K6AA_NUM_SUPPLIES ARRAY_SIZE(s5k6aa_supply_names)
-
-enum s5k6aa_gpio_id {
- STBY,
- RST,
- GPIO_NUM,
-};
-
-struct s5k6aa_regval {
- u16 addr;
- u16 val;
-};
-
-struct s5k6aa_pixfmt {
- enum v4l2_mbus_pixelcode code;
- u32 colorspace;
- /* REG_P_FMT(x) register value */
- u16 reg_p_fmt;
-};
-
-struct s5k6aa_preset {
- /* output pixel format and resolution */
- struct v4l2_mbus_framefmt mbus_fmt;
- u8 clk_id;
- u8 index;
-};
-
-struct s5k6aa_ctrls {
- struct v4l2_ctrl_handler handler;
- /* Auto / manual white balance cluster */
- struct v4l2_ctrl *awb;
- struct v4l2_ctrl *gain_red;
- struct v4l2_ctrl *gain_blue;
- struct v4l2_ctrl *gain_green;
- /* Mirror cluster */
- struct v4l2_ctrl *hflip;
- struct v4l2_ctrl *vflip;
- /* Auto exposure / manual exposure and gain cluster */
- struct v4l2_ctrl *auto_exp;
- struct v4l2_ctrl *exposure;
- struct v4l2_ctrl *gain;
-};
-
-struct s5k6aa_interval {
- u16 reg_fr_time;
- struct v4l2_fract interval;
- /* Maximum rectangle for the interval */
- struct v4l2_frmsize_discrete size;
-};
-
-struct s5k6aa {
- struct v4l2_subdev sd;
- struct media_pad pad;
-
- enum v4l2_mbus_type bus_type;
- u8 mipi_lanes;
-
- int (*s_power)(int enable);
- struct regulator_bulk_data supplies[S5K6AA_NUM_SUPPLIES];
- struct s5k6aa_gpio gpio[GPIO_NUM];
-
- /* external master clock frequency */
- unsigned long mclk_frequency;
- /* ISP internal master clock frequency */
- u16 clk_fop;
- /* output pixel clock frequency range */
- u16 pclk_fmin;
- u16 pclk_fmax;
-
- unsigned int inv_hflip:1;
- unsigned int inv_vflip:1;
-
- /* protects the struct members below */
- struct mutex lock;
-
- /* sensor matrix scan window */
- struct v4l2_rect ccd_rect;
-
- struct s5k6aa_ctrls ctrls;
- struct s5k6aa_preset presets[S5K6AA_MAX_PRESETS];
- struct s5k6aa_preset *preset;
- const struct s5k6aa_interval *fiv;
-
- unsigned int streaming:1;
- unsigned int apply_cfg:1;
- unsigned int apply_crop:1;
- unsigned int power;
-};
-
-static struct s5k6aa_regval s5k6aa_analog_config[] = {
- /* Analog settings */
- { 0x112a, 0x0000 }, { 0x1132, 0x0000 },
- { 0x113e, 0x0000 }, { 0x115c, 0x0000 },
- { 0x1164, 0x0000 }, { 0x1174, 0x0000 },
- { 0x1178, 0x0000 }, { 0x077a, 0x0000 },
- { 0x077c, 0x0000 }, { 0x077e, 0x0000 },
- { 0x0780, 0x0000 }, { 0x0782, 0x0000 },
- { 0x0784, 0x0000 }, { 0x0786, 0x0000 },
- { 0x0788, 0x0000 }, { 0x07a2, 0x0000 },
- { 0x07a4, 0x0000 }, { 0x07a6, 0x0000 },
- { 0x07a8, 0x0000 }, { 0x07b6, 0x0000 },
- { 0x07b8, 0x0002 }, { 0x07ba, 0x0004 },
- { 0x07bc, 0x0004 }, { 0x07be, 0x0005 },
- { 0x07c0, 0x0005 }, { S5K6AA_TERM, 0 },
-};
-
-/* TODO: Add RGB888 and Bayer format */
-static const struct s5k6aa_pixfmt s5k6aa_formats[] = {
- { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 5 },
- /* range 16-240 */
- { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_REC709, 6 },
- { V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_JPEG, 0 },
-};
-
-static const struct s5k6aa_interval s5k6aa_intervals[] = {
- { 1000, {10000, 1000000}, {1280, 1024} }, /* 10 fps */
- { 666, {15000, 1000000}, {1280, 1024} }, /* 15 fps */
- { 500, {20000, 1000000}, {1280, 720} }, /* 20 fps */
- { 400, {25000, 1000000}, {640, 480} }, /* 25 fps */
- { 333, {33300, 1000000}, {640, 480} }, /* 30 fps */
-};
-
-#define S5K6AA_INTERVAL_DEF_INDEX 1 /* 15 fps */
-
-static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct s5k6aa, ctrls.handler)->sd;
-}
-
-static inline struct s5k6aa *to_s5k6aa(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct s5k6aa, sd);
-}
-
-/* Set initial values for all preview presets */
-static void s5k6aa_presets_data_init(struct s5k6aa *s5k6aa)
-{
- struct s5k6aa_preset *preset = &s5k6aa->presets[0];
- int i;
-
- for (i = 0; i < S5K6AA_MAX_PRESETS; i++) {
- preset->mbus_fmt.width = S5K6AA_OUT_WIDTH_DEF;
- preset->mbus_fmt.height = S5K6AA_OUT_HEIGHT_DEF;
- preset->mbus_fmt.code = s5k6aa_formats[0].code;
- preset->index = i;
- preset->clk_id = 0;
- preset++;
- }
-
- s5k6aa->fiv = &s5k6aa_intervals[S5K6AA_INTERVAL_DEF_INDEX];
- s5k6aa->preset = &s5k6aa->presets[0];
-}
-
-static int s5k6aa_i2c_read(struct i2c_client *client, u16 addr, u16 *val)
-{
- u8 wbuf[2] = {addr >> 8, addr & 0xFF};
- struct i2c_msg msg[2];
- u8 rbuf[2];
- int ret;
-
- msg[0].addr = client->addr;
- msg[0].flags = 0;
- msg[0].len = 2;
- msg[0].buf = wbuf;
-
- msg[1].addr = client->addr;
- msg[1].flags = I2C_M_RD;
- msg[1].len = 2;
- msg[1].buf = rbuf;
-
- ret = i2c_transfer(client->adapter, msg, 2);
- *val = be16_to_cpu(*((u16 *)rbuf));
-
- v4l2_dbg(3, debug, client, "i2c_read: 0x%04X : 0x%04x\n", addr, *val);
-
- return ret == 2 ? 0 : ret;
-}
-
-static int s5k6aa_i2c_write(struct i2c_client *client, u16 addr, u16 val)
-{
- u8 buf[4] = {addr >> 8, addr & 0xFF, val >> 8, val & 0xFF};
-
- int ret = i2c_master_send(client, buf, 4);
- v4l2_dbg(3, debug, client, "i2c_write: 0x%04X : 0x%04x\n", addr, val);
-
- return ret == 4 ? 0 : ret;
-}
-
-/* The command register write, assumes Command_Wr_addH = 0x7000. */
-static int s5k6aa_write(struct i2c_client *c, u16 addr, u16 val)
-{
- int ret = s5k6aa_i2c_write(c, REG_CMDWR_ADDRL, addr);
- if (ret)
- return ret;
- return s5k6aa_i2c_write(c, REG_CMDBUF0_ADDR, val);
-}
-
-/* The command register read, assumes Command_Rd_addH = 0x7000. */
-static int s5k6aa_read(struct i2c_client *client, u16 addr, u16 *val)
-{
- int ret = s5k6aa_i2c_write(client, REG_CMDRD_ADDRL, addr);
- if (ret)
- return ret;
- return s5k6aa_i2c_read(client, REG_CMDBUF0_ADDR, val);
-}
-
-static int s5k6aa_write_array(struct v4l2_subdev *sd,
- const struct s5k6aa_regval *msg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u16 addr_incr = 0;
- int ret = 0;
-
- while (msg->addr != S5K6AA_TERM) {
- if (addr_incr != 2)
- ret = s5k6aa_i2c_write(client, REG_CMDWR_ADDRL,
- msg->addr);
- if (ret)
- break;
- ret = s5k6aa_i2c_write(client, REG_CMDBUF0_ADDR, msg->val);
- if (ret)
- break;
- /* Assume that msg->addr is always less than 0xfffc */
- addr_incr = (msg + 1)->addr - msg->addr;
- msg++;
- }
-
- return ret;
-}
-
-/* Configure the AHB high address bytes for GTG registers access */
-static int s5k6aa_set_ahb_address(struct i2c_client *client)
-{
- int ret = s5k6aa_i2c_write(client, AHB_MSB_ADDR_PTR, GEN_REG_OFFSH);
- if (ret)
- return ret;
- ret = s5k6aa_i2c_write(client, REG_CMDRD_ADDRH, HOST_SWIF_OFFSH);
- if (ret)
- return ret;
- return s5k6aa_i2c_write(client, REG_CMDWR_ADDRH, HOST_SWIF_OFFSH);
-}
-
-/**
- * s5k6aa_configure_pixel_clock - apply ISP main clock/PLL configuration
- *
- * Configure the internal ISP PLL for the required output frequency.
- * Locking: called with s5k6aa.lock mutex held.
- */
-static int s5k6aa_configure_pixel_clocks(struct s5k6aa *s5k6aa)
-{
- struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
- unsigned long fmclk = s5k6aa->mclk_frequency / 1000;
- u16 status;
- int ret;
-
- if (WARN(fmclk < MIN_MCLK_FREQ_KHZ || fmclk > MAX_MCLK_FREQ_KHZ,
- "Invalid clock frequency: %ld\n", fmclk))
- return -EINVAL;
-
- s5k6aa->pclk_fmin = PCLK_FREQ_MIN;
- s5k6aa->pclk_fmax = PCLK_FREQ_MAX;
- s5k6aa->clk_fop = SYS_PLL_OUT_FREQ;
-
- /* External input clock frequency in kHz */
- ret = s5k6aa_write(c, REG_I_INCLK_FREQ_H, fmclk >> 16);
- if (!ret)
- ret = s5k6aa_write(c, REG_I_INCLK_FREQ_L, fmclk & 0xFFFF);
- if (!ret)
- ret = s5k6aa_write(c, REG_I_USE_NPVI_CLOCKS, 1);
- /* Internal PLL frequency */
- if (!ret)
- ret = s5k6aa_write(c, REG_I_OPCLK_4KHZ(0), s5k6aa->clk_fop);
- if (!ret)
- ret = s5k6aa_write(c, REG_I_MIN_OUTRATE_4KHZ(0),
- s5k6aa->pclk_fmin);
- if (!ret)
- ret = s5k6aa_write(c, REG_I_MAX_OUTRATE_4KHZ(0),
- s5k6aa->pclk_fmax);
- if (!ret)
- ret = s5k6aa_write(c, REG_I_INIT_PARAMS_UPDATED, 1);
- if (!ret)
- ret = s5k6aa_read(c, REG_I_ERROR_INFO, &status);
-
- return ret ? ret : (status ? -EINVAL : 0);
-}
-
-/* Set horizontal and vertical image flipping */
-static int s5k6aa_set_mirror(struct s5k6aa *s5k6aa, int horiz_flip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
- int index = s5k6aa->preset->index;
-
- unsigned int vflip = s5k6aa->ctrls.vflip->val ^ s5k6aa->inv_vflip;
- unsigned int flip = (horiz_flip ^ s5k6aa->inv_hflip) | (vflip << 1);
-
- return s5k6aa_write(client, REG_P_PREV_MIRROR(index), flip);
-}
-
-/* Configure auto/manual white balance and R/G/B gains */
-static int s5k6aa_set_awb(struct s5k6aa *s5k6aa, int awb)
-{
- struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
- struct s5k6aa_ctrls *ctrls = &s5k6aa->ctrls;
- u16 reg;
-
- int ret = s5k6aa_read(c, REG_DBG_AUTOALG_EN, &reg);
-
- if (!ret && !awb) {
- ret = s5k6aa_write(c, REG_SF_RGAIN, ctrls->gain_red->val);
- if (!ret)
- ret = s5k6aa_write(c, REG_SF_RGAIN_CHG, 1);
- if (ret)
- return ret;
-
- ret = s5k6aa_write(c, REG_SF_GGAIN, ctrls->gain_green->val);
- if (!ret)
- ret = s5k6aa_write(c, REG_SF_GGAIN_CHG, 1);
- if (ret)
- return ret;
-
- ret = s5k6aa_write(c, REG_SF_BGAIN, ctrls->gain_blue->val);
- if (!ret)
- ret = s5k6aa_write(c, REG_SF_BGAIN_CHG, 1);
- }
- if (!ret) {
- reg = awb ? reg | AALG_WB_EN_MASK : reg & ~AALG_WB_EN_MASK;
- ret = s5k6aa_write(c, REG_DBG_AUTOALG_EN, reg);
- }
-
- return ret;
-}
-
-/* Program FW with exposure time, 'exposure' in us units */
-static int s5k6aa_set_user_exposure(struct i2c_client *client, int exposure)
-{
- unsigned int time = exposure / 10;
-
- int ret = s5k6aa_write(client, REG_SF_USR_EXPOSURE_L, time & 0xffff);
- if (!ret)
- ret = s5k6aa_write(client, REG_SF_USR_EXPOSURE_H, time >> 16);
- if (ret)
- return ret;
- return s5k6aa_write(client, REG_SF_USR_EXPOSURE_CHG, 1);
-}
-
-static int s5k6aa_set_user_gain(struct i2c_client *client, int gain)
-{
- int ret = s5k6aa_write(client, REG_SF_USR_TOT_GAIN, gain);
- if (ret)
- return ret;
- return s5k6aa_write(client, REG_SF_USR_TOT_GAIN_CHG, 1);
-}
-
-/* Set auto/manual exposure and total gain */
-static int s5k6aa_set_auto_exposure(struct s5k6aa *s5k6aa, int value)
-{
- struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
- unsigned int exp_time = s5k6aa->ctrls.exposure->val;
- u16 auto_alg;
-
- int ret = s5k6aa_read(c, REG_DBG_AUTOALG_EN, &auto_alg);
- if (ret)
- return ret;
-
- v4l2_dbg(1, debug, c, "man_exp: %d, auto_exp: %d, a_alg: 0x%x\n",
- exp_time, value, auto_alg);
-
- if (value == V4L2_EXPOSURE_AUTO) {
- auto_alg |= AALG_AE_EN_MASK | AALG_DIVLEI_EN_MASK;
- } else {
- ret = s5k6aa_set_user_exposure(c, exp_time);
- if (ret)
- return ret;
- ret = s5k6aa_set_user_gain(c, s5k6aa->ctrls.gain->val);
- if (ret)
- return ret;
- auto_alg &= ~(AALG_AE_EN_MASK | AALG_DIVLEI_EN_MASK);
- }
-
- return s5k6aa_write(c, REG_DBG_AUTOALG_EN, auto_alg);
-}
-
-static int s5k6aa_set_anti_flicker(struct s5k6aa *s5k6aa, int value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
- u16 auto_alg;
- int ret;
-
- ret = s5k6aa_read(client, REG_DBG_AUTOALG_EN, &auto_alg);
- if (ret)
- return ret;
-
- if (value == V4L2_CID_POWER_LINE_FREQUENCY_AUTO) {
- auto_alg |= AALG_FLICKER_EN_MASK;
- } else {
- auto_alg &= ~AALG_FLICKER_EN_MASK;
- /* The V4L2_CID_LINE_FREQUENCY control values match
- * the register values */
- ret = s5k6aa_write(client, REG_SF_FLICKER_QUANT, value);
- if (ret)
- return ret;
- ret = s5k6aa_write(client, REG_SF_FLICKER_QUANT_CHG, 1);
- if (ret)
- return ret;
- }
-
- return s5k6aa_write(client, REG_DBG_AUTOALG_EN, auto_alg);
-}
-
-static int s5k6aa_set_colorfx(struct s5k6aa *s5k6aa, int val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
- static const struct v4l2_control colorfx[] = {
- { V4L2_COLORFX_NONE, 0 },
- { V4L2_COLORFX_BW, 1 },
- { V4L2_COLORFX_NEGATIVE, 2 },
- { V4L2_COLORFX_SEPIA, 3 },
- { V4L2_COLORFX_SKY_BLUE, 4 },
- { V4L2_COLORFX_SKETCH, 5 },
- };
- int i;
-
- for (i = 0; i < ARRAY_SIZE(colorfx); i++) {
- if (colorfx[i].id == val)
- return s5k6aa_write(client, REG_G_SPEC_EFFECTS,
- colorfx[i].value);
- }
- return -EINVAL;
-}
-
-static int s5k6aa_preview_config_status(struct i2c_client *client)
-{
- u16 error = 0;
- int ret = s5k6aa_read(client, REG_G_PREV_CFG_ERROR, &error);
-
- v4l2_dbg(1, debug, client, "error: 0x%x (%d)\n", error, ret);
- return ret ? ret : (error ? -EINVAL : 0);
-}
-
-static int s5k6aa_get_pixfmt_index(struct s5k6aa *s5k6aa,
- struct v4l2_mbus_framefmt *mf)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(s5k6aa_formats); i++)
- if (mf->colorspace == s5k6aa_formats[i].colorspace &&
- mf->code == s5k6aa_formats[i].code)
- return i;
- return 0;
-}
-
-static int s5k6aa_set_output_framefmt(struct s5k6aa *s5k6aa,
- struct s5k6aa_preset *preset)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
- int fmt_index = s5k6aa_get_pixfmt_index(s5k6aa, &preset->mbus_fmt);
- int ret;
-
- ret = s5k6aa_write(client, REG_P_OUT_WIDTH(preset->index),
- preset->mbus_fmt.width);
- if (!ret)
- ret = s5k6aa_write(client, REG_P_OUT_HEIGHT(preset->index),
- preset->mbus_fmt.height);
- if (!ret)
- ret = s5k6aa_write(client, REG_P_FMT(preset->index),
- s5k6aa_formats[fmt_index].reg_p_fmt);
- return ret;
-}
-
-static int s5k6aa_set_input_params(struct s5k6aa *s5k6aa)
-{
- struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
- struct v4l2_rect *r = &s5k6aa->ccd_rect;
- int ret;
-
- ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_WIDTH, r->width);
- if (!ret)
- ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_HEIGHT, r->height);
- if (!ret)
- ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_XOFFS, r->left);
- if (!ret)
- ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_YOFFS, r->top);
- if (!ret)
- ret = s5k6aa_write(c, REG_G_INPUTS_CHANGE_REQ, 1);
- if (!ret)
- s5k6aa->apply_crop = 0;
-
- return ret;
-}
-
-/**
- * s5k6aa_configure_video_bus - configure the video output interface
- * @bus_type: video bus type: parallel or MIPI-CSI
- * @nlanes: number of MIPI lanes to be used (MIPI-CSI only)
- *
- * Note: Only parallel bus operation has been tested.
- */
-static int s5k6aa_configure_video_bus(struct s5k6aa *s5k6aa,
- enum v4l2_mbus_type bus_type, int nlanes)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
- u16 cfg = 0;
- int ret;
-
- /*
- * TODO: The sensor is supposed to support BT.601 and BT.656
- * but there is nothing indicating how to switch between both
- * in the datasheet. For now default BT.601 interface is assumed.
- */
- if (bus_type == V4L2_MBUS_CSI2)
- cfg = nlanes;
- else if (bus_type != V4L2_MBUS_PARALLEL)
- return -EINVAL;
-
- ret = s5k6aa_write(client, REG_OIF_EN_MIPI_LANES, cfg);
- if (ret)
- return ret;
- return s5k6aa_write(client, REG_OIF_CFG_CHG, 1);
-}
-
-/* This function should be called when switching to new user configuration set*/
-static int s5k6aa_new_config_sync(struct i2c_client *client, int timeout,
- int cid)
-{
- unsigned long end = jiffies + msecs_to_jiffies(timeout);
- u16 reg = 1;
- int ret;
-
- ret = s5k6aa_write(client, REG_G_ACTIVE_PREV_CFG, cid);
- if (!ret)
- ret = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
- if (!ret)
- ret = s5k6aa_write(client, REG_G_NEW_CFG_SYNC, 1);
- if (timeout == 0)
- return ret;
-
- while (ret >= 0 && time_is_after_jiffies(end)) {
- ret = s5k6aa_read(client, REG_G_NEW_CFG_SYNC, &reg);
- if (!reg)
- return 0;
- usleep_range(1000, 5000);
- }
- return ret ? ret : -ETIMEDOUT;
-}
-
-/**
- * s5k6aa_set_prev_config - write user preview register set
- *
- * Configure output resolution and color fromat, pixel clock
- * frequency range, device frame rate type and frame period range.
- */
-static int s5k6aa_set_prev_config(struct s5k6aa *s5k6aa,
- struct s5k6aa_preset *preset)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
- int idx = preset->index;
- u16 frame_rate_q;
- int ret;
-
- if (s5k6aa->fiv->reg_fr_time >= S5K6AA_MAX_HIGHRES_FR_TIME)
- frame_rate_q = FR_RATE_Q_BEST_FRRATE;
- else
- frame_rate_q = FR_RATE_Q_BEST_QUALITY;
-
- ret = s5k6aa_set_output_framefmt(s5k6aa, preset);
- if (!ret)
- ret = s5k6aa_write(client, REG_P_MAX_OUT_RATE(idx),
- s5k6aa->pclk_fmax);
- if (!ret)
- ret = s5k6aa_write(client, REG_P_MIN_OUT_RATE(idx),
- s5k6aa->pclk_fmin);
- if (!ret)
- ret = s5k6aa_write(client, REG_P_CLK_INDEX(idx),
- preset->clk_id);
- if (!ret)
- ret = s5k6aa_write(client, REG_P_FR_RATE_TYPE(idx),
- FR_RATE_DYNAMIC);
- if (!ret)
- ret = s5k6aa_write(client, REG_P_FR_RATE_Q_TYPE(idx),
- frame_rate_q);
- if (!ret)
- ret = s5k6aa_write(client, REG_P_MAX_FR_TIME(idx),
- s5k6aa->fiv->reg_fr_time + 33);
- if (!ret)
- ret = s5k6aa_write(client, REG_P_MIN_FR_TIME(idx),
- s5k6aa->fiv->reg_fr_time - 33);
- if (!ret)
- ret = s5k6aa_new_config_sync(client, 250, idx);
- if (!ret)
- ret = s5k6aa_preview_config_status(client);
- if (!ret)
- s5k6aa->apply_cfg = 0;
-
- v4l2_dbg(1, debug, client, "Frame interval: %d +/- 3.3ms. (%d)\n",
- s5k6aa->fiv->reg_fr_time, ret);
- return ret;
-}
-
-/**
- * s5k6aa_initialize_isp - basic ISP MCU initialization
- *
- * Configure AHB addresses for registers read/write; configure PLLs for
- * required output pixel clock. The ISP power supply needs to be already
- * enabled, with an optional H/W reset.
- * Locking: called with s5k6aa.lock mutex held.
- */
-static int s5k6aa_initialize_isp(struct v4l2_subdev *sd)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct s5k6aa *s5k6aa = to_s5k6aa(sd);
- int ret;
-
- s5k6aa->apply_crop = 1;
- s5k6aa->apply_cfg = 1;
- msleep(100);
-
- ret = s5k6aa_set_ahb_address(client);
- if (ret)
- return ret;
- ret = s5k6aa_configure_video_bus(s5k6aa, s5k6aa->bus_type,
- s5k6aa->mipi_lanes);
- if (ret)
- return ret;
- ret = s5k6aa_write_array(sd, s5k6aa_analog_config);
- if (ret)
- return ret;
- msleep(20);
-
- return s5k6aa_configure_pixel_clocks(s5k6aa);
-}
-
-static int s5k6aa_gpio_set_value(struct s5k6aa *priv, int id, u32 val)
-{
- if (!gpio_is_valid(priv->gpio[id].gpio))
- return 0;
- gpio_set_value(priv->gpio[id].gpio, !!val);
- return 1;
-}
-
-static int s5k6aa_gpio_assert(struct s5k6aa *priv, int id)
-{
- return s5k6aa_gpio_set_value(priv, id, priv->gpio[id].level);
-}
-
-static int s5k6aa_gpio_deassert(struct s5k6aa *priv, int id)
-{
- return s5k6aa_gpio_set_value(priv, id, !priv->gpio[id].level);
-}
-
-static int __s5k6aa_power_on(struct s5k6aa *s5k6aa)
-{
- int ret;
-
- ret = regulator_bulk_enable(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
- if (ret)
- return ret;
- if (s5k6aa_gpio_deassert(s5k6aa, STBY))
- usleep_range(150, 200);
-
- if (s5k6aa->s_power)
- ret = s5k6aa->s_power(1);
- usleep_range(4000, 4000);
-
- if (s5k6aa_gpio_deassert(s5k6aa, RST))
- msleep(20);
-
- return ret;
-}
-
-static int __s5k6aa_power_off(struct s5k6aa *s5k6aa)
-{
- int ret;
-
- if (s5k6aa_gpio_assert(s5k6aa, RST))
- usleep_range(100, 150);
-
- if (s5k6aa->s_power) {
- ret = s5k6aa->s_power(0);
- if (ret)
- return ret;
- }
- if (s5k6aa_gpio_assert(s5k6aa, STBY))
- usleep_range(50, 100);
- s5k6aa->streaming = 0;
-
- return regulator_bulk_disable(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
-}
-
-/*
- * V4L2 subdev core and video operations
- */
-static int s5k6aa_set_power(struct v4l2_subdev *sd, int on)
-{
- struct s5k6aa *s5k6aa = to_s5k6aa(sd);
- int ret = 0;
-
- mutex_lock(&s5k6aa->lock);
-
- if (!on == s5k6aa->power) {
- if (on) {
- ret = __s5k6aa_power_on(s5k6aa);
- if (!ret)
- ret = s5k6aa_initialize_isp(sd);
- } else {
- ret = __s5k6aa_power_off(s5k6aa);
- }
-
- if (!ret)
- s5k6aa->power += on ? 1 : -1;
- }
-
- mutex_unlock(&s5k6aa->lock);
-
- if (!on || ret || s5k6aa->power != 1)
- return ret;
-
- return v4l2_ctrl_handler_setup(sd->ctrl_handler);
-}
-
-static int __s5k6aa_stream(struct s5k6aa *s5k6aa, int enable)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
- int ret = 0;
-
- ret = s5k6aa_write(client, REG_G_ENABLE_PREV, enable);
- if (!ret)
- ret = s5k6aa_write(client, REG_G_ENABLE_PREV_CHG, 1);
- if (!ret)
- s5k6aa->streaming = enable;
-
- return ret;
-}
-
-static int s5k6aa_s_stream(struct v4l2_subdev *sd, int on)
-{
- struct s5k6aa *s5k6aa = to_s5k6aa(sd);
- int ret = 0;
-
- mutex_lock(&s5k6aa->lock);
-
- if (s5k6aa->streaming == !on) {
- if (!ret && s5k6aa->apply_cfg)
- ret = s5k6aa_set_prev_config(s5k6aa, s5k6aa->preset);
- if (s5k6aa->apply_crop)
- ret = s5k6aa_set_input_params(s5k6aa);
- if (!ret)
- ret = __s5k6aa_stream(s5k6aa, !!on);
- }
- mutex_unlock(&s5k6aa->lock);
-
- return ret;
-}
-
-static int s5k6aa_g_frame_interval(struct v4l2_subdev *sd,
- struct v4l2_subdev_frame_interval *fi)
-{
- struct s5k6aa *s5k6aa = to_s5k6aa(sd);
-
- mutex_lock(&s5k6aa->lock);
- fi->interval = s5k6aa->fiv->interval;
- mutex_unlock(&s5k6aa->lock);
-
- return 0;
-}
-
-static int __s5k6aa_set_frame_interval(struct s5k6aa *s5k6aa,
- struct v4l2_subdev_frame_interval *fi)
-{
- struct v4l2_mbus_framefmt *mbus_fmt = &s5k6aa->preset->mbus_fmt;
- const struct s5k6aa_interval *fiv = &s5k6aa_intervals[0];
- unsigned int err, min_err = UINT_MAX;
- unsigned int i, fr_time;
-
- if (fi->interval.denominator == 0)
- return -EINVAL;
-
- fr_time = fi->interval.numerator * 10000 / fi->interval.denominator;
-
- for (i = 0; i < ARRAY_SIZE(s5k6aa_intervals); i++) {
- const struct s5k6aa_interval *iv = &s5k6aa_intervals[i];
-
- if (mbus_fmt->width > iv->size.width ||
- mbus_fmt->height > iv->size.height)
- continue;
-
- err = abs(iv->reg_fr_time - fr_time);
- if (err < min_err) {
- fiv = iv;
- min_err = err;
- }
- }
- s5k6aa->fiv = fiv;
-
- v4l2_dbg(1, debug, &s5k6aa->sd, "Changed frame interval to %d us\n",
- fiv->reg_fr_time * 100);
- return 0;
-}
-
-static int s5k6aa_s_frame_interval(struct v4l2_subdev *sd,
- struct v4l2_subdev_frame_interval *fi)
-{
- struct s5k6aa *s5k6aa = to_s5k6aa(sd);
- int ret;
-
- v4l2_dbg(1, debug, sd, "Setting %d/%d frame interval\n",
- fi->interval.numerator, fi->interval.denominator);
-
- mutex_lock(&s5k6aa->lock);
- ret = __s5k6aa_set_frame_interval(s5k6aa, fi);
- s5k6aa->apply_cfg = 1;
-
- mutex_unlock(&s5k6aa->lock);
- return ret;
-}
-
-/*
- * V4L2 subdev pad level and video operations
- */
-static int s5k6aa_enum_frame_interval(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_frame_interval_enum *fie)
-{
- struct s5k6aa *s5k6aa = to_s5k6aa(sd);
- const struct s5k6aa_interval *fi;
- int ret = 0;
-
- if (fie->index > ARRAY_SIZE(s5k6aa_intervals))
- return -EINVAL;
-
- v4l_bound_align_image(&fie->width, S5K6AA_WIN_WIDTH_MIN,
- S5K6AA_WIN_WIDTH_MAX, 1,
- &fie->height, S5K6AA_WIN_HEIGHT_MIN,
- S5K6AA_WIN_HEIGHT_MAX, 1, 0);
-
- mutex_lock(&s5k6aa->lock);
- fi = &s5k6aa_intervals[fie->index];
- if (fie->width > fi->size.width || fie->height > fi->size.height)
- ret = -EINVAL;
- else
- fie->interval = fi->interval;
- mutex_unlock(&s5k6aa->lock);
-
- return ret;
-}
-
-static int s5k6aa_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- if (code->index >= ARRAY_SIZE(s5k6aa_formats))
- return -EINVAL;
-
- code->code = s5k6aa_formats[code->index].code;
- return 0;
-}
-
-static int s5k6aa_enum_frame_size(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_frame_size_enum *fse)
-{
- int i = ARRAY_SIZE(s5k6aa_formats);
-
- if (fse->index > 0)
- return -EINVAL;
-
- while (--i)
- if (fse->code == s5k6aa_formats[i].code)
- break;
-
- fse->code = s5k6aa_formats[i].code;
- fse->min_width = S5K6AA_WIN_WIDTH_MIN;
- fse->max_width = S5K6AA_WIN_WIDTH_MAX;
- fse->max_height = S5K6AA_WIN_HEIGHT_MIN;
- fse->min_height = S5K6AA_WIN_HEIGHT_MAX;
-
- return 0;
-}
-
-static struct v4l2_rect *
-__s5k6aa_get_crop_rect(struct s5k6aa *s5k6aa, struct v4l2_subdev_fh *fh,
- enum v4l2_subdev_format_whence which)
-{
- if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
- return &s5k6aa->ccd_rect;
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_crop(fh, 0);
-
- return NULL;
-}
-
-static void s5k6aa_try_format(struct s5k6aa *s5k6aa,
- struct v4l2_mbus_framefmt *mf)
-{
- unsigned int index;
-
- v4l_bound_align_image(&mf->width, S5K6AA_WIN_WIDTH_MIN,
- S5K6AA_WIN_WIDTH_MAX, 1,
- &mf->height, S5K6AA_WIN_HEIGHT_MIN,
- S5K6AA_WIN_HEIGHT_MAX, 1, 0);
-
- if (mf->colorspace != V4L2_COLORSPACE_JPEG &&
- mf->colorspace != V4L2_COLORSPACE_REC709)
- mf->colorspace = V4L2_COLORSPACE_JPEG;
-
- index = s5k6aa_get_pixfmt_index(s5k6aa, mf);
-
- mf->colorspace = s5k6aa_formats[index].colorspace;
- mf->code = s5k6aa_formats[index].code;
- mf->field = V4L2_FIELD_NONE;
-}
-
-static int s5k6aa_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct s5k6aa *s5k6aa = to_s5k6aa(sd);
- struct v4l2_mbus_framefmt *mf;
-
- memset(fmt->reserved, 0, sizeof(fmt->reserved));
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(fh, 0);
- fmt->format = *mf;
- return 0;
- }
-
- mutex_lock(&s5k6aa->lock);
- fmt->format = s5k6aa->preset->mbus_fmt;
- mutex_unlock(&s5k6aa->lock);
-
- return 0;
-}
-
-static int s5k6aa_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct s5k6aa *s5k6aa = to_s5k6aa(sd);
- struct s5k6aa_preset *preset = s5k6aa->preset;
- struct v4l2_mbus_framefmt *mf;
- struct v4l2_rect *crop;
- int ret = 0;
-
- mutex_lock(&s5k6aa->lock);
- s5k6aa_try_format(s5k6aa, &fmt->format);
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(fh, fmt->pad);
- crop = v4l2_subdev_get_try_crop(fh, 0);
- } else {
- if (s5k6aa->streaming) {
- ret = -EBUSY;
- } else {
- mf = &preset->mbus_fmt;
- crop = &s5k6aa->ccd_rect;
- s5k6aa->apply_cfg = 1;
- }
- }
-
- if (ret == 0) {
- struct v4l2_subdev_frame_interval fiv = {
- .interval = {0, 1}
- };
-
- *mf = fmt->format;
- /*
- * Make sure the crop window is valid, i.e. its size is
- * greater than the output window, as the ISP supports
- * only down-scaling.
- */
- crop->width = clamp_t(unsigned int, crop->width, mf->width,
- S5K6AA_WIN_WIDTH_MAX);
- crop->height = clamp_t(unsigned int, crop->height, mf->height,
- S5K6AA_WIN_HEIGHT_MAX);
- crop->left = clamp_t(unsigned int, crop->left, 0,
- S5K6AA_WIN_WIDTH_MAX - crop->width);
- crop->top = clamp_t(unsigned int, crop->top, 0,
- S5K6AA_WIN_HEIGHT_MAX - crop->height);
-
- /* Reset to minimum possible frame interval */
- ret = __s5k6aa_set_frame_interval(s5k6aa, &fiv);
- }
- mutex_unlock(&s5k6aa->lock);
-
- return ret;
-}
-
-static int s5k6aa_get_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_crop *crop)
-{
- struct s5k6aa *s5k6aa = to_s5k6aa(sd);
- struct v4l2_rect *rect;
-
- memset(crop->reserved, 0, sizeof(crop->reserved));
- mutex_lock(&s5k6aa->lock);
-
- rect = __s5k6aa_get_crop_rect(s5k6aa, fh, crop->which);
- if (rect)
- crop->rect = *rect;
-
- mutex_unlock(&s5k6aa->lock);
-
- v4l2_dbg(1, debug, sd, "Current crop rectangle: (%d,%d)/%dx%d\n",
- rect->left, rect->top, rect->width, rect->height);
-
- return 0;
-}
-
-static int s5k6aa_set_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_crop *crop)
-{
- struct s5k6aa *s5k6aa = to_s5k6aa(sd);
- struct v4l2_mbus_framefmt *mf;
- unsigned int max_x, max_y;
- struct v4l2_rect *crop_r;
-
- mutex_lock(&s5k6aa->lock);
- crop_r = __s5k6aa_get_crop_rect(s5k6aa, fh, crop->which);
-
- if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- mf = &s5k6aa->preset->mbus_fmt;
- s5k6aa->apply_crop = 1;
- } else {
- mf = v4l2_subdev_get_try_format(fh, 0);
- }
- v4l_bound_align_image(&crop->rect.width, mf->width,
- S5K6AA_WIN_WIDTH_MAX, 1,
- &crop->rect.height, mf->height,
- S5K6AA_WIN_HEIGHT_MAX, 1, 0);
-
- max_x = (S5K6AA_WIN_WIDTH_MAX - crop->rect.width) & ~1;
- max_y = (S5K6AA_WIN_HEIGHT_MAX - crop->rect.height) & ~1;
-
- crop->rect.left = clamp_t(unsigned int, crop->rect.left, 0, max_x);
- crop->rect.top = clamp_t(unsigned int, crop->rect.top, 0, max_y);
-
- *crop_r = crop->rect;
-
- mutex_unlock(&s5k6aa->lock);
-
- v4l2_dbg(1, debug, sd, "Set crop rectangle: (%d,%d)/%dx%d\n",
- crop_r->left, crop_r->top, crop_r->width, crop_r->height);
-
- return 0;
-}
-
-static const struct v4l2_subdev_pad_ops s5k6aa_pad_ops = {
- .enum_mbus_code = s5k6aa_enum_mbus_code,
- .enum_frame_size = s5k6aa_enum_frame_size,
- .enum_frame_interval = s5k6aa_enum_frame_interval,
- .get_fmt = s5k6aa_get_fmt,
- .set_fmt = s5k6aa_set_fmt,
- .get_crop = s5k6aa_get_crop,
- .set_crop = s5k6aa_set_crop,
-};
-
-static const struct v4l2_subdev_video_ops s5k6aa_video_ops = {
- .g_frame_interval = s5k6aa_g_frame_interval,
- .s_frame_interval = s5k6aa_s_frame_interval,
- .s_stream = s5k6aa_s_stream,
-};
-
-/*
- * V4L2 subdev controls
- */
-
-static int s5k6aa_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct s5k6aa *s5k6aa = to_s5k6aa(sd);
- int idx, err = 0;
-
- v4l2_dbg(1, debug, sd, "ctrl: 0x%x, value: %d\n", ctrl->id, ctrl->val);
-
- mutex_lock(&s5k6aa->lock);
- /*
- * If the device is not powered up by the host driver do
- * not apply any controls to H/W at this time. Instead
- * the controls will be restored right after power-up.
- */
- if (s5k6aa->power == 0)
- goto unlock;
- idx = s5k6aa->preset->index;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTO_WHITE_BALANCE:
- err = s5k6aa_set_awb(s5k6aa, ctrl->val);
- break;
-
- case V4L2_CID_BRIGHTNESS:
- err = s5k6aa_write(client, REG_USER_BRIGHTNESS, ctrl->val);
- break;
-
- case V4L2_CID_COLORFX:
- err = s5k6aa_set_colorfx(s5k6aa, ctrl->val);
- break;
-
- case V4L2_CID_CONTRAST:
- err = s5k6aa_write(client, REG_USER_CONTRAST, ctrl->val);
- break;
-
- case V4L2_CID_EXPOSURE_AUTO:
- err = s5k6aa_set_auto_exposure(s5k6aa, ctrl->val);
- break;
-
- case V4L2_CID_HFLIP:
- err = s5k6aa_set_mirror(s5k6aa, ctrl->val);
- if (err)
- break;
- err = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
- break;
-
- case V4L2_CID_POWER_LINE_FREQUENCY:
- err = s5k6aa_set_anti_flicker(s5k6aa, ctrl->val);
- break;
-
- case V4L2_CID_SATURATION:
- err = s5k6aa_write(client, REG_USER_SATURATION, ctrl->val);
- break;
-
- case V4L2_CID_SHARPNESS:
- err = s5k6aa_write(client, REG_USER_SHARPBLUR, ctrl->val);
- break;
-
- case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
- err = s5k6aa_write(client, REG_P_COLORTEMP(idx), ctrl->val);
- if (err)
- break;
- err = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
- break;
- }
-unlock:
- mutex_unlock(&s5k6aa->lock);
- return err;
-}
-
-static const struct v4l2_ctrl_ops s5k6aa_ctrl_ops = {
- .s_ctrl = s5k6aa_s_ctrl,
-};
-
-static int s5k6aa_log_status(struct v4l2_subdev *sd)
-{
- v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name);
- return 0;
-}
-
-#define V4L2_CID_RED_GAIN (V4L2_CTRL_CLASS_CAMERA | 0x1001)
-#define V4L2_CID_GREEN_GAIN (V4L2_CTRL_CLASS_CAMERA | 0x1002)
-#define V4L2_CID_BLUE_GAIN (V4L2_CTRL_CLASS_CAMERA | 0x1003)
-
-static const struct v4l2_ctrl_config s5k6aa_ctrls[] = {
- {
- .ops = &s5k6aa_ctrl_ops,
- .id = V4L2_CID_RED_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain, Red",
- .min = 0,
- .max = 256,
- .def = 127,
- .step = 1,
- }, {
- .ops = &s5k6aa_ctrl_ops,
- .id = V4L2_CID_GREEN_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain, Green",
- .min = 0,
- .max = 256,
- .def = 127,
- .step = 1,
- }, {
- .ops = &s5k6aa_ctrl_ops,
- .id = V4L2_CID_BLUE_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain, Blue",
- .min = 0,
- .max = 256,
- .def = 127,
- .step = 1,
- },
-};
-
-static int s5k6aa_initialize_ctrls(struct s5k6aa *s5k6aa)
-{
- const struct v4l2_ctrl_ops *ops = &s5k6aa_ctrl_ops;
- struct s5k6aa_ctrls *ctrls = &s5k6aa->ctrls;
- struct v4l2_ctrl_handler *hdl = &ctrls->handler;
-
- int ret = v4l2_ctrl_handler_init(hdl, 16);
- if (ret)
- return ret;
- /* Auto white balance cluster */
- ctrls->awb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE,
- 0, 1, 1, 1);
- ctrls->gain_red = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[0], NULL);
- ctrls->gain_green = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[1], NULL);
- ctrls->gain_blue = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[2], NULL);
- v4l2_ctrl_auto_cluster(4, &ctrls->awb, 0, false);
-
- ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
- ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_cluster(2, &ctrls->hflip);
-
- ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
- V4L2_CID_EXPOSURE_AUTO,
- V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
- /* Exposure time: x 1 us */
- ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
- 0, 6000000U, 1, 100000U);
- /* Total gain: 256 <=> 1x */
- ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
- 0, 256, 1, 256);
- v4l2_ctrl_auto_cluster(3, &ctrls->auto_exp, 0, false);
-
- v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
- V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
-
- v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX,
- V4L2_COLORFX_SKY_BLUE, ~0x6f, V4L2_COLORFX_NONE);
-
- v4l2_ctrl_new_std(hdl, ops, V4L2_CID_WHITE_BALANCE_TEMPERATURE,
- 0, 256, 1, 0);
-
- v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, -127, 127, 1, 0);
- v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -127, 127, 1, 0);
- v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -127, 127, 1, 0);
- v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, -127, 127, 1, 0);
-
- if (hdl->error) {
- ret = hdl->error;
- v4l2_ctrl_handler_free(hdl);
- return ret;
- }
-
- s5k6aa->sd.ctrl_handler = hdl;
- return 0;
-}
-
-/*
- * V4L2 subdev internal operations
- */
-static int s5k6aa_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
- struct v4l2_rect *crop = v4l2_subdev_get_try_crop(fh, 0);
-
- format->colorspace = s5k6aa_formats[0].colorspace;
- format->code = s5k6aa_formats[0].code;
- format->width = S5K6AA_OUT_WIDTH_DEF;
- format->height = S5K6AA_OUT_HEIGHT_DEF;
- format->field = V4L2_FIELD_NONE;
-
- crop->width = S5K6AA_WIN_WIDTH_MAX;
- crop->height = S5K6AA_WIN_HEIGHT_MAX;
- crop->left = 0;
- crop->top = 0;
-
- return 0;
-}
-
-int s5k6aa_check_fw_revision(struct s5k6aa *s5k6aa)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
- u16 api_ver = 0, fw_rev = 0;
-
- int ret = s5k6aa_set_ahb_address(client);
-
- if (!ret)
- ret = s5k6aa_read(client, REG_FW_APIVER, &api_ver);
- if (!ret)
- ret = s5k6aa_read(client, REG_FW_REVISION, &fw_rev);
- if (ret) {
- v4l2_err(&s5k6aa->sd, "FW revision check failed!\n");
- return ret;
- }
-
- v4l2_info(&s5k6aa->sd, "FW API ver.: 0x%X, FW rev.: 0x%X\n",
- api_ver, fw_rev);
-
- return api_ver == S5K6AAFX_FW_APIVER ? 0 : -ENODEV;
-}
-
-static int s5k6aa_registered(struct v4l2_subdev *sd)
-{
- struct s5k6aa *s5k6aa = to_s5k6aa(sd);
- int ret;
-
- mutex_lock(&s5k6aa->lock);
- ret = __s5k6aa_power_on(s5k6aa);
- if (!ret) {
- msleep(100);
- ret = s5k6aa_check_fw_revision(s5k6aa);
- __s5k6aa_power_off(s5k6aa);
- }
- mutex_unlock(&s5k6aa->lock);
-
- return ret;
-}
-
-static const struct v4l2_subdev_internal_ops s5k6aa_subdev_internal_ops = {
- .registered = s5k6aa_registered,
- .open = s5k6aa_open,
-};
-
-static const struct v4l2_subdev_core_ops s5k6aa_core_ops = {
- .s_power = s5k6aa_set_power,
- .log_status = s5k6aa_log_status,
-};
-
-static const struct v4l2_subdev_ops s5k6aa_subdev_ops = {
- .core = &s5k6aa_core_ops,
- .pad = &s5k6aa_pad_ops,
- .video = &s5k6aa_video_ops,
-};
-
-/*
- * GPIO setup
- */
-static int s5k6aa_configure_gpio(int nr, int val, const char *name)
-{
- unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
- int ret;
-
- if (!gpio_is_valid(nr))
- return 0;
- ret = gpio_request_one(nr, flags, name);
- if (!ret)
- gpio_export(nr, 0);
- return ret;
-}
-
-static void s5k6aa_free_gpios(struct s5k6aa *s5k6aa)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(s5k6aa->gpio); i++) {
- if (!gpio_is_valid(s5k6aa->gpio[i].gpio))
- continue;
- gpio_free(s5k6aa->gpio[i].gpio);
- s5k6aa->gpio[i].gpio = -EINVAL;
- }
-}
-
-static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa,
- const struct s5k6aa_platform_data *pdata)
-{
- const struct s5k6aa_gpio *gpio = &pdata->gpio_stby;
- int ret;
-
- s5k6aa->gpio[STBY].gpio = -EINVAL;
- s5k6aa->gpio[RST].gpio = -EINVAL;
-
- ret = s5k6aa_configure_gpio(gpio->gpio, gpio->level, "S5K6AA_STBY");
- if (ret) {
- s5k6aa_free_gpios(s5k6aa);
- return ret;
- }
- s5k6aa->gpio[STBY] = *gpio;
- if (gpio_is_valid(gpio->gpio))
- gpio_set_value(gpio->gpio, 0);
-
- gpio = &pdata->gpio_reset;
- ret = s5k6aa_configure_gpio(gpio->gpio, gpio->level, "S5K6AA_RST");
- if (ret) {
- s5k6aa_free_gpios(s5k6aa);
- return ret;
- }
- s5k6aa->gpio[RST] = *gpio;
- if (gpio_is_valid(gpio->gpio))
- gpio_set_value(gpio->gpio, 0);
-
- return 0;
-}
-
-static int s5k6aa_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- const struct s5k6aa_platform_data *pdata = client->dev.platform_data;
- struct v4l2_subdev *sd;
- struct s5k6aa *s5k6aa;
- int i, ret;
-
- if (pdata == NULL) {
- dev_err(&client->dev, "Platform data not specified\n");
- return -EINVAL;
- }
-
- if (pdata->mclk_frequency == 0) {
- dev_err(&client->dev, "MCLK frequency not specified\n");
- return -EINVAL;
- }
-
- s5k6aa = kzalloc(sizeof(*s5k6aa), GFP_KERNEL);
- if (!s5k6aa)
- return -ENOMEM;
-
- mutex_init(&s5k6aa->lock);
-
- s5k6aa->mclk_frequency = pdata->mclk_frequency;
- s5k6aa->bus_type = pdata->bus_type;
- s5k6aa->mipi_lanes = pdata->nlanes;
- s5k6aa->s_power = pdata->set_power;
- s5k6aa->inv_hflip = pdata->horiz_flip;
- s5k6aa->inv_vflip = pdata->vert_flip;
-
- sd = &s5k6aa->sd;
- v4l2_i2c_subdev_init(sd, client, &s5k6aa_subdev_ops);
- strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name));
-
- sd->internal_ops = &s5k6aa_subdev_internal_ops;
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad, 0);
- if (ret)
- goto out_err1;
-
- ret = s5k6aa_configure_gpios(s5k6aa, pdata);
- if (ret)
- goto out_err2;
-
- for (i = 0; i < S5K6AA_NUM_SUPPLIES; i++)
- s5k6aa->supplies[i].supply = s5k6aa_supply_names[i];
-
- ret = regulator_bulk_get(&client->dev, S5K6AA_NUM_SUPPLIES,
- s5k6aa->supplies);
- if (ret) {
- dev_err(&client->dev, "Failed to get regulators\n");
- goto out_err3;
- }
-
- ret = s5k6aa_initialize_ctrls(s5k6aa);
- if (ret)
- goto out_err4;
-
- s5k6aa_presets_data_init(s5k6aa);
-
- s5k6aa->ccd_rect.width = S5K6AA_WIN_WIDTH_MAX;
- s5k6aa->ccd_rect.height = S5K6AA_WIN_HEIGHT_MAX;
- s5k6aa->ccd_rect.left = 0;
- s5k6aa->ccd_rect.top = 0;
-
- return 0;
-
-out_err4:
- regulator_bulk_free(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
-out_err3:
- s5k6aa_free_gpios(s5k6aa);
-out_err2:
- media_entity_cleanup(&s5k6aa->sd.entity);
-out_err1:
- kfree(s5k6aa);
- return ret;
-}
-
-static int s5k6aa_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct s5k6aa *s5k6aa = to_s5k6aa(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(sd->ctrl_handler);
- media_entity_cleanup(&sd->entity);
- regulator_bulk_free(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
- s5k6aa_free_gpios(s5k6aa);
- kfree(s5k6aa);
-
- return 0;
-}
-
-static const struct i2c_device_id s5k6aa_id[] = {
- { DRIVER_NAME, 0 },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, s5k6aa_id);
-
-
-static struct i2c_driver s5k6aa_i2c_driver = {
- .driver = {
- .name = DRIVER_NAME
- },
- .probe = s5k6aa_probe,
- .remove = s5k6aa_remove,
- .id_table = s5k6aa_id,
-};
-
-module_i2c_driver(s5k6aa_i2c_driver);
-
-MODULE_DESCRIPTION("Samsung S5K6AA(FX) SXGA camera driver");
-MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/s5p-fimc/Kconfig b/drivers/media/video/s5p-fimc/Kconfig
deleted file mode 100644
index a564f7eeb06..00000000000
--- a/drivers/media/video/s5p-fimc/Kconfig
+++ /dev/null
@@ -1,48 +0,0 @@
-
-config VIDEO_SAMSUNG_S5P_FIMC
- bool "Samsung S5P/EXYNOS SoC camera interface driver (experimental)"
- depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && PLAT_S5P && PM_RUNTIME
- depends on EXPERIMENTAL
- help
- Say Y here to enable camera host interface devices for
- Samsung S5P and EXYNOS SoC series.
-
-if VIDEO_SAMSUNG_S5P_FIMC
-
-config VIDEO_S5P_FIMC
- tristate "S5P/EXYNOS4 FIMC/CAMIF camera interface driver"
- depends on I2C
- select VIDEOBUF2_DMA_CONTIG
- select V4L2_MEM2MEM_DEV
- help
- This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC camera host
- interface and video postprocessor (FIMC and FIMC-LITE) devices.
-
- To compile this driver as a module, choose M here: the
- module will be called s5p-fimc.
-
-config VIDEO_S5P_MIPI_CSIS
- tristate "S5P/EXYNOS MIPI-CSI2 receiver (MIPI-CSIS) driver"
- depends on REGULATOR
- help
- This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2
- receiver (MIPI-CSIS) devices.
-
- To compile this driver as a module, choose M here: the
- module will be called s5p-csis.
-
-if ARCH_EXYNOS
-
-config VIDEO_EXYNOS_FIMC_LITE
- tristate "EXYNOS FIMC-LITE camera interface driver"
- depends on I2C
- select VIDEOBUF2_DMA_CONTIG
- help
- This is a V4L2 driver for Samsung EXYNOS4/5 SoC FIMC-LITE camera
- host interface.
-
- To compile this driver as a module, choose M here: the
- module will be called exynos-fimc-lite.
-endif
-
-endif # VIDEO_SAMSUNG_S5P_FIMC
diff --git a/drivers/media/video/s5p-fimc/Makefile b/drivers/media/video/s5p-fimc/Makefile
deleted file mode 100644
index 46485143e1c..00000000000
--- a/drivers/media/video/s5p-fimc/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-m2m.o fimc-capture.o fimc-mdevice.o
-exynos-fimc-lite-objs += fimc-lite-reg.o fimc-lite.o
-s5p-csis-objs := mipi-csis.o
-
-obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS) += s5p-csis.o
-obj-$(CONFIG_VIDEO_EXYNOS_FIMC_LITE) += exynos-fimc-lite.o
-obj-$(CONFIG_VIDEO_S5P_FIMC) += s5p-fimc.o
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
deleted file mode 100644
index 8e413dd3c0b..00000000000
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ /dev/null
@@ -1,1738 +0,0 @@
-/*
- * Samsung S5P/EXYNOS4 SoC series camera interface (camera capture) driver
- *
- * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/bug.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/pm_runtime.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "fimc-mdevice.h"
-#include "fimc-core.h"
-#include "fimc-reg.h"
-
-static int fimc_capture_hw_init(struct fimc_dev *fimc)
-{
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct fimc_pipeline *p = &fimc->pipeline;
- struct fimc_sensor_info *sensor;
- unsigned long flags;
- int ret = 0;
-
- if (p->subdevs[IDX_SENSOR] == NULL || ctx == NULL)
- return -ENXIO;
- if (ctx->s_frame.fmt == NULL)
- return -EINVAL;
-
- sensor = v4l2_get_subdev_hostdata(p->subdevs[IDX_SENSOR]);
-
- spin_lock_irqsave(&fimc->slock, flags);
- fimc_prepare_dma_offset(ctx, &ctx->d_frame);
- fimc_set_yuv_order(ctx);
-
- fimc_hw_set_camera_polarity(fimc, sensor->pdata);
- fimc_hw_set_camera_type(fimc, sensor->pdata);
- fimc_hw_set_camera_source(fimc, sensor->pdata);
- fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
-
- ret = fimc_set_scaler_info(ctx);
- if (!ret) {
- fimc_hw_set_input_path(ctx);
- fimc_hw_set_prescaler(ctx);
- fimc_hw_set_mainscaler(ctx);
- fimc_hw_set_target_format(ctx);
- fimc_hw_set_rotation(ctx);
- fimc_hw_set_effect(ctx);
- fimc_hw_set_output_path(ctx);
- fimc_hw_set_out_dma(ctx);
- if (fimc->variant->has_alpha)
- fimc_hw_set_rgb_alpha(ctx);
- clear_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- }
- spin_unlock_irqrestore(&fimc->slock, flags);
- return ret;
-}
-
-/*
- * Reinitialize the driver so it is ready to start the streaming again.
- * Set fimc->state to indicate stream off and the hardware shut down state.
- * If not suspending (@suspend is false), return any buffers to videobuf2.
- * Otherwise put any owned buffers onto the pending buffers queue, so they
- * can be re-spun when the device is being resumed. Also perform FIMC
- * software reset and disable streaming on the whole pipeline if required.
- */
-static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
-{
- struct fimc_vid_cap *cap = &fimc->vid_cap;
- struct fimc_vid_buffer *buf;
- unsigned long flags;
- bool streaming;
-
- spin_lock_irqsave(&fimc->slock, flags);
- streaming = fimc->state & (1 << ST_CAPT_ISP_STREAM);
-
- fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_SHUT |
- 1 << ST_CAPT_STREAM | 1 << ST_CAPT_ISP_STREAM);
- if (suspend)
- fimc->state |= (1 << ST_CAPT_SUSPENDED);
- else
- fimc->state &= ~(1 << ST_CAPT_PEND | 1 << ST_CAPT_SUSPENDED);
-
- /* Release unused buffers */
- while (!suspend && !list_empty(&cap->pending_buf_q)) {
- buf = fimc_pending_queue_pop(cap);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- }
- /* If suspending put unused buffers onto pending queue */
- while (!list_empty(&cap->active_buf_q)) {
- buf = fimc_active_queue_pop(cap);
- if (suspend)
- fimc_pending_queue_add(cap, buf);
- else
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- }
-
- fimc_hw_reset(fimc);
- cap->buf_index = 0;
-
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (streaming)
- return fimc_pipeline_s_stream(&fimc->pipeline, 0);
- else
- return 0;
-}
-
-static int fimc_stop_capture(struct fimc_dev *fimc, bool suspend)
-{
- unsigned long flags;
-
- if (!fimc_capture_active(fimc))
- return 0;
-
- spin_lock_irqsave(&fimc->slock, flags);
- set_bit(ST_CAPT_SHUT, &fimc->state);
- fimc_deactivate_capture(fimc);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- wait_event_timeout(fimc->irq_queue,
- !test_bit(ST_CAPT_SHUT, &fimc->state),
- (2*HZ/10)); /* 200 ms */
-
- return fimc_capture_state_cleanup(fimc, suspend);
-}
-
-/**
- * fimc_capture_config_update - apply the camera interface configuration
- *
- * To be called from within the interrupt handler with fimc.slock
- * spinlock held. It updates the camera pixel crop, rotation and
- * image flip in H/W.
- */
-static int fimc_capture_config_update(struct fimc_ctx *ctx)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- int ret;
-
- fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
-
- ret = fimc_set_scaler_info(ctx);
- if (ret)
- return ret;
-
- fimc_hw_set_prescaler(ctx);
- fimc_hw_set_mainscaler(ctx);
- fimc_hw_set_target_format(ctx);
- fimc_hw_set_rotation(ctx);
- fimc_hw_set_effect(ctx);
- fimc_prepare_dma_offset(ctx, &ctx->d_frame);
- fimc_hw_set_out_dma(ctx);
- if (fimc->variant->has_alpha)
- fimc_hw_set_rgb_alpha(ctx);
-
- clear_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- return ret;
-}
-
-void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
-{
- struct fimc_vid_cap *cap = &fimc->vid_cap;
- struct fimc_vid_buffer *v_buf;
- struct timeval *tv;
- struct timespec ts;
-
- if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) {
- wake_up(&fimc->irq_queue);
- goto done;
- }
-
- if (!list_empty(&cap->active_buf_q) &&
- test_bit(ST_CAPT_RUN, &fimc->state) && deq_buf) {
- ktime_get_real_ts(&ts);
-
- v_buf = fimc_active_queue_pop(cap);
-
- tv = &v_buf->vb.v4l2_buf.timestamp;
- tv->tv_sec = ts.tv_sec;
- tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
- v_buf->vb.v4l2_buf.sequence = cap->frame_count++;
-
- vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE);
- }
-
- if (!list_empty(&cap->pending_buf_q)) {
-
- v_buf = fimc_pending_queue_pop(cap);
- fimc_hw_set_output_addr(fimc, &v_buf->paddr, cap->buf_index);
- v_buf->index = cap->buf_index;
-
- /* Move the buffer to the capture active queue */
- fimc_active_queue_add(cap, v_buf);
-
- dbg("next frame: %d, done frame: %d",
- fimc_hw_get_frame_index(fimc), v_buf->index);
-
- if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
- cap->buf_index = 0;
- }
-
- if (cap->active_buf_cnt == 0) {
- if (deq_buf)
- clear_bit(ST_CAPT_RUN, &fimc->state);
-
- if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
- cap->buf_index = 0;
- } else {
- set_bit(ST_CAPT_RUN, &fimc->state);
- }
-
- if (test_bit(ST_CAPT_APPLY_CFG, &fimc->state))
- fimc_capture_config_update(cap->ctx);
-done:
- if (cap->active_buf_cnt == 1) {
- fimc_deactivate_capture(fimc);
- clear_bit(ST_CAPT_STREAM, &fimc->state);
- }
-
- dbg("frame: %d, active_buf_cnt: %d",
- fimc_hw_get_frame_index(fimc), cap->active_buf_cnt);
-}
-
-
-static int start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct fimc_ctx *ctx = q->drv_priv;
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- int min_bufs;
- int ret;
-
- vid_cap->frame_count = 0;
-
- ret = fimc_capture_hw_init(fimc);
- if (ret) {
- fimc_capture_state_cleanup(fimc, false);
- return ret;
- }
-
- set_bit(ST_CAPT_PEND, &fimc->state);
-
- min_bufs = fimc->vid_cap.reqbufs_count > 1 ? 2 : 1;
-
- if (vid_cap->active_buf_cnt >= min_bufs &&
- !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) {
- fimc_activate_capture(ctx);
-
- if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
- fimc_pipeline_s_stream(&fimc->pipeline, 1);
- }
-
- return 0;
-}
-
-static int stop_streaming(struct vb2_queue *q)
-{
- struct fimc_ctx *ctx = q->drv_priv;
- struct fimc_dev *fimc = ctx->fimc_dev;
-
- if (!fimc_capture_active(fimc))
- return -EINVAL;
-
- return fimc_stop_capture(fimc, false);
-}
-
-int fimc_capture_suspend(struct fimc_dev *fimc)
-{
- bool suspend = fimc_capture_busy(fimc);
-
- int ret = fimc_stop_capture(fimc, suspend);
- if (ret)
- return ret;
- return fimc_pipeline_shutdown(&fimc->pipeline);
-}
-
-static void buffer_queue(struct vb2_buffer *vb);
-
-int fimc_capture_resume(struct fimc_dev *fimc)
-{
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- struct fimc_vid_buffer *buf;
- int i;
-
- if (!test_and_clear_bit(ST_CAPT_SUSPENDED, &fimc->state))
- return 0;
-
- INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
- vid_cap->buf_index = 0;
- fimc_pipeline_initialize(&fimc->pipeline, &vid_cap->vfd->entity,
- false);
- fimc_capture_hw_init(fimc);
-
- clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
-
- for (i = 0; i < vid_cap->reqbufs_count; i++) {
- if (list_empty(&vid_cap->pending_buf_q))
- break;
- buf = fimc_pending_queue_pop(vid_cap);
- buffer_queue(&buf->vb);
- }
- return 0;
-
-}
-
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
- unsigned int *num_buffers, unsigned int *num_planes,
- unsigned int sizes[], void *allocators[])
-{
- const struct v4l2_pix_format_mplane *pixm = NULL;
- struct fimc_ctx *ctx = vq->drv_priv;
- struct fimc_frame *frame = &ctx->d_frame;
- struct fimc_fmt *fmt = frame->fmt;
- unsigned long wh;
- int i;
-
- if (pfmt) {
- pixm = &pfmt->fmt.pix_mp;
- fmt = fimc_find_format(&pixm->pixelformat, NULL,
- FMT_FLAGS_CAM | FMT_FLAGS_M2M, -1);
- wh = pixm->width * pixm->height;
- } else {
- wh = frame->f_width * frame->f_height;
- }
-
- if (fmt == NULL)
- return -EINVAL;
-
- *num_planes = fmt->memplanes;
-
- for (i = 0; i < fmt->memplanes; i++) {
- unsigned int size = (wh * fmt->depth[i]) / 8;
- if (pixm)
- sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
- else
- sizes[i] = max_t(u32, size, frame->payload[i]);
-
- allocators[i] = ctx->fimc_dev->alloc_ctx;
- }
-
- return 0;
-}
-
-static int buffer_prepare(struct vb2_buffer *vb)
-{
- struct vb2_queue *vq = vb->vb2_queue;
- struct fimc_ctx *ctx = vq->drv_priv;
- int i;
-
- if (ctx->d_frame.fmt == NULL)
- return -EINVAL;
-
- for (i = 0; i < ctx->d_frame.fmt->memplanes; i++) {
- unsigned long size = ctx->d_frame.payload[i];
-
- if (vb2_plane_size(vb, i) < size) {
- v4l2_err(ctx->fimc_dev->vid_cap.vfd,
- "User buffer too small (%ld < %ld)\n",
- vb2_plane_size(vb, i), size);
- return -EINVAL;
- }
- vb2_set_plane_payload(vb, i, size);
- }
-
- return 0;
-}
-
-static void buffer_queue(struct vb2_buffer *vb)
-{
- struct fimc_vid_buffer *buf
- = container_of(vb, struct fimc_vid_buffer, vb);
- struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- unsigned long flags;
- int min_bufs;
-
- spin_lock_irqsave(&fimc->slock, flags);
- fimc_prepare_addr(ctx, &buf->vb, &ctx->d_frame, &buf->paddr);
-
- if (!test_bit(ST_CAPT_SUSPENDED, &fimc->state) &&
- !test_bit(ST_CAPT_STREAM, &fimc->state) &&
- vid_cap->active_buf_cnt < FIMC_MAX_OUT_BUFS) {
- /* Setup the buffer directly for processing. */
- int buf_id = (vid_cap->reqbufs_count == 1) ? -1 :
- vid_cap->buf_index;
-
- fimc_hw_set_output_addr(fimc, &buf->paddr, buf_id);
- buf->index = vid_cap->buf_index;
- fimc_active_queue_add(vid_cap, buf);
-
- if (++vid_cap->buf_index >= FIMC_MAX_OUT_BUFS)
- vid_cap->buf_index = 0;
- } else {
- fimc_pending_queue_add(vid_cap, buf);
- }
-
- min_bufs = vid_cap->reqbufs_count > 1 ? 2 : 1;
-
-
- if (vb2_is_streaming(&vid_cap->vbq) &&
- vid_cap->active_buf_cnt >= min_bufs &&
- !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) {
- fimc_activate_capture(ctx);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
- fimc_pipeline_s_stream(&fimc->pipeline, 1);
- return;
- }
- spin_unlock_irqrestore(&fimc->slock, flags);
-}
-
-static void fimc_lock(struct vb2_queue *vq)
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
- mutex_lock(&ctx->fimc_dev->lock);
-}
-
-static void fimc_unlock(struct vb2_queue *vq)
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
- mutex_unlock(&ctx->fimc_dev->lock);
-}
-
-static struct vb2_ops fimc_capture_qops = {
- .queue_setup = queue_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .wait_prepare = fimc_unlock,
- .wait_finish = fimc_lock,
- .start_streaming = start_streaming,
- .stop_streaming = stop_streaming,
-};
-
-/**
- * fimc_capture_ctrls_create - initialize the control handler
- * Initialize the capture video node control handler and fill it
- * with the FIMC controls. Inherit any sensor's controls if the
- * 'user_subdev_api' flag is false (default behaviour).
- * This function need to be called with the graph mutex held.
- */
-int fimc_capture_ctrls_create(struct fimc_dev *fimc)
-{
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- int ret;
-
- if (WARN_ON(vid_cap->ctx == NULL))
- return -ENXIO;
- if (vid_cap->ctx->ctrls.ready)
- return 0;
-
- ret = fimc_ctrls_create(vid_cap->ctx);
- if (ret || vid_cap->user_subdev_api || !vid_cap->ctx->ctrls.ready)
- return ret;
-
- return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrls.handler,
- fimc->pipeline.subdevs[IDX_SENSOR]->ctrl_handler);
-}
-
-static int fimc_capture_set_default_format(struct fimc_dev *fimc);
-
-static int fimc_capture_open(struct file *file)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- int ret = -EBUSY;
-
- dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
-
- if (mutex_lock_interruptible(&fimc->lock))
- return -ERESTARTSYS;
-
- if (fimc_m2m_active(fimc))
- goto unlock;
-
- set_bit(ST_CAPT_BUSY, &fimc->state);
- ret = pm_runtime_get_sync(&fimc->pdev->dev);
- if (ret < 0)
- goto unlock;
-
- ret = v4l2_fh_open(file);
- if (ret) {
- pm_runtime_put(&fimc->pdev->dev);
- goto unlock;
- }
-
- if (++fimc->vid_cap.refcnt == 1) {
- ret = fimc_pipeline_initialize(&fimc->pipeline,
- &fimc->vid_cap.vfd->entity, true);
-
- if (!ret && !fimc->vid_cap.user_subdev_api)
- ret = fimc_capture_set_default_format(fimc);
-
- if (!ret)
- ret = fimc_capture_ctrls_create(fimc);
-
- if (ret < 0) {
- clear_bit(ST_CAPT_BUSY, &fimc->state);
- pm_runtime_put_sync(&fimc->pdev->dev);
- fimc->vid_cap.refcnt--;
- v4l2_fh_release(file);
- }
- }
-unlock:
- mutex_unlock(&fimc->lock);
- return ret;
-}
-
-static int fimc_capture_close(struct file *file)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- int ret;
-
- dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
-
- if (mutex_lock_interruptible(&fimc->lock))
- return -ERESTARTSYS;
-
- if (--fimc->vid_cap.refcnt == 0) {
- clear_bit(ST_CAPT_BUSY, &fimc->state);
- fimc_stop_capture(fimc, false);
- fimc_pipeline_shutdown(&fimc->pipeline);
- clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
- }
-
- pm_runtime_put(&fimc->pdev->dev);
-
- if (fimc->vid_cap.refcnt == 0) {
- vb2_queue_release(&fimc->vid_cap.vbq);
- fimc_ctrls_delete(fimc->vid_cap.ctx);
- }
-
- ret = v4l2_fh_release(file);
-
- mutex_unlock(&fimc->lock);
- return ret;
-}
-
-static unsigned int fimc_capture_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- int ret;
-
- if (mutex_lock_interruptible(&fimc->lock))
- return POLL_ERR;
-
- ret = vb2_poll(&fimc->vid_cap.vbq, file, wait);
- mutex_unlock(&fimc->lock);
-
- return ret;
-}
-
-static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- int ret;
-
- if (mutex_lock_interruptible(&fimc->lock))
- return -ERESTARTSYS;
-
- ret = vb2_mmap(&fimc->vid_cap.vbq, vma);
- mutex_unlock(&fimc->lock);
-
- return ret;
-}
-
-static const struct v4l2_file_operations fimc_capture_fops = {
- .owner = THIS_MODULE,
- .open = fimc_capture_open,
- .release = fimc_capture_close,
- .poll = fimc_capture_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = fimc_capture_mmap,
-};
-
-/*
- * Format and crop negotiation helpers
- */
-
-static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx,
- u32 *width, u32 *height,
- u32 *code, u32 *fourcc, int pad)
-{
- bool rotation = ctx->rotation == 90 || ctx->rotation == 270;
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_variant *var = fimc->variant;
- struct fimc_pix_limit *pl = var->pix_limit;
- struct fimc_frame *dst = &ctx->d_frame;
- u32 depth, min_w, max_w, min_h, align_h = 3;
- u32 mask = FMT_FLAGS_CAM;
- struct fimc_fmt *ffmt;
-
- /* Color conversion from/to JPEG is not supported */
- if (code && ctx->s_frame.fmt && pad == FIMC_SD_PAD_SOURCE &&
- fimc_fmt_is_jpeg(ctx->s_frame.fmt->color))
- *code = V4L2_MBUS_FMT_JPEG_1X8;
-
- if (fourcc && *fourcc != V4L2_PIX_FMT_JPEG && pad != FIMC_SD_PAD_SINK)
- mask |= FMT_FLAGS_M2M;
-
- ffmt = fimc_find_format(fourcc, code, mask, 0);
- if (WARN_ON(!ffmt))
- return NULL;
- if (code)
- *code = ffmt->mbus_code;
- if (fourcc)
- *fourcc = ffmt->fourcc;
-
- if (pad == FIMC_SD_PAD_SINK) {
- max_w = fimc_fmt_is_jpeg(ffmt->color) ?
- pl->scaler_dis_w : pl->scaler_en_w;
- /* Apply the camera input interface pixel constraints */
- v4l_bound_align_image(width, max_t(u32, *width, 32), max_w, 4,
- height, max_t(u32, *height, 32),
- FIMC_CAMIF_MAX_HEIGHT,
- fimc_fmt_is_jpeg(ffmt->color) ? 3 : 1,
- 0);
- return ffmt;
- }
- /* Can't scale or crop in transparent (JPEG) transfer mode */
- if (fimc_fmt_is_jpeg(ffmt->color)) {
- *width = ctx->s_frame.f_width;
- *height = ctx->s_frame.f_height;
- return ffmt;
- }
- /* Apply the scaler and the output DMA constraints */
- max_w = rotation ? pl->out_rot_en_w : pl->out_rot_dis_w;
- if (ctx->state & FIMC_COMPOSE) {
- min_w = dst->offs_h + dst->width;
- min_h = dst->offs_v + dst->height;
- } else {
- min_w = var->min_out_pixsize;
- min_h = var->min_out_pixsize;
- }
- if (var->min_vsize_align == 1 && !rotation)
- align_h = fimc_fmt_is_rgb(ffmt->color) ? 0 : 1;
-
- depth = fimc_get_format_depth(ffmt);
- v4l_bound_align_image(width, min_w, max_w,
- ffs(var->min_out_pixsize) - 1,
- height, min_h, FIMC_CAMIF_MAX_HEIGHT,
- align_h,
- 64/(ALIGN(depth, 8)));
-
- dbg("pad%d: code: 0x%x, %dx%d. dst fmt: %dx%d",
- pad, code ? *code : 0, *width, *height,
- dst->f_width, dst->f_height);
-
- return ffmt;
-}
-
-static void fimc_capture_try_selection(struct fimc_ctx *ctx,
- struct v4l2_rect *r,
- int target)
-{
- bool rotate = ctx->rotation == 90 || ctx->rotation == 270;
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_variant *var = fimc->variant;
- struct fimc_pix_limit *pl = var->pix_limit;
- struct fimc_frame *sink = &ctx->s_frame;
- u32 max_w, max_h, min_w = 0, min_h = 0, min_sz;
- u32 align_sz = 0, align_h = 4;
- u32 max_sc_h, max_sc_v;
-
- /* In JPEG transparent transfer mode cropping is not supported */
- if (fimc_fmt_is_jpeg(ctx->d_frame.fmt->color)) {
- r->width = sink->f_width;
- r->height = sink->f_height;
- r->left = r->top = 0;
- return;
- }
- if (target == V4L2_SEL_TGT_COMPOSE) {
- if (ctx->rotation != 90 && ctx->rotation != 270)
- align_h = 1;
- max_sc_h = min(SCALER_MAX_HRATIO, 1 << (ffs(sink->width) - 3));
- max_sc_v = min(SCALER_MAX_VRATIO, 1 << (ffs(sink->height) - 1));
- min_sz = var->min_out_pixsize;
- } else {
- u32 depth = fimc_get_format_depth(sink->fmt);
- align_sz = 64/ALIGN(depth, 8);
- min_sz = var->min_inp_pixsize;
- min_w = min_h = min_sz;
- max_sc_h = max_sc_v = 1;
- }
- /*
- * For the compose rectangle the following constraints must be met:
- * - it must fit in the sink pad format rectangle (f_width/f_height);
- * - maximum downscaling ratio is 64;
- * - maximum crop size depends if the rotator is used or not;
- * - the sink pad format width/height must be 4 multiple of the
- * prescaler ratios determined by sink pad size and source pad crop,
- * the prescaler ratio is returned by fimc_get_scaler_factor().
- */
- max_w = min_t(u32,
- rotate ? pl->out_rot_en_w : pl->out_rot_dis_w,
- rotate ? sink->f_height : sink->f_width);
- max_h = min_t(u32, FIMC_CAMIF_MAX_HEIGHT, sink->f_height);
-
- if (target == V4L2_SEL_TGT_COMPOSE) {
- min_w = min_t(u32, max_w, sink->f_width / max_sc_h);
- min_h = min_t(u32, max_h, sink->f_height / max_sc_v);
- if (rotate) {
- swap(max_sc_h, max_sc_v);
- swap(min_w, min_h);
- }
- }
- v4l_bound_align_image(&r->width, min_w, max_w, ffs(min_sz) - 1,
- &r->height, min_h, max_h, align_h,
- align_sz);
- /* Adjust left/top if crop/compose rectangle is out of bounds */
- r->left = clamp_t(u32, r->left, 0, sink->f_width - r->width);
- r->top = clamp_t(u32, r->top, 0, sink->f_height - r->height);
- r->left = round_down(r->left, var->hor_offs_align);
-
- dbg("target %#x: (%d,%d)/%dx%d, sink fmt: %dx%d",
- target, r->left, r->top, r->width, r->height,
- sink->f_width, sink->f_height);
-}
-
-/*
- * The video node ioctl operations
- */
-static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1);
- strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1);
- cap->bus_info[0] = 0;
- cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE_MPLANE;
-
- return 0;
-}
-
-static int fimc_cap_enum_fmt_mplane(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct fimc_fmt *fmt;
-
- fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM | FMT_FLAGS_M2M,
- f->index);
- if (!fmt)
- return -EINVAL;
- strncpy(f->description, fmt->name, sizeof(f->description) - 1);
- f->pixelformat = fmt->fourcc;
- if (fmt->fourcc == V4L2_MBUS_FMT_JPEG_1X8)
- f->flags |= V4L2_FMT_FLAG_COMPRESSED;
- return 0;
-}
-
-/**
- * fimc_pipeline_try_format - negotiate and/or set formats at pipeline
- * elements
- * @ctx: FIMC capture context
- * @tfmt: media bus format to try/set on subdevs
- * @fmt_id: fimc pixel format id corresponding to returned @tfmt (output)
- * @set: true to set format on subdevs, false to try only
- */
-static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
- struct v4l2_mbus_framefmt *tfmt,
- struct fimc_fmt **fmt_id,
- bool set)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
- struct v4l2_subdev *csis = fimc->pipeline.subdevs[IDX_CSIS];
- struct v4l2_subdev_format sfmt;
- struct v4l2_mbus_framefmt *mf = &sfmt.format;
- struct fimc_fmt *ffmt = NULL;
- int ret, i = 0;
-
- if (WARN_ON(!sd || !tfmt))
- return -EINVAL;
-
- memset(&sfmt, 0, sizeof(sfmt));
- sfmt.format = *tfmt;
-
- sfmt.which = set ? V4L2_SUBDEV_FORMAT_ACTIVE : V4L2_SUBDEV_FORMAT_TRY;
- while (1) {
- ffmt = fimc_find_format(NULL, mf->code != 0 ? &mf->code : NULL,
- FMT_FLAGS_CAM, i++);
- if (ffmt == NULL) {
- /*
- * Notify user-space if common pixel code for
- * host and sensor does not exist.
- */
- return -EINVAL;
- }
- mf->code = tfmt->code = ffmt->mbus_code;
-
- ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &sfmt);
- if (ret)
- return ret;
- if (mf->code != tfmt->code) {
- mf->code = 0;
- continue;
- }
- if (mf->width != tfmt->width || mf->height != tfmt->height) {
- u32 fcc = ffmt->fourcc;
- tfmt->width = mf->width;
- tfmt->height = mf->height;
- ffmt = fimc_capture_try_format(ctx,
- &tfmt->width, &tfmt->height,
- NULL, &fcc, FIMC_SD_PAD_SOURCE);
- if (ffmt && ffmt->mbus_code)
- mf->code = ffmt->mbus_code;
- if (mf->width != tfmt->width ||
- mf->height != tfmt->height)
- continue;
- tfmt->code = mf->code;
- }
- if (csis)
- ret = v4l2_subdev_call(csis, pad, set_fmt, NULL, &sfmt);
-
- if (mf->code == tfmt->code &&
- mf->width == tfmt->width && mf->height == tfmt->height)
- break;
- }
-
- if (fmt_id && ffmt)
- *fmt_id = ffmt;
- *tfmt = *mf;
-
- dbg("code: 0x%x, %dx%d, %p", mf->code, mf->width, mf->height, ffmt);
- return 0;
-}
-
-static int fimc_cap_g_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
-
- return fimc_fill_format(&ctx->d_frame, f);
-}
-
-static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct v4l2_mbus_framefmt mf;
- struct fimc_fmt *ffmt = NULL;
-
- if (pix->pixelformat == V4L2_PIX_FMT_JPEG) {
- fimc_capture_try_format(ctx, &pix->width, &pix->height,
- NULL, &pix->pixelformat,
- FIMC_SD_PAD_SINK);
- ctx->s_frame.f_width = pix->width;
- ctx->s_frame.f_height = pix->height;
- }
- ffmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
- NULL, &pix->pixelformat,
- FIMC_SD_PAD_SOURCE);
- if (!ffmt)
- return -EINVAL;
-
- if (!fimc->vid_cap.user_subdev_api) {
- mf.width = pix->width;
- mf.height = pix->height;
- mf.code = ffmt->mbus_code;
- fimc_md_graph_lock(fimc);
- fimc_pipeline_try_format(ctx, &mf, &ffmt, false);
- fimc_md_graph_unlock(fimc);
-
- pix->width = mf.width;
- pix->height = mf.height;
- if (ffmt)
- pix->pixelformat = ffmt->fourcc;
- }
-
- fimc_adjust_mplane_format(ffmt, pix->width, pix->height, pix);
- return 0;
-}
-
-static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx, bool jpeg)
-{
- ctx->scaler.enabled = !jpeg;
- fimc_ctrls_activate(ctx, !jpeg);
-
- if (jpeg)
- set_bit(ST_CAPT_JPEG, &ctx->fimc_dev->state);
- else
- clear_bit(ST_CAPT_JPEG, &ctx->fimc_dev->state);
-}
-
-static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f)
-{
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct v4l2_mbus_framefmt *mf = &fimc->vid_cap.mf;
- struct fimc_frame *ff = &ctx->d_frame;
- struct fimc_fmt *s_fmt = NULL;
- int ret, i;
-
- if (vb2_is_busy(&fimc->vid_cap.vbq))
- return -EBUSY;
-
- /* Pre-configure format at camera interface input, for JPEG only */
- if (pix->pixelformat == V4L2_PIX_FMT_JPEG) {
- fimc_capture_try_format(ctx, &pix->width, &pix->height,
- NULL, &pix->pixelformat,
- FIMC_SD_PAD_SINK);
- ctx->s_frame.f_width = pix->width;
- ctx->s_frame.f_height = pix->height;
- }
- /* Try the format at the scaler and the DMA output */
- ff->fmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
- NULL, &pix->pixelformat,
- FIMC_SD_PAD_SOURCE);
- if (!ff->fmt)
- return -EINVAL;
-
- /* Update RGB Alpha control state and value range */
- fimc_alpha_ctrl_update(ctx);
-
- /* Try to match format at the host and the sensor */
- if (!fimc->vid_cap.user_subdev_api) {
- mf->code = ff->fmt->mbus_code;
- mf->width = pix->width;
- mf->height = pix->height;
-
- fimc_md_graph_lock(fimc);
- ret = fimc_pipeline_try_format(ctx, mf, &s_fmt, true);
- fimc_md_graph_unlock(fimc);
- if (ret)
- return ret;
- pix->width = mf->width;
- pix->height = mf->height;
- }
-
- fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix);
- for (i = 0; i < ff->fmt->colplanes; i++)
- ff->payload[i] = pix->plane_fmt[i].sizeimage;
-
- set_frame_bounds(ff, pix->width, pix->height);
- /* Reset the composition rectangle if not yet configured */
- if (!(ctx->state & FIMC_COMPOSE))
- set_frame_crop(ff, 0, 0, pix->width, pix->height);
-
- fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ff->fmt->color));
-
- /* Reset cropping and set format at the camera interface input */
- if (!fimc->vid_cap.user_subdev_api) {
- ctx->s_frame.fmt = s_fmt;
- set_frame_bounds(&ctx->s_frame, pix->width, pix->height);
- set_frame_crop(&ctx->s_frame, 0, 0, pix->width, pix->height);
- }
-
- return ret;
-}
-
-static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return fimc_capture_set_format(fimc, f);
-}
-
-static int fimc_cap_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
-
- if (i->index != 0)
- return -EINVAL;
-
- i->type = V4L2_INPUT_TYPE_CAMERA;
- if (sd)
- strlcpy(i->name, sd->name, sizeof(i->name));
- return 0;
-}
-
-static int fimc_cap_s_input(struct file *file, void *priv, unsigned int i)
-{
- return i == 0 ? i : -EINVAL;
-}
-
-static int fimc_cap_g_input(struct file *file, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-/**
- * fimc_pipeline_validate - check for formats inconsistencies
- * between source and sink pad of each link
- *
- * Return 0 if all formats match or -EPIPE otherwise.
- */
-static int fimc_pipeline_validate(struct fimc_dev *fimc)
-{
- struct v4l2_subdev_format sink_fmt, src_fmt;
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- struct v4l2_subdev *sd;
- struct media_pad *pad;
- int ret;
-
- /* Start with the video capture node pad */
- pad = media_entity_remote_source(&vid_cap->vd_pad);
- if (pad == NULL)
- return -EPIPE;
- /* FIMC.{N} subdevice */
- sd = media_entity_to_v4l2_subdev(pad->entity);
-
- while (1) {
- /* Retrieve format at the sink pad */
- pad = &sd->entity.pads[0];
- if (!(pad->flags & MEDIA_PAD_FL_SINK))
- break;
- /* Don't call FIMC subdev operation to avoid nested locking */
- if (sd == &fimc->vid_cap.subdev) {
- struct fimc_frame *ff = &vid_cap->ctx->s_frame;
- sink_fmt.format.width = ff->f_width;
- sink_fmt.format.height = ff->f_height;
- sink_fmt.format.code = ff->fmt ? ff->fmt->mbus_code : 0;
- } else {
- sink_fmt.pad = pad->index;
- sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sink_fmt);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return -EPIPE;
- }
- /* Retrieve format at the source pad */
- pad = media_entity_remote_source(pad);
- if (pad == NULL ||
- media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
- break;
-
- sd = media_entity_to_v4l2_subdev(pad->entity);
- src_fmt.pad = pad->index;
- src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return -EPIPE;
-
- if (src_fmt.format.width != sink_fmt.format.width ||
- src_fmt.format.height != sink_fmt.format.height ||
- src_fmt.format.code != sink_fmt.format.code)
- return -EPIPE;
- }
- return 0;
-}
-
-static int fimc_cap_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_pipeline *p = &fimc->pipeline;
- struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR];
- int ret;
-
- if (fimc_capture_active(fimc))
- return -EBUSY;
-
- ret = media_entity_pipeline_start(&sd->entity, p->m_pipeline);
- if (ret < 0)
- return ret;
-
- if (fimc->vid_cap.user_subdev_api) {
- ret = fimc_pipeline_validate(fimc);
- if (ret < 0) {
- media_entity_pipeline_stop(&sd->entity);
- return ret;
- }
- }
- return vb2_streamon(&fimc->vid_cap.vbq, type);
-}
-
-static int fimc_cap_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
- int ret;
-
- ret = vb2_streamoff(&fimc->vid_cap.vbq, type);
- if (ret == 0)
- media_entity_pipeline_stop(&sd->entity);
- return ret;
-}
-
-static int fimc_cap_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- int ret = vb2_reqbufs(&fimc->vid_cap.vbq, reqbufs);
-
- if (!ret)
- fimc->vid_cap.reqbufs_count = reqbufs->count;
- return ret;
-}
-
-static int fimc_cap_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return vb2_querybuf(&fimc->vid_cap.vbq, buf);
-}
-
-static int fimc_cap_qbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return vb2_qbuf(&fimc->vid_cap.vbq, buf);
-}
-
-static int fimc_cap_dqbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return vb2_dqbuf(&fimc->vid_cap.vbq, buf, file->f_flags & O_NONBLOCK);
-}
-
-static int fimc_cap_create_bufs(struct file *file, void *priv,
- struct v4l2_create_buffers *create)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return vb2_create_bufs(&fimc->vid_cap.vbq, create);
-}
-
-static int fimc_cap_prepare_buf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return vb2_prepare_buf(&fimc->vid_cap.vbq, b);
-}
-
-static int fimc_cap_g_selection(struct file *file, void *fh,
- struct v4l2_selection *s)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct fimc_frame *f = &ctx->s_frame;
-
- if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return -EINVAL;
-
- switch (s->target) {
- case V4L2_SEL_TGT_COMPOSE_DEFAULT:
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- f = &ctx->d_frame;
- case V4L2_SEL_TGT_CROP_BOUNDS:
- case V4L2_SEL_TGT_CROP_DEFAULT:
- s->r.left = 0;
- s->r.top = 0;
- s->r.width = f->o_width;
- s->r.height = f->o_height;
- return 0;
-
- case V4L2_SEL_TGT_COMPOSE:
- f = &ctx->d_frame;
- case V4L2_SEL_TGT_CROP:
- s->r.left = f->offs_h;
- s->r.top = f->offs_v;
- s->r.width = f->width;
- s->r.height = f->height;
- return 0;
- }
-
- return -EINVAL;
-}
-
-/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
-static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
-{
- if (a->left < b->left || a->top < b->top)
- return 0;
- if (a->left + a->width > b->left + b->width)
- return 0;
- if (a->top + a->height > b->top + b->height)
- return 0;
-
- return 1;
-}
-
-static int fimc_cap_s_selection(struct file *file, void *fh,
- struct v4l2_selection *s)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct v4l2_rect rect = s->r;
- struct fimc_frame *f;
- unsigned long flags;
-
- if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return -EINVAL;
-
- if (s->target == V4L2_SEL_TGT_COMPOSE)
- f = &ctx->d_frame;
- else if (s->target == V4L2_SEL_TGT_CROP)
- f = &ctx->s_frame;
- else
- return -EINVAL;
-
- fimc_capture_try_selection(ctx, &rect, s->target);
-
- if (s->flags & V4L2_SEL_FLAG_LE &&
- !enclosed_rectangle(&rect, &s->r))
- return -ERANGE;
-
- if (s->flags & V4L2_SEL_FLAG_GE &&
- !enclosed_rectangle(&s->r, &rect))
- return -ERANGE;
-
- s->r = rect;
- spin_lock_irqsave(&fimc->slock, flags);
- set_frame_crop(f, s->r.left, s->r.top, s->r.width,
- s->r.height);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- return 0;
-}
-
-static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
- .vidioc_querycap = fimc_vidioc_querycap_capture,
-
- .vidioc_enum_fmt_vid_cap_mplane = fimc_cap_enum_fmt_mplane,
- .vidioc_try_fmt_vid_cap_mplane = fimc_cap_try_fmt_mplane,
- .vidioc_s_fmt_vid_cap_mplane = fimc_cap_s_fmt_mplane,
- .vidioc_g_fmt_vid_cap_mplane = fimc_cap_g_fmt_mplane,
-
- .vidioc_reqbufs = fimc_cap_reqbufs,
- .vidioc_querybuf = fimc_cap_querybuf,
-
- .vidioc_qbuf = fimc_cap_qbuf,
- .vidioc_dqbuf = fimc_cap_dqbuf,
-
- .vidioc_prepare_buf = fimc_cap_prepare_buf,
- .vidioc_create_bufs = fimc_cap_create_bufs,
-
- .vidioc_streamon = fimc_cap_streamon,
- .vidioc_streamoff = fimc_cap_streamoff,
-
- .vidioc_g_selection = fimc_cap_g_selection,
- .vidioc_s_selection = fimc_cap_s_selection,
-
- .vidioc_enum_input = fimc_cap_enum_input,
- .vidioc_s_input = fimc_cap_s_input,
- .vidioc_g_input = fimc_cap_g_input,
-};
-
-/* Capture subdev media entity operations */
-static int fimc_link_setup(struct media_entity *entity,
- const struct media_pad *local,
- const struct media_pad *remote, u32 flags)
-{
- struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
-
- if (media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
- return -EINVAL;
-
- if (WARN_ON(fimc == NULL))
- return 0;
-
- dbg("%s --> %s, flags: 0x%x. input: 0x%x",
- local->entity->name, remote->entity->name, flags,
- fimc->vid_cap.input);
-
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (fimc->vid_cap.input != 0)
- return -EBUSY;
- fimc->vid_cap.input = sd->grp_id;
- return 0;
- }
-
- fimc->vid_cap.input = 0;
- return 0;
-}
-
-static const struct media_entity_operations fimc_sd_media_ops = {
- .link_setup = fimc_link_setup,
-};
-
-/**
- * fimc_sensor_notify - v4l2_device notification from a sensor subdev
- * @sd: pointer to a subdev generating the notification
- * @notification: the notification type, must be S5P_FIMC_TX_END_NOTIFY
- * @arg: pointer to an u32 type integer that stores the frame payload value
- *
- * The End Of Frame notification sent by sensor subdev in its still capture
- * mode. If there is only a single VSYNC generated by the sensor at the
- * beginning of a frame transmission, FIMC does not issue the LastIrq
- * (end of frame) interrupt. And this notification is used to complete the
- * frame capture and returning a buffer to user-space. Subdev drivers should
- * call this notification from their last 'End of frame capture' interrupt.
- */
-void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
- void *arg)
-{
- struct fimc_sensor_info *sensor;
- struct fimc_vid_buffer *buf;
- struct fimc_md *fmd;
- struct fimc_dev *fimc;
- unsigned long flags;
-
- if (sd == NULL)
- return;
-
- sensor = v4l2_get_subdev_hostdata(sd);
- fmd = entity_to_fimc_mdev(&sd->entity);
-
- spin_lock_irqsave(&fmd->slock, flags);
- fimc = sensor ? sensor->host : NULL;
-
- if (fimc && arg && notification == S5P_FIMC_TX_END_NOTIFY &&
- test_bit(ST_CAPT_PEND, &fimc->state)) {
- unsigned long irq_flags;
- spin_lock_irqsave(&fimc->slock, irq_flags);
- if (!list_empty(&fimc->vid_cap.active_buf_q)) {
- buf = list_entry(fimc->vid_cap.active_buf_q.next,
- struct fimc_vid_buffer, list);
- vb2_set_plane_payload(&buf->vb, 0, *((u32 *)arg));
- }
- fimc_capture_irq_handler(fimc, 1);
- fimc_deactivate_capture(fimc);
- spin_unlock_irqrestore(&fimc->slock, irq_flags);
- }
- spin_unlock_irqrestore(&fmd->slock, flags);
-}
-
-static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- struct fimc_fmt *fmt;
-
- fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, code->index);
- if (!fmt)
- return -EINVAL;
- code->code = fmt->mbus_code;
- return 0;
-}
-
-static int fimc_subdev_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct v4l2_mbus_framefmt *mf;
- struct fimc_frame *ff;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(fh, fmt->pad);
- fmt->format = *mf;
- return 0;
- }
- mf = &fmt->format;
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- ff = fmt->pad == FIMC_SD_PAD_SINK ? &ctx->s_frame : &ctx->d_frame;
-
- mutex_lock(&fimc->lock);
- /* The pixel code is same on both input and output pad */
- if (!WARN_ON(ctx->s_frame.fmt == NULL))
- mf->code = ctx->s_frame.fmt->mbus_code;
- mf->width = ff->f_width;
- mf->height = ff->f_height;
- mutex_unlock(&fimc->lock);
-
- return 0;
-}
-
-static int fimc_subdev_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *mf = &fmt->format;
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct fimc_frame *ff;
- struct fimc_fmt *ffmt;
-
- dbg("pad%d: code: 0x%x, %dx%d",
- fmt->pad, mf->code, mf->width, mf->height);
-
- if (fmt->pad == FIMC_SD_PAD_SOURCE &&
- vb2_is_busy(&fimc->vid_cap.vbq))
- return -EBUSY;
-
- mutex_lock(&fimc->lock);
- ffmt = fimc_capture_try_format(ctx, &mf->width, &mf->height,
- &mf->code, NULL, fmt->pad);
- mutex_unlock(&fimc->lock);
- mf->colorspace = V4L2_COLORSPACE_JPEG;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(fh, fmt->pad);
- *mf = fmt->format;
- return 0;
- }
- /* Update RGB Alpha control state and value range */
- fimc_alpha_ctrl_update(ctx);
-
- fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ffmt->color));
-
- ff = fmt->pad == FIMC_SD_PAD_SINK ?
- &ctx->s_frame : &ctx->d_frame;
-
- mutex_lock(&fimc->lock);
- set_frame_bounds(ff, mf->width, mf->height);
- fimc->vid_cap.mf = *mf;
- ff->fmt = ffmt;
-
- /* Reset the crop rectangle if required. */
- if (!(fmt->pad == FIMC_SD_PAD_SOURCE && (ctx->state & FIMC_COMPOSE)))
- set_frame_crop(ff, 0, 0, mf->width, mf->height);
-
- if (fmt->pad == FIMC_SD_PAD_SINK)
- ctx->state &= ~FIMC_COMPOSE;
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static int fimc_subdev_get_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct fimc_frame *f = &ctx->s_frame;
- struct v4l2_rect *r = &sel->r;
- struct v4l2_rect *try_sel;
-
- if (sel->pad != FIMC_SD_PAD_SINK)
- return -EINVAL;
-
- mutex_lock(&fimc->lock);
-
- switch (sel->target) {
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- f = &ctx->d_frame;
- case V4L2_SEL_TGT_CROP_BOUNDS:
- r->width = f->o_width;
- r->height = f->o_height;
- r->left = 0;
- r->top = 0;
- mutex_unlock(&fimc->lock);
- return 0;
-
- case V4L2_SEL_TGT_CROP:
- try_sel = v4l2_subdev_get_try_crop(fh, sel->pad);
- break;
- case V4L2_SEL_TGT_COMPOSE:
- try_sel = v4l2_subdev_get_try_compose(fh, sel->pad);
- f = &ctx->d_frame;
- break;
- default:
- mutex_unlock(&fimc->lock);
- return -EINVAL;
- }
-
- if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
- sel->r = *try_sel;
- } else {
- r->left = f->offs_h;
- r->top = f->offs_v;
- r->width = f->width;
- r->height = f->height;
- }
-
- dbg("target %#x: l:%d, t:%d, %dx%d, f_w: %d, f_h: %d",
- sel->pad, r->left, r->top, r->width, r->height,
- f->f_width, f->f_height);
-
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static int fimc_subdev_set_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct fimc_frame *f = &ctx->s_frame;
- struct v4l2_rect *r = &sel->r;
- struct v4l2_rect *try_sel;
- unsigned long flags;
-
- if (sel->pad != FIMC_SD_PAD_SINK)
- return -EINVAL;
-
- mutex_lock(&fimc->lock);
- fimc_capture_try_selection(ctx, r, V4L2_SEL_TGT_CROP);
-
- switch (sel->target) {
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- f = &ctx->d_frame;
- case V4L2_SEL_TGT_CROP_BOUNDS:
- r->width = f->o_width;
- r->height = f->o_height;
- r->left = 0;
- r->top = 0;
- mutex_unlock(&fimc->lock);
- return 0;
-
- case V4L2_SEL_TGT_CROP:
- try_sel = v4l2_subdev_get_try_crop(fh, sel->pad);
- break;
- case V4L2_SEL_TGT_COMPOSE:
- try_sel = v4l2_subdev_get_try_compose(fh, sel->pad);
- f = &ctx->d_frame;
- break;
- default:
- mutex_unlock(&fimc->lock);
- return -EINVAL;
- }
-
- if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
- *try_sel = sel->r;
- } else {
- spin_lock_irqsave(&fimc->slock, flags);
- set_frame_crop(f, r->left, r->top, r->width, r->height);
- set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- spin_unlock_irqrestore(&fimc->slock, flags);
- if (sel->target == V4L2_SEL_TGT_COMPOSE)
- ctx->state |= FIMC_COMPOSE;
- }
-
- dbg("target %#x: (%d,%d)/%dx%d", sel->target, r->left, r->top,
- r->width, r->height);
-
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static struct v4l2_subdev_pad_ops fimc_subdev_pad_ops = {
- .enum_mbus_code = fimc_subdev_enum_mbus_code,
- .get_selection = fimc_subdev_get_selection,
- .set_selection = fimc_subdev_set_selection,
- .get_fmt = fimc_subdev_get_fmt,
- .set_fmt = fimc_subdev_set_fmt,
-};
-
-static struct v4l2_subdev_ops fimc_subdev_ops = {
- .pad = &fimc_subdev_pad_ops,
-};
-
-/* Set default format at the sensor and host interface */
-static int fimc_capture_set_default_format(struct fimc_dev *fimc)
-{
- struct v4l2_format fmt = {
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
- .fmt.pix_mp = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_YUYV,
- .field = V4L2_FIELD_NONE,
- .colorspace = V4L2_COLORSPACE_JPEG,
- },
- };
-
- return fimc_capture_set_format(fimc, &fmt);
-}
-
-/* fimc->lock must be already initialized */
-static int fimc_register_capture_device(struct fimc_dev *fimc,
- struct v4l2_device *v4l2_dev)
-{
- struct video_device *vfd;
- struct fimc_vid_cap *vid_cap;
- struct fimc_ctx *ctx;
- struct vb2_queue *q;
- int ret = -ENOMEM;
-
- ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- ctx->fimc_dev = fimc;
- ctx->in_path = FIMC_IO_CAMERA;
- ctx->out_path = FIMC_IO_DMA;
- ctx->state = FIMC_CTX_CAP;
- ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
- ctx->d_frame.fmt = ctx->s_frame.fmt;
-
- vfd = video_device_alloc();
- if (!vfd) {
- v4l2_err(v4l2_dev, "Failed to allocate video device\n");
- goto err_vd_alloc;
- }
-
- snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.capture", fimc->id);
-
- vfd->fops = &fimc_capture_fops;
- vfd->ioctl_ops = &fimc_capture_ioctl_ops;
- vfd->v4l2_dev = v4l2_dev;
- vfd->minor = -1;
- vfd->release = video_device_release;
- vfd->lock = &fimc->lock;
-
- video_set_drvdata(vfd, fimc);
-
- vid_cap = &fimc->vid_cap;
- vid_cap->vfd = vfd;
- vid_cap->active_buf_cnt = 0;
- vid_cap->reqbufs_count = 0;
- vid_cap->refcnt = 0;
-
- INIT_LIST_HEAD(&vid_cap->pending_buf_q);
- INIT_LIST_HEAD(&vid_cap->active_buf_q);
- vid_cap->ctx = ctx;
-
- q = &fimc->vid_cap.vbq;
- memset(q, 0, sizeof(*q));
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- q->io_modes = VB2_MMAP | VB2_USERPTR;
- q->drv_priv = fimc->vid_cap.ctx;
- q->ops = &fimc_capture_qops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->buf_struct_size = sizeof(struct fimc_vid_buffer);
-
- vb2_queue_init(q);
-
- vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
- ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
- if (ret)
- goto err_ent;
-
- ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
- if (ret)
- goto err_vd;
-
- v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
- vfd->name, video_device_node_name(vfd));
-
- vfd->ctrl_handler = &ctx->ctrls.handler;
- return 0;
-
-err_vd:
- media_entity_cleanup(&vfd->entity);
-err_ent:
- video_device_release(vfd);
-err_vd_alloc:
- kfree(ctx);
- return ret;
-}
-
-static int fimc_capture_subdev_registered(struct v4l2_subdev *sd)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- int ret;
-
- ret = fimc_register_m2m_device(fimc, sd->v4l2_dev);
- if (ret)
- return ret;
-
- ret = fimc_register_capture_device(fimc, sd->v4l2_dev);
- if (ret)
- fimc_unregister_m2m_device(fimc);
-
- return ret;
-}
-
-static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
-
- if (fimc == NULL)
- return;
-
- fimc_unregister_m2m_device(fimc);
-
- if (fimc->vid_cap.vfd) {
- media_entity_cleanup(&fimc->vid_cap.vfd->entity);
- video_unregister_device(fimc->vid_cap.vfd);
- fimc->vid_cap.vfd = NULL;
- }
-
- kfree(fimc->vid_cap.ctx);
- fimc->vid_cap.ctx = NULL;
-}
-
-static const struct v4l2_subdev_internal_ops fimc_capture_sd_internal_ops = {
- .registered = fimc_capture_subdev_registered,
- .unregistered = fimc_capture_subdev_unregistered,
-};
-
-int fimc_initialize_capture_subdev(struct fimc_dev *fimc)
-{
- struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
- int ret;
-
- v4l2_subdev_init(sd, &fimc_subdev_ops);
- sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
- snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->pdev->id);
-
- fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
- fimc->vid_cap.sd_pads, 0);
- if (ret)
- return ret;
-
- sd->entity.ops = &fimc_sd_media_ops;
- sd->internal_ops = &fimc_capture_sd_internal_ops;
- v4l2_set_subdevdata(sd, fimc);
- return 0;
-}
-
-void fimc_unregister_capture_subdev(struct fimc_dev *fimc)
-{
- struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
-
- v4l2_device_unregister_subdev(sd);
- media_entity_cleanup(&sd->entity);
- v4l2_set_subdevdata(sd, NULL);
-}
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
deleted file mode 100644
index 1a445404e73..00000000000
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ /dev/null
@@ -1,1239 +0,0 @@
-/*
- * Samsung S5P/EXYNOS4 SoC series FIMC (CAMIF) driver
- *
- * Copyright (C) 2010-2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation, either version 2 of the License,
- * or (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/bug.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/list.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "fimc-core.h"
-#include "fimc-reg.h"
-#include "fimc-mdevice.h"
-
-static char *fimc_clocks[MAX_FIMC_CLOCKS] = {
- "sclk_fimc", "fimc"
-};
-
-static struct fimc_fmt fimc_formats[] = {
- {
- .name = "RGB565",
- .fourcc = V4L2_PIX_FMT_RGB565,
- .depth = { 16 },
- .color = FIMC_FMT_RGB565,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "BGR666",
- .fourcc = V4L2_PIX_FMT_BGR666,
- .depth = { 32 },
- .color = FIMC_FMT_RGB666,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "ARGB8888, 32 bpp",
- .fourcc = V4L2_PIX_FMT_RGB32,
- .depth = { 32 },
- .color = FIMC_FMT_RGB888,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M | FMT_HAS_ALPHA,
- }, {
- .name = "ARGB1555",
- .fourcc = V4L2_PIX_FMT_RGB555,
- .depth = { 16 },
- .color = FIMC_FMT_RGB555,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
- }, {
- .name = "ARGB4444",
- .fourcc = V4L2_PIX_FMT_RGB444,
- .depth = { 16 },
- .color = FIMC_FMT_RGB444,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
- }, {
- .name = "YUV 4:2:2 packed, YCbYCr",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = { 16 },
- .color = FIMC_FMT_YCBYCR422,
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
- .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
- }, {
- .name = "YUV 4:2:2 packed, CbYCrY",
- .fourcc = V4L2_PIX_FMT_UYVY,
- .depth = { 16 },
- .color = FIMC_FMT_CBYCRY422,
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
- .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
- }, {
- .name = "YUV 4:2:2 packed, CrYCbY",
- .fourcc = V4L2_PIX_FMT_VYUY,
- .depth = { 16 },
- .color = FIMC_FMT_CRYCBY422,
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8,
- .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
- }, {
- .name = "YUV 4:2:2 packed, YCrYCb",
- .fourcc = V4L2_PIX_FMT_YVYU,
- .depth = { 16 },
- .color = FIMC_FMT_YCRYCB422,
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8,
- .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
- }, {
- .name = "YUV 4:2:2 planar, Y/Cb/Cr",
- .fourcc = V4L2_PIX_FMT_YUV422P,
- .depth = { 12 },
- .color = FIMC_FMT_YCBYCR422,
- .memplanes = 1,
- .colplanes = 3,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "YUV 4:2:2 planar, Y/CbCr",
- .fourcc = V4L2_PIX_FMT_NV16,
- .depth = { 16 },
- .color = FIMC_FMT_YCBYCR422,
- .memplanes = 1,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "YUV 4:2:2 planar, Y/CrCb",
- .fourcc = V4L2_PIX_FMT_NV61,
- .depth = { 16 },
- .color = FIMC_FMT_YCRYCB422,
- .memplanes = 1,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "YUV 4:2:0 planar, YCbCr",
- .fourcc = V4L2_PIX_FMT_YUV420,
- .depth = { 12 },
- .color = FIMC_FMT_YCBCR420,
- .memplanes = 1,
- .colplanes = 3,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "YUV 4:2:0 planar, Y/CbCr",
- .fourcc = V4L2_PIX_FMT_NV12,
- .depth = { 12 },
- .color = FIMC_FMT_YCBCR420,
- .memplanes = 1,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "YUV 4:2:0 non-contig. 2p, Y/CbCr",
- .fourcc = V4L2_PIX_FMT_NV12M,
- .color = FIMC_FMT_YCBCR420,
- .depth = { 8, 4 },
- .memplanes = 2,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "YUV 4:2:0 non-contig. 3p, Y/Cb/Cr",
- .fourcc = V4L2_PIX_FMT_YUV420M,
- .color = FIMC_FMT_YCBCR420,
- .depth = { 8, 2, 2 },
- .memplanes = 3,
- .colplanes = 3,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "YUV 4:2:0 non-contig. 2p, tiled",
- .fourcc = V4L2_PIX_FMT_NV12MT,
- .color = FIMC_FMT_YCBCR420,
- .depth = { 8, 4 },
- .memplanes = 2,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .name = "JPEG encoded data",
- .fourcc = V4L2_PIX_FMT_JPEG,
- .color = FIMC_FMT_JPEG,
- .depth = { 8 },
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_JPEG_1X8,
- .flags = FMT_FLAGS_CAM,
- },
-};
-
-struct fimc_fmt *fimc_get_format(unsigned int index)
-{
- if (index >= ARRAY_SIZE(fimc_formats))
- return NULL;
-
- return &fimc_formats[index];
-}
-
-int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
- int dw, int dh, int rotation)
-{
- if (rotation == 90 || rotation == 270)
- swap(dw, dh);
-
- if (!ctx->scaler.enabled)
- return (sw == dw && sh == dh) ? 0 : -EINVAL;
-
- if ((sw >= SCALER_MAX_HRATIO * dw) || (sh >= SCALER_MAX_VRATIO * dh))
- return -EINVAL;
-
- return 0;
-}
-
-static int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift)
-{
- u32 sh = 6;
-
- if (src >= 64 * tar)
- return -EINVAL;
-
- while (sh--) {
- u32 tmp = 1 << sh;
- if (src >= tar * tmp) {
- *shift = sh, *ratio = tmp;
- return 0;
- }
- }
- *shift = 0, *ratio = 1;
- return 0;
-}
-
-int fimc_set_scaler_info(struct fimc_ctx *ctx)
-{
- struct fimc_variant *variant = ctx->fimc_dev->variant;
- struct device *dev = &ctx->fimc_dev->pdev->dev;
- struct fimc_scaler *sc = &ctx->scaler;
- struct fimc_frame *s_frame = &ctx->s_frame;
- struct fimc_frame *d_frame = &ctx->d_frame;
- int tx, ty, sx, sy;
- int ret;
-
- if (ctx->rotation == 90 || ctx->rotation == 270) {
- ty = d_frame->width;
- tx = d_frame->height;
- } else {
- tx = d_frame->width;
- ty = d_frame->height;
- }
- if (tx <= 0 || ty <= 0) {
- dev_err(dev, "Invalid target size: %dx%d", tx, ty);
- return -EINVAL;
- }
-
- sx = s_frame->width;
- sy = s_frame->height;
- if (sx <= 0 || sy <= 0) {
- dev_err(dev, "Invalid source size: %dx%d", sx, sy);
- return -EINVAL;
- }
- sc->real_width = sx;
- sc->real_height = sy;
-
- ret = fimc_get_scaler_factor(sx, tx, &sc->pre_hratio, &sc->hfactor);
- if (ret)
- return ret;
-
- ret = fimc_get_scaler_factor(sy, ty, &sc->pre_vratio, &sc->vfactor);
- if (ret)
- return ret;
-
- sc->pre_dst_width = sx / sc->pre_hratio;
- sc->pre_dst_height = sy / sc->pre_vratio;
-
- if (variant->has_mainscaler_ext) {
- sc->main_hratio = (sx << 14) / (tx << sc->hfactor);
- sc->main_vratio = (sy << 14) / (ty << sc->vfactor);
- } else {
- sc->main_hratio = (sx << 8) / (tx << sc->hfactor);
- sc->main_vratio = (sy << 8) / (ty << sc->vfactor);
-
- }
-
- sc->scaleup_h = (tx >= sx) ? 1 : 0;
- sc->scaleup_v = (ty >= sy) ? 1 : 0;
-
- /* check to see if input and output size/format differ */
- if (s_frame->fmt->color == d_frame->fmt->color
- && s_frame->width == d_frame->width
- && s_frame->height == d_frame->height)
- sc->copy_mode = 1;
- else
- sc->copy_mode = 0;
-
- return 0;
-}
-
-static irqreturn_t fimc_irq_handler(int irq, void *priv)
-{
- struct fimc_dev *fimc = priv;
- struct fimc_ctx *ctx;
-
- fimc_hw_clear_irq(fimc);
-
- spin_lock(&fimc->slock);
-
- if (test_and_clear_bit(ST_M2M_PEND, &fimc->state)) {
- if (test_and_clear_bit(ST_M2M_SUSPENDING, &fimc->state)) {
- set_bit(ST_M2M_SUSPENDED, &fimc->state);
- wake_up(&fimc->irq_queue);
- goto out;
- }
- ctx = v4l2_m2m_get_curr_priv(fimc->m2m.m2m_dev);
- if (ctx != NULL) {
- spin_unlock(&fimc->slock);
- fimc_m2m_job_finish(ctx, VB2_BUF_STATE_DONE);
-
- if (ctx->state & FIMC_CTX_SHUT) {
- ctx->state &= ~FIMC_CTX_SHUT;
- wake_up(&fimc->irq_queue);
- }
- return IRQ_HANDLED;
- }
- } else if (test_bit(ST_CAPT_PEND, &fimc->state)) {
- int last_buf = test_bit(ST_CAPT_JPEG, &fimc->state) &&
- fimc->vid_cap.reqbufs_count == 1;
- fimc_capture_irq_handler(fimc, !last_buf);
- }
-out:
- spin_unlock(&fimc->slock);
- return IRQ_HANDLED;
-}
-
-/* The color format (colplanes, memplanes) must be already configured. */
-int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
- struct fimc_frame *frame, struct fimc_addr *paddr)
-{
- int ret = 0;
- u32 pix_size;
-
- if (vb == NULL || frame == NULL)
- return -EINVAL;
-
- pix_size = frame->width * frame->height;
-
- dbg("memplanes= %d, colplanes= %d, pix_size= %d",
- frame->fmt->memplanes, frame->fmt->colplanes, pix_size);
-
- paddr->y = vb2_dma_contig_plane_dma_addr(vb, 0);
-
- if (frame->fmt->memplanes == 1) {
- switch (frame->fmt->colplanes) {
- case 1:
- paddr->cb = 0;
- paddr->cr = 0;
- break;
- case 2:
- /* decompose Y into Y/Cb */
- paddr->cb = (u32)(paddr->y + pix_size);
- paddr->cr = 0;
- break;
- case 3:
- paddr->cb = (u32)(paddr->y + pix_size);
- /* decompose Y into Y/Cb/Cr */
- if (FIMC_FMT_YCBCR420 == frame->fmt->color)
- paddr->cr = (u32)(paddr->cb
- + (pix_size >> 2));
- else /* 422 */
- paddr->cr = (u32)(paddr->cb
- + (pix_size >> 1));
- break;
- default:
- return -EINVAL;
- }
- } else {
- if (frame->fmt->memplanes >= 2)
- paddr->cb = vb2_dma_contig_plane_dma_addr(vb, 1);
-
- if (frame->fmt->memplanes == 3)
- paddr->cr = vb2_dma_contig_plane_dma_addr(vb, 2);
- }
-
- dbg("PHYS_ADDR: y= 0x%X cb= 0x%X cr= 0x%X ret= %d",
- paddr->y, paddr->cb, paddr->cr, ret);
-
- return ret;
-}
-
-/* Set order for 1 and 2 plane YCBCR 4:2:2 formats. */
-void fimc_set_yuv_order(struct fimc_ctx *ctx)
-{
- /* The one only mode supported in SoC. */
- ctx->in_order_2p = FIMC_REG_CIOCTRL_ORDER422_2P_LSB_CRCB;
- ctx->out_order_2p = FIMC_REG_CIOCTRL_ORDER422_2P_LSB_CRCB;
-
- /* Set order for 1 plane input formats. */
- switch (ctx->s_frame.fmt->color) {
- case FIMC_FMT_YCRYCB422:
- ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_CBYCRY;
- break;
- case FIMC_FMT_CBYCRY422:
- ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_YCRYCB;
- break;
- case FIMC_FMT_CRYCBY422:
- ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_YCBYCR;
- break;
- case FIMC_FMT_YCBYCR422:
- default:
- ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_CRYCBY;
- break;
- }
- dbg("ctx->in_order_1p= %d", ctx->in_order_1p);
-
- switch (ctx->d_frame.fmt->color) {
- case FIMC_FMT_YCRYCB422:
- ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_CBYCRY;
- break;
- case FIMC_FMT_CBYCRY422:
- ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_YCRYCB;
- break;
- case FIMC_FMT_CRYCBY422:
- ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_YCBYCR;
- break;
- case FIMC_FMT_YCBYCR422:
- default:
- ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_CRYCBY;
- break;
- }
- dbg("ctx->out_order_1p= %d", ctx->out_order_1p);
-}
-
-void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
-{
- struct fimc_variant *variant = ctx->fimc_dev->variant;
- u32 i, depth = 0;
-
- for (i = 0; i < f->fmt->colplanes; i++)
- depth += f->fmt->depth[i];
-
- f->dma_offset.y_h = f->offs_h;
- if (!variant->pix_hoff)
- f->dma_offset.y_h *= (depth >> 3);
-
- f->dma_offset.y_v = f->offs_v;
-
- f->dma_offset.cb_h = f->offs_h;
- f->dma_offset.cb_v = f->offs_v;
-
- f->dma_offset.cr_h = f->offs_h;
- f->dma_offset.cr_v = f->offs_v;
-
- if (!variant->pix_hoff) {
- if (f->fmt->colplanes == 3) {
- f->dma_offset.cb_h >>= 1;
- f->dma_offset.cr_h >>= 1;
- }
- if (f->fmt->color == FIMC_FMT_YCBCR420) {
- f->dma_offset.cb_v >>= 1;
- f->dma_offset.cr_v >>= 1;
- }
- }
-
- dbg("in_offset: color= %d, y_h= %d, y_v= %d",
- f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v);
-}
-
-static int fimc_set_color_effect(struct fimc_ctx *ctx, enum v4l2_colorfx colorfx)
-{
- struct fimc_effect *effect = &ctx->effect;
-
- switch (colorfx) {
- case V4L2_COLORFX_NONE:
- effect->type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
- break;
- case V4L2_COLORFX_BW:
- effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
- effect->pat_cb = 128;
- effect->pat_cr = 128;
- break;
- case V4L2_COLORFX_SEPIA:
- effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
- effect->pat_cb = 115;
- effect->pat_cr = 145;
- break;
- case V4L2_COLORFX_NEGATIVE:
- effect->type = FIMC_REG_CIIMGEFF_FIN_NEGATIVE;
- break;
- case V4L2_COLORFX_EMBOSS:
- effect->type = FIMC_REG_CIIMGEFF_FIN_EMBOSSING;
- break;
- case V4L2_COLORFX_ART_FREEZE:
- effect->type = FIMC_REG_CIIMGEFF_FIN_ARTFREEZE;
- break;
- case V4L2_COLORFX_SILHOUETTE:
- effect->type = FIMC_REG_CIIMGEFF_FIN_SILHOUETTE;
- break;
- case V4L2_COLORFX_SET_CBCR:
- effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
- effect->pat_cb = ctx->ctrls.colorfx_cbcr->val >> 8;
- effect->pat_cr = ctx->ctrls.colorfx_cbcr->val & 0xff;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * V4L2 controls handling
- */
-#define ctrl_to_ctx(__ctrl) \
- container_of((__ctrl)->handler, struct fimc_ctx, ctrls.handler)
-
-static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_variant *variant = fimc->variant;
- unsigned int flags = FIMC_DST_FMT | FIMC_SRC_FMT;
- int ret = 0;
-
- if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_HFLIP:
- ctx->hflip = ctrl->val;
- break;
-
- case V4L2_CID_VFLIP:
- ctx->vflip = ctrl->val;
- break;
-
- case V4L2_CID_ROTATE:
- if (fimc_capture_pending(fimc) ||
- (ctx->state & flags) == flags) {
- ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
- ctx->s_frame.height, ctx->d_frame.width,
- ctx->d_frame.height, ctrl->val);
- if (ret)
- return -EINVAL;
- }
- if ((ctrl->val == 90 || ctrl->val == 270) &&
- !variant->has_out_rot)
- return -EINVAL;
-
- ctx->rotation = ctrl->val;
- break;
-
- case V4L2_CID_ALPHA_COMPONENT:
- ctx->d_frame.alpha = ctrl->val;
- break;
-
- case V4L2_CID_COLORFX:
- ret = fimc_set_color_effect(ctx, ctrl->val);
- if (ret)
- return ret;
- break;
- }
-
- ctx->state |= FIMC_PARAMS;
- set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- return 0;
-}
-
-static int fimc_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct fimc_ctx *ctx = ctrl_to_ctx(ctrl);
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&ctx->fimc_dev->slock, flags);
- ret = __fimc_s_ctrl(ctx, ctrl);
- spin_unlock_irqrestore(&ctx->fimc_dev->slock, flags);
-
- return ret;
-}
-
-static const struct v4l2_ctrl_ops fimc_ctrl_ops = {
- .s_ctrl = fimc_s_ctrl,
-};
-
-int fimc_ctrls_create(struct fimc_ctx *ctx)
-{
- struct fimc_variant *variant = ctx->fimc_dev->variant;
- unsigned int max_alpha = fimc_get_alpha_mask(ctx->d_frame.fmt);
- struct fimc_ctrls *ctrls = &ctx->ctrls;
- struct v4l2_ctrl_handler *handler = &ctrls->handler;
-
- if (ctx->ctrls.ready)
- return 0;
-
- v4l2_ctrl_handler_init(handler, 6);
-
- ctrls->rotate = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
- V4L2_CID_ROTATE, 0, 270, 90, 0);
- ctrls->hflip = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- ctrls->vflip = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
-
- if (variant->has_alpha)
- ctrls->alpha = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
- V4L2_CID_ALPHA_COMPONENT,
- 0, max_alpha, 1, 0);
- else
- ctrls->alpha = NULL;
-
- ctrls->colorfx = v4l2_ctrl_new_std_menu(handler, &fimc_ctrl_ops,
- V4L2_CID_COLORFX, V4L2_COLORFX_SET_CBCR,
- ~0x983f, V4L2_COLORFX_NONE);
-
- ctrls->colorfx_cbcr = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
- V4L2_CID_COLORFX_CBCR, 0, 0xffff, 1, 0);
-
- ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
-
- if (!handler->error) {
- v4l2_ctrl_cluster(2, &ctrls->colorfx);
- ctrls->ready = true;
- }
-
- return handler->error;
-}
-
-void fimc_ctrls_delete(struct fimc_ctx *ctx)
-{
- struct fimc_ctrls *ctrls = &ctx->ctrls;
-
- if (ctrls->ready) {
- v4l2_ctrl_handler_free(&ctrls->handler);
- ctrls->ready = false;
- ctrls->alpha = NULL;
- }
-}
-
-void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active)
-{
- unsigned int has_alpha = ctx->d_frame.fmt->flags & FMT_HAS_ALPHA;
- struct fimc_ctrls *ctrls = &ctx->ctrls;
-
- if (!ctrls->ready)
- return;
-
- mutex_lock(ctrls->handler.lock);
- v4l2_ctrl_activate(ctrls->rotate, active);
- v4l2_ctrl_activate(ctrls->hflip, active);
- v4l2_ctrl_activate(ctrls->vflip, active);
- v4l2_ctrl_activate(ctrls->colorfx, active);
- if (ctrls->alpha)
- v4l2_ctrl_activate(ctrls->alpha, active && has_alpha);
-
- if (active) {
- fimc_set_color_effect(ctx, ctrls->colorfx->cur.val);
- ctx->rotation = ctrls->rotate->val;
- ctx->hflip = ctrls->hflip->val;
- ctx->vflip = ctrls->vflip->val;
- } else {
- ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
- ctx->rotation = 0;
- ctx->hflip = 0;
- ctx->vflip = 0;
- }
- mutex_unlock(ctrls->handler.lock);
-}
-
-/* Update maximum value of the alpha color control */
-void fimc_alpha_ctrl_update(struct fimc_ctx *ctx)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct v4l2_ctrl *ctrl = ctx->ctrls.alpha;
-
- if (ctrl == NULL || !fimc->variant->has_alpha)
- return;
-
- v4l2_ctrl_lock(ctrl);
- ctrl->maximum = fimc_get_alpha_mask(ctx->d_frame.fmt);
-
- if (ctrl->cur.val > ctrl->maximum)
- ctrl->cur.val = ctrl->maximum;
-
- v4l2_ctrl_unlock(ctrl);
-}
-
-int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f)
-{
- struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
- int i;
-
- pixm->width = frame->o_width;
- pixm->height = frame->o_height;
- pixm->field = V4L2_FIELD_NONE;
- pixm->pixelformat = frame->fmt->fourcc;
- pixm->colorspace = V4L2_COLORSPACE_JPEG;
- pixm->num_planes = frame->fmt->memplanes;
-
- for (i = 0; i < pixm->num_planes; ++i) {
- int bpl = frame->f_width;
- if (frame->fmt->colplanes == 1) /* packed formats */
- bpl = (bpl * frame->fmt->depth[0]) / 8;
- pixm->plane_fmt[i].bytesperline = bpl;
- pixm->plane_fmt[i].sizeimage = (frame->o_width *
- frame->o_height * frame->fmt->depth[i]) / 8;
- }
- return 0;
-}
-
-void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f)
-{
- struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
-
- frame->f_width = pixm->plane_fmt[0].bytesperline;
- if (frame->fmt->colplanes == 1)
- frame->f_width = (frame->f_width * 8) / frame->fmt->depth[0];
- frame->f_height = pixm->height;
- frame->width = pixm->width;
- frame->height = pixm->height;
- frame->o_width = pixm->width;
- frame->o_height = pixm->height;
- frame->offs_h = 0;
- frame->offs_v = 0;
-}
-
-/**
- * fimc_adjust_mplane_format - adjust bytesperline/sizeimage for each plane
- * @fmt: fimc pixel format description (input)
- * @width: requested pixel width
- * @height: requested pixel height
- * @pix: multi-plane format to adjust
- */
-void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
- struct v4l2_pix_format_mplane *pix)
-{
- u32 bytesperline = 0;
- int i;
-
- pix->colorspace = V4L2_COLORSPACE_JPEG;
- pix->field = V4L2_FIELD_NONE;
- pix->num_planes = fmt->memplanes;
- pix->pixelformat = fmt->fourcc;
- pix->height = height;
- pix->width = width;
-
- for (i = 0; i < pix->num_planes; ++i) {
- struct v4l2_plane_pix_format *plane_fmt = &pix->plane_fmt[i];
- u32 bpl = plane_fmt->bytesperline;
-
- if (fmt->colplanes > 1 && (bpl == 0 || bpl < pix->width))
- bpl = pix->width; /* Planar */
-
- if (fmt->colplanes == 1 && /* Packed */
- (bpl == 0 || ((bpl * 8) / fmt->depth[i]) < pix->width))
- bpl = (pix->width * fmt->depth[0]) / 8;
-
- if (i == 0) /* Same bytesperline for each plane. */
- bytesperline = bpl;
-
- plane_fmt->bytesperline = bytesperline;
- plane_fmt->sizeimage = max((pix->width * pix->height *
- fmt->depth[i]) / 8, plane_fmt->sizeimage);
- }
-}
-
-/**
- * fimc_find_format - lookup fimc color format by fourcc or media bus format
- * @pixelformat: fourcc to match, ignored if null
- * @mbus_code: media bus code to match, ignored if null
- * @mask: the color flags to match
- * @index: offset in the fimc_formats array, ignored if negative
- */
-struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
- unsigned int mask, int index)
-{
- struct fimc_fmt *fmt, *def_fmt = NULL;
- unsigned int i;
- int id = 0;
-
- if (index >= (int)ARRAY_SIZE(fimc_formats))
- return NULL;
-
- for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) {
- fmt = &fimc_formats[i];
- if (!(fmt->flags & mask))
- continue;
- if (pixelformat && fmt->fourcc == *pixelformat)
- return fmt;
- if (mbus_code && fmt->mbus_code == *mbus_code)
- return fmt;
- if (index == id)
- def_fmt = fmt;
- id++;
- }
- return def_fmt;
-}
-
-static void fimc_clk_put(struct fimc_dev *fimc)
-{
- int i;
- for (i = 0; i < MAX_FIMC_CLOCKS; i++) {
- if (IS_ERR_OR_NULL(fimc->clock[i]))
- continue;
- clk_unprepare(fimc->clock[i]);
- clk_put(fimc->clock[i]);
- fimc->clock[i] = NULL;
- }
-}
-
-static int fimc_clk_get(struct fimc_dev *fimc)
-{
- int i, ret;
-
- for (i = 0; i < MAX_FIMC_CLOCKS; i++) {
- fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clocks[i]);
- if (IS_ERR(fimc->clock[i]))
- goto err;
- ret = clk_prepare(fimc->clock[i]);
- if (ret < 0) {
- clk_put(fimc->clock[i]);
- fimc->clock[i] = NULL;
- goto err;
- }
- }
- return 0;
-err:
- fimc_clk_put(fimc);
- dev_err(&fimc->pdev->dev, "failed to get clock: %s\n",
- fimc_clocks[i]);
- return -ENXIO;
-}
-
-static int fimc_m2m_suspend(struct fimc_dev *fimc)
-{
- unsigned long flags;
- int timeout;
-
- spin_lock_irqsave(&fimc->slock, flags);
- if (!fimc_m2m_pending(fimc)) {
- spin_unlock_irqrestore(&fimc->slock, flags);
- return 0;
- }
- clear_bit(ST_M2M_SUSPENDED, &fimc->state);
- set_bit(ST_M2M_SUSPENDING, &fimc->state);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- timeout = wait_event_timeout(fimc->irq_queue,
- test_bit(ST_M2M_SUSPENDED, &fimc->state),
- FIMC_SHUTDOWN_TIMEOUT);
-
- clear_bit(ST_M2M_SUSPENDING, &fimc->state);
- return timeout == 0 ? -EAGAIN : 0;
-}
-
-static int fimc_m2m_resume(struct fimc_dev *fimc)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&fimc->slock, flags);
- /* Clear for full H/W setup in first run after resume */
- fimc->m2m.ctx = NULL;
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (test_and_clear_bit(ST_M2M_SUSPENDED, &fimc->state))
- fimc_m2m_job_finish(fimc->m2m.ctx,
- VB2_BUF_STATE_ERROR);
- return 0;
-}
-
-static int fimc_probe(struct platform_device *pdev)
-{
- struct fimc_drvdata *drv_data = fimc_get_drvdata(pdev);
- struct s5p_platform_fimc *pdata;
- struct fimc_dev *fimc;
- struct resource *res;
- int ret = 0;
-
- if (pdev->id >= drv_data->num_entities) {
- dev_err(&pdev->dev, "Invalid platform device id: %d\n",
- pdev->id);
- return -EINVAL;
- }
-
- fimc = devm_kzalloc(&pdev->dev, sizeof(*fimc), GFP_KERNEL);
- if (!fimc)
- return -ENOMEM;
-
- fimc->id = pdev->id;
-
- fimc->variant = drv_data->variant[fimc->id];
- fimc->pdev = pdev;
- pdata = pdev->dev.platform_data;
- fimc->pdata = pdata;
-
- init_waitqueue_head(&fimc->irq_queue);
- spin_lock_init(&fimc->slock);
- mutex_init(&fimc->lock);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- fimc->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (fimc->regs == NULL) {
- dev_err(&pdev->dev, "Failed to obtain io memory\n");
- return -ENOENT;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "Failed to get IRQ resource\n");
- return -ENXIO;
- }
-
- ret = fimc_clk_get(fimc);
- if (ret)
- return ret;
- clk_set_rate(fimc->clock[CLK_BUS], drv_data->lclk_frequency);
- clk_enable(fimc->clock[CLK_BUS]);
-
- ret = devm_request_irq(&pdev->dev, res->start, fimc_irq_handler,
- 0, dev_name(&pdev->dev), fimc);
- if (ret) {
- dev_err(&pdev->dev, "failed to install irq (%d)\n", ret);
- goto err_clk;
- }
-
- ret = fimc_initialize_capture_subdev(fimc);
- if (ret)
- goto err_clk;
-
- platform_set_drvdata(pdev, fimc);
- pm_runtime_enable(&pdev->dev);
- ret = pm_runtime_get_sync(&pdev->dev);
- if (ret < 0)
- goto err_sd;
- /* Initialize contiguous memory allocator */
- fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
- if (IS_ERR(fimc->alloc_ctx)) {
- ret = PTR_ERR(fimc->alloc_ctx);
- goto err_pm;
- }
-
- dev_dbg(&pdev->dev, "FIMC.%d registered successfully\n", fimc->id);
-
- pm_runtime_put(&pdev->dev);
- return 0;
-err_pm:
- pm_runtime_put(&pdev->dev);
-err_sd:
- fimc_unregister_capture_subdev(fimc);
-err_clk:
- fimc_clk_put(fimc);
- return ret;
-}
-
-static int fimc_runtime_resume(struct device *dev)
-{
- struct fimc_dev *fimc = dev_get_drvdata(dev);
-
- dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
-
- /* Enable clocks and perform basic initalization */
- clk_enable(fimc->clock[CLK_GATE]);
- fimc_hw_reset(fimc);
-
- /* Resume the capture or mem-to-mem device */
- if (fimc_capture_busy(fimc))
- return fimc_capture_resume(fimc);
-
- return fimc_m2m_resume(fimc);
-}
-
-static int fimc_runtime_suspend(struct device *dev)
-{
- struct fimc_dev *fimc = dev_get_drvdata(dev);
- int ret = 0;
-
- if (fimc_capture_busy(fimc))
- ret = fimc_capture_suspend(fimc);
- else
- ret = fimc_m2m_suspend(fimc);
- if (!ret)
- clk_disable(fimc->clock[CLK_GATE]);
-
- dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
- return ret;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int fimc_resume(struct device *dev)
-{
- struct fimc_dev *fimc = dev_get_drvdata(dev);
- unsigned long flags;
-
- dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
-
- /* Do not resume if the device was idle before system suspend */
- spin_lock_irqsave(&fimc->slock, flags);
- if (!test_and_clear_bit(ST_LPM, &fimc->state) ||
- (!fimc_m2m_active(fimc) && !fimc_capture_busy(fimc))) {
- spin_unlock_irqrestore(&fimc->slock, flags);
- return 0;
- }
- fimc_hw_reset(fimc);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (fimc_capture_busy(fimc))
- return fimc_capture_resume(fimc);
-
- return fimc_m2m_resume(fimc);
-}
-
-static int fimc_suspend(struct device *dev)
-{
- struct fimc_dev *fimc = dev_get_drvdata(dev);
-
- dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
-
- if (test_and_set_bit(ST_LPM, &fimc->state))
- return 0;
- if (fimc_capture_busy(fimc))
- return fimc_capture_suspend(fimc);
-
- return fimc_m2m_suspend(fimc);
-}
-#endif /* CONFIG_PM_SLEEP */
-
-static int __devexit fimc_remove(struct platform_device *pdev)
-{
- struct fimc_dev *fimc = platform_get_drvdata(pdev);
-
- pm_runtime_disable(&pdev->dev);
- pm_runtime_set_suspended(&pdev->dev);
-
- fimc_unregister_capture_subdev(fimc);
- vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
-
- clk_disable(fimc->clock[CLK_BUS]);
- fimc_clk_put(fimc);
-
- dev_info(&pdev->dev, "driver unloaded\n");
- return 0;
-}
-
-/* Image pixel limits, similar across several FIMC HW revisions. */
-static struct fimc_pix_limit s5p_pix_limit[4] = {
- [0] = {
- .scaler_en_w = 3264,
- .scaler_dis_w = 8192,
- .in_rot_en_h = 1920,
- .in_rot_dis_w = 8192,
- .out_rot_en_w = 1920,
- .out_rot_dis_w = 4224,
- },
- [1] = {
- .scaler_en_w = 4224,
- .scaler_dis_w = 8192,
- .in_rot_en_h = 1920,
- .in_rot_dis_w = 8192,
- .out_rot_en_w = 1920,
- .out_rot_dis_w = 4224,
- },
- [2] = {
- .scaler_en_w = 1920,
- .scaler_dis_w = 8192,
- .in_rot_en_h = 1280,
- .in_rot_dis_w = 8192,
- .out_rot_en_w = 1280,
- .out_rot_dis_w = 1920,
- },
- [3] = {
- .scaler_en_w = 1920,
- .scaler_dis_w = 8192,
- .in_rot_en_h = 1366,
- .in_rot_dis_w = 8192,
- .out_rot_en_w = 1366,
- .out_rot_dis_w = 1920,
- },
-};
-
-static struct fimc_variant fimc0_variant_s5p = {
- .has_inp_rot = 1,
- .has_out_rot = 1,
- .has_cam_if = 1,
- .min_inp_pixsize = 16,
- .min_out_pixsize = 16,
- .hor_offs_align = 8,
- .min_vsize_align = 16,
- .out_buf_count = 4,
- .pix_limit = &s5p_pix_limit[0],
-};
-
-static struct fimc_variant fimc2_variant_s5p = {
- .has_cam_if = 1,
- .min_inp_pixsize = 16,
- .min_out_pixsize = 16,
- .hor_offs_align = 8,
- .min_vsize_align = 16,
- .out_buf_count = 4,
- .pix_limit = &s5p_pix_limit[1],
-};
-
-static struct fimc_variant fimc0_variant_s5pv210 = {
- .pix_hoff = 1,
- .has_inp_rot = 1,
- .has_out_rot = 1,
- .has_cam_if = 1,
- .min_inp_pixsize = 16,
- .min_out_pixsize = 16,
- .hor_offs_align = 8,
- .min_vsize_align = 16,
- .out_buf_count = 4,
- .pix_limit = &s5p_pix_limit[1],
-};
-
-static struct fimc_variant fimc1_variant_s5pv210 = {
- .pix_hoff = 1,
- .has_inp_rot = 1,
- .has_out_rot = 1,
- .has_cam_if = 1,
- .has_mainscaler_ext = 1,
- .min_inp_pixsize = 16,
- .min_out_pixsize = 16,
- .hor_offs_align = 1,
- .min_vsize_align = 1,
- .out_buf_count = 4,
- .pix_limit = &s5p_pix_limit[2],
-};
-
-static struct fimc_variant fimc2_variant_s5pv210 = {
- .has_cam_if = 1,
- .pix_hoff = 1,
- .min_inp_pixsize = 16,
- .min_out_pixsize = 16,
- .hor_offs_align = 8,
- .min_vsize_align = 16,
- .out_buf_count = 4,
- .pix_limit = &s5p_pix_limit[2],
-};
-
-static struct fimc_variant fimc0_variant_exynos4 = {
- .pix_hoff = 1,
- .has_inp_rot = 1,
- .has_out_rot = 1,
- .has_cam_if = 1,
- .has_cistatus2 = 1,
- .has_mainscaler_ext = 1,
- .has_alpha = 1,
- .min_inp_pixsize = 16,
- .min_out_pixsize = 16,
- .hor_offs_align = 2,
- .min_vsize_align = 1,
- .out_buf_count = 32,
- .pix_limit = &s5p_pix_limit[1],
-};
-
-static struct fimc_variant fimc3_variant_exynos4 = {
- .pix_hoff = 1,
- .has_cam_if = 1,
- .has_cistatus2 = 1,
- .has_mainscaler_ext = 1,
- .has_alpha = 1,
- .min_inp_pixsize = 16,
- .min_out_pixsize = 16,
- .hor_offs_align = 2,
- .min_vsize_align = 1,
- .out_buf_count = 32,
- .pix_limit = &s5p_pix_limit[3],
-};
-
-/* S5PC100 */
-static struct fimc_drvdata fimc_drvdata_s5p = {
- .variant = {
- [0] = &fimc0_variant_s5p,
- [1] = &fimc0_variant_s5p,
- [2] = &fimc2_variant_s5p,
- },
- .num_entities = 3,
- .lclk_frequency = 133000000UL,
-};
-
-/* S5PV210, S5PC110 */
-static struct fimc_drvdata fimc_drvdata_s5pv210 = {
- .variant = {
- [0] = &fimc0_variant_s5pv210,
- [1] = &fimc1_variant_s5pv210,
- [2] = &fimc2_variant_s5pv210,
- },
- .num_entities = 3,
- .lclk_frequency = 166000000UL,
-};
-
-/* EXYNOS4210, S5PV310, S5PC210 */
-static struct fimc_drvdata fimc_drvdata_exynos4 = {
- .variant = {
- [0] = &fimc0_variant_exynos4,
- [1] = &fimc0_variant_exynos4,
- [2] = &fimc0_variant_exynos4,
- [3] = &fimc3_variant_exynos4,
- },
- .num_entities = 4,
- .lclk_frequency = 166000000UL,
-};
-
-static struct platform_device_id fimc_driver_ids[] = {
- {
- .name = "s5p-fimc",
- .driver_data = (unsigned long)&fimc_drvdata_s5p,
- }, {
- .name = "s5pv210-fimc",
- .driver_data = (unsigned long)&fimc_drvdata_s5pv210,
- }, {
- .name = "exynos4-fimc",
- .driver_data = (unsigned long)&fimc_drvdata_exynos4,
- },
- {},
-};
-MODULE_DEVICE_TABLE(platform, fimc_driver_ids);
-
-static const struct dev_pm_ops fimc_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(fimc_suspend, fimc_resume)
- SET_RUNTIME_PM_OPS(fimc_runtime_suspend, fimc_runtime_resume, NULL)
-};
-
-static struct platform_driver fimc_driver = {
- .probe = fimc_probe,
- .remove = __devexit_p(fimc_remove),
- .id_table = fimc_driver_ids,
- .driver = {
- .name = FIMC_MODULE_NAME,
- .owner = THIS_MODULE,
- .pm = &fimc_pm_ops,
- }
-};
-
-int __init fimc_register_driver(void)
-{
- return platform_driver_register(&fimc_driver);
-}
-
-void __exit fimc_unregister_driver(void)
-{
- platform_driver_unregister(&fimc_driver);
-}
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h
deleted file mode 100644
index 808ccc62184..00000000000
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ /dev/null
@@ -1,713 +0,0 @@
-/*
- * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef FIMC_CORE_H_
-#define FIMC_CORE_H_
-
-/*#define DEBUG*/
-
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-#include <linux/io.h>
-#include <asm/sizes.h>
-
-#include <media/media-entity.h>
-#include <media/videobuf2-core.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/v4l2-mediabus.h>
-#include <media/s5p_fimc.h>
-
-#define dbg(fmt, args...) \
- pr_debug("%s:%d: " fmt "\n", __func__, __LINE__, ##args)
-
-/* Time to wait for next frame VSYNC interrupt while stopping operation. */
-#define FIMC_SHUTDOWN_TIMEOUT ((100*HZ)/1000)
-#define MAX_FIMC_CLOCKS 2
-#define FIMC_MODULE_NAME "s5p-fimc"
-#define FIMC_MAX_DEVS 4
-#define FIMC_MAX_OUT_BUFS 4
-#define SCALER_MAX_HRATIO 64
-#define SCALER_MAX_VRATIO 64
-#define DMA_MIN_SIZE 8
-#define FIMC_CAMIF_MAX_HEIGHT 0x2000
-
-/* indices to the clocks array */
-enum {
- CLK_BUS,
- CLK_GATE,
-};
-
-enum fimc_dev_flags {
- ST_LPM,
- /* m2m node */
- ST_M2M_RUN,
- ST_M2M_PEND,
- ST_M2M_SUSPENDING,
- ST_M2M_SUSPENDED,
- /* capture node */
- ST_CAPT_PEND,
- ST_CAPT_RUN,
- ST_CAPT_STREAM,
- ST_CAPT_ISP_STREAM,
- ST_CAPT_SUSPENDED,
- ST_CAPT_SHUT,
- ST_CAPT_BUSY,
- ST_CAPT_APPLY_CFG,
- ST_CAPT_JPEG,
-};
-
-#define fimc_m2m_active(dev) test_bit(ST_M2M_RUN, &(dev)->state)
-#define fimc_m2m_pending(dev) test_bit(ST_M2M_PEND, &(dev)->state)
-
-#define fimc_capture_running(dev) test_bit(ST_CAPT_RUN, &(dev)->state)
-#define fimc_capture_pending(dev) test_bit(ST_CAPT_PEND, &(dev)->state)
-#define fimc_capture_busy(dev) test_bit(ST_CAPT_BUSY, &(dev)->state)
-
-enum fimc_datapath {
- FIMC_IO_NONE,
- FIMC_IO_CAMERA,
- FIMC_IO_DMA,
- FIMC_IO_LCDFIFO,
- FIMC_IO_WRITEBACK,
- FIMC_IO_ISP,
-};
-
-enum fimc_color_fmt {
- FIMC_FMT_RGB444 = 0x10,
- FIMC_FMT_RGB555,
- FIMC_FMT_RGB565,
- FIMC_FMT_RGB666,
- FIMC_FMT_RGB888,
- FIMC_FMT_RGB30_LOCAL,
- FIMC_FMT_YCBCR420 = 0x20,
- FIMC_FMT_YCBYCR422,
- FIMC_FMT_YCRYCB422,
- FIMC_FMT_CBYCRY422,
- FIMC_FMT_CRYCBY422,
- FIMC_FMT_YCBCR444_LOCAL,
- FIMC_FMT_JPEG = 0x40,
- FIMC_FMT_RAW8 = 0x80,
- FIMC_FMT_RAW10,
- FIMC_FMT_RAW12,
-};
-
-#define fimc_fmt_is_rgb(x) (!!((x) & 0x10))
-#define fimc_fmt_is_jpeg(x) (!!((x) & 0x40))
-
-#define IS_M2M(__strt) ((__strt) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || \
- __strt == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
-
-/* The hardware context state. */
-#define FIMC_PARAMS (1 << 0)
-#define FIMC_SRC_FMT (1 << 3)
-#define FIMC_DST_FMT (1 << 4)
-#define FIMC_COMPOSE (1 << 5)
-#define FIMC_CTX_M2M (1 << 16)
-#define FIMC_CTX_CAP (1 << 17)
-#define FIMC_CTX_SHUT (1 << 18)
-
-/* Image conversion flags */
-#define FIMC_IN_DMA_ACCESS_TILED (1 << 0)
-#define FIMC_IN_DMA_ACCESS_LINEAR (0 << 0)
-#define FIMC_OUT_DMA_ACCESS_TILED (1 << 1)
-#define FIMC_OUT_DMA_ACCESS_LINEAR (0 << 1)
-#define FIMC_SCAN_MODE_PROGRESSIVE (0 << 2)
-#define FIMC_SCAN_MODE_INTERLACED (1 << 2)
-/*
- * YCbCr data dynamic range for RGB-YUV color conversion.
- * Y/Cb/Cr: (0 ~ 255) */
-#define FIMC_COLOR_RANGE_WIDE (0 << 3)
-/* Y (16 ~ 235), Cb/Cr (16 ~ 240) */
-#define FIMC_COLOR_RANGE_NARROW (1 << 3)
-
-/**
- * struct fimc_fmt - the driver's internal color format data
- * @mbus_code: Media Bus pixel code, -1 if not applicable
- * @name: format description
- * @fourcc: the fourcc code for this format, 0 if not applicable
- * @color: the corresponding fimc_color_fmt
- * @memplanes: number of physically non-contiguous data planes
- * @colplanes: number of physically contiguous data planes
- * @depth: per plane driver's private 'number of bits per pixel'
- * @flags: flags indicating which operation mode format applies to
- */
-struct fimc_fmt {
- enum v4l2_mbus_pixelcode mbus_code;
- char *name;
- u32 fourcc;
- u32 color;
- u16 memplanes;
- u16 colplanes;
- u8 depth[VIDEO_MAX_PLANES];
- u16 flags;
-#define FMT_FLAGS_CAM (1 << 0)
-#define FMT_FLAGS_M2M_IN (1 << 1)
-#define FMT_FLAGS_M2M_OUT (1 << 2)
-#define FMT_FLAGS_M2M (1 << 1 | 1 << 2)
-#define FMT_HAS_ALPHA (1 << 3)
-};
-
-/**
- * struct fimc_dma_offset - pixel offset information for DMA
- * @y_h: y value horizontal offset
- * @y_v: y value vertical offset
- * @cb_h: cb value horizontal offset
- * @cb_v: cb value vertical offset
- * @cr_h: cr value horizontal offset
- * @cr_v: cr value vertical offset
- */
-struct fimc_dma_offset {
- int y_h;
- int y_v;
- int cb_h;
- int cb_v;
- int cr_h;
- int cr_v;
-};
-
-/**
- * struct fimc_effect - color effect information
- * @type: effect type
- * @pat_cb: cr value when type is "arbitrary"
- * @pat_cr: cr value when type is "arbitrary"
- */
-struct fimc_effect {
- u32 type;
- u8 pat_cb;
- u8 pat_cr;
-};
-
-/**
- * struct fimc_scaler - the configuration data for FIMC inetrnal scaler
- * @scaleup_h: flag indicating scaling up horizontally
- * @scaleup_v: flag indicating scaling up vertically
- * @copy_mode: flag indicating transparent DMA transfer (no scaling
- * and color format conversion)
- * @enabled: flag indicating if the scaler is used
- * @hfactor: horizontal shift factor
- * @vfactor: vertical shift factor
- * @pre_hratio: horizontal ratio of the prescaler
- * @pre_vratio: vertical ratio of the prescaler
- * @pre_dst_width: the prescaler's destination width
- * @pre_dst_height: the prescaler's destination height
- * @main_hratio: the main scaler's horizontal ratio
- * @main_vratio: the main scaler's vertical ratio
- * @real_width: source pixel (width - offset)
- * @real_height: source pixel (height - offset)
- */
-struct fimc_scaler {
- unsigned int scaleup_h:1;
- unsigned int scaleup_v:1;
- unsigned int copy_mode:1;
- unsigned int enabled:1;
- u32 hfactor;
- u32 vfactor;
- u32 pre_hratio;
- u32 pre_vratio;
- u32 pre_dst_width;
- u32 pre_dst_height;
- u32 main_hratio;
- u32 main_vratio;
- u32 real_width;
- u32 real_height;
-};
-
-/**
- * struct fimc_addr - the FIMC physical address set for DMA
- * @y: luminance plane physical address
- * @cb: Cb plane physical address
- * @cr: Cr plane physical address
- */
-struct fimc_addr {
- u32 y;
- u32 cb;
- u32 cr;
-};
-
-/**
- * struct fimc_vid_buffer - the driver's video buffer
- * @vb: v4l videobuf buffer
- * @list: linked list structure for buffer queue
- * @paddr: precalculated physical address set
- * @index: buffer index for the output DMA engine
- */
-struct fimc_vid_buffer {
- struct vb2_buffer vb;
- struct list_head list;
- struct fimc_addr paddr;
- int index;
-};
-
-/**
- * struct fimc_frame - source/target frame properties
- * @f_width: image full width (virtual screen size)
- * @f_height: image full height (virtual screen size)
- * @o_width: original image width as set by S_FMT
- * @o_height: original image height as set by S_FMT
- * @offs_h: image horizontal pixel offset
- * @offs_v: image vertical pixel offset
- * @width: image pixel width
- * @height: image pixel weight
- * @payload: image size in bytes (w x h x bpp)
- * @paddr: image frame buffer physical addresses
- * @dma_offset: DMA offset in bytes
- * @fmt: fimc color format pointer
- */
-struct fimc_frame {
- u32 f_width;
- u32 f_height;
- u32 o_width;
- u32 o_height;
- u32 offs_h;
- u32 offs_v;
- u32 width;
- u32 height;
- unsigned long payload[VIDEO_MAX_PLANES];
- struct fimc_addr paddr;
- struct fimc_dma_offset dma_offset;
- struct fimc_fmt *fmt;
- u8 alpha;
-};
-
-/**
- * struct fimc_m2m_device - v4l2 memory-to-memory device data
- * @vfd: the video device node for v4l2 m2m mode
- * @m2m_dev: v4l2 memory-to-memory device data
- * @ctx: hardware context data
- * @refcnt: the reference counter
- */
-struct fimc_m2m_device {
- struct video_device *vfd;
- struct v4l2_m2m_dev *m2m_dev;
- struct fimc_ctx *ctx;
- int refcnt;
-};
-
-#define FIMC_SD_PAD_SINK 0
-#define FIMC_SD_PAD_SOURCE 1
-#define FIMC_SD_PADS_NUM 2
-
-/**
- * struct fimc_vid_cap - camera capture device information
- * @ctx: hardware context data
- * @vfd: video device node for camera capture mode
- * @subdev: subdev exposing the FIMC processing block
- * @vd_pad: fimc video capture node pad
- * @sd_pads: fimc video processing block pads
- * @mf: media bus format at the FIMC camera input (and the scaler output) pad
- * @pending_buf_q: the pending buffer queue head
- * @active_buf_q: the queue head of buffers scheduled in hardware
- * @vbq: the capture am video buffer queue
- * @active_buf_cnt: number of video buffers scheduled in hardware
- * @buf_index: index for managing the output DMA buffers
- * @frame_count: the frame counter for statistics
- * @reqbufs_count: the number of buffers requested in REQBUFS ioctl
- * @input_index: input (camera sensor) index
- * @refcnt: driver's private reference counter
- * @input: capture input type, grp_id of the attached subdev
- * @user_subdev_api: true if subdevs are not configured by the host driver
- */
-struct fimc_vid_cap {
- struct fimc_ctx *ctx;
- struct vb2_alloc_ctx *alloc_ctx;
- struct video_device *vfd;
- struct v4l2_subdev subdev;
- struct media_pad vd_pad;
- struct v4l2_mbus_framefmt mf;
- struct media_pad sd_pads[FIMC_SD_PADS_NUM];
- struct list_head pending_buf_q;
- struct list_head active_buf_q;
- struct vb2_queue vbq;
- int active_buf_cnt;
- int buf_index;
- unsigned int frame_count;
- unsigned int reqbufs_count;
- int input_index;
- int refcnt;
- u32 input;
- bool user_subdev_api;
-};
-
-/**
- * struct fimc_pix_limit - image pixel size limits in various IP configurations
- *
- * @scaler_en_w: max input pixel width when the scaler is enabled
- * @scaler_dis_w: max input pixel width when the scaler is disabled
- * @in_rot_en_h: max input width with the input rotator is on
- * @in_rot_dis_w: max input width with the input rotator is off
- * @out_rot_en_w: max output width with the output rotator on
- * @out_rot_dis_w: max output width with the output rotator off
- */
-struct fimc_pix_limit {
- u16 scaler_en_w;
- u16 scaler_dis_w;
- u16 in_rot_en_h;
- u16 in_rot_dis_w;
- u16 out_rot_en_w;
- u16 out_rot_dis_w;
-};
-
-/**
- * struct fimc_variant - FIMC device variant information
- * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes
- * @has_inp_rot: set if has input rotator
- * @has_out_rot: set if has output rotator
- * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision
- * @has_mainscaler_ext: 1 if extended mainscaler ratios in CIEXTEN register
- * are present in this IP revision
- * @has_cam_if: set if this instance has a camera input interface
- * @pix_limit: pixel size constraints for the scaler
- * @min_inp_pixsize: minimum input pixel size
- * @min_out_pixsize: minimum output pixel size
- * @hor_offs_align: horizontal pixel offset aligment
- * @min_vsize_align: minimum vertical pixel size alignment
- * @out_buf_count: the number of buffers in output DMA sequence
- */
-struct fimc_variant {
- unsigned int pix_hoff:1;
- unsigned int has_inp_rot:1;
- unsigned int has_out_rot:1;
- unsigned int has_cistatus2:1;
- unsigned int has_mainscaler_ext:1;
- unsigned int has_cam_if:1;
- unsigned int has_alpha:1;
- struct fimc_pix_limit *pix_limit;
- u16 min_inp_pixsize;
- u16 min_out_pixsize;
- u16 hor_offs_align;
- u16 min_vsize_align;
- u16 out_buf_count;
-};
-
-/**
- * struct fimc_drvdata - per device type driver data
- * @variant: variant information for this device
- * @num_entities: number of fimc instances available in a SoC
- * @lclk_frequency: local bus clock frequency
- */
-struct fimc_drvdata {
- struct fimc_variant *variant[FIMC_MAX_DEVS];
- int num_entities;
- unsigned long lclk_frequency;
-};
-
-#define fimc_get_drvdata(_pdev) \
- ((struct fimc_drvdata *) platform_get_device_id(_pdev)->driver_data)
-
-struct fimc_ctx;
-
-/**
- * struct fimc_dev - abstraction for FIMC entity
- * @slock: the spinlock protecting this data structure
- * @lock: the mutex protecting this data structure
- * @pdev: pointer to the FIMC platform device
- * @pdata: pointer to the device platform data
- * @variant: the IP variant information
- * @id: FIMC device index (0..FIMC_MAX_DEVS)
- * @clock: clocks required for FIMC operation
- * @regs: the mapped hardware registers
- * @irq_queue: interrupt handler waitqueue
- * @v4l2_dev: root v4l2_device
- * @m2m: memory-to-memory V4L2 device information
- * @vid_cap: camera capture device information
- * @state: flags used to synchronize m2m and capture mode operation
- * @alloc_ctx: videobuf2 memory allocator context
- * @pipeline: fimc video capture pipeline data structure
- */
-struct fimc_dev {
- spinlock_t slock;
- struct mutex lock;
- struct platform_device *pdev;
- struct s5p_platform_fimc *pdata;
- struct fimc_variant *variant;
- u16 id;
- struct clk *clock[MAX_FIMC_CLOCKS];
- void __iomem *regs;
- wait_queue_head_t irq_queue;
- struct v4l2_device *v4l2_dev;
- struct fimc_m2m_device m2m;
- struct fimc_vid_cap vid_cap;
- unsigned long state;
- struct vb2_alloc_ctx *alloc_ctx;
- struct fimc_pipeline pipeline;
-};
-
-/**
- * struct fimc_ctrls - v4l2 controls structure
- * @handler: the control handler
- * @colorfx: image effect control
- * @colorfx_cbcr: Cb/Cr coefficients control
- * @rotate: image rotation control
- * @hflip: horizontal flip control
- * @vflip: vertical flip control
- * @alpha: RGB alpha control
- * @ready: true if @handler is initialized
- */
-struct fimc_ctrls {
- struct v4l2_ctrl_handler handler;
- struct {
- struct v4l2_ctrl *colorfx;
- struct v4l2_ctrl *colorfx_cbcr;
- };
- struct v4l2_ctrl *rotate;
- struct v4l2_ctrl *hflip;
- struct v4l2_ctrl *vflip;
- struct v4l2_ctrl *alpha;
- bool ready;
-};
-
-/**
- * fimc_ctx - the device context data
- * @s_frame: source frame properties
- * @d_frame: destination frame properties
- * @out_order_1p: output 1-plane YCBCR order
- * @out_order_2p: output 2-plane YCBCR order
- * @in_order_1p input 1-plane YCBCR order
- * @in_order_2p: input 2-plane YCBCR order
- * @in_path: input mode (DMA or camera)
- * @out_path: output mode (DMA or FIFO)
- * @scaler: image scaler properties
- * @effect: image effect
- * @rotation: image clockwise rotation in degrees
- * @hflip: indicates image horizontal flip if set
- * @vflip: indicates image vertical flip if set
- * @flags: additional flags for image conversion
- * @state: flags to keep track of user configuration
- * @fimc_dev: the FIMC device this context applies to
- * @m2m_ctx: memory-to-memory device context
- * @fh: v4l2 file handle
- * @ctrls: v4l2 controls structure
- */
-struct fimc_ctx {
- struct fimc_frame s_frame;
- struct fimc_frame d_frame;
- u32 out_order_1p;
- u32 out_order_2p;
- u32 in_order_1p;
- u32 in_order_2p;
- enum fimc_datapath in_path;
- enum fimc_datapath out_path;
- struct fimc_scaler scaler;
- struct fimc_effect effect;
- int rotation;
- unsigned int hflip:1;
- unsigned int vflip:1;
- u32 flags;
- u32 state;
- struct fimc_dev *fimc_dev;
- struct v4l2_m2m_ctx *m2m_ctx;
- struct v4l2_fh fh;
- struct fimc_ctrls ctrls;
-};
-
-#define fh_to_ctx(__fh) container_of(__fh, struct fimc_ctx, fh)
-
-static inline void set_frame_bounds(struct fimc_frame *f, u32 width, u32 height)
-{
- f->o_width = width;
- f->o_height = height;
- f->f_width = width;
- f->f_height = height;
-}
-
-static inline void set_frame_crop(struct fimc_frame *f,
- u32 left, u32 top, u32 width, u32 height)
-{
- f->offs_h = left;
- f->offs_v = top;
- f->width = width;
- f->height = height;
-}
-
-static inline u32 fimc_get_format_depth(struct fimc_fmt *ff)
-{
- u32 i, depth = 0;
-
- if (ff != NULL)
- for (i = 0; i < ff->colplanes; i++)
- depth += ff->depth[i];
- return depth;
-}
-
-static inline bool fimc_capture_active(struct fimc_dev *fimc)
-{
- unsigned long flags;
- bool ret;
-
- spin_lock_irqsave(&fimc->slock, flags);
- ret = !!(fimc->state & (1 << ST_CAPT_RUN) ||
- fimc->state & (1 << ST_CAPT_PEND));
- spin_unlock_irqrestore(&fimc->slock, flags);
- return ret;
-}
-
-static inline void fimc_ctx_state_set(u32 state, struct fimc_ctx *ctx)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ctx->fimc_dev->slock, flags);
- ctx->state |= state;
- spin_unlock_irqrestore(&ctx->fimc_dev->slock, flags);
-}
-
-static inline bool fimc_ctx_state_is_set(u32 mask, struct fimc_ctx *ctx)
-{
- unsigned long flags;
- bool ret;
-
- spin_lock_irqsave(&ctx->fimc_dev->slock, flags);
- ret = (ctx->state & mask) == mask;
- spin_unlock_irqrestore(&ctx->fimc_dev->slock, flags);
- return ret;
-}
-
-static inline int tiled_fmt(struct fimc_fmt *fmt)
-{
- return fmt->fourcc == V4L2_PIX_FMT_NV12MT;
-}
-
-/* Return the alpha component bit mask */
-static inline int fimc_get_alpha_mask(struct fimc_fmt *fmt)
-{
- switch (fmt->color) {
- case FIMC_FMT_RGB444: return 0x0f;
- case FIMC_FMT_RGB555: return 0x01;
- case FIMC_FMT_RGB888: return 0xff;
- default: return 0;
- };
-}
-
-static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
- enum v4l2_buf_type type)
-{
- struct fimc_frame *frame;
-
- if (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE == type) {
- if (fimc_ctx_state_is_set(FIMC_CTX_M2M, ctx))
- frame = &ctx->s_frame;
- else
- return ERR_PTR(-EINVAL);
- } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == type) {
- frame = &ctx->d_frame;
- } else {
- v4l2_err(ctx->fimc_dev->v4l2_dev,
- "Wrong buffer/video queue type (%d)\n", type);
- return ERR_PTR(-EINVAL);
- }
-
- return frame;
-}
-
-/* -----------------------------------------------------*/
-/* fimc-core.c */
-int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
- struct v4l2_fmtdesc *f);
-int fimc_ctrls_create(struct fimc_ctx *ctx);
-void fimc_ctrls_delete(struct fimc_ctx *ctx);
-void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active);
-void fimc_alpha_ctrl_update(struct fimc_ctx *ctx);
-int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f);
-void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
- struct v4l2_pix_format_mplane *pix);
-struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
- unsigned int mask, int index);
-struct fimc_fmt *fimc_get_format(unsigned int index);
-
-int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
- int dw, int dh, int rotation);
-int fimc_set_scaler_info(struct fimc_ctx *ctx);
-int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags);
-int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
- struct fimc_frame *frame, struct fimc_addr *paddr);
-void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f);
-void fimc_set_yuv_order(struct fimc_ctx *ctx);
-void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f);
-void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf);
-
-int fimc_register_m2m_device(struct fimc_dev *fimc,
- struct v4l2_device *v4l2_dev);
-void fimc_unregister_m2m_device(struct fimc_dev *fimc);
-int fimc_register_driver(void);
-void fimc_unregister_driver(void);
-
-/* -----------------------------------------------------*/
-/* fimc-m2m.c */
-void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state);
-
-/* -----------------------------------------------------*/
-/* fimc-capture.c */
-int fimc_initialize_capture_subdev(struct fimc_dev *fimc);
-void fimc_unregister_capture_subdev(struct fimc_dev *fimc);
-int fimc_capture_ctrls_create(struct fimc_dev *fimc);
-void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
- void *arg);
-int fimc_capture_suspend(struct fimc_dev *fimc);
-int fimc_capture_resume(struct fimc_dev *fimc);
-
-/*
- * Buffer list manipulation functions. Must be called with fimc.slock held.
- */
-
-/**
- * fimc_active_queue_add - add buffer to the capture active buffers queue
- * @buf: buffer to add to the active buffers list
- */
-static inline void fimc_active_queue_add(struct fimc_vid_cap *vid_cap,
- struct fimc_vid_buffer *buf)
-{
- list_add_tail(&buf->list, &vid_cap->active_buf_q);
- vid_cap->active_buf_cnt++;
-}
-
-/**
- * fimc_active_queue_pop - pop buffer from the capture active buffers queue
- *
- * The caller must assure the active_buf_q list is not empty.
- */
-static inline struct fimc_vid_buffer *fimc_active_queue_pop(
- struct fimc_vid_cap *vid_cap)
-{
- struct fimc_vid_buffer *buf;
- buf = list_entry(vid_cap->active_buf_q.next,
- struct fimc_vid_buffer, list);
- list_del(&buf->list);
- vid_cap->active_buf_cnt--;
- return buf;
-}
-
-/**
- * fimc_pending_queue_add - add buffer to the capture pending buffers queue
- * @buf: buffer to add to the pending buffers list
- */
-static inline void fimc_pending_queue_add(struct fimc_vid_cap *vid_cap,
- struct fimc_vid_buffer *buf)
-{
- list_add_tail(&buf->list, &vid_cap->pending_buf_q);
-}
-
-/**
- * fimc_pending_queue_pop - pop buffer from the capture pending buffers queue
- *
- * The caller must assure the pending_buf_q list is not empty.
- */
-static inline struct fimc_vid_buffer *fimc_pending_queue_pop(
- struct fimc_vid_cap *vid_cap)
-{
- struct fimc_vid_buffer *buf;
- buf = list_entry(vid_cap->pending_buf_q.next,
- struct fimc_vid_buffer, list);
- list_del(&buf->list);
- return buf;
-}
-
-#endif /* FIMC_CORE_H_ */
diff --git a/drivers/media/video/s5p-fimc/fimc-lite-reg.c b/drivers/media/video/s5p-fimc/fimc-lite-reg.c
deleted file mode 100644
index f996e94873f..00000000000
--- a/drivers/media/video/s5p-fimc/fimc-lite-reg.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Register interface file for EXYNOS FIMC-LITE (camera interface) driver
- *
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <media/s5p_fimc.h>
-
-#include "fimc-lite-reg.h"
-#include "fimc-lite.h"
-#include "fimc-core.h"
-
-#define FLITE_RESET_TIMEOUT 50 /* in ms */
-
-void flite_hw_reset(struct fimc_lite *dev)
-{
- unsigned long end = jiffies + msecs_to_jiffies(FLITE_RESET_TIMEOUT);
- u32 cfg;
-
- cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
- cfg |= FLITE_REG_CIGCTRL_SWRST_REQ;
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
-
- while (time_is_after_jiffies(end)) {
- cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
- if (cfg & FLITE_REG_CIGCTRL_SWRST_RDY)
- break;
- usleep_range(1000, 5000);
- }
-
- cfg |= FLITE_REG_CIGCTRL_SWRST;
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
-}
-
-void flite_hw_clear_pending_irq(struct fimc_lite *dev)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CISTATUS);
- cfg &= ~FLITE_REG_CISTATUS_IRQ_CAM;
- writel(cfg, dev->regs + FLITE_REG_CISTATUS);
-}
-
-u32 flite_hw_get_interrupt_source(struct fimc_lite *dev)
-{
- u32 intsrc = readl(dev->regs + FLITE_REG_CISTATUS);
- return intsrc & FLITE_REG_CISTATUS_IRQ_MASK;
-}
-
-void flite_hw_clear_last_capture_end(struct fimc_lite *dev)
-{
-
- u32 cfg = readl(dev->regs + FLITE_REG_CISTATUS2);
- cfg &= ~FLITE_REG_CISTATUS2_LASTCAPEND;
- writel(cfg, dev->regs + FLITE_REG_CISTATUS2);
-}
-
-void flite_hw_set_interrupt_mask(struct fimc_lite *dev)
-{
- u32 cfg, intsrc;
-
- /* Select interrupts to be enabled for each output mode */
- if (dev->out_path == FIMC_IO_DMA) {
- intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
- FLITE_REG_CIGCTRL_IRQ_LASTEN |
- FLITE_REG_CIGCTRL_IRQ_STARTEN;
- } else {
- /* An output to the FIMC-IS */
- intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
- FLITE_REG_CIGCTRL_IRQ_LASTEN;
- }
-
- cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
- cfg |= FLITE_REG_CIGCTRL_IRQ_DISABLE_MASK;
- cfg &= ~intsrc;
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
-}
-
-void flite_hw_capture_start(struct fimc_lite *dev)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CIIMGCPT);
- cfg |= FLITE_REG_CIIMGCPT_IMGCPTEN;
- writel(cfg, dev->regs + FLITE_REG_CIIMGCPT);
-}
-
-void flite_hw_capture_stop(struct fimc_lite *dev)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CIIMGCPT);
- cfg &= ~FLITE_REG_CIIMGCPT_IMGCPTEN;
- writel(cfg, dev->regs + FLITE_REG_CIIMGCPT);
-}
-
-/*
- * Test pattern (color bars) enable/disable. External sensor
- * pixel clock must be active for the test pattern to work.
- */
-void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
- if (on)
- cfg |= FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR;
- else
- cfg &= ~FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR;
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
-}
-
-static const u32 src_pixfmt_map[8][3] = {
- { V4L2_MBUS_FMT_YUYV8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCBYCR,
- FLITE_REG_CIGCTRL_YUV422_1P },
- { V4L2_MBUS_FMT_YVYU8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCRYCB,
- FLITE_REG_CIGCTRL_YUV422_1P },
- { V4L2_MBUS_FMT_UYVY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CBYCRY,
- FLITE_REG_CIGCTRL_YUV422_1P },
- { V4L2_MBUS_FMT_VYUY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CRYCBY,
- FLITE_REG_CIGCTRL_YUV422_1P },
- { V4L2_PIX_FMT_SGRBG8, 0, FLITE_REG_CIGCTRL_RAW8 },
- { V4L2_PIX_FMT_SGRBG10, 0, FLITE_REG_CIGCTRL_RAW10 },
- { V4L2_PIX_FMT_SGRBG12, 0, FLITE_REG_CIGCTRL_RAW12 },
- { V4L2_MBUS_FMT_JPEG_1X8, 0, FLITE_REG_CIGCTRL_USER(1) },
-};
-
-/* Set camera input pixel format and resolution */
-void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f)
-{
- enum v4l2_mbus_pixelcode pixelcode = dev->fmt->mbus_code;
- unsigned int i = ARRAY_SIZE(src_pixfmt_map);
- u32 cfg;
-
- while (i-- >= 0) {
- if (src_pixfmt_map[i][0] == pixelcode)
- break;
- }
-
- if (i == 0 && src_pixfmt_map[i][0] != pixelcode) {
- v4l2_err(dev->vfd,
- "Unsupported pixel code, falling back to %#08x\n",
- src_pixfmt_map[i][0]);
- }
-
- cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
- cfg &= ~FLITE_REG_CIGCTRL_FMT_MASK;
- cfg |= src_pixfmt_map[i][2];
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
-
- cfg = readl(dev->regs + FLITE_REG_CISRCSIZE);
- cfg &= ~(FLITE_REG_CISRCSIZE_ORDER422_MASK |
- FLITE_REG_CISRCSIZE_SIZE_CAM_MASK);
- cfg |= (f->f_width << 16) | f->f_height;
- cfg |= src_pixfmt_map[i][1];
- writel(cfg, dev->regs + FLITE_REG_CISRCSIZE);
-}
-
-/* Set the camera host input window offsets (cropping) */
-void flite_hw_set_window_offset(struct fimc_lite *dev, struct flite_frame *f)
-{
- u32 hoff2, voff2;
- u32 cfg;
-
- cfg = readl(dev->regs + FLITE_REG_CIWDOFST);
- cfg &= ~FLITE_REG_CIWDOFST_OFST_MASK;
- cfg |= (f->rect.left << 16) | f->rect.top;
- cfg |= FLITE_REG_CIWDOFST_WINOFSEN;
- writel(cfg, dev->regs + FLITE_REG_CIWDOFST);
-
- hoff2 = f->f_width - f->rect.width - f->rect.left;
- voff2 = f->f_height - f->rect.height - f->rect.top;
-
- cfg = (hoff2 << 16) | voff2;
- writel(cfg, dev->regs + FLITE_REG_CIWDOFST2);
-}
-
-/* Select camera port (A, B) */
-static void flite_hw_set_camera_port(struct fimc_lite *dev, int id)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CIGENERAL);
- if (id == 0)
- cfg &= ~FLITE_REG_CIGENERAL_CAM_B;
- else
- cfg |= FLITE_REG_CIGENERAL_CAM_B;
- writel(cfg, dev->regs + FLITE_REG_CIGENERAL);
-}
-
-/* Select serial or parallel bus, camera port (A,B) and set signals polarity */
-void flite_hw_set_camera_bus(struct fimc_lite *dev,
- struct s5p_fimc_isp_info *s_info)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
- unsigned int flags = s_info->flags;
-
- if (s_info->bus_type != FIMC_MIPI_CSI2) {
- cfg &= ~(FLITE_REG_CIGCTRL_SELCAM_MIPI |
- FLITE_REG_CIGCTRL_INVPOLPCLK |
- FLITE_REG_CIGCTRL_INVPOLVSYNC |
- FLITE_REG_CIGCTRL_INVPOLHREF);
-
- if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
- cfg |= FLITE_REG_CIGCTRL_INVPOLPCLK;
-
- if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
- cfg |= FLITE_REG_CIGCTRL_INVPOLVSYNC;
-
- if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
- cfg |= FLITE_REG_CIGCTRL_INVPOLHREF;
- } else {
- cfg |= FLITE_REG_CIGCTRL_SELCAM_MIPI;
- }
-
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
-
- flite_hw_set_camera_port(dev, s_info->mux_id);
-}
-
-static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
-{
- static const u32 pixcode[4][2] = {
- { V4L2_MBUS_FMT_YUYV8_2X8, FLITE_REG_CIODMAFMT_YCBYCR },
- { V4L2_MBUS_FMT_YVYU8_2X8, FLITE_REG_CIODMAFMT_YCRYCB },
- { V4L2_MBUS_FMT_UYVY8_2X8, FLITE_REG_CIODMAFMT_CBYCRY },
- { V4L2_MBUS_FMT_VYUY8_2X8, FLITE_REG_CIODMAFMT_CRYCBY },
- };
- u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT);
- unsigned int i = ARRAY_SIZE(pixcode);
-
- while (i-- >= 0)
- if (pixcode[i][0] == dev->fmt->mbus_code)
- break;
- cfg &= ~FLITE_REG_CIODMAFMT_YCBCR_ORDER_MASK;
- writel(cfg | pixcode[i][1], dev->regs + FLITE_REG_CIODMAFMT);
-}
-
-void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f)
-{
- u32 cfg;
-
- /* Maximum output pixel size */
- cfg = readl(dev->regs + FLITE_REG_CIOCAN);
- cfg &= ~FLITE_REG_CIOCAN_MASK;
- cfg = (f->f_height << 16) | f->f_width;
- writel(cfg, dev->regs + FLITE_REG_CIOCAN);
-
- /* DMA offsets */
- cfg = readl(dev->regs + FLITE_REG_CIOOFF);
- cfg &= ~FLITE_REG_CIOOFF_MASK;
- cfg |= (f->rect.top << 16) | f->rect.left;
- writel(cfg, dev->regs + FLITE_REG_CIOOFF);
-}
-
-/* Enable/disable output DMA, set output pixel size and offsets (composition) */
-void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
- bool enable)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
-
- if (!enable) {
- cfg |= FLITE_REG_CIGCTRL_ODMA_DISABLE;
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
- return;
- }
-
- cfg &= ~FLITE_REG_CIGCTRL_ODMA_DISABLE;
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
-
- flite_hw_set_out_order(dev, f);
- flite_hw_set_dma_window(dev, f);
-}
-
-void flite_hw_dump_regs(struct fimc_lite *dev, const char *label)
-{
- struct {
- u32 offset;
- const char * const name;
- } registers[] = {
- { 0x00, "CISRCSIZE" },
- { 0x04, "CIGCTRL" },
- { 0x08, "CIIMGCPT" },
- { 0x0c, "CICPTSEQ" },
- { 0x10, "CIWDOFST" },
- { 0x14, "CIWDOFST2" },
- { 0x18, "CIODMAFMT" },
- { 0x20, "CIOCAN" },
- { 0x24, "CIOOFF" },
- { 0x30, "CIOSA" },
- { 0x40, "CISTATUS" },
- { 0x44, "CISTATUS2" },
- { 0xf0, "CITHOLD" },
- { 0xfc, "CIGENERAL" },
- };
- u32 i;
-
- pr_info("--- %s ---\n", label);
- for (i = 0; i < ARRAY_SIZE(registers); i++) {
- u32 cfg = readl(dev->regs + registers[i].offset);
- pr_info("%s: %s:\t0x%08x\n", __func__, registers[i].name, cfg);
- }
-}
diff --git a/drivers/media/video/s5p-fimc/fimc-lite-reg.h b/drivers/media/video/s5p-fimc/fimc-lite-reg.h
deleted file mode 100644
index adb9e9e6f3c..00000000000
--- a/drivers/media/video/s5p-fimc/fimc-lite-reg.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef FIMC_LITE_REG_H_
-#define FIMC_LITE_REG_H_
-
-#include "fimc-lite.h"
-
-/* Camera Source size */
-#define FLITE_REG_CISRCSIZE 0x00
-#define FLITE_REG_CISRCSIZE_ORDER422_IN_YCBYCR (0 << 14)
-#define FLITE_REG_CISRCSIZE_ORDER422_IN_YCRYCB (1 << 14)
-#define FLITE_REG_CISRCSIZE_ORDER422_IN_CBYCRY (2 << 14)
-#define FLITE_REG_CISRCSIZE_ORDER422_IN_CRYCBY (3 << 14)
-#define FLITE_REG_CISRCSIZE_ORDER422_MASK (0x3 << 14)
-#define FLITE_REG_CISRCSIZE_SIZE_CAM_MASK (0x3fff << 16 | 0x3fff)
-
-/* Global control */
-#define FLITE_REG_CIGCTRL 0x04
-#define FLITE_REG_CIGCTRL_YUV422_1P (0x1e << 24)
-#define FLITE_REG_CIGCTRL_RAW8 (0x2a << 24)
-#define FLITE_REG_CIGCTRL_RAW10 (0x2b << 24)
-#define FLITE_REG_CIGCTRL_RAW12 (0x2c << 24)
-#define FLITE_REG_CIGCTRL_RAW14 (0x2d << 24)
-/* User defined formats. x = 0...15 */
-#define FLITE_REG_CIGCTRL_USER(x) ((0x30 + x - 1) << 24)
-#define FLITE_REG_CIGCTRL_FMT_MASK (0x3f << 24)
-#define FLITE_REG_CIGCTRL_SHADOWMASK_DISABLE (1 << 21)
-#define FLITE_REG_CIGCTRL_ODMA_DISABLE (1 << 20)
-#define FLITE_REG_CIGCTRL_SWRST_REQ (1 << 19)
-#define FLITE_REG_CIGCTRL_SWRST_RDY (1 << 18)
-#define FLITE_REG_CIGCTRL_SWRST (1 << 17)
-#define FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR (1 << 15)
-#define FLITE_REG_CIGCTRL_INVPOLPCLK (1 << 14)
-#define FLITE_REG_CIGCTRL_INVPOLVSYNC (1 << 13)
-#define FLITE_REG_CIGCTRL_INVPOLHREF (1 << 12)
-/* Interrupts mask bits (1 disables an interrupt) */
-#define FLITE_REG_CIGCTRL_IRQ_LASTEN (1 << 8)
-#define FLITE_REG_CIGCTRL_IRQ_ENDEN (1 << 7)
-#define FLITE_REG_CIGCTRL_IRQ_STARTEN (1 << 6)
-#define FLITE_REG_CIGCTRL_IRQ_OVFEN (1 << 5)
-#define FLITE_REG_CIGCTRL_IRQ_DISABLE_MASK (0xf << 5)
-#define FLITE_REG_CIGCTRL_SELCAM_MIPI (1 << 3)
-
-/* Image Capture Enable */
-#define FLITE_REG_CIIMGCPT 0x08
-#define FLITE_REG_CIIMGCPT_IMGCPTEN (1 << 31)
-#define FLITE_REG_CIIMGCPT_CPT_FREN (1 << 25)
-#define FLITE_REG_CIIMGCPT_CPT_MOD_FRCNT (1 << 18)
-#define FLITE_REG_CIIMGCPT_CPT_MOD_FREN (0 << 18)
-
-/* Capture Sequence */
-#define FLITE_REG_CICPTSEQ 0x0c
-
-/* Camera Window Offset */
-#define FLITE_REG_CIWDOFST 0x10
-#define FLITE_REG_CIWDOFST_WINOFSEN (1 << 31)
-#define FLITE_REG_CIWDOFST_CLROVIY (1 << 31)
-#define FLITE_REG_CIWDOFST_CLROVFICB (1 << 15)
-#define FLITE_REG_CIWDOFST_CLROVFICR (1 << 14)
-#define FLITE_REG_CIWDOFST_OFST_MASK ((0x1fff << 16) | 0x1fff)
-
-/* Camera Window Offset2 */
-#define FLITE_REG_CIWDOFST2 0x14
-
-/* Camera Output DMA Format */
-#define FLITE_REG_CIODMAFMT 0x18
-#define FLITE_REG_CIODMAFMT_RAW_CON (1 << 15)
-#define FLITE_REG_CIODMAFMT_PACK12 (1 << 14)
-#define FLITE_REG_CIODMAFMT_CRYCBY (0 << 4)
-#define FLITE_REG_CIODMAFMT_CBYCRY (1 << 4)
-#define FLITE_REG_CIODMAFMT_YCRYCB (2 << 4)
-#define FLITE_REG_CIODMAFMT_YCBYCR (3 << 4)
-#define FLITE_REG_CIODMAFMT_YCBCR_ORDER_MASK (0x3 << 4)
-
-/* Camera Output Canvas */
-#define FLITE_REG_CIOCAN 0x20
-#define FLITE_REG_CIOCAN_MASK ((0x3fff << 16) | 0x3fff)
-
-/* Camera Output DMA Offset */
-#define FLITE_REG_CIOOFF 0x24
-#define FLITE_REG_CIOOFF_MASK ((0x3fff << 16) | 0x3fff)
-
-/* Camera Output DMA Start Address */
-#define FLITE_REG_CIOSA 0x30
-
-/* Camera Status */
-#define FLITE_REG_CISTATUS 0x40
-#define FLITE_REG_CISTATUS_MIPI_VVALID (1 << 22)
-#define FLITE_REG_CISTATUS_MIPI_HVALID (1 << 21)
-#define FLITE_REG_CISTATUS_MIPI_DVALID (1 << 20)
-#define FLITE_REG_CISTATUS_ITU_VSYNC (1 << 14)
-#define FLITE_REG_CISTATUS_ITU_HREFF (1 << 13)
-#define FLITE_REG_CISTATUS_OVFIY (1 << 10)
-#define FLITE_REG_CISTATUS_OVFICB (1 << 9)
-#define FLITE_REG_CISTATUS_OVFICR (1 << 8)
-#define FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW (1 << 7)
-#define FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND (1 << 6)
-#define FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART (1 << 5)
-#define FLITE_REG_CISTATUS_IRQ_SRC_FRMEND (1 << 4)
-#define FLITE_REG_CISTATUS_IRQ_CAM (1 << 0)
-#define FLITE_REG_CISTATUS_IRQ_MASK (0xf << 4)
-
-/* Camera Status2 */
-#define FLITE_REG_CISTATUS2 0x44
-#define FLITE_REG_CISTATUS2_LASTCAPEND (1 << 1)
-#define FLITE_REG_CISTATUS2_FRMEND (1 << 0)
-
-/* Qos Threshold */
-#define FLITE_REG_CITHOLD 0xf0
-#define FLITE_REG_CITHOLD_W_QOS_EN (1 << 30)
-
-/* Camera General Purpose */
-#define FLITE_REG_CIGENERAL 0xfc
-/* b0: 1 - camera B, 0 - camera A */
-#define FLITE_REG_CIGENERAL_CAM_B (1 << 0)
-
-/* ----------------------------------------------------------------------------
- * Function declarations
- */
-void flite_hw_reset(struct fimc_lite *dev);
-void flite_hw_clear_pending_irq(struct fimc_lite *dev);
-u32 flite_hw_get_interrupt_source(struct fimc_lite *dev);
-void flite_hw_clear_last_capture_end(struct fimc_lite *dev);
-void flite_hw_set_interrupt_mask(struct fimc_lite *dev);
-void flite_hw_capture_start(struct fimc_lite *dev);
-void flite_hw_capture_stop(struct fimc_lite *dev);
-void flite_hw_set_camera_bus(struct fimc_lite *dev,
- struct s5p_fimc_isp_info *s_info);
-void flite_hw_set_camera_polarity(struct fimc_lite *dev,
- struct s5p_fimc_isp_info *cam);
-void flite_hw_set_window_offset(struct fimc_lite *dev, struct flite_frame *f);
-void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f);
-
-void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
- bool enable);
-void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f);
-void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on);
-void flite_hw_dump_regs(struct fimc_lite *dev, const char *label);
-
-static inline void flite_hw_set_output_addr(struct fimc_lite *dev, u32 paddr)
-{
- writel(paddr, dev->regs + FLITE_REG_CIOSA);
-}
-#endif /* FIMC_LITE_REG_H */
diff --git a/drivers/media/video/s5p-fimc/fimc-lite.c b/drivers/media/video/s5p-fimc/fimc-lite.c
deleted file mode 100644
index c5b57e805b6..00000000000
--- a/drivers/media/video/s5p-fimc/fimc-lite.c
+++ /dev/null
@@ -1,1606 +0,0 @@
-/*
- * Samsung EXYNOS FIMC-LITE (camera host interface) driver
-*
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
-
-#include <linux/bug.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "fimc-mdevice.h"
-#include "fimc-core.h"
-#include "fimc-lite-reg.h"
-
-static int debug;
-module_param(debug, int, 0644);
-
-static const struct fimc_fmt fimc_lite_formats[] = {
- {
- .name = "YUV 4:2:2 packed, YCbYCr",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = { 16 },
- .color = FIMC_FMT_YCBYCR422,
- .memplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
- }, {
- .name = "YUV 4:2:2 packed, CbYCrY",
- .fourcc = V4L2_PIX_FMT_UYVY,
- .depth = { 16 },
- .color = FIMC_FMT_CBYCRY422,
- .memplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
- }, {
- .name = "YUV 4:2:2 packed, CrYCbY",
- .fourcc = V4L2_PIX_FMT_VYUY,
- .depth = { 16 },
- .color = FIMC_FMT_CRYCBY422,
- .memplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8,
- }, {
- .name = "YUV 4:2:2 packed, YCrYCb",
- .fourcc = V4L2_PIX_FMT_YVYU,
- .depth = { 16 },
- .color = FIMC_FMT_YCRYCB422,
- .memplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8,
- }, {
- .name = "RAW8 (GRBG)",
- .fourcc = V4L2_PIX_FMT_SGRBG8,
- .depth = { 8 },
- .color = FIMC_FMT_RAW8,
- .memplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_SGRBG8_1X8,
- }, {
- .name = "RAW10 (GRBG)",
- .fourcc = V4L2_PIX_FMT_SGRBG10,
- .depth = { 10 },
- .color = FIMC_FMT_RAW10,
- .memplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_SGRBG10_1X10,
- }, {
- .name = "RAW12 (GRBG)",
- .fourcc = V4L2_PIX_FMT_SGRBG12,
- .depth = { 12 },
- .color = FIMC_FMT_RAW12,
- .memplanes = 1,
- .mbus_code = V4L2_MBUS_FMT_SGRBG12_1X12,
- },
-};
-
-/**
- * fimc_lite_find_format - lookup fimc color format by fourcc or media bus code
- * @pixelformat: fourcc to match, ignored if null
- * @mbus_code: media bus code to match, ignored if null
- * @index: index to the fimc_lite_formats array, ignored if negative
- */
-static const struct fimc_fmt *fimc_lite_find_format(const u32 *pixelformat,
- const u32 *mbus_code, int index)
-{
- const struct fimc_fmt *fmt, *def_fmt = NULL;
- unsigned int i;
- int id = 0;
-
- if (index >= (int)ARRAY_SIZE(fimc_lite_formats))
- return NULL;
-
- for (i = 0; i < ARRAY_SIZE(fimc_lite_formats); ++i) {
- fmt = &fimc_lite_formats[i];
- if (pixelformat && fmt->fourcc == *pixelformat)
- return fmt;
- if (mbus_code && fmt->mbus_code == *mbus_code)
- return fmt;
- if (index == id)
- def_fmt = fmt;
- id++;
- }
- return def_fmt;
-}
-
-static int fimc_lite_hw_init(struct fimc_lite *fimc)
-{
- struct fimc_pipeline *pipeline = &fimc->pipeline;
- struct fimc_sensor_info *sensor;
- unsigned long flags;
-
- if (pipeline->subdevs[IDX_SENSOR] == NULL)
- return -ENXIO;
-
- if (fimc->fmt == NULL)
- return -EINVAL;
-
- sensor = v4l2_get_subdev_hostdata(pipeline->subdevs[IDX_SENSOR]);
- spin_lock_irqsave(&fimc->slock, flags);
-
- flite_hw_set_camera_bus(fimc, sensor->pdata);
- flite_hw_set_source_format(fimc, &fimc->inp_frame);
- flite_hw_set_window_offset(fimc, &fimc->inp_frame);
- flite_hw_set_output_dma(fimc, &fimc->out_frame, true);
- flite_hw_set_interrupt_mask(fimc);
- flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
-
- if (debug > 0)
- flite_hw_dump_regs(fimc, __func__);
-
- spin_unlock_irqrestore(&fimc->slock, flags);
- return 0;
-}
-
-/*
- * Reinitialize the driver so it is ready to start the streaming again.
- * Set fimc->state to indicate stream off and the hardware shut down state.
- * If not suspending (@suspend is false), return any buffers to videobuf2.
- * Otherwise put any owned buffers onto the pending buffers queue, so they
- * can be re-spun when the device is being resumed. Also perform FIMC
- * software reset and disable streaming on the whole pipeline if required.
- */
-static int fimc_lite_reinit(struct fimc_lite *fimc, bool suspend)
-{
- struct flite_buffer *buf;
- unsigned long flags;
- bool streaming;
-
- spin_lock_irqsave(&fimc->slock, flags);
- streaming = fimc->state & (1 << ST_SENSOR_STREAM);
-
- fimc->state &= ~(1 << ST_FLITE_RUN | 1 << ST_FLITE_OFF |
- 1 << ST_FLITE_STREAM | 1 << ST_SENSOR_STREAM);
- if (suspend)
- fimc->state |= (1 << ST_FLITE_SUSPENDED);
- else
- fimc->state &= ~(1 << ST_FLITE_PENDING |
- 1 << ST_FLITE_SUSPENDED);
-
- /* Release unused buffers */
- while (!suspend && !list_empty(&fimc->pending_buf_q)) {
- buf = fimc_lite_pending_queue_pop(fimc);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- }
- /* If suspending put unused buffers onto pending queue */
- while (!list_empty(&fimc->active_buf_q)) {
- buf = fimc_lite_active_queue_pop(fimc);
- if (suspend)
- fimc_lite_pending_queue_add(fimc, buf);
- else
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- }
-
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- flite_hw_reset(fimc);
-
- if (!streaming)
- return 0;
-
- return fimc_pipeline_s_stream(&fimc->pipeline, 0);
-}
-
-static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend)
-{
- unsigned long flags;
-
- if (!fimc_lite_active(fimc))
- return 0;
-
- spin_lock_irqsave(&fimc->slock, flags);
- set_bit(ST_FLITE_OFF, &fimc->state);
- flite_hw_capture_stop(fimc);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- wait_event_timeout(fimc->irq_queue,
- !test_bit(ST_FLITE_OFF, &fimc->state),
- (2*HZ/10)); /* 200 ms */
-
- return fimc_lite_reinit(fimc, suspend);
-}
-
-/* Must be called with fimc.slock spinlock held. */
-static void fimc_lite_config_update(struct fimc_lite *fimc)
-{
- flite_hw_set_window_offset(fimc, &fimc->inp_frame);
- flite_hw_set_dma_window(fimc, &fimc->out_frame);
- flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
- clear_bit(ST_FLITE_CONFIG, &fimc->state);
-}
-
-static irqreturn_t flite_irq_handler(int irq, void *priv)
-{
- struct fimc_lite *fimc = priv;
- struct flite_buffer *vbuf;
- unsigned long flags;
- struct timeval *tv;
- struct timespec ts;
- u32 intsrc;
-
- spin_lock_irqsave(&fimc->slock, flags);
-
- intsrc = flite_hw_get_interrupt_source(fimc);
- flite_hw_clear_pending_irq(fimc);
-
- if (test_and_clear_bit(ST_FLITE_OFF, &fimc->state)) {
- wake_up(&fimc->irq_queue);
- goto done;
- }
-
- if (intsrc & FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW) {
- clear_bit(ST_FLITE_RUN, &fimc->state);
- fimc->events.data_overflow++;
- }
-
- if (intsrc & FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND) {
- flite_hw_clear_last_capture_end(fimc);
- clear_bit(ST_FLITE_STREAM, &fimc->state);
- wake_up(&fimc->irq_queue);
- }
-
- if (fimc->out_path != FIMC_IO_DMA)
- goto done;
-
- if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART) &&
- test_bit(ST_FLITE_RUN, &fimc->state) &&
- !list_empty(&fimc->active_buf_q) &&
- !list_empty(&fimc->pending_buf_q)) {
- vbuf = fimc_lite_active_queue_pop(fimc);
- ktime_get_ts(&ts);
- tv = &vbuf->vb.v4l2_buf.timestamp;
- tv->tv_sec = ts.tv_sec;
- tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
- vbuf->vb.v4l2_buf.sequence = fimc->frame_count++;
- vb2_buffer_done(&vbuf->vb, VB2_BUF_STATE_DONE);
-
- vbuf = fimc_lite_pending_queue_pop(fimc);
- flite_hw_set_output_addr(fimc, vbuf->paddr);
- fimc_lite_active_queue_add(fimc, vbuf);
- }
-
- if (test_bit(ST_FLITE_CONFIG, &fimc->state))
- fimc_lite_config_update(fimc);
-
- if (list_empty(&fimc->pending_buf_q)) {
- flite_hw_capture_stop(fimc);
- clear_bit(ST_FLITE_STREAM, &fimc->state);
- }
-done:
- set_bit(ST_FLITE_RUN, &fimc->state);
- spin_unlock_irqrestore(&fimc->slock, flags);
- return IRQ_HANDLED;
-}
-
-static int start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct fimc_lite *fimc = q->drv_priv;
- int ret;
-
- fimc->frame_count = 0;
-
- ret = fimc_lite_hw_init(fimc);
- if (ret) {
- fimc_lite_reinit(fimc, false);
- return ret;
- }
-
- set_bit(ST_FLITE_PENDING, &fimc->state);
-
- if (!list_empty(&fimc->active_buf_q) &&
- !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
- flite_hw_capture_start(fimc);
-
- if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
- fimc_pipeline_s_stream(&fimc->pipeline, 1);
- }
- if (debug > 0)
- flite_hw_dump_regs(fimc, __func__);
-
- return 0;
-}
-
-static int stop_streaming(struct vb2_queue *q)
-{
- struct fimc_lite *fimc = q->drv_priv;
-
- if (!fimc_lite_active(fimc))
- return -EINVAL;
-
- return fimc_lite_stop_capture(fimc, false);
-}
-
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
- unsigned int *num_buffers, unsigned int *num_planes,
- unsigned int sizes[], void *allocators[])
-{
- const struct v4l2_pix_format_mplane *pixm = NULL;
- struct fimc_lite *fimc = vq->drv_priv;
- struct flite_frame *frame = &fimc->out_frame;
- const struct fimc_fmt *fmt = fimc->fmt;
- unsigned long wh;
- int i;
-
- if (pfmt) {
- pixm = &pfmt->fmt.pix_mp;
- fmt = fimc_lite_find_format(&pixm->pixelformat, NULL, -1);
- wh = pixm->width * pixm->height;
- } else {
- wh = frame->f_width * frame->f_height;
- }
-
- if (fmt == NULL)
- return -EINVAL;
-
- *num_planes = fmt->memplanes;
-
- for (i = 0; i < fmt->memplanes; i++) {
- unsigned int size = (wh * fmt->depth[i]) / 8;
- if (pixm)
- sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
- else
- sizes[i] = size;
- allocators[i] = fimc->alloc_ctx;
- }
-
- return 0;
-}
-
-static int buffer_prepare(struct vb2_buffer *vb)
-{
- struct vb2_queue *vq = vb->vb2_queue;
- struct fimc_lite *fimc = vq->drv_priv;
- int i;
-
- if (fimc->fmt == NULL)
- return -EINVAL;
-
- for (i = 0; i < fimc->fmt->memplanes; i++) {
- unsigned long size = fimc->payload[i];
-
- if (vb2_plane_size(vb, i) < size) {
- v4l2_err(fimc->vfd,
- "User buffer too small (%ld < %ld)\n",
- vb2_plane_size(vb, i), size);
- return -EINVAL;
- }
- vb2_set_plane_payload(vb, i, size);
- }
-
- return 0;
-}
-
-static void buffer_queue(struct vb2_buffer *vb)
-{
- struct flite_buffer *buf
- = container_of(vb, struct flite_buffer, vb);
- struct fimc_lite *fimc = vb2_get_drv_priv(vb->vb2_queue);
- unsigned long flags;
-
- spin_lock_irqsave(&fimc->slock, flags);
- buf->paddr = vb2_dma_contig_plane_dma_addr(vb, 0);
-
- if (!test_bit(ST_FLITE_SUSPENDED, &fimc->state) &&
- !test_bit(ST_FLITE_STREAM, &fimc->state) &&
- list_empty(&fimc->active_buf_q)) {
- flite_hw_set_output_addr(fimc, buf->paddr);
- fimc_lite_active_queue_add(fimc, buf);
- } else {
- fimc_lite_pending_queue_add(fimc, buf);
- }
-
- if (vb2_is_streaming(&fimc->vb_queue) &&
- !list_empty(&fimc->pending_buf_q) &&
- !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
- flite_hw_capture_start(fimc);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
- fimc_pipeline_s_stream(&fimc->pipeline, 1);
- return;
- }
- spin_unlock_irqrestore(&fimc->slock, flags);
-}
-
-static void fimc_lock(struct vb2_queue *vq)
-{
- struct fimc_lite *fimc = vb2_get_drv_priv(vq);
- mutex_lock(&fimc->lock);
-}
-
-static void fimc_unlock(struct vb2_queue *vq)
-{
- struct fimc_lite *fimc = vb2_get_drv_priv(vq);
- mutex_unlock(&fimc->lock);
-}
-
-static const struct vb2_ops fimc_lite_qops = {
- .queue_setup = queue_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .wait_prepare = fimc_unlock,
- .wait_finish = fimc_lock,
- .start_streaming = start_streaming,
- .stop_streaming = stop_streaming,
-};
-
-static void fimc_lite_clear_event_counters(struct fimc_lite *fimc)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&fimc->slock, flags);
- memset(&fimc->events, 0, sizeof(fimc->events));
- spin_unlock_irqrestore(&fimc->slock, flags);
-}
-
-static int fimc_lite_open(struct file *file)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- int ret;
-
- if (mutex_lock_interruptible(&fimc->lock))
- return -ERESTARTSYS;
-
- set_bit(ST_FLITE_IN_USE, &fimc->state);
- ret = pm_runtime_get_sync(&fimc->pdev->dev);
- if (ret < 0)
- goto done;
-
- ret = v4l2_fh_open(file);
- if (ret < 0)
- goto done;
-
- if (++fimc->ref_count == 1 && fimc->out_path == FIMC_IO_DMA) {
- ret = fimc_pipeline_initialize(&fimc->pipeline,
- &fimc->vfd->entity, true);
- if (ret < 0) {
- pm_runtime_put_sync(&fimc->pdev->dev);
- fimc->ref_count--;
- v4l2_fh_release(file);
- clear_bit(ST_FLITE_IN_USE, &fimc->state);
- }
-
- fimc_lite_clear_event_counters(fimc);
- }
-done:
- mutex_unlock(&fimc->lock);
- return ret;
-}
-
-static int fimc_lite_close(struct file *file)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- int ret;
-
- if (mutex_lock_interruptible(&fimc->lock))
- return -ERESTARTSYS;
-
- if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) {
- clear_bit(ST_FLITE_IN_USE, &fimc->state);
- fimc_lite_stop_capture(fimc, false);
- fimc_pipeline_shutdown(&fimc->pipeline);
- clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
- }
-
- pm_runtime_put(&fimc->pdev->dev);
-
- if (fimc->ref_count == 0)
- vb2_queue_release(&fimc->vb_queue);
-
- ret = v4l2_fh_release(file);
-
- mutex_unlock(&fimc->lock);
- return ret;
-}
-
-static unsigned int fimc_lite_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- int ret;
-
- if (mutex_lock_interruptible(&fimc->lock))
- return POLL_ERR;
-
- ret = vb2_poll(&fimc->vb_queue, file, wait);
- mutex_unlock(&fimc->lock);
-
- return ret;
-}
-
-static int fimc_lite_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- int ret;
-
- if (mutex_lock_interruptible(&fimc->lock))
- return -ERESTARTSYS;
-
- ret = vb2_mmap(&fimc->vb_queue, vma);
- mutex_unlock(&fimc->lock);
-
- return ret;
-}
-
-static const struct v4l2_file_operations fimc_lite_fops = {
- .owner = THIS_MODULE,
- .open = fimc_lite_open,
- .release = fimc_lite_close,
- .poll = fimc_lite_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = fimc_lite_mmap,
-};
-
-/*
- * Format and crop negotiation helpers
- */
-
-static const struct fimc_fmt *fimc_lite_try_format(struct fimc_lite *fimc,
- u32 *width, u32 *height,
- u32 *code, u32 *fourcc, int pad)
-{
- struct flite_variant *variant = fimc->variant;
- const struct fimc_fmt *fmt;
-
- fmt = fimc_lite_find_format(fourcc, code, 0);
- if (WARN_ON(!fmt))
- return NULL;
-
- if (code)
- *code = fmt->mbus_code;
- if (fourcc)
- *fourcc = fmt->fourcc;
-
- if (pad == FLITE_SD_PAD_SINK) {
- v4l_bound_align_image(width, 8, variant->max_width,
- ffs(variant->out_width_align) - 1,
- height, 0, variant->max_height, 0, 0);
- } else {
- v4l_bound_align_image(width, 8, fimc->inp_frame.rect.width,
- ffs(variant->out_width_align) - 1,
- height, 0, fimc->inp_frame.rect.height,
- 0, 0);
- }
-
- v4l2_dbg(1, debug, &fimc->subdev, "code: 0x%x, %dx%d\n",
- code ? *code : 0, *width, *height);
-
- return fmt;
-}
-
-static void fimc_lite_try_crop(struct fimc_lite *fimc, struct v4l2_rect *r)
-{
- struct flite_frame *frame = &fimc->inp_frame;
-
- v4l_bound_align_image(&r->width, 0, frame->f_width, 0,
- &r->height, 0, frame->f_height, 0, 0);
-
- /* Adjust left/top if cropping rectangle got out of bounds */
- r->left = clamp_t(u32, r->left, 0, frame->f_width - r->width);
- r->left = round_down(r->left, fimc->variant->win_hor_offs_align);
- r->top = clamp_t(u32, r->top, 0, frame->f_height - r->height);
-
- v4l2_dbg(1, debug, &fimc->subdev, "(%d,%d)/%dx%d, sink fmt: %dx%d",
- r->left, r->top, r->width, r->height,
- frame->f_width, frame->f_height);
-}
-
-static void fimc_lite_try_compose(struct fimc_lite *fimc, struct v4l2_rect *r)
-{
- struct flite_frame *frame = &fimc->out_frame;
- struct v4l2_rect *crop_rect = &fimc->inp_frame.rect;
-
- /* Scaling is not supported so we enforce compose rectangle size
- same as size of the sink crop rectangle. */
- r->width = crop_rect->width;
- r->height = crop_rect->height;
-
- /* Adjust left/top if the composing rectangle got out of bounds */
- r->left = clamp_t(u32, r->left, 0, frame->f_width - r->width);
- r->left = round_down(r->left, fimc->variant->out_hor_offs_align);
- r->top = clamp_t(u32, r->top, 0, fimc->out_frame.f_height - r->height);
-
- v4l2_dbg(1, debug, &fimc->subdev, "(%d,%d)/%dx%d, source fmt: %dx%d",
- r->left, r->top, r->width, r->height,
- frame->f_width, frame->f_height);
-}
-
-/*
- * Video node ioctl operations
- */
-static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- strlcpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver));
- cap->bus_info[0] = 0;
- cap->card[0] = 0;
- cap->capabilities = V4L2_CAP_STREAMING;
- return 0;
-}
-
-static int fimc_lite_enum_fmt_mplane(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- const struct fimc_fmt *fmt;
-
- if (f->index >= ARRAY_SIZE(fimc_lite_formats))
- return -EINVAL;
-
- fmt = &fimc_lite_formats[f->index];
- strlcpy(f->description, fmt->name, sizeof(f->description));
- f->pixelformat = fmt->fourcc;
-
- return 0;
-}
-
-static int fimc_lite_g_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
- struct v4l2_plane_pix_format *plane_fmt = &pixm->plane_fmt[0];
- struct flite_frame *frame = &fimc->out_frame;
- const struct fimc_fmt *fmt = fimc->fmt;
-
- plane_fmt->bytesperline = (frame->f_width * fmt->depth[0]) / 8;
- plane_fmt->sizeimage = plane_fmt->bytesperline * frame->f_height;
-
- pixm->num_planes = fmt->memplanes;
- pixm->pixelformat = fmt->fourcc;
- pixm->width = frame->f_width;
- pixm->height = frame->f_height;
- pixm->field = V4L2_FIELD_NONE;
- pixm->colorspace = V4L2_COLORSPACE_JPEG;
- return 0;
-}
-
-static int fimc_lite_try_fmt(struct fimc_lite *fimc,
- struct v4l2_pix_format_mplane *pixm,
- const struct fimc_fmt **ffmt)
-{
- struct flite_variant *variant = fimc->variant;
- u32 bpl = pixm->plane_fmt[0].bytesperline;
- const struct fimc_fmt *fmt;
-
- fmt = fimc_lite_find_format(&pixm->pixelformat, NULL, 0);
- if (WARN_ON(fmt == NULL))
- return -EINVAL;
- if (ffmt)
- *ffmt = fmt;
- v4l_bound_align_image(&pixm->width, 8, variant->max_width,
- ffs(variant->out_width_align) - 1,
- &pixm->height, 0, variant->max_height, 0, 0);
-
- if ((bpl == 0 || ((bpl * 8) / fmt->depth[0]) < pixm->width))
- pixm->plane_fmt[0].bytesperline = (pixm->width *
- fmt->depth[0]) / 8;
-
- if (pixm->plane_fmt[0].sizeimage == 0)
- pixm->plane_fmt[0].sizeimage = (pixm->width * pixm->height *
- fmt->depth[0]) / 8;
- pixm->num_planes = fmt->memplanes;
- pixm->pixelformat = fmt->fourcc;
- pixm->colorspace = V4L2_COLORSPACE_JPEG;
- pixm->field = V4L2_FIELD_NONE;
- return 0;
-}
-
-static int fimc_lite_try_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_lite *fimc = video_drvdata(file);
-
- return fimc_lite_try_fmt(fimc, &f->fmt.pix_mp, NULL);
-}
-
-static int fimc_lite_s_fmt_mplane(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
- struct fimc_lite *fimc = video_drvdata(file);
- struct flite_frame *frame = &fimc->out_frame;
- const struct fimc_fmt *fmt = NULL;
- int ret;
-
- if (vb2_is_busy(&fimc->vb_queue))
- return -EBUSY;
-
- ret = fimc_lite_try_fmt(fimc, &f->fmt.pix_mp, &fmt);
- if (ret < 0)
- return ret;
-
- fimc->fmt = fmt;
- fimc->payload[0] = max((pixm->width * pixm->height * fmt->depth[0]) / 8,
- pixm->plane_fmt[0].sizeimage);
- frame->f_width = pixm->width;
- frame->f_height = pixm->height;
-
- return 0;
-}
-
-static int fimc_pipeline_validate(struct fimc_lite *fimc)
-{
- struct v4l2_subdev *sd = &fimc->subdev;
- struct v4l2_subdev_format sink_fmt, src_fmt;
- struct media_pad *pad;
- int ret;
-
- while (1) {
- /* Retrieve format at the sink pad */
- pad = &sd->entity.pads[0];
- if (!(pad->flags & MEDIA_PAD_FL_SINK))
- break;
- /* Don't call FIMC subdev operation to avoid nested locking */
- if (sd == &fimc->subdev) {
- struct flite_frame *ff = &fimc->out_frame;
- sink_fmt.format.width = ff->f_width;
- sink_fmt.format.height = ff->f_height;
- sink_fmt.format.code = fimc->fmt->mbus_code;
- } else {
- sink_fmt.pad = pad->index;
- sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL,
- &sink_fmt);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return -EPIPE;
- }
- /* Retrieve format at the source pad */
- pad = media_entity_remote_source(pad);
- if (pad == NULL ||
- media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
- break;
-
- sd = media_entity_to_v4l2_subdev(pad->entity);
- src_fmt.pad = pad->index;
- src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return -EPIPE;
-
- if (src_fmt.format.width != sink_fmt.format.width ||
- src_fmt.format.height != sink_fmt.format.height ||
- src_fmt.format.code != sink_fmt.format.code)
- return -EPIPE;
- }
- return 0;
-}
-
-static int fimc_lite_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- struct v4l2_subdev *sensor = fimc->pipeline.subdevs[IDX_SENSOR];
- struct fimc_pipeline *p = &fimc->pipeline;
- int ret;
-
- if (fimc_lite_active(fimc))
- return -EBUSY;
-
- ret = media_entity_pipeline_start(&sensor->entity, p->m_pipeline);
- if (ret < 0)
- return ret;
-
- ret = fimc_pipeline_validate(fimc);
- if (ret) {
- media_entity_pipeline_stop(&sensor->entity);
- return ret;
- }
-
- return vb2_streamon(&fimc->vb_queue, type);
-}
-
-static int fimc_lite_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
- int ret;
-
- ret = vb2_streamoff(&fimc->vb_queue, type);
- if (ret == 0)
- media_entity_pipeline_stop(&sd->entity);
- return ret;
-}
-
-static int fimc_lite_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- int ret;
-
- reqbufs->count = max_t(u32, FLITE_REQ_BUFS_MIN, reqbufs->count);
- ret = vb2_reqbufs(&fimc->vb_queue, reqbufs);
- if (!ret < 0)
- fimc->reqbufs_count = reqbufs->count;
-
- return ret;
-}
-
-static int fimc_lite_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct fimc_lite *fimc = video_drvdata(file);
-
- return vb2_querybuf(&fimc->vb_queue, buf);
-}
-
-static int fimc_lite_qbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct fimc_lite *fimc = video_drvdata(file);
-
- return vb2_qbuf(&fimc->vb_queue, buf);
-}
-
-static int fimc_lite_dqbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct fimc_lite *fimc = video_drvdata(file);
-
- return vb2_dqbuf(&fimc->vb_queue, buf, file->f_flags & O_NONBLOCK);
-}
-
-static int fimc_lite_create_bufs(struct file *file, void *priv,
- struct v4l2_create_buffers *create)
-{
- struct fimc_lite *fimc = video_drvdata(file);
-
- return vb2_create_bufs(&fimc->vb_queue, create);
-}
-
-static int fimc_lite_prepare_buf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct fimc_lite *fimc = video_drvdata(file);
-
- return vb2_prepare_buf(&fimc->vb_queue, b);
-}
-
-/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
-static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
-{
- if (a->left < b->left || a->top < b->top)
- return 0;
- if (a->left + a->width > b->left + b->width)
- return 0;
- if (a->top + a->height > b->top + b->height)
- return 0;
-
- return 1;
-}
-
-static int fimc_lite_g_selection(struct file *file, void *fh,
- struct v4l2_selection *sel)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- struct flite_frame *f = &fimc->out_frame;
-
- if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return -EINVAL;
-
- switch (sel->target) {
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- case V4L2_SEL_TGT_COMPOSE_DEFAULT:
- sel->r.left = 0;
- sel->r.top = 0;
- sel->r.width = f->f_width;
- sel->r.height = f->f_height;
- return 0;
-
- case V4L2_SEL_TGT_COMPOSE:
- sel->r = f->rect;
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int fimc_lite_s_selection(struct file *file, void *fh,
- struct v4l2_selection *sel)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- struct flite_frame *f = &fimc->out_frame;
- struct v4l2_rect rect = sel->r;
- unsigned long flags;
-
- if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
- sel->target != V4L2_SEL_TGT_COMPOSE)
- return -EINVAL;
-
- fimc_lite_try_compose(fimc, &rect);
-
- if ((sel->flags & V4L2_SEL_FLAG_LE) &&
- !enclosed_rectangle(&rect, &sel->r))
- return -ERANGE;
-
- if ((sel->flags & V4L2_SEL_FLAG_GE) &&
- !enclosed_rectangle(&sel->r, &rect))
- return -ERANGE;
-
- sel->r = rect;
- spin_lock_irqsave(&fimc->slock, flags);
- f->rect = rect;
- set_bit(ST_FLITE_CONFIG, &fimc->state);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- return 0;
-}
-
-static const struct v4l2_ioctl_ops fimc_lite_ioctl_ops = {
- .vidioc_querycap = fimc_vidioc_querycap_capture,
- .vidioc_enum_fmt_vid_cap_mplane = fimc_lite_enum_fmt_mplane,
- .vidioc_try_fmt_vid_cap_mplane = fimc_lite_try_fmt_mplane,
- .vidioc_s_fmt_vid_cap_mplane = fimc_lite_s_fmt_mplane,
- .vidioc_g_fmt_vid_cap_mplane = fimc_lite_g_fmt_mplane,
- .vidioc_g_selection = fimc_lite_g_selection,
- .vidioc_s_selection = fimc_lite_s_selection,
- .vidioc_reqbufs = fimc_lite_reqbufs,
- .vidioc_querybuf = fimc_lite_querybuf,
- .vidioc_prepare_buf = fimc_lite_prepare_buf,
- .vidioc_create_bufs = fimc_lite_create_bufs,
- .vidioc_qbuf = fimc_lite_qbuf,
- .vidioc_dqbuf = fimc_lite_dqbuf,
- .vidioc_streamon = fimc_lite_streamon,
- .vidioc_streamoff = fimc_lite_streamoff,
-};
-
-/* Capture subdev media entity operations */
-static int fimc_lite_link_setup(struct media_entity *entity,
- const struct media_pad *local,
- const struct media_pad *remote, u32 flags)
-{
- struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
- unsigned int remote_ent_type = media_entity_type(remote->entity);
-
- if (WARN_ON(fimc == NULL))
- return 0;
-
- v4l2_dbg(1, debug, sd, "%s: %s --> %s, flags: 0x%x. source_id: 0x%x",
- __func__, local->entity->name, remote->entity->name,
- flags, fimc->source_subdev_grp_id);
-
- switch (local->index) {
- case FIMC_SD_PAD_SINK:
- if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV)
- return -EINVAL;
-
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (fimc->source_subdev_grp_id != 0)
- return -EBUSY;
- fimc->source_subdev_grp_id = sd->grp_id;
- return 0;
- }
-
- fimc->source_subdev_grp_id = 0;
- break;
-
- case FIMC_SD_PAD_SOURCE:
- if (!(flags & MEDIA_LNK_FL_ENABLED)) {
- fimc->out_path = FIMC_IO_NONE;
- return 0;
- }
- if (remote_ent_type == MEDIA_ENT_T_V4L2_SUBDEV)
- fimc->out_path = FIMC_IO_ISP;
- else
- fimc->out_path = FIMC_IO_DMA;
- break;
-
- default:
- v4l2_err(sd, "Invalid pad index\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const struct media_entity_operations fimc_lite_subdev_media_ops = {
- .link_setup = fimc_lite_link_setup,
-};
-
-static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- const struct fimc_fmt *fmt;
-
- fmt = fimc_lite_find_format(NULL, NULL, code->index);
- if (!fmt)
- return -EINVAL;
- code->code = fmt->mbus_code;
- return 0;
-}
-
-static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *mf = &fmt->format;
- struct flite_frame *f = &fimc->out_frame;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(fh, fmt->pad);
- fmt->format = *mf;
- return 0;
- }
- mf->colorspace = V4L2_COLORSPACE_JPEG;
-
- mutex_lock(&fimc->lock);
- mf->code = fimc->fmt->mbus_code;
-
- if (fmt->pad == FLITE_SD_PAD_SINK) {
- /* full camera input frame size */
- mf->width = f->f_width;
- mf->height = f->f_height;
- } else {
- /* crop size */
- mf->width = f->rect.width;
- mf->height = f->rect.height;
- }
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *mf = &fmt->format;
- struct flite_frame *sink = &fimc->inp_frame;
- const struct fimc_fmt *ffmt;
-
- v4l2_dbg(1, debug, sd, "pad%d: code: 0x%x, %dx%d",
- fmt->pad, mf->code, mf->width, mf->height);
-
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- mutex_lock(&fimc->lock);
-
- if ((fimc->out_path == FIMC_IO_ISP && sd->entity.stream_count > 0) ||
- (fimc->out_path == FIMC_IO_DMA && vb2_is_busy(&fimc->vb_queue))) {
- mutex_unlock(&fimc->lock);
- return -EBUSY;
- }
-
- ffmt = fimc_lite_try_format(fimc, &mf->width, &mf->height,
- &mf->code, NULL, fmt->pad);
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(fh, fmt->pad);
- *mf = fmt->format;
- mutex_unlock(&fimc->lock);
- return 0;
- }
-
- if (fmt->pad == FLITE_SD_PAD_SINK) {
- sink->f_width = mf->width;
- sink->f_height = mf->height;
- fimc->fmt = ffmt;
- /* Set sink crop rectangle */
- sink->rect.width = mf->width;
- sink->rect.height = mf->height;
- sink->rect.left = 0;
- sink->rect.top = 0;
- /* Reset source crop rectangle */
- fimc->out_frame.rect = sink->rect;
- } else {
- /* Allow changing format only on sink pad */
- mf->code = fimc->fmt->mbus_code;
- mf->width = sink->rect.width;
- mf->height = sink->rect.height;
- }
-
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
- struct flite_frame *f = &fimc->inp_frame;
-
- if ((sel->target != V4L2_SEL_TGT_CROP &&
- sel->target != V4L2_SEL_TGT_CROP_BOUNDS) ||
- sel->pad != FLITE_SD_PAD_SINK)
- return -EINVAL;
-
- if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
- sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad);
- return 0;
- }
-
- mutex_lock(&fimc->lock);
- if (sel->target == V4L2_SEL_TGT_CROP) {
- sel->r = f->rect;
- } else {
- sel->r.left = 0;
- sel->r.top = 0;
- sel->r.width = f->f_width;
- sel->r.height = f->f_height;
- }
- mutex_unlock(&fimc->lock);
-
- v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %d, f_h: %d",
- __func__, f->rect.left, f->rect.top, f->rect.width,
- f->rect.height, f->f_width, f->f_height);
-
- return 0;
-}
-
-static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
- struct flite_frame *f = &fimc->inp_frame;
- int ret = 0;
-
- if (sel->target != V4L2_SEL_TGT_CROP || sel->pad != FLITE_SD_PAD_SINK)
- return -EINVAL;
-
- mutex_lock(&fimc->lock);
- fimc_lite_try_crop(fimc, &sel->r);
-
- if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
- *v4l2_subdev_get_try_crop(fh, sel->pad) = sel->r;
- } else {
- unsigned long flags;
- spin_lock_irqsave(&fimc->slock, flags);
- f->rect = sel->r;
- /* Same crop rectangle on the source pad */
- fimc->out_frame.rect = sel->r;
- set_bit(ST_FLITE_CONFIG, &fimc->state);
- spin_unlock_irqrestore(&fimc->slock, flags);
- }
- mutex_unlock(&fimc->lock);
-
- v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %d, f_h: %d",
- __func__, f->rect.left, f->rect.top, f->rect.width,
- f->rect.height, f->f_width, f->f_height);
-
- return ret;
-}
-
-static int fimc_lite_subdev_s_stream(struct v4l2_subdev *sd, int on)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
-
- if (fimc->out_path == FIMC_IO_DMA)
- return -ENOIOCTLCMD;
-
- /* TODO: */
-
- return 0;
-}
-
-static int fimc_lite_subdev_s_power(struct v4l2_subdev *sd, int on)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
-
- if (fimc->out_path == FIMC_IO_DMA)
- return -ENOIOCTLCMD;
-
- /* TODO: */
-
- return 0;
-}
-
-static int fimc_lite_log_status(struct v4l2_subdev *sd)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
-
- flite_hw_dump_regs(fimc, __func__);
- return 0;
-}
-
-static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
- struct vb2_queue *q = &fimc->vb_queue;
- struct video_device *vfd;
- int ret;
-
- fimc->fmt = &fimc_lite_formats[0];
- fimc->out_path = FIMC_IO_DMA;
-
- vfd = video_device_alloc();
- if (!vfd) {
- v4l2_err(sd->v4l2_dev, "Failed to allocate video device\n");
- return -ENOMEM;
- }
-
- snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture",
- fimc->index);
-
- vfd->fops = &fimc_lite_fops;
- vfd->ioctl_ops = &fimc_lite_ioctl_ops;
- vfd->v4l2_dev = sd->v4l2_dev;
- vfd->minor = -1;
- vfd->release = video_device_release;
- vfd->lock = &fimc->lock;
- fimc->vfd = vfd;
- fimc->ref_count = 0;
- fimc->reqbufs_count = 0;
-
- INIT_LIST_HEAD(&fimc->pending_buf_q);
- INIT_LIST_HEAD(&fimc->active_buf_q);
-
- memset(q, 0, sizeof(*q));
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- q->io_modes = VB2_MMAP | VB2_USERPTR;
- q->ops = &fimc_lite_qops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->buf_struct_size = sizeof(struct flite_buffer);
- q->drv_priv = fimc;
-
- vb2_queue_init(q);
-
- fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
- ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0);
- if (ret)
- goto err;
-
- video_set_drvdata(vfd, fimc);
-
- ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
- if (ret)
- goto err_vd;
-
- v4l2_info(sd->v4l2_dev, "Registered %s as /dev/%s\n",
- vfd->name, video_device_node_name(vfd));
- return 0;
-
- err_vd:
- media_entity_cleanup(&vfd->entity);
- err:
- video_device_release(vfd);
- return ret;
-}
-
-static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
-
- if (fimc == NULL)
- return;
-
- if (fimc->vfd) {
- video_unregister_device(fimc->vfd);
- media_entity_cleanup(&fimc->vfd->entity);
- fimc->vfd = NULL;
- }
-}
-
-static const struct v4l2_subdev_internal_ops fimc_lite_subdev_internal_ops = {
- .registered = fimc_lite_subdev_registered,
- .unregistered = fimc_lite_subdev_unregistered,
-};
-
-static const struct v4l2_subdev_pad_ops fimc_lite_subdev_pad_ops = {
- .enum_mbus_code = fimc_lite_subdev_enum_mbus_code,
- .get_selection = fimc_lite_subdev_get_selection,
- .set_selection = fimc_lite_subdev_set_selection,
- .get_fmt = fimc_lite_subdev_get_fmt,
- .set_fmt = fimc_lite_subdev_set_fmt,
-};
-
-static const struct v4l2_subdev_video_ops fimc_lite_subdev_video_ops = {
- .s_stream = fimc_lite_subdev_s_stream,
-};
-
-static const struct v4l2_subdev_core_ops fimc_lite_core_ops = {
- .s_power = fimc_lite_subdev_s_power,
- .log_status = fimc_lite_log_status,
-};
-
-static struct v4l2_subdev_ops fimc_lite_subdev_ops = {
- .core = &fimc_lite_core_ops,
- .video = &fimc_lite_subdev_video_ops,
- .pad = &fimc_lite_subdev_pad_ops,
-};
-
-static int fimc_lite_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct fimc_lite *fimc = container_of(ctrl->handler, struct fimc_lite,
- ctrl_handler);
- set_bit(ST_FLITE_CONFIG, &fimc->state);
- return 0;
-}
-
-static const struct v4l2_ctrl_ops fimc_lite_ctrl_ops = {
- .s_ctrl = fimc_lite_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config fimc_lite_ctrl = {
- .ops = &fimc_lite_ctrl_ops,
- .id = V4L2_CTRL_CLASS_USER | 0x1001,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Test Pattern 640x480",
-};
-
-static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
-{
- struct v4l2_ctrl_handler *handler = &fimc->ctrl_handler;
- struct v4l2_subdev *sd = &fimc->subdev;
- int ret;
-
- v4l2_subdev_init(sd, &fimc_lite_subdev_ops);
- sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
- snprintf(sd->name, sizeof(sd->name), "FIMC-LITE.%d", fimc->index);
-
- fimc->subdev_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- fimc->subdev_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
- fimc->subdev_pads, 0);
- if (ret)
- return ret;
-
- v4l2_ctrl_handler_init(handler, 1);
- fimc->test_pattern = v4l2_ctrl_new_custom(handler, &fimc_lite_ctrl,
- NULL);
- if (handler->error) {
- media_entity_cleanup(&sd->entity);
- return handler->error;
- }
-
- sd->ctrl_handler = handler;
- sd->internal_ops = &fimc_lite_subdev_internal_ops;
- sd->entity.ops = &fimc_lite_subdev_media_ops;
- v4l2_set_subdevdata(sd, fimc);
-
- return 0;
-}
-
-static void fimc_lite_unregister_capture_subdev(struct fimc_lite *fimc)
-{
- struct v4l2_subdev *sd = &fimc->subdev;
-
- v4l2_device_unregister_subdev(sd);
- media_entity_cleanup(&sd->entity);
- v4l2_ctrl_handler_free(&fimc->ctrl_handler);
- v4l2_set_subdevdata(sd, NULL);
-}
-
-static void fimc_lite_clk_put(struct fimc_lite *fimc)
-{
- if (IS_ERR_OR_NULL(fimc->clock))
- return;
-
- clk_unprepare(fimc->clock);
- clk_put(fimc->clock);
- fimc->clock = NULL;
-}
-
-static int fimc_lite_clk_get(struct fimc_lite *fimc)
-{
- int ret;
-
- fimc->clock = clk_get(&fimc->pdev->dev, FLITE_CLK_NAME);
- if (IS_ERR(fimc->clock))
- return PTR_ERR(fimc->clock);
-
- ret = clk_prepare(fimc->clock);
- if (ret < 0) {
- clk_put(fimc->clock);
- fimc->clock = NULL;
- }
- return ret;
-}
-
-static int __devinit fimc_lite_probe(struct platform_device *pdev)
-{
- struct flite_drvdata *drv_data = fimc_lite_get_drvdata(pdev);
- struct fimc_lite *fimc;
- struct resource *res;
- int ret;
-
- fimc = devm_kzalloc(&pdev->dev, sizeof(*fimc), GFP_KERNEL);
- if (!fimc)
- return -ENOMEM;
-
- fimc->index = pdev->id;
- fimc->variant = drv_data->variant[fimc->index];
- fimc->pdev = pdev;
-
- init_waitqueue_head(&fimc->irq_queue);
- spin_lock_init(&fimc->slock);
- mutex_init(&fimc->lock);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- fimc->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (fimc->regs == NULL) {
- dev_err(&pdev->dev, "Failed to obtain io memory\n");
- return -ENOENT;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "Failed to get IRQ resource\n");
- return -ENXIO;
- }
-
- ret = fimc_lite_clk_get(fimc);
- if (ret)
- return ret;
-
- ret = devm_request_irq(&pdev->dev, res->start, flite_irq_handler,
- 0, dev_name(&pdev->dev), fimc);
- if (ret) {
- dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret);
- goto err_clk;
- }
-
- /* The video node will be created within the subdev's registered() op */
- ret = fimc_lite_create_capture_subdev(fimc);
- if (ret)
- goto err_clk;
-
- platform_set_drvdata(pdev, fimc);
- pm_runtime_enable(&pdev->dev);
- ret = pm_runtime_get_sync(&pdev->dev);
- if (ret < 0)
- goto err_sd;
-
- fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
- if (IS_ERR(fimc->alloc_ctx)) {
- ret = PTR_ERR(fimc->alloc_ctx);
- goto err_pm;
- }
- pm_runtime_put(&pdev->dev);
-
- dev_dbg(&pdev->dev, "FIMC-LITE.%d registered successfully\n",
- fimc->index);
- return 0;
-err_pm:
- pm_runtime_put(&pdev->dev);
-err_sd:
- fimc_lite_unregister_capture_subdev(fimc);
-err_clk:
- fimc_lite_clk_put(fimc);
- return ret;
-}
-
-static int fimc_lite_runtime_resume(struct device *dev)
-{
- struct fimc_lite *fimc = dev_get_drvdata(dev);
-
- clk_enable(fimc->clock);
- return 0;
-}
-
-static int fimc_lite_runtime_suspend(struct device *dev)
-{
- struct fimc_lite *fimc = dev_get_drvdata(dev);
-
- clk_disable(fimc->clock);
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int fimc_lite_resume(struct device *dev)
-{
- struct fimc_lite *fimc = dev_get_drvdata(dev);
- struct flite_buffer *buf;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&fimc->slock, flags);
- if (!test_and_clear_bit(ST_LPM, &fimc->state) ||
- !test_bit(ST_FLITE_IN_USE, &fimc->state)) {
- spin_unlock_irqrestore(&fimc->slock, flags);
- return 0;
- }
- flite_hw_reset(fimc);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (!test_and_clear_bit(ST_FLITE_SUSPENDED, &fimc->state))
- return 0;
-
- INIT_LIST_HEAD(&fimc->active_buf_q);
- fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd->entity, false);
- fimc_lite_hw_init(fimc);
- clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
-
- for (i = 0; i < fimc->reqbufs_count; i++) {
- if (list_empty(&fimc->pending_buf_q))
- break;
- buf = fimc_lite_pending_queue_pop(fimc);
- buffer_queue(&buf->vb);
- }
- return 0;
-}
-
-static int fimc_lite_suspend(struct device *dev)
-{
- struct fimc_lite *fimc = dev_get_drvdata(dev);
- bool suspend = test_bit(ST_FLITE_IN_USE, &fimc->state);
- int ret;
-
- if (test_and_set_bit(ST_LPM, &fimc->state))
- return 0;
-
- ret = fimc_lite_stop_capture(fimc, suspend);
- if (ret < 0 || !fimc_lite_active(fimc))
- return ret;
-
- return fimc_pipeline_shutdown(&fimc->pipeline);
-}
-#endif /* CONFIG_PM_SLEEP */
-
-static int __devexit fimc_lite_remove(struct platform_device *pdev)
-{
- struct fimc_lite *fimc = platform_get_drvdata(pdev);
- struct device *dev = &pdev->dev;
-
- pm_runtime_disable(dev);
- pm_runtime_set_suspended(dev);
- fimc_lite_unregister_capture_subdev(fimc);
- vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
- fimc_lite_clk_put(fimc);
-
- dev_info(dev, "Driver unloaded\n");
- return 0;
-}
-
-static struct flite_variant fimc_lite0_variant_exynos4 = {
- .max_width = 8192,
- .max_height = 8192,
- .out_width_align = 8,
- .win_hor_offs_align = 2,
- .out_hor_offs_align = 8,
-};
-
-/* EXYNOS4212, EXYNOS4412 */
-static struct flite_drvdata fimc_lite_drvdata_exynos4 = {
- .variant = {
- [0] = &fimc_lite0_variant_exynos4,
- [1] = &fimc_lite0_variant_exynos4,
- },
-};
-
-static struct platform_device_id fimc_lite_driver_ids[] = {
- {
- .name = "exynos-fimc-lite",
- .driver_data = (unsigned long)&fimc_lite_drvdata_exynos4,
- },
- { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(platform, fimc_lite_driver_ids);
-
-static const struct dev_pm_ops fimc_lite_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(fimc_lite_suspend, fimc_lite_resume)
- SET_RUNTIME_PM_OPS(fimc_lite_runtime_suspend, fimc_lite_runtime_resume,
- NULL)
-};
-
-static struct platform_driver fimc_lite_driver = {
- .probe = fimc_lite_probe,
- .remove = __devexit_p(fimc_lite_remove),
- .id_table = fimc_lite_driver_ids,
- .driver = {
- .name = FIMC_LITE_DRV_NAME,
- .owner = THIS_MODULE,
- .pm = &fimc_lite_pm_ops,
- }
-};
-module_platform_driver(fimc_lite_driver);
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" FIMC_LITE_DRV_NAME);
diff --git a/drivers/media/video/s5p-fimc/fimc-lite.h b/drivers/media/video/s5p-fimc/fimc-lite.h
deleted file mode 100644
index 44424eee81d..00000000000
--- a/drivers/media/video/s5p-fimc/fimc-lite.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef FIMC_LITE_H_
-#define FIMC_LITE_H_
-
-#include <asm/sizes.h>
-#include <linux/io.h>
-#include <linux/irqreturn.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-
-#include <media/media-entity.h>
-#include <media/videobuf2-core.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-mediabus.h>
-#include <media/s5p_fimc.h>
-
-#include "fimc-core.h"
-
-#define FIMC_LITE_DRV_NAME "exynos-fimc-lite"
-#define FLITE_CLK_NAME "flite"
-#define FIMC_LITE_MAX_DEVS 2
-#define FLITE_REQ_BUFS_MIN 2
-
-/* Bit index definitions for struct fimc_lite::state */
-enum {
- ST_FLITE_LPM,
- ST_FLITE_PENDING,
- ST_FLITE_RUN,
- ST_FLITE_STREAM,
- ST_FLITE_SUSPENDED,
- ST_FLITE_OFF,
- ST_FLITE_IN_USE,
- ST_FLITE_CONFIG,
- ST_SENSOR_STREAM,
-};
-
-#define FLITE_SD_PAD_SINK 0
-#define FLITE_SD_PAD_SOURCE 1
-#define FLITE_SD_PADS_NUM 2
-
-struct flite_variant {
- unsigned short max_width;
- unsigned short max_height;
- unsigned short out_width_align;
- unsigned short win_hor_offs_align;
- unsigned short out_hor_offs_align;
-};
-
-struct flite_drvdata {
- struct flite_variant *variant[FIMC_LITE_MAX_DEVS];
-};
-
-#define fimc_lite_get_drvdata(_pdev) \
- ((struct flite_drvdata *) platform_get_device_id(_pdev)->driver_data)
-
-struct fimc_lite_events {
- unsigned int data_overflow;
-};
-
-#define FLITE_MAX_PLANES 1
-
-/**
- * struct flite_frame - source/target frame properties
- * @f_width: full pixel width
- * @f_height: full pixel height
- * @rect: crop/composition rectangle
- */
-struct flite_frame {
- u16 f_width;
- u16 f_height;
- struct v4l2_rect rect;
-};
-
-/**
- * struct flite_buffer - video buffer structure
- * @vb: vb2 buffer
- * @list: list head for the buffers queue
- * @paddr: precalculated physical address
- */
-struct flite_buffer {
- struct vb2_buffer vb;
- struct list_head list;
- dma_addr_t paddr;
-};
-
-/**
- * struct fimc_lite - fimc lite structure
- * @pdev: pointer to FIMC-LITE platform device
- * @variant: variant information for this IP
- * @v4l2_dev: pointer to top the level v4l2_device
- * @vfd: video device node
- * @fh: v4l2 file handle
- * @alloc_ctx: videobuf2 memory allocator context
- * @subdev: FIMC-LITE subdev
- * @vd_pad: media (sink) pad for the capture video node
- * @subdev_pads: the subdev media pads
- * @ctrl_handler: v4l2 control handler
- * @test_pattern: test pattern controls
- * @index: FIMC-LITE platform device index
- * @pipeline: video capture pipeline data structure
- * @slock: spinlock protecting this data structure and the hw registers
- * @lock: mutex serializing video device and the subdev operations
- * @clock: FIMC-LITE gate clock
- * @regs: memory mapped io registers
- * @irq_queue: interrupt handler waitqueue
- * @fmt: pointer to color format description structure
- * @payload: image size in bytes (w x h x bpp)
- * @inp_frame: camera input frame structure
- * @out_frame: DMA output frame structure
- * @out_path: output data path (DMA or FIFO)
- * @source_subdev_grp_id: source subdev group id
- * @state: driver state flags
- * @pending_buf_q: pending buffers queue head
- * @active_buf_q: the queue head of buffers scheduled in hardware
- * @vb_queue: vb2 buffers queue
- * @active_buf_count: number of video buffers scheduled in hardware
- * @frame_count: the captured frames counter
- * @reqbufs_count: the number of buffers requested with REQBUFS ioctl
- * @ref_count: driver's private reference counter
- */
-struct fimc_lite {
- struct platform_device *pdev;
- struct flite_variant *variant;
- struct v4l2_device *v4l2_dev;
- struct video_device *vfd;
- struct v4l2_fh fh;
- struct vb2_alloc_ctx *alloc_ctx;
- struct v4l2_subdev subdev;
- struct media_pad vd_pad;
- struct media_pad subdev_pads[FLITE_SD_PADS_NUM];
- struct v4l2_ctrl_handler ctrl_handler;
- struct v4l2_ctrl *test_pattern;
- u32 index;
- struct fimc_pipeline pipeline;
-
- struct mutex lock;
- spinlock_t slock;
-
- struct clk *clock;
- void __iomem *regs;
- wait_queue_head_t irq_queue;
-
- const struct fimc_fmt *fmt;
- unsigned long payload[FLITE_MAX_PLANES];
- struct flite_frame inp_frame;
- struct flite_frame out_frame;
- enum fimc_datapath out_path;
- unsigned int source_subdev_grp_id;
-
- unsigned long state;
- struct list_head pending_buf_q;
- struct list_head active_buf_q;
- struct vb2_queue vb_queue;
- unsigned int frame_count;
- unsigned int reqbufs_count;
- int ref_count;
-
- struct fimc_lite_events events;
-};
-
-static inline bool fimc_lite_active(struct fimc_lite *fimc)
-{
- unsigned long flags;
- bool ret;
-
- spin_lock_irqsave(&fimc->slock, flags);
- ret = fimc->state & (1 << ST_FLITE_RUN) ||
- fimc->state & (1 << ST_FLITE_PENDING);
- spin_unlock_irqrestore(&fimc->slock, flags);
- return ret;
-}
-
-static inline void fimc_lite_active_queue_add(struct fimc_lite *dev,
- struct flite_buffer *buf)
-{
- list_add_tail(&buf->list, &dev->active_buf_q);
-}
-
-static inline struct flite_buffer *fimc_lite_active_queue_pop(
- struct fimc_lite *dev)
-{
- struct flite_buffer *buf = list_entry(dev->active_buf_q.next,
- struct flite_buffer, list);
- list_del(&buf->list);
- return buf;
-}
-
-static inline void fimc_lite_pending_queue_add(struct fimc_lite *dev,
- struct flite_buffer *buf)
-{
- list_add_tail(&buf->list, &dev->pending_buf_q);
-}
-
-static inline struct flite_buffer *fimc_lite_pending_queue_pop(
- struct fimc_lite *dev)
-{
- struct flite_buffer *buf = list_entry(dev->pending_buf_q.next,
- struct flite_buffer, list);
- list_del(&buf->list);
- return buf;
-}
-
-#endif /* FIMC_LITE_H_ */
diff --git a/drivers/media/video/s5p-fimc/fimc-m2m.c b/drivers/media/video/s5p-fimc/fimc-m2m.c
deleted file mode 100644
index c587011d80e..00000000000
--- a/drivers/media/video/s5p-fimc/fimc-m2m.c
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- * Samsung S5P/EXYNOS4 SoC series FIMC (video postprocessor) driver
- *
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki, <s.nawrocki@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation, either version 2 of the License,
- * or (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/bug.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/list.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "fimc-core.h"
-#include "fimc-reg.h"
-#include "fimc-mdevice.h"
-
-
-static unsigned int get_m2m_fmt_flags(unsigned int stream_type)
-{
- if (stream_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return FMT_FLAGS_M2M_IN;
- else
- return FMT_FLAGS_M2M_OUT;
-}
-
-void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state)
-{
- struct vb2_buffer *src_vb, *dst_vb;
-
- if (!ctx || !ctx->m2m_ctx)
- return;
-
- src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
-
- if (src_vb && dst_vb) {
- v4l2_m2m_buf_done(src_vb, vb_state);
- v4l2_m2m_buf_done(dst_vb, vb_state);
- v4l2_m2m_job_finish(ctx->fimc_dev->m2m.m2m_dev,
- ctx->m2m_ctx);
- }
-}
-
-/* Complete the transaction which has been scheduled for execution. */
-static int fimc_m2m_shutdown(struct fimc_ctx *ctx)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- int ret;
-
- if (!fimc_m2m_pending(fimc))
- return 0;
-
- fimc_ctx_state_set(FIMC_CTX_SHUT, ctx);
-
- ret = wait_event_timeout(fimc->irq_queue,
- !fimc_ctx_state_is_set(FIMC_CTX_SHUT, ctx),
- FIMC_SHUTDOWN_TIMEOUT);
-
- return ret == 0 ? -ETIMEDOUT : ret;
-}
-
-static int start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct fimc_ctx *ctx = q->drv_priv;
- int ret;
-
- ret = pm_runtime_get_sync(&ctx->fimc_dev->pdev->dev);
- return ret > 0 ? 0 : ret;
-}
-
-static int stop_streaming(struct vb2_queue *q)
-{
- struct fimc_ctx *ctx = q->drv_priv;
- int ret;
-
- ret = fimc_m2m_shutdown(ctx);
- if (ret == -ETIMEDOUT)
- fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
-
- pm_runtime_put(&ctx->fimc_dev->pdev->dev);
- return 0;
-}
-
-static void fimc_device_run(void *priv)
-{
- struct vb2_buffer *vb = NULL;
- struct fimc_ctx *ctx = priv;
- struct fimc_frame *sf, *df;
- struct fimc_dev *fimc;
- unsigned long flags;
- u32 ret;
-
- if (WARN(!ctx, "Null context\n"))
- return;
-
- fimc = ctx->fimc_dev;
- spin_lock_irqsave(&fimc->slock, flags);
-
- set_bit(ST_M2M_PEND, &fimc->state);
- sf = &ctx->s_frame;
- df = &ctx->d_frame;
-
- if (ctx->state & FIMC_PARAMS) {
- /* Prepare the DMA offsets for scaler */
- fimc_prepare_dma_offset(ctx, sf);
- fimc_prepare_dma_offset(ctx, df);
- }
-
- vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
- ret = fimc_prepare_addr(ctx, vb, sf, &sf->paddr);
- if (ret)
- goto dma_unlock;
-
- vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
- ret = fimc_prepare_addr(ctx, vb, df, &df->paddr);
- if (ret)
- goto dma_unlock;
-
- /* Reconfigure hardware if the context has changed. */
- if (fimc->m2m.ctx != ctx) {
- ctx->state |= FIMC_PARAMS;
- fimc->m2m.ctx = ctx;
- }
-
- if (ctx->state & FIMC_PARAMS) {
- fimc_set_yuv_order(ctx);
- fimc_hw_set_input_path(ctx);
- fimc_hw_set_in_dma(ctx);
- ret = fimc_set_scaler_info(ctx);
- if (ret)
- goto dma_unlock;
- fimc_hw_set_prescaler(ctx);
- fimc_hw_set_mainscaler(ctx);
- fimc_hw_set_target_format(ctx);
- fimc_hw_set_rotation(ctx);
- fimc_hw_set_effect(ctx);
- fimc_hw_set_out_dma(ctx);
- if (fimc->variant->has_alpha)
- fimc_hw_set_rgb_alpha(ctx);
- fimc_hw_set_output_path(ctx);
- }
- fimc_hw_set_input_addr(fimc, &sf->paddr);
- fimc_hw_set_output_addr(fimc, &df->paddr, -1);
-
- fimc_activate_capture(ctx);
- ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP |
- FIMC_SRC_FMT | FIMC_DST_FMT);
- fimc_hw_activate_input_dma(fimc, true);
-
-dma_unlock:
- spin_unlock_irqrestore(&fimc->slock, flags);
-}
-
-static void fimc_job_abort(void *priv)
-{
- fimc_m2m_shutdown(priv);
-}
-
-static int fimc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
- unsigned int *num_buffers, unsigned int *num_planes,
- unsigned int sizes[], void *allocators[])
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
- struct fimc_frame *f;
- int i;
-
- f = ctx_get_frame(ctx, vq->type);
- if (IS_ERR(f))
- return PTR_ERR(f);
- /*
- * Return number of non-contigous planes (plane buffers)
- * depending on the configured color format.
- */
- if (!f->fmt)
- return -EINVAL;
-
- *num_planes = f->fmt->memplanes;
- for (i = 0; i < f->fmt->memplanes; i++) {
- sizes[i] = (f->f_width * f->f_height * f->fmt->depth[i]) / 8;
- allocators[i] = ctx->fimc_dev->alloc_ctx;
- }
- return 0;
-}
-
-static int fimc_buf_prepare(struct vb2_buffer *vb)
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct fimc_frame *frame;
- int i;
-
- frame = ctx_get_frame(ctx, vb->vb2_queue->type);
- if (IS_ERR(frame))
- return PTR_ERR(frame);
-
- for (i = 0; i < frame->fmt->memplanes; i++)
- vb2_set_plane_payload(vb, i, frame->payload[i]);
-
- return 0;
-}
-
-static void fimc_buf_queue(struct vb2_buffer *vb)
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-
- dbg("ctx: %p, ctx->state: 0x%x", ctx, ctx->state);
-
- if (ctx->m2m_ctx)
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
-}
-
-static void fimc_lock(struct vb2_queue *vq)
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
- mutex_lock(&ctx->fimc_dev->lock);
-}
-
-static void fimc_unlock(struct vb2_queue *vq)
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
- mutex_unlock(&ctx->fimc_dev->lock);
-}
-
-static struct vb2_ops fimc_qops = {
- .queue_setup = fimc_queue_setup,
- .buf_prepare = fimc_buf_prepare,
- .buf_queue = fimc_buf_queue,
- .wait_prepare = fimc_unlock,
- .wait_finish = fimc_lock,
- .stop_streaming = stop_streaming,
- .start_streaming = start_streaming,
-};
-
-/*
- * V4L2 ioctl handlers
- */
-static int fimc_m2m_querycap(struct file *file, void *fh,
- struct v4l2_capability *cap)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_dev *fimc = ctx->fimc_dev;
-
- strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1);
- strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1);
- cap->bus_info[0] = 0;
- /*
- * This is only a mem-to-mem video device. The capture and output
- * device capability flags are left only for backward compatibility
- * and are scheduled for removal.
- */
- cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE |
- V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
-
- return 0;
-}
-
-static int fimc_m2m_enum_fmt_mplane(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct fimc_fmt *fmt;
-
- fmt = fimc_find_format(NULL, NULL, get_m2m_fmt_flags(f->type),
- f->index);
- if (!fmt)
- return -EINVAL;
-
- strncpy(f->description, fmt->name, sizeof(f->description) - 1);
- f->pixelformat = fmt->fourcc;
- return 0;
-}
-
-static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_frame *frame = ctx_get_frame(ctx, f->type);
-
- if (IS_ERR(frame))
- return PTR_ERR(frame);
-
- return fimc_fill_format(frame, f);
-}
-
-static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_variant *variant = fimc->variant;
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct fimc_fmt *fmt;
- u32 max_w, mod_x, mod_y;
-
- if (!IS_M2M(f->type))
- return -EINVAL;
-
- dbg("w: %d, h: %d", pix->width, pix->height);
-
- fmt = fimc_find_format(&pix->pixelformat, NULL,
- get_m2m_fmt_flags(f->type), 0);
- if (WARN(fmt == NULL, "Pixel format lookup failed"))
- return -EINVAL;
-
- if (pix->field == V4L2_FIELD_ANY)
- pix->field = V4L2_FIELD_NONE;
- else if (pix->field != V4L2_FIELD_NONE)
- return -EINVAL;
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- max_w = variant->pix_limit->scaler_dis_w;
- mod_x = ffs(variant->min_inp_pixsize) - 1;
- } else {
- max_w = variant->pix_limit->out_rot_dis_w;
- mod_x = ffs(variant->min_out_pixsize) - 1;
- }
-
- if (tiled_fmt(fmt)) {
- mod_x = 6; /* 64 x 32 pixels tile */
- mod_y = 5;
- } else {
- if (variant->min_vsize_align == 1)
- mod_y = fimc_fmt_is_rgb(fmt->color) ? 0 : 1;
- else
- mod_y = ffs(variant->min_vsize_align) - 1;
- }
-
- v4l_bound_align_image(&pix->width, 16, max_w, mod_x,
- &pix->height, 8, variant->pix_limit->scaler_dis_w, mod_y, 0);
-
- fimc_adjust_mplane_format(fmt, pix->width, pix->height, &f->fmt.pix_mp);
- return 0;
-}
-
-static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
-
- return fimc_try_fmt_mplane(ctx, f);
-}
-
-static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct vb2_queue *vq;
- struct fimc_frame *frame;
- struct v4l2_pix_format_mplane *pix;
- int i, ret = 0;
-
- ret = fimc_try_fmt_mplane(ctx, f);
- if (ret)
- return ret;
-
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
-
- if (vb2_is_busy(vq)) {
- v4l2_err(fimc->m2m.vfd, "queue (%d) busy\n", f->type);
- return -EBUSY;
- }
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- frame = &ctx->s_frame;
- else
- frame = &ctx->d_frame;
-
- pix = &f->fmt.pix_mp;
- frame->fmt = fimc_find_format(&pix->pixelformat, NULL,
- get_m2m_fmt_flags(f->type), 0);
- if (!frame->fmt)
- return -EINVAL;
-
- /* Update RGB Alpha control state and value range */
- fimc_alpha_ctrl_update(ctx);
-
- for (i = 0; i < frame->fmt->colplanes; i++) {
- frame->payload[i] =
- (pix->width * pix->height * frame->fmt->depth[i]) / 8;
- }
-
- fimc_fill_frame(frame, f);
-
- ctx->scaler.enabled = 1;
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- fimc_ctx_state_set(FIMC_PARAMS | FIMC_DST_FMT, ctx);
- else
- fimc_ctx_state_set(FIMC_PARAMS | FIMC_SRC_FMT, ctx);
-
- dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height);
-
- return 0;
-}
-
-static int fimc_m2m_reqbufs(struct file *file, void *fh,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
-
- return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
-}
-
-static int fimc_m2m_querybuf(struct file *file, void *fh,
- struct v4l2_buffer *buf)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
-
- return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
-}
-
-static int fimc_m2m_qbuf(struct file *file, void *fh,
- struct v4l2_buffer *buf)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
-
- return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int fimc_m2m_dqbuf(struct file *file, void *fh,
- struct v4l2_buffer *buf)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
-
- return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int fimc_m2m_streamon(struct file *file, void *fh,
- enum v4l2_buf_type type)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
-
- /* The source and target color format need to be set */
- if (V4L2_TYPE_IS_OUTPUT(type)) {
- if (!fimc_ctx_state_is_set(FIMC_SRC_FMT, ctx))
- return -EINVAL;
- } else if (!fimc_ctx_state_is_set(FIMC_DST_FMT, ctx)) {
- return -EINVAL;
- }
-
- return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
-}
-
-static int fimc_m2m_streamoff(struct file *file, void *fh,
- enum v4l2_buf_type type)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
-
- return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
-}
-
-static int fimc_m2m_cropcap(struct file *file, void *fh,
- struct v4l2_cropcap *cr)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_frame *frame;
-
- frame = ctx_get_frame(ctx, cr->type);
- if (IS_ERR(frame))
- return PTR_ERR(frame);
-
- cr->bounds.left = 0;
- cr->bounds.top = 0;
- cr->bounds.width = frame->o_width;
- cr->bounds.height = frame->o_height;
- cr->defrect = cr->bounds;
-
- return 0;
-}
-
-static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_frame *frame;
-
- frame = ctx_get_frame(ctx, cr->type);
- if (IS_ERR(frame))
- return PTR_ERR(frame);
-
- cr->c.left = frame->offs_h;
- cr->c.top = frame->offs_v;
- cr->c.width = frame->width;
- cr->c.height = frame->height;
-
- return 0;
-}
-
-static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_frame *f;
- u32 min_size, halign, depth = 0;
- int i;
-
- if (cr->c.top < 0 || cr->c.left < 0) {
- v4l2_err(fimc->m2m.vfd,
- "doesn't support negative values for top & left\n");
- return -EINVAL;
- }
- if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- f = &ctx->d_frame;
- else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- f = &ctx->s_frame;
- else
- return -EINVAL;
-
- min_size = (f == &ctx->s_frame) ?
- fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
-
- /* Get pixel alignment constraints. */
- if (fimc->variant->min_vsize_align == 1)
- halign = fimc_fmt_is_rgb(f->fmt->color) ? 0 : 1;
- else
- halign = ffs(fimc->variant->min_vsize_align) - 1;
-
- for (i = 0; i < f->fmt->colplanes; i++)
- depth += f->fmt->depth[i];
-
- v4l_bound_align_image(&cr->c.width, min_size, f->o_width,
- ffs(min_size) - 1,
- &cr->c.height, min_size, f->o_height,
- halign, 64/(ALIGN(depth, 8)));
-
- /* adjust left/top if cropping rectangle is out of bounds */
- if (cr->c.left + cr->c.width > f->o_width)
- cr->c.left = f->o_width - cr->c.width;
- if (cr->c.top + cr->c.height > f->o_height)
- cr->c.top = f->o_height - cr->c.height;
-
- cr->c.left = round_down(cr->c.left, min_size);
- cr->c.top = round_down(cr->c.top, fimc->variant->hor_offs_align);
-
- dbg("l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d",
- cr->c.left, cr->c.top, cr->c.width, cr->c.height,
- f->f_width, f->f_height);
-
- return 0;
-}
-
-static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_frame *f;
- int ret;
-
- ret = fimc_m2m_try_crop(ctx, cr);
- if (ret)
- return ret;
-
- f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ?
- &ctx->s_frame : &ctx->d_frame;
-
- /* Check to see if scaling ratio is within supported range */
- if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
- if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- ret = fimc_check_scaler_ratio(ctx, cr->c.width,
- cr->c.height, ctx->d_frame.width,
- ctx->d_frame.height, ctx->rotation);
- } else {
- ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
- ctx->s_frame.height, cr->c.width,
- cr->c.height, ctx->rotation);
- }
- if (ret) {
- v4l2_err(fimc->m2m.vfd, "Out of scaler range\n");
- return -EINVAL;
- }
- }
-
- f->offs_h = cr->c.left;
- f->offs_v = cr->c.top;
- f->width = cr->c.width;
- f->height = cr->c.height;
-
- fimc_ctx_state_set(FIMC_PARAMS, ctx);
-
- return 0;
-}
-
-static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
- .vidioc_querycap = fimc_m2m_querycap,
- .vidioc_enum_fmt_vid_cap_mplane = fimc_m2m_enum_fmt_mplane,
- .vidioc_enum_fmt_vid_out_mplane = fimc_m2m_enum_fmt_mplane,
- .vidioc_g_fmt_vid_cap_mplane = fimc_m2m_g_fmt_mplane,
- .vidioc_g_fmt_vid_out_mplane = fimc_m2m_g_fmt_mplane,
- .vidioc_try_fmt_vid_cap_mplane = fimc_m2m_try_fmt_mplane,
- .vidioc_try_fmt_vid_out_mplane = fimc_m2m_try_fmt_mplane,
- .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane,
- .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane,
- .vidioc_reqbufs = fimc_m2m_reqbufs,
- .vidioc_querybuf = fimc_m2m_querybuf,
- .vidioc_qbuf = fimc_m2m_qbuf,
- .vidioc_dqbuf = fimc_m2m_dqbuf,
- .vidioc_streamon = fimc_m2m_streamon,
- .vidioc_streamoff = fimc_m2m_streamoff,
- .vidioc_g_crop = fimc_m2m_g_crop,
- .vidioc_s_crop = fimc_m2m_s_crop,
- .vidioc_cropcap = fimc_m2m_cropcap
-
-};
-
-static int queue_init(void *priv, struct vb2_queue *src_vq,
- struct vb2_queue *dst_vq)
-{
- struct fimc_ctx *ctx = priv;
- int ret;
-
- memset(src_vq, 0, sizeof(*src_vq));
- src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
- src_vq->drv_priv = ctx;
- src_vq->ops = &fimc_qops;
- src_vq->mem_ops = &vb2_dma_contig_memops;
- src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-
- ret = vb2_queue_init(src_vq);
- if (ret)
- return ret;
-
- memset(dst_vq, 0, sizeof(*dst_vq));
- dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
- dst_vq->drv_priv = ctx;
- dst_vq->ops = &fimc_qops;
- dst_vq->mem_ops = &vb2_dma_contig_memops;
- dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-
- return vb2_queue_init(dst_vq);
-}
-
-static int fimc_m2m_open(struct file *file)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_ctx *ctx;
- int ret = -EBUSY;
-
- dbg("pid: %d, state: 0x%lx, refcnt: %d",
- task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt);
-
- if (mutex_lock_interruptible(&fimc->lock))
- return -ERESTARTSYS;
- /*
- * Return if the corresponding video capture node
- * is already opened.
- */
- if (fimc->vid_cap.refcnt > 0)
- goto unlock;
-
- ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
- if (!ctx) {
- ret = -ENOMEM;
- goto unlock;
- }
- v4l2_fh_init(&ctx->fh, fimc->m2m.vfd);
- ctx->fimc_dev = fimc;
-
- /* Default color format */
- ctx->s_frame.fmt = fimc_get_format(0);
- ctx->d_frame.fmt = fimc_get_format(0);
-
- ret = fimc_ctrls_create(ctx);
- if (ret)
- goto error_fh;
-
- /* Use separate control handler per file handle */
- ctx->fh.ctrl_handler = &ctx->ctrls.handler;
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
-
- /* Setup the device context for memory-to-memory mode */
- ctx->state = FIMC_CTX_M2M;
- ctx->flags = 0;
- ctx->in_path = FIMC_IO_DMA;
- ctx->out_path = FIMC_IO_DMA;
-
- ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
- if (IS_ERR(ctx->m2m_ctx)) {
- ret = PTR_ERR(ctx->m2m_ctx);
- goto error_c;
- }
-
- if (fimc->m2m.refcnt++ == 0)
- set_bit(ST_M2M_RUN, &fimc->state);
-
- mutex_unlock(&fimc->lock);
- return 0;
-
-error_c:
- fimc_ctrls_delete(ctx);
-error_fh:
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
- kfree(ctx);
-unlock:
- mutex_unlock(&fimc->lock);
- return ret;
-}
-
-static int fimc_m2m_release(struct file *file)
-{
- struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
- struct fimc_dev *fimc = ctx->fimc_dev;
-
- dbg("pid: %d, state: 0x%lx, refcnt= %d",
- task_pid_nr(current), fimc->state, fimc->m2m.refcnt);
-
- if (mutex_lock_interruptible(&fimc->lock))
- return -ERESTARTSYS;
-
- v4l2_m2m_ctx_release(ctx->m2m_ctx);
- fimc_ctrls_delete(ctx);
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
-
- if (--fimc->m2m.refcnt <= 0)
- clear_bit(ST_M2M_RUN, &fimc->state);
- kfree(ctx);
-
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static unsigned int fimc_m2m_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
- struct fimc_dev *fimc = ctx->fimc_dev;
- int ret;
-
- if (mutex_lock_interruptible(&fimc->lock))
- return -ERESTARTSYS;
-
- ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
- mutex_unlock(&fimc->lock);
-
- return ret;
-}
-
-
-static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
- struct fimc_dev *fimc = ctx->fimc_dev;
- int ret;
-
- if (mutex_lock_interruptible(&fimc->lock))
- return -ERESTARTSYS;
-
- ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
- mutex_unlock(&fimc->lock);
-
- return ret;
-}
-
-static const struct v4l2_file_operations fimc_m2m_fops = {
- .owner = THIS_MODULE,
- .open = fimc_m2m_open,
- .release = fimc_m2m_release,
- .poll = fimc_m2m_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = fimc_m2m_mmap,
-};
-
-static struct v4l2_m2m_ops m2m_ops = {
- .device_run = fimc_device_run,
- .job_abort = fimc_job_abort,
-};
-
-int fimc_register_m2m_device(struct fimc_dev *fimc,
- struct v4l2_device *v4l2_dev)
-{
- struct video_device *vfd;
- struct platform_device *pdev;
- int ret = 0;
-
- if (!fimc)
- return -ENODEV;
-
- pdev = fimc->pdev;
- fimc->v4l2_dev = v4l2_dev;
-
- vfd = video_device_alloc();
- if (!vfd) {
- v4l2_err(v4l2_dev, "Failed to allocate video device\n");
- return -ENOMEM;
- }
-
- vfd->fops = &fimc_m2m_fops;
- vfd->ioctl_ops = &fimc_m2m_ioctl_ops;
- vfd->v4l2_dev = v4l2_dev;
- vfd->minor = -1;
- vfd->release = video_device_release;
- vfd->lock = &fimc->lock;
-
- snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id);
- video_set_drvdata(vfd, fimc);
-
- fimc->m2m.vfd = vfd;
- fimc->m2m.m2m_dev = v4l2_m2m_init(&m2m_ops);
- if (IS_ERR(fimc->m2m.m2m_dev)) {
- v4l2_err(v4l2_dev, "failed to initialize v4l2-m2m device\n");
- ret = PTR_ERR(fimc->m2m.m2m_dev);
- goto err_init;
- }
-
- ret = media_entity_init(&vfd->entity, 0, NULL, 0);
- if (ret)
- goto err_me;
-
- ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
- if (ret)
- goto err_vd;
-
- v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
- vfd->name, video_device_node_name(vfd));
- return 0;
-
-err_vd:
- media_entity_cleanup(&vfd->entity);
-err_me:
- v4l2_m2m_release(fimc->m2m.m2m_dev);
-err_init:
- video_device_release(fimc->m2m.vfd);
- return ret;
-}
-
-void fimc_unregister_m2m_device(struct fimc_dev *fimc)
-{
- if (!fimc)
- return;
-
- if (fimc->m2m.m2m_dev)
- v4l2_m2m_release(fimc->m2m.m2m_dev);
- if (fimc->m2m.vfd) {
- media_entity_cleanup(&fimc->m2m.vfd->entity);
- /* Can also be called if video device wasn't registered */
- video_unregister_device(fimc->m2m.vfd);
- }
-}
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c
deleted file mode 100644
index e65bb283fd8..00000000000
--- a/drivers/media/video/s5p-fimc/fimc-mdevice.c
+++ /dev/null
@@ -1,1037 +0,0 @@
-/*
- * S5P/EXYNOS4 SoC series camera host interface media device driver
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation, either version 2 of the License,
- * or (at your option) any later version.
- */
-
-#include <linux/bug.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/i2c.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <media/v4l2-ctrls.h>
-#include <media/media-device.h>
-
-#include "fimc-core.h"
-#include "fimc-lite.h"
-#include "fimc-mdevice.h"
-#include "mipi-csis.h"
-
-static int __fimc_md_set_camclk(struct fimc_md *fmd,
- struct fimc_sensor_info *s_info,
- bool on);
-/**
- * fimc_pipeline_prepare - update pipeline information with subdevice pointers
- * @fimc: fimc device terminating the pipeline
- *
- * Caller holds the graph mutex.
- */
-void fimc_pipeline_prepare(struct fimc_pipeline *p, struct media_entity *me)
-{
- struct media_pad *pad = &me->pads[0];
- struct v4l2_subdev *sd;
- int i;
-
- for (i = 0; i < IDX_MAX; i++)
- p->subdevs[i] = NULL;
-
- while (1) {
- if (!(pad->flags & MEDIA_PAD_FL_SINK))
- break;
-
- /* source pad */
- pad = media_entity_remote_source(pad);
- if (pad == NULL ||
- media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
- break;
-
- sd = media_entity_to_v4l2_subdev(pad->entity);
-
- switch (sd->grp_id) {
- case SENSOR_GROUP_ID:
- p->subdevs[IDX_SENSOR] = sd;
- break;
- case CSIS_GROUP_ID:
- p->subdevs[IDX_CSIS] = sd;
- break;
- case FLITE_GROUP_ID:
- p->subdevs[IDX_FLITE] = sd;
- break;
- case FIMC_GROUP_ID:
- /* No need to control FIMC subdev through subdev ops */
- break;
- default:
- pr_warn("%s: Unknown subdev grp_id: %#x\n",
- __func__, sd->grp_id);
- }
- /* sink pad */
- pad = &sd->entity.pads[0];
- }
-}
-
-/**
- * __subdev_set_power - change power state of a single subdev
- * @sd: subdevice to change power state for
- * @on: 1 to enable power or 0 to disable
- *
- * Return result of s_power subdev operation or -ENXIO if sd argument
- * is NULL. Return 0 if the subdevice does not implement s_power.
- */
-static int __subdev_set_power(struct v4l2_subdev *sd, int on)
-{
- int *use_count;
- int ret;
-
- if (sd == NULL)
- return -ENXIO;
-
- use_count = &sd->entity.use_count;
- if (on && (*use_count)++ > 0)
- return 0;
- else if (!on && (*use_count == 0 || --(*use_count) > 0))
- return 0;
- ret = v4l2_subdev_call(sd, core, s_power, on);
-
- return ret != -ENOIOCTLCMD ? ret : 0;
-}
-
-/**
- * fimc_pipeline_s_power - change power state of all pipeline subdevs
- * @fimc: fimc device terminating the pipeline
- * @state: true to power on, false to power off
- *
- * Needs to be called with the graph mutex held.
- */
-int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state)
-{
- unsigned int i;
- int ret;
-
- if (p->subdevs[IDX_SENSOR] == NULL)
- return -ENXIO;
-
- for (i = 0; i < IDX_MAX; i++) {
- unsigned int idx = state ? (IDX_MAX - 1) - i : i;
-
- ret = __subdev_set_power(p->subdevs[idx], state);
- if (ret < 0 && ret != -ENXIO)
- return ret;
- }
-
- return 0;
-}
-
-/**
- * __fimc_pipeline_initialize - update the pipeline information, enable power
- * of all pipeline subdevs and the sensor clock
- * @me: media entity to start graph walk with
- * @prep: true to acquire sensor (and csis) subdevs
- *
- * This function must be called with the graph mutex held.
- */
-static int __fimc_pipeline_initialize(struct fimc_pipeline *p,
- struct media_entity *me, bool prep)
-{
- int ret;
-
- if (prep)
- fimc_pipeline_prepare(p, me);
-
- if (p->subdevs[IDX_SENSOR] == NULL)
- return -EINVAL;
-
- ret = fimc_md_set_camclk(p->subdevs[IDX_SENSOR], true);
- if (ret)
- return ret;
-
- return fimc_pipeline_s_power(p, 1);
-}
-
-int fimc_pipeline_initialize(struct fimc_pipeline *p, struct media_entity *me,
- bool prep)
-{
- int ret;
-
- mutex_lock(&me->parent->graph_mutex);
- ret = __fimc_pipeline_initialize(p, me, prep);
- mutex_unlock(&me->parent->graph_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(fimc_pipeline_initialize);
-
-/**
- * __fimc_pipeline_shutdown - disable the sensor clock and pipeline power
- * @fimc: fimc device terminating the pipeline
- *
- * Disable power of all subdevs in the pipeline and turn off the external
- * sensor clock.
- * Called with the graph mutex held.
- */
-static int __fimc_pipeline_shutdown(struct fimc_pipeline *p)
-{
- int ret = 0;
-
- if (p->subdevs[IDX_SENSOR]) {
- ret = fimc_pipeline_s_power(p, 0);
- fimc_md_set_camclk(p->subdevs[IDX_SENSOR], false);
- }
- return ret == -ENXIO ? 0 : ret;
-}
-
-int fimc_pipeline_shutdown(struct fimc_pipeline *p)
-{
- struct media_entity *me;
- int ret;
-
- if (!p || !p->subdevs[IDX_SENSOR])
- return -EINVAL;
-
- me = &p->subdevs[IDX_SENSOR]->entity;
- mutex_lock(&me->parent->graph_mutex);
- ret = __fimc_pipeline_shutdown(p);
- mutex_unlock(&me->parent->graph_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(fimc_pipeline_shutdown);
-
-/**
- * fimc_pipeline_s_stream - invoke s_stream on pipeline subdevs
- * @pipeline: video pipeline structure
- * @on: passed as the s_stream call argument
- */
-int fimc_pipeline_s_stream(struct fimc_pipeline *p, bool on)
-{
- int i, ret;
-
- if (p->subdevs[IDX_SENSOR] == NULL)
- return -ENODEV;
-
- for (i = 0; i < IDX_MAX; i++) {
- unsigned int idx = on ? (IDX_MAX - 1) - i : i;
-
- ret = v4l2_subdev_call(p->subdevs[idx], video, s_stream, on);
-
- if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
- return ret;
- }
-
- return 0;
-
-}
-EXPORT_SYMBOL_GPL(fimc_pipeline_s_stream);
-
-/*
- * Sensor subdevice helper functions
- */
-static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd,
- struct fimc_sensor_info *s_info)
-{
- struct i2c_adapter *adapter;
- struct v4l2_subdev *sd = NULL;
-
- if (!s_info || !fmd)
- return NULL;
-
- adapter = i2c_get_adapter(s_info->pdata->i2c_bus_num);
- if (!adapter) {
- v4l2_warn(&fmd->v4l2_dev,
- "Failed to get I2C adapter %d, deferring probe\n",
- s_info->pdata->i2c_bus_num);
- return ERR_PTR(-EPROBE_DEFER);
- }
- sd = v4l2_i2c_new_subdev_board(&fmd->v4l2_dev, adapter,
- s_info->pdata->board_info, NULL);
- if (IS_ERR_OR_NULL(sd)) {
- i2c_put_adapter(adapter);
- v4l2_warn(&fmd->v4l2_dev,
- "Failed to acquire subdev %s, deferring probe\n",
- s_info->pdata->board_info->type);
- return ERR_PTR(-EPROBE_DEFER);
- }
- v4l2_set_subdev_hostdata(sd, s_info);
- sd->grp_id = SENSOR_GROUP_ID;
-
- v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice %s\n",
- s_info->pdata->board_info->type);
- return sd;
-}
-
-static void fimc_md_unregister_sensor(struct v4l2_subdev *sd)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct i2c_adapter *adapter;
-
- if (!client)
- return;
- v4l2_device_unregister_subdev(sd);
- adapter = client->adapter;
- i2c_unregister_device(client);
- if (adapter)
- i2c_put_adapter(adapter);
-}
-
-static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
-{
- struct s5p_platform_fimc *pdata = fmd->pdev->dev.platform_data;
- struct fimc_dev *fd = NULL;
- int num_clients, ret, i;
-
- /*
- * Runtime resume one of the FIMC entities to make sure
- * the sclk_cam clocks are not globally disabled.
- */
- for (i = 0; !fd && i < ARRAY_SIZE(fmd->fimc); i++)
- if (fmd->fimc[i])
- fd = fmd->fimc[i];
- if (!fd)
- return -ENXIO;
- ret = pm_runtime_get_sync(&fd->pdev->dev);
- if (ret < 0)
- return ret;
-
- WARN_ON(pdata->num_clients > ARRAY_SIZE(fmd->sensor));
- num_clients = min_t(u32, pdata->num_clients, ARRAY_SIZE(fmd->sensor));
-
- fmd->num_sensors = num_clients;
- for (i = 0; i < num_clients; i++) {
- struct v4l2_subdev *sd;
-
- fmd->sensor[i].pdata = &pdata->isp_info[i];
- ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], true);
- if (ret)
- break;
- sd = fimc_md_register_sensor(fmd, &fmd->sensor[i]);
- ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], false);
-
- if (!IS_ERR(sd)) {
- fmd->sensor[i].subdev = sd;
- } else {
- fmd->sensor[i].subdev = NULL;
- ret = PTR_ERR(sd);
- break;
- }
- if (ret)
- break;
- }
- pm_runtime_put(&fd->pdev->dev);
- return ret;
-}
-
-/*
- * MIPI CSIS and FIMC platform devices registration.
- */
-static int fimc_register_callback(struct device *dev, void *p)
-{
- struct fimc_dev *fimc = dev_get_drvdata(dev);
- struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
- struct fimc_md *fmd = p;
- int ret = 0;
-
- if (!fimc || !fimc->pdev)
- return 0;
-
- if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS)
- return 0;
-
- fmd->fimc[fimc->pdev->id] = fimc;
- sd->grp_id = FIMC_GROUP_ID;
-
- ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
- if (ret) {
- v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.%d (%d)\n",
- fimc->id, ret);
- }
-
- return ret;
-}
-
-static int fimc_lite_register_callback(struct device *dev, void *p)
-{
- struct fimc_lite *fimc = dev_get_drvdata(dev);
- struct v4l2_subdev *sd = &fimc->subdev;
- struct fimc_md *fmd = p;
- int ret;
-
- if (fimc == NULL)
- return 0;
-
- if (fimc->index >= FIMC_LITE_MAX_DEVS)
- return 0;
-
- fmd->fimc_lite[fimc->index] = fimc;
- sd->grp_id = FLITE_GROUP_ID;
-
- ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
- if (ret) {
- v4l2_err(&fmd->v4l2_dev,
- "Failed to register FIMC-LITE.%d (%d)\n",
- fimc->index, ret);
- }
- return ret;
-}
-
-static int csis_register_callback(struct device *dev, void *p)
-{
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
- struct platform_device *pdev;
- struct fimc_md *fmd = p;
- int id, ret;
-
- if (!sd)
- return 0;
- pdev = v4l2_get_subdevdata(sd);
- if (!pdev || pdev->id < 0 || pdev->id >= CSIS_MAX_ENTITIES)
- return 0;
- v4l2_info(sd, "csis%d sd: %s\n", pdev->id, sd->name);
-
- id = pdev->id < 0 ? 0 : pdev->id;
- fmd->csis[id].sd = sd;
- sd->grp_id = CSIS_GROUP_ID;
- ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
- if (ret)
- v4l2_err(&fmd->v4l2_dev,
- "Failed to register CSIS subdevice: %d\n", ret);
- return ret;
-}
-
-/**
- * fimc_md_register_platform_entities - register FIMC and CSIS media entities
- */
-static int fimc_md_register_platform_entities(struct fimc_md *fmd)
-{
- struct s5p_platform_fimc *pdata = fmd->pdev->dev.platform_data;
- struct device_driver *driver;
- int ret, i;
-
- driver = driver_find(FIMC_MODULE_NAME, &platform_bus_type);
- if (!driver) {
- v4l2_warn(&fmd->v4l2_dev,
- "%s driver not found, deffering probe\n",
- FIMC_MODULE_NAME);
- return -EPROBE_DEFER;
- }
-
- ret = driver_for_each_device(driver, NULL, fmd,
- fimc_register_callback);
- if (ret)
- return ret;
-
- driver = driver_find(FIMC_LITE_DRV_NAME, &platform_bus_type);
- if (driver && try_module_get(driver->owner)) {
- ret = driver_for_each_device(driver, NULL, fmd,
- fimc_lite_register_callback);
- if (ret)
- return ret;
- module_put(driver->owner);
- }
- /*
- * Check if there is any sensor on the MIPI-CSI2 bus and
- * if not skip the s5p-csis module loading.
- */
- if (pdata == NULL)
- return 0;
- for (i = 0; i < pdata->num_clients; i++) {
- if (pdata->isp_info[i].bus_type == FIMC_MIPI_CSI2) {
- ret = 1;
- break;
- }
- }
- if (!ret)
- return 0;
-
- driver = driver_find(CSIS_DRIVER_NAME, &platform_bus_type);
- if (!driver || !try_module_get(driver->owner)) {
- v4l2_warn(&fmd->v4l2_dev,
- "%s driver not found, deffering probe\n",
- CSIS_DRIVER_NAME);
- return -EPROBE_DEFER;
- }
-
- return driver_for_each_device(driver, NULL, fmd,
- csis_register_callback);
-}
-
-static void fimc_md_unregister_entities(struct fimc_md *fmd)
-{
- int i;
-
- for (i = 0; i < FIMC_MAX_DEVS; i++) {
- if (fmd->fimc[i] == NULL)
- continue;
- v4l2_device_unregister_subdev(&fmd->fimc[i]->vid_cap.subdev);
- fmd->fimc[i] = NULL;
- }
- for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
- if (fmd->fimc_lite[i] == NULL)
- continue;
- v4l2_device_unregister_subdev(&fmd->fimc_lite[i]->subdev);
- fmd->fimc_lite[i] = NULL;
- }
- for (i = 0; i < CSIS_MAX_ENTITIES; i++) {
- if (fmd->csis[i].sd == NULL)
- continue;
- v4l2_device_unregister_subdev(fmd->csis[i].sd);
- module_put(fmd->csis[i].sd->owner);
- fmd->csis[i].sd = NULL;
- }
- for (i = 0; i < fmd->num_sensors; i++) {
- if (fmd->sensor[i].subdev == NULL)
- continue;
- fimc_md_unregister_sensor(fmd->sensor[i].subdev);
- fmd->sensor[i].subdev = NULL;
- }
-}
-
-/**
- * __fimc_md_create_fimc_links - create links to all FIMC entities
- * @fmd: fimc media device
- * @source: the source entity to create links to all fimc entities from
- * @sensor: sensor subdev linked to FIMC[fimc_id] entity, may be null
- * @pad: the source entity pad index
- * @link_mask: bitmask of the fimc devices for which link should be enabled
- */
-static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
- struct media_entity *source,
- struct v4l2_subdev *sensor,
- int pad, int link_mask)
-{
- struct fimc_sensor_info *s_info;
- struct media_entity *sink;
- unsigned int flags = 0;
- int ret, i;
-
- for (i = 0; i < FIMC_MAX_DEVS; i++) {
- if (!fmd->fimc[i])
- continue;
- /*
- * Some FIMC variants are not fitted with camera capture
- * interface. Skip creating a link from sensor for those.
- */
- if (!fmd->fimc[i]->variant->has_cam_if)
- continue;
-
- flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0;
-
- sink = &fmd->fimc[i]->vid_cap.subdev.entity;
- ret = media_entity_create_link(source, pad, sink,
- FIMC_SD_PAD_SINK, flags);
- if (ret)
- return ret;
-
- /* Notify FIMC capture subdev entity */
- ret = media_entity_call(sink, link_setup, &sink->pads[0],
- &source->pads[pad], flags);
- if (ret)
- break;
-
- v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]",
- source->name, flags ? '=' : '-', sink->name);
-
- if (flags == 0 || sensor == NULL)
- continue;
- s_info = v4l2_get_subdev_hostdata(sensor);
- if (!WARN_ON(s_info == NULL)) {
- unsigned long irq_flags;
- spin_lock_irqsave(&fmd->slock, irq_flags);
- s_info->host = fmd->fimc[i];
- spin_unlock_irqrestore(&fmd->slock, irq_flags);
- }
- }
-
- for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
- if (!fmd->fimc_lite[i])
- continue;
-
- if (link_mask & (1 << (i + FIMC_MAX_DEVS)))
- flags = MEDIA_LNK_FL_ENABLED;
- else
- flags = 0;
-
- sink = &fmd->fimc_lite[i]->subdev.entity;
- ret = media_entity_create_link(source, pad, sink,
- FLITE_SD_PAD_SINK, flags);
- if (ret)
- return ret;
-
- /* Notify FIMC-LITE subdev entity */
- ret = media_entity_call(sink, link_setup, &sink->pads[0],
- &source->pads[pad], flags);
- if (ret)
- break;
-
- v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]",
- source->name, flags ? '=' : '-', sink->name);
- }
- return 0;
-}
-
-/* Create links from FIMC-LITE source pads to other entities */
-static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
-{
- struct media_entity *source, *sink;
- unsigned int flags = MEDIA_LNK_FL_ENABLED;
- int i, ret;
-
- for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
- struct fimc_lite *fimc = fmd->fimc_lite[i];
- if (fimc == NULL)
- continue;
- source = &fimc->subdev.entity;
- sink = &fimc->vfd->entity;
- /* FIMC-LITE's subdev and video node */
- ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
- sink, 0, flags);
- if (ret)
- break;
- /* TODO: create links to other entities */
- }
-
- return ret;
-}
-
-/**
- * fimc_md_create_links - create default links between registered entities
- *
- * Parallel interface sensor entities are connected directly to FIMC capture
- * entities. The sensors using MIPI CSIS bus are connected through immutable
- * link with CSI receiver entity specified by mux_id. Any registered CSIS
- * entity has a link to each registered FIMC capture entity. Enabled links
- * are created by default between each subsequent registered sensor and
- * subsequent FIMC capture entity. The number of default active links is
- * determined by the number of available sensors or FIMC entities,
- * whichever is less.
- */
-static int fimc_md_create_links(struct fimc_md *fmd)
-{
- struct v4l2_subdev *sensor, *csis;
- struct s5p_fimc_isp_info *pdata;
- struct fimc_sensor_info *s_info;
- struct media_entity *source, *sink;
- int i, pad, fimc_id = 0, ret = 0;
- u32 flags, link_mask = 0;
-
- for (i = 0; i < fmd->num_sensors; i++) {
- if (fmd->sensor[i].subdev == NULL)
- continue;
-
- sensor = fmd->sensor[i].subdev;
- s_info = v4l2_get_subdev_hostdata(sensor);
- if (!s_info || !s_info->pdata)
- continue;
-
- source = NULL;
- pdata = s_info->pdata;
-
- switch (pdata->bus_type) {
- case FIMC_MIPI_CSI2:
- if (WARN(pdata->mux_id >= CSIS_MAX_ENTITIES,
- "Wrong CSI channel id: %d\n", pdata->mux_id))
- return -EINVAL;
-
- csis = fmd->csis[pdata->mux_id].sd;
- if (WARN(csis == NULL,
- "MIPI-CSI interface specified "
- "but s5p-csis module is not loaded!\n"))
- return -EINVAL;
-
- ret = media_entity_create_link(&sensor->entity, 0,
- &csis->entity, CSIS_PAD_SINK,
- MEDIA_LNK_FL_IMMUTABLE |
- MEDIA_LNK_FL_ENABLED);
- if (ret)
- return ret;
-
- v4l2_info(&fmd->v4l2_dev, "created link [%s] => [%s]",
- sensor->entity.name, csis->entity.name);
-
- source = NULL;
- break;
-
- case FIMC_ITU_601...FIMC_ITU_656:
- source = &sensor->entity;
- pad = 0;
- break;
-
- default:
- v4l2_err(&fmd->v4l2_dev, "Wrong bus_type: %x\n",
- pdata->bus_type);
- return -EINVAL;
- }
- if (source == NULL)
- continue;
-
- link_mask = 1 << fimc_id++;
- ret = __fimc_md_create_fimc_sink_links(fmd, source, sensor,
- pad, link_mask);
- }
-
- for (i = 0; i < ARRAY_SIZE(fmd->csis); i++) {
- if (fmd->csis[i].sd == NULL)
- continue;
- source = &fmd->csis[i].sd->entity;
- pad = CSIS_PAD_SOURCE;
-
- link_mask = 1 << fimc_id++;
- ret = __fimc_md_create_fimc_sink_links(fmd, source, NULL,
- pad, link_mask);
- }
-
- /* Create immutable links between each FIMC's subdev and video node */
- flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED;
- for (i = 0; i < FIMC_MAX_DEVS; i++) {
- if (!fmd->fimc[i])
- continue;
- source = &fmd->fimc[i]->vid_cap.subdev.entity;
- sink = &fmd->fimc[i]->vid_cap.vfd->entity;
- ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
- sink, 0, flags);
- if (ret)
- break;
- }
-
- return __fimc_md_create_flite_source_links(fmd);
-}
-
-/*
- * The peripheral sensor clock management.
- */
-static int fimc_md_get_clocks(struct fimc_md *fmd)
-{
- char clk_name[32];
- struct clk *clock;
- int i;
-
- for (i = 0; i < FIMC_MAX_CAMCLKS; i++) {
- snprintf(clk_name, sizeof(clk_name), "sclk_cam%u", i);
- clock = clk_get(NULL, clk_name);
- if (IS_ERR_OR_NULL(clock)) {
- v4l2_err(&fmd->v4l2_dev, "Failed to get clock: %s",
- clk_name);
- return -ENXIO;
- }
- fmd->camclk[i].clock = clock;
- }
- return 0;
-}
-
-static void fimc_md_put_clocks(struct fimc_md *fmd)
-{
- int i = FIMC_MAX_CAMCLKS;
-
- while (--i >= 0) {
- if (IS_ERR_OR_NULL(fmd->camclk[i].clock))
- continue;
- clk_put(fmd->camclk[i].clock);
- fmd->camclk[i].clock = NULL;
- }
-}
-
-static int __fimc_md_set_camclk(struct fimc_md *fmd,
- struct fimc_sensor_info *s_info,
- bool on)
-{
- struct s5p_fimc_isp_info *pdata = s_info->pdata;
- struct fimc_camclk_info *camclk;
- int ret = 0;
-
- if (WARN_ON(pdata->clk_id >= FIMC_MAX_CAMCLKS) || fmd == NULL)
- return -EINVAL;
-
- camclk = &fmd->camclk[pdata->clk_id];
-
- dbg("camclk %d, f: %lu, use_count: %d, on: %d",
- pdata->clk_id, pdata->clk_frequency, camclk->use_count, on);
-
- if (on) {
- if (camclk->use_count > 0 &&
- camclk->frequency != pdata->clk_frequency)
- return -EINVAL;
-
- if (camclk->use_count++ == 0) {
- clk_set_rate(camclk->clock, pdata->clk_frequency);
- camclk->frequency = pdata->clk_frequency;
- ret = clk_enable(camclk->clock);
- dbg("Enabled camclk %d: f: %lu", pdata->clk_id,
- clk_get_rate(camclk->clock));
- }
- return ret;
- }
-
- if (WARN_ON(camclk->use_count == 0))
- return 0;
-
- if (--camclk->use_count == 0) {
- clk_disable(camclk->clock);
- dbg("Disabled camclk %d", pdata->clk_id);
- }
- return ret;
-}
-
-/**
- * fimc_md_set_camclk - peripheral sensor clock setup
- * @sd: sensor subdev to configure sclk_cam clock for
- * @on: 1 to enable or 0 to disable the clock
- *
- * There are 2 separate clock outputs available in the SoC for external
- * image processors. These clocks are shared between all registered FIMC
- * devices to which sensors can be attached, either directly or through
- * the MIPI CSI receiver. The clock is allowed here to be used by
- * multiple sensors concurrently if they use same frequency.
- * This function should only be called when the graph mutex is held.
- */
-int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on)
-{
- struct fimc_sensor_info *s_info = v4l2_get_subdev_hostdata(sd);
- struct fimc_md *fmd = entity_to_fimc_mdev(&sd->entity);
-
- return __fimc_md_set_camclk(fmd, s_info, on);
-}
-
-static int fimc_md_link_notify(struct media_pad *source,
- struct media_pad *sink, u32 flags)
-{
- struct fimc_lite *fimc_lite = NULL;
- struct fimc_dev *fimc = NULL;
- struct fimc_pipeline *pipeline;
- struct v4l2_subdev *sd;
- int ret = 0;
-
- if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
- return 0;
-
- sd = media_entity_to_v4l2_subdev(sink->entity);
-
- switch (sd->grp_id) {
- case FLITE_GROUP_ID:
- fimc_lite = v4l2_get_subdevdata(sd);
- pipeline = &fimc_lite->pipeline;
- break;
- case FIMC_GROUP_ID:
- fimc = v4l2_get_subdevdata(sd);
- pipeline = &fimc->pipeline;
- break;
- default:
- return 0;
- }
-
- if (!(flags & MEDIA_LNK_FL_ENABLED)) {
- ret = __fimc_pipeline_shutdown(pipeline);
- pipeline->subdevs[IDX_SENSOR] = NULL;
- pipeline->subdevs[IDX_CSIS] = NULL;
-
- if (fimc) {
- mutex_lock(&fimc->lock);
- fimc_ctrls_delete(fimc->vid_cap.ctx);
- mutex_unlock(&fimc->lock);
- }
- return ret;
- }
- /*
- * Link activation. Enable power of pipeline elements only if the
- * pipeline is already in use, i.e. its video node is opened.
- * Recreate the controls destroyed during the link deactivation.
- */
- if (fimc) {
- mutex_lock(&fimc->lock);
- if (fimc->vid_cap.refcnt > 0) {
- ret = __fimc_pipeline_initialize(pipeline,
- source->entity, true);
- if (!ret)
- ret = fimc_capture_ctrls_create(fimc);
- }
- mutex_unlock(&fimc->lock);
- } else {
- mutex_lock(&fimc_lite->lock);
- if (fimc_lite->ref_count > 0) {
- ret = __fimc_pipeline_initialize(pipeline,
- source->entity, true);
- }
- mutex_unlock(&fimc_lite->lock);
- }
- return ret ? -EPIPE : ret;
-}
-
-static ssize_t fimc_md_sysfs_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct fimc_md *fmd = platform_get_drvdata(pdev);
-
- if (fmd->user_subdev_api)
- return strlcpy(buf, "Sub-device API (sub-dev)\n", PAGE_SIZE);
-
- return strlcpy(buf, "V4L2 video node only API (vid-dev)\n", PAGE_SIZE);
-}
-
-static ssize_t fimc_md_sysfs_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct fimc_md *fmd = platform_get_drvdata(pdev);
- bool subdev_api;
- int i;
-
- if (!strcmp(buf, "vid-dev\n"))
- subdev_api = false;
- else if (!strcmp(buf, "sub-dev\n"))
- subdev_api = true;
- else
- return count;
-
- fmd->user_subdev_api = subdev_api;
- for (i = 0; i < FIMC_MAX_DEVS; i++)
- if (fmd->fimc[i])
- fmd->fimc[i]->vid_cap.user_subdev_api = subdev_api;
- return count;
-}
-/*
- * This device attribute is to select video pipeline configuration method.
- * There are following valid values:
- * vid-dev - for V4L2 video node API only, subdevice will be configured
- * by the host driver.
- * sub-dev - for media controller API, subdevs must be configured in user
- * space before starting streaming.
- */
-static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO,
- fimc_md_sysfs_show, fimc_md_sysfs_store);
-
-static int fimc_md_probe(struct platform_device *pdev)
-{
- struct v4l2_device *v4l2_dev;
- struct fimc_md *fmd;
- int ret;
-
- fmd = devm_kzalloc(&pdev->dev, sizeof(*fmd), GFP_KERNEL);
- if (!fmd)
- return -ENOMEM;
-
- spin_lock_init(&fmd->slock);
- fmd->pdev = pdev;
-
- strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC",
- sizeof(fmd->media_dev.model));
- fmd->media_dev.link_notify = fimc_md_link_notify;
- fmd->media_dev.dev = &pdev->dev;
-
- v4l2_dev = &fmd->v4l2_dev;
- v4l2_dev->mdev = &fmd->media_dev;
- v4l2_dev->notify = fimc_sensor_notify;
- snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s",
- dev_name(&pdev->dev));
-
- ret = v4l2_device_register(&pdev->dev, &fmd->v4l2_dev);
- if (ret < 0) {
- v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
- return ret;
- }
- ret = media_device_register(&fmd->media_dev);
- if (ret < 0) {
- v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret);
- goto err_md;
- }
- ret = fimc_md_get_clocks(fmd);
- if (ret)
- goto err_clk;
-
- fmd->user_subdev_api = false;
-
- /* Protect the media graph while we're registering entities */
- mutex_lock(&fmd->media_dev.graph_mutex);
-
- ret = fimc_md_register_platform_entities(fmd);
- if (ret)
- goto err_unlock;
-
- if (pdev->dev.platform_data) {
- ret = fimc_md_register_sensor_entities(fmd);
- if (ret)
- goto err_unlock;
- }
- ret = fimc_md_create_links(fmd);
- if (ret)
- goto err_unlock;
- ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
- if (ret)
- goto err_unlock;
-
- ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
- if (ret)
- goto err_unlock;
-
- platform_set_drvdata(pdev, fmd);
- mutex_unlock(&fmd->media_dev.graph_mutex);
- return 0;
-
-err_unlock:
- mutex_unlock(&fmd->media_dev.graph_mutex);
-err_clk:
- media_device_unregister(&fmd->media_dev);
- fimc_md_put_clocks(fmd);
- fimc_md_unregister_entities(fmd);
-err_md:
- v4l2_device_unregister(&fmd->v4l2_dev);
- return ret;
-}
-
-static int __devexit fimc_md_remove(struct platform_device *pdev)
-{
- struct fimc_md *fmd = platform_get_drvdata(pdev);
-
- if (!fmd)
- return 0;
- device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
- fimc_md_unregister_entities(fmd);
- media_device_unregister(&fmd->media_dev);
- fimc_md_put_clocks(fmd);
- return 0;
-}
-
-static struct platform_driver fimc_md_driver = {
- .probe = fimc_md_probe,
- .remove = __devexit_p(fimc_md_remove),
- .driver = {
- .name = "s5p-fimc-md",
- .owner = THIS_MODULE,
- }
-};
-
-static int __init fimc_md_init(void)
-{
- int ret;
-
- request_module("s5p-csis");
- ret = fimc_register_driver();
- if (ret)
- return ret;
-
- return platform_driver_register(&fimc_md_driver);
-}
-
-static void __exit fimc_md_exit(void)
-{
- platform_driver_unregister(&fimc_md_driver);
- fimc_unregister_driver();
-}
-
-module_init(fimc_md_init);
-module_exit(fimc_md_exit);
-
-MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
-MODULE_DESCRIPTION("S5P FIMC camera host interface/video postprocessor driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("2.0.1");
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.h b/drivers/media/video/s5p-fimc/fimc-mdevice.h
deleted file mode 100644
index 1f5dbaff544..00000000000
--- a/drivers/media/video/s5p-fimc/fimc-mdevice.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef FIMC_MDEVICE_H_
-#define FIMC_MDEVICE_H_
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-#include <media/media-device.h>
-#include <media/media-entity.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-
-#include "fimc-core.h"
-#include "fimc-lite.h"
-#include "mipi-csis.h"
-
-/* Group IDs of sensor, MIPI-CSIS, FIMC-LITE and the writeback subdevs. */
-#define SENSOR_GROUP_ID (1 << 8)
-#define CSIS_GROUP_ID (1 << 9)
-#define WRITEBACK_GROUP_ID (1 << 10)
-#define FIMC_GROUP_ID (1 << 11)
-#define FLITE_GROUP_ID (1 << 12)
-
-#define FIMC_MAX_SENSORS 8
-#define FIMC_MAX_CAMCLKS 2
-
-struct fimc_csis_info {
- struct v4l2_subdev *sd;
- int id;
-};
-
-struct fimc_camclk_info {
- struct clk *clock;
- int use_count;
- unsigned long frequency;
-};
-
-/**
- * struct fimc_sensor_info - image data source subdev information
- * @pdata: sensor's atrributes passed as media device's platform data
- * @subdev: image sensor v4l2 subdev
- * @host: fimc device the sensor is currently linked to
- *
- * This data structure applies to image sensor and the writeback subdevs.
- */
-struct fimc_sensor_info {
- struct s5p_fimc_isp_info *pdata;
- struct v4l2_subdev *subdev;
- struct fimc_dev *host;
-};
-
-/**
- * struct fimc_md - fimc media device information
- * @csis: MIPI CSIS subdevs data
- * @sensor: array of registered sensor subdevs
- * @num_sensors: actual number of registered sensors
- * @camclk: external sensor clock information
- * @fimc: array of registered fimc devices
- * @media_dev: top level media device
- * @v4l2_dev: top level v4l2_device holding up the subdevs
- * @pdev: platform device this media device is hooked up into
- * @user_subdev_api: true if subdevs are not configured by the host driver
- * @slock: spinlock protecting @sensor array
- */
-struct fimc_md {
- struct fimc_csis_info csis[CSIS_MAX_ENTITIES];
- struct fimc_sensor_info sensor[FIMC_MAX_SENSORS];
- int num_sensors;
- struct fimc_camclk_info camclk[FIMC_MAX_CAMCLKS];
- struct fimc_lite *fimc_lite[FIMC_LITE_MAX_DEVS];
- struct fimc_dev *fimc[FIMC_MAX_DEVS];
- struct media_device media_dev;
- struct v4l2_device v4l2_dev;
- struct platform_device *pdev;
- bool user_subdev_api;
- spinlock_t slock;
-};
-
-#define is_subdev_pad(pad) (pad == NULL || \
- media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV)
-
-#define me_subtype(me) \
- ((me->type) & (MEDIA_ENT_TYPE_MASK | MEDIA_ENT_SUBTYPE_MASK))
-
-#define subdev_has_devnode(__sd) (__sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE)
-
-static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
-{
- return me->parent == NULL ? NULL :
- container_of(me->parent, struct fimc_md, media_dev);
-}
-
-static inline void fimc_md_graph_lock(struct fimc_dev *fimc)
-{
- BUG_ON(fimc->vid_cap.vfd == NULL);
- mutex_lock(&fimc->vid_cap.vfd->entity.parent->graph_mutex);
-}
-
-static inline void fimc_md_graph_unlock(struct fimc_dev *fimc)
-{
- BUG_ON(fimc->vid_cap.vfd == NULL);
- mutex_unlock(&fimc->vid_cap.vfd->entity.parent->graph_mutex);
-}
-
-int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
-void fimc_pipeline_prepare(struct fimc_pipeline *p, struct media_entity *me);
-int fimc_pipeline_initialize(struct fimc_pipeline *p, struct media_entity *me,
- bool resume);
-int fimc_pipeline_shutdown(struct fimc_pipeline *p);
-int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state);
-int fimc_pipeline_s_stream(struct fimc_pipeline *p, bool state);
-
-#endif
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/video/s5p-fimc/fimc-reg.c
deleted file mode 100644
index 0e3eb9ce4f9..00000000000
--- a/drivers/media/video/s5p-fimc/fimc-reg.c
+++ /dev/null
@@ -1,775 +0,0 @@
-/*
- * Register interface file for Samsung Camera Interface (FIMC) driver
- *
- * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki, <s.nawrocki@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <media/s5p_fimc.h>
-
-#include "fimc-reg.h"
-#include "fimc-core.h"
-
-
-void fimc_hw_reset(struct fimc_dev *dev)
-{
- u32 cfg;
-
- cfg = readl(dev->regs + FIMC_REG_CISRCFMT);
- cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
- writel(cfg, dev->regs + FIMC_REG_CISRCFMT);
-
- /* Software reset. */
- cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
- cfg |= (FIMC_REG_CIGCTRL_SWRST | FIMC_REG_CIGCTRL_IRQ_LEVEL);
- writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
- udelay(10);
-
- cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
- cfg &= ~FIMC_REG_CIGCTRL_SWRST;
- writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
-
- if (dev->variant->out_buf_count > 4)
- fimc_hw_set_dma_seq(dev, 0xF);
-}
-
-static u32 fimc_hw_get_in_flip(struct fimc_ctx *ctx)
-{
- u32 flip = FIMC_REG_MSCTRL_FLIP_NORMAL;
-
- if (ctx->hflip)
- flip = FIMC_REG_MSCTRL_FLIP_X_MIRROR;
- if (ctx->vflip)
- flip = FIMC_REG_MSCTRL_FLIP_Y_MIRROR;
-
- if (ctx->rotation <= 90)
- return flip;
-
- return (flip ^ FIMC_REG_MSCTRL_FLIP_180) & FIMC_REG_MSCTRL_FLIP_180;
-}
-
-static u32 fimc_hw_get_target_flip(struct fimc_ctx *ctx)
-{
- u32 flip = FIMC_REG_CITRGFMT_FLIP_NORMAL;
-
- if (ctx->hflip)
- flip |= FIMC_REG_CITRGFMT_FLIP_X_MIRROR;
- if (ctx->vflip)
- flip |= FIMC_REG_CITRGFMT_FLIP_Y_MIRROR;
-
- if (ctx->rotation <= 90)
- return flip;
-
- return (flip ^ FIMC_REG_CITRGFMT_FLIP_180) & FIMC_REG_CITRGFMT_FLIP_180;
-}
-
-void fimc_hw_set_rotation(struct fimc_ctx *ctx)
-{
- u32 cfg, flip;
- struct fimc_dev *dev = ctx->fimc_dev;
-
- cfg = readl(dev->regs + FIMC_REG_CITRGFMT);
- cfg &= ~(FIMC_REG_CITRGFMT_INROT90 | FIMC_REG_CITRGFMT_OUTROT90 |
- FIMC_REG_CITRGFMT_FLIP_180);
-
- /*
- * The input and output rotator cannot work simultaneously.
- * Use the output rotator in output DMA mode or the input rotator
- * in direct fifo output mode.
- */
- if (ctx->rotation == 90 || ctx->rotation == 270) {
- if (ctx->out_path == FIMC_IO_LCDFIFO)
- cfg |= FIMC_REG_CITRGFMT_INROT90;
- else
- cfg |= FIMC_REG_CITRGFMT_OUTROT90;
- }
-
- if (ctx->out_path == FIMC_IO_DMA) {
- cfg |= fimc_hw_get_target_flip(ctx);
- writel(cfg, dev->regs + FIMC_REG_CITRGFMT);
- } else {
- /* LCD FIFO path */
- flip = readl(dev->regs + FIMC_REG_MSCTRL);
- flip &= ~FIMC_REG_MSCTRL_FLIP_MASK;
- flip |= fimc_hw_get_in_flip(ctx);
- writel(flip, dev->regs + FIMC_REG_MSCTRL);
- }
-}
-
-void fimc_hw_set_target_format(struct fimc_ctx *ctx)
-{
- u32 cfg;
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
-
- dbg("w= %d, h= %d color: %d", frame->width,
- frame->height, frame->fmt->color);
-
- cfg = readl(dev->regs + FIMC_REG_CITRGFMT);
- cfg &= ~(FIMC_REG_CITRGFMT_FMT_MASK | FIMC_REG_CITRGFMT_HSIZE_MASK |
- FIMC_REG_CITRGFMT_VSIZE_MASK);
-
- switch (frame->fmt->color) {
- case FIMC_FMT_RGB444...FIMC_FMT_RGB888:
- cfg |= FIMC_REG_CITRGFMT_RGB;
- break;
- case FIMC_FMT_YCBCR420:
- cfg |= FIMC_REG_CITRGFMT_YCBCR420;
- break;
- case FIMC_FMT_YCBYCR422...FIMC_FMT_CRYCBY422:
- if (frame->fmt->colplanes == 1)
- cfg |= FIMC_REG_CITRGFMT_YCBCR422_1P;
- else
- cfg |= FIMC_REG_CITRGFMT_YCBCR422;
- break;
- default:
- break;
- }
-
- if (ctx->rotation == 90 || ctx->rotation == 270)
- cfg |= (frame->height << 16) | frame->width;
- else
- cfg |= (frame->width << 16) | frame->height;
-
- writel(cfg, dev->regs + FIMC_REG_CITRGFMT);
-
- cfg = readl(dev->regs + FIMC_REG_CITAREA);
- cfg &= ~FIMC_REG_CITAREA_MASK;
- cfg |= (frame->width * frame->height);
- writel(cfg, dev->regs + FIMC_REG_CITAREA);
-}
-
-static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
- u32 cfg;
-
- cfg = (frame->f_height << 16) | frame->f_width;
- writel(cfg, dev->regs + FIMC_REG_ORGOSIZE);
-
- /* Select color space conversion equation (HD/SD size).*/
- cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
- if (frame->f_width >= 1280) /* HD */
- cfg |= FIMC_REG_CIGCTRL_CSC_ITU601_709;
- else /* SD */
- cfg &= ~FIMC_REG_CIGCTRL_CSC_ITU601_709;
- writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
-
-}
-
-void fimc_hw_set_out_dma(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
- struct fimc_dma_offset *offset = &frame->dma_offset;
- struct fimc_fmt *fmt = frame->fmt;
- u32 cfg;
-
- /* Set the input dma offsets. */
- cfg = (offset->y_v << 16) | offset->y_h;
- writel(cfg, dev->regs + FIMC_REG_CIOYOFF);
-
- cfg = (offset->cb_v << 16) | offset->cb_h;
- writel(cfg, dev->regs + FIMC_REG_CIOCBOFF);
-
- cfg = (offset->cr_v << 16) | offset->cr_h;
- writel(cfg, dev->regs + FIMC_REG_CIOCROFF);
-
- fimc_hw_set_out_dma_size(ctx);
-
- /* Configure chroma components order. */
- cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
-
- cfg &= ~(FIMC_REG_CIOCTRL_ORDER2P_MASK |
- FIMC_REG_CIOCTRL_ORDER422_MASK |
- FIMC_REG_CIOCTRL_YCBCR_PLANE_MASK |
- FIMC_REG_CIOCTRL_RGB16FMT_MASK);
-
- if (fmt->colplanes == 1)
- cfg |= ctx->out_order_1p;
- else if (fmt->colplanes == 2)
- cfg |= ctx->out_order_2p | FIMC_REG_CIOCTRL_YCBCR_2PLANE;
- else if (fmt->colplanes == 3)
- cfg |= FIMC_REG_CIOCTRL_YCBCR_3PLANE;
-
- if (fmt->color == FIMC_FMT_RGB565)
- cfg |= FIMC_REG_CIOCTRL_RGB565;
- else if (fmt->color == FIMC_FMT_RGB555)
- cfg |= FIMC_REG_CIOCTRL_ARGB1555;
- else if (fmt->color == FIMC_FMT_RGB444)
- cfg |= FIMC_REG_CIOCTRL_ARGB4444;
-
- writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
-}
-
-static void fimc_hw_en_autoload(struct fimc_dev *dev, int enable)
-{
- u32 cfg = readl(dev->regs + FIMC_REG_ORGISIZE);
- if (enable)
- cfg |= FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
- else
- cfg &= ~FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
- writel(cfg, dev->regs + FIMC_REG_ORGISIZE);
-}
-
-void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable)
-{
- u32 cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
- if (enable)
- cfg |= FIMC_REG_CIOCTRL_LASTIRQ_ENABLE;
- else
- cfg &= ~FIMC_REG_CIOCTRL_LASTIRQ_ENABLE;
- writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
-}
-
-void fimc_hw_set_prescaler(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_scaler *sc = &ctx->scaler;
- u32 cfg, shfactor;
-
- shfactor = 10 - (sc->hfactor + sc->vfactor);
- cfg = shfactor << 28;
-
- cfg |= (sc->pre_hratio << 16) | sc->pre_vratio;
- writel(cfg, dev->regs + FIMC_REG_CISCPRERATIO);
-
- cfg = (sc->pre_dst_width << 16) | sc->pre_dst_height;
- writel(cfg, dev->regs + FIMC_REG_CISCPREDST);
-}
-
-static void fimc_hw_set_scaler(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_scaler *sc = &ctx->scaler;
- struct fimc_frame *src_frame = &ctx->s_frame;
- struct fimc_frame *dst_frame = &ctx->d_frame;
-
- u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
-
- cfg &= ~(FIMC_REG_CISCCTRL_CSCR2Y_WIDE | FIMC_REG_CISCCTRL_CSCY2R_WIDE |
- FIMC_REG_CISCCTRL_SCALEUP_H | FIMC_REG_CISCCTRL_SCALEUP_V |
- FIMC_REG_CISCCTRL_SCALERBYPASS | FIMC_REG_CISCCTRL_ONE2ONE |
- FIMC_REG_CISCCTRL_INRGB_FMT_MASK | FIMC_REG_CISCCTRL_OUTRGB_FMT_MASK |
- FIMC_REG_CISCCTRL_INTERLACE | FIMC_REG_CISCCTRL_RGB_EXT);
-
- if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW))
- cfg |= (FIMC_REG_CISCCTRL_CSCR2Y_WIDE |
- FIMC_REG_CISCCTRL_CSCY2R_WIDE);
-
- if (!sc->enabled)
- cfg |= FIMC_REG_CISCCTRL_SCALERBYPASS;
-
- if (sc->scaleup_h)
- cfg |= FIMC_REG_CISCCTRL_SCALEUP_H;
-
- if (sc->scaleup_v)
- cfg |= FIMC_REG_CISCCTRL_SCALEUP_V;
-
- if (sc->copy_mode)
- cfg |= FIMC_REG_CISCCTRL_ONE2ONE;
-
- if (ctx->in_path == FIMC_IO_DMA) {
- switch (src_frame->fmt->color) {
- case FIMC_FMT_RGB565:
- cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB565;
- break;
- case FIMC_FMT_RGB666:
- cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB666;
- break;
- case FIMC_FMT_RGB888:
- cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB888;
- break;
- }
- }
-
- if (ctx->out_path == FIMC_IO_DMA) {
- u32 color = dst_frame->fmt->color;
-
- if (color >= FIMC_FMT_RGB444 && color <= FIMC_FMT_RGB565)
- cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB565;
- else if (color == FIMC_FMT_RGB666)
- cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB666;
- else if (color == FIMC_FMT_RGB888)
- cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888;
- } else {
- cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888;
-
- if (ctx->flags & FIMC_SCAN_MODE_INTERLACED)
- cfg |= FIMC_REG_CISCCTRL_INTERLACE;
- }
-
- writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
-}
-
-void fimc_hw_set_mainscaler(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_variant *variant = dev->variant;
- struct fimc_scaler *sc = &ctx->scaler;
- u32 cfg;
-
- dbg("main_hratio= 0x%X main_vratio= 0x%X",
- sc->main_hratio, sc->main_vratio);
-
- fimc_hw_set_scaler(ctx);
-
- cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
- cfg &= ~(FIMC_REG_CISCCTRL_MHRATIO_MASK |
- FIMC_REG_CISCCTRL_MVRATIO_MASK);
-
- if (variant->has_mainscaler_ext) {
- cfg |= FIMC_REG_CISCCTRL_MHRATIO_EXT(sc->main_hratio);
- cfg |= FIMC_REG_CISCCTRL_MVRATIO_EXT(sc->main_vratio);
- writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
-
- cfg = readl(dev->regs + FIMC_REG_CIEXTEN);
-
- cfg &= ~(FIMC_REG_CIEXTEN_MVRATIO_EXT_MASK |
- FIMC_REG_CIEXTEN_MHRATIO_EXT_MASK);
- cfg |= FIMC_REG_CIEXTEN_MHRATIO_EXT(sc->main_hratio);
- cfg |= FIMC_REG_CIEXTEN_MVRATIO_EXT(sc->main_vratio);
- writel(cfg, dev->regs + FIMC_REG_CIEXTEN);
- } else {
- cfg |= FIMC_REG_CISCCTRL_MHRATIO(sc->main_hratio);
- cfg |= FIMC_REG_CISCCTRL_MVRATIO(sc->main_vratio);
- writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
- }
-}
-
-void fimc_hw_en_capture(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
-
- u32 cfg = readl(dev->regs + FIMC_REG_CIIMGCPT);
-
- if (ctx->out_path == FIMC_IO_DMA) {
- /* one shot mode */
- cfg |= FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE |
- FIMC_REG_CIIMGCPT_IMGCPTEN;
- } else {
- /* Continuous frame capture mode (freerun). */
- cfg &= ~(FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE |
- FIMC_REG_CIIMGCPT_CPT_FRMOD_CNT);
- cfg |= FIMC_REG_CIIMGCPT_IMGCPTEN;
- }
-
- if (ctx->scaler.enabled)
- cfg |= FIMC_REG_CIIMGCPT_IMGCPTEN_SC;
-
- cfg |= FIMC_REG_CIIMGCPT_IMGCPTEN;
- writel(cfg, dev->regs + FIMC_REG_CIIMGCPT);
-}
-
-void fimc_hw_set_effect(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_effect *effect = &ctx->effect;
- u32 cfg = 0;
-
- if (effect->type != FIMC_REG_CIIMGEFF_FIN_BYPASS) {
- cfg |= FIMC_REG_CIIMGEFF_IE_SC_AFTER |
- FIMC_REG_CIIMGEFF_IE_ENABLE;
- cfg |= effect->type;
- if (effect->type == FIMC_REG_CIIMGEFF_FIN_ARBITRARY)
- cfg |= (effect->pat_cb << 13) | effect->pat_cr;
- }
-
- writel(cfg, dev->regs + FIMC_REG_CIIMGEFF);
-}
-
-void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
- u32 cfg;
-
- if (!(frame->fmt->flags & FMT_HAS_ALPHA))
- return;
-
- cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
- cfg &= ~FIMC_REG_CIOCTRL_ALPHA_OUT_MASK;
- cfg |= (frame->alpha << 4);
- writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
-}
-
-static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->s_frame;
- u32 cfg_o = 0;
- u32 cfg_r = 0;
-
- if (FIMC_IO_LCDFIFO == ctx->out_path)
- cfg_r |= FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
-
- cfg_o |= (frame->f_height << 16) | frame->f_width;
- cfg_r |= (frame->height << 16) | frame->width;
-
- writel(cfg_o, dev->regs + FIMC_REG_ORGISIZE);
- writel(cfg_r, dev->regs + FIMC_REG_CIREAL_ISIZE);
-}
-
-void fimc_hw_set_in_dma(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->s_frame;
- struct fimc_dma_offset *offset = &frame->dma_offset;
- u32 cfg;
-
- /* Set the pixel offsets. */
- cfg = (offset->y_v << 16) | offset->y_h;
- writel(cfg, dev->regs + FIMC_REG_CIIYOFF);
-
- cfg = (offset->cb_v << 16) | offset->cb_h;
- writel(cfg, dev->regs + FIMC_REG_CIICBOFF);
-
- cfg = (offset->cr_v << 16) | offset->cr_h;
- writel(cfg, dev->regs + FIMC_REG_CIICROFF);
-
- /* Input original and real size. */
- fimc_hw_set_in_dma_size(ctx);
-
- /* Use DMA autoload only in FIFO mode. */
- fimc_hw_en_autoload(dev, ctx->out_path == FIMC_IO_LCDFIFO);
-
- /* Set the input DMA to process single frame only. */
- cfg = readl(dev->regs + FIMC_REG_MSCTRL);
- cfg &= ~(FIMC_REG_MSCTRL_INFORMAT_MASK
- | FIMC_REG_MSCTRL_IN_BURST_COUNT_MASK
- | FIMC_REG_MSCTRL_INPUT_MASK
- | FIMC_REG_MSCTRL_C_INT_IN_MASK
- | FIMC_REG_MSCTRL_2P_IN_ORDER_MASK);
-
- cfg |= (FIMC_REG_MSCTRL_IN_BURST_COUNT(4)
- | FIMC_REG_MSCTRL_INPUT_MEMORY
- | FIMC_REG_MSCTRL_FIFO_CTRL_FULL);
-
- switch (frame->fmt->color) {
- case FIMC_FMT_RGB565...FIMC_FMT_RGB888:
- cfg |= FIMC_REG_MSCTRL_INFORMAT_RGB;
- break;
- case FIMC_FMT_YCBCR420:
- cfg |= FIMC_REG_MSCTRL_INFORMAT_YCBCR420;
-
- if (frame->fmt->colplanes == 2)
- cfg |= ctx->in_order_2p | FIMC_REG_MSCTRL_C_INT_IN_2PLANE;
- else
- cfg |= FIMC_REG_MSCTRL_C_INT_IN_3PLANE;
-
- break;
- case FIMC_FMT_YCBYCR422...FIMC_FMT_CRYCBY422:
- if (frame->fmt->colplanes == 1) {
- cfg |= ctx->in_order_1p
- | FIMC_REG_MSCTRL_INFORMAT_YCBCR422_1P;
- } else {
- cfg |= FIMC_REG_MSCTRL_INFORMAT_YCBCR422;
-
- if (frame->fmt->colplanes == 2)
- cfg |= ctx->in_order_2p
- | FIMC_REG_MSCTRL_C_INT_IN_2PLANE;
- else
- cfg |= FIMC_REG_MSCTRL_C_INT_IN_3PLANE;
- }
- break;
- default:
- break;
- }
-
- writel(cfg, dev->regs + FIMC_REG_MSCTRL);
-
- /* Input/output DMA linear/tiled mode. */
- cfg = readl(dev->regs + FIMC_REG_CIDMAPARAM);
- cfg &= ~FIMC_REG_CIDMAPARAM_TILE_MASK;
-
- if (tiled_fmt(ctx->s_frame.fmt))
- cfg |= FIMC_REG_CIDMAPARAM_R_64X32;
-
- if (tiled_fmt(ctx->d_frame.fmt))
- cfg |= FIMC_REG_CIDMAPARAM_W_64X32;
-
- writel(cfg, dev->regs + FIMC_REG_CIDMAPARAM);
-}
-
-
-void fimc_hw_set_input_path(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
-
- u32 cfg = readl(dev->regs + FIMC_REG_MSCTRL);
- cfg &= ~FIMC_REG_MSCTRL_INPUT_MASK;
-
- if (ctx->in_path == FIMC_IO_DMA)
- cfg |= FIMC_REG_MSCTRL_INPUT_MEMORY;
- else
- cfg |= FIMC_REG_MSCTRL_INPUT_EXTCAM;
-
- writel(cfg, dev->regs + FIMC_REG_MSCTRL);
-}
-
-void fimc_hw_set_output_path(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
-
- u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
- cfg &= ~FIMC_REG_CISCCTRL_LCDPATHEN_FIFO;
- if (ctx->out_path == FIMC_IO_LCDFIFO)
- cfg |= FIMC_REG_CISCCTRL_LCDPATHEN_FIFO;
- writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
-}
-
-void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *paddr)
-{
- u32 cfg = readl(dev->regs + FIMC_REG_CIREAL_ISIZE);
- cfg |= FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS;
- writel(cfg, dev->regs + FIMC_REG_CIREAL_ISIZE);
-
- writel(paddr->y, dev->regs + FIMC_REG_CIIYSA(0));
- writel(paddr->cb, dev->regs + FIMC_REG_CIICBSA(0));
- writel(paddr->cr, dev->regs + FIMC_REG_CIICRSA(0));
-
- cfg &= ~FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS;
- writel(cfg, dev->regs + FIMC_REG_CIREAL_ISIZE);
-}
-
-void fimc_hw_set_output_addr(struct fimc_dev *dev,
- struct fimc_addr *paddr, int index)
-{
- int i = (index == -1) ? 0 : index;
- do {
- writel(paddr->y, dev->regs + FIMC_REG_CIOYSA(i));
- writel(paddr->cb, dev->regs + FIMC_REG_CIOCBSA(i));
- writel(paddr->cr, dev->regs + FIMC_REG_CIOCRSA(i));
- dbg("dst_buf[%d]: 0x%X, cb: 0x%X, cr: 0x%X",
- i, paddr->y, paddr->cb, paddr->cr);
- } while (index == -1 && ++i < FIMC_MAX_OUT_BUFS);
-}
-
-int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
- struct s5p_fimc_isp_info *cam)
-{
- u32 cfg = readl(fimc->regs + FIMC_REG_CIGCTRL);
-
- cfg &= ~(FIMC_REG_CIGCTRL_INVPOLPCLK | FIMC_REG_CIGCTRL_INVPOLVSYNC |
- FIMC_REG_CIGCTRL_INVPOLHREF | FIMC_REG_CIGCTRL_INVPOLHSYNC |
- FIMC_REG_CIGCTRL_INVPOLFIELD);
-
- if (cam->flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
- cfg |= FIMC_REG_CIGCTRL_INVPOLPCLK;
-
- if (cam->flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
- cfg |= FIMC_REG_CIGCTRL_INVPOLVSYNC;
-
- if (cam->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
- cfg |= FIMC_REG_CIGCTRL_INVPOLHREF;
-
- if (cam->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
- cfg |= FIMC_REG_CIGCTRL_INVPOLHSYNC;
-
- if (cam->flags & V4L2_MBUS_FIELD_EVEN_LOW)
- cfg |= FIMC_REG_CIGCTRL_INVPOLFIELD;
-
- writel(cfg, fimc->regs + FIMC_REG_CIGCTRL);
-
- return 0;
-}
-
-struct mbus_pixfmt_desc {
- u32 pixelcode;
- u32 cisrcfmt;
- u16 bus_width;
-};
-
-static const struct mbus_pixfmt_desc pix_desc[] = {
- { V4L2_MBUS_FMT_YUYV8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCBYCR, 8 },
- { V4L2_MBUS_FMT_YVYU8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCRYCB, 8 },
- { V4L2_MBUS_FMT_VYUY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CRYCBY, 8 },
- { V4L2_MBUS_FMT_UYVY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CBYCRY, 8 },
-};
-
-int fimc_hw_set_camera_source(struct fimc_dev *fimc,
- struct s5p_fimc_isp_info *cam)
-{
- struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame;
- u32 cfg = 0;
- u32 bus_width;
- int i;
-
- if (cam->bus_type == FIMC_ITU_601 || cam->bus_type == FIMC_ITU_656) {
- for (i = 0; i < ARRAY_SIZE(pix_desc); i++) {
- if (fimc->vid_cap.mf.code == pix_desc[i].pixelcode) {
- cfg = pix_desc[i].cisrcfmt;
- bus_width = pix_desc[i].bus_width;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(pix_desc)) {
- v4l2_err(fimc->vid_cap.vfd,
- "Camera color format not supported: %d\n",
- fimc->vid_cap.mf.code);
- return -EINVAL;
- }
-
- if (cam->bus_type == FIMC_ITU_601) {
- if (bus_width == 8)
- cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
- else if (bus_width == 16)
- cfg |= FIMC_REG_CISRCFMT_ITU601_16BIT;
- } /* else defaults to ITU-R BT.656 8-bit */
- } else if (cam->bus_type == FIMC_MIPI_CSI2) {
- if (fimc_fmt_is_jpeg(f->fmt->color))
- cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
- }
-
- cfg |= (f->o_width << 16) | f->o_height;
- writel(cfg, fimc->regs + FIMC_REG_CISRCFMT);
- return 0;
-}
-
-void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f)
-{
- u32 hoff2, voff2;
-
- u32 cfg = readl(fimc->regs + FIMC_REG_CIWDOFST);
-
- cfg &= ~(FIMC_REG_CIWDOFST_HOROFF_MASK | FIMC_REG_CIWDOFST_VEROFF_MASK);
- cfg |= FIMC_REG_CIWDOFST_OFF_EN |
- (f->offs_h << 16) | f->offs_v;
-
- writel(cfg, fimc->regs + FIMC_REG_CIWDOFST);
-
- /* See CIWDOFSTn register description in the datasheet for details. */
- hoff2 = f->o_width - f->width - f->offs_h;
- voff2 = f->o_height - f->height - f->offs_v;
- cfg = (hoff2 << 16) | voff2;
- writel(cfg, fimc->regs + FIMC_REG_CIWDOFST2);
-}
-
-int fimc_hw_set_camera_type(struct fimc_dev *fimc,
- struct s5p_fimc_isp_info *cam)
-{
- u32 cfg, tmp;
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- u32 csis_data_alignment = 32;
-
- cfg = readl(fimc->regs + FIMC_REG_CIGCTRL);
-
- /* Select ITU B interface, disable Writeback path and test pattern. */
- cfg &= ~(FIMC_REG_CIGCTRL_TESTPAT_MASK | FIMC_REG_CIGCTRL_SELCAM_ITU_A |
- FIMC_REG_CIGCTRL_SELCAM_MIPI | FIMC_REG_CIGCTRL_CAMIF_SELWB |
- FIMC_REG_CIGCTRL_SELCAM_MIPI_A | FIMC_REG_CIGCTRL_CAM_JPEG);
-
- switch (cam->bus_type) {
- case FIMC_MIPI_CSI2:
- cfg |= FIMC_REG_CIGCTRL_SELCAM_MIPI;
-
- if (cam->mux_id == 0)
- cfg |= FIMC_REG_CIGCTRL_SELCAM_MIPI_A;
-
- /* TODO: add remaining supported formats. */
- switch (vid_cap->mf.code) {
- case V4L2_MBUS_FMT_VYUY8_2X8:
- tmp = FIMC_REG_CSIIMGFMT_YCBCR422_8BIT;
- break;
- case V4L2_MBUS_FMT_JPEG_1X8:
- tmp = FIMC_REG_CSIIMGFMT_USER(1);
- cfg |= FIMC_REG_CIGCTRL_CAM_JPEG;
- break;
- default:
- v4l2_err(vid_cap->vfd,
- "Not supported camera pixel format: %#x\n",
- vid_cap->mf.code);
- return -EINVAL;
- }
- tmp |= (csis_data_alignment == 32) << 8;
-
- writel(tmp, fimc->regs + FIMC_REG_CSIIMGFMT);
- break;
- case FIMC_ITU_601...FIMC_ITU_656:
- if (cam->mux_id == 0) /* ITU-A, ITU-B: 0, 1 */
- cfg |= FIMC_REG_CIGCTRL_SELCAM_ITU_A;
- break;
- case FIMC_LCD_WB:
- cfg |= FIMC_REG_CIGCTRL_CAMIF_SELWB;
- break;
- default:
- v4l2_err(vid_cap->vfd, "Invalid camera bus type selected\n");
- return -EINVAL;
- }
- writel(cfg, fimc->regs + FIMC_REG_CIGCTRL);
-
- return 0;
-}
-
-void fimc_hw_clear_irq(struct fimc_dev *dev)
-{
- u32 cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
- cfg |= FIMC_REG_CIGCTRL_IRQ_CLR;
- writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
-}
-
-void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on)
-{
- u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
- if (on)
- cfg |= FIMC_REG_CISCCTRL_SCALERSTART;
- else
- cfg &= ~FIMC_REG_CISCCTRL_SCALERSTART;
- writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
-}
-
-void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on)
-{
- u32 cfg = readl(dev->regs + FIMC_REG_MSCTRL);
- if (on)
- cfg |= FIMC_REG_MSCTRL_ENVID;
- else
- cfg &= ~FIMC_REG_MSCTRL_ENVID;
- writel(cfg, dev->regs + FIMC_REG_MSCTRL);
-}
-
-void fimc_hw_dis_capture(struct fimc_dev *dev)
-{
- u32 cfg = readl(dev->regs + FIMC_REG_CIIMGCPT);
- cfg &= ~(FIMC_REG_CIIMGCPT_IMGCPTEN | FIMC_REG_CIIMGCPT_IMGCPTEN_SC);
- writel(cfg, dev->regs + FIMC_REG_CIIMGCPT);
-}
-
-/* Return an index to the buffer actually being written. */
-u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
-{
- u32 reg;
-
- if (dev->variant->has_cistatus2) {
- reg = readl(dev->regs + FIMC_REG_CISTATUS2) & 0x3F;
- return reg > 0 ? --reg : reg;
- }
-
- reg = readl(dev->regs + FIMC_REG_CISTATUS);
-
- return (reg & FIMC_REG_CISTATUS_FRAMECNT_MASK) >>
- FIMC_REG_CISTATUS_FRAMECNT_SHIFT;
-}
-
-/* Locking: the caller holds fimc->slock */
-void fimc_activate_capture(struct fimc_ctx *ctx)
-{
- fimc_hw_enable_scaler(ctx->fimc_dev, ctx->scaler.enabled);
- fimc_hw_en_capture(ctx);
-}
-
-void fimc_deactivate_capture(struct fimc_dev *fimc)
-{
- fimc_hw_en_lastirq(fimc, true);
- fimc_hw_dis_capture(fimc);
- fimc_hw_enable_scaler(fimc, false);
- fimc_hw_en_lastirq(fimc, false);
-}
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.h b/drivers/media/video/s5p-fimc/fimc-reg.h
deleted file mode 100644
index 579ac8ac03d..00000000000
--- a/drivers/media/video/s5p-fimc/fimc-reg.h
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Samsung camera host interface (FIMC) registers definition
- *
- * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef FIMC_REG_H_
-#define FIMC_REG_H_
-
-#include "fimc-core.h"
-
-/* Input source format */
-#define FIMC_REG_CISRCFMT 0x00
-#define FIMC_REG_CISRCFMT_ITU601_8BIT (1 << 31)
-#define FIMC_REG_CISRCFMT_ITU601_16BIT (1 << 29)
-#define FIMC_REG_CISRCFMT_ORDER422_YCBYCR (0 << 14)
-#define FIMC_REG_CISRCFMT_ORDER422_YCRYCB (1 << 14)
-#define FIMC_REG_CISRCFMT_ORDER422_CBYCRY (2 << 14)
-#define FIMC_REG_CISRCFMT_ORDER422_CRYCBY (3 << 14)
-
-/* Window offset */
-#define FIMC_REG_CIWDOFST 0x04
-#define FIMC_REG_CIWDOFST_OFF_EN (1 << 31)
-#define FIMC_REG_CIWDOFST_CLROVFIY (1 << 30)
-#define FIMC_REG_CIWDOFST_CLROVRLB (1 << 29)
-#define FIMC_REG_CIWDOFST_HOROFF_MASK (0x7ff << 16)
-#define FIMC_REG_CIWDOFST_CLROVFICB (1 << 15)
-#define FIMC_REG_CIWDOFST_CLROVFICR (1 << 14)
-#define FIMC_REG_CIWDOFST_VEROFF_MASK (0xfff << 0)
-
-/* Global control */
-#define FIMC_REG_CIGCTRL 0x08
-#define FIMC_REG_CIGCTRL_SWRST (1 << 31)
-#define FIMC_REG_CIGCTRL_CAMRST_A (1 << 30)
-#define FIMC_REG_CIGCTRL_SELCAM_ITU_A (1 << 29)
-#define FIMC_REG_CIGCTRL_TESTPAT_NORMAL (0 << 27)
-#define FIMC_REG_CIGCTRL_TESTPAT_COLOR_BAR (1 << 27)
-#define FIMC_REG_CIGCTRL_TESTPAT_HOR_INC (2 << 27)
-#define FIMC_REG_CIGCTRL_TESTPAT_VER_INC (3 << 27)
-#define FIMC_REG_CIGCTRL_TESTPAT_MASK (3 << 27)
-#define FIMC_REG_CIGCTRL_TESTPAT_SHIFT 27
-#define FIMC_REG_CIGCTRL_INVPOLPCLK (1 << 26)
-#define FIMC_REG_CIGCTRL_INVPOLVSYNC (1 << 25)
-#define FIMC_REG_CIGCTRL_INVPOLHREF (1 << 24)
-#define FIMC_REG_CIGCTRL_IRQ_OVFEN (1 << 22)
-#define FIMC_REG_CIGCTRL_HREF_MASK (1 << 21)
-#define FIMC_REG_CIGCTRL_IRQ_LEVEL (1 << 20)
-#define FIMC_REG_CIGCTRL_IRQ_CLR (1 << 19)
-#define FIMC_REG_CIGCTRL_IRQ_ENABLE (1 << 16)
-#define FIMC_REG_CIGCTRL_SHDW_DISABLE (1 << 12)
-#define FIMC_REG_CIGCTRL_CAM_JPEG (1 << 8)
-#define FIMC_REG_CIGCTRL_SELCAM_MIPI_A (1 << 7)
-#define FIMC_REG_CIGCTRL_CAMIF_SELWB (1 << 6)
-/* 0 - ITU601; 1 - ITU709 */
-#define FIMC_REG_CIGCTRL_CSC_ITU601_709 (1 << 5)
-#define FIMC_REG_CIGCTRL_INVPOLHSYNC (1 << 4)
-#define FIMC_REG_CIGCTRL_SELCAM_MIPI (1 << 3)
-#define FIMC_REG_CIGCTRL_INVPOLFIELD (1 << 1)
-#define FIMC_REG_CIGCTRL_INTERLACE (1 << 0)
-
-/* Window offset 2 */
-#define FIMC_REG_CIWDOFST2 0x14
-#define FIMC_REG_CIWDOFST2_HOROFF_MASK (0xfff << 16)
-#define FIMC_REG_CIWDOFST2_VEROFF_MASK (0xfff << 0)
-
-/* Output DMA Y/Cb/Cr plane start addresses */
-#define FIMC_REG_CIOYSA(n) (0x18 + (n) * 4)
-#define FIMC_REG_CIOCBSA(n) (0x28 + (n) * 4)
-#define FIMC_REG_CIOCRSA(n) (0x38 + (n) * 4)
-
-/* Target image format */
-#define FIMC_REG_CITRGFMT 0x48
-#define FIMC_REG_CITRGFMT_INROT90 (1 << 31)
-#define FIMC_REG_CITRGFMT_YCBCR420 (0 << 29)
-#define FIMC_REG_CITRGFMT_YCBCR422 (1 << 29)
-#define FIMC_REG_CITRGFMT_YCBCR422_1P (2 << 29)
-#define FIMC_REG_CITRGFMT_RGB (3 << 29)
-#define FIMC_REG_CITRGFMT_FMT_MASK (3 << 29)
-#define FIMC_REG_CITRGFMT_HSIZE_MASK (0xfff << 16)
-#define FIMC_REG_CITRGFMT_FLIP_SHIFT 14
-#define FIMC_REG_CITRGFMT_FLIP_NORMAL (0 << 14)
-#define FIMC_REG_CITRGFMT_FLIP_X_MIRROR (1 << 14)
-#define FIMC_REG_CITRGFMT_FLIP_Y_MIRROR (2 << 14)
-#define FIMC_REG_CITRGFMT_FLIP_180 (3 << 14)
-#define FIMC_REG_CITRGFMT_FLIP_MASK (3 << 14)
-#define FIMC_REG_CITRGFMT_OUTROT90 (1 << 13)
-#define FIMC_REG_CITRGFMT_VSIZE_MASK (0xfff << 0)
-
-/* Output DMA control */
-#define FIMC_REG_CIOCTRL 0x4c
-#define FIMC_REG_CIOCTRL_ORDER422_MASK (3 << 0)
-#define FIMC_REG_CIOCTRL_ORDER422_CRYCBY (0 << 0)
-#define FIMC_REG_CIOCTRL_ORDER422_CBYCRY (1 << 0)
-#define FIMC_REG_CIOCTRL_ORDER422_YCRYCB (2 << 0)
-#define FIMC_REG_CIOCTRL_ORDER422_YCBYCR (3 << 0)
-#define FIMC_REG_CIOCTRL_LASTIRQ_ENABLE (1 << 2)
-#define FIMC_REG_CIOCTRL_YCBCR_3PLANE (0 << 3)
-#define FIMC_REG_CIOCTRL_YCBCR_2PLANE (1 << 3)
-#define FIMC_REG_CIOCTRL_YCBCR_PLANE_MASK (1 << 3)
-#define FIMC_REG_CIOCTRL_ALPHA_OUT_MASK (0xff << 4)
-#define FIMC_REG_CIOCTRL_RGB16FMT_MASK (3 << 16)
-#define FIMC_REG_CIOCTRL_RGB565 (0 << 16)
-#define FIMC_REG_CIOCTRL_ARGB1555 (1 << 16)
-#define FIMC_REG_CIOCTRL_ARGB4444 (2 << 16)
-#define FIMC_REG_CIOCTRL_ORDER2P_SHIFT 24
-#define FIMC_REG_CIOCTRL_ORDER2P_MASK (3 << 24)
-#define FIMC_REG_CIOCTRL_ORDER422_2P_LSB_CRCB (0 << 24)
-
-/* Pre-scaler control 1 */
-#define FIMC_REG_CISCPRERATIO 0x50
-
-#define FIMC_REG_CISCPREDST 0x54
-
-/* Main scaler control */
-#define FIMC_REG_CISCCTRL 0x58
-#define FIMC_REG_CISCCTRL_SCALERBYPASS (1 << 31)
-#define FIMC_REG_CISCCTRL_SCALEUP_H (1 << 30)
-#define FIMC_REG_CISCCTRL_SCALEUP_V (1 << 29)
-#define FIMC_REG_CISCCTRL_CSCR2Y_WIDE (1 << 28)
-#define FIMC_REG_CISCCTRL_CSCY2R_WIDE (1 << 27)
-#define FIMC_REG_CISCCTRL_LCDPATHEN_FIFO (1 << 26)
-#define FIMC_REG_CISCCTRL_INTERLACE (1 << 25)
-#define FIMC_REG_CISCCTRL_SCALERSTART (1 << 15)
-#define FIMC_REG_CISCCTRL_INRGB_FMT_RGB565 (0 << 13)
-#define FIMC_REG_CISCCTRL_INRGB_FMT_RGB666 (1 << 13)
-#define FIMC_REG_CISCCTRL_INRGB_FMT_RGB888 (2 << 13)
-#define FIMC_REG_CISCCTRL_INRGB_FMT_MASK (3 << 13)
-#define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB565 (0 << 11)
-#define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB666 (1 << 11)
-#define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888 (2 << 11)
-#define FIMC_REG_CISCCTRL_OUTRGB_FMT_MASK (3 << 11)
-#define FIMC_REG_CISCCTRL_RGB_EXT (1 << 10)
-#define FIMC_REG_CISCCTRL_ONE2ONE (1 << 9)
-#define FIMC_REG_CISCCTRL_MHRATIO(x) ((x) << 16)
-#define FIMC_REG_CISCCTRL_MVRATIO(x) ((x) << 0)
-#define FIMC_REG_CISCCTRL_MHRATIO_MASK (0x1ff << 16)
-#define FIMC_REG_CISCCTRL_MVRATIO_MASK (0x1ff << 0)
-#define FIMC_REG_CISCCTRL_MHRATIO_EXT(x) (((x) >> 6) << 16)
-#define FIMC_REG_CISCCTRL_MVRATIO_EXT(x) (((x) >> 6) << 0)
-
-/* Target area */
-#define FIMC_REG_CITAREA 0x5c
-#define FIMC_REG_CITAREA_MASK 0x0fffffff
-
-/* General status */
-#define FIMC_REG_CISTATUS 0x64
-#define FIMC_REG_CISTATUS_OVFIY (1 << 31)
-#define FIMC_REG_CISTATUS_OVFICB (1 << 30)
-#define FIMC_REG_CISTATUS_OVFICR (1 << 29)
-#define FIMC_REG_CISTATUS_VSYNC (1 << 28)
-#define FIMC_REG_CISTATUS_FRAMECNT_MASK (3 << 26)
-#define FIMC_REG_CISTATUS_FRAMECNT_SHIFT 26
-#define FIMC_REG_CISTATUS_WINOFF_EN (1 << 25)
-#define FIMC_REG_CISTATUS_IMGCPT_EN (1 << 22)
-#define FIMC_REG_CISTATUS_IMGCPT_SCEN (1 << 21)
-#define FIMC_REG_CISTATUS_VSYNC_A (1 << 20)
-#define FIMC_REG_CISTATUS_VSYNC_B (1 << 19)
-#define FIMC_REG_CISTATUS_OVRLB (1 << 18)
-#define FIMC_REG_CISTATUS_FRAME_END (1 << 17)
-#define FIMC_REG_CISTATUS_LASTCAPT_END (1 << 16)
-#define FIMC_REG_CISTATUS_VVALID_A (1 << 15)
-#define FIMC_REG_CISTATUS_VVALID_B (1 << 14)
-
-/* Indexes to the last and the currently processed buffer. */
-#define FIMC_REG_CISTATUS2 0x68
-
-/* Image capture control */
-#define FIMC_REG_CIIMGCPT 0xc0
-#define FIMC_REG_CIIMGCPT_IMGCPTEN (1 << 31)
-#define FIMC_REG_CIIMGCPT_IMGCPTEN_SC (1 << 30)
-#define FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE (1 << 25)
-#define FIMC_REG_CIIMGCPT_CPT_FRMOD_CNT (1 << 18)
-
-/* Frame capture sequence */
-#define FIMC_REG_CICPTSEQ 0xc4
-
-/* Image effect */
-#define FIMC_REG_CIIMGEFF 0xd0
-#define FIMC_REG_CIIMGEFF_IE_ENABLE (1 << 30)
-#define FIMC_REG_CIIMGEFF_IE_SC_BEFORE (0 << 29)
-#define FIMC_REG_CIIMGEFF_IE_SC_AFTER (1 << 29)
-#define FIMC_REG_CIIMGEFF_FIN_BYPASS (0 << 26)
-#define FIMC_REG_CIIMGEFF_FIN_ARBITRARY (1 << 26)
-#define FIMC_REG_CIIMGEFF_FIN_NEGATIVE (2 << 26)
-#define FIMC_REG_CIIMGEFF_FIN_ARTFREEZE (3 << 26)
-#define FIMC_REG_CIIMGEFF_FIN_EMBOSSING (4 << 26)
-#define FIMC_REG_CIIMGEFF_FIN_SILHOUETTE (5 << 26)
-#define FIMC_REG_CIIMGEFF_FIN_MASK (7 << 26)
-#define FIMC_REG_CIIMGEFF_PAT_CBCR_MASK ((0xff << 13) | 0xff)
-
-/* Input DMA Y/Cb/Cr plane start address 0/1 */
-#define FIMC_REG_CIIYSA(n) (0xd4 + (n) * 0x70)
-#define FIMC_REG_CIICBSA(n) (0xd8 + (n) * 0x70)
-#define FIMC_REG_CIICRSA(n) (0xdc + (n) * 0x70)
-
-/* Real input DMA image size */
-#define FIMC_REG_CIREAL_ISIZE 0xf8
-#define FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN (1 << 31)
-#define FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS (1 << 30)
-
-/* Input DMA control */
-#define FIMC_REG_MSCTRL 0xfc
-#define FIMC_REG_MSCTRL_IN_BURST_COUNT_MASK (0xf << 24)
-#define FIMC_REG_MSCTRL_2P_IN_ORDER_MASK (3 << 16)
-#define FIMC_REG_MSCTRL_2P_IN_ORDER_SHIFT 16
-#define FIMC_REG_MSCTRL_C_INT_IN_3PLANE (0 << 15)
-#define FIMC_REG_MSCTRL_C_INT_IN_2PLANE (1 << 15)
-#define FIMC_REG_MSCTRL_C_INT_IN_MASK (1 << 15)
-#define FIMC_REG_MSCTRL_FLIP_SHIFT 13
-#define FIMC_REG_MSCTRL_FLIP_MASK (3 << 13)
-#define FIMC_REG_MSCTRL_FLIP_NORMAL (0 << 13)
-#define FIMC_REG_MSCTRL_FLIP_X_MIRROR (1 << 13)
-#define FIMC_REG_MSCTRL_FLIP_Y_MIRROR (2 << 13)
-#define FIMC_REG_MSCTRL_FLIP_180 (3 << 13)
-#define FIMC_REG_MSCTRL_FIFO_CTRL_FULL (1 << 12)
-#define FIMC_REG_MSCTRL_ORDER422_SHIFT 4
-#define FIMC_REG_MSCTRL_ORDER422_YCBYCR (0 << 4)
-#define FIMC_REG_MSCTRL_ORDER422_CBYCRY (1 << 4)
-#define FIMC_REG_MSCTRL_ORDER422_YCRYCB (2 << 4)
-#define FIMC_REG_MSCTRL_ORDER422_CRYCBY (3 << 4)
-#define FIMC_REG_MSCTRL_ORDER422_MASK (3 << 4)
-#define FIMC_REG_MSCTRL_INPUT_EXTCAM (0 << 3)
-#define FIMC_REG_MSCTRL_INPUT_MEMORY (1 << 3)
-#define FIMC_REG_MSCTRL_INPUT_MASK (1 << 3)
-#define FIMC_REG_MSCTRL_INFORMAT_YCBCR420 (0 << 1)
-#define FIMC_REG_MSCTRL_INFORMAT_YCBCR422 (1 << 1)
-#define FIMC_REG_MSCTRL_INFORMAT_YCBCR422_1P (2 << 1)
-#define FIMC_REG_MSCTRL_INFORMAT_RGB (3 << 1)
-#define FIMC_REG_MSCTRL_INFORMAT_MASK (3 << 1)
-#define FIMC_REG_MSCTRL_ENVID (1 << 0)
-#define FIMC_REG_MSCTRL_IN_BURST_COUNT(x) ((x) << 24)
-
-/* Output DMA Y/Cb/Cr offset */
-#define FIMC_REG_CIOYOFF 0x168
-#define FIMC_REG_CIOCBOFF 0x16c
-#define FIMC_REG_CIOCROFF 0x170
-
-/* Input DMA Y/Cb/Cr offset */
-#define FIMC_REG_CIIYOFF 0x174
-#define FIMC_REG_CIICBOFF 0x178
-#define FIMC_REG_CIICROFF 0x17c
-
-/* Input DMA original image size */
-#define FIMC_REG_ORGISIZE 0x180
-
-/* Output DMA original image size */
-#define FIMC_REG_ORGOSIZE 0x184
-
-/* Real output DMA image size (extension register) */
-#define FIMC_REG_CIEXTEN 0x188
-#define FIMC_REG_CIEXTEN_MHRATIO_EXT(x) (((x) & 0x3f) << 10)
-#define FIMC_REG_CIEXTEN_MVRATIO_EXT(x) ((x) & 0x3f)
-#define FIMC_REG_CIEXTEN_MHRATIO_EXT_MASK (0x3f << 10)
-#define FIMC_REG_CIEXTEN_MVRATIO_EXT_MASK 0x3f
-
-#define FIMC_REG_CIDMAPARAM 0x18c
-#define FIMC_REG_CIDMAPARAM_R_LINEAR (0 << 29)
-#define FIMC_REG_CIDMAPARAM_R_64X32 (3 << 29)
-#define FIMC_REG_CIDMAPARAM_W_LINEAR (0 << 13)
-#define FIMC_REG_CIDMAPARAM_W_64X32 (3 << 13)
-#define FIMC_REG_CIDMAPARAM_TILE_MASK ((3 << 29) | (3 << 13))
-
-/* MIPI CSI image format */
-#define FIMC_REG_CSIIMGFMT 0x194
-#define FIMC_REG_CSIIMGFMT_YCBCR422_8BIT 0x1e
-#define FIMC_REG_CSIIMGFMT_RAW8 0x2a
-#define FIMC_REG_CSIIMGFMT_RAW10 0x2b
-#define FIMC_REG_CSIIMGFMT_RAW12 0x2c
-/* User defined formats. x = 0...16. */
-#define FIMC_REG_CSIIMGFMT_USER(x) (0x30 + x - 1)
-
-/* Output frame buffer sequence mask */
-#define FIMC_REG_CIFCNTSEQ 0x1fc
-
-/*
- * Function declarations
- */
-void fimc_hw_reset(struct fimc_dev *fimc);
-void fimc_hw_set_rotation(struct fimc_ctx *ctx);
-void fimc_hw_set_target_format(struct fimc_ctx *ctx);
-void fimc_hw_set_out_dma(struct fimc_ctx *ctx);
-void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable);
-void fimc_hw_en_irq(struct fimc_dev *fimc, int enable);
-void fimc_hw_set_prescaler(struct fimc_ctx *ctx);
-void fimc_hw_set_mainscaler(struct fimc_ctx *ctx);
-void fimc_hw_en_capture(struct fimc_ctx *ctx);
-void fimc_hw_set_effect(struct fimc_ctx *ctx);
-void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx);
-void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
-void fimc_hw_set_input_path(struct fimc_ctx *ctx);
-void fimc_hw_set_output_path(struct fimc_ctx *ctx);
-void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *paddr);
-void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *paddr,
- int index);
-int fimc_hw_set_camera_source(struct fimc_dev *fimc,
- struct s5p_fimc_isp_info *cam);
-void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f);
-int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
- struct s5p_fimc_isp_info *cam);
-int fimc_hw_set_camera_type(struct fimc_dev *fimc,
- struct s5p_fimc_isp_info *cam);
-void fimc_hw_clear_irq(struct fimc_dev *dev);
-void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on);
-void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on);
-void fimc_hw_dis_capture(struct fimc_dev *dev);
-u32 fimc_hw_get_frame_index(struct fimc_dev *dev);
-void fimc_activate_capture(struct fimc_ctx *ctx);
-void fimc_deactivate_capture(struct fimc_dev *fimc);
-
-/**
- * fimc_hw_set_dma_seq - configure output DMA buffer sequence
- * @mask: bitmask for the DMA output buffer registers, set to 0 to skip buffer
- * This function masks output DMA ring buffers, it allows to select which of
- * the 32 available output buffer address registers will be used by the DMA
- * engine.
- */
-static inline void fimc_hw_set_dma_seq(struct fimc_dev *dev, u32 mask)
-{
- writel(mask, dev->regs + FIMC_REG_CIFCNTSEQ);
-}
-
-#endif /* FIMC_REG_H_ */
diff --git a/drivers/media/video/s5p-fimc/mipi-csis.c b/drivers/media/video/s5p-fimc/mipi-csis.c
deleted file mode 100644
index 5e898432883..00000000000
--- a/drivers/media/video/s5p-fimc/mipi-csis.c
+++ /dev/null
@@ -1,722 +0,0 @@
-/*
- * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
- *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki, <s.nawrocki@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/memory.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-subdev.h>
-#include <linux/platform_data/mipi-csis.h>
-#include "mipi-csis.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-/* Register map definition */
-
-/* CSIS global control */
-#define S5PCSIS_CTRL 0x00
-#define S5PCSIS_CTRL_DPDN_DEFAULT (0 << 31)
-#define S5PCSIS_CTRL_DPDN_SWAP (1 << 31)
-#define S5PCSIS_CTRL_ALIGN_32BIT (1 << 20)
-#define S5PCSIS_CTRL_UPDATE_SHADOW (1 << 16)
-#define S5PCSIS_CTRL_WCLK_EXTCLK (1 << 8)
-#define S5PCSIS_CTRL_RESET (1 << 4)
-#define S5PCSIS_CTRL_ENABLE (1 << 0)
-
-/* D-PHY control */
-#define S5PCSIS_DPHYCTRL 0x04
-#define S5PCSIS_DPHYCTRL_HSS_MASK (0x1f << 27)
-#define S5PCSIS_DPHYCTRL_ENABLE (0x1f << 0)
-
-#define S5PCSIS_CONFIG 0x08
-#define S5PCSIS_CFG_FMT_YCBCR422_8BIT (0x1e << 2)
-#define S5PCSIS_CFG_FMT_RAW8 (0x2a << 2)
-#define S5PCSIS_CFG_FMT_RAW10 (0x2b << 2)
-#define S5PCSIS_CFG_FMT_RAW12 (0x2c << 2)
-/* User defined formats, x = 1...4 */
-#define S5PCSIS_CFG_FMT_USER(x) ((0x30 + x - 1) << 2)
-#define S5PCSIS_CFG_FMT_MASK (0x3f << 2)
-#define S5PCSIS_CFG_NR_LANE_MASK 3
-
-/* Interrupt mask. */
-#define S5PCSIS_INTMSK 0x10
-#define S5PCSIS_INTMSK_EN_ALL 0xf000003f
-#define S5PCSIS_INTSRC 0x14
-
-/* Pixel resolution */
-#define S5PCSIS_RESOL 0x2c
-#define CSIS_MAX_PIX_WIDTH 0xffff
-#define CSIS_MAX_PIX_HEIGHT 0xffff
-
-enum {
- CSIS_CLK_MUX,
- CSIS_CLK_GATE,
-};
-
-static char *csi_clock_name[] = {
- [CSIS_CLK_MUX] = "sclk_csis",
- [CSIS_CLK_GATE] = "csis",
-};
-#define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name)
-
-static const char * const csis_supply_name[] = {
- "vdd11", /* 1.1V or 1.2V (s5pc100) MIPI CSI suppply */
- "vdd18", /* VDD 1.8V and MIPI CSI PLL supply */
-};
-#define CSIS_NUM_SUPPLIES ARRAY_SIZE(csis_supply_name)
-
-enum {
- ST_POWERED = 1,
- ST_STREAMING = 2,
- ST_SUSPENDED = 4,
-};
-
-/**
- * struct csis_state - the driver's internal state data structure
- * @lock: mutex serializing the subdev and power management operations,
- * protecting @format and @flags members
- * @pads: CSIS pads array
- * @sd: v4l2_subdev associated with CSIS device instance
- * @pdev: CSIS platform device
- * @regs: mmaped I/O registers memory
- * @clock: CSIS clocks
- * @irq: requested s5p-mipi-csis irq number
- * @flags: the state variable for power and streaming control
- * @csis_fmt: current CSIS pixel format
- * @format: common media bus format for the source and sink pad
- */
-struct csis_state {
- struct mutex lock;
- struct media_pad pads[CSIS_PADS_NUM];
- struct v4l2_subdev sd;
- struct platform_device *pdev;
- void __iomem *regs;
- struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
- struct clk *clock[NUM_CSIS_CLOCKS];
- int irq;
- u32 flags;
- const struct csis_pix_format *csis_fmt;
- struct v4l2_mbus_framefmt format;
-};
-
-/**
- * struct csis_pix_format - CSIS pixel format description
- * @pix_width_alignment: horizontal pixel alignment, width will be
- * multiple of 2^pix_width_alignment
- * @code: corresponding media bus code
- * @fmt_reg: S5PCSIS_CONFIG register value
- * @data_alignment: MIPI-CSI data alignment in bits
- */
-struct csis_pix_format {
- unsigned int pix_width_alignment;
- enum v4l2_mbus_pixelcode code;
- u32 fmt_reg;
- u8 data_alignment;
-};
-
-static const struct csis_pix_format s5pcsis_formats[] = {
- {
- .code = V4L2_MBUS_FMT_VYUY8_2X8,
- .fmt_reg = S5PCSIS_CFG_FMT_YCBCR422_8BIT,
- .data_alignment = 32,
- }, {
- .code = V4L2_MBUS_FMT_JPEG_1X8,
- .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
- .data_alignment = 32,
- },
-};
-
-#define s5pcsis_write(__csis, __r, __v) writel(__v, __csis->regs + __r)
-#define s5pcsis_read(__csis, __r) readl(__csis->regs + __r)
-
-static struct csis_state *sd_to_csis_state(struct v4l2_subdev *sdev)
-{
- return container_of(sdev, struct csis_state, sd);
-}
-
-static const struct csis_pix_format *find_csis_format(
- struct v4l2_mbus_framefmt *mf)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(s5pcsis_formats); i++)
- if (mf->code == s5pcsis_formats[i].code)
- return &s5pcsis_formats[i];
- return NULL;
-}
-
-static void s5pcsis_enable_interrupts(struct csis_state *state, bool on)
-{
- u32 val = s5pcsis_read(state, S5PCSIS_INTMSK);
-
- val = on ? val | S5PCSIS_INTMSK_EN_ALL :
- val & ~S5PCSIS_INTMSK_EN_ALL;
- s5pcsis_write(state, S5PCSIS_INTMSK, val);
-}
-
-static void s5pcsis_reset(struct csis_state *state)
-{
- u32 val = s5pcsis_read(state, S5PCSIS_CTRL);
-
- s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_RESET);
- udelay(10);
-}
-
-static void s5pcsis_system_enable(struct csis_state *state, int on)
-{
- u32 val;
-
- val = s5pcsis_read(state, S5PCSIS_CTRL);
- if (on)
- val |= S5PCSIS_CTRL_ENABLE;
- else
- val &= ~S5PCSIS_CTRL_ENABLE;
- s5pcsis_write(state, S5PCSIS_CTRL, val);
-
- val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
- if (on)
- val |= S5PCSIS_DPHYCTRL_ENABLE;
- else
- val &= ~S5PCSIS_DPHYCTRL_ENABLE;
- s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
-}
-
-/* Called with the state.lock mutex held */
-static void __s5pcsis_set_format(struct csis_state *state)
-{
- struct v4l2_mbus_framefmt *mf = &state->format;
- u32 val;
-
- v4l2_dbg(1, debug, &state->sd, "fmt: %d, %d x %d\n",
- mf->code, mf->width, mf->height);
-
- /* Color format */
- val = s5pcsis_read(state, S5PCSIS_CONFIG);
- val = (val & ~S5PCSIS_CFG_FMT_MASK) | state->csis_fmt->fmt_reg;
- s5pcsis_write(state, S5PCSIS_CONFIG, val);
-
- /* Pixel resolution */
- val = (mf->width << 16) | mf->height;
- s5pcsis_write(state, S5PCSIS_RESOL, val);
-}
-
-static void s5pcsis_set_hsync_settle(struct csis_state *state, int settle)
-{
- u32 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
-
- val = (val & ~S5PCSIS_DPHYCTRL_HSS_MASK) | (settle << 27);
- s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
-}
-
-static void s5pcsis_set_params(struct csis_state *state)
-{
- struct s5p_platform_mipi_csis *pdata = state->pdev->dev.platform_data;
- u32 val;
-
- val = s5pcsis_read(state, S5PCSIS_CONFIG);
- val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (pdata->lanes - 1);
- s5pcsis_write(state, S5PCSIS_CONFIG, val);
-
- __s5pcsis_set_format(state);
- s5pcsis_set_hsync_settle(state, pdata->hs_settle);
-
- val = s5pcsis_read(state, S5PCSIS_CTRL);
- if (state->csis_fmt->data_alignment == 32)
- val |= S5PCSIS_CTRL_ALIGN_32BIT;
- else /* 24-bits */
- val &= ~S5PCSIS_CTRL_ALIGN_32BIT;
- /* Not using external clock. */
- val &= ~S5PCSIS_CTRL_WCLK_EXTCLK;
- s5pcsis_write(state, S5PCSIS_CTRL, val);
-
- /* Update the shadow register. */
- val = s5pcsis_read(state, S5PCSIS_CTRL);
- s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_UPDATE_SHADOW);
-}
-
-static void s5pcsis_clk_put(struct csis_state *state)
-{
- int i;
-
- for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
- if (IS_ERR_OR_NULL(state->clock[i]))
- continue;
- clk_unprepare(state->clock[i]);
- clk_put(state->clock[i]);
- state->clock[i] = NULL;
- }
-}
-
-static int s5pcsis_clk_get(struct csis_state *state)
-{
- struct device *dev = &state->pdev->dev;
- int i, ret;
-
- for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
- state->clock[i] = clk_get(dev, csi_clock_name[i]);
- if (IS_ERR(state->clock[i]))
- goto err;
- ret = clk_prepare(state->clock[i]);
- if (ret < 0) {
- clk_put(state->clock[i]);
- state->clock[i] = NULL;
- goto err;
- }
- }
- return 0;
-err:
- s5pcsis_clk_put(state);
- dev_err(dev, "failed to get clock: %s\n", csi_clock_name[i]);
- return -ENXIO;
-}
-
-static int s5pcsis_s_power(struct v4l2_subdev *sd, int on)
-{
- struct csis_state *state = sd_to_csis_state(sd);
- struct device *dev = &state->pdev->dev;
-
- if (on)
- return pm_runtime_get_sync(dev);
-
- return pm_runtime_put_sync(dev);
-}
-
-static void s5pcsis_start_stream(struct csis_state *state)
-{
- s5pcsis_reset(state);
- s5pcsis_set_params(state);
- s5pcsis_system_enable(state, true);
- s5pcsis_enable_interrupts(state, true);
-}
-
-static void s5pcsis_stop_stream(struct csis_state *state)
-{
- s5pcsis_enable_interrupts(state, false);
- s5pcsis_system_enable(state, false);
-}
-
-/* v4l2_subdev operations */
-static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct csis_state *state = sd_to_csis_state(sd);
- int ret = 0;
-
- v4l2_dbg(1, debug, sd, "%s: %d, state: 0x%x\n",
- __func__, enable, state->flags);
-
- if (enable) {
- ret = pm_runtime_get_sync(&state->pdev->dev);
- if (ret && ret != 1)
- return ret;
- }
- mutex_lock(&state->lock);
- if (enable) {
- if (state->flags & ST_SUSPENDED) {
- ret = -EBUSY;
- goto unlock;
- }
- s5pcsis_start_stream(state);
- state->flags |= ST_STREAMING;
- } else {
- s5pcsis_stop_stream(state);
- state->flags &= ~ST_STREAMING;
- }
-unlock:
- mutex_unlock(&state->lock);
- if (!enable)
- pm_runtime_put(&state->pdev->dev);
-
- return ret == 1 ? 0 : ret;
-}
-
-static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- if (code->index >= ARRAY_SIZE(s5pcsis_formats))
- return -EINVAL;
-
- code->code = s5pcsis_formats[code->index].code;
- return 0;
-}
-
-static struct csis_pix_format const *s5pcsis_try_format(
- struct v4l2_mbus_framefmt *mf)
-{
- struct csis_pix_format const *csis_fmt;
-
- csis_fmt = find_csis_format(mf);
- if (csis_fmt == NULL)
- csis_fmt = &s5pcsis_formats[0];
-
- mf->code = csis_fmt->code;
- v4l_bound_align_image(&mf->width, 1, CSIS_MAX_PIX_WIDTH,
- csis_fmt->pix_width_alignment,
- &mf->height, 1, CSIS_MAX_PIX_HEIGHT, 1,
- 0);
- return csis_fmt;
-}
-
-static struct v4l2_mbus_framefmt *__s5pcsis_get_format(
- struct csis_state *state, struct v4l2_subdev_fh *fh,
- u32 pad, enum v4l2_subdev_format_whence which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL;
-
- return &state->format;
-}
-
-static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct csis_state *state = sd_to_csis_state(sd);
- struct csis_pix_format const *csis_fmt;
- struct v4l2_mbus_framefmt *mf;
-
- if (fmt->pad != CSIS_PAD_SOURCE && fmt->pad != CSIS_PAD_SINK)
- return -EINVAL;
-
- mf = __s5pcsis_get_format(state, fh, fmt->pad, fmt->which);
-
- if (fmt->pad == CSIS_PAD_SOURCE) {
- if (mf) {
- mutex_lock(&state->lock);
- fmt->format = *mf;
- mutex_unlock(&state->lock);
- }
- return 0;
- }
- csis_fmt = s5pcsis_try_format(&fmt->format);
- if (mf) {
- mutex_lock(&state->lock);
- *mf = fmt->format;
- if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
- state->csis_fmt = csis_fmt;
- mutex_unlock(&state->lock);
- }
- return 0;
-}
-
-static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct csis_state *state = sd_to_csis_state(sd);
- struct v4l2_mbus_framefmt *mf;
-
- if (fmt->pad != CSIS_PAD_SOURCE && fmt->pad != CSIS_PAD_SINK)
- return -EINVAL;
-
- mf = __s5pcsis_get_format(state, fh, fmt->pad, fmt->which);
- if (!mf)
- return -EINVAL;
-
- mutex_lock(&state->lock);
- fmt->format = *mf;
- mutex_unlock(&state->lock);
- return 0;
-}
-
-static int s5pcsis_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
-
- format->colorspace = V4L2_COLORSPACE_JPEG;
- format->code = s5pcsis_formats[0].code;
- format->width = S5PCSIS_DEF_PIX_WIDTH;
- format->height = S5PCSIS_DEF_PIX_HEIGHT;
- format->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static const struct v4l2_subdev_internal_ops s5pcsis_sd_internal_ops = {
- .open = s5pcsis_open,
-};
-
-static struct v4l2_subdev_core_ops s5pcsis_core_ops = {
- .s_power = s5pcsis_s_power,
-};
-
-static struct v4l2_subdev_pad_ops s5pcsis_pad_ops = {
- .enum_mbus_code = s5pcsis_enum_mbus_code,
- .get_fmt = s5pcsis_get_fmt,
- .set_fmt = s5pcsis_set_fmt,
-};
-
-static struct v4l2_subdev_video_ops s5pcsis_video_ops = {
- .s_stream = s5pcsis_s_stream,
-};
-
-static struct v4l2_subdev_ops s5pcsis_subdev_ops = {
- .core = &s5pcsis_core_ops,
- .pad = &s5pcsis_pad_ops,
- .video = &s5pcsis_video_ops,
-};
-
-static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id)
-{
- struct csis_state *state = dev_id;
- u32 val;
-
- /* Just clear the interrupt pending bits. */
- val = s5pcsis_read(state, S5PCSIS_INTSRC);
- s5pcsis_write(state, S5PCSIS_INTSRC, val);
-
- return IRQ_HANDLED;
-}
-
-static int __devinit s5pcsis_probe(struct platform_device *pdev)
-{
- struct s5p_platform_mipi_csis *pdata;
- struct resource *mem_res;
- struct csis_state *state;
- int ret = -ENOMEM;
- int i;
-
- state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL);
- if (!state)
- return -ENOMEM;
-
- mutex_init(&state->lock);
- state->pdev = pdev;
-
- pdata = pdev->dev.platform_data;
- if (pdata == NULL || pdata->phy_enable == NULL) {
- dev_err(&pdev->dev, "Platform data not fully specified\n");
- return -EINVAL;
- }
-
- if ((pdev->id == 1 && pdata->lanes > CSIS1_MAX_LANES) ||
- pdata->lanes > CSIS0_MAX_LANES) {
- dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n",
- pdata->lanes);
- return -EINVAL;
- }
-
- mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- state->regs = devm_request_and_ioremap(&pdev->dev, mem_res);
- if (state->regs == NULL) {
- dev_err(&pdev->dev, "Failed to request and remap io memory\n");
- return -ENXIO;
- }
-
- state->irq = platform_get_irq(pdev, 0);
- if (state->irq < 0) {
- dev_err(&pdev->dev, "Failed to get irq\n");
- return state->irq;
- }
-
- for (i = 0; i < CSIS_NUM_SUPPLIES; i++)
- state->supplies[i].supply = csis_supply_name[i];
-
- ret = regulator_bulk_get(&pdev->dev, CSIS_NUM_SUPPLIES,
- state->supplies);
- if (ret)
- return ret;
-
- ret = s5pcsis_clk_get(state);
- if (ret)
- goto e_clkput;
-
- clk_enable(state->clock[CSIS_CLK_MUX]);
- if (pdata->clk_rate)
- clk_set_rate(state->clock[CSIS_CLK_MUX], pdata->clk_rate);
- else
- dev_WARN(&pdev->dev, "No clock frequency specified!\n");
-
- ret = devm_request_irq(&pdev->dev, state->irq, s5pcsis_irq_handler,
- 0, dev_name(&pdev->dev), state);
- if (ret) {
- dev_err(&pdev->dev, "Interrupt request failed\n");
- goto e_regput;
- }
-
- v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops);
- state->sd.owner = THIS_MODULE;
- strlcpy(state->sd.name, dev_name(&pdev->dev), sizeof(state->sd.name));
- state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- state->csis_fmt = &s5pcsis_formats[0];
-
- state->format.code = s5pcsis_formats[0].code;
- state->format.width = S5PCSIS_DEF_PIX_WIDTH;
- state->format.height = S5PCSIS_DEF_PIX_HEIGHT;
-
- state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_init(&state->sd.entity,
- CSIS_PADS_NUM, state->pads, 0);
- if (ret < 0)
- goto e_clkput;
-
- /* This allows to retrieve the platform device id by the host driver */
- v4l2_set_subdevdata(&state->sd, pdev);
-
- /* .. and a pointer to the subdev. */
- platform_set_drvdata(pdev, &state->sd);
-
- pm_runtime_enable(&pdev->dev);
- return 0;
-
-e_regput:
- regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies);
-e_clkput:
- clk_disable(state->clock[CSIS_CLK_MUX]);
- s5pcsis_clk_put(state);
- return ret;
-}
-
-static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
-{
- struct s5p_platform_mipi_csis *pdata = dev->platform_data;
- struct platform_device *pdev = to_platform_device(dev);
- struct v4l2_subdev *sd = platform_get_drvdata(pdev);
- struct csis_state *state = sd_to_csis_state(sd);
- int ret = 0;
-
- v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
- __func__, state->flags);
-
- mutex_lock(&state->lock);
- if (state->flags & ST_POWERED) {
- s5pcsis_stop_stream(state);
- ret = pdata->phy_enable(state->pdev, false);
- if (ret)
- goto unlock;
- ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
- state->supplies);
- if (ret)
- goto unlock;
- clk_disable(state->clock[CSIS_CLK_GATE]);
- state->flags &= ~ST_POWERED;
- if (!runtime)
- state->flags |= ST_SUSPENDED;
- }
- unlock:
- mutex_unlock(&state->lock);
- return ret ? -EAGAIN : 0;
-}
-
-static int s5pcsis_pm_resume(struct device *dev, bool runtime)
-{
- struct s5p_platform_mipi_csis *pdata = dev->platform_data;
- struct platform_device *pdev = to_platform_device(dev);
- struct v4l2_subdev *sd = platform_get_drvdata(pdev);
- struct csis_state *state = sd_to_csis_state(sd);
- int ret = 0;
-
- v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
- __func__, state->flags);
-
- mutex_lock(&state->lock);
- if (!runtime && !(state->flags & ST_SUSPENDED))
- goto unlock;
-
- if (!(state->flags & ST_POWERED)) {
- ret = regulator_bulk_enable(CSIS_NUM_SUPPLIES,
- state->supplies);
- if (ret)
- goto unlock;
- ret = pdata->phy_enable(state->pdev, true);
- if (!ret) {
- state->flags |= ST_POWERED;
- } else {
- regulator_bulk_disable(CSIS_NUM_SUPPLIES,
- state->supplies);
- goto unlock;
- }
- clk_enable(state->clock[CSIS_CLK_GATE]);
- }
- if (state->flags & ST_STREAMING)
- s5pcsis_start_stream(state);
-
- state->flags &= ~ST_SUSPENDED;
- unlock:
- mutex_unlock(&state->lock);
- return ret ? -EAGAIN : 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int s5pcsis_suspend(struct device *dev)
-{
- return s5pcsis_pm_suspend(dev, false);
-}
-
-static int s5pcsis_resume(struct device *dev)
-{
- return s5pcsis_pm_resume(dev, false);
-}
-#endif
-
-#ifdef CONFIG_PM_RUNTIME
-static int s5pcsis_runtime_suspend(struct device *dev)
-{
- return s5pcsis_pm_suspend(dev, true);
-}
-
-static int s5pcsis_runtime_resume(struct device *dev)
-{
- return s5pcsis_pm_resume(dev, true);
-}
-#endif
-
-static int __devexit s5pcsis_remove(struct platform_device *pdev)
-{
- struct v4l2_subdev *sd = platform_get_drvdata(pdev);
- struct csis_state *state = sd_to_csis_state(sd);
-
- pm_runtime_disable(&pdev->dev);
- s5pcsis_pm_suspend(&pdev->dev, false);
- clk_disable(state->clock[CSIS_CLK_MUX]);
- pm_runtime_set_suspended(&pdev->dev);
- s5pcsis_clk_put(state);
- regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies);
-
- media_entity_cleanup(&state->sd.entity);
-
- return 0;
-}
-
-static const struct dev_pm_ops s5pcsis_pm_ops = {
- SET_RUNTIME_PM_OPS(s5pcsis_runtime_suspend, s5pcsis_runtime_resume,
- NULL)
- SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume)
-};
-
-static struct platform_driver s5pcsis_driver = {
- .probe = s5pcsis_probe,
- .remove = __devexit_p(s5pcsis_remove),
- .driver = {
- .name = CSIS_DRIVER_NAME,
- .owner = THIS_MODULE,
- .pm = &s5pcsis_pm_ops,
- },
-};
-
-module_platform_driver(s5pcsis_driver);
-
-MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
-MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI-CSI2 receiver driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/s5p-fimc/mipi-csis.h b/drivers/media/video/s5p-fimc/mipi-csis.h
deleted file mode 100644
index 2709286396e..00000000000
--- a/drivers/media/video/s5p-fimc/mipi-csis.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef S5P_MIPI_CSIS_H_
-#define S5P_MIPI_CSIS_H_
-
-#define CSIS_DRIVER_NAME "s5p-mipi-csis"
-#define CSIS_MAX_ENTITIES 2
-#define CSIS0_MAX_LANES 4
-#define CSIS1_MAX_LANES 2
-
-#define CSIS_PAD_SINK 0
-#define CSIS_PAD_SOURCE 1
-#define CSIS_PADS_NUM 2
-
-#define S5PCSIS_DEF_PIX_WIDTH 640
-#define S5PCSIS_DEF_PIX_HEIGHT 480
-
-#endif
diff --git a/drivers/media/video/s5p-g2d/Makefile b/drivers/media/video/s5p-g2d/Makefile
deleted file mode 100644
index 2c48c416a80..00000000000
--- a/drivers/media/video/s5p-g2d/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-s5p-g2d-objs := g2d.o g2d-hw.o
-
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d.o
diff --git a/drivers/media/video/s5p-g2d/g2d-hw.c b/drivers/media/video/s5p-g2d/g2d-hw.c
deleted file mode 100644
index 5b86cbe408e..00000000000
--- a/drivers/media/video/s5p-g2d/g2d-hw.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Samsung S5P G2D - 2D Graphics Accelerator Driver
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * Kamil Debski, <k.debski@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version
- */
-
-#include <linux/io.h>
-
-#include "g2d.h"
-#include "g2d-regs.h"
-
-#define w(x, a) writel((x), d->regs + (a))
-#define r(a) readl(d->regs + (a))
-
-/* g2d_reset clears all g2d registers */
-void g2d_reset(struct g2d_dev *d)
-{
- w(1, SOFT_RESET_REG);
-}
-
-void g2d_set_src_size(struct g2d_dev *d, struct g2d_frame *f)
-{
- u32 n;
-
- w(f->stride & 0xFFFF, SRC_STRIDE_REG);
-
- n = f->o_height & 0xFFF;
- n <<= 16;
- n |= f->o_width & 0xFFF;
- w(n, SRC_LEFT_TOP_REG);
-
- n = f->bottom & 0xFFF;
- n <<= 16;
- n |= f->right & 0xFFF;
- w(n, SRC_RIGHT_BOTTOM_REG);
-
- w(f->fmt->hw, SRC_COLOR_MODE_REG);
-}
-
-void g2d_set_src_addr(struct g2d_dev *d, dma_addr_t a)
-{
- w(a, SRC_BASE_ADDR_REG);
-}
-
-void g2d_set_dst_size(struct g2d_dev *d, struct g2d_frame *f)
-{
- u32 n;
-
- w(f->stride & 0xFFFF, DST_STRIDE_REG);
-
- n = f->o_height & 0xFFF;
- n <<= 16;
- n |= f->o_width & 0xFFF;
- w(n, DST_LEFT_TOP_REG);
-
- n = f->bottom & 0xFFF;
- n <<= 16;
- n |= f->right & 0xFFF;
- w(n, DST_RIGHT_BOTTOM_REG);
-
- w(f->fmt->hw, DST_COLOR_MODE_REG);
-}
-
-void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a)
-{
- w(a, DST_BASE_ADDR_REG);
-}
-
-void g2d_set_rop4(struct g2d_dev *d, u32 r)
-{
- w(r, ROP4_REG);
-}
-
-void g2d_set_flip(struct g2d_dev *d, u32 r)
-{
- w(r, SRC_MSK_DIRECT_REG);
-}
-
-u32 g2d_cmd_stretch(u32 e)
-{
- e &= 1;
- return e << 4;
-}
-
-void g2d_set_cmd(struct g2d_dev *d, u32 c)
-{
- w(c, BITBLT_COMMAND_REG);
-}
-
-void g2d_start(struct g2d_dev *d)
-{
- /* Clear cache */
- w(0x7, CACHECTL_REG);
- /* Enable interrupt */
- w(1, INTEN_REG);
- /* Start G2D engine */
- w(1, BITBLT_START_REG);
-}
-
-void g2d_clear_int(struct g2d_dev *d)
-{
- w(1, INTC_PEND_REG);
-}
diff --git a/drivers/media/video/s5p-g2d/g2d-regs.h b/drivers/media/video/s5p-g2d/g2d-regs.h
deleted file mode 100644
index 02e1cf50da4..00000000000
--- a/drivers/media/video/s5p-g2d/g2d-regs.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Samsung S5P G2D - 2D Graphics Accelerator Driver
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * Kamil Debski, <k.debski@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version
- */
-
-/* General Registers */
-#define SOFT_RESET_REG 0x0000 /* Software reset reg */
-#define INTEN_REG 0x0004 /* Interrupt Enable reg */
-#define INTC_PEND_REG 0x000C /* Interrupt Control Pending reg */
-#define FIFO_STAT_REG 0x0010 /* Command FIFO Status reg */
-#define AXI_ID_MODE_REG 0x0014 /* AXI Read ID Mode reg */
-#define CACHECTL_REG 0x0018 /* Cache & Buffer clear reg */
-#define AXI_MODE_REG 0x001C /* AXI Mode reg */
-
-/* Command Registers */
-#define BITBLT_START_REG 0x0100 /* BitBLT Start reg */
-#define BITBLT_COMMAND_REG 0x0104 /* Command reg for BitBLT */
-
-/* Parameter Setting Registers (Rotate & Direction) */
-#define ROTATE_REG 0x0200 /* Rotation reg */
-#define SRC_MSK_DIRECT_REG 0x0204 /* Src and Mask Direction reg */
-#define DST_PAT_DIRECT_REG 0x0208 /* Dest and Pattern Direction reg */
-
-/* Parameter Setting Registers (Src) */
-#define SRC_SELECT_REG 0x0300 /* Src Image Selection reg */
-#define SRC_BASE_ADDR_REG 0x0304 /* Src Image Base Address reg */
-#define SRC_STRIDE_REG 0x0308 /* Src Stride reg */
-#define SRC_COLOR_MODE_REG 0x030C /* Src Image Color Mode reg */
-#define SRC_LEFT_TOP_REG 0x0310 /* Src Left Top Coordinate reg */
-#define SRC_RIGHT_BOTTOM_REG 0x0314 /* Src Right Bottom Coordinate reg */
-
-/* Parameter Setting Registers (Dest) */
-#define DST_SELECT_REG 0x0400 /* Dest Image Selection reg */
-#define DST_BASE_ADDR_REG 0x0404 /* Dest Image Base Address reg */
-#define DST_STRIDE_REG 0x0408 /* Dest Stride reg */
-#define DST_COLOR_MODE_REG 0x040C /* Dest Image Color Mode reg */
-#define DST_LEFT_TOP_REG 0x0410 /* Dest Left Top Coordinate reg */
-#define DST_RIGHT_BOTTOM_REG 0x0414 /* Dest Right Bottom Coordinate reg */
-
-/* Parameter Setting Registers (Pattern) */
-#define PAT_BASE_ADDR_REG 0x0500 /* Pattern Image Base Address reg */
-#define PAT_SIZE_REG 0x0504 /* Pattern Image Size reg */
-#define PAT_COLOR_MODE_REG 0x0508 /* Pattern Image Color Mode reg */
-#define PAT_OFFSET_REG 0x050C /* Pattern Left Top Coordinate reg */
-#define PAT_STRIDE_REG 0x0510 /* Pattern Stride reg */
-
-/* Parameter Setting Registers (Mask) */
-#define MASK_BASE_ADDR_REG 0x0520 /* Mask Base Address reg */
-#define MASK_STRIDE_REG 0x0524 /* Mask Stride reg */
-
-/* Parameter Setting Registers (Clipping Window) */
-#define CW_LT_REG 0x0600 /* LeftTop coordinates of Clip Window */
-#define CW_RB_REG 0x0604 /* RightBottom coordinates of Clip
- Window */
-
-/* Parameter Setting Registers (ROP & Alpha Setting) */
-#define THIRD_OPERAND_REG 0x0610 /* Third Operand Selection reg */
-#define ROP4_REG 0x0614 /* Raster Operation reg */
-#define ALPHA_REG 0x0618 /* Alpha value, Fading offset value */
-
-/* Parameter Setting Registers (Color) */
-#define FG_COLOR_REG 0x0700 /* Foreground Color reg */
-#define BG_COLOR_REG 0x0704 /* Background Color reg */
-#define BS_COLOR_REG 0x0708 /* Blue Screen Color reg */
-
-/* Parameter Setting Registers (Color Key) */
-#define SRC_COLORKEY_CTRL_REG 0x0710 /* Src Colorkey control reg */
-#define SRC_COLORKEY_DR_MIN_REG 0x0714 /* Src Colorkey Decision Reference
- Min reg */
-#define SRC_COLORKEY_DR_MAX_REG 0x0718 /* Src Colorkey Decision Reference
- Max reg */
-#define DST_COLORKEY_CTRL_REG 0x071C /* Dest Colorkey control reg */
-#define DST_COLORKEY_DR_MIN_REG 0x0720 /* Dest Colorkey Decision Reference
- Min reg */
-#define DST_COLORKEY_DR_MAX_REG 0x0724 /* Dest Colorkey Decision Reference
- Max reg */
-
-/* Color mode values */
-
-#define ORDER_XRGB 0
-#define ORDER_RGBX 1
-#define ORDER_XBGR 2
-#define ORDER_BGRX 3
-
-#define MODE_XRGB_8888 0
-#define MODE_ARGB_8888 1
-#define MODE_RGB_565 2
-#define MODE_XRGB_1555 3
-#define MODE_ARGB_1555 4
-#define MODE_XRGB_4444 5
-#define MODE_ARGB_4444 6
-#define MODE_PACKED_RGB_888 7
-
-#define COLOR_MODE(o, m) (((o) << 4) | (m))
-
-/* ROP4 operation values */
-#define ROP4_COPY 0xCCCC
-#define ROP4_INVERT 0x3333
-
-/* Hardware limits */
-#define MAX_WIDTH 8000
-#define MAX_HEIGHT 8000
-
-#define G2D_TIMEOUT 500
-
-#define DEFAULT_WIDTH 100
-#define DEFAULT_HEIGHT 100
-
diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c
deleted file mode 100644
index 7c220043520..00000000000
--- a/drivers/media/video/s5p-g2d/g2d.c
+++ /dev/null
@@ -1,832 +0,0 @@
-/*
- * Samsung S5P G2D - 2D Graphics Accelerator Driver
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * Kamil Debski, <k.debski@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/version.h>
-#include <linux/timer.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-
-#include <linux/platform_device.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "g2d.h"
-#include "g2d-regs.h"
-
-#define fh2ctx(__fh) container_of(__fh, struct g2d_ctx, fh)
-
-static struct g2d_fmt formats[] = {
- {
- .name = "XRGB_8888",
- .fourcc = V4L2_PIX_FMT_RGB32,
- .depth = 32,
- .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_8888),
- },
- {
- .name = "RGB_565",
- .fourcc = V4L2_PIX_FMT_RGB565X,
- .depth = 16,
- .hw = COLOR_MODE(ORDER_XRGB, MODE_RGB_565),
- },
- {
- .name = "XRGB_1555",
- .fourcc = V4L2_PIX_FMT_RGB555X,
- .depth = 16,
- .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_1555),
- },
- {
- .name = "XRGB_4444",
- .fourcc = V4L2_PIX_FMT_RGB444,
- .depth = 16,
- .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_4444),
- },
- {
- .name = "PACKED_RGB_888",
- .fourcc = V4L2_PIX_FMT_RGB24,
- .depth = 24,
- .hw = COLOR_MODE(ORDER_XRGB, MODE_PACKED_RGB_888),
- },
-};
-#define NUM_FORMATS ARRAY_SIZE(formats)
-
-static struct g2d_frame def_frame = {
- .width = DEFAULT_WIDTH,
- .height = DEFAULT_HEIGHT,
- .c_width = DEFAULT_WIDTH,
- .c_height = DEFAULT_HEIGHT,
- .o_width = 0,
- .o_height = 0,
- .fmt = &formats[0],
- .right = DEFAULT_WIDTH,
- .bottom = DEFAULT_HEIGHT,
-};
-
-static struct g2d_fmt *find_fmt(struct v4l2_format *f)
-{
- unsigned int i;
- for (i = 0; i < NUM_FORMATS; i++) {
- if (formats[i].fourcc == f->fmt.pix.pixelformat)
- return &formats[i];
- }
- return NULL;
-}
-
-
-static struct g2d_frame *get_frame(struct g2d_ctx *ctx,
- enum v4l2_buf_type type)
-{
- switch (type) {
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- return &ctx->in;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- return &ctx->out;
- default:
- return ERR_PTR(-EINVAL);
- }
-}
-
-static int g2d_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
- unsigned int *nbuffers, unsigned int *nplanes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- struct g2d_ctx *ctx = vb2_get_drv_priv(vq);
- struct g2d_frame *f = get_frame(ctx, vq->type);
-
- if (IS_ERR(f))
- return PTR_ERR(f);
-
- sizes[0] = f->size;
- *nplanes = 1;
- alloc_ctxs[0] = ctx->dev->alloc_ctx;
-
- if (*nbuffers == 0)
- *nbuffers = 1;
-
- return 0;
-}
-
-static int g2d_buf_prepare(struct vb2_buffer *vb)
-{
- struct g2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct g2d_frame *f = get_frame(ctx, vb->vb2_queue->type);
-
- if (IS_ERR(f))
- return PTR_ERR(f);
- vb2_set_plane_payload(vb, 0, f->size);
- return 0;
-}
-
-static void g2d_buf_queue(struct vb2_buffer *vb)
-{
- struct g2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
-}
-
-
-static struct vb2_ops g2d_qops = {
- .queue_setup = g2d_queue_setup,
- .buf_prepare = g2d_buf_prepare,
- .buf_queue = g2d_buf_queue,
-};
-
-static int queue_init(void *priv, struct vb2_queue *src_vq,
- struct vb2_queue *dst_vq)
-{
- struct g2d_ctx *ctx = priv;
- int ret;
-
- memset(src_vq, 0, sizeof(*src_vq));
- src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
- src_vq->drv_priv = ctx;
- src_vq->ops = &g2d_qops;
- src_vq->mem_ops = &vb2_dma_contig_memops;
- src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-
- ret = vb2_queue_init(src_vq);
- if (ret)
- return ret;
-
- memset(dst_vq, 0, sizeof(*dst_vq));
- dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
- dst_vq->drv_priv = ctx;
- dst_vq->ops = &g2d_qops;
- dst_vq->mem_ops = &vb2_dma_contig_memops;
- dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-
- return vb2_queue_init(dst_vq);
-}
-
-static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct g2d_ctx *ctx = container_of(ctrl->handler, struct g2d_ctx,
- ctrl_handler);
- unsigned long flags;
-
- spin_lock_irqsave(&ctx->dev->ctrl_lock, flags);
- switch (ctrl->id) {
- case V4L2_CID_COLORFX:
- if (ctrl->val == V4L2_COLORFX_NEGATIVE)
- ctx->rop = ROP4_INVERT;
- else
- ctx->rop = ROP4_COPY;
- break;
-
- case V4L2_CID_HFLIP:
- ctx->flip = ctx->ctrl_hflip->val | (ctx->ctrl_vflip->val << 1);
- break;
-
- }
- spin_unlock_irqrestore(&ctx->dev->ctrl_lock, flags);
- return 0;
-}
-
-static const struct v4l2_ctrl_ops g2d_ctrl_ops = {
- .s_ctrl = g2d_s_ctrl,
-};
-
-static int g2d_setup_ctrls(struct g2d_ctx *ctx)
-{
- struct g2d_dev *dev = ctx->dev;
-
- v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
-
- ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &g2d_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
-
- ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &g2d_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
-
- v4l2_ctrl_new_std_menu(
- &ctx->ctrl_handler,
- &g2d_ctrl_ops,
- V4L2_CID_COLORFX,
- V4L2_COLORFX_NEGATIVE,
- ~((1 << V4L2_COLORFX_NONE) | (1 << V4L2_COLORFX_NEGATIVE)),
- V4L2_COLORFX_NONE);
-
- if (ctx->ctrl_handler.error) {
- int err = ctx->ctrl_handler.error;
- v4l2_err(&dev->v4l2_dev, "g2d_setup_ctrls failed\n");
- v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- return err;
- }
-
- v4l2_ctrl_cluster(2, &ctx->ctrl_hflip);
-
- return 0;
-}
-
-static int g2d_open(struct file *file)
-{
- struct g2d_dev *dev = video_drvdata(file);
- struct g2d_ctx *ctx = NULL;
- int ret = 0;
-
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
- ctx->dev = dev;
- /* Set default formats */
- ctx->in = def_frame;
- ctx->out = def_frame;
-
- ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
- if (IS_ERR(ctx->m2m_ctx)) {
- ret = PTR_ERR(ctx->m2m_ctx);
- kfree(ctx);
- return ret;
- }
- v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
-
- g2d_setup_ctrls(ctx);
-
- /* Write the default values to the ctx struct */
- v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
-
- ctx->fh.ctrl_handler = &ctx->ctrl_handler;
-
- v4l2_info(&dev->v4l2_dev, "instance opened\n");
- return 0;
-}
-
-static int g2d_release(struct file *file)
-{
- struct g2d_dev *dev = video_drvdata(file);
- struct g2d_ctx *ctx = fh2ctx(file->private_data);
-
- v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
- kfree(ctx);
- v4l2_info(&dev->v4l2_dev, "instance closed\n");
- return 0;
-}
-
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- strncpy(cap->driver, G2D_NAME, sizeof(cap->driver) - 1);
- strncpy(cap->card, G2D_NAME, sizeof(cap->card) - 1);
- cap->bus_info[0] = 0;
- cap->version = KERNEL_VERSION(1, 0, 0);
- /*
- * This is only a mem-to-mem video device. The capture and output
- * device capability flags are left only for backward compatibility
- * and are scheduled for removal.
- */
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
- V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
- return 0;
-}
-
-static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
-{
- struct g2d_fmt *fmt;
- if (f->index >= NUM_FORMATS)
- return -EINVAL;
- fmt = &formats[f->index];
- f->pixelformat = fmt->fourcc;
- strncpy(f->description, fmt->name, sizeof(f->description) - 1);
- return 0;
-}
-
-static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
-{
- struct g2d_ctx *ctx = prv;
- struct vb2_queue *vq;
- struct g2d_frame *frm;
-
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
- if (!vq)
- return -EINVAL;
- frm = get_frame(ctx, f->type);
- if (IS_ERR(frm))
- return PTR_ERR(frm);
-
- f->fmt.pix.width = frm->width;
- f->fmt.pix.height = frm->height;
- f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.pixelformat = frm->fmt->fourcc;
- f->fmt.pix.bytesperline = (frm->width * frm->fmt->depth) >> 3;
- f->fmt.pix.sizeimage = frm->size;
- return 0;
-}
-
-static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f)
-{
- struct g2d_fmt *fmt;
- enum v4l2_field *field;
-
- fmt = find_fmt(f);
- if (!fmt)
- return -EINVAL;
-
- field = &f->fmt.pix.field;
- if (*field == V4L2_FIELD_ANY)
- *field = V4L2_FIELD_NONE;
- else if (*field != V4L2_FIELD_NONE)
- return -EINVAL;
-
- if (f->fmt.pix.width > MAX_WIDTH)
- f->fmt.pix.width = MAX_WIDTH;
- if (f->fmt.pix.height > MAX_HEIGHT)
- f->fmt.pix.height = MAX_HEIGHT;
-
- if (f->fmt.pix.width < 1)
- f->fmt.pix.width = 1;
- if (f->fmt.pix.height < 1)
- f->fmt.pix.height = 1;
-
- f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
- f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
- return 0;
-}
-
-static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
-{
- struct g2d_ctx *ctx = prv;
- struct g2d_dev *dev = ctx->dev;
- struct vb2_queue *vq;
- struct g2d_frame *frm;
- struct g2d_fmt *fmt;
- int ret = 0;
-
- /* Adjust all values accordingly to the hardware capabilities
- * and chosen format. */
- ret = vidioc_try_fmt(file, prv, f);
- if (ret)
- return ret;
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
- if (vb2_is_busy(vq)) {
- v4l2_err(&dev->v4l2_dev, "queue (%d) bust\n", f->type);
- return -EBUSY;
- }
- frm = get_frame(ctx, f->type);
- if (IS_ERR(frm))
- return PTR_ERR(frm);
- fmt = find_fmt(f);
- if (!fmt)
- return -EINVAL;
- frm->width = f->fmt.pix.width;
- frm->height = f->fmt.pix.height;
- frm->size = f->fmt.pix.sizeimage;
- /* Reset crop settings */
- frm->o_width = 0;
- frm->o_height = 0;
- frm->c_width = frm->width;
- frm->c_height = frm->height;
- frm->right = frm->width;
- frm->bottom = frm->height;
- frm->fmt = fmt;
- frm->stride = f->fmt.pix.bytesperline;
- return 0;
-}
-
-static unsigned int g2d_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct g2d_ctx *ctx = fh2ctx(file->private_data);
- return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
-}
-
-static int g2d_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct g2d_ctx *ctx = fh2ctx(file->private_data);
- return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct g2d_ctx *ctx = priv;
- return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct g2d_ctx *ctx = priv;
- return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct g2d_ctx *ctx = priv;
- return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct g2d_ctx *ctx = priv;
- return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
-}
-
-
-static int vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct g2d_ctx *ctx = priv;
- return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
-}
-
-static int vidioc_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct g2d_ctx *ctx = priv;
- return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
-}
-
-static int vidioc_cropcap(struct file *file, void *priv,
- struct v4l2_cropcap *cr)
-{
- struct g2d_ctx *ctx = priv;
- struct g2d_frame *f;
-
- f = get_frame(ctx, cr->type);
- if (IS_ERR(f))
- return PTR_ERR(f);
-
- cr->bounds.left = 0;
- cr->bounds.top = 0;
- cr->bounds.width = f->width;
- cr->bounds.height = f->height;
- cr->defrect = cr->bounds;
- return 0;
-}
-
-static int vidioc_g_crop(struct file *file, void *prv, struct v4l2_crop *cr)
-{
- struct g2d_ctx *ctx = prv;
- struct g2d_frame *f;
-
- f = get_frame(ctx, cr->type);
- if (IS_ERR(f))
- return PTR_ERR(f);
-
- cr->c.left = f->o_height;
- cr->c.top = f->o_width;
- cr->c.width = f->c_width;
- cr->c.height = f->c_height;
- return 0;
-}
-
-static int vidioc_try_crop(struct file *file, void *prv, struct v4l2_crop *cr)
-{
- struct g2d_ctx *ctx = prv;
- struct g2d_dev *dev = ctx->dev;
- struct g2d_frame *f;
-
- f = get_frame(ctx, cr->type);
- if (IS_ERR(f))
- return PTR_ERR(f);
-
- if (cr->c.top < 0 || cr->c.left < 0) {
- v4l2_err(&dev->v4l2_dev,
- "doesn't support negative values for top & left\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vidioc_s_crop(struct file *file, void *prv, struct v4l2_crop *cr)
-{
- struct g2d_ctx *ctx = prv;
- struct g2d_frame *f;
- int ret;
-
- ret = vidioc_try_crop(file, prv, cr);
- if (ret)
- return ret;
- f = get_frame(ctx, cr->type);
- if (IS_ERR(f))
- return PTR_ERR(f);
-
- f->c_width = cr->c.width;
- f->c_height = cr->c.height;
- f->o_width = cr->c.left;
- f->o_height = cr->c.top;
- f->bottom = f->o_height + f->c_height;
- f->right = f->o_width + f->c_width;
- return 0;
-}
-
-static void g2d_lock(void *prv)
-{
- struct g2d_ctx *ctx = prv;
- struct g2d_dev *dev = ctx->dev;
- mutex_lock(&dev->mutex);
-}
-
-static void g2d_unlock(void *prv)
-{
- struct g2d_ctx *ctx = prv;
- struct g2d_dev *dev = ctx->dev;
- mutex_unlock(&dev->mutex);
-}
-
-static void job_abort(void *prv)
-{
- struct g2d_ctx *ctx = prv;
- struct g2d_dev *dev = ctx->dev;
- int ret;
-
- if (dev->curr == NULL) /* No job currently running */
- return;
-
- ret = wait_event_timeout(dev->irq_queue,
- dev->curr == NULL,
- msecs_to_jiffies(G2D_TIMEOUT));
-}
-
-static void device_run(void *prv)
-{
- struct g2d_ctx *ctx = prv;
- struct g2d_dev *dev = ctx->dev;
- struct vb2_buffer *src, *dst;
- unsigned long flags;
- u32 cmd = 0;
-
- dev->curr = ctx;
-
- src = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
- dst = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
-
- clk_enable(dev->gate);
- g2d_reset(dev);
-
- spin_lock_irqsave(&dev->ctrl_lock, flags);
-
- g2d_set_src_size(dev, &ctx->in);
- g2d_set_src_addr(dev, vb2_dma_contig_plane_dma_addr(src, 0));
-
- g2d_set_dst_size(dev, &ctx->out);
- g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0));
-
- g2d_set_rop4(dev, ctx->rop);
- g2d_set_flip(dev, ctx->flip);
-
- if (ctx->in.c_width != ctx->out.c_width ||
- ctx->in.c_height != ctx->out.c_height)
- cmd |= g2d_cmd_stretch(1);
- g2d_set_cmd(dev, cmd);
- g2d_start(dev);
-
- spin_unlock_irqrestore(&dev->ctrl_lock, flags);
-}
-
-static irqreturn_t g2d_isr(int irq, void *prv)
-{
- struct g2d_dev *dev = prv;
- struct g2d_ctx *ctx = dev->curr;
- struct vb2_buffer *src, *dst;
-
- g2d_clear_int(dev);
- clk_disable(dev->gate);
-
- BUG_ON(ctx == NULL);
-
- src = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- dst = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
-
- BUG_ON(src == NULL);
- BUG_ON(dst == NULL);
-
- v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE);
- v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
- v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx);
-
- dev->curr = NULL;
- wake_up(&dev->irq_queue);
- return IRQ_HANDLED;
-}
-
-static const struct v4l2_file_operations g2d_fops = {
- .owner = THIS_MODULE,
- .open = g2d_open,
- .release = g2d_release,
- .poll = g2d_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = g2d_mmap,
-};
-
-static const struct v4l2_ioctl_ops g2d_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
-
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt,
-
- .vidioc_enum_fmt_vid_out = vidioc_enum_fmt,
- .vidioc_g_fmt_vid_out = vidioc_g_fmt,
- .vidioc_try_fmt_vid_out = vidioc_try_fmt,
- .vidioc_s_fmt_vid_out = vidioc_s_fmt,
-
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
-
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
-
- .vidioc_g_crop = vidioc_g_crop,
- .vidioc_s_crop = vidioc_s_crop,
- .vidioc_cropcap = vidioc_cropcap,
-};
-
-static struct video_device g2d_videodev = {
- .name = G2D_NAME,
- .fops = &g2d_fops,
- .ioctl_ops = &g2d_ioctl_ops,
- .minor = -1,
- .release = video_device_release,
-};
-
-static struct v4l2_m2m_ops g2d_m2m_ops = {
- .device_run = device_run,
- .job_abort = job_abort,
- .lock = g2d_lock,
- .unlock = g2d_unlock,
-};
-
-static int g2d_probe(struct platform_device *pdev)
-{
- struct g2d_dev *dev;
- struct video_device *vfd;
- struct resource *res;
- int ret = 0;
-
- dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
-
- spin_lock_init(&dev->ctrl_lock);
- mutex_init(&dev->mutex);
- atomic_set(&dev->num_inst, 0);
- init_waitqueue_head(&dev->irq_queue);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- dev->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (dev->regs == NULL) {
- dev_err(&pdev->dev, "Failed to obtain io memory\n");
- return -ENOENT;
- }
-
- dev->clk = clk_get(&pdev->dev, "sclk_fimg2d");
- if (IS_ERR_OR_NULL(dev->clk)) {
- dev_err(&pdev->dev, "failed to get g2d clock\n");
- return -ENXIO;
- }
-
- ret = clk_prepare(dev->clk);
- if (ret) {
- dev_err(&pdev->dev, "failed to prepare g2d clock\n");
- goto put_clk;
- }
-
- dev->gate = clk_get(&pdev->dev, "fimg2d");
- if (IS_ERR_OR_NULL(dev->gate)) {
- dev_err(&pdev->dev, "failed to get g2d clock gate\n");
- ret = -ENXIO;
- goto unprep_clk;
- }
-
- ret = clk_prepare(dev->gate);
- if (ret) {
- dev_err(&pdev->dev, "failed to prepare g2d clock gate\n");
- goto put_clk_gate;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(&pdev->dev, "failed to find IRQ\n");
- ret = -ENXIO;
- goto unprep_clk_gate;
- }
-
- dev->irq = res->start;
-
- ret = devm_request_irq(&pdev->dev, dev->irq, g2d_isr,
- 0, pdev->name, dev);
- if (ret) {
- dev_err(&pdev->dev, "failed to install IRQ\n");
- goto put_clk_gate;
- }
-
- dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
- if (IS_ERR(dev->alloc_ctx)) {
- ret = PTR_ERR(dev->alloc_ctx);
- goto unprep_clk_gate;
- }
-
- ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
- if (ret)
- goto alloc_ctx_cleanup;
- vfd = video_device_alloc();
- if (!vfd) {
- v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
- ret = -ENOMEM;
- goto unreg_v4l2_dev;
- }
- *vfd = g2d_videodev;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
- vfd->lock = &dev->mutex;
- ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
- if (ret) {
- v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
- goto rel_vdev;
- }
- video_set_drvdata(vfd, dev);
- snprintf(vfd->name, sizeof(vfd->name), "%s", g2d_videodev.name);
- dev->vfd = vfd;
- v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n",
- vfd->num);
- platform_set_drvdata(pdev, dev);
- dev->m2m_dev = v4l2_m2m_init(&g2d_m2m_ops);
- if (IS_ERR(dev->m2m_dev)) {
- v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
- ret = PTR_ERR(dev->m2m_dev);
- goto unreg_video_dev;
- }
-
- def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3;
-
- return 0;
-
-unreg_video_dev:
- video_unregister_device(dev->vfd);
-rel_vdev:
- video_device_release(vfd);
-unreg_v4l2_dev:
- v4l2_device_unregister(&dev->v4l2_dev);
-alloc_ctx_cleanup:
- vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
-unprep_clk_gate:
- clk_unprepare(dev->gate);
-put_clk_gate:
- clk_put(dev->gate);
-unprep_clk:
- clk_unprepare(dev->clk);
-put_clk:
- clk_put(dev->clk);
-
- return ret;
-}
-
-static int g2d_remove(struct platform_device *pdev)
-{
- struct g2d_dev *dev = (struct g2d_dev *)platform_get_drvdata(pdev);
-
- v4l2_info(&dev->v4l2_dev, "Removing " G2D_NAME);
- v4l2_m2m_release(dev->m2m_dev);
- video_unregister_device(dev->vfd);
- v4l2_device_unregister(&dev->v4l2_dev);
- vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
- clk_unprepare(dev->gate);
- clk_put(dev->gate);
- clk_unprepare(dev->clk);
- clk_put(dev->clk);
- return 0;
-}
-
-static struct platform_driver g2d_pdrv = {
- .probe = g2d_probe,
- .remove = g2d_remove,
- .driver = {
- .name = G2D_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(g2d_pdrv);
-
-MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>");
-MODULE_DESCRIPTION("S5P G2D 2d graphics accelerator driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/s5p-g2d/g2d.h b/drivers/media/video/s5p-g2d/g2d.h
deleted file mode 100644
index 6b765b0216c..00000000000
--- a/drivers/media/video/s5p-g2d/g2d.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Samsung S5P G2D - 2D Graphics Accelerator Driver
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * Kamil Debski, <k.debski@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version
- */
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-
-#define G2D_NAME "s5p-g2d"
-
-struct g2d_dev {
- struct v4l2_device v4l2_dev;
- struct v4l2_m2m_dev *m2m_dev;
- struct video_device *vfd;
- struct mutex mutex;
- spinlock_t ctrl_lock;
- atomic_t num_inst;
- struct vb2_alloc_ctx *alloc_ctx;
- void __iomem *regs;
- struct clk *clk;
- struct clk *gate;
- struct g2d_ctx *curr;
- int irq;
- wait_queue_head_t irq_queue;
-};
-
-struct g2d_frame {
- /* Original dimensions */
- u32 width;
- u32 height;
- /* Crop size */
- u32 c_width;
- u32 c_height;
- /* Offset */
- u32 o_width;
- u32 o_height;
- /* Image format */
- struct g2d_fmt *fmt;
- /* Variables that can calculated once and reused */
- u32 stride;
- u32 bottom;
- u32 right;
- u32 size;
-};
-
-struct g2d_ctx {
- struct v4l2_fh fh;
- struct g2d_dev *dev;
- struct v4l2_m2m_ctx *m2m_ctx;
- struct g2d_frame in;
- struct g2d_frame out;
- struct v4l2_ctrl *ctrl_hflip;
- struct v4l2_ctrl *ctrl_vflip;
- struct v4l2_ctrl_handler ctrl_handler;
- u32 rop;
- u32 flip;
-};
-
-struct g2d_fmt {
- char *name;
- u32 fourcc;
- int depth;
- u32 hw;
-};
-
-
-void g2d_reset(struct g2d_dev *d);
-void g2d_set_src_size(struct g2d_dev *d, struct g2d_frame *f);
-void g2d_set_src_addr(struct g2d_dev *d, dma_addr_t a);
-void g2d_set_dst_size(struct g2d_dev *d, struct g2d_frame *f);
-void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a);
-void g2d_start(struct g2d_dev *d);
-void g2d_clear_int(struct g2d_dev *d);
-void g2d_set_rop4(struct g2d_dev *d, u32 r);
-void g2d_set_flip(struct g2d_dev *d, u32 r);
-u32 g2d_cmd_stretch(u32 e);
-void g2d_set_cmd(struct g2d_dev *d, u32 c);
-
-
diff --git a/drivers/media/video/s5p-jpeg/Makefile b/drivers/media/video/s5p-jpeg/Makefile
deleted file mode 100644
index ddc2900d88a..00000000000
--- a/drivers/media/video/s5p-jpeg/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-s5p-jpeg-objs := jpeg-core.o
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) := s5p-jpeg.o
diff --git a/drivers/media/video/s5p-jpeg/jpeg-core.c b/drivers/media/video/s5p-jpeg/jpeg-core.c
deleted file mode 100644
index 813b801238d..00000000000
--- a/drivers/media/video/s5p-jpeg/jpeg-core.c
+++ /dev/null
@@ -1,1515 +0,0 @@
-/* linux/drivers/media/video/s5p-jpeg/jpeg-core.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/gfp.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "jpeg-core.h"
-#include "jpeg-hw.h"
-
-static struct s5p_jpeg_fmt formats_enc[] = {
- {
- .name = "JPEG JFIF",
- .fourcc = V4L2_PIX_FMT_JPEG,
- .colplanes = 1,
- .types = MEM2MEM_CAPTURE,
- },
- {
- .name = "YUV 4:2:2 packed, YCbYCr",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = 16,
- .colplanes = 1,
- .types = MEM2MEM_OUTPUT,
- },
- {
- .name = "RGB565",
- .fourcc = V4L2_PIX_FMT_RGB565,
- .depth = 16,
- .colplanes = 1,
- .types = MEM2MEM_OUTPUT,
- },
-};
-#define NUM_FORMATS_ENC ARRAY_SIZE(formats_enc)
-
-static struct s5p_jpeg_fmt formats_dec[] = {
- {
- .name = "YUV 4:2:0 planar, YCbCr",
- .fourcc = V4L2_PIX_FMT_YUV420,
- .depth = 12,
- .colplanes = 3,
- .h_align = 4,
- .v_align = 4,
- .types = MEM2MEM_CAPTURE,
- },
- {
- .name = "YUV 4:2:2 packed, YCbYCr",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = 16,
- .colplanes = 1,
- .h_align = 4,
- .v_align = 3,
- .types = MEM2MEM_CAPTURE,
- },
- {
- .name = "JPEG JFIF",
- .fourcc = V4L2_PIX_FMT_JPEG,
- .colplanes = 1,
- .types = MEM2MEM_OUTPUT,
- },
-};
-#define NUM_FORMATS_DEC ARRAY_SIZE(formats_dec)
-
-static const unsigned char qtbl_luminance[4][64] = {
- {/* level 1 - high quality */
- 8, 6, 6, 8, 12, 14, 16, 17,
- 6, 6, 6, 8, 10, 13, 12, 15,
- 6, 6, 7, 8, 13, 14, 18, 24,
- 8, 8, 8, 14, 13, 19, 24, 35,
- 12, 10, 13, 13, 20, 26, 34, 39,
- 14, 13, 14, 19, 26, 34, 39, 39,
- 16, 12, 18, 24, 34, 39, 39, 39,
- 17, 15, 24, 35, 39, 39, 39, 39
- },
- {/* level 2 */
- 12, 8, 8, 12, 17, 21, 24, 23,
- 8, 9, 9, 11, 15, 19, 18, 23,
- 8, 9, 10, 12, 19, 20, 27, 36,
- 12, 11, 12, 21, 20, 28, 36, 53,
- 17, 15, 19, 20, 30, 39, 51, 59,
- 21, 19, 20, 28, 39, 51, 59, 59,
- 24, 18, 27, 36, 51, 59, 59, 59,
- 23, 23, 36, 53, 59, 59, 59, 59
- },
- {/* level 3 */
- 16, 11, 11, 16, 23, 27, 31, 30,
- 11, 12, 12, 15, 20, 23, 23, 30,
- 11, 12, 13, 16, 23, 26, 35, 47,
- 16, 15, 16, 23, 26, 37, 47, 64,
- 23, 20, 23, 26, 39, 51, 64, 64,
- 27, 23, 26, 37, 51, 64, 64, 64,
- 31, 23, 35, 47, 64, 64, 64, 64,
- 30, 30, 47, 64, 64, 64, 64, 64
- },
- {/*level 4 - low quality */
- 20, 16, 25, 39, 50, 46, 62, 68,
- 16, 18, 23, 38, 38, 53, 65, 68,
- 25, 23, 31, 38, 53, 65, 68, 68,
- 39, 38, 38, 53, 65, 68, 68, 68,
- 50, 38, 53, 65, 68, 68, 68, 68,
- 46, 53, 65, 68, 68, 68, 68, 68,
- 62, 65, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68
- }
-};
-
-static const unsigned char qtbl_chrominance[4][64] = {
- {/* level 1 - high quality */
- 9, 8, 9, 11, 14, 17, 19, 24,
- 8, 10, 9, 11, 14, 13, 17, 22,
- 9, 9, 13, 14, 13, 15, 23, 26,
- 11, 11, 14, 14, 15, 20, 26, 33,
- 14, 14, 13, 15, 20, 24, 33, 39,
- 17, 13, 15, 20, 24, 32, 39, 39,
- 19, 17, 23, 26, 33, 39, 39, 39,
- 24, 22, 26, 33, 39, 39, 39, 39
- },
- {/* level 2 */
- 13, 11, 13, 16, 20, 20, 29, 37,
- 11, 14, 14, 14, 16, 20, 26, 32,
- 13, 14, 15, 17, 20, 23, 35, 40,
- 16, 14, 17, 21, 23, 30, 40, 50,
- 20, 16, 20, 23, 30, 37, 50, 59,
- 20, 20, 23, 30, 37, 48, 59, 59,
- 29, 26, 35, 40, 50, 59, 59, 59,
- 37, 32, 40, 50, 59, 59, 59, 59
- },
- {/* level 3 */
- 17, 15, 17, 21, 20, 26, 38, 48,
- 15, 19, 18, 17, 20, 26, 35, 43,
- 17, 18, 20, 22, 26, 30, 46, 53,
- 21, 17, 22, 28, 30, 39, 53, 64,
- 20, 20, 26, 30, 39, 48, 64, 64,
- 26, 26, 30, 39, 48, 63, 64, 64,
- 38, 35, 46, 53, 64, 64, 64, 64,
- 48, 43, 53, 64, 64, 64, 64, 64
- },
- {/*level 4 - low quality */
- 21, 25, 32, 38, 54, 68, 68, 68,
- 25, 28, 24, 38, 54, 68, 68, 68,
- 32, 24, 32, 43, 66, 68, 68, 68,
- 38, 38, 43, 53, 68, 68, 68, 68,
- 54, 54, 66, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68
- }
-};
-
-static const unsigned char hdctbl0[16] = {
- 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
-};
-
-static const unsigned char hdctblg0[12] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
-};
-static const unsigned char hactbl0[16] = {
- 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
-};
-static const unsigned char hactblg0[162] = {
- 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
- 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
- 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
- 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
- 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
- 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
- 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
- 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
- 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
- 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
- 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
- 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
- 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
- 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
- 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
- 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
- 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
- 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
- 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
- 0xf9, 0xfa
-};
-
-static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
-{
- return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
-}
-
-static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
-{
- return container_of(fh, struct s5p_jpeg_ctx, fh);
-}
-
-static inline void jpeg_set_qtbl(void __iomem *regs, const unsigned char *qtbl,
- unsigned long tab, int len)
-{
- int i;
-
- for (i = 0; i < len; i++)
- writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
-}
-
-static inline void jpeg_set_qtbl_lum(void __iomem *regs, int quality)
-{
- /* this driver fills quantisation table 0 with data for luma */
- jpeg_set_qtbl(regs, qtbl_luminance[quality], S5P_JPG_QTBL_CONTENT(0),
- ARRAY_SIZE(qtbl_luminance[quality]));
-}
-
-static inline void jpeg_set_qtbl_chr(void __iomem *regs, int quality)
-{
- /* this driver fills quantisation table 1 with data for chroma */
- jpeg_set_qtbl(regs, qtbl_chrominance[quality], S5P_JPG_QTBL_CONTENT(1),
- ARRAY_SIZE(qtbl_chrominance[quality]));
-}
-
-static inline void jpeg_set_htbl(void __iomem *regs, const unsigned char *htbl,
- unsigned long tab, int len)
-{
- int i;
-
- for (i = 0; i < len; i++)
- writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
-}
-
-static inline void jpeg_set_hdctbl(void __iomem *regs)
-{
- /* this driver fills table 0 for this component */
- jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0), ARRAY_SIZE(hdctbl0));
-}
-
-static inline void jpeg_set_hdctblg(void __iomem *regs)
-{
- /* this driver fills table 0 for this component */
- jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0), ARRAY_SIZE(hdctblg0));
-}
-
-static inline void jpeg_set_hactbl(void __iomem *regs)
-{
- /* this driver fills table 0 for this component */
- jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0), ARRAY_SIZE(hactbl0));
-}
-
-static inline void jpeg_set_hactblg(void __iomem *regs)
-{
- /* this driver fills table 0 for this component */
- jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0), ARRAY_SIZE(hactblg0));
-}
-
-/*
- * ============================================================================
- * Device file operations
- * ============================================================================
- */
-
-static int queue_init(void *priv, struct vb2_queue *src_vq,
- struct vb2_queue *dst_vq);
-static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode,
- __u32 pixelformat);
-static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
-
-static int s5p_jpeg_open(struct file *file)
-{
- struct s5p_jpeg *jpeg = video_drvdata(file);
- struct video_device *vfd = video_devdata(file);
- struct s5p_jpeg_ctx *ctx;
- struct s5p_jpeg_fmt *out_fmt;
- int ret = 0;
-
- ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- v4l2_fh_init(&ctx->fh, vfd);
- /* Use separate control handler per file handle */
- ctx->fh.ctrl_handler = &ctx->ctrl_handler;
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
-
- ctx->jpeg = jpeg;
- if (vfd == jpeg->vfd_encoder) {
- ctx->mode = S5P_JPEG_ENCODE;
- out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_RGB565);
- } else {
- ctx->mode = S5P_JPEG_DECODE;
- out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_JPEG);
- }
-
- ret = s5p_jpeg_controls_create(ctx);
- if (ret < 0)
- goto error;
-
- ctx->m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
- if (IS_ERR(ctx->m2m_ctx)) {
- ret = PTR_ERR(ctx->m2m_ctx);
- goto error;
- }
-
- ctx->out_q.fmt = out_fmt;
- ctx->cap_q.fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_YUYV);
- return 0;
-
-error:
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
- kfree(ctx);
- return ret;
-}
-
-static int s5p_jpeg_release(struct file *file)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
-
- v4l2_m2m_ctx_release(ctx->m2m_ctx);
- v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
- kfree(ctx);
-
- return 0;
-}
-
-static unsigned int s5p_jpeg_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
-
- return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
-}
-
-static int s5p_jpeg_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
-
- return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
-}
-
-static const struct v4l2_file_operations s5p_jpeg_fops = {
- .owner = THIS_MODULE,
- .open = s5p_jpeg_open,
- .release = s5p_jpeg_release,
- .poll = s5p_jpeg_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = s5p_jpeg_mmap,
-};
-
-/*
- * ============================================================================
- * video ioctl operations
- * ============================================================================
- */
-
-static int get_byte(struct s5p_jpeg_buffer *buf)
-{
- if (buf->curr >= buf->size)
- return -1;
-
- return ((unsigned char *)buf->data)[buf->curr++];
-}
-
-static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
-{
- unsigned int temp;
- int byte;
-
- byte = get_byte(buf);
- if (byte == -1)
- return -1;
- temp = byte << 8;
- byte = get_byte(buf);
- if (byte == -1)
- return -1;
- *word = (unsigned int)byte | temp;
- return 0;
-}
-
-static void skip(struct s5p_jpeg_buffer *buf, long len)
-{
- if (len <= 0)
- return;
-
- while (len--)
- get_byte(buf);
-}
-
-static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
- unsigned long buffer, unsigned long size)
-{
- int c, components, notfound;
- unsigned int height, width, word;
- long length;
- struct s5p_jpeg_buffer jpeg_buffer;
-
- jpeg_buffer.size = size;
- jpeg_buffer.data = buffer;
- jpeg_buffer.curr = 0;
-
- notfound = 1;
- while (notfound) {
- c = get_byte(&jpeg_buffer);
- if (c == -1)
- break;
- if (c != 0xff)
- continue;
- do
- c = get_byte(&jpeg_buffer);
- while (c == 0xff);
- if (c == -1)
- break;
- if (c == 0)
- continue;
- length = 0;
- switch (c) {
- /* SOF0: baseline JPEG */
- case SOF0:
- if (get_word_be(&jpeg_buffer, &word))
- break;
- if (get_byte(&jpeg_buffer) == -1)
- break;
- if (get_word_be(&jpeg_buffer, &height))
- break;
- if (get_word_be(&jpeg_buffer, &width))
- break;
- components = get_byte(&jpeg_buffer);
- if (components == -1)
- break;
- notfound = 0;
-
- skip(&jpeg_buffer, components * 3);
- break;
-
- /* skip payload-less markers */
- case RST ... RST + 7:
- case SOI:
- case EOI:
- case TEM:
- break;
-
- /* skip uninteresting payload markers */
- default:
- if (get_word_be(&jpeg_buffer, &word))
- break;
- length = (long)word - 2;
- skip(&jpeg_buffer, length);
- break;
- }
- }
- result->w = width;
- result->h = height;
- result->size = components;
- return !notfound;
-}
-
-static int s5p_jpeg_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
-
- if (ctx->mode == S5P_JPEG_ENCODE) {
- strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
- sizeof(cap->driver));
- strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
- sizeof(cap->card));
- } else {
- strlcpy(cap->driver, S5P_JPEG_M2M_NAME " decoder",
- sizeof(cap->driver));
- strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
- sizeof(cap->card));
- }
- cap->bus_info[0] = 0;
- /*
- * This is only a mem-to-mem video device. The capture and output
- * device capability flags are left only for backward compatibility
- * and are scheduled for removal.
- */
- cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M |
- V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT;
- return 0;
-}
-
-static int enum_fmt(struct s5p_jpeg_fmt *formats, int n,
- struct v4l2_fmtdesc *f, u32 type)
-{
- int i, num = 0;
-
- for (i = 0; i < n; ++i) {
- if (formats[i].types & type) {
- /* index-th format of type type found ? */
- if (num == f->index)
- break;
- /* Correct type but haven't reached our index yet,
- * just increment per-type index */
- ++num;
- }
- }
-
- /* Format not found */
- if (i >= n)
- return -EINVAL;
-
- strlcpy(f->description, formats[i].name, sizeof(f->description));
- f->pixelformat = formats[i].fourcc;
-
- return 0;
-}
-
-static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
-
- if (ctx->mode == S5P_JPEG_ENCODE)
- return enum_fmt(formats_enc, NUM_FORMATS_ENC, f,
- MEM2MEM_CAPTURE);
-
- return enum_fmt(formats_dec, NUM_FORMATS_DEC, f, MEM2MEM_CAPTURE);
-}
-
-static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
-
- if (ctx->mode == S5P_JPEG_ENCODE)
- return enum_fmt(formats_enc, NUM_FORMATS_ENC, f,
- MEM2MEM_OUTPUT);
-
- return enum_fmt(formats_dec, NUM_FORMATS_DEC, f, MEM2MEM_OUTPUT);
-}
-
-static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
- enum v4l2_buf_type type)
-{
- if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return &ctx->out_q;
- if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return &ctx->cap_q;
-
- return NULL;
-}
-
-static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
-{
- struct vb2_queue *vq;
- struct s5p_jpeg_q_data *q_data = NULL;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
-
- vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type);
- if (!vq)
- return -EINVAL;
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
- ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
- return -EINVAL;
- q_data = get_q_data(ct, f->type);
- BUG_ON(q_data == NULL);
-
- pix->width = q_data->w;
- pix->height = q_data->h;
- pix->field = V4L2_FIELD_NONE;
- pix->pixelformat = q_data->fmt->fourcc;
- pix->bytesperline = 0;
- if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
- u32 bpl = q_data->w;
- if (q_data->fmt->colplanes == 1)
- bpl = (bpl * q_data->fmt->depth) >> 3;
- pix->bytesperline = bpl;
- }
- pix->sizeimage = q_data->size;
-
- return 0;
-}
-
-static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode,
- u32 pixelformat)
-{
- unsigned int k;
- struct s5p_jpeg_fmt *formats;
- int n;
-
- if (mode == S5P_JPEG_ENCODE) {
- formats = formats_enc;
- n = NUM_FORMATS_ENC;
- } else {
- formats = formats_dec;
- n = NUM_FORMATS_DEC;
- }
-
- for (k = 0; k < n; k++) {
- struct s5p_jpeg_fmt *fmt = &formats[k];
- if (fmt->fourcc == pixelformat)
- return fmt;
- }
-
- return NULL;
-
-}
-
-static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
- unsigned int walign,
- u32 *h, unsigned int hmin, unsigned int hmax,
- unsigned int halign)
-{
- int width, height, w_step, h_step;
-
- width = *w;
- height = *h;
-
- w_step = 1 << walign;
- h_step = 1 << halign;
- v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
-
- if (*w < width && (*w + w_step) < wmax)
- *w += w_step;
- if (*h < height && (*h + h_step) < hmax)
- *h += h_step;
-
-}
-
-static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
- struct s5p_jpeg_ctx *ctx, int q_type)
-{
- struct v4l2_pix_format *pix = &f->fmt.pix;
-
- if (pix->field == V4L2_FIELD_ANY)
- pix->field = V4L2_FIELD_NONE;
- else if (pix->field != V4L2_FIELD_NONE)
- return -EINVAL;
-
- /* V4L2 specification suggests the driver corrects the format struct
- * if any of the dimensions is unsupported */
- if (q_type == MEM2MEM_OUTPUT)
- jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
- S5P_JPEG_MAX_WIDTH, 0,
- &pix->height, S5P_JPEG_MIN_HEIGHT,
- S5P_JPEG_MAX_HEIGHT, 0);
- else
- jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
- S5P_JPEG_MAX_WIDTH, fmt->h_align,
- &pix->height, S5P_JPEG_MIN_HEIGHT,
- S5P_JPEG_MAX_HEIGHT, fmt->v_align);
-
- if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
- if (pix->sizeimage <= 0)
- pix->sizeimage = PAGE_SIZE;
- pix->bytesperline = 0;
- } else {
- u32 bpl = pix->bytesperline;
-
- if (fmt->colplanes > 1 && bpl < pix->width)
- bpl = pix->width; /* planar */
-
- if (fmt->colplanes == 1 && /* packed */
- (bpl << 3) * fmt->depth < pix->width)
- bpl = (pix->width * fmt->depth) >> 3;
-
- pix->bytesperline = bpl;
- pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
- }
-
- return 0;
-}
-
-static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
- struct s5p_jpeg_fmt *fmt;
-
- fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat);
- if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
- v4l2_err(&ctx->jpeg->v4l2_dev,
- "Fourcc format (0x%08x) invalid.\n",
- f->fmt.pix.pixelformat);
- return -EINVAL;
- }
-
- return vidioc_try_fmt(f, fmt, ctx, MEM2MEM_CAPTURE);
-}
-
-static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
- struct s5p_jpeg_fmt *fmt;
-
- fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat);
- if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
- v4l2_err(&ctx->jpeg->v4l2_dev,
- "Fourcc format (0x%08x) invalid.\n",
- f->fmt.pix.pixelformat);
- return -EINVAL;
- }
-
- return vidioc_try_fmt(f, fmt, ctx, MEM2MEM_OUTPUT);
-}
-
-static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
-{
- struct vb2_queue *vq;
- struct s5p_jpeg_q_data *q_data = NULL;
- struct v4l2_pix_format *pix = &f->fmt.pix;
-
- vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type);
- if (!vq)
- return -EINVAL;
-
- q_data = get_q_data(ct, f->type);
- BUG_ON(q_data == NULL);
-
- if (vb2_is_busy(vq)) {
- v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
- return -EBUSY;
- }
-
- q_data->fmt = s5p_jpeg_find_format(ct->mode, pix->pixelformat);
- q_data->w = pix->width;
- q_data->h = pix->height;
- if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)
- q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
- else
- q_data->size = pix->sizeimage;
-
- return 0;
-}
-
-static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- int ret;
-
- ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
- if (ret)
- return ret;
-
- return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
-}
-
-static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- int ret;
-
- ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
- if (ret)
- return ret;
-
- return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
-}
-
-static int s5p_jpeg_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
-
- return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
-}
-
-static int s5p_jpeg_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
-
- return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
-}
-
-static int s5p_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
-
- return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int s5p_jpeg_dqbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
-
- return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int s5p_jpeg_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
-
- return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
-}
-
-static int s5p_jpeg_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
-
- return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
-}
-
-static int s5p_jpeg_g_selection(struct file *file, void *priv,
- struct v4l2_selection *s)
-{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
-
- if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- /* For JPEG blob active == default == bounds */
- switch (s->target) {
- case V4L2_SEL_TGT_CROP:
- case V4L2_SEL_TGT_CROP_BOUNDS:
- case V4L2_SEL_TGT_CROP_DEFAULT:
- case V4L2_SEL_TGT_COMPOSE:
- case V4L2_SEL_TGT_COMPOSE_DEFAULT:
- s->r.width = ctx->out_q.w;
- s->r.height = ctx->out_q.h;
- break;
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- case V4L2_SEL_TGT_COMPOSE_PADDED:
- s->r.width = ctx->cap_q.w;
- s->r.height = ctx->cap_q.h;
- break;
- default:
- return -EINVAL;
- }
- s->r.left = 0;
- s->r.top = 0;
- return 0;
-}
-
-/*
- * V4L2 controls
- */
-
-static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
- struct s5p_jpeg *jpeg = ctx->jpeg;
- unsigned long flags;
-
- switch (ctrl->id) {
- case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
- spin_lock_irqsave(&jpeg->slock, flags);
-
- WARN_ON(ctx->subsampling > S5P_SUBSAMPLING_MODE_GRAY);
- if (ctx->subsampling > 2)
- ctrl->val = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
- else
- ctrl->val = ctx->subsampling;
- spin_unlock_irqrestore(&jpeg->slock, flags);
- break;
- }
-
- return 0;
-}
-
-static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
- unsigned long flags;
-
- spin_lock_irqsave(&ctx->jpeg->slock, flags);
-
- switch (ctrl->id) {
- case V4L2_CID_JPEG_COMPRESSION_QUALITY:
- ctx->compr_quality = S5P_JPEG_COMPR_QUAL_WORST - ctrl->val;
- break;
- case V4L2_CID_JPEG_RESTART_INTERVAL:
- ctx->restart_interval = ctrl->val;
- break;
- case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
- ctx->subsampling = ctrl->val;
- break;
- }
-
- spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
- return 0;
-}
-
-static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
- .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
- .s_ctrl = s5p_jpeg_s_ctrl,
-};
-
-static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
-{
- unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
- struct v4l2_ctrl *ctrl;
-
- v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
-
- if (ctx->mode == S5P_JPEG_ENCODE) {
- v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
- V4L2_CID_JPEG_COMPRESSION_QUALITY,
- 0, 3, 1, 3);
-
- v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
- V4L2_CID_JPEG_RESTART_INTERVAL,
- 0, 3, 0xffff, 0);
- mask = ~0x06; /* 422, 420 */
- }
-
- ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
- V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
- V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
- V4L2_JPEG_CHROMA_SUBSAMPLING_422);
-
- if (ctx->ctrl_handler.error)
- return ctx->ctrl_handler.error;
-
- if (ctx->mode == S5P_JPEG_DECODE)
- ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
- V4L2_CTRL_FLAG_READ_ONLY;
- return 0;
-}
-
-static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
- .vidioc_querycap = s5p_jpeg_querycap,
-
- .vidioc_enum_fmt_vid_cap = s5p_jpeg_enum_fmt_vid_cap,
- .vidioc_enum_fmt_vid_out = s5p_jpeg_enum_fmt_vid_out,
-
- .vidioc_g_fmt_vid_cap = s5p_jpeg_g_fmt,
- .vidioc_g_fmt_vid_out = s5p_jpeg_g_fmt,
-
- .vidioc_try_fmt_vid_cap = s5p_jpeg_try_fmt_vid_cap,
- .vidioc_try_fmt_vid_out = s5p_jpeg_try_fmt_vid_out,
-
- .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap,
- .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out,
-
- .vidioc_reqbufs = s5p_jpeg_reqbufs,
- .vidioc_querybuf = s5p_jpeg_querybuf,
-
- .vidioc_qbuf = s5p_jpeg_qbuf,
- .vidioc_dqbuf = s5p_jpeg_dqbuf,
-
- .vidioc_streamon = s5p_jpeg_streamon,
- .vidioc_streamoff = s5p_jpeg_streamoff,
-
- .vidioc_g_selection = s5p_jpeg_g_selection,
-};
-
-/*
- * ============================================================================
- * mem2mem callbacks
- * ============================================================================
- */
-
-static void s5p_jpeg_device_run(void *priv)
-{
- struct s5p_jpeg_ctx *ctx = priv;
- struct s5p_jpeg *jpeg = ctx->jpeg;
- struct vb2_buffer *src_buf, *dst_buf;
- unsigned long src_addr, dst_addr;
-
- src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
- dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
- src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
- dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
-
- jpeg_reset(jpeg->regs);
- jpeg_poweron(jpeg->regs);
- jpeg_proc_mode(jpeg->regs, ctx->mode);
- if (ctx->mode == S5P_JPEG_ENCODE) {
- if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
- jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_565);
- else
- jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_422);
- jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
- jpeg_dri(jpeg->regs, ctx->restart_interval);
- jpeg_x(jpeg->regs, ctx->out_q.w);
- jpeg_y(jpeg->regs, ctx->out_q.h);
- jpeg_imgadr(jpeg->regs, src_addr);
- jpeg_jpgadr(jpeg->regs, dst_addr);
-
- /* ultimately comes from sizeimage from userspace */
- jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
-
- /* JPEG RGB to YCbCr conversion matrix */
- jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
- jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
- jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
- jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
- jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
- jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
- jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
- jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
- jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
-
- /*
- * JPEG IP allows storing 4 quantization tables
- * We fill table 0 for luma and table 1 for chroma
- */
- jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
- jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
- /* use table 0 for Y */
- jpeg_qtbl(jpeg->regs, 1, 0);
- /* use table 1 for Cb and Cr*/
- jpeg_qtbl(jpeg->regs, 2, 1);
- jpeg_qtbl(jpeg->regs, 3, 1);
-
- /* Y, Cb, Cr use Huffman table 0 */
- jpeg_htbl_ac(jpeg->regs, 1);
- jpeg_htbl_dc(jpeg->regs, 1);
- jpeg_htbl_ac(jpeg->regs, 2);
- jpeg_htbl_dc(jpeg->regs, 2);
- jpeg_htbl_ac(jpeg->regs, 3);
- jpeg_htbl_dc(jpeg->regs, 3);
- } else { /* S5P_JPEG_DECODE */
- jpeg_rst_int_enable(jpeg->regs, true);
- jpeg_data_num_int_enable(jpeg->regs, true);
- jpeg_final_mcu_num_int_enable(jpeg->regs, true);
- if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
- jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
- else
- jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
- jpeg_jpgadr(jpeg->regs, src_addr);
- jpeg_imgadr(jpeg->regs, dst_addr);
- }
-
- jpeg_start(jpeg->regs);
-}
-
-static int s5p_jpeg_job_ready(void *priv)
-{
- struct s5p_jpeg_ctx *ctx = priv;
-
- if (ctx->mode == S5P_JPEG_DECODE)
- return ctx->hdr_parsed;
- return 1;
-}
-
-static void s5p_jpeg_job_abort(void *priv)
-{
-}
-
-static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
- .device_run = s5p_jpeg_device_run,
- .job_ready = s5p_jpeg_job_ready,
- .job_abort = s5p_jpeg_job_abort,
-};
-
-/*
- * ============================================================================
- * Queue operations
- * ============================================================================
- */
-
-static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
- unsigned int *nbuffers, unsigned int *nplanes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
- struct s5p_jpeg_q_data *q_data = NULL;
- unsigned int size, count = *nbuffers;
-
- q_data = get_q_data(ctx, vq->type);
- BUG_ON(q_data == NULL);
-
- size = q_data->size;
-
- /*
- * header is parsed during decoding and parsed information stored
- * in the context so we do not allow another buffer to overwrite it
- */
- if (ctx->mode == S5P_JPEG_DECODE)
- count = 1;
-
- *nbuffers = count;
- *nplanes = 1;
- sizes[0] = size;
- alloc_ctxs[0] = ctx->jpeg->alloc_ctx;
-
- return 0;
-}
-
-static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
-{
- struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct s5p_jpeg_q_data *q_data = NULL;
-
- q_data = get_q_data(ctx, vb->vb2_queue->type);
- BUG_ON(q_data == NULL);
-
- if (vb2_plane_size(vb, 0) < q_data->size) {
- pr_err("%s data will not fit into plane (%lu < %lu)\n",
- __func__, vb2_plane_size(vb, 0),
- (long)q_data->size);
- return -EINVAL;
- }
-
- vb2_set_plane_payload(vb, 0, q_data->size);
-
- return 0;
-}
-
-static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
-{
- struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-
- if (ctx->mode == S5P_JPEG_DECODE &&
- vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- struct s5p_jpeg_q_data tmp, *q_data;
- ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
- (unsigned long)vb2_plane_vaddr(vb, 0),
- min((unsigned long)ctx->out_q.size,
- vb2_get_plane_payload(vb, 0)));
- if (!ctx->hdr_parsed) {
- vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
- return;
- }
-
- q_data = &ctx->out_q;
- q_data->w = tmp.w;
- q_data->h = tmp.h;
-
- q_data = &ctx->cap_q;
- q_data->w = tmp.w;
- q_data->h = tmp.h;
-
- jpeg_bound_align_image(&q_data->w, S5P_JPEG_MIN_WIDTH,
- S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
- &q_data->h, S5P_JPEG_MIN_HEIGHT,
- S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align
- );
- q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
- }
- if (ctx->m2m_ctx)
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
-}
-
-static void s5p_jpeg_wait_prepare(struct vb2_queue *vq)
-{
- struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
-
- mutex_unlock(&ctx->jpeg->lock);
-}
-
-static void s5p_jpeg_wait_finish(struct vb2_queue *vq)
-{
- struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
-
- mutex_lock(&ctx->jpeg->lock);
-}
-
-static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
- int ret;
-
- ret = pm_runtime_get_sync(ctx->jpeg->dev);
-
- return ret > 0 ? 0 : ret;
-}
-
-static int s5p_jpeg_stop_streaming(struct vb2_queue *q)
-{
- struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
-
- pm_runtime_put(ctx->jpeg->dev);
-
- return 0;
-}
-
-static struct vb2_ops s5p_jpeg_qops = {
- .queue_setup = s5p_jpeg_queue_setup,
- .buf_prepare = s5p_jpeg_buf_prepare,
- .buf_queue = s5p_jpeg_buf_queue,
- .wait_prepare = s5p_jpeg_wait_prepare,
- .wait_finish = s5p_jpeg_wait_finish,
- .start_streaming = s5p_jpeg_start_streaming,
- .stop_streaming = s5p_jpeg_stop_streaming,
-};
-
-static int queue_init(void *priv, struct vb2_queue *src_vq,
- struct vb2_queue *dst_vq)
-{
- struct s5p_jpeg_ctx *ctx = priv;
- int ret;
-
- memset(src_vq, 0, sizeof(*src_vq));
- src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
- src_vq->drv_priv = ctx;
- src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
- src_vq->ops = &s5p_jpeg_qops;
- src_vq->mem_ops = &vb2_dma_contig_memops;
-
- ret = vb2_queue_init(src_vq);
- if (ret)
- return ret;
-
- memset(dst_vq, 0, sizeof(*dst_vq));
- dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
- dst_vq->drv_priv = ctx;
- dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
- dst_vq->ops = &s5p_jpeg_qops;
- dst_vq->mem_ops = &vb2_dma_contig_memops;
-
- return vb2_queue_init(dst_vq);
-}
-
-/*
- * ============================================================================
- * ISR
- * ============================================================================
- */
-
-static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
-{
- struct s5p_jpeg *jpeg = dev_id;
- struct s5p_jpeg_ctx *curr_ctx;
- struct vb2_buffer *src_buf, *dst_buf;
- unsigned long payload_size = 0;
- enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
- bool enc_jpeg_too_large = false;
- bool timer_elapsed = false;
- bool op_completed = false;
-
- spin_lock(&jpeg->slock);
-
- curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
-
- src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
- dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
-
- if (curr_ctx->mode == S5P_JPEG_ENCODE)
- enc_jpeg_too_large = jpeg_enc_stream_stat(jpeg->regs);
- timer_elapsed = jpeg_timer_stat(jpeg->regs);
- op_completed = jpeg_result_stat_ok(jpeg->regs);
- if (curr_ctx->mode == S5P_JPEG_DECODE)
- op_completed = op_completed && jpeg_stream_stat_ok(jpeg->regs);
-
- if (enc_jpeg_too_large) {
- state = VB2_BUF_STATE_ERROR;
- jpeg_clear_enc_stream_stat(jpeg->regs);
- } else if (timer_elapsed) {
- state = VB2_BUF_STATE_ERROR;
- jpeg_clear_timer_stat(jpeg->regs);
- } else if (!op_completed) {
- state = VB2_BUF_STATE_ERROR;
- } else {
- payload_size = jpeg_compressed_size(jpeg->regs);
- }
-
- v4l2_m2m_buf_done(src_buf, state);
- if (curr_ctx->mode == S5P_JPEG_ENCODE)
- vb2_set_plane_payload(dst_buf, 0, payload_size);
- v4l2_m2m_buf_done(dst_buf, state);
- v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->m2m_ctx);
-
- curr_ctx->subsampling = jpeg_get_subsampling_mode(jpeg->regs);
- spin_unlock(&jpeg->slock);
-
- jpeg_clear_int(jpeg->regs);
-
- return IRQ_HANDLED;
-}
-
-/*
- * ============================================================================
- * Driver basic infrastructure
- * ============================================================================
- */
-
-static int s5p_jpeg_probe(struct platform_device *pdev)
-{
- struct s5p_jpeg *jpeg;
- struct resource *res;
- int ret;
-
- /* JPEG IP abstraction struct */
- jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
- if (!jpeg)
- return -ENOMEM;
-
- mutex_init(&jpeg->lock);
- spin_lock_init(&jpeg->slock);
- jpeg->dev = &pdev->dev;
-
- /* memory-mapped registers */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- jpeg->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (jpeg->regs == NULL) {
- dev_err(&pdev->dev, "Failed to obtain io memory\n");
- return -ENOENT;
- }
-
- /* interrupt service routine registration */
- jpeg->irq = ret = platform_get_irq(pdev, 0);
- if (ret < 0) {
- dev_err(&pdev->dev, "cannot find IRQ\n");
- return ret;
- }
-
- ret = devm_request_irq(&pdev->dev, jpeg->irq, s5p_jpeg_irq, 0,
- dev_name(&pdev->dev), jpeg);
- if (ret) {
- dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
- return ret;
- }
-
- /* clocks */
- jpeg->clk = clk_get(&pdev->dev, "jpeg");
- if (IS_ERR(jpeg->clk)) {
- dev_err(&pdev->dev, "cannot get clock\n");
- ret = PTR_ERR(jpeg->clk);
- return ret;
- }
- dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
- clk_enable(jpeg->clk);
-
- /* v4l2 device */
- ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
- if (ret) {
- dev_err(&pdev->dev, "Failed to register v4l2 device\n");
- goto clk_get_rollback;
- }
-
- /* mem2mem device */
- jpeg->m2m_dev = v4l2_m2m_init(&s5p_jpeg_m2m_ops);
- if (IS_ERR(jpeg->m2m_dev)) {
- v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
- ret = PTR_ERR(jpeg->m2m_dev);
- goto device_register_rollback;
- }
-
- jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
- if (IS_ERR(jpeg->alloc_ctx)) {
- v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
- ret = PTR_ERR(jpeg->alloc_ctx);
- goto m2m_init_rollback;
- }
-
- /* JPEG encoder /dev/videoX node */
- jpeg->vfd_encoder = video_device_alloc();
- if (!jpeg->vfd_encoder) {
- v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
- ret = -ENOMEM;
- goto vb2_allocator_rollback;
- }
- strlcpy(jpeg->vfd_encoder->name, S5P_JPEG_M2M_NAME,
- sizeof(jpeg->vfd_encoder->name));
- jpeg->vfd_encoder->fops = &s5p_jpeg_fops;
- jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
- jpeg->vfd_encoder->minor = -1;
- jpeg->vfd_encoder->release = video_device_release;
- jpeg->vfd_encoder->lock = &jpeg->lock;
- jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &jpeg->vfd_encoder->flags);
-
- ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
- if (ret) {
- v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
- goto enc_vdev_alloc_rollback;
- }
-
- video_set_drvdata(jpeg->vfd_encoder, jpeg);
- v4l2_info(&jpeg->v4l2_dev,
- "encoder device registered as /dev/video%d\n",
- jpeg->vfd_encoder->num);
-
- /* JPEG decoder /dev/videoX node */
- jpeg->vfd_decoder = video_device_alloc();
- if (!jpeg->vfd_decoder) {
- v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
- ret = -ENOMEM;
- goto enc_vdev_register_rollback;
- }
- strlcpy(jpeg->vfd_decoder->name, S5P_JPEG_M2M_NAME,
- sizeof(jpeg->vfd_decoder->name));
- jpeg->vfd_decoder->fops = &s5p_jpeg_fops;
- jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
- jpeg->vfd_decoder->minor = -1;
- jpeg->vfd_decoder->release = video_device_release;
- jpeg->vfd_decoder->lock = &jpeg->lock;
- jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev;
- /* Locking in file operations other than ioctl should be done by the driver,
- not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &jpeg->vfd_decoder->flags);
-
- ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
- if (ret) {
- v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
- goto dec_vdev_alloc_rollback;
- }
-
- video_set_drvdata(jpeg->vfd_decoder, jpeg);
- v4l2_info(&jpeg->v4l2_dev,
- "decoder device registered as /dev/video%d\n",
- jpeg->vfd_decoder->num);
-
- /* final statements & power management */
- platform_set_drvdata(pdev, jpeg);
-
- pm_runtime_enable(&pdev->dev);
-
- v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
-
- return 0;
-
-dec_vdev_alloc_rollback:
- video_device_release(jpeg->vfd_decoder);
-
-enc_vdev_register_rollback:
- video_unregister_device(jpeg->vfd_encoder);
-
-enc_vdev_alloc_rollback:
- video_device_release(jpeg->vfd_encoder);
-
-vb2_allocator_rollback:
- vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
-
-m2m_init_rollback:
- v4l2_m2m_release(jpeg->m2m_dev);
-
-device_register_rollback:
- v4l2_device_unregister(&jpeg->v4l2_dev);
-
-clk_get_rollback:
- clk_disable(jpeg->clk);
- clk_put(jpeg->clk);
-
- return ret;
-}
-
-static int s5p_jpeg_remove(struct platform_device *pdev)
-{
- struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
-
- pm_runtime_disable(jpeg->dev);
-
- video_unregister_device(jpeg->vfd_decoder);
- video_device_release(jpeg->vfd_decoder);
- video_unregister_device(jpeg->vfd_encoder);
- video_device_release(jpeg->vfd_encoder);
- vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
- v4l2_m2m_release(jpeg->m2m_dev);
- v4l2_device_unregister(&jpeg->v4l2_dev);
-
- clk_disable(jpeg->clk);
- clk_put(jpeg->clk);
-
- return 0;
-}
-
-static int s5p_jpeg_runtime_suspend(struct device *dev)
-{
- return 0;
-}
-
-static int s5p_jpeg_runtime_resume(struct device *dev)
-{
- struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
- /*
- * JPEG IP allows storing two Huffman tables for each component
- * We fill table 0 for each component
- */
- jpeg_set_hdctbl(jpeg->regs);
- jpeg_set_hdctblg(jpeg->regs);
- jpeg_set_hactbl(jpeg->regs);
- jpeg_set_hactblg(jpeg->regs);
- return 0;
-}
-
-static const struct dev_pm_ops s5p_jpeg_pm_ops = {
- .runtime_suspend = s5p_jpeg_runtime_suspend,
- .runtime_resume = s5p_jpeg_runtime_resume,
-};
-
-static struct platform_driver s5p_jpeg_driver = {
- .probe = s5p_jpeg_probe,
- .remove = s5p_jpeg_remove,
- .driver = {
- .owner = THIS_MODULE,
- .name = S5P_JPEG_M2M_NAME,
- .pm = &s5p_jpeg_pm_ops,
- },
-};
-
-module_platform_driver(s5p_jpeg_driver);
-
-MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
-MODULE_DESCRIPTION("Samsung JPEG codec driver");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/media/video/s5p-jpeg/jpeg-core.h b/drivers/media/video/s5p-jpeg/jpeg-core.h
deleted file mode 100644
index 9d0cd2b76f6..00000000000
--- a/drivers/media/video/s5p-jpeg/jpeg-core.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/* linux/drivers/media/video/s5p-jpeg/jpeg-core.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef JPEG_CORE_H_
-#define JPEG_CORE_H_
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-ctrls.h>
-
-#define S5P_JPEG_M2M_NAME "s5p-jpeg"
-
-/* JPEG compression quality setting */
-#define S5P_JPEG_COMPR_QUAL_BEST 0
-#define S5P_JPEG_COMPR_QUAL_WORST 3
-
-/* JPEG RGB to YCbCr conversion matrix coefficients */
-#define S5P_JPEG_COEF11 0x4d
-#define S5P_JPEG_COEF12 0x97
-#define S5P_JPEG_COEF13 0x1e
-#define S5P_JPEG_COEF21 0x2c
-#define S5P_JPEG_COEF22 0x57
-#define S5P_JPEG_COEF23 0x83
-#define S5P_JPEG_COEF31 0x83
-#define S5P_JPEG_COEF32 0x6e
-#define S5P_JPEG_COEF33 0x13
-
-/* a selection of JPEG markers */
-#define TEM 0x01
-#define SOF0 0xc0
-#define RST 0xd0
-#define SOI 0xd8
-#define EOI 0xd9
-#define DHP 0xde
-
-/* Flags that indicate a format can be used for capture/output */
-#define MEM2MEM_CAPTURE (1 << 0)
-#define MEM2MEM_OUTPUT (1 << 1)
-
-/**
- * struct s5p_jpeg - JPEG IP abstraction
- * @lock: the mutex protecting this structure
- * @slock: spinlock protecting the device contexts
- * @v4l2_dev: v4l2 device for mem2mem mode
- * @vfd_encoder: video device node for encoder mem2mem mode
- * @vfd_decoder: video device node for decoder mem2mem mode
- * @m2m_dev: v4l2 mem2mem device data
- * @regs: JPEG IP registers mapping
- * @irq: JPEG IP irq
- * @clk: JPEG IP clock
- * @dev: JPEG IP struct device
- * @alloc_ctx: videobuf2 memory allocator's context
- */
-struct s5p_jpeg {
- struct mutex lock;
- struct spinlock slock;
-
- struct v4l2_device v4l2_dev;
- struct video_device *vfd_encoder;
- struct video_device *vfd_decoder;
- struct v4l2_m2m_dev *m2m_dev;
-
- void __iomem *regs;
- unsigned int irq;
- struct clk *clk;
- struct device *dev;
- void *alloc_ctx;
-};
-
-/**
- * struct jpeg_fmt - driver's internal color format data
- * @name: format descritpion
- * @fourcc: the fourcc code, 0 if not applicable
- * @depth: number of bits per pixel
- * @colplanes: number of color planes (1 for packed formats)
- * @h_align: horizontal alignment order (align to 2^h_align)
- * @v_align: vertical alignment order (align to 2^v_align)
- * @types: types of queue this format is applicable to
- */
-struct s5p_jpeg_fmt {
- char *name;
- u32 fourcc;
- int depth;
- int colplanes;
- int h_align;
- int v_align;
- u32 types;
-};
-
-/**
- * s5p_jpeg_q_data - parameters of one queue
- * @fmt: driver-specific format of this queue
- * @w: image width
- * @h: image height
- * @size: image buffer size in bytes
- */
-struct s5p_jpeg_q_data {
- struct s5p_jpeg_fmt *fmt;
- u32 w;
- u32 h;
- u32 size;
-};
-
-/**
- * s5p_jpeg_ctx - the device context data
- * @jpeg: JPEG IP device for this context
- * @mode: compression (encode) operation or decompression (decode)
- * @compr_quality: destination image quality in compression (encode) mode
- * @m2m_ctx: mem2mem device context
- * @out_q: source (output) queue information
- * @cap_fmt: destination (capture) queue queue information
- * @hdr_parsed: set if header has been parsed during decompression
- * @ctrl_handler: controls handler
- */
-struct s5p_jpeg_ctx {
- struct s5p_jpeg *jpeg;
- unsigned int mode;
- unsigned short compr_quality;
- unsigned short restart_interval;
- unsigned short subsampling;
- struct v4l2_m2m_ctx *m2m_ctx;
- struct s5p_jpeg_q_data out_q;
- struct s5p_jpeg_q_data cap_q;
- struct v4l2_fh fh;
- bool hdr_parsed;
- struct v4l2_ctrl_handler ctrl_handler;
-};
-
-/**
- * s5p_jpeg_buffer - description of memory containing input JPEG data
- * @size: buffer size
- * @curr: current position in the buffer
- * @data: pointer to the data
- */
-struct s5p_jpeg_buffer {
- unsigned long size;
- unsigned long curr;
- unsigned long data;
-};
-
-#endif /* JPEG_CORE_H */
diff --git a/drivers/media/video/s5p-jpeg/jpeg-hw.h b/drivers/media/video/s5p-jpeg/jpeg-hw.h
deleted file mode 100644
index f12f0fdbde7..00000000000
--- a/drivers/media/video/s5p-jpeg/jpeg-hw.h
+++ /dev/null
@@ -1,357 +0,0 @@
-/* linux/drivers/media/video/s5p-jpeg/jpeg-hw.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef JPEG_HW_H_
-#define JPEG_HW_H_
-
-#include <linux/io.h>
-#include <linux/videodev2.h>
-
-#include "jpeg-hw.h"
-#include "jpeg-regs.h"
-
-#define S5P_JPEG_MIN_WIDTH 32
-#define S5P_JPEG_MIN_HEIGHT 32
-#define S5P_JPEG_MAX_WIDTH 8192
-#define S5P_JPEG_MAX_HEIGHT 8192
-#define S5P_JPEG_ENCODE 0
-#define S5P_JPEG_DECODE 1
-#define S5P_JPEG_RAW_IN_565 0
-#define S5P_JPEG_RAW_IN_422 1
-#define S5P_JPEG_RAW_OUT_422 0
-#define S5P_JPEG_RAW_OUT_420 1
-
-static inline void jpeg_reset(void __iomem *regs)
-{
- unsigned long reg;
-
- writel(1, regs + S5P_JPG_SW_RESET);
- reg = readl(regs + S5P_JPG_SW_RESET);
- /* no other way but polling for when JPEG IP becomes operational */
- while (reg != 0) {
- cpu_relax();
- reg = readl(regs + S5P_JPG_SW_RESET);
- }
-}
-
-static inline void jpeg_poweron(void __iomem *regs)
-{
- writel(S5P_POWER_ON, regs + S5P_JPGCLKCON);
-}
-
-static inline void jpeg_input_raw_mode(void __iomem *regs, unsigned long mode)
-{
- unsigned long reg, m;
-
- m = S5P_MOD_SEL_565;
- if (mode == S5P_JPEG_RAW_IN_565)
- m = S5P_MOD_SEL_565;
- else if (mode == S5P_JPEG_RAW_IN_422)
- m = S5P_MOD_SEL_422;
-
- reg = readl(regs + S5P_JPGCMOD);
- reg &= ~S5P_MOD_SEL_MASK;
- reg |= m;
- writel(reg, regs + S5P_JPGCMOD);
-}
-
-static inline void jpeg_input_raw_y16(void __iomem *regs, bool y16)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPGCMOD);
- if (y16)
- reg |= S5P_MODE_Y16;
- else
- reg &= ~S5P_MODE_Y16_MASK;
- writel(reg, regs + S5P_JPGCMOD);
-}
-
-static inline void jpeg_proc_mode(void __iomem *regs, unsigned long mode)
-{
- unsigned long reg, m;
-
- m = S5P_PROC_MODE_DECOMPR;
- if (mode == S5P_JPEG_ENCODE)
- m = S5P_PROC_MODE_COMPR;
- else
- m = S5P_PROC_MODE_DECOMPR;
- reg = readl(regs + S5P_JPGMOD);
- reg &= ~S5P_PROC_MODE_MASK;
- reg |= m;
- writel(reg, regs + S5P_JPGMOD);
-}
-
-static inline void jpeg_subsampling_mode(void __iomem *regs, unsigned int mode)
-{
- unsigned long reg, m;
-
- if (mode == V4L2_JPEG_CHROMA_SUBSAMPLING_420)
- m = S5P_SUBSAMPLING_MODE_420;
- else
- m = S5P_SUBSAMPLING_MODE_422;
-
- reg = readl(regs + S5P_JPGMOD);
- reg &= ~S5P_SUBSAMPLING_MODE_MASK;
- reg |= m;
- writel(reg, regs + S5P_JPGMOD);
-}
-
-static inline unsigned int jpeg_get_subsampling_mode(void __iomem *regs)
-{
- return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK;
-}
-
-static inline void jpeg_dri(void __iomem *regs, unsigned int dri)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPGDRI_U);
- reg &= ~0xff;
- reg |= (dri >> 8) & 0xff;
- writel(reg, regs + S5P_JPGDRI_U);
-
- reg = readl(regs + S5P_JPGDRI_L);
- reg &= ~0xff;
- reg |= dri & 0xff;
- writel(reg, regs + S5P_JPGDRI_L);
-}
-
-static inline void jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPG_QTBL);
- reg &= ~S5P_QT_NUMt_MASK(t);
- reg |= (n << S5P_QT_NUMt_SHIFT(t)) & S5P_QT_NUMt_MASK(t);
- writel(reg, regs + S5P_JPG_QTBL);
-}
-
-static inline void jpeg_htbl_ac(void __iomem *regs, unsigned int t)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPG_HTBL);
- reg &= ~S5P_HT_NUMt_AC_MASK(t);
- /* this driver uses table 0 for all color components */
- reg |= (0 << S5P_HT_NUMt_AC_SHIFT(t)) & S5P_HT_NUMt_AC_MASK(t);
- writel(reg, regs + S5P_JPG_HTBL);
-}
-
-static inline void jpeg_htbl_dc(void __iomem *regs, unsigned int t)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPG_HTBL);
- reg &= ~S5P_HT_NUMt_DC_MASK(t);
- /* this driver uses table 0 for all color components */
- reg |= (0 << S5P_HT_NUMt_DC_SHIFT(t)) & S5P_HT_NUMt_DC_MASK(t);
- writel(reg, regs + S5P_JPG_HTBL);
-}
-
-static inline void jpeg_y(void __iomem *regs, unsigned int y)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPGY_U);
- reg &= ~0xff;
- reg |= (y >> 8) & 0xff;
- writel(reg, regs + S5P_JPGY_U);
-
- reg = readl(regs + S5P_JPGY_L);
- reg &= ~0xff;
- reg |= y & 0xff;
- writel(reg, regs + S5P_JPGY_L);
-}
-
-static inline void jpeg_x(void __iomem *regs, unsigned int x)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPGX_U);
- reg &= ~0xff;
- reg |= (x >> 8) & 0xff;
- writel(reg, regs + S5P_JPGX_U);
-
- reg = readl(regs + S5P_JPGX_L);
- reg &= ~0xff;
- reg |= x & 0xff;
- writel(reg, regs + S5P_JPGX_L);
-}
-
-static inline void jpeg_rst_int_enable(void __iomem *regs, bool enable)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPGINTSE);
- reg &= ~S5P_RSTm_INT_EN_MASK;
- if (enable)
- reg |= S5P_RSTm_INT_EN;
- writel(reg, regs + S5P_JPGINTSE);
-}
-
-static inline void jpeg_data_num_int_enable(void __iomem *regs, bool enable)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPGINTSE);
- reg &= ~S5P_DATA_NUM_INT_EN_MASK;
- if (enable)
- reg |= S5P_DATA_NUM_INT_EN;
- writel(reg, regs + S5P_JPGINTSE);
-}
-
-static inline void jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPGINTSE);
- reg &= ~S5P_FINAL_MCU_NUM_INT_EN_MASK;
- if (enbl)
- reg |= S5P_FINAL_MCU_NUM_INT_EN;
- writel(reg, regs + S5P_JPGINTSE);
-}
-
-static inline void jpeg_timer_enable(void __iomem *regs, unsigned long val)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPG_TIMER_SE);
- reg |= S5P_TIMER_INT_EN;
- reg &= ~S5P_TIMER_INIT_MASK;
- reg |= val & S5P_TIMER_INIT_MASK;
- writel(reg, regs + S5P_JPG_TIMER_SE);
-}
-
-static inline void jpeg_timer_disable(void __iomem *regs)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPG_TIMER_SE);
- reg &= ~S5P_TIMER_INT_EN_MASK;
- writel(reg, regs + S5P_JPG_TIMER_SE);
-}
-
-static inline int jpeg_timer_stat(void __iomem *regs)
-{
- return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK)
- >> S5P_TIMER_INT_STAT_SHIFT);
-}
-
-static inline void jpeg_clear_timer_stat(void __iomem *regs)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPG_TIMER_SE);
- reg &= ~S5P_TIMER_INT_STAT_MASK;
- writel(reg, regs + S5P_JPG_TIMER_SE);
-}
-
-static inline void jpeg_enc_stream_int(void __iomem *regs, unsigned long size)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE);
- reg &= ~S5P_ENC_STREAM_BOUND_MASK;
- reg |= S5P_ENC_STREAM_INT_EN;
- reg |= size & S5P_ENC_STREAM_BOUND_MASK;
- writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE);
-}
-
-static inline int jpeg_enc_stream_stat(void __iomem *regs)
-{
- return (int)(readl(regs + S5P_JPG_ENC_STREAM_INTST) &
- S5P_ENC_STREAM_INT_STAT_MASK);
-}
-
-static inline void jpeg_clear_enc_stream_stat(void __iomem *regs)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE);
- reg &= ~S5P_ENC_STREAM_INT_MASK;
- writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE);
-}
-
-static inline void jpeg_outform_raw(void __iomem *regs, unsigned long format)
-{
- unsigned long reg, f;
-
- f = S5P_DEC_OUT_FORMAT_422;
- if (format == S5P_JPEG_RAW_OUT_422)
- f = S5P_DEC_OUT_FORMAT_422;
- else if (format == S5P_JPEG_RAW_OUT_420)
- f = S5P_DEC_OUT_FORMAT_420;
- reg = readl(regs + S5P_JPG_OUTFORM);
- reg &= ~S5P_DEC_OUT_FORMAT_MASK;
- reg |= f;
- writel(reg, regs + S5P_JPG_OUTFORM);
-}
-
-static inline void jpeg_jpgadr(void __iomem *regs, unsigned long addr)
-{
- writel(addr, regs + S5P_JPG_JPGADR);
-}
-
-static inline void jpeg_imgadr(void __iomem *regs, unsigned long addr)
-{
- writel(addr, regs + S5P_JPG_IMGADR);
-}
-
-static inline void jpeg_coef(void __iomem *regs, unsigned int i,
- unsigned int j, unsigned int coef)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPG_COEF(i));
- reg &= ~S5P_COEFn_MASK(j);
- reg |= (coef << S5P_COEFn_SHIFT(j)) & S5P_COEFn_MASK(j);
- writel(reg, regs + S5P_JPG_COEF(i));
-}
-
-static inline void jpeg_start(void __iomem *regs)
-{
- writel(1, regs + S5P_JSTART);
-}
-
-static inline int jpeg_result_stat_ok(void __iomem *regs)
-{
- return (int)((readl(regs + S5P_JPGINTST) & S5P_RESULT_STAT_MASK)
- >> S5P_RESULT_STAT_SHIFT);
-}
-
-static inline int jpeg_stream_stat_ok(void __iomem *regs)
-{
- return !(int)((readl(regs + S5P_JPGINTST) & S5P_STREAM_STAT_MASK)
- >> S5P_STREAM_STAT_SHIFT);
-}
-
-static inline void jpeg_clear_int(void __iomem *regs)
-{
- unsigned long reg;
-
- reg = readl(regs + S5P_JPGINTST);
- writel(S5P_INT_RELEASE, regs + S5P_JPGCOM);
- reg = readl(regs + S5P_JPGOPR);
-}
-
-static inline unsigned int jpeg_compressed_size(void __iomem *regs)
-{
- unsigned long jpeg_size = 0;
-
- jpeg_size |= (readl(regs + S5P_JPGCNT_U) & 0xff) << 16;
- jpeg_size |= (readl(regs + S5P_JPGCNT_M) & 0xff) << 8;
- jpeg_size |= (readl(regs + S5P_JPGCNT_L) & 0xff);
-
- return (unsigned int)jpeg_size;
-}
-
-#endif /* JPEG_HW_H_ */
diff --git a/drivers/media/video/s5p-jpeg/jpeg-regs.h b/drivers/media/video/s5p-jpeg/jpeg-regs.h
deleted file mode 100644
index 91f4dd5f86d..00000000000
--- a/drivers/media/video/s5p-jpeg/jpeg-regs.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/* linux/drivers/media/video/s5p-jpeg/jpeg-regs.h
- *
- * Register definition file for Samsung JPEG codec driver
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef JPEG_REGS_H_
-#define JPEG_REGS_H_
-
-/* JPEG mode register */
-#define S5P_JPGMOD 0x00
-#define S5P_PROC_MODE_MASK (0x1 << 3)
-#define S5P_PROC_MODE_DECOMPR (0x1 << 3)
-#define S5P_PROC_MODE_COMPR (0x0 << 3)
-#define S5P_SUBSAMPLING_MODE_MASK 0x7
-#define S5P_SUBSAMPLING_MODE_444 (0x0 << 0)
-#define S5P_SUBSAMPLING_MODE_422 (0x1 << 0)
-#define S5P_SUBSAMPLING_MODE_420 (0x2 << 0)
-#define S5P_SUBSAMPLING_MODE_GRAY (0x3 << 0)
-
-/* JPEG operation status register */
-#define S5P_JPGOPR 0x04
-
-/* Quantization tables*/
-#define S5P_JPG_QTBL 0x08
-#define S5P_QT_NUMt_SHIFT(t) (((t) - 1) << 1)
-#define S5P_QT_NUMt_MASK(t) (0x3 << S5P_QT_NUMt_SHIFT(t))
-
-/* Huffman tables */
-#define S5P_JPG_HTBL 0x0c
-#define S5P_HT_NUMt_AC_SHIFT(t) (((t) << 1) - 1)
-#define S5P_HT_NUMt_AC_MASK(t) (0x1 << S5P_HT_NUMt_AC_SHIFT(t))
-
-#define S5P_HT_NUMt_DC_SHIFT(t) (((t) - 1) << 1)
-#define S5P_HT_NUMt_DC_MASK(t) (0x1 << S5P_HT_NUMt_DC_SHIFT(t))
-
-/* JPEG restart interval register upper byte */
-#define S5P_JPGDRI_U 0x10
-
-/* JPEG restart interval register lower byte */
-#define S5P_JPGDRI_L 0x14
-
-/* JPEG vertical resolution register upper byte */
-#define S5P_JPGY_U 0x18
-
-/* JPEG vertical resolution register lower byte */
-#define S5P_JPGY_L 0x1c
-
-/* JPEG horizontal resolution register upper byte */
-#define S5P_JPGX_U 0x20
-
-/* JPEG horizontal resolution register lower byte */
-#define S5P_JPGX_L 0x24
-
-/* JPEG byte count register upper byte */
-#define S5P_JPGCNT_U 0x28
-
-/* JPEG byte count register middle byte */
-#define S5P_JPGCNT_M 0x2c
-
-/* JPEG byte count register lower byte */
-#define S5P_JPGCNT_L 0x30
-
-/* JPEG interrupt setting register */
-#define S5P_JPGINTSE 0x34
-#define S5P_RSTm_INT_EN_MASK (0x1 << 7)
-#define S5P_RSTm_INT_EN (0x1 << 7)
-#define S5P_DATA_NUM_INT_EN_MASK (0x1 << 6)
-#define S5P_DATA_NUM_INT_EN (0x1 << 6)
-#define S5P_FINAL_MCU_NUM_INT_EN_MASK (0x1 << 5)
-#define S5P_FINAL_MCU_NUM_INT_EN (0x1 << 5)
-
-/* JPEG interrupt status register */
-#define S5P_JPGINTST 0x38
-#define S5P_RESULT_STAT_SHIFT 6
-#define S5P_RESULT_STAT_MASK (0x1 << S5P_RESULT_STAT_SHIFT)
-#define S5P_STREAM_STAT_SHIFT 5
-#define S5P_STREAM_STAT_MASK (0x1 << S5P_STREAM_STAT_SHIFT)
-
-/* JPEG command register */
-#define S5P_JPGCOM 0x4c
-#define S5P_INT_RELEASE (0x1 << 2)
-
-/* Raw image data r/w address register */
-#define S5P_JPG_IMGADR 0x50
-
-/* JPEG file r/w address register */
-#define S5P_JPG_JPGADR 0x58
-
-/* Coefficient for RGB-to-YCbCr converter register */
-#define S5P_JPG_COEF(n) (0x5c + (((n) - 1) << 2))
-#define S5P_COEFn_SHIFT(j) ((3 - (j)) << 3)
-#define S5P_COEFn_MASK(j) (0xff << S5P_COEFn_SHIFT(j))
-
-/* JPEG color mode register */
-#define S5P_JPGCMOD 0x68
-#define S5P_MOD_SEL_MASK (0x7 << 5)
-#define S5P_MOD_SEL_422 (0x1 << 5)
-#define S5P_MOD_SEL_565 (0x2 << 5)
-#define S5P_MODE_Y16_MASK (0x1 << 1)
-#define S5P_MODE_Y16 (0x1 << 1)
-
-/* JPEG clock control register */
-#define S5P_JPGCLKCON 0x6c
-#define S5P_CLK_DOWN_READY (0x1 << 1)
-#define S5P_POWER_ON (0x1 << 0)
-
-/* JPEG start register */
-#define S5P_JSTART 0x70
-
-/* JPEG SW reset register */
-#define S5P_JPG_SW_RESET 0x78
-
-/* JPEG timer setting register */
-#define S5P_JPG_TIMER_SE 0x7c
-#define S5P_TIMER_INT_EN_MASK (0x1 << 31)
-#define S5P_TIMER_INT_EN (0x1 << 31)
-#define S5P_TIMER_INIT_MASK 0x7fffffff
-
-/* JPEG timer status register */
-#define S5P_JPG_TIMER_ST 0x80
-#define S5P_TIMER_INT_STAT_SHIFT 31
-#define S5P_TIMER_INT_STAT_MASK (0x1 << S5P_TIMER_INT_STAT_SHIFT)
-#define S5P_TIMER_CNT_SHIFT 0
-#define S5P_TIMER_CNT_MASK 0x7fffffff
-
-/* JPEG decompression output format register */
-#define S5P_JPG_OUTFORM 0x88
-#define S5P_DEC_OUT_FORMAT_MASK (0x1 << 0)
-#define S5P_DEC_OUT_FORMAT_422 (0x0 << 0)
-#define S5P_DEC_OUT_FORMAT_420 (0x1 << 0)
-
-/* JPEG version register */
-#define S5P_JPG_VERSION 0x8c
-
-/* JPEG compressed stream size interrupt setting register */
-#define S5P_JPG_ENC_STREAM_INTSE 0x98
-#define S5P_ENC_STREAM_INT_MASK (0x1 << 24)
-#define S5P_ENC_STREAM_INT_EN (0x1 << 24)
-#define S5P_ENC_STREAM_BOUND_MASK 0xffffff
-
-/* JPEG compressed stream size interrupt status register */
-#define S5P_JPG_ENC_STREAM_INTST 0x9c
-#define S5P_ENC_STREAM_INT_STAT_MASK 0x1
-
-/* JPEG quantizer table register */
-#define S5P_JPG_QTBL_CONTENT(n) (0x400 + (n) * 0x100)
-
-/* JPEG DC Huffman table register */
-#define S5P_JPG_HDCTBL(n) (0x800 + (n) * 0x400)
-
-/* JPEG DC Huffman table register */
-#define S5P_JPG_HDCTBLG(n) (0x840 + (n) * 0x400)
-
-/* JPEG AC Huffman table register */
-#define S5P_JPG_HACTBL(n) (0x880 + (n) * 0x400)
-
-/* JPEG AC Huffman table register */
-#define S5P_JPG_HACTBLG(n) (0x8c0 + (n) * 0x400)
-
-#endif /* JPEG_REGS_H_ */
-
diff --git a/drivers/media/video/s5p-mfc/Makefile b/drivers/media/video/s5p-mfc/Makefile
deleted file mode 100644
index d0663409af0..00000000000
--- a/drivers/media/video/s5p-mfc/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o
-s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o s5p_mfc_opr.o
-s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o
-s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_cmd.o
-s5p-mfc-y += s5p_mfc_pm.o s5p_mfc_shm.o
diff --git a/drivers/media/video/s5p-mfc/regs-mfc.h b/drivers/media/video/s5p-mfc/regs-mfc.h
deleted file mode 100644
index a19bece41ba..00000000000
--- a/drivers/media/video/s5p-mfc/regs-mfc.h
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Register definition file for Samsung MFC V5.1 Interface (FIMV) driver
- *
- * Kamil Debski, Copyright (c) 2010 Samsung Electronics
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef _REGS_FIMV_H
-#define _REGS_FIMV_H
-
-#define S5P_FIMV_REG_SIZE (S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR)
-#define S5P_FIMV_REG_COUNT ((S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR) / 4)
-
-/* Number of bits that the buffer address should be shifted for particular
- * MFC buffers. */
-#define S5P_FIMV_START_ADDR 0x0000
-#define S5P_FIMV_END_ADDR 0xe008
-
-#define S5P_FIMV_SW_RESET 0x0000
-#define S5P_FIMV_RISC_HOST_INT 0x0008
-
-/* Command from HOST to RISC */
-#define S5P_FIMV_HOST2RISC_CMD 0x0030
-#define S5P_FIMV_HOST2RISC_ARG1 0x0034
-#define S5P_FIMV_HOST2RISC_ARG2 0x0038
-#define S5P_FIMV_HOST2RISC_ARG3 0x003c
-#define S5P_FIMV_HOST2RISC_ARG4 0x0040
-
-/* Command from RISC to HOST */
-#define S5P_FIMV_RISC2HOST_CMD 0x0044
-#define S5P_FIMV_RISC2HOST_CMD_MASK 0x1FFFF
-#define S5P_FIMV_RISC2HOST_ARG1 0x0048
-#define S5P_FIMV_RISC2HOST_ARG2 0x004c
-#define S5P_FIMV_RISC2HOST_ARG3 0x0050
-#define S5P_FIMV_RISC2HOST_ARG4 0x0054
-
-#define S5P_FIMV_FW_VERSION 0x0058
-#define S5P_FIMV_SYS_MEM_SZ 0x005c
-#define S5P_FIMV_FW_STATUS 0x0080
-
-/* Memory controller register */
-#define S5P_FIMV_MC_DRAMBASE_ADR_A 0x0508
-#define S5P_FIMV_MC_DRAMBASE_ADR_B 0x050c
-#define S5P_FIMV_MC_STATUS 0x0510
-
-/* Common register */
-#define S5P_FIMV_COMMON_BASE_A 0x0600
-#define S5P_FIMV_COMMON_BASE_B 0x0700
-
-/* Decoder */
-#define S5P_FIMV_DEC_CHROMA_ADR (S5P_FIMV_COMMON_BASE_A)
-#define S5P_FIMV_DEC_LUMA_ADR (S5P_FIMV_COMMON_BASE_B)
-
-/* H.264 decoding */
-#define S5P_FIMV_H264_VERT_NB_MV_ADR (S5P_FIMV_COMMON_BASE_A + 0x8c)
- /* vertical neighbor motion vector */
-#define S5P_FIMV_H264_NB_IP_ADR (S5P_FIMV_COMMON_BASE_A + 0x90)
- /* neighbor pixels for intra pred */
-#define S5P_FIMV_H264_MV_ADR (S5P_FIMV_COMMON_BASE_B + 0x80)
- /* H264 motion vector */
-
-/* MPEG4 decoding */
-#define S5P_FIMV_MPEG4_NB_DCAC_ADR (S5P_FIMV_COMMON_BASE_A + 0x8c)
- /* neighbor AC/DC coeff. */
-#define S5P_FIMV_MPEG4_UP_NB_MV_ADR (S5P_FIMV_COMMON_BASE_A + 0x90)
- /* upper neighbor motion vector */
-#define S5P_FIMV_MPEG4_SA_MV_ADR (S5P_FIMV_COMMON_BASE_A + 0x94)
- /* subseq. anchor motion vector */
-#define S5P_FIMV_MPEG4_OT_LINE_ADR (S5P_FIMV_COMMON_BASE_A + 0x98)
- /* overlap transform line */
-#define S5P_FIMV_MPEG4_SP_ADR (S5P_FIMV_COMMON_BASE_A + 0xa8)
- /* syntax parser */
-
-/* H.263 decoding */
-#define S5P_FIMV_H263_NB_DCAC_ADR (S5P_FIMV_COMMON_BASE_A + 0x8c)
-#define S5P_FIMV_H263_UP_NB_MV_ADR (S5P_FIMV_COMMON_BASE_A + 0x90)
-#define S5P_FIMV_H263_SA_MV_ADR (S5P_FIMV_COMMON_BASE_A + 0x94)
-#define S5P_FIMV_H263_OT_LINE_ADR (S5P_FIMV_COMMON_BASE_A + 0x98)
-
-/* VC-1 decoding */
-#define S5P_FIMV_VC1_NB_DCAC_ADR (S5P_FIMV_COMMON_BASE_A + 0x8c)
-#define S5P_FIMV_VC1_UP_NB_MV_ADR (S5P_FIMV_COMMON_BASE_A + 0x90)
-#define S5P_FIMV_VC1_SA_MV_ADR (S5P_FIMV_COMMON_BASE_A + 0x94)
-#define S5P_FIMV_VC1_OT_LINE_ADR (S5P_FIMV_COMMON_BASE_A + 0x98)
-#define S5P_FIMV_VC1_BITPLANE3_ADR (S5P_FIMV_COMMON_BASE_A + 0x9c)
- /* bitplane3 */
-#define S5P_FIMV_VC1_BITPLANE2_ADR (S5P_FIMV_COMMON_BASE_A + 0xa0)
- /* bitplane2 */
-#define S5P_FIMV_VC1_BITPLANE1_ADR (S5P_FIMV_COMMON_BASE_A + 0xa4)
- /* bitplane1 */
-
-/* Encoder */
-#define S5P_FIMV_ENC_REF0_LUMA_ADR (S5P_FIMV_COMMON_BASE_A + 0x1c)
-#define S5P_FIMV_ENC_REF1_LUMA_ADR (S5P_FIMV_COMMON_BASE_A + 0x20)
- /* reconstructed luma */
-#define S5P_FIMV_ENC_REF0_CHROMA_ADR (S5P_FIMV_COMMON_BASE_B)
-#define S5P_FIMV_ENC_REF1_CHROMA_ADR (S5P_FIMV_COMMON_BASE_B + 0x04)
- /* reconstructed chroma */
-#define S5P_FIMV_ENC_REF2_LUMA_ADR (S5P_FIMV_COMMON_BASE_B + 0x10)
-#define S5P_FIMV_ENC_REF2_CHROMA_ADR (S5P_FIMV_COMMON_BASE_B + 0x08)
-#define S5P_FIMV_ENC_REF3_LUMA_ADR (S5P_FIMV_COMMON_BASE_B + 0x14)
-#define S5P_FIMV_ENC_REF3_CHROMA_ADR (S5P_FIMV_COMMON_BASE_B + 0x0c)
-
-/* H.264 encoding */
-#define S5P_FIMV_H264_UP_MV_ADR (S5P_FIMV_COMMON_BASE_A)
- /* upper motion vector */
-#define S5P_FIMV_H264_NBOR_INFO_ADR (S5P_FIMV_COMMON_BASE_A + 0x04)
- /* entropy engine's neighbor info. */
-#define S5P_FIMV_H264_UP_INTRA_MD_ADR (S5P_FIMV_COMMON_BASE_A + 0x08)
- /* upper intra MD */
-#define S5P_FIMV_H264_COZERO_FLAG_ADR (S5P_FIMV_COMMON_BASE_A + 0x10)
- /* direct cozero flag */
-#define S5P_FIMV_H264_UP_INTRA_PRED_ADR (S5P_FIMV_COMMON_BASE_B + 0x40)
- /* upper intra PRED */
-
-/* H.263 encoding */
-#define S5P_FIMV_H263_UP_MV_ADR (S5P_FIMV_COMMON_BASE_A)
- /* upper motion vector */
-#define S5P_FIMV_H263_ACDC_COEF_ADR (S5P_FIMV_COMMON_BASE_A + 0x04)
- /* upper Q coeff. */
-
-/* MPEG4 encoding */
-#define S5P_FIMV_MPEG4_UP_MV_ADR (S5P_FIMV_COMMON_BASE_A)
- /* upper motion vector */
-#define S5P_FIMV_MPEG4_ACDC_COEF_ADR (S5P_FIMV_COMMON_BASE_A + 0x04)
- /* upper Q coeff. */
-#define S5P_FIMV_MPEG4_COZERO_FLAG_ADR (S5P_FIMV_COMMON_BASE_A + 0x10)
- /* direct cozero flag */
-
-#define S5P_FIMV_ENC_REF_B_LUMA_ADR 0x062c /* ref B Luma addr */
-#define S5P_FIMV_ENC_REF_B_CHROMA_ADR 0x0630 /* ref B Chroma addr */
-
-#define S5P_FIMV_ENC_CUR_LUMA_ADR 0x0718 /* current Luma addr */
-#define S5P_FIMV_ENC_CUR_CHROMA_ADR 0x071C /* current Chroma addr */
-
-/* Codec common register */
-#define S5P_FIMV_ENC_HSIZE_PX 0x0818 /* frame width at encoder */
-#define S5P_FIMV_ENC_VSIZE_PX 0x081c /* frame height at encoder */
-#define S5P_FIMV_ENC_PROFILE 0x0830 /* profile register */
-#define S5P_FIMV_ENC_PROFILE_H264_MAIN 0
-#define S5P_FIMV_ENC_PROFILE_H264_HIGH 1
-#define S5P_FIMV_ENC_PROFILE_H264_BASELINE 2
-#define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE 0
-#define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE 1
-#define S5P_FIMV_ENC_PIC_STRUCT 0x083c /* picture field/frame flag */
-#define S5P_FIMV_ENC_LF_CTRL 0x0848 /* loop filter control */
-#define S5P_FIMV_ENC_ALPHA_OFF 0x084c /* loop filter alpha offset */
-#define S5P_FIMV_ENC_BETA_OFF 0x0850 /* loop filter beta offset */
-#define S5P_FIMV_MR_BUSIF_CTRL 0x0854 /* hidden, bus interface ctrl */
-#define S5P_FIMV_ENC_PXL_CACHE_CTRL 0x0a00 /* pixel cache control */
-
-/* Channel & stream interface register */
-#define S5P_FIMV_SI_RTN_CHID 0x2000 /* Return CH inst ID register */
-#define S5P_FIMV_SI_CH0_INST_ID 0x2040 /* codec instance ID */
-#define S5P_FIMV_SI_CH1_INST_ID 0x2080 /* codec instance ID */
-/* Decoder */
-#define S5P_FIMV_SI_VRESOL 0x2004 /* vertical res of decoder */
-#define S5P_FIMV_SI_HRESOL 0x2008 /* horizontal res of decoder */
-#define S5P_FIMV_SI_BUF_NUMBER 0x200c /* number of frames in the
- decoded pic */
-#define S5P_FIMV_SI_DISPLAY_Y_ADR 0x2010 /* luma addr of displayed pic */
-#define S5P_FIMV_SI_DISPLAY_C_ADR 0x2014 /* chroma addrof displayed pic */
-
-#define S5P_FIMV_SI_CONSUMED_BYTES 0x2018 /* Consumed number of bytes to
- decode a frame */
-#define S5P_FIMV_SI_DISPLAY_STATUS 0x201c /* status of decoded picture */
-
-#define S5P_FIMV_SI_DECODE_Y_ADR 0x2024 /* luma addr of decoded pic */
-#define S5P_FIMV_SI_DECODE_C_ADR 0x2028 /* chroma addrof decoded pic */
-#define S5P_FIMV_SI_DECODE_STATUS 0x202c /* status of decoded picture */
-
-#define S5P_FIMV_SI_CH0_SB_ST_ADR 0x2044 /* start addr of stream buf */
-#define S5P_FIMV_SI_CH0_SB_FRM_SIZE 0x2048 /* size of stream buf */
-#define S5P_FIMV_SI_CH0_DESC_ADR 0x204c /* addr of descriptor buf */
-#define S5P_FIMV_SI_CH0_CPB_SIZE 0x2058 /* max size of coded pic. buf */
-#define S5P_FIMV_SI_CH0_DESC_SIZE 0x205c /* max size of descriptor buf */
-
-#define S5P_FIMV_SI_CH1_SB_ST_ADR 0x2084 /* start addr of stream buf */
-#define S5P_FIMV_SI_CH1_SB_FRM_SIZE 0x2088 /* size of stream buf */
-#define S5P_FIMV_SI_CH1_DESC_ADR 0x208c /* addr of descriptor buf */
-#define S5P_FIMV_SI_CH1_CPB_SIZE 0x2098 /* max size of coded pic. buf */
-#define S5P_FIMV_SI_CH1_DESC_SIZE 0x209c /* max size of descriptor buf */
-
-#define S5P_FIMV_CRC_LUMA0 0x2030 /* luma crc data per frame
- (top field) */
-#define S5P_FIMV_CRC_CHROMA0 0x2034 /* chroma crc data per frame
- (top field) */
-#define S5P_FIMV_CRC_LUMA1 0x2038 /* luma crc data per bottom
- field */
-#define S5P_FIMV_CRC_CHROMA1 0x203c /* chroma crc data per bottom
- field */
-
-/* Display status */
-#define S5P_FIMV_DEC_STATUS_DECODING_ONLY 0
-#define S5P_FIMV_DEC_STATUS_DECODING_DISPLAY 1
-#define S5P_FIMV_DEC_STATUS_DISPLAY_ONLY 2
-#define S5P_FIMV_DEC_STATUS_DECODING_EMPTY 3
-#define S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK 7
-#define S5P_FIMV_DEC_STATUS_PROGRESSIVE (0<<3)
-#define S5P_FIMV_DEC_STATUS_INTERLACE (1<<3)
-#define S5P_FIMV_DEC_STATUS_INTERLACE_MASK (1<<3)
-#define S5P_FIMV_DEC_STATUS_CRC_NUMBER_TWO (0<<4)
-#define S5P_FIMV_DEC_STATUS_CRC_NUMBER_FOUR (1<<4)
-#define S5P_FIMV_DEC_STATUS_CRC_NUMBER_MASK (1<<4)
-#define S5P_FIMV_DEC_STATUS_CRC_GENERATED (1<<5)
-#define S5P_FIMV_DEC_STATUS_CRC_NOT_GENERATED (0<<5)
-#define S5P_FIMV_DEC_STATUS_CRC_MASK (1<<5)
-
-#define S5P_FIMV_DEC_STATUS_RESOLUTION_MASK (3<<4)
-#define S5P_FIMV_DEC_STATUS_RESOLUTION_INC (1<<4)
-#define S5P_FIMV_DEC_STATUS_RESOLUTION_DEC (2<<4)
-
-/* Decode frame address */
-#define S5P_FIMV_DECODE_Y_ADR 0x2024
-#define S5P_FIMV_DECODE_C_ADR 0x2028
-
-/* Decoded frame tpe */
-#define S5P_FIMV_DECODE_FRAME_TYPE 0x2020
-#define S5P_FIMV_DECODE_FRAME_MASK 7
-
-#define S5P_FIMV_DECODE_FRAME_SKIPPED 0
-#define S5P_FIMV_DECODE_FRAME_I_FRAME 1
-#define S5P_FIMV_DECODE_FRAME_P_FRAME 2
-#define S5P_FIMV_DECODE_FRAME_B_FRAME 3
-#define S5P_FIMV_DECODE_FRAME_OTHER_FRAME 4
-
-/* Sizes of buffers required for decoding */
-#define S5P_FIMV_DEC_NB_IP_SIZE (32 * 1024)
-#define S5P_FIMV_DEC_VERT_NB_MV_SIZE (16 * 1024)
-#define S5P_FIMV_DEC_NB_DCAC_SIZE (16 * 1024)
-#define S5P_FIMV_DEC_UPNB_MV_SIZE (68 * 1024)
-#define S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE (136 * 1024)
-#define S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE (32 * 1024)
-#define S5P_FIMV_DEC_VC1_BITPLANE_SIZE (2 * 1024)
-#define S5P_FIMV_DEC_STX_PARSER_SIZE (68 * 1024)
-
-#define S5P_FIMV_DEC_BUF_ALIGN (8 * 1024)
-#define S5P_FIMV_ENC_BUF_ALIGN (8 * 1024)
-#define S5P_FIMV_NV12M_HALIGN 16
-#define S5P_FIMV_NV12M_LVALIGN 16
-#define S5P_FIMV_NV12M_CVALIGN 8
-#define S5P_FIMV_NV12MT_HALIGN 128
-#define S5P_FIMV_NV12MT_VALIGN 32
-#define S5P_FIMV_NV12M_SALIGN 2048
-#define S5P_FIMV_NV12MT_SALIGN 8192
-
-/* Sizes of buffers required for encoding */
-#define S5P_FIMV_ENC_UPMV_SIZE 0x10000
-#define S5P_FIMV_ENC_COLFLG_SIZE 0x10000
-#define S5P_FIMV_ENC_INTRAMD_SIZE 0x10000
-#define S5P_FIMV_ENC_INTRAPRED_SIZE 0x4000
-#define S5P_FIMV_ENC_NBORINFO_SIZE 0x10000
-#define S5P_FIMV_ENC_ACDCCOEF_SIZE 0x10000
-
-/* Encoder */
-#define S5P_FIMV_ENC_SI_STRM_SIZE 0x2004 /* stream size */
-#define S5P_FIMV_ENC_SI_PIC_CNT 0x2008 /* picture count */
-#define S5P_FIMV_ENC_SI_WRITE_PTR 0x200c /* write pointer */
-#define S5P_FIMV_ENC_SI_SLICE_TYPE 0x2010 /* slice type(I/P/B/IDR) */
-#define S5P_FIMV_ENC_SI_SLICE_TYPE_NON_CODED 0
-#define S5P_FIMV_ENC_SI_SLICE_TYPE_I 1
-#define S5P_FIMV_ENC_SI_SLICE_TYPE_P 2
-#define S5P_FIMV_ENC_SI_SLICE_TYPE_B 3
-#define S5P_FIMV_ENC_SI_SLICE_TYPE_SKIPPED 4
-#define S5P_FIMV_ENC_SI_SLICE_TYPE_OTHERS 5
-#define S5P_FIMV_ENCODED_Y_ADDR 0x2014 /* the addr of the encoded
- luma pic */
-#define S5P_FIMV_ENCODED_C_ADDR 0x2018 /* the addr of the encoded
- chroma pic */
-
-#define S5P_FIMV_ENC_SI_CH0_SB_ADR 0x2044 /* addr of stream buf */
-#define S5P_FIMV_ENC_SI_CH0_SB_SIZE 0x204c /* size of stream buf */
-#define S5P_FIMV_ENC_SI_CH0_CUR_Y_ADR 0x2050 /* current Luma addr */
-#define S5P_FIMV_ENC_SI_CH0_CUR_C_ADR 0x2054 /* current Chroma addr */
-#define S5P_FIMV_ENC_SI_CH0_FRAME_INS 0x2058 /* frame insertion */
-
-#define S5P_FIMV_ENC_SI_CH1_SB_ADR 0x2084 /* addr of stream buf */
-#define S5P_FIMV_ENC_SI_CH1_SB_SIZE 0x208c /* size of stream buf */
-#define S5P_FIMV_ENC_SI_CH1_CUR_Y_ADR 0x2090 /* current Luma addr */
-#define S5P_FIMV_ENC_SI_CH1_CUR_C_ADR 0x2094 /* current Chroma addr */
-#define S5P_FIMV_ENC_SI_CH1_FRAME_INS 0x2098 /* frame insertion */
-
-#define S5P_FIMV_ENC_PIC_TYPE_CTRL 0xc504 /* pic type level control */
-#define S5P_FIMV_ENC_B_RECON_WRITE_ON 0xc508 /* B frame recon write ctrl */
-#define S5P_FIMV_ENC_MSLICE_CTRL 0xc50c /* multi slice control */
-#define S5P_FIMV_ENC_MSLICE_MB 0xc510 /* MB number in the one slice */
-#define S5P_FIMV_ENC_MSLICE_BIT 0xc514 /* bit count for one slice */
-#define S5P_FIMV_ENC_CIR_CTRL 0xc518 /* number of intra refresh MB */
-#define S5P_FIMV_ENC_MAP_FOR_CUR 0xc51c /* linear or tiled mode */
-#define S5P_FIMV_ENC_PADDING_CTRL 0xc520 /* padding control */
-
-#define S5P_FIMV_ENC_RC_CONFIG 0xc5a0 /* RC config */
-#define S5P_FIMV_ENC_RC_BIT_RATE 0xc5a8 /* bit rate */
-#define S5P_FIMV_ENC_RC_QBOUND 0xc5ac /* max/min QP */
-#define S5P_FIMV_ENC_RC_RPARA 0xc5b0 /* rate control reaction coeff */
-#define S5P_FIMV_ENC_RC_MB_CTRL 0xc5b4 /* MB adaptive scaling */
-
-/* Encoder for H264 only */
-#define S5P_FIMV_ENC_H264_ENTROPY_MODE 0xd004 /* CAVLC or CABAC */
-#define S5P_FIMV_ENC_H264_ALPHA_OFF 0xd008 /* loop filter alpha offset */
-#define S5P_FIMV_ENC_H264_BETA_OFF 0xd00c /* loop filter beta offset */
-#define S5P_FIMV_ENC_H264_NUM_OF_REF 0xd010 /* number of reference for P/B */
-#define S5P_FIMV_ENC_H264_TRANS_FLAG 0xd034 /* 8x8 transform flag in PPS &
- high profile */
-
-#define S5P_FIMV_ENC_RC_FRAME_RATE 0xd0d0 /* frame rate */
-
-/* Encoder for MPEG4 only */
-#define S5P_FIMV_ENC_MPEG4_QUART_PXL 0xe008 /* qpel interpolation ctrl */
-
-/* Additional */
-#define S5P_FIMV_SI_CH0_DPB_CONF_CTRL 0x2068 /* DPB Config Control Register */
-#define S5P_FIMV_SLICE_INT_MASK 1
-#define S5P_FIMV_SLICE_INT_SHIFT 31
-#define S5P_FIMV_DDELAY_ENA_SHIFT 30
-#define S5P_FIMV_DDELAY_VAL_MASK 0xff
-#define S5P_FIMV_DDELAY_VAL_SHIFT 16
-#define S5P_FIMV_DPB_COUNT_MASK 0xffff
-#define S5P_FIMV_DPB_FLUSH_MASK 1
-#define S5P_FIMV_DPB_FLUSH_SHIFT 14
-
-
-#define S5P_FIMV_SI_CH0_RELEASE_BUF 0x2060 /* DPB release buffer register */
-#define S5P_FIMV_SI_CH0_HOST_WR_ADR 0x2064 /* address of shared memory */
-
-/* Codec numbers */
-#define S5P_FIMV_CODEC_NONE -1
-
-#define S5P_FIMV_CODEC_H264_DEC 0
-#define S5P_FIMV_CODEC_VC1_DEC 1
-#define S5P_FIMV_CODEC_MPEG4_DEC 2
-#define S5P_FIMV_CODEC_MPEG2_DEC 3
-#define S5P_FIMV_CODEC_H263_DEC 4
-#define S5P_FIMV_CODEC_VC1RCV_DEC 5
-
-#define S5P_FIMV_CODEC_H264_ENC 16
-#define S5P_FIMV_CODEC_MPEG4_ENC 17
-#define S5P_FIMV_CODEC_H263_ENC 18
-
-/* Channel Control Register */
-#define S5P_FIMV_CH_SEQ_HEADER 1
-#define S5P_FIMV_CH_FRAME_START 2
-#define S5P_FIMV_CH_LAST_FRAME 3
-#define S5P_FIMV_CH_INIT_BUFS 4
-#define S5P_FIMV_CH_FRAME_START_REALLOC 5
-#define S5P_FIMV_CH_MASK 7
-#define S5P_FIMV_CH_SHIFT 16
-
-
-/* Host to RISC command */
-#define S5P_FIMV_H2R_CMD_EMPTY 0
-#define S5P_FIMV_H2R_CMD_OPEN_INSTANCE 1
-#define S5P_FIMV_H2R_CMD_CLOSE_INSTANCE 2
-#define S5P_FIMV_H2R_CMD_SYS_INIT 3
-#define S5P_FIMV_H2R_CMD_FLUSH 4
-#define S5P_FIMV_H2R_CMD_SLEEP 5
-#define S5P_FIMV_H2R_CMD_WAKEUP 6
-
-#define S5P_FIMV_R2H_CMD_EMPTY 0
-#define S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET 1
-#define S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET 2
-#define S5P_FIMV_R2H_CMD_RSV_RET 3
-#define S5P_FIMV_R2H_CMD_SEQ_DONE_RET 4
-#define S5P_FIMV_R2H_CMD_FRAME_DONE_RET 5
-#define S5P_FIMV_R2H_CMD_SLICE_DONE_RET 6
-#define S5P_FIMV_R2H_CMD_ENC_COMPLETE_RET 7
-#define S5P_FIMV_R2H_CMD_SYS_INIT_RET 8
-#define S5P_FIMV_R2H_CMD_FW_STATUS_RET 9
-#define S5P_FIMV_R2H_CMD_SLEEP_RET 10
-#define S5P_FIMV_R2H_CMD_WAKEUP_RET 11
-#define S5P_FIMV_R2H_CMD_FLUSH_RET 12
-#define S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET 15
-#define S5P_FIMV_R2H_CMD_EDFU_INIT_RET 16
-#define S5P_FIMV_R2H_CMD_ERR_RET 32
-
-/* Error handling defines */
-#define S5P_FIMV_ERR_WARNINGS_START 145
-#define S5P_FIMV_ERR_DEC_MASK 0xFFFF
-#define S5P_FIMV_ERR_DEC_SHIFT 0
-#define S5P_FIMV_ERR_DSPL_MASK 0xFFFF0000
-#define S5P_FIMV_ERR_DSPL_SHIFT 16
-
-/* Shared memory registers' offsets */
-
-/* An offset of the start position in the stream when
- * the start position is not aligned */
-#define S5P_FIMV_SHARED_CROP_INFO_H 0x0020
-#define S5P_FIMV_SHARED_CROP_LEFT_MASK 0xFFFF
-#define S5P_FIMV_SHARED_CROP_LEFT_SHIFT 0
-#define S5P_FIMV_SHARED_CROP_RIGHT_MASK 0xFFFF0000
-#define S5P_FIMV_SHARED_CROP_RIGHT_SHIFT 16
-#define S5P_FIMV_SHARED_CROP_INFO_V 0x0024
-#define S5P_FIMV_SHARED_CROP_TOP_MASK 0xFFFF
-#define S5P_FIMV_SHARED_CROP_TOP_SHIFT 0
-#define S5P_FIMV_SHARED_CROP_BOTTOM_MASK 0xFFFF0000
-#define S5P_FIMV_SHARED_CROP_BOTTOM_SHIFT 16
-#define S5P_FIMV_SHARED_SET_FRAME_TAG 0x0004
-#define S5P_FIMV_SHARED_GET_FRAME_TAG_TOP 0x0008
-#define S5P_FIMV_SHARED_GET_FRAME_TAG_BOT 0x000C
-#define S5P_FIMV_SHARED_START_BYTE_NUM 0x0018
-#define S5P_FIMV_SHARED_RC_VOP_TIMING 0x0030
-#define S5P_FIMV_SHARED_LUMA_DPB_SIZE 0x0064
-#define S5P_FIMV_SHARED_CHROMA_DPB_SIZE 0x0068
-#define S5P_FIMV_SHARED_MV_SIZE 0x006C
-#define S5P_FIMV_SHARED_PIC_TIME_TOP 0x0010
-#define S5P_FIMV_SHARED_PIC_TIME_BOTTOM 0x0014
-#define S5P_FIMV_SHARED_EXT_ENC_CONTROL 0x0028
-#define S5P_FIMV_SHARED_P_B_FRAME_QP 0x0070
-#define S5P_FIMV_SHARED_ASPECT_RATIO_IDC 0x0074
-#define S5P_FIMV_SHARED_EXTENDED_SAR 0x0078
-#define S5P_FIMV_SHARED_H264_I_PERIOD 0x009C
-#define S5P_FIMV_SHARED_RC_CONTROL_CONFIG 0x00A0
-
-#endif /* _REGS_FIMV_H */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc.c b/drivers/media/video/s5p-mfc/s5p_mfc.c
deleted file mode 100644
index 9bb68e7b5ae..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc.c
+++ /dev/null
@@ -1,1223 +0,0 @@
-/*
- * Samsung S5P Multi Format Codec v 5.1
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * Kamil Debski, <k.debski@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/workqueue.h>
-#include <media/videobuf2-core.h>
-#include "regs-mfc.h"
-#include "s5p_mfc_ctrl.h"
-#include "s5p_mfc_debug.h"
-#include "s5p_mfc_dec.h"
-#include "s5p_mfc_enc.h"
-#include "s5p_mfc_intr.h"
-#include "s5p_mfc_opr.h"
-#include "s5p_mfc_pm.h"
-#include "s5p_mfc_shm.h"
-
-#define S5P_MFC_NAME "s5p-mfc"
-#define S5P_MFC_DEC_NAME "s5p-mfc-dec"
-#define S5P_MFC_ENC_NAME "s5p-mfc-enc"
-
-int debug;
-module_param(debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug level - higher value produces more verbose messages");
-
-/* Helper functions for interrupt processing */
-/* Remove from hw execution round robin */
-static void clear_work_bit(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
-
- spin_lock(&dev->condlock);
- clear_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock(&dev->condlock);
-}
-
-/* Wake up context wait_queue */
-static void wake_up_ctx(struct s5p_mfc_ctx *ctx, unsigned int reason,
- unsigned int err)
-{
- ctx->int_cond = 1;
- ctx->int_type = reason;
- ctx->int_err = err;
- wake_up(&ctx->queue);
-}
-
-/* Wake up device wait_queue */
-static void wake_up_dev(struct s5p_mfc_dev *dev, unsigned int reason,
- unsigned int err)
-{
- dev->int_cond = 1;
- dev->int_type = reason;
- dev->int_err = err;
- wake_up(&dev->queue);
-}
-
-static void s5p_mfc_watchdog(unsigned long arg)
-{
- struct s5p_mfc_dev *dev = (struct s5p_mfc_dev *)arg;
-
- if (test_bit(0, &dev->hw_lock))
- atomic_inc(&dev->watchdog_cnt);
- if (atomic_read(&dev->watchdog_cnt) >= MFC_WATCHDOG_CNT) {
- /* This means that hw is busy and no interrupts were
- * generated by hw for the Nth time of running this
- * watchdog timer. This usually means a serious hw
- * error. Now it is time to kill all instances and
- * reset the MFC. */
- mfc_err("Time out during waiting for HW\n");
- queue_work(dev->watchdog_workqueue, &dev->watchdog_work);
- }
- dev->watchdog_timer.expires = jiffies +
- msecs_to_jiffies(MFC_WATCHDOG_INTERVAL);
- add_timer(&dev->watchdog_timer);
-}
-
-static void s5p_mfc_watchdog_worker(struct work_struct *work)
-{
- struct s5p_mfc_dev *dev;
- struct s5p_mfc_ctx *ctx;
- unsigned long flags;
- int mutex_locked;
- int i, ret;
-
- dev = container_of(work, struct s5p_mfc_dev, watchdog_work);
-
- mfc_err("Driver timeout error handling\n");
- /* Lock the mutex that protects open and release.
- * This is necessary as they may load and unload firmware. */
- mutex_locked = mutex_trylock(&dev->mfc_mutex);
- if (!mutex_locked)
- mfc_err("Error: some instance may be closing/opening\n");
- spin_lock_irqsave(&dev->irqlock, flags);
-
- s5p_mfc_clock_off();
-
- for (i = 0; i < MFC_NUM_CONTEXTS; i++) {
- ctx = dev->ctx[i];
- if (!ctx)
- continue;
- ctx->state = MFCINST_ERROR;
- s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
- s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
- clear_work_bit(ctx);
- wake_up_ctx(ctx, S5P_FIMV_R2H_CMD_ERR_RET, 0);
- }
- clear_bit(0, &dev->hw_lock);
- spin_unlock_irqrestore(&dev->irqlock, flags);
- /* Double check if there is at least one instance running.
- * If no instance is in memory than no firmware should be present */
- if (dev->num_inst > 0) {
- ret = s5p_mfc_reload_firmware(dev);
- if (ret) {
- mfc_err("Failed to reload FW\n");
- goto unlock;
- }
- s5p_mfc_clock_on();
- ret = s5p_mfc_init_hw(dev);
- if (ret)
- mfc_err("Failed to reinit FW\n");
- }
-unlock:
- if (mutex_locked)
- mutex_unlock(&dev->mfc_mutex);
-}
-
-static enum s5p_mfc_node_type s5p_mfc_get_node_type(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
-
- if (!vdev) {
- mfc_err("failed to get video_device");
- return MFCNODE_INVALID;
- }
- if (vdev->index == 0)
- return MFCNODE_DECODER;
- else if (vdev->index == 1)
- return MFCNODE_ENCODER;
- return MFCNODE_INVALID;
-}
-
-static void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev)
-{
- mfc_write(dev, 0, S5P_FIMV_RISC_HOST_INT);
- mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
- mfc_write(dev, 0xffff, S5P_FIMV_SI_RTN_CHID);
-}
-
-static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_buf *dst_buf;
-
- ctx->state = MFCINST_FINISHED;
- ctx->sequence++;
- while (!list_empty(&ctx->dst_queue)) {
- dst_buf = list_entry(ctx->dst_queue.next,
- struct s5p_mfc_buf, list);
- mfc_debug(2, "Cleaning up buffer: %d\n",
- dst_buf->b->v4l2_buf.index);
- vb2_set_plane_payload(dst_buf->b, 0, 0);
- vb2_set_plane_payload(dst_buf->b, 1, 0);
- list_del(&dst_buf->list);
- ctx->dst_queue_cnt--;
- dst_buf->b->v4l2_buf.sequence = (ctx->sequence++);
-
- if (s5p_mfc_read_shm(ctx, PIC_TIME_TOP) ==
- s5p_mfc_read_shm(ctx, PIC_TIME_BOT))
- dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE;
- else
- dst_buf->b->v4l2_buf.field = V4L2_FIELD_INTERLACED;
-
- ctx->dec_dst_flag &= ~(1 << dst_buf->b->v4l2_buf.index);
- vb2_buffer_done(dst_buf->b, VB2_BUF_STATE_DONE);
- }
-}
-
-static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_buf *dst_buf, *src_buf;
- size_t dec_y_addr = s5p_mfc_get_dec_y_adr();
- unsigned int frame_type = s5p_mfc_get_frame_type();
-
- /* Copy timestamp / timecode from decoded src to dst and set
- appropraite flags */
- src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
- list_for_each_entry(dst_buf, &ctx->dst_queue, list) {
- if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dec_y_addr) {
- memcpy(&dst_buf->b->v4l2_buf.timecode,
- &src_buf->b->v4l2_buf.timecode,
- sizeof(struct v4l2_timecode));
- memcpy(&dst_buf->b->v4l2_buf.timestamp,
- &src_buf->b->v4l2_buf.timestamp,
- sizeof(struct timeval));
- switch (frame_type) {
- case S5P_FIMV_DECODE_FRAME_I_FRAME:
- dst_buf->b->v4l2_buf.flags |=
- V4L2_BUF_FLAG_KEYFRAME;
- break;
- case S5P_FIMV_DECODE_FRAME_P_FRAME:
- dst_buf->b->v4l2_buf.flags |=
- V4L2_BUF_FLAG_PFRAME;
- break;
- case S5P_FIMV_DECODE_FRAME_B_FRAME:
- dst_buf->b->v4l2_buf.flags |=
- V4L2_BUF_FLAG_BFRAME;
- break;
- }
- break;
- }
- }
-}
-
-static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_buf *dst_buf;
- size_t dspl_y_addr = s5p_mfc_get_dspl_y_adr();
- unsigned int frame_type = s5p_mfc_get_frame_type();
- unsigned int index;
-
- /* If frame is same as previous then skip and do not dequeue */
- if (frame_type == S5P_FIMV_DECODE_FRAME_SKIPPED) {
- if (!ctx->after_packed_pb)
- ctx->sequence++;
- ctx->after_packed_pb = 0;
- return;
- }
- ctx->sequence++;
- /* The MFC returns address of the buffer, now we have to
- * check which videobuf does it correspond to */
- list_for_each_entry(dst_buf, &ctx->dst_queue, list) {
- /* Check if this is the buffer we're looking for */
- if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dspl_y_addr) {
- list_del(&dst_buf->list);
- ctx->dst_queue_cnt--;
- dst_buf->b->v4l2_buf.sequence = ctx->sequence;
- if (s5p_mfc_read_shm(ctx, PIC_TIME_TOP) ==
- s5p_mfc_read_shm(ctx, PIC_TIME_BOT))
- dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE;
- else
- dst_buf->b->v4l2_buf.field =
- V4L2_FIELD_INTERLACED;
- vb2_set_plane_payload(dst_buf->b, 0, ctx->luma_size);
- vb2_set_plane_payload(dst_buf->b, 1, ctx->chroma_size);
- clear_bit(dst_buf->b->v4l2_buf.index,
- &ctx->dec_dst_flag);
-
- vb2_buffer_done(dst_buf->b,
- err ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-
- index = dst_buf->b->v4l2_buf.index;
- break;
- }
- }
-}
-
-/* Handle frame decoding interrupt */
-static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
- unsigned int reason, unsigned int err)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned int dst_frame_status;
- struct s5p_mfc_buf *src_buf;
- unsigned long flags;
- unsigned int res_change;
-
- unsigned int index;
-
- dst_frame_status = s5p_mfc_get_dspl_status()
- & S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK;
- res_change = s5p_mfc_get_dspl_status()
- & S5P_FIMV_DEC_STATUS_RESOLUTION_MASK;
- mfc_debug(2, "Frame Status: %x\n", dst_frame_status);
- if (ctx->state == MFCINST_RES_CHANGE_INIT)
- ctx->state = MFCINST_RES_CHANGE_FLUSH;
- if (res_change) {
- ctx->state = MFCINST_RES_CHANGE_INIT;
- s5p_mfc_clear_int_flags(dev);
- wake_up_ctx(ctx, reason, err);
- if (test_and_clear_bit(0, &dev->hw_lock) == 0)
- BUG();
- s5p_mfc_clock_off();
- s5p_mfc_try_run(dev);
- return;
- }
- if (ctx->dpb_flush_flag)
- ctx->dpb_flush_flag = 0;
-
- spin_lock_irqsave(&dev->irqlock, flags);
- /* All frames remaining in the buffer have been extracted */
- if (dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_EMPTY) {
- if (ctx->state == MFCINST_RES_CHANGE_FLUSH) {
- s5p_mfc_handle_frame_all_extracted(ctx);
- ctx->state = MFCINST_RES_CHANGE_END;
- goto leave_handle_frame;
- } else {
- s5p_mfc_handle_frame_all_extracted(ctx);
- }
- }
-
- if (dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_DISPLAY ||
- dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_ONLY)
- s5p_mfc_handle_frame_copy_time(ctx);
-
- /* A frame has been decoded and is in the buffer */
- if (dst_frame_status == S5P_FIMV_DEC_STATUS_DISPLAY_ONLY ||
- dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_DISPLAY) {
- s5p_mfc_handle_frame_new(ctx, err);
- } else {
- mfc_debug(2, "No frame decode\n");
- }
- /* Mark source buffer as complete */
- if (dst_frame_status != S5P_FIMV_DEC_STATUS_DISPLAY_ONLY
- && !list_empty(&ctx->src_queue)) {
- src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
- list);
- ctx->consumed_stream += s5p_mfc_get_consumed_stream();
- if (ctx->codec_mode != S5P_FIMV_CODEC_H264_DEC &&
- s5p_mfc_get_frame_type() == S5P_FIMV_DECODE_FRAME_P_FRAME
- && ctx->consumed_stream + STUFF_BYTE <
- src_buf->b->v4l2_planes[0].bytesused) {
- /* Run MFC again on the same buffer */
- mfc_debug(2, "Running again the same buffer\n");
- ctx->after_packed_pb = 1;
- } else {
- index = src_buf->b->v4l2_buf.index;
- mfc_debug(2, "MFC needs next buffer\n");
- ctx->consumed_stream = 0;
- list_del(&src_buf->list);
- ctx->src_queue_cnt--;
- if (s5p_mfc_err_dec(err) > 0)
- vb2_buffer_done(src_buf->b, VB2_BUF_STATE_ERROR);
- else
- vb2_buffer_done(src_buf->b, VB2_BUF_STATE_DONE);
- }
- }
-leave_handle_frame:
- spin_unlock_irqrestore(&dev->irqlock, flags);
- if ((ctx->src_queue_cnt == 0 && ctx->state != MFCINST_FINISHING)
- || ctx->dst_queue_cnt < ctx->dpb_count)
- clear_work_bit(ctx);
- s5p_mfc_clear_int_flags(dev);
- wake_up_ctx(ctx, reason, err);
- if (test_and_clear_bit(0, &dev->hw_lock) == 0)
- BUG();
- s5p_mfc_clock_off();
- s5p_mfc_try_run(dev);
-}
-
-/* Error handling for interrupt */
-static void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx,
- unsigned int reason, unsigned int err)
-{
- struct s5p_mfc_dev *dev;
- unsigned long flags;
-
- /* If no context is available then all necessary
- * processing has been done. */
- if (ctx == NULL)
- return;
-
- dev = ctx->dev;
- mfc_err("Interrupt Error: %08x\n", err);
- s5p_mfc_clear_int_flags(dev);
- wake_up_dev(dev, reason, err);
-
- /* Error recovery is dependent on the state of context */
- switch (ctx->state) {
- case MFCINST_INIT:
- /* This error had to happen while acquireing instance */
- case MFCINST_GOT_INST:
- /* This error had to happen while parsing the header */
- case MFCINST_HEAD_PARSED:
- /* This error had to happen while setting dst buffers */
- case MFCINST_RETURN_INST:
- /* This error had to happen while releasing instance */
- clear_work_bit(ctx);
- wake_up_ctx(ctx, reason, err);
- if (test_and_clear_bit(0, &dev->hw_lock) == 0)
- BUG();
- s5p_mfc_clock_off();
- ctx->state = MFCINST_ERROR;
- break;
- case MFCINST_FINISHING:
- case MFCINST_FINISHED:
- case MFCINST_RUNNING:
- /* It is higly probable that an error occured
- * while decoding a frame */
- clear_work_bit(ctx);
- ctx->state = MFCINST_ERROR;
- /* Mark all dst buffers as having an error */
- spin_lock_irqsave(&dev->irqlock, flags);
- s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
- /* Mark all src buffers as having an error */
- s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
- spin_unlock_irqrestore(&dev->irqlock, flags);
- if (test_and_clear_bit(0, &dev->hw_lock) == 0)
- BUG();
- s5p_mfc_clock_off();
- break;
- default:
- mfc_err("Encountered an error interrupt which had not been handled\n");
- break;
- }
- return;
-}
-
-/* Header parsing interrupt handling */
-static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
- unsigned int reason, unsigned int err)
-{
- struct s5p_mfc_dev *dev;
- unsigned int guard_width, guard_height;
-
- if (ctx == NULL)
- return;
- dev = ctx->dev;
- if (ctx->c_ops->post_seq_start) {
- if (ctx->c_ops->post_seq_start(ctx))
- mfc_err("post_seq_start() failed\n");
- } else {
- ctx->img_width = s5p_mfc_get_img_width();
- ctx->img_height = s5p_mfc_get_img_height();
-
- ctx->buf_width = ALIGN(ctx->img_width,
- S5P_FIMV_NV12MT_HALIGN);
- ctx->buf_height = ALIGN(ctx->img_height,
- S5P_FIMV_NV12MT_VALIGN);
- mfc_debug(2, "SEQ Done: Movie dimensions %dx%d, "
- "buffer dimensions: %dx%d\n", ctx->img_width,
- ctx->img_height, ctx->buf_width,
- ctx->buf_height);
- if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) {
- ctx->luma_size = ALIGN(ctx->buf_width *
- ctx->buf_height, S5P_FIMV_DEC_BUF_ALIGN);
- ctx->chroma_size = ALIGN(ctx->buf_width *
- ALIGN((ctx->img_height >> 1),
- S5P_FIMV_NV12MT_VALIGN),
- S5P_FIMV_DEC_BUF_ALIGN);
- ctx->mv_size = ALIGN(ctx->buf_width *
- ALIGN((ctx->buf_height >> 2),
- S5P_FIMV_NV12MT_VALIGN),
- S5P_FIMV_DEC_BUF_ALIGN);
- } else {
- guard_width = ALIGN(ctx->img_width + 24,
- S5P_FIMV_NV12MT_HALIGN);
- guard_height = ALIGN(ctx->img_height + 16,
- S5P_FIMV_NV12MT_VALIGN);
- ctx->luma_size = ALIGN(guard_width *
- guard_height, S5P_FIMV_DEC_BUF_ALIGN);
- guard_width = ALIGN(ctx->img_width + 16,
- S5P_FIMV_NV12MT_HALIGN);
- guard_height = ALIGN((ctx->img_height >> 1) + 4,
- S5P_FIMV_NV12MT_VALIGN);
- ctx->chroma_size = ALIGN(guard_width *
- guard_height, S5P_FIMV_DEC_BUF_ALIGN);
- ctx->mv_size = 0;
- }
- ctx->dpb_count = s5p_mfc_get_dpb_count();
- if (ctx->img_width == 0 || ctx->img_height == 0)
- ctx->state = MFCINST_ERROR;
- else
- ctx->state = MFCINST_HEAD_PARSED;
- }
- s5p_mfc_clear_int_flags(dev);
- clear_work_bit(ctx);
- if (test_and_clear_bit(0, &dev->hw_lock) == 0)
- BUG();
- s5p_mfc_clock_off();
- s5p_mfc_try_run(dev);
- wake_up_ctx(ctx, reason, err);
-}
-
-/* Header parsing interrupt handling */
-static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
- unsigned int reason, unsigned int err)
-{
- struct s5p_mfc_buf *src_buf;
- struct s5p_mfc_dev *dev;
- unsigned long flags;
-
- if (ctx == NULL)
- return;
- dev = ctx->dev;
- s5p_mfc_clear_int_flags(dev);
- ctx->int_type = reason;
- ctx->int_err = err;
- ctx->int_cond = 1;
- spin_lock(&dev->condlock);
- clear_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock(&dev->condlock);
- if (err == 0) {
- ctx->state = MFCINST_RUNNING;
- if (!ctx->dpb_flush_flag) {
- spin_lock_irqsave(&dev->irqlock, flags);
- if (!list_empty(&ctx->src_queue)) {
- src_buf = list_entry(ctx->src_queue.next,
- struct s5p_mfc_buf, list);
- list_del(&src_buf->list);
- ctx->src_queue_cnt--;
- vb2_buffer_done(src_buf->b,
- VB2_BUF_STATE_DONE);
- }
- spin_unlock_irqrestore(&dev->irqlock, flags);
- } else {
- ctx->dpb_flush_flag = 0;
- }
- if (test_and_clear_bit(0, &dev->hw_lock) == 0)
- BUG();
-
- s5p_mfc_clock_off();
-
- wake_up(&ctx->queue);
- s5p_mfc_try_run(dev);
- } else {
- if (test_and_clear_bit(0, &dev->hw_lock) == 0)
- BUG();
-
- s5p_mfc_clock_off();
-
- wake_up(&ctx->queue);
- }
-}
-
-/* Interrupt processing */
-static irqreturn_t s5p_mfc_irq(int irq, void *priv)
-{
- struct s5p_mfc_dev *dev = priv;
- struct s5p_mfc_ctx *ctx;
- unsigned int reason;
- unsigned int err;
-
- mfc_debug_enter();
- /* Reset the timeout watchdog */
- atomic_set(&dev->watchdog_cnt, 0);
- ctx = dev->ctx[dev->curr_ctx];
- /* Get the reason of interrupt and the error code */
- reason = s5p_mfc_get_int_reason();
- err = s5p_mfc_get_int_err();
- mfc_debug(1, "Int reason: %d (err: %08x)\n", reason, err);
- switch (reason) {
- case S5P_FIMV_R2H_CMD_ERR_RET:
- /* An error has occured */
- if (ctx->state == MFCINST_RUNNING &&
- s5p_mfc_err_dec(err) >= S5P_FIMV_ERR_WARNINGS_START)
- s5p_mfc_handle_frame(ctx, reason, err);
- else
- s5p_mfc_handle_error(ctx, reason, err);
- clear_bit(0, &dev->enter_suspend);
- break;
-
- case S5P_FIMV_R2H_CMD_SLICE_DONE_RET:
- case S5P_FIMV_R2H_CMD_FRAME_DONE_RET:
- if (ctx->c_ops->post_frame_start) {
- if (ctx->c_ops->post_frame_start(ctx))
- mfc_err("post_frame_start() failed\n");
- s5p_mfc_clear_int_flags(dev);
- wake_up_ctx(ctx, reason, err);
- if (test_and_clear_bit(0, &dev->hw_lock) == 0)
- BUG();
- s5p_mfc_clock_off();
- s5p_mfc_try_run(dev);
- } else {
- s5p_mfc_handle_frame(ctx, reason, err);
- }
- break;
-
- case S5P_FIMV_R2H_CMD_SEQ_DONE_RET:
- s5p_mfc_handle_seq_done(ctx, reason, err);
- break;
-
- case S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET:
- ctx->inst_no = s5p_mfc_get_inst_no();
- ctx->state = MFCINST_GOT_INST;
- clear_work_bit(ctx);
- wake_up(&ctx->queue);
- goto irq_cleanup_hw;
-
- case S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET:
- clear_work_bit(ctx);
- ctx->state = MFCINST_FREE;
- wake_up(&ctx->queue);
- goto irq_cleanup_hw;
-
- case S5P_FIMV_R2H_CMD_SYS_INIT_RET:
- case S5P_FIMV_R2H_CMD_FW_STATUS_RET:
- case S5P_FIMV_R2H_CMD_SLEEP_RET:
- case S5P_FIMV_R2H_CMD_WAKEUP_RET:
- if (ctx)
- clear_work_bit(ctx);
- s5p_mfc_clear_int_flags(dev);
- wake_up_dev(dev, reason, err);
- clear_bit(0, &dev->hw_lock);
- clear_bit(0, &dev->enter_suspend);
- break;
-
- case S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET:
- s5p_mfc_handle_init_buffers(ctx, reason, err);
- break;
- default:
- mfc_debug(2, "Unknown int reason\n");
- s5p_mfc_clear_int_flags(dev);
- }
- mfc_debug_leave();
- return IRQ_HANDLED;
-irq_cleanup_hw:
- s5p_mfc_clear_int_flags(dev);
- ctx->int_type = reason;
- ctx->int_err = err;
- ctx->int_cond = 1;
- if (test_and_clear_bit(0, &dev->hw_lock) == 0)
- mfc_err("Failed to unlock hw\n");
-
- s5p_mfc_clock_off();
-
- s5p_mfc_try_run(dev);
- mfc_debug(2, "Exit via irq_cleanup_hw\n");
- return IRQ_HANDLED;
-}
-
-/* Open an MFC node */
-static int s5p_mfc_open(struct file *file)
-{
- struct s5p_mfc_dev *dev = video_drvdata(file);
- struct s5p_mfc_ctx *ctx = NULL;
- struct vb2_queue *q;
- unsigned long flags;
- int ret = 0;
-
- mfc_debug_enter();
- dev->num_inst++; /* It is guarded by mfc_mutex in vfd */
- /* Allocate memory for context */
- ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
- if (!ctx) {
- mfc_err("Not enough memory\n");
- ret = -ENOMEM;
- goto err_alloc;
- }
- v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
- ctx->dev = dev;
- INIT_LIST_HEAD(&ctx->src_queue);
- INIT_LIST_HEAD(&ctx->dst_queue);
- ctx->src_queue_cnt = 0;
- ctx->dst_queue_cnt = 0;
- /* Get context number */
- ctx->num = 0;
- while (dev->ctx[ctx->num]) {
- ctx->num++;
- if (ctx->num >= MFC_NUM_CONTEXTS) {
- mfc_err("Too many open contexts\n");
- ret = -EBUSY;
- goto err_no_ctx;
- }
- }
- /* Mark context as idle */
- spin_lock_irqsave(&dev->condlock, flags);
- clear_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- dev->ctx[ctx->num] = ctx;
- if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) {
- ctx->type = MFCINST_DECODER;
- ctx->c_ops = get_dec_codec_ops();
- /* Setup ctrl handler */
- ret = s5p_mfc_dec_ctrls_setup(ctx);
- if (ret) {
- mfc_err("Failed to setup mfc controls\n");
- goto err_ctrls_setup;
- }
- } else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) {
- ctx->type = MFCINST_ENCODER;
- ctx->c_ops = get_enc_codec_ops();
- /* only for encoder */
- INIT_LIST_HEAD(&ctx->ref_queue);
- ctx->ref_queue_cnt = 0;
- /* Setup ctrl handler */
- ret = s5p_mfc_enc_ctrls_setup(ctx);
- if (ret) {
- mfc_err("Failed to setup mfc controls\n");
- goto err_ctrls_setup;
- }
- } else {
- ret = -ENOENT;
- goto err_bad_node;
- }
- ctx->fh.ctrl_handler = &ctx->ctrl_handler;
- ctx->inst_no = -1;
- /* Load firmware if this is the first instance */
- if (dev->num_inst == 1) {
- dev->watchdog_timer.expires = jiffies +
- msecs_to_jiffies(MFC_WATCHDOG_INTERVAL);
- add_timer(&dev->watchdog_timer);
- ret = s5p_mfc_power_on();
- if (ret < 0) {
- mfc_err("power on failed\n");
- goto err_pwr_enable;
- }
- s5p_mfc_clock_on();
- ret = s5p_mfc_alloc_and_load_firmware(dev);
- if (ret)
- goto err_alloc_fw;
- /* Init the FW */
- ret = s5p_mfc_init_hw(dev);
- if (ret)
- goto err_init_hw;
- s5p_mfc_clock_off();
- }
- /* Init videobuf2 queue for CAPTURE */
- q = &ctx->vq_dst;
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- q->drv_priv = &ctx->fh;
- if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) {
- q->io_modes = VB2_MMAP;
- q->ops = get_dec_queue_ops();
- } else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) {
- q->io_modes = VB2_MMAP | VB2_USERPTR;
- q->ops = get_enc_queue_ops();
- } else {
- ret = -ENOENT;
- goto err_queue_init;
- }
- q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops;
- ret = vb2_queue_init(q);
- if (ret) {
- mfc_err("Failed to initialize videobuf2 queue(capture)\n");
- goto err_queue_init;
- }
- /* Init videobuf2 queue for OUTPUT */
- q = &ctx->vq_src;
- q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- q->io_modes = VB2_MMAP;
- q->drv_priv = &ctx->fh;
- if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) {
- q->io_modes = VB2_MMAP;
- q->ops = get_dec_queue_ops();
- } else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) {
- q->io_modes = VB2_MMAP | VB2_USERPTR;
- q->ops = get_enc_queue_ops();
- } else {
- ret = -ENOENT;
- goto err_queue_init;
- }
- q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops;
- ret = vb2_queue_init(q);
- if (ret) {
- mfc_err("Failed to initialize videobuf2 queue(output)\n");
- goto err_queue_init;
- }
- init_waitqueue_head(&ctx->queue);
- mfc_debug_leave();
- return ret;
- /* Deinit when failure occured */
-err_queue_init:
-err_init_hw:
- s5p_mfc_release_firmware(dev);
-err_alloc_fw:
- dev->ctx[ctx->num] = NULL;
- del_timer_sync(&dev->watchdog_timer);
- s5p_mfc_clock_off();
-err_pwr_enable:
- if (dev->num_inst == 1) {
- if (s5p_mfc_power_off() < 0)
- mfc_err("power off failed\n");
- s5p_mfc_release_firmware(dev);
- }
-err_ctrls_setup:
- s5p_mfc_dec_ctrls_delete(ctx);
-err_bad_node:
-err_no_ctx:
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
- kfree(ctx);
-err_alloc:
- dev->num_inst--;
- mfc_debug_leave();
- return ret;
-}
-
-/* Release MFC context */
-static int s5p_mfc_release(struct file *file)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data);
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned long flags;
-
- mfc_debug_enter();
- s5p_mfc_clock_on();
- vb2_queue_release(&ctx->vq_src);
- vb2_queue_release(&ctx->vq_dst);
- /* Mark context as idle */
- spin_lock_irqsave(&dev->condlock, flags);
- clear_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- /* If instance was initialised then
- * return instance and free reosurces */
- if (ctx->inst_no != MFC_NO_INSTANCE_SET) {
- mfc_debug(2, "Has to free instance\n");
- ctx->state = MFCINST_RETURN_INST;
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_try_run(dev);
- /* Wait until instance is returned or timeout occured */
- if (s5p_mfc_wait_for_done_ctx
- (ctx, S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET, 0)) {
- s5p_mfc_clock_off();
- mfc_err("Err returning instance\n");
- }
- mfc_debug(2, "After free instance\n");
- /* Free resources */
- s5p_mfc_release_codec_buffers(ctx);
- s5p_mfc_release_instance_buffer(ctx);
- if (ctx->type == MFCINST_DECODER)
- s5p_mfc_release_dec_desc_buffer(ctx);
-
- ctx->inst_no = MFC_NO_INSTANCE_SET;
- }
- /* hardware locking scheme */
- if (dev->curr_ctx == ctx->num)
- clear_bit(0, &dev->hw_lock);
- dev->num_inst--;
- if (dev->num_inst == 0) {
- mfc_debug(2, "Last instance - release firmware\n");
- /* reset <-> F/W release */
- s5p_mfc_reset(dev);
- s5p_mfc_release_firmware(dev);
- del_timer_sync(&dev->watchdog_timer);
- if (s5p_mfc_power_off() < 0)
- mfc_err("Power off failed\n");
- }
- mfc_debug(2, "Shutting down clock\n");
- s5p_mfc_clock_off();
- dev->ctx[ctx->num] = NULL;
- s5p_mfc_dec_ctrls_delete(ctx);
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
- kfree(ctx);
- mfc_debug_leave();
- return 0;
-}
-
-/* Poll */
-static unsigned int s5p_mfc_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data);
- struct s5p_mfc_dev *dev = ctx->dev;
- struct vb2_queue *src_q, *dst_q;
- struct vb2_buffer *src_vb = NULL, *dst_vb = NULL;
- unsigned int rc = 0;
- unsigned long flags;
-
- src_q = &ctx->vq_src;
- dst_q = &ctx->vq_dst;
- /*
- * There has to be at least one buffer queued on each queued_list, which
- * means either in driver already or waiting for driver to claim it
- * and start processing.
- */
- if ((!src_q->streaming || list_empty(&src_q->queued_list))
- && (!dst_q->streaming || list_empty(&dst_q->queued_list))) {
- rc = POLLERR;
- goto end;
- }
- mutex_unlock(&dev->mfc_mutex);
- poll_wait(file, &src_q->done_wq, wait);
- poll_wait(file, &dst_q->done_wq, wait);
- mutex_lock(&dev->mfc_mutex);
- spin_lock_irqsave(&src_q->done_lock, flags);
- if (!list_empty(&src_q->done_list))
- src_vb = list_first_entry(&src_q->done_list, struct vb2_buffer,
- done_entry);
- if (src_vb && (src_vb->state == VB2_BUF_STATE_DONE
- || src_vb->state == VB2_BUF_STATE_ERROR))
- rc |= POLLOUT | POLLWRNORM;
- spin_unlock_irqrestore(&src_q->done_lock, flags);
- spin_lock_irqsave(&dst_q->done_lock, flags);
- if (!list_empty(&dst_q->done_list))
- dst_vb = list_first_entry(&dst_q->done_list, struct vb2_buffer,
- done_entry);
- if (dst_vb && (dst_vb->state == VB2_BUF_STATE_DONE
- || dst_vb->state == VB2_BUF_STATE_ERROR))
- rc |= POLLIN | POLLRDNORM;
- spin_unlock_irqrestore(&dst_q->done_lock, flags);
-end:
- return rc;
-}
-
-/* Mmap */
-static int s5p_mfc_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data);
- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
- int ret;
- if (offset < DST_QUEUE_OFF_BASE) {
- mfc_debug(2, "mmaping source\n");
- ret = vb2_mmap(&ctx->vq_src, vma);
- } else { /* capture */
- mfc_debug(2, "mmaping destination\n");
- vma->vm_pgoff -= (DST_QUEUE_OFF_BASE >> PAGE_SHIFT);
- ret = vb2_mmap(&ctx->vq_dst, vma);
- }
- return ret;
-}
-
-/* v4l2 ops */
-static const struct v4l2_file_operations s5p_mfc_fops = {
- .owner = THIS_MODULE,
- .open = s5p_mfc_open,
- .release = s5p_mfc_release,
- .poll = s5p_mfc_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = s5p_mfc_mmap,
-};
-
-static int match_child(struct device *dev, void *data)
-{
- if (!dev_name(dev))
- return 0;
- return !strcmp(dev_name(dev), (char *)data);
-}
-
-/* MFC probe function */
-static int s5p_mfc_probe(struct platform_device *pdev)
-{
- struct s5p_mfc_dev *dev;
- struct video_device *vfd;
- struct resource *res;
- int ret;
-
- pr_debug("%s++\n", __func__);
- dev = devm_kzalloc(&pdev->dev, sizeof *dev, GFP_KERNEL);
- if (!dev) {
- dev_err(&pdev->dev, "Not enough memory for MFC device\n");
- return -ENOMEM;
- }
-
- spin_lock_init(&dev->irqlock);
- spin_lock_init(&dev->condlock);
- dev->plat_dev = pdev;
- if (!dev->plat_dev) {
- dev_err(&pdev->dev, "No platform data specified\n");
- return -ENODEV;
- }
-
- ret = s5p_mfc_init_pm(dev);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to get mfc clock source\n");
- return ret;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- dev->regs_base = devm_request_and_ioremap(&pdev->dev, res);
- if (dev->regs_base == NULL) {
- dev_err(&pdev->dev, "Failed to obtain io memory\n");
- return -ENOENT;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "failed to get irq resource\n");
- ret = -ENOENT;
- goto err_res;
- }
- dev->irq = res->start;
- ret = devm_request_irq(&pdev->dev, dev->irq, s5p_mfc_irq,
- IRQF_DISABLED, pdev->name, dev);
- if (ret) {
- dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret);
- goto err_res;
- }
-
- dev->mem_dev_l = device_find_child(&dev->plat_dev->dev, "s5p-mfc-l",
- match_child);
- if (!dev->mem_dev_l) {
- mfc_err("Mem child (L) device get failed\n");
- ret = -ENODEV;
- goto err_res;
- }
- dev->mem_dev_r = device_find_child(&dev->plat_dev->dev, "s5p-mfc-r",
- match_child);
- if (!dev->mem_dev_r) {
- mfc_err("Mem child (R) device get failed\n");
- ret = -ENODEV;
- goto err_res;
- }
-
- dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l);
- if (IS_ERR_OR_NULL(dev->alloc_ctx[0])) {
- ret = PTR_ERR(dev->alloc_ctx[0]);
- goto err_res;
- }
- dev->alloc_ctx[1] = vb2_dma_contig_init_ctx(dev->mem_dev_r);
- if (IS_ERR_OR_NULL(dev->alloc_ctx[1])) {
- ret = PTR_ERR(dev->alloc_ctx[1]);
- goto err_mem_init_ctx_1;
- }
-
- mutex_init(&dev->mfc_mutex);
-
- ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
- if (ret)
- goto err_v4l2_dev_reg;
- init_waitqueue_head(&dev->queue);
-
- /* decoder */
- vfd = video_device_alloc();
- if (!vfd) {
- v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
- ret = -ENOMEM;
- goto err_dec_alloc;
- }
- vfd->fops = &s5p_mfc_fops,
- vfd->ioctl_ops = get_dec_v4l2_ioctl_ops();
- vfd->release = video_device_release,
- vfd->lock = &dev->mfc_mutex;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
- vfd->v4l2_dev = &dev->v4l2_dev;
- snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_DEC_NAME);
- dev->vfd_dec = vfd;
- ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
- if (ret) {
- v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
- video_device_release(vfd);
- goto err_dec_reg;
- }
- v4l2_info(&dev->v4l2_dev,
- "decoder registered as /dev/video%d\n", vfd->num);
- video_set_drvdata(vfd, dev);
-
- /* encoder */
- vfd = video_device_alloc();
- if (!vfd) {
- v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
- ret = -ENOMEM;
- goto err_enc_alloc;
- }
- vfd->fops = &s5p_mfc_fops,
- vfd->ioctl_ops = get_enc_v4l2_ioctl_ops();
- vfd->release = video_device_release,
- vfd->lock = &dev->mfc_mutex;
- /* This should not be necessary */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
- vfd->v4l2_dev = &dev->v4l2_dev;
- snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_ENC_NAME);
- dev->vfd_enc = vfd;
- ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
- if (ret) {
- v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
- video_device_release(vfd);
- goto err_enc_reg;
- }
- v4l2_info(&dev->v4l2_dev,
- "encoder registered as /dev/video%d\n", vfd->num);
- video_set_drvdata(vfd, dev);
- platform_set_drvdata(pdev, dev);
-
- dev->hw_lock = 0;
- dev->watchdog_workqueue = create_singlethread_workqueue(S5P_MFC_NAME);
- INIT_WORK(&dev->watchdog_work, s5p_mfc_watchdog_worker);
- atomic_set(&dev->watchdog_cnt, 0);
- init_timer(&dev->watchdog_timer);
- dev->watchdog_timer.data = (unsigned long)dev;
- dev->watchdog_timer.function = s5p_mfc_watchdog;
-
- pr_debug("%s--\n", __func__);
- return 0;
-
-/* Deinit MFC if probe had failed */
-err_enc_reg:
- video_device_release(dev->vfd_enc);
-err_enc_alloc:
- video_unregister_device(dev->vfd_dec);
-err_dec_reg:
- video_device_release(dev->vfd_dec);
-err_dec_alloc:
- v4l2_device_unregister(&dev->v4l2_dev);
-err_v4l2_dev_reg:
- vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[1]);
-err_mem_init_ctx_1:
- vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[0]);
-err_res:
- s5p_mfc_final_pm(dev);
-
- pr_debug("%s-- with error\n", __func__);
- return ret;
-
-}
-
-/* Remove the driver */
-static int __devexit s5p_mfc_remove(struct platform_device *pdev)
-{
- struct s5p_mfc_dev *dev = platform_get_drvdata(pdev);
-
- v4l2_info(&dev->v4l2_dev, "Removing %s\n", pdev->name);
-
- del_timer_sync(&dev->watchdog_timer);
- flush_workqueue(dev->watchdog_workqueue);
- destroy_workqueue(dev->watchdog_workqueue);
-
- video_unregister_device(dev->vfd_enc);
- video_unregister_device(dev->vfd_dec);
- v4l2_device_unregister(&dev->v4l2_dev);
- vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[0]);
- vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[1]);
-
- s5p_mfc_final_pm(dev);
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-
-static int s5p_mfc_suspend(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev);
- int ret;
-
- if (m_dev->num_inst == 0)
- return 0;
- return s5p_mfc_sleep(m_dev);
- if (test_and_set_bit(0, &m_dev->enter_suspend) != 0) {
- mfc_err("Error: going to suspend for a second time\n");
- return -EIO;
- }
-
- /* Check if we're processing then wait if it necessary. */
- while (test_and_set_bit(0, &m_dev->hw_lock) != 0) {
- /* Try and lock the HW */
- /* Wait on the interrupt waitqueue */
- ret = wait_event_interruptible_timeout(m_dev->queue,
- m_dev->int_cond || m_dev->ctx[m_dev->curr_ctx]->int_cond,
- msecs_to_jiffies(MFC_INT_TIMEOUT));
-
- if (ret == 0) {
- mfc_err("Waiting for hardware to finish timed out\n");
- return -EIO;
- }
- }
- return 0;
-}
-
-static int s5p_mfc_resume(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev);
-
- if (m_dev->num_inst == 0)
- return 0;
- return s5p_mfc_wakeup(m_dev);
-}
-#endif
-
-#ifdef CONFIG_PM_RUNTIME
-static int s5p_mfc_runtime_suspend(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev);
-
- atomic_set(&m_dev->pm.power, 0);
- return 0;
-}
-
-static int s5p_mfc_runtime_resume(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev);
- int pre_power;
-
- if (!m_dev->alloc_ctx)
- return 0;
- pre_power = atomic_read(&m_dev->pm.power);
- atomic_set(&m_dev->pm.power, 1);
- return 0;
-}
-#endif
-
-/* Power management */
-static const struct dev_pm_ops s5p_mfc_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(s5p_mfc_suspend, s5p_mfc_resume)
- SET_RUNTIME_PM_OPS(s5p_mfc_runtime_suspend, s5p_mfc_runtime_resume,
- NULL)
-};
-
-static struct platform_driver s5p_mfc_driver = {
- .probe = s5p_mfc_probe,
- .remove = __devexit_p(s5p_mfc_remove),
- .driver = {
- .name = S5P_MFC_NAME,
- .owner = THIS_MODULE,
- .pm = &s5p_mfc_pm_ops
- },
-};
-
-module_platform_driver(s5p_mfc_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>");
-MODULE_DESCRIPTION("Samsung S5P Multi Format Codec V4L2 driver");
-
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c b/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c
deleted file mode 100644
index f0665ed1a52..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include "regs-mfc.h"
-#include "s5p_mfc_cmd.h"
-#include "s5p_mfc_common.h"
-#include "s5p_mfc_debug.h"
-
-/* This function is used to send a command to the MFC */
-static int s5p_mfc_cmd_host2risc(struct s5p_mfc_dev *dev, int cmd,
- struct s5p_mfc_cmd_args *args)
-{
- int cur_cmd;
- unsigned long timeout;
-
- timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
- /* wait until host to risc command register becomes 'H2R_CMD_EMPTY' */
- do {
- if (time_after(jiffies, timeout)) {
- mfc_err("Timeout while waiting for hardware\n");
- return -EIO;
- }
- cur_cmd = mfc_read(dev, S5P_FIMV_HOST2RISC_CMD);
- } while (cur_cmd != S5P_FIMV_H2R_CMD_EMPTY);
- mfc_write(dev, args->arg[0], S5P_FIMV_HOST2RISC_ARG1);
- mfc_write(dev, args->arg[1], S5P_FIMV_HOST2RISC_ARG2);
- mfc_write(dev, args->arg[2], S5P_FIMV_HOST2RISC_ARG3);
- mfc_write(dev, args->arg[3], S5P_FIMV_HOST2RISC_ARG4);
- /* Issue the command */
- mfc_write(dev, cmd, S5P_FIMV_HOST2RISC_CMD);
- return 0;
-}
-
-/* Initialize the MFC */
-int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev)
-{
- struct s5p_mfc_cmd_args h2r_args;
-
- memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
- h2r_args.arg[0] = dev->fw_size;
- return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_SYS_INIT, &h2r_args);
-}
-
-/* Suspend the MFC hardware */
-int s5p_mfc_sleep_cmd(struct s5p_mfc_dev *dev)
-{
- struct s5p_mfc_cmd_args h2r_args;
-
- memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
- return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_SLEEP, &h2r_args);
-}
-
-/* Wake up the MFC hardware */
-int s5p_mfc_wakeup_cmd(struct s5p_mfc_dev *dev)
-{
- struct s5p_mfc_cmd_args h2r_args;
-
- memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
- return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_WAKEUP, &h2r_args);
-}
-
-
-int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_cmd_args h2r_args;
- int ret;
-
- /* Preparing decoding - getting instance number */
- mfc_debug(2, "Getting instance number (codec: %d)\n", ctx->codec_mode);
- dev->curr_ctx = ctx->num;
- memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
- h2r_args.arg[0] = ctx->codec_mode;
- h2r_args.arg[1] = 0; /* no crc & no pixelcache */
- h2r_args.arg[2] = ctx->ctx_ofs;
- h2r_args.arg[3] = ctx->ctx_size;
- ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE,
- &h2r_args);
- if (ret) {
- mfc_err("Failed to create a new instance\n");
- ctx->state = MFCINST_ERROR;
- }
- return ret;
-}
-
-int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_cmd_args h2r_args;
- int ret;
-
- if (ctx->state == MFCINST_FREE) {
- mfc_err("Instance already returned\n");
- ctx->state = MFCINST_ERROR;
- return -EINVAL;
- }
- /* Closing decoding instance */
- mfc_debug(2, "Returning instance number %d\n", ctx->inst_no);
- dev->curr_ctx = ctx->num;
- memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
- h2r_args.arg[0] = ctx->inst_no;
- ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_CLOSE_INSTANCE,
- &h2r_args);
- if (ret) {
- mfc_err("Failed to return an instance\n");
- ctx->state = MFCINST_ERROR;
- return -EINVAL;
- }
- return 0;
-}
-
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h b/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h
deleted file mode 100644
index 5ceebfe6131..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef S5P_MFC_CMD_H_
-#define S5P_MFC_CMD_H_
-
-#include "s5p_mfc_common.h"
-
-#define MAX_H2R_ARG 4
-
-struct s5p_mfc_cmd_args {
- unsigned int arg[MAX_H2R_ARG];
-};
-
-int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev);
-int s5p_mfc_sleep_cmd(struct s5p_mfc_dev *dev);
-int s5p_mfc_wakeup_cmd(struct s5p_mfc_dev *dev);
-int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx);
-int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx);
-
-#endif /* S5P_MFC_CMD_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_common.h b/drivers/media/video/s5p-mfc/s5p_mfc_common.h
deleted file mode 100644
index bd5706a6bad..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_common.h
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * Samsung S5P Multi Format Codec v 5.0
- *
- * This file contains definitions of enums and structs used by the codec
- * driver.
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * Kamil Debski, <k.debski@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version
- */
-
-#ifndef S5P_MFC_COMMON_H_
-#define S5P_MFC_COMMON_H_
-
-#include "regs-mfc.h"
-#include <linux/platform_device.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
-
-/* Definitions related to MFC memory */
-
-/* Offset base used to differentiate between CAPTURE and OUTPUT
-* while mmaping */
-#define DST_QUEUE_OFF_BASE (TASK_SIZE / 2)
-
-/* Offset used by the hardware to store addresses */
-#define MFC_OFFSET_SHIFT 11
-
-#define FIRMWARE_ALIGN 0x20000 /* 128KB */
-#define MFC_H264_CTX_BUF_SIZE 0x96000 /* 600KB per H264 instance */
-#define MFC_CTX_BUF_SIZE 0x2800 /* 10KB per instance */
-#define DESC_BUF_SIZE 0x20000 /* 128KB for DESC buffer */
-#define SHARED_BUF_SIZE 0x2000 /* 8KB for shared buffer */
-
-#define DEF_CPB_SIZE 0x40000 /* 512KB */
-
-#define MFC_BANK1_ALLOC_CTX 0
-#define MFC_BANK2_ALLOC_CTX 1
-
-#define MFC_BANK1_ALIGN_ORDER 13
-#define MFC_BANK2_ALIGN_ORDER 13
-#define MFC_BASE_ALIGN_ORDER 17
-
-#include <media/videobuf2-dma-contig.h>
-
-static inline dma_addr_t s5p_mfc_mem_cookie(void *a, void *b)
-{
- /* Same functionality as the vb2_dma_contig_plane_paddr */
- dma_addr_t *paddr = vb2_dma_contig_memops.cookie(b);
-
- return *paddr;
-}
-
-/* MFC definitions */
-#define MFC_MAX_EXTRA_DPB 5
-#define MFC_MAX_BUFFERS 32
-#define MFC_NUM_CONTEXTS 4
-/* Interrupt timeout */
-#define MFC_INT_TIMEOUT 2000
-/* Busy wait timeout */
-#define MFC_BW_TIMEOUT 500
-/* Watchdog interval */
-#define MFC_WATCHDOG_INTERVAL 1000
-/* After how many executions watchdog should assume lock up */
-#define MFC_WATCHDOG_CNT 10
-#define MFC_NO_INSTANCE_SET -1
-#define MFC_ENC_CAP_PLANE_COUNT 1
-#define MFC_ENC_OUT_PLANE_COUNT 2
-#define STUFF_BYTE 4
-#define MFC_MAX_CTRLS 64
-
-#define mfc_read(dev, offset) readl(dev->regs_base + (offset))
-#define mfc_write(dev, data, offset) writel((data), dev->regs_base + \
- (offset))
-
-/**
- * enum s5p_mfc_fmt_type - type of the pixelformat
- */
-enum s5p_mfc_fmt_type {
- MFC_FMT_DEC,
- MFC_FMT_ENC,
- MFC_FMT_RAW,
-};
-
-/**
- * enum s5p_mfc_node_type - The type of an MFC device node.
- */
-enum s5p_mfc_node_type {
- MFCNODE_INVALID = -1,
- MFCNODE_DECODER = 0,
- MFCNODE_ENCODER = 1,
-};
-
-/**
- * enum s5p_mfc_inst_type - The type of an MFC instance.
- */
-enum s5p_mfc_inst_type {
- MFCINST_INVALID,
- MFCINST_DECODER,
- MFCINST_ENCODER,
-};
-
-/**
- * enum s5p_mfc_inst_state - The state of an MFC instance.
- */
-enum s5p_mfc_inst_state {
- MFCINST_FREE = 0,
- MFCINST_INIT = 100,
- MFCINST_GOT_INST,
- MFCINST_HEAD_PARSED,
- MFCINST_BUFS_SET,
- MFCINST_RUNNING,
- MFCINST_FINISHING,
- MFCINST_FINISHED,
- MFCINST_RETURN_INST,
- MFCINST_ERROR,
- MFCINST_ABORT,
- MFCINST_RES_CHANGE_INIT,
- MFCINST_RES_CHANGE_FLUSH,
- MFCINST_RES_CHANGE_END,
-};
-
-/**
- * enum s5p_mfc_queue_state - The state of buffer queue.
- */
-enum s5p_mfc_queue_state {
- QUEUE_FREE,
- QUEUE_BUFS_REQUESTED,
- QUEUE_BUFS_QUERIED,
- QUEUE_BUFS_MMAPED,
-};
-
-/**
- * enum s5p_mfc_decode_arg - type of frame decoding
- */
-enum s5p_mfc_decode_arg {
- MFC_DEC_FRAME,
- MFC_DEC_LAST_FRAME,
- MFC_DEC_RES_CHANGE,
-};
-
-struct s5p_mfc_ctx;
-
-/**
- * struct s5p_mfc_buf - MFC buffer
- */
-struct s5p_mfc_buf {
- struct list_head list;
- struct vb2_buffer *b;
- union {
- struct {
- size_t luma;
- size_t chroma;
- } raw;
- size_t stream;
- } cookie;
- int used;
-};
-
-/**
- * struct s5p_mfc_pm - power management data structure
- */
-struct s5p_mfc_pm {
- struct clk *clock;
- struct clk *clock_gate;
- atomic_t power;
- struct device *device;
-};
-
-/**
- * struct s5p_mfc_dev - The struct containing driver internal parameters.
- *
- * @v4l2_dev: v4l2_device
- * @vfd_dec: video device for decoding
- * @vfd_enc: video device for encoding
- * @plat_dev: platform device
- * @mem_dev_l: child device of the left memory bank (0)
- * @mem_dev_r: child device of the right memory bank (1)
- * @regs_base: base address of the MFC hw registers
- * @irq: irq resource
- * @dec_ctrl_handler: control framework handler for decoding
- * @enc_ctrl_handler: control framework handler for encoding
- * @pm: power management control
- * @num_inst: couter of active MFC instances
- * @irqlock: lock for operations on videobuf2 queues
- * @condlock: lock for changing/checking if a context is ready to be
- * processed
- * @mfc_mutex: lock for video_device
- * @int_cond: variable used by the waitqueue
- * @int_type: type of last interrupt
- * @int_err: error number for last interrupt
- * @queue: waitqueue for waiting for completion of device commands
- * @fw_size: size of firmware
- * @bank1: address of the beggining of bank 1 memory
- * @bank2: address of the beggining of bank 2 memory
- * @hw_lock: used for hardware locking
- * @ctx: array of driver contexts
- * @curr_ctx: number of the currently running context
- * @ctx_work_bits: used to mark which contexts are waiting for hardware
- * @watchdog_cnt: counter for the watchdog
- * @watchdog_workqueue: workqueue for the watchdog
- * @watchdog_work: worker for the watchdog
- * @alloc_ctx: videobuf2 allocator contexts for two memory banks
- * @enter_suspend: flag set when entering suspend
- *
- */
-struct s5p_mfc_dev {
- struct v4l2_device v4l2_dev;
- struct video_device *vfd_dec;
- struct video_device *vfd_enc;
- struct platform_device *plat_dev;
- struct device *mem_dev_l;
- struct device *mem_dev_r;
- void __iomem *regs_base;
- int irq;
- struct v4l2_ctrl_handler dec_ctrl_handler;
- struct v4l2_ctrl_handler enc_ctrl_handler;
- struct s5p_mfc_pm pm;
- int num_inst;
- spinlock_t irqlock; /* lock when operating on videobuf2 queues */
- spinlock_t condlock; /* lock when changing/checking if a context is
- ready to be processed */
- struct mutex mfc_mutex; /* video_device lock */
- int int_cond;
- int int_type;
- unsigned int int_err;
- wait_queue_head_t queue;
- size_t fw_size;
- size_t bank1;
- size_t bank2;
- unsigned long hw_lock;
- struct s5p_mfc_ctx *ctx[MFC_NUM_CONTEXTS];
- int curr_ctx;
- unsigned long ctx_work_bits;
- atomic_t watchdog_cnt;
- struct timer_list watchdog_timer;
- struct workqueue_struct *watchdog_workqueue;
- struct work_struct watchdog_work;
- void *alloc_ctx[2];
- unsigned long enter_suspend;
-};
-
-/**
- * struct s5p_mfc_h264_enc_params - encoding parameters for h264
- */
-struct s5p_mfc_h264_enc_params {
- enum v4l2_mpeg_video_h264_profile profile;
- enum v4l2_mpeg_video_h264_loop_filter_mode loop_filter_mode;
- s8 loop_filter_alpha;
- s8 loop_filter_beta;
- enum v4l2_mpeg_video_h264_entropy_mode entropy_mode;
- u8 max_ref_pic;
- u8 num_ref_pic_4p;
- int _8x8_transform;
- int rc_mb;
- int rc_mb_dark;
- int rc_mb_smooth;
- int rc_mb_static;
- int rc_mb_activity;
- int vui_sar;
- u8 vui_sar_idc;
- u16 vui_ext_sar_width;
- u16 vui_ext_sar_height;
- int open_gop;
- u16 open_gop_size;
- u8 rc_frame_qp;
- u8 rc_min_qp;
- u8 rc_max_qp;
- u8 rc_p_frame_qp;
- u8 rc_b_frame_qp;
- enum v4l2_mpeg_video_h264_level level_v4l2;
- int level;
- u16 cpb_size;
-};
-
-/**
- * struct s5p_mfc_mpeg4_enc_params - encoding parameters for h263 and mpeg4
- */
-struct s5p_mfc_mpeg4_enc_params {
- /* MPEG4 Only */
- enum v4l2_mpeg_video_mpeg4_profile profile;
- int quarter_pixel;
- /* Common for MPEG4, H263 */
- u16 vop_time_res;
- u16 vop_frm_delta;
- u8 rc_frame_qp;
- u8 rc_min_qp;
- u8 rc_max_qp;
- u8 rc_p_frame_qp;
- u8 rc_b_frame_qp;
- enum v4l2_mpeg_video_mpeg4_level level_v4l2;
- int level;
-};
-
-/**
- * struct s5p_mfc_enc_params - general encoding parameters
- */
-struct s5p_mfc_enc_params {
- u16 width;
- u16 height;
-
- u16 gop_size;
- enum v4l2_mpeg_video_multi_slice_mode slice_mode;
- u16 slice_mb;
- u32 slice_bit;
- u16 intra_refresh_mb;
- int pad;
- u8 pad_luma;
- u8 pad_cb;
- u8 pad_cr;
- int rc_frame;
- u32 rc_bitrate;
- u16 rc_reaction_coeff;
- u16 vbv_size;
-
- enum v4l2_mpeg_video_header_mode seq_hdr_mode;
- enum v4l2_mpeg_mfc51_video_frame_skip_mode frame_skip_mode;
- int fixed_target_bit;
-
- u8 num_b_frame;
- u32 rc_framerate_num;
- u32 rc_framerate_denom;
- int interlace;
-
- union {
- struct s5p_mfc_h264_enc_params h264;
- struct s5p_mfc_mpeg4_enc_params mpeg4;
- } codec;
-
-};
-
-/**
- * struct s5p_mfc_codec_ops - codec ops, used by encoding
- */
-struct s5p_mfc_codec_ops {
- /* initialization routines */
- int (*pre_seq_start) (struct s5p_mfc_ctx *ctx);
- int (*post_seq_start) (struct s5p_mfc_ctx *ctx);
- /* execution routines */
- int (*pre_frame_start) (struct s5p_mfc_ctx *ctx);
- int (*post_frame_start) (struct s5p_mfc_ctx *ctx);
-};
-
-#define call_cop(c, op, args...) \
- (((c)->c_ops->op) ? \
- ((c)->c_ops->op(args)) : 0)
-
-/**
- * struct s5p_mfc_ctx - This struct contains the instance context
- *
- * @dev: pointer to the s5p_mfc_dev of the device
- * @fh: struct v4l2_fh
- * @num: number of the context that this structure describes
- * @int_cond: variable used by the waitqueue
- * @int_type: type of the last interrupt
- * @int_err: error number received from MFC hw in the interrupt
- * @queue: waitqueue that can be used to wait for this context to
- * finish
- * @src_fmt: source pixelformat information
- * @dst_fmt: destination pixelformat information
- * @vq_src: vb2 queue for source buffers
- * @vq_dst: vb2 queue for destination buffers
- * @src_queue: driver internal queue for source buffers
- * @dst_queue: driver internal queue for destination buffers
- * @src_queue_cnt: number of buffers queued on the source internal queue
- * @dst_queue_cnt: number of buffers queued on the dest internal queue
- * @type: type of the instance - decoder or encoder
- * @state: state of the context
- * @inst_no: number of hw instance associated with the context
- * @img_width: width of the image that is decoded or encoded
- * @img_height: height of the image that is decoded or encoded
- * @buf_width: width of the buffer for processed image
- * @buf_height: height of the buffer for processed image
- * @luma_size: size of a luma plane
- * @chroma_size: size of a chroma plane
- * @mv_size: size of a motion vectors buffer
- * @consumed_stream: number of bytes that have been used so far from the
- * decoding buffer
- * @dpb_flush_flag: flag used to indicate that a DPB buffers are being
- * flushed
- * @bank1_buf: handle to memory allocated for temporary buffers from
- * memory bank 1
- * @bank1_phys: address of the temporary buffers from memory bank 1
- * @bank1_size: size of the memory allocated for temporary buffers from
- * memory bank 1
- * @bank2_buf: handle to memory allocated for temporary buffers from
- * memory bank 2
- * @bank2_phys: address of the temporary buffers from memory bank 2
- * @bank2_size: size of the memory allocated for temporary buffers from
- * memory bank 2
- * @capture_state: state of the capture buffers queue
- * @output_state: state of the output buffers queue
- * @src_bufs: information on allocated source buffers
- * @dst_bufs: information on allocated destination buffers
- * @sequence: counter for the sequence number for v4l2
- * @dec_dst_flag: flags for buffers queued in the hardware
- * @dec_src_buf_size: size of the buffer for source buffers in decoding
- * @codec_mode: number of codec mode used by MFC hw
- * @slice_interface: slice interface flag
- * @loop_filter_mpeg4: loop filter for MPEG4 flag
- * @display_delay: value of the display delay for H264
- * @display_delay_enable: display delay for H264 enable flag
- * @after_packed_pb: flag used to track buffer when stream is in
- * Packed PB format
- * @dpb_count: count of the DPB buffers required by MFC hw
- * @total_dpb_count: count of DPB buffers with additional buffers
- * requested by the application
- * @ctx_buf: handle to the memory associated with this context
- * @ctx_phys: address of the memory associated with this context
- * @ctx_size: size of the memory associated with this context
- * @desc_buf: description buffer for decoding handle
- * @desc_phys: description buffer for decoding address
- * @shm_alloc: handle for the shared memory buffer
- * @shm: virtual address for the shared memory buffer
- * @shm_ofs: address offset for shared memory
- * @enc_params: encoding parameters for MFC
- * @enc_dst_buf_size: size of the buffers for encoder output
- * @frame_type: used to force the type of the next encoded frame
- * @ref_queue: list of the reference buffers for encoding
- * @ref_queue_cnt: number of the buffers in the reference list
- * @c_ops: ops for encoding
- * @ctrls: array of controls, used when adding controls to the
- * v4l2 control framework
- * @ctrl_handler: handler for v4l2 framework
- */
-struct s5p_mfc_ctx {
- struct s5p_mfc_dev *dev;
- struct v4l2_fh fh;
-
- int num;
-
- int int_cond;
- int int_type;
- unsigned int int_err;
- wait_queue_head_t queue;
-
- struct s5p_mfc_fmt *src_fmt;
- struct s5p_mfc_fmt *dst_fmt;
-
- struct vb2_queue vq_src;
- struct vb2_queue vq_dst;
-
- struct list_head src_queue;
- struct list_head dst_queue;
-
- unsigned int src_queue_cnt;
- unsigned int dst_queue_cnt;
-
- enum s5p_mfc_inst_type type;
- enum s5p_mfc_inst_state state;
- int inst_no;
-
- /* Image parameters */
- int img_width;
- int img_height;
- int buf_width;
- int buf_height;
-
- int luma_size;
- int chroma_size;
- int mv_size;
-
- unsigned long consumed_stream;
-
- unsigned int dpb_flush_flag;
-
- /* Buffers */
- void *bank1_buf;
- size_t bank1_phys;
- size_t bank1_size;
-
- void *bank2_buf;
- size_t bank2_phys;
- size_t bank2_size;
-
- enum s5p_mfc_queue_state capture_state;
- enum s5p_mfc_queue_state output_state;
-
- struct s5p_mfc_buf src_bufs[MFC_MAX_BUFFERS];
- int src_bufs_cnt;
- struct s5p_mfc_buf dst_bufs[MFC_MAX_BUFFERS];
- int dst_bufs_cnt;
-
- unsigned int sequence;
- unsigned long dec_dst_flag;
- size_t dec_src_buf_size;
-
- /* Control values */
- int codec_mode;
- int slice_interface;
- int loop_filter_mpeg4;
- int display_delay;
- int display_delay_enable;
- int after_packed_pb;
-
- int dpb_count;
- int total_dpb_count;
-
- /* Buffers */
- void *ctx_buf;
- size_t ctx_phys;
- size_t ctx_ofs;
- size_t ctx_size;
-
- void *desc_buf;
- size_t desc_phys;
-
-
- void *shm_alloc;
- void *shm;
- size_t shm_ofs;
-
- struct s5p_mfc_enc_params enc_params;
-
- size_t enc_dst_buf_size;
-
- enum v4l2_mpeg_mfc51_video_force_frame_type force_frame_type;
-
- struct list_head ref_queue;
- unsigned int ref_queue_cnt;
-
- struct s5p_mfc_codec_ops *c_ops;
-
- struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
- struct v4l2_ctrl_handler ctrl_handler;
-};
-
-/*
- * struct s5p_mfc_fmt - structure used to store information about pixelformats
- * used by the MFC
- */
-struct s5p_mfc_fmt {
- char *name;
- u32 fourcc;
- u32 codec_mode;
- enum s5p_mfc_fmt_type type;
- u32 num_planes;
-};
-
-/**
- * struct mfc_control - structure used to store information about MFC controls
- * it is used to initialize the control framework.
- */
-struct mfc_control {
- __u32 id;
- enum v4l2_ctrl_type type;
- __u8 name[32]; /* Whatever */
- __s32 minimum; /* Note signedness */
- __s32 maximum;
- __s32 step;
- __u32 menu_skip_mask;
- __s32 default_value;
- __u32 flags;
- __u32 reserved[2];
- __u8 is_volatile;
-};
-
-
-#define fh_to_ctx(__fh) container_of(__fh, struct s5p_mfc_ctx, fh)
-#define ctrl_to_ctx(__ctrl) \
- container_of((__ctrl)->handler, struct s5p_mfc_ctx, ctrl_handler)
-
-#endif /* S5P_MFC_COMMON_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
deleted file mode 100644
index 08a5cfeaa59..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/firmware.h>
-#include <linux/jiffies.h>
-#include <linux/sched.h>
-#include "regs-mfc.h"
-#include "s5p_mfc_cmd.h"
-#include "s5p_mfc_common.h"
-#include "s5p_mfc_debug.h"
-#include "s5p_mfc_intr.h"
-#include "s5p_mfc_pm.h"
-
-static void *s5p_mfc_bitproc_buf;
-static size_t s5p_mfc_bitproc_phys;
-static unsigned char *s5p_mfc_bitproc_virt;
-
-/* Allocate and load firmware */
-int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
-{
- struct firmware *fw_blob;
- size_t bank2_base_phys;
- void *b_base;
- int err;
-
- /* Firmare has to be present as a separate file or compiled
- * into kernel. */
- mfc_debug_enter();
- err = request_firmware((const struct firmware **)&fw_blob,
- "s5p-mfc.fw", dev->v4l2_dev.dev);
- if (err != 0) {
- mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
- return -EINVAL;
- }
- dev->fw_size = ALIGN(fw_blob->size, FIRMWARE_ALIGN);
- if (s5p_mfc_bitproc_buf) {
- mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n");
- release_firmware(fw_blob);
- return -ENOMEM;
- }
- s5p_mfc_bitproc_buf = vb2_dma_contig_memops.alloc(
- dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], dev->fw_size);
- if (IS_ERR(s5p_mfc_bitproc_buf)) {
- s5p_mfc_bitproc_buf = NULL;
- mfc_err("Allocating bitprocessor buffer failed\n");
- release_firmware(fw_blob);
- return -ENOMEM;
- }
- s5p_mfc_bitproc_phys = s5p_mfc_mem_cookie(
- dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], s5p_mfc_bitproc_buf);
- if (s5p_mfc_bitproc_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) {
- mfc_err("The base memory for bank 1 is not aligned to 128KB\n");
- vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
- s5p_mfc_bitproc_phys = 0;
- s5p_mfc_bitproc_buf = NULL;
- release_firmware(fw_blob);
- return -EIO;
- }
- s5p_mfc_bitproc_virt = vb2_dma_contig_memops.vaddr(s5p_mfc_bitproc_buf);
- if (!s5p_mfc_bitproc_virt) {
- mfc_err("Bitprocessor memory remap failed\n");
- vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
- s5p_mfc_bitproc_phys = 0;
- s5p_mfc_bitproc_buf = NULL;
- release_firmware(fw_blob);
- return -EIO;
- }
- dev->bank1 = s5p_mfc_bitproc_phys;
- b_base = vb2_dma_contig_memops.alloc(
- dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], 1 << MFC_BANK2_ALIGN_ORDER);
- if (IS_ERR(b_base)) {
- vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
- s5p_mfc_bitproc_phys = 0;
- s5p_mfc_bitproc_buf = NULL;
- mfc_err("Allocating bank2 base failed\n");
- release_firmware(fw_blob);
- return -ENOMEM;
- }
- bank2_base_phys = s5p_mfc_mem_cookie(
- dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], b_base);
- vb2_dma_contig_memops.put(b_base);
- if (bank2_base_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) {
- mfc_err("The base memory for bank 2 is not aligned to 128KB\n");
- vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
- s5p_mfc_bitproc_phys = 0;
- s5p_mfc_bitproc_buf = NULL;
- release_firmware(fw_blob);
- return -EIO;
- }
- dev->bank2 = bank2_base_phys;
- memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size);
- wmb();
- release_firmware(fw_blob);
- mfc_debug_leave();
- return 0;
-}
-
-/* Reload firmware to MFC */
-int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev)
-{
- struct firmware *fw_blob;
- int err;
-
- /* Firmare has to be present as a separate file or compiled
- * into kernel. */
- mfc_debug_enter();
- err = request_firmware((const struct firmware **)&fw_blob,
- "s5p-mfc.fw", dev->v4l2_dev.dev);
- if (err != 0) {
- mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
- return -EINVAL;
- }
- if (fw_blob->size > dev->fw_size) {
- mfc_err("MFC firmware is too big to be loaded\n");
- release_firmware(fw_blob);
- return -ENOMEM;
- }
- if (s5p_mfc_bitproc_buf == NULL || s5p_mfc_bitproc_phys == 0) {
- mfc_err("MFC firmware is not allocated or was not mapped correctly\n");
- release_firmware(fw_blob);
- return -EINVAL;
- }
- memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size);
- wmb();
- release_firmware(fw_blob);
- mfc_debug_leave();
- return 0;
-}
-
-/* Release firmware memory */
-int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev)
-{
- /* Before calling this function one has to make sure
- * that MFC is no longer processing */
- if (!s5p_mfc_bitproc_buf)
- return -EINVAL;
- vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
- s5p_mfc_bitproc_virt = NULL;
- s5p_mfc_bitproc_phys = 0;
- s5p_mfc_bitproc_buf = NULL;
- return 0;
-}
-
-/* Reset the device */
-int s5p_mfc_reset(struct s5p_mfc_dev *dev)
-{
- unsigned int mc_status;
- unsigned long timeout;
-
- mfc_debug_enter();
- /* Stop procedure */
- /* reset RISC */
- mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
- /* All reset except for MC */
- mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
- mdelay(10);
-
- timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
- /* Check MC status */
- do {
- if (time_after(jiffies, timeout)) {
- mfc_err("Timeout while resetting MFC\n");
- return -EIO;
- }
-
- mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS);
-
- } while (mc_status & 0x3);
-
- mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
- mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
- mfc_debug_leave();
- return 0;
-}
-
-static inline void s5p_mfc_init_memctrl(struct s5p_mfc_dev *dev)
-{
- mfc_write(dev, dev->bank1, S5P_FIMV_MC_DRAMBASE_ADR_A);
- mfc_write(dev, dev->bank2, S5P_FIMV_MC_DRAMBASE_ADR_B);
- mfc_debug(2, "Bank1: %08x, Bank2: %08x\n", dev->bank1, dev->bank2);
-}
-
-static inline void s5p_mfc_clear_cmds(struct s5p_mfc_dev *dev)
-{
- mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH0_INST_ID);
- mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH1_INST_ID);
- mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
- mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD);
-}
-
-/* Initialize hardware */
-int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
-{
- unsigned int ver;
- int ret;
-
- mfc_debug_enter();
- if (!s5p_mfc_bitproc_buf)
- return -EINVAL;
-
- /* 0. MFC reset */
- mfc_debug(2, "MFC reset..\n");
- s5p_mfc_clock_on();
- ret = s5p_mfc_reset(dev);
- if (ret) {
- mfc_err("Failed to reset MFC - timeout\n");
- return ret;
- }
- mfc_debug(2, "Done MFC reset..\n");
- /* 1. Set DRAM base Addr */
- s5p_mfc_init_memctrl(dev);
- /* 2. Initialize registers of channel I/F */
- s5p_mfc_clear_cmds(dev);
- /* 3. Release reset signal to the RISC */
- s5p_mfc_clean_dev_int_flags(dev);
- mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
- mfc_debug(2, "Will now wait for completion of firmware transfer\n");
- if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_FW_STATUS_RET)) {
- mfc_err("Failed to load firmware\n");
- s5p_mfc_reset(dev);
- s5p_mfc_clock_off();
- return -EIO;
- }
- s5p_mfc_clean_dev_int_flags(dev);
- /* 4. Initialize firmware */
- ret = s5p_mfc_sys_init_cmd(dev);
- if (ret) {
- mfc_err("Failed to send command to MFC - timeout\n");
- s5p_mfc_reset(dev);
- s5p_mfc_clock_off();
- return ret;
- }
- mfc_debug(2, "Ok, now will write a command to init the system\n");
- if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_SYS_INIT_RET)) {
- mfc_err("Failed to load firmware\n");
- s5p_mfc_reset(dev);
- s5p_mfc_clock_off();
- return -EIO;
- }
- dev->int_cond = 0;
- if (dev->int_err != 0 || dev->int_type !=
- S5P_FIMV_R2H_CMD_SYS_INIT_RET) {
- /* Failure. */
- mfc_err("Failed to init firmware - error: %d int: %d\n",
- dev->int_err, dev->int_type);
- s5p_mfc_reset(dev);
- s5p_mfc_clock_off();
- return -EIO;
- }
- ver = mfc_read(dev, S5P_FIMV_FW_VERSION);
- mfc_debug(2, "MFC F/W version : %02xyy, %02xmm, %02xdd\n",
- (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
- s5p_mfc_clock_off();
- mfc_debug_leave();
- return 0;
-}
-
-
-int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
-{
- int ret;
-
- mfc_debug_enter();
- s5p_mfc_clock_on();
- s5p_mfc_clean_dev_int_flags(dev);
- ret = s5p_mfc_sleep_cmd(dev);
- if (ret) {
- mfc_err("Failed to send command to MFC - timeout\n");
- return ret;
- }
- if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_SLEEP_RET)) {
- mfc_err("Failed to sleep\n");
- return -EIO;
- }
- s5p_mfc_clock_off();
- dev->int_cond = 0;
- if (dev->int_err != 0 || dev->int_type !=
- S5P_FIMV_R2H_CMD_SLEEP_RET) {
- /* Failure. */
- mfc_err("Failed to sleep - error: %d int: %d\n", dev->int_err,
- dev->int_type);
- return -EIO;
- }
- mfc_debug_leave();
- return ret;
-}
-
-int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
-{
- int ret;
-
- mfc_debug_enter();
- /* 0. MFC reset */
- mfc_debug(2, "MFC reset..\n");
- s5p_mfc_clock_on();
- ret = s5p_mfc_reset(dev);
- if (ret) {
- mfc_err("Failed to reset MFC - timeout\n");
- return ret;
- }
- mfc_debug(2, "Done MFC reset..\n");
- /* 1. Set DRAM base Addr */
- s5p_mfc_init_memctrl(dev);
- /* 2. Initialize registers of channel I/F */
- s5p_mfc_clear_cmds(dev);
- s5p_mfc_clean_dev_int_flags(dev);
- /* 3. Initialize firmware */
- ret = s5p_mfc_wakeup_cmd(dev);
- if (ret) {
- mfc_err("Failed to send command to MFC - timeout\n");
- return ret;
- }
- /* 4. Release reset signal to the RISC */
- mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
- mfc_debug(2, "Ok, now will write a command to wakeup the system\n");
- if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_WAKEUP_RET)) {
- mfc_err("Failed to load firmware\n");
- return -EIO;
- }
- s5p_mfc_clock_off();
- dev->int_cond = 0;
- if (dev->int_err != 0 || dev->int_type !=
- S5P_FIMV_R2H_CMD_WAKEUP_RET) {
- /* Failure. */
- mfc_err("Failed to wakeup - error: %d int: %d\n", dev->int_err,
- dev->int_type);
- return -EIO;
- }
- mfc_debug_leave();
- return 0;
-}
-
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h b/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h
deleted file mode 100644
index 61dc23b7ee5..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef S5P_MFC_CTRL_H
-#define S5P_MFC_CTRL_H
-
-#include "s5p_mfc_common.h"
-
-int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev);
-int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev);
-int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev);
-
-int s5p_mfc_init_hw(struct s5p_mfc_dev *dev);
-
-int s5p_mfc_sleep(struct s5p_mfc_dev *dev);
-int s5p_mfc_wakeup(struct s5p_mfc_dev *dev);
-
-int s5p_mfc_reset(struct s5p_mfc_dev *dev);
-
-#endif /* S5P_MFC_CTRL_H */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_debug.h b/drivers/media/video/s5p-mfc/s5p_mfc_debug.h
deleted file mode 100644
index ecb8616a492..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_debug.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * drivers/media/video/samsung/mfc5/s5p_mfc_debug.h
- *
- * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
- * This file contains debug macros
- *
- * Kamil Debski, Copyright (c) 2011 Samsung Electronics
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef S5P_MFC_DEBUG_H_
-#define S5P_MFC_DEBUG_H_
-
-#define DEBUG
-
-#ifdef DEBUG
-extern int debug;
-
-#define mfc_debug(level, fmt, args...) \
- do { \
- if (debug >= level) \
- printk(KERN_DEBUG "%s:%d: " fmt, \
- __func__, __LINE__, ##args); \
- } while (0)
-#else
-#define mfc_debug(level, fmt, args...)
-#endif
-
-#define mfc_debug_enter() mfc_debug(5, "enter")
-#define mfc_debug_leave() mfc_debug(5, "leave")
-
-#define mfc_err(fmt, args...) \
- do { \
- printk(KERN_ERR "%s:%d: " fmt, \
- __func__, __LINE__, ##args); \
- } while (0)
-
-#define mfc_info(fmt, args...) \
- do { \
- printk(KERN_INFO "%s:%d: " fmt, \
- __func__, __LINE__, ##args); \
- } while (0)
-
-#endif /* S5P_MFC_DEBUG_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
deleted file mode 100644
index c5d567f87d7..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
+++ /dev/null
@@ -1,1044 +0,0 @@
-/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- * Kamil Debski, <k.debski@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/version.h>
-#include <linux/videodev2.h>
-#include <linux/workqueue.h>
-#include <media/v4l2-ctrls.h>
-#include <media/videobuf2-core.h>
-#include "regs-mfc.h"
-#include "s5p_mfc_common.h"
-#include "s5p_mfc_debug.h"
-#include "s5p_mfc_dec.h"
-#include "s5p_mfc_intr.h"
-#include "s5p_mfc_opr.h"
-#include "s5p_mfc_pm.h"
-#include "s5p_mfc_shm.h"
-
-static struct s5p_mfc_fmt formats[] = {
- {
- .name = "4:2:0 2 Planes 64x32 Tiles",
- .fourcc = V4L2_PIX_FMT_NV12MT,
- .codec_mode = S5P_FIMV_CODEC_NONE,
- .type = MFC_FMT_RAW,
- .num_planes = 2,
- },
- {
- .name = "4:2:0 2 Planes",
- .fourcc = V4L2_PIX_FMT_NV12M,
- .codec_mode = S5P_FIMV_CODEC_NONE,
- .type = MFC_FMT_RAW,
- .num_planes = 2,
- },
- {
- .name = "H264 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_H264,
- .codec_mode = S5P_FIMV_CODEC_H264_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
- },
- {
- .name = "H263 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_H263,
- .codec_mode = S5P_FIMV_CODEC_H263_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
- },
- {
- .name = "MPEG1 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_MPEG1,
- .codec_mode = S5P_FIMV_CODEC_MPEG2_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
- },
- {
- .name = "MPEG2 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_MPEG2,
- .codec_mode = S5P_FIMV_CODEC_MPEG2_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
- },
- {
- .name = "MPEG4 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_MPEG4,
- .codec_mode = S5P_FIMV_CODEC_MPEG4_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
- },
- {
- .name = "XviD Encoded Stream",
- .fourcc = V4L2_PIX_FMT_XVID,
- .codec_mode = S5P_FIMV_CODEC_MPEG4_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
- },
- {
- .name = "VC1 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
- .codec_mode = S5P_FIMV_CODEC_VC1_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
- },
- {
- .name = "VC1 RCV Encoded Stream",
- .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
- .codec_mode = S5P_FIMV_CODEC_VC1RCV_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
- },
-};
-
-#define NUM_FORMATS ARRAY_SIZE(formats)
-
-/* Find selected format description */
-static struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t)
-{
- unsigned int i;
-
- for (i = 0; i < NUM_FORMATS; i++) {
- if (formats[i].fourcc == f->fmt.pix_mp.pixelformat &&
- formats[i].type == t)
- return &formats[i];
- }
- return NULL;
-}
-
-static struct mfc_control controls[] = {
- {
- .id = V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "H264 Display Delay",
- .minimum = 0,
- .maximum = 16383,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "H264 Display Delay Enable",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Mpeg4 Loop Filter Enable",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Slice Interface Enable",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Minimum number of cap bufs",
- .minimum = 1,
- .maximum = 32,
- .step = 1,
- .default_value = 1,
- .is_volatile = 1,
- },
-};
-
-#define NUM_CTRLS ARRAY_SIZE(controls)
-
-/* Check whether a context should be run on hardware */
-static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx)
-{
- /* Context is to parse header */
- if (ctx->src_queue_cnt >= 1 && ctx->state == MFCINST_GOT_INST)
- return 1;
- /* Context is to decode a frame */
- if (ctx->src_queue_cnt >= 1 &&
- ctx->state == MFCINST_RUNNING &&
- ctx->dst_queue_cnt >= ctx->dpb_count)
- return 1;
- /* Context is to return last frame */
- if (ctx->state == MFCINST_FINISHING &&
- ctx->dst_queue_cnt >= ctx->dpb_count)
- return 1;
- /* Context is to set buffers */
- if (ctx->src_queue_cnt >= 1 &&
- ctx->state == MFCINST_HEAD_PARSED &&
- ctx->capture_state == QUEUE_BUFS_MMAPED)
- return 1;
- /* Resolution change */
- if ((ctx->state == MFCINST_RES_CHANGE_INIT ||
- ctx->state == MFCINST_RES_CHANGE_FLUSH) &&
- ctx->dst_queue_cnt >= ctx->dpb_count)
- return 1;
- if (ctx->state == MFCINST_RES_CHANGE_END &&
- ctx->src_queue_cnt >= 1)
- return 1;
- mfc_debug(2, "ctx is not ready\n");
- return 0;
-}
-
-static struct s5p_mfc_codec_ops decoder_codec_ops = {
- .pre_seq_start = NULL,
- .post_seq_start = NULL,
- .pre_frame_start = NULL,
- .post_frame_start = NULL,
-};
-
-/* Query capabilities of the device */
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct s5p_mfc_dev *dev = video_drvdata(file);
-
- strncpy(cap->driver, dev->plat_dev->name, sizeof(cap->driver) - 1);
- strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1);
- cap->bus_info[0] = 0;
- cap->version = KERNEL_VERSION(1, 0, 0);
- /*
- * This is only a mem-to-mem video device. The capture and output
- * device capability flags are left only for backward compatibility
- * and are scheduled for removal.
- */
- cap->capabilities = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING |
- V4L2_CAP_VIDEO_CAPTURE_MPLANE |
- V4L2_CAP_VIDEO_OUTPUT_MPLANE;
- return 0;
-}
-
-/* Enumerate format */
-static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool mplane, bool out)
-{
- struct s5p_mfc_fmt *fmt;
- int i, j = 0;
-
- for (i = 0; i < ARRAY_SIZE(formats); ++i) {
- if (mplane && formats[i].num_planes == 1)
- continue;
- else if (!mplane && formats[i].num_planes > 1)
- continue;
- if (out && formats[i].type != MFC_FMT_DEC)
- continue;
- else if (!out && formats[i].type != MFC_FMT_RAW)
- continue;
-
- if (j == f->index)
- break;
- ++j;
- }
- if (i == ARRAY_SIZE(formats))
- return -EINVAL;
- fmt = &formats[i];
- strlcpy(f->description, fmt->name, sizeof(f->description));
- f->pixelformat = fmt->fourcc;
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv,
- struct v4l2_fmtdesc *f)
-{
- return vidioc_enum_fmt(f, false, false);
-}
-
-static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv,
- struct v4l2_fmtdesc *f)
-{
- return vidioc_enum_fmt(f, true, false);
-}
-
-static int vidioc_enum_fmt_vid_out(struct file *file, void *prov,
- struct v4l2_fmtdesc *f)
-{
- return vidioc_enum_fmt(f, false, true);
-}
-
-static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov,
- struct v4l2_fmtdesc *f)
-{
- return vidioc_enum_fmt(f, true, true);
-}
-
-/* Get format */
-static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
- struct v4l2_pix_format_mplane *pix_mp;
-
- mfc_debug_enter();
- pix_mp = &f->fmt.pix_mp;
- if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
- (ctx->state == MFCINST_GOT_INST || ctx->state ==
- MFCINST_RES_CHANGE_END)) {
- /* If the MFC is parsing the header,
- * so wait until it is finished */
- s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_wait_for_done_ctx(ctx, S5P_FIMV_R2H_CMD_SEQ_DONE_RET,
- 0);
- }
- if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
- ctx->state >= MFCINST_HEAD_PARSED &&
- ctx->state < MFCINST_ABORT) {
- /* This is run on CAPTURE (decode output) */
- /* Width and height are set to the dimensions
- of the movie, the buffer is bigger and
- further processing stages should crop to this
- rectangle. */
- pix_mp->width = ctx->buf_width;
- pix_mp->height = ctx->buf_height;
- pix_mp->field = V4L2_FIELD_NONE;
- pix_mp->num_planes = 2;
- /* Set pixelformat to the format in which MFC
- outputs the decoded frame */
- pix_mp->pixelformat = V4L2_PIX_FMT_NV12MT;
- pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
- pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
- pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
- pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- /* This is run on OUTPUT
- The buffer contains compressed image
- so width and height have no meaning */
- pix_mp->width = 0;
- pix_mp->height = 0;
- pix_mp->field = V4L2_FIELD_NONE;
- pix_mp->plane_fmt[0].bytesperline = ctx->dec_src_buf_size;
- pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size;
- pix_mp->pixelformat = ctx->src_fmt->fourcc;
- pix_mp->num_planes = ctx->src_fmt->num_planes;
- } else {
- mfc_err("Format could not be read\n");
- mfc_debug(2, "%s-- with error\n", __func__);
- return -EINVAL;
- }
- mfc_debug_leave();
- return 0;
-}
-
-/* Try format */
-static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
-{
- struct s5p_mfc_fmt *fmt;
-
- if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- mfc_err("This node supports decoding only\n");
- return -EINVAL;
- }
- fmt = find_format(f, MFC_FMT_DEC);
- if (!fmt) {
- mfc_err("Unsupported format\n");
- return -EINVAL;
- }
- if (fmt->type != MFC_FMT_DEC) {
- mfc_err("\n");
- return -EINVAL;
- }
- return 0;
-}
-
-/* Set format */
-static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
-{
- struct s5p_mfc_dev *dev = video_drvdata(file);
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
- int ret = 0;
- struct s5p_mfc_fmt *fmt;
- struct v4l2_pix_format_mplane *pix_mp;
-
- mfc_debug_enter();
- ret = vidioc_try_fmt(file, priv, f);
- pix_mp = &f->fmt.pix_mp;
- if (ret)
- return ret;
- if (ctx->vq_src.streaming || ctx->vq_dst.streaming) {
- v4l2_err(&dev->v4l2_dev, "%s queue busy\n", __func__);
- ret = -EBUSY;
- goto out;
- }
- fmt = find_format(f, MFC_FMT_DEC);
- if (!fmt || fmt->codec_mode == S5P_FIMV_CODEC_NONE) {
- mfc_err("Unknown codec\n");
- ret = -EINVAL;
- goto out;
- }
- if (fmt->type != MFC_FMT_DEC) {
- mfc_err("Wrong format selected, you should choose "
- "format for decoding\n");
- ret = -EINVAL;
- goto out;
- }
- ctx->src_fmt = fmt;
- ctx->codec_mode = fmt->codec_mode;
- mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
- pix_mp->height = 0;
- pix_mp->width = 0;
- if (pix_mp->plane_fmt[0].sizeimage)
- ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage;
- else
- pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size =
- DEF_CPB_SIZE;
- pix_mp->plane_fmt[0].bytesperline = 0;
- ctx->state = MFCINST_INIT;
-out:
- mfc_debug_leave();
- return ret;
-}
-
-/* Reqeust buffers */
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct s5p_mfc_dev *dev = video_drvdata(file);
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
- int ret = 0;
- unsigned long flags;
-
- if (reqbufs->memory != V4L2_MEMORY_MMAP) {
- mfc_err("Only V4L2_MEMORY_MAP is supported\n");
- return -EINVAL;
- }
- if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- /* Can only request buffers after an instance has been opened.*/
- if (ctx->state == MFCINST_INIT) {
- ctx->src_bufs_cnt = 0;
- if (reqbufs->count == 0) {
- mfc_debug(2, "Freeing buffers\n");
- s5p_mfc_clock_on();
- ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
- s5p_mfc_clock_off();
- return ret;
- }
- /* Decoding */
- if (ctx->output_state != QUEUE_FREE) {
- mfc_err("Bufs have already been requested\n");
- return -EINVAL;
- }
- s5p_mfc_clock_on();
- ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
- s5p_mfc_clock_off();
- if (ret) {
- mfc_err("vb2_reqbufs on output failed\n");
- return ret;
- }
- mfc_debug(2, "vb2_reqbufs: %d\n", ret);
- ctx->output_state = QUEUE_BUFS_REQUESTED;
- }
- } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- ctx->dst_bufs_cnt = 0;
- if (reqbufs->count == 0) {
- mfc_debug(2, "Freeing buffers\n");
- s5p_mfc_clock_on();
- ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
- s5p_mfc_clock_off();
- return ret;
- }
- if (ctx->capture_state != QUEUE_FREE) {
- mfc_err("Bufs have already been requested\n");
- return -EINVAL;
- }
- ctx->capture_state = QUEUE_BUFS_REQUESTED;
- s5p_mfc_clock_on();
- ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
- s5p_mfc_clock_off();
- if (ret) {
- mfc_err("vb2_reqbufs on capture failed\n");
- return ret;
- }
- if (reqbufs->count < ctx->dpb_count) {
- mfc_err("Not enough buffers allocated\n");
- reqbufs->count = 0;
- s5p_mfc_clock_on();
- ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
- s5p_mfc_clock_off();
- return -ENOMEM;
- }
- ctx->total_dpb_count = reqbufs->count;
- ret = s5p_mfc_alloc_codec_buffers(ctx);
- if (ret) {
- mfc_err("Failed to allocate decoding buffers\n");
- reqbufs->count = 0;
- s5p_mfc_clock_on();
- ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
- s5p_mfc_clock_off();
- return -ENOMEM;
- }
- if (ctx->dst_bufs_cnt == ctx->total_dpb_count) {
- ctx->capture_state = QUEUE_BUFS_MMAPED;
- } else {
- mfc_err("Not all buffers passed to buf_init\n");
- reqbufs->count = 0;
- s5p_mfc_clock_on();
- ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
- s5p_mfc_release_codec_buffers(ctx);
- s5p_mfc_clock_off();
- return -ENOMEM;
- }
- if (s5p_mfc_ctx_ready(ctx)) {
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- }
- s5p_mfc_try_run(dev);
- s5p_mfc_wait_for_done_ctx(ctx,
- S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET, 0);
- }
- return ret;
-}
-
-/* Query buffer */
-static int vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
- int ret;
- int i;
-
- if (buf->memory != V4L2_MEMORY_MMAP) {
- mfc_err("Only mmaped buffers can be used\n");
- return -EINVAL;
- }
- mfc_debug(2, "State: %d, buf->type: %d\n", ctx->state, buf->type);
- if (ctx->state == MFCINST_INIT &&
- buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- ret = vb2_querybuf(&ctx->vq_src, buf);
- } else if (ctx->state == MFCINST_RUNNING &&
- buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- ret = vb2_querybuf(&ctx->vq_dst, buf);
- for (i = 0; i < buf->length; i++)
- buf->m.planes[i].m.mem_offset += DST_QUEUE_OFF_BASE;
- } else {
- mfc_err("vidioc_querybuf called in an inappropriate state\n");
- ret = -EINVAL;
- }
- mfc_debug_leave();
- return ret;
-}
-
-/* Queue a buffer */
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
-
- if (ctx->state == MFCINST_ERROR) {
- mfc_err("Call on QBUF after unrecoverable error\n");
- return -EIO;
- }
- if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return vb2_qbuf(&ctx->vq_src, buf);
- else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return vb2_qbuf(&ctx->vq_dst, buf);
- return -EINVAL;
-}
-
-/* Dequeue a buffer */
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
-
- if (ctx->state == MFCINST_ERROR) {
- mfc_err("Call on DQBUF after unrecoverable error\n");
- return -EIO;
- }
- if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
- else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
- return -EINVAL;
-}
-
-/* Stream on */
-static int vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned long flags;
- int ret = -EINVAL;
-
- mfc_debug_enter();
- if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-
- if (ctx->state == MFCINST_INIT) {
- ctx->dst_bufs_cnt = 0;
- ctx->src_bufs_cnt = 0;
- ctx->capture_state = QUEUE_FREE;
- ctx->output_state = QUEUE_FREE;
- s5p_mfc_alloc_instance_buffer(ctx);
- s5p_mfc_alloc_dec_temp_buffers(ctx);
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_try_run(dev);
-
- if (s5p_mfc_wait_for_done_ctx(ctx,
- S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET, 0)) {
- /* Error or timeout */
- mfc_err("Error getting instance from hardware\n");
- s5p_mfc_release_instance_buffer(ctx);
- s5p_mfc_release_dec_desc_buffer(ctx);
- return -EIO;
- }
- mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
- }
- ret = vb2_streamon(&ctx->vq_src, type);
- }
- else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- ret = vb2_streamon(&ctx->vq_dst, type);
- mfc_debug_leave();
- return ret;
-}
-
-/* Stream off, which equals to a pause */
-static int vidioc_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
-
- if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return vb2_streamoff(&ctx->vq_src, type);
- else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return vb2_streamoff(&ctx->vq_dst, type);
- return -EINVAL;
-}
-
-/* Set controls - v4l2 control framework */
-static int s5p_mfc_dec_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl);
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY:
- ctx->display_delay = ctrl->val;
- break;
- case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE:
- ctx->display_delay_enable = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
- ctx->loop_filter_mpeg4 = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE:
- ctx->slice_interface = ctrl->val;
- break;
- default:
- mfc_err("Invalid control 0x%08x\n", ctrl->id);
- return -EINVAL;
- }
- return 0;
-}
-
-static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl);
- struct s5p_mfc_dev *dev = ctx->dev;
-
- switch (ctrl->id) {
- case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
- if (ctx->state >= MFCINST_HEAD_PARSED &&
- ctx->state < MFCINST_ABORT) {
- ctrl->val = ctx->dpb_count;
- break;
- } else if (ctx->state != MFCINST_INIT) {
- v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n");
- return -EINVAL;
- }
- /* Should wait for the header to be parsed */
- s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_wait_for_done_ctx(ctx,
- S5P_FIMV_R2H_CMD_SEQ_DONE_RET, 0);
- if (ctx->state >= MFCINST_HEAD_PARSED &&
- ctx->state < MFCINST_ABORT) {
- ctrl->val = ctx->dpb_count;
- } else {
- v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n");
- return -EINVAL;
- }
- break;
- }
- return 0;
-}
-
-
-static const struct v4l2_ctrl_ops s5p_mfc_dec_ctrl_ops = {
- .s_ctrl = s5p_mfc_dec_s_ctrl,
- .g_volatile_ctrl = s5p_mfc_dec_g_v_ctrl,
-};
-
-/* Get cropping information */
-static int vidioc_g_crop(struct file *file, void *priv,
- struct v4l2_crop *cr)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
- u32 left, right, top, bottom;
-
- if (ctx->state != MFCINST_HEAD_PARSED &&
- ctx->state != MFCINST_RUNNING && ctx->state != MFCINST_FINISHING
- && ctx->state != MFCINST_FINISHED) {
- mfc_err("Cannont set crop\n");
- return -EINVAL;
- }
- if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_H264) {
- left = s5p_mfc_read_shm(ctx, CROP_INFO_H);
- right = left >> S5P_FIMV_SHARED_CROP_RIGHT_SHIFT;
- left = left & S5P_FIMV_SHARED_CROP_LEFT_MASK;
- top = s5p_mfc_read_shm(ctx, CROP_INFO_V);
- bottom = top >> S5P_FIMV_SHARED_CROP_BOTTOM_SHIFT;
- top = top & S5P_FIMV_SHARED_CROP_TOP_MASK;
- cr->c.left = left;
- cr->c.top = top;
- cr->c.width = ctx->img_width - left - right;
- cr->c.height = ctx->img_height - top - bottom;
- mfc_debug(2, "Cropping info [h264]: l=%d t=%d "
- "w=%d h=%d (r=%d b=%d fw=%d fh=%d\n", left, top,
- cr->c.width, cr->c.height, right, bottom,
- ctx->buf_width, ctx->buf_height);
- } else {
- cr->c.left = 0;
- cr->c.top = 0;
- cr->c.width = ctx->img_width;
- cr->c.height = ctx->img_height;
- mfc_debug(2, "Cropping info: w=%d h=%d fw=%d "
- "fh=%d\n", cr->c.width, cr->c.height, ctx->buf_width,
- ctx->buf_height);
- }
- return 0;
-}
-
-/* v4l2_ioctl_ops */
-static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane,
- .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
- .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane,
- .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt,
- .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt,
- .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt,
- .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt,
- .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt,
- .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_g_crop = vidioc_g_crop,
-};
-
-static int s5p_mfc_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt, unsigned int *buf_count,
- unsigned int *plane_count, unsigned int psize[],
- void *allocators[])
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
-
- /* Video output for decoding (source)
- * this can be set after getting an instance */
- if (ctx->state == MFCINST_INIT &&
- vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- /* A single plane is required for input */
- *plane_count = 1;
- if (*buf_count < 1)
- *buf_count = 1;
- if (*buf_count > MFC_MAX_BUFFERS)
- *buf_count = MFC_MAX_BUFFERS;
- /* Video capture for decoding (destination)
- * this can be set after the header was parsed */
- } else if (ctx->state == MFCINST_HEAD_PARSED &&
- vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- /* Output plane count is 2 - one for Y and one for CbCr */
- *plane_count = 2;
- /* Setup buffer count */
- if (*buf_count < ctx->dpb_count)
- *buf_count = ctx->dpb_count;
- if (*buf_count > ctx->dpb_count + MFC_MAX_EXTRA_DPB)
- *buf_count = ctx->dpb_count + MFC_MAX_EXTRA_DPB;
- if (*buf_count > MFC_MAX_BUFFERS)
- *buf_count = MFC_MAX_BUFFERS;
- } else {
- mfc_err("State seems invalid. State = %d, vq->type = %d\n",
- ctx->state, vq->type);
- return -EINVAL;
- }
- mfc_debug(2, "Buffer count=%d, plane count=%d\n",
- *buf_count, *plane_count);
- if (ctx->state == MFCINST_HEAD_PARSED &&
- vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- psize[0] = ctx->luma_size;
- psize[1] = ctx->chroma_size;
- allocators[0] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
- allocators[1] = ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
- } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
- ctx->state == MFCINST_INIT) {
- psize[0] = ctx->dec_src_buf_size;
- allocators[0] = ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
- } else {
- mfc_err("This video node is dedicated to decoding. Decoding not initalised\n");
- return -EINVAL;
- }
- return 0;
-}
-
-static void s5p_mfc_unlock(struct vb2_queue *q)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
- struct s5p_mfc_dev *dev = ctx->dev;
-
- mutex_unlock(&dev->mfc_mutex);
-}
-
-static void s5p_mfc_lock(struct vb2_queue *q)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
- struct s5p_mfc_dev *dev = ctx->dev;
-
- mutex_lock(&dev->mfc_mutex);
-}
-
-static int s5p_mfc_buf_init(struct vb2_buffer *vb)
-{
- struct vb2_queue *vq = vb->vb2_queue;
- struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
- unsigned int i;
-
- if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- if (ctx->capture_state == QUEUE_BUFS_MMAPED)
- return 0;
- for (i = 0; i <= ctx->src_fmt->num_planes ; i++) {
- if (IS_ERR_OR_NULL(ERR_PTR(
- vb2_dma_contig_plane_dma_addr(vb, i)))) {
- mfc_err("Plane mem not allocated\n");
- return -EINVAL;
- }
- }
- if (vb2_plane_size(vb, 0) < ctx->luma_size ||
- vb2_plane_size(vb, 1) < ctx->chroma_size) {
- mfc_err("Plane buffer (CAPTURE) is too small\n");
- return -EINVAL;
- }
- i = vb->v4l2_buf.index;
- ctx->dst_bufs[i].b = vb;
- ctx->dst_bufs[i].cookie.raw.luma =
- vb2_dma_contig_plane_dma_addr(vb, 0);
- ctx->dst_bufs[i].cookie.raw.chroma =
- vb2_dma_contig_plane_dma_addr(vb, 1);
- ctx->dst_bufs_cnt++;
- } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- if (IS_ERR_OR_NULL(ERR_PTR(
- vb2_dma_contig_plane_dma_addr(vb, 0)))) {
- mfc_err("Plane memory not allocated\n");
- return -EINVAL;
- }
- if (vb2_plane_size(vb, 0) < ctx->dec_src_buf_size) {
- mfc_err("Plane buffer (OUTPUT) is too small\n");
- return -EINVAL;
- }
-
- i = vb->v4l2_buf.index;
- ctx->src_bufs[i].b = vb;
- ctx->src_bufs[i].cookie.stream =
- vb2_dma_contig_plane_dma_addr(vb, 0);
- ctx->src_bufs_cnt++;
- } else {
- mfc_err("s5p_mfc_buf_init: unknown queue type\n");
- return -EINVAL;
- }
- return 0;
-}
-
-static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned long flags;
-
- v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
- if (ctx->state == MFCINST_FINISHING ||
- ctx->state == MFCINST_FINISHED)
- ctx->state = MFCINST_RUNNING;
- /* If context is ready then dev = work->data;schedule it to run */
- if (s5p_mfc_ctx_ready(ctx)) {
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- }
- s5p_mfc_try_run(dev);
- return 0;
-}
-
-static int s5p_mfc_stop_streaming(struct vb2_queue *q)
-{
- unsigned long flags;
- struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
- struct s5p_mfc_dev *dev = ctx->dev;
- int aborted = 0;
-
- if ((ctx->state == MFCINST_FINISHING ||
- ctx->state == MFCINST_RUNNING) &&
- dev->curr_ctx == ctx->num && dev->hw_lock) {
- ctx->state = MFCINST_ABORT;
- s5p_mfc_wait_for_done_ctx(ctx,
- S5P_FIMV_R2H_CMD_FRAME_DONE_RET, 0);
- aborted = 1;
- }
- spin_lock_irqsave(&dev->irqlock, flags);
- if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
- INIT_LIST_HEAD(&ctx->dst_queue);
- ctx->dst_queue_cnt = 0;
- ctx->dpb_flush_flag = 1;
- ctx->dec_dst_flag = 0;
- }
- if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
- INIT_LIST_HEAD(&ctx->src_queue);
- ctx->src_queue_cnt = 0;
- }
- if (aborted)
- ctx->state = MFCINST_RUNNING;
- spin_unlock_irqrestore(&dev->irqlock, flags);
- return 0;
-}
-
-
-static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
-{
- struct vb2_queue *vq = vb->vb2_queue;
- struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned long flags;
- struct s5p_mfc_buf *mfc_buf;
-
- if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- mfc_buf = &ctx->src_bufs[vb->v4l2_buf.index];
- mfc_buf->used = 0;
- spin_lock_irqsave(&dev->irqlock, flags);
- list_add_tail(&mfc_buf->list, &ctx->src_queue);
- ctx->src_queue_cnt++;
- spin_unlock_irqrestore(&dev->irqlock, flags);
- } else if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- mfc_buf = &ctx->dst_bufs[vb->v4l2_buf.index];
- mfc_buf->used = 0;
- /* Mark destination as available for use by MFC */
- spin_lock_irqsave(&dev->irqlock, flags);
- set_bit(vb->v4l2_buf.index, &ctx->dec_dst_flag);
- list_add_tail(&mfc_buf->list, &ctx->dst_queue);
- ctx->dst_queue_cnt++;
- spin_unlock_irqrestore(&dev->irqlock, flags);
- } else {
- mfc_err("Unsupported buffer type (%d)\n", vq->type);
- }
- if (s5p_mfc_ctx_ready(ctx)) {
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- }
- s5p_mfc_try_run(dev);
-}
-
-static struct vb2_ops s5p_mfc_dec_qops = {
- .queue_setup = s5p_mfc_queue_setup,
- .wait_prepare = s5p_mfc_unlock,
- .wait_finish = s5p_mfc_lock,
- .buf_init = s5p_mfc_buf_init,
- .start_streaming = s5p_mfc_start_streaming,
- .stop_streaming = s5p_mfc_stop_streaming,
- .buf_queue = s5p_mfc_buf_queue,
-};
-
-struct s5p_mfc_codec_ops *get_dec_codec_ops(void)
-{
- return &decoder_codec_ops;
-}
-
-struct vb2_ops *get_dec_queue_ops(void)
-{
- return &s5p_mfc_dec_qops;
-}
-
-const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void)
-{
- return &s5p_mfc_dec_ioctl_ops;
-}
-
-#define IS_MFC51_PRIV(x) ((V4L2_CTRL_ID2CLASS(x) == V4L2_CTRL_CLASS_MPEG) \
- && V4L2_CTRL_DRIVER_PRIV(x))
-
-int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx)
-{
- struct v4l2_ctrl_config cfg;
- int i;
-
- v4l2_ctrl_handler_init(&ctx->ctrl_handler, NUM_CTRLS);
- if (ctx->ctrl_handler.error) {
- mfc_err("v4l2_ctrl_handler_init failed\n");
- return ctx->ctrl_handler.error;
- }
-
- for (i = 0; i < NUM_CTRLS; i++) {
- if (IS_MFC51_PRIV(controls[i].id)) {
- memset(&cfg, 0, sizeof(struct v4l2_ctrl_config));
- cfg.ops = &s5p_mfc_dec_ctrl_ops;
- cfg.id = controls[i].id;
- cfg.min = controls[i].minimum;
- cfg.max = controls[i].maximum;
- cfg.def = controls[i].default_value;
- cfg.name = controls[i].name;
- cfg.type = controls[i].type;
-
- cfg.step = controls[i].step;
- cfg.menu_skip_mask = 0;
-
- ctx->ctrls[i] = v4l2_ctrl_new_custom(&ctx->ctrl_handler,
- &cfg, NULL);
- } else {
- ctx->ctrls[i] = v4l2_ctrl_new_std(&ctx->ctrl_handler,
- &s5p_mfc_dec_ctrl_ops,
- controls[i].id, controls[i].minimum,
- controls[i].maximum, controls[i].step,
- controls[i].default_value);
- }
- if (ctx->ctrl_handler.error) {
- mfc_err("Adding control (%d) failed\n", i);
- return ctx->ctrl_handler.error;
- }
- if (controls[i].is_volatile && ctx->ctrls[i])
- ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE;
- }
- return 0;
-}
-
-void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx)
-{
- int i;
-
- v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- for (i = 0; i < NUM_CTRLS; i++)
- ctx->ctrls[i] = NULL;
-}
-
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.h b/drivers/media/video/s5p-mfc/s5p_mfc_dec.h
deleted file mode 100644
index fb8b215db0e..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_dec.h
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef S5P_MFC_DEC_H_
-#define S5P_MFC_DEC_H_
-
-struct s5p_mfc_codec_ops *get_dec_codec_ops(void);
-struct vb2_ops *get_dec_queue_ops(void);
-const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void);
-struct s5p_mfc_fmt *get_dec_def_fmt(bool src);
-int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx);
-void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx);
-
-#endif /* S5P_MFC_DEC_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
deleted file mode 100644
index aa1c244cf66..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
+++ /dev/null
@@ -1,1834 +0,0 @@
-/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * Jeongtae Park <jtp.park@samsung.com>
- * Kamil Debski <k.debski@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/version.h>
-#include <linux/videodev2.h>
-#include <linux/workqueue.h>
-#include <media/v4l2-ctrls.h>
-#include <media/videobuf2-core.h>
-#include "regs-mfc.h"
-#include "s5p_mfc_common.h"
-#include "s5p_mfc_debug.h"
-#include "s5p_mfc_enc.h"
-#include "s5p_mfc_intr.h"
-#include "s5p_mfc_opr.h"
-
-static struct s5p_mfc_fmt formats[] = {
- {
- .name = "4:2:0 2 Planes 64x32 Tiles",
- .fourcc = V4L2_PIX_FMT_NV12MT,
- .codec_mode = S5P_FIMV_CODEC_NONE,
- .type = MFC_FMT_RAW,
- .num_planes = 2,
- },
- {
- .name = "4:2:0 2 Planes",
- .fourcc = V4L2_PIX_FMT_NV12M,
- .codec_mode = S5P_FIMV_CODEC_NONE,
- .type = MFC_FMT_RAW,
- .num_planes = 2,
- },
- {
- .name = "H264 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_H264,
- .codec_mode = S5P_FIMV_CODEC_H264_ENC,
- .type = MFC_FMT_ENC,
- .num_planes = 1,
- },
- {
- .name = "MPEG4 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_MPEG4,
- .codec_mode = S5P_FIMV_CODEC_MPEG4_ENC,
- .type = MFC_FMT_ENC,
- .num_planes = 1,
- },
- {
- .name = "H263 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_H263,
- .codec_mode = S5P_FIMV_CODEC_H263_ENC,
- .type = MFC_FMT_ENC,
- .num_planes = 1,
- },
-};
-
-#define NUM_FORMATS ARRAY_SIZE(formats)
-static struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t)
-{
- unsigned int i;
-
- for (i = 0; i < NUM_FORMATS; i++) {
- if (formats[i].fourcc == f->fmt.pix_mp.pixelformat &&
- formats[i].type == t)
- return &formats[i];
- }
- return NULL;
-}
-
-static struct mfc_control controls[] = {
- {
- .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 0,
- .maximum = (1 << 16) - 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
- .type = V4L2_CTRL_TYPE_MENU,
- .minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
- .maximum = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES,
- .default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
- .menu_skip_mask = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 1,
- .maximum = (1 << 16) - 1,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 1900,
- .maximum = (1 << 30) - 1,
- .step = 1,
- .default_value = 1900,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 0,
- .maximum = (1 << 16) - 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Padding Control Enable",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Padding Color YUV Value",
- .minimum = 0,
- .maximum = (1 << 25) - 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_BITRATE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 1,
- .maximum = (1 << 30) - 1,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Rate Control Reaction Coeff.",
- .minimum = 1,
- .maximum = (1 << 16) - 1,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE,
- .type = V4L2_CTRL_TYPE_MENU,
- .name = "Force frame type",
- .minimum = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED,
- .maximum = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED,
- .default_value = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED,
- .menu_skip_mask = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_VBV_SIZE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 0,
- .maximum = (1 << 16) - 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 0,
- .maximum = (1 << 16) - 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_HEADER_MODE,
- .type = V4L2_CTRL_TYPE_MENU,
- .minimum = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
- .maximum = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
- .default_value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
- .menu_skip_mask = 0,
- },
- {
- .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE,
- .type = V4L2_CTRL_TYPE_MENU,
- .name = "Frame Skip Enable",
- .minimum = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED,
- .maximum = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT,
- .menu_skip_mask = 0,
- .default_value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED,
- },
- {
- .id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Fixed Target Bit Enable",
- .minimum = 0,
- .maximum = 1,
- .default_value = 0,
- .menu_skip_mask = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_B_FRAMES,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 0,
- .maximum = 2,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
- .type = V4L2_CTRL_TYPE_MENU,
- .minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
- .maximum = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
- .default_value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
- .menu_skip_mask = ~(
- (1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
- (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
- (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)
- ),
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
- .type = V4L2_CTRL_TYPE_MENU,
- .minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
- .maximum = V4L2_MPEG_VIDEO_H264_LEVEL_4_0,
- .default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
- .type = V4L2_CTRL_TYPE_MENU,
- .minimum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
- .maximum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5,
- .default_value = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
- .menu_skip_mask = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
- .type = V4L2_CTRL_TYPE_MENU,
- .minimum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,
- .maximum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY,
- .default_value = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,
- .menu_skip_mask = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = -6,
- .maximum = 6,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = -6,
- .maximum = 6,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
- .type = V4L2_CTRL_TYPE_MENU,
- .minimum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
- .maximum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
- .default_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
- .menu_skip_mask = 0,
- },
- {
- .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "The Number of Ref. Pic for P",
- .minimum = 1,
- .maximum = 2,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 0,
- .maximum = 51,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 0,
- .maximum = 51,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 0,
- .maximum = 51,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 0,
- .maximum = 51,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 0,
- .maximum = 51,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "H263 I-Frame QP value",
- .minimum = 1,
- .maximum = 31,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "H263 Minimum QP value",
- .minimum = 1,
- .maximum = 31,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "H263 Maximum QP value",
- .minimum = 1,
- .maximum = 31,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "H263 P frame QP value",
- .minimum = 1,
- .maximum = 31,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "H263 B frame QP value",
- .minimum = 1,
- .maximum = 31,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "MPEG4 I-Frame QP value",
- .minimum = 1,
- .maximum = 31,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "MPEG4 Minimum QP value",
- .minimum = 1,
- .maximum = 31,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "MPEG4 Maximum QP value",
- .minimum = 0,
- .maximum = 51,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "MPEG4 P frame QP value",
- .minimum = 1,
- .maximum = 31,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "MPEG4 B frame QP value",
- .minimum = 1,
- .maximum = 31,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "H264 Dark Reg Adaptive RC",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "H264 Smooth Reg Adaptive RC",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "H264 Static Reg Adaptive RC",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "H264 Activity Reg Adaptive RC",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,
- .type = V4L2_CTRL_TYPE_MENU,
- .minimum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED,
- .maximum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED,
- .default_value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED,
- .menu_skip_mask = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 0,
- .maximum = (1 << 16) - 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 0,
- .maximum = (1 << 16) - 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 0,
- .maximum = (1 << 16) - 1,
- .step = 1,
- .default_value = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
- .type = V4L2_CTRL_TYPE_MENU,
- .minimum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
- .maximum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE,
- .default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
- .menu_skip_mask = 0,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
-};
-
-#define NUM_CTRLS ARRAY_SIZE(controls)
-static const char * const *mfc51_get_menu(u32 id)
-{
- static const char * const mfc51_video_frame_skip[] = {
- "Disabled",
- "Level Limit",
- "VBV/CPB Limit",
- NULL,
- };
- static const char * const mfc51_video_force_frame[] = {
- "Disabled",
- "I Frame",
- "Not Coded",
- NULL,
- };
- switch (id) {
- case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE:
- return mfc51_video_frame_skip;
- case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
- return mfc51_video_force_frame;
- }
- return NULL;
-}
-
-static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx)
-{
- mfc_debug(2, "src=%d, dst=%d, state=%d\n",
- ctx->src_queue_cnt, ctx->dst_queue_cnt, ctx->state);
- /* context is ready to make header */
- if (ctx->state == MFCINST_GOT_INST && ctx->dst_queue_cnt >= 1)
- return 1;
- /* context is ready to encode a frame */
- if (ctx->state == MFCINST_RUNNING &&
- ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
- return 1;
- /* context is ready to encode remain frames */
- if (ctx->state == MFCINST_FINISHING &&
- ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
- return 1;
- mfc_debug(2, "ctx is not ready\n");
- return 0;
-}
-
-static void cleanup_ref_queue(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_buf *mb_entry;
- unsigned long mb_y_addr, mb_c_addr;
-
- /* move buffers in ref queue to src queue */
- while (!list_empty(&ctx->ref_queue)) {
- mb_entry = list_entry((&ctx->ref_queue)->next,
- struct s5p_mfc_buf, list);
- mb_y_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 0);
- mb_c_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 1);
- list_del(&mb_entry->list);
- ctx->ref_queue_cnt--;
- list_add_tail(&mb_entry->list, &ctx->src_queue);
- ctx->src_queue_cnt++;
- }
- mfc_debug(2, "enc src count: %d, enc ref count: %d\n",
- ctx->src_queue_cnt, ctx->ref_queue_cnt);
- INIT_LIST_HEAD(&ctx->ref_queue);
- ctx->ref_queue_cnt = 0;
-}
-
-static int enc_pre_seq_start(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_buf *dst_mb;
- unsigned long dst_addr;
- unsigned int dst_size;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->irqlock, flags);
- dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
- dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
- dst_size = vb2_plane_size(dst_mb->b, 0);
- s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
- spin_unlock_irqrestore(&dev->irqlock, flags);
- return 0;
-}
-
-static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
- struct s5p_mfc_buf *dst_mb;
- unsigned long flags;
-
- if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) {
- spin_lock_irqsave(&dev->irqlock, flags);
- dst_mb = list_entry(ctx->dst_queue.next,
- struct s5p_mfc_buf, list);
- list_del(&dst_mb->list);
- ctx->dst_queue_cnt--;
- vb2_set_plane_payload(dst_mb->b, 0,
- s5p_mfc_get_enc_strm_size());
- vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE);
- spin_unlock_irqrestore(&dev->irqlock, flags);
- }
- ctx->state = MFCINST_RUNNING;
- if (s5p_mfc_ctx_ready(ctx)) {
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- }
- s5p_mfc_try_run(dev);
- return 0;
-}
-
-static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_buf *dst_mb;
- struct s5p_mfc_buf *src_mb;
- unsigned long flags;
- unsigned long src_y_addr, src_c_addr, dst_addr;
- unsigned int dst_size;
-
- spin_lock_irqsave(&dev->irqlock, flags);
- src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
- src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0);
- src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1);
- s5p_mfc_set_enc_frame_buffer(ctx, src_y_addr, src_c_addr);
- spin_unlock_irqrestore(&dev->irqlock, flags);
-
- spin_lock_irqsave(&dev->irqlock, flags);
- dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
- dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
- dst_size = vb2_plane_size(dst_mb->b, 0);
- s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
- spin_unlock_irqrestore(&dev->irqlock, flags);
-
- return 0;
-}
-
-static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_buf *mb_entry;
- unsigned long enc_y_addr, enc_c_addr;
- unsigned long mb_y_addr, mb_c_addr;
- int slice_type;
- unsigned int strm_size;
- unsigned long flags;
-
- slice_type = s5p_mfc_get_enc_slice_type();
- strm_size = s5p_mfc_get_enc_strm_size();
- mfc_debug(2, "Encoded slice type: %d", slice_type);
- mfc_debug(2, "Encoded stream size: %d", strm_size);
- mfc_debug(2, "Display order: %d",
- mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
- spin_lock_irqsave(&dev->irqlock, flags);
- if (slice_type >= 0) {
- s5p_mfc_get_enc_frame_buffer(ctx, &enc_y_addr, &enc_c_addr);
- list_for_each_entry(mb_entry, &ctx->src_queue, list) {
- mb_y_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 0);
- mb_c_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 1);
- if ((enc_y_addr == mb_y_addr) &&
- (enc_c_addr == mb_c_addr)) {
- list_del(&mb_entry->list);
- ctx->src_queue_cnt--;
- vb2_buffer_done(mb_entry->b,
- VB2_BUF_STATE_DONE);
- break;
- }
- }
- list_for_each_entry(mb_entry, &ctx->ref_queue, list) {
- mb_y_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 0);
- mb_c_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 1);
- if ((enc_y_addr == mb_y_addr) &&
- (enc_c_addr == mb_c_addr)) {
- list_del(&mb_entry->list);
- ctx->ref_queue_cnt--;
- vb2_buffer_done(mb_entry->b,
- VB2_BUF_STATE_DONE);
- break;
- }
- }
- }
- if ((ctx->src_queue_cnt > 0) && (ctx->state == MFCINST_RUNNING)) {
- mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
- list);
- if (mb_entry->used) {
- list_del(&mb_entry->list);
- ctx->src_queue_cnt--;
- list_add_tail(&mb_entry->list, &ctx->ref_queue);
- ctx->ref_queue_cnt++;
- }
- mfc_debug(2, "enc src count: %d, enc ref count: %d\n",
- ctx->src_queue_cnt, ctx->ref_queue_cnt);
- }
- if (strm_size > 0) {
- /* at least one more dest. buffers exist always */
- mb_entry = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf,
- list);
- list_del(&mb_entry->list);
- ctx->dst_queue_cnt--;
- switch (slice_type) {
- case S5P_FIMV_ENC_SI_SLICE_TYPE_I:
- mb_entry->b->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
- break;
- case S5P_FIMV_ENC_SI_SLICE_TYPE_P:
- mb_entry->b->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
- break;
- case S5P_FIMV_ENC_SI_SLICE_TYPE_B:
- mb_entry->b->v4l2_buf.flags |= V4L2_BUF_FLAG_BFRAME;
- break;
- }
- vb2_set_plane_payload(mb_entry->b, 0, strm_size);
- vb2_buffer_done(mb_entry->b, VB2_BUF_STATE_DONE);
- }
- spin_unlock_irqrestore(&dev->irqlock, flags);
- if ((ctx->src_queue_cnt == 0) || (ctx->dst_queue_cnt == 0)) {
- spin_lock(&dev->condlock);
- clear_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock(&dev->condlock);
- }
- return 0;
-}
-
-static struct s5p_mfc_codec_ops encoder_codec_ops = {
- .pre_seq_start = enc_pre_seq_start,
- .post_seq_start = enc_post_seq_start,
- .pre_frame_start = enc_pre_frame_start,
- .post_frame_start = enc_post_frame_start,
-};
-
-/* Query capabilities of the device */
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct s5p_mfc_dev *dev = video_drvdata(file);
-
- strncpy(cap->driver, dev->plat_dev->name, sizeof(cap->driver) - 1);
- strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1);
- cap->bus_info[0] = 0;
- cap->version = KERNEL_VERSION(1, 0, 0);
- /*
- * This is only a mem-to-mem video device. The capture and output
- * device capability flags are left only for backward compatibility
- * and are scheduled for removal.
- */
- cap->capabilities = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING |
- V4L2_CAP_VIDEO_CAPTURE_MPLANE |
- V4L2_CAP_VIDEO_OUTPUT_MPLANE;
- return 0;
-}
-
-static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool mplane, bool out)
-{
- struct s5p_mfc_fmt *fmt;
- int i, j = 0;
-
- for (i = 0; i < ARRAY_SIZE(formats); ++i) {
- if (mplane && formats[i].num_planes == 1)
- continue;
- else if (!mplane && formats[i].num_planes > 1)
- continue;
- if (out && formats[i].type != MFC_FMT_RAW)
- continue;
- else if (!out && formats[i].type != MFC_FMT_ENC)
- continue;
- if (j == f->index) {
- fmt = &formats[i];
- strlcpy(f->description, fmt->name,
- sizeof(f->description));
- f->pixelformat = fmt->fourcc;
- return 0;
- }
- ++j;
- }
- return -EINVAL;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv,
- struct v4l2_fmtdesc *f)
-{
- return vidioc_enum_fmt(f, false, false);
-}
-
-static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv,
- struct v4l2_fmtdesc *f)
-{
- return vidioc_enum_fmt(f, true, false);
-}
-
-static int vidioc_enum_fmt_vid_out(struct file *file, void *prov,
- struct v4l2_fmtdesc *f)
-{
- return vidioc_enum_fmt(f, false, true);
-}
-
-static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov,
- struct v4l2_fmtdesc *f)
-{
- return vidioc_enum_fmt(f, true, true);
-}
-
-static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
- struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
-
- mfc_debug(2, "f->type = %d ctx->state = %d\n", f->type, ctx->state);
- if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- /* This is run on output (encoder dest) */
- pix_fmt_mp->width = 0;
- pix_fmt_mp->height = 0;
- pix_fmt_mp->field = V4L2_FIELD_NONE;
- pix_fmt_mp->pixelformat = ctx->dst_fmt->fourcc;
- pix_fmt_mp->num_planes = ctx->dst_fmt->num_planes;
-
- pix_fmt_mp->plane_fmt[0].bytesperline = ctx->enc_dst_buf_size;
- pix_fmt_mp->plane_fmt[0].sizeimage = ctx->enc_dst_buf_size;
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- /* This is run on capture (encoder src) */
- pix_fmt_mp->width = ctx->img_width;
- pix_fmt_mp->height = ctx->img_height;
-
- pix_fmt_mp->field = V4L2_FIELD_NONE;
- pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
- pix_fmt_mp->num_planes = ctx->src_fmt->num_planes;
-
- pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
- pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
- pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
- pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
- } else {
- mfc_err("invalid buf type\n");
- return -EINVAL;
- }
- return 0;
-}
-
-static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
-{
- struct s5p_mfc_fmt *fmt;
- struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- fmt = find_format(f, MFC_FMT_ENC);
- if (!fmt) {
- mfc_err("failed to try output format\n");
- return -EINVAL;
- }
-
- if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) {
- mfc_err("must be set encoding output size\n");
- return -EINVAL;
- }
-
- pix_fmt_mp->plane_fmt[0].bytesperline =
- pix_fmt_mp->plane_fmt[0].sizeimage;
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- fmt = find_format(f, MFC_FMT_RAW);
- if (!fmt) {
- mfc_err("failed to try output format\n");
- return -EINVAL;
- }
-
- if (fmt->num_planes != pix_fmt_mp->num_planes) {
- mfc_err("failed to try output format\n");
- return -EINVAL;
- }
- v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1,
- &pix_fmt_mp->height, 4, 1080, 1, 0);
- } else {
- mfc_err("invalid buf type\n");
- return -EINVAL;
- }
- return 0;
-}
-
-static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
-{
- struct s5p_mfc_dev *dev = video_drvdata(file);
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
- struct s5p_mfc_fmt *fmt;
- struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
- unsigned long flags;
- int ret = 0;
-
- ret = vidioc_try_fmt(file, priv, f);
- if (ret)
- return ret;
- if (ctx->vq_src.streaming || ctx->vq_dst.streaming) {
- v4l2_err(&dev->v4l2_dev, "%s queue busy\n", __func__);
- ret = -EBUSY;
- goto out;
- }
- if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- fmt = find_format(f, MFC_FMT_ENC);
- if (!fmt) {
- mfc_err("failed to set capture format\n");
- return -EINVAL;
- }
- ctx->state = MFCINST_INIT;
- ctx->dst_fmt = fmt;
- ctx->codec_mode = ctx->dst_fmt->codec_mode;
- ctx->enc_dst_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage;
- pix_fmt_mp->plane_fmt[0].bytesperline = 0;
- ctx->dst_bufs_cnt = 0;
- ctx->capture_state = QUEUE_FREE;
- s5p_mfc_alloc_instance_buffer(ctx);
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_try_run(dev);
- if (s5p_mfc_wait_for_done_ctx(ctx, \
- S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET, 1)) {
- /* Error or timeout */
- mfc_err("Error getting instance from hardware\n");
- s5p_mfc_release_instance_buffer(ctx);
- ret = -EIO;
- goto out;
- }
- mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- fmt = find_format(f, MFC_FMT_RAW);
- if (!fmt) {
- mfc_err("failed to set output format\n");
- return -EINVAL;
- }
- if (fmt->num_planes != pix_fmt_mp->num_planes) {
- mfc_err("failed to set output format\n");
- ret = -EINVAL;
- goto out;
- }
- ctx->src_fmt = fmt;
- ctx->img_width = pix_fmt_mp->width;
- ctx->img_height = pix_fmt_mp->height;
- mfc_debug(2, "codec number: %d\n", ctx->src_fmt->codec_mode);
- mfc_debug(2, "fmt - w: %d, h: %d, ctx - w: %d, h: %d\n",
- pix_fmt_mp->width, pix_fmt_mp->height,
- ctx->img_width, ctx->img_height);
- if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) {
- ctx->buf_width = ALIGN(ctx->img_width,
- S5P_FIMV_NV12M_HALIGN);
- ctx->luma_size = ALIGN(ctx->img_width,
- S5P_FIMV_NV12M_HALIGN) * ALIGN(ctx->img_height,
- S5P_FIMV_NV12M_LVALIGN);
- ctx->chroma_size = ALIGN(ctx->img_width,
- S5P_FIMV_NV12M_HALIGN) * ALIGN((ctx->img_height
- >> 1), S5P_FIMV_NV12M_CVALIGN);
-
- ctx->luma_size = ALIGN(ctx->luma_size,
- S5P_FIMV_NV12M_SALIGN);
- ctx->chroma_size = ALIGN(ctx->chroma_size,
- S5P_FIMV_NV12M_SALIGN);
-
- pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
- pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
- pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
- pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
-
- } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT) {
- ctx->buf_width = ALIGN(ctx->img_width,
- S5P_FIMV_NV12MT_HALIGN);
- ctx->luma_size = ALIGN(ctx->img_width,
- S5P_FIMV_NV12MT_HALIGN) * ALIGN(ctx->img_height,
- S5P_FIMV_NV12MT_VALIGN);
- ctx->chroma_size = ALIGN(ctx->img_width,
- S5P_FIMV_NV12MT_HALIGN) * ALIGN((ctx->img_height
- >> 1), S5P_FIMV_NV12MT_VALIGN);
- ctx->luma_size = ALIGN(ctx->luma_size,
- S5P_FIMV_NV12MT_SALIGN);
- ctx->chroma_size = ALIGN(ctx->chroma_size,
- S5P_FIMV_NV12MT_SALIGN);
-
- pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
- pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
- pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
- pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
- }
- ctx->src_bufs_cnt = 0;
- ctx->output_state = QUEUE_FREE;
- } else {
- mfc_err("invalid buf type\n");
- return -EINVAL;
- }
-out:
- mfc_debug_leave();
- return ret;
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
- int ret = 0;
-
- /* if memory is not mmp or userptr return error */
- if ((reqbufs->memory != V4L2_MEMORY_MMAP) &&
- (reqbufs->memory != V4L2_MEMORY_USERPTR))
- return -EINVAL;
- if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- if (ctx->capture_state != QUEUE_FREE) {
- mfc_err("invalid capture state: %d\n",
- ctx->capture_state);
- return -EINVAL;
- }
- ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
- if (ret != 0) {
- mfc_err("error in vb2_reqbufs() for E(D)\n");
- return ret;
- }
- ctx->capture_state = QUEUE_BUFS_REQUESTED;
- ret = s5p_mfc_alloc_codec_buffers(ctx);
- if (ret) {
- mfc_err("Failed to allocate encoding buffers\n");
- reqbufs->count = 0;
- ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
- return -ENOMEM;
- }
- } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- if (ctx->output_state != QUEUE_FREE) {
- mfc_err("invalid output state: %d\n",
- ctx->output_state);
- return -EINVAL;
- }
- ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
- if (ret != 0) {
- mfc_err("error in vb2_reqbufs() for E(S)\n");
- return ret;
- }
- ctx->output_state = QUEUE_BUFS_REQUESTED;
- } else {
- mfc_err("invalid buf type\n");
- return -EINVAL;
- }
- return ret;
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
- int ret = 0;
-
- /* if memory is not mmp or userptr return error */
- if ((buf->memory != V4L2_MEMORY_MMAP) &&
- (buf->memory != V4L2_MEMORY_USERPTR))
- return -EINVAL;
- if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- if (ctx->state != MFCINST_GOT_INST) {
- mfc_err("invalid context state: %d\n", ctx->state);
- return -EINVAL;
- }
- ret = vb2_querybuf(&ctx->vq_dst, buf);
- if (ret != 0) {
- mfc_err("error in vb2_querybuf() for E(D)\n");
- return ret;
- }
- buf->m.planes[0].m.mem_offset += DST_QUEUE_OFF_BASE;
- } else if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- ret = vb2_querybuf(&ctx->vq_src, buf);
- if (ret != 0) {
- mfc_err("error in vb2_querybuf() for E(S)\n");
- return ret;
- }
- } else {
- mfc_err("invalid buf type\n");
- return -EINVAL;
- }
- return ret;
-}
-
-/* Queue a buffer */
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
-
- if (ctx->state == MFCINST_ERROR) {
- mfc_err("Call on QBUF after unrecoverable error\n");
- return -EIO;
- }
- if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return vb2_qbuf(&ctx->vq_src, buf);
- else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return vb2_qbuf(&ctx->vq_dst, buf);
- return -EINVAL;
-}
-
-/* Dequeue a buffer */
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
-
- if (ctx->state == MFCINST_ERROR) {
- mfc_err("Call on DQBUF after unrecoverable error\n");
- return -EIO;
- }
- if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
- else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
- return -EINVAL;
-}
-
-/* Stream on */
-static int vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
-
- if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return vb2_streamon(&ctx->vq_src, type);
- else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return vb2_streamon(&ctx->vq_dst, type);
- return -EINVAL;
-}
-
-/* Stream off, which equals to a pause */
-static int vidioc_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
-
- if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return vb2_streamoff(&ctx->vq_src, type);
- else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return vb2_streamoff(&ctx->vq_dst, type);
- return -EINVAL;
-}
-
-static inline int h264_level(enum v4l2_mpeg_video_h264_level lvl)
-{
- static unsigned int t[V4L2_MPEG_VIDEO_H264_LEVEL_4_0 + 1] = {
- /* V4L2_MPEG_VIDEO_H264_LEVEL_1_0 */ 10,
- /* V4L2_MPEG_VIDEO_H264_LEVEL_1B */ 9,
- /* V4L2_MPEG_VIDEO_H264_LEVEL_1_1 */ 11,
- /* V4L2_MPEG_VIDEO_H264_LEVEL_1_2 */ 12,
- /* V4L2_MPEG_VIDEO_H264_LEVEL_1_3 */ 13,
- /* V4L2_MPEG_VIDEO_H264_LEVEL_2_0 */ 20,
- /* V4L2_MPEG_VIDEO_H264_LEVEL_2_1 */ 21,
- /* V4L2_MPEG_VIDEO_H264_LEVEL_2_2 */ 22,
- /* V4L2_MPEG_VIDEO_H264_LEVEL_3_0 */ 30,
- /* V4L2_MPEG_VIDEO_H264_LEVEL_3_1 */ 31,
- /* V4L2_MPEG_VIDEO_H264_LEVEL_3_2 */ 32,
- /* V4L2_MPEG_VIDEO_H264_LEVEL_4_0 */ 40,
- };
- return t[lvl];
-}
-
-static inline int mpeg4_level(enum v4l2_mpeg_video_mpeg4_level lvl)
-{
- static unsigned int t[V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 + 1] = {
- /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 */ 0,
- /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B */ 9,
- /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 */ 1,
- /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 */ 2,
- /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 */ 3,
- /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B */ 7,
- /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 */ 4,
- /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 */ 5,
- };
- return t[lvl];
-}
-
-static inline int vui_sar_idc(enum v4l2_mpeg_video_h264_vui_sar_idc sar)
-{
- static unsigned int t[V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED + 1] = {
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED */ 0,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1 */ 1,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11 */ 2,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11 */ 3,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11 */ 4,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33 */ 5,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11 */ 6,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11 */ 7,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11 */ 8,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33 */ 9,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11 */ 10,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11 */ 11,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33 */ 12,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99 */ 13,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3 */ 14,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2 */ 15,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1 */ 16,
- /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED */ 255,
- };
- return t[sar];
-}
-
-static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl);
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- p->gop_size = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
- p->slice_mode = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
- p->slice_mb = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
- p->slice_bit = ctrl->val * 8;
- break;
- case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
- p->intra_refresh_mb = ctrl->val;
- break;
- case V4L2_CID_MPEG_MFC51_VIDEO_PADDING:
- p->pad = ctrl->val;
- break;
- case V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV:
- p->pad_luma = (ctrl->val >> 16) & 0xff;
- p->pad_cb = (ctrl->val >> 8) & 0xff;
- p->pad_cr = (ctrl->val >> 0) & 0xff;
- break;
- case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
- p->rc_frame = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- p->rc_bitrate = ctrl->val;
- break;
- case V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF:
- p->rc_reaction_coeff = ctrl->val;
- break;
- case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
- ctx->force_frame_type = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_VBV_SIZE:
- p->vbv_size = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
- p->codec.h264.cpb_size = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
- p->seq_hdr_mode = ctrl->val;
- break;
- case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE:
- p->frame_skip_mode = ctrl->val;
- break;
- case V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT:
- p->fixed_target_bit = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- p->num_b_frame = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
- switch (ctrl->val) {
- case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
- p->codec.h264.profile =
- S5P_FIMV_ENC_PROFILE_H264_MAIN;
- break;
- case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
- p->codec.h264.profile =
- S5P_FIMV_ENC_PROFILE_H264_HIGH;
- break;
- case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
- p->codec.h264.profile =
- S5P_FIMV_ENC_PROFILE_H264_BASELINE;
- break;
- default:
- ret = -EINVAL;
- }
- break;
- case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
- p->codec.h264.level_v4l2 = ctrl->val;
- p->codec.h264.level = h264_level(ctrl->val);
- if (p->codec.h264.level < 0) {
- mfc_err("Level number is wrong\n");
- ret = p->codec.h264.level;
- }
- break;
- case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
- p->codec.mpeg4.level_v4l2 = ctrl->val;
- p->codec.mpeg4.level = mpeg4_level(ctrl->val);
- if (p->codec.mpeg4.level < 0) {
- mfc_err("Level number is wrong\n");
- ret = p->codec.mpeg4.level;
- }
- break;
- case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
- p->codec.h264.loop_filter_mode = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
- p->codec.h264.loop_filter_alpha = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
- p->codec.h264.loop_filter_beta = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
- p->codec.h264.entropy_mode = ctrl->val;
- break;
- case V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P:
- p->codec.h264.num_ref_pic_4p = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
- p->codec.h264._8x8_transform = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
- p->codec.h264.rc_mb = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
- p->codec.h264.rc_frame_qp = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
- p->codec.h264.rc_min_qp = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
- p->codec.h264.rc_max_qp = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
- p->codec.h264.rc_p_frame_qp = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
- p->codec.h264.rc_b_frame_qp = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
- case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
- p->codec.mpeg4.rc_frame_qp = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
- case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
- p->codec.mpeg4.rc_min_qp = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
- case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
- p->codec.mpeg4.rc_max_qp = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
- case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
- p->codec.mpeg4.rc_p_frame_qp = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
- case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
- p->codec.mpeg4.rc_b_frame_qp = ctrl->val;
- break;
- case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK:
- p->codec.h264.rc_mb_dark = ctrl->val;
- break;
- case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH:
- p->codec.h264.rc_mb_smooth = ctrl->val;
- break;
- case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC:
- p->codec.h264.rc_mb_static = ctrl->val;
- break;
- case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY:
- p->codec.h264.rc_mb_activity = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
- p->codec.h264.vui_sar = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
- p->codec.h264.vui_sar_idc = vui_sar_idc(ctrl->val);
- break;
- case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:
- p->codec.h264.vui_ext_sar_width = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:
- p->codec.h264.vui_ext_sar_height = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
- p->codec.h264.open_gop = !ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
- p->codec.h264.open_gop_size = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
- switch (ctrl->val) {
- case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
- p->codec.mpeg4.profile =
- S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE;
- break;
- case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
- p->codec.mpeg4.profile =
- S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE;
- break;
- default:
- ret = -EINVAL;
- }
- break;
- case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
- p->codec.mpeg4.quarter_pixel = ctrl->val;
- break;
- default:
- v4l2_err(&dev->v4l2_dev, "Invalid control, id=%d, val=%d\n",
- ctrl->id, ctrl->val);
- ret = -EINVAL;
- }
- return ret;
-}
-
-static const struct v4l2_ctrl_ops s5p_mfc_enc_ctrl_ops = {
- .s_ctrl = s5p_mfc_enc_s_ctrl,
-};
-
-static int vidioc_s_parm(struct file *file, void *priv,
- struct v4l2_streamparm *a)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
-
- if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- ctx->enc_params.rc_framerate_num =
- a->parm.output.timeperframe.denominator;
- ctx->enc_params.rc_framerate_denom =
- a->parm.output.timeperframe.numerator;
- } else {
- mfc_err("Setting FPS is only possible for the output queue\n");
- return -EINVAL;
- }
- return 0;
-}
-
-static int vidioc_g_parm(struct file *file, void *priv,
- struct v4l2_streamparm *a)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
-
- if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- a->parm.output.timeperframe.denominator =
- ctx->enc_params.rc_framerate_num;
- a->parm.output.timeperframe.numerator =
- ctx->enc_params.rc_framerate_denom;
- } else {
- mfc_err("Setting FPS is only possible for the output queue\n");
- return -EINVAL;
- }
- return 0;
-}
-
-static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane,
- .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
- .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane,
- .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt,
- .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt,
- .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt,
- .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt,
- .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt,
- .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_s_parm = vidioc_s_parm,
- .vidioc_g_parm = vidioc_g_parm,
-};
-
-static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb)
-{
- int i;
-
- if (!fmt)
- return -EINVAL;
- if (fmt->num_planes != vb->num_planes) {
- mfc_err("invalid plane number for the format\n");
- return -EINVAL;
- }
- for (i = 0; i < fmt->num_planes; i++) {
- if (!vb2_dma_contig_plane_dma_addr(vb, i)) {
- mfc_err("failed to get plane cookie\n");
- return -EINVAL;
- }
- mfc_debug(2, "index: %d, plane[%d] cookie: 0x%08zx",
- vb->v4l2_buf.index, i,
- vb2_dma_contig_plane_dma_addr(vb, i));
- }
- return 0;
-}
-
-static int s5p_mfc_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
- unsigned int *buf_count, unsigned int *plane_count,
- unsigned int psize[], void *allocators[])
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
-
- if (ctx->state != MFCINST_GOT_INST) {
- mfc_err("inavlid state: %d\n", ctx->state);
- return -EINVAL;
- }
- if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- if (ctx->dst_fmt)
- *plane_count = ctx->dst_fmt->num_planes;
- else
- *plane_count = MFC_ENC_CAP_PLANE_COUNT;
- if (*buf_count < 1)
- *buf_count = 1;
- if (*buf_count > MFC_MAX_BUFFERS)
- *buf_count = MFC_MAX_BUFFERS;
- psize[0] = ctx->enc_dst_buf_size;
- allocators[0] = ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
- } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- if (ctx->src_fmt)
- *plane_count = ctx->src_fmt->num_planes;
- else
- *plane_count = MFC_ENC_OUT_PLANE_COUNT;
-
- if (*buf_count < 1)
- *buf_count = 1;
- if (*buf_count > MFC_MAX_BUFFERS)
- *buf_count = MFC_MAX_BUFFERS;
- psize[0] = ctx->luma_size;
- psize[1] = ctx->chroma_size;
- allocators[0] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
- allocators[1] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
- } else {
- mfc_err("inavlid queue type: %d\n", vq->type);
- return -EINVAL;
- }
- return 0;
-}
-
-static void s5p_mfc_unlock(struct vb2_queue *q)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
- struct s5p_mfc_dev *dev = ctx->dev;
-
- mutex_unlock(&dev->mfc_mutex);
-}
-
-static void s5p_mfc_lock(struct vb2_queue *q)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
- struct s5p_mfc_dev *dev = ctx->dev;
-
- mutex_lock(&dev->mfc_mutex);
-}
-
-static int s5p_mfc_buf_init(struct vb2_buffer *vb)
-{
- struct vb2_queue *vq = vb->vb2_queue;
- struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
- unsigned int i;
- int ret;
-
- if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- ret = check_vb_with_fmt(ctx->dst_fmt, vb);
- if (ret < 0)
- return ret;
- i = vb->v4l2_buf.index;
- ctx->dst_bufs[i].b = vb;
- ctx->dst_bufs[i].cookie.stream =
- vb2_dma_contig_plane_dma_addr(vb, 0);
- ctx->dst_bufs_cnt++;
- } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- ret = check_vb_with_fmt(ctx->src_fmt, vb);
- if (ret < 0)
- return ret;
- i = vb->v4l2_buf.index;
- ctx->src_bufs[i].b = vb;
- ctx->src_bufs[i].cookie.raw.luma =
- vb2_dma_contig_plane_dma_addr(vb, 0);
- ctx->src_bufs[i].cookie.raw.chroma =
- vb2_dma_contig_plane_dma_addr(vb, 1);
- ctx->src_bufs_cnt++;
- } else {
- mfc_err("inavlid queue type: %d\n", vq->type);
- return -EINVAL;
- }
- return 0;
-}
-
-static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
-{
- struct vb2_queue *vq = vb->vb2_queue;
- struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
- int ret;
-
- if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- ret = check_vb_with_fmt(ctx->dst_fmt, vb);
- if (ret < 0)
- return ret;
- mfc_debug(2, "plane size: %ld, dst size: %d\n",
- vb2_plane_size(vb, 0), ctx->enc_dst_buf_size);
- if (vb2_plane_size(vb, 0) < ctx->enc_dst_buf_size) {
- mfc_err("plane size is too small for capture\n");
- return -EINVAL;
- }
- } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- ret = check_vb_with_fmt(ctx->src_fmt, vb);
- if (ret < 0)
- return ret;
- mfc_debug(2, "plane size: %ld, luma size: %d\n",
- vb2_plane_size(vb, 0), ctx->luma_size);
- mfc_debug(2, "plane size: %ld, chroma size: %d\n",
- vb2_plane_size(vb, 1), ctx->chroma_size);
- if (vb2_plane_size(vb, 0) < ctx->luma_size ||
- vb2_plane_size(vb, 1) < ctx->chroma_size) {
- mfc_err("plane size is too small for output\n");
- return -EINVAL;
- }
- } else {
- mfc_err("inavlid queue type: %d\n", vq->type);
- return -EINVAL;
- }
- return 0;
-}
-
-static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned long flags;
-
- v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
- /* If context is ready then dev = work->data;schedule it to run */
- if (s5p_mfc_ctx_ready(ctx)) {
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- }
- s5p_mfc_try_run(dev);
- return 0;
-}
-
-static int s5p_mfc_stop_streaming(struct vb2_queue *q)
-{
- unsigned long flags;
- struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
- struct s5p_mfc_dev *dev = ctx->dev;
-
- if ((ctx->state == MFCINST_FINISHING ||
- ctx->state == MFCINST_RUNNING) &&
- dev->curr_ctx == ctx->num && dev->hw_lock) {
- ctx->state = MFCINST_ABORT;
- s5p_mfc_wait_for_done_ctx(ctx, S5P_FIMV_R2H_CMD_FRAME_DONE_RET,
- 0);
- }
- ctx->state = MFCINST_FINISHED;
- spin_lock_irqsave(&dev->irqlock, flags);
- if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
- INIT_LIST_HEAD(&ctx->dst_queue);
- ctx->dst_queue_cnt = 0;
- }
- if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- cleanup_ref_queue(ctx);
- s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
- INIT_LIST_HEAD(&ctx->src_queue);
- ctx->src_queue_cnt = 0;
- }
- spin_unlock_irqrestore(&dev->irqlock, flags);
- return 0;
-}
-
-static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
-{
- struct vb2_queue *vq = vb->vb2_queue;
- struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned long flags;
- struct s5p_mfc_buf *mfc_buf;
-
- if (ctx->state == MFCINST_ERROR) {
- vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
- cleanup_ref_queue(ctx);
- return;
- }
- if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- mfc_buf = &ctx->dst_bufs[vb->v4l2_buf.index];
- mfc_buf->used = 0;
- /* Mark destination as available for use by MFC */
- spin_lock_irqsave(&dev->irqlock, flags);
- list_add_tail(&mfc_buf->list, &ctx->dst_queue);
- ctx->dst_queue_cnt++;
- spin_unlock_irqrestore(&dev->irqlock, flags);
- } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- mfc_buf = &ctx->src_bufs[vb->v4l2_buf.index];
- mfc_buf->used = 0;
- spin_lock_irqsave(&dev->irqlock, flags);
- if (vb->v4l2_planes[0].bytesused == 0) {
- mfc_debug(1, "change state to FINISHING\n");
- ctx->state = MFCINST_FINISHING;
- vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
- cleanup_ref_queue(ctx);
- } else {
- list_add_tail(&mfc_buf->list, &ctx->src_queue);
- ctx->src_queue_cnt++;
- }
- spin_unlock_irqrestore(&dev->irqlock, flags);
- } else {
- mfc_err("unsupported buffer type (%d)\n", vq->type);
- }
- if (s5p_mfc_ctx_ready(ctx)) {
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- }
- s5p_mfc_try_run(dev);
-}
-
-static struct vb2_ops s5p_mfc_enc_qops = {
- .queue_setup = s5p_mfc_queue_setup,
- .wait_prepare = s5p_mfc_unlock,
- .wait_finish = s5p_mfc_lock,
- .buf_init = s5p_mfc_buf_init,
- .buf_prepare = s5p_mfc_buf_prepare,
- .start_streaming = s5p_mfc_start_streaming,
- .stop_streaming = s5p_mfc_stop_streaming,
- .buf_queue = s5p_mfc_buf_queue,
-};
-
-struct s5p_mfc_codec_ops *get_enc_codec_ops(void)
-{
- return &encoder_codec_ops;
-}
-
-struct vb2_ops *get_enc_queue_ops(void)
-{
- return &s5p_mfc_enc_qops;
-}
-
-const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void)
-{
- return &s5p_mfc_enc_ioctl_ops;
-}
-
-#define IS_MFC51_PRIV(x) ((V4L2_CTRL_ID2CLASS(x) == V4L2_CTRL_CLASS_MPEG) \
- && V4L2_CTRL_DRIVER_PRIV(x))
-
-int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx)
-{
- struct v4l2_ctrl_config cfg;
- int i;
-
- v4l2_ctrl_handler_init(&ctx->ctrl_handler, NUM_CTRLS);
- if (ctx->ctrl_handler.error) {
- mfc_err("v4l2_ctrl_handler_init failed\n");
- return ctx->ctrl_handler.error;
- }
- for (i = 0; i < NUM_CTRLS; i++) {
- if (IS_MFC51_PRIV(controls[i].id)) {
- memset(&cfg, 0, sizeof(struct v4l2_ctrl_config));
- cfg.ops = &s5p_mfc_enc_ctrl_ops;
- cfg.id = controls[i].id;
- cfg.min = controls[i].minimum;
- cfg.max = controls[i].maximum;
- cfg.def = controls[i].default_value;
- cfg.name = controls[i].name;
- cfg.type = controls[i].type;
- cfg.flags = 0;
-
- if (cfg.type == V4L2_CTRL_TYPE_MENU) {
- cfg.step = 0;
- cfg.menu_skip_mask = cfg.menu_skip_mask;
- cfg.qmenu = mfc51_get_menu(cfg.id);
- } else {
- cfg.step = controls[i].step;
- cfg.menu_skip_mask = 0;
- }
- ctx->ctrls[i] = v4l2_ctrl_new_custom(&ctx->ctrl_handler,
- &cfg, NULL);
- } else {
- if (controls[i].type == V4L2_CTRL_TYPE_MENU) {
- ctx->ctrls[i] = v4l2_ctrl_new_std_menu(
- &ctx->ctrl_handler,
- &s5p_mfc_enc_ctrl_ops, controls[i].id,
- controls[i].maximum, 0,
- controls[i].default_value);
- } else {
- ctx->ctrls[i] = v4l2_ctrl_new_std(
- &ctx->ctrl_handler,
- &s5p_mfc_enc_ctrl_ops, controls[i].id,
- controls[i].minimum,
- controls[i].maximum, controls[i].step,
- controls[i].default_value);
- }
- }
- if (ctx->ctrl_handler.error) {
- mfc_err("Adding control (%d) failed\n", i);
- return ctx->ctrl_handler.error;
- }
- if (controls[i].is_volatile && ctx->ctrls[i])
- ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE;
- }
- return 0;
-}
-
-void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx)
-{
- int i;
-
- v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- for (i = 0; i < NUM_CTRLS; i++)
- ctx->ctrls[i] = NULL;
-}
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.h b/drivers/media/video/s5p-mfc/s5p_mfc_enc.h
deleted file mode 100644
index 405bdd3ee08..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_enc.h
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef S5P_MFC_ENC_H_
-#define S5P_MFC_ENC_H_
-
-struct s5p_mfc_codec_ops *get_enc_codec_ops(void);
-struct vb2_ops *get_enc_queue_ops(void);
-const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void);
-struct s5p_mfc_fmt *get_enc_def_fmt(bool src);
-int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx);
-void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx);
-
-#endif /* S5P_MFC_ENC_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_intr.c b/drivers/media/video/s5p-mfc/s5p_mfc_intr.c
deleted file mode 100644
index 8f2f8bf4da7..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_intr.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * drivers/media/video/samsung/mfc5/s5p_mfc_intr.c
- *
- * C file for Samsung MFC (Multi Function Codec - FIMV) driver
- * This file contains functions used to wait for command completion.
- *
- * Kamil Debski, Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/io.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include "regs-mfc.h"
-#include "s5p_mfc_common.h"
-#include "s5p_mfc_debug.h"
-#include "s5p_mfc_intr.h"
-
-int s5p_mfc_wait_for_done_dev(struct s5p_mfc_dev *dev, int command)
-{
- int ret;
-
- ret = wait_event_interruptible_timeout(dev->queue,
- (dev->int_cond && (dev->int_type == command
- || dev->int_type == S5P_FIMV_R2H_CMD_ERR_RET)),
- msecs_to_jiffies(MFC_INT_TIMEOUT));
- if (ret == 0) {
- mfc_err("Interrupt (dev->int_type:%d, command:%d) timed out\n",
- dev->int_type, command);
- return 1;
- } else if (ret == -ERESTARTSYS) {
- mfc_err("Interrupted by a signal\n");
- return 1;
- }
- mfc_debug(1, "Finished waiting (dev->int_type:%d, command: %d)\n",
- dev->int_type, command);
- if (dev->int_type == S5P_FIMV_R2H_CMD_ERR_RET)
- return 1;
- return 0;
-}
-
-void s5p_mfc_clean_dev_int_flags(struct s5p_mfc_dev *dev)
-{
- dev->int_cond = 0;
- dev->int_type = 0;
- dev->int_err = 0;
-}
-
-int s5p_mfc_wait_for_done_ctx(struct s5p_mfc_ctx *ctx,
- int command, int interrupt)
-{
- int ret;
-
- if (interrupt) {
- ret = wait_event_interruptible_timeout(ctx->queue,
- (ctx->int_cond && (ctx->int_type == command
- || ctx->int_type == S5P_FIMV_R2H_CMD_ERR_RET)),
- msecs_to_jiffies(MFC_INT_TIMEOUT));
- } else {
- ret = wait_event_timeout(ctx->queue,
- (ctx->int_cond && (ctx->int_type == command
- || ctx->int_type == S5P_FIMV_R2H_CMD_ERR_RET)),
- msecs_to_jiffies(MFC_INT_TIMEOUT));
- }
- if (ret == 0) {
- mfc_err("Interrupt (ctx->int_type:%d, command:%d) timed out\n",
- ctx->int_type, command);
- return 1;
- } else if (ret == -ERESTARTSYS) {
- mfc_err("Interrupted by a signal\n");
- return 1;
- }
- mfc_debug(1, "Finished waiting (ctx->int_type:%d, command: %d)\n",
- ctx->int_type, command);
- if (ctx->int_type == S5P_FIMV_R2H_CMD_ERR_RET)
- return 1;
- return 0;
-}
-
-void s5p_mfc_clean_ctx_int_flags(struct s5p_mfc_ctx *ctx)
-{
- ctx->int_cond = 0;
- ctx->int_type = 0;
- ctx->int_err = 0;
-}
-
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_intr.h b/drivers/media/video/s5p-mfc/s5p_mfc_intr.h
deleted file mode 100644
index 122d7732f74..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_intr.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * drivers/media/video/samsung/mfc5/s5p_mfc_intr.h
- *
- * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
- * It contains waiting functions declarations.
- *
- * Kamil Debski, Copyright (C) 2011 Samsung Electronics
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef S5P_MFC_INTR_H_
-#define S5P_MFC_INTR_H_
-
-#include "s5p_mfc_common.h"
-
-int s5p_mfc_wait_for_done_ctx(struct s5p_mfc_ctx *ctx,
- int command, int interrupt);
-int s5p_mfc_wait_for_done_dev(struct s5p_mfc_dev *dev, int command);
-void s5p_mfc_clean_ctx_int_flags(struct s5p_mfc_ctx *ctx);
-void s5p_mfc_clean_dev_int_flags(struct s5p_mfc_dev *dev);
-
-#endif /* S5P_MFC_INTR_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_opr.c b/drivers/media/video/s5p-mfc/s5p_mfc_opr.c
deleted file mode 100644
index e6217cbfa4a..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_opr.c
+++ /dev/null
@@ -1,1397 +0,0 @@
-/*
- * drivers/media/video/samsung/mfc5/s5p_mfc_opr.c
- *
- * Samsung MFC (Multi Function Codec - FIMV) driver
- * This file contains hw related functions.
- *
- * Kamil Debski, Copyright (c) 2011 Samsung Electronics
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "regs-mfc.h"
-#include "s5p_mfc_cmd.h"
-#include "s5p_mfc_common.h"
-#include "s5p_mfc_ctrl.h"
-#include "s5p_mfc_debug.h"
-#include "s5p_mfc_intr.h"
-#include "s5p_mfc_opr.h"
-#include "s5p_mfc_pm.h"
-#include "s5p_mfc_shm.h"
-#include <asm/cacheflush.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/err.h>
-#include <linux/firmware.h>
-#include <linux/io.h>
-#include <linux/jiffies.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-
-#define OFFSETA(x) (((x) - dev->bank1) >> MFC_OFFSET_SHIFT)
-#define OFFSETB(x) (((x) - dev->bank2) >> MFC_OFFSET_SHIFT)
-
-/* Allocate temporary buffers for decoding */
-int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx)
-{
- void *desc_virt;
- struct s5p_mfc_dev *dev = ctx->dev;
-
- ctx->desc_buf = vb2_dma_contig_memops.alloc(
- dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], DESC_BUF_SIZE);
- if (IS_ERR_VALUE((int)ctx->desc_buf)) {
- ctx->desc_buf = NULL;
- mfc_err("Allocating DESC buffer failed\n");
- return -ENOMEM;
- }
- ctx->desc_phys = s5p_mfc_mem_cookie(
- dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->desc_buf);
- BUG_ON(ctx->desc_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
- desc_virt = vb2_dma_contig_memops.vaddr(ctx->desc_buf);
- if (desc_virt == NULL) {
- vb2_dma_contig_memops.put(ctx->desc_buf);
- ctx->desc_phys = 0;
- ctx->desc_buf = NULL;
- mfc_err("Remapping DESC buffer failed\n");
- return -ENOMEM;
- }
- memset(desc_virt, 0, DESC_BUF_SIZE);
- wmb();
- return 0;
-}
-
-/* Release temporary buffers for decoding */
-void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
-{
- if (ctx->desc_phys) {
- vb2_dma_contig_memops.put(ctx->desc_buf);
- ctx->desc_phys = 0;
- ctx->desc_buf = NULL;
- }
-}
-
-/* Allocate codec buffers */
-int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned int enc_ref_y_size = 0;
- unsigned int enc_ref_c_size = 0;
- unsigned int guard_width, guard_height;
-
- if (ctx->type == MFCINST_DECODER) {
- mfc_debug(2, "Luma size:%d Chroma size:%d MV size:%d\n",
- ctx->luma_size, ctx->chroma_size, ctx->mv_size);
- mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count);
- } else if (ctx->type == MFCINST_ENCODER) {
- enc_ref_y_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
- * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
- enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN);
-
- if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) {
- enc_ref_c_size = ALIGN(ctx->img_width,
- S5P_FIMV_NV12MT_HALIGN)
- * ALIGN(ctx->img_height >> 1,
- S5P_FIMV_NV12MT_VALIGN);
- enc_ref_c_size = ALIGN(enc_ref_c_size,
- S5P_FIMV_NV12MT_SALIGN);
- } else {
- guard_width = ALIGN(ctx->img_width + 16,
- S5P_FIMV_NV12MT_HALIGN);
- guard_height = ALIGN((ctx->img_height >> 1) + 4,
- S5P_FIMV_NV12MT_VALIGN);
- enc_ref_c_size = ALIGN(guard_width * guard_height,
- S5P_FIMV_NV12MT_SALIGN);
- }
- mfc_debug(2, "recon luma size: %d chroma size: %d\n",
- enc_ref_y_size, enc_ref_c_size);
- } else {
- return -EINVAL;
- }
- /* Codecs have different memory requirements */
- switch (ctx->codec_mode) {
- case S5P_FIMV_CODEC_H264_DEC:
- ctx->bank1_size =
- ALIGN(S5P_FIMV_DEC_NB_IP_SIZE +
- S5P_FIMV_DEC_VERT_NB_MV_SIZE,
- S5P_FIMV_DEC_BUF_ALIGN);
- ctx->bank2_size = ctx->total_dpb_count * ctx->mv_size;
- break;
- case S5P_FIMV_CODEC_MPEG4_DEC:
- ctx->bank1_size =
- ALIGN(S5P_FIMV_DEC_NB_DCAC_SIZE +
- S5P_FIMV_DEC_UPNB_MV_SIZE +
- S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +
- S5P_FIMV_DEC_STX_PARSER_SIZE +
- S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE,
- S5P_FIMV_DEC_BUF_ALIGN);
- ctx->bank2_size = 0;
- break;
- case S5P_FIMV_CODEC_VC1RCV_DEC:
- case S5P_FIMV_CODEC_VC1_DEC:
- ctx->bank1_size =
- ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE +
- S5P_FIMV_DEC_UPNB_MV_SIZE +
- S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +
- S5P_FIMV_DEC_NB_DCAC_SIZE +
- 3 * S5P_FIMV_DEC_VC1_BITPLANE_SIZE,
- S5P_FIMV_DEC_BUF_ALIGN);
- ctx->bank2_size = 0;
- break;
- case S5P_FIMV_CODEC_MPEG2_DEC:
- ctx->bank1_size = 0;
- ctx->bank2_size = 0;
- break;
- case S5P_FIMV_CODEC_H263_DEC:
- ctx->bank1_size =
- ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE +
- S5P_FIMV_DEC_UPNB_MV_SIZE +
- S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +
- S5P_FIMV_DEC_NB_DCAC_SIZE,
- S5P_FIMV_DEC_BUF_ALIGN);
- ctx->bank2_size = 0;
- break;
- case S5P_FIMV_CODEC_H264_ENC:
- ctx->bank1_size = (enc_ref_y_size * 2) +
- S5P_FIMV_ENC_UPMV_SIZE +
- S5P_FIMV_ENC_COLFLG_SIZE +
- S5P_FIMV_ENC_INTRAMD_SIZE +
- S5P_FIMV_ENC_NBORINFO_SIZE;
- ctx->bank2_size = (enc_ref_y_size * 2) +
- (enc_ref_c_size * 4) +
- S5P_FIMV_ENC_INTRAPRED_SIZE;
- break;
- case S5P_FIMV_CODEC_MPEG4_ENC:
- ctx->bank1_size = (enc_ref_y_size * 2) +
- S5P_FIMV_ENC_UPMV_SIZE +
- S5P_FIMV_ENC_COLFLG_SIZE +
- S5P_FIMV_ENC_ACDCCOEF_SIZE;
- ctx->bank2_size = (enc_ref_y_size * 2) +
- (enc_ref_c_size * 4);
- break;
- case S5P_FIMV_CODEC_H263_ENC:
- ctx->bank1_size = (enc_ref_y_size * 2) +
- S5P_FIMV_ENC_UPMV_SIZE +
- S5P_FIMV_ENC_ACDCCOEF_SIZE;
- ctx->bank2_size = (enc_ref_y_size * 2) +
- (enc_ref_c_size * 4);
- break;
- default:
- break;
- }
- /* Allocate only if memory from bank 1 is necessary */
- if (ctx->bank1_size > 0) {
- ctx->bank1_buf = vb2_dma_contig_memops.alloc(
- dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_size);
- if (IS_ERR(ctx->bank1_buf)) {
- ctx->bank1_buf = NULL;
- printk(KERN_ERR
- "Buf alloc for decoding failed (port A)\n");
- return -ENOMEM;
- }
- ctx->bank1_phys = s5p_mfc_mem_cookie(
- dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_buf);
- BUG_ON(ctx->bank1_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
- }
- /* Allocate only if memory from bank 2 is necessary */
- if (ctx->bank2_size > 0) {
- ctx->bank2_buf = vb2_dma_contig_memops.alloc(
- dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], ctx->bank2_size);
- if (IS_ERR(ctx->bank2_buf)) {
- ctx->bank2_buf = NULL;
- mfc_err("Buf alloc for decoding failed (port B)\n");
- return -ENOMEM;
- }
- ctx->bank2_phys = s5p_mfc_mem_cookie(
- dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], ctx->bank2_buf);
- BUG_ON(ctx->bank2_phys & ((1 << MFC_BANK2_ALIGN_ORDER) - 1));
- }
- return 0;
-}
-
-/* Release buffers allocated for codec */
-void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx)
-{
- if (ctx->bank1_buf) {
- vb2_dma_contig_memops.put(ctx->bank1_buf);
- ctx->bank1_buf = NULL;
- ctx->bank1_phys = 0;
- ctx->bank1_size = 0;
- }
- if (ctx->bank2_buf) {
- vb2_dma_contig_memops.put(ctx->bank2_buf);
- ctx->bank2_buf = NULL;
- ctx->bank2_phys = 0;
- ctx->bank2_size = 0;
- }
-}
-
-/* Allocate memory for instance data buffer */
-int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx)
-{
- void *context_virt;
- struct s5p_mfc_dev *dev = ctx->dev;
-
- if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC ||
- ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
- ctx->ctx_size = MFC_H264_CTX_BUF_SIZE;
- else
- ctx->ctx_size = MFC_CTX_BUF_SIZE;
- ctx->ctx_buf = vb2_dma_contig_memops.alloc(
- dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_size);
- if (IS_ERR(ctx->ctx_buf)) {
- mfc_err("Allocating context buffer failed\n");
- ctx->ctx_phys = 0;
- ctx->ctx_buf = NULL;
- return -ENOMEM;
- }
- ctx->ctx_phys = s5p_mfc_mem_cookie(
- dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_buf);
- BUG_ON(ctx->ctx_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
- ctx->ctx_ofs = OFFSETA(ctx->ctx_phys);
- context_virt = vb2_dma_contig_memops.vaddr(ctx->ctx_buf);
- if (context_virt == NULL) {
- mfc_err("Remapping instance buffer failed\n");
- vb2_dma_contig_memops.put(ctx->ctx_buf);
- ctx->ctx_phys = 0;
- ctx->ctx_buf = NULL;
- return -ENOMEM;
- }
- /* Zero content of the allocated memory */
- memset(context_virt, 0, ctx->ctx_size);
- wmb();
- if (s5p_mfc_init_shm(ctx) < 0) {
- vb2_dma_contig_memops.put(ctx->ctx_buf);
- ctx->ctx_phys = 0;
- ctx->ctx_buf = NULL;
- return -ENOMEM;
- }
- return 0;
-}
-
-/* Release instance buffer */
-void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx)
-{
- if (ctx->ctx_buf) {
- vb2_dma_contig_memops.put(ctx->ctx_buf);
- ctx->ctx_phys = 0;
- ctx->ctx_buf = NULL;
- }
- if (ctx->shm_alloc) {
- vb2_dma_contig_memops.put(ctx->shm_alloc);
- ctx->shm_alloc = NULL;
- ctx->shm = NULL;
- }
-}
-
-/* Set registers for decoding temporary buffers */
-void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
-
- mfc_write(dev, OFFSETA(ctx->desc_phys), S5P_FIMV_SI_CH0_DESC_ADR);
- mfc_write(dev, DESC_BUF_SIZE, S5P_FIMV_SI_CH0_DESC_SIZE);
-}
-
-/* Set registers for shared buffer */
-static void s5p_mfc_set_shared_buffer(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- mfc_write(dev, ctx->shm_ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR);
-}
-
-/* Set registers for decoding stream buffer */
-int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr,
- unsigned int start_num_byte, unsigned int buf_size)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
-
- mfc_write(dev, OFFSETA(buf_addr), S5P_FIMV_SI_CH0_SB_ST_ADR);
- mfc_write(dev, ctx->dec_src_buf_size, S5P_FIMV_SI_CH0_CPB_SIZE);
- mfc_write(dev, buf_size, S5P_FIMV_SI_CH0_SB_FRM_SIZE);
- s5p_mfc_write_shm(ctx, start_num_byte, START_BYTE_NUM);
- return 0;
-}
-
-/* Set decoding frame buffer */
-int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx)
-{
- unsigned int frame_size, i;
- unsigned int frame_size_ch, frame_size_mv;
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned int dpb;
- size_t buf_addr1, buf_addr2;
- int buf_size1, buf_size2;
-
- buf_addr1 = ctx->bank1_phys;
- buf_size1 = ctx->bank1_size;
- buf_addr2 = ctx->bank2_phys;
- buf_size2 = ctx->bank2_size;
- dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) &
- ~S5P_FIMV_DPB_COUNT_MASK;
- mfc_write(dev, ctx->total_dpb_count | dpb,
- S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
- s5p_mfc_set_shared_buffer(ctx);
- switch (ctx->codec_mode) {
- case S5P_FIMV_CODEC_H264_DEC:
- mfc_write(dev, OFFSETA(buf_addr1),
- S5P_FIMV_H264_VERT_NB_MV_ADR);
- buf_addr1 += S5P_FIMV_DEC_VERT_NB_MV_SIZE;
- buf_size1 -= S5P_FIMV_DEC_VERT_NB_MV_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H264_NB_IP_ADR);
- buf_addr1 += S5P_FIMV_DEC_NB_IP_SIZE;
- buf_size1 -= S5P_FIMV_DEC_NB_IP_SIZE;
- break;
- case S5P_FIMV_CODEC_MPEG4_DEC:
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_NB_DCAC_ADR);
- buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
- buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_UP_NB_MV_ADR);
- buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;
- buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_SA_MV_ADR);
- buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
- buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_SP_ADR);
- buf_addr1 += S5P_FIMV_DEC_STX_PARSER_SIZE;
- buf_size1 -= S5P_FIMV_DEC_STX_PARSER_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_OT_LINE_ADR);
- buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
- buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
- break;
- case S5P_FIMV_CODEC_H263_DEC:
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_OT_LINE_ADR);
- buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
- buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_UP_NB_MV_ADR);
- buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;
- buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_SA_MV_ADR);
- buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
- buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_NB_DCAC_ADR);
- buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
- buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
- break;
- case S5P_FIMV_CODEC_VC1_DEC:
- case S5P_FIMV_CODEC_VC1RCV_DEC:
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_NB_DCAC_ADR);
- buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
- buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_OT_LINE_ADR);
- buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
- buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_UP_NB_MV_ADR);
- buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;
- buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_SA_MV_ADR);
- buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
- buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE3_ADR);
- buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
- buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE2_ADR);
- buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
- buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE1_ADR);
- buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
- buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
- break;
- case S5P_FIMV_CODEC_MPEG2_DEC:
- break;
- default:
- mfc_err("Unknown codec for decoding (%x)\n",
- ctx->codec_mode);
- return -EINVAL;
- break;
- }
- frame_size = ctx->luma_size;
- frame_size_ch = ctx->chroma_size;
- frame_size_mv = ctx->mv_size;
- mfc_debug(2, "Frm size: %d ch: %d mv: %d\n", frame_size, frame_size_ch,
- frame_size_mv);
- for (i = 0; i < ctx->total_dpb_count; i++) {
- /* Bank2 */
- mfc_debug(2, "Luma %d: %x\n", i,
- ctx->dst_bufs[i].cookie.raw.luma);
- mfc_write(dev, OFFSETB(ctx->dst_bufs[i].cookie.raw.luma),
- S5P_FIMV_DEC_LUMA_ADR + i * 4);
- mfc_debug(2, "\tChroma %d: %x\n", i,
- ctx->dst_bufs[i].cookie.raw.chroma);
- mfc_write(dev, OFFSETA(ctx->dst_bufs[i].cookie.raw.chroma),
- S5P_FIMV_DEC_CHROMA_ADR + i * 4);
- if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) {
- mfc_debug(2, "\tBuf2: %x, size: %d\n",
- buf_addr2, buf_size2);
- mfc_write(dev, OFFSETB(buf_addr2),
- S5P_FIMV_H264_MV_ADR + i * 4);
- buf_addr2 += frame_size_mv;
- buf_size2 -= frame_size_mv;
- }
- }
- mfc_debug(2, "Buf1: %u, buf_size1: %d\n", buf_addr1, buf_size1);
- mfc_debug(2, "Buf 1/2 size after: %d/%d (frames %d)\n",
- buf_size1, buf_size2, ctx->total_dpb_count);
- if (buf_size1 < 0 || buf_size2 < 0) {
- mfc_debug(2, "Not enough memory has been allocated\n");
- return -ENOMEM;
- }
- s5p_mfc_write_shm(ctx, frame_size, ALLOC_LUMA_DPB_SIZE);
- s5p_mfc_write_shm(ctx, frame_size_ch, ALLOC_CHROMA_DPB_SIZE);
- if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC)
- s5p_mfc_write_shm(ctx, frame_size_mv, ALLOC_MV_SIZE);
- mfc_write(dev, ((S5P_FIMV_CH_INIT_BUFS & S5P_FIMV_CH_MASK)
- << S5P_FIMV_CH_SHIFT) | (ctx->inst_no),
- S5P_FIMV_SI_CH0_INST_ID);
- return 0;
-}
-
-/* Set registers for encoding stream buffer */
-int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx,
- unsigned long addr, unsigned int size)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
-
- mfc_write(dev, OFFSETA(addr), S5P_FIMV_ENC_SI_CH0_SB_ADR);
- mfc_write(dev, size, S5P_FIMV_ENC_SI_CH0_SB_SIZE);
- return 0;
-}
-
-void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
- unsigned long y_addr, unsigned long c_addr)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
-
- mfc_write(dev, OFFSETB(y_addr), S5P_FIMV_ENC_SI_CH0_CUR_Y_ADR);
- mfc_write(dev, OFFSETB(c_addr), S5P_FIMV_ENC_SI_CH0_CUR_C_ADR);
-}
-
-void s5p_mfc_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
- unsigned long *y_addr, unsigned long *c_addr)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
-
- *y_addr = dev->bank2 + (mfc_read(dev, S5P_FIMV_ENCODED_Y_ADDR)
- << MFC_OFFSET_SHIFT);
- *c_addr = dev->bank2 + (mfc_read(dev, S5P_FIMV_ENCODED_C_ADDR)
- << MFC_OFFSET_SHIFT);
-}
-
-/* Set encoding ref & codec buffer */
-int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- size_t buf_addr1, buf_addr2;
- size_t buf_size1, buf_size2;
- unsigned int enc_ref_y_size, enc_ref_c_size;
- unsigned int guard_width, guard_height;
- int i;
-
- buf_addr1 = ctx->bank1_phys;
- buf_size1 = ctx->bank1_size;
- buf_addr2 = ctx->bank2_phys;
- buf_size2 = ctx->bank2_size;
- enc_ref_y_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
- * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
- enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN);
- if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) {
- enc_ref_c_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
- * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12MT_VALIGN);
- enc_ref_c_size = ALIGN(enc_ref_c_size, S5P_FIMV_NV12MT_SALIGN);
- } else {
- guard_width = ALIGN(ctx->img_width + 16,
- S5P_FIMV_NV12MT_HALIGN);
- guard_height = ALIGN((ctx->img_height >> 1) + 4,
- S5P_FIMV_NV12MT_VALIGN);
- enc_ref_c_size = ALIGN(guard_width * guard_height,
- S5P_FIMV_NV12MT_SALIGN);
- }
- mfc_debug(2, "buf_size1: %d, buf_size2: %d\n", buf_size1, buf_size2);
- switch (ctx->codec_mode) {
- case S5P_FIMV_CODEC_H264_ENC:
- for (i = 0; i < 2; i++) {
- mfc_write(dev, OFFSETA(buf_addr1),
- S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
- buf_addr1 += enc_ref_y_size;
- buf_size1 -= enc_ref_y_size;
-
- mfc_write(dev, OFFSETB(buf_addr2),
- S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));
- buf_addr2 += enc_ref_y_size;
- buf_size2 -= enc_ref_y_size;
- }
- for (i = 0; i < 4; i++) {
- mfc_write(dev, OFFSETB(buf_addr2),
- S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));
- buf_addr2 += enc_ref_c_size;
- buf_size2 -= enc_ref_c_size;
- }
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H264_UP_MV_ADR);
- buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;
- buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1),
- S5P_FIMV_H264_COZERO_FLAG_ADR);
- buf_addr1 += S5P_FIMV_ENC_COLFLG_SIZE;
- buf_size1 -= S5P_FIMV_ENC_COLFLG_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1),
- S5P_FIMV_H264_UP_INTRA_MD_ADR);
- buf_addr1 += S5P_FIMV_ENC_INTRAMD_SIZE;
- buf_size1 -= S5P_FIMV_ENC_INTRAMD_SIZE;
- mfc_write(dev, OFFSETB(buf_addr2),
- S5P_FIMV_H264_UP_INTRA_PRED_ADR);
- buf_addr2 += S5P_FIMV_ENC_INTRAPRED_SIZE;
- buf_size2 -= S5P_FIMV_ENC_INTRAPRED_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1),
- S5P_FIMV_H264_NBOR_INFO_ADR);
- buf_addr1 += S5P_FIMV_ENC_NBORINFO_SIZE;
- buf_size1 -= S5P_FIMV_ENC_NBORINFO_SIZE;
- mfc_debug(2, "buf_size1: %d, buf_size2: %d\n",
- buf_size1, buf_size2);
- break;
- case S5P_FIMV_CODEC_MPEG4_ENC:
- for (i = 0; i < 2; i++) {
- mfc_write(dev, OFFSETA(buf_addr1),
- S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
- buf_addr1 += enc_ref_y_size;
- buf_size1 -= enc_ref_y_size;
- mfc_write(dev, OFFSETB(buf_addr2),
- S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));
- buf_addr2 += enc_ref_y_size;
- buf_size2 -= enc_ref_y_size;
- }
- for (i = 0; i < 4; i++) {
- mfc_write(dev, OFFSETB(buf_addr2),
- S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));
- buf_addr2 += enc_ref_c_size;
- buf_size2 -= enc_ref_c_size;
- }
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_UP_MV_ADR);
- buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;
- buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1),
- S5P_FIMV_MPEG4_COZERO_FLAG_ADR);
- buf_addr1 += S5P_FIMV_ENC_COLFLG_SIZE;
- buf_size1 -= S5P_FIMV_ENC_COLFLG_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1),
- S5P_FIMV_MPEG4_ACDC_COEF_ADR);
- buf_addr1 += S5P_FIMV_ENC_ACDCCOEF_SIZE;
- buf_size1 -= S5P_FIMV_ENC_ACDCCOEF_SIZE;
- mfc_debug(2, "buf_size1: %d, buf_size2: %d\n",
- buf_size1, buf_size2);
- break;
- case S5P_FIMV_CODEC_H263_ENC:
- for (i = 0; i < 2; i++) {
- mfc_write(dev, OFFSETA(buf_addr1),
- S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
- buf_addr1 += enc_ref_y_size;
- buf_size1 -= enc_ref_y_size;
- mfc_write(dev, OFFSETB(buf_addr2),
- S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));
- buf_addr2 += enc_ref_y_size;
- buf_size2 -= enc_ref_y_size;
- }
- for (i = 0; i < 4; i++) {
- mfc_write(dev, OFFSETB(buf_addr2),
- S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));
- buf_addr2 += enc_ref_c_size;
- buf_size2 -= enc_ref_c_size;
- }
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_UP_MV_ADR);
- buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;
- buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;
- mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_ACDC_COEF_ADR);
- buf_addr1 += S5P_FIMV_ENC_ACDCCOEF_SIZE;
- buf_size1 -= S5P_FIMV_ENC_ACDCCOEF_SIZE;
- mfc_debug(2, "buf_size1: %d, buf_size2: %d\n",
- buf_size1, buf_size2);
- break;
- default:
- mfc_err("Unknown codec set for encoding: %d\n",
- ctx->codec_mode);
- return -EINVAL;
- }
- return 0;
-}
-
-static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
- unsigned int reg;
- unsigned int shm;
-
- /* width */
- mfc_write(dev, ctx->img_width, S5P_FIMV_ENC_HSIZE_PX);
- /* height */
- mfc_write(dev, ctx->img_height, S5P_FIMV_ENC_VSIZE_PX);
- /* pictype : enable, IDR period */
- reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);
- reg |= (1 << 18);
- reg &= ~(0xFFFF);
- reg |= p->gop_size;
- mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);
- mfc_write(dev, 0, S5P_FIMV_ENC_B_RECON_WRITE_ON);
- /* multi-slice control */
- /* multi-slice MB number or bit size */
- mfc_write(dev, p->slice_mode, S5P_FIMV_ENC_MSLICE_CTRL);
- if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
- mfc_write(dev, p->slice_mb, S5P_FIMV_ENC_MSLICE_MB);
- } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
- mfc_write(dev, p->slice_bit, S5P_FIMV_ENC_MSLICE_BIT);
- } else {
- mfc_write(dev, 0, S5P_FIMV_ENC_MSLICE_MB);
- mfc_write(dev, 0, S5P_FIMV_ENC_MSLICE_BIT);
- }
- /* cyclic intra refresh */
- mfc_write(dev, p->intra_refresh_mb, S5P_FIMV_ENC_CIR_CTRL);
- /* memory structure cur. frame */
- if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M)
- mfc_write(dev, 0, S5P_FIMV_ENC_MAP_FOR_CUR);
- else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT)
- mfc_write(dev, 3, S5P_FIMV_ENC_MAP_FOR_CUR);
- /* padding control & value */
- reg = mfc_read(dev, S5P_FIMV_ENC_PADDING_CTRL);
- if (p->pad) {
- /** enable */
- reg |= (1 << 31);
- /** cr value */
- reg &= ~(0xFF << 16);
- reg |= (p->pad_cr << 16);
- /** cb value */
- reg &= ~(0xFF << 8);
- reg |= (p->pad_cb << 8);
- /** y value */
- reg &= ~(0xFF);
- reg |= (p->pad_luma);
- } else {
- /** disable & all value clear */
- reg = 0;
- }
- mfc_write(dev, reg, S5P_FIMV_ENC_PADDING_CTRL);
- /* rate control config. */
- reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
- /** frame-level rate control */
- reg &= ~(0x1 << 9);
- reg |= (p->rc_frame << 9);
- mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
- /* bit rate */
- if (p->rc_frame)
- mfc_write(dev, p->rc_bitrate,
- S5P_FIMV_ENC_RC_BIT_RATE);
- else
- mfc_write(dev, 0, S5P_FIMV_ENC_RC_BIT_RATE);
- /* reaction coefficient */
- if (p->rc_frame)
- mfc_write(dev, p->rc_reaction_coeff, S5P_FIMV_ENC_RC_RPARA);
- shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
- /* seq header ctrl */
- shm &= ~(0x1 << 3);
- shm |= (p->seq_hdr_mode << 3);
- /* frame skip mode */
- shm &= ~(0x3 << 1);
- shm |= (p->frame_skip_mode << 1);
- s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
- /* fixed target bit */
- s5p_mfc_write_shm(ctx, p->fixed_target_bit, RC_CONTROL_CONFIG);
- return 0;
-}
-
-static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
- struct s5p_mfc_h264_enc_params *p_264 = &p->codec.h264;
- unsigned int reg;
- unsigned int shm;
-
- s5p_mfc_set_enc_params(ctx);
- /* pictype : number of B */
- reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);
- /* num_b_frame - 0 ~ 2 */
- reg &= ~(0x3 << 16);
- reg |= (p->num_b_frame << 16);
- mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);
- /* profile & level */
- reg = mfc_read(dev, S5P_FIMV_ENC_PROFILE);
- /* level */
- reg &= ~(0xFF << 8);
- reg |= (p_264->level << 8);
- /* profile - 0 ~ 2 */
- reg &= ~(0x3F);
- reg |= p_264->profile;
- mfc_write(dev, reg, S5P_FIMV_ENC_PROFILE);
- /* interlace */
- mfc_write(dev, p->interlace, S5P_FIMV_ENC_PIC_STRUCT);
- /* height */
- if (p->interlace)
- mfc_write(dev, ctx->img_height >> 1, S5P_FIMV_ENC_VSIZE_PX);
- /* loopfilter ctrl */
- mfc_write(dev, p_264->loop_filter_mode, S5P_FIMV_ENC_LF_CTRL);
- /* loopfilter alpha offset */
- if (p_264->loop_filter_alpha < 0) {
- reg = 0x10;
- reg |= (0xFF - p_264->loop_filter_alpha) + 1;
- } else {
- reg = 0x00;
- reg |= (p_264->loop_filter_alpha & 0xF);
- }
- mfc_write(dev, reg, S5P_FIMV_ENC_ALPHA_OFF);
- /* loopfilter beta offset */
- if (p_264->loop_filter_beta < 0) {
- reg = 0x10;
- reg |= (0xFF - p_264->loop_filter_beta) + 1;
- } else {
- reg = 0x00;
- reg |= (p_264->loop_filter_beta & 0xF);
- }
- mfc_write(dev, reg, S5P_FIMV_ENC_BETA_OFF);
- /* entropy coding mode */
- if (p_264->entropy_mode == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC)
- mfc_write(dev, 1, S5P_FIMV_ENC_H264_ENTROPY_MODE);
- else
- mfc_write(dev, 0, S5P_FIMV_ENC_H264_ENTROPY_MODE);
- /* number of ref. picture */
- reg = mfc_read(dev, S5P_FIMV_ENC_H264_NUM_OF_REF);
- /* num of ref. pictures of P */
- reg &= ~(0x3 << 5);
- reg |= (p_264->num_ref_pic_4p << 5);
- /* max number of ref. pictures */
- reg &= ~(0x1F);
- reg |= p_264->max_ref_pic;
- mfc_write(dev, reg, S5P_FIMV_ENC_H264_NUM_OF_REF);
- /* 8x8 transform enable */
- mfc_write(dev, p_264->_8x8_transform, S5P_FIMV_ENC_H264_TRANS_FLAG);
- /* rate control config. */
- reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
- /* macroblock level rate control */
- reg &= ~(0x1 << 8);
- reg |= (p_264->rc_mb << 8);
- /* frame QP */
- reg &= ~(0x3F);
- reg |= p_264->rc_frame_qp;
- mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
- /* frame rate */
- if (p->rc_frame && p->rc_framerate_denom)
- mfc_write(dev, p->rc_framerate_num * 1000
- / p->rc_framerate_denom, S5P_FIMV_ENC_RC_FRAME_RATE);
- else
- mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);
- /* max & min value of QP */
- reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);
- /* max QP */
- reg &= ~(0x3F << 8);
- reg |= (p_264->rc_max_qp << 8);
- /* min QP */
- reg &= ~(0x3F);
- reg |= p_264->rc_min_qp;
- mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
- /* macroblock adaptive scaling features */
- if (p_264->rc_mb) {
- reg = mfc_read(dev, S5P_FIMV_ENC_RC_MB_CTRL);
- /* dark region */
- reg &= ~(0x1 << 3);
- reg |= (p_264->rc_mb_dark << 3);
- /* smooth region */
- reg &= ~(0x1 << 2);
- reg |= (p_264->rc_mb_smooth << 2);
- /* static region */
- reg &= ~(0x1 << 1);
- reg |= (p_264->rc_mb_static << 1);
- /* high activity region */
- reg &= ~(0x1);
- reg |= p_264->rc_mb_activity;
- mfc_write(dev, reg, S5P_FIMV_ENC_RC_MB_CTRL);
- }
- if (!p->rc_frame &&
- !p_264->rc_mb) {
- shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
- shm &= ~(0xFFF);
- shm |= ((p_264->rc_b_frame_qp & 0x3F) << 6);
- shm |= (p_264->rc_p_frame_qp & 0x3F);
- s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
- }
- /* extended encoder ctrl */
- shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
- /* AR VUI control */
- shm &= ~(0x1 << 15);
- shm |= (p_264->vui_sar << 1);
- s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
- if (p_264->vui_sar) {
- /* aspect ration IDC */
- shm = s5p_mfc_read_shm(ctx, SAMPLE_ASPECT_RATIO_IDC);
- shm &= ~(0xFF);
- shm |= p_264->vui_sar_idc;
- s5p_mfc_write_shm(ctx, shm, SAMPLE_ASPECT_RATIO_IDC);
- if (p_264->vui_sar_idc == 0xFF) {
- /* sample AR info */
- shm = s5p_mfc_read_shm(ctx, EXTENDED_SAR);
- shm &= ~(0xFFFFFFFF);
- shm |= p_264->vui_ext_sar_width << 16;
- shm |= p_264->vui_ext_sar_height;
- s5p_mfc_write_shm(ctx, shm, EXTENDED_SAR);
- }
- }
- /* intra picture period for H.264 */
- shm = s5p_mfc_read_shm(ctx, H264_I_PERIOD);
- /* control */
- shm &= ~(0x1 << 16);
- shm |= (p_264->open_gop << 16);
- /* value */
- if (p_264->open_gop) {
- shm &= ~(0xFFFF);
- shm |= p_264->open_gop_size;
- }
- s5p_mfc_write_shm(ctx, shm, H264_I_PERIOD);
- /* extended encoder ctrl */
- shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
- /* vbv buffer size */
- if (p->frame_skip_mode ==
- V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
- shm &= ~(0xFFFF << 16);
- shm |= (p_264->cpb_size << 16);
- }
- s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
- return 0;
-}
-
-static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
- struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4;
- unsigned int reg;
- unsigned int shm;
- unsigned int framerate;
-
- s5p_mfc_set_enc_params(ctx);
- /* pictype : number of B */
- reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);
- /* num_b_frame - 0 ~ 2 */
- reg &= ~(0x3 << 16);
- reg |= (p->num_b_frame << 16);
- mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);
- /* profile & level */
- reg = mfc_read(dev, S5P_FIMV_ENC_PROFILE);
- /* level */
- reg &= ~(0xFF << 8);
- reg |= (p_mpeg4->level << 8);
- /* profile - 0 ~ 2 */
- reg &= ~(0x3F);
- reg |= p_mpeg4->profile;
- mfc_write(dev, reg, S5P_FIMV_ENC_PROFILE);
- /* quarter_pixel */
- mfc_write(dev, p_mpeg4->quarter_pixel, S5P_FIMV_ENC_MPEG4_QUART_PXL);
- /* qp */
- if (!p->rc_frame) {
- shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
- shm &= ~(0xFFF);
- shm |= ((p_mpeg4->rc_b_frame_qp & 0x3F) << 6);
- shm |= (p_mpeg4->rc_p_frame_qp & 0x3F);
- s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
- }
- /* frame rate */
- if (p->rc_frame) {
- if (p->rc_framerate_denom > 0) {
- framerate = p->rc_framerate_num * 1000 /
- p->rc_framerate_denom;
- mfc_write(dev, framerate,
- S5P_FIMV_ENC_RC_FRAME_RATE);
- shm = s5p_mfc_read_shm(ctx, RC_VOP_TIMING);
- shm &= ~(0xFFFFFFFF);
- shm |= (1 << 31);
- shm |= ((p->rc_framerate_num & 0x7FFF) << 16);
- shm |= (p->rc_framerate_denom & 0xFFFF);
- s5p_mfc_write_shm(ctx, shm, RC_VOP_TIMING);
- }
- } else {
- mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);
- }
- /* rate control config. */
- reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
- /* frame QP */
- reg &= ~(0x3F);
- reg |= p_mpeg4->rc_frame_qp;
- mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
- /* max & min value of QP */
- reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);
- /* max QP */
- reg &= ~(0x3F << 8);
- reg |= (p_mpeg4->rc_max_qp << 8);
- /* min QP */
- reg &= ~(0x3F);
- reg |= p_mpeg4->rc_min_qp;
- mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
- /* extended encoder ctrl */
- shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
- /* vbv buffer size */
- if (p->frame_skip_mode ==
- V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
- shm &= ~(0xFFFF << 16);
- shm |= (p->vbv_size << 16);
- }
- s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
- return 0;
-}
-
-static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
- struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4;
- unsigned int reg;
- unsigned int shm;
-
- s5p_mfc_set_enc_params(ctx);
- /* qp */
- if (!p->rc_frame) {
- shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
- shm &= ~(0xFFF);
- shm |= (p_h263->rc_p_frame_qp & 0x3F);
- s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
- }
- /* frame rate */
- if (p->rc_frame && p->rc_framerate_denom)
- mfc_write(dev, p->rc_framerate_num * 1000
- / p->rc_framerate_denom, S5P_FIMV_ENC_RC_FRAME_RATE);
- else
- mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);
- /* rate control config. */
- reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
- /* frame QP */
- reg &= ~(0x3F);
- reg |= p_h263->rc_frame_qp;
- mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
- /* max & min value of QP */
- reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);
- /* max QP */
- reg &= ~(0x3F << 8);
- reg |= (p_h263->rc_max_qp << 8);
- /* min QP */
- reg &= ~(0x3F);
- reg |= p_h263->rc_min_qp;
- mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
- /* extended encoder ctrl */
- shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
- /* vbv buffer size */
- if (p->frame_skip_mode ==
- V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
- shm &= ~(0xFFFF << 16);
- shm |= (p->vbv_size << 16);
- }
- s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
- return 0;
-}
-
-/* Initialize decoding */
-int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
-
- s5p_mfc_set_shared_buffer(ctx);
- /* Setup loop filter, for decoding this is only valid for MPEG4 */
- if (ctx->codec_mode == S5P_FIMV_CODEC_MPEG4_DEC)
- mfc_write(dev, ctx->loop_filter_mpeg4, S5P_FIMV_ENC_LF_CTRL);
- else
- mfc_write(dev, 0, S5P_FIMV_ENC_LF_CTRL);
- mfc_write(dev, ((ctx->slice_interface & S5P_FIMV_SLICE_INT_MASK) <<
- S5P_FIMV_SLICE_INT_SHIFT) | (ctx->display_delay_enable <<
- S5P_FIMV_DDELAY_ENA_SHIFT) | ((ctx->display_delay &
- S5P_FIMV_DDELAY_VAL_MASK) << S5P_FIMV_DDELAY_VAL_SHIFT),
- S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
- mfc_write(dev,
- ((S5P_FIMV_CH_SEQ_HEADER & S5P_FIMV_CH_MASK) << S5P_FIMV_CH_SHIFT)
- | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
- return 0;
-}
-
-static void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned int dpb;
-
- if (flush)
- dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) | (
- S5P_FIMV_DPB_FLUSH_MASK << S5P_FIMV_DPB_FLUSH_SHIFT);
- else
- dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) &
- ~(S5P_FIMV_DPB_FLUSH_MASK << S5P_FIMV_DPB_FLUSH_SHIFT);
- mfc_write(dev, dpb, S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
-}
-
-/* Decode a single frame */
-int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx,
- enum s5p_mfc_decode_arg last_frame)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
-
- mfc_write(dev, ctx->dec_dst_flag, S5P_FIMV_SI_CH0_RELEASE_BUF);
- s5p_mfc_set_shared_buffer(ctx);
- s5p_mfc_set_flush(ctx, ctx->dpb_flush_flag);
- /* Issue different commands to instance basing on whether it
- * is the last frame or not. */
- switch (last_frame) {
- case MFC_DEC_FRAME:
- mfc_write(dev, ((S5P_FIMV_CH_FRAME_START & S5P_FIMV_CH_MASK) <<
- S5P_FIMV_CH_SHIFT) | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
- break;
- case MFC_DEC_LAST_FRAME:
- mfc_write(dev, ((S5P_FIMV_CH_LAST_FRAME & S5P_FIMV_CH_MASK) <<
- S5P_FIMV_CH_SHIFT) | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
- break;
- case MFC_DEC_RES_CHANGE:
- mfc_write(dev, ((S5P_FIMV_CH_FRAME_START_REALLOC &
- S5P_FIMV_CH_MASK) << S5P_FIMV_CH_SHIFT) | (ctx->inst_no),
- S5P_FIMV_SI_CH0_INST_ID);
- break;
- }
- mfc_debug(2, "Decoding a usual frame\n");
- return 0;
-}
-
-int s5p_mfc_init_encode(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
-
- if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
- s5p_mfc_set_enc_params_h264(ctx);
- else if (ctx->codec_mode == S5P_FIMV_CODEC_MPEG4_ENC)
- s5p_mfc_set_enc_params_mpeg4(ctx);
- else if (ctx->codec_mode == S5P_FIMV_CODEC_H263_ENC)
- s5p_mfc_set_enc_params_h263(ctx);
- else {
- mfc_err("Unknown codec for encoding (%x)\n",
- ctx->codec_mode);
- return -EINVAL;
- }
- s5p_mfc_set_shared_buffer(ctx);
- mfc_write(dev, ((S5P_FIMV_CH_SEQ_HEADER << 16) & 0x70000) |
- (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
- return 0;
-}
-
-/* Encode a single frame */
-int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- /* memory structure cur. frame */
- if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M)
- mfc_write(dev, 0, S5P_FIMV_ENC_MAP_FOR_CUR);
- else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT)
- mfc_write(dev, 3, S5P_FIMV_ENC_MAP_FOR_CUR);
- s5p_mfc_set_shared_buffer(ctx);
- mfc_write(dev, (S5P_FIMV_CH_FRAME_START << 16 & 0x70000) |
- (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
- return 0;
-}
-
-static int s5p_mfc_get_new_ctx(struct s5p_mfc_dev *dev)
-{
- unsigned long flags;
- int new_ctx;
- int cnt;
-
- spin_lock_irqsave(&dev->condlock, flags);
- new_ctx = (dev->curr_ctx + 1) % MFC_NUM_CONTEXTS;
- cnt = 0;
- while (!test_bit(new_ctx, &dev->ctx_work_bits)) {
- new_ctx = (new_ctx + 1) % MFC_NUM_CONTEXTS;
- if (++cnt > MFC_NUM_CONTEXTS) {
- /* No contexts to run */
- spin_unlock_irqrestore(&dev->condlock, flags);
- return -EAGAIN;
- }
- }
- spin_unlock_irqrestore(&dev->condlock, flags);
- return new_ctx;
-}
-
-static void s5p_mfc_run_res_change(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
-
- s5p_mfc_set_dec_stream_buffer(ctx, 0, 0, 0);
- dev->curr_ctx = ctx->num;
- s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_decode_one_frame(ctx, MFC_DEC_RES_CHANGE);
-}
-
-static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_buf *temp_vb;
- unsigned long flags;
- unsigned int index;
-
- spin_lock_irqsave(&dev->irqlock, flags);
- /* Frames are being decoded */
- if (list_empty(&ctx->src_queue)) {
- mfc_debug(2, "No src buffers\n");
- spin_unlock_irqrestore(&dev->irqlock, flags);
- return -EAGAIN;
- }
- /* Get the next source buffer */
- temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
- temp_vb->used = 1;
- s5p_mfc_set_dec_stream_buffer(ctx,
- vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), ctx->consumed_stream,
- temp_vb->b->v4l2_planes[0].bytesused);
- spin_unlock_irqrestore(&dev->irqlock, flags);
- index = temp_vb->b->v4l2_buf.index;
- dev->curr_ctx = ctx->num;
- s5p_mfc_clean_ctx_int_flags(ctx);
- if (temp_vb->b->v4l2_planes[0].bytesused == 0) {
- last_frame = MFC_DEC_LAST_FRAME;
- mfc_debug(2, "Setting ctx->state to FINISHING\n");
- ctx->state = MFCINST_FINISHING;
- }
- s5p_mfc_decode_one_frame(ctx, last_frame);
- return 0;
-}
-
-static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned long flags;
- struct s5p_mfc_buf *dst_mb;
- struct s5p_mfc_buf *src_mb;
- unsigned long src_y_addr, src_c_addr, dst_addr;
- unsigned int dst_size;
-
- spin_lock_irqsave(&dev->irqlock, flags);
- if (list_empty(&ctx->src_queue)) {
- mfc_debug(2, "no src buffers\n");
- spin_unlock_irqrestore(&dev->irqlock, flags);
- return -EAGAIN;
- }
- if (list_empty(&ctx->dst_queue)) {
- mfc_debug(2, "no dst buffers\n");
- spin_unlock_irqrestore(&dev->irqlock, flags);
- return -EAGAIN;
- }
- src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
- src_mb->used = 1;
- src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0);
- src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1);
- s5p_mfc_set_enc_frame_buffer(ctx, src_y_addr, src_c_addr);
- dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
- dst_mb->used = 1;
- dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
- dst_size = vb2_plane_size(dst_mb->b, 0);
- s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
- spin_unlock_irqrestore(&dev->irqlock, flags);
- dev->curr_ctx = ctx->num;
- s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_encode_one_frame(ctx);
- return 0;
-}
-
-static void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned long flags;
- struct s5p_mfc_buf *temp_vb;
-
- /* Initializing decoding - parsing header */
- spin_lock_irqsave(&dev->irqlock, flags);
- mfc_debug(2, "Preparing to init decoding\n");
- temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
- s5p_mfc_set_dec_desc_buffer(ctx);
- mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
- s5p_mfc_set_dec_stream_buffer(ctx,
- vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
- 0, temp_vb->b->v4l2_planes[0].bytesused);
- spin_unlock_irqrestore(&dev->irqlock, flags);
- dev->curr_ctx = ctx->num;
- s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_init_decode(ctx);
-}
-
-static void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned long flags;
- struct s5p_mfc_buf *dst_mb;
- unsigned long dst_addr;
- unsigned int dst_size;
-
- s5p_mfc_set_enc_ref_buffer(ctx);
- spin_lock_irqsave(&dev->irqlock, flags);
- dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
- dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
- dst_size = vb2_plane_size(dst_mb->b, 0);
- s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
- spin_unlock_irqrestore(&dev->irqlock, flags);
- dev->curr_ctx = ctx->num;
- s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_init_encode(ctx);
-}
-
-static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned long flags;
- struct s5p_mfc_buf *temp_vb;
- int ret;
-
- /*
- * Header was parsed now starting processing
- * First set the output frame buffers
- */
- if (ctx->capture_state != QUEUE_BUFS_MMAPED) {
- mfc_err("It seems that not all destionation buffers were "
- "mmaped\nMFC requires that all destination are mmaped "
- "before starting processing\n");
- return -EAGAIN;
- }
- spin_lock_irqsave(&dev->irqlock, flags);
- if (list_empty(&ctx->src_queue)) {
- mfc_err("Header has been deallocated in the middle of"
- " initialization\n");
- spin_unlock_irqrestore(&dev->irqlock, flags);
- return -EIO;
- }
- temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
- mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
- s5p_mfc_set_dec_stream_buffer(ctx,
- vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
- 0, temp_vb->b->v4l2_planes[0].bytesused);
- spin_unlock_irqrestore(&dev->irqlock, flags);
- dev->curr_ctx = ctx->num;
- s5p_mfc_clean_ctx_int_flags(ctx);
- ret = s5p_mfc_set_dec_frame_buffer(ctx);
- if (ret) {
- mfc_err("Failed to alloc frame mem\n");
- ctx->state = MFCINST_ERROR;
- }
- return ret;
-}
-
-/* Try running an operation on hardware */
-void s5p_mfc_try_run(struct s5p_mfc_dev *dev)
-{
- struct s5p_mfc_ctx *ctx;
- int new_ctx;
- unsigned int ret = 0;
-
- if (test_bit(0, &dev->enter_suspend)) {
- mfc_debug(1, "Entering suspend so do not schedule any jobs\n");
- return;
- }
- /* Check whether hardware is not running */
- if (test_and_set_bit(0, &dev->hw_lock) != 0) {
- /* This is perfectly ok, the scheduled ctx should wait */
- mfc_debug(1, "Couldn't lock HW\n");
- return;
- }
- /* Choose the context to run */
- new_ctx = s5p_mfc_get_new_ctx(dev);
- if (new_ctx < 0) {
- /* No contexts to run */
- if (test_and_clear_bit(0, &dev->hw_lock) == 0) {
- mfc_err("Failed to unlock hardware\n");
- return;
- }
- mfc_debug(1, "No ctx is scheduled to be run\n");
- return;
- }
- ctx = dev->ctx[new_ctx];
- /* Got context to run in ctx */
- /*
- * Last frame has already been sent to MFC.
- * Now obtaining frames from MFC buffer
- */
- s5p_mfc_clock_on();
- if (ctx->type == MFCINST_DECODER) {
- s5p_mfc_set_dec_desc_buffer(ctx);
- switch (ctx->state) {
- case MFCINST_FINISHING:
- s5p_mfc_run_dec_frame(ctx, MFC_DEC_LAST_FRAME);
- break;
- case MFCINST_RUNNING:
- ret = s5p_mfc_run_dec_frame(ctx, MFC_DEC_FRAME);
- break;
- case MFCINST_INIT:
- s5p_mfc_clean_ctx_int_flags(ctx);
- ret = s5p_mfc_open_inst_cmd(ctx);
- break;
- case MFCINST_RETURN_INST:
- s5p_mfc_clean_ctx_int_flags(ctx);
- ret = s5p_mfc_close_inst_cmd(ctx);
- break;
- case MFCINST_GOT_INST:
- s5p_mfc_run_init_dec(ctx);
- break;
- case MFCINST_HEAD_PARSED:
- ret = s5p_mfc_run_init_dec_buffers(ctx);
- mfc_debug(1, "head parsed\n");
- break;
- case MFCINST_RES_CHANGE_INIT:
- s5p_mfc_run_res_change(ctx);
- break;
- case MFCINST_RES_CHANGE_FLUSH:
- s5p_mfc_run_dec_frame(ctx, MFC_DEC_FRAME);
- break;
- case MFCINST_RES_CHANGE_END:
- mfc_debug(2, "Finished remaining frames after resolution change\n");
- ctx->capture_state = QUEUE_FREE;
- mfc_debug(2, "Will re-init the codec\n");
- s5p_mfc_run_init_dec(ctx);
- break;
- default:
- ret = -EAGAIN;
- }
- } else if (ctx->type == MFCINST_ENCODER) {
- switch (ctx->state) {
- case MFCINST_FINISHING:
- case MFCINST_RUNNING:
- ret = s5p_mfc_run_enc_frame(ctx);
- break;
- case MFCINST_INIT:
- s5p_mfc_clean_ctx_int_flags(ctx);
- ret = s5p_mfc_open_inst_cmd(ctx);
- break;
- case MFCINST_RETURN_INST:
- s5p_mfc_clean_ctx_int_flags(ctx);
- ret = s5p_mfc_close_inst_cmd(ctx);
- break;
- case MFCINST_GOT_INST:
- s5p_mfc_run_init_enc(ctx);
- break;
- default:
- ret = -EAGAIN;
- }
- } else {
- mfc_err("Invalid context type: %d\n", ctx->type);
- ret = -EAGAIN;
- }
-
- if (ret) {
- /* Free hardware lock */
- if (test_and_clear_bit(0, &dev->hw_lock) == 0)
- mfc_err("Failed to unlock hardware\n");
-
- /* This is in deed imporant, as no operation has been
- * scheduled, reduce the clock count as no one will
- * ever do this, because no interrupt related to this try_run
- * will ever come from hardware. */
- s5p_mfc_clock_off();
- }
-}
-
-
-void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq)
-{
- struct s5p_mfc_buf *b;
- int i;
-
- while (!list_empty(lh)) {
- b = list_entry(lh->next, struct s5p_mfc_buf, list);
- for (i = 0; i < b->b->num_planes; i++)
- vb2_set_plane_payload(b->b, i, 0);
- vb2_buffer_done(b->b, VB2_BUF_STATE_ERROR);
- list_del(&b->list);
- }
-}
-
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_opr.h b/drivers/media/video/s5p-mfc/s5p_mfc_opr.h
deleted file mode 100644
index 5932d1c782c..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_opr.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * drivers/media/video/samsung/mfc5/s5p_mfc_opr.h
- *
- * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
- * Contains declarations of hw related functions.
- *
- * Kamil Debski, Copyright (C) 2011 Samsung Electronics
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef S5P_MFC_OPR_H_
-#define S5P_MFC_OPR_H_
-
-#include "s5p_mfc_common.h"
-
-int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx);
-int s5p_mfc_init_encode(struct s5p_mfc_ctx *mfc_ctx);
-
-/* Decoding functions */
-int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx);
-int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr,
- unsigned int start_num_byte,
- unsigned int buf_size);
-
-/* Encoding functions */
-void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
- unsigned long y_addr, unsigned long c_addr);
-int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx,
- unsigned long addr, unsigned int size);
-void s5p_mfc_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
- unsigned long *y_addr, unsigned long *c_addr);
-int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *mfc_ctx);
-
-int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx,
- enum s5p_mfc_decode_arg last_frame);
-int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *mfc_ctx);
-
-/* Memory allocation */
-int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx);
-void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx);
-void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx);
-
-int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx);
-void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx);
-
-int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx);
-void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx);
-
-void s5p_mfc_try_run(struct s5p_mfc_dev *dev);
-void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
-
-#define s5p_mfc_get_dspl_y_adr() (readl(dev->regs_base + \
- S5P_FIMV_SI_DISPLAY_Y_ADR) << \
- MFC_OFFSET_SHIFT)
-#define s5p_mfc_get_dec_y_adr() (readl(dev->regs_base + \
- S5P_FIMV_SI_DECODE_Y_ADR) << \
- MFC_OFFSET_SHIFT)
-#define s5p_mfc_get_dspl_status() readl(dev->regs_base + \
- S5P_FIMV_SI_DISPLAY_STATUS)
-#define s5p_mfc_get_dec_status() readl(dev->regs_base + \
- S5P_FIMV_SI_DECODE_STATUS)
-#define s5p_mfc_get_frame_type() (readl(dev->regs_base + \
- S5P_FIMV_DECODE_FRAME_TYPE) \
- & S5P_FIMV_DECODE_FRAME_MASK)
-#define s5p_mfc_get_consumed_stream() readl(dev->regs_base + \
- S5P_FIMV_SI_CONSUMED_BYTES)
-#define s5p_mfc_get_int_reason() (readl(dev->regs_base + \
- S5P_FIMV_RISC2HOST_CMD) & \
- S5P_FIMV_RISC2HOST_CMD_MASK)
-#define s5p_mfc_get_int_err() readl(dev->regs_base + \
- S5P_FIMV_RISC2HOST_ARG2)
-#define s5p_mfc_err_dec(x) (((x) & S5P_FIMV_ERR_DEC_MASK) >> \
- S5P_FIMV_ERR_DEC_SHIFT)
-#define s5p_mfc_err_dspl(x) (((x) & S5P_FIMV_ERR_DSPL_MASK) >> \
- S5P_FIMV_ERR_DSPL_SHIFT)
-#define s5p_mfc_get_img_width() readl(dev->regs_base + \
- S5P_FIMV_SI_HRESOL)
-#define s5p_mfc_get_img_height() readl(dev->regs_base + \
- S5P_FIMV_SI_VRESOL)
-#define s5p_mfc_get_dpb_count() readl(dev->regs_base + \
- S5P_FIMV_SI_BUF_NUMBER)
-#define s5p_mfc_get_inst_no() readl(dev->regs_base + \
- S5P_FIMV_RISC2HOST_ARG1)
-#define s5p_mfc_get_enc_strm_size() readl(dev->regs_base + \
- S5P_FIMV_ENC_SI_STRM_SIZE)
-#define s5p_mfc_get_enc_slice_type() readl(dev->regs_base + \
- S5P_FIMV_ENC_SI_SLICE_TYPE)
-
-#endif /* S5P_MFC_OPR_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_pm.c b/drivers/media/video/s5p-mfc/s5p_mfc_pm.c
deleted file mode 100644
index 738a607be43..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_pm.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_pm.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#ifdef CONFIG_PM_RUNTIME
-#include <linux/pm_runtime.h>
-#endif
-#include "s5p_mfc_common.h"
-#include "s5p_mfc_debug.h"
-#include "s5p_mfc_pm.h"
-
-#define MFC_CLKNAME "sclk_mfc"
-#define MFC_GATE_CLK_NAME "mfc"
-
-#define CLK_DEBUG
-
-static struct s5p_mfc_pm *pm;
-static struct s5p_mfc_dev *p_dev;
-
-#ifdef CLK_DEBUG
-atomic_t clk_ref;
-#endif
-
-int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
-{
- int ret = 0;
-
- pm = &dev->pm;
- p_dev = dev;
- pm->clock_gate = clk_get(&dev->plat_dev->dev, MFC_GATE_CLK_NAME);
- if (IS_ERR(pm->clock_gate)) {
- mfc_err("Failed to get clock-gating control\n");
- ret = PTR_ERR(pm->clock_gate);
- goto err_g_ip_clk;
- }
-
- ret = clk_prepare(pm->clock_gate);
- if (ret) {
- mfc_err("Failed to preapre clock-gating control\n");
- goto err_p_ip_clk;
- }
-
- pm->clock = clk_get(&dev->plat_dev->dev, MFC_CLKNAME);
- if (IS_ERR(pm->clock)) {
- mfc_err("Failed to get MFC clock\n");
- ret = PTR_ERR(pm->clock);
- goto err_g_ip_clk_2;
- }
-
- ret = clk_prepare(pm->clock);
- if (ret) {
- mfc_err("Failed to prepare MFC clock\n");
- goto err_p_ip_clk_2;
- }
-
- atomic_set(&pm->power, 0);
-#ifdef CONFIG_PM_RUNTIME
- pm->device = &dev->plat_dev->dev;
- pm_runtime_enable(pm->device);
-#endif
-#ifdef CLK_DEBUG
- atomic_set(&clk_ref, 0);
-#endif
- return 0;
-err_p_ip_clk_2:
- clk_put(pm->clock);
-err_g_ip_clk_2:
- clk_unprepare(pm->clock_gate);
-err_p_ip_clk:
- clk_put(pm->clock_gate);
-err_g_ip_clk:
- return ret;
-}
-
-void s5p_mfc_final_pm(struct s5p_mfc_dev *dev)
-{
- clk_unprepare(pm->clock_gate);
- clk_put(pm->clock_gate);
- clk_unprepare(pm->clock);
- clk_put(pm->clock);
-#ifdef CONFIG_PM_RUNTIME
- pm_runtime_disable(pm->device);
-#endif
-}
-
-int s5p_mfc_clock_on(void)
-{
- int ret;
-#ifdef CLK_DEBUG
- atomic_inc(&clk_ref);
- mfc_debug(3, "+ %d", atomic_read(&clk_ref));
-#endif
- ret = clk_enable(pm->clock_gate);
- return ret;
-}
-
-void s5p_mfc_clock_off(void)
-{
-#ifdef CLK_DEBUG
- atomic_dec(&clk_ref);
- mfc_debug(3, "- %d", atomic_read(&clk_ref));
-#endif
- clk_disable(pm->clock_gate);
-}
-
-int s5p_mfc_power_on(void)
-{
-#ifdef CONFIG_PM_RUNTIME
- return pm_runtime_get_sync(pm->device);
-#else
- atomic_set(&pm->power, 1);
- return 0;
-#endif
-}
-
-int s5p_mfc_power_off(void)
-{
-#ifdef CONFIG_PM_RUNTIME
- return pm_runtime_put_sync(pm->device);
-#else
- atomic_set(&pm->power, 0);
- return 0;
-#endif
-}
-
-
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_pm.h b/drivers/media/video/s5p-mfc/s5p_mfc_pm.h
deleted file mode 100644
index 5107914f27e..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_pm.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_pm.h
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef S5P_MFC_PM_H_
-#define S5P_MFC_PM_H_
-
-int s5p_mfc_init_pm(struct s5p_mfc_dev *dev);
-void s5p_mfc_final_pm(struct s5p_mfc_dev *dev);
-
-int s5p_mfc_clock_on(void);
-void s5p_mfc_clock_off(void);
-int s5p_mfc_power_on(void);
-int s5p_mfc_power_off(void);
-
-#endif /* S5P_MFC_PM_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_shm.c b/drivers/media/video/s5p-mfc/s5p_mfc_shm.c
deleted file mode 100644
index 91fdbac8c37..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_shm.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_shm.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifdef CONFIG_ARCH_EXYNOS4
-#include <linux/dma-mapping.h>
-#endif
-#include <linux/io.h>
-#include "s5p_mfc_common.h"
-#include "s5p_mfc_debug.h"
-
-int s5p_mfc_init_shm(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- void *shm_alloc_ctx = dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
-
- ctx->shm_alloc = vb2_dma_contig_memops.alloc(shm_alloc_ctx,
- SHARED_BUF_SIZE);
- if (IS_ERR(ctx->shm_alloc)) {
- mfc_err("failed to allocate shared memory\n");
- return PTR_ERR(ctx->shm_alloc);
- }
- /* shm_ofs only keeps the offset from base (port a) */
- ctx->shm_ofs = s5p_mfc_mem_cookie(shm_alloc_ctx, ctx->shm_alloc)
- - dev->bank1;
- BUG_ON(ctx->shm_ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
- ctx->shm = vb2_dma_contig_memops.vaddr(ctx->shm_alloc);
- if (!ctx->shm) {
- vb2_dma_contig_memops.put(ctx->shm_alloc);
- ctx->shm_ofs = 0;
- ctx->shm_alloc = NULL;
- mfc_err("failed to virt addr of shared memory\n");
- return -ENOMEM;
- }
- memset((void *)ctx->shm, 0, SHARED_BUF_SIZE);
- wmb();
- return 0;
-}
-
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_shm.h b/drivers/media/video/s5p-mfc/s5p_mfc_shm.h
deleted file mode 100644
index cf962a46627..00000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_shm.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_shm.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef S5P_MFC_SHM_H_
-#define S5P_MFC_SHM_H_
-
-enum MFC_SHM_OFS {
- EXTENEDED_DECODE_STATUS = 0x00, /* D */
- SET_FRAME_TAG = 0x04, /* D */
- GET_FRAME_TAG_TOP = 0x08, /* D */
- GET_FRAME_TAG_BOT = 0x0C, /* D */
- PIC_TIME_TOP = 0x10, /* D */
- PIC_TIME_BOT = 0x14, /* D */
- START_BYTE_NUM = 0x18, /* D */
-
- CROP_INFO_H = 0x20, /* D */
- CROP_INFO_V = 0x24, /* D */
- EXT_ENC_CONTROL = 0x28, /* E */
- ENC_PARAM_CHANGE = 0x2C, /* E */
- RC_VOP_TIMING = 0x30, /* E, MPEG4 */
- HEC_PERIOD = 0x34, /* E, MPEG4 */
- METADATA_ENABLE = 0x38, /* C */
- METADATA_STATUS = 0x3C, /* C */
- METADATA_DISPLAY_INDEX = 0x40, /* C */
- EXT_METADATA_START_ADDR = 0x44, /* C */
- PUT_EXTRADATA = 0x48, /* C */
- EXTRADATA_ADDR = 0x4C, /* C */
-
- ALLOC_LUMA_DPB_SIZE = 0x64, /* D */
- ALLOC_CHROMA_DPB_SIZE = 0x68, /* D */
- ALLOC_MV_SIZE = 0x6C, /* D */
- P_B_FRAME_QP = 0x70, /* E */
- SAMPLE_ASPECT_RATIO_IDC = 0x74, /* E, H.264, depend on
- ASPECT_RATIO_VUI_ENABLE in EXT_ENC_CONTROL */
- EXTENDED_SAR = 0x78, /* E, H.264, depned on
- ASPECT_RATIO_VUI_ENABLE in EXT_ENC_CONTROL */
- DISP_PIC_PROFILE = 0x7C, /* D */
- FLUSH_CMD_TYPE = 0x80, /* C */
- FLUSH_CMD_INBUF1 = 0x84, /* C */
- FLUSH_CMD_INBUF2 = 0x88, /* C */
- FLUSH_CMD_OUTBUF = 0x8C, /* E */
- NEW_RC_BIT_RATE = 0x90, /* E, format as RC_BIT_RATE(0xC5A8)
- depend on RC_BIT_RATE_CHANGE in ENC_PARAM_CHANGE */
- NEW_RC_FRAME_RATE = 0x94, /* E, format as RC_FRAME_RATE(0xD0D0)
- depend on RC_FRAME_RATE_CHANGE in ENC_PARAM_CHANGE */
- NEW_I_PERIOD = 0x98, /* E, format as I_FRM_CTRL(0xC504)
- depend on I_PERIOD_CHANGE in ENC_PARAM_CHANGE */
- H264_I_PERIOD = 0x9C, /* E, H.264, open GOP */
- RC_CONTROL_CONFIG = 0xA0, /* E */
- BATCH_INPUT_ADDR = 0xA4, /* E */
- BATCH_OUTPUT_ADDR = 0xA8, /* E */
- BATCH_OUTPUT_SIZE = 0xAC, /* E */
- MIN_LUMA_DPB_SIZE = 0xB0, /* D */
- DEVICE_FORMAT_ID = 0xB4, /* C */
- H264_POC_TYPE = 0xB8, /* D */
- MIN_CHROMA_DPB_SIZE = 0xBC, /* D */
- DISP_PIC_FRAME_TYPE = 0xC0, /* D */
- FREE_LUMA_DPB = 0xC4, /* D, VC1 MPEG4 */
- ASPECT_RATIO_INFO = 0xC8, /* D, MPEG4 */
- EXTENDED_PAR = 0xCC, /* D, MPEG4 */
- DBG_HISTORY_INPUT0 = 0xD0, /* C */
- DBG_HISTORY_INPUT1 = 0xD4, /* C */
- DBG_HISTORY_OUTPUT = 0xD8, /* C */
- HIERARCHICAL_P_QP = 0xE0, /* E, H.264 */
-};
-
-int s5p_mfc_init_shm(struct s5p_mfc_ctx *ctx);
-
-#define s5p_mfc_write_shm(ctx, x, ofs) \
- do { \
- writel(x, (ctx->shm + ofs)); \
- wmb(); \
- } while (0)
-
-static inline u32 s5p_mfc_read_shm(struct s5p_mfc_ctx *ctx, unsigned int ofs)
-{
- rmb();
- return readl(ctx->shm + ofs);
-}
-
-#endif /* S5P_MFC_SHM_H_ */
diff --git a/drivers/media/video/s5p-tv/Kconfig b/drivers/media/video/s5p-tv/Kconfig
deleted file mode 100644
index f248b285672..00000000000
--- a/drivers/media/video/s5p-tv/Kconfig
+++ /dev/null
@@ -1,86 +0,0 @@
-# drivers/media/video/s5p-tv/Kconfig
-#
-# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
-# http://www.samsung.com/
-# Tomasz Stanislawski <t.stanislaws@samsung.com>
-#
-# Licensed under GPL
-
-config VIDEO_SAMSUNG_S5P_TV
- bool "Samsung TV driver for S5P platform (experimental)"
- depends on PLAT_S5P && PM_RUNTIME
- depends on EXPERIMENTAL
- default n
- ---help---
- Say Y here to enable selecting the TV output devices for
- Samsung S5P platform.
-
-if VIDEO_SAMSUNG_S5P_TV
-
-config VIDEO_SAMSUNG_S5P_HDMI
- tristate "Samsung HDMI Driver"
- depends on VIDEO_V4L2
- depends on VIDEO_SAMSUNG_S5P_TV
- select VIDEO_SAMSUNG_S5P_HDMIPHY
- help
- Say Y here if you want support for the HDMI output
- interface in S5P Samsung SoC. The driver can be compiled
- as module. It is an auxiliary driver, that exposes a V4L2
- subdev for use by other drivers. This driver requires
- hdmiphy driver to work correctly.
-
-config VIDEO_SAMSUNG_S5P_HDMI_DEBUG
- bool "Enable debug for HDMI Driver"
- depends on VIDEO_SAMSUNG_S5P_HDMI
- default n
- help
- Enables debugging for HDMI driver.
-
-config VIDEO_SAMSUNG_S5P_HDMIPHY
- tristate "Samsung HDMIPHY Driver"
- depends on VIDEO_DEV && VIDEO_V4L2 && I2C
- depends on VIDEO_SAMSUNG_S5P_TV
- help
- Say Y here if you want support for the physical HDMI
- interface in S5P Samsung SoC. The driver can be compiled
- as module. It is an I2C driver, that exposes a V4L2
- subdev for use by other drivers.
-
-config VIDEO_SAMSUNG_S5P_SII9234
- tristate "Samsung SII9234 Driver"
- depends on VIDEO_DEV && VIDEO_V4L2 && I2C
- depends on VIDEO_SAMSUNG_S5P_TV
- help
- Say Y here if you want support for the MHL interface
- in S5P Samsung SoC. The driver can be compiled
- as module. It is an I2C driver, that exposes a V4L2
- subdev for use by other drivers.
-
-config VIDEO_SAMSUNG_S5P_SDO
- tristate "Samsung Analog TV Driver"
- depends on VIDEO_DEV && VIDEO_V4L2
- depends on VIDEO_SAMSUNG_S5P_TV
- help
- Say Y here if you want support for the analog TV output
- interface in S5P Samsung SoC. The driver can be compiled
- as module. It is an auxiliary driver, that exposes a V4L2
- subdev for use by other drivers. This driver requires
- hdmiphy driver to work correctly.
-
-config VIDEO_SAMSUNG_S5P_MIXER
- tristate "Samsung Mixer and Video Processor Driver"
- depends on VIDEO_DEV && VIDEO_V4L2
- depends on VIDEO_SAMSUNG_S5P_TV
- select VIDEOBUF2_DMA_CONTIG
- help
- Say Y here if you want support for the Mixer in Samsung S5P SoCs.
- This device produce image data to one of output interfaces.
-
-config VIDEO_SAMSUNG_S5P_MIXER_DEBUG
- bool "Enable debug for Mixer Driver"
- depends on VIDEO_SAMSUNG_S5P_MIXER
- default n
- help
- Enables debugging for Mixer driver.
-
-endif # VIDEO_SAMSUNG_S5P_TV
diff --git a/drivers/media/video/s5p-tv/Makefile b/drivers/media/video/s5p-tv/Makefile
deleted file mode 100644
index f49e756a2fd..00000000000
--- a/drivers/media/video/s5p-tv/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# drivers/media/video/samsung/tvout/Makefile
-#
-# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
-# http://www.samsung.com/
-# Tomasz Stanislawski <t.stanislaws@samsung.com>
-#
-# Licensed under GPL
-
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_HDMIPHY) += s5p-hdmiphy.o
-s5p-hdmiphy-y += hdmiphy_drv.o
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_SII9234) += s5p-sii9234.o
-s5p-sii9234-y += sii9234_drv.o
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_HDMI) += s5p-hdmi.o
-s5p-hdmi-y += hdmi_drv.o
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_SDO) += s5p-sdo.o
-s5p-sdo-y += sdo_drv.o
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MIXER) += s5p-mixer.o
-s5p-mixer-y += mixer_drv.o mixer_video.o mixer_reg.o mixer_grp_layer.o mixer_vp_layer.o
-
diff --git a/drivers/media/video/s5p-tv/hdmi_drv.c b/drivers/media/video/s5p-tv/hdmi_drv.c
deleted file mode 100644
index 20cb6eef297..00000000000
--- a/drivers/media/video/s5p-tv/hdmi_drv.c
+++ /dev/null
@@ -1,1007 +0,0 @@
-/*
- * Samsung HDMI interface driver
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *
- * Tomasz Stanislawski, <t.stanislaws@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundiation. either version 2 of the License,
- * or (at your option) any later version
- */
-
-#ifdef CONFIG_VIDEO_SAMSUNG_S5P_HDMI_DEBUG
-#define DEBUG
-#endif
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <media/v4l2-subdev.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/delay.h>
-#include <linux/bug.h>
-#include <linux/pm_runtime.h>
-#include <linux/clk.h>
-#include <linux/regulator/consumer.h>
-
-#include <media/s5p_hdmi.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-device.h>
-
-#include "regs-hdmi.h"
-
-MODULE_AUTHOR("Tomasz Stanislawski, <t.stanislaws@samsung.com>");
-MODULE_DESCRIPTION("Samsung HDMI");
-MODULE_LICENSE("GPL");
-
-/* default preset configured on probe */
-#define HDMI_DEFAULT_PRESET V4L2_DV_480P59_94
-
-struct hdmi_pulse {
- u32 beg;
- u32 end;
-};
-
-struct hdmi_timings {
- struct hdmi_pulse hact;
- u32 hsyn_pol; /* 0 - high, 1 - low */
- struct hdmi_pulse hsyn;
- u32 interlaced;
- struct hdmi_pulse vact[2];
- u32 vsyn_pol; /* 0 - high, 1 - low */
- u32 vsyn_off;
- struct hdmi_pulse vsyn[2];
-};
-
-struct hdmi_resources {
- struct clk *hdmi;
- struct clk *sclk_hdmi;
- struct clk *sclk_pixel;
- struct clk *sclk_hdmiphy;
- struct clk *hdmiphy;
- struct regulator_bulk_data *regul_bulk;
- int regul_count;
-};
-
-struct hdmi_device {
- /** base address of HDMI registers */
- void __iomem *regs;
- /** HDMI interrupt */
- unsigned int irq;
- /** pointer to device parent */
- struct device *dev;
- /** subdev generated by HDMI device */
- struct v4l2_subdev sd;
- /** V4L2 device structure */
- struct v4l2_device v4l2_dev;
- /** subdev of HDMIPHY interface */
- struct v4l2_subdev *phy_sd;
- /** subdev of MHL interface */
- struct v4l2_subdev *mhl_sd;
- /** configuration of current graphic mode */
- const struct hdmi_timings *cur_conf;
- /** flag indicating that timings are dirty */
- int cur_conf_dirty;
- /** current preset */
- u32 cur_preset;
- /** other resources */
- struct hdmi_resources res;
-};
-
-static struct platform_device_id hdmi_driver_types[] = {
- {
- .name = "s5pv210-hdmi",
- }, {
- .name = "exynos4-hdmi",
- }, {
- /* end node */
- }
-};
-
-static const struct v4l2_subdev_ops hdmi_sd_ops;
-
-static struct hdmi_device *sd_to_hdmi_dev(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct hdmi_device, sd);
-}
-
-static inline
-void hdmi_write(struct hdmi_device *hdev, u32 reg_id, u32 value)
-{
- writel(value, hdev->regs + reg_id);
-}
-
-static inline
-void hdmi_write_mask(struct hdmi_device *hdev, u32 reg_id, u32 value, u32 mask)
-{
- u32 old = readl(hdev->regs + reg_id);
- value = (value & mask) | (old & ~mask);
- writel(value, hdev->regs + reg_id);
-}
-
-static inline
-void hdmi_writeb(struct hdmi_device *hdev, u32 reg_id, u8 value)
-{
- writeb(value, hdev->regs + reg_id);
-}
-
-static inline
-void hdmi_writebn(struct hdmi_device *hdev, u32 reg_id, int n, u32 value)
-{
- switch (n) {
- default:
- writeb(value >> 24, hdev->regs + reg_id + 12);
- case 3:
- writeb(value >> 16, hdev->regs + reg_id + 8);
- case 2:
- writeb(value >> 8, hdev->regs + reg_id + 4);
- case 1:
- writeb(value >> 0, hdev->regs + reg_id + 0);
- }
-}
-
-static inline u32 hdmi_read(struct hdmi_device *hdev, u32 reg_id)
-{
- return readl(hdev->regs + reg_id);
-}
-
-static irqreturn_t hdmi_irq_handler(int irq, void *dev_data)
-{
- struct hdmi_device *hdev = dev_data;
- u32 intc_flag;
-
- (void)irq;
- intc_flag = hdmi_read(hdev, HDMI_INTC_FLAG);
- /* clearing flags for HPD plug/unplug */
- if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
- printk(KERN_INFO "unplugged\n");
- hdmi_write_mask(hdev, HDMI_INTC_FLAG, ~0,
- HDMI_INTC_FLAG_HPD_UNPLUG);
- }
- if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
- printk(KERN_INFO "plugged\n");
- hdmi_write_mask(hdev, HDMI_INTC_FLAG, ~0,
- HDMI_INTC_FLAG_HPD_PLUG);
- }
-
- return IRQ_HANDLED;
-}
-
-static void hdmi_reg_init(struct hdmi_device *hdev)
-{
- /* enable HPD interrupts */
- hdmi_write_mask(hdev, HDMI_INTC_CON, ~0, HDMI_INTC_EN_GLOBAL |
- HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
- /* choose DVI mode */
- hdmi_write_mask(hdev, HDMI_MODE_SEL,
- HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
- hdmi_write_mask(hdev, HDMI_CON_2, ~0,
- HDMI_DVI_PERAMBLE_EN | HDMI_DVI_BAND_EN);
- /* disable bluescreen */
- hdmi_write_mask(hdev, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
- /* choose bluescreen (fecal) color */
- hdmi_writeb(hdev, HDMI_BLUE_SCREEN_0, 0x12);
- hdmi_writeb(hdev, HDMI_BLUE_SCREEN_1, 0x34);
- hdmi_writeb(hdev, HDMI_BLUE_SCREEN_2, 0x56);
-}
-
-static void hdmi_timing_apply(struct hdmi_device *hdev,
- const struct hdmi_timings *t)
-{
- /* setting core registers */
- hdmi_writebn(hdev, HDMI_H_BLANK_0, 2, t->hact.beg);
- hdmi_writebn(hdev, HDMI_H_SYNC_GEN_0, 3,
- (t->hsyn_pol << 20) | (t->hsyn.end << 10) | t->hsyn.beg);
- hdmi_writeb(hdev, HDMI_VSYNC_POL, t->vsyn_pol);
- hdmi_writebn(hdev, HDMI_V_BLANK_0, 3,
- (t->vact[0].beg << 11) | t->vact[0].end);
- hdmi_writebn(hdev, HDMI_V_SYNC_GEN_1_0, 3,
- (t->vsyn[0].beg << 12) | t->vsyn[0].end);
- if (t->interlaced) {
- u32 vsyn_trans = t->hsyn.beg + t->vsyn_off;
-
- hdmi_writeb(hdev, HDMI_INT_PRO_MODE, 1);
- hdmi_writebn(hdev, HDMI_H_V_LINE_0, 3,
- (t->hact.end << 12) | t->vact[1].end);
- hdmi_writebn(hdev, HDMI_V_BLANK_F_0, 3,
- (t->vact[1].end << 11) | t->vact[1].beg);
- hdmi_writebn(hdev, HDMI_V_SYNC_GEN_2_0, 3,
- (t->vsyn[1].beg << 12) | t->vsyn[1].end);
- hdmi_writebn(hdev, HDMI_V_SYNC_GEN_3_0, 3,
- (vsyn_trans << 12) | vsyn_trans);
- } else {
- hdmi_writeb(hdev, HDMI_INT_PRO_MODE, 0);
- hdmi_writebn(hdev, HDMI_H_V_LINE_0, 3,
- (t->hact.end << 12) | t->vact[0].end);
- }
-
- /* Timing generator registers */
- hdmi_writebn(hdev, HDMI_TG_H_FSZ_L, 2, t->hact.end);
- hdmi_writebn(hdev, HDMI_TG_HACT_ST_L, 2, t->hact.beg);
- hdmi_writebn(hdev, HDMI_TG_HACT_SZ_L, 2, t->hact.end - t->hact.beg);
- hdmi_writebn(hdev, HDMI_TG_VSYNC_L, 2, t->vsyn[0].beg);
- hdmi_writebn(hdev, HDMI_TG_VACT_ST_L, 2, t->vact[0].beg);
- hdmi_writebn(hdev, HDMI_TG_VACT_SZ_L, 2,
- t->vact[0].end - t->vact[0].beg);
- hdmi_writebn(hdev, HDMI_TG_VSYNC_TOP_HDMI_L, 2, t->vsyn[0].beg);
- hdmi_writebn(hdev, HDMI_TG_FIELD_TOP_HDMI_L, 2, t->vsyn[0].beg);
- if (t->interlaced) {
- hdmi_write_mask(hdev, HDMI_TG_CMD, ~0, HDMI_TG_FIELD_EN);
- hdmi_writebn(hdev, HDMI_TG_V_FSZ_L, 2, t->vact[1].end);
- hdmi_writebn(hdev, HDMI_TG_VSYNC2_L, 2, t->vsyn[1].beg);
- hdmi_writebn(hdev, HDMI_TG_FIELD_CHG_L, 2, t->vact[0].end);
- hdmi_writebn(hdev, HDMI_TG_VACT_ST2_L, 2, t->vact[1].beg);
- hdmi_writebn(hdev, HDMI_TG_VSYNC_BOT_HDMI_L, 2, t->vsyn[1].beg);
- hdmi_writebn(hdev, HDMI_TG_FIELD_BOT_HDMI_L, 2, t->vsyn[1].beg);
- } else {
- hdmi_write_mask(hdev, HDMI_TG_CMD, 0, HDMI_TG_FIELD_EN);
- hdmi_writebn(hdev, HDMI_TG_V_FSZ_L, 2, t->vact[0].end);
- }
-}
-
-static int hdmi_conf_apply(struct hdmi_device *hdmi_dev)
-{
- struct device *dev = hdmi_dev->dev;
- const struct hdmi_timings *conf = hdmi_dev->cur_conf;
- struct v4l2_dv_preset preset;
- int ret;
-
- dev_dbg(dev, "%s\n", __func__);
-
- /* skip if conf is already synchronized with HW */
- if (!hdmi_dev->cur_conf_dirty)
- return 0;
-
- /* reset hdmiphy */
- hdmi_write_mask(hdmi_dev, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
- mdelay(10);
- hdmi_write_mask(hdmi_dev, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
- mdelay(10);
-
- /* configure presets */
- preset.preset = hdmi_dev->cur_preset;
- ret = v4l2_subdev_call(hdmi_dev->phy_sd, video, s_dv_preset, &preset);
- if (ret) {
- dev_err(dev, "failed to set preset (%u)\n", preset.preset);
- return ret;
- }
-
- /* resetting HDMI core */
- hdmi_write_mask(hdmi_dev, HDMI_CORE_RSTOUT, 0, HDMI_CORE_SW_RSTOUT);
- mdelay(10);
- hdmi_write_mask(hdmi_dev, HDMI_CORE_RSTOUT, ~0, HDMI_CORE_SW_RSTOUT);
- mdelay(10);
-
- hdmi_reg_init(hdmi_dev);
-
- /* setting core registers */
- hdmi_timing_apply(hdmi_dev, conf);
-
- hdmi_dev->cur_conf_dirty = 0;
-
- return 0;
-}
-
-static void hdmi_dumpregs(struct hdmi_device *hdev, char *prefix)
-{
-#define DUMPREG(reg_id) \
- dev_dbg(hdev->dev, "%s:" #reg_id " = %08x\n", prefix, \
- readl(hdev->regs + reg_id))
-
- dev_dbg(hdev->dev, "%s: ---- CONTROL REGISTERS ----\n", prefix);
- DUMPREG(HDMI_INTC_FLAG);
- DUMPREG(HDMI_INTC_CON);
- DUMPREG(HDMI_HPD_STATUS);
- DUMPREG(HDMI_PHY_RSTOUT);
- DUMPREG(HDMI_PHY_VPLL);
- DUMPREG(HDMI_PHY_CMU);
- DUMPREG(HDMI_CORE_RSTOUT);
-
- dev_dbg(hdev->dev, "%s: ---- CORE REGISTERS ----\n", prefix);
- DUMPREG(HDMI_CON_0);
- DUMPREG(HDMI_CON_1);
- DUMPREG(HDMI_CON_2);
- DUMPREG(HDMI_SYS_STATUS);
- DUMPREG(HDMI_PHY_STATUS);
- DUMPREG(HDMI_STATUS_EN);
- DUMPREG(HDMI_HPD);
- DUMPREG(HDMI_MODE_SEL);
- DUMPREG(HDMI_HPD_GEN);
- DUMPREG(HDMI_DC_CONTROL);
- DUMPREG(HDMI_VIDEO_PATTERN_GEN);
-
- dev_dbg(hdev->dev, "%s: ---- CORE SYNC REGISTERS ----\n", prefix);
- DUMPREG(HDMI_H_BLANK_0);
- DUMPREG(HDMI_H_BLANK_1);
- DUMPREG(HDMI_V_BLANK_0);
- DUMPREG(HDMI_V_BLANK_1);
- DUMPREG(HDMI_V_BLANK_2);
- DUMPREG(HDMI_H_V_LINE_0);
- DUMPREG(HDMI_H_V_LINE_1);
- DUMPREG(HDMI_H_V_LINE_2);
- DUMPREG(HDMI_VSYNC_POL);
- DUMPREG(HDMI_INT_PRO_MODE);
- DUMPREG(HDMI_V_BLANK_F_0);
- DUMPREG(HDMI_V_BLANK_F_1);
- DUMPREG(HDMI_V_BLANK_F_2);
- DUMPREG(HDMI_H_SYNC_GEN_0);
- DUMPREG(HDMI_H_SYNC_GEN_1);
- DUMPREG(HDMI_H_SYNC_GEN_2);
- DUMPREG(HDMI_V_SYNC_GEN_1_0);
- DUMPREG(HDMI_V_SYNC_GEN_1_1);
- DUMPREG(HDMI_V_SYNC_GEN_1_2);
- DUMPREG(HDMI_V_SYNC_GEN_2_0);
- DUMPREG(HDMI_V_SYNC_GEN_2_1);
- DUMPREG(HDMI_V_SYNC_GEN_2_2);
- DUMPREG(HDMI_V_SYNC_GEN_3_0);
- DUMPREG(HDMI_V_SYNC_GEN_3_1);
- DUMPREG(HDMI_V_SYNC_GEN_3_2);
-
- dev_dbg(hdev->dev, "%s: ---- TG REGISTERS ----\n", prefix);
- DUMPREG(HDMI_TG_CMD);
- DUMPREG(HDMI_TG_H_FSZ_L);
- DUMPREG(HDMI_TG_H_FSZ_H);
- DUMPREG(HDMI_TG_HACT_ST_L);
- DUMPREG(HDMI_TG_HACT_ST_H);
- DUMPREG(HDMI_TG_HACT_SZ_L);
- DUMPREG(HDMI_TG_HACT_SZ_H);
- DUMPREG(HDMI_TG_V_FSZ_L);
- DUMPREG(HDMI_TG_V_FSZ_H);
- DUMPREG(HDMI_TG_VSYNC_L);
- DUMPREG(HDMI_TG_VSYNC_H);
- DUMPREG(HDMI_TG_VSYNC2_L);
- DUMPREG(HDMI_TG_VSYNC2_H);
- DUMPREG(HDMI_TG_VACT_ST_L);
- DUMPREG(HDMI_TG_VACT_ST_H);
- DUMPREG(HDMI_TG_VACT_SZ_L);
- DUMPREG(HDMI_TG_VACT_SZ_H);
- DUMPREG(HDMI_TG_FIELD_CHG_L);
- DUMPREG(HDMI_TG_FIELD_CHG_H);
- DUMPREG(HDMI_TG_VACT_ST2_L);
- DUMPREG(HDMI_TG_VACT_ST2_H);
- DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
- DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
- DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
- DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
- DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
- DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
- DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
- DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
-#undef DUMPREG
-}
-
-static const struct hdmi_timings hdmi_timings_480p = {
- .hact = { .beg = 138, .end = 858 },
- .hsyn_pol = 1,
- .hsyn = { .beg = 16, .end = 16 + 62 },
- .interlaced = 0,
- .vact[0] = { .beg = 42 + 3, .end = 522 + 3 },
- .vsyn_pol = 1,
- .vsyn[0] = { .beg = 6 + 3, .end = 12 + 3},
-};
-
-static const struct hdmi_timings hdmi_timings_576p50 = {
- .hact = { .beg = 144, .end = 864 },
- .hsyn_pol = 1,
- .hsyn = { .beg = 12, .end = 12 + 64 },
- .interlaced = 0,
- .vact[0] = { .beg = 44 + 5, .end = 620 + 5 },
- .vsyn_pol = 1,
- .vsyn[0] = { .beg = 0 + 5, .end = 5 + 5},
-};
-
-static const struct hdmi_timings hdmi_timings_720p60 = {
- .hact = { .beg = 370, .end = 1650 },
- .hsyn_pol = 0,
- .hsyn = { .beg = 110, .end = 110 + 40 },
- .interlaced = 0,
- .vact[0] = { .beg = 25 + 5, .end = 745 + 5 },
- .vsyn_pol = 0,
- .vsyn[0] = { .beg = 0 + 5, .end = 5 + 5},
-};
-
-static const struct hdmi_timings hdmi_timings_720p50 = {
- .hact = { .beg = 700, .end = 1980 },
- .hsyn_pol = 0,
- .hsyn = { .beg = 440, .end = 440 + 40 },
- .interlaced = 0,
- .vact[0] = { .beg = 25 + 5, .end = 745 + 5 },
- .vsyn_pol = 0,
- .vsyn[0] = { .beg = 0 + 5, .end = 5 + 5},
-};
-
-static const struct hdmi_timings hdmi_timings_1080p24 = {
- .hact = { .beg = 830, .end = 2750 },
- .hsyn_pol = 0,
- .hsyn = { .beg = 638, .end = 638 + 44 },
- .interlaced = 0,
- .vact[0] = { .beg = 41 + 4, .end = 1121 + 4 },
- .vsyn_pol = 0,
- .vsyn[0] = { .beg = 0 + 4, .end = 5 + 4},
-};
-
-static const struct hdmi_timings hdmi_timings_1080p60 = {
- .hact = { .beg = 280, .end = 2200 },
- .hsyn_pol = 0,
- .hsyn = { .beg = 88, .end = 88 + 44 },
- .interlaced = 0,
- .vact[0] = { .beg = 41 + 4, .end = 1121 + 4 },
- .vsyn_pol = 0,
- .vsyn[0] = { .beg = 0 + 4, .end = 5 + 4},
-};
-
-static const struct hdmi_timings hdmi_timings_1080i60 = {
- .hact = { .beg = 280, .end = 2200 },
- .hsyn_pol = 0,
- .hsyn = { .beg = 88, .end = 88 + 44 },
- .interlaced = 1,
- .vact[0] = { .beg = 20 + 2, .end = 560 + 2 },
- .vact[1] = { .beg = 583 + 2, .end = 1123 + 2 },
- .vsyn_pol = 0,
- .vsyn_off = 1100,
- .vsyn[0] = { .beg = 0 + 2, .end = 5 + 2},
- .vsyn[1] = { .beg = 562 + 2, .end = 567 + 2},
-};
-
-static const struct hdmi_timings hdmi_timings_1080i50 = {
- .hact = { .beg = 720, .end = 2640 },
- .hsyn_pol = 0,
- .hsyn = { .beg = 528, .end = 528 + 44 },
- .interlaced = 1,
- .vact[0] = { .beg = 20 + 2, .end = 560 + 2 },
- .vact[1] = { .beg = 583 + 2, .end = 1123 + 2 },
- .vsyn_pol = 0,
- .vsyn_off = 1320,
- .vsyn[0] = { .beg = 0 + 2, .end = 5 + 2},
- .vsyn[1] = { .beg = 562 + 2, .end = 567 + 2},
-};
-
-static const struct hdmi_timings hdmi_timings_1080p50 = {
- .hact = { .beg = 720, .end = 2640 },
- .hsyn_pol = 0,
- .hsyn = { .beg = 528, .end = 528 + 44 },
- .interlaced = 0,
- .vact[0] = { .beg = 41 + 4, .end = 1121 + 4 },
- .vsyn_pol = 0,
- .vsyn[0] = { .beg = 0 + 4, .end = 5 + 4},
-};
-
-static const struct {
- u32 preset;
- const struct hdmi_timings *timings;
-} hdmi_timings[] = {
- { V4L2_DV_480P59_94, &hdmi_timings_480p },
- { V4L2_DV_576P50, &hdmi_timings_576p50 },
- { V4L2_DV_720P50, &hdmi_timings_720p50 },
- { V4L2_DV_720P59_94, &hdmi_timings_720p60 },
- { V4L2_DV_720P60, &hdmi_timings_720p60 },
- { V4L2_DV_1080P24, &hdmi_timings_1080p24 },
- { V4L2_DV_1080P30, &hdmi_timings_1080p60 },
- { V4L2_DV_1080P50, &hdmi_timings_1080p50 },
- { V4L2_DV_1080I50, &hdmi_timings_1080i50 },
- { V4L2_DV_1080I60, &hdmi_timings_1080i60 },
- { V4L2_DV_1080P60, &hdmi_timings_1080p60 },
-};
-
-static const struct hdmi_timings *hdmi_preset2timings(u32 preset)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(hdmi_timings); ++i)
- if (hdmi_timings[i].preset == preset)
- return hdmi_timings[i].timings;
- return NULL;
-}
-
-static int hdmi_streamon(struct hdmi_device *hdev)
-{
- struct device *dev = hdev->dev;
- struct hdmi_resources *res = &hdev->res;
- int ret, tries;
-
- dev_dbg(dev, "%s\n", __func__);
-
- ret = hdmi_conf_apply(hdev);
- if (ret)
- return ret;
-
- ret = v4l2_subdev_call(hdev->phy_sd, video, s_stream, 1);
- if (ret)
- return ret;
-
- /* waiting for HDMIPHY's PLL to get to steady state */
- for (tries = 100; tries; --tries) {
- u32 val = hdmi_read(hdev, HDMI_PHY_STATUS);
- if (val & HDMI_PHY_STATUS_READY)
- break;
- mdelay(1);
- }
- /* steady state not achieved */
- if (tries == 0) {
- dev_err(dev, "hdmiphy's pll could not reach steady state.\n");
- v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0);
- hdmi_dumpregs(hdev, "hdmiphy - s_stream");
- return -EIO;
- }
-
- /* starting MHL */
- ret = v4l2_subdev_call(hdev->mhl_sd, video, s_stream, 1);
- if (hdev->mhl_sd && ret) {
- v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0);
- hdmi_dumpregs(hdev, "mhl - s_stream");
- return -EIO;
- }
-
- /* hdmiphy clock is used for HDMI in streaming mode */
- clk_disable(res->sclk_hdmi);
- clk_set_parent(res->sclk_hdmi, res->sclk_hdmiphy);
- clk_enable(res->sclk_hdmi);
-
- /* enable HDMI and timing generator */
- hdmi_write_mask(hdev, HDMI_CON_0, ~0, HDMI_EN);
- hdmi_write_mask(hdev, HDMI_TG_CMD, ~0, HDMI_TG_EN);
- hdmi_dumpregs(hdev, "streamon");
- return 0;
-}
-
-static int hdmi_streamoff(struct hdmi_device *hdev)
-{
- struct device *dev = hdev->dev;
- struct hdmi_resources *res = &hdev->res;
-
- dev_dbg(dev, "%s\n", __func__);
-
- hdmi_write_mask(hdev, HDMI_CON_0, 0, HDMI_EN);
- hdmi_write_mask(hdev, HDMI_TG_CMD, 0, HDMI_TG_EN);
-
- /* pixel(vpll) clock is used for HDMI in config mode */
- clk_disable(res->sclk_hdmi);
- clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
- clk_enable(res->sclk_hdmi);
-
- v4l2_subdev_call(hdev->mhl_sd, video, s_stream, 0);
- v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0);
-
- hdmi_dumpregs(hdev, "streamoff");
- return 0;
-}
-
-static int hdmi_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
- struct device *dev = hdev->dev;
-
- dev_dbg(dev, "%s(%d)\n", __func__, enable);
- if (enable)
- return hdmi_streamon(hdev);
- return hdmi_streamoff(hdev);
-}
-
-static void hdmi_resource_poweron(struct hdmi_resources *res)
-{
- /* turn HDMI power on */
- regulator_bulk_enable(res->regul_count, res->regul_bulk);
- /* power-on hdmi physical interface */
- clk_enable(res->hdmiphy);
- /* use VPP as parent clock; HDMIPHY is not working yet */
- clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
- /* turn clocks on */
- clk_enable(res->sclk_hdmi);
-}
-
-static void hdmi_resource_poweroff(struct hdmi_resources *res)
-{
- /* turn clocks off */
- clk_disable(res->sclk_hdmi);
- /* power-off hdmiphy */
- clk_disable(res->hdmiphy);
- /* turn HDMI power off */
- regulator_bulk_disable(res->regul_count, res->regul_bulk);
-}
-
-static int hdmi_s_power(struct v4l2_subdev *sd, int on)
-{
- struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
- int ret;
-
- if (on)
- ret = pm_runtime_get_sync(hdev->dev);
- else
- ret = pm_runtime_put_sync(hdev->dev);
- /* only values < 0 indicate errors */
- return IS_ERR_VALUE(ret) ? ret : 0;
-}
-
-static int hdmi_s_dv_preset(struct v4l2_subdev *sd,
- struct v4l2_dv_preset *preset)
-{
- struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
- struct device *dev = hdev->dev;
- const struct hdmi_timings *conf;
-
- conf = hdmi_preset2timings(preset->preset);
- if (conf == NULL) {
- dev_err(dev, "preset (%u) not supported\n", preset->preset);
- return -EINVAL;
- }
- hdev->cur_conf = conf;
- hdev->cur_conf_dirty = 1;
- hdev->cur_preset = preset->preset;
- return 0;
-}
-
-static int hdmi_g_dv_preset(struct v4l2_subdev *sd,
- struct v4l2_dv_preset *preset)
-{
- memset(preset, 0, sizeof(*preset));
- preset->preset = sd_to_hdmi_dev(sd)->cur_preset;
- return 0;
-}
-
-static int hdmi_g_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *fmt)
-{
- struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
- const struct hdmi_timings *t = hdev->cur_conf;
-
- dev_dbg(hdev->dev, "%s\n", __func__);
- if (!hdev->cur_conf)
- return -EINVAL;
- memset(fmt, 0, sizeof *fmt);
- fmt->width = t->hact.end - t->hact.beg;
- fmt->height = t->vact[0].end - t->vact[0].beg;
- fmt->code = V4L2_MBUS_FMT_FIXED; /* means RGB888 */
- fmt->colorspace = V4L2_COLORSPACE_SRGB;
- if (t->interlaced) {
- fmt->field = V4L2_FIELD_INTERLACED;
- fmt->height *= 2;
- } else {
- fmt->field = V4L2_FIELD_NONE;
- }
- return 0;
-}
-
-static int hdmi_enum_dv_presets(struct v4l2_subdev *sd,
- struct v4l2_dv_enum_preset *preset)
-{
- if (preset->index >= ARRAY_SIZE(hdmi_timings))
- return -EINVAL;
- return v4l_fill_dv_preset_info(hdmi_timings[preset->index].preset,
- preset);
-}
-
-static const struct v4l2_subdev_core_ops hdmi_sd_core_ops = {
- .s_power = hdmi_s_power,
-};
-
-static const struct v4l2_subdev_video_ops hdmi_sd_video_ops = {
- .s_dv_preset = hdmi_s_dv_preset,
- .g_dv_preset = hdmi_g_dv_preset,
- .enum_dv_presets = hdmi_enum_dv_presets,
- .g_mbus_fmt = hdmi_g_mbus_fmt,
- .s_stream = hdmi_s_stream,
-};
-
-static const struct v4l2_subdev_ops hdmi_sd_ops = {
- .core = &hdmi_sd_core_ops,
- .video = &hdmi_sd_video_ops,
-};
-
-static int hdmi_runtime_suspend(struct device *dev)
-{
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
- struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
-
- dev_dbg(dev, "%s\n", __func__);
- v4l2_subdev_call(hdev->mhl_sd, core, s_power, 0);
- hdmi_resource_poweroff(&hdev->res);
- /* flag that device context is lost */
- hdev->cur_conf_dirty = 1;
- return 0;
-}
-
-static int hdmi_runtime_resume(struct device *dev)
-{
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
- struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
- int ret = 0;
-
- dev_dbg(dev, "%s\n", __func__);
-
- hdmi_resource_poweron(&hdev->res);
-
- /* starting MHL */
- ret = v4l2_subdev_call(hdev->mhl_sd, core, s_power, 1);
- if (hdev->mhl_sd && ret)
- goto fail;
-
- dev_dbg(dev, "poweron succeed\n");
-
- return 0;
-
-fail:
- hdmi_resource_poweroff(&hdev->res);
- dev_err(dev, "poweron failed\n");
-
- return ret;
-}
-
-static const struct dev_pm_ops hdmi_pm_ops = {
- .runtime_suspend = hdmi_runtime_suspend,
- .runtime_resume = hdmi_runtime_resume,
-};
-
-static void hdmi_resources_cleanup(struct hdmi_device *hdev)
-{
- struct hdmi_resources *res = &hdev->res;
-
- dev_dbg(hdev->dev, "HDMI resource cleanup\n");
- /* put clocks, power */
- if (res->regul_count)
- regulator_bulk_free(res->regul_count, res->regul_bulk);
- /* kfree is NULL-safe */
- kfree(res->regul_bulk);
- if (!IS_ERR_OR_NULL(res->hdmiphy))
- clk_put(res->hdmiphy);
- if (!IS_ERR_OR_NULL(res->sclk_hdmiphy))
- clk_put(res->sclk_hdmiphy);
- if (!IS_ERR_OR_NULL(res->sclk_pixel))
- clk_put(res->sclk_pixel);
- if (!IS_ERR_OR_NULL(res->sclk_hdmi))
- clk_put(res->sclk_hdmi);
- if (!IS_ERR_OR_NULL(res->hdmi))
- clk_put(res->hdmi);
- memset(res, 0, sizeof *res);
-}
-
-static int hdmi_resources_init(struct hdmi_device *hdev)
-{
- struct device *dev = hdev->dev;
- struct hdmi_resources *res = &hdev->res;
- static char *supply[] = {
- "hdmi-en",
- "vdd",
- "vdd_osc",
- "vdd_pll",
- };
- int i, ret;
-
- dev_dbg(dev, "HDMI resource init\n");
-
- memset(res, 0, sizeof *res);
- /* get clocks, power */
-
- res->hdmi = clk_get(dev, "hdmi");
- if (IS_ERR_OR_NULL(res->hdmi)) {
- dev_err(dev, "failed to get clock 'hdmi'\n");
- goto fail;
- }
- res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
- if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
- dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
- goto fail;
- }
- res->sclk_pixel = clk_get(dev, "sclk_pixel");
- if (IS_ERR_OR_NULL(res->sclk_pixel)) {
- dev_err(dev, "failed to get clock 'sclk_pixel'\n");
- goto fail;
- }
- res->sclk_hdmiphy = clk_get(dev, "sclk_hdmiphy");
- if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) {
- dev_err(dev, "failed to get clock 'sclk_hdmiphy'\n");
- goto fail;
- }
- res->hdmiphy = clk_get(dev, "hdmiphy");
- if (IS_ERR_OR_NULL(res->hdmiphy)) {
- dev_err(dev, "failed to get clock 'hdmiphy'\n");
- goto fail;
- }
- res->regul_bulk = kcalloc(ARRAY_SIZE(supply),
- sizeof(res->regul_bulk[0]), GFP_KERNEL);
- if (!res->regul_bulk) {
- dev_err(dev, "failed to get memory for regulators\n");
- goto fail;
- }
- for (i = 0; i < ARRAY_SIZE(supply); ++i) {
- res->regul_bulk[i].supply = supply[i];
- res->regul_bulk[i].consumer = NULL;
- }
-
- ret = regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
- if (ret) {
- dev_err(dev, "failed to get regulators\n");
- goto fail;
- }
- res->regul_count = ARRAY_SIZE(supply);
-
- return 0;
-fail:
- dev_err(dev, "HDMI resource init - failed\n");
- hdmi_resources_cleanup(hdev);
- return -ENODEV;
-}
-
-static int __devinit hdmi_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct resource *res;
- struct i2c_adapter *adapter;
- struct v4l2_subdev *sd;
- struct hdmi_device *hdmi_dev = NULL;
- struct s5p_hdmi_platform_data *pdata = dev->platform_data;
- int ret;
-
- dev_dbg(dev, "probe start\n");
-
- if (!pdata) {
- dev_err(dev, "platform data is missing\n");
- ret = -ENODEV;
- goto fail;
- }
-
- hdmi_dev = devm_kzalloc(&pdev->dev, sizeof(*hdmi_dev), GFP_KERNEL);
- if (!hdmi_dev) {
- dev_err(dev, "out of memory\n");
- ret = -ENOMEM;
- goto fail;
- }
-
- hdmi_dev->dev = dev;
-
- ret = hdmi_resources_init(hdmi_dev);
- if (ret)
- goto fail;
-
- /* mapping HDMI registers */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(dev, "get memory resource failed.\n");
- ret = -ENXIO;
- goto fail_init;
- }
-
- hdmi_dev->regs = devm_ioremap(&pdev->dev, res->start,
- resource_size(res));
- if (hdmi_dev->regs == NULL) {
- dev_err(dev, "register mapping failed.\n");
- ret = -ENXIO;
- goto fail_init;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res == NULL) {
- dev_err(dev, "get interrupt resource failed.\n");
- ret = -ENXIO;
- goto fail_init;
- }
-
- ret = devm_request_irq(&pdev->dev, res->start, hdmi_irq_handler, 0,
- "hdmi", hdmi_dev);
- if (ret) {
- dev_err(dev, "request interrupt failed.\n");
- goto fail_init;
- }
- hdmi_dev->irq = res->start;
-
- /* setting v4l2 name to prevent WARN_ON in v4l2_device_register */
- strlcpy(hdmi_dev->v4l2_dev.name, dev_name(dev),
- sizeof(hdmi_dev->v4l2_dev.name));
- /* passing NULL owner prevents driver from erasing drvdata */
- ret = v4l2_device_register(NULL, &hdmi_dev->v4l2_dev);
- if (ret) {
- dev_err(dev, "could not register v4l2 device.\n");
- goto fail_init;
- }
-
- /* testing if hdmiphy info is present */
- if (!pdata->hdmiphy_info) {
- dev_err(dev, "hdmiphy info is missing in platform data\n");
- ret = -ENXIO;
- goto fail_vdev;
- }
-
- adapter = i2c_get_adapter(pdata->hdmiphy_bus);
- if (adapter == NULL) {
- dev_err(dev, "hdmiphy adapter request failed\n");
- ret = -ENXIO;
- goto fail_vdev;
- }
-
- hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->v4l2_dev,
- adapter, pdata->hdmiphy_info, NULL);
- /* on failure or not adapter is no longer useful */
- i2c_put_adapter(adapter);
- if (hdmi_dev->phy_sd == NULL) {
- dev_err(dev, "missing subdev for hdmiphy\n");
- ret = -ENODEV;
- goto fail_vdev;
- }
-
- /* initialization of MHL interface if present */
- if (pdata->mhl_info) {
- adapter = i2c_get_adapter(pdata->mhl_bus);
- if (adapter == NULL) {
- dev_err(dev, "MHL adapter request failed\n");
- ret = -ENXIO;
- goto fail_vdev;
- }
-
- hdmi_dev->mhl_sd = v4l2_i2c_new_subdev_board(
- &hdmi_dev->v4l2_dev, adapter,
- pdata->mhl_info, NULL);
- /* on failure or not adapter is no longer useful */
- i2c_put_adapter(adapter);
- if (hdmi_dev->mhl_sd == NULL) {
- dev_err(dev, "missing subdev for MHL\n");
- ret = -ENODEV;
- goto fail_vdev;
- }
- }
-
- clk_enable(hdmi_dev->res.hdmi);
-
- pm_runtime_enable(dev);
-
- sd = &hdmi_dev->sd;
- v4l2_subdev_init(sd, &hdmi_sd_ops);
- sd->owner = THIS_MODULE;
-
- strlcpy(sd->name, "s5p-hdmi", sizeof sd->name);
- hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET;
- /* FIXME: missing fail preset is not supported */
- hdmi_dev->cur_conf = hdmi_preset2timings(hdmi_dev->cur_preset);
- hdmi_dev->cur_conf_dirty = 1;
-
- /* storing subdev for call that have only access to struct device */
- dev_set_drvdata(dev, sd);
-
- dev_info(dev, "probe successful\n");
-
- return 0;
-
-fail_vdev:
- v4l2_device_unregister(&hdmi_dev->v4l2_dev);
-
-fail_init:
- hdmi_resources_cleanup(hdmi_dev);
-
-fail:
- dev_err(dev, "probe failed\n");
- return ret;
-}
-
-static int __devexit hdmi_remove(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
- struct hdmi_device *hdmi_dev = sd_to_hdmi_dev(sd);
-
- pm_runtime_disable(dev);
- clk_disable(hdmi_dev->res.hdmi);
- v4l2_device_unregister(&hdmi_dev->v4l2_dev);
- disable_irq(hdmi_dev->irq);
- hdmi_resources_cleanup(hdmi_dev);
- dev_info(dev, "remove successful\n");
-
- return 0;
-}
-
-static struct platform_driver hdmi_driver __refdata = {
- .probe = hdmi_probe,
- .remove = __devexit_p(hdmi_remove),
- .id_table = hdmi_driver_types,
- .driver = {
- .name = "s5p-hdmi",
- .owner = THIS_MODULE,
- .pm = &hdmi_pm_ops,
- }
-};
-
-module_platform_driver(hdmi_driver);
diff --git a/drivers/media/video/s5p-tv/hdmiphy_drv.c b/drivers/media/video/s5p-tv/hdmiphy_drv.c
deleted file mode 100644
index f67b3863180..00000000000
--- a/drivers/media/video/s5p-tv/hdmiphy_drv.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Samsung HDMI Physical interface driver
- *
- * Copyright (C) 2010-2011 Samsung Electronics Co.Ltd
- * Author: Tomasz Stanislawski <t.stanislaws@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/err.h>
-
-#include <media/v4l2-subdev.h>
-
-MODULE_AUTHOR("Tomasz Stanislawski <t.stanislaws@samsung.com>");
-MODULE_DESCRIPTION("Samsung HDMI Physical interface driver");
-MODULE_LICENSE("GPL");
-
-struct hdmiphy_conf {
- unsigned long pixclk;
- const u8 *data;
-};
-
-struct hdmiphy_ctx {
- struct v4l2_subdev sd;
- const struct hdmiphy_conf *conf_tab;
-};
-
-static const struct hdmiphy_conf hdmiphy_conf_s5pv210[] = {
- { .pixclk = 27000000, .data = (u8 [32]) {
- 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
- 0x6B, 0x10, 0x02, 0x52, 0xDF, 0xF2, 0x54, 0x87,
- 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
- 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, }
- },
- { .pixclk = 27027000, .data = (u8 [32]) {
- 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
- 0x6B, 0x10, 0x02, 0x52, 0xDF, 0xF2, 0x54, 0x87,
- 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
- 0x22, 0x40, 0xE2, 0x26, 0x00, 0x00, 0x00, 0x00, }
- },
- { .pixclk = 74176000, .data = (u8 [32]) {
- 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xEF, 0x5B,
- 0x6D, 0x10, 0x01, 0x52, 0xEF, 0xF3, 0x54, 0xB9,
- 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
- 0x22, 0x40, 0xA5, 0x26, 0x01, 0x00, 0x00, 0x00, }
- },
- { .pixclk = 74250000, .data = (u8 [32]) {
- 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xF8, 0x40,
- 0x6A, 0x10, 0x01, 0x52, 0xFF, 0xF1, 0x54, 0xBA,
- 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
- 0x22, 0x40, 0xA4, 0x26, 0x01, 0x00, 0x00, 0x00, }
- },
- { /* end marker */ }
-};
-
-static const struct hdmiphy_conf hdmiphy_conf_exynos4210[] = {
- { .pixclk = 27000000, .data = (u8 [32]) {
- 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
- 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
- 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
- 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, }
- },
- { .pixclk = 27027000, .data = (u8 [32]) {
- 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
- 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
- 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
- 0x22, 0x40, 0xE2, 0x26, 0x00, 0x00, 0x00, 0x00, }
- },
- { .pixclk = 74176000, .data = (u8 [32]) {
- 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xEF, 0x5B,
- 0x6D, 0x10, 0x01, 0x51, 0xEF, 0xF3, 0x54, 0xB9,
- 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
- 0x22, 0x40, 0xA5, 0x26, 0x01, 0x00, 0x00, 0x00, }
- },
- { .pixclk = 74250000, .data = (u8 [32]) {
- 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xF8, 0x40,
- 0x6A, 0x10, 0x01, 0x51, 0xFF, 0xF1, 0x54, 0xBA,
- 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
- 0x22, 0x40, 0xA4, 0x26, 0x01, 0x00, 0x00, 0x00, }
- },
- { .pixclk = 148352000, .data = (u8 [32]) {
- 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xEF, 0x5B,
- 0x6D, 0x18, 0x00, 0x51, 0xEF, 0xF3, 0x54, 0xB9,
- 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
- 0x11, 0x40, 0xA5, 0x26, 0x02, 0x00, 0x00, 0x00, }
- },
- { .pixclk = 148500000, .data = (u8 [32]) {
- 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xF8, 0x40,
- 0x6A, 0x18, 0x00, 0x51, 0xFF, 0xF1, 0x54, 0xBA,
- 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
- 0x11, 0x40, 0xA4, 0x26, 0x02, 0x00, 0x00, 0x00, }
- },
- { /* end marker */ }
-};
-
-static const struct hdmiphy_conf hdmiphy_conf_exynos4212[] = {
- { .pixclk = 27000000, .data = (u8 [32]) {
- 0x01, 0x11, 0x2D, 0x75, 0x00, 0x01, 0x00, 0x08,
- 0x82, 0x00, 0x0E, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
- 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0x71,
- 0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, }
- },
- { .pixclk = 27027000, .data = (u8 [32]) {
- 0x01, 0x91, 0x2D, 0x72, 0x00, 0x64, 0x12, 0x08,
- 0x43, 0x20, 0x0E, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
- 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0x71,
- 0x54, 0xE2, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, }
- },
- { .pixclk = 74176000, .data = (u8 [32]) {
- 0x01, 0x91, 0x3E, 0x35, 0x00, 0x5B, 0xDE, 0x08,
- 0x82, 0x20, 0x73, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
- 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0x52,
- 0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, }
- },
- { .pixclk = 74250000, .data = (u8 [32]) {
- 0x01, 0x91, 0x3E, 0x35, 0x00, 0x40, 0xF0, 0x08,
- 0x82, 0x20, 0x73, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
- 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0x52,
- 0x54, 0xA4, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, }
- },
- { .pixclk = 148500000, .data = (u8 [32]) {
- 0x01, 0x91, 0x3E, 0x15, 0x00, 0x40, 0xF0, 0x08,
- 0x82, 0x20, 0x73, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
- 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0xA4,
- 0x54, 0x4A, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00, }
- },
- { /* end marker */ }
-};
-
-static const struct hdmiphy_conf hdmiphy_conf_exynos4412[] = {
- { .pixclk = 27000000, .data = (u8 [32]) {
- 0x01, 0x11, 0x2D, 0x75, 0x40, 0x01, 0x00, 0x08,
- 0x82, 0x00, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
- 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
- 0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, }
- },
- { .pixclk = 27027000, .data = (u8 [32]) {
- 0x01, 0x91, 0x2D, 0x72, 0x40, 0x64, 0x12, 0x08,
- 0x43, 0x20, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
- 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
- 0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, }
- },
- { .pixclk = 74176000, .data = (u8 [32]) {
- 0x01, 0x91, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0x08,
- 0x81, 0x20, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
- 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
- 0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, }
- },
- { .pixclk = 74250000, .data = (u8 [32]) {
- 0x01, 0x91, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
- 0x81, 0x20, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
- 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
- 0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, }
- },
- { .pixclk = 148500000, .data = (u8 [32]) {
- 0x01, 0x91, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
- 0x81, 0x20, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
- 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
- 0x54, 0x4B, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00, }
- },
- { /* end marker */ }
-};
-
-static inline struct hdmiphy_ctx *sd_to_ctx(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct hdmiphy_ctx, sd);
-}
-
-static unsigned long hdmiphy_preset_to_pixclk(u32 preset)
-{
- static const unsigned long pixclk[] = {
- [V4L2_DV_480P59_94] = 27000000,
- [V4L2_DV_576P50] = 27000000,
- [V4L2_DV_720P59_94] = 74176000,
- [V4L2_DV_720P50] = 74250000,
- [V4L2_DV_720P60] = 74250000,
- [V4L2_DV_1080P24] = 74250000,
- [V4L2_DV_1080P30] = 74250000,
- [V4L2_DV_1080I50] = 74250000,
- [V4L2_DV_1080I60] = 74250000,
- [V4L2_DV_1080P50] = 148500000,
- [V4L2_DV_1080P60] = 148500000,
- };
- if (preset < ARRAY_SIZE(pixclk))
- return pixclk[preset];
- else
- return 0;
-}
-
-static const u8 *hdmiphy_find_conf(u32 preset, const struct hdmiphy_conf *conf)
-{
- unsigned long pixclk;
-
- pixclk = hdmiphy_preset_to_pixclk(preset);
- if (!pixclk)
- return NULL;
-
- for (; conf->pixclk; ++conf)
- if (conf->pixclk == pixclk)
- return conf->data;
- return NULL;
-}
-
-static int hdmiphy_s_power(struct v4l2_subdev *sd, int on)
-{
- /* to be implemented */
- return 0;
-}
-
-static int hdmiphy_s_dv_preset(struct v4l2_subdev *sd,
- struct v4l2_dv_preset *preset)
-{
- const u8 *data;
- u8 buffer[32];
- int ret;
- struct hdmiphy_ctx *ctx = sd_to_ctx(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct device *dev = &client->dev;
-
- dev_info(dev, "s_dv_preset(preset = %d)\n", preset->preset);
- data = hdmiphy_find_conf(preset->preset, ctx->conf_tab);
- if (!data) {
- dev_err(dev, "format not supported\n");
- return -EINVAL;
- }
-
- /* storing configuration to the device */
- memcpy(buffer, data, 32);
- ret = i2c_master_send(client, buffer, 32);
- if (ret != 32) {
- dev_err(dev, "failed to configure HDMIPHY via I2C\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static int hdmiphy_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct device *dev = &client->dev;
- u8 buffer[2];
- int ret;
-
- dev_info(dev, "s_stream(%d)\n", enable);
- /* going to/from configuration from/to operation mode */
- buffer[0] = 0x1f;
- buffer[1] = enable ? 0x80 : 0x00;
-
- ret = i2c_master_send(client, buffer, 2);
- if (ret != 2) {
- dev_err(dev, "stream (%d) failed\n", enable);
- return -EIO;
- }
- return 0;
-}
-
-static const struct v4l2_subdev_core_ops hdmiphy_core_ops = {
- .s_power = hdmiphy_s_power,
-};
-
-static const struct v4l2_subdev_video_ops hdmiphy_video_ops = {
- .s_dv_preset = hdmiphy_s_dv_preset,
- .s_stream = hdmiphy_s_stream,
-};
-
-static const struct v4l2_subdev_ops hdmiphy_ops = {
- .core = &hdmiphy_core_ops,
- .video = &hdmiphy_video_ops,
-};
-
-static int __devinit hdmiphy_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct hdmiphy_ctx *ctx;
-
- ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- ctx->conf_tab = (struct hdmiphy_conf *)id->driver_data;
- v4l2_i2c_subdev_init(&ctx->sd, client, &hdmiphy_ops);
-
- dev_info(&client->dev, "probe successful\n");
- return 0;
-}
-
-static int __devexit hdmiphy_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct hdmiphy_ctx *ctx = sd_to_ctx(sd);
-
- kfree(ctx);
- dev_info(&client->dev, "remove successful\n");
-
- return 0;
-}
-
-static const struct i2c_device_id hdmiphy_id[] = {
- { "hdmiphy", (unsigned long)hdmiphy_conf_exynos4210 },
- { "hdmiphy-s5pv210", (unsigned long)hdmiphy_conf_s5pv210 },
- { "hdmiphy-exynos4210", (unsigned long)hdmiphy_conf_exynos4210 },
- { "hdmiphy-exynos4212", (unsigned long)hdmiphy_conf_exynos4212 },
- { "hdmiphy-exynos4412", (unsigned long)hdmiphy_conf_exynos4412 },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, hdmiphy_id);
-
-static struct i2c_driver hdmiphy_driver = {
- .driver = {
- .name = "s5p-hdmiphy",
- .owner = THIS_MODULE,
- },
- .probe = hdmiphy_probe,
- .remove = __devexit_p(hdmiphy_remove),
- .id_table = hdmiphy_id,
-};
-
-module_i2c_driver(hdmiphy_driver);
diff --git a/drivers/media/video/s5p-tv/mixer.h b/drivers/media/video/s5p-tv/mixer.h
deleted file mode 100644
index ddb422e2355..00000000000
--- a/drivers/media/video/s5p-tv/mixer.h
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Samsung TV Mixer driver
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *
- * Tomasz Stanislawski, <t.stanislaws@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundiation. either version 2 of the License,
- * or (at your option) any later version
- */
-
-#ifndef SAMSUNG_MIXER_H
-#define SAMSUNG_MIXER_H
-
-#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MIXER_DEBUG
- #define DEBUG
-#endif
-
-#include <linux/fb.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <media/v4l2-device.h>
-#include <media/videobuf2-core.h>
-
-#include "regs-mixer.h"
-
-/** maximum number of output interfaces */
-#define MXR_MAX_OUTPUTS 2
-/** maximum number of input interfaces (layers) */
-#define MXR_MAX_LAYERS 3
-#define MXR_DRIVER_NAME "s5p-mixer"
-/** maximal number of planes for every layer */
-#define MXR_MAX_PLANES 2
-
-#define MXR_ENABLE 1
-#define MXR_DISABLE 0
-
-/** description of a macroblock for packed formats */
-struct mxr_block {
- /** vertical number of pixels in macroblock */
- unsigned int width;
- /** horizontal number of pixels in macroblock */
- unsigned int height;
- /** size of block in bytes */
- unsigned int size;
-};
-
-/** description of supported format */
-struct mxr_format {
- /** format name/mnemonic */
- const char *name;
- /** fourcc identifier */
- u32 fourcc;
- /** colorspace identifier */
- enum v4l2_colorspace colorspace;
- /** number of planes in image data */
- int num_planes;
- /** description of block for each plane */
- struct mxr_block plane[MXR_MAX_PLANES];
- /** number of subframes in image data */
- int num_subframes;
- /** specifies to which subframe belong given plane */
- int plane2subframe[MXR_MAX_PLANES];
- /** internal code, driver dependant */
- unsigned long cookie;
-};
-
-/** description of crop configuration for image */
-struct mxr_crop {
- /** width of layer in pixels */
- unsigned int full_width;
- /** height of layer in pixels */
- unsigned int full_height;
- /** horizontal offset of first pixel to be displayed */
- unsigned int x_offset;
- /** vertical offset of first pixel to be displayed */
- unsigned int y_offset;
- /** width of displayed data in pixels */
- unsigned int width;
- /** height of displayed data in pixels */
- unsigned int height;
- /** indicate which fields are present in buffer */
- unsigned int field;
-};
-
-/** stages of geometry operations */
-enum mxr_geometry_stage {
- MXR_GEOMETRY_SINK,
- MXR_GEOMETRY_COMPOSE,
- MXR_GEOMETRY_CROP,
- MXR_GEOMETRY_SOURCE,
-};
-
-/* flag indicating that offset should be 0 */
-#define MXR_NO_OFFSET 0x80000000
-
-/** description of transformation from source to destination image */
-struct mxr_geometry {
- /** cropping for source image */
- struct mxr_crop src;
- /** cropping for destination image */
- struct mxr_crop dst;
- /** layer-dependant description of horizontal scaling */
- unsigned int x_ratio;
- /** layer-dependant description of vertical scaling */
- unsigned int y_ratio;
-};
-
-/** instance of a buffer */
-struct mxr_buffer {
- /** common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
- /** node for layer's lists */
- struct list_head list;
-};
-
-
-/** internal states of layer */
-enum mxr_layer_state {
- /** layers is not shown */
- MXR_LAYER_IDLE = 0,
- /** layer is shown */
- MXR_LAYER_STREAMING,
- /** state before STREAMOFF is finished */
- MXR_LAYER_STREAMING_FINISH,
-};
-
-/** forward declarations */
-struct mxr_device;
-struct mxr_layer;
-
-/** callback for layers operation */
-struct mxr_layer_ops {
- /* TODO: try to port it to subdev API */
- /** handler for resource release function */
- void (*release)(struct mxr_layer *);
- /** setting buffer to HW */
- void (*buffer_set)(struct mxr_layer *, struct mxr_buffer *);
- /** setting format and geometry in HW */
- void (*format_set)(struct mxr_layer *);
- /** streaming stop/start */
- void (*stream_set)(struct mxr_layer *, int);
- /** adjusting geometry */
- void (*fix_geometry)(struct mxr_layer *,
- enum mxr_geometry_stage, unsigned long);
-};
-
-/** layer instance, a single window and content displayed on output */
-struct mxr_layer {
- /** parent mixer device */
- struct mxr_device *mdev;
- /** layer index (unique identifier) */
- int idx;
- /** callbacks for layer methods */
- struct mxr_layer_ops ops;
- /** format array */
- const struct mxr_format **fmt_array;
- /** size of format array */
- unsigned long fmt_array_size;
-
- /** lock for protection of list and state fields */
- spinlock_t enq_slock;
- /** list for enqueued buffers */
- struct list_head enq_list;
- /** buffer currently owned by hardware in temporary registers */
- struct mxr_buffer *update_buf;
- /** buffer currently owned by hardware in shadow registers */
- struct mxr_buffer *shadow_buf;
- /** state of layer IDLE/STREAMING */
- enum mxr_layer_state state;
-
- /** mutex for protection of fields below */
- struct mutex mutex;
- /** handler for video node */
- struct video_device vfd;
- /** queue for output buffers */
- struct vb2_queue vb_queue;
- /** current image format */
- const struct mxr_format *fmt;
- /** current geometry of image */
- struct mxr_geometry geo;
-};
-
-/** description of mixers output interface */
-struct mxr_output {
- /** name of output */
- char name[32];
- /** output subdev */
- struct v4l2_subdev *sd;
- /** cookie used for configuration of registers */
- int cookie;
-};
-
-/** specify source of output subdevs */
-struct mxr_output_conf {
- /** name of output (connector) */
- char *output_name;
- /** name of module that generates output subdev */
- char *module_name;
- /** cookie need for mixer HW */
- int cookie;
-};
-
-struct clk;
-struct regulator;
-
-/** auxiliary resources used my mixer */
-struct mxr_resources {
- /** interrupt index */
- int irq;
- /** pointer to Mixer registers */
- void __iomem *mxr_regs;
- /** pointer to Video Processor registers */
- void __iomem *vp_regs;
- /** other resources, should used under mxr_device.mutex */
- struct clk *mixer;
- struct clk *vp;
- struct clk *sclk_mixer;
- struct clk *sclk_hdmi;
- struct clk *sclk_dac;
-};
-
-/* event flags used */
-enum mxr_devide_flags {
- MXR_EVENT_VSYNC = 0,
- MXR_EVENT_TOP = 1,
-};
-
-/** drivers instance */
-struct mxr_device {
- /** master device */
- struct device *dev;
- /** state of each layer */
- struct mxr_layer *layer[MXR_MAX_LAYERS];
- /** state of each output */
- struct mxr_output *output[MXR_MAX_OUTPUTS];
- /** number of registered outputs */
- int output_cnt;
-
- /* video resources */
-
- /** V4L2 device */
- struct v4l2_device v4l2_dev;
- /** context of allocator */
- void *alloc_ctx;
- /** event wait queue */
- wait_queue_head_t event_queue;
- /** state flags */
- unsigned long event_flags;
-
- /** spinlock for protection of registers */
- spinlock_t reg_slock;
-
- /** mutex for protection of fields below */
- struct mutex mutex;
- /** number of entities depndant on output configuration */
- int n_output;
- /** number of users that do streaming */
- int n_streamer;
- /** index of current output */
- int current_output;
- /** auxiliary resources used my mixer */
- struct mxr_resources res;
-};
-
-/** transform device structure into mixer device */
-static inline struct mxr_device *to_mdev(struct device *dev)
-{
- struct v4l2_device *vdev = dev_get_drvdata(dev);
- return container_of(vdev, struct mxr_device, v4l2_dev);
-}
-
-/** get current output data, should be called under mdev's mutex */
-static inline struct mxr_output *to_output(struct mxr_device *mdev)
-{
- return mdev->output[mdev->current_output];
-}
-
-/** get current output subdev, should be called under mdev's mutex */
-static inline struct v4l2_subdev *to_outsd(struct mxr_device *mdev)
-{
- struct mxr_output *out = to_output(mdev);
- return out ? out->sd : NULL;
-}
-
-/** forward declaration for mixer platform data */
-struct mxr_platform_data;
-
-/** acquiring common video resources */
-int __devinit mxr_acquire_video(struct mxr_device *mdev,
- struct mxr_output_conf *output_cont, int output_count);
-
-/** releasing common video resources */
-void mxr_release_video(struct mxr_device *mdev);
-
-struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx);
-struct mxr_layer *mxr_vp_layer_create(struct mxr_device *mdev, int idx);
-struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
- int idx, char *name, struct mxr_layer_ops *ops);
-
-void mxr_base_layer_release(struct mxr_layer *layer);
-void mxr_layer_release(struct mxr_layer *layer);
-
-int mxr_base_layer_register(struct mxr_layer *layer);
-void mxr_base_layer_unregister(struct mxr_layer *layer);
-
-unsigned long mxr_get_plane_size(const struct mxr_block *blk,
- unsigned int width, unsigned int height);
-
-/** adds new consumer for mixer's power */
-int __must_check mxr_power_get(struct mxr_device *mdev);
-/** removes consumer for mixer's power */
-void mxr_power_put(struct mxr_device *mdev);
-/** add new client for output configuration */
-void mxr_output_get(struct mxr_device *mdev);
-/** removes new client for output configuration */
-void mxr_output_put(struct mxr_device *mdev);
-/** add new client for streaming */
-void mxr_streamer_get(struct mxr_device *mdev);
-/** removes new client for streaming */
-void mxr_streamer_put(struct mxr_device *mdev);
-/** returns format of data delivared to current output */
-void mxr_get_mbus_fmt(struct mxr_device *mdev,
- struct v4l2_mbus_framefmt *mbus_fmt);
-
-/* Debug */
-
-#define mxr_err(mdev, fmt, ...) dev_err(mdev->dev, fmt, ##__VA_ARGS__)
-#define mxr_warn(mdev, fmt, ...) dev_warn(mdev->dev, fmt, ##__VA_ARGS__)
-#define mxr_info(mdev, fmt, ...) dev_info(mdev->dev, fmt, ##__VA_ARGS__)
-
-#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MIXER_DEBUG
- #define mxr_dbg(mdev, fmt, ...) dev_dbg(mdev->dev, fmt, ##__VA_ARGS__)
-#else
- #define mxr_dbg(mdev, fmt, ...) do { (void) mdev; } while (0)
-#endif
-
-/* accessing Mixer's and Video Processor's registers */
-
-void mxr_vsync_set_update(struct mxr_device *mdev, int en);
-void mxr_reg_reset(struct mxr_device *mdev);
-irqreturn_t mxr_irq_handler(int irq, void *dev_data);
-void mxr_reg_s_output(struct mxr_device *mdev, int cookie);
-void mxr_reg_streamon(struct mxr_device *mdev);
-void mxr_reg_streamoff(struct mxr_device *mdev);
-int mxr_reg_wait4vsync(struct mxr_device *mdev);
-void mxr_reg_set_mbus_fmt(struct mxr_device *mdev,
- struct v4l2_mbus_framefmt *fmt);
-void mxr_reg_graph_layer_stream(struct mxr_device *mdev, int idx, int en);
-void mxr_reg_graph_buffer(struct mxr_device *mdev, int idx, dma_addr_t addr);
-void mxr_reg_graph_format(struct mxr_device *mdev, int idx,
- const struct mxr_format *fmt, const struct mxr_geometry *geo);
-
-void mxr_reg_vp_layer_stream(struct mxr_device *mdev, int en);
-void mxr_reg_vp_buffer(struct mxr_device *mdev,
- dma_addr_t luma_addr[2], dma_addr_t chroma_addr[2]);
-void mxr_reg_vp_format(struct mxr_device *mdev,
- const struct mxr_format *fmt, const struct mxr_geometry *geo);
-void mxr_reg_dump(struct mxr_device *mdev);
-
-#endif /* SAMSUNG_MIXER_H */
-
diff --git a/drivers/media/video/s5p-tv/mixer_drv.c b/drivers/media/video/s5p-tv/mixer_drv.c
deleted file mode 100644
index edca0659288..00000000000
--- a/drivers/media/video/s5p-tv/mixer_drv.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * Samsung TV Mixer driver
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *
- * Tomasz Stanislawski, <t.stanislaws@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundiation. either version 2 of the License,
- * or (at your option) any later version
- */
-
-#include "mixer.h"
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/fb.h>
-#include <linux/delay.h>
-#include <linux/pm_runtime.h>
-#include <linux/clk.h>
-
-MODULE_AUTHOR("Tomasz Stanislawski, <t.stanislaws@samsung.com>");
-MODULE_DESCRIPTION("Samsung MIXER");
-MODULE_LICENSE("GPL");
-
-/* --------- DRIVER PARAMETERS ---------- */
-
-static struct mxr_output_conf mxr_output_conf[] = {
- {
- .output_name = "S5P HDMI connector",
- .module_name = "s5p-hdmi",
- .cookie = 1,
- },
- {
- .output_name = "S5P SDO connector",
- .module_name = "s5p-sdo",
- .cookie = 0,
- },
-};
-
-void mxr_get_mbus_fmt(struct mxr_device *mdev,
- struct v4l2_mbus_framefmt *mbus_fmt)
-{
- struct v4l2_subdev *sd;
- int ret;
-
- mutex_lock(&mdev->mutex);
- sd = to_outsd(mdev);
- ret = v4l2_subdev_call(sd, video, g_mbus_fmt, mbus_fmt);
- WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
- mutex_unlock(&mdev->mutex);
-}
-
-void mxr_streamer_get(struct mxr_device *mdev)
-{
- mutex_lock(&mdev->mutex);
- ++mdev->n_streamer;
- mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer);
- if (mdev->n_streamer == 1) {
- struct v4l2_subdev *sd = to_outsd(mdev);
- struct v4l2_mbus_framefmt mbus_fmt;
- struct mxr_resources *res = &mdev->res;
- int ret;
-
- if (to_output(mdev)->cookie == 0)
- clk_set_parent(res->sclk_mixer, res->sclk_dac);
- else
- clk_set_parent(res->sclk_mixer, res->sclk_hdmi);
- mxr_reg_s_output(mdev, to_output(mdev)->cookie);
-
- ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mbus_fmt);
- WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
- ret = v4l2_subdev_call(sd, video, s_stream, 1);
- WARN(ret, "starting stream failed for output %s\n", sd->name);
-
- mxr_reg_set_mbus_fmt(mdev, &mbus_fmt);
- mxr_reg_streamon(mdev);
- ret = mxr_reg_wait4vsync(mdev);
- WARN(ret, "failed to get vsync (%d) from output\n", ret);
- }
- mutex_unlock(&mdev->mutex);
- mxr_reg_dump(mdev);
- /* FIXME: what to do when streaming fails? */
-}
-
-void mxr_streamer_put(struct mxr_device *mdev)
-{
- mutex_lock(&mdev->mutex);
- --mdev->n_streamer;
- mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer);
- if (mdev->n_streamer == 0) {
- int ret;
- struct v4l2_subdev *sd = to_outsd(mdev);
-
- mxr_reg_streamoff(mdev);
- /* vsync applies Mixer setup */
- ret = mxr_reg_wait4vsync(mdev);
- WARN(ret, "failed to get vsync (%d) from output\n", ret);
- ret = v4l2_subdev_call(sd, video, s_stream, 0);
- WARN(ret, "stopping stream failed for output %s\n", sd->name);
- }
- WARN(mdev->n_streamer < 0, "negative number of streamers (%d)\n",
- mdev->n_streamer);
- mutex_unlock(&mdev->mutex);
- mxr_reg_dump(mdev);
-}
-
-void mxr_output_get(struct mxr_device *mdev)
-{
- mutex_lock(&mdev->mutex);
- ++mdev->n_output;
- mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output);
- /* turn on auxiliary driver */
- if (mdev->n_output == 1)
- v4l2_subdev_call(to_outsd(mdev), core, s_power, 1);
- mutex_unlock(&mdev->mutex);
-}
-
-void mxr_output_put(struct mxr_device *mdev)
-{
- mutex_lock(&mdev->mutex);
- --mdev->n_output;
- mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output);
- /* turn on auxiliary driver */
- if (mdev->n_output == 0)
- v4l2_subdev_call(to_outsd(mdev), core, s_power, 0);
- WARN(mdev->n_output < 0, "negative number of output users (%d)\n",
- mdev->n_output);
- mutex_unlock(&mdev->mutex);
-}
-
-int mxr_power_get(struct mxr_device *mdev)
-{
- int ret = pm_runtime_get_sync(mdev->dev);
-
- /* returning 1 means that power is already enabled,
- * so zero success be returned */
- if (IS_ERR_VALUE(ret))
- return ret;
- return 0;
-}
-
-void mxr_power_put(struct mxr_device *mdev)
-{
- pm_runtime_put_sync(mdev->dev);
-}
-
-/* --------- RESOURCE MANAGEMENT -------------*/
-
-static int __devinit mxr_acquire_plat_resources(struct mxr_device *mdev,
- struct platform_device *pdev)
-{
- struct resource *res;
- int ret;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr");
- if (res == NULL) {
- mxr_err(mdev, "get memory resource failed.\n");
- ret = -ENXIO;
- goto fail;
- }
-
- mdev->res.mxr_regs = ioremap(res->start, resource_size(res));
- if (mdev->res.mxr_regs == NULL) {
- mxr_err(mdev, "register mapping failed.\n");
- ret = -ENXIO;
- goto fail;
- }
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp");
- if (res == NULL) {
- mxr_err(mdev, "get memory resource failed.\n");
- ret = -ENXIO;
- goto fail_mxr_regs;
- }
-
- mdev->res.vp_regs = ioremap(res->start, resource_size(res));
- if (mdev->res.vp_regs == NULL) {
- mxr_err(mdev, "register mapping failed.\n");
- ret = -ENXIO;
- goto fail_mxr_regs;
- }
-
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq");
- if (res == NULL) {
- mxr_err(mdev, "get interrupt resource failed.\n");
- ret = -ENXIO;
- goto fail_vp_regs;
- }
-
- ret = request_irq(res->start, mxr_irq_handler, 0, "s5p-mixer", mdev);
- if (ret) {
- mxr_err(mdev, "request interrupt failed.\n");
- goto fail_vp_regs;
- }
- mdev->res.irq = res->start;
-
- return 0;
-
-fail_vp_regs:
- iounmap(mdev->res.vp_regs);
-
-fail_mxr_regs:
- iounmap(mdev->res.mxr_regs);
-
-fail:
- return ret;
-}
-
-static void mxr_release_plat_resources(struct mxr_device *mdev)
-{
- free_irq(mdev->res.irq, mdev);
- iounmap(mdev->res.vp_regs);
- iounmap(mdev->res.mxr_regs);
-}
-
-static void mxr_release_clocks(struct mxr_device *mdev)
-{
- struct mxr_resources *res = &mdev->res;
-
- if (!IS_ERR_OR_NULL(res->sclk_dac))
- clk_put(res->sclk_dac);
- if (!IS_ERR_OR_NULL(res->sclk_hdmi))
- clk_put(res->sclk_hdmi);
- if (!IS_ERR_OR_NULL(res->sclk_mixer))
- clk_put(res->sclk_mixer);
- if (!IS_ERR_OR_NULL(res->vp))
- clk_put(res->vp);
- if (!IS_ERR_OR_NULL(res->mixer))
- clk_put(res->mixer);
-}
-
-static int mxr_acquire_clocks(struct mxr_device *mdev)
-{
- struct mxr_resources *res = &mdev->res;
- struct device *dev = mdev->dev;
-
- res->mixer = clk_get(dev, "mixer");
- if (IS_ERR_OR_NULL(res->mixer)) {
- mxr_err(mdev, "failed to get clock 'mixer'\n");
- goto fail;
- }
- res->vp = clk_get(dev, "vp");
- if (IS_ERR_OR_NULL(res->vp)) {
- mxr_err(mdev, "failed to get clock 'vp'\n");
- goto fail;
- }
- res->sclk_mixer = clk_get(dev, "sclk_mixer");
- if (IS_ERR_OR_NULL(res->sclk_mixer)) {
- mxr_err(mdev, "failed to get clock 'sclk_mixer'\n");
- goto fail;
- }
- res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
- if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
- mxr_err(mdev, "failed to get clock 'sclk_hdmi'\n");
- goto fail;
- }
- res->sclk_dac = clk_get(dev, "sclk_dac");
- if (IS_ERR_OR_NULL(res->sclk_dac)) {
- mxr_err(mdev, "failed to get clock 'sclk_dac'\n");
- goto fail;
- }
-
- return 0;
-fail:
- mxr_release_clocks(mdev);
- return -ENODEV;
-}
-
-static int __devinit mxr_acquire_resources(struct mxr_device *mdev,
- struct platform_device *pdev)
-{
- int ret;
- ret = mxr_acquire_plat_resources(mdev, pdev);
-
- if (ret)
- goto fail;
-
- ret = mxr_acquire_clocks(mdev);
- if (ret)
- goto fail_plat;
-
- mxr_info(mdev, "resources acquired\n");
- return 0;
-
-fail_plat:
- mxr_release_plat_resources(mdev);
-fail:
- mxr_err(mdev, "resources acquire failed\n");
- return ret;
-}
-
-static void mxr_release_resources(struct mxr_device *mdev)
-{
- mxr_release_clocks(mdev);
- mxr_release_plat_resources(mdev);
- memset(&mdev->res, 0, sizeof mdev->res);
-}
-
-static void mxr_release_layers(struct mxr_device *mdev)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(mdev->layer); ++i)
- if (mdev->layer[i])
- mxr_layer_release(mdev->layer[i]);
-}
-
-static int __devinit mxr_acquire_layers(struct mxr_device *mdev,
- struct mxr_platform_data *pdata)
-{
- mdev->layer[0] = mxr_graph_layer_create(mdev, 0);
- mdev->layer[1] = mxr_graph_layer_create(mdev, 1);
- mdev->layer[2] = mxr_vp_layer_create(mdev, 0);
-
- if (!mdev->layer[0] || !mdev->layer[1] || !mdev->layer[2]) {
- mxr_err(mdev, "failed to acquire layers\n");
- goto fail;
- }
-
- return 0;
-
-fail:
- mxr_release_layers(mdev);
- return -ENODEV;
-}
-
-/* ---------- POWER MANAGEMENT ----------- */
-
-static int mxr_runtime_resume(struct device *dev)
-{
- struct mxr_device *mdev = to_mdev(dev);
- struct mxr_resources *res = &mdev->res;
-
- mxr_dbg(mdev, "resume - start\n");
- mutex_lock(&mdev->mutex);
- /* turn clocks on */
- clk_enable(res->mixer);
- clk_enable(res->vp);
- clk_enable(res->sclk_mixer);
- /* apply default configuration */
- mxr_reg_reset(mdev);
- mxr_dbg(mdev, "resume - finished\n");
-
- mutex_unlock(&mdev->mutex);
- return 0;
-}
-
-static int mxr_runtime_suspend(struct device *dev)
-{
- struct mxr_device *mdev = to_mdev(dev);
- struct mxr_resources *res = &mdev->res;
- mxr_dbg(mdev, "suspend - start\n");
- mutex_lock(&mdev->mutex);
- /* turn clocks off */
- clk_disable(res->sclk_mixer);
- clk_disable(res->vp);
- clk_disable(res->mixer);
- mutex_unlock(&mdev->mutex);
- mxr_dbg(mdev, "suspend - finished\n");
- return 0;
-}
-
-static const struct dev_pm_ops mxr_pm_ops = {
- .runtime_suspend = mxr_runtime_suspend,
- .runtime_resume = mxr_runtime_resume,
-};
-
-/* --------- DRIVER INITIALIZATION ---------- */
-
-static int __devinit mxr_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct mxr_platform_data *pdata = dev->platform_data;
- struct mxr_device *mdev;
- int ret;
-
- /* mdev does not exist yet so no mxr_dbg is used */
- dev_info(dev, "probe start\n");
-
- mdev = kzalloc(sizeof *mdev, GFP_KERNEL);
- if (!mdev) {
- mxr_err(mdev, "not enough memory.\n");
- ret = -ENOMEM;
- goto fail;
- }
-
- /* setup pointer to master device */
- mdev->dev = dev;
-
- mutex_init(&mdev->mutex);
- spin_lock_init(&mdev->reg_slock);
- init_waitqueue_head(&mdev->event_queue);
-
- /* acquire resources: regs, irqs, clocks, regulators */
- ret = mxr_acquire_resources(mdev, pdev);
- if (ret)
- goto fail_mem;
-
- /* configure resources for video output */
- ret = mxr_acquire_video(mdev, mxr_output_conf,
- ARRAY_SIZE(mxr_output_conf));
- if (ret)
- goto fail_resources;
-
- /* configure layers */
- ret = mxr_acquire_layers(mdev, pdata);
- if (ret)
- goto fail_video;
-
- pm_runtime_enable(dev);
-
- mxr_info(mdev, "probe successful\n");
- return 0;
-
-fail_video:
- mxr_release_video(mdev);
-
-fail_resources:
- mxr_release_resources(mdev);
-
-fail_mem:
- kfree(mdev);
-
-fail:
- dev_info(dev, "probe failed\n");
- return ret;
-}
-
-static int __devexit mxr_remove(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct mxr_device *mdev = to_mdev(dev);
-
- pm_runtime_disable(dev);
-
- mxr_release_layers(mdev);
- mxr_release_video(mdev);
- mxr_release_resources(mdev);
-
- kfree(mdev);
-
- dev_info(dev, "remove successful\n");
- return 0;
-}
-
-static struct platform_driver mxr_driver __refdata = {
- .probe = mxr_probe,
- .remove = __devexit_p(mxr_remove),
- .driver = {
- .name = MXR_DRIVER_NAME,
- .owner = THIS_MODULE,
- .pm = &mxr_pm_ops,
- }
-};
-
-static int __init mxr_init(void)
-{
- int i, ret;
- static const char banner[] __initconst = KERN_INFO
- "Samsung TV Mixer driver, "
- "(c) 2010-2011 Samsung Electronics Co., Ltd.\n";
- printk(banner);
-
- /* Loading auxiliary modules */
- for (i = 0; i < ARRAY_SIZE(mxr_output_conf); ++i)
- request_module(mxr_output_conf[i].module_name);
-
- ret = platform_driver_register(&mxr_driver);
- if (ret != 0) {
- printk(KERN_ERR "registration of MIXER driver failed\n");
- return -ENXIO;
- }
-
- return 0;
-}
-module_init(mxr_init);
-
-static void __exit mxr_exit(void)
-{
- platform_driver_unregister(&mxr_driver);
-}
-module_exit(mxr_exit);
diff --git a/drivers/media/video/s5p-tv/mixer_grp_layer.c b/drivers/media/video/s5p-tv/mixer_grp_layer.c
deleted file mode 100644
index b93a21f5aa1..00000000000
--- a/drivers/media/video/s5p-tv/mixer_grp_layer.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Samsung TV Mixer driver
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *
- * Tomasz Stanislawski, <t.stanislaws@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundiation. either version 2 of the License,
- * or (at your option) any later version
- */
-
-#include "mixer.h"
-
-#include <media/videobuf2-dma-contig.h>
-
-/* FORMAT DEFINITIONS */
-
-static const struct mxr_format mxr_fb_fmt_rgb565 = {
- .name = "RGB565",
- .fourcc = V4L2_PIX_FMT_RGB565,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .num_planes = 1,
- .plane = {
- { .width = 1, .height = 1, .size = 2 },
- },
- .num_subframes = 1,
- .cookie = 4,
-};
-
-static const struct mxr_format mxr_fb_fmt_argb1555 = {
- .name = "ARGB1555",
- .num_planes = 1,
- .fourcc = V4L2_PIX_FMT_RGB555,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .plane = {
- { .width = 1, .height = 1, .size = 2 },
- },
- .num_subframes = 1,
- .cookie = 5,
-};
-
-static const struct mxr_format mxr_fb_fmt_argb4444 = {
- .name = "ARGB4444",
- .num_planes = 1,
- .fourcc = V4L2_PIX_FMT_RGB444,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .plane = {
- { .width = 1, .height = 1, .size = 2 },
- },
- .num_subframes = 1,
- .cookie = 6,
-};
-
-static const struct mxr_format mxr_fb_fmt_argb8888 = {
- .name = "ARGB8888",
- .fourcc = V4L2_PIX_FMT_BGR32,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .num_planes = 1,
- .plane = {
- { .width = 1, .height = 1, .size = 4 },
- },
- .num_subframes = 1,
- .cookie = 7,
-};
-
-static const struct mxr_format *mxr_graph_format[] = {
- &mxr_fb_fmt_rgb565,
- &mxr_fb_fmt_argb1555,
- &mxr_fb_fmt_argb4444,
- &mxr_fb_fmt_argb8888,
-};
-
-/* AUXILIARY CALLBACKS */
-
-static void mxr_graph_layer_release(struct mxr_layer *layer)
-{
- mxr_base_layer_unregister(layer);
- mxr_base_layer_release(layer);
-}
-
-static void mxr_graph_buffer_set(struct mxr_layer *layer,
- struct mxr_buffer *buf)
-{
- dma_addr_t addr = 0;
-
- if (buf)
- addr = vb2_dma_contig_plane_dma_addr(&buf->vb, 0);
- mxr_reg_graph_buffer(layer->mdev, layer->idx, addr);
-}
-
-static void mxr_graph_stream_set(struct mxr_layer *layer, int en)
-{
- mxr_reg_graph_layer_stream(layer->mdev, layer->idx, en);
-}
-
-static void mxr_graph_format_set(struct mxr_layer *layer)
-{
- mxr_reg_graph_format(layer->mdev, layer->idx,
- layer->fmt, &layer->geo);
-}
-
-static inline unsigned int closest(unsigned int x, unsigned int a,
- unsigned int b, unsigned long flags)
-{
- unsigned int mid = (a + b) / 2;
-
- /* choosing closest value with constraints according to table:
- * -------------+-----+-----+-----+-------+
- * flags | 0 | LE | GE | LE|GE |
- * -------------+-----+-----+-----+-------+
- * x <= a | a | a | a | a |
- * a < x <= mid | a | a | b | a |
- * mid < x < b | b | a | b | b |
- * b <= x | b | b | b | b |
- * -------------+-----+-----+-----+-------+
- */
-
- /* remove all non-constraint flags */
- flags &= V4L2_SEL_FLAG_LE | V4L2_SEL_FLAG_GE;
-
- if (x <= a)
- return a;
- if (x >= b)
- return b;
- if (flags == V4L2_SEL_FLAG_LE)
- return a;
- if (flags == V4L2_SEL_FLAG_GE)
- return b;
- if (x <= mid)
- return a;
- return b;
-}
-
-static inline unsigned int do_center(unsigned int center,
- unsigned int size, unsigned int upper, unsigned int flags)
-{
- unsigned int lower;
-
- if (flags & MXR_NO_OFFSET)
- return 0;
-
- lower = center - min(center, size / 2);
- return min(lower, upper - size);
-}
-
-static void mxr_graph_fix_geometry(struct mxr_layer *layer,
- enum mxr_geometry_stage stage, unsigned long flags)
-{
- struct mxr_geometry *geo = &layer->geo;
- struct mxr_crop *src = &geo->src;
- struct mxr_crop *dst = &geo->dst;
- unsigned int x_center, y_center;
-
- switch (stage) {
-
- case MXR_GEOMETRY_SINK: /* nothing to be fixed here */
- flags = 0;
- /* fall through */
-
- case MXR_GEOMETRY_COMPOSE:
- /* remember center of the area */
- x_center = dst->x_offset + dst->width / 2;
- y_center = dst->y_offset + dst->height / 2;
- /* round up/down to 2 multiple depending on flags */
- if (flags & V4L2_SEL_FLAG_LE) {
- dst->width = round_down(dst->width, 2);
- dst->height = round_down(dst->height, 2);
- } else {
- dst->width = round_up(dst->width, 2);
- dst->height = round_up(dst->height, 2);
- }
- /* assure that compose rect is inside display area */
- dst->width = min(dst->width, dst->full_width);
- dst->height = min(dst->height, dst->full_height);
-
- /* ensure that compose is reachable using 2x scaling */
- dst->width = min(dst->width, 2 * src->full_width);
- dst->height = min(dst->height, 2 * src->full_height);
-
- /* setup offsets */
- dst->x_offset = do_center(x_center, dst->width,
- dst->full_width, flags);
- dst->y_offset = do_center(y_center, dst->height,
- dst->full_height, flags);
- flags = 0;
- /* fall through */
-
- case MXR_GEOMETRY_CROP:
- /* remember center of the area */
- x_center = src->x_offset + src->width / 2;
- y_center = src->y_offset + src->height / 2;
- /* ensure that cropping area lies inside the buffer */
- if (src->full_width < dst->width)
- src->width = dst->width / 2;
- else
- src->width = closest(src->width, dst->width / 2,
- dst->width, flags);
-
- if (src->width == dst->width)
- geo->x_ratio = 0;
- else
- geo->x_ratio = 1;
-
- if (src->full_height < dst->height)
- src->height = dst->height / 2;
- else
- src->height = closest(src->height, dst->height / 2,
- dst->height, flags);
-
- if (src->height == dst->height)
- geo->y_ratio = 0;
- else
- geo->y_ratio = 1;
-
- /* setup offsets */
- src->x_offset = do_center(x_center, src->width,
- src->full_width, flags);
- src->y_offset = do_center(y_center, src->height,
- src->full_height, flags);
- flags = 0;
- /* fall through */
- case MXR_GEOMETRY_SOURCE:
- src->full_width = clamp_val(src->full_width,
- src->width + src->x_offset, 32767);
- src->full_height = clamp_val(src->full_height,
- src->height + src->y_offset, 2047);
- };
-}
-
-/* PUBLIC API */
-
-struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx)
-{
- struct mxr_layer *layer;
- int ret;
- struct mxr_layer_ops ops = {
- .release = mxr_graph_layer_release,
- .buffer_set = mxr_graph_buffer_set,
- .stream_set = mxr_graph_stream_set,
- .format_set = mxr_graph_format_set,
- .fix_geometry = mxr_graph_fix_geometry,
- };
- char name[32];
-
- sprintf(name, "graph%d", idx);
-
- layer = mxr_base_layer_create(mdev, idx, name, &ops);
- if (layer == NULL) {
- mxr_err(mdev, "failed to initialize layer(%d) base\n", idx);
- goto fail;
- }
-
- layer->fmt_array = mxr_graph_format;
- layer->fmt_array_size = ARRAY_SIZE(mxr_graph_format);
-
- ret = mxr_base_layer_register(layer);
- if (ret)
- goto fail_layer;
-
- return layer;
-
-fail_layer:
- mxr_base_layer_release(layer);
-
-fail:
- return NULL;
-}
-
diff --git a/drivers/media/video/s5p-tv/mixer_reg.c b/drivers/media/video/s5p-tv/mixer_reg.c
deleted file mode 100644
index 3b1670a045f..00000000000
--- a/drivers/media/video/s5p-tv/mixer_reg.c
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Samsung TV Mixer driver
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *
- * Tomasz Stanislawski, <t.stanislaws@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundiation. either version 2 of the License,
- * or (at your option) any later version
- */
-
-#include "mixer.h"
-#include "regs-mixer.h"
-#include "regs-vp.h"
-
-#include <linux/delay.h>
-
-/* Register access subroutines */
-
-static inline u32 vp_read(struct mxr_device *mdev, u32 reg_id)
-{
- return readl(mdev->res.vp_regs + reg_id);
-}
-
-static inline void vp_write(struct mxr_device *mdev, u32 reg_id, u32 val)
-{
- writel(val, mdev->res.vp_regs + reg_id);
-}
-
-static inline void vp_write_mask(struct mxr_device *mdev, u32 reg_id,
- u32 val, u32 mask)
-{
- u32 old = vp_read(mdev, reg_id);
-
- val = (val & mask) | (old & ~mask);
- writel(val, mdev->res.vp_regs + reg_id);
-}
-
-static inline u32 mxr_read(struct mxr_device *mdev, u32 reg_id)
-{
- return readl(mdev->res.mxr_regs + reg_id);
-}
-
-static inline void mxr_write(struct mxr_device *mdev, u32 reg_id, u32 val)
-{
- writel(val, mdev->res.mxr_regs + reg_id);
-}
-
-static inline void mxr_write_mask(struct mxr_device *mdev, u32 reg_id,
- u32 val, u32 mask)
-{
- u32 old = mxr_read(mdev, reg_id);
-
- val = (val & mask) | (old & ~mask);
- writel(val, mdev->res.mxr_regs + reg_id);
-}
-
-void mxr_vsync_set_update(struct mxr_device *mdev, int en)
-{
- /* block update on vsync */
- mxr_write_mask(mdev, MXR_STATUS, en ? MXR_STATUS_SYNC_ENABLE : 0,
- MXR_STATUS_SYNC_ENABLE);
- vp_write(mdev, VP_SHADOW_UPDATE, en ? VP_SHADOW_UPDATE_ENABLE : 0);
-}
-
-static void __mxr_reg_vp_reset(struct mxr_device *mdev)
-{
- int tries = 100;
-
- vp_write(mdev, VP_SRESET, VP_SRESET_PROCESSING);
- for (tries = 100; tries; --tries) {
- /* waiting until VP_SRESET_PROCESSING is 0 */
- if (~vp_read(mdev, VP_SRESET) & VP_SRESET_PROCESSING)
- break;
- mdelay(10);
- }
- WARN(tries == 0, "failed to reset Video Processor\n");
-}
-
-static void mxr_reg_vp_default_filter(struct mxr_device *mdev);
-
-void mxr_reg_reset(struct mxr_device *mdev)
-{
- unsigned long flags;
- u32 val; /* value stored to register */
-
- spin_lock_irqsave(&mdev->reg_slock, flags);
- mxr_vsync_set_update(mdev, MXR_DISABLE);
-
- /* set output in RGB888 mode */
- mxr_write(mdev, MXR_CFG, MXR_CFG_OUT_RGB888);
-
- /* 16 beat burst in DMA */
- mxr_write_mask(mdev, MXR_STATUS, MXR_STATUS_16_BURST,
- MXR_STATUS_BURST_MASK);
-
- /* setting default layer priority: layer1 > video > layer0
- * because typical usage scenario would be
- * layer0 - framebuffer
- * video - video overlay
- * layer1 - OSD
- */
- val = MXR_LAYER_CFG_GRP0_VAL(1);
- val |= MXR_LAYER_CFG_VP_VAL(2);
- val |= MXR_LAYER_CFG_GRP1_VAL(3);
- mxr_write(mdev, MXR_LAYER_CFG, val);
-
- /* use dark gray background color */
- mxr_write(mdev, MXR_BG_COLOR0, 0x808080);
- mxr_write(mdev, MXR_BG_COLOR1, 0x808080);
- mxr_write(mdev, MXR_BG_COLOR2, 0x808080);
-
- /* setting graphical layers */
-
- val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
- val |= MXR_GRP_CFG_BLEND_PRE_MUL; /* premul mode */
- val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */
-
- /* the same configuration for both layers */
- mxr_write(mdev, MXR_GRAPHIC_CFG(0), val);
- mxr_write(mdev, MXR_GRAPHIC_CFG(1), val);
-
- /* configuration of Video Processor Registers */
- __mxr_reg_vp_reset(mdev);
- mxr_reg_vp_default_filter(mdev);
-
- /* enable all interrupts */
- mxr_write_mask(mdev, MXR_INT_EN, ~0, MXR_INT_EN_ALL);
-
- mxr_vsync_set_update(mdev, MXR_ENABLE);
- spin_unlock_irqrestore(&mdev->reg_slock, flags);
-}
-
-void mxr_reg_graph_format(struct mxr_device *mdev, int idx,
- const struct mxr_format *fmt, const struct mxr_geometry *geo)
-{
- u32 val;
- unsigned long flags;
-
- spin_lock_irqsave(&mdev->reg_slock, flags);
- mxr_vsync_set_update(mdev, MXR_DISABLE);
-
- /* setup format */
- mxr_write_mask(mdev, MXR_GRAPHIC_CFG(idx),
- MXR_GRP_CFG_FORMAT_VAL(fmt->cookie), MXR_GRP_CFG_FORMAT_MASK);
-
- /* setup geometry */
- mxr_write(mdev, MXR_GRAPHIC_SPAN(idx), geo->src.full_width);
- val = MXR_GRP_WH_WIDTH(geo->src.width);
- val |= MXR_GRP_WH_HEIGHT(geo->src.height);
- val |= MXR_GRP_WH_H_SCALE(geo->x_ratio);
- val |= MXR_GRP_WH_V_SCALE(geo->y_ratio);
- mxr_write(mdev, MXR_GRAPHIC_WH(idx), val);
-
- /* setup offsets in source image */
- val = MXR_GRP_SXY_SX(geo->src.x_offset);
- val |= MXR_GRP_SXY_SY(geo->src.y_offset);
- mxr_write(mdev, MXR_GRAPHIC_SXY(idx), val);
-
- /* setup offsets in display image */
- val = MXR_GRP_DXY_DX(geo->dst.x_offset);
- val |= MXR_GRP_DXY_DY(geo->dst.y_offset);
- mxr_write(mdev, MXR_GRAPHIC_DXY(idx), val);
-
- mxr_vsync_set_update(mdev, MXR_ENABLE);
- spin_unlock_irqrestore(&mdev->reg_slock, flags);
-}
-
-void mxr_reg_vp_format(struct mxr_device *mdev,
- const struct mxr_format *fmt, const struct mxr_geometry *geo)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mdev->reg_slock, flags);
- mxr_vsync_set_update(mdev, MXR_DISABLE);
-
- vp_write_mask(mdev, VP_MODE, fmt->cookie, VP_MODE_FMT_MASK);
-
- /* setting size of input image */
- vp_write(mdev, VP_IMG_SIZE_Y, VP_IMG_HSIZE(geo->src.full_width) |
- VP_IMG_VSIZE(geo->src.full_height));
- /* chroma height has to reduced by 2 to avoid chroma distorions */
- vp_write(mdev, VP_IMG_SIZE_C, VP_IMG_HSIZE(geo->src.full_width) |
- VP_IMG_VSIZE(geo->src.full_height / 2));
-
- vp_write(mdev, VP_SRC_WIDTH, geo->src.width);
- vp_write(mdev, VP_SRC_HEIGHT, geo->src.height);
- vp_write(mdev, VP_SRC_H_POSITION,
- VP_SRC_H_POSITION_VAL(geo->src.x_offset));
- vp_write(mdev, VP_SRC_V_POSITION, geo->src.y_offset);
-
- vp_write(mdev, VP_DST_WIDTH, geo->dst.width);
- vp_write(mdev, VP_DST_H_POSITION, geo->dst.x_offset);
- if (geo->dst.field == V4L2_FIELD_INTERLACED) {
- vp_write(mdev, VP_DST_HEIGHT, geo->dst.height / 2);
- vp_write(mdev, VP_DST_V_POSITION, geo->dst.y_offset / 2);
- } else {
- vp_write(mdev, VP_DST_HEIGHT, geo->dst.height);
- vp_write(mdev, VP_DST_V_POSITION, geo->dst.y_offset);
- }
-
- vp_write(mdev, VP_H_RATIO, geo->x_ratio);
- vp_write(mdev, VP_V_RATIO, geo->y_ratio);
-
- vp_write(mdev, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
-
- mxr_vsync_set_update(mdev, MXR_ENABLE);
- spin_unlock_irqrestore(&mdev->reg_slock, flags);
-
-}
-
-void mxr_reg_graph_buffer(struct mxr_device *mdev, int idx, dma_addr_t addr)
-{
- u32 val = addr ? ~0 : 0;
- unsigned long flags;
-
- spin_lock_irqsave(&mdev->reg_slock, flags);
- mxr_vsync_set_update(mdev, MXR_DISABLE);
-
- if (idx == 0)
- mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_GRP0_ENABLE);
- else
- mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
- mxr_write(mdev, MXR_GRAPHIC_BASE(idx), addr);
-
- mxr_vsync_set_update(mdev, MXR_ENABLE);
- spin_unlock_irqrestore(&mdev->reg_slock, flags);
-}
-
-void mxr_reg_vp_buffer(struct mxr_device *mdev,
- dma_addr_t luma_addr[2], dma_addr_t chroma_addr[2])
-{
- u32 val = luma_addr[0] ? ~0 : 0;
- unsigned long flags;
-
- spin_lock_irqsave(&mdev->reg_slock, flags);
- mxr_vsync_set_update(mdev, MXR_DISABLE);
-
- mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_VP_ENABLE);
- vp_write_mask(mdev, VP_ENABLE, val, VP_ENABLE_ON);
- /* TODO: fix tiled mode */
- vp_write(mdev, VP_TOP_Y_PTR, luma_addr[0]);
- vp_write(mdev, VP_TOP_C_PTR, chroma_addr[0]);
- vp_write(mdev, VP_BOT_Y_PTR, luma_addr[1]);
- vp_write(mdev, VP_BOT_C_PTR, chroma_addr[1]);
-
- mxr_vsync_set_update(mdev, MXR_ENABLE);
- spin_unlock_irqrestore(&mdev->reg_slock, flags);
-}
-
-static void mxr_irq_layer_handle(struct mxr_layer *layer)
-{
- struct list_head *head = &layer->enq_list;
- struct mxr_buffer *done;
-
- /* skip non-existing layer */
- if (layer == NULL)
- return;
-
- spin_lock(&layer->enq_slock);
- if (layer->state == MXR_LAYER_IDLE)
- goto done;
-
- done = layer->shadow_buf;
- layer->shadow_buf = layer->update_buf;
-
- if (list_empty(head)) {
- if (layer->state != MXR_LAYER_STREAMING)
- layer->update_buf = NULL;
- } else {
- struct mxr_buffer *next;
- next = list_first_entry(head, struct mxr_buffer, list);
- list_del(&next->list);
- layer->update_buf = next;
- }
-
- layer->ops.buffer_set(layer, layer->update_buf);
-
- if (done && done != layer->shadow_buf)
- vb2_buffer_done(&done->vb, VB2_BUF_STATE_DONE);
-
-done:
- spin_unlock(&layer->enq_slock);
-}
-
-irqreturn_t mxr_irq_handler(int irq, void *dev_data)
-{
- struct mxr_device *mdev = dev_data;
- u32 i, val;
-
- spin_lock(&mdev->reg_slock);
- val = mxr_read(mdev, MXR_INT_STATUS);
-
- /* wake up process waiting for VSYNC */
- if (val & MXR_INT_STATUS_VSYNC) {
- set_bit(MXR_EVENT_VSYNC, &mdev->event_flags);
- /* toggle TOP field event if working in interlaced mode */
- if (~mxr_read(mdev, MXR_CFG) & MXR_CFG_SCAN_PROGRASSIVE)
- change_bit(MXR_EVENT_TOP, &mdev->event_flags);
- wake_up(&mdev->event_queue);
- /* vsync interrupt use different bit for read and clear */
- val &= ~MXR_INT_STATUS_VSYNC;
- val |= MXR_INT_CLEAR_VSYNC;
- }
-
- /* clear interrupts */
- mxr_write(mdev, MXR_INT_STATUS, val);
-
- spin_unlock(&mdev->reg_slock);
- /* leave on non-vsync event */
- if (~val & MXR_INT_CLEAR_VSYNC)
- return IRQ_HANDLED;
- /* skip layer update on bottom field */
- if (!test_bit(MXR_EVENT_TOP, &mdev->event_flags))
- return IRQ_HANDLED;
- for (i = 0; i < MXR_MAX_LAYERS; ++i)
- mxr_irq_layer_handle(mdev->layer[i]);
- return IRQ_HANDLED;
-}
-
-void mxr_reg_s_output(struct mxr_device *mdev, int cookie)
-{
- u32 val;
-
- val = cookie == 0 ? MXR_CFG_DST_SDO : MXR_CFG_DST_HDMI;
- mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_DST_MASK);
-}
-
-void mxr_reg_streamon(struct mxr_device *mdev)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mdev->reg_slock, flags);
- /* single write -> no need to block vsync update */
-
- /* start MIXER */
- mxr_write_mask(mdev, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
- set_bit(MXR_EVENT_TOP, &mdev->event_flags);
-
- spin_unlock_irqrestore(&mdev->reg_slock, flags);
-}
-
-void mxr_reg_streamoff(struct mxr_device *mdev)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mdev->reg_slock, flags);
- /* single write -> no need to block vsync update */
-
- /* stop MIXER */
- mxr_write_mask(mdev, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
-
- spin_unlock_irqrestore(&mdev->reg_slock, flags);
-}
-
-int mxr_reg_wait4vsync(struct mxr_device *mdev)
-{
- int ret;
-
- clear_bit(MXR_EVENT_VSYNC, &mdev->event_flags);
- /* TODO: consider adding interruptible */
- ret = wait_event_timeout(mdev->event_queue,
- test_bit(MXR_EVENT_VSYNC, &mdev->event_flags),
- msecs_to_jiffies(1000));
- if (ret > 0)
- return 0;
- if (ret < 0)
- return ret;
- mxr_warn(mdev, "no vsync detected - timeout\n");
- return -ETIME;
-}
-
-void mxr_reg_set_mbus_fmt(struct mxr_device *mdev,
- struct v4l2_mbus_framefmt *fmt)
-{
- u32 val = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&mdev->reg_slock, flags);
- mxr_vsync_set_update(mdev, MXR_DISABLE);
-
- /* selecting colorspace accepted by output */
- if (fmt->colorspace == V4L2_COLORSPACE_JPEG)
- val |= MXR_CFG_OUT_YUV444;
- else
- val |= MXR_CFG_OUT_RGB888;
-
- /* choosing between interlace and progressive mode */
- if (fmt->field == V4L2_FIELD_INTERLACED)
- val |= MXR_CFG_SCAN_INTERLACE;
- else
- val |= MXR_CFG_SCAN_PROGRASSIVE;
-
- /* choosing between porper HD and SD mode */
- if (fmt->height == 480)
- val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
- else if (fmt->height == 576)
- val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
- else if (fmt->height == 720)
- val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
- else if (fmt->height == 1080)
- val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
- else
- WARN(1, "unrecognized mbus height %u!\n", fmt->height);
-
- mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_SCAN_MASK |
- MXR_CFG_OUT_MASK);
-
- val = (fmt->field == V4L2_FIELD_INTERLACED) ? ~0 : 0;
- vp_write_mask(mdev, VP_MODE, val,
- VP_MODE_LINE_SKIP | VP_MODE_FIELD_ID_AUTO_TOGGLING);
-
- mxr_vsync_set_update(mdev, MXR_ENABLE);
- spin_unlock_irqrestore(&mdev->reg_slock, flags);
-}
-
-void mxr_reg_graph_layer_stream(struct mxr_device *mdev, int idx, int en)
-{
- /* no extra actions need to be done */
-}
-
-void mxr_reg_vp_layer_stream(struct mxr_device *mdev, int en)
-{
- /* no extra actions need to be done */
-}
-
-static const u8 filter_y_horiz_tap8[] = {
- 0, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 0, 0, 0,
- 0, 2, 4, 5, 6, 6, 6, 6,
- 6, 5, 5, 4, 3, 2, 1, 1,
- 0, -6, -12, -16, -18, -20, -21, -20,
- -20, -18, -16, -13, -10, -8, -5, -2,
- 127, 126, 125, 121, 114, 107, 99, 89,
- 79, 68, 57, 46, 35, 25, 16, 8,
-};
-
-static const u8 filter_y_vert_tap4[] = {
- 0, -3, -6, -8, -8, -8, -8, -7,
- -6, -5, -4, -3, -2, -1, -1, 0,
- 127, 126, 124, 118, 111, 102, 92, 81,
- 70, 59, 48, 37, 27, 19, 11, 5,
- 0, 5, 11, 19, 27, 37, 48, 59,
- 70, 81, 92, 102, 111, 118, 124, 126,
- 0, 0, -1, -1, -2, -3, -4, -5,
- -6, -7, -8, -8, -8, -8, -6, -3,
-};
-
-static const u8 filter_cr_horiz_tap4[] = {
- 0, -3, -6, -8, -8, -8, -8, -7,
- -6, -5, -4, -3, -2, -1, -1, 0,
- 127, 126, 124, 118, 111, 102, 92, 81,
- 70, 59, 48, 37, 27, 19, 11, 5,
-};
-
-static inline void mxr_reg_vp_filter_set(struct mxr_device *mdev,
- int reg_id, const u8 *data, unsigned int size)
-{
- /* assure 4-byte align */
- BUG_ON(size & 3);
- for (; size; size -= 4, reg_id += 4, data += 4) {
- u32 val = (data[0] << 24) | (data[1] << 16) |
- (data[2] << 8) | data[3];
- vp_write(mdev, reg_id, val);
- }
-}
-
-static void mxr_reg_vp_default_filter(struct mxr_device *mdev)
-{
- mxr_reg_vp_filter_set(mdev, VP_POLY8_Y0_LL,
- filter_y_horiz_tap8, sizeof filter_y_horiz_tap8);
- mxr_reg_vp_filter_set(mdev, VP_POLY4_Y0_LL,
- filter_y_vert_tap4, sizeof filter_y_vert_tap4);
- mxr_reg_vp_filter_set(mdev, VP_POLY4_C0_LL,
- filter_cr_horiz_tap4, sizeof filter_cr_horiz_tap4);
-}
-
-static void mxr_reg_mxr_dump(struct mxr_device *mdev)
-{
-#define DUMPREG(reg_id) \
-do { \
- mxr_dbg(mdev, #reg_id " = %08x\n", \
- (u32)readl(mdev->res.mxr_regs + reg_id)); \
-} while (0)
-
- DUMPREG(MXR_STATUS);
- DUMPREG(MXR_CFG);
- DUMPREG(MXR_INT_EN);
- DUMPREG(MXR_INT_STATUS);
-
- DUMPREG(MXR_LAYER_CFG);
- DUMPREG(MXR_VIDEO_CFG);
-
- DUMPREG(MXR_GRAPHIC0_CFG);
- DUMPREG(MXR_GRAPHIC0_BASE);
- DUMPREG(MXR_GRAPHIC0_SPAN);
- DUMPREG(MXR_GRAPHIC0_WH);
- DUMPREG(MXR_GRAPHIC0_SXY);
- DUMPREG(MXR_GRAPHIC0_DXY);
-
- DUMPREG(MXR_GRAPHIC1_CFG);
- DUMPREG(MXR_GRAPHIC1_BASE);
- DUMPREG(MXR_GRAPHIC1_SPAN);
- DUMPREG(MXR_GRAPHIC1_WH);
- DUMPREG(MXR_GRAPHIC1_SXY);
- DUMPREG(MXR_GRAPHIC1_DXY);
-#undef DUMPREG
-}
-
-static void mxr_reg_vp_dump(struct mxr_device *mdev)
-{
-#define DUMPREG(reg_id) \
-do { \
- mxr_dbg(mdev, #reg_id " = %08x\n", \
- (u32) readl(mdev->res.vp_regs + reg_id)); \
-} while (0)
-
-
- DUMPREG(VP_ENABLE);
- DUMPREG(VP_SRESET);
- DUMPREG(VP_SHADOW_UPDATE);
- DUMPREG(VP_FIELD_ID);
- DUMPREG(VP_MODE);
- DUMPREG(VP_IMG_SIZE_Y);
- DUMPREG(VP_IMG_SIZE_C);
- DUMPREG(VP_PER_RATE_CTRL);
- DUMPREG(VP_TOP_Y_PTR);
- DUMPREG(VP_BOT_Y_PTR);
- DUMPREG(VP_TOP_C_PTR);
- DUMPREG(VP_BOT_C_PTR);
- DUMPREG(VP_ENDIAN_MODE);
- DUMPREG(VP_SRC_H_POSITION);
- DUMPREG(VP_SRC_V_POSITION);
- DUMPREG(VP_SRC_WIDTH);
- DUMPREG(VP_SRC_HEIGHT);
- DUMPREG(VP_DST_H_POSITION);
- DUMPREG(VP_DST_V_POSITION);
- DUMPREG(VP_DST_WIDTH);
- DUMPREG(VP_DST_HEIGHT);
- DUMPREG(VP_H_RATIO);
- DUMPREG(VP_V_RATIO);
-
-#undef DUMPREG
-}
-
-void mxr_reg_dump(struct mxr_device *mdev)
-{
- mxr_reg_mxr_dump(mdev);
- mxr_reg_vp_dump(mdev);
-}
-
diff --git a/drivers/media/video/s5p-tv/mixer_video.c b/drivers/media/video/s5p-tv/mixer_video.c
deleted file mode 100644
index 6c74b05d1f9..00000000000
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ /dev/null
@@ -1,1112 +0,0 @@
-/*
- * Samsung TV Mixer driver
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *
- * Tomasz Stanislawski, <t.stanislaws@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation. either version 2 of the License,
- * or (at your option) any later version
- */
-
-#include "mixer.h"
-
-#include <media/v4l2-ioctl.h>
-#include <linux/videodev2.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/timer.h>
-#include <media/videobuf2-dma-contig.h>
-
-static int find_reg_callback(struct device *dev, void *p)
-{
- struct v4l2_subdev **sd = p;
-
- *sd = dev_get_drvdata(dev);
- /* non-zero value stops iteration */
- return 1;
-}
-
-static struct v4l2_subdev *find_and_register_subdev(
- struct mxr_device *mdev, char *module_name)
-{
- struct device_driver *drv;
- struct v4l2_subdev *sd = NULL;
- int ret;
-
- /* TODO: add waiting until probe is finished */
- drv = driver_find(module_name, &platform_bus_type);
- if (!drv) {
- mxr_warn(mdev, "module %s is missing\n", module_name);
- return NULL;
- }
- /* driver refcnt is increased, it is safe to iterate over devices */
- ret = driver_for_each_device(drv, NULL, &sd, find_reg_callback);
- /* ret == 0 means that find_reg_callback was never executed */
- if (sd == NULL) {
- mxr_warn(mdev, "module %s provides no subdev!\n", module_name);
- goto done;
- }
- /* v4l2_device_register_subdev detects if sd is NULL */
- ret = v4l2_device_register_subdev(&mdev->v4l2_dev, sd);
- if (ret) {
- mxr_warn(mdev, "failed to register subdev %s\n", sd->name);
- sd = NULL;
- }
-
-done:
- return sd;
-}
-
-int __devinit mxr_acquire_video(struct mxr_device *mdev,
- struct mxr_output_conf *output_conf, int output_count)
-{
- struct device *dev = mdev->dev;
- struct v4l2_device *v4l2_dev = &mdev->v4l2_dev;
- int i;
- int ret = 0;
- struct v4l2_subdev *sd;
-
- strlcpy(v4l2_dev->name, dev_name(mdev->dev), sizeof(v4l2_dev->name));
- /* prepare context for V4L2 device */
- ret = v4l2_device_register(dev, v4l2_dev);
- if (ret) {
- mxr_err(mdev, "could not register v4l2 device.\n");
- goto fail;
- }
-
- mdev->alloc_ctx = vb2_dma_contig_init_ctx(mdev->dev);
- if (IS_ERR_OR_NULL(mdev->alloc_ctx)) {
- mxr_err(mdev, "could not acquire vb2 allocator\n");
- goto fail_v4l2_dev;
- }
-
- /* registering outputs */
- mdev->output_cnt = 0;
- for (i = 0; i < output_count; ++i) {
- struct mxr_output_conf *conf = &output_conf[i];
- struct mxr_output *out;
-
- sd = find_and_register_subdev(mdev, conf->module_name);
- /* trying to register next output */
- if (sd == NULL)
- continue;
- out = kzalloc(sizeof *out, GFP_KERNEL);
- if (out == NULL) {
- mxr_err(mdev, "no memory for '%s'\n",
- conf->output_name);
- ret = -ENOMEM;
- /* registered subdevs are removed in fail_v4l2_dev */
- goto fail_output;
- }
- strlcpy(out->name, conf->output_name, sizeof(out->name));
- out->sd = sd;
- out->cookie = conf->cookie;
- mdev->output[mdev->output_cnt++] = out;
- mxr_info(mdev, "added output '%s' from module '%s'\n",
- conf->output_name, conf->module_name);
- /* checking if maximal number of outputs is reached */
- if (mdev->output_cnt >= MXR_MAX_OUTPUTS)
- break;
- }
-
- if (mdev->output_cnt == 0) {
- mxr_err(mdev, "failed to register any output\n");
- ret = -ENODEV;
- /* skipping fail_output because there is nothing to free */
- goto fail_vb2_allocator;
- }
-
- return 0;
-
-fail_output:
- /* kfree is NULL-safe */
- for (i = 0; i < mdev->output_cnt; ++i)
- kfree(mdev->output[i]);
- memset(mdev->output, 0, sizeof mdev->output);
-
-fail_vb2_allocator:
- /* freeing allocator context */
- vb2_dma_contig_cleanup_ctx(mdev->alloc_ctx);
-
-fail_v4l2_dev:
- /* NOTE: automatically unregister all subdevs */
- v4l2_device_unregister(v4l2_dev);
-
-fail:
- return ret;
-}
-
-void mxr_release_video(struct mxr_device *mdev)
-{
- int i;
-
- /* kfree is NULL-safe */
- for (i = 0; i < mdev->output_cnt; ++i)
- kfree(mdev->output[i]);
-
- vb2_dma_contig_cleanup_ctx(mdev->alloc_ctx);
- v4l2_device_unregister(&mdev->v4l2_dev);
-}
-
-static int mxr_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct mxr_layer *layer = video_drvdata(file);
-
- mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
-
- strlcpy(cap->driver, MXR_DRIVER_NAME, sizeof cap->driver);
- strlcpy(cap->card, layer->vfd.name, sizeof cap->card);
- sprintf(cap->bus_info, "%d", layer->idx);
- cap->version = KERNEL_VERSION(0, 1, 0);
- cap->capabilities = V4L2_CAP_STREAMING |
- V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
-
- return 0;
-}
-
-static void mxr_geometry_dump(struct mxr_device *mdev, struct mxr_geometry *geo)
-{
- mxr_dbg(mdev, "src.full_size = (%u, %u)\n",
- geo->src.full_width, geo->src.full_height);
- mxr_dbg(mdev, "src.size = (%u, %u)\n",
- geo->src.width, geo->src.height);
- mxr_dbg(mdev, "src.offset = (%u, %u)\n",
- geo->src.x_offset, geo->src.y_offset);
- mxr_dbg(mdev, "dst.full_size = (%u, %u)\n",
- geo->dst.full_width, geo->dst.full_height);
- mxr_dbg(mdev, "dst.size = (%u, %u)\n",
- geo->dst.width, geo->dst.height);
- mxr_dbg(mdev, "dst.offset = (%u, %u)\n",
- geo->dst.x_offset, geo->dst.y_offset);
- mxr_dbg(mdev, "ratio = (%u, %u)\n",
- geo->x_ratio, geo->y_ratio);
-}
-
-static void mxr_layer_default_geo(struct mxr_layer *layer)
-{
- struct mxr_device *mdev = layer->mdev;
- struct v4l2_mbus_framefmt mbus_fmt;
-
- memset(&layer->geo, 0, sizeof layer->geo);
-
- mxr_get_mbus_fmt(mdev, &mbus_fmt);
-
- layer->geo.dst.full_width = mbus_fmt.width;
- layer->geo.dst.full_height = mbus_fmt.height;
- layer->geo.dst.width = layer->geo.dst.full_width;
- layer->geo.dst.height = layer->geo.dst.full_height;
- layer->geo.dst.field = mbus_fmt.field;
-
- layer->geo.src.full_width = mbus_fmt.width;
- layer->geo.src.full_height = mbus_fmt.height;
- layer->geo.src.width = layer->geo.src.full_width;
- layer->geo.src.height = layer->geo.src.full_height;
-
- mxr_geometry_dump(mdev, &layer->geo);
- layer->ops.fix_geometry(layer, MXR_GEOMETRY_SINK, 0);
- mxr_geometry_dump(mdev, &layer->geo);
-}
-
-static void mxr_layer_update_output(struct mxr_layer *layer)
-{
- struct mxr_device *mdev = layer->mdev;
- struct v4l2_mbus_framefmt mbus_fmt;
-
- mxr_get_mbus_fmt(mdev, &mbus_fmt);
- /* checking if update is needed */
- if (layer->geo.dst.full_width == mbus_fmt.width &&
- layer->geo.dst.full_height == mbus_fmt.width)
- return;
-
- layer->geo.dst.full_width = mbus_fmt.width;
- layer->geo.dst.full_height = mbus_fmt.height;
- layer->geo.dst.field = mbus_fmt.field;
- layer->ops.fix_geometry(layer, MXR_GEOMETRY_SINK, 0);
-
- mxr_geometry_dump(mdev, &layer->geo);
-}
-
-static const struct mxr_format *find_format_by_fourcc(
- struct mxr_layer *layer, unsigned long fourcc);
-static const struct mxr_format *find_format_by_index(
- struct mxr_layer *layer, unsigned long index);
-
-static int mxr_enum_fmt(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct mxr_layer *layer = video_drvdata(file);
- struct mxr_device *mdev = layer->mdev;
- const struct mxr_format *fmt;
-
- mxr_dbg(mdev, "%s\n", __func__);
- fmt = find_format_by_index(layer, f->index);
- if (fmt == NULL)
- return -EINVAL;
-
- strlcpy(f->description, fmt->name, sizeof(f->description));
- f->pixelformat = fmt->fourcc;
-
- return 0;
-}
-
-static unsigned int divup(unsigned int divident, unsigned int divisor)
-{
- return (divident + divisor - 1) / divisor;
-}
-
-unsigned long mxr_get_plane_size(const struct mxr_block *blk,
- unsigned int width, unsigned int height)
-{
- unsigned int bl_width = divup(width, blk->width);
- unsigned int bl_height = divup(height, blk->height);
-
- return bl_width * bl_height * blk->size;
-}
-
-static void mxr_mplane_fill(struct v4l2_plane_pix_format *planes,
- const struct mxr_format *fmt, u32 width, u32 height)
-{
- int i;
-
- /* checking if nothing to fill */
- if (!planes)
- return;
-
- memset(planes, 0, sizeof(*planes) * fmt->num_subframes);
- for (i = 0; i < fmt->num_planes; ++i) {
- struct v4l2_plane_pix_format *plane = planes
- + fmt->plane2subframe[i];
- const struct mxr_block *blk = &fmt->plane[i];
- u32 bl_width = divup(width, blk->width);
- u32 bl_height = divup(height, blk->height);
- u32 sizeimage = bl_width * bl_height * blk->size;
- u16 bytesperline = bl_width * blk->size / blk->height;
-
- plane->sizeimage += sizeimage;
- plane->bytesperline = max(plane->bytesperline, bytesperline);
- }
-}
-
-static int mxr_g_fmt(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct mxr_layer *layer = video_drvdata(file);
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
-
- mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
-
- pix->width = layer->geo.src.full_width;
- pix->height = layer->geo.src.full_height;
- pix->field = V4L2_FIELD_NONE;
- pix->pixelformat = layer->fmt->fourcc;
- pix->colorspace = layer->fmt->colorspace;
- mxr_mplane_fill(pix->plane_fmt, layer->fmt, pix->width, pix->height);
-
- return 0;
-}
-
-static int mxr_s_fmt(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct mxr_layer *layer = video_drvdata(file);
- const struct mxr_format *fmt;
- struct v4l2_pix_format_mplane *pix;
- struct mxr_device *mdev = layer->mdev;
- struct mxr_geometry *geo = &layer->geo;
-
- mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
-
- pix = &f->fmt.pix_mp;
- fmt = find_format_by_fourcc(layer, pix->pixelformat);
- if (fmt == NULL) {
- mxr_warn(mdev, "not recognized fourcc: %08x\n",
- pix->pixelformat);
- return -EINVAL;
- }
- layer->fmt = fmt;
- /* set source size to highest accepted value */
- geo->src.full_width = max(geo->dst.full_width, pix->width);
- geo->src.full_height = max(geo->dst.full_height, pix->height);
- layer->ops.fix_geometry(layer, MXR_GEOMETRY_SOURCE, 0);
- mxr_geometry_dump(mdev, &layer->geo);
- /* set cropping to total visible screen */
- geo->src.width = pix->width;
- geo->src.height = pix->height;
- geo->src.x_offset = 0;
- geo->src.y_offset = 0;
- /* assure consistency of geometry */
- layer->ops.fix_geometry(layer, MXR_GEOMETRY_CROP, MXR_NO_OFFSET);
- mxr_geometry_dump(mdev, &layer->geo);
- /* set full size to lowest possible value */
- geo->src.full_width = 0;
- geo->src.full_height = 0;
- layer->ops.fix_geometry(layer, MXR_GEOMETRY_SOURCE, 0);
- mxr_geometry_dump(mdev, &layer->geo);
-
- /* returning results */
- mxr_g_fmt(file, priv, f);
-
- return 0;
-}
-
-static int mxr_g_selection(struct file *file, void *fh,
- struct v4l2_selection *s)
-{
- struct mxr_layer *layer = video_drvdata(file);
- struct mxr_geometry *geo = &layer->geo;
-
- mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
-
- if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return -EINVAL;
-
- switch (s->target) {
- case V4L2_SEL_TGT_CROP:
- s->r.left = geo->src.x_offset;
- s->r.top = geo->src.y_offset;
- s->r.width = geo->src.width;
- s->r.height = geo->src.height;
- break;
- case V4L2_SEL_TGT_CROP_DEFAULT:
- case V4L2_SEL_TGT_CROP_BOUNDS:
- s->r.left = 0;
- s->r.top = 0;
- s->r.width = geo->src.full_width;
- s->r.height = geo->src.full_height;
- break;
- case V4L2_SEL_TGT_COMPOSE:
- case V4L2_SEL_TGT_COMPOSE_PADDED:
- s->r.left = geo->dst.x_offset;
- s->r.top = geo->dst.y_offset;
- s->r.width = geo->dst.width;
- s->r.height = geo->dst.height;
- break;
- case V4L2_SEL_TGT_COMPOSE_DEFAULT:
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- s->r.left = 0;
- s->r.top = 0;
- s->r.width = geo->dst.full_width;
- s->r.height = geo->dst.full_height;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* returns 1 if rectangle 'a' is inside 'b' */
-static int mxr_is_rect_inside(struct v4l2_rect *a, struct v4l2_rect *b)
-{
- if (a->left < b->left)
- return 0;
- if (a->top < b->top)
- return 0;
- if (a->left + a->width > b->left + b->width)
- return 0;
- if (a->top + a->height > b->top + b->height)
- return 0;
- return 1;
-}
-
-static int mxr_s_selection(struct file *file, void *fh,
- struct v4l2_selection *s)
-{
- struct mxr_layer *layer = video_drvdata(file);
- struct mxr_geometry *geo = &layer->geo;
- struct mxr_crop *target = NULL;
- enum mxr_geometry_stage stage;
- struct mxr_geometry tmp;
- struct v4l2_rect res;
-
- memset(&res, 0, sizeof res);
-
- mxr_dbg(layer->mdev, "%s: rect: %dx%d@%d,%d\n", __func__,
- s->r.width, s->r.height, s->r.left, s->r.top);
-
- if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return -EINVAL;
-
- switch (s->target) {
- /* ignore read-only targets */
- case V4L2_SEL_TGT_CROP_DEFAULT:
- case V4L2_SEL_TGT_CROP_BOUNDS:
- res.width = geo->src.full_width;
- res.height = geo->src.full_height;
- break;
-
- /* ignore read-only targets */
- case V4L2_SEL_TGT_COMPOSE_DEFAULT:
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- res.width = geo->dst.full_width;
- res.height = geo->dst.full_height;
- break;
-
- case V4L2_SEL_TGT_CROP:
- target = &geo->src;
- stage = MXR_GEOMETRY_CROP;
- break;
- case V4L2_SEL_TGT_COMPOSE:
- case V4L2_SEL_TGT_COMPOSE_PADDED:
- target = &geo->dst;
- stage = MXR_GEOMETRY_COMPOSE;
- break;
- default:
- return -EINVAL;
- }
- /* apply change and update geometry if needed */
- if (target) {
- /* backup current geometry if setup fails */
- memcpy(&tmp, geo, sizeof tmp);
-
- /* apply requested selection */
- target->x_offset = s->r.left;
- target->y_offset = s->r.top;
- target->width = s->r.width;
- target->height = s->r.height;
-
- layer->ops.fix_geometry(layer, stage, s->flags);
-
- /* retrieve update selection rectangle */
- res.left = target->x_offset;
- res.top = target->y_offset;
- res.width = target->width;
- res.height = target->height;
-
- mxr_geometry_dump(layer->mdev, &layer->geo);
- }
-
- /* checking if the rectangle satisfies constraints */
- if ((s->flags & V4L2_SEL_FLAG_LE) && !mxr_is_rect_inside(&res, &s->r))
- goto fail;
- if ((s->flags & V4L2_SEL_FLAG_GE) && !mxr_is_rect_inside(&s->r, &res))
- goto fail;
-
- /* return result rectangle */
- s->r = res;
-
- return 0;
-fail:
- /* restore old geometry, which is not touched if target is NULL */
- if (target)
- memcpy(geo, &tmp, sizeof tmp);
- return -ERANGE;
-}
-
-static int mxr_enum_dv_presets(struct file *file, void *fh,
- struct v4l2_dv_enum_preset *preset)
-{
- struct mxr_layer *layer = video_drvdata(file);
- struct mxr_device *mdev = layer->mdev;
- int ret;
-
- /* lock protects from changing sd_out */
- mutex_lock(&mdev->mutex);
- ret = v4l2_subdev_call(to_outsd(mdev), video, enum_dv_presets, preset);
- mutex_unlock(&mdev->mutex);
-
- return ret ? -EINVAL : 0;
-}
-
-static int mxr_s_dv_preset(struct file *file, void *fh,
- struct v4l2_dv_preset *preset)
-{
- struct mxr_layer *layer = video_drvdata(file);
- struct mxr_device *mdev = layer->mdev;
- int ret;
-
- /* lock protects from changing sd_out */
- mutex_lock(&mdev->mutex);
-
- /* preset change cannot be done while there is an entity
- * dependant on output configuration
- */
- if (mdev->n_output > 0) {
- mutex_unlock(&mdev->mutex);
- return -EBUSY;
- }
-
- ret = v4l2_subdev_call(to_outsd(mdev), video, s_dv_preset, preset);
-
- mutex_unlock(&mdev->mutex);
-
- mxr_layer_update_output(layer);
-
- /* any failure should return EINVAL according to V4L2 doc */
- return ret ? -EINVAL : 0;
-}
-
-static int mxr_g_dv_preset(struct file *file, void *fh,
- struct v4l2_dv_preset *preset)
-{
- struct mxr_layer *layer = video_drvdata(file);
- struct mxr_device *mdev = layer->mdev;
- int ret;
-
- /* lock protects from changing sd_out */
- mutex_lock(&mdev->mutex);
- ret = v4l2_subdev_call(to_outsd(mdev), video, g_dv_preset, preset);
- mutex_unlock(&mdev->mutex);
-
- return ret ? -EINVAL : 0;
-}
-
-static int mxr_s_std(struct file *file, void *fh, v4l2_std_id *norm)
-{
- struct mxr_layer *layer = video_drvdata(file);
- struct mxr_device *mdev = layer->mdev;
- int ret;
-
- /* lock protects from changing sd_out */
- mutex_lock(&mdev->mutex);
-
- /* standard change cannot be done while there is an entity
- * dependant on output configuration
- */
- if (mdev->n_output > 0) {
- mutex_unlock(&mdev->mutex);
- return -EBUSY;
- }
-
- ret = v4l2_subdev_call(to_outsd(mdev), video, s_std_output, *norm);
-
- mutex_unlock(&mdev->mutex);
-
- mxr_layer_update_output(layer);
-
- return ret ? -EINVAL : 0;
-}
-
-static int mxr_g_std(struct file *file, void *fh, v4l2_std_id *norm)
-{
- struct mxr_layer *layer = video_drvdata(file);
- struct mxr_device *mdev = layer->mdev;
- int ret;
-
- /* lock protects from changing sd_out */
- mutex_lock(&mdev->mutex);
- ret = v4l2_subdev_call(to_outsd(mdev), video, g_std_output, norm);
- mutex_unlock(&mdev->mutex);
-
- return ret ? -EINVAL : 0;
-}
-
-static int mxr_enum_output(struct file *file, void *fh, struct v4l2_output *a)
-{
- struct mxr_layer *layer = video_drvdata(file);
- struct mxr_device *mdev = layer->mdev;
- struct mxr_output *out;
- struct v4l2_subdev *sd;
-
- if (a->index >= mdev->output_cnt)
- return -EINVAL;
- out = mdev->output[a->index];
- BUG_ON(out == NULL);
- sd = out->sd;
- strlcpy(a->name, out->name, sizeof(a->name));
-
- /* try to obtain supported tv norms */
- v4l2_subdev_call(sd, video, g_tvnorms_output, &a->std);
- a->capabilities = 0;
- if (sd->ops->video && sd->ops->video->s_dv_preset)
- a->capabilities |= V4L2_OUT_CAP_PRESETS;
- if (sd->ops->video && sd->ops->video->s_std_output)
- a->capabilities |= V4L2_OUT_CAP_STD;
- a->type = V4L2_OUTPUT_TYPE_ANALOG;
-
- return 0;
-}
-
-static int mxr_s_output(struct file *file, void *fh, unsigned int i)
-{
- struct video_device *vfd = video_devdata(file);
- struct mxr_layer *layer = video_drvdata(file);
- struct mxr_device *mdev = layer->mdev;
-
- if (i >= mdev->output_cnt || mdev->output[i] == NULL)
- return -EINVAL;
-
- mutex_lock(&mdev->mutex);
- if (mdev->n_output > 0) {
- mutex_unlock(&mdev->mutex);
- return -EBUSY;
- }
- mdev->current_output = i;
- vfd->tvnorms = 0;
- v4l2_subdev_call(to_outsd(mdev), video, g_tvnorms_output,
- &vfd->tvnorms);
- mutex_unlock(&mdev->mutex);
-
- /* update layers geometry */
- mxr_layer_update_output(layer);
-
- mxr_dbg(mdev, "tvnorms = %08llx\n", vfd->tvnorms);
-
- return 0;
-}
-
-static int mxr_g_output(struct file *file, void *fh, unsigned int *p)
-{
- struct mxr_layer *layer = video_drvdata(file);
- struct mxr_device *mdev = layer->mdev;
-
- mutex_lock(&mdev->mutex);
- *p = mdev->current_output;
- mutex_unlock(&mdev->mutex);
-
- return 0;
-}
-
-static int mxr_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct mxr_layer *layer = video_drvdata(file);
-
- mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
- return vb2_reqbufs(&layer->vb_queue, p);
-}
-
-static int mxr_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct mxr_layer *layer = video_drvdata(file);
-
- mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
- return vb2_querybuf(&layer->vb_queue, p);
-}
-
-static int mxr_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct mxr_layer *layer = video_drvdata(file);
-
- mxr_dbg(layer->mdev, "%s:%d(%d)\n", __func__, __LINE__, p->index);
- return vb2_qbuf(&layer->vb_queue, p);
-}
-
-static int mxr_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct mxr_layer *layer = video_drvdata(file);
-
- mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
- return vb2_dqbuf(&layer->vb_queue, p, file->f_flags & O_NONBLOCK);
-}
-
-static int mxr_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct mxr_layer *layer = video_drvdata(file);
-
- mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
- return vb2_streamon(&layer->vb_queue, i);
-}
-
-static int mxr_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct mxr_layer *layer = video_drvdata(file);
-
- mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
- return vb2_streamoff(&layer->vb_queue, i);
-}
-
-static const struct v4l2_ioctl_ops mxr_ioctl_ops = {
- .vidioc_querycap = mxr_querycap,
- /* format handling */
- .vidioc_enum_fmt_vid_out = mxr_enum_fmt,
- .vidioc_s_fmt_vid_out_mplane = mxr_s_fmt,
- .vidioc_g_fmt_vid_out_mplane = mxr_g_fmt,
- /* buffer control */
- .vidioc_reqbufs = mxr_reqbufs,
- .vidioc_querybuf = mxr_querybuf,
- .vidioc_qbuf = mxr_qbuf,
- .vidioc_dqbuf = mxr_dqbuf,
- /* Streaming control */
- .vidioc_streamon = mxr_streamon,
- .vidioc_streamoff = mxr_streamoff,
- /* Preset functions */
- .vidioc_enum_dv_presets = mxr_enum_dv_presets,
- .vidioc_s_dv_preset = mxr_s_dv_preset,
- .vidioc_g_dv_preset = mxr_g_dv_preset,
- /* analog TV standard functions */
- .vidioc_s_std = mxr_s_std,
- .vidioc_g_std = mxr_g_std,
- /* Output handling */
- .vidioc_enum_output = mxr_enum_output,
- .vidioc_s_output = mxr_s_output,
- .vidioc_g_output = mxr_g_output,
- /* selection ioctls */
- .vidioc_g_selection = mxr_g_selection,
- .vidioc_s_selection = mxr_s_selection,
-};
-
-static int mxr_video_open(struct file *file)
-{
- struct mxr_layer *layer = video_drvdata(file);
- struct mxr_device *mdev = layer->mdev;
- int ret = 0;
-
- mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
- /* assure device probe is finished */
- wait_for_device_probe();
- /* creating context for file descriptor */
- ret = v4l2_fh_open(file);
- if (ret) {
- mxr_err(mdev, "v4l2_fh_open failed\n");
- return ret;
- }
-
- /* leaving if layer is already initialized */
- if (!v4l2_fh_is_singular_file(file))
- return 0;
-
- /* FIXME: should power be enabled on open? */
- ret = mxr_power_get(mdev);
- if (ret) {
- mxr_err(mdev, "power on failed\n");
- goto fail_fh_open;
- }
-
- ret = vb2_queue_init(&layer->vb_queue);
- if (ret != 0) {
- mxr_err(mdev, "failed to initialize vb2 queue\n");
- goto fail_power;
- }
- /* set default format, first on the list */
- layer->fmt = layer->fmt_array[0];
- /* setup default geometry */
- mxr_layer_default_geo(layer);
-
- return 0;
-
-fail_power:
- mxr_power_put(mdev);
-
-fail_fh_open:
- v4l2_fh_release(file);
-
- return ret;
-}
-
-static unsigned int
-mxr_video_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct mxr_layer *layer = video_drvdata(file);
-
- mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
-
- return vb2_poll(&layer->vb_queue, file, wait);
-}
-
-static int mxr_video_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct mxr_layer *layer = video_drvdata(file);
-
- mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
-
- return vb2_mmap(&layer->vb_queue, vma);
-}
-
-static int mxr_video_release(struct file *file)
-{
- struct mxr_layer *layer = video_drvdata(file);
-
- mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
- if (v4l2_fh_is_singular_file(file)) {
- vb2_queue_release(&layer->vb_queue);
- mxr_power_put(layer->mdev);
- }
- v4l2_fh_release(file);
- return 0;
-}
-
-static const struct v4l2_file_operations mxr_fops = {
- .owner = THIS_MODULE,
- .open = mxr_video_open,
- .poll = mxr_video_poll,
- .mmap = mxr_video_mmap,
- .release = mxr_video_release,
- .unlocked_ioctl = video_ioctl2,
-};
-
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
- unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[],
- void *alloc_ctxs[])
-{
- struct mxr_layer *layer = vb2_get_drv_priv(vq);
- const struct mxr_format *fmt = layer->fmt;
- int i;
- struct mxr_device *mdev = layer->mdev;
- struct v4l2_plane_pix_format planes[3];
-
- mxr_dbg(mdev, "%s\n", __func__);
- /* checking if format was configured */
- if (fmt == NULL)
- return -EINVAL;
- mxr_dbg(mdev, "fmt = %s\n", fmt->name);
- mxr_mplane_fill(planes, fmt, layer->geo.src.full_width,
- layer->geo.src.full_height);
-
- *nplanes = fmt->num_subframes;
- for (i = 0; i < fmt->num_subframes; ++i) {
- alloc_ctxs[i] = layer->mdev->alloc_ctx;
- sizes[i] = planes[i].sizeimage;
- mxr_dbg(mdev, "size[%d] = %08x\n", i, sizes[i]);
- }
-
- if (*nbuffers == 0)
- *nbuffers = 1;
-
- return 0;
-}
-
-static void buf_queue(struct vb2_buffer *vb)
-{
- struct mxr_buffer *buffer = container_of(vb, struct mxr_buffer, vb);
- struct mxr_layer *layer = vb2_get_drv_priv(vb->vb2_queue);
- struct mxr_device *mdev = layer->mdev;
- unsigned long flags;
-
- spin_lock_irqsave(&layer->enq_slock, flags);
- list_add_tail(&buffer->list, &layer->enq_list);
- spin_unlock_irqrestore(&layer->enq_slock, flags);
-
- mxr_dbg(mdev, "queuing buffer\n");
-}
-
-static void wait_lock(struct vb2_queue *vq)
-{
- struct mxr_layer *layer = vb2_get_drv_priv(vq);
-
- mxr_dbg(layer->mdev, "%s\n", __func__);
- mutex_lock(&layer->mutex);
-}
-
-static void wait_unlock(struct vb2_queue *vq)
-{
- struct mxr_layer *layer = vb2_get_drv_priv(vq);
-
- mxr_dbg(layer->mdev, "%s\n", __func__);
- mutex_unlock(&layer->mutex);
-}
-
-static int start_streaming(struct vb2_queue *vq, unsigned int count)
-{
- struct mxr_layer *layer = vb2_get_drv_priv(vq);
- struct mxr_device *mdev = layer->mdev;
- unsigned long flags;
-
- mxr_dbg(mdev, "%s\n", __func__);
-
- if (count == 0) {
- mxr_dbg(mdev, "no output buffers queued\n");
- return -EINVAL;
- }
-
- /* block any changes in output configuration */
- mxr_output_get(mdev);
-
- mxr_layer_update_output(layer);
- layer->ops.format_set(layer);
- /* enabling layer in hardware */
- spin_lock_irqsave(&layer->enq_slock, flags);
- layer->state = MXR_LAYER_STREAMING;
- spin_unlock_irqrestore(&layer->enq_slock, flags);
-
- layer->ops.stream_set(layer, MXR_ENABLE);
- mxr_streamer_get(mdev);
-
- return 0;
-}
-
-static void mxr_watchdog(unsigned long arg)
-{
- struct mxr_layer *layer = (struct mxr_layer *) arg;
- struct mxr_device *mdev = layer->mdev;
- unsigned long flags;
-
- mxr_err(mdev, "watchdog fired for layer %s\n", layer->vfd.name);
-
- spin_lock_irqsave(&layer->enq_slock, flags);
-
- if (layer->update_buf == layer->shadow_buf)
- layer->update_buf = NULL;
- if (layer->update_buf) {
- vb2_buffer_done(&layer->update_buf->vb, VB2_BUF_STATE_ERROR);
- layer->update_buf = NULL;
- }
- if (layer->shadow_buf) {
- vb2_buffer_done(&layer->shadow_buf->vb, VB2_BUF_STATE_ERROR);
- layer->shadow_buf = NULL;
- }
- spin_unlock_irqrestore(&layer->enq_slock, flags);
-}
-
-static int stop_streaming(struct vb2_queue *vq)
-{
- struct mxr_layer *layer = vb2_get_drv_priv(vq);
- struct mxr_device *mdev = layer->mdev;
- unsigned long flags;
- struct timer_list watchdog;
- struct mxr_buffer *buf, *buf_tmp;
-
- mxr_dbg(mdev, "%s\n", __func__);
-
- spin_lock_irqsave(&layer->enq_slock, flags);
-
- /* reset list */
- layer->state = MXR_LAYER_STREAMING_FINISH;
-
- /* set all buffer to be done */
- list_for_each_entry_safe(buf, buf_tmp, &layer->enq_list, list) {
- list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- }
-
- spin_unlock_irqrestore(&layer->enq_slock, flags);
-
- /* give 1 seconds to complete to complete last buffers */
- setup_timer_on_stack(&watchdog, mxr_watchdog,
- (unsigned long)layer);
- mod_timer(&watchdog, jiffies + msecs_to_jiffies(1000));
-
- /* wait until all buffers are goes to done state */
- vb2_wait_for_all_buffers(vq);
-
- /* stop timer if all synchronization is done */
- del_timer_sync(&watchdog);
- destroy_timer_on_stack(&watchdog);
-
- /* stopping hardware */
- spin_lock_irqsave(&layer->enq_slock, flags);
- layer->state = MXR_LAYER_IDLE;
- spin_unlock_irqrestore(&layer->enq_slock, flags);
-
- /* disabling layer in hardware */
- layer->ops.stream_set(layer, MXR_DISABLE);
- /* remove one streamer */
- mxr_streamer_put(mdev);
- /* allow changes in output configuration */
- mxr_output_put(mdev);
- return 0;
-}
-
-static struct vb2_ops mxr_video_qops = {
- .queue_setup = queue_setup,
- .buf_queue = buf_queue,
- .wait_prepare = wait_unlock,
- .wait_finish = wait_lock,
- .start_streaming = start_streaming,
- .stop_streaming = stop_streaming,
-};
-
-/* FIXME: try to put this functions to mxr_base_layer_create */
-int mxr_base_layer_register(struct mxr_layer *layer)
-{
- struct mxr_device *mdev = layer->mdev;
- int ret;
-
- ret = video_register_device(&layer->vfd, VFL_TYPE_GRABBER, -1);
- if (ret)
- mxr_err(mdev, "failed to register video device\n");
- else
- mxr_info(mdev, "registered layer %s as /dev/video%d\n",
- layer->vfd.name, layer->vfd.num);
- return ret;
-}
-
-void mxr_base_layer_unregister(struct mxr_layer *layer)
-{
- video_unregister_device(&layer->vfd);
-}
-
-void mxr_layer_release(struct mxr_layer *layer)
-{
- if (layer->ops.release)
- layer->ops.release(layer);
-}
-
-void mxr_base_layer_release(struct mxr_layer *layer)
-{
- kfree(layer);
-}
-
-static void mxr_vfd_release(struct video_device *vdev)
-{
- printk(KERN_INFO "video device release\n");
-}
-
-struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
- int idx, char *name, struct mxr_layer_ops *ops)
-{
- struct mxr_layer *layer;
-
- layer = kzalloc(sizeof *layer, GFP_KERNEL);
- if (layer == NULL) {
- mxr_err(mdev, "not enough memory for layer.\n");
- goto fail;
- }
-
- layer->mdev = mdev;
- layer->idx = idx;
- layer->ops = *ops;
-
- spin_lock_init(&layer->enq_slock);
- INIT_LIST_HEAD(&layer->enq_list);
- mutex_init(&layer->mutex);
-
- layer->vfd = (struct video_device) {
- .minor = -1,
- .release = mxr_vfd_release,
- .fops = &mxr_fops,
- .ioctl_ops = &mxr_ioctl_ops,
- };
- strlcpy(layer->vfd.name, name, sizeof(layer->vfd.name));
- /* let framework control PRIORITY */
- set_bit(V4L2_FL_USE_FH_PRIO, &layer->vfd.flags);
-
- video_set_drvdata(&layer->vfd, layer);
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &layer->vfd.flags);
- layer->vfd.lock = &layer->mutex;
- layer->vfd.v4l2_dev = &mdev->v4l2_dev;
-
- layer->vb_queue = (struct vb2_queue) {
- .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
- .io_modes = VB2_MMAP | VB2_USERPTR,
- .drv_priv = layer,
- .buf_struct_size = sizeof(struct mxr_buffer),
- .ops = &mxr_video_qops,
- .mem_ops = &vb2_dma_contig_memops,
- };
-
- return layer;
-
-fail:
- return NULL;
-}
-
-static const struct mxr_format *find_format_by_fourcc(
- struct mxr_layer *layer, unsigned long fourcc)
-{
- int i;
-
- for (i = 0; i < layer->fmt_array_size; ++i)
- if (layer->fmt_array[i]->fourcc == fourcc)
- return layer->fmt_array[i];
- return NULL;
-}
-
-static const struct mxr_format *find_format_by_index(
- struct mxr_layer *layer, unsigned long index)
-{
- if (index >= layer->fmt_array_size)
- return NULL;
- return layer->fmt_array[index];
-}
-
diff --git a/drivers/media/video/s5p-tv/mixer_vp_layer.c b/drivers/media/video/s5p-tv/mixer_vp_layer.c
deleted file mode 100644
index 3d13a636877..00000000000
--- a/drivers/media/video/s5p-tv/mixer_vp_layer.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Samsung TV Mixer driver
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *
- * Tomasz Stanislawski, <t.stanislaws@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundiation. either version 2 of the License,
- * or (at your option) any later version
- */
-
-#include "mixer.h"
-
-#include "regs-vp.h"
-
-#include <media/videobuf2-dma-contig.h>
-
-/* FORMAT DEFINITIONS */
-static const struct mxr_format mxr_fmt_nv12 = {
- .name = "NV12",
- .fourcc = V4L2_PIX_FMT_NV12,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .num_planes = 2,
- .plane = {
- { .width = 1, .height = 1, .size = 1 },
- { .width = 2, .height = 2, .size = 2 },
- },
- .num_subframes = 1,
- .cookie = VP_MODE_NV12 | VP_MODE_MEM_LINEAR,
-};
-
-static const struct mxr_format mxr_fmt_nv21 = {
- .name = "NV21",
- .fourcc = V4L2_PIX_FMT_NV21,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .num_planes = 2,
- .plane = {
- { .width = 1, .height = 1, .size = 1 },
- { .width = 2, .height = 2, .size = 2 },
- },
- .num_subframes = 1,
- .cookie = VP_MODE_NV21 | VP_MODE_MEM_LINEAR,
-};
-
-static const struct mxr_format mxr_fmt_nv12m = {
- .name = "NV12 (mplane)",
- .fourcc = V4L2_PIX_FMT_NV12M,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .num_planes = 2,
- .plane = {
- { .width = 1, .height = 1, .size = 1 },
- { .width = 2, .height = 2, .size = 2 },
- },
- .num_subframes = 2,
- .plane2subframe = {0, 1},
- .cookie = VP_MODE_NV12 | VP_MODE_MEM_LINEAR,
-};
-
-static const struct mxr_format mxr_fmt_nv12mt = {
- .name = "NV12 tiled (mplane)",
- .fourcc = V4L2_PIX_FMT_NV12MT,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .num_planes = 2,
- .plane = {
- { .width = 128, .height = 32, .size = 4096 },
- { .width = 128, .height = 32, .size = 2048 },
- },
- .num_subframes = 2,
- .plane2subframe = {0, 1},
- .cookie = VP_MODE_NV12 | VP_MODE_MEM_TILED,
-};
-
-static const struct mxr_format *mxr_video_format[] = {
- &mxr_fmt_nv12,
- &mxr_fmt_nv21,
- &mxr_fmt_nv12m,
- &mxr_fmt_nv12mt,
-};
-
-/* AUXILIARY CALLBACKS */
-
-static void mxr_vp_layer_release(struct mxr_layer *layer)
-{
- mxr_base_layer_unregister(layer);
- mxr_base_layer_release(layer);
-}
-
-static void mxr_vp_buffer_set(struct mxr_layer *layer,
- struct mxr_buffer *buf)
-{
- dma_addr_t luma_addr[2] = {0, 0};
- dma_addr_t chroma_addr[2] = {0, 0};
-
- if (buf == NULL) {
- mxr_reg_vp_buffer(layer->mdev, luma_addr, chroma_addr);
- return;
- }
- luma_addr[0] = vb2_dma_contig_plane_dma_addr(&buf->vb, 0);
- if (layer->fmt->num_subframes == 2) {
- chroma_addr[0] = vb2_dma_contig_plane_dma_addr(&buf->vb, 1);
- } else {
- /* FIXME: mxr_get_plane_size compute integer division,
- * which is slow and should not be performed in interrupt */
- chroma_addr[0] = luma_addr[0] + mxr_get_plane_size(
- &layer->fmt->plane[0], layer->geo.src.full_width,
- layer->geo.src.full_height);
- }
- if (layer->fmt->cookie & VP_MODE_MEM_TILED) {
- luma_addr[1] = luma_addr[0] + 0x40;
- chroma_addr[1] = chroma_addr[0] + 0x40;
- } else {
- luma_addr[1] = luma_addr[0] + layer->geo.src.full_width;
- chroma_addr[1] = chroma_addr[0];
- }
- mxr_reg_vp_buffer(layer->mdev, luma_addr, chroma_addr);
-}
-
-static void mxr_vp_stream_set(struct mxr_layer *layer, int en)
-{
- mxr_reg_vp_layer_stream(layer->mdev, en);
-}
-
-static void mxr_vp_format_set(struct mxr_layer *layer)
-{
- mxr_reg_vp_format(layer->mdev, layer->fmt, &layer->geo);
-}
-
-static inline unsigned int do_center(unsigned int center,
- unsigned int size, unsigned int upper, unsigned int flags)
-{
- unsigned int lower;
-
- if (flags & MXR_NO_OFFSET)
- return 0;
-
- lower = center - min(center, size / 2);
- return min(lower, upper - size);
-}
-
-static void mxr_vp_fix_geometry(struct mxr_layer *layer,
- enum mxr_geometry_stage stage, unsigned long flags)
-{
- struct mxr_geometry *geo = &layer->geo;
- struct mxr_crop *src = &geo->src;
- struct mxr_crop *dst = &geo->dst;
- unsigned long x_center, y_center;
-
- switch (stage) {
-
- case MXR_GEOMETRY_SINK: /* nothing to be fixed here */
- case MXR_GEOMETRY_COMPOSE:
- /* remember center of the area */
- x_center = dst->x_offset + dst->width / 2;
- y_center = dst->y_offset + dst->height / 2;
-
- /* ensure that compose is reachable using 16x scaling */
- dst->width = clamp(dst->width, 8U, 16 * src->full_width);
- dst->height = clamp(dst->height, 1U, 16 * src->full_height);
-
- /* setup offsets */
- dst->x_offset = do_center(x_center, dst->width,
- dst->full_width, flags);
- dst->y_offset = do_center(y_center, dst->height,
- dst->full_height, flags);
- flags = 0; /* remove possible MXR_NO_OFFSET flag */
- /* fall through */
- case MXR_GEOMETRY_CROP:
- /* remember center of the area */
- x_center = src->x_offset + src->width / 2;
- y_center = src->y_offset + src->height / 2;
-
- /* ensure scaling is between 0.25x .. 16x */
- src->width = clamp(src->width, round_up(dst->width / 16, 4),
- dst->width * 4);
- src->height = clamp(src->height, round_up(dst->height / 16, 4),
- dst->height * 4);
-
- /* hardware limits */
- src->width = clamp(src->width, 32U, 2047U);
- src->height = clamp(src->height, 4U, 2047U);
-
- /* setup offsets */
- src->x_offset = do_center(x_center, src->width,
- src->full_width, flags);
- src->y_offset = do_center(y_center, src->height,
- src->full_height, flags);
-
- /* setting scaling ratio */
- geo->x_ratio = (src->width << 16) / dst->width;
- geo->y_ratio = (src->height << 16) / dst->height;
- /* fall through */
-
- case MXR_GEOMETRY_SOURCE:
- src->full_width = clamp(src->full_width,
- ALIGN(src->width + src->x_offset, 8), 8192U);
- src->full_height = clamp(src->full_height,
- src->height + src->y_offset, 8192U);
- };
-}
-
-/* PUBLIC API */
-
-struct mxr_layer *mxr_vp_layer_create(struct mxr_device *mdev, int idx)
-{
- struct mxr_layer *layer;
- int ret;
- struct mxr_layer_ops ops = {
- .release = mxr_vp_layer_release,
- .buffer_set = mxr_vp_buffer_set,
- .stream_set = mxr_vp_stream_set,
- .format_set = mxr_vp_format_set,
- .fix_geometry = mxr_vp_fix_geometry,
- };
- char name[32];
-
- sprintf(name, "video%d", idx);
-
- layer = mxr_base_layer_create(mdev, idx, name, &ops);
- if (layer == NULL) {
- mxr_err(mdev, "failed to initialize layer(%d) base\n", idx);
- goto fail;
- }
-
- layer->fmt_array = mxr_video_format;
- layer->fmt_array_size = ARRAY_SIZE(mxr_video_format);
-
- ret = mxr_base_layer_register(layer);
- if (ret)
- goto fail_layer;
-
- return layer;
-
-fail_layer:
- mxr_base_layer_release(layer);
-
-fail:
- return NULL;
-}
-
diff --git a/drivers/media/video/s5p-tv/regs-hdmi.h b/drivers/media/video/s5p-tv/regs-hdmi.h
deleted file mode 100644
index a889d1f57f2..00000000000
--- a/drivers/media/video/s5p-tv/regs-hdmi.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-hdmi.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * HDMI register header file for Samsung TVOUT driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef SAMSUNG_REGS_HDMI_H
-#define SAMSUNG_REGS_HDMI_H
-
-/*
- * Register part
-*/
-
-#define HDMI_CTRL_BASE(x) ((x) + 0x00000000)
-#define HDMI_CORE_BASE(x) ((x) + 0x00010000)
-#define HDMI_TG_BASE(x) ((x) + 0x00050000)
-
-/* Control registers */
-#define HDMI_INTC_CON HDMI_CTRL_BASE(0x0000)
-#define HDMI_INTC_FLAG HDMI_CTRL_BASE(0x0004)
-#define HDMI_HPD_STATUS HDMI_CTRL_BASE(0x000C)
-#define HDMI_PHY_RSTOUT HDMI_CTRL_BASE(0x0014)
-#define HDMI_PHY_VPLL HDMI_CTRL_BASE(0x0018)
-#define HDMI_PHY_CMU HDMI_CTRL_BASE(0x001C)
-#define HDMI_CORE_RSTOUT HDMI_CTRL_BASE(0x0020)
-
-/* Core registers */
-#define HDMI_CON_0 HDMI_CORE_BASE(0x0000)
-#define HDMI_CON_1 HDMI_CORE_BASE(0x0004)
-#define HDMI_CON_2 HDMI_CORE_BASE(0x0008)
-#define HDMI_SYS_STATUS HDMI_CORE_BASE(0x0010)
-#define HDMI_PHY_STATUS HDMI_CORE_BASE(0x0014)
-#define HDMI_STATUS_EN HDMI_CORE_BASE(0x0020)
-#define HDMI_HPD HDMI_CORE_BASE(0x0030)
-#define HDMI_MODE_SEL HDMI_CORE_BASE(0x0040)
-#define HDMI_BLUE_SCREEN_0 HDMI_CORE_BASE(0x0050)
-#define HDMI_BLUE_SCREEN_1 HDMI_CORE_BASE(0x0054)
-#define HDMI_BLUE_SCREEN_2 HDMI_CORE_BASE(0x0058)
-#define HDMI_H_BLANK_0 HDMI_CORE_BASE(0x00A0)
-#define HDMI_H_BLANK_1 HDMI_CORE_BASE(0x00A4)
-#define HDMI_V_BLANK_0 HDMI_CORE_BASE(0x00B0)
-#define HDMI_V_BLANK_1 HDMI_CORE_BASE(0x00B4)
-#define HDMI_V_BLANK_2 HDMI_CORE_BASE(0x00B8)
-#define HDMI_H_V_LINE_0 HDMI_CORE_BASE(0x00C0)
-#define HDMI_H_V_LINE_1 HDMI_CORE_BASE(0x00C4)
-#define HDMI_H_V_LINE_2 HDMI_CORE_BASE(0x00C8)
-#define HDMI_VSYNC_POL HDMI_CORE_BASE(0x00E4)
-#define HDMI_INT_PRO_MODE HDMI_CORE_BASE(0x00E8)
-#define HDMI_V_BLANK_F_0 HDMI_CORE_BASE(0x0110)
-#define HDMI_V_BLANK_F_1 HDMI_CORE_BASE(0x0114)
-#define HDMI_V_BLANK_F_2 HDMI_CORE_BASE(0x0118)
-#define HDMI_H_SYNC_GEN_0 HDMI_CORE_BASE(0x0120)
-#define HDMI_H_SYNC_GEN_1 HDMI_CORE_BASE(0x0124)
-#define HDMI_H_SYNC_GEN_2 HDMI_CORE_BASE(0x0128)
-#define HDMI_V_SYNC_GEN_1_0 HDMI_CORE_BASE(0x0130)
-#define HDMI_V_SYNC_GEN_1_1 HDMI_CORE_BASE(0x0134)
-#define HDMI_V_SYNC_GEN_1_2 HDMI_CORE_BASE(0x0138)
-#define HDMI_V_SYNC_GEN_2_0 HDMI_CORE_BASE(0x0140)
-#define HDMI_V_SYNC_GEN_2_1 HDMI_CORE_BASE(0x0144)
-#define HDMI_V_SYNC_GEN_2_2 HDMI_CORE_BASE(0x0148)
-#define HDMI_V_SYNC_GEN_3_0 HDMI_CORE_BASE(0x0150)
-#define HDMI_V_SYNC_GEN_3_1 HDMI_CORE_BASE(0x0154)
-#define HDMI_V_SYNC_GEN_3_2 HDMI_CORE_BASE(0x0158)
-#define HDMI_AVI_CON HDMI_CORE_BASE(0x0300)
-#define HDMI_AVI_BYTE(n) HDMI_CORE_BASE(0x0320 + 4 * (n))
-#define HDMI_DC_CONTROL HDMI_CORE_BASE(0x05C0)
-#define HDMI_VIDEO_PATTERN_GEN HDMI_CORE_BASE(0x05C4)
-#define HDMI_HPD_GEN HDMI_CORE_BASE(0x05C8)
-
-/* Timing generator registers */
-#define HDMI_TG_CMD HDMI_TG_BASE(0x0000)
-#define HDMI_TG_H_FSZ_L HDMI_TG_BASE(0x0018)
-#define HDMI_TG_H_FSZ_H HDMI_TG_BASE(0x001C)
-#define HDMI_TG_HACT_ST_L HDMI_TG_BASE(0x0020)
-#define HDMI_TG_HACT_ST_H HDMI_TG_BASE(0x0024)
-#define HDMI_TG_HACT_SZ_L HDMI_TG_BASE(0x0028)
-#define HDMI_TG_HACT_SZ_H HDMI_TG_BASE(0x002C)
-#define HDMI_TG_V_FSZ_L HDMI_TG_BASE(0x0030)
-#define HDMI_TG_V_FSZ_H HDMI_TG_BASE(0x0034)
-#define HDMI_TG_VSYNC_L HDMI_TG_BASE(0x0038)
-#define HDMI_TG_VSYNC_H HDMI_TG_BASE(0x003C)
-#define HDMI_TG_VSYNC2_L HDMI_TG_BASE(0x0040)
-#define HDMI_TG_VSYNC2_H HDMI_TG_BASE(0x0044)
-#define HDMI_TG_VACT_ST_L HDMI_TG_BASE(0x0048)
-#define HDMI_TG_VACT_ST_H HDMI_TG_BASE(0x004C)
-#define HDMI_TG_VACT_SZ_L HDMI_TG_BASE(0x0050)
-#define HDMI_TG_VACT_SZ_H HDMI_TG_BASE(0x0054)
-#define HDMI_TG_FIELD_CHG_L HDMI_TG_BASE(0x0058)
-#define HDMI_TG_FIELD_CHG_H HDMI_TG_BASE(0x005C)
-#define HDMI_TG_VACT_ST2_L HDMI_TG_BASE(0x0060)
-#define HDMI_TG_VACT_ST2_H HDMI_TG_BASE(0x0064)
-#define HDMI_TG_VSYNC_TOP_HDMI_L HDMI_TG_BASE(0x0078)
-#define HDMI_TG_VSYNC_TOP_HDMI_H HDMI_TG_BASE(0x007C)
-#define HDMI_TG_VSYNC_BOT_HDMI_L HDMI_TG_BASE(0x0080)
-#define HDMI_TG_VSYNC_BOT_HDMI_H HDMI_TG_BASE(0x0084)
-#define HDMI_TG_FIELD_TOP_HDMI_L HDMI_TG_BASE(0x0088)
-#define HDMI_TG_FIELD_TOP_HDMI_H HDMI_TG_BASE(0x008C)
-#define HDMI_TG_FIELD_BOT_HDMI_L HDMI_TG_BASE(0x0090)
-#define HDMI_TG_FIELD_BOT_HDMI_H HDMI_TG_BASE(0x0094)
-
-/*
- * Bit definition part
- */
-
-/* HDMI_INTC_CON */
-#define HDMI_INTC_EN_GLOBAL (1 << 6)
-#define HDMI_INTC_EN_HPD_PLUG (1 << 3)
-#define HDMI_INTC_EN_HPD_UNPLUG (1 << 2)
-
-/* HDMI_INTC_FLAG */
-#define HDMI_INTC_FLAG_HPD_PLUG (1 << 3)
-#define HDMI_INTC_FLAG_HPD_UNPLUG (1 << 2)
-
-/* HDMI_PHY_RSTOUT */
-#define HDMI_PHY_SW_RSTOUT (1 << 0)
-
-/* HDMI_CORE_RSTOUT */
-#define HDMI_CORE_SW_RSTOUT (1 << 0)
-
-/* HDMI_CON_0 */
-#define HDMI_BLUE_SCR_EN (1 << 5)
-#define HDMI_EN (1 << 0)
-
-/* HDMI_CON_2 */
-#define HDMI_DVI_PERAMBLE_EN (1 << 5)
-#define HDMI_DVI_BAND_EN (1 << 1)
-
-/* HDMI_PHY_STATUS */
-#define HDMI_PHY_STATUS_READY (1 << 0)
-
-/* HDMI_MODE_SEL */
-#define HDMI_MODE_HDMI_EN (1 << 1)
-#define HDMI_MODE_DVI_EN (1 << 0)
-#define HDMI_MODE_MASK (3 << 0)
-
-/* HDMI_TG_CMD */
-#define HDMI_TG_FIELD_EN (1 << 1)
-#define HDMI_TG_EN (1 << 0)
-
-#endif /* SAMSUNG_REGS_HDMI_H */
diff --git a/drivers/media/video/s5p-tv/regs-mixer.h b/drivers/media/video/s5p-tv/regs-mixer.h
deleted file mode 100644
index 158abb43d0a..00000000000
--- a/drivers/media/video/s5p-tv/regs-mixer.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * Mixer register header file for Samsung Mixer driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-#ifndef SAMSUNG_REGS_MIXER_H
-#define SAMSUNG_REGS_MIXER_H
-
-/*
- * Register part
- */
-#define MXR_STATUS 0x0000
-#define MXR_CFG 0x0004
-#define MXR_INT_EN 0x0008
-#define MXR_INT_STATUS 0x000C
-#define MXR_LAYER_CFG 0x0010
-#define MXR_VIDEO_CFG 0x0014
-#define MXR_GRAPHIC0_CFG 0x0020
-#define MXR_GRAPHIC0_BASE 0x0024
-#define MXR_GRAPHIC0_SPAN 0x0028
-#define MXR_GRAPHIC0_SXY 0x002C
-#define MXR_GRAPHIC0_WH 0x0030
-#define MXR_GRAPHIC0_DXY 0x0034
-#define MXR_GRAPHIC0_BLANK 0x0038
-#define MXR_GRAPHIC1_CFG 0x0040
-#define MXR_GRAPHIC1_BASE 0x0044
-#define MXR_GRAPHIC1_SPAN 0x0048
-#define MXR_GRAPHIC1_SXY 0x004C
-#define MXR_GRAPHIC1_WH 0x0050
-#define MXR_GRAPHIC1_DXY 0x0054
-#define MXR_GRAPHIC1_BLANK 0x0058
-#define MXR_BG_CFG 0x0060
-#define MXR_BG_COLOR0 0x0064
-#define MXR_BG_COLOR1 0x0068
-#define MXR_BG_COLOR2 0x006C
-
-/* for parametrized access to layer registers */
-#define MXR_GRAPHIC_CFG(i) (0x0020 + (i) * 0x20)
-#define MXR_GRAPHIC_BASE(i) (0x0024 + (i) * 0x20)
-#define MXR_GRAPHIC_SPAN(i) (0x0028 + (i) * 0x20)
-#define MXR_GRAPHIC_SXY(i) (0x002C + (i) * 0x20)
-#define MXR_GRAPHIC_WH(i) (0x0030 + (i) * 0x20)
-#define MXR_GRAPHIC_DXY(i) (0x0034 + (i) * 0x20)
-
-/*
- * Bit definition part
- */
-
-/* generates mask for range of bits */
-#define MXR_MASK(high_bit, low_bit) \
- (((2 << ((high_bit) - (low_bit))) - 1) << (low_bit))
-
-#define MXR_MASK_VAL(val, high_bit, low_bit) \
- (((val) << (low_bit)) & MXR_MASK(high_bit, low_bit))
-
-/* bits for MXR_STATUS */
-#define MXR_STATUS_16_BURST (1 << 7)
-#define MXR_STATUS_BURST_MASK (1 << 7)
-#define MXR_STATUS_SYNC_ENABLE (1 << 2)
-#define MXR_STATUS_REG_RUN (1 << 0)
-
-/* bits for MXR_CFG */
-#define MXR_CFG_OUT_YUV444 (0 << 8)
-#define MXR_CFG_OUT_RGB888 (1 << 8)
-#define MXR_CFG_OUT_MASK (1 << 8)
-#define MXR_CFG_DST_SDO (0 << 7)
-#define MXR_CFG_DST_HDMI (1 << 7)
-#define MXR_CFG_DST_MASK (1 << 7)
-#define MXR_CFG_SCAN_HD_720 (0 << 6)
-#define MXR_CFG_SCAN_HD_1080 (1 << 6)
-#define MXR_CFG_GRP1_ENABLE (1 << 5)
-#define MXR_CFG_GRP0_ENABLE (1 << 4)
-#define MXR_CFG_VP_ENABLE (1 << 3)
-#define MXR_CFG_SCAN_INTERLACE (0 << 2)
-#define MXR_CFG_SCAN_PROGRASSIVE (1 << 2)
-#define MXR_CFG_SCAN_NTSC (0 << 1)
-#define MXR_CFG_SCAN_PAL (1 << 1)
-#define MXR_CFG_SCAN_SD (0 << 0)
-#define MXR_CFG_SCAN_HD (1 << 0)
-#define MXR_CFG_SCAN_MASK 0x47
-
-/* bits for MXR_GRAPHICn_CFG */
-#define MXR_GRP_CFG_COLOR_KEY_DISABLE (1 << 21)
-#define MXR_GRP_CFG_BLEND_PRE_MUL (1 << 20)
-#define MXR_GRP_CFG_FORMAT_VAL(x) MXR_MASK_VAL(x, 11, 8)
-#define MXR_GRP_CFG_FORMAT_MASK MXR_GRP_CFG_FORMAT_VAL(~0)
-#define MXR_GRP_CFG_ALPHA_VAL(x) MXR_MASK_VAL(x, 7, 0)
-
-/* bits for MXR_GRAPHICn_WH */
-#define MXR_GRP_WH_H_SCALE(x) MXR_MASK_VAL(x, 28, 28)
-#define MXR_GRP_WH_V_SCALE(x) MXR_MASK_VAL(x, 12, 12)
-#define MXR_GRP_WH_WIDTH(x) MXR_MASK_VAL(x, 26, 16)
-#define MXR_GRP_WH_HEIGHT(x) MXR_MASK_VAL(x, 10, 0)
-
-/* bits for MXR_GRAPHICn_SXY */
-#define MXR_GRP_SXY_SX(x) MXR_MASK_VAL(x, 26, 16)
-#define MXR_GRP_SXY_SY(x) MXR_MASK_VAL(x, 10, 0)
-
-/* bits for MXR_GRAPHICn_DXY */
-#define MXR_GRP_DXY_DX(x) MXR_MASK_VAL(x, 26, 16)
-#define MXR_GRP_DXY_DY(x) MXR_MASK_VAL(x, 10, 0)
-
-/* bits for MXR_INT_EN */
-#define MXR_INT_EN_VSYNC (1 << 11)
-#define MXR_INT_EN_ALL (0x0f << 8)
-
-/* bit for MXR_INT_STATUS */
-#define MXR_INT_CLEAR_VSYNC (1 << 11)
-#define MXR_INT_STATUS_VSYNC (1 << 0)
-
-/* bit for MXR_LAYER_CFG */
-#define MXR_LAYER_CFG_GRP1_VAL(x) MXR_MASK_VAL(x, 11, 8)
-#define MXR_LAYER_CFG_GRP0_VAL(x) MXR_MASK_VAL(x, 7, 4)
-#define MXR_LAYER_CFG_VP_VAL(x) MXR_MASK_VAL(x, 3, 0)
-
-#endif /* SAMSUNG_REGS_MIXER_H */
-
diff --git a/drivers/media/video/s5p-tv/regs-sdo.h b/drivers/media/video/s5p-tv/regs-sdo.h
deleted file mode 100644
index 7f7c2b8ac14..00000000000
--- a/drivers/media/video/s5p-tv/regs-sdo.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* drivers/media/video/s5p-tv/regs-sdo.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * SDO register description file
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef SAMSUNG_REGS_SDO_H
-#define SAMSUNG_REGS_SDO_H
-
-/*
- * Register part
- */
-
-#define SDO_CLKCON 0x0000
-#define SDO_CONFIG 0x0008
-#define SDO_VBI 0x0014
-#define SDO_DAC 0x003C
-#define SDO_CCCON 0x0180
-#define SDO_IRQ 0x0280
-#define SDO_IRQMASK 0x0284
-#define SDO_VERSION 0x03D8
-
-/*
- * Bit definition part
- */
-
-/* SDO Clock Control Register (SDO_CLKCON) */
-#define SDO_TVOUT_SW_RESET (1 << 4)
-#define SDO_TVOUT_CLOCK_READY (1 << 1)
-#define SDO_TVOUT_CLOCK_ON (1 << 0)
-
-/* SDO Video Standard Configuration Register (SDO_CONFIG) */
-#define SDO_PROGRESSIVE (1 << 4)
-#define SDO_NTSC_M 0
-#define SDO_PAL_M 1
-#define SDO_PAL_BGHID 2
-#define SDO_PAL_N 3
-#define SDO_PAL_NC 4
-#define SDO_NTSC_443 8
-#define SDO_PAL_60 9
-#define SDO_STANDARD_MASK 0xf
-
-/* SDO VBI Configuration Register (SDO_VBI) */
-#define SDO_CVBS_WSS_INS (1 << 14)
-#define SDO_CVBS_CLOSED_CAPTION_MASK (3 << 12)
-
-/* SDO DAC Configuration Register (SDO_DAC) */
-#define SDO_POWER_ON_DAC (1 << 0)
-
-/* SDO Color Compensation On/Off Control (SDO_CCCON) */
-#define SDO_COMPENSATION_BHS_ADJ_OFF (1 << 4)
-#define SDO_COMPENSATION_CVBS_COMP_OFF (1 << 0)
-
-/* SDO Interrupt Request Register (SDO_IRQ) */
-#define SDO_VSYNC_IRQ_PEND (1 << 0)
-
-#endif /* SAMSUNG_REGS_SDO_H */
diff --git a/drivers/media/video/s5p-tv/regs-vp.h b/drivers/media/video/s5p-tv/regs-vp.h
deleted file mode 100644
index 6c63984e11e..00000000000
--- a/drivers/media/video/s5p-tv/regs-vp.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * Video processor register header file for Samsung Mixer driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef SAMSUNG_REGS_VP_H
-#define SAMSUNG_REGS_VP_H
-
-/*
- * Register part
- */
-
-#define VP_ENABLE 0x0000
-#define VP_SRESET 0x0004
-#define VP_SHADOW_UPDATE 0x0008
-#define VP_FIELD_ID 0x000C
-#define VP_MODE 0x0010
-#define VP_IMG_SIZE_Y 0x0014
-#define VP_IMG_SIZE_C 0x0018
-#define VP_PER_RATE_CTRL 0x001C
-#define VP_TOP_Y_PTR 0x0028
-#define VP_BOT_Y_PTR 0x002C
-#define VP_TOP_C_PTR 0x0030
-#define VP_BOT_C_PTR 0x0034
-#define VP_ENDIAN_MODE 0x03CC
-#define VP_SRC_H_POSITION 0x0044
-#define VP_SRC_V_POSITION 0x0048
-#define VP_SRC_WIDTH 0x004C
-#define VP_SRC_HEIGHT 0x0050
-#define VP_DST_H_POSITION 0x0054
-#define VP_DST_V_POSITION 0x0058
-#define VP_DST_WIDTH 0x005C
-#define VP_DST_HEIGHT 0x0060
-#define VP_H_RATIO 0x0064
-#define VP_V_RATIO 0x0068
-#define VP_POLY8_Y0_LL 0x006C
-#define VP_POLY4_Y0_LL 0x00EC
-#define VP_POLY4_C0_LL 0x012C
-
-/*
- * Bit definition part
- */
-
-/* generates mask for range of bits */
-
-#define VP_MASK(high_bit, low_bit) \
- (((2 << ((high_bit) - (low_bit))) - 1) << (low_bit))
-
-#define VP_MASK_VAL(val, high_bit, low_bit) \
- (((val) << (low_bit)) & VP_MASK(high_bit, low_bit))
-
- /* VP_ENABLE */
-#define VP_ENABLE_ON (1 << 0)
-
-/* VP_SRESET */
-#define VP_SRESET_PROCESSING (1 << 0)
-
-/* VP_SHADOW_UPDATE */
-#define VP_SHADOW_UPDATE_ENABLE (1 << 0)
-
-/* VP_MODE */
-#define VP_MODE_NV12 (0 << 6)
-#define VP_MODE_NV21 (1 << 6)
-#define VP_MODE_LINE_SKIP (1 << 5)
-#define VP_MODE_MEM_LINEAR (0 << 4)
-#define VP_MODE_MEM_TILED (1 << 4)
-#define VP_MODE_FMT_MASK (5 << 4)
-#define VP_MODE_FIELD_ID_AUTO_TOGGLING (1 << 2)
-#define VP_MODE_2D_IPC (1 << 1)
-
-/* VP_IMG_SIZE_Y */
-/* VP_IMG_SIZE_C */
-#define VP_IMG_HSIZE(x) VP_MASK_VAL(x, 29, 16)
-#define VP_IMG_VSIZE(x) VP_MASK_VAL(x, 13, 0)
-
-/* VP_SRC_H_POSITION */
-#define VP_SRC_H_POSITION_VAL(x) VP_MASK_VAL(x, 14, 4)
-
-/* VP_ENDIAN_MODE */
-#define VP_ENDIAN_MODE_LITTLE (1 << 0)
-
-#endif /* SAMSUNG_REGS_VP_H */
diff --git a/drivers/media/video/s5p-tv/sdo_drv.c b/drivers/media/video/s5p-tv/sdo_drv.c
deleted file mode 100644
index f6bca2c20e8..00000000000
--- a/drivers/media/video/s5p-tv/sdo_drv.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * Samsung Standard Definition Output (SDO) driver
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *
- * Tomasz Stanislawski, <t.stanislaws@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundiation. either version 2 of the License,
- * or (at your option) any later version
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-
-#include <media/v4l2-subdev.h>
-
-#include "regs-sdo.h"
-
-MODULE_AUTHOR("Tomasz Stanislawski, <t.stanislaws@samsung.com>");
-MODULE_DESCRIPTION("Samsung Standard Definition Output (SDO)");
-MODULE_LICENSE("GPL");
-
-#define SDO_DEFAULT_STD V4L2_STD_PAL
-
-struct sdo_format {
- v4l2_std_id id;
- /* all modes are 720 pixels wide */
- unsigned int height;
- unsigned int cookie;
-};
-
-struct sdo_device {
- /** pointer to device parent */
- struct device *dev;
- /** base address of SDO registers */
- void __iomem *regs;
- /** SDO interrupt */
- unsigned int irq;
- /** DAC source clock */
- struct clk *sclk_dac;
- /** DAC clock */
- struct clk *dac;
- /** DAC physical interface */
- struct clk *dacphy;
- /** clock for control of VPLL */
- struct clk *fout_vpll;
- /** regulator for SDO IP power */
- struct regulator *vdac;
- /** regulator for SDO plug detection */
- struct regulator *vdet;
- /** subdev used as device interface */
- struct v4l2_subdev sd;
- /** current format */
- const struct sdo_format *fmt;
-};
-
-static inline struct sdo_device *sd_to_sdev(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct sdo_device, sd);
-}
-
-static inline
-void sdo_write_mask(struct sdo_device *sdev, u32 reg_id, u32 value, u32 mask)
-{
- u32 old = readl(sdev->regs + reg_id);
- value = (value & mask) | (old & ~mask);
- writel(value, sdev->regs + reg_id);
-}
-
-static inline
-void sdo_write(struct sdo_device *sdev, u32 reg_id, u32 value)
-{
- writel(value, sdev->regs + reg_id);
-}
-
-static inline
-u32 sdo_read(struct sdo_device *sdev, u32 reg_id)
-{
- return readl(sdev->regs + reg_id);
-}
-
-static irqreturn_t sdo_irq_handler(int irq, void *dev_data)
-{
- struct sdo_device *sdev = dev_data;
-
- /* clear interrupt */
- sdo_write_mask(sdev, SDO_IRQ, ~0, SDO_VSYNC_IRQ_PEND);
- return IRQ_HANDLED;
-}
-
-static void sdo_reg_debug(struct sdo_device *sdev)
-{
-#define DBGREG(reg_id) \
- dev_info(sdev->dev, #reg_id " = %08x\n", \
- sdo_read(sdev, reg_id))
-
- DBGREG(SDO_CLKCON);
- DBGREG(SDO_CONFIG);
- DBGREG(SDO_VBI);
- DBGREG(SDO_DAC);
- DBGREG(SDO_IRQ);
- DBGREG(SDO_IRQMASK);
- DBGREG(SDO_VERSION);
-}
-
-static const struct sdo_format sdo_format[] = {
- { V4L2_STD_PAL_N, .height = 576, .cookie = SDO_PAL_N },
- { V4L2_STD_PAL_Nc, .height = 576, .cookie = SDO_PAL_NC },
- { V4L2_STD_PAL_M, .height = 480, .cookie = SDO_PAL_M },
- { V4L2_STD_PAL_60, .height = 480, .cookie = SDO_PAL_60 },
- { V4L2_STD_NTSC_443, .height = 480, .cookie = SDO_NTSC_443 },
- { V4L2_STD_PAL, .height = 576, .cookie = SDO_PAL_BGHID },
- { V4L2_STD_NTSC_M, .height = 480, .cookie = SDO_NTSC_M },
-};
-
-static const struct sdo_format *sdo_find_format(v4l2_std_id id)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(sdo_format); ++i)
- if (sdo_format[i].id & id)
- return &sdo_format[i];
- return NULL;
-}
-
-static int sdo_g_tvnorms_output(struct v4l2_subdev *sd, v4l2_std_id *std)
-{
- *std = V4L2_STD_NTSC_M | V4L2_STD_PAL_M | V4L2_STD_PAL |
- V4L2_STD_PAL_N | V4L2_STD_PAL_Nc |
- V4L2_STD_NTSC_443 | V4L2_STD_PAL_60;
- return 0;
-}
-
-static int sdo_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct sdo_device *sdev = sd_to_sdev(sd);
- const struct sdo_format *fmt;
- fmt = sdo_find_format(std);
- if (fmt == NULL)
- return -EINVAL;
- sdev->fmt = fmt;
- return 0;
-}
-
-static int sdo_g_std_output(struct v4l2_subdev *sd, v4l2_std_id *std)
-{
- *std = sd_to_sdev(sd)->fmt->id;
- return 0;
-}
-
-static int sdo_g_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *fmt)
-{
- struct sdo_device *sdev = sd_to_sdev(sd);
-
- if (!sdev->fmt)
- return -ENXIO;
- /* all modes are 720 pixels wide */
- fmt->width = 720;
- fmt->height = sdev->fmt->height;
- fmt->code = V4L2_MBUS_FMT_FIXED;
- fmt->field = V4L2_FIELD_INTERLACED;
- fmt->colorspace = V4L2_COLORSPACE_JPEG;
- return 0;
-}
-
-static int sdo_s_power(struct v4l2_subdev *sd, int on)
-{
- struct sdo_device *sdev = sd_to_sdev(sd);
- struct device *dev = sdev->dev;
- int ret;
-
- dev_info(dev, "sdo_s_power(%d)\n", on);
-
- if (on)
- ret = pm_runtime_get_sync(dev);
- else
- ret = pm_runtime_put_sync(dev);
-
- /* only values < 0 indicate errors */
- return IS_ERR_VALUE(ret) ? ret : 0;
-}
-
-static int sdo_streamon(struct sdo_device *sdev)
-{
- /* set proper clock for Timing Generator */
- clk_set_rate(sdev->fout_vpll, 54000000);
- dev_info(sdev->dev, "fout_vpll.rate = %lu\n",
- clk_get_rate(sdev->fout_vpll));
- /* enable clock in SDO */
- sdo_write_mask(sdev, SDO_CLKCON, ~0, SDO_TVOUT_CLOCK_ON);
- clk_enable(sdev->dacphy);
- /* enable DAC */
- sdo_write_mask(sdev, SDO_DAC, ~0, SDO_POWER_ON_DAC);
- sdo_reg_debug(sdev);
- return 0;
-}
-
-static int sdo_streamoff(struct sdo_device *sdev)
-{
- int tries;
-
- sdo_write_mask(sdev, SDO_DAC, 0, SDO_POWER_ON_DAC);
- clk_disable(sdev->dacphy);
- sdo_write_mask(sdev, SDO_CLKCON, 0, SDO_TVOUT_CLOCK_ON);
- for (tries = 100; tries; --tries) {
- if (sdo_read(sdev, SDO_CLKCON) & SDO_TVOUT_CLOCK_READY)
- break;
- mdelay(1);
- }
- if (tries == 0)
- dev_err(sdev->dev, "failed to stop streaming\n");
- return tries ? 0 : -EIO;
-}
-
-static int sdo_s_stream(struct v4l2_subdev *sd, int on)
-{
- struct sdo_device *sdev = sd_to_sdev(sd);
- return on ? sdo_streamon(sdev) : sdo_streamoff(sdev);
-}
-
-static const struct v4l2_subdev_core_ops sdo_sd_core_ops = {
- .s_power = sdo_s_power,
-};
-
-static const struct v4l2_subdev_video_ops sdo_sd_video_ops = {
- .s_std_output = sdo_s_std_output,
- .g_std_output = sdo_g_std_output,
- .g_tvnorms_output = sdo_g_tvnorms_output,
- .g_mbus_fmt = sdo_g_mbus_fmt,
- .s_stream = sdo_s_stream,
-};
-
-static const struct v4l2_subdev_ops sdo_sd_ops = {
- .core = &sdo_sd_core_ops,
- .video = &sdo_sd_video_ops,
-};
-
-static int sdo_runtime_suspend(struct device *dev)
-{
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
- struct sdo_device *sdev = sd_to_sdev(sd);
-
- dev_info(dev, "suspend\n");
- regulator_disable(sdev->vdet);
- regulator_disable(sdev->vdac);
- clk_disable(sdev->sclk_dac);
- return 0;
-}
-
-static int sdo_runtime_resume(struct device *dev)
-{
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
- struct sdo_device *sdev = sd_to_sdev(sd);
-
- dev_info(dev, "resume\n");
- clk_enable(sdev->sclk_dac);
- regulator_enable(sdev->vdac);
- regulator_enable(sdev->vdet);
-
- /* software reset */
- sdo_write_mask(sdev, SDO_CLKCON, ~0, SDO_TVOUT_SW_RESET);
- mdelay(10);
- sdo_write_mask(sdev, SDO_CLKCON, 0, SDO_TVOUT_SW_RESET);
-
- /* setting TV mode */
- sdo_write_mask(sdev, SDO_CONFIG, sdev->fmt->cookie, SDO_STANDARD_MASK);
- /* XXX: forcing interlaced mode using undocumented bit */
- sdo_write_mask(sdev, SDO_CONFIG, 0, SDO_PROGRESSIVE);
- /* turn all VBI off */
- sdo_write_mask(sdev, SDO_VBI, 0, SDO_CVBS_WSS_INS |
- SDO_CVBS_CLOSED_CAPTION_MASK);
- /* turn all post processing off */
- sdo_write_mask(sdev, SDO_CCCON, ~0, SDO_COMPENSATION_BHS_ADJ_OFF |
- SDO_COMPENSATION_CVBS_COMP_OFF);
- sdo_reg_debug(sdev);
- return 0;
-}
-
-static const struct dev_pm_ops sdo_pm_ops = {
- .runtime_suspend = sdo_runtime_suspend,
- .runtime_resume = sdo_runtime_resume,
-};
-
-static int __devinit sdo_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct sdo_device *sdev;
- struct resource *res;
- int ret = 0;
- struct clk *sclk_vpll;
-
- dev_info(dev, "probe start\n");
- sdev = devm_kzalloc(&pdev->dev, sizeof *sdev, GFP_KERNEL);
- if (!sdev) {
- dev_err(dev, "not enough memory.\n");
- ret = -ENOMEM;
- goto fail;
- }
- sdev->dev = dev;
-
- /* mapping registers */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(dev, "get memory resource failed.\n");
- ret = -ENXIO;
- goto fail;
- }
-
- sdev->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
- if (sdev->regs == NULL) {
- dev_err(dev, "register mapping failed.\n");
- ret = -ENXIO;
- goto fail;
- }
-
- /* acquiring interrupt */
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res == NULL) {
- dev_err(dev, "get interrupt resource failed.\n");
- ret = -ENXIO;
- goto fail;
- }
- ret = devm_request_irq(&pdev->dev, res->start, sdo_irq_handler, 0,
- "s5p-sdo", sdev);
- if (ret) {
- dev_err(dev, "request interrupt failed.\n");
- goto fail;
- }
- sdev->irq = res->start;
-
- /* acquire clocks */
- sdev->sclk_dac = clk_get(dev, "sclk_dac");
- if (IS_ERR_OR_NULL(sdev->sclk_dac)) {
- dev_err(dev, "failed to get clock 'sclk_dac'\n");
- ret = -ENXIO;
- goto fail;
- }
- sdev->dac = clk_get(dev, "dac");
- if (IS_ERR_OR_NULL(sdev->dac)) {
- dev_err(dev, "failed to get clock 'dac'\n");
- ret = -ENXIO;
- goto fail_sclk_dac;
- }
- sdev->dacphy = clk_get(dev, "dacphy");
- if (IS_ERR_OR_NULL(sdev->dacphy)) {
- dev_err(dev, "failed to get clock 'dacphy'\n");
- ret = -ENXIO;
- goto fail_dac;
- }
- sclk_vpll = clk_get(dev, "sclk_vpll");
- if (IS_ERR_OR_NULL(sclk_vpll)) {
- dev_err(dev, "failed to get clock 'sclk_vpll'\n");
- ret = -ENXIO;
- goto fail_dacphy;
- }
- clk_set_parent(sdev->sclk_dac, sclk_vpll);
- clk_put(sclk_vpll);
- sdev->fout_vpll = clk_get(dev, "fout_vpll");
- if (IS_ERR_OR_NULL(sdev->fout_vpll)) {
- dev_err(dev, "failed to get clock 'fout_vpll'\n");
- goto fail_dacphy;
- }
- dev_info(dev, "fout_vpll.rate = %lu\n", clk_get_rate(sclk_vpll));
-
- /* acquire regulator */
- sdev->vdac = regulator_get(dev, "vdd33a_dac");
- if (IS_ERR_OR_NULL(sdev->vdac)) {
- dev_err(dev, "failed to get regulator 'vdac'\n");
- goto fail_fout_vpll;
- }
- sdev->vdet = regulator_get(dev, "vdet");
- if (IS_ERR_OR_NULL(sdev->vdet)) {
- dev_err(dev, "failed to get regulator 'vdet'\n");
- goto fail_vdac;
- }
-
- /* enable gate for dac clock, because mixer uses it */
- clk_enable(sdev->dac);
-
- /* configure power management */
- pm_runtime_enable(dev);
-
- /* configuration of interface subdevice */
- v4l2_subdev_init(&sdev->sd, &sdo_sd_ops);
- sdev->sd.owner = THIS_MODULE;
- strlcpy(sdev->sd.name, "s5p-sdo", sizeof sdev->sd.name);
-
- /* set default format */
- sdev->fmt = sdo_find_format(SDO_DEFAULT_STD);
- BUG_ON(sdev->fmt == NULL);
-
- /* keeping subdev in device's private for use by other drivers */
- dev_set_drvdata(dev, &sdev->sd);
-
- dev_info(dev, "probe succeeded\n");
- return 0;
-
-fail_vdac:
- regulator_put(sdev->vdac);
-fail_fout_vpll:
- clk_put(sdev->fout_vpll);
-fail_dacphy:
- clk_put(sdev->dacphy);
-fail_dac:
- clk_put(sdev->dac);
-fail_sclk_dac:
- clk_put(sdev->sclk_dac);
-fail:
- dev_info(dev, "probe failed\n");
- return ret;
-}
-
-static int __devexit sdo_remove(struct platform_device *pdev)
-{
- struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev);
- struct sdo_device *sdev = sd_to_sdev(sd);
-
- pm_runtime_disable(&pdev->dev);
- clk_disable(sdev->dac);
- regulator_put(sdev->vdet);
- regulator_put(sdev->vdac);
- clk_put(sdev->fout_vpll);
- clk_put(sdev->dacphy);
- clk_put(sdev->dac);
- clk_put(sdev->sclk_dac);
-
- dev_info(&pdev->dev, "remove successful\n");
- return 0;
-}
-
-static struct platform_driver sdo_driver __refdata = {
- .probe = sdo_probe,
- .remove = __devexit_p(sdo_remove),
- .driver = {
- .name = "s5p-sdo",
- .owner = THIS_MODULE,
- .pm = &sdo_pm_ops,
- }
-};
-
-module_platform_driver(sdo_driver);
diff --git a/drivers/media/video/s5p-tv/sii9234_drv.c b/drivers/media/video/s5p-tv/sii9234_drv.c
deleted file mode 100644
index 6d348f90237..00000000000
--- a/drivers/media/video/s5p-tv/sii9234_drv.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Samsung MHL interface driver
- *
- * Copyright (C) 2011 Samsung Electronics Co.Ltd
- * Author: Tomasz Stanislawski <t.stanislaws@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/freezer.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kthread.h>
-#include <linux/module.h>
-#include <linux/pm_runtime.h>
-#include <linux/regulator/machine.h>
-#include <linux/slab.h>
-
-#include <mach/gpio.h>
-#include <plat/gpio-cfg.h>
-
-#include <media/sii9234.h>
-#include <media/v4l2-subdev.h>
-
-MODULE_AUTHOR("Tomasz Stanislawski <t.stanislaws@samsung.com>");
-MODULE_DESCRIPTION("Samsung MHL interface driver");
-MODULE_LICENSE("GPL");
-
-struct sii9234_context {
- struct i2c_client *client;
- struct regulator *power;
- int gpio_n_reset;
- struct v4l2_subdev sd;
-};
-
-static inline struct sii9234_context *sd_to_context(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct sii9234_context, sd);
-}
-
-static inline int sii9234_readb(struct i2c_client *client, int addr)
-{
- return i2c_smbus_read_byte_data(client, addr);
-}
-
-static inline int sii9234_writeb(struct i2c_client *client, int addr, int value)
-{
- return i2c_smbus_write_byte_data(client, addr, value);
-}
-
-static inline int sii9234_writeb_mask(struct i2c_client *client, int addr,
- int value, int mask)
-{
- int ret;
-
- ret = i2c_smbus_read_byte_data(client, addr);
- if (ret < 0)
- return ret;
- ret = (ret & ~mask) | (value & mask);
- return i2c_smbus_write_byte_data(client, addr, ret);
-}
-
-static inline int sii9234_readb_idx(struct i2c_client *client, int addr)
-{
- int ret;
- ret = i2c_smbus_write_byte_data(client, 0xbc, addr >> 8);
- if (ret < 0)
- return ret;
- ret = i2c_smbus_write_byte_data(client, 0xbd, addr & 0xff);
- if (ret < 0)
- return ret;
- return i2c_smbus_read_byte_data(client, 0xbe);
-}
-
-static inline int sii9234_writeb_idx(struct i2c_client *client, int addr,
- int value)
-{
- int ret;
- ret = i2c_smbus_write_byte_data(client, 0xbc, addr >> 8);
- if (ret < 0)
- return ret;
- ret = i2c_smbus_write_byte_data(client, 0xbd, addr & 0xff);
- if (ret < 0)
- return ret;
- ret = i2c_smbus_write_byte_data(client, 0xbe, value);
- return ret;
-}
-
-static inline int sii9234_writeb_idx_mask(struct i2c_client *client, int addr,
- int value, int mask)
-{
- int ret;
-
- ret = sii9234_readb_idx(client, addr);
- if (ret < 0)
- return ret;
- ret = (ret & ~mask) | (value & mask);
- return sii9234_writeb_idx(client, addr, ret);
-}
-
-static int sii9234_reset(struct sii9234_context *ctx)
-{
- struct i2c_client *client = ctx->client;
- struct device *dev = &client->dev;
- int ret, tries;
-
- gpio_direction_output(ctx->gpio_n_reset, 1);
- mdelay(1);
- gpio_direction_output(ctx->gpio_n_reset, 0);
- mdelay(1);
- gpio_direction_output(ctx->gpio_n_reset, 1);
- mdelay(1);
-
- /* going to TTPI mode */
- ret = sii9234_writeb(client, 0xc7, 0);
- if (ret < 0) {
- dev_err(dev, "failed to set TTPI mode\n");
- return ret;
- }
- for (tries = 0; tries < 100 ; ++tries) {
- ret = sii9234_readb(client, 0x1b);
- if (ret > 0)
- break;
- if (ret < 0) {
- dev_err(dev, "failed to reset device\n");
- return -EIO;
- }
- mdelay(1);
- }
- if (tries == 100) {
- dev_err(dev, "maximal number of tries reached\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static int sii9234_verify_version(struct i2c_client *client)
-{
- struct device *dev = &client->dev;
- int family, rev, tpi_rev, dev_id, sub_id, hdcp, id;
-
- family = sii9234_readb(client, 0x1b);
- rev = sii9234_readb(client, 0x1c) & 0x0f;
- tpi_rev = sii9234_readb(client, 0x1d) & 0x7f;
- dev_id = sii9234_readb_idx(client, 0x0103);
- sub_id = sii9234_readb_idx(client, 0x0102);
- hdcp = sii9234_readb(client, 0x30);
-
- if (family < 0 || rev < 0 || tpi_rev < 0 || dev_id < 0 ||
- sub_id < 0 || hdcp < 0) {
- dev_err(dev, "failed to read chip's version\n");
- return -EIO;
- }
-
- id = (dev_id << 8) | sub_id;
-
- dev_info(dev, "chip: SiL%02x family: %02x, rev: %02x\n",
- id, family, rev);
- dev_info(dev, "tpi_rev:%02x, hdcp: %02x\n", tpi_rev, hdcp);
- if (id != 0x9234) {
- dev_err(dev, "not supported chip\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-static u8 data[][3] = {
-/* setup from driver created by doonsoo45.kim */
- { 0x01, 0x05, 0x04 }, /* Enable Auto soft reset on SCDT = 0 */
- { 0x01, 0x08, 0x35 }, /* Power Up TMDS Tx Core */
- { 0x01, 0x0d, 0x1c }, /* HDMI Transcode mode enable */
- { 0x01, 0x2b, 0x01 }, /* Enable HDCP Compliance workaround */
- { 0x01, 0x79, 0x40 }, /* daniel test...MHL_INT */
- { 0x01, 0x80, 0x34 }, /* Enable Rx PLL Clock Value */
- { 0x01, 0x90, 0x27 }, /* Enable CBUS discovery */
- { 0x01, 0x91, 0xe5 }, /* Skip RGND detection */
- { 0x01, 0x92, 0x46 }, /* Force MHD mode */
- { 0x01, 0x93, 0xdc }, /* Disable CBUS pull-up during RGND measurement */
- { 0x01, 0x94, 0x66 }, /* 1.8V CBUS VTH & GND threshold */
- { 0x01, 0x95, 0x31 }, /* RGND block & single discovery attempt */
- { 0x01, 0x96, 0x22 }, /* use 1K and 2K setting */
- { 0x01, 0xa0, 0x10 }, /* SIMG: Term mode */
- { 0x01, 0xa1, 0xfc }, /* Disable internal Mobile HD driver */
- { 0x01, 0xa3, 0xfa }, /* SIMG: Output Swing default EB, 3x Clk Mult */
- { 0x01, 0xa5, 0x80 }, /* SIMG: RGND Hysterisis, 3x mode for Beast */
- { 0x01, 0xa6, 0x0c }, /* SIMG: Swing Offset */
- { 0x02, 0x3d, 0x3f }, /* Power up CVCC 1.2V core */
- { 0x03, 0x00, 0x00 }, /* SIMG: correcting HW default */
- { 0x03, 0x11, 0x01 }, /* Enable TxPLL Clock */
- { 0x03, 0x12, 0x15 }, /* Enable Tx Clock Path & Equalizer */
- { 0x03, 0x13, 0x60 }, /* SIMG: Set termination value */
- { 0x03, 0x14, 0xf0 }, /* SIMG: Change CKDT level */
- { 0x03, 0x17, 0x07 }, /* SIMG: PLL Calrefsel */
- { 0x03, 0x1a, 0x20 }, /* VCO Cal */
- { 0x03, 0x22, 0xe0 }, /* SIMG: Auto EQ */
- { 0x03, 0x23, 0xc0 }, /* SIMG: Auto EQ */
- { 0x03, 0x24, 0xa0 }, /* SIMG: Auto EQ */
- { 0x03, 0x25, 0x80 }, /* SIMG: Auto EQ */
- { 0x03, 0x26, 0x60 }, /* SIMG: Auto EQ */
- { 0x03, 0x27, 0x40 }, /* SIMG: Auto EQ */
- { 0x03, 0x28, 0x20 }, /* SIMG: Auto EQ */
- { 0x03, 0x29, 0x00 }, /* SIMG: Auto EQ */
- { 0x03, 0x31, 0x0b }, /* SIMG: Rx PLL BW value from I2C BW ~ 4MHz */
- { 0x03, 0x45, 0x06 }, /* SIMG: DPLL Mode */
- { 0x03, 0x4b, 0x06 }, /* SIMG: Correcting HW default */
- { 0x03, 0x4c, 0xa0 }, /* Manual zone control */
- { 0x03, 0x4d, 0x02 }, /* SIMG: PLL Mode Value (order is important) */
-};
-
-static int sii9234_set_internal(struct sii9234_context *ctx)
-{
- struct i2c_client *client = ctx->client;
- int i, ret;
-
- for (i = 0; i < ARRAY_SIZE(data); ++i) {
- int addr = (data[i][0] << 8) | data[i][1];
- ret = sii9234_writeb_idx(client, addr, data[i][2]);
- if (ret < 0)
- return ret;
- }
- return 0;
-}
-
-static int sii9234_runtime_suspend(struct device *dev)
-{
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
- struct sii9234_context *ctx = sd_to_context(sd);
- struct i2c_client *client = ctx->client;
-
- dev_info(dev, "suspend start\n");
-
- sii9234_writeb_mask(client, 0x1e, 3, 3);
- regulator_disable(ctx->power);
-
- return 0;
-}
-
-static int sii9234_runtime_resume(struct device *dev)
-{
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
- struct sii9234_context *ctx = sd_to_context(sd);
- struct i2c_client *client = ctx->client;
- int ret;
-
- dev_info(dev, "resume start\n");
- regulator_enable(ctx->power);
-
- ret = sii9234_reset(ctx);
- if (ret)
- goto fail;
-
- /* enable tpi */
- ret = sii9234_writeb_mask(client, 0x1e, 1, 0);
- if (ret < 0)
- goto fail;
- ret = sii9234_set_internal(ctx);
- if (ret < 0)
- goto fail;
-
- return 0;
-
-fail:
- dev_err(dev, "failed to resume\n");
- regulator_disable(ctx->power);
-
- return ret;
-}
-
-static const struct dev_pm_ops sii9234_pm_ops = {
- .runtime_suspend = sii9234_runtime_suspend,
- .runtime_resume = sii9234_runtime_resume,
-};
-
-static int sii9234_s_power(struct v4l2_subdev *sd, int on)
-{
- struct sii9234_context *ctx = sd_to_context(sd);
- int ret;
-
- if (on)
- ret = pm_runtime_get_sync(&ctx->client->dev);
- else
- ret = pm_runtime_put(&ctx->client->dev);
- /* only values < 0 indicate errors */
- return IS_ERR_VALUE(ret) ? ret : 0;
-}
-
-static int sii9234_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct sii9234_context *ctx = sd_to_context(sd);
-
- /* (dis/en)able TDMS output */
- sii9234_writeb_mask(ctx->client, 0x1a, enable ? 0 : ~0 , 1 << 4);
- return 0;
-}
-
-static const struct v4l2_subdev_core_ops sii9234_core_ops = {
- .s_power = sii9234_s_power,
-};
-
-static const struct v4l2_subdev_video_ops sii9234_video_ops = {
- .s_stream = sii9234_s_stream,
-};
-
-static const struct v4l2_subdev_ops sii9234_ops = {
- .core = &sii9234_core_ops,
- .video = &sii9234_video_ops,
-};
-
-static int __devinit sii9234_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct device *dev = &client->dev;
- struct sii9234_platform_data *pdata = dev->platform_data;
- struct sii9234_context *ctx;
- int ret;
-
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx) {
- dev_err(dev, "out of memory\n");
- ret = -ENOMEM;
- goto fail;
- }
- ctx->client = client;
-
- ctx->power = regulator_get(dev, "hdmi-en");
- if (IS_ERR(ctx->power)) {
- dev_err(dev, "failed to acquire regulator hdmi-en\n");
- ret = PTR_ERR(ctx->power);
- goto fail_ctx;
- }
-
- ctx->gpio_n_reset = pdata->gpio_n_reset;
- ret = gpio_request(ctx->gpio_n_reset, "MHL_RST");
- if (ret) {
- dev_err(dev, "failed to acquire MHL_RST gpio\n");
- goto fail_power;
- }
-
- v4l2_i2c_subdev_init(&ctx->sd, client, &sii9234_ops);
-
- pm_runtime_enable(dev);
-
- /* enable device */
- ret = pm_runtime_get_sync(dev);
- if (ret)
- goto fail_pm;
-
- /* verify chip version */
- ret = sii9234_verify_version(client);
- if (ret)
- goto fail_pm_get;
-
- /* stop processing */
- pm_runtime_put(dev);
-
- dev_info(dev, "probe successful\n");
-
- return 0;
-
-fail_pm_get:
- pm_runtime_put_sync(dev);
-
-fail_pm:
- pm_runtime_disable(dev);
- gpio_free(ctx->gpio_n_reset);
-
-fail_power:
- regulator_put(ctx->power);
-
-fail_ctx:
- kfree(ctx);
-
-fail:
- dev_err(dev, "probe failed\n");
-
- return ret;
-}
-
-static int __devexit sii9234_remove(struct i2c_client *client)
-{
- struct device *dev = &client->dev;
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct sii9234_context *ctx = sd_to_context(sd);
-
- pm_runtime_disable(dev);
- gpio_free(ctx->gpio_n_reset);
- regulator_put(ctx->power);
- kfree(ctx);
-
- dev_info(dev, "remove successful\n");
-
- return 0;
-}
-
-
-static const struct i2c_device_id sii9234_id[] = {
- { "SII9234", 0 },
- { },
-};
-
-MODULE_DEVICE_TABLE(i2c, sii9234_id);
-static struct i2c_driver sii9234_driver = {
- .driver = {
- .name = "sii9234",
- .owner = THIS_MODULE,
- .pm = &sii9234_pm_ops,
- },
- .probe = sii9234_probe,
- .remove = __devexit_p(sii9234_remove),
- .id_table = sii9234_id,
-};
-
-module_i2c_driver(sii9234_driver);
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
deleted file mode 100644
index 0caac50d7cf..00000000000
--- a/drivers/media/video/saa6588.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- Driver for SAA6588 RDS decoder
-
- (c) 2005 Hans J. Koch
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/wait.h>
-#include <asm/uaccess.h>
-
-#include <media/saa6588.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-
-
-/* insmod options */
-static unsigned int debug;
-static unsigned int xtal;
-static unsigned int mmbs;
-static unsigned int plvl;
-static unsigned int bufblocks = 100;
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debug messages");
-module_param(xtal, int, 0);
-MODULE_PARM_DESC(xtal, "select oscillator frequency (0..3), default 0");
-module_param(mmbs, int, 0);
-MODULE_PARM_DESC(mmbs, "enable MMBS mode: 0=off (default), 1=on");
-module_param(plvl, int, 0);
-MODULE_PARM_DESC(plvl, "select pause level (0..3), default 0");
-module_param(bufblocks, int, 0);
-MODULE_PARM_DESC(bufblocks, "number of buffered blocks, default 100");
-
-MODULE_DESCRIPTION("v4l2 driver module for SAA6588 RDS decoder");
-MODULE_AUTHOR("Hans J. Koch <koch@hjk-az.de>");
-
-MODULE_LICENSE("GPL");
-
-/* ---------------------------------------------------------------------- */
-
-#define UNSET (-1U)
-#define PREFIX "saa6588: "
-#define dprintk if (debug) printk
-
-struct saa6588 {
- struct v4l2_subdev sd;
- struct delayed_work work;
- spinlock_t lock;
- unsigned char *buffer;
- unsigned int buf_size;
- unsigned int rd_index;
- unsigned int wr_index;
- unsigned int block_count;
- unsigned char last_blocknum;
- wait_queue_head_t read_queue;
- int data_available_for_read;
- u8 sync;
-};
-
-static inline struct saa6588 *to_saa6588(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct saa6588, sd);
-}
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * SAA6588 defines
- */
-
-/* Initialization and mode control byte (0w) */
-
-/* bit 0+1 (DAC0/DAC1) */
-#define cModeStandard 0x00
-#define cModeFastPI 0x01
-#define cModeReducedRequest 0x02
-#define cModeInvalid 0x03
-
-/* bit 2 (RBDS) */
-#define cProcessingModeRDS 0x00
-#define cProcessingModeRBDS 0x04
-
-/* bit 3+4 (SYM0/SYM1) */
-#define cErrCorrectionNone 0x00
-#define cErrCorrection2Bits 0x08
-#define cErrCorrection5Bits 0x10
-#define cErrCorrectionNoneRBDS 0x18
-
-/* bit 5 (NWSY) */
-#define cSyncNormal 0x00
-#define cSyncRestart 0x20
-
-/* bit 6 (TSQD) */
-#define cSigQualityDetectOFF 0x00
-#define cSigQualityDetectON 0x40
-
-/* bit 7 (SQCM) */
-#define cSigQualityTriggered 0x00
-#define cSigQualityContinous 0x80
-
-/* Pause level and flywheel control byte (1w) */
-
-/* bits 0..5 (FEB0..FEB5) */
-#define cFlywheelMaxBlocksMask 0x3F
-#define cFlywheelDefault 0x20
-
-/* bits 6+7 (PL0/PL1) */
-#define cPauseLevel_11mV 0x00
-#define cPauseLevel_17mV 0x40
-#define cPauseLevel_27mV 0x80
-#define cPauseLevel_43mV 0xC0
-
-/* Pause time/oscillator frequency/quality detector control byte (1w) */
-
-/* bits 0..4 (SQS0..SQS4) */
-#define cQualityDetectSensMask 0x1F
-#define cQualityDetectDefault 0x0F
-
-/* bit 5 (SOSC) */
-#define cSelectOscFreqOFF 0x00
-#define cSelectOscFreqON 0x20
-
-/* bit 6+7 (PTF0/PTF1) */
-#define cOscFreq_4332kHz 0x00
-#define cOscFreq_8664kHz 0x40
-#define cOscFreq_12996kHz 0x80
-#define cOscFreq_17328kHz 0xC0
-
-/* ---------------------------------------------------------------------- */
-
-static int block_to_user_buf(struct saa6588 *s, unsigned char __user *user_buf)
-{
- int i;
-
- if (s->rd_index == s->wr_index) {
- if (debug > 2)
- dprintk(PREFIX "Read: buffer empty.\n");
- return 0;
- }
-
- if (debug > 2) {
- dprintk(PREFIX "Read: ");
- for (i = s->rd_index; i < s->rd_index + 3; i++)
- dprintk("0x%02x ", s->buffer[i]);
- }
-
- if (copy_to_user(user_buf, &s->buffer[s->rd_index], 3))
- return -EFAULT;
-
- s->rd_index += 3;
- if (s->rd_index >= s->buf_size)
- s->rd_index = 0;
- s->block_count--;
-
- if (debug > 2)
- dprintk("%d blocks total.\n", s->block_count);
-
- return 1;
-}
-
-static void read_from_buf(struct saa6588 *s, struct saa6588_command *a)
-{
- unsigned long flags;
-
- unsigned char __user *buf_ptr = a->buffer;
- unsigned int i;
- unsigned int rd_blocks;
-
- a->result = 0;
- if (!a->buffer)
- return;
-
- while (!s->data_available_for_read) {
- int ret = wait_event_interruptible(s->read_queue,
- s->data_available_for_read);
- if (ret == -ERESTARTSYS) {
- a->result = -EINTR;
- return;
- }
- }
-
- spin_lock_irqsave(&s->lock, flags);
- rd_blocks = a->block_count;
- if (rd_blocks > s->block_count)
- rd_blocks = s->block_count;
-
- if (!rd_blocks) {
- spin_unlock_irqrestore(&s->lock, flags);
- return;
- }
-
- for (i = 0; i < rd_blocks; i++) {
- if (block_to_user_buf(s, buf_ptr)) {
- buf_ptr += 3;
- a->result++;
- } else
- break;
- }
- a->result *= 3;
- s->data_available_for_read = (s->block_count > 0);
- spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void block_to_buf(struct saa6588 *s, unsigned char *blockbuf)
-{
- unsigned int i;
-
- if (debug > 3)
- dprintk(PREFIX "New block: ");
-
- for (i = 0; i < 3; ++i) {
- if (debug > 3)
- dprintk("0x%02x ", blockbuf[i]);
- s->buffer[s->wr_index] = blockbuf[i];
- s->wr_index++;
- }
-
- if (s->wr_index >= s->buf_size)
- s->wr_index = 0;
-
- if (s->wr_index == s->rd_index) {
- s->rd_index += 3;
- if (s->rd_index >= s->buf_size)
- s->rd_index = 0;
- } else
- s->block_count++;
-
- if (debug > 3)
- dprintk("%d blocks total.\n", s->block_count);
-}
-
-static void saa6588_i2c_poll(struct saa6588 *s)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&s->sd);
- unsigned long flags;
- unsigned char tmpbuf[6];
- unsigned char blocknum;
- unsigned char tmp;
-
- /* Although we only need 3 bytes, we have to read at least 6.
- SAA6588 returns garbage otherwise. */
- if (6 != i2c_master_recv(client, &tmpbuf[0], 6)) {
- if (debug > 1)
- dprintk(PREFIX "read error!\n");
- return;
- }
-
- s->sync = tmpbuf[0] & 0x10;
- if (!s->sync)
- return;
- blocknum = tmpbuf[0] >> 5;
- if (blocknum == s->last_blocknum) {
- if (debug > 3)
- dprintk("Saw block %d again.\n", blocknum);
- return;
- }
-
- s->last_blocknum = blocknum;
-
- /*
- Byte order according to v4l2 specification:
-
- Byte 0: Least Significant Byte of RDS Block
- Byte 1: Most Significant Byte of RDS Block
- Byte 2 Bit 7: Error bit. Indicates that an uncorrectable error
- occurred during reception of this block.
- Bit 6: Corrected bit. Indicates that an error was
- corrected for this data block.
- Bits 5-3: Same as bits 0-2.
- Bits 2-0: Block number.
-
- SAA6588 byte order is Status-MSB-LSB, so we have to swap the
- first and the last of the 3 bytes block.
- */
-
- tmp = tmpbuf[2];
- tmpbuf[2] = tmpbuf[0];
- tmpbuf[0] = tmp;
-
- /* Map 'Invalid block E' to 'Invalid Block' */
- if (blocknum == 6)
- blocknum = V4L2_RDS_BLOCK_INVALID;
- /* And if are not in mmbs mode, then 'Block E' is also mapped
- to 'Invalid Block'. As far as I can tell MMBS is discontinued,
- and if there is ever a need to support E blocks, then please
- contact the linux-media mailinglist. */
- else if (!mmbs && blocknum == 5)
- blocknum = V4L2_RDS_BLOCK_INVALID;
- tmp = blocknum;
- tmp |= blocknum << 3; /* Received offset == Offset Name (OK ?) */
- if ((tmpbuf[2] & 0x03) == 0x03)
- tmp |= V4L2_RDS_BLOCK_ERROR; /* uncorrectable error */
- else if ((tmpbuf[2] & 0x03) != 0x00)
- tmp |= V4L2_RDS_BLOCK_CORRECTED; /* corrected error */
- tmpbuf[2] = tmp; /* Is this enough ? Should we also check other bits ? */
-
- spin_lock_irqsave(&s->lock, flags);
- block_to_buf(s, tmpbuf);
- spin_unlock_irqrestore(&s->lock, flags);
- s->data_available_for_read = 1;
- wake_up_interruptible(&s->read_queue);
-}
-
-static void saa6588_work(struct work_struct *work)
-{
- struct saa6588 *s = container_of(work, struct saa6588, work.work);
-
- saa6588_i2c_poll(s);
- schedule_delayed_work(&s->work, msecs_to_jiffies(20));
-}
-
-static void saa6588_configure(struct saa6588 *s)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&s->sd);
- unsigned char buf[3];
- int rc;
-
- buf[0] = cSyncRestart;
- if (mmbs)
- buf[0] |= cProcessingModeRBDS;
-
- buf[1] = cFlywheelDefault;
- switch (plvl) {
- case 0:
- buf[1] |= cPauseLevel_11mV;
- break;
- case 1:
- buf[1] |= cPauseLevel_17mV;
- break;
- case 2:
- buf[1] |= cPauseLevel_27mV;
- break;
- case 3:
- buf[1] |= cPauseLevel_43mV;
- break;
- default: /* nothing */
- break;
- }
-
- buf[2] = cQualityDetectDefault | cSelectOscFreqON;
-
- switch (xtal) {
- case 0:
- buf[2] |= cOscFreq_4332kHz;
- break;
- case 1:
- buf[2] |= cOscFreq_8664kHz;
- break;
- case 2:
- buf[2] |= cOscFreq_12996kHz;
- break;
- case 3:
- buf[2] |= cOscFreq_17328kHz;
- break;
- default: /* nothing */
- break;
- }
-
- dprintk(PREFIX "writing: 0w=0x%02x 1w=0x%02x 2w=0x%02x\n",
- buf[0], buf[1], buf[2]);
-
- rc = i2c_master_send(client, buf, 3);
- if (rc != 3)
- printk(PREFIX "i2c i/o error: rc == %d (should be 3)\n", rc);
-}
-
-/* ---------------------------------------------------------------------- */
-
-static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
- struct saa6588 *s = to_saa6588(sd);
- struct saa6588_command *a = arg;
-
- switch (cmd) {
- /* --- open() for /dev/radio --- */
- case SAA6588_CMD_OPEN:
- a->result = 0; /* return error if chip doesn't work ??? */
- break;
- /* --- close() for /dev/radio --- */
- case SAA6588_CMD_CLOSE:
- s->data_available_for_read = 1;
- wake_up_interruptible(&s->read_queue);
- a->result = 0;
- break;
- /* --- read() for /dev/radio --- */
- case SAA6588_CMD_READ:
- read_from_buf(s, a);
- break;
- /* --- poll() for /dev/radio --- */
- case SAA6588_CMD_POLL:
- a->result = 0;
- if (s->data_available_for_read) {
- a->result |= POLLIN | POLLRDNORM;
- }
- poll_wait(a->instance, &s->read_queue, a->event_list);
- break;
-
- default:
- /* nothing */
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static int saa6588_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct saa6588 *s = to_saa6588(sd);
-
- vt->capability |= V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO;
- if (s->sync)
- vt->rxsubchans |= V4L2_TUNER_SUB_RDS;
- return 0;
-}
-
-static int saa6588_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct saa6588 *s = to_saa6588(sd);
-
- saa6588_configure(s);
- return 0;
-}
-
-static int saa6588_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA6588, 0);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops saa6588_core_ops = {
- .g_chip_ident = saa6588_g_chip_ident,
- .ioctl = saa6588_ioctl,
-};
-
-static const struct v4l2_subdev_tuner_ops saa6588_tuner_ops = {
- .g_tuner = saa6588_g_tuner,
- .s_tuner = saa6588_s_tuner,
-};
-
-static const struct v4l2_subdev_ops saa6588_ops = {
- .core = &saa6588_core_ops,
- .tuner = &saa6588_tuner_ops,
-};
-
-/* ---------------------------------------------------------------------- */
-
-static int saa6588_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct saa6588 *s;
- struct v4l2_subdev *sd;
-
- v4l_info(client, "saa6588 found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- s = kzalloc(sizeof(*s), GFP_KERNEL);
- if (s == NULL)
- return -ENOMEM;
-
- s->buf_size = bufblocks * 3;
-
- s->buffer = kmalloc(s->buf_size, GFP_KERNEL);
- if (s->buffer == NULL) {
- kfree(s);
- return -ENOMEM;
- }
- sd = &s->sd;
- v4l2_i2c_subdev_init(sd, client, &saa6588_ops);
- spin_lock_init(&s->lock);
- s->block_count = 0;
- s->wr_index = 0;
- s->rd_index = 0;
- s->last_blocknum = 0xff;
- init_waitqueue_head(&s->read_queue);
- s->data_available_for_read = 0;
-
- saa6588_configure(s);
-
- /* start polling via eventd */
- INIT_DELAYED_WORK(&s->work, saa6588_work);
- schedule_delayed_work(&s->work, 0);
- return 0;
-}
-
-static int saa6588_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct saa6588 *s = to_saa6588(sd);
-
- v4l2_device_unregister_subdev(sd);
-
- cancel_delayed_work_sync(&s->work);
-
- kfree(s->buffer);
- kfree(s);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id saa6588_id[] = {
- { "saa6588", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, saa6588_id);
-
-static struct i2c_driver saa6588_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "saa6588",
- },
- .probe = saa6588_probe,
- .remove = saa6588_remove,
- .id_table = saa6588_id,
-};
-
-module_i2c_driver(saa6588_driver);
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
deleted file mode 100644
index 51cd4c8f052..00000000000
--- a/drivers/media/video/saa7110.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * saa7110 - Philips SAA7110(A) video decoder driver
- *
- * Copyright (C) 1998 Pauline Middelink <middelin@polyware.nl>
- *
- * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- * - some corrections for Pinnacle Systems Inc. DC10plus card.
- *
- * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
- * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-
-MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
-MODULE_AUTHOR("Pauline Middelink");
-MODULE_LICENSE("GPL");
-
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-#define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */
-#define SAA7110_MAX_OUTPUT 1 /* 1 YUV */
-
-#define SAA7110_NR_REG 0x35
-
-struct saa7110 {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- u8 reg[SAA7110_NR_REG];
-
- v4l2_std_id norm;
- int input;
- int enable;
-
- wait_queue_head_t wq;
-};
-
-static inline struct saa7110 *to_saa7110(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct saa7110, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct saa7110, hdl)->sd;
-}
-
-/* ----------------------------------------------------------------------- */
-/* I2C support functions */
-/* ----------------------------------------------------------------------- */
-
-static int saa7110_write(struct v4l2_subdev *sd, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct saa7110 *decoder = to_saa7110(sd);
-
- decoder->reg[reg] = value;
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static int saa7110_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct saa7110 *decoder = to_saa7110(sd);
- int ret = -1;
- u8 reg = *data; /* first register to write to */
-
- /* Sanity check */
- if (reg + (len - 1) > SAA7110_NR_REG)
- return ret;
-
- /* the saa7110 has an autoincrement function, use it if
- * the adapter understands raw I2C */
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- ret = i2c_master_send(client, data, len);
-
- /* Cache the written data */
- memcpy(decoder->reg + reg, data + 1, len - 1);
- } else {
- for (++data, --len; len; len--) {
- ret = saa7110_write(sd, reg++, *data++);
- if (ret < 0)
- break;
- }
- }
-
- return ret;
-}
-
-static inline int saa7110_read(struct v4l2_subdev *sd)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_read_byte(client);
-}
-
-/* ----------------------------------------------------------------------- */
-/* SAA7110 functions */
-/* ----------------------------------------------------------------------- */
-
-#define FRESP_06H_COMPST 0x03 /*0x13*/
-#define FRESP_06H_SVIDEO 0x83 /*0xC0*/
-
-
-static int saa7110_selmux(struct v4l2_subdev *sd, int chan)
-{
- static const unsigned char modes[9][8] = {
- /* mode 0 */
- {FRESP_06H_COMPST, 0xD9, 0x17, 0x40, 0x03,
- 0x44, 0x75, 0x16},
- /* mode 1 */
- {FRESP_06H_COMPST, 0xD8, 0x17, 0x40, 0x03,
- 0x44, 0x75, 0x16},
- /* mode 2 */
- {FRESP_06H_COMPST, 0xBA, 0x07, 0x91, 0x03,
- 0x60, 0xB5, 0x05},
- /* mode 3 */
- {FRESP_06H_COMPST, 0xB8, 0x07, 0x91, 0x03,
- 0x60, 0xB5, 0x05},
- /* mode 4 */
- {FRESP_06H_COMPST, 0x7C, 0x07, 0xD2, 0x83,
- 0x60, 0xB5, 0x03},
- /* mode 5 */
- {FRESP_06H_COMPST, 0x78, 0x07, 0xD2, 0x83,
- 0x60, 0xB5, 0x03},
- /* mode 6 */
- {FRESP_06H_SVIDEO, 0x59, 0x17, 0x42, 0xA3,
- 0x44, 0x75, 0x12},
- /* mode 7 */
- {FRESP_06H_SVIDEO, 0x9A, 0x17, 0xB1, 0x13,
- 0x60, 0xB5, 0x14},
- /* mode 8 */
- {FRESP_06H_SVIDEO, 0x3C, 0x27, 0xC1, 0x23,
- 0x44, 0x75, 0x21}
- };
- struct saa7110 *decoder = to_saa7110(sd);
- const unsigned char *ptr = modes[chan];
-
- saa7110_write(sd, 0x06, ptr[0]); /* Luminance control */
- saa7110_write(sd, 0x20, ptr[1]); /* Analog Control #1 */
- saa7110_write(sd, 0x21, ptr[2]); /* Analog Control #2 */
- saa7110_write(sd, 0x22, ptr[3]); /* Mixer Control #1 */
- saa7110_write(sd, 0x2C, ptr[4]); /* Mixer Control #2 */
- saa7110_write(sd, 0x30, ptr[5]); /* ADCs gain control */
- saa7110_write(sd, 0x31, ptr[6]); /* Mixer Control #3 */
- saa7110_write(sd, 0x21, ptr[7]); /* Analog Control #2 */
- decoder->input = chan;
-
- return 0;
-}
-
-static const unsigned char initseq[1 + SAA7110_NR_REG] = {
- 0, 0x4C, 0x3C, 0x0D, 0xEF, 0xBD, 0xF2, 0x03, 0x00,
- /* 0x08 */ 0xF8, 0xF8, 0x60, 0x60, 0x00, 0x86, 0x18, 0x90,
- /* 0x10 */ 0x00, 0x59, 0x40, 0x46, 0x42, 0x1A, 0xFF, 0xDA,
- /* 0x18 */ 0xF2, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* 0x20 */ 0xD9, 0x16, 0x40, 0x41, 0x80, 0x41, 0x80, 0x4F,
- /* 0x28 */ 0xFE, 0x01, 0xCF, 0x0F, 0x03, 0x01, 0x03, 0x0C,
- /* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02
-};
-
-static v4l2_std_id determine_norm(struct v4l2_subdev *sd)
-{
- DEFINE_WAIT(wait);
- struct saa7110 *decoder = to_saa7110(sd);
- int status;
-
- /* mode changed, start automatic detection */
- saa7110_write_block(sd, initseq, sizeof(initseq));
- saa7110_selmux(sd, decoder->input);
- prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
- schedule_timeout(msecs_to_jiffies(250));
- finish_wait(&decoder->wq, &wait);
- status = saa7110_read(sd);
- if (status & 0x40) {
- v4l2_dbg(1, debug, sd, "status=0x%02x (no signal)\n", status);
- return decoder->norm; /* no change*/
- }
- if ((status & 3) == 0) {
- saa7110_write(sd, 0x06, 0x83);
- if (status & 0x20) {
- v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC/no color)\n", status);
- /*saa7110_write(sd,0x2E,0x81);*/
- return V4L2_STD_NTSC;
- }
- v4l2_dbg(1, debug, sd, "status=0x%02x (PAL/no color)\n", status);
- /*saa7110_write(sd,0x2E,0x9A);*/
- return V4L2_STD_PAL;
- }
- /*saa7110_write(sd,0x06,0x03);*/
- if (status & 0x20) { /* 60Hz */
- v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC)\n", status);
- saa7110_write(sd, 0x0D, 0x86);
- saa7110_write(sd, 0x0F, 0x50);
- saa7110_write(sd, 0x11, 0x2C);
- /*saa7110_write(sd,0x2E,0x81);*/
- return V4L2_STD_NTSC;
- }
-
- /* 50Hz -> PAL/SECAM */
- saa7110_write(sd, 0x0D, 0x86);
- saa7110_write(sd, 0x0F, 0x10);
- saa7110_write(sd, 0x11, 0x59);
- /*saa7110_write(sd,0x2E,0x9A);*/
-
- prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
- schedule_timeout(msecs_to_jiffies(250));
- finish_wait(&decoder->wq, &wait);
-
- status = saa7110_read(sd);
- if ((status & 0x03) == 0x01) {
- v4l2_dbg(1, debug, sd, "status=0x%02x (SECAM)\n", status);
- saa7110_write(sd, 0x0D, 0x87);
- return V4L2_STD_SECAM;
- }
- v4l2_dbg(1, debug, sd, "status=0x%02x (PAL)\n", status);
- return V4L2_STD_PAL;
-}
-
-static int saa7110_g_input_status(struct v4l2_subdev *sd, u32 *pstatus)
-{
- struct saa7110 *decoder = to_saa7110(sd);
- int res = V4L2_IN_ST_NO_SIGNAL;
- int status = saa7110_read(sd);
-
- v4l2_dbg(1, debug, sd, "status=0x%02x norm=%llx\n",
- status, (unsigned long long)decoder->norm);
- if (!(status & 0x40))
- res = 0;
- if (!(status & 0x03))
- res |= V4L2_IN_ST_NO_COLOR;
-
- *pstatus = res;
- return 0;
-}
-
-static int saa7110_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
-{
- *(v4l2_std_id *)std = determine_norm(sd);
- return 0;
-}
-
-static int saa7110_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct saa7110 *decoder = to_saa7110(sd);
-
- if (decoder->norm != std) {
- decoder->norm = std;
- /*saa7110_write(sd, 0x06, 0x03);*/
- if (std & V4L2_STD_NTSC) {
- saa7110_write(sd, 0x0D, 0x86);
- saa7110_write(sd, 0x0F, 0x50);
- saa7110_write(sd, 0x11, 0x2C);
- /*saa7110_write(sd, 0x2E, 0x81);*/
- v4l2_dbg(1, debug, sd, "switched to NTSC\n");
- } else if (std & V4L2_STD_PAL) {
- saa7110_write(sd, 0x0D, 0x86);
- saa7110_write(sd, 0x0F, 0x10);
- saa7110_write(sd, 0x11, 0x59);
- /*saa7110_write(sd, 0x2E, 0x9A);*/
- v4l2_dbg(1, debug, sd, "switched to PAL\n");
- } else if (std & V4L2_STD_SECAM) {
- saa7110_write(sd, 0x0D, 0x87);
- saa7110_write(sd, 0x0F, 0x10);
- saa7110_write(sd, 0x11, 0x59);
- /*saa7110_write(sd, 0x2E, 0x9A);*/
- v4l2_dbg(1, debug, sd, "switched to SECAM\n");
- } else {
- return -EINVAL;
- }
- }
- return 0;
-}
-
-static int saa7110_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct saa7110 *decoder = to_saa7110(sd);
-
- if (input >= SAA7110_MAX_INPUT) {
- v4l2_dbg(1, debug, sd, "input=%d not available\n", input);
- return -EINVAL;
- }
- if (decoder->input != input) {
- saa7110_selmux(sd, input);
- v4l2_dbg(1, debug, sd, "switched to input=%d\n", input);
- }
- return 0;
-}
-
-static int saa7110_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct saa7110 *decoder = to_saa7110(sd);
-
- if (decoder->enable != enable) {
- decoder->enable = enable;
- saa7110_write(sd, 0x0E, enable ? 0x18 : 0x80);
- v4l2_dbg(1, debug, sd, "YUV %s\n", enable ? "on" : "off");
- }
- return 0;
-}
-
-static int saa7110_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- saa7110_write(sd, 0x19, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- saa7110_write(sd, 0x13, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- saa7110_write(sd, 0x12, ctrl->val);
- break;
- case V4L2_CID_HUE:
- saa7110_write(sd, 0x07, ctrl->val);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int saa7110_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7110, 0);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_ctrl_ops saa7110_ctrl_ops = {
- .s_ctrl = saa7110_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops saa7110_core_ops = {
- .g_chip_ident = saa7110_g_chip_ident,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
- .s_std = saa7110_s_std,
-};
-
-static const struct v4l2_subdev_video_ops saa7110_video_ops = {
- .s_routing = saa7110_s_routing,
- .s_stream = saa7110_s_stream,
- .querystd = saa7110_querystd,
- .g_input_status = saa7110_g_input_status,
-};
-
-static const struct v4l2_subdev_ops saa7110_ops = {
- .core = &saa7110_core_ops,
- .video = &saa7110_video_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7110_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct saa7110 *decoder;
- struct v4l2_subdev *sd;
- int rv;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
- return -ENODEV;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
- if (!decoder)
- return -ENOMEM;
- sd = &decoder->sd;
- v4l2_i2c_subdev_init(sd, client, &saa7110_ops);
- decoder->norm = V4L2_STD_PAL;
- decoder->input = 0;
- decoder->enable = 1;
- v4l2_ctrl_handler_init(&decoder->hdl, 2);
- v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 127, 1, 64);
- v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
- V4L2_CID_SATURATION, 0, 127, 1, 64);
- v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
- V4L2_CID_HUE, -128, 127, 1, 0);
- sd->ctrl_handler = &decoder->hdl;
- if (decoder->hdl.error) {
- int err = decoder->hdl.error;
-
- v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(decoder);
- return err;
- }
- v4l2_ctrl_handler_setup(&decoder->hdl);
-
- init_waitqueue_head(&decoder->wq);
-
- rv = saa7110_write_block(sd, initseq, sizeof(initseq));
- if (rv < 0) {
- v4l2_dbg(1, debug, sd, "init status %d\n", rv);
- } else {
- int ver, status;
- saa7110_write(sd, 0x21, 0x10);
- saa7110_write(sd, 0x0e, 0x18);
- saa7110_write(sd, 0x0D, 0x04);
- ver = saa7110_read(sd);
- saa7110_write(sd, 0x0D, 0x06);
- /*mdelay(150);*/
- status = saa7110_read(sd);
- v4l2_dbg(1, debug, sd, "version %x, status=0x%02x\n",
- ver, status);
- saa7110_write(sd, 0x0D, 0x86);
- saa7110_write(sd, 0x0F, 0x10);
- saa7110_write(sd, 0x11, 0x59);
- /*saa7110_write(sd, 0x2E, 0x9A);*/
- }
-
- /*saa7110_selmux(sd,0);*/
- /*determine_norm(sd);*/
- /* setup and implicit mode 0 select has been performed */
-
- return 0;
-}
-
-static int saa7110_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct saa7110 *decoder = to_saa7110(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(decoder);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id saa7110_id[] = {
- { "saa7110", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, saa7110_id);
-
-static struct i2c_driver saa7110_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "saa7110",
- },
- .probe = saa7110_probe,
- .remove = saa7110_remove,
- .id_table = saa7110_id,
-};
-
-module_i2c_driver(saa7110_driver);
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
deleted file mode 100644
index 2107336cd83..00000000000
--- a/drivers/media/video/saa7115.c
+++ /dev/null
@@ -1,1727 +0,0 @@
-/* saa711x - Philips SAA711x video decoder driver
- * This driver can work with saa7111, saa7111a, saa7113, saa7114,
- * saa7115 and saa7118.
- *
- * Based on saa7114 driver by Maxim Yevtyushkin, which is based on
- * the saa7111 driver by Dave Perks.
- *
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
- *
- * Slight changes for video timing and attachment output by
- * Wolfgang Scherr <scherr@net4you.net>
- *
- * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003)
- * by Ronald Bultje <rbultje@ronald.bitfreak.net>
- *
- * Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com>
- * (2/17/2003)
- *
- * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
- *
- * Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
- * SAA7111, SAA7113 and SAA7118 support
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "saa711x_regs.h"
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/saa7115.h>
-#include <asm/div64.h>
-
-#define VRES_60HZ (480+16)
-
-MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");
-MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
- "Hans Verkuil, Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
-
-static bool debug;
-module_param(debug, bool, 0644);
-
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-
-struct saa711x_state {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
-
- struct {
- /* chroma gain control cluster */
- struct v4l2_ctrl *agc;
- struct v4l2_ctrl *gain;
- };
-
- v4l2_std_id std;
- int input;
- int output;
- int enable;
- int radio;
- int width;
- int height;
- u32 ident;
- u32 audclk_freq;
- u32 crystal_freq;
- u8 ucgc;
- u8 cgcdiv;
- u8 apll;
-};
-
-static inline struct saa711x_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct saa711x_state, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct saa711x_state, hdl)->sd;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static inline int saa711x_write(struct v4l2_subdev *sd, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-/* Sanity routine to check if a register is present */
-static int saa711x_has_reg(const int id, const u8 reg)
-{
- if (id == V4L2_IDENT_SAA7111)
- return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
- (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
- if (id == V4L2_IDENT_SAA7111A)
- return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
- reg != 0x14 && reg != 0x18 && reg != 0x19 &&
- reg != 0x1d && reg != 0x1e;
-
- /* common for saa7113/4/5/8 */
- if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
- reg == 0xa3 || reg == 0xa7 || reg == 0xab || reg == 0xaf || (reg >= 0xb5 && reg <= 0xb7) ||
- reg == 0xd3 || reg == 0xd7 || reg == 0xdb || reg == 0xdf || (reg >= 0xe5 && reg <= 0xe7) ||
- reg == 0x82 || (reg >= 0x89 && reg <= 0x8e)))
- return 0;
-
- switch (id) {
- case V4L2_IDENT_SAA7113:
- return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
- reg != 0x5d && reg < 0x63;
- case V4L2_IDENT_SAA7114:
- return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
- (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
- reg != 0x81 && reg < 0xf0;
- case V4L2_IDENT_SAA7115:
- return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
- case V4L2_IDENT_SAA7118:
- return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
- (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
- (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
- }
- return 1;
-}
-
-static int saa711x_writeregs(struct v4l2_subdev *sd, const unsigned char *regs)
-{
- struct saa711x_state *state = to_state(sd);
- unsigned char reg, data;
-
- while (*regs != 0x00) {
- reg = *(regs++);
- data = *(regs++);
-
- /* According with datasheets, reserved regs should be
- filled with 0 - seems better not to touch on they */
- if (saa711x_has_reg(state->ident, reg)) {
- if (saa711x_write(sd, reg, data) < 0)
- return -1;
- } else {
- v4l2_dbg(1, debug, sd, "tried to access reserved reg 0x%02x\n", reg);
- }
- }
- return 0;
-}
-
-static inline int saa711x_read(struct v4l2_subdev *sd, u8 reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-/* ----------------------------------------------------------------------- */
-
-/* SAA7111 initialization table */
-static const unsigned char saa7111_init[] = {
- R_01_INC_DELAY, 0x00, /* reserved */
-
- /*front end */
- R_02_INPUT_CNTL_1, 0xd0, /* FUSE=3, GUDL=2, MODE=0 */
- R_03_INPUT_CNTL_2, 0x23, /* HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0,
- * GAFIX=0, GAI1=256, GAI2=256 */
- R_04_INPUT_CNTL_3, 0x00, /* GAI1=256 */
- R_05_INPUT_CNTL_4, 0x00, /* GAI2=256 */
-
- /* decoder */
- R_06_H_SYNC_START, 0xf3, /* HSB at 13(50Hz) / 17(60Hz)
- * pixels after end of last line */
- R_07_H_SYNC_STOP, 0xe8, /* HSS seems to be needed to
- * work with NTSC, too */
- R_08_SYNC_CNTL, 0xc8, /* AUFD=1, FSEL=1, EXFIL=0,
- * VTRC=1, HPLL=0, VNOI=0 */
- R_09_LUMA_CNTL, 0x01, /* BYPS=0, PREF=0, BPSS=0,
- * VBLB=0, UPTCV=0, APER=1 */
- R_0A_LUMA_BRIGHT_CNTL, 0x80,
- R_0B_LUMA_CONTRAST_CNTL, 0x47, /* 0b - CONT=1.109 */
- R_0C_CHROMA_SAT_CNTL, 0x40,
- R_0D_CHROMA_HUE_CNTL, 0x00,
- R_0E_CHROMA_CNTL_1, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
- * FCTC=0, CHBW=1 */
- R_0F_CHROMA_GAIN_CNTL, 0x00, /* reserved */
- R_10_CHROMA_CNTL_2, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
- R_11_MODE_DELAY_CNTL, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
- * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
- R_12_RT_SIGNAL_CNTL, 0x00, /* 12 - output control 2 */
- R_13_RT_X_PORT_OUT_CNTL, 0x00, /* 13 - output control 3 */
- R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
- R_15_VGATE_START_FID_CHG, 0x00,
- R_16_VGATE_STOP, 0x00,
- R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
-
- 0x00, 0x00
-};
-
-/* SAA7113 init codes */
-static const unsigned char saa7113_init[] = {
- R_01_INC_DELAY, 0x08,
- R_02_INPUT_CNTL_1, 0xc2,
- R_03_INPUT_CNTL_2, 0x30,
- R_04_INPUT_CNTL_3, 0x00,
- R_05_INPUT_CNTL_4, 0x00,
- R_06_H_SYNC_START, 0x89,
- R_07_H_SYNC_STOP, 0x0d,
- R_08_SYNC_CNTL, 0x88,
- R_09_LUMA_CNTL, 0x01,
- R_0A_LUMA_BRIGHT_CNTL, 0x80,
- R_0B_LUMA_CONTRAST_CNTL, 0x47,
- R_0C_CHROMA_SAT_CNTL, 0x40,
- R_0D_CHROMA_HUE_CNTL, 0x00,
- R_0E_CHROMA_CNTL_1, 0x01,
- R_0F_CHROMA_GAIN_CNTL, 0x2a,
- R_10_CHROMA_CNTL_2, 0x08,
- R_11_MODE_DELAY_CNTL, 0x0c,
- R_12_RT_SIGNAL_CNTL, 0x07,
- R_13_RT_X_PORT_OUT_CNTL, 0x00,
- R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
- R_15_VGATE_START_FID_CHG, 0x00,
- R_16_VGATE_STOP, 0x00,
- R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
-
- 0x00, 0x00
-};
-
-/* If a value differs from the Hauppauge driver values, then the comment starts with
- 'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
- Hauppauge driver sets. */
-
-/* SAA7114 and SAA7115 initialization table */
-static const unsigned char saa7115_init_auto_input[] = {
- /* Front-End Part */
- R_01_INC_DELAY, 0x48, /* white peak control disabled */
- R_03_INPUT_CNTL_2, 0x20, /* was 0x30. 0x20: long vertical blanking */
- R_04_INPUT_CNTL_3, 0x90, /* analog gain set to 0 */
- R_05_INPUT_CNTL_4, 0x90, /* analog gain set to 0 */
- /* Decoder Part */
- R_06_H_SYNC_START, 0xeb, /* horiz sync begin = -21 */
- R_07_H_SYNC_STOP, 0xe0, /* horiz sync stop = -17 */
- R_09_LUMA_CNTL, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */
- R_0A_LUMA_BRIGHT_CNTL, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */
- R_0B_LUMA_CONTRAST_CNTL, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */
- R_0C_CHROMA_SAT_CNTL, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */
- R_0D_CHROMA_HUE_CNTL, 0x00,
- R_0F_CHROMA_GAIN_CNTL, 0x00, /* use automatic gain */
- R_10_CHROMA_CNTL_2, 0x06, /* chroma: active adaptive combfilter */
- R_11_MODE_DELAY_CNTL, 0x00,
- R_12_RT_SIGNAL_CNTL, 0x9d, /* RTS0 output control: VGATE */
- R_13_RT_X_PORT_OUT_CNTL, 0x80, /* ITU656 standard mode, RTCO output enable RTCE */
- R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
- R_18_RAW_DATA_GAIN_CNTL, 0x40, /* gain 0x00 = nominal */
- R_19_RAW_DATA_OFF_CNTL, 0x80,
- R_1A_COLOR_KILL_LVL_CNTL, 0x77, /* recommended value */
- R_1B_MISC_TVVCRDET, 0x42, /* recommended value */
- R_1C_ENHAN_COMB_CTRL1, 0xa9, /* recommended value */
- R_1D_ENHAN_COMB_CTRL2, 0x01, /* recommended value */
-
-
- R_80_GLOBAL_CNTL_1, 0x0, /* No tasks enabled at init */
-
- /* Power Device Control */
- R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset device */
- R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* set device programmed, all in operational mode */
- 0x00, 0x00
-};
-
-/* Used to reset saa7113, saa7114 and saa7115 */
-static const unsigned char saa7115_cfg_reset_scaler[] = {
- R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00, /* disable I-port output */
- R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
- R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
- R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* enable I-port output */
- 0x00, 0x00
-};
-
-/* ============== SAA7715 VIDEO templates ============= */
-
-static const unsigned char saa7115_cfg_60hz_video[] = {
- R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
- R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
-
- R_15_VGATE_START_FID_CHG, 0x03,
- R_16_VGATE_STOP, 0x11,
- R_17_MISC_VGATE_CONF_AND_MSB, 0x9c,
-
- R_08_SYNC_CNTL, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
- R_0E_CHROMA_CNTL_1, 0x07, /* video autodetection is on */
-
- R_5A_V_OFF_FOR_SLICER, 0x06, /* standard 60hz value for ITU656 line counting */
-
- /* Task A */
- R_90_A_TASK_HANDLING_CNTL, 0x80,
- R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
- R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
- R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
-
- /* hoffset low (input), 0x0002 is minimum */
- R_94_A_HORIZ_INPUT_WINDOW_START, 0x01,
- R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
-
- /* hsize low (input), 0x02d0 = 720 */
- R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
- R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
-
- R_98_A_VERT_INPUT_WINDOW_START, 0x05,
- R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
-
- R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x0c,
- R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
-
- R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
- R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,
-
- R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x0c,
- R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
-
- /* Task B */
- R_C0_B_TASK_HANDLING_CNTL, 0x00,
- R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
- R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
- R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
-
- /* 0x0002 is minimum */
- R_C4_B_HORIZ_INPUT_WINDOW_START, 0x02,
- R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
-
- /* 0x02d0 = 720 */
- R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
- R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
-
- /* vwindow start 0x12 = 18 */
- R_C8_B_VERT_INPUT_WINDOW_START, 0x12,
- R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
-
- /* vwindow length 0xf8 = 248 */
- R_CA_B_VERT_INPUT_WINDOW_LENGTH, VRES_60HZ>>1,
- R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, VRES_60HZ>>9,
-
- /* hwindow 0x02d0 = 720 */
- R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
- R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
-
- R_F0_LFCO_PER_LINE, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
- R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0 */
- R_F5_PULSGEN_LINE_LENGTH, 0xad,
- R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
-
- 0x00, 0x00
-};
-
-static const unsigned char saa7115_cfg_50hz_video[] = {
- R_80_GLOBAL_CNTL_1, 0x00,
- R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
-
- R_15_VGATE_START_FID_CHG, 0x37, /* VGATE start */
- R_16_VGATE_STOP, 0x16,
- R_17_MISC_VGATE_CONF_AND_MSB, 0x99,
-
- R_08_SYNC_CNTL, 0x28, /* 0x28 = PAL */
- R_0E_CHROMA_CNTL_1, 0x07,
-
- R_5A_V_OFF_FOR_SLICER, 0x03, /* standard 50hz value */
-
- /* Task A */
- R_90_A_TASK_HANDLING_CNTL, 0x81,
- R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
- R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
- R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
-
- /* This is weird: the datasheet says that you should use 2 as the minimum value, */
- /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
- /* hoffset low (input), 0x0002 is minimum */
- R_94_A_HORIZ_INPUT_WINDOW_START, 0x00,
- R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
-
- /* hsize low (input), 0x02d0 = 720 */
- R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
- R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
-
- R_98_A_VERT_INPUT_WINDOW_START, 0x03,
- R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
-
- /* vsize 0x12 = 18 */
- R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x12,
- R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
-
- /* hsize 0x05a0 = 1440 */
- R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
- R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05, /* hsize hi (output) */
- R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x12, /* vsize low (output), 0x12 = 18 */
- R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00, /* vsize hi (output) */
-
- /* Task B */
- R_C0_B_TASK_HANDLING_CNTL, 0x00,
- R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
- R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
- R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
-
- /* This is weird: the datasheet says that you should use 2 as the minimum value, */
- /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
- /* hoffset low (input), 0x0002 is minimum. See comment above. */
- R_C4_B_HORIZ_INPUT_WINDOW_START, 0x00,
- R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
-
- /* hsize 0x02d0 = 720 */
- R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
- R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
-
- /* voffset 0x16 = 22 */
- R_C8_B_VERT_INPUT_WINDOW_START, 0x16,
- R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
-
- /* vsize 0x0120 = 288 */
- R_CA_B_VERT_INPUT_WINDOW_LENGTH, 0x20,
- R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, 0x01,
-
- /* hsize 0x02d0 = 720 */
- R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
- R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
-
- R_F0_LFCO_PER_LINE, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
- R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0, (was 0x05) */
- R_F5_PULSGEN_LINE_LENGTH, 0xb0,
- R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
-
- 0x00, 0x00
-};
-
-/* ============== SAA7715 VIDEO templates (end) ======= */
-
-static const unsigned char saa7115_cfg_vbi_on[] = {
- R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
- R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
- R_80_GLOBAL_CNTL_1, 0x30, /* Activate both tasks */
- R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
- R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */
-
- 0x00, 0x00
-};
-
-static const unsigned char saa7115_cfg_vbi_off[] = {
- R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
- R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
- R_80_GLOBAL_CNTL_1, 0x20, /* Activate only task "B" */
- R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
- R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */
-
- 0x00, 0x00
-};
-
-
-static const unsigned char saa7115_init_misc[] = {
- R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F, 0x01,
- R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 0x01,
- R_84_I_PORT_SIGNAL_DEF, 0x20,
- R_85_I_PORT_SIGNAL_POLAR, 0x21,
- R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT, 0xc5,
- R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
-
- /* Task A */
- R_A0_A_HORIZ_PRESCALING, 0x01,
- R_A1_A_ACCUMULATION_LENGTH, 0x00,
- R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
-
- /* Configure controls at nominal value*/
- R_A4_A_LUMA_BRIGHTNESS_CNTL, 0x80,
- R_A5_A_LUMA_CONTRAST_CNTL, 0x40,
- R_A6_A_CHROMA_SATURATION_CNTL, 0x40,
-
- /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
- R_A8_A_HORIZ_LUMA_SCALING_INC, 0x00,
- R_A9_A_HORIZ_LUMA_SCALING_INC_MSB, 0x02,
-
- R_AA_A_HORIZ_LUMA_PHASE_OFF, 0x00,
-
- /* must be horiz lum scaling / 2 */
- R_AC_A_HORIZ_CHROMA_SCALING_INC, 0x00,
- R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB, 0x01,
-
- /* must be offset luma / 2 */
- R_AE_A_HORIZ_CHROMA_PHASE_OFF, 0x00,
-
- R_B0_A_VERT_LUMA_SCALING_INC, 0x00,
- R_B1_A_VERT_LUMA_SCALING_INC_MSB, 0x04,
-
- R_B2_A_VERT_CHROMA_SCALING_INC, 0x00,
- R_B3_A_VERT_CHROMA_SCALING_INC_MSB, 0x04,
-
- R_B4_A_VERT_SCALING_MODE_CNTL, 0x01,
-
- R_B8_A_VERT_CHROMA_PHASE_OFF_00, 0x00,
- R_B9_A_VERT_CHROMA_PHASE_OFF_01, 0x00,
- R_BA_A_VERT_CHROMA_PHASE_OFF_10, 0x00,
- R_BB_A_VERT_CHROMA_PHASE_OFF_11, 0x00,
-
- R_BC_A_VERT_LUMA_PHASE_OFF_00, 0x00,
- R_BD_A_VERT_LUMA_PHASE_OFF_01, 0x00,
- R_BE_A_VERT_LUMA_PHASE_OFF_10, 0x00,
- R_BF_A_VERT_LUMA_PHASE_OFF_11, 0x00,
-
- /* Task B */
- R_D0_B_HORIZ_PRESCALING, 0x01,
- R_D1_B_ACCUMULATION_LENGTH, 0x00,
- R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
-
- /* Configure controls at nominal value*/
- R_D4_B_LUMA_BRIGHTNESS_CNTL, 0x80,
- R_D5_B_LUMA_CONTRAST_CNTL, 0x40,
- R_D6_B_CHROMA_SATURATION_CNTL, 0x40,
-
- /* hor lum scaling 0x0400 = 1 */
- R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,
- R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
-
- R_DA_B_HORIZ_LUMA_PHASE_OFF, 0x00,
-
- /* must be hor lum scaling / 2 */
- R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
- R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
-
- /* must be offset luma / 2 */
- R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA, 0x00,
-
- R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
- R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
-
- R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
- R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
-
- R_E4_B_VERT_SCALING_MODE_CNTL, 0x01,
-
- R_E8_B_VERT_CHROMA_PHASE_OFF_00, 0x00,
- R_E9_B_VERT_CHROMA_PHASE_OFF_01, 0x00,
- R_EA_B_VERT_CHROMA_PHASE_OFF_10, 0x00,
- R_EB_B_VERT_CHROMA_PHASE_OFF_11, 0x00,
-
- R_EC_B_VERT_LUMA_PHASE_OFF_00, 0x00,
- R_ED_B_VERT_LUMA_PHASE_OFF_01, 0x00,
- R_EE_B_VERT_LUMA_PHASE_OFF_10, 0x00,
- R_EF_B_VERT_LUMA_PHASE_OFF_11, 0x00,
-
- R_F2_NOMINAL_PLL2_DTO, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */
- R_F3_PLL_INCREMENT, 0x46,
- R_F4_PLL2_STATUS, 0x00,
- R_F7_PULSE_A_POS_MSB, 0x4b, /* not the recommended settings! */
- R_F8_PULSE_B_POS, 0x00,
- R_F9_PULSE_B_POS_MSB, 0x4b,
- R_FA_PULSE_C_POS, 0x00,
- R_FB_PULSE_C_POS_MSB, 0x4b,
-
- /* PLL2 lock detection settings: 71 lines 50% phase error */
- R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES, 0x88,
-
- /* Turn off VBI */
- R_40_SLICER_CNTL_1, 0x20, /* No framing code errors allowed. */
- R_41_LCR_BASE, 0xff,
- R_41_LCR_BASE+1, 0xff,
- R_41_LCR_BASE+2, 0xff,
- R_41_LCR_BASE+3, 0xff,
- R_41_LCR_BASE+4, 0xff,
- R_41_LCR_BASE+5, 0xff,
- R_41_LCR_BASE+6, 0xff,
- R_41_LCR_BASE+7, 0xff,
- R_41_LCR_BASE+8, 0xff,
- R_41_LCR_BASE+9, 0xff,
- R_41_LCR_BASE+10, 0xff,
- R_41_LCR_BASE+11, 0xff,
- R_41_LCR_BASE+12, 0xff,
- R_41_LCR_BASE+13, 0xff,
- R_41_LCR_BASE+14, 0xff,
- R_41_LCR_BASE+15, 0xff,
- R_41_LCR_BASE+16, 0xff,
- R_41_LCR_BASE+17, 0xff,
- R_41_LCR_BASE+18, 0xff,
- R_41_LCR_BASE+19, 0xff,
- R_41_LCR_BASE+20, 0xff,
- R_41_LCR_BASE+21, 0xff,
- R_41_LCR_BASE+22, 0xff,
- R_58_PROGRAM_FRAMING_CODE, 0x40,
- R_59_H_OFF_FOR_SLICER, 0x47,
- R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF, 0x83,
- R_5D_DID, 0xbd,
- R_5E_SDID, 0x35,
-
- R_02_INPUT_CNTL_1, 0xc4, /* input tuner -> input 4, amplifier active */
-
- R_80_GLOBAL_CNTL_1, 0x20, /* enable task B */
- R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
- R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
- 0x00, 0x00
-};
-
-static int saa711x_odd_parity(u8 c)
-{
- c ^= (c >> 4);
- c ^= (c >> 2);
- c ^= (c >> 1);
-
- return c & 1;
-}
-
-static int saa711x_decode_vps(u8 *dst, u8 *p)
-{
- static const u8 biphase_tbl[] = {
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
- 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
- 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
- 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
- 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
- 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
- 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
- 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
- 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
- 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
- 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
- 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
- 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
- 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
- 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
- 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
- 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
- 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
- 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
- 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
- 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
- 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- };
- int i;
- u8 c, err = 0;
-
- for (i = 0; i < 2 * 13; i += 2) {
- err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
- c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4);
- dst[i / 2] = c;
- }
- return err & 0xf0;
-}
-
-static int saa711x_decode_wss(u8 *p)
-{
- static const int wss_bits[8] = {
- 0, 0, 0, 1, 0, 1, 1, 1
- };
- unsigned char parity;
- int wss = 0;
- int i;
-
- for (i = 0; i < 16; i++) {
- int b1 = wss_bits[p[i] & 7];
- int b2 = wss_bits[(p[i] >> 3) & 7];
-
- if (b1 == b2)
- return -1;
- wss |= b2 << i;
- }
- parity = wss & 15;
- parity ^= parity >> 2;
- parity ^= parity >> 1;
-
- if (!(parity & 1))
- return -1;
-
- return wss;
-}
-
-static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
-{
- struct saa711x_state *state = to_state(sd);
- u32 acpf;
- u32 acni;
- u32 hz;
- u64 f;
- u8 acc = 0; /* reg 0x3a, audio clock control */
-
- /* Checks for chips that don't have audio clock (saa7111, saa7113) */
- if (!saa711x_has_reg(state->ident, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
- return 0;
-
- v4l2_dbg(1, debug, sd, "set audio clock freq: %d\n", freq);
-
- /* sanity check */
- if (freq < 32000 || freq > 48000)
- return -EINVAL;
-
- /* hz is the refresh rate times 100 */
- hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
- /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
- acpf = (25600 * freq) / hz;
- /* acni = (256 * freq * 2^23) / crystal_frequency =
- (freq * 2^(8+23)) / crystal_frequency =
- (freq << 31) / crystal_frequency */
- f = freq;
- f = f << 31;
- do_div(f, state->crystal_freq);
- acni = f;
- if (state->ucgc) {
- acpf = acpf * state->cgcdiv / 16;
- acni = acni * state->cgcdiv / 16;
- acc = 0x80;
- if (state->cgcdiv == 3)
- acc |= 0x40;
- }
- if (state->apll)
- acc |= 0x08;
-
- saa711x_write(sd, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
- saa711x_write(sd, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10);
- saa711x_write(sd, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
-
- saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
- saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
- (acpf >> 8) & 0xff);
- saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
- (acpf >> 16) & 0x03);
-
- saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
- saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
- saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
- state->audclk_freq = freq;
- return 0;
-}
-
-static int saa711x_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct saa711x_state *state = to_state(sd);
-
- switch (ctrl->id) {
- case V4L2_CID_CHROMA_AGC:
- /* chroma gain cluster */
- if (state->agc->val)
- state->gain->val =
- saa711x_read(sd, R_0F_CHROMA_GAIN_CNTL) & 0x7f;
- break;
- }
- return 0;
-}
-
-static int saa711x_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct saa711x_state *state = to_state(sd);
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- saa711x_write(sd, R_0A_LUMA_BRIGHT_CNTL, ctrl->val);
- break;
-
- case V4L2_CID_CONTRAST:
- saa711x_write(sd, R_0B_LUMA_CONTRAST_CNTL, ctrl->val);
- break;
-
- case V4L2_CID_SATURATION:
- saa711x_write(sd, R_0C_CHROMA_SAT_CNTL, ctrl->val);
- break;
-
- case V4L2_CID_HUE:
- saa711x_write(sd, R_0D_CHROMA_HUE_CNTL, ctrl->val);
- break;
-
- case V4L2_CID_CHROMA_AGC:
- /* chroma gain cluster */
- if (state->agc->val)
- saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, state->gain->val);
- else
- saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, state->gain->val | 0x80);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int saa711x_set_size(struct v4l2_subdev *sd, int width, int height)
-{
- struct saa711x_state *state = to_state(sd);
- int HPSC, HFSC;
- int VSCY;
- int res;
- int is_50hz = state->std & V4L2_STD_625_50;
- int Vsrc = is_50hz ? 576 : 480;
-
- v4l2_dbg(1, debug, sd, "decoder set size to %ix%i\n", width, height);
-
- /* FIXME need better bounds checking here */
- if ((width < 1) || (width > 1440))
- return -EINVAL;
- if ((height < 1) || (height > Vsrc))
- return -EINVAL;
-
- if (!saa711x_has_reg(state->ident, R_D0_B_HORIZ_PRESCALING)) {
- /* Decoder only supports 720 columns and 480 or 576 lines */
- if (width != 720)
- return -EINVAL;
- if (height != Vsrc)
- return -EINVAL;
- }
-
- state->width = width;
- state->height = height;
-
- if (!saa711x_has_reg(state->ident, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH))
- return 0;
-
- /* probably have a valid size, let's set it */
- /* Set output width/height */
- /* width */
-
- saa711x_write(sd, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
- (u8) (width & 0xff));
- saa711x_write(sd, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
- (u8) ((width >> 8) & 0xff));
-
- /* Vertical Scaling uses height/2 */
- res = height / 2;
-
- /* On 60Hz, it is using a higher Vertical Output Size */
- if (!is_50hz)
- res += (VRES_60HZ - 480) >> 1;
-
- /* height */
- saa711x_write(sd, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
- (u8) (res & 0xff));
- saa711x_write(sd, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
- (u8) ((res >> 8) & 0xff));
-
- /* Scaling settings */
- /* Hprescaler is floor(inres/outres) */
- HPSC = (int)(720 / width);
- /* 0 is not allowed (div. by zero) */
- HPSC = HPSC ? HPSC : 1;
- HFSC = (int)((1024 * 720) / (HPSC * width));
- /* FIXME hardcodes to "Task B"
- * write H prescaler integer */
- saa711x_write(sd, R_D0_B_HORIZ_PRESCALING,
- (u8) (HPSC & 0x3f));
-
- v4l2_dbg(1, debug, sd, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
- /* write H fine-scaling (luminance) */
- saa711x_write(sd, R_D8_B_HORIZ_LUMA_SCALING_INC,
- (u8) (HFSC & 0xff));
- saa711x_write(sd, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
- (u8) ((HFSC >> 8) & 0xff));
- /* write H fine-scaling (chrominance)
- * must be lum/2, so i'll just bitshift :) */
- saa711x_write(sd, R_DC_B_HORIZ_CHROMA_SCALING,
- (u8) ((HFSC >> 1) & 0xff));
- saa711x_write(sd, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
- (u8) ((HFSC >> 9) & 0xff));
-
- VSCY = (int)((1024 * Vsrc) / height);
- v4l2_dbg(1, debug, sd, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
-
- /* Correct Contrast and Luminance */
- saa711x_write(sd, R_D5_B_LUMA_CONTRAST_CNTL,
- (u8) (64 * 1024 / VSCY));
- saa711x_write(sd, R_D6_B_CHROMA_SATURATION_CNTL,
- (u8) (64 * 1024 / VSCY));
-
- /* write V fine-scaling (luminance) */
- saa711x_write(sd, R_E0_B_VERT_LUMA_SCALING_INC,
- (u8) (VSCY & 0xff));
- saa711x_write(sd, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
- (u8) ((VSCY >> 8) & 0xff));
- /* write V fine-scaling (chrominance) */
- saa711x_write(sd, R_E2_B_VERT_CHROMA_SCALING_INC,
- (u8) (VSCY & 0xff));
- saa711x_write(sd, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
- (u8) ((VSCY >> 8) & 0xff));
-
- saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
-
- /* Activates task "B" */
- saa711x_write(sd, R_80_GLOBAL_CNTL_1,
- saa711x_read(sd, R_80_GLOBAL_CNTL_1) | 0x20);
-
- return 0;
-}
-
-static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct saa711x_state *state = to_state(sd);
-
- /* Prevent unnecessary standard changes. During a standard
- change the I-Port is temporarily disabled. Any devices
- reading from that port can get confused.
- Note that s_std is also used to switch from
- radio to TV mode, so if a s_std is broadcast to
- all I2C devices then you do not want to have an unwanted
- side-effect here. */
- if (std == state->std)
- return;
-
- state->std = std;
-
- // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
- if (std & V4L2_STD_525_60) {
- v4l2_dbg(1, debug, sd, "decoder set standard 60 Hz\n");
- saa711x_writeregs(sd, saa7115_cfg_60hz_video);
- saa711x_set_size(sd, 720, 480);
- } else {
- v4l2_dbg(1, debug, sd, "decoder set standard 50 Hz\n");
- saa711x_writeregs(sd, saa7115_cfg_50hz_video);
- saa711x_set_size(sd, 720, 576);
- }
-
- /* Register 0E - Bits D6-D4 on NO-AUTO mode
- (SAA7111 and SAA7113 doesn't have auto mode)
- 50 Hz / 625 lines 60 Hz / 525 lines
- 000 PAL BGDHI (4.43Mhz) NTSC M (3.58MHz)
- 001 NTSC 4.43 (50 Hz) PAL 4.43 (60 Hz)
- 010 Combination-PAL N (3.58MHz) NTSC 4.43 (60 Hz)
- 011 NTSC N (3.58MHz) PAL M (3.58MHz)
- 100 reserved NTSC-Japan (3.58MHz)
- */
- if (state->ident <= V4L2_IDENT_SAA7113) {
- u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
-
- if (std == V4L2_STD_PAL_M) {
- reg |= 0x30;
- } else if (std == V4L2_STD_PAL_Nc) {
- reg |= 0x20;
- } else if (std == V4L2_STD_PAL_60) {
- reg |= 0x10;
- } else if (std == V4L2_STD_NTSC_M_JP) {
- reg |= 0x40;
- } else if (std & V4L2_STD_SECAM) {
- reg |= 0x50;
- }
- saa711x_write(sd, R_0E_CHROMA_CNTL_1, reg);
- } else {
- /* restart task B if needed */
- int taskb = saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10;
-
- if (taskb && state->ident == V4L2_IDENT_SAA7114) {
- saa711x_writeregs(sd, saa7115_cfg_vbi_on);
- }
-
- /* switch audio mode too! */
- saa711x_s_clock_freq(sd, state->audclk_freq);
- }
-}
-
-/* setup the sliced VBI lcr registers according to the sliced VBI format */
-static void saa711x_set_lcr(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
-{
- struct saa711x_state *state = to_state(sd);
- int is_50hz = (state->std & V4L2_STD_625_50);
- u8 lcr[24];
- int i, x;
-
-#if 1
- /* saa7113/7114/7118 VBI support are experimental */
- if (!saa711x_has_reg(state->ident, R_41_LCR_BASE))
- return;
-
-#else
- /* SAA7113 and SAA7118 also should support VBI - Need testing */
- if (state->ident != V4L2_IDENT_SAA7115)
- return;
-#endif
-
- for (i = 0; i <= 23; i++)
- lcr[i] = 0xff;
-
- if (fmt == NULL) {
- /* raw VBI */
- if (is_50hz)
- for (i = 6; i <= 23; i++)
- lcr[i] = 0xdd;
- else
- for (i = 10; i <= 21; i++)
- lcr[i] = 0xdd;
- } else {
- /* sliced VBI */
- /* first clear lines that cannot be captured */
- if (is_50hz) {
- for (i = 0; i <= 5; i++)
- fmt->service_lines[0][i] =
- fmt->service_lines[1][i] = 0;
- }
- else {
- for (i = 0; i <= 9; i++)
- fmt->service_lines[0][i] =
- fmt->service_lines[1][i] = 0;
- for (i = 22; i <= 23; i++)
- fmt->service_lines[0][i] =
- fmt->service_lines[1][i] = 0;
- }
-
- /* Now set the lcr values according to the specified service */
- for (i = 6; i <= 23; i++) {
- lcr[i] = 0;
- for (x = 0; x <= 1; x++) {
- switch (fmt->service_lines[1-x][i]) {
- case 0:
- lcr[i] |= 0xf << (4 * x);
- break;
- case V4L2_SLICED_TELETEXT_B:
- lcr[i] |= 1 << (4 * x);
- break;
- case V4L2_SLICED_CAPTION_525:
- lcr[i] |= 4 << (4 * x);
- break;
- case V4L2_SLICED_WSS_625:
- lcr[i] |= 5 << (4 * x);
- break;
- case V4L2_SLICED_VPS:
- lcr[i] |= 7 << (4 * x);
- break;
- }
- }
- }
- }
-
- /* write the lcr registers */
- for (i = 2; i <= 23; i++) {
- saa711x_write(sd, i - 2 + R_41_LCR_BASE, lcr[i]);
- }
-
- /* enable/disable raw VBI capturing */
- saa711x_writeregs(sd, fmt == NULL ?
- saa7115_cfg_vbi_on :
- saa7115_cfg_vbi_off);
-}
-
-static int saa711x_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *sliced)
-{
- static u16 lcr2vbi[] = {
- 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
- 0, V4L2_SLICED_CAPTION_525, /* 4 */
- V4L2_SLICED_WSS_625, 0, /* 5 */
- V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */
- 0, 0, 0, 0
- };
- int i;
-
- memset(sliced, 0, sizeof(*sliced));
- /* done if using raw VBI */
- if (saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10)
- return 0;
- for (i = 2; i <= 23; i++) {
- u8 v = saa711x_read(sd, i - 2 + R_41_LCR_BASE);
-
- sliced->service_lines[0][i] = lcr2vbi[v >> 4];
- sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
- sliced->service_set |=
- sliced->service_lines[0][i] | sliced->service_lines[1][i];
- }
- return 0;
-}
-
-static int saa711x_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
-{
- saa711x_set_lcr(sd, NULL);
- return 0;
-}
-
-static int saa711x_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
-{
- saa711x_set_lcr(sd, fmt);
- return 0;
-}
-
-static int saa711x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
-{
- if (fmt->code != V4L2_MBUS_FMT_FIXED)
- return -EINVAL;
- fmt->field = V4L2_FIELD_INTERLACED;
- fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
- return saa711x_set_size(sd, fmt->width, fmt->height);
-}
-
-/* Decode the sliced VBI data stream as created by the saa7115.
- The format is described in the saa7115 datasheet in Tables 25 and 26
- and in Figure 33.
- The current implementation uses SAV/EAV codes and not the ancillary data
- headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
- code. */
-static int saa711x_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
-{
- struct saa711x_state *state = to_state(sd);
- static const char vbi_no_data_pattern[] = {
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
- };
- u8 *p = vbi->p;
- u32 wss;
- int id1, id2; /* the ID1 and ID2 bytes from the internal header */
-
- vbi->type = 0; /* mark result as a failure */
- id1 = p[2];
- id2 = p[3];
- /* Note: the field bit is inverted for 60 Hz video */
- if (state->std & V4L2_STD_525_60)
- id1 ^= 0x40;
-
- /* Skip internal header, p now points to the start of the payload */
- p += 4;
- vbi->p = p;
-
- /* calculate field and line number of the VBI packet (1-23) */
- vbi->is_second_field = ((id1 & 0x40) != 0);
- vbi->line = (id1 & 0x3f) << 3;
- vbi->line |= (id2 & 0x70) >> 4;
-
- /* Obtain data type */
- id2 &= 0xf;
-
- /* If the VBI slicer does not detect any signal it will fill up
- the payload buffer with 0xa0 bytes. */
- if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
- return 0;
-
- /* decode payloads */
- switch (id2) {
- case 1:
- vbi->type = V4L2_SLICED_TELETEXT_B;
- break;
- case 4:
- if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
- return 0;
- vbi->type = V4L2_SLICED_CAPTION_525;
- break;
- case 5:
- wss = saa711x_decode_wss(p);
- if (wss == -1)
- return 0;
- p[0] = wss & 0xff;
- p[1] = wss >> 8;
- vbi->type = V4L2_SLICED_WSS_625;
- break;
- case 7:
- if (saa711x_decode_vps(p, p) != 0)
- return 0;
- vbi->type = V4L2_SLICED_VPS;
- break;
- default:
- break;
- }
- return 0;
-}
-
-/* ============ SAA7115 AUDIO settings (end) ============= */
-
-static int saa711x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct saa711x_state *state = to_state(sd);
- int status;
-
- if (state->radio)
- return 0;
- status = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
-
- v4l2_dbg(1, debug, sd, "status: 0x%02x\n", status);
- vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
- return 0;
-}
-
-static int saa711x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct saa711x_state *state = to_state(sd);
-
- state->radio = 0;
- saa711x_set_v4lstd(sd, std);
- return 0;
-}
-
-static int saa711x_s_radio(struct v4l2_subdev *sd)
-{
- struct saa711x_state *state = to_state(sd);
-
- state->radio = 1;
- return 0;
-}
-
-static int saa711x_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct saa711x_state *state = to_state(sd);
- u8 mask = (state->ident <= V4L2_IDENT_SAA7111A) ? 0xf8 : 0xf0;
-
- v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
- input, output);
-
- /* saa7111/3 does not have these inputs */
- if (state->ident <= V4L2_IDENT_SAA7113 &&
- (input == SAA7115_COMPOSITE4 ||
- input == SAA7115_COMPOSITE5)) {
- return -EINVAL;
- }
- if (input > SAA7115_SVIDEO3)
- return -EINVAL;
- if (state->input == input && state->output == output)
- return 0;
- v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
- (input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite",
- (output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
- state->input = input;
-
- /* saa7111 has slightly different input numbering */
- if (state->ident <= V4L2_IDENT_SAA7111A) {
- if (input >= SAA7115_COMPOSITE4)
- input -= 2;
- /* saa7111 specific */
- saa711x_write(sd, R_10_CHROMA_CNTL_2,
- (saa711x_read(sd, R_10_CHROMA_CNTL_2) & 0x3f) |
- ((output & 0xc0) ^ 0x40));
- saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL,
- (saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL) & 0xf0) |
- ((output & 2) ? 0x0a : 0));
- }
-
- /* select mode */
- saa711x_write(sd, R_02_INPUT_CNTL_1,
- (saa711x_read(sd, R_02_INPUT_CNTL_1) & mask) |
- input);
-
- /* bypass chrominance trap for S-Video modes */
- saa711x_write(sd, R_09_LUMA_CNTL,
- (saa711x_read(sd, R_09_LUMA_CNTL) & 0x7f) |
- (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
-
- state->output = output;
- if (state->ident == V4L2_IDENT_SAA7114 ||
- state->ident == V4L2_IDENT_SAA7115) {
- saa711x_write(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
- (saa711x_read(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) |
- (state->output & 0x01));
- }
- return 0;
-}
-
-static int saa711x_s_gpio(struct v4l2_subdev *sd, u32 val)
-{
- struct saa711x_state *state = to_state(sd);
-
- if (state->ident > V4L2_IDENT_SAA7111A)
- return -EINVAL;
- saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
- (val ? 0x80 : 0));
- return 0;
-}
-
-static int saa711x_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct saa711x_state *state = to_state(sd);
-
- v4l2_dbg(1, debug, sd, "%s output\n",
- enable ? "enable" : "disable");
-
- if (state->enable == enable)
- return 0;
- state->enable = enable;
- if (!saa711x_has_reg(state->ident, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED))
- return 0;
- saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, state->enable);
- return 0;
-}
-
-static int saa711x_s_crystal_freq(struct v4l2_subdev *sd, u32 freq, u32 flags)
-{
- struct saa711x_state *state = to_state(sd);
-
- if (freq != SAA7115_FREQ_32_11_MHZ && freq != SAA7115_FREQ_24_576_MHZ)
- return -EINVAL;
- state->crystal_freq = freq;
- state->cgcdiv = (flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
- state->ucgc = (flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
- state->apll = (flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
- saa711x_s_clock_freq(sd, state->audclk_freq);
- return 0;
-}
-
-static int saa711x_reset(struct v4l2_subdev *sd, u32 val)
-{
- v4l2_dbg(1, debug, sd, "decoder RESET\n");
- saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
- return 0;
-}
-
-static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *data)
-{
- /* Note: the internal field ID is inverted for NTSC,
- so data->field 0 maps to the saa7115 even field,
- whereas for PAL it maps to the saa7115 odd field. */
- switch (data->id) {
- case V4L2_SLICED_WSS_625:
- if (saa711x_read(sd, 0x6b) & 0xc0)
- return -EIO;
- data->data[0] = saa711x_read(sd, 0x6c);
- data->data[1] = saa711x_read(sd, 0x6d);
- return 0;
- case V4L2_SLICED_CAPTION_525:
- if (data->field == 0) {
- /* CC */
- if (saa711x_read(sd, 0x66) & 0x30)
- return -EIO;
- data->data[0] = saa711x_read(sd, 0x69);
- data->data[1] = saa711x_read(sd, 0x6a);
- return 0;
- }
- /* XDS */
- if (saa711x_read(sd, 0x66) & 0xc0)
- return -EIO;
- data->data[0] = saa711x_read(sd, 0x67);
- data->data[1] = saa711x_read(sd, 0x68);
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
-{
- struct saa711x_state *state = to_state(sd);
- int reg1f, reg1e;
-
- /*
- * The V4L2 core already initializes std with all supported
- * Standards. All driver needs to do is to mask it, to remove
- * standards that don't apply from the mask
- */
-
- reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
- v4l2_dbg(1, debug, sd, "Status byte 2 (0x1f)=0x%02x\n", reg1f);
-
- /* horizontal/vertical not locked */
- if (reg1f & 0x40)
- goto ret;
-
- if (reg1f & 0x20)
- *std &= V4L2_STD_525_60;
- else
- *std &= V4L2_STD_625_50;
-
- if (state->ident != V4L2_IDENT_SAA7115)
- goto ret;
-
- reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
-
- switch (reg1e & 0x03) {
- case 1:
- *std &= V4L2_STD_NTSC;
- break;
- case 2:
- /*
- * V4L2_STD_PAL just cover the european PAL standards.
- * This is wrong, as the device could also be using an
- * other PAL standard.
- */
- *std &= V4L2_STD_PAL | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc |
- V4L2_STD_PAL_M | V4L2_STD_PAL_60;
- break;
- case 3:
- *std &= V4L2_STD_SECAM;
- break;
- default:
- /* Can't detect anything */
- break;
- }
-
- v4l2_dbg(1, debug, sd, "Status byte 1 (0x1e)=0x%02x\n", reg1e);
-
-ret:
- v4l2_dbg(1, debug, sd, "detected std mask = %08Lx\n", *std);
-
- return 0;
-}
-
-static int saa711x_g_input_status(struct v4l2_subdev *sd, u32 *status)
-{
- struct saa711x_state *state = to_state(sd);
- int reg1e = 0x80;
- int reg1f;
-
- *status = V4L2_IN_ST_NO_SIGNAL;
- if (state->ident == V4L2_IDENT_SAA7115)
- reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
- reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
- if ((reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80)
- *status = 0;
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- reg->val = saa711x_read(sd, reg->reg & 0xff);
- reg->size = 1;
- return 0;
-}
-
-static int saa711x_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- saa711x_write(sd, reg->reg & 0xff, reg->val & 0xff);
- return 0;
-}
-#endif
-
-static int saa711x_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct saa711x_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, state->ident, 0);
-}
-
-static int saa711x_log_status(struct v4l2_subdev *sd)
-{
- struct saa711x_state *state = to_state(sd);
- int reg1e, reg1f;
- int signalOk;
- int vcr;
-
- v4l2_info(sd, "Audio frequency: %d Hz\n", state->audclk_freq);
- if (state->ident != V4L2_IDENT_SAA7115) {
- /* status for the saa7114 */
- reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
- signalOk = (reg1f & 0xc1) == 0x81;
- v4l2_info(sd, "Video signal: %s\n", signalOk ? "ok" : "bad");
- v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
- return 0;
- }
-
- /* status for the saa7115 */
- reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
- reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
-
- signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
- vcr = !(reg1f & 0x10);
-
- if (state->input >= 6)
- v4l2_info(sd, "Input: S-Video %d\n", state->input - 6);
- else
- v4l2_info(sd, "Input: Composite %d\n", state->input);
- v4l2_info(sd, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
- v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
-
- switch (reg1e & 0x03) {
- case 1:
- v4l2_info(sd, "Detected format: NTSC\n");
- break;
- case 2:
- v4l2_info(sd, "Detected format: PAL\n");
- break;
- case 3:
- v4l2_info(sd, "Detected format: SECAM\n");
- break;
- default:
- v4l2_info(sd, "Detected format: BW/No color\n");
- break;
- }
- v4l2_info(sd, "Width, Height: %d, %d\n", state->width, state->height);
- v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_ctrl_ops saa711x_ctrl_ops = {
- .s_ctrl = saa711x_s_ctrl,
- .g_volatile_ctrl = saa711x_g_volatile_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops saa711x_core_ops = {
- .log_status = saa711x_log_status,
- .g_chip_ident = saa711x_g_chip_ident,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
- .s_std = saa711x_s_std,
- .reset = saa711x_reset,
- .s_gpio = saa711x_s_gpio,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = saa711x_g_register,
- .s_register = saa711x_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_tuner_ops saa711x_tuner_ops = {
- .s_radio = saa711x_s_radio,
- .g_tuner = saa711x_g_tuner,
-};
-
-static const struct v4l2_subdev_audio_ops saa711x_audio_ops = {
- .s_clock_freq = saa711x_s_clock_freq,
-};
-
-static const struct v4l2_subdev_video_ops saa711x_video_ops = {
- .s_routing = saa711x_s_routing,
- .s_crystal_freq = saa711x_s_crystal_freq,
- .s_mbus_fmt = saa711x_s_mbus_fmt,
- .s_stream = saa711x_s_stream,
- .querystd = saa711x_querystd,
- .g_input_status = saa711x_g_input_status,
-};
-
-static const struct v4l2_subdev_vbi_ops saa711x_vbi_ops = {
- .g_vbi_data = saa711x_g_vbi_data,
- .decode_vbi_line = saa711x_decode_vbi_line,
- .g_sliced_fmt = saa711x_g_sliced_fmt,
- .s_sliced_fmt = saa711x_s_sliced_fmt,
- .s_raw_fmt = saa711x_s_raw_fmt,
-};
-
-static const struct v4l2_subdev_ops saa711x_ops = {
- .core = &saa711x_core_ops,
- .tuner = &saa711x_tuner_ops,
- .audio = &saa711x_audio_ops,
- .video = &saa711x_video_ops,
- .vbi = &saa711x_vbi_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int saa711x_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct saa711x_state *state;
- struct v4l2_subdev *sd;
- struct v4l2_ctrl_handler *hdl;
- int i;
- char name[17];
- char chip_id;
- int autodetect = !id || id->driver_data == 1;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- for (i = 0; i < 0x0f; i++) {
- i2c_smbus_write_byte_data(client, 0, i);
- name[i] = (i2c_smbus_read_byte_data(client, 0) & 0x0f) + '0';
- if (name[i] > '9')
- name[i] += 'a' - '9' - 1;
- }
- name[i] = '\0';
-
- chip_id = name[5];
-
- /* Check whether this chip is part of the saa711x series */
- if (memcmp(name + 1, "f711", 4)) {
- v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n",
- client->addr << 1, name);
- return -ENODEV;
- }
-
- /* Safety check */
- if (!autodetect && id->name[6] != chip_id) {
- v4l_warn(client, "found saa711%c while %s was expected\n",
- chip_id, id->name);
- }
- snprintf(client->name, sizeof(client->name), "saa711%c", chip_id);
- v4l_info(client, "saa711%c found (%s) @ 0x%x (%s)\n", chip_id, name,
- client->addr << 1, client->adapter->name);
-
- state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &saa711x_ops);
-
- hdl = &state->hdl;
- v4l2_ctrl_handler_init(hdl, 6);
- /* add in ascending ID order */
- v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 127, 1, 64);
- v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
- V4L2_CID_SATURATION, 0, 127, 1, 64);
- v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
- V4L2_CID_HUE, -128, 127, 1, 0);
- state->agc = v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
- V4L2_CID_CHROMA_AGC, 0, 1, 1, 1);
- state->gain = v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
- V4L2_CID_CHROMA_GAIN, 0, 127, 1, 40);
- sd->ctrl_handler = hdl;
- if (hdl->error) {
- int err = hdl->error;
-
- v4l2_ctrl_handler_free(hdl);
- kfree(state);
- return err;
- }
- v4l2_ctrl_auto_cluster(2, &state->agc, 0, true);
-
- state->input = -1;
- state->output = SAA7115_IPORT_ON;
- state->enable = 1;
- state->radio = 0;
- switch (chip_id) {
- case '1':
- state->ident = V4L2_IDENT_SAA7111;
- if (saa711x_read(sd, R_00_CHIP_VERSION) & 0xf0) {
- v4l_info(client, "saa7111a variant found\n");
- state->ident = V4L2_IDENT_SAA7111A;
- }
- break;
- case '3':
- state->ident = V4L2_IDENT_SAA7113;
- break;
- case '4':
- state->ident = V4L2_IDENT_SAA7114;
- break;
- case '5':
- state->ident = V4L2_IDENT_SAA7115;
- break;
- case '8':
- state->ident = V4L2_IDENT_SAA7118;
- break;
- default:
- state->ident = V4L2_IDENT_SAA7111;
- v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n");
- break;
- }
-
- state->audclk_freq = 48000;
-
- v4l2_dbg(1, debug, sd, "writing init values\n");
-
- /* init to 60hz/48khz */
- state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
- switch (state->ident) {
- case V4L2_IDENT_SAA7111:
- case V4L2_IDENT_SAA7111A:
- saa711x_writeregs(sd, saa7111_init);
- break;
- case V4L2_IDENT_SAA7113:
- saa711x_writeregs(sd, saa7113_init);
- break;
- default:
- state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
- saa711x_writeregs(sd, saa7115_init_auto_input);
- }
- if (state->ident > V4L2_IDENT_SAA7111A)
- saa711x_writeregs(sd, saa7115_init_misc);
- saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
- v4l2_ctrl_handler_setup(hdl);
-
- v4l2_dbg(1, debug, sd, "status: (1E) 0x%02x, (1F) 0x%02x\n",
- saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC),
- saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa711x_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(sd->ctrl_handler);
- kfree(to_state(sd));
- return 0;
-}
-
-static const struct i2c_device_id saa711x_id[] = {
- { "saa7115_auto", 1 }, /* autodetect */
- { "saa7111", 0 },
- { "saa7113", 0 },
- { "saa7114", 0 },
- { "saa7115", 0 },
- { "saa7118", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, saa711x_id);
-
-static struct i2c_driver saa711x_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "saa7115",
- },
- .probe = saa711x_probe,
- .remove = saa711x_remove,
- .id_table = saa711x_id,
-};
-
-module_i2c_driver(saa711x_driver);
diff --git a/drivers/media/video/saa711x_regs.h b/drivers/media/video/saa711x_regs.h
deleted file mode 100644
index 4e5f2eb0a2c..00000000000
--- a/drivers/media/video/saa711x_regs.h
+++ /dev/null
@@ -1,549 +0,0 @@
-/* saa711x - Philips SAA711x video decoder register specifications
- *
- * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#define R_00_CHIP_VERSION 0x00
-/* Video Decoder */
- /* Video Decoder - Frontend part */
-#define R_01_INC_DELAY 0x01
-#define R_02_INPUT_CNTL_1 0x02
-#define R_03_INPUT_CNTL_2 0x03
-#define R_04_INPUT_CNTL_3 0x04
-#define R_05_INPUT_CNTL_4 0x05
- /* Video Decoder - Decoder part */
-#define R_06_H_SYNC_START 0x06
-#define R_07_H_SYNC_STOP 0x07
-#define R_08_SYNC_CNTL 0x08
-#define R_09_LUMA_CNTL 0x09
-#define R_0A_LUMA_BRIGHT_CNTL 0x0a
-#define R_0B_LUMA_CONTRAST_CNTL 0x0b
-#define R_0C_CHROMA_SAT_CNTL 0x0c
-#define R_0D_CHROMA_HUE_CNTL 0x0d
-#define R_0E_CHROMA_CNTL_1 0x0e
-#define R_0F_CHROMA_GAIN_CNTL 0x0f
-#define R_10_CHROMA_CNTL_2 0x10
-#define R_11_MODE_DELAY_CNTL 0x11
-#define R_12_RT_SIGNAL_CNTL 0x12
-#define R_13_RT_X_PORT_OUT_CNTL 0x13
-#define R_14_ANAL_ADC_COMPAT_CNTL 0x14
-#define R_15_VGATE_START_FID_CHG 0x15
-#define R_16_VGATE_STOP 0x16
-#define R_17_MISC_VGATE_CONF_AND_MSB 0x17
-#define R_18_RAW_DATA_GAIN_CNTL 0x18
-#define R_19_RAW_DATA_OFF_CNTL 0x19
-#define R_1A_COLOR_KILL_LVL_CNTL 0x1a
-#define R_1B_MISC_TVVCRDET 0x1b
-#define R_1C_ENHAN_COMB_CTRL1 0x1c
-#define R_1D_ENHAN_COMB_CTRL2 0x1d
-#define R_1E_STATUS_BYTE_1_VD_DEC 0x1e
-#define R_1F_STATUS_BYTE_2_VD_DEC 0x1f
-
-/* Component processing and interrupt masking part */
-#define R_23_INPUT_CNTL_5 0x23
-#define R_24_INPUT_CNTL_6 0x24
-#define R_25_INPUT_CNTL_7 0x25
-#define R_29_COMP_DELAY 0x29
-#define R_2A_COMP_BRIGHT_CNTL 0x2a
-#define R_2B_COMP_CONTRAST_CNTL 0x2b
-#define R_2C_COMP_SAT_CNTL 0x2c
-#define R_2D_INTERRUPT_MASK_1 0x2d
-#define R_2E_INTERRUPT_MASK_2 0x2e
-#define R_2F_INTERRUPT_MASK_3 0x2f
-
-/* Audio clock generator part */
-#define R_30_AUD_MAST_CLK_CYCLES_PER_FIELD 0x30
-#define R_34_AUD_MAST_CLK_NOMINAL_INC 0x34
-#define R_38_CLK_RATIO_AMXCLK_TO_ASCLK 0x38
-#define R_39_CLK_RATIO_ASCLK_TO_ALRCLK 0x39
-#define R_3A_AUD_CLK_GEN_BASIC_SETUP 0x3a
-
-/* General purpose VBI data slicer part */
-#define R_40_SLICER_CNTL_1 0x40
-#define R_41_LCR_BASE 0x41
-#define R_58_PROGRAM_FRAMING_CODE 0x58
-#define R_59_H_OFF_FOR_SLICER 0x59
-#define R_5A_V_OFF_FOR_SLICER 0x5a
-#define R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF 0x5b
-#define R_5D_DID 0x5d
-#define R_5E_SDID 0x5e
-#define R_60_SLICER_STATUS_BYTE_0 0x60
-#define R_61_SLICER_STATUS_BYTE_1 0x61
-#define R_62_SLICER_STATUS_BYTE_2 0x62
-
-/* X port, I port and the scaler part */
- /* Task independent global settings */
-#define R_80_GLOBAL_CNTL_1 0x80
-#define R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F 0x81
-#define R_83_X_PORT_I_O_ENA_AND_OUT_CLK 0x83
-#define R_84_I_PORT_SIGNAL_DEF 0x84
-#define R_85_I_PORT_SIGNAL_POLAR 0x85
-#define R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT 0x86
-#define R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED 0x87
-#define R_88_POWER_SAVE_ADC_PORT_CNTL 0x88
-#define R_8F_STATUS_INFO_SCALER 0x8f
- /* Task A definition */
- /* Basic settings and acquisition window definition */
-#define R_90_A_TASK_HANDLING_CNTL 0x90
-#define R_91_A_X_PORT_FORMATS_AND_CONF 0x91
-#define R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL 0x92
-#define R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF 0x93
-#define R_94_A_HORIZ_INPUT_WINDOW_START 0x94
-#define R_95_A_HORIZ_INPUT_WINDOW_START_MSB 0x95
-#define R_96_A_HORIZ_INPUT_WINDOW_LENGTH 0x96
-#define R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB 0x97
-#define R_98_A_VERT_INPUT_WINDOW_START 0x98
-#define R_99_A_VERT_INPUT_WINDOW_START_MSB 0x99
-#define R_9A_A_VERT_INPUT_WINDOW_LENGTH 0x9a
-#define R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB 0x9b
-#define R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH 0x9c
-#define R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB 0x9d
-#define R_9E_A_VERT_OUTPUT_WINDOW_LENGTH 0x9e
-#define R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB 0x9f
- /* FIR filtering and prescaling */
-#define R_A0_A_HORIZ_PRESCALING 0xa0
-#define R_A1_A_ACCUMULATION_LENGTH 0xa1
-#define R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER 0xa2
-#define R_A4_A_LUMA_BRIGHTNESS_CNTL 0xa4
-#define R_A5_A_LUMA_CONTRAST_CNTL 0xa5
-#define R_A6_A_CHROMA_SATURATION_CNTL 0xa6
- /* Horizontal phase scaling */
-#define R_A8_A_HORIZ_LUMA_SCALING_INC 0xa8
-#define R_A9_A_HORIZ_LUMA_SCALING_INC_MSB 0xa9
-#define R_AA_A_HORIZ_LUMA_PHASE_OFF 0xaa
-#define R_AC_A_HORIZ_CHROMA_SCALING_INC 0xac
-#define R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB 0xad
-#define R_AE_A_HORIZ_CHROMA_PHASE_OFF 0xae
-#define R_AF_A_HORIZ_CHROMA_PHASE_OFF_MSB 0xaf
- /* Vertical scaling */
-#define R_B0_A_VERT_LUMA_SCALING_INC 0xb0
-#define R_B1_A_VERT_LUMA_SCALING_INC_MSB 0xb1
-#define R_B2_A_VERT_CHROMA_SCALING_INC 0xb2
-#define R_B3_A_VERT_CHROMA_SCALING_INC_MSB 0xb3
-#define R_B4_A_VERT_SCALING_MODE_CNTL 0xb4
-#define R_B8_A_VERT_CHROMA_PHASE_OFF_00 0xb8
-#define R_B9_A_VERT_CHROMA_PHASE_OFF_01 0xb9
-#define R_BA_A_VERT_CHROMA_PHASE_OFF_10 0xba
-#define R_BB_A_VERT_CHROMA_PHASE_OFF_11 0xbb
-#define R_BC_A_VERT_LUMA_PHASE_OFF_00 0xbc
-#define R_BD_A_VERT_LUMA_PHASE_OFF_01 0xbd
-#define R_BE_A_VERT_LUMA_PHASE_OFF_10 0xbe
-#define R_BF_A_VERT_LUMA_PHASE_OFF_11 0xbf
- /* Task B definition */
- /* Basic settings and acquisition window definition */
-#define R_C0_B_TASK_HANDLING_CNTL 0xc0
-#define R_C1_B_X_PORT_FORMATS_AND_CONF 0xc1
-#define R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION 0xc2
-#define R_C3_B_I_PORT_FORMATS_AND_CONF 0xc3
-#define R_C4_B_HORIZ_INPUT_WINDOW_START 0xc4
-#define R_C5_B_HORIZ_INPUT_WINDOW_START_MSB 0xc5
-#define R_C6_B_HORIZ_INPUT_WINDOW_LENGTH 0xc6
-#define R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB 0xc7
-#define R_C8_B_VERT_INPUT_WINDOW_START 0xc8
-#define R_C9_B_VERT_INPUT_WINDOW_START_MSB 0xc9
-#define R_CA_B_VERT_INPUT_WINDOW_LENGTH 0xca
-#define R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB 0xcb
-#define R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH 0xcc
-#define R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB 0xcd
-#define R_CE_B_VERT_OUTPUT_WINDOW_LENGTH 0xce
-#define R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB 0xcf
- /* FIR filtering and prescaling */
-#define R_D0_B_HORIZ_PRESCALING 0xd0
-#define R_D1_B_ACCUMULATION_LENGTH 0xd1
-#define R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER 0xd2
-#define R_D4_B_LUMA_BRIGHTNESS_CNTL 0xd4
-#define R_D5_B_LUMA_CONTRAST_CNTL 0xd5
-#define R_D6_B_CHROMA_SATURATION_CNTL 0xd6
- /* Horizontal phase scaling */
-#define R_D8_B_HORIZ_LUMA_SCALING_INC 0xd8
-#define R_D9_B_HORIZ_LUMA_SCALING_INC_MSB 0xd9
-#define R_DA_B_HORIZ_LUMA_PHASE_OFF 0xda
-#define R_DC_B_HORIZ_CHROMA_SCALING 0xdc
-#define R_DD_B_HORIZ_CHROMA_SCALING_MSB 0xdd
-#define R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA 0xde
- /* Vertical scaling */
-#define R_E0_B_VERT_LUMA_SCALING_INC 0xe0
-#define R_E1_B_VERT_LUMA_SCALING_INC_MSB 0xe1
-#define R_E2_B_VERT_CHROMA_SCALING_INC 0xe2
-#define R_E3_B_VERT_CHROMA_SCALING_INC_MSB 0xe3
-#define R_E4_B_VERT_SCALING_MODE_CNTL 0xe4
-#define R_E8_B_VERT_CHROMA_PHASE_OFF_00 0xe8
-#define R_E9_B_VERT_CHROMA_PHASE_OFF_01 0xe9
-#define R_EA_B_VERT_CHROMA_PHASE_OFF_10 0xea
-#define R_EB_B_VERT_CHROMA_PHASE_OFF_11 0xeb
-#define R_EC_B_VERT_LUMA_PHASE_OFF_00 0xec
-#define R_ED_B_VERT_LUMA_PHASE_OFF_01 0xed
-#define R_EE_B_VERT_LUMA_PHASE_OFF_10 0xee
-#define R_EF_B_VERT_LUMA_PHASE_OFF_11 0xef
-
-/* second PLL (PLL2) and Pulsegenerator Programming */
-#define R_F0_LFCO_PER_LINE 0xf0
-#define R_F1_P_I_PARAM_SELECT 0xf1
-#define R_F2_NOMINAL_PLL2_DTO 0xf2
-#define R_F3_PLL_INCREMENT 0xf3
-#define R_F4_PLL2_STATUS 0xf4
-#define R_F5_PULSGEN_LINE_LENGTH 0xf5
-#define R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG 0xf6
-#define R_F7_PULSE_A_POS_MSB 0xf7
-#define R_F8_PULSE_B_POS 0xf8
-#define R_F9_PULSE_B_POS_MSB 0xf9
-#define R_FA_PULSE_C_POS 0xfa
-#define R_FB_PULSE_C_POS_MSB 0xfb
-#define R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES 0xff
-
-#if 0
-/* Those structs will be used in the future for debug purposes */
-struct saa711x_reg_descr {
- u8 reg;
- int count;
- char *name;
-};
-
-struct saa711x_reg_descr saa711x_regs[] = {
- /* REG COUNT NAME */
- {R_00_CHIP_VERSION,1,
- "Chip version"},
-
- /* Video Decoder: R_01_INC_DELAY to R_1F_STATUS_BYTE_2_VD_DEC */
-
- /* Video Decoder - Frontend part: R_01_INC_DELAY to R_05_INPUT_CNTL_4 */
- {R_01_INC_DELAY,1,
- "Increment delay"},
- {R_02_INPUT_CNTL_1,1,
- "Analog input control 1"},
- {R_03_INPUT_CNTL_2,1,
- "Analog input control 2"},
- {R_04_INPUT_CNTL_3,1,
- "Analog input control 3"},
- {R_05_INPUT_CNTL_4,1,
- "Analog input control 4"},
-
- /* Video Decoder - Decoder part: R_06_H_SYNC_START to R_1F_STATUS_BYTE_2_VD_DEC */
- {R_06_H_SYNC_START,1,
- "Horizontal sync start"},
- {R_07_H_SYNC_STOP,1,
- "Horizontal sync stop"},
- {R_08_SYNC_CNTL,1,
- "Sync control"},
- {R_09_LUMA_CNTL,1,
- "Luminance control"},
- {R_0A_LUMA_BRIGHT_CNTL,1,
- "Luminance brightness control"},
- {R_0B_LUMA_CONTRAST_CNTL,1,
- "Luminance contrast control"},
- {R_0C_CHROMA_SAT_CNTL,1,
- "Chrominance saturation control"},
- {R_0D_CHROMA_HUE_CNTL,1,
- "Chrominance hue control"},
- {R_0E_CHROMA_CNTL_1,1,
- "Chrominance control 1"},
- {R_0F_CHROMA_GAIN_CNTL,1,
- "Chrominance gain control"},
- {R_10_CHROMA_CNTL_2,1,
- "Chrominance control 2"},
- {R_11_MODE_DELAY_CNTL,1,
- "Mode/delay control"},
- {R_12_RT_SIGNAL_CNTL,1,
- "RT signal control"},
- {R_13_RT_X_PORT_OUT_CNTL,1,
- "RT/X port output control"},
- {R_14_ANAL_ADC_COMPAT_CNTL,1,
- "Analog/ADC/compatibility control"},
- {R_15_VGATE_START_FID_CHG, 1,
- "VGATE start FID change"},
- {R_16_VGATE_STOP,1,
- "VGATE stop"},
- {R_17_MISC_VGATE_CONF_AND_MSB, 1,
- "Miscellaneous VGATE configuration and MSBs"},
- {R_18_RAW_DATA_GAIN_CNTL,1,
- "Raw data gain control",},
- {R_19_RAW_DATA_OFF_CNTL,1,
- "Raw data offset control",},
- {R_1A_COLOR_KILL_LVL_CNTL,1,
- "Color Killer Level Control"},
- { R_1B_MISC_TVVCRDET, 1,
- "MISC /TVVCRDET"},
- { R_1C_ENHAN_COMB_CTRL1, 1,
- "Enhanced comb ctrl1"},
- { R_1D_ENHAN_COMB_CTRL2, 1,
- "Enhanced comb ctrl1"},
- {R_1E_STATUS_BYTE_1_VD_DEC,1,
- "Status byte 1 video decoder"},
- {R_1F_STATUS_BYTE_2_VD_DEC,1,
- "Status byte 2 video decoder"},
-
- /* Component processing and interrupt masking part: 0x20h to R_2F_INTERRUPT_MASK_3 */
- /* 0x20 to 0x22 - Reserved */
- {R_23_INPUT_CNTL_5,1,
- "Analog input control 5"},
- {R_24_INPUT_CNTL_6,1,
- "Analog input control 6"},
- {R_25_INPUT_CNTL_7,1,
- "Analog input control 7"},
- /* 0x26 to 0x28 - Reserved */
- {R_29_COMP_DELAY,1,
- "Component delay"},
- {R_2A_COMP_BRIGHT_CNTL,1,
- "Component brightness control"},
- {R_2B_COMP_CONTRAST_CNTL,1,
- "Component contrast control"},
- {R_2C_COMP_SAT_CNTL,1,
- "Component saturation control"},
- {R_2D_INTERRUPT_MASK_1,1,
- "Interrupt mask 1"},
- {R_2E_INTERRUPT_MASK_2,1,
- "Interrupt mask 2"},
- {R_2F_INTERRUPT_MASK_3,1,
- "Interrupt mask 3"},
-
- /* Audio clock generator part: R_30_AUD_MAST_CLK_CYCLES_PER_FIELD to 0x3f */
- {R_30_AUD_MAST_CLK_CYCLES_PER_FIELD,3,
- "Audio master clock cycles per field"},
- /* 0x33 - Reserved */
- {R_34_AUD_MAST_CLK_NOMINAL_INC,3,
- "Audio master clock nominal increment"},
- /* 0x37 - Reserved */
- {R_38_CLK_RATIO_AMXCLK_TO_ASCLK,1,
- "Clock ratio AMXCLK to ASCLK"},
- {R_39_CLK_RATIO_ASCLK_TO_ALRCLK,1,
- "Clock ratio ASCLK to ALRCLK"},
- {R_3A_AUD_CLK_GEN_BASIC_SETUP,1,
- "Audio clock generator basic setup"},
- /* 0x3b-0x3f - Reserved */
-
- /* General purpose VBI data slicer part: R_40_SLICER_CNTL_1 to 0x7f */
- {R_40_SLICER_CNTL_1,1,
- "Slicer control 1"},
- {R_41_LCR,23,
- "R_41_LCR"},
- {R_58_PROGRAM_FRAMING_CODE,1,
- "Programmable framing code"},
- {R_59_H_OFF_FOR_SLICER,1,
- "Horizontal offset for slicer"},
- {R_5A_V_OFF_FOR_SLICER,1,
- "Vertical offset for slicer"},
- {R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF,1,
- "Field offset and MSBs for horizontal and vertical offset"},
- {R_5D_DID,1,
- "Header and data identification (R_5D_DID)"},
- {R_5E_SDID,1,
- "Sliced data identification (R_5E_SDID) code"},
- {R_60_SLICER_STATUS_BYTE_0,1,
- "Slicer status byte 0"},
- {R_61_SLICER_STATUS_BYTE_1,1,
- "Slicer status byte 1"},
- {R_62_SLICER_STATUS_BYTE_2,1,
- "Slicer status byte 2"},
- /* 0x63-0x7f - Reserved */
-
- /* X port, I port and the scaler part: R_80_GLOBAL_CNTL_1 to R_EF_B_VERT_LUMA_PHASE_OFF_11 */
- /* Task independent global settings: R_80_GLOBAL_CNTL_1 to R_8F_STATUS_INFO_SCALER */
- {R_80_GLOBAL_CNTL_1,1,
- "Global control 1"},
- {R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F,1,
- "Vertical sync and Field ID source selection, retimed V and F signals"},
- /* 0x82 - Reserved */
- {R_83_X_PORT_I_O_ENA_AND_OUT_CLK,1,
- "X port I/O enable and output clock"},
- {R_84_I_PORT_SIGNAL_DEF,1,
- "I port signal definitions"},
- {R_85_I_PORT_SIGNAL_POLAR,1,
- "I port signal polarities"},
- {R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT,1,
- "I port FIFO flag control and arbitration"},
- {R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 1,
- "I port I/O enable output clock and gated"},
- {R_88_POWER_SAVE_ADC_PORT_CNTL,1,
- "Power save/ADC port control"},
- /* 089-0x8e - Reserved */
- {R_8F_STATUS_INFO_SCALER,1,
- "Status information scaler part"},
-
- /* Task A definition: R_90_A_TASK_HANDLING_CNTL to R_BF_A_VERT_LUMA_PHASE_OFF_11 */
- /* Task A: Basic settings and acquisition window definition */
- {R_90_A_TASK_HANDLING_CNTL,1,
- "Task A: Task handling control"},
- {R_91_A_X_PORT_FORMATS_AND_CONF,1,
- "Task A: X port formats and configuration"},
- {R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL,1,
- "Task A: X port input reference signal definition"},
- {R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF,1,
- "Task A: I port output formats and configuration"},
- {R_94_A_HORIZ_INPUT_WINDOW_START,2,
- "Task A: Horizontal input window start"},
- {R_96_A_HORIZ_INPUT_WINDOW_LENGTH,2,
- "Task A: Horizontal input window length"},
- {R_98_A_VERT_INPUT_WINDOW_START,2,
- "Task A: Vertical input window start"},
- {R_9A_A_VERT_INPUT_WINDOW_LENGTH,2,
- "Task A: Vertical input window length"},
- {R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH,2,
- "Task A: Horizontal output window length"},
- {R_9E_A_VERT_OUTPUT_WINDOW_LENGTH,2,
- "Task A: Vertical output window length"},
-
- /* Task A: FIR filtering and prescaling */
- {R_A0_A_HORIZ_PRESCALING,1,
- "Task A: Horizontal prescaling"},
- {R_A1_A_ACCUMULATION_LENGTH,1,
- "Task A: Accumulation length"},
- {R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER,1,
- "Task A: Prescaler DC gain and FIR prefilter"},
- /* 0xa3 - Reserved */
- {R_A4_A_LUMA_BRIGHTNESS_CNTL,1,
- "Task A: Luminance brightness control"},
- {R_A5_A_LUMA_CONTRAST_CNTL,1,
- "Task A: Luminance contrast control"},
- {R_A6_A_CHROMA_SATURATION_CNTL,1,
- "Task A: Chrominance saturation control"},
- /* 0xa7 - Reserved */
-
- /* Task A: Horizontal phase scaling */
- {R_A8_A_HORIZ_LUMA_SCALING_INC,2,
- "Task A: Horizontal luminance scaling increment"},
- {R_AA_A_HORIZ_LUMA_PHASE_OFF,1,
- "Task A: Horizontal luminance phase offset"},
- /* 0xab - Reserved */
- {R_AC_A_HORIZ_CHROMA_SCALING_INC,2,
- "Task A: Horizontal chrominance scaling increment"},
- {R_AE_A_HORIZ_CHROMA_PHASE_OFF,1,
- "Task A: Horizontal chrominance phase offset"},
- /* 0xaf - Reserved */
-
- /* Task A: Vertical scaling */
- {R_B0_A_VERT_LUMA_SCALING_INC,2,
- "Task A: Vertical luminance scaling increment"},
- {R_B2_A_VERT_CHROMA_SCALING_INC,2,
- "Task A: Vertical chrominance scaling increment"},
- {R_B4_A_VERT_SCALING_MODE_CNTL,1,
- "Task A: Vertical scaling mode control"},
- /* 0xb5-0xb7 - Reserved */
- {R_B8_A_VERT_CHROMA_PHASE_OFF_00,1,
- "Task A: Vertical chrominance phase offset '00'"},
- {R_B9_A_VERT_CHROMA_PHASE_OFF_01,1,
- "Task A: Vertical chrominance phase offset '01'"},
- {R_BA_A_VERT_CHROMA_PHASE_OFF_10,1,
- "Task A: Vertical chrominance phase offset '10'"},
- {R_BB_A_VERT_CHROMA_PHASE_OFF_11,1,
- "Task A: Vertical chrominance phase offset '11'"},
- {R_BC_A_VERT_LUMA_PHASE_OFF_00,1,
- "Task A: Vertical luminance phase offset '00'"},
- {R_BD_A_VERT_LUMA_PHASE_OFF_01,1,
- "Task A: Vertical luminance phase offset '01'"},
- {R_BE_A_VERT_LUMA_PHASE_OFF_10,1,
- "Task A: Vertical luminance phase offset '10'"},
- {R_BF_A_VERT_LUMA_PHASE_OFF_11,1,
- "Task A: Vertical luminance phase offset '11'"},
-
- /* Task B definition: R_C0_B_TASK_HANDLING_CNTL to R_EF_B_VERT_LUMA_PHASE_OFF_11 */
- /* Task B: Basic settings and acquisition window definition */
- {R_C0_B_TASK_HANDLING_CNTL,1,
- "Task B: Task handling control"},
- {R_C1_B_X_PORT_FORMATS_AND_CONF,1,
- "Task B: X port formats and configuration"},
- {R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION,1,
- "Task B: Input reference signal definition"},
- {R_C3_B_I_PORT_FORMATS_AND_CONF,1,
- "Task B: I port formats and configuration"},
- {R_C4_B_HORIZ_INPUT_WINDOW_START,2,
- "Task B: Horizontal input window start"},
- {R_C6_B_HORIZ_INPUT_WINDOW_LENGTH,2,
- "Task B: Horizontal input window length"},
- {R_C8_B_VERT_INPUT_WINDOW_START,2,
- "Task B: Vertical input window start"},
- {R_CA_B_VERT_INPUT_WINDOW_LENGTH,2,
- "Task B: Vertical input window length"},
- {R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,2,
- "Task B: Horizontal output window length"},
- {R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,2,
- "Task B: Vertical output window length"},
-
- /* Task B: FIR filtering and prescaling */
- {R_D0_B_HORIZ_PRESCALING,1,
- "Task B: Horizontal prescaling"},
- {R_D1_B_ACCUMULATION_LENGTH,1,
- "Task B: Accumulation length"},
- {R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER,1,
- "Task B: Prescaler DC gain and FIR prefilter"},
- /* 0xd3 - Reserved */
- {R_D4_B_LUMA_BRIGHTNESS_CNTL,1,
- "Task B: Luminance brightness control"},
- {R_D5_B_LUMA_CONTRAST_CNTL,1,
- "Task B: Luminance contrast control"},
- {R_D6_B_CHROMA_SATURATION_CNTL,1,
- "Task B: Chrominance saturation control"},
- /* 0xd7 - Reserved */
-
- /* Task B: Horizontal phase scaling */
- {R_D8_B_HORIZ_LUMA_SCALING_INC,2,
- "Task B: Horizontal luminance scaling increment"},
- {R_DA_B_HORIZ_LUMA_PHASE_OFF,1,
- "Task B: Horizontal luminance phase offset"},
- /* 0xdb - Reserved */
- {R_DC_B_HORIZ_CHROMA_SCALING,2,
- "Task B: Horizontal chrominance scaling"},
- {R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA,1,
- "Task B: Horizontal Phase Offset Chroma"},
- /* 0xdf - Reserved */
-
- /* Task B: Vertical scaling */
- {R_E0_B_VERT_LUMA_SCALING_INC,2,
- "Task B: Vertical luminance scaling increment"},
- {R_E2_B_VERT_CHROMA_SCALING_INC,2,
- "Task B: Vertical chrominance scaling increment"},
- {R_E4_B_VERT_SCALING_MODE_CNTL,1,
- "Task B: Vertical scaling mode control"},
- /* 0xe5-0xe7 - Reserved */
- {R_E8_B_VERT_CHROMA_PHASE_OFF_00,1,
- "Task B: Vertical chrominance phase offset '00'"},
- {R_E9_B_VERT_CHROMA_PHASE_OFF_01,1,
- "Task B: Vertical chrominance phase offset '01'"},
- {R_EA_B_VERT_CHROMA_PHASE_OFF_10,1,
- "Task B: Vertical chrominance phase offset '10'"},
- {R_EB_B_VERT_CHROMA_PHASE_OFF_11,1,
- "Task B: Vertical chrominance phase offset '11'"},
- {R_EC_B_VERT_LUMA_PHASE_OFF_00,1,
- "Task B: Vertical luminance phase offset '00'"},
- {R_ED_B_VERT_LUMA_PHASE_OFF_01,1,
- "Task B: Vertical luminance phase offset '01'"},
- {R_EE_B_VERT_LUMA_PHASE_OFF_10,1,
- "Task B: Vertical luminance phase offset '10'"},
- {R_EF_B_VERT_LUMA_PHASE_OFF_11,1,
- "Task B: Vertical luminance phase offset '11'"},
-
- /* second PLL (PLL2) and Pulsegenerator Programming */
- { R_F0_LFCO_PER_LINE, 1,
- "LFCO's per line"},
- { R_F1_P_I_PARAM_SELECT,1,
- "P-/I- Param. Select., PLL Mode, PLL H-Src., LFCO's per line"},
- { R_F2_NOMINAL_PLL2_DTO,1,
- "Nominal PLL2 DTO"},
- {R_F3_PLL_INCREMENT,1,
- "PLL2 Increment"},
- {R_F4_PLL2_STATUS,1,
- "PLL2 Status"},
- {R_F5_PULSGEN_LINE_LENGTH,1,
- "Pulsgen. line length"},
- {R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG,1,
- "Pulse A Position, Pulsgen Resync., Pulsgen. H-Src., Pulsgen. line length"},
- {R_F7_PULSE_A_POS_MSB,1,
- "Pulse A Position"},
- {R_F8_PULSE_B_POS,2,
- "Pulse B Position"},
- {R_FA_PULSE_C_POS,2,
- "Pulse C Position"},
- /* 0xfc to 0xfe - Reserved */
- {R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES,1,
- "S_PLL max. phase, error threshold, PLL2 no. of lines, threshold"},
-};
-#endif
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
deleted file mode 100644
index 39c90b08eea..00000000000
--- a/drivers/media/video/saa7127.c
+++ /dev/null
@@ -1,855 +0,0 @@
-/*
- * saa7127 - Philips SAA7127/SAA7129 video encoder driver
- *
- * Copyright (C) 2003 Roy Bulter <rbulter@hetnet.nl>
- *
- * Based on SAA7126 video encoder driver by Gillem & Andreas Oberritter
- *
- * Copyright (C) 2000-2001 Gillem <htoa@gmx.net>
- * Copyright (C) 2002 Andreas Oberritter <obi@saftware.de>
- *
- * Based on Stadis 4:2:2 MPEG-2 Decoder Driver by Nathan Laredo
- *
- * Copyright (C) 1999 Nathan Laredo <laredo@gnu.org>
- *
- * This driver is designed for the Hauppauge 250/350 Linux driver
- * from the ivtv Project
- *
- * Copyright (C) 2003 Kevin Thayer <nufan_wfk@yahoo.com>
- *
- * Dual output support:
- * Copyright (C) 2004 Eric Varsanyi
- *
- * NTSC Tuning and 7.5 IRE Setup
- * Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- *
- * VBI additions & cleanup:
- * Copyright (C) 2004, 2005 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * Note: the saa7126 is identical to the saa7127, and the saa7128 is
- * identical to the saa7129, except that the saa7126 and saa7128 have
- * macrovision anti-taping support. This driver will almost certainly
- * work fine for those chips, except of course for the missing anti-taping
- * support.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/saa7127.h>
-
-static int debug;
-static int test_image;
-
-MODULE_DESCRIPTION("Philips SAA7127/9 video encoder driver");
-MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil");
-MODULE_LICENSE("GPL");
-module_param(debug, int, 0644);
-module_param(test_image, int, 0644);
-MODULE_PARM_DESC(debug, "debug level (0-2)");
-MODULE_PARM_DESC(test_image, "test_image (0-1)");
-
-
-/*
- * SAA7127 registers
- */
-
-#define SAA7127_REG_STATUS 0x00
-#define SAA7127_REG_WIDESCREEN_CONFIG 0x26
-#define SAA7127_REG_WIDESCREEN_ENABLE 0x27
-#define SAA7127_REG_BURST_START 0x28
-#define SAA7127_REG_BURST_END 0x29
-#define SAA7127_REG_COPYGEN_0 0x2a
-#define SAA7127_REG_COPYGEN_1 0x2b
-#define SAA7127_REG_COPYGEN_2 0x2c
-#define SAA7127_REG_OUTPUT_PORT_CONTROL 0x2d
-#define SAA7127_REG_GAIN_LUMINANCE_RGB 0x38
-#define SAA7127_REG_GAIN_COLORDIFF_RGB 0x39
-#define SAA7127_REG_INPUT_PORT_CONTROL_1 0x3a
-#define SAA7129_REG_FADE_KEY_COL2 0x4f
-#define SAA7127_REG_CHROMA_PHASE 0x5a
-#define SAA7127_REG_GAINU 0x5b
-#define SAA7127_REG_GAINV 0x5c
-#define SAA7127_REG_BLACK_LEVEL 0x5d
-#define SAA7127_REG_BLANKING_LEVEL 0x5e
-#define SAA7127_REG_VBI_BLANKING 0x5f
-#define SAA7127_REG_DAC_CONTROL 0x61
-#define SAA7127_REG_BURST_AMP 0x62
-#define SAA7127_REG_SUBC3 0x63
-#define SAA7127_REG_SUBC2 0x64
-#define SAA7127_REG_SUBC1 0x65
-#define SAA7127_REG_SUBC0 0x66
-#define SAA7127_REG_LINE_21_ODD_0 0x67
-#define SAA7127_REG_LINE_21_ODD_1 0x68
-#define SAA7127_REG_LINE_21_EVEN_0 0x69
-#define SAA7127_REG_LINE_21_EVEN_1 0x6a
-#define SAA7127_REG_RCV_PORT_CONTROL 0x6b
-#define SAA7127_REG_VTRIG 0x6c
-#define SAA7127_REG_HTRIG_HI 0x6d
-#define SAA7127_REG_MULTI 0x6e
-#define SAA7127_REG_CLOSED_CAPTION 0x6f
-#define SAA7127_REG_RCV2_OUTPUT_START 0x70
-#define SAA7127_REG_RCV2_OUTPUT_END 0x71
-#define SAA7127_REG_RCV2_OUTPUT_MSBS 0x72
-#define SAA7127_REG_TTX_REQUEST_H_START 0x73
-#define SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH 0x74
-#define SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT 0x75
-#define SAA7127_REG_TTX_ODD_REQ_VERT_START 0x76
-#define SAA7127_REG_TTX_ODD_REQ_VERT_END 0x77
-#define SAA7127_REG_TTX_EVEN_REQ_VERT_START 0x78
-#define SAA7127_REG_TTX_EVEN_REQ_VERT_END 0x79
-#define SAA7127_REG_FIRST_ACTIVE 0x7a
-#define SAA7127_REG_LAST_ACTIVE 0x7b
-#define SAA7127_REG_MSB_VERTICAL 0x7c
-#define SAA7127_REG_DISABLE_TTX_LINE_LO_0 0x7e
-#define SAA7127_REG_DISABLE_TTX_LINE_LO_1 0x7f
-
-/*
- **********************************************************************
- *
- * Arrays with configuration parameters for the SAA7127
- *
- **********************************************************************
- */
-
-struct i2c_reg_value {
- unsigned char reg;
- unsigned char value;
-};
-
-static const struct i2c_reg_value saa7129_init_config_extra[] = {
- { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 },
- { SAA7127_REG_VTRIG, 0xfa },
- { 0, 0 }
-};
-
-static const struct i2c_reg_value saa7127_init_config_common[] = {
- { SAA7127_REG_WIDESCREEN_CONFIG, 0x0d },
- { SAA7127_REG_WIDESCREEN_ENABLE, 0x00 },
- { SAA7127_REG_COPYGEN_0, 0x77 },
- { SAA7127_REG_COPYGEN_1, 0x41 },
- { SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */
- { SAA7127_REG_OUTPUT_PORT_CONTROL, 0xbf },
- { SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 },
- { SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 },
- { SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */
- { SAA7127_REG_LINE_21_ODD_0, 0x77 },
- { SAA7127_REG_LINE_21_ODD_1, 0x41 },
- { SAA7127_REG_LINE_21_EVEN_0, 0x88 },
- { SAA7127_REG_LINE_21_EVEN_1, 0x41 },
- { SAA7127_REG_RCV_PORT_CONTROL, 0x12 },
- { SAA7127_REG_VTRIG, 0xf9 },
- { SAA7127_REG_HTRIG_HI, 0x00 },
- { SAA7127_REG_RCV2_OUTPUT_START, 0x41 },
- { SAA7127_REG_RCV2_OUTPUT_END, 0xc3 },
- { SAA7127_REG_RCV2_OUTPUT_MSBS, 0x00 },
- { SAA7127_REG_TTX_REQUEST_H_START, 0x3e },
- { SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH, 0xb8 },
- { SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT, 0x03 },
- { SAA7127_REG_TTX_ODD_REQ_VERT_START, 0x15 },
- { SAA7127_REG_TTX_ODD_REQ_VERT_END, 0x16 },
- { SAA7127_REG_TTX_EVEN_REQ_VERT_START, 0x15 },
- { SAA7127_REG_TTX_EVEN_REQ_VERT_END, 0x16 },
- { SAA7127_REG_FIRST_ACTIVE, 0x1a },
- { SAA7127_REG_LAST_ACTIVE, 0x01 },
- { SAA7127_REG_MSB_VERTICAL, 0xc0 },
- { SAA7127_REG_DISABLE_TTX_LINE_LO_0, 0x00 },
- { SAA7127_REG_DISABLE_TTX_LINE_LO_1, 0x00 },
- { 0, 0 }
-};
-
-#define SAA7127_60HZ_DAC_CONTROL 0x15
-static const struct i2c_reg_value saa7127_init_config_60hz[] = {
- { SAA7127_REG_BURST_START, 0x19 },
- /* BURST_END is also used as a chip ID in saa7127_probe */
- { SAA7127_REG_BURST_END, 0x1d },
- { SAA7127_REG_CHROMA_PHASE, 0xa3 },
- { SAA7127_REG_GAINU, 0x98 },
- { SAA7127_REG_GAINV, 0xd3 },
- { SAA7127_REG_BLACK_LEVEL, 0x39 },
- { SAA7127_REG_BLANKING_LEVEL, 0x2e },
- { SAA7127_REG_VBI_BLANKING, 0x2e },
- { SAA7127_REG_DAC_CONTROL, 0x15 },
- { SAA7127_REG_BURST_AMP, 0x4d },
- { SAA7127_REG_SUBC3, 0x1f },
- { SAA7127_REG_SUBC2, 0x7c },
- { SAA7127_REG_SUBC1, 0xf0 },
- { SAA7127_REG_SUBC0, 0x21 },
- { SAA7127_REG_MULTI, 0x90 },
- { SAA7127_REG_CLOSED_CAPTION, 0x11 },
- { 0, 0 }
-};
-
-#define SAA7127_50HZ_PAL_DAC_CONTROL 0x02
-static struct i2c_reg_value saa7127_init_config_50hz_pal[] = {
- { SAA7127_REG_BURST_START, 0x21 },
- /* BURST_END is also used as a chip ID in saa7127_probe */
- { SAA7127_REG_BURST_END, 0x1d },
- { SAA7127_REG_CHROMA_PHASE, 0x3f },
- { SAA7127_REG_GAINU, 0x7d },
- { SAA7127_REG_GAINV, 0xaf },
- { SAA7127_REG_BLACK_LEVEL, 0x33 },
- { SAA7127_REG_BLANKING_LEVEL, 0x35 },
- { SAA7127_REG_VBI_BLANKING, 0x35 },
- { SAA7127_REG_DAC_CONTROL, 0x02 },
- { SAA7127_REG_BURST_AMP, 0x2f },
- { SAA7127_REG_SUBC3, 0xcb },
- { SAA7127_REG_SUBC2, 0x8a },
- { SAA7127_REG_SUBC1, 0x09 },
- { SAA7127_REG_SUBC0, 0x2a },
- { SAA7127_REG_MULTI, 0xa0 },
- { SAA7127_REG_CLOSED_CAPTION, 0x00 },
- { 0, 0 }
-};
-
-#define SAA7127_50HZ_SECAM_DAC_CONTROL 0x08
-static struct i2c_reg_value saa7127_init_config_50hz_secam[] = {
- { SAA7127_REG_BURST_START, 0x21 },
- /* BURST_END is also used as a chip ID in saa7127_probe */
- { SAA7127_REG_BURST_END, 0x1d },
- { SAA7127_REG_CHROMA_PHASE, 0x3f },
- { SAA7127_REG_GAINU, 0x6a },
- { SAA7127_REG_GAINV, 0x81 },
- { SAA7127_REG_BLACK_LEVEL, 0x33 },
- { SAA7127_REG_BLANKING_LEVEL, 0x35 },
- { SAA7127_REG_VBI_BLANKING, 0x35 },
- { SAA7127_REG_DAC_CONTROL, 0x08 },
- { SAA7127_REG_BURST_AMP, 0x2f },
- { SAA7127_REG_SUBC3, 0xb2 },
- { SAA7127_REG_SUBC2, 0x3b },
- { SAA7127_REG_SUBC1, 0xa3 },
- { SAA7127_REG_SUBC0, 0x28 },
- { SAA7127_REG_MULTI, 0x90 },
- { SAA7127_REG_CLOSED_CAPTION, 0x00 },
- { 0, 0 }
-};
-
-/*
- **********************************************************************
- *
- * Encoder Struct, holds the configuration state of the encoder
- *
- **********************************************************************
- */
-
-struct saa7127_state {
- struct v4l2_subdev sd;
- v4l2_std_id std;
- u32 ident;
- enum saa7127_input_type input_type;
- enum saa7127_output_type output_type;
- int video_enable;
- int wss_enable;
- u16 wss_mode;
- int cc_enable;
- u16 cc_data;
- int xds_enable;
- u16 xds_data;
- int vps_enable;
- u8 vps_data[5];
- u8 reg_2d;
- u8 reg_3a;
- u8 reg_3a_cb; /* colorbar bit */
- u8 reg_61;
-};
-
-static inline struct saa7127_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct saa7127_state, sd);
-}
-
-static const char * const output_strs[] =
-{
- "S-Video + Composite",
- "Composite",
- "S-Video",
- "RGB",
- "YUV C",
- "YUV V"
-};
-
-static const char * const wss_strs[] = {
- "invalid",
- "letterbox 14:9 center",
- "letterbox 14:9 top",
- "invalid",
- "letterbox 16:9 top",
- "invalid",
- "invalid",
- "16:9 full format anamorphic",
- "4:3 full format",
- "invalid",
- "invalid",
- "letterbox 16:9 center",
- "invalid",
- "letterbox >16:9 center",
- "14:9 full format center",
- "invalid",
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_read(struct v4l2_subdev *sd, u8 reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_write(struct v4l2_subdev *sd, u8 reg, u8 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int i;
-
- for (i = 0; i < 3; i++) {
- if (i2c_smbus_write_byte_data(client, reg, val) == 0)
- return 0;
- }
- v4l2_err(sd, "I2C Write Problem\n");
- return -1;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_write_inittab(struct v4l2_subdev *sd,
- const struct i2c_reg_value *regs)
-{
- while (regs->reg != 0) {
- saa7127_write(sd, regs->reg, regs->value);
- regs++;
- }
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_vps(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data)
-{
- struct saa7127_state *state = to_state(sd);
- int enable = (data->line != 0);
-
- if (enable && (data->field != 0 || data->line != 16))
- return -EINVAL;
- if (state->vps_enable != enable) {
- v4l2_dbg(1, debug, sd, "Turn VPS Signal %s\n", enable ? "on" : "off");
- saa7127_write(sd, 0x54, enable << 7);
- state->vps_enable = enable;
- }
- if (!enable)
- return 0;
-
- state->vps_data[0] = data->data[2];
- state->vps_data[1] = data->data[8];
- state->vps_data[2] = data->data[9];
- state->vps_data[3] = data->data[10];
- state->vps_data[4] = data->data[11];
- v4l2_dbg(1, debug, sd, "Set VPS data %02x %02x %02x %02x %02x\n",
- state->vps_data[0], state->vps_data[1],
- state->vps_data[2], state->vps_data[3],
- state->vps_data[4]);
- saa7127_write(sd, 0x55, state->vps_data[0]);
- saa7127_write(sd, 0x56, state->vps_data[1]);
- saa7127_write(sd, 0x57, state->vps_data[2]);
- saa7127_write(sd, 0x58, state->vps_data[3]);
- saa7127_write(sd, 0x59, state->vps_data[4]);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_cc(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data)
-{
- struct saa7127_state *state = to_state(sd);
- u16 cc = data->data[1] << 8 | data->data[0];
- int enable = (data->line != 0);
-
- if (enable && (data->field != 0 || data->line != 21))
- return -EINVAL;
- if (state->cc_enable != enable) {
- v4l2_dbg(1, debug, sd,
- "Turn CC %s\n", enable ? "on" : "off");
- saa7127_write(sd, SAA7127_REG_CLOSED_CAPTION,
- (state->xds_enable << 7) | (enable << 6) | 0x11);
- state->cc_enable = enable;
- }
- if (!enable)
- return 0;
-
- v4l2_dbg(2, debug, sd, "CC data: %04x\n", cc);
- saa7127_write(sd, SAA7127_REG_LINE_21_ODD_0, cc & 0xff);
- saa7127_write(sd, SAA7127_REG_LINE_21_ODD_1, cc >> 8);
- state->cc_data = cc;
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_xds(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data)
-{
- struct saa7127_state *state = to_state(sd);
- u16 xds = data->data[1] << 8 | data->data[0];
- int enable = (data->line != 0);
-
- if (enable && (data->field != 1 || data->line != 21))
- return -EINVAL;
- if (state->xds_enable != enable) {
- v4l2_dbg(1, debug, sd, "Turn XDS %s\n", enable ? "on" : "off");
- saa7127_write(sd, SAA7127_REG_CLOSED_CAPTION,
- (enable << 7) | (state->cc_enable << 6) | 0x11);
- state->xds_enable = enable;
- }
- if (!enable)
- return 0;
-
- v4l2_dbg(2, debug, sd, "XDS data: %04x\n", xds);
- saa7127_write(sd, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff);
- saa7127_write(sd, SAA7127_REG_LINE_21_EVEN_1, xds >> 8);
- state->xds_data = xds;
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_wss(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data)
-{
- struct saa7127_state *state = to_state(sd);
- int enable = (data->line != 0);
-
- if (enable && (data->field != 0 || data->line != 23))
- return -EINVAL;
- if (state->wss_enable != enable) {
- v4l2_dbg(1, debug, sd, "Turn WSS %s\n", enable ? "on" : "off");
- saa7127_write(sd, 0x27, enable << 7);
- state->wss_enable = enable;
- }
- if (!enable)
- return 0;
-
- saa7127_write(sd, 0x26, data->data[0]);
- saa7127_write(sd, 0x27, 0x80 | (data->data[1] & 0x3f));
- v4l2_dbg(1, debug, sd,
- "WSS mode: %s\n", wss_strs[data->data[0] & 0xf]);
- state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0];
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_video_enable(struct v4l2_subdev *sd, int enable)
-{
- struct saa7127_state *state = to_state(sd);
-
- if (enable) {
- v4l2_dbg(1, debug, sd, "Enable Video Output\n");
- saa7127_write(sd, 0x2d, state->reg_2d);
- saa7127_write(sd, 0x61, state->reg_61);
- } else {
- v4l2_dbg(1, debug, sd, "Disable Video Output\n");
- saa7127_write(sd, 0x2d, (state->reg_2d & 0xf0));
- saa7127_write(sd, 0x61, (state->reg_61 | 0xc0));
- }
- state->video_enable = enable;
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct saa7127_state *state = to_state(sd);
- const struct i2c_reg_value *inittab;
-
- if (std & V4L2_STD_525_60) {
- v4l2_dbg(1, debug, sd, "Selecting 60 Hz video Standard\n");
- inittab = saa7127_init_config_60hz;
- state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
-
- } else if (state->ident == V4L2_IDENT_SAA7129 &&
- (std & V4L2_STD_SECAM) &&
- !(std & (V4L2_STD_625_50 & ~V4L2_STD_SECAM))) {
-
- /* If and only if SECAM, with a SAA712[89] */
- v4l2_dbg(1, debug, sd,
- "Selecting 50 Hz SECAM video Standard\n");
- inittab = saa7127_init_config_50hz_secam;
- state->reg_61 = SAA7127_50HZ_SECAM_DAC_CONTROL;
-
- } else {
- v4l2_dbg(1, debug, sd, "Selecting 50 Hz PAL video Standard\n");
- inittab = saa7127_init_config_50hz_pal;
- state->reg_61 = SAA7127_50HZ_PAL_DAC_CONTROL;
- }
-
- /* Write Table */
- saa7127_write_inittab(sd, inittab);
- state->std = std;
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_output_type(struct v4l2_subdev *sd, int output)
-{
- struct saa7127_state *state = to_state(sd);
-
- switch (output) {
- case SAA7127_OUTPUT_TYPE_RGB:
- state->reg_2d = 0x0f; /* RGB + CVBS (for sync) */
- state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
- break;
-
- case SAA7127_OUTPUT_TYPE_COMPOSITE:
- if (state->ident == V4L2_IDENT_SAA7129)
- state->reg_2d = 0x20; /* CVBS only */
- else
- state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
- state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
- break;
-
- case SAA7127_OUTPUT_TYPE_SVIDEO:
- if (state->ident == V4L2_IDENT_SAA7129)
- state->reg_2d = 0x18; /* Y + C */
- else
- state->reg_2d = 0xff; /*11111111 croma -> R, luma -> CVBS + G + B */
- state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
- break;
-
- case SAA7127_OUTPUT_TYPE_YUV_V:
- state->reg_2d = 0x4f; /* reg 2D = 01001111, all DAC's on, RGB + VBS */
- state->reg_3a = 0x0b; /* reg 3A = 00001011, bypass RGB-matrix */
- break;
-
- case SAA7127_OUTPUT_TYPE_YUV_C:
- state->reg_2d = 0x0f; /* reg 2D = 00001111, all DAC's on, RGB + CVBS */
- state->reg_3a = 0x0b; /* reg 3A = 00001011, bypass RGB-matrix */
- break;
-
- case SAA7127_OUTPUT_TYPE_BOTH:
- if (state->ident == V4L2_IDENT_SAA7129)
- state->reg_2d = 0x38;
- else
- state->reg_2d = 0xbf;
- state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
- break;
-
- default:
- return -EINVAL;
- }
- v4l2_dbg(1, debug, sd,
- "Selecting %s output type\n", output_strs[output]);
-
- /* Configure Encoder */
- saa7127_write(sd, 0x2d, state->reg_2d);
- saa7127_write(sd, 0x3a, state->reg_3a | state->reg_3a_cb);
- state->output_type = output;
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_input_type(struct v4l2_subdev *sd, int input)
-{
- struct saa7127_state *state = to_state(sd);
-
- switch (input) {
- case SAA7127_INPUT_TYPE_NORMAL: /* avia */
- v4l2_dbg(1, debug, sd, "Selecting Normal Encoder Input\n");
- state->reg_3a_cb = 0;
- break;
-
- case SAA7127_INPUT_TYPE_TEST_IMAGE: /* color bar */
- v4l2_dbg(1, debug, sd, "Selecting Color Bar generator\n");
- state->reg_3a_cb = 0x80;
- break;
-
- default:
- return -EINVAL;
- }
- saa7127_write(sd, 0x3a, state->reg_3a | state->reg_3a_cb);
- state->input_type = input;
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct saa7127_state *state = to_state(sd);
-
- if (state->std == std)
- return 0;
- return saa7127_set_std(sd, std);
-}
-
-static int saa7127_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct saa7127_state *state = to_state(sd);
- int rc = 0;
-
- if (state->input_type != input)
- rc = saa7127_set_input_type(sd, input);
- if (rc == 0 && state->output_type != output)
- rc = saa7127_set_output_type(sd, output);
- return rc;
-}
-
-static int saa7127_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct saa7127_state *state = to_state(sd);
-
- if (state->video_enable == enable)
- return 0;
- return saa7127_set_video_enable(sd, enable);
-}
-
-static int saa7127_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
-{
- struct saa7127_state *state = to_state(sd);
-
- memset(fmt, 0, sizeof(*fmt));
- if (state->vps_enable)
- fmt->service_lines[0][16] = V4L2_SLICED_VPS;
- if (state->wss_enable)
- fmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
- if (state->cc_enable) {
- fmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
- fmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
- }
- fmt->service_set =
- (state->vps_enable ? V4L2_SLICED_VPS : 0) |
- (state->wss_enable ? V4L2_SLICED_WSS_625 : 0) |
- (state->cc_enable ? V4L2_SLICED_CAPTION_525 : 0);
- return 0;
-}
-
-static int saa7127_s_vbi_data(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data)
-{
- switch (data->id) {
- case V4L2_SLICED_WSS_625:
- return saa7127_set_wss(sd, data);
- case V4L2_SLICED_VPS:
- return saa7127_set_vps(sd, data);
- case V4L2_SLICED_CAPTION_525:
- if (data->field == 0)
- return saa7127_set_cc(sd, data);
- return saa7127_set_xds(sd, data);
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int saa7127_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- reg->val = saa7127_read(sd, reg->reg & 0xff);
- reg->size = 1;
- return 0;
-}
-
-static int saa7127_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- saa7127_write(sd, reg->reg & 0xff, reg->val & 0xff);
- return 0;
-}
-#endif
-
-static int saa7127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct saa7127_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, state->ident, 0);
-}
-
-static int saa7127_log_status(struct v4l2_subdev *sd)
-{
- struct saa7127_state *state = to_state(sd);
-
- v4l2_info(sd, "Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz");
- v4l2_info(sd, "Input: %s\n", state->input_type ? "color bars" : "normal");
- v4l2_info(sd, "Output: %s\n", state->video_enable ?
- output_strs[state->output_type] : "disabled");
- v4l2_info(sd, "WSS: %s\n", state->wss_enable ?
- wss_strs[state->wss_mode] : "disabled");
- v4l2_info(sd, "VPS: %s\n", state->vps_enable ? "enabled" : "disabled");
- v4l2_info(sd, "CC: %s\n", state->cc_enable ? "enabled" : "disabled");
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops saa7127_core_ops = {
- .log_status = saa7127_log_status,
- .g_chip_ident = saa7127_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = saa7127_g_register,
- .s_register = saa7127_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_video_ops saa7127_video_ops = {
- .s_std_output = saa7127_s_std_output,
- .s_routing = saa7127_s_routing,
- .s_stream = saa7127_s_stream,
-};
-
-static const struct v4l2_subdev_vbi_ops saa7127_vbi_ops = {
- .s_vbi_data = saa7127_s_vbi_data,
- .g_sliced_fmt = saa7127_g_sliced_fmt,
-};
-
-static const struct v4l2_subdev_ops saa7127_ops = {
- .core = &saa7127_core_ops,
- .video = &saa7127_video_ops,
- .vbi = &saa7127_vbi_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct saa7127_state *state;
- struct v4l2_subdev *sd;
- struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 }; /* set to disabled */
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- v4l_dbg(1, debug, client, "detecting saa7127 client on address 0x%x\n",
- client->addr << 1);
-
- state = kzalloc(sizeof(struct saa7127_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
-
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &saa7127_ops);
-
- /* First test register 0: Bits 5-7 are a version ID (should be 0),
- and bit 2 should also be 0.
- This is rather general, so the second test is more specific and
- looks at the 'ending point of burst in clock cycles' which is
- 0x1d after a reset and not expected to ever change. */
- if ((saa7127_read(sd, 0) & 0xe4) != 0 ||
- (saa7127_read(sd, 0x29) & 0x3f) != 0x1d) {
- v4l2_dbg(1, debug, sd, "saa7127 not found\n");
- kfree(state);
- return -ENODEV;
- }
-
- if (id->driver_data) { /* Chip type is already known */
- state->ident = id->driver_data;
- } else { /* Needs detection */
- int read_result;
-
- /* Detect if it's an saa7129 */
- read_result = saa7127_read(sd, SAA7129_REG_FADE_KEY_COL2);
- saa7127_write(sd, SAA7129_REG_FADE_KEY_COL2, 0xaa);
- if (saa7127_read(sd, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
- saa7127_write(sd, SAA7129_REG_FADE_KEY_COL2,
- read_result);
- state->ident = V4L2_IDENT_SAA7129;
- strlcpy(client->name, "saa7129", I2C_NAME_SIZE);
- } else {
- state->ident = V4L2_IDENT_SAA7127;
- strlcpy(client->name, "saa7127", I2C_NAME_SIZE);
- }
- }
-
- v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
- client->addr << 1, client->adapter->name);
-
- v4l2_dbg(1, debug, sd, "Configuring encoder\n");
- saa7127_write_inittab(sd, saa7127_init_config_common);
- saa7127_set_std(sd, V4L2_STD_NTSC);
- saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH);
- saa7127_set_vps(sd, &vbi);
- saa7127_set_wss(sd, &vbi);
- saa7127_set_cc(sd, &vbi);
- saa7127_set_xds(sd, &vbi);
- if (test_image == 1)
- /* The Encoder has an internal Colorbar generator */
- /* This can be used for debugging */
- saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE);
- else
- saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
- saa7127_set_video_enable(sd, 1);
-
- if (state->ident == V4L2_IDENT_SAA7129)
- saa7127_write_inittab(sd, saa7129_init_config_extra);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- /* Turn off TV output */
- saa7127_set_video_enable(sd, 0);
- kfree(to_state(sd));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static struct i2c_device_id saa7127_id[] = {
- { "saa7127_auto", 0 }, /* auto-detection */
- { "saa7126", V4L2_IDENT_SAA7127 },
- { "saa7127", V4L2_IDENT_SAA7127 },
- { "saa7128", V4L2_IDENT_SAA7129 },
- { "saa7129", V4L2_IDENT_SAA7129 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, saa7127_id);
-
-static struct i2c_driver saa7127_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "saa7127",
- },
- .probe = saa7127_probe,
- .remove = saa7127_remove,
- .id_table = saa7127_id,
-};
-
-module_i2c_driver(saa7127_driver);
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
deleted file mode 100644
index 39fc0187a74..00000000000
--- a/drivers/media/video/saa7134/Kconfig
+++ /dev/null
@@ -1,64 +0,0 @@
-config VIDEO_SAA7134
- tristate "Philips SAA7134 support"
- depends on VIDEO_DEV && PCI && I2C
- select VIDEOBUF_DMA_SG
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- select CRC32
- select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO
- ---help---
- This is a video4linux driver for Philips SAA713x based
- TV cards.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7134.
-
-config VIDEO_SAA7134_ALSA
- tristate "Philips SAA7134 DMA audio support"
- depends on VIDEO_SAA7134 && SND
- select SND_PCM
- ---help---
- This is a video4linux driver for direct (DMA) audio in
- Philips SAA713x based TV cards using ALSA
-
- To compile this driver as a module, choose M here: the
- module will be called saa7134-alsa.
-
-config VIDEO_SAA7134_RC
- bool "Philips SAA7134 Remote Controller support"
- depends on RC_CORE
- depends on VIDEO_SAA7134
- depends on !(RC_CORE=m && VIDEO_SAA7134=y)
- default y
- ---help---
- Enables Remote Controller support on saa7134 driver.
-
-config VIDEO_SAA7134_DVB
- tristate "DVB/ATSC Support for saa7134 based TV cards"
- depends on VIDEO_SAA7134 && DVB_CORE
- select VIDEOBUF_DVB
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select DVB_MT352 if !DVB_FE_CUSTOMISE
- select DVB_TDA1004X if !DVB_FE_CUSTOMISE
- select DVB_NXT200X if !DVB_FE_CUSTOMISE
- select DVB_TDA10086 if !DVB_FE_CUSTOMISE
- select DVB_TDA826X if !DVB_FE_CUSTOMISE
- select DVB_ISL6421 if !DVB_FE_CUSTOMISE
- select DVB_ISL6405 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
- select DVB_ZL10036 if !DVB_FE_CUSTOMISE
- select DVB_MT312 if !DVB_FE_CUSTOMISE
- select DVB_LNBP21 if !DVB_FE_CUSTOMISE
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
- select DVB_TDA10048 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
- select DVB_ZL10039 if !DVB_FE_CUSTOMISE
- ---help---
- This adds support for DVB cards based on the
- Philips saa7134 chip.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7134-dvb.
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
deleted file mode 100644
index da3899329f5..00000000000
--- a/drivers/media/video/saa7134/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-
-saa7134-y := saa7134-cards.o saa7134-core.o saa7134-i2c.o
-saa7134-y += saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o
-saa7134-y += saa7134-video.o
-saa7134-$(CONFIG_VIDEO_SAA7134_RC) += saa7134-input.o
-
-obj-$(CONFIG_VIDEO_SAA7134) += saa6752hs.o saa7134.o saa7134-empress.o
-
-obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o
-
-obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
-
-ccflags-y += -I$(srctree)/drivers/media/video
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
-ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
deleted file mode 100644
index f147b05bd86..00000000000
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ /dev/null
@@ -1,1012 +0,0 @@
- /*
- saa6752hs - i2c-driver for the saa6752hs by Philips
-
- Copyright (C) 2004 Andrew de Quincey
-
- AC-3 support:
-
- Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License vs published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mvss Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/i2c.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-#include <linux/init.h>
-#include <linux/crc32.h>
-
-#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000
-#define MPEG_VIDEO_MAX_BITRATE_MAX 27000
-#define MPEG_TOTAL_TARGET_BITRATE_MAX 27000
-#define MPEG_PID_MAX ((1 << 14) - 1)
-
-
-MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder");
-MODULE_AUTHOR("Andrew de Quincey");
-MODULE_LICENSE("GPL");
-
-enum saa6752hs_videoformat {
- SAA6752HS_VF_D1 = 0, /* standard D1 video format: 720x576 */
- SAA6752HS_VF_2_3_D1 = 1,/* 2/3D1 video format: 480x576 */
- SAA6752HS_VF_1_2_D1 = 2,/* 1/2D1 video format: 352x576 */
- SAA6752HS_VF_SIF = 3, /* SIF video format: 352x288 */
- SAA6752HS_VF_UNKNOWN,
-};
-
-struct saa6752hs_mpeg_params {
- /* transport streams */
- __u16 ts_pid_pmt;
- __u16 ts_pid_audio;
- __u16 ts_pid_video;
- __u16 ts_pid_pcr;
-
- /* audio */
- enum v4l2_mpeg_audio_encoding au_encoding;
- enum v4l2_mpeg_audio_l2_bitrate au_l2_bitrate;
- enum v4l2_mpeg_audio_ac3_bitrate au_ac3_bitrate;
-
- /* video */
- enum v4l2_mpeg_video_aspect vi_aspect;
- enum v4l2_mpeg_video_bitrate_mode vi_bitrate_mode;
- __u32 vi_bitrate;
- __u32 vi_bitrate_peak;
-};
-
-static const struct v4l2_format v4l2_format_table[] =
-{
- [SAA6752HS_VF_D1] =
- { .fmt = { .pix = { .width = 720, .height = 576 }}},
- [SAA6752HS_VF_2_3_D1] =
- { .fmt = { .pix = { .width = 480, .height = 576 }}},
- [SAA6752HS_VF_1_2_D1] =
- { .fmt = { .pix = { .width = 352, .height = 576 }}},
- [SAA6752HS_VF_SIF] =
- { .fmt = { .pix = { .width = 352, .height = 288 }}},
- [SAA6752HS_VF_UNKNOWN] =
- { .fmt = { .pix = { .width = 0, .height = 0}}},
-};
-
-struct saa6752hs_state {
- struct v4l2_subdev sd;
- int chip;
- u32 revision;
- int has_ac3;
- struct saa6752hs_mpeg_params params;
- enum saa6752hs_videoformat video_format;
- v4l2_std_id standard;
-};
-
-enum saa6752hs_command {
- SAA6752HS_COMMAND_RESET = 0,
- SAA6752HS_COMMAND_STOP = 1,
- SAA6752HS_COMMAND_START = 2,
- SAA6752HS_COMMAND_PAUSE = 3,
- SAA6752HS_COMMAND_RECONFIGURE = 4,
- SAA6752HS_COMMAND_SLEEP = 5,
- SAA6752HS_COMMAND_RECONFIGURE_FORCE = 6,
-
- SAA6752HS_COMMAND_MAX
-};
-
-static inline struct saa6752hs_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct saa6752hs_state, sd);
-}
-
-/* ---------------------------------------------------------------------- */
-
-static u8 PAT[] = {
- 0xc2, /* i2c register */
- 0x00, /* table number for encoder */
-
- 0x47, /* sync */
- 0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) */
- 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
-
- 0x00, /* PSI pointer to start of table */
-
- 0x00, /* tid(0) */
- 0xb0, 0x0d, /* section_syntax_indicator(1), section_length(13) */
-
- 0x00, 0x01, /* transport_stream_id(1) */
-
- 0xc1, /* version_number(0), current_next_indicator(1) */
-
- 0x00, 0x00, /* section_number(0), last_section_number(0) */
-
- 0x00, 0x01, /* program_number(1) */
-
- 0xe0, 0x00, /* PMT PID */
-
- 0x00, 0x00, 0x00, 0x00 /* CRC32 */
-};
-
-static u8 PMT[] = {
- 0xc2, /* i2c register */
- 0x01, /* table number for encoder */
-
- 0x47, /* sync */
- 0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid */
- 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
-
- 0x00, /* PSI pointer to start of table */
-
- 0x02, /* tid(2) */
- 0xb0, 0x17, /* section_syntax_indicator(1), section_length(23) */
-
- 0x00, 0x01, /* program_number(1) */
-
- 0xc1, /* version_number(0), current_next_indicator(1) */
-
- 0x00, 0x00, /* section_number(0), last_section_number(0) */
-
- 0xe0, 0x00, /* PCR_PID */
-
- 0xf0, 0x00, /* program_info_length(0) */
-
- 0x02, 0xe0, 0x00, 0xf0, 0x00, /* video stream type(2), pid */
- 0x04, 0xe0, 0x00, 0xf0, 0x00, /* audio stream type(4), pid */
-
- 0x00, 0x00, 0x00, 0x00 /* CRC32 */
-};
-
-static u8 PMT_AC3[] = {
- 0xc2, /* i2c register */
- 0x01, /* table number for encoder(1) */
- 0x47, /* sync */
-
- 0x40, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0) */
- 0x10, /* PMT PID (0x0010) */
- 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
-
- 0x00, /* PSI pointer to start of table */
-
- 0x02, /* TID (2) */
- 0xb0, 0x1a, /* section_syntax_indicator(1), section_length(26) */
-
- 0x00, 0x01, /* program_number(1) */
-
- 0xc1, /* version_number(0), current_next_indicator(1) */
-
- 0x00, 0x00, /* section_number(0), last_section_number(0) */
-
- 0xe1, 0x04, /* PCR_PID (0x0104) */
-
- 0xf0, 0x00, /* program_info_length(0) */
-
- 0x02, 0xe1, 0x00, 0xf0, 0x00, /* video stream type(2), pid */
- 0x06, 0xe1, 0x03, 0xf0, 0x03, /* audio stream type(6), pid */
- 0x6a, /* AC3 */
- 0x01, /* Descriptor_length(1) */
- 0x00, /* component_type_flag(0), bsid_flag(0), mainid_flag(0), asvc_flag(0), reserved flags(0) */
-
- 0xED, 0xDE, 0x2D, 0xF3 /* CRC32 BE */
-};
-
-static struct saa6752hs_mpeg_params param_defaults =
-{
- .ts_pid_pmt = 16,
- .ts_pid_video = 260,
- .ts_pid_audio = 256,
- .ts_pid_pcr = 259,
-
- .vi_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
- .vi_bitrate = 4000,
- .vi_bitrate_peak = 6000,
- .vi_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
-
- .au_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
- .au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K,
- .au_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_256K,
-};
-
-/* ---------------------------------------------------------------------- */
-
-static int saa6752hs_chip_command(struct i2c_client *client,
- enum saa6752hs_command command)
-{
- unsigned char buf[3];
- unsigned long timeout;
- int status = 0;
-
- /* execute the command */
- switch(command) {
- case SAA6752HS_COMMAND_RESET:
- buf[0] = 0x00;
- break;
-
- case SAA6752HS_COMMAND_STOP:
- buf[0] = 0x03;
- break;
-
- case SAA6752HS_COMMAND_START:
- buf[0] = 0x02;
- break;
-
- case SAA6752HS_COMMAND_PAUSE:
- buf[0] = 0x04;
- break;
-
- case SAA6752HS_COMMAND_RECONFIGURE:
- buf[0] = 0x05;
- break;
-
- case SAA6752HS_COMMAND_SLEEP:
- buf[0] = 0x06;
- break;
-
- case SAA6752HS_COMMAND_RECONFIGURE_FORCE:
- buf[0] = 0x07;
- break;
-
- default:
- return -EINVAL;
- }
-
- /* set it and wait for it to be so */
- i2c_master_send(client, buf, 1);
- timeout = jiffies + HZ * 3;
- for (;;) {
- /* get the current status */
- buf[0] = 0x10;
- i2c_master_send(client, buf, 1);
- i2c_master_recv(client, buf, 1);
-
- if (!(buf[0] & 0x20))
- break;
- if (time_after(jiffies,timeout)) {
- status = -ETIMEDOUT;
- break;
- }
-
- msleep(10);
- }
-
- /* delay a bit to let encoder settle */
- msleep(50);
-
- return status;
-}
-
-
-static inline void set_reg8(struct i2c_client *client, uint8_t reg, uint8_t val)
-{
- u8 buf[2];
-
- buf[0] = reg;
- buf[1] = val;
- i2c_master_send(client, buf, 2);
-}
-
-static inline void set_reg16(struct i2c_client *client, uint8_t reg, uint16_t val)
-{
- u8 buf[3];
-
- buf[0] = reg;
- buf[1] = val >> 8;
- buf[2] = val & 0xff;
- i2c_master_send(client, buf, 3);
-}
-
-static int saa6752hs_set_bitrate(struct i2c_client *client,
- struct saa6752hs_state *h)
-{
- struct saa6752hs_mpeg_params *params = &h->params;
- int tot_bitrate;
- int is_384k;
-
- /* set the bitrate mode */
- set_reg8(client, 0x71,
- params->vi_bitrate_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
-
- /* set the video bitrate */
- if (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) {
- /* set the target bitrate */
- set_reg16(client, 0x80, params->vi_bitrate);
-
- /* set the max bitrate */
- set_reg16(client, 0x81, params->vi_bitrate_peak);
- tot_bitrate = params->vi_bitrate_peak;
- } else {
- /* set the target bitrate (no max bitrate for CBR) */
- set_reg16(client, 0x81, params->vi_bitrate);
- tot_bitrate = params->vi_bitrate;
- }
-
- /* set the audio encoding */
- set_reg8(client, 0x93,
- params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3);
-
- /* set the audio bitrate */
- if (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3)
- is_384k = V4L2_MPEG_AUDIO_AC3_BITRATE_384K == params->au_ac3_bitrate;
- else
- is_384k = V4L2_MPEG_AUDIO_L2_BITRATE_384K == params->au_l2_bitrate;
- set_reg8(client, 0x94, is_384k);
- tot_bitrate += is_384k ? 384 : 256;
-
- /* Note: the total max bitrate is determined by adding the video and audio
- bitrates together and also adding an extra 768kbit/s to stay on the
- safe side. If more control should be required, then an extra MPEG control
- should be added. */
- tot_bitrate += 768;
- if (tot_bitrate > MPEG_TOTAL_TARGET_BITRATE_MAX)
- tot_bitrate = MPEG_TOTAL_TARGET_BITRATE_MAX;
-
- /* set the total bitrate */
- set_reg16(client, 0xb1, tot_bitrate);
- return 0;
-}
-
-
-static int get_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
- struct v4l2_ext_control *ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_MPEG_STREAM_TYPE:
- ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
- break;
- case V4L2_CID_MPEG_STREAM_PID_PMT:
- ctrl->value = params->ts_pid_pmt;
- break;
- case V4L2_CID_MPEG_STREAM_PID_AUDIO:
- ctrl->value = params->ts_pid_audio;
- break;
- case V4L2_CID_MPEG_STREAM_PID_VIDEO:
- ctrl->value = params->ts_pid_video;
- break;
- case V4L2_CID_MPEG_STREAM_PID_PCR:
- ctrl->value = params->ts_pid_pcr;
- break;
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- ctrl->value = params->au_encoding;
- break;
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- ctrl->value = params->au_l2_bitrate;
- break;
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- if (!has_ac3)
- return -EINVAL;
- ctrl->value = params->au_ac3_bitrate;
- break;
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- ctrl->value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
- break;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- ctrl->value = params->vi_aspect;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- ctrl->value = params->vi_bitrate * 1000;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- ctrl->value = params->vi_bitrate_peak * 1000;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- ctrl->value = params->vi_bitrate_mode;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
- struct v4l2_ext_control *ctrl, int set)
-{
- int old = 0, new;
-
- new = ctrl->value;
- switch (ctrl->id) {
- case V4L2_CID_MPEG_STREAM_TYPE:
- old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_STREAM_PID_PMT:
- old = params->ts_pid_pmt;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_pmt = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_AUDIO:
- old = params->ts_pid_audio;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_audio = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_VIDEO:
- old = params->ts_pid_video;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_video = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_PCR:
- old = params->ts_pid_pcr;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_pcr = new;
- break;
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- old = params->au_encoding;
- if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
- (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
- return -ERANGE;
- params->au_encoding = new;
- break;
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- old = params->au_l2_bitrate;
- if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K &&
- new != V4L2_MPEG_AUDIO_L2_BITRATE_384K)
- return -ERANGE;
- if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K)
- new = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
- else
- new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
- params->au_l2_bitrate = new;
- break;
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- if (!has_ac3)
- return -EINVAL;
- old = params->au_ac3_bitrate;
- if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
- new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
- return -ERANGE;
- if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
- new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
- else
- new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
- params->au_ac3_bitrate = new;
- break;
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- old = params->vi_aspect;
- if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
- new != V4L2_MPEG_VIDEO_ASPECT_4x3)
- return -ERANGE;
- if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
- new = V4L2_MPEG_VIDEO_ASPECT_4x3;
- params->vi_aspect = new;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- old = params->vi_bitrate * 1000;
- new = 1000 * (new / 1000);
- if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- return -ERANGE;
- if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
- params->vi_bitrate = new / 1000;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- old = params->vi_bitrate_peak * 1000;
- new = 1000 * (new / 1000);
- if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- return -ERANGE;
- if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
- params->vi_bitrate_peak = new / 1000;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- old = params->vi_bitrate_mode;
- params->vi_bitrate_mode = new;
- break;
- default:
- return -EINVAL;
- }
- ctrl->value = new;
- return 0;
-}
-
-
-static int saa6752hs_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
-{
- struct saa6752hs_state *h = to_state(sd);
- struct saa6752hs_mpeg_params *params = &h->params;
- int err;
-
- switch (qctrl->id) {
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
- h->has_ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 :
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
- 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
-
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_L2_BITRATE_256K,
- V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
- V4L2_MPEG_AUDIO_L2_BITRATE_256K);
-
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- if (!h->has_ac3)
- return -EINVAL;
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_AC3_BITRATE_256K,
- V4L2_MPEG_AUDIO_AC3_BITRATE_384K, 1,
- V4L2_MPEG_AUDIO_AC3_BITRATE_256K);
-
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, 1,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
-
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
-
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_ASPECT_4x3,
- V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
- V4L2_MPEG_VIDEO_ASPECT_4x3);
-
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
- if (err == 0 &&
- params->vi_bitrate_mode ==
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return err;
-
- case V4L2_CID_MPEG_STREAM_TYPE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
- V4L2_MPEG_STREAM_TYPE_MPEG2_TS, 1,
- V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
-
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
- case V4L2_CID_MPEG_STREAM_PID_PMT:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16);
- case V4L2_CID_MPEG_STREAM_PID_AUDIO:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260);
- case V4L2_CID_MPEG_STREAM_PID_VIDEO:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256);
- case V4L2_CID_MPEG_STREAM_PID_PCR:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259);
-
- default:
- break;
- }
- return -EINVAL;
-}
-
-static int saa6752hs_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qmenu)
-{
- static const u32 mpeg_audio_encoding[] = {
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
- V4L2_CTRL_MENU_IDS_END
- };
- static const u32 mpeg_audio_ac3_encoding[] = {
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
- V4L2_MPEG_AUDIO_ENCODING_AC3,
- V4L2_CTRL_MENU_IDS_END
- };
- static u32 mpeg_audio_l2_bitrate[] = {
- V4L2_MPEG_AUDIO_L2_BITRATE_256K,
- V4L2_MPEG_AUDIO_L2_BITRATE_384K,
- V4L2_CTRL_MENU_IDS_END
- };
- static u32 mpeg_audio_ac3_bitrate[] = {
- V4L2_MPEG_AUDIO_AC3_BITRATE_256K,
- V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
- V4L2_CTRL_MENU_IDS_END
- };
- struct saa6752hs_state *h = to_state(sd);
- struct v4l2_queryctrl qctrl;
- int err;
-
- qctrl.id = qmenu->id;
- err = saa6752hs_queryctrl(sd, &qctrl);
- if (err)
- return err;
- switch (qmenu->id) {
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- return v4l2_ctrl_query_menu_valid_items(qmenu,
- mpeg_audio_l2_bitrate);
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- if (!h->has_ac3)
- return -EINVAL;
- return v4l2_ctrl_query_menu_valid_items(qmenu,
- mpeg_audio_ac3_bitrate);
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- return v4l2_ctrl_query_menu_valid_items(qmenu,
- h->has_ac3 ? mpeg_audio_ac3_encoding :
- mpeg_audio_encoding);
- }
- return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL);
-}
-
-static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes)
-{
- unsigned char buf[9], buf2[4];
- struct saa6752hs_state *h = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- unsigned size;
- u32 crc;
- unsigned char localPAT[256];
- unsigned char localPMT[256];
-
- /* Set video format - must be done first as it resets other settings */
- set_reg8(client, 0x41, h->video_format);
-
- /* Set number of lines in input signal */
- set_reg8(client, 0x40, (h->standard & V4L2_STD_525_60) ? 1 : 0);
-
- /* set bitrate */
- saa6752hs_set_bitrate(client, h);
-
- /* Set GOP structure {3, 13} */
- set_reg16(client, 0x72, 0x030d);
-
- /* Set minimum Q-scale {4} */
- set_reg8(client, 0x82, 0x04);
-
- /* Set maximum Q-scale {12} */
- set_reg8(client, 0x83, 0x0c);
-
- /* Set Output Protocol */
- set_reg8(client, 0xd0, 0x81);
-
- /* Set video output stream format {TS} */
- set_reg8(client, 0xb0, 0x05);
-
- /* Set leading null byte for TS */
- set_reg16(client, 0xf6, leading_null_bytes);
-
- /* compute PAT */
- memcpy(localPAT, PAT, sizeof(PAT));
- localPAT[17] = 0xe0 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
- localPAT[18] = h->params.ts_pid_pmt & 0xff;
- crc = crc32_be(~0, &localPAT[7], sizeof(PAT) - 7 - 4);
- localPAT[sizeof(PAT) - 4] = (crc >> 24) & 0xFF;
- localPAT[sizeof(PAT) - 3] = (crc >> 16) & 0xFF;
- localPAT[sizeof(PAT) - 2] = (crc >> 8) & 0xFF;
- localPAT[sizeof(PAT) - 1] = crc & 0xFF;
-
- /* compute PMT */
- if (h->params.au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) {
- size = sizeof(PMT_AC3);
- memcpy(localPMT, PMT_AC3, size);
- } else {
- size = sizeof(PMT);
- memcpy(localPMT, PMT, size);
- }
- localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
- localPMT[4] = h->params.ts_pid_pmt & 0xff;
- localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F);
- localPMT[16] = h->params.ts_pid_pcr & 0xFF;
- localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F);
- localPMT[21] = h->params.ts_pid_video & 0xFF;
- localPMT[25] = 0xE0 | ((h->params.ts_pid_audio >> 8) & 0x0F);
- localPMT[26] = h->params.ts_pid_audio & 0xFF;
- crc = crc32_be(~0, &localPMT[7], size - 7 - 4);
- localPMT[size - 4] = (crc >> 24) & 0xFF;
- localPMT[size - 3] = (crc >> 16) & 0xFF;
- localPMT[size - 2] = (crc >> 8) & 0xFF;
- localPMT[size - 1] = crc & 0xFF;
-
- /* Set Audio PID */
- set_reg16(client, 0xc1, h->params.ts_pid_audio);
-
- /* Set Video PID */
- set_reg16(client, 0xc0, h->params.ts_pid_video);
-
- /* Set PCR PID */
- set_reg16(client, 0xc4, h->params.ts_pid_pcr);
-
- /* Send SI tables */
- i2c_master_send(client, localPAT, sizeof(PAT));
- i2c_master_send(client, localPMT, size);
-
- /* mute then unmute audio. This removes buzzing artefacts */
- set_reg8(client, 0xa4, 1);
- set_reg8(client, 0xa4, 0);
-
- /* start it going */
- saa6752hs_chip_command(client, SAA6752HS_COMMAND_START);
-
- /* readout current state */
- buf[0] = 0xE1;
- buf[1] = 0xA7;
- buf[2] = 0xFE;
- buf[3] = 0x82;
- buf[4] = 0xB0;
- i2c_master_send(client, buf, 5);
- i2c_master_recv(client, buf2, 4);
-
- /* change aspect ratio */
- buf[0] = 0xE0;
- buf[1] = 0xA7;
- buf[2] = 0xFE;
- buf[3] = 0x82;
- buf[4] = 0xB0;
- buf[5] = buf2[0];
- switch (h->params.vi_aspect) {
- case V4L2_MPEG_VIDEO_ASPECT_16x9:
- buf[6] = buf2[1] | 0x40;
- break;
- case V4L2_MPEG_VIDEO_ASPECT_4x3:
- default:
- buf[6] = buf2[1] & 0xBF;
- break;
- }
- buf[7] = buf2[2];
- buf[8] = buf2[3];
- i2c_master_send(client, buf, 9);
-
- return 0;
-}
-
-static int saa6752hs_do_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls, int set)
-{
- struct saa6752hs_state *h = to_state(sd);
- struct saa6752hs_mpeg_params params;
- int i;
-
- if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
-
- params = h->params;
- for (i = 0; i < ctrls->count; i++) {
- int err = handle_ctrl(h->has_ac3, &params, ctrls->controls + i, set);
-
- if (err) {
- ctrls->error_idx = i;
- return err;
- }
- }
- if (set)
- h->params = params;
- return 0;
-}
-
-static int saa6752hs_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
-{
- return saa6752hs_do_ext_ctrls(sd, ctrls, 1);
-}
-
-static int saa6752hs_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
-{
- return saa6752hs_do_ext_ctrls(sd, ctrls, 0);
-}
-
-static int saa6752hs_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
-{
- struct saa6752hs_state *h = to_state(sd);
- int i;
-
- if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
-
- for (i = 0; i < ctrls->count; i++) {
- int err = get_ctrl(h->has_ac3, &h->params, ctrls->controls + i);
-
- if (err) {
- ctrls->error_idx = i;
- return err;
- }
- }
- return 0;
-}
-
-static int saa6752hs_g_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
-{
- struct saa6752hs_state *h = to_state(sd);
-
- if (h->video_format == SAA6752HS_VF_UNKNOWN)
- h->video_format = SAA6752HS_VF_D1;
- f->width = v4l2_format_table[h->video_format].fmt.pix.width;
- f->height = v4l2_format_table[h->video_format].fmt.pix.height;
- f->code = V4L2_MBUS_FMT_FIXED;
- f->field = V4L2_FIELD_INTERLACED;
- f->colorspace = V4L2_COLORSPACE_SMPTE170M;
- return 0;
-}
-
-static int saa6752hs_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
-{
- struct saa6752hs_state *h = to_state(sd);
- int dist_352, dist_480, dist_720;
-
- if (f->code != V4L2_MBUS_FMT_FIXED)
- return -EINVAL;
-
- /*
- FIXME: translate and round width/height into EMPRESS
- subsample type:
-
- type | PAL | NTSC
- ---------------------------
- SIF | 352x288 | 352x240
- 1/2 D1 | 352x576 | 352x480
- 2/3 D1 | 480x576 | 480x480
- D1 | 720x576 | 720x480
- */
-
- dist_352 = abs(f->width - 352);
- dist_480 = abs(f->width - 480);
- dist_720 = abs(f->width - 720);
- if (dist_720 < dist_480) {
- f->width = 720;
- f->height = 576;
- h->video_format = SAA6752HS_VF_D1;
- } else if (dist_480 < dist_352) {
- f->width = 480;
- f->height = 576;
- h->video_format = SAA6752HS_VF_2_3_D1;
- } else {
- f->width = 352;
- if (abs(f->height - 576) <
- abs(f->height - 288)) {
- f->height = 576;
- h->video_format = SAA6752HS_VF_1_2_D1;
- } else {
- f->height = 288;
- h->video_format = SAA6752HS_VF_SIF;
- }
- }
- f->field = V4L2_FIELD_INTERLACED;
- f->colorspace = V4L2_COLORSPACE_SMPTE170M;
- return 0;
-}
-
-static int saa6752hs_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct saa6752hs_state *h = to_state(sd);
-
- h->standard = std;
- return 0;
-}
-
-static int saa6752hs_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct saa6752hs_state *h = to_state(sd);
-
- return v4l2_chip_ident_i2c_client(client,
- chip, h->chip, h->revision);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
- .g_chip_ident = saa6752hs_g_chip_ident,
- .init = saa6752hs_init,
- .queryctrl = saa6752hs_queryctrl,
- .querymenu = saa6752hs_querymenu,
- .g_ext_ctrls = saa6752hs_g_ext_ctrls,
- .s_ext_ctrls = saa6752hs_s_ext_ctrls,
- .try_ext_ctrls = saa6752hs_try_ext_ctrls,
- .s_std = saa6752hs_s_std,
-};
-
-static const struct v4l2_subdev_video_ops saa6752hs_video_ops = {
- .s_mbus_fmt = saa6752hs_s_mbus_fmt,
- .g_mbus_fmt = saa6752hs_g_mbus_fmt,
-};
-
-static const struct v4l2_subdev_ops saa6752hs_ops = {
- .core = &saa6752hs_core_ops,
- .video = &saa6752hs_video_ops,
-};
-
-static int saa6752hs_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL);
- struct v4l2_subdev *sd;
- u8 addr = 0x13;
- u8 data[12];
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
- if (h == NULL)
- return -ENOMEM;
- sd = &h->sd;
- v4l2_i2c_subdev_init(sd, client, &saa6752hs_ops);
-
- i2c_master_send(client, &addr, 1);
- i2c_master_recv(client, data, sizeof(data));
- h->chip = V4L2_IDENT_SAA6752HS;
- h->revision = (data[8] << 8) | data[9];
- h->has_ac3 = 0;
- if (h->revision == 0x0206) {
- h->chip = V4L2_IDENT_SAA6752HS_AC3;
- h->has_ac3 = 1;
- v4l_info(client, "support AC-3\n");
- }
- h->params = param_defaults;
- h->standard = 0; /* Assume 625 input lines */
- return 0;
-}
-
-static int saa6752hs_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(to_state(sd));
- return 0;
-}
-
-static const struct i2c_device_id saa6752hs_id[] = {
- { "saa6752hs", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, saa6752hs_id);
-
-static struct i2c_driver saa6752hs_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "saa6752hs",
- },
- .probe = saa6752hs_probe,
- .remove = saa6752hs_remove,
- .id_table = saa6752hs_id,
-};
-
-module_i2c_driver(saa6752hs_driver);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
deleted file mode 100644
index 10460fd3ce3..00000000000
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ /dev/null
@@ -1,1209 +0,0 @@
-/*
- * SAA713x ALSA support for V4L
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <linux/interrupt.h>
-
-#include "saa7134.h"
-#include "saa7134-reg.h"
-
-static unsigned int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug,"enable debug messages [alsa]");
-
-/*
- * Configuration macros
- */
-
-/* defaults */
-#define MIXER_ADDR_UNSELECTED -1
-#define MIXER_ADDR_TVTUNER 0
-#define MIXER_ADDR_LINE1 1
-#define MIXER_ADDR_LINE2 2
-#define MIXER_ADDR_LAST 2
-
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
-
-module_param_array(index, int, NULL, 0444);
-module_param_array(enable, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
-MODULE_PARM_DESC(enable, "Enable (or not) the SAA7134 capture interface(s).");
-
-#define dprintk(fmt, arg...) if (debug) \
- printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ##arg)
-
-
-
-/*
- * Main chip structure
- */
-
-typedef struct snd_card_saa7134 {
- struct snd_card *card;
- spinlock_t mixer_lock;
- int mixer_volume[MIXER_ADDR_LAST+1][2];
- int capture_source_addr;
- int capture_source[2];
- struct snd_kcontrol *capture_ctl[MIXER_ADDR_LAST+1];
- struct pci_dev *pci;
- struct saa7134_dev *dev;
-
- unsigned long iobase;
- s16 irq;
- u16 mute_was_on;
-
- spinlock_t lock;
-} snd_card_saa7134_t;
-
-
-/*
- * PCM structure
- */
-
-typedef struct snd_card_saa7134_pcm {
- struct saa7134_dev *dev;
-
- spinlock_t lock;
-
- struct snd_pcm_substream *substream;
-} snd_card_saa7134_pcm_t;
-
-static struct snd_card *snd_saa7134_cards[SNDRV_CARDS];
-
-
-/*
- * saa7134 DMA audio stop
- *
- * Called when the capture device is released or the buffer overflows
- *
- * - Copied verbatim from saa7134-oss's dsp_dma_stop.
- *
- */
-
-static void saa7134_dma_stop(struct saa7134_dev *dev)
-{
- dev->dmasound.dma_blk = -1;
- dev->dmasound.dma_running = 0;
- saa7134_set_dmabits(dev);
-}
-
-/*
- * saa7134 DMA audio start
- *
- * Called when preparing the capture device for use
- *
- * - Copied verbatim from saa7134-oss's dsp_dma_start.
- *
- */
-
-static void saa7134_dma_start(struct saa7134_dev *dev)
-{
- dev->dmasound.dma_blk = 0;
- dev->dmasound.dma_running = 1;
- saa7134_set_dmabits(dev);
-}
-
-/*
- * saa7134 audio DMA IRQ handler
- *
- * Called whenever we get an SAA7134_IRQ_REPORT_DONE_RA3 interrupt
- * Handles shifting between the 2 buffers, manages the read counters,
- * and notifies ALSA when periods elapse
- *
- * - Mostly copied from saa7134-oss's saa7134_irq_oss_done.
- *
- */
-
-static void saa7134_irq_alsa_done(struct saa7134_dev *dev,
- unsigned long status)
-{
- int next_blk, reg = 0;
-
- spin_lock(&dev->slock);
- if (UNSET == dev->dmasound.dma_blk) {
- dprintk("irq: recording stopped\n");
- goto done;
- }
- if (0 != (status & 0x0f000000))
- dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
- if (0 == (status & 0x10000000)) {
- /* odd */
- if (0 == (dev->dmasound.dma_blk & 0x01))
- reg = SAA7134_RS_BA1(6);
- } else {
- /* even */
- if (1 == (dev->dmasound.dma_blk & 0x01))
- reg = SAA7134_RS_BA2(6);
- }
- if (0 == reg) {
- dprintk("irq: field oops [%s]\n",
- (status & 0x10000000) ? "even" : "odd");
- goto done;
- }
-
- if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
- dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count,
- dev->dmasound.bufsize, dev->dmasound.blocks);
- spin_unlock(&dev->slock);
- snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN);
- return;
- }
-
- /* next block addr */
- next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
- saa_writel(reg,next_blk * dev->dmasound.blksize);
- if (debug > 2)
- dprintk("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n",
- (status & 0x10000000) ? "even" : "odd ", next_blk,
- next_blk * dev->dmasound.blksize, dev->dmasound.blocks, dev->dmasound.blksize, dev->dmasound.read_count);
-
- /* update status & wake waiting readers */
- dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
- dev->dmasound.read_count += dev->dmasound.blksize;
-
- dev->dmasound.recording_on = reg;
-
- if (dev->dmasound.read_count >= snd_pcm_lib_period_bytes(dev->dmasound.substream)) {
- spin_unlock(&dev->slock);
- snd_pcm_period_elapsed(dev->dmasound.substream);
- spin_lock(&dev->slock);
- }
-
- done:
- spin_unlock(&dev->slock);
-
-}
-
-/*
- * IRQ request handler
- *
- * Runs along with saa7134's IRQ handler, discards anything that isn't
- * DMA sound
- *
- */
-
-static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id)
-{
- struct saa7134_dmasound *dmasound = dev_id;
- struct saa7134_dev *dev = dmasound->priv_data;
-
- unsigned long report, status;
- int loop, handled = 0;
-
- for (loop = 0; loop < 10; loop++) {
- report = saa_readl(SAA7134_IRQ_REPORT);
- status = saa_readl(SAA7134_IRQ_STATUS);
-
- if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
- handled = 1;
- saa_writel(SAA7134_IRQ_REPORT,
- SAA7134_IRQ_REPORT_DONE_RA3);
- saa7134_irq_alsa_done(dev, status);
- } else {
- goto out;
- }
- }
-
- if (loop == 10) {
- dprintk("error! looping IRQ!");
- }
-
-out:
- return IRQ_RETVAL(handled);
-}
-
-/*
- * ALSA capture trigger
- *
- * - One of the ALSA capture callbacks.
- *
- * Called whenever a capture is started or stopped. Must be defined,
- * but there's nothing we want to do here
- *
- */
-
-static int snd_card_saa7134_capture_trigger(struct snd_pcm_substream * substream,
- int cmd)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_card_saa7134_pcm_t *pcm = runtime->private_data;
- struct saa7134_dev *dev=pcm->dev;
- int err = 0;
-
- spin_lock(&dev->slock);
- if (cmd == SNDRV_PCM_TRIGGER_START) {
- /* start dma */
- saa7134_dma_start(dev);
- } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- /* stop dma */
- saa7134_dma_stop(dev);
- } else {
- err = -EINVAL;
- }
- spin_unlock(&dev->slock);
-
- return err;
-}
-
-/*
- * DMA buffer initialization
- *
- * Uses V4L functions to initialize the DMA. Shouldn't be necessary in
- * ALSA, but I was unable to use ALSA's own DMA, and had to force the
- * usage of V4L's
- *
- * - Copied verbatim from saa7134-oss.
- *
- */
-
-static int dsp_buffer_init(struct saa7134_dev *dev)
-{
- int err;
-
- BUG_ON(!dev->dmasound.bufsize);
-
- videobuf_dma_init(&dev->dmasound.dma);
- err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
- (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
- if (0 != err)
- return err;
- return 0;
-}
-
-/*
- * DMA buffer release
- *
- * Called after closing the device, during snd_card_saa7134_capture_close
- *
- */
-
-static int dsp_buffer_free(struct saa7134_dev *dev)
-{
- BUG_ON(!dev->dmasound.blksize);
-
- videobuf_dma_free(&dev->dmasound.dma);
-
- dev->dmasound.blocks = 0;
- dev->dmasound.blksize = 0;
- dev->dmasound.bufsize = 0;
-
- return 0;
-}
-
-/*
- * Setting the capture source and updating the ALSA controls
- */
-static int snd_saa7134_capsrc_set(struct snd_kcontrol *kcontrol,
- int left, int right, bool force_notify)
-{
- snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
- int change = 0, addr = kcontrol->private_value;
- int active, old_addr;
- u32 anabar, xbarin;
- int analog_io, rate;
- struct saa7134_dev *dev;
-
- dev = chip->dev;
-
- spin_lock_irq(&chip->mixer_lock);
-
- active = left != 0 || right != 0;
- old_addr = chip->capture_source_addr;
-
- /* The active capture source cannot be deactivated */
- if (active) {
- change = old_addr != addr ||
- chip->capture_source[0] != left ||
- chip->capture_source[1] != right;
-
- chip->capture_source[0] = left;
- chip->capture_source[1] = right;
- chip->capture_source_addr = addr;
- dev->dmasound.input = addr;
- }
- spin_unlock_irq(&chip->mixer_lock);
-
- if (change) {
- switch (dev->pci->device) {
-
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- switch (addr) {
- case MIXER_ADDR_TVTUNER:
- saa_andorb(SAA7134_AUDIO_FORMAT_CTRL,
- 0xc0, 0xc0);
- saa_andorb(SAA7134_SIF_SAMPLE_FREQ,
- 0x03, 0x00);
- break;
- case MIXER_ADDR_LINE1:
- case MIXER_ADDR_LINE2:
- analog_io = (MIXER_ADDR_LINE1 == addr) ?
- 0x00 : 0x08;
- rate = (32000 == dev->dmasound.rate) ?
- 0x01 : 0x03;
- saa_andorb(SAA7134_ANALOG_IO_SELECT,
- 0x08, analog_io);
- saa_andorb(SAA7134_AUDIO_FORMAT_CTRL,
- 0xc0, 0x80);
- saa_andorb(SAA7134_SIF_SAMPLE_FREQ,
- 0x03, rate);
- break;
- }
-
- break;
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- xbarin = 0x03; /* adc */
- anabar = 0;
- switch (addr) {
- case MIXER_ADDR_TVTUNER:
- xbarin = 0; /* Demodulator */
- anabar = 2; /* DACs */
- break;
- case MIXER_ADDR_LINE1:
- anabar = 0; /* aux1, aux1 */
- break;
- case MIXER_ADDR_LINE2:
- anabar = 9; /* aux2, aux2 */
- break;
- }
-
- /* output xbar always main channel */
- saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1,
- 0xbbbb10);
-
- if (left || right) {
- /* We've got data, turn the input on */
- saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1,
- xbarin);
- saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
- } else {
- saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1,
- 0);
- saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
- }
- break;
- }
- }
-
- if (change) {
- if (force_notify)
- snd_ctl_notify(chip->card,
- SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->capture_ctl[addr]->id);
-
- if (old_addr != MIXER_ADDR_UNSELECTED && old_addr != addr)
- snd_ctl_notify(chip->card,
- SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->capture_ctl[old_addr]->id);
- }
-
- return change;
-}
-
-/*
- * ALSA PCM preparation
- *
- * - One of the ALSA capture callbacks.
- *
- * Called right after the capture device is opened, this function configures
- * the buffer using the previously defined functions, allocates the memory,
- * sets up the hardware registers, and then starts the DMA. When this function
- * returns, the audio should be flowing.
- *
- */
-
-static int snd_card_saa7134_capture_prepare(struct snd_pcm_substream * substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int bswap, sign;
- u32 fmt, control;
- snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
- struct saa7134_dev *dev;
- snd_card_saa7134_pcm_t *pcm = runtime->private_data;
-
- pcm->dev->dmasound.substream = substream;
-
- dev = saa7134->dev;
-
- if (snd_pcm_format_width(runtime->format) == 8)
- fmt = 0x00;
- else
- fmt = 0x01;
-
- if (snd_pcm_format_signed(runtime->format))
- sign = 1;
- else
- sign = 0;
-
- if (snd_pcm_format_big_endian(runtime->format))
- bswap = 1;
- else
- bswap = 0;
-
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- if (1 == runtime->channels)
- fmt |= (1 << 3);
- if (2 == runtime->channels)
- fmt |= (3 << 3);
- if (sign)
- fmt |= 0x04;
-
- fmt |= (MIXER_ADDR_TVTUNER == dev->dmasound.input) ? 0xc0 : 0x80;
- saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff));
- saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >> 8);
- saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16);
- saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
-
- break;
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- if (1 == runtime->channels)
- fmt |= (1 << 4);
- if (2 == runtime->channels)
- fmt |= (2 << 4);
- if (!sign)
- fmt |= 0x04;
- saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1);
- saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
- break;
- }
-
- dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
- runtime->format, runtime->channels, fmt,
- bswap ? 'b' : '-');
- /* dma: setup channel 6 (= AUDIO) */
- control = SAA7134_RS_CONTROL_BURST_16 |
- SAA7134_RS_CONTROL_ME |
- (dev->dmasound.pt.dma >> 12);
- if (bswap)
- control |= SAA7134_RS_CONTROL_BSWAP;
-
- saa_writel(SAA7134_RS_BA1(6),0);
- saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
- saa_writel(SAA7134_RS_PITCH(6),0);
- saa_writel(SAA7134_RS_CONTROL(6),control);
-
- dev->dmasound.rate = runtime->rate;
-
- /* Setup and update the card/ALSA controls */
- snd_saa7134_capsrc_set(saa7134->capture_ctl[dev->dmasound.input], 1, 1,
- true);
-
- return 0;
-
-}
-
-/*
- * ALSA pointer fetching
- *
- * - One of the ALSA capture callbacks.
- *
- * Called whenever a period elapses, it must return the current hardware
- * position of the buffer.
- * Also resets the read counter used to prevent overruns
- *
- */
-
-static snd_pcm_uframes_t
-snd_card_saa7134_capture_pointer(struct snd_pcm_substream * substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_card_saa7134_pcm_t *pcm = runtime->private_data;
- struct saa7134_dev *dev=pcm->dev;
-
- if (dev->dmasound.read_count) {
- dev->dmasound.read_count -= snd_pcm_lib_period_bytes(substream);
- dev->dmasound.read_offset += snd_pcm_lib_period_bytes(substream);
- if (dev->dmasound.read_offset == dev->dmasound.bufsize)
- dev->dmasound.read_offset = 0;
- }
-
- return bytes_to_frames(runtime, dev->dmasound.read_offset);
-}
-
-/*
- * ALSA hardware capabilities definition
- *
- * Report only 32kHz for ALSA:
- *
- * - SAA7133/35 uses DDEP (DemDec Easy Programming mode), which works in 32kHz
- * only
- * - SAA7134 for TV mode uses DemDec mode (32kHz)
- * - Radio works in 32kHz only
- * - When recording 48kHz from Line1/Line2, switching of capture source to TV
- * means
- * switching to 32kHz without any frequency translation
- */
-
-static struct snd_pcm_hardware snd_card_saa7134_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S16_BE | \
- SNDRV_PCM_FMTBIT_S8 | \
- SNDRV_PCM_FMTBIT_U8 | \
- SNDRV_PCM_FMTBIT_U16_LE | \
- SNDRV_PCM_FMTBIT_U16_BE,
- .rates = SNDRV_PCM_RATE_32000,
- .rate_min = 32000,
- .rate_max = 32000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (256*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (256*1024),
- .periods_min = 4,
- .periods_max = 1024,
-};
-
-static void snd_card_saa7134_runtime_free(struct snd_pcm_runtime *runtime)
-{
- snd_card_saa7134_pcm_t *pcm = runtime->private_data;
-
- kfree(pcm);
-}
-
-
-/*
- * ALSA hardware params
- *
- * - One of the ALSA capture callbacks.
- *
- * Called on initialization, right before the PCM preparation
- *
- */
-
-static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
- struct snd_pcm_hw_params * hw_params)
-{
- snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
- struct saa7134_dev *dev;
- unsigned int period_size, periods;
- int err;
-
- period_size = params_period_bytes(hw_params);
- periods = params_periods(hw_params);
-
- if (period_size < 0x100 || period_size > 0x10000)
- return -EINVAL;
- if (periods < 4)
- return -EINVAL;
- if (period_size * periods > 1024 * 1024)
- return -EINVAL;
-
- dev = saa7134->dev;
-
- if (dev->dmasound.blocks == periods &&
- dev->dmasound.blksize == period_size)
- return 0;
-
- /* release the old buffer */
- if (substream->runtime->dma_area) {
- saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
- videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
- dsp_buffer_free(dev);
- substream->runtime->dma_area = NULL;
- }
- dev->dmasound.blocks = periods;
- dev->dmasound.blksize = period_size;
- dev->dmasound.bufsize = period_size * periods;
-
- err = dsp_buffer_init(dev);
- if (0 != err) {
- dev->dmasound.blocks = 0;
- dev->dmasound.blksize = 0;
- dev->dmasound.bufsize = 0;
- return err;
- }
-
- if (0 != (err = videobuf_dma_map(&dev->pci->dev, &dev->dmasound.dma))) {
- dsp_buffer_free(dev);
- return err;
- }
- if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) {
- videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
- dsp_buffer_free(dev);
- return err;
- }
- if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
- dev->dmasound.dma.sglist,
- dev->dmasound.dma.sglen,
- 0))) {
- saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
- videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
- dsp_buffer_free(dev);
- return err;
- }
-
- /* I should be able to use runtime->dma_addr in the control
- byte, but it doesn't work. So I allocate the DMA using the
- V4L functions, and force ALSA to use that as the DMA area */
-
- substream->runtime->dma_area = dev->dmasound.dma.vaddr;
- substream->runtime->dma_bytes = dev->dmasound.bufsize;
- substream->runtime->dma_addr = 0;
-
- return 0;
-
-}
-
-/*
- * ALSA hardware release
- *
- * - One of the ALSA capture callbacks.
- *
- * Called after closing the device, but before snd_card_saa7134_capture_close
- * It stops the DMA audio and releases the buffers.
- *
- */
-
-static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream)
-{
- snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
- struct saa7134_dev *dev;
-
- dev = saa7134->dev;
-
- if (substream->runtime->dma_area) {
- saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
- videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
- dsp_buffer_free(dev);
- substream->runtime->dma_area = NULL;
- }
-
- return 0;
-}
-
-/*
- * ALSA capture finish
- *
- * - One of the ALSA capture callbacks.
- *
- * Called after closing the device.
- *
- */
-
-static int snd_card_saa7134_capture_close(struct snd_pcm_substream * substream)
-{
- snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
- struct saa7134_dev *dev = saa7134->dev;
-
- if (saa7134->mute_was_on) {
- dev->ctl_mute = 1;
- saa7134_tvaudio_setmute(dev);
- }
- return 0;
-}
-
-/*
- * ALSA capture start
- *
- * - One of the ALSA capture callbacks.
- *
- * Called when opening the device. It creates and populates the PCM
- * structure
- *
- */
-
-static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_card_saa7134_pcm_t *pcm;
- snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
- struct saa7134_dev *dev;
- int amux, err;
-
- if (!saa7134) {
- printk(KERN_ERR "BUG: saa7134 can't find device struct."
- " Can't proceed with open\n");
- return -ENODEV;
- }
- dev = saa7134->dev;
- mutex_lock(&dev->dmasound.lock);
-
- dev->dmasound.read_count = 0;
- dev->dmasound.read_offset = 0;
-
- amux = dev->input->amux;
- if ((amux < 1) || (amux > 3))
- amux = 1;
- dev->dmasound.input = amux - 1;
-
- mutex_unlock(&dev->dmasound.lock);
-
- pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
- if (pcm == NULL)
- return -ENOMEM;
-
- pcm->dev=saa7134->dev;
-
- spin_lock_init(&pcm->lock);
-
- pcm->substream = substream;
- runtime->private_data = pcm;
- runtime->private_free = snd_card_saa7134_runtime_free;
- runtime->hw = snd_card_saa7134_capture;
-
- if (dev->ctl_mute != 0) {
- saa7134->mute_was_on = 1;
- dev->ctl_mute = 0;
- saa7134_tvaudio_setmute(dev);
- }
-
- err = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0)
- return err;
-
- err = snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIODS, 2);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-/*
- * page callback (needed for mmap)
- */
-
-static struct page *snd_card_saa7134_page(struct snd_pcm_substream *substream,
- unsigned long offset)
-{
- void *pageptr = substream->runtime->dma_area + offset;
- return vmalloc_to_page(pageptr);
-}
-
-/*
- * ALSA capture callbacks definition
- */
-
-static struct snd_pcm_ops snd_card_saa7134_capture_ops = {
- .open = snd_card_saa7134_capture_open,
- .close = snd_card_saa7134_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_card_saa7134_hw_params,
- .hw_free = snd_card_saa7134_hw_free,
- .prepare = snd_card_saa7134_capture_prepare,
- .trigger = snd_card_saa7134_capture_trigger,
- .pointer = snd_card_saa7134_capture_pointer,
- .page = snd_card_saa7134_page,
-};
-
-/*
- * ALSA PCM setup
- *
- * Called when initializing the board. Sets up the name and hooks up
- * the callbacks
- *
- */
-
-static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
-{
- struct snd_pcm *pcm;
- int err;
-
- if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_saa7134_capture_ops);
- pcm->private_data = saa7134;
- pcm->info_flags = 0;
- strcpy(pcm->name, "SAA7134 PCM");
- return 0;
-}
-
-#define SAA713x_VOLUME(xname, xindex, addr) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_saa7134_volume_info, \
- .get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \
- .private_value = addr }
-
-static int snd_saa7134_volume_info(struct snd_kcontrol * kcontrol,
- struct snd_ctl_elem_info * uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 20;
- return 0;
-}
-
-static int snd_saa7134_volume_get(struct snd_kcontrol * kcontrol,
- struct snd_ctl_elem_value * ucontrol)
-{
- snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
- int addr = kcontrol->private_value;
-
- ucontrol->value.integer.value[0] = chip->mixer_volume[addr][0];
- ucontrol->value.integer.value[1] = chip->mixer_volume[addr][1];
- return 0;
-}
-
-static int snd_saa7134_volume_put(struct snd_kcontrol * kcontrol,
- struct snd_ctl_elem_value * ucontrol)
-{
- snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
- struct saa7134_dev *dev = chip->dev;
-
- int change, addr = kcontrol->private_value;
- int left, right;
-
- left = ucontrol->value.integer.value[0];
- if (left < 0)
- left = 0;
- if (left > 20)
- left = 20;
- right = ucontrol->value.integer.value[1];
- if (right < 0)
- right = 0;
- if (right > 20)
- right = 20;
- spin_lock_irq(&chip->mixer_lock);
- change = 0;
- if (chip->mixer_volume[addr][0] != left) {
- change = 1;
- right = left;
- }
- if (chip->mixer_volume[addr][1] != right) {
- change = 1;
- left = right;
- }
- if (change) {
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- switch (addr) {
- case MIXER_ADDR_TVTUNER:
- left = 20;
- break;
- case MIXER_ADDR_LINE1:
- saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x10,
- (left > 10) ? 0x00 : 0x10);
- break;
- case MIXER_ADDR_LINE2:
- saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x20,
- (left > 10) ? 0x00 : 0x20);
- break;
- }
- break;
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- switch (addr) {
- case MIXER_ADDR_TVTUNER:
- left = 20;
- break;
- case MIXER_ADDR_LINE1:
- saa_andorb(0x0594, 0x10,
- (left > 10) ? 0x00 : 0x10);
- break;
- case MIXER_ADDR_LINE2:
- saa_andorb(0x0594, 0x20,
- (left > 10) ? 0x00 : 0x20);
- break;
- }
- break;
- }
- chip->mixer_volume[addr][0] = left;
- chip->mixer_volume[addr][1] = right;
- }
- spin_unlock_irq(&chip->mixer_lock);
- return change;
-}
-
-#define SAA713x_CAPSRC(xname, xindex, addr) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_saa7134_capsrc_info, \
- .get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \
- .private_value = addr }
-
-static int snd_saa7134_capsrc_info(struct snd_kcontrol * kcontrol,
- struct snd_ctl_elem_info * uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol,
- struct snd_ctl_elem_value * ucontrol)
-{
- snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
- int addr = kcontrol->private_value;
-
- spin_lock_irq(&chip->mixer_lock);
- if (chip->capture_source_addr == addr) {
- ucontrol->value.integer.value[0] = chip->capture_source[0];
- ucontrol->value.integer.value[1] = chip->capture_source[1];
- } else {
- ucontrol->value.integer.value[0] = 0;
- ucontrol->value.integer.value[1] = 0;
- }
- spin_unlock_irq(&chip->mixer_lock);
-
- return 0;
-}
-
-static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol,
- struct snd_ctl_elem_value * ucontrol)
-{
- int left, right;
- left = ucontrol->value.integer.value[0] & 1;
- right = ucontrol->value.integer.value[1] & 1;
-
- return snd_saa7134_capsrc_set(kcontrol, left, right, false);
-}
-
-static struct snd_kcontrol_new snd_saa7134_volume_controls[] = {
-SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
-SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
-SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2),
-};
-
-static struct snd_kcontrol_new snd_saa7134_capture_controls[] = {
-SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
-SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
-SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
-};
-
-/*
- * ALSA mixer setup
- *
- * Called when initializing the board. Sets up the name and hooks up
- * the callbacks
- *
- */
-
-static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
-{
- struct snd_card *card = chip->card;
- struct snd_kcontrol *kcontrol;
- unsigned int idx;
- int err, addr;
-
- strcpy(card->mixername, "SAA7134 Mixer");
-
- for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_volume_controls); idx++) {
- kcontrol = snd_ctl_new1(&snd_saa7134_volume_controls[idx],
- chip);
- err = snd_ctl_add(card, kcontrol);
- if (err < 0)
- return err;
- }
-
- for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_capture_controls); idx++) {
- kcontrol = snd_ctl_new1(&snd_saa7134_capture_controls[idx],
- chip);
- addr = snd_saa7134_capture_controls[idx].private_value;
- chip->capture_ctl[addr] = kcontrol;
- err = snd_ctl_add(card, kcontrol);
- if (err < 0)
- return err;
- }
-
- chip->capture_source_addr = MIXER_ADDR_UNSELECTED;
- return 0;
-}
-
-static void snd_saa7134_free(struct snd_card * card)
-{
- snd_card_saa7134_t *chip = card->private_data;
-
- if (chip->dev->dmasound.priv_data == NULL)
- return;
-
- if (chip->irq >= 0)
- free_irq(chip->irq, &chip->dev->dmasound);
-
- chip->dev->dmasound.priv_data = NULL;
-
-}
-
-/*
- * ALSA initialization
- *
- * Called by the init routine, once for each saa7134 device present,
- * it creates the basic structures and registers the ALSA devices
- *
- */
-
-static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
-{
-
- struct snd_card *card;
- snd_card_saa7134_t *chip;
- int err;
-
-
- if (devnum >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[devnum])
- return -ENODEV;
-
- err = snd_card_create(index[devnum], id[devnum], THIS_MODULE,
- sizeof(snd_card_saa7134_t), &card);
- if (err < 0)
- return err;
-
- strcpy(card->driver, "SAA7134");
-
- /* Card "creation" */
-
- card->private_free = snd_saa7134_free;
- chip = card->private_data;
-
- spin_lock_init(&chip->lock);
- spin_lock_init(&chip->mixer_lock);
-
- chip->dev = dev;
-
- chip->card = card;
-
- chip->pci = dev->pci;
- chip->iobase = pci_resource_start(dev->pci, 0);
-
-
- err = request_irq(dev->pci->irq, saa7134_alsa_irq,
- IRQF_SHARED | IRQF_DISABLED, dev->name,
- (void*) &dev->dmasound);
-
- if (err < 0) {
- printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n",
- dev->name, dev->pci->irq);
- goto __nodev;
- }
-
- chip->irq = dev->pci->irq;
-
- mutex_init(&dev->dmasound.lock);
-
- if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
- goto __nodev;
-
- if ((err = snd_card_saa7134_pcm(chip, 0)) < 0)
- goto __nodev;
-
- snd_card_set_dev(card, &chip->pci->dev);
-
- /* End of "creation" */
-
- strcpy(card->shortname, "SAA7134");
- sprintf(card->longname, "%s at 0x%lx irq %d",
- chip->dev->name, chip->iobase, chip->irq);
-
- printk(KERN_INFO "%s/alsa: %s registered as card %d\n",dev->name,card->longname,index[devnum]);
-
- if ((err = snd_card_register(card)) == 0) {
- snd_saa7134_cards[devnum] = card;
- return 0;
- }
-
-__nodev:
- snd_card_free(card);
- return err;
-}
-
-
-static int alsa_device_init(struct saa7134_dev *dev)
-{
- dev->dmasound.priv_data = dev;
- alsa_card_saa7134_create(dev,dev->nr);
- return 1;
-}
-
-static int alsa_device_exit(struct saa7134_dev *dev)
-{
-
- snd_card_free(snd_saa7134_cards[dev->nr]);
- snd_saa7134_cards[dev->nr] = NULL;
- return 1;
-}
-
-/*
- * Module initializer
- *
- * Loops through present saa7134 cards, and assigns an ALSA device
- * to each one
- *
- */
-
-static int saa7134_alsa_init(void)
-{
- struct saa7134_dev *dev = NULL;
- struct list_head *list;
-
- saa7134_dmasound_init = alsa_device_init;
- saa7134_dmasound_exit = alsa_device_exit;
-
- printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
-
- list_for_each(list,&saa7134_devlist) {
- dev = list_entry(list, struct saa7134_dev, devlist);
- if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130)
- printk(KERN_INFO "%s/alsa: %s doesn't support digital audio\n",
- dev->name, saa7134_boards[dev->board].name);
- else
- alsa_device_init(dev);
- }
-
- if (dev == NULL)
- printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n");
-
- return 0;
-
-}
-
-/*
- * Module destructor
- */
-
-static void saa7134_alsa_exit(void)
-{
- int idx;
-
- for (idx = 0; idx < SNDRV_CARDS; idx++) {
- snd_card_free(snd_saa7134_cards[idx]);
- }
-
- saa7134_dmasound_init = NULL;
- saa7134_dmasound_exit = NULL;
- printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n");
-
- return;
-}
-
-/* We initialize this late, to make sure the sound system is up and running */
-late_initcall(saa7134_alsa_init);
-module_exit(saa7134_alsa_exit);
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Ricardo Cerqueira");
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
deleted file mode 100644
index bc08f1dbc29..00000000000
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ /dev/null
@@ -1,8026 +0,0 @@
-/*
- *
- * device driver for philips saa7134 based TV cards
- * card-specific stuff.
- *
- * (c) 2001-04 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-#include "saa7134-reg.h"
-#include "saa7134.h"
-#include "tuner-xc2028.h"
-#include <media/v4l2-common.h>
-#include <media/tveeprom.h>
-#include "tea5767.h"
-#include "tda18271.h"
-#include "xc5000.h"
-#include "s5h1411.h"
-
-/* commly used strings */
-static char name_mute[] = "mute";
-static char name_radio[] = "Radio";
-static char name_tv[] = "Television";
-static char name_tv_mono[] = "TV (mono only)";
-static char name_comp[] = "Composite";
-static char name_comp1[] = "Composite1";
-static char name_comp2[] = "Composite2";
-static char name_comp3[] = "Composite3";
-static char name_comp4[] = "Composite4";
-static char name_svideo[] = "S-Video";
-
-/* ------------------------------------------------------------------ */
-/* board config info */
-
-/* If radio_type !=UNSET, radio_addr should be specified
- */
-
-struct saa7134_board saa7134_boards[] = {
- [SAA7134_BOARD_UNKNOWN] = {
- .name = "UNKNOWN/GENERIC",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
-
- .inputs = {{
- .name = "default",
- .vmux = 0,
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_PROTEUS_PRO] = {
- /* /me */
- .name = "Proteus Pro [philips reference design]",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
-
- .inputs = {{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_FLYVIDEO3000] = {
- /* "Marco d'Itri" <md@Linux.IT> */
- .name = "LifeView FlyVIDEO3000",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
-
- .gpiomask = 0xe000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .gpio = 0x8000,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .gpio = 0x0000,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- .gpio = 0x4000,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE2,
- .gpio = 0x4000,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- .gpio = 0x4000,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x2000,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- .gpio = 0x8000,
- },
- },
- [SAA7134_BOARD_FLYVIDEO2000] = {
- /* "TC Wan" <tcwan@cs.usm.my> */
- .name = "LifeView/Typhoon FlyVIDEO2000",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
-
- .gpiomask = 0xe000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .gpio = 0x0000,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- .gpio = 0x4000,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE2,
- .gpio = 0x4000,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- .gpio = 0x4000,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x2000,
- },
- .mute = {
- .name = name_mute,
- .amux = LINE2,
- .gpio = 0x8000,
- },
- },
- [SAA7134_BOARD_FLYTVPLATINUM_MINI] = {
- /* "Arnaud Quette" <aquette@free.fr> */
- .name = "LifeView FlyTV Platinum Mini",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
-
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1, /* Composite signal on S-Video input */
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2, /* Composite input */
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_FLYTVPLATINUM_FM] = {
- /* LifeView FlyTV Platinum FM (LR214WF) */
- /* "Peter Missel <peter.missel@onlinehome.de> */
- .name = "LifeView FlyTV Platinum FM / Gold",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
-
- .gpiomask = 0x1E000, /* Set GP16 and unused 15,14,13 to Output */
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .gpio = 0x10000, /* GP16=1 selects TV input */
- .tv = 1,
- },{
-/* .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .gpio = 0x0000,
- .tv = 1,
- },{
-*/ .name = name_comp1, /* Composite signal on S-Video input */
- .vmux = 0,
- .amux = LINE2,
-/* .gpio = 0x4000, */
- },{
- .name = name_comp2, /* Composite input */
- .vmux = 3,
- .amux = LINE2,
-/* .gpio = 0x4000, */
- },{
- .name = name_svideo, /* S-Video signal on S-Video input */
- .vmux = 8,
- .amux = LINE2,
-/* .gpio = 0x4000, */
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x00000, /* GP16=0 selects FM radio antenna */
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- .gpio = 0x10000,
- },
- },
- [SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM] = {
- /* RoverMedia TV Link Pro FM (LR138 REV:I) */
- /* Eugene Yudin <Eugene.Yudin@gmail.com> */
- .name = "RoverMedia TV Link Pro FM",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MFPE05 2 */
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0xe000,
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .gpio = 0x8000,
- .tv = 1,
- }, {
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .gpio = 0x0000,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- .gpio = 0x4000,
- }, {
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE2,
- .gpio = 0x4000,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- .gpio = 0x4000,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x2000,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- .gpio = 0x8000,
- },
- },
- [SAA7134_BOARD_EMPRESS] = {
- /* "Gert Vervoort" <gert.vervoort@philips.com> */
- .name = "EMPRESS",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .empress_addr = 0x20,
-
- .inputs = {{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- .mpeg = SAA7134_MPEG_EMPRESS,
- .video_out = CCIR656,
- },
- [SAA7134_BOARD_MONSTERTV] = {
- /* "K.Ohta" <alpha292@bremen.or.jp> */
- .name = "SKNet Monster TV",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
-
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_MD9717] = {
- .name = "Tevion MD 9717",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- /* workaround for problems with normal TV sound */
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- },
- },
- [SAA7134_BOARD_TVSTATION_RDS] = {
- /* Typhoon TV Tuner RDS: Art.Nr. 50694 */
- .name = "KNC One TV-Station RDS / Typhoon TV Tuner RDS",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
-
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
-
- .name = "CVid over SVid",
- .vmux = 0,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_TVSTATION_DVR] = {
- .name = "KNC One TV-Station DVR",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .empress_addr = 0x20,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x820000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x20000,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x20000,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x20000,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x20000,
- },
- .mpeg = SAA7134_MPEG_EMPRESS,
- .video_out = CCIR656,
- },
- [SAA7134_BOARD_CINERGY400] = {
- .name = "Terratec Cinergy 400 TV",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp2, /* CVideo over SVideo Connector */
- .vmux = 0,
- .amux = LINE1,
- }}
- },
- [SAA7134_BOARD_MD5044] = {
- .name = "Medion 5044",
- .audio_clock = 0x00187de7, /* was: 0x00200000, */
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- /* workaround for problems with normal TV sound */
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_KWORLD] = {
- .name = "Kworld/KuroutoShikou SAA7130-TVPCI",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- }},
- },
- [SAA7134_BOARD_CINERGY600] = {
- .name = "Terratec Cinergy 600 TV",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp2, /* CVideo over SVideo Connector */
- .vmux = 0,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_MD7134] = {
- .name = "Medion 7134",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- },
- },
- [SAA7134_BOARD_TYPHOON_90031] = {
- /* aka Typhoon "TV+Radio", Art.Nr 90031 */
- /* Tom Zoerner <tomzo at users sourceforge net> */
- .name = "Typhoon TV+Radio 90031",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_ELSA] = {
- .name = "ELSA EX-VISION 300TV",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_HITACHI_NTSC,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 4,
- .amux = LINE2,
- .tv = 1,
- }},
- },
- [SAA7134_BOARD_ELSA_500TV] = {
- .name = "ELSA EX-VISION 500TV",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_HITACHI_NTSC,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_svideo,
- .vmux = 7,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 8,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 8,
- .amux = LINE2,
- .tv = 1,
- }},
- },
- [SAA7134_BOARD_ELSA_700TV] = {
- .name = "ELSA EX-VISION 700TV",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_HITACHI_NTSC,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 4,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 6,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 7,
- .amux = LINE1,
- }},
- .mute = {
- .name = name_mute,
- .amux = TV,
- },
- },
- [SAA7134_BOARD_ASUSTeK_TVFM7134] = {
- .name = "ASUS TV-FM 7134",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- },
- },
- [SAA7134_BOARD_ASUSTeK_TVFM7135] = {
- .name = "ASUS TV-FM 7135",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x200000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .gpio = 0x0000,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE2,
- .gpio = 0x0000,
- },{
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE2,
- .gpio = 0x0000,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x200000,
- },
- .mute = {
- .name = name_mute,
- .gpio = 0x0000,
- },
-
- },
- [SAA7134_BOARD_VA1000POWER] = {
- .name = "AOPEN VA1000 POWER",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_NTSC,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- }},
- },
- [SAA7134_BOARD_10MOONSTVMASTER] = {
- /* "lilicheng" <llc@linuxfans.org> */
- .name = "10MOONS PCI TV CAPTURE CARD",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0xe000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .gpio = 0x0000,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- .gpio = 0x4000,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE2,
- .gpio = 0x4000,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- .gpio = 0x4000,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x2000,
- },
- .mute = {
- .name = name_mute,
- .amux = LINE2,
- .gpio = 0x8000,
- },
- },
- [SAA7134_BOARD_BMK_MPEX_NOTUNER] = {
- /* "Andrew de Quincey" <adq@lidskialf.net> */
- .name = "BMK MPEX No Tuner",
- .audio_clock = 0x200000,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .empress_addr = 0x20,
- .inputs = {{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE1,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_comp3,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_comp4,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .mpeg = SAA7134_MPEG_EMPRESS,
- .video_out = CCIR656,
- },
- [SAA7134_BOARD_VIDEOMATE_TV] = {
- .name = "Compro VideoMate TV",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- }},
- },
- [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS] = {
- .name = "Compro VideoMate TV Gold+",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .gpiomask = 0x800c0000,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x06c00012,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x0ac20012,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .gpio = 0x08c20012,
- .tv = 1,
- }}, /* radio and probably mute is missing */
- },
- [SAA7134_BOARD_CRONOS_PLUS] = {
- /*
- gpio pins:
- 0 .. 3 BASE_ID
- 4 .. 7 PROTECT_ID
- 8 .. 11 USER_OUT
- 12 .. 13 USER_IN
- 14 .. 15 VIDIN_SEL
- */
- .name = "Matrox CronosPlus",
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0xcf00,
- .inputs = {{
- .name = name_comp1,
- .vmux = 0,
- .gpio = 2 << 14,
- },{
- .name = name_comp2,
- .vmux = 0,
- .gpio = 1 << 14,
- },{
- .name = name_comp3,
- .vmux = 0,
- .gpio = 0 << 14,
- },{
- .name = name_comp4,
- .vmux = 0,
- .gpio = 3 << 14,
- },{
- .name = name_svideo,
- .vmux = 8,
- .gpio = 2 << 14,
- }},
- },
- [SAA7134_BOARD_MD2819] = {
- .name = "AverMedia M156 / Medion 2819",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x03,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x00,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x02,
- }, {
- .name = name_comp2,
- .vmux = 0,
- .amux = LINE1,
- .gpio = 0x02,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x02,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- .gpio = 0x01,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- .gpio = 0x00,
- },
- },
- [SAA7134_BOARD_BMK_MPEX_TUNER] = {
- /* "Greg Wickham <greg.wickham@grangenet.net> */
- .name = "BMK MPEX Tuner",
- .audio_clock = 0x200000,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .empress_addr = 0x20,
- .inputs = {{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }},
- .mpeg = SAA7134_MPEG_EMPRESS,
- .video_out = CCIR656,
- },
- [SAA7134_BOARD_ASUSTEK_TVFM7133] = {
- .name = "ASUS TV-FM 7133",
- .audio_clock = 0x00187de7,
- /* probably wrong, the 7133 one is the NTSC version ...
- * .tuner_type = TUNER_PHILIPS_FM1236_MK3 */
- .tuner_type = TUNER_LG_NTSC_NEW_TAPC,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
-
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- },
- },
- [SAA7134_BOARD_PINNACLE_PCTV_STEREO] = {
- .name = "Pinnacle PCTV Stereo (saa7134)",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_MT2032,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_INACTIVE,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2,
- .vmux = 1,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_MANLI_MTV002] = {
- /* Ognjen Nastic <ognjen@logosoft.ba> */
- .name = "Manli MuchTV M-TV002",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_MANLI_MTV001] = {
- /* Ognjen Nastic <ognjen@logosoft.ba> UNTESTED */
- .name = "Manli MuchTV M-TV001",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- }},
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- },
- },
- [SAA7134_BOARD_TG3000TV] = {
- /* TransGear 3000TV */
- .name = "Nagase Sangyo TransGear 3000TV",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_ECS_TVP3XP] = {
- .name = "Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) ",
- .audio_clock = 0x187de7, /* xtal 32.1 MHz */
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = "CVid over SVid",
- .vmux = 0,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_ECS_TVP3XP_4CB5] = {
- .name = "Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)",
- .audio_clock = 0x187de7,
- .tuner_type = TUNER_PHILIPS_NTSC,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = "CVid over SVid",
- .vmux = 0,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_ECS_TVP3XP_4CB6] = {
- /* Barry Scott <barry.scott@onelan.co.uk> */
- .name = "Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM)",
- .audio_clock = 0x187de7,
- .tuner_type = TUNER_PHILIPS_PAL_I,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = "CVid over SVid",
- .vmux = 0,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_AVACSSMARTTV] = {
- /* Roman Pszonczenko <romka@kolos.math.uni.lodz.pl> */
- .name = "AVACS SmartTV",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x200000,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER] = {
- /* Michael Smith <msmith@cbnco.com> */
- .name = "AVerMedia DVD EZMaker",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_comp1,
- .vmux = 3,
- },{
- .name = name_svideo,
- .vmux = 8,
- }},
- },
- [SAA7134_BOARD_AVERMEDIA_M103] = {
- /* Massimo Piccioni <dafastidio@libero.it> */
- .name = "AVerMedia MiniPCI DVB-T Hybrid M103",
- .audio_clock = 0x187de7,
- .tuner_type = TUNER_XC2028,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- } },
- },
- [SAA7134_BOARD_NOVAC_PRIMETV7133] = {
- /* toshii@netbsd.org */
- .name = "Noval Prime TV 7133",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_ALPS_TSBH1_NTSC,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_comp1,
- .vmux = 3,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_svideo,
- .vmux = 8,
- }},
- },
- [SAA7134_BOARD_AVERMEDIA_STUDIO_305] = {
- .name = "AverMedia AverTV Studio 305",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1256_IH3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_STUDIO_505] = {
- /* Vasiliy Temnikov <vaka@newmail.ru> */
- .name = "AverMedia AverTV Studio 505",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- }, {
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- },
- },
- [SAA7134_BOARD_UPMOST_PURPLE_TV] = {
- .name = "UPMOST PURPLE TV",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1236_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 7,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_svideo,
- .vmux = 7,
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_ITEMS_MTV005] = {
- /* Norman Jonas <normanjonas@arcor.de> */
- .name = "Items MuchTV Plus / IT-005",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_CINERGY200] = {
- .name = "Terratec Cinergy 200 TV",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp2, /* CVideo over SVideo Connector */
- .vmux = 0,
- .amux = LINE1,
- }},
- .mute = {
- .name = name_mute,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_VIDEOMATE_TV_PVR] = {
- /* Alain St-Denis <alain@topaze.homeip.net> */
- .name = "Compro VideoMate TV PVR/FM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x808c0080,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x00080,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x00080,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2_LEFT,
- .tv = 1,
- .gpio = 0x00080,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x80000,
- },
- .mute = {
- .name = name_mute,
- .amux = LINE2,
- .gpio = 0x40000,
- },
- },
- [SAA7134_BOARD_SABRENT_SBTTVFM] = {
- /* Michael Rodriguez-Torrent <mrtorrent@asu.edu> */
- .name = "Sabrent SBT-TVFM (saa7130)",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_ZOLID_XPERT_TV7134] = {
- /* Helge Jensen <helge.jensen@slog.dk> */
- .name = ":Zolid Xpert TV7134",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_NTSC,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- }},
- },
- [SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE] = {
- /* "Matteo Az" <matte.az@nospam.libero.it> ;-) */
- .name = "Empire PCI TV-Radio LE",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x4000,
- .inputs = {{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .gpio = 0x8000,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x8000,
- },{
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE1,
- .gpio = 0x8000,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- .gpio = 0x8000,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- .gpio =0x8000,
- }
- },
- [SAA7134_BOARD_AVERMEDIA_STUDIO_307] = {
- /*
- Nickolay V. Shmyrev <nshmyrev@yandex.ru>
- Lots of thanks to Andrey Zolotarev <zolotarev_andrey@mail.ru>
- */
- .name = "Avermedia AVerTV Studio 307",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1256_IH3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x03,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x00,
- },{
- .name = name_comp,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x02,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x02,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- .gpio = 0x01,
- },
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- .gpio = 0x00,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_GO_007_FM] = {
- .name = "Avermedia AVerTV GO 007 FM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x00300003,
- /* .gpiomask = 0x8c240003, */
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x01,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- .gpio = 0x02,
- },{
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE1,
- .gpio = 0x02,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x00300001,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- .gpio = 0x01,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_CARDBUS] = {
- /* Kees.Blom@cwi.nl */
- .name = "AVerMedia Cardbus TV/Radio (E500)",
- .audio_clock = 0x187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_CARDBUS_501] = {
- /* Oldrich Jedlicka <oldium.pro@seznam.cz> */
- .name = "AVerMedia Cardbus TV/Radio (E501R)",
- .audio_clock = 0x187de7,
- .tuner_type = TUNER_ALPS_TSBE5_PAL,
- .radio_type = TUNER_TEA5767,
- .tuner_addr = 0x61,
- .radio_addr = 0x60,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x08000000,
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x08000000,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x08000000,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x08000000,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x00000000,
- },
- },
- [SAA7134_BOARD_CINERGY400_CARDBUS] = {
- .name = "Terratec Cinergy 400 mobile",
- .audio_clock = 0x187de7,
- .tuner_type = TUNER_ALPS_TSBE5_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_CINERGY600_MK3] = {
- .name = "Terratec Cinergy 600 TV MK3",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp2, /* CVideo over SVideo Connector */
- .vmux = 0,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_VIDEOMATE_GOLD_PLUS] = {
- /* Dylan Walkden <dylan_walkden@hotmail.com> */
- .name = "Compro VideoMate Gold+ Pal",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x1ce780,
- .inputs = {{
- .name = name_svideo,
- .vmux = 0, /* CVideo over SVideo Connector - ok? */
- .amux = LINE1,
- .gpio = 0x008080,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x008080,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x008080,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x80000,
- },
- .mute = {
- .name = name_mute,
- .amux = LINE2,
- .gpio = 0x0c8000,
- },
- },
- [SAA7134_BOARD_PINNACLE_300I_DVBT_PAL] = {
- .name = "Pinnacle PCTV 300i DVB-T + PAL",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_MT2032,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_INACTIVE,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2,
- .vmux = 1,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_PROVIDEO_PV952] = {
- /* andreas.kretschmer@web.de */
- .name = "ProVideo PV952",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_305] = {
- /* much like the "studio" version but without radio
- * and another tuner (sirspiritus@yandex.ru) */
- .name = "AverMedia AverTV/305",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FQ1216ME,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- },
- },
- [SAA7134_BOARD_FLYDVBTDUO] = {
- /* LifeView FlyDVB-T DUO */
- /* "Nico Sabbi <nsabbi@tiscali.it> Hartmut Hackmann hartmut.hackmann@t-online.de*/
- .name = "LifeView FlyDVB-T DUO / MSI TV@nywhere Duo",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x00200000,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .gpio = 0x200000, /* GPIO21=High for TV input */
- .tv = 1,
- },{
- .name = name_comp1, /* Composite signal on S-Video input */
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2, /* Composite input */
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo, /* S-Video signal on S-Video input */
- .vmux = 8,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */
- },
- },
- [SAA7134_BOARD_PHILIPS_TOUGH] = {
- .name = "Philips TOUGH DVB-T reference design",
- .tuner_type = TUNER_ABSENT,
- .audio_clock = 0x00187de7,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_AVERMEDIA_307] = {
- /*
- Davydov Vladimir <vladimir@iqmedia.com>
- */
- .name = "Avermedia AVerTV 307",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FQ1216ME,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_ADS_INSTANT_TV] = {
- .name = "ADS Tech Instant TV (saa7135)",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_KWORLD_VSTREAM_XPERT] = {
- .name = "Kworld/Tevion V-Stream Xpert TV PVR7134",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_PAL_I,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x0700,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x000,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x200, /* gpio by DScaler */
- },{
- .name = name_svideo,
- .vmux = 0,
- .amux = LINE1,
- .gpio = 0x200,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- .gpio = 0x100,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- .gpio = 0x000,
- },
- },
- [SAA7134_BOARD_FLYDVBT_DUO_CARDBUS] = {
- .name = "LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .gpiomask = 0x00200000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .gpio = 0x200000, /* GPIO21=High for TV input */
- .tv = 1,
- },{
- .name = name_svideo, /* S-Video signal on S-Video input */
- .vmux = 8,
- .amux = LINE2,
- },{
- .name = name_comp1, /* Composite signal on S-Video input */
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2, /* Composite input */
- .vmux = 3,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */
- },
- },
- [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII] = {
- .name = "Compro VideoMate TV Gold+II",
- .audio_clock = 0x002187de7,
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .radio_type = TUNER_TEA5767,
- .tuner_addr = 0x63,
- .radio_addr = 0x60,
- .gpiomask = 0x8c1880,
- .inputs = {{
- .name = name_svideo,
- .vmux = 0,
- .amux = LINE1,
- .gpio = 0x800800,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x801000,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x800000,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x880000,
- },
- .mute = {
- .name = name_mute,
- .amux = LINE2,
- .gpio = 0x840000,
- },
- },
- [SAA7134_BOARD_KWORLD_XPERT] = {
- /*
- FIXME:
- - Remote control doesn't initialize properly.
- - Audio volume starts muted,
- then gradually increases after channel change.
- - Overlay scaling problems (application error?)
- - Composite S-Video untested.
- From: Konrad Rzepecki <hannibal@megapolis.pl>
- */
- .name = "Kworld Xpert TV PVR7134",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_TENA_9533_DI,
- .radio_type = TUNER_TEA5767,
- .tuner_addr = 0x61,
- .radio_addr = 0x60,
- .gpiomask = 0x0700,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x000,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x200, /* gpio by DScaler */
- },{
- .name = name_svideo,
- .vmux = 0,
- .amux = LINE1,
- .gpio = 0x200,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- .gpio = 0x100,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- .gpio = 0x000,
- },
- },
- [SAA7134_BOARD_FLYTV_DIGIMATRIX] = {
- .name = "FlyTV mini Asus Digimatrix",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_LG_TALN,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio, /* radio unconfirmed */
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_KWORLD_TERMINATOR] = {
- /* Kworld V-Stream Studio TV Terminator */
- /* "James Webb <jrwebb@qwest.net> */
- .name = "V-Stream Studio TV Terminator",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 1 << 21,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .gpio = 0x0000000,
- .tv = 1,
- },{
- .name = name_comp1, /* Composite input */
- .vmux = 3,
- .amux = LINE2,
- .gpio = 0x0000000,
- },{
- .name = name_svideo, /* S-Video input */
- .vmux = 8,
- .amux = LINE2,
- .gpio = 0x0000000,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_YUAN_TUN900] = {
- /* FIXME:
- * S-Video and composite sources untested.
- * Radio not working.
- * Remote control not yet implemented.
- * From : codemaster@webgeeks.be */
- .name = "Yuan TUN-900 (saa7135)",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr= ADDR_UNSET,
- .radio_addr= ADDR_UNSET,
- .gpiomask = 0x00010003,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x01,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- .gpio = 0x02,
- },{
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE2,
- .gpio = 0x02,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- .gpio = 0x00010003,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- .gpio = 0x01,
- },
- },
- [SAA7134_BOARD_BEHOLD_409FM] = {
- /* <http://tuner.beholder.ru>, Sergey <skiv@orel.ru> */
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 409 FM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_GOTVIEW_7135] = {
- /* Mike Baikov <mike@baikov.com> */
- /* Andrey Cvetcov <ays14@yandex.ru> */
- .name = "GoTView 7135 PCI",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x00200003,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x00200003,
- },{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .gpio = 0x00200003,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x00200003,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x00200003,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x00200003,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- .gpio = 0x00200003,
- },
- },
- [SAA7134_BOARD_PHILIPS_EUROPA] = {
- .name = "Philips EUROPA V3 reference design",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TD1316,
- .radio_type = UNSET,
- .tuner_addr = 0x61,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_VIDEOMATE_DVBT_300] = {
- .name = "Compro Videomate DVB-T300",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TD1316,
- .radio_type = UNSET,
- .tuner_addr = 0x61,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_VIDEOMATE_DVBT_200] = {
- .name = "Compro Videomate DVB-T200",
- .tuner_type = TUNER_ABSENT,
- .audio_clock = 0x00187de7,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_RTD_VFG7350] = {
- .name = "RTD Embedded Technologies VFG7350",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .empress_addr = 0x21,
- .inputs = {{
- .name = "Composite 0",
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = "Composite 1",
- .vmux = 1,
- .amux = LINE2,
- },{
- .name = "Composite 2",
- .vmux = 2,
- .amux = LINE1,
- },{
- .name = "Composite 3",
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = "S-Video 0",
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = "S-Video 1",
- .vmux = 9,
- .amux = LINE2,
- }},
- .mpeg = SAA7134_MPEG_EMPRESS,
- .video_out = CCIR656,
- .vid_port_opts = ( SET_T_CODE_POLARITY_NON_INVERTED |
- SET_CLOCK_NOT_DELAYED |
- SET_CLOCK_INVERTED |
- SET_VSYNC_OFF ),
- },
- [SAA7134_BOARD_RTD_VFG7330] = {
- .name = "RTD Embedded Technologies VFG7330",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = "Composite 0",
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = "Composite 1",
- .vmux = 1,
- .amux = LINE2,
- },{
- .name = "Composite 2",
- .vmux = 2,
- .amux = LINE1,
- },{
- .name = "Composite 3",
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = "S-Video 0",
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = "S-Video 1",
- .vmux = 9,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_FLYTVPLATINUM_MINI2] = {
- .name = "LifeView FlyTV Platinum Mini2",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
-
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1, /* Composite signal on S-Video input */
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2, /* Composite input */
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180] = {
- /* Michael Krufky <mkrufky@m1k.net>
- * Uses Alps Electric TDHU2, containing NXT2004 ATSC Decoder
- * AFAIK, there is no analog demod, thus,
- * no support for analog television.
- */
- .name = "AVerMedia AVerTVHD MCE A180",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_MONSTERTV_MOBILE] = {
- .name = "SKNet MonsterTV Mobile",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
-
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_PINNACLE_PCTV_110i] = {
- .name = "Pinnacle PCTV 40i/50i/110i (saa7133)",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x080200000,
- .inputs = { {
- .name = name_tv,
- .vmux = 4,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE2,
- }, {
- .name = name_comp2,
- .vmux = 0,
- .amux = LINE2,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_ASUSTeK_P7131_DUAL] = {
- .name = "ASUSTeK P7131 Dual",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 1 << 21,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x0000000,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE2,
- .gpio = 0x0200000,
- },{
- .name = name_comp2,
- .vmux = 0,
- .amux = LINE2,
- .gpio = 0x0200000,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- .gpio = 0x0200000,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_SEDNA_PC_TV_CARDBUS] = {
- /* Paul Tom Zalac <pzalac@gmail.com> */
- /* Pavel Mihaylov <bin@bash.info> */
- .name = "Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)",
- /* Sedna/MuchTV (OEM) Cardbus TV Tuner */
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0xe880c0,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV] = {
- /* "Cyril Lacoux (Yack)" <clacoux@ifeelgood.org> */
- .name = "ASUS Digimatrix TV",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_FQ1216ME,
- .tda9887_conf = TDA9887_PRESENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_PHILIPS_TIGER] = {
- .name = "Philips Tiger reference design",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 0,
- .mpeg = SAA7134_MPEG_DVB,
- .gpiomask = 0x0200000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_MSI_TVATANYWHERE_PLUS] = {
- .name = "MSI TV@Anywhere plus",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 1 << 21,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE2, /* unconfirmed, taken from Philips driver */
- },{
- .name = name_comp2,
- .vmux = 0, /* untested, Composite over S-Video */
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_CINERGY250PCI] = {
- /* remote-control does not work. The signal about a
- key press comes in via gpio, but the key code
- doesn't. Neither does it have an i2c remote control
- interface. */
- .name = "Terratec Cinergy 250 PCI TV",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x80200000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_svideo, /* NOT tested */
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_FLYDVB_TRIO] = {
- /* LifeView LR319 FlyDVB Trio */
- /* Peter Missel <peter.missel@onlinehome.de> */
- .name = "LifeView FlyDVB Trio",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x00200000,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv, /* Analog broadcast/cable TV */
- .vmux = 1,
- .amux = TV,
- .gpio = 0x200000, /* GPIO21=High for TV input */
- .tv = 1,
- },{
- .name = name_svideo, /* S-Video signal on S-Video input */
- .vmux = 8,
- .amux = LINE2,
- },{
- .name = name_comp1, /* Composite signal on S-Video input */
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2, /* Composite input */
- .vmux = 3,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */
- },
- },
- [SAA7134_BOARD_AVERMEDIA_777] = {
- .name = "AverTV DVB-T 777",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_FLYDVBT_LR301] = {
- /* LifeView FlyDVB-T */
- /* Giampiero Giancipoli <gianci@libero.it> */
- .name = "LifeView FlyDVB-T / Genius VideoWonder DVB-T",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_comp1, /* Composite input */
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo, /* S-Video signal on S-Video input */
- .vmux = 8,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331] = {
- .name = "ADS Instant TV Duo Cardbus PTV331",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .gpiomask = 0x00600000, /* Bit 21 0=Radio, Bit 22 0=TV */
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x00200000,
- }},
- },
- [SAA7134_BOARD_TEVION_DVBT_220RF] = {
- .name = "Tevion/KWorld DVB-T 220RF",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .gpiomask = 1 << 21,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_comp2,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_KWORLD_DVBT_210] = {
- .name = "KWorld DVB-T 210",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .gpiomask = 1 << 21,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_KWORLD_ATSC110] = {
- .name = "Kworld ATSC110/115",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TUV1236D,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_AVERMEDIA_A169_B] = {
- /* AVerMedia A169 */
- /* Rickard Osser <ricky@osser.se> */
- /* This card has two saa7134 chips on it,
- but only one of them is currently working. */
- .name = "AVerMedia A169 B",
- .audio_clock = 0x02187de7,
- .tuner_type = TUNER_LG_TALN,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x0a60000,
- },
- [SAA7134_BOARD_AVERMEDIA_A169_B1] = {
- /* AVerMedia A169 */
- /* Rickard Osser <ricky@osser.se> */
- .name = "AVerMedia A169 B1",
- .audio_clock = 0x02187de7,
- .tuner_type = TUNER_LG_TALN,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0xca60000,
- .inputs = {{
- .name = name_tv,
- .vmux = 4,
- .amux = TV,
- .tv = 1,
- .gpio = 0x04a61000,
- },{
- .name = name_comp2, /* Composite SVIDEO (B/W if signal is carried with SVIDEO) */
- .vmux = 1,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 9, /* 9 is correct as S-VIDEO1 according to a169.inf! */
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_MD7134_BRIDGE_2] = {
- /* The second saa7134 on this card only serves as DVB-S host bridge */
- .name = "Medion 7134 Bridge #2",
- .audio_clock = 0x00187de7,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- },
- [SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS] = {
- .name = "LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .gpiomask = 0x00600000, /* Bit 21 0=Radio, Bit 22 0=TV */
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .gpio = 0x200000, /* GPIO21=High for TV input */
- .tv = 1,
- },{
- .name = name_svideo, /* S-Video signal on S-Video input */
- .vmux = 8,
- .amux = LINE2,
- },{
- .name = name_comp1, /* Composite signal on S-Video input */
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2, /* Composite input */
- .vmux = 3,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */
- },
- },
- [SAA7134_BOARD_FLYVIDEO3000_NTSC] = {
- /* "Zac Bowling" <zac@zacbowling.com> */
- .name = "LifeView FlyVIDEO3000 (NTSC)",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_NTSC,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
-
- .gpiomask = 0xe000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .gpio = 0x8000,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .gpio = 0x0000,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- .gpio = 0x4000,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE2,
- .gpio = 0x4000,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- .gpio = 0x4000,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x2000,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- .gpio = 0x8000,
- },
- },
- [SAA7134_BOARD_MEDION_MD8800_QUADRO] = {
- .name = "Medion Md8800 Quadro",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_FLYDVBS_LR300] = {
- /* LifeView FlyDVB-s */
- /* Igor M. Liplianin <liplianin@tut.by> */
- .name = "LifeView FlyDVB-S /Acorp TV134DS",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_comp1, /* Composite input */
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo, /* S-Video signal on S-Video input */
- .vmux = 8,
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_PROTEUS_2309] = {
- .name = "Proteus Pro 2309",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_A16AR] = {
- /* Petr Baudis <pasky@ucw.cz> */
- .name = "AVerMedia TV Hybrid A16AR",
- .audio_clock = 0x187de7,
- .tuner_type = TUNER_PHILIPS_TD1316, /* untested */
- .radio_type = TUNER_TEA5767, /* untested */
- .tuner_addr = ADDR_UNSET,
- .radio_addr = 0x60,
- .tda9887_conf = TDA9887_PRESENT,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- },
- },
- [SAA7134_BOARD_ASUS_EUROPA2_HYBRID] = {
- .name = "Asus Europa2 OEM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT| TDA9887_PORT1_ACTIVE | TDA9887_PORT2_ACTIVE,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- },
- },
- [SAA7134_BOARD_PINNACLE_PCTV_310i] = {
- .name = "Pinnacle PCTV 310i",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 1,
- .mpeg = SAA7134_MPEG_DVB,
- .gpiomask = 0x000200000,
- .inputs = {{
- .name = name_tv,
- .vmux = 4,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE2,
- },{
- .name = name_comp2,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_STUDIO_507] = {
- /* Mikhail Fedotov <mo_fedotov@mail.ru> */
- .name = "Avermedia AVerTV Studio 507",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1256_IH3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x03,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x00,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- .gpio = 0x00,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE2,
- .gpio = 0x00,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- .gpio = 0x00,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x01,
- },
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- .gpio = 0x00,
- },
- },
- [SAA7134_BOARD_VIDEOMATE_DVBT_200A] = {
- /* Francis Barber <fedora@barber-family.id.au> */
- .name = "Compro Videomate DVB-T200A",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_HAUPPAUGE_HVR1110] = {
- /* Thomas Genty <tomlohave@gmail.com> */
- /* David Bentham <db260179@hotmail.com> */
- .name = "Hauppauge WinTV-HVR1110 DVB-T/Hybrid",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 1,
- .mpeg = SAA7134_MPEG_DVB,
- .gpiomask = 0x0200100,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x0000100,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200100,
- },
- },
- [SAA7134_BOARD_HAUPPAUGE_HVR1150] = {
- .name = "Hauppauge WinTV-HVR1150 ATSC/QAM-Hybrid",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 3,
- .mpeg = SAA7134_MPEG_DVB,
- .ts_type = SAA7134_MPEG_TS_SERIAL,
- .ts_force_val = 1,
- .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x0000100,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0800100, /* GPIO 23 HI for FM */
- },
- },
- [SAA7134_BOARD_HAUPPAUGE_HVR1120] = {
- .name = "Hauppauge WinTV-HVR1120 DVB-T/Hybrid",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 3,
- .mpeg = SAA7134_MPEG_DVB,
- .ts_type = SAA7134_MPEG_TS_SERIAL,
- .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x0000100,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0800100, /* GPIO 23 HI for FM */
- },
- },
- [SAA7134_BOARD_CINERGY_HT_PCMCIA] = {
- .name = "Terratec Cinergy HT PCMCIA",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_ENCORE_ENLTV] = {
- /* Steven Walter <stevenrwalter@gmail.com>
- Juan Pablo Sormani <sorman@gmail.com> */
- .name = "Encore ENLTV",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_TNF_5335MF,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = 3,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 7,
- .amux = 4,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = 2,
- },{
- .name = name_svideo,
- .vmux = 0,
- .amux = 2,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
-/* .gpio = 0x00300001,*/
- .gpio = 0x20000,
-
- },
- .mute = {
- .name = name_mute,
- .amux = 0,
- },
- },
- [SAA7134_BOARD_ENCORE_ENLTV_FM] = {
- /* Juan Pablo Sormani <sorman@gmail.com> */
- .name = "Encore ENLTV-FM",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_FCV1236D,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = 3,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 7,
- .amux = 4,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = 2,
- },{
- .name = name_svideo,
- .vmux = 0,
- .amux = 2,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x20000,
-
- },
- .mute = {
- .name = name_mute,
- .amux = 0,
- },
- },
- [SAA7134_BOARD_ENCORE_ENLTV_FM53] = {
- .name = "Encore ENLTV-FM v5.3",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_TNF_5335MF,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x7000,
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = 1,
- .tv = 1,
- .gpio = 0x50000,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = 2,
- .gpio = 0x2000,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = 2,
- .gpio = 0x2000,
- } },
- .radio = {
- .name = name_radio,
- .vmux = 1,
- .amux = 1,
- },
- .mute = {
- .name = name_mute,
- .gpio = 0xf000,
- .amux = 0,
- },
- },
- [SAA7134_BOARD_ENCORE_ENLTV_FM3] = {
- .name = "Encore ENLTV-FM 3",
- .audio_clock = 0x02187de7,
- .tuner_type = TUNER_TENA_TNF_5337,
- .radio_type = TUNER_TEA5767,
- .tuner_addr = 0x61,
- .radio_addr = 0x60,
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .vmux = 1,
- .amux = LINE1,
- },
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- .gpio = 0x43000,
- },
- },
- [SAA7134_BOARD_CINERGY_HT_PCI] = {
- .name = "Terratec Cinergy HT PCI",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_PHILIPS_TIGER_S] = {
- .name = "Philips Tiger - S Reference design",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 2,
- .mpeg = SAA7134_MPEG_DVB,
- .gpiomask = 0x0200000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_M102] = {
- .name = "Avermedia M102",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 1<<21,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_ASUS_P7131_4871] = {
- .name = "ASUS P7131 4871",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 2,
- .mpeg = SAA7134_MPEG_DVB,
- .gpiomask = 0x0200000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x0200000,
- }},
- },
- [SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA] = {
- .name = "ASUSTeK P7131 Hybrid",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 2,
- .gpiomask = 1 << 21,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x0000000,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE2,
- .gpio = 0x0200000,
- },{
- .name = name_comp2,
- .vmux = 0,
- .amux = LINE2,
- .gpio = 0x0200000,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- .gpio = 0x0200000,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_ASUSTeK_P7131_ANALOG] = {
- .name = "ASUSTeK P7131 Analog",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 1 << 21,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x0000000,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE2,
- }, {
- .name = name_comp2,
- .vmux = 0,
- .amux = LINE2,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_SABRENT_TV_PCB05] = {
- .name = "Sabrent PCMCIA TV-PCB05",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_comp2,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .mute = {
- .name = name_mute,
- .amux = TV,
- },
- },
- [SAA7134_BOARD_10MOONSTVMASTER3] = {
- /* Tony Wan <aloha_cn@hotmail.com> */
- .name = "10MOONS TM300 TV Card",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x7000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .gpio = 0x0000,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x2000,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x2000,
- }},
- .mute = {
- .name = name_mute,
- .amux = LINE2,
- .gpio = 0x3000,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_SUPER_007] = {
- .name = "Avermedia Super 007",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 0,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv, /* FIXME: analog tv untested */
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }},
- },
- [SAA7134_BOARD_AVERMEDIA_M135A] = {
- .name = "Avermedia PCI pure analog (M135A)",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 2,
- .gpiomask = 0x020200000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x00200000,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- .gpio = 0x01,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_M733A] = {
- .name = "Avermedia PCI M733A",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 0,
- .gpiomask = 0x020200000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x00200000,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- .gpio = 0x01,
- },
- },
- [SAA7134_BOARD_BEHOLD_401] = {
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 401",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FQ1216ME,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- }},
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- },
- },
- [SAA7134_BOARD_BEHOLD_403] = {
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 403",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FQ1216ME,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- }},
- },
- [SAA7134_BOARD_BEHOLD_403FM] = {
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 403 FM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FQ1216ME,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_405] = {
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 405",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- }},
- },
- [SAA7134_BOARD_BEHOLD_405FM] = {
- /* Sergey <skiv@orel.ru> */
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 405 FM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_407] = {
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 407",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0xc0c000,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- .gpio = 0xc0c000,
- },{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- .gpio = 0xc0c000,
- }},
- },
- [SAA7134_BOARD_BEHOLD_407FM] = {
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 407 FM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0xc0c000,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- .gpio = 0xc0c000,
- },{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- .gpio = 0xc0c000,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0xc0c000,
- },
- },
- [SAA7134_BOARD_BEHOLD_409] = {
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 409",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- },
- [SAA7134_BOARD_BEHOLD_505FM] = {
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 505 FM",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_505RDS_MK5] = {
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 505 RDS",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_FM1216MK5,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_507_9FM] = {
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 507 FM / BeholdTV 509 FM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_507RDS_MK5] = {
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 507 RDS",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216MK5,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_507RDS_MK3] = {
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 507 RDS",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = {
- /* Beholder Intl. Ltd. 2008 */
- /* Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV Columbus TV/FM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_ALPS_TSBE5_PAL,
- .radio_type = TUNER_TEA5767,
- .tuner_addr = 0xc2 >> 1,
- .radio_addr = 0xc0 >> 1,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x000A8004,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- .gpio = 0x000A8004,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- .gpio = 0x000A8000,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x000A8000,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x000A8000,
- },
- },
- [SAA7134_BOARD_BEHOLD_607FM_MK3] = {
- /* Andrey Melnikoff <temnota@kmv.ru> */
- .name = "Beholder BeholdTV 607 FM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_609FM_MK3] = {
- /* Andrey Melnikoff <temnota@kmv.ru> */
- .name = "Beholder BeholdTV 609 FM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_607FM_MK5] = {
- /* Andrey Melnikoff <temnota@kmv.ru> */
- .name = "Beholder BeholdTV 607 FM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216MK5,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_609FM_MK5] = {
- /* Andrey Melnikoff <temnota@kmv.ru> */
- .name = "Beholder BeholdTV 609 FM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216MK5,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_607RDS_MK3] = {
- /* Andrey Melnikoff <temnota@kmv.ru> */
- .name = "Beholder BeholdTV 607 RDS",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_609RDS_MK3] = {
- /* Andrey Melnikoff <temnota@kmv.ru> */
- .name = "Beholder BeholdTV 609 RDS",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_607RDS_MK5] = {
- /* Andrey Melnikoff <temnota@kmv.ru> */
- .name = "Beholder BeholdTV 607 RDS",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216MK5,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_609RDS_MK5] = {
- /* Andrey Melnikoff <temnota@kmv.ru> */
- .name = "Beholder BeholdTV 609 RDS",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216MK5,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_BEHOLD_M6] = {
- /* Igor Kuznetsov <igk@igk.ru> */
- /* Andrey Melnikoff <temnota@kmv.ru> */
- /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
- /* Alexey Osipov <lion-simba@pridelands.ru> */
- .name = "Beholder BeholdTV M6",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .empress_addr = 0x20,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = { {
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- .mpeg = SAA7134_MPEG_EMPRESS,
- .video_out = CCIR656,
- .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED |
- SET_CLOCK_NOT_DELAYED |
- SET_CLOCK_INVERTED |
- SET_VSYNC_OFF),
- },
- [SAA7134_BOARD_BEHOLD_M63] = {
- /* Igor Kuznetsov <igk@igk.ru> */
- /* Andrey Melnikoff <temnota@kmv.ru> */
- /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV M63",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .empress_addr = 0x20,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = { {
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- .mpeg = SAA7134_MPEG_EMPRESS,
- .video_out = CCIR656,
- .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED |
- SET_CLOCK_NOT_DELAYED |
- SET_CLOCK_INVERTED |
- SET_VSYNC_OFF),
- },
- [SAA7134_BOARD_BEHOLD_M6_EXTRA] = {
- /* Igor Kuznetsov <igk@igk.ru> */
- /* Andrey Melnikoff <temnota@kmv.ru> */
- /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
- /* Alexey Osipov <lion-simba@pridelands.ru> */
- .name = "Beholder BeholdTV M6 Extra",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216MK5,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
- .empress_addr = 0x20,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = { {
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- .mpeg = SAA7134_MPEG_EMPRESS,
- .video_out = CCIR656,
- .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED |
- SET_CLOCK_NOT_DELAYED |
- SET_CLOCK_INVERTED |
- SET_VSYNC_OFF),
- },
- [SAA7134_BOARD_TWINHAN_DTV_DVB_3056] = {
- .name = "Twinhan Hybrid DTV-DVB 3056 PCI",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 2,
- .mpeg = SAA7134_MPEG_DVB,
- .gpiomask = 0x0200000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8, /* untested */
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_GENIUS_TVGO_A11MCE] = {
- /* Adrian Pardini <pardo.bsso@gmail.com> */
- .name = "Genius TVGO AM11MCE",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_TNF_5335MF,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0xf000,
- .inputs = {{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .gpio = 0x0000,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x2000,
- .tv = 1
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x2000,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x1000,
- },
- .mute = {
- .name = name_mute,
- .amux = LINE2,
- .gpio = 0x6000,
- },
- },
- [SAA7134_BOARD_PHILIPS_SNAKE] = {
- .name = "NXP Snake DVB-S reference design",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- },
- [SAA7134_BOARD_CREATIX_CTX953] = {
- .name = "Medion/Creatix CTX953 Hybrid",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 0,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- },
- [SAA7134_BOARD_MSI_TVANYWHERE_AD11] = {
- .name = "MSI TV@nywhere A/D v1.1",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 2,
- .mpeg = SAA7134_MPEG_DVB,
- .gpiomask = 0x0200000,
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_CARDBUS_506] = {
- .name = "AVerMedia Cardbus TV/Radio (E506R)",
- .audio_clock = 0x187de7,
- .tuner_type = TUNER_XC2028,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_A16D] = {
- .name = "AVerMedia Hybrid TV/Radio (A16D)",
- .audio_clock = 0x187de7,
- .tuner_type = TUNER_XC2028,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }, {
- .name = name_comp,
- .vmux = 0,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_M115] = {
- .name = "Avermedia M115",
- .audio_clock = 0x187de7,
- .tuner_type = TUNER_XC2028,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- } },
- },
- [SAA7134_BOARD_VIDEOMATE_T750] = {
- /* John Newbigin <jn@it.swin.edu.au> */
- .name = "Compro VideoMate T750",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_XC2028,
- .radio_type = UNSET,
- .tuner_addr = 0x61,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE2,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- }
- },
- [SAA7134_BOARD_AVERMEDIA_A700_PRO] = {
- /* Matthias Schwarzott <zzam@gentoo.org> */
- .name = "Avermedia DVB-S Pro A700",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = { {
- .name = name_comp,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE1,
- } },
- },
- [SAA7134_BOARD_AVERMEDIA_A700_HYBRID] = {
- /* Matthias Schwarzott <zzam@gentoo.org> */
- .name = "Avermedia DVB-S Hybrid+FM A700",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_XC2028,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = { {
- .name = name_tv,
- .vmux = 4,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- },
- },
- [SAA7134_BOARD_BEHOLD_H6] = {
- /* Igor Kuznetsov <igk@igk.ru> */
- .name = "Beholder BeholdTV H6",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FMD1216MEX_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_ASUSTeK_TIGER_3IN1] = {
- .name = "Asus Tiger 3in1",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 2,
- .gpiomask = 1 << 21,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp,
- .vmux = 0,
- .amux = LINE2,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_ASUSTeK_PS3_100] = {
- .name = "Asus My Cinema PS3-100",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 2,
- .gpiomask = 1 << 21,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp,
- .vmux = 0,
- .amux = LINE2,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_REAL_ANGEL_220] = {
- .name = "Zogis Real Angel 220",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_TNF_5335MF,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x801a8087,
- .inputs = { {
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- .gpio = 0x624000,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- .gpio = 0x624000,
- }, {
- .name = name_svideo,
- .vmux = 1,
- .amux = LINE1,
- .gpio = 0x624000,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x624001,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- },
- },
- [SAA7134_BOARD_ADS_INSTANT_HDTV_PCI] = {
- .name = "ADS Tech Instant HDTV",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TUV1236D,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp,
- .vmux = 4,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- },
- [SAA7134_BOARD_ASUSTeK_TIGER] = {
- .name = "Asus Tiger Rev:1.00",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 0,
- .mpeg = SAA7134_MPEG_DVB,
- .gpiomask = 0x0200000,
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE2,
- }, {
- .name = name_comp2,
- .vmux = 0,
- .amux = LINE2,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0200000,
- },
- },
- [SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG] = {
- .name = "Kworld Plus TV Analog Lite PCI",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_YMEC_TVF_5533MF,
- .radio_type = TUNER_TEA5767,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = 0x60,
- .gpiomask = 0x80000700,
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- .gpio = 0x100,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x200,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x200,
- } },
- .radio = {
- .name = name_radio,
- .vmux = 1,
- .amux = LINE1,
- .gpio = 0x100,
- },
- .mute = {
- .name = name_mute,
- .vmux = 8,
- .amux = 2,
- },
- },
- [SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG] = {
- .name = "Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .tuner_addr = ADDR_UNSET,
- .radio_type = UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x8e054000,
- .mpeg = SAA7134_MPEG_DVB,
- .ts_type = SAA7134_MPEG_TS_PARALLEL,
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
-#if 0 /* FIXME */
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x200,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x200,
-#endif
- } },
-#if 0
- .radio = {
- .name = name_radio,
- .vmux = 1,
- .amux = LINE1,
- .gpio = 0x100,
- },
-#endif
- .mute = {
- .name = name_mute,
- .vmux = 0,
- .amux = TV,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS] = {
- .name = "Avermedia AVerTV GO 007 FM Plus",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x00300003,
- /* .gpiomask = 0x8c240003, */
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x01,
- }, {
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE1,
- .gpio = 0x02,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x00300001,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- .gpio = 0x01,
- },
- },
- [SAA7134_BOARD_AVERMEDIA_STUDIO_507UA] = {
- /* Andy Shevchenko <andy@smile.org.ua> */
- .name = "Avermedia AVerTV Studio 507UA",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* Should be MK5 */
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x03,
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x00,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x00,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x00,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x01,
- },
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- .gpio = 0x00,
- },
- },
- [SAA7134_BOARD_VIDEOMATE_S350] = {
- /* Jan D. Louw <jd.louw@mweb.co.za */
- .name = "Compro VideoMate S350/S300",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = { {
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8, /* Not tested */
- .amux = LINE1
- } },
- },
- [SAA7134_BOARD_BEHOLD_X7] = {
- /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV X7",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_XC5000,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = { {
- .name = name_tv,
- .vmux = 2,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 9,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- },
- },
- [SAA7134_BOARD_ZOLID_HYBRID_PCI] = {
- .name = "Zolid Hybrid TV Tuner PCI",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tuner_config = 0,
- .mpeg = SAA7134_MPEG_DVB,
- .ts_type = SAA7134_MPEG_TS_PARALLEL,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- } },
- .radio = { /* untested */
- .name = name_radio,
- .amux = TV,
- },
- },
- [SAA7134_BOARD_ASUS_EUROPA_HYBRID] = {
- .name = "Asus Europa Hybrid OEM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TD1316,
- .radio_type = UNSET,
- .tuner_addr = 0x61,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = { {
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE2,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- } },
- },
- [SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S] = {
- .name = "Leadtek Winfast DTV1000S",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = { {
- .name = name_comp1,
- .vmux = 3,
- }, {
- .name = name_svideo,
- .vmux = 8,
- } },
- },
- [SAA7134_BOARD_BEHOLD_505RDS_MK3] = {
- /* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 505 RDS",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
- .tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x00008000,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- },
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_HAWELL_HW_404M7] = {
- /* Hawell HW-404M7 & Hawell HW-808M7 */
- /* Bogoslovskiy Viktor <bogovic@bk.ru> */
- .name = "Hawell HW-404M7",
- .audio_clock = 0x00200000,
- .tuner_type = UNSET,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x389c00,
- .inputs = {{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x01fc00,
- } },
- },
- [SAA7134_BOARD_BEHOLD_H7] = {
- /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV H7",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_XC5000,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .ts_type = SAA7134_MPEG_TS_PARALLEL,
- .inputs = { {
- .name = name_tv,
- .vmux = 2,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 9,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- },
- },
- [SAA7134_BOARD_BEHOLD_A7] = {
- /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV A7",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_XC5000,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = { {
- .name = name_tv,
- .vmux = 2,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 9,
- .amux = LINE1,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- },
- },
- [SAA7134_BOARD_TECHNOTREND_BUDGET_T3000] = {
- .name = "TechoTrend TT-budget T-3000",
- .tuner_type = TUNER_PHILIPS_TD1316,
- .audio_clock = 0x00187de7,
- .radio_type = UNSET,
- .tuner_addr = 0x63,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE,
- .mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- } },
- },
- [SAA7134_BOARD_VIDEOMATE_M1F] = {
- /* Pavel Osnova <pvosnova@gmail.com> */
- .name = "Compro VideoMate Vista M1F",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .radio_type = TUNER_TEA5767,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = 0x60,
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE2,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- } },
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- },
- .mute = {
- .name = name_mute,
- .amux = TV,
- },
- },
- [SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2] = {
- /* Timothy Lee <timothy.lee@siriushk.com> */
- .name = "MagicPro ProHDTV Pro2 DMB-TH/Hybrid",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_config = 3,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x02050000,
- .mpeg = SAA7134_MPEG_DVB,
- .ts_type = SAA7134_MPEG_TS_PARALLEL,
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x00050000,
- }, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x00050000,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x00050000,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x00050000,
- },
- .mute = {
- .name = name_mute,
- .vmux = 0,
- .amux = TV,
- .gpio = 0x00050000,
- },
- },
- [SAA7134_BOARD_BEHOLD_501] = {
- /* Beholder Intl. Ltd. 2010 */
- /* Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 501",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x00008000,
- .inputs = { {
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- },
- },
- [SAA7134_BOARD_BEHOLD_503FM] = {
- /* Beholder Intl. Ltd. 2010 */
- /* Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 503 FM",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .gpiomask = 0x00008000,
- .inputs = { {
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- }, {
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- },
- },
- [SAA7134_BOARD_SENSORAY811_911] = {
- .name = "Sensoray 811/911",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- }, {
- .name = name_comp3,
- .vmux = 2,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- } },
- },
- [SAA7134_BOARD_KWORLD_PC150U] = {
- .name = "Kworld PC150-U",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
- .gpiomask = 1 << 21,
- .ts_type = SAA7134_MPEG_TS_PARALLEL,
- .inputs = { {
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- }, {
- .name = name_comp,
- .vmux = 3,
- .amux = LINE1,
- }, {
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- } },
- .radio = {
- .name = name_radio,
- .amux = TV,
- .gpio = 0x0000000,
- },
- },
-
-};
-
-const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
-
-/* ------------------------------------------------------------------ */
-/* PCI ids + subsystem IDs */
-
-struct pci_device_id saa7134_pci_tbl[] = {
- {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2001,
- .driver_data = SAA7134_BOARD_PROTEUS_PRO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2001,
- .driver_data = SAA7134_BOARD_PROTEUS_PRO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x6752,
- .driver_data = SAA7134_BOARD_EMPRESS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1131,
- .subdevice = 0x4e85,
- .driver_data = SAA7134_BOARD_MONSTERTV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x153b,
- .subdevice = 0x1142,
- .driver_data = SAA7134_BOARD_CINERGY400,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x153b,
- .subdevice = 0x1143,
- .driver_data = SAA7134_BOARD_CINERGY600,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x153b,
- .subdevice = 0x1158,
- .driver_data = SAA7134_BOARD_CINERGY600_MK3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x153b,
- .subdevice = 0x1162,
- .driver_data = SAA7134_BOARD_CINERGY400_CARDBUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5169,
- .subdevice = 0x0138,
- .driver_data = SAA7134_BOARD_FLYVIDEO3000_NTSC,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5168,
- .subdevice = 0x0138,
- .driver_data = SAA7134_BOARD_FLYVIDEO3000,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x4e42, /* "Typhoon PCI Capture TV Card" Art.No. 50673 */
- .subdevice = 0x0138,
- .driver_data = SAA7134_BOARD_FLYVIDEO3000,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x5168,
- .subdevice = 0x0138,
- .driver_data = SAA7134_BOARD_FLYVIDEO2000,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x4e42, /* Typhoon */
- .subdevice = 0x0138, /* LifeView FlyTV Prime30 OEM */
- .driver_data = SAA7134_BOARD_FLYVIDEO2000,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168,
- .subdevice = 0x0212, /* minipci, LR212 */
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x14c0,
- .subdevice = 0x1212, /* minipci, LR1212 */
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI2,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x4e42,
- .subdevice = 0x0212, /* OEM minipci, LR212 */
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168, /* Animation Technologies (LifeView) */
- .subdevice = 0x0214, /* Standard PCI, LR214 Rev E and earlier (SAA7135) */
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168, /* Animation Technologies (LifeView) */
- .subdevice = 0x5214, /* Standard PCI, LR214 Rev F onwards (SAA7131) */
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1489, /* KYE */
- .subdevice = 0x0214, /* Genius VideoWonder ProTV */
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, /* is an LR214WF actually */
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x16be,
- .subdevice = 0x0003,
- .driver_data = SAA7134_BOARD_MD7134,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x16be, /* CTX946 analog TV, HW mpeg, DVB-T */
- .subdevice = 0x5000, /* only analog TV and DVB-T for now */
- .driver_data = SAA7134_BOARD_MD7134,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1048,
- .subdevice = 0x226b,
- .driver_data = SAA7134_BOARD_ELSA,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1048,
- .subdevice = 0x226a,
- .driver_data = SAA7134_BOARD_ELSA_500TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1048,
- .subdevice = 0x226c,
- .driver_data = SAA7134_BOARD_ELSA_700TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4842,
- .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4845,
- .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7135,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4830,
- .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4843,
- .driver_data = SAA7134_BOARD_ASUSTEK_TVFM7133,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4840,
- .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0xfe01,
- .driver_data = SAA7134_BOARD_TVSTATION_RDS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1894,
- .subdevice = 0xfe01,
- .driver_data = SAA7134_BOARD_TVSTATION_RDS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1894,
- .subdevice = 0xa006,
- .driver_data = SAA7134_BOARD_TVSTATION_DVR,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1131,
- .subdevice = 0x7133,
- .driver_data = SAA7134_BOARD_VA1000POWER,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2001,
- .driver_data = SAA7134_BOARD_10MOONSTVMASTER,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x185b,
- .subdevice = 0xc100,
- .driver_data = SAA7134_BOARD_VIDEOMATE_TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x185b,
- .subdevice = 0xc100,
- .driver_data = SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_MATROX,
- .subdevice = 0x48d0,
- .driver_data = SAA7134_BOARD_CRONOS_PLUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa70b,
- .driver_data = SAA7134_BOARD_MD2819,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa7a1,
- .driver_data = SAA7134_BOARD_AVERMEDIA_A700_PRO,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa7a2,
- .driver_data = SAA7134_BOARD_AVERMEDIA_A700_HYBRID,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x2115,
- .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_305,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa115,
- .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_505,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x2108,
- .driver_data = SAA7134_BOARD_AVERMEDIA_305,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x10ff,
- .driver_data = SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER,
- },{
- /* AVerMedia CardBus */
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xd6ee,
- .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS,
- },{
- /* AVerMedia CardBus */
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xb7e9,
- .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS_501,
- }, {
- /* TransGear 3000TV */
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x050c,
- .driver_data = SAA7134_BOARD_TG3000TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x11bd,
- .subdevice = 0x002b,
- .driver_data = SAA7134_BOARD_PINNACLE_PCTV_STEREO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x11bd,
- .subdevice = 0x002d,
- .driver_data = SAA7134_BOARD_PINNACLE_300I_DVBT_PAL,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1019,
- .subdevice = 0x4cb4,
- .driver_data = SAA7134_BOARD_ECS_TVP3XP,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1019,
- .subdevice = 0x4cb5,
- .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB5,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1019,
- .subdevice = 0x4cb6,
- .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB6,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x12ab,
- .subdevice = 0x0800,
- .driver_data = SAA7134_BOARD_UPMOST_PURPLE_TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x153b,
- .subdevice = 0x1152,
- .driver_data = SAA7134_BOARD_CINERGY200,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x185b,
- .subdevice = 0xc100,
- .driver_data = SAA7134_BOARD_VIDEOMATE_TV_PVR,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x9715,
- .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_307,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa70a,
- .driver_data = SAA7134_BOARD_AVERMEDIA_307,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x185b,
- .subdevice = 0xc200,
- .driver_data = SAA7134_BOARD_VIDEOMATE_GOLD_PLUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1540,
- .subdevice = 0x9524,
- .driver_data = SAA7134_BOARD_PROVIDEO_PV952,
-
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168,
- .subdevice = 0x0502, /* Cardbus version */
- .driver_data = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168,
- .subdevice = 0x0306, /* PCI version */
- .driver_data = SAA7134_BOARD_FLYDVBTDUO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf31f,
- .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM,
-
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf11d,
- .driver_data = SAA7134_BOARD_AVERMEDIA_M135A,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x4155,
- .driver_data = SAA7134_BOARD_AVERMEDIA_M733A,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x4255,
- .driver_data = SAA7134_BOARD_AVERMEDIA_M733A,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2004,
- .driver_data = SAA7134_BOARD_PHILIPS_TOUGH,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1421,
- .subdevice = 0x0350, /* PCI version */
- .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1421,
- .subdevice = 0x0351, /* PCI version, new revision */
- .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1421,
- .subdevice = 0x0370, /* cardbus version */
- .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1421,
- .subdevice = 0x1370, /* cardbus version */
- .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
-
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x4e42, /* Typhoon */
- .subdevice = 0x0502, /* LifeView LR502 OEM */
- .driver_data = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1043,
- .subdevice = 0x0210, /* mini pci NTSC version */
- .driver_data = SAA7134_BOARD_FLYTV_DIGIMATRIX,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1043,
- .subdevice = 0x0210, /* mini pci PAL/SECAM version */
- .driver_data = SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV,
-
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0000, /* It shouldn't break anything, since subdevice id seems unique */
- .subdevice = 0x4091,
- .driver_data = SAA7134_BOARD_BEHOLD_409FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5456, /* GoTView */
- .subdevice = 0x7135,
- .driver_data = SAA7134_BOARD_GOTVIEW_7135,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2004,
- .driver_data = SAA7134_BOARD_PHILIPS_EUROPA,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x185b,
- .subdevice = 0xc900,
- .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_300,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x185b,
- .subdevice = 0xc901,
- .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_200,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1435,
- .subdevice = 0x7350,
- .driver_data = SAA7134_BOARD_RTD_VFG7350,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1435,
- .subdevice = 0x7330,
- .driver_data = SAA7134_BOARD_RTD_VFG7330,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461,
- .subdevice = 0x1044,
- .driver_data = SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1131,
- .subdevice = 0x4ee9,
- .driver_data = SAA7134_BOARD_MONSTERTV_MOBILE,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x11bd,
- .subdevice = 0x002e,
- .driver_data = SAA7134_BOARD_PINNACLE_PCTV_110i,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1043,
- .subdevice = 0x4862,
- .driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2018,
- .driver_data = SAA7134_BOARD_PHILIPS_TIGER,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1462,
- .subdevice = 0x6231, /* tda8275a, ks003 IR */
- .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1462,
- .subdevice = 0x8624, /* tda8275, ks003 IR */
- .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x153b,
- .subdevice = 0x1160,
- .driver_data = SAA7134_BOARD_CINERGY250PCI,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA 7131E */
- .subvendor = 0x5168,
- .subdevice = 0x0319,
- .driver_data = SAA7134_BOARD_FLYDVB_TRIO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461,
- .subdevice = 0x2c05,
- .driver_data = SAA7134_BOARD_AVERMEDIA_777,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5168,
- .subdevice = 0x0301,
- .driver_data = SAA7134_BOARD_FLYDVBT_LR301,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0331,
- .subdevice = 0x1421,
- .driver_data = SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x17de,
- .subdevice = 0x7201,
- .driver_data = SAA7134_BOARD_TEVION_DVBT_220RF,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x17de,
- .subdevice = 0x7250,
- .driver_data = SAA7134_BOARD_KWORLD_DVBT_210,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
- .subvendor = 0x17de,
- .subdevice = 0x7350,
- .driver_data = SAA7134_BOARD_KWORLD_ATSC110,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
- .subvendor = 0x17de,
- .subdevice = 0x7352,
- .driver_data = SAA7134_BOARD_KWORLD_ATSC110, /* ATSC 115 */
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
- .subvendor = 0x17de,
- .subdevice = 0xa134,
- .driver_data = SAA7134_BOARD_KWORLD_PC150U,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461,
- .subdevice = 0x7360,
- .driver_data = SAA7134_BOARD_AVERMEDIA_A169_B,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461,
- .subdevice = 0x6360,
- .driver_data = SAA7134_BOARD_AVERMEDIA_A169_B1,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x16be,
- .subdevice = 0x0005,
- .driver_data = SAA7134_BOARD_MD7134_BRIDGE_2,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5168,
- .subdevice = 0x0300,
- .driver_data = SAA7134_BOARD_FLYDVBS_LR300,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x4e42,
- .subdevice = 0x0300,/* LR300 */
- .driver_data = SAA7134_BOARD_FLYDVBS_LR300,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1489,
- .subdevice = 0x0301,
- .driver_data = SAA7134_BOARD_FLYDVBT_LR301,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168, /* Animation Technologies (LifeView) */
- .subdevice = 0x0304,
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168,
- .subdevice = 0x3306,
- .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168,
- .subdevice = 0x3502, /* whats the difference to 0x3306 ?*/
- .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168,
- .subdevice = 0x3307, /* FlyDVB-T Hybrid Mini PCI */
- .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x16be,
- .subdevice = 0x0007,
- .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x16be,
- .subdevice = 0x0008,
- .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x16be,
- .subdevice = 0x000d, /* triple CTX948_V1.1.1 */
- .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461,
- .subdevice = 0x2c05,
- .driver_data = SAA7134_BOARD_AVERMEDIA_777,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1489,
- .subdevice = 0x0502, /* Cardbus version */
- .driver_data = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x0919, /* Philips Proteus PRO 2309 */
- .subdevice = 0x2003,
- .driver_data = SAA7134_BOARD_PROTEUS_2309,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461,
- .subdevice = 0x2c00,
- .driver_data = SAA7134_BOARD_AVERMEDIA_A16AR,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1043,
- .subdevice = 0x4860,
- .driver_data = SAA7134_BOARD_ASUS_EUROPA2_HYBRID,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x11bd,
- .subdevice = 0x002f,
- .driver_data = SAA7134_BOARD_PINNACLE_PCTV_310i,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x9715,
- .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa11b,
- .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507UA,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1043,
- .subdevice = 0x4876,
- .driver_data = SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6700,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6701,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6702,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6703,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6704,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6705,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6706,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1150,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6707,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6708,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1150,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6709,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x670a,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x153b,
- .subdevice = 0x1172,
- .driver_data = SAA7134_BOARD_CINERGY_HT_PCMCIA,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2342,
- .driver_data = SAA7134_BOARD_ENCORE_ENLTV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1131,
- .subdevice = 0x2341,
- .driver_data = SAA7134_BOARD_ENCORE_ENLTV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x3016,
- .subdevice = 0x2344,
- .driver_data = SAA7134_BOARD_ENCORE_ENLTV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1131,
- .subdevice = 0x230f,
- .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1a7f,
- .subdevice = 0x2008,
- .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM53,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1a7f,
- .subdevice = 0x2108,
- .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM3,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x153b,
- .subdevice = 0x1175,
- .driver_data = SAA7134_BOARD_CINERGY_HT_PCI,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf31e,
- .driver_data = SAA7134_BOARD_AVERMEDIA_M102,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x4E42, /* MSI */
- .subdevice = 0x0306, /* TV@nywhere DUO */
- .driver_data = SAA7134_BOARD_FLYDVBTDUO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1043,
- .subdevice = 0x4871,
- .driver_data = SAA7134_BOARD_ASUS_P7131_4871,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1043,
- .subdevice = 0x4857, /* REV:1.00 */
- .driver_data = SAA7134_BOARD_ASUSTeK_TIGER,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x0919, /* SinoVideo PCI 2309 Proteus (7134) */
- .subdevice = 0x2003, /* OEM cardbus */
- .driver_data = SAA7134_BOARD_SABRENT_TV_PCB05,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2304,
- .driver_data = SAA7134_BOARD_10MOONSTVMASTER3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf01d, /* AVerTV DVB-T Super 007 */
- .driver_data = SAA7134_BOARD_AVERMEDIA_SUPER_007,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x0000,
- .subdevice = 0x4016,
- .driver_data = SAA7134_BOARD_BEHOLD_401,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x0000,
- .subdevice = 0x4036,
- .driver_data = SAA7134_BOARD_BEHOLD_403,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x0000,
- .subdevice = 0x4037,
- .driver_data = SAA7134_BOARD_BEHOLD_403FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x0000,
- .subdevice = 0x4050,
- .driver_data = SAA7134_BOARD_BEHOLD_405,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x0000,
- .subdevice = 0x4051,
- .driver_data = SAA7134_BOARD_BEHOLD_405FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x0000,
- .subdevice = 0x4070,
- .driver_data = SAA7134_BOARD_BEHOLD_407,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x0000,
- .subdevice = 0x4071,
- .driver_data = SAA7134_BOARD_BEHOLD_407FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0000,
- .subdevice = 0x4090,
- .driver_data = SAA7134_BOARD_BEHOLD_409,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x0000,
- .subdevice = 0x505B,
- .driver_data = SAA7134_BOARD_BEHOLD_505RDS_MK5,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x0000,
- .subdevice = 0x5051,
- .driver_data = SAA7134_BOARD_BEHOLD_505RDS_MK3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x5ace,
- .subdevice = 0x5050,
- .driver_data = SAA7134_BOARD_BEHOLD_505FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0000,
- .subdevice = 0x5071,
- .driver_data = SAA7134_BOARD_BEHOLD_507RDS_MK3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0000,
- .subdevice = 0x507B,
- .driver_data = SAA7134_BOARD_BEHOLD_507RDS_MK5,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5ace,
- .subdevice = 0x5070,
- .driver_data = SAA7134_BOARD_BEHOLD_507_9FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x5090,
- .driver_data = SAA7134_BOARD_BEHOLD_507_9FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0000,
- .subdevice = 0x5201,
- .driver_data = SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5ace,
- .subdevice = 0x6070,
- .driver_data = SAA7134_BOARD_BEHOLD_607FM_MK3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5ace,
- .subdevice = 0x6071,
- .driver_data = SAA7134_BOARD_BEHOLD_607FM_MK5,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5ace,
- .subdevice = 0x6072,
- .driver_data = SAA7134_BOARD_BEHOLD_607RDS_MK3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5ace,
- .subdevice = 0x6073,
- .driver_data = SAA7134_BOARD_BEHOLD_607RDS_MK5,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6090,
- .driver_data = SAA7134_BOARD_BEHOLD_609FM_MK3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6091,
- .driver_data = SAA7134_BOARD_BEHOLD_609FM_MK5,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6092,
- .driver_data = SAA7134_BOARD_BEHOLD_609RDS_MK3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6093,
- .driver_data = SAA7134_BOARD_BEHOLD_609RDS_MK5,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6190,
- .driver_data = SAA7134_BOARD_BEHOLD_M6,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6193,
- .driver_data = SAA7134_BOARD_BEHOLD_M6_EXTRA,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6191,
- .driver_data = SAA7134_BOARD_BEHOLD_M63,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x4e42,
- .subdevice = 0x3502,
- .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1822, /*Twinhan Technology Co. Ltd*/
- .subdevice = 0x0022,
- .driver_data = SAA7134_BOARD_TWINHAN_DTV_DVB_3056,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x16be,
- .subdevice = 0x0010, /* Medion version CTX953_V.1.4.3 */
- .driver_data = SAA7134_BOARD_CREATIX_CTX953,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1462, /* MSI */
- .subdevice = 0x8625, /* TV@nywhere A/D v1.1 */
- .driver_data = SAA7134_BOARD_MSI_TVANYWHERE_AD11,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf436,
- .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS_506,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf936,
- .driver_data = SAA7134_BOARD_AVERMEDIA_A16D,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa836,
- .driver_data = SAA7134_BOARD_AVERMEDIA_M115,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x185b,
- .subdevice = 0xc900,
- .driver_data = SAA7134_BOARD_VIDEOMATE_T750,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
- .subvendor = 0x1421,
- .subdevice = 0x0380,
- .driver_data = SAA7134_BOARD_ADS_INSTANT_HDTV_PCI,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5169,
- .subdevice = 0x1502,
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6290,
- .driver_data = SAA7134_BOARD_BEHOLD_H6,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf636,
- .driver_data = SAA7134_BOARD_AVERMEDIA_M103,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf736,
- .driver_data = SAA7134_BOARD_AVERMEDIA_M103,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1043,
- .subdevice = 0x4878, /* REV:1.02G */
- .driver_data = SAA7134_BOARD_ASUSTeK_TIGER_3IN1,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1043,
- .subdevice = 0x48cd,
- .driver_data = SAA7134_BOARD_ASUSTeK_PS3_100,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x17de,
- .subdevice = 0x7128,
- .driver_data = SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x17de,
- .subdevice = 0xb136,
- .driver_data = SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf31d,
- .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x185b,
- .subdevice = 0xc900,
- .driver_data = SAA7134_BOARD_VIDEOMATE_S350,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace, /* Beholder Intl. Ltd. */
- .subdevice = 0x7595,
- .driver_data = SAA7134_BOARD_BEHOLD_X7,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x19d1, /* RoverMedia */
- .subdevice = 0x0138, /* LifeView FlyTV Prime30 OEM */
- .driver_data = SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2004,
- .driver_data = SAA7134_BOARD_ZOLID_HYBRID_PCI,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1043,
- .subdevice = 0x4847,
- .driver_data = SAA7134_BOARD_ASUS_EUROPA_HYBRID,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x107d,
- .subdevice = 0x6655,
- .driver_data = SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x13c2,
- .subdevice = 0x2804,
- .driver_data = SAA7134_BOARD_TECHNOTREND_BUDGET_T3000,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace, /* Beholder Intl. Ltd. */
- .subdevice = 0x7190,
- .driver_data = SAA7134_BOARD_BEHOLD_H7,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace, /* Beholder Intl. Ltd. */
- .subdevice = 0x7090,
- .driver_data = SAA7134_BOARD_BEHOLD_A7,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
- .subvendor = 0x185b,
- .subdevice = 0xc900,
- .driver_data = SAA7134_BOARD_VIDEOMATE_M1F,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x5030,
- .driver_data = SAA7134_BOARD_BEHOLD_503FM,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x5ace,
- .subdevice = 0x5010,
- .driver_data = SAA7134_BOARD_BEHOLD_501,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x17de,
- .subdevice = 0xd136,
- .driver_data = SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x6000,
- .subdevice = 0x0811,
- .driver_data = SAA7134_BOARD_SENSORAY811_911,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x6000,
- .subdevice = 0x0911,
- .driver_data = SAA7134_BOARD_SENSORAY811_911,
- }, {
- /* --- boards without eeprom + subsystem ID --- */
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0,
- .driver_data = SAA7134_BOARD_NOAUTO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0,
- .driver_data = SAA7134_BOARD_NOAUTO,
- },{
- /* --- default catch --- */
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- .driver_data = SAA7134_BOARD_UNKNOWN,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- .driver_data = SAA7134_BOARD_UNKNOWN,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- .driver_data = SAA7134_BOARD_UNKNOWN,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- .driver_data = SAA7134_BOARD_UNKNOWN,
- },{
- /* --- end of list --- */
- }
-};
-MODULE_DEVICE_TABLE(pci, saa7134_pci_tbl);
-
-/* ----------------------------------------------------------- */
-/* flyvideo tweaks */
-
-
-static void board_flyvideo(struct saa7134_dev *dev)
-{
- printk("%s: there are different flyvideo cards with different tuners\n"
- "%s: out there, you might have to use the tuner=<nr> insmod\n"
- "%s: option to override the default value.\n",
- dev->name, dev->name, dev->name);
-}
-
-static int saa7134_xc2028_callback(struct saa7134_dev *dev,
- int command, int arg)
-{
- switch (command) {
- case XC2028_TUNER_RESET:
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00000000);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000);
- switch (dev->board) {
- case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
- case SAA7134_BOARD_AVERMEDIA_M103:
- saa7134_set_gpio(dev, 23, 0);
- msleep(10);
- saa7134_set_gpio(dev, 23, 1);
- break;
- case SAA7134_BOARD_AVERMEDIA_A16D:
- saa7134_set_gpio(dev, 21, 0);
- msleep(10);
- saa7134_set_gpio(dev, 21, 1);
- break;
- case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
- saa7134_set_gpio(dev, 18, 0);
- msleep(10);
- saa7134_set_gpio(dev, 18, 1);
- break;
- case SAA7134_BOARD_VIDEOMATE_T750:
- saa7134_set_gpio(dev, 20, 0);
- msleep(10);
- saa7134_set_gpio(dev, 20, 1);
- break;
- }
- return 0;
- }
- return -EINVAL;
-}
-
-static int saa7134_xc5000_callback(struct saa7134_dev *dev,
- int command, int arg)
-{
- switch (dev->board) {
- case SAA7134_BOARD_BEHOLD_X7:
- case SAA7134_BOARD_BEHOLD_H7:
- case SAA7134_BOARD_BEHOLD_A7:
- if (command == XC5000_TUNER_RESET) {
- /* Down and UP pheripherial RESET pin for reset all chips */
- saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
- msleep(10);
- saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
- msleep(10);
- }
- break;
- default:
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000);
- saa_andorl(SAA7133_ANALOG_IO_SELECT >> 2, 0x02, 0x02);
- saa_andorl(SAA7134_ANALOG_IN_CTRL1 >> 2, 0x81, 0x81);
- saa_andorl(SAA7134_AUDIO_CLOCK0 >> 2, 0x03187de7, 0x03187de7);
- saa_andorl(SAA7134_AUDIO_PLL_CTRL >> 2, 0x03, 0x03);
- saa_andorl(SAA7134_AUDIO_CLOCKS_PER_FIELD0 >> 2,
- 0x0001e000, 0x0001e000);
- break;
- }
- return 0;
-}
-
-static int saa7134_tda8290_827x_callback(struct saa7134_dev *dev,
- int command, int arg)
-{
- u8 sync_control;
-
- switch (command) {
- case 0: /* switch LNA gain through GPIO 22*/
- saa7134_set_gpio(dev, 22, arg) ;
- break;
- case 1: /* vsync output at GPIO22. 50 / 60Hz */
- saa_andorb(SAA7134_VIDEO_PORT_CTRL3, 0x80, 0x80);
- saa_andorb(SAA7134_VIDEO_PORT_CTRL6, 0x0f, 0x03);
- if (arg == 1)
- sync_control = 11;
- else
- sync_control = 17;
- saa_writeb(SAA7134_VGATE_START, sync_control);
- saa_writeb(SAA7134_VGATE_STOP, sync_control + 1);
- saa_andorb(SAA7134_MISC_VGATE_MSB, 0x03, 0x00);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static inline int saa7134_tda18271_hvr11x0_toggle_agc(struct saa7134_dev *dev,
- enum tda18271_mode mode)
-{
- /* toggle AGC switch through GPIO 26 */
- switch (mode) {
- case TDA18271_ANALOG:
- saa7134_set_gpio(dev, 26, 0);
- break;
- case TDA18271_DIGITAL:
- saa7134_set_gpio(dev, 26, 1);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static inline int saa7134_kworld_sbtvd_toggle_agc(struct saa7134_dev *dev,
- enum tda18271_mode mode)
-{
- /* toggle AGC switch through GPIO 27 */
- switch (mode) {
- case TDA18271_ANALOG:
- saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x4000);
- saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x4000);
- msleep(20);
- break;
- case TDA18271_DIGITAL:
- saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x14000);
- saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x14000);
- msleep(20);
- saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x54000);
- saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x54000);
- msleep(30);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int saa7134_kworld_pc150u_toggle_agc(struct saa7134_dev *dev,
- enum tda18271_mode mode)
-{
- switch (mode) {
- case TDA18271_ANALOG:
- saa7134_set_gpio(dev, 18, 0);
- break;
- case TDA18271_DIGITAL:
- saa7134_set_gpio(dev, 18, 1);
- msleep(30);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
- int command, int arg)
-{
- int ret = 0;
-
- switch (command) {
- case TDA18271_CALLBACK_CMD_AGC_ENABLE: /* 0 */
- switch (dev->board) {
- case SAA7134_BOARD_HAUPPAUGE_HVR1150:
- case SAA7134_BOARD_HAUPPAUGE_HVR1120:
- case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
- ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg);
- break;
- case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
- ret = saa7134_kworld_sbtvd_toggle_agc(dev, arg);
- break;
- case SAA7134_BOARD_KWORLD_PC150U:
- ret = saa7134_kworld_pc150u_toggle_agc(dev, arg);
- break;
- default:
- break;
- }
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
-static int saa7134_tda8290_callback(struct saa7134_dev *dev,
- int command, int arg)
-{
- int ret;
-
- switch (dev->board) {
- case SAA7134_BOARD_HAUPPAUGE_HVR1150:
- case SAA7134_BOARD_HAUPPAUGE_HVR1120:
- case SAA7134_BOARD_AVERMEDIA_M733A:
- case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
- case SAA7134_BOARD_KWORLD_PC150U:
- case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
- /* tda8290 + tda18271 */
- ret = saa7134_tda8290_18271_callback(dev, command, arg);
- break;
- default:
- /* tda8290 + tda827x */
- ret = saa7134_tda8290_827x_callback(dev, command, arg);
- break;
- }
- return ret;
-}
-
-int saa7134_tuner_callback(void *priv, int component, int command, int arg)
-{
- struct saa7134_dev *dev = priv;
-
- if (dev != NULL) {
- switch (dev->tuner_type) {
- case TUNER_PHILIPS_TDA8290:
- return saa7134_tda8290_callback(dev, command, arg);
- case TUNER_XC2028:
- return saa7134_xc2028_callback(dev, command, arg);
- case TUNER_XC5000:
- return saa7134_xc5000_callback(dev, command, arg);
- }
- } else {
- printk(KERN_ERR "saa7134: Error - device struct undefined.\n");
- return -EINVAL;
- }
- return -EINVAL;
-}
-EXPORT_SYMBOL(saa7134_tuner_callback);
-
-/* ----------------------------------------------------------- */
-
-static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data)
-{
- struct tveeprom tv;
-
- tveeprom_hauppauge_analog(&dev->i2c_client, &tv, eeprom_data);
-
- /* Make sure we support the board model */
- switch (tv.model) {
- case 67019: /* WinTV-HVR1110 (Retail, IR Blaster, hybrid, FM, SVid/Comp, 3.5mm audio in) */
- case 67109: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */
- case 67201: /* WinTV-HVR1150 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */
- case 67301: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */
- case 67209: /* WinTV-HVR1110 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */
- case 67559: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
- case 67569: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM) */
- case 67579: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM) */
- case 67589: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */
- case 67599: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */
- case 67651: /* WinTV-HVR1150 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
- case 67659: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
- break;
- default:
- printk(KERN_WARNING "%s: warning: "
- "unknown hauppauge model #%d\n", dev->name, tv.model);
- break;
- }
-
- printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n",
- dev->name, tv.model);
-}
-
-/* ----------------------------------------------------------- */
-
-int saa7134_board_init1(struct saa7134_dev *dev)
-{
- /* Always print gpio, often manufacturers encode tuner type and other info. */
- saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0);
- dev->gpio_value = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
- printk(KERN_INFO "%s: board init: gpio is %x\n", dev->name, dev->gpio_value);
-
- switch (dev->board) {
- case SAA7134_BOARD_FLYVIDEO2000:
- case SAA7134_BOARD_FLYVIDEO3000:
- case SAA7134_BOARD_FLYVIDEO3000_NTSC:
- dev->has_remote = SAA7134_REMOTE_GPIO;
- board_flyvideo(dev);
- break;
- case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
- case SAA7134_BOARD_FLYTVPLATINUM_FM:
- case SAA7134_BOARD_CINERGY400:
- case SAA7134_BOARD_CINERGY600:
- case SAA7134_BOARD_CINERGY600_MK3:
- case SAA7134_BOARD_ECS_TVP3XP:
- case SAA7134_BOARD_ECS_TVP3XP_4CB5:
- case SAA7134_BOARD_ECS_TVP3XP_4CB6:
- case SAA7134_BOARD_MD2819:
- case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
- case SAA7134_BOARD_KWORLD_XPERT:
- case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
- case SAA7134_BOARD_AVERMEDIA_STUDIO_505:
- case SAA7134_BOARD_AVERMEDIA_305:
- case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
- case SAA7134_BOARD_AVERMEDIA_307:
- case SAA7134_BOARD_AVERMEDIA_STUDIO_507:
- case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
- case SAA7134_BOARD_AVERMEDIA_777:
- case SAA7134_BOARD_AVERMEDIA_M135A:
-/* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */
- case SAA7134_BOARD_VIDEOMATE_TV_PVR:
- case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
- case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
- case SAA7134_BOARD_VIDEOMATE_M1F:
- case SAA7134_BOARD_VIDEOMATE_DVBT_300:
- case SAA7134_BOARD_VIDEOMATE_DVBT_200:
- case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
- case SAA7134_BOARD_MANLI_MTV001:
- case SAA7134_BOARD_MANLI_MTV002:
- case SAA7134_BOARD_BEHOLD_409FM:
- case SAA7134_BOARD_AVACSSMARTTV:
- case SAA7134_BOARD_GOTVIEW_7135:
- case SAA7134_BOARD_KWORLD_TERMINATOR:
- case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
- case SAA7134_BOARD_FLYDVBT_LR301:
- case SAA7134_BOARD_ASUSTeK_PS3_100:
- case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
- case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
- case SAA7134_BOARD_ASUSTeK_P7131_ANALOG:
- case SAA7134_BOARD_FLYDVBTDUO:
- case SAA7134_BOARD_PROTEUS_2309:
- case SAA7134_BOARD_AVERMEDIA_A16AR:
- case SAA7134_BOARD_ENCORE_ENLTV:
- case SAA7134_BOARD_ENCORE_ENLTV_FM:
- case SAA7134_BOARD_ENCORE_ENLTV_FM53:
- case SAA7134_BOARD_ENCORE_ENLTV_FM3:
- case SAA7134_BOARD_10MOONSTVMASTER3:
- case SAA7134_BOARD_BEHOLD_401:
- case SAA7134_BOARD_BEHOLD_403:
- case SAA7134_BOARD_BEHOLD_403FM:
- case SAA7134_BOARD_BEHOLD_405:
- case SAA7134_BOARD_BEHOLD_405FM:
- case SAA7134_BOARD_BEHOLD_407:
- case SAA7134_BOARD_BEHOLD_407FM:
- case SAA7134_BOARD_BEHOLD_409:
- case SAA7134_BOARD_BEHOLD_505FM:
- case SAA7134_BOARD_BEHOLD_505RDS_MK5:
- case SAA7134_BOARD_BEHOLD_505RDS_MK3:
- case SAA7134_BOARD_BEHOLD_507_9FM:
- case SAA7134_BOARD_BEHOLD_507RDS_MK3:
- case SAA7134_BOARD_BEHOLD_507RDS_MK5:
- case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
- case SAA7134_BOARD_REAL_ANGEL_220:
- case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
- case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
- case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM:
- case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
- dev->has_remote = SAA7134_REMOTE_GPIO;
- break;
- case SAA7134_BOARD_FLYDVBS_LR300:
- saa_writeb(SAA7134_GPIO_GPMODE3, 0x80);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x40);
- dev->has_remote = SAA7134_REMOTE_GPIO;
- break;
- case SAA7134_BOARD_MD5044:
- printk("%s: seems there are two different versions of the MD5044\n"
- "%s: (with the same ID) out there. If sound doesn't work for\n"
- "%s: you try the audio_clock_override=0x200000 insmod option.\n",
- dev->name,dev->name,dev->name);
- break;
- case SAA7134_BOARD_CINERGY400_CARDBUS:
- /* power-up tuner chip */
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
- break;
- case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
- /* this turns the remote control chip off to work around a bug in it */
- saa_writeb(SAA7134_GPIO_GPMODE1, 0x80);
- saa_writeb(SAA7134_GPIO_GPSTATUS1, 0x80);
- break;
- case SAA7134_BOARD_MONSTERTV_MOBILE:
- /* power-up tuner chip */
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004);
- break;
- case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
- /* turn the fan on */
- saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
- saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06);
- break;
- case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
- case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x08000000, 0x08000000);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08000000, 0x00000000);
- break;
- case SAA7134_BOARD_AVERMEDIA_CARDBUS:
- case SAA7134_BOARD_AVERMEDIA_M115:
- /* power-down tuner chip */
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0);
- msleep(10);
- /* power-up tuner chip */
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0xffffffff);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
- msleep(10);
- break;
- case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
- /* power-down tuner chip */
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x08400000, 0x08400000);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08400000, 0);
- msleep(10);
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x08400000, 0x08400000);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08400000, 0x08400000);
- msleep(10);
- dev->has_remote = SAA7134_REMOTE_I2C;
- break;
- case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
- saa7134_set_gpio(dev, 23, 0);
- msleep(10);
- saa7134_set_gpio(dev, 23, 1);
- dev->has_remote = SAA7134_REMOTE_I2C;
- break;
- case SAA7134_BOARD_AVERMEDIA_M103:
- saa7134_set_gpio(dev, 23, 0);
- msleep(10);
- saa7134_set_gpio(dev, 23, 1);
- break;
- case SAA7134_BOARD_AVERMEDIA_A16D:
- saa7134_set_gpio(dev, 21, 0);
- msleep(10);
- saa7134_set_gpio(dev, 21, 1);
- msleep(1);
- dev->has_remote = SAA7134_REMOTE_GPIO;
- break;
- case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
- /* power-down tuner chip */
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x000A8004, 0x000A8004);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x000A8004, 0);
- msleep(10);
- /* power-up tuner chip */
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x000A8004, 0x000A8004);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x000A8004, 0x000A8004);
- msleep(10);
- /* remote via GPIO */
- dev->has_remote = SAA7134_REMOTE_GPIO;
- break;
- case SAA7134_BOARD_RTD_VFG7350:
-
- /*
- * Make sure Production Test Register at offset 0x1D1 is cleared
- * to take chip out of test mode. Clearing bit 4 (TST_EN_AOUT)
- * prevents pin 105 from remaining low; keeping pin 105 low
- * continually resets the SAA6752 chip.
- */
-
- saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00);
- break;
- case SAA7134_BOARD_HAUPPAUGE_HVR1150:
- case SAA7134_BOARD_HAUPPAUGE_HVR1120:
- dev->has_remote = SAA7134_REMOTE_GPIO;
- /* GPIO 26 high for digital, low for analog */
- saa7134_set_gpio(dev, 26, 0);
- msleep(1);
-
- saa7134_set_gpio(dev, 22, 0);
- msleep(10);
- saa7134_set_gpio(dev, 22, 1);
- break;
- /* i2c remotes */
- case SAA7134_BOARD_PINNACLE_PCTV_110i:
- case SAA7134_BOARD_PINNACLE_PCTV_310i:
- case SAA7134_BOARD_UPMOST_PURPLE_TV:
- case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
- case SAA7134_BOARD_HAUPPAUGE_HVR1110:
- case SAA7134_BOARD_BEHOLD_607FM_MK3:
- case SAA7134_BOARD_BEHOLD_607FM_MK5:
- case SAA7134_BOARD_BEHOLD_609FM_MK3:
- case SAA7134_BOARD_BEHOLD_609FM_MK5:
- case SAA7134_BOARD_BEHOLD_607RDS_MK3:
- case SAA7134_BOARD_BEHOLD_607RDS_MK5:
- case SAA7134_BOARD_BEHOLD_609RDS_MK3:
- case SAA7134_BOARD_BEHOLD_609RDS_MK5:
- case SAA7134_BOARD_BEHOLD_M6:
- case SAA7134_BOARD_BEHOLD_M63:
- case SAA7134_BOARD_BEHOLD_M6_EXTRA:
- case SAA7134_BOARD_BEHOLD_H6:
- case SAA7134_BOARD_BEHOLD_X7:
- case SAA7134_BOARD_BEHOLD_H7:
- case SAA7134_BOARD_BEHOLD_A7:
- case SAA7134_BOARD_KWORLD_PC150U:
- dev->has_remote = SAA7134_REMOTE_I2C;
- break;
- case SAA7134_BOARD_AVERMEDIA_A169_B:
- printk("%s: %s: dual saa713x broadcast decoders\n"
- "%s: Sorry, none of the inputs to this chip are supported yet.\n"
- "%s: Dual decoder functionality is disabled for now, use the other chip.\n",
- dev->name,card(dev).name,dev->name,dev->name);
- break;
- case SAA7134_BOARD_AVERMEDIA_M102:
- /* enable tuner */
- dev->has_remote = SAA7134_REMOTE_GPIO;
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x8c040007, 0x8c040007);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0c0007cd, 0x0c0007cd);
- break;
- case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
- case SAA7134_BOARD_AVERMEDIA_A700_PRO:
- /* write windows gpio values */
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x80040100, 0x80040100);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100);
- break;
- case SAA7134_BOARD_VIDEOMATE_S350:
- dev->has_remote = SAA7134_REMOTE_GPIO;
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0000C000, 0x0000C000);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0000C000, 0x0000C000);
- break;
- case SAA7134_BOARD_AVERMEDIA_M733A:
- saa7134_set_gpio(dev, 1, 1);
- msleep(10);
- saa7134_set_gpio(dev, 1, 0);
- msleep(10);
- saa7134_set_gpio(dev, 1, 1);
- dev->has_remote = SAA7134_REMOTE_GPIO;
- break;
- case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
- /* enable LGS-8G75 */
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0e050000, 0x0c050000);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0e050000, 0x0c050000);
- break;
- case SAA7134_BOARD_VIDEOMATE_T750:
- /* enable the analog tuner */
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00008000, 0x00008000);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000);
- break;
- }
- return 0;
-}
-
-static void saa7134_tuner_setup(struct saa7134_dev *dev)
-{
- struct tuner_setup tun_setup;
- unsigned int mode_mask = T_RADIO | T_ANALOG_TV;
-
- memset(&tun_setup, 0, sizeof(tun_setup));
- tun_setup.tuner_callback = saa7134_tuner_callback;
-
- if (saa7134_boards[dev->board].radio_type != UNSET) {
- tun_setup.type = saa7134_boards[dev->board].radio_type;
- tun_setup.addr = saa7134_boards[dev->board].radio_addr;
-
- tun_setup.mode_mask = T_RADIO;
-
- saa_call_all(dev, tuner, s_type_addr, &tun_setup);
- mode_mask &= ~T_RADIO;
- }
-
- if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type != UNSET)) {
- tun_setup.type = dev->tuner_type;
- tun_setup.addr = dev->tuner_addr;
- tun_setup.config = saa7134_boards[dev->board].tuner_config;
- tun_setup.tuner_callback = saa7134_tuner_callback;
-
- tun_setup.mode_mask = mode_mask;
-
- saa_call_all(dev, tuner, s_type_addr, &tun_setup);
- }
-
- if (dev->tda9887_conf) {
- struct v4l2_priv_tun_config tda9887_cfg;
-
- tda9887_cfg.tuner = TUNER_TDA9887;
- tda9887_cfg.priv = &dev->tda9887_conf;
-
- saa_call_all(dev, tuner, s_config, &tda9887_cfg);
- }
-
- if (dev->tuner_type == TUNER_XC2028) {
- struct v4l2_priv_tun_config xc2028_cfg;
- struct xc2028_ctrl ctl;
-
- memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
- memset(&ctl, 0, sizeof(ctl));
-
- ctl.fname = XC2028_DEFAULT_FIRMWARE;
- ctl.max_len = 64;
-
- switch (dev->board) {
- case SAA7134_BOARD_AVERMEDIA_A16D:
- case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
- case SAA7134_BOARD_AVERMEDIA_M103:
- case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
- ctl.demod = XC3028_FE_ZARLINK456;
- break;
- default:
- ctl.demod = XC3028_FE_OREN538;
- ctl.mts = 1;
- }
-
- xc2028_cfg.tuner = TUNER_XC2028;
- xc2028_cfg.priv = &ctl;
-
- saa_call_all(dev, tuner, s_config, &xc2028_cfg);
- }
-}
-
-/* stuff which needs working i2c */
-int saa7134_board_init2(struct saa7134_dev *dev)
-{
- unsigned char buf;
- int board;
-
- /* Put here the code that enables the chips that are needed
- for analog mode and doesn't depend on the tuner attachment.
- It is also a good idea to get tuner type from eeprom, etc before
- initializing tuner, since we can avoid loading tuner driver
- on devices that has TUNER_ABSENT
- */
- switch (dev->board) {
- case SAA7134_BOARD_BMK_MPEX_NOTUNER:
- case SAA7134_BOARD_BMK_MPEX_TUNER:
- /* Checks if the device has a tuner at 0x60 addr
- If the device doesn't have a tuner, TUNER_ABSENT
- will be used at tuner_type, avoiding loading tuner
- without needing it
- */
- dev->i2c_client.addr = 0x60;
- board = (i2c_master_recv(&dev->i2c_client, &buf, 0) < 0)
- ? SAA7134_BOARD_BMK_MPEX_NOTUNER
- : SAA7134_BOARD_BMK_MPEX_TUNER;
- if (board == dev->board)
- break;
- dev->board = board;
- printk("%s: board type fixup: %s\n", dev->name,
- saa7134_boards[dev->board].name);
- dev->tuner_type = saa7134_boards[dev->board].tuner_type;
-
- break;
- case SAA7134_BOARD_MD7134:
- {
- u8 subaddr;
- u8 data[3];
- int ret, tuner_t;
- struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, .len = 1},
- {.addr=0x50, .flags=I2C_M_RD, .buf=data, .len = 3}};
-
- subaddr= 0x14;
- tuner_t = 0;
-
- /* Retrieve device data from eeprom, checking for the
- proper tuner_type.
- */
- ret = i2c_transfer(&dev->i2c_adap, msg, 2);
- if (ret != 2) {
- printk(KERN_ERR "EEPROM read failure\n");
- } else if ((data[0] != 0) && (data[0] != 0xff)) {
- /* old config structure */
- subaddr = data[0] + 2;
- msg[1].len = 2;
- i2c_transfer(&dev->i2c_adap, msg, 2);
- tuner_t = (data[0] << 8) + data[1];
- switch (tuner_t){
- case 0x0103:
- dev->tuner_type = TUNER_PHILIPS_PAL;
- break;
- case 0x010C:
- dev->tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
- break;
- default:
- printk(KERN_ERR "%s Can't determine tuner type %x from EEPROM\n", dev->name, tuner_t);
- }
- } else if ((data[1] != 0) && (data[1] != 0xff)) {
- /* new config structure */
- subaddr = data[1] + 1;
- msg[1].len = 1;
- i2c_transfer(&dev->i2c_adap, msg, 2);
- subaddr = data[0] + 1;
- msg[1].len = 2;
- i2c_transfer(&dev->i2c_adap, msg, 2);
- tuner_t = (data[1] << 8) + data[0];
- switch (tuner_t) {
- case 0x0005:
- dev->tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
- break;
- case 0x001d:
- dev->tuner_type = TUNER_PHILIPS_FMD1216ME_MK3;
- printk(KERN_INFO "%s Board has DVB-T\n", dev->name);
- break;
- default:
- printk(KERN_ERR "%s Can't determine tuner type %x from EEPROM\n", dev->name, tuner_t);
- }
- } else {
- printk(KERN_ERR "%s unexpected config structure\n", dev->name);
- }
-
- printk(KERN_INFO "%s Tuner type is %d\n", dev->name, dev->tuner_type);
- break;
- }
- case SAA7134_BOARD_PHILIPS_EUROPA:
- if (dev->autodetected && (dev->eedata[0x41] == 0x1c)) {
- /* Reconfigure board as Snake reference design */
- dev->board = SAA7134_BOARD_PHILIPS_SNAKE;
- dev->tuner_type = saa7134_boards[dev->board].tuner_type;
- printk(KERN_INFO "%s: Reconfigured board as %s\n",
- dev->name, saa7134_boards[dev->board].name);
- break;
- }
- /* break intentionally omitted */
- case SAA7134_BOARD_VIDEOMATE_DVBT_300:
- case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
- case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
- case SAA7134_BOARD_TECHNOTREND_BUDGET_T3000:
- {
-
- /* The Philips EUROPA based hybrid boards have the tuner
- connected through the channel decoder. We have to make it
- transparent to find it
- */
- u8 data[] = { 0x07, 0x02};
- struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
- i2c_transfer(&dev->i2c_adap, &msg, 1);
-
- break;
- }
- case SAA7134_BOARD_PHILIPS_TIGER:
- case SAA7134_BOARD_PHILIPS_TIGER_S:
- {
- u8 data[] = { 0x3c, 0x33, 0x60};
- struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
- if (dev->autodetected && (dev->eedata[0x49] == 0x50)) {
- dev->board = SAA7134_BOARD_PHILIPS_TIGER_S;
- printk(KERN_INFO "%s: Reconfigured board as %s\n",
- dev->name, saa7134_boards[dev->board].name);
- }
- if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
- dev->tuner_type = TUNER_PHILIPS_TDA8290;
-
- data[2] = 0x68;
- i2c_transfer(&dev->i2c_adap, &msg, 1);
- break;
- }
- i2c_transfer(&dev->i2c_adap, &msg, 1);
- break;
- }
- case SAA7134_BOARD_ASUSTeK_TVFM7135:
- /* The card below is detected as card=53, but is different */
- if (dev->autodetected && (dev->eedata[0x27] == 0x03)) {
- dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG;
- printk(KERN_INFO "%s: P7131 analog only, using "
- "entry of %s\n",
- dev->name, saa7134_boards[dev->board].name);
-
- /* IR init has already happened for other cards, so
- * we have to catch up. */
- dev->has_remote = SAA7134_REMOTE_GPIO;
- saa7134_input_init1(dev);
- }
- break;
- case SAA7134_BOARD_HAUPPAUGE_HVR1150:
- case SAA7134_BOARD_HAUPPAUGE_HVR1120:
- hauppauge_eeprom(dev, dev->eedata+0x80);
- break;
- case SAA7134_BOARD_HAUPPAUGE_HVR1110:
- hauppauge_eeprom(dev, dev->eedata+0x80);
- /* break intentionally omitted */
- case SAA7134_BOARD_PINNACLE_PCTV_310i:
- case SAA7134_BOARD_KWORLD_DVBT_210:
- case SAA7134_BOARD_TEVION_DVBT_220RF:
- case SAA7134_BOARD_ASUSTeK_TIGER:
- case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
- case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
- case SAA7134_BOARD_MEDION_MD8800_QUADRO:
- case SAA7134_BOARD_AVERMEDIA_SUPER_007:
- case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
- case SAA7134_BOARD_CREATIX_CTX953:
- {
- /* this is a hybrid board, initialize to analog mode
- * and configure firmware eeprom address
- */
- u8 data[] = { 0x3c, 0x33, 0x60};
- struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
- i2c_transfer(&dev->i2c_adap, &msg, 1);
- break;
- }
- case SAA7134_BOARD_ASUSTeK_TIGER_3IN1:
- {
- u8 data[] = { 0x3c, 0x33, 0x60};
- struct i2c_msg msg = {.addr = 0x0b, .flags = 0, .buf = data,
- .len = sizeof(data)};
- i2c_transfer(&dev->i2c_adap, &msg, 1);
- break;
- }
- case SAA7134_BOARD_ASUSTeK_PS3_100:
- {
- u8 data[] = { 0x3c, 0x33, 0x60};
- struct i2c_msg msg = {.addr = 0x0b, .flags = 0, .buf = data,
- .len = sizeof(data)};
- i2c_transfer(&dev->i2c_adap, &msg, 1);
- break;
- }
- case SAA7134_BOARD_FLYDVB_TRIO:
- {
- u8 temp = 0;
- int rc;
- u8 data[] = { 0x3c, 0x33, 0x62};
- struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)};
- i2c_transfer(&dev->i2c_adap, &msg, 1);
-
- /*
- * send weak up message to pic16C505 chip
- * @ LifeView FlyDVB Trio
- */
- msg.buf = &temp;
- msg.addr = 0x0b;
- msg.len = 1;
- if (1 != i2c_transfer(&dev->i2c_adap, &msg, 1)) {
- printk(KERN_WARNING "%s: send wake up byte to pic16C505"
- "(IR chip) failed\n", dev->name);
- } else {
- msg.flags = I2C_M_RD;
- rc = i2c_transfer(&dev->i2c_adap, &msg, 1);
- printk(KERN_INFO "%s: probe IR chip @ i2c 0x%02x: %s\n",
- dev->name, msg.addr,
- (1 == rc) ? "yes" : "no");
- if (rc == 1)
- dev->has_remote = SAA7134_REMOTE_I2C;
- }
- break;
- }
- case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
- case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
- {
- /* initialize analog mode */
- u8 data[] = { 0x3c, 0x33, 0x6a};
- struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
- i2c_transfer(&dev->i2c_adap, &msg, 1);
- break;
- }
- case SAA7134_BOARD_CINERGY_HT_PCMCIA:
- case SAA7134_BOARD_CINERGY_HT_PCI:
- {
- /* initialize analog mode */
- u8 data[] = { 0x3c, 0x33, 0x68};
- struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
- i2c_transfer(&dev->i2c_adap, &msg, 1);
- break;
- }
- case SAA7134_BOARD_VIDEOMATE_DVBT_200:
- case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
- /* The T200 and the T200A share the same pci id. Consequently,
- * we are going to query eeprom to try to find out which one we
- * are actually looking at. */
-
- /* Don't do this if the board was specifically selected with an
- * insmod option or if we have the default configuration T200*/
- if (!dev->autodetected || (dev->eedata[0x41] == 0xd0))
- break;
- if (dev->eedata[0x41] == 0x02) {
- /* Reconfigure board as T200A */
- dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A;
- dev->tuner_type = saa7134_boards[dev->board].tuner_type;
- dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
- printk(KERN_INFO "%s: Reconfigured board as %s\n",
- dev->name, saa7134_boards[dev->board].name);
- } else {
- printk(KERN_WARNING "%s: Unexpected tuner type info: %x in eeprom\n",
- dev->name, dev->eedata[0x41]);
- break;
- }
- break;
- case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
- case SAA7134_BOARD_KWORLD_ATSC110:
- {
- struct i2c_msg msg = { .addr = 0x0a, .flags = 0 };
- int i;
- static u8 buffer[][2] = {
- { 0x10, 0x12 },
- { 0x13, 0x04 },
- { 0x16, 0x00 },
- { 0x14, 0x04 },
- { 0x17, 0x00 },
- };
-
- for (i = 0; i < ARRAY_SIZE(buffer); i++) {
- msg.buf = &buffer[i][0];
- msg.len = ARRAY_SIZE(buffer[0]);
- if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
- printk(KERN_WARNING
- "%s: Unable to enable tuner(%i).\n",
- dev->name, i);
- }
- break;
- }
- case SAA7134_BOARD_BEHOLD_H6:
- {
- u8 data[] = { 0x09, 0x9f, 0x86, 0x11};
- struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = data,
- .len = sizeof(data)};
-
- /* The tuner TUNER_PHILIPS_FMD1216MEX_MK3 after hardware */
- /* start has disabled IF and enabled DVB-T. When saa7134 */
- /* scan I2C devices it not detect IF tda9887 and can`t */
- /* watch TV without software reboot. For solve this problem */
- /* switch the tuner to analog TV mode manually. */
- if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
- printk(KERN_WARNING
- "%s: Unable to enable IF of the tuner.\n",
- dev->name);
- break;
- }
- case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
- saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x4000);
- saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x4000);
-
- saa7134_set_gpio(dev, 27, 0);
- break;
- } /* switch() */
-
- /* initialize tuner */
- if (TUNER_ABSENT != dev->tuner_type) {
- int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
-
- /* Note: radio tuner address is always filled in,
- so we do not need to probe for a radio tuner device. */
- if (dev->radio_type != UNSET)
- v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, "tuner",
- dev->radio_addr, NULL);
- if (has_demod)
- v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, "tuner",
- 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
- if (dev->tuner_addr == ADDR_UNSET) {
- enum v4l2_i2c_tuner_type type =
- has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
-
- v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, "tuner",
- 0, v4l2_i2c_tuner_addrs(type));
- } else {
- v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, "tuner",
- dev->tuner_addr, NULL);
- }
- }
-
- saa7134_tuner_setup(dev);
-
- switch (dev->board) {
- case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
- case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
- {
- struct v4l2_priv_tun_config tea5767_cfg;
- struct tea5767_ctrl ctl;
-
- dev->i2c_client.addr = 0xC0;
- /* set TEA5767(analog FM) defines */
- memset(&ctl, 0, sizeof(ctl));
- ctl.xtal_freq = TEA5767_HIGH_LO_13MHz;
- tea5767_cfg.tuner = TUNER_TEA5767;
- tea5767_cfg.priv = &ctl;
- saa_call_all(dev, tuner, s_config, &tea5767_cfg);
- break;
- }
- } /* switch() */
-
- return 0;
-}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
deleted file mode 100644
index f2b37e05b96..00000000000
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ /dev/null
@@ -1,1368 +0,0 @@
-/*
- *
- * device driver for philips saa7134 based TV cards
- * driver core
- *
- * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/kmod.h>
-#include <linux/sound.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/dma-mapping.h>
-#include <linux/pm.h>
-
-#include "saa7134-reg.h"
-#include "saa7134.h"
-
-MODULE_DESCRIPTION("v4l2 driver module for saa7130/34 based TV cards");
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(SAA7134_VERSION);
-
-
-/* ------------------------------------------------------------------ */
-
-static unsigned int irq_debug;
-module_param(irq_debug, int, 0644);
-MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]");
-
-static unsigned int core_debug;
-module_param(core_debug, int, 0644);
-MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
-
-static unsigned int gpio_tracking;
-module_param(gpio_tracking, int, 0644);
-MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]");
-
-static unsigned int alsa = 1;
-module_param(alsa, int, 0644);
-MODULE_PARM_DESC(alsa,"enable/disable ALSA DMA sound [dmasound]");
-
-static unsigned int latency = UNSET;
-module_param(latency, int, 0444);
-MODULE_PARM_DESC(latency,"pci latency timer");
-
-int saa7134_no_overlay=-1;
-module_param_named(no_overlay, saa7134_no_overlay, int, 0444);
-MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)"
- " [some VIA/SIS chipsets are known to have problem with overlay]");
-
-static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
-static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
-static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
-static unsigned int tuner[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
-static unsigned int card[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
-
-
-module_param_array(video_nr, int, NULL, 0444);
-module_param_array(vbi_nr, int, NULL, 0444);
-module_param_array(radio_nr, int, NULL, 0444);
-module_param_array(tuner, int, NULL, 0444);
-module_param_array(card, int, NULL, 0444);
-
-MODULE_PARM_DESC(video_nr, "video device number");
-MODULE_PARM_DESC(vbi_nr, "vbi device number");
-MODULE_PARM_DESC(radio_nr, "radio device number");
-MODULE_PARM_DESC(tuner, "tuner type");
-MODULE_PARM_DESC(card, "card type");
-
-DEFINE_MUTEX(saa7134_devlist_lock);
-EXPORT_SYMBOL(saa7134_devlist_lock);
-LIST_HEAD(saa7134_devlist);
-EXPORT_SYMBOL(saa7134_devlist);
-static LIST_HEAD(mops_list);
-static unsigned int saa7134_devcount;
-
-int (*saa7134_dmasound_init)(struct saa7134_dev *dev);
-int (*saa7134_dmasound_exit)(struct saa7134_dev *dev);
-
-#define dprintk(fmt, arg...) if (core_debug) \
- printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg)
-
-void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
-{
- unsigned long mode,status;
-
- if (!gpio_tracking)
- return;
- /* rising SAA7134_GPIO_GPRESCAN reads the status */
- saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,0);
- saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,SAA7134_GPIO_GPRESCAN);
- mode = saa_readl(SAA7134_GPIO_GPMODE0 >> 2) & 0xfffffff;
- status = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & 0xfffffff;
- printk(KERN_DEBUG
- "%s: gpio: mode=0x%07lx in=0x%07lx out=0x%07lx [%s]\n",
- dev->name, mode, (~mode) & status, mode & status, msg);
-}
-
-void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value)
-{
- u32 index, bitval;
-
- index = 1 << bit_no;
- switch (value) {
- case 0: /* static value */
- case 1: dprintk("setting GPIO%d to static %d\n", bit_no, value);
- /* turn sync mode off if necessary */
- if (index & 0x00c00000)
- saa_andorb(SAA7134_VIDEO_PORT_CTRL6, 0x0f, 0x00);
- if (value)
- bitval = index;
- else
- bitval = 0;
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, index, index);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, index, bitval);
- break;
- case 3: /* tristate */
- dprintk("setting GPIO%d to tristate\n", bit_no);
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, index, 0);
- break;
- }
-}
-
-/* ------------------------------------------------------------------ */
-
-
-/* ----------------------------------------------------------- */
-/* delayed request_module */
-
-#if defined(CONFIG_MODULES) && defined(MODULE)
-
-static void request_module_async(struct work_struct *work){
- struct saa7134_dev* dev = container_of(work, struct saa7134_dev, request_module_wk);
- if (card_is_empress(dev))
- request_module("saa7134-empress");
- if (card_is_dvb(dev))
- request_module("saa7134-dvb");
- if (alsa) {
- if (dev->pci->device != PCI_DEVICE_ID_PHILIPS_SAA7130)
- request_module("saa7134-alsa");
- }
-}
-
-static void request_submodules(struct saa7134_dev *dev)
-{
- INIT_WORK(&dev->request_module_wk, request_module_async);
- schedule_work(&dev->request_module_wk);
-}
-
-static void flush_request_submodules(struct saa7134_dev *dev)
-{
- flush_work(&dev->request_module_wk);
-}
-
-#else
-#define request_submodules(dev)
-#define flush_request_submodules(dev)
-#endif /* CONFIG_MODULES */
-
-/* ------------------------------------------------------------------ */
-
-/* nr of (saa7134-)pages for the given buffer size */
-static int saa7134_buffer_pages(int size)
-{
- size = PAGE_ALIGN(size);
- size += PAGE_SIZE; /* for non-page-aligned buffers */
- size /= 4096;
- return size;
-}
-
-/* calc max # of buffers from size (must not exceed the 4MB virtual
- * address space per DMA channel) */
-int saa7134_buffer_count(unsigned int size, unsigned int count)
-{
- unsigned int maxcount;
-
- maxcount = 1024 / saa7134_buffer_pages(size);
- if (count > maxcount)
- count = maxcount;
- return count;
-}
-
-int saa7134_buffer_startpage(struct saa7134_buf *buf)
-{
- return saa7134_buffer_pages(buf->vb.bsize) * buf->vb.i;
-}
-
-unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
-{
- unsigned long base;
- struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
-
- base = saa7134_buffer_startpage(buf) * 4096;
- base += dma->sglist[0].offset;
- return base;
-}
-
-/* ------------------------------------------------------------------ */
-
-int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
-{
- __le32 *cpu;
- dma_addr_t dma_addr = 0;
-
- cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
- if (NULL == cpu)
- return -ENOMEM;
- pt->size = SAA7134_PGTABLE_SIZE;
- pt->cpu = cpu;
- pt->dma = dma_addr;
- return 0;
-}
-
-int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
- struct scatterlist *list, unsigned int length,
- unsigned int startpage)
-{
- __le32 *ptr;
- unsigned int i,p;
-
- BUG_ON(NULL == pt || NULL == pt->cpu);
-
- ptr = pt->cpu + startpage;
- for (i = 0; i < length; i++, list++)
- for (p = 0; p * 4096 < list->length; p++, ptr++)
- *ptr = cpu_to_le32(sg_dma_address(list) - list->offset);
- return 0;
-}
-
-void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt)
-{
- if (NULL == pt->cpu)
- return;
- pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
- pt->cpu = NULL;
-}
-
-/* ------------------------------------------------------------------ */
-
-void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf)
-{
- struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
- BUG_ON(in_interrupt());
-
- videobuf_waiton(q, &buf->vb, 0, 0);
- videobuf_dma_unmap(q->dev, dma);
- videobuf_dma_free(dma);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-/* ------------------------------------------------------------------ */
-
-int saa7134_buffer_queue(struct saa7134_dev *dev,
- struct saa7134_dmaqueue *q,
- struct saa7134_buf *buf)
-{
- struct saa7134_buf *next = NULL;
-
- assert_spin_locked(&dev->slock);
- dprintk("buffer_queue %p\n",buf);
- if (NULL == q->curr) {
- if (!q->need_two) {
- q->curr = buf;
- buf->activate(dev,buf,NULL);
- } else if (list_empty(&q->queue)) {
- list_add_tail(&buf->vb.queue,&q->queue);
- buf->vb.state = VIDEOBUF_QUEUED;
- } else {
- next = list_entry(q->queue.next,struct saa7134_buf,
- vb.queue);
- q->curr = buf;
- buf->activate(dev,buf,next);
- }
- } else {
- list_add_tail(&buf->vb.queue,&q->queue);
- buf->vb.state = VIDEOBUF_QUEUED;
- }
- return 0;
-}
-
-void saa7134_buffer_finish(struct saa7134_dev *dev,
- struct saa7134_dmaqueue *q,
- unsigned int state)
-{
- assert_spin_locked(&dev->slock);
- dprintk("buffer_finish %p\n",q->curr);
-
- /* finish current buffer */
- q->curr->vb.state = state;
- do_gettimeofday(&q->curr->vb.ts);
- wake_up(&q->curr->vb.done);
- q->curr = NULL;
-}
-
-void saa7134_buffer_next(struct saa7134_dev *dev,
- struct saa7134_dmaqueue *q)
-{
- struct saa7134_buf *buf,*next = NULL;
-
- assert_spin_locked(&dev->slock);
- BUG_ON(NULL != q->curr);
-
- if (!list_empty(&q->queue)) {
- /* activate next one from queue */
- buf = list_entry(q->queue.next,struct saa7134_buf,vb.queue);
- dprintk("buffer_next %p [prev=%p/next=%p]\n",
- buf,q->queue.prev,q->queue.next);
- list_del(&buf->vb.queue);
- if (!list_empty(&q->queue))
- next = list_entry(q->queue.next,struct saa7134_buf,
- vb.queue);
- q->curr = buf;
- buf->activate(dev,buf,next);
- dprintk("buffer_next #2 prev=%p/next=%p\n",
- q->queue.prev,q->queue.next);
- } else {
- /* nothing to do -- just stop DMA */
- dprintk("buffer_next %p\n",NULL);
- saa7134_set_dmabits(dev);
- del_timer(&q->timeout);
-
- if (card_has_mpeg(dev))
- if (dev->ts_started)
- saa7134_ts_stop(dev);
- }
-}
-
-void saa7134_buffer_timeout(unsigned long data)
-{
- struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue*)data;
- struct saa7134_dev *dev = q->dev;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->slock,flags);
-
- /* try to reset the hardware (SWRST) */
- saa_writeb(SAA7134_REGION_ENABLE, 0x00);
- saa_writeb(SAA7134_REGION_ENABLE, 0x80);
- saa_writeb(SAA7134_REGION_ENABLE, 0x00);
-
- /* flag current buffer as failed,
- try to start over with the next one. */
- if (q->curr) {
- dprintk("timeout on %p\n",q->curr);
- saa7134_buffer_finish(dev,q,VIDEOBUF_ERROR);
- }
- saa7134_buffer_next(dev,q);
- spin_unlock_irqrestore(&dev->slock,flags);
-}
-
-/* ------------------------------------------------------------------ */
-
-int saa7134_set_dmabits(struct saa7134_dev *dev)
-{
- u32 split, task=0, ctrl=0, irq=0;
- enum v4l2_field cap = V4L2_FIELD_ANY;
- enum v4l2_field ov = V4L2_FIELD_ANY;
-
- assert_spin_locked(&dev->slock);
-
- if (dev->insuspend)
- return 0;
-
- /* video capture -- dma 0 + video task A */
- if (dev->video_q.curr) {
- task |= 0x01;
- ctrl |= SAA7134_MAIN_CTRL_TE0;
- irq |= SAA7134_IRQ1_INTE_RA0_1 |
- SAA7134_IRQ1_INTE_RA0_0;
- cap = dev->video_q.curr->vb.field;
- }
-
- /* video capture -- dma 1+2 (planar modes) */
- if (dev->video_q.curr &&
- dev->video_q.curr->fmt->planar) {
- ctrl |= SAA7134_MAIN_CTRL_TE4 |
- SAA7134_MAIN_CTRL_TE5;
- }
-
- /* screen overlay -- dma 0 + video task B */
- if (dev->ovenable) {
- task |= 0x10;
- ctrl |= SAA7134_MAIN_CTRL_TE1;
- ov = dev->ovfield;
- }
-
- /* vbi capture -- dma 0 + vbi task A+B */
- if (dev->vbi_q.curr) {
- task |= 0x22;
- ctrl |= SAA7134_MAIN_CTRL_TE2 |
- SAA7134_MAIN_CTRL_TE3;
- irq |= SAA7134_IRQ1_INTE_RA0_7 |
- SAA7134_IRQ1_INTE_RA0_6 |
- SAA7134_IRQ1_INTE_RA0_5 |
- SAA7134_IRQ1_INTE_RA0_4;
- }
-
- /* audio capture -- dma 3 */
- if (dev->dmasound.dma_running) {
- ctrl |= SAA7134_MAIN_CTRL_TE6;
- irq |= SAA7134_IRQ1_INTE_RA3_1 |
- SAA7134_IRQ1_INTE_RA3_0;
- }
-
- /* TS capture -- dma 5 */
- if (dev->ts_q.curr) {
- ctrl |= SAA7134_MAIN_CTRL_TE5;
- irq |= SAA7134_IRQ1_INTE_RA2_1 |
- SAA7134_IRQ1_INTE_RA2_0;
- }
-
- /* set task conditions + field handling */
- if (V4L2_FIELD_HAS_BOTH(cap) || V4L2_FIELD_HAS_BOTH(ov) || cap == ov) {
- /* default config -- use full frames */
- saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);
- saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);
- saa_writeb(SAA7134_FIELD_HANDLING(TASK_A), 0x02);
- saa_writeb(SAA7134_FIELD_HANDLING(TASK_B), 0x02);
- split = 0;
- } else {
- /* split fields between tasks */
- if (V4L2_FIELD_TOP == cap) {
- /* odd A, even B, repeat */
- saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);
- saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0e);
- } else {
- /* odd B, even A, repeat */
- saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0e);
- saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);
- }
- saa_writeb(SAA7134_FIELD_HANDLING(TASK_A), 0x01);
- saa_writeb(SAA7134_FIELD_HANDLING(TASK_B), 0x01);
- split = 1;
- }
-
- /* irqs */
- saa_writeb(SAA7134_REGION_ENABLE, task);
- saa_writel(SAA7134_IRQ1, irq);
- saa_andorl(SAA7134_MAIN_CTRL,
- SAA7134_MAIN_CTRL_TE0 |
- SAA7134_MAIN_CTRL_TE1 |
- SAA7134_MAIN_CTRL_TE2 |
- SAA7134_MAIN_CTRL_TE3 |
- SAA7134_MAIN_CTRL_TE4 |
- SAA7134_MAIN_CTRL_TE5 |
- SAA7134_MAIN_CTRL_TE6,
- ctrl);
- dprintk("dmabits: task=0x%02x ctrl=0x%02x irq=0x%x split=%s\n",
- task, ctrl, irq, split ? "no" : "yes");
-
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-/* IRQ handler + helpers */
-
-static char *irqbits[] = {
- "DONE_RA0", "DONE_RA1", "DONE_RA2", "DONE_RA3",
- "AR", "PE", "PWR_ON", "RDCAP", "INTL", "FIDT", "MMC",
- "TRIG_ERR", "CONF_ERR", "LOAD_ERR",
- "GPIO16", "GPIO18", "GPIO22", "GPIO23"
-};
-#define IRQBITS ARRAY_SIZE(irqbits)
-
-static void print_irqstatus(struct saa7134_dev *dev, int loop,
- unsigned long report, unsigned long status)
-{
- unsigned int i;
-
- printk(KERN_DEBUG "%s/irq[%d,%ld]: r=0x%lx s=0x%02lx",
- dev->name,loop,jiffies,report,status);
- for (i = 0; i < IRQBITS; i++) {
- if (!(report & (1 << i)))
- continue;
- printk(" %s",irqbits[i]);
- }
- if (report & SAA7134_IRQ_REPORT_DONE_RA0) {
- printk(" | RA0=%s,%s,%s,%ld",
- (status & 0x40) ? "vbi" : "video",
- (status & 0x20) ? "b" : "a",
- (status & 0x10) ? "odd" : "even",
- (status & 0x0f));
- }
- printk("\n");
-}
-
-static irqreturn_t saa7134_irq(int irq, void *dev_id)
-{
- struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
- unsigned long report,status;
- int loop, handled = 0;
-
- if (dev->insuspend)
- goto out;
-
- for (loop = 0; loop < 10; loop++) {
- report = saa_readl(SAA7134_IRQ_REPORT);
- status = saa_readl(SAA7134_IRQ_STATUS);
-
- /* If dmasound support is active and we get a sound report,
- * mask out the report and let the saa7134-alsa module deal
- * with it */
- if ((report & SAA7134_IRQ_REPORT_DONE_RA3) &&
- (dev->dmasound.priv_data != NULL) )
- {
- if (irq_debug > 1)
- printk(KERN_DEBUG "%s/irq: preserving DMA sound interrupt\n",
- dev->name);
- report &= ~SAA7134_IRQ_REPORT_DONE_RA3;
- }
-
- if (0 == report) {
- if (irq_debug > 1)
- printk(KERN_DEBUG "%s/irq: no (more) work\n",
- dev->name);
- goto out;
- }
-
- handled = 1;
- saa_writel(SAA7134_IRQ_REPORT,report);
- if (irq_debug)
- print_irqstatus(dev,loop,report,status);
-
-
- if ((report & SAA7134_IRQ_REPORT_RDCAP) ||
- (report & SAA7134_IRQ_REPORT_INTL))
- saa7134_irq_video_signalchange(dev);
-
-
- if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&
- (status & 0x60) == 0)
- saa7134_irq_video_done(dev,status);
-
- if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&
- (status & 0x40) == 0x40)
- saa7134_irq_vbi_done(dev,status);
-
- if ((report & SAA7134_IRQ_REPORT_DONE_RA2) &&
- card_has_mpeg(dev))
- saa7134_irq_ts_done(dev,status);
-
- if (report & SAA7134_IRQ_REPORT_GPIO16) {
- switch (dev->has_remote) {
- case SAA7134_REMOTE_GPIO:
- if (!dev->remote)
- break;
- if (dev->remote->mask_keydown & 0x10000) {
- saa7134_input_irq(dev);
- }
- break;
-
- case SAA7134_REMOTE_I2C:
- break; /* FIXME: invoke I2C get_key() */
-
- default: /* GPIO16 not used by IR remote */
- break;
- }
- }
-
- if (report & SAA7134_IRQ_REPORT_GPIO18) {
- switch (dev->has_remote) {
- case SAA7134_REMOTE_GPIO:
- if (!dev->remote)
- break;
- if ((dev->remote->mask_keydown & 0x40000) ||
- (dev->remote->mask_keyup & 0x40000)) {
- saa7134_input_irq(dev);
- }
- break;
-
- case SAA7134_REMOTE_I2C:
- break; /* FIXME: invoke I2C get_key() */
-
- default: /* GPIO18 not used by IR remote */
- break;
- }
- }
- }
-
- if (10 == loop) {
- print_irqstatus(dev,loop,report,status);
- if (report & SAA7134_IRQ_REPORT_PE) {
- /* disable all parity error */
- printk(KERN_WARNING "%s/irq: looping -- "
- "clearing PE (parity error!) enable bit\n",dev->name);
- saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE);
- } else if (report & SAA7134_IRQ_REPORT_GPIO16) {
- /* disable gpio16 IRQ */
- printk(KERN_WARNING "%s/irq: looping -- "
- "clearing GPIO16 enable bit\n",dev->name);
- saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO16_P);
- saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO16_N);
- } else if (report & SAA7134_IRQ_REPORT_GPIO18) {
- /* disable gpio18 IRQs */
- printk(KERN_WARNING "%s/irq: looping -- "
- "clearing GPIO18 enable bit\n",dev->name);
- saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_P);
- saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_N);
- } else {
- /* disable all irqs */
- printk(KERN_WARNING "%s/irq: looping -- "
- "clearing all enable bits\n",dev->name);
- saa_writel(SAA7134_IRQ1,0);
- saa_writel(SAA7134_IRQ2,0);
- }
- }
-
- out:
- return IRQ_RETVAL(handled);
-}
-
-/* ------------------------------------------------------------------ */
-
-/* early init (no i2c, no irq) */
-
-static int saa7134_hw_enable1(struct saa7134_dev *dev)
-{
- /* RAM FIFO config */
- saa_writel(SAA7134_FIFO_SIZE, 0x08070503);
- saa_writel(SAA7134_THRESHOULD, 0x02020202);
-
- /* enable audio + video processing */
- saa_writel(SAA7134_MAIN_CTRL,
- SAA7134_MAIN_CTRL_VPLLE |
- SAA7134_MAIN_CTRL_APLLE |
- SAA7134_MAIN_CTRL_EXOSC |
- SAA7134_MAIN_CTRL_EVFE1 |
- SAA7134_MAIN_CTRL_EVFE2 |
- SAA7134_MAIN_CTRL_ESFE |
- SAA7134_MAIN_CTRL_EBDAC);
-
- /*
- * Initialize OSS _after_ enabling audio clock PLL and audio processing.
- * OSS initialization writes to registers via the audio DSP; these
- * writes will fail unless the audio clock has been started. At worst,
- * audio will not work.
- */
-
- /* enable peripheral devices */
- saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
-
- /* set vertical line numbering start (vbi needs this) */
- saa_writeb(SAA7134_SOURCE_TIMING2, 0x20);
-
- return 0;
-}
-
-static int saa7134_hwinit1(struct saa7134_dev *dev)
-{
- dprintk("hwinit1\n");
-
- saa_writel(SAA7134_IRQ1, 0);
- saa_writel(SAA7134_IRQ2, 0);
-
- /* Clear any stale IRQ reports */
- saa_writel(SAA7134_IRQ_REPORT, saa_readl(SAA7134_IRQ_REPORT));
-
- mutex_init(&dev->lock);
- spin_lock_init(&dev->slock);
-
- saa7134_track_gpio(dev,"pre-init");
- saa7134_video_init1(dev);
- saa7134_vbi_init1(dev);
- if (card_has_mpeg(dev))
- saa7134_ts_init1(dev);
- saa7134_input_init1(dev);
-
- saa7134_hw_enable1(dev);
-
- return 0;
-}
-
-/* late init (with i2c + irq) */
-static int saa7134_hw_enable2(struct saa7134_dev *dev)
-{
-
- unsigned int irq2_mask;
-
- /* enable IRQ's */
- irq2_mask =
- SAA7134_IRQ2_INTE_DEC3 |
- SAA7134_IRQ2_INTE_DEC2 |
- SAA7134_IRQ2_INTE_DEC1 |
- SAA7134_IRQ2_INTE_DEC0 |
- SAA7134_IRQ2_INTE_PE |
- SAA7134_IRQ2_INTE_AR;
-
- if (dev->has_remote == SAA7134_REMOTE_GPIO && dev->remote) {
- if (dev->remote->mask_keydown & 0x10000)
- irq2_mask |= SAA7134_IRQ2_INTE_GPIO16_N;
- else { /* Allow enabling both IRQ edge triggers */
- if (dev->remote->mask_keydown & 0x40000)
- irq2_mask |= SAA7134_IRQ2_INTE_GPIO18_P;
- if (dev->remote->mask_keyup & 0x40000)
- irq2_mask |= SAA7134_IRQ2_INTE_GPIO18_N;
- }
- }
-
- if (dev->has_remote == SAA7134_REMOTE_I2C) {
- request_module("ir-kbd-i2c");
- }
-
- saa_writel(SAA7134_IRQ1, 0);
- saa_writel(SAA7134_IRQ2, irq2_mask);
-
- return 0;
-}
-
-static int saa7134_hwinit2(struct saa7134_dev *dev)
-{
-
- dprintk("hwinit2\n");
-
- saa7134_video_init2(dev);
- saa7134_tvaudio_init2(dev);
-
- saa7134_hw_enable2(dev);
-
- return 0;
-}
-
-
-/* shutdown */
-static int saa7134_hwfini(struct saa7134_dev *dev)
-{
- dprintk("hwfini\n");
-
- if (card_has_mpeg(dev))
- saa7134_ts_fini(dev);
- saa7134_input_fini(dev);
- saa7134_vbi_fini(dev);
- saa7134_tvaudio_fini(dev);
- return 0;
-}
-
-static void __devinit must_configure_manually(int has_eeprom)
-{
- unsigned int i,p;
-
- if (!has_eeprom)
- printk(KERN_WARNING
- "saa7134: <rant>\n"
- "saa7134: Congratulations! Your TV card vendor saved a few\n"
- "saa7134: cents for a eeprom, thus your pci board has no\n"
- "saa7134: subsystem ID and I can't identify it automatically\n"
- "saa7134: </rant>\n"
- "saa7134: I feel better now. Ok, here are the good news:\n"
- "saa7134: You can use the card=<nr> insmod option to specify\n"
- "saa7134: which board do you have. The list:\n");
- else
- printk(KERN_WARNING
- "saa7134: Board is currently unknown. You might try to use the card=<nr>\n"
- "saa7134: insmod option to specify which board do you have, but this is\n"
- "saa7134: somewhat risky, as might damage your card. It is better to ask\n"
- "saa7134: for support at linux-media@vger.kernel.org.\n"
- "saa7134: The supported cards are:\n");
-
- for (i = 0; i < saa7134_bcount; i++) {
- printk(KERN_WARNING "saa7134: card=%d -> %-40.40s",
- i,saa7134_boards[i].name);
- for (p = 0; saa7134_pci_tbl[p].driver_data; p++) {
- if (saa7134_pci_tbl[p].driver_data != i)
- continue;
- printk(" %04x:%04x",
- saa7134_pci_tbl[p].subvendor,
- saa7134_pci_tbl[p].subdevice);
- }
- printk("\n");
- }
-}
-
-static struct video_device *vdev_init(struct saa7134_dev *dev,
- struct video_device *template,
- char *type)
-{
- struct video_device *vfd;
-
- vfd = video_device_alloc();
- if (NULL == vfd)
- return NULL;
- *vfd = *template;
- vfd->v4l2_dev = &dev->v4l2_dev;
- vfd->release = video_device_release;
- vfd->debug = video_debug;
- snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
- dev->name, type, saa7134_boards[dev->board].name);
- video_set_drvdata(vfd, dev);
- return vfd;
-}
-
-static void saa7134_unregister_video(struct saa7134_dev *dev)
-{
- if (dev->video_dev) {
- if (video_is_registered(dev->video_dev))
- video_unregister_device(dev->video_dev);
- else
- video_device_release(dev->video_dev);
- dev->video_dev = NULL;
- }
- if (dev->vbi_dev) {
- if (video_is_registered(dev->vbi_dev))
- video_unregister_device(dev->vbi_dev);
- else
- video_device_release(dev->vbi_dev);
- dev->vbi_dev = NULL;
- }
- if (dev->radio_dev) {
- if (video_is_registered(dev->radio_dev))
- video_unregister_device(dev->radio_dev);
- else
- video_device_release(dev->radio_dev);
- dev->radio_dev = NULL;
- }
-}
-
-static void mpeg_ops_attach(struct saa7134_mpeg_ops *ops,
- struct saa7134_dev *dev)
-{
- int err;
-
- if (NULL != dev->mops)
- return;
- if (saa7134_boards[dev->board].mpeg != ops->type)
- return;
- err = ops->init(dev);
- if (0 != err)
- return;
- dev->mops = ops;
-}
-
-static void mpeg_ops_detach(struct saa7134_mpeg_ops *ops,
- struct saa7134_dev *dev)
-{
- if (NULL == dev->mops)
- return;
- if (dev->mops != ops)
- return;
- dev->mops->fini(dev);
- dev->mops = NULL;
-}
-
-static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
-{
- struct saa7134_dev *dev;
- struct saa7134_mpeg_ops *mops;
- int err;
-
- if (saa7134_devcount == SAA7134_MAXBOARDS)
- return -ENOMEM;
-
- dev = kzalloc(sizeof(*dev),GFP_KERNEL);
- if (NULL == dev)
- return -ENOMEM;
-
- err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
- if (err)
- goto fail0;
-
- /* pci init */
- dev->pci = pci_dev;
- if (pci_enable_device(pci_dev)) {
- err = -EIO;
- goto fail1;
- }
-
- dev->nr = saa7134_devcount;
- sprintf(dev->name,"saa%x[%d]",pci_dev->device,dev->nr);
-
- /* pci quirks */
- if (pci_pci_problems) {
- if (pci_pci_problems & PCIPCI_TRITON)
- printk(KERN_INFO "%s: quirk: PCIPCI_TRITON\n", dev->name);
- if (pci_pci_problems & PCIPCI_NATOMA)
- printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA\n", dev->name);
- if (pci_pci_problems & PCIPCI_VIAETBF)
- printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF\n", dev->name);
- if (pci_pci_problems & PCIPCI_VSFX)
- printk(KERN_INFO "%s: quirk: PCIPCI_VSFX\n",dev->name);
-#ifdef PCIPCI_ALIMAGIK
- if (pci_pci_problems & PCIPCI_ALIMAGIK) {
- printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
- dev->name);
- latency = 0x0A;
- }
-#endif
- if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) {
- printk(KERN_INFO "%s: quirk: this driver and your "
- "chipset may not work together"
- " in overlay mode.\n",dev->name);
- if (!saa7134_no_overlay) {
- printk(KERN_INFO "%s: quirk: overlay "
- "mode will be disabled.\n",
- dev->name);
- saa7134_no_overlay = 1;
- } else {
- printk(KERN_INFO "%s: quirk: overlay "
- "mode will be forced. Use this"
- " option at your own risk.\n",
- dev->name);
- }
- }
- }
- if (UNSET != latency) {
- printk(KERN_INFO "%s: setting pci latency timer to %d\n",
- dev->name,latency);
- pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
- }
-
- /* print pci info */
- dev->pci_rev = pci_dev->revision;
- pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
- printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
- "latency: %d, mmio: 0x%llx\n", dev->name,
- pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
- dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0));
- pci_set_master(pci_dev);
- if (!pci_dma_supported(pci_dev, DMA_BIT_MASK(32))) {
- printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name);
- err = -EIO;
- goto fail1;
- }
-
- /* board config */
- dev->board = pci_id->driver_data;
- if (card[dev->nr] >= 0 &&
- card[dev->nr] < saa7134_bcount)
- dev->board = card[dev->nr];
- if (SAA7134_BOARD_UNKNOWN == dev->board)
- must_configure_manually(0);
- else if (SAA7134_BOARD_NOAUTO == dev->board) {
- must_configure_manually(1);
- dev->board = SAA7134_BOARD_UNKNOWN;
- }
- dev->autodetected = card[dev->nr] != dev->board;
- dev->tuner_type = saa7134_boards[dev->board].tuner_type;
- dev->tuner_addr = saa7134_boards[dev->board].tuner_addr;
- dev->radio_type = saa7134_boards[dev->board].radio_type;
- dev->radio_addr = saa7134_boards[dev->board].radio_addr;
- dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
- if (UNSET != tuner[dev->nr])
- dev->tuner_type = tuner[dev->nr];
- printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
- dev->name,pci_dev->subsystem_vendor,
- pci_dev->subsystem_device,saa7134_boards[dev->board].name,
- dev->board, dev->autodetected ?
- "autodetected" : "insmod option");
-
- /* get mmio */
- if (!request_mem_region(pci_resource_start(pci_dev,0),
- pci_resource_len(pci_dev,0),
- dev->name)) {
- err = -EBUSY;
- printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
- dev->name,(unsigned long long)pci_resource_start(pci_dev,0));
- goto fail1;
- }
- dev->lmmio = ioremap(pci_resource_start(pci_dev, 0),
- pci_resource_len(pci_dev, 0));
- dev->bmmio = (__u8 __iomem *)dev->lmmio;
- if (NULL == dev->lmmio) {
- err = -EIO;
- printk(KERN_ERR "%s: can't ioremap() MMIO memory\n",
- dev->name);
- goto fail2;
- }
-
- /* initialize hardware #1 */
- saa7134_board_init1(dev);
- saa7134_hwinit1(dev);
-
- /* get irq */
- err = request_irq(pci_dev->irq, saa7134_irq,
- IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
- if (err < 0) {
- printk(KERN_ERR "%s: can't get IRQ %d\n",
- dev->name,pci_dev->irq);
- goto fail3;
- }
-
- /* wait a bit, register i2c bus */
- msleep(100);
- saa7134_i2c_register(dev);
- saa7134_board_init2(dev);
-
- saa7134_hwinit2(dev);
-
- /* load i2c helpers */
- if (card_is_empress(dev)) {
- struct v4l2_subdev *sd =
- v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- "saa6752hs",
- saa7134_boards[dev->board].empress_addr, NULL);
-
- if (sd)
- sd->grp_id = GRP_EMPRESS;
- }
-
- if (saa7134_boards[dev->board].rds_addr) {
- struct v4l2_subdev *sd;
-
- sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, "saa6588",
- 0, I2C_ADDRS(saa7134_boards[dev->board].rds_addr));
- if (sd) {
- printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
- dev->has_rds = 1;
- }
- }
-
- v4l2_prio_init(&dev->prio);
-
- mutex_lock(&saa7134_devlist_lock);
- list_for_each_entry(mops, &mops_list, next)
- mpeg_ops_attach(mops, dev);
- list_add_tail(&dev->devlist, &saa7134_devlist);
- mutex_unlock(&saa7134_devlist_lock);
-
- /* check for signal */
- saa7134_irq_video_signalchange(dev);
-
- if (TUNER_ABSENT != dev->tuner_type)
- saa_call_all(dev, core, s_power, 0);
-
- /* register v4l devices */
- if (saa7134_no_overlay > 0)
- printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name);
-
- dev->video_dev = vdev_init(dev,&saa7134_video_template,"video");
- err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
- video_nr[dev->nr]);
- if (err < 0) {
- printk(KERN_INFO "%s: can't register video device\n",
- dev->name);
- goto fail4;
- }
- printk(KERN_INFO "%s: registered device %s [v4l2]\n",
- dev->name, video_device_node_name(dev->video_dev));
-
- dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi");
-
- err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
- vbi_nr[dev->nr]);
- if (err < 0)
- goto fail4;
- printk(KERN_INFO "%s: registered device %s\n",
- dev->name, video_device_node_name(dev->vbi_dev));
-
- if (card_has_radio(dev)) {
- dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio");
- err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
- radio_nr[dev->nr]);
- if (err < 0)
- goto fail4;
- printk(KERN_INFO "%s: registered device %s\n",
- dev->name, video_device_node_name(dev->radio_dev));
- }
-
- /* everything worked */
- saa7134_devcount++;
-
- if (saa7134_dmasound_init && !dev->dmasound.priv_data)
- saa7134_dmasound_init(dev);
-
- request_submodules(dev);
- return 0;
-
- fail4:
- saa7134_unregister_video(dev);
- saa7134_i2c_unregister(dev);
- free_irq(pci_dev->irq, dev);
- fail3:
- saa7134_hwfini(dev);
- iounmap(dev->lmmio);
- fail2:
- release_mem_region(pci_resource_start(pci_dev,0),
- pci_resource_len(pci_dev,0));
- fail1:
- v4l2_device_unregister(&dev->v4l2_dev);
- fail0:
- kfree(dev);
- return err;
-}
-
-static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
-{
- struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
- struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
- struct saa7134_mpeg_ops *mops;
-
- flush_request_submodules(dev);
-
- /* Release DMA sound modules if present */
- if (saa7134_dmasound_exit && dev->dmasound.priv_data) {
- saa7134_dmasound_exit(dev);
- }
-
- /* debugging ... */
- if (irq_debug) {
- u32 report = saa_readl(SAA7134_IRQ_REPORT);
- u32 status = saa_readl(SAA7134_IRQ_STATUS);
- print_irqstatus(dev,42,report,status);
- }
-
- /* disable peripheral devices */
- saa_writeb(SAA7134_SPECIAL_MODE,0);
-
- /* shutdown hardware */
- saa_writel(SAA7134_IRQ1,0);
- saa_writel(SAA7134_IRQ2,0);
- saa_writel(SAA7134_MAIN_CTRL,0);
-
- /* shutdown subsystems */
- saa7134_hwfini(dev);
-
- /* unregister */
- mutex_lock(&saa7134_devlist_lock);
- list_del(&dev->devlist);
- list_for_each_entry(mops, &mops_list, next)
- mpeg_ops_detach(mops, dev);
- mutex_unlock(&saa7134_devlist_lock);
- saa7134_devcount--;
-
- saa7134_i2c_unregister(dev);
- saa7134_unregister_video(dev);
-
-
- /* the DMA sound modules should be unloaded before reaching
- this, but just in case they are still present... */
- if (dev->dmasound.priv_data != NULL) {
- free_irq(pci_dev->irq, &dev->dmasound);
- dev->dmasound.priv_data = NULL;
- }
-
-
- /* release resources */
- free_irq(pci_dev->irq, dev);
- iounmap(dev->lmmio);
- release_mem_region(pci_resource_start(pci_dev,0),
- pci_resource_len(pci_dev,0));
-
-
- v4l2_device_unregister(&dev->v4l2_dev);
-
- /* free memory */
- kfree(dev);
-}
-
-#ifdef CONFIG_PM
-
-/* resends a current buffer in queue after resume */
-static int saa7134_buffer_requeue(struct saa7134_dev *dev,
- struct saa7134_dmaqueue *q)
-{
- struct saa7134_buf *buf, *next;
-
- assert_spin_locked(&dev->slock);
-
- buf = q->curr;
- next = buf;
- dprintk("buffer_requeue\n");
-
- if (!buf)
- return 0;
-
- dprintk("buffer_requeue : resending active buffers \n");
-
- if (!list_empty(&q->queue))
- next = list_entry(q->queue.next, struct saa7134_buf,
- vb.queue);
- buf->activate(dev, buf, next);
-
- return 0;
-}
-
-static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
-{
- struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
- struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
-
- /* disable overlay - apps should enable it explicitly on resume*/
- dev->ovenable = 0;
-
- /* Disable interrupts, DMA, and rest of the chip*/
- saa_writel(SAA7134_IRQ1, 0);
- saa_writel(SAA7134_IRQ2, 0);
- saa_writel(SAA7134_MAIN_CTRL, 0);
-
- dev->insuspend = 1;
- synchronize_irq(pci_dev->irq);
-
- /* ACK interrupts once more, just in case,
- since the IRQ handler won't ack them anymore*/
-
- saa_writel(SAA7134_IRQ_REPORT, saa_readl(SAA7134_IRQ_REPORT));
-
- /* Disable timeout timers - if we have active buffers, we will
- fill them on resume*/
-
- del_timer(&dev->video_q.timeout);
- del_timer(&dev->vbi_q.timeout);
- del_timer(&dev->ts_q.timeout);
-
- if (dev->remote)
- saa7134_ir_stop(dev);
-
- pci_save_state(pci_dev);
- pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
-
- return 0;
-}
-
-static int saa7134_resume(struct pci_dev *pci_dev)
-{
- struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
- struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
- unsigned long flags;
-
- pci_set_power_state(pci_dev, PCI_D0);
- pci_restore_state(pci_dev);
-
- /* Do things that are done in saa7134_initdev ,
- except of initializing memory structures.*/
-
- saa7134_board_init1(dev);
-
- /* saa7134_hwinit1 */
- if (saa7134_boards[dev->board].video_out)
- saa7134_videoport_init(dev);
- if (card_has_mpeg(dev))
- saa7134_ts_init_hw(dev);
- if (dev->remote)
- saa7134_ir_start(dev);
- saa7134_hw_enable1(dev);
-
- msleep(100);
-
- saa7134_board_init2(dev);
-
- /*saa7134_hwinit2*/
- saa7134_set_tvnorm_hw(dev);
- saa7134_tvaudio_setmute(dev);
- saa7134_tvaudio_setvolume(dev, dev->ctl_volume);
- saa7134_tvaudio_init(dev);
- saa7134_enable_i2s(dev);
- saa7134_hw_enable2(dev);
-
- saa7134_irq_video_signalchange(dev);
-
- /*resume unfinished buffer(s)*/
- spin_lock_irqsave(&dev->slock, flags);
- saa7134_buffer_requeue(dev, &dev->video_q);
- saa7134_buffer_requeue(dev, &dev->vbi_q);
- saa7134_buffer_requeue(dev, &dev->ts_q);
-
- /* FIXME: Disable DMA audio sound - temporary till proper support
- is implemented*/
-
- dev->dmasound.dma_running = 0;
-
- /* start DMA now*/
- dev->insuspend = 0;
- smp_wmb();
- saa7134_set_dmabits(dev);
- spin_unlock_irqrestore(&dev->slock, flags);
-
- return 0;
-}
-#endif
-
-/* ----------------------------------------------------------- */
-
-int saa7134_ts_register(struct saa7134_mpeg_ops *ops)
-{
- struct saa7134_dev *dev;
-
- mutex_lock(&saa7134_devlist_lock);
- list_for_each_entry(dev, &saa7134_devlist, devlist)
- mpeg_ops_attach(ops, dev);
- list_add_tail(&ops->next,&mops_list);
- mutex_unlock(&saa7134_devlist_lock);
- return 0;
-}
-
-void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops)
-{
- struct saa7134_dev *dev;
-
- mutex_lock(&saa7134_devlist_lock);
- list_del(&ops->next);
- list_for_each_entry(dev, &saa7134_devlist, devlist)
- mpeg_ops_detach(ops, dev);
- mutex_unlock(&saa7134_devlist_lock);
-}
-
-EXPORT_SYMBOL(saa7134_ts_register);
-EXPORT_SYMBOL(saa7134_ts_unregister);
-
-/* ----------------------------------------------------------- */
-
-static struct pci_driver saa7134_pci_driver = {
- .name = "saa7134",
- .id_table = saa7134_pci_tbl,
- .probe = saa7134_initdev,
- .remove = __devexit_p(saa7134_finidev),
-#ifdef CONFIG_PM
- .suspend = saa7134_suspend,
- .resume = saa7134_resume
-#endif
-};
-
-static int __init saa7134_init(void)
-{
- INIT_LIST_HEAD(&saa7134_devlist);
- printk(KERN_INFO "saa7130/34: v4l2 driver version %s loaded\n",
- SAA7134_VERSION);
- return pci_register_driver(&saa7134_pci_driver);
-}
-
-static void __exit saa7134_fini(void)
-{
- pci_unregister_driver(&saa7134_pci_driver);
-}
-
-module_init(saa7134_init);
-module_exit(saa7134_fini);
-
-/* ----------------------------------------------------------- */
-
-EXPORT_SYMBOL(saa7134_set_gpio);
-EXPORT_SYMBOL(saa7134_boards);
-
-/* ----------------- for the DMA sound modules --------------- */
-
-EXPORT_SYMBOL(saa7134_dmasound_init);
-EXPORT_SYMBOL(saa7134_dmasound_exit);
-EXPORT_SYMBOL(saa7134_pgtable_free);
-EXPORT_SYMBOL(saa7134_pgtable_build);
-EXPORT_SYMBOL(saa7134_pgtable_alloc);
-EXPORT_SYMBOL(saa7134_set_dmabits);
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
deleted file mode 100644
index cc7f3d6ee96..00000000000
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ /dev/null
@@ -1,1936 +0,0 @@
-/*
- *
- * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * Extended 3 / 2005 by Hartmut Hackmann to support various
- * cards with the tda10046 DVB-T channel decoder
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/kthread.h>
-#include <linux/suspend.h>
-
-#include "saa7134-reg.h"
-#include "saa7134.h"
-#include <media/v4l2-common.h>
-#include "dvb-pll.h"
-#include <dvb_frontend.h>
-
-#include "mt352.h"
-#include "mt352_priv.h" /* FIXME */
-#include "tda1004x.h"
-#include "nxt200x.h"
-#include "tuner-xc2028.h"
-#include "xc5000.h"
-
-#include "tda10086.h"
-#include "tda826x.h"
-#include "tda827x.h"
-#include "isl6421.h"
-#include "isl6405.h"
-#include "lnbp21.h"
-#include "tuner-simple.h"
-#include "tda10048.h"
-#include "tda18271.h"
-#include "lgdt3305.h"
-#include "tda8290.h"
-#include "mb86a20s.h"
-#include "lgs8gxx.h"
-
-#include "zl10353.h"
-#include "qt1010.h"
-
-#include "zl10036.h"
-#include "zl10039.h"
-#include "mt312.h"
-#include "s5h1411.h"
-
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
-MODULE_LICENSE("GPL");
-
-static unsigned int antenna_pwr;
-
-module_param(antenna_pwr, int, 0444);
-MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)");
-
-static int use_frontend;
-module_param(use_frontend, int, 0644);
-MODULE_PARM_DESC(use_frontend,"for cards with multiple frontends (0: terrestrial, 1: satellite)");
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off module debugging (default:off).");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define dprintk(fmt, arg...) do { if (debug) \
- printk(KERN_DEBUG "%s/dvb: " fmt, dev->name , ## arg); } while(0)
-
-/* Print a warning */
-#define wprintk(fmt, arg...) \
- printk(KERN_WARNING "%s/dvb: " fmt, dev->name, ## arg)
-
-/* ------------------------------------------------------------------
- * mt352 based DVB-T cards
- */
-
-static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on)
-{
- u32 ok;
-
- if (!on) {
- saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 26));
- saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
- return 0;
- }
-
- saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 26));
- saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
- udelay(10);
-
- saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 28));
- saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28));
- udelay(10);
- saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28));
- udelay(10);
- ok = saa_readl(SAA7134_GPIO_GPSTATUS0) & (1 << 27);
- dprintk("%s %s\n", __func__, ok ? "on" : "off");
-
- if (!ok)
- saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
- return ok;
-}
-
-static int mt352_pinnacle_init(struct dvb_frontend* fe)
-{
- static u8 clock_config [] = { CLOCK_CTL, 0x3d, 0x28 };
- static u8 reset [] = { RESET, 0x80 };
- static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
- static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0xa0 };
- static u8 capt_range_cfg[] = { CAPT_RANGE, 0x31 };
- static u8 fsm_ctl_cfg[] = { 0x7b, 0x04 };
- static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x0f };
- static u8 scan_ctl_cfg [] = { SCAN_CTL, 0x0d };
- static u8 irq_cfg [] = { INTERRUPT_EN_0, 0x00, 0x00, 0x00, 0x00 };
- struct saa7134_dev *dev= fe->dvb->priv;
-
- dprintk("%s called\n", __func__);
-
- mt352_write(fe, clock_config, sizeof(clock_config));
- udelay(200);
- mt352_write(fe, reset, sizeof(reset));
- mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
- mt352_write(fe, agc_cfg, sizeof(agc_cfg));
- mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
- mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
-
- mt352_write(fe, fsm_ctl_cfg, sizeof(fsm_ctl_cfg));
- mt352_write(fe, scan_ctl_cfg, sizeof(scan_ctl_cfg));
- mt352_write(fe, irq_cfg, sizeof(irq_cfg));
-
- return 0;
-}
-
-static int mt352_aver777_init(struct dvb_frontend* fe)
-{
- static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x2d };
- static u8 reset [] = { RESET, 0x80 };
- static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
- static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0xa0 };
- static u8 capt_range_cfg[] = { CAPT_RANGE, 0x33 };
-
- mt352_write(fe, clock_config, sizeof(clock_config));
- udelay(200);
- mt352_write(fe, reset, sizeof(reset));
- mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
- mt352_write(fe, agc_cfg, sizeof(agc_cfg));
- mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
-
- return 0;
-}
-
-static int mt352_avermedia_xc3028_init(struct dvb_frontend *fe)
-{
- static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x2d };
- static u8 reset [] = { RESET, 0x80 };
- static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
- static u8 agc_cfg [] = { AGC_TARGET, 0xe };
- static u8 capt_range_cfg[] = { CAPT_RANGE, 0x33 };
-
- mt352_write(fe, clock_config, sizeof(clock_config));
- udelay(200);
- mt352_write(fe, reset, sizeof(reset));
- mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
- mt352_write(fe, agc_cfg, sizeof(agc_cfg));
- mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
- return 0;
-}
-
-static int mt352_pinnacle_tuner_set_params(struct dvb_frontend *fe)
-{
- struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- u8 off[] = { 0x00, 0xf1};
- u8 on[] = { 0x00, 0x71};
- struct i2c_msg msg = {.addr=0x43, .flags=0, .buf=off, .len = sizeof(off)};
-
- struct saa7134_dev *dev = fe->dvb->priv;
- struct v4l2_frequency f;
-
- /* set frequency (mt2050) */
- f.tuner = 0;
- f.type = V4L2_TUNER_DIGITAL_TV;
- f.frequency = c->frequency / 1000 * 16 / 1000;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(&dev->i2c_adap, &msg, 1);
- saa_call_all(dev, tuner, s_frequency, &f);
- msg.buf = on;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(&dev->i2c_adap, &msg, 1);
-
- pinnacle_antenna_pwr(dev, antenna_pwr);
-
- /* mt352 setup */
- return mt352_pinnacle_init(fe);
-}
-
-static struct mt352_config pinnacle_300i = {
- .demod_address = 0x3c >> 1,
- .adc_clock = 20333,
- .if2 = 36150,
- .no_tuner = 1,
- .demod_init = mt352_pinnacle_init,
-};
-
-static struct mt352_config avermedia_777 = {
- .demod_address = 0xf,
- .demod_init = mt352_aver777_init,
-};
-
-static struct mt352_config avermedia_xc3028_mt352_dev = {
- .demod_address = (0x1e >> 1),
- .no_tuner = 1,
- .demod_init = mt352_avermedia_xc3028_init,
-};
-
-static struct tda18271_std_map mb86a20s_tda18271_std_map = {
- .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
- .if_lvl = 7, .rfagc_top = 0x37, },
-};
-
-static struct tda18271_config kworld_tda18271_config = {
- .std_map = &mb86a20s_tda18271_std_map,
- .gate = TDA18271_GATE_DIGITAL,
- .config = 3, /* Use tuner callback for AGC */
-
-};
-
-static const struct mb86a20s_config kworld_mb86a20s_config = {
- .demod_address = 0x10,
-};
-
-static int kworld_sbtvd_gate_ctrl(struct dvb_frontend* fe, int enable)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
-
- unsigned char initmsg[] = {0x45, 0x97};
- unsigned char msg_enable[] = {0x45, 0xc1};
- unsigned char msg_disable[] = {0x45, 0x81};
- struct i2c_msg msg = {.addr = 0x4b, .flags = 0, .buf = initmsg, .len = 2};
-
- if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) {
- wprintk("could not access the I2C gate\n");
- return -EIO;
- }
- if (enable)
- msg.buf = msg_enable;
- else
- msg.buf = msg_disable;
- if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) {
- wprintk("could not access the I2C gate\n");
- return -EIO;
- }
- msleep(20);
- return 0;
-}
-
-/* ==================================================================
- * tda1004x based DVB-T cards, helper functions
- */
-
-static int philips_tda1004x_request_firmware(struct dvb_frontend *fe,
- const struct firmware **fw, char *name)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
- return request_firmware(fw, name, &dev->pci->dev);
-}
-
-/* ------------------------------------------------------------------
- * these tuners are tu1216, td1316(a)
- */
-
-static int philips_tda6651_pll_set(struct dvb_frontend *fe)
-{
- struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- struct saa7134_dev *dev = fe->dvb->priv;
- struct tda1004x_state *state = fe->demodulator_priv;
- u8 addr = state->config->tuner_address;
- u8 tuner_buf[4];
- struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tuner_buf,.len =
- sizeof(tuner_buf) };
- int tuner_frequency = 0;
- u8 band, cp, filter;
-
- /* determine charge pump */
- tuner_frequency = c->frequency + 36166000;
- if (tuner_frequency < 87000000)
- return -EINVAL;
- else if (tuner_frequency < 130000000)
- cp = 3;
- else if (tuner_frequency < 160000000)
- cp = 5;
- else if (tuner_frequency < 200000000)
- cp = 6;
- else if (tuner_frequency < 290000000)
- cp = 3;
- else if (tuner_frequency < 420000000)
- cp = 5;
- else if (tuner_frequency < 480000000)
- cp = 6;
- else if (tuner_frequency < 620000000)
- cp = 3;
- else if (tuner_frequency < 830000000)
- cp = 5;
- else if (tuner_frequency < 895000000)
- cp = 7;
- else
- return -EINVAL;
-
- /* determine band */
- if (c->frequency < 49000000)
- return -EINVAL;
- else if (c->frequency < 161000000)
- band = 1;
- else if (c->frequency < 444000000)
- band = 2;
- else if (c->frequency < 861000000)
- band = 4;
- else
- return -EINVAL;
-
- /* setup PLL filter */
- switch (c->bandwidth_hz) {
- case 6000000:
- filter = 0;
- break;
-
- case 7000000:
- filter = 0;
- break;
-
- case 8000000:
- filter = 1;
- break;
-
- default:
- return -EINVAL;
- }
-
- /* calculate divisor
- * ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
- */
- tuner_frequency = (((c->frequency / 1000) * 6) + 217496) / 1000;
-
- /* setup tuner buffer */
- tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
- tuner_buf[1] = tuner_frequency & 0xff;
- tuner_buf[2] = 0xca;
- tuner_buf[3] = (cp << 5) | (filter << 3) | band;
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) {
- wprintk("could not write to tuner at addr: 0x%02x\n",
- addr << 1);
- return -EIO;
- }
- msleep(1);
- return 0;
-}
-
-static int philips_tu1216_init(struct dvb_frontend *fe)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
- struct tda1004x_state *state = fe->demodulator_priv;
- u8 addr = state->config->tuner_address;
- static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
- struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
-
- /* setup PLL configuration */
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
- return -EIO;
- msleep(1);
-
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static struct tda1004x_config philips_tu1216_60_config = {
- .demod_address = 0x8,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_4M,
- .agc_config = TDA10046_AGC_DEFAULT,
- .if_freq = TDA10046_FREQ_3617,
- .tuner_address = 0x60,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config philips_tu1216_61_config = {
-
- .demod_address = 0x8,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_4M,
- .agc_config = TDA10046_AGC_DEFAULT,
- .if_freq = TDA10046_FREQ_3617,
- .tuner_address = 0x61,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-/* ------------------------------------------------------------------ */
-
-static int philips_td1316_tuner_init(struct dvb_frontend *fe)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
- struct tda1004x_state *state = fe->demodulator_priv;
- u8 addr = state->config->tuner_address;
- static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab };
- struct i2c_msg init_msg = {.addr = addr,.flags = 0,.buf = msg,.len = sizeof(msg) };
-
- /* setup PLL configuration */
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
- return -EIO;
- return 0;
-}
-
-static int philips_td1316_tuner_set_params(struct dvb_frontend *fe)
-{
- return philips_tda6651_pll_set(fe);
-}
-
-static int philips_td1316_tuner_sleep(struct dvb_frontend *fe)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
- struct tda1004x_state *state = fe->demodulator_priv;
- u8 addr = state->config->tuner_address;
- static u8 msg[] = { 0x0b, 0xdc, 0x86, 0xa4 };
- struct i2c_msg analog_msg = {.addr = addr,.flags = 0,.buf = msg,.len = sizeof(msg) };
-
- /* switch the tuner to analog mode */
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(&dev->i2c_adap, &analog_msg, 1) != 1)
- return -EIO;
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int philips_europa_tuner_init(struct dvb_frontend *fe)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
- static u8 msg[] = { 0x00, 0x40};
- struct i2c_msg init_msg = {.addr = 0x43,.flags = 0,.buf = msg,.len = sizeof(msg) };
-
-
- if (philips_td1316_tuner_init(fe))
- return -EIO;
- msleep(1);
- if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
- return -EIO;
-
- return 0;
-}
-
-static int philips_europa_tuner_sleep(struct dvb_frontend *fe)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
-
- static u8 msg[] = { 0x00, 0x14 };
- struct i2c_msg analog_msg = {.addr = 0x43,.flags = 0,.buf = msg,.len = sizeof(msg) };
-
- if (philips_td1316_tuner_sleep(fe))
- return -EIO;
-
- /* switch the board to analog mode */
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
- return 0;
-}
-
-static int philips_europa_demod_sleep(struct dvb_frontend *fe)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
-
- if (dev->original_demod_sleep)
- dev->original_demod_sleep(fe);
- fe->ops.i2c_gate_ctrl(fe, 1);
- return 0;
-}
-
-static struct tda1004x_config philips_europa_config = {
-
- .demod_address = 0x8,
- .invert = 0,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_4M,
- .agc_config = TDA10046_AGC_IFO_AUTO_POS,
- .if_freq = TDA10046_FREQ_052,
- .tuner_address = 0x61,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config medion_cardbus = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_IFO_AUTO_NEG,
- .if_freq = TDA10046_FREQ_3613,
- .tuner_address = 0x61,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config technotrend_budget_t3000_config = {
- .demod_address = 0x8,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_4M,
- .agc_config = TDA10046_AGC_DEFAULT,
- .if_freq = TDA10046_FREQ_3617,
- .tuner_address = 0x63,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-/* ------------------------------------------------------------------
- * tda 1004x based cards with philips silicon tuner
- */
-
-static int tda8290_i2c_gate_ctrl( struct dvb_frontend* fe, int enable)
-{
- struct tda1004x_state *state = fe->demodulator_priv;
-
- u8 addr = state->config->i2c_gate;
- static u8 tda8290_close[] = { 0x21, 0xc0};
- static u8 tda8290_open[] = { 0x21, 0x80};
- struct i2c_msg tda8290_msg = {.addr = addr,.flags = 0, .len = 2};
- if (enable) {
- tda8290_msg.buf = tda8290_close;
- } else {
- tda8290_msg.buf = tda8290_open;
- }
- if (i2c_transfer(state->i2c, &tda8290_msg, 1) != 1) {
- struct saa7134_dev *dev = fe->dvb->priv;
- wprintk("could not access tda8290 I2C gate\n");
- return -EIO;
- }
- msleep(20);
- return 0;
-}
-
-static int philips_tda827x_tuner_init(struct dvb_frontend *fe)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
- struct tda1004x_state *state = fe->demodulator_priv;
-
- switch (state->config->antenna_switch) {
- case 0: break;
- case 1: dprintk("setting GPIO21 to 0 (TV antenna?)\n");
- saa7134_set_gpio(dev, 21, 0);
- break;
- case 2: dprintk("setting GPIO21 to 1 (Radio antenna?)\n");
- saa7134_set_gpio(dev, 21, 1);
- break;
- }
- return 0;
-}
-
-static int philips_tda827x_tuner_sleep(struct dvb_frontend *fe)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
- struct tda1004x_state *state = fe->demodulator_priv;
-
- switch (state->config->antenna_switch) {
- case 0: break;
- case 1: dprintk("setting GPIO21 to 1 (Radio antenna?)\n");
- saa7134_set_gpio(dev, 21, 1);
- break;
- case 2: dprintk("setting GPIO21 to 0 (TV antenna?)\n");
- saa7134_set_gpio(dev, 21, 0);
- break;
- }
- return 0;
-}
-
-static int configure_tda827x_fe(struct saa7134_dev *dev,
- struct tda1004x_config *cdec_conf,
- struct tda827x_config *tuner_conf)
-{
- struct videobuf_dvb_frontend *fe0;
-
- /* Get the first frontend */
- fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
-
- fe0->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- if (cdec_conf->i2c_gate)
- fe0->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
- if (dvb_attach(tda827x_attach, fe0->dvb.frontend,
- cdec_conf->tuner_address,
- &dev->i2c_adap, tuner_conf))
- return 0;
-
- wprintk("no tda827x tuner found at addr: %02x\n",
- cdec_conf->tuner_address);
- }
- return -EINVAL;
-}
-
-/* ------------------------------------------------------------------ */
-
-static struct tda827x_config tda827x_cfg_0 = {
- .init = philips_tda827x_tuner_init,
- .sleep = philips_tda827x_tuner_sleep,
- .config = 0,
- .switch_addr = 0
-};
-
-static struct tda827x_config tda827x_cfg_1 = {
- .init = philips_tda827x_tuner_init,
- .sleep = philips_tda827x_tuner_sleep,
- .config = 1,
- .switch_addr = 0x4b
-};
-
-static struct tda827x_config tda827x_cfg_2 = {
- .init = philips_tda827x_tuner_init,
- .sleep = philips_tda827x_tuner_sleep,
- .config = 2,
- .switch_addr = 0x4b
-};
-
-static struct tda827x_config tda827x_cfg_2_sw42 = {
- .init = philips_tda827x_tuner_init,
- .sleep = philips_tda827x_tuner_sleep,
- .config = 2,
- .switch_addr = 0x42
-};
-
-/* ------------------------------------------------------------------ */
-
-static struct tda1004x_config tda827x_lifeview_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP11_I,
- .if_freq = TDA10046_FREQ_045,
- .tuner_address = 0x60,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config philips_tiger_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP11_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x4b,
- .tuner_address = 0x61,
- .antenna_switch= 1,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config cinergy_ht_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP01_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x4b,
- .tuner_address = 0x61,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config cinergy_ht_pci_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP01_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x4b,
- .tuner_address = 0x60,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config philips_tiger_s_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP01_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x4b,
- .tuner_address = 0x61,
- .antenna_switch= 1,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config pinnacle_pctv_310i_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP11_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x4b,
- .tuner_address = 0x61,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config hauppauge_hvr_1110_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP11_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x4b,
- .tuner_address = 0x61,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config asus_p7131_dual_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP11_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x4b,
- .tuner_address = 0x61,
- .antenna_switch= 2,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config lifeview_trio_config = {
- .demod_address = 0x09,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP00_I,
- .if_freq = TDA10046_FREQ_045,
- .tuner_address = 0x60,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config tevion_dvbt220rf_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP11_I,
- .if_freq = TDA10046_FREQ_045,
- .tuner_address = 0x60,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config md8800_dvbt_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP01_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x4b,
- .tuner_address = 0x60,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config asus_p7131_4871_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP01_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x4b,
- .tuner_address = 0x61,
- .antenna_switch= 2,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config asus_p7131_hybrid_lna_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP11_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x4b,
- .tuner_address = 0x61,
- .antenna_switch= 2,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config kworld_dvb_t_210_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP11_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x4b,
- .tuner_address = 0x61,
- .antenna_switch= 1,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config avermedia_super_007_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP01_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x4b,
- .tuner_address = 0x60,
- .antenna_switch= 1,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config twinhan_dtv_dvb_3056_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP01_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x42,
- .tuner_address = 0x61,
- .antenna_switch = 1,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config asus_tiger_3in1_config = {
- .demod_address = 0x0b,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP11_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x4b,
- .tuner_address = 0x61,
- .antenna_switch = 1,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct tda1004x_config asus_ps3_100_config = {
- .demod_address = 0x0b,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP11_I,
- .if_freq = TDA10046_FREQ_045,
- .i2c_gate = 0x4b,
- .tuner_address = 0x61,
- .antenna_switch = 1,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-/* ------------------------------------------------------------------
- * special case: this card uses saa713x GPIO22 for the mode switch
- */
-
-static int ads_duo_tuner_init(struct dvb_frontend *fe)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
- philips_tda827x_tuner_init(fe);
- /* route TDA8275a AGC input to the channel decoder */
- saa7134_set_gpio(dev, 22, 1);
- return 0;
-}
-
-static int ads_duo_tuner_sleep(struct dvb_frontend *fe)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
- /* route TDA8275a AGC input to the analog IF chip*/
- saa7134_set_gpio(dev, 22, 0);
- philips_tda827x_tuner_sleep(fe);
- return 0;
-}
-
-static struct tda827x_config ads_duo_cfg = {
- .init = ads_duo_tuner_init,
- .sleep = ads_duo_tuner_sleep,
- .config = 0
-};
-
-static struct tda1004x_config ads_tech_duo_config = {
- .demod_address = 0x08,
- .invert = 1,
- .invert_oclk = 0,
- .xtal_freq = TDA10046_XTAL_16M,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GP00_I,
- .if_freq = TDA10046_FREQ_045,
- .tuner_address = 0x61,
- .request_firmware = philips_tda1004x_request_firmware
-};
-
-static struct zl10353_config behold_h6_config = {
- .demod_address = 0x1e>>1,
- .no_tuner = 1,
- .parallel_ts = 1,
- .disable_i2c_gate_ctrl = 1,
-};
-
-static struct xc5000_config behold_x7_tunerconfig = {
- .i2c_address = 0xc2>>1,
- .if_khz = 4560,
- .radio_input = XC5000_RADIO_FM1,
-};
-
-static struct zl10353_config behold_x7_config = {
- .demod_address = 0x1e>>1,
- .if2 = 45600,
- .no_tuner = 1,
- .parallel_ts = 1,
- .disable_i2c_gate_ctrl = 1,
-};
-
-static struct zl10353_config videomate_t750_zl10353_config = {
- .demod_address = 0x0f,
- .no_tuner = 1,
- .parallel_ts = 1,
- .disable_i2c_gate_ctrl = 1,
-};
-
-static struct qt1010_config videomate_t750_qt1010_config = {
- .i2c_address = 0x62
-};
-
-
-/* ==================================================================
- * tda10086 based DVB-S cards, helper functions
- */
-
-static struct tda10086_config flydvbs = {
- .demod_address = 0x0e,
- .invert = 0,
- .diseqc_tone = 0,
- .xtal_freq = TDA10086_XTAL_16M,
-};
-
-static struct tda10086_config sd1878_4m = {
- .demod_address = 0x0e,
- .invert = 0,
- .diseqc_tone = 0,
- .xtal_freq = TDA10086_XTAL_4M,
-};
-
-/* ------------------------------------------------------------------
- * special case: lnb supply is connected to the gated i2c
- */
-
-static int md8800_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
- int res = -EIO;
- struct saa7134_dev *dev = fe->dvb->priv;
- if (fe->ops.i2c_gate_ctrl) {
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (dev->original_set_voltage)
- res = dev->original_set_voltage(fe, voltage);
- fe->ops.i2c_gate_ctrl(fe, 0);
- }
- return res;
-};
-
-static int md8800_set_high_voltage(struct dvb_frontend *fe, long arg)
-{
- int res = -EIO;
- struct saa7134_dev *dev = fe->dvb->priv;
- if (fe->ops.i2c_gate_ctrl) {
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (dev->original_set_high_voltage)
- res = dev->original_set_high_voltage(fe, arg);
- fe->ops.i2c_gate_ctrl(fe, 0);
- }
- return res;
-};
-
-static int md8800_set_voltage2(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
- u8 wbuf[2] = { 0x1f, 00 };
- u8 rbuf;
- struct i2c_msg msg[] = { { .addr = 0x08, .flags = 0, .buf = wbuf, .len = 1 },
- { .addr = 0x08, .flags = I2C_M_RD, .buf = &rbuf, .len = 1 } };
-
- if (i2c_transfer(&dev->i2c_adap, msg, 2) != 2)
- return -EIO;
- /* NOTE: this assumes that gpo1 is used, it might be bit 5 (gpo2) */
- if (voltage == SEC_VOLTAGE_18)
- wbuf[1] = rbuf | 0x10;
- else
- wbuf[1] = rbuf & 0xef;
- msg[0].len = 2;
- i2c_transfer(&dev->i2c_adap, msg, 1);
- return 0;
-}
-
-static int md8800_set_high_voltage2(struct dvb_frontend *fe, long arg)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
- wprintk("%s: sorry can't set high LNB supply voltage from here\n", __func__);
- return -EIO;
-}
-
-/* ==================================================================
- * nxt200x based ATSC cards, helper functions
- */
-
-static struct nxt200x_config avertvhda180 = {
- .demod_address = 0x0a,
-};
-
-static struct nxt200x_config kworldatsc110 = {
- .demod_address = 0x0a,
-};
-
-/* ------------------------------------------------------------------ */
-
-static struct mt312_config avertv_a700_mt312 = {
- .demod_address = 0x0e,
- .voltage_inverted = 1,
-};
-
-static struct zl10036_config avertv_a700_tuner = {
- .tuner_address = 0x60,
-};
-
-static struct mt312_config zl10313_compro_s350_config = {
- .demod_address = 0x0e,
-};
-
-static struct lgdt3305_config hcw_lgdt3305_config = {
- .i2c_addr = 0x0e,
- .mpeg_mode = LGDT3305_MPEG_SERIAL,
- .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE,
- .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
- .deny_i2c_rptr = 1,
- .spectral_inversion = 1,
- .qam_if_khz = 4000,
- .vsb_if_khz = 3250,
-};
-
-static struct tda10048_config hcw_tda10048_config = {
- .demod_address = 0x10 >> 1,
- .output_mode = TDA10048_SERIAL_OUTPUT,
- .fwbulkwritelen = TDA10048_BULKWRITE_200,
- .inversion = TDA10048_INVERSION_ON,
- .dtv6_if_freq_khz = TDA10048_IF_3300,
- .dtv7_if_freq_khz = TDA10048_IF_3500,
- .dtv8_if_freq_khz = TDA10048_IF_4000,
- .clk_freq_khz = TDA10048_CLK_16000,
- .disable_gate_access = 1,
-};
-
-static struct tda18271_std_map hauppauge_tda18271_std_map = {
- .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4,
- .if_lvl = 1, .rfagc_top = 0x58, },
- .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5,
- .if_lvl = 1, .rfagc_top = 0x58, },
-};
-
-static struct tda18271_config hcw_tda18271_config = {
- .std_map = &hauppauge_tda18271_std_map,
- .gate = TDA18271_GATE_ANALOG,
- .config = 3,
- .output_opt = TDA18271_OUTPUT_LT_OFF,
-};
-
-static struct tda829x_config tda829x_no_probe = {
- .probe_tuner = TDA829X_DONT_PROBE,
-};
-
-static struct tda10048_config zolid_tda10048_config = {
- .demod_address = 0x10 >> 1,
- .output_mode = TDA10048_PARALLEL_OUTPUT,
- .fwbulkwritelen = TDA10048_BULKWRITE_200,
- .inversion = TDA10048_INVERSION_ON,
- .dtv6_if_freq_khz = TDA10048_IF_3300,
- .dtv7_if_freq_khz = TDA10048_IF_3500,
- .dtv8_if_freq_khz = TDA10048_IF_4000,
- .clk_freq_khz = TDA10048_CLK_16000,
- .disable_gate_access = 1,
-};
-
-static struct tda18271_config zolid_tda18271_config = {
- .gate = TDA18271_GATE_ANALOG,
-};
-
-static struct tda10048_config dtv1000s_tda10048_config = {
- .demod_address = 0x10 >> 1,
- .output_mode = TDA10048_PARALLEL_OUTPUT,
- .fwbulkwritelen = TDA10048_BULKWRITE_200,
- .inversion = TDA10048_INVERSION_ON,
- .dtv6_if_freq_khz = TDA10048_IF_3300,
- .dtv7_if_freq_khz = TDA10048_IF_3800,
- .dtv8_if_freq_khz = TDA10048_IF_4300,
- .clk_freq_khz = TDA10048_CLK_16000,
- .disable_gate_access = 1,
-};
-
-static struct tda18271_std_map dtv1000s_tda18271_std_map = {
- .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
- .if_lvl = 1, .rfagc_top = 0x37, },
- .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5,
- .if_lvl = 1, .rfagc_top = 0x37, },
- .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6,
- .if_lvl = 1, .rfagc_top = 0x37, },
-};
-
-static struct tda18271_config dtv1000s_tda18271_config = {
- .std_map = &dtv1000s_tda18271_std_map,
- .gate = TDA18271_GATE_ANALOG,
-};
-
-static struct lgs8gxx_config prohdtv_pro2_lgs8g75_config = {
- .prod = LGS8GXX_PROD_LGS8G75,
- .demod_address = 0x1d,
- .serial_ts = 0,
- .ts_clk_pol = 1,
- .ts_clk_gated = 0,
- .if_clk_freq = 30400, /* 30.4 MHz */
- .if_freq = 4000, /* 4.00 MHz */
- .if_neg_center = 0,
- .ext_adc = 0,
- .adc_signed = 1,
- .adc_vpp = 3, /* 2.0 Vpp */
- .if_neg_edge = 1,
-};
-
-static struct tda18271_config prohdtv_pro2_tda18271_config = {
- .gate = TDA18271_GATE_ANALOG,
- .output_opt = TDA18271_OUTPUT_LT_OFF,
-};
-
-static struct tda18271_std_map kworld_tda18271_std_map = {
- .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 3,
- .if_lvl = 6, .rfagc_top = 0x37 },
- .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
- .if_lvl = 6, .rfagc_top = 0x37 },
-};
-
-static struct tda18271_config kworld_pc150u_tda18271_config = {
- .std_map = &kworld_tda18271_std_map,
- .gate = TDA18271_GATE_ANALOG,
- .output_opt = TDA18271_OUTPUT_LT_OFF,
- .config = 3, /* Use tuner callback for AGC */
- .rf_cal_on_startup = 1
-};
-
-static struct s5h1411_config kworld_s5h1411_config = {
- .output_mode = S5H1411_PARALLEL_OUTPUT,
- .gpio = S5H1411_GPIO_OFF,
- .qam_if = S5H1411_IF_4000,
- .vsb_if = S5H1411_IF_3250,
- .inversion = S5H1411_INVERSION_ON,
- .status_mode = S5H1411_DEMODLOCKING,
- .mpeg_timing =
- S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-
-/* ==================================================================
- * Core code
- */
-
-static int dvb_init(struct saa7134_dev *dev)
-{
- int ret;
- int attach_xc3028 = 0;
- struct videobuf_dvb_frontend *fe0;
-
- /* FIXME: add support for multi-frontend */
- mutex_init(&dev->frontends.lock);
- INIT_LIST_HEAD(&dev->frontends.felist);
-
- printk(KERN_INFO "%s() allocating 1 frontend\n", __func__);
- fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, 1);
- if (!fe0) {
- printk(KERN_ERR "%s() failed to alloc\n", __func__);
- return -ENOMEM;
- }
-
- /* init struct videobuf_dvb */
- dev->ts.nr_bufs = 32;
- dev->ts.nr_packets = 32*4;
- fe0->dvb.name = dev->name;
- videobuf_queue_sg_init(&fe0->dvb.dvbq, &saa7134_ts_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_ALTERNATE,
- sizeof(struct saa7134_buf),
- dev, NULL);
-
- switch (dev->board) {
- case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
- dprintk("pinnacle 300i dvb setup\n");
- fe0->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- fe0->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params;
- }
- break;
- case SAA7134_BOARD_AVERMEDIA_777:
- case SAA7134_BOARD_AVERMEDIA_A16AR:
- dprintk("avertv 777 dvb setup\n");
- fe0->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &dev->i2c_adap, 0x61,
- TUNER_PHILIPS_TD1316);
- }
- break;
- case SAA7134_BOARD_AVERMEDIA_A16D:
- dprintk("AverMedia A16D dvb setup\n");
- fe0->dvb.frontend = dvb_attach(mt352_attach,
- &avermedia_xc3028_mt352_dev,
- &dev->i2c_adap);
- attach_xc3028 = 1;
- break;
- case SAA7134_BOARD_MD7134:
- fe0->dvb.frontend = dvb_attach(tda10046_attach,
- &medion_cardbus,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &dev->i2c_adap, medion_cardbus.tuner_address,
- TUNER_PHILIPS_FMD1216ME_MK3);
- }
- break;
- case SAA7134_BOARD_PHILIPS_TOUGH:
- fe0->dvb.frontend = dvb_attach(tda10046_attach,
- &philips_tu1216_60_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
- fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
- }
- break;
- case SAA7134_BOARD_FLYDVBTDUO:
- case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
- if (configure_tda827x_fe(dev, &tda827x_lifeview_config,
- &tda827x_cfg_0) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_PHILIPS_EUROPA:
- case SAA7134_BOARD_VIDEOMATE_DVBT_300:
- case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
- fe0->dvb.frontend = dvb_attach(tda10046_attach,
- &philips_europa_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep;
- fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
- fe0->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
- fe0->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
- fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
- }
- break;
- case SAA7134_BOARD_TECHNOTREND_BUDGET_T3000:
- fe0->dvb.frontend = dvb_attach(tda10046_attach,
- &technotrend_budget_t3000_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep;
- fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
- fe0->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
- fe0->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
- fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
- }
- break;
- case SAA7134_BOARD_VIDEOMATE_DVBT_200:
- fe0->dvb.frontend = dvb_attach(tda10046_attach,
- &philips_tu1216_61_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
- fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
- }
- break;
- case SAA7134_BOARD_KWORLD_DVBT_210:
- if (configure_tda827x_fe(dev, &kworld_dvb_t_210_config,
- &tda827x_cfg_2) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_HAUPPAUGE_HVR1120:
- fe0->dvb.frontend = dvb_attach(tda10048_attach,
- &hcw_tda10048_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(tda829x_attach, fe0->dvb.frontend,
- &dev->i2c_adap, 0x4b,
- &tda829x_no_probe);
- dvb_attach(tda18271_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_adap,
- &hcw_tda18271_config);
- }
- break;
- case SAA7134_BOARD_PHILIPS_TIGER:
- if (configure_tda827x_fe(dev, &philips_tiger_config,
- &tda827x_cfg_0) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_PINNACLE_PCTV_310i:
- if (configure_tda827x_fe(dev, &pinnacle_pctv_310i_config,
- &tda827x_cfg_1) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_HAUPPAUGE_HVR1110:
- if (configure_tda827x_fe(dev, &hauppauge_hvr_1110_config,
- &tda827x_cfg_1) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_HAUPPAUGE_HVR1150:
- fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
- &hcw_lgdt3305_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- dvb_attach(tda829x_attach, fe0->dvb.frontend,
- &dev->i2c_adap, 0x4b,
- &tda829x_no_probe);
- dvb_attach(tda18271_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_adap,
- &hcw_tda18271_config);
- }
- break;
- case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
- if (configure_tda827x_fe(dev, &asus_p7131_dual_config,
- &tda827x_cfg_0) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_FLYDVBT_LR301:
- if (configure_tda827x_fe(dev, &tda827x_lifeview_config,
- &tda827x_cfg_0) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_FLYDVB_TRIO:
- if (!use_frontend) { /* terrestrial */
- if (configure_tda827x_fe(dev, &lifeview_trio_config,
- &tda827x_cfg_0) < 0)
- goto detach_frontend;
- } else { /* satellite */
- fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63,
- &dev->i2c_adap, 0) == NULL) {
- wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);
- goto detach_frontend;
- }
- if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap,
- 0x08, 0, 0) == NULL) {
- wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);
- goto detach_frontend;
- }
- }
- }
- break;
- case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
- case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
- fe0->dvb.frontend = dvb_attach(tda10046_attach,
- &ads_tech_duo_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- if (dvb_attach(tda827x_attach,fe0->dvb.frontend,
- ads_tech_duo_config.tuner_address, &dev->i2c_adap,
- &ads_duo_cfg) == NULL) {
- wprintk("no tda827x tuner found at addr: %02x\n",
- ads_tech_duo_config.tuner_address);
- goto detach_frontend;
- }
- } else
- wprintk("failed to attach tda10046\n");
- break;
- case SAA7134_BOARD_TEVION_DVBT_220RF:
- if (configure_tda827x_fe(dev, &tevion_dvbt220rf_config,
- &tda827x_cfg_0) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_MEDION_MD8800_QUADRO:
- if (!use_frontend) { /* terrestrial */
- if (configure_tda827x_fe(dev, &md8800_dvbt_config,
- &tda827x_cfg_0) < 0)
- goto detach_frontend;
- } else { /* satellite */
- fe0->dvb.frontend = dvb_attach(tda10086_attach,
- &flydvbs, &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- struct dvb_frontend *fe = fe0->dvb.frontend;
- u8 dev_id = dev->eedata[2];
- u8 data = 0xc4;
- struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1};
-
- if (dvb_attach(tda826x_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_adap, 0) == NULL) {
- wprintk("%s: Medion Quadro, no tda826x "
- "found !\n", __func__);
- goto detach_frontend;
- }
- if (dev_id != 0x08) {
- /* we need to open the i2c gate (we know it exists) */
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (dvb_attach(isl6405_attach, fe,
- &dev->i2c_adap, 0x08, 0, 0) == NULL) {
- wprintk("%s: Medion Quadro, no ISL6405 "
- "found !\n", __func__);
- goto detach_frontend;
- }
- if (dev_id == 0x07) {
- /* fire up the 2nd section of the LNB supply since
- we can't do this from the other section */
- msg.buf = &data;
- i2c_transfer(&dev->i2c_adap, &msg, 1);
- }
- fe->ops.i2c_gate_ctrl(fe, 0);
- dev->original_set_voltage = fe->ops.set_voltage;
- fe->ops.set_voltage = md8800_set_voltage;
- dev->original_set_high_voltage = fe->ops.enable_high_lnb_voltage;
- fe->ops.enable_high_lnb_voltage = md8800_set_high_voltage;
- } else {
- fe->ops.set_voltage = md8800_set_voltage2;
- fe->ops.enable_high_lnb_voltage = md8800_set_high_voltage2;
- }
- }
- }
- break;
- case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
- fe0->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
- &dev->i2c_adap);
- if (fe0->dvb.frontend)
- dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61,
- NULL, DVB_PLL_TDHU2);
- break;
- case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
- case SAA7134_BOARD_KWORLD_ATSC110:
- fe0->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
- &dev->i2c_adap);
- if (fe0->dvb.frontend)
- dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &dev->i2c_adap, 0x61,
- TUNER_PHILIPS_TUV1236D);
- break;
- case SAA7134_BOARD_KWORLD_PC150U:
- saa7134_set_gpio(dev, 18, 1); /* Switch to digital mode */
- saa7134_tuner_callback(dev, 0,
- TDA18271_CALLBACK_CMD_AGC_ENABLE, 1);
- fe0->dvb.frontend = dvb_attach(s5h1411_attach,
- &kworld_s5h1411_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(tda829x_attach, fe0->dvb.frontend,
- &dev->i2c_adap, 0x4b,
- &tda829x_no_probe);
- dvb_attach(tda18271_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_adap,
- &kworld_pc150u_tda18271_config);
- }
- break;
- case SAA7134_BOARD_FLYDVBS_LR300:
- fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60,
- &dev->i2c_adap, 0) == NULL) {
- wprintk("%s: No tda826x found!\n", __func__);
- goto detach_frontend;
- }
- if (dvb_attach(isl6421_attach, fe0->dvb.frontend,
- &dev->i2c_adap, 0x08, 0, 0) == NULL) {
- wprintk("%s: No ISL6421 found!\n", __func__);
- goto detach_frontend;
- }
- }
- break;
- case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
- fe0->dvb.frontend = dvb_attach(tda10046_attach,
- &medion_cardbus,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep;
- fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
-
- dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &dev->i2c_adap, medion_cardbus.tuner_address,
- TUNER_PHILIPS_FMD1216ME_MK3);
- }
- break;
- case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
- fe0->dvb.frontend = dvb_attach(tda10046_attach,
- &philips_europa_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- fe0->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init;
- fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
- }
- break;
- case SAA7134_BOARD_CINERGY_HT_PCMCIA:
- if (configure_tda827x_fe(dev, &cinergy_ht_config,
- &tda827x_cfg_0) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_CINERGY_HT_PCI:
- if (configure_tda827x_fe(dev, &cinergy_ht_pci_config,
- &tda827x_cfg_0) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_PHILIPS_TIGER_S:
- if (configure_tda827x_fe(dev, &philips_tiger_s_config,
- &tda827x_cfg_2) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_ASUS_P7131_4871:
- if (configure_tda827x_fe(dev, &asus_p7131_4871_config,
- &tda827x_cfg_2) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
- if (configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config,
- &tda827x_cfg_2) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_AVERMEDIA_SUPER_007:
- if (configure_tda827x_fe(dev, &avermedia_super_007_config,
- &tda827x_cfg_0) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
- if (configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config,
- &tda827x_cfg_2_sw42) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_PHILIPS_SNAKE:
- fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60,
- &dev->i2c_adap, 0) == NULL) {
- wprintk("%s: No tda826x found!\n", __func__);
- goto detach_frontend;
- }
- if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
- &dev->i2c_adap, 0, 0) == NULL) {
- wprintk("%s: No lnbp21 found!\n", __func__);
- goto detach_frontend;
- }
- }
- break;
- case SAA7134_BOARD_CREATIX_CTX953:
- if (configure_tda827x_fe(dev, &md8800_dvbt_config,
- &tda827x_cfg_0) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_MSI_TVANYWHERE_AD11:
- if (configure_tda827x_fe(dev, &philips_tiger_s_config,
- &tda827x_cfg_2) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
- dprintk("AverMedia E506R dvb setup\n");
- saa7134_set_gpio(dev, 25, 0);
- msleep(10);
- saa7134_set_gpio(dev, 25, 1);
- fe0->dvb.frontend = dvb_attach(mt352_attach,
- &avermedia_xc3028_mt352_dev,
- &dev->i2c_adap);
- attach_xc3028 = 1;
- break;
- case SAA7134_BOARD_MD7134_BRIDGE_2:
- fe0->dvb.frontend = dvb_attach(tda10086_attach,
- &sd1878_4m, &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- struct dvb_frontend *fe;
- if (dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
- &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) {
- wprintk("%s: MD7134 DVB-S, no SD1878 "
- "found !\n", __func__);
- goto detach_frontend;
- }
- /* we need to open the i2c gate (we know it exists) */
- fe = fe0->dvb.frontend;
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (dvb_attach(isl6405_attach, fe,
- &dev->i2c_adap, 0x08, 0, 0) == NULL) {
- wprintk("%s: MD7134 DVB-S, no ISL6405 "
- "found !\n", __func__);
- goto detach_frontend;
- }
- fe->ops.i2c_gate_ctrl(fe, 0);
- dev->original_set_voltage = fe->ops.set_voltage;
- fe->ops.set_voltage = md8800_set_voltage;
- dev->original_set_high_voltage = fe->ops.enable_high_lnb_voltage;
- fe->ops.enable_high_lnb_voltage = md8800_set_high_voltage;
- }
- break;
- case SAA7134_BOARD_AVERMEDIA_M103:
- saa7134_set_gpio(dev, 25, 0);
- msleep(10);
- saa7134_set_gpio(dev, 25, 1);
- fe0->dvb.frontend = dvb_attach(mt352_attach,
- &avermedia_xc3028_mt352_dev,
- &dev->i2c_adap);
- attach_xc3028 = 1;
- break;
- case SAA7134_BOARD_ASUSTeK_TIGER_3IN1:
- if (!use_frontend) { /* terrestrial */
- if (configure_tda827x_fe(dev, &asus_tiger_3in1_config,
- &tda827x_cfg_2) < 0)
- goto detach_frontend;
- } else { /* satellite */
- fe0->dvb.frontend = dvb_attach(tda10086_attach,
- &flydvbs, &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- if (dvb_attach(tda826x_attach,
- fe0->dvb.frontend, 0x60,
- &dev->i2c_adap, 0) == NULL) {
- wprintk("%s: Asus Tiger 3in1, no "
- "tda826x found!\n", __func__);
- goto detach_frontend;
- }
- if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
- &dev->i2c_adap, 0, 0) == NULL) {
- wprintk("%s: Asus Tiger 3in1, no lnbp21"
- " found!\n", __func__);
- goto detach_frontend;
- }
- }
- }
- break;
- case SAA7134_BOARD_ASUSTeK_PS3_100:
- if (!use_frontend) { /* terrestrial */
- if (configure_tda827x_fe(dev, &asus_ps3_100_config,
- &tda827x_cfg_2) < 0)
- goto detach_frontend;
- } else { /* satellite */
- fe0->dvb.frontend = dvb_attach(tda10086_attach,
- &flydvbs, &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- if (dvb_attach(tda826x_attach,
- fe0->dvb.frontend, 0x60,
- &dev->i2c_adap, 0) == NULL) {
- wprintk("%s: Asus My Cinema PS3-100, no "
- "tda826x found!\n", __func__);
- goto detach_frontend;
- }
- if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
- &dev->i2c_adap, 0, 0) == NULL) {
- wprintk("%s: Asus My Cinema PS3-100, no lnbp21"
- " found!\n", __func__);
- goto detach_frontend;
- }
- }
- }
- break;
- case SAA7134_BOARD_ASUSTeK_TIGER:
- if (configure_tda827x_fe(dev, &philips_tiger_config,
- &tda827x_cfg_0) < 0)
- goto detach_frontend;
- break;
- case SAA7134_BOARD_BEHOLD_H6:
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &behold_h6_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
- &dev->i2c_adap, 0x61,
- TUNER_PHILIPS_FMD1216MEX_MK3);
- }
- break;
- case SAA7134_BOARD_BEHOLD_X7:
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &behold_x7_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- dvb_attach(xc5000_attach, fe0->dvb.frontend,
- &dev->i2c_adap, &behold_x7_tunerconfig);
- }
- break;
- case SAA7134_BOARD_BEHOLD_H7:
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &behold_x7_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- dvb_attach(xc5000_attach, fe0->dvb.frontend,
- &dev->i2c_adap, &behold_x7_tunerconfig);
- }
- break;
- case SAA7134_BOARD_AVERMEDIA_A700_PRO:
- case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
- /* Zarlink ZL10313 */
- fe0->dvb.frontend = dvb_attach(mt312_attach,
- &avertv_a700_mt312, &dev->i2c_adap);
- if (fe0->dvb.frontend) {
- if (dvb_attach(zl10036_attach, fe0->dvb.frontend,
- &avertv_a700_tuner, &dev->i2c_adap) == NULL) {
- wprintk("%s: No zl10036 found!\n",
- __func__);
- }
- }
- break;
- case SAA7134_BOARD_VIDEOMATE_S350:
- fe0->dvb.frontend = dvb_attach(mt312_attach,
- &zl10313_compro_s350_config, &dev->i2c_adap);
- if (fe0->dvb.frontend)
- if (dvb_attach(zl10039_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_adap) == NULL)
- wprintk("%s: No zl10039 found!\n",
- __func__);
-
- break;
- case SAA7134_BOARD_VIDEOMATE_T750:
- fe0->dvb.frontend = dvb_attach(zl10353_attach,
- &videomate_t750_zl10353_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- if (dvb_attach(qt1010_attach,
- fe0->dvb.frontend,
- &dev->i2c_adap,
- &videomate_t750_qt1010_config) == NULL)
- wprintk("error attaching QT1010\n");
- }
- break;
- case SAA7134_BOARD_ZOLID_HYBRID_PCI:
- fe0->dvb.frontend = dvb_attach(tda10048_attach,
- &zolid_tda10048_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(tda829x_attach, fe0->dvb.frontend,
- &dev->i2c_adap, 0x4b,
- &tda829x_no_probe);
- dvb_attach(tda18271_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_adap,
- &zolid_tda18271_config);
- }
- break;
- case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
- fe0->dvb.frontend = dvb_attach(tda10048_attach,
- &dtv1000s_tda10048_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(tda829x_attach, fe0->dvb.frontend,
- &dev->i2c_adap, 0x4b,
- &tda829x_no_probe);
- dvb_attach(tda18271_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_adap,
- &dtv1000s_tda18271_config);
- }
- break;
- case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
- /* Switch to digital mode */
- saa7134_tuner_callback(dev, 0,
- TDA18271_CALLBACK_CMD_AGC_ENABLE, 1);
- fe0->dvb.frontend = dvb_attach(mb86a20s_attach,
- &kworld_mb86a20s_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(tda829x_attach, fe0->dvb.frontend,
- &dev->i2c_adap, 0x4b,
- &tda829x_no_probe);
- dvb_attach(tda18271_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_adap,
- &kworld_tda18271_config);
- fe0->dvb.frontend->ops.i2c_gate_ctrl = kworld_sbtvd_gate_ctrl;
- }
-
- /* mb86a20s need to use the I2C gateway */
- break;
- case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
- fe0->dvb.frontend = dvb_attach(lgs8gxx_attach,
- &prohdtv_pro2_lgs8g75_config,
- &dev->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(tda829x_attach, fe0->dvb.frontend,
- &dev->i2c_adap, 0x4b,
- &tda829x_no_probe);
- dvb_attach(tda18271_attach, fe0->dvb.frontend,
- 0x60, &dev->i2c_adap,
- &prohdtv_pro2_tda18271_config);
- }
- break;
- default:
- wprintk("Huh? unknown DVB card?\n");
- break;
- }
-
- if (attach_xc3028) {
- struct dvb_frontend *fe;
- struct xc2028_config cfg = {
- .i2c_adap = &dev->i2c_adap,
- .i2c_addr = 0x61,
- };
-
- if (!fe0->dvb.frontend)
- goto detach_frontend;
-
- fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
- if (!fe) {
- printk(KERN_ERR "%s/2: xc3028 attach failed\n",
- dev->name);
- goto detach_frontend;
- }
- }
-
- if (NULL == fe0->dvb.frontend) {
- printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name);
- goto detach_frontend;
- }
- /* define general-purpose callback pointer */
- fe0->dvb.frontend->callback = saa7134_tuner_callback;
-
- /* register everything else */
- ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
- &dev->pci->dev, adapter_nr, 0, NULL);
-
- /* this sequence is necessary to make the tda1004x load its firmware
- * and to enter analog mode of hybrid boards
- */
- if (!ret) {
- if (fe0->dvb.frontend->ops.init)
- fe0->dvb.frontend->ops.init(fe0->dvb.frontend);
- if (fe0->dvb.frontend->ops.sleep)
- fe0->dvb.frontend->ops.sleep(fe0->dvb.frontend);
- if (fe0->dvb.frontend->ops.tuner_ops.sleep)
- fe0->dvb.frontend->ops.tuner_ops.sleep(fe0->dvb.frontend);
- }
- return ret;
-
-detach_frontend:
- videobuf_dvb_dealloc_frontends(&dev->frontends);
- return -EINVAL;
-}
-
-static int dvb_fini(struct saa7134_dev *dev)
-{
- struct videobuf_dvb_frontend *fe0;
-
- /* Get the first frontend */
- fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
- if (!fe0)
- return -EINVAL;
-
- /* FIXME: I suspect that this code is bogus, since the entry for
- Pinnacle 300I DVB-T PAL already defines the proper init to allow
- the detection of mt2032 (TDA9887_PORT2_INACTIVE)
- */
- if (dev->board == SAA7134_BOARD_PINNACLE_300I_DVBT_PAL) {
- struct v4l2_priv_tun_config tda9887_cfg;
- static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
-
- tda9887_cfg.tuner = TUNER_TDA9887;
- tda9887_cfg.priv = &on;
-
- /* otherwise we don't detect the tuner on next insmod */
- saa_call_all(dev, tuner, s_config, &tda9887_cfg);
- } else if (dev->board == SAA7134_BOARD_MEDION_MD8800_QUADRO) {
- if ((dev->eedata[2] == 0x07) && use_frontend) {
- /* turn off the 2nd lnb supply */
- u8 data = 0x80;
- struct i2c_msg msg = {.addr = 0x08, .buf = &data, .flags = 0, .len = 1};
- struct dvb_frontend *fe;
- fe = fe0->dvb.frontend;
- if (fe->ops.i2c_gate_ctrl) {
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(&dev->i2c_adap, &msg, 1);
- fe->ops.i2c_gate_ctrl(fe, 0);
- }
- }
- }
- videobuf_dvb_unregister_bus(&dev->frontends);
- return 0;
-}
-
-static struct saa7134_mpeg_ops dvb_ops = {
- .type = SAA7134_MPEG_DVB,
- .init = dvb_init,
- .fini = dvb_fini,
-};
-
-static int __init dvb_register(void)
-{
- return saa7134_ts_register(&dvb_ops);
-}
-
-static void __exit dvb_unregister(void)
-{
- saa7134_ts_unregister(&dvb_ops);
-}
-
-module_init(dvb_register);
-module_exit(dvb_unregister);
-
-/* ------------------------------------------------------------------ */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
deleted file mode 100644
index 4df79c65690..00000000000
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ /dev/null
@@ -1,590 +0,0 @@
-/*
- *
- * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-
-#include "saa7134-reg.h"
-#include "saa7134.h"
-
-#include <media/saa6752hs.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-
-/* ------------------------------------------------------------------ */
-
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
-MODULE_LICENSE("GPL");
-
-static unsigned int empress_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
-
-module_param_array(empress_nr, int, NULL, 0444);
-MODULE_PARM_DESC(empress_nr,"ts device number");
-
-static unsigned int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug,"enable debug messages");
-
-#define dprintk(fmt, arg...) if (debug) \
- printk(KERN_DEBUG "%s/empress: " fmt, dev->name , ## arg)
-
-/* ------------------------------------------------------------------ */
-
-static void ts_reset_encoder(struct saa7134_dev* dev)
-{
- if (!dev->empress_started)
- return;
-
- saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
- msleep(10);
- saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
- msleep(100);
- dev->empress_started = 0;
-}
-
-static int ts_init_encoder(struct saa7134_dev* dev)
-{
- u32 leading_null_bytes = 0;
-
- /* If more cards start to need this, then this
- should probably be added to the card definitions. */
- switch (dev->board) {
- case SAA7134_BOARD_BEHOLD_M6:
- case SAA7134_BOARD_BEHOLD_M63:
- case SAA7134_BOARD_BEHOLD_M6_EXTRA:
- leading_null_bytes = 1;
- break;
- }
- ts_reset_encoder(dev);
- saa_call_all(dev, core, init, leading_null_bytes);
- dev->empress_started = 1;
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int ts_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct saa7134_dev *dev = video_drvdata(file);
- int err;
-
- dprintk("open dev=%s\n", video_device_node_name(vdev));
- err = -EBUSY;
- if (!mutex_trylock(&dev->empress_tsq.vb_lock))
- return err;
- if (atomic_read(&dev->empress_users))
- goto done;
-
- /* Unmute audio */
- saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
- saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6));
-
- atomic_inc(&dev->empress_users);
- file->private_data = dev;
- err = 0;
-
-done:
- mutex_unlock(&dev->empress_tsq.vb_lock);
- return err;
-}
-
-static int ts_release(struct file *file)
-{
- struct saa7134_dev *dev = file->private_data;
-
- videobuf_stop(&dev->empress_tsq);
- videobuf_mmap_free(&dev->empress_tsq);
-
- /* stop the encoder */
- ts_reset_encoder(dev);
-
- /* Mute audio */
- saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
- saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
-
- atomic_dec(&dev->empress_users);
-
- return 0;
-}
-
-static ssize_t
-ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
-{
- struct saa7134_dev *dev = file->private_data;
-
- if (!dev->empress_started)
- ts_init_encoder(dev);
-
- return videobuf_read_stream(&dev->empress_tsq,
- data, count, ppos, 0,
- file->f_flags & O_NONBLOCK);
-}
-
-static unsigned int
-ts_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct saa7134_dev *dev = file->private_data;
-
- return videobuf_poll_stream(file, &dev->empress_tsq, wait);
-}
-
-
-static int
-ts_mmap(struct file *file, struct vm_area_struct * vma)
-{
- struct saa7134_dev *dev = file->private_data;
-
- return videobuf_mmap_mapper(&dev->empress_tsq, vma);
-}
-
-/*
- * This function is _not_ called directly, but from
- * video_generic_ioctl (and maybe others). userspace
- * copying is done already, arg is a kernel pointer.
- */
-
-static int empress_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct saa7134_dev *dev = file->private_data;
-
- strcpy(cap->driver, "saa7134");
- strlcpy(cap->card, saa7134_boards[dev->board].name,
- sizeof(cap->card));
- sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
- cap->capabilities =
- V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING;
- return 0;
-}
-
-static int empress_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- if (i->index != 0)
- return -EINVAL;
-
- i->type = V4L2_INPUT_TYPE_CAMERA;
- strcpy(i->name, "CCIR656");
-
- return 0;
-}
-
-static int empress_g_input(struct file *file, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int empress_s_input(struct file *file, void *priv, unsigned int i)
-{
- if (i != 0)
- return -EINVAL;
-
- return 0;
-}
-
-static int empress_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (f->index != 0)
- return -EINVAL;
-
- strlcpy(f->description, "MPEG TS", sizeof(f->description));
- f->pixelformat = V4L2_PIX_FMT_MPEG;
-
- return 0;
-}
-
-static int empress_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7134_dev *dev = file->private_data;
- struct v4l2_mbus_framefmt mbus_fmt;
-
- saa_call_all(dev, video, g_mbus_fmt, &mbus_fmt);
-
- v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
-
- return 0;
-}
-
-static int empress_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7134_dev *dev = file->private_data;
- struct v4l2_mbus_framefmt mbus_fmt;
-
- v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
- saa_call_all(dev, video, s_mbus_fmt, &mbus_fmt);
- v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
-
- return 0;
-}
-
-static int empress_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7134_dev *dev = file->private_data;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
-
- return 0;
-}
-
-static int empress_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct saa7134_dev *dev = file->private_data;
-
- return videobuf_reqbufs(&dev->empress_tsq, p);
-}
-
-static int empress_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct saa7134_dev *dev = file->private_data;
-
- return videobuf_querybuf(&dev->empress_tsq, b);
-}
-
-static int empress_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct saa7134_dev *dev = file->private_data;
-
- return videobuf_qbuf(&dev->empress_tsq, b);
-}
-
-static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct saa7134_dev *dev = file->private_data;
-
- return videobuf_dqbuf(&dev->empress_tsq, b,
- file->f_flags & O_NONBLOCK);
-}
-
-static int empress_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct saa7134_dev *dev = file->private_data;
-
- return videobuf_streamon(&dev->empress_tsq);
-}
-
-static int empress_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct saa7134_dev *dev = file->private_data;
-
- return videobuf_streamoff(&dev->empress_tsq);
-}
-
-static int empress_s_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- struct saa7134_dev *dev = file->private_data;
- int err;
-
- /* count == 0 is abused in saa6752hs.c, so that special
- case is handled here explicitly. */
- if (ctrls->count == 0)
- return 0;
-
- if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
-
- err = saa_call_empress(dev, core, s_ext_ctrls, ctrls);
- ts_init_encoder(dev);
-
- return err;
-}
-
-static int empress_g_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- struct saa7134_dev *dev = file->private_data;
-
- if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
- return saa_call_empress(dev, core, g_ext_ctrls, ctrls);
-}
-
-static int empress_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *c)
-{
- struct saa7134_dev *dev = file->private_data;
-
- return saa7134_g_ctrl_internal(dev, NULL, c);
-}
-
-static int empress_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *c)
-{
- struct saa7134_dev *dev = file->private_data;
-
- return saa7134_s_ctrl_internal(dev, NULL, c);
-}
-
-static int empress_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *c)
-{
- /* Must be sorted from low to high control ID! */
- static const u32 user_ctrls[] = {
- V4L2_CID_USER_CLASS,
- V4L2_CID_BRIGHTNESS,
- V4L2_CID_CONTRAST,
- V4L2_CID_SATURATION,
- V4L2_CID_HUE,
- V4L2_CID_AUDIO_VOLUME,
- V4L2_CID_AUDIO_MUTE,
- V4L2_CID_HFLIP,
- 0
- };
-
- /* Must be sorted from low to high control ID! */
- static const u32 mpeg_ctrls[] = {
- V4L2_CID_MPEG_CLASS,
- V4L2_CID_MPEG_STREAM_TYPE,
- V4L2_CID_MPEG_STREAM_PID_PMT,
- V4L2_CID_MPEG_STREAM_PID_AUDIO,
- V4L2_CID_MPEG_STREAM_PID_VIDEO,
- V4L2_CID_MPEG_STREAM_PID_PCR,
- V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
- V4L2_CID_MPEG_AUDIO_ENCODING,
- V4L2_CID_MPEG_AUDIO_L2_BITRATE,
- V4L2_CID_MPEG_VIDEO_ENCODING,
- V4L2_CID_MPEG_VIDEO_ASPECT,
- V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
- V4L2_CID_MPEG_VIDEO_BITRATE,
- V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
- 0
- };
- static const u32 *ctrl_classes[] = {
- user_ctrls,
- mpeg_ctrls,
- NULL
- };
- struct saa7134_dev *dev = file->private_data;
-
- c->id = v4l2_ctrl_next(ctrl_classes, c->id);
- if (c->id == 0)
- return -EINVAL;
- if (c->id == V4L2_CID_USER_CLASS || c->id == V4L2_CID_MPEG_CLASS)
- return v4l2_ctrl_query_fill(c, 0, 0, 0, 0);
- if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
- return saa7134_queryctrl(file, priv, c);
- return saa_call_empress(dev, core, queryctrl, c);
-}
-
-static int empress_querymenu(struct file *file, void *priv,
- struct v4l2_querymenu *c)
-{
- struct saa7134_dev *dev = file->private_data;
-
- if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
- return saa_call_empress(dev, core, querymenu, c);
-}
-
-static int empress_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct saa7134_dev *dev = file->private_data;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type == V4L2_CHIP_MATCH_I2C_DRIVER &&
- !strcmp(chip->match.name, "saa6752hs"))
- return saa_call_empress(dev, core, g_chip_ident, chip);
- if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR)
- return saa_call_empress(dev, core, g_chip_ident, chip);
- return -EINVAL;
-}
-
-static int empress_s_std(struct file *file, void *priv, v4l2_std_id *id)
-{
- struct saa7134_dev *dev = file->private_data;
-
- return saa7134_s_std_internal(dev, NULL, id);
-}
-
-static int empress_g_std(struct file *file, void *priv, v4l2_std_id *id)
-{
- struct saa7134_dev *dev = file->private_data;
-
- *id = dev->tvnorm->id;
- return 0;
-}
-
-static const struct v4l2_file_operations ts_fops =
-{
- .owner = THIS_MODULE,
- .open = ts_open,
- .release = ts_release,
- .read = ts_read,
- .poll = ts_poll,
- .mmap = ts_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops ts_ioctl_ops = {
- .vidioc_querycap = empress_querycap,
- .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap,
- .vidioc_reqbufs = empress_reqbufs,
- .vidioc_querybuf = empress_querybuf,
- .vidioc_qbuf = empress_qbuf,
- .vidioc_dqbuf = empress_dqbuf,
- .vidioc_streamon = empress_streamon,
- .vidioc_streamoff = empress_streamoff,
- .vidioc_s_ext_ctrls = empress_s_ext_ctrls,
- .vidioc_g_ext_ctrls = empress_g_ext_ctrls,
- .vidioc_enum_input = empress_enum_input,
- .vidioc_g_input = empress_g_input,
- .vidioc_s_input = empress_s_input,
- .vidioc_queryctrl = empress_queryctrl,
- .vidioc_querymenu = empress_querymenu,
- .vidioc_g_ctrl = empress_g_ctrl,
- .vidioc_s_ctrl = empress_s_ctrl,
- .vidioc_g_chip_ident = empress_g_chip_ident,
- .vidioc_s_std = empress_s_std,
- .vidioc_g_std = empress_g_std,
-};
-
-/* ----------------------------------------------------------- */
-
-static struct video_device saa7134_empress_template = {
- .name = "saa7134-empress",
- .fops = &ts_fops,
- .ioctl_ops = &ts_ioctl_ops,
-
- .tvnorms = SAA7134_NORMS,
- .current_norm = V4L2_STD_PAL,
-};
-
-static void empress_signal_update(struct work_struct *work)
-{
- struct saa7134_dev* dev =
- container_of(work, struct saa7134_dev, empress_workqueue);
-
- if (dev->nosignal) {
- dprintk("no video signal\n");
- } else {
- dprintk("video signal acquired\n");
- }
-}
-
-static void empress_signal_change(struct saa7134_dev *dev)
-{
- schedule_work(&dev->empress_workqueue);
-}
-
-
-static int empress_init(struct saa7134_dev *dev)
-{
- int err;
-
- dprintk("%s: %s\n",dev->name,__func__);
- dev->empress_dev = video_device_alloc();
- if (NULL == dev->empress_dev)
- return -ENOMEM;
- *(dev->empress_dev) = saa7134_empress_template;
- dev->empress_dev->parent = &dev->pci->dev;
- dev->empress_dev->release = video_device_release;
- snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
- "%s empress (%s)", dev->name,
- saa7134_boards[dev->board].name);
-
- INIT_WORK(&dev->empress_workqueue, empress_signal_update);
-
- video_set_drvdata(dev->empress_dev, dev);
- err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,
- empress_nr[dev->nr]);
- if (err < 0) {
- printk(KERN_INFO "%s: can't register video device\n",
- dev->name);
- video_device_release(dev->empress_dev);
- dev->empress_dev = NULL;
- return err;
- }
- printk(KERN_INFO "%s: registered device %s [mpeg]\n",
- dev->name, video_device_node_name(dev->empress_dev));
-
- videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_ALTERNATE,
- sizeof(struct saa7134_buf),
- dev, NULL);
-
- empress_signal_update(&dev->empress_workqueue);
- return 0;
-}
-
-static int empress_fini(struct saa7134_dev *dev)
-{
- dprintk("%s: %s\n",dev->name,__func__);
-
- if (NULL == dev->empress_dev)
- return 0;
- flush_work(&dev->empress_workqueue);
- video_unregister_device(dev->empress_dev);
- dev->empress_dev = NULL;
- return 0;
-}
-
-static struct saa7134_mpeg_ops empress_ops = {
- .type = SAA7134_MPEG_EMPRESS,
- .init = empress_init,
- .fini = empress_fini,
- .signal_change = empress_signal_change,
-};
-
-static int __init empress_register(void)
-{
- return saa7134_ts_register(&empress_ops);
-}
-
-static void __exit empress_unregister(void)
-{
- saa7134_ts_unregister(&empress_ops);
-}
-
-module_init(empress_register);
-module_exit(empress_unregister);
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
deleted file mode 100644
index a176ec3285e..00000000000
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- *
- * device driver for philips saa7134 based TV cards
- * i2c interface support
- *
- * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-
-#include "saa7134-reg.h"
-#include "saa7134.h"
-#include <media/v4l2-common.h>
-
-/* ----------------------------------------------------------- */
-
-static unsigned int i2c_debug;
-module_param(i2c_debug, int, 0644);
-MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]");
-
-static unsigned int i2c_scan;
-module_param(i2c_scan, int, 0444);
-MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
-
-#define d1printk if (1 == i2c_debug) printk
-#define d2printk if (2 == i2c_debug) printk
-
-#define I2C_WAIT_DELAY 32
-#define I2C_WAIT_RETRY 16
-
-/* ----------------------------------------------------------- */
-
-static char *str_i2c_status[] = {
- "IDLE", "DONE_STOP", "BUSY", "TO_SCL", "TO_ARB", "DONE_WRITE",
- "DONE_READ", "DONE_WRITE_TO", "DONE_READ_TO", "NO_DEVICE",
- "NO_ACKN", "BUS_ERR", "ARB_LOST", "SEQ_ERR", "ST_ERR", "SW_ERR"
-};
-
-enum i2c_status {
- IDLE = 0, // no I2C command pending
- DONE_STOP = 1, // I2C command done and STOP executed
- BUSY = 2, // executing I2C command
- TO_SCL = 3, // executing I2C command, time out on clock stretching
- TO_ARB = 4, // time out on arbitration trial, still trying
- DONE_WRITE = 5, // I2C command done and awaiting next write command
- DONE_READ = 6, // I2C command done and awaiting next read command
- DONE_WRITE_TO = 7, // see 5, and time out on status echo
- DONE_READ_TO = 8, // see 6, and time out on status echo
- NO_DEVICE = 9, // no acknowledge on device slave address
- NO_ACKN = 10, // no acknowledge after data byte transfer
- BUS_ERR = 11, // bus error
- ARB_LOST = 12, // arbitration lost during transfer
- SEQ_ERR = 13, // erroneous programming sequence
- ST_ERR = 14, // wrong status echoing
- SW_ERR = 15 // software error
-};
-
-static char *str_i2c_attr[] = {
- "NOP", "STOP", "CONTINUE", "START"
-};
-
-enum i2c_attr {
- NOP = 0, // no operation on I2C bus
- STOP = 1, // stop condition, no associated byte transfer
- CONTINUE = 2, // continue with byte transfer
- START = 3 // start condition with byte transfer
-};
-
-static inline enum i2c_status i2c_get_status(struct saa7134_dev *dev)
-{
- enum i2c_status status;
-
- status = saa_readb(SAA7134_I2C_ATTR_STATUS) & 0x0f;
- d2printk(KERN_DEBUG "%s: i2c stat <= %s\n",dev->name,
- str_i2c_status[status]);
- return status;
-}
-
-static inline void i2c_set_status(struct saa7134_dev *dev,
- enum i2c_status status)
-{
- d2printk(KERN_DEBUG "%s: i2c stat => %s\n",dev->name,
- str_i2c_status[status]);
- saa_andorb(SAA7134_I2C_ATTR_STATUS,0x0f,status);
-}
-
-static inline void i2c_set_attr(struct saa7134_dev *dev, enum i2c_attr attr)
-{
- d2printk(KERN_DEBUG "%s: i2c attr => %s\n",dev->name,
- str_i2c_attr[attr]);
- saa_andorb(SAA7134_I2C_ATTR_STATUS,0xc0,attr << 6);
-}
-
-static inline int i2c_is_error(enum i2c_status status)
-{
- switch (status) {
- case NO_DEVICE:
- case NO_ACKN:
- case BUS_ERR:
- case ARB_LOST:
- case SEQ_ERR:
- case ST_ERR:
- return true;
- default:
- return false;
- }
-}
-
-static inline int i2c_is_idle(enum i2c_status status)
-{
- switch (status) {
- case IDLE:
- case DONE_STOP:
- return true;
- default:
- return false;
- }
-}
-
-static inline int i2c_is_busy(enum i2c_status status)
-{
- switch (status) {
- case BUSY:
- case TO_SCL:
- case TO_ARB:
- return true;
- default:
- return false;
- }
-}
-
-static int i2c_is_busy_wait(struct saa7134_dev *dev)
-{
- enum i2c_status status;
- int count;
-
- for (count = 0; count < I2C_WAIT_RETRY; count++) {
- status = i2c_get_status(dev);
- if (!i2c_is_busy(status))
- break;
- saa_wait(I2C_WAIT_DELAY);
- }
- if (I2C_WAIT_RETRY == count)
- return false;
- return true;
-}
-
-static int i2c_reset(struct saa7134_dev *dev)
-{
- enum i2c_status status;
- int count;
-
- d2printk(KERN_DEBUG "%s: i2c reset\n",dev->name);
- status = i2c_get_status(dev);
- if (!i2c_is_error(status))
- return true;
- i2c_set_status(dev,status);
-
- for (count = 0; count < I2C_WAIT_RETRY; count++) {
- status = i2c_get_status(dev);
- if (!i2c_is_error(status))
- break;
- udelay(I2C_WAIT_DELAY);
- }
- if (I2C_WAIT_RETRY == count)
- return false;
-
- if (!i2c_is_idle(status))
- return false;
-
- i2c_set_attr(dev,NOP);
- return true;
-}
-
-static inline int i2c_send_byte(struct saa7134_dev *dev,
- enum i2c_attr attr,
- unsigned char data)
-{
- enum i2c_status status;
- __u32 dword;
-
- /* have to write both attr + data in one 32bit word */
- dword = saa_readl(SAA7134_I2C_ATTR_STATUS >> 2);
- dword &= 0x0f;
- dword |= (attr << 6);
- dword |= ((__u32)data << 8);
- dword |= 0x00 << 16; /* 100 kHz */
-// dword |= 0x40 << 16; /* 400 kHz */
- dword |= 0xf0 << 24;
- saa_writel(SAA7134_I2C_ATTR_STATUS >> 2, dword);
- d2printk(KERN_DEBUG "%s: i2c data => 0x%x\n",dev->name,data);
-
- if (!i2c_is_busy_wait(dev))
- return -EIO;
- status = i2c_get_status(dev);
- if (i2c_is_error(status))
- return -EIO;
- return 0;
-}
-
-static inline int i2c_recv_byte(struct saa7134_dev *dev)
-{
- enum i2c_status status;
- unsigned char data;
-
- i2c_set_attr(dev,CONTINUE);
- if (!i2c_is_busy_wait(dev))
- return -EIO;
- status = i2c_get_status(dev);
- if (i2c_is_error(status))
- return -EIO;
- data = saa_readb(SAA7134_I2C_DATA);
- d2printk(KERN_DEBUG "%s: i2c data <= 0x%x\n",dev->name,data);
- return data;
-}
-
-static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg *msgs, int num)
-{
- struct saa7134_dev *dev = i2c_adap->algo_data;
- enum i2c_status status;
- unsigned char data;
- int addr,rc,i,byte;
-
- status = i2c_get_status(dev);
- if (!i2c_is_idle(status))
- if (!i2c_reset(dev))
- return -EIO;
-
- d2printk("start xfer\n");
- d1printk(KERN_DEBUG "%s: i2c xfer:",dev->name);
- for (i = 0; i < num; i++) {
- if (!(msgs[i].flags & I2C_M_NOSTART) || 0 == i) {
- /* send address */
- d2printk("send address\n");
- addr = msgs[i].addr << 1;
- if (msgs[i].flags & I2C_M_RD)
- addr |= 1;
- if (i > 0 && msgs[i].flags &
- I2C_M_RD && msgs[i].addr != 0x40 &&
- msgs[i].addr != 0x19) {
- /* workaround for a saa7134 i2c bug
- * needed to talk to the mt352 demux
- * thanks to pinnacle for the hint */
- int quirk = 0xfe;
- d1printk(" [%02x quirk]",quirk);
- i2c_send_byte(dev,START,quirk);
- i2c_recv_byte(dev);
- }
- d1printk(" < %02x", addr);
- rc = i2c_send_byte(dev,START,addr);
- if (rc < 0)
- goto err;
- }
- if (msgs[i].flags & I2C_M_RD) {
- /* read bytes */
- d2printk("read bytes\n");
- for (byte = 0; byte < msgs[i].len; byte++) {
- d1printk(" =");
- rc = i2c_recv_byte(dev);
- if (rc < 0)
- goto err;
- d1printk("%02x", rc);
- msgs[i].buf[byte] = rc;
- }
- /* discard mysterious extra byte when reading
- from Samsung S5H1411. i2c bus gets error
- if we do not. */
- if (0x19 == msgs[i].addr) {
- d1printk(" ?");
- rc = i2c_recv_byte(dev);
- if (rc < 0)
- goto err;
- d1printk("%02x", rc);
- }
- } else {
- /* write bytes */
- d2printk("write bytes\n");
- for (byte = 0; byte < msgs[i].len; byte++) {
- data = msgs[i].buf[byte];
- d1printk(" %02x", data);
- rc = i2c_send_byte(dev,CONTINUE,data);
- if (rc < 0)
- goto err;
- }
- }
- }
- d2printk("xfer done\n");
- d1printk(" >");
- i2c_set_attr(dev,STOP);
- rc = -EIO;
- if (!i2c_is_busy_wait(dev))
- goto err;
- status = i2c_get_status(dev);
- if (i2c_is_error(status))
- goto err;
- /* ensure that the bus is idle for at least one bit slot */
- msleep(1);
-
- d1printk("\n");
- return num;
- err:
- if (1 == i2c_debug) {
- status = i2c_get_status(dev);
- printk(" ERROR: %s\n",str_i2c_status[status]);
- }
- return rc;
-}
-
-/* ----------------------------------------------------------- */
-
-static u32 functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_SMBUS_EMUL;
-}
-
-static struct i2c_algorithm saa7134_algo = {
- .master_xfer = saa7134_i2c_xfer,
- .functionality = functionality,
-};
-
-static struct i2c_adapter saa7134_adap_template = {
- .owner = THIS_MODULE,
- .name = "saa7134",
- .algo = &saa7134_algo,
-};
-
-static struct i2c_client saa7134_client_template = {
- .name = "saa7134 internal",
-};
-
-/* ----------------------------------------------------------- */
-
-static int
-saa7134_i2c_eeprom(struct saa7134_dev *dev, unsigned char *eedata, int len)
-{
- unsigned char buf;
- int i,err;
-
- dev->i2c_client.addr = 0xa0 >> 1;
- buf = 0;
- if (1 != (err = i2c_master_send(&dev->i2c_client,&buf,1))) {
- printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
- dev->name,err);
- return -1;
- }
- if (len != (err = i2c_master_recv(&dev->i2c_client,eedata,len))) {
- printk(KERN_WARNING "%s: i2c eeprom read error (err=%d)\n",
- dev->name,err);
- return -1;
- }
- for (i = 0; i < len; i++) {
- if (0 == (i % 16))
- printk(KERN_INFO "%s: i2c eeprom %02x:",dev->name,i);
- printk(" %02x",eedata[i]);
- if (15 == (i % 16))
- printk("\n");
- }
- return 0;
-}
-
-static char *i2c_devs[128] = {
- [ 0x20 ] = "mpeg encoder (saa6752hs)",
- [ 0xa0 >> 1 ] = "eeprom",
- [ 0xc0 >> 1 ] = "tuner (analog)",
- [ 0x86 >> 1 ] = "tda9887",
- [ 0x5a >> 1 ] = "remote control",
-};
-
-static void do_i2c_scan(char *name, struct i2c_client *c)
-{
- unsigned char buf;
- int i,rc;
-
- for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
- c->addr = i;
- rc = i2c_master_recv(c,&buf,0);
- if (rc < 0)
- continue;
- printk("%s: i2c scan: found device @ 0x%x [%s]\n",
- name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
- }
-}
-
-int saa7134_i2c_register(struct saa7134_dev *dev)
-{
- dev->i2c_adap = saa7134_adap_template;
- dev->i2c_adap.dev.parent = &dev->pci->dev;
- strcpy(dev->i2c_adap.name,dev->name);
- dev->i2c_adap.algo_data = dev;
- i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
- i2c_add_adapter(&dev->i2c_adap);
-
- dev->i2c_client = saa7134_client_template;
- dev->i2c_client.adapter = &dev->i2c_adap;
-
- saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata));
- if (i2c_scan)
- do_i2c_scan(dev->name,&dev->i2c_client);
-
- /* Instantiate the IR receiver device, if present */
- saa7134_probe_i2c_ir(dev);
- return 0;
-}
-
-int saa7134_i2c_unregister(struct saa7134_dev *dev)
-{
- i2c_del_adapter(&dev->i2c_adap);
- return 0;
-}
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
deleted file mode 100644
index 05c6e217d8a..00000000000
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ /dev/null
@@ -1,1045 +0,0 @@
-/*
- *
- * handle saa7134 IR remotes via linux kernel input layer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-
-#include "saa7134-reg.h"
-#include "saa7134.h"
-
-#define MODULE_NAME "saa7134"
-
-static unsigned int disable_ir;
-module_param(disable_ir, int, 0444);
-MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
-
-static unsigned int ir_debug;
-module_param(ir_debug, int, 0644);
-MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
-
-static int pinnacle_remote;
-module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */
-MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)");
-
-#define dprintk(fmt, arg...) if (ir_debug) \
- printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
-#define i2cdprintk(fmt, arg...) if (ir_debug) \
- printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg)
-
-/* Helper function for raw decoding at GPIO16 or GPIO18 */
-static int saa7134_raw_decode_irq(struct saa7134_dev *dev);
-
-/* -------------------- GPIO generic keycode builder -------------------- */
-
-static int build_key(struct saa7134_dev *dev)
-{
- struct saa7134_card_ir *ir = dev->remote;
- u32 gpio, data;
-
- /* here comes the additional handshake steps for some cards */
- switch (dev->board) {
- case SAA7134_BOARD_GOTVIEW_7135:
- saa_setb(SAA7134_GPIO_GPSTATUS1, 0x80);
- saa_clearb(SAA7134_GPIO_GPSTATUS1, 0x80);
- break;
- }
- /* rising SAA7134_GPIO_GPRESCAN reads the status */
- saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
-
- gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
- if (ir->polling) {
- if (ir->last_gpio == gpio)
- return 0;
- ir->last_gpio = gpio;
- }
-
- data = ir_extract_bits(gpio, ir->mask_keycode);
- dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
- gpio, ir->mask_keycode, data);
-
- switch (dev->board) {
- case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
- if (data == ir->mask_keycode)
- rc_keyup(ir->dev);
- else
- rc_keydown_notimeout(ir->dev, data, 0);
- return 0;
- }
-
- if (ir->polling) {
- if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
- (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
- rc_keydown_notimeout(ir->dev, data, 0);
- } else {
- rc_keyup(ir->dev);
- }
- }
- else { /* IRQ driven mode - handle key press and release in one go */
- if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
- (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
- rc_keydown_notimeout(ir->dev, data, 0);
- rc_keyup(ir->dev);
- }
- }
-
- return 0;
-}
-
-/* --------------------- Chip specific I2C key builders ----------------- */
-
-static int get_key_flydvb_trio(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- int gpio;
- int attempt = 0;
- unsigned char b;
-
- /* We need this to access GPI Used by the saa_readl macro. */
- struct saa7134_dev *dev = ir->c->adapter->algo_data;
-
- if (dev == NULL) {
- i2cdprintk("get_key_flydvb_trio: "
- "ir->c->adapter->algo_data is NULL!\n");
- return -EIO;
- }
-
- /* rising SAA7134_GPIGPRESCAN reads the status */
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-
- gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
-
- if (0x40000 & ~gpio)
- return 0; /* No button press */
-
- /* No button press - only before first key pressed */
- if (b == 0xFF)
- return 0;
-
- /* poll IR chip */
- /* weak up the IR chip */
- b = 0;
-
- while (1 != i2c_master_send(ir->c, &b, 1)) {
- if ((attempt++) < 10) {
- /*
- * wait a bit for next attempt -
- * I don't know how make it better
- */
- msleep(10);
- continue;
- }
- i2cdprintk("send wake up byte to pic16C505 (IR chip)"
- "failed %dx\n", attempt);
- return -EIO;
- }
- if (1 != i2c_master_recv(ir->c, &b, 1)) {
- i2cdprintk("read error\n");
- return -EIO;
- }
-
- *ir_key = b;
- *ir_raw = b;
- return 1;
-}
-
-static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
- u32 *ir_raw)
-{
- unsigned char b;
- int gpio;
-
- /* <dev> is needed to access GPIO. Used by the saa_readl macro. */
- struct saa7134_dev *dev = ir->c->adapter->algo_data;
- if (dev == NULL) {
- i2cdprintk("get_key_msi_tvanywhere_plus: "
- "ir->c->adapter->algo_data is NULL!\n");
- return -EIO;
- }
-
- /* rising SAA7134_GPIO_GPRESCAN reads the status */
-
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-
- gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
-
- /* GPIO&0x40 is pulsed low when a button is pressed. Don't do
- I2C receive if gpio&0x40 is not low. */
-
- if (gpio & 0x40)
- return 0; /* No button press */
-
- /* GPIO says there is a button press. Get it. */
-
- if (1 != i2c_master_recv(ir->c, &b, 1)) {
- i2cdprintk("read error\n");
- return -EIO;
- }
-
- /* No button press */
-
- if (b == 0xff)
- return 0;
-
- /* Button pressed */
-
- dprintk("get_key_msi_tvanywhere_plus: Key = 0x%02X\n", b);
- *ir_key = b;
- *ir_raw = b;
- return 1;
-}
-
-/* copied and modified from get_key_msi_tvanywhere_plus() */
-static int get_key_kworld_pc150u(struct IR_i2c *ir, u32 *ir_key,
- u32 *ir_raw)
-{
- unsigned char b;
- unsigned int gpio;
-
- /* <dev> is needed to access GPIO. Used by the saa_readl macro. */
- struct saa7134_dev *dev = ir->c->adapter->algo_data;
- if (dev == NULL) {
- i2cdprintk("get_key_kworld_pc150u: "
- "ir->c->adapter->algo_data is NULL!\n");
- return -EIO;
- }
-
- /* rising SAA7134_GPIO_GPRESCAN reads the status */
-
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-
- gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
-
- /* GPIO&0x100 is pulsed low when a button is pressed. Don't do
- I2C receive if gpio&0x100 is not low. */
-
- if (gpio & 0x100)
- return 0; /* No button press */
-
- /* GPIO says there is a button press. Get it. */
-
- if (1 != i2c_master_recv(ir->c, &b, 1)) {
- i2cdprintk("read error\n");
- return -EIO;
- }
-
- /* No button press */
-
- if (b == 0xff)
- return 0;
-
- /* Button pressed */
-
- dprintk("get_key_kworld_pc150u: Key = 0x%02X\n", b);
- *ir_key = b;
- *ir_raw = b;
- return 1;
-}
-
-static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- unsigned char b;
-
- /* poll IR chip */
- if (1 != i2c_master_recv(ir->c, &b, 1)) {
- i2cdprintk("read error\n");
- return -EIO;
- }
-
- /* no button press */
- if (b==0)
- return 0;
-
- /* repeating */
- if (b & 0x80)
- return 1;
-
- *ir_key = b;
- *ir_raw = b;
- return 1;
-}
-
-static int get_key_hvr1110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- unsigned char buf[5];
-
- /* poll IR chip */
- if (5 != i2c_master_recv(ir->c, buf, 5))
- return -EIO;
-
- /* Check if some key were pressed */
- if (!(buf[0] & 0x80))
- return 0;
-
- /*
- * buf[3] & 0x80 is always high.
- * buf[3] & 0x40 is a parity bit. A repeat event is marked
- * by preserving it into two separate readings
- * buf[4] bits 0 and 1, and buf[1] and buf[2] are always
- * zero.
- */
- *ir_key = 0x1fff & ((buf[3] << 8) | (buf[4] >> 2));
- *ir_raw = *ir_key;
- return 1;
-}
-
-
-static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- unsigned char data[12];
- u32 gpio;
-
- struct saa7134_dev *dev = ir->c->adapter->algo_data;
-
- /* rising SAA7134_GPIO_GPRESCAN reads the status */
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-
- gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
-
- if (0x400000 & ~gpio)
- return 0; /* No button press */
-
- ir->c->addr = 0x5a >> 1;
-
- if (12 != i2c_master_recv(ir->c, data, 12)) {
- i2cdprintk("read error\n");
- return -EIO;
- }
-
- if (data[9] != (unsigned char)(~data[8]))
- return 0;
-
- *ir_raw = ((data[10] << 16) | (data[11] << 8) | (data[9] << 0));
- *ir_key = *ir_raw;
-
- return 1;
-}
-
-/* Common (grey or coloured) pinnacle PCTV remote handling
- *
- */
-static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
- int parity_offset, int marker, int code_modulo)
-{
- unsigned char b[4];
- unsigned int start = 0,parity = 0,code = 0;
-
- /* poll IR chip */
- if (4 != i2c_master_recv(ir->c, b, 4)) {
- i2cdprintk("read error\n");
- return -EIO;
- }
-
- for (start = 0; start < ARRAY_SIZE(b); start++) {
- if (b[start] == marker) {
- code=b[(start+parity_offset + 1) % 4];
- parity=b[(start+parity_offset) % 4];
- }
- }
-
- /* Empty Request */
- if (parity == 0)
- return 0;
-
- /* Repeating... */
- if (ir->old == parity)
- return 0;
-
- ir->old = parity;
-
- /* drop special codes when a key is held down a long time for the grey controller
- In this case, the second bit of the code is asserted */
- if (marker == 0xfe && (code & 0x40))
- return 0;
-
- code %= code_modulo;
-
- *ir_raw = code;
- *ir_key = code;
-
- i2cdprintk("Pinnacle PCTV key %02x\n", code);
-
- return 1;
-}
-
-/* The grey pinnacle PCTV remote
- *
- * There are one issue with this remote:
- * - I2c packet does not change when the same key is pressed quickly. The workaround
- * is to hold down each key for about half a second, so that another code is generated
- * in the i2c packet, and the function can distinguish key presses.
- *
- * Sylvain Pasche <sylvain.pasche@gmail.com>
- */
-static int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
-
- return get_key_pinnacle(ir, ir_key, ir_raw, 1, 0xfe, 0xff);
-}
-
-
-/* The new pinnacle PCTV remote (with the colored buttons)
- *
- * Ricardo Cerqueira <v4l@cerqueira.org>
- */
-static int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE
- *
- * this is the only value that results in 42 unique
- * codes < 128
- */
-
- return get_key_pinnacle(ir, ir_key, ir_raw, 2, 0x80, 0x88);
-}
-
-void saa7134_input_irq(struct saa7134_dev *dev)
-{
- struct saa7134_card_ir *ir;
-
- if (!dev || !dev->remote)
- return;
-
- ir = dev->remote;
- if (!ir->running)
- return;
-
- if (!ir->polling && !ir->raw_decode) {
- build_key(dev);
- } else if (ir->raw_decode) {
- saa7134_raw_decode_irq(dev);
- }
-}
-
-static void saa7134_input_timer(unsigned long data)
-{
- struct saa7134_dev *dev = (struct saa7134_dev *)data;
- struct saa7134_card_ir *ir = dev->remote;
-
- build_key(dev);
- mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
-}
-
-static void ir_raw_decode_timer_end(unsigned long data)
-{
- struct saa7134_dev *dev = (struct saa7134_dev *)data;
- struct saa7134_card_ir *ir = dev->remote;
-
- ir_raw_event_handle(dev->remote->dev);
-
- ir->active = false;
-}
-
-static int __saa7134_ir_start(void *priv)
-{
- struct saa7134_dev *dev = priv;
- struct saa7134_card_ir *ir;
-
- if (!dev || !dev->remote)
- return -EINVAL;
-
- ir = dev->remote;
- if (ir->running)
- return 0;
-
- /* Moved here from saa7134_input_init1() because the latter
- * is not called on device resume */
- switch (dev->board) {
- case SAA7134_BOARD_MD2819:
- case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
- case SAA7134_BOARD_AVERMEDIA_305:
- case SAA7134_BOARD_AVERMEDIA_307:
- case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
- case SAA7134_BOARD_AVERMEDIA_STUDIO_505:
- case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
- case SAA7134_BOARD_AVERMEDIA_STUDIO_507:
- case SAA7134_BOARD_AVERMEDIA_STUDIO_507UA:
- case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
- case SAA7134_BOARD_AVERMEDIA_M102:
- case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
- /* Without this we won't receive key up events */
- saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
- saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
- break;
- case SAA7134_BOARD_AVERMEDIA_777:
- case SAA7134_BOARD_AVERMEDIA_A16AR:
- /* Without this we won't receive key up events */
- saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
- saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
- break;
- case SAA7134_BOARD_AVERMEDIA_A16D:
- /* Without this we won't receive key up events */
- saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
- saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
- break;
- case SAA7134_BOARD_GOTVIEW_7135:
- saa_setb(SAA7134_GPIO_GPMODE1, 0x80);
- break;
- }
-
- ir->running = true;
- ir->active = false;
-
- if (ir->polling) {
- setup_timer(&ir->timer, saa7134_input_timer,
- (unsigned long)dev);
- ir->timer.expires = jiffies + HZ;
- add_timer(&ir->timer);
- } else if (ir->raw_decode) {
- /* set timer_end for code completion */
- setup_timer(&ir->timer, ir_raw_decode_timer_end,
- (unsigned long)dev);
- }
-
- return 0;
-}
-
-static void __saa7134_ir_stop(void *priv)
-{
- struct saa7134_dev *dev = priv;
- struct saa7134_card_ir *ir;
-
- if (!dev || !dev->remote)
- return;
-
- ir = dev->remote;
- if (!ir->running)
- return;
-
- if (ir->polling || ir->raw_decode)
- del_timer_sync(&ir->timer);
-
- ir->active = false;
- ir->running = false;
-
- return;
-}
-
-int saa7134_ir_start(struct saa7134_dev *dev)
-{
- if (dev->remote->users)
- return __saa7134_ir_start(dev);
-
- return 0;
-}
-
-void saa7134_ir_stop(struct saa7134_dev *dev)
-{
- if (dev->remote->users)
- __saa7134_ir_stop(dev);
-}
-
-static int saa7134_ir_open(struct rc_dev *rc)
-{
- struct saa7134_dev *dev = rc->priv;
-
- dev->remote->users++;
- return __saa7134_ir_start(dev);
-}
-
-static void saa7134_ir_close(struct rc_dev *rc)
-{
- struct saa7134_dev *dev = rc->priv;
-
- dev->remote->users--;
- if (!dev->remote->users)
- __saa7134_ir_stop(dev);
-}
-
-int saa7134_input_init1(struct saa7134_dev *dev)
-{
- struct saa7134_card_ir *ir;
- struct rc_dev *rc;
- char *ir_codes = NULL;
- u32 mask_keycode = 0;
- u32 mask_keydown = 0;
- u32 mask_keyup = 0;
- unsigned polling = 0;
- bool raw_decode = false;
- int err;
-
- if (dev->has_remote != SAA7134_REMOTE_GPIO)
- return -ENODEV;
- if (disable_ir)
- return -ENODEV;
-
- /* detect & configure */
- switch (dev->board) {
- case SAA7134_BOARD_FLYVIDEO2000:
- case SAA7134_BOARD_FLYVIDEO3000:
- case SAA7134_BOARD_FLYTVPLATINUM_FM:
- case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
- case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM:
- ir_codes = RC_MAP_FLYVIDEO;
- mask_keycode = 0xEC00000;
- mask_keydown = 0x0040000;
- break;
- case SAA7134_BOARD_CINERGY400:
- case SAA7134_BOARD_CINERGY600:
- case SAA7134_BOARD_CINERGY600_MK3:
- ir_codes = RC_MAP_CINERGY;
- mask_keycode = 0x00003f;
- mask_keyup = 0x040000;
- break;
- case SAA7134_BOARD_ECS_TVP3XP:
- case SAA7134_BOARD_ECS_TVP3XP_4CB5:
- ir_codes = RC_MAP_EZTV;
- mask_keycode = 0x00017c;
- mask_keyup = 0x000002;
- polling = 50; // ms
- break;
- case SAA7134_BOARD_KWORLD_XPERT:
- case SAA7134_BOARD_AVACSSMARTTV:
- ir_codes = RC_MAP_PIXELVIEW;
- mask_keycode = 0x00001F;
- mask_keyup = 0x000020;
- polling = 50; // ms
- break;
- case SAA7134_BOARD_MD2819:
- case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
- case SAA7134_BOARD_AVERMEDIA_305:
- case SAA7134_BOARD_AVERMEDIA_307:
- case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
- case SAA7134_BOARD_AVERMEDIA_STUDIO_505:
- case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
- case SAA7134_BOARD_AVERMEDIA_STUDIO_507:
- case SAA7134_BOARD_AVERMEDIA_STUDIO_507UA:
- case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
- case SAA7134_BOARD_AVERMEDIA_M102:
- case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
- ir_codes = RC_MAP_AVERMEDIA;
- mask_keycode = 0x0007C8;
- mask_keydown = 0x000010;
- polling = 50; // ms
- /* GPIO stuff moved to __saa7134_ir_start() */
- break;
- case SAA7134_BOARD_AVERMEDIA_M135A:
- ir_codes = RC_MAP_AVERMEDIA_M135A;
- mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
- mask_keyup = 0x0040000;
- mask_keycode = 0xffff;
- raw_decode = true;
- break;
- case SAA7134_BOARD_AVERMEDIA_M733A:
- ir_codes = RC_MAP_AVERMEDIA_M733A_RM_K6;
- mask_keydown = 0x0040000;
- mask_keyup = 0x0040000;
- mask_keycode = 0xffff;
- raw_decode = true;
- break;
- case SAA7134_BOARD_AVERMEDIA_777:
- case SAA7134_BOARD_AVERMEDIA_A16AR:
- ir_codes = RC_MAP_AVERMEDIA;
- mask_keycode = 0x02F200;
- mask_keydown = 0x000400;
- polling = 50; // ms
- /* GPIO stuff moved to __saa7134_ir_start() */
- break;
- case SAA7134_BOARD_AVERMEDIA_A16D:
- ir_codes = RC_MAP_AVERMEDIA_A16D;
- mask_keycode = 0x02F200;
- mask_keydown = 0x000400;
- polling = 50; /* ms */
- /* GPIO stuff moved to __saa7134_ir_start() */
- break;
- case SAA7134_BOARD_KWORLD_TERMINATOR:
- ir_codes = RC_MAP_PIXELVIEW;
- mask_keycode = 0x00001f;
- mask_keyup = 0x000060;
- polling = 50; // ms
- break;
- case SAA7134_BOARD_MANLI_MTV001:
- case SAA7134_BOARD_MANLI_MTV002:
- ir_codes = RC_MAP_MANLI;
- mask_keycode = 0x001f00;
- mask_keyup = 0x004000;
- polling = 50; /* ms */
- break;
- case SAA7134_BOARD_BEHOLD_409FM:
- case SAA7134_BOARD_BEHOLD_401:
- case SAA7134_BOARD_BEHOLD_403:
- case SAA7134_BOARD_BEHOLD_403FM:
- case SAA7134_BOARD_BEHOLD_405:
- case SAA7134_BOARD_BEHOLD_405FM:
- case SAA7134_BOARD_BEHOLD_407:
- case SAA7134_BOARD_BEHOLD_407FM:
- case SAA7134_BOARD_BEHOLD_409:
- case SAA7134_BOARD_BEHOLD_505FM:
- case SAA7134_BOARD_BEHOLD_505RDS_MK5:
- case SAA7134_BOARD_BEHOLD_505RDS_MK3:
- case SAA7134_BOARD_BEHOLD_507_9FM:
- case SAA7134_BOARD_BEHOLD_507RDS_MK3:
- case SAA7134_BOARD_BEHOLD_507RDS_MK5:
- ir_codes = RC_MAP_MANLI;
- mask_keycode = 0x003f00;
- mask_keyup = 0x004000;
- polling = 50; /* ms */
- break;
- case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
- ir_codes = RC_MAP_BEHOLD_COLUMBUS;
- mask_keycode = 0x003f00;
- mask_keyup = 0x004000;
- polling = 50; // ms
- break;
- case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
- ir_codes = RC_MAP_PCTV_SEDNA;
- mask_keycode = 0x001f00;
- mask_keyup = 0x004000;
- polling = 50; // ms
- break;
- case SAA7134_BOARD_GOTVIEW_7135:
- ir_codes = RC_MAP_GOTVIEW7135;
- mask_keycode = 0x0003CC;
- mask_keydown = 0x000010;
- polling = 5; /* ms */
- /* GPIO stuff moved to __saa7134_ir_start() */
- break;
- case SAA7134_BOARD_VIDEOMATE_TV_PVR:
- case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
- case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
- ir_codes = RC_MAP_VIDEOMATE_TV_PVR;
- mask_keycode = 0x00003F;
- mask_keyup = 0x400000;
- polling = 50; // ms
- break;
- case SAA7134_BOARD_PROTEUS_2309:
- ir_codes = RC_MAP_PROTEUS_2309;
- mask_keycode = 0x00007F;
- mask_keyup = 0x000080;
- polling = 50; // ms
- break;
- case SAA7134_BOARD_VIDEOMATE_DVBT_300:
- case SAA7134_BOARD_VIDEOMATE_DVBT_200:
- ir_codes = RC_MAP_VIDEOMATE_TV_PVR;
- mask_keycode = 0x003F00;
- mask_keyup = 0x040000;
- break;
- case SAA7134_BOARD_FLYDVBS_LR300:
- case SAA7134_BOARD_FLYDVBT_LR301:
- case SAA7134_BOARD_FLYDVBTDUO:
- ir_codes = RC_MAP_FLYDVB;
- mask_keycode = 0x0001F00;
- mask_keydown = 0x0040000;
- break;
- case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
- case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
- case SAA7134_BOARD_ASUSTeK_P7131_ANALOG:
- ir_codes = RC_MAP_ASUS_PC39;
- mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
- mask_keyup = 0x0040000;
- mask_keycode = 0xffff;
- raw_decode = true;
- break;
- case SAA7134_BOARD_ASUSTeK_PS3_100:
- ir_codes = RC_MAP_ASUS_PS3_100;
- mask_keydown = 0x0040000;
- mask_keyup = 0x0040000;
- mask_keycode = 0xffff;
- raw_decode = true;
- break;
- case SAA7134_BOARD_ENCORE_ENLTV:
- case SAA7134_BOARD_ENCORE_ENLTV_FM:
- ir_codes = RC_MAP_ENCORE_ENLTV;
- mask_keycode = 0x00007f;
- mask_keyup = 0x040000;
- polling = 50; // ms
- break;
- case SAA7134_BOARD_ENCORE_ENLTV_FM53:
- case SAA7134_BOARD_ENCORE_ENLTV_FM3:
- ir_codes = RC_MAP_ENCORE_ENLTV_FM53;
- mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
- mask_keyup = 0x0040000;
- mask_keycode = 0xffff;
- raw_decode = true;
- break;
- case SAA7134_BOARD_10MOONSTVMASTER3:
- ir_codes = RC_MAP_ENCORE_ENLTV;
- mask_keycode = 0x5f80000;
- mask_keyup = 0x8000000;
- polling = 50; //ms
- break;
- case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
- ir_codes = RC_MAP_GENIUS_TVGO_A11MCE;
- mask_keycode = 0xff;
- mask_keydown = 0xf00000;
- polling = 50; /* ms */
- break;
- case SAA7134_BOARD_REAL_ANGEL_220:
- ir_codes = RC_MAP_REAL_AUDIO_220_32_KEYS;
- mask_keycode = 0x3f00;
- mask_keyup = 0x4000;
- polling = 50; /* ms */
- break;
- case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
- ir_codes = RC_MAP_KWORLD_PLUS_TV_ANALOG;
- mask_keycode = 0x7f;
- polling = 40; /* ms */
- break;
- case SAA7134_BOARD_VIDEOMATE_S350:
- ir_codes = RC_MAP_VIDEOMATE_S350;
- mask_keycode = 0x003f00;
- mask_keydown = 0x040000;
- break;
- case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
- ir_codes = RC_MAP_WINFAST;
- mask_keycode = 0x5f00;
- mask_keyup = 0x020000;
- polling = 50; /* ms */
- break;
- case SAA7134_BOARD_VIDEOMATE_M1F:
- ir_codes = RC_MAP_VIDEOMATE_K100;
- mask_keycode = 0x0ff00;
- mask_keyup = 0x040000;
- break;
- case SAA7134_BOARD_HAUPPAUGE_HVR1150:
- case SAA7134_BOARD_HAUPPAUGE_HVR1120:
- ir_codes = RC_MAP_HAUPPAUGE;
- mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
- mask_keyup = 0x0040000;
- mask_keycode = 0xffff;
- raw_decode = true;
- break;
- }
- if (NULL == ir_codes) {
- printk("%s: Oops: IR config error [card=%d]\n",
- dev->name, dev->board);
- return -ENODEV;
- }
-
- ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- rc = rc_allocate_device();
- if (!ir || !rc) {
- err = -ENOMEM;
- goto err_out_free;
- }
-
- ir->dev = rc;
- dev->remote = ir;
-
- /* init hardware-specific stuff */
- ir->mask_keycode = mask_keycode;
- ir->mask_keydown = mask_keydown;
- ir->mask_keyup = mask_keyup;
- ir->polling = polling;
- ir->raw_decode = raw_decode;
-
- /* init input device */
- snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
- saa7134_boards[dev->board].name);
- snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
- pci_name(dev->pci));
-
- rc->priv = dev;
- rc->open = saa7134_ir_open;
- rc->close = saa7134_ir_close;
- if (raw_decode)
- rc->driver_type = RC_DRIVER_IR_RAW;
-
- rc->input_name = ir->name;
- rc->input_phys = ir->phys;
- rc->input_id.bustype = BUS_PCI;
- rc->input_id.version = 1;
- if (dev->pci->subsystem_vendor) {
- rc->input_id.vendor = dev->pci->subsystem_vendor;
- rc->input_id.product = dev->pci->subsystem_device;
- } else {
- rc->input_id.vendor = dev->pci->vendor;
- rc->input_id.product = dev->pci->device;
- }
- rc->dev.parent = &dev->pci->dev;
- rc->map_name = ir_codes;
- rc->driver_name = MODULE_NAME;
-
- err = rc_register_device(rc);
- if (err)
- goto err_out_free;
-
- return 0;
-
-err_out_free:
- rc_free_device(rc);
- dev->remote = NULL;
- kfree(ir);
- return err;
-}
-
-void saa7134_input_fini(struct saa7134_dev *dev)
-{
- if (NULL == dev->remote)
- return;
-
- saa7134_ir_stop(dev);
- rc_unregister_device(dev->remote->dev);
- kfree(dev->remote);
- dev->remote = NULL;
-}
-
-void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
-{
- struct i2c_board_info info;
- struct i2c_msg msg_msi = {
- .addr = 0x50,
- .flags = I2C_M_RD,
- .len = 0,
- .buf = NULL,
- };
- int rc;
-
- if (disable_ir) {
- dprintk("IR has been disabled, not probing for i2c remote\n");
- return;
- }
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- memset(&dev->init_data, 0, sizeof(dev->init_data));
- strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
-
- switch (dev->board) {
- case SAA7134_BOARD_PINNACLE_PCTV_110i:
- case SAA7134_BOARD_PINNACLE_PCTV_310i:
- dev->init_data.name = "Pinnacle PCTV";
- if (pinnacle_remote == 0) {
- dev->init_data.get_key = get_key_pinnacle_color;
- dev->init_data.ir_codes = RC_MAP_PINNACLE_COLOR;
- info.addr = 0x47;
- } else {
- dev->init_data.get_key = get_key_pinnacle_grey;
- dev->init_data.ir_codes = RC_MAP_PINNACLE_GREY;
- info.addr = 0x47;
- }
- break;
- case SAA7134_BOARD_UPMOST_PURPLE_TV:
- dev->init_data.name = "Purple TV";
- dev->init_data.get_key = get_key_purpletv;
- dev->init_data.ir_codes = RC_MAP_PURPLETV;
- info.addr = 0x7a;
- break;
- case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
- dev->init_data.name = "MSI TV@nywhere Plus";
- dev->init_data.get_key = get_key_msi_tvanywhere_plus;
- dev->init_data.ir_codes = RC_MAP_MSI_TVANYWHERE_PLUS;
- /*
- * MSI TV@nyware Plus requires more frequent polling
- * otherwise it will miss some keypresses
- */
- dev->init_data.polling_interval = 50;
- info.addr = 0x30;
- /* MSI TV@nywhere Plus controller doesn't seem to
- respond to probes unless we read something from
- an existing device. Weird...
- REVISIT: might no longer be needed */
- rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
- dprintk("probe 0x%02x @ %s: %s\n",
- msg_msi.addr, dev->i2c_adap.name,
- (1 == rc) ? "yes" : "no");
- break;
- case SAA7134_BOARD_KWORLD_PC150U:
- /* copied and modified from MSI TV@nywhere Plus */
- dev->init_data.name = "Kworld PC150-U";
- dev->init_data.get_key = get_key_kworld_pc150u;
- dev->init_data.ir_codes = RC_MAP_KWORLD_PC150U;
- info.addr = 0x30;
- /* MSI TV@nywhere Plus controller doesn't seem to
- respond to probes unless we read something from
- an existing device. Weird...
- REVISIT: might no longer be needed */
- rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
- dprintk("probe 0x%02x @ %s: %s\n",
- msg_msi.addr, dev->i2c_adap.name,
- (1 == rc) ? "yes" : "no");
- break;
- case SAA7134_BOARD_HAUPPAUGE_HVR1110:
- dev->init_data.name = "HVR 1110";
- dev->init_data.get_key = get_key_hvr1110;
- dev->init_data.ir_codes = RC_MAP_HAUPPAUGE;
- info.addr = 0x71;
- break;
- case SAA7134_BOARD_BEHOLD_607FM_MK3:
- case SAA7134_BOARD_BEHOLD_607FM_MK5:
- case SAA7134_BOARD_BEHOLD_609FM_MK3:
- case SAA7134_BOARD_BEHOLD_609FM_MK5:
- case SAA7134_BOARD_BEHOLD_607RDS_MK3:
- case SAA7134_BOARD_BEHOLD_607RDS_MK5:
- case SAA7134_BOARD_BEHOLD_609RDS_MK3:
- case SAA7134_BOARD_BEHOLD_609RDS_MK5:
- case SAA7134_BOARD_BEHOLD_M6:
- case SAA7134_BOARD_BEHOLD_M63:
- case SAA7134_BOARD_BEHOLD_M6_EXTRA:
- case SAA7134_BOARD_BEHOLD_H6:
- case SAA7134_BOARD_BEHOLD_X7:
- case SAA7134_BOARD_BEHOLD_H7:
- case SAA7134_BOARD_BEHOLD_A7:
- dev->init_data.name = "BeholdTV";
- dev->init_data.get_key = get_key_beholdm6xx;
- dev->init_data.ir_codes = RC_MAP_BEHOLD;
- dev->init_data.type = RC_TYPE_NEC;
- info.addr = 0x2d;
- break;
- case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
- case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
- info.addr = 0x40;
- break;
- case SAA7134_BOARD_FLYDVB_TRIO:
- dev->init_data.name = "FlyDVB Trio";
- dev->init_data.get_key = get_key_flydvb_trio;
- dev->init_data.ir_codes = RC_MAP_FLYDVB;
- info.addr = 0x0b;
- break;
- default:
- dprintk("No I2C IR support for board %x\n", dev->board);
- return;
- }
-
- if (dev->init_data.name)
- info.platform_data = &dev->init_data;
- i2c_new_device(&dev->i2c_adap, &info);
-}
-
-static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
-{
- struct saa7134_card_ir *ir = dev->remote;
- unsigned long timeout;
- int space;
-
- /* Generate initial event */
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- space = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown;
- ir_raw_event_store_edge(dev->remote->dev, space ? IR_SPACE : IR_PULSE);
-
- /*
- * Wait 15 ms from the start of the first IR event before processing
- * the event. This time is enough for NEC protocol. May need adjustments
- * to work with other protocols.
- */
- if (!ir->active) {
- timeout = jiffies + msecs_to_jiffies(15);
- mod_timer(&ir->timer, timeout);
- ir->active = true;
- }
-
- return 1;
-}
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
deleted file mode 100644
index e7e0af101fa..00000000000
--- a/drivers/media/video/saa7134/saa7134-reg.h
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- *
- * philips saa7134 registers
- */
-
-/* ------------------------------------------------------------------ */
-/*
- * PCI ID's
- */
-#ifndef PCI_DEVICE_ID_PHILIPS_SAA7130
-# define PCI_DEVICE_ID_PHILIPS_SAA7130 0x7130
-#endif
-#ifndef PCI_DEVICE_ID_PHILIPS_SAA7133
-# define PCI_DEVICE_ID_PHILIPS_SAA7133 0x7133
-#endif
-#ifndef PCI_DEVICE_ID_PHILIPS_SAA7134
-# define PCI_DEVICE_ID_PHILIPS_SAA7134 0x7134
-#endif
-#ifndef PCI_DEVICE_ID_PHILIPS_SAA7135
-# define PCI_DEVICE_ID_PHILIPS_SAA7135 0x7135
-#endif
-
-/* ------------------------------------------------------------------ */
-/*
- * registers -- 32 bit
- */
-
-/* DMA channels, n = 0 ... 6 */
-#define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n)
-#define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n)
-#define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n)
-#define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n)
-#define SAA7134_RS_CONTROL_WSWAP (0x01 << 25)
-#define SAA7134_RS_CONTROL_BSWAP (0x01 << 24)
-#define SAA7134_RS_CONTROL_BURST_2 (0x01 << 21)
-#define SAA7134_RS_CONTROL_BURST_4 (0x02 << 21)
-#define SAA7134_RS_CONTROL_BURST_8 (0x03 << 21)
-#define SAA7134_RS_CONTROL_BURST_16 (0x04 << 21)
-#define SAA7134_RS_CONTROL_BURST_32 (0x05 << 21)
-#define SAA7134_RS_CONTROL_BURST_64 (0x06 << 21)
-#define SAA7134_RS_CONTROL_BURST_MAX (0x07 << 21)
-#define SAA7134_RS_CONTROL_ME (0x01 << 20)
-#define SAA7134_FIFO_SIZE (0x2a0 >> 2)
-#define SAA7134_THRESHOULD (0x2a4 >> 2)
-
-#define SAA7133_NUM_SAMPLES (0x588 >> 2)
-#define SAA7133_AUDIO_CHANNEL (0x58c >> 2)
-#define SAA7133_AUDIO_FORMAT (0x58f >> 2)
-#define SAA7133_DIGITAL_OUTPUT_SEL1 (0x46c >> 2)
-#define SAA7133_DIGITAL_OUTPUT_SEL2 (0x470 >> 2)
-#define SAA7133_DIGITAL_INPUT_XBAR1 (0x464 >> 2)
-#define SAA7133_ANALOG_IO_SELECT (0x594 >> 2)
-
-/* main control */
-#define SAA7134_MAIN_CTRL (0x2a8 >> 2)
-#define SAA7134_MAIN_CTRL_VPLLE (1 << 15)
-#define SAA7134_MAIN_CTRL_APLLE (1 << 14)
-#define SAA7134_MAIN_CTRL_EXOSC (1 << 13)
-#define SAA7134_MAIN_CTRL_EVFE1 (1 << 12)
-#define SAA7134_MAIN_CTRL_EVFE2 (1 << 11)
-#define SAA7134_MAIN_CTRL_ESFE (1 << 10)
-#define SAA7134_MAIN_CTRL_EBADC (1 << 9)
-#define SAA7134_MAIN_CTRL_EBDAC (1 << 8)
-#define SAA7134_MAIN_CTRL_TE6 (1 << 6)
-#define SAA7134_MAIN_CTRL_TE5 (1 << 5)
-#define SAA7134_MAIN_CTRL_TE4 (1 << 4)
-#define SAA7134_MAIN_CTRL_TE3 (1 << 3)
-#define SAA7134_MAIN_CTRL_TE2 (1 << 2)
-#define SAA7134_MAIN_CTRL_TE1 (1 << 1)
-#define SAA7134_MAIN_CTRL_TE0 (1 << 0)
-
-/* DMA status */
-#define SAA7134_DMA_STATUS (0x2ac >> 2)
-
-/* audio / video status */
-#define SAA7134_AV_STATUS (0x2c0 >> 2)
-#define SAA7134_AV_STATUS_STEREO (1 << 17)
-#define SAA7134_AV_STATUS_DUAL (1 << 16)
-#define SAA7134_AV_STATUS_PILOT (1 << 15)
-#define SAA7134_AV_STATUS_SMB (1 << 14)
-#define SAA7134_AV_STATUS_DMB (1 << 13)
-#define SAA7134_AV_STATUS_VDSP (1 << 12)
-#define SAA7134_AV_STATUS_IIC_STATUS (3 << 10)
-#define SAA7134_AV_STATUS_MVM (7 << 7)
-#define SAA7134_AV_STATUS_FIDT (1 << 6)
-#define SAA7134_AV_STATUS_INTL (1 << 5)
-#define SAA7134_AV_STATUS_RDCAP (1 << 4)
-#define SAA7134_AV_STATUS_PWR_ON (1 << 3)
-#define SAA7134_AV_STATUS_LOAD_ERR (1 << 2)
-#define SAA7134_AV_STATUS_TRIG_ERR (1 << 1)
-#define SAA7134_AV_STATUS_CONF_ERR (1 << 0)
-
-/* interrupt */
-#define SAA7134_IRQ1 (0x2c4 >> 2)
-#define SAA7134_IRQ1_INTE_RA3_1 (1 << 25)
-#define SAA7134_IRQ1_INTE_RA3_0 (1 << 24)
-#define SAA7134_IRQ1_INTE_RA2_3 (1 << 19)
-#define SAA7134_IRQ1_INTE_RA2_2 (1 << 18)
-#define SAA7134_IRQ1_INTE_RA2_1 (1 << 17)
-#define SAA7134_IRQ1_INTE_RA2_0 (1 << 16)
-#define SAA7134_IRQ1_INTE_RA1_3 (1 << 11)
-#define SAA7134_IRQ1_INTE_RA1_2 (1 << 10)
-#define SAA7134_IRQ1_INTE_RA1_1 (1 << 9)
-#define SAA7134_IRQ1_INTE_RA1_0 (1 << 8)
-#define SAA7134_IRQ1_INTE_RA0_7 (1 << 7)
-#define SAA7134_IRQ1_INTE_RA0_6 (1 << 6)
-#define SAA7134_IRQ1_INTE_RA0_5 (1 << 5)
-#define SAA7134_IRQ1_INTE_RA0_4 (1 << 4)
-#define SAA7134_IRQ1_INTE_RA0_3 (1 << 3)
-#define SAA7134_IRQ1_INTE_RA0_2 (1 << 2)
-#define SAA7134_IRQ1_INTE_RA0_1 (1 << 1)
-#define SAA7134_IRQ1_INTE_RA0_0 (1 << 0)
-
-#define SAA7134_IRQ2 (0x2c8 >> 2)
-#define SAA7134_IRQ2_INTE_GPIO23_N (1 << 17) /* negative edge */
-#define SAA7134_IRQ2_INTE_GPIO23_P (1 << 16) /* positive edge */
-#define SAA7134_IRQ2_INTE_GPIO22_N (1 << 15) /* negative edge */
-#define SAA7134_IRQ2_INTE_GPIO22_P (1 << 14) /* positive edge */
-#define SAA7134_IRQ2_INTE_GPIO18_N (1 << 13) /* negative edge */
-#define SAA7134_IRQ2_INTE_GPIO18_P (1 << 12) /* positive edge */
-#define SAA7134_IRQ2_INTE_GPIO16_N (1 << 11) /* negative edge */
-#define SAA7134_IRQ2_INTE_GPIO16_P (1 << 10) /* positive edge */
-#define SAA7134_IRQ2_INTE_SC2 (1 << 9)
-#define SAA7134_IRQ2_INTE_SC1 (1 << 8)
-#define SAA7134_IRQ2_INTE_SC0 (1 << 7)
-#define SAA7134_IRQ2_INTE_DEC4 (1 << 6)
-#define SAA7134_IRQ2_INTE_DEC3 (1 << 5)
-#define SAA7134_IRQ2_INTE_DEC2 (1 << 4)
-#define SAA7134_IRQ2_INTE_DEC1 (1 << 3)
-#define SAA7134_IRQ2_INTE_DEC0 (1 << 2)
-#define SAA7134_IRQ2_INTE_PE (1 << 1)
-#define SAA7134_IRQ2_INTE_AR (1 << 0)
-
-#define SAA7134_IRQ_REPORT (0x2cc >> 2)
-#define SAA7134_IRQ_REPORT_GPIO23 (1 << 17)
-#define SAA7134_IRQ_REPORT_GPIO22 (1 << 16)
-#define SAA7134_IRQ_REPORT_GPIO18 (1 << 15)
-#define SAA7134_IRQ_REPORT_GPIO16 (1 << 14)
-#define SAA7134_IRQ_REPORT_LOAD_ERR (1 << 13)
-#define SAA7134_IRQ_REPORT_CONF_ERR (1 << 12)
-#define SAA7134_IRQ_REPORT_TRIG_ERR (1 << 11)
-#define SAA7134_IRQ_REPORT_MMC (1 << 10)
-#define SAA7134_IRQ_REPORT_FIDT (1 << 9)
-#define SAA7134_IRQ_REPORT_INTL (1 << 8)
-#define SAA7134_IRQ_REPORT_RDCAP (1 << 7)
-#define SAA7134_IRQ_REPORT_PWR_ON (1 << 6)
-#define SAA7134_IRQ_REPORT_PE (1 << 5)
-#define SAA7134_IRQ_REPORT_AR (1 << 4)
-#define SAA7134_IRQ_REPORT_DONE_RA3 (1 << 3)
-#define SAA7134_IRQ_REPORT_DONE_RA2 (1 << 2)
-#define SAA7134_IRQ_REPORT_DONE_RA1 (1 << 1)
-#define SAA7134_IRQ_REPORT_DONE_RA0 (1 << 0)
-#define SAA7134_IRQ_STATUS (0x2d0 >> 2)
-
-
-/* ------------------------------------------------------------------ */
-/*
- * registers -- 8 bit
- */
-
-/* video decoder */
-#define SAA7134_INCR_DELAY 0x101
-#define SAA7134_ANALOG_IN_CTRL1 0x102
-#define SAA7134_ANALOG_IN_CTRL2 0x103
-#define SAA7134_ANALOG_IN_CTRL3 0x104
-#define SAA7134_ANALOG_IN_CTRL4 0x105
-#define SAA7134_HSYNC_START 0x106
-#define SAA7134_HSYNC_STOP 0x107
-#define SAA7134_SYNC_CTRL 0x108
-#define SAA7134_LUMA_CTRL 0x109
-#define SAA7134_DEC_LUMA_BRIGHT 0x10a
-#define SAA7134_DEC_LUMA_CONTRAST 0x10b
-#define SAA7134_DEC_CHROMA_SATURATION 0x10c
-#define SAA7134_DEC_CHROMA_HUE 0x10d
-#define SAA7134_CHROMA_CTRL1 0x10e
-#define SAA7134_CHROMA_GAIN 0x10f
-#define SAA7134_CHROMA_CTRL2 0x110
-#define SAA7134_MODE_DELAY_CTRL 0x111
-
-#define SAA7134_ANALOG_ADC 0x114
-#define SAA7134_VGATE_START 0x115
-#define SAA7134_VGATE_STOP 0x116
-#define SAA7134_MISC_VGATE_MSB 0x117
-#define SAA7134_RAW_DATA_GAIN 0x118
-#define SAA7134_RAW_DATA_OFFSET 0x119
-#define SAA7134_STATUS_VIDEO1 0x11e
-#define SAA7134_STATUS_VIDEO2 0x11f
-
-/* video scaler */
-#define SAA7134_SOURCE_TIMING1 0x000
-#define SAA7134_SOURCE_TIMING2 0x001
-#define SAA7134_REGION_ENABLE 0x004
-#define SAA7134_SCALER_STATUS0 0x006
-#define SAA7134_SCALER_STATUS1 0x007
-#define SAA7134_START_GREEN 0x00c
-#define SAA7134_START_BLUE 0x00d
-#define SAA7134_START_RED 0x00e
-#define SAA7134_GREEN_PATH(x) (0x010 +x)
-#define SAA7134_BLUE_PATH(x) (0x020 +x)
-#define SAA7134_RED_PATH(x) (0x030 +x)
-
-#define TASK_A 0x040
-#define TASK_B 0x080
-#define SAA7134_TASK_CONDITIONS(t) (0x000 +t)
-#define SAA7134_FIELD_HANDLING(t) (0x001 +t)
-#define SAA7134_DATA_PATH(t) (0x002 +t)
-#define SAA7134_VBI_H_START1(t) (0x004 +t)
-#define SAA7134_VBI_H_START2(t) (0x005 +t)
-#define SAA7134_VBI_H_STOP1(t) (0x006 +t)
-#define SAA7134_VBI_H_STOP2(t) (0x007 +t)
-#define SAA7134_VBI_V_START1(t) (0x008 +t)
-#define SAA7134_VBI_V_START2(t) (0x009 +t)
-#define SAA7134_VBI_V_STOP1(t) (0x00a +t)
-#define SAA7134_VBI_V_STOP2(t) (0x00b +t)
-#define SAA7134_VBI_H_LEN1(t) (0x00c +t)
-#define SAA7134_VBI_H_LEN2(t) (0x00d +t)
-#define SAA7134_VBI_V_LEN1(t) (0x00e +t)
-#define SAA7134_VBI_V_LEN2(t) (0x00f +t)
-
-#define SAA7134_VIDEO_H_START1(t) (0x014 +t)
-#define SAA7134_VIDEO_H_START2(t) (0x015 +t)
-#define SAA7134_VIDEO_H_STOP1(t) (0x016 +t)
-#define SAA7134_VIDEO_H_STOP2(t) (0x017 +t)
-#define SAA7134_VIDEO_V_START1(t) (0x018 +t)
-#define SAA7134_VIDEO_V_START2(t) (0x019 +t)
-#define SAA7134_VIDEO_V_STOP1(t) (0x01a +t)
-#define SAA7134_VIDEO_V_STOP2(t) (0x01b +t)
-#define SAA7134_VIDEO_PIXELS1(t) (0x01c +t)
-#define SAA7134_VIDEO_PIXELS2(t) (0x01d +t)
-#define SAA7134_VIDEO_LINES1(t) (0x01e +t)
-#define SAA7134_VIDEO_LINES2(t) (0x01f +t)
-
-#define SAA7134_H_PRESCALE(t) (0x020 +t)
-#define SAA7134_ACC_LENGTH(t) (0x021 +t)
-#define SAA7134_LEVEL_CTRL(t) (0x022 +t)
-#define SAA7134_FIR_PREFILTER_CTRL(t) (0x023 +t)
-#define SAA7134_LUMA_BRIGHT(t) (0x024 +t)
-#define SAA7134_LUMA_CONTRAST(t) (0x025 +t)
-#define SAA7134_CHROMA_SATURATION(t) (0x026 +t)
-#define SAA7134_VBI_H_SCALE_INC1(t) (0x028 +t)
-#define SAA7134_VBI_H_SCALE_INC2(t) (0x029 +t)
-#define SAA7134_VBI_PHASE_OFFSET_LUMA(t) (0x02a +t)
-#define SAA7134_VBI_PHASE_OFFSET_CHROMA(t) (0x02b +t)
-#define SAA7134_H_SCALE_INC1(t) (0x02c +t)
-#define SAA7134_H_SCALE_INC2(t) (0x02d +t)
-#define SAA7134_H_PHASE_OFF_LUMA(t) (0x02e +t)
-#define SAA7134_H_PHASE_OFF_CHROMA(t) (0x02f +t)
-#define SAA7134_V_SCALE_RATIO1(t) (0x030 +t)
-#define SAA7134_V_SCALE_RATIO2(t) (0x031 +t)
-#define SAA7134_V_FILTER(t) (0x032 +t)
-#define SAA7134_V_PHASE_OFFSET0(t) (0x034 +t)
-#define SAA7134_V_PHASE_OFFSET1(t) (0x035 +t)
-#define SAA7134_V_PHASE_OFFSET2(t) (0x036 +t)
-#define SAA7134_V_PHASE_OFFSET3(t) (0x037 +t)
-
-/* clipping & dma */
-#define SAA7134_OFMT_VIDEO_A 0x300
-#define SAA7134_OFMT_DATA_A 0x301
-#define SAA7134_OFMT_VIDEO_B 0x302
-#define SAA7134_OFMT_DATA_B 0x303
-#define SAA7134_ALPHA_NOCLIP 0x304
-#define SAA7134_ALPHA_CLIP 0x305
-#define SAA7134_UV_PIXEL 0x308
-#define SAA7134_CLIP_RED 0x309
-#define SAA7134_CLIP_GREEN 0x30a
-#define SAA7134_CLIP_BLUE 0x30b
-
-/* i2c bus */
-#define SAA7134_I2C_ATTR_STATUS 0x180
-#define SAA7134_I2C_DATA 0x181
-#define SAA7134_I2C_CLOCK_SELECT 0x182
-#define SAA7134_I2C_TIMER 0x183
-
-/* audio */
-#define SAA7134_NICAM_ADD_DATA1 0x140
-#define SAA7134_NICAM_ADD_DATA2 0x141
-#define SAA7134_NICAM_STATUS 0x142
-#define SAA7134_AUDIO_STATUS 0x143
-#define SAA7134_NICAM_ERROR_COUNT 0x144
-#define SAA7134_IDENT_SIF 0x145
-#define SAA7134_LEVEL_READOUT1 0x146
-#define SAA7134_LEVEL_READOUT2 0x147
-#define SAA7134_NICAM_ERROR_LOW 0x148
-#define SAA7134_NICAM_ERROR_HIGH 0x149
-#define SAA7134_DCXO_IDENT_CTRL 0x14a
-#define SAA7134_DEMODULATOR 0x14b
-#define SAA7134_AGC_GAIN_SELECT 0x14c
-#define SAA7134_CARRIER1_FREQ0 0x150
-#define SAA7134_CARRIER1_FREQ1 0x151
-#define SAA7134_CARRIER1_FREQ2 0x152
-#define SAA7134_CARRIER2_FREQ0 0x154
-#define SAA7134_CARRIER2_FREQ1 0x155
-#define SAA7134_CARRIER2_FREQ2 0x156
-#define SAA7134_NUM_SAMPLES0 0x158
-#define SAA7134_NUM_SAMPLES1 0x159
-#define SAA7134_NUM_SAMPLES2 0x15a
-#define SAA7134_AUDIO_FORMAT_CTRL 0x15b
-#define SAA7134_MONITOR_SELECT 0x160
-#define SAA7134_FM_DEEMPHASIS 0x161
-#define SAA7134_FM_DEMATRIX 0x162
-#define SAA7134_CHANNEL1_LEVEL 0x163
-#define SAA7134_CHANNEL2_LEVEL 0x164
-#define SAA7134_NICAM_CONFIG 0x165
-#define SAA7134_NICAM_LEVEL_ADJUST 0x166
-#define SAA7134_STEREO_DAC_OUTPUT_SELECT 0x167
-#define SAA7134_I2S_OUTPUT_FORMAT 0x168
-#define SAA7134_I2S_OUTPUT_SELECT 0x169
-#define SAA7134_I2S_OUTPUT_LEVEL 0x16a
-#define SAA7134_DSP_OUTPUT_SELECT 0x16b
-#define SAA7134_AUDIO_MUTE_CTRL 0x16c
-#define SAA7134_SIF_SAMPLE_FREQ 0x16d
-#define SAA7134_ANALOG_IO_SELECT 0x16e
-#define SAA7134_AUDIO_CLOCK0 0x170
-#define SAA7134_AUDIO_CLOCK1 0x171
-#define SAA7134_AUDIO_CLOCK2 0x172
-#define SAA7134_AUDIO_PLL_CTRL 0x173
-#define SAA7134_AUDIO_CLOCKS_PER_FIELD0 0x174
-#define SAA7134_AUDIO_CLOCKS_PER_FIELD1 0x175
-#define SAA7134_AUDIO_CLOCKS_PER_FIELD2 0x176
-
-/* video port output */
-#define SAA7134_VIDEO_PORT_CTRL0 0x190
-#define SAA7134_VIDEO_PORT_CTRL1 0x191
-#define SAA7134_VIDEO_PORT_CTRL2 0x192
-#define SAA7134_VIDEO_PORT_CTRL3 0x193
-#define SAA7134_VIDEO_PORT_CTRL4 0x194
-#define SAA7134_VIDEO_PORT_CTRL5 0x195
-#define SAA7134_VIDEO_PORT_CTRL6 0x196
-#define SAA7134_VIDEO_PORT_CTRL7 0x197
-#define SAA7134_VIDEO_PORT_CTRL8 0x198
-
-/* transport stream interface */
-#define SAA7134_TS_PARALLEL 0x1a0
-#define SAA7134_TS_PARALLEL_SERIAL 0x1a1
-#define SAA7134_TS_SERIAL0 0x1a2
-#define SAA7134_TS_SERIAL1 0x1a3
-#define SAA7134_TS_DMA0 0x1a4
-#define SAA7134_TS_DMA1 0x1a5
-#define SAA7134_TS_DMA2 0x1a6
-
-/* GPIO Controls */
-#define SAA7134_GPIO_GPRESCAN 0x80
-#define SAA7134_GPIO_27_25 0x0E
-
-#define SAA7134_GPIO_GPMODE0 0x1B0
-#define SAA7134_GPIO_GPMODE1 0x1B1
-#define SAA7134_GPIO_GPMODE2 0x1B2
-#define SAA7134_GPIO_GPMODE3 0x1B3
-#define SAA7134_GPIO_GPSTATUS0 0x1B4
-#define SAA7134_GPIO_GPSTATUS1 0x1B5
-#define SAA7134_GPIO_GPSTATUS2 0x1B6
-#define SAA7134_GPIO_GPSTATUS3 0x1B7
-
-/* I2S output */
-#define SAA7134_I2S_AUDIO_OUTPUT 0x1c0
-
-/* test modes */
-#define SAA7134_SPECIAL_MODE 0x1d0
-#define SAA7134_PRODUCTION_TEST_MODE 0x1d1
-
-/* audio -- saa7133 + saa7135 only */
-#define SAA7135_DSP_RWSTATE 0x580
-#define SAA7135_DSP_RWSTATE_ERR (1 << 3)
-#define SAA7135_DSP_RWSTATE_IDA (1 << 2)
-#define SAA7135_DSP_RWSTATE_RDB (1 << 1)
-#define SAA7135_DSP_RWSTATE_WRR (1 << 0)
-
-#define SAA7135_DSP_RWCLEAR 0x586
-#define SAA7135_DSP_RWCLEAR_RERR 1
-
-#define SAA7133_I2S_AUDIO_CONTROL 0x591
-/* ------------------------------------------------------------------ */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
-
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
deleted file mode 100644
index 2e3f4b412d8..00000000000
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- *
- * device driver for philips saa7134 based TV cards
- * video4linux video interface
- *
- * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-
-#include "saa7134-reg.h"
-#include "saa7134.h"
-
-/* ------------------------------------------------------------------ */
-
-static unsigned int ts_debug;
-module_param(ts_debug, int, 0644);
-MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]");
-
-#define dprintk(fmt, arg...) if (ts_debug) \
- printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg)
-
-/* ------------------------------------------------------------------ */
-
-static int buffer_activate(struct saa7134_dev *dev,
- struct saa7134_buf *buf,
- struct saa7134_buf *next)
-{
-
- dprintk("buffer_activate [%p]",buf);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->top_seen = 0;
-
- if (NULL == next)
- next = buf;
- if (V4L2_FIELD_TOP == buf->vb.field) {
- dprintk("- [top] buf=%p next=%p\n",buf,next);
- saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf));
- saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next));
- } else {
- dprintk("- [bottom] buf=%p next=%p\n",buf,next);
- saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
- saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
- }
-
- /* start DMA */
- saa7134_set_dmabits(dev);
-
- mod_timer(&dev->ts_q.timeout, jiffies+TS_BUFFER_TIMEOUT);
-
- if (!dev->ts_started)
- saa7134_ts_start(dev);
-
- return 0;
-}
-
-static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct saa7134_dev *dev = q->priv_data;
- struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
- unsigned int lines, llength, size;
- int err;
-
- dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
-
- llength = TS_PACKET_SIZE;
- lines = dev->ts.nr_packets;
-
- size = lines * llength;
- if (0 != buf->vb.baddr && buf->vb.bsize < size)
- return -EINVAL;
-
- if (buf->vb.size != size) {
- saa7134_dma_free(q,buf);
- }
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
-
- struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
-
- dprintk("buffer_prepare: needs_init\n");
-
- buf->vb.width = llength;
- buf->vb.height = lines;
- buf->vb.size = size;
- buf->pt = &dev->ts.pt_ts;
-
- err = videobuf_iolock(q,&buf->vb,NULL);
- if (err)
- goto oops;
- err = saa7134_pgtable_build(dev->pci,buf->pt,
- dma->sglist,
- dma->sglen,
- saa7134_buffer_startpage(buf));
- if (err)
- goto oops;
- }
-
- buf->vb.state = VIDEOBUF_PREPARED;
- buf->activate = buffer_activate;
- buf->vb.field = field;
- return 0;
-
- oops:
- saa7134_dma_free(q,buf);
- return err;
-}
-
-static int
-buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
-{
- struct saa7134_dev *dev = q->priv_data;
-
- *size = TS_PACKET_SIZE * dev->ts.nr_packets;
- if (0 == *count)
- *count = dev->ts.nr_bufs;
- *count = saa7134_buffer_count(*size,*count);
-
- return 0;
-}
-
-static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct saa7134_dev *dev = q->priv_data;
- struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
-
- saa7134_buffer_queue(dev,&dev->ts_q,buf);
-}
-
-static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
- struct saa7134_dev *dev = q->priv_data;
-
- if (dev->ts_started)
- saa7134_ts_stop(dev);
-
- saa7134_dma_free(q,buf);
-}
-
-struct videobuf_queue_ops saa7134_ts_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-EXPORT_SYMBOL_GPL(saa7134_ts_qops);
-
-/* ----------------------------------------------------------- */
-/* exported stuff */
-
-static unsigned int tsbufs = 8;
-module_param(tsbufs, int, 0444);
-MODULE_PARM_DESC(tsbufs, "number of ts buffers for read/write IO, range 2-32");
-
-static unsigned int ts_nr_packets = 64;
-module_param(ts_nr_packets, int, 0444);
-MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)");
-
-int saa7134_ts_init_hw(struct saa7134_dev *dev)
-{
- /* deactivate TS softreset */
- saa_writeb(SAA7134_TS_SERIAL1, 0x00);
- /* TSSOP high active, TSVAL high active, TSLOCK ignored */
- saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
- saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1));
- saa_writeb(SAA7134_TS_DMA0, ((dev->ts.nr_packets-1)&0xff));
- saa_writeb(SAA7134_TS_DMA1, (((dev->ts.nr_packets-1)>>8)&0xff));
- /* TSNOPIT=0, TSCOLAP=0 */
- saa_writeb(SAA7134_TS_DMA2,
- ((((dev->ts.nr_packets-1)>>16)&0x3f) | 0x00));
-
- return 0;
-}
-
-int saa7134_ts_init1(struct saa7134_dev *dev)
-{
- /* sanitycheck insmod options */
- if (tsbufs < 2)
- tsbufs = 2;
- if (tsbufs > VIDEO_MAX_FRAME)
- tsbufs = VIDEO_MAX_FRAME;
- if (ts_nr_packets < 4)
- ts_nr_packets = 4;
- if (ts_nr_packets > 312)
- ts_nr_packets = 312;
- dev->ts.nr_bufs = tsbufs;
- dev->ts.nr_packets = ts_nr_packets;
-
- INIT_LIST_HEAD(&dev->ts_q.queue);
- init_timer(&dev->ts_q.timeout);
- dev->ts_q.timeout.function = saa7134_buffer_timeout;
- dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q);
- dev->ts_q.dev = dev;
- dev->ts_q.need_two = 1;
- dev->ts_started = 0;
- saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts);
-
- /* init TS hw */
- saa7134_ts_init_hw(dev);
-
- return 0;
-}
-
-/* Function for stop TS */
-int saa7134_ts_stop(struct saa7134_dev *dev)
-{
- dprintk("TS stop\n");
-
- BUG_ON(!dev->ts_started);
-
- /* Stop TS stream */
- switch (saa7134_boards[dev->board].ts_type) {
- case SAA7134_MPEG_TS_PARALLEL:
- saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
- dev->ts_started = 0;
- break;
- case SAA7134_MPEG_TS_SERIAL:
- saa_writeb(SAA7134_TS_SERIAL0, 0x40);
- dev->ts_started = 0;
- break;
- }
- return 0;
-}
-
-/* Function for start TS */
-int saa7134_ts_start(struct saa7134_dev *dev)
-{
- dprintk("TS start\n");
-
- BUG_ON(dev->ts_started);
-
- /* dma: setup channel 5 (= TS) */
- saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff);
- saa_writeb(SAA7134_TS_DMA1,
- ((dev->ts.nr_packets - 1) >> 8) & 0xff);
- /* TSNOPIT=0, TSCOLAP=0 */
- saa_writeb(SAA7134_TS_DMA2,
- (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00);
- saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE);
- saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 |
- SAA7134_RS_CONTROL_ME |
- (dev->ts.pt_ts.dma >> 12));
-
- /* reset hardware TS buffers */
- saa_writeb(SAA7134_TS_SERIAL1, 0x00);
- saa_writeb(SAA7134_TS_SERIAL1, 0x03);
- saa_writeb(SAA7134_TS_SERIAL1, 0x00);
- saa_writeb(SAA7134_TS_SERIAL1, 0x01);
-
- /* TS clock non-inverted */
- saa_writeb(SAA7134_TS_SERIAL1, 0x00);
-
- /* Start TS stream */
- switch (saa7134_boards[dev->board].ts_type) {
- case SAA7134_MPEG_TS_PARALLEL:
- saa_writeb(SAA7134_TS_SERIAL0, 0x40);
- saa_writeb(SAA7134_TS_PARALLEL, 0xec |
- (saa7134_boards[dev->board].ts_force_val << 4));
- break;
- case SAA7134_MPEG_TS_SERIAL:
- saa_writeb(SAA7134_TS_SERIAL0, 0xd8);
- saa_writeb(SAA7134_TS_PARALLEL, 0x6c |
- (saa7134_boards[dev->board].ts_force_val << 4));
- saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc);
- saa_writeb(SAA7134_TS_SERIAL1, 0x02);
- break;
- }
-
- dev->ts_started = 1;
-
- return 0;
-}
-
-int saa7134_ts_fini(struct saa7134_dev *dev)
-{
- saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts);
- return 0;
-}
-
-void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
-{
- enum v4l2_field field;
-
- spin_lock(&dev->slock);
- if (dev->ts_q.curr) {
- field = dev->ts_q.curr->vb.field;
- if (field == V4L2_FIELD_TOP) {
- if ((status & 0x100000) != 0x000000)
- goto done;
- } else {
- if ((status & 0x100000) != 0x100000)
- goto done;
- }
- saa7134_buffer_finish(dev,&dev->ts_q,VIDEOBUF_DONE);
- }
- saa7134_buffer_next(dev,&dev->ts_q);
-
- done:
- spin_unlock(&dev->slock);
-}
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
deleted file mode 100644
index b7a99bee2f9..00000000000
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ /dev/null
@@ -1,1087 +0,0 @@
-/*
- *
- * device driver for philips saa7134 based TV cards
- * tv audio decoder (fm stereo, nicam, ...)
- *
- * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/kthread.h>
-#include <linux/delay.h>
-#include <linux/freezer.h>
-#include <asm/div64.h>
-
-#include "saa7134-reg.h"
-#include "saa7134.h"
-
-/* ------------------------------------------------------------------ */
-
-static unsigned int audio_debug;
-module_param(audio_debug, int, 0644);
-MODULE_PARM_DESC(audio_debug,"enable debug messages [tv audio]");
-
-static unsigned int audio_ddep;
-module_param(audio_ddep, int, 0644);
-MODULE_PARM_DESC(audio_ddep,"audio ddep overwrite");
-
-static int audio_clock_override = UNSET;
-module_param(audio_clock_override, int, 0644);
-
-static int audio_clock_tweak;
-module_param(audio_clock_tweak, int, 0644);
-MODULE_PARM_DESC(audio_clock_tweak, "Audio clock tick fine tuning for cards with audio crystal that's slightly off (range [-1024 .. 1024])");
-
-#define dprintk(fmt, arg...) if (audio_debug) \
- printk(KERN_DEBUG "%s/audio: " fmt, dev->name , ## arg)
-#define d2printk(fmt, arg...) if (audio_debug > 1) \
- printk(KERN_DEBUG "%s/audio: " fmt, dev->name, ## arg)
-
-#define print_regb(reg) printk("%s: reg 0x%03x [%-16s]: 0x%02x\n", \
- dev->name,(SAA7134_##reg),(#reg),saa_readb((SAA7134_##reg)))
-
-/* msecs */
-#define SCAN_INITIAL_DELAY 1000
-#define SCAN_SAMPLE_DELAY 200
-#define SCAN_SUBCARRIER_DELAY 2000
-
-/* ------------------------------------------------------------------ */
-/* saa7134 code */
-
-static struct mainscan {
- char *name;
- v4l2_std_id std;
- int carr;
-} mainscan[] = {
- {
- .name = "MN",
- .std = V4L2_STD_MN,
- .carr = 4500,
- },{
- .name = "BGH",
- .std = V4L2_STD_B | V4L2_STD_GH,
- .carr = 5500,
- },{
- .name = "I",
- .std = V4L2_STD_PAL_I,
- .carr = 6000,
- },{
- .name = "DKL",
- .std = V4L2_STD_DK | V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC,
- .carr = 6500,
- }
-};
-
-static struct saa7134_tvaudio tvaudio[] = {
- {
- .name = "PAL-B/G FM-stereo",
- .std = V4L2_STD_PAL_BG,
- .mode = TVAUDIO_FM_BG_STEREO,
- .carr1 = 5500,
- .carr2 = 5742,
- },{
- .name = "PAL-D/K1 FM-stereo",
- .std = V4L2_STD_PAL_DK,
- .carr1 = 6500,
- .carr2 = 6258,
- .mode = TVAUDIO_FM_BG_STEREO,
- },{
- .name = "PAL-D/K2 FM-stereo",
- .std = V4L2_STD_PAL_DK,
- .carr1 = 6500,
- .carr2 = 6742,
- .mode = TVAUDIO_FM_BG_STEREO,
- },{
- .name = "PAL-D/K3 FM-stereo",
- .std = V4L2_STD_PAL_DK,
- .carr1 = 6500,
- .carr2 = 5742,
- .mode = TVAUDIO_FM_BG_STEREO,
- },{
- .name = "PAL-B/G NICAM",
- .std = V4L2_STD_PAL_BG,
- .carr1 = 5500,
- .carr2 = 5850,
- .mode = TVAUDIO_NICAM_FM,
- },{
- .name = "PAL-I NICAM",
- .std = V4L2_STD_PAL_I,
- .carr1 = 6000,
- .carr2 = 6552,
- .mode = TVAUDIO_NICAM_FM,
- },{
- .name = "PAL-D/K NICAM",
- .std = V4L2_STD_PAL_DK,
- .carr1 = 6500,
- .carr2 = 5850,
- .mode = TVAUDIO_NICAM_FM,
- },{
- .name = "SECAM-L NICAM",
- .std = V4L2_STD_SECAM_L,
- .carr1 = 6500,
- .carr2 = 5850,
- .mode = TVAUDIO_NICAM_AM,
- },{
- .name = "SECAM-D/K NICAM",
- .std = V4L2_STD_SECAM_DK,
- .carr1 = 6500,
- .carr2 = 5850,
- .mode = TVAUDIO_NICAM_FM,
- },{
- .name = "NTSC-A2 FM-stereo",
- .std = V4L2_STD_NTSC,
- .carr1 = 4500,
- .carr2 = 4724,
- .mode = TVAUDIO_FM_K_STEREO,
- },{
- .name = "NTSC-M",
- .std = V4L2_STD_NTSC,
- .carr1 = 4500,
- .carr2 = -1,
- .mode = TVAUDIO_FM_MONO,
- }
-};
-#define TVAUDIO ARRAY_SIZE(tvaudio)
-
-/* ------------------------------------------------------------------ */
-
-static u32 tvaudio_carr2reg(u32 carrier)
-{
- u64 a = carrier;
-
- a <<= 24;
- do_div(a,12288);
- return a;
-}
-
-static void tvaudio_setcarrier(struct saa7134_dev *dev,
- int primary, int secondary)
-{
- if (-1 == secondary)
- secondary = primary;
- saa_writel(SAA7134_CARRIER1_FREQ0 >> 2, tvaudio_carr2reg(primary));
- saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary));
-}
-
-#define SAA7134_MUTE_MASK 0xbb
-#define SAA7134_MUTE_ANALOG 0x04
-#define SAA7134_MUTE_I2S 0x40
-
-static void mute_input_7134(struct saa7134_dev *dev)
-{
- unsigned int mute;
- struct saa7134_input *in;
- int ausel=0, ics=0, ocs=0;
- int mask;
-
- /* look what is to do ... */
- in = dev->input;
- mute = (dev->ctl_mute ||
- (dev->automute && (&card(dev).radio) != in));
- if (card(dev).mute.name) {
- /*
- * 7130 - we'll mute using some unconnected audio input
- * 7134 - we'll probably should switch external mux with gpio
- */
- if (mute)
- in = &card(dev).mute;
- }
-
- if (dev->hw_mute == mute &&
- dev->hw_input == in && !dev->insuspend) {
- dprintk("mute/input: nothing to do [mute=%d,input=%s]\n",
- mute,in->name);
- return;
- }
-
- dprintk("ctl_mute=%d automute=%d input=%s => mute=%d input=%s\n",
- dev->ctl_mute,dev->automute,dev->input->name,mute,in->name);
- dev->hw_mute = mute;
- dev->hw_input = in;
-
- if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device)
- /* 7134 mute */
- saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ?
- SAA7134_MUTE_MASK |
- SAA7134_MUTE_ANALOG |
- SAA7134_MUTE_I2S :
- SAA7134_MUTE_MASK);
-
- /* switch internal audio mux */
- switch (in->amux) {
- case TV: ausel=0xc0; ics=0x00; ocs=0x02; break;
- case LINE1: ausel=0x80; ics=0x00; ocs=0x00; break;
- case LINE2: ausel=0x80; ics=0x08; ocs=0x01; break;
- case LINE2_LEFT: ausel=0x80; ics=0x08; ocs=0x05; break;
- }
- saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, ausel);
- saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, ics);
- saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, ocs);
- // for oss, we need to change the clock configuration
- if (in->amux == TV)
- saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
- else
- saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x01);
-
- /* switch gpio-connected external audio mux */
- if (0 == card(dev).gpiomask)
- return;
-
- mask = card(dev).gpiomask;
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
- saa7134_track_gpio(dev,in->name);
-}
-
-static void tvaudio_setmode(struct saa7134_dev *dev,
- struct saa7134_tvaudio *audio,
- char *note)
-{
- int acpf, tweak = 0;
-
- if (dev->tvnorm->id == V4L2_STD_NTSC) {
- acpf = 0x19066;
- } else {
- acpf = 0x1e000;
- }
- if (audio_clock_tweak > -1024 && audio_clock_tweak < 1024)
- tweak = audio_clock_tweak;
-
- if (note)
- dprintk("tvaudio_setmode: %s %s [%d.%03d/%d.%03d MHz] acpf=%d%+d\n",
- note,audio->name,
- audio->carr1 / 1000, audio->carr1 % 1000,
- audio->carr2 / 1000, audio->carr2 % 1000,
- acpf, tweak);
-
- acpf += tweak;
- saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD0, (acpf & 0x0000ff) >> 0);
- saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD1, (acpf & 0x00ff00) >> 8);
- saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD2, (acpf & 0x030000) >> 16);
- tvaudio_setcarrier(dev,audio->carr1,audio->carr2);
-
- switch (audio->mode) {
- case TVAUDIO_FM_MONO:
- case TVAUDIO_FM_BG_STEREO:
- saa_writeb(SAA7134_DEMODULATOR, 0x00);
- saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00);
- saa_writeb(SAA7134_FM_DEEMPHASIS, 0x22);
- saa_writeb(SAA7134_FM_DEMATRIX, 0x80);
- saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa0);
- break;
- case TVAUDIO_FM_K_STEREO:
- saa_writeb(SAA7134_DEMODULATOR, 0x00);
- saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x01);
- saa_writeb(SAA7134_FM_DEEMPHASIS, 0x22);
- saa_writeb(SAA7134_FM_DEMATRIX, 0x80);
- saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa0);
- break;
- case TVAUDIO_NICAM_FM:
- saa_writeb(SAA7134_DEMODULATOR, 0x10);
- saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00);
- saa_writeb(SAA7134_FM_DEEMPHASIS, 0x44);
- saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa1);
- saa_writeb(SAA7134_NICAM_CONFIG, 0x00);
- break;
- case TVAUDIO_NICAM_AM:
- saa_writeb(SAA7134_DEMODULATOR, 0x12);
- saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00);
- saa_writeb(SAA7134_FM_DEEMPHASIS, 0x44);
- saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa1);
- saa_writeb(SAA7134_NICAM_CONFIG, 0x00);
- break;
- case TVAUDIO_FM_SAT_STEREO:
- /* not implemented (yet) */
- break;
- }
-}
-
-static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
-{
- if (dev->thread.scan1 == dev->thread.scan2 &&
- !kthread_should_stop()) {
- if (timeout < 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- } else {
- schedule_timeout_interruptible
- (msecs_to_jiffies(timeout));
- }
- }
- return dev->thread.scan1 != dev->thread.scan2;
-}
-
-static int tvaudio_checkcarrier(struct saa7134_dev *dev, struct mainscan *scan)
-{
- __s32 left,right,value;
-
- if (!(dev->tvnorm->id & scan->std)) {
- value = 0;
- dprintk("skipping %d.%03d MHz [%4s]\n",
- scan->carr / 1000, scan->carr % 1000, scan->name);
- return 0;
- }
-
- if (audio_debug > 1) {
- int i;
- dprintk("debug %d:",scan->carr);
- for (i = -150; i <= 150; i += 30) {
- tvaudio_setcarrier(dev,scan->carr+i,scan->carr+i);
- saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
- if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
- return -1;
- value = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
- if (0 == i)
- printk(" # %6d # ",value >> 16);
- else
- printk(" %6d",value >> 16);
- }
- printk("\n");
- }
-
- tvaudio_setcarrier(dev,scan->carr-90,scan->carr-90);
- saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
- if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
- return -1;
- left = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
-
- tvaudio_setcarrier(dev,scan->carr+90,scan->carr+90);
- saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
- if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
- return -1;
- right = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
-
- left >>= 16;
- right >>= 16;
- value = left > right ? left - right : right - left;
- dprintk("scanning %d.%03d MHz [%4s] => dc is %5d [%d/%d]\n",
- scan->carr / 1000, scan->carr % 1000,
- scan->name, value, left, right);
- return value;
-}
-
-
-static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *audio)
-{
- __u32 idp, nicam, nicam_status;
- int retval = -1;
-
- switch (audio->mode) {
- case TVAUDIO_FM_MONO:
- return V4L2_TUNER_SUB_MONO;
- case TVAUDIO_FM_K_STEREO:
- case TVAUDIO_FM_BG_STEREO:
- idp = (saa_readb(SAA7134_IDENT_SIF) & 0xe0) >> 5;
- dprintk("getstereo: fm/stereo: idp=0x%x\n",idp);
- if (0x03 == (idp & 0x03))
- retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- else if (0x05 == (idp & 0x05))
- retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
- else if (0x01 == (idp & 0x01))
- retval = V4L2_TUNER_SUB_MONO;
- break;
- case TVAUDIO_FM_SAT_STEREO:
- /* not implemented (yet) */
- break;
- case TVAUDIO_NICAM_FM:
- case TVAUDIO_NICAM_AM:
- nicam = saa_readb(SAA7134_AUDIO_STATUS);
- dprintk("getstereo: nicam=0x%x\n",nicam);
- if (nicam & 0x1) {
- nicam_status = saa_readb(SAA7134_NICAM_STATUS);
- dprintk("getstereo: nicam_status=0x%x\n", nicam_status);
-
- switch (nicam_status & 0x03) {
- case 0x01:
- retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- break;
- case 0x02:
- retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
- break;
- default:
- retval = V4L2_TUNER_SUB_MONO;
- }
- } else {
- /* No nicam detected */
- }
- break;
- }
- if (retval != -1)
- dprintk("found audio subchannels:%s%s%s%s\n",
- (retval & V4L2_TUNER_SUB_MONO) ? " mono" : "",
- (retval & V4L2_TUNER_SUB_STEREO) ? " stereo" : "",
- (retval & V4L2_TUNER_SUB_LANG1) ? " lang1" : "",
- (retval & V4L2_TUNER_SUB_LANG2) ? " lang2" : "");
- return retval;
-}
-
-static int tvaudio_setstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *audio,
- u32 mode)
-{
- static char *name[] = {
- [ V4L2_TUNER_MODE_MONO ] = "mono",
- [ V4L2_TUNER_MODE_STEREO ] = "stereo",
- [ V4L2_TUNER_MODE_LANG1 ] = "lang1",
- [ V4L2_TUNER_MODE_LANG2 ] = "lang2",
- [ V4L2_TUNER_MODE_LANG1_LANG2 ] = "lang1+lang2",
- };
- static u32 fm[] = {
- [ V4L2_TUNER_MODE_MONO ] = 0x00, /* ch1 */
- [ V4L2_TUNER_MODE_STEREO ] = 0x80, /* auto */
- [ V4L2_TUNER_MODE_LANG1 ] = 0x00, /* ch1 */
- [ V4L2_TUNER_MODE_LANG2 ] = 0x01, /* ch2 */
- [ V4L2_TUNER_MODE_LANG1_LANG2 ] = 0x80, /* auto */
- };
- u32 reg;
-
- switch (audio->mode) {
- case TVAUDIO_FM_MONO:
- /* nothing to do ... */
- break;
- case TVAUDIO_FM_K_STEREO:
- case TVAUDIO_FM_BG_STEREO:
- case TVAUDIO_NICAM_AM:
- case TVAUDIO_NICAM_FM:
- dprintk("setstereo [fm] => %s\n",
- name[ mode % ARRAY_SIZE(name) ]);
- reg = fm[ mode % ARRAY_SIZE(fm) ];
- saa_writeb(SAA7134_FM_DEMATRIX, reg);
- break;
- case TVAUDIO_FM_SAT_STEREO:
- /* Not implemented */
- break;
- }
- return 0;
-}
-
-static int tvaudio_thread(void *data)
-{
- struct saa7134_dev *dev = data;
- int carr_vals[ARRAY_SIZE(mainscan)];
- unsigned int i, audio, nscan;
- int max1,max2,carrier,rx,mode,lastmode,default_carrier;
-
- set_freezable();
-
- for (;;) {
- tvaudio_sleep(dev,-1);
- if (kthread_should_stop())
- goto done;
-
- restart:
- try_to_freeze();
-
- dev->thread.scan1 = dev->thread.scan2;
- dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
- dev->tvaudio = NULL;
-
- saa_writeb(SAA7134_MONITOR_SELECT, 0xa0);
- saa_writeb(SAA7134_FM_DEMATRIX, 0x80);
-
- if (dev->ctl_automute)
- dev->automute = 1;
-
- mute_input_7134(dev);
-
- /* give the tuner some time */
- if (tvaudio_sleep(dev,SCAN_INITIAL_DELAY))
- goto restart;
-
- max1 = 0;
- max2 = 0;
- nscan = 0;
- carrier = 0;
- default_carrier = 0;
- for (i = 0; i < ARRAY_SIZE(mainscan); i++) {
- if (!(dev->tvnorm->id & mainscan[i].std))
- continue;
- if (!default_carrier)
- default_carrier = mainscan[i].carr;
- nscan++;
- }
-
- if (1 == nscan) {
- /* only one candidate -- skip scan ;) */
- dprintk("only one main carrier candidate - skipping scan\n");
- max1 = 12345;
- carrier = default_carrier;
- } else {
- /* scan for the main carrier */
- saa_writeb(SAA7134_MONITOR_SELECT,0x00);
- tvaudio_setmode(dev,&tvaudio[0],NULL);
- for (i = 0; i < ARRAY_SIZE(mainscan); i++) {
- carr_vals[i] = tvaudio_checkcarrier(dev, mainscan+i);
- if (dev->thread.scan1 != dev->thread.scan2)
- goto restart;
- }
- for (max1 = 0, max2 = 0, i = 0; i < ARRAY_SIZE(mainscan); i++) {
- if (max1 < carr_vals[i]) {
- max2 = max1;
- max1 = carr_vals[i];
- carrier = mainscan[i].carr;
- } else if (max2 < carr_vals[i]) {
- max2 = carr_vals[i];
- }
- }
- }
-
- if (0 != carrier && max1 > 2000 && max1 > max2*3) {
- /* found good carrier */
- dprintk("found %s main sound carrier @ %d.%03d MHz [%d/%d]\n",
- dev->tvnorm->name, carrier/1000, carrier%1000,
- max1, max2);
- dev->last_carrier = carrier;
- dev->automute = 0;
-
- } else if (0 != dev->last_carrier) {
- /* no carrier -- try last detected one as fallback */
- carrier = dev->last_carrier;
- dprintk("audio carrier scan failed, "
- "using %d.%03d MHz [last detected]\n",
- carrier/1000, carrier%1000);
- dev->automute = 1;
-
- } else {
- /* no carrier + no fallback -- use default */
- carrier = default_carrier;
- dprintk("audio carrier scan failed, "
- "using %d.%03d MHz [default]\n",
- carrier/1000, carrier%1000);
- dev->automute = 1;
- }
- tvaudio_setcarrier(dev,carrier,carrier);
- saa_andorb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0x30, 0x00);
- saa7134_tvaudio_setmute(dev);
- /* find the exact tv audio norm */
- for (audio = UNSET, i = 0; i < TVAUDIO; i++) {
- if (dev->tvnorm->id != UNSET &&
- !(dev->tvnorm->id & tvaudio[i].std))
- continue;
- if (tvaudio[i].carr1 != carrier)
- continue;
- /* Note: at least the primary carrier is right here */
- if (UNSET == audio)
- audio = i;
- tvaudio_setmode(dev,&tvaudio[i],"trying");
- if (tvaudio_sleep(dev,SCAN_SUBCARRIER_DELAY))
- goto restart;
- if (-1 != tvaudio_getstereo(dev,&tvaudio[i])) {
- audio = i;
- break;
- }
- }
- saa_andorb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0x30, 0x30);
- if (UNSET == audio)
- continue;
- tvaudio_setmode(dev,&tvaudio[audio],"using");
-
- tvaudio_setstereo(dev,&tvaudio[audio],V4L2_TUNER_MODE_MONO);
- dev->tvaudio = &tvaudio[audio];
-
- lastmode = 42;
- for (;;) {
-
- try_to_freeze();
-
- if (tvaudio_sleep(dev,5000))
- goto restart;
- if (kthread_should_stop())
- break;
- if (UNSET == dev->thread.mode) {
- rx = tvaudio_getstereo(dev, &tvaudio[audio]);
- mode = saa7134_tvaudio_rx2mode(rx);
- } else {
- mode = dev->thread.mode;
- }
- if (lastmode != mode) {
- tvaudio_setstereo(dev,&tvaudio[audio],mode);
- lastmode = mode;
- }
- }
- }
-
- done:
- dev->thread.stopped = 1;
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-/* saa7133 / saa7135 code */
-
-static char *stdres[0x20] = {
- [0x00] = "no standard detected",
- [0x01] = "B/G (in progress)",
- [0x02] = "D/K (in progress)",
- [0x03] = "M (in progress)",
-
- [0x04] = "B/G A2",
- [0x05] = "B/G NICAM",
- [0x06] = "D/K A2 (1)",
- [0x07] = "D/K A2 (2)",
- [0x08] = "D/K A2 (3)",
- [0x09] = "D/K NICAM",
- [0x0a] = "L NICAM",
- [0x0b] = "I NICAM",
-
- [0x0c] = "M Korea",
- [0x0d] = "M BTSC ",
- [0x0e] = "M EIAJ",
-
- [0x0f] = "FM radio / IF 10.7 / 50 deemp",
- [0x10] = "FM radio / IF 10.7 / 75 deemp",
- [0x11] = "FM radio / IF sel / 50 deemp",
- [0x12] = "FM radio / IF sel / 75 deemp",
-
- [0x13 ... 0x1e ] = "unknown",
- [0x1f] = "??? [in progress]",
-};
-
-#define DSP_RETRY 32
-#define DSP_DELAY 16
-#define SAA7135_DSP_RWCLEAR_RERR 1
-
-static inline int saa_dsp_reset_error_bit(struct saa7134_dev *dev)
-{
- int state = saa_readb(SAA7135_DSP_RWSTATE);
- if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) {
- d2printk("%s: resetting error bit\n", dev->name);
- saa_writeb(SAA7135_DSP_RWCLEAR, SAA7135_DSP_RWCLEAR_RERR);
- }
- return 0;
-}
-
-static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit)
-{
- int state, count = DSP_RETRY;
-
- state = saa_readb(SAA7135_DSP_RWSTATE);
- if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) {
- printk(KERN_WARNING "%s: dsp access error\n", dev->name);
- saa_dsp_reset_error_bit(dev);
- return -EIO;
- }
- while (0 == (state & bit)) {
- if (unlikely(0 == count)) {
- printk("%s: dsp access wait timeout [bit=%s]\n",
- dev->name,
- (bit & SAA7135_DSP_RWSTATE_WRR) ? "WRR" :
- (bit & SAA7135_DSP_RWSTATE_RDB) ? "RDB" :
- (bit & SAA7135_DSP_RWSTATE_IDA) ? "IDA" :
- "???");
- return -EIO;
- }
- saa_wait(DSP_DELAY);
- state = saa_readb(SAA7135_DSP_RWSTATE);
- count--;
- }
- return 0;
-}
-
-
-int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value)
-{
- int err;
-
- d2printk("dsp write reg 0x%x = 0x%06x\n",reg<<2,value);
- err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_WRR);
- if (err < 0)
- return err;
- saa_writel(reg,value);
- err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_WRR);
- if (err < 0)
- return err;
- return 0;
-}
-
-static int getstereo_7133(struct saa7134_dev *dev)
-{
- int retval = V4L2_TUNER_SUB_MONO;
- u32 value;
-
- value = saa_readl(0x528 >> 2);
- if (value & 0x20)
- retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
- if (value & 0x40)
- retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- return retval;
-}
-
-static int mute_input_7133(struct saa7134_dev *dev)
-{
- u32 reg = 0;
- u32 xbarin, xbarout;
- int mask;
- struct saa7134_input *in;
-
- xbarin = 0x03;
- switch (dev->input->amux) {
- case TV:
- reg = 0x02;
- xbarin = 0;
- break;
- case LINE1:
- reg = 0x00;
- break;
- case LINE2:
- case LINE2_LEFT:
- reg = 0x09;
- break;
- }
- saa_dsp_writel(dev, 0x464 >> 2, xbarin);
- if (dev->ctl_mute) {
- reg = 0x07;
- xbarout = 0xbbbbbb;
- } else
- xbarout = 0xbbbb10;
- saa_dsp_writel(dev, 0x46c >> 2, xbarout);
-
- saa_writel(0x594 >> 2, reg);
-
-
- /* switch gpio-connected external audio mux */
- if (0 != card(dev).gpiomask) {
- mask = card(dev).gpiomask;
-
- if (card(dev).mute.name && dev->ctl_mute)
- in = &card(dev).mute;
- else
- in = dev->input;
-
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
- saa7134_track_gpio(dev,in->name);
- }
-
- return 0;
-}
-
-static int tvaudio_thread_ddep(void *data)
-{
- struct saa7134_dev *dev = data;
- u32 value, norms;
-
- set_freezable();
- for (;;) {
- tvaudio_sleep(dev,-1);
- if (kthread_should_stop())
- goto done;
- restart:
- try_to_freeze();
-
- dev->thread.scan1 = dev->thread.scan2;
- dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
-
- if (audio_ddep >= 0x04 && audio_ddep <= 0x0e) {
- /* insmod option override */
- norms = (audio_ddep << 2) | 0x01;
- dprintk("ddep override: %s\n",stdres[audio_ddep]);
- } else if (&card(dev).radio == dev->input) {
- dprintk("FM Radio\n");
- if (dev->tuner_type == TUNER_PHILIPS_TDA8290) {
- norms = (0x11 << 2) | 0x01;
- saa_dsp_writel(dev, 0x42c >> 2, 0x729555);
- } else {
- norms = (0x0f << 2) | 0x01;
- }
- } else {
- /* (let chip) scan for sound carrier */
- norms = 0;
- if (dev->tvnorm->id & (V4L2_STD_B | V4L2_STD_GH))
- norms |= 0x04;
- if (dev->tvnorm->id & V4L2_STD_PAL_I)
- norms |= 0x20;
- if (dev->tvnorm->id & V4L2_STD_DK)
- norms |= 0x08;
- if (dev->tvnorm->id & V4L2_STD_MN)
- norms |= 0x40;
- if (dev->tvnorm->id & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))
- norms |= 0x10;
- if (0 == norms)
- norms = 0x7c; /* all */
- dprintk("scanning:%s%s%s%s%s\n",
- (norms & 0x04) ? " B/G" : "",
- (norms & 0x08) ? " D/K" : "",
- (norms & 0x10) ? " L/L'" : "",
- (norms & 0x20) ? " I" : "",
- (norms & 0x40) ? " M" : "");
- }
-
- /* kick automatic standard detection */
- saa_dsp_writel(dev, 0x454 >> 2, 0);
- saa_dsp_writel(dev, 0x454 >> 2, norms | 0x80);
-
- /* setup crossbars */
- saa_dsp_writel(dev, 0x464 >> 2, 0x000000);
- saa_dsp_writel(dev, 0x470 >> 2, 0x101010);
-
- if (tvaudio_sleep(dev,3000))
- goto restart;
- value = saa_readl(0x528 >> 2) & 0xffffff;
-
- dprintk("tvaudio thread status: 0x%x [%s%s%s]\n",
- value, stdres[value & 0x1f],
- (value & 0x000020) ? ",stereo" : "",
- (value & 0x000040) ? ",dual" : "");
- dprintk("detailed status: "
- "%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n",
- (value & 0x000080) ? " A2/EIAJ pilot tone " : "",
- (value & 0x000100) ? " A2/EIAJ dual " : "",
- (value & 0x000200) ? " A2/EIAJ stereo " : "",
- (value & 0x000400) ? " A2/EIAJ noise mute " : "",
-
- (value & 0x000800) ? " BTSC/FM radio pilot " : "",
- (value & 0x001000) ? " SAP carrier " : "",
- (value & 0x002000) ? " BTSC stereo noise mute " : "",
- (value & 0x004000) ? " SAP noise mute " : "",
- (value & 0x008000) ? " VDSP " : "",
-
- (value & 0x010000) ? " NICST " : "",
- (value & 0x020000) ? " NICDU " : "",
- (value & 0x040000) ? " NICAM muted " : "",
- (value & 0x080000) ? " NICAM reserve sound " : "",
-
- (value & 0x100000) ? " init done " : "");
- }
-
- done:
- dev->thread.stopped = 1;
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-/* common stuff + external entry points */
-
-void saa7134_enable_i2s(struct saa7134_dev *dev)
-{
- int i2s_format;
-
- if (!card_is_empress(dev))
- return;
-
- if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130)
- return;
-
- /* configure GPIO for out */
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0E000000, 0x00000000);
-
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- /* Set I2S format (SONY)  */
- saa_writeb(SAA7133_I2S_AUDIO_CONTROL, 0x00);
- /* Start I2S */
- saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x11);
- break;
-
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- i2s_format = (dev->input->amux == TV) ? 0x00 : 0x01;
-
- /* enable I2S audio output for the mpeg encoder */
- saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80);
- saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2s_format);
- saa_writeb(SAA7134_I2S_OUTPUT_LEVEL, 0x0F);
- saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x01);
-
- default:
- break;
- }
-}
-
-int saa7134_tvaudio_rx2mode(u32 rx)
-{
- u32 mode;
-
- mode = V4L2_TUNER_MODE_MONO;
- if (rx & V4L2_TUNER_SUB_STEREO)
- mode = V4L2_TUNER_MODE_STEREO;
- else if (rx & V4L2_TUNER_SUB_LANG1)
- mode = V4L2_TUNER_MODE_LANG1;
- else if (rx & V4L2_TUNER_SUB_LANG2)
- mode = V4L2_TUNER_MODE_LANG2;
- return mode;
-}
-
-void saa7134_tvaudio_setmute(struct saa7134_dev *dev)
-{
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7130:
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- mute_input_7134(dev);
- break;
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- mute_input_7133(dev);
- break;
- }
-}
-
-void saa7134_tvaudio_setinput(struct saa7134_dev *dev,
- struct saa7134_input *in)
-{
- dev->input = in;
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7130:
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- mute_input_7134(dev);
- break;
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- mute_input_7133(dev);
- break;
- }
- saa7134_enable_i2s(dev);
-}
-
-void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level)
-{
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- saa_writeb(SAA7134_CHANNEL1_LEVEL, level & 0x1f);
- saa_writeb(SAA7134_CHANNEL2_LEVEL, level & 0x1f);
- saa_writeb(SAA7134_NICAM_LEVEL_ADJUST, level & 0x1f);
- break;
- }
-}
-
-int saa7134_tvaudio_getstereo(struct saa7134_dev *dev)
-{
- int retval = V4L2_TUNER_SUB_MONO;
-
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- if (dev->tvaudio)
- retval = tvaudio_getstereo(dev,dev->tvaudio);
- break;
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- retval = getstereo_7133(dev);
- break;
- }
- return retval;
-}
-
-void saa7134_tvaudio_init(struct saa7134_dev *dev)
-{
- int clock = saa7134_boards[dev->board].audio_clock;
-
- if (UNSET != audio_clock_override)
- clock = audio_clock_override;
-
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- /* init all audio registers */
- saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x00);
- if (need_resched())
- schedule();
- else
- udelay(10);
-
- saa_writeb(SAA7134_AUDIO_CLOCK0, clock & 0xff);
- saa_writeb(SAA7134_AUDIO_CLOCK1, (clock >> 8) & 0xff);
- saa_writeb(SAA7134_AUDIO_CLOCK2, (clock >> 16) & 0xff);
- /* frame locked audio is mandatory for NICAM */
- saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x01);
- saa_writeb(SAA7134_NICAM_ERROR_LOW, 0x14);
- saa_writeb(SAA7134_NICAM_ERROR_HIGH, 0x50);
- break;
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- saa_writel(0x598 >> 2, clock);
- saa_dsp_writel(dev, 0x474 >> 2, 0x00);
- saa_dsp_writel(dev, 0x450 >> 2, 0x00);
- }
-}
-
-int saa7134_tvaudio_init2(struct saa7134_dev *dev)
-{
- int (*my_thread)(void *data) = NULL;
-
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- my_thread = tvaudio_thread;
- break;
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- my_thread = tvaudio_thread_ddep;
- break;
- }
-
- dev->thread.thread = NULL;
- dev->thread.scan1 = dev->thread.scan2 = 0;
- if (my_thread) {
- saa7134_tvaudio_init(dev);
- /* start tvaudio thread */
- dev->thread.thread = kthread_run(my_thread, dev, "%s", dev->name);
- if (IS_ERR(dev->thread.thread)) {
- printk(KERN_WARNING "%s: kernel_thread() failed\n",
- dev->name);
- /* XXX: missing error handling here */
- }
- }
-
- saa7134_enable_i2s(dev);
- return 0;
-}
-
-int saa7134_tvaudio_close(struct saa7134_dev *dev)
-{
- dev->automute = 1;
- /* anything else to undo? */
- return 0;
-}
-
-int saa7134_tvaudio_fini(struct saa7134_dev *dev)
-{
- /* shutdown tvaudio thread */
- if (dev->thread.thread && !dev->thread.stopped)
- kthread_stop(dev->thread.thread);
-
- saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, 0x00); /* LINE1 */
- return 0;
-}
-
-int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
-{
- if (dev->input->amux != TV) {
- dprintk("sound IF not in use, skipping scan\n");
- dev->automute = 0;
- saa7134_tvaudio_setmute(dev);
- } else if (dev->thread.thread) {
- dev->thread.mode = UNSET;
- dev->thread.scan2++;
-
- if (!dev->insuspend && !dev->thread.stopped)
- wake_up_process(dev->thread.thread);
- } else {
- dev->automute = 0;
- saa7134_tvaudio_setmute(dev);
- }
- return 0;
-}
-
-EXPORT_SYMBOL(saa_dsp_writel);
-EXPORT_SYMBOL(saa7134_tvaudio_setmute);
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c
deleted file mode 100644
index e9aa94b807f..00000000000
--- a/drivers/media/video/saa7134/saa7134-vbi.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- *
- * device driver for philips saa7134 based TV cards
- * video4linux video interface
- *
- * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#include "saa7134-reg.h"
-#include "saa7134.h"
-
-/* ------------------------------------------------------------------ */
-
-static unsigned int vbi_debug;
-module_param(vbi_debug, int, 0644);
-MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]");
-
-static unsigned int vbibufs = 4;
-module_param(vbibufs, int, 0444);
-MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32");
-
-#define dprintk(fmt, arg...) if (vbi_debug) \
- printk(KERN_DEBUG "%s/vbi: " fmt, dev->name , ## arg)
-
-/* ------------------------------------------------------------------ */
-
-#define VBI_LINE_COUNT 16
-#define VBI_LINE_LENGTH 2048
-#define VBI_SCALE 0x200
-
-static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf,
- int task)
-{
- struct saa7134_tvnorm *norm = dev->tvnorm;
-
- /* setup video scaler */
- saa_writeb(SAA7134_VBI_H_START1(task), norm->h_start & 0xff);
- saa_writeb(SAA7134_VBI_H_START2(task), norm->h_start >> 8);
- saa_writeb(SAA7134_VBI_H_STOP1(task), norm->h_stop & 0xff);
- saa_writeb(SAA7134_VBI_H_STOP2(task), norm->h_stop >> 8);
- saa_writeb(SAA7134_VBI_V_START1(task), norm->vbi_v_start_0 & 0xff);
- saa_writeb(SAA7134_VBI_V_START2(task), norm->vbi_v_start_0 >> 8);
- saa_writeb(SAA7134_VBI_V_STOP1(task), norm->vbi_v_stop_0 & 0xff);
- saa_writeb(SAA7134_VBI_V_STOP2(task), norm->vbi_v_stop_0 >> 8);
-
- saa_writeb(SAA7134_VBI_H_SCALE_INC1(task), VBI_SCALE & 0xff);
- saa_writeb(SAA7134_VBI_H_SCALE_INC2(task), VBI_SCALE >> 8);
- saa_writeb(SAA7134_VBI_PHASE_OFFSET_LUMA(task), 0x00);
- saa_writeb(SAA7134_VBI_PHASE_OFFSET_CHROMA(task), 0x00);
-
- saa_writeb(SAA7134_VBI_H_LEN1(task), buf->vb.width & 0xff);
- saa_writeb(SAA7134_VBI_H_LEN2(task), buf->vb.width >> 8);
- saa_writeb(SAA7134_VBI_V_LEN1(task), buf->vb.height & 0xff);
- saa_writeb(SAA7134_VBI_V_LEN2(task), buf->vb.height >> 8);
-
- saa_andorb(SAA7134_DATA_PATH(task), 0xc0, 0x00);
-}
-
-/* ------------------------------------------------------------------ */
-
-static int buffer_activate(struct saa7134_dev *dev,
- struct saa7134_buf *buf,
- struct saa7134_buf *next)
-{
- unsigned long control,base;
-
- dprintk("buffer_activate [%p]\n",buf);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->top_seen = 0;
-
- task_init(dev,buf,TASK_A);
- task_init(dev,buf,TASK_B);
- saa_writeb(SAA7134_OFMT_DATA_A, 0x06);
- saa_writeb(SAA7134_OFMT_DATA_B, 0x06);
-
- /* DMA: setup channel 2+3 (= VBI Task A+B) */
- base = saa7134_buffer_base(buf);
- control = SAA7134_RS_CONTROL_BURST_16 |
- SAA7134_RS_CONTROL_ME |
- (buf->pt->dma >> 12);
- saa_writel(SAA7134_RS_BA1(2),base);
- saa_writel(SAA7134_RS_BA2(2),base + buf->vb.size/2);
- saa_writel(SAA7134_RS_PITCH(2),buf->vb.width);
- saa_writel(SAA7134_RS_CONTROL(2),control);
- saa_writel(SAA7134_RS_BA1(3),base);
- saa_writel(SAA7134_RS_BA2(3),base + buf->vb.size/2);
- saa_writel(SAA7134_RS_PITCH(3),buf->vb.width);
- saa_writel(SAA7134_RS_CONTROL(3),control);
-
- /* start DMA */
- saa7134_set_dmabits(dev);
- mod_timer(&dev->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
-
- return 0;
-}
-
-static int buffer_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct saa7134_fh *fh = q->priv_data;
- struct saa7134_dev *dev = fh->dev;
- struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
- struct saa7134_tvnorm *norm = dev->tvnorm;
- unsigned int lines, llength, size;
- int err;
-
- lines = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1;
- if (lines > VBI_LINE_COUNT)
- lines = VBI_LINE_COUNT;
- llength = VBI_LINE_LENGTH;
- size = lines * llength * 2;
- if (0 != buf->vb.baddr && buf->vb.bsize < size)
- return -EINVAL;
-
- if (buf->vb.size != size)
- saa7134_dma_free(q,buf);
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
-
- buf->vb.width = llength;
- buf->vb.height = lines;
- buf->vb.size = size;
- buf->pt = &fh->pt_vbi;
-
- err = videobuf_iolock(q,&buf->vb,NULL);
- if (err)
- goto oops;
- err = saa7134_pgtable_build(dev->pci,buf->pt,
- dma->sglist,
- dma->sglen,
- saa7134_buffer_startpage(buf));
- if (err)
- goto oops;
- }
- buf->vb.state = VIDEOBUF_PREPARED;
- buf->activate = buffer_activate;
- buf->vb.field = field;
- return 0;
-
- oops:
- saa7134_dma_free(q,buf);
- return err;
-}
-
-static int
-buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
-{
- struct saa7134_fh *fh = q->priv_data;
- struct saa7134_dev *dev = fh->dev;
- int llength,lines;
-
- lines = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 +1;
- llength = VBI_LINE_LENGTH;
- *size = lines * llength * 2;
- if (0 == *count)
- *count = vbibufs;
- *count = saa7134_buffer_count(*size,*count);
- return 0;
-}
-
-static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct saa7134_fh *fh = q->priv_data;
- struct saa7134_dev *dev = fh->dev;
- struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
-
- saa7134_buffer_queue(dev,&dev->vbi_q,buf);
-}
-
-static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
-
- saa7134_dma_free(q,buf);
-}
-
-struct videobuf_queue_ops saa7134_vbi_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-/* ------------------------------------------------------------------ */
-
-int saa7134_vbi_init1(struct saa7134_dev *dev)
-{
- INIT_LIST_HEAD(&dev->vbi_q.queue);
- init_timer(&dev->vbi_q.timeout);
- dev->vbi_q.timeout.function = saa7134_buffer_timeout;
- dev->vbi_q.timeout.data = (unsigned long)(&dev->vbi_q);
- dev->vbi_q.dev = dev;
-
- if (vbibufs < 2)
- vbibufs = 2;
- if (vbibufs > VIDEO_MAX_FRAME)
- vbibufs = VIDEO_MAX_FRAME;
- return 0;
-}
-
-int saa7134_vbi_fini(struct saa7134_dev *dev)
-{
- /* nothing */
- return 0;
-}
-
-void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)
-{
- spin_lock(&dev->slock);
- if (dev->vbi_q.curr) {
- dev->vbi_fieldcount++;
- /* make sure we have seen both fields */
- if ((status & 0x10) == 0x00) {
- dev->vbi_q.curr->top_seen = 1;
- goto done;
- }
- if (!dev->vbi_q.curr->top_seen)
- goto done;
-
- dev->vbi_q.curr->vb.field_count = dev->vbi_fieldcount;
- saa7134_buffer_finish(dev,&dev->vbi_q,VIDEOBUF_DONE);
- }
- saa7134_buffer_next(dev,&dev->vbi_q);
-
- done:
- spin_unlock(&dev->slock);
-}
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
deleted file mode 100644
index 6de10b1e725..00000000000
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ /dev/null
@@ -1,2661 +0,0 @@
-/*
- *
- * device driver for philips saa7134 based TV cards
- * video4linux video interface
- *
- * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/sort.h>
-
-#include "saa7134-reg.h"
-#include "saa7134.h"
-#include <media/v4l2-common.h>
-#include <media/saa6588.h>
-
-/* ------------------------------------------------------------------ */
-
-unsigned int video_debug;
-static unsigned int gbuffers = 8;
-static unsigned int noninterlaced; /* 0 */
-static unsigned int gbufsize = 720*576*4;
-static unsigned int gbufsize_max = 720*576*4;
-static char secam[] = "--";
-module_param(video_debug, int, 0644);
-MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
-module_param(gbuffers, int, 0444);
-MODULE_PARM_DESC(gbuffers,"number of capture buffers, range 2-32");
-module_param(noninterlaced, int, 0644);
-MODULE_PARM_DESC(noninterlaced,"capture non interlaced video");
-module_param_string(secam, secam, sizeof(secam), 0644);
-MODULE_PARM_DESC(secam, "force SECAM variant, either DK,L or Lc");
-
-
-#define dprintk(fmt, arg...) if (video_debug&0x04) \
- printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg)
-
-/* ------------------------------------------------------------------ */
-/* Defines for Video Output Port Register at address 0x191 */
-
-/* Bit 0: VIP code T bit polarity */
-
-#define VP_T_CODE_P_NON_INVERTED 0x00
-#define VP_T_CODE_P_INVERTED 0x01
-
-/* ------------------------------------------------------------------ */
-/* Defines for Video Output Port Register at address 0x195 */
-
-/* Bit 2: Video output clock delay control */
-
-#define VP_CLK_CTRL2_NOT_DELAYED 0x00
-#define VP_CLK_CTRL2_DELAYED 0x04
-
-/* Bit 1: Video output clock invert control */
-
-#define VP_CLK_CTRL1_NON_INVERTED 0x00
-#define VP_CLK_CTRL1_INVERTED 0x02
-
-/* ------------------------------------------------------------------ */
-/* Defines for Video Output Port Register at address 0x196 */
-
-/* Bits 2 to 0: VSYNC pin video vertical sync type */
-
-#define VP_VS_TYPE_MASK 0x07
-
-#define VP_VS_TYPE_OFF 0x00
-#define VP_VS_TYPE_V123 0x01
-#define VP_VS_TYPE_V_ITU 0x02
-#define VP_VS_TYPE_VGATE_L 0x03
-#define VP_VS_TYPE_RESERVED1 0x04
-#define VP_VS_TYPE_RESERVED2 0x05
-#define VP_VS_TYPE_F_ITU 0x06
-#define VP_VS_TYPE_SC_FID 0x07
-
-/* ------------------------------------------------------------------ */
-/* data structs for video */
-
-static int video_out[][9] = {
- [CCIR656] = { 0x00, 0xb1, 0x00, 0xa1, 0x00, 0x04, 0x06, 0x00, 0x00 },
-};
-
-static struct saa7134_format formats[] = {
- {
- .name = "8 bpp gray",
- .fourcc = V4L2_PIX_FMT_GREY,
- .depth = 8,
- .pm = 0x06,
- },{
- .name = "15 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_RGB555,
- .depth = 16,
- .pm = 0x13 | 0x80,
- },{
- .name = "15 bpp RGB, be",
- .fourcc = V4L2_PIX_FMT_RGB555X,
- .depth = 16,
- .pm = 0x13 | 0x80,
- .bswap = 1,
- },{
- .name = "16 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_RGB565,
- .depth = 16,
- .pm = 0x10 | 0x80,
- },{
- .name = "16 bpp RGB, be",
- .fourcc = V4L2_PIX_FMT_RGB565X,
- .depth = 16,
- .pm = 0x10 | 0x80,
- .bswap = 1,
- },{
- .name = "24 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_BGR24,
- .depth = 24,
- .pm = 0x11,
- },{
- .name = "24 bpp RGB, be",
- .fourcc = V4L2_PIX_FMT_RGB24,
- .depth = 24,
- .pm = 0x11,
- .bswap = 1,
- },{
- .name = "32 bpp RGB, le",
- .fourcc = V4L2_PIX_FMT_BGR32,
- .depth = 32,
- .pm = 0x12,
- },{
- .name = "32 bpp RGB, be",
- .fourcc = V4L2_PIX_FMT_RGB32,
- .depth = 32,
- .pm = 0x12,
- .bswap = 1,
- .wswap = 1,
- },{
- .name = "4:2:2 packed, YUYV",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = 16,
- .pm = 0x00,
- .bswap = 1,
- .yuv = 1,
- },{
- .name = "4:2:2 packed, UYVY",
- .fourcc = V4L2_PIX_FMT_UYVY,
- .depth = 16,
- .pm = 0x00,
- .yuv = 1,
- },{
- .name = "4:2:2 planar, Y-Cb-Cr",
- .fourcc = V4L2_PIX_FMT_YUV422P,
- .depth = 16,
- .pm = 0x09,
- .yuv = 1,
- .planar = 1,
- .hshift = 1,
- .vshift = 0,
- },{
- .name = "4:2:0 planar, Y-Cb-Cr",
- .fourcc = V4L2_PIX_FMT_YUV420,
- .depth = 12,
- .pm = 0x0a,
- .yuv = 1,
- .planar = 1,
- .hshift = 1,
- .vshift = 1,
- },{
- .name = "4:2:0 planar, Y-Cb-Cr",
- .fourcc = V4L2_PIX_FMT_YVU420,
- .depth = 12,
- .pm = 0x0a,
- .yuv = 1,
- .planar = 1,
- .uvswap = 1,
- .hshift = 1,
- .vshift = 1,
- }
-};
-#define FORMATS ARRAY_SIZE(formats)
-
-#define NORM_625_50 \
- .h_start = 0, \
- .h_stop = 719, \
- .video_v_start = 24, \
- .video_v_stop = 311, \
- .vbi_v_start_0 = 7, \
- .vbi_v_stop_0 = 22, \
- .vbi_v_start_1 = 319, \
- .src_timing = 4
-
-#define NORM_525_60 \
- .h_start = 0, \
- .h_stop = 719, \
- .video_v_start = 23, \
- .video_v_stop = 262, \
- .vbi_v_start_0 = 10, \
- .vbi_v_stop_0 = 21, \
- .vbi_v_start_1 = 273, \
- .src_timing = 7
-
-static struct saa7134_tvnorm tvnorms[] = {
- {
- .name = "PAL", /* autodetect */
- .id = V4L2_STD_PAL,
- NORM_625_50,
-
- .sync_control = 0x18,
- .luma_control = 0x40,
- .chroma_ctrl1 = 0x81,
- .chroma_gain = 0x2a,
- .chroma_ctrl2 = 0x06,
- .vgate_misc = 0x1c,
-
- },{
- .name = "PAL-BG",
- .id = V4L2_STD_PAL_BG,
- NORM_625_50,
-
- .sync_control = 0x18,
- .luma_control = 0x40,
- .chroma_ctrl1 = 0x81,
- .chroma_gain = 0x2a,
- .chroma_ctrl2 = 0x06,
- .vgate_misc = 0x1c,
-
- },{
- .name = "PAL-I",
- .id = V4L2_STD_PAL_I,
- NORM_625_50,
-
- .sync_control = 0x18,
- .luma_control = 0x40,
- .chroma_ctrl1 = 0x81,
- .chroma_gain = 0x2a,
- .chroma_ctrl2 = 0x06,
- .vgate_misc = 0x1c,
-
- },{
- .name = "PAL-DK",
- .id = V4L2_STD_PAL_DK,
- NORM_625_50,
-
- .sync_control = 0x18,
- .luma_control = 0x40,
- .chroma_ctrl1 = 0x81,
- .chroma_gain = 0x2a,
- .chroma_ctrl2 = 0x06,
- .vgate_misc = 0x1c,
-
- },{
- .name = "NTSC",
- .id = V4L2_STD_NTSC,
- NORM_525_60,
-
- .sync_control = 0x59,
- .luma_control = 0x40,
- .chroma_ctrl1 = 0x89,
- .chroma_gain = 0x2a,
- .chroma_ctrl2 = 0x0e,
- .vgate_misc = 0x18,
-
- },{
- .name = "SECAM",
- .id = V4L2_STD_SECAM,
- NORM_625_50,
-
- .sync_control = 0x18,
- .luma_control = 0x1b,
- .chroma_ctrl1 = 0xd1,
- .chroma_gain = 0x80,
- .chroma_ctrl2 = 0x00,
- .vgate_misc = 0x1c,
-
- },{
- .name = "SECAM-DK",
- .id = V4L2_STD_SECAM_DK,
- NORM_625_50,
-
- .sync_control = 0x18,
- .luma_control = 0x1b,
- .chroma_ctrl1 = 0xd1,
- .chroma_gain = 0x80,
- .chroma_ctrl2 = 0x00,
- .vgate_misc = 0x1c,
-
- },{
- .name = "SECAM-L",
- .id = V4L2_STD_SECAM_L,
- NORM_625_50,
-
- .sync_control = 0x18,
- .luma_control = 0x1b,
- .chroma_ctrl1 = 0xd1,
- .chroma_gain = 0x80,
- .chroma_ctrl2 = 0x00,
- .vgate_misc = 0x1c,
-
- },{
- .name = "SECAM-Lc",
- .id = V4L2_STD_SECAM_LC,
- NORM_625_50,
-
- .sync_control = 0x18,
- .luma_control = 0x1b,
- .chroma_ctrl1 = 0xd1,
- .chroma_gain = 0x80,
- .chroma_ctrl2 = 0x00,
- .vgate_misc = 0x1c,
-
- },{
- .name = "PAL-M",
- .id = V4L2_STD_PAL_M,
- NORM_525_60,
-
- .sync_control = 0x59,
- .luma_control = 0x40,
- .chroma_ctrl1 = 0xb9,
- .chroma_gain = 0x2a,
- .chroma_ctrl2 = 0x0e,
- .vgate_misc = 0x18,
-
- },{
- .name = "PAL-Nc",
- .id = V4L2_STD_PAL_Nc,
- NORM_625_50,
-
- .sync_control = 0x18,
- .luma_control = 0x40,
- .chroma_ctrl1 = 0xa1,
- .chroma_gain = 0x2a,
- .chroma_ctrl2 = 0x06,
- .vgate_misc = 0x1c,
-
- },{
- .name = "PAL-60",
- .id = V4L2_STD_PAL_60,
-
- .h_start = 0,
- .h_stop = 719,
- .video_v_start = 23,
- .video_v_stop = 262,
- .vbi_v_start_0 = 10,
- .vbi_v_stop_0 = 21,
- .vbi_v_start_1 = 273,
- .src_timing = 7,
-
- .sync_control = 0x18,
- .luma_control = 0x40,
- .chroma_ctrl1 = 0x81,
- .chroma_gain = 0x2a,
- .chroma_ctrl2 = 0x06,
- .vgate_misc = 0x1c,
- }
-};
-#define TVNORMS ARRAY_SIZE(tvnorms)
-
-#define V4L2_CID_PRIVATE_INVERT (V4L2_CID_PRIVATE_BASE + 0)
-#define V4L2_CID_PRIVATE_Y_ODD (V4L2_CID_PRIVATE_BASE + 1)
-#define V4L2_CID_PRIVATE_Y_EVEN (V4L2_CID_PRIVATE_BASE + 2)
-#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_PRIVATE_BASE + 3)
-#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 4)
-
-static const struct v4l2_queryctrl no_ctrl = {
- .name = "42",
- .flags = V4L2_CTRL_FLAG_DISABLED,
-};
-static const struct v4l2_queryctrl video_ctrls[] = {
- /* --- video --- */
- {
- .id = V4L2_CID_BRIGHTNESS,
- .name = "Brightness",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 128,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_CONTRAST,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 127,
- .step = 1,
- .default_value = 68,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_SATURATION,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 127,
- .step = 1,
- .default_value = 64,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_HUE,
- .name = "Hue",
- .minimum = -128,
- .maximum = 127,
- .step = 1,
- .default_value = 0,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_HFLIP,
- .name = "Mirror",
- .minimum = 0,
- .maximum = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },
- /* --- audio --- */
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = -15,
- .maximum = 15,
- .step = 1,
- .default_value = 0,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
- /* --- private --- */
- {
- .id = V4L2_CID_PRIVATE_INVERT,
- .name = "Invert",
- .minimum = 0,
- .maximum = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_PRIVATE_Y_ODD,
- .name = "y offset odd field",
- .minimum = 0,
- .maximum = 128,
- .step = 1,
- .default_value = 0,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_PRIVATE_Y_EVEN,
- .name = "y offset even field",
- .minimum = 0,
- .maximum = 128,
- .step = 1,
- .default_value = 0,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_PRIVATE_AUTOMUTE,
- .name = "automute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- }
-};
-static const unsigned int CTRLS = ARRAY_SIZE(video_ctrls);
-
-static const struct v4l2_queryctrl* ctrl_by_id(unsigned int id)
-{
- unsigned int i;
-
- for (i = 0; i < CTRLS; i++)
- if (video_ctrls[i].id == id)
- return video_ctrls+i;
- return NULL;
-}
-
-static struct saa7134_format* format_by_fourcc(unsigned int fourcc)
-{
- unsigned int i;
-
- for (i = 0; i < FORMATS; i++)
- if (formats[i].fourcc == fourcc)
- return formats+i;
- return NULL;
-}
-
-/* ----------------------------------------------------------------------- */
-/* resource management */
-
-static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bit)
-{
- if (fh->resources & bit)
- /* have it already allocated */
- return 1;
-
- /* is it free? */
- mutex_lock(&dev->lock);
- if (dev->resources & bit) {
- /* no, someone else uses it */
- mutex_unlock(&dev->lock);
- return 0;
- }
- /* it's free, grab it */
- fh->resources |= bit;
- dev->resources |= bit;
- dprintk("res: get %d\n",bit);
- mutex_unlock(&dev->lock);
- return 1;
-}
-
-static int res_check(struct saa7134_fh *fh, unsigned int bit)
-{
- return (fh->resources & bit);
-}
-
-static int res_locked(struct saa7134_dev *dev, unsigned int bit)
-{
- return (dev->resources & bit);
-}
-
-static
-void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
-{
- BUG_ON((fh->resources & bits) != bits);
-
- mutex_lock(&dev->lock);
- fh->resources &= ~bits;
- dev->resources &= ~bits;
- dprintk("res: put %d\n",bits);
- mutex_unlock(&dev->lock);
-}
-
-/* ------------------------------------------------------------------ */
-
-static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
-{
- dprintk("set tv norm = %s\n",norm->name);
- dev->tvnorm = norm;
-
- /* setup cropping */
- dev->crop_bounds.left = norm->h_start;
- dev->crop_defrect.left = norm->h_start;
- dev->crop_bounds.width = norm->h_stop - norm->h_start +1;
- dev->crop_defrect.width = norm->h_stop - norm->h_start +1;
-
- dev->crop_bounds.top = (norm->vbi_v_stop_0+1)*2;
- dev->crop_defrect.top = norm->video_v_start*2;
- dev->crop_bounds.height = ((norm->id & V4L2_STD_525_60) ? 524 : 624)
- - dev->crop_bounds.top;
- dev->crop_defrect.height = (norm->video_v_stop - norm->video_v_start +1)*2;
-
- dev->crop_current = dev->crop_defrect;
-
- saa7134_set_tvnorm_hw(dev);
-}
-
-static void video_mux(struct saa7134_dev *dev, int input)
-{
- dprintk("video input = %d [%s]\n", input, card_in(dev, input).name);
- dev->ctl_input = input;
- set_tvnorm(dev, dev->tvnorm);
- saa7134_tvaudio_setinput(dev, &card_in(dev, input));
-}
-
-
-static void saa7134_set_decoder(struct saa7134_dev *dev)
-{
- int luma_control, sync_control, mux;
-
- struct saa7134_tvnorm *norm = dev->tvnorm;
- mux = card_in(dev, dev->ctl_input).vmux;
-
- luma_control = norm->luma_control;
- sync_control = norm->sync_control;
-
- if (mux > 5)
- luma_control |= 0x80; /* svideo */
- if (noninterlaced || dev->nosignal)
- sync_control |= 0x20;
-
- /* setup video decoder */
- saa_writeb(SAA7134_INCR_DELAY, 0x08);
- saa_writeb(SAA7134_ANALOG_IN_CTRL1, 0xc0 | mux);
- saa_writeb(SAA7134_ANALOG_IN_CTRL2, 0x00);
-
- saa_writeb(SAA7134_ANALOG_IN_CTRL3, 0x90);
- saa_writeb(SAA7134_ANALOG_IN_CTRL4, 0x90);
- saa_writeb(SAA7134_HSYNC_START, 0xeb);
- saa_writeb(SAA7134_HSYNC_STOP, 0xe0);
- saa_writeb(SAA7134_SOURCE_TIMING1, norm->src_timing);
-
- saa_writeb(SAA7134_SYNC_CTRL, sync_control);
- saa_writeb(SAA7134_LUMA_CTRL, luma_control);
- saa_writeb(SAA7134_DEC_LUMA_BRIGHT, dev->ctl_bright);
-
- saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
- dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
-
- saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
- dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
-
- saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue);
- saa_writeb(SAA7134_CHROMA_CTRL1, norm->chroma_ctrl1);
- saa_writeb(SAA7134_CHROMA_GAIN, norm->chroma_gain);
-
- saa_writeb(SAA7134_CHROMA_CTRL2, norm->chroma_ctrl2);
- saa_writeb(SAA7134_MODE_DELAY_CTRL, 0x00);
-
- saa_writeb(SAA7134_ANALOG_ADC, 0x01);
- saa_writeb(SAA7134_VGATE_START, 0x11);
- saa_writeb(SAA7134_VGATE_STOP, 0xfe);
- saa_writeb(SAA7134_MISC_VGATE_MSB, norm->vgate_misc);
- saa_writeb(SAA7134_RAW_DATA_GAIN, 0x40);
- saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80);
-}
-
-void saa7134_set_tvnorm_hw(struct saa7134_dev *dev)
-{
- saa7134_set_decoder(dev);
-
- if (card_in(dev, dev->ctl_input).tv)
- saa_call_all(dev, core, s_std, dev->tvnorm->id);
- /* Set the correct norm for the saa6752hs. This function
- does nothing if there is no saa6752hs. */
- saa_call_empress(dev, core, s_std, dev->tvnorm->id);
-}
-
-static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
-{
- static const struct {
- int xpsc;
- int xacl;
- int xc2_1;
- int xdcg;
- int vpfy;
- } vals[] = {
- /* XPSC XACL XC2_1 XDCG VPFY */
- { 1, 0, 0, 0, 0 },
- { 2, 2, 1, 2, 2 },
- { 3, 4, 1, 3, 2 },
- { 4, 8, 1, 4, 2 },
- { 5, 8, 1, 4, 2 },
- { 6, 8, 1, 4, 3 },
- { 7, 8, 1, 4, 3 },
- { 8, 15, 0, 4, 3 },
- { 9, 15, 0, 4, 3 },
- { 10, 16, 1, 5, 3 },
- };
- static const int count = ARRAY_SIZE(vals);
- int i;
-
- for (i = 0; i < count; i++)
- if (vals[i].xpsc == prescale)
- break;
- if (i == count)
- return;
-
- saa_writeb(SAA7134_H_PRESCALE(task), vals[i].xpsc);
- saa_writeb(SAA7134_ACC_LENGTH(task), vals[i].xacl);
- saa_writeb(SAA7134_LEVEL_CTRL(task),
- (vals[i].xc2_1 << 3) | (vals[i].xdcg));
- saa_andorb(SAA7134_FIR_PREFILTER_CTRL(task), 0x0f,
- (vals[i].vpfy << 2) | vals[i].vpfy);
-}
-
-static void set_v_scale(struct saa7134_dev *dev, int task, int yscale)
-{
- int val,mirror;
-
- saa_writeb(SAA7134_V_SCALE_RATIO1(task), yscale & 0xff);
- saa_writeb(SAA7134_V_SCALE_RATIO2(task), yscale >> 8);
-
- mirror = (dev->ctl_mirror) ? 0x02 : 0x00;
- if (yscale < 2048) {
- /* LPI */
- dprintk("yscale LPI yscale=%d\n",yscale);
- saa_writeb(SAA7134_V_FILTER(task), 0x00 | mirror);
- saa_writeb(SAA7134_LUMA_CONTRAST(task), 0x40);
- saa_writeb(SAA7134_CHROMA_SATURATION(task), 0x40);
- } else {
- /* ACM */
- val = 0x40 * 1024 / yscale;
- dprintk("yscale ACM yscale=%d val=0x%x\n",yscale,val);
- saa_writeb(SAA7134_V_FILTER(task), 0x01 | mirror);
- saa_writeb(SAA7134_LUMA_CONTRAST(task), val);
- saa_writeb(SAA7134_CHROMA_SATURATION(task), val);
- }
- saa_writeb(SAA7134_LUMA_BRIGHT(task), 0x80);
-}
-
-static void set_size(struct saa7134_dev *dev, int task,
- int width, int height, int interlace)
-{
- int prescale,xscale,yscale,y_even,y_odd;
- int h_start, h_stop, v_start, v_stop;
- int div = interlace ? 2 : 1;
-
- /* setup video scaler */
- h_start = dev->crop_current.left;
- v_start = dev->crop_current.top/2;
- h_stop = (dev->crop_current.left + dev->crop_current.width -1);
- v_stop = (dev->crop_current.top + dev->crop_current.height -1)/2;
-
- saa_writeb(SAA7134_VIDEO_H_START1(task), h_start & 0xff);
- saa_writeb(SAA7134_VIDEO_H_START2(task), h_start >> 8);
- saa_writeb(SAA7134_VIDEO_H_STOP1(task), h_stop & 0xff);
- saa_writeb(SAA7134_VIDEO_H_STOP2(task), h_stop >> 8);
- saa_writeb(SAA7134_VIDEO_V_START1(task), v_start & 0xff);
- saa_writeb(SAA7134_VIDEO_V_START2(task), v_start >> 8);
- saa_writeb(SAA7134_VIDEO_V_STOP1(task), v_stop & 0xff);
- saa_writeb(SAA7134_VIDEO_V_STOP2(task), v_stop >> 8);
-
- prescale = dev->crop_current.width / width;
- if (0 == prescale)
- prescale = 1;
- xscale = 1024 * dev->crop_current.width / prescale / width;
- yscale = 512 * div * dev->crop_current.height / height;
- dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
- set_h_prescale(dev,task,prescale);
- saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff);
- saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8);
- set_v_scale(dev,task,yscale);
-
- saa_writeb(SAA7134_VIDEO_PIXELS1(task), width & 0xff);
- saa_writeb(SAA7134_VIDEO_PIXELS2(task), width >> 8);
- saa_writeb(SAA7134_VIDEO_LINES1(task), height/div & 0xff);
- saa_writeb(SAA7134_VIDEO_LINES2(task), height/div >> 8);
-
- /* deinterlace y offsets */
- y_odd = dev->ctl_y_odd;
- y_even = dev->ctl_y_even;
- saa_writeb(SAA7134_V_PHASE_OFFSET0(task), y_odd);
- saa_writeb(SAA7134_V_PHASE_OFFSET1(task), y_even);
- saa_writeb(SAA7134_V_PHASE_OFFSET2(task), y_odd);
- saa_writeb(SAA7134_V_PHASE_OFFSET3(task), y_even);
-}
-
-/* ------------------------------------------------------------------ */
-
-struct cliplist {
- __u16 position;
- __u8 enable;
- __u8 disable;
-};
-
-static void set_cliplist(struct saa7134_dev *dev, int reg,
- struct cliplist *cl, int entries, char *name)
-{
- __u8 winbits = 0;
- int i;
-
- for (i = 0; i < entries; i++) {
- winbits |= cl[i].enable;
- winbits &= ~cl[i].disable;
- if (i < 15 && cl[i].position == cl[i+1].position)
- continue;
- saa_writeb(reg + 0, winbits);
- saa_writeb(reg + 2, cl[i].position & 0xff);
- saa_writeb(reg + 3, cl[i].position >> 8);
- dprintk("clip: %s winbits=%02x pos=%d\n",
- name,winbits,cl[i].position);
- reg += 8;
- }
- for (; reg < 0x400; reg += 8) {
- saa_writeb(reg+ 0, 0);
- saa_writeb(reg + 1, 0);
- saa_writeb(reg + 2, 0);
- saa_writeb(reg + 3, 0);
- }
-}
-
-static int clip_range(int val)
-{
- if (val < 0)
- val = 0;
- return val;
-}
-
-/* Sort into smallest position first order */
-static int cliplist_cmp(const void *a, const void *b)
-{
- const struct cliplist *cla = a;
- const struct cliplist *clb = b;
- if (cla->position < clb->position)
- return -1;
- if (cla->position > clb->position)
- return 1;
- return 0;
-}
-
-static int setup_clipping(struct saa7134_dev *dev, struct v4l2_clip *clips,
- int nclips, int interlace)
-{
- struct cliplist col[16], row[16];
- int cols = 0, rows = 0, i;
- int div = interlace ? 2 : 1;
-
- memset(col, 0, sizeof(col));
- memset(row, 0, sizeof(row));
- for (i = 0; i < nclips && i < 8; i++) {
- col[cols].position = clip_range(clips[i].c.left);
- col[cols].enable = (1 << i);
- cols++;
- col[cols].position = clip_range(clips[i].c.left+clips[i].c.width);
- col[cols].disable = (1 << i);
- cols++;
- row[rows].position = clip_range(clips[i].c.top / div);
- row[rows].enable = (1 << i);
- rows++;
- row[rows].position = clip_range((clips[i].c.top + clips[i].c.height)
- / div);
- row[rows].disable = (1 << i);
- rows++;
- }
- sort(col, cols, sizeof col[0], cliplist_cmp, NULL);
- sort(row, rows, sizeof row[0], cliplist_cmp, NULL);
- set_cliplist(dev,0x380,col,cols,"cols");
- set_cliplist(dev,0x384,row,rows,"rows");
- return 0;
-}
-
-static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
-{
- enum v4l2_field field;
- int maxw, maxh;
-
- if (NULL == dev->ovbuf.base)
- return -EINVAL;
- if (NULL == dev->ovfmt)
- return -EINVAL;
- if (win->w.width < 48 || win->w.height < 32)
- return -EINVAL;
- if (win->clipcount > 2048)
- return -EINVAL;
-
- field = win->field;
- maxw = dev->crop_current.width;
- maxh = dev->crop_current.height;
-
- if (V4L2_FIELD_ANY == field) {
- field = (win->w.height > maxh/2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_TOP;
- }
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- break;
- default:
- return -EINVAL;
- }
-
- win->field = field;
- if (win->w.width > maxw)
- win->w.width = maxw;
- if (win->w.height > maxh)
- win->w.height = maxh;
- return 0;
-}
-
-static int start_preview(struct saa7134_dev *dev, struct saa7134_fh *fh)
-{
- unsigned long base,control,bpl;
- int err;
-
- err = verify_preview(dev,&fh->win);
- if (0 != err)
- return err;
-
- dev->ovfield = fh->win.field;
- dprintk("start_preview %dx%d+%d+%d %s field=%s\n",
- fh->win.w.width,fh->win.w.height,
- fh->win.w.left,fh->win.w.top,
- dev->ovfmt->name,v4l2_field_names[dev->ovfield]);
-
- /* setup window + clipping */
- set_size(dev,TASK_B,fh->win.w.width,fh->win.w.height,
- V4L2_FIELD_HAS_BOTH(dev->ovfield));
- setup_clipping(dev,fh->clips,fh->nclips,
- V4L2_FIELD_HAS_BOTH(dev->ovfield));
- if (dev->ovfmt->yuv)
- saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x03);
- else
- saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x01);
- saa_writeb(SAA7134_OFMT_VIDEO_B, dev->ovfmt->pm | 0x20);
-
- /* dma: setup channel 1 (= Video Task B) */
- base = (unsigned long)dev->ovbuf.base;
- base += dev->ovbuf.fmt.bytesperline * fh->win.w.top;
- base += dev->ovfmt->depth/8 * fh->win.w.left;
- bpl = dev->ovbuf.fmt.bytesperline;
- control = SAA7134_RS_CONTROL_BURST_16;
- if (dev->ovfmt->bswap)
- control |= SAA7134_RS_CONTROL_BSWAP;
- if (dev->ovfmt->wswap)
- control |= SAA7134_RS_CONTROL_WSWAP;
- if (V4L2_FIELD_HAS_BOTH(dev->ovfield)) {
- saa_writel(SAA7134_RS_BA1(1),base);
- saa_writel(SAA7134_RS_BA2(1),base+bpl);
- saa_writel(SAA7134_RS_PITCH(1),bpl*2);
- saa_writel(SAA7134_RS_CONTROL(1),control);
- } else {
- saa_writel(SAA7134_RS_BA1(1),base);
- saa_writel(SAA7134_RS_BA2(1),base);
- saa_writel(SAA7134_RS_PITCH(1),bpl);
- saa_writel(SAA7134_RS_CONTROL(1),control);
- }
-
- /* start dma */
- dev->ovenable = 1;
- saa7134_set_dmabits(dev);
-
- return 0;
-}
-
-static int stop_preview(struct saa7134_dev *dev, struct saa7134_fh *fh)
-{
- dev->ovenable = 0;
- saa7134_set_dmabits(dev);
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int buffer_activate(struct saa7134_dev *dev,
- struct saa7134_buf *buf,
- struct saa7134_buf *next)
-{
- unsigned long base,control,bpl;
- unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */
-
- dprintk("buffer_activate buf=%p\n",buf);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->top_seen = 0;
-
- set_size(dev,TASK_A,buf->vb.width,buf->vb.height,
- V4L2_FIELD_HAS_BOTH(buf->vb.field));
- if (buf->fmt->yuv)
- saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x03);
- else
- saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x01);
- saa_writeb(SAA7134_OFMT_VIDEO_A, buf->fmt->pm);
-
- /* DMA: setup channel 0 (= Video Task A0) */
- base = saa7134_buffer_base(buf);
- if (buf->fmt->planar)
- bpl = buf->vb.width;
- else
- bpl = (buf->vb.width * buf->fmt->depth) / 8;
- control = SAA7134_RS_CONTROL_BURST_16 |
- SAA7134_RS_CONTROL_ME |
- (buf->pt->dma >> 12);
- if (buf->fmt->bswap)
- control |= SAA7134_RS_CONTROL_BSWAP;
- if (buf->fmt->wswap)
- control |= SAA7134_RS_CONTROL_WSWAP;
- if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) {
- /* interlaced */
- saa_writel(SAA7134_RS_BA1(0),base);
- saa_writel(SAA7134_RS_BA2(0),base+bpl);
- saa_writel(SAA7134_RS_PITCH(0),bpl*2);
- } else {
- /* non-interlaced */
- saa_writel(SAA7134_RS_BA1(0),base);
- saa_writel(SAA7134_RS_BA2(0),base);
- saa_writel(SAA7134_RS_PITCH(0),bpl);
- }
- saa_writel(SAA7134_RS_CONTROL(0),control);
-
- if (buf->fmt->planar) {
- /* DMA: setup channel 4+5 (= planar task A) */
- bpl_uv = bpl >> buf->fmt->hshift;
- lines_uv = buf->vb.height >> buf->fmt->vshift;
- base2 = base + bpl * buf->vb.height;
- base3 = base2 + bpl_uv * lines_uv;
- if (buf->fmt->uvswap)
- tmp = base2, base2 = base3, base3 = tmp;
- dprintk("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n",
- bpl_uv,lines_uv,base2,base3);
- if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) {
- /* interlaced */
- saa_writel(SAA7134_RS_BA1(4),base2);
- saa_writel(SAA7134_RS_BA2(4),base2+bpl_uv);
- saa_writel(SAA7134_RS_PITCH(4),bpl_uv*2);
- saa_writel(SAA7134_RS_BA1(5),base3);
- saa_writel(SAA7134_RS_BA2(5),base3+bpl_uv);
- saa_writel(SAA7134_RS_PITCH(5),bpl_uv*2);
- } else {
- /* non-interlaced */
- saa_writel(SAA7134_RS_BA1(4),base2);
- saa_writel(SAA7134_RS_BA2(4),base2);
- saa_writel(SAA7134_RS_PITCH(4),bpl_uv);
- saa_writel(SAA7134_RS_BA1(5),base3);
- saa_writel(SAA7134_RS_BA2(5),base3);
- saa_writel(SAA7134_RS_PITCH(5),bpl_uv);
- }
- saa_writel(SAA7134_RS_CONTROL(4),control);
- saa_writel(SAA7134_RS_CONTROL(5),control);
- }
-
- /* start DMA */
- saa7134_set_dmabits(dev);
- mod_timer(&dev->video_q.timeout, jiffies+BUFFER_TIMEOUT);
- return 0;
-}
-
-static int buffer_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct saa7134_fh *fh = q->priv_data;
- struct saa7134_dev *dev = fh->dev;
- struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
- unsigned int size;
- int err;
-
- /* sanity checks */
- if (NULL == fh->fmt)
- return -EINVAL;
- if (fh->width < 48 ||
- fh->height < 32 ||
- fh->width/4 > dev->crop_current.width ||
- fh->height/4 > dev->crop_current.height ||
- fh->width > dev->crop_bounds.width ||
- fh->height > dev->crop_bounds.height)
- return -EINVAL;
- size = (fh->width * fh->height * fh->fmt->depth) >> 3;
- if (0 != buf->vb.baddr && buf->vb.bsize < size)
- return -EINVAL;
-
- dprintk("buffer_prepare [%d,size=%dx%d,bytes=%d,fields=%s,%s]\n",
- vb->i,fh->width,fh->height,size,v4l2_field_names[field],
- fh->fmt->name);
- if (buf->vb.width != fh->width ||
- buf->vb.height != fh->height ||
- buf->vb.size != size ||
- buf->vb.field != field ||
- buf->fmt != fh->fmt) {
- saa7134_dma_free(q,buf);
- }
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
-
- buf->vb.width = fh->width;
- buf->vb.height = fh->height;
- buf->vb.size = size;
- buf->vb.field = field;
- buf->fmt = fh->fmt;
- buf->pt = &fh->pt_cap;
- dev->video_q.curr = NULL;
-
- err = videobuf_iolock(q,&buf->vb,&dev->ovbuf);
- if (err)
- goto oops;
- err = saa7134_pgtable_build(dev->pci,buf->pt,
- dma->sglist,
- dma->sglen,
- saa7134_buffer_startpage(buf));
- if (err)
- goto oops;
- }
- buf->vb.state = VIDEOBUF_PREPARED;
- buf->activate = buffer_activate;
- return 0;
-
- oops:
- saa7134_dma_free(q,buf);
- return err;
-}
-
-static int
-buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
-{
- struct saa7134_fh *fh = q->priv_data;
-
- *size = fh->fmt->depth * fh->width * fh->height >> 3;
- if (0 == *count)
- *count = gbuffers;
- *count = saa7134_buffer_count(*size,*count);
- return 0;
-}
-
-static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct saa7134_fh *fh = q->priv_data;
- struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
-
- saa7134_buffer_queue(fh->dev,&fh->dev->video_q,buf);
-}
-
-static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
-
- saa7134_dma_free(q,buf);
-}
-
-static struct videobuf_queue_ops video_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-/* ------------------------------------------------------------------ */
-
-int saa7134_g_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c)
-{
- const struct v4l2_queryctrl* ctrl;
-
- ctrl = ctrl_by_id(c->id);
- if (NULL == ctrl)
- return -EINVAL;
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- c->value = dev->ctl_bright;
- break;
- case V4L2_CID_HUE:
- c->value = dev->ctl_hue;
- break;
- case V4L2_CID_CONTRAST:
- c->value = dev->ctl_contrast;
- break;
- case V4L2_CID_SATURATION:
- c->value = dev->ctl_saturation;
- break;
- case V4L2_CID_AUDIO_MUTE:
- c->value = dev->ctl_mute;
- break;
- case V4L2_CID_AUDIO_VOLUME:
- c->value = dev->ctl_volume;
- break;
- case V4L2_CID_PRIVATE_INVERT:
- c->value = dev->ctl_invert;
- break;
- case V4L2_CID_HFLIP:
- c->value = dev->ctl_mirror;
- break;
- case V4L2_CID_PRIVATE_Y_EVEN:
- c->value = dev->ctl_y_even;
- break;
- case V4L2_CID_PRIVATE_Y_ODD:
- c->value = dev->ctl_y_odd;
- break;
- case V4L2_CID_PRIVATE_AUTOMUTE:
- c->value = dev->ctl_automute;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(saa7134_g_ctrl_internal);
-
-static int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c)
-{
- struct saa7134_fh *fh = priv;
-
- return saa7134_g_ctrl_internal(fh->dev, fh, c);
-}
-
-int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c)
-{
- const struct v4l2_queryctrl* ctrl;
- unsigned long flags;
- int restart_overlay = 0;
- int err;
-
- /* When called from the empress code fh == NULL.
- That needs to be fixed somehow, but for now this is
- good enough. */
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
- err = -EINVAL;
-
- mutex_lock(&dev->lock);
-
- ctrl = ctrl_by_id(c->id);
- if (NULL == ctrl)
- goto error;
-
- dprintk("set_control name=%s val=%d\n",ctrl->name,c->value);
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_BOOLEAN:
- case V4L2_CTRL_TYPE_MENU:
- case V4L2_CTRL_TYPE_INTEGER:
- if (c->value < ctrl->minimum)
- c->value = ctrl->minimum;
- if (c->value > ctrl->maximum)
- c->value = ctrl->maximum;
- break;
- default:
- /* nothing */;
- };
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- dev->ctl_bright = c->value;
- saa_writeb(SAA7134_DEC_LUMA_BRIGHT, dev->ctl_bright);
- break;
- case V4L2_CID_HUE:
- dev->ctl_hue = c->value;
- saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue);
- break;
- case V4L2_CID_CONTRAST:
- dev->ctl_contrast = c->value;
- saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
- dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
- break;
- case V4L2_CID_SATURATION:
- dev->ctl_saturation = c->value;
- saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
- dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
- break;
- case V4L2_CID_AUDIO_MUTE:
- dev->ctl_mute = c->value;
- saa7134_tvaudio_setmute(dev);
- break;
- case V4L2_CID_AUDIO_VOLUME:
- dev->ctl_volume = c->value;
- saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
- break;
- case V4L2_CID_PRIVATE_INVERT:
- dev->ctl_invert = c->value;
- saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
- dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
- saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
- dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
- break;
- case V4L2_CID_HFLIP:
- dev->ctl_mirror = c->value;
- restart_overlay = 1;
- break;
- case V4L2_CID_PRIVATE_Y_EVEN:
- dev->ctl_y_even = c->value;
- restart_overlay = 1;
- break;
- case V4L2_CID_PRIVATE_Y_ODD:
- dev->ctl_y_odd = c->value;
- restart_overlay = 1;
- break;
- case V4L2_CID_PRIVATE_AUTOMUTE:
- {
- struct v4l2_priv_tun_config tda9887_cfg;
-
- tda9887_cfg.tuner = TUNER_TDA9887;
- tda9887_cfg.priv = &dev->tda9887_conf;
-
- dev->ctl_automute = c->value;
- if (dev->tda9887_conf) {
- if (dev->ctl_automute)
- dev->tda9887_conf |= TDA9887_AUTOMUTE;
- else
- dev->tda9887_conf &= ~TDA9887_AUTOMUTE;
-
- saa_call_all(dev, tuner, s_config, &tda9887_cfg);
- }
- break;
- }
- default:
- goto error;
- }
- if (restart_overlay && fh && res_check(fh, RESOURCE_OVERLAY)) {
- spin_lock_irqsave(&dev->slock,flags);
- stop_preview(dev,fh);
- start_preview(dev,fh);
- spin_unlock_irqrestore(&dev->slock,flags);
- }
- err = 0;
-
-error:
- mutex_unlock(&dev->lock);
- return err;
-}
-EXPORT_SYMBOL_GPL(saa7134_s_ctrl_internal);
-
-static int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c)
-{
- struct saa7134_fh *fh = f;
-
- return saa7134_s_ctrl_internal(fh->dev, fh, c);
-}
-
-/* ------------------------------------------------------------------ */
-
-static struct videobuf_queue* saa7134_queue(struct saa7134_fh *fh)
-{
- struct videobuf_queue* q = NULL;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- q = &fh->cap;
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- q = &fh->vbi;
- break;
- default:
- BUG();
- }
- return q;
-}
-
-static int saa7134_resource(struct saa7134_fh *fh)
-{
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return RESOURCE_VIDEO;
-
- if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
- return RESOURCE_VBI;
-
- BUG();
- return 0;
-}
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct saa7134_dev *dev = video_drvdata(file);
- struct saa7134_fh *fh;
- enum v4l2_buf_type type = 0;
- int radio = 0;
-
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- case VFL_TYPE_VBI:
- type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- case VFL_TYPE_RADIO:
- radio = 1;
- break;
- }
-
- dprintk("open dev=%s radio=%d type=%s\n", video_device_node_name(vdev),
- radio, v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh),GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- file->private_data = fh;
- fh->dev = dev;
- fh->radio = radio;
- fh->type = type;
- fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
- fh->width = 720;
- fh->height = 576;
- v4l2_prio_open(&dev->prio, &fh->prio);
-
- videobuf_queue_sg_init(&fh->cap, &video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct saa7134_buf),
- fh, NULL);
- videobuf_queue_sg_init(&fh->vbi, &saa7134_vbi_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VBI_CAPTURE,
- V4L2_FIELD_SEQ_TB,
- sizeof(struct saa7134_buf),
- fh, NULL);
- saa7134_pgtable_alloc(dev->pci,&fh->pt_cap);
- saa7134_pgtable_alloc(dev->pci,&fh->pt_vbi);
-
- if (fh->radio) {
- /* switch to radio mode */
- saa7134_tvaudio_setinput(dev,&card(dev).radio);
- saa_call_all(dev, tuner, s_radio);
- } else {
- /* switch to video/vbi mode */
- video_mux(dev,dev->ctl_input);
- }
- return 0;
-}
-
-static ssize_t
-video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
-{
- struct saa7134_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (res_locked(fh->dev,RESOURCE_VIDEO))
- return -EBUSY;
- return videobuf_read_one(saa7134_queue(fh),
- data, count, ppos,
- file->f_flags & O_NONBLOCK);
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (!res_get(fh->dev,fh,RESOURCE_VBI))
- return -EBUSY;
- return videobuf_read_stream(saa7134_queue(fh),
- data, count, ppos, 1,
- file->f_flags & O_NONBLOCK);
- break;
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int
-video_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct saa7134_fh *fh = file->private_data;
- struct videobuf_buffer *buf = NULL;
- unsigned int rc = 0;
-
- if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
- return videobuf_poll_stream(file, &fh->vbi, wait);
-
- if (res_check(fh,RESOURCE_VIDEO)) {
- mutex_lock(&fh->cap.vb_lock);
- if (!list_empty(&fh->cap.stream))
- buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
- } else {
- mutex_lock(&fh->cap.vb_lock);
- if (UNSET == fh->cap.read_off) {
- /* need to capture a new frame */
- if (res_locked(fh->dev,RESOURCE_VIDEO))
- goto err;
- if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field))
- goto err;
- fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
- fh->cap.read_off = 0;
- }
- buf = fh->cap.read_buf;
- }
-
- if (!buf)
- goto err;
-
- poll_wait(file, &buf->done, wait);
- if (buf->state == VIDEOBUF_DONE ||
- buf->state == VIDEOBUF_ERROR)
- rc = POLLIN|POLLRDNORM;
- mutex_unlock(&fh->cap.vb_lock);
- return rc;
-
-err:
- mutex_unlock(&fh->cap.vb_lock);
- return POLLERR;
-}
-
-static int video_release(struct file *file)
-{
- struct saa7134_fh *fh = file->private_data;
- struct saa7134_dev *dev = fh->dev;
- struct saa6588_command cmd;
- unsigned long flags;
-
- saa7134_tvaudio_close(dev);
-
- /* turn off overlay */
- if (res_check(fh, RESOURCE_OVERLAY)) {
- spin_lock_irqsave(&dev->slock,flags);
- stop_preview(dev,fh);
- spin_unlock_irqrestore(&dev->slock,flags);
- res_free(dev,fh,RESOURCE_OVERLAY);
- }
-
- /* stop video capture */
- if (res_check(fh, RESOURCE_VIDEO)) {
- videobuf_streamoff(&fh->cap);
- res_free(dev,fh,RESOURCE_VIDEO);
- }
- if (fh->cap.read_buf) {
- buffer_release(&fh->cap,fh->cap.read_buf);
- kfree(fh->cap.read_buf);
- }
-
- /* stop vbi capture */
- if (res_check(fh, RESOURCE_VBI)) {
- videobuf_stop(&fh->vbi);
- res_free(dev,fh,RESOURCE_VBI);
- }
-
- /* ts-capture will not work in planar mode, so turn it off Hac: 04.05*/
- saa_andorb(SAA7134_OFMT_VIDEO_A, 0x1f, 0);
- saa_andorb(SAA7134_OFMT_VIDEO_B, 0x1f, 0);
- saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
- saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
-
- saa_call_all(dev, core, s_power, 0);
- if (fh->radio)
- saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
-
- /* free stuff */
- videobuf_mmap_free(&fh->cap);
- videobuf_mmap_free(&fh->vbi);
- saa7134_pgtable_free(dev->pci,&fh->pt_cap);
- saa7134_pgtable_free(dev->pci,&fh->pt_vbi);
-
- v4l2_prio_close(&dev->prio, fh->prio);
- file->private_data = NULL;
- kfree(fh);
- return 0;
-}
-
-static int video_mmap(struct file *file, struct vm_area_struct * vma)
-{
- struct saa7134_fh *fh = file->private_data;
-
- return videobuf_mmap_mapper(saa7134_queue(fh), vma);
-}
-
-static ssize_t radio_read(struct file *file, char __user *data,
- size_t count, loff_t *ppos)
-{
- struct saa7134_fh *fh = file->private_data;
- struct saa7134_dev *dev = fh->dev;
- struct saa6588_command cmd;
-
- cmd.block_count = count/3;
- cmd.buffer = data;
- cmd.instance = file;
- cmd.result = -ENODEV;
-
- saa_call_all(dev, core, ioctl, SAA6588_CMD_READ, &cmd);
-
- return cmd.result;
-}
-
-static unsigned int radio_poll(struct file *file, poll_table *wait)
-{
- struct saa7134_fh *fh = file->private_data;
- struct saa7134_dev *dev = fh->dev;
- struct saa6588_command cmd;
-
- cmd.instance = file;
- cmd.event_list = wait;
- cmd.result = -ENODEV;
- saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd);
-
- return cmd.result;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
- struct saa7134_tvnorm *norm = dev->tvnorm;
-
- f->fmt.vbi.sampling_rate = 6750000 * 4;
- f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;
- f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
- f->fmt.vbi.offset = 64 * 4;
- f->fmt.vbi.start[0] = norm->vbi_v_start_0;
- f->fmt.vbi.count[0] = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1;
- f->fmt.vbi.start[1] = norm->vbi_v_start_1;
- f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
- f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */
-
- return 0;
-}
-
-static int saa7134_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7134_fh *fh = priv;
-
- f->fmt.pix.width = fh->width;
- f->fmt.pix.height = fh->height;
- f->fmt.pix.field = fh->cap.field;
- f->fmt.pix.pixelformat = fh->fmt->fourcc;
- f->fmt.pix.bytesperline =
- (f->fmt.pix.width * fh->fmt->depth) >> 3;
- f->fmt.pix.sizeimage =
- f->fmt.pix.height * f->fmt.pix.bytesperline;
- return 0;
-}
-
-static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7134_fh *fh = priv;
-
- if (saa7134_no_overlay > 0) {
- printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
- return -EINVAL;
- }
- f->fmt.win = fh->win;
-
- return 0;
-}
-
-static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
- struct saa7134_format *fmt;
- enum v4l2_field field;
- unsigned int maxw, maxh;
-
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- if (NULL == fmt)
- return -EINVAL;
-
- field = f->fmt.pix.field;
- maxw = min(dev->crop_current.width*4, dev->crop_bounds.width);
- maxh = min(dev->crop_current.height*4, dev->crop_bounds.height);
-
- if (V4L2_FIELD_ANY == field) {
- field = (f->fmt.pix.height > maxh/2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_BOTTOM;
- }
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- break;
- default:
- return -EINVAL;
- }
-
- f->fmt.pix.field = field;
- if (f->fmt.pix.width < 48)
- f->fmt.pix.width = 48;
- if (f->fmt.pix.height < 32)
- f->fmt.pix.height = 32;
- if (f->fmt.pix.width > maxw)
- f->fmt.pix.width = maxw;
- if (f->fmt.pix.height > maxh)
- f->fmt.pix.height = maxh;
- f->fmt.pix.width &= ~0x03;
- f->fmt.pix.bytesperline =
- (f->fmt.pix.width * fmt->depth) >> 3;
- f->fmt.pix.sizeimage =
- f->fmt.pix.height * f->fmt.pix.bytesperline;
-
- return 0;
-}
-
-static int saa7134_try_fmt_vid_overlay(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
-
- if (saa7134_no_overlay > 0) {
- printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
- return -EINVAL;
- }
-
- return verify_preview(dev, &f->fmt.win);
-}
-
-static int saa7134_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7134_fh *fh = priv;
- int err;
-
- err = saa7134_try_fmt_vid_cap(file, priv, f);
- if (0 != err)
- return err;
-
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->width = f->fmt.pix.width;
- fh->height = f->fmt.pix.height;
- fh->cap.field = f->fmt.pix.field;
- return 0;
-}
-
-static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
- int err;
- unsigned long flags;
-
- if (saa7134_no_overlay > 0) {
- printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
- return -EINVAL;
- }
- err = verify_preview(dev, &f->fmt.win);
- if (0 != err)
- return err;
-
- mutex_lock(&dev->lock);
-
- fh->win = f->fmt.win;
- fh->nclips = f->fmt.win.clipcount;
-
- if (fh->nclips > 8)
- fh->nclips = 8;
-
- if (copy_from_user(fh->clips, f->fmt.win.clips,
- sizeof(struct v4l2_clip)*fh->nclips)) {
- mutex_unlock(&dev->lock);
- return -EFAULT;
- }
-
- if (res_check(fh, RESOURCE_OVERLAY)) {
- spin_lock_irqsave(&dev->slock, flags);
- stop_preview(dev, fh);
- start_preview(dev, fh);
- spin_unlock_irqrestore(&dev->slock, flags);
- }
-
- mutex_unlock(&dev->lock);
- return 0;
-}
-
-int saa7134_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c)
-{
- const struct v4l2_queryctrl *ctrl;
-
- if ((c->id < V4L2_CID_BASE ||
- c->id >= V4L2_CID_LASTP1) &&
- (c->id < V4L2_CID_PRIVATE_BASE ||
- c->id >= V4L2_CID_PRIVATE_LASTP1))
- return -EINVAL;
- ctrl = ctrl_by_id(c->id);
- *c = (NULL != ctrl) ? *ctrl : no_ctrl;
- return 0;
-}
-EXPORT_SYMBOL_GPL(saa7134_queryctrl);
-
-static int saa7134_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
- unsigned int n;
-
- n = i->index;
- if (n >= SAA7134_INPUT_MAX)
- return -EINVAL;
- if (NULL == card_in(dev, i->index).name)
- return -EINVAL;
- i->index = n;
- i->type = V4L2_INPUT_TYPE_CAMERA;
- strcpy(i->name, card_in(dev, n).name);
- if (card_in(dev, n).tv)
- i->type = V4L2_INPUT_TYPE_TUNER;
- i->audioset = 1;
- if (n == dev->ctl_input) {
- int v1 = saa_readb(SAA7134_STATUS_VIDEO1);
- int v2 = saa_readb(SAA7134_STATUS_VIDEO2);
-
- if (0 != (v1 & 0x40))
- i->status |= V4L2_IN_ST_NO_H_LOCK;
- if (0 != (v2 & 0x40))
- i->status |= V4L2_IN_ST_NO_SYNC;
- if (0 != (v2 & 0x0e))
- i->status |= V4L2_IN_ST_MACROVISION;
- }
- i->std = SAA7134_NORMS;
- return 0;
-}
-
-static int saa7134_g_input(struct file *file, void *priv, unsigned int *i)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
-
- *i = dev->ctl_input;
- return 0;
-}
-
-static int saa7134_s_input(struct file *file, void *priv, unsigned int i)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
- int err;
-
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
-
- if (i >= SAA7134_INPUT_MAX)
- return -EINVAL;
- if (NULL == card_in(dev, i).name)
- return -EINVAL;
- mutex_lock(&dev->lock);
- video_mux(dev, i);
- mutex_unlock(&dev->lock);
- return 0;
-}
-
-static int saa7134_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
-
- unsigned int tuner_type = dev->tuner_type;
-
- strcpy(cap->driver, "saa7134");
- strlcpy(cap->card, saa7134_boards[dev->board].name,
- sizeof(cap->card));
- sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
- cap->capabilities =
- V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_VBI_CAPTURE |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING |
- V4L2_CAP_TUNER;
- if (dev->has_rds)
- cap->capabilities |= V4L2_CAP_RDS_CAPTURE;
- if (saa7134_no_overlay <= 0)
- cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
-
- if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET))
- cap->capabilities &= ~V4L2_CAP_TUNER;
- return 0;
-}
-
-int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id *id)
-{
- unsigned long flags;
- unsigned int i;
- v4l2_std_id fixup;
- int err;
-
- /* When called from the empress code fh == NULL.
- That needs to be fixed somehow, but for now this is
- good enough. */
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- } else if (res_locked(dev, RESOURCE_OVERLAY)) {
- /* Don't change the std from the mpeg device
- if overlay is active. */
- return -EBUSY;
- }
-
- for (i = 0; i < TVNORMS; i++)
- if (*id == tvnorms[i].id)
- break;
-
- if (i == TVNORMS)
- for (i = 0; i < TVNORMS; i++)
- if (*id & tvnorms[i].id)
- break;
- if (i == TVNORMS)
- return -EINVAL;
-
- if ((*id & V4L2_STD_SECAM) && (secam[0] != '-')) {
- if (secam[0] == 'L' || secam[0] == 'l') {
- if (secam[1] == 'C' || secam[1] == 'c')
- fixup = V4L2_STD_SECAM_LC;
- else
- fixup = V4L2_STD_SECAM_L;
- } else {
- if (secam[0] == 'D' || secam[0] == 'd')
- fixup = V4L2_STD_SECAM_DK;
- else
- fixup = V4L2_STD_SECAM;
- }
- for (i = 0; i < TVNORMS; i++) {
- if (fixup == tvnorms[i].id)
- break;
- }
- if (i == TVNORMS)
- return -EINVAL;
- }
-
- *id = tvnorms[i].id;
-
- mutex_lock(&dev->lock);
- if (fh && res_check(fh, RESOURCE_OVERLAY)) {
- spin_lock_irqsave(&dev->slock, flags);
- stop_preview(dev, fh);
- spin_unlock_irqrestore(&dev->slock, flags);
-
- set_tvnorm(dev, &tvnorms[i]);
-
- spin_lock_irqsave(&dev->slock, flags);
- start_preview(dev, fh);
- spin_unlock_irqrestore(&dev->slock, flags);
- } else
- set_tvnorm(dev, &tvnorms[i]);
-
- saa7134_tvaudio_do_scan(dev);
- mutex_unlock(&dev->lock);
- return 0;
-}
-EXPORT_SYMBOL_GPL(saa7134_s_std_internal);
-
-static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id)
-{
- struct saa7134_fh *fh = priv;
-
- return saa7134_s_std_internal(fh->dev, fh, id);
-}
-
-static int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
-
- *id = dev->tvnorm->id;
- return 0;
-}
-
-static int saa7134_cropcap(struct file *file, void *priv,
- struct v4l2_cropcap *cap)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
-
- if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
- cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
- return -EINVAL;
- cap->bounds = dev->crop_bounds;
- cap->defrect = dev->crop_defrect;
- cap->pixelaspect.numerator = 1;
- cap->pixelaspect.denominator = 1;
- if (dev->tvnorm->id & V4L2_STD_525_60) {
- cap->pixelaspect.numerator = 11;
- cap->pixelaspect.denominator = 10;
- }
- if (dev->tvnorm->id & V4L2_STD_625_50) {
- cap->pixelaspect.numerator = 54;
- cap->pixelaspect.denominator = 59;
- }
- return 0;
-}
-
-static int saa7134_g_crop(struct file *file, void *f, struct v4l2_crop *crop)
-{
- struct saa7134_fh *fh = f;
- struct saa7134_dev *dev = fh->dev;
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
- crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
- return -EINVAL;
- crop->c = dev->crop_current;
- return 0;
-}
-
-static int saa7134_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
-{
- struct saa7134_fh *fh = f;
- struct saa7134_dev *dev = fh->dev;
- struct v4l2_rect *b = &dev->crop_bounds;
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
- crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
- return -EINVAL;
- if (crop->c.height < 0)
- return -EINVAL;
- if (crop->c.width < 0)
- return -EINVAL;
-
- if (res_locked(fh->dev, RESOURCE_OVERLAY))
- return -EBUSY;
- if (res_locked(fh->dev, RESOURCE_VIDEO))
- return -EBUSY;
-
- if (crop->c.top < b->top)
- crop->c.top = b->top;
- if (crop->c.top > b->top + b->height)
- crop->c.top = b->top + b->height;
- if (crop->c.height > b->top - crop->c.top + b->height)
- crop->c.height = b->top - crop->c.top + b->height;
-
- if (crop->c.left < b->left)
- crop->c.left = b->left;
- if (crop->c.left > b->left + b->width)
- crop->c.left = b->left + b->width;
- if (crop->c.width > b->left - crop->c.left + b->width)
- crop->c.width = b->left - crop->c.left + b->width;
-
- dev->crop_current = crop->c;
- return 0;
-}
-
-static int saa7134_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
- int n;
-
- if (0 != t->index)
- return -EINVAL;
- memset(t, 0, sizeof(*t));
- for (n = 0; n < SAA7134_INPUT_MAX; n++) {
- if (card_in(dev, n).tv)
- break;
- }
- if (n == SAA7134_INPUT_MAX)
- return -EINVAL;
- if (NULL != card_in(dev, n).name) {
- strcpy(t->name, "Television");
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM |
- V4L2_TUNER_CAP_STEREO |
- V4L2_TUNER_CAP_LANG1 |
- V4L2_TUNER_CAP_LANG2;
- t->rangehigh = 0xffffffffUL;
- t->rxsubchans = saa7134_tvaudio_getstereo(dev);
- t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans);
- }
- if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03))
- t->signal = 0xffff;
- return 0;
-}
-
-static int saa7134_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
- int rx, mode, err;
-
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
-
- mode = dev->thread.mode;
- if (UNSET == mode) {
- rx = saa7134_tvaudio_getstereo(dev);
- mode = saa7134_tvaudio_rx2mode(rx);
- }
- if (mode != t->audmode)
- dev->thread.mode = t->audmode;
-
- return 0;
-}
-
-static int saa7134_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
-
- f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- f->frequency = dev->ctl_freq;
-
- return 0;
-}
-
-static int saa7134_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
- int err;
-
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
-
- if (0 != f->tuner)
- return -EINVAL;
- if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
- return -EINVAL;
- if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
- return -EINVAL;
- mutex_lock(&dev->lock);
- dev->ctl_freq = f->frequency;
-
- saa_call_all(dev, tuner, s_frequency, f);
-
- saa7134_tvaudio_do_scan(dev);
- mutex_unlock(&dev->lock);
- return 0;
-}
-
-static int saa7134_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- strcpy(a->name, "audio");
- return 0;
-}
-
-static int saa7134_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- return 0;
-}
-
-static int saa7134_g_priority(struct file *file, void *f, enum v4l2_priority *p)
-{
- struct saa7134_fh *fh = f;
- struct saa7134_dev *dev = fh->dev;
-
- *p = v4l2_prio_max(&dev->prio);
- return 0;
-}
-
-static int saa7134_s_priority(struct file *file, void *f,
- enum v4l2_priority prio)
-{
- struct saa7134_fh *fh = f;
- struct saa7134_dev *dev = fh->dev;
-
- return v4l2_prio_change(&dev->prio, &fh->prio, prio);
-}
-
-static int saa7134_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (f->index >= FORMATS)
- return -EINVAL;
-
- strlcpy(f->description, formats[f->index].name,
- sizeof(f->description));
-
- f->pixelformat = formats[f->index].fourcc;
-
- return 0;
-}
-
-static int saa7134_enum_fmt_vid_overlay(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (saa7134_no_overlay > 0) {
- printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
- return -EINVAL;
- }
-
- if ((f->index >= FORMATS) || formats[f->index].planar)
- return -EINVAL;
-
- strlcpy(f->description, formats[f->index].name,
- sizeof(f->description));
-
- f->pixelformat = formats[f->index].fourcc;
-
- return 0;
-}
-
-static int saa7134_g_fbuf(struct file *file, void *f,
- struct v4l2_framebuffer *fb)
-{
- struct saa7134_fh *fh = f;
- struct saa7134_dev *dev = fh->dev;
-
- *fb = dev->ovbuf;
- fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
-
- return 0;
-}
-
-static int saa7134_s_fbuf(struct file *file, void *f,
- struct v4l2_framebuffer *fb)
-{
- struct saa7134_fh *fh = f;
- struct saa7134_dev *dev = fh->dev;
- struct saa7134_format *fmt;
-
- if (!capable(CAP_SYS_ADMIN) &&
- !capable(CAP_SYS_RAWIO))
- return -EPERM;
-
- /* check args */
- fmt = format_by_fourcc(fb->fmt.pixelformat);
- if (NULL == fmt)
- return -EINVAL;
-
- /* ok, accept it */
- dev->ovbuf = *fb;
- dev->ovfmt = fmt;
- if (0 == dev->ovbuf.fmt.bytesperline)
- dev->ovbuf.fmt.bytesperline =
- dev->ovbuf.fmt.width*fmt->depth/8;
- return 0;
-}
-
-static int saa7134_overlay(struct file *file, void *f, unsigned int on)
-{
- struct saa7134_fh *fh = f;
- struct saa7134_dev *dev = fh->dev;
- unsigned long flags;
-
- if (on) {
- if (saa7134_no_overlay > 0) {
- dprintk("no_overlay\n");
- return -EINVAL;
- }
-
- if (!res_get(dev, fh, RESOURCE_OVERLAY))
- return -EBUSY;
- spin_lock_irqsave(&dev->slock, flags);
- start_preview(dev, fh);
- spin_unlock_irqrestore(&dev->slock, flags);
- }
- if (!on) {
- if (!res_check(fh, RESOURCE_OVERLAY))
- return -EINVAL;
- spin_lock_irqsave(&dev->slock, flags);
- stop_preview(dev, fh);
- spin_unlock_irqrestore(&dev->slock, flags);
- res_free(dev, fh, RESOURCE_OVERLAY);
- }
- return 0;
-}
-
-static int saa7134_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct saa7134_fh *fh = priv;
- return videobuf_reqbufs(saa7134_queue(fh), p);
-}
-
-static int saa7134_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct saa7134_fh *fh = priv;
- return videobuf_querybuf(saa7134_queue(fh), b);
-}
-
-static int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct saa7134_fh *fh = priv;
- return videobuf_qbuf(saa7134_queue(fh), b);
-}
-
-static int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct saa7134_fh *fh = priv;
- return videobuf_dqbuf(saa7134_queue(fh), b,
- file->f_flags & O_NONBLOCK);
-}
-
-static int saa7134_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
- int res = saa7134_resource(fh);
-
- if (!res_get(dev, fh, res))
- return -EBUSY;
-
- return videobuf_streamon(saa7134_queue(fh));
-}
-
-static int saa7134_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- int err;
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
- int res = saa7134_resource(fh);
-
- err = videobuf_streamoff(saa7134_queue(fh));
- if (err < 0)
- return err;
- res_free(dev, fh, res);
- return 0;
-}
-
-static int saa7134_g_parm(struct file *file, void *fh,
- struct v4l2_streamparm *parm)
-{
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vidioc_g_register (struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
-
- if (!v4l2_chip_match_host(&reg->match))
- return -EINVAL;
- reg->val = saa_readb(reg->reg);
- reg->size = 1;
- return 0;
-}
-
-static int vidioc_s_register (struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
-
- if (!v4l2_chip_match_host(&reg->match))
- return -EINVAL;
- saa_writeb(reg->reg&0xffffff, reg->val);
- return 0;
-}
-#endif
-
-static int radio_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct saa7134_fh *fh = file->private_data;
- struct saa7134_dev *dev = fh->dev;
-
- strcpy(cap->driver, "saa7134");
- strlcpy(cap->card, saa7134_boards[dev->board].name, sizeof(cap->card));
- sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
- cap->capabilities = V4L2_CAP_TUNER;
- return 0;
-}
-
-static int radio_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct saa7134_fh *fh = file->private_data;
- struct saa7134_dev *dev = fh->dev;
-
- if (0 != t->index)
- return -EINVAL;
-
- memset(t, 0, sizeof(*t));
- strcpy(t->name, "Radio");
- t->type = V4L2_TUNER_RADIO;
-
- saa_call_all(dev, tuner, g_tuner, t);
- if (dev->input->amux == TV) {
- t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11);
- t->rxsubchans = (saa_readb(0x529) & 0x08) ?
- V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
- }
- return 0;
-}
-static int radio_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct saa7134_fh *fh = file->private_data;
- struct saa7134_dev *dev = fh->dev;
-
- if (0 != t->index)
- return -EINVAL;
-
- saa_call_all(dev, tuner, s_tuner, t);
- return 0;
-}
-
-static int radio_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- if (i->index != 0)
- return -EINVAL;
-
- strcpy(i->name, "Radio");
- i->type = V4L2_INPUT_TYPE_TUNER;
-
- return 0;
-}
-
-static int radio_g_input(struct file *filp, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int radio_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- memset(a, 0, sizeof(*a));
- strcpy(a->name, "Radio");
- return 0;
-}
-
-static int radio_s_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- return 0;
-}
-
-static int radio_s_input(struct file *filp, void *priv, unsigned int i)
-{
- return 0;
-}
-
-static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm)
-{
- return 0;
-}
-
-static int radio_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *c)
-{
- const struct v4l2_queryctrl *ctrl;
-
- if (c->id < V4L2_CID_BASE ||
- c->id >= V4L2_CID_LASTP1)
- return -EINVAL;
- if (c->id == V4L2_CID_AUDIO_MUTE) {
- ctrl = ctrl_by_id(c->id);
- *c = *ctrl;
- } else
- *c = no_ctrl;
- return 0;
-}
-
-static const struct v4l2_file_operations video_fops =
-{
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = video_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = saa7134_querycap,
- .vidioc_enum_fmt_vid_cap = saa7134_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = saa7134_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = saa7134_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = saa7134_s_fmt_vid_cap,
- .vidioc_enum_fmt_vid_overlay = saa7134_enum_fmt_vid_overlay,
- .vidioc_g_fmt_vid_overlay = saa7134_g_fmt_vid_overlay,
- .vidioc_try_fmt_vid_overlay = saa7134_try_fmt_vid_overlay,
- .vidioc_s_fmt_vid_overlay = saa7134_s_fmt_vid_overlay,
- .vidioc_g_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap,
- .vidioc_try_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap,
- .vidioc_s_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap,
- .vidioc_g_audio = saa7134_g_audio,
- .vidioc_s_audio = saa7134_s_audio,
- .vidioc_cropcap = saa7134_cropcap,
- .vidioc_reqbufs = saa7134_reqbufs,
- .vidioc_querybuf = saa7134_querybuf,
- .vidioc_qbuf = saa7134_qbuf,
- .vidioc_dqbuf = saa7134_dqbuf,
- .vidioc_s_std = saa7134_s_std,
- .vidioc_g_std = saa7134_g_std,
- .vidioc_enum_input = saa7134_enum_input,
- .vidioc_g_input = saa7134_g_input,
- .vidioc_s_input = saa7134_s_input,
- .vidioc_queryctrl = saa7134_queryctrl,
- .vidioc_g_ctrl = saa7134_g_ctrl,
- .vidioc_s_ctrl = saa7134_s_ctrl,
- .vidioc_streamon = saa7134_streamon,
- .vidioc_streamoff = saa7134_streamoff,
- .vidioc_g_tuner = saa7134_g_tuner,
- .vidioc_s_tuner = saa7134_s_tuner,
- .vidioc_g_crop = saa7134_g_crop,
- .vidioc_s_crop = saa7134_s_crop,
- .vidioc_g_fbuf = saa7134_g_fbuf,
- .vidioc_s_fbuf = saa7134_s_fbuf,
- .vidioc_overlay = saa7134_overlay,
- .vidioc_g_priority = saa7134_g_priority,
- .vidioc_s_priority = saa7134_s_priority,
- .vidioc_g_parm = saa7134_g_parm,
- .vidioc_g_frequency = saa7134_g_frequency,
- .vidioc_s_frequency = saa7134_s_frequency,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vidioc_g_register,
- .vidioc_s_register = vidioc_s_register,
-#endif
-};
-
-static const struct v4l2_file_operations radio_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .read = radio_read,
- .release = video_release,
- .ioctl = video_ioctl2,
- .poll = radio_poll,
-};
-
-static const struct v4l2_ioctl_ops radio_ioctl_ops = {
- .vidioc_querycap = radio_querycap,
- .vidioc_g_tuner = radio_g_tuner,
- .vidioc_enum_input = radio_enum_input,
- .vidioc_g_audio = radio_g_audio,
- .vidioc_s_tuner = radio_s_tuner,
- .vidioc_s_audio = radio_s_audio,
- .vidioc_s_input = radio_s_input,
- .vidioc_s_std = radio_s_std,
- .vidioc_queryctrl = radio_queryctrl,
- .vidioc_g_input = radio_g_input,
- .vidioc_g_ctrl = saa7134_g_ctrl,
- .vidioc_s_ctrl = saa7134_s_ctrl,
- .vidioc_g_frequency = saa7134_g_frequency,
- .vidioc_s_frequency = saa7134_s_frequency,
-};
-
-/* ----------------------------------------------------------- */
-/* exported stuff */
-
-struct video_device saa7134_video_template = {
- .name = "saa7134-video",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = SAA7134_NORMS,
- .current_norm = V4L2_STD_PAL,
-};
-
-struct video_device saa7134_radio_template = {
- .name = "saa7134-radio",
- .fops = &radio_fops,
- .ioctl_ops = &radio_ioctl_ops,
-};
-
-int saa7134_video_init1(struct saa7134_dev *dev)
-{
- /* sanitycheck insmod options */
- if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
- gbuffers = 2;
- if (gbufsize < 0 || gbufsize > gbufsize_max)
- gbufsize = gbufsize_max;
- gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
-
- /* put some sensible defaults into the data structures ... */
- dev->ctl_bright = ctrl_by_id(V4L2_CID_BRIGHTNESS)->default_value;
- dev->ctl_contrast = ctrl_by_id(V4L2_CID_CONTRAST)->default_value;
- dev->ctl_hue = ctrl_by_id(V4L2_CID_HUE)->default_value;
- dev->ctl_saturation = ctrl_by_id(V4L2_CID_SATURATION)->default_value;
- dev->ctl_volume = ctrl_by_id(V4L2_CID_AUDIO_VOLUME)->default_value;
- dev->ctl_mute = 1; // ctrl_by_id(V4L2_CID_AUDIO_MUTE)->default_value;
- dev->ctl_invert = ctrl_by_id(V4L2_CID_PRIVATE_INVERT)->default_value;
- dev->ctl_automute = ctrl_by_id(V4L2_CID_PRIVATE_AUTOMUTE)->default_value;
-
- if (dev->tda9887_conf && dev->ctl_automute)
- dev->tda9887_conf |= TDA9887_AUTOMUTE;
- dev->automute = 0;
-
- INIT_LIST_HEAD(&dev->video_q.queue);
- init_timer(&dev->video_q.timeout);
- dev->video_q.timeout.function = saa7134_buffer_timeout;
- dev->video_q.timeout.data = (unsigned long)(&dev->video_q);
- dev->video_q.dev = dev;
-
- if (saa7134_boards[dev->board].video_out)
- saa7134_videoport_init(dev);
-
- return 0;
-}
-
-int saa7134_videoport_init(struct saa7134_dev *dev)
-{
- /* enable video output */
- int vo = saa7134_boards[dev->board].video_out;
- int video_reg;
- unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts;
-
- /* Configure videoport */
- saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
- video_reg = video_out[vo][1];
- if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED)
- video_reg &= ~VP_T_CODE_P_INVERTED;
- saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg);
- saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
- saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
- video_reg = video_out[vo][5];
- if (vid_port_opts & SET_CLOCK_NOT_DELAYED)
- video_reg &= ~VP_CLK_CTRL2_DELAYED;
- if (vid_port_opts & SET_CLOCK_INVERTED)
- video_reg |= VP_CLK_CTRL1_INVERTED;
- saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_reg);
- video_reg = video_out[vo][6];
- if (vid_port_opts & SET_VSYNC_OFF) {
- video_reg &= ~VP_VS_TYPE_MASK;
- video_reg |= VP_VS_TYPE_OFF;
- }
- saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_reg);
- saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
- saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
-
- /* Start videoport */
- saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
-
- return 0;
-}
-
-int saa7134_video_init2(struct saa7134_dev *dev)
-{
- /* init video hw */
- set_tvnorm(dev,&tvnorms[0]);
- video_mux(dev,0);
- saa7134_tvaudio_setmute(dev);
- saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
- return 0;
-}
-
-void saa7134_irq_video_signalchange(struct saa7134_dev *dev)
-{
- static const char *st[] = {
- "(no signal)", "NTSC", "PAL", "SECAM" };
- u32 st1,st2;
-
- st1 = saa_readb(SAA7134_STATUS_VIDEO1);
- st2 = saa_readb(SAA7134_STATUS_VIDEO2);
- dprintk("DCSDT: pll: %s, sync: %s, norm: %s\n",
- (st1 & 0x40) ? "not locked" : "locked",
- (st2 & 0x40) ? "no" : "yes",
- st[st1 & 0x03]);
- dev->nosignal = (st1 & 0x40) || (st2 & 0x40) || !(st2 & 0x1);
-
- if (dev->nosignal) {
- /* no video signal -> mute audio */
- if (dev->ctl_automute)
- dev->automute = 1;
- saa7134_tvaudio_setmute(dev);
- } else {
- /* wake up tvaudio audio carrier scan thread */
- saa7134_tvaudio_do_scan(dev);
- }
-
- if ((st2 & 0x80) && !noninterlaced && !dev->nosignal)
- saa_clearb(SAA7134_SYNC_CTRL, 0x20);
- else
- saa_setb(SAA7134_SYNC_CTRL, 0x20);
-
- if (dev->mops && dev->mops->signal_change)
- dev->mops->signal_change(dev);
-}
-
-
-void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)
-{
- enum v4l2_field field;
-
- spin_lock(&dev->slock);
- if (dev->video_q.curr) {
- dev->video_fieldcount++;
- field = dev->video_q.curr->vb.field;
- if (V4L2_FIELD_HAS_BOTH(field)) {
- /* make sure we have seen both fields */
- if ((status & 0x10) == 0x00) {
- dev->video_q.curr->top_seen = 1;
- goto done;
- }
- if (!dev->video_q.curr->top_seen)
- goto done;
- } else if (field == V4L2_FIELD_TOP) {
- if ((status & 0x10) != 0x10)
- goto done;
- } else if (field == V4L2_FIELD_BOTTOM) {
- if ((status & 0x10) != 0x00)
- goto done;
- }
- dev->video_q.curr->vb.field_count = dev->video_fieldcount;
- saa7134_buffer_finish(dev,&dev->video_q,VIDEOBUF_DONE);
- }
- saa7134_buffer_next(dev,&dev->video_q);
-
- done:
- spin_unlock(&dev->slock);
-}
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
deleted file mode 100644
index 89c8333736a..00000000000
--- a/drivers/media/video/saa7134/saa7134.h
+++ /dev/null
@@ -1,856 +0,0 @@
-/*
- *
- * v4l2 device driver for philips saa7134 based TV cards
- *
- * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define SAA7134_VERSION "0, 2, 17"
-
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/kdev_t.h>
-#include <linux/input.h>
-#include <linux/notifier.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-
-#include <asm/io.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <media/tuner.h>
-#include <media/rc-core.h>
-#include <media/ir-kbd-i2c.h>
-#include <media/videobuf-dma-sg.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE)
-#include <media/videobuf-dvb.h>
-#endif
-
-#define UNSET (-1U)
-
-/* ----------------------------------------------------------- */
-/* enums */
-
-enum saa7134_tvaudio_mode {
- TVAUDIO_FM_MONO = 1,
- TVAUDIO_FM_BG_STEREO = 2,
- TVAUDIO_FM_SAT_STEREO = 3,
- TVAUDIO_FM_K_STEREO = 4,
- TVAUDIO_NICAM_AM = 5,
- TVAUDIO_NICAM_FM = 6,
-};
-
-enum saa7134_audio_in {
- TV = 1,
- LINE1 = 2,
- LINE2 = 3,
- LINE2_LEFT,
-};
-
-enum saa7134_video_out {
- CCIR656 = 1,
-};
-
-/* ----------------------------------------------------------- */
-/* static data */
-
-struct saa7134_tvnorm {
- char *name;
- v4l2_std_id id;
-
- /* video decoder */
- unsigned int sync_control;
- unsigned int luma_control;
- unsigned int chroma_ctrl1;
- unsigned int chroma_gain;
- unsigned int chroma_ctrl2;
- unsigned int vgate_misc;
-
- /* video scaler */
- unsigned int h_start;
- unsigned int h_stop;
- unsigned int video_v_start;
- unsigned int video_v_stop;
- unsigned int vbi_v_start_0;
- unsigned int vbi_v_stop_0;
- unsigned int src_timing;
- unsigned int vbi_v_start_1;
-};
-
-struct saa7134_tvaudio {
- char *name;
- v4l2_std_id std;
- enum saa7134_tvaudio_mode mode;
- int carr1;
- int carr2;
-};
-
-struct saa7134_format {
- char *name;
- unsigned int fourcc;
- unsigned int depth;
- unsigned int pm;
- unsigned int vshift; /* vertical downsampling (for planar yuv) */
- unsigned int hshift; /* horizontal downsampling (for planar yuv) */
- unsigned int bswap:1;
- unsigned int wswap:1;
- unsigned int yuv:1;
- unsigned int planar:1;
- unsigned int uvswap:1;
-};
-
-struct saa7134_card_ir {
- struct rc_dev *dev;
-
- char name[32];
- char phys[32];
- unsigned users;
-
- u32 polling;
- u32 last_gpio;
- u32 mask_keycode, mask_keydown, mask_keyup;
-
- bool running;
- bool active;
-
- struct timer_list timer;
-
- /* IR core raw decoding */
- u32 raw_decode;
-};
-
-/* ----------------------------------------------------------- */
-/* card configuration */
-
-#define SAA7134_BOARD_NOAUTO UNSET
-#define SAA7134_BOARD_UNKNOWN 0
-#define SAA7134_BOARD_PROTEUS_PRO 1
-#define SAA7134_BOARD_FLYVIDEO3000 2
-#define SAA7134_BOARD_FLYVIDEO2000 3
-#define SAA7134_BOARD_EMPRESS 4
-#define SAA7134_BOARD_MONSTERTV 5
-#define SAA7134_BOARD_MD9717 6
-#define SAA7134_BOARD_TVSTATION_RDS 7
-#define SAA7134_BOARD_CINERGY400 8
-#define SAA7134_BOARD_MD5044 9
-#define SAA7134_BOARD_KWORLD 10
-#define SAA7134_BOARD_CINERGY600 11
-#define SAA7134_BOARD_MD7134 12
-#define SAA7134_BOARD_TYPHOON_90031 13
-#define SAA7134_BOARD_ELSA 14
-#define SAA7134_BOARD_ELSA_500TV 15
-#define SAA7134_BOARD_ASUSTeK_TVFM7134 16
-#define SAA7134_BOARD_VA1000POWER 17
-#define SAA7134_BOARD_BMK_MPEX_NOTUNER 18
-#define SAA7134_BOARD_VIDEOMATE_TV 19
-#define SAA7134_BOARD_CRONOS_PLUS 20
-#define SAA7134_BOARD_10MOONSTVMASTER 21
-#define SAA7134_BOARD_MD2819 22
-#define SAA7134_BOARD_BMK_MPEX_TUNER 23
-#define SAA7134_BOARD_TVSTATION_DVR 24
-#define SAA7134_BOARD_ASUSTEK_TVFM7133 25
-#define SAA7134_BOARD_PINNACLE_PCTV_STEREO 26
-#define SAA7134_BOARD_MANLI_MTV002 27
-#define SAA7134_BOARD_MANLI_MTV001 28
-#define SAA7134_BOARD_TG3000TV 29
-#define SAA7134_BOARD_ECS_TVP3XP 30
-#define SAA7134_BOARD_ECS_TVP3XP_4CB5 31
-#define SAA7134_BOARD_AVACSSMARTTV 32
-#define SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER 33
-#define SAA7134_BOARD_NOVAC_PRIMETV7133 34
-#define SAA7134_BOARD_AVERMEDIA_STUDIO_305 35
-#define SAA7134_BOARD_UPMOST_PURPLE_TV 36
-#define SAA7134_BOARD_ITEMS_MTV005 37
-#define SAA7134_BOARD_CINERGY200 38
-#define SAA7134_BOARD_FLYTVPLATINUM_MINI 39
-#define SAA7134_BOARD_VIDEOMATE_TV_PVR 40
-#define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS 41
-#define SAA7134_BOARD_SABRENT_SBTTVFM 42
-#define SAA7134_BOARD_ZOLID_XPERT_TV7134 43
-#define SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE 44
-#define SAA7134_BOARD_AVERMEDIA_STUDIO_307 45
-#define SAA7134_BOARD_AVERMEDIA_CARDBUS 46
-#define SAA7134_BOARD_CINERGY400_CARDBUS 47
-#define SAA7134_BOARD_CINERGY600_MK3 48
-#define SAA7134_BOARD_VIDEOMATE_GOLD_PLUS 49
-#define SAA7134_BOARD_PINNACLE_300I_DVBT_PAL 50
-#define SAA7134_BOARD_PROVIDEO_PV952 51
-#define SAA7134_BOARD_AVERMEDIA_305 52
-#define SAA7134_BOARD_ASUSTeK_TVFM7135 53
-#define SAA7134_BOARD_FLYTVPLATINUM_FM 54
-#define SAA7134_BOARD_FLYDVBTDUO 55
-#define SAA7134_BOARD_AVERMEDIA_307 56
-#define SAA7134_BOARD_AVERMEDIA_GO_007_FM 57
-#define SAA7134_BOARD_ADS_INSTANT_TV 58
-#define SAA7134_BOARD_KWORLD_VSTREAM_XPERT 59
-#define SAA7134_BOARD_FLYDVBT_DUO_CARDBUS 60
-#define SAA7134_BOARD_PHILIPS_TOUGH 61
-#define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII 62
-#define SAA7134_BOARD_KWORLD_XPERT 63
-#define SAA7134_BOARD_FLYTV_DIGIMATRIX 64
-#define SAA7134_BOARD_KWORLD_TERMINATOR 65
-#define SAA7134_BOARD_YUAN_TUN900 66
-#define SAA7134_BOARD_BEHOLD_409FM 67
-#define SAA7134_BOARD_GOTVIEW_7135 68
-#define SAA7134_BOARD_PHILIPS_EUROPA 69
-#define SAA7134_BOARD_VIDEOMATE_DVBT_300 70
-#define SAA7134_BOARD_VIDEOMATE_DVBT_200 71
-#define SAA7134_BOARD_RTD_VFG7350 72
-#define SAA7134_BOARD_RTD_VFG7330 73
-#define SAA7134_BOARD_FLYTVPLATINUM_MINI2 74
-#define SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180 75
-#define SAA7134_BOARD_MONSTERTV_MOBILE 76
-#define SAA7134_BOARD_PINNACLE_PCTV_110i 77
-#define SAA7134_BOARD_ASUSTeK_P7131_DUAL 78
-#define SAA7134_BOARD_SEDNA_PC_TV_CARDBUS 79
-#define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80
-#define SAA7134_BOARD_PHILIPS_TIGER 81
-#define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS 82
-#define SAA7134_BOARD_CINERGY250PCI 83
-#define SAA7134_BOARD_FLYDVB_TRIO 84
-#define SAA7134_BOARD_AVERMEDIA_777 85
-#define SAA7134_BOARD_FLYDVBT_LR301 86
-#define SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331 87
-#define SAA7134_BOARD_TEVION_DVBT_220RF 88
-#define SAA7134_BOARD_ELSA_700TV 89
-#define SAA7134_BOARD_KWORLD_ATSC110 90
-#define SAA7134_BOARD_AVERMEDIA_A169_B 91
-#define SAA7134_BOARD_AVERMEDIA_A169_B1 92
-#define SAA7134_BOARD_MD7134_BRIDGE_2 93
-#define SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS 94
-#define SAA7134_BOARD_FLYVIDEO3000_NTSC 95
-#define SAA7134_BOARD_MEDION_MD8800_QUADRO 96
-#define SAA7134_BOARD_FLYDVBS_LR300 97
-#define SAA7134_BOARD_PROTEUS_2309 98
-#define SAA7134_BOARD_AVERMEDIA_A16AR 99
-#define SAA7134_BOARD_ASUS_EUROPA2_HYBRID 100
-#define SAA7134_BOARD_PINNACLE_PCTV_310i 101
-#define SAA7134_BOARD_AVERMEDIA_STUDIO_507 102
-#define SAA7134_BOARD_VIDEOMATE_DVBT_200A 103
-#define SAA7134_BOARD_HAUPPAUGE_HVR1110 104
-#define SAA7134_BOARD_CINERGY_HT_PCMCIA 105
-#define SAA7134_BOARD_ENCORE_ENLTV 106
-#define SAA7134_BOARD_ENCORE_ENLTV_FM 107
-#define SAA7134_BOARD_CINERGY_HT_PCI 108
-#define SAA7134_BOARD_PHILIPS_TIGER_S 109
-#define SAA7134_BOARD_AVERMEDIA_M102 110
-#define SAA7134_BOARD_ASUS_P7131_4871 111
-#define SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA 112
-#define SAA7134_BOARD_ECS_TVP3XP_4CB6 113
-#define SAA7134_BOARD_KWORLD_DVBT_210 114
-#define SAA7134_BOARD_SABRENT_TV_PCB05 115
-#define SAA7134_BOARD_10MOONSTVMASTER3 116
-#define SAA7134_BOARD_AVERMEDIA_SUPER_007 117
-#define SAA7134_BOARD_BEHOLD_401 118
-#define SAA7134_BOARD_BEHOLD_403 119
-#define SAA7134_BOARD_BEHOLD_403FM 120
-#define SAA7134_BOARD_BEHOLD_405 121
-#define SAA7134_BOARD_BEHOLD_405FM 122
-#define SAA7134_BOARD_BEHOLD_407 123
-#define SAA7134_BOARD_BEHOLD_407FM 124
-#define SAA7134_BOARD_BEHOLD_409 125
-#define SAA7134_BOARD_BEHOLD_505FM 126
-#define SAA7134_BOARD_BEHOLD_507_9FM 127
-#define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128
-#define SAA7134_BOARD_BEHOLD_607FM_MK3 129
-#define SAA7134_BOARD_BEHOLD_M6 130
-#define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131
-#define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132
-#define SAA7134_BOARD_PHILIPS_SNAKE 133
-#define SAA7134_BOARD_CREATIX_CTX953 134
-#define SAA7134_BOARD_MSI_TVANYWHERE_AD11 135
-#define SAA7134_BOARD_AVERMEDIA_CARDBUS_506 136
-#define SAA7134_BOARD_AVERMEDIA_A16D 137
-#define SAA7134_BOARD_AVERMEDIA_M115 138
-#define SAA7134_BOARD_VIDEOMATE_T750 139
-#define SAA7134_BOARD_AVERMEDIA_A700_PRO 140
-#define SAA7134_BOARD_AVERMEDIA_A700_HYBRID 141
-#define SAA7134_BOARD_BEHOLD_H6 142
-#define SAA7134_BOARD_BEHOLD_M63 143
-#define SAA7134_BOARD_BEHOLD_M6_EXTRA 144
-#define SAA7134_BOARD_AVERMEDIA_M103 145
-#define SAA7134_BOARD_ASUSTeK_P7131_ANALOG 146
-#define SAA7134_BOARD_ASUSTeK_TIGER_3IN1 147
-#define SAA7134_BOARD_ENCORE_ENLTV_FM53 148
-#define SAA7134_BOARD_AVERMEDIA_M135A 149
-#define SAA7134_BOARD_REAL_ANGEL_220 150
-#define SAA7134_BOARD_ADS_INSTANT_HDTV_PCI 151
-#define SAA7134_BOARD_ASUSTeK_TIGER 152
-#define SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG 153
-#define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154
-#define SAA7134_BOARD_HAUPPAUGE_HVR1150 155
-#define SAA7134_BOARD_HAUPPAUGE_HVR1120 156
-#define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157
-#define SAA7134_BOARD_AVERMEDIA_CARDBUS_501 158
-#define SAA7134_BOARD_BEHOLD_505RDS_MK5 159
-#define SAA7134_BOARD_BEHOLD_507RDS_MK3 160
-#define SAA7134_BOARD_BEHOLD_507RDS_MK5 161
-#define SAA7134_BOARD_BEHOLD_607FM_MK5 162
-#define SAA7134_BOARD_BEHOLD_609FM_MK3 163
-#define SAA7134_BOARD_BEHOLD_609FM_MK5 164
-#define SAA7134_BOARD_BEHOLD_607RDS_MK3 165
-#define SAA7134_BOARD_BEHOLD_607RDS_MK5 166
-#define SAA7134_BOARD_BEHOLD_609RDS_MK3 167
-#define SAA7134_BOARD_BEHOLD_609RDS_MK5 168
-#define SAA7134_BOARD_VIDEOMATE_S350 169
-#define SAA7134_BOARD_AVERMEDIA_STUDIO_505 170
-#define SAA7134_BOARD_BEHOLD_X7 171
-#define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172
-#define SAA7134_BOARD_ZOLID_HYBRID_PCI 173
-#define SAA7134_BOARD_ASUS_EUROPA_HYBRID 174
-#define SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S 175
-#define SAA7134_BOARD_BEHOLD_505RDS_MK3 176
-#define SAA7134_BOARD_HAWELL_HW_404M7 177
-#define SAA7134_BOARD_BEHOLD_H7 178
-#define SAA7134_BOARD_BEHOLD_A7 179
-#define SAA7134_BOARD_AVERMEDIA_M733A 180
-#define SAA7134_BOARD_TECHNOTREND_BUDGET_T3000 181
-#define SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG 182
-#define SAA7134_BOARD_VIDEOMATE_M1F 183
-#define SAA7134_BOARD_ENCORE_ENLTV_FM3 184
-#define SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2 185
-#define SAA7134_BOARD_BEHOLD_501 186
-#define SAA7134_BOARD_BEHOLD_503FM 187
-#define SAA7134_BOARD_SENSORAY811_911 188
-#define SAA7134_BOARD_KWORLD_PC150U 189
-#define SAA7134_BOARD_ASUSTeK_PS3_100 190
-
-#define SAA7134_MAXBOARDS 32
-#define SAA7134_INPUT_MAX 8
-
-/* ----------------------------------------------------------- */
-/* Since we support 2 remote types, lets tell them apart */
-
-#define SAA7134_REMOTE_GPIO 1
-#define SAA7134_REMOTE_I2C 2
-
-/* ----------------------------------------------------------- */
-/* Video Output Port Register Initialization Options */
-
-#define SET_T_CODE_POLARITY_NON_INVERTED (1 << 0)
-#define SET_CLOCK_NOT_DELAYED (1 << 1)
-#define SET_CLOCK_INVERTED (1 << 2)
-#define SET_VSYNC_OFF (1 << 3)
-
-struct saa7134_input {
- char *name;
- unsigned int vmux;
- enum saa7134_audio_in amux;
- unsigned int gpio;
- unsigned int tv:1;
-};
-
-enum saa7134_mpeg_type {
- SAA7134_MPEG_UNUSED,
- SAA7134_MPEG_EMPRESS,
- SAA7134_MPEG_DVB,
-};
-
-enum saa7134_mpeg_ts_type {
- SAA7134_MPEG_TS_PARALLEL = 0,
- SAA7134_MPEG_TS_SERIAL,
-};
-
-struct saa7134_board {
- char *name;
- unsigned int audio_clock;
-
- /* input switching */
- unsigned int gpiomask;
- struct saa7134_input inputs[SAA7134_INPUT_MAX];
- struct saa7134_input radio;
- struct saa7134_input mute;
-
- /* i2c chip info */
- unsigned int tuner_type;
- unsigned int radio_type;
- unsigned char tuner_addr;
- unsigned char radio_addr;
- unsigned char empress_addr;
- unsigned char rds_addr;
-
- unsigned int tda9887_conf;
- unsigned int tuner_config;
-
- /* peripheral I/O */
- enum saa7134_video_out video_out;
- enum saa7134_mpeg_type mpeg;
- enum saa7134_mpeg_ts_type ts_type;
- unsigned int vid_port_opts;
- unsigned int ts_force_val:1;
-};
-
-#define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name)
-#define card_is_empress(dev) (SAA7134_MPEG_EMPRESS == saa7134_boards[dev->board].mpeg)
-#define card_is_dvb(dev) (SAA7134_MPEG_DVB == saa7134_boards[dev->board].mpeg)
-#define card_has_mpeg(dev) (SAA7134_MPEG_UNUSED != saa7134_boards[dev->board].mpeg)
-#define card(dev) (saa7134_boards[dev->board])
-#define card_in(dev,n) (saa7134_boards[dev->board].inputs[n])
-
-/* ----------------------------------------------------------- */
-/* device / file handle status */
-
-#define RESOURCE_OVERLAY 1
-#define RESOURCE_VIDEO 2
-#define RESOURCE_VBI 4
-
-#define INTERLACE_AUTO 0
-#define INTERLACE_ON 1
-#define INTERLACE_OFF 2
-
-#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
-#define TS_BUFFER_TIMEOUT msecs_to_jiffies(1000) /* 1 second */
-
-struct saa7134_dev;
-struct saa7134_dma;
-
-/* saa7134 page table */
-struct saa7134_pgtable {
- unsigned int size;
- __le32 *cpu;
- dma_addr_t dma;
-};
-
-/* tvaudio thread status */
-struct saa7134_thread {
- struct task_struct *thread;
- unsigned int scan1;
- unsigned int scan2;
- unsigned int mode;
- unsigned int stopped;
-};
-
-/* buffer for one video/vbi/ts frame */
-struct saa7134_buf {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
-
- /* saa7134 specific */
- struct saa7134_format *fmt;
- unsigned int top_seen;
- int (*activate)(struct saa7134_dev *dev,
- struct saa7134_buf *buf,
- struct saa7134_buf *next);
-
- /* page tables */
- struct saa7134_pgtable *pt;
-};
-
-struct saa7134_dmaqueue {
- struct saa7134_dev *dev;
- struct saa7134_buf *curr;
- struct list_head queue;
- struct timer_list timeout;
- unsigned int need_two;
-};
-
-/* video filehandle status */
-struct saa7134_fh {
- struct saa7134_dev *dev;
- unsigned int radio;
- enum v4l2_buf_type type;
- unsigned int resources;
- enum v4l2_priority prio;
-
- /* video overlay */
- struct v4l2_window win;
- struct v4l2_clip clips[8];
- unsigned int nclips;
-
- /* video capture */
- struct saa7134_format *fmt;
- unsigned int width,height;
- struct videobuf_queue cap;
- struct saa7134_pgtable pt_cap;
-
- /* vbi capture */
- struct videobuf_queue vbi;
- struct saa7134_pgtable pt_vbi;
-};
-
-/* dmasound dsp status */
-struct saa7134_dmasound {
- struct mutex lock;
- int minor_mixer;
- int minor_dsp;
- unsigned int users_dsp;
-
- /* mixer */
- enum saa7134_audio_in input;
- unsigned int count;
- unsigned int line1;
- unsigned int line2;
-
- /* dsp */
- unsigned int afmt;
- unsigned int rate;
- unsigned int channels;
- unsigned int recording_on;
- unsigned int dma_running;
- unsigned int blocks;
- unsigned int blksize;
- unsigned int bufsize;
- struct saa7134_pgtable pt;
- struct videobuf_dmabuf dma;
- unsigned int dma_blk;
- unsigned int read_offset;
- unsigned int read_count;
- void * priv_data;
- struct snd_pcm_substream *substream;
-};
-
-/* ts/mpeg status */
-struct saa7134_ts {
- /* TS capture */
- struct saa7134_pgtable pt_ts;
- int nr_packets;
- int nr_bufs;
-};
-
-/* ts/mpeg ops */
-struct saa7134_mpeg_ops {
- enum saa7134_mpeg_type type;
- struct list_head next;
- int (*init)(struct saa7134_dev *dev);
- int (*fini)(struct saa7134_dev *dev);
- void (*signal_change)(struct saa7134_dev *dev);
-};
-
-/* global device status */
-struct saa7134_dev {
- struct list_head devlist;
- struct mutex lock;
- spinlock_t slock;
- struct v4l2_prio_state prio;
- struct v4l2_device v4l2_dev;
- /* workstruct for loading modules */
- struct work_struct request_module_wk;
-
- /* insmod option/autodetected */
- int autodetected;
-
- /* various device info */
- unsigned int resources;
- struct video_device *video_dev;
- struct video_device *radio_dev;
- struct video_device *vbi_dev;
- struct saa7134_dmasound dmasound;
-
- /* infrared remote */
- int has_remote;
- struct saa7134_card_ir *remote;
-
- /* pci i/o */
- char name[32];
- int nr;
- struct pci_dev *pci;
- unsigned char pci_rev,pci_lat;
- __u32 __iomem *lmmio;
- __u8 __iomem *bmmio;
-
- /* config info */
- unsigned int board;
- unsigned int tuner_type;
- unsigned int radio_type;
- unsigned char tuner_addr;
- unsigned char radio_addr;
-
- unsigned int tda9887_conf;
- unsigned int gpio_value;
-
- /* i2c i/o */
- struct i2c_adapter i2c_adap;
- struct i2c_client i2c_client;
- unsigned char eedata[256];
- int has_rds;
-
- /* video overlay */
- struct v4l2_framebuffer ovbuf;
- struct saa7134_format *ovfmt;
- unsigned int ovenable;
- enum v4l2_field ovfield;
-
- /* video+ts+vbi capture */
- struct saa7134_dmaqueue video_q;
- struct saa7134_dmaqueue vbi_q;
- unsigned int video_fieldcount;
- unsigned int vbi_fieldcount;
-
- /* various v4l controls */
- struct saa7134_tvnorm *tvnorm; /* video */
- struct saa7134_tvaudio *tvaudio;
- unsigned int ctl_input;
- int ctl_bright;
- int ctl_contrast;
- int ctl_hue;
- int ctl_saturation;
- int ctl_freq;
- int ctl_mute; /* audio */
- int ctl_volume;
- int ctl_invert; /* private */
- int ctl_mirror;
- int ctl_y_odd;
- int ctl_y_even;
- int ctl_automute;
-
- /* crop */
- struct v4l2_rect crop_bounds;
- struct v4l2_rect crop_defrect;
- struct v4l2_rect crop_current;
-
- /* other global state info */
- unsigned int automute;
- struct saa7134_thread thread;
- struct saa7134_input *input;
- struct saa7134_input *hw_input;
- unsigned int hw_mute;
- int last_carrier;
- int nosignal;
- unsigned int insuspend;
-
- /* I2C keyboard data */
- struct IR_i2c_init_data init_data;
-
- /* SAA7134_MPEG_* */
- struct saa7134_ts ts;
- struct saa7134_dmaqueue ts_q;
- int ts_started;
- struct saa7134_mpeg_ops *mops;
-
- /* SAA7134_MPEG_EMPRESS only */
- struct video_device *empress_dev;
- struct videobuf_queue empress_tsq;
- atomic_t empress_users;
- struct work_struct empress_workqueue;
- int empress_started;
-
-#if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE)
- /* SAA7134_MPEG_DVB only */
- struct videobuf_dvb_frontends frontends;
- int (*original_demod_sleep)(struct dvb_frontend *fe);
- int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
- int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg);
-#endif
- void (*gate_ctrl)(struct saa7134_dev *dev, int open);
-};
-
-/* ----------------------------------------------------------- */
-
-#define saa_readl(reg) readl(dev->lmmio + (reg))
-#define saa_writel(reg,value) writel((value), dev->lmmio + (reg));
-#define saa_andorl(reg,mask,value) \
- writel((readl(dev->lmmio+(reg)) & ~(mask)) |\
- ((value) & (mask)), dev->lmmio+(reg))
-#define saa_setl(reg,bit) saa_andorl((reg),(bit),(bit))
-#define saa_clearl(reg,bit) saa_andorl((reg),(bit),0)
-
-#define saa_readb(reg) readb(dev->bmmio + (reg))
-#define saa_writeb(reg,value) writeb((value), dev->bmmio + (reg));
-#define saa_andorb(reg,mask,value) \
- writeb((readb(dev->bmmio+(reg)) & ~(mask)) |\
- ((value) & (mask)), dev->bmmio+(reg))
-#define saa_setb(reg,bit) saa_andorb((reg),(bit),(bit))
-#define saa_clearb(reg,bit) saa_andorb((reg),(bit),0)
-
-#define saa_wait(us) { udelay(us); }
-
-#define SAA7134_NORMS (\
- V4L2_STD_PAL | V4L2_STD_PAL_N | \
- V4L2_STD_PAL_Nc | V4L2_STD_SECAM | \
- V4L2_STD_NTSC | V4L2_STD_PAL_M | \
- V4L2_STD_PAL_60)
-
-#define GRP_EMPRESS (1)
-#define saa_call_all(dev, o, f, args...) do { \
- if (dev->gate_ctrl) \
- dev->gate_ctrl(dev, 1); \
- v4l2_device_call_all(&(dev)->v4l2_dev, 0, o, f , ##args); \
- if (dev->gate_ctrl) \
- dev->gate_ctrl(dev, 0); \
-} while (0)
-
-#define saa_call_empress(dev, o, f, args...) ({ \
- long _rc; \
- if (dev->gate_ctrl) \
- dev->gate_ctrl(dev, 1); \
- _rc = v4l2_device_call_until_err(&(dev)->v4l2_dev, \
- GRP_EMPRESS, o, f , ##args); \
- if (dev->gate_ctrl) \
- dev->gate_ctrl(dev, 0); \
- _rc; \
-})
-
-/* ----------------------------------------------------------- */
-/* saa7134-core.c */
-
-extern struct list_head saa7134_devlist;
-extern struct mutex saa7134_devlist_lock;
-extern int saa7134_no_overlay;
-
-void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
-void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value);
-
-#define SAA7134_PGTABLE_SIZE 4096
-
-int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt);
-int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
- struct scatterlist *list, unsigned int length,
- unsigned int startpage);
-void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt);
-
-int saa7134_buffer_count(unsigned int size, unsigned int count);
-int saa7134_buffer_startpage(struct saa7134_buf *buf);
-unsigned long saa7134_buffer_base(struct saa7134_buf *buf);
-
-int saa7134_buffer_queue(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
- struct saa7134_buf *buf);
-void saa7134_buffer_finish(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
- unsigned int state);
-void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
-void saa7134_buffer_timeout(unsigned long data);
-void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf);
-
-int saa7134_set_dmabits(struct saa7134_dev *dev);
-
-extern int (*saa7134_dmasound_init)(struct saa7134_dev *dev);
-extern int (*saa7134_dmasound_exit)(struct saa7134_dev *dev);
-
-
-/* ----------------------------------------------------------- */
-/* saa7134-cards.c */
-
-extern struct saa7134_board saa7134_boards[];
-extern const unsigned int saa7134_bcount;
-extern struct pci_device_id __devinitdata saa7134_pci_tbl[];
-
-extern int saa7134_board_init1(struct saa7134_dev *dev);
-extern int saa7134_board_init2(struct saa7134_dev *dev);
-int saa7134_tuner_callback(void *priv, int component, int command, int arg);
-
-
-/* ----------------------------------------------------------- */
-/* saa7134-i2c.c */
-
-int saa7134_i2c_register(struct saa7134_dev *dev);
-int saa7134_i2c_unregister(struct saa7134_dev *dev);
-
-
-/* ----------------------------------------------------------- */
-/* saa7134-video.c */
-
-extern unsigned int video_debug;
-extern struct video_device saa7134_video_template;
-extern struct video_device saa7134_radio_template;
-
-int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c);
-int saa7134_g_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c);
-int saa7134_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c);
-int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id *id);
-
-int saa7134_videoport_init(struct saa7134_dev *dev);
-void saa7134_set_tvnorm_hw(struct saa7134_dev *dev);
-
-int saa7134_video_init1(struct saa7134_dev *dev);
-int saa7134_video_init2(struct saa7134_dev *dev);
-void saa7134_irq_video_signalchange(struct saa7134_dev *dev);
-void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status);
-
-
-/* ----------------------------------------------------------- */
-/* saa7134-ts.c */
-
-#define TS_PACKET_SIZE 188 /* TS packets 188 bytes */
-
-extern struct videobuf_queue_ops saa7134_ts_qops;
-
-int saa7134_ts_init1(struct saa7134_dev *dev);
-int saa7134_ts_fini(struct saa7134_dev *dev);
-void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status);
-
-int saa7134_ts_register(struct saa7134_mpeg_ops *ops);
-void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops);
-
-int saa7134_ts_init_hw(struct saa7134_dev *dev);
-
-int saa7134_ts_start(struct saa7134_dev *dev);
-int saa7134_ts_stop(struct saa7134_dev *dev);
-
-/* ----------------------------------------------------------- */
-/* saa7134-vbi.c */
-
-extern struct videobuf_queue_ops saa7134_vbi_qops;
-extern struct video_device saa7134_vbi_template;
-
-int saa7134_vbi_init1(struct saa7134_dev *dev);
-int saa7134_vbi_fini(struct saa7134_dev *dev);
-void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status);
-
-
-/* ----------------------------------------------------------- */
-/* saa7134-tvaudio.c */
-
-int saa7134_tvaudio_rx2mode(u32 rx);
-
-void saa7134_tvaudio_setmute(struct saa7134_dev *dev);
-void saa7134_tvaudio_setinput(struct saa7134_dev *dev,
- struct saa7134_input *in);
-void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level);
-int saa7134_tvaudio_getstereo(struct saa7134_dev *dev);
-
-void saa7134_tvaudio_init(struct saa7134_dev *dev);
-int saa7134_tvaudio_init2(struct saa7134_dev *dev);
-int saa7134_tvaudio_fini(struct saa7134_dev *dev);
-int saa7134_tvaudio_do_scan(struct saa7134_dev *dev);
-int saa7134_tvaudio_close(struct saa7134_dev *dev);
-
-int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value);
-
-void saa7134_enable_i2s(struct saa7134_dev *dev);
-
-/* ----------------------------------------------------------- */
-/* saa7134-oss.c */
-
-extern const struct file_operations saa7134_dsp_fops;
-extern const struct file_operations saa7134_mixer_fops;
-
-int saa7134_oss_init1(struct saa7134_dev *dev);
-int saa7134_oss_fini(struct saa7134_dev *dev);
-void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status);
-
-/* ----------------------------------------------------------- */
-/* saa7134-input.c */
-
-#if defined(CONFIG_VIDEO_SAA7134_RC)
-int saa7134_input_init1(struct saa7134_dev *dev);
-void saa7134_input_fini(struct saa7134_dev *dev);
-void saa7134_input_irq(struct saa7134_dev *dev);
-void saa7134_probe_i2c_ir(struct saa7134_dev *dev);
-int saa7134_ir_start(struct saa7134_dev *dev);
-void saa7134_ir_stop(struct saa7134_dev *dev);
-#else
-#define saa7134_input_init1(dev) ((void)0)
-#define saa7134_input_fini(dev) ((void)0)
-#define saa7134_input_irq(dev) ((void)0)
-#define saa7134_probe_i2c_ir(dev) ((void)0)
-#define saa7134_ir_start(dev) ((void)0)
-#define saa7134_ir_stop(dev) ((void)0)
-#endif
diff --git a/drivers/media/video/saa7164/Kconfig b/drivers/media/video/saa7164/Kconfig
deleted file mode 100644
index 35326372517..00000000000
--- a/drivers/media/video/saa7164/Kconfig
+++ /dev/null
@@ -1,18 +0,0 @@
-config VIDEO_SAA7164
- tristate "NXP SAA7164 support"
- depends on DVB_CORE && PCI && I2C
- select I2C_ALGOBIT
- select FW_LOADER
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- select VIDEOBUF_DVB
- select DVB_TDA10048 if !DVB_FE_CUSTOMISE
- select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
- ---help---
- This is a video4linux driver for NXP SAA7164 based
- TV cards.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7164
-
diff --git a/drivers/media/video/saa7164/Makefile b/drivers/media/video/saa7164/Makefile
deleted file mode 100644
index 068443af30c..00000000000
--- a/drivers/media/video/saa7164/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-saa7164-objs := saa7164-cards.o saa7164-core.o saa7164-i2c.o saa7164-dvb.o \
- saa7164-fw.o saa7164-bus.o saa7164-cmd.o saa7164-api.o \
- saa7164-buffer.o saa7164-encoder.o saa7164-vbi.o
-
-obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o
-
-ccflags-y += -I$(srctree)/drivers/media/video
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
-ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
-
-ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c
deleted file mode 100644
index c8799fdaae6..00000000000
--- a/drivers/media/video/saa7164/saa7164-api.c
+++ /dev/null
@@ -1,1519 +0,0 @@
-/*
- * Driver for the NXP SAA7164 PCIe bridge
- *
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/wait.h>
-#include <linux/slab.h>
-
-#include "saa7164.h"
-
-int saa7164_api_get_load_info(struct saa7164_dev *dev, struct tmFwInfoStruct *i)
-{
- int ret;
-
- if (!(saa_debug & DBGLVL_CPU))
- return 0;
-
- dprintk(DBGLVL_API, "%s()\n", __func__);
-
- i->deviceinst = 0;
- i->devicespec = 0;
- i->mode = 0;
- i->status = 0;
-
- ret = saa7164_cmd_send(dev, 0, GET_CUR,
- GET_FW_STATUS_CONTROL, sizeof(struct tmFwInfoStruct), i);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- printk(KERN_INFO "saa7164[%d]-CPU: %d percent", dev->nr, i->CPULoad);
-
- return ret;
-}
-
-int saa7164_api_collect_debug(struct saa7164_dev *dev)
-{
- struct tmComResDebugGetData d;
- u8 more = 255;
- int ret;
-
- dprintk(DBGLVL_API, "%s()\n", __func__);
-
- while (more--) {
-
- memset(&d, 0, sizeof(d));
-
- ret = saa7164_cmd_send(dev, 0, GET_CUR,
- GET_DEBUG_DATA_CONTROL, sizeof(d), &d);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n",
- __func__, ret);
-
- if (d.dwResult != SAA_OK)
- break;
-
- printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr,
- d.ucDebugData);
- }
-
- return 0;
-}
-
-int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level)
-{
- struct tmComResDebugSetLevel lvl;
- int ret;
-
- dprintk(DBGLVL_API, "%s(level=%d)\n", __func__, level);
-
- /* Retrieve current state */
- ret = saa7164_cmd_send(dev, 0, GET_CUR,
- SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel);
-
- lvl.dwDebugLevel = level;
-
- /* set new state */
- ret = saa7164_cmd_send(dev, 0, SET_CUR,
- SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- return ret;
-}
-
-int saa7164_api_set_vbi_format(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- struct tmComResProbeCommit fmt, rsp;
- int ret;
-
- dprintk(DBGLVL_API, "%s(nr=%d, unitid=0x%x)\n", __func__,
- port->nr, port->hwcfg.unitid);
-
- fmt.bmHint = 0;
- fmt.bFormatIndex = 1;
- fmt.bFrameIndex = 1;
-
- /* Probe, see if it can support this format */
- ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
- SET_CUR, SAA_PROBE_CONTROL, sizeof(fmt), &fmt);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() set error, ret = 0x%x\n", __func__, ret);
-
- /* See of the format change was successful */
- ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
- GET_CUR, SAA_PROBE_CONTROL, sizeof(rsp), &rsp);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() get error, ret = 0x%x\n", __func__, ret);
- } else {
- /* Compare requested vs received, should be same */
- if (memcmp(&fmt, &rsp, sizeof(rsp)) == 0) {
- dprintk(DBGLVL_API, "SET/PROBE Verified\n");
-
- /* Ask the device to select the negotiated format */
- ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
- SET_CUR, SAA_COMMIT_CONTROL, sizeof(fmt), &fmt);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() commit error, ret = 0x%x\n",
- __func__, ret);
-
- ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
- GET_CUR, SAA_COMMIT_CONTROL, sizeof(rsp), &rsp);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() GET commit error, ret = 0x%x\n",
- __func__, ret);
-
- if (memcmp(&fmt, &rsp, sizeof(rsp)) != 0) {
- printk(KERN_ERR "%s() memcmp error, ret = 0x%x\n",
- __func__, ret);
- } else
- dprintk(DBGLVL_API, "SET/COMMIT Verified\n");
-
- dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint);
- dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n",
- rsp.bFormatIndex);
- dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n",
- rsp.bFrameIndex);
- } else
- printk(KERN_ERR "%s() compare failed\n", __func__);
- }
-
- if (ret == SAA_OK)
- dprintk(DBGLVL_API, "%s(nr=%d) Success\n", __func__, port->nr);
-
- return ret;
-}
-
-int saa7164_api_set_gop_size(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- struct tmComResEncVideoGopStructure gs;
- int ret;
-
- dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
- gs.ucRefFrameDist = port->encoder_params.refdist;
- gs.ucGOPSize = port->encoder_params.gop_size;
- ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
- EU_VIDEO_GOP_STRUCTURE_CONTROL,
- sizeof(gs), &gs);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- return ret;
-}
-
-int saa7164_api_set_encoder(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- struct tmComResEncVideoBitRate vb;
- struct tmComResEncAudioBitRate ab;
- int ret;
-
- dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__,
- port->hwcfg.sourceid);
-
- if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS)
- port->encoder_profile = EU_PROFILE_PS_DVD;
- else
- port->encoder_profile = EU_PROFILE_TS_HQ;
-
- ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
- EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- /* Resolution */
- ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
- EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- /* Establish video bitrates */
- if (port->encoder_params.bitrate_mode ==
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
- vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_CONSTANT;
- else
- vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK;
- vb.dwVideoBitRate = port->encoder_params.bitrate;
- vb.dwVideoBitRatePeak = port->encoder_params.bitrate_peak;
- ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
- EU_VIDEO_BIT_RATE_CONTROL,
- sizeof(struct tmComResEncVideoBitRate),
- &vb);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- /* Establish audio bitrates */
- ab.ucAudioBitRateMode = 0;
- ab.dwAudioBitRate = 384000;
- ab.dwAudioBitRatePeak = ab.dwAudioBitRate;
- ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
- EU_AUDIO_BIT_RATE_CONTROL,
- sizeof(struct tmComResEncAudioBitRate),
- &ab);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
- ret);
-
- saa7164_api_set_aspect_ratio(port);
- saa7164_api_set_gop_size(port);
-
- return ret;
-}
-
-int saa7164_api_get_encoder(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- struct tmComResEncVideoBitRate v;
- struct tmComResEncAudioBitRate a;
- struct tmComResEncVideoInputAspectRatio ar;
- int ret;
-
- dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__,
- port->hwcfg.sourceid);
-
- port->encoder_profile = 0;
- port->video_format = 0;
- port->video_resolution = 0;
- port->audio_format = 0;
-
- ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
- EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
- EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8),
- &port->video_resolution);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
- EU_VIDEO_FORMAT_CONTROL, sizeof(u8), &port->video_format);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
- EU_VIDEO_BIT_RATE_CONTROL, sizeof(v), &v);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
- EU_AUDIO_FORMAT_CONTROL, sizeof(u8), &port->audio_format);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
- EU_AUDIO_BIT_RATE_CONTROL, sizeof(a), &a);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- /* Aspect Ratio */
- ar.width = 0;
- ar.height = 0;
- ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
- EU_VIDEO_INPUT_ASPECT_CONTROL,
- sizeof(struct tmComResEncVideoInputAspectRatio), &ar);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- dprintk(DBGLVL_ENC, "encoder_profile = %d\n", port->encoder_profile);
- dprintk(DBGLVL_ENC, "video_format = %d\n", port->video_format);
- dprintk(DBGLVL_ENC, "audio_format = %d\n", port->audio_format);
- dprintk(DBGLVL_ENC, "video_resolution= %d\n", port->video_resolution);
- dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n",
- v.ucVideoBitRateMode);
- dprintk(DBGLVL_ENC, "v.dwVideoBitRate = %d\n",
- v.dwVideoBitRate);
- dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n",
- v.dwVideoBitRatePeak);
- dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n",
- a.ucAudioBitRateMode);
- dprintk(DBGLVL_ENC, "a.dwVideoBitRate = %d\n",
- a.dwAudioBitRate);
- dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n",
- a.dwAudioBitRatePeak);
- dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n",
- ar.width, ar.height);
-
- return ret;
-}
-
-int saa7164_api_set_aspect_ratio(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- struct tmComResEncVideoInputAspectRatio ar;
- int ret;
-
- dprintk(DBGLVL_ENC, "%s(%d)\n", __func__,
- port->encoder_params.ctl_aspect);
-
- switch (port->encoder_params.ctl_aspect) {
- case V4L2_MPEG_VIDEO_ASPECT_1x1:
- ar.width = 1;
- ar.height = 1;
- break;
- case V4L2_MPEG_VIDEO_ASPECT_4x3:
- ar.width = 4;
- ar.height = 3;
- break;
- case V4L2_MPEG_VIDEO_ASPECT_16x9:
- ar.width = 16;
- ar.height = 9;
- break;
- case V4L2_MPEG_VIDEO_ASPECT_221x100:
- ar.width = 221;
- ar.height = 100;
- break;
- default:
- BUG();
- }
-
- dprintk(DBGLVL_ENC, "%s(%d) now %d:%d\n", __func__,
- port->encoder_params.ctl_aspect,
- ar.width, ar.height);
-
- /* Aspect Ratio */
- ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
- EU_VIDEO_INPUT_ASPECT_CONTROL,
- sizeof(struct tmComResEncVideoInputAspectRatio), &ar);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- return ret;
-}
-
-int saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl)
-{
- struct saa7164_dev *dev = port->dev;
- int ret;
- u16 val;
-
- if (ctl == PU_BRIGHTNESS_CONTROL)
- val = port->ctl_brightness;
- else
- if (ctl == PU_CONTRAST_CONTROL)
- val = port->ctl_contrast;
- else
- if (ctl == PU_HUE_CONTROL)
- val = port->ctl_hue;
- else
- if (ctl == PU_SATURATION_CONTROL)
- val = port->ctl_saturation;
- else
- if (ctl == PU_SHARPNESS_CONTROL)
- val = port->ctl_sharpness;
- else
- return -EINVAL;
-
- dprintk(DBGLVL_ENC, "%s() unitid=0x%x ctl=%d, val=%d\n",
- __func__, port->encunit.vsourceid, ctl, val);
-
- ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, SET_CUR,
- ctl, sizeof(u16), &val);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- return ret;
-}
-
-int saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl)
-{
- struct saa7164_dev *dev = port->dev;
- int ret;
- u16 val;
-
- ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, GET_CUR,
- ctl, sizeof(u16), &val);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
- return ret;
- }
-
- dprintk(DBGLVL_ENC, "%s() ctl=%d, val=%d\n",
- __func__, ctl, val);
-
- if (ctl == PU_BRIGHTNESS_CONTROL)
- port->ctl_brightness = val;
- else
- if (ctl == PU_CONTRAST_CONTROL)
- port->ctl_contrast = val;
- else
- if (ctl == PU_HUE_CONTROL)
- port->ctl_hue = val;
- else
- if (ctl == PU_SATURATION_CONTROL)
- port->ctl_saturation = val;
- else
- if (ctl == PU_SHARPNESS_CONTROL)
- port->ctl_sharpness = val;
-
- return ret;
-}
-
-int saa7164_api_set_videomux(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- u8 inputs[] = { 1, 2, 2, 2, 5, 5, 5 };
- int ret;
-
- dprintk(DBGLVL_ENC, "%s() v_mux=%d a_mux=%d\n",
- __func__, port->mux_input, inputs[port->mux_input - 1]);
-
- /* Audio Mute */
- ret = saa7164_api_audio_mute(port, 1);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- /* Video Mux */
- ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, SET_CUR,
- SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- /* Audio Mux */
- ret = saa7164_cmd_send(port->dev, port->audfeat.sourceid, SET_CUR,
- SU_INPUT_SELECT_CONTROL, sizeof(u8),
- &inputs[port->mux_input - 1]);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- /* Audio UnMute */
- ret = saa7164_api_audio_mute(port, 0);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- return ret;
-}
-
-int saa7164_api_audio_mute(struct saa7164_port *port, int mute)
-{
- struct saa7164_dev *dev = port->dev;
- u8 v = mute;
- int ret;
-
- dprintk(DBGLVL_API, "%s(%d)\n", __func__, mute);
-
- ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
- MUTE_CONTROL, sizeof(u8), &v);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- return ret;
-}
-
-/* 0 = silence, 0xff = full */
-int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level)
-{
- struct saa7164_dev *dev = port->dev;
- s16 v, min, max;
- int ret;
-
- dprintk(DBGLVL_API, "%s(%d)\n", __func__, level);
-
- /* Obtain the min/max ranges */
- ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MIN,
- VOLUME_CONTROL, sizeof(u16), &min);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MAX,
- VOLUME_CONTROL, sizeof(u16), &max);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR,
- (0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__,
- level, min, max, v);
-
- v = level;
- if (v < min)
- v = min;
- if (v > max)
- v = max;
-
- /* Left */
- ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
- (0x01 << 8) | VOLUME_CONTROL, sizeof(s16), &v);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- /* Right */
- ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
- (0x02 << 8) | VOLUME_CONTROL, sizeof(s16), &v);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR,
- (0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__,
- level, min, max, v);
-
- return ret;
-}
-
-int saa7164_api_set_audio_std(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- struct tmComResAudioDefaults lvl;
- struct tmComResTunerStandard tvaudio;
- int ret;
-
- dprintk(DBGLVL_API, "%s()\n", __func__);
-
- /* Establish default levels */
- lvl.ucDecoderLevel = TMHW_LEV_ADJ_DECLEV_DEFAULT;
- lvl.ucDecoderFM_Level = TMHW_LEV_ADJ_DECLEV_DEFAULT;
- lvl.ucMonoLevel = TMHW_LEV_ADJ_MONOLEV_DEFAULT;
- lvl.ucNICAM_Level = TMHW_LEV_ADJ_NICLEV_DEFAULT;
- lvl.ucSAP_Level = TMHW_LEV_ADJ_SAPLEV_DEFAULT;
- lvl.ucADC_Level = TMHW_LEV_ADJ_ADCLEV_DEFAULT;
- ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
- AUDIO_DEFAULT_CONTROL, sizeof(struct tmComResAudioDefaults),
- &lvl);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- /* Manually select the appropriate TV audio standard */
- if (port->encodernorm.id & V4L2_STD_NTSC) {
- tvaudio.std = TU_STANDARD_NTSC_M;
- tvaudio.country = 1;
- } else {
- tvaudio.std = TU_STANDARD_PAL_I;
- tvaudio.country = 44;
- }
-
- ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
- TU_STANDARD_CONTROL, sizeof(tvaudio), &tvaudio);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n",
- __func__, ret);
- return ret;
-}
-
-int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect)
-{
- struct saa7164_dev *dev = port->dev;
- struct tmComResTunerStandardAuto p;
- int ret;
-
- dprintk(DBGLVL_API, "%s(%d)\n", __func__, autodetect);
-
- /* Disable TV Audio autodetect if not already set (buggy) */
- if (autodetect)
- p.mode = TU_STANDARD_AUTO;
- else
- p.mode = TU_STANDARD_MANUAL;
- ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
- TU_STANDARD_AUTO_CONTROL, sizeof(p), &p);
- if (ret != SAA_OK)
- printk(KERN_ERR
- "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n",
- __func__, ret);
-
- return ret;
-}
-
-int saa7164_api_get_videomux(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int ret;
-
- ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, GET_CUR,
- SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- dprintk(DBGLVL_ENC, "%s() v_mux=%d\n",
- __func__, port->mux_input);
-
- return ret;
-}
-
-int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val)
-{
- struct saa7164_dev *dev = port->dev;
-
- u16 len = 0;
- u8 buf[256];
- int ret;
- u8 mas;
-
- dprintk(DBGLVL_API, "%s(nr=%d type=%d val=%x)\n", __func__,
- port->nr, port->type, val);
-
- if (port->nr == 0)
- mas = 0xd0;
- else
- mas = 0xe0;
-
- memset(buf, 0, sizeof(buf));
-
- buf[0x00] = 0x04;
- buf[0x01] = 0x00;
- buf[0x02] = 0x00;
- buf[0x03] = 0x00;
-
- buf[0x04] = 0x04;
- buf[0x05] = 0x00;
- buf[0x06] = 0x00;
- buf[0x07] = 0x00;
-
- buf[0x08] = reg;
- buf[0x09] = 0x26;
- buf[0x0a] = mas;
- buf[0x0b] = 0xb0;
-
- buf[0x0c] = val;
- buf[0x0d] = 0x00;
- buf[0x0e] = 0x00;
- buf[0x0f] = 0x00;
-
- ret = saa7164_cmd_send(dev, port->ifunit.unitid, GET_LEN,
- EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
- return -EIO;
- }
-
- ret = saa7164_cmd_send(dev, port->ifunit.unitid, SET_CUR,
- EXU_REGISTER_ACCESS_CONTROL, len, &buf);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
-#if 0
- saa7164_dumphex16(dev, buf, 16);
-#endif
- return ret == SAA_OK ? 0 : -EIO;
-}
-
-/* Disable the IF block AGC controls */
-int saa7164_api_configure_dif(struct saa7164_port *port, u32 std)
-{
- struct saa7164_dev *dev = port->dev;
- int ret = 0;
- u8 agc_disable;
-
- dprintk(DBGLVL_API, "%s(nr=%d, 0x%x)\n", __func__, port->nr, std);
-
- if (std & V4L2_STD_NTSC) {
- dprintk(DBGLVL_API, " NTSC\n");
- saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
- agc_disable = 0;
- } else if (std & V4L2_STD_PAL_I) {
- dprintk(DBGLVL_API, " PAL-I\n");
- saa7164_api_set_dif(port, 0x00, 0x08); /* Video Standard */
- agc_disable = 0;
- } else if (std & V4L2_STD_PAL_M) {
- dprintk(DBGLVL_API, " PAL-M\n");
- saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
- agc_disable = 0;
- } else if (std & V4L2_STD_PAL_N) {
- dprintk(DBGLVL_API, " PAL-N\n");
- saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
- agc_disable = 0;
- } else if (std & V4L2_STD_PAL_Nc) {
- dprintk(DBGLVL_API, " PAL-Nc\n");
- saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
- agc_disable = 0;
- } else if (std & V4L2_STD_PAL_B) {
- dprintk(DBGLVL_API, " PAL-B\n");
- saa7164_api_set_dif(port, 0x00, 0x02); /* Video Standard */
- agc_disable = 0;
- } else if (std & V4L2_STD_PAL_DK) {
- dprintk(DBGLVL_API, " PAL-DK\n");
- saa7164_api_set_dif(port, 0x00, 0x10); /* Video Standard */
- agc_disable = 0;
- } else if (std & V4L2_STD_SECAM_L) {
- dprintk(DBGLVL_API, " SECAM-L\n");
- saa7164_api_set_dif(port, 0x00, 0x20); /* Video Standard */
- agc_disable = 0;
- } else {
- /* Unknown standard, assume DTV */
- dprintk(DBGLVL_API, " Unknown (assuming DTV)\n");
- /* Undefinded Video Standard */
- saa7164_api_set_dif(port, 0x00, 0x80);
- agc_disable = 1;
- }
-
- saa7164_api_set_dif(port, 0x48, 0xa0); /* AGC Functions 1 */
- saa7164_api_set_dif(port, 0xc0, agc_disable); /* AGC Output Disable */
- saa7164_api_set_dif(port, 0x7c, 0x04); /* CVBS EQ */
- saa7164_api_set_dif(port, 0x04, 0x01); /* Active */
- msleep(100);
- saa7164_api_set_dif(port, 0x04, 0x00); /* Active (again) */
- msleep(100);
-
- return ret;
-}
-
-/* Ensure the dif is in the correct state for the operating mode
- * (analog / dtv). We only configure the diff through the analog encoder
- * so when we're in digital mode we need to find the appropriate encoder
- * and use it to configure the DIF.
- */
-int saa7164_api_initialize_dif(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- struct saa7164_port *p = NULL;
- int ret = -EINVAL;
- u32 std = 0;
-
- dprintk(DBGLVL_API, "%s(nr=%d type=%d)\n", __func__,
- port->nr, port->type);
-
- if (port->type == SAA7164_MPEG_ENCODER) {
- /* Pick any analog standard to init the diff.
- * we'll come back during encoder_init'
- * and set the correct standard if requried.
- */
- std = V4L2_STD_NTSC;
- } else
- if (port->type == SAA7164_MPEG_DVB) {
- if (port->nr == SAA7164_PORT_TS1)
- p = &dev->ports[SAA7164_PORT_ENC1];
- else
- p = &dev->ports[SAA7164_PORT_ENC2];
- } else
- if (port->type == SAA7164_MPEG_VBI) {
- std = V4L2_STD_NTSC;
- if (port->nr == SAA7164_PORT_VBI1)
- p = &dev->ports[SAA7164_PORT_ENC1];
- else
- p = &dev->ports[SAA7164_PORT_ENC2];
- } else
- BUG();
-
- if (p)
- ret = saa7164_api_configure_dif(p, std);
-
- return ret;
-}
-
-int saa7164_api_transition_port(struct saa7164_port *port, u8 mode)
-{
- struct saa7164_dev *dev = port->dev;
-
- int ret;
-
- dprintk(DBGLVL_API, "%s(nr=%d unitid=0x%x,%d)\n",
- __func__, port->nr, port->hwcfg.unitid, mode);
-
- ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR,
- SAA_STATE_CONTROL, sizeof(mode), &mode);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s(portnr %d unitid 0x%x) error, ret = 0x%x\n",
- __func__, port->nr, port->hwcfg.unitid, ret);
-
- return ret;
-}
-
-int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version)
-{
- int ret;
-
- ret = saa7164_cmd_send(dev, 0, GET_CUR,
- GET_FW_VERSION_CONTROL, sizeof(u32), version);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- return ret;
-}
-
-int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen)
-{
- u8 reg[] = { 0x0f, 0x00 };
-
- if (buflen < 128)
- return -ENOMEM;
-
- /* Assumption: Hauppauge eeprom is at 0xa0 on on bus 0 */
- /* TODO: Pull the details from the boards struct */
- return saa7164_api_i2c_read(&dev->i2c_bus[0], 0xa0 >> 1, sizeof(reg),
- &reg[0], 128, buf);
-}
-
-int saa7164_api_configure_port_vbi(struct saa7164_dev *dev,
- struct saa7164_port *port)
-{
- struct tmComResVBIFormatDescrHeader *fmt = &port->vbi_fmt_ntsc;
-
- dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex);
- dprintk(DBGLVL_API, " VideoStandard = 0x%x\n", fmt->VideoStandard);
- dprintk(DBGLVL_API, " StartLine = %d\n", fmt->StartLine);
- dprintk(DBGLVL_API, " EndLine = %d\n", fmt->EndLine);
- dprintk(DBGLVL_API, " FieldRate = %d\n", fmt->FieldRate);
- dprintk(DBGLVL_API, " bNumLines = %d\n", fmt->bNumLines);
-
- /* Cache the hardware configuration in the port */
-
- port->bufcounter = port->hwcfg.BARLocation;
- port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
- port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
- port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
- port->bufptr32l = port->hwcfg.BARLocation +
- (4 * sizeof(u32)) +
- (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
- port->bufptr32h = port->hwcfg.BARLocation +
- (4 * sizeof(u32)) +
- (sizeof(u32) * port->hwcfg.buffercount);
- port->bufptr64 = port->hwcfg.BARLocation +
- (4 * sizeof(u32)) +
- (sizeof(u32) * port->hwcfg.buffercount);
- dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
- port->hwcfg.BARLocation);
-
- dprintk(DBGLVL_API, " = VS_FORMAT_VBI (becomes dev->en[%d])\n",
- port->nr);
-
- return 0;
-}
-
-int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
- struct saa7164_port *port,
- struct tmComResTSFormatDescrHeader *tsfmt)
-{
- dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", tsfmt->bFormatIndex);
- dprintk(DBGLVL_API, " bDataOffset = 0x%x\n", tsfmt->bDataOffset);
- dprintk(DBGLVL_API, " bPacketLength= 0x%x\n", tsfmt->bPacketLength);
- dprintk(DBGLVL_API, " bStrideLength= 0x%x\n", tsfmt->bStrideLength);
- dprintk(DBGLVL_API, " bguid = (....)\n");
-
- /* Cache the hardware configuration in the port */
-
- port->bufcounter = port->hwcfg.BARLocation;
- port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
- port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
- port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
- port->bufptr32l = port->hwcfg.BARLocation +
- (4 * sizeof(u32)) +
- (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
- port->bufptr32h = port->hwcfg.BARLocation +
- (4 * sizeof(u32)) +
- (sizeof(u32) * port->hwcfg.buffercount);
- port->bufptr64 = port->hwcfg.BARLocation +
- (4 * sizeof(u32)) +
- (sizeof(u32) * port->hwcfg.buffercount);
- dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
- port->hwcfg.BARLocation);
-
- dprintk(DBGLVL_API, " = VS_FORMAT_MPEGTS (becomes dev->ts[%d])\n",
- port->nr);
-
- return 0;
-}
-
-int saa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev,
- struct saa7164_port *port,
- struct tmComResPSFormatDescrHeader *fmt)
-{
- dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex);
- dprintk(DBGLVL_API, " wPacketLength= 0x%x\n", fmt->wPacketLength);
- dprintk(DBGLVL_API, " wPackLength= 0x%x\n", fmt->wPackLength);
- dprintk(DBGLVL_API, " bPackDataType= 0x%x\n", fmt->bPackDataType);
-
- /* Cache the hardware configuration in the port */
- /* TODO: CHECK THIS in the port config */
- port->bufcounter = port->hwcfg.BARLocation;
- port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
- port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
- port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
- port->bufptr32l = port->hwcfg.BARLocation +
- (4 * sizeof(u32)) +
- (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
- port->bufptr32h = port->hwcfg.BARLocation +
- (4 * sizeof(u32)) +
- (sizeof(u32) * port->hwcfg.buffercount);
- port->bufptr64 = port->hwcfg.BARLocation +
- (4 * sizeof(u32)) +
- (sizeof(u32) * port->hwcfg.buffercount);
- dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
- port->hwcfg.BARLocation);
-
- dprintk(DBGLVL_API, " = VS_FORMAT_MPEGPS (becomes dev->enc[%d])\n",
- port->nr);
-
- return 0;
-}
-
-int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
-{
- struct saa7164_port *tsport = NULL;
- struct saa7164_port *encport = NULL;
- struct saa7164_port *vbiport = NULL;
- u32 idx, next_offset;
- int i;
- struct tmComResDescrHeader *hdr, *t;
- struct tmComResExtDevDescrHeader *exthdr;
- struct tmComResPathDescrHeader *pathhdr;
- struct tmComResAntTermDescrHeader *anttermhdr;
- struct tmComResTunerDescrHeader *tunerunithdr;
- struct tmComResDMATermDescrHeader *vcoutputtermhdr;
- struct tmComResTSFormatDescrHeader *tsfmt;
- struct tmComResPSFormatDescrHeader *psfmt;
- struct tmComResSelDescrHeader *psel;
- struct tmComResProcDescrHeader *pdh;
- struct tmComResAFeatureDescrHeader *afd;
- struct tmComResEncoderDescrHeader *edh;
- struct tmComResVBIFormatDescrHeader *vbifmt;
- u32 currpath = 0;
-
- dprintk(DBGLVL_API,
- "%s(?,?,%d) sizeof(struct tmComResDescrHeader) = %d bytes\n",
- __func__, len, (u32)sizeof(struct tmComResDescrHeader));
-
- for (idx = 0; idx < (len - sizeof(struct tmComResDescrHeader));) {
-
- hdr = (struct tmComResDescrHeader *)(buf + idx);
-
- if (hdr->type != CS_INTERFACE)
- return SAA_ERR_NOT_SUPPORTED;
-
- dprintk(DBGLVL_API, "@ 0x%x =\n", idx);
- switch (hdr->subtype) {
- case GENERAL_REQUEST:
- dprintk(DBGLVL_API, " GENERAL_REQUEST\n");
- break;
- case VC_TUNER_PATH:
- dprintk(DBGLVL_API, " VC_TUNER_PATH\n");
- pathhdr = (struct tmComResPathDescrHeader *)(buf + idx);
- dprintk(DBGLVL_API, " pathid = 0x%x\n",
- pathhdr->pathid);
- currpath = pathhdr->pathid;
- break;
- case VC_INPUT_TERMINAL:
- dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n");
- anttermhdr =
- (struct tmComResAntTermDescrHeader *)(buf + idx);
- dprintk(DBGLVL_API, " terminalid = 0x%x\n",
- anttermhdr->terminalid);
- dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
- anttermhdr->terminaltype);
- switch (anttermhdr->terminaltype) {
- case ITT_ANTENNA:
- dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
- break;
- case LINE_CONNECTOR:
- dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
- break;
- case SPDIF_CONNECTOR:
- dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
- break;
- case COMPOSITE_CONNECTOR:
- dprintk(DBGLVL_API,
- " = COMPOSITE_CONNECTOR\n");
- break;
- case SVIDEO_CONNECTOR:
- dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
- break;
- case COMPONENT_CONNECTOR:
- dprintk(DBGLVL_API,
- " = COMPONENT_CONNECTOR\n");
- break;
- case STANDARD_DMA:
- dprintk(DBGLVL_API, " = STANDARD_DMA\n");
- break;
- default:
- dprintk(DBGLVL_API, " = undefined (0x%x)\n",
- anttermhdr->terminaltype);
- }
- dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
- anttermhdr->assocterminal);
- dprintk(DBGLVL_API, " iterminal = 0x%x\n",
- anttermhdr->iterminal);
- dprintk(DBGLVL_API, " controlsize = 0x%x\n",
- anttermhdr->controlsize);
- break;
- case VC_OUTPUT_TERMINAL:
- dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n");
- vcoutputtermhdr =
- (struct tmComResDMATermDescrHeader *)(buf + idx);
- dprintk(DBGLVL_API, " unitid = 0x%x\n",
- vcoutputtermhdr->unitid);
- dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
- vcoutputtermhdr->terminaltype);
- switch (vcoutputtermhdr->terminaltype) {
- case ITT_ANTENNA:
- dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
- break;
- case LINE_CONNECTOR:
- dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
- break;
- case SPDIF_CONNECTOR:
- dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
- break;
- case COMPOSITE_CONNECTOR:
- dprintk(DBGLVL_API,
- " = COMPOSITE_CONNECTOR\n");
- break;
- case SVIDEO_CONNECTOR:
- dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
- break;
- case COMPONENT_CONNECTOR:
- dprintk(DBGLVL_API,
- " = COMPONENT_CONNECTOR\n");
- break;
- case STANDARD_DMA:
- dprintk(DBGLVL_API, " = STANDARD_DMA\n");
- break;
- default:
- dprintk(DBGLVL_API, " = undefined (0x%x)\n",
- vcoutputtermhdr->terminaltype);
- }
- dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
- vcoutputtermhdr->assocterminal);
- dprintk(DBGLVL_API, " sourceid = 0x%x\n",
- vcoutputtermhdr->sourceid);
- dprintk(DBGLVL_API, " iterminal = 0x%x\n",
- vcoutputtermhdr->iterminal);
- dprintk(DBGLVL_API, " BARLocation = 0x%x\n",
- vcoutputtermhdr->BARLocation);
- dprintk(DBGLVL_API, " flags = 0x%x\n",
- vcoutputtermhdr->flags);
- dprintk(DBGLVL_API, " interruptid = 0x%x\n",
- vcoutputtermhdr->interruptid);
- dprintk(DBGLVL_API, " buffercount = 0x%x\n",
- vcoutputtermhdr->buffercount);
- dprintk(DBGLVL_API, " metadatasize = 0x%x\n",
- vcoutputtermhdr->metadatasize);
- dprintk(DBGLVL_API, " controlsize = 0x%x\n",
- vcoutputtermhdr->controlsize);
- dprintk(DBGLVL_API, " numformats = 0x%x\n",
- vcoutputtermhdr->numformats);
-
- t = (struct tmComResDescrHeader *)
- ((struct tmComResDMATermDescrHeader *)(buf + idx));
- next_offset = idx + (vcoutputtermhdr->len);
- for (i = 0; i < vcoutputtermhdr->numformats; i++) {
- t = (struct tmComResDescrHeader *)
- (buf + next_offset);
- switch (t->subtype) {
- case VS_FORMAT_MPEG2TS:
- tsfmt =
- (struct tmComResTSFormatDescrHeader *)t;
- if (currpath == 1)
- tsport = &dev->ports[SAA7164_PORT_TS1];
- else
- tsport = &dev->ports[SAA7164_PORT_TS2];
- memcpy(&tsport->hwcfg, vcoutputtermhdr,
- sizeof(*vcoutputtermhdr));
- saa7164_api_configure_port_mpeg2ts(dev,
- tsport, tsfmt);
- break;
- case VS_FORMAT_MPEG2PS:
- psfmt =
- (struct tmComResPSFormatDescrHeader *)t;
- if (currpath == 1)
- encport = &dev->ports[SAA7164_PORT_ENC1];
- else
- encport = &dev->ports[SAA7164_PORT_ENC2];
- memcpy(&encport->hwcfg, vcoutputtermhdr,
- sizeof(*vcoutputtermhdr));
- saa7164_api_configure_port_mpeg2ps(dev,
- encport, psfmt);
- break;
- case VS_FORMAT_VBI:
- vbifmt =
- (struct tmComResVBIFormatDescrHeader *)t;
- if (currpath == 1)
- vbiport = &dev->ports[SAA7164_PORT_VBI1];
- else
- vbiport = &dev->ports[SAA7164_PORT_VBI2];
- memcpy(&vbiport->hwcfg, vcoutputtermhdr,
- sizeof(*vcoutputtermhdr));
- memcpy(&vbiport->vbi_fmt_ntsc, vbifmt,
- sizeof(*vbifmt));
- saa7164_api_configure_port_vbi(dev,
- vbiport);
- break;
- case VS_FORMAT_RDS:
- dprintk(DBGLVL_API,
- " = VS_FORMAT_RDS\n");
- break;
- case VS_FORMAT_UNCOMPRESSED:
- dprintk(DBGLVL_API,
- " = VS_FORMAT_UNCOMPRESSED\n");
- break;
- case VS_FORMAT_TYPE:
- dprintk(DBGLVL_API,
- " = VS_FORMAT_TYPE\n");
- break;
- default:
- dprintk(DBGLVL_API,
- " = undefined (0x%x)\n",
- t->subtype);
- }
- next_offset += t->len;
- }
-
- break;
- case TUNER_UNIT:
- dprintk(DBGLVL_API, " TUNER_UNIT\n");
- tunerunithdr =
- (struct tmComResTunerDescrHeader *)(buf + idx);
- dprintk(DBGLVL_API, " unitid = 0x%x\n",
- tunerunithdr->unitid);
- dprintk(DBGLVL_API, " sourceid = 0x%x\n",
- tunerunithdr->sourceid);
- dprintk(DBGLVL_API, " iunit = 0x%x\n",
- tunerunithdr->iunit);
- dprintk(DBGLVL_API, " tuningstandards = 0x%x\n",
- tunerunithdr->tuningstandards);
- dprintk(DBGLVL_API, " controlsize = 0x%x\n",
- tunerunithdr->controlsize);
- dprintk(DBGLVL_API, " controls = 0x%x\n",
- tunerunithdr->controls);
-
- if (tunerunithdr->unitid == tunerunithdr->iunit) {
- if (currpath == 1)
- encport = &dev->ports[SAA7164_PORT_ENC1];
- else
- encport = &dev->ports[SAA7164_PORT_ENC2];
- memcpy(&encport->tunerunit, tunerunithdr,
- sizeof(struct tmComResTunerDescrHeader));
- dprintk(DBGLVL_API,
- " (becomes dev->enc[%d] tuner)\n",
- encport->nr);
- }
- break;
- case VC_SELECTOR_UNIT:
- psel = (struct tmComResSelDescrHeader *)(buf + idx);
- dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n");
- dprintk(DBGLVL_API, " unitid = 0x%x\n",
- psel->unitid);
- dprintk(DBGLVL_API, " nrinpins = 0x%x\n",
- psel->nrinpins);
- dprintk(DBGLVL_API, " sourceid = 0x%x\n",
- psel->sourceid);
- break;
- case VC_PROCESSING_UNIT:
- pdh = (struct tmComResProcDescrHeader *)(buf + idx);
- dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n");
- dprintk(DBGLVL_API, " unitid = 0x%x\n",
- pdh->unitid);
- dprintk(DBGLVL_API, " sourceid = 0x%x\n",
- pdh->sourceid);
- dprintk(DBGLVL_API, " controlsize = 0x%x\n",
- pdh->controlsize);
- if (pdh->controlsize == 0x04) {
- if (currpath == 1)
- encport = &dev->ports[SAA7164_PORT_ENC1];
- else
- encport = &dev->ports[SAA7164_PORT_ENC2];
- memcpy(&encport->vidproc, pdh,
- sizeof(struct tmComResProcDescrHeader));
- dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n",
- encport->nr);
- }
- break;
- case FEATURE_UNIT:
- afd = (struct tmComResAFeatureDescrHeader *)(buf + idx);
- dprintk(DBGLVL_API, " FEATURE_UNIT\n");
- dprintk(DBGLVL_API, " unitid = 0x%x\n",
- afd->unitid);
- dprintk(DBGLVL_API, " sourceid = 0x%x\n",
- afd->sourceid);
- dprintk(DBGLVL_API, " controlsize = 0x%x\n",
- afd->controlsize);
- if (currpath == 1)
- encport = &dev->ports[SAA7164_PORT_ENC1];
- else
- encport = &dev->ports[SAA7164_PORT_ENC2];
- memcpy(&encport->audfeat, afd,
- sizeof(struct tmComResAFeatureDescrHeader));
- dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n",
- encport->nr);
- break;
- case ENCODER_UNIT:
- edh = (struct tmComResEncoderDescrHeader *)(buf + idx);
- dprintk(DBGLVL_API, " ENCODER_UNIT\n");
- dprintk(DBGLVL_API, " subtype = 0x%x\n", edh->subtype);
- dprintk(DBGLVL_API, " unitid = 0x%x\n", edh->unitid);
- dprintk(DBGLVL_API, " vsourceid = 0x%x\n",
- edh->vsourceid);
- dprintk(DBGLVL_API, " asourceid = 0x%x\n",
- edh->asourceid);
- dprintk(DBGLVL_API, " iunit = 0x%x\n", edh->iunit);
- if (edh->iunit == edh->unitid) {
- if (currpath == 1)
- encport = &dev->ports[SAA7164_PORT_ENC1];
- else
- encport = &dev->ports[SAA7164_PORT_ENC2];
- memcpy(&encport->encunit, edh,
- sizeof(struct tmComResEncoderDescrHeader));
- dprintk(DBGLVL_API,
- " (becomes dev->enc[%d])\n",
- encport->nr);
- }
- break;
- case EXTENSION_UNIT:
- dprintk(DBGLVL_API, " EXTENSION_UNIT\n");
- exthdr = (struct tmComResExtDevDescrHeader *)(buf + idx);
- dprintk(DBGLVL_API, " unitid = 0x%x\n",
- exthdr->unitid);
- dprintk(DBGLVL_API, " deviceid = 0x%x\n",
- exthdr->deviceid);
- dprintk(DBGLVL_API, " devicetype = 0x%x\n",
- exthdr->devicetype);
- if (exthdr->devicetype & 0x1)
- dprintk(DBGLVL_API, " = Decoder Device\n");
- if (exthdr->devicetype & 0x2)
- dprintk(DBGLVL_API, " = GPIO Source\n");
- if (exthdr->devicetype & 0x4)
- dprintk(DBGLVL_API, " = Video Decoder\n");
- if (exthdr->devicetype & 0x8)
- dprintk(DBGLVL_API, " = Audio Decoder\n");
- if (exthdr->devicetype & 0x20)
- dprintk(DBGLVL_API, " = Crossbar\n");
- if (exthdr->devicetype & 0x40)
- dprintk(DBGLVL_API, " = Tuner\n");
- if (exthdr->devicetype & 0x80)
- dprintk(DBGLVL_API, " = IF PLL\n");
- if (exthdr->devicetype & 0x100)
- dprintk(DBGLVL_API, " = Demodulator\n");
- if (exthdr->devicetype & 0x200)
- dprintk(DBGLVL_API, " = RDS Decoder\n");
- if (exthdr->devicetype & 0x400)
- dprintk(DBGLVL_API, " = Encoder\n");
- if (exthdr->devicetype & 0x800)
- dprintk(DBGLVL_API, " = IR Decoder\n");
- if (exthdr->devicetype & 0x1000)
- dprintk(DBGLVL_API, " = EEPROM\n");
- if (exthdr->devicetype & 0x2000)
- dprintk(DBGLVL_API,
- " = VBI Decoder\n");
- if (exthdr->devicetype & 0x10000)
- dprintk(DBGLVL_API,
- " = Streaming Device\n");
- if (exthdr->devicetype & 0x20000)
- dprintk(DBGLVL_API,
- " = DRM Device\n");
- if (exthdr->devicetype & 0x40000000)
- dprintk(DBGLVL_API,
- " = Generic Device\n");
- if (exthdr->devicetype & 0x80000000)
- dprintk(DBGLVL_API,
- " = Config Space Device\n");
- dprintk(DBGLVL_API, " numgpiopins = 0x%x\n",
- exthdr->numgpiopins);
- dprintk(DBGLVL_API, " numgpiogroups = 0x%x\n",
- exthdr->numgpiogroups);
- dprintk(DBGLVL_API, " controlsize = 0x%x\n",
- exthdr->controlsize);
- if (exthdr->devicetype & 0x80) {
- if (currpath == 1)
- encport = &dev->ports[SAA7164_PORT_ENC1];
- else
- encport = &dev->ports[SAA7164_PORT_ENC2];
- memcpy(&encport->ifunit, exthdr,
- sizeof(struct tmComResExtDevDescrHeader));
- dprintk(DBGLVL_API,
- " (becomes dev->enc[%d])\n",
- encport->nr);
- }
- break;
- case PVC_INFRARED_UNIT:
- dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n");
- break;
- case DRM_UNIT:
- dprintk(DBGLVL_API, " DRM_UNIT\n");
- break;
- default:
- dprintk(DBGLVL_API, "default %d\n", hdr->subtype);
- }
-
- dprintk(DBGLVL_API, " 1.%x\n", hdr->len);
- dprintk(DBGLVL_API, " 2.%x\n", hdr->type);
- dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype);
- dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid);
-
- idx += hdr->len;
- }
-
- return 0;
-}
-
-int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
-{
- int ret;
- u32 buflen = 0;
- u8 *buf;
-
- dprintk(DBGLVL_API, "%s()\n", __func__);
-
- /* Get the total descriptor length */
- ret = saa7164_cmd_send(dev, 0, GET_LEN,
- GET_DESCRIPTORS_CONTROL, sizeof(buflen), &buflen);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
-
- dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n",
- __func__, buflen);
-
- /* Allocate enough storage for all of the descs */
- buf = kzalloc(buflen, GFP_KERNEL);
- if (!buf)
- return SAA_ERR_NO_RESOURCES;
-
- /* Retrieve them */
- ret = saa7164_cmd_send(dev, 0, GET_CUR,
- GET_DESCRIPTORS_CONTROL, buflen, buf);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
- goto out;
- }
-
- if (saa_debug & DBGLVL_API)
- saa7164_dumphex16(dev, buf, (buflen/16)*16);
-
- saa7164_api_dump_subdevs(dev, buf, buflen);
-
-out:
- kfree(buf);
- return ret;
-}
-
-int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
- u32 datalen, u8 *data)
-{
- struct saa7164_dev *dev = bus->dev;
- u16 len = 0;
- int unitid;
- u8 buf[256];
- int ret;
-
- dprintk(DBGLVL_API, "%s()\n", __func__);
-
- if (reglen > 4)
- return -EIO;
-
- /* Prepare the send buffer */
- /* Bytes 00-03 source register length
- * 04-07 source bytes to read
- * 08... register address
- */
- memset(buf, 0, sizeof(buf));
- memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen);
- *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
- *((u32 *)(buf + 1 * sizeof(u32))) = datalen;
-
- unitid = saa7164_i2caddr_to_unitid(bus, addr);
- if (unitid < 0) {
- printk(KERN_ERR
- "%s() error, cannot translate regaddr 0x%x to unitid\n",
- __func__, addr);
- return -EIO;
- }
-
- ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
- EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
- return -EIO;
- }
-
- dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
-
- if (saa_debug & DBGLVL_I2C)
- saa7164_dumphex16(dev, buf, 2 * 16);
-
- ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR,
- EXU_REGISTER_ACCESS_CONTROL, len, &buf);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
- else {
- if (saa_debug & DBGLVL_I2C)
- saa7164_dumphex16(dev, buf, sizeof(buf));
- memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen);
- }
-
- return ret == SAA_OK ? 0 : -EIO;
-}
-
-/* For a given 8 bit i2c address device, write the buffer */
-int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
- u8 *data)
-{
- struct saa7164_dev *dev = bus->dev;
- u16 len = 0;
- int unitid;
- int reglen;
- u8 buf[256];
- int ret;
-
- dprintk(DBGLVL_API, "%s()\n", __func__);
-
- if ((datalen == 0) || (datalen > 232))
- return -EIO;
-
- memset(buf, 0, sizeof(buf));
-
- unitid = saa7164_i2caddr_to_unitid(bus, addr);
- if (unitid < 0) {
- printk(KERN_ERR
- "%s() error, cannot translate regaddr 0x%x to unitid\n",
- __func__, addr);
- return -EIO;
- }
-
- reglen = saa7164_i2caddr_to_reglen(bus, addr);
- if (reglen < 0) {
- printk(KERN_ERR
- "%s() error, cannot translate regaddr to reglen\n",
- __func__);
- return -EIO;
- }
-
- ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
- EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
- return -EIO;
- }
-
- dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
-
- /* Prepare the send buffer */
- /* Bytes 00-03 dest register length
- * 04-07 dest bytes to write
- * 08... register address
- */
- *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
- *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen;
- memcpy((buf + 2 * sizeof(u32)), data, datalen);
-
- if (saa_debug & DBGLVL_I2C)
- saa7164_dumphex16(dev, buf, sizeof(buf));
-
- ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR,
- EXU_REGISTER_ACCESS_CONTROL, len, &buf);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
-
- return ret == SAA_OK ? 0 : -EIO;
-}
-
-int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
- u8 pin, u8 state)
-{
- int ret;
- struct tmComResGPIO t;
-
- dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n",
- __func__, unitid, pin, state);
-
- if ((pin > 7) || (state > 2))
- return SAA_ERR_BAD_PARAMETER;
-
- t.pin = pin;
- t.state = state;
-
- ret = saa7164_cmd_send(dev, unitid, SET_CUR,
- EXU_GPIO_CONTROL, sizeof(t), &t);
- if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n",
- __func__, ret);
-
- return ret;
-}
-
-int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid,
- u8 pin)
-{
- return saa7164_api_modify_gpio(dev, unitid, pin, 1);
-}
-
-int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid,
- u8 pin)
-{
- return saa7164_api_modify_gpio(dev, unitid, pin, 0);
-}
-
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c
deleted file mode 100644
index 66696fa8341..00000000000
--- a/drivers/media/video/saa7164/saa7164-buffer.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Driver for the NXP SAA7164 PCIe bridge
- *
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/slab.h>
-
-#include "saa7164.h"
-
-/* The PCI address space for buffer handling looks like this:
- *
- * +-u32 wide-------------+
- * | +
- * +-u64 wide------------------------------------+
- * + +
- * +----------------------+
- * | CurrentBufferPtr + Pointer to current PCI buffer >-+
- * +----------------------+ |
- * | Unused + |
- * +----------------------+ |
- * | Pitch + = 188 (bytes) |
- * +----------------------+ |
- * | PCI buffer size + = pitch * number of lines (312) |
- * +----------------------+ |
- * |0| Buf0 Write Offset + |
- * +----------------------+ v
- * |1| Buf1 Write Offset + |
- * +----------------------+ |
- * |2| Buf2 Write Offset + |
- * +----------------------+ |
- * |3| Buf3 Write Offset + |
- * +----------------------+ |
- * ... More write offsets |
- * +---------------------------------------------+ |
- * +0| set of ptrs to PCI pagetables + |
- * +---------------------------------------------+ |
- * +1| set of ptrs to PCI pagetables + <--------+
- * +---------------------------------------------+
- * +2| set of ptrs to PCI pagetables +
- * +---------------------------------------------+
- * +3| set of ptrs to PCI pagetables + >--+
- * +---------------------------------------------+ |
- * ... More buffer pointers | +----------------+
- * +->| pt[0] TS data |
- * | +----------------+
- * |
- * | +----------------+
- * +->| pt[1] TS data |
- * | +----------------+
- * | etc
- */
-
-void saa7164_buffer_display(struct saa7164_buffer *buf)
-{
- struct saa7164_dev *dev = buf->port->dev;
- int i;
-
- dprintk(DBGLVL_BUF, "%s() buffer @ 0x%p nr=%d\n",
- __func__, buf, buf->idx);
- dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08llx len = 0x%x\n",
- buf->cpu, (long long)buf->dma, buf->pci_size);
- dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08llx len = 0x%x\n",
- buf->pt_cpu, (long long)buf->pt_dma, buf->pt_size);
-
- /* Format the Page Table Entries to point into the data buffer */
- for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) {
-
- dprintk(DBGLVL_BUF, " pt[%02d] = 0x%p -> 0x%llx\n",
- i, buf->pt_cpu, (u64)*(buf->pt_cpu));
-
- }
-}
-/* Allocate a new buffer structure and associated PCI space in bytes.
- * len must be a multiple of sizeof(u64)
- */
-struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port,
- u32 len)
-{
- struct tmHWStreamParameters *params = &port->hw_streamingparams;
- struct saa7164_buffer *buf = NULL;
- struct saa7164_dev *dev = port->dev;
- int i;
-
- if ((len == 0) || (len >= 65536) || (len % sizeof(u64))) {
- log_warn("%s() SAA_ERR_BAD_PARAMETER\n", __func__);
- goto ret;
- }
-
- buf = kzalloc(sizeof(struct saa7164_buffer), GFP_KERNEL);
- if (!buf) {
- log_warn("%s() SAA_ERR_NO_RESOURCES\n", __func__);
- goto ret;
- }
-
- buf->idx = -1;
- buf->port = port;
- buf->flags = SAA7164_BUFFER_FREE;
- buf->pos = 0;
- buf->actual_size = params->pitch * params->numberoflines;
- buf->crc = 0;
- /* TODO: arg len is being ignored */
- buf->pci_size = SAA7164_PT_ENTRIES * 0x1000;
- buf->pt_size = (SAA7164_PT_ENTRIES * sizeof(u64)) + 0x1000;
-
- /* Allocate contiguous memory */
- buf->cpu = pci_alloc_consistent(port->dev->pci, buf->pci_size,
- &buf->dma);
- if (!buf->cpu)
- goto fail1;
-
- buf->pt_cpu = pci_alloc_consistent(port->dev->pci, buf->pt_size,
- &buf->pt_dma);
- if (!buf->pt_cpu)
- goto fail2;
-
- /* init the buffers to a known pattern, easier during debugging */
- memset_io(buf->cpu, 0xff, buf->pci_size);
- buf->crc = crc32(0, buf->cpu, buf->actual_size);
- memset_io(buf->pt_cpu, 0xff, buf->pt_size);
-
- dprintk(DBGLVL_BUF, "%s() allocated buffer @ 0x%p (%d pageptrs)\n",
- __func__, buf, params->numpagetables);
- dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08lx len = 0x%x\n",
- buf->cpu, (long)buf->dma, buf->pci_size);
- dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08lx len = 0x%x\n",
- buf->pt_cpu, (long)buf->pt_dma, buf->pt_size);
-
- /* Format the Page Table Entries to point into the data buffer */
- for (i = 0 ; i < params->numpagetables; i++) {
-
- *(buf->pt_cpu + i) = buf->dma + (i * 0x1000); /* TODO */
- dprintk(DBGLVL_BUF, " pt[%02d] = 0x%p -> 0x%llx\n",
- i, buf->pt_cpu, (u64)*(buf->pt_cpu));
-
- }
-
- goto ret;
-
-fail2:
- pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma);
-fail1:
- kfree(buf);
-
- buf = NULL;
-ret:
- return buf;
-}
-
-int saa7164_buffer_dealloc(struct saa7164_buffer *buf)
-{
- struct saa7164_dev *dev;
-
- if (!buf || !buf->port)
- return SAA_ERR_BAD_PARAMETER;
- dev = buf->port->dev;
-
- dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n",
- __func__, buf);
-
- if (buf->flags != SAA7164_BUFFER_FREE)
- log_warn(" freeing a non-free buffer\n");
-
- pci_free_consistent(dev->pci, buf->pci_size, buf->cpu, buf->dma);
- pci_free_consistent(dev->pci, buf->pt_size, buf->pt_cpu, buf->pt_dma);
-
- kfree(buf);
-
- return SAA_OK;
-}
-
-int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i)
-{
- struct saa7164_dev *dev = port->dev;
-
- if ((i < 0) || (i >= port->hwcfg.buffercount))
- return -EINVAL;
-
- dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i);
-
- saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
-
- return 0;
-}
-
-/* Write a buffer into the hardware */
-int saa7164_buffer_activate(struct saa7164_buffer *buf, int i)
-{
- struct saa7164_port *port = buf->port;
- struct saa7164_dev *dev = port->dev;
-
- if ((i < 0) || (i >= port->hwcfg.buffercount))
- return -EINVAL;
-
- dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i);
-
- buf->idx = i; /* Note of which buffer list index position we occupy */
- buf->flags = SAA7164_BUFFER_BUSY;
- buf->pos = 0;
-
- /* TODO: Review this in light of 32v64 assignments */
- saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
- saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i), buf->pt_dma);
- saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0);
-
- dprintk(DBGLVL_BUF, " buf[%d] offset 0x%llx (0x%x) "
- "buf 0x%llx/%llx (0x%x/%x) nr=%d\n",
- buf->idx,
- (u64)port->bufoffset + (i * sizeof(u32)),
- saa7164_readl(port->bufoffset + (sizeof(u32) * i)),
- (u64)port->bufptr32h + ((sizeof(u32) * 2) * i),
- (u64)port->bufptr32l + ((sizeof(u32) * 2) * i),
- saa7164_readl(port->bufptr32h + ((sizeof(u32) * i) * 2)),
- saa7164_readl(port->bufptr32l + ((sizeof(u32) * i) * 2)),
- buf->idx);
-
- return 0;
-}
-
-int saa7164_buffer_cfg_port(struct saa7164_port *port)
-{
- struct tmHWStreamParameters *params = &port->hw_streamingparams;
- struct saa7164_dev *dev = port->dev;
- struct saa7164_buffer *buf;
- struct list_head *c, *n;
- int i = 0;
-
- dprintk(DBGLVL_BUF, "%s(port=%d)\n", __func__, port->nr);
-
- saa7164_writel(port->bufcounter, 0);
- saa7164_writel(port->pitch, params->pitch);
- saa7164_writel(port->bufsize, params->pitch * params->numberoflines);
-
- dprintk(DBGLVL_BUF, " configured:\n");
- dprintk(DBGLVL_BUF, " lmmio 0x%p\n", dev->lmmio);
- dprintk(DBGLVL_BUF, " bufcounter 0x%x = 0x%x\n", port->bufcounter,
- saa7164_readl(port->bufcounter));
-
- dprintk(DBGLVL_BUF, " pitch 0x%x = %d\n", port->pitch,
- saa7164_readl(port->pitch));
-
- dprintk(DBGLVL_BUF, " bufsize 0x%x = %d\n", port->bufsize,
- saa7164_readl(port->bufsize));
-
- dprintk(DBGLVL_BUF, " buffercount = %d\n", port->hwcfg.buffercount);
- dprintk(DBGLVL_BUF, " bufoffset = 0x%x\n", port->bufoffset);
- dprintk(DBGLVL_BUF, " bufptr32h = 0x%x\n", port->bufptr32h);
- dprintk(DBGLVL_BUF, " bufptr32l = 0x%x\n", port->bufptr32l);
-
- /* Poke the buffers and offsets into PCI space */
- mutex_lock(&port->dmaqueue_lock);
- list_for_each_safe(c, n, &port->dmaqueue.list) {
- buf = list_entry(c, struct saa7164_buffer, list);
-
- if (buf->flags != SAA7164_BUFFER_FREE)
- BUG();
-
- /* Place the buffer in the h/w queue */
- saa7164_buffer_activate(buf, i);
-
- /* Don't exceed the device maximum # bufs */
- if (i++ > port->hwcfg.buffercount)
- BUG();
-
- }
- mutex_unlock(&port->dmaqueue_lock);
-
- return 0;
-}
-
-struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev,
- u32 len)
-{
- struct saa7164_user_buffer *buf;
-
- buf = kzalloc(sizeof(struct saa7164_user_buffer), GFP_KERNEL);
- if (!buf)
- return NULL;
-
- buf->data = kzalloc(len, GFP_KERNEL);
-
- if (!buf->data) {
- kfree(buf);
- return NULL;
- }
-
- buf->actual_size = len;
- buf->pos = 0;
- buf->crc = 0;
-
- dprintk(DBGLVL_BUF, "%s() allocated user buffer @ 0x%p\n",
- __func__, buf);
-
- return buf;
-}
-
-void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf)
-{
- if (!buf)
- return;
-
- kfree(buf->data);
- buf->data = NULL;
-
- kfree(buf);
-}
-
diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c
deleted file mode 100644
index a7f58a99875..00000000000
--- a/drivers/media/video/saa7164/saa7164-bus.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Driver for the NXP SAA7164 PCIe bridge
- *
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "saa7164.h"
-
-/* The message bus to/from the firmware is a ring buffer in PCI address
- * space. Establish the defaults.
- */
-int saa7164_bus_setup(struct saa7164_dev *dev)
-{
- struct tmComResBusInfo *b = &dev->bus;
-
- mutex_init(&b->lock);
-
- b->Type = TYPE_BUS_PCIe;
- b->m_wMaxReqSize = SAA_DEVICE_MAXREQUESTSIZE;
-
- b->m_pdwSetRing = (u8 *)(dev->bmmio +
- ((u32)dev->busdesc.CommandRing));
-
- b->m_dwSizeSetRing = SAA_DEVICE_BUFFERBLOCKSIZE;
-
- b->m_pdwGetRing = (u8 *)(dev->bmmio +
- ((u32)dev->busdesc.ResponseRing));
-
- b->m_dwSizeGetRing = SAA_DEVICE_BUFFERBLOCKSIZE;
-
- b->m_dwSetWritePos = ((u32)dev->intfdesc.BARLocation) +
- (2 * sizeof(u64));
- b->m_dwSetReadPos = b->m_dwSetWritePos + (1 * sizeof(u32));
-
- b->m_dwGetWritePos = b->m_dwSetWritePos + (2 * sizeof(u32));
- b->m_dwGetReadPos = b->m_dwSetWritePos + (3 * sizeof(u32));
-
- return 0;
-}
-
-void saa7164_bus_dump(struct saa7164_dev *dev)
-{
- struct tmComResBusInfo *b = &dev->bus;
-
- dprintk(DBGLVL_BUS, "Dumping the bus structure:\n");
- dprintk(DBGLVL_BUS, " .type = %d\n", b->Type);
- dprintk(DBGLVL_BUS, " .dev->bmmio = 0x%p\n", dev->bmmio);
- dprintk(DBGLVL_BUS, " .m_wMaxReqSize = 0x%x\n", b->m_wMaxReqSize);
- dprintk(DBGLVL_BUS, " .m_pdwSetRing = 0x%p\n", b->m_pdwSetRing);
- dprintk(DBGLVL_BUS, " .m_dwSizeSetRing = 0x%x\n", b->m_dwSizeSetRing);
- dprintk(DBGLVL_BUS, " .m_pdwGetRing = 0x%p\n", b->m_pdwGetRing);
- dprintk(DBGLVL_BUS, " .m_dwSizeGetRing = 0x%x\n", b->m_dwSizeGetRing);
-
- dprintk(DBGLVL_BUS, " .m_dwSetReadPos = 0x%x (0x%08x)\n",
- b->m_dwSetReadPos, saa7164_readl(b->m_dwSetReadPos));
-
- dprintk(DBGLVL_BUS, " .m_dwSetWritePos = 0x%x (0x%08x)\n",
- b->m_dwSetWritePos, saa7164_readl(b->m_dwSetWritePos));
-
- dprintk(DBGLVL_BUS, " .m_dwGetReadPos = 0x%x (0x%08x)\n",
- b->m_dwGetReadPos, saa7164_readl(b->m_dwGetReadPos));
-
- dprintk(DBGLVL_BUS, " .m_dwGetWritePos = 0x%x (0x%08x)\n",
- b->m_dwGetWritePos, saa7164_readl(b->m_dwGetWritePos));
-
-}
-
-/* Intensionally throw a BUG() if the state of the message bus looks corrupt */
-void saa7164_bus_verify(struct saa7164_dev *dev)
-{
- struct tmComResBusInfo *b = &dev->bus;
- int bug = 0;
-
- if (saa7164_readl(b->m_dwSetReadPos) > b->m_dwSizeSetRing)
- bug++;
-
- if (saa7164_readl(b->m_dwSetWritePos) > b->m_dwSizeSetRing)
- bug++;
-
- if (saa7164_readl(b->m_dwGetReadPos) > b->m_dwSizeGetRing)
- bug++;
-
- if (saa7164_readl(b->m_dwGetWritePos) > b->m_dwSizeGetRing)
- bug++;
-
- if (bug) {
- saa_debug = 0xffff; /* Ensure we get the bus dump */
- saa7164_bus_dump(dev);
- saa_debug = 1024; /* Ensure we get the bus dump */
- BUG();
- }
-}
-
-void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo* m,
- void *buf)
-{
- dprintk(DBGLVL_BUS, "Dumping msg structure:\n");
- dprintk(DBGLVL_BUS, " .id = %d\n", m->id);
- dprintk(DBGLVL_BUS, " .flags = 0x%x\n", m->flags);
- dprintk(DBGLVL_BUS, " .size = 0x%x\n", m->size);
- dprintk(DBGLVL_BUS, " .command = 0x%x\n", m->command);
- dprintk(DBGLVL_BUS, " .controlselector = 0x%x\n", m->controlselector);
- dprintk(DBGLVL_BUS, " .seqno = %d\n", m->seqno);
- if (buf)
- dprintk(DBGLVL_BUS, " .buffer (ignored)\n");
-}
-
-/*
- * Places a command or a response on the bus. The implementation does not
- * know if it is a command or a response it just places the data on the
- * bus depending on the bus information given in the struct tmComResBusInfo
- * structure. If the command or response does not fit into the bus ring
- * buffer it will be refused.
- *
- * Return Value:
- * SAA_OK The function executed successfully.
- * < 0 One or more members are not initialized.
- */
-int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg,
- void *buf)
-{
- struct tmComResBusInfo *bus = &dev->bus;
- u32 bytes_to_write, free_write_space, timeout, curr_srp, curr_swp;
- u32 new_swp, space_rem;
- int ret = SAA_ERR_BAD_PARAMETER;
-
- if (!msg) {
- printk(KERN_ERR "%s() !msg\n", __func__);
- return SAA_ERR_BAD_PARAMETER;
- }
-
- dprintk(DBGLVL_BUS, "%s()\n", __func__);
-
- saa7164_bus_verify(dev);
-
- msg->size = cpu_to_le16(msg->size);
- msg->command = cpu_to_le32(msg->command);
- msg->controlselector = cpu_to_le16(msg->controlselector);
-
- if (msg->size > dev->bus.m_wMaxReqSize) {
- printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n",
- __func__);
- return SAA_ERR_BAD_PARAMETER;
- }
-
- if ((msg->size > 0) && (buf == NULL)) {
- printk(KERN_ERR "%s() Missing message buffer\n", __func__);
- return SAA_ERR_BAD_PARAMETER;
- }
-
- /* Lock the bus from any other access */
- mutex_lock(&bus->lock);
-
- bytes_to_write = sizeof(*msg) + msg->size;
- free_write_space = 0;
- timeout = SAA_BUS_TIMEOUT;
- curr_srp = le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos));
- curr_swp = le32_to_cpu(saa7164_readl(bus->m_dwSetWritePos));
-
- /* Deal with ring wrapping issues */
- if (curr_srp > curr_swp)
- /* Deal with the wrapped ring */
- free_write_space = curr_srp - curr_swp;
- else
- /* The ring has not wrapped yet */
- free_write_space = (curr_srp + bus->m_dwSizeSetRing) - curr_swp;
-
- dprintk(DBGLVL_BUS, "%s() bytes_to_write = %d\n", __func__,
- bytes_to_write);
-
- dprintk(DBGLVL_BUS, "%s() free_write_space = %d\n", __func__,
- free_write_space);
-
- dprintk(DBGLVL_BUS, "%s() curr_srp = %x\n", __func__, curr_srp);
- dprintk(DBGLVL_BUS, "%s() curr_swp = %x\n", __func__, curr_swp);
-
- /* Process the msg and write the content onto the bus */
- while (bytes_to_write >= free_write_space) {
-
- if (timeout-- == 0) {
- printk(KERN_ERR "%s() bus timeout\n", __func__);
- ret = SAA_ERR_NO_RESOURCES;
- goto out;
- }
-
- /* TODO: Review this delay, efficient? */
- /* Wait, allowing the hardware fetch time */
- mdelay(1);
-
- /* Check the space usage again */
- curr_srp = le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos));
-
- /* Deal with ring wrapping issues */
- if (curr_srp > curr_swp)
- /* Deal with the wrapped ring */
- free_write_space = curr_srp - curr_swp;
- else
- /* Read didn't wrap around the buffer */
- free_write_space = (curr_srp + bus->m_dwSizeSetRing) -
- curr_swp;
-
- }
-
- /* Calculate the new write position */
- new_swp = curr_swp + bytes_to_write;
-
- dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp);
- dprintk(DBGLVL_BUS, "%s() bus->m_dwSizeSetRing = %x\n", __func__,
- bus->m_dwSizeSetRing);
-
- /* Mental Note: line 462 tmmhComResBusPCIe.cpp */
-
- /* Check if we're going to wrap again */
- if (new_swp > bus->m_dwSizeSetRing) {
-
- /* Ring wraps */
- new_swp -= bus->m_dwSizeSetRing;
-
- space_rem = bus->m_dwSizeSetRing - curr_swp;
-
- dprintk(DBGLVL_BUS, "%s() space_rem = %x\n", __func__,
- space_rem);
-
- dprintk(DBGLVL_BUS, "%s() sizeof(*msg) = %d\n", __func__,
- (u32)sizeof(*msg));
-
- if (space_rem < sizeof(*msg)) {
- dprintk(DBGLVL_BUS, "%s() tr4\n", __func__);
-
- /* Split the msg into pieces as the ring wraps */
- memcpy(bus->m_pdwSetRing + curr_swp, msg, space_rem);
- memcpy(bus->m_pdwSetRing, (u8 *)msg + space_rem,
- sizeof(*msg) - space_rem);
-
- memcpy(bus->m_pdwSetRing + sizeof(*msg) - space_rem,
- buf, msg->size);
-
- } else if (space_rem == sizeof(*msg)) {
- dprintk(DBGLVL_BUS, "%s() tr5\n", __func__);
-
- /* Additional data at the beginning of the ring */
- memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
- memcpy(bus->m_pdwSetRing, buf, msg->size);
-
- } else {
- /* Additional data wraps around the ring */
- memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
- if (msg->size > 0) {
- memcpy(bus->m_pdwSetRing + curr_swp +
- sizeof(*msg), buf, space_rem -
- sizeof(*msg));
- memcpy(bus->m_pdwSetRing, (u8 *)buf +
- space_rem - sizeof(*msg),
- bytes_to_write - space_rem);
- }
-
- }
-
- } /* (new_swp > bus->m_dwSizeSetRing) */
- else {
- dprintk(DBGLVL_BUS, "%s() tr6\n", __func__);
-
- /* The ring buffer doesn't wrap, two simple copies */
- memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
- memcpy(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf,
- msg->size);
- }
-
- dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp);
-
- /* Update the bus write position */
- saa7164_writel(bus->m_dwSetWritePos, cpu_to_le32(new_swp));
- ret = SAA_OK;
-
-out:
- saa7164_bus_dump(dev);
- mutex_unlock(&bus->lock);
- saa7164_bus_verify(dev);
- return ret;
-}
-
-/*
- * Receive a command or a response from the bus. The implementation does not
- * know if it is a command or a response it simply dequeues the data,
- * depending on the bus information given in the struct tmComResBusInfo
- * structure.
- *
- * Return Value:
- * 0 The function executed successfully.
- * < 0 One or more members are not initialized.
- */
-int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
- void *buf, int peekonly)
-{
- struct tmComResBusInfo *bus = &dev->bus;
- u32 bytes_to_read, write_distance, curr_grp, curr_gwp,
- new_grp, buf_size, space_rem;
- struct tmComResInfo msg_tmp;
- int ret = SAA_ERR_BAD_PARAMETER;
-
- saa7164_bus_verify(dev);
-
- if (msg == NULL)
- return ret;
-
- if (msg->size > dev->bus.m_wMaxReqSize) {
- printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n",
- __func__);
- return ret;
- }
-
- if ((peekonly == 0) && (msg->size > 0) && (buf == NULL)) {
- printk(KERN_ERR
- "%s() Missing msg buf, size should be %d bytes\n",
- __func__, msg->size);
- return ret;
- }
-
- mutex_lock(&bus->lock);
-
- /* Peek the bus to see if a msg exists, if it's not what we're expecting
- * then return cleanly else read the message from the bus.
- */
- curr_gwp = le32_to_cpu(saa7164_readl(bus->m_dwGetWritePos));
- curr_grp = le32_to_cpu(saa7164_readl(bus->m_dwGetReadPos));
-
- if (curr_gwp == curr_grp) {
- ret = SAA_ERR_EMPTY;
- goto out;
- }
-
- bytes_to_read = sizeof(*msg);
-
- /* Calculate write distance to current read position */
- write_distance = 0;
- if (curr_gwp >= curr_grp)
- /* Write doesn't wrap around the ring */
- write_distance = curr_gwp - curr_grp;
- else
- /* Write wraps around the ring */
- write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp;
-
- if (bytes_to_read > write_distance) {
- printk(KERN_ERR "%s() No message/response found\n", __func__);
- ret = SAA_ERR_INVALID_COMMAND;
- goto out;
- }
-
- /* Calculate the new read position */
- new_grp = curr_grp + bytes_to_read;
- if (new_grp > bus->m_dwSizeGetRing) {
-
- /* Ring wraps */
- new_grp -= bus->m_dwSizeGetRing;
- space_rem = bus->m_dwSizeGetRing - curr_grp;
-
- memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, space_rem);
- memcpy((u8 *)&msg_tmp + space_rem, bus->m_pdwGetRing,
- bytes_to_read - space_rem);
-
- } else {
- /* No wrapping */
- memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, bytes_to_read);
- }
-
- /* No need to update the read positions, because this was a peek */
- /* If the caller specifically want to peek, return */
- if (peekonly) {
- memcpy(msg, &msg_tmp, sizeof(*msg));
- goto peekout;
- }
-
- /* Check if the command/response matches what is expected */
- if ((msg_tmp.id != msg->id) || (msg_tmp.command != msg->command) ||
- (msg_tmp.controlselector != msg->controlselector) ||
- (msg_tmp.seqno != msg->seqno) || (msg_tmp.size != msg->size)) {
-
- printk(KERN_ERR "%s() Unexpected msg miss-match\n", __func__);
- saa7164_bus_dumpmsg(dev, msg, buf);
- saa7164_bus_dumpmsg(dev, &msg_tmp, NULL);
- ret = SAA_ERR_INVALID_COMMAND;
- goto out;
- }
-
- /* Get the actual command and response from the bus */
- buf_size = msg->size;
-
- bytes_to_read = sizeof(*msg) + msg->size;
- /* Calculate write distance to current read position */
- write_distance = 0;
- if (curr_gwp >= curr_grp)
- /* Write doesn't wrap around the ring */
- write_distance = curr_gwp - curr_grp;
- else
- /* Write wraps around the ring */
- write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp;
-
- if (bytes_to_read > write_distance) {
- printk(KERN_ERR "%s() Invalid bus state, missing msg "
- "or mangled ring, faulty H/W / bad code?\n", __func__);
- ret = SAA_ERR_INVALID_COMMAND;
- goto out;
- }
-
- /* Calculate the new read position */
- new_grp = curr_grp + bytes_to_read;
- if (new_grp > bus->m_dwSizeGetRing) {
-
- /* Ring wraps */
- new_grp -= bus->m_dwSizeGetRing;
- space_rem = bus->m_dwSizeGetRing - curr_grp;
-
- if (space_rem < sizeof(*msg)) {
- /* msg wraps around the ring */
- memcpy(msg, bus->m_pdwGetRing + curr_grp, space_rem);
- memcpy((u8 *)msg + space_rem, bus->m_pdwGetRing,
- sizeof(*msg) - space_rem);
- if (buf)
- memcpy(buf, bus->m_pdwGetRing + sizeof(*msg) -
- space_rem, buf_size);
-
- } else if (space_rem == sizeof(*msg)) {
- memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
- if (buf)
- memcpy(buf, bus->m_pdwGetRing, buf_size);
- } else {
- /* Additional data wraps around the ring */
- memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
- if (buf) {
- memcpy(buf, bus->m_pdwGetRing + curr_grp +
- sizeof(*msg), space_rem - sizeof(*msg));
- memcpy(buf + space_rem - sizeof(*msg),
- bus->m_pdwGetRing, bytes_to_read -
- space_rem);
- }
-
- }
-
- } else {
- /* No wrapping */
- memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
- if (buf)
- memcpy(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg),
- buf_size);
- }
-
- /* Update the read positions, adjusting the ring */
- saa7164_writel(bus->m_dwGetReadPos, cpu_to_le32(new_grp));
-
-peekout:
- msg->size = le16_to_cpu(msg->size);
- msg->command = le32_to_cpu(msg->command);
- msg->controlselector = le16_to_cpu(msg->controlselector);
- ret = SAA_OK;
-out:
- mutex_unlock(&bus->lock);
- saa7164_bus_verify(dev);
- return ret;
-}
-
diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c
deleted file mode 100644
index 5b72da5ce41..00000000000
--- a/drivers/media/video/saa7164/saa7164-cards.c
+++ /dev/null
@@ -1,773 +0,0 @@
-/*
- * Driver for the NXP SAA7164 PCIe bridge
- *
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-
-#include "saa7164.h"
-
-/* The Bridge API needs to understand register widths (in bytes) for the
- * attached I2C devices, so we can simplify the virtual i2c mechansms
- * and keep the -i2c.c implementation clean.
- */
-#define REGLEN_8bit 1
-#define REGLEN_16bit 2
-
-struct saa7164_board saa7164_boards[] = {
- [SAA7164_BOARD_UNKNOWN] = {
- /* Bridge will not load any firmware, without knowing
- * the rev this would be fatal. */
- .name = "Unknown",
- },
- [SAA7164_BOARD_UNKNOWN_REV2] = {
- /* Bridge will load the v2 f/w and dump descriptors */
- /* Required during new board bringup */
- .name = "Generic Rev2",
- .chiprev = SAA7164_CHIP_REV2,
- },
- [SAA7164_BOARD_UNKNOWN_REV3] = {
- /* Bridge will load the v2 f/w and dump descriptors */
- /* Required during new board bringup */
- .name = "Generic Rev3",
- .chiprev = SAA7164_CHIP_REV3,
- },
- [SAA7164_BOARD_HAUPPAUGE_HVR2200] = {
- .name = "Hauppauge WinTV-HVR2200",
- .porta = SAA7164_MPEG_DVB,
- .portb = SAA7164_MPEG_DVB,
- .portc = SAA7164_MPEG_ENCODER,
- .portd = SAA7164_MPEG_ENCODER,
- .porte = SAA7164_MPEG_VBI,
- .portf = SAA7164_MPEG_VBI,
- .chiprev = SAA7164_CHIP_REV3,
- .unit = {{
- .id = 0x1d,
- .type = SAA7164_UNIT_EEPROM,
- .name = "4K EEPROM",
- .i2c_bus_nr = SAA7164_I2C_BUS_0,
- .i2c_bus_addr = 0xa0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x04,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x1b,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x1e,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "TDA10048-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0x10 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x1f,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "TDA10048-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0x12 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- } },
- },
- [SAA7164_BOARD_HAUPPAUGE_HVR2200_2] = {
- .name = "Hauppauge WinTV-HVR2200",
- .porta = SAA7164_MPEG_DVB,
- .portb = SAA7164_MPEG_DVB,
- .portc = SAA7164_MPEG_ENCODER,
- .portd = SAA7164_MPEG_ENCODER,
- .porte = SAA7164_MPEG_VBI,
- .portf = SAA7164_MPEG_VBI,
- .chiprev = SAA7164_CHIP_REV2,
- .unit = {{
- .id = 0x06,
- .type = SAA7164_UNIT_EEPROM,
- .name = "4K EEPROM",
- .i2c_bus_nr = SAA7164_I2C_BUS_0,
- .i2c_bus_addr = 0xa0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x04,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x05,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "TDA10048-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0x10 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x1e,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x1f,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "TDA10048-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0x12 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- } },
- },
- [SAA7164_BOARD_HAUPPAUGE_HVR2200_3] = {
- .name = "Hauppauge WinTV-HVR2200",
- .porta = SAA7164_MPEG_DVB,
- .portb = SAA7164_MPEG_DVB,
- .portc = SAA7164_MPEG_ENCODER,
- .portd = SAA7164_MPEG_ENCODER,
- .porte = SAA7164_MPEG_VBI,
- .portf = SAA7164_MPEG_VBI,
- .chiprev = SAA7164_CHIP_REV2,
- .unit = {{
- .id = 0x1d,
- .type = SAA7164_UNIT_EEPROM,
- .name = "4K EEPROM",
- .i2c_bus_nr = SAA7164_I2C_BUS_0,
- .i2c_bus_addr = 0xa0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x04,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x05,
- .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
- .name = "TDA8290-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0x84 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x1b,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x1c,
- .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
- .name = "TDA8290-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0x84 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x1e,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "TDA10048-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0x10 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x1f,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "TDA10048-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0x12 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- } },
- },
- [SAA7164_BOARD_HAUPPAUGE_HVR2200_4] = {
- .name = "Hauppauge WinTV-HVR2200",
- .porta = SAA7164_MPEG_DVB,
- .portb = SAA7164_MPEG_DVB,
- .portc = SAA7164_MPEG_ENCODER,
- .portd = SAA7164_MPEG_ENCODER,
- .porte = SAA7164_MPEG_VBI,
- .portf = SAA7164_MPEG_VBI,
- .chiprev = SAA7164_CHIP_REV3,
- .unit = {{
- .id = 0x1d,
- .type = SAA7164_UNIT_EEPROM,
- .name = "4K EEPROM",
- .i2c_bus_nr = SAA7164_I2C_BUS_0,
- .i2c_bus_addr = 0xa0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x04,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x05,
- .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
- .name = "TDA8290-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0x84 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x1b,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x1c,
- .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
- .name = "TDA8290-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0x84 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x1e,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "TDA10048-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0x10 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x1f,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "TDA10048-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0x12 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- } },
- },
- [SAA7164_BOARD_HAUPPAUGE_HVR2250] = {
- .name = "Hauppauge WinTV-HVR2250",
- .porta = SAA7164_MPEG_DVB,
- .portb = SAA7164_MPEG_DVB,
- .portc = SAA7164_MPEG_ENCODER,
- .portd = SAA7164_MPEG_ENCODER,
- .porte = SAA7164_MPEG_VBI,
- .portf = SAA7164_MPEG_VBI,
- .chiprev = SAA7164_CHIP_REV3,
- .unit = {{
- .id = 0x22,
- .type = SAA7164_UNIT_EEPROM,
- .name = "4K EEPROM",
- .i2c_bus_nr = SAA7164_I2C_BUS_0,
- .i2c_bus_addr = 0xa0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x04,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x07,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "CX24228/S5H1411-1 (TOP)",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0x32 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x08,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "CX24228/S5H1411-1 (QAM)",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0x34 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x1e,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x20,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "CX24228/S5H1411-2 (TOP)",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0x32 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x23,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "CX24228/S5H1411-2 (QAM)",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0x34 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- } },
- },
- [SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = {
- .name = "Hauppauge WinTV-HVR2250",
- .porta = SAA7164_MPEG_DVB,
- .portb = SAA7164_MPEG_DVB,
- .portc = SAA7164_MPEG_ENCODER,
- .portd = SAA7164_MPEG_ENCODER,
- .porte = SAA7164_MPEG_VBI,
- .portf = SAA7164_MPEG_VBI,
- .chiprev = SAA7164_CHIP_REV3,
- .unit = {{
- .id = 0x28,
- .type = SAA7164_UNIT_EEPROM,
- .name = "4K EEPROM",
- .i2c_bus_nr = SAA7164_I2C_BUS_0,
- .i2c_bus_addr = 0xa0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x04,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x07,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "CX24228/S5H1411-1 (TOP)",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0x32 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x08,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "CX24228/S5H1411-1 (QAM)",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0x34 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x24,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x26,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "CX24228/S5H1411-2 (TOP)",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0x32 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x29,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "CX24228/S5H1411-2 (QAM)",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0x34 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- } },
- },
- [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = {
- .name = "Hauppauge WinTV-HVR2250",
- .porta = SAA7164_MPEG_DVB,
- .portb = SAA7164_MPEG_DVB,
- .portc = SAA7164_MPEG_ENCODER,
- .portd = SAA7164_MPEG_ENCODER,
- .porte = SAA7164_MPEG_VBI,
- .portf = SAA7164_MPEG_VBI,
- .chiprev = SAA7164_CHIP_REV3,
- .unit = {{
- .id = 0x26,
- .type = SAA7164_UNIT_EEPROM,
- .name = "4K EEPROM",
- .i2c_bus_nr = SAA7164_I2C_BUS_0,
- .i2c_bus_addr = 0xa0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x04,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x07,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "CX24228/S5H1411-1 (TOP)",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0x32 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x08,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "CX24228/S5H1411-1 (QAM)",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0x34 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x22,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x24,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "CX24228/S5H1411-2 (TOP)",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0x32 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x27,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "CX24228/S5H1411-2 (QAM)",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0x34 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- } },
- },
- [SAA7164_BOARD_HAUPPAUGE_HVR2200_5] = {
- .name = "Hauppauge WinTV-HVR2200",
- .porta = SAA7164_MPEG_DVB,
- .portb = SAA7164_MPEG_DVB,
- .chiprev = SAA7164_CHIP_REV3,
- .unit = {{
- .id = 0x23,
- .type = SAA7164_UNIT_EEPROM,
- .name = "4K EEPROM",
- .i2c_bus_nr = SAA7164_I2C_BUS_0,
- .i2c_bus_addr = 0xa0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x04,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x05,
- .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
- .name = "TDA8290-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0x84 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x21,
- .type = SAA7164_UNIT_TUNER,
- .name = "TDA18271-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0xc0 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x22,
- .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
- .name = "TDA8290-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0x84 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x24,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "TDA10048-1",
- .i2c_bus_nr = SAA7164_I2C_BUS_1,
- .i2c_bus_addr = 0x10 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- }, {
- .id = 0x25,
- .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
- .name = "TDA10048-2",
- .i2c_bus_nr = SAA7164_I2C_BUS_2,
- .i2c_bus_addr = 0x12 >> 1,
- .i2c_reg_len = REGLEN_8bit,
- } },
- },
-};
-const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
-
-/* ------------------------------------------------------------------ */
-/* PCI subsystem IDs */
-
-struct saa7164_subid saa7164_subids[] = {
- {
- .subvendor = 0x0070,
- .subdevice = 0x8880,
- .card = SAA7164_BOARD_HAUPPAUGE_HVR2250,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x8810,
- .card = SAA7164_BOARD_HAUPPAUGE_HVR2250,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x8980,
- .card = SAA7164_BOARD_HAUPPAUGE_HVR2200,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x8900,
- .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_2,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x8901,
- .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_3,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x88A1,
- .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x8891,
- .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x8851,
- .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x8940,
- .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_4,
- }, {
- .subvendor = 0x0070,
- .subdevice = 0x8953,
- .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_5,
- },
-};
-const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
-
-void saa7164_card_list(struct saa7164_dev *dev)
-{
- int i;
-
- if (0 == dev->pci->subsystem_vendor &&
- 0 == dev->pci->subsystem_device) {
- printk(KERN_ERR
- "%s: Board has no valid PCIe Subsystem ID and can't\n"
- "%s: be autodetected. Pass card=<n> insmod option to\n"
- "%s: workaround that. Send complaints to the vendor\n"
- "%s: of the TV card. Best regards,\n"
- "%s: -- tux\n",
- dev->name, dev->name, dev->name, dev->name, dev->name);
- } else {
- printk(KERN_ERR
- "%s: Your board isn't known (yet) to the driver.\n"
- "%s: Try to pick one of the existing card configs via\n"
- "%s: card=<n> insmod option. Updating to the latest\n"
- "%s: version might help as well.\n",
- dev->name, dev->name, dev->name, dev->name);
- }
-
- printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod "
- "option:\n", dev->name);
-
- for (i = 0; i < saa7164_bcount; i++)
- printk(KERN_ERR "%s: card=%d -> %s\n",
- dev->name, i, saa7164_boards[i].name);
-}
-
-/* TODO: clean this define up into the -cards.c structs */
-#define PCIEBRIDGE_UNITID 2
-
-void saa7164_gpio_setup(struct saa7164_dev *dev)
-{
- switch (dev->board) {
- case SAA7164_BOARD_HAUPPAUGE_HVR2200:
- case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
- case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
- case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
- case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
- case SAA7164_BOARD_HAUPPAUGE_HVR2250:
- case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
- case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
- /*
- GPIO 2: s5h1411 / tda10048-1 demod reset
- GPIO 3: s5h1411 / tda10048-2 demod reset
- GPIO 7: IRBlaster Zilog reset
- */
-
- /* Reset parts by going in and out of reset */
- saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
- saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
-
- msleep(20);
-
- saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
- saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
- break;
- }
-}
-
-static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
-{
- struct tveeprom tv;
-
- /* TODO: Assumption: eeprom on bus 0 */
- tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
- eeprom_data);
-
- /* Make sure we support the board model */
- switch (tv.model) {
- case 88001:
- /* Development board - Limit circulation */
- /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
- * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
- case 88021:
- /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
- * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */
- break;
- case 88041:
- /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
- * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
- break;
- case 88061:
- /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
- * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */
- break;
- case 89519:
- case 89609:
- /* WinTV-HVR2200 (PCIe, Retail, full-height)
- * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
- break;
- case 89619:
- /* WinTV-HVR2200 (PCIe, Retail, half-height)
- * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
- break;
- default:
- printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n",
- dev->name, tv.model);
- break;
- }
-
- printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
- tv.model);
-}
-
-void saa7164_card_setup(struct saa7164_dev *dev)
-{
- static u8 eeprom[256];
-
- if (dev->i2c_bus[0].i2c_rc == 0) {
- if (saa7164_api_read_eeprom(dev, &eeprom[0],
- sizeof(eeprom)) < 0)
- return;
- }
-
- switch (dev->board) {
- case SAA7164_BOARD_HAUPPAUGE_HVR2200:
- case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
- case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
- case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
- case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
- case SAA7164_BOARD_HAUPPAUGE_HVR2250:
- case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
- case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
- hauppauge_eeprom(dev, &eeprom[0]);
- break;
- }
-}
-
-/* With most other drivers, the kernel expects to communicate with subdrivers
- * through i2c. This bridge does not allow that, it does not expose any direct
- * access to I2C. Instead we have to communicate through the device f/w for
- * register access to 'processing units'. Each unit has a unique
- * id, regardless of how the physical implementation occurs across
- * the three physical i2c busses. The being said if we want leverge of
- * the existing kernel drivers for tuners and demods we have to 'speak i2c',
- * to this bridge implements 3 virtual i2c buses. This is a helper function
- * for those.
- *
- * Description: Translate the kernels notion of an i2c address and bus into
- * the appropriate unitid.
- */
-int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr)
-{
- /* For a given bus and i2c device address, return the saa7164 unique
- * unitid. < 0 on error */
-
- struct saa7164_dev *dev = bus->dev;
- struct saa7164_unit *unit;
- int i;
-
- for (i = 0; i < SAA7164_MAX_UNITS; i++) {
- unit = &saa7164_boards[dev->board].unit[i];
-
- if (unit->type == SAA7164_UNIT_UNDEFINED)
- continue;
- if ((bus->nr == unit->i2c_bus_nr) &&
- (addr == unit->i2c_bus_addr))
- return unit->id;
- }
-
- return -1;
-}
-
-/* The 7164 API needs to know the i2c register length in advance.
- * this is a helper function. Based on a specific chip addr and bus return the
- * reg length.
- */
-int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr)
-{
- /* For a given bus and i2c device address, return the
- * saa7164 registry address width. < 0 on error
- */
-
- struct saa7164_dev *dev = bus->dev;
- struct saa7164_unit *unit;
- int i;
-
- for (i = 0; i < SAA7164_MAX_UNITS; i++) {
- unit = &saa7164_boards[dev->board].unit[i];
-
- if (unit->type == SAA7164_UNIT_UNDEFINED)
- continue;
-
- if ((bus->nr == unit->i2c_bus_nr) &&
- (addr == unit->i2c_bus_addr))
- return unit->i2c_reg_len;
- }
-
- return -1;
-}
-/* TODO: implement a 'findeeprom' functio like the above and fix any other
- * eeprom related todo's in -api.c.
- */
-
-/* Translate a unitid into a x readable device name, for display purposes. */
-char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid)
-{
- char *undefed = "UNDEFINED";
- char *bridge = "BRIDGE";
- struct saa7164_unit *unit;
- int i;
-
- if (unitid == 0)
- return bridge;
-
- for (i = 0; i < SAA7164_MAX_UNITS; i++) {
- unit = &saa7164_boards[dev->board].unit[i];
-
- if (unit->type == SAA7164_UNIT_UNDEFINED)
- continue;
-
- if (unitid == unit->id)
- return unit->name;
- }
-
- return undefed;
-}
-
diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c
deleted file mode 100644
index 62fac7f9d04..00000000000
--- a/drivers/media/video/saa7164/saa7164-cmd.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Driver for the NXP SAA7164 PCIe bridge
- *
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/wait.h>
-
-#include "saa7164.h"
-
-int saa7164_cmd_alloc_seqno(struct saa7164_dev *dev)
-{
- int i, ret = -1;
-
- mutex_lock(&dev->lock);
- for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
- if (dev->cmds[i].inuse == 0) {
- dev->cmds[i].inuse = 1;
- dev->cmds[i].signalled = 0;
- dev->cmds[i].timeout = 0;
- ret = dev->cmds[i].seqno;
- break;
- }
- }
- mutex_unlock(&dev->lock);
-
- return ret;
-}
-
-void saa7164_cmd_free_seqno(struct saa7164_dev *dev, u8 seqno)
-{
- mutex_lock(&dev->lock);
- if ((dev->cmds[seqno].inuse == 1) &&
- (dev->cmds[seqno].seqno == seqno)) {
- dev->cmds[seqno].inuse = 0;
- dev->cmds[seqno].signalled = 0;
- dev->cmds[seqno].timeout = 0;
- }
- mutex_unlock(&dev->lock);
-}
-
-void saa7164_cmd_timeout_seqno(struct saa7164_dev *dev, u8 seqno)
-{
- mutex_lock(&dev->lock);
- if ((dev->cmds[seqno].inuse == 1) &&
- (dev->cmds[seqno].seqno == seqno)) {
- dev->cmds[seqno].timeout = 1;
- }
- mutex_unlock(&dev->lock);
-}
-
-u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno)
-{
- int ret = 0;
-
- mutex_lock(&dev->lock);
- if ((dev->cmds[seqno].inuse == 1) &&
- (dev->cmds[seqno].seqno == seqno)) {
- ret = dev->cmds[seqno].timeout;
- }
- mutex_unlock(&dev->lock);
-
- return ret;
-}
-
-/* Commands to the f/w get marshelled to/from this code then onto the PCI
- * -bus/c running buffer. */
-int saa7164_irq_dequeue(struct saa7164_dev *dev)
-{
- int ret = SAA_OK, i = 0;
- u32 timeout;
- wait_queue_head_t *q = NULL;
- u8 tmp[512];
- dprintk(DBGLVL_CMD, "%s()\n", __func__);
-
- /* While any outstand message on the bus exists... */
- do {
-
- /* Peek the msg bus */
- struct tmComResInfo tRsp = { 0, 0, 0, 0, 0, 0 };
- ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
- if (ret != SAA_OK)
- break;
-
- q = &dev->cmds[tRsp.seqno].wait;
- timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
- dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
- if (!timeout) {
- dprintk(DBGLVL_CMD,
- "%s() signalled seqno(%d) (for dequeue)\n",
- __func__, tRsp.seqno);
- dev->cmds[tRsp.seqno].signalled = 1;
- wake_up(q);
- } else {
- printk(KERN_ERR
- "%s() found timed out command on the bus\n",
- __func__);
-
- /* Clean the bus */
- ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
- printk(KERN_ERR "%s() ret = %x\n", __func__, ret);
- if (ret == SAA_ERR_EMPTY)
- /* Someone else already fetched the response */
- return SAA_OK;
-
- if (ret != SAA_OK)
- return ret;
- }
-
- /* It's unlikely to have more than 4 or 5 pending messages,
- * ensure we exit at some point regardless.
- */
- } while (i++ < 32);
-
- return ret;
-}
-
-/* Commands to the f/w get marshelled to/from this code then onto the PCI
- * -bus/c running buffer. */
-int saa7164_cmd_dequeue(struct saa7164_dev *dev)
-{
- int loop = 1;
- int ret;
- u32 timeout;
- wait_queue_head_t *q = NULL;
- u8 tmp[512];
- dprintk(DBGLVL_CMD, "%s()\n", __func__);
-
- while (loop) {
-
- struct tmComResInfo tRsp = { 0, 0, 0, 0, 0, 0 };
- ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
- if (ret == SAA_ERR_EMPTY)
- return SAA_OK;
-
- if (ret != SAA_OK)
- return ret;
-
- q = &dev->cmds[tRsp.seqno].wait;
- timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
- dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
- if (timeout) {
- printk(KERN_ERR "found timed out command on the bus\n");
-
- /* Clean the bus */
- ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
- printk(KERN_ERR "ret = %x\n", ret);
- if (ret == SAA_ERR_EMPTY)
- /* Someone else already fetched the response */
- return SAA_OK;
-
- if (ret != SAA_OK)
- return ret;
-
- if (tRsp.flags & PVC_CMDFLAG_CONTINUE)
- printk(KERN_ERR "split response\n");
- else
- saa7164_cmd_free_seqno(dev, tRsp.seqno);
-
- printk(KERN_ERR " timeout continue\n");
- continue;
- }
-
- dprintk(DBGLVL_CMD, "%s() signalled seqno(%d) (for dequeue)\n",
- __func__, tRsp.seqno);
- dev->cmds[tRsp.seqno].signalled = 1;
- wake_up(q);
- return SAA_OK;
- }
-
- return SAA_OK;
-}
-
-int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo *msg,
- void *buf)
-{
- struct tmComResBusInfo *bus = &dev->bus;
- u8 cmd_sent;
- u16 size, idx;
- u32 cmds;
- void *tmp;
- int ret = -1;
-
- if (!msg) {
- printk(KERN_ERR "%s() !msg\n", __func__);
- return SAA_ERR_BAD_PARAMETER;
- }
-
- mutex_lock(&dev->cmds[msg->id].lock);
-
- size = msg->size;
- idx = 0;
- cmds = size / bus->m_wMaxReqSize;
- if (size % bus->m_wMaxReqSize == 0)
- cmds -= 1;
-
- cmd_sent = 0;
-
- /* Split the request into smaller chunks */
- for (idx = 0; idx < cmds; idx++) {
-
- msg->flags |= SAA_CMDFLAG_CONTINUE;
- msg->size = bus->m_wMaxReqSize;
- tmp = buf + idx * bus->m_wMaxReqSize;
-
- ret = saa7164_bus_set(dev, msg, tmp);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() set failed %d\n", __func__, ret);
-
- if (cmd_sent) {
- ret = SAA_ERR_BUSY;
- goto out;
- }
- ret = SAA_ERR_OVERFLOW;
- goto out;
- }
- cmd_sent = 1;
- }
-
- /* If not the last command... */
- if (idx != 0)
- msg->flags &= ~SAA_CMDFLAG_CONTINUE;
-
- msg->size = size - idx * bus->m_wMaxReqSize;
-
- ret = saa7164_bus_set(dev, msg, buf + idx * bus->m_wMaxReqSize);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() set last failed %d\n", __func__, ret);
-
- if (cmd_sent) {
- ret = SAA_ERR_BUSY;
- goto out;
- }
- ret = SAA_ERR_OVERFLOW;
- goto out;
- }
- ret = SAA_OK;
-
-out:
- mutex_unlock(&dev->cmds[msg->id].lock);
- return ret;
-}
-
-/* Wait for a signal event, without holding a mutex. Either return TIMEOUT if
- * the event never occurred, or SAA_OK if it was signaled during the wait.
- */
-int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
-{
- wait_queue_head_t *q = NULL;
- int ret = SAA_BUS_TIMEOUT;
- unsigned long stamp;
- int r;
-
- if (saa_debug >= 4)
- saa7164_bus_dump(dev);
-
- dprintk(DBGLVL_CMD, "%s(seqno=%d)\n", __func__, seqno);
-
- mutex_lock(&dev->lock);
- if ((dev->cmds[seqno].inuse == 1) &&
- (dev->cmds[seqno].seqno == seqno)) {
- q = &dev->cmds[seqno].wait;
- }
- mutex_unlock(&dev->lock);
-
- if (q) {
- /* If we haven't been signalled we need to wait */
- if (dev->cmds[seqno].signalled == 0) {
- stamp = jiffies;
- dprintk(DBGLVL_CMD,
- "%s(seqno=%d) Waiting (signalled=%d)\n",
- __func__, seqno, dev->cmds[seqno].signalled);
-
- /* Wait for signalled to be flagged or timeout */
- /* In a highly stressed system this can easily extend
- * into multiple seconds before the deferred worker
- * is scheduled, and we're woken up via signal.
- * We typically are signalled in < 50ms but it can
- * take MUCH longer.
- */
- wait_event_timeout(*q, dev->cmds[seqno].signalled,
- (HZ * waitsecs));
- r = time_before(jiffies, stamp + (HZ * waitsecs));
- if (r)
- ret = SAA_OK;
- else
- saa7164_cmd_timeout_seqno(dev, seqno);
-
- dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting res = %d "
- "(signalled=%d)\n", __func__, seqno, r,
- dev->cmds[seqno].signalled);
- } else
- ret = SAA_OK;
- } else
- printk(KERN_ERR "%s(seqno=%d) seqno is invalid\n",
- __func__, seqno);
-
- return ret;
-}
-
-void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno)
-{
- int i;
- dprintk(DBGLVL_CMD, "%s()\n", __func__);
-
- mutex_lock(&dev->lock);
- for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
- if (dev->cmds[i].inuse == 1) {
- dprintk(DBGLVL_CMD,
- "seqno %d inuse, sig = %d, t/out = %d\n",
- dev->cmds[i].seqno,
- dev->cmds[i].signalled,
- dev->cmds[i].timeout);
- }
- }
-
- for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
- if ((dev->cmds[i].inuse == 1) && ((i == 0) ||
- (dev->cmds[i].signalled) || (dev->cmds[i].timeout))) {
- dprintk(DBGLVL_CMD, "%s(seqno=%d) calling wake_up\n",
- __func__, i);
- dev->cmds[i].signalled = 1;
- wake_up(&dev->cmds[i].wait);
- }
- }
- mutex_unlock(&dev->lock);
-}
-
-int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command,
- u16 controlselector, u16 size, void *buf)
-{
- struct tmComResInfo command_t, *pcommand_t;
- struct tmComResInfo response_t, *presponse_t;
- u8 errdata[256];
- u16 resp_dsize;
- u16 data_recd;
- u32 loop;
- int ret;
- int safety = 0;
-
- dprintk(DBGLVL_CMD, "%s(unitid = %s (%d) , command = 0x%x, "
- "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id,
- command, controlselector);
-
- if ((size == 0) || (buf == NULL)) {
- printk(KERN_ERR "%s() Invalid param\n", __func__);
- return SAA_ERR_BAD_PARAMETER;
- }
-
- /* Prepare some basic command/response structures */
- memset(&command_t, 0, sizeof(command_t));
- memset(&response_t, 0, sizeof(response_t));
- pcommand_t = &command_t;
- presponse_t = &response_t;
- command_t.id = id;
- command_t.command = command;
- command_t.controlselector = controlselector;
- command_t.size = size;
-
- /* Allocate a unique sequence number */
- ret = saa7164_cmd_alloc_seqno(dev);
- if (ret < 0) {
- printk(KERN_ERR "%s() No free sequences\n", __func__);
- ret = SAA_ERR_NO_RESOURCES;
- goto out;
- }
-
- command_t.seqno = (u8)ret;
-
- /* Send Command */
- resp_dsize = size;
- pcommand_t->size = size;
-
- dprintk(DBGLVL_CMD, "%s() pcommand_t.seqno = %d\n",
- __func__, pcommand_t->seqno);
-
- dprintk(DBGLVL_CMD, "%s() pcommand_t.size = %d\n",
- __func__, pcommand_t->size);
-
- ret = saa7164_cmd_set(dev, pcommand_t, buf);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() set command failed %d\n", __func__, ret);
-
- if (ret != SAA_ERR_BUSY)
- saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
- else
- /* Flag a timeout, because at least one
- * command was sent */
- saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
-
- goto out;
- }
-
- /* With split responses we have to collect the msgs piece by piece */
- data_recd = 0;
- loop = 1;
- while (loop) {
- dprintk(DBGLVL_CMD, "%s() loop\n", __func__);
-
- ret = saa7164_cmd_wait(dev, pcommand_t->seqno);
- dprintk(DBGLVL_CMD, "%s() loop ret = %d\n", __func__, ret);
-
- /* if power is down and this is not a power command ... */
-
- if (ret == SAA_BUS_TIMEOUT) {
- printk(KERN_ERR "Event timed out\n");
- saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
- return ret;
- }
-
- if (ret != SAA_OK) {
- printk(KERN_ERR "spurious error\n");
- return ret;
- }
-
- /* Peek response */
- ret = saa7164_bus_get(dev, presponse_t, NULL, 1);
- if (ret == SAA_ERR_EMPTY) {
- dprintk(4, "%s() SAA_ERR_EMPTY\n", __func__);
- continue;
- }
- if (ret != SAA_OK) {
- printk(KERN_ERR "peek failed\n");
- return ret;
- }
-
- dprintk(DBGLVL_CMD, "%s() presponse_t->seqno = %d\n",
- __func__, presponse_t->seqno);
-
- dprintk(DBGLVL_CMD, "%s() presponse_t->flags = 0x%x\n",
- __func__, presponse_t->flags);
-
- dprintk(DBGLVL_CMD, "%s() presponse_t->size = %d\n",
- __func__, presponse_t->size);
-
- /* Check if the response was for our command */
- if (presponse_t->seqno != pcommand_t->seqno) {
-
- dprintk(DBGLVL_CMD,
- "wrong event: seqno = %d, "
- "expected seqno = %d, "
- "will dequeue regardless\n",
- presponse_t->seqno, pcommand_t->seqno);
-
- ret = saa7164_cmd_dequeue(dev);
- if (ret != SAA_OK) {
- printk(KERN_ERR "dequeue failed, ret = %d\n",
- ret);
- if (safety++ > 16) {
- printk(KERN_ERR
- "dequeue exceeded, safety exit\n");
- return SAA_ERR_BUSY;
- }
- }
-
- continue;
- }
-
- if ((presponse_t->flags & PVC_RESPONSEFLAG_ERROR) != 0) {
-
- memset(&errdata[0], 0, sizeof(errdata));
-
- ret = saa7164_bus_get(dev, presponse_t, &errdata[0], 0);
- if (ret != SAA_OK) {
- printk(KERN_ERR "get error(2)\n");
- return ret;
- }
-
- saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
-
- dprintk(DBGLVL_CMD, "%s() errdata %02x%02x%02x%02x\n",
- __func__, errdata[0], errdata[1], errdata[2],
- errdata[3]);
-
- /* Map error codes */
- dprintk(DBGLVL_CMD, "%s() cmd, error code = 0x%x\n",
- __func__, errdata[0]);
-
- switch (errdata[0]) {
- case PVC_ERRORCODE_INVALID_COMMAND:
- dprintk(DBGLVL_CMD, "%s() INVALID_COMMAND\n",
- __func__);
- ret = SAA_ERR_INVALID_COMMAND;
- break;
- case PVC_ERRORCODE_INVALID_DATA:
- dprintk(DBGLVL_CMD, "%s() INVALID_DATA\n",
- __func__);
- ret = SAA_ERR_BAD_PARAMETER;
- break;
- case PVC_ERRORCODE_TIMEOUT:
- dprintk(DBGLVL_CMD, "%s() TIMEOUT\n", __func__);
- ret = SAA_ERR_TIMEOUT;
- break;
- case PVC_ERRORCODE_NAK:
- dprintk(DBGLVL_CMD, "%s() NAK\n", __func__);
- ret = SAA_ERR_NULL_PACKET;
- break;
- case PVC_ERRORCODE_UNKNOWN:
- case PVC_ERRORCODE_INVALID_CONTROL:
- dprintk(DBGLVL_CMD,
- "%s() UNKNOWN OR INVALID CONTROL\n",
- __func__);
- default:
- dprintk(DBGLVL_CMD, "%s() UNKNOWN\n", __func__);
- ret = SAA_ERR_NOT_SUPPORTED;
- }
-
- /* See of other commands are on the bus */
- if (saa7164_cmd_dequeue(dev) != SAA_OK)
- printk(KERN_ERR "dequeue(2) failed\n");
-
- return ret;
- }
-
- /* If response is invalid */
- if ((presponse_t->id != pcommand_t->id) ||
- (presponse_t->command != pcommand_t->command) ||
- (presponse_t->controlselector !=
- pcommand_t->controlselector) ||
- (((resp_dsize - data_recd) != presponse_t->size) &&
- !(presponse_t->flags & PVC_CMDFLAG_CONTINUE)) ||
- ((resp_dsize - data_recd) < presponse_t->size)) {
-
- /* Invalid */
- dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__);
- ret = saa7164_bus_get(dev, presponse_t, NULL, 0);
- if (ret != SAA_OK) {
- printk(KERN_ERR "get failed\n");
- return ret;
- }
-
- /* See of other commands are on the bus */
- if (saa7164_cmd_dequeue(dev) != SAA_OK)
- printk(KERN_ERR "dequeue(3) failed\n");
- continue;
- }
-
- /* OK, now we're actually getting out correct response */
- ret = saa7164_bus_get(dev, presponse_t, buf + data_recd, 0);
- if (ret != SAA_OK) {
- printk(KERN_ERR "get failed\n");
- return ret;
- }
-
- data_recd = presponse_t->size + data_recd;
- if (resp_dsize == data_recd) {
- dprintk(DBGLVL_CMD, "%s() Resp recd\n", __func__);
- break;
- }
-
- /* See of other commands are on the bus */
- if (saa7164_cmd_dequeue(dev) != SAA_OK)
- printk(KERN_ERR "dequeue(3) failed\n");
-
- continue;
-
- } /* (loop) */
-
- /* Release the sequence number allocation */
- saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
-
- /* if powerdown signal all pending commands */
-
- dprintk(DBGLVL_CMD, "%s() Calling dequeue then exit\n", __func__);
-
- /* See of other commands are on the bus */
- if (saa7164_cmd_dequeue(dev) != SAA_OK)
- printk(KERN_ERR "dequeue(4) failed\n");
-
- ret = SAA_OK;
-out:
- return ret;
-}
-
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
deleted file mode 100644
index 3b7d7b4e303..00000000000
--- a/drivers/media/video/saa7164/saa7164-core.c
+++ /dev/null
@@ -1,1526 +0,0 @@
-/*
- * Driver for the NXP SAA7164 PCIe bridge
- *
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kmod.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <asm/div64.h>
-
-#ifdef CONFIG_PROC_FS
-#include <linux/proc_fs.h>
-#endif
-#include "saa7164.h"
-
-MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards");
-MODULE_AUTHOR("Steven Toth <stoth@kernellabs.com>");
-MODULE_LICENSE("GPL");
-
-/*
- * 1 Basic
- * 2
- * 4 i2c
- * 8 api
- * 16 cmd
- * 32 bus
- */
-
-unsigned int saa_debug;
-module_param_named(debug, saa_debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debug messages");
-
-unsigned int fw_debug;
-module_param(fw_debug, int, 0644);
-MODULE_PARM_DESC(fw_debug, "Firware debug level def:2");
-
-unsigned int encoder_buffers = SAA7164_MAX_ENCODER_BUFFERS;
-module_param(encoder_buffers, int, 0644);
-MODULE_PARM_DESC(encoder_buffers, "Total buffers in read queue 16-512 def:64");
-
-unsigned int vbi_buffers = SAA7164_MAX_VBI_BUFFERS;
-module_param(vbi_buffers, int, 0644);
-MODULE_PARM_DESC(vbi_buffers, "Total buffers in read queue 16-512 def:64");
-
-unsigned int waitsecs = 10;
-module_param(waitsecs, int, 0644);
-MODULE_PARM_DESC(waitsecs, "timeout on firmware messages");
-
-static unsigned int card[] = {[0 ... (SAA7164_MAXBOARDS - 1)] = UNSET };
-module_param_array(card, int, NULL, 0444);
-MODULE_PARM_DESC(card, "card type");
-
-unsigned int print_histogram = 64;
-module_param(print_histogram, int, 0644);
-MODULE_PARM_DESC(print_histogram, "print histogram values once");
-
-unsigned int crc_checking = 1;
-module_param(crc_checking, int, 0644);
-MODULE_PARM_DESC(crc_checking, "enable crc sanity checking on buffers");
-
-unsigned int guard_checking = 1;
-module_param(guard_checking, int, 0644);
-MODULE_PARM_DESC(guard_checking,
- "enable dma sanity checking for buffer overruns");
-
-static unsigned int saa7164_devcount;
-
-static DEFINE_MUTEX(devlist);
-LIST_HEAD(saa7164_devlist);
-
-#define INT_SIZE 16
-
-void saa7164_dumphex16FF(struct saa7164_dev *dev, u8 *buf, int len)
-{
- int i;
- u8 tmp[16];
- memset(&tmp[0], 0xff, sizeof(tmp));
-
- printk(KERN_INFO "--------------------> "
- "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
-
- for (i = 0; i < len; i += 16) {
- if (memcmp(&tmp, buf + i, sizeof(tmp)) != 0) {
- printk(KERN_INFO " [0x%08x] "
- "%02x %02x %02x %02x %02x %02x %02x %02x "
- "%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
- *(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3),
- *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7),
- *(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11),
- *(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15));
- }
- }
-}
-
-static void saa7164_pack_verifier(struct saa7164_buffer *buf)
-{
- u8 *p = (u8 *)buf->cpu;
- int i;
-
- for (i = 0; i < buf->actual_size; i += 2048) {
-
- if ((*(p + i + 0) != 0x00) || (*(p + i + 1) != 0x00) ||
- (*(p + i + 2) != 0x01) || (*(p + i + 3) != 0xBA)) {
- printk(KERN_ERR "No pack at 0x%x\n", i);
-#if 0
- saa7164_dumphex16FF(buf->port->dev, (p + i), 32);
-#endif
- }
- }
-}
-
-#define FIXED_VIDEO_PID 0xf1
-#define FIXED_AUDIO_PID 0xf2
-
-static void saa7164_ts_verifier(struct saa7164_buffer *buf)
-{
- struct saa7164_port *port = buf->port;
- u32 i;
- u8 cc, a;
- u16 pid;
- u8 __iomem *bufcpu = (u8 *)buf->cpu;
-
- port->sync_errors = 0;
- port->v_cc_errors = 0;
- port->a_cc_errors = 0;
-
- for (i = 0; i < buf->actual_size; i += 188) {
- if (*(bufcpu + i) != 0x47)
- port->sync_errors++;
-
- /* TODO: Query pid lower 8 bits, ignoring upper bits intensionally */
- pid = ((*(bufcpu + i + 1) & 0x1f) << 8) | *(bufcpu + i + 2);
- cc = *(bufcpu + i + 3) & 0x0f;
-
- if (pid == FIXED_VIDEO_PID) {
- a = ((port->last_v_cc + 1) & 0x0f);
- if (a != cc) {
- printk(KERN_ERR "video cc last = %x current = %x i = %d\n",
- port->last_v_cc, cc, i);
- port->v_cc_errors++;
- }
-
- port->last_v_cc = cc;
- } else
- if (pid == FIXED_AUDIO_PID) {
- a = ((port->last_a_cc + 1) & 0x0f);
- if (a != cc) {
- printk(KERN_ERR "audio cc last = %x current = %x i = %d\n",
- port->last_a_cc, cc, i);
- port->a_cc_errors++;
- }
-
- port->last_a_cc = cc;
- }
-
- }
-
- /* Only report errors if we've been through this function atleast
- * once already and the cached cc values are primed. First time through
- * always generates errors.
- */
- if (port->v_cc_errors && (port->done_first_interrupt > 1))
- printk(KERN_ERR "video pid cc, %d errors\n", port->v_cc_errors);
-
- if (port->a_cc_errors && (port->done_first_interrupt > 1))
- printk(KERN_ERR "audio pid cc, %d errors\n", port->a_cc_errors);
-
- if (port->sync_errors && (port->done_first_interrupt > 1))
- printk(KERN_ERR "sync_errors = %d\n", port->sync_errors);
-
- if (port->done_first_interrupt == 1)
- port->done_first_interrupt++;
-}
-
-static void saa7164_histogram_reset(struct saa7164_histogram *hg, char *name)
-{
- int i;
-
- memset(hg, 0, sizeof(struct saa7164_histogram));
- strcpy(hg->name, name);
-
- /* First 30ms x 1ms */
- for (i = 0; i < 30; i++)
- hg->counter1[0 + i].val = i;
-
- /* 30 - 200ms x 10ms */
- for (i = 0; i < 18; i++)
- hg->counter1[30 + i].val = 30 + (i * 10);
-
- /* 200 - 2000ms x 100ms */
- for (i = 0; i < 15; i++)
- hg->counter1[48 + i].val = 200 + (i * 200);
-
- /* Catch all massive value (2secs) */
- hg->counter1[55].val = 2000;
-
- /* Catch all massive value (4secs) */
- hg->counter1[56].val = 4000;
-
- /* Catch all massive value (8secs) */
- hg->counter1[57].val = 8000;
-
- /* Catch all massive value (15secs) */
- hg->counter1[58].val = 15000;
-
- /* Catch all massive value (30secs) */
- hg->counter1[59].val = 30000;
-
- /* Catch all massive value (60secs) */
- hg->counter1[60].val = 60000;
-
- /* Catch all massive value (5mins) */
- hg->counter1[61].val = 300000;
-
- /* Catch all massive value (15mins) */
- hg->counter1[62].val = 900000;
-
- /* Catch all massive values (1hr) */
- hg->counter1[63].val = 3600000;
-}
-
-void saa7164_histogram_update(struct saa7164_histogram *hg, u32 val)
-{
- int i;
- for (i = 0; i < 64; i++) {
- if (val <= hg->counter1[i].val) {
- hg->counter1[i].count++;
- hg->counter1[i].update_time = jiffies;
- break;
- }
- }
-}
-
-static void saa7164_histogram_print(struct saa7164_port *port,
- struct saa7164_histogram *hg)
-{
- u32 entries = 0;
- int i;
-
- printk(KERN_ERR "Histogram named %s (ms, count, last_update_jiffy)\n", hg->name);
- for (i = 0; i < 64; i++) {
- if (hg->counter1[i].count == 0)
- continue;
-
- printk(KERN_ERR " %4d %12d %Ld\n",
- hg->counter1[i].val,
- hg->counter1[i].count,
- hg->counter1[i].update_time);
-
- entries++;
- }
- printk(KERN_ERR "Total: %d\n", entries);
-}
-
-static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr)
-{
- struct saa7164_dev *dev = port->dev;
- struct saa7164_buffer *buf = NULL;
- struct saa7164_user_buffer *ubuf = NULL;
- struct list_head *c, *n;
- int i = 0;
- u8 __iomem *p;
-
- mutex_lock(&port->dmaqueue_lock);
- list_for_each_safe(c, n, &port->dmaqueue.list) {
-
- buf = list_entry(c, struct saa7164_buffer, list);
- if (i++ > port->hwcfg.buffercount) {
- printk(KERN_ERR "%s() illegal i count %d\n",
- __func__, i);
- break;
- }
-
- if (buf->idx == bufnr) {
-
- /* Found the buffer, deal with it */
- dprintk(DBGLVL_IRQ, "%s() bufnr: %d\n", __func__, bufnr);
-
- if (crc_checking) {
- /* Throw a new checksum on the dma buffer */
- buf->crc = crc32(0, buf->cpu, buf->actual_size);
- }
-
- if (guard_checking) {
- p = (u8 *)buf->cpu;
- if ((*(p + buf->actual_size + 0) != 0xff) ||
- (*(p + buf->actual_size + 1) != 0xff) ||
- (*(p + buf->actual_size + 2) != 0xff) ||
- (*(p + buf->actual_size + 3) != 0xff) ||
- (*(p + buf->actual_size + 0x10) != 0xff) ||
- (*(p + buf->actual_size + 0x11) != 0xff) ||
- (*(p + buf->actual_size + 0x12) != 0xff) ||
- (*(p + buf->actual_size + 0x13) != 0xff)) {
- printk(KERN_ERR "%s() buf %p guard buffer breach\n",
- __func__, buf);
-#if 0
- saa7164_dumphex16FF(dev, (p + buf->actual_size) - 32 , 64);
-#endif
- }
- }
-
- if ((port->nr != SAA7164_PORT_VBI1) && (port->nr != SAA7164_PORT_VBI2)) {
- /* Validate the incoming buffer content */
- if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)
- saa7164_ts_verifier(buf);
- else if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS)
- saa7164_pack_verifier(buf);
- }
-
- /* find a free user buffer and clone to it */
- if (!list_empty(&port->list_buf_free.list)) {
-
- /* Pull the first buffer from the used list */
- ubuf = list_first_entry(&port->list_buf_free.list,
- struct saa7164_user_buffer, list);
-
- if (buf->actual_size <= ubuf->actual_size) {
-
- memcpy_fromio(ubuf->data, buf->cpu,
- ubuf->actual_size);
-
- if (crc_checking) {
- /* Throw a new checksum on the read buffer */
- ubuf->crc = crc32(0, ubuf->data, ubuf->actual_size);
- }
-
- /* Requeue the buffer on the free list */
- ubuf->pos = 0;
-
- list_move_tail(&ubuf->list,
- &port->list_buf_used.list);
-
- /* Flag any userland waiters */
- wake_up_interruptible(&port->wait_read);
-
- } else {
- printk(KERN_ERR "buf %p bufsize fails match\n", buf);
- }
-
- } else
- printk(KERN_ERR "encirq no free buffers, increase param encoder_buffers\n");
-
- /* Ensure offset into buffer remains 0, fill buffer
- * with known bad data. We check for this data at a later point
- * in time. */
- saa7164_buffer_zero_offsets(port, bufnr);
- memset_io(buf->cpu, 0xff, buf->pci_size);
- if (crc_checking) {
- /* Throw yet aanother new checksum on the dma buffer */
- buf->crc = crc32(0, buf->cpu, buf->actual_size);
- }
-
- break;
- }
- }
- mutex_unlock(&port->dmaqueue_lock);
-}
-
-static void saa7164_work_enchandler(struct work_struct *w)
-{
- struct saa7164_port *port =
- container_of(w, struct saa7164_port, workenc);
- struct saa7164_dev *dev = port->dev;
-
- u32 wp, mcb, rp, cnt = 0;
-
- port->last_svc_msecs_diff = port->last_svc_msecs;
- port->last_svc_msecs = jiffies_to_msecs(jiffies);
-
- port->last_svc_msecs_diff = port->last_svc_msecs -
- port->last_svc_msecs_diff;
-
- saa7164_histogram_update(&port->svc_interval,
- port->last_svc_msecs_diff);
-
- port->last_irq_svc_msecs_diff = port->last_svc_msecs -
- port->last_irq_msecs;
-
- saa7164_histogram_update(&port->irq_svc_interval,
- port->last_irq_svc_msecs_diff);
-
- dprintk(DBGLVL_IRQ,
- "%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n",
- __func__,
- port->last_svc_msecs_diff,
- port->last_irq_svc_msecs_diff,
- port->last_svc_wp,
- port->last_svc_rp
- );
-
- /* Current write position */
- wp = saa7164_readl(port->bufcounter);
- if (wp > (port->hwcfg.buffercount - 1)) {
- printk(KERN_ERR "%s() illegal buf count %d\n", __func__, wp);
- return;
- }
-
- /* Most current complete buffer */
- if (wp == 0)
- mcb = (port->hwcfg.buffercount - 1);
- else
- mcb = wp - 1;
-
- while (1) {
- if (port->done_first_interrupt == 0) {
- port->done_first_interrupt++;
- rp = mcb;
- } else
- rp = (port->last_svc_rp + 1) % 8;
-
- if ((rp < 0) || (rp > (port->hwcfg.buffercount - 1))) {
- printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp);
- break;
- }
-
- saa7164_work_enchandler_helper(port, rp);
- port->last_svc_rp = rp;
- cnt++;
-
- if (rp == mcb)
- break;
- }
-
- /* TODO: Convert this into a /proc/saa7164 style readable file */
- if (print_histogram == port->nr) {
- saa7164_histogram_print(port, &port->irq_interval);
- saa7164_histogram_print(port, &port->svc_interval);
- saa7164_histogram_print(port, &port->irq_svc_interval);
- saa7164_histogram_print(port, &port->read_interval);
- saa7164_histogram_print(port, &port->poll_interval);
- /* TODO: fix this to preserve any previous state */
- print_histogram = 64 + port->nr;
- }
-}
-
-static void saa7164_work_vbihandler(struct work_struct *w)
-{
- struct saa7164_port *port =
- container_of(w, struct saa7164_port, workenc);
- struct saa7164_dev *dev = port->dev;
-
- u32 wp, mcb, rp, cnt = 0;
-
- port->last_svc_msecs_diff = port->last_svc_msecs;
- port->last_svc_msecs = jiffies_to_msecs(jiffies);
- port->last_svc_msecs_diff = port->last_svc_msecs -
- port->last_svc_msecs_diff;
-
- saa7164_histogram_update(&port->svc_interval,
- port->last_svc_msecs_diff);
-
- port->last_irq_svc_msecs_diff = port->last_svc_msecs -
- port->last_irq_msecs;
-
- saa7164_histogram_update(&port->irq_svc_interval,
- port->last_irq_svc_msecs_diff);
-
- dprintk(DBGLVL_IRQ,
- "%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n",
- __func__,
- port->last_svc_msecs_diff,
- port->last_irq_svc_msecs_diff,
- port->last_svc_wp,
- port->last_svc_rp
- );
-
- /* Current write position */
- wp = saa7164_readl(port->bufcounter);
- if (wp > (port->hwcfg.buffercount - 1)) {
- printk(KERN_ERR "%s() illegal buf count %d\n", __func__, wp);
- return;
- }
-
- /* Most current complete buffer */
- if (wp == 0)
- mcb = (port->hwcfg.buffercount - 1);
- else
- mcb = wp - 1;
-
- while (1) {
- if (port->done_first_interrupt == 0) {
- port->done_first_interrupt++;
- rp = mcb;
- } else
- rp = (port->last_svc_rp + 1) % 8;
-
- if ((rp < 0) || (rp > (port->hwcfg.buffercount - 1))) {
- printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp);
- break;
- }
-
- saa7164_work_enchandler_helper(port, rp);
- port->last_svc_rp = rp;
- cnt++;
-
- if (rp == mcb)
- break;
- }
-
- /* TODO: Convert this into a /proc/saa7164 style readable file */
- if (print_histogram == port->nr) {
- saa7164_histogram_print(port, &port->irq_interval);
- saa7164_histogram_print(port, &port->svc_interval);
- saa7164_histogram_print(port, &port->irq_svc_interval);
- saa7164_histogram_print(port, &port->read_interval);
- saa7164_histogram_print(port, &port->poll_interval);
- /* TODO: fix this to preserve any previous state */
- print_histogram = 64 + port->nr;
- }
-}
-
-static void saa7164_work_cmdhandler(struct work_struct *w)
-{
- struct saa7164_dev *dev = container_of(w, struct saa7164_dev, workcmd);
-
- /* Wake up any complete commands */
- saa7164_irq_dequeue(dev);
-}
-
-static void saa7164_buffer_deliver(struct saa7164_buffer *buf)
-{
- struct saa7164_port *port = buf->port;
-
- /* Feed the transport payload into the kernel demux */
- dvb_dmx_swfilter_packets(&port->dvb.demux, (u8 *)buf->cpu,
- SAA7164_TS_NUMBER_OF_LINES);
-
-}
-
-static irqreturn_t saa7164_irq_vbi(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
-
- /* Store old time */
- port->last_irq_msecs_diff = port->last_irq_msecs;
-
- /* Collect new stats */
- port->last_irq_msecs = jiffies_to_msecs(jiffies);
-
- /* Calculate stats */
- port->last_irq_msecs_diff = port->last_irq_msecs -
- port->last_irq_msecs_diff;
-
- saa7164_histogram_update(&port->irq_interval,
- port->last_irq_msecs_diff);
-
- dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed\n", __func__,
- port->last_irq_msecs_diff);
-
- /* Tis calls the vbi irq handler */
- schedule_work(&port->workenc);
- return 0;
-}
-
-static irqreturn_t saa7164_irq_encoder(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
-
- /* Store old time */
- port->last_irq_msecs_diff = port->last_irq_msecs;
-
- /* Collect new stats */
- port->last_irq_msecs = jiffies_to_msecs(jiffies);
-
- /* Calculate stats */
- port->last_irq_msecs_diff = port->last_irq_msecs -
- port->last_irq_msecs_diff;
-
- saa7164_histogram_update(&port->irq_interval,
- port->last_irq_msecs_diff);
-
- dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed\n", __func__,
- port->last_irq_msecs_diff);
-
- schedule_work(&port->workenc);
- return 0;
-}
-
-static irqreturn_t saa7164_irq_ts(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- struct saa7164_buffer *buf;
- struct list_head *c, *n;
- int wp, i = 0, rp;
-
- /* Find the current write point from the hardware */
- wp = saa7164_readl(port->bufcounter);
- if (wp > (port->hwcfg.buffercount - 1))
- BUG();
-
- /* Find the previous buffer to the current write point */
- if (wp == 0)
- rp = (port->hwcfg.buffercount - 1);
- else
- rp = wp - 1;
-
- /* Lookup the WP in the buffer list */
- /* TODO: turn this into a worker thread */
- list_for_each_safe(c, n, &port->dmaqueue.list) {
- buf = list_entry(c, struct saa7164_buffer, list);
- if (i++ > port->hwcfg.buffercount)
- BUG();
-
- if (buf->idx == rp) {
- /* Found the buffer, deal with it */
- dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n",
- __func__, wp, rp);
- saa7164_buffer_deliver(buf);
- break;
- }
-
- }
- return 0;
-}
-
-/* Primary IRQ handler and dispatch mechanism */
-static irqreturn_t saa7164_irq(int irq, void *dev_id)
-{
- struct saa7164_dev *dev = dev_id;
- struct saa7164_port *porta = &dev->ports[SAA7164_PORT_TS1];
- struct saa7164_port *portb = &dev->ports[SAA7164_PORT_TS2];
- struct saa7164_port *portc = &dev->ports[SAA7164_PORT_ENC1];
- struct saa7164_port *portd = &dev->ports[SAA7164_PORT_ENC2];
- struct saa7164_port *porte = &dev->ports[SAA7164_PORT_VBI1];
- struct saa7164_port *portf = &dev->ports[SAA7164_PORT_VBI2];
-
- u32 intid, intstat[INT_SIZE/4];
- int i, handled = 0, bit;
-
- if (dev == NULL) {
- printk(KERN_ERR "%s() No device specified\n", __func__);
- handled = 0;
- goto out;
- }
-
- /* Check that the hardware is accessible. If the status bytes are
- * 0xFF then the device is not accessible, the the IRQ belongs
- * to another driver.
- * 4 x u32 interrupt registers.
- */
- for (i = 0; i < INT_SIZE/4; i++) {
-
- /* TODO: Convert into saa7164_readl() */
- /* Read the 4 hardware interrupt registers */
- intstat[i] = saa7164_readl(dev->int_status + (i * 4));
-
- if (intstat[i])
- handled = 1;
- }
- if (handled == 0)
- goto out;
-
- /* For each of the HW interrupt registers */
- for (i = 0; i < INT_SIZE/4; i++) {
-
- if (intstat[i]) {
- /* Each function of the board has it's own interruptid.
- * Find the function that triggered then call
- * it's handler.
- */
- for (bit = 0; bit < 32; bit++) {
-
- if (((intstat[i] >> bit) & 0x00000001) == 0)
- continue;
-
- /* Calculate the interrupt id (0x00 to 0x7f) */
-
- intid = (i * 32) + bit;
- if (intid == dev->intfdesc.bInterruptId) {
- /* A response to an cmd/api call */
- schedule_work(&dev->workcmd);
- } else if (intid == porta->hwcfg.interruptid) {
-
- /* Transport path 1 */
- saa7164_irq_ts(porta);
-
- } else if (intid == portb->hwcfg.interruptid) {
-
- /* Transport path 2 */
- saa7164_irq_ts(portb);
-
- } else if (intid == portc->hwcfg.interruptid) {
-
- /* Encoder path 1 */
- saa7164_irq_encoder(portc);
-
- } else if (intid == portd->hwcfg.interruptid) {
-
- /* Encoder path 2 */
- saa7164_irq_encoder(portd);
-
- } else if (intid == porte->hwcfg.interruptid) {
-
- /* VBI path 1 */
- saa7164_irq_vbi(porte);
-
- } else if (intid == portf->hwcfg.interruptid) {
-
- /* VBI path 2 */
- saa7164_irq_vbi(portf);
-
- } else {
- /* Find the function */
- dprintk(DBGLVL_IRQ,
- "%s() unhandled interrupt "
- "reg 0x%x bit 0x%x "
- "intid = 0x%x\n",
- __func__, i, bit, intid);
- }
- }
-
- /* Ack it */
- saa7164_writel(dev->int_ack + (i * 4), intstat[i]);
-
- }
- }
-out:
- return IRQ_RETVAL(handled);
-}
-
-void saa7164_getfirmwarestatus(struct saa7164_dev *dev)
-{
- struct saa7164_fw_status *s = &dev->fw_status;
-
- dev->fw_status.status = saa7164_readl(SAA_DEVICE_SYSINIT_STATUS);
- dev->fw_status.mode = saa7164_readl(SAA_DEVICE_SYSINIT_MODE);
- dev->fw_status.spec = saa7164_readl(SAA_DEVICE_SYSINIT_SPEC);
- dev->fw_status.inst = saa7164_readl(SAA_DEVICE_SYSINIT_INST);
- dev->fw_status.cpuload = saa7164_readl(SAA_DEVICE_SYSINIT_CPULOAD);
- dev->fw_status.remainheap =
- saa7164_readl(SAA_DEVICE_SYSINIT_REMAINHEAP);
-
- dprintk(1, "Firmware status:\n");
- dprintk(1, " .status = 0x%08x\n", s->status);
- dprintk(1, " .mode = 0x%08x\n", s->mode);
- dprintk(1, " .spec = 0x%08x\n", s->spec);
- dprintk(1, " .inst = 0x%08x\n", s->inst);
- dprintk(1, " .cpuload = 0x%08x\n", s->cpuload);
- dprintk(1, " .remainheap = 0x%08x\n", s->remainheap);
-}
-
-u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev)
-{
- u32 reg;
-
- reg = saa7164_readl(SAA_DEVICE_VERSION);
- dprintk(1, "Device running firmware version %d.%d.%d.%d (0x%x)\n",
- (reg & 0x0000fc00) >> 10,
- (reg & 0x000003e0) >> 5,
- (reg & 0x0000001f),
- (reg & 0xffff0000) >> 16,
- reg);
-
- return reg;
-}
-
-/* TODO: Debugging func, remove */
-void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len)
-{
- int i;
-
- printk(KERN_INFO "--------------------> "
- "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
-
- for (i = 0; i < len; i += 16)
- printk(KERN_INFO " [0x%08x] "
- "%02x %02x %02x %02x %02x %02x %02x %02x "
- "%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
- *(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3),
- *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7),
- *(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11),
- *(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15));
-}
-
-/* TODO: Debugging func, remove */
-void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr)
-{
- int i;
-
- dprintk(1, "--------------------> "
- "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
-
- for (i = 0; i < 0x100; i += 16)
- dprintk(1, "region0[0x%08x] = "
- "%02x %02x %02x %02x %02x %02x %02x %02x"
- " %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
- (u8)saa7164_readb(addr + i + 0),
- (u8)saa7164_readb(addr + i + 1),
- (u8)saa7164_readb(addr + i + 2),
- (u8)saa7164_readb(addr + i + 3),
- (u8)saa7164_readb(addr + i + 4),
- (u8)saa7164_readb(addr + i + 5),
- (u8)saa7164_readb(addr + i + 6),
- (u8)saa7164_readb(addr + i + 7),
- (u8)saa7164_readb(addr + i + 8),
- (u8)saa7164_readb(addr + i + 9),
- (u8)saa7164_readb(addr + i + 10),
- (u8)saa7164_readb(addr + i + 11),
- (u8)saa7164_readb(addr + i + 12),
- (u8)saa7164_readb(addr + i + 13),
- (u8)saa7164_readb(addr + i + 14),
- (u8)saa7164_readb(addr + i + 15)
- );
-}
-
-static void saa7164_dump_hwdesc(struct saa7164_dev *dev)
-{
- dprintk(1, "@0x%p hwdesc sizeof(struct tmComResHWDescr) = %d bytes\n",
- &dev->hwdesc, (u32)sizeof(struct tmComResHWDescr));
-
- dprintk(1, " .bLength = 0x%x\n", dev->hwdesc.bLength);
- dprintk(1, " .bDescriptorType = 0x%x\n", dev->hwdesc.bDescriptorType);
- dprintk(1, " .bDescriptorSubtype = 0x%x\n",
- dev->hwdesc.bDescriptorSubtype);
-
- dprintk(1, " .bcdSpecVersion = 0x%x\n", dev->hwdesc.bcdSpecVersion);
- dprintk(1, " .dwClockFrequency = 0x%x\n", dev->hwdesc.dwClockFrequency);
- dprintk(1, " .dwClockUpdateRes = 0x%x\n", dev->hwdesc.dwClockUpdateRes);
- dprintk(1, " .bCapabilities = 0x%x\n", dev->hwdesc.bCapabilities);
- dprintk(1, " .dwDeviceRegistersLocation = 0x%x\n",
- dev->hwdesc.dwDeviceRegistersLocation);
-
- dprintk(1, " .dwHostMemoryRegion = 0x%x\n",
- dev->hwdesc.dwHostMemoryRegion);
-
- dprintk(1, " .dwHostMemoryRegionSize = 0x%x\n",
- dev->hwdesc.dwHostMemoryRegionSize);
-
- dprintk(1, " .dwHostHibernatMemRegion = 0x%x\n",
- dev->hwdesc.dwHostHibernatMemRegion);
-
- dprintk(1, " .dwHostHibernatMemRegionSize = 0x%x\n",
- dev->hwdesc.dwHostHibernatMemRegionSize);
-}
-
-static void saa7164_dump_intfdesc(struct saa7164_dev *dev)
-{
- dprintk(1, "@0x%p intfdesc "
- "sizeof(struct tmComResInterfaceDescr) = %d bytes\n",
- &dev->intfdesc, (u32)sizeof(struct tmComResInterfaceDescr));
-
- dprintk(1, " .bLength = 0x%x\n", dev->intfdesc.bLength);
- dprintk(1, " .bDescriptorType = 0x%x\n", dev->intfdesc.bDescriptorType);
- dprintk(1, " .bDescriptorSubtype = 0x%x\n",
- dev->intfdesc.bDescriptorSubtype);
-
- dprintk(1, " .bFlags = 0x%x\n", dev->intfdesc.bFlags);
- dprintk(1, " .bInterfaceType = 0x%x\n", dev->intfdesc.bInterfaceType);
- dprintk(1, " .bInterfaceId = 0x%x\n", dev->intfdesc.bInterfaceId);
- dprintk(1, " .bBaseInterface = 0x%x\n", dev->intfdesc.bBaseInterface);
- dprintk(1, " .bInterruptId = 0x%x\n", dev->intfdesc.bInterruptId);
- dprintk(1, " .bDebugInterruptId = 0x%x\n",
- dev->intfdesc.bDebugInterruptId);
-
- dprintk(1, " .BARLocation = 0x%x\n", dev->intfdesc.BARLocation);
-}
-
-static void saa7164_dump_busdesc(struct saa7164_dev *dev)
-{
- dprintk(1, "@0x%p busdesc sizeof(struct tmComResBusDescr) = %d bytes\n",
- &dev->busdesc, (u32)sizeof(struct tmComResBusDescr));
-
- dprintk(1, " .CommandRing = 0x%016Lx\n", dev->busdesc.CommandRing);
- dprintk(1, " .ResponseRing = 0x%016Lx\n", dev->busdesc.ResponseRing);
- dprintk(1, " .CommandWrite = 0x%x\n", dev->busdesc.CommandWrite);
- dprintk(1, " .CommandRead = 0x%x\n", dev->busdesc.CommandRead);
- dprintk(1, " .ResponseWrite = 0x%x\n", dev->busdesc.ResponseWrite);
- dprintk(1, " .ResponseRead = 0x%x\n", dev->busdesc.ResponseRead);
-}
-
-/* Much of the hardware configuration and PCI registers are configured
- * dynamically depending on firmware. We have to cache some initial
- * structures then use these to locate other important structures
- * from PCI space.
- */
-static void saa7164_get_descriptors(struct saa7164_dev *dev)
-{
- memcpy_fromio(&dev->hwdesc, dev->bmmio, sizeof(struct tmComResHWDescr));
- memcpy_fromio(&dev->intfdesc, dev->bmmio + sizeof(struct tmComResHWDescr),
- sizeof(struct tmComResInterfaceDescr));
- memcpy_fromio(&dev->busdesc, dev->bmmio + dev->intfdesc.BARLocation,
- sizeof(struct tmComResBusDescr));
-
- if (dev->hwdesc.bLength != sizeof(struct tmComResHWDescr)) {
- printk(KERN_ERR "Structure struct tmComResHWDescr is mangled\n");
- printk(KERN_ERR "Need %x got %d\n", dev->hwdesc.bLength,
- (u32)sizeof(struct tmComResHWDescr));
- } else
- saa7164_dump_hwdesc(dev);
-
- if (dev->intfdesc.bLength != sizeof(struct tmComResInterfaceDescr)) {
- printk(KERN_ERR "struct struct tmComResInterfaceDescr is mangled\n");
- printk(KERN_ERR "Need %x got %d\n", dev->intfdesc.bLength,
- (u32)sizeof(struct tmComResInterfaceDescr));
- } else
- saa7164_dump_intfdesc(dev);
-
- saa7164_dump_busdesc(dev);
-}
-
-static int saa7164_pci_quirks(struct saa7164_dev *dev)
-{
- return 0;
-}
-
-static int get_resources(struct saa7164_dev *dev)
-{
- if (request_mem_region(pci_resource_start(dev->pci, 0),
- pci_resource_len(dev->pci, 0), dev->name)) {
-
- if (request_mem_region(pci_resource_start(dev->pci, 2),
- pci_resource_len(dev->pci, 2), dev->name))
- return 0;
- }
-
- printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx or 0x%llx\n",
- dev->name,
- (u64)pci_resource_start(dev->pci, 0),
- (u64)pci_resource_start(dev->pci, 2));
-
- return -EBUSY;
-}
-
-static int saa7164_port_init(struct saa7164_dev *dev, int portnr)
-{
- struct saa7164_port *port = NULL;
-
- if ((portnr < 0) || (portnr >= SAA7164_MAX_PORTS))
- BUG();
-
- port = &dev->ports[portnr];
-
- port->dev = dev;
- port->nr = portnr;
-
- if ((portnr == SAA7164_PORT_TS1) || (portnr == SAA7164_PORT_TS2))
- port->type = SAA7164_MPEG_DVB;
- else
- if ((portnr == SAA7164_PORT_ENC1) || (portnr == SAA7164_PORT_ENC2)) {
- port->type = SAA7164_MPEG_ENCODER;
-
- /* We need a deferred interrupt handler for cmd handling */
- INIT_WORK(&port->workenc, saa7164_work_enchandler);
- } else if ((portnr == SAA7164_PORT_VBI1) || (portnr == SAA7164_PORT_VBI2)) {
- port->type = SAA7164_MPEG_VBI;
-
- /* We need a deferred interrupt handler for cmd handling */
- INIT_WORK(&port->workenc, saa7164_work_vbihandler);
- } else
- BUG();
-
- /* Init all the critical resources */
- mutex_init(&port->dvb.lock);
- INIT_LIST_HEAD(&port->dmaqueue.list);
- mutex_init(&port->dmaqueue_lock);
-
- INIT_LIST_HEAD(&port->list_buf_used.list);
- INIT_LIST_HEAD(&port->list_buf_free.list);
- init_waitqueue_head(&port->wait_read);
-
-
- saa7164_histogram_reset(&port->irq_interval, "irq intervals");
- saa7164_histogram_reset(&port->svc_interval, "deferred intervals");
- saa7164_histogram_reset(&port->irq_svc_interval,
- "irq to deferred intervals");
- saa7164_histogram_reset(&port->read_interval,
- "encoder/vbi read() intervals");
- saa7164_histogram_reset(&port->poll_interval,
- "encoder/vbi poll() intervals");
-
- return 0;
-}
-
-static int saa7164_dev_setup(struct saa7164_dev *dev)
-{
- int i;
-
- mutex_init(&dev->lock);
- atomic_inc(&dev->refcount);
- dev->nr = saa7164_devcount++;
-
- snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr);
-
- mutex_lock(&devlist);
- list_add_tail(&dev->devlist, &saa7164_devlist);
- mutex_unlock(&devlist);
-
- /* board config */
- dev->board = UNSET;
- if (card[dev->nr] < saa7164_bcount)
- dev->board = card[dev->nr];
-
- for (i = 0; UNSET == dev->board && i < saa7164_idcount; i++)
- if (dev->pci->subsystem_vendor == saa7164_subids[i].subvendor &&
- dev->pci->subsystem_device ==
- saa7164_subids[i].subdevice)
- dev->board = saa7164_subids[i].card;
-
- if (UNSET == dev->board) {
- dev->board = SAA7164_BOARD_UNKNOWN;
- saa7164_card_list(dev);
- }
-
- dev->pci_bus = dev->pci->bus->number;
- dev->pci_slot = PCI_SLOT(dev->pci->devfn);
-
- /* I2C Defaults / setup */
- dev->i2c_bus[0].dev = dev;
- dev->i2c_bus[0].nr = 0;
- dev->i2c_bus[1].dev = dev;
- dev->i2c_bus[1].nr = 1;
- dev->i2c_bus[2].dev = dev;
- dev->i2c_bus[2].nr = 2;
-
- /* Transport + Encoder ports 1, 2, 3, 4 - Defaults / setup */
- saa7164_port_init(dev, SAA7164_PORT_TS1);
- saa7164_port_init(dev, SAA7164_PORT_TS2);
- saa7164_port_init(dev, SAA7164_PORT_ENC1);
- saa7164_port_init(dev, SAA7164_PORT_ENC2);
- saa7164_port_init(dev, SAA7164_PORT_VBI1);
- saa7164_port_init(dev, SAA7164_PORT_VBI2);
-
- if (get_resources(dev) < 0) {
- printk(KERN_ERR "CORE %s No more PCIe resources for "
- "subsystem: %04x:%04x\n",
- dev->name, dev->pci->subsystem_vendor,
- dev->pci->subsystem_device);
-
- saa7164_devcount--;
- return -ENODEV;
- }
-
- /* PCI/e allocations */
- dev->lmmio = ioremap(pci_resource_start(dev->pci, 0),
- pci_resource_len(dev->pci, 0));
-
- dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2),
- pci_resource_len(dev->pci, 2));
-
- dev->bmmio = (u8 __iomem *)dev->lmmio;
- dev->bmmio2 = (u8 __iomem *)dev->lmmio2;
-
- /* Inerrupt and ack register locations offset of bmmio */
- dev->int_status = 0x183000 + 0xf80;
- dev->int_ack = 0x183000 + 0xf90;
-
- printk(KERN_INFO
- "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
- dev->name, dev->pci->subsystem_vendor,
- dev->pci->subsystem_device, saa7164_boards[dev->board].name,
- dev->board, card[dev->nr] == dev->board ?
- "insmod option" : "autodetected");
-
- saa7164_pci_quirks(dev);
-
- return 0;
-}
-
-static void saa7164_dev_unregister(struct saa7164_dev *dev)
-{
- dprintk(1, "%s()\n", __func__);
-
- release_mem_region(pci_resource_start(dev->pci, 0),
- pci_resource_len(dev->pci, 0));
-
- release_mem_region(pci_resource_start(dev->pci, 2),
- pci_resource_len(dev->pci, 2));
-
- if (!atomic_dec_and_test(&dev->refcount))
- return;
-
- iounmap(dev->lmmio);
- iounmap(dev->lmmio2);
-
- return;
-}
-
-#ifdef CONFIG_PROC_FS
-static int saa7164_proc_show(struct seq_file *m, void *v)
-{
- struct saa7164_dev *dev;
- struct tmComResBusInfo *b;
- struct list_head *list;
- int i, c;
-
- if (saa7164_devcount == 0)
- return 0;
-
- list_for_each(list, &saa7164_devlist) {
- dev = list_entry(list, struct saa7164_dev, devlist);
- seq_printf(m, "%s = %p\n", dev->name, dev);
-
- /* Lock the bus from any other access */
- b = &dev->bus;
- mutex_lock(&b->lock);
-
- seq_printf(m, " .m_pdwSetWritePos = 0x%x (0x%08x)\n",
- b->m_dwSetReadPos, saa7164_readl(b->m_dwSetReadPos));
-
- seq_printf(m, " .m_pdwSetReadPos = 0x%x (0x%08x)\n",
- b->m_dwSetWritePos, saa7164_readl(b->m_dwSetWritePos));
-
- seq_printf(m, " .m_pdwGetWritePos = 0x%x (0x%08x)\n",
- b->m_dwGetReadPos, saa7164_readl(b->m_dwGetReadPos));
-
- seq_printf(m, " .m_pdwGetReadPos = 0x%x (0x%08x)\n",
- b->m_dwGetWritePos, saa7164_readl(b->m_dwGetWritePos));
- c = 0;
- seq_printf(m, "\n Set Ring:\n");
- seq_printf(m, "\n addr 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
- for (i = 0; i < b->m_dwSizeSetRing; i++) {
- if (c == 0)
- seq_printf(m, " %04x:", i);
-
- seq_printf(m, " %02x", *(b->m_pdwSetRing + i));
-
- if (++c == 16) {
- seq_printf(m, "\n");
- c = 0;
- }
- }
-
- c = 0;
- seq_printf(m, "\n Get Ring:\n");
- seq_printf(m, "\n addr 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
- for (i = 0; i < b->m_dwSizeGetRing; i++) {
- if (c == 0)
- seq_printf(m, " %04x:", i);
-
- seq_printf(m, " %02x", *(b->m_pdwGetRing + i));
-
- if (++c == 16) {
- seq_printf(m, "\n");
- c = 0;
- }
- }
-
- mutex_unlock(&b->lock);
-
- }
-
- return 0;
-}
-
-static int saa7164_proc_open(struct inode *inode, struct file *filp)
-{
- return single_open(filp, saa7164_proc_show, NULL);
-}
-
-static const struct file_operations saa7164_proc_fops = {
- .open = saa7164_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int saa7164_proc_create(void)
-{
- struct proc_dir_entry *pe;
-
- pe = proc_create("saa7164", S_IRUGO, NULL, &saa7164_proc_fops);
- if (!pe)
- return -ENOMEM;
-
- return 0;
-}
-#endif
-
-static int saa7164_thread_function(void *data)
-{
- struct saa7164_dev *dev = data;
- struct tmFwInfoStruct fwinfo;
- u64 last_poll_time = 0;
-
- dprintk(DBGLVL_THR, "thread started\n");
-
- set_freezable();
-
- while (1) {
- msleep_interruptible(100);
- if (kthread_should_stop())
- break;
- try_to_freeze();
-
- dprintk(DBGLVL_THR, "thread running\n");
-
- /* Dump the firmware debug message to console */
- /* Polling this costs us 1-2% of the arm CPU */
- /* convert this into a respnde to interrupt 0x7a */
- saa7164_api_collect_debug(dev);
-
- /* Monitor CPU load every 1 second */
- if ((last_poll_time + 1000 /* ms */) < jiffies_to_msecs(jiffies)) {
- saa7164_api_get_load_info(dev, &fwinfo);
- last_poll_time = jiffies_to_msecs(jiffies);
- }
-
- }
-
- dprintk(DBGLVL_THR, "thread exiting\n");
- return 0;
-}
-
-static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
-{
- struct saa7164_dev *dev;
- int err, i;
- u32 version;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (NULL == dev)
- return -ENOMEM;
-
- /* pci init */
- dev->pci = pci_dev;
- if (pci_enable_device(pci_dev)) {
- err = -EIO;
- goto fail_free;
- }
-
- if (saa7164_dev_setup(dev) < 0) {
- err = -EINVAL;
- goto fail_free;
- }
-
- /* print pci info */
- dev->pci_rev = pci_dev->revision;
- pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
- printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
- "latency: %d, mmio: 0x%llx\n", dev->name,
- pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
- dev->pci_lat,
- (unsigned long long)pci_resource_start(pci_dev, 0));
-
- pci_set_master(pci_dev);
- /* TODO */
- if (!pci_dma_supported(pci_dev, 0xffffffff)) {
- printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
- err = -EIO;
- goto fail_irq;
- }
-
- err = request_irq(pci_dev->irq, saa7164_irq,
- IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
- if (err < 0) {
- printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
- pci_dev->irq);
- err = -EIO;
- goto fail_irq;
- }
-
- pci_set_drvdata(pci_dev, dev);
-
- /* Init the internal command list */
- for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
- dev->cmds[i].seqno = i;
- dev->cmds[i].inuse = 0;
- mutex_init(&dev->cmds[i].lock);
- init_waitqueue_head(&dev->cmds[i].wait);
- }
-
- /* We need a deferred interrupt handler for cmd handling */
- INIT_WORK(&dev->workcmd, saa7164_work_cmdhandler);
-
- /* Only load the firmware if we know the board */
- if (dev->board != SAA7164_BOARD_UNKNOWN) {
-
- err = saa7164_downloadfirmware(dev);
- if (err < 0) {
- printk(KERN_ERR
- "Failed to boot firmware, no features "
- "registered\n");
- goto fail_fw;
- }
-
- saa7164_get_descriptors(dev);
- saa7164_dumpregs(dev, 0);
- saa7164_getcurrentfirmwareversion(dev);
- saa7164_getfirmwarestatus(dev);
- err = saa7164_bus_setup(dev);
- if (err < 0)
- printk(KERN_ERR
- "Failed to setup the bus, will continue\n");
- saa7164_bus_dump(dev);
-
- /* Ping the running firmware via the command bus and get the
- * firmware version, this checks the bus is running OK.
- */
- version = 0;
- if (saa7164_api_get_fw_version(dev, &version) == SAA_OK)
- dprintk(1, "Bus is operating correctly using "
- "version %d.%d.%d.%d (0x%x)\n",
- (version & 0x0000fc00) >> 10,
- (version & 0x000003e0) >> 5,
- (version & 0x0000001f),
- (version & 0xffff0000) >> 16,
- version);
- else
- printk(KERN_ERR
- "Failed to communicate with the firmware\n");
-
- /* Bring up the I2C buses */
- saa7164_i2c_register(&dev->i2c_bus[0]);
- saa7164_i2c_register(&dev->i2c_bus[1]);
- saa7164_i2c_register(&dev->i2c_bus[2]);
- saa7164_gpio_setup(dev);
- saa7164_card_setup(dev);
-
- /* Parse the dynamic device configuration, find various
- * media endpoints (MPEG, WMV, PS, TS) and cache their
- * configuration details into the driver, so we can
- * reference them later during simething_register() func,
- * interrupt handlers, deferred work handlers etc.
- */
- saa7164_api_enum_subdevs(dev);
-
- /* Begin to create the video sub-systems and register funcs */
- if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) {
- if (saa7164_dvb_register(&dev->ports[SAA7164_PORT_TS1]) < 0) {
- printk(KERN_ERR "%s() Failed to register "
- "dvb adapters on porta\n",
- __func__);
- }
- }
-
- if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) {
- if (saa7164_dvb_register(&dev->ports[SAA7164_PORT_TS2]) < 0) {
- printk(KERN_ERR"%s() Failed to register "
- "dvb adapters on portb\n",
- __func__);
- }
- }
-
- if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER) {
- if (saa7164_encoder_register(&dev->ports[SAA7164_PORT_ENC1]) < 0) {
- printk(KERN_ERR"%s() Failed to register "
- "mpeg encoder\n", __func__);
- }
- }
-
- if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER) {
- if (saa7164_encoder_register(&dev->ports[SAA7164_PORT_ENC2]) < 0) {
- printk(KERN_ERR"%s() Failed to register "
- "mpeg encoder\n", __func__);
- }
- }
-
- if (saa7164_boards[dev->board].porte == SAA7164_MPEG_VBI) {
- if (saa7164_vbi_register(&dev->ports[SAA7164_PORT_VBI1]) < 0) {
- printk(KERN_ERR"%s() Failed to register "
- "vbi device\n", __func__);
- }
- }
-
- if (saa7164_boards[dev->board].portf == SAA7164_MPEG_VBI) {
- if (saa7164_vbi_register(&dev->ports[SAA7164_PORT_VBI2]) < 0) {
- printk(KERN_ERR"%s() Failed to register "
- "vbi device\n", __func__);
- }
- }
- saa7164_api_set_debug(dev, fw_debug);
-
- if (fw_debug) {
- dev->kthread = kthread_run(saa7164_thread_function, dev,
- "saa7164 debug");
- if (!dev->kthread)
- printk(KERN_ERR "%s() Failed to create "
- "debug kernel thread\n", __func__);
- }
-
- } /* != BOARD_UNKNOWN */
- else
- printk(KERN_ERR "%s() Unsupported board detected, "
- "registering without firmware\n", __func__);
-
- dprintk(1, "%s() parameter debug = %d\n", __func__, saa_debug);
- dprintk(1, "%s() parameter waitsecs = %d\n", __func__, waitsecs);
-
-fail_fw:
- return 0;
-
-fail_irq:
- saa7164_dev_unregister(dev);
-fail_free:
- kfree(dev);
- return err;
-}
-
-static void saa7164_shutdown(struct saa7164_dev *dev)
-{
- dprintk(1, "%s()\n", __func__);
-}
-
-static void __devexit saa7164_finidev(struct pci_dev *pci_dev)
-{
- struct saa7164_dev *dev = pci_get_drvdata(pci_dev);
-
- if (dev->board != SAA7164_BOARD_UNKNOWN) {
- if (fw_debug && dev->kthread) {
- kthread_stop(dev->kthread);
- dev->kthread = NULL;
- }
- if (dev->firmwareloaded)
- saa7164_api_set_debug(dev, 0x00);
- }
-
- saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1],
- &dev->ports[SAA7164_PORT_ENC1].irq_interval);
- saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1],
- &dev->ports[SAA7164_PORT_ENC1].svc_interval);
- saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1],
- &dev->ports[SAA7164_PORT_ENC1].irq_svc_interval);
- saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1],
- &dev->ports[SAA7164_PORT_ENC1].read_interval);
- saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1],
- &dev->ports[SAA7164_PORT_ENC1].poll_interval);
- saa7164_histogram_print(&dev->ports[SAA7164_PORT_VBI1],
- &dev->ports[SAA7164_PORT_VBI1].read_interval);
- saa7164_histogram_print(&dev->ports[SAA7164_PORT_VBI2],
- &dev->ports[SAA7164_PORT_VBI2].poll_interval);
-
- saa7164_shutdown(dev);
-
- if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB)
- saa7164_dvb_unregister(&dev->ports[SAA7164_PORT_TS1]);
-
- if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB)
- saa7164_dvb_unregister(&dev->ports[SAA7164_PORT_TS2]);
-
- if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER)
- saa7164_encoder_unregister(&dev->ports[SAA7164_PORT_ENC1]);
-
- if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER)
- saa7164_encoder_unregister(&dev->ports[SAA7164_PORT_ENC2]);
-
- if (saa7164_boards[dev->board].porte == SAA7164_MPEG_VBI)
- saa7164_vbi_unregister(&dev->ports[SAA7164_PORT_VBI1]);
-
- if (saa7164_boards[dev->board].portf == SAA7164_MPEG_VBI)
- saa7164_vbi_unregister(&dev->ports[SAA7164_PORT_VBI2]);
-
- saa7164_i2c_unregister(&dev->i2c_bus[0]);
- saa7164_i2c_unregister(&dev->i2c_bus[1]);
- saa7164_i2c_unregister(&dev->i2c_bus[2]);
-
- pci_disable_device(pci_dev);
-
- /* unregister stuff */
- free_irq(pci_dev->irq, dev);
- pci_set_drvdata(pci_dev, NULL);
-
- mutex_lock(&devlist);
- list_del(&dev->devlist);
- mutex_unlock(&devlist);
-
- saa7164_dev_unregister(dev);
- kfree(dev);
-}
-
-static struct pci_device_id saa7164_pci_tbl[] = {
- {
- /* SAA7164 */
- .vendor = 0x1131,
- .device = 0x7164,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- }, {
- /* --- end of list --- */
- }
-};
-MODULE_DEVICE_TABLE(pci, saa7164_pci_tbl);
-
-static struct pci_driver saa7164_pci_driver = {
- .name = "saa7164",
- .id_table = saa7164_pci_tbl,
- .probe = saa7164_initdev,
- .remove = __devexit_p(saa7164_finidev),
- /* TODO */
- .suspend = NULL,
- .resume = NULL,
-};
-
-static int __init saa7164_init(void)
-{
- printk(KERN_INFO "saa7164 driver loaded\n");
-
-#ifdef CONFIG_PROC_FS
- saa7164_proc_create();
-#endif
- return pci_register_driver(&saa7164_pci_driver);
-}
-
-static void __exit saa7164_fini(void)
-{
-#ifdef CONFIG_PROC_FS
- remove_proc_entry("saa7164", NULL);
-#endif
- pci_unregister_driver(&saa7164_pci_driver);
-}
-
-module_init(saa7164_init);
-module_exit(saa7164_fini);
-
diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c
deleted file mode 100644
index 5c5cc3ebf9b..00000000000
--- a/drivers/media/video/saa7164/saa7164-dvb.c
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * Driver for the NXP SAA7164 PCIe bridge
- *
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "saa7164.h"
-
-#include "tda10048.h"
-#include "tda18271.h"
-#include "s5h1411.h"
-
-#define DRIVER_NAME "saa7164"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-/* addr is in the card struct, get it from there */
-static struct tda10048_config hauppauge_hvr2200_1_config = {
- .demod_address = 0x10 >> 1,
- .output_mode = TDA10048_SERIAL_OUTPUT,
- .fwbulkwritelen = TDA10048_BULKWRITE_200,
- .inversion = TDA10048_INVERSION_ON,
- .dtv6_if_freq_khz = TDA10048_IF_3300,
- .dtv7_if_freq_khz = TDA10048_IF_3500,
- .dtv8_if_freq_khz = TDA10048_IF_4000,
- .clk_freq_khz = TDA10048_CLK_16000,
-};
-static struct tda10048_config hauppauge_hvr2200_2_config = {
- .demod_address = 0x12 >> 1,
- .output_mode = TDA10048_SERIAL_OUTPUT,
- .fwbulkwritelen = TDA10048_BULKWRITE_200,
- .inversion = TDA10048_INVERSION_ON,
- .dtv6_if_freq_khz = TDA10048_IF_3300,
- .dtv7_if_freq_khz = TDA10048_IF_3500,
- .dtv8_if_freq_khz = TDA10048_IF_4000,
- .clk_freq_khz = TDA10048_CLK_16000,
-};
-
-static struct tda18271_std_map hauppauge_tda18271_std_map = {
- .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 3,
- .if_lvl = 6, .rfagc_top = 0x37 },
- .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
- .if_lvl = 6, .rfagc_top = 0x37 },
-};
-
-static struct tda18271_config hauppauge_hvr22x0_tuner_config = {
- .std_map = &hauppauge_tda18271_std_map,
- .gate = TDA18271_GATE_ANALOG,
- .role = TDA18271_MASTER,
-};
-
-static struct tda18271_config hauppauge_hvr22x0s_tuner_config = {
- .std_map = &hauppauge_tda18271_std_map,
- .gate = TDA18271_GATE_ANALOG,
- .role = TDA18271_SLAVE,
- .output_opt = TDA18271_OUTPUT_LT_OFF,
- .rf_cal_on_startup = 1
-};
-
-static struct s5h1411_config hauppauge_s5h1411_config = {
- .output_mode = S5H1411_SERIAL_OUTPUT,
- .gpio = S5H1411_GPIO_ON,
- .qam_if = S5H1411_IF_4000,
- .vsb_if = S5H1411_IF_3250,
- .inversion = S5H1411_INVERSION_ON,
- .status_mode = S5H1411_DEMODLOCKING,
- .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
-};
-
-static int saa7164_dvb_stop_port(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int ret;
-
- ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
- if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
- __func__, ret);
- ret = -EIO;
- } else {
- dprintk(DBGLVL_DVB, "%s() Stopped\n", __func__);
- ret = 0;
- }
-
- return ret;
-}
-
-static int saa7164_dvb_acquire_port(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int ret;
-
- ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
- if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
- __func__, ret);
- ret = -EIO;
- } else {
- dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__);
- ret = 0;
- }
-
- return ret;
-}
-
-static int saa7164_dvb_pause_port(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int ret;
-
- ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
- if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
- __func__, ret);
- ret = -EIO;
- } else {
- dprintk(DBGLVL_DVB, "%s() Paused\n", __func__);
- ret = 0;
- }
-
- return ret;
-}
-
-/* Firmware is very windows centric, meaning you have to transition
- * the part through AVStream / KS Windows stages, forwards or backwards.
- * States are: stopped, acquired (h/w), paused, started.
- */
-static int saa7164_dvb_stop_streaming(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- struct saa7164_buffer *buf;
- struct list_head *p, *q;
- int ret;
-
- dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
-
- ret = saa7164_dvb_pause_port(port);
- ret = saa7164_dvb_acquire_port(port);
- ret = saa7164_dvb_stop_port(port);
-
- /* Mark the hardware buffers as free */
- mutex_lock(&port->dmaqueue_lock);
- list_for_each_safe(p, q, &port->dmaqueue.list) {
- buf = list_entry(p, struct saa7164_buffer, list);
- buf->flags = SAA7164_BUFFER_FREE;
- }
- mutex_unlock(&port->dmaqueue_lock);
-
- return ret;
-}
-
-static int saa7164_dvb_start_port(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int ret = 0, result;
-
- dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
-
- saa7164_buffer_cfg_port(port);
-
- /* Acquire the hardware */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
- __func__, result);
-
- /* Stop the hardware, regardless */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() acquire/forced stop transition "
- "failed, res = 0x%x\n", __func__, result);
- }
- ret = -EIO;
- goto out;
- } else
- dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__);
-
- /* Pause the hardware */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
- __func__, result);
-
- /* Stop the hardware, regardless */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() pause/forced stop transition "
- "failed, res = 0x%x\n", __func__, result);
- }
-
- ret = -EIO;
- goto out;
- } else
- dprintk(DBGLVL_DVB, "%s() Paused\n", __func__);
-
- /* Start the hardware */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
- __func__, result);
-
- /* Stop the hardware, regardless */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() run/forced stop transition "
- "failed, res = 0x%x\n", __func__, result);
- }
-
- ret = -EIO;
- } else
- dprintk(DBGLVL_DVB, "%s() Running\n", __func__);
-
-out:
- return ret;
-}
-
-static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct saa7164_port *port = (struct saa7164_port *) demux->priv;
- struct saa7164_dvb *dvb = &port->dvb;
- struct saa7164_dev *dev = port->dev;
- int ret = 0;
-
- dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
-
- if (!demux->dmx.frontend)
- return -EINVAL;
-
- if (dvb) {
- mutex_lock(&dvb->lock);
- if (dvb->feeding++ == 0) {
- /* Start transport */
- ret = saa7164_dvb_start_port(port);
- }
- mutex_unlock(&dvb->lock);
- dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
- __func__, port->nr, dvb->feeding);
- }
-
- return ret;
-}
-
-static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct saa7164_port *port = (struct saa7164_port *) demux->priv;
- struct saa7164_dvb *dvb = &port->dvb;
- struct saa7164_dev *dev = port->dev;
- int ret = 0;
-
- dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
-
- if (dvb) {
- mutex_lock(&dvb->lock);
- if (--dvb->feeding == 0) {
- /* Stop transport */
- ret = saa7164_dvb_stop_streaming(port);
- }
- mutex_unlock(&dvb->lock);
- dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
- __func__, port->nr, dvb->feeding);
- }
-
- return ret;
-}
-
-static int dvb_register(struct saa7164_port *port)
-{
- struct saa7164_dvb *dvb = &port->dvb;
- struct saa7164_dev *dev = port->dev;
- struct saa7164_buffer *buf;
- int result, i;
-
- dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
-
- if (port->type != SAA7164_MPEG_DVB)
- BUG();
-
- /* Sanity check that the PCI configuration space is active */
- if (port->hwcfg.BARLocation == 0) {
- result = -ENOMEM;
- printk(KERN_ERR "%s: dvb_register_adapter failed "
- "(errno = %d), NO PCI configuration\n",
- DRIVER_NAME, result);
- goto fail_adapter;
- }
-
- /* Init and establish defaults */
- port->hw_streamingparams.bitspersample = 8;
- port->hw_streamingparams.samplesperline = 188;
- port->hw_streamingparams.numberoflines =
- (SAA7164_TS_NUMBER_OF_LINES * 188) / 188;
-
- port->hw_streamingparams.pitch = 188;
- port->hw_streamingparams.linethreshold = 0;
- port->hw_streamingparams.pagetablelistvirt = NULL;
- port->hw_streamingparams.pagetablelistphys = NULL;
- port->hw_streamingparams.numpagetables = 2 +
- ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE);
-
- port->hw_streamingparams.numpagetableentries = port->hwcfg.buffercount;
-
- /* Allocate the PCI resources */
- for (i = 0; i < port->hwcfg.buffercount; i++) {
- buf = saa7164_buffer_alloc(port,
- port->hw_streamingparams.numberoflines *
- port->hw_streamingparams.pitch);
-
- if (!buf) {
- result = -ENOMEM;
- printk(KERN_ERR "%s: dvb_register_adapter failed "
- "(errno = %d), unable to allocate buffers\n",
- DRIVER_NAME, result);
- goto fail_adapter;
- }
-
- mutex_lock(&port->dmaqueue_lock);
- list_add_tail(&buf->list, &port->dmaqueue.list);
- mutex_unlock(&port->dmaqueue_lock);
- }
-
- /* register adapter */
- result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE,
- &dev->pci->dev, adapter_nr);
- if (result < 0) {
- printk(KERN_ERR "%s: dvb_register_adapter failed "
- "(errno = %d)\n", DRIVER_NAME, result);
- goto fail_adapter;
- }
- dvb->adapter.priv = port;
-
- /* register frontend */
- result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
- if (result < 0) {
- printk(KERN_ERR "%s: dvb_register_frontend failed "
- "(errno = %d)\n", DRIVER_NAME, result);
- goto fail_frontend;
- }
-
- /* register demux stuff */
- dvb->demux.dmx.capabilities =
- DMX_TS_FILTERING | DMX_SECTION_FILTERING |
- DMX_MEMORY_BASED_FILTERING;
- dvb->demux.priv = port;
- dvb->demux.filternum = 256;
- dvb->demux.feednum = 256;
- dvb->demux.start_feed = saa7164_dvb_start_feed;
- dvb->demux.stop_feed = saa7164_dvb_stop_feed;
- result = dvb_dmx_init(&dvb->demux);
- if (result < 0) {
- printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n",
- DRIVER_NAME, result);
- goto fail_dmx;
- }
-
- dvb->dmxdev.filternum = 256;
- dvb->dmxdev.demux = &dvb->demux.dmx;
- dvb->dmxdev.capabilities = 0;
- result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
- if (result < 0) {
- printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n",
- DRIVER_NAME, result);
- goto fail_dmxdev;
- }
-
- dvb->fe_hw.source = DMX_FRONTEND_0;
- result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- if (result < 0) {
- printk(KERN_ERR "%s: add_frontend failed "
- "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result);
- goto fail_fe_hw;
- }
-
- dvb->fe_mem.source = DMX_MEMORY_FE;
- result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
- if (result < 0) {
- printk(KERN_ERR "%s: add_frontend failed "
- "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result);
- goto fail_fe_mem;
- }
-
- result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- if (result < 0) {
- printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n",
- DRIVER_NAME, result);
- goto fail_fe_conn;
- }
-
- /* register network adapter */
- dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
- return 0;
-
-fail_fe_conn:
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
-fail_fe_mem:
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
-fail_fe_hw:
- dvb_dmxdev_release(&dvb->dmxdev);
-fail_dmxdev:
- dvb_dmx_release(&dvb->demux);
-fail_dmx:
- dvb_unregister_frontend(dvb->frontend);
-fail_frontend:
- dvb_frontend_detach(dvb->frontend);
- dvb_unregister_adapter(&dvb->adapter);
-fail_adapter:
- return result;
-}
-
-int saa7164_dvb_unregister(struct saa7164_port *port)
-{
- struct saa7164_dvb *dvb = &port->dvb;
- struct saa7164_dev *dev = port->dev;
- struct saa7164_buffer *b;
- struct list_head *c, *n;
-
- dprintk(DBGLVL_DVB, "%s()\n", __func__);
-
- if (port->type != SAA7164_MPEG_DVB)
- BUG();
-
- /* Remove any allocated buffers */
- mutex_lock(&port->dmaqueue_lock);
- list_for_each_safe(c, n, &port->dmaqueue.list) {
- b = list_entry(c, struct saa7164_buffer, list);
- list_del(c);
- saa7164_buffer_dealloc(b);
- }
- mutex_unlock(&port->dmaqueue_lock);
-
- if (dvb->frontend == NULL)
- return 0;
-
- dvb_net_release(&dvb->net);
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- dvb_dmxdev_release(&dvb->dmxdev);
- dvb_dmx_release(&dvb->demux);
- dvb_unregister_frontend(dvb->frontend);
- dvb_frontend_detach(dvb->frontend);
- dvb_unregister_adapter(&dvb->adapter);
- return 0;
-}
-
-/* All the DVB attach calls go here, this function get's modified
- * for each new card.
- */
-int saa7164_dvb_register(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- struct saa7164_dvb *dvb = &port->dvb;
- struct saa7164_i2c *i2c_bus = NULL;
- int ret;
-
- dprintk(DBGLVL_DVB, "%s()\n", __func__);
-
- /* init frontend */
- switch (dev->board) {
- case SAA7164_BOARD_HAUPPAUGE_HVR2200:
- case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
- case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
- case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
- case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
- i2c_bus = &dev->i2c_bus[port->nr + 1];
- switch (port->nr) {
- case 0:
- port->dvb.frontend = dvb_attach(tda10048_attach,
- &hauppauge_hvr2200_1_config,
- &i2c_bus->i2c_adap);
-
- if (port->dvb.frontend != NULL) {
- /* TODO: addr is in the card struct */
- dvb_attach(tda18271_attach, port->dvb.frontend,
- 0xc0 >> 1, &i2c_bus->i2c_adap,
- &hauppauge_hvr22x0_tuner_config);
- }
-
- break;
- case 1:
- port->dvb.frontend = dvb_attach(tda10048_attach,
- &hauppauge_hvr2200_2_config,
- &i2c_bus->i2c_adap);
-
- if (port->dvb.frontend != NULL) {
- /* TODO: addr is in the card struct */
- dvb_attach(tda18271_attach, port->dvb.frontend,
- 0xc0 >> 1, &i2c_bus->i2c_adap,
- &hauppauge_hvr22x0s_tuner_config);
- }
-
- break;
- }
- break;
- case SAA7164_BOARD_HAUPPAUGE_HVR2250:
- case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
- case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
- i2c_bus = &dev->i2c_bus[port->nr + 1];
-
- port->dvb.frontend = dvb_attach(s5h1411_attach,
- &hauppauge_s5h1411_config,
- &i2c_bus->i2c_adap);
-
- if (port->dvb.frontend != NULL) {
- if (port->nr == 0) {
- /* Master TDA18271 */
- /* TODO: addr is in the card struct */
- dvb_attach(tda18271_attach, port->dvb.frontend,
- 0xc0 >> 1, &i2c_bus->i2c_adap,
- &hauppauge_hvr22x0_tuner_config);
- } else {
- /* Slave TDA18271 */
- dvb_attach(tda18271_attach, port->dvb.frontend,
- 0xc0 >> 1, &i2c_bus->i2c_adap,
- &hauppauge_hvr22x0s_tuner_config);
- }
- }
-
- break;
- default:
- printk(KERN_ERR "%s: The frontend isn't supported\n",
- dev->name);
- break;
- }
- if (NULL == dvb->frontend) {
- printk(KERN_ERR "%s() Frontend initialization failed\n",
- __func__);
- return -1;
- }
-
- /* register everything */
- ret = dvb_register(port);
- if (ret < 0) {
- if (dvb->frontend->ops.release)
- dvb->frontend->ops.release(dvb->frontend);
- return ret;
- }
-
- return 0;
-}
-
diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c
deleted file mode 100644
index a9ed686ad08..00000000000
--- a/drivers/media/video/saa7164/saa7164-encoder.c
+++ /dev/null
@@ -1,1500 +0,0 @@
-/*
- * Driver for the NXP SAA7164 PCIe bridge
- *
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "saa7164.h"
-
-#define ENCODER_MAX_BITRATE 6500000
-#define ENCODER_MIN_BITRATE 1000000
-#define ENCODER_DEF_BITRATE 5000000
-
-static struct saa7164_tvnorm saa7164_tvnorms[] = {
- {
- .name = "NTSC-M",
- .id = V4L2_STD_NTSC_M,
- }, {
- .name = "NTSC-JP",
- .id = V4L2_STD_NTSC_M_JP,
- }
-};
-
-static const u32 saa7164_v4l2_ctrls[] = {
- V4L2_CID_BRIGHTNESS,
- V4L2_CID_CONTRAST,
- V4L2_CID_SATURATION,
- V4L2_CID_HUE,
- V4L2_CID_AUDIO_VOLUME,
- V4L2_CID_SHARPNESS,
- V4L2_CID_MPEG_STREAM_TYPE,
- V4L2_CID_MPEG_VIDEO_ASPECT,
- V4L2_CID_MPEG_VIDEO_B_FRAMES,
- V4L2_CID_MPEG_VIDEO_GOP_SIZE,
- V4L2_CID_MPEG_AUDIO_MUTE,
- V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
- V4L2_CID_MPEG_VIDEO_BITRATE,
- V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
- 0
-};
-
-/* Take the encoder configuration form the port struct and
- * flush it to the hardware.
- */
-static void saa7164_encoder_configure(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
- port->encoder_params.width = port->width;
- port->encoder_params.height = port->height;
- port->encoder_params.is_50hz =
- (port->encodernorm.id & V4L2_STD_625_50) != 0;
-
- /* Set up the DIF (enable it) for analog mode by default */
- saa7164_api_initialize_dif(port);
-
- /* Configure the correct video standard */
- saa7164_api_configure_dif(port, port->encodernorm.id);
-
- /* Ensure the audio decoder is correct configured */
- saa7164_api_set_audio_std(port);
-}
-
-static int saa7164_encoder_buffers_dealloc(struct saa7164_port *port)
-{
- struct list_head *c, *n, *p, *q, *l, *v;
- struct saa7164_dev *dev = port->dev;
- struct saa7164_buffer *buf;
- struct saa7164_user_buffer *ubuf;
-
- /* Remove any allocated buffers */
- mutex_lock(&port->dmaqueue_lock);
-
- dprintk(DBGLVL_ENC, "%s(port=%d) dmaqueue\n", __func__, port->nr);
- list_for_each_safe(c, n, &port->dmaqueue.list) {
- buf = list_entry(c, struct saa7164_buffer, list);
- list_del(c);
- saa7164_buffer_dealloc(buf);
- }
-
- dprintk(DBGLVL_ENC, "%s(port=%d) used\n", __func__, port->nr);
- list_for_each_safe(p, q, &port->list_buf_used.list) {
- ubuf = list_entry(p, struct saa7164_user_buffer, list);
- list_del(p);
- saa7164_buffer_dealloc_user(ubuf);
- }
-
- dprintk(DBGLVL_ENC, "%s(port=%d) free\n", __func__, port->nr);
- list_for_each_safe(l, v, &port->list_buf_free.list) {
- ubuf = list_entry(l, struct saa7164_user_buffer, list);
- list_del(l);
- saa7164_buffer_dealloc_user(ubuf);
- }
-
- mutex_unlock(&port->dmaqueue_lock);
- dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr);
-
- return 0;
-}
-
-/* Dynamic buffer switch at encoder start time */
-static int saa7164_encoder_buffers_alloc(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- struct saa7164_buffer *buf;
- struct saa7164_user_buffer *ubuf;
- struct tmHWStreamParameters *params = &port->hw_streamingparams;
- int result = -ENODEV, i;
- int len = 0;
-
- dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
- if (port->encoder_params.stream_type ==
- V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {
- dprintk(DBGLVL_ENC,
- "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_PS\n",
- __func__);
- params->samplesperline = 128;
- params->numberoflines = 256;
- params->pitch = 128;
- params->numpagetables = 2 +
- ((SAA7164_PS_NUMBER_OF_LINES * 128) / PAGE_SIZE);
- } else
- if (port->encoder_params.stream_type ==
- V4L2_MPEG_STREAM_TYPE_MPEG2_TS) {
- dprintk(DBGLVL_ENC,
- "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_TS\n",
- __func__);
- params->samplesperline = 188;
- params->numberoflines = 312;
- params->pitch = 188;
- params->numpagetables = 2 +
- ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE);
- } else
- BUG();
-
- /* Init and establish defaults */
- params->bitspersample = 8;
- params->linethreshold = 0;
- params->pagetablelistvirt = NULL;
- params->pagetablelistphys = NULL;
- params->numpagetableentries = port->hwcfg.buffercount;
-
- /* Allocate the PCI resources, buffers (hard) */
- for (i = 0; i < port->hwcfg.buffercount; i++) {
- buf = saa7164_buffer_alloc(port,
- params->numberoflines *
- params->pitch);
-
- if (!buf) {
- printk(KERN_ERR "%s() failed "
- "(errno = %d), unable to allocate buffer\n",
- __func__, result);
- result = -ENOMEM;
- goto failed;
- } else {
-
- mutex_lock(&port->dmaqueue_lock);
- list_add_tail(&buf->list, &port->dmaqueue.list);
- mutex_unlock(&port->dmaqueue_lock);
-
- }
- }
-
- /* Allocate some kernel buffers for copying
- * to userpsace.
- */
- len = params->numberoflines * params->pitch;
-
- if (encoder_buffers < 16)
- encoder_buffers = 16;
- if (encoder_buffers > 512)
- encoder_buffers = 512;
-
- for (i = 0; i < encoder_buffers; i++) {
-
- ubuf = saa7164_buffer_alloc_user(dev, len);
- if (ubuf) {
- mutex_lock(&port->dmaqueue_lock);
- list_add_tail(&ubuf->list, &port->list_buf_free.list);
- mutex_unlock(&port->dmaqueue_lock);
- }
-
- }
-
- result = 0;
-
-failed:
- return result;
-}
-
-static int saa7164_encoder_initialize(struct saa7164_port *port)
-{
- saa7164_encoder_configure(port);
- return 0;
-}
-
-/* -- V4L2 --------------------------------------------------------- */
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
- unsigned int i;
-
- dprintk(DBGLVL_ENC, "%s(id=0x%x)\n", __func__, (u32)*id);
-
- for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) {
- if (*id & saa7164_tvnorms[i].id)
- break;
- }
- if (i == ARRAY_SIZE(saa7164_tvnorms))
- return -EINVAL;
-
- port->encodernorm = saa7164_tvnorms[i];
-
- /* Update the audio decoder while is not running in
- * auto detect mode.
- */
- saa7164_api_set_audio_std(port);
-
- dprintk(DBGLVL_ENC, "%s(id=0x%x) OK\n", __func__, (u32)*id);
-
- return 0;
-}
-
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- int n;
-
- char *inputs[] = { "tuner", "composite", "svideo", "aux",
- "composite 2", "svideo 2", "aux 2" };
-
- if (i->index >= 7)
- return -EINVAL;
-
- strcpy(i->name, inputs[i->index]);
-
- if (i->index == 0)
- i->type = V4L2_INPUT_TYPE_TUNER;
- else
- i->type = V4L2_INPUT_TYPE_CAMERA;
-
- for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++)
- i->std |= saa7164_tvnorms[n].id;
-
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- if (saa7164_api_get_videomux(port) != SAA_OK)
- return -EIO;
-
- *i = (port->mux_input - 1);
-
- dprintk(DBGLVL_ENC, "%s() input=%d\n", __func__, *i);
-
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- dprintk(DBGLVL_ENC, "%s() input=%d\n", __func__, i);
-
- if (i >= 7)
- return -EINVAL;
-
- port->mux_input = i + 1;
-
- if (saa7164_api_set_videomux(port) != SAA_OK)
- return -EIO;
-
- return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- if (0 != t->index)
- return -EINVAL;
-
- strcpy(t->name, "tuner");
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO;
-
- dprintk(DBGLVL_ENC, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
-
- return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- /* Update the A/V core */
- return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
-
- f->type = V4L2_TUNER_ANALOG_TV;
- f->frequency = port->freq;
-
- return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
- struct saa7164_port *tsport;
- struct dvb_frontend *fe;
-
- /* TODO: Pull this for the std */
- struct analog_parameters params = {
- .mode = V4L2_TUNER_ANALOG_TV,
- .audmode = V4L2_TUNER_MODE_STEREO,
- .std = port->encodernorm.id,
- .frequency = f->frequency
- };
-
- /* Stop the encoder */
- dprintk(DBGLVL_ENC, "%s() frequency=%d tuner=%d\n", __func__,
- f->frequency, f->tuner);
-
- if (f->tuner != 0)
- return -EINVAL;
-
- if (f->type != V4L2_TUNER_ANALOG_TV)
- return -EINVAL;
-
- port->freq = f->frequency;
-
- /* Update the hardware */
- if (port->nr == SAA7164_PORT_ENC1)
- tsport = &dev->ports[SAA7164_PORT_TS1];
- else
- if (port->nr == SAA7164_PORT_ENC2)
- tsport = &dev->ports[SAA7164_PORT_TS2];
- else
- BUG();
-
- fe = tsport->dvb.frontend;
-
- if (fe && fe->ops.tuner_ops.set_analog_params)
- fe->ops.tuner_ops.set_analog_params(fe, &params);
- else
- printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__);
-
- saa7164_encoder_initialize(port);
-
- return 0;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__,
- ctl->id, ctl->value);
-
- switch (ctl->id) {
- case V4L2_CID_BRIGHTNESS:
- ctl->value = port->ctl_brightness;
- break;
- case V4L2_CID_CONTRAST:
- ctl->value = port->ctl_contrast;
- break;
- case V4L2_CID_SATURATION:
- ctl->value = port->ctl_saturation;
- break;
- case V4L2_CID_HUE:
- ctl->value = port->ctl_hue;
- break;
- case V4L2_CID_SHARPNESS:
- ctl->value = port->ctl_sharpness;
- break;
- case V4L2_CID_AUDIO_VOLUME:
- ctl->value = port->ctl_volume;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
- int ret = 0;
-
- dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__,
- ctl->id, ctl->value);
-
- switch (ctl->id) {
- case V4L2_CID_BRIGHTNESS:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_brightness = ctl->value;
- saa7164_api_set_usercontrol(port,
- PU_BRIGHTNESS_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_CONTRAST:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_contrast = ctl->value;
- saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_SATURATION:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_saturation = ctl->value;
- saa7164_api_set_usercontrol(port,
- PU_SATURATION_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_HUE:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_hue = ctl->value;
- saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_SHARPNESS:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_sharpness = ctl->value;
- saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_AUDIO_VOLUME:
- if ((ctl->value >= -83) && (ctl->value <= 24)) {
- port->ctl_volume = ctl->value;
- saa7164_api_set_audio_volume(port, port->ctl_volume);
- } else
- ret = -EINVAL;
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int saa7164_get_ctrl(struct saa7164_port *port,
- struct v4l2_ext_control *ctrl)
-{
- struct saa7164_encoder_params *params = &port->encoder_params;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- ctrl->value = params->bitrate;
- break;
- case V4L2_CID_MPEG_STREAM_TYPE:
- ctrl->value = params->stream_type;
- break;
- case V4L2_CID_MPEG_AUDIO_MUTE:
- ctrl->value = params->ctl_mute;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- ctrl->value = params->ctl_aspect;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- ctrl->value = params->bitrate_mode;
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- ctrl->value = params->refdist;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- ctrl->value = params->bitrate_peak;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- ctrl->value = params->gop_size;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int vidioc_g_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = saa7164_get_ctrl(port, ctrl);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
-
- }
-
- return -EINVAL;
-}
-
-static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
-{
- int ret = -EINVAL;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- if ((ctrl->value >= ENCODER_MIN_BITRATE) &&
- (ctrl->value <= ENCODER_MAX_BITRATE))
- ret = 0;
- break;
- case V4L2_CID_MPEG_STREAM_TYPE:
- if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) ||
- (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS))
- ret = 0;
- break;
- case V4L2_CID_MPEG_AUDIO_MUTE:
- if ((ctrl->value >= 0) &&
- (ctrl->value <= 1))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) &&
- (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- if ((ctrl->value >= 0) &&
- (ctrl->value <= 255))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- if ((ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) ||
- (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- if ((ctrl->value >= 1) &&
- (ctrl->value <= 3))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- if ((ctrl->value >= ENCODER_MIN_BITRATE) &&
- (ctrl->value <= ENCODER_MAX_BITRATE))
- ret = 0;
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int vidioc_try_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = saa7164_try_ctrl(ctrl, 0);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
- }
-
- return -EINVAL;
-}
-
-static int saa7164_set_ctrl(struct saa7164_port *port,
- struct v4l2_ext_control *ctrl)
-{
- struct saa7164_encoder_params *params = &port->encoder_params;
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- params->bitrate = ctrl->value;
- break;
- case V4L2_CID_MPEG_STREAM_TYPE:
- params->stream_type = ctrl->value;
- break;
- case V4L2_CID_MPEG_AUDIO_MUTE:
- params->ctl_mute = ctrl->value;
- ret = saa7164_api_audio_mute(port, params->ctl_mute);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
- ret);
- ret = -EIO;
- }
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- params->ctl_aspect = ctrl->value;
- ret = saa7164_api_set_aspect_ratio(port);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
- ret);
- ret = -EIO;
- }
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- params->bitrate_mode = ctrl->value;
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- params->refdist = ctrl->value;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- params->bitrate_peak = ctrl->value;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- params->gop_size = ctrl->value;
- break;
- default:
- return -EINVAL;
- }
-
- /* TODO: Update the hardware */
-
- return ret;
-}
-
-static int vidioc_s_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = saa7164_try_ctrl(ctrl, 0);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- err = saa7164_set_ctrl(port, ctrl);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
-
- }
-
- return -EINVAL;
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- strcpy(cap->driver, dev->name);
- strlcpy(cap->card, saa7164_boards[dev->board].name,
- sizeof(cap->card));
- sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
-
- cap->capabilities =
- V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_READWRITE |
- 0;
-
- cap->capabilities |= V4L2_CAP_TUNER;
- cap->version = 0;
-
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (f->index != 0)
- return -EINVAL;
-
- strlcpy(f->description, "MPEG", sizeof(f->description));
- f->pixelformat = V4L2_PIX_FMT_MPEG;
-
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- port->ts_packet_size * port->ts_packet_count;
- f->fmt.pix.colorspace = 0;
- f->fmt.pix.width = port->width;
- f->fmt.pix.height = port->height;
-
- dprintk(DBGLVL_ENC, "VIDIOC_G_FMT: w: %d, h: %d\n",
- port->width, port->height);
-
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- port->ts_packet_size * port->ts_packet_count;
- f->fmt.pix.colorspace = 0;
- dprintk(DBGLVL_ENC, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
- port->width, port->height);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- port->ts_packet_size * port->ts_packet_count;
- f->fmt.pix.colorspace = 0;
-
- dprintk(DBGLVL_ENC, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
- f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
-
- return 0;
-}
-
-static int fill_queryctrl(struct saa7164_encoder_params *params,
- struct v4l2_queryctrl *c)
-{
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127);
- case V4L2_CID_CONTRAST:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66);
- case V4L2_CID_SATURATION:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62);
- case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128);
- case V4L2_CID_SHARPNESS:
- return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8);
- case V4L2_CID_MPEG_AUDIO_MUTE:
- return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0);
- case V4L2_CID_AUDIO_VOLUME:
- return v4l2_ctrl_query_fill(c, -83, 24, 1, 20);
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- return v4l2_ctrl_query_fill(c,
- ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE,
- 100000, ENCODER_DEF_BITRATE);
- case V4L2_CID_MPEG_STREAM_TYPE:
- return v4l2_ctrl_query_fill(c,
- V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
- V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
- 1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- return v4l2_ctrl_query_fill(c,
- V4L2_MPEG_VIDEO_ASPECT_1x1,
- V4L2_MPEG_VIDEO_ASPECT_221x100,
- 1, V4L2_MPEG_VIDEO_ASPECT_4x3);
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- return v4l2_ctrl_query_fill(c,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
- 1, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- return v4l2_ctrl_query_fill(c,
- 1, 3, 1, 1);
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- return v4l2_ctrl_query_fill(c,
- ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE,
- 100000, ENCODER_DEF_BITRATE);
- default:
- return -EINVAL;
- }
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *c)
-{
- struct saa7164_encoder_fh *fh = priv;
- struct saa7164_port *port = fh->port;
- int i, next;
- u32 id = c->id;
-
- memset(c, 0, sizeof(*c));
-
- next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
- c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
-
- for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) {
- if (next) {
- if (c->id < saa7164_v4l2_ctrls[i])
- c->id = saa7164_v4l2_ctrls[i];
- else
- continue;
- }
-
- if (c->id == saa7164_v4l2_ctrls[i])
- return fill_queryctrl(&port->encoder_params, c);
-
- if (c->id < saa7164_v4l2_ctrls[i])
- break;
- }
-
- return -EINVAL;
-}
-
-static int saa7164_encoder_stop_port(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int ret;
-
- ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
- if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
- __func__, ret);
- ret = -EIO;
- } else {
- dprintk(DBGLVL_ENC, "%s() Stopped\n", __func__);
- ret = 0;
- }
-
- return ret;
-}
-
-static int saa7164_encoder_acquire_port(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int ret;
-
- ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
- if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
- __func__, ret);
- ret = -EIO;
- } else {
- dprintk(DBGLVL_ENC, "%s() Acquired\n", __func__);
- ret = 0;
- }
-
- return ret;
-}
-
-static int saa7164_encoder_pause_port(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int ret;
-
- ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
- if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
- __func__, ret);
- ret = -EIO;
- } else {
- dprintk(DBGLVL_ENC, "%s() Paused\n", __func__);
- ret = 0;
- }
-
- return ret;
-}
-
-/* Firmware is very windows centric, meaning you have to transition
- * the part through AVStream / KS Windows stages, forwards or backwards.
- * States are: stopped, acquired (h/w), paused, started.
- * We have to leave here will all of the soft buffers on the free list,
- * else the cfg_post() func won't have soft buffers to correctly configure.
- */
-static int saa7164_encoder_stop_streaming(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- struct saa7164_buffer *buf;
- struct saa7164_user_buffer *ubuf;
- struct list_head *c, *n;
- int ret;
-
- dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr);
-
- ret = saa7164_encoder_pause_port(port);
- ret = saa7164_encoder_acquire_port(port);
- ret = saa7164_encoder_stop_port(port);
-
- dprintk(DBGLVL_ENC, "%s(port=%d) Hardware stopped\n", __func__,
- port->nr);
-
- /* Reset the state of any allocated buffer resources */
- mutex_lock(&port->dmaqueue_lock);
-
- /* Reset the hard and soft buffer state */
- list_for_each_safe(c, n, &port->dmaqueue.list) {
- buf = list_entry(c, struct saa7164_buffer, list);
- buf->flags = SAA7164_BUFFER_FREE;
- buf->pos = 0;
- }
-
- list_for_each_safe(c, n, &port->list_buf_used.list) {
- ubuf = list_entry(c, struct saa7164_user_buffer, list);
- ubuf->pos = 0;
- list_move_tail(&ubuf->list, &port->list_buf_free.list);
- }
-
- mutex_unlock(&port->dmaqueue_lock);
-
- /* Free any allocated resources */
- saa7164_encoder_buffers_dealloc(port);
-
- dprintk(DBGLVL_ENC, "%s(port=%d) Released\n", __func__, port->nr);
-
- return ret;
-}
-
-static int saa7164_encoder_start_streaming(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int result, ret = 0;
-
- dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr);
-
- port->done_first_interrupt = 0;
-
- /* allocate all of the PCIe DMA buffer resources on the fly,
- * allowing switching between TS and PS payloads without
- * requiring a complete driver reload.
- */
- saa7164_encoder_buffers_alloc(port);
-
- /* Configure the encoder with any cache values */
- saa7164_api_set_encoder(port);
- saa7164_api_get_encoder(port);
-
- /* Place the empty buffers on the hardware */
- saa7164_buffer_cfg_port(port);
-
- /* Acquire the hardware */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
- __func__, result);
-
- /* Stop the hardware, regardless */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() acquire/forced stop transition "
- "failed, res = 0x%x\n", __func__, result);
- }
- ret = -EIO;
- goto out;
- } else
- dprintk(DBGLVL_ENC, "%s() Acquired\n", __func__);
-
- /* Pause the hardware */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
- __func__, result);
-
- /* Stop the hardware, regardless */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() pause/forced stop transition "
- "failed, res = 0x%x\n", __func__, result);
- }
-
- ret = -EIO;
- goto out;
- } else
- dprintk(DBGLVL_ENC, "%s() Paused\n", __func__);
-
- /* Start the hardware */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
- __func__, result);
-
- /* Stop the hardware, regardless */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() run/forced stop transition "
- "failed, res = 0x%x\n", __func__, result);
- }
-
- ret = -EIO;
- } else
- dprintk(DBGLVL_ENC, "%s() Running\n", __func__);
-
-out:
- return ret;
-}
-
-static int fops_open(struct file *file)
-{
- struct saa7164_dev *dev;
- struct saa7164_port *port;
- struct saa7164_encoder_fh *fh;
-
- port = (struct saa7164_port *)video_get_drvdata(video_devdata(file));
- if (!port)
- return -ENODEV;
-
- dev = port->dev;
-
- dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- file->private_data = fh;
- fh->port = port;
-
- return 0;
-}
-
-static int fops_release(struct file *file)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
- /* Shut device down on last close */
- if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
- if (atomic_dec_return(&port->v4l_reader_count) == 0) {
- /* stop mpeg capture then cancel buffers */
- saa7164_encoder_stop_streaming(port);
- }
- }
-
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port)
-{
- struct saa7164_user_buffer *ubuf = NULL;
- struct saa7164_dev *dev = port->dev;
- u32 crc;
-
- mutex_lock(&port->dmaqueue_lock);
- if (!list_empty(&port->list_buf_used.list)) {
- ubuf = list_first_entry(&port->list_buf_used.list,
- struct saa7164_user_buffer, list);
-
- if (crc_checking) {
- crc = crc32(0, ubuf->data, ubuf->actual_size);
- if (crc != ubuf->crc) {
- printk(KERN_ERR
- "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n",
- __func__,
- ubuf, ubuf->crc, crc);
- }
- }
-
- }
- mutex_unlock(&port->dmaqueue_lock);
-
- dprintk(DBGLVL_ENC, "%s() returns %p\n", __func__, ubuf);
-
- return ubuf;
-}
-
-static ssize_t fops_read(struct file *file, char __user *buffer,
- size_t count, loff_t *pos)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_user_buffer *ubuf = NULL;
- struct saa7164_dev *dev = port->dev;
- int ret = 0;
- int rem, cnt;
- u8 *p;
-
- port->last_read_msecs_diff = port->last_read_msecs;
- port->last_read_msecs = jiffies_to_msecs(jiffies);
- port->last_read_msecs_diff = port->last_read_msecs -
- port->last_read_msecs_diff;
-
- saa7164_histogram_update(&port->read_interval,
- port->last_read_msecs_diff);
-
- if (*pos) {
- printk(KERN_ERR "%s() ESPIPE\n", __func__);
- return -ESPIPE;
- }
-
- if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
- if (atomic_inc_return(&port->v4l_reader_count) == 1) {
-
- if (saa7164_encoder_initialize(port) < 0) {
- printk(KERN_ERR "%s() EINVAL\n", __func__);
- return -EINVAL;
- }
-
- saa7164_encoder_start_streaming(port);
- msleep(200);
- }
- }
-
- /* blocking wait for buffer */
- if ((file->f_flags & O_NONBLOCK) == 0) {
- if (wait_event_interruptible(port->wait_read,
- saa7164_enc_next_buf(port))) {
- printk(KERN_ERR "%s() ERESTARTSYS\n", __func__);
- return -ERESTARTSYS;
- }
- }
-
- /* Pull the first buffer from the used list */
- ubuf = saa7164_enc_next_buf(port);
-
- while ((count > 0) && ubuf) {
-
- /* set remaining bytes to copy */
- rem = ubuf->actual_size - ubuf->pos;
- cnt = rem > count ? count : rem;
-
- p = ubuf->data + ubuf->pos;
-
- dprintk(DBGLVL_ENC,
- "%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n",
- __func__, (int)count, cnt, rem, ubuf, ubuf->pos);
-
- if (copy_to_user(buffer, p, cnt)) {
- printk(KERN_ERR "%s() copy_to_user failed\n", __func__);
- if (!ret) {
- printk(KERN_ERR "%s() EFAULT\n", __func__);
- ret = -EFAULT;
- }
- goto err;
- }
-
- ubuf->pos += cnt;
- count -= cnt;
- buffer += cnt;
- ret += cnt;
-
- if (ubuf->pos > ubuf->actual_size)
- printk(KERN_ERR "read() pos > actual, huh?\n");
-
- if (ubuf->pos == ubuf->actual_size) {
-
- /* finished with current buffer, take next buffer */
-
- /* Requeue the buffer on the free list */
- ubuf->pos = 0;
-
- mutex_lock(&port->dmaqueue_lock);
- list_move_tail(&ubuf->list, &port->list_buf_free.list);
- mutex_unlock(&port->dmaqueue_lock);
-
- /* Dequeue next */
- if ((file->f_flags & O_NONBLOCK) == 0) {
- if (wait_event_interruptible(port->wait_read,
- saa7164_enc_next_buf(port))) {
- break;
- }
- }
- ubuf = saa7164_enc_next_buf(port);
- }
- }
-err:
- if (!ret && !ubuf)
- ret = -EAGAIN;
-
- return ret;
-}
-
-static unsigned int fops_poll(struct file *file, poll_table *wait)
-{
- struct saa7164_encoder_fh *fh =
- (struct saa7164_encoder_fh *)file->private_data;
- struct saa7164_port *port = fh->port;
- unsigned int mask = 0;
-
- port->last_poll_msecs_diff = port->last_poll_msecs;
- port->last_poll_msecs = jiffies_to_msecs(jiffies);
- port->last_poll_msecs_diff = port->last_poll_msecs -
- port->last_poll_msecs_diff;
-
- saa7164_histogram_update(&port->poll_interval,
- port->last_poll_msecs_diff);
-
- if (!video_is_registered(port->v4l_device))
- return -EIO;
-
- if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
- if (atomic_inc_return(&port->v4l_reader_count) == 1) {
- if (saa7164_encoder_initialize(port) < 0)
- return -EINVAL;
- saa7164_encoder_start_streaming(port);
- msleep(200);
- }
- }
-
- /* blocking wait for buffer */
- if ((file->f_flags & O_NONBLOCK) == 0) {
- if (wait_event_interruptible(port->wait_read,
- saa7164_enc_next_buf(port))) {
- return -ERESTARTSYS;
- }
- }
-
- /* Pull the first buffer from the used list */
- if (!list_empty(&port->list_buf_used.list))
- mask |= POLLIN | POLLRDNORM;
-
- return mask;
-}
-
-static const struct v4l2_file_operations mpeg_fops = {
- .owner = THIS_MODULE,
- .open = fops_open,
- .release = fops_release,
- .read = fops_read,
- .poll = fops_poll,
- .unlocked_ioctl = video_ioctl2,
-};
-
-int saa7164_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
- struct saa7164_dev *dev = port->dev;
- dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
- return 0;
-}
-
-int saa7164_g_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
- struct saa7164_dev *dev = port->dev;
- dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- return 0;
-}
-
-int saa7164_s_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
- struct saa7164_dev *dev = port->dev;
- dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- return 0;
-}
-
-static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
- .vidioc_s_std = vidioc_s_std,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
- .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
- .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_chip_ident = saa7164_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = saa7164_g_register,
- .vidioc_s_register = saa7164_s_register,
-#endif
-};
-
-static struct video_device saa7164_mpeg_template = {
- .name = "saa7164",
- .fops = &mpeg_fops,
- .ioctl_ops = &mpeg_ioctl_ops,
- .minor = -1,
- .tvnorms = SAA7164_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
-
-static struct video_device *saa7164_encoder_alloc(
- struct saa7164_port *port,
- struct pci_dev *pci,
- struct video_device *template,
- char *type)
-{
- struct video_device *vfd;
- struct saa7164_dev *dev = port->dev;
-
- dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
- vfd = video_device_alloc();
- if (NULL == vfd)
- return NULL;
-
- *vfd = *template;
- snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
- type, saa7164_boards[dev->board].name);
-
- vfd->parent = &pci->dev;
- vfd->release = video_device_release;
- return vfd;
-}
-
-int saa7164_encoder_register(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int result = -ENODEV;
-
- dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
- if (port->type != SAA7164_MPEG_ENCODER)
- BUG();
-
- /* Sanity check that the PCI configuration space is active */
- if (port->hwcfg.BARLocation == 0) {
- printk(KERN_ERR "%s() failed "
- "(errno = %d), NO PCI configuration\n",
- __func__, result);
- result = -ENOMEM;
- goto failed;
- }
-
- /* Establish encoder defaults here */
- /* Set default TV standard */
- port->encodernorm = saa7164_tvnorms[0];
- port->width = 720;
- port->mux_input = 1; /* Composite */
- port->video_format = EU_VIDEO_FORMAT_MPEG_2;
- port->audio_format = 0;
- port->video_resolution = 0;
- port->ctl_brightness = 127;
- port->ctl_contrast = 66;
- port->ctl_hue = 128;
- port->ctl_saturation = 62;
- port->ctl_sharpness = 8;
- port->encoder_params.bitrate = ENCODER_DEF_BITRATE;
- port->encoder_params.bitrate_peak = ENCODER_DEF_BITRATE;
- port->encoder_params.bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
- port->encoder_params.stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
- port->encoder_params.ctl_mute = 0;
- port->encoder_params.ctl_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3;
- port->encoder_params.refdist = 1;
- port->encoder_params.gop_size = SAA7164_ENCODER_DEFAULT_GOP_SIZE;
-
- if (port->encodernorm.id & V4L2_STD_525_60)
- port->height = 480;
- else
- port->height = 576;
-
- /* Allocate and register the video device node */
- port->v4l_device = saa7164_encoder_alloc(port,
- dev->pci, &saa7164_mpeg_template, "mpeg");
-
- if (!port->v4l_device) {
- printk(KERN_INFO "%s: can't allocate mpeg device\n",
- dev->name);
- result = -ENOMEM;
- goto failed;
- }
-
- video_set_drvdata(port->v4l_device, port);
- result = video_register_device(port->v4l_device,
- VFL_TYPE_GRABBER, -1);
- if (result < 0) {
- printk(KERN_INFO "%s: can't register mpeg device\n",
- dev->name);
- /* TODO: We're going to leak here if we don't dealloc
- The buffers above. The unreg function can't deal wit it.
- */
- goto failed;
- }
-
- printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
- dev->name, port->v4l_device->num);
-
- /* Configure the hardware defaults */
- saa7164_api_set_videomux(port);
- saa7164_api_set_usercontrol(port, PU_BRIGHTNESS_CONTROL);
- saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
- saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
- saa7164_api_set_usercontrol(port, PU_SATURATION_CONTROL);
- saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
- saa7164_api_audio_mute(port, 0);
- saa7164_api_set_audio_volume(port, 20);
- saa7164_api_set_aspect_ratio(port);
-
- /* Disable audio standard detection, it's buggy */
- saa7164_api_set_audio_detection(port, 0);
-
- saa7164_api_set_encoder(port);
- saa7164_api_get_encoder(port);
-
- result = 0;
-failed:
- return result;
-}
-
-void saa7164_encoder_unregister(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
-
- dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr);
-
- if (port->type != SAA7164_MPEG_ENCODER)
- BUG();
-
- if (port->v4l_device) {
- if (port->v4l_device->minor != -1)
- video_unregister_device(port->v4l_device);
- else
- video_device_release(port->v4l_device);
-
- port->v4l_device = NULL;
- }
-
- dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr);
-}
-
diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c
deleted file mode 100644
index a266bf0169e..00000000000
--- a/drivers/media/video/saa7164/saa7164-fw.c
+++ /dev/null
@@ -1,613 +0,0 @@
-/*
- * Driver for the NXP SAA7164 PCIe bridge
- *
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/firmware.h>
-#include <linux/slab.h>
-
-#include "saa7164.h"
-
-#define SAA7164_REV2_FIRMWARE "NXP7164-2010-03-10.1.fw"
-#define SAA7164_REV2_FIRMWARE_SIZE 4019072
-
-#define SAA7164_REV3_FIRMWARE "NXP7164-2010-03-10.1.fw"
-#define SAA7164_REV3_FIRMWARE_SIZE 4019072
-
-struct fw_header {
- u32 firmwaresize;
- u32 bslsize;
- u32 reserved;
- u32 version;
-};
-
-int saa7164_dl_wait_ack(struct saa7164_dev *dev, u32 reg)
-{
- u32 timeout = SAA_DEVICE_TIMEOUT;
- while ((saa7164_readl(reg) & 0x01) == 0) {
- timeout -= 10;
- if (timeout == 0) {
- printk(KERN_ERR "%s() timeout (no d/l ack)\n",
- __func__);
- return -EBUSY;
- }
- msleep(100);
- }
-
- return 0;
-}
-
-int saa7164_dl_wait_clr(struct saa7164_dev *dev, u32 reg)
-{
- u32 timeout = SAA_DEVICE_TIMEOUT;
- while (saa7164_readl(reg) & 0x01) {
- timeout -= 10;
- if (timeout == 0) {
- printk(KERN_ERR "%s() timeout (no d/l clr)\n",
- __func__);
- return -EBUSY;
- }
- msleep(100);
- }
-
- return 0;
-}
-
-/* TODO: move dlflags into dev-> and change to write/readl/b */
-/* TODO: Excessive levels of debug */
-int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize,
- u32 dlflags, u8 *dst, u32 dstsize)
-{
- u32 reg, timeout, offset;
- u8 *srcbuf = NULL;
- int ret;
-
- u32 dlflag = dlflags;
- u32 dlflag_ack = dlflag + 4;
- u32 drflag = dlflag_ack + 4;
- u32 drflag_ack = drflag + 4;
- u32 bleflag = drflag_ack + 4;
-
- dprintk(DBGLVL_FW,
- "%s(image=%p, size=%d, flags=0x%x, dst=%p, dstsize=0x%x)\n",
- __func__, src, srcsize, dlflags, dst, dstsize);
-
- if ((src == NULL) || (dst == NULL)) {
- ret = -EIO;
- goto out;
- }
-
- srcbuf = kzalloc(4 * 1048576, GFP_KERNEL);
- if (NULL == srcbuf) {
- ret = -ENOMEM;
- goto out;
- }
-
- if (srcsize > (4*1048576)) {
- ret = -ENOMEM;
- goto out;
- }
-
- memcpy(srcbuf, src, srcsize);
-
- dprintk(DBGLVL_FW, "%s() dlflag = 0x%x\n", __func__, dlflag);
- dprintk(DBGLVL_FW, "%s() dlflag_ack = 0x%x\n", __func__, dlflag_ack);
- dprintk(DBGLVL_FW, "%s() drflag = 0x%x\n", __func__, drflag);
- dprintk(DBGLVL_FW, "%s() drflag_ack = 0x%x\n", __func__, drflag_ack);
- dprintk(DBGLVL_FW, "%s() bleflag = 0x%x\n", __func__, bleflag);
-
- reg = saa7164_readl(dlflag);
- dprintk(DBGLVL_FW, "%s() dlflag (0x%x)= 0x%x\n", __func__, dlflag, reg);
- if (reg == 1)
- dprintk(DBGLVL_FW,
- "%s() Download flag already set, please reboot\n",
- __func__);
-
- /* Indicate download start */
- saa7164_writel(dlflag, 1);
- ret = saa7164_dl_wait_ack(dev, dlflag_ack);
- if (ret < 0)
- goto out;
-
- /* Ack download start, then wait for wait */
- saa7164_writel(dlflag, 0);
- ret = saa7164_dl_wait_clr(dev, dlflag_ack);
- if (ret < 0)
- goto out;
-
- /* Deal with the raw firmware, in the appropriate chunk size */
- for (offset = 0; srcsize > dstsize;
- srcsize -= dstsize, offset += dstsize) {
-
- dprintk(DBGLVL_FW, "%s() memcpy %d\n", __func__, dstsize);
- memcpy(dst, srcbuf + offset, dstsize);
-
- /* Flag the data as ready */
- saa7164_writel(drflag, 1);
- ret = saa7164_dl_wait_ack(dev, drflag_ack);
- if (ret < 0)
- goto out;
-
- /* Wait for indication data was received */
- saa7164_writel(drflag, 0);
- ret = saa7164_dl_wait_clr(dev, drflag_ack);
- if (ret < 0)
- goto out;
-
- }
-
- dprintk(DBGLVL_FW, "%s() memcpy(l) %d\n", __func__, dstsize);
- /* Write last block to the device */
- memcpy(dst, srcbuf+offset, srcsize);
-
- /* Flag the data as ready */
- saa7164_writel(drflag, 1);
- ret = saa7164_dl_wait_ack(dev, drflag_ack);
- if (ret < 0)
- goto out;
-
- saa7164_writel(drflag, 0);
- timeout = 0;
- while (saa7164_readl(bleflag) != SAA_DEVICE_IMAGE_BOOTING) {
- if (saa7164_readl(bleflag) & SAA_DEVICE_IMAGE_CORRUPT) {
- printk(KERN_ERR "%s() image corrupt\n", __func__);
- ret = -EBUSY;
- goto out;
- }
-
- if (saa7164_readl(bleflag) & SAA_DEVICE_MEMORY_CORRUPT) {
- printk(KERN_ERR "%s() device memory corrupt\n",
- __func__);
- ret = -EBUSY;
- goto out;
- }
-
- msleep(10); /* Checkpatch throws a < 20ms warning */
- if (timeout++ > 60)
- break;
- }
-
- printk(KERN_INFO "%s() Image downloaded, booting...\n", __func__);
-
- ret = saa7164_dl_wait_clr(dev, drflag_ack);
- if (ret < 0)
- goto out;
-
- printk(KERN_INFO "%s() Image booted successfully.\n", __func__);
- ret = 0;
-
-out:
- kfree(srcbuf);
- return ret;
-}
-
-/* TODO: Excessive debug */
-/* Load the firmware. Optionally it can be in ROM or newer versions
- * can be on disk, saving the expense of the ROM hardware. */
-int saa7164_downloadfirmware(struct saa7164_dev *dev)
-{
- /* u32 second_timeout = 60 * SAA_DEVICE_TIMEOUT; */
- u32 tmp, filesize, version, err_flags, first_timeout, fwlength;
- u32 second_timeout, updatebootloader = 1, bootloadersize = 0;
- const struct firmware *fw = NULL;
- struct fw_header *hdr, *boothdr = NULL, *fwhdr;
- u32 bootloaderversion = 0, fwloadersize;
- u8 *bootloaderoffset = NULL, *fwloaderoffset;
- char *fwname;
- int ret;
-
- dprintk(DBGLVL_FW, "%s()\n", __func__);
-
- if (saa7164_boards[dev->board].chiprev == SAA7164_CHIP_REV2) {
- fwname = SAA7164_REV2_FIRMWARE;
- fwlength = SAA7164_REV2_FIRMWARE_SIZE;
- } else {
- fwname = SAA7164_REV3_FIRMWARE;
- fwlength = SAA7164_REV3_FIRMWARE_SIZE;
- }
-
- version = saa7164_getcurrentfirmwareversion(dev);
-
- if (version == 0x00) {
-
- second_timeout = 100;
- first_timeout = 100;
- err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS);
- dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
- __func__, err_flags);
-
- while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
- dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
- __func__, err_flags);
- msleep(10); /* Checkpatch throws a < 20ms warning */
-
- if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
- printk(KERN_ERR "%s() firmware corrupt\n",
- __func__);
- break;
- }
- if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) {
- printk(KERN_ERR "%s() device memory corrupt\n",
- __func__);
- break;
- }
- if (err_flags & SAA_DEVICE_NO_IMAGE) {
- printk(KERN_ERR "%s() no first image\n",
- __func__);
- break;
- }
- if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) {
- first_timeout -= 10;
- if (first_timeout == 0) {
- printk(KERN_ERR
- "%s() no first image\n",
- __func__);
- break;
- }
- } else if (err_flags & SAA_DEVICE_IMAGE_LOADING) {
- second_timeout -= 10;
- if (second_timeout == 0) {
- printk(KERN_ERR
- "%s() FW load time exceeded\n",
- __func__);
- break;
- }
- } else {
- second_timeout -= 10;
- if (second_timeout == 0) {
- printk(KERN_ERR
- "%s() Unknown bootloader flags 0x%x\n",
- __func__, err_flags);
- break;
- }
- }
-
- err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS);
- } /* While != Booting */
-
- if (err_flags == SAA_DEVICE_IMAGE_BOOTING) {
- dprintk(DBGLVL_FW, "%s() Loader 1 has loaded.\n",
- __func__);
- first_timeout = SAA_DEVICE_TIMEOUT;
- second_timeout = 60 * SAA_DEVICE_TIMEOUT;
- second_timeout = 100;
-
- err_flags = saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS);
- dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
- __func__, err_flags);
- while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
- dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
- __func__, err_flags);
- msleep(10); /* Checkpatch throws a < 20ms warning */
-
- if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
- printk(KERN_ERR
- "%s() firmware corrupt\n",
- __func__);
- break;
- }
- if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) {
- printk(KERN_ERR
- "%s() device memory corrupt\n",
- __func__);
- break;
- }
- if (err_flags & SAA_DEVICE_NO_IMAGE) {
- printk(KERN_ERR "%s() no first image\n",
- __func__);
- break;
- }
- if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) {
- first_timeout -= 10;
- if (first_timeout == 0) {
- printk(KERN_ERR
- "%s() no second image\n",
- __func__);
- break;
- }
- } else if (err_flags &
- SAA_DEVICE_IMAGE_LOADING) {
- second_timeout -= 10;
- if (second_timeout == 0) {
- printk(KERN_ERR
- "%s() FW load time exceeded\n",
- __func__);
- break;
- }
- } else {
- second_timeout -= 10;
- if (second_timeout == 0) {
- printk(KERN_ERR
- "%s() Unknown bootloader flags 0x%x\n",
- __func__, err_flags);
- break;
- }
- }
-
- err_flags =
- saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS);
- } /* err_flags != SAA_DEVICE_IMAGE_BOOTING */
-
- dprintk(DBGLVL_FW, "%s() Loader flags 1:0x%x 2:0x%x.\n",
- __func__,
- saa7164_readl(SAA_BOOTLOADERERROR_FLAGS),
- saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS));
-
- } /* err_flags == SAA_DEVICE_IMAGE_BOOTING */
-
- /* It's possible for both firmwares to have booted,
- * but that doesn't mean they've finished booting yet.
- */
- if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
- SAA_DEVICE_IMAGE_BOOTING) &&
- (saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) ==
- SAA_DEVICE_IMAGE_BOOTING)) {
-
-
- dprintk(DBGLVL_FW, "%s() Loader 2 has loaded.\n",
- __func__);
-
- first_timeout = SAA_DEVICE_TIMEOUT;
- while (first_timeout) {
- msleep(10); /* Checkpatch throws a < 20ms warning */
-
- version =
- saa7164_getcurrentfirmwareversion(dev);
- if (version) {
- dprintk(DBGLVL_FW,
- "%s() All f/w loaded successfully\n",
- __func__);
- break;
- } else {
- first_timeout -= 10;
- if (first_timeout == 0) {
- printk(KERN_ERR
- "%s() FW did not boot\n",
- __func__);
- break;
- }
- }
- }
- }
- version = saa7164_getcurrentfirmwareversion(dev);
- } /* version == 0 */
-
- /* Has the firmware really booted? */
- if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
- SAA_DEVICE_IMAGE_BOOTING) &&
- (saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) ==
- SAA_DEVICE_IMAGE_BOOTING) && (version == 0)) {
-
- printk(KERN_ERR
- "%s() The firmware hung, probably bad firmware\n",
- __func__);
-
- /* Tell the second stage loader we have a deadlock */
- saa7164_writel(SAA_DEVICE_DEADLOCK_DETECTED_OFFSET,
- SAA_DEVICE_DEADLOCK_DETECTED);
-
- saa7164_getfirmwarestatus(dev);
-
- return -ENOMEM;
- }
-
- dprintk(DBGLVL_FW, "Device has Firmware Version %d.%d.%d.%d\n",
- (version & 0x0000fc00) >> 10,
- (version & 0x000003e0) >> 5,
- (version & 0x0000001f),
- (version & 0xffff0000) >> 16);
-
- /* Load the firmwware from the disk if required */
- if (version == 0) {
-
- printk(KERN_INFO "%s() Waiting for firmware upload (%s)\n",
- __func__, fwname);
-
- ret = request_firmware(&fw, fwname, &dev->pci->dev);
- if (ret) {
- printk(KERN_ERR "%s() Upload failed. "
- "(file not found?)\n", __func__);
- return -ENOMEM;
- }
-
- printk(KERN_INFO "%s() firmware read %Zu bytes.\n",
- __func__, fw->size);
-
- if (fw->size != fwlength) {
- printk(KERN_ERR "xc5000: firmware incorrect size\n");
- ret = -ENOMEM;
- goto out;
- }
-
- printk(KERN_INFO "%s() firmware loaded.\n", __func__);
-
- hdr = (struct fw_header *)fw->data;
- printk(KERN_INFO "Firmware file header part 1:\n");
- printk(KERN_INFO " .FirmwareSize = 0x%x\n", hdr->firmwaresize);
- printk(KERN_INFO " .BSLSize = 0x%x\n", hdr->bslsize);
- printk(KERN_INFO " .Reserved = 0x%x\n", hdr->reserved);
- printk(KERN_INFO " .Version = 0x%x\n", hdr->version);
-
- /* Retrieve bootloader if reqd */
- if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0))
- /* Second bootloader in the firmware file */
- filesize = hdr->reserved * 16;
- else
- filesize = (hdr->firmwaresize + hdr->bslsize) *
- 16 + sizeof(struct fw_header);
-
- printk(KERN_INFO "%s() SecBootLoader.FileSize = %d\n",
- __func__, filesize);
-
- /* Get bootloader (if reqd) and firmware header */
- if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) {
- /* Second boot loader is required */
-
- /* Get the loader header */
- boothdr = (struct fw_header *)(fw->data +
- sizeof(struct fw_header));
-
- bootloaderversion =
- saa7164_readl(SAA_DEVICE_2ND_VERSION);
- dprintk(DBGLVL_FW, "Onboard BootLoader:\n");
- dprintk(DBGLVL_FW, "->Flag 0x%x\n",
- saa7164_readl(SAA_BOOTLOADERERROR_FLAGS));
- dprintk(DBGLVL_FW, "->Ack 0x%x\n",
- saa7164_readl(SAA_DATAREADY_FLAG_ACK));
- dprintk(DBGLVL_FW, "->FW Version 0x%x\n", version);
- dprintk(DBGLVL_FW, "->Loader Version 0x%x\n",
- bootloaderversion);
-
- if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
- 0x03) && (saa7164_readl(SAA_DATAREADY_FLAG_ACK)
- == 0x00) && (version == 0x00)) {
-
- dprintk(DBGLVL_FW, "BootLoader version in "
- "rom %d.%d.%d.%d\n",
- (bootloaderversion & 0x0000fc00) >> 10,
- (bootloaderversion & 0x000003e0) >> 5,
- (bootloaderversion & 0x0000001f),
- (bootloaderversion & 0xffff0000) >> 16
- );
- dprintk(DBGLVL_FW, "BootLoader version "
- "in file %d.%d.%d.%d\n",
- (boothdr->version & 0x0000fc00) >> 10,
- (boothdr->version & 0x000003e0) >> 5,
- (boothdr->version & 0x0000001f),
- (boothdr->version & 0xffff0000) >> 16
- );
-
- if (bootloaderversion == boothdr->version)
- updatebootloader = 0;
- }
-
- /* Calculate offset to firmware header */
- tmp = (boothdr->firmwaresize + boothdr->bslsize) * 16 +
- (sizeof(struct fw_header) +
- sizeof(struct fw_header));
-
- fwhdr = (struct fw_header *)(fw->data+tmp);
- } else {
- /* No second boot loader */
- fwhdr = hdr;
- }
-
- dprintk(DBGLVL_FW, "Firmware version in file %d.%d.%d.%d\n",
- (fwhdr->version & 0x0000fc00) >> 10,
- (fwhdr->version & 0x000003e0) >> 5,
- (fwhdr->version & 0x0000001f),
- (fwhdr->version & 0xffff0000) >> 16
- );
-
- if (version == fwhdr->version) {
- /* No download, firmware already on board */
- ret = 0;
- goto out;
- }
-
- if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) {
- if (updatebootloader) {
- /* Get ready to upload the bootloader */
- bootloadersize = (boothdr->firmwaresize +
- boothdr->bslsize) * 16 +
- sizeof(struct fw_header);
-
- bootloaderoffset = (u8 *)(fw->data +
- sizeof(struct fw_header));
-
- dprintk(DBGLVL_FW, "bootloader d/l starts.\n");
- printk(KERN_INFO "%s() FirmwareSize = 0x%x\n",
- __func__, boothdr->firmwaresize);
- printk(KERN_INFO "%s() BSLSize = 0x%x\n",
- __func__, boothdr->bslsize);
- printk(KERN_INFO "%s() Reserved = 0x%x\n",
- __func__, boothdr->reserved);
- printk(KERN_INFO "%s() Version = 0x%x\n",
- __func__, boothdr->version);
- ret = saa7164_downloadimage(
- dev,
- bootloaderoffset,
- bootloadersize,
- SAA_DOWNLOAD_FLAGS,
- dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET,
- SAA_DEVICE_BUFFERBLOCKSIZE);
- if (ret < 0) {
- printk(KERN_ERR
- "bootloader d/l has failed\n");
- goto out;
- }
- dprintk(DBGLVL_FW,
- "bootloader download complete.\n");
-
- }
-
- printk(KERN_ERR "starting firmware download(2)\n");
- bootloadersize = (boothdr->firmwaresize +
- boothdr->bslsize) * 16 +
- sizeof(struct fw_header);
-
- bootloaderoffset =
- (u8 *)(fw->data + sizeof(struct fw_header));
-
- fwloaderoffset = bootloaderoffset + bootloadersize;
-
- /* TODO: fix this bounds overrun here with old f/ws */
- fwloadersize = (fwhdr->firmwaresize + fwhdr->bslsize) *
- 16 + sizeof(struct fw_header);
-
- ret = saa7164_downloadimage(
- dev,
- fwloaderoffset,
- fwloadersize,
- SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET,
- dev->bmmio + SAA_DEVICE_2ND_DOWNLOAD_OFFSET,
- SAA_DEVICE_2ND_BUFFERBLOCKSIZE);
- if (ret < 0) {
- printk(KERN_ERR "firmware download failed\n");
- goto out;
- }
- printk(KERN_ERR "firmware download complete.\n");
-
- } else {
-
- /* No bootloader update reqd, download firmware only */
- printk(KERN_ERR "starting firmware download(3)\n");
-
- ret = saa7164_downloadimage(
- dev,
- (u8 *)fw->data,
- fw->size,
- SAA_DOWNLOAD_FLAGS,
- dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET,
- SAA_DEVICE_BUFFERBLOCKSIZE);
- if (ret < 0) {
- printk(KERN_ERR "firmware download failed\n");
- goto out;
- }
- printk(KERN_ERR "firmware download complete.\n");
- }
- }
-
- dev->firmwareloaded = 1;
- ret = 0;
-
-out:
- release_firmware(fw);
- return ret;
-}
diff --git a/drivers/media/video/saa7164/saa7164-i2c.c b/drivers/media/video/saa7164/saa7164-i2c.c
deleted file mode 100644
index 4f7e3b42263..00000000000
--- a/drivers/media/video/saa7164/saa7164-i2c.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Driver for the NXP SAA7164 PCIe bridge
- *
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-
-#include "saa7164.h"
-
-static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
-{
- struct saa7164_i2c *bus = i2c_adap->algo_data;
- struct saa7164_dev *dev = bus->dev;
- int i, retval = 0;
-
- dprintk(DBGLVL_I2C, "%s(num = %d)\n", __func__, num);
-
- for (i = 0 ; i < num; i++) {
- dprintk(DBGLVL_I2C, "%s(num = %d) addr = 0x%02x len = 0x%x\n",
- __func__, num, msgs[i].addr, msgs[i].len);
- if (msgs[i].flags & I2C_M_RD) {
- /* Unsupported - Yet*/
- printk(KERN_ERR "%s() Unsupported - Yet\n", __func__);
- continue;
- } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
- msgs[i].addr == msgs[i + 1].addr) {
- /* write then read from same address */
-
- retval = saa7164_api_i2c_read(bus, msgs[i].addr,
- msgs[i].len, msgs[i].buf,
- msgs[i+1].len, msgs[i+1].buf
- );
-
- i++;
-
- if (retval < 0)
- goto err;
- } else {
- /* write */
- retval = saa7164_api_i2c_write(bus, msgs[i].addr,
- msgs[i].len, msgs[i].buf);
- }
- if (retval < 0)
- goto err;
- }
- return num;
-
-err:
- return retval;
-}
-
-static u32 saa7164_functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm saa7164_i2c_algo_template = {
- .master_xfer = i2c_xfer,
- .functionality = saa7164_functionality,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static struct i2c_adapter saa7164_i2c_adap_template = {
- .name = "saa7164",
- .owner = THIS_MODULE,
- .algo = &saa7164_i2c_algo_template,
-};
-
-static struct i2c_client saa7164_i2c_client_template = {
- .name = "saa7164 internal",
-};
-
-int saa7164_i2c_register(struct saa7164_i2c *bus)
-{
- struct saa7164_dev *dev = bus->dev;
-
- dprintk(DBGLVL_I2C, "%s(bus = %d)\n", __func__, bus->nr);
-
- bus->i2c_adap = saa7164_i2c_adap_template;
- bus->i2c_client = saa7164_i2c_client_template;
-
- bus->i2c_adap.dev.parent = &dev->pci->dev;
-
- strlcpy(bus->i2c_adap.name, bus->dev->name,
- sizeof(bus->i2c_adap.name));
-
- bus->i2c_adap.algo_data = bus;
- i2c_set_adapdata(&bus->i2c_adap, bus);
- i2c_add_adapter(&bus->i2c_adap);
-
- bus->i2c_client.adapter = &bus->i2c_adap;
-
- if (0 != bus->i2c_rc)
- printk(KERN_ERR "%s: i2c bus %d register FAILED\n",
- dev->name, bus->nr);
-
- return bus->i2c_rc;
-}
-
-int saa7164_i2c_unregister(struct saa7164_i2c *bus)
-{
- i2c_del_adapter(&bus->i2c_adap);
- return 0;
-}
diff --git a/drivers/media/video/saa7164/saa7164-reg.h b/drivers/media/video/saa7164/saa7164-reg.h
deleted file mode 100644
index 2bbf81583d3..00000000000
--- a/drivers/media/video/saa7164/saa7164-reg.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Driver for the NXP SAA7164 PCIe bridge
- *
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* TODO: Retest the driver with errors expressed as negatives */
-
-/* Result codes */
-#define SAA_OK 0
-#define SAA_ERR_BAD_PARAMETER 0x09
-#define SAA_ERR_NO_RESOURCES 0x0c
-#define SAA_ERR_NOT_SUPPORTED 0x13
-#define SAA_ERR_BUSY 0x15
-#define SAA_ERR_READ 0x17
-#define SAA_ERR_TIMEOUT 0x1f
-#define SAA_ERR_OVERFLOW 0x20
-#define SAA_ERR_EMPTY 0x22
-#define SAA_ERR_NOT_STARTED 0x23
-#define SAA_ERR_ALREADY_STARTED 0x24
-#define SAA_ERR_NOT_STOPPED 0x25
-#define SAA_ERR_ALREADY_STOPPED 0x26
-#define SAA_ERR_INVALID_COMMAND 0x3e
-#define SAA_ERR_NULL_PACKET 0x59
-
-/* Errors and flags from the silicon */
-#define PVC_ERRORCODE_UNKNOWN 0x00
-#define PVC_ERRORCODE_INVALID_COMMAND 0x01
-#define PVC_ERRORCODE_INVALID_CONTROL 0x02
-#define PVC_ERRORCODE_INVALID_DATA 0x03
-#define PVC_ERRORCODE_TIMEOUT 0x04
-#define PVC_ERRORCODE_NAK 0x05
-#define PVC_RESPONSEFLAG_ERROR 0x01
-#define PVC_RESPONSEFLAG_OVERFLOW 0x02
-#define PVC_RESPONSEFLAG_RESET 0x04
-#define PVC_RESPONSEFLAG_INTERFACE 0x08
-#define PVC_RESPONSEFLAG_CONTINUED 0x10
-#define PVC_CMDFLAG_INTERRUPT 0x02
-#define PVC_CMDFLAG_INTERFACE 0x04
-#define PVC_CMDFLAG_SERIALIZE 0x08
-#define PVC_CMDFLAG_CONTINUE 0x10
-
-/* Silicon Commands */
-#define GET_DESCRIPTORS_CONTROL 0x01
-#define GET_STRING_CONTROL 0x03
-#define GET_LANGUAGE_CONTROL 0x05
-#define SET_POWER_CONTROL 0x07
-#define GET_FW_STATUS_CONTROL 0x08
-#define GET_FW_VERSION_CONTROL 0x09
-#define SET_DEBUG_LEVEL_CONTROL 0x0B
-#define GET_DEBUG_DATA_CONTROL 0x0C
-#define GET_PRODUCTION_INFO_CONTROL 0x0D
-
-/* cmd defines */
-#define SAA_CMDFLAG_CONTINUE 0x10
-#define SAA_CMD_MAX_MSG_UNITS 256
-
-/* Some defines */
-#define SAA_BUS_TIMEOUT 50
-#define SAA_DEVICE_TIMEOUT 5000
-#define SAA_DEVICE_MAXREQUESTSIZE 256
-
-/* Register addresses */
-#define SAA_DEVICE_VERSION 0x30
-#define SAA_DOWNLOAD_FLAGS 0x34
-#define SAA_DOWNLOAD_FLAG 0x34
-#define SAA_DOWNLOAD_FLAG_ACK 0x38
-#define SAA_DATAREADY_FLAG 0x3C
-#define SAA_DATAREADY_FLAG_ACK 0x40
-
-/* Boot loader register and bit definitions */
-#define SAA_BOOTLOADERERROR_FLAGS 0x44
-#define SAA_DEVICE_IMAGE_SEARCHING 0x01
-#define SAA_DEVICE_IMAGE_LOADING 0x02
-#define SAA_DEVICE_IMAGE_BOOTING 0x03
-#define SAA_DEVICE_IMAGE_CORRUPT 0x04
-#define SAA_DEVICE_MEMORY_CORRUPT 0x08
-#define SAA_DEVICE_NO_IMAGE 0x10
-
-/* Register addresses */
-#define SAA_DEVICE_2ND_VERSION 0x50
-#define SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET 0x54
-
-/* Register addresses */
-#define SAA_SECONDSTAGEERROR_FLAGS 0x64
-
-/* Bootloader regs and flags */
-#define SAA_DEVICE_DEADLOCK_DETECTED_OFFSET 0x6C
-#define SAA_DEVICE_DEADLOCK_DETECTED 0xDEADDEAD
-
-/* Basic firmware status registers */
-#define SAA_DEVICE_SYSINIT_STATUS_OFFSET 0x70
-#define SAA_DEVICE_SYSINIT_STATUS 0x70
-#define SAA_DEVICE_SYSINIT_MODE 0x74
-#define SAA_DEVICE_SYSINIT_SPEC 0x78
-#define SAA_DEVICE_SYSINIT_INST 0x7C
-#define SAA_DEVICE_SYSINIT_CPULOAD 0x80
-#define SAA_DEVICE_SYSINIT_REMAINHEAP 0x84
-
-#define SAA_DEVICE_DOWNLOAD_OFFSET 0x1000
-#define SAA_DEVICE_BUFFERBLOCKSIZE 0x1000
-
-#define SAA_DEVICE_2ND_BUFFERBLOCKSIZE 0x100000
-#define SAA_DEVICE_2ND_DOWNLOAD_OFFSET 0x200000
-
-/* Descriptors */
-#define CS_INTERFACE 0x24
-
-/* Descriptor subtypes */
-#define VC_INPUT_TERMINAL 0x02
-#define VC_OUTPUT_TERMINAL 0x03
-#define VC_SELECTOR_UNIT 0x04
-#define VC_PROCESSING_UNIT 0x05
-#define FEATURE_UNIT 0x06
-#define TUNER_UNIT 0x09
-#define ENCODER_UNIT 0x0A
-#define EXTENSION_UNIT 0x0B
-#define VC_TUNER_PATH 0xF0
-#define PVC_HARDWARE_DESCRIPTOR 0xF1
-#define PVC_INTERFACE_DESCRIPTOR 0xF2
-#define PVC_INFRARED_UNIT 0xF3
-#define DRM_UNIT 0xF4
-#define GENERAL_REQUEST 0xF5
-
-/* Format Types */
-#define VS_FORMAT_TYPE 0x02
-#define VS_FORMAT_TYPE_I 0x01
-#define VS_FORMAT_UNCOMPRESSED 0x04
-#define VS_FRAME_UNCOMPRESSED 0x05
-#define VS_FORMAT_MPEG2PS 0x09
-#define VS_FORMAT_MPEG2TS 0x0A
-#define VS_FORMAT_MPEG4SL 0x0B
-#define VS_FORMAT_WM9 0x0C
-#define VS_FORMAT_DIVX 0x0D
-#define VS_FORMAT_VBI 0x0E
-#define VS_FORMAT_RDS 0x0F
-
-/* Device extension commands */
-#define EXU_REGISTER_ACCESS_CONTROL 0x00
-#define EXU_GPIO_CONTROL 0x01
-#define EXU_GPIO_GROUP_CONTROL 0x02
-#define EXU_INTERRUPT_CONTROL 0x03
-
-/* State Transition and args */
-#define SAA_PROBE_CONTROL 0x01
-#define SAA_COMMIT_CONTROL 0x02
-#define SAA_STATE_CONTROL 0x03
-#define SAA_DMASTATE_STOP 0x00
-#define SAA_DMASTATE_ACQUIRE 0x01
-#define SAA_DMASTATE_PAUSE 0x02
-#define SAA_DMASTATE_RUN 0x03
-
-/* A/V Mux Input Selector */
-#define SU_INPUT_SELECT_CONTROL 0x01
-
-/* Encoder Profiles */
-#define EU_PROFILE_PS_DVD 0x06
-#define EU_PROFILE_TS_HQ 0x09
-#define EU_VIDEO_FORMAT_MPEG_2 0x02
-
-/* Tuner */
-#define TU_AUDIO_MODE_CONTROL 0x17
-
-/* Video Formats */
-#define TU_STANDARD_CONTROL 0x00
-#define TU_STANDARD_AUTO_CONTROL 0x01
-#define TU_STANDARD_NONE 0x00
-#define TU_STANDARD_NTSC_M 0x01
-#define TU_STANDARD_PAL_I 0x08
-#define TU_STANDARD_MANUAL 0x00
-#define TU_STANDARD_AUTO 0x01
-
-/* Video Controls */
-#define PU_BRIGHTNESS_CONTROL 0x02
-#define PU_CONTRAST_CONTROL 0x03
-#define PU_HUE_CONTROL 0x06
-#define PU_SATURATION_CONTROL 0x07
-#define PU_SHARPNESS_CONTROL 0x08
-
-/* Audio Controls */
-#define MUTE_CONTROL 0x01
-#define VOLUME_CONTROL 0x02
-#define AUDIO_DEFAULT_CONTROL 0x0D
-
-/* Default Volume Levels */
-#define TMHW_LEV_ADJ_DECLEV_DEFAULT 0x00
-#define TMHW_LEV_ADJ_MONOLEV_DEFAULT 0x00
-#define TMHW_LEV_ADJ_NICLEV_DEFAULT 0x00
-#define TMHW_LEV_ADJ_SAPLEV_DEFAULT 0x00
-#define TMHW_LEV_ADJ_ADCLEV_DEFAULT 0x00
-
-/* Encoder Related Commands */
-#define EU_PROFILE_CONTROL 0x00
-#define EU_VIDEO_FORMAT_CONTROL 0x01
-#define EU_VIDEO_BIT_RATE_CONTROL 0x02
-#define EU_VIDEO_RESOLUTION_CONTROL 0x03
-#define EU_VIDEO_GOP_STRUCTURE_CONTROL 0x04
-#define EU_VIDEO_INPUT_ASPECT_CONTROL 0x0A
-#define EU_AUDIO_FORMAT_CONTROL 0x0C
-#define EU_AUDIO_BIT_RATE_CONTROL 0x0D
-
-/* Firmware Debugging */
-#define SET_DEBUG_LEVEL_CONTROL 0x0B
-#define GET_DEBUG_DATA_CONTROL 0x0C
diff --git a/drivers/media/video/saa7164/saa7164-types.h b/drivers/media/video/saa7164/saa7164-types.h
deleted file mode 100644
index 1d2140a3eb3..00000000000
--- a/drivers/media/video/saa7164/saa7164-types.h
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Driver for the NXP SAA7164 PCIe bridge
- *
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* TODO: Cleanup and shorten the namespace */
-
-/* Some structues are passed directly to/from the firmware and
- * have strict alignment requirements. This is one of them.
- */
-struct tmComResHWDescr {
- u8 bLength;
- u8 bDescriptorType;
- u8 bDescriptorSubtype;
- u16 bcdSpecVersion;
- u32 dwClockFrequency;
- u32 dwClockUpdateRes;
- u8 bCapabilities;
- u32 dwDeviceRegistersLocation;
- u32 dwHostMemoryRegion;
- u32 dwHostMemoryRegionSize;
- u32 dwHostHibernatMemRegion;
- u32 dwHostHibernatMemRegionSize;
-} __attribute__((packed));
-
-/* This is DWORD aligned on windows but I can't find the right
- * gcc syntax to match the binary data from the device.
- * I've manually padded with Reserved[3] bytes to match the hardware,
- * but this could break if GCC decies to pack in a different way.
- */
-struct tmComResInterfaceDescr {
- u8 bLength;
- u8 bDescriptorType;
- u8 bDescriptorSubtype;
- u8 bFlags;
- u8 bInterfaceType;
- u8 bInterfaceId;
- u8 bBaseInterface;
- u8 bInterruptId;
- u8 bDebugInterruptId;
- u8 BARLocation;
- u8 Reserved[3];
-};
-
-struct tmComResBusDescr {
- u64 CommandRing;
- u64 ResponseRing;
- u32 CommandWrite;
- u32 CommandRead;
- u32 ResponseWrite;
- u32 ResponseRead;
-};
-
-enum tmBusType {
- NONE = 0,
- TYPE_BUS_PCI = 1,
- TYPE_BUS_PCIe = 2,
- TYPE_BUS_USB = 3,
- TYPE_BUS_I2C = 4
-};
-
-struct tmComResBusInfo {
- enum tmBusType Type;
- u16 m_wMaxReqSize;
- u8 *m_pdwSetRing;
- u32 m_dwSizeSetRing;
- u8 *m_pdwGetRing;
- u32 m_dwSizeGetRing;
- u32 m_dwSetWritePos;
- u32 m_dwSetReadPos;
- u32 m_dwGetWritePos;
- u32 m_dwGetReadPos;
-
- /* All access is protected */
- struct mutex lock;
-
-};
-
-struct tmComResInfo {
- u8 id;
- u8 flags;
- u16 size;
- u32 command;
- u16 controlselector;
- u8 seqno;
-} __attribute__((packed));
-
-enum tmComResCmd {
- SET_CUR = 0x01,
- GET_CUR = 0x81,
- GET_MIN = 0x82,
- GET_MAX = 0x83,
- GET_RES = 0x84,
- GET_LEN = 0x85,
- GET_INFO = 0x86,
- GET_DEF = 0x87
-};
-
-struct cmd {
- u8 seqno;
- u32 inuse;
- u32 timeout;
- u32 signalled;
- struct mutex lock;
- wait_queue_head_t wait;
-};
-
-struct tmDescriptor {
- u32 pathid;
- u32 size;
- void *descriptor;
-};
-
-struct tmComResDescrHeader {
- u8 len;
- u8 type;
- u8 subtype;
- u8 unitid;
-} __attribute__((packed));
-
-struct tmComResExtDevDescrHeader {
- u8 len;
- u8 type;
- u8 subtype;
- u8 unitid;
- u32 devicetype;
- u16 deviceid;
- u32 numgpiopins;
- u8 numgpiogroups;
- u8 controlsize;
-} __attribute__((packed));
-
-struct tmComResGPIO {
- u32 pin;
- u8 state;
-} __attribute__((packed));
-
-struct tmComResPathDescrHeader {
- u8 len;
- u8 type;
- u8 subtype;
- u8 pathid;
-} __attribute__((packed));
-
-/* terminaltype */
-enum tmComResTermType {
- ITT_ANTENNA = 0x0203,
- LINE_CONNECTOR = 0x0603,
- SPDIF_CONNECTOR = 0x0605,
- COMPOSITE_CONNECTOR = 0x0401,
- SVIDEO_CONNECTOR = 0x0402,
- COMPONENT_CONNECTOR = 0x0403,
- STANDARD_DMA = 0xF101
-};
-
-struct tmComResAntTermDescrHeader {
- u8 len;
- u8 type;
- u8 subtype;
- u8 terminalid;
- u16 terminaltype;
- u8 assocterminal;
- u8 iterminal;
- u8 controlsize;
-} __attribute__((packed));
-
-struct tmComResTunerDescrHeader {
- u8 len;
- u8 type;
- u8 subtype;
- u8 unitid;
- u8 sourceid;
- u8 iunit;
- u32 tuningstandards;
- u8 controlsize;
- u32 controls;
-} __attribute__((packed));
-
-enum tmBufferFlag {
- /* the buffer does not contain any valid data */
- TM_BUFFER_FLAG_EMPTY,
-
- /* the buffer is filled with valid data */
- TM_BUFFER_FLAG_DONE,
-
- /* the buffer is the dummy buffer - TODO??? */
- TM_BUFFER_FLAG_DUMMY_BUFFER
-};
-
-struct tmBuffer {
- u64 *pagetablevirt;
- u64 pagetablephys;
- u16 offset;
- u8 *context;
- u64 timestamp;
- enum tmBufferFlag BufferFlag;
- u32 lostbuffers;
- u32 validbuffers;
- u64 *dummypagevirt;
- u64 dummypagephys;
- u64 *addressvirt;
-};
-
-struct tmHWStreamParameters {
- u32 bitspersample;
- u32 samplesperline;
- u32 numberoflines;
- u32 pitch;
- u32 linethreshold;
- u64 **pagetablelistvirt;
- u64 *pagetablelistphys;
- u32 numpagetables;
- u32 numpagetableentries;
-};
-
-struct tmStreamParameters {
- struct tmHWStreamParameters HWStreamParameters;
- u64 qwDummyPageTablePhys;
- u64 *pDummyPageTableVirt;
-};
-
-struct tmComResDMATermDescrHeader {
- u8 len;
- u8 type;
- u8 subtyle;
- u8 unitid;
- u16 terminaltype;
- u8 assocterminal;
- u8 sourceid;
- u8 iterminal;
- u32 BARLocation;
- u8 flags;
- u8 interruptid;
- u8 buffercount;
- u8 metadatasize;
- u8 numformats;
- u8 controlsize;
-} __attribute__((packed));
-
-/*
- *
- * Description:
- * This is the transport stream format header.
- *
- * Settings:
- * bLength - The size of this descriptor in bytes.
- * bDescriptorType - CS_INTERFACE.
- * bDescriptorSubtype - VS_FORMAT_MPEG2TS descriptor subtype.
- * bFormatIndex - A non-zero constant that uniquely identifies the
- * format.
- * bDataOffset - Offset to TSP packet within MPEG-2 TS transport
- * stride, in bytes.
- * bPacketLength - Length of TSP packet, in bytes (typically 188).
- * bStrideLength - Length of MPEG-2 TS transport stride.
- * guidStrideFormat - A Globally Unique Identifier indicating the
- * format of the stride data (if any). Set to zeros
- * if there is no Stride Data, or if the Stride
- * Data is to be ignored by the application.
- *
- */
-struct tmComResTSFormatDescrHeader {
- u8 len;
- u8 type;
- u8 subtype;
- u8 bFormatIndex;
- u8 bDataOffset;
- u8 bPacketLength;
- u8 bStrideLength;
- u8 guidStrideFormat[16];
-} __attribute__((packed));
-
-/* Encoder related structures */
-
-/* A/V Mux Selector */
-struct tmComResSelDescrHeader {
- u8 len;
- u8 type;
- u8 subtype;
- u8 unitid;
- u8 nrinpins;
- u8 sourceid;
-} __attribute__((packed));
-
-/* A/V Audio processor definitions */
-struct tmComResProcDescrHeader {
- u8 len;
- u8 type;
- u8 subtype;
- u8 unitid;
- u8 sourceid;
- u16 wreserved;
- u8 controlsize;
-} __attribute__((packed));
-
-/* Video bitrate control message */
-#define EU_VIDEO_BIT_RATE_MODE_CONSTANT (0)
-#define EU_VIDEO_BIT_RATE_MODE_VARIABLE_AVERAGE (1)
-#define EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK (2)
-struct tmComResEncVideoBitRate {
- u8 ucVideoBitRateMode;
- u32 dwVideoBitRate;
- u32 dwVideoBitRatePeak;
-} __attribute__((packed));
-
-/* Video Encoder Aspect Ratio message */
-struct tmComResEncVideoInputAspectRatio {
- u8 width;
- u8 height;
-} __attribute__((packed));
-
-/* Video Encoder GOP IBP message */
-/* 1. IPPPPPPPPPPPPPP */
-/* 2. IBPBPBPBPBPBPBP */
-/* 3. IBBPBBPBBPBBP */
-#define SAA7164_ENCODER_DEFAULT_GOP_DIST (1)
-#define SAA7164_ENCODER_DEFAULT_GOP_SIZE (15)
-struct tmComResEncVideoGopStructure {
- u8 ucGOPSize; /* GOP Size 12, 15 */
- u8 ucRefFrameDist; /* Reference Frame Distance */
-} __attribute__((packed));
-
-/* Encoder processor definition */
-struct tmComResEncoderDescrHeader {
- u8 len;
- u8 type;
- u8 subtype;
- u8 unitid;
- u8 vsourceid;
- u8 asourceid;
- u8 iunit;
- u32 dwmControlCap;
- u32 dwmProfileCap;
- u32 dwmVidFormatCap;
- u8 bmVidBitrateCap;
- u16 wmVidResolutionsCap;
- u16 wmVidFrmRateCap;
- u32 dwmAudFormatCap;
- u8 bmAudBitrateCap;
-} __attribute__((packed));
-
-/* Audio processor definition */
-struct tmComResAFeatureDescrHeader {
- u8 len;
- u8 type;
- u8 subtype;
- u8 unitid;
- u8 sourceid;
- u8 controlsize;
-} __attribute__((packed));
-
-/* Audio control messages */
-struct tmComResAudioDefaults {
- u8 ucDecoderLevel;
- u8 ucDecoderFM_Level;
- u8 ucMonoLevel;
- u8 ucNICAM_Level;
- u8 ucSAP_Level;
- u8 ucADC_Level;
-} __attribute__((packed));
-
-/* Audio bitrate control message */
-struct tmComResEncAudioBitRate {
- u8 ucAudioBitRateMode;
- u32 dwAudioBitRate;
- u32 dwAudioBitRatePeak;
-} __attribute__((packed));
-
-/* Tuner / AV Decoder messages */
-struct tmComResTunerStandard {
- u8 std;
- u32 country;
-} __attribute__((packed));
-
-struct tmComResTunerStandardAuto {
- u8 mode;
-} __attribute__((packed));
-
-/* EEPROM definition for PS stream types */
-struct tmComResPSFormatDescrHeader {
- u8 len;
- u8 type;
- u8 subtype;
- u8 bFormatIndex;
- u16 wPacketLength;
- u16 wPackLength;
- u8 bPackDataType;
-} __attribute__((packed));
-
-/* VBI control structure */
-struct tmComResVBIFormatDescrHeader {
- u8 len;
- u8 type;
- u8 subtype; /* VS_FORMAT_VBI */
- u8 bFormatIndex;
- u32 VideoStandard; /* See KS_AnalogVideoStandard, NTSC = 1 */
- u8 StartLine; /* NTSC Start = 10 */
- u8 EndLine; /* NTSC = 21 */
- u8 FieldRate; /* 60 for NTSC */
- u8 bNumLines; /* Unused - scheduled for removal */
-} __attribute__((packed));
-
-struct tmComResProbeCommit {
- u16 bmHint;
- u8 bFormatIndex;
- u8 bFrameIndex;
-} __attribute__((packed));
-
-struct tmComResDebugSetLevel {
- u32 dwDebugLevel;
-} __attribute__((packed));
-
-struct tmComResDebugGetData {
- u32 dwResult;
- u8 ucDebugData[256];
-} __attribute__((packed));
-
-struct tmFwInfoStruct {
- u32 status;
- u32 mode;
- u32 devicespec;
- u32 deviceinst;
- u32 CPULoad;
- u32 RemainHeap;
- u32 CPUClock;
- u32 RAMSpeed;
-} __attribute__((packed));
diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/video/saa7164/saa7164-vbi.c
deleted file mode 100644
index d8e6c8f1407..00000000000
--- a/drivers/media/video/saa7164/saa7164-vbi.c
+++ /dev/null
@@ -1,1374 +0,0 @@
-/*
- * Driver for the NXP SAA7164 PCIe bridge
- *
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "saa7164.h"
-
-static struct saa7164_tvnorm saa7164_tvnorms[] = {
- {
- .name = "NTSC-M",
- .id = V4L2_STD_NTSC_M,
- }, {
- .name = "NTSC-JP",
- .id = V4L2_STD_NTSC_M_JP,
- }
-};
-
-static const u32 saa7164_v4l2_ctrls[] = {
- 0
-};
-
-/* Take the encoder configuration from the port struct and
- * flush it to the hardware.
- */
-static void saa7164_vbi_configure(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- dprintk(DBGLVL_VBI, "%s()\n", __func__);
-
- port->vbi_params.width = port->width;
- port->vbi_params.height = port->height;
- port->vbi_params.is_50hz =
- (port->encodernorm.id & V4L2_STD_625_50) != 0;
-
- /* Set up the DIF (enable it) for analog mode by default */
- saa7164_api_initialize_dif(port);
-
- /* Configure the correct video standard */
-#if 0
- saa7164_api_configure_dif(port, port->encodernorm.id);
-#endif
-
-#if 0
- /* Ensure the audio decoder is correct configured */
- saa7164_api_set_audio_std(port);
-#endif
- dprintk(DBGLVL_VBI, "%s() ends\n", __func__);
-}
-
-static int saa7164_vbi_buffers_dealloc(struct saa7164_port *port)
-{
- struct list_head *c, *n, *p, *q, *l, *v;
- struct saa7164_dev *dev = port->dev;
- struct saa7164_buffer *buf;
- struct saa7164_user_buffer *ubuf;
-
- /* Remove any allocated buffers */
- mutex_lock(&port->dmaqueue_lock);
-
- dprintk(DBGLVL_VBI, "%s(port=%d) dmaqueue\n", __func__, port->nr);
- list_for_each_safe(c, n, &port->dmaqueue.list) {
- buf = list_entry(c, struct saa7164_buffer, list);
- list_del(c);
- saa7164_buffer_dealloc(buf);
- }
-
- dprintk(DBGLVL_VBI, "%s(port=%d) used\n", __func__, port->nr);
- list_for_each_safe(p, q, &port->list_buf_used.list) {
- ubuf = list_entry(p, struct saa7164_user_buffer, list);
- list_del(p);
- saa7164_buffer_dealloc_user(ubuf);
- }
-
- dprintk(DBGLVL_VBI, "%s(port=%d) free\n", __func__, port->nr);
- list_for_each_safe(l, v, &port->list_buf_free.list) {
- ubuf = list_entry(l, struct saa7164_user_buffer, list);
- list_del(l);
- saa7164_buffer_dealloc_user(ubuf);
- }
-
- mutex_unlock(&port->dmaqueue_lock);
- dprintk(DBGLVL_VBI, "%s(port=%d) done\n", __func__, port->nr);
-
- return 0;
-}
-
-/* Dynamic buffer switch at vbi start time */
-static int saa7164_vbi_buffers_alloc(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- struct saa7164_buffer *buf;
- struct saa7164_user_buffer *ubuf;
- struct tmHWStreamParameters *params = &port->hw_streamingparams;
- int result = -ENODEV, i;
- int len = 0;
-
- dprintk(DBGLVL_VBI, "%s()\n", __func__);
-
- /* TODO: NTSC SPECIFIC */
- /* Init and establish defaults */
- params->samplesperline = 1440;
- params->numberoflines = 12;
- params->numberoflines = 18;
- params->pitch = 1600;
- params->pitch = 1440;
- params->numpagetables = 2 +
- ((params->numberoflines * params->pitch) / PAGE_SIZE);
- params->bitspersample = 8;
- params->linethreshold = 0;
- params->pagetablelistvirt = NULL;
- params->pagetablelistphys = NULL;
- params->numpagetableentries = port->hwcfg.buffercount;
-
- /* Allocate the PCI resources, buffers (hard) */
- for (i = 0; i < port->hwcfg.buffercount; i++) {
- buf = saa7164_buffer_alloc(port,
- params->numberoflines *
- params->pitch);
-
- if (!buf) {
- printk(KERN_ERR "%s() failed "
- "(errno = %d), unable to allocate buffer\n",
- __func__, result);
- result = -ENOMEM;
- goto failed;
- } else {
-
- mutex_lock(&port->dmaqueue_lock);
- list_add_tail(&buf->list, &port->dmaqueue.list);
- mutex_unlock(&port->dmaqueue_lock);
-
- }
- }
-
- /* Allocate some kernel buffers for copying
- * to userpsace.
- */
- len = params->numberoflines * params->pitch;
-
- if (vbi_buffers < 16)
- vbi_buffers = 16;
- if (vbi_buffers > 512)
- vbi_buffers = 512;
-
- for (i = 0; i < vbi_buffers; i++) {
-
- ubuf = saa7164_buffer_alloc_user(dev, len);
- if (ubuf) {
- mutex_lock(&port->dmaqueue_lock);
- list_add_tail(&ubuf->list, &port->list_buf_free.list);
- mutex_unlock(&port->dmaqueue_lock);
- }
-
- }
-
- result = 0;
-
-failed:
- return result;
-}
-
-
-static int saa7164_vbi_initialize(struct saa7164_port *port)
-{
- saa7164_vbi_configure(port);
- return 0;
-}
-
-/* -- V4L2 --------------------------------------------------------- */
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
- unsigned int i;
-
- dprintk(DBGLVL_VBI, "%s(id=0x%x)\n", __func__, (u32)*id);
-
- for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) {
- if (*id & saa7164_tvnorms[i].id)
- break;
- }
- if (i == ARRAY_SIZE(saa7164_tvnorms))
- return -EINVAL;
-
- port->encodernorm = saa7164_tvnorms[i];
-
- /* Update the audio decoder while is not running in
- * auto detect mode.
- */
- saa7164_api_set_audio_std(port);
-
- dprintk(DBGLVL_VBI, "%s(id=0x%x) OK\n", __func__, (u32)*id);
-
- return 0;
-}
-
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- int n;
-
- char *inputs[] = { "tuner", "composite", "svideo", "aux",
- "composite 2", "svideo 2", "aux 2" };
-
- if (i->index >= 7)
- return -EINVAL;
-
- strcpy(i->name, inputs[i->index]);
-
- if (i->index == 0)
- i->type = V4L2_INPUT_TYPE_TUNER;
- else
- i->type = V4L2_INPUT_TYPE_CAMERA;
-
- for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++)
- i->std |= saa7164_tvnorms[n].id;
-
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- if (saa7164_api_get_videomux(port) != SAA_OK)
- return -EIO;
-
- *i = (port->mux_input - 1);
-
- dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, *i);
-
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, i);
-
- if (i >= 7)
- return -EINVAL;
-
- port->mux_input = i + 1;
-
- if (saa7164_api_set_videomux(port) != SAA_OK)
- return -EIO;
-
- return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- if (0 != t->index)
- return -EINVAL;
-
- strcpy(t->name, "tuner");
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO;
-
- dprintk(DBGLVL_VBI, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
-
- return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- /* Update the A/V core */
- return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
-
- f->type = V4L2_TUNER_ANALOG_TV;
- f->frequency = port->freq;
-
- return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
- struct saa7164_port *tsport;
- struct dvb_frontend *fe;
-
- /* TODO: Pull this for the std */
- struct analog_parameters params = {
- .mode = V4L2_TUNER_ANALOG_TV,
- .audmode = V4L2_TUNER_MODE_STEREO,
- .std = port->encodernorm.id,
- .frequency = f->frequency
- };
-
- /* Stop the encoder */
- dprintk(DBGLVL_VBI, "%s() frequency=%d tuner=%d\n", __func__,
- f->frequency, f->tuner);
-
- if (f->tuner != 0)
- return -EINVAL;
-
- if (f->type != V4L2_TUNER_ANALOG_TV)
- return -EINVAL;
-
- port->freq = f->frequency;
-
- /* Update the hardware */
- if (port->nr == SAA7164_PORT_VBI1)
- tsport = &dev->ports[SAA7164_PORT_TS1];
- else
- if (port->nr == SAA7164_PORT_VBI2)
- tsport = &dev->ports[SAA7164_PORT_TS2];
- else
- BUG();
-
- fe = tsport->dvb.frontend;
-
- if (fe && fe->ops.tuner_ops.set_analog_params)
- fe->ops.tuner_ops.set_analog_params(fe, &params);
- else
- printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__);
-
- saa7164_vbi_initialize(port);
-
- return 0;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__,
- ctl->id, ctl->value);
-
- switch (ctl->id) {
- case V4L2_CID_BRIGHTNESS:
- ctl->value = port->ctl_brightness;
- break;
- case V4L2_CID_CONTRAST:
- ctl->value = port->ctl_contrast;
- break;
- case V4L2_CID_SATURATION:
- ctl->value = port->ctl_saturation;
- break;
- case V4L2_CID_HUE:
- ctl->value = port->ctl_hue;
- break;
- case V4L2_CID_SHARPNESS:
- ctl->value = port->ctl_sharpness;
- break;
- case V4L2_CID_AUDIO_VOLUME:
- ctl->value = port->ctl_volume;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
- int ret = 0;
-
- dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__,
- ctl->id, ctl->value);
-
- switch (ctl->id) {
- case V4L2_CID_BRIGHTNESS:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_brightness = ctl->value;
- saa7164_api_set_usercontrol(port,
- PU_BRIGHTNESS_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_CONTRAST:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_contrast = ctl->value;
- saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_SATURATION:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_saturation = ctl->value;
- saa7164_api_set_usercontrol(port,
- PU_SATURATION_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_HUE:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_hue = ctl->value;
- saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_SHARPNESS:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_sharpness = ctl->value;
- saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_AUDIO_VOLUME:
- if ((ctl->value >= -83) && (ctl->value <= 24)) {
- port->ctl_volume = ctl->value;
- saa7164_api_set_audio_volume(port, port->ctl_volume);
- } else
- ret = -EINVAL;
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int saa7164_get_ctrl(struct saa7164_port *port,
- struct v4l2_ext_control *ctrl)
-{
- struct saa7164_vbi_params *params = &port->vbi_params;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_STREAM_TYPE:
- ctrl->value = params->stream_type;
- break;
- case V4L2_CID_MPEG_AUDIO_MUTE:
- ctrl->value = params->ctl_mute;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- ctrl->value = params->ctl_aspect;
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- ctrl->value = params->refdist;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- ctrl->value = params->gop_size;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int vidioc_g_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = saa7164_get_ctrl(port, ctrl);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
-
- }
-
- return -EINVAL;
-}
-
-static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
-{
- int ret = -EINVAL;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_STREAM_TYPE:
- if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) ||
- (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS))
- ret = 0;
- break;
- case V4L2_CID_MPEG_AUDIO_MUTE:
- if ((ctrl->value >= 0) &&
- (ctrl->value <= 1))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) &&
- (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- if ((ctrl->value >= 0) &&
- (ctrl->value <= 255))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- if ((ctrl->value >= 1) &&
- (ctrl->value <= 3))
- ret = 0;
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int vidioc_try_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = saa7164_try_ctrl(ctrl, 0);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
- }
-
- return -EINVAL;
-}
-
-static int saa7164_set_ctrl(struct saa7164_port *port,
- struct v4l2_ext_control *ctrl)
-{
- struct saa7164_vbi_params *params = &port->vbi_params;
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_STREAM_TYPE:
- params->stream_type = ctrl->value;
- break;
- case V4L2_CID_MPEG_AUDIO_MUTE:
- params->ctl_mute = ctrl->value;
- ret = saa7164_api_audio_mute(port, params->ctl_mute);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
- ret);
- ret = -EIO;
- }
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- params->ctl_aspect = ctrl->value;
- ret = saa7164_api_set_aspect_ratio(port);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
- ret);
- ret = -EIO;
- }
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- params->refdist = ctrl->value;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- params->gop_size = ctrl->value;
- break;
- default:
- return -EINVAL;
- }
-
- /* TODO: Update the hardware */
-
- return ret;
-}
-
-static int vidioc_s_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = saa7164_try_ctrl(ctrl, 0);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- err = saa7164_set_ctrl(port, ctrl);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
-
- }
-
- return -EINVAL;
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- strcpy(cap->driver, dev->name);
- strlcpy(cap->card, saa7164_boards[dev->board].name,
- sizeof(cap->card));
- sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
-
- cap->capabilities =
- V4L2_CAP_VBI_CAPTURE |
- V4L2_CAP_READWRITE |
- 0;
-
- cap->capabilities |= V4L2_CAP_TUNER;
- cap->version = 0;
-
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (f->index != 0)
- return -EINVAL;
-
- strlcpy(f->description, "VBI", sizeof(f->description));
- f->pixelformat = V4L2_PIX_FMT_MPEG;
-
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- port->ts_packet_size * port->ts_packet_count;
- f->fmt.pix.colorspace = 0;
- f->fmt.pix.width = port->width;
- f->fmt.pix.height = port->height;
-
- dprintk(DBGLVL_VBI, "VIDIOC_G_FMT: w: %d, h: %d\n",
- port->width, port->height);
-
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- port->ts_packet_size * port->ts_packet_count;
- f->fmt.pix.colorspace = 0;
- dprintk(DBGLVL_VBI, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
- port->width, port->height);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- port->ts_packet_size * port->ts_packet_count;
- f->fmt.pix.colorspace = 0;
-
- dprintk(DBGLVL_VBI, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
- f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
-
- return 0;
-}
-
-static int fill_queryctrl(struct saa7164_vbi_params *params,
- struct v4l2_queryctrl *c)
-{
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127);
- case V4L2_CID_CONTRAST:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66);
- case V4L2_CID_SATURATION:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62);
- case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128);
- case V4L2_CID_SHARPNESS:
- return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8);
- case V4L2_CID_MPEG_AUDIO_MUTE:
- return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0);
- case V4L2_CID_AUDIO_VOLUME:
- return v4l2_ctrl_query_fill(c, -83, 24, 1, 20);
- case V4L2_CID_MPEG_STREAM_TYPE:
- return v4l2_ctrl_query_fill(c,
- V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
- V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
- 1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- return v4l2_ctrl_query_fill(c,
- V4L2_MPEG_VIDEO_ASPECT_1x1,
- V4L2_MPEG_VIDEO_ASPECT_221x100,
- 1, V4L2_MPEG_VIDEO_ASPECT_4x3);
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- return v4l2_ctrl_query_fill(c,
- 1, 3, 1, 1);
- default:
- return -EINVAL;
- }
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *c)
-{
- struct saa7164_vbi_fh *fh = priv;
- struct saa7164_port *port = fh->port;
- int i, next;
- u32 id = c->id;
-
- memset(c, 0, sizeof(*c));
-
- next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
- c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
-
- for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) {
- if (next) {
- if (c->id < saa7164_v4l2_ctrls[i])
- c->id = saa7164_v4l2_ctrls[i];
- else
- continue;
- }
-
- if (c->id == saa7164_v4l2_ctrls[i])
- return fill_queryctrl(&port->vbi_params, c);
-
- if (c->id < saa7164_v4l2_ctrls[i])
- break;
- }
-
- return -EINVAL;
-}
-
-static int saa7164_vbi_stop_port(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int ret;
-
- ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
- if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
- __func__, ret);
- ret = -EIO;
- } else {
- dprintk(DBGLVL_VBI, "%s() Stopped\n", __func__);
- ret = 0;
- }
-
- return ret;
-}
-
-static int saa7164_vbi_acquire_port(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int ret;
-
- ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
- if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
- __func__, ret);
- ret = -EIO;
- } else {
- dprintk(DBGLVL_VBI, "%s() Acquired\n", __func__);
- ret = 0;
- }
-
- return ret;
-}
-
-static int saa7164_vbi_pause_port(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int ret;
-
- ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
- if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
- __func__, ret);
- ret = -EIO;
- } else {
- dprintk(DBGLVL_VBI, "%s() Paused\n", __func__);
- ret = 0;
- }
-
- return ret;
-}
-
-/* Firmware is very windows centric, meaning you have to transition
- * the part through AVStream / KS Windows stages, forwards or backwards.
- * States are: stopped, acquired (h/w), paused, started.
- * We have to leave here will all of the soft buffers on the free list,
- * else the cfg_post() func won't have soft buffers to correctly configure.
- */
-static int saa7164_vbi_stop_streaming(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- struct saa7164_buffer *buf;
- struct saa7164_user_buffer *ubuf;
- struct list_head *c, *n;
- int ret;
-
- dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
-
- ret = saa7164_vbi_pause_port(port);
- ret = saa7164_vbi_acquire_port(port);
- ret = saa7164_vbi_stop_port(port);
-
- dprintk(DBGLVL_VBI, "%s(port=%d) Hardware stopped\n", __func__,
- port->nr);
-
- /* Reset the state of any allocated buffer resources */
- mutex_lock(&port->dmaqueue_lock);
-
- /* Reset the hard and soft buffer state */
- list_for_each_safe(c, n, &port->dmaqueue.list) {
- buf = list_entry(c, struct saa7164_buffer, list);
- buf->flags = SAA7164_BUFFER_FREE;
- buf->pos = 0;
- }
-
- list_for_each_safe(c, n, &port->list_buf_used.list) {
- ubuf = list_entry(c, struct saa7164_user_buffer, list);
- ubuf->pos = 0;
- list_move_tail(&ubuf->list, &port->list_buf_free.list);
- }
-
- mutex_unlock(&port->dmaqueue_lock);
-
- /* Free any allocated resources */
- saa7164_vbi_buffers_dealloc(port);
-
- dprintk(DBGLVL_VBI, "%s(port=%d) Released\n", __func__, port->nr);
-
- return ret;
-}
-
-static int saa7164_vbi_start_streaming(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int result, ret = 0;
-
- dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
-
- port->done_first_interrupt = 0;
-
- /* allocate all of the PCIe DMA buffer resources on the fly,
- * allowing switching between TS and PS payloads without
- * requiring a complete driver reload.
- */
- saa7164_vbi_buffers_alloc(port);
-
- /* Configure the encoder with any cache values */
-#if 0
- saa7164_api_set_encoder(port);
- saa7164_api_get_encoder(port);
-#endif
-
- /* Place the empty buffers on the hardware */
- saa7164_buffer_cfg_port(port);
-
- /* Negotiate format */
- if (saa7164_api_set_vbi_format(port) != SAA_OK) {
- printk(KERN_ERR "%s() No supported VBI format\n", __func__);
- ret = -EIO;
- goto out;
- }
-
- /* Acquire the hardware */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
- __func__, result);
-
- ret = -EIO;
- goto out;
- } else
- dprintk(DBGLVL_VBI, "%s() Acquired\n", __func__);
-
- /* Pause the hardware */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
- __func__, result);
-
- /* Stop the hardware, regardless */
- result = saa7164_vbi_stop_port(port);
- if (result != SAA_OK) {
- printk(KERN_ERR "%s() pause/forced stop transition "
- "failed, res = 0x%x\n", __func__, result);
- }
-
- ret = -EIO;
- goto out;
- } else
- dprintk(DBGLVL_VBI, "%s() Paused\n", __func__);
-
- /* Start the hardware */
- result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
- if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
- printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
- __func__, result);
-
- /* Stop the hardware, regardless */
- result = saa7164_vbi_acquire_port(port);
- result = saa7164_vbi_stop_port(port);
- if (result != SAA_OK) {
- printk(KERN_ERR "%s() run/forced stop transition "
- "failed, res = 0x%x\n", __func__, result);
- }
-
- ret = -EIO;
- } else
- dprintk(DBGLVL_VBI, "%s() Running\n", __func__);
-
-out:
- return ret;
-}
-
-int saa7164_vbi_fmt(struct file *file, void *priv, struct v4l2_format *f)
-{
- /* ntsc */
- f->fmt.vbi.samples_per_line = 1600;
- f->fmt.vbi.samples_per_line = 1440;
- f->fmt.vbi.sampling_rate = 27000000;
- f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
- f->fmt.vbi.offset = 0;
- f->fmt.vbi.flags = 0;
- f->fmt.vbi.start[0] = 10;
- f->fmt.vbi.count[0] = 18;
- f->fmt.vbi.start[1] = 263 + 10 + 1;
- f->fmt.vbi.count[1] = 18;
- return 0;
-}
-
-static int fops_open(struct file *file)
-{
- struct saa7164_dev *dev;
- struct saa7164_port *port;
- struct saa7164_vbi_fh *fh;
-
- port = (struct saa7164_port *)video_get_drvdata(video_devdata(file));
- if (!port)
- return -ENODEV;
-
- dev = port->dev;
-
- dprintk(DBGLVL_VBI, "%s()\n", __func__);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- file->private_data = fh;
- fh->port = port;
-
- return 0;
-}
-
-static int fops_release(struct file *file)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- dprintk(DBGLVL_VBI, "%s()\n", __func__);
-
- /* Shut device down on last close */
- if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
- if (atomic_dec_return(&port->v4l_reader_count) == 0) {
- /* stop vbi capture then cancel buffers */
- saa7164_vbi_stop_streaming(port);
- }
- }
-
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port)
-{
- struct saa7164_user_buffer *ubuf = NULL;
- struct saa7164_dev *dev = port->dev;
- u32 crc;
-
- mutex_lock(&port->dmaqueue_lock);
- if (!list_empty(&port->list_buf_used.list)) {
- ubuf = list_first_entry(&port->list_buf_used.list,
- struct saa7164_user_buffer, list);
-
- if (crc_checking) {
- crc = crc32(0, ubuf->data, ubuf->actual_size);
- if (crc != ubuf->crc) {
- printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n",
- __func__,
- ubuf, ubuf->crc, crc);
- }
- }
-
- }
- mutex_unlock(&port->dmaqueue_lock);
-
- dprintk(DBGLVL_VBI, "%s() returns %p\n", __func__, ubuf);
-
- return ubuf;
-}
-
-static ssize_t fops_read(struct file *file, char __user *buffer,
- size_t count, loff_t *pos)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_user_buffer *ubuf = NULL;
- struct saa7164_dev *dev = port->dev;
- int ret = 0;
- int rem, cnt;
- u8 *p;
-
- port->last_read_msecs_diff = port->last_read_msecs;
- port->last_read_msecs = jiffies_to_msecs(jiffies);
- port->last_read_msecs_diff = port->last_read_msecs -
- port->last_read_msecs_diff;
-
- saa7164_histogram_update(&port->read_interval,
- port->last_read_msecs_diff);
-
- if (*pos) {
- printk(KERN_ERR "%s() ESPIPE\n", __func__);
- return -ESPIPE;
- }
-
- if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
- if (atomic_inc_return(&port->v4l_reader_count) == 1) {
-
- if (saa7164_vbi_initialize(port) < 0) {
- printk(KERN_ERR "%s() EINVAL\n", __func__);
- return -EINVAL;
- }
-
- saa7164_vbi_start_streaming(port);
- msleep(200);
- }
- }
-
- /* blocking wait for buffer */
- if ((file->f_flags & O_NONBLOCK) == 0) {
- if (wait_event_interruptible(port->wait_read,
- saa7164_vbi_next_buf(port))) {
- printk(KERN_ERR "%s() ERESTARTSYS\n", __func__);
- return -ERESTARTSYS;
- }
- }
-
- /* Pull the first buffer from the used list */
- ubuf = saa7164_vbi_next_buf(port);
-
- while ((count > 0) && ubuf) {
-
- /* set remaining bytes to copy */
- rem = ubuf->actual_size - ubuf->pos;
- cnt = rem > count ? count : rem;
-
- p = ubuf->data + ubuf->pos;
-
- dprintk(DBGLVL_VBI,
- "%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n",
- __func__, (int)count, cnt, rem, ubuf, ubuf->pos);
-
- if (copy_to_user(buffer, p, cnt)) {
- printk(KERN_ERR "%s() copy_to_user failed\n", __func__);
- if (!ret) {
- printk(KERN_ERR "%s() EFAULT\n", __func__);
- ret = -EFAULT;
- }
- goto err;
- }
-
- ubuf->pos += cnt;
- count -= cnt;
- buffer += cnt;
- ret += cnt;
-
- if (ubuf->pos > ubuf->actual_size)
- printk(KERN_ERR "read() pos > actual, huh?\n");
-
- if (ubuf->pos == ubuf->actual_size) {
-
- /* finished with current buffer, take next buffer */
-
- /* Requeue the buffer on the free list */
- ubuf->pos = 0;
-
- mutex_lock(&port->dmaqueue_lock);
- list_move_tail(&ubuf->list, &port->list_buf_free.list);
- mutex_unlock(&port->dmaqueue_lock);
-
- /* Dequeue next */
- if ((file->f_flags & O_NONBLOCK) == 0) {
- if (wait_event_interruptible(port->wait_read,
- saa7164_vbi_next_buf(port))) {
- break;
- }
- }
- ubuf = saa7164_vbi_next_buf(port);
- }
- }
-err:
- if (!ret && !ubuf) {
- printk(KERN_ERR "%s() EAGAIN\n", __func__);
- ret = -EAGAIN;
- }
-
- return ret;
-}
-
-static unsigned int fops_poll(struct file *file, poll_table *wait)
-{
- struct saa7164_vbi_fh *fh = (struct saa7164_vbi_fh *)file->private_data;
- struct saa7164_port *port = fh->port;
- unsigned int mask = 0;
-
- port->last_poll_msecs_diff = port->last_poll_msecs;
- port->last_poll_msecs = jiffies_to_msecs(jiffies);
- port->last_poll_msecs_diff = port->last_poll_msecs -
- port->last_poll_msecs_diff;
-
- saa7164_histogram_update(&port->poll_interval,
- port->last_poll_msecs_diff);
-
- if (!video_is_registered(port->v4l_device))
- return -EIO;
-
- if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
- if (atomic_inc_return(&port->v4l_reader_count) == 1) {
- if (saa7164_vbi_initialize(port) < 0)
- return -EINVAL;
- saa7164_vbi_start_streaming(port);
- msleep(200);
- }
- }
-
- /* blocking wait for buffer */
- if ((file->f_flags & O_NONBLOCK) == 0) {
- if (wait_event_interruptible(port->wait_read,
- saa7164_vbi_next_buf(port))) {
- return -ERESTARTSYS;
- }
- }
-
- /* Pull the first buffer from the used list */
- if (!list_empty(&port->list_buf_used.list))
- mask |= POLLIN | POLLRDNORM;
-
- return mask;
-}
-static const struct v4l2_file_operations vbi_fops = {
- .owner = THIS_MODULE,
- .open = fops_open,
- .release = fops_release,
- .read = fops_read,
- .poll = fops_poll,
- .unlocked_ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
- .vidioc_s_std = vidioc_s_std,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
- .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
- .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
- .vidioc_queryctrl = vidioc_queryctrl,
-#if 0
- .vidioc_g_chip_ident = saa7164_g_chip_ident,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-#if 0
- .vidioc_g_register = saa7164_g_register,
- .vidioc_s_register = saa7164_s_register,
-#endif
-#endif
- .vidioc_g_fmt_vbi_cap = saa7164_vbi_fmt,
- .vidioc_try_fmt_vbi_cap = saa7164_vbi_fmt,
- .vidioc_s_fmt_vbi_cap = saa7164_vbi_fmt,
-};
-
-static struct video_device saa7164_vbi_template = {
- .name = "saa7164",
- .fops = &vbi_fops,
- .ioctl_ops = &vbi_ioctl_ops,
- .minor = -1,
- .tvnorms = SAA7164_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
-
-static struct video_device *saa7164_vbi_alloc(
- struct saa7164_port *port,
- struct pci_dev *pci,
- struct video_device *template,
- char *type)
-{
- struct video_device *vfd;
- struct saa7164_dev *dev = port->dev;
-
- dprintk(DBGLVL_VBI, "%s()\n", __func__);
-
- vfd = video_device_alloc();
- if (NULL == vfd)
- return NULL;
-
- *vfd = *template;
- snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
- type, saa7164_boards[dev->board].name);
-
- vfd->parent = &pci->dev;
- vfd->release = video_device_release;
- return vfd;
-}
-
-int saa7164_vbi_register(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
- int result = -ENODEV;
-
- dprintk(DBGLVL_VBI, "%s()\n", __func__);
-
- if (port->type != SAA7164_MPEG_VBI)
- BUG();
-
- /* Sanity check that the PCI configuration space is active */
- if (port->hwcfg.BARLocation == 0) {
- printk(KERN_ERR "%s() failed "
- "(errno = %d), NO PCI configuration\n",
- __func__, result);
- result = -ENOMEM;
- goto failed;
- }
-
- /* Establish VBI defaults here */
-
- /* Allocate and register the video device node */
- port->v4l_device = saa7164_vbi_alloc(port,
- dev->pci, &saa7164_vbi_template, "vbi");
-
- if (!port->v4l_device) {
- printk(KERN_INFO "%s: can't allocate vbi device\n",
- dev->name);
- result = -ENOMEM;
- goto failed;
- }
-
- video_set_drvdata(port->v4l_device, port);
- result = video_register_device(port->v4l_device,
- VFL_TYPE_VBI, -1);
- if (result < 0) {
- printk(KERN_INFO "%s: can't register vbi device\n",
- dev->name);
- /* TODO: We're going to leak here if we don't dealloc
- The buffers above. The unreg function can't deal wit it.
- */
- goto failed;
- }
-
- printk(KERN_INFO "%s: registered device vbi%d [vbi]\n",
- dev->name, port->v4l_device->num);
-
- /* Configure the hardware defaults */
-
- result = 0;
-failed:
- return result;
-}
-
-void saa7164_vbi_unregister(struct saa7164_port *port)
-{
- struct saa7164_dev *dev = port->dev;
-
- dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
-
- if (port->type != SAA7164_MPEG_VBI)
- BUG();
-
- if (port->v4l_device) {
- if (port->v4l_device->minor != -1)
- video_unregister_device(port->v4l_device);
- else
- video_device_release(port->v4l_device);
-
- port->v4l_device = NULL;
- }
-
-}
diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h
deleted file mode 100644
index 35219b9b0fb..00000000000
--- a/drivers/media/video/saa7164/saa7164.h
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- * Driver for the NXP SAA7164 PCIe bridge
- *
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- Driver architecture
- *******************
-
- saa7164_core.c/buffer.c/cards.c/i2c.c/dvb.c
- | : Standard Linux driver framework for creating
- | : exposing and managing interfaces to the rest
- | : of the kernel or userland. Also uses _fw.c to load
- | : firmware direct into the PCIe bus, bypassing layers.
- V
- saa7164_api..() : Translate kernel specific functions/features
- | : into command buffers.
- V
- saa7164_cmd..() : Manages the flow of command packets on/off,
- | : the bus. Deal with bus errors, timeouts etc.
- V
- saa7164_bus..() : Manage a read/write memory ring buffer in the
- | : PCIe Address space.
- |
- | saa7164_fw...() : Load any frimware
- | | : direct into the device
- V V
- <- ----------------- PCIe address space -------------------- ->
-*/
-
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/kdev_t.h>
-#include <linux/mutex.h>
-#include <linux/crc32.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-
-#include <media/tuner.h>
-#include <media/tveeprom.h>
-#include <media/videobuf-dma-sg.h>
-#include <media/videobuf-dvb.h>
-#include <dvb_demux.h>
-#include <dvb_frontend.h>
-#include <dvb_net.h>
-#include <dvbdev.h>
-#include <dmxdev.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
-
-#include "saa7164-reg.h"
-#include "saa7164-types.h"
-
-#define SAA7164_MAXBOARDS 8
-
-#define UNSET (-1U)
-#define SAA7164_BOARD_NOAUTO UNSET
-#define SAA7164_BOARD_UNKNOWN 0
-#define SAA7164_BOARD_UNKNOWN_REV2 1
-#define SAA7164_BOARD_UNKNOWN_REV3 2
-#define SAA7164_BOARD_HAUPPAUGE_HVR2250 3
-#define SAA7164_BOARD_HAUPPAUGE_HVR2200 4
-#define SAA7164_BOARD_HAUPPAUGE_HVR2200_2 5
-#define SAA7164_BOARD_HAUPPAUGE_HVR2200_3 6
-#define SAA7164_BOARD_HAUPPAUGE_HVR2250_2 7
-#define SAA7164_BOARD_HAUPPAUGE_HVR2250_3 8
-#define SAA7164_BOARD_HAUPPAUGE_HVR2200_4 9
-#define SAA7164_BOARD_HAUPPAUGE_HVR2200_5 10
-
-#define SAA7164_MAX_UNITS 8
-#define SAA7164_TS_NUMBER_OF_LINES 312
-#define SAA7164_PS_NUMBER_OF_LINES 256
-#define SAA7164_PT_ENTRIES 16 /* (312 * 188) / 4096 */
-#define SAA7164_MAX_ENCODER_BUFFERS 64 /* max 5secs of latency at 6Mbps */
-#define SAA7164_MAX_VBI_BUFFERS 64
-
-/* Port related defines */
-#define SAA7164_PORT_TS1 (0)
-#define SAA7164_PORT_TS2 (SAA7164_PORT_TS1 + 1)
-#define SAA7164_PORT_ENC1 (SAA7164_PORT_TS2 + 1)
-#define SAA7164_PORT_ENC2 (SAA7164_PORT_ENC1 + 1)
-#define SAA7164_PORT_VBI1 (SAA7164_PORT_ENC2 + 1)
-#define SAA7164_PORT_VBI2 (SAA7164_PORT_VBI1 + 1)
-#define SAA7164_MAX_PORTS (SAA7164_PORT_VBI2 + 1)
-
-#define DBGLVL_FW 4
-#define DBGLVL_DVB 8
-#define DBGLVL_I2C 16
-#define DBGLVL_API 32
-#define DBGLVL_CMD 64
-#define DBGLVL_BUS 128
-#define DBGLVL_IRQ 256
-#define DBGLVL_BUF 512
-#define DBGLVL_ENC 1024
-#define DBGLVL_VBI 2048
-#define DBGLVL_THR 4096
-#define DBGLVL_CPU 8192
-
-#define SAA7164_NORMS \
- (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443)
-
-enum port_t {
- SAA7164_MPEG_UNDEFINED = 0,
- SAA7164_MPEG_DVB,
- SAA7164_MPEG_ENCODER,
- SAA7164_MPEG_VBI,
-};
-
-enum saa7164_i2c_bus_nr {
- SAA7164_I2C_BUS_0 = 0,
- SAA7164_I2C_BUS_1,
- SAA7164_I2C_BUS_2,
-};
-
-enum saa7164_buffer_flags {
- SAA7164_BUFFER_UNDEFINED = 0,
- SAA7164_BUFFER_FREE,
- SAA7164_BUFFER_BUSY,
- SAA7164_BUFFER_FULL
-};
-
-enum saa7164_unit_type {
- SAA7164_UNIT_UNDEFINED = 0,
- SAA7164_UNIT_DIGITAL_DEMODULATOR,
- SAA7164_UNIT_ANALOG_DEMODULATOR,
- SAA7164_UNIT_TUNER,
- SAA7164_UNIT_EEPROM,
- SAA7164_UNIT_ZILOG_IRBLASTER,
- SAA7164_UNIT_ENCODER,
-};
-
-/* The PCIe bridge doesn't grant direct access to i2c.
- * Instead, you address i2c devices using a uniqely
- * allocated 'unitid' value via a messaging API. This
- * is a problem. The kernel and existing demod/tuner
- * drivers expect to talk 'i2c', so we have to maintain
- * a translation layer, and a series of functions to
- * convert i2c bus + device address into a unit id.
- */
-struct saa7164_unit {
- enum saa7164_unit_type type;
- u8 id;
- char *name;
- enum saa7164_i2c_bus_nr i2c_bus_nr;
- u8 i2c_bus_addr;
- u8 i2c_reg_len;
-};
-
-struct saa7164_board {
- char *name;
- enum port_t porta, portb, portc,
- portd, porte, portf;
- enum {
- SAA7164_CHIP_UNDEFINED = 0,
- SAA7164_CHIP_REV2,
- SAA7164_CHIP_REV3,
- } chiprev;
- struct saa7164_unit unit[SAA7164_MAX_UNITS];
-};
-
-struct saa7164_subid {
- u16 subvendor;
- u16 subdevice;
- u32 card;
-};
-
-struct saa7164_encoder_fh {
- struct saa7164_port *port;
- atomic_t v4l_reading;
-};
-
-struct saa7164_vbi_fh {
- struct saa7164_port *port;
- atomic_t v4l_reading;
-};
-
-struct saa7164_histogram_bucket {
- u32 val;
- u32 count;
- u64 update_time;
-};
-
-struct saa7164_histogram {
- char name[32];
- struct saa7164_histogram_bucket counter1[64];
-};
-
-struct saa7164_user_buffer {
- struct list_head list;
-
- /* Attributes */
- u8 *data;
- u32 pos;
- u32 actual_size;
-
- u32 crc;
-};
-
-struct saa7164_fw_status {
-
- /* RISC Core details */
- u32 status;
- u32 mode;
- u32 spec;
- u32 inst;
- u32 cpuload;
- u32 remainheap;
-
- /* Firmware version */
- u32 version;
- u32 major;
- u32 sub;
- u32 rel;
- u32 buildnr;
-};
-
-struct saa7164_dvb {
- struct mutex lock;
- struct dvb_adapter adapter;
- struct dvb_frontend *frontend;
- struct dvb_demux demux;
- struct dmxdev dmxdev;
- struct dmx_frontend fe_hw;
- struct dmx_frontend fe_mem;
- struct dvb_net net;
- int feeding;
-};
-
-struct saa7164_i2c {
- struct saa7164_dev *dev;
-
- enum saa7164_i2c_bus_nr nr;
-
- /* I2C I/O */
- struct i2c_adapter i2c_adap;
- struct i2c_client i2c_client;
- u32 i2c_rc;
-};
-
-struct saa7164_ctrl {
- struct v4l2_queryctrl v;
-};
-
-struct saa7164_tvnorm {
- char *name;
- v4l2_std_id id;
-};
-
-struct saa7164_encoder_params {
- struct saa7164_tvnorm encodernorm;
- u32 height;
- u32 width;
- u32 is_50hz;
- u32 bitrate; /* bps */
- u32 bitrate_peak; /* bps */
- u32 bitrate_mode;
- u32 stream_type; /* V4L2_MPEG_STREAM_TYPE_MPEG2_TS */
-
- u32 audio_sampling_freq;
- u32 ctl_mute;
- u32 ctl_aspect;
- u32 refdist;
- u32 gop_size;
-};
-
-struct saa7164_vbi_params {
- struct saa7164_tvnorm encodernorm;
- u32 height;
- u32 width;
- u32 is_50hz;
- u32 bitrate; /* bps */
- u32 bitrate_peak; /* bps */
- u32 bitrate_mode;
- u32 stream_type; /* V4L2_MPEG_STREAM_TYPE_MPEG2_TS */
-
- u32 audio_sampling_freq;
- u32 ctl_mute;
- u32 ctl_aspect;
- u32 refdist;
- u32 gop_size;
-};
-
-struct saa7164_port;
-
-struct saa7164_buffer {
- struct list_head list;
-
- /* Note of which h/w buffer list index position we occupy */
- int idx;
-
- struct saa7164_port *port;
-
- /* Hardware Specific */
- /* PCI Memory allocations */
- enum saa7164_buffer_flags flags; /* Free, Busy, Full */
-
- /* A block of page align PCI memory */
- u32 pci_size; /* PCI allocation size in bytes */
- u64 __iomem *cpu; /* Virtual address */
- dma_addr_t dma; /* Physical address */
- u32 crc; /* Checksum for the entire buffer data */
-
- /* A page table that splits the block into a number of entries */
- u32 pt_size; /* PCI allocation size in bytes */
- u64 __iomem *pt_cpu; /* Virtual address */
- dma_addr_t pt_dma; /* Physical address */
-
- /* Encoder fops */
- u32 pos;
- u32 actual_size;
-};
-
-struct saa7164_port {
-
- struct saa7164_dev *dev;
- enum port_t type;
- int nr;
-
- /* --- Generic port attributes --- */
-
- /* HW stream parameters */
- struct tmHWStreamParameters hw_streamingparams;
-
- /* DMA configuration values, is seeded during initialization */
- struct tmComResDMATermDescrHeader hwcfg;
-
- /* hardware specific registers */
- u32 bufcounter;
- u32 pitch;
- u32 bufsize;
- u32 bufoffset;
- u32 bufptr32l;
- u32 bufptr32h;
- u64 bufptr64;
-
- u32 numpte; /* Number of entries in array, only valid in head */
-
- struct mutex dmaqueue_lock;
- struct saa7164_buffer dmaqueue;
-
- u64 last_irq_msecs, last_svc_msecs;
- u64 last_irq_msecs_diff, last_svc_msecs_diff;
- u32 last_svc_wp;
- u32 last_svc_rp;
- u64 last_irq_svc_msecs_diff;
- u64 last_read_msecs, last_read_msecs_diff;
- u64 last_poll_msecs, last_poll_msecs_diff;
-
- struct saa7164_histogram irq_interval;
- struct saa7164_histogram svc_interval;
- struct saa7164_histogram irq_svc_interval;
- struct saa7164_histogram read_interval;
- struct saa7164_histogram poll_interval;
-
- /* --- DVB Transport Specific --- */
- struct saa7164_dvb dvb;
-
- /* --- Encoder/V4L related attributes --- */
- /* Encoder */
- /* Defaults established in saa7164-encoder.c */
- struct saa7164_tvnorm encodernorm;
- u32 height;
- u32 width;
- u32 freq;
- u32 ts_packet_size;
- u32 ts_packet_count;
- u8 mux_input;
- u8 encoder_profile;
- u8 video_format;
- u8 audio_format;
- u8 video_resolution;
- u16 ctl_brightness;
- u16 ctl_contrast;
- u16 ctl_hue;
- u16 ctl_saturation;
- u16 ctl_sharpness;
- s8 ctl_volume;
-
- struct tmComResAFeatureDescrHeader audfeat;
- struct tmComResEncoderDescrHeader encunit;
- struct tmComResProcDescrHeader vidproc;
- struct tmComResExtDevDescrHeader ifunit;
- struct tmComResTunerDescrHeader tunerunit;
-
- struct work_struct workenc;
-
- /* V4L Encoder Video */
- struct saa7164_encoder_params encoder_params;
- struct video_device *v4l_device;
- atomic_t v4l_reader_count;
-
- struct saa7164_buffer list_buf_used;
- struct saa7164_buffer list_buf_free;
- wait_queue_head_t wait_read;
-
- /* V4L VBI */
- struct tmComResVBIFormatDescrHeader vbi_fmt_ntsc;
- struct saa7164_vbi_params vbi_params;
-
- /* Debug */
- u32 sync_errors;
- u32 v_cc_errors;
- u32 a_cc_errors;
- u8 last_v_cc;
- u8 last_a_cc;
- u32 done_first_interrupt;
-};
-
-struct saa7164_dev {
- struct list_head devlist;
- atomic_t refcount;
-
- /* pci stuff */
- struct pci_dev *pci;
- unsigned char pci_rev, pci_lat;
- int pci_bus, pci_slot;
- u32 __iomem *lmmio;
- u8 __iomem *bmmio;
- u32 __iomem *lmmio2;
- u8 __iomem *bmmio2;
- int pci_irqmask;
-
- /* board details */
- int nr;
- int hwrevision;
- u32 board;
- char name[16];
-
- /* firmware status */
- struct saa7164_fw_status fw_status;
- u32 firmwareloaded;
-
- struct tmComResHWDescr hwdesc;
- struct tmComResInterfaceDescr intfdesc;
- struct tmComResBusDescr busdesc;
-
- struct tmComResBusInfo bus;
-
- /* Interrupt status and ack registers */
- u32 int_status;
- u32 int_ack;
-
- struct cmd cmds[SAA_CMD_MAX_MSG_UNITS];
- struct mutex lock;
-
- /* I2c related */
- struct saa7164_i2c i2c_bus[3];
-
- /* Transport related */
- struct saa7164_port ports[SAA7164_MAX_PORTS];
-
- /* Deferred command/api interrupts handling */
- struct work_struct workcmd;
-
- /* A kernel thread to monitor the firmware log, used
- * only in debug mode.
- */
- struct task_struct *kthread;
-
-};
-
-extern struct list_head saa7164_devlist;
-extern unsigned int waitsecs;
-extern unsigned int encoder_buffers;
-extern unsigned int vbi_buffers;
-
-/* ----------------------------------------------------------- */
-/* saa7164-core.c */
-void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr);
-void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len);
-void saa7164_getfirmwarestatus(struct saa7164_dev *dev);
-u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev);
-void saa7164_histogram_update(struct saa7164_histogram *hg, u32 val);
-
-/* ----------------------------------------------------------- */
-/* saa7164-fw.c */
-int saa7164_downloadfirmware(struct saa7164_dev *dev);
-
-/* ----------------------------------------------------------- */
-/* saa7164-i2c.c */
-extern int saa7164_i2c_register(struct saa7164_i2c *bus);
-extern int saa7164_i2c_unregister(struct saa7164_i2c *bus);
-extern void saa7164_call_i2c_clients(struct saa7164_i2c *bus,
- unsigned int cmd, void *arg);
-
-/* ----------------------------------------------------------- */
-/* saa7164-bus.c */
-int saa7164_bus_setup(struct saa7164_dev *dev);
-void saa7164_bus_dump(struct saa7164_dev *dev);
-int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg,
- void *buf);
-int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
- void *buf, int peekonly);
-
-/* ----------------------------------------------------------- */
-/* saa7164-cmd.c */
-int saa7164_cmd_send(struct saa7164_dev *dev,
- u8 id, enum tmComResCmd command, u16 controlselector,
- u16 size, void *buf);
-void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno);
-int saa7164_irq_dequeue(struct saa7164_dev *dev);
-
-/* ----------------------------------------------------------- */
-/* saa7164-api.c */
-int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version);
-int saa7164_api_enum_subdevs(struct saa7164_dev *dev);
-int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
- u32 datalen, u8 *data);
-int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr,
- u32 datalen, u8 *data);
-int saa7164_api_dif_write(struct saa7164_i2c *bus, u8 addr,
- u32 datalen, u8 *data);
-int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen);
-int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin);
-int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin);
-int saa7164_api_transition_port(struct saa7164_port *port, u8 mode);
-int saa7164_api_initialize_dif(struct saa7164_port *port);
-int saa7164_api_configure_dif(struct saa7164_port *port, u32 std);
-int saa7164_api_set_encoder(struct saa7164_port *port);
-int saa7164_api_get_encoder(struct saa7164_port *port);
-int saa7164_api_set_aspect_ratio(struct saa7164_port *port);
-int saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl);
-int saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl);
-int saa7164_api_set_videomux(struct saa7164_port *port);
-int saa7164_api_audio_mute(struct saa7164_port *port, int mute);
-int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level);
-int saa7164_api_set_audio_std(struct saa7164_port *port);
-int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect);
-int saa7164_api_get_videomux(struct saa7164_port *port);
-int saa7164_api_set_vbi_format(struct saa7164_port *port);
-int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level);
-int saa7164_api_collect_debug(struct saa7164_dev *dev);
-int saa7164_api_get_load_info(struct saa7164_dev *dev,
- struct tmFwInfoStruct *i);
-
-/* ----------------------------------------------------------- */
-/* saa7164-cards.c */
-extern struct saa7164_board saa7164_boards[];
-extern const unsigned int saa7164_bcount;
-
-extern struct saa7164_subid saa7164_subids[];
-extern const unsigned int saa7164_idcount;
-
-extern void saa7164_card_list(struct saa7164_dev *dev);
-extern void saa7164_gpio_setup(struct saa7164_dev *dev);
-extern void saa7164_card_setup(struct saa7164_dev *dev);
-
-extern int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr);
-extern int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr);
-extern char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid);
-
-/* ----------------------------------------------------------- */
-/* saa7164-dvb.c */
-extern int saa7164_dvb_register(struct saa7164_port *port);
-extern int saa7164_dvb_unregister(struct saa7164_port *port);
-
-/* ----------------------------------------------------------- */
-/* saa7164-buffer.c */
-extern struct saa7164_buffer *saa7164_buffer_alloc(
- struct saa7164_port *port, u32 len);
-extern int saa7164_buffer_dealloc(struct saa7164_buffer *buf);
-extern void saa7164_buffer_display(struct saa7164_buffer *buf);
-extern int saa7164_buffer_activate(struct saa7164_buffer *buf, int i);
-extern int saa7164_buffer_cfg_port(struct saa7164_port *port);
-extern struct saa7164_user_buffer *saa7164_buffer_alloc_user(
- struct saa7164_dev *dev, u32 len);
-extern void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf);
-extern int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i);
-
-/* ----------------------------------------------------------- */
-/* saa7164-encoder.c */
-int saa7164_encoder_register(struct saa7164_port *port);
-void saa7164_encoder_unregister(struct saa7164_port *port);
-
-/* ----------------------------------------------------------- */
-/* saa7164-vbi.c */
-int saa7164_vbi_register(struct saa7164_port *port);
-void saa7164_vbi_unregister(struct saa7164_port *port);
-
-/* ----------------------------------------------------------- */
-
-extern unsigned int crc_checking;
-
-extern unsigned int saa_debug;
-#define dprintk(level, fmt, arg...)\
- do { if (saa_debug & level)\
- printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\
- } while (0)
-
-#define log_warn(fmt, arg...)\
- do { \
- printk(KERN_WARNING "%s: " fmt, dev->name, ## arg);\
- } while (0)
-
-#define saa7164_readl(reg) readl(dev->lmmio + ((reg) >> 2))
-#define saa7164_writel(reg, value) writel((value), dev->lmmio + ((reg) >> 2))
-
-#define saa7164_readb(reg) readl(dev->bmmio + (reg))
-#define saa7164_writeb(reg, value) writel((value), dev->bmmio + (reg))
-
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
deleted file mode 100644
index 1e84466515a..00000000000
--- a/drivers/media/video/saa717x.c
+++ /dev/null
@@ -1,1378 +0,0 @@
-/*
- * saa717x - Philips SAA717xHL video decoder driver
- *
- * Based on the saa7115 driver
- *
- * Changes by Ohta Kyuma <alpha292@bremen.or.jp>
- * - Apply to SAA717x,NEC uPD64031,uPD64083. (1/31/2004)
- *
- * Changes by T.Adachi (tadachi@tadachi-net.com)
- * - support audio, video scaler etc, and checked the initialize sequence.
- *
- * Cleaned up by Hans Verkuil <hverkuil@xs4all.nl>
- *
- * Note: this is a reversed engineered driver based on captures from
- * the I2C bus under Windows. This chip is very similar to the saa7134,
- * though. Unfortunately, this driver is currently only working for NTSC.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-
-#include <linux/videodev2.h>
-#include <linux/i2c.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-
-MODULE_DESCRIPTION("Philips SAA717x audio/video decoder driver");
-MODULE_AUTHOR("K. Ohta, T. Adachi, Hans Verkuil");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-
-struct saa717x_state {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- v4l2_std_id std;
- int input;
- int enable;
- int radio;
- int playback;
- int audio;
- int tuner_audio_mode;
- int audio_main_mute;
- int audio_main_vol_r;
- int audio_main_vol_l;
- u16 audio_main_bass;
- u16 audio_main_treble;
- u16 audio_main_volume;
- u16 audio_main_balance;
- int audio_input;
-};
-
-static inline struct saa717x_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct saa717x_state, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct saa717x_state, hdl)->sd;
-}
-
-/* ----------------------------------------------------------------------- */
-
-/* for audio mode */
-#define TUNER_AUDIO_MONO 0 /* LL */
-#define TUNER_AUDIO_STEREO 1 /* LR */
-#define TUNER_AUDIO_LANG1 2 /* LL */
-#define TUNER_AUDIO_LANG2 3 /* RR */
-
-#define SAA717X_NTSC_WIDTH (704)
-#define SAA717X_NTSC_HEIGHT (480)
-
-/* ----------------------------------------------------------------------- */
-
-static int saa717x_write(struct v4l2_subdev *sd, u32 reg, u32 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct i2c_adapter *adap = client->adapter;
- int fw_addr = reg == 0x454 || (reg >= 0x464 && reg <= 0x478) || reg == 0x480 || reg == 0x488;
- unsigned char mm1[6];
- struct i2c_msg msg;
-
- msg.flags = 0;
- msg.addr = client->addr;
- mm1[0] = (reg >> 8) & 0xff;
- mm1[1] = reg & 0xff;
-
- if (fw_addr) {
- mm1[4] = (value >> 16) & 0xff;
- mm1[3] = (value >> 8) & 0xff;
- mm1[2] = value & 0xff;
- } else {
- mm1[2] = value & 0xff;
- }
- msg.len = fw_addr ? 5 : 3; /* Long Registers have *only* three bytes! */
- msg.buf = mm1;
- v4l2_dbg(2, debug, sd, "wrote: reg 0x%03x=%08x\n", reg, value);
- return i2c_transfer(adap, &msg, 1) == 1;
-}
-
-static void saa717x_write_regs(struct v4l2_subdev *sd, u32 *data)
-{
- while (data[0] || data[1]) {
- saa717x_write(sd, data[0], data[1]);
- data += 2;
- }
-}
-
-static u32 saa717x_read(struct v4l2_subdev *sd, u32 reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct i2c_adapter *adap = client->adapter;
- int fw_addr = (reg >= 0x404 && reg <= 0x4b8) || reg == 0x528;
- unsigned char mm1[2];
- unsigned char mm2[4] = { 0, 0, 0, 0 };
- struct i2c_msg msgs[2];
- u32 value;
-
- msgs[0].flags = 0;
- msgs[1].flags = I2C_M_RD;
- msgs[0].addr = msgs[1].addr = client->addr;
- mm1[0] = (reg >> 8) & 0xff;
- mm1[1] = reg & 0xff;
- msgs[0].len = 2;
- msgs[0].buf = mm1;
- msgs[1].len = fw_addr ? 3 : 1; /* Multibyte Registers contains *only* 3 bytes */
- msgs[1].buf = mm2;
- i2c_transfer(adap, msgs, 2);
-
- if (fw_addr)
- value = (mm2[2] & 0xff) | ((mm2[1] & 0xff) >> 8) | ((mm2[0] & 0xff) >> 16);
- else
- value = mm2[0] & 0xff;
-
- v4l2_dbg(2, debug, sd, "read: reg 0x%03x=0x%08x\n", reg, value);
- return value;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static u32 reg_init_initialize[] =
-{
- /* from linux driver */
- 0x101, 0x008, /* Increment delay */
-
- 0x103, 0x000, /* Analog input control 2 */
- 0x104, 0x090, /* Analog input control 3 */
- 0x105, 0x090, /* Analog input control 4 */
- 0x106, 0x0eb, /* Horizontal sync start */
- 0x107, 0x0e0, /* Horizontal sync stop */
- 0x109, 0x055, /* Luminance control */
-
- 0x10f, 0x02a, /* Chroma gain control */
- 0x110, 0x000, /* Chroma control 2 */
-
- 0x114, 0x045, /* analog/ADC */
-
- 0x118, 0x040, /* RAW data gain */
- 0x119, 0x080, /* RAW data offset */
-
- 0x044, 0x000, /* VBI horizontal input window start (L) TASK A */
- 0x045, 0x000, /* VBI horizontal input window start (H) TASK A */
- 0x046, 0x0cf, /* VBI horizontal input window stop (L) TASK A */
- 0x047, 0x002, /* VBI horizontal input window stop (H) TASK A */
-
- 0x049, 0x000, /* VBI vertical input window start (H) TASK A */
-
- 0x04c, 0x0d0, /* VBI horizontal output length (L) TASK A */
- 0x04d, 0x002, /* VBI horizontal output length (H) TASK A */
-
- 0x064, 0x080, /* Lumina brightness TASK A */
- 0x065, 0x040, /* Luminance contrast TASK A */
- 0x066, 0x040, /* Chroma saturation TASK A */
- /* 067H: Reserved */
- 0x068, 0x000, /* VBI horizontal scaling increment (L) TASK A */
- 0x069, 0x004, /* VBI horizontal scaling increment (H) TASK A */
- 0x06a, 0x000, /* VBI phase offset TASK A */
-
- 0x06e, 0x000, /* Horizontal phase offset Luma TASK A */
- 0x06f, 0x000, /* Horizontal phase offset Chroma TASK A */
-
- 0x072, 0x000, /* Vertical filter mode TASK A */
-
- 0x084, 0x000, /* VBI horizontal input window start (L) TAKS B */
- 0x085, 0x000, /* VBI horizontal input window start (H) TAKS B */
- 0x086, 0x0cf, /* VBI horizontal input window stop (L) TAKS B */
- 0x087, 0x002, /* VBI horizontal input window stop (H) TAKS B */
-
- 0x089, 0x000, /* VBI vertical input window start (H) TAKS B */
-
- 0x08c, 0x0d0, /* VBI horizontal output length (L) TASK B */
- 0x08d, 0x002, /* VBI horizontal output length (H) TASK B */
-
- 0x0a4, 0x080, /* Lumina brightness TASK B */
- 0x0a5, 0x040, /* Luminance contrast TASK B */
- 0x0a6, 0x040, /* Chroma saturation TASK B */
- /* 0A7H reserved */
- 0x0a8, 0x000, /* VBI horizontal scaling increment (L) TASK B */
- 0x0a9, 0x004, /* VBI horizontal scaling increment (H) TASK B */
- 0x0aa, 0x000, /* VBI phase offset TASK B */
-
- 0x0ae, 0x000, /* Horizontal phase offset Luma TASK B */
- 0x0af, 0x000, /*Horizontal phase offset Chroma TASK B */
-
- 0x0b2, 0x000, /* Vertical filter mode TASK B */
-
- 0x00c, 0x000, /* Start point GREEN path */
- 0x00d, 0x000, /* Start point BLUE path */
- 0x00e, 0x000, /* Start point RED path */
-
- 0x010, 0x010, /* GREEN path gamma curve --- */
- 0x011, 0x020,
- 0x012, 0x030,
- 0x013, 0x040,
- 0x014, 0x050,
- 0x015, 0x060,
- 0x016, 0x070,
- 0x017, 0x080,
- 0x018, 0x090,
- 0x019, 0x0a0,
- 0x01a, 0x0b0,
- 0x01b, 0x0c0,
- 0x01c, 0x0d0,
- 0x01d, 0x0e0,
- 0x01e, 0x0f0,
- 0x01f, 0x0ff, /* --- GREEN path gamma curve */
-
- 0x020, 0x010, /* BLUE path gamma curve --- */
- 0x021, 0x020,
- 0x022, 0x030,
- 0x023, 0x040,
- 0x024, 0x050,
- 0x025, 0x060,
- 0x026, 0x070,
- 0x027, 0x080,
- 0x028, 0x090,
- 0x029, 0x0a0,
- 0x02a, 0x0b0,
- 0x02b, 0x0c0,
- 0x02c, 0x0d0,
- 0x02d, 0x0e0,
- 0x02e, 0x0f0,
- 0x02f, 0x0ff, /* --- BLUE path gamma curve */
-
- 0x030, 0x010, /* RED path gamma curve --- */
- 0x031, 0x020,
- 0x032, 0x030,
- 0x033, 0x040,
- 0x034, 0x050,
- 0x035, 0x060,
- 0x036, 0x070,
- 0x037, 0x080,
- 0x038, 0x090,
- 0x039, 0x0a0,
- 0x03a, 0x0b0,
- 0x03b, 0x0c0,
- 0x03c, 0x0d0,
- 0x03d, 0x0e0,
- 0x03e, 0x0f0,
- 0x03f, 0x0ff, /* --- RED path gamma curve */
-
- 0x109, 0x085, /* Luminance control */
-
- /**** from app start ****/
- 0x584, 0x000, /* AGC gain control */
- 0x585, 0x000, /* Program count */
- 0x586, 0x003, /* Status reset */
- 0x588, 0x0ff, /* Number of audio samples (L) */
- 0x589, 0x00f, /* Number of audio samples (M) */
- 0x58a, 0x000, /* Number of audio samples (H) */
- 0x58b, 0x000, /* Audio select */
- 0x58c, 0x010, /* Audio channel assign1 */
- 0x58d, 0x032, /* Audio channel assign2 */
- 0x58e, 0x054, /* Audio channel assign3 */
- 0x58f, 0x023, /* Audio format */
- 0x590, 0x000, /* SIF control */
-
- 0x595, 0x000, /* ?? */
- 0x596, 0x000, /* ?? */
- 0x597, 0x000, /* ?? */
-
- 0x464, 0x00, /* Digital input crossbar1 */
-
- 0x46c, 0xbbbb10, /* Digital output selection1-3 */
- 0x470, 0x101010, /* Digital output selection4-6 */
-
- 0x478, 0x00, /* Sound feature control */
-
- 0x474, 0x18, /* Softmute control */
-
- 0x454, 0x0425b9, /* Sound Easy programming(reset) */
- 0x454, 0x042539, /* Sound Easy programming(reset) */
-
-
- /**** common setting( of DVD play, including scaler commands) ****/
- 0x042, 0x003, /* Data path configuration for VBI (TASK A) */
-
- 0x082, 0x003, /* Data path configuration for VBI (TASK B) */
-
- 0x108, 0x0f8, /* Sync control */
- 0x2a9, 0x0fd, /* ??? */
- 0x102, 0x089, /* select video input "mode 9" */
- 0x111, 0x000, /* Mode/delay control */
-
- 0x10e, 0x00a, /* Chroma control 1 */
-
- 0x594, 0x002, /* SIF, analog I/O select */
-
- 0x454, 0x0425b9, /* Sound */
- 0x454, 0x042539,
-
- 0x111, 0x000,
- 0x10e, 0x00a,
- 0x464, 0x000,
- 0x300, 0x000,
- 0x301, 0x006,
- 0x302, 0x000,
- 0x303, 0x006,
- 0x308, 0x040,
- 0x309, 0x000,
- 0x30a, 0x000,
- 0x30b, 0x000,
- 0x000, 0x002,
- 0x001, 0x000,
- 0x002, 0x000,
- 0x003, 0x000,
- 0x004, 0x033,
- 0x040, 0x01d,
- 0x041, 0x001,
- 0x042, 0x004,
- 0x043, 0x000,
- 0x080, 0x01e,
- 0x081, 0x001,
- 0x082, 0x004,
- 0x083, 0x000,
- 0x190, 0x018,
- 0x115, 0x000,
- 0x116, 0x012,
- 0x117, 0x018,
- 0x04a, 0x011,
- 0x08a, 0x011,
- 0x04b, 0x000,
- 0x08b, 0x000,
- 0x048, 0x000,
- 0x088, 0x000,
- 0x04e, 0x012,
- 0x08e, 0x012,
- 0x058, 0x012,
- 0x098, 0x012,
- 0x059, 0x000,
- 0x099, 0x000,
- 0x05a, 0x003,
- 0x09a, 0x003,
- 0x05b, 0x001,
- 0x09b, 0x001,
- 0x054, 0x008,
- 0x094, 0x008,
- 0x055, 0x000,
- 0x095, 0x000,
- 0x056, 0x0c7,
- 0x096, 0x0c7,
- 0x057, 0x002,
- 0x097, 0x002,
- 0x0ff, 0x0ff,
- 0x060, 0x001,
- 0x0a0, 0x001,
- 0x061, 0x000,
- 0x0a1, 0x000,
- 0x062, 0x000,
- 0x0a2, 0x000,
- 0x063, 0x000,
- 0x0a3, 0x000,
- 0x070, 0x000,
- 0x0b0, 0x000,
- 0x071, 0x004,
- 0x0b1, 0x004,
- 0x06c, 0x0e9,
- 0x0ac, 0x0e9,
- 0x06d, 0x003,
- 0x0ad, 0x003,
- 0x05c, 0x0d0,
- 0x09c, 0x0d0,
- 0x05d, 0x002,
- 0x09d, 0x002,
- 0x05e, 0x0f2,
- 0x09e, 0x0f2,
- 0x05f, 0x000,
- 0x09f, 0x000,
- 0x074, 0x000,
- 0x0b4, 0x000,
- 0x075, 0x000,
- 0x0b5, 0x000,
- 0x076, 0x000,
- 0x0b6, 0x000,
- 0x077, 0x000,
- 0x0b7, 0x000,
- 0x195, 0x008,
- 0x0ff, 0x0ff,
- 0x108, 0x0f8,
- 0x111, 0x000,
- 0x10e, 0x00a,
- 0x2a9, 0x0fd,
- 0x464, 0x001,
- 0x454, 0x042135,
- 0x598, 0x0e7,
- 0x599, 0x07d,
- 0x59a, 0x018,
- 0x59c, 0x066,
- 0x59d, 0x090,
- 0x59e, 0x001,
- 0x584, 0x000,
- 0x585, 0x000,
- 0x586, 0x003,
- 0x588, 0x0ff,
- 0x589, 0x00f,
- 0x58a, 0x000,
- 0x58b, 0x000,
- 0x58c, 0x010,
- 0x58d, 0x032,
- 0x58e, 0x054,
- 0x58f, 0x023,
- 0x590, 0x000,
- 0x595, 0x000,
- 0x596, 0x000,
- 0x597, 0x000,
- 0x464, 0x000,
- 0x46c, 0xbbbb10,
- 0x470, 0x101010,
-
-
- 0x478, 0x000,
- 0x474, 0x018,
- 0x454, 0x042135,
- 0x598, 0x0e7,
- 0x599, 0x07d,
- 0x59a, 0x018,
- 0x59c, 0x066,
- 0x59d, 0x090,
- 0x59e, 0x001,
- 0x584, 0x000,
- 0x585, 0x000,
- 0x586, 0x003,
- 0x588, 0x0ff,
- 0x589, 0x00f,
- 0x58a, 0x000,
- 0x58b, 0x000,
- 0x58c, 0x010,
- 0x58d, 0x032,
- 0x58e, 0x054,
- 0x58f, 0x023,
- 0x590, 0x000,
- 0x595, 0x000,
- 0x596, 0x000,
- 0x597, 0x000,
- 0x464, 0x000,
- 0x46c, 0xbbbb10,
- 0x470, 0x101010,
-
- 0x478, 0x000,
- 0x474, 0x018,
- 0x454, 0x042135,
- 0x598, 0x0e7,
- 0x599, 0x07d,
- 0x59a, 0x018,
- 0x59c, 0x066,
- 0x59d, 0x090,
- 0x59e, 0x001,
- 0x584, 0x000,
- 0x585, 0x000,
- 0x586, 0x003,
- 0x588, 0x0ff,
- 0x589, 0x00f,
- 0x58a, 0x000,
- 0x58b, 0x000,
- 0x58c, 0x010,
- 0x58d, 0x032,
- 0x58e, 0x054,
- 0x58f, 0x023,
- 0x590, 0x000,
- 0x595, 0x000,
- 0x596, 0x000,
- 0x597, 0x000,
- 0x464, 0x000,
- 0x46c, 0xbbbb10,
- 0x470, 0x101010,
- 0x478, 0x000,
- 0x474, 0x018,
- 0x454, 0x042135,
- 0x193, 0x000,
- 0x300, 0x000,
- 0x301, 0x006,
- 0x302, 0x000,
- 0x303, 0x006,
- 0x308, 0x040,
- 0x309, 0x000,
- 0x30a, 0x000,
- 0x30b, 0x000,
- 0x000, 0x002,
- 0x001, 0x000,
- 0x002, 0x000,
- 0x003, 0x000,
- 0x004, 0x033,
- 0x040, 0x01d,
- 0x041, 0x001,
- 0x042, 0x004,
- 0x043, 0x000,
- 0x080, 0x01e,
- 0x081, 0x001,
- 0x082, 0x004,
- 0x083, 0x000,
- 0x190, 0x018,
- 0x115, 0x000,
- 0x116, 0x012,
- 0x117, 0x018,
- 0x04a, 0x011,
- 0x08a, 0x011,
- 0x04b, 0x000,
- 0x08b, 0x000,
- 0x048, 0x000,
- 0x088, 0x000,
- 0x04e, 0x012,
- 0x08e, 0x012,
- 0x058, 0x012,
- 0x098, 0x012,
- 0x059, 0x000,
- 0x099, 0x000,
- 0x05a, 0x003,
- 0x09a, 0x003,
- 0x05b, 0x001,
- 0x09b, 0x001,
- 0x054, 0x008,
- 0x094, 0x008,
- 0x055, 0x000,
- 0x095, 0x000,
- 0x056, 0x0c7,
- 0x096, 0x0c7,
- 0x057, 0x002,
- 0x097, 0x002,
- 0x060, 0x001,
- 0x0a0, 0x001,
- 0x061, 0x000,
- 0x0a1, 0x000,
- 0x062, 0x000,
- 0x0a2, 0x000,
- 0x063, 0x000,
- 0x0a3, 0x000,
- 0x070, 0x000,
- 0x0b0, 0x000,
- 0x071, 0x004,
- 0x0b1, 0x004,
- 0x06c, 0x0e9,
- 0x0ac, 0x0e9,
- 0x06d, 0x003,
- 0x0ad, 0x003,
- 0x05c, 0x0d0,
- 0x09c, 0x0d0,
- 0x05d, 0x002,
- 0x09d, 0x002,
- 0x05e, 0x0f2,
- 0x09e, 0x0f2,
- 0x05f, 0x000,
- 0x09f, 0x000,
- 0x074, 0x000,
- 0x0b4, 0x000,
- 0x075, 0x000,
- 0x0b5, 0x000,
- 0x076, 0x000,
- 0x0b6, 0x000,
- 0x077, 0x000,
- 0x0b7, 0x000,
- 0x195, 0x008,
- 0x598, 0x0e7,
- 0x599, 0x07d,
- 0x59a, 0x018,
- 0x59c, 0x066,
- 0x59d, 0x090,
- 0x59e, 0x001,
- 0x584, 0x000,
- 0x585, 0x000,
- 0x586, 0x003,
- 0x588, 0x0ff,
- 0x589, 0x00f,
- 0x58a, 0x000,
- 0x58b, 0x000,
- 0x58c, 0x010,
- 0x58d, 0x032,
- 0x58e, 0x054,
- 0x58f, 0x023,
- 0x590, 0x000,
- 0x595, 0x000,
- 0x596, 0x000,
- 0x597, 0x000,
- 0x464, 0x000,
- 0x46c, 0xbbbb10,
- 0x470, 0x101010,
- 0x478, 0x000,
- 0x474, 0x018,
- 0x454, 0x042135,
- 0x193, 0x0a6,
- 0x108, 0x0f8,
- 0x042, 0x003,
- 0x082, 0x003,
- 0x454, 0x0425b9,
- 0x454, 0x042539,
- 0x193, 0x000,
- 0x193, 0x0a6,
- 0x464, 0x000,
-
- 0, 0
-};
-
-/* Tuner */
-static u32 reg_init_tuner_input[] = {
- 0x108, 0x0f8, /* Sync control */
- 0x111, 0x000, /* Mode/delay control */
- 0x10e, 0x00a, /* Chroma control 1 */
- 0, 0
-};
-
-/* Composite */
-static u32 reg_init_composite_input[] = {
- 0x108, 0x0e8, /* Sync control */
- 0x111, 0x000, /* Mode/delay control */
- 0x10e, 0x04a, /* Chroma control 1 */
- 0, 0
-};
-
-/* S-Video */
-static u32 reg_init_svideo_input[] = {
- 0x108, 0x0e8, /* Sync control */
- 0x111, 0x000, /* Mode/delay control */
- 0x10e, 0x04a, /* Chroma control 1 */
- 0, 0
-};
-
-static u32 reg_set_audio_template[4][2] =
-{
- { /* for MONO
- tadachi 6/29 DMA audio output select?
- Register 0x46c
- 7-4: DMA2, 3-0: DMA1 ch. DMA4, DMA3 DMA2, DMA1
- 0: MAIN left, 1: MAIN right
- 2: AUX1 left, 3: AUX1 right
- 4: AUX2 left, 5: AUX2 right
- 6: DPL left, 7: DPL right
- 8: DPL center, 9: DPL surround
- A: monitor output, B: digital sense */
- 0xbbbb00,
-
- /* tadachi 6/29 DAC and I2S output select?
- Register 0x470
- 7-4:DAC right ch. 3-0:DAC left ch.
- I2S1 right,left I2S2 right,left */
- 0x00,
- },
- { /* for STEREO */
- 0xbbbb10, 0x101010,
- },
- { /* for LANG1 */
- 0xbbbb00, 0x00,
- },
- { /* for LANG2/SAP */
- 0xbbbb11, 0x111111,
- }
-};
-
-
-/* Get detected audio flags (from saa7134 driver) */
-static void get_inf_dev_status(struct v4l2_subdev *sd,
- int *dual_flag, int *stereo_flag)
-{
- u32 reg_data3;
-
- static char *stdres[0x20] = {
- [0x00] = "no standard detected",
- [0x01] = "B/G (in progress)",
- [0x02] = "D/K (in progress)",
- [0x03] = "M (in progress)",
-
- [0x04] = "B/G A2",
- [0x05] = "B/G NICAM",
- [0x06] = "D/K A2 (1)",
- [0x07] = "D/K A2 (2)",
- [0x08] = "D/K A2 (3)",
- [0x09] = "D/K NICAM",
- [0x0a] = "L NICAM",
- [0x0b] = "I NICAM",
-
- [0x0c] = "M Korea",
- [0x0d] = "M BTSC ",
- [0x0e] = "M EIAJ",
-
- [0x0f] = "FM radio / IF 10.7 / 50 deemp",
- [0x10] = "FM radio / IF 10.7 / 75 deemp",
- [0x11] = "FM radio / IF sel / 50 deemp",
- [0x12] = "FM radio / IF sel / 75 deemp",
-
- [0x13 ... 0x1e] = "unknown",
- [0x1f] = "??? [in progress]",
- };
-
-
- *dual_flag = *stereo_flag = 0;
-
- /* (demdec status: 0x528) */
-
- /* read current status */
- reg_data3 = saa717x_read(sd, 0x0528);
-
- v4l2_dbg(1, debug, sd, "tvaudio thread status: 0x%x [%s%s%s]\n",
- reg_data3, stdres[reg_data3 & 0x1f],
- (reg_data3 & 0x000020) ? ",stereo" : "",
- (reg_data3 & 0x000040) ? ",dual" : "");
- v4l2_dbg(1, debug, sd, "detailed status: "
- "%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n",
- (reg_data3 & 0x000080) ? " A2/EIAJ pilot tone " : "",
- (reg_data3 & 0x000100) ? " A2/EIAJ dual " : "",
- (reg_data3 & 0x000200) ? " A2/EIAJ stereo " : "",
- (reg_data3 & 0x000400) ? " A2/EIAJ noise mute " : "",
-
- (reg_data3 & 0x000800) ? " BTSC/FM radio pilot " : "",
- (reg_data3 & 0x001000) ? " SAP carrier " : "",
- (reg_data3 & 0x002000) ? " BTSC stereo noise mute " : "",
- (reg_data3 & 0x004000) ? " SAP noise mute " : "",
- (reg_data3 & 0x008000) ? " VDSP " : "",
-
- (reg_data3 & 0x010000) ? " NICST " : "",
- (reg_data3 & 0x020000) ? " NICDU " : "",
- (reg_data3 & 0x040000) ? " NICAM muted " : "",
- (reg_data3 & 0x080000) ? " NICAM reserve sound " : "",
-
- (reg_data3 & 0x100000) ? " init done " : "");
-
- if (reg_data3 & 0x000220) {
- v4l2_dbg(1, debug, sd, "ST!!!\n");
- *stereo_flag = 1;
- }
-
- if (reg_data3 & 0x000140) {
- v4l2_dbg(1, debug, sd, "DUAL!!!\n");
- *dual_flag = 1;
- }
-}
-
-/* regs write to set audio mode */
-static void set_audio_mode(struct v4l2_subdev *sd, int audio_mode)
-{
- v4l2_dbg(1, debug, sd, "writing registers to set audio mode by set %d\n",
- audio_mode);
-
- saa717x_write(sd, 0x46c, reg_set_audio_template[audio_mode][0]);
- saa717x_write(sd, 0x470, reg_set_audio_template[audio_mode][1]);
-}
-
-/* write regs to set audio volume, bass and treble */
-static int set_audio_regs(struct v4l2_subdev *sd,
- struct saa717x_state *decoder)
-{
- u8 mute = 0xac; /* -84 dB */
- u32 val;
- unsigned int work_l, work_r;
-
- /* set SIF analog I/O select */
- saa717x_write(sd, 0x0594, decoder->audio_input);
- v4l2_dbg(1, debug, sd, "set audio input %d\n",
- decoder->audio_input);
-
- /* normalize ( 65535 to 0 -> 24 to -40 (not -84)) */
- work_l = (min(65536 - decoder->audio_main_balance, 32768) * decoder->audio_main_volume) / 32768;
- work_r = (min(decoder->audio_main_balance, (u16)32768) * decoder->audio_main_volume) / 32768;
- decoder->audio_main_vol_l = (long)work_l * (24 - (-40)) / 65535 - 40;
- decoder->audio_main_vol_r = (long)work_r * (24 - (-40)) / 65535 - 40;
-
- /* set main volume */
- /* main volume L[7-0],R[7-0],0x00 24=24dB,-83dB, -84(mute) */
- /* def:0dB->6dB(MPG600GR) */
- /* if mute is on, set mute */
- if (decoder->audio_main_mute) {
- val = mute | (mute << 8);
- } else {
- val = (u8)decoder->audio_main_vol_l |
- ((u8)decoder->audio_main_vol_r << 8);
- }
-
- saa717x_write(sd, 0x480, val);
-
- /* set bass and treble */
- val = decoder->audio_main_bass & 0x1f;
- val |= (decoder->audio_main_treble & 0x1f) << 5;
- saa717x_write(sd, 0x488, val);
- return 0;
-}
-
-/********** scaling staff ***********/
-static void set_h_prescale(struct v4l2_subdev *sd,
- int task, int prescale)
-{
- static const struct {
- int xpsc;
- int xacl;
- int xc2_1;
- int xdcg;
- int vpfy;
- } vals[] = {
- /* XPSC XACL XC2_1 XDCG VPFY */
- { 1, 0, 0, 0, 0 },
- { 2, 2, 1, 2, 2 },
- { 3, 4, 1, 3, 2 },
- { 4, 8, 1, 4, 2 },
- { 5, 8, 1, 4, 2 },
- { 6, 8, 1, 4, 3 },
- { 7, 8, 1, 4, 3 },
- { 8, 15, 0, 4, 3 },
- { 9, 15, 0, 4, 3 },
- { 10, 16, 1, 5, 3 },
- };
- static const int count = ARRAY_SIZE(vals);
- int i, task_shift;
-
- task_shift = task * 0x40;
- for (i = 0; i < count; i++)
- if (vals[i].xpsc == prescale)
- break;
- if (i == count)
- return;
-
- /* horizonal prescaling */
- saa717x_write(sd, 0x60 + task_shift, vals[i].xpsc);
- /* accumulation length */
- saa717x_write(sd, 0x61 + task_shift, vals[i].xacl);
- /* level control */
- saa717x_write(sd, 0x62 + task_shift,
- (vals[i].xc2_1 << 3) | vals[i].xdcg);
- /*FIR prefilter control */
- saa717x_write(sd, 0x63 + task_shift,
- (vals[i].vpfy << 2) | vals[i].vpfy);
-}
-
-/********** scaling staff ***********/
-static void set_v_scale(struct v4l2_subdev *sd, int task, int yscale)
-{
- int task_shift;
-
- task_shift = task * 0x40;
- /* Vertical scaling ratio (LOW) */
- saa717x_write(sd, 0x70 + task_shift, yscale & 0xff);
- /* Vertical scaling ratio (HI) */
- saa717x_write(sd, 0x71 + task_shift, yscale >> 8);
-}
-
-static int saa717x_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct saa717x_state *state = to_state(sd);
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- saa717x_write(sd, 0x10a, ctrl->val);
- return 0;
-
- case V4L2_CID_CONTRAST:
- saa717x_write(sd, 0x10b, ctrl->val);
- return 0;
-
- case V4L2_CID_SATURATION:
- saa717x_write(sd, 0x10c, ctrl->val);
- return 0;
-
- case V4L2_CID_HUE:
- saa717x_write(sd, 0x10d, ctrl->val);
- return 0;
-
- case V4L2_CID_AUDIO_MUTE:
- state->audio_main_mute = ctrl->val;
- break;
-
- case V4L2_CID_AUDIO_VOLUME:
- state->audio_main_volume = ctrl->val;
- break;
-
- case V4L2_CID_AUDIO_BALANCE:
- state->audio_main_balance = ctrl->val;
- break;
-
- case V4L2_CID_AUDIO_TREBLE:
- state->audio_main_treble = ctrl->val;
- break;
-
- case V4L2_CID_AUDIO_BASS:
- state->audio_main_bass = ctrl->val;
- break;
-
- default:
- return 0;
- }
- set_audio_regs(sd, state);
- return 0;
-}
-
-static int saa717x_s_video_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct saa717x_state *decoder = to_state(sd);
- int is_tuner = input & 0x80; /* tuner input flag */
-
- input &= 0x7f;
-
- v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input);
- /* inputs from 0-9 are available*/
- /* saa717x have mode0-mode9 but mode5 is reserved. */
- if (input > 9 || input == 5)
- return -EINVAL;
-
- if (decoder->input != input) {
- int input_line = input;
-
- decoder->input = input_line;
- v4l2_dbg(1, debug, sd, "now setting %s input %d\n",
- input_line >= 6 ? "S-Video" : "Composite",
- input_line);
-
- /* select mode */
- saa717x_write(sd, 0x102,
- (saa717x_read(sd, 0x102) & 0xf0) |
- input_line);
-
- /* bypass chrominance trap for modes 6..9 */
- saa717x_write(sd, 0x109,
- (saa717x_read(sd, 0x109) & 0x7f) |
- (input_line < 6 ? 0x0 : 0x80));
-
- /* change audio_mode */
- if (is_tuner) {
- /* tuner */
- set_audio_mode(sd, decoder->tuner_audio_mode);
- } else {
- /* Force to STEREO mode if Composite or
- * S-Video were chosen */
- set_audio_mode(sd, TUNER_AUDIO_STEREO);
- }
- /* change initialize procedure (Composite/S-Video) */
- if (is_tuner)
- saa717x_write_regs(sd, reg_init_tuner_input);
- else if (input_line >= 6)
- saa717x_write_regs(sd, reg_init_svideo_input);
- else
- saa717x_write_regs(sd, reg_init_composite_input);
- }
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- reg->val = saa717x_read(sd, reg->reg);
- reg->size = 1;
- return 0;
-}
-
-static int saa717x_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u16 addr = reg->reg & 0xffff;
- u8 val = reg->val & 0xff;
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- saa717x_write(sd, addr, val);
- return 0;
-}
-#endif
-
-static int saa717x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
-{
- int prescale, h_scale, v_scale;
-
- v4l2_dbg(1, debug, sd, "decoder set size\n");
-
- if (fmt->code != V4L2_MBUS_FMT_FIXED)
- return -EINVAL;
-
- /* FIXME need better bounds checking here */
- if (fmt->width < 1 || fmt->width > 1440)
- return -EINVAL;
- if (fmt->height < 1 || fmt->height > 960)
- return -EINVAL;
-
- fmt->field = V4L2_FIELD_INTERLACED;
- fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
-
- /* scaling setting */
- /* NTSC and interlace only */
- prescale = SAA717X_NTSC_WIDTH / fmt->width;
- if (prescale == 0)
- prescale = 1;
- h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / fmt->width;
- /* interlace */
- v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / fmt->height;
-
- /* Horizontal prescaling etc */
- set_h_prescale(sd, 0, prescale);
- set_h_prescale(sd, 1, prescale);
-
- /* Horizontal scaling increment */
- /* TASK A */
- saa717x_write(sd, 0x6C, (u8)(h_scale & 0xFF));
- saa717x_write(sd, 0x6D, (u8)((h_scale >> 8) & 0xFF));
- /* TASK B */
- saa717x_write(sd, 0xAC, (u8)(h_scale & 0xFF));
- saa717x_write(sd, 0xAD, (u8)((h_scale >> 8) & 0xFF));
-
- /* Vertical prescaling etc */
- set_v_scale(sd, 0, v_scale);
- set_v_scale(sd, 1, v_scale);
-
- /* set video output size */
- /* video number of pixels at output */
- /* TASK A */
- saa717x_write(sd, 0x5C, (u8)(fmt->width & 0xFF));
- saa717x_write(sd, 0x5D, (u8)((fmt->width >> 8) & 0xFF));
- /* TASK B */
- saa717x_write(sd, 0x9C, (u8)(fmt->width & 0xFF));
- saa717x_write(sd, 0x9D, (u8)((fmt->width >> 8) & 0xFF));
-
- /* video number of lines at output */
- /* TASK A */
- saa717x_write(sd, 0x5E, (u8)(fmt->height & 0xFF));
- saa717x_write(sd, 0x5F, (u8)((fmt->height >> 8) & 0xFF));
- /* TASK B */
- saa717x_write(sd, 0x9E, (u8)(fmt->height & 0xFF));
- saa717x_write(sd, 0x9F, (u8)((fmt->height >> 8) & 0xFF));
- return 0;
-}
-
-static int saa717x_s_radio(struct v4l2_subdev *sd)
-{
- struct saa717x_state *decoder = to_state(sd);
-
- decoder->radio = 1;
- return 0;
-}
-
-static int saa717x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct saa717x_state *decoder = to_state(sd);
-
- v4l2_dbg(1, debug, sd, "decoder set norm ");
- v4l2_dbg(1, debug, sd, "(not yet implementd)\n");
-
- decoder->radio = 0;
- decoder->std = std;
- return 0;
-}
-
-static int saa717x_s_audio_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct saa717x_state *decoder = to_state(sd);
-
- if (input < 3) { /* FIXME! --tadachi */
- decoder->audio_input = input;
- v4l2_dbg(1, debug, sd,
- "set decoder audio input to %d\n",
- decoder->audio_input);
- set_audio_regs(sd, decoder);
- return 0;
- }
- return -ERANGE;
-}
-
-static int saa717x_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct saa717x_state *decoder = to_state(sd);
-
- v4l2_dbg(1, debug, sd, "decoder %s output\n",
- enable ? "enable" : "disable");
- decoder->enable = enable;
- saa717x_write(sd, 0x193, enable ? 0xa6 : 0x26);
- return 0;
-}
-
-/* change audio mode */
-static int saa717x_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct saa717x_state *decoder = to_state(sd);
- int audio_mode;
- char *mes[4] = {
- "MONO", "STEREO", "LANG1", "LANG2/SAP"
- };
-
- audio_mode = TUNER_AUDIO_STEREO;
-
- switch (vt->audmode) {
- case V4L2_TUNER_MODE_MONO:
- audio_mode = TUNER_AUDIO_MONO;
- break;
- case V4L2_TUNER_MODE_STEREO:
- audio_mode = TUNER_AUDIO_STEREO;
- break;
- case V4L2_TUNER_MODE_LANG2:
- audio_mode = TUNER_AUDIO_LANG2;
- break;
- case V4L2_TUNER_MODE_LANG1:
- audio_mode = TUNER_AUDIO_LANG1;
- break;
- }
-
- v4l2_dbg(1, debug, sd, "change audio mode to %s\n",
- mes[audio_mode]);
- decoder->tuner_audio_mode = audio_mode;
- /* The registers are not changed here. */
- /* See DECODER_ENABLE_OUTPUT section. */
- set_audio_mode(sd, decoder->tuner_audio_mode);
- return 0;
-}
-
-static int saa717x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct saa717x_state *decoder = to_state(sd);
- int dual_f, stereo_f;
-
- if (decoder->radio)
- return 0;
- get_inf_dev_status(sd, &dual_f, &stereo_f);
-
- v4l2_dbg(1, debug, sd, "DETECT==st:%d dual:%d\n",
- stereo_f, dual_f);
-
- /* mono */
- if ((dual_f == 0) && (stereo_f == 0)) {
- vt->rxsubchans = V4L2_TUNER_SUB_MONO;
- v4l2_dbg(1, debug, sd, "DETECT==MONO\n");
- }
-
- /* stereo */
- if (stereo_f == 1) {
- if (vt->audmode == V4L2_TUNER_MODE_STEREO ||
- vt->audmode == V4L2_TUNER_MODE_LANG1) {
- vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
- v4l2_dbg(1, debug, sd, "DETECT==ST(ST)\n");
- } else {
- vt->rxsubchans = V4L2_TUNER_SUB_MONO;
- v4l2_dbg(1, debug, sd, "DETECT==ST(MONO)\n");
- }
- }
-
- /* dual */
- if (dual_f == 1) {
- if (vt->audmode == V4L2_TUNER_MODE_LANG2) {
- vt->rxsubchans = V4L2_TUNER_SUB_LANG2 | V4L2_TUNER_SUB_MONO;
- v4l2_dbg(1, debug, sd, "DETECT==DUAL1\n");
- } else {
- vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_MONO;
- v4l2_dbg(1, debug, sd, "DETECT==DUAL2\n");
- }
- }
- return 0;
-}
-
-static int saa717x_log_status(struct v4l2_subdev *sd)
-{
- struct saa717x_state *state = to_state(sd);
-
- v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_ctrl_ops saa717x_ctrl_ops = {
- .s_ctrl = saa717x_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops saa717x_core_ops = {
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = saa717x_g_register,
- .s_register = saa717x_s_register,
-#endif
- .s_std = saa717x_s_std,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
- .log_status = saa717x_log_status,
-};
-
-static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = {
- .g_tuner = saa717x_g_tuner,
- .s_tuner = saa717x_s_tuner,
- .s_radio = saa717x_s_radio,
-};
-
-static const struct v4l2_subdev_video_ops saa717x_video_ops = {
- .s_routing = saa717x_s_video_routing,
- .s_mbus_fmt = saa717x_s_mbus_fmt,
- .s_stream = saa717x_s_stream,
-};
-
-static const struct v4l2_subdev_audio_ops saa717x_audio_ops = {
- .s_routing = saa717x_s_audio_routing,
-};
-
-static const struct v4l2_subdev_ops saa717x_ops = {
- .core = &saa717x_core_ops,
- .tuner = &saa717x_tuner_ops,
- .audio = &saa717x_audio_ops,
- .video = &saa717x_video_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-
-/* i2c implementation */
-
-/* ----------------------------------------------------------------------- */
-static int saa717x_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct saa717x_state *decoder;
- struct v4l2_ctrl_handler *hdl;
- struct v4l2_subdev *sd;
- u8 id = 0;
- char *p = "";
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- decoder = kzalloc(sizeof(struct saa717x_state), GFP_KERNEL);
- if (decoder == NULL)
- return -ENOMEM;
-
- sd = &decoder->sd;
- v4l2_i2c_subdev_init(sd, client, &saa717x_ops);
-
- if (saa717x_write(sd, 0x5a4, 0xfe) &&
- saa717x_write(sd, 0x5a5, 0x0f) &&
- saa717x_write(sd, 0x5a6, 0x00) &&
- saa717x_write(sd, 0x5a7, 0x01))
- id = saa717x_read(sd, 0x5a0);
- if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) {
- v4l2_dbg(1, debug, sd, "saa717x not found (id=%02x)\n", id);
- kfree(decoder);
- return -ENODEV;
- }
- if (id == 0xc2)
- p = "saa7173";
- else if (id == 0x32)
- p = "saa7174A";
- else if (id == 0x6c)
- p = "saa7174HL";
- else
- p = "saa7171";
- v4l2_info(sd, "%s found @ 0x%x (%s)\n", p,
- client->addr << 1, client->adapter->name);
-
- hdl = &decoder->hdl;
- v4l2_ctrl_handler_init(hdl, 9);
- /* add in ascending ID order */
- v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 68);
- v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, 64);
- v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
- V4L2_CID_HUE, -128, 127, 1, 0);
- v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
- V4L2_CID_AUDIO_VOLUME, 0, 65535, 65535 / 100, 42000);
- v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
- V4L2_CID_AUDIO_BALANCE, 0, 65535, 65535 / 100, 32768);
- v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
- V4L2_CID_AUDIO_BASS, -16, 15, 1, 0);
- v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
- V4L2_CID_AUDIO_TREBLE, -16, 15, 1, 0);
- v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
- V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
- sd->ctrl_handler = hdl;
- if (hdl->error) {
- int err = hdl->error;
-
- v4l2_ctrl_handler_free(hdl);
- kfree(decoder);
- return err;
- }
-
- decoder->std = V4L2_STD_NTSC;
- decoder->input = -1;
- decoder->enable = 1;
-
- /* FIXME!! */
- decoder->playback = 0; /* initially capture mode used */
- decoder->audio = 1; /* DECODER_AUDIO_48_KHZ */
-
- decoder->audio_input = 2; /* FIXME!! */
-
- decoder->tuner_audio_mode = TUNER_AUDIO_STEREO;
- /* set volume, bass and treble */
- decoder->audio_main_vol_l = 6;
- decoder->audio_main_vol_r = 6;
-
- v4l2_dbg(1, debug, sd, "writing init values\n");
-
- /* FIXME!! */
- saa717x_write_regs(sd, reg_init_initialize);
-
- v4l2_ctrl_handler_setup(hdl);
-
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(2*HZ);
- return 0;
-}
-
-static int saa717x_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(sd->ctrl_handler);
- kfree(to_state(sd));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id saa717x_id[] = {
- { "saa717x", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, saa717x_id);
-
-static struct i2c_driver saa717x_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "saa717x",
- },
- .probe = saa717x_probe,
- .remove = saa717x_remove,
- .id_table = saa717x_id,
-};
-
-module_i2c_driver(saa717x_driver);
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
deleted file mode 100644
index 2c6b65c76e2..00000000000
--- a/drivers/media/video/saa7185.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * saa7185 - Philips SAA7185B video encoder driver version 0.0.3
- *
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- *
- * Slight changes for video timing and attachment output by
- * Wolfgang Scherr <scherr@net4you.net>
- *
- * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
- * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-
-MODULE_DESCRIPTION("Philips SAA7185 video encoder driver");
-MODULE_AUTHOR("Dave Perks");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-
-/* ----------------------------------------------------------------------- */
-
-struct saa7185 {
- struct v4l2_subdev sd;
- unsigned char reg[128];
-
- v4l2_std_id norm;
-};
-
-static inline struct saa7185 *to_saa7185(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct saa7185, sd);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static inline int saa7185_read(struct v4l2_subdev *sd)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_read_byte(client);
-}
-
-static int saa7185_write(struct v4l2_subdev *sd, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct saa7185 *encoder = to_saa7185(sd);
-
- v4l2_dbg(1, debug, sd, "%02x set to %02x\n", reg, value);
- encoder->reg[reg] = value;
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static int saa7185_write_block(struct v4l2_subdev *sd,
- const u8 *data, unsigned int len)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct saa7185 *encoder = to_saa7185(sd);
- int ret = -1;
- u8 reg;
-
- /* the adv7175 has an autoincrement function, use it if
- * the adapter understands raw I2C */
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- /* do raw I2C, not smbus compatible */
- u8 block_data[32];
- int block_len;
-
- while (len >= 2) {
- block_len = 0;
- block_data[block_len++] = reg = data[0];
- do {
- block_data[block_len++] =
- encoder->reg[reg++] = data[1];
- len -= 2;
- data += 2;
- } while (len >= 2 && data[0] == reg && block_len < 32);
- ret = i2c_master_send(client, block_data, block_len);
- if (ret < 0)
- break;
- }
- } else {
- /* do some slow I2C emulation kind of thing */
- while (len >= 2) {
- reg = *data++;
- ret = saa7185_write(sd, reg, *data++);
- if (ret < 0)
- break;
- len -= 2;
- }
- }
-
- return ret;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const unsigned char init_common[] = {
- 0x3a, 0x0f, /* CBENB=0, V656=0, VY2C=1,
- * YUV2C=1, MY2C=1, MUV2C=1 */
-
- 0x42, 0x6b, /* OVLY0=107 */
- 0x43, 0x00, /* OVLU0=0 white */
- 0x44, 0x00, /* OVLV0=0 */
- 0x45, 0x22, /* OVLY1=34 */
- 0x46, 0xac, /* OVLU1=172 yellow */
- 0x47, 0x0e, /* OVLV1=14 */
- 0x48, 0x03, /* OVLY2=3 */
- 0x49, 0x1d, /* OVLU2=29 cyan */
- 0x4a, 0xac, /* OVLV2=172 */
- 0x4b, 0xf0, /* OVLY3=240 */
- 0x4c, 0xc8, /* OVLU3=200 green */
- 0x4d, 0xb9, /* OVLV3=185 */
- 0x4e, 0xd4, /* OVLY4=212 */
- 0x4f, 0x38, /* OVLU4=56 magenta */
- 0x50, 0x47, /* OVLV4=71 */
- 0x51, 0xc1, /* OVLY5=193 */
- 0x52, 0xe3, /* OVLU5=227 red */
- 0x53, 0x54, /* OVLV5=84 */
- 0x54, 0xa3, /* OVLY6=163 */
- 0x55, 0x54, /* OVLU6=84 blue */
- 0x56, 0xf2, /* OVLV6=242 */
- 0x57, 0x90, /* OVLY7=144 */
- 0x58, 0x00, /* OVLU7=0 black */
- 0x59, 0x00, /* OVLV7=0 */
-
- 0x5a, 0x00, /* CHPS=0 */
- 0x5b, 0x76, /* GAINU=118 */
- 0x5c, 0xa5, /* GAINV=165 */
- 0x5d, 0x3c, /* BLCKL=60 */
- 0x5e, 0x3a, /* BLNNL=58 */
- 0x5f, 0x3a, /* CCRS=0, BLNVB=58 */
- 0x60, 0x00, /* NULL */
-
- /* 0x61 - 0x66 set according to norm */
-
- 0x67, 0x00, /* 0 : caption 1st byte odd field */
- 0x68, 0x00, /* 0 : caption 2nd byte odd field */
- 0x69, 0x00, /* 0 : caption 1st byte even field */
- 0x6a, 0x00, /* 0 : caption 2nd byte even field */
-
- 0x6b, 0x91, /* MODIN=2, PCREF=0, SCCLN=17 */
- 0x6c, 0x20, /* SRCV1=0, TRCV2=1, ORCV1=0, PRCV1=0,
- * CBLF=0, ORCV2=0, PRCV2=0 */
- 0x6d, 0x00, /* SRCM1=0, CCEN=0 */
-
- 0x6e, 0x0e, /* HTRIG=0x005, approx. centered, at
- * least for PAL */
- 0x6f, 0x00, /* HTRIG upper bits */
- 0x70, 0x20, /* PHRES=0, SBLN=1, VTRIG=0 */
-
- /* The following should not be needed */
-
- 0x71, 0x15, /* BMRQ=0x115 */
- 0x72, 0x90, /* EMRQ=0x690 */
- 0x73, 0x61, /* EMRQ=0x690, BMRQ=0x115 */
- 0x74, 0x00, /* NULL */
- 0x75, 0x00, /* NULL */
- 0x76, 0x00, /* NULL */
- 0x77, 0x15, /* BRCV=0x115 */
- 0x78, 0x90, /* ERCV=0x690 */
- 0x79, 0x61, /* ERCV=0x690, BRCV=0x115 */
-
- /* Field length controls */
-
- 0x7a, 0x70, /* FLC=0 */
-
- /* The following should not be needed if SBLN = 1 */
-
- 0x7b, 0x16, /* FAL=22 */
- 0x7c, 0x35, /* LAL=244 */
- 0x7d, 0x20, /* LAL=244, FAL=22 */
-};
-
-static const unsigned char init_pal[] = {
- 0x61, 0x1e, /* FISE=0, PAL=1, SCBW=1, RTCE=1,
- * YGS=1, INPI=0, DOWN=0 */
- 0x62, 0xc8, /* DECTYP=1, BSTA=72 */
- 0x63, 0xcb, /* FSC0 */
- 0x64, 0x8a, /* FSC1 */
- 0x65, 0x09, /* FSC2 */
- 0x66, 0x2a, /* FSC3 */
-};
-
-static const unsigned char init_ntsc[] = {
- 0x61, 0x1d, /* FISE=1, PAL=0, SCBW=1, RTCE=1,
- * YGS=1, INPI=0, DOWN=0 */
- 0x62, 0xe6, /* DECTYP=1, BSTA=102 */
- 0x63, 0x1f, /* FSC0 */
- 0x64, 0x7c, /* FSC1 */
- 0x65, 0xf0, /* FSC2 */
- 0x66, 0x21, /* FSC3 */
-};
-
-
-static int saa7185_init(struct v4l2_subdev *sd, u32 val)
-{
- struct saa7185 *encoder = to_saa7185(sd);
-
- saa7185_write_block(sd, init_common, sizeof(init_common));
- if (encoder->norm & V4L2_STD_NTSC)
- saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
- else
- saa7185_write_block(sd, init_pal, sizeof(init_pal));
- return 0;
-}
-
-static int saa7185_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct saa7185 *encoder = to_saa7185(sd);
-
- if (std & V4L2_STD_NTSC)
- saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
- else if (std & V4L2_STD_PAL)
- saa7185_write_block(sd, init_pal, sizeof(init_pal));
- else
- return -EINVAL;
- encoder->norm = std;
- return 0;
-}
-
-static int saa7185_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct saa7185 *encoder = to_saa7185(sd);
-
- /* RJ: input = 0: input is from SA7111
- input = 1: input is from ZR36060 */
-
- switch (input) {
- case 0:
- /* turn off colorbar */
- saa7185_write(sd, 0x3a, 0x0f);
- /* Switch RTCE to 1 */
- saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08);
- saa7185_write(sd, 0x6e, 0x01);
- break;
-
- case 1:
- /* turn off colorbar */
- saa7185_write(sd, 0x3a, 0x0f);
- /* Switch RTCE to 0 */
- saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x00);
- /* SW: a slight sync problem... */
- saa7185_write(sd, 0x6e, 0x00);
- break;
-
- case 2:
- /* turn on colorbar */
- saa7185_write(sd, 0x3a, 0x8f);
- /* Switch RTCE to 0 */
- saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08);
- /* SW: a slight sync problem... */
- saa7185_write(sd, 0x6e, 0x01);
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int saa7185_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7185, 0);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops saa7185_core_ops = {
- .g_chip_ident = saa7185_g_chip_ident,
- .init = saa7185_init,
-};
-
-static const struct v4l2_subdev_video_ops saa7185_video_ops = {
- .s_std_output = saa7185_s_std_output,
- .s_routing = saa7185_s_routing,
-};
-
-static const struct v4l2_subdev_ops saa7185_ops = {
- .core = &saa7185_core_ops,
- .video = &saa7185_video_ops,
-};
-
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7185_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int i;
- struct saa7185 *encoder;
- struct v4l2_subdev *sd;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL);
- if (encoder == NULL)
- return -ENOMEM;
- encoder->norm = V4L2_STD_NTSC;
- sd = &encoder->sd;
- v4l2_i2c_subdev_init(sd, client, &saa7185_ops);
-
- i = saa7185_write_block(sd, init_common, sizeof(init_common));
- if (i >= 0)
- i = saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
- if (i < 0)
- v4l2_dbg(1, debug, sd, "init error %d\n", i);
- else
- v4l2_dbg(1, debug, sd, "revision 0x%x\n",
- saa7185_read(sd) >> 5);
- return 0;
-}
-
-static int saa7185_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct saa7185 *encoder = to_saa7185(sd);
-
- v4l2_device_unregister_subdev(sd);
- /* SW: output off is active */
- saa7185_write(sd, 0x61, (encoder->reg[0x61]) | 0x40);
- kfree(encoder);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id saa7185_id[] = {
- { "saa7185", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, saa7185_id);
-
-static struct i2c_driver saa7185_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "saa7185",
- },
- .probe = saa7185_probe,
- .remove = saa7185_remove,
- .id_table = saa7185_id,
-};
-
-module_i2c_driver(saa7185_driver);
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c
deleted file mode 100644
index d7d1670e0ca..00000000000
--- a/drivers/media/video/saa7191.c
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- * saa7191.c - Philips SAA7191 video decoder driver
- *
- * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
- * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-
-#include <linux/videodev2.h>
-#include <linux/i2c.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-
-#include "saa7191.h"
-
-#define SAA7191_MODULE_VERSION "0.0.5"
-
-MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
-MODULE_VERSION(SAA7191_MODULE_VERSION);
-MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
-MODULE_LICENSE("GPL");
-
-
-// #define SAA7191_DEBUG
-
-#ifdef SAA7191_DEBUG
-#define dprintk(x...) printk("SAA7191: " x);
-#else
-#define dprintk(x...)
-#endif
-
-#define SAA7191_SYNC_COUNT 30
-#define SAA7191_SYNC_DELAY 100 /* milliseconds */
-
-struct saa7191 {
- struct v4l2_subdev sd;
-
- /* the register values are stored here as the actual
- * I2C-registers are write-only */
- u8 reg[25];
-
- int input;
- v4l2_std_id norm;
-};
-
-static inline struct saa7191 *to_saa7191(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct saa7191, sd);
-}
-
-static const u8 initseq[] = {
- 0, /* Subaddress */
-
- 0x50, /* (0x50) SAA7191_REG_IDEL */
-
- /* 50 Hz signal timing */
- 0x30, /* (0x30) SAA7191_REG_HSYB */
- 0x00, /* (0x00) SAA7191_REG_HSYS */
- 0xe8, /* (0xe8) SAA7191_REG_HCLB */
- 0xb6, /* (0xb6) SAA7191_REG_HCLS */
- 0xf4, /* (0xf4) SAA7191_REG_HPHI */
-
- /* control */
- SAA7191_LUMA_APER_1, /* (0x01) SAA7191_REG_LUMA - CVBS mode */
- 0x00, /* (0x00) SAA7191_REG_HUEC */
- 0xf8, /* (0xf8) SAA7191_REG_CKTQ */
- 0xf8, /* (0xf8) SAA7191_REG_CKTS */
- 0x90, /* (0x90) SAA7191_REG_PLSE */
- 0x90, /* (0x90) SAA7191_REG_SESE */
- 0x00, /* (0x00) SAA7191_REG_GAIN */
- SAA7191_STDC_NFEN | SAA7191_STDC_HRMV, /* (0x0c) SAA7191_REG_STDC
- * - not SECAM,
- * slow time constant */
- SAA7191_IOCK_OEDC | SAA7191_IOCK_OEHS | SAA7191_IOCK_OEVS
- | SAA7191_IOCK_OEDY, /* (0x78) SAA7191_REG_IOCK
- * - chroma from CVBS, GPSW1 & 2 off */
- SAA7191_CTL3_AUFD | SAA7191_CTL3_SCEN | SAA7191_CTL3_OFTS
- | SAA7191_CTL3_YDEL0, /* (0x99) SAA7191_REG_CTL3
- * - automatic field detection */
- 0x00, /* (0x00) SAA7191_REG_CTL4 */
- 0x2c, /* (0x2c) SAA7191_REG_CHCV - PAL nominal value */
- 0x00, /* unused */
- 0x00, /* unused */
-
- /* 60 Hz signal timing */
- 0x34, /* (0x34) SAA7191_REG_HS6B */
- 0x0a, /* (0x0a) SAA7191_REG_HS6S */
- 0xf4, /* (0xf4) SAA7191_REG_HC6B */
- 0xce, /* (0xce) SAA7191_REG_HC6S */
- 0xf4, /* (0xf4) SAA7191_REG_HP6I */
-};
-
-/* SAA7191 register handling */
-
-static u8 saa7191_read_reg(struct v4l2_subdev *sd, u8 reg)
-{
- return to_saa7191(sd)->reg[reg];
-}
-
-static int saa7191_read_status(struct v4l2_subdev *sd, u8 *value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
-
- ret = i2c_master_recv(client, value, 1);
- if (ret < 0) {
- printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed\n");
- return ret;
- }
-
- return 0;
-}
-
-
-static int saa7191_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- to_saa7191(sd)->reg[reg] = value;
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-/* the first byte of data must be the first subaddress number (register) */
-static int saa7191_write_block(struct v4l2_subdev *sd,
- u8 length, const u8 *data)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct saa7191 *decoder = to_saa7191(sd);
- int i;
- int ret;
-
- for (i = 0; i < (length - 1); i++) {
- decoder->reg[data[0] + i] = data[i + 1];
- }
-
- ret = i2c_master_send(client, data, length);
- if (ret < 0) {
- printk(KERN_ERR "SAA7191: saa7191_write_block(): "
- "write failed\n");
- return ret;
- }
-
- return 0;
-}
-
-/* Helper functions */
-
-static int saa7191_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct saa7191 *decoder = to_saa7191(sd);
- u8 luma = saa7191_read_reg(sd, SAA7191_REG_LUMA);
- u8 iock = saa7191_read_reg(sd, SAA7191_REG_IOCK);
- int err;
-
- switch (input) {
- case SAA7191_INPUT_COMPOSITE: /* Set Composite input */
- iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1
- | SAA7191_IOCK_GPSW2);
- /* Chrominance trap active */
- luma &= ~SAA7191_LUMA_BYPS;
- break;
- case SAA7191_INPUT_SVIDEO: /* Set S-Video input */
- iock |= SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW2;
- /* Chrominance trap bypassed */
- luma |= SAA7191_LUMA_BYPS;
- break;
- default:
- return -EINVAL;
- }
-
- err = saa7191_write_reg(sd, SAA7191_REG_LUMA, luma);
- if (err)
- return -EIO;
- err = saa7191_write_reg(sd, SAA7191_REG_IOCK, iock);
- if (err)
- return -EIO;
-
- decoder->input = input;
-
- return 0;
-}
-
-static int saa7191_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
- struct saa7191 *decoder = to_saa7191(sd);
- u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC);
- u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3);
- u8 chcv = saa7191_read_reg(sd, SAA7191_REG_CHCV);
- int err;
-
- if (norm & V4L2_STD_PAL) {
- stdc &= ~SAA7191_STDC_SECS;
- ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
- chcv = SAA7191_CHCV_PAL;
- } else if (norm & V4L2_STD_NTSC) {
- stdc &= ~SAA7191_STDC_SECS;
- ctl3 &= ~SAA7191_CTL3_AUFD;
- ctl3 |= SAA7191_CTL3_FSEL;
- chcv = SAA7191_CHCV_NTSC;
- } else if (norm & V4L2_STD_SECAM) {
- stdc |= SAA7191_STDC_SECS;
- ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
- chcv = SAA7191_CHCV_PAL;
- } else {
- return -EINVAL;
- }
-
- err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
- if (err)
- return -EIO;
- err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc);
- if (err)
- return -EIO;
- err = saa7191_write_reg(sd, SAA7191_REG_CHCV, chcv);
- if (err)
- return -EIO;
-
- decoder->norm = norm;
-
- dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
- stdc, chcv);
- dprintk("norm: %llx\n", norm);
-
- return 0;
-}
-
-static int saa7191_wait_for_signal(struct v4l2_subdev *sd, u8 *status)
-{
- int i = 0;
-
- dprintk("Checking for signal...\n");
-
- for (i = 0; i < SAA7191_SYNC_COUNT; i++) {
- if (saa7191_read_status(sd, status))
- return -EIO;
-
- if (((*status) & SAA7191_STATUS_HLCK) == 0) {
- dprintk("Signal found\n");
- return 0;
- }
-
- msleep(SAA7191_SYNC_DELAY);
- }
-
- dprintk("No signal\n");
-
- return -EBUSY;
-}
-
-static int saa7191_querystd(struct v4l2_subdev *sd, v4l2_std_id *norm)
-{
- struct saa7191 *decoder = to_saa7191(sd);
- u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC);
- u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3);
- u8 status;
- v4l2_std_id old_norm = decoder->norm;
- int err = 0;
-
- dprintk("SAA7191 extended signal auto-detection...\n");
-
- *norm = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
- stdc &= ~SAA7191_STDC_SECS;
- ctl3 &= ~(SAA7191_CTL3_FSEL);
-
- err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc);
- if (err) {
- err = -EIO;
- goto out;
- }
- err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
- if (err) {
- err = -EIO;
- goto out;
- }
-
- ctl3 |= SAA7191_CTL3_AUFD;
- err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
- if (err) {
- err = -EIO;
- goto out;
- }
-
- msleep(SAA7191_SYNC_DELAY);
-
- err = saa7191_wait_for_signal(sd, &status);
- if (err)
- goto out;
-
- if (status & SAA7191_STATUS_FIDT) {
- /* 60Hz signal -> NTSC */
- dprintk("60Hz signal: NTSC\n");
- *norm = V4L2_STD_NTSC;
- return 0;
- }
-
- /* 50Hz signal */
- dprintk("50Hz signal: Trying PAL...\n");
-
- /* try PAL first */
- err = saa7191_s_std(sd, V4L2_STD_PAL);
- if (err)
- goto out;
-
- msleep(SAA7191_SYNC_DELAY);
-
- err = saa7191_wait_for_signal(sd, &status);
- if (err)
- goto out;
-
- /* not 50Hz ? */
- if (status & SAA7191_STATUS_FIDT) {
- dprintk("No 50Hz signal\n");
- saa7191_s_std(sd, old_norm);
- return -EAGAIN;
- }
-
- if (status & SAA7191_STATUS_CODE) {
- dprintk("PAL\n");
- *norm = V4L2_STD_PAL;
- return saa7191_s_std(sd, old_norm);
- }
-
- dprintk("No color detected with PAL - Trying SECAM...\n");
-
- /* no color detected ? -> try SECAM */
- err = saa7191_s_std(sd, V4L2_STD_SECAM);
- if (err)
- goto out;
-
- msleep(SAA7191_SYNC_DELAY);
-
- err = saa7191_wait_for_signal(sd, &status);
- if (err)
- goto out;
-
- /* not 50Hz ? */
- if (status & SAA7191_STATUS_FIDT) {
- dprintk("No 50Hz signal\n");
- err = -EAGAIN;
- goto out;
- }
-
- if (status & SAA7191_STATUS_CODE) {
- /* Color detected -> SECAM */
- dprintk("SECAM\n");
- *norm = V4L2_STD_SECAM;
- return saa7191_s_std(sd, old_norm);
- }
-
- dprintk("No color detected with SECAM - Going back to PAL.\n");
-
-out:
- return saa7191_s_std(sd, old_norm);
-}
-
-static int saa7191_autodetect_norm(struct v4l2_subdev *sd)
-{
- u8 status;
-
- dprintk("SAA7191 signal auto-detection...\n");
-
- dprintk("Reading status...\n");
-
- if (saa7191_read_status(sd, &status))
- return -EIO;
-
- dprintk("Checking for signal...\n");
-
- /* no signal ? */
- if (status & SAA7191_STATUS_HLCK) {
- dprintk("No signal\n");
- return -EBUSY;
- }
-
- dprintk("Signal found\n");
-
- if (status & SAA7191_STATUS_FIDT) {
- /* 60hz signal -> NTSC */
- dprintk("NTSC\n");
- return saa7191_s_std(sd, V4L2_STD_NTSC);
- } else {
- /* 50hz signal -> PAL */
- dprintk("PAL\n");
- return saa7191_s_std(sd, V4L2_STD_PAL);
- }
-}
-
-static int saa7191_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- u8 reg;
- int ret = 0;
-
- switch (ctrl->id) {
- case SAA7191_CONTROL_BANDPASS:
- case SAA7191_CONTROL_BANDPASS_WEIGHT:
- case SAA7191_CONTROL_CORING:
- reg = saa7191_read_reg(sd, SAA7191_REG_LUMA);
- switch (ctrl->id) {
- case SAA7191_CONTROL_BANDPASS:
- ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK)
- >> SAA7191_LUMA_BPSS_SHIFT;
- break;
- case SAA7191_CONTROL_BANDPASS_WEIGHT:
- ctrl->value = ((s32)reg & SAA7191_LUMA_APER_MASK)
- >> SAA7191_LUMA_APER_SHIFT;
- break;
- case SAA7191_CONTROL_CORING:
- ctrl->value = ((s32)reg & SAA7191_LUMA_CORI_MASK)
- >> SAA7191_LUMA_CORI_SHIFT;
- break;
- }
- break;
- case SAA7191_CONTROL_FORCE_COLOUR:
- case SAA7191_CONTROL_CHROMA_GAIN:
- reg = saa7191_read_reg(sd, SAA7191_REG_GAIN);
- if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR)
- ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
- else
- ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
- >> SAA7191_GAIN_LFIS_SHIFT;
- break;
- case V4L2_CID_HUE:
- reg = saa7191_read_reg(sd, SAA7191_REG_HUEC);
- if (reg < 0x80)
- reg += 0x80;
- else
- reg -= 0x80;
- ctrl->value = (s32)reg;
- break;
- case SAA7191_CONTROL_VTRC:
- reg = saa7191_read_reg(sd, SAA7191_REG_STDC);
- ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0;
- break;
- case SAA7191_CONTROL_LUMA_DELAY:
- reg = saa7191_read_reg(sd, SAA7191_REG_CTL3);
- ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK)
- >> SAA7191_CTL3_YDEL_SHIFT;
- if (ctrl->value >= 4)
- ctrl->value -= 8;
- break;
- case SAA7191_CONTROL_VNR:
- reg = saa7191_read_reg(sd, SAA7191_REG_CTL4);
- ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK)
- >> SAA7191_CTL4_VNOI_SHIFT;
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int saa7191_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- u8 reg;
- int ret = 0;
-
- switch (ctrl->id) {
- case SAA7191_CONTROL_BANDPASS:
- case SAA7191_CONTROL_BANDPASS_WEIGHT:
- case SAA7191_CONTROL_CORING:
- reg = saa7191_read_reg(sd, SAA7191_REG_LUMA);
- switch (ctrl->id) {
- case SAA7191_CONTROL_BANDPASS:
- reg &= ~SAA7191_LUMA_BPSS_MASK;
- reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT)
- & SAA7191_LUMA_BPSS_MASK;
- break;
- case SAA7191_CONTROL_BANDPASS_WEIGHT:
- reg &= ~SAA7191_LUMA_APER_MASK;
- reg |= (ctrl->value << SAA7191_LUMA_APER_SHIFT)
- & SAA7191_LUMA_APER_MASK;
- break;
- case SAA7191_CONTROL_CORING:
- reg &= ~SAA7191_LUMA_CORI_MASK;
- reg |= (ctrl->value << SAA7191_LUMA_CORI_SHIFT)
- & SAA7191_LUMA_CORI_MASK;
- break;
- }
- ret = saa7191_write_reg(sd, SAA7191_REG_LUMA, reg);
- break;
- case SAA7191_CONTROL_FORCE_COLOUR:
- case SAA7191_CONTROL_CHROMA_GAIN:
- reg = saa7191_read_reg(sd, SAA7191_REG_GAIN);
- if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) {
- if (ctrl->value)
- reg |= SAA7191_GAIN_COLO;
- else
- reg &= ~SAA7191_GAIN_COLO;
- } else {
- reg &= ~SAA7191_GAIN_LFIS_MASK;
- reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT)
- & SAA7191_GAIN_LFIS_MASK;
- }
- ret = saa7191_write_reg(sd, SAA7191_REG_GAIN, reg);
- break;
- case V4L2_CID_HUE:
- reg = ctrl->value & 0xff;
- if (reg < 0x80)
- reg += 0x80;
- else
- reg -= 0x80;
- ret = saa7191_write_reg(sd, SAA7191_REG_HUEC, reg);
- break;
- case SAA7191_CONTROL_VTRC:
- reg = saa7191_read_reg(sd, SAA7191_REG_STDC);
- if (ctrl->value)
- reg |= SAA7191_STDC_VTRC;
- else
- reg &= ~SAA7191_STDC_VTRC;
- ret = saa7191_write_reg(sd, SAA7191_REG_STDC, reg);
- break;
- case SAA7191_CONTROL_LUMA_DELAY: {
- s32 value = ctrl->value;
- if (value < 0)
- value += 8;
- reg = saa7191_read_reg(sd, SAA7191_REG_CTL3);
- reg &= ~SAA7191_CTL3_YDEL_MASK;
- reg |= (value << SAA7191_CTL3_YDEL_SHIFT)
- & SAA7191_CTL3_YDEL_MASK;
- ret = saa7191_write_reg(sd, SAA7191_REG_CTL3, reg);
- break;
- }
- case SAA7191_CONTROL_VNR:
- reg = saa7191_read_reg(sd, SAA7191_REG_CTL4);
- reg &= ~SAA7191_CTL4_VNOI_MASK;
- reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT)
- & SAA7191_CTL4_VNOI_MASK;
- ret = saa7191_write_reg(sd, SAA7191_REG_CTL4, reg);
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-/* I2C-interface */
-
-static int saa7191_g_input_status(struct v4l2_subdev *sd, u32 *status)
-{
- u8 status_reg;
- int res = V4L2_IN_ST_NO_SIGNAL;
-
- if (saa7191_read_status(sd, &status_reg))
- return -EIO;
- if ((status_reg & SAA7191_STATUS_HLCK) == 0)
- res = 0;
- if (!(status_reg & SAA7191_STATUS_CODE))
- res |= V4L2_IN_ST_NO_COLOR;
- *status = res;
- return 0;
-}
-
-
-static int saa7191_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7191, 0);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops saa7191_core_ops = {
- .g_chip_ident = saa7191_g_chip_ident,
- .g_ctrl = saa7191_g_ctrl,
- .s_ctrl = saa7191_s_ctrl,
- .s_std = saa7191_s_std,
-};
-
-static const struct v4l2_subdev_video_ops saa7191_video_ops = {
- .s_routing = saa7191_s_routing,
- .querystd = saa7191_querystd,
- .g_input_status = saa7191_g_input_status,
-};
-
-static const struct v4l2_subdev_ops saa7191_ops = {
- .core = &saa7191_core_ops,
- .video = &saa7191_video_ops,
-};
-
-static int saa7191_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int err = 0;
- struct saa7191 *decoder;
- struct v4l2_subdev *sd;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
- if (!decoder)
- return -ENOMEM;
-
- sd = &decoder->sd;
- v4l2_i2c_subdev_init(sd, client, &saa7191_ops);
-
- err = saa7191_write_block(sd, sizeof(initseq), initseq);
- if (err) {
- printk(KERN_ERR "SAA7191 initialization failed\n");
- kfree(decoder);
- return err;
- }
-
- printk(KERN_INFO "SAA7191 initialized\n");
-
- decoder->input = SAA7191_INPUT_COMPOSITE;
- decoder->norm = V4L2_STD_PAL;
-
- err = saa7191_autodetect_norm(sd);
- if (err && (err != -EBUSY))
- printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
-
- return 0;
-}
-
-static int saa7191_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(to_saa7191(sd));
- return 0;
-}
-
-static const struct i2c_device_id saa7191_id[] = {
- { "saa7191", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, saa7191_id);
-
-static struct i2c_driver saa7191_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "saa7191",
- },
- .probe = saa7191_probe,
- .remove = saa7191_remove,
- .id_table = saa7191_id,
-};
-
-module_i2c_driver(saa7191_driver);
diff --git a/drivers/media/video/saa7191.h b/drivers/media/video/saa7191.h
deleted file mode 100644
index 803c74d6066..00000000000
--- a/drivers/media/video/saa7191.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * saa7191.h - Philips SAA7191 video decoder driver
- *
- * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
- * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _SAA7191_H_
-#define _SAA7191_H_
-
-/* Philips SAA7191 DMSD I2C bus address */
-#define SAA7191_ADDR 0x8a
-
-/* Register subaddresses. */
-#define SAA7191_REG_IDEL 0x00
-#define SAA7191_REG_HSYB 0x01
-#define SAA7191_REG_HSYS 0x02
-#define SAA7191_REG_HCLB 0x03
-#define SAA7191_REG_HCLS 0x04
-#define SAA7191_REG_HPHI 0x05
-#define SAA7191_REG_LUMA 0x06
-#define SAA7191_REG_HUEC 0x07
-#define SAA7191_REG_CKTQ 0x08 /* bits 3-7 */
-#define SAA7191_REG_CKTS 0x09 /* bits 3-7 */
-#define SAA7191_REG_PLSE 0x0a
-#define SAA7191_REG_SESE 0x0b
-#define SAA7191_REG_GAIN 0x0c
-#define SAA7191_REG_STDC 0x0d
-#define SAA7191_REG_IOCK 0x0e
-#define SAA7191_REG_CTL3 0x0f
-#define SAA7191_REG_CTL4 0x10
-#define SAA7191_REG_CHCV 0x11
-#define SAA7191_REG_HS6B 0x14
-#define SAA7191_REG_HS6S 0x15
-#define SAA7191_REG_HC6B 0x16
-#define SAA7191_REG_HC6S 0x17
-#define SAA7191_REG_HP6I 0x18
-#define SAA7191_REG_STATUS 0xff /* not really a subaddress */
-
-/* Status Register definitions */
-#define SAA7191_STATUS_CODE 0x01 /* color detected flag */
-#define SAA7191_STATUS_FIDT 0x20 /* signal type 50/60 Hz */
-#define SAA7191_STATUS_HLCK 0x40 /* PLL unlocked(1)/locked(0) */
-#define SAA7191_STATUS_STTC 0x80 /* tv/vtr time constant */
-
-/* Luminance Control Register definitions */
-/* input mode select bit:
- * 0=CVBS (chrominance trap active), 1=S-Video (trap bypassed) */
-#define SAA7191_LUMA_BYPS 0x80
-/* pre-filter (only when chrominance trap is active) */
-#define SAA7191_LUMA_PREF 0x40
-/* aperture bandpass to select different characteristics with maximums
- * (bits 4-5) */
-#define SAA7191_LUMA_BPSS_MASK 0x30
-#define SAA7191_LUMA_BPSS_SHIFT 4
-#define SAA7191_LUMA_BPSS_3 0x30
-#define SAA7191_LUMA_BPSS_2 0x20
-#define SAA7191_LUMA_BPSS_1 0x10
-#define SAA7191_LUMA_BPSS_0 0x00
-/* coring range for high frequency components according to 8-bit luminance
- * (bits 2-3)
- * 0=coring off, n= (+-)n LSB */
-#define SAA7191_LUMA_CORI_MASK 0x0c
-#define SAA7191_LUMA_CORI_SHIFT 2
-#define SAA7191_LUMA_CORI_3 0x0c
-#define SAA7191_LUMA_CORI_2 0x08
-#define SAA7191_LUMA_CORI_1 0x04
-#define SAA7191_LUMA_CORI_0 0x00
-/* aperture bandpass filter weights high frequency components of luminance
- * signal (bits 0-1)
- * 0=factor 0, 1=0.25, 2=0.5, 3=1 */
-#define SAA7191_LUMA_APER_MASK 0x03
-#define SAA7191_LUMA_APER_SHIFT 0
-#define SAA7191_LUMA_APER_3 0x03
-#define SAA7191_LUMA_APER_2 0x02
-#define SAA7191_LUMA_APER_1 0x01
-#define SAA7191_LUMA_APER_0 0x00
-
-/* Chrominance Gain Control Settings Register definitions */
-/* colour on: 0=automatic colour-killer enabled, 1=forced colour on */
-#define SAA7191_GAIN_COLO 0x80
-/* chrominance gain control (AGC filter)
- * 0=loop filter time constant slow, 1=medium, 2=fast, 3=actual gain */
-#define SAA7191_GAIN_LFIS_MASK 0x60
-#define SAA7191_GAIN_LFIS_SHIFT 5
-#define SAA7191_GAIN_LFIS_3 0x60
-#define SAA7191_GAIN_LFIS_2 0x40
-#define SAA7191_GAIN_LFIS_1 0x20
-#define SAA7191_GAIN_LFIS_0 0x00
-
-/* Standard/Mode Control Register definitions */
-/* tv/vtr mode bit: 0=TV mode (slow time constant),
- * 1=VTR mode (fast time constant) */
-#define SAA7191_STDC_VTRC 0x80
-/* SAA7191B-specific functions enable (RTCO, ODD and GPSW0 outputs)
- * 0=outputs set to high-impedance (circuit equals SAA7191), 1=enabled */
-#define SAA7191_STDC_NFEN 0x08
-/* HREF generation: 0=like SAA7191, 1=HREF is 8xLLC2 clocks earlier */
-#define SAA7191_STDC_HRMV 0x04
-/* general purpose switch 0
- * (not used with VINO afaik) */
-#define SAA7191_STDC_GPSW0 0x02
-/* SECAM mode bit: 0=other standards, 1=SECAM */
-#define SAA7191_STDC_SECS 0x01
-
-/* I/O and Clock Control Register definitions */
-/* horizontal clock PLL: 0=PLL closed,
- * 1=PLL circuit open and horizontal freq fixed */
-#define SAA7191_IOCK_HPLL 0x80
-/* colour-difference output enable (outputs UV0-UV7) */
-#define SAA7191_IOCK_OEDC 0x40
-/* H-sync output enable */
-#define SAA7191_IOCK_OEHS 0x20
-/* V-sync output enable */
-#define SAA7191_IOCK_OEVS 0x10
-/* luminance output enable (outputs Y0-Y7) */
-#define SAA7191_IOCK_OEDY 0x08
-/* S-VHS bit (chrominance from CVBS or from chrominance input):
- * 0=controlled by BYPS-bit, 1=from chrominance input */
-#define SAA7191_IOCK_CHRS 0x04
-/* general purpose switch 2
- * VINO-specific: 0=used with CVBS, 1=used with S-Video */
-#define SAA7191_IOCK_GPSW2 0x02
-/* general purpose switch 1 */
-/* VINO-specific: 0=always, 1=not used!*/
-#define SAA7191_IOCK_GPSW1 0x01
-
-/* Miscellaneous Control #1 Register definitions */
-/* automatic field detection (50/60Hz standard) */
-#define SAA7191_CTL3_AUFD 0x80
-/* field select: (if AUFD=0)
- * 0=50Hz (625 lines), 1=60Hz (525 lines) */
-#define SAA7191_CTL3_FSEL 0x40
-/* SECAM cross-colour reduction enable */
-#define SAA7191_CTL3_SXCR 0x20
-/* sync and clamping pulse enable (HCL and HSY outputs) */
-#define SAA7191_CTL3_SCEN 0x10
-/* output format: 0=4:1:1, 1=4:2:2 (4:2:2 for VINO) */
-#define SAA7191_CTL3_OFTS 0x08
-/* luminance delay compensation
- * 0=0*2/LLC, 1=+1*2/LLC, 2=+2*2/LLC, 3=+3*2/LLC,
- * 4=-4*2/LLC, 5=-3*2/LLC, 6=-2*2/LLC, 7=-1*2/LLC
- * step size = 2/LLC = 67.8ns for 50Hz, 81.5ns for 60Hz */
-#define SAA7191_CTL3_YDEL_MASK 0x07
-#define SAA7191_CTL3_YDEL_SHIFT 0
-#define SAA7191_CTL3_YDEL2 0x04
-#define SAA7191_CTL3_YDEL1 0x02
-#define SAA7191_CTL3_YDEL0 0x01
-
-/* Miscellaneous Control #2 Register definitions */
-/* select HREF position
- * 0=normal, HREF is matched to YUV output port,
- * 1=HREF is matched to CVBS input port */
-#define SAA7191_CTL4_HRFS 0x04
-/* vertical noise reduction
- * 0=normal, 1=searching window, 2=auto-deflection, 3=reduction bypassed */
-#define SAA7191_CTL4_VNOI_MASK 0x03
-#define SAA7191_CTL4_VNOI_SHIFT 0
-#define SAA7191_CTL4_VNOI_3 0x03
-#define SAA7191_CTL4_VNOI_2 0x02
-#define SAA7191_CTL4_VNOI_1 0x01
-#define SAA7191_CTL4_VNOI_0 0x00
-
-/* Chrominance Gain Control Register definitions
- * - for QAM-modulated input signals, effects output amplitude
- * (SECAM gain fixed)
- * (nominal values for UV CCIR level) */
-#define SAA7191_CHCV_NTSC 0x2c
-#define SAA7191_CHCV_PAL 0x59
-
-/* Driver interface definitions */
-#define SAA7191_INPUT_COMPOSITE 0
-#define SAA7191_INPUT_SVIDEO 1
-
-#define SAA7191_NORM_PAL 1
-#define SAA7191_NORM_NTSC 2
-#define SAA7191_NORM_SECAM 3
-
-struct saa7191_status {
- /* 0=no signal, 1=signal detected */
- int signal;
- /* 0=50hz (pal) signal, 1=60hz (ntsc) signal */
- int signal_60hz;
- /* 0=no color detected, 1=color detected */
- int color;
-
- /* current SAA7191_INPUT_ */
- int input;
- /* current SAA7191_NORM_ */
- int norm;
-};
-
-#define SAA7191_BANDPASS_MIN 0x00
-#define SAA7191_BANDPASS_MAX 0x03
-#define SAA7191_BANDPASS_DEFAULT 0x00
-
-#define SAA7191_BANDPASS_WEIGHT_MIN 0x00
-#define SAA7191_BANDPASS_WEIGHT_MAX 0x03
-#define SAA7191_BANDPASS_WEIGHT_DEFAULT 0x01
-
-#define SAA7191_CORING_MIN 0x00
-#define SAA7191_CORING_MAX 0x03
-#define SAA7191_CORING_DEFAULT 0x00
-
-#define SAA7191_HUE_MIN 0x00
-#define SAA7191_HUE_MAX 0xff
-#define SAA7191_HUE_DEFAULT 0x80
-
-#define SAA7191_VTRC_MIN 0x00
-#define SAA7191_VTRC_MAX 0x01
-#define SAA7191_VTRC_DEFAULT 0x00
-
-#define SAA7191_FORCE_COLOUR_MIN 0x00
-#define SAA7191_FORCE_COLOUR_MAX 0x01
-#define SAA7191_FORCE_COLOUR_DEFAULT 0x00
-
-#define SAA7191_CHROMA_GAIN_MIN 0x00
-#define SAA7191_CHROMA_GAIN_MAX 0x03
-#define SAA7191_CHROMA_GAIN_DEFAULT 0x00
-
-#define SAA7191_LUMA_DELAY_MIN -0x04
-#define SAA7191_LUMA_DELAY_MAX 0x03
-#define SAA7191_LUMA_DELAY_DEFAULT 0x01
-
-#define SAA7191_VNR_MIN 0x00
-#define SAA7191_VNR_MAX 0x03
-#define SAA7191_VNR_DEFAULT 0x00
-
-#define SAA7191_CONTROL_BANDPASS (V4L2_CID_PRIVATE_BASE + 0)
-#define SAA7191_CONTROL_BANDPASS_WEIGHT (V4L2_CID_PRIVATE_BASE + 1)
-#define SAA7191_CONTROL_CORING (V4L2_CID_PRIVATE_BASE + 2)
-#define SAA7191_CONTROL_FORCE_COLOUR (V4L2_CID_PRIVATE_BASE + 3)
-#define SAA7191_CONTROL_CHROMA_GAIN (V4L2_CID_PRIVATE_BASE + 4)
-#define SAA7191_CONTROL_VTRC (V4L2_CID_PRIVATE_BASE + 5)
-#define SAA7191_CONTROL_LUMA_DELAY (V4L2_CID_PRIVATE_BASE + 6)
-#define SAA7191_CONTROL_VNR (V4L2_CID_PRIVATE_BASE + 7)
-
-#define DECODER_SAA7191_GET_STATUS _IOR('d', 195, struct saa7191_status)
-#define DECODER_SAA7191_SET_NORM _IOW('d', 196, int)
-
-#endif
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
deleted file mode 100644
index 0baaf94db7e..00000000000
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ /dev/null
@@ -1,2331 +0,0 @@
-/*
- * V4L2 Driver for SuperH Mobile CEU interface
- *
- * Copyright (C) 2008 Magnus Damm
- *
- * Based on V4L2 Driver for PXA camera host - "pxa_camera.c",
- *
- * Copyright (C) 2006, Sascha Hauer, Pengutronix
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/io.h>
-#include <linux/completion.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/moduleparam.h>
-#include <linux/time.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/videodev2.h>
-#include <linux/pm_runtime.h>
-#include <linux/sched.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-dev.h>
-#include <media/soc_camera.h>
-#include <media/sh_mobile_ceu.h>
-#include <media/sh_mobile_csi2.h>
-#include <media/videobuf2-dma-contig.h>
-#include <media/v4l2-mediabus.h>
-#include <media/soc_mediabus.h>
-
-/* register offsets for sh7722 / sh7723 */
-
-#define CAPSR 0x00 /* Capture start register */
-#define CAPCR 0x04 /* Capture control register */
-#define CAMCR 0x08 /* Capture interface control register */
-#define CMCYR 0x0c /* Capture interface cycle register */
-#define CAMOR 0x10 /* Capture interface offset register */
-#define CAPWR 0x14 /* Capture interface width register */
-#define CAIFR 0x18 /* Capture interface input format register */
-#define CSTCR 0x20 /* Camera strobe control register (<= sh7722) */
-#define CSECR 0x24 /* Camera strobe emission count register (<= sh7722) */
-#define CRCNTR 0x28 /* CEU register control register */
-#define CRCMPR 0x2c /* CEU register forcible control register */
-#define CFLCR 0x30 /* Capture filter control register */
-#define CFSZR 0x34 /* Capture filter size clip register */
-#define CDWDR 0x38 /* Capture destination width register */
-#define CDAYR 0x3c /* Capture data address Y register */
-#define CDACR 0x40 /* Capture data address C register */
-#define CDBYR 0x44 /* Capture data bottom-field address Y register */
-#define CDBCR 0x48 /* Capture data bottom-field address C register */
-#define CBDSR 0x4c /* Capture bundle destination size register */
-#define CFWCR 0x5c /* Firewall operation control register */
-#define CLFCR 0x60 /* Capture low-pass filter control register */
-#define CDOCR 0x64 /* Capture data output control register */
-#define CDDCR 0x68 /* Capture data complexity level register */
-#define CDDAR 0x6c /* Capture data complexity level address register */
-#define CEIER 0x70 /* Capture event interrupt enable register */
-#define CETCR 0x74 /* Capture event flag clear register */
-#define CSTSR 0x7c /* Capture status register */
-#define CSRTR 0x80 /* Capture software reset register */
-#define CDSSR 0x84 /* Capture data size register */
-#define CDAYR2 0x90 /* Capture data address Y register 2 */
-#define CDACR2 0x94 /* Capture data address C register 2 */
-#define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */
-#define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */
-
-#undef DEBUG_GEOMETRY
-#ifdef DEBUG_GEOMETRY
-#define dev_geo dev_info
-#else
-#define dev_geo dev_dbg
-#endif
-
-/* per video frame buffer */
-struct sh_mobile_ceu_buffer {
- struct vb2_buffer vb; /* v4l buffer must be first */
- struct list_head queue;
-};
-
-struct sh_mobile_ceu_dev {
- struct soc_camera_host ici;
- struct soc_camera_device *icd;
- struct platform_device *csi2_pdev;
-
- unsigned int irq;
- void __iomem *base;
- size_t video_limit;
- size_t buf_total;
-
- spinlock_t lock; /* Protects video buffer lists */
- struct list_head capture;
- struct vb2_buffer *active;
- struct vb2_alloc_ctx *alloc_ctx;
-
- struct sh_mobile_ceu_info *pdata;
- struct completion complete;
-
- u32 cflcr;
-
- /* static max sizes either from platform data or default */
- int max_width;
- int max_height;
-
- enum v4l2_field field;
- int sequence;
-
- unsigned int image_mode:1;
- unsigned int is_16bit:1;
- unsigned int frozen:1;
-};
-
-struct sh_mobile_ceu_cam {
- /* CEU offsets within the camera output, before the CEU scaler */
- unsigned int ceu_left;
- unsigned int ceu_top;
- /* Client output, as seen by the CEU */
- unsigned int width;
- unsigned int height;
- /*
- * User window from S_CROP / G_CROP, produced by client cropping and
- * scaling, CEU scaling and CEU cropping, mapped back onto the client
- * input window
- */
- struct v4l2_rect subrect;
- /* Camera cropping rectangle */
- struct v4l2_rect rect;
- const struct soc_mbus_pixelfmt *extra_fmt;
- enum v4l2_mbus_pixelcode code;
-};
-
-static struct sh_mobile_ceu_buffer *to_ceu_vb(struct vb2_buffer *vb)
-{
- return container_of(vb, struct sh_mobile_ceu_buffer, vb);
-}
-
-static void ceu_write(struct sh_mobile_ceu_dev *priv,
- unsigned long reg_offs, u32 data)
-{
- iowrite32(data, priv->base + reg_offs);
-}
-
-static u32 ceu_read(struct sh_mobile_ceu_dev *priv, unsigned long reg_offs)
-{
- return ioread32(priv->base + reg_offs);
-}
-
-static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
-{
- int i, success = 0;
- struct soc_camera_device *icd = pcdev->icd;
-
- ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
-
- /* wait CSTSR.CPTON bit */
- for (i = 0; i < 1000; i++) {
- if (!(ceu_read(pcdev, CSTSR) & 1)) {
- success++;
- break;
- }
- udelay(1);
- }
-
- /* wait CAPSR.CPKIL bit */
- for (i = 0; i < 1000; i++) {
- if (!(ceu_read(pcdev, CAPSR) & (1 << 16))) {
- success++;
- break;
- }
- udelay(1);
- }
-
-
- if (2 != success) {
- dev_warn(icd->pdev, "soft reset time out\n");
- return -EIO;
- }
-
- return 0;
-}
-
-/*
- * Videobuf operations
- */
-
-/*
- * .queue_setup() is called to check, whether the driver can accept the
- * requested number of buffers and to fill in plane sizes
- * for the current frame format if required
- */
-static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
- unsigned int *count, unsigned int *num_planes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
-
- if (fmt) {
- const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
- fmt->fmt.pix.pixelformat);
- unsigned int bytes_per_line;
- int ret;
-
- if (!xlate)
- return -EINVAL;
-
- ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
- xlate->host_fmt);
- if (ret < 0)
- return ret;
-
- bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret);
-
- ret = soc_mbus_image_size(xlate->host_fmt, bytes_per_line,
- fmt->fmt.pix.height);
- if (ret < 0)
- return ret;
-
- sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret);
- } else {
- /* Called from VIDIOC_REQBUFS or in compatibility mode */
- sizes[0] = icd->sizeimage;
- }
-
- alloc_ctxs[0] = pcdev->alloc_ctx;
-
- if (!vq->num_buffers)
- pcdev->sequence = 0;
-
- if (!*count)
- *count = 2;
-
- /* If *num_planes != 0, we have already verified *count. */
- if (pcdev->video_limit && !*num_planes) {
- size_t size = PAGE_ALIGN(sizes[0]) * *count;
-
- if (size + pcdev->buf_total > pcdev->video_limit)
- *count = (pcdev->video_limit - pcdev->buf_total) /
- PAGE_ALIGN(sizes[0]);
- }
-
- *num_planes = 1;
-
- dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
-
- return 0;
-}
-
-#define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */
-#define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */
-#define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */
-#define CEU_CEIER_VBP (1 << 20) /* vbp error */
-#define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */
-#define CEU_CEIER_MASK (CEU_CEIER_CPEIE | CEU_CEIER_VBP)
-
-
-/*
- * return value doesn't reflex the success/failure to queue the new buffer,
- * but rather the status of the previous buffer.
- */
-static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
-{
- struct soc_camera_device *icd = pcdev->icd;
- dma_addr_t phys_addr_top, phys_addr_bottom;
- unsigned long top1, top2;
- unsigned long bottom1, bottom2;
- u32 status;
- bool planar;
- int ret = 0;
-
- /*
- * The hardware is _very_ picky about this sequence. Especially
- * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge
- * several not-so-well documented interrupt sources in CETCR.
- */
- ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_MASK);
- status = ceu_read(pcdev, CETCR);
- ceu_write(pcdev, CETCR, ~status & CEU_CETCR_MAGIC);
- if (!pcdev->frozen)
- ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK);
- ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
- ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);
-
- /*
- * When a VBP interrupt occurs, a capture end interrupt does not occur
- * and the image of that frame is not captured correctly. So, soft reset
- * is needed here.
- */
- if (status & CEU_CEIER_VBP) {
- sh_mobile_ceu_soft_reset(pcdev);
- ret = -EIO;
- }
-
- if (pcdev->frozen) {
- complete(&pcdev->complete);
- return ret;
- }
-
- if (!pcdev->active)
- return ret;
-
- if (V4L2_FIELD_INTERLACED_BT == pcdev->field) {
- top1 = CDBYR;
- top2 = CDBCR;
- bottom1 = CDAYR;
- bottom2 = CDACR;
- } else {
- top1 = CDAYR;
- top2 = CDACR;
- bottom1 = CDBYR;
- bottom2 = CDBCR;
- }
-
- phys_addr_top = vb2_dma_contig_plane_dma_addr(pcdev->active, 0);
-
- switch (icd->current_fmt->host_fmt->fourcc) {
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- case V4L2_PIX_FMT_NV16:
- case V4L2_PIX_FMT_NV61:
- planar = true;
- break;
- default:
- planar = false;
- }
-
- ceu_write(pcdev, top1, phys_addr_top);
- if (V4L2_FIELD_NONE != pcdev->field) {
- phys_addr_bottom = phys_addr_top + icd->bytesperline;
- ceu_write(pcdev, bottom1, phys_addr_bottom);
- }
-
- if (planar) {
- phys_addr_top += icd->bytesperline * icd->user_height;
- ceu_write(pcdev, top2, phys_addr_top);
- if (V4L2_FIELD_NONE != pcdev->field) {
- phys_addr_bottom = phys_addr_top + icd->bytesperline;
- ceu_write(pcdev, bottom2, phys_addr_bottom);
- }
- }
-
- ceu_write(pcdev, CAPSR, 0x1); /* start capture */
-
- return ret;
-}
-
-static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
-{
- struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
-
- /* Added list head initialization on alloc */
- WARN(!list_empty(&buf->queue), "Buffer %p on queue!\n", vb);
-
- return 0;
-}
-
-static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
-{
- struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
- struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
- unsigned long size;
-
- size = icd->sizeimage;
-
- if (vb2_plane_size(vb, 0) < size) {
- dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
- vb->v4l2_buf.index, vb2_plane_size(vb, 0), size);
- goto error;
- }
-
- vb2_set_plane_payload(vb, 0, size);
-
- dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
- vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
-
-#ifdef DEBUG
- /*
- * This can be useful if you want to see if we actually fill
- * the buffer with something
- */
- if (vb2_plane_vaddr(vb, 0))
- memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
-#endif
-
- spin_lock_irq(&pcdev->lock);
- list_add_tail(&buf->queue, &pcdev->capture);
-
- if (!pcdev->active) {
- /*
- * Because there were no active buffer at this moment,
- * we are not interested in the return value of
- * sh_mobile_ceu_capture here.
- */
- pcdev->active = vb;
- sh_mobile_ceu_capture(pcdev);
- }
- spin_unlock_irq(&pcdev->lock);
-
- return;
-
-error:
- vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
-}
-
-static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
-{
- struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
-
- spin_lock_irq(&pcdev->lock);
-
- if (pcdev->active == vb) {
- /* disable capture (release DMA buffer), reset */
- ceu_write(pcdev, CAPSR, 1 << 16);
- pcdev->active = NULL;
- }
-
- /*
- * Doesn't hurt also if the list is empty, but it hurts, if queuing the
- * buffer failed, and .buf_init() hasn't been called
- */
- if (buf->queue.next)
- list_del_init(&buf->queue);
-
- pcdev->buf_total -= PAGE_ALIGN(vb2_plane_size(vb, 0));
- dev_dbg(icd->parent, "%s() %zu bytes buffers\n", __func__,
- pcdev->buf_total);
-
- spin_unlock_irq(&pcdev->lock);
-}
-
-static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
-{
- struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
-
- pcdev->buf_total += PAGE_ALIGN(vb2_plane_size(vb, 0));
- dev_dbg(icd->parent, "%s() %zu bytes buffers\n", __func__,
- pcdev->buf_total);
-
- /* This is for locking debugging only */
- INIT_LIST_HEAD(&to_ceu_vb(vb)->queue);
- return 0;
-}
-
-static int sh_mobile_ceu_stop_streaming(struct vb2_queue *q)
-{
- struct soc_camera_device *icd = container_of(q, struct soc_camera_device, vb2_vidq);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
- struct list_head *buf_head, *tmp;
-
- spin_lock_irq(&pcdev->lock);
-
- pcdev->active = NULL;
-
- list_for_each_safe(buf_head, tmp, &pcdev->capture)
- list_del_init(buf_head);
-
- spin_unlock_irq(&pcdev->lock);
-
- return sh_mobile_ceu_soft_reset(pcdev);
-}
-
-static struct vb2_ops sh_mobile_ceu_videobuf_ops = {
- .queue_setup = sh_mobile_ceu_videobuf_setup,
- .buf_prepare = sh_mobile_ceu_videobuf_prepare,
- .buf_queue = sh_mobile_ceu_videobuf_queue,
- .buf_cleanup = sh_mobile_ceu_videobuf_release,
- .buf_init = sh_mobile_ceu_videobuf_init,
- .wait_prepare = soc_camera_unlock,
- .wait_finish = soc_camera_lock,
- .stop_streaming = sh_mobile_ceu_stop_streaming,
-};
-
-static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
-{
- struct sh_mobile_ceu_dev *pcdev = data;
- struct vb2_buffer *vb;
- int ret;
-
- spin_lock(&pcdev->lock);
-
- vb = pcdev->active;
- if (!vb)
- /* Stale interrupt from a released buffer */
- goto out;
-
- list_del_init(&to_ceu_vb(vb)->queue);
-
- if (!list_empty(&pcdev->capture))
- pcdev->active = &list_entry(pcdev->capture.next,
- struct sh_mobile_ceu_buffer, queue)->vb;
- else
- pcdev->active = NULL;
-
- ret = sh_mobile_ceu_capture(pcdev);
- do_gettimeofday(&vb->v4l2_buf.timestamp);
- if (!ret) {
- vb->v4l2_buf.field = pcdev->field;
- vb->v4l2_buf.sequence = pcdev->sequence++;
- }
- vb2_buffer_done(vb, ret < 0 ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-
-out:
- spin_unlock(&pcdev->lock);
-
- return IRQ_HANDLED;
-}
-
-static struct v4l2_subdev *find_csi2(struct sh_mobile_ceu_dev *pcdev)
-{
- struct v4l2_subdev *sd;
-
- if (!pcdev->csi2_pdev)
- return NULL;
-
- v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev)
- if (&pcdev->csi2_pdev->dev == v4l2_get_subdevdata(sd))
- return sd;
-
- return NULL;
-}
-
-/* Called with .video_lock held */
-static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
- struct v4l2_subdev *csi2_sd;
- int ret;
-
- if (pcdev->icd)
- return -EBUSY;
-
- dev_info(icd->parent,
- "SuperH Mobile CEU driver attached to camera %d\n",
- icd->devnum);
-
- pm_runtime_get_sync(ici->v4l2_dev.dev);
-
- pcdev->buf_total = 0;
-
- ret = sh_mobile_ceu_soft_reset(pcdev);
-
- csi2_sd = find_csi2(pcdev);
- if (csi2_sd) {
- csi2_sd->grp_id = soc_camera_grp_id(icd);
- v4l2_set_subdev_hostdata(csi2_sd, icd);
- }
-
- ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
- if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {
- pm_runtime_put_sync(ici->v4l2_dev.dev);
- return ret;
- }
-
- /*
- * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver
- * has not found this soc-camera device among its clients
- */
- if (ret == -ENODEV && csi2_sd)
- csi2_sd->grp_id = 0;
- pcdev->icd = icd;
-
- return 0;
-}
-
-/* Called with .video_lock held */
-static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
- struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
-
- BUG_ON(icd != pcdev->icd);
-
- v4l2_subdev_call(csi2_sd, core, s_power, 0);
- if (csi2_sd)
- csi2_sd->grp_id = 0;
- /* disable capture, disable interrupts */
- ceu_write(pcdev, CEIER, 0);
- sh_mobile_ceu_soft_reset(pcdev);
-
- /* make sure active buffer is canceled */
- spin_lock_irq(&pcdev->lock);
- if (pcdev->active) {
- list_del_init(&to_ceu_vb(pcdev->active)->queue);
- vb2_buffer_done(pcdev->active, VB2_BUF_STATE_ERROR);
- pcdev->active = NULL;
- }
- spin_unlock_irq(&pcdev->lock);
-
- pm_runtime_put_sync(ici->v4l2_dev.dev);
-
- dev_info(icd->parent,
- "SuperH Mobile CEU driver detached from camera %d\n",
- icd->devnum);
-
- pcdev->icd = NULL;
-}
-
-/*
- * See chapter 29.4.12 "Capture Filter Control Register (CFLCR)"
- * in SH7722 Hardware Manual
- */
-static unsigned int size_dst(unsigned int src, unsigned int scale)
-{
- unsigned int mant_pre = scale >> 12;
- if (!src || !scale)
- return src;
- return ((mant_pre + 2 * (src - 1)) / (2 * mant_pre) - 1) *
- mant_pre * 4096 / scale + 1;
-}
-
-static u16 calc_scale(unsigned int src, unsigned int *dst)
-{
- u16 scale;
-
- if (src == *dst)
- return 0;
-
- scale = (src * 4096 / *dst) & ~7;
-
- while (scale > 4096 && size_dst(src, scale) < *dst)
- scale -= 8;
-
- *dst = size_dst(src, scale);
-
- return scale;
-}
-
-/* rect is guaranteed to not exceed the scaled camera rectangle */
-static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_cam *cam = icd->host_priv;
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
- unsigned int height, width, cdwdr_width, in_width, in_height;
- unsigned int left_offset, top_offset;
- u32 camor;
-
- dev_geo(icd->parent, "Crop %ux%u@%u:%u\n",
- icd->user_width, icd->user_height, cam->ceu_left, cam->ceu_top);
-
- left_offset = cam->ceu_left;
- top_offset = cam->ceu_top;
-
- WARN_ON(icd->user_width & 3 || icd->user_height & 3);
-
- width = icd->user_width;
-
- if (pcdev->image_mode) {
- in_width = cam->width;
- if (!pcdev->is_16bit) {
- in_width *= 2;
- left_offset *= 2;
- }
- } else {
- unsigned int w_factor;
-
- switch (icd->current_fmt->host_fmt->packing) {
- case SOC_MBUS_PACKING_2X8_PADHI:
- w_factor = 2;
- break;
- default:
- w_factor = 1;
- }
-
- in_width = cam->width * w_factor;
- left_offset *= w_factor;
- }
-
- cdwdr_width = icd->bytesperline;
-
- height = icd->user_height;
- in_height = cam->height;
- if (V4L2_FIELD_NONE != pcdev->field) {
- height = (height / 2) & ~3;
- in_height /= 2;
- top_offset /= 2;
- cdwdr_width *= 2;
- }
-
- /* CSI2 special configuration */
- if (pcdev->pdata->csi2) {
- in_width = ((in_width - 2) * 2);
- left_offset *= 2;
- }
-
- /* Set CAMOR, CAPWR, CFSZR, take care of CDWDR */
- camor = left_offset | (top_offset << 16);
-
- dev_geo(icd->parent,
- "CAMOR 0x%x, CAPWR 0x%x, CFSZR 0x%x, CDWDR 0x%x\n", camor,
- (in_height << 16) | in_width, (height << 16) | width,
- cdwdr_width);
-
- ceu_write(pcdev, CAMOR, camor);
- ceu_write(pcdev, CAPWR, (in_height << 16) | in_width);
- /* CFSZR clipping is applied _after_ the scaling filter (CFLCR) */
- ceu_write(pcdev, CFSZR, (height << 16) | width);
- ceu_write(pcdev, CDWDR, cdwdr_width);
-}
-
-static u32 capture_save_reset(struct sh_mobile_ceu_dev *pcdev)
-{
- u32 capsr = ceu_read(pcdev, CAPSR);
- ceu_write(pcdev, CAPSR, 1 << 16); /* reset, stop capture */
- return capsr;
-}
-
-static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr)
-{
- unsigned long timeout = jiffies + 10 * HZ;
-
- /*
- * Wait until the end of the current frame. It can take a long time,
- * but if it has been aborted by a CAPSR reset, it shoule exit sooner.
- */
- while ((ceu_read(pcdev, CSTSR) & 1) && time_before(jiffies, timeout))
- msleep(1);
-
- if (time_after(jiffies, timeout)) {
- dev_err(pcdev->ici.v4l2_dev.dev,
- "Timeout waiting for frame end! Interface problem?\n");
- return;
- }
-
- /* Wait until reset clears, this shall not hang... */
- while (ceu_read(pcdev, CAPSR) & (1 << 16))
- udelay(10);
-
- /* Anything to restore? */
- if (capsr & ~(1 << 16))
- ceu_write(pcdev, CAPSR, capsr);
-}
-
-/* Find the bus subdevice driver, e.g., CSI2 */
-static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev,
- struct soc_camera_device *icd)
-{
- if (pcdev->csi2_pdev) {
- struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
- if (csi2_sd && csi2_sd->grp_id == soc_camera_grp_id(icd))
- return csi2_sd;
- }
-
- return soc_camera_to_subdev(icd);
-}
-
-#define CEU_BUS_FLAGS (V4L2_MBUS_MASTER | \
- V4L2_MBUS_PCLK_SAMPLE_RISING | \
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
- V4L2_MBUS_HSYNC_ACTIVE_LOW | \
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
- V4L2_MBUS_VSYNC_ACTIVE_LOW | \
- V4L2_MBUS_DATA_ACTIVE_HIGH)
-
-/* Capture is not running, no interrupts, no locking needed */
-static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
- struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd);
- struct sh_mobile_ceu_cam *cam = icd->host_priv;
- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
- unsigned long value, common_flags = CEU_BUS_FLAGS;
- u32 capsr = capture_save_reset(pcdev);
- unsigned int yuv_lineskip;
- int ret;
-
- /*
- * If the client doesn't implement g_mbus_config, we just use our
- * platform data
- */
- ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
- if (!ret) {
- common_flags = soc_mbus_config_compatible(&cfg,
- common_flags);
- if (!common_flags)
- return -EINVAL;
- } else if (ret != -ENOIOCTLCMD) {
- return ret;
- }
-
- /* Make choises, based on platform preferences */
- if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
- (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
- if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW)
- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
- else
- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
- }
-
- if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
- (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
- if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW)
- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
- else
- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
- }
-
- cfg.flags = common_flags;
- ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return ret;
-
- if (icd->current_fmt->host_fmt->bits_per_sample > 8)
- pcdev->is_16bit = 1;
- else
- pcdev->is_16bit = 0;
-
- ceu_write(pcdev, CRCNTR, 0);
- ceu_write(pcdev, CRCMPR, 0);
-
- value = 0x00000010; /* data fetch by default */
- yuv_lineskip = 0x10;
-
- switch (icd->current_fmt->host_fmt->fourcc) {
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- /* convert 4:2:2 -> 4:2:0 */
- yuv_lineskip = 0; /* skip for NV12/21, no skip for NV16/61 */
- /* fall-through */
- case V4L2_PIX_FMT_NV16:
- case V4L2_PIX_FMT_NV61:
- switch (cam->code) {
- case V4L2_MBUS_FMT_UYVY8_2X8:
- value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */
- break;
- case V4L2_MBUS_FMT_VYUY8_2X8:
- value = 0x00000100; /* Cr0, Y0, Cb0, Y1 */
- break;
- case V4L2_MBUS_FMT_YUYV8_2X8:
- value = 0x00000200; /* Y0, Cb0, Y1, Cr0 */
- break;
- case V4L2_MBUS_FMT_YVYU8_2X8:
- value = 0x00000300; /* Y0, Cr0, Y1, Cb0 */
- break;
- default:
- BUG();
- }
- }
-
- if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV21 ||
- icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV61)
- value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */
-
- value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
- value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
-
- if (pcdev->pdata->csi2) /* CSI2 mode */
- value |= 3 << 12;
- else if (pcdev->is_16bit)
- value |= 1 << 12;
- else if (pcdev->pdata->flags & SH_CEU_FLAG_LOWER_8BIT)
- value |= 2 << 12;
-
- ceu_write(pcdev, CAMCR, value);
-
- ceu_write(pcdev, CAPCR, 0x00300000);
-
- switch (pcdev->field) {
- case V4L2_FIELD_INTERLACED_TB:
- value = 0x101;
- break;
- case V4L2_FIELD_INTERLACED_BT:
- value = 0x102;
- break;
- default:
- value = 0;
- break;
- }
- ceu_write(pcdev, CAIFR, value);
-
- sh_mobile_ceu_set_rect(icd);
- mdelay(1);
-
- dev_geo(icd->parent, "CFLCR 0x%x\n", pcdev->cflcr);
- ceu_write(pcdev, CFLCR, pcdev->cflcr);
-
- /*
- * A few words about byte order (observed in Big Endian mode)
- *
- * In data fetch mode bytes are received in chunks of 8 bytes.
- * D0, D1, D2, D3, D4, D5, D6, D7 (D0 received first)
- *
- * The data is however by default written to memory in reverse order:
- * D7, D6, D5, D4, D3, D2, D1, D0 (D7 written to lowest byte)
- *
- * The lowest three bits of CDOCR allows us to do swapping,
- * using 7 we swap the data bytes to match the incoming order:
- * D0, D1, D2, D3, D4, D5, D6, D7
- */
- value = 0x00000007 | yuv_lineskip;
-
- ceu_write(pcdev, CDOCR, value);
- ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */
-
- capture_restore(pcdev, capsr);
-
- /* not in bundle mode: skip CBDSR, CDAYR2, CDACR2, CDBYR2, CDBCR2 */
- return 0;
-}
-
-static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
- unsigned char buswidth)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
- struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd);
- unsigned long common_flags = CEU_BUS_FLAGS;
- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
- int ret;
-
- ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
- if (!ret)
- common_flags = soc_mbus_config_compatible(&cfg,
- common_flags);
- else if (ret != -ENOIOCTLCMD)
- return ret;
-
- if (!common_flags || buswidth > 16)
- return -EINVAL;
-
- return 0;
-}
-
-static const struct soc_mbus_pixelfmt sh_mobile_ceu_formats[] = {
- {
- .fourcc = V4L2_PIX_FMT_NV12,
- .name = "NV12",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_1_5X8,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PLANAR_2Y_C,
- }, {
- .fourcc = V4L2_PIX_FMT_NV21,
- .name = "NV21",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_1_5X8,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PLANAR_2Y_C,
- }, {
- .fourcc = V4L2_PIX_FMT_NV16,
- .name = "NV16",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PLANAR_Y_C,
- }, {
- .fourcc = V4L2_PIX_FMT_NV61,
- .name = "NV61",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PLANAR_Y_C,
- },
-};
-
-/* This will be corrected as we get more formats */
-static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt)
-{
- return fmt->packing == SOC_MBUS_PACKING_NONE ||
- (fmt->bits_per_sample == 8 &&
- fmt->packing == SOC_MBUS_PACKING_1_5X8) ||
- (fmt->bits_per_sample == 8 &&
- fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
- (fmt->bits_per_sample > 8 &&
- fmt->packing == SOC_MBUS_PACKING_EXTEND16);
-}
-
-static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect);
-
-static struct soc_camera_device *ctrl_to_icd(struct v4l2_ctrl *ctrl)
-{
- return container_of(ctrl->handler, struct soc_camera_device,
- ctrl_handler);
-}
-
-static int sh_mobile_ceu_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct soc_camera_device *icd = ctrl_to_icd(ctrl);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
-
- switch (ctrl->id) {
- case V4L2_CID_SHARPNESS:
- switch (icd->current_fmt->host_fmt->fourcc) {
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- case V4L2_PIX_FMT_NV16:
- case V4L2_PIX_FMT_NV61:
- ceu_write(pcdev, CLFCR, !ctrl->val);
- return 0;
- }
- break;
- }
-
- return -EINVAL;
-}
-
-static const struct v4l2_ctrl_ops sh_mobile_ceu_ctrl_ops = {
- .s_ctrl = sh_mobile_ceu_s_ctrl,
-};
-
-static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int idx,
- struct soc_camera_format_xlate *xlate)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct device *dev = icd->parent;
- struct soc_camera_host *ici = to_soc_camera_host(dev);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
- int ret, k, n;
- int formats = 0;
- struct sh_mobile_ceu_cam *cam;
- enum v4l2_mbus_pixelcode code;
- const struct soc_mbus_pixelfmt *fmt;
-
- ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
- if (ret < 0)
- /* No more formats */
- return 0;
-
- fmt = soc_mbus_get_fmtdesc(code);
- if (!fmt) {
- dev_warn(dev, "unsupported format code #%u: %d\n", idx, code);
- return 0;
- }
-
- if (!pcdev->pdata->csi2) {
- /* Are there any restrictions in the CSI-2 case? */
- ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample);
- if (ret < 0)
- return 0;
- }
-
- if (!icd->host_priv) {
- struct v4l2_mbus_framefmt mf;
- struct v4l2_rect rect;
- int shift = 0;
-
- /* Add our control */
- v4l2_ctrl_new_std(&icd->ctrl_handler, &sh_mobile_ceu_ctrl_ops,
- V4L2_CID_SHARPNESS, 0, 1, 1, 0);
- if (icd->ctrl_handler.error)
- return icd->ctrl_handler.error;
-
- /* FIXME: subwindow is lost between close / open */
-
- /* Cache current client geometry */
- ret = client_g_rect(sd, &rect);
- if (ret < 0)
- return ret;
-
- /* First time */
- ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- /*
- * All currently existing CEU implementations support 2560x1920
- * or larger frames. If the sensor is proposing too big a frame,
- * don't bother with possibly supportred by the CEU larger
- * sizes, just try VGA multiples. If needed, this can be
- * adjusted in the future.
- */
- while ((mf.width > pcdev->max_width ||
- mf.height > pcdev->max_height) && shift < 4) {
- /* Try 2560x1920, 1280x960, 640x480, 320x240 */
- mf.width = 2560 >> shift;
- mf.height = 1920 >> shift;
- ret = v4l2_device_call_until_err(sd->v4l2_dev,
- soc_camera_grp_id(icd), video,
- s_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
- shift++;
- }
-
- if (shift == 4) {
- dev_err(dev, "Failed to configure the client below %ux%x\n",
- mf.width, mf.height);
- return -EIO;
- }
-
- dev_geo(dev, "camera fmt %ux%u\n", mf.width, mf.height);
-
- cam = kzalloc(sizeof(*cam), GFP_KERNEL);
- if (!cam)
- return -ENOMEM;
-
- /* We are called with current camera crop, initialise subrect with it */
- cam->rect = rect;
- cam->subrect = rect;
-
- cam->width = mf.width;
- cam->height = mf.height;
-
- icd->host_priv = cam;
- } else {
- cam = icd->host_priv;
- }
-
- /* Beginning of a pass */
- if (!idx)
- cam->extra_fmt = NULL;
-
- switch (code) {
- case V4L2_MBUS_FMT_UYVY8_2X8:
- case V4L2_MBUS_FMT_VYUY8_2X8:
- case V4L2_MBUS_FMT_YUYV8_2X8:
- case V4L2_MBUS_FMT_YVYU8_2X8:
- if (cam->extra_fmt)
- break;
-
- /*
- * Our case is simple so far: for any of the above four camera
- * formats we add all our four synthesized NV* formats, so,
- * just marking the device with a single flag suffices. If
- * the format generation rules are more complex, you would have
- * to actually hang your already added / counted formats onto
- * the host_priv pointer and check whether the format you're
- * going to add now is already there.
- */
- cam->extra_fmt = sh_mobile_ceu_formats;
-
- n = ARRAY_SIZE(sh_mobile_ceu_formats);
- formats += n;
- for (k = 0; xlate && k < n; k++) {
- xlate->host_fmt = &sh_mobile_ceu_formats[k];
- xlate->code = code;
- xlate++;
- dev_dbg(dev, "Providing format %s using code %d\n",
- sh_mobile_ceu_formats[k].name, code);
- }
- break;
- default:
- if (!sh_mobile_ceu_packing_supported(fmt))
- return 0;
- }
-
- /* Generic pass-through */
- formats++;
- if (xlate) {
- xlate->host_fmt = fmt;
- xlate->code = code;
- xlate++;
- dev_dbg(dev, "Providing format %s in pass-through mode\n",
- fmt->name);
- }
-
- return formats;
-}
-
-static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd)
-{
- kfree(icd->host_priv);
- icd->host_priv = NULL;
-}
-
-/* Check if any dimension of r1 is smaller than respective one of r2 */
-static bool is_smaller(struct v4l2_rect *r1, struct v4l2_rect *r2)
-{
- return r1->width < r2->width || r1->height < r2->height;
-}
-
-/* Check if r1 fails to cover r2 */
-static bool is_inside(struct v4l2_rect *r1, struct v4l2_rect *r2)
-{
- return r1->left > r2->left || r1->top > r2->top ||
- r1->left + r1->width < r2->left + r2->width ||
- r1->top + r1->height < r2->top + r2->height;
-}
-
-static unsigned int scale_down(unsigned int size, unsigned int scale)
-{
- return (size * 4096 + scale / 2) / scale;
-}
-
-static unsigned int calc_generic_scale(unsigned int input, unsigned int output)
-{
- return (input * 4096 + output / 2) / output;
-}
-
-/* Get and store current client crop */
-static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
-{
- struct v4l2_crop crop;
- struct v4l2_cropcap cap;
- int ret;
-
- crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- ret = v4l2_subdev_call(sd, video, g_crop, &crop);
- if (!ret) {
- *rect = crop.c;
- return ret;
- }
-
- /* Camera driver doesn't support .g_crop(), assume default rectangle */
- cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- ret = v4l2_subdev_call(sd, video, cropcap, &cap);
- if (!ret)
- *rect = cap.defrect;
-
- return ret;
-}
-
-/* Client crop has changed, update our sub-rectangle to remain within the area */
-static void update_subrect(struct sh_mobile_ceu_cam *cam)
-{
- struct v4l2_rect *rect = &cam->rect, *subrect = &cam->subrect;
-
- if (rect->width < subrect->width)
- subrect->width = rect->width;
-
- if (rect->height < subrect->height)
- subrect->height = rect->height;
-
- if (rect->left > subrect->left)
- subrect->left = rect->left;
- else if (rect->left + rect->width >
- subrect->left + subrect->width)
- subrect->left = rect->left + rect->width -
- subrect->width;
-
- if (rect->top > subrect->top)
- subrect->top = rect->top;
- else if (rect->top + rect->height >
- subrect->top + subrect->height)
- subrect->top = rect->top + rect->height -
- subrect->height;
-}
-
-/*
- * The common for both scaling and cropping iterative approach is:
- * 1. try if the client can produce exactly what requested by the user
- * 2. if (1) failed, try to double the client image until we get one big enough
- * 3. if (2) failed, try to request the maximum image
- */
-static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop,
- struct v4l2_crop *cam_crop)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
- struct device *dev = sd->v4l2_dev->dev;
- struct sh_mobile_ceu_cam *cam = icd->host_priv;
- struct v4l2_cropcap cap;
- int ret;
- unsigned int width, height;
-
- v4l2_subdev_call(sd, video, s_crop, crop);
- ret = client_g_rect(sd, cam_rect);
- if (ret < 0)
- return ret;
-
- /*
- * Now cam_crop contains the current camera input rectangle, and it must
- * be within camera cropcap bounds
- */
- if (!memcmp(rect, cam_rect, sizeof(*rect))) {
- /* Even if camera S_CROP failed, but camera rectangle matches */
- dev_dbg(dev, "Camera S_CROP successful for %dx%d@%d:%d\n",
- rect->width, rect->height, rect->left, rect->top);
- cam->rect = *cam_rect;
- return 0;
- }
-
- /* Try to fix cropping, that camera hasn't managed to set */
- dev_geo(dev, "Fix camera S_CROP for %dx%d@%d:%d to %dx%d@%d:%d\n",
- cam_rect->width, cam_rect->height,
- cam_rect->left, cam_rect->top,
- rect->width, rect->height, rect->left, rect->top);
-
- /* We need sensor maximum rectangle */
- ret = v4l2_subdev_call(sd, video, cropcap, &cap);
- if (ret < 0)
- return ret;
-
- /* Put user requested rectangle within sensor bounds */
- soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2,
- cap.bounds.width);
- soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4,
- cap.bounds.height);
-
- /*
- * Popular special case - some cameras can only handle fixed sizes like
- * QVGA, VGA,... Take care to avoid infinite loop.
- */
- width = max(cam_rect->width, 2);
- height = max(cam_rect->height, 2);
-
- /*
- * Loop as long as sensor is not covering the requested rectangle and
- * is still within its bounds
- */
- while (!ret && (is_smaller(cam_rect, rect) ||
- is_inside(cam_rect, rect)) &&
- (cap.bounds.width > width || cap.bounds.height > height)) {
-
- width *= 2;
- height *= 2;
-
- cam_rect->width = width;
- cam_rect->height = height;
-
- /*
- * We do not know what capabilities the camera has to set up
- * left and top borders. We could try to be smarter in iterating
- * them, e.g., if camera current left is to the right of the
- * target left, set it to the middle point between the current
- * left and minimum left. But that would add too much
- * complexity: we would have to iterate each border separately.
- * Instead we just drop to the left and top bounds.
- */
- if (cam_rect->left > rect->left)
- cam_rect->left = cap.bounds.left;
-
- if (cam_rect->left + cam_rect->width < rect->left + rect->width)
- cam_rect->width = rect->left + rect->width -
- cam_rect->left;
-
- if (cam_rect->top > rect->top)
- cam_rect->top = cap.bounds.top;
-
- if (cam_rect->top + cam_rect->height < rect->top + rect->height)
- cam_rect->height = rect->top + rect->height -
- cam_rect->top;
-
- v4l2_subdev_call(sd, video, s_crop, cam_crop);
- ret = client_g_rect(sd, cam_rect);
- dev_geo(dev, "Camera S_CROP %d for %dx%d@%d:%d\n", ret,
- cam_rect->width, cam_rect->height,
- cam_rect->left, cam_rect->top);
- }
-
- /* S_CROP must not modify the rectangle */
- if (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) {
- /*
- * The camera failed to configure a suitable cropping,
- * we cannot use the current rectangle, set to max
- */
- *cam_rect = cap.bounds;
- v4l2_subdev_call(sd, video, s_crop, cam_crop);
- ret = client_g_rect(sd, cam_rect);
- dev_geo(dev, "Camera S_CROP %d for max %dx%d@%d:%d\n", ret,
- cam_rect->width, cam_rect->height,
- cam_rect->left, cam_rect->top);
- }
-
- if (!ret) {
- cam->rect = *cam_rect;
- update_subrect(cam);
- }
-
- return ret;
-}
-
-/* Iterative s_mbus_fmt, also updates cached client crop on success */
-static int client_s_fmt(struct soc_camera_device *icd,
- struct v4l2_mbus_framefmt *mf, bool ceu_can_scale)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
- struct sh_mobile_ceu_cam *cam = icd->host_priv;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct device *dev = icd->parent;
- unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
- unsigned int max_width, max_height;
- struct v4l2_cropcap cap;
- bool ceu_1to1;
- int ret;
-
- ret = v4l2_device_call_until_err(sd->v4l2_dev,
- soc_camera_grp_id(icd), video,
- s_mbus_fmt, mf);
- if (ret < 0)
- return ret;
-
- dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
-
- if (width == mf->width && height == mf->height) {
- /* Perfect! The client has done it all. */
- ceu_1to1 = true;
- goto update_cache;
- }
-
- ceu_1to1 = false;
- if (!ceu_can_scale)
- goto update_cache;
-
- cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- ret = v4l2_subdev_call(sd, video, cropcap, &cap);
- if (ret < 0)
- return ret;
-
- max_width = min(cap.bounds.width, pcdev->max_width);
- max_height = min(cap.bounds.height, pcdev->max_height);
-
- /* Camera set a format, but geometry is not precise, try to improve */
- tmp_w = mf->width;
- tmp_h = mf->height;
-
- /* width <= max_width && height <= max_height - guaranteed by try_fmt */
- while ((width > tmp_w || height > tmp_h) &&
- tmp_w < max_width && tmp_h < max_height) {
- tmp_w = min(2 * tmp_w, max_width);
- tmp_h = min(2 * tmp_h, max_height);
- mf->width = tmp_w;
- mf->height = tmp_h;
- ret = v4l2_device_call_until_err(sd->v4l2_dev,
- soc_camera_grp_id(icd), video,
- s_mbus_fmt, mf);
- dev_geo(dev, "Camera scaled to %ux%u\n",
- mf->width, mf->height);
- if (ret < 0) {
- /* This shouldn't happen */
- dev_err(dev, "Client failed to set format: %d\n", ret);
- return ret;
- }
- }
-
-update_cache:
- /* Update cache */
- ret = client_g_rect(sd, &cam->rect);
- if (ret < 0)
- return ret;
-
- if (ceu_1to1)
- cam->subrect = cam->rect;
- else
- update_subrect(cam);
-
- return 0;
-}
-
-/**
- * @width - on output: user width, mapped back to input
- * @height - on output: user height, mapped back to input
- * @mf - in- / output camera output window
- */
-static int client_scale(struct soc_camera_device *icd,
- struct v4l2_mbus_framefmt *mf,
- unsigned int *width, unsigned int *height,
- bool ceu_can_scale)
-{
- struct sh_mobile_ceu_cam *cam = icd->host_priv;
- struct device *dev = icd->parent;
- struct v4l2_mbus_framefmt mf_tmp = *mf;
- unsigned int scale_h, scale_v;
- int ret;
-
- /*
- * 5. Apply iterative camera S_FMT for camera user window (also updates
- * client crop cache and the imaginary sub-rectangle).
- */
- ret = client_s_fmt(icd, &mf_tmp, ceu_can_scale);
- if (ret < 0)
- return ret;
-
- dev_geo(dev, "5: camera scaled to %ux%u\n",
- mf_tmp.width, mf_tmp.height);
-
- /* 6. Retrieve camera output window (g_fmt) */
-
- /* unneeded - it is already in "mf_tmp" */
-
- /* 7. Calculate new client scales. */
- scale_h = calc_generic_scale(cam->rect.width, mf_tmp.width);
- scale_v = calc_generic_scale(cam->rect.height, mf_tmp.height);
-
- mf->width = mf_tmp.width;
- mf->height = mf_tmp.height;
- mf->colorspace = mf_tmp.colorspace;
-
- /*
- * 8. Calculate new CEU crop - apply camera scales to previously
- * updated "effective" crop.
- */
- *width = scale_down(cam->subrect.width, scale_h);
- *height = scale_down(cam->subrect.height, scale_v);
-
- dev_geo(dev, "8: new client sub-window %ux%u\n", *width, *height);
-
- return 0;
-}
-
-/*
- * CEU can scale and crop, but we don't want to waste bandwidth and kill the
- * framerate by always requesting the maximum image from the client. See
- * Documentation/video4linux/sh_mobile_ceu_camera.txt for a description of
- * scaling and cropping algorithms and for the meaning of referenced here steps.
- */
-static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
- struct v4l2_crop *a)
-{
- struct v4l2_rect *rect = &a->c;
- struct device *dev = icd->parent;
- struct soc_camera_host *ici = to_soc_camera_host(dev);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
- struct v4l2_crop cam_crop;
- struct sh_mobile_ceu_cam *cam = icd->host_priv;
- struct v4l2_rect *cam_rect = &cam_crop.c;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct v4l2_mbus_framefmt mf;
- unsigned int scale_cam_h, scale_cam_v, scale_ceu_h, scale_ceu_v,
- out_width, out_height;
- int interm_width, interm_height;
- u32 capsr, cflcr;
- int ret;
-
- dev_geo(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height,
- rect->left, rect->top);
-
- /* During camera cropping its output window can change too, stop CEU */
- capsr = capture_save_reset(pcdev);
- dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr);
-
- /*
- * 1. - 2. Apply iterative camera S_CROP for new input window, read back
- * actual camera rectangle.
- */
- ret = client_s_crop(icd, a, &cam_crop);
- if (ret < 0)
- return ret;
-
- dev_geo(dev, "1-2: camera cropped to %ux%u@%u:%u\n",
- cam_rect->width, cam_rect->height,
- cam_rect->left, cam_rect->top);
-
- /* On success cam_crop contains current camera crop */
-
- /* 3. Retrieve camera output window */
- ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- if (mf.width > pcdev->max_width || mf.height > pcdev->max_height)
- return -EINVAL;
-
- /* 4. Calculate camera scales */
- scale_cam_h = calc_generic_scale(cam_rect->width, mf.width);
- scale_cam_v = calc_generic_scale(cam_rect->height, mf.height);
-
- /* Calculate intermediate window */
- interm_width = scale_down(rect->width, scale_cam_h);
- interm_height = scale_down(rect->height, scale_cam_v);
-
- if (interm_width < icd->user_width) {
- u32 new_scale_h;
-
- new_scale_h = calc_generic_scale(rect->width, icd->user_width);
-
- mf.width = scale_down(cam_rect->width, new_scale_h);
- }
-
- if (interm_height < icd->user_height) {
- u32 new_scale_v;
-
- new_scale_v = calc_generic_scale(rect->height, icd->user_height);
-
- mf.height = scale_down(cam_rect->height, new_scale_v);
- }
-
- if (interm_width < icd->user_width || interm_height < icd->user_height) {
- ret = v4l2_device_call_until_err(sd->v4l2_dev,
- soc_camera_grp_id(icd), video,
- s_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- dev_geo(dev, "New camera output %ux%u\n", mf.width, mf.height);
- scale_cam_h = calc_generic_scale(cam_rect->width, mf.width);
- scale_cam_v = calc_generic_scale(cam_rect->height, mf.height);
- interm_width = scale_down(rect->width, scale_cam_h);
- interm_height = scale_down(rect->height, scale_cam_v);
- }
-
- /* Cache camera output window */
- cam->width = mf.width;
- cam->height = mf.height;
-
- if (pcdev->image_mode) {
- out_width = min(interm_width, icd->user_width);
- out_height = min(interm_height, icd->user_height);
- } else {
- out_width = interm_width;
- out_height = interm_height;
- }
-
- /*
- * 5. Calculate CEU scales from camera scales from results of (5) and
- * the user window
- */
- scale_ceu_h = calc_scale(interm_width, &out_width);
- scale_ceu_v = calc_scale(interm_height, &out_height);
-
- dev_geo(dev, "5: CEU scales %u:%u\n", scale_ceu_h, scale_ceu_v);
-
- /* Apply CEU scales. */
- cflcr = scale_ceu_h | (scale_ceu_v << 16);
- if (cflcr != pcdev->cflcr) {
- pcdev->cflcr = cflcr;
- ceu_write(pcdev, CFLCR, cflcr);
- }
-
- icd->user_width = out_width & ~3;
- icd->user_height = out_height & ~3;
- /* Offsets are applied at the CEU scaling filter input */
- cam->ceu_left = scale_down(rect->left - cam_rect->left, scale_cam_h) & ~1;
- cam->ceu_top = scale_down(rect->top - cam_rect->top, scale_cam_v) & ~1;
-
- /* 6. Use CEU cropping to crop to the new window. */
- sh_mobile_ceu_set_rect(icd);
-
- cam->subrect = *rect;
-
- dev_geo(dev, "6: CEU cropped to %ux%u@%u:%u\n",
- icd->user_width, icd->user_height,
- cam->ceu_left, cam->ceu_top);
-
- /* Restore capture. The CE bit can be cleared by the hardware */
- if (pcdev->active)
- capsr |= 1;
- capture_restore(pcdev, capsr);
-
- /* Even if only camera cropping succeeded */
- return ret;
-}
-
-static int sh_mobile_ceu_get_crop(struct soc_camera_device *icd,
- struct v4l2_crop *a)
-{
- struct sh_mobile_ceu_cam *cam = icd->host_priv;
-
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->c = cam->subrect;
-
- return 0;
-}
-
-/*
- * Calculate real client output window by applying new scales to the current
- * client crop. New scales are calculated from the requested output format and
- * CEU crop, mapped backed onto the client input (subrect).
- */
-static void calculate_client_output(struct soc_camera_device *icd,
- const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf)
-{
- struct sh_mobile_ceu_cam *cam = icd->host_priv;
- struct device *dev = icd->parent;
- struct v4l2_rect *cam_subrect = &cam->subrect;
- unsigned int scale_v, scale_h;
-
- if (cam_subrect->width == cam->rect.width &&
- cam_subrect->height == cam->rect.height) {
- /* No sub-cropping */
- mf->width = pix->width;
- mf->height = pix->height;
- return;
- }
-
- /* 1.-2. Current camera scales and subwin - cached. */
-
- dev_geo(dev, "2: subwin %ux%u@%u:%u\n",
- cam_subrect->width, cam_subrect->height,
- cam_subrect->left, cam_subrect->top);
-
- /*
- * 3. Calculate new combined scales from input sub-window to requested
- * user window.
- */
-
- /*
- * TODO: CEU cannot scale images larger than VGA to smaller than SubQCIF
- * (128x96) or larger than VGA
- */
- scale_h = calc_generic_scale(cam_subrect->width, pix->width);
- scale_v = calc_generic_scale(cam_subrect->height, pix->height);
-
- dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
-
- /*
- * 4. Calculate desired client output window by applying combined scales
- * to client (real) input window.
- */
- mf->width = scale_down(cam->rect.width, scale_h);
- mf->height = scale_down(cam->rect.height, scale_v);
-}
-
-/* Similar to set_crop multistage iterative algorithm */
-static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct device *dev = icd->parent;
- struct soc_camera_host *ici = to_soc_camera_host(dev);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
- struct sh_mobile_ceu_cam *cam = icd->host_priv;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- __u32 pixfmt = pix->pixelformat;
- const struct soc_camera_format_xlate *xlate;
- /* Keep Compiler Happy */
- unsigned int ceu_sub_width = 0, ceu_sub_height = 0;
- u16 scale_v, scale_h;
- int ret;
- bool image_mode;
- enum v4l2_field field;
-
- switch (pix->field) {
- default:
- pix->field = V4L2_FIELD_NONE;
- /* fall-through */
- case V4L2_FIELD_INTERLACED_TB:
- case V4L2_FIELD_INTERLACED_BT:
- case V4L2_FIELD_NONE:
- field = pix->field;
- break;
- case V4L2_FIELD_INTERLACED:
- field = V4L2_FIELD_INTERLACED_TB;
- break;
- }
-
- xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
- if (!xlate) {
- dev_warn(dev, "Format %x not found\n", pixfmt);
- return -EINVAL;
- }
-
- /* 1.-4. Calculate desired client output geometry */
- calculate_client_output(icd, pix, &mf);
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- switch (pixfmt) {
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- case V4L2_PIX_FMT_NV16:
- case V4L2_PIX_FMT_NV61:
- image_mode = true;
- break;
- default:
- image_mode = false;
- }
-
- dev_geo(dev, "S_FMT(pix=0x%x, fld 0x%x, code 0x%x, %ux%u)\n", pixfmt, mf.field, mf.code,
- pix->width, pix->height);
-
- dev_geo(dev, "4: request camera output %ux%u\n", mf.width, mf.height);
-
- /* 5. - 9. */
- ret = client_scale(icd, &mf, &ceu_sub_width, &ceu_sub_height,
- image_mode && V4L2_FIELD_NONE == field);
-
- dev_geo(dev, "5-9: client scale return %d\n", ret);
-
- /* Done with the camera. Now see if we can improve the result */
-
- dev_geo(dev, "fmt %ux%u, requested %ux%u\n",
- mf.width, mf.height, pix->width, pix->height);
- if (ret < 0)
- return ret;
-
- if (mf.code != xlate->code)
- return -EINVAL;
-
- /* 9. Prepare CEU crop */
- cam->width = mf.width;
- cam->height = mf.height;
-
- /* 10. Use CEU scaling to scale to the requested user window. */
-
- /* We cannot scale up */
- if (pix->width > ceu_sub_width)
- ceu_sub_width = pix->width;
-
- if (pix->height > ceu_sub_height)
- ceu_sub_height = pix->height;
-
- pix->colorspace = mf.colorspace;
-
- if (image_mode) {
- /* Scale pix->{width x height} down to width x height */
- scale_h = calc_scale(ceu_sub_width, &pix->width);
- scale_v = calc_scale(ceu_sub_height, &pix->height);
- } else {
- pix->width = ceu_sub_width;
- pix->height = ceu_sub_height;
- scale_h = 0;
- scale_v = 0;
- }
-
- pcdev->cflcr = scale_h | (scale_v << 16);
-
- /*
- * We have calculated CFLCR, the actual configuration will be performed
- * in sh_mobile_ceu_set_bus_param()
- */
-
- dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n",
- ceu_sub_width, scale_h, pix->width,
- ceu_sub_height, scale_v, pix->height);
-
- cam->code = xlate->code;
- icd->current_fmt = xlate;
-
- pcdev->field = field;
- pcdev->image_mode = image_mode;
-
- /* CFSZR requirement */
- pix->width &= ~3;
- pix->height &= ~3;
-
- return 0;
-}
-
-#define CEU_CHDW_MAX 8188U /* Maximum line stride */
-
-static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct v4l2_mbus_framefmt mf;
- __u32 pixfmt = pix->pixelformat;
- int width, height;
- int ret;
-
- dev_geo(icd->parent, "TRY_FMT(pix=0x%x, %ux%u)\n",
- pixfmt, pix->width, pix->height);
-
- xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
- if (!xlate) {
- xlate = icd->current_fmt;
- dev_dbg(icd->parent, "Format %x not found, keeping %x\n",
- pixfmt, xlate->host_fmt->fourcc);
- pixfmt = xlate->host_fmt->fourcc;
- pix->pixelformat = pixfmt;
- pix->colorspace = icd->colorspace;
- }
-
- /* FIXME: calculate using depth and bus width */
-
- /* CFSZR requires height and width to be 4-pixel aligned */
- v4l_bound_align_image(&pix->width, 2, pcdev->max_width, 2,
- &pix->height, 4, pcdev->max_height, 2, 0);
-
- width = pix->width;
- height = pix->height;
-
- /* limit to sensor capabilities */
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.code = xlate->code;
- mf.colorspace = pix->colorspace;
-
- ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
- video, try_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
-
- switch (pixfmt) {
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- case V4L2_PIX_FMT_NV16:
- case V4L2_PIX_FMT_NV61:
- /* FIXME: check against rect_max after converting soc-camera */
- /* We can scale precisely, need a bigger image from camera */
- if (pix->width < width || pix->height < height) {
- /*
- * We presume, the sensor behaves sanely, i.e., if
- * requested a bigger rectangle, it will not return a
- * smaller one.
- */
- mf.width = pcdev->max_width;
- mf.height = pcdev->max_height;
- ret = v4l2_device_call_until_err(sd->v4l2_dev,
- soc_camera_grp_id(icd), video,
- try_mbus_fmt, &mf);
- if (ret < 0) {
- /* Shouldn't actually happen... */
- dev_err(icd->parent,
- "FIXME: client try_fmt() = %d\n", ret);
- return ret;
- }
- }
- /* We will scale exactly */
- if (mf.width > width)
- pix->width = width;
- if (mf.height > height)
- pix->height = height;
-
- pix->bytesperline = max(pix->bytesperline, pix->width);
- pix->bytesperline = min(pix->bytesperline, CEU_CHDW_MAX);
- pix->bytesperline &= ~3;
- break;
-
- default:
- /* Configurable stride isn't supported in pass-through mode. */
- pix->bytesperline = 0;
- }
-
- pix->width &= ~3;
- pix->height &= ~3;
- pix->sizeimage = 0;
-
- dev_geo(icd->parent, "%s(): return %d, fmt 0x%x, %ux%u\n",
- __func__, ret, pix->pixelformat, pix->width, pix->height);
-
- return ret;
-}
-
-static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd,
- struct v4l2_crop *a)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
- u32 out_width = icd->user_width, out_height = icd->user_height;
- int ret;
-
- /* Freeze queue */
- pcdev->frozen = 1;
- /* Wait for frame */
- ret = wait_for_completion_interruptible(&pcdev->complete);
- /* Stop the client */
- ret = v4l2_subdev_call(sd, video, s_stream, 0);
- if (ret < 0)
- dev_warn(icd->parent,
- "Client failed to stop the stream: %d\n", ret);
- else
- /* Do the crop, if it fails, there's nothing more we can do */
- sh_mobile_ceu_set_crop(icd, a);
-
- dev_geo(icd->parent, "Output after crop: %ux%u\n", icd->user_width, icd->user_height);
-
- if (icd->user_width != out_width || icd->user_height != out_height) {
- struct v4l2_format f = {
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- .fmt.pix = {
- .width = out_width,
- .height = out_height,
- .pixelformat = icd->current_fmt->host_fmt->fourcc,
- .field = pcdev->field,
- .colorspace = icd->colorspace,
- },
- };
- ret = sh_mobile_ceu_set_fmt(icd, &f);
- if (!ret && (out_width != f.fmt.pix.width ||
- out_height != f.fmt.pix.height))
- ret = -EINVAL;
- if (!ret) {
- icd->user_width = out_width & ~3;
- icd->user_height = out_height & ~3;
- ret = sh_mobile_ceu_set_bus_param(icd);
- }
- }
-
- /* Thaw the queue */
- pcdev->frozen = 0;
- spin_lock_irq(&pcdev->lock);
- sh_mobile_ceu_capture(pcdev);
- spin_unlock_irq(&pcdev->lock);
- /* Start the client */
- ret = v4l2_subdev_call(sd, video, s_stream, 1);
- return ret;
-}
-
-static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt)
-{
- struct soc_camera_device *icd = file->private_data;
-
- return vb2_poll(&icd->vb2_vidq, file, pt);
-}
-
-static int sh_mobile_ceu_querycap(struct soc_camera_host *ici,
- struct v4l2_capability *cap)
-{
- strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card));
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
- return 0;
-}
-
-static int sh_mobile_ceu_init_videobuf(struct vb2_queue *q,
- struct soc_camera_device *icd)
-{
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- q->io_modes = VB2_MMAP | VB2_USERPTR;
- q->drv_priv = icd;
- q->ops = &sh_mobile_ceu_videobuf_ops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->buf_struct_size = sizeof(struct sh_mobile_ceu_buffer);
-
- return vb2_queue_init(q);
-}
-
-static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
- .owner = THIS_MODULE,
- .add = sh_mobile_ceu_add_device,
- .remove = sh_mobile_ceu_remove_device,
- .get_formats = sh_mobile_ceu_get_formats,
- .put_formats = sh_mobile_ceu_put_formats,
- .get_crop = sh_mobile_ceu_get_crop,
- .set_crop = sh_mobile_ceu_set_crop,
- .set_livecrop = sh_mobile_ceu_set_livecrop,
- .set_fmt = sh_mobile_ceu_set_fmt,
- .try_fmt = sh_mobile_ceu_try_fmt,
- .poll = sh_mobile_ceu_poll,
- .querycap = sh_mobile_ceu_querycap,
- .set_bus_param = sh_mobile_ceu_set_bus_param,
- .init_videobuf2 = sh_mobile_ceu_init_videobuf,
-};
-
-struct bus_wait {
- struct notifier_block notifier;
- struct completion completion;
- struct device *dev;
-};
-
-static int bus_notify(struct notifier_block *nb,
- unsigned long action, void *data)
-{
- struct device *dev = data;
- struct bus_wait *wait = container_of(nb, struct bus_wait, notifier);
-
- if (wait->dev != dev)
- return NOTIFY_DONE;
-
- switch (action) {
- case BUS_NOTIFY_UNBOUND_DRIVER:
- /* Protect from module unloading */
- wait_for_completion(&wait->completion);
- return NOTIFY_OK;
- }
- return NOTIFY_DONE;
-}
-
-static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
-{
- struct sh_mobile_ceu_dev *pcdev;
- struct resource *res;
- void __iomem *base;
- unsigned int irq;
- int err = 0;
- struct bus_wait wait = {
- .completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion),
- .notifier.notifier_call = bus_notify,
- };
- struct sh_mobile_ceu_companion *csi2;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- irq = platform_get_irq(pdev, 0);
- if (!res || (int)irq <= 0) {
- dev_err(&pdev->dev, "Not enough CEU platform resources.\n");
- err = -ENODEV;
- goto exit;
- }
-
- pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
- if (!pcdev) {
- dev_err(&pdev->dev, "Could not allocate pcdev\n");
- err = -ENOMEM;
- goto exit;
- }
-
- INIT_LIST_HEAD(&pcdev->capture);
- spin_lock_init(&pcdev->lock);
- init_completion(&pcdev->complete);
-
- pcdev->pdata = pdev->dev.platform_data;
- if (!pcdev->pdata) {
- err = -EINVAL;
- dev_err(&pdev->dev, "CEU platform data not set.\n");
- goto exit_kfree;
- }
-
- pcdev->max_width = pcdev->pdata->max_width ? : 2560;
- pcdev->max_height = pcdev->pdata->max_height ? : 1920;
-
- base = ioremap_nocache(res->start, resource_size(res));
- if (!base) {
- err = -ENXIO;
- dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n");
- goto exit_kfree;
- }
-
- pcdev->irq = irq;
- pcdev->base = base;
- pcdev->video_limit = 0; /* only enabled if second resource exists */
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (res) {
- err = dma_declare_coherent_memory(&pdev->dev, res->start,
- res->start,
- resource_size(res),
- DMA_MEMORY_MAP |
- DMA_MEMORY_EXCLUSIVE);
- if (!err) {
- dev_err(&pdev->dev, "Unable to declare CEU memory.\n");
- err = -ENXIO;
- goto exit_iounmap;
- }
-
- pcdev->video_limit = resource_size(res);
- }
-
- /* request irq */
- err = request_irq(pcdev->irq, sh_mobile_ceu_irq, IRQF_DISABLED,
- dev_name(&pdev->dev), pcdev);
- if (err) {
- dev_err(&pdev->dev, "Unable to register CEU interrupt.\n");
- goto exit_release_mem;
- }
-
- pm_suspend_ignore_children(&pdev->dev, true);
- pm_runtime_enable(&pdev->dev);
- pm_runtime_resume(&pdev->dev);
-
- pcdev->ici.priv = pcdev;
- pcdev->ici.v4l2_dev.dev = &pdev->dev;
- pcdev->ici.nr = pdev->id;
- pcdev->ici.drv_name = dev_name(&pdev->dev);
- pcdev->ici.ops = &sh_mobile_ceu_host_ops;
- pcdev->ici.capabilities = SOCAM_HOST_CAP_STRIDE;
-
- pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
- if (IS_ERR(pcdev->alloc_ctx)) {
- err = PTR_ERR(pcdev->alloc_ctx);
- goto exit_free_clk;
- }
-
- err = soc_camera_host_register(&pcdev->ici);
- if (err)
- goto exit_free_ctx;
-
- /* CSI2 interfacing */
- csi2 = pcdev->pdata->csi2;
- if (csi2) {
- struct platform_device *csi2_pdev =
- platform_device_alloc("sh-mobile-csi2", csi2->id);
- struct sh_csi2_pdata *csi2_pdata = csi2->platform_data;
-
- if (!csi2_pdev) {
- err = -ENOMEM;
- goto exit_host_unregister;
- }
-
- pcdev->csi2_pdev = csi2_pdev;
-
- err = platform_device_add_data(csi2_pdev, csi2_pdata, sizeof(*csi2_pdata));
- if (err < 0)
- goto exit_pdev_put;
-
- csi2_pdata = csi2_pdev->dev.platform_data;
- csi2_pdata->v4l2_dev = &pcdev->ici.v4l2_dev;
-
- csi2_pdev->resource = csi2->resource;
- csi2_pdev->num_resources = csi2->num_resources;
-
- err = platform_device_add(csi2_pdev);
- if (err < 0)
- goto exit_pdev_put;
-
- wait.dev = &csi2_pdev->dev;
-
- err = bus_register_notifier(&platform_bus_type, &wait.notifier);
- if (err < 0)
- goto exit_pdev_unregister;
-
- /*
- * From this point the driver module will not unload, until
- * we complete the completion.
- */
-
- if (!csi2_pdev->dev.driver) {
- complete(&wait.completion);
- /* Either too late, or probing failed */
- bus_unregister_notifier(&platform_bus_type, &wait.notifier);
- err = -ENXIO;
- goto exit_pdev_unregister;
- }
-
- /*
- * The module is still loaded, in the worst case it is hanging
- * in device release on our completion. So, _now_ dereferencing
- * the "owner" is safe!
- */
-
- err = try_module_get(csi2_pdev->dev.driver->owner);
-
- /* Let notifier complete, if it has been locked */
- complete(&wait.completion);
- bus_unregister_notifier(&platform_bus_type, &wait.notifier);
- if (!err) {
- err = -ENODEV;
- goto exit_pdev_unregister;
- }
- }
-
- return 0;
-
-exit_pdev_unregister:
- platform_device_del(pcdev->csi2_pdev);
-exit_pdev_put:
- pcdev->csi2_pdev->resource = NULL;
- platform_device_put(pcdev->csi2_pdev);
-exit_host_unregister:
- soc_camera_host_unregister(&pcdev->ici);
-exit_free_ctx:
- vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
-exit_free_clk:
- pm_runtime_disable(&pdev->dev);
- free_irq(pcdev->irq, pcdev);
-exit_release_mem:
- if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
- dma_release_declared_memory(&pdev->dev);
-exit_iounmap:
- iounmap(base);
-exit_kfree:
- kfree(pcdev);
-exit:
- return err;
-}
-
-static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
-{
- struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
- struct sh_mobile_ceu_dev *pcdev = container_of(soc_host,
- struct sh_mobile_ceu_dev, ici);
- struct platform_device *csi2_pdev = pcdev->csi2_pdev;
-
- soc_camera_host_unregister(soc_host);
- pm_runtime_disable(&pdev->dev);
- free_irq(pcdev->irq, pcdev);
- if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
- dma_release_declared_memory(&pdev->dev);
- iounmap(pcdev->base);
- vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
- if (csi2_pdev && csi2_pdev->dev.driver) {
- struct module *csi2_drv = csi2_pdev->dev.driver->owner;
- platform_device_del(csi2_pdev);
- csi2_pdev->resource = NULL;
- platform_device_put(csi2_pdev);
- module_put(csi2_drv);
- }
- kfree(pcdev);
-
- return 0;
-}
-
-static int sh_mobile_ceu_runtime_nop(struct device *dev)
-{
- /* Runtime PM callback shared between ->runtime_suspend()
- * and ->runtime_resume(). Simply returns success.
- *
- * This driver re-initializes all registers after
- * pm_runtime_get_sync() anyway so there is no need
- * to save and restore registers here.
- */
- return 0;
-}
-
-static const struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = {
- .runtime_suspend = sh_mobile_ceu_runtime_nop,
- .runtime_resume = sh_mobile_ceu_runtime_nop,
-};
-
-static struct platform_driver sh_mobile_ceu_driver = {
- .driver = {
- .name = "sh_mobile_ceu",
- .pm = &sh_mobile_ceu_dev_pm_ops,
- },
- .probe = sh_mobile_ceu_probe,
- .remove = __devexit_p(sh_mobile_ceu_remove),
-};
-
-static int __init sh_mobile_ceu_init(void)
-{
- /* Whatever return code */
- request_module("sh_mobile_csi2");
- return platform_driver_register(&sh_mobile_ceu_driver);
-}
-
-static void __exit sh_mobile_ceu_exit(void)
-{
- platform_driver_unregister(&sh_mobile_ceu_driver);
-}
-
-module_init(sh_mobile_ceu_init);
-module_exit(sh_mobile_ceu_exit);
-
-MODULE_DESCRIPTION("SuperH Mobile CEU driver");
-MODULE_AUTHOR("Magnus Damm");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.6");
-MODULE_ALIAS("platform:sh_mobile_ceu");
diff --git a/drivers/media/video/sh_mobile_csi2.c b/drivers/media/video/sh_mobile_csi2.c
deleted file mode 100644
index 05286500b4d..00000000000
--- a/drivers/media/video/sh_mobile_csi2.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Driver for the SH-Mobile MIPI CSI-2 unit
- *
- * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/module.h>
-
-#include <media/sh_mobile_ceu.h>
-#include <media/sh_mobile_csi2.h>
-#include <media/soc_camera.h>
-#include <media/soc_mediabus.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-mediabus.h>
-#include <media/v4l2-subdev.h>
-
-#define SH_CSI2_TREF 0x00
-#define SH_CSI2_SRST 0x04
-#define SH_CSI2_PHYCNT 0x08
-#define SH_CSI2_CHKSUM 0x0C
-#define SH_CSI2_VCDT 0x10
-
-struct sh_csi2 {
- struct v4l2_subdev subdev;
- struct list_head list;
- unsigned int irq;
- unsigned long mipi_flags;
- void __iomem *base;
- struct platform_device *pdev;
- struct sh_csi2_client_config *client;
-};
-
-static int sh_csi2_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev);
- struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data;
-
- if (mf->width > 8188)
- mf->width = 8188;
- else if (mf->width & 1)
- mf->width &= ~1;
-
- switch (pdata->type) {
- case SH_CSI2C:
- switch (mf->code) {
- case V4L2_MBUS_FMT_UYVY8_2X8: /* YUV422 */
- case V4L2_MBUS_FMT_YUYV8_1_5X8: /* YUV420 */
- case V4L2_MBUS_FMT_Y8_1X8: /* RAW8 */
- case V4L2_MBUS_FMT_SBGGR8_1X8:
- case V4L2_MBUS_FMT_SGRBG8_1X8:
- break;
- default:
- /* All MIPI CSI-2 devices must support one of primary formats */
- mf->code = V4L2_MBUS_FMT_YUYV8_2X8;
- }
- break;
- case SH_CSI2I:
- switch (mf->code) {
- case V4L2_MBUS_FMT_Y8_1X8: /* RAW8 */
- case V4L2_MBUS_FMT_SBGGR8_1X8:
- case V4L2_MBUS_FMT_SGRBG8_1X8:
- case V4L2_MBUS_FMT_SBGGR10_1X10: /* RAW10 */
- case V4L2_MBUS_FMT_SBGGR12_1X12: /* RAW12 */
- break;
- default:
- /* All MIPI CSI-2 devices must support one of primary formats */
- mf->code = V4L2_MBUS_FMT_SBGGR8_1X8;
- }
- break;
- }
-
- return 0;
-}
-
-/*
- * We have done our best in try_fmt to try and tell the sensor, which formats
- * we support. If now the configuration is unsuitable for us we can only
- * error out.
- */
-static int sh_csi2_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev);
- u32 tmp = (priv->client->channel & 3) << 8;
-
- dev_dbg(sd->v4l2_dev->dev, "%s(%u)\n", __func__, mf->code);
- if (mf->width > 8188 || mf->width & 1)
- return -EINVAL;
-
- switch (mf->code) {
- case V4L2_MBUS_FMT_UYVY8_2X8:
- tmp |= 0x1e; /* YUV422 8 bit */
- break;
- case V4L2_MBUS_FMT_YUYV8_1_5X8:
- tmp |= 0x18; /* YUV420 8 bit */
- break;
- case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE:
- tmp |= 0x21; /* RGB555 */
- break;
- case V4L2_MBUS_FMT_RGB565_2X8_BE:
- tmp |= 0x22; /* RGB565 */
- break;
- case V4L2_MBUS_FMT_Y8_1X8:
- case V4L2_MBUS_FMT_SBGGR8_1X8:
- case V4L2_MBUS_FMT_SGRBG8_1X8:
- tmp |= 0x2a; /* RAW8 */
- break;
- default:
- return -EINVAL;
- }
-
- iowrite32(tmp, priv->base + SH_CSI2_VCDT);
-
- return 0;
-}
-
-static int sh_csi2_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING |
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
- V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH;
- cfg->type = V4L2_MBUS_PARALLEL;
-
- return 0;
-}
-
-static int sh_csi2_s_mbus_config(struct v4l2_subdev *sd,
- const struct v4l2_mbus_config *cfg)
-{
- struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev);
- struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd);
- struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
- struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,
- .flags = priv->mipi_flags};
-
- return v4l2_subdev_call(client_sd, video, s_mbus_config, &client_cfg);
-}
-
-static struct v4l2_subdev_video_ops sh_csi2_subdev_video_ops = {
- .s_mbus_fmt = sh_csi2_s_fmt,
- .try_mbus_fmt = sh_csi2_try_fmt,
- .g_mbus_config = sh_csi2_g_mbus_config,
- .s_mbus_config = sh_csi2_s_mbus_config,
-};
-
-static void sh_csi2_hwinit(struct sh_csi2 *priv)
-{
- struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data;
- __u32 tmp = 0x10; /* Enable MIPI CSI clock lane */
-
- /* Reflect registers immediately */
- iowrite32(0x00000001, priv->base + SH_CSI2_TREF);
- /* reset CSI2 harware */
- iowrite32(0x00000001, priv->base + SH_CSI2_SRST);
- udelay(5);
- iowrite32(0x00000000, priv->base + SH_CSI2_SRST);
-
- switch (pdata->type) {
- case SH_CSI2C:
- if (priv->client->lanes == 1)
- tmp |= 1;
- else
- /* Default - both lanes */
- tmp |= 3;
- break;
- case SH_CSI2I:
- if (!priv->client->lanes || priv->client->lanes > 4)
- /* Default - all 4 lanes */
- tmp |= 0xf;
- else
- tmp |= (1 << priv->client->lanes) - 1;
- }
-
- if (priv->client->phy == SH_CSI2_PHY_MAIN)
- tmp |= 0x8000;
-
- iowrite32(tmp, priv->base + SH_CSI2_PHYCNT);
-
- tmp = 0;
- if (pdata->flags & SH_CSI2_ECC)
- tmp |= 2;
- if (pdata->flags & SH_CSI2_CRC)
- tmp |= 1;
- iowrite32(tmp, priv->base + SH_CSI2_CHKSUM);
-}
-
-static int sh_csi2_client_connect(struct sh_csi2 *priv)
-{
- struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data;
- struct soc_camera_device *icd = v4l2_get_subdev_hostdata(&priv->subdev);
- struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
- struct device *dev = v4l2_get_subdevdata(&priv->subdev);
- struct v4l2_mbus_config cfg;
- unsigned long common_flags, csi2_flags;
- int i, ret;
-
- if (priv->client)
- return -EBUSY;
-
- for (i = 0; i < pdata->num_clients; i++)
- if (&pdata->clients[i].pdev->dev == icd->pdev)
- break;
-
- dev_dbg(dev, "%s(%p): found #%d\n", __func__, dev, i);
-
- if (i == pdata->num_clients)
- return -ENODEV;
-
- /* Check if we can support this camera */
- csi2_flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | V4L2_MBUS_CSI2_1_LANE;
-
- switch (pdata->type) {
- case SH_CSI2C:
- if (pdata->clients[i].lanes != 1)
- csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
- break;
- case SH_CSI2I:
- switch (pdata->clients[i].lanes) {
- default:
- csi2_flags |= V4L2_MBUS_CSI2_4_LANE;
- case 3:
- csi2_flags |= V4L2_MBUS_CSI2_3_LANE;
- case 2:
- csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
- }
- }
-
- cfg.type = V4L2_MBUS_CSI2;
- ret = v4l2_subdev_call(client_sd, video, g_mbus_config, &cfg);
- if (ret == -ENOIOCTLCMD)
- common_flags = csi2_flags;
- else if (!ret)
- common_flags = soc_mbus_config_compatible(&cfg,
- csi2_flags);
- else
- common_flags = 0;
-
- if (!common_flags)
- return -EINVAL;
-
- /* All good: camera MIPI configuration supported */
- priv->mipi_flags = common_flags;
- priv->client = pdata->clients + i;
-
- pm_runtime_get_sync(dev);
-
- sh_csi2_hwinit(priv);
-
- return 0;
-}
-
-static void sh_csi2_client_disconnect(struct sh_csi2 *priv)
-{
- if (!priv->client)
- return;
-
- priv->client = NULL;
-
- pm_runtime_put(v4l2_get_subdevdata(&priv->subdev));
-}
-
-static int sh_csi2_s_power(struct v4l2_subdev *sd, int on)
-{
- struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev);
-
- if (on)
- return sh_csi2_client_connect(priv);
-
- sh_csi2_client_disconnect(priv);
- return 0;
-}
-
-static struct v4l2_subdev_core_ops sh_csi2_subdev_core_ops = {
- .s_power = sh_csi2_s_power,
-};
-
-static struct v4l2_subdev_ops sh_csi2_subdev_ops = {
- .core = &sh_csi2_subdev_core_ops,
- .video = &sh_csi2_subdev_video_ops,
-};
-
-static __devinit int sh_csi2_probe(struct platform_device *pdev)
-{
- struct resource *res;
- unsigned int irq;
- int ret;
- struct sh_csi2 *priv;
- /* Platform data specify the PHY, lanes, ECC, CRC */
- struct sh_csi2_pdata *pdata = pdev->dev.platform_data;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- /* Interrupt unused so far */
- irq = platform_get_irq(pdev, 0);
-
- if (!res || (int)irq <= 0 || !pdata) {
- dev_err(&pdev->dev, "Not enough CSI2 platform resources.\n");
- return -ENODEV;
- }
-
- /* TODO: Add support for CSI2I. Careful: different register layout! */
- if (pdata->type != SH_CSI2C) {
- dev_err(&pdev->dev, "Only CSI2C supported ATM.\n");
- return -EINVAL;
- }
-
- priv = kzalloc(sizeof(struct sh_csi2), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->irq = irq;
-
- if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
- dev_err(&pdev->dev, "CSI2 register region already claimed\n");
- ret = -EBUSY;
- goto ereqreg;
- }
-
- priv->base = ioremap(res->start, resource_size(res));
- if (!priv->base) {
- ret = -ENXIO;
- dev_err(&pdev->dev, "Unable to ioremap CSI2 registers.\n");
- goto eremap;
- }
-
- priv->pdev = pdev;
- platform_set_drvdata(pdev, priv);
-
- v4l2_subdev_init(&priv->subdev, &sh_csi2_subdev_ops);
- v4l2_set_subdevdata(&priv->subdev, &pdev->dev);
-
- snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s.mipi-csi",
- dev_name(pdata->v4l2_dev->dev));
- ret = v4l2_device_register_subdev(pdata->v4l2_dev, &priv->subdev);
- dev_dbg(&pdev->dev, "%s(%p): ret(register_subdev) = %d\n", __func__, priv, ret);
- if (ret < 0)
- goto esdreg;
-
- pm_runtime_enable(&pdev->dev);
-
- dev_dbg(&pdev->dev, "CSI2 probed.\n");
-
- return 0;
-
-esdreg:
- iounmap(priv->base);
-eremap:
- release_mem_region(res->start, resource_size(res));
-ereqreg:
- kfree(priv);
-
- return ret;
-}
-
-static __devexit int sh_csi2_remove(struct platform_device *pdev)
-{
- struct sh_csi2 *priv = platform_get_drvdata(pdev);
- struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- v4l2_device_unregister_subdev(&priv->subdev);
- pm_runtime_disable(&pdev->dev);
- iounmap(priv->base);
- release_mem_region(res->start, resource_size(res));
- platform_set_drvdata(pdev, NULL);
- kfree(priv);
-
- return 0;
-}
-
-static struct platform_driver __refdata sh_csi2_pdrv = {
- .remove = __devexit_p(sh_csi2_remove),
- .probe = sh_csi2_probe,
- .driver = {
- .name = "sh-mobile-csi2",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(sh_csi2_pdrv);
-
-MODULE_DESCRIPTION("SH-Mobile MIPI CSI-2 driver");
-MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:sh-mobile-csi2");
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c
deleted file mode 100644
index 8fd1874382c..00000000000
--- a/drivers/media/video/sh_vou.c
+++ /dev/null
@@ -1,1497 +0,0 @@
-/*
- * SuperH Video Output Unit (VOU) driver
- *
- * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/module.h>
-
-#include <media/sh_vou.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-mediabus.h>
-#include <media/videobuf-dma-contig.h>
-
-/* Mirror addresses are not available for all registers */
-#define VOUER 0
-#define VOUCR 4
-#define VOUSTR 8
-#define VOUVCR 0xc
-#define VOUISR 0x10
-#define VOUBCR 0x14
-#define VOUDPR 0x18
-#define VOUDSR 0x1c
-#define VOUVPR 0x20
-#define VOUIR 0x24
-#define VOUSRR 0x28
-#define VOUMSR 0x2c
-#define VOUHIR 0x30
-#define VOUDFR 0x34
-#define VOUAD1R 0x38
-#define VOUAD2R 0x3c
-#define VOUAIR 0x40
-#define VOUSWR 0x44
-#define VOURCR 0x48
-#define VOURPR 0x50
-
-enum sh_vou_status {
- SH_VOU_IDLE,
- SH_VOU_INITIALISING,
- SH_VOU_RUNNING,
-};
-
-#define VOU_MAX_IMAGE_WIDTH 720
-#define VOU_MAX_IMAGE_HEIGHT 576
-
-struct sh_vou_device {
- struct v4l2_device v4l2_dev;
- struct video_device *vdev;
- atomic_t use_count;
- struct sh_vou_pdata *pdata;
- spinlock_t lock;
- void __iomem *base;
- /* State information */
- struct v4l2_pix_format pix;
- struct v4l2_rect rect;
- struct list_head queue;
- v4l2_std_id std;
- int pix_idx;
- struct videobuf_buffer *active;
- enum sh_vou_status status;
- struct mutex fop_lock;
-};
-
-struct sh_vou_file {
- struct videobuf_queue vbq;
-};
-
-/* Register access routines for sides A, B and mirror addresses */
-static void sh_vou_reg_a_write(struct sh_vou_device *vou_dev, unsigned int reg,
- u32 value)
-{
- __raw_writel(value, vou_dev->base + reg);
-}
-
-static void sh_vou_reg_ab_write(struct sh_vou_device *vou_dev, unsigned int reg,
- u32 value)
-{
- __raw_writel(value, vou_dev->base + reg);
- __raw_writel(value, vou_dev->base + reg + 0x1000);
-}
-
-static void sh_vou_reg_m_write(struct sh_vou_device *vou_dev, unsigned int reg,
- u32 value)
-{
- __raw_writel(value, vou_dev->base + reg + 0x2000);
-}
-
-static u32 sh_vou_reg_a_read(struct sh_vou_device *vou_dev, unsigned int reg)
-{
- return __raw_readl(vou_dev->base + reg);
-}
-
-static void sh_vou_reg_a_set(struct sh_vou_device *vou_dev, unsigned int reg,
- u32 value, u32 mask)
-{
- u32 old = __raw_readl(vou_dev->base + reg);
-
- value = (value & mask) | (old & ~mask);
- __raw_writel(value, vou_dev->base + reg);
-}
-
-static void sh_vou_reg_b_set(struct sh_vou_device *vou_dev, unsigned int reg,
- u32 value, u32 mask)
-{
- sh_vou_reg_a_set(vou_dev, reg + 0x1000, value, mask);
-}
-
-static void sh_vou_reg_ab_set(struct sh_vou_device *vou_dev, unsigned int reg,
- u32 value, u32 mask)
-{
- sh_vou_reg_a_set(vou_dev, reg, value, mask);
- sh_vou_reg_b_set(vou_dev, reg, value, mask);
-}
-
-struct sh_vou_fmt {
- u32 pfmt;
- char *desc;
- unsigned char bpp;
- unsigned char rgb;
- unsigned char yf;
- unsigned char pkf;
-};
-
-/* Further pixel formats can be added */
-static struct sh_vou_fmt vou_fmt[] = {
- {
- .pfmt = V4L2_PIX_FMT_NV12,
- .bpp = 12,
- .desc = "YVU420 planar",
- .yf = 0,
- .rgb = 0,
- },
- {
- .pfmt = V4L2_PIX_FMT_NV16,
- .bpp = 16,
- .desc = "YVYU planar",
- .yf = 1,
- .rgb = 0,
- },
- {
- .pfmt = V4L2_PIX_FMT_RGB24,
- .bpp = 24,
- .desc = "RGB24",
- .pkf = 2,
- .rgb = 1,
- },
- {
- .pfmt = V4L2_PIX_FMT_RGB565,
- .bpp = 16,
- .desc = "RGB565",
- .pkf = 3,
- .rgb = 1,
- },
- {
- .pfmt = V4L2_PIX_FMT_RGB565X,
- .bpp = 16,
- .desc = "RGB565 byteswapped",
- .pkf = 3,
- .rgb = 1,
- },
-};
-
-static void sh_vou_schedule_next(struct sh_vou_device *vou_dev,
- struct videobuf_buffer *vb)
-{
- dma_addr_t addr1, addr2;
-
- addr1 = videobuf_to_dma_contig(vb);
- switch (vou_dev->pix.pixelformat) {
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV16:
- addr2 = addr1 + vou_dev->pix.width * vou_dev->pix.height;
- break;
- default:
- addr2 = 0;
- }
-
- sh_vou_reg_m_write(vou_dev, VOUAD1R, addr1);
- sh_vou_reg_m_write(vou_dev, VOUAD2R, addr2);
-}
-
-static void sh_vou_stream_start(struct sh_vou_device *vou_dev,
- struct videobuf_buffer *vb)
-{
- unsigned int row_coeff;
-#ifdef __LITTLE_ENDIAN
- u32 dataswap = 7;
-#else
- u32 dataswap = 0;
-#endif
-
- switch (vou_dev->pix.pixelformat) {
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV16:
- row_coeff = 1;
- break;
- case V4L2_PIX_FMT_RGB565:
- dataswap ^= 1;
- case V4L2_PIX_FMT_RGB565X:
- row_coeff = 2;
- break;
- case V4L2_PIX_FMT_RGB24:
- row_coeff = 3;
- break;
- }
-
- sh_vou_reg_a_write(vou_dev, VOUSWR, dataswap);
- sh_vou_reg_ab_write(vou_dev, VOUAIR, vou_dev->pix.width * row_coeff);
- sh_vou_schedule_next(vou_dev, vb);
-}
-
-static void free_buffer(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- BUG_ON(in_interrupt());
-
- /* Wait until this buffer is no longer in STATE_QUEUED or STATE_ACTIVE */
- videobuf_waiton(vq, vb, 0, 0);
- videobuf_dma_contig_free(vq, vb);
- vb->state = VIDEOBUF_NEEDS_INIT;
-}
-
-/* Locking: caller holds fop_lock mutex */
-static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count,
- unsigned int *size)
-{
- struct video_device *vdev = vq->priv_data;
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
-
- *size = vou_fmt[vou_dev->pix_idx].bpp * vou_dev->pix.width *
- vou_dev->pix.height / 8;
-
- if (*count < 2)
- *count = 2;
-
- /* Taking into account maximum frame size, *count will stay >= 2 */
- if (PAGE_ALIGN(*size) * *count > 4 * 1024 * 1024)
- *count = 4 * 1024 * 1024 / PAGE_ALIGN(*size);
-
- dev_dbg(vq->dev, "%s(): count=%d, size=%d\n", __func__, *count, *size);
-
- return 0;
-}
-
-/* Locking: caller holds fop_lock mutex */
-static int sh_vou_buf_prepare(struct videobuf_queue *vq,
- struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct video_device *vdev = vq->priv_data;
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
- struct v4l2_pix_format *pix = &vou_dev->pix;
- int bytes_per_line = vou_fmt[vou_dev->pix_idx].bpp * pix->width / 8;
- int ret;
-
- dev_dbg(vq->dev, "%s()\n", __func__);
-
- if (vb->width != pix->width ||
- vb->height != pix->height ||
- vb->field != pix->field) {
- vb->width = pix->width;
- vb->height = pix->height;
- vb->field = field;
- if (vb->state != VIDEOBUF_NEEDS_INIT)
- free_buffer(vq, vb);
- }
-
- vb->size = vb->height * bytes_per_line;
- if (vb->baddr && vb->bsize < vb->size) {
- /* User buffer too small */
- dev_warn(vq->dev, "User buffer too small: [%u] @ %lx\n",
- vb->bsize, vb->baddr);
- return -EINVAL;
- }
-
- if (vb->state == VIDEOBUF_NEEDS_INIT) {
- ret = videobuf_iolock(vq, vb, NULL);
- if (ret < 0) {
- dev_warn(vq->dev, "IOLOCK buf-type %d: %d\n",
- vb->memory, ret);
- return ret;
- }
- vb->state = VIDEOBUF_PREPARED;
- }
-
- dev_dbg(vq->dev,
- "%s(): fmt #%d, %u bytes per line, phys 0x%x, type %d, state %d\n",
- __func__, vou_dev->pix_idx, bytes_per_line,
- videobuf_to_dma_contig(vb), vb->memory, vb->state);
-
- return 0;
-}
-
-/* Locking: caller holds fop_lock mutex and vq->irqlock spinlock */
-static void sh_vou_buf_queue(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct video_device *vdev = vq->priv_data;
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
-
- dev_dbg(vq->dev, "%s()\n", __func__);
-
- vb->state = VIDEOBUF_QUEUED;
- list_add_tail(&vb->queue, &vou_dev->queue);
-
- if (vou_dev->status == SH_VOU_RUNNING) {
- return;
- } else if (!vou_dev->active) {
- vou_dev->active = vb;
- /* Start from side A: we use mirror addresses, so, set B */
- sh_vou_reg_a_write(vou_dev, VOURPR, 1);
- dev_dbg(vq->dev, "%s: first buffer status 0x%x\n", __func__,
- sh_vou_reg_a_read(vou_dev, VOUSTR));
- sh_vou_schedule_next(vou_dev, vb);
- /* Only activate VOU after the second buffer */
- } else if (vou_dev->active->queue.next == &vb->queue) {
- /* Second buffer - initialise register side B */
- sh_vou_reg_a_write(vou_dev, VOURPR, 0);
- sh_vou_stream_start(vou_dev, vb);
-
- /* Register side switching with frame VSYNC */
- sh_vou_reg_a_write(vou_dev, VOURCR, 5);
- dev_dbg(vq->dev, "%s: second buffer status 0x%x\n", __func__,
- sh_vou_reg_a_read(vou_dev, VOUSTR));
-
- /* Enable End-of-Frame (VSYNC) interrupts */
- sh_vou_reg_a_write(vou_dev, VOUIR, 0x10004);
- /* Two buffers on the queue - activate the hardware */
-
- vou_dev->status = SH_VOU_RUNNING;
- sh_vou_reg_a_write(vou_dev, VOUER, 0x107);
- }
-}
-
-static void sh_vou_buf_release(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct video_device *vdev = vq->priv_data;
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
- unsigned long flags;
-
- dev_dbg(vq->dev, "%s()\n", __func__);
-
- spin_lock_irqsave(&vou_dev->lock, flags);
-
- if (vou_dev->active == vb) {
- /* disable output */
- sh_vou_reg_a_set(vou_dev, VOUER, 0, 1);
- /* ...but the current frame will complete */
- sh_vou_reg_a_set(vou_dev, VOUIR, 0, 0x30000);
- vou_dev->active = NULL;
- }
-
- if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED)) {
- vb->state = VIDEOBUF_ERROR;
- list_del(&vb->queue);
- }
-
- spin_unlock_irqrestore(&vou_dev->lock, flags);
-
- free_buffer(vq, vb);
-}
-
-static struct videobuf_queue_ops sh_vou_video_qops = {
- .buf_setup = sh_vou_buf_setup,
- .buf_prepare = sh_vou_buf_prepare,
- .buf_queue = sh_vou_buf_queue,
- .buf_release = sh_vou_buf_release,
-};
-
-/* Video IOCTLs */
-static int sh_vou_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct sh_vou_file *vou_file = priv;
-
- dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
-
- strlcpy(cap->card, "SuperH VOU", sizeof(cap->card));
- cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
- return 0;
-}
-
-/* Enumerate formats, that the device can accept from the user */
-static int sh_vou_enum_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_fmtdesc *fmt)
-{
- struct sh_vou_file *vou_file = priv;
-
- if (fmt->index >= ARRAY_SIZE(vou_fmt))
- return -EINVAL;
-
- dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
-
- fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- strlcpy(fmt->description, vou_fmt[fmt->index].desc,
- sizeof(fmt->description));
- fmt->pixelformat = vou_fmt[fmt->index].pfmt;
-
- return 0;
-}
-
-static int sh_vou_g_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct video_device *vdev = video_devdata(file);
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
-
- dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
- fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- fmt->fmt.pix = vou_dev->pix;
-
- return 0;
-}
-
-static const unsigned char vou_scale_h_num[] = {1, 9, 2, 9, 4};
-static const unsigned char vou_scale_h_den[] = {1, 8, 1, 4, 1};
-static const unsigned char vou_scale_h_fld[] = {0, 2, 1, 3};
-static const unsigned char vou_scale_v_num[] = {1, 2, 4};
-static const unsigned char vou_scale_v_den[] = {1, 1, 1};
-static const unsigned char vou_scale_v_fld[] = {0, 1};
-
-static void sh_vou_configure_geometry(struct sh_vou_device *vou_dev,
- int pix_idx, int w_idx, int h_idx)
-{
- struct sh_vou_fmt *fmt = vou_fmt + pix_idx;
- unsigned int black_left, black_top, width_max, height_max,
- frame_in_height, frame_out_height, frame_out_top;
- struct v4l2_rect *rect = &vou_dev->rect;
- struct v4l2_pix_format *pix = &vou_dev->pix;
- u32 vouvcr = 0, dsr_h, dsr_v;
-
- if (vou_dev->std & V4L2_STD_525_60) {
- width_max = 858;
- height_max = 262;
- } else {
- width_max = 864;
- height_max = 312;
- }
-
- frame_in_height = pix->height / 2;
- frame_out_height = rect->height / 2;
- frame_out_top = rect->top / 2;
-
- /*
- * Cropping scheme: max useful image is 720x480, and the total video
- * area is 858x525 (NTSC) or 864x625 (PAL). AK8813 / 8814 starts
- * sampling data beginning with fixed 276th (NTSC) / 288th (PAL) clock,
- * of which the first 33 / 25 clocks HSYNC must be held active. This
- * has to be configured in CR[HW]. 1 pixel equals 2 clock periods.
- * This gives CR[HW] = 16 / 12, VPR[HVP] = 138 / 144, which gives
- * exactly 858 - 138 = 864 - 144 = 720! We call the out-of-display area,
- * beyond DSR, specified on the left and top by the VPR register "black
- * pixels" and out-of-image area (DPR) "background pixels." We fix VPR
- * at 138 / 144 : 20, because that's the HSYNC timing, that our first
- * client requires, and that's exactly what leaves us 720 pixels for the
- * image; we leave VPR[VVP] at default 20 for now, because the client
- * doesn't seem to have any special requirements for it. Otherwise we
- * could also set it to max - 240 = 22 / 72. Thus VPR depends only on
- * the selected standard, and DPR and DSR are selected according to
- * cropping. Q: how does the client detect the first valid line? Does
- * HSYNC stay inactive during invalid (black) lines?
- */
- black_left = width_max - VOU_MAX_IMAGE_WIDTH;
- black_top = 20;
-
- dsr_h = rect->width + rect->left;
- dsr_v = frame_out_height + frame_out_top;
-
- dev_dbg(vou_dev->v4l2_dev.dev,
- "image %ux%u, black %u:%u, offset %u:%u, display %ux%u\n",
- pix->width, frame_in_height, black_left, black_top,
- rect->left, frame_out_top, dsr_h, dsr_v);
-
- /* VOUISR height - half of a frame height in frame mode */
- sh_vou_reg_ab_write(vou_dev, VOUISR, (pix->width << 16) | frame_in_height);
- sh_vou_reg_ab_write(vou_dev, VOUVPR, (black_left << 16) | black_top);
- sh_vou_reg_ab_write(vou_dev, VOUDPR, (rect->left << 16) | frame_out_top);
- sh_vou_reg_ab_write(vou_dev, VOUDSR, (dsr_h << 16) | dsr_v);
-
- /*
- * if necessary, we could set VOUHIR to
- * max(black_left + dsr_h, width_max) here
- */
-
- if (w_idx)
- vouvcr |= (1 << 15) | (vou_scale_h_fld[w_idx - 1] << 4);
- if (h_idx)
- vouvcr |= (1 << 14) | vou_scale_v_fld[h_idx - 1];
-
- dev_dbg(vou_dev->v4l2_dev.dev, "%s: scaling 0x%x\n", fmt->desc, vouvcr);
-
- /* To produce a colour bar for testing set bit 23 of VOUVCR */
- sh_vou_reg_ab_write(vou_dev, VOUVCR, vouvcr);
- sh_vou_reg_ab_write(vou_dev, VOUDFR,
- fmt->pkf | (fmt->yf << 8) | (fmt->rgb << 16));
-}
-
-struct sh_vou_geometry {
- struct v4l2_rect output;
- unsigned int in_width;
- unsigned int in_height;
- int scale_idx_h;
- int scale_idx_v;
-};
-
-/*
- * Find input geometry, that we can use to produce output, closest to the
- * requested rectangle, using VOU scaling
- */
-static void vou_adjust_input(struct sh_vou_geometry *geo, v4l2_std_id std)
-{
- /* The compiler cannot know, that best and idx will indeed be set */
- unsigned int best_err = UINT_MAX, best = 0, img_height_max;
- int i, idx = 0;
-
- if (std & V4L2_STD_525_60)
- img_height_max = 480;
- else
- img_height_max = 576;
-
- /* Image width must be a multiple of 4 */
- v4l_bound_align_image(&geo->in_width, 0, VOU_MAX_IMAGE_WIDTH, 2,
- &geo->in_height, 0, img_height_max, 1, 0);
-
- /* Select scales to come as close as possible to the output image */
- for (i = ARRAY_SIZE(vou_scale_h_num) - 1; i >= 0; i--) {
- unsigned int err;
- unsigned int found = geo->output.width * vou_scale_h_den[i] /
- vou_scale_h_num[i];
-
- if (found > VOU_MAX_IMAGE_WIDTH)
- /* scales increase */
- break;
-
- err = abs(found - geo->in_width);
- if (err < best_err) {
- best_err = err;
- idx = i;
- best = found;
- }
- if (!err)
- break;
- }
-
- geo->in_width = best;
- geo->scale_idx_h = idx;
-
- best_err = UINT_MAX;
-
- /* This loop can be replaced with one division */
- for (i = ARRAY_SIZE(vou_scale_v_num) - 1; i >= 0; i--) {
- unsigned int err;
- unsigned int found = geo->output.height * vou_scale_v_den[i] /
- vou_scale_v_num[i];
-
- if (found > img_height_max)
- /* scales increase */
- break;
-
- err = abs(found - geo->in_height);
- if (err < best_err) {
- best_err = err;
- idx = i;
- best = found;
- }
- if (!err)
- break;
- }
-
- geo->in_height = best;
- geo->scale_idx_v = idx;
-}
-
-/*
- * Find output geometry, that we can produce, using VOU scaling, closest to
- * the requested rectangle
- */
-static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std)
-{
- unsigned int best_err = UINT_MAX, best, width_max, height_max,
- img_height_max;
- int i, idx;
-
- if (std & V4L2_STD_525_60) {
- width_max = 858;
- height_max = 262 * 2;
- img_height_max = 480;
- } else {
- width_max = 864;
- height_max = 312 * 2;
- img_height_max = 576;
- }
-
- /* Select scales to come as close as possible to the output image */
- for (i = 0; i < ARRAY_SIZE(vou_scale_h_num); i++) {
- unsigned int err;
- unsigned int found = geo->in_width * vou_scale_h_num[i] /
- vou_scale_h_den[i];
-
- if (found > VOU_MAX_IMAGE_WIDTH)
- /* scales increase */
- break;
-
- err = abs(found - geo->output.width);
- if (err < best_err) {
- best_err = err;
- idx = i;
- best = found;
- }
- if (!err)
- break;
- }
-
- geo->output.width = best;
- geo->scale_idx_h = idx;
- if (geo->output.left + best > width_max)
- geo->output.left = width_max - best;
-
- pr_debug("%s(): W %u * %u/%u = %u\n", __func__, geo->in_width,
- vou_scale_h_num[idx], vou_scale_h_den[idx], best);
-
- best_err = UINT_MAX;
-
- /* This loop can be replaced with one division */
- for (i = 0; i < ARRAY_SIZE(vou_scale_v_num); i++) {
- unsigned int err;
- unsigned int found = geo->in_height * vou_scale_v_num[i] /
- vou_scale_v_den[i];
-
- if (found > img_height_max)
- /* scales increase */
- break;
-
- err = abs(found - geo->output.height);
- if (err < best_err) {
- best_err = err;
- idx = i;
- best = found;
- }
- if (!err)
- break;
- }
-
- geo->output.height = best;
- geo->scale_idx_v = idx;
- if (geo->output.top + best > height_max)
- geo->output.top = height_max - best;
-
- pr_debug("%s(): H %u * %u/%u = %u\n", __func__, geo->in_height,
- vou_scale_v_num[idx], vou_scale_v_den[idx], best);
-}
-
-static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct video_device *vdev = video_devdata(file);
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
- unsigned int img_height_max;
- int pix_idx;
- struct sh_vou_geometry geo;
- struct v4l2_mbus_framefmt mbfmt = {
- /* Revisit: is this the correct code? */
- .code = V4L2_MBUS_FMT_YUYV8_2X8,
- .field = V4L2_FIELD_INTERLACED,
- .colorspace = V4L2_COLORSPACE_SMPTE170M,
- };
- int ret;
-
- dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u -> %ux%u\n", __func__,
- vou_dev->rect.width, vou_dev->rect.height,
- pix->width, pix->height);
-
- if (pix->field == V4L2_FIELD_ANY)
- pix->field = V4L2_FIELD_NONE;
-
- if (fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
- pix->field != V4L2_FIELD_NONE)
- return -EINVAL;
-
- for (pix_idx = 0; pix_idx < ARRAY_SIZE(vou_fmt); pix_idx++)
- if (vou_fmt[pix_idx].pfmt == pix->pixelformat)
- break;
-
- if (pix_idx == ARRAY_SIZE(vou_fmt))
- return -EINVAL;
-
- if (vou_dev->std & V4L2_STD_525_60)
- img_height_max = 480;
- else
- img_height_max = 576;
-
- /* Image width must be a multiple of 4 */
- v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 2,
- &pix->height, 0, img_height_max, 1, 0);
-
- geo.in_width = pix->width;
- geo.in_height = pix->height;
- geo.output = vou_dev->rect;
-
- vou_adjust_output(&geo, vou_dev->std);
-
- mbfmt.width = geo.output.width;
- mbfmt.height = geo.output.height;
- ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
- s_mbus_fmt, &mbfmt);
- /* Must be implemented, so, don't check for -ENOIOCTLCMD */
- if (ret < 0)
- return ret;
-
- dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u -> %ux%u\n", __func__,
- geo.output.width, geo.output.height, mbfmt.width, mbfmt.height);
-
- /* Sanity checks */
- if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH ||
- (unsigned)mbfmt.height > img_height_max ||
- mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8)
- return -EIO;
-
- if (mbfmt.width != geo.output.width ||
- mbfmt.height != geo.output.height) {
- geo.output.width = mbfmt.width;
- geo.output.height = mbfmt.height;
-
- vou_adjust_input(&geo, vou_dev->std);
- }
-
- /* We tried to preserve output rectangle, but it could have changed */
- vou_dev->rect = geo.output;
- pix->width = geo.in_width;
- pix->height = geo.in_height;
-
- dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u\n", __func__,
- pix->width, pix->height);
-
- vou_dev->pix_idx = pix_idx;
-
- vou_dev->pix = *pix;
-
- sh_vou_configure_geometry(vou_dev, pix_idx,
- geo.scale_idx_h, geo.scale_idx_v);
-
- return 0;
-}
-
-static int sh_vou_try_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct sh_vou_file *vou_file = priv;
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
- int i;
-
- dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
-
- fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- pix->field = V4L2_FIELD_NONE;
-
- v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 1,
- &pix->height, 0, VOU_MAX_IMAGE_HEIGHT, 1, 0);
-
- for (i = 0; ARRAY_SIZE(vou_fmt); i++)
- if (vou_fmt[i].pfmt == pix->pixelformat)
- return 0;
-
- pix->pixelformat = vou_fmt[0].pfmt;
-
- return 0;
-}
-
-static int sh_vou_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *req)
-{
- struct sh_vou_file *vou_file = priv;
-
- dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
-
- if (req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
-
- return videobuf_reqbufs(&vou_file->vbq, req);
-}
-
-static int sh_vou_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct sh_vou_file *vou_file = priv;
-
- dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
-
- return videobuf_querybuf(&vou_file->vbq, b);
-}
-
-static int sh_vou_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct sh_vou_file *vou_file = priv;
-
- dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
-
- return videobuf_qbuf(&vou_file->vbq, b);
-}
-
-static int sh_vou_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct sh_vou_file *vou_file = priv;
-
- dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
-
- return videobuf_dqbuf(&vou_file->vbq, b, file->f_flags & O_NONBLOCK);
-}
-
-static int sh_vou_streamon(struct file *file, void *priv,
- enum v4l2_buf_type buftype)
-{
- struct video_device *vdev = video_devdata(file);
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
- struct sh_vou_file *vou_file = priv;
- int ret;
-
- dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
-
- ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0,
- video, s_stream, 1);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return ret;
-
- /* This calls our .buf_queue() (== sh_vou_buf_queue) */
- return videobuf_streamon(&vou_file->vbq);
-}
-
-static int sh_vou_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type buftype)
-{
- struct video_device *vdev = video_devdata(file);
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
- struct sh_vou_file *vou_file = priv;
-
- dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
-
- /*
- * This calls buf_release from host driver's videobuf_queue_ops for all
- * remaining buffers. When the last buffer is freed, stop streaming
- */
- videobuf_streamoff(&vou_file->vbq);
- v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video, s_stream, 0);
-
- return 0;
-}
-
-static u32 sh_vou_ntsc_mode(enum sh_vou_bus_fmt bus_fmt)
-{
- switch (bus_fmt) {
- default:
- pr_warning("%s(): Invalid bus-format code %d, using default 8-bit\n",
- __func__, bus_fmt);
- case SH_VOU_BUS_8BIT:
- return 1;
- case SH_VOU_BUS_16BIT:
- return 0;
- case SH_VOU_BUS_BT656:
- return 3;
- }
-}
-
-static int sh_vou_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
-{
- struct video_device *vdev = video_devdata(file);
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
- int ret;
-
- dev_dbg(vou_dev->v4l2_dev.dev, "%s(): 0x%llx\n", __func__, *std_id);
-
- if (*std_id & ~vdev->tvnorms)
- return -EINVAL;
-
- ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
- s_std_output, *std_id);
- /* Shall we continue, if the subdev doesn't support .s_std_output()? */
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return ret;
-
- if (*std_id & V4L2_STD_525_60)
- sh_vou_reg_ab_set(vou_dev, VOUCR,
- sh_vou_ntsc_mode(vou_dev->pdata->bus_fmt) << 29, 7 << 29);
- else
- sh_vou_reg_ab_set(vou_dev, VOUCR, 5 << 29, 7 << 29);
-
- vou_dev->std = *std_id;
-
- return 0;
-}
-
-static int sh_vou_g_std(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct video_device *vdev = video_devdata(file);
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
-
- dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
- *std = vou_dev->std;
-
- return 0;
-}
-
-static int sh_vou_g_crop(struct file *file, void *fh, struct v4l2_crop *a)
-{
- struct video_device *vdev = video_devdata(file);
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
-
- dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
- a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- a->c = vou_dev->rect;
-
- return 0;
-}
-
-/* Assume a dull encoder, do all the work ourselves. */
-static int sh_vou_s_crop(struct file *file, void *fh, struct v4l2_crop *a)
-{
- struct video_device *vdev = video_devdata(file);
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
- struct v4l2_rect *rect = &a->c;
- struct v4l2_crop sd_crop = {.type = V4L2_BUF_TYPE_VIDEO_OUTPUT};
- struct v4l2_pix_format *pix = &vou_dev->pix;
- struct sh_vou_geometry geo;
- struct v4l2_mbus_framefmt mbfmt = {
- /* Revisit: is this the correct code? */
- .code = V4L2_MBUS_FMT_YUYV8_2X8,
- .field = V4L2_FIELD_INTERLACED,
- .colorspace = V4L2_COLORSPACE_SMPTE170M,
- };
- unsigned int img_height_max;
- int ret;
-
- dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u@%u:%u\n", __func__,
- rect->width, rect->height, rect->left, rect->top);
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
-
- if (vou_dev->std & V4L2_STD_525_60)
- img_height_max = 480;
- else
- img_height_max = 576;
-
- v4l_bound_align_image(&rect->width, 0, VOU_MAX_IMAGE_WIDTH, 1,
- &rect->height, 0, img_height_max, 1, 0);
-
- if (rect->width + rect->left > VOU_MAX_IMAGE_WIDTH)
- rect->left = VOU_MAX_IMAGE_WIDTH - rect->width;
-
- if (rect->height + rect->top > img_height_max)
- rect->top = img_height_max - rect->height;
-
- geo.output = *rect;
- geo.in_width = pix->width;
- geo.in_height = pix->height;
-
- /* Configure the encoder one-to-one, position at 0, ignore errors */
- sd_crop.c.width = geo.output.width;
- sd_crop.c.height = geo.output.height;
- /*
- * We first issue a S_CROP, so that the subsequent S_FMT delivers the
- * final encoder configuration.
- */
- v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
- s_crop, &sd_crop);
- mbfmt.width = geo.output.width;
- mbfmt.height = geo.output.height;
- ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
- s_mbus_fmt, &mbfmt);
- /* Must be implemented, so, don't check for -ENOIOCTLCMD */
- if (ret < 0)
- return ret;
-
- /* Sanity checks */
- if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH ||
- (unsigned)mbfmt.height > img_height_max ||
- mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8)
- return -EIO;
-
- geo.output.width = mbfmt.width;
- geo.output.height = mbfmt.height;
-
- /*
- * No down-scaling. According to the API, current call has precedence:
- * http://v4l2spec.bytesex.org/spec/x1904.htm#AEN1954 paragraph two.
- */
- vou_adjust_input(&geo, vou_dev->std);
-
- /* We tried to preserve output rectangle, but it could have changed */
- vou_dev->rect = geo.output;
- pix->width = geo.in_width;
- pix->height = geo.in_height;
-
- sh_vou_configure_geometry(vou_dev, vou_dev->pix_idx,
- geo.scale_idx_h, geo.scale_idx_v);
-
- return 0;
-}
-
-/*
- * Total field: NTSC 858 x 2 * 262/263, PAL 864 x 2 * 312/313, default rectangle
- * is the initial register values, height takes the interlaced format into
- * account. The actual image can only go up to 720 x 2 * 240, So, VOUVPR can
- * actually only meaningfully contain values <= 720 and <= 240 respectively, and
- * not <= 864 and <= 312.
- */
-static int sh_vou_cropcap(struct file *file, void *priv,
- struct v4l2_cropcap *a)
-{
- struct sh_vou_file *vou_file = priv;
-
- dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
-
- a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = VOU_MAX_IMAGE_WIDTH;
- a->bounds.height = VOU_MAX_IMAGE_HEIGHT;
- /* Default = max, set VOUDPR = 0, which is not hardware default */
- a->defrect.left = 0;
- a->defrect.top = 0;
- a->defrect.width = VOU_MAX_IMAGE_WIDTH;
- a->defrect.height = VOU_MAX_IMAGE_HEIGHT;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static irqreturn_t sh_vou_isr(int irq, void *dev_id)
-{
- struct sh_vou_device *vou_dev = dev_id;
- static unsigned long j;
- struct videobuf_buffer *vb;
- static int cnt;
- static int side;
- u32 irq_status = sh_vou_reg_a_read(vou_dev, VOUIR), masked;
- u32 vou_status = sh_vou_reg_a_read(vou_dev, VOUSTR);
-
- if (!(irq_status & 0x300)) {
- if (printk_timed_ratelimit(&j, 500))
- dev_warn(vou_dev->v4l2_dev.dev, "IRQ status 0x%x!\n",
- irq_status);
- return IRQ_NONE;
- }
-
- spin_lock(&vou_dev->lock);
- if (!vou_dev->active || list_empty(&vou_dev->queue)) {
- if (printk_timed_ratelimit(&j, 500))
- dev_warn(vou_dev->v4l2_dev.dev,
- "IRQ without active buffer: %x!\n", irq_status);
- /* Just ack: buf_release will disable further interrupts */
- sh_vou_reg_a_set(vou_dev, VOUIR, 0, 0x300);
- spin_unlock(&vou_dev->lock);
- return IRQ_HANDLED;
- }
-
- masked = ~(0x300 & irq_status) & irq_status & 0x30304;
- dev_dbg(vou_dev->v4l2_dev.dev,
- "IRQ status 0x%x -> 0x%x, VOU status 0x%x, cnt %d\n",
- irq_status, masked, vou_status, cnt);
-
- cnt++;
- side = vou_status & 0x10000;
-
- /* Clear only set interrupts */
- sh_vou_reg_a_write(vou_dev, VOUIR, masked);
-
- vb = vou_dev->active;
- list_del(&vb->queue);
-
- vb->state = VIDEOBUF_DONE;
- do_gettimeofday(&vb->ts);
- vb->field_count++;
- wake_up(&vb->done);
-
- if (list_empty(&vou_dev->queue)) {
- /* Stop VOU */
- dev_dbg(vou_dev->v4l2_dev.dev, "%s: queue empty after %d\n",
- __func__, cnt);
- sh_vou_reg_a_set(vou_dev, VOUER, 0, 1);
- vou_dev->active = NULL;
- vou_dev->status = SH_VOU_INITIALISING;
- /* Disable End-of-Frame (VSYNC) interrupts */
- sh_vou_reg_a_set(vou_dev, VOUIR, 0, 0x30000);
- spin_unlock(&vou_dev->lock);
- return IRQ_HANDLED;
- }
-
- vou_dev->active = list_entry(vou_dev->queue.next,
- struct videobuf_buffer, queue);
-
- if (vou_dev->active->queue.next != &vou_dev->queue) {
- struct videobuf_buffer *new = list_entry(vou_dev->active->queue.next,
- struct videobuf_buffer, queue);
- sh_vou_schedule_next(vou_dev, new);
- }
-
- spin_unlock(&vou_dev->lock);
-
- return IRQ_HANDLED;
-}
-
-static int sh_vou_hw_init(struct sh_vou_device *vou_dev)
-{
- struct sh_vou_pdata *pdata = vou_dev->pdata;
- u32 voucr = sh_vou_ntsc_mode(pdata->bus_fmt) << 29;
- int i = 100;
-
- /* Disable all IRQs */
- sh_vou_reg_a_write(vou_dev, VOUIR, 0);
-
- /* Reset VOU interfaces - registers unaffected */
- sh_vou_reg_a_write(vou_dev, VOUSRR, 0x101);
- while (--i && (sh_vou_reg_a_read(vou_dev, VOUSRR) & 0x101))
- udelay(1);
-
- if (!i)
- return -ETIMEDOUT;
-
- dev_dbg(vou_dev->v4l2_dev.dev, "Reset took %dus\n", 100 - i);
-
- if (pdata->flags & SH_VOU_PCLK_FALLING)
- voucr |= 1 << 28;
- if (pdata->flags & SH_VOU_HSYNC_LOW)
- voucr |= 1 << 27;
- if (pdata->flags & SH_VOU_VSYNC_LOW)
- voucr |= 1 << 26;
- sh_vou_reg_ab_set(vou_dev, VOUCR, voucr, 0xfc000000);
-
- /* Manual register side switching at first */
- sh_vou_reg_a_write(vou_dev, VOURCR, 4);
- /* Default - fixed HSYNC length, can be made configurable is required */
- sh_vou_reg_ab_write(vou_dev, VOUMSR, 0x800000);
-
- return 0;
-}
-
-/* File operations */
-static int sh_vou_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
- struct sh_vou_file *vou_file = kzalloc(sizeof(struct sh_vou_file),
- GFP_KERNEL);
-
- if (!vou_file)
- return -ENOMEM;
-
- dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
-
- file->private_data = vou_file;
-
- if (atomic_inc_return(&vou_dev->use_count) == 1) {
- int ret;
- /* First open */
- vou_dev->status = SH_VOU_INITIALISING;
- pm_runtime_get_sync(vdev->v4l2_dev->dev);
- ret = sh_vou_hw_init(vou_dev);
- if (ret < 0) {
- atomic_dec(&vou_dev->use_count);
- pm_runtime_put(vdev->v4l2_dev->dev);
- vou_dev->status = SH_VOU_IDLE;
- return ret;
- }
- }
-
- videobuf_queue_dma_contig_init(&vou_file->vbq, &sh_vou_video_qops,
- vou_dev->v4l2_dev.dev, &vou_dev->lock,
- V4L2_BUF_TYPE_VIDEO_OUTPUT,
- V4L2_FIELD_NONE,
- sizeof(struct videobuf_buffer), vdev,
- &vou_dev->fop_lock);
-
- return 0;
-}
-
-static int sh_vou_release(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
- struct sh_vou_file *vou_file = file->private_data;
-
- dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
-
- if (!atomic_dec_return(&vou_dev->use_count)) {
- /* Last close */
- vou_dev->status = SH_VOU_IDLE;
- sh_vou_reg_a_set(vou_dev, VOUER, 0, 0x101);
- pm_runtime_put(vdev->v4l2_dev->dev);
- }
-
- file->private_data = NULL;
- kfree(vou_file);
-
- return 0;
-}
-
-static int sh_vou_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct sh_vou_file *vou_file = file->private_data;
-
- dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
-
- return videobuf_mmap_mapper(&vou_file->vbq, vma);
-}
-
-static unsigned int sh_vou_poll(struct file *file, poll_table *wait)
-{
- struct sh_vou_file *vou_file = file->private_data;
-
- dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
-
- return videobuf_poll_stream(file, &vou_file->vbq, wait);
-}
-
-static int sh_vou_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *id)
-{
- struct video_device *vdev = video_devdata(file);
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
-
- return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, g_chip_ident, id);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int sh_vou_g_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct video_device *vdev = video_devdata(file);
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
-
- return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, g_register, reg);
-}
-
-static int sh_vou_s_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct video_device *vdev = video_devdata(file);
- struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
-
- return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, s_register, reg);
-}
-#endif
-
-/* sh_vou display ioctl operations */
-static const struct v4l2_ioctl_ops sh_vou_ioctl_ops = {
- .vidioc_querycap = sh_vou_querycap,
- .vidioc_enum_fmt_vid_out = sh_vou_enum_fmt_vid_out,
- .vidioc_g_fmt_vid_out = sh_vou_g_fmt_vid_out,
- .vidioc_s_fmt_vid_out = sh_vou_s_fmt_vid_out,
- .vidioc_try_fmt_vid_out = sh_vou_try_fmt_vid_out,
- .vidioc_reqbufs = sh_vou_reqbufs,
- .vidioc_querybuf = sh_vou_querybuf,
- .vidioc_qbuf = sh_vou_qbuf,
- .vidioc_dqbuf = sh_vou_dqbuf,
- .vidioc_streamon = sh_vou_streamon,
- .vidioc_streamoff = sh_vou_streamoff,
- .vidioc_s_std = sh_vou_s_std,
- .vidioc_g_std = sh_vou_g_std,
- .vidioc_cropcap = sh_vou_cropcap,
- .vidioc_g_crop = sh_vou_g_crop,
- .vidioc_s_crop = sh_vou_s_crop,
- .vidioc_g_chip_ident = sh_vou_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = sh_vou_g_register,
- .vidioc_s_register = sh_vou_s_register,
-#endif
-};
-
-static const struct v4l2_file_operations sh_vou_fops = {
- .owner = THIS_MODULE,
- .open = sh_vou_open,
- .release = sh_vou_release,
- .unlocked_ioctl = video_ioctl2,
- .mmap = sh_vou_mmap,
- .poll = sh_vou_poll,
-};
-
-static const struct video_device sh_vou_video_template = {
- .name = "sh_vou",
- .fops = &sh_vou_fops,
- .ioctl_ops = &sh_vou_ioctl_ops,
- .tvnorms = V4L2_STD_525_60, /* PAL only supported in 8-bit non-bt656 mode */
- .current_norm = V4L2_STD_NTSC_M,
-};
-
-static int __devinit sh_vou_probe(struct platform_device *pdev)
-{
- struct sh_vou_pdata *vou_pdata = pdev->dev.platform_data;
- struct v4l2_rect *rect;
- struct v4l2_pix_format *pix;
- struct i2c_adapter *i2c_adap;
- struct video_device *vdev;
- struct sh_vou_device *vou_dev;
- struct resource *reg_res, *region;
- struct v4l2_subdev *subdev;
- int irq, ret;
-
- reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- irq = platform_get_irq(pdev, 0);
-
- if (!vou_pdata || !reg_res || irq <= 0) {
- dev_err(&pdev->dev, "Insufficient VOU platform information.\n");
- return -ENODEV;
- }
-
- vou_dev = kzalloc(sizeof(*vou_dev), GFP_KERNEL);
- if (!vou_dev)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&vou_dev->queue);
- spin_lock_init(&vou_dev->lock);
- mutex_init(&vou_dev->fop_lock);
- atomic_set(&vou_dev->use_count, 0);
- vou_dev->pdata = vou_pdata;
- vou_dev->status = SH_VOU_IDLE;
-
- rect = &vou_dev->rect;
- pix = &vou_dev->pix;
-
- /* Fill in defaults */
- vou_dev->std = sh_vou_video_template.current_norm;
- rect->left = 0;
- rect->top = 0;
- rect->width = VOU_MAX_IMAGE_WIDTH;
- rect->height = 480;
- pix->width = VOU_MAX_IMAGE_WIDTH;
- pix->height = 480;
- pix->pixelformat = V4L2_PIX_FMT_YVYU;
- pix->field = V4L2_FIELD_NONE;
- pix->bytesperline = VOU_MAX_IMAGE_WIDTH * 2;
- pix->sizeimage = VOU_MAX_IMAGE_WIDTH * 2 * 480;
- pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
-
- region = request_mem_region(reg_res->start, resource_size(reg_res),
- pdev->name);
- if (!region) {
- dev_err(&pdev->dev, "VOU region already claimed\n");
- ret = -EBUSY;
- goto ereqmemreg;
- }
-
- vou_dev->base = ioremap(reg_res->start, resource_size(reg_res));
- if (!vou_dev->base) {
- ret = -ENOMEM;
- goto emap;
- }
-
- ret = request_irq(irq, sh_vou_isr, 0, "vou", vou_dev);
- if (ret < 0)
- goto ereqirq;
-
- ret = v4l2_device_register(&pdev->dev, &vou_dev->v4l2_dev);
- if (ret < 0) {
- dev_err(&pdev->dev, "Error registering v4l2 device\n");
- goto ev4l2devreg;
- }
-
- /* Allocate memory for video device */
- vdev = video_device_alloc();
- if (vdev == NULL) {
- ret = -ENOMEM;
- goto evdevalloc;
- }
-
- *vdev = sh_vou_video_template;
- if (vou_pdata->bus_fmt == SH_VOU_BUS_8BIT)
- vdev->tvnorms |= V4L2_STD_PAL;
- vdev->v4l2_dev = &vou_dev->v4l2_dev;
- vdev->release = video_device_release;
- vdev->lock = &vou_dev->fop_lock;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags);
-
- vou_dev->vdev = vdev;
- video_set_drvdata(vdev, vou_dev);
-
- pm_runtime_enable(&pdev->dev);
- pm_runtime_resume(&pdev->dev);
-
- i2c_adap = i2c_get_adapter(vou_pdata->i2c_adap);
- if (!i2c_adap) {
- ret = -ENODEV;
- goto ei2cgadap;
- }
-
- ret = sh_vou_hw_init(vou_dev);
- if (ret < 0)
- goto ereset;
-
- subdev = v4l2_i2c_new_subdev_board(&vou_dev->v4l2_dev, i2c_adap,
- vou_pdata->board_info, NULL);
- if (!subdev) {
- ret = -ENOMEM;
- goto ei2cnd;
- }
-
- ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
- if (ret < 0)
- goto evregdev;
-
- return 0;
-
-evregdev:
-ei2cnd:
-ereset:
- i2c_put_adapter(i2c_adap);
-ei2cgadap:
- video_device_release(vdev);
- pm_runtime_disable(&pdev->dev);
-evdevalloc:
- v4l2_device_unregister(&vou_dev->v4l2_dev);
-ev4l2devreg:
- free_irq(irq, vou_dev);
-ereqirq:
- iounmap(vou_dev->base);
-emap:
- release_mem_region(reg_res->start, resource_size(reg_res));
-ereqmemreg:
- kfree(vou_dev);
- return ret;
-}
-
-static int __devexit sh_vou_remove(struct platform_device *pdev)
-{
- int irq = platform_get_irq(pdev, 0);
- struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
- struct sh_vou_device *vou_dev = container_of(v4l2_dev,
- struct sh_vou_device, v4l2_dev);
- struct v4l2_subdev *sd = list_entry(v4l2_dev->subdevs.next,
- struct v4l2_subdev, list);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct resource *reg_res;
-
- if (irq > 0)
- free_irq(irq, vou_dev);
- pm_runtime_disable(&pdev->dev);
- video_unregister_device(vou_dev->vdev);
- i2c_put_adapter(client->adapter);
- v4l2_device_unregister(&vou_dev->v4l2_dev);
- iounmap(vou_dev->base);
- reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (reg_res)
- release_mem_region(reg_res->start, resource_size(reg_res));
- kfree(vou_dev);
- return 0;
-}
-
-static struct platform_driver __refdata sh_vou = {
- .remove = __devexit_p(sh_vou_remove),
- .driver = {
- .name = "sh-vou",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init sh_vou_init(void)
-{
- return platform_driver_probe(&sh_vou, sh_vou_probe);
-}
-
-static void __exit sh_vou_exit(void)
-{
- platform_driver_unregister(&sh_vou);
-}
-
-module_init(sh_vou_init);
-module_exit(sh_vou_exit);
-
-MODULE_DESCRIPTION("SuperH VOU driver");
-MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION("0.1.0");
-MODULE_ALIAS("platform:sh-vou");
diff --git a/drivers/media/video/smiapp-pll.c b/drivers/media/video/smiapp-pll.c
deleted file mode 100644
index a2e41a21dc6..00000000000
--- a/drivers/media/video/smiapp-pll.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * drivers/media/video/smiapp-pll.c
- *
- * Generic driver for SMIA/SMIA++ compliant camera modules
- *
- * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/gcd.h>
-#include <linux/lcm.h>
-#include <linux/module.h>
-
-#include "smiapp-pll.h"
-
-/* Return an even number or one. */
-static inline uint32_t clk_div_even(uint32_t a)
-{
- return max_t(uint32_t, 1, a & ~1);
-}
-
-/* Return an even number or one. */
-static inline uint32_t clk_div_even_up(uint32_t a)
-{
- if (a == 1)
- return 1;
- return (a + 1) & ~1;
-}
-
-static inline uint32_t is_one_or_even(uint32_t a)
-{
- if (a == 1)
- return 1;
- if (a & 1)
- return 0;
-
- return 1;
-}
-
-static int bounds_check(struct device *dev, uint32_t val,
- uint32_t min, uint32_t max, char *str)
-{
- if (val >= min && val <= max)
- return 0;
-
- dev_warn(dev, "%s out of bounds: %d (%d--%d)\n", str, val, min, max);
-
- return -EINVAL;
-}
-
-static void print_pll(struct device *dev, struct smiapp_pll *pll)
-{
- dev_dbg(dev, "pre_pll_clk_div\t%d\n", pll->pre_pll_clk_div);
- dev_dbg(dev, "pll_multiplier \t%d\n", pll->pll_multiplier);
- if (pll->flags != SMIAPP_PLL_FLAG_NO_OP_CLOCKS) {
- dev_dbg(dev, "op_sys_clk_div \t%d\n", pll->op_sys_clk_div);
- dev_dbg(dev, "op_pix_clk_div \t%d\n", pll->op_pix_clk_div);
- }
- dev_dbg(dev, "vt_sys_clk_div \t%d\n", pll->vt_sys_clk_div);
- dev_dbg(dev, "vt_pix_clk_div \t%d\n", pll->vt_pix_clk_div);
-
- dev_dbg(dev, "ext_clk_freq_hz \t%d\n", pll->ext_clk_freq_hz);
- dev_dbg(dev, "pll_ip_clk_freq_hz \t%d\n", pll->pll_ip_clk_freq_hz);
- dev_dbg(dev, "pll_op_clk_freq_hz \t%d\n", pll->pll_op_clk_freq_hz);
- if (pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS) {
- dev_dbg(dev, "op_sys_clk_freq_hz \t%d\n",
- pll->op_sys_clk_freq_hz);
- dev_dbg(dev, "op_pix_clk_freq_hz \t%d\n",
- pll->op_pix_clk_freq_hz);
- }
- dev_dbg(dev, "vt_sys_clk_freq_hz \t%d\n", pll->vt_sys_clk_freq_hz);
- dev_dbg(dev, "vt_pix_clk_freq_hz \t%d\n", pll->vt_pix_clk_freq_hz);
-}
-
-int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
- struct smiapp_pll *pll)
-{
- uint32_t sys_div;
- uint32_t best_pix_div = INT_MAX >> 1;
- uint32_t vt_op_binning_div;
- uint32_t lane_op_clock_ratio;
- uint32_t mul, div;
- uint32_t more_mul_min, more_mul_max;
- uint32_t more_mul_factor;
- uint32_t min_vt_div, max_vt_div, vt_div;
- uint32_t min_sys_div, max_sys_div;
- unsigned int i;
- int rval;
-
- if (pll->flags & SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE)
- lane_op_clock_ratio = pll->lanes;
- else
- lane_op_clock_ratio = 1;
- dev_dbg(dev, "lane_op_clock_ratio: %d\n", lane_op_clock_ratio);
-
- dev_dbg(dev, "binning: %dx%d\n", pll->binning_horizontal,
- pll->binning_vertical);
-
- /* CSI transfers 2 bits per clock per lane; thus times 2 */
- pll->pll_op_clk_freq_hz = pll->link_freq * 2
- * (pll->lanes / lane_op_clock_ratio);
-
- /* Figure out limits for pre-pll divider based on extclk */
- dev_dbg(dev, "min / max pre_pll_clk_div: %d / %d\n",
- limits->min_pre_pll_clk_div, limits->max_pre_pll_clk_div);
- limits->max_pre_pll_clk_div =
- min_t(uint16_t, limits->max_pre_pll_clk_div,
- clk_div_even(pll->ext_clk_freq_hz /
- limits->min_pll_ip_freq_hz));
- limits->min_pre_pll_clk_div =
- max_t(uint16_t, limits->min_pre_pll_clk_div,
- clk_div_even_up(
- DIV_ROUND_UP(pll->ext_clk_freq_hz,
- limits->max_pll_ip_freq_hz)));
- dev_dbg(dev, "pre-pll check: min / max pre_pll_clk_div: %d / %d\n",
- limits->min_pre_pll_clk_div, limits->max_pre_pll_clk_div);
-
- i = gcd(pll->pll_op_clk_freq_hz, pll->ext_clk_freq_hz);
- mul = div_u64(pll->pll_op_clk_freq_hz, i);
- div = pll->ext_clk_freq_hz / i;
- dev_dbg(dev, "mul %d / div %d\n", mul, div);
-
- limits->min_pre_pll_clk_div =
- max_t(uint16_t, limits->min_pre_pll_clk_div,
- clk_div_even_up(
- DIV_ROUND_UP(mul * pll->ext_clk_freq_hz,
- limits->max_pll_op_freq_hz)));
- dev_dbg(dev, "pll_op check: min / max pre_pll_clk_div: %d / %d\n",
- limits->min_pre_pll_clk_div, limits->max_pre_pll_clk_div);
-
- if (limits->min_pre_pll_clk_div > limits->max_pre_pll_clk_div) {
- dev_err(dev, "unable to compute pre_pll divisor\n");
- return -EINVAL;
- }
-
- pll->pre_pll_clk_div = limits->min_pre_pll_clk_div;
-
- /*
- * Get pre_pll_clk_div so that our pll_op_clk_freq_hz won't be
- * too high.
- */
- dev_dbg(dev, "pre_pll_clk_div %d\n", pll->pre_pll_clk_div);
-
- /* Don't go above max pll multiplier. */
- more_mul_max = limits->max_pll_multiplier / mul;
- dev_dbg(dev, "more_mul_max: max_pll_multiplier check: %d\n",
- more_mul_max);
- /* Don't go above max pll op frequency. */
- more_mul_max =
- min_t(int,
- more_mul_max,
- limits->max_pll_op_freq_hz
- / (pll->ext_clk_freq_hz / pll->pre_pll_clk_div * mul));
- dev_dbg(dev, "more_mul_max: max_pll_op_freq_hz check: %d\n",
- more_mul_max);
- /* Don't go above the division capability of op sys clock divider. */
- more_mul_max = min(more_mul_max,
- limits->max_op_sys_clk_div * pll->pre_pll_clk_div
- / div);
- dev_dbg(dev, "more_mul_max: max_op_sys_clk_div check: %d\n",
- more_mul_max);
- /* Ensure we won't go above min_pll_multiplier. */
- more_mul_max = min(more_mul_max,
- DIV_ROUND_UP(limits->max_pll_multiplier, mul));
- dev_dbg(dev, "more_mul_max: min_pll_multiplier check: %d\n",
- more_mul_max);
-
- /* Ensure we won't go below min_pll_op_freq_hz. */
- more_mul_min = DIV_ROUND_UP(limits->min_pll_op_freq_hz,
- pll->ext_clk_freq_hz / pll->pre_pll_clk_div
- * mul);
- dev_dbg(dev, "more_mul_min: min_pll_op_freq_hz check: %d\n",
- more_mul_min);
- /* Ensure we won't go below min_pll_multiplier. */
- more_mul_min = max(more_mul_min,
- DIV_ROUND_UP(limits->min_pll_multiplier, mul));
- dev_dbg(dev, "more_mul_min: min_pll_multiplier check: %d\n",
- more_mul_min);
-
- if (more_mul_min > more_mul_max) {
- dev_warn(dev,
- "unable to compute more_mul_min and more_mul_max");
- return -EINVAL;
- }
-
- more_mul_factor = lcm(div, pll->pre_pll_clk_div) / div;
- dev_dbg(dev, "more_mul_factor: %d\n", more_mul_factor);
- more_mul_factor = lcm(more_mul_factor, limits->min_op_sys_clk_div);
- dev_dbg(dev, "more_mul_factor: min_op_sys_clk_div: %d\n",
- more_mul_factor);
- i = roundup(more_mul_min, more_mul_factor);
- if (!is_one_or_even(i))
- i <<= 1;
-
- dev_dbg(dev, "final more_mul: %d\n", i);
- if (i > more_mul_max) {
- dev_warn(dev, "final more_mul is bad, max %d", more_mul_max);
- return -EINVAL;
- }
-
- pll->pll_multiplier = mul * i;
- pll->op_sys_clk_div = div * i / pll->pre_pll_clk_div;
- dev_dbg(dev, "op_sys_clk_div: %d\n", pll->op_sys_clk_div);
-
- pll->pll_ip_clk_freq_hz = pll->ext_clk_freq_hz
- / pll->pre_pll_clk_div;
-
- pll->pll_op_clk_freq_hz = pll->pll_ip_clk_freq_hz
- * pll->pll_multiplier;
-
- /* Derive pll_op_clk_freq_hz. */
- pll->op_sys_clk_freq_hz =
- pll->pll_op_clk_freq_hz / pll->op_sys_clk_div;
-
- pll->op_pix_clk_div = pll->bits_per_pixel;
- dev_dbg(dev, "op_pix_clk_div: %d\n", pll->op_pix_clk_div);
-
- pll->op_pix_clk_freq_hz =
- pll->op_sys_clk_freq_hz / pll->op_pix_clk_div;
-
- /*
- * Some sensors perform analogue binning and some do this
- * digitally. The ones doing this digitally can be roughly be
- * found out using this formula. The ones doing this digitally
- * should run at higher clock rate, so smaller divisor is used
- * on video timing side.
- */
- if (limits->min_line_length_pck_bin > limits->min_line_length_pck
- / pll->binning_horizontal)
- vt_op_binning_div = pll->binning_horizontal;
- else
- vt_op_binning_div = 1;
- dev_dbg(dev, "vt_op_binning_div: %d\n", vt_op_binning_div);
-
- /*
- * Profile 2 supports vt_pix_clk_div E [4, 10]
- *
- * Horizontal binning can be used as a base for difference in
- * divisors. One must make sure that horizontal blanking is
- * enough to accommodate the CSI-2 sync codes.
- *
- * Take scaling factor into account as well.
- *
- * Find absolute limits for the factor of vt divider.
- */
- dev_dbg(dev, "scale_m: %d\n", pll->scale_m);
- min_vt_div = DIV_ROUND_UP(pll->op_pix_clk_div * pll->op_sys_clk_div
- * pll->scale_n,
- lane_op_clock_ratio * vt_op_binning_div
- * pll->scale_m);
-
- /* Find smallest and biggest allowed vt divisor. */
- dev_dbg(dev, "min_vt_div: %d\n", min_vt_div);
- min_vt_div = max(min_vt_div,
- DIV_ROUND_UP(pll->pll_op_clk_freq_hz,
- limits->max_vt_pix_clk_freq_hz));
- dev_dbg(dev, "min_vt_div: max_vt_pix_clk_freq_hz: %d\n",
- min_vt_div);
- min_vt_div = max_t(uint32_t, min_vt_div,
- limits->min_vt_pix_clk_div
- * limits->min_vt_sys_clk_div);
- dev_dbg(dev, "min_vt_div: min_vt_clk_div: %d\n", min_vt_div);
-
- max_vt_div = limits->max_vt_sys_clk_div * limits->max_vt_pix_clk_div;
- dev_dbg(dev, "max_vt_div: %d\n", max_vt_div);
- max_vt_div = min(max_vt_div,
- DIV_ROUND_UP(pll->pll_op_clk_freq_hz,
- limits->min_vt_pix_clk_freq_hz));
- dev_dbg(dev, "max_vt_div: min_vt_pix_clk_freq_hz: %d\n",
- max_vt_div);
-
- /*
- * Find limitsits for sys_clk_div. Not all values are possible
- * with all values of pix_clk_div.
- */
- min_sys_div = limits->min_vt_sys_clk_div;
- dev_dbg(dev, "min_sys_div: %d\n", min_sys_div);
- min_sys_div = max(min_sys_div,
- DIV_ROUND_UP(min_vt_div,
- limits->max_vt_pix_clk_div));
- dev_dbg(dev, "min_sys_div: max_vt_pix_clk_div: %d\n", min_sys_div);
- min_sys_div = max(min_sys_div,
- pll->pll_op_clk_freq_hz
- / limits->max_vt_sys_clk_freq_hz);
- dev_dbg(dev, "min_sys_div: max_pll_op_clk_freq_hz: %d\n", min_sys_div);
- min_sys_div = clk_div_even_up(min_sys_div);
- dev_dbg(dev, "min_sys_div: one or even: %d\n", min_sys_div);
-
- max_sys_div = limits->max_vt_sys_clk_div;
- dev_dbg(dev, "max_sys_div: %d\n", max_sys_div);
- max_sys_div = min(max_sys_div,
- DIV_ROUND_UP(max_vt_div,
- limits->min_vt_pix_clk_div));
- dev_dbg(dev, "max_sys_div: min_vt_pix_clk_div: %d\n", max_sys_div);
- max_sys_div = min(max_sys_div,
- DIV_ROUND_UP(pll->pll_op_clk_freq_hz,
- limits->min_vt_pix_clk_freq_hz));
- dev_dbg(dev, "max_sys_div: min_vt_pix_clk_freq_hz: %d\n", max_sys_div);
-
- /*
- * Find pix_div such that a legal pix_div * sys_div results
- * into a value which is not smaller than div, the desired
- * divisor.
- */
- for (vt_div = min_vt_div; vt_div <= max_vt_div;
- vt_div += 2 - (vt_div & 1)) {
- for (sys_div = min_sys_div;
- sys_div <= max_sys_div;
- sys_div += 2 - (sys_div & 1)) {
- int pix_div = DIV_ROUND_UP(vt_div, sys_div);
-
- if (pix_div < limits->min_vt_pix_clk_div
- || pix_div > limits->max_vt_pix_clk_div) {
- dev_dbg(dev,
- "pix_div %d too small or too big (%d--%d)\n",
- pix_div,
- limits->min_vt_pix_clk_div,
- limits->max_vt_pix_clk_div);
- continue;
- }
-
- /* Check if this one is better. */
- if (pix_div * sys_div
- <= roundup(min_vt_div, best_pix_div))
- best_pix_div = pix_div;
- }
- if (best_pix_div < INT_MAX >> 1)
- break;
- }
-
- pll->vt_sys_clk_div = DIV_ROUND_UP(min_vt_div, best_pix_div);
- pll->vt_pix_clk_div = best_pix_div;
-
- pll->vt_sys_clk_freq_hz =
- pll->pll_op_clk_freq_hz / pll->vt_sys_clk_div;
- pll->vt_pix_clk_freq_hz =
- pll->vt_sys_clk_freq_hz / pll->vt_pix_clk_div;
-
- pll->pixel_rate_csi =
- pll->op_pix_clk_freq_hz * lane_op_clock_ratio;
-
- print_pll(dev, pll);
-
- rval = bounds_check(dev, pll->pre_pll_clk_div,
- limits->min_pre_pll_clk_div,
- limits->max_pre_pll_clk_div, "pre_pll_clk_div");
- if (!rval)
- rval = bounds_check(
- dev, pll->pll_ip_clk_freq_hz,
- limits->min_pll_ip_freq_hz, limits->max_pll_ip_freq_hz,
- "pll_ip_clk_freq_hz");
- if (!rval)
- rval = bounds_check(
- dev, pll->pll_multiplier,
- limits->min_pll_multiplier, limits->max_pll_multiplier,
- "pll_multiplier");
- if (!rval)
- rval = bounds_check(
- dev, pll->pll_op_clk_freq_hz,
- limits->min_pll_op_freq_hz, limits->max_pll_op_freq_hz,
- "pll_op_clk_freq_hz");
- if (!rval)
- rval = bounds_check(
- dev, pll->op_sys_clk_div,
- limits->min_op_sys_clk_div, limits->max_op_sys_clk_div,
- "op_sys_clk_div");
- if (!rval)
- rval = bounds_check(
- dev, pll->op_pix_clk_div,
- limits->min_op_pix_clk_div, limits->max_op_pix_clk_div,
- "op_pix_clk_div");
- if (!rval)
- rval = bounds_check(
- dev, pll->op_sys_clk_freq_hz,
- limits->min_op_sys_clk_freq_hz,
- limits->max_op_sys_clk_freq_hz,
- "op_sys_clk_freq_hz");
- if (!rval)
- rval = bounds_check(
- dev, pll->op_pix_clk_freq_hz,
- limits->min_op_pix_clk_freq_hz,
- limits->max_op_pix_clk_freq_hz,
- "op_pix_clk_freq_hz");
- if (!rval)
- rval = bounds_check(
- dev, pll->vt_sys_clk_freq_hz,
- limits->min_vt_sys_clk_freq_hz,
- limits->max_vt_sys_clk_freq_hz,
- "vt_sys_clk_freq_hz");
- if (!rval)
- rval = bounds_check(
- dev, pll->vt_pix_clk_freq_hz,
- limits->min_vt_pix_clk_freq_hz,
- limits->max_vt_pix_clk_freq_hz,
- "vt_pix_clk_freq_hz");
-
- return rval;
-}
-EXPORT_SYMBOL_GPL(smiapp_pll_calculate);
-
-MODULE_AUTHOR("Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>");
-MODULE_DESCRIPTION("Generic SMIA/SMIA++ PLL calculator");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/smiapp-pll.h b/drivers/media/video/smiapp-pll.h
deleted file mode 100644
index 9eab63f23af..00000000000
--- a/drivers/media/video/smiapp-pll.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * drivers/media/video/smiapp-pll.h
- *
- * Generic driver for SMIA/SMIA++ compliant camera modules
- *
- * Copyright (C) 2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef SMIAPP_PLL_H
-#define SMIAPP_PLL_H
-
-#include <linux/device.h>
-
-struct smiapp_pll {
- uint8_t lanes;
- uint8_t binning_horizontal;
- uint8_t binning_vertical;
- uint8_t scale_m;
- uint8_t scale_n;
- uint8_t bits_per_pixel;
- uint16_t flags;
- uint32_t link_freq;
-
- uint16_t pre_pll_clk_div;
- uint16_t pll_multiplier;
- uint16_t op_sys_clk_div;
- uint16_t op_pix_clk_div;
- uint16_t vt_sys_clk_div;
- uint16_t vt_pix_clk_div;
-
- uint32_t ext_clk_freq_hz;
- uint32_t pll_ip_clk_freq_hz;
- uint32_t pll_op_clk_freq_hz;
- uint32_t op_sys_clk_freq_hz;
- uint32_t op_pix_clk_freq_hz;
- uint32_t vt_sys_clk_freq_hz;
- uint32_t vt_pix_clk_freq_hz;
-
- uint32_t pixel_rate_csi;
-};
-
-struct smiapp_pll_limits {
- /* Strict PLL limits */
- uint32_t min_ext_clk_freq_hz;
- uint32_t max_ext_clk_freq_hz;
- uint16_t min_pre_pll_clk_div;
- uint16_t max_pre_pll_clk_div;
- uint32_t min_pll_ip_freq_hz;
- uint32_t max_pll_ip_freq_hz;
- uint16_t min_pll_multiplier;
- uint16_t max_pll_multiplier;
- uint32_t min_pll_op_freq_hz;
- uint32_t max_pll_op_freq_hz;
-
- uint16_t min_vt_sys_clk_div;
- uint16_t max_vt_sys_clk_div;
- uint32_t min_vt_sys_clk_freq_hz;
- uint32_t max_vt_sys_clk_freq_hz;
- uint16_t min_vt_pix_clk_div;
- uint16_t max_vt_pix_clk_div;
- uint32_t min_vt_pix_clk_freq_hz;
- uint32_t max_vt_pix_clk_freq_hz;
-
- uint16_t min_op_sys_clk_div;
- uint16_t max_op_sys_clk_div;
- uint32_t min_op_sys_clk_freq_hz;
- uint32_t max_op_sys_clk_freq_hz;
- uint16_t min_op_pix_clk_div;
- uint16_t max_op_pix_clk_div;
- uint32_t min_op_pix_clk_freq_hz;
- uint32_t max_op_pix_clk_freq_hz;
-
- /* Other relevant limits */
- uint32_t min_line_length_pck_bin;
- uint32_t min_line_length_pck;
-};
-
-/* op pix clock is for all lanes in total normally */
-#define SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE (1 << 0)
-#define SMIAPP_PLL_FLAG_NO_OP_CLOCKS (1 << 1)
-
-struct device;
-
-int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
- struct smiapp_pll *pll);
-
-#endif /* SMIAPP_PLL_H */
diff --git a/drivers/media/video/smiapp/Kconfig b/drivers/media/video/smiapp/Kconfig
deleted file mode 100644
index 3149cda1d0d..00000000000
--- a/drivers/media/video/smiapp/Kconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-config VIDEO_SMIAPP
- tristate "SMIA++/SMIA sensor support"
- depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAVE_CLK
- depends on MEDIA_CAMERA_SUPPORT
- select VIDEO_SMIAPP_PLL
- ---help---
- This is a generic driver for SMIA++/SMIA camera modules.
diff --git a/drivers/media/video/smiapp/Makefile b/drivers/media/video/smiapp/Makefile
deleted file mode 100644
index 36b0cfa2c54..00000000000
--- a/drivers/media/video/smiapp/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-smiapp-objs += smiapp-core.o smiapp-regs.o \
- smiapp-quirk.o smiapp-limits.o
-obj-$(CONFIG_VIDEO_SMIAPP) += smiapp.o
-
-ccflags-y += -Idrivers/media/video
diff --git a/drivers/media/video/smiapp/smiapp-core.c b/drivers/media/video/smiapp/smiapp-core.c
deleted file mode 100644
index bfd47c10613..00000000000
--- a/drivers/media/video/smiapp/smiapp-core.c
+++ /dev/null
@@ -1,2895 +0,0 @@
-/*
- * drivers/media/video/smiapp/smiapp-core.c
- *
- * Generic driver for SMIA/SMIA++ compliant camera modules
- *
- * Copyright (C) 2010--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * Based on smiapp driver by Vimarsh Zutshi
- * Based on jt8ev1.c by Vimarsh Zutshi
- * Based on smia-sensor.c by Tuukka Toivonen <tuukkat76@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/regulator/consumer.h>
-#include <linux/v4l2-mediabus.h>
-#include <media/v4l2-device.h>
-
-#include "smiapp.h"
-
-#define SMIAPP_ALIGN_DIM(dim, flags) \
- ((flags) & V4L2_SEL_FLAG_GE \
- ? ALIGN((dim), 2) \
- : (dim) & ~1)
-
-/*
- * smiapp_module_idents - supported camera modules
- */
-static const struct smiapp_module_ident smiapp_module_idents[] = {
- SMIAPP_IDENT_L(0x01, 0x022b, -1, "vs6555"),
- SMIAPP_IDENT_L(0x01, 0x022e, -1, "vw6558"),
- SMIAPP_IDENT_L(0x07, 0x7698, -1, "ovm7698"),
- SMIAPP_IDENT_L(0x0b, 0x4242, -1, "smiapp-003"),
- SMIAPP_IDENT_L(0x0c, 0x208a, -1, "tcm8330md"),
- SMIAPP_IDENT_LQ(0x0c, 0x2134, -1, "tcm8500md", &smiapp_tcm8500md_quirk),
- SMIAPP_IDENT_L(0x0c, 0x213e, -1, "et8en2"),
- SMIAPP_IDENT_L(0x0c, 0x2184, -1, "tcm8580md"),
- SMIAPP_IDENT_LQ(0x0c, 0x560f, -1, "jt8ew9", &smiapp_jt8ew9_quirk),
- SMIAPP_IDENT_LQ(0x10, 0x4141, -1, "jt8ev1", &smiapp_jt8ev1_quirk),
- SMIAPP_IDENT_LQ(0x10, 0x4241, -1, "imx125es", &smiapp_imx125es_quirk),
-};
-
-/*
- *
- * Dynamic Capability Identification
- *
- */
-
-static int smiapp_read_frame_fmt(struct smiapp_sensor *sensor)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- u32 fmt_model_type, fmt_model_subtype, ncol_desc, nrow_desc;
- unsigned int i;
- int rval;
- int line_count = 0;
- int embedded_start = -1, embedded_end = -1;
- int image_start = 0;
-
- rval = smiapp_read(sensor, SMIAPP_REG_U8_FRAME_FORMAT_MODEL_TYPE,
- &fmt_model_type);
- if (rval)
- return rval;
-
- rval = smiapp_read(sensor, SMIAPP_REG_U8_FRAME_FORMAT_MODEL_SUBTYPE,
- &fmt_model_subtype);
- if (rval)
- return rval;
-
- ncol_desc = (fmt_model_subtype
- & SMIAPP_FRAME_FORMAT_MODEL_SUBTYPE_NCOLS_MASK)
- >> SMIAPP_FRAME_FORMAT_MODEL_SUBTYPE_NCOLS_SHIFT;
- nrow_desc = fmt_model_subtype
- & SMIAPP_FRAME_FORMAT_MODEL_SUBTYPE_NROWS_MASK;
-
- dev_dbg(&client->dev, "format_model_type %s\n",
- fmt_model_type == SMIAPP_FRAME_FORMAT_MODEL_TYPE_2BYTE
- ? "2 byte" :
- fmt_model_type == SMIAPP_FRAME_FORMAT_MODEL_TYPE_4BYTE
- ? "4 byte" : "is simply bad");
-
- for (i = 0; i < ncol_desc + nrow_desc; i++) {
- u32 desc;
- u32 pixelcode;
- u32 pixels;
- char *which;
- char *what;
-
- if (fmt_model_type == SMIAPP_FRAME_FORMAT_MODEL_TYPE_2BYTE) {
- rval = smiapp_read(
- sensor,
- SMIAPP_REG_U16_FRAME_FORMAT_DESCRIPTOR_2(i),
- &desc);
- if (rval)
- return rval;
-
- pixelcode =
- (desc
- & SMIAPP_FRAME_FORMAT_DESC_2_PIXELCODE_MASK)
- >> SMIAPP_FRAME_FORMAT_DESC_2_PIXELCODE_SHIFT;
- pixels = desc & SMIAPP_FRAME_FORMAT_DESC_2_PIXELS_MASK;
- } else if (fmt_model_type
- == SMIAPP_FRAME_FORMAT_MODEL_TYPE_4BYTE) {
- rval = smiapp_read(
- sensor,
- SMIAPP_REG_U32_FRAME_FORMAT_DESCRIPTOR_4(i),
- &desc);
- if (rval)
- return rval;
-
- pixelcode =
- (desc
- & SMIAPP_FRAME_FORMAT_DESC_4_PIXELCODE_MASK)
- >> SMIAPP_FRAME_FORMAT_DESC_4_PIXELCODE_SHIFT;
- pixels = desc & SMIAPP_FRAME_FORMAT_DESC_4_PIXELS_MASK;
- } else {
- dev_dbg(&client->dev,
- "invalid frame format model type %d\n",
- fmt_model_type);
- return -EINVAL;
- }
-
- if (i < ncol_desc)
- which = "columns";
- else
- which = "rows";
-
- switch (pixelcode) {
- case SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_EMBEDDED:
- what = "embedded";
- break;
- case SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_DUMMY:
- what = "dummy";
- break;
- case SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_BLACK:
- what = "black";
- break;
- case SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_DARK:
- what = "dark";
- break;
- case SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_VISIBLE:
- what = "visible";
- break;
- default:
- what = "invalid";
- dev_dbg(&client->dev, "pixelcode %d\n", pixelcode);
- break;
- }
-
- dev_dbg(&client->dev, "%s pixels: %d %s\n",
- what, pixels, which);
-
- if (i < ncol_desc)
- continue;
-
- /* Handle row descriptors */
- if (pixelcode
- == SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_EMBEDDED) {
- embedded_start = line_count;
- } else {
- if (pixelcode == SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_VISIBLE
- || pixels >= sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES] / 2)
- image_start = line_count;
- if (embedded_start != -1 && embedded_end == -1)
- embedded_end = line_count;
- }
- line_count += pixels;
- }
-
- if (embedded_start == -1 || embedded_end == -1) {
- embedded_start = 0;
- embedded_end = 0;
- }
-
- dev_dbg(&client->dev, "embedded data from lines %d to %d\n",
- embedded_start, embedded_end);
- dev_dbg(&client->dev, "image data starts at line %d\n", image_start);
-
- return 0;
-}
-
-static int smiapp_pll_configure(struct smiapp_sensor *sensor)
-{
- struct smiapp_pll *pll = &sensor->pll;
- int rval;
-
- rval = smiapp_write(
- sensor, SMIAPP_REG_U16_VT_PIX_CLK_DIV, pll->vt_pix_clk_div);
- if (rval < 0)
- return rval;
-
- rval = smiapp_write(
- sensor, SMIAPP_REG_U16_VT_SYS_CLK_DIV, pll->vt_sys_clk_div);
- if (rval < 0)
- return rval;
-
- rval = smiapp_write(
- sensor, SMIAPP_REG_U16_PRE_PLL_CLK_DIV, pll->pre_pll_clk_div);
- if (rval < 0)
- return rval;
-
- rval = smiapp_write(
- sensor, SMIAPP_REG_U16_PLL_MULTIPLIER, pll->pll_multiplier);
- if (rval < 0)
- return rval;
-
- /* Lane op clock ratio does not apply here. */
- rval = smiapp_write(
- sensor, SMIAPP_REG_U32_REQUESTED_LINK_BIT_RATE_MBPS,
- DIV_ROUND_UP(pll->op_sys_clk_freq_hz, 1000000 / 256 / 256));
- if (rval < 0 || sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)
- return rval;
-
- rval = smiapp_write(
- sensor, SMIAPP_REG_U16_OP_PIX_CLK_DIV, pll->op_pix_clk_div);
- if (rval < 0)
- return rval;
-
- return smiapp_write(
- sensor, SMIAPP_REG_U16_OP_SYS_CLK_DIV, pll->op_sys_clk_div);
-}
-
-static int smiapp_pll_update(struct smiapp_sensor *sensor)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- struct smiapp_pll_limits lim = {
- .min_pre_pll_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_PRE_PLL_CLK_DIV],
- .max_pre_pll_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_PRE_PLL_CLK_DIV],
- .min_pll_ip_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_PLL_IP_FREQ_HZ],
- .max_pll_ip_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_PLL_IP_FREQ_HZ],
- .min_pll_multiplier = sensor->limits[SMIAPP_LIMIT_MIN_PLL_MULTIPLIER],
- .max_pll_multiplier = sensor->limits[SMIAPP_LIMIT_MAX_PLL_MULTIPLIER],
- .min_pll_op_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_PLL_OP_FREQ_HZ],
- .max_pll_op_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_PLL_OP_FREQ_HZ],
-
- .min_op_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV],
- .max_op_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV],
- .min_op_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV],
- .max_op_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV],
- .min_op_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_FREQ_HZ],
- .max_op_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_FREQ_HZ],
- .min_op_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_FREQ_HZ],
- .max_op_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_FREQ_HZ],
-
- .min_vt_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_VT_SYS_CLK_DIV],
- .max_vt_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_VT_SYS_CLK_DIV],
- .min_vt_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_VT_PIX_CLK_DIV],
- .max_vt_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_VT_PIX_CLK_DIV],
- .min_vt_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_VT_SYS_CLK_FREQ_HZ],
- .max_vt_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_VT_SYS_CLK_FREQ_HZ],
- .min_vt_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_VT_PIX_CLK_FREQ_HZ],
- .max_vt_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_VT_PIX_CLK_FREQ_HZ],
-
- .min_line_length_pck_bin = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN],
- .min_line_length_pck = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK],
- };
- struct smiapp_pll *pll = &sensor->pll;
- int rval;
-
- memset(&sensor->pll, 0, sizeof(sensor->pll));
-
- pll->lanes = sensor->platform_data->lanes;
- pll->ext_clk_freq_hz = sensor->platform_data->ext_clk;
-
- if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) {
- /*
- * Fill in operational clock divisors limits from the
- * video timing ones. On profile 0 sensors the
- * requirements regarding them are essentially the
- * same as on VT ones.
- */
- lim.min_op_sys_clk_div = lim.min_vt_sys_clk_div;
- lim.max_op_sys_clk_div = lim.max_vt_sys_clk_div;
- lim.min_op_pix_clk_div = lim.min_vt_pix_clk_div;
- lim.max_op_pix_clk_div = lim.max_vt_pix_clk_div;
- lim.min_op_sys_clk_freq_hz = lim.min_vt_sys_clk_freq_hz;
- lim.max_op_sys_clk_freq_hz = lim.max_vt_sys_clk_freq_hz;
- lim.min_op_pix_clk_freq_hz = lim.min_vt_pix_clk_freq_hz;
- lim.max_op_pix_clk_freq_hz = lim.max_vt_pix_clk_freq_hz;
- /* Profile 0 sensors have no separate OP clock branch. */
- pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS;
- }
-
- if (smiapp_needs_quirk(sensor,
- SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE))
- pll->flags |= SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE;
-
- pll->binning_horizontal = sensor->binning_horizontal;
- pll->binning_vertical = sensor->binning_vertical;
- pll->link_freq =
- sensor->link_freq->qmenu_int[sensor->link_freq->val];
- pll->scale_m = sensor->scale_m;
- pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
- pll->bits_per_pixel = sensor->csi_format->compressed;
-
- rval = smiapp_pll_calculate(&client->dev, &lim, pll);
- if (rval < 0)
- return rval;
-
- sensor->pixel_rate_parray->cur.val64 = pll->vt_pix_clk_freq_hz;
- sensor->pixel_rate_csi->cur.val64 = pll->pixel_rate_csi;
-
- return 0;
-}
-
-
-/*
- *
- * V4L2 Controls handling
- *
- */
-
-static void __smiapp_update_exposure_limits(struct smiapp_sensor *sensor)
-{
- struct v4l2_ctrl *ctrl = sensor->exposure;
- int max;
-
- max = sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
- + sensor->vblank->val
- - sensor->limits[SMIAPP_LIMIT_COARSE_INTEGRATION_TIME_MAX_MARGIN];
-
- ctrl->maximum = max;
- if (ctrl->default_value > max)
- ctrl->default_value = max;
- if (ctrl->val > max)
- ctrl->val = max;
- if (ctrl->cur.val > max)
- ctrl->cur.val = max;
-}
-
-/*
- * Order matters.
- *
- * 1. Bits-per-pixel, descending.
- * 2. Bits-per-pixel compressed, descending.
- * 3. Pixel order, same as in pixel_order_str. Formats for all four pixel
- * orders must be defined.
- */
-static const struct smiapp_csi_data_format smiapp_csi_data_formats[] = {
- { V4L2_MBUS_FMT_SGRBG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GRBG, },
- { V4L2_MBUS_FMT_SRGGB12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_RGGB, },
- { V4L2_MBUS_FMT_SBGGR12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_BGGR, },
- { V4L2_MBUS_FMT_SGBRG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GBRG, },
- { V4L2_MBUS_FMT_SGRBG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GRBG, },
- { V4L2_MBUS_FMT_SRGGB10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_RGGB, },
- { V4L2_MBUS_FMT_SBGGR10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_BGGR, },
- { V4L2_MBUS_FMT_SGBRG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GBRG, },
- { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GRBG, },
- { V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_RGGB, },
- { V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_BGGR, },
- { V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GBRG, },
- { V4L2_MBUS_FMT_SGRBG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GRBG, },
- { V4L2_MBUS_FMT_SRGGB8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_RGGB, },
- { V4L2_MBUS_FMT_SBGGR8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_BGGR, },
- { V4L2_MBUS_FMT_SGBRG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GBRG, },
-};
-
-const char *pixel_order_str[] = { "GRBG", "RGGB", "BGGR", "GBRG" };
-
-#define to_csi_format_idx(fmt) (((unsigned long)(fmt) \
- - (unsigned long)smiapp_csi_data_formats) \
- / sizeof(*smiapp_csi_data_formats))
-
-static u32 smiapp_pixel_order(struct smiapp_sensor *sensor)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- int flip = 0;
-
- if (sensor->hflip) {
- if (sensor->hflip->val)
- flip |= SMIAPP_IMAGE_ORIENTATION_HFLIP;
-
- if (sensor->vflip->val)
- flip |= SMIAPP_IMAGE_ORIENTATION_VFLIP;
- }
-
- flip ^= sensor->hvflip_inv_mask;
-
- dev_dbg(&client->dev, "flip %d\n", flip);
- return sensor->default_pixel_order ^ flip;
-}
-
-static void smiapp_update_mbus_formats(struct smiapp_sensor *sensor)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- unsigned int csi_format_idx =
- to_csi_format_idx(sensor->csi_format) & ~3;
- unsigned int internal_csi_format_idx =
- to_csi_format_idx(sensor->internal_csi_format) & ~3;
- unsigned int pixel_order = smiapp_pixel_order(sensor);
-
- sensor->mbus_frame_fmts =
- sensor->default_mbus_frame_fmts << pixel_order;
- sensor->csi_format =
- &smiapp_csi_data_formats[csi_format_idx + pixel_order];
- sensor->internal_csi_format =
- &smiapp_csi_data_formats[internal_csi_format_idx
- + pixel_order];
-
- BUG_ON(max(internal_csi_format_idx, csi_format_idx) + pixel_order
- >= ARRAY_SIZE(smiapp_csi_data_formats));
- BUG_ON(min(internal_csi_format_idx, csi_format_idx) < 0);
-
- dev_dbg(&client->dev, "new pixel order %s\n",
- pixel_order_str[pixel_order]);
-}
-
-static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct smiapp_sensor *sensor =
- container_of(ctrl->handler, struct smiapp_subdev, ctrl_handler)
- ->sensor;
- u32 orient = 0;
- int exposure;
- int rval;
-
- switch (ctrl->id) {
- case V4L2_CID_ANALOGUE_GAIN:
- return smiapp_write(
- sensor,
- SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL, ctrl->val);
-
- case V4L2_CID_EXPOSURE:
- return smiapp_write(
- sensor,
- SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val);
-
- case V4L2_CID_HFLIP:
- case V4L2_CID_VFLIP:
- if (sensor->streaming)
- return -EBUSY;
-
- if (sensor->hflip->val)
- orient |= SMIAPP_IMAGE_ORIENTATION_HFLIP;
-
- if (sensor->vflip->val)
- orient |= SMIAPP_IMAGE_ORIENTATION_VFLIP;
-
- orient ^= sensor->hvflip_inv_mask;
- rval = smiapp_write(sensor,
- SMIAPP_REG_U8_IMAGE_ORIENTATION,
- orient);
- if (rval < 0)
- return rval;
-
- smiapp_update_mbus_formats(sensor);
-
- return 0;
-
- case V4L2_CID_VBLANK:
- exposure = sensor->exposure->val;
-
- __smiapp_update_exposure_limits(sensor);
-
- if (exposure > sensor->exposure->maximum) {
- sensor->exposure->val =
- sensor->exposure->maximum;
- rval = smiapp_set_ctrl(
- sensor->exposure);
- if (rval < 0)
- return rval;
- }
-
- return smiapp_write(
- sensor, SMIAPP_REG_U16_FRAME_LENGTH_LINES,
- sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
- + ctrl->val);
-
- case V4L2_CID_HBLANK:
- return smiapp_write(
- sensor, SMIAPP_REG_U16_LINE_LENGTH_PCK,
- sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
- + ctrl->val);
-
- case V4L2_CID_LINK_FREQ:
- if (sensor->streaming)
- return -EBUSY;
-
- return smiapp_pll_update(sensor);
-
- default:
- return -EINVAL;
- }
-}
-
-static const struct v4l2_ctrl_ops smiapp_ctrl_ops = {
- .s_ctrl = smiapp_set_ctrl,
-};
-
-static int smiapp_init_controls(struct smiapp_sensor *sensor)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- unsigned int max;
- int rval;
-
- rval = v4l2_ctrl_handler_init(&sensor->pixel_array->ctrl_handler, 7);
- if (rval)
- return rval;
- sensor->pixel_array->ctrl_handler.lock = &sensor->mutex;
-
- sensor->analog_gain = v4l2_ctrl_new_std(
- &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
- V4L2_CID_ANALOGUE_GAIN,
- sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MIN],
- sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MAX],
- max(sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_STEP], 1U),
- sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MIN]);
-
- /* Exposure limits will be updated soon, use just something here. */
- sensor->exposure = v4l2_ctrl_new_std(
- &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 0, 1, 0);
-
- sensor->hflip = v4l2_ctrl_new_std(
- &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- sensor->vflip = v4l2_ctrl_new_std(
- &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
-
- sensor->vblank = v4l2_ctrl_new_std(
- &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
- V4L2_CID_VBLANK, 0, 1, 1, 0);
-
- if (sensor->vblank)
- sensor->vblank->flags |= V4L2_CTRL_FLAG_UPDATE;
-
- sensor->hblank = v4l2_ctrl_new_std(
- &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
- V4L2_CID_HBLANK, 0, 1, 1, 0);
-
- if (sensor->hblank)
- sensor->hblank->flags |= V4L2_CTRL_FLAG_UPDATE;
-
- sensor->pixel_rate_parray = v4l2_ctrl_new_std(
- &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
- V4L2_CID_PIXEL_RATE, 0, 0, 1, 0);
-
- if (sensor->pixel_array->ctrl_handler.error) {
- dev_err(&client->dev,
- "pixel array controls initialization failed (%d)\n",
- sensor->pixel_array->ctrl_handler.error);
- rval = sensor->pixel_array->ctrl_handler.error;
- goto error;
- }
-
- sensor->pixel_array->sd.ctrl_handler =
- &sensor->pixel_array->ctrl_handler;
-
- v4l2_ctrl_cluster(2, &sensor->hflip);
-
- rval = v4l2_ctrl_handler_init(&sensor->src->ctrl_handler, 0);
- if (rval)
- goto error;
- sensor->src->ctrl_handler.lock = &sensor->mutex;
-
- for (max = 0; sensor->platform_data->op_sys_clock[max + 1]; max++);
-
- sensor->link_freq = v4l2_ctrl_new_int_menu(
- &sensor->src->ctrl_handler, &smiapp_ctrl_ops,
- V4L2_CID_LINK_FREQ, max, 0,
- sensor->platform_data->op_sys_clock);
-
- sensor->pixel_rate_csi = v4l2_ctrl_new_std(
- &sensor->src->ctrl_handler, &smiapp_ctrl_ops,
- V4L2_CID_PIXEL_RATE, 0, 0, 1, 0);
-
- if (sensor->src->ctrl_handler.error) {
- dev_err(&client->dev,
- "src controls initialization failed (%d)\n",
- sensor->src->ctrl_handler.error);
- rval = sensor->src->ctrl_handler.error;
- goto error;
- }
-
- sensor->src->sd.ctrl_handler =
- &sensor->src->ctrl_handler;
-
- return 0;
-
-error:
- v4l2_ctrl_handler_free(&sensor->pixel_array->ctrl_handler);
- v4l2_ctrl_handler_free(&sensor->src->ctrl_handler);
-
- return rval;
-}
-
-static void smiapp_free_controls(struct smiapp_sensor *sensor)
-{
- unsigned int i;
-
- for (i = 0; i < sensor->ssds_used; i++)
- v4l2_ctrl_handler_free(&sensor->ssds[i].ctrl_handler);
-}
-
-static int smiapp_get_limits(struct smiapp_sensor *sensor, int const *limit,
- unsigned int n)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- unsigned int i;
- u32 val;
- int rval;
-
- for (i = 0; i < n; i++) {
- rval = smiapp_read(
- sensor, smiapp_reg_limits[limit[i]].addr, &val);
- if (rval)
- return rval;
- sensor->limits[limit[i]] = val;
- dev_dbg(&client->dev, "0x%8.8x \"%s\" = %d, 0x%x\n",
- smiapp_reg_limits[limit[i]].addr,
- smiapp_reg_limits[limit[i]].what, val, val);
- }
-
- return 0;
-}
-
-static int smiapp_get_all_limits(struct smiapp_sensor *sensor)
-{
- unsigned int i;
- int rval;
-
- for (i = 0; i < SMIAPP_LIMIT_LAST; i++) {
- rval = smiapp_get_limits(sensor, &i, 1);
- if (rval < 0)
- return rval;
- }
-
- if (sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN] == 0)
- smiapp_replace_limit(sensor, SMIAPP_LIMIT_SCALER_N_MIN, 16);
-
- return 0;
-}
-
-static int smiapp_get_limits_binning(struct smiapp_sensor *sensor)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- static u32 const limits[] = {
- SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN,
- SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES_BIN,
- SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN,
- SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK_BIN,
- SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN,
- SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MIN_BIN,
- SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MAX_MARGIN_BIN,
- };
- static u32 const limits_replace[] = {
- SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES,
- SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES,
- SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK,
- SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK,
- SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK,
- SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MIN,
- SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MAX_MARGIN,
- };
- unsigned int i;
- int rval;
-
- if (sensor->limits[SMIAPP_LIMIT_BINNING_CAPABILITY] ==
- SMIAPP_BINNING_CAPABILITY_NO) {
- for (i = 0; i < ARRAY_SIZE(limits); i++)
- sensor->limits[limits[i]] =
- sensor->limits[limits_replace[i]];
-
- return 0;
- }
-
- rval = smiapp_get_limits(sensor, limits, ARRAY_SIZE(limits));
- if (rval < 0)
- return rval;
-
- /*
- * Sanity check whether the binning limits are valid. If not,
- * use the non-binning ones.
- */
- if (sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN]
- && sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN]
- && sensor->limits[SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN])
- return 0;
-
- for (i = 0; i < ARRAY_SIZE(limits); i++) {
- dev_dbg(&client->dev,
- "replace limit 0x%8.8x \"%s\" = %d, 0x%x\n",
- smiapp_reg_limits[limits[i]].addr,
- smiapp_reg_limits[limits[i]].what,
- sensor->limits[limits_replace[i]],
- sensor->limits[limits_replace[i]]);
- sensor->limits[limits[i]] =
- sensor->limits[limits_replace[i]];
- }
-
- return 0;
-}
-
-static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- unsigned int type, n;
- unsigned int i, pixel_order;
- int rval;
-
- rval = smiapp_read(
- sensor, SMIAPP_REG_U8_DATA_FORMAT_MODEL_TYPE, &type);
- if (rval)
- return rval;
-
- dev_dbg(&client->dev, "data_format_model_type %d\n", type);
-
- rval = smiapp_read(sensor, SMIAPP_REG_U8_PIXEL_ORDER,
- &pixel_order);
- if (rval)
- return rval;
-
- if (pixel_order >= ARRAY_SIZE(pixel_order_str)) {
- dev_dbg(&client->dev, "bad pixel order %d\n", pixel_order);
- return -EINVAL;
- }
-
- dev_dbg(&client->dev, "pixel order %d (%s)\n", pixel_order,
- pixel_order_str[pixel_order]);
-
- switch (type) {
- case SMIAPP_DATA_FORMAT_MODEL_TYPE_NORMAL:
- n = SMIAPP_DATA_FORMAT_MODEL_TYPE_NORMAL_N;
- break;
- case SMIAPP_DATA_FORMAT_MODEL_TYPE_EXTENDED:
- n = SMIAPP_DATA_FORMAT_MODEL_TYPE_EXTENDED_N;
- break;
- default:
- return -EINVAL;
- }
-
- sensor->default_pixel_order = pixel_order;
- sensor->mbus_frame_fmts = 0;
-
- for (i = 0; i < n; i++) {
- unsigned int fmt, j;
-
- rval = smiapp_read(
- sensor,
- SMIAPP_REG_U16_DATA_FORMAT_DESCRIPTOR(i), &fmt);
- if (rval)
- return rval;
-
- dev_dbg(&client->dev, "bpp %d, compressed %d\n",
- fmt >> 8, (u8)fmt);
-
- for (j = 0; j < ARRAY_SIZE(smiapp_csi_data_formats); j++) {
- const struct smiapp_csi_data_format *f =
- &smiapp_csi_data_formats[j];
-
- if (f->pixel_order != SMIAPP_PIXEL_ORDER_GRBG)
- continue;
-
- if (f->width != fmt >> 8 || f->compressed != (u8)fmt)
- continue;
-
- dev_dbg(&client->dev, "jolly good! %d\n", j);
-
- sensor->default_mbus_frame_fmts |= 1 << j;
- if (!sensor->csi_format) {
- sensor->csi_format = f;
- sensor->internal_csi_format = f;
- }
- }
- }
-
- if (!sensor->csi_format) {
- dev_err(&client->dev, "no supported mbus code found\n");
- return -EINVAL;
- }
-
- smiapp_update_mbus_formats(sensor);
-
- return 0;
-}
-
-static void smiapp_update_blanking(struct smiapp_sensor *sensor)
-{
- struct v4l2_ctrl *vblank = sensor->vblank;
- struct v4l2_ctrl *hblank = sensor->hblank;
-
- vblank->minimum =
- max_t(int,
- sensor->limits[SMIAPP_LIMIT_MIN_FRAME_BLANKING_LINES],
- sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN] -
- sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height);
- vblank->maximum =
- sensor->limits[SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES_BIN] -
- sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height;
-
- vblank->val = clamp_t(int, vblank->val,
- vblank->minimum, vblank->maximum);
- vblank->default_value = vblank->minimum;
- vblank->val = vblank->val;
- vblank->cur.val = vblank->val;
-
- hblank->minimum =
- max_t(int,
- sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN] -
- sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width,
- sensor->limits[SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN]);
- hblank->maximum =
- sensor->limits[SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK_BIN] -
- sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width;
-
- hblank->val = clamp_t(int, hblank->val,
- hblank->minimum, hblank->maximum);
- hblank->default_value = hblank->minimum;
- hblank->val = hblank->val;
- hblank->cur.val = hblank->val;
-
- __smiapp_update_exposure_limits(sensor);
-}
-
-static int smiapp_update_mode(struct smiapp_sensor *sensor)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- unsigned int binning_mode;
- int rval;
-
- dev_dbg(&client->dev, "frame size: %dx%d\n",
- sensor->src->crop[SMIAPP_PAD_SRC].width,
- sensor->src->crop[SMIAPP_PAD_SRC].height);
- dev_dbg(&client->dev, "csi format width: %d\n",
- sensor->csi_format->width);
-
- /* Binning has to be set up here; it affects limits */
- if (sensor->binning_horizontal == 1 &&
- sensor->binning_vertical == 1) {
- binning_mode = 0;
- } else {
- u8 binning_type =
- (sensor->binning_horizontal << 4)
- | sensor->binning_vertical;
-
- rval = smiapp_write(
- sensor, SMIAPP_REG_U8_BINNING_TYPE, binning_type);
- if (rval < 0)
- return rval;
-
- binning_mode = 1;
- }
- rval = smiapp_write(sensor, SMIAPP_REG_U8_BINNING_MODE, binning_mode);
- if (rval < 0)
- return rval;
-
- /* Get updated limits due to binning */
- rval = smiapp_get_limits_binning(sensor);
- if (rval < 0)
- return rval;
-
- rval = smiapp_pll_update(sensor);
- if (rval < 0)
- return rval;
-
- /* Output from pixel array, including blanking */
- smiapp_update_blanking(sensor);
-
- dev_dbg(&client->dev, "vblank\t\t%d\n", sensor->vblank->val);
- dev_dbg(&client->dev, "hblank\t\t%d\n", sensor->hblank->val);
-
- dev_dbg(&client->dev, "real timeperframe\t100/%d\n",
- sensor->pll.vt_pix_clk_freq_hz /
- ((sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
- + sensor->hblank->val) *
- (sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
- + sensor->vblank->val) / 100));
-
- return 0;
-}
-
-/*
- *
- * SMIA++ NVM handling
- *
- */
-static int smiapp_read_nvm(struct smiapp_sensor *sensor,
- unsigned char *nvm)
-{
- u32 i, s, p, np, v;
- int rval = 0, rval2;
-
- np = sensor->nvm_size / SMIAPP_NVM_PAGE_SIZE;
- for (p = 0; p < np; p++) {
- rval = smiapp_write(
- sensor,
- SMIAPP_REG_U8_DATA_TRANSFER_IF_1_PAGE_SELECT, p);
- if (rval)
- goto out;
-
- rval = smiapp_write(sensor,
- SMIAPP_REG_U8_DATA_TRANSFER_IF_1_CTRL,
- SMIAPP_DATA_TRANSFER_IF_1_CTRL_EN |
- SMIAPP_DATA_TRANSFER_IF_1_CTRL_RD_EN);
- if (rval)
- goto out;
-
- for (i = 0; i < 1000; i++) {
- rval = smiapp_read(
- sensor,
- SMIAPP_REG_U8_DATA_TRANSFER_IF_1_STATUS, &s);
-
- if (rval)
- goto out;
-
- if (s & SMIAPP_DATA_TRANSFER_IF_1_STATUS_RD_READY)
- break;
-
- if (--i == 0) {
- rval = -ETIMEDOUT;
- goto out;
- }
-
- }
-
- for (i = 0; i < SMIAPP_NVM_PAGE_SIZE; i++) {
- rval = smiapp_read(
- sensor,
- SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_0 + i,
- &v);
- if (rval)
- goto out;
-
- *nvm++ = v;
- }
- }
-
-out:
- rval2 = smiapp_write(sensor, SMIAPP_REG_U8_DATA_TRANSFER_IF_1_CTRL, 0);
- if (rval < 0)
- return rval;
- else
- return rval2;
-}
-
-/*
- *
- * SMIA++ CCI address control
- *
- */
-static int smiapp_change_cci_addr(struct smiapp_sensor *sensor)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- int rval;
- u32 val;
-
- client->addr = sensor->platform_data->i2c_addr_dfl;
-
- rval = smiapp_write(sensor,
- SMIAPP_REG_U8_CCI_ADDRESS_CONTROL,
- sensor->platform_data->i2c_addr_alt << 1);
- if (rval)
- return rval;
-
- client->addr = sensor->platform_data->i2c_addr_alt;
-
- /* verify addr change went ok */
- rval = smiapp_read(sensor, SMIAPP_REG_U8_CCI_ADDRESS_CONTROL, &val);
- if (rval)
- return rval;
-
- if (val != sensor->platform_data->i2c_addr_alt << 1)
- return -ENODEV;
-
- return 0;
-}
-
-/*
- *
- * SMIA++ Mode Control
- *
- */
-static int smiapp_setup_flash_strobe(struct smiapp_sensor *sensor)
-{
- struct smiapp_flash_strobe_parms *strobe_setup;
- unsigned int ext_freq = sensor->platform_data->ext_clk;
- u32 tmp;
- u32 strobe_adjustment;
- u32 strobe_width_high_rs;
- int rval;
-
- strobe_setup = sensor->platform_data->strobe_setup;
-
- /*
- * How to calculate registers related to strobe length. Please
- * do not change, or if you do at least know what you're
- * doing. :-)
- *
- * Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> 2010-10-25
- *
- * flash_strobe_length [us] / 10^6 = (tFlash_strobe_width_ctrl
- * / EXTCLK freq [Hz]) * flash_strobe_adjustment
- *
- * tFlash_strobe_width_ctrl E N, [1 - 0xffff]
- * flash_strobe_adjustment E N, [1 - 0xff]
- *
- * The formula above is written as below to keep it on one
- * line:
- *
- * l / 10^6 = w / e * a
- *
- * Let's mark w * a by x:
- *
- * x = w * a
- *
- * Thus, we get:
- *
- * x = l * e / 10^6
- *
- * The strobe width must be at least as long as requested,
- * thus rounding upwards is needed.
- *
- * x = (l * e + 10^6 - 1) / 10^6
- * -----------------------------
- *
- * Maximum possible accuracy is wanted at all times. Thus keep
- * a as small as possible.
- *
- * Calculate a, assuming maximum w, with rounding upwards:
- *
- * a = (x + (2^16 - 1) - 1) / (2^16 - 1)
- * -------------------------------------
- *
- * Thus, we also get w, with that a, with rounding upwards:
- *
- * w = (x + a - 1) / a
- * -------------------
- *
- * To get limits:
- *
- * x E [1, (2^16 - 1) * (2^8 - 1)]
- *
- * Substituting maximum x to the original formula (with rounding),
- * the maximum l is thus
- *
- * (2^16 - 1) * (2^8 - 1) * 10^6 = l * e + 10^6 - 1
- *
- * l = (10^6 * (2^16 - 1) * (2^8 - 1) - 10^6 + 1) / e
- * --------------------------------------------------
- *
- * flash_strobe_length must be clamped between 1 and
- * (10^6 * (2^16 - 1) * (2^8 - 1) - 10^6 + 1) / EXTCLK freq.
- *
- * Then,
- *
- * flash_strobe_adjustment = ((flash_strobe_length *
- * EXTCLK freq + 10^6 - 1) / 10^6 + (2^16 - 1) - 1) / (2^16 - 1)
- *
- * tFlash_strobe_width_ctrl = ((flash_strobe_length *
- * EXTCLK freq + 10^6 - 1) / 10^6 +
- * flash_strobe_adjustment - 1) / flash_strobe_adjustment
- */
- tmp = div_u64(1000000ULL * ((1 << 16) - 1) * ((1 << 8) - 1) -
- 1000000 + 1, ext_freq);
- strobe_setup->strobe_width_high_us =
- clamp_t(u32, strobe_setup->strobe_width_high_us, 1, tmp);
-
- tmp = div_u64(((u64)strobe_setup->strobe_width_high_us * (u64)ext_freq +
- 1000000 - 1), 1000000ULL);
- strobe_adjustment = (tmp + (1 << 16) - 1 - 1) / ((1 << 16) - 1);
- strobe_width_high_rs = (tmp + strobe_adjustment - 1) /
- strobe_adjustment;
-
- rval = smiapp_write(sensor, SMIAPP_REG_U8_FLASH_MODE_RS,
- strobe_setup->mode);
- if (rval < 0)
- goto out;
-
- rval = smiapp_write(sensor, SMIAPP_REG_U8_FLASH_STROBE_ADJUSTMENT,
- strobe_adjustment);
- if (rval < 0)
- goto out;
-
- rval = smiapp_write(
- sensor, SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_HIGH_RS_CTRL,
- strobe_width_high_rs);
- if (rval < 0)
- goto out;
-
- rval = smiapp_write(sensor, SMIAPP_REG_U16_TFLASH_STROBE_DELAY_RS_CTRL,
- strobe_setup->strobe_delay);
- if (rval < 0)
- goto out;
-
- rval = smiapp_write(sensor, SMIAPP_REG_U16_FLASH_STROBE_START_POINT,
- strobe_setup->stobe_start_point);
- if (rval < 0)
- goto out;
-
- rval = smiapp_write(sensor, SMIAPP_REG_U8_FLASH_TRIGGER_RS,
- strobe_setup->trigger);
-
-out:
- sensor->platform_data->strobe_setup->trigger = 0;
-
- return rval;
-}
-
-/* -----------------------------------------------------------------------------
- * Power management
- */
-
-static int smiapp_power_on(struct smiapp_sensor *sensor)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- unsigned int sleep;
- int rval;
-
- rval = regulator_enable(sensor->vana);
- if (rval) {
- dev_err(&client->dev, "failed to enable vana regulator\n");
- return rval;
- }
- usleep_range(1000, 1000);
-
- if (sensor->platform_data->set_xclk)
- rval = sensor->platform_data->set_xclk(
- &sensor->src->sd, sensor->platform_data->ext_clk);
- else
- rval = clk_enable(sensor->ext_clk);
- if (rval < 0) {
- dev_dbg(&client->dev, "failed to set xclk\n");
- goto out_xclk_fail;
- }
- usleep_range(1000, 1000);
-
- if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
- gpio_set_value(sensor->platform_data->xshutdown, 1);
-
- sleep = SMIAPP_RESET_DELAY(sensor->platform_data->ext_clk);
- usleep_range(sleep, sleep);
-
- /*
- * Failures to respond to the address change command have been noticed.
- * Those failures seem to be caused by the sensor requiring a longer
- * boot time than advertised. An additional 10ms delay seems to work
- * around the issue, but the SMIA++ I2C write retry hack makes the delay
- * unnecessary. The failures need to be investigated to find a proper
- * fix, and a delay will likely need to be added here if the I2C write
- * retry hack is reverted before the root cause of the boot time issue
- * is found.
- */
-
- if (sensor->platform_data->i2c_addr_alt) {
- rval = smiapp_change_cci_addr(sensor);
- if (rval) {
- dev_err(&client->dev, "cci address change error\n");
- goto out_cci_addr_fail;
- }
- }
-
- rval = smiapp_write(sensor, SMIAPP_REG_U8_SOFTWARE_RESET,
- SMIAPP_SOFTWARE_RESET);
- if (rval < 0) {
- dev_err(&client->dev, "software reset failed\n");
- goto out_cci_addr_fail;
- }
-
- if (sensor->platform_data->i2c_addr_alt) {
- rval = smiapp_change_cci_addr(sensor);
- if (rval) {
- dev_err(&client->dev, "cci address change error\n");
- goto out_cci_addr_fail;
- }
- }
-
- rval = smiapp_write(sensor, SMIAPP_REG_U16_COMPRESSION_MODE,
- SMIAPP_COMPRESSION_MODE_SIMPLE_PREDICTOR);
- if (rval) {
- dev_err(&client->dev, "compression mode set failed\n");
- goto out_cci_addr_fail;
- }
-
- rval = smiapp_write(
- sensor, SMIAPP_REG_U16_EXTCLK_FREQUENCY_MHZ,
- sensor->platform_data->ext_clk / (1000000 / (1 << 8)));
- if (rval) {
- dev_err(&client->dev, "extclk frequency set failed\n");
- goto out_cci_addr_fail;
- }
-
- rval = smiapp_write(sensor, SMIAPP_REG_U8_CSI_LANE_MODE,
- sensor->platform_data->lanes - 1);
- if (rval) {
- dev_err(&client->dev, "csi lane mode set failed\n");
- goto out_cci_addr_fail;
- }
-
- rval = smiapp_write(sensor, SMIAPP_REG_U8_FAST_STANDBY_CTRL,
- SMIAPP_FAST_STANDBY_CTRL_IMMEDIATE);
- if (rval) {
- dev_err(&client->dev, "fast standby set failed\n");
- goto out_cci_addr_fail;
- }
-
- rval = smiapp_write(sensor, SMIAPP_REG_U8_CSI_SIGNALLING_MODE,
- sensor->platform_data->csi_signalling_mode);
- if (rval) {
- dev_err(&client->dev, "csi signalling mode set failed\n");
- goto out_cci_addr_fail;
- }
-
- /* DPHY control done by sensor based on requested link rate */
- rval = smiapp_write(sensor, SMIAPP_REG_U8_DPHY_CTRL,
- SMIAPP_DPHY_CTRL_UI);
- if (rval < 0)
- return rval;
-
- rval = smiapp_call_quirk(sensor, post_poweron);
- if (rval) {
- dev_err(&client->dev, "post_poweron quirks failed\n");
- goto out_cci_addr_fail;
- }
-
- /* Are we still initialising...? If yes, return here. */
- if (!sensor->pixel_array)
- return 0;
-
- rval = v4l2_ctrl_handler_setup(
- &sensor->pixel_array->ctrl_handler);
- if (rval)
- goto out_cci_addr_fail;
-
- rval = v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
- if (rval)
- goto out_cci_addr_fail;
-
- mutex_lock(&sensor->mutex);
- rval = smiapp_update_mode(sensor);
- mutex_unlock(&sensor->mutex);
- if (rval < 0)
- goto out_cci_addr_fail;
-
- return 0;
-
-out_cci_addr_fail:
- if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
- gpio_set_value(sensor->platform_data->xshutdown, 0);
- if (sensor->platform_data->set_xclk)
- sensor->platform_data->set_xclk(&sensor->src->sd, 0);
- else
- clk_disable(sensor->ext_clk);
-
-out_xclk_fail:
- regulator_disable(sensor->vana);
- return rval;
-}
-
-static void smiapp_power_off(struct smiapp_sensor *sensor)
-{
- /*
- * Currently power/clock to lens are enable/disabled separately
- * but they are essentially the same signals. So if the sensor is
- * powered off while the lens is powered on the sensor does not
- * really see a power off and next time the cci address change
- * will fail. So do a soft reset explicitly here.
- */
- if (sensor->platform_data->i2c_addr_alt)
- smiapp_write(sensor,
- SMIAPP_REG_U8_SOFTWARE_RESET,
- SMIAPP_SOFTWARE_RESET);
-
- if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
- gpio_set_value(sensor->platform_data->xshutdown, 0);
- if (sensor->platform_data->set_xclk)
- sensor->platform_data->set_xclk(&sensor->src->sd, 0);
- else
- clk_disable(sensor->ext_clk);
- usleep_range(5000, 5000);
- regulator_disable(sensor->vana);
- sensor->streaming = 0;
-}
-
-static int smiapp_set_power(struct v4l2_subdev *subdev, int on)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- int ret = 0;
-
- mutex_lock(&sensor->power_mutex);
-
- /*
- * If the power count is modified from 0 to != 0 or from != 0
- * to 0, update the power state.
- */
- if (!sensor->power_count == !on)
- goto out;
-
- if (on) {
- /* Power on and perform initialisation. */
- ret = smiapp_power_on(sensor);
- if (ret < 0)
- goto out;
- } else {
- smiapp_power_off(sensor);
- }
-
- /* Update the power count. */
- sensor->power_count += on ? 1 : -1;
- WARN_ON(sensor->power_count < 0);
-
-out:
- mutex_unlock(&sensor->power_mutex);
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * Video stream management
- */
-
-static int smiapp_start_streaming(struct smiapp_sensor *sensor)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- int rval;
-
- mutex_lock(&sensor->mutex);
-
- rval = smiapp_write(sensor, SMIAPP_REG_U16_CSI_DATA_FORMAT,
- (sensor->csi_format->width << 8) |
- sensor->csi_format->compressed);
- if (rval)
- goto out;
-
- rval = smiapp_pll_configure(sensor);
- if (rval)
- goto out;
-
- /* Analog crop start coordinates */
- rval = smiapp_write(sensor, SMIAPP_REG_U16_X_ADDR_START,
- sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].left);
- if (rval < 0)
- goto out;
-
- rval = smiapp_write(sensor, SMIAPP_REG_U16_Y_ADDR_START,
- sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].top);
- if (rval < 0)
- goto out;
-
- /* Analog crop end coordinates */
- rval = smiapp_write(
- sensor, SMIAPP_REG_U16_X_ADDR_END,
- sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].left
- + sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width - 1);
- if (rval < 0)
- goto out;
-
- rval = smiapp_write(
- sensor, SMIAPP_REG_U16_Y_ADDR_END,
- sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].top
- + sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height - 1);
- if (rval < 0)
- goto out;
-
- /*
- * Output from pixel array, including blanking, is set using
- * controls below. No need to set here.
- */
-
- /* Digital crop */
- if (sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY]
- == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) {
- rval = smiapp_write(
- sensor, SMIAPP_REG_U16_DIGITAL_CROP_X_OFFSET,
- sensor->scaler->crop[SMIAPP_PAD_SINK].left);
- if (rval < 0)
- goto out;
-
- rval = smiapp_write(
- sensor, SMIAPP_REG_U16_DIGITAL_CROP_Y_OFFSET,
- sensor->scaler->crop[SMIAPP_PAD_SINK].top);
- if (rval < 0)
- goto out;
-
- rval = smiapp_write(
- sensor, SMIAPP_REG_U16_DIGITAL_CROP_IMAGE_WIDTH,
- sensor->scaler->crop[SMIAPP_PAD_SINK].width);
- if (rval < 0)
- goto out;
-
- rval = smiapp_write(
- sensor, SMIAPP_REG_U16_DIGITAL_CROP_IMAGE_HEIGHT,
- sensor->scaler->crop[SMIAPP_PAD_SINK].height);
- if (rval < 0)
- goto out;
- }
-
- /* Scaling */
- if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
- != SMIAPP_SCALING_CAPABILITY_NONE) {
- rval = smiapp_write(sensor, SMIAPP_REG_U16_SCALING_MODE,
- sensor->scaling_mode);
- if (rval < 0)
- goto out;
-
- rval = smiapp_write(sensor, SMIAPP_REG_U16_SCALE_M,
- sensor->scale_m);
- if (rval < 0)
- goto out;
- }
-
- /* Output size from sensor */
- rval = smiapp_write(sensor, SMIAPP_REG_U16_X_OUTPUT_SIZE,
- sensor->src->crop[SMIAPP_PAD_SRC].width);
- if (rval < 0)
- goto out;
- rval = smiapp_write(sensor, SMIAPP_REG_U16_Y_OUTPUT_SIZE,
- sensor->src->crop[SMIAPP_PAD_SRC].height);
- if (rval < 0)
- goto out;
-
- if ((sensor->flash_capability &
- (SMIAPP_FLASH_MODE_CAPABILITY_SINGLE_STROBE |
- SMIAPP_FLASH_MODE_CAPABILITY_MULTIPLE_STROBE)) &&
- sensor->platform_data->strobe_setup != NULL &&
- sensor->platform_data->strobe_setup->trigger != 0) {
- rval = smiapp_setup_flash_strobe(sensor);
- if (rval)
- goto out;
- }
-
- rval = smiapp_call_quirk(sensor, pre_streamon);
- if (rval) {
- dev_err(&client->dev, "pre_streamon quirks failed\n");
- goto out;
- }
-
- rval = smiapp_write(sensor, SMIAPP_REG_U8_MODE_SELECT,
- SMIAPP_MODE_SELECT_STREAMING);
-
-out:
- mutex_unlock(&sensor->mutex);
-
- return rval;
-}
-
-static int smiapp_stop_streaming(struct smiapp_sensor *sensor)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- int rval;
-
- mutex_lock(&sensor->mutex);
- rval = smiapp_write(sensor, SMIAPP_REG_U8_MODE_SELECT,
- SMIAPP_MODE_SELECT_SOFTWARE_STANDBY);
- if (rval)
- goto out;
-
- rval = smiapp_call_quirk(sensor, post_streamoff);
- if (rval)
- dev_err(&client->dev, "post_streamoff quirks failed\n");
-
-out:
- mutex_unlock(&sensor->mutex);
- return rval;
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev video operations
- */
-
-static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- int rval;
-
- if (sensor->streaming == enable)
- return 0;
-
- if (enable) {
- sensor->streaming = 1;
- rval = smiapp_start_streaming(sensor);
- if (rval < 0)
- sensor->streaming = 0;
- } else {
- rval = smiapp_stop_streaming(sensor);
- sensor->streaming = 0;
- }
-
- return rval;
-}
-
-static int smiapp_enum_mbus_code(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- struct i2c_client *client = v4l2_get_subdevdata(subdev);
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- unsigned int i;
- int idx = -1;
- int rval = -EINVAL;
-
- mutex_lock(&sensor->mutex);
-
- dev_err(&client->dev, "subdev %s, pad %d, index %d\n",
- subdev->name, code->pad, code->index);
-
- if (subdev != &sensor->src->sd || code->pad != SMIAPP_PAD_SRC) {
- if (code->index)
- goto out;
-
- code->code = sensor->internal_csi_format->code;
- rval = 0;
- goto out;
- }
-
- for (i = 0; i < ARRAY_SIZE(smiapp_csi_data_formats); i++) {
- if (sensor->mbus_frame_fmts & (1 << i))
- idx++;
-
- if (idx == code->index) {
- code->code = smiapp_csi_data_formats[i].code;
- dev_err(&client->dev, "found index %d, i %d, code %x\n",
- code->index, i, code->code);
- rval = 0;
- break;
- }
- }
-
-out:
- mutex_unlock(&sensor->mutex);
-
- return rval;
-}
-
-static u32 __smiapp_get_mbus_code(struct v4l2_subdev *subdev,
- unsigned int pad)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
-
- if (subdev == &sensor->src->sd && pad == SMIAPP_PAD_SRC)
- return sensor->csi_format->code;
- else
- return sensor->internal_csi_format->code;
-}
-
-static int __smiapp_get_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- fmt->format = *v4l2_subdev_get_try_format(fh, fmt->pad);
- } else {
- struct v4l2_rect *r;
-
- if (fmt->pad == ssd->source_pad)
- r = &ssd->crop[ssd->source_pad];
- else
- r = &ssd->sink_fmt;
-
- fmt->format.code = __smiapp_get_mbus_code(subdev, fmt->pad);
- fmt->format.width = r->width;
- fmt->format.height = r->height;
- }
-
- return 0;
-}
-
-static int smiapp_get_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- int rval;
-
- mutex_lock(&sensor->mutex);
- rval = __smiapp_get_format(subdev, fh, fmt);
- mutex_unlock(&sensor->mutex);
-
- return rval;
-}
-
-static void smiapp_get_crop_compose(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_rect **crops,
- struct v4l2_rect **comps, int which)
-{
- struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
- unsigned int i;
-
- if (which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- if (crops)
- for (i = 0; i < subdev->entity.num_pads; i++)
- crops[i] = &ssd->crop[i];
- if (comps)
- *comps = &ssd->compose;
- } else {
- if (crops) {
- for (i = 0; i < subdev->entity.num_pads; i++) {
- crops[i] = v4l2_subdev_get_try_crop(fh, i);
- BUG_ON(!crops[i]);
- }
- }
- if (comps) {
- *comps = v4l2_subdev_get_try_compose(fh,
- SMIAPP_PAD_SINK);
- BUG_ON(!*comps);
- }
- }
-}
-
-/* Changes require propagation only on sink pad. */
-static void smiapp_propagate(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh, int which,
- int target)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
- struct v4l2_rect *comp, *crops[SMIAPP_PADS];
-
- smiapp_get_crop_compose(subdev, fh, crops, &comp, which);
-
- switch (target) {
- case V4L2_SEL_TGT_CROP:
- comp->width = crops[SMIAPP_PAD_SINK]->width;
- comp->height = crops[SMIAPP_PAD_SINK]->height;
- if (which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- if (ssd == sensor->scaler) {
- sensor->scale_m =
- sensor->limits[
- SMIAPP_LIMIT_SCALER_N_MIN];
- sensor->scaling_mode =
- SMIAPP_SCALING_MODE_NONE;
- } else if (ssd == sensor->binner) {
- sensor->binning_horizontal = 1;
- sensor->binning_vertical = 1;
- }
- }
- /* Fall through */
- case V4L2_SEL_TGT_COMPOSE:
- *crops[SMIAPP_PAD_SRC] = *comp;
- break;
- default:
- BUG();
- }
-}
-
-static const struct smiapp_csi_data_format
-*smiapp_validate_csi_data_format(struct smiapp_sensor *sensor, u32 code)
-{
- const struct smiapp_csi_data_format *csi_format = sensor->csi_format;
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(smiapp_csi_data_formats); i++) {
- if (sensor->mbus_frame_fmts & (1 << i)
- && smiapp_csi_data_formats[i].code == code)
- return &smiapp_csi_data_formats[i];
- }
-
- return csi_format;
-}
-
-static int smiapp_set_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_format *fmt)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
- struct v4l2_rect *crops[SMIAPP_PADS];
-
- mutex_lock(&sensor->mutex);
-
- /*
- * Media bus code is changeable on src subdev's source pad. On
- * other source pads we just get format here.
- */
- if (fmt->pad == ssd->source_pad) {
- u32 code = fmt->format.code;
- int rval = __smiapp_get_format(subdev, fh, fmt);
-
- if (!rval && subdev == &sensor->src->sd) {
- const struct smiapp_csi_data_format *csi_format =
- smiapp_validate_csi_data_format(sensor, code);
- if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
- sensor->csi_format = csi_format;
- fmt->format.code = csi_format->code;
- }
-
- mutex_unlock(&sensor->mutex);
- return rval;
- }
-
- /* Sink pad. Width and height are changeable here. */
- fmt->format.code = __smiapp_get_mbus_code(subdev, fmt->pad);
- fmt->format.width &= ~1;
- fmt->format.height &= ~1;
-
- fmt->format.width =
- clamp(fmt->format.width,
- sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],
- sensor->limits[SMIAPP_LIMIT_MAX_X_OUTPUT_SIZE]);
- fmt->format.height =
- clamp(fmt->format.height,
- sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE],
- sensor->limits[SMIAPP_LIMIT_MAX_Y_OUTPUT_SIZE]);
-
- smiapp_get_crop_compose(subdev, fh, crops, NULL, fmt->which);
-
- crops[ssd->sink_pad]->left = 0;
- crops[ssd->sink_pad]->top = 0;
- crops[ssd->sink_pad]->width = fmt->format.width;
- crops[ssd->sink_pad]->height = fmt->format.height;
- if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
- ssd->sink_fmt = *crops[ssd->sink_pad];
- smiapp_propagate(subdev, fh, fmt->which,
- V4L2_SEL_TGT_CROP);
-
- mutex_unlock(&sensor->mutex);
-
- return 0;
-}
-
-/*
- * Calculate goodness of scaled image size compared to expected image
- * size and flags provided.
- */
-#define SCALING_GOODNESS 100000
-#define SCALING_GOODNESS_EXTREME 100000000
-static int scaling_goodness(struct v4l2_subdev *subdev, int w, int ask_w,
- int h, int ask_h, u32 flags)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- struct i2c_client *client = v4l2_get_subdevdata(subdev);
- int val = 0;
-
- w &= ~1;
- ask_w &= ~1;
- h &= ~1;
- ask_h &= ~1;
-
- if (flags & V4L2_SEL_FLAG_GE) {
- if (w < ask_w)
- val -= SCALING_GOODNESS;
- if (h < ask_h)
- val -= SCALING_GOODNESS;
- }
-
- if (flags & V4L2_SEL_FLAG_LE) {
- if (w > ask_w)
- val -= SCALING_GOODNESS;
- if (h > ask_h)
- val -= SCALING_GOODNESS;
- }
-
- val -= abs(w - ask_w);
- val -= abs(h - ask_h);
-
- if (w < sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE])
- val -= SCALING_GOODNESS_EXTREME;
-
- dev_dbg(&client->dev, "w %d ask_w %d h %d ask_h %d goodness %d\n",
- w, ask_h, h, ask_h, val);
-
- return val;
-}
-
-static void smiapp_set_compose_binner(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel,
- struct v4l2_rect **crops,
- struct v4l2_rect *comp)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- unsigned int i;
- unsigned int binh = 1, binv = 1;
- unsigned int best = scaling_goodness(
- subdev,
- crops[SMIAPP_PAD_SINK]->width, sel->r.width,
- crops[SMIAPP_PAD_SINK]->height, sel->r.height, sel->flags);
-
- for (i = 0; i < sensor->nbinning_subtypes; i++) {
- int this = scaling_goodness(
- subdev,
- crops[SMIAPP_PAD_SINK]->width
- / sensor->binning_subtypes[i].horizontal,
- sel->r.width,
- crops[SMIAPP_PAD_SINK]->height
- / sensor->binning_subtypes[i].vertical,
- sel->r.height, sel->flags);
-
- if (this > best) {
- binh = sensor->binning_subtypes[i].horizontal;
- binv = sensor->binning_subtypes[i].vertical;
- best = this;
- }
- }
- if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- sensor->binning_vertical = binv;
- sensor->binning_horizontal = binh;
- }
-
- sel->r.width = (crops[SMIAPP_PAD_SINK]->width / binh) & ~1;
- sel->r.height = (crops[SMIAPP_PAD_SINK]->height / binv) & ~1;
-}
-
-/*
- * Calculate best scaling ratio and mode for given output resolution.
- *
- * Try all of these: horizontal ratio, vertical ratio and smallest
- * size possible (horizontally).
- *
- * Also try whether horizontal scaler or full scaler gives a better
- * result.
- */
-static void smiapp_set_compose_scaler(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel,
- struct v4l2_rect **crops,
- struct v4l2_rect *comp)
-{
- struct i2c_client *client = v4l2_get_subdevdata(subdev);
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- u32 min, max, a, b, max_m;
- u32 scale_m = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
- int mode = SMIAPP_SCALING_MODE_HORIZONTAL;
- u32 try[4];
- u32 ntry = 0;
- unsigned int i;
- int best = INT_MIN;
-
- sel->r.width = min_t(unsigned int, sel->r.width,
- crops[SMIAPP_PAD_SINK]->width);
- sel->r.height = min_t(unsigned int, sel->r.height,
- crops[SMIAPP_PAD_SINK]->height);
-
- a = crops[SMIAPP_PAD_SINK]->width
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN] / sel->r.width;
- b = crops[SMIAPP_PAD_SINK]->height
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN] / sel->r.height;
- max_m = crops[SMIAPP_PAD_SINK]->width
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]
- / sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE];
-
- a = min(sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX],
- max(a, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN]));
- b = min(sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX],
- max(b, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN]));
- max_m = min(sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX],
- max(max_m, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN]));
-
- dev_dbg(&client->dev, "scaling: a %d b %d max_m %d\n", a, b, max_m);
-
- min = min(max_m, min(a, b));
- max = min(max_m, max(a, b));
-
- try[ntry] = min;
- ntry++;
- if (min != max) {
- try[ntry] = max;
- ntry++;
- }
- if (max != max_m) {
- try[ntry] = min + 1;
- ntry++;
- if (min != max) {
- try[ntry] = max + 1;
- ntry++;
- }
- }
-
- for (i = 0; i < ntry; i++) {
- int this = scaling_goodness(
- subdev,
- crops[SMIAPP_PAD_SINK]->width
- / try[i]
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN],
- sel->r.width,
- crops[SMIAPP_PAD_SINK]->height,
- sel->r.height,
- sel->flags);
-
- dev_dbg(&client->dev, "trying factor %d (%d)\n", try[i], i);
-
- if (this > best) {
- scale_m = try[i];
- mode = SMIAPP_SCALING_MODE_HORIZONTAL;
- best = this;
- }
-
- if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
- == SMIAPP_SCALING_CAPABILITY_HORIZONTAL)
- continue;
-
- this = scaling_goodness(
- subdev, crops[SMIAPP_PAD_SINK]->width
- / try[i]
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN],
- sel->r.width,
- crops[SMIAPP_PAD_SINK]->height
- / try[i]
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN],
- sel->r.height,
- sel->flags);
-
- if (this > best) {
- scale_m = try[i];
- mode = SMIAPP_SCALING_MODE_BOTH;
- best = this;
- }
- }
-
- sel->r.width =
- (crops[SMIAPP_PAD_SINK]->width
- / scale_m
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]) & ~1;
- if (mode == SMIAPP_SCALING_MODE_BOTH)
- sel->r.height =
- (crops[SMIAPP_PAD_SINK]->height
- / scale_m
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN])
- & ~1;
- else
- sel->r.height = crops[SMIAPP_PAD_SINK]->height;
-
- if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- sensor->scale_m = scale_m;
- sensor->scaling_mode = mode;
- }
-}
-/* We're only called on source pads. This function sets scaling. */
-static int smiapp_set_compose(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
- struct v4l2_rect *comp, *crops[SMIAPP_PADS];
-
- smiapp_get_crop_compose(subdev, fh, crops, &comp, sel->which);
-
- sel->r.top = 0;
- sel->r.left = 0;
-
- if (ssd == sensor->binner)
- smiapp_set_compose_binner(subdev, fh, sel, crops, comp);
- else
- smiapp_set_compose_scaler(subdev, fh, sel, crops, comp);
-
- *comp = sel->r;
- smiapp_propagate(subdev, fh, sel->which,
- V4L2_SEL_TGT_COMPOSE);
-
- if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE)
- return smiapp_update_mode(sensor);
-
- return 0;
-}
-
-static int __smiapp_sel_supported(struct v4l2_subdev *subdev,
- struct v4l2_subdev_selection *sel)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
-
- /* We only implement crop in three places. */
- switch (sel->target) {
- case V4L2_SEL_TGT_CROP:
- case V4L2_SEL_TGT_CROP_BOUNDS:
- if (ssd == sensor->pixel_array
- && sel->pad == SMIAPP_PA_PAD_SRC)
- return 0;
- if (ssd == sensor->src
- && sel->pad == SMIAPP_PAD_SRC)
- return 0;
- if (ssd == sensor->scaler
- && sel->pad == SMIAPP_PAD_SINK
- && sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY]
- == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP)
- return 0;
- return -EINVAL;
- case V4L2_SEL_TGT_COMPOSE:
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- if (sel->pad == ssd->source_pad)
- return -EINVAL;
- if (ssd == sensor->binner)
- return 0;
- if (ssd == sensor->scaler
- && sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
- != SMIAPP_SCALING_CAPABILITY_NONE)
- return 0;
- /* Fall through */
- default:
- return -EINVAL;
- }
-}
-
-static int smiapp_set_crop(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
- struct v4l2_rect *src_size, *crops[SMIAPP_PADS];
- struct v4l2_rect _r;
-
- smiapp_get_crop_compose(subdev, fh, crops, NULL, sel->which);
-
- if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- if (sel->pad == ssd->sink_pad)
- src_size = &ssd->sink_fmt;
- else
- src_size = &ssd->compose;
- } else {
- if (sel->pad == ssd->sink_pad) {
- _r.left = 0;
- _r.top = 0;
- _r.width = v4l2_subdev_get_try_format(fh, sel->pad)
- ->width;
- _r.height = v4l2_subdev_get_try_format(fh, sel->pad)
- ->height;
- src_size = &_r;
- } else {
- src_size =
- v4l2_subdev_get_try_compose(
- fh, ssd->sink_pad);
- }
- }
-
- if (ssd == sensor->src && sel->pad == SMIAPP_PAD_SRC) {
- sel->r.left = 0;
- sel->r.top = 0;
- }
-
- sel->r.width = min(sel->r.width, src_size->width);
- sel->r.height = min(sel->r.height, src_size->height);
-
- sel->r.left = min(sel->r.left, src_size->width - sel->r.width);
- sel->r.top = min(sel->r.top, src_size->height - sel->r.height);
-
- *crops[sel->pad] = sel->r;
-
- if (ssd != sensor->pixel_array && sel->pad == SMIAPP_PAD_SINK)
- smiapp_propagate(subdev, fh, sel->which,
- V4L2_SEL_TGT_CROP);
-
- return 0;
-}
-
-static int __smiapp_get_selection(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
- struct v4l2_rect *comp, *crops[SMIAPP_PADS];
- struct v4l2_rect sink_fmt;
- int ret;
-
- ret = __smiapp_sel_supported(subdev, sel);
- if (ret)
- return ret;
-
- smiapp_get_crop_compose(subdev, fh, crops, &comp, sel->which);
-
- if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- sink_fmt = ssd->sink_fmt;
- } else {
- struct v4l2_mbus_framefmt *fmt =
- v4l2_subdev_get_try_format(fh, ssd->sink_pad);
-
- sink_fmt.left = 0;
- sink_fmt.top = 0;
- sink_fmt.width = fmt->width;
- sink_fmt.height = fmt->height;
- }
-
- switch (sel->target) {
- case V4L2_SEL_TGT_CROP_BOUNDS:
- if (ssd == sensor->pixel_array) {
- sel->r.width =
- sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
- sel->r.height =
- sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1;
- } else if (sel->pad == ssd->sink_pad) {
- sel->r = sink_fmt;
- } else {
- sel->r = *comp;
- }
- break;
- case V4L2_SEL_TGT_CROP:
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- sel->r = *crops[sel->pad];
- break;
- case V4L2_SEL_TGT_COMPOSE:
- sel->r = *comp;
- break;
- }
-
- return 0;
-}
-
-static int smiapp_get_selection(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- int rval;
-
- mutex_lock(&sensor->mutex);
- rval = __smiapp_get_selection(subdev, fh, sel);
- mutex_unlock(&sensor->mutex);
-
- return rval;
-}
-static int smiapp_set_selection(struct v4l2_subdev *subdev,
- struct v4l2_subdev_fh *fh,
- struct v4l2_subdev_selection *sel)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- int ret;
-
- ret = __smiapp_sel_supported(subdev, sel);
- if (ret)
- return ret;
-
- mutex_lock(&sensor->mutex);
-
- sel->r.left = max(0, sel->r.left & ~1);
- sel->r.top = max(0, sel->r.top & ~1);
- sel->r.width = max(0, SMIAPP_ALIGN_DIM(sel->r.width, sel->flags));
- sel->r.height = max(0, SMIAPP_ALIGN_DIM(sel->r.height, sel->flags));
-
- sel->r.width = max_t(unsigned int,
- sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],
- sel->r.width);
- sel->r.height = max_t(unsigned int,
- sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE],
- sel->r.height);
-
- switch (sel->target) {
- case V4L2_SEL_TGT_CROP:
- ret = smiapp_set_crop(subdev, fh, sel);
- break;
- case V4L2_SEL_TGT_COMPOSE:
- ret = smiapp_set_compose(subdev, fh, sel);
- break;
- default:
- BUG();
- }
-
- mutex_unlock(&sensor->mutex);
- return ret;
-}
-
-static int smiapp_get_skip_frames(struct v4l2_subdev *subdev, u32 *frames)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
-
- *frames = sensor->frame_skip;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * sysfs attributes
- */
-
-static ssize_t
-smiapp_sysfs_nvm_read(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct v4l2_subdev *subdev = i2c_get_clientdata(to_i2c_client(dev));
- struct i2c_client *client = v4l2_get_subdevdata(subdev);
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- unsigned int nbytes;
-
- if (!sensor->dev_init_done)
- return -EBUSY;
-
- if (!sensor->nvm_size) {
- /* NVM not read yet - read it now */
- sensor->nvm_size = sensor->platform_data->nvm_size;
- if (smiapp_set_power(subdev, 1) < 0)
- return -ENODEV;
- if (smiapp_read_nvm(sensor, sensor->nvm)) {
- dev_err(&client->dev, "nvm read failed\n");
- return -ENODEV;
- }
- smiapp_set_power(subdev, 0);
- }
- /*
- * NVM is still way below a PAGE_SIZE, so we can safely
- * assume this for now.
- */
- nbytes = min_t(unsigned int, sensor->nvm_size, PAGE_SIZE);
- memcpy(buf, sensor->nvm, nbytes);
-
- return nbytes;
-}
-static DEVICE_ATTR(nvm, S_IRUGO, smiapp_sysfs_nvm_read, NULL);
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev core operations
- */
-
-static int smiapp_identify_module(struct v4l2_subdev *subdev)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- struct i2c_client *client = v4l2_get_subdevdata(subdev);
- struct smiapp_module_info *minfo = &sensor->minfo;
- unsigned int i;
- int rval = 0;
-
- minfo->name = SMIAPP_NAME;
-
- /* Module info */
- rval = smiapp_read_8only(sensor, SMIAPP_REG_U8_MANUFACTURER_ID,
- &minfo->manufacturer_id);
- if (!rval)
- rval = smiapp_read_8only(sensor, SMIAPP_REG_U16_MODEL_ID,
- &minfo->model_id);
- if (!rval)
- rval = smiapp_read_8only(sensor,
- SMIAPP_REG_U8_REVISION_NUMBER_MAJOR,
- &minfo->revision_number_major);
- if (!rval)
- rval = smiapp_read_8only(sensor,
- SMIAPP_REG_U8_REVISION_NUMBER_MINOR,
- &minfo->revision_number_minor);
- if (!rval)
- rval = smiapp_read_8only(sensor,
- SMIAPP_REG_U8_MODULE_DATE_YEAR,
- &minfo->module_year);
- if (!rval)
- rval = smiapp_read_8only(sensor,
- SMIAPP_REG_U8_MODULE_DATE_MONTH,
- &minfo->module_month);
- if (!rval)
- rval = smiapp_read_8only(sensor, SMIAPP_REG_U8_MODULE_DATE_DAY,
- &minfo->module_day);
-
- /* Sensor info */
- if (!rval)
- rval = smiapp_read_8only(sensor,
- SMIAPP_REG_U8_SENSOR_MANUFACTURER_ID,
- &minfo->sensor_manufacturer_id);
- if (!rval)
- rval = smiapp_read_8only(sensor,
- SMIAPP_REG_U16_SENSOR_MODEL_ID,
- &minfo->sensor_model_id);
- if (!rval)
- rval = smiapp_read_8only(sensor,
- SMIAPP_REG_U8_SENSOR_REVISION_NUMBER,
- &minfo->sensor_revision_number);
- if (!rval)
- rval = smiapp_read_8only(sensor,
- SMIAPP_REG_U8_SENSOR_FIRMWARE_VERSION,
- &minfo->sensor_firmware_version);
-
- /* SMIA */
- if (!rval)
- rval = smiapp_read_8only(sensor, SMIAPP_REG_U8_SMIA_VERSION,
- &minfo->smia_version);
- if (!rval)
- rval = smiapp_read_8only(sensor, SMIAPP_REG_U8_SMIAPP_VERSION,
- &minfo->smiapp_version);
-
- if (rval) {
- dev_err(&client->dev, "sensor detection failed\n");
- return -ENODEV;
- }
-
- dev_dbg(&client->dev, "module 0x%2.2x-0x%4.4x\n",
- minfo->manufacturer_id, minfo->model_id);
-
- dev_dbg(&client->dev,
- "module revision 0x%2.2x-0x%2.2x date %2.2d-%2.2d-%2.2d\n",
- minfo->revision_number_major, minfo->revision_number_minor,
- minfo->module_year, minfo->module_month, minfo->module_day);
-
- dev_dbg(&client->dev, "sensor 0x%2.2x-0x%4.4x\n",
- minfo->sensor_manufacturer_id, minfo->sensor_model_id);
-
- dev_dbg(&client->dev,
- "sensor revision 0x%2.2x firmware version 0x%2.2x\n",
- minfo->sensor_revision_number, minfo->sensor_firmware_version);
-
- dev_dbg(&client->dev, "smia version %2.2d smiapp version %2.2d\n",
- minfo->smia_version, minfo->smiapp_version);
-
- /*
- * Some modules have bad data in the lvalues below. Hope the
- * rvalues have better stuff. The lvalues are module
- * parameters whereas the rvalues are sensor parameters.
- */
- if (!minfo->manufacturer_id && !minfo->model_id) {
- minfo->manufacturer_id = minfo->sensor_manufacturer_id;
- minfo->model_id = minfo->sensor_model_id;
- minfo->revision_number_major = minfo->sensor_revision_number;
- }
-
- for (i = 0; i < ARRAY_SIZE(smiapp_module_idents); i++) {
- if (smiapp_module_idents[i].manufacturer_id
- != minfo->manufacturer_id)
- continue;
- if (smiapp_module_idents[i].model_id != minfo->model_id)
- continue;
- if (smiapp_module_idents[i].flags
- & SMIAPP_MODULE_IDENT_FLAG_REV_LE) {
- if (smiapp_module_idents[i].revision_number_major
- < minfo->revision_number_major)
- continue;
- } else {
- if (smiapp_module_idents[i].revision_number_major
- != minfo->revision_number_major)
- continue;
- }
-
- minfo->name = smiapp_module_idents[i].name;
- minfo->quirk = smiapp_module_idents[i].quirk;
- break;
- }
-
- if (i >= ARRAY_SIZE(smiapp_module_idents))
- dev_warn(&client->dev,
- "no quirks for this module; let's hope it's fully compliant\n");
-
- dev_dbg(&client->dev, "the sensor is called %s, ident %2.2x%4.4x%2.2x\n",
- minfo->name, minfo->manufacturer_id, minfo->model_id,
- minfo->revision_number_major);
-
- strlcpy(subdev->name, sensor->minfo.name, sizeof(subdev->name));
-
- return 0;
-}
-
-static const struct v4l2_subdev_ops smiapp_ops;
-static const struct v4l2_subdev_internal_ops smiapp_internal_ops;
-static const struct media_entity_operations smiapp_entity_ops;
-
-static int smiapp_registered(struct v4l2_subdev *subdev)
-{
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- struct i2c_client *client = v4l2_get_subdevdata(subdev);
- struct smiapp_subdev *last = NULL;
- u32 tmp;
- unsigned int i;
- int rval;
-
- sensor->vana = regulator_get(&client->dev, "VANA");
- if (IS_ERR(sensor->vana)) {
- dev_err(&client->dev, "could not get regulator for vana\n");
- return -ENODEV;
- }
-
- if (!sensor->platform_data->set_xclk) {
- sensor->ext_clk = clk_get(&client->dev,
- sensor->platform_data->ext_clk_name);
- if (IS_ERR(sensor->ext_clk)) {
- dev_err(&client->dev, "could not get clock %s\n",
- sensor->platform_data->ext_clk_name);
- rval = -ENODEV;
- goto out_clk_get;
- }
-
- rval = clk_set_rate(sensor->ext_clk,
- sensor->platform_data->ext_clk);
- if (rval < 0) {
- dev_err(&client->dev,
- "unable to set clock %s freq to %u\n",
- sensor->platform_data->ext_clk_name,
- sensor->platform_data->ext_clk);
- rval = -ENODEV;
- goto out_clk_set_rate;
- }
- }
-
- if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) {
- if (gpio_request_one(sensor->platform_data->xshutdown, 0,
- "SMIA++ xshutdown") != 0) {
- dev_err(&client->dev,
- "unable to acquire reset gpio %d\n",
- sensor->platform_data->xshutdown);
- rval = -ENODEV;
- goto out_clk_set_rate;
- }
- }
-
- rval = smiapp_power_on(sensor);
- if (rval) {
- rval = -ENODEV;
- goto out_smiapp_power_on;
- }
-
- rval = smiapp_identify_module(subdev);
- if (rval) {
- rval = -ENODEV;
- goto out_power_off;
- }
-
- rval = smiapp_get_all_limits(sensor);
- if (rval) {
- rval = -ENODEV;
- goto out_power_off;
- }
-
- /*
- * Handle Sensor Module orientation on the board.
- *
- * The application of H-FLIP and V-FLIP on the sensor is modified by
- * the sensor orientation on the board.
- *
- * For SMIAPP_BOARD_SENSOR_ORIENT_180 the default behaviour is to set
- * both H-FLIP and V-FLIP for normal operation which also implies
- * that a set/unset operation for user space HFLIP and VFLIP v4l2
- * controls will need to be internally inverted.
- *
- * Rotation also changes the bayer pattern.
- */
- if (sensor->platform_data->module_board_orient ==
- SMIAPP_MODULE_BOARD_ORIENT_180)
- sensor->hvflip_inv_mask = SMIAPP_IMAGE_ORIENTATION_HFLIP |
- SMIAPP_IMAGE_ORIENTATION_VFLIP;
-
- rval = smiapp_get_mbus_formats(sensor);
- if (rval) {
- rval = -ENODEV;
- goto out_power_off;
- }
-
- if (sensor->limits[SMIAPP_LIMIT_BINNING_CAPABILITY]) {
- u32 val;
-
- rval = smiapp_read(sensor,
- SMIAPP_REG_U8_BINNING_SUBTYPES, &val);
- if (rval < 0) {
- rval = -ENODEV;
- goto out_power_off;
- }
- sensor->nbinning_subtypes = min_t(u8, val,
- SMIAPP_BINNING_SUBTYPES);
-
- for (i = 0; i < sensor->nbinning_subtypes; i++) {
- rval = smiapp_read(
- sensor, SMIAPP_REG_U8_BINNING_TYPE_n(i), &val);
- if (rval < 0) {
- rval = -ENODEV;
- goto out_power_off;
- }
- sensor->binning_subtypes[i] =
- *(struct smiapp_binning_subtype *)&val;
-
- dev_dbg(&client->dev, "binning %xx%x\n",
- sensor->binning_subtypes[i].horizontal,
- sensor->binning_subtypes[i].vertical);
- }
- }
- sensor->binning_horizontal = 1;
- sensor->binning_vertical = 1;
-
- /* SMIA++ NVM initialization - it will be read from the sensor
- * when it is first requested by userspace.
- */
- if (sensor->minfo.smiapp_version && sensor->platform_data->nvm_size) {
- sensor->nvm = kzalloc(sensor->platform_data->nvm_size,
- GFP_KERNEL);
- if (sensor->nvm == NULL) {
- dev_err(&client->dev, "nvm buf allocation failed\n");
- rval = -ENOMEM;
- goto out_power_off;
- }
-
- if (device_create_file(&client->dev, &dev_attr_nvm) != 0) {
- dev_err(&client->dev, "sysfs nvm entry failed\n");
- rval = -EBUSY;
- goto out_power_off;
- }
- }
-
- rval = smiapp_call_quirk(sensor, limits);
- if (rval) {
- dev_err(&client->dev, "limits quirks failed\n");
- goto out_nvm_release;
- }
-
- /* We consider this as profile 0 sensor if any of these are zero. */
- if (!sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV] ||
- !sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV] ||
- !sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV] ||
- !sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV]) {
- sensor->minfo.smiapp_profile = SMIAPP_PROFILE_0;
- } else if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
- != SMIAPP_SCALING_CAPABILITY_NONE) {
- if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
- == SMIAPP_SCALING_CAPABILITY_HORIZONTAL)
- sensor->minfo.smiapp_profile = SMIAPP_PROFILE_1;
- else
- sensor->minfo.smiapp_profile = SMIAPP_PROFILE_2;
- sensor->scaler = &sensor->ssds[sensor->ssds_used];
- sensor->ssds_used++;
- } else if (sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY]
- == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) {
- sensor->scaler = &sensor->ssds[sensor->ssds_used];
- sensor->ssds_used++;
- }
- sensor->binner = &sensor->ssds[sensor->ssds_used];
- sensor->ssds_used++;
- sensor->pixel_array = &sensor->ssds[sensor->ssds_used];
- sensor->ssds_used++;
-
- sensor->scale_m = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
-
- for (i = 0; i < SMIAPP_SUBDEVS; i++) {
- struct {
- struct smiapp_subdev *ssd;
- char *name;
- } const __this[] = {
- { sensor->scaler, "scaler", },
- { sensor->binner, "binner", },
- { sensor->pixel_array, "pixel array", },
- }, *_this = &__this[i];
- struct smiapp_subdev *this = _this->ssd;
-
- if (!this)
- continue;
-
- if (this != sensor->src)
- v4l2_subdev_init(&this->sd, &smiapp_ops);
-
- this->sensor = sensor;
-
- if (this == sensor->pixel_array) {
- this->npads = 1;
- } else {
- this->npads = 2;
- this->source_pad = 1;
- }
-
- snprintf(this->sd.name,
- sizeof(this->sd.name), "%s %s",
- sensor->minfo.name, _this->name);
-
- this->sink_fmt.width =
- sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
- this->sink_fmt.height =
- sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1;
- this->compose.width = this->sink_fmt.width;
- this->compose.height = this->sink_fmt.height;
- this->crop[this->source_pad] = this->compose;
- this->pads[this->source_pad].flags = MEDIA_PAD_FL_SOURCE;
- if (this != sensor->pixel_array) {
- this->crop[this->sink_pad] = this->compose;
- this->pads[this->sink_pad].flags = MEDIA_PAD_FL_SINK;
- }
-
- this->sd.entity.ops = &smiapp_entity_ops;
-
- if (last == NULL) {
- last = this;
- continue;
- }
-
- this->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- this->sd.internal_ops = &smiapp_internal_ops;
- this->sd.owner = NULL;
- v4l2_set_subdevdata(&this->sd, client);
-
- rval = media_entity_init(&this->sd.entity,
- this->npads, this->pads, 0);
- if (rval) {
- dev_err(&client->dev,
- "media_entity_init failed\n");
- goto out_nvm_release;
- }
-
- rval = media_entity_create_link(&this->sd.entity,
- this->source_pad,
- &last->sd.entity,
- last->sink_pad,
- MEDIA_LNK_FL_ENABLED |
- MEDIA_LNK_FL_IMMUTABLE);
- if (rval) {
- dev_err(&client->dev,
- "media_entity_create_link failed\n");
- goto out_nvm_release;
- }
-
- rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev,
- &this->sd);
- if (rval) {
- dev_err(&client->dev,
- "v4l2_device_register_subdev failed\n");
- goto out_nvm_release;
- }
-
- last = this;
- }
-
- dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile);
-
- sensor->pixel_array->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-
- /* final steps */
- smiapp_read_frame_fmt(sensor);
- rval = smiapp_init_controls(sensor);
- if (rval < 0)
- goto out_nvm_release;
-
- rval = smiapp_update_mode(sensor);
- if (rval) {
- dev_err(&client->dev, "update mode failed\n");
- goto out_nvm_release;
- }
-
- sensor->streaming = false;
- sensor->dev_init_done = true;
-
- /* check flash capability */
- rval = smiapp_read(sensor, SMIAPP_REG_U8_FLASH_MODE_CAPABILITY, &tmp);
- sensor->flash_capability = tmp;
- if (rval)
- goto out_nvm_release;
-
- smiapp_power_off(sensor);
-
- return 0;
-
-out_nvm_release:
- device_remove_file(&client->dev, &dev_attr_nvm);
-
-out_power_off:
- kfree(sensor->nvm);
- sensor->nvm = NULL;
- smiapp_power_off(sensor);
-
-out_smiapp_power_on:
- if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
- gpio_free(sensor->platform_data->xshutdown);
-
-out_clk_set_rate:
- clk_put(sensor->ext_clk);
- sensor->ext_clk = NULL;
-
-out_clk_get:
- regulator_put(sensor->vana);
- sensor->vana = NULL;
- return rval;
-}
-
-static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- struct smiapp_subdev *ssd = to_smiapp_subdev(sd);
- struct smiapp_sensor *sensor = ssd->sensor;
- u32 mbus_code =
- smiapp_csi_data_formats[smiapp_pixel_order(sensor)].code;
- unsigned int i;
-
- mutex_lock(&sensor->mutex);
-
- for (i = 0; i < ssd->npads; i++) {
- struct v4l2_mbus_framefmt *try_fmt =
- v4l2_subdev_get_try_format(fh, i);
- struct v4l2_rect *try_crop = v4l2_subdev_get_try_crop(fh, i);
- struct v4l2_rect *try_comp;
-
- try_fmt->width = sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
- try_fmt->height = sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1;
- try_fmt->code = mbus_code;
-
- try_crop->top = 0;
- try_crop->left = 0;
- try_crop->width = try_fmt->width;
- try_crop->height = try_fmt->height;
-
- if (ssd != sensor->pixel_array)
- continue;
-
- try_comp = v4l2_subdev_get_try_compose(fh, i);
- *try_comp = *try_crop;
- }
-
- mutex_unlock(&sensor->mutex);
-
- return smiapp_set_power(sd, 1);
-}
-
-static int smiapp_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- return smiapp_set_power(sd, 0);
-}
-
-static const struct v4l2_subdev_video_ops smiapp_video_ops = {
- .s_stream = smiapp_set_stream,
-};
-
-static const struct v4l2_subdev_core_ops smiapp_core_ops = {
- .s_power = smiapp_set_power,
-};
-
-static const struct v4l2_subdev_pad_ops smiapp_pad_ops = {
- .enum_mbus_code = smiapp_enum_mbus_code,
- .get_fmt = smiapp_get_format,
- .set_fmt = smiapp_set_format,
- .get_selection = smiapp_get_selection,
- .set_selection = smiapp_set_selection,
-};
-
-static const struct v4l2_subdev_sensor_ops smiapp_sensor_ops = {
- .g_skip_frames = smiapp_get_skip_frames,
-};
-
-static const struct v4l2_subdev_ops smiapp_ops = {
- .core = &smiapp_core_ops,
- .video = &smiapp_video_ops,
- .pad = &smiapp_pad_ops,
- .sensor = &smiapp_sensor_ops,
-};
-
-static const struct media_entity_operations smiapp_entity_ops = {
- .link_validate = v4l2_subdev_link_validate,
-};
-
-static const struct v4l2_subdev_internal_ops smiapp_internal_src_ops = {
- .registered = smiapp_registered,
- .open = smiapp_open,
- .close = smiapp_close,
-};
-
-static const struct v4l2_subdev_internal_ops smiapp_internal_ops = {
- .open = smiapp_open,
- .close = smiapp_close,
-};
-
-/* -----------------------------------------------------------------------------
- * I2C Driver
- */
-
-#ifdef CONFIG_PM
-
-static int smiapp_suspend(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- bool streaming;
-
- BUG_ON(mutex_is_locked(&sensor->mutex));
-
- if (sensor->power_count == 0)
- return 0;
-
- if (sensor->streaming)
- smiapp_stop_streaming(sensor);
-
- streaming = sensor->streaming;
-
- smiapp_power_off(sensor);
-
- /* save state for resume */
- sensor->streaming = streaming;
-
- return 0;
-}
-
-static int smiapp_resume(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- int rval;
-
- if (sensor->power_count == 0)
- return 0;
-
- rval = smiapp_power_on(sensor);
- if (rval)
- return rval;
-
- if (sensor->streaming)
- rval = smiapp_start_streaming(sensor);
-
- return rval;
-}
-
-#else
-
-#define smiapp_suspend NULL
-#define smiapp_resume NULL
-
-#endif /* CONFIG_PM */
-
-static int smiapp_probe(struct i2c_client *client,
- const struct i2c_device_id *devid)
-{
- struct smiapp_sensor *sensor;
- int rval;
-
- if (client->dev.platform_data == NULL)
- return -ENODEV;
-
- sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
- if (sensor == NULL)
- return -ENOMEM;
-
- sensor->platform_data = client->dev.platform_data;
- mutex_init(&sensor->mutex);
- mutex_init(&sensor->power_mutex);
- sensor->src = &sensor->ssds[sensor->ssds_used];
-
- v4l2_i2c_subdev_init(&sensor->src->sd, client, &smiapp_ops);
- sensor->src->sd.internal_ops = &smiapp_internal_src_ops;
- sensor->src->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- sensor->src->sensor = sensor;
-
- sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE;
- rval = media_entity_init(&sensor->src->sd.entity, 2,
- sensor->src->pads, 0);
- if (rval < 0)
- kfree(sensor);
-
- return rval;
-}
-
-static int __exit smiapp_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
- unsigned int i;
-
- if (sensor->power_count) {
- if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
- gpio_set_value(sensor->platform_data->xshutdown, 0);
- if (sensor->platform_data->set_xclk)
- sensor->platform_data->set_xclk(&sensor->src->sd, 0);
- else
- clk_disable(sensor->ext_clk);
- sensor->power_count = 0;
- }
-
- if (sensor->nvm) {
- device_remove_file(&client->dev, &dev_attr_nvm);
- kfree(sensor->nvm);
- }
-
- for (i = 0; i < sensor->ssds_used; i++) {
- media_entity_cleanup(&sensor->ssds[i].sd.entity);
- v4l2_device_unregister_subdev(&sensor->ssds[i].sd);
- }
- smiapp_free_controls(sensor);
- if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
- gpio_free(sensor->platform_data->xshutdown);
- if (sensor->ext_clk)
- clk_put(sensor->ext_clk);
- if (sensor->vana)
- regulator_put(sensor->vana);
-
- kfree(sensor);
-
- return 0;
-}
-
-static const struct i2c_device_id smiapp_id_table[] = {
- { SMIAPP_NAME, 0 },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, smiapp_id_table);
-
-static const struct dev_pm_ops smiapp_pm_ops = {
- .suspend = smiapp_suspend,
- .resume = smiapp_resume,
-};
-
-static struct i2c_driver smiapp_i2c_driver = {
- .driver = {
- .name = SMIAPP_NAME,
- .pm = &smiapp_pm_ops,
- },
- .probe = smiapp_probe,
- .remove = __exit_p(smiapp_remove),
- .id_table = smiapp_id_table,
-};
-
-module_i2c_driver(smiapp_i2c_driver);
-
-MODULE_AUTHOR("Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>");
-MODULE_DESCRIPTION("Generic SMIA/SMIA++ camera module driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/smiapp/smiapp-limits.c b/drivers/media/video/smiapp/smiapp-limits.c
deleted file mode 100644
index 0800e095724..00000000000
--- a/drivers/media/video/smiapp/smiapp-limits.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * drivers/media/video/smiapp/smiapp-limits.c
- *
- * Generic driver for SMIA/SMIA++ compliant camera modules
- *
- * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "smiapp.h"
-
-struct smiapp_reg_limits smiapp_reg_limits[] = {
- { SMIAPP_REG_U16_ANALOGUE_GAIN_CAPABILITY, "analogue_gain_capability" }, /* 0 */
- { SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_MIN, "analogue_gain_code_min" },
- { SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_MAX, "analogue_gain_code_max" },
- { SMIAPP_REG_U8_THS_ZERO_MIN, "ths_zero_min" },
- { SMIAPP_REG_U8_TCLK_TRAIL_MIN, "tclk_trail_min" },
- { SMIAPP_REG_U16_INTEGRATION_TIME_CAPABILITY, "integration_time_capability" }, /* 5 */
- { SMIAPP_REG_U16_COARSE_INTEGRATION_TIME_MIN, "coarse_integration_time_min" },
- { SMIAPP_REG_U16_COARSE_INTEGRATION_TIME_MAX_MARGIN, "coarse_integration_time_max_margin" },
- { SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MIN, "fine_integration_time_min" },
- { SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MAX_MARGIN, "fine_integration_time_max_margin" },
- { SMIAPP_REG_U16_DIGITAL_GAIN_CAPABILITY, "digital_gain_capability" }, /* 10 */
- { SMIAPP_REG_U16_DIGITAL_GAIN_MIN, "digital_gain_min" },
- { SMIAPP_REG_U16_DIGITAL_GAIN_MAX, "digital_gain_max" },
- { SMIAPP_REG_F32_MIN_EXT_CLK_FREQ_HZ, "min_ext_clk_freq_hz" },
- { SMIAPP_REG_F32_MAX_EXT_CLK_FREQ_HZ, "max_ext_clk_freq_hz" },
- { SMIAPP_REG_U16_MIN_PRE_PLL_CLK_DIV, "min_pre_pll_clk_div" }, /* 15 */
- { SMIAPP_REG_U16_MAX_PRE_PLL_CLK_DIV, "max_pre_pll_clk_div" },
- { SMIAPP_REG_F32_MIN_PLL_IP_FREQ_HZ, "min_pll_ip_freq_hz" },
- { SMIAPP_REG_F32_MAX_PLL_IP_FREQ_HZ, "max_pll_ip_freq_hz" },
- { SMIAPP_REG_U16_MIN_PLL_MULTIPLIER, "min_pll_multiplier" },
- { SMIAPP_REG_U16_MAX_PLL_MULTIPLIER, "max_pll_multiplier" }, /* 20 */
- { SMIAPP_REG_F32_MIN_PLL_OP_FREQ_HZ, "min_pll_op_freq_hz" },
- { SMIAPP_REG_F32_MAX_PLL_OP_FREQ_HZ, "max_pll_op_freq_hz" },
- { SMIAPP_REG_U16_MIN_VT_SYS_CLK_DIV, "min_vt_sys_clk_div" },
- { SMIAPP_REG_U16_MAX_VT_SYS_CLK_DIV, "max_vt_sys_clk_div" },
- { SMIAPP_REG_F32_MIN_VT_SYS_CLK_FREQ_HZ, "min_vt_sys_clk_freq_hz" }, /* 25 */
- { SMIAPP_REG_F32_MAX_VT_SYS_CLK_FREQ_HZ, "max_vt_sys_clk_freq_hz" },
- { SMIAPP_REG_F32_MIN_VT_PIX_CLK_FREQ_HZ, "min_vt_pix_clk_freq_hz" },
- { SMIAPP_REG_F32_MAX_VT_PIX_CLK_FREQ_HZ, "max_vt_pix_clk_freq_hz" },
- { SMIAPP_REG_U16_MIN_VT_PIX_CLK_DIV, "min_vt_pix_clk_div" },
- { SMIAPP_REG_U16_MAX_VT_PIX_CLK_DIV, "max_vt_pix_clk_div" }, /* 30 */
- { SMIAPP_REG_U16_MIN_FRAME_LENGTH_LINES, "min_frame_length_lines" },
- { SMIAPP_REG_U16_MAX_FRAME_LENGTH_LINES, "max_frame_length_lines" },
- { SMIAPP_REG_U16_MIN_LINE_LENGTH_PCK, "min_line_length_pck" },
- { SMIAPP_REG_U16_MAX_LINE_LENGTH_PCK, "max_line_length_pck" },
- { SMIAPP_REG_U16_MIN_LINE_BLANKING_PCK, "min_line_blanking_pck" }, /* 35 */
- { SMIAPP_REG_U16_MIN_FRAME_BLANKING_LINES, "min_frame_blanking_lines" },
- { SMIAPP_REG_U8_MIN_LINE_LENGTH_PCK_STEP_SIZE, "min_line_length_pck_step_size" },
- { SMIAPP_REG_U16_MIN_OP_SYS_CLK_DIV, "min_op_sys_clk_div" },
- { SMIAPP_REG_U16_MAX_OP_SYS_CLK_DIV, "max_op_sys_clk_div" },
- { SMIAPP_REG_F32_MIN_OP_SYS_CLK_FREQ_HZ, "min_op_sys_clk_freq_hz" }, /* 40 */
- { SMIAPP_REG_F32_MAX_OP_SYS_CLK_FREQ_HZ, "max_op_sys_clk_freq_hz" },
- { SMIAPP_REG_U16_MIN_OP_PIX_CLK_DIV, "min_op_pix_clk_div" },
- { SMIAPP_REG_U16_MAX_OP_PIX_CLK_DIV, "max_op_pix_clk_div" },
- { SMIAPP_REG_F32_MIN_OP_PIX_CLK_FREQ_HZ, "min_op_pix_clk_freq_hz" },
- { SMIAPP_REG_F32_MAX_OP_PIX_CLK_FREQ_HZ, "max_op_pix_clk_freq_hz" }, /* 45 */
- { SMIAPP_REG_U16_X_ADDR_MIN, "x_addr_min" },
- { SMIAPP_REG_U16_Y_ADDR_MIN, "y_addr_min" },
- { SMIAPP_REG_U16_X_ADDR_MAX, "x_addr_max" },
- { SMIAPP_REG_U16_Y_ADDR_MAX, "y_addr_max" },
- { SMIAPP_REG_U16_MIN_X_OUTPUT_SIZE, "min_x_output_size" }, /* 50 */
- { SMIAPP_REG_U16_MIN_Y_OUTPUT_SIZE, "min_y_output_size" },
- { SMIAPP_REG_U16_MAX_X_OUTPUT_SIZE, "max_x_output_size" },
- { SMIAPP_REG_U16_MAX_Y_OUTPUT_SIZE, "max_y_output_size" },
- { SMIAPP_REG_U16_MIN_EVEN_INC, "min_even_inc" },
- { SMIAPP_REG_U16_MAX_EVEN_INC, "max_even_inc" }, /* 55 */
- { SMIAPP_REG_U16_MIN_ODD_INC, "min_odd_inc" },
- { SMIAPP_REG_U16_MAX_ODD_INC, "max_odd_inc" },
- { SMIAPP_REG_U16_SCALING_CAPABILITY, "scaling_capability" },
- { SMIAPP_REG_U16_SCALER_M_MIN, "scaler_m_min" },
- { SMIAPP_REG_U16_SCALER_M_MAX, "scaler_m_max" }, /* 60 */
- { SMIAPP_REG_U16_SCALER_N_MIN, "scaler_n_min" },
- { SMIAPP_REG_U16_SCALER_N_MAX, "scaler_n_max" },
- { SMIAPP_REG_U16_SPATIAL_SAMPLING_CAPABILITY, "spatial_sampling_capability" },
- { SMIAPP_REG_U8_DIGITAL_CROP_CAPABILITY, "digital_crop_capability" },
- { SMIAPP_REG_U16_COMPRESSION_CAPABILITY, "compression_capability" }, /* 65 */
- { SMIAPP_REG_U8_FIFO_SUPPORT_CAPABILITY, "fifo_support_capability" },
- { SMIAPP_REG_U8_DPHY_CTRL_CAPABILITY, "dphy_ctrl_capability" },
- { SMIAPP_REG_U8_CSI_LANE_MODE_CAPABILITY, "csi_lane_mode_capability" },
- { SMIAPP_REG_U8_CSI_SIGNALLING_MODE_CAPABILITY, "csi_signalling_mode_capability" },
- { SMIAPP_REG_U8_FAST_STANDBY_CAPABILITY, "fast_standby_capability" }, /* 70 */
- { SMIAPP_REG_U8_CCI_ADDRESS_CONTROL_CAPABILITY, "cci_address_control_capability" },
- { SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_1_LANE_MODE_MBPS, "max_per_lane_bitrate_1_lane_mode_mbps" },
- { SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_2_LANE_MODE_MBPS, "max_per_lane_bitrate_2_lane_mode_mbps" },
- { SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_3_LANE_MODE_MBPS, "max_per_lane_bitrate_3_lane_mode_mbps" },
- { SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_4_LANE_MODE_MBPS, "max_per_lane_bitrate_4_lane_mode_mbps" }, /* 75 */
- { SMIAPP_REG_U8_TEMP_SENSOR_CAPABILITY, "temp_sensor_capability" },
- { SMIAPP_REG_U16_MIN_FRAME_LENGTH_LINES_BIN, "min_frame_length_lines_bin" },
- { SMIAPP_REG_U16_MAX_FRAME_LENGTH_LINES_BIN, "max_frame_length_lines_bin" },
- { SMIAPP_REG_U16_MIN_LINE_LENGTH_PCK_BIN, "min_line_length_pck_bin" },
- { SMIAPP_REG_U16_MAX_LINE_LENGTH_PCK_BIN, "max_line_length_pck_bin" }, /* 80 */
- { SMIAPP_REG_U16_MIN_LINE_BLANKING_PCK_BIN, "min_line_blanking_pck_bin" },
- { SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MIN_BIN, "fine_integration_time_min_bin" },
- { SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MAX_MARGIN_BIN, "fine_integration_time_max_margin_bin" },
- { SMIAPP_REG_U8_BINNING_CAPABILITY, "binning_capability" },
- { SMIAPP_REG_U8_BINNING_WEIGHTING_CAPABILITY, "binning_weighting_capability" }, /* 85 */
- { SMIAPP_REG_U8_DATA_TRANSFER_IF_CAPABILITY, "data_transfer_if_capability" },
- { SMIAPP_REG_U8_SHADING_CORRECTION_CAPABILITY, "shading_correction_capability" },
- { SMIAPP_REG_U8_GREEN_IMBALANCE_CAPABILITY, "green_imbalance_capability" },
- { SMIAPP_REG_U8_BLACK_LEVEL_CAPABILITY, "black_level_capability" },
- { SMIAPP_REG_U8_MODULE_SPECIFIC_CORRECTION_CAPABILITY, "module_specific_correction_capability" }, /* 90 */
- { SMIAPP_REG_U16_DEFECT_CORRECTION_CAPABILITY, "defect_correction_capability" },
- { SMIAPP_REG_U16_DEFECT_CORRECTION_CAPABILITY_2, "defect_correction_capability_2" },
- { SMIAPP_REG_U8_EDOF_CAPABILITY, "edof_capability" },
- { SMIAPP_REG_U8_COLOUR_FEEDBACK_CAPABILITY, "colour_feedback_capability" },
- { SMIAPP_REG_U8_ESTIMATION_MODE_CAPABILITY, "estimation_mode_capability" }, /* 95 */
- { SMIAPP_REG_U8_ESTIMATION_ZONE_CAPABILITY, "estimation_zone_capability" },
- { SMIAPP_REG_U16_CAPABILITY_TRDY_MIN, "capability_trdy_min" },
- { SMIAPP_REG_U8_FLASH_MODE_CAPABILITY, "flash_mode_capability" },
- { SMIAPP_REG_U8_ACTUATOR_CAPABILITY, "actuator_capability" },
- { SMIAPP_REG_U8_BRACKETING_LUT_CAPABILITY_1, "bracketing_lut_capability_1" }, /* 100 */
- { SMIAPP_REG_U8_BRACKETING_LUT_CAPABILITY_2, "bracketing_lut_capability_2" },
- { SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_STEP, "analogue_gain_code_step" },
- { 0, NULL },
-};
diff --git a/drivers/media/video/smiapp/smiapp-limits.h b/drivers/media/video/smiapp/smiapp-limits.h
deleted file mode 100644
index 7f4836bb78d..00000000000
--- a/drivers/media/video/smiapp/smiapp-limits.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * drivers/media/video/smiapp/smiapp-limits.h
- *
- * Generic driver for SMIA/SMIA++ compliant camera modules
- *
- * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#define SMIAPP_LIMIT_ANALOGUE_GAIN_CAPABILITY 0
-#define SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MIN 1
-#define SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MAX 2
-#define SMIAPP_LIMIT_THS_ZERO_MIN 3
-#define SMIAPP_LIMIT_TCLK_TRAIL_MIN 4
-#define SMIAPP_LIMIT_INTEGRATION_TIME_CAPABILITY 5
-#define SMIAPP_LIMIT_COARSE_INTEGRATION_TIME_MIN 6
-#define SMIAPP_LIMIT_COARSE_INTEGRATION_TIME_MAX_MARGIN 7
-#define SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MIN 8
-#define SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MAX_MARGIN 9
-#define SMIAPP_LIMIT_DIGITAL_GAIN_CAPABILITY 10
-#define SMIAPP_LIMIT_DIGITAL_GAIN_MIN 11
-#define SMIAPP_LIMIT_DIGITAL_GAIN_MAX 12
-#define SMIAPP_LIMIT_MIN_EXT_CLK_FREQ_HZ 13
-#define SMIAPP_LIMIT_MAX_EXT_CLK_FREQ_HZ 14
-#define SMIAPP_LIMIT_MIN_PRE_PLL_CLK_DIV 15
-#define SMIAPP_LIMIT_MAX_PRE_PLL_CLK_DIV 16
-#define SMIAPP_LIMIT_MIN_PLL_IP_FREQ_HZ 17
-#define SMIAPP_LIMIT_MAX_PLL_IP_FREQ_HZ 18
-#define SMIAPP_LIMIT_MIN_PLL_MULTIPLIER 19
-#define SMIAPP_LIMIT_MAX_PLL_MULTIPLIER 20
-#define SMIAPP_LIMIT_MIN_PLL_OP_FREQ_HZ 21
-#define SMIAPP_LIMIT_MAX_PLL_OP_FREQ_HZ 22
-#define SMIAPP_LIMIT_MIN_VT_SYS_CLK_DIV 23
-#define SMIAPP_LIMIT_MAX_VT_SYS_CLK_DIV 24
-#define SMIAPP_LIMIT_MIN_VT_SYS_CLK_FREQ_HZ 25
-#define SMIAPP_LIMIT_MAX_VT_SYS_CLK_FREQ_HZ 26
-#define SMIAPP_LIMIT_MIN_VT_PIX_CLK_FREQ_HZ 27
-#define SMIAPP_LIMIT_MAX_VT_PIX_CLK_FREQ_HZ 28
-#define SMIAPP_LIMIT_MIN_VT_PIX_CLK_DIV 29
-#define SMIAPP_LIMIT_MAX_VT_PIX_CLK_DIV 30
-#define SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES 31
-#define SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES 32
-#define SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK 33
-#define SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK 34
-#define SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK 35
-#define SMIAPP_LIMIT_MIN_FRAME_BLANKING_LINES 36
-#define SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_STEP_SIZE 37
-#define SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV 38
-#define SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV 39
-#define SMIAPP_LIMIT_MIN_OP_SYS_CLK_FREQ_HZ 40
-#define SMIAPP_LIMIT_MAX_OP_SYS_CLK_FREQ_HZ 41
-#define SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV 42
-#define SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV 43
-#define SMIAPP_LIMIT_MIN_OP_PIX_CLK_FREQ_HZ 44
-#define SMIAPP_LIMIT_MAX_OP_PIX_CLK_FREQ_HZ 45
-#define SMIAPP_LIMIT_X_ADDR_MIN 46
-#define SMIAPP_LIMIT_Y_ADDR_MIN 47
-#define SMIAPP_LIMIT_X_ADDR_MAX 48
-#define SMIAPP_LIMIT_Y_ADDR_MAX 49
-#define SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE 50
-#define SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE 51
-#define SMIAPP_LIMIT_MAX_X_OUTPUT_SIZE 52
-#define SMIAPP_LIMIT_MAX_Y_OUTPUT_SIZE 53
-#define SMIAPP_LIMIT_MIN_EVEN_INC 54
-#define SMIAPP_LIMIT_MAX_EVEN_INC 55
-#define SMIAPP_LIMIT_MIN_ODD_INC 56
-#define SMIAPP_LIMIT_MAX_ODD_INC 57
-#define SMIAPP_LIMIT_SCALING_CAPABILITY 58
-#define SMIAPP_LIMIT_SCALER_M_MIN 59
-#define SMIAPP_LIMIT_SCALER_M_MAX 60
-#define SMIAPP_LIMIT_SCALER_N_MIN 61
-#define SMIAPP_LIMIT_SCALER_N_MAX 62
-#define SMIAPP_LIMIT_SPATIAL_SAMPLING_CAPABILITY 63
-#define SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY 64
-#define SMIAPP_LIMIT_COMPRESSION_CAPABILITY 65
-#define SMIAPP_LIMIT_FIFO_SUPPORT_CAPABILITY 66
-#define SMIAPP_LIMIT_DPHY_CTRL_CAPABILITY 67
-#define SMIAPP_LIMIT_CSI_LANE_MODE_CAPABILITY 68
-#define SMIAPP_LIMIT_CSI_SIGNALLING_MODE_CAPABILITY 69
-#define SMIAPP_LIMIT_FAST_STANDBY_CAPABILITY 70
-#define SMIAPP_LIMIT_CCI_ADDRESS_CONTROL_CAPABILITY 71
-#define SMIAPP_LIMIT_MAX_PER_LANE_BITRATE_1_LANE_MODE_MBPS 72
-#define SMIAPP_LIMIT_MAX_PER_LANE_BITRATE_2_LANE_MODE_MBPS 73
-#define SMIAPP_LIMIT_MAX_PER_LANE_BITRATE_3_LANE_MODE_MBPS 74
-#define SMIAPP_LIMIT_MAX_PER_LANE_BITRATE_4_LANE_MODE_MBPS 75
-#define SMIAPP_LIMIT_TEMP_SENSOR_CAPABILITY 76
-#define SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN 77
-#define SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES_BIN 78
-#define SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN 79
-#define SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK_BIN 80
-#define SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN 81
-#define SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MIN_BIN 82
-#define SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MAX_MARGIN_BIN 83
-#define SMIAPP_LIMIT_BINNING_CAPABILITY 84
-#define SMIAPP_LIMIT_BINNING_WEIGHTING_CAPABILITY 85
-#define SMIAPP_LIMIT_DATA_TRANSFER_IF_CAPABILITY 86
-#define SMIAPP_LIMIT_SHADING_CORRECTION_CAPABILITY 87
-#define SMIAPP_LIMIT_GREEN_IMBALANCE_CAPABILITY 88
-#define SMIAPP_LIMIT_BLACK_LEVEL_CAPABILITY 89
-#define SMIAPP_LIMIT_MODULE_SPECIFIC_CORRECTION_CAPABILITY 90
-#define SMIAPP_LIMIT_DEFECT_CORRECTION_CAPABILITY 91
-#define SMIAPP_LIMIT_DEFECT_CORRECTION_CAPABILITY_2 92
-#define SMIAPP_LIMIT_EDOF_CAPABILITY 93
-#define SMIAPP_LIMIT_COLOUR_FEEDBACK_CAPABILITY 94
-#define SMIAPP_LIMIT_ESTIMATION_MODE_CAPABILITY 95
-#define SMIAPP_LIMIT_ESTIMATION_ZONE_CAPABILITY 96
-#define SMIAPP_LIMIT_CAPABILITY_TRDY_MIN 97
-#define SMIAPP_LIMIT_FLASH_MODE_CAPABILITY 98
-#define SMIAPP_LIMIT_ACTUATOR_CAPABILITY 99
-#define SMIAPP_LIMIT_BRACKETING_LUT_CAPABILITY_1 100
-#define SMIAPP_LIMIT_BRACKETING_LUT_CAPABILITY_2 101
-#define SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_STEP 102
-#define SMIAPP_LIMIT_LAST 103
diff --git a/drivers/media/video/smiapp/smiapp-quirk.c b/drivers/media/video/smiapp/smiapp-quirk.c
deleted file mode 100644
index 55e87950dce..00000000000
--- a/drivers/media/video/smiapp/smiapp-quirk.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * drivers/media/video/smiapp/smiapp-quirk.c
- *
- * Generic driver for SMIA/SMIA++ compliant camera modules
- *
- * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/delay.h>
-
-#include "smiapp.h"
-
-static int smiapp_write_8(struct smiapp_sensor *sensor, u16 reg, u8 val)
-{
- return smiapp_write(sensor, (SMIA_REG_8BIT << 16) | reg, val);
-}
-
-static int smiapp_write_8s(struct smiapp_sensor *sensor,
- struct smiapp_reg_8 *regs, int len)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- int rval;
-
- for (; len > 0; len--, regs++) {
- rval = smiapp_write_8(sensor, regs->reg, regs->val);
- if (rval < 0) {
- dev_err(&client->dev,
- "error %d writing reg 0x%4.4x, val 0x%2.2x",
- rval, regs->reg, regs->val);
- return rval;
- }
- }
-
- return 0;
-}
-
-void smiapp_replace_limit(struct smiapp_sensor *sensor,
- u32 limit, u32 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
-
- dev_dbg(&client->dev, "quirk: 0x%8.8x \"%s\" = %d, 0x%x\n",
- smiapp_reg_limits[limit].addr,
- smiapp_reg_limits[limit].what, val, val);
- sensor->limits[limit] = val;
-}
-
-int smiapp_replace_limit_at(struct smiapp_sensor *sensor,
- u32 reg, u32 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- int i;
-
- for (i = 0; smiapp_reg_limits[i].addr; i++) {
- if ((smiapp_reg_limits[i].addr & 0xffff) != reg)
- continue;
-
- smiapp_replace_limit(sensor, i, val);
-
- return 0;
- }
-
- dev_dbg(&client->dev, "quirk: bad register 0x%4.4x\n", reg);
-
- return -EINVAL;
-}
-
-bool smiapp_quirk_reg(struct smiapp_sensor *sensor,
- u32 reg, u32 *val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- const struct smia_reg *sreg;
-
- if (!sensor->minfo.quirk)
- return false;
-
- sreg = sensor->minfo.quirk->regs;
-
- if (!sreg)
- return false;
-
- while (sreg->type) {
- u16 type = reg >> 16;
- u16 reg16 = reg;
-
- if (sreg->type != type || sreg->reg != reg16) {
- sreg++;
- continue;
- }
-
- switch ((u8)type) {
- case SMIA_REG_8BIT:
- dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%2.2x\n",
- reg, sreg->val);
- break;
- case SMIA_REG_16BIT:
- dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%4.4x\n",
- reg, sreg->val);
- break;
- case SMIA_REG_32BIT:
- dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%8.8x\n",
- reg, sreg->val);
- break;
- }
-
- *val = sreg->val;
-
- return true;
- }
-
- return false;
-}
-
-static int jt8ew9_limits(struct smiapp_sensor *sensor)
-{
- if (sensor->minfo.revision_number_major < 0x03)
- sensor->frame_skip = 1;
-
- /* Below 24 gain doesn't have effect at all, */
- /* but ~59 is needed for full dynamic range */
- smiapp_replace_limit(sensor, SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MIN, 59);
- smiapp_replace_limit(
- sensor, SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MAX, 6000);
-
- return 0;
-}
-
-static int jt8ew9_post_poweron(struct smiapp_sensor *sensor)
-{
- struct smiapp_reg_8 regs[] = {
- { 0x30a3, 0xd8 }, /* Output port control : LVDS ports only */
- { 0x30ae, 0x00 }, /* 0x0307 pll_multiplier maximum value on PLL input 9.6MHz ( 19.2MHz is divided on pre_pll_div) */
- { 0x30af, 0xd0 }, /* 0x0307 pll_multiplier maximum value on PLL input 9.6MHz ( 19.2MHz is divided on pre_pll_div) */
- { 0x322d, 0x04 }, /* Adjusting Processing Image Size to Scaler Toshiba Recommendation Setting */
- { 0x3255, 0x0f }, /* Horizontal Noise Reduction Control Toshiba Recommendation Setting */
- { 0x3256, 0x15 }, /* Horizontal Noise Reduction Control Toshiba Recommendation Setting */
- { 0x3258, 0x70 }, /* Analog Gain Control Toshiba Recommendation Setting */
- { 0x3259, 0x70 }, /* Analog Gain Control Toshiba Recommendation Setting */
- { 0x325f, 0x7c }, /* Analog Gain Control Toshiba Recommendation Setting */
- { 0x3302, 0x06 }, /* Pixel Reference Voltage Control Toshiba Recommendation Setting */
- { 0x3304, 0x00 }, /* Pixel Reference Voltage Control Toshiba Recommendation Setting */
- { 0x3307, 0x22 }, /* Pixel Reference Voltage Control Toshiba Recommendation Setting */
- { 0x3308, 0x8d }, /* Pixel Reference Voltage Control Toshiba Recommendation Setting */
- { 0x331e, 0x0f }, /* Black Hole Sun Correction Control Toshiba Recommendation Setting */
- { 0x3320, 0x30 }, /* Black Hole Sun Correction Control Toshiba Recommendation Setting */
- { 0x3321, 0x11 }, /* Black Hole Sun Correction Control Toshiba Recommendation Setting */
- { 0x3322, 0x98 }, /* Black Hole Sun Correction Control Toshiba Recommendation Setting */
- { 0x3323, 0x64 }, /* Black Hole Sun Correction Control Toshiba Recommendation Setting */
- { 0x3325, 0x83 }, /* Read Out Timing Control Toshiba Recommendation Setting */
- { 0x3330, 0x18 }, /* Read Out Timing Control Toshiba Recommendation Setting */
- { 0x333c, 0x01 }, /* Read Out Timing Control Toshiba Recommendation Setting */
- { 0x3345, 0x2f }, /* Black Hole Sun Correction Control Toshiba Recommendation Setting */
- { 0x33de, 0x38 }, /* Horizontal Noise Reduction Control Toshiba Recommendation Setting */
- /* Taken from v03. No idea what the rest are. */
- { 0x32e0, 0x05 },
- { 0x32e1, 0x05 },
- { 0x32e2, 0x04 },
- { 0x32e5, 0x04 },
- { 0x32e6, 0x04 },
-
- };
-
- return smiapp_write_8s(sensor, regs, ARRAY_SIZE(regs));
-}
-
-const struct smiapp_quirk smiapp_jt8ew9_quirk = {
- .limits = jt8ew9_limits,
- .post_poweron = jt8ew9_post_poweron,
-};
-
-static int imx125es_post_poweron(struct smiapp_sensor *sensor)
-{
- /* Taken from v02. No idea what the other two are. */
- struct smiapp_reg_8 regs[] = {
- /*
- * 0x3302: clk during frame blanking:
- * 0x00 - HS mode, 0x01 - LP11
- */
- { 0x3302, 0x01 },
- { 0x302d, 0x00 },
- { 0x3b08, 0x8c },
- };
-
- return smiapp_write_8s(sensor, regs, ARRAY_SIZE(regs));
-}
-
-const struct smiapp_quirk smiapp_imx125es_quirk = {
- .post_poweron = imx125es_post_poweron,
-};
-
-static int jt8ev1_limits(struct smiapp_sensor *sensor)
-{
- smiapp_replace_limit(sensor, SMIAPP_LIMIT_X_ADDR_MAX, 4271);
- smiapp_replace_limit(sensor,
- SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN, 184);
-
- return 0;
-}
-
-static int jt8ev1_post_poweron(struct smiapp_sensor *sensor)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- int rval;
-
- struct smiapp_reg_8 regs[] = {
- { 0x3031, 0xcd }, /* For digital binning (EQ_MONI) */
- { 0x30a3, 0xd0 }, /* FLASH STROBE enable */
- { 0x3237, 0x00 }, /* For control of pulse timing for ADC */
- { 0x3238, 0x43 },
- { 0x3301, 0x06 }, /* For analog bias for sensor */
- { 0x3302, 0x06 },
- { 0x3304, 0x00 },
- { 0x3305, 0x88 },
- { 0x332a, 0x14 },
- { 0x332c, 0x6b },
- { 0x3336, 0x01 },
- { 0x333f, 0x1f },
- { 0x3355, 0x00 },
- { 0x3356, 0x20 },
- { 0x33bf, 0x20 }, /* Adjust the FBC speed */
- { 0x33c9, 0x20 },
- { 0x33ce, 0x30 }, /* Adjust the parameter for logic function */
- { 0x33cf, 0xec }, /* For Black sun */
- { 0x3328, 0x80 }, /* Ugh. No idea what's this. */
- };
-
- struct smiapp_reg_8 regs_96[] = {
- { 0x30ae, 0x00 }, /* For control of ADC clock */
- { 0x30af, 0xd0 },
- { 0x30b0, 0x01 },
- };
-
- rval = smiapp_write_8s(sensor, regs, ARRAY_SIZE(regs));
- if (rval < 0)
- return rval;
-
- switch (sensor->platform_data->ext_clk) {
- case 9600000:
- return smiapp_write_8s(sensor, regs_96,
- ARRAY_SIZE(regs_96));
- default:
- dev_warn(&client->dev, "no MSRs for %d Hz ext_clk\n",
- sensor->platform_data->ext_clk);
- return 0;
- }
-}
-
-static int jt8ev1_pre_streamon(struct smiapp_sensor *sensor)
-{
- return smiapp_write_8(sensor, 0x3328, 0x00);
-}
-
-static int jt8ev1_post_streamoff(struct smiapp_sensor *sensor)
-{
- int rval;
-
- /* Workaround: allows fast standby to work properly */
- rval = smiapp_write_8(sensor, 0x3205, 0x04);
- if (rval < 0)
- return rval;
-
- /* Wait for 1 ms + one line => 2 ms is likely enough */
- usleep_range(2000, 2000);
-
- /* Restore it */
- rval = smiapp_write_8(sensor, 0x3205, 0x00);
- if (rval < 0)
- return rval;
-
- return smiapp_write_8(sensor, 0x3328, 0x80);
-}
-
-const struct smiapp_quirk smiapp_jt8ev1_quirk = {
- .limits = jt8ev1_limits,
- .post_poweron = jt8ev1_post_poweron,
- .pre_streamon = jt8ev1_pre_streamon,
- .post_streamoff = jt8ev1_post_streamoff,
- .flags = SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE,
-};
-
-static int tcm8500md_limits(struct smiapp_sensor *sensor)
-{
- smiapp_replace_limit(sensor, SMIAPP_LIMIT_MIN_PLL_IP_FREQ_HZ, 2700000);
-
- return 0;
-}
-
-const struct smiapp_quirk smiapp_tcm8500md_quirk = {
- .limits = tcm8500md_limits,
-};
diff --git a/drivers/media/video/smiapp/smiapp-quirk.h b/drivers/media/video/smiapp/smiapp-quirk.h
deleted file mode 100644
index f4dcaabaefe..00000000000
--- a/drivers/media/video/smiapp/smiapp-quirk.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * drivers/media/video/smiapp/smiapp-quirk.h
- *
- * Generic driver for SMIA/SMIA++ compliant camera modules
- *
- * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __SMIAPP_QUIRK__
-#define __SMIAPP_QUIRK__
-
-struct smiapp_sensor;
-
-/**
- * struct smiapp_quirk - quirks for sensors that deviate from SMIA++ standard
- *
- * @limits: Replace sensor->limits with values which can't be read from
- * sensor registers. Called the first time the sensor is powered up.
- * @post_poweron: Called always after the sensor has been fully powered on.
- * @pre_streamon: Called just before streaming is enabled.
- * @post_streamon: Called right after stopping streaming.
- */
-struct smiapp_quirk {
- int (*limits)(struct smiapp_sensor *sensor);
- int (*post_poweron)(struct smiapp_sensor *sensor);
- int (*pre_streamon)(struct smiapp_sensor *sensor);
- int (*post_streamoff)(struct smiapp_sensor *sensor);
- const struct smia_reg *regs;
- unsigned long flags;
-};
-
-/* op pix clock is for all lanes in total normally */
-#define SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE (1 << 0)
-#define SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY (1 << 1)
-
-struct smiapp_reg_8 {
- u16 reg;
- u8 val;
-};
-
-void smiapp_replace_limit(struct smiapp_sensor *sensor,
- u32 limit, u32 val);
-bool smiapp_quirk_reg(struct smiapp_sensor *sensor,
- u32 reg, u32 *val);
-
-#define SMIAPP_MK_QUIRK_REG(_reg, _val) \
- { \
- .type = (_reg >> 16), \
- .reg = (u16)_reg, \
- .val = _val, \
- }
-
-#define smiapp_call_quirk(_sensor, _quirk, ...) \
- (_sensor->minfo.quirk && \
- _sensor->minfo.quirk->_quirk ? \
- _sensor->minfo.quirk->_quirk(_sensor, ##__VA_ARGS__) : 0)
-
-#define smiapp_needs_quirk(_sensor, _quirk) \
- (_sensor->minfo.quirk ? \
- _sensor->minfo.quirk->flags & _quirk : 0)
-
-extern const struct smiapp_quirk smiapp_jt8ev1_quirk;
-extern const struct smiapp_quirk smiapp_imx125es_quirk;
-extern const struct smiapp_quirk smiapp_jt8ew9_quirk;
-extern const struct smiapp_quirk smiapp_tcm8500md_quirk;
-
-#endif /* __SMIAPP_QUIRK__ */
diff --git a/drivers/media/video/smiapp/smiapp-reg-defs.h b/drivers/media/video/smiapp/smiapp-reg-defs.h
deleted file mode 100644
index a089eb8161e..00000000000
--- a/drivers/media/video/smiapp/smiapp-reg-defs.h
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * drivers/media/video/smiapp/smiapp-reg-defs.h
- *
- * Generic driver for SMIA/SMIA++ compliant camera modules
- *
- * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#define SMIAPP_REG_MK_U8(r) ((SMIA_REG_8BIT << 16) | (r))
-#define SMIAPP_REG_MK_U16(r) ((SMIA_REG_16BIT << 16) | (r))
-#define SMIAPP_REG_MK_U32(r) ((SMIA_REG_32BIT << 16) | (r))
-
-#define SMIAPP_REG_MK_F32(r) (SMIA_REG_FLAG_FLOAT | (SMIA_REG_32BIT << 16) | (r))
-
-#define SMIAPP_REG_U16_MODEL_ID SMIAPP_REG_MK_U16(0x0000)
-#define SMIAPP_REG_U8_REVISION_NUMBER_MAJOR SMIAPP_REG_MK_U8(0x0002)
-#define SMIAPP_REG_U8_MANUFACTURER_ID SMIAPP_REG_MK_U8(0x0003)
-#define SMIAPP_REG_U8_SMIA_VERSION SMIAPP_REG_MK_U8(0x0004)
-#define SMIAPP_REG_U8_FRAME_COUNT SMIAPP_REG_MK_U8(0x0005)
-#define SMIAPP_REG_U8_PIXEL_ORDER SMIAPP_REG_MK_U8(0x0006)
-#define SMIAPP_REG_U16_DATA_PEDESTAL SMIAPP_REG_MK_U16(0x0008)
-#define SMIAPP_REG_U8_PIXEL_DEPTH SMIAPP_REG_MK_U8(0x000c)
-#define SMIAPP_REG_U8_REVISION_NUMBER_MINOR SMIAPP_REG_MK_U8(0x0010)
-#define SMIAPP_REG_U8_SMIAPP_VERSION SMIAPP_REG_MK_U8(0x0011)
-#define SMIAPP_REG_U8_MODULE_DATE_YEAR SMIAPP_REG_MK_U8(0x0012)
-#define SMIAPP_REG_U8_MODULE_DATE_MONTH SMIAPP_REG_MK_U8(0x0013)
-#define SMIAPP_REG_U8_MODULE_DATE_DAY SMIAPP_REG_MK_U8(0x0014)
-#define SMIAPP_REG_U8_MODULE_DATE_PHASE SMIAPP_REG_MK_U8(0x0015)
-#define SMIAPP_REG_U16_SENSOR_MODEL_ID SMIAPP_REG_MK_U16(0x0016)
-#define SMIAPP_REG_U8_SENSOR_REVISION_NUMBER SMIAPP_REG_MK_U8(0x0018)
-#define SMIAPP_REG_U8_SENSOR_MANUFACTURER_ID SMIAPP_REG_MK_U8(0x0019)
-#define SMIAPP_REG_U8_SENSOR_FIRMWARE_VERSION SMIAPP_REG_MK_U8(0x001a)
-#define SMIAPP_REG_U32_SERIAL_NUMBER SMIAPP_REG_MK_U32(0x001c)
-#define SMIAPP_REG_U8_FRAME_FORMAT_MODEL_TYPE SMIAPP_REG_MK_U8(0x0040)
-#define SMIAPP_REG_U8_FRAME_FORMAT_MODEL_SUBTYPE SMIAPP_REG_MK_U8(0x0041)
-#define SMIAPP_REG_U16_FRAME_FORMAT_DESCRIPTOR_2(n) SMIAPP_REG_MK_U16(0x0042 + ((n) << 1)) /* 0 <= n <= 14 */
-#define SMIAPP_REG_U32_FRAME_FORMAT_DESCRIPTOR_4(n) SMIAPP_REG_MK_U32(0x0060 + ((n) << 2)) /* 0 <= n <= 7 */
-#define SMIAPP_REG_U16_ANALOGUE_GAIN_CAPABILITY SMIAPP_REG_MK_U16(0x0080)
-#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_MIN SMIAPP_REG_MK_U16(0x0084)
-#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_MAX SMIAPP_REG_MK_U16(0x0086)
-#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_STEP SMIAPP_REG_MK_U16(0x0088)
-#define SMIAPP_REG_U16_ANALOGUE_GAIN_TYPE SMIAPP_REG_MK_U16(0x008a)
-#define SMIAPP_REG_U16_ANALOGUE_GAIN_M0 SMIAPP_REG_MK_U16(0x008c)
-#define SMIAPP_REG_U16_ANALOGUE_GAIN_C0 SMIAPP_REG_MK_U16(0x008e)
-#define SMIAPP_REG_U16_ANALOGUE_GAIN_M1 SMIAPP_REG_MK_U16(0x0090)
-#define SMIAPP_REG_U16_ANALOGUE_GAIN_C1 SMIAPP_REG_MK_U16(0x0092)
-#define SMIAPP_REG_U8_DATA_FORMAT_MODEL_TYPE SMIAPP_REG_MK_U8(0x00c0)
-#define SMIAPP_REG_U8_DATA_FORMAT_MODEL_SUBTYPE SMIAPP_REG_MK_U8(0x00c1)
-#define SMIAPP_REG_U16_DATA_FORMAT_DESCRIPTOR(n) SMIAPP_REG_MK_U16(0x00c2 + ((n) << 1))
-#define SMIAPP_REG_U8_MODE_SELECT SMIAPP_REG_MK_U8(0x0100)
-#define SMIAPP_REG_U8_IMAGE_ORIENTATION SMIAPP_REG_MK_U8(0x0101)
-#define SMIAPP_REG_U8_SOFTWARE_RESET SMIAPP_REG_MK_U8(0x0103)
-#define SMIAPP_REG_U8_GROUPED_PARAMETER_HOLD SMIAPP_REG_MK_U8(0x0104)
-#define SMIAPP_REG_U8_MASK_CORRUPTED_FRAMES SMIAPP_REG_MK_U8(0x0105)
-#define SMIAPP_REG_U8_FAST_STANDBY_CTRL SMIAPP_REG_MK_U8(0x0106)
-#define SMIAPP_REG_U8_CCI_ADDRESS_CONTROL SMIAPP_REG_MK_U8(0x0107)
-#define SMIAPP_REG_U8_2ND_CCI_IF_CONTROL SMIAPP_REG_MK_U8(0x0108)
-#define SMIAPP_REG_U8_2ND_CCI_ADDRESS_CONTROL SMIAPP_REG_MK_U8(0x0109)
-#define SMIAPP_REG_U8_CSI_CHANNEL_IDENTIFIER SMIAPP_REG_MK_U8(0x0110)
-#define SMIAPP_REG_U8_CSI_SIGNALLING_MODE SMIAPP_REG_MK_U8(0x0111)
-#define SMIAPP_REG_U16_CSI_DATA_FORMAT SMIAPP_REG_MK_U16(0x0112)
-#define SMIAPP_REG_U8_CSI_LANE_MODE SMIAPP_REG_MK_U8(0x0114)
-#define SMIAPP_REG_U8_CSI2_10_TO_8_DT SMIAPP_REG_MK_U8(0x0115)
-#define SMIAPP_REG_U8_CSI2_10_TO_7_DT SMIAPP_REG_MK_U8(0x0116)
-#define SMIAPP_REG_U8_CSI2_10_TO_6_DT SMIAPP_REG_MK_U8(0x0117)
-#define SMIAPP_REG_U8_CSI2_12_TO_8_DT SMIAPP_REG_MK_U8(0x0118)
-#define SMIAPP_REG_U8_CSI2_12_TO_7_DT SMIAPP_REG_MK_U8(0x0119)
-#define SMIAPP_REG_U8_CSI2_12_TO_6_DT SMIAPP_REG_MK_U8(0x011a)
-#define SMIAPP_REG_U8_CSI2_14_TO_10_DT SMIAPP_REG_MK_U8(0x011b)
-#define SMIAPP_REG_U8_CSI2_14_TO_8_DT SMIAPP_REG_MK_U8(0x011c)
-#define SMIAPP_REG_U8_CSI2_16_TO_10_DT SMIAPP_REG_MK_U8(0x011d)
-#define SMIAPP_REG_U8_CSI2_16_TO_8_DT SMIAPP_REG_MK_U8(0x011e)
-#define SMIAPP_REG_U8_GAIN_MODE SMIAPP_REG_MK_U8(0x0120)
-#define SMIAPP_REG_U16_VANA_VOLTAGE SMIAPP_REG_MK_U16(0x0130)
-#define SMIAPP_REG_U16_VDIG_VOLTAGE SMIAPP_REG_MK_U16(0x0132)
-#define SMIAPP_REG_U16_VIO_VOLTAGE SMIAPP_REG_MK_U16(0x0134)
-#define SMIAPP_REG_U16_EXTCLK_FREQUENCY_MHZ SMIAPP_REG_MK_U16(0x0136)
-#define SMIAPP_REG_U8_TEMP_SENSOR_CONTROL SMIAPP_REG_MK_U8(0x0138)
-#define SMIAPP_REG_U8_TEMP_SENSOR_MODE SMIAPP_REG_MK_U8(0x0139)
-#define SMIAPP_REG_U8_TEMP_SENSOR_OUTPUT SMIAPP_REG_MK_U8(0x013a)
-#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME SMIAPP_REG_MK_U16(0x0200)
-#define SMIAPP_REG_U16_COARSE_INTEGRATION_TIME SMIAPP_REG_MK_U16(0x0202)
-#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL SMIAPP_REG_MK_U16(0x0204)
-#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GREENR SMIAPP_REG_MK_U16(0x0206)
-#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_RED SMIAPP_REG_MK_U16(0x0208)
-#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_BLUE SMIAPP_REG_MK_U16(0x020a)
-#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GREENB SMIAPP_REG_MK_U16(0x020c)
-#define SMIAPP_REG_U16_DIGITAL_GAIN_GREENR SMIAPP_REG_MK_U16(0x020e)
-#define SMIAPP_REG_U16_DIGITAL_GAIN_RED SMIAPP_REG_MK_U16(0x0210)
-#define SMIAPP_REG_U16_DIGITAL_GAIN_BLUE SMIAPP_REG_MK_U16(0x0212)
-#define SMIAPP_REG_U16_DIGITAL_GAIN_GREENB SMIAPP_REG_MK_U16(0x0214)
-#define SMIAPP_REG_U16_VT_PIX_CLK_DIV SMIAPP_REG_MK_U16(0x0300)
-#define SMIAPP_REG_U16_VT_SYS_CLK_DIV SMIAPP_REG_MK_U16(0x0302)
-#define SMIAPP_REG_U16_PRE_PLL_CLK_DIV SMIAPP_REG_MK_U16(0x0304)
-#define SMIAPP_REG_U16_PLL_MULTIPLIER SMIAPP_REG_MK_U16(0x0306)
-#define SMIAPP_REG_U16_OP_PIX_CLK_DIV SMIAPP_REG_MK_U16(0x0308)
-#define SMIAPP_REG_U16_OP_SYS_CLK_DIV SMIAPP_REG_MK_U16(0x030a)
-#define SMIAPP_REG_U16_FRAME_LENGTH_LINES SMIAPP_REG_MK_U16(0x0340)
-#define SMIAPP_REG_U16_LINE_LENGTH_PCK SMIAPP_REG_MK_U16(0x0342)
-#define SMIAPP_REG_U16_X_ADDR_START SMIAPP_REG_MK_U16(0x0344)
-#define SMIAPP_REG_U16_Y_ADDR_START SMIAPP_REG_MK_U16(0x0346)
-#define SMIAPP_REG_U16_X_ADDR_END SMIAPP_REG_MK_U16(0x0348)
-#define SMIAPP_REG_U16_Y_ADDR_END SMIAPP_REG_MK_U16(0x034a)
-#define SMIAPP_REG_U16_X_OUTPUT_SIZE SMIAPP_REG_MK_U16(0x034c)
-#define SMIAPP_REG_U16_Y_OUTPUT_SIZE SMIAPP_REG_MK_U16(0x034e)
-#define SMIAPP_REG_U16_X_EVEN_INC SMIAPP_REG_MK_U16(0x0380)
-#define SMIAPP_REG_U16_X_ODD_INC SMIAPP_REG_MK_U16(0x0382)
-#define SMIAPP_REG_U16_Y_EVEN_INC SMIAPP_REG_MK_U16(0x0384)
-#define SMIAPP_REG_U16_Y_ODD_INC SMIAPP_REG_MK_U16(0x0386)
-#define SMIAPP_REG_U16_SCALING_MODE SMIAPP_REG_MK_U16(0x0400)
-#define SMIAPP_REG_U16_SPATIAL_SAMPLING SMIAPP_REG_MK_U16(0x0402)
-#define SMIAPP_REG_U16_SCALE_M SMIAPP_REG_MK_U16(0x0404)
-#define SMIAPP_REG_U16_SCALE_N SMIAPP_REG_MK_U16(0x0406)
-#define SMIAPP_REG_U16_DIGITAL_CROP_X_OFFSET SMIAPP_REG_MK_U16(0x0408)
-#define SMIAPP_REG_U16_DIGITAL_CROP_Y_OFFSET SMIAPP_REG_MK_U16(0x040a)
-#define SMIAPP_REG_U16_DIGITAL_CROP_IMAGE_WIDTH SMIAPP_REG_MK_U16(0x040c)
-#define SMIAPP_REG_U16_DIGITAL_CROP_IMAGE_HEIGHT SMIAPP_REG_MK_U16(0x040e)
-#define SMIAPP_REG_U16_COMPRESSION_MODE SMIAPP_REG_MK_U16(0x0500)
-#define SMIAPP_REG_U16_TEST_PATTERN_MODE SMIAPP_REG_MK_U16(0x0600)
-#define SMIAPP_REG_U16_TEST_DATA_RED SMIAPP_REG_MK_U16(0x0602)
-#define SMIAPP_REG_U16_TEST_DATA_GREENR SMIAPP_REG_MK_U16(0x0604)
-#define SMIAPP_REG_U16_TEST_DATA_BLUE SMIAPP_REG_MK_U16(0x0606)
-#define SMIAPP_REG_U16_TEST_DATA_GREENB SMIAPP_REG_MK_U16(0x0608)
-#define SMIAPP_REG_U16_HORIZONTAL_CURSOR_WIDTH SMIAPP_REG_MK_U16(0x060a)
-#define SMIAPP_REG_U16_HORIZONTAL_CURSOR_POSITION SMIAPP_REG_MK_U16(0x060c)
-#define SMIAPP_REG_U16_VERTICAL_CURSOR_WIDTH SMIAPP_REG_MK_U16(0x060e)
-#define SMIAPP_REG_U16_VERTICAL_CURSOR_POSITION SMIAPP_REG_MK_U16(0x0610)
-#define SMIAPP_REG_U16_FIFO_WATER_MARK_PIXELS SMIAPP_REG_MK_U16(0x0700)
-#define SMIAPP_REG_U8_TCLK_POST SMIAPP_REG_MK_U8(0x0800)
-#define SMIAPP_REG_U8_THS_PREPARE SMIAPP_REG_MK_U8(0x0801)
-#define SMIAPP_REG_U8_THS_ZERO_MIN SMIAPP_REG_MK_U8(0x0802)
-#define SMIAPP_REG_U8_THS_TRAIL SMIAPP_REG_MK_U8(0x0803)
-#define SMIAPP_REG_U8_TCLK_TRAIL_MIN SMIAPP_REG_MK_U8(0x0804)
-#define SMIAPP_REG_U8_TCLK_PREPARE SMIAPP_REG_MK_U8(0x0805)
-#define SMIAPP_REG_U8_TCLK_ZERO SMIAPP_REG_MK_U8(0x0806)
-#define SMIAPP_REG_U8_TLPX SMIAPP_REG_MK_U8(0x0807)
-#define SMIAPP_REG_U8_DPHY_CTRL SMIAPP_REG_MK_U8(0x0808)
-#define SMIAPP_REG_U32_REQUESTED_LINK_BIT_RATE_MBPS SMIAPP_REG_MK_U32(0x0820)
-#define SMIAPP_REG_U8_BINNING_MODE SMIAPP_REG_MK_U8(0x0900)
-#define SMIAPP_REG_U8_BINNING_TYPE SMIAPP_REG_MK_U8(0x0901)
-#define SMIAPP_REG_U8_BINNING_WEIGHTING SMIAPP_REG_MK_U8(0x0902)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_CTRL SMIAPP_REG_MK_U8(0x0a00)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_STATUS SMIAPP_REG_MK_U8(0x0a01)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_PAGE_SELECT SMIAPP_REG_MK_U8(0x0a02)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_0 SMIAPP_REG_MK_U8(0x0a04)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_1 SMIAPP_REG_MK_U8(0x0a05)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_2 SMIAPP_REG_MK_U8(0x0a06)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_3 SMIAPP_REG_MK_U8(0x0a07)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_4 SMIAPP_REG_MK_U8(0x0a08)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_5 SMIAPP_REG_MK_U8(0x0a09)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_12 SMIAPP_REG_MK_U8(0x0a10)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_13 SMIAPP_REG_MK_U8(0x0a11)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_14 SMIAPP_REG_MK_U8(0x0a12)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_15 SMIAPP_REG_MK_U8(0x0a13)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_16 SMIAPP_REG_MK_U8(0x0a14)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_17 SMIAPP_REG_MK_U8(0x0a15)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_18 SMIAPP_REG_MK_U8(0x0a16)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_19 SMIAPP_REG_MK_U8(0x0a17)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_20 SMIAPP_REG_MK_U8(0x0a18)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_21 SMIAPP_REG_MK_U8(0x0a19)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_22 SMIAPP_REG_MK_U8(0x0a1a)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_23 SMIAPP_REG_MK_U8(0x0a1b)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_24 SMIAPP_REG_MK_U8(0x0a1c)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_25 SMIAPP_REG_MK_U8(0x0a1d)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_26 SMIAPP_REG_MK_U8(0x0a1e)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_27 SMIAPP_REG_MK_U8(0x0a1f)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_28 SMIAPP_REG_MK_U8(0x0a20)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_29 SMIAPP_REG_MK_U8(0x0a21)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_30 SMIAPP_REG_MK_U8(0x0a22)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_31 SMIAPP_REG_MK_U8(0x0a23)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_32 SMIAPP_REG_MK_U8(0x0a24)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_33 SMIAPP_REG_MK_U8(0x0a25)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_34 SMIAPP_REG_MK_U8(0x0a26)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_35 SMIAPP_REG_MK_U8(0x0a27)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_36 SMIAPP_REG_MK_U8(0x0a28)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_37 SMIAPP_REG_MK_U8(0x0a29)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_38 SMIAPP_REG_MK_U8(0x0a2a)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_39 SMIAPP_REG_MK_U8(0x0a2b)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_40 SMIAPP_REG_MK_U8(0x0a2c)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_41 SMIAPP_REG_MK_U8(0x0a2d)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_42 SMIAPP_REG_MK_U8(0x0a2e)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_43 SMIAPP_REG_MK_U8(0x0a2f)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_44 SMIAPP_REG_MK_U8(0x0a30)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_45 SMIAPP_REG_MK_U8(0x0a31)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_46 SMIAPP_REG_MK_U8(0x0a32)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_47 SMIAPP_REG_MK_U8(0x0a33)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_48 SMIAPP_REG_MK_U8(0x0a34)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_49 SMIAPP_REG_MK_U8(0x0a35)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_50 SMIAPP_REG_MK_U8(0x0a36)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_51 SMIAPP_REG_MK_U8(0x0a37)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_52 SMIAPP_REG_MK_U8(0x0a38)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_53 SMIAPP_REG_MK_U8(0x0a39)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_54 SMIAPP_REG_MK_U8(0x0a3a)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_55 SMIAPP_REG_MK_U8(0x0a3b)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_56 SMIAPP_REG_MK_U8(0x0a3c)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_57 SMIAPP_REG_MK_U8(0x0a3d)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_58 SMIAPP_REG_MK_U8(0x0a3e)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_59 SMIAPP_REG_MK_U8(0x0a3f)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_60 SMIAPP_REG_MK_U8(0x0a40)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_61 SMIAPP_REG_MK_U8(0x0a41)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_62 SMIAPP_REG_MK_U8(0x0a42)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_63 SMIAPP_REG_MK_U8(0x0a43)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_CTRL SMIAPP_REG_MK_U8(0x0a44)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_STATUS SMIAPP_REG_MK_U8(0x0a45)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_PAGE_SELECT SMIAPP_REG_MK_U8(0x0a46)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_0 SMIAPP_REG_MK_U8(0x0a48)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_1 SMIAPP_REG_MK_U8(0x0a49)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_2 SMIAPP_REG_MK_U8(0x0a4a)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_3 SMIAPP_REG_MK_U8(0x0a4b)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_4 SMIAPP_REG_MK_U8(0x0a4c)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_5 SMIAPP_REG_MK_U8(0x0a4d)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_6 SMIAPP_REG_MK_U8(0x0a4e)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_7 SMIAPP_REG_MK_U8(0x0a4f)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_8 SMIAPP_REG_MK_U8(0x0a50)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_9 SMIAPP_REG_MK_U8(0x0a51)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_10 SMIAPP_REG_MK_U8(0x0a52)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_11 SMIAPP_REG_MK_U8(0x0a53)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_12 SMIAPP_REG_MK_U8(0x0a54)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_13 SMIAPP_REG_MK_U8(0x0a55)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_14 SMIAPP_REG_MK_U8(0x0a56)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_15 SMIAPP_REG_MK_U8(0x0a57)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_16 SMIAPP_REG_MK_U8(0x0a58)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_17 SMIAPP_REG_MK_U8(0x0a59)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_18 SMIAPP_REG_MK_U8(0x0a5a)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_19 SMIAPP_REG_MK_U8(0x0a5b)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_20 SMIAPP_REG_MK_U8(0x0a5c)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_21 SMIAPP_REG_MK_U8(0x0a5d)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_22 SMIAPP_REG_MK_U8(0x0a5e)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_23 SMIAPP_REG_MK_U8(0x0a5f)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_24 SMIAPP_REG_MK_U8(0x0a60)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_25 SMIAPP_REG_MK_U8(0x0a61)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_26 SMIAPP_REG_MK_U8(0x0a62)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_27 SMIAPP_REG_MK_U8(0x0a63)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_28 SMIAPP_REG_MK_U8(0x0a64)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_29 SMIAPP_REG_MK_U8(0x0a65)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_30 SMIAPP_REG_MK_U8(0x0a66)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_31 SMIAPP_REG_MK_U8(0x0a67)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_32 SMIAPP_REG_MK_U8(0x0a68)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_33 SMIAPP_REG_MK_U8(0x0a69)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_34 SMIAPP_REG_MK_U8(0x0a6a)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_35 SMIAPP_REG_MK_U8(0x0a6b)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_36 SMIAPP_REG_MK_U8(0x0a6c)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_37 SMIAPP_REG_MK_U8(0x0a6d)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_38 SMIAPP_REG_MK_U8(0x0a6e)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_39 SMIAPP_REG_MK_U8(0x0a6f)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_40 SMIAPP_REG_MK_U8(0x0a70)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_41 SMIAPP_REG_MK_U8(0x0a71)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_42 SMIAPP_REG_MK_U8(0x0a72)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_43 SMIAPP_REG_MK_U8(0x0a73)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_44 SMIAPP_REG_MK_U8(0x0a74)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_45 SMIAPP_REG_MK_U8(0x0a75)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_46 SMIAPP_REG_MK_U8(0x0a76)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_47 SMIAPP_REG_MK_U8(0x0a77)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_48 SMIAPP_REG_MK_U8(0x0a78)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_49 SMIAPP_REG_MK_U8(0x0a79)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_50 SMIAPP_REG_MK_U8(0x0a7a)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_51 SMIAPP_REG_MK_U8(0x0a7b)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_52 SMIAPP_REG_MK_U8(0x0a7c)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_53 SMIAPP_REG_MK_U8(0x0a7d)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_54 SMIAPP_REG_MK_U8(0x0a7e)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_55 SMIAPP_REG_MK_U8(0x0a7f)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_56 SMIAPP_REG_MK_U8(0x0a80)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_57 SMIAPP_REG_MK_U8(0x0a81)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_58 SMIAPP_REG_MK_U8(0x0a82)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_59 SMIAPP_REG_MK_U8(0x0a83)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_60 SMIAPP_REG_MK_U8(0x0a84)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_61 SMIAPP_REG_MK_U8(0x0a85)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_62 SMIAPP_REG_MK_U8(0x0a86)
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_63 SMIAPP_REG_MK_U8(0x0a87)
-#define SMIAPP_REG_U8_SHADING_CORRECTION_ENABLE SMIAPP_REG_MK_U8(0x0b00)
-#define SMIAPP_REG_U8_LUMINANCE_CORRECTION_LEVEL SMIAPP_REG_MK_U8(0x0b01)
-#define SMIAPP_REG_U8_GREEN_IMBALANCE_FILTER_ENABLE SMIAPP_REG_MK_U8(0x0b02)
-#define SMIAPP_REG_U8_GREEN_IMBALANCE_FILTER_WEIGHT SMIAPP_REG_MK_U8(0x0b03)
-#define SMIAPP_REG_U8_BLACK_LEVEL_CORRECTION_ENABLE SMIAPP_REG_MK_U8(0x0b04)
-#define SMIAPP_REG_U8_MAPPED_COUPLET_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b05)
-#define SMIAPP_REG_U8_SINGLE_DEFECT_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b06)
-#define SMIAPP_REG_U8_SINGLE_DEFECT_CORRECT_WEIGHT SMIAPP_REG_MK_U8(0x0b07)
-#define SMIAPP_REG_U8_DYNAMIC_COUPLET_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b08)
-#define SMIAPP_REG_U8_DYNAMIC_COUPLET_CORRECT_WEIGHT SMIAPP_REG_MK_U8(0x0b09)
-#define SMIAPP_REG_U8_COMBINED_DEFECT_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b0a)
-#define SMIAPP_REG_U8_COMBINED_DEFECT_CORRECT_WEIGHT SMIAPP_REG_MK_U8(0x0b0b)
-#define SMIAPP_REG_U8_MODULE_SPECIFIC_CORRECTION_ENABLE SMIAPP_REG_MK_U8(0x0b0c)
-#define SMIAPP_REG_U8_MODULE_SPECIFIC_CORRECTION_WEIGHT SMIAPP_REG_MK_U8(0x0b0d)
-#define SMIAPP_REG_U8_MAPPED_LINE_DEFECT_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b0e)
-#define SMIAPP_REG_U8_MAPPED_LINE_DEFECT_CORRECT_ADJUST SMIAPP_REG_MK_U8(0x0b0f)
-#define SMIAPP_REG_U8_MAPPED_COUPLET_CORRECT_ADJUST SMIAPP_REG_MK_U8(0x0b10)
-#define SMIAPP_REG_U8_MAPPED_TRIPLET_DEFECT_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b11)
-#define SMIAPP_REG_U8_MAPPED_TRIPLET_DEFECT_CORRECT_ADJUST SMIAPP_REG_MK_U8(0x0b12)
-#define SMIAPP_REG_U8_DYNAMIC_TRIPLET_DEFECT_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b13)
-#define SMIAPP_REG_U8_DYNAMIC_TRIPLET_DEFECT_CORRECT_ADJUST SMIAPP_REG_MK_U8(0x0b14)
-#define SMIAPP_REG_U8_DYNAMIC_LINE_DEFECT_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b15)
-#define SMIAPP_REG_U8_DYNAMIC_LINE_DEFECT_CORRECT_ADJUST SMIAPP_REG_MK_U8(0x0b16)
-#define SMIAPP_REG_U8_EDOF_MODE SMIAPP_REG_MK_U8(0x0b80)
-#define SMIAPP_REG_U8_SHARPNESS SMIAPP_REG_MK_U8(0x0b83)
-#define SMIAPP_REG_U8_DENOISING SMIAPP_REG_MK_U8(0x0b84)
-#define SMIAPP_REG_U8_MODULE_SPECIFIC SMIAPP_REG_MK_U8(0x0b85)
-#define SMIAPP_REG_U16_DEPTH_OF_FIELD SMIAPP_REG_MK_U16(0x0b86)
-#define SMIAPP_REG_U16_FOCUS_DISTANCE SMIAPP_REG_MK_U16(0x0b88)
-#define SMIAPP_REG_U8_ESTIMATION_MODE_CTRL SMIAPP_REG_MK_U8(0x0b8a)
-#define SMIAPP_REG_U16_COLOUR_TEMPERATURE SMIAPP_REG_MK_U16(0x0b8c)
-#define SMIAPP_REG_U16_ABSOLUTE_GAIN_GREENR SMIAPP_REG_MK_U16(0x0b8e)
-#define SMIAPP_REG_U16_ABSOLUTE_GAIN_RED SMIAPP_REG_MK_U16(0x0b90)
-#define SMIAPP_REG_U16_ABSOLUTE_GAIN_BLUE SMIAPP_REG_MK_U16(0x0b92)
-#define SMIAPP_REG_U16_ABSOLUTE_GAIN_GREENB SMIAPP_REG_MK_U16(0x0b94)
-#define SMIAPP_REG_U8_ESTIMATION_ZONE_MODE SMIAPP_REG_MK_U8(0x0bc0)
-#define SMIAPP_REG_U16_FIXED_ZONE_WEIGHTING SMIAPP_REG_MK_U16(0x0bc2)
-#define SMIAPP_REG_U16_CUSTOM_ZONE_X_START SMIAPP_REG_MK_U16(0x0bc4)
-#define SMIAPP_REG_U16_CUSTOM_ZONE_Y_START SMIAPP_REG_MK_U16(0x0bc6)
-#define SMIAPP_REG_U16_CUSTOM_ZONE_WIDTH SMIAPP_REG_MK_U16(0x0bc8)
-#define SMIAPP_REG_U16_CUSTOM_ZONE_HEIGHT SMIAPP_REG_MK_U16(0x0bca)
-#define SMIAPP_REG_U8_GLOBAL_RESET_CTRL1 SMIAPP_REG_MK_U8(0x0c00)
-#define SMIAPP_REG_U8_GLOBAL_RESET_CTRL2 SMIAPP_REG_MK_U8(0x0c01)
-#define SMIAPP_REG_U8_GLOBAL_RESET_MODE_CONFIG_1 SMIAPP_REG_MK_U8(0x0c02)
-#define SMIAPP_REG_U8_GLOBAL_RESET_MODE_CONFIG_2 SMIAPP_REG_MK_U8(0x0c03)
-#define SMIAPP_REG_U16_TRDY_CTRL SMIAPP_REG_MK_U16(0x0c04)
-#define SMIAPP_REG_U16_TRDOUT_CTRL SMIAPP_REG_MK_U16(0x0c06)
-#define SMIAPP_REG_U16_TSHUTTER_STROBE_DELAY_CTRL SMIAPP_REG_MK_U16(0x0c08)
-#define SMIAPP_REG_U16_TSHUTTER_STROBE_WIDTH_CTRL SMIAPP_REG_MK_U16(0x0c0a)
-#define SMIAPP_REG_U16_TFLASH_STROBE_DELAY_CTRL SMIAPP_REG_MK_U16(0x0c0c)
-#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_HIGH_CTRL SMIAPP_REG_MK_U16(0x0c0e)
-#define SMIAPP_REG_U16_TGRST_INTERVAL_CTRL SMIAPP_REG_MK_U16(0x0c10)
-#define SMIAPP_REG_U8_FLASH_STROBE_ADJUSTMENT SMIAPP_REG_MK_U8(0x0c12)
-#define SMIAPP_REG_U16_FLASH_STROBE_START_POINT SMIAPP_REG_MK_U16(0x0c14)
-#define SMIAPP_REG_U16_TFLASH_STROBE_DELAY_RS_CTRL SMIAPP_REG_MK_U16(0x0c16)
-#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_HIGH_RS_CTRL SMIAPP_REG_MK_U16(0x0c18)
-#define SMIAPP_REG_U8_FLASH_MODE_RS SMIAPP_REG_MK_U8(0x0c1a)
-#define SMIAPP_REG_U8_FLASH_TRIGGER_RS SMIAPP_REG_MK_U8(0x0c1b)
-#define SMIAPP_REG_U8_FLASH_STATUS SMIAPP_REG_MK_U8(0x0c1c)
-#define SMIAPP_REG_U8_SA_STROBE_MODE SMIAPP_REG_MK_U8(0x0c1d)
-#define SMIAPP_REG_U16_SA_STROBE_START_POINT SMIAPP_REG_MK_U16(0x0c1e)
-#define SMIAPP_REG_U16_TSA_STROBE_DELAY_CTRL SMIAPP_REG_MK_U16(0x0c20)
-#define SMIAPP_REG_U16_TSA_STROBE_WIDTH_CTRL SMIAPP_REG_MK_U16(0x0c22)
-#define SMIAPP_REG_U8_SA_STROBE_TRIGGER SMIAPP_REG_MK_U8(0x0c24)
-#define SMIAPP_REG_U8_SPECIAL_ACTUATOR_STATUS SMIAPP_REG_MK_U8(0x0c25)
-#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH2_HIGH_RS_CTRL SMIAPP_REG_MK_U16(0x0c26)
-#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_LOW_RS_CTRL SMIAPP_REG_MK_U16(0x0c28)
-#define SMIAPP_REG_U8_TFLASH_STROBE_COUNT_RS_CTRL SMIAPP_REG_MK_U8(0x0c2a)
-#define SMIAPP_REG_U8_TFLASH_STROBE_COUNT_CTRL SMIAPP_REG_MK_U8(0x0c2b)
-#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH2_HIGH_CTRL SMIAPP_REG_MK_U16(0x0c2c)
-#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_LOW_CTRL SMIAPP_REG_MK_U16(0x0c2e)
-#define SMIAPP_REG_U8_LOW_LEVEL_CTRL SMIAPP_REG_MK_U8(0x0c80)
-#define SMIAPP_REG_U16_MAIN_TRIGGER_REF_POINT SMIAPP_REG_MK_U16(0x0c82)
-#define SMIAPP_REG_U16_MAIN_TRIGGER_T3 SMIAPP_REG_MK_U16(0x0c84)
-#define SMIAPP_REG_U8_MAIN_TRIGGER_COUNT SMIAPP_REG_MK_U8(0x0c86)
-#define SMIAPP_REG_U16_PHASE1_TRIGGER_T3 SMIAPP_REG_MK_U16(0x0c88)
-#define SMIAPP_REG_U8_PHASE1_TRIGGER_COUNT SMIAPP_REG_MK_U8(0x0c8a)
-#define SMIAPP_REG_U16_PHASE2_TRIGGER_T3 SMIAPP_REG_MK_U16(0x0c8c)
-#define SMIAPP_REG_U8_PHASE2_TRIGGER_COUNT SMIAPP_REG_MK_U8(0x0c8e)
-#define SMIAPP_REG_U8_MECH_SHUTTER_CTRL SMIAPP_REG_MK_U8(0x0d00)
-#define SMIAPP_REG_U8_OPERATION_MODE SMIAPP_REG_MK_U8(0x0d01)
-#define SMIAPP_REG_U8_ACT_STATE1 SMIAPP_REG_MK_U8(0x0d02)
-#define SMIAPP_REG_U8_ACT_STATE2 SMIAPP_REG_MK_U8(0x0d03)
-#define SMIAPP_REG_U16_FOCUS_CHANGE SMIAPP_REG_MK_U16(0x0d80)
-#define SMIAPP_REG_U16_FOCUS_CHANGE_CONTROL SMIAPP_REG_MK_U16(0x0d82)
-#define SMIAPP_REG_U16_FOCUS_CHANGE_NUMBER_PHASE1 SMIAPP_REG_MK_U16(0x0d84)
-#define SMIAPP_REG_U16_FOCUS_CHANGE_NUMBER_PHASE2 SMIAPP_REG_MK_U16(0x0d86)
-#define SMIAPP_REG_U8_STROBE_COUNT_PHASE1 SMIAPP_REG_MK_U8(0x0d88)
-#define SMIAPP_REG_U8_STROBE_COUNT_PHASE2 SMIAPP_REG_MK_U8(0x0d89)
-#define SMIAPP_REG_U8_POSITION SMIAPP_REG_MK_U8(0x0d8a)
-#define SMIAPP_REG_U8_BRACKETING_LUT_CONTROL SMIAPP_REG_MK_U8(0x0e00)
-#define SMIAPP_REG_U8_BRACKETING_LUT_MODE SMIAPP_REG_MK_U8(0x0e01)
-#define SMIAPP_REG_U8_BRACKETING_LUT_ENTRY_CONTROL SMIAPP_REG_MK_U8(0x0e02)
-#define SMIAPP_REG_U8_LUT_PARAMETERS_START SMIAPP_REG_MK_U8(0x0e10)
-#define SMIAPP_REG_U8_LUT_PARAMETERS_END SMIAPP_REG_MK_U8(0x0eff)
-#define SMIAPP_REG_U16_INTEGRATION_TIME_CAPABILITY SMIAPP_REG_MK_U16(0x1000)
-#define SMIAPP_REG_U16_COARSE_INTEGRATION_TIME_MIN SMIAPP_REG_MK_U16(0x1004)
-#define SMIAPP_REG_U16_COARSE_INTEGRATION_TIME_MAX_MARGIN SMIAPP_REG_MK_U16(0x1006)
-#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MIN SMIAPP_REG_MK_U16(0x1008)
-#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MAX_MARGIN SMIAPP_REG_MK_U16(0x100a)
-#define SMIAPP_REG_U16_DIGITAL_GAIN_CAPABILITY SMIAPP_REG_MK_U16(0x1080)
-#define SMIAPP_REG_U16_DIGITAL_GAIN_MIN SMIAPP_REG_MK_U16(0x1084)
-#define SMIAPP_REG_U16_DIGITAL_GAIN_MAX SMIAPP_REG_MK_U16(0x1086)
-#define SMIAPP_REG_U16_DIGITAL_GAIN_STEP_SIZE SMIAPP_REG_MK_U16(0x1088)
-#define SMIAPP_REG_F32_MIN_EXT_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1100)
-#define SMIAPP_REG_F32_MAX_EXT_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1104)
-#define SMIAPP_REG_U16_MIN_PRE_PLL_CLK_DIV SMIAPP_REG_MK_U16(0x1108)
-#define SMIAPP_REG_U16_MAX_PRE_PLL_CLK_DIV SMIAPP_REG_MK_U16(0x110a)
-#define SMIAPP_REG_F32_MIN_PLL_IP_FREQ_HZ SMIAPP_REG_MK_F32(0x110c)
-#define SMIAPP_REG_F32_MAX_PLL_IP_FREQ_HZ SMIAPP_REG_MK_F32(0x1110)
-#define SMIAPP_REG_U16_MIN_PLL_MULTIPLIER SMIAPP_REG_MK_U16(0x1114)
-#define SMIAPP_REG_U16_MAX_PLL_MULTIPLIER SMIAPP_REG_MK_U16(0x1116)
-#define SMIAPP_REG_F32_MIN_PLL_OP_FREQ_HZ SMIAPP_REG_MK_F32(0x1118)
-#define SMIAPP_REG_F32_MAX_PLL_OP_FREQ_HZ SMIAPP_REG_MK_F32(0x111c)
-#define SMIAPP_REG_U16_MIN_VT_SYS_CLK_DIV SMIAPP_REG_MK_U16(0x1120)
-#define SMIAPP_REG_U16_MAX_VT_SYS_CLK_DIV SMIAPP_REG_MK_U16(0x1122)
-#define SMIAPP_REG_F32_MIN_VT_SYS_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1124)
-#define SMIAPP_REG_F32_MAX_VT_SYS_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1128)
-#define SMIAPP_REG_F32_MIN_VT_PIX_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x112c)
-#define SMIAPP_REG_F32_MAX_VT_PIX_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1130)
-#define SMIAPP_REG_U16_MIN_VT_PIX_CLK_DIV SMIAPP_REG_MK_U16(0x1134)
-#define SMIAPP_REG_U16_MAX_VT_PIX_CLK_DIV SMIAPP_REG_MK_U16(0x1136)
-#define SMIAPP_REG_U16_MIN_FRAME_LENGTH_LINES SMIAPP_REG_MK_U16(0x1140)
-#define SMIAPP_REG_U16_MAX_FRAME_LENGTH_LINES SMIAPP_REG_MK_U16(0x1142)
-#define SMIAPP_REG_U16_MIN_LINE_LENGTH_PCK SMIAPP_REG_MK_U16(0x1144)
-#define SMIAPP_REG_U16_MAX_LINE_LENGTH_PCK SMIAPP_REG_MK_U16(0x1146)
-#define SMIAPP_REG_U16_MIN_LINE_BLANKING_PCK SMIAPP_REG_MK_U16(0x1148)
-#define SMIAPP_REG_U16_MIN_FRAME_BLANKING_LINES SMIAPP_REG_MK_U16(0x114a)
-#define SMIAPP_REG_U8_MIN_LINE_LENGTH_PCK_STEP_SIZE SMIAPP_REG_MK_U8(0x114c)
-#define SMIAPP_REG_U16_MIN_OP_SYS_CLK_DIV SMIAPP_REG_MK_U16(0x1160)
-#define SMIAPP_REG_U16_MAX_OP_SYS_CLK_DIV SMIAPP_REG_MK_U16(0x1162)
-#define SMIAPP_REG_F32_MIN_OP_SYS_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1164)
-#define SMIAPP_REG_F32_MAX_OP_SYS_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1168)
-#define SMIAPP_REG_U16_MIN_OP_PIX_CLK_DIV SMIAPP_REG_MK_U16(0x116c)
-#define SMIAPP_REG_U16_MAX_OP_PIX_CLK_DIV SMIAPP_REG_MK_U16(0x116e)
-#define SMIAPP_REG_F32_MIN_OP_PIX_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1170)
-#define SMIAPP_REG_F32_MAX_OP_PIX_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1174)
-#define SMIAPP_REG_U16_X_ADDR_MIN SMIAPP_REG_MK_U16(0x1180)
-#define SMIAPP_REG_U16_Y_ADDR_MIN SMIAPP_REG_MK_U16(0x1182)
-#define SMIAPP_REG_U16_X_ADDR_MAX SMIAPP_REG_MK_U16(0x1184)
-#define SMIAPP_REG_U16_Y_ADDR_MAX SMIAPP_REG_MK_U16(0x1186)
-#define SMIAPP_REG_U16_MIN_X_OUTPUT_SIZE SMIAPP_REG_MK_U16(0x1188)
-#define SMIAPP_REG_U16_MIN_Y_OUTPUT_SIZE SMIAPP_REG_MK_U16(0x118a)
-#define SMIAPP_REG_U16_MAX_X_OUTPUT_SIZE SMIAPP_REG_MK_U16(0x118c)
-#define SMIAPP_REG_U16_MAX_Y_OUTPUT_SIZE SMIAPP_REG_MK_U16(0x118e)
-#define SMIAPP_REG_U16_MIN_EVEN_INC SMIAPP_REG_MK_U16(0x11c0)
-#define SMIAPP_REG_U16_MAX_EVEN_INC SMIAPP_REG_MK_U16(0x11c2)
-#define SMIAPP_REG_U16_MIN_ODD_INC SMIAPP_REG_MK_U16(0x11c4)
-#define SMIAPP_REG_U16_MAX_ODD_INC SMIAPP_REG_MK_U16(0x11c6)
-#define SMIAPP_REG_U16_SCALING_CAPABILITY SMIAPP_REG_MK_U16(0x1200)
-#define SMIAPP_REG_U16_SCALER_M_MIN SMIAPP_REG_MK_U16(0x1204)
-#define SMIAPP_REG_U16_SCALER_M_MAX SMIAPP_REG_MK_U16(0x1206)
-#define SMIAPP_REG_U16_SCALER_N_MIN SMIAPP_REG_MK_U16(0x1208)
-#define SMIAPP_REG_U16_SCALER_N_MAX SMIAPP_REG_MK_U16(0x120a)
-#define SMIAPP_REG_U16_SPATIAL_SAMPLING_CAPABILITY SMIAPP_REG_MK_U16(0x120c)
-#define SMIAPP_REG_U8_DIGITAL_CROP_CAPABILITY SMIAPP_REG_MK_U8(0x120e)
-#define SMIAPP_REG_U16_COMPRESSION_CAPABILITY SMIAPP_REG_MK_U16(0x1300)
-#define SMIAPP_REG_U16_MATRIX_ELEMENT_REDINRED SMIAPP_REG_MK_U16(0x1400)
-#define SMIAPP_REG_U16_MATRIX_ELEMENT_GREENINRED SMIAPP_REG_MK_U16(0x1402)
-#define SMIAPP_REG_U16_MATRIX_ELEMENT_BLUEINRED SMIAPP_REG_MK_U16(0x1404)
-#define SMIAPP_REG_U16_MATRIX_ELEMENT_REDINGREEN SMIAPP_REG_MK_U16(0x1406)
-#define SMIAPP_REG_U16_MATRIX_ELEMENT_GREENINGREEN SMIAPP_REG_MK_U16(0x1408)
-#define SMIAPP_REG_U16_MATRIX_ELEMENT_BLUEINGREEN SMIAPP_REG_MK_U16(0x140a)
-#define SMIAPP_REG_U16_MATRIX_ELEMENT_REDINBLUE SMIAPP_REG_MK_U16(0x140c)
-#define SMIAPP_REG_U16_MATRIX_ELEMENT_GREENINBLUE SMIAPP_REG_MK_U16(0x140e)
-#define SMIAPP_REG_U16_MATRIX_ELEMENT_BLUEINBLUE SMIAPP_REG_MK_U16(0x1410)
-#define SMIAPP_REG_U16_FIFO_SIZE_PIXELS SMIAPP_REG_MK_U16(0x1500)
-#define SMIAPP_REG_U8_FIFO_SUPPORT_CAPABILITY SMIAPP_REG_MK_U8(0x1502)
-#define SMIAPP_REG_U8_DPHY_CTRL_CAPABILITY SMIAPP_REG_MK_U8(0x1600)
-#define SMIAPP_REG_U8_CSI_LANE_MODE_CAPABILITY SMIAPP_REG_MK_U8(0x1601)
-#define SMIAPP_REG_U8_CSI_SIGNALLING_MODE_CAPABILITY SMIAPP_REG_MK_U8(0x1602)
-#define SMIAPP_REG_U8_FAST_STANDBY_CAPABILITY SMIAPP_REG_MK_U8(0x1603)
-#define SMIAPP_REG_U8_CCI_ADDRESS_CONTROL_CAPABILITY SMIAPP_REG_MK_U8(0x1604)
-#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_1_LANE_MODE_MBPS SMIAPP_REG_MK_U32(0x1608)
-#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_2_LANE_MODE_MBPS SMIAPP_REG_MK_U32(0x160c)
-#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_3_LANE_MODE_MBPS SMIAPP_REG_MK_U32(0x1610)
-#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_4_LANE_MODE_MBPS SMIAPP_REG_MK_U32(0x1614)
-#define SMIAPP_REG_U8_TEMP_SENSOR_CAPABILITY SMIAPP_REG_MK_U8(0x1618)
-#define SMIAPP_REG_U16_MIN_FRAME_LENGTH_LINES_BIN SMIAPP_REG_MK_U16(0x1700)
-#define SMIAPP_REG_U16_MAX_FRAME_LENGTH_LINES_BIN SMIAPP_REG_MK_U16(0x1702)
-#define SMIAPP_REG_U16_MIN_LINE_LENGTH_PCK_BIN SMIAPP_REG_MK_U16(0x1704)
-#define SMIAPP_REG_U16_MAX_LINE_LENGTH_PCK_BIN SMIAPP_REG_MK_U16(0x1706)
-#define SMIAPP_REG_U16_MIN_LINE_BLANKING_PCK_BIN SMIAPP_REG_MK_U16(0x1708)
-#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MIN_BIN SMIAPP_REG_MK_U16(0x170a)
-#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MAX_MARGIN_BIN SMIAPP_REG_MK_U16(0x170c)
-#define SMIAPP_REG_U8_BINNING_CAPABILITY SMIAPP_REG_MK_U8(0x1710)
-#define SMIAPP_REG_U8_BINNING_WEIGHTING_CAPABILITY SMIAPP_REG_MK_U8(0x1711)
-#define SMIAPP_REG_U8_BINNING_SUBTYPES SMIAPP_REG_MK_U8(0x1712)
-#define SMIAPP_REG_U8_BINNING_TYPE_n(n) SMIAPP_REG_MK_U8(0x1713 + (n)) /* 1 <= n <= 237 */
-#define SMIAPP_REG_U8_DATA_TRANSFER_IF_CAPABILITY SMIAPP_REG_MK_U8(0x1800)
-#define SMIAPP_REG_U8_SHADING_CORRECTION_CAPABILITY SMIAPP_REG_MK_U8(0x1900)
-#define SMIAPP_REG_U8_GREEN_IMBALANCE_CAPABILITY SMIAPP_REG_MK_U8(0x1901)
-#define SMIAPP_REG_U8_BLACK_LEVEL_CAPABILITY SMIAPP_REG_MK_U8(0x1902)
-#define SMIAPP_REG_U8_MODULE_SPECIFIC_CORRECTION_CAPABILITY SMIAPP_REG_MK_U8(0x1903)
-#define SMIAPP_REG_U16_DEFECT_CORRECTION_CAPABILITY SMIAPP_REG_MK_U16(0x1904)
-#define SMIAPP_REG_U16_DEFECT_CORRECTION_CAPABILITY_2 SMIAPP_REG_MK_U16(0x1906)
-#define SMIAPP_REG_U8_EDOF_CAPABILITY SMIAPP_REG_MK_U8(0x1980)
-#define SMIAPP_REG_U8_ESTIMATION_FRAMES SMIAPP_REG_MK_U8(0x1981)
-#define SMIAPP_REG_U8_SUPPORTS_SHARPNESS_ADJ SMIAPP_REG_MK_U8(0x1982)
-#define SMIAPP_REG_U8_SUPPORTS_DENOISING_ADJ SMIAPP_REG_MK_U8(0x1983)
-#define SMIAPP_REG_U8_SUPPORTS_MODULE_SPECIFIC_ADJ SMIAPP_REG_MK_U8(0x1984)
-#define SMIAPP_REG_U8_SUPPORTS_DEPTH_OF_FIELD_ADJ SMIAPP_REG_MK_U8(0x1985)
-#define SMIAPP_REG_U8_SUPPORTS_FOCUS_DISTANCE_ADJ SMIAPP_REG_MK_U8(0x1986)
-#define SMIAPP_REG_U8_COLOUR_FEEDBACK_CAPABILITY SMIAPP_REG_MK_U8(0x1987)
-#define SMIAPP_REG_U8_EDOF_SUPPORT_AB_NXM SMIAPP_REG_MK_U8(0x1988)
-#define SMIAPP_REG_U8_ESTIMATION_MODE_CAPABILITY SMIAPP_REG_MK_U8(0x19c0)
-#define SMIAPP_REG_U8_ESTIMATION_ZONE_CAPABILITY SMIAPP_REG_MK_U8(0x19c1)
-#define SMIAPP_REG_U16_EST_DEPTH_OF_FIELD SMIAPP_REG_MK_U16(0x19c2)
-#define SMIAPP_REG_U16_EST_FOCUS_DISTANCE SMIAPP_REG_MK_U16(0x19c4)
-#define SMIAPP_REG_U16_CAPABILITY_TRDY_MIN SMIAPP_REG_MK_U16(0x1a00)
-#define SMIAPP_REG_U8_FLASH_MODE_CAPABILITY SMIAPP_REG_MK_U8(0x1a02)
-#define SMIAPP_REG_U16_MECH_SHUT_AND_ACT_START_ADDR SMIAPP_REG_MK_U16(0x1b02)
-#define SMIAPP_REG_U8_ACTUATOR_CAPABILITY SMIAPP_REG_MK_U8(0x1b04)
-#define SMIAPP_REG_U16_ACTUATOR_TYPE SMIAPP_REG_MK_U16(0x1b40)
-#define SMIAPP_REG_U8_AF_DEVICE_ADDRESS SMIAPP_REG_MK_U8(0x1b42)
-#define SMIAPP_REG_U16_FOCUS_CHANGE_ADDRESS SMIAPP_REG_MK_U16(0x1b44)
-#define SMIAPP_REG_U8_BRACKETING_LUT_CAPABILITY_1 SMIAPP_REG_MK_U8(0x1c00)
-#define SMIAPP_REG_U8_BRACKETING_LUT_CAPABILITY_2 SMIAPP_REG_MK_U8(0x1c01)
-#define SMIAPP_REG_U8_BRACKETING_LUT_SIZE SMIAPP_REG_MK_U8(0x1c02)
diff --git a/drivers/media/video/smiapp/smiapp-reg.h b/drivers/media/video/smiapp/smiapp-reg.h
deleted file mode 100644
index d0167aa1753..00000000000
--- a/drivers/media/video/smiapp/smiapp-reg.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * drivers/media/video/smiapp/smiapp-reg.h
- *
- * Generic driver for SMIA/SMIA++ compliant camera modules
- *
- * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __SMIAPP_REG_H_
-#define __SMIAPP_REG_H_
-
-#include "smiapp-reg-defs.h"
-
-/* Bits for above register */
-#define SMIAPP_IMAGE_ORIENTATION_HFLIP (1 << 0)
-#define SMIAPP_IMAGE_ORIENTATION_VFLIP (1 << 1)
-
-#define SMIAPP_DATA_TRANSFER_IF_1_CTRL_EN (1 << 0)
-#define SMIAPP_DATA_TRANSFER_IF_1_CTRL_RD_EN (0 << 1)
-#define SMIAPP_DATA_TRANSFER_IF_1_CTRL_WR_EN (1 << 1)
-#define SMIAPP_DATA_TRANSFER_IF_1_CTRL_ERR_CLEAR (1 << 2)
-#define SMIAPP_DATA_TRANSFER_IF_1_STATUS_RD_READY (1 << 0)
-#define SMIAPP_DATA_TRANSFER_IF_1_STATUS_WR_READY (1 << 1)
-#define SMIAPP_DATA_TRANSFER_IF_1_STATUS_EDATA (1 << 2)
-#define SMIAPP_DATA_TRANSFER_IF_1_STATUS_EUSAGE (1 << 3)
-
-#define SMIAPP_SOFTWARE_RESET (1 << 0)
-
-#define SMIAPP_FLASH_MODE_CAPABILITY_SINGLE_STROBE (1 << 0)
-#define SMIAPP_FLASH_MODE_CAPABILITY_MULTIPLE_STROBE (1 << 1)
-
-#define SMIAPP_DPHY_CTRL_AUTOMATIC 0
-/* DPHY control based on REQUESTED_LINK_BIT_RATE_MBPS */
-#define SMIAPP_DPHY_CTRL_UI 1
-#define SMIAPP_DPHY_CTRL_REGISTER 2
-
-#define SMIAPP_COMPRESSION_MODE_SIMPLE_PREDICTOR 1
-#define SMIAPP_COMPRESSION_MODE_ADVANCED_PREDICTOR 2
-
-#define SMIAPP_MODE_SELECT_SOFTWARE_STANDBY 0
-#define SMIAPP_MODE_SELECT_STREAMING 1
-
-#define SMIAPP_SCALING_MODE_NONE 0
-#define SMIAPP_SCALING_MODE_HORIZONTAL 1
-#define SMIAPP_SCALING_MODE_BOTH 2
-
-#define SMIAPP_SCALING_CAPABILITY_NONE 0
-#define SMIAPP_SCALING_CAPABILITY_HORIZONTAL 1
-#define SMIAPP_SCALING_CAPABILITY_BOTH 2 /* horizontal/both */
-
-/* digital crop right before scaler */
-#define SMIAPP_DIGITAL_CROP_CAPABILITY_NONE 0
-#define SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP 1
-
-#define SMIAPP_BINNING_CAPABILITY_NO 0
-#define SMIAPP_BINNING_CAPABILITY_YES 1
-
-/* Maximum number of binning subtypes */
-#define SMIAPP_BINNING_SUBTYPES 253
-
-#define SMIAPP_PIXEL_ORDER_GRBG 0
-#define SMIAPP_PIXEL_ORDER_RGGB 1
-#define SMIAPP_PIXEL_ORDER_BGGR 2
-#define SMIAPP_PIXEL_ORDER_GBRG 3
-
-#define SMIAPP_DATA_FORMAT_MODEL_TYPE_NORMAL 1
-#define SMIAPP_DATA_FORMAT_MODEL_TYPE_EXTENDED 2
-#define SMIAPP_DATA_FORMAT_MODEL_TYPE_NORMAL_N 8
-#define SMIAPP_DATA_FORMAT_MODEL_TYPE_EXTENDED_N 16
-
-#define SMIAPP_FRAME_FORMAT_MODEL_TYPE_2BYTE 0x01
-#define SMIAPP_FRAME_FORMAT_MODEL_TYPE_4BYTE 0x02
-#define SMIAPP_FRAME_FORMAT_MODEL_SUBTYPE_NROWS_MASK 0x0f
-#define SMIAPP_FRAME_FORMAT_MODEL_SUBTYPE_NCOLS_MASK 0xf0
-#define SMIAPP_FRAME_FORMAT_MODEL_SUBTYPE_NCOLS_SHIFT 4
-
-#define SMIAPP_FRAME_FORMAT_DESC_2_PIXELCODE_MASK 0xf000
-#define SMIAPP_FRAME_FORMAT_DESC_2_PIXELCODE_SHIFT 12
-#define SMIAPP_FRAME_FORMAT_DESC_2_PIXELS_MASK 0x0fff
-
-#define SMIAPP_FRAME_FORMAT_DESC_4_PIXELCODE_MASK 0xf0000000
-#define SMIAPP_FRAME_FORMAT_DESC_4_PIXELCODE_SHIFT 28
-#define SMIAPP_FRAME_FORMAT_DESC_4_PIXELS_MASK 0x0000ffff
-
-#define SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_EMBEDDED 1
-#define SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_DUMMY 2
-#define SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_BLACK 3
-#define SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_DARK 4
-#define SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_VISIBLE 5
-
-#define SMIAPP_FAST_STANDBY_CTRL_COMPLETE_FRAMES 0
-#define SMIAPP_FAST_STANDBY_CTRL_IMMEDIATE 1
-
-/* Scaling N factor */
-#define SMIAPP_SCALE_N 16
-
-/* Image statistics registers */
-/* Registers 0x2000 to 0x2fff are reserved for future
- * use for statistics features.
- */
-
-/* Manufacturer Specific Registers: 0x3000 to 0x3fff
- * The manufacturer specifies these as a black box.
- */
-
-#endif /* __SMIAPP_REG_H_ */
diff --git a/drivers/media/video/smiapp/smiapp-regs.c b/drivers/media/video/smiapp/smiapp-regs.c
deleted file mode 100644
index b1812b17a40..00000000000
--- a/drivers/media/video/smiapp/smiapp-regs.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * drivers/media/video/smiapp/smiapp-regs.c
- *
- * Generic driver for SMIA/SMIA++ compliant camera modules
- *
- * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-
-#include "smiapp.h"
-#include "smiapp-regs.h"
-
-static uint32_t float_to_u32_mul_1000000(struct i2c_client *client,
- uint32_t phloat)
-{
- int32_t exp;
- uint64_t man;
-
- if (phloat >= 0x80000000) {
- dev_err(&client->dev, "this is a negative number\n");
- return 0;
- }
-
- if (phloat == 0x7f800000)
- return ~0; /* Inf. */
-
- if ((phloat & 0x7f800000) == 0x7f800000) {
- dev_err(&client->dev, "NaN or other special number\n");
- return 0;
- }
-
- /* Valid cases begin here */
- if (phloat == 0)
- return 0; /* Valid zero */
-
- if (phloat > 0x4f800000)
- return ~0; /* larger than 4294967295 */
-
- /*
- * Unbias exponent (note how phloat is now guaranteed to
- * have 0 in the high bit)
- */
- exp = ((int32_t)phloat >> 23) - 127;
-
- /* Extract mantissa, add missing '1' bit and it's in MHz */
- man = ((phloat & 0x7fffff) | 0x800000) * 1000000ULL;
-
- if (exp < 0)
- man >>= -exp;
- else
- man <<= exp;
-
- man >>= 23; /* Remove mantissa bias */
-
- return man & 0xffffffff;
-}
-
-
-/*
- * Read a 8/16/32-bit i2c register. The value is returned in 'val'.
- * Returns zero if successful, or non-zero otherwise.
- */
-static int ____smiapp_read(struct smiapp_sensor *sensor, u16 reg,
- u16 len, u32 *val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- struct i2c_msg msg;
- unsigned char data[4];
- u16 offset = reg;
- int r;
-
- msg.addr = client->addr;
- msg.flags = 0;
- msg.len = 2;
- msg.buf = data;
-
- /* high byte goes out first */
- data[0] = (u8) (offset >> 8);
- data[1] = (u8) offset;
- r = i2c_transfer(client->adapter, &msg, 1);
- if (r != 1) {
- if (r >= 0)
- r = -EBUSY;
- goto err;
- }
-
- msg.len = len;
- msg.flags = I2C_M_RD;
- r = i2c_transfer(client->adapter, &msg, 1);
- if (r != 1) {
- if (r >= 0)
- r = -EBUSY;
- goto err;
- }
-
- *val = 0;
- /* high byte comes first */
- switch (len) {
- case SMIA_REG_32BIT:
- *val = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) +
- data[3];
- break;
- case SMIA_REG_16BIT:
- *val = (data[0] << 8) + data[1];
- break;
- case SMIA_REG_8BIT:
- *val = data[0];
- break;
- default:
- BUG();
- }
-
- return 0;
-
-err:
- dev_err(&client->dev, "read from offset 0x%x error %d\n", offset, r);
-
- return r;
-}
-
-/* Read a register using 8-bit access only. */
-static int ____smiapp_read_8only(struct smiapp_sensor *sensor, u16 reg,
- u16 len, u32 *val)
-{
- unsigned int i;
- int rval;
-
- *val = 0;
-
- for (i = 0; i < len; i++) {
- u32 val8;
-
- rval = ____smiapp_read(sensor, reg + i, 1, &val8);
- if (rval < 0)
- return rval;
- *val |= val8 << ((len - i - 1) << 3);
- }
-
- return 0;
-}
-
-/*
- * Read a 8/16/32-bit i2c register. The value is returned in 'val'.
- * Returns zero if successful, or non-zero otherwise.
- */
-static int __smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val,
- bool only8)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- unsigned int len = (u8)(reg >> 16);
- int rval;
-
- if (len != SMIA_REG_8BIT && len != SMIA_REG_16BIT
- && len != SMIA_REG_32BIT)
- return -EINVAL;
-
- if (smiapp_quirk_reg(sensor, reg, val))
- goto found_quirk;
-
- if (len == SMIA_REG_8BIT && !only8)
- rval = ____smiapp_read(sensor, (u16)reg, len, val);
- else
- rval = ____smiapp_read_8only(sensor, (u16)reg, len, val);
- if (rval < 0)
- return rval;
-
-found_quirk:
- if (reg & SMIA_REG_FLAG_FLOAT)
- *val = float_to_u32_mul_1000000(client, *val);
-
- return 0;
-}
-
-int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val)
-{
- return __smiapp_read(
- sensor, reg, val,
- smiapp_needs_quirk(sensor,
- SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY));
-}
-
-int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val)
-{
- return __smiapp_read(sensor, reg, val, true);
-}
-
-/*
- * Write to a 8/16-bit register.
- * Returns zero if successful, or non-zero otherwise.
- */
-int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- struct i2c_msg msg;
- unsigned char data[6];
- unsigned int retries;
- unsigned int flags = reg >> 24;
- unsigned int len = (u8)(reg >> 16);
- u16 offset = reg;
- int r;
-
- if ((len != SMIA_REG_8BIT && len != SMIA_REG_16BIT &&
- len != SMIA_REG_32BIT) || flags)
- return -EINVAL;
-
- msg.addr = client->addr;
- msg.flags = 0; /* Write */
- msg.len = 2 + len;
- msg.buf = data;
-
- /* high byte goes out first */
- data[0] = (u8) (reg >> 8);
- data[1] = (u8) (reg & 0xff);
-
- switch (len) {
- case SMIA_REG_8BIT:
- data[2] = val;
- break;
- case SMIA_REG_16BIT:
- data[2] = val >> 8;
- data[3] = val;
- break;
- case SMIA_REG_32BIT:
- data[2] = val >> 24;
- data[3] = val >> 16;
- data[4] = val >> 8;
- data[5] = val;
- break;
- default:
- BUG();
- }
-
- for (retries = 0; retries < 5; retries++) {
- /*
- * Due to unknown reason sensor stops responding. This
- * loop is a temporaty solution until the root cause
- * is found.
- */
- r = i2c_transfer(client->adapter, &msg, 1);
- if (r == 1) {
- if (retries)
- dev_err(&client->dev,
- "sensor i2c stall encountered. "
- "retries: %d\n", retries);
- return 0;
- }
-
- usleep_range(2000, 2000);
- }
-
- dev_err(&client->dev,
- "wrote 0x%x to offset 0x%x error %d\n", val, offset, r);
-
- return r;
-}
diff --git a/drivers/media/video/smiapp/smiapp-regs.h b/drivers/media/video/smiapp/smiapp-regs.h
deleted file mode 100644
index 7f9013b4797..00000000000
--- a/drivers/media/video/smiapp/smiapp-regs.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * include/media/smiapp/smiapp-regs.h
- *
- * Generic driver for SMIA/SMIA++ compliant camera modules
- *
- * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef SMIAPP_REGS_H
-#define SMIAPP_REGS_H
-
-#include <linux/i2c.h>
-#include <linux/types.h>
-
-/* Use upper 8 bits of the type field for flags */
-#define SMIA_REG_FLAG_FLOAT (1 << 24)
-
-#define SMIA_REG_8BIT 1
-#define SMIA_REG_16BIT 2
-#define SMIA_REG_32BIT 4
-struct smia_reg {
- u16 type;
- u16 reg; /* 16-bit offset */
- u32 val; /* 8/16/32-bit value */
-};
-
-struct smiapp_sensor;
-
-int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val);
-int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val);
-int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val);
-
-#endif
diff --git a/drivers/media/video/smiapp/smiapp.h b/drivers/media/video/smiapp/smiapp.h
deleted file mode 100644
index 587f7f11238..00000000000
--- a/drivers/media/video/smiapp/smiapp.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * drivers/media/video/smiapp/smiapp.h
- *
- * Generic driver for SMIA/SMIA++ compliant camera modules
- *
- * Copyright (C) 2010--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __SMIAPP_PRIV_H_
-#define __SMIAPP_PRIV_H_
-
-#include <linux/mutex.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-subdev.h>
-#include <media/smiapp.h>
-
-#include "smiapp-pll.h"
-#include "smiapp-reg.h"
-#include "smiapp-regs.h"
-#include "smiapp-quirk.h"
-
-/*
- * Standard SMIA++ constants
- */
-#define SMIA_VERSION_1 10
-#define SMIAPP_VERSION_0_8 8 /* Draft 0.8 */
-#define SMIAPP_VERSION_0_9 9 /* Draft 0.9 */
-#define SMIAPP_VERSION_1 10
-
-#define SMIAPP_PROFILE_0 0
-#define SMIAPP_PROFILE_1 1
-#define SMIAPP_PROFILE_2 2
-
-#define SMIAPP_NVM_PAGE_SIZE 64 /* bytes */
-
-#define SMIAPP_RESET_DELAY_CLOCKS 2400
-#define SMIAPP_RESET_DELAY(clk) \
- (1000 + (SMIAPP_RESET_DELAY_CLOCKS * 1000 \
- + (clk) / 1000 - 1) / ((clk) / 1000))
-
-#include "smiapp-limits.h"
-
-struct smiapp_quirk;
-
-#define SMIAPP_MODULE_IDENT_FLAG_REV_LE (1 << 0)
-
-struct smiapp_module_ident {
- u8 manufacturer_id;
- u16 model_id;
- u8 revision_number_major;
-
- u8 flags;
-
- char *name;
- const struct smiapp_quirk *quirk;
-};
-
-struct smiapp_module_info {
- u32 manufacturer_id;
- u32 model_id;
- u32 revision_number_major;
- u32 revision_number_minor;
-
- u32 module_year;
- u32 module_month;
- u32 module_day;
-
- u32 sensor_manufacturer_id;
- u32 sensor_model_id;
- u32 sensor_revision_number;
- u32 sensor_firmware_version;
-
- u32 smia_version;
- u32 smiapp_version;
-
- u32 smiapp_profile;
-
- char *name;
- const struct smiapp_quirk *quirk;
-};
-
-#define SMIAPP_IDENT_FQ(manufacturer, model, rev, fl, _name, _quirk) \
- { .manufacturer_id = manufacturer, \
- .model_id = model, \
- .revision_number_major = rev, \
- .flags = fl, \
- .name = _name, \
- .quirk = _quirk, }
-
-#define SMIAPP_IDENT_LQ(manufacturer, model, rev, _name, _quirk) \
- { .manufacturer_id = manufacturer, \
- .model_id = model, \
- .revision_number_major = rev, \
- .flags = SMIAPP_MODULE_IDENT_FLAG_REV_LE, \
- .name = _name, \
- .quirk = _quirk, }
-
-#define SMIAPP_IDENT_L(manufacturer, model, rev, _name) \
- { .manufacturer_id = manufacturer, \
- .model_id = model, \
- .revision_number_major = rev, \
- .flags = SMIAPP_MODULE_IDENT_FLAG_REV_LE, \
- .name = _name, }
-
-#define SMIAPP_IDENT_Q(manufacturer, model, rev, _name, _quirk) \
- { .manufacturer_id = manufacturer, \
- .model_id = model, \
- .revision_number_major = rev, \
- .flags = 0, \
- .name = _name, \
- .quirk = _quirk, }
-
-#define SMIAPP_IDENT(manufacturer, model, rev, _name) \
- { .manufacturer_id = manufacturer, \
- .model_id = model, \
- .revision_number_major = rev, \
- .flags = 0, \
- .name = _name, }
-
-struct smiapp_reg_limits {
- u32 addr;
- char *what;
-};
-
-extern struct smiapp_reg_limits smiapp_reg_limits[];
-
-struct smiapp_csi_data_format {
- u32 code;
- u8 width;
- u8 compressed;
- u8 pixel_order;
-};
-
-#define SMIAPP_SUBDEVS 3
-
-#define SMIAPP_PA_PAD_SRC 0
-#define SMIAPP_PAD_SINK 0
-#define SMIAPP_PAD_SRC 1
-#define SMIAPP_PADS 2
-
-struct smiapp_binning_subtype {
- u8 horizontal:4;
- u8 vertical:4;
-} __packed;
-
-struct smiapp_subdev {
- struct v4l2_subdev sd;
- struct media_pad pads[2];
- struct v4l2_rect sink_fmt;
- struct v4l2_rect crop[2];
- struct v4l2_rect compose; /* compose on sink */
- unsigned short sink_pad;
- unsigned short source_pad;
- int npads;
- struct smiapp_sensor *sensor;
- struct v4l2_ctrl_handler ctrl_handler;
-};
-
-/*
- * struct smiapp_sensor - Main device structure
- */
-struct smiapp_sensor {
- /*
- * "mutex" is used to serialise access to all fields here
- * except v4l2_ctrls at the end of the struct. "mutex" is also
- * used to serialise access to file handle specific
- * information. The exception to this rule is the power_mutex
- * below.
- */
- struct mutex mutex;
- /*
- * power_mutex is used to serialise power management related
- * activities. Acquiring "mutex" at that time isn't necessary
- * since there are no other users anyway.
- */
- struct mutex power_mutex;
- struct smiapp_subdev ssds[SMIAPP_SUBDEVS];
- u32 ssds_used;
- struct smiapp_subdev *src;
- struct smiapp_subdev *binner;
- struct smiapp_subdev *scaler;
- struct smiapp_subdev *pixel_array;
- struct smiapp_platform_data *platform_data;
- struct regulator *vana;
- struct clk *ext_clk;
- u32 limits[SMIAPP_LIMIT_LAST];
- u8 nbinning_subtypes;
- struct smiapp_binning_subtype binning_subtypes[SMIAPP_BINNING_SUBTYPES];
- u32 mbus_frame_fmts;
- const struct smiapp_csi_data_format *csi_format;
- const struct smiapp_csi_data_format *internal_csi_format;
- u32 default_mbus_frame_fmts;
- int default_pixel_order;
-
- u8 binning_horizontal;
- u8 binning_vertical;
-
- u8 scale_m;
- u8 scaling_mode;
-
- u8 hvflip_inv_mask; /* H/VFLIP inversion due to sensor orientation */
- u8 flash_capability;
- u8 frame_skip;
-
- int power_count;
-
- bool streaming;
- bool dev_init_done;
-
- u8 *nvm; /* nvm memory buffer */
- unsigned int nvm_size; /* bytes */
-
- struct smiapp_module_info minfo;
-
- struct smiapp_pll pll;
-
- /* Pixel array controls */
- struct v4l2_ctrl *analog_gain;
- struct v4l2_ctrl *exposure;
- struct v4l2_ctrl *hflip;
- struct v4l2_ctrl *vflip;
- struct v4l2_ctrl *vblank;
- struct v4l2_ctrl *hblank;
- struct v4l2_ctrl *pixel_rate_parray;
- /* src controls */
- struct v4l2_ctrl *link_freq;
- struct v4l2_ctrl *pixel_rate_csi;
-};
-
-#define to_smiapp_subdev(_sd) \
- container_of(_sd, struct smiapp_subdev, sd)
-
-#define to_smiapp_sensor(_sd) \
- (to_smiapp_subdev(_sd)->sensor)
-
-#endif /* __SMIAPP_PRIV_H_ */
diff --git a/drivers/media/video/sn9c102/Kconfig b/drivers/media/video/sn9c102/Kconfig
deleted file mode 100644
index 6ebaf2940d0..00000000000
--- a/drivers/media/video/sn9c102/Kconfig
+++ /dev/null
@@ -1,14 +0,0 @@
-config USB_SN9C102
- tristate "USB SN9C1xx PC Camera Controller support (DEPRECATED)"
- depends on VIDEO_V4L2
- ---help---
- This driver is DEPRECATED please use the gspca sonixb and
- sonixj modules instead.
-
- Say Y here if you want support for cameras based on SONiX SN9C101,
- SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers.
-
- See <file:Documentation/video4linux/sn9c102.txt> for more info.
-
- To compile this driver as a module, choose M here: the
- module will be called sn9c102.
diff --git a/drivers/media/video/sn9c102/Makefile b/drivers/media/video/sn9c102/Makefile
deleted file mode 100644
index 7ecd5a90c7c..00000000000
--- a/drivers/media/video/sn9c102/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-sn9c102-objs := sn9c102_core.o \
- sn9c102_hv7131d.o \
- sn9c102_hv7131r.o \
- sn9c102_mi0343.o \
- sn9c102_mi0360.o \
- sn9c102_mt9v111.o \
- sn9c102_ov7630.o \
- sn9c102_ov7660.o \
- sn9c102_pas106b.o \
- sn9c102_pas202bcb.o \
- sn9c102_tas5110c1b.o \
- sn9c102_tas5110d.o \
- sn9c102_tas5130d1b.o
-
-obj-$(CONFIG_USB_SN9C102) += sn9c102.o
diff --git a/drivers/media/video/sn9c102/sn9c102.h b/drivers/media/video/sn9c102/sn9c102.h
deleted file mode 100644
index 2bc153e869b..00000000000
--- a/drivers/media/video/sn9c102/sn9c102.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/***************************************************************************
- * V4L2 driver for SN9C1xx PC Camera Controllers *
- * *
- * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#ifndef _SN9C102_H_
-#define _SN9C102_H_
-
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/types.h>
-#include <linux/param.h>
-#include <linux/rwsem.h>
-#include <linux/mutex.h>
-#include <linux/string.h>
-#include <linux/stddef.h>
-#include <linux/kref.h>
-
-#include "sn9c102_config.h"
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-enum sn9c102_frame_state {
- F_UNUSED,
- F_QUEUED,
- F_GRABBING,
- F_DONE,
- F_ERROR,
-};
-
-struct sn9c102_frame_t {
- void* bufmem;
- struct v4l2_buffer buf;
- enum sn9c102_frame_state state;
- struct list_head frame;
- unsigned long vma_use_count;
-};
-
-enum sn9c102_dev_state {
- DEV_INITIALIZED = 0x01,
- DEV_DISCONNECTED = 0x02,
- DEV_MISCONFIGURED = 0x04,
-};
-
-enum sn9c102_io_method {
- IO_NONE,
- IO_READ,
- IO_MMAP,
-};
-
-enum sn9c102_stream_state {
- STREAM_OFF,
- STREAM_INTERRUPT,
- STREAM_ON,
-};
-
-typedef char sn9c102_sof_header_t[62];
-
-struct sn9c102_sof_t {
- sn9c102_sof_header_t header;
- u16 bytesread;
-};
-
-struct sn9c102_sysfs_attr {
- u16 reg, i2c_reg;
- sn9c102_sof_header_t frame_header;
-};
-
-struct sn9c102_module_param {
- u8 force_munmap;
- u16 frame_timeout;
-};
-
-static DEFINE_MUTEX(sn9c102_sysfs_lock);
-static DECLARE_RWSEM(sn9c102_dev_lock);
-
-struct sn9c102_device {
- struct video_device* v4ldev;
-
- enum sn9c102_bridge bridge;
- struct sn9c102_sensor sensor;
-
- struct usb_device* usbdev;
- struct urb* urb[SN9C102_URBS];
- void* transfer_buffer[SN9C102_URBS];
- u8* control_buffer;
-
- struct sn9c102_frame_t *frame_current, frame[SN9C102_MAX_FRAMES];
- struct list_head inqueue, outqueue;
- u32 frame_count, nbuffers, nreadbuffers;
-
- enum sn9c102_io_method io;
- enum sn9c102_stream_state stream;
-
- struct v4l2_jpegcompression compression;
-
- struct sn9c102_sysfs_attr sysfs;
- struct sn9c102_sof_t sof;
- u16 reg[384];
-
- struct sn9c102_module_param module_param;
-
- struct kref kref;
- enum sn9c102_dev_state state;
- u8 users;
-
- struct completion probe;
- struct mutex open_mutex, fileop_mutex;
- spinlock_t queue_lock;
- wait_queue_head_t wait_open, wait_frame, wait_stream;
-};
-
-/*****************************************************************************/
-
-struct sn9c102_device*
-sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id)
-{
- return usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id) ? cam : NULL;
-}
-
-
-void
-sn9c102_attach_sensor(struct sn9c102_device* cam,
- const struct sn9c102_sensor* sensor)
-{
- memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor));
-}
-
-
-enum sn9c102_bridge
-sn9c102_get_bridge(struct sn9c102_device* cam)
-{
- return cam->bridge;
-}
-
-
-struct sn9c102_sensor* sn9c102_get_sensor(struct sn9c102_device* cam)
-{
- return &cam->sensor;
-}
-
-/*****************************************************************************/
-
-#undef DBG
-#undef KDBG
-#ifdef SN9C102_DEBUG
-# define DBG(level, fmt, args...) \
-do { \
- if (debug >= (level)) { \
- if ((level) == 1) \
- dev_err(&cam->usbdev->dev, fmt "\n", ## args); \
- else if ((level) == 2) \
- dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
- else if ((level) >= 3) \
- dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
- __func__, __LINE__ , ## args); \
- } \
-} while (0)
-# define V4LDBG(level, name, cmd) \
-do { \
- if (debug >= (level)) \
- v4l_printk_ioctl(name, cmd); \
-} while (0)
-# define KDBG(level, fmt, args...) \
-do { \
- if (debug >= (level)) { \
- if ((level) == 1 || (level) == 2) \
- pr_info("sn9c102: " fmt "\n", ## args); \
- else if ((level) == 3) \
- pr_debug("sn9c102: [%s:%d] " fmt "\n", \
- __func__, __LINE__ , ## args); \
- } \
-} while (0)
-#else
-# define DBG(level, fmt, args...) do {;} while(0)
-# define V4LDBG(level, name, cmd) do {;} while(0)
-# define KDBG(level, fmt, args...) do {;} while(0)
-#endif
-
-#undef PDBG
-#define PDBG(fmt, args...) \
-dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __func__, \
- __LINE__ , ## args)
-
-#undef PDBGG
-#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
-
-#endif /* _SN9C102_H_ */
diff --git a/drivers/media/video/sn9c102/sn9c102_config.h b/drivers/media/video/sn9c102/sn9c102_config.h
deleted file mode 100644
index 0f4e0378b07..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_config.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/***************************************************************************
- * Global parameters for the V4L2 driver for SN9C1xx PC Camera Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#ifndef _SN9C102_CONFIG_H_
-#define _SN9C102_CONFIG_H_
-
-#include <linux/types.h>
-#include <linux/jiffies.h>
-
-#define SN9C102_DEBUG
-#define SN9C102_DEBUG_LEVEL 2
-#define SN9C102_MAX_DEVICES 64
-#define SN9C102_PRESERVE_IMGSCALE 0
-#define SN9C102_FORCE_MUNMAP 0
-#define SN9C102_MAX_FRAMES 32
-#define SN9C102_URBS 2
-#define SN9C102_ISO_PACKETS 7
-#define SN9C102_ALTERNATE_SETTING 8
-#define SN9C102_URB_TIMEOUT msecs_to_jiffies(2 * SN9C102_ISO_PACKETS)
-#define SN9C102_CTRL_TIMEOUT 300
-#define SN9C102_FRAME_TIMEOUT 0
-
-/*****************************************************************************/
-
-static const u8 SN9C102_Y_QTABLE0[64] = {
- 8, 5, 5, 8, 12, 20, 25, 30,
- 6, 6, 7, 9, 13, 29, 30, 27,
- 7, 6, 8, 12, 20, 28, 34, 28,
- 7, 8, 11, 14, 25, 43, 40, 31,
- 9, 11, 18, 28, 34, 54, 51, 38,
- 12, 17, 27, 32, 40, 52, 56, 46,
- 24, 32, 39, 43, 51, 60, 60, 50,
- 36, 46, 47, 49, 56, 50, 51, 49
-};
-
-static const u8 SN9C102_UV_QTABLE0[64] = {
- 8, 9, 12, 23, 49, 49, 49, 49,
- 9, 10, 13, 33, 49, 49, 49, 49,
- 12, 13, 28, 49, 49, 49, 49, 49,
- 23, 33, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49
-};
-
-static const u8 SN9C102_Y_QTABLE1[64] = {
- 16, 11, 10, 16, 24, 40, 51, 61,
- 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 56, 68, 109, 103, 77,
- 24, 35, 55, 64, 81, 104, 113, 92,
- 49, 64, 78, 87, 103, 121, 120, 101,
- 72, 92, 95, 98, 112, 100, 103, 99
-};
-
-static const u8 SN9C102_UV_QTABLE1[64] = {
- 17, 18, 24, 47, 99, 99, 99, 99,
- 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 66, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99
-};
-
-#endif /* _SN9C102_CONFIG_H_ */
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
deleted file mode 100644
index 19ea780b16f..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ /dev/null
@@ -1,3421 +0,0 @@
-/***************************************************************************
- * V4L2 driver for SN9C1xx PC Camera Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/fs.h>
-#include <linux/delay.h>
-#include <linux/compiler.h>
-#include <linux/ioctl.h>
-#include <linux/poll.h>
-#include <linux/stat.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/version.h>
-#include <linux/page-flags.h>
-#include <asm/byteorder.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#include "sn9c102.h"
-
-/*****************************************************************************/
-
-#define SN9C102_MODULE_NAME "V4L2 driver for SN9C1xx PC Camera Controllers"
-#define SN9C102_MODULE_ALIAS "sn9c1xx"
-#define SN9C102_MODULE_AUTHOR "(C) 2004-2007 Luca Risolia"
-#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
-#define SN9C102_MODULE_LICENSE "GPL"
-#define SN9C102_MODULE_VERSION "1:1.48"
-
-/*****************************************************************************/
-
-MODULE_DEVICE_TABLE(usb, sn9c102_id_table);
-
-MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL);
-MODULE_DESCRIPTION(SN9C102_MODULE_NAME);
-MODULE_ALIAS(SN9C102_MODULE_ALIAS);
-MODULE_VERSION(SN9C102_MODULE_VERSION);
-MODULE_LICENSE(SN9C102_MODULE_LICENSE);
-
-static short video_nr[] = {[0 ... SN9C102_MAX_DEVICES-1] = -1};
-module_param_array(video_nr, short, NULL, 0444);
-MODULE_PARM_DESC(video_nr,
- " <-1|n[,...]>"
- "\nSpecify V4L2 minor mode number."
- "\n-1 = use next available (default)"
- "\n n = use minor number n (integer >= 0)"
- "\nYou can specify up to "__MODULE_STRING(SN9C102_MAX_DEVICES)
- " cameras this way."
- "\nFor example:"
- "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
- "\nthe second camera and use auto for the first"
- "\none and for every other camera."
- "\n");
-
-static bool force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] =
- SN9C102_FORCE_MUNMAP};
-module_param_array(force_munmap, bool, NULL, 0444);
-MODULE_PARM_DESC(force_munmap,
- " <0|1[,...]>"
- "\nForce the application to unmap previously"
- "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
- "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
- "\nthis feature. This parameter is specific for each"
- "\ndetected camera."
- "\n0 = do not force memory unmapping"
- "\n1 = force memory unmapping (save memory)"
- "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
- "\n");
-
-static unsigned int frame_timeout[] = {[0 ... SN9C102_MAX_DEVICES-1] =
- SN9C102_FRAME_TIMEOUT};
-module_param_array(frame_timeout, uint, NULL, 0644);
-MODULE_PARM_DESC(frame_timeout,
- " <0|n[,...]>"
- "\nTimeout for a video frame in seconds before"
- "\nreturning an I/O error; 0 for infinity."
- "\nThis parameter is specific for each detected camera."
- "\nDefault value is "__MODULE_STRING(SN9C102_FRAME_TIMEOUT)"."
- "\n");
-
-#ifdef SN9C102_DEBUG
-static unsigned short debug = SN9C102_DEBUG_LEVEL;
-module_param(debug, ushort, 0644);
-MODULE_PARM_DESC(debug,
- " <n>"
- "\nDebugging information level, from 0 to 3:"
- "\n0 = none (use carefully)"
- "\n1 = critical errors"
- "\n2 = significant informations"
- "\n3 = more verbose messages"
- "\nLevel 3 is useful for testing only."
- "\nDefault value is "__MODULE_STRING(SN9C102_DEBUG_LEVEL)"."
- "\n");
-#endif
-
-/*
- Add the probe entries to this table. Be sure to add the entry in the right
- place, since, on failure, the next probing routine is called according to
- the order of the list below, from top to bottom.
-*/
-static int (*sn9c102_sensor_table[])(struct sn9c102_device *) = {
- &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */
- &sn9c102_probe_hv7131r, /* strong detection based on SENSOR ids */
- &sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */
- &sn9c102_probe_mi0360, /* strong detection based on SENSOR ids */
- &sn9c102_probe_mt9v111, /* strong detection based on SENSOR ids */
- &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */
- &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */
- &sn9c102_probe_ov7630, /* strong detection based on SENSOR ids */
- &sn9c102_probe_ov7660, /* strong detection based on SENSOR ids */
- &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */
- &sn9c102_probe_tas5110d, /* detection based on USB pid/vid */
- &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */
-};
-
-/*****************************************************************************/
-
-static u32
-sn9c102_request_buffers(struct sn9c102_device* cam, u32 count,
- enum sn9c102_io_method io)
-{
- struct v4l2_pix_format* p = &(cam->sensor.pix_format);
- struct v4l2_rect* r = &(cam->sensor.cropcap.bounds);
- size_t imagesize = cam->module_param.force_munmap || io == IO_READ ?
- (p->width * p->height * p->priv) / 8 :
- (r->width * r->height * p->priv) / 8;
- void* buff = NULL;
- u32 i;
-
- if (count > SN9C102_MAX_FRAMES)
- count = SN9C102_MAX_FRAMES;
-
- if (cam->bridge == BRIDGE_SN9C105 || cam->bridge == BRIDGE_SN9C120)
- imagesize += 589 + 2; /* length of JPEG header + EOI marker */
-
- cam->nbuffers = count;
- while (cam->nbuffers > 0) {
- if ((buff = vmalloc_32_user(cam->nbuffers *
- PAGE_ALIGN(imagesize))))
- break;
- cam->nbuffers--;
- }
-
- for (i = 0; i < cam->nbuffers; i++) {
- cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize);
- cam->frame[i].buf.index = i;
- cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize);
- cam->frame[i].buf.length = imagesize;
- cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- cam->frame[i].buf.sequence = 0;
- cam->frame[i].buf.field = V4L2_FIELD_NONE;
- cam->frame[i].buf.memory = V4L2_MEMORY_MMAP;
- cam->frame[i].buf.flags = 0;
- }
-
- return cam->nbuffers;
-}
-
-
-static void sn9c102_release_buffers(struct sn9c102_device* cam)
-{
- if (cam->nbuffers) {
- vfree(cam->frame[0].bufmem);
- cam->nbuffers = 0;
- }
- cam->frame_current = NULL;
-}
-
-
-static void sn9c102_empty_framequeues(struct sn9c102_device* cam)
-{
- u32 i;
-
- INIT_LIST_HEAD(&cam->inqueue);
- INIT_LIST_HEAD(&cam->outqueue);
-
- for (i = 0; i < SN9C102_MAX_FRAMES; i++) {
- cam->frame[i].state = F_UNUSED;
- cam->frame[i].buf.bytesused = 0;
- }
-}
-
-
-static void sn9c102_requeue_outqueue(struct sn9c102_device* cam)
-{
- struct sn9c102_frame_t *i;
-
- list_for_each_entry(i, &cam->outqueue, frame) {
- i->state = F_QUEUED;
- list_add(&i->frame, &cam->inqueue);
- }
-
- INIT_LIST_HEAD(&cam->outqueue);
-}
-
-
-static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
-{
- unsigned long lock_flags;
- u32 i;
-
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].state == F_UNUSED) {
- cam->frame[i].state = F_QUEUED;
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_add_tail(&cam->frame[i].frame, &cam->inqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
- }
-}
-
-/*****************************************************************************/
-
-/*
- Write a sequence of count value/register pairs. Returns -1 after the first
- failed write, or 0 for no errors.
-*/
-int sn9c102_write_regs(struct sn9c102_device* cam, const u8 valreg[][2],
- int count)
-{
- struct usb_device* udev = cam->usbdev;
- u8* buff = cam->control_buffer;
- int i, res;
-
- for (i = 0; i < count; i++) {
- u8 index = valreg[i][1];
-
- /*
- index is a u8, so it must be <256 and can't be out of range.
- If we put in a check anyway, gcc annoys us with a warning
- hat our check is useless. People get all uppity when they
- see warnings in the kernel compile.
- */
-
- *buff = valreg[i][0];
-
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08,
- 0x41, index, 0, buff, 1,
- SN9C102_CTRL_TIMEOUT);
-
- if (res < 0) {
- DBG(3, "Failed to write a register (value 0x%02X, "
- "index 0x%02X, error %d)", *buff, index, res);
- return -1;
- }
-
- cam->reg[index] = *buff;
- }
-
- return 0;
-}
-
-
-int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index)
-{
- struct usb_device* udev = cam->usbdev;
- u8* buff = cam->control_buffer;
- int res;
-
- if (index >= ARRAY_SIZE(cam->reg))
- return -1;
-
- *buff = value;
-
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
- index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
- if (res < 0) {
- DBG(3, "Failed to write a register (value 0x%02X, index "
- "0x%02X, error %d)", value, index, res);
- return -1;
- }
-
- cam->reg[index] = value;
-
- return 0;
-}
-
-
-/* NOTE: with the SN9C10[123] reading some registers always returns 0 */
-int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
-{
- struct usb_device* udev = cam->usbdev;
- u8* buff = cam->control_buffer;
- int res;
-
- res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
- index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- DBG(3, "Failed to read a register (index 0x%02X, error %d)",
- index, res);
-
- return (res >= 0) ? (int)(*buff) : -1;
-}
-
-
-int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index)
-{
- if (index >= ARRAY_SIZE(cam->reg))
- return -1;
-
- return cam->reg[index];
-}
-
-
-static int
-sn9c102_i2c_wait(struct sn9c102_device* cam,
- const struct sn9c102_sensor* sensor)
-{
- int i, r;
-
- for (i = 1; i <= 5; i++) {
- r = sn9c102_read_reg(cam, 0x08);
- if (r < 0)
- return -EIO;
- if (r & 0x04)
- return 0;
- if (sensor->frequency & SN9C102_I2C_400KHZ)
- udelay(5*16);
- else
- udelay(16*16);
- }
- return -EBUSY;
-}
-
-
-static int
-sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
- const struct sn9c102_sensor* sensor)
-{
- int r , err = 0;
-
- r = sn9c102_read_reg(cam, 0x08);
- if (r < 0)
- err += r;
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
- if (!(r & 0x08))
- err += -1;
- } else {
- if (r & 0x08)
- err += -1;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int
-sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
- const struct sn9c102_sensor* sensor)
-{
- int r;
- r = sn9c102_read_reg(cam, 0x08);
- return (r < 0 || (r >= 0 && (r & 0x08))) ? -EIO : 0;
-}
-
-
-int
-sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
- const struct sn9c102_sensor* sensor, u8 data0,
- u8 data1, u8 n, u8 buffer[])
-{
- struct usb_device* udev = cam->usbdev;
- u8* data = cam->control_buffer;
- int i = 0, err = 0, res;
-
- /* Write cycle */
- data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
- ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) | 0x10;
- data[1] = data0; /* I2C slave id */
- data[2] = data1; /* address */
- data[7] = 0x10;
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
- 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- err += res;
-
- err += sn9c102_i2c_wait(cam, sensor);
-
- /* Read cycle - n bytes */
- data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
- ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) |
- (n << 4) | 0x02;
- data[1] = data0;
- data[7] = 0x10;
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
- 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- err += res;
-
- err += sn9c102_i2c_wait(cam, sensor);
-
- /* The first read byte will be placed in data[4] */
- res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
- 0x0a, 0, data, 5, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- err += res;
-
- err += sn9c102_i2c_detect_read_error(cam, sensor);
-
- PDBGG("I2C read: address 0x%02X, first read byte: 0x%02X", data1,
- data[4]);
-
- if (err) {
- DBG(3, "I2C read failed for %s image sensor", sensor->name);
- return -1;
- }
-
- if (buffer)
- for (i = 0; i < n && i < 5; i++)
- buffer[n-i-1] = data[4-i];
-
- return (int)data[4];
-}
-
-
-int
-sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
- const struct sn9c102_sensor* sensor, u8 n, u8 data0,
- u8 data1, u8 data2, u8 data3, u8 data4, u8 data5)
-{
- struct usb_device* udev = cam->usbdev;
- u8* data = cam->control_buffer;
- int err = 0, res;
-
- /* Write cycle. It usually is address + value */
- data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
- ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0)
- | ((n - 1) << 4);
- data[1] = data0;
- data[2] = data1;
- data[3] = data2;
- data[4] = data3;
- data[5] = data4;
- data[6] = data5;
- data[7] = 0x17;
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
- 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- err += res;
-
- err += sn9c102_i2c_wait(cam, sensor);
- err += sn9c102_i2c_detect_write_error(cam, sensor);
-
- if (err)
- DBG(3, "I2C write failed for %s image sensor", sensor->name);
-
- PDBGG("I2C raw write: %u bytes, data0 = 0x%02X, data1 = 0x%02X, "
- "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X",
- n, data0, data1, data2, data3, data4, data5);
-
- return err ? -1 : 0;
-}
-
-
-int
-sn9c102_i2c_try_read(struct sn9c102_device* cam,
- const struct sn9c102_sensor* sensor, u8 address)
-{
- return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
- address, 1, NULL);
-}
-
-
-static int sn9c102_i2c_try_write(struct sn9c102_device* cam,
- const struct sn9c102_sensor* sensor,
- u8 address, u8 value)
-{
- return sn9c102_i2c_try_raw_write(cam, sensor, 3,
- sensor->i2c_slave_id, address,
- value, 0, 0, 0);
-}
-
-
-int sn9c102_i2c_read(struct sn9c102_device* cam, u8 address)
-{
- return sn9c102_i2c_try_read(cam, &cam->sensor, address);
-}
-
-
-int sn9c102_i2c_write(struct sn9c102_device* cam, u8 address, u8 value)
-{
- return sn9c102_i2c_try_write(cam, &cam->sensor, address, value);
-}
-
-/*****************************************************************************/
-
-static size_t sn9c102_sof_length(struct sn9c102_device* cam)
-{
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- return 12;
- case BRIDGE_SN9C103:
- return 18;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- return 62;
- }
-
- return 0;
-}
-
-
-static void*
-sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len)
-{
- static const char marker[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
- const char *m = mem;
- size_t soflen = 0, i, j;
-
- soflen = sn9c102_sof_length(cam);
-
- for (i = 0; i < len; i++) {
- size_t b;
-
- /* Read the variable part of the header */
- if (unlikely(cam->sof.bytesread >= sizeof(marker))) {
- cam->sof.header[cam->sof.bytesread] = *(m+i);
- if (++cam->sof.bytesread == soflen) {
- cam->sof.bytesread = 0;
- return mem + i;
- }
- continue;
- }
-
- /* Search for the SOF marker (fixed part) in the header */
- for (j = 0, b=cam->sof.bytesread; j+b < sizeof(marker); j++) {
- if (unlikely(i+j == len))
- return NULL;
- if (*(m+i+j) == marker[cam->sof.bytesread]) {
- cam->sof.header[cam->sof.bytesread] = *(m+i+j);
- if (++cam->sof.bytesread == sizeof(marker)) {
- PDBGG("Bytes to analyze: %zd. SOF "
- "starts at byte #%zd", len, i);
- i += j+1;
- break;
- }
- } else {
- cam->sof.bytesread = 0;
- break;
- }
- }
- }
-
- return NULL;
-}
-
-
-static void*
-sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
-{
- static const u8 eof_header[4][4] = {
- {0x00, 0x00, 0x00, 0x00},
- {0x40, 0x00, 0x00, 0x00},
- {0x80, 0x00, 0x00, 0x00},
- {0xc0, 0x00, 0x00, 0x00},
- };
- size_t i, j;
-
- /* The EOF header does not exist in compressed data */
- if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X ||
- cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
- return NULL;
-
- /*
- The EOF header might cross the packet boundary, but this is not a
- problem, since the end of a frame is determined by checking its size
- in the first place.
- */
- for (i = 0; (len >= 4) && (i <= len - 4); i++)
- for (j = 0; j < ARRAY_SIZE(eof_header); j++)
- if (!memcmp(mem + i, eof_header[j], 4))
- return mem + i;
-
- return NULL;
-}
-
-
-static void
-sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
-{
- static const u8 jpeg_header[589] = {
- 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x06, 0x04, 0x05,
- 0x06, 0x05, 0x04, 0x06, 0x06, 0x05, 0x06, 0x07, 0x07, 0x06,
- 0x08, 0x0a, 0x10, 0x0a, 0x0a, 0x09, 0x09, 0x0a, 0x14, 0x0e,
- 0x0f, 0x0c, 0x10, 0x17, 0x14, 0x18, 0x18, 0x17, 0x14, 0x16,
- 0x16, 0x1a, 0x1d, 0x25, 0x1f, 0x1a, 0x1b, 0x23, 0x1c, 0x16,
- 0x16, 0x20, 0x2c, 0x20, 0x23, 0x26, 0x27, 0x29, 0x2a, 0x29,
- 0x19, 0x1f, 0x2d, 0x30, 0x2d, 0x28, 0x30, 0x25, 0x28, 0x29,
- 0x28, 0x01, 0x07, 0x07, 0x07, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
- 0x0a, 0x13, 0x28, 0x1a, 0x16, 0x1a, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xff, 0xc4, 0x01, 0xa2,
- 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
- 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01,
- 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
- 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x10, 0x00,
- 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04,
- 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04,
- 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
- 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23,
- 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62,
- 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25,
- 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
- 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
- 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
- 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
- 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
- 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
- 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
- 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3,
- 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3,
- 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3,
- 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x11, 0x00, 0x02,
- 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04,
- 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
- 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
- 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1,
- 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1,
- 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19,
- 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
- 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
- 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
- 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
- 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
- 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
- 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
- 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3,
- 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,
- 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc0, 0x00, 0x11,
- 0x08, 0x01, 0xe0, 0x02, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02,
- 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03,
- 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
- };
- u8 *pos = f->bufmem;
-
- memcpy(pos, jpeg_header, sizeof(jpeg_header));
- *(pos + 6) = 0x00;
- *(pos + 7 + 64) = 0x01;
- if (cam->compression.quality == 0) {
- memcpy(pos + 7, SN9C102_Y_QTABLE0, 64);
- memcpy(pos + 8 + 64, SN9C102_UV_QTABLE0, 64);
- } else if (cam->compression.quality == 1) {
- memcpy(pos + 7, SN9C102_Y_QTABLE1, 64);
- memcpy(pos + 8 + 64, SN9C102_UV_QTABLE1, 64);
- }
- *(pos + 564) = cam->sensor.pix_format.width & 0xFF;
- *(pos + 563) = (cam->sensor.pix_format.width >> 8) & 0xFF;
- *(pos + 562) = cam->sensor.pix_format.height & 0xFF;
- *(pos + 561) = (cam->sensor.pix_format.height >> 8) & 0xFF;
- *(pos + 567) = 0x21;
-
- f->buf.bytesused += sizeof(jpeg_header);
-}
-
-
-static void sn9c102_urb_complete(struct urb *urb)
-{
- struct sn9c102_device* cam = urb->context;
- struct sn9c102_frame_t** f;
- size_t imagesize, soflen;
- u8 i;
- int err = 0;
-
- if (urb->status == -ENOENT)
- return;
-
- f = &cam->frame_current;
-
- if (cam->stream == STREAM_INTERRUPT) {
- cam->stream = STREAM_OFF;
- if ((*f))
- (*f)->state = F_QUEUED;
- cam->sof.bytesread = 0;
- DBG(3, "Stream interrupted by application");
- wake_up(&cam->wait_stream);
- }
-
- if (cam->state & DEV_DISCONNECTED)
- return;
-
- if (cam->state & DEV_MISCONFIGURED) {
- wake_up_interruptible(&cam->wait_frame);
- return;
- }
-
- if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue))
- goto resubmit_urb;
-
- if (!(*f))
- (*f) = list_entry(cam->inqueue.next, struct sn9c102_frame_t,
- frame);
-
- imagesize = (cam->sensor.pix_format.width *
- cam->sensor.pix_format.height *
- cam->sensor.pix_format.priv) / 8;
- if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
- imagesize += 589; /* length of jpeg header */
- soflen = sn9c102_sof_length(cam);
-
- for (i = 0; i < urb->number_of_packets; i++) {
- unsigned int img, len, status;
- void *pos, *sof, *eof;
-
- len = urb->iso_frame_desc[i].actual_length;
- status = urb->iso_frame_desc[i].status;
- pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
-
- if (status) {
- DBG(3, "Error in isochronous frame");
- (*f)->state = F_ERROR;
- cam->sof.bytesread = 0;
- continue;
- }
-
- PDBGG("Isochrnous frame: length %u, #%u i", len, i);
-
-redo:
- sof = sn9c102_find_sof_header(cam, pos, len);
- if (likely(!sof)) {
- eof = sn9c102_find_eof_header(cam, pos, len);
- if ((*f)->state == F_GRABBING) {
-end_of_frame:
- img = len;
-
- if (eof)
- img = (eof > pos) ? eof - pos - 1 : 0;
-
- if ((*f)->buf.bytesused + img > imagesize) {
- u32 b;
- b = (*f)->buf.bytesused + img -
- imagesize;
- img = imagesize - (*f)->buf.bytesused;
- PDBGG("Expected EOF not found: video "
- "frame cut");
- if (eof)
- DBG(3, "Exceeded limit: +%u "
- "bytes", (unsigned)(b));
- }
-
- memcpy((*f)->bufmem + (*f)->buf.bytesused, pos,
- img);
-
- if ((*f)->buf.bytesused == 0)
- do_gettimeofday(&(*f)->buf.timestamp);
-
- (*f)->buf.bytesused += img;
-
- if ((*f)->buf.bytesused == imagesize ||
- ((cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_SN9C10X ||
- cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_JPEG) && eof)) {
- u32 b;
-
- b = (*f)->buf.bytesused;
- (*f)->state = F_DONE;
- (*f)->buf.sequence= ++cam->frame_count;
-
- spin_lock(&cam->queue_lock);
- list_move_tail(&(*f)->frame,
- &cam->outqueue);
- if (!list_empty(&cam->inqueue))
- (*f) = list_entry(
- cam->inqueue.next,
- struct sn9c102_frame_t,
- frame );
- else
- (*f) = NULL;
- spin_unlock(&cam->queue_lock);
-
- memcpy(cam->sysfs.frame_header,
- cam->sof.header, soflen);
-
- DBG(3, "Video frame captured: %lu "
- "bytes", (unsigned long)(b));
-
- if (!(*f))
- goto resubmit_urb;
-
- } else if (eof) {
- (*f)->state = F_ERROR;
- DBG(3, "Not expected EOF after %lu "
- "bytes of image data",
- (unsigned long)
- ((*f)->buf.bytesused));
- }
-
- if (sof) /* (1) */
- goto start_of_frame;
-
- } else if (eof) {
- DBG(3, "EOF without SOF");
- continue;
-
- } else {
- PDBGG("Ignoring pointless isochronous frame");
- continue;
- }
-
- } else if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR) {
-start_of_frame:
- (*f)->state = F_GRABBING;
- (*f)->buf.bytesused = 0;
- len -= (sof - pos);
- pos = sof;
- if (cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_JPEG)
- sn9c102_write_jpegheader(cam, (*f));
- DBG(3, "SOF detected: new video frame");
- if (len)
- goto redo;
-
- } else if ((*f)->state == F_GRABBING) {
- eof = sn9c102_find_eof_header(cam, pos, len);
- if (eof && eof < sof)
- goto end_of_frame; /* (1) */
- else {
- if (cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_SN9C10X ||
- cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_JPEG) {
- if (sof - pos >= soflen) {
- eof = sof - soflen;
- } else { /* remove header */
- eof = pos;
- (*f)->buf.bytesused -=
- (soflen - (sof - pos));
- }
- goto end_of_frame;
- } else {
- DBG(3, "SOF before expected EOF after "
- "%lu bytes of image data",
- (unsigned long)
- ((*f)->buf.bytesused));
- goto start_of_frame;
- }
- }
- }
- }
-
-resubmit_urb:
- urb->dev = cam->usbdev;
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (err < 0 && err != -EPERM) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "usb_submit_urb() failed");
- }
-
- wake_up_interruptible(&cam->wait_frame);
-}
-
-
-static int sn9c102_start_transfer(struct sn9c102_device* cam)
-{
- struct usb_device *udev = cam->usbdev;
- struct urb* urb;
- struct usb_host_interface* altsetting = usb_altnum_to_altsetting(
- usb_ifnum_to_if(udev, 0),
- SN9C102_ALTERNATE_SETTING);
- const unsigned int psz = le16_to_cpu(altsetting->
- endpoint[0].desc.wMaxPacketSize);
- s8 i, j;
- int err = 0;
-
- for (i = 0; i < SN9C102_URBS; i++) {
- cam->transfer_buffer[i] = kzalloc(SN9C102_ISO_PACKETS * psz,
- GFP_KERNEL);
- if (!cam->transfer_buffer[i]) {
- err = -ENOMEM;
- DBG(1, "Not enough memory");
- goto free_buffers;
- }
- }
-
- for (i = 0; i < SN9C102_URBS; i++) {
- urb = usb_alloc_urb(SN9C102_ISO_PACKETS, GFP_KERNEL);
- cam->urb[i] = urb;
- if (!urb) {
- err = -ENOMEM;
- DBG(1, "usb_alloc_urb() failed");
- goto free_urbs;
- }
- urb->dev = udev;
- urb->context = cam;
- urb->pipe = usb_rcvisocpipe(udev, 1);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->number_of_packets = SN9C102_ISO_PACKETS;
- urb->complete = sn9c102_urb_complete;
- urb->transfer_buffer = cam->transfer_buffer[i];
- urb->transfer_buffer_length = psz * SN9C102_ISO_PACKETS;
- urb->interval = 1;
- for (j = 0; j < SN9C102_ISO_PACKETS; j++) {
- urb->iso_frame_desc[j].offset = psz * j;
- urb->iso_frame_desc[j].length = psz;
- }
- }
-
- /* Enable video */
- if (!(cam->reg[0x01] & 0x04)) {
- err = sn9c102_write_reg(cam, cam->reg[0x01] | 0x04, 0x01);
- if (err) {
- err = -EIO;
- DBG(1, "I/O hardware error");
- goto free_urbs;
- }
- }
-
- err = usb_set_interface(udev, 0, SN9C102_ALTERNATE_SETTING);
- if (err) {
- DBG(1, "usb_set_interface() failed");
- goto free_urbs;
- }
-
- cam->frame_current = NULL;
- cam->sof.bytesread = 0;
-
- for (i = 0; i < SN9C102_URBS; i++) {
- err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
- if (err) {
- for (j = i-1; j >= 0; j--)
- usb_kill_urb(cam->urb[j]);
- DBG(1, "usb_submit_urb() failed, error %d", err);
- goto free_urbs;
- }
- }
-
- return 0;
-
-free_urbs:
- for (i = 0; (i < SN9C102_URBS) && cam->urb[i]; i++)
- usb_free_urb(cam->urb[i]);
-
-free_buffers:
- for (i = 0; (i < SN9C102_URBS) && cam->transfer_buffer[i]; i++)
- kfree(cam->transfer_buffer[i]);
-
- return err;
-}
-
-
-static int sn9c102_stop_transfer(struct sn9c102_device* cam)
-{
- struct usb_device *udev = cam->usbdev;
- s8 i;
- int err = 0;
-
- if (cam->state & DEV_DISCONNECTED)
- return 0;
-
- for (i = SN9C102_URBS-1; i >= 0; i--) {
- usb_kill_urb(cam->urb[i]);
- usb_free_urb(cam->urb[i]);
- kfree(cam->transfer_buffer[i]);
- }
-
- err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
- if (err)
- DBG(3, "usb_set_interface() failed");
-
- return err;
-}
-
-
-static int sn9c102_stream_interrupt(struct sn9c102_device* cam)
-{
- cam->stream = STREAM_INTERRUPT;
- wait_event_timeout(cam->wait_stream,
- (cam->stream == STREAM_OFF) ||
- (cam->state & DEV_DISCONNECTED),
- SN9C102_URB_TIMEOUT);
- if (cam->state & DEV_DISCONNECTED)
- return -ENODEV;
- else if (cam->stream != STREAM_OFF) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "URB timeout reached. The camera is misconfigured. "
- "To use it, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- return 0;
-}
-
-/*****************************************************************************/
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static u16 sn9c102_strtou16(const char* buff, size_t len, ssize_t* count)
-{
- char str[7];
- char* endp;
- unsigned long val;
-
- if (len < 6) {
- strncpy(str, buff, len);
- str[len] = '\0';
- } else {
- strncpy(str, buff, 6);
- str[6] = '\0';
- }
-
- val = simple_strtoul(str, &endp, 0);
-
- *count = 0;
- if (val <= 0xffff)
- *count = (ssize_t)(endp - str);
- if ((*count) && (len == *count+1) && (buff[*count] == '\n'))
- *count += 1;
-
- return (u16)val;
-}
-
-/*
- NOTE 1: being inside one of the following methods implies that the v4l
- device exists for sure (see kobjects and reference counters)
- NOTE 2: buffers are PAGE_SIZE long
-*/
-
-static ssize_t sn9c102_show_reg(struct device* cd,
- struct device_attribute *attr, char* buf)
-{
- struct sn9c102_device* cam;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- count = sprintf(buf, "%u\n", cam->sysfs.reg);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_reg(struct device* cd, struct device_attribute *attr,
- const char* buf, size_t len)
-{
- struct sn9c102_device* cam;
- u16 index;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- index = sn9c102_strtou16(buf, len, &count);
- if (index >= ARRAY_SIZE(cam->reg) || !count) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
- cam->sysfs.reg = index;
-
- DBG(2, "Moved SN9C1XX register index to 0x%02X", cam->sysfs.reg);
- DBG(3, "Written bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t sn9c102_show_val(struct device* cd,
- struct device_attribute *attr, char* buf)
-{
- struct sn9c102_device* cam;
- ssize_t count;
- int val;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- if ((val = sn9c102_read_reg(cam, cam->sysfs.reg)) < 0) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
- count = sprintf(buf, "%d\n", val);
-
- DBG(3, "Read bytes: %zd, value: %d", count, val);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_val(struct device* cd, struct device_attribute *attr,
- const char* buf, size_t len)
-{
- struct sn9c102_device* cam;
- u16 value;
- ssize_t count;
- int err;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
- err = sn9c102_write_reg(cam, value, cam->sysfs.reg);
- if (err) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
- DBG(2, "Written SN9C1XX reg. 0x%02X, val. 0x%02X",
- cam->sysfs.reg, value);
- DBG(3, "Written bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t sn9c102_show_i2c_reg(struct device* cd,
- struct device_attribute *attr, char* buf)
-{
- struct sn9c102_device* cam;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg);
-
- DBG(3, "Read bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_i2c_reg(struct device* cd, struct device_attribute *attr,
- const char* buf, size_t len)
-{
- struct sn9c102_device* cam;
- u16 index;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- index = sn9c102_strtou16(buf, len, &count);
- if (!count) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
- cam->sysfs.i2c_reg = index;
-
- DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
- DBG(3, "Written bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t sn9c102_show_i2c_val(struct device* cd,
- struct device_attribute *attr, char* buf)
-{
- struct sn9c102_device* cam;
- ssize_t count;
- int val;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- if (!(cam->sensor.sysfs_ops & SN9C102_I2C_READ)) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENOSYS;
- }
-
- if ((val = sn9c102_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
- count = sprintf(buf, "%d\n", val);
-
- DBG(3, "Read bytes: %zd, value: %d", count, val);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_i2c_val(struct device* cd, struct device_attribute *attr,
- const char* buf, size_t len)
-{
- struct sn9c102_device* cam;
- u16 value;
- ssize_t count;
- int err;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- if (!(cam->sensor.sysfs_ops & SN9C102_I2C_WRITE)) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENOSYS;
- }
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
- err = sn9c102_i2c_write(cam, cam->sysfs.i2c_reg, value);
- if (err) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
- DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X",
- cam->sysfs.i2c_reg, value);
- DBG(3, "Written bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_green(struct device* cd, struct device_attribute *attr,
- const char* buf, size_t len)
-{
- struct sn9c102_device* cam;
- enum sn9c102_bridge bridge;
- ssize_t res = 0;
- u16 value;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- bridge = cam->bridge;
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count)
- return -EINVAL;
-
- switch (bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- if (value > 0x0f)
- return -EINVAL;
- if ((res = sn9c102_store_reg(cd, attr, "0x11", 4)) >= 0)
- res = sn9c102_store_val(cd, attr, buf, len);
- break;
- case BRIDGE_SN9C103:
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (value > 0x7f)
- return -EINVAL;
- if ((res = sn9c102_store_reg(cd, attr, "0x07", 4)) >= 0)
- res = sn9c102_store_val(cd, attr, buf, len);
- break;
- }
-
- return res;
-}
-
-
-static ssize_t
-sn9c102_store_blue(struct device* cd, struct device_attribute *attr,
- const char* buf, size_t len)
-{
- ssize_t res = 0;
- u16 value;
- ssize_t count;
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count || value > 0x7f)
- return -EINVAL;
-
- if ((res = sn9c102_store_reg(cd, attr, "0x06", 4)) >= 0)
- res = sn9c102_store_val(cd, attr, buf, len);
-
- return res;
-}
-
-
-static ssize_t
-sn9c102_store_red(struct device* cd, struct device_attribute *attr,
- const char* buf, size_t len)
-{
- ssize_t res = 0;
- u16 value;
- ssize_t count;
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count || value > 0x7f)
- return -EINVAL;
-
- if ((res = sn9c102_store_reg(cd, attr, "0x05", 4)) >= 0)
- res = sn9c102_store_val(cd, attr, buf, len);
-
- return res;
-}
-
-
-static ssize_t sn9c102_show_frame_header(struct device* cd,
- struct device_attribute *attr,
- char* buf)
-{
- struct sn9c102_device* cam;
- ssize_t count;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam)
- return -ENODEV;
-
- count = sizeof(cam->sysfs.frame_header);
- memcpy(buf, cam->sysfs.frame_header, count);
-
- DBG(3, "Frame header, read bytes: %zd", count);
-
- return count;
-}
-
-
-static DEVICE_ATTR(reg, S_IRUGO | S_IWUSR, sn9c102_show_reg, sn9c102_store_reg);
-static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, sn9c102_show_val, sn9c102_store_val);
-static DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
- sn9c102_show_i2c_reg, sn9c102_store_i2c_reg);
-static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
- sn9c102_show_i2c_val, sn9c102_store_i2c_val);
-static DEVICE_ATTR(green, S_IWUSR, NULL, sn9c102_store_green);
-static DEVICE_ATTR(blue, S_IWUSR, NULL, sn9c102_store_blue);
-static DEVICE_ATTR(red, S_IWUSR, NULL, sn9c102_store_red);
-static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL);
-
-
-static int sn9c102_create_sysfs(struct sn9c102_device* cam)
-{
- struct device *dev = &(cam->v4ldev->dev);
- int err = 0;
-
- if ((err = device_create_file(dev, &dev_attr_reg)))
- goto err_out;
- if ((err = device_create_file(dev, &dev_attr_val)))
- goto err_reg;
- if ((err = device_create_file(dev, &dev_attr_frame_header)))
- goto err_val;
-
- if (cam->sensor.sysfs_ops) {
- if ((err = device_create_file(dev, &dev_attr_i2c_reg)))
- goto err_frame_header;
- if ((err = device_create_file(dev, &dev_attr_i2c_val)))
- goto err_i2c_reg;
- }
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
- if ((err = device_create_file(dev, &dev_attr_green)))
- goto err_i2c_val;
- } else {
- if ((err = device_create_file(dev, &dev_attr_blue)))
- goto err_i2c_val;
- if ((err = device_create_file(dev, &dev_attr_red)))
- goto err_blue;
- }
-
- return 0;
-
-err_blue:
- device_remove_file(dev, &dev_attr_blue);
-err_i2c_val:
- if (cam->sensor.sysfs_ops)
- device_remove_file(dev, &dev_attr_i2c_val);
-err_i2c_reg:
- if (cam->sensor.sysfs_ops)
- device_remove_file(dev, &dev_attr_i2c_reg);
-err_frame_header:
- device_remove_file(dev, &dev_attr_frame_header);
-err_val:
- device_remove_file(dev, &dev_attr_val);
-err_reg:
- device_remove_file(dev, &dev_attr_reg);
-err_out:
- return err;
-}
-#endif /* CONFIG_VIDEO_ADV_DEBUG */
-
-/*****************************************************************************/
-
-static int
-sn9c102_set_pix_format(struct sn9c102_device* cam, struct v4l2_pix_format* pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X ||
- pix->pixelformat == V4L2_PIX_FMT_JPEG) {
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80,
- 0x18);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f,
- 0x18);
- break;
- }
- } else {
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f,
- 0x18);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80,
- 0x18);
- break;
- }
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int
-sn9c102_set_compression(struct sn9c102_device* cam,
- struct v4l2_jpegcompression* compression)
-{
- int i, err = 0;
-
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- if (compression->quality == 0)
- err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01,
- 0x17);
- else if (compression->quality == 1)
- err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe,
- 0x17);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (compression->quality == 0) {
- for (i = 0; i <= 63; i++) {
- err += sn9c102_write_reg(cam,
- SN9C102_Y_QTABLE1[i],
- 0x100 + i);
- err += sn9c102_write_reg(cam,
- SN9C102_UV_QTABLE1[i],
- 0x140 + i);
- }
- err += sn9c102_write_reg(cam, cam->reg[0x18] & 0xbf,
- 0x18);
- } else if (compression->quality == 1) {
- for (i = 0; i <= 63; i++) {
- err += sn9c102_write_reg(cam,
- SN9C102_Y_QTABLE1[i],
- 0x100 + i);
- err += sn9c102_write_reg(cam,
- SN9C102_UV_QTABLE1[i],
- 0x140 + i);
- }
- err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x40,
- 0x18);
- }
- break;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int sn9c102_set_scale(struct sn9c102_device* cam, u8 scale)
-{
- u8 r = 0;
- int err = 0;
-
- if (scale == 1)
- r = cam->reg[0x18] & 0xcf;
- else if (scale == 2) {
- r = cam->reg[0x18] & 0xcf;
- r |= 0x10;
- } else if (scale == 4)
- r = cam->reg[0x18] | 0x20;
-
- err += sn9c102_write_reg(cam, r, 0x18);
- if (err)
- return -EIO;
-
- PDBGG("Scaling factor: %u", scale);
-
- return 0;
-}
-
-
-static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect)
-{
- struct sn9c102_sensor* s = &cam->sensor;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left),
- v_start = (u8)(rect->top - s->cropcap.bounds.top),
- h_size = (u8)(rect->width / 16),
- v_size = (u8)(rect->height / 16);
- int err = 0;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
- err += sn9c102_write_reg(cam, h_size, 0x15);
- err += sn9c102_write_reg(cam, v_size, 0x16);
- if (err)
- return -EIO;
-
- PDBGG("h_start, v_start, h_size, v_size, ho_size, vo_size "
- "%u %u %u %u", h_start, v_start, h_size, v_size);
-
- return 0;
-}
-
-
-static int sn9c102_init(struct sn9c102_device* cam)
-{
- struct sn9c102_sensor* s = &cam->sensor;
- struct v4l2_control ctrl;
- struct v4l2_queryctrl *qctrl;
- struct v4l2_rect* rect;
- u8 i = 0;
- int err = 0;
-
- if (!(cam->state & DEV_INITIALIZED)) {
- mutex_init(&cam->open_mutex);
- init_waitqueue_head(&cam->wait_open);
- qctrl = s->qctrl;
- rect = &(s->cropcap.defrect);
- } else { /* use current values */
- qctrl = s->_qctrl;
- rect = &(s->_rect);
- }
-
- err += sn9c102_set_scale(cam, rect->width / s->pix_format.width);
- err += sn9c102_set_crop(cam, rect);
- if (err)
- return err;
-
- if (s->init) {
- err = s->init(cam);
- if (err) {
- DBG(3, "Sensor initialization failed");
- return err;
- }
- }
-
- if (!(cam->state & DEV_INITIALIZED))
- if (cam->bridge == BRIDGE_SN9C101 ||
- cam->bridge == BRIDGE_SN9C102 ||
- cam->bridge == BRIDGE_SN9C103) {
- if (s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
- s->pix_format.pixelformat= V4L2_PIX_FMT_SBGGR8;
- cam->compression.quality = cam->reg[0x17] & 0x01 ?
- 0 : 1;
- } else {
- if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
- s->pix_format.pixelformat = V4L2_PIX_FMT_JPEG;
- cam->compression.quality = cam->reg[0x18] & 0x40 ?
- 0 : 1;
- err += sn9c102_set_compression(cam, &cam->compression);
- }
- else
- err += sn9c102_set_compression(cam, &cam->compression);
- err += sn9c102_set_pix_format(cam, &s->pix_format);
- if (s->set_pix_format)
- err += s->set_pix_format(cam, &s->pix_format);
- if (err)
- return err;
-
- if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X ||
- s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
- DBG(3, "Compressed video format is active, quality %d",
- cam->compression.quality);
- else
- DBG(3, "Uncompressed video format is active");
-
- if (s->set_crop)
- if ((err = s->set_crop(cam, rect))) {
- DBG(3, "set_crop() failed");
- return err;
- }
-
- if (s->set_ctrl) {
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
- if (s->qctrl[i].id != 0 &&
- !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
- ctrl.id = s->qctrl[i].id;
- ctrl.value = qctrl[i].default_value;
- err = s->set_ctrl(cam, &ctrl);
- if (err) {
- DBG(3, "Set %s control failed",
- s->qctrl[i].name);
- return err;
- }
- DBG(3, "Image sensor supports '%s' control",
- s->qctrl[i].name);
- }
- }
-
- if (!(cam->state & DEV_INITIALIZED)) {
- mutex_init(&cam->fileop_mutex);
- spin_lock_init(&cam->queue_lock);
- init_waitqueue_head(&cam->wait_frame);
- init_waitqueue_head(&cam->wait_stream);
- cam->nreadbuffers = 2;
- memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
- memcpy(&(s->_rect), &(s->cropcap.defrect),
- sizeof(struct v4l2_rect));
- cam->state |= DEV_INITIALIZED;
- }
-
- DBG(2, "Initialization succeeded");
- return 0;
-}
-
-/*****************************************************************************/
-
-static void sn9c102_release_resources(struct kref *kref)
-{
- struct sn9c102_device *cam;
-
- mutex_lock(&sn9c102_sysfs_lock);
-
- cam = container_of(kref, struct sn9c102_device, kref);
-
- DBG(2, "V4L2 device %s deregistered",
- video_device_node_name(cam->v4ldev));
- video_set_drvdata(cam->v4ldev, NULL);
- video_unregister_device(cam->v4ldev);
- usb_put_dev(cam->usbdev);
- kfree(cam->control_buffer);
- kfree(cam);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
-}
-
-
-static int sn9c102_open(struct file *filp)
-{
- struct sn9c102_device* cam;
- int err = 0;
-
- /*
- A read_trylock() in open() is the only safe way to prevent race
- conditions with disconnect(), one close() and multiple (not
- necessarily simultaneous) attempts to open(). For example, it
- prevents from waiting for a second access, while the device
- structure is being deallocated, after a possible disconnect() and
- during a following close() holding the write lock: given that, after
- this deallocation, no access will be possible anymore, using the
- non-trylock version would have let open() gain the access to the
- device structure improperly.
- For this reason the lock must also not be per-device.
- */
- if (!down_read_trylock(&sn9c102_dev_lock))
- return -ERESTARTSYS;
-
- cam = video_drvdata(filp);
-
- if (wait_for_completion_interruptible(&cam->probe)) {
- up_read(&sn9c102_dev_lock);
- return -ERESTARTSYS;
- }
-
- kref_get(&cam->kref);
-
- /*
- Make sure to isolate all the simultaneous opens.
- */
- if (mutex_lock_interruptible(&cam->open_mutex)) {
- kref_put(&cam->kref, sn9c102_release_resources);
- up_read(&sn9c102_dev_lock);
- return -ERESTARTSYS;
- }
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- err = -ENODEV;
- goto out;
- }
-
- if (cam->users) {
- DBG(2, "Device %s is already in use",
- video_device_node_name(cam->v4ldev));
- DBG(3, "Simultaneous opens are not supported");
- /*
- open() must follow the open flags and should block
- eventually while the device is in use.
- */
- if ((filp->f_flags & O_NONBLOCK) ||
- (filp->f_flags & O_NDELAY)) {
- err = -EWOULDBLOCK;
- goto out;
- }
- DBG(2, "A blocking open() has been requested. Wait for the "
- "device to be released...");
- up_read(&sn9c102_dev_lock);
- /*
- We will not release the "open_mutex" lock, so that only one
- process can be in the wait queue below. This way the process
- will be sleeping while holding the lock, without losing its
- priority after any wake_up().
- */
- err = wait_event_interruptible_exclusive(cam->wait_open,
- (cam->state & DEV_DISCONNECTED)
- || !cam->users);
- down_read(&sn9c102_dev_lock);
- if (err)
- goto out;
- if (cam->state & DEV_DISCONNECTED) {
- err = -ENODEV;
- goto out;
- }
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- err = sn9c102_init(cam);
- if (err) {
- DBG(1, "Initialization failed again. "
- "I will retry on next open().");
- goto out;
- }
- cam->state &= ~DEV_MISCONFIGURED;
- }
-
- if ((err = sn9c102_start_transfer(cam)))
- goto out;
-
- filp->private_data = cam;
- cam->users++;
- cam->io = IO_NONE;
- cam->stream = STREAM_OFF;
- cam->nbuffers = 0;
- cam->frame_count = 0;
- sn9c102_empty_framequeues(cam);
-
- DBG(3, "Video device %s is open", video_device_node_name(cam->v4ldev));
-
-out:
- mutex_unlock(&cam->open_mutex);
- if (err)
- kref_put(&cam->kref, sn9c102_release_resources);
-
- up_read(&sn9c102_dev_lock);
- return err;
-}
-
-
-static int sn9c102_release(struct file *filp)
-{
- struct sn9c102_device* cam;
-
- down_write(&sn9c102_dev_lock);
-
- cam = video_drvdata(filp);
-
- sn9c102_stop_transfer(cam);
- sn9c102_release_buffers(cam);
- cam->users--;
- wake_up_interruptible_nr(&cam->wait_open, 1);
-
- DBG(3, "Video device %s closed", video_device_node_name(cam->v4ldev));
-
- kref_put(&cam->kref, sn9c102_release_resources);
-
- up_write(&sn9c102_dev_lock);
-
- return 0;
-}
-
-
-static ssize_t
-sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
- struct sn9c102_frame_t* f, * i;
- unsigned long lock_flags;
- long timeout;
- int err = 0;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- if (cam->io == IO_MMAP) {
- DBG(3, "Close and open the device again to choose "
- "the read method");
- mutex_unlock(&cam->fileop_mutex);
- return -EBUSY;
- }
-
- if (cam->io == IO_NONE) {
- if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) {
- DBG(1, "read() failed, not enough memory");
- mutex_unlock(&cam->fileop_mutex);
- return -ENOMEM;
- }
- cam->io = IO_READ;
- cam->stream = STREAM_ON;
- }
-
- if (list_empty(&cam->inqueue)) {
- if (!list_empty(&cam->outqueue))
- sn9c102_empty_framequeues(cam);
- sn9c102_queue_unusedframes(cam);
- }
-
- if (!count) {
- mutex_unlock(&cam->fileop_mutex);
- return 0;
- }
-
- if (list_empty(&cam->outqueue)) {
- if (filp->f_flags & O_NONBLOCK) {
- mutex_unlock(&cam->fileop_mutex);
- return -EAGAIN;
- }
- if (!cam->module_param.frame_timeout) {
- err = wait_event_interruptible
- ( cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED) );
- if (err) {
- mutex_unlock(&cam->fileop_mutex);
- return err;
- }
- } else {
- timeout = wait_event_interruptible_timeout
- ( cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED),
- msecs_to_jiffies(
- cam->module_param.frame_timeout * 1000
- )
- );
- if (timeout < 0) {
- mutex_unlock(&cam->fileop_mutex);
- return timeout;
- } else if (timeout == 0 &&
- !(cam->state & DEV_DISCONNECTED)) {
- DBG(1, "Video frame timeout elapsed");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
- }
- if (cam->state & DEV_DISCONNECTED) {
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
- if (cam->state & DEV_MISCONFIGURED) {
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
- }
-
- f = list_entry(cam->outqueue.prev, struct sn9c102_frame_t, frame);
-
- if (count > f->buf.bytesused)
- count = f->buf.bytesused;
-
- if (copy_to_user(buf, f->bufmem, count)) {
- err = -EFAULT;
- goto exit;
- }
- *f_pos += count;
-
-exit:
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_for_each_entry(i, &cam->outqueue, frame)
- i->state = F_UNUSED;
- INIT_LIST_HEAD(&cam->outqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-
- sn9c102_queue_unusedframes(cam);
-
- PDBGG("Frame #%lu, bytes read: %zu",
- (unsigned long)f->buf.index, count);
-
- mutex_unlock(&cam->fileop_mutex);
-
- return count;
-}
-
-
-static unsigned int sn9c102_poll(struct file *filp, poll_table *wait)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
- struct sn9c102_frame_t* f;
- unsigned long lock_flags;
- unsigned int mask = 0;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return POLLERR;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- goto error;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- goto error;
- }
-
- if (cam->io == IO_NONE) {
- if (!sn9c102_request_buffers(cam, cam->nreadbuffers,
- IO_READ)) {
- DBG(1, "poll() failed, not enough memory");
- goto error;
- }
- cam->io = IO_READ;
- cam->stream = STREAM_ON;
- }
-
- if (cam->io == IO_READ) {
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_for_each_entry(f, &cam->outqueue, frame)
- f->state = F_UNUSED;
- INIT_LIST_HEAD(&cam->outqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
- sn9c102_queue_unusedframes(cam);
- }
-
- poll_wait(filp, &cam->wait_frame, wait);
-
- if (!list_empty(&cam->outqueue))
- mask |= POLLIN | POLLRDNORM;
-
- mutex_unlock(&cam->fileop_mutex);
-
- return mask;
-
-error:
- mutex_unlock(&cam->fileop_mutex);
- return POLLERR;
-}
-
-
-static void sn9c102_vm_open(struct vm_area_struct* vma)
-{
- struct sn9c102_frame_t* f = vma->vm_private_data;
- f->vma_use_count++;
-}
-
-
-static void sn9c102_vm_close(struct vm_area_struct* vma)
-{
- /* NOTE: buffers are not freed here */
- struct sn9c102_frame_t* f = vma->vm_private_data;
- f->vma_use_count--;
-}
-
-
-static const struct vm_operations_struct sn9c102_vm_ops = {
- .open = sn9c102_vm_open,
- .close = sn9c102_vm_close,
-};
-
-
-static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
- unsigned long size = vma->vm_end - vma->vm_start,
- start = vma->vm_start;
- void *pos;
- u32 i;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- if (!(vma->vm_flags & (VM_WRITE | VM_READ))) {
- mutex_unlock(&cam->fileop_mutex);
- return -EACCES;
- }
-
- if (cam->io != IO_MMAP ||
- size != PAGE_ALIGN(cam->frame[0].buf.length)) {
- mutex_unlock(&cam->fileop_mutex);
- return -EINVAL;
- }
-
- for (i = 0; i < cam->nbuffers; i++) {
- if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
- break;
- }
- if (i == cam->nbuffers) {
- mutex_unlock(&cam->fileop_mutex);
- return -EINVAL;
- }
-
- vma->vm_flags |= VM_IO;
- vma->vm_flags |= VM_RESERVED;
-
- pos = cam->frame[i].bufmem;
- while (size > 0) { /* size is page-aligned */
- if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
- mutex_unlock(&cam->fileop_mutex);
- return -EAGAIN;
- }
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- vma->vm_ops = &sn9c102_vm_ops;
- vma->vm_private_data = &cam->frame[i];
- sn9c102_vm_open(vma);
-
- mutex_unlock(&cam->fileop_mutex);
-
- return 0;
-}
-
-/*****************************************************************************/
-
-static int
-sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_capability cap = {
- .driver = "sn9c102",
- .version = LINUX_VERSION_CODE,
- .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING,
- };
-
- strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
- if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
- strlcpy(cap.bus_info, dev_name(&cam->usbdev->dev),
- sizeof(cap.bus_info));
-
- if (copy_to_user(arg, &cap, sizeof(cap)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_input i;
-
- if (copy_from_user(&i, arg, sizeof(i)))
- return -EFAULT;
-
- if (i.index)
- return -EINVAL;
-
- memset(&i, 0, sizeof(i));
- strcpy(i.name, "Camera");
- i.type = V4L2_INPUT_TYPE_CAMERA;
- i.capabilities = V4L2_IN_CAP_STD;
-
- if (copy_to_user(arg, &i, sizeof(i)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_input(struct sn9c102_device* cam, void __user * arg)
-{
- int index = 0;
-
- if (copy_to_user(arg, &index, sizeof(index)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_input(struct sn9c102_device* cam, void __user * arg)
-{
- int index;
-
- if (copy_from_user(&index, arg, sizeof(index)))
- return -EFAULT;
-
- if (index != 0)
- return -EINVAL;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg)
-{
- struct sn9c102_sensor* s = &cam->sensor;
- struct v4l2_queryctrl qc;
- u8 i;
-
- if (copy_from_user(&qc, arg, sizeof(qc)))
- return -EFAULT;
-
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
- if (qc.id && qc.id == s->qctrl[i].id) {
- memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
- if (copy_to_user(arg, &qc, sizeof(qc)))
- return -EFAULT;
- return 0;
- }
-
- return -EINVAL;
-}
-
-
-static int
-sn9c102_vidioc_g_ctrl(struct sn9c102_device* cam, void __user * arg)
-{
- struct sn9c102_sensor* s = &cam->sensor;
- struct v4l2_control ctrl;
- int err = 0;
- u8 i;
-
- if (!s->get_ctrl && !s->set_ctrl)
- return -EINVAL;
-
- if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
- return -EFAULT;
-
- if (!s->get_ctrl) {
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
- if (ctrl.id && ctrl.id == s->qctrl[i].id) {
- ctrl.value = s->_qctrl[i].default_value;
- goto exit;
- }
- return -EINVAL;
- } else
- err = s->get_ctrl(cam, &ctrl);
-
-exit:
- if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
- return -EFAULT;
-
- PDBGG("VIDIOC_G_CTRL: id %lu, value %lu",
- (unsigned long)ctrl.id, (unsigned long)ctrl.value);
-
- return err;
-}
-
-
-static int
-sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg)
-{
- struct sn9c102_sensor* s = &cam->sensor;
- struct v4l2_control ctrl;
- u8 i;
- int err = 0;
-
- if (!s->set_ctrl)
- return -EINVAL;
-
- if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
- return -EFAULT;
-
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) {
- if (ctrl.id == s->qctrl[i].id) {
- if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)
- return -EINVAL;
- if (ctrl.value < s->qctrl[i].minimum ||
- ctrl.value > s->qctrl[i].maximum)
- return -ERANGE;
- ctrl.value -= ctrl.value % s->qctrl[i].step;
- break;
- }
- }
- if (i == ARRAY_SIZE(s->qctrl))
- return -EINVAL;
- if ((err = s->set_ctrl(cam, &ctrl)))
- return err;
-
- s->_qctrl[i].default_value = ctrl.value;
-
- PDBGG("VIDIOC_S_CTRL: id %lu, value %lu",
- (unsigned long)ctrl.id, (unsigned long)ctrl.value);
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_cropcap(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_cropcap* cc = &(cam->sensor.cropcap);
-
- cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- cc->pixelaspect.numerator = 1;
- cc->pixelaspect.denominator = 1;
-
- if (copy_to_user(arg, cc, sizeof(*cc)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg)
-{
- struct sn9c102_sensor* s = &cam->sensor;
- struct v4l2_crop crop = {
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- };
-
- memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
-
- if (copy_to_user(arg, &crop, sizeof(crop)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
-{
- struct sn9c102_sensor* s = &cam->sensor;
- struct v4l2_crop crop;
- struct v4l2_rect* rect;
- struct v4l2_rect* bounds = &(s->cropcap.bounds);
- struct v4l2_pix_format* pix_format = &(s->pix_format);
- u8 scale;
- const enum sn9c102_stream_state stream = cam->stream;
- const u32 nbuffers = cam->nbuffers;
- u32 i;
- int err = 0;
-
- if (copy_from_user(&crop, arg, sizeof(crop)))
- return -EFAULT;
-
- rect = &(crop.c);
-
- if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (cam->module_param.force_munmap)
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].vma_use_count) {
- DBG(3, "VIDIOC_S_CROP failed. "
- "Unmap the buffers first.");
- return -EBUSY;
- }
-
- /* Preserve R,G or B origin */
- rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L;
- rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L;
-
- if (rect->width < 16)
- rect->width = 16;
- if (rect->height < 16)
- rect->height = 16;
- if (rect->width > bounds->width)
- rect->width = bounds->width;
- if (rect->height > bounds->height)
- rect->height = bounds->height;
- if (rect->left < bounds->left)
- rect->left = bounds->left;
- if (rect->top < bounds->top)
- rect->top = bounds->top;
- if (rect->left + rect->width > bounds->left + bounds->width)
- rect->left = bounds->left+bounds->width - rect->width;
- if (rect->top + rect->height > bounds->top + bounds->height)
- rect->top = bounds->top+bounds->height - rect->height;
-
- rect->width &= ~15L;
- rect->height &= ~15L;
-
- if (SN9C102_PRESERVE_IMGSCALE) {
- /* Calculate the actual scaling factor */
- u32 a, b;
- a = rect->width * rect->height;
- b = pix_format->width * pix_format->height;
- scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
- } else
- scale = 1;
-
- if (cam->stream == STREAM_ON)
- if ((err = sn9c102_stream_interrupt(cam)))
- return err;
-
- if (copy_to_user(arg, &crop, sizeof(crop))) {
- cam->stream = stream;
- return -EFAULT;
- }
-
- if (cam->module_param.force_munmap || cam->io == IO_READ)
- sn9c102_release_buffers(cam);
-
- err = sn9c102_set_crop(cam, rect);
- if (s->set_crop)
- err += s->set_crop(cam, rect);
- err += sn9c102_set_scale(cam, scale);
-
- if (err) { /* atomic, no rollback in ioctl() */
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- s->pix_format.width = rect->width/scale;
- s->pix_format.height = rect->height/scale;
- memcpy(&(s->_rect), rect, sizeof(*rect));
-
- if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
- nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -ENOMEM;
- }
-
- if (cam->io == IO_READ)
- sn9c102_empty_framequeues(cam);
- else if (cam->module_param.force_munmap)
- sn9c102_requeue_outqueue(cam);
-
- cam->stream = stream;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_enum_framesizes(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_frmsizeenum frmsize;
-
- if (copy_from_user(&frmsize, arg, sizeof(frmsize)))
- return -EFAULT;
-
- if (frmsize.index != 0)
- return -EINVAL;
-
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- if (frmsize.pixel_format != V4L2_PIX_FMT_SN9C10X &&
- frmsize.pixel_format != V4L2_PIX_FMT_SBGGR8)
- return -EINVAL;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (frmsize.pixel_format != V4L2_PIX_FMT_JPEG &&
- frmsize.pixel_format != V4L2_PIX_FMT_SBGGR8)
- return -EINVAL;
- }
-
- frmsize.type = V4L2_FRMSIZE_TYPE_STEPWISE;
- frmsize.stepwise.min_width = frmsize.stepwise.step_width = 16;
- frmsize.stepwise.min_height = frmsize.stepwise.step_height = 16;
- frmsize.stepwise.max_width = cam->sensor.cropcap.bounds.width;
- frmsize.stepwise.max_height = cam->sensor.cropcap.bounds.height;
- memset(&frmsize.reserved, 0, sizeof(frmsize.reserved));
-
- if (copy_to_user(arg, &frmsize, sizeof(frmsize)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_fmtdesc fmtd;
-
- if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
- return -EFAULT;
-
- if (fmtd.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (fmtd.index == 0) {
- strcpy(fmtd.description, "bayer rgb");
- fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
- } else if (fmtd.index == 1) {
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- strcpy(fmtd.description, "compressed");
- fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- strcpy(fmtd.description, "JPEG");
- fmtd.pixelformat = V4L2_PIX_FMT_JPEG;
- break;
- }
- fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
- } else
- return -EINVAL;
-
- fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
-
- if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_format format;
- struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format);
-
- if (copy_from_user(&format, arg, sizeof(format)))
- return -EFAULT;
-
- if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- pfmt->colorspace = (pfmt->pixelformat == V4L2_PIX_FMT_JPEG) ?
- V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
- pfmt->bytesperline = (pfmt->pixelformat == V4L2_PIX_FMT_SN9C10X ||
- pfmt->pixelformat == V4L2_PIX_FMT_JPEG)
- ? 0 : (pfmt->width * pfmt->priv) / 8;
- pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
- pfmt->field = V4L2_FIELD_NONE;
- memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
-
- if (copy_to_user(arg, &format, sizeof(format)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
- void __user * arg)
-{
- struct sn9c102_sensor* s = &cam->sensor;
- struct v4l2_format format;
- struct v4l2_pix_format* pix;
- struct v4l2_pix_format* pfmt = &(s->pix_format);
- struct v4l2_rect* bounds = &(s->cropcap.bounds);
- struct v4l2_rect rect;
- u8 scale;
- const enum sn9c102_stream_state stream = cam->stream;
- const u32 nbuffers = cam->nbuffers;
- u32 i;
- int err = 0;
-
- if (copy_from_user(&format, arg, sizeof(format)))
- return -EFAULT;
-
- pix = &(format.fmt.pix);
-
- if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- memcpy(&rect, &(s->_rect), sizeof(rect));
-
- { /* calculate the actual scaling factor */
- u32 a, b;
- a = rect.width * rect.height;
- b = pix->width * pix->height;
- scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
- }
-
- rect.width = scale * pix->width;
- rect.height = scale * pix->height;
-
- if (rect.width < 16)
- rect.width = 16;
- if (rect.height < 16)
- rect.height = 16;
- if (rect.width > bounds->left + bounds->width - rect.left)
- rect.width = bounds->left + bounds->width - rect.left;
- if (rect.height > bounds->top + bounds->height - rect.top)
- rect.height = bounds->top + bounds->height - rect.top;
-
- rect.width &= ~15L;
- rect.height &= ~15L;
-
- { /* adjust the scaling factor */
- u32 a, b;
- a = rect.width * rect.height;
- b = pix->width * pix->height;
- scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
- }
-
- pix->width = rect.width / scale;
- pix->height = rect.height / scale;
-
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
- pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
- pix->pixelformat = pfmt->pixelformat;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (pix->pixelformat != V4L2_PIX_FMT_JPEG &&
- pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
- pix->pixelformat = pfmt->pixelformat;
- break;
- }
- pix->priv = pfmt->priv; /* bpp */
- pix->colorspace = (pix->pixelformat == V4L2_PIX_FMT_JPEG) ?
- V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
- pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X ||
- pix->pixelformat == V4L2_PIX_FMT_JPEG)
- ? 0 : (pix->width * pix->priv) / 8;
- pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
- pix->field = V4L2_FIELD_NONE;
-
- if (cmd == VIDIOC_TRY_FMT) {
- if (copy_to_user(arg, &format, sizeof(format)))
- return -EFAULT;
- return 0;
- }
-
- if (cam->module_param.force_munmap)
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].vma_use_count) {
- DBG(3, "VIDIOC_S_FMT failed. Unmap the "
- "buffers first.");
- return -EBUSY;
- }
-
- if (cam->stream == STREAM_ON)
- if ((err = sn9c102_stream_interrupt(cam)))
- return err;
-
- if (copy_to_user(arg, &format, sizeof(format))) {
- cam->stream = stream;
- return -EFAULT;
- }
-
- if (cam->module_param.force_munmap || cam->io == IO_READ)
- sn9c102_release_buffers(cam);
-
- err += sn9c102_set_pix_format(cam, pix);
- err += sn9c102_set_crop(cam, &rect);
- if (s->set_pix_format)
- err += s->set_pix_format(cam, pix);
- if (s->set_crop)
- err += s->set_crop(cam, &rect);
- err += sn9c102_set_scale(cam, scale);
-
- if (err) { /* atomic, no rollback in ioctl() */
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- memcpy(pfmt, pix, sizeof(*pix));
- memcpy(&(s->_rect), &rect, sizeof(rect));
-
- if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
- nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -ENOMEM;
- }
-
- if (cam->io == IO_READ)
- sn9c102_empty_framequeues(cam);
- else if (cam->module_param.force_munmap)
- sn9c102_requeue_outqueue(cam);
-
- cam->stream = stream;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_jpegcomp(struct sn9c102_device* cam, void __user * arg)
-{
- if (copy_to_user(arg, &cam->compression, sizeof(cam->compression)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_jpegcompression jc;
- const enum sn9c102_stream_state stream = cam->stream;
- int err = 0;
-
- if (copy_from_user(&jc, arg, sizeof(jc)))
- return -EFAULT;
-
- if (jc.quality != 0 && jc.quality != 1)
- return -EINVAL;
-
- if (cam->stream == STREAM_ON)
- if ((err = sn9c102_stream_interrupt(cam)))
- return err;
-
- err += sn9c102_set_compression(cam, &jc);
- if (err) { /* atomic, no rollback in ioctl() */
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware problems. "
- "To use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- cam->compression.quality = jc.quality;
-
- cam->stream = stream;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_requestbuffers rb;
- u32 i;
- int err;
-
- if (copy_from_user(&rb, arg, sizeof(rb)))
- return -EFAULT;
-
- if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- rb.memory != V4L2_MEMORY_MMAP)
- return -EINVAL;
-
- if (cam->io == IO_READ) {
- DBG(3, "Close and open the device again to choose the mmap "
- "I/O method");
- return -EBUSY;
- }
-
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].vma_use_count) {
- DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are "
- "still mapped.");
- return -EBUSY;
- }
-
- if (cam->stream == STREAM_ON)
- if ((err = sn9c102_stream_interrupt(cam)))
- return err;
-
- sn9c102_empty_framequeues(cam);
-
- sn9c102_release_buffers(cam);
- if (rb.count)
- rb.count = sn9c102_request_buffers(cam, rb.count, IO_MMAP);
-
- if (copy_to_user(arg, &rb, sizeof(rb))) {
- sn9c102_release_buffers(cam);
- cam->io = IO_NONE;
- return -EFAULT;
- }
-
- cam->io = rb.count ? IO_MMAP : IO_NONE;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_querybuf(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_buffer b;
-
- if (copy_from_user(&b, arg, sizeof(b)))
- return -EFAULT;
-
- if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- b.index >= cam->nbuffers || cam->io != IO_MMAP)
- return -EINVAL;
-
- memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
-
- if (cam->frame[b.index].vma_use_count)
- b.flags |= V4L2_BUF_FLAG_MAPPED;
-
- if (cam->frame[b.index].state == F_DONE)
- b.flags |= V4L2_BUF_FLAG_DONE;
- else if (cam->frame[b.index].state != F_UNUSED)
- b.flags |= V4L2_BUF_FLAG_QUEUED;
-
- if (copy_to_user(arg, &b, sizeof(b)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_qbuf(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_buffer b;
- unsigned long lock_flags;
-
- if (copy_from_user(&b, arg, sizeof(b)))
- return -EFAULT;
-
- if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- b.index >= cam->nbuffers || cam->io != IO_MMAP)
- return -EINVAL;
-
- if (cam->frame[b.index].state != F_UNUSED)
- return -EINVAL;
-
- cam->frame[b.index].state = F_QUEUED;
-
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-
- PDBGG("Frame #%lu queued", (unsigned long)b.index);
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp,
- void __user * arg)
-{
- struct v4l2_buffer b;
- struct sn9c102_frame_t *f;
- unsigned long lock_flags;
- long timeout;
- int err = 0;
-
- if (copy_from_user(&b, arg, sizeof(b)))
- return -EFAULT;
-
- if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
- return -EINVAL;
-
- if (list_empty(&cam->outqueue)) {
- if (cam->stream == STREAM_OFF)
- return -EINVAL;
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- if (!cam->module_param.frame_timeout) {
- err = wait_event_interruptible
- ( cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED) );
- if (err)
- return err;
- } else {
- timeout = wait_event_interruptible_timeout
- ( cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED),
- cam->module_param.frame_timeout *
- 1000 * msecs_to_jiffies(1) );
- if (timeout < 0)
- return timeout;
- else if (timeout == 0 &&
- !(cam->state & DEV_DISCONNECTED)) {
- DBG(1, "Video frame timeout elapsed");
- return -EIO;
- }
- }
- if (cam->state & DEV_DISCONNECTED)
- return -ENODEV;
- if (cam->state & DEV_MISCONFIGURED)
- return -EIO;
- }
-
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- f = list_entry(cam->outqueue.next, struct sn9c102_frame_t, frame);
- list_del(cam->outqueue.next);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-
- f->state = F_UNUSED;
-
- memcpy(&b, &f->buf, sizeof(b));
- if (f->vma_use_count)
- b.flags |= V4L2_BUF_FLAG_MAPPED;
-
- if (copy_to_user(arg, &b, sizeof(b)))
- return -EFAULT;
-
- PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg)
-{
- int type;
-
- if (copy_from_user(&type, arg, sizeof(type)))
- return -EFAULT;
-
- if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
- return -EINVAL;
-
- cam->stream = STREAM_ON;
-
- DBG(3, "Stream on");
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_streamoff(struct sn9c102_device* cam, void __user * arg)
-{
- int type, err;
-
- if (copy_from_user(&type, arg, sizeof(type)))
- return -EFAULT;
-
- if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
- return -EINVAL;
-
- if (cam->stream == STREAM_ON)
- if ((err = sn9c102_stream_interrupt(cam)))
- return err;
-
- sn9c102_empty_framequeues(cam);
-
- DBG(3, "Stream off");
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_parm(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_streamparm sp;
-
- if (copy_from_user(&sp, arg, sizeof(sp)))
- return -EFAULT;
-
- if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- sp.parm.capture.extendedmode = 0;
- sp.parm.capture.readbuffers = cam->nreadbuffers;
-
- if (copy_to_user(arg, &sp, sizeof(sp)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_parm(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_streamparm sp;
-
- if (copy_from_user(&sp, arg, sizeof(sp)))
- return -EFAULT;
-
- if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- sp.parm.capture.extendedmode = 0;
-
- if (sp.parm.capture.readbuffers == 0)
- sp.parm.capture.readbuffers = cam->nreadbuffers;
-
- if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES)
- sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES;
-
- if (copy_to_user(arg, &sp, sizeof(sp)))
- return -EFAULT;
-
- cam->nreadbuffers = sp.parm.capture.readbuffers;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_enumaudio(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_audio audio;
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
- return -EINVAL;
-
- if (copy_from_user(&audio, arg, sizeof(audio)))
- return -EFAULT;
-
- if (audio.index != 0)
- return -EINVAL;
-
- strcpy(audio.name, "Microphone");
- audio.capability = 0;
- audio.mode = 0;
-
- if (copy_to_user(arg, &audio, sizeof(audio)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_audio(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_audio audio;
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
- return -EINVAL;
-
- if (copy_from_user(&audio, arg, sizeof(audio)))
- return -EFAULT;
-
- memset(&audio, 0, sizeof(audio));
- strcpy(audio.name, "Microphone");
-
- if (copy_to_user(arg, &audio, sizeof(audio)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_audio(struct sn9c102_device* cam, void __user * arg)
-{
- struct v4l2_audio audio;
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
- return -EINVAL;
-
- if (copy_from_user(&audio, arg, sizeof(audio)))
- return -EFAULT;
-
- if (audio.index != 0)
- return -EINVAL;
-
- return 0;
-}
-
-
-static long sn9c102_ioctl_v4l2(struct file *filp,
- unsigned int cmd, void __user *arg)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
-
- switch (cmd) {
-
- case VIDIOC_QUERYCAP:
- return sn9c102_vidioc_querycap(cam, arg);
-
- case VIDIOC_ENUMINPUT:
- return sn9c102_vidioc_enuminput(cam, arg);
-
- case VIDIOC_G_INPUT:
- return sn9c102_vidioc_g_input(cam, arg);
-
- case VIDIOC_S_INPUT:
- return sn9c102_vidioc_s_input(cam, arg);
-
- case VIDIOC_QUERYCTRL:
- return sn9c102_vidioc_query_ctrl(cam, arg);
-
- case VIDIOC_G_CTRL:
- return sn9c102_vidioc_g_ctrl(cam, arg);
-
- case VIDIOC_S_CTRL:
- return sn9c102_vidioc_s_ctrl(cam, arg);
-
- case VIDIOC_CROPCAP:
- return sn9c102_vidioc_cropcap(cam, arg);
-
- case VIDIOC_G_CROP:
- return sn9c102_vidioc_g_crop(cam, arg);
-
- case VIDIOC_S_CROP:
- return sn9c102_vidioc_s_crop(cam, arg);
-
- case VIDIOC_ENUM_FRAMESIZES:
- return sn9c102_vidioc_enum_framesizes(cam, arg);
-
- case VIDIOC_ENUM_FMT:
- return sn9c102_vidioc_enum_fmt(cam, arg);
-
- case VIDIOC_G_FMT:
- return sn9c102_vidioc_g_fmt(cam, arg);
-
- case VIDIOC_TRY_FMT:
- case VIDIOC_S_FMT:
- return sn9c102_vidioc_try_s_fmt(cam, cmd, arg);
-
- case VIDIOC_G_JPEGCOMP:
- return sn9c102_vidioc_g_jpegcomp(cam, arg);
-
- case VIDIOC_S_JPEGCOMP:
- return sn9c102_vidioc_s_jpegcomp(cam, arg);
-
- case VIDIOC_REQBUFS:
- return sn9c102_vidioc_reqbufs(cam, arg);
-
- case VIDIOC_QUERYBUF:
- return sn9c102_vidioc_querybuf(cam, arg);
-
- case VIDIOC_QBUF:
- return sn9c102_vidioc_qbuf(cam, arg);
-
- case VIDIOC_DQBUF:
- return sn9c102_vidioc_dqbuf(cam, filp, arg);
-
- case VIDIOC_STREAMON:
- return sn9c102_vidioc_streamon(cam, arg);
-
- case VIDIOC_STREAMOFF:
- return sn9c102_vidioc_streamoff(cam, arg);
-
- case VIDIOC_G_PARM:
- return sn9c102_vidioc_g_parm(cam, arg);
-
- case VIDIOC_S_PARM:
- return sn9c102_vidioc_s_parm(cam, arg);
-
- case VIDIOC_ENUMAUDIO:
- return sn9c102_vidioc_enumaudio(cam, arg);
-
- case VIDIOC_G_AUDIO:
- return sn9c102_vidioc_g_audio(cam, arg);
-
- case VIDIOC_S_AUDIO:
- return sn9c102_vidioc_s_audio(cam, arg);
-
- default:
- return -ENOTTY;
-
- }
-}
-
-
-static long sn9c102_ioctl(struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
- int err = 0;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- V4LDBG(3, "sn9c102", cmd);
-
- err = sn9c102_ioctl_v4l2(filp, cmd, (void __user *)arg);
-
- mutex_unlock(&cam->fileop_mutex);
-
- return err;
-}
-
-/*****************************************************************************/
-
-static const struct v4l2_file_operations sn9c102_fops = {
- .owner = THIS_MODULE,
- .open = sn9c102_open,
- .release = sn9c102_release,
- .unlocked_ioctl = sn9c102_ioctl,
- .read = sn9c102_read,
- .poll = sn9c102_poll,
- .mmap = sn9c102_mmap,
-};
-
-/*****************************************************************************/
-
-/* It exists a single interface only. We do not need to validate anything. */
-static int
-sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct sn9c102_device* cam;
- static unsigned int dev_nr;
- unsigned int i;
- int err = 0, r;
-
- if (!(cam = kzalloc(sizeof(struct sn9c102_device), GFP_KERNEL)))
- return -ENOMEM;
-
- cam->usbdev = udev;
-
- if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) {
- DBG(1, "kzalloc() failed");
- err = -ENOMEM;
- goto fail;
- }
-
- if (!(cam->v4ldev = video_device_alloc())) {
- DBG(1, "video_device_alloc() failed");
- err = -ENOMEM;
- goto fail;
- }
-
- r = sn9c102_read_reg(cam, 0x00);
- if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) {
- DBG(1, "Sorry, this is not a SN9C1xx-based camera "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- err = -ENODEV;
- goto fail;
- }
-
- cam->bridge = id->driver_info;
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- DBG(2, "SN9C10[12] PC Camera Controller detected "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- break;
- case BRIDGE_SN9C103:
- DBG(2, "SN9C103 PC Camera Controller detected "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- break;
- case BRIDGE_SN9C105:
- DBG(2, "SN9C105 PC Camera Controller detected "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- break;
- case BRIDGE_SN9C120:
- DBG(2, "SN9C120 PC Camera Controller detected "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- break;
- }
-
- for (i = 0; i < ARRAY_SIZE(sn9c102_sensor_table); i++) {
- err = sn9c102_sensor_table[i](cam);
- if (!err)
- break;
- }
-
- if (!err) {
- DBG(2, "%s image sensor detected", cam->sensor.name);
- DBG(3, "Support for %s maintained by %s",
- cam->sensor.name, cam->sensor.maintainer);
- } else {
- DBG(1, "No supported image sensor detected for this bridge");
- err = -ENODEV;
- goto fail;
- }
-
- if (!(cam->bridge & cam->sensor.supported_bridge)) {
- DBG(1, "Bridge not supported");
- err = -ENODEV;
- goto fail;
- }
-
- if (sn9c102_init(cam)) {
- DBG(1, "Initialization failed. I will retry on open().");
- cam->state |= DEV_MISCONFIGURED;
- }
-
- strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
- cam->v4ldev->fops = &sn9c102_fops;
- cam->v4ldev->release = video_device_release;
- cam->v4ldev->parent = &udev->dev;
-
- init_completion(&cam->probe);
-
- err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
- video_nr[dev_nr]);
- if (err) {
- DBG(1, "V4L2 device registration failed");
- if (err == -ENFILE && video_nr[dev_nr] == -1)
- DBG(1, "Free /dev/videoX node not found");
- video_nr[dev_nr] = -1;
- dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
- complete_all(&cam->probe);
- goto fail;
- }
-
- DBG(2, "V4L2 device registered as %s",
- video_device_node_name(cam->v4ldev));
-
- video_set_drvdata(cam->v4ldev, cam);
- cam->module_param.force_munmap = force_munmap[dev_nr];
- cam->module_param.frame_timeout = frame_timeout[dev_nr];
-
- dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- err = sn9c102_create_sysfs(cam);
- if (!err)
- DBG(2, "Optional device control through 'sysfs' "
- "interface ready");
- else
- DBG(2, "Failed to create optional 'sysfs' interface for "
- "device controlling. Error #%d", err);
-#else
- DBG(2, "Optional device control through 'sysfs' interface disabled");
- DBG(3, "Compile the kernel with the 'CONFIG_VIDEO_ADV_DEBUG' "
- "configuration option to enable it.");
-#endif
-
- usb_set_intfdata(intf, cam);
- kref_init(&cam->kref);
- usb_get_dev(cam->usbdev);
-
- complete_all(&cam->probe);
-
- return 0;
-
-fail:
- if (cam) {
- kfree(cam->control_buffer);
- if (cam->v4ldev)
- video_device_release(cam->v4ldev);
- kfree(cam);
- }
- return err;
-}
-
-
-static void sn9c102_usb_disconnect(struct usb_interface* intf)
-{
- struct sn9c102_device* cam;
-
- down_write(&sn9c102_dev_lock);
-
- cam = usb_get_intfdata(intf);
-
- DBG(2, "Disconnecting %s...", cam->v4ldev->name);
-
- if (cam->users) {
- DBG(2, "Device %s is open! Deregistration and memory "
- "deallocation are deferred.",
- video_device_node_name(cam->v4ldev));
- cam->state |= DEV_MISCONFIGURED;
- sn9c102_stop_transfer(cam);
- cam->state |= DEV_DISCONNECTED;
- wake_up_interruptible(&cam->wait_frame);
- wake_up(&cam->wait_stream);
- } else
- cam->state |= DEV_DISCONNECTED;
-
- wake_up_interruptible_all(&cam->wait_open);
-
- kref_put(&cam->kref, sn9c102_release_resources);
-
- up_write(&sn9c102_dev_lock);
-}
-
-
-static struct usb_driver sn9c102_usb_driver = {
- .name = "sn9c102",
- .id_table = sn9c102_id_table,
- .probe = sn9c102_usb_probe,
- .disconnect = sn9c102_usb_disconnect,
-};
-
-module_usb_driver(sn9c102_usb_driver);
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
deleted file mode 100644
index b3d2cc72965..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/***************************************************************************
- * Table of device identifiers of the SN9C1xx PC Camera Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#ifndef _SN9C102_DEVTABLE_H_
-#define _SN9C102_DEVTABLE_H_
-
-#include <linux/usb.h>
-
-struct sn9c102_device;
-
-/*
- Each SN9C1xx camera has proper PID/VID identifiers.
- SN9C103, SN9C105, SN9C120 support multiple interfaces, but we only have to
- handle the video class interface.
-*/
-#define SN9C102_USB_DEVICE(vend, prod, bridge) \
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
- USB_DEVICE_ID_MATCH_INT_CLASS, \
- .idVendor = (vend), \
- .idProduct = (prod), \
- .bInterfaceClass = 0xff, \
- .driver_info = (bridge)
-
-static const struct usb_device_id sn9c102_id_table[] = {
- /* SN9C101 and SN9C102 */
-#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
- { SN9C102_USB_DEVICE(0x0c45, 0x6001, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */
- { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), },
-#endif
- { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), },
-#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
- { SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), },
-#endif
- { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), }, /* not in sonixb */
-#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
- { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */
- { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), },
-#endif
- { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), }, /* not in sonixb */
- /* SN9C103 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6080, BRIDGE_SN9C103), }, non existent ? */
- { SN9C102_USB_DEVICE(0x0c45, 0x6082, BRIDGE_SN9C103), }, /* not in sonixb */
-#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6083, BRIDGE_SN9C103), }, HY7131D/E */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6088, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x608a, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x608b, BRIDGE_SN9C103), }, non existent ? */
- { SN9C102_USB_DEVICE(0x0c45, 0x608c, BRIDGE_SN9C103), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x608e, BRIDGE_SN9C103), }, CISVF10 */
- { SN9C102_USB_DEVICE(0x0c45, 0x608f, BRIDGE_SN9C103), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60a0, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60a2, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60a3, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60a8, BRIDGE_SN9C103), }, PAS106 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60aa, BRIDGE_SN9C103), }, TAS5130 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ab, BRIDGE_SN9C103), }, TAS5110, non existent */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ac, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ae, BRIDGE_SN9C103), }, non existent ? */
- { SN9C102_USB_DEVICE(0x0c45, 0x60af, BRIDGE_SN9C103), },
- { SN9C102_USB_DEVICE(0x0c45, 0x60b0, BRIDGE_SN9C103), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60b2, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60b3, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60b8, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ba, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60bb, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), }, non existent ? */
-#endif
- /* SN9C105 */
-#if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE
- { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60c2, BRIDGE_SN9C105), }, PO1030 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60c8, BRIDGE_SN9C105), }, OM6801 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60cc, BRIDGE_SN9C105), }, HV7131GP */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ea, BRIDGE_SN9C105), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ec, BRIDGE_SN9C105), }, MO4000 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ef, BRIDGE_SN9C105), }, ICM105C */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60fa, BRIDGE_SN9C105), }, OV7648 */
- { SN9C102_USB_DEVICE(0x0c45, 0x60fb, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), },
- /* SN9C120 */
- { SN9C102_USB_DEVICE(0x0458, 0x7025, BRIDGE_SN9C120), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), }, po2030 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), }, om6801 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), }, S5K53BEB */
- { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), }, MO8000 */
- { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), },
- { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
- { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
- { SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), },
-#endif
- { }
-};
-
-/*
- Probing functions: on success, you must attach the sensor to the camera
- by calling sn9c102_attach_sensor().
- To enable the I2C communication, you might need to perform a really basic
- initialization of the SN9C1XX chip.
- Functions must return 0 on success, the appropriate error otherwise.
-*/
-extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam);
-extern int sn9c102_probe_hv7131r(struct sn9c102_device* cam);
-extern int sn9c102_probe_mi0343(struct sn9c102_device* cam);
-extern int sn9c102_probe_mi0360(struct sn9c102_device* cam);
-extern int sn9c102_probe_mt9v111(struct sn9c102_device *cam);
-extern int sn9c102_probe_ov7630(struct sn9c102_device* cam);
-extern int sn9c102_probe_ov7660(struct sn9c102_device* cam);
-extern int sn9c102_probe_pas106b(struct sn9c102_device* cam);
-extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam);
-extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam);
-extern int sn9c102_probe_tas5110d(struct sn9c102_device* cam);
-extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam);
-
-#endif /* _SN9C102_DEVTABLE_H_ */
diff --git a/drivers/media/video/sn9c102/sn9c102_hv7131d.c b/drivers/media/video/sn9c102/sn9c102_hv7131d.c
deleted file mode 100644
index 2dce5c908c8..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_hv7131d.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/***************************************************************************
- * Plug-in for HV7131D image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int hv7131d_init(struct sn9c102_device* cam)
-{
- int err;
-
- err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
- {0x00, 0x14}, {0x60, 0x17},
- {0x0e, 0x18}, {0xf2, 0x19});
-
- err += sn9c102_i2c_write(cam, 0x01, 0x04);
- err += sn9c102_i2c_write(cam, 0x02, 0x00);
- err += sn9c102_i2c_write(cam, 0x28, 0x00);
-
- return err;
-}
-
-
-static int hv7131d_get_ctrl(struct sn9c102_device* cam,
- struct v4l2_control* ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- {
- int r1 = sn9c102_i2c_read(cam, 0x26),
- r2 = sn9c102_i2c_read(cam, 0x27);
- if (r1 < 0 || r2 < 0)
- return -EIO;
- ctrl->value = (r1 << 8) | (r2 & 0xff);
- }
- return 0;
- case V4L2_CID_RED_BALANCE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x31)) < 0)
- return -EIO;
- ctrl->value = 0x3f - (ctrl->value & 0x3f);
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x33)) < 0)
- return -EIO;
- ctrl->value = 0x3f - (ctrl->value & 0x3f);
- return 0;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x32)) < 0)
- return -EIO;
- ctrl->value = 0x3f - (ctrl->value & 0x3f);
- return 0;
- case SN9C102_V4L2_CID_RESET_LEVEL:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x30)) < 0)
- return -EIO;
- ctrl->value &= 0x3f;
- return 0;
- case SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x34)) < 0)
- return -EIO;
- ctrl->value &= 0x07;
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-
-static int hv7131d_set_ctrl(struct sn9c102_device* cam,
- const struct v4l2_control* ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_write(cam, 0x26, ctrl->value >> 8);
- err += sn9c102_i2c_write(cam, 0x27, ctrl->value & 0xff);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_write(cam, 0x31, 0x3f - ctrl->value);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_write(cam, 0x33, 0x3f - ctrl->value);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_write(cam, 0x32, 0x3f - ctrl->value);
- break;
- case SN9C102_V4L2_CID_RESET_LEVEL:
- err += sn9c102_i2c_write(cam, 0x30, ctrl->value);
- break;
- case SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE:
- err += sn9c102_i2c_write(cam, 0x34, ctrl->value);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int hv7131d_set_crop(struct sn9c102_device* cam,
- const struct v4l2_rect* rect)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 2,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int hv7131d_set_pix_format(struct sn9c102_device* cam,
- const struct v4l2_pix_format* pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
- err += sn9c102_write_reg(cam, 0x42, 0x19);
- else
- err += sn9c102_write_reg(cam, 0xf2, 0x19);
-
- return err;
-}
-
-
-static const struct sn9c102_sensor hv7131d = {
- .name = "HV7131D",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x11,
- .init = &hv7131d_init,
- .qctrl = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x0250,
- .maximum = 0xffff,
- .step = 0x0001,
- .default_value = 0x0250,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x1e,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_RESET_LEVEL,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "reset level",
- .minimum = 0x19,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x30,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "pixel bias voltage",
- .minimum = 0x00,
- .maximum = 0x07,
- .step = 0x01,
- .default_value = 0x02,
- .flags = 0,
- },
- },
- .get_ctrl = &hv7131d_get_ctrl,
- .set_ctrl = &hv7131d_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &hv7131d_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &hv7131d_set_pix_format
-};
-
-
-int sn9c102_probe_hv7131d(struct sn9c102_device* cam)
-{
- int r0 = 0, r1 = 0, err;
-
- err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17});
-
- r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00);
- r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01);
- if (err || r0 < 0 || r1 < 0)
- return -EIO;
-
- if ((r0 != 0x00 && r0 != 0x01) || r1 != 0x04)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &hv7131d);
-
- return 0;
-}
diff --git a/drivers/media/video/sn9c102/sn9c102_hv7131r.c b/drivers/media/video/sn9c102/sn9c102_hv7131r.c
deleted file mode 100644
index 4295887ff60..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_hv7131r.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/***************************************************************************
- * Plug-in for HV7131R image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int hv7131r_init(struct sn9c102_device* cam)
-{
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- err = sn9c102_write_const_regs(cam, {0x00, 0x03}, {0x1a, 0x04},
- {0x20, 0x05}, {0x20, 0x06},
- {0x03, 0x10}, {0x00, 0x14},
- {0x60, 0x17}, {0x0a, 0x18},
- {0xf0, 0x19}, {0x1d, 0x1a},
- {0x10, 0x1b}, {0x02, 0x1c},
- {0x03, 0x1d}, {0x0f, 0x1e},
- {0x0c, 0x1f}, {0x00, 0x20},
- {0x10, 0x21}, {0x20, 0x22},
- {0x30, 0x23}, {0x40, 0x24},
- {0x50, 0x25}, {0x60, 0x26},
- {0x70, 0x27}, {0x80, 0x28},
- {0x90, 0x29}, {0xa0, 0x2a},
- {0xb0, 0x2b}, {0xc0, 0x2c},
- {0xd0, 0x2d}, {0xe0, 0x2e},
- {0xf0, 0x2f}, {0xff, 0x30});
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
- {0x00, 0x03}, {0x1a, 0x04},
- {0x44, 0x05}, {0x3e, 0x06},
- {0x1a, 0x07}, {0x03, 0x10},
- {0x08, 0x14}, {0xa3, 0x17},
- {0x4b, 0x18}, {0x00, 0x19},
- {0x1d, 0x1a}, {0x10, 0x1b},
- {0x02, 0x1c}, {0x03, 0x1d},
- {0x0f, 0x1e}, {0x0c, 0x1f},
- {0x00, 0x20}, {0x29, 0x21},
- {0x40, 0x22}, {0x54, 0x23},
- {0x66, 0x24}, {0x76, 0x25},
- {0x85, 0x26}, {0x94, 0x27},
- {0xa1, 0x28}, {0xae, 0x29},
- {0xbb, 0x2a}, {0xc7, 0x2b},
- {0xd3, 0x2c}, {0xde, 0x2d},
- {0xea, 0x2e}, {0xf4, 0x2f},
- {0xff, 0x30}, {0x00, 0x3F},
- {0xC7, 0x40}, {0x01, 0x41},
- {0x44, 0x42}, {0x00, 0x43},
- {0x44, 0x44}, {0x00, 0x45},
- {0x44, 0x46}, {0x00, 0x47},
- {0xC7, 0x48}, {0x01, 0x49},
- {0xC7, 0x4A}, {0x01, 0x4B},
- {0xC7, 0x4C}, {0x01, 0x4D},
- {0x44, 0x4E}, {0x00, 0x4F},
- {0x44, 0x50}, {0x00, 0x51},
- {0x44, 0x52}, {0x00, 0x53},
- {0xC7, 0x54}, {0x01, 0x55},
- {0xC7, 0x56}, {0x01, 0x57},
- {0xC7, 0x58}, {0x01, 0x59},
- {0x44, 0x5A}, {0x00, 0x5B},
- {0x44, 0x5C}, {0x00, 0x5D},
- {0x44, 0x5E}, {0x00, 0x5F},
- {0xC7, 0x60}, {0x01, 0x61},
- {0xC7, 0x62}, {0x01, 0x63},
- {0xC7, 0x64}, {0x01, 0x65},
- {0x44, 0x66}, {0x00, 0x67},
- {0x44, 0x68}, {0x00, 0x69},
- {0x44, 0x6A}, {0x00, 0x6B},
- {0xC7, 0x6C}, {0x01, 0x6D},
- {0xC7, 0x6E}, {0x01, 0x6F},
- {0xC7, 0x70}, {0x01, 0x71},
- {0x44, 0x72}, {0x00, 0x73},
- {0x44, 0x74}, {0x00, 0x75},
- {0x44, 0x76}, {0x00, 0x77},
- {0xC7, 0x78}, {0x01, 0x79},
- {0xC7, 0x7A}, {0x01, 0x7B},
- {0xC7, 0x7C}, {0x01, 0x7D},
- {0x44, 0x7E}, {0x00, 0x7F},
- {0x14, 0x84}, {0x00, 0x85},
- {0x27, 0x86}, {0x00, 0x87},
- {0x07, 0x88}, {0x00, 0x89},
- {0xEC, 0x8A}, {0x0f, 0x8B},
- {0xD8, 0x8C}, {0x0f, 0x8D},
- {0x3D, 0x8E}, {0x00, 0x8F},
- {0x3D, 0x90}, {0x00, 0x91},
- {0xCD, 0x92}, {0x0f, 0x93},
- {0xf7, 0x94}, {0x0f, 0x95},
- {0x0C, 0x96}, {0x00, 0x97},
- {0x00, 0x98}, {0x66, 0x99},
- {0x05, 0x9A}, {0x00, 0x9B},
- {0x04, 0x9C}, {0x00, 0x9D},
- {0x08, 0x9E}, {0x00, 0x9F},
- {0x2D, 0xC0}, {0x2D, 0xC1},
- {0x3A, 0xC2}, {0x05, 0xC3},
- {0x04, 0xC4}, {0x3F, 0xC5},
- {0x00, 0xC6}, {0x00, 0xC7},
- {0x50, 0xC8}, {0x3C, 0xC9},
- {0x28, 0xCA}, {0xD8, 0xCB},
- {0x14, 0xCC}, {0xEC, 0xCD},
- {0x32, 0xCE}, {0xDD, 0xCF},
- {0x32, 0xD0}, {0xDD, 0xD1},
- {0x6A, 0xD2}, {0x50, 0xD3},
- {0x00, 0xD4}, {0x00, 0xD5},
- {0x00, 0xD6});
- break;
- default:
- break;
- }
-
- err += sn9c102_i2c_write(cam, 0x20, 0x00);
- err += sn9c102_i2c_write(cam, 0x21, 0xd6);
- err += sn9c102_i2c_write(cam, 0x25, 0x06);
-
- return err;
-}
-
-
-static int hv7131r_get_ctrl(struct sn9c102_device* cam,
- struct v4l2_control* ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x30)) < 0)
- return -EIO;
- return 0;
- case V4L2_CID_RED_BALANCE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x31)) < 0)
- return -EIO;
- ctrl->value = ctrl->value & 0x3f;
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x33)) < 0)
- return -EIO;
- ctrl->value = ctrl->value & 0x3f;
- return 0;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x32)) < 0)
- return -EIO;
- ctrl->value = ctrl->value & 0x3f;
- return 0;
- case V4L2_CID_BLACK_LEVEL:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x01)) < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x08) ? 1 : 0;
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-
-static int hv7131r_set_ctrl(struct sn9c102_device* cam,
- const struct v4l2_control* ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x30, ctrl->value);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_write(cam, 0x31, ctrl->value);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_write(cam, 0x33, ctrl->value);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_write(cam, 0x32, ctrl->value);
- break;
- case V4L2_CID_BLACK_LEVEL:
- {
- int r = sn9c102_i2c_read(cam, 0x01);
- if (r < 0)
- return -EIO;
- err += sn9c102_i2c_write(cam, 0x01,
- (ctrl->value<<3) | (r&0xf7));
- }
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int hv7131r_set_crop(struct sn9c102_device* cam,
- const struct v4l2_rect* rect)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int hv7131r_set_pix_format(struct sn9c102_device* cam,
- const struct v4l2_pix_format* pix)
-{
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_write_reg(cam, 0xa0, 0x19);
- err += sn9c102_i2c_write(cam, 0x01, 0x04);
- } else {
- err += sn9c102_write_reg(cam, 0x30, 0x19);
- err += sn9c102_i2c_write(cam, 0x01, 0x04);
- }
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_write_reg(cam, 0xa5, 0x17);
- err += sn9c102_i2c_write(cam, 0x01, 0x24);
- } else {
- err += sn9c102_write_reg(cam, 0xa3, 0x17);
- err += sn9c102_i2c_write(cam, 0x01, 0x04);
- }
- break;
- default:
- break;
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor hv7131r = {
- .name = "HV7131R",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x11,
- .init = &hv7131r_init,
- .qctrl = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = 0x40,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x08,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x1a,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x2f,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLACK_LEVEL,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto black level compensation",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- },
- .get_ctrl = &hv7131r_get_ctrl,
- .set_ctrl = &hv7131r_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &hv7131r_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &hv7131r_set_pix_format
-};
-
-
-int sn9c102_probe_hv7131r(struct sn9c102_device* cam)
-{
- int devid, err;
-
- err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x02},
- {0x34, 0x01}, {0x20, 0x17},
- {0x34, 0x01}, {0x46, 0x01});
-
- devid = sn9c102_i2c_try_read(cam, &hv7131r, 0x00);
- if (err || devid < 0)
- return -EIO;
-
- if (devid != 0x02)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &hv7131r);
-
- return 0;
-}
diff --git a/drivers/media/video/sn9c102/sn9c102_mi0343.c b/drivers/media/video/sn9c102/sn9c102_mi0343.c
deleted file mode 100644
index 1f5b09bec89..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_mi0343.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/***************************************************************************
- * Plug-in for MI-0343 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int mi0343_init(struct sn9c102_device* cam)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
-
- err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
- {0x0a, 0x14}, {0x40, 0x01},
- {0x20, 0x17}, {0x07, 0x18},
- {0xa0, 0x19});
-
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x01, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
- 0x01, 0xe1, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
- 0x02, 0x81, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
- 0x00, 0x17, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
- 0x00, 0x11, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62,
- 0x04, 0x9a, 0, 0);
-
- return err;
-}
-
-
-static int mi0343_get_ctrl(struct sn9c102_device* cam,
- struct v4l2_control* ctrl)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- u8 data[2];
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[0];
- return 0;
- case V4L2_CID_GAIN:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
- data) < 0)
- return -EIO;
- break;
- case V4L2_CID_HFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x20 ? 1 : 0;
- return 0;
- case V4L2_CID_VFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x80 ? 1 : 0;
- return 0;
- case V4L2_CID_RED_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
- data) < 0)
- return -EIO;
- break;
- case V4L2_CID_BLUE_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
- data) < 0)
- return -EIO;
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
- data) < 0)
- return -EIO;
- break;
- default:
- return -EINVAL;
- }
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- case V4L2_CID_RED_BALANCE:
- case V4L2_CID_BLUE_BALANCE:
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = data[1] | (data[0] << 8);
- if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
- ctrl->value -= 0x10;
- else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
- ctrl->value -= 0x60;
- else if (ctrl->value >= 0xe0 && ctrl->value <= 0xff)
- ctrl->value -= 0xe0;
- }
-
- return 0;
-}
-
-
-static int mi0343_set_ctrl(struct sn9c102_device* cam,
- const struct v4l2_control* ctrl)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- u16 reg = 0;
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- case V4L2_CID_RED_BALANCE:
- case V4L2_CID_BLUE_BALANCE:
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (ctrl->value <= (0x3f-0x10))
- reg = 0x10 + ctrl->value;
- else if (ctrl->value <= ((0x3f-0x10) + (0x7f-0x60)))
- reg = 0x60 + (ctrl->value - (0x3f-0x10));
- else
- reg = 0xe0 + (ctrl->value - (0x3f-0x10) - (0x7f-0x60));
- break;
- }
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x09, ctrl->value, 0x00,
- 0, 0);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x35, reg >> 8, reg & 0xff,
- 0, 0);
- break;
- case V4L2_CID_HFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20, ctrl->value ? 0x40:0x00,
- ctrl->value ? 0x20:0x00,
- 0, 0);
- break;
- case V4L2_CID_VFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20, ctrl->value ? 0x80:0x00,
- ctrl->value ? 0x80:0x00,
- 0, 0);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2d, reg >> 8, reg & 0xff,
- 0, 0);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2c, reg >> 8, reg & 0xff,
- 0, 0);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2b, reg >> 8, reg & 0xff,
- 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2e, reg >> 8, reg & 0xff,
- 0, 0);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int mi0343_set_crop(struct sn9c102_device* cam,
- const struct v4l2_rect* rect)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int mi0343_set_pix_format(struct sn9c102_device* cam,
- const struct v4l2_pix_format* pix)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) {
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x0a, 0x00, 0x03, 0, 0);
- err += sn9c102_write_reg(cam, 0x20, 0x19);
- } else {
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x0a, 0x00, 0x05, 0, 0);
- err += sn9c102_write_reg(cam, 0xa0, 0x19);
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor mi0343 = {
- .name = "MI-0343",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x5d,
- .init = &mi0343_init,
- .qctrl = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x06,
- .flags = 0,
- },
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),/*0x6d*/
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = ((0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0)),
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- },
- .get_ctrl = &mi0343_get_ctrl,
- .set_ctrl = &mi0343_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &mi0343_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &mi0343_set_pix_format
-};
-
-
-int sn9c102_probe_mi0343(struct sn9c102_device* cam)
-{
- u8 data[2];
-
- if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17}))
- return -EIO;
-
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
- 2, data) < 0)
- return -EIO;
-
- if (data[1] != 0x42 || data[0] != 0xe3)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &mi0343);
-
- return 0;
-}
diff --git a/drivers/media/video/sn9c102/sn9c102_mi0360.c b/drivers/media/video/sn9c102/sn9c102_mi0360.c
deleted file mode 100644
index d973fc1973d..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_mi0360.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/***************************************************************************
- * Plug-in for MI-0360 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int mi0360_init(struct sn9c102_device* cam)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
- {0x0a, 0x14}, {0x40, 0x01},
- {0x20, 0x17}, {0x07, 0x18},
- {0xa0, 0x19}, {0x02, 0x1c},
- {0x03, 0x1d}, {0x0f, 0x1e},
- {0x0c, 0x1f}, {0x00, 0x20},
- {0x10, 0x21}, {0x20, 0x22},
- {0x30, 0x23}, {0x40, 0x24},
- {0x50, 0x25}, {0x60, 0x26},
- {0x70, 0x27}, {0x80, 0x28},
- {0x90, 0x29}, {0xa0, 0x2a},
- {0xb0, 0x2b}, {0xc0, 0x2c},
- {0xd0, 0x2d}, {0xe0, 0x2e},
- {0xf0, 0x2f}, {0xff, 0x30});
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
- {0x00, 0x03}, {0x1a, 0x04},
- {0x50, 0x05}, {0x20, 0x06},
- {0x10, 0x07}, {0x03, 0x10},
- {0x08, 0x14}, {0xa2, 0x17},
- {0x47, 0x18}, {0x00, 0x19},
- {0x1d, 0x1a}, {0x10, 0x1b},
- {0x02, 0x1c}, {0x03, 0x1d},
- {0x0f, 0x1e}, {0x0c, 0x1f},
- {0x00, 0x20}, {0x29, 0x21},
- {0x40, 0x22}, {0x54, 0x23},
- {0x66, 0x24}, {0x76, 0x25},
- {0x85, 0x26}, {0x94, 0x27},
- {0xa1, 0x28}, {0xae, 0x29},
- {0xbb, 0x2a}, {0xc7, 0x2b},
- {0xd3, 0x2c}, {0xde, 0x2d},
- {0xea, 0x2e}, {0xf4, 0x2f},
- {0xff, 0x30}, {0x00, 0x3F},
- {0xC7, 0x40}, {0x01, 0x41},
- {0x44, 0x42}, {0x00, 0x43},
- {0x44, 0x44}, {0x00, 0x45},
- {0x44, 0x46}, {0x00, 0x47},
- {0xC7, 0x48}, {0x01, 0x49},
- {0xC7, 0x4A}, {0x01, 0x4B},
- {0xC7, 0x4C}, {0x01, 0x4D},
- {0x44, 0x4E}, {0x00, 0x4F},
- {0x44, 0x50}, {0x00, 0x51},
- {0x44, 0x52}, {0x00, 0x53},
- {0xC7, 0x54}, {0x01, 0x55},
- {0xC7, 0x56}, {0x01, 0x57},
- {0xC7, 0x58}, {0x01, 0x59},
- {0x44, 0x5A}, {0x00, 0x5B},
- {0x44, 0x5C}, {0x00, 0x5D},
- {0x44, 0x5E}, {0x00, 0x5F},
- {0xC7, 0x60}, {0x01, 0x61},
- {0xC7, 0x62}, {0x01, 0x63},
- {0xC7, 0x64}, {0x01, 0x65},
- {0x44, 0x66}, {0x00, 0x67},
- {0x44, 0x68}, {0x00, 0x69},
- {0x44, 0x6A}, {0x00, 0x6B},
- {0xC7, 0x6C}, {0x01, 0x6D},
- {0xC7, 0x6E}, {0x01, 0x6F},
- {0xC7, 0x70}, {0x01, 0x71},
- {0x44, 0x72}, {0x00, 0x73},
- {0x44, 0x74}, {0x00, 0x75},
- {0x44, 0x76}, {0x00, 0x77},
- {0xC7, 0x78}, {0x01, 0x79},
- {0xC7, 0x7A}, {0x01, 0x7B},
- {0xC7, 0x7C}, {0x01, 0x7D},
- {0x44, 0x7E}, {0x00, 0x7F},
- {0x14, 0x84}, {0x00, 0x85},
- {0x27, 0x86}, {0x00, 0x87},
- {0x07, 0x88}, {0x00, 0x89},
- {0xEC, 0x8A}, {0x0f, 0x8B},
- {0xD8, 0x8C}, {0x0f, 0x8D},
- {0x3D, 0x8E}, {0x00, 0x8F},
- {0x3D, 0x90}, {0x00, 0x91},
- {0xCD, 0x92}, {0x0f, 0x93},
- {0xf7, 0x94}, {0x0f, 0x95},
- {0x0C, 0x96}, {0x00, 0x97},
- {0x00, 0x98}, {0x66, 0x99},
- {0x05, 0x9A}, {0x00, 0x9B},
- {0x04, 0x9C}, {0x00, 0x9D},
- {0x08, 0x9E}, {0x00, 0x9F},
- {0x2D, 0xC0}, {0x2D, 0xC1},
- {0x3A, 0xC2}, {0x05, 0xC3},
- {0x04, 0xC4}, {0x3F, 0xC5},
- {0x00, 0xC6}, {0x00, 0xC7},
- {0x50, 0xC8}, {0x3C, 0xC9},
- {0x28, 0xCA}, {0xD8, 0xCB},
- {0x14, 0xCC}, {0xEC, 0xCD},
- {0x32, 0xCE}, {0xDD, 0xCF},
- {0x32, 0xD0}, {0xDD, 0xD1},
- {0x6A, 0xD2}, {0x50, 0xD3},
- {0x00, 0xD4}, {0x00, 0xD5},
- {0x00, 0xD6});
- break;
- default:
- break;
- }
-
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x01, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
- 0x01, 0xe1, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
- 0x02, 0x81, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
- 0x00, 0x17, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
- 0x00, 0x11, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62,
- 0x04, 0x9a, 0, 0);
-
- return err;
-}
-
-
-static int mi0360_get_ctrl(struct sn9c102_device* cam,
- struct v4l2_control* ctrl)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- u8 data[2];
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[0];
- return 0;
- case V4L2_CID_GAIN:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1];
- return 0;
- case V4L2_CID_RED_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1];
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1];
- return 0;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1];
- return 0;
- case V4L2_CID_HFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x20 ? 1 : 0;
- return 0;
- case V4L2_CID_VFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x80 ? 1 : 0;
- return 0;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-static int mi0360_set_ctrl(struct sn9c102_device* cam,
- const struct v4l2_control* ctrl)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x09, ctrl->value, 0x00,
- 0, 0);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x35, 0x03, ctrl->value,
- 0, 0);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2c, 0x03, ctrl->value,
- 0, 0);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2d, 0x03, ctrl->value,
- 0, 0);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2b, 0x03, ctrl->value,
- 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2e, 0x03, ctrl->value,
- 0, 0);
- break;
- case V4L2_CID_HFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20, ctrl->value ? 0x40:0x00,
- ctrl->value ? 0x20:0x00,
- 0, 0);
- break;
- case V4L2_CID_VFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20, ctrl->value ? 0x80:0x00,
- ctrl->value ? 0x80:0x00,
- 0, 0);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int mi0360_set_crop(struct sn9c102_device* cam,
- const struct v4l2_rect* rect)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1;
- break;
- default:
- break;
- }
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int mi0360_set_pix_format(struct sn9c102_device* cam,
- const struct v4l2_pix_format* pix)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x0a, 0x00, 0x05, 0, 0);
- err += sn9c102_write_reg(cam, 0x60, 0x19);
- if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
- sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
- err += sn9c102_write_reg(cam, 0xa6, 0x17);
- } else {
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x0a, 0x00, 0x02, 0, 0);
- err += sn9c102_write_reg(cam, 0x20, 0x19);
- if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
- sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
- err += sn9c102_write_reg(cam, 0xa2, 0x17);
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor mi0360 = {
- .name = "MI-0360",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x5d,
- .init = &mi0360_init,
- .qctrl = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x05,
- .flags = 0,
- },
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x25,
- .flags = 0,
- },
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x0f,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x32,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x25,
- .flags = 0,
- },
- },
- .get_ctrl = &mi0360_get_ctrl,
- .set_ctrl = &mi0360_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &mi0360_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &mi0360_set_pix_format
-};
-
-
-int sn9c102_probe_mi0360(struct sn9c102_device* cam)
-{
-
- u8 data[2];
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17}))
- return -EIO;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
- {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17}))
- return -EIO;
- break;
- default:
- break;
- }
-
- if (sn9c102_i2c_try_raw_read(cam, &mi0360, mi0360.i2c_slave_id, 0x00,
- 2, data) < 0)
- return -EIO;
-
- if (data[0] != 0x82 || data[1] != 0x43)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &mi0360);
-
- return 0;
-}
diff --git a/drivers/media/video/sn9c102/sn9c102_mt9v111.c b/drivers/media/video/sn9c102/sn9c102_mt9v111.c
deleted file mode 100644
index 95986eb492e..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_mt9v111.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/***************************************************************************
- * Plug-in for MT9V111 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int mt9v111_init(struct sn9c102_device *cam)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
- {0x00, 0x03}, {0x1a, 0x04},
- {0x1f, 0x05}, {0x20, 0x06},
- {0x1f, 0x07}, {0x81, 0x08},
- {0x5c, 0x09}, {0x00, 0x0a},
- {0x00, 0x0b}, {0x00, 0x0c},
- {0x00, 0x0d}, {0x00, 0x0e},
- {0x00, 0x0f}, {0x03, 0x10},
- {0x00, 0x11}, {0x00, 0x12},
- {0x02, 0x13}, {0x14, 0x14},
- {0x28, 0x15}, {0x1e, 0x16},
- {0xe2, 0x17}, {0x06, 0x18},
- {0x00, 0x19}, {0x00, 0x1a},
- {0x00, 0x1b}, {0x08, 0x20},
- {0x39, 0x21}, {0x51, 0x22},
- {0x63, 0x23}, {0x73, 0x24},
- {0x82, 0x25}, {0x8f, 0x26},
- {0x9b, 0x27}, {0xa7, 0x28},
- {0xb1, 0x29}, {0xbc, 0x2a},
- {0xc6, 0x2b}, {0xcf, 0x2c},
- {0xd8, 0x2d}, {0xe1, 0x2e},
- {0xea, 0x2f}, {0xf2, 0x30},
- {0x13, 0x84}, {0x00, 0x85},
- {0x25, 0x86}, {0x00, 0x87},
- {0x07, 0x88}, {0x00, 0x89},
- {0xee, 0x8a}, {0x0f, 0x8b},
- {0xe5, 0x8c}, {0x0f, 0x8d},
- {0x2e, 0x8e}, {0x00, 0x8f},
- {0x30, 0x90}, {0x00, 0x91},
- {0xd4, 0x92}, {0x0f, 0x93},
- {0xfc, 0x94}, {0x0f, 0x95},
- {0x14, 0x96}, {0x00, 0x97},
- {0x00, 0x98}, {0x60, 0x99},
- {0x07, 0x9a}, {0x40, 0x9b},
- {0x20, 0x9c}, {0x00, 0x9d},
- {0x00, 0x9e}, {0x00, 0x9f},
- {0x2d, 0xc0}, {0x2d, 0xc1},
- {0x3a, 0xc2}, {0x05, 0xc3},
- {0x04, 0xc4}, {0x3f, 0xc5},
- {0x00, 0xc6}, {0x00, 0xc7},
- {0x50, 0xc8}, {0x3c, 0xc9},
- {0x28, 0xca}, {0xd8, 0xcb},
- {0x14, 0xcc}, {0xec, 0xcd},
- {0x32, 0xce}, {0xdd, 0xcf},
- {0x2d, 0xd0}, {0xdd, 0xd1},
- {0x6a, 0xd2}, {0x50, 0xd3},
- {0x60, 0xd4}, {0x00, 0xd5},
- {0x00, 0xd6});
-
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x01,
- 0x00, 0x01, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x01, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x08,
- 0x04, 0x80, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x01,
- 0x00, 0x04, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x08,
- 0x00, 0x08, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x02,
- 0x00, 0x16, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
- 0x01, 0xe7, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
- 0x02, 0x87, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
- 0x00, 0x40, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
- 0x00, 0x09, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x07,
- 0x30, 0x02, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0c,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x12,
- 0x00, 0xb0, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x13,
- 0x00, 0x7c, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x1e,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x20,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x20,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x01,
- 0x00, 0x04, 0, 0);
-
- return err;
-}
-
-static int mt9v111_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- u8 data[2];
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x80 ? 1 : 0;
- return 0;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-static int mt9v111_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20,
- ctrl->value ? 0x80 : 0x00,
- ctrl->value ? 0x80 : 0x00, 0,
- 0);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-static int mt9v111_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 v_start = (u8) (rect->top - s->cropcap.bounds.top) + 2;
-
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-static int mt9v111_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_write_reg(cam, 0xb4, 0x17);
- } else {
- err += sn9c102_write_reg(cam, 0xe2, 0x17);
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor mt9v111 = {
- .name = "MT9V111",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C105 | BRIDGE_SN9C120,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x5c,
- .init = &mt9v111_init,
- .qctrl = {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- },
- .get_ctrl = &mt9v111_get_ctrl,
- .set_ctrl = &mt9v111_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &mt9v111_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &mt9v111_set_pix_format
-};
-
-
-int sn9c102_probe_mt9v111(struct sn9c102_device *cam)
-{
- u8 data[2];
- int err = 0;
-
- err += sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
- {0x29, 0x01}, {0x42, 0x17},
- {0x62, 0x17}, {0x08, 0x01});
- err += sn9c102_i2c_try_raw_write(cam, &mt9v111, 4,
- mt9v111.i2c_slave_id, 0x01, 0x00,
- 0x04, 0, 0);
- if (err || sn9c102_i2c_try_raw_read(cam, &mt9v111,
- mt9v111.i2c_slave_id, 0x36, 2,
- data) < 0)
- return -EIO;
-
- if (data[0] != 0x82 || data[1] != 0x3a)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &mt9v111);
-
- return 0;
-}
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7630.c b/drivers/media/video/sn9c102/sn9c102_ov7630.c
deleted file mode 100644
index 803712c29f0..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_ov7630.c
+++ /dev/null
@@ -1,626 +0,0 @@
-/***************************************************************************
- * Plug-in for OV7630 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int ov7630_init(struct sn9c102_device* cam)
-{
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- err = sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17},
- {0x0f, 0x18}, {0x50, 0x19});
-
- err += sn9c102_i2c_write(cam, 0x12, 0x8d);
- err += sn9c102_i2c_write(cam, 0x12, 0x0d);
- err += sn9c102_i2c_write(cam, 0x11, 0x00);
- err += sn9c102_i2c_write(cam, 0x15, 0x35);
- err += sn9c102_i2c_write(cam, 0x16, 0x03);
- err += sn9c102_i2c_write(cam, 0x17, 0x1c);
- err += sn9c102_i2c_write(cam, 0x18, 0xbd);
- err += sn9c102_i2c_write(cam, 0x19, 0x06);
- err += sn9c102_i2c_write(cam, 0x1a, 0xf6);
- err += sn9c102_i2c_write(cam, 0x1b, 0x04);
- err += sn9c102_i2c_write(cam, 0x20, 0x44);
- err += sn9c102_i2c_write(cam, 0x23, 0xee);
- err += sn9c102_i2c_write(cam, 0x26, 0xa0);
- err += sn9c102_i2c_write(cam, 0x27, 0x9a);
- err += sn9c102_i2c_write(cam, 0x28, 0x20);
- err += sn9c102_i2c_write(cam, 0x29, 0x30);
- err += sn9c102_i2c_write(cam, 0x2f, 0x3d);
- err += sn9c102_i2c_write(cam, 0x30, 0x24);
- err += sn9c102_i2c_write(cam, 0x32, 0x86);
- err += sn9c102_i2c_write(cam, 0x60, 0xa9);
- err += sn9c102_i2c_write(cam, 0x61, 0x42);
- err += sn9c102_i2c_write(cam, 0x65, 0x00);
- err += sn9c102_i2c_write(cam, 0x69, 0x38);
- err += sn9c102_i2c_write(cam, 0x6f, 0x88);
- err += sn9c102_i2c_write(cam, 0x70, 0x0b);
- err += sn9c102_i2c_write(cam, 0x71, 0x00);
- err += sn9c102_i2c_write(cam, 0x74, 0x21);
- err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
- break;
- case BRIDGE_SN9C103:
- err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
- {0x1a, 0x04}, {0x20, 0x05},
- {0x20, 0x06}, {0x20, 0x07},
- {0x03, 0x10}, {0x0a, 0x14},
- {0x60, 0x17}, {0x0f, 0x18},
- {0x50, 0x19}, {0x1d, 0x1a},
- {0x10, 0x1b}, {0x02, 0x1c},
- {0x03, 0x1d}, {0x0f, 0x1e},
- {0x0c, 0x1f}, {0x00, 0x20},
- {0x10, 0x21}, {0x20, 0x22},
- {0x30, 0x23}, {0x40, 0x24},
- {0x50, 0x25}, {0x60, 0x26},
- {0x70, 0x27}, {0x80, 0x28},
- {0x90, 0x29}, {0xa0, 0x2a},
- {0xb0, 0x2b}, {0xc0, 0x2c},
- {0xd0, 0x2d}, {0xe0, 0x2e},
- {0xf0, 0x2f}, {0xff, 0x30});
-
- err += sn9c102_i2c_write(cam, 0x12, 0x8d);
- err += sn9c102_i2c_write(cam, 0x12, 0x0d);
- err += sn9c102_i2c_write(cam, 0x15, 0x34);
- err += sn9c102_i2c_write(cam, 0x11, 0x01);
- err += sn9c102_i2c_write(cam, 0x1b, 0x04);
- err += sn9c102_i2c_write(cam, 0x20, 0x44);
- err += sn9c102_i2c_write(cam, 0x23, 0xee);
- err += sn9c102_i2c_write(cam, 0x26, 0xa0);
- err += sn9c102_i2c_write(cam, 0x27, 0x9a);
- err += sn9c102_i2c_write(cam, 0x28, 0x20);
- err += sn9c102_i2c_write(cam, 0x29, 0x30);
- err += sn9c102_i2c_write(cam, 0x2f, 0x3d);
- err += sn9c102_i2c_write(cam, 0x30, 0x24);
- err += sn9c102_i2c_write(cam, 0x32, 0x86);
- err += sn9c102_i2c_write(cam, 0x60, 0xa9);
- err += sn9c102_i2c_write(cam, 0x61, 0x42);
- err += sn9c102_i2c_write(cam, 0x65, 0x00);
- err += sn9c102_i2c_write(cam, 0x69, 0x38);
- err += sn9c102_i2c_write(cam, 0x6f, 0x88);
- err += sn9c102_i2c_write(cam, 0x70, 0x0b);
- err += sn9c102_i2c_write(cam, 0x71, 0x00);
- err += sn9c102_i2c_write(cam, 0x74, 0x21);
- err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err = sn9c102_write_const_regs(cam, {0x40, 0x02}, {0x00, 0x03},
- {0x1a, 0x04}, {0x03, 0x10},
- {0x0a, 0x14}, {0xe2, 0x17},
- {0x0b, 0x18}, {0x00, 0x19},
- {0x1d, 0x1a}, {0x10, 0x1b},
- {0x02, 0x1c}, {0x03, 0x1d},
- {0x0f, 0x1e}, {0x0c, 0x1f},
- {0x00, 0x20}, {0x24, 0x21},
- {0x3b, 0x22}, {0x47, 0x23},
- {0x60, 0x24}, {0x71, 0x25},
- {0x80, 0x26}, {0x8f, 0x27},
- {0x9d, 0x28}, {0xaa, 0x29},
- {0xb8, 0x2a}, {0xc4, 0x2b},
- {0xd1, 0x2c}, {0xdd, 0x2d},
- {0xe8, 0x2e}, {0xf4, 0x2f},
- {0xff, 0x30}, {0x00, 0x3f},
- {0xc7, 0x40}, {0x01, 0x41},
- {0x44, 0x42}, {0x00, 0x43},
- {0x44, 0x44}, {0x00, 0x45},
- {0x44, 0x46}, {0x00, 0x47},
- {0xc7, 0x48}, {0x01, 0x49},
- {0xc7, 0x4a}, {0x01, 0x4b},
- {0xc7, 0x4c}, {0x01, 0x4d},
- {0x44, 0x4e}, {0x00, 0x4f},
- {0x44, 0x50}, {0x00, 0x51},
- {0x44, 0x52}, {0x00, 0x53},
- {0xc7, 0x54}, {0x01, 0x55},
- {0xc7, 0x56}, {0x01, 0x57},
- {0xc7, 0x58}, {0x01, 0x59},
- {0x44, 0x5a}, {0x00, 0x5b},
- {0x44, 0x5c}, {0x00, 0x5d},
- {0x44, 0x5e}, {0x00, 0x5f},
- {0xc7, 0x60}, {0x01, 0x61},
- {0xc7, 0x62}, {0x01, 0x63},
- {0xc7, 0x64}, {0x01, 0x65},
- {0x44, 0x66}, {0x00, 0x67},
- {0x44, 0x68}, {0x00, 0x69},
- {0x44, 0x6a}, {0x00, 0x6b},
- {0xc7, 0x6c}, {0x01, 0x6d},
- {0xc7, 0x6e}, {0x01, 0x6f},
- {0xc7, 0x70}, {0x01, 0x71},
- {0x44, 0x72}, {0x00, 0x73},
- {0x44, 0x74}, {0x00, 0x75},
- {0x44, 0x76}, {0x00, 0x77},
- {0xc7, 0x78}, {0x01, 0x79},
- {0xc7, 0x7a}, {0x01, 0x7b},
- {0xc7, 0x7c}, {0x01, 0x7d},
- {0x44, 0x7e}, {0x00, 0x7f},
- {0x17, 0x84}, {0x00, 0x85},
- {0x2e, 0x86}, {0x00, 0x87},
- {0x09, 0x88}, {0x00, 0x89},
- {0xe8, 0x8a}, {0x0f, 0x8b},
- {0xda, 0x8c}, {0x0f, 0x8d},
- {0x40, 0x8e}, {0x00, 0x8f},
- {0x37, 0x90}, {0x00, 0x91},
- {0xcf, 0x92}, {0x0f, 0x93},
- {0xfa, 0x94}, {0x0f, 0x95},
- {0x00, 0x96}, {0x00, 0x97},
- {0x00, 0x98}, {0x66, 0x99},
- {0x00, 0x9a}, {0x40, 0x9b},
- {0x20, 0x9c}, {0x00, 0x9d},
- {0x00, 0x9e}, {0x00, 0x9f},
- {0x2d, 0xc0}, {0x2d, 0xc1},
- {0x3a, 0xc2}, {0x00, 0xc3},
- {0x04, 0xc4}, {0x3f, 0xc5},
- {0x00, 0xc6}, {0x00, 0xc7},
- {0x50, 0xc8}, {0x3c, 0xc9},
- {0x28, 0xca}, {0xd8, 0xcb},
- {0x14, 0xcc}, {0xec, 0xcd},
- {0x32, 0xce}, {0xdd, 0xcf},
- {0x32, 0xd0}, {0xdd, 0xd1},
- {0x6a, 0xd2}, {0x50, 0xd3},
- {0x60, 0xd4}, {0x00, 0xd5},
- {0x00, 0xd6});
-
- err += sn9c102_i2c_write(cam, 0x12, 0x80);
- err += sn9c102_i2c_write(cam, 0x12, 0x48);
- err += sn9c102_i2c_write(cam, 0x01, 0x80);
- err += sn9c102_i2c_write(cam, 0x02, 0x80);
- err += sn9c102_i2c_write(cam, 0x03, 0x80);
- err += sn9c102_i2c_write(cam, 0x04, 0x10);
- err += sn9c102_i2c_write(cam, 0x05, 0x20);
- err += sn9c102_i2c_write(cam, 0x06, 0x80);
- err += sn9c102_i2c_write(cam, 0x11, 0x00);
- err += sn9c102_i2c_write(cam, 0x0c, 0x20);
- err += sn9c102_i2c_write(cam, 0x0d, 0x20);
- err += sn9c102_i2c_write(cam, 0x15, 0x80);
- err += sn9c102_i2c_write(cam, 0x16, 0x03);
- err += sn9c102_i2c_write(cam, 0x17, 0x1b);
- err += sn9c102_i2c_write(cam, 0x18, 0xbd);
- err += sn9c102_i2c_write(cam, 0x19, 0x05);
- err += sn9c102_i2c_write(cam, 0x1a, 0xf6);
- err += sn9c102_i2c_write(cam, 0x1b, 0x04);
- err += sn9c102_i2c_write(cam, 0x21, 0x1b);
- err += sn9c102_i2c_write(cam, 0x22, 0x00);
- err += sn9c102_i2c_write(cam, 0x23, 0xde);
- err += sn9c102_i2c_write(cam, 0x24, 0x10);
- err += sn9c102_i2c_write(cam, 0x25, 0x8a);
- err += sn9c102_i2c_write(cam, 0x26, 0xa0);
- err += sn9c102_i2c_write(cam, 0x27, 0xca);
- err += sn9c102_i2c_write(cam, 0x28, 0xa2);
- err += sn9c102_i2c_write(cam, 0x29, 0x74);
- err += sn9c102_i2c_write(cam, 0x2a, 0x88);
- err += sn9c102_i2c_write(cam, 0x2b, 0x34);
- err += sn9c102_i2c_write(cam, 0x2c, 0x88);
- err += sn9c102_i2c_write(cam, 0x2e, 0x00);
- err += sn9c102_i2c_write(cam, 0x2f, 0x00);
- err += sn9c102_i2c_write(cam, 0x30, 0x00);
- err += sn9c102_i2c_write(cam, 0x32, 0xc2);
- err += sn9c102_i2c_write(cam, 0x33, 0x08);
- err += sn9c102_i2c_write(cam, 0x4c, 0x40);
- err += sn9c102_i2c_write(cam, 0x4d, 0xf3);
- err += sn9c102_i2c_write(cam, 0x60, 0x05);
- err += sn9c102_i2c_write(cam, 0x61, 0x40);
- err += sn9c102_i2c_write(cam, 0x62, 0x12);
- err += sn9c102_i2c_write(cam, 0x63, 0x57);
- err += sn9c102_i2c_write(cam, 0x64, 0x73);
- err += sn9c102_i2c_write(cam, 0x65, 0x00);
- err += sn9c102_i2c_write(cam, 0x66, 0x55);
- err += sn9c102_i2c_write(cam, 0x67, 0x01);
- err += sn9c102_i2c_write(cam, 0x68, 0xac);
- err += sn9c102_i2c_write(cam, 0x69, 0x38);
- err += sn9c102_i2c_write(cam, 0x6f, 0x1f);
- err += sn9c102_i2c_write(cam, 0x70, 0x01);
- err += sn9c102_i2c_write(cam, 0x71, 0x00);
- err += sn9c102_i2c_write(cam, 0x72, 0x10);
- err += sn9c102_i2c_write(cam, 0x73, 0x50);
- err += sn9c102_i2c_write(cam, 0x74, 0x20);
- err += sn9c102_i2c_write(cam, 0x76, 0x01);
- err += sn9c102_i2c_write(cam, 0x77, 0xf3);
- err += sn9c102_i2c_write(cam, 0x78, 0x90);
- err += sn9c102_i2c_write(cam, 0x79, 0x98);
- err += sn9c102_i2c_write(cam, 0x7a, 0x98);
- err += sn9c102_i2c_write(cam, 0x7b, 0x00);
- err += sn9c102_i2c_write(cam, 0x7c, 0x38);
- err += sn9c102_i2c_write(cam, 0x7d, 0xff);
- break;
- default:
- break;
- }
-
- return err;
-}
-
-
-static int ov7630_get_ctrl(struct sn9c102_device* cam,
- struct v4l2_control* ctrl)
-{
- enum sn9c102_bridge bridge = sn9c102_get_bridge(cam);
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x10)) < 0)
- return -EIO;
- break;
- case V4L2_CID_RED_BALANCE:
- if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120)
- ctrl->value = sn9c102_pread_reg(cam, 0x05);
- else
- ctrl->value = sn9c102_pread_reg(cam, 0x07);
- break;
- case V4L2_CID_BLUE_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x06);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120)
- ctrl->value = sn9c102_pread_reg(cam, 0x07);
- else
- ctrl->value = sn9c102_pread_reg(cam, 0x05);
- break;
- break;
- case V4L2_CID_GAIN:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x00)) < 0)
- return -EIO;
- ctrl->value &= 0x3f;
- break;
- case V4L2_CID_DO_WHITE_BALANCE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x0c)) < 0)
- return -EIO;
- ctrl->value &= 0x3f;
- break;
- case V4L2_CID_WHITENESS:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x0d)) < 0)
- return -EIO;
- ctrl->value &= 0x3f;
- break;
- case V4L2_CID_AUTOGAIN:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x13)) < 0)
- return -EIO;
- ctrl->value &= 0x01;
- break;
- case V4L2_CID_VFLIP:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x75)) < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x80) ? 1 : 0;
- break;
- case SN9C102_V4L2_CID_GAMMA:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x14)) < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x02) ? 1 : 0;
- break;
- case SN9C102_V4L2_CID_BAND_FILTER:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x2d)) < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x02) ? 1 : 0;
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int ov7630_set_ctrl(struct sn9c102_device* cam,
- const struct v4l2_control* ctrl)
-{
- enum sn9c102_bridge bridge = sn9c102_get_bridge(cam);
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_write(cam, 0x10, ctrl->value);
- break;
- case V4L2_CID_RED_BALANCE:
- if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120)
- err += sn9c102_write_reg(cam, ctrl->value, 0x05);
- else
- err += sn9c102_write_reg(cam, ctrl->value, 0x07);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_write_reg(cam, ctrl->value, 0x06);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120)
- err += sn9c102_write_reg(cam, ctrl->value, 0x07);
- else
- err += sn9c102_write_reg(cam, ctrl->value, 0x05);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x00, ctrl->value);
- break;
- case V4L2_CID_DO_WHITE_BALANCE:
- err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
- break;
- case V4L2_CID_WHITENESS:
- err += sn9c102_i2c_write(cam, 0x0d, ctrl->value);
- break;
- case V4L2_CID_AUTOGAIN:
- err += sn9c102_i2c_write(cam, 0x13, ctrl->value |
- (ctrl->value << 1));
- break;
- case V4L2_CID_VFLIP:
- err += sn9c102_i2c_write(cam, 0x75, 0x0e | (ctrl->value << 7));
- break;
- case SN9C102_V4L2_CID_GAMMA:
- err += sn9c102_i2c_write(cam, 0x14, ctrl->value << 2);
- break;
- case SN9C102_V4L2_CID_BAND_FILTER:
- err += sn9c102_i2c_write(cam, 0x2d, ctrl->value << 2);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int ov7630_set_crop(struct sn9c102_device* cam,
- const struct v4l2_rect* rect)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4;
- break;
- default:
- break;
- }
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int ov7630_set_pix_format(struct sn9c102_device* cam,
- const struct v4l2_pix_format* pix)
-{
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8)
- err += sn9c102_write_reg(cam, 0x50, 0x19);
- else
- err += sn9c102_write_reg(cam, 0x20, 0x19);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_write_reg(cam, 0xe5, 0x17);
- err += sn9c102_i2c_write(cam, 0x11, 0x04);
- } else {
- err += sn9c102_write_reg(cam, 0xe2, 0x17);
- err += sn9c102_i2c_write(cam, 0x11, 0x02);
- }
- break;
- default:
- break;
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor ov7630 = {
- .name = "OV7630",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103 |
- BRIDGE_SN9C105 | BRIDGE_SN9C120,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x21,
- .init = &ov7630_init,
- .qctrl = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x14,
- .flags = 0,
- },
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = 0x60,
- .flags = 0,
- },
- {
- .id = V4L2_CID_WHITENESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "white balance background: red",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = V4L2_CID_DO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "white balance background: blue",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto adjust",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x01,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_BAND_FILTER,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "band filter",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GAMMA,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "rgb gamma",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- },
- .get_ctrl = &ov7630_get_ctrl,
- .set_ctrl = &ov7630_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &ov7630_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SN9C10X,
- .priv = 8,
- },
- .set_pix_format = &ov7630_set_pix_format
-};
-
-
-int sn9c102_probe_ov7630(struct sn9c102_device* cam)
-{
- int pid, ver, err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17});
- break;
- case BRIDGE_SN9C103: /* do _not_ change anything! */
- err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x42, 0x01},
- {0x28, 0x17}, {0x44, 0x02});
- pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a);
- if (err || pid < 0) /* try a different initialization */
- err += sn9c102_write_const_regs(cam, {0x01, 0x01},
- {0x00, 0x01});
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err = sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
- {0x29, 0x01}, {0x74, 0x02},
- {0x0e, 0x01}, {0x44, 0x01});
- break;
- default:
- break;
- }
-
- pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a);
- ver = sn9c102_i2c_try_read(cam, &ov7630, 0x0b);
- if (err || pid < 0 || ver < 0)
- return -EIO;
- if (pid != 0x76 || ver != 0x31)
- return -ENODEV;
- sn9c102_attach_sensor(cam, &ov7630);
-
- return 0;
-}
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7660.c b/drivers/media/video/sn9c102/sn9c102_ov7660.c
deleted file mode 100644
index 7977795d342..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_ov7660.c
+++ /dev/null
@@ -1,538 +0,0 @@
-/***************************************************************************
- * Plug-in for OV7660 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int ov7660_init(struct sn9c102_device* cam)
-{
- int err = 0;
-
- err = sn9c102_write_const_regs(cam, {0x40, 0x02}, {0x00, 0x03},
- {0x1a, 0x04}, {0x03, 0x10},
- {0x08, 0x14}, {0x20, 0x17},
- {0x8b, 0x18}, {0x00, 0x19},
- {0x1d, 0x1a}, {0x10, 0x1b},
- {0x02, 0x1c}, {0x03, 0x1d},
- {0x0f, 0x1e}, {0x0c, 0x1f},
- {0x00, 0x20}, {0x29, 0x21},
- {0x40, 0x22}, {0x54, 0x23},
- {0x66, 0x24}, {0x76, 0x25},
- {0x85, 0x26}, {0x94, 0x27},
- {0xa1, 0x28}, {0xae, 0x29},
- {0xbb, 0x2a}, {0xc7, 0x2b},
- {0xd3, 0x2c}, {0xde, 0x2d},
- {0xea, 0x2e}, {0xf4, 0x2f},
- {0xff, 0x30}, {0x00, 0x3f},
- {0xc7, 0x40}, {0x01, 0x41},
- {0x44, 0x42}, {0x00, 0x43},
- {0x44, 0x44}, {0x00, 0x45},
- {0x44, 0x46}, {0x00, 0x47},
- {0xc7, 0x48}, {0x01, 0x49},
- {0xc7, 0x4a}, {0x01, 0x4b},
- {0xc7, 0x4c}, {0x01, 0x4d},
- {0x44, 0x4e}, {0x00, 0x4f},
- {0x44, 0x50}, {0x00, 0x51},
- {0x44, 0x52}, {0x00, 0x53},
- {0xc7, 0x54}, {0x01, 0x55},
- {0xc7, 0x56}, {0x01, 0x57},
- {0xc7, 0x58}, {0x01, 0x59},
- {0x44, 0x5a}, {0x00, 0x5b},
- {0x44, 0x5c}, {0x00, 0x5d},
- {0x44, 0x5e}, {0x00, 0x5f},
- {0xc7, 0x60}, {0x01, 0x61},
- {0xc7, 0x62}, {0x01, 0x63},
- {0xc7, 0x64}, {0x01, 0x65},
- {0x44, 0x66}, {0x00, 0x67},
- {0x44, 0x68}, {0x00, 0x69},
- {0x44, 0x6a}, {0x00, 0x6b},
- {0xc7, 0x6c}, {0x01, 0x6d},
- {0xc7, 0x6e}, {0x01, 0x6f},
- {0xc7, 0x70}, {0x01, 0x71},
- {0x44, 0x72}, {0x00, 0x73},
- {0x44, 0x74}, {0x00, 0x75},
- {0x44, 0x76}, {0x00, 0x77},
- {0xc7, 0x78}, {0x01, 0x79},
- {0xc7, 0x7a}, {0x01, 0x7b},
- {0xc7, 0x7c}, {0x01, 0x7d},
- {0x44, 0x7e}, {0x00, 0x7f},
- {0x14, 0x84}, {0x00, 0x85},
- {0x27, 0x86}, {0x00, 0x87},
- {0x07, 0x88}, {0x00, 0x89},
- {0xec, 0x8a}, {0x0f, 0x8b},
- {0xd8, 0x8c}, {0x0f, 0x8d},
- {0x3d, 0x8e}, {0x00, 0x8f},
- {0x3d, 0x90}, {0x00, 0x91},
- {0xcd, 0x92}, {0x0f, 0x93},
- {0xf7, 0x94}, {0x0f, 0x95},
- {0x0c, 0x96}, {0x00, 0x97},
- {0x00, 0x98}, {0x66, 0x99},
- {0x05, 0x9a}, {0x00, 0x9b},
- {0x04, 0x9c}, {0x00, 0x9d},
- {0x08, 0x9e}, {0x00, 0x9f},
- {0x2d, 0xc0}, {0x2d, 0xc1},
- {0x3a, 0xc2}, {0x05, 0xc3},
- {0x04, 0xc4}, {0x3f, 0xc5},
- {0x00, 0xc6}, {0x00, 0xc7},
- {0x50, 0xc8}, {0x3C, 0xc9},
- {0x28, 0xca}, {0xd8, 0xcb},
- {0x14, 0xcc}, {0xec, 0xcd},
- {0x32, 0xce}, {0xdd, 0xcf},
- {0x32, 0xd0}, {0xdd, 0xd1},
- {0x6a, 0xd2}, {0x50, 0xd3},
- {0x00, 0xd4}, {0x00, 0xd5},
- {0x00, 0xd6});
-
- err += sn9c102_i2c_write(cam, 0x12, 0x80);
- err += sn9c102_i2c_write(cam, 0x11, 0x09);
- err += sn9c102_i2c_write(cam, 0x00, 0x0A);
- err += sn9c102_i2c_write(cam, 0x01, 0x80);
- err += sn9c102_i2c_write(cam, 0x02, 0x80);
- err += sn9c102_i2c_write(cam, 0x03, 0x00);
- err += sn9c102_i2c_write(cam, 0x04, 0x00);
- err += sn9c102_i2c_write(cam, 0x05, 0x08);
- err += sn9c102_i2c_write(cam, 0x06, 0x0B);
- err += sn9c102_i2c_write(cam, 0x07, 0x00);
- err += sn9c102_i2c_write(cam, 0x08, 0x1C);
- err += sn9c102_i2c_write(cam, 0x09, 0x01);
- err += sn9c102_i2c_write(cam, 0x0A, 0x76);
- err += sn9c102_i2c_write(cam, 0x0B, 0x60);
- err += sn9c102_i2c_write(cam, 0x0C, 0x00);
- err += sn9c102_i2c_write(cam, 0x0D, 0x08);
- err += sn9c102_i2c_write(cam, 0x0E, 0x04);
- err += sn9c102_i2c_write(cam, 0x0F, 0x6F);
- err += sn9c102_i2c_write(cam, 0x10, 0x20);
- err += sn9c102_i2c_write(cam, 0x11, 0x03);
- err += sn9c102_i2c_write(cam, 0x12, 0x05);
- err += sn9c102_i2c_write(cam, 0x13, 0xC7);
- err += sn9c102_i2c_write(cam, 0x14, 0x2C);
- err += sn9c102_i2c_write(cam, 0x15, 0x00);
- err += sn9c102_i2c_write(cam, 0x16, 0x02);
- err += sn9c102_i2c_write(cam, 0x17, 0x10);
- err += sn9c102_i2c_write(cam, 0x18, 0x60);
- err += sn9c102_i2c_write(cam, 0x19, 0x02);
- err += sn9c102_i2c_write(cam, 0x1A, 0x7B);
- err += sn9c102_i2c_write(cam, 0x1B, 0x02);
- err += sn9c102_i2c_write(cam, 0x1C, 0x7F);
- err += sn9c102_i2c_write(cam, 0x1D, 0xA2);
- err += sn9c102_i2c_write(cam, 0x1E, 0x01);
- err += sn9c102_i2c_write(cam, 0x1F, 0x0E);
- err += sn9c102_i2c_write(cam, 0x20, 0x05);
- err += sn9c102_i2c_write(cam, 0x21, 0x05);
- err += sn9c102_i2c_write(cam, 0x22, 0x05);
- err += sn9c102_i2c_write(cam, 0x23, 0x05);
- err += sn9c102_i2c_write(cam, 0x24, 0x68);
- err += sn9c102_i2c_write(cam, 0x25, 0x58);
- err += sn9c102_i2c_write(cam, 0x26, 0xD4);
- err += sn9c102_i2c_write(cam, 0x27, 0x80);
- err += sn9c102_i2c_write(cam, 0x28, 0x80);
- err += sn9c102_i2c_write(cam, 0x29, 0x30);
- err += sn9c102_i2c_write(cam, 0x2A, 0x00);
- err += sn9c102_i2c_write(cam, 0x2B, 0x00);
- err += sn9c102_i2c_write(cam, 0x2C, 0x80);
- err += sn9c102_i2c_write(cam, 0x2D, 0x00);
- err += sn9c102_i2c_write(cam, 0x2E, 0x00);
- err += sn9c102_i2c_write(cam, 0x2F, 0x0E);
- err += sn9c102_i2c_write(cam, 0x30, 0x08);
- err += sn9c102_i2c_write(cam, 0x31, 0x30);
- err += sn9c102_i2c_write(cam, 0x32, 0xB4);
- err += sn9c102_i2c_write(cam, 0x33, 0x00);
- err += sn9c102_i2c_write(cam, 0x34, 0x07);
- err += sn9c102_i2c_write(cam, 0x35, 0x84);
- err += sn9c102_i2c_write(cam, 0x36, 0x00);
- err += sn9c102_i2c_write(cam, 0x37, 0x0C);
- err += sn9c102_i2c_write(cam, 0x38, 0x02);
- err += sn9c102_i2c_write(cam, 0x39, 0x43);
- err += sn9c102_i2c_write(cam, 0x3A, 0x00);
- err += sn9c102_i2c_write(cam, 0x3B, 0x0A);
- err += sn9c102_i2c_write(cam, 0x3C, 0x6C);
- err += sn9c102_i2c_write(cam, 0x3D, 0x99);
- err += sn9c102_i2c_write(cam, 0x3E, 0x0E);
- err += sn9c102_i2c_write(cam, 0x3F, 0x41);
- err += sn9c102_i2c_write(cam, 0x40, 0xC1);
- err += sn9c102_i2c_write(cam, 0x41, 0x22);
- err += sn9c102_i2c_write(cam, 0x42, 0x08);
- err += sn9c102_i2c_write(cam, 0x43, 0xF0);
- err += sn9c102_i2c_write(cam, 0x44, 0x10);
- err += sn9c102_i2c_write(cam, 0x45, 0x78);
- err += sn9c102_i2c_write(cam, 0x46, 0xA8);
- err += sn9c102_i2c_write(cam, 0x47, 0x60);
- err += sn9c102_i2c_write(cam, 0x48, 0x80);
- err += sn9c102_i2c_write(cam, 0x49, 0x00);
- err += sn9c102_i2c_write(cam, 0x4A, 0x00);
- err += sn9c102_i2c_write(cam, 0x4B, 0x00);
- err += sn9c102_i2c_write(cam, 0x4C, 0x00);
- err += sn9c102_i2c_write(cam, 0x4D, 0x00);
- err += sn9c102_i2c_write(cam, 0x4E, 0x00);
- err += sn9c102_i2c_write(cam, 0x4F, 0x46);
- err += sn9c102_i2c_write(cam, 0x50, 0x36);
- err += sn9c102_i2c_write(cam, 0x51, 0x0F);
- err += sn9c102_i2c_write(cam, 0x52, 0x17);
- err += sn9c102_i2c_write(cam, 0x53, 0x7F);
- err += sn9c102_i2c_write(cam, 0x54, 0x96);
- err += sn9c102_i2c_write(cam, 0x55, 0x40);
- err += sn9c102_i2c_write(cam, 0x56, 0x40);
- err += sn9c102_i2c_write(cam, 0x57, 0x40);
- err += sn9c102_i2c_write(cam, 0x58, 0x0F);
- err += sn9c102_i2c_write(cam, 0x59, 0xBA);
- err += sn9c102_i2c_write(cam, 0x5A, 0x9A);
- err += sn9c102_i2c_write(cam, 0x5B, 0x22);
- err += sn9c102_i2c_write(cam, 0x5C, 0xB9);
- err += sn9c102_i2c_write(cam, 0x5D, 0x9B);
- err += sn9c102_i2c_write(cam, 0x5E, 0x10);
- err += sn9c102_i2c_write(cam, 0x5F, 0xF0);
- err += sn9c102_i2c_write(cam, 0x60, 0x05);
- err += sn9c102_i2c_write(cam, 0x61, 0x60);
- err += sn9c102_i2c_write(cam, 0x62, 0x00);
- err += sn9c102_i2c_write(cam, 0x63, 0x00);
- err += sn9c102_i2c_write(cam, 0x64, 0x50);
- err += sn9c102_i2c_write(cam, 0x65, 0x30);
- err += sn9c102_i2c_write(cam, 0x66, 0x00);
- err += sn9c102_i2c_write(cam, 0x67, 0x80);
- err += sn9c102_i2c_write(cam, 0x68, 0x7A);
- err += sn9c102_i2c_write(cam, 0x69, 0x90);
- err += sn9c102_i2c_write(cam, 0x6A, 0x80);
- err += sn9c102_i2c_write(cam, 0x6B, 0x0A);
- err += sn9c102_i2c_write(cam, 0x6C, 0x30);
- err += sn9c102_i2c_write(cam, 0x6D, 0x48);
- err += sn9c102_i2c_write(cam, 0x6E, 0x80);
- err += sn9c102_i2c_write(cam, 0x6F, 0x74);
- err += sn9c102_i2c_write(cam, 0x70, 0x64);
- err += sn9c102_i2c_write(cam, 0x71, 0x60);
- err += sn9c102_i2c_write(cam, 0x72, 0x5C);
- err += sn9c102_i2c_write(cam, 0x73, 0x58);
- err += sn9c102_i2c_write(cam, 0x74, 0x54);
- err += sn9c102_i2c_write(cam, 0x75, 0x4C);
- err += sn9c102_i2c_write(cam, 0x76, 0x40);
- err += sn9c102_i2c_write(cam, 0x77, 0x38);
- err += sn9c102_i2c_write(cam, 0x78, 0x34);
- err += sn9c102_i2c_write(cam, 0x79, 0x30);
- err += sn9c102_i2c_write(cam, 0x7A, 0x2F);
- err += sn9c102_i2c_write(cam, 0x7B, 0x2B);
- err += sn9c102_i2c_write(cam, 0x7C, 0x03);
- err += sn9c102_i2c_write(cam, 0x7D, 0x07);
- err += sn9c102_i2c_write(cam, 0x7E, 0x17);
- err += sn9c102_i2c_write(cam, 0x7F, 0x34);
- err += sn9c102_i2c_write(cam, 0x80, 0x41);
- err += sn9c102_i2c_write(cam, 0x81, 0x4D);
- err += sn9c102_i2c_write(cam, 0x82, 0x58);
- err += sn9c102_i2c_write(cam, 0x83, 0x63);
- err += sn9c102_i2c_write(cam, 0x84, 0x6E);
- err += sn9c102_i2c_write(cam, 0x85, 0x77);
- err += sn9c102_i2c_write(cam, 0x86, 0x87);
- err += sn9c102_i2c_write(cam, 0x87, 0x95);
- err += sn9c102_i2c_write(cam, 0x88, 0xAF);
- err += sn9c102_i2c_write(cam, 0x89, 0xC7);
- err += sn9c102_i2c_write(cam, 0x8A, 0xDF);
- err += sn9c102_i2c_write(cam, 0x8B, 0x99);
- err += sn9c102_i2c_write(cam, 0x8C, 0x99);
- err += sn9c102_i2c_write(cam, 0x8D, 0xCF);
- err += sn9c102_i2c_write(cam, 0x8E, 0x20);
- err += sn9c102_i2c_write(cam, 0x8F, 0x26);
- err += sn9c102_i2c_write(cam, 0x90, 0x10);
- err += sn9c102_i2c_write(cam, 0x91, 0x0C);
- err += sn9c102_i2c_write(cam, 0x92, 0x25);
- err += sn9c102_i2c_write(cam, 0x93, 0x00);
- err += sn9c102_i2c_write(cam, 0x94, 0x50);
- err += sn9c102_i2c_write(cam, 0x95, 0x50);
- err += sn9c102_i2c_write(cam, 0x96, 0x00);
- err += sn9c102_i2c_write(cam, 0x97, 0x01);
- err += sn9c102_i2c_write(cam, 0x98, 0x10);
- err += sn9c102_i2c_write(cam, 0x99, 0x40);
- err += sn9c102_i2c_write(cam, 0x9A, 0x40);
- err += sn9c102_i2c_write(cam, 0x9B, 0x20);
- err += sn9c102_i2c_write(cam, 0x9C, 0x00);
- err += sn9c102_i2c_write(cam, 0x9D, 0x99);
- err += sn9c102_i2c_write(cam, 0x9E, 0x7F);
- err += sn9c102_i2c_write(cam, 0x9F, 0x00);
- err += sn9c102_i2c_write(cam, 0xA0, 0x00);
- err += sn9c102_i2c_write(cam, 0xA1, 0x00);
-
- return err;
-}
-
-
-static int ov7660_get_ctrl(struct sn9c102_device* cam,
- struct v4l2_control* ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x10)) < 0)
- return -EIO;
- break;
- case V4L2_CID_DO_WHITE_BALANCE:
- if ((ctrl->value = sn9c102_read_reg(cam, 0x02)) < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x04) ? 1 : 0;
- break;
- case V4L2_CID_RED_BALANCE:
- if ((ctrl->value = sn9c102_read_reg(cam, 0x05)) < 0)
- return -EIO;
- ctrl->value &= 0x7f;
- break;
- case V4L2_CID_BLUE_BALANCE:
- if ((ctrl->value = sn9c102_read_reg(cam, 0x06)) < 0)
- return -EIO;
- ctrl->value &= 0x7f;
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if ((ctrl->value = sn9c102_read_reg(cam, 0x07)) < 0)
- return -EIO;
- ctrl->value &= 0x7f;
- break;
- case SN9C102_V4L2_CID_BAND_FILTER:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x3b)) < 0)
- return -EIO;
- ctrl->value &= 0x08;
- break;
- case V4L2_CID_GAIN:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x00)) < 0)
- return -EIO;
- ctrl->value &= 0x1f;
- break;
- case V4L2_CID_AUTOGAIN:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x13)) < 0)
- return -EIO;
- ctrl->value &= 0x01;
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int ov7660_set_ctrl(struct sn9c102_device* cam,
- const struct v4l2_control* ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_write(cam, 0x10, ctrl->value);
- break;
- case V4L2_CID_DO_WHITE_BALANCE:
- err += sn9c102_write_reg(cam, 0x43 | (ctrl->value << 2), 0x02);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_write_reg(cam, ctrl->value, 0x05);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_write_reg(cam, ctrl->value, 0x06);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_write_reg(cam, ctrl->value, 0x07);
- break;
- case SN9C102_V4L2_CID_BAND_FILTER:
- err += sn9c102_i2c_write(cam, ctrl->value << 3, 0x3b);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x00, 0x60 + ctrl->value);
- break;
- case V4L2_CID_AUTOGAIN:
- err += sn9c102_i2c_write(cam, 0x13, 0xc0 |
- (ctrl->value * 0x07));
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int ov7660_set_crop(struct sn9c102_device* cam,
- const struct v4l2_rect* rect)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int ov7660_set_pix_format(struct sn9c102_device* cam,
- const struct v4l2_pix_format* pix)
-{
- int r0, err = 0;
-
- r0 = sn9c102_pread_reg(cam, 0x01);
-
- if (pix->pixelformat == V4L2_PIX_FMT_JPEG) {
- err += sn9c102_write_reg(cam, r0 | 0x40, 0x01);
- err += sn9c102_write_reg(cam, 0xa2, 0x17);
- err += sn9c102_i2c_write(cam, 0x11, 0x00);
- } else {
- err += sn9c102_write_reg(cam, r0 | 0x40, 0x01);
- err += sn9c102_write_reg(cam, 0xa2, 0x17);
- err += sn9c102_i2c_write(cam, 0x11, 0x0d);
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor ov7660 = {
- .name = "OV7660",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C105 | BRIDGE_SN9C120,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x21,
- .init = &ov7660_init,
- .qctrl = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0x1f,
- .step = 0x01,
- .default_value = 0x09,
- .flags = 0,
- },
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = 0x27,
- .flags = 0,
- },
- {
- .id = V4L2_CID_DO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "night mode",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x14,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x14,
- .flags = 0,
- },
- {
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto adjust",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x01,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x14,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_BAND_FILTER,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "band filter",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- },
- .get_ctrl = &ov7660_get_ctrl,
- .set_ctrl = &ov7660_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &ov7660_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_JPEG,
- .priv = 8,
- },
- .set_pix_format = &ov7660_set_pix_format
-};
-
-
-int sn9c102_probe_ov7660(struct sn9c102_device* cam)
-{
- int pid, ver, err;
-
- err = sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
- {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17});
-
- pid = sn9c102_i2c_try_read(cam, &ov7660, 0x0a);
- ver = sn9c102_i2c_try_read(cam, &ov7660, 0x0b);
- if (err || pid < 0 || ver < 0)
- return -EIO;
- if (pid != 0x76 || ver != 0x60)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &ov7660);
-
- return 0;
-}
diff --git a/drivers/media/video/sn9c102/sn9c102_pas106b.c b/drivers/media/video/sn9c102/sn9c102_pas106b.c
deleted file mode 100644
index 81cd969c1b7..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_pas106b.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/***************************************************************************
- * Plug-in for PAS106B image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include <linux/delay.h>
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int pas106b_init(struct sn9c102_device* cam)
-{
- int err = 0;
-
- err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
- {0x00, 0x14}, {0x20, 0x17},
- {0x20, 0x19}, {0x09, 0x18});
-
- err += sn9c102_i2c_write(cam, 0x02, 0x0c);
- err += sn9c102_i2c_write(cam, 0x05, 0x5a);
- err += sn9c102_i2c_write(cam, 0x06, 0x88);
- err += sn9c102_i2c_write(cam, 0x07, 0x80);
- err += sn9c102_i2c_write(cam, 0x10, 0x06);
- err += sn9c102_i2c_write(cam, 0x11, 0x06);
- err += sn9c102_i2c_write(cam, 0x12, 0x00);
- err += sn9c102_i2c_write(cam, 0x14, 0x02);
- err += sn9c102_i2c_write(cam, 0x13, 0x01);
-
- msleep(400);
-
- return err;
-}
-
-
-static int pas106b_get_ctrl(struct sn9c102_device* cam,
- struct v4l2_control* ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- {
- int r1 = sn9c102_i2c_read(cam, 0x03),
- r2 = sn9c102_i2c_read(cam, 0x04);
- if (r1 < 0 || r2 < 0)
- return -EIO;
- ctrl->value = (r1 << 4) | (r2 & 0x0f);
- }
- return 0;
- case V4L2_CID_RED_BALANCE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x0c)) < 0)
- return -EIO;
- ctrl->value &= 0x1f;
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x09)) < 0)
- return -EIO;
- ctrl->value &= 0x1f;
- return 0;
- case V4L2_CID_GAIN:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x0e)) < 0)
- return -EIO;
- ctrl->value &= 0x1f;
- return 0;
- case V4L2_CID_CONTRAST:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x0f)) < 0)
- return -EIO;
- ctrl->value &= 0x07;
- return 0;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x0a)) < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x1f) << 1;
- return 0;
- case SN9C102_V4L2_CID_DAC_MAGNITUDE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x08)) < 0)
- return -EIO;
- ctrl->value &= 0xf8;
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-
-static int pas106b_set_ctrl(struct sn9c102_device* cam,
- const struct v4l2_control* ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_write(cam, 0x03, ctrl->value >> 4);
- err += sn9c102_i2c_write(cam, 0x04, ctrl->value & 0x0f);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_write(cam, 0x09, ctrl->value);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x0e, ctrl->value);
- break;
- case V4L2_CID_CONTRAST:
- err += sn9c102_i2c_write(cam, 0x0f, ctrl->value);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_write(cam, 0x0a, ctrl->value >> 1);
- err += sn9c102_i2c_write(cam, 0x0b, ctrl->value >> 1);
- break;
- case SN9C102_V4L2_CID_DAC_MAGNITUDE:
- err += sn9c102_i2c_write(cam, 0x08, ctrl->value << 3);
- break;
- default:
- return -EINVAL;
- }
- err += sn9c102_i2c_write(cam, 0x13, 0x01);
-
- return err ? -EIO : 0;
-}
-
-
-static int pas106b_set_crop(struct sn9c102_device* cam,
- const struct v4l2_rect* rect)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int pas106b_set_pix_format(struct sn9c102_device* cam,
- const struct v4l2_pix_format* pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
- err += sn9c102_write_reg(cam, 0x2c, 0x17);
- else
- err += sn9c102_write_reg(cam, 0x20, 0x17);
-
- return err;
-}
-
-
-static const struct sn9c102_sensor pas106b = {
- .name = "PAS106B",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x40,
- .init = &pas106b_init,
- .qctrl = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x125,
- .maximum = 0xfff,
- .step = 0x001,
- .default_value = 0x140,
- .flags = 0,
- },
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0x1f,
- .step = 0x01,
- .default_value = 0x0d,
- .flags = 0,
- },
- {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "contrast",
- .minimum = 0x00,
- .maximum = 0x07,
- .step = 0x01,
- .default_value = 0x00, /* 0x00~0x03 have same effect */
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x1f,
- .step = 0x01,
- .default_value = 0x04,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x1f,
- .step = 0x01,
- .default_value = 0x06,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x3e,
- .step = 0x02,
- .default_value = 0x02,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_DAC_MAGNITUDE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "DAC magnitude",
- .minimum = 0x00,
- .maximum = 0x1f,
- .step = 0x01,
- .default_value = 0x01,
- .flags = 0,
- },
- },
- .get_ctrl = &pas106b_get_ctrl,
- .set_ctrl = &pas106b_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 352,
- .height = 288,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 352,
- .height = 288,
- },
- },
- .set_crop = &pas106b_set_crop,
- .pix_format = {
- .width = 352,
- .height = 288,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8, /* we use this field as 'bits per pixel' */
- },
- .set_pix_format = &pas106b_set_pix_format
-};
-
-
-int sn9c102_probe_pas106b(struct sn9c102_device* cam)
-{
- int r0 = 0, r1 = 0;
- unsigned int pid = 0;
-
- /*
- Minimal initialization to enable the I2C communication
- NOTE: do NOT change the values!
- */
- if (sn9c102_write_const_regs(cam,
- {0x01, 0x01}, /* sensor power down */
- {0x00, 0x01}, /* sensor power on */
- {0x28, 0x17})) /* sensor clock at 24 MHz */
- return -EIO;
-
- r0 = sn9c102_i2c_try_read(cam, &pas106b, 0x00);
- r1 = sn9c102_i2c_try_read(cam, &pas106b, 0x01);
- if (r0 < 0 || r1 < 0)
- return -EIO;
-
- pid = (r0 << 11) | ((r1 & 0xf0) >> 4);
- if (pid != 0x007)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &pas106b);
-
- return 0;
-}
diff --git a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c b/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
deleted file mode 100644
index 2e86fdc8698..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/***************************************************************************
- * Plug-in for PAS202BCB image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2004 by Carlos Eduardo Medaglia Dyonisio *
- * <medaglia@undl.org.br> *
- * *
- * Support for SN9C103, DAC Magnitude, exposure and green gain controls *
- * added by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include <linux/delay.h>
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int pas202bcb_init(struct sn9c102_device* cam)
-{
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
- {0x00, 0x14}, {0x20, 0x17},
- {0x30, 0x19}, {0x09, 0x18});
- break;
- case BRIDGE_SN9C103:
- err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
- {0x1a, 0x04}, {0x20, 0x05},
- {0x20, 0x06}, {0x20, 0x07},
- {0x00, 0x10}, {0x00, 0x11},
- {0x00, 0x14}, {0x20, 0x17},
- {0x30, 0x19}, {0x09, 0x18},
- {0x02, 0x1c}, {0x03, 0x1d},
- {0x0f, 0x1e}, {0x0c, 0x1f},
- {0x00, 0x20}, {0x10, 0x21},
- {0x20, 0x22}, {0x30, 0x23},
- {0x40, 0x24}, {0x50, 0x25},
- {0x60, 0x26}, {0x70, 0x27},
- {0x80, 0x28}, {0x90, 0x29},
- {0xa0, 0x2a}, {0xb0, 0x2b},
- {0xc0, 0x2c}, {0xd0, 0x2d},
- {0xe0, 0x2e}, {0xf0, 0x2f},
- {0xff, 0x30});
- break;
- default:
- break;
- }
-
- err += sn9c102_i2c_write(cam, 0x02, 0x14);
- err += sn9c102_i2c_write(cam, 0x03, 0x40);
- err += sn9c102_i2c_write(cam, 0x0d, 0x2c);
- err += sn9c102_i2c_write(cam, 0x0e, 0x01);
- err += sn9c102_i2c_write(cam, 0x0f, 0xa9);
- err += sn9c102_i2c_write(cam, 0x10, 0x08);
- err += sn9c102_i2c_write(cam, 0x13, 0x63);
- err += sn9c102_i2c_write(cam, 0x15, 0x70);
- err += sn9c102_i2c_write(cam, 0x11, 0x01);
-
- msleep(400);
-
- return err;
-}
-
-
-static int pas202bcb_get_ctrl(struct sn9c102_device* cam,
- struct v4l2_control* ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- {
- int r1 = sn9c102_i2c_read(cam, 0x04),
- r2 = sn9c102_i2c_read(cam, 0x05);
- if (r1 < 0 || r2 < 0)
- return -EIO;
- ctrl->value = (r1 << 6) | (r2 & 0x3f);
- }
- return 0;
- case V4L2_CID_RED_BALANCE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x09)) < 0)
- return -EIO;
- ctrl->value &= 0x0f;
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x07)) < 0)
- return -EIO;
- ctrl->value &= 0x0f;
- return 0;
- case V4L2_CID_GAIN:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x10)) < 0)
- return -EIO;
- ctrl->value &= 0x1f;
- return 0;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x08)) < 0)
- return -EIO;
- ctrl->value &= 0x0f;
- return 0;
- case SN9C102_V4L2_CID_DAC_MAGNITUDE:
- if ((ctrl->value = sn9c102_i2c_read(cam, 0x0c)) < 0)
- return -EIO;
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-
-static int pas202bcb_set_pix_format(struct sn9c102_device* cam,
- const struct v4l2_pix_format* pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
- err += sn9c102_write_reg(cam, 0x28, 0x17);
- else
- err += sn9c102_write_reg(cam, 0x20, 0x17);
-
- return err;
-}
-
-
-static int pas202bcb_set_ctrl(struct sn9c102_device* cam,
- const struct v4l2_control* ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_write(cam, 0x04, ctrl->value >> 6);
- err += sn9c102_i2c_write(cam, 0x05, ctrl->value & 0x3f);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_write(cam, 0x09, ctrl->value);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_write(cam, 0x07, ctrl->value);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x10, ctrl->value);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_write(cam, 0x08, ctrl->value);
- break;
- case SN9C102_V4L2_CID_DAC_MAGNITUDE:
- err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
- break;
- default:
- return -EINVAL;
- }
- err += sn9c102_i2c_write(cam, 0x11, 0x01);
-
- return err ? -EIO : 0;
-}
-
-
-static int pas202bcb_set_crop(struct sn9c102_device* cam,
- const struct v4l2_rect* rect)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = 0,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4;
- break;
- case BRIDGE_SN9C103:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 3;
- break;
- default:
- break;
- }
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static const struct sn9c102_sensor pas202bcb = {
- .name = "PAS202BCB",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x40,
- .init = &pas202bcb_init,
- .qctrl = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x01e5,
- .maximum = 0x3fff,
- .step = 0x0001,
- .default_value = 0x01e5,
- .flags = 0,
- },
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0x1f,
- .step = 0x01,
- .default_value = 0x0b,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x05,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_DAC_MAGNITUDE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "DAC magnitude",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = 0x04,
- .flags = 0,
- },
- },
- .get_ctrl = &pas202bcb_get_ctrl,
- .set_ctrl = &pas202bcb_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &pas202bcb_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &pas202bcb_set_pix_format
-};
-
-
-int sn9c102_probe_pas202bcb(struct sn9c102_device* cam)
-{
- int r0 = 0, r1 = 0, err = 0;
- unsigned int pid = 0;
-
- /*
- * Minimal initialization to enable the I2C communication
- * NOTE: do NOT change the values!
- */
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- err = sn9c102_write_const_regs(cam,
- {0x01, 0x01}, /* power down */
- {0x40, 0x01}, /* power on */
- {0x28, 0x17});/* clock 24 MHz */
- break;
- case BRIDGE_SN9C103: /* do _not_ change anything! */
- err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x01},
- {0x44, 0x02}, {0x29, 0x17});
- break;
- default:
- break;
- }
-
- r0 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x00);
- r1 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x01);
-
- if (err || r0 < 0 || r1 < 0)
- return -EIO;
-
- pid = (r0 << 4) | ((r1 & 0xf0) >> 4);
- if (pid != 0x017)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &pas202bcb);
-
- return 0;
-}
diff --git a/drivers/media/video/sn9c102/sn9c102_sensor.h b/drivers/media/video/sn9c102/sn9c102_sensor.h
deleted file mode 100644
index 3679970dba2..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_sensor.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/***************************************************************************
- * API for image sensors connected to the SN9C1xx PC Camera Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#ifndef _SN9C102_SENSOR_H_
-#define _SN9C102_SENSOR_H_
-
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include <linux/device.h>
-#include <linux/stddef.h>
-#include <linux/errno.h>
-#include <asm/types.h>
-
-struct sn9c102_device;
-struct sn9c102_sensor;
-
-/*****************************************************************************/
-
-/*
- OVERVIEW.
- This is a small interface that allows you to add support for any CCD/CMOS
- image sensors connected to the SN9C1XX bridges. The entire API is documented
- below. In the most general case, to support a sensor there are three steps
- you have to follow:
- 1) define the main "sn9c102_sensor" structure by setting the basic fields;
- 2) write a probing function to be called by the core module when the USB
- camera is recognized, then add both the USB ids and the name of that
- function to the two corresponding tables in sn9c102_devtable.h;
- 3) implement the methods that you want/need (and fill the rest of the main
- structure accordingly).
- "sn9c102_pas106b.c" is an example of all this stuff. Remember that you do
- NOT need to touch the source code of the core module for the things to work
- properly, unless you find bugs or flaws in it. Finally, do not forget to
- read the V4L2 API for completeness.
-*/
-
-/*****************************************************************************/
-
-enum sn9c102_bridge {
- BRIDGE_SN9C101 = 0x01,
- BRIDGE_SN9C102 = 0x02,
- BRIDGE_SN9C103 = 0x04,
- BRIDGE_SN9C105 = 0x08,
- BRIDGE_SN9C120 = 0x10,
-};
-
-/* Return the bridge name */
-enum sn9c102_bridge sn9c102_get_bridge(struct sn9c102_device* cam);
-
-/* Return a pointer the sensor struct attached to the camera */
-struct sn9c102_sensor* sn9c102_get_sensor(struct sn9c102_device* cam);
-
-/* Identify a device */
-extern struct sn9c102_device*
-sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id);
-
-/* Attach a probed sensor to the camera. */
-extern void
-sn9c102_attach_sensor(struct sn9c102_device* cam,
- const struct sn9c102_sensor* sensor);
-
-/*
- Read/write routines: they always return -1 on error, 0 or the read value
- otherwise. NOTE that a real read operation is not supported by the SN9C1XX
- chip for some of its registers. To work around this problem, a pseudo-read
- call is provided instead: it returns the last successfully written value
- on the register (0 if it has never been written), the usual -1 on error.
-*/
-
-/* The "try" I2C I/O versions are used when probing the sensor */
-extern int sn9c102_i2c_try_read(struct sn9c102_device*,
- const struct sn9c102_sensor*, u8 address);
-
-/*
- These must be used if and only if the sensor doesn't implement the standard
- I2C protocol. There are a number of good reasons why you must use the
- single-byte versions of these functions: do not abuse. The first function
- writes n bytes, from data0 to datan, to registers 0x09 - 0x09+n of SN9C1XX
- chip. The second one programs the registers 0x09 and 0x10 with data0 and
- data1, and places the n bytes read from the sensor register table in the
- buffer pointed by 'buffer'. Both the functions return -1 on error; the write
- version returns 0 on success, while the read version returns the first read
- byte.
-*/
-extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
- const struct sn9c102_sensor* sensor, u8 n,
- u8 data0, u8 data1, u8 data2, u8 data3,
- u8 data4, u8 data5);
-extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
- const struct sn9c102_sensor* sensor,
- u8 data0, u8 data1, u8 n, u8 buffer[]);
-
-/* To be used after the sensor struct has been attached to the camera struct */
-extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
-extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
-
-/* I/O on registers in the bridge. Could be used by the sensor methods too */
-extern int sn9c102_read_reg(struct sn9c102_device*, u16 index);
-extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
-extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
-extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2],
- int count);
-/*
- Write multiple registers with constant values. For example:
- sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
- Register addresses must be < 256.
-*/
-#define sn9c102_write_const_regs(sn9c102_device, data...) \
- ({ static const u8 _valreg[][2] = {data}; \
- sn9c102_write_regs(sn9c102_device, _valreg, ARRAY_SIZE(_valreg)); })
-
-/*****************************************************************************/
-
-enum sn9c102_i2c_sysfs_ops {
- SN9C102_I2C_READ = 0x01,
- SN9C102_I2C_WRITE = 0x02,
-};
-
-enum sn9c102_i2c_frequency { /* sensors may support both the frequencies */
- SN9C102_I2C_100KHZ = 0x01,
- SN9C102_I2C_400KHZ = 0x02,
-};
-
-enum sn9c102_i2c_interface {
- SN9C102_I2C_2WIRES,
- SN9C102_I2C_3WIRES,
-};
-
-#define SN9C102_MAX_CTRLS (V4L2_CID_LASTP1-V4L2_CID_BASE+10)
-
-struct sn9c102_sensor {
- char name[32], /* sensor name */
- maintainer[64]; /* name of the maintainer <email> */
-
- enum sn9c102_bridge supported_bridge; /* supported SN9C1xx bridges */
-
- /* Supported operations through the 'sysfs' interface */
- enum sn9c102_i2c_sysfs_ops sysfs_ops;
-
- /*
- These sensor capabilities must be provided if the SN9C1XX controller
- needs to communicate through the sensor serial interface by using
- at least one of the i2c functions available.
- */
- enum sn9c102_i2c_frequency frequency;
- enum sn9c102_i2c_interface interface;
-
- /*
- This identifier must be provided if the image sensor implements
- the standard I2C protocol.
- */
- u8 i2c_slave_id; /* reg. 0x09 */
-
- /*
- NOTE: Where not noted,most of the functions below are not mandatory.
- Set to null if you do not implement them. If implemented,
- they must return 0 on success, the proper error otherwise.
- */
-
- int (*init)(struct sn9c102_device* cam);
- /*
- This function will be called after the sensor has been attached.
- It should be used to initialize the sensor only, but may also
- configure part of the SN9C1XX chip if necessary. You don't need to
- setup picture settings like brightness, contrast, etc.. here, if
- the corresponding controls are implemented (see below), since
- they are adjusted in the core driver by calling the set_ctrl()
- method after init(), where the arguments are the default values
- specified in the v4l2_queryctrl list of supported controls;
- Same suggestions apply for other settings, _if_ the corresponding
- methods are present; if not, the initialization must configure the
- sensor according to the default configuration structures below.
- */
-
- struct v4l2_queryctrl qctrl[SN9C102_MAX_CTRLS];
- /*
- Optional list of default controls, defined as indicated in the
- V4L2 API. Menu type controls are not handled by this interface.
- */
-
- int (*get_ctrl)(struct sn9c102_device* cam, struct v4l2_control* ctrl);
- int (*set_ctrl)(struct sn9c102_device* cam,
- const struct v4l2_control* ctrl);
- /*
- You must implement at least the set_ctrl method if you have defined
- the list above. The returned value must follow the V4L2
- specifications for the VIDIOC_G|C_CTRL ioctls. V4L2_CID_H|VCENTER
- are not supported by this driver, so do not implement them. Also,
- you don't have to check whether the passed values are out of bounds,
- given that this is done by the core module.
- */
-
- struct v4l2_cropcap cropcap;
- /*
- Think the image sensor as a grid of R,G,B monochromatic pixels
- disposed according to a particular Bayer pattern, which describes
- the complete array of pixels, from (0,0) to (xmax, ymax). We will
- use this coordinate system from now on. It is assumed the sensor
- chip can be programmed to capture/transmit a subsection of that
- array of pixels: we will call this subsection "active window".
- It is not always true that the largest achievable active window can
- cover the whole array of pixels. The V4L2 API defines another
- area called "source rectangle", which, in turn, is a subrectangle of
- the active window. The SN9C1XX chip is always programmed to read the
- source rectangle.
- The bounds of both the active window and the source rectangle are
- specified in the cropcap substructures 'bounds' and 'defrect'.
- By default, the source rectangle should cover the largest possible
- area. Again, it is not always true that the largest source rectangle
- can cover the entire active window, although it is a rare case for
- the hardware we have. The bounds of the source rectangle _must_ be
- multiple of 16 and must use the same coordinate system as indicated
- before; their centers shall align initially.
- If necessary, the sensor chip must be initialized during init() to
- set the bounds of the active sensor window; however, by default, it
- usually covers the largest achievable area (maxwidth x maxheight)
- of pixels, so no particular initialization is needed, if you have
- defined the correct default bounds in the structures.
- See the V4L2 API for further details.
- NOTE: once you have defined the bounds of the active window
- (struct cropcap.bounds) you must not change them.anymore.
- Only 'bounds' and 'defrect' fields are mandatory, other fields
- will be ignored.
- */
-
- int (*set_crop)(struct sn9c102_device* cam,
- const struct v4l2_rect* rect);
- /*
- To be called on VIDIOC_C_SETCROP. The core module always calls a
- default routine which configures the appropriate SN9C1XX regs (also
- scaling), but you may need to override/adjust specific stuff.
- 'rect' contains width and height values that are multiple of 16: in
- case you override the default function, you always have to program
- the chip to match those values; on error return the corresponding
- error code without rolling back.
- NOTE: in case, you must program the SN9C1XX chip to get rid of
- blank pixels or blank lines at the _start_ of each line or
- frame after each HSYNC or VSYNC, so that the image starts with
- real RGB data (see regs 0x12, 0x13) (having set H_SIZE and,
- V_SIZE you don't have to care about blank pixels or blank
- lines at the end of each line or frame).
- */
-
- struct v4l2_pix_format pix_format;
- /*
- What you have to define here are: 1) initial 'width' and 'height' of
- the target rectangle 2) the initial 'pixelformat', which can be
- either V4L2_PIX_FMT_SN9C10X, V4L2_PIX_FMT_JPEG (for ompressed video)
- or V4L2_PIX_FMT_SBGGR8 3) 'priv', which we'll be used to indicate
- the number of bits per pixel for uncompressed video, 8 or 9 (despite
- the current value of 'pixelformat').
- NOTE 1: both 'width' and 'height' _must_ be either 1/1 or 1/2 or 1/4
- of cropcap.defrect.width and cropcap.defrect.height. I
- suggest 1/1.
- NOTE 2: The initial compression quality is defined by the first bit
- of reg 0x17 during the initialization of the image sensor.
- NOTE 3: as said above, you have to program the SN9C1XX chip to get
- rid of any blank pixels, so that the output of the sensor
- matches the RGB bayer sequence (i.e. BGBGBG...GRGRGR).
- */
-
- int (*set_pix_format)(struct sn9c102_device* cam,
- const struct v4l2_pix_format* pix);
- /*
- To be called on VIDIOC_S_FMT, when switching from the SBGGR8 to
- SN9C10X pixel format or viceversa. On error return the corresponding
- error code without rolling back.
- */
-
- /*
- Do NOT write to the data below, it's READ ONLY. It is used by the
- core module to store successfully updated values of the above
- settings, for rollbacks..etc..in case of errors during atomic I/O
- */
- struct v4l2_queryctrl _qctrl[SN9C102_MAX_CTRLS];
- struct v4l2_rect _rect;
-};
-
-/*****************************************************************************/
-
-/* Private ioctl's for control settings supported by some image sensors */
-#define SN9C102_V4L2_CID_DAC_MAGNITUDE (V4L2_CID_PRIVATE_BASE + 0)
-#define SN9C102_V4L2_CID_GREEN_BALANCE (V4L2_CID_PRIVATE_BASE + 1)
-#define SN9C102_V4L2_CID_RESET_LEVEL (V4L2_CID_PRIVATE_BASE + 2)
-#define SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE (V4L2_CID_PRIVATE_BASE + 3)
-#define SN9C102_V4L2_CID_GAMMA (V4L2_CID_PRIVATE_BASE + 4)
-#define SN9C102_V4L2_CID_BAND_FILTER (V4L2_CID_PRIVATE_BASE + 5)
-#define SN9C102_V4L2_CID_BRIGHT_LEVEL (V4L2_CID_PRIVATE_BASE + 6)
-
-#endif /* _SN9C102_SENSOR_H_ */
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c b/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
deleted file mode 100644
index 04cdfdde856..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/***************************************************************************
- * Plug-in for TAS5110C1B image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int tas5110c1b_init(struct sn9c102_device* cam)
-{
- int err = 0;
-
- err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x44, 0x01},
- {0x00, 0x10}, {0x00, 0x11},
- {0x0a, 0x14}, {0x60, 0x17},
- {0x06, 0x18}, {0xfb, 0x19});
-
- err += sn9c102_i2c_write(cam, 0xc0, 0x80);
-
- return err;
-}
-
-
-static int tas5110c1b_set_ctrl(struct sn9c102_device* cam,
- const struct v4l2_control* ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int tas5110c1b_set_crop(struct sn9c102_device* cam,
- const struct v4l2_rect* rect)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- /* Don't change ! */
- err += sn9c102_write_reg(cam, 0x14, 0x1a);
- err += sn9c102_write_reg(cam, 0x0a, 0x1b);
- err += sn9c102_write_reg(cam, sn9c102_pread_reg(cam, 0x19), 0x19);
-
- return err;
-}
-
-
-static int tas5110c1b_set_pix_format(struct sn9c102_device* cam,
- const struct v4l2_pix_format* pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
- err += sn9c102_write_reg(cam, 0x2b, 0x19);
- else
- err += sn9c102_write_reg(cam, 0xfb, 0x19);
-
- return err;
-}
-
-
-static const struct sn9c102_sensor tas5110c1b = {
- .name = "TAS5110C1B",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
- .sysfs_ops = SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_3WIRES,
- .init = &tas5110c1b_init,
- .qctrl = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0xf6,
- .step = 0x01,
- .default_value = 0x40,
- .flags = 0,
- },
- },
- .set_ctrl = &tas5110c1b_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 352,
- .height = 288,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 352,
- .height = 288,
- },
- },
- .set_crop = &tas5110c1b_set_crop,
- .pix_format = {
- .width = 352,
- .height = 288,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &tas5110c1b_set_pix_format
-};
-
-
-int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam)
-{
- const struct usb_device_id tas5110c1b_id_table[] = {
- { USB_DEVICE(0x0c45, 0x6001), },
- { USB_DEVICE(0x0c45, 0x6005), },
- { USB_DEVICE(0x0c45, 0x60ab), },
- { }
- };
-
- /* Sensor detection is based on USB pid/vid */
- if (!sn9c102_match_id(cam, tas5110c1b_id_table))
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &tas5110c1b);
-
- return 0;
-}
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5110d.c b/drivers/media/video/sn9c102/sn9c102_tas5110d.c
deleted file mode 100644
index 9372e6f9fcf..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_tas5110d.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/***************************************************************************
- * Plug-in for TAS5110D image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int tas5110d_init(struct sn9c102_device* cam)
-{
- int err;
-
- err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x04, 0x01},
- {0x0a, 0x14}, {0x60, 0x17},
- {0x06, 0x18}, {0xfb, 0x19});
-
- err += sn9c102_i2c_write(cam, 0x9a, 0xca);
-
- return err;
-}
-
-
-static int tas5110d_set_crop(struct sn9c102_device* cam,
- const struct v4l2_rect* rect)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- err += sn9c102_write_reg(cam, 0x14, 0x1a);
- err += sn9c102_write_reg(cam, 0x0a, 0x1b);
-
- return err;
-}
-
-
-static int tas5110d_set_pix_format(struct sn9c102_device* cam,
- const struct v4l2_pix_format* pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
- err += sn9c102_write_reg(cam, 0x3b, 0x19);
- else
- err += sn9c102_write_reg(cam, 0xfb, 0x19);
-
- return err;
-}
-
-
-static const struct sn9c102_sensor tas5110d = {
- .name = "TAS5110D",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
- .sysfs_ops = SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x61,
- .init = &tas5110d_init,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 352,
- .height = 288,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 352,
- .height = 288,
- },
- },
- .set_crop = &tas5110d_set_crop,
- .pix_format = {
- .width = 352,
- .height = 288,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &tas5110d_set_pix_format
-};
-
-
-int sn9c102_probe_tas5110d(struct sn9c102_device* cam)
-{
- const struct usb_device_id tas5110d_id_table[] = {
- { USB_DEVICE(0x0c45, 0x6007), },
- { }
- };
-
- if (!sn9c102_match_id(cam, tas5110d_id_table))
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &tas5110d);
-
- return 0;
-}
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c b/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
deleted file mode 100644
index a30bbc4389f..00000000000
--- a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/***************************************************************************
- * Plug-in for TAS5130D1B image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int tas5130d1b_init(struct sn9c102_device* cam)
-{
- int err;
-
- err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x20, 0x17},
- {0x04, 0x01}, {0x01, 0x10},
- {0x00, 0x11}, {0x00, 0x14},
- {0x60, 0x17}, {0x07, 0x18});
-
- return err;
-}
-
-
-static int tas5130d1b_set_ctrl(struct sn9c102_device* cam,
- const struct v4l2_control* ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value);
- break;
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_write(cam, 0x40, 0x47 - ctrl->value);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int tas5130d1b_set_crop(struct sn9c102_device* cam,
- const struct v4l2_rect* rect)
-{
- struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 104,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 12;
- int err = 0;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- /* Do NOT change! */
- err += sn9c102_write_reg(cam, 0x1f, 0x1a);
- err += sn9c102_write_reg(cam, 0x1a, 0x1b);
- err += sn9c102_write_reg(cam, sn9c102_pread_reg(cam, 0x19), 0x19);
-
- return err;
-}
-
-
-static int tas5130d1b_set_pix_format(struct sn9c102_device* cam,
- const struct v4l2_pix_format* pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
- err += sn9c102_write_reg(cam, 0x63, 0x19);
- else
- err += sn9c102_write_reg(cam, 0xf3, 0x19);
-
- return err;
-}
-
-
-static const struct sn9c102_sensor tas5130d1b = {
- .name = "TAS5130D1B",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
- .sysfs_ops = SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_3WIRES,
- .init = &tas5130d1b_init,
- .qctrl = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0xf6,
- .step = 0x02,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0x47,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- },
- .set_ctrl = &tas5130d1b_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &tas5130d1b_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &tas5130d1b_set_pix_format
-};
-
-
-int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam)
-{
- const struct usb_device_id tas5130d1b_id_table[] = {
- { USB_DEVICE(0x0c45, 0x6024), },
- { USB_DEVICE(0x0c45, 0x6025), },
- { USB_DEVICE(0x0c45, 0x60aa), },
- { }
- };
-
- /* Sensor detection is based on USB pid/vid */
- if (!sn9c102_match_id(cam, tas5130d1b_id_table))
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &tas5130d1b);
-
- return 0;
-}
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
deleted file mode 100644
index 1bde255e45d..00000000000
--- a/drivers/media/video/soc_camera.c
+++ /dev/null
@@ -1,1546 +0,0 @@
-/*
- * camera image capture (abstract) bus driver
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This driver provides an interface between platform-specific camera
- * busses and camera devices. It should be used if the camera is
- * connected not over a "proper" bus like PCI or USB, but over a
- * special bus, like, for example, the Quick Capture interface on PXA270
- * SoCs. Later it should also be used for i.MX31 SoCs from Freescale.
- * It can handle multiple cameras and / or multiple busses, which can
- * be used, e.g., in stereo-vision applications.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/pm_runtime.h>
-#include <linux/vmalloc.h>
-
-#include <media/soc_camera.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-dev.h>
-#include <media/videobuf-core.h>
-#include <media/videobuf2-core.h>
-#include <media/soc_mediabus.h>
-
-/* Default to VGA resolution */
-#define DEFAULT_WIDTH 640
-#define DEFAULT_HEIGHT 480
-
-#define is_streaming(ici, icd) \
- (((ici)->ops->init_videobuf) ? \
- (icd)->vb_vidq.streaming : \
- vb2_is_streaming(&(icd)->vb2_vidq))
-
-static LIST_HEAD(hosts);
-static LIST_HEAD(devices);
-static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */
-
-static int soc_camera_power_on(struct soc_camera_device *icd,
- struct soc_camera_link *icl)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- int ret = regulator_bulk_enable(icl->num_regulators,
- icl->regulators);
- if (ret < 0) {
- dev_err(icd->pdev, "Cannot enable regulators\n");
- return ret;
- }
-
- if (icl->power) {
- ret = icl->power(icd->control, 1);
- if (ret < 0) {
- dev_err(icd->pdev,
- "Platform failed to power-on the camera.\n");
- goto elinkpwr;
- }
- }
-
- ret = v4l2_subdev_call(sd, core, s_power, 1);
- if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
- goto esdpwr;
-
- return 0;
-
-esdpwr:
- if (icl->power)
- icl->power(icd->control, 0);
-elinkpwr:
- regulator_bulk_disable(icl->num_regulators,
- icl->regulators);
- return ret;
-}
-
-static int soc_camera_power_off(struct soc_camera_device *icd,
- struct soc_camera_link *icl)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- int ret = v4l2_subdev_call(sd, core, s_power, 0);
-
- if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
- return ret;
-
- if (icl->power) {
- ret = icl->power(icd->control, 0);
- if (ret < 0) {
- dev_err(icd->pdev,
- "Platform failed to power-off the camera.\n");
- return ret;
- }
- }
-
- ret = regulator_bulk_disable(icl->num_regulators,
- icl->regulators);
- if (ret < 0)
- dev_err(icd->pdev, "Cannot disable regulators\n");
-
- return ret;
-}
-
-const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
- struct soc_camera_device *icd, unsigned int fourcc)
-{
- unsigned int i;
-
- for (i = 0; i < icd->num_user_formats; i++)
- if (icd->user_formats[i].host_fmt->fourcc == fourcc)
- return icd->user_formats + i;
- return NULL;
-}
-EXPORT_SYMBOL(soc_camera_xlate_by_fourcc);
-
-/**
- * soc_camera_apply_board_flags() - apply platform SOCAM_SENSOR_INVERT_* flags
- * @icl: camera platform parameters
- * @cfg: media bus configuration
- * @return: resulting flags
- */
-unsigned long soc_camera_apply_board_flags(struct soc_camera_link *icl,
- const struct v4l2_mbus_config *cfg)
-{
- unsigned long f, flags = cfg->flags;
-
- /* If only one of the two polarities is supported, switch to the opposite */
- if (icl->flags & SOCAM_SENSOR_INVERT_HSYNC) {
- f = flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW);
- if (f == V4L2_MBUS_HSYNC_ACTIVE_HIGH || f == V4L2_MBUS_HSYNC_ACTIVE_LOW)
- flags ^= V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW;
- }
-
- if (icl->flags & SOCAM_SENSOR_INVERT_VSYNC) {
- f = flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW);
- if (f == V4L2_MBUS_VSYNC_ACTIVE_HIGH || f == V4L2_MBUS_VSYNC_ACTIVE_LOW)
- flags ^= V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW;
- }
-
- if (icl->flags & SOCAM_SENSOR_INVERT_PCLK) {
- f = flags & (V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING);
- if (f == V4L2_MBUS_PCLK_SAMPLE_RISING || f == V4L2_MBUS_PCLK_SAMPLE_FALLING)
- flags ^= V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING;
- }
-
- return flags;
-}
-EXPORT_SYMBOL(soc_camera_apply_board_flags);
-
-#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
- ((x) >> 24) & 0xff
-
-static int soc_camera_try_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- int ret;
-
- dev_dbg(icd->pdev, "TRY_FMT(%c%c%c%c, %ux%u)\n",
- pixfmtstr(pix->pixelformat), pix->width, pix->height);
-
- if (pix->pixelformat != V4L2_PIX_FMT_JPEG &&
- !(ici->capabilities & SOCAM_HOST_CAP_STRIDE)) {
- pix->bytesperline = 0;
- pix->sizeimage = 0;
- }
-
- ret = ici->ops->try_fmt(icd, f);
- if (ret < 0)
- return ret;
-
- xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
- if (!xlate)
- return -EINVAL;
-
- ret = soc_mbus_bytes_per_line(pix->width, xlate->host_fmt);
- if (ret < 0)
- return ret;
-
- pix->bytesperline = max_t(u32, pix->bytesperline, ret);
-
- ret = soc_mbus_image_size(xlate->host_fmt, pix->bytesperline,
- pix->height);
- if (ret < 0)
- return ret;
-
- pix->sizeimage = max_t(u32, pix->sizeimage, ret);
-
- return 0;
-}
-
-static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct soc_camera_device *icd = file->private_data;
-
- WARN_ON(priv != file->private_data);
-
- /* Only single-plane capture is supported so far */
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- /* limit format to hardware capabilities */
- return soc_camera_try_fmt(icd, f);
-}
-
-static int soc_camera_enum_input(struct file *file, void *priv,
- struct v4l2_input *inp)
-{
- if (inp->index != 0)
- return -EINVAL;
-
- /* default is camera */
- inp->type = V4L2_INPUT_TYPE_CAMERA;
- inp->std = V4L2_STD_UNKNOWN;
- strcpy(inp->name, "Camera");
-
- return 0;
-}
-
-static int soc_camera_g_input(struct file *file, void *priv, unsigned int *i)
-{
- *i = 0;
-
- return 0;
-}
-
-static int soc_camera_s_input(struct file *file, void *priv, unsigned int i)
-{
- if (i > 0)
- return -EINVAL;
-
- return 0;
-}
-
-static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
-{
- struct soc_camera_device *icd = file->private_data;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
- return v4l2_subdev_call(sd, core, s_std, *a);
-}
-
-static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a)
-{
- struct soc_camera_device *icd = file->private_data;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
- return v4l2_subdev_call(sd, core, g_std, a);
-}
-
-static int soc_camera_enum_framesizes(struct file *file, void *fh,
- struct v4l2_frmsizeenum *fsize)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- return ici->ops->enum_framesizes(icd, fsize);
-}
-
-static int soc_camera_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- int ret;
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- WARN_ON(priv != file->private_data);
-
- if (icd->streamer && icd->streamer != file)
- return -EBUSY;
-
- if (ici->ops->init_videobuf) {
- ret = videobuf_reqbufs(&icd->vb_vidq, p);
- if (ret < 0)
- return ret;
-
- ret = ici->ops->reqbufs(icd, p);
- } else {
- ret = vb2_reqbufs(&icd->vb2_vidq, p);
- }
-
- if (!ret && !icd->streamer)
- icd->streamer = file;
-
- return ret;
-}
-
-static int soc_camera_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- WARN_ON(priv != file->private_data);
-
- if (ici->ops->init_videobuf)
- return videobuf_querybuf(&icd->vb_vidq, p);
- else
- return vb2_querybuf(&icd->vb2_vidq, p);
-}
-
-static int soc_camera_qbuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- WARN_ON(priv != file->private_data);
-
- if (icd->streamer != file)
- return -EBUSY;
-
- if (ici->ops->init_videobuf)
- return videobuf_qbuf(&icd->vb_vidq, p);
- else
- return vb2_qbuf(&icd->vb2_vidq, p);
-}
-
-static int soc_camera_dqbuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- WARN_ON(priv != file->private_data);
-
- if (icd->streamer != file)
- return -EBUSY;
-
- if (ici->ops->init_videobuf)
- return videobuf_dqbuf(&icd->vb_vidq, p, file->f_flags & O_NONBLOCK);
- else
- return vb2_dqbuf(&icd->vb2_vidq, p, file->f_flags & O_NONBLOCK);
-}
-
-static int soc_camera_create_bufs(struct file *file, void *priv,
- struct v4l2_create_buffers *create)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- /* videobuf2 only */
- if (ici->ops->init_videobuf)
- return -EINVAL;
- else
- return vb2_create_bufs(&icd->vb2_vidq, create);
-}
-
-static int soc_camera_prepare_buf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- /* videobuf2 only */
- if (ici->ops->init_videobuf)
- return -EINVAL;
- else
- return vb2_prepare_buf(&icd->vb2_vidq, b);
-}
-
-/* Always entered with .video_lock held */
-static int soc_camera_init_user_formats(struct soc_camera_device *icd)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- unsigned int i, fmts = 0, raw_fmts = 0;
- int ret;
- enum v4l2_mbus_pixelcode code;
-
- while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, raw_fmts, &code))
- raw_fmts++;
-
- if (!ici->ops->get_formats)
- /*
- * Fallback mode - the host will have to serve all
- * sensor-provided formats one-to-one to the user
- */
- fmts = raw_fmts;
- else
- /*
- * First pass - only count formats this host-sensor
- * configuration can provide
- */
- for (i = 0; i < raw_fmts; i++) {
- ret = ici->ops->get_formats(icd, i, NULL);
- if (ret < 0)
- return ret;
- fmts += ret;
- }
-
- if (!fmts)
- return -ENXIO;
-
- icd->user_formats =
- vmalloc(fmts * sizeof(struct soc_camera_format_xlate));
- if (!icd->user_formats)
- return -ENOMEM;
-
- dev_dbg(icd->pdev, "Found %d supported formats.\n", fmts);
-
- /* Second pass - actually fill data formats */
- fmts = 0;
- for (i = 0; i < raw_fmts; i++)
- if (!ici->ops->get_formats) {
- v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code);
- icd->user_formats[fmts].host_fmt =
- soc_mbus_get_fmtdesc(code);
- if (icd->user_formats[fmts].host_fmt)
- icd->user_formats[fmts++].code = code;
- } else {
- ret = ici->ops->get_formats(icd, i,
- &icd->user_formats[fmts]);
- if (ret < 0)
- goto egfmt;
- fmts += ret;
- }
-
- icd->num_user_formats = fmts;
- icd->current_fmt = &icd->user_formats[0];
-
- return 0;
-
-egfmt:
- vfree(icd->user_formats);
- return ret;
-}
-
-/* Always entered with .video_lock held */
-static void soc_camera_free_user_formats(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- if (ici->ops->put_formats)
- ici->ops->put_formats(icd);
- icd->current_fmt = NULL;
- icd->num_user_formats = 0;
- vfree(icd->user_formats);
- icd->user_formats = NULL;
-}
-
-/* Called with .vb_lock held, or from the first open(2), see comment there */
-static int soc_camera_set_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct v4l2_pix_format *pix = &f->fmt.pix;
- int ret;
-
- dev_dbg(icd->pdev, "S_FMT(%c%c%c%c, %ux%u)\n",
- pixfmtstr(pix->pixelformat), pix->width, pix->height);
-
- /* We always call try_fmt() before set_fmt() or set_crop() */
- ret = soc_camera_try_fmt(icd, f);
- if (ret < 0)
- return ret;
-
- ret = ici->ops->set_fmt(icd, f);
- if (ret < 0) {
- return ret;
- } else if (!icd->current_fmt ||
- icd->current_fmt->host_fmt->fourcc != pix->pixelformat) {
- dev_err(icd->pdev,
- "Host driver hasn't set up current format correctly!\n");
- return -EINVAL;
- }
-
- icd->user_width = pix->width;
- icd->user_height = pix->height;
- icd->bytesperline = pix->bytesperline;
- icd->sizeimage = pix->sizeimage;
- icd->colorspace = pix->colorspace;
- icd->field = pix->field;
- if (ici->ops->init_videobuf)
- icd->vb_vidq.field = pix->field;
-
- dev_dbg(icd->pdev, "set width: %d height: %d\n",
- icd->user_width, icd->user_height);
-
- /* set physical bus parameters */
- return ici->ops->set_bus_param(icd);
-}
-
-static int soc_camera_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct soc_camera_device *icd = dev_get_drvdata(vdev->parent);
- struct soc_camera_link *icl = to_soc_camera_link(icd);
- struct soc_camera_host *ici;
- int ret;
-
- if (!to_soc_camera_control(icd))
- /* No device driver attached */
- return -ENODEV;
-
- ici = to_soc_camera_host(icd->parent);
-
- if (!try_module_get(ici->ops->owner)) {
- dev_err(icd->pdev, "Couldn't lock capture bus driver.\n");
- return -EINVAL;
- }
-
- icd->use_count++;
-
- /* Now we really have to activate the camera */
- if (icd->use_count == 1) {
- /* Restore parameters before the last close() per V4L2 API */
- struct v4l2_format f = {
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- .fmt.pix = {
- .width = icd->user_width,
- .height = icd->user_height,
- .field = icd->field,
- .colorspace = icd->colorspace,
- .pixelformat =
- icd->current_fmt->host_fmt->fourcc,
- },
- };
-
- /* The camera could have been already on, try to reset */
- if (icl->reset)
- icl->reset(icd->pdev);
-
- /* Don't mess with the host during probe */
- mutex_lock(&ici->host_lock);
- ret = ici->ops->add(icd);
- mutex_unlock(&ici->host_lock);
- if (ret < 0) {
- dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret);
- goto eiciadd;
- }
-
- ret = soc_camera_power_on(icd, icl);
- if (ret < 0)
- goto epower;
-
- pm_runtime_enable(&icd->vdev->dev);
- ret = pm_runtime_resume(&icd->vdev->dev);
- if (ret < 0 && ret != -ENOSYS)
- goto eresume;
-
- /*
- * Try to configure with default parameters. Notice: this is the
- * very first open, so, we cannot race against other calls,
- * apart from someone else calling open() simultaneously, but
- * .video_lock is protecting us against it.
- */
- ret = soc_camera_set_fmt(icd, &f);
- if (ret < 0)
- goto esfmt;
-
- if (ici->ops->init_videobuf) {
- ici->ops->init_videobuf(&icd->vb_vidq, icd);
- } else {
- ret = ici->ops->init_videobuf2(&icd->vb2_vidq, icd);
- if (ret < 0)
- goto einitvb;
- }
- v4l2_ctrl_handler_setup(&icd->ctrl_handler);
- }
-
- file->private_data = icd;
- dev_dbg(icd->pdev, "camera device open\n");
-
- return 0;
-
- /*
- * First four errors are entered with the .video_lock held
- * and use_count == 1
- */
-einitvb:
-esfmt:
- pm_runtime_disable(&icd->vdev->dev);
-eresume:
- soc_camera_power_off(icd, icl);
-epower:
- ici->ops->remove(icd);
-eiciadd:
- icd->use_count--;
- module_put(ici->ops->owner);
-
- return ret;
-}
-
-static int soc_camera_close(struct file *file)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- icd->use_count--;
- if (!icd->use_count) {
- struct soc_camera_link *icl = to_soc_camera_link(icd);
-
- pm_runtime_suspend(&icd->vdev->dev);
- pm_runtime_disable(&icd->vdev->dev);
-
- if (ici->ops->init_videobuf2)
- vb2_queue_release(&icd->vb2_vidq);
- ici->ops->remove(icd);
-
- soc_camera_power_off(icd, icl);
- }
-
- if (icd->streamer == file)
- icd->streamer = NULL;
-
- module_put(ici->ops->owner);
-
- dev_dbg(icd->pdev, "camera device close\n");
-
- return 0;
-}
-
-static ssize_t soc_camera_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct soc_camera_device *icd = file->private_data;
- int err = -EINVAL;
-
- dev_err(icd->pdev, "camera device read not implemented\n");
-
- return err;
-}
-
-static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- int err;
-
- dev_dbg(icd->pdev, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
-
- if (icd->streamer != file)
- return -EBUSY;
-
- if (ici->ops->init_videobuf)
- err = videobuf_mmap_mapper(&icd->vb_vidq, vma);
- else
- err = vb2_mmap(&icd->vb2_vidq, vma);
-
- dev_dbg(icd->pdev, "vma start=0x%08lx, size=%ld, ret=%d\n",
- (unsigned long)vma->vm_start,
- (unsigned long)vma->vm_end - (unsigned long)vma->vm_start,
- err);
-
- return err;
-}
-
-static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- if (icd->streamer != file)
- return -EBUSY;
-
- if (ici->ops->init_videobuf && list_empty(&icd->vb_vidq.stream)) {
- dev_err(icd->pdev, "Trying to poll with no queued buffers!\n");
- return POLLERR;
- }
-
- return ici->ops->poll(file, pt);
-}
-
-void soc_camera_lock(struct vb2_queue *vq)
-{
- struct soc_camera_device *icd = vb2_get_drv_priv(vq);
- mutex_lock(&icd->video_lock);
-}
-EXPORT_SYMBOL(soc_camera_lock);
-
-void soc_camera_unlock(struct vb2_queue *vq)
-{
- struct soc_camera_device *icd = vb2_get_drv_priv(vq);
- mutex_unlock(&icd->video_lock);
-}
-EXPORT_SYMBOL(soc_camera_unlock);
-
-static struct v4l2_file_operations soc_camera_fops = {
- .owner = THIS_MODULE,
- .open = soc_camera_open,
- .release = soc_camera_close,
- .unlocked_ioctl = video_ioctl2,
- .read = soc_camera_read,
- .mmap = soc_camera_mmap,
- .poll = soc_camera_poll,
-};
-
-static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct soc_camera_device *icd = file->private_data;
- int ret;
-
- WARN_ON(priv != file->private_data);
-
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- dev_warn(icd->pdev, "Wrong buf-type %d\n", f->type);
- return -EINVAL;
- }
-
- if (icd->streamer && icd->streamer != file)
- return -EBUSY;
-
- if (is_streaming(to_soc_camera_host(icd->parent), icd)) {
- dev_err(icd->pdev, "S_FMT denied: queue initialised\n");
- return -EBUSY;
- }
-
- ret = soc_camera_set_fmt(icd, f);
-
- if (!ret && !icd->streamer)
- icd->streamer = file;
-
- return ret;
-}
-
-static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct soc_camera_device *icd = file->private_data;
- const struct soc_mbus_pixelfmt *format;
-
- WARN_ON(priv != file->private_data);
-
- if (f->index >= icd->num_user_formats)
- return -EINVAL;
-
- format = icd->user_formats[f->index].host_fmt;
-
- if (format->name)
- strlcpy(f->description, format->name, sizeof(f->description));
- f->pixelformat = format->fourcc;
- return 0;
-}
-
-static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct soc_camera_device *icd = file->private_data;
- struct v4l2_pix_format *pix = &f->fmt.pix;
-
- WARN_ON(priv != file->private_data);
-
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- pix->width = icd->user_width;
- pix->height = icd->user_height;
- pix->bytesperline = icd->bytesperline;
- pix->sizeimage = icd->sizeimage;
- pix->field = icd->field;
- pix->pixelformat = icd->current_fmt->host_fmt->fourcc;
- pix->colorspace = icd->colorspace;
- dev_dbg(icd->pdev, "current_fmt->fourcc: 0x%08x\n",
- icd->current_fmt->host_fmt->fourcc);
- return 0;
-}
-
-static int soc_camera_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- WARN_ON(priv != file->private_data);
-
- strlcpy(cap->driver, ici->drv_name, sizeof(cap->driver));
- return ici->ops->querycap(ici, cap);
-}
-
-static int soc_camera_streamon(struct file *file, void *priv,
- enum v4l2_buf_type i)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- int ret;
-
- WARN_ON(priv != file->private_data);
-
- if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (icd->streamer != file)
- return -EBUSY;
-
- /* This calls buf_queue from host driver's videobuf_queue_ops */
- if (ici->ops->init_videobuf)
- ret = videobuf_streamon(&icd->vb_vidq);
- else
- ret = vb2_streamon(&icd->vb2_vidq, i);
-
- if (!ret)
- v4l2_subdev_call(sd, video, s_stream, 1);
-
- return ret;
-}
-
-static int soc_camera_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type i)
-{
- struct soc_camera_device *icd = file->private_data;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- WARN_ON(priv != file->private_data);
-
- if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (icd->streamer != file)
- return -EBUSY;
-
- /*
- * This calls buf_release from host driver's videobuf_queue_ops for all
- * remaining buffers. When the last buffer is freed, stop capture
- */
- if (ici->ops->init_videobuf)
- videobuf_streamoff(&icd->vb_vidq);
- else
- vb2_streamoff(&icd->vb2_vidq, i);
-
- v4l2_subdev_call(sd, video, s_stream, 0);
-
- return 0;
-}
-
-static int soc_camera_cropcap(struct file *file, void *fh,
- struct v4l2_cropcap *a)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- return ici->ops->cropcap(icd, a);
-}
-
-static int soc_camera_g_crop(struct file *file, void *fh,
- struct v4l2_crop *a)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- int ret;
-
- ret = ici->ops->get_crop(icd, a);
-
- return ret;
-}
-
-/*
- * According to the V4L2 API, drivers shall not update the struct v4l2_crop
- * argument with the actual geometry, instead, the user shall use G_CROP to
- * retrieve it.
- */
-static int soc_camera_s_crop(struct file *file, void *fh,
- struct v4l2_crop *a)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct v4l2_rect *rect = &a->c;
- struct v4l2_crop current_crop;
- int ret;
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- dev_dbg(icd->pdev, "S_CROP(%ux%u@%u:%u)\n",
- rect->width, rect->height, rect->left, rect->top);
-
- /* If get_crop fails, we'll let host and / or client drivers decide */
- ret = ici->ops->get_crop(icd, &current_crop);
-
- /* Prohibit window size change with initialised buffers */
- if (ret < 0) {
- dev_err(icd->pdev,
- "S_CROP denied: getting current crop failed\n");
- } else if ((a->c.width == current_crop.c.width &&
- a->c.height == current_crop.c.height) ||
- !is_streaming(ici, icd)) {
- /* same size or not streaming - use .set_crop() */
- ret = ici->ops->set_crop(icd, a);
- } else if (ici->ops->set_livecrop) {
- ret = ici->ops->set_livecrop(icd, a);
- } else {
- dev_err(icd->pdev,
- "S_CROP denied: queue initialised and sizes differ\n");
- ret = -EBUSY;
- }
-
- return ret;
-}
-
-static int soc_camera_g_parm(struct file *file, void *fh,
- struct v4l2_streamparm *a)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- if (ici->ops->get_parm)
- return ici->ops->get_parm(icd, a);
-
- return -ENOIOCTLCMD;
-}
-
-static int soc_camera_s_parm(struct file *file, void *fh,
- struct v4l2_streamparm *a)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-
- if (ici->ops->set_parm)
- return ici->ops->set_parm(icd, a);
-
- return -ENOIOCTLCMD;
-}
-
-static int soc_camera_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *id)
-{
- struct soc_camera_device *icd = file->private_data;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
- return v4l2_subdev_call(sd, core, g_chip_ident, id);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int soc_camera_g_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct soc_camera_device *icd = file->private_data;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
- return v4l2_subdev_call(sd, core, g_register, reg);
-}
-
-static int soc_camera_s_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct soc_camera_device *icd = file->private_data;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
- return v4l2_subdev_call(sd, core, s_register, reg);
-}
-#endif
-
-static int soc_camera_probe(struct soc_camera_device *icd);
-
-/* So far this function cannot fail */
-static void scan_add_host(struct soc_camera_host *ici)
-{
- struct soc_camera_device *icd;
-
- mutex_lock(&ici->host_lock);
-
- list_for_each_entry(icd, &devices, list) {
- if (icd->iface == ici->nr) {
- int ret;
-
- icd->parent = ici->v4l2_dev.dev;
- ret = soc_camera_probe(icd);
- }
- }
-
- mutex_unlock(&ici->host_lock);
-}
-
-#ifdef CONFIG_I2C_BOARDINFO
-static int soc_camera_init_i2c(struct soc_camera_device *icd,
- struct soc_camera_link *icl)
-{
- struct i2c_client *client;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id);
- struct v4l2_subdev *subdev;
-
- if (!adap) {
- dev_err(icd->pdev, "Cannot get I2C adapter #%d. No driver?\n",
- icl->i2c_adapter_id);
- goto ei2cga;
- }
-
- icl->board_info->platform_data = icl;
-
- subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
- icl->board_info, NULL);
- if (!subdev)
- goto ei2cnd;
-
- client = v4l2_get_subdevdata(subdev);
-
- /* Use to_i2c_client(dev) to recover the i2c client */
- icd->control = &client->dev;
-
- return 0;
-ei2cnd:
- i2c_put_adapter(adap);
-ei2cga:
- return -ENODEV;
-}
-
-static void soc_camera_free_i2c(struct soc_camera_device *icd)
-{
- struct i2c_client *client =
- to_i2c_client(to_soc_camera_control(icd));
- struct i2c_adapter *adap = client->adapter;
-
- icd->control = NULL;
- v4l2_device_unregister_subdev(i2c_get_clientdata(client));
- i2c_unregister_device(client);
- i2c_put_adapter(adap);
-}
-#else
-#define soc_camera_init_i2c(icd, icl) (-ENODEV)
-#define soc_camera_free_i2c(icd) do {} while (0)
-#endif
-
-static int soc_camera_video_start(struct soc_camera_device *icd);
-static int video_dev_create(struct soc_camera_device *icd);
-/* Called during host-driver probe */
-static int soc_camera_probe(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct soc_camera_link *icl = to_soc_camera_link(icd);
- struct device *control = NULL;
- struct v4l2_subdev *sd;
- struct v4l2_mbus_framefmt mf;
- int ret;
-
- dev_info(icd->pdev, "Probing %s\n", dev_name(icd->pdev));
-
- /*
- * Currently the subdev with the largest number of controls (13) is
- * ov6550. So let's pick 16 as a hint for the control handler. Note
- * that this is a hint only: too large and you waste some memory, too
- * small and there is a (very) small performance hit when looking up
- * controls in the internal hash.
- */
- ret = v4l2_ctrl_handler_init(&icd->ctrl_handler, 16);
- if (ret < 0)
- return ret;
-
- ret = regulator_bulk_get(icd->pdev, icl->num_regulators,
- icl->regulators);
- if (ret < 0)
- goto ereg;
-
- /* The camera could have been already on, try to reset */
- if (icl->reset)
- icl->reset(icd->pdev);
-
- ret = ici->ops->add(icd);
- if (ret < 0)
- goto eadd;
-
- /*
- * This will not yet call v4l2_subdev_core_ops::s_power(1), because the
- * subdevice has not been initialised yet. We'll have to call it once
- * again after initialisation, even though it shouldn't be needed, we
- * don't do any IO here.
- */
- ret = soc_camera_power_on(icd, icl);
- if (ret < 0)
- goto epower;
-
- /* Must have icd->vdev before registering the device */
- ret = video_dev_create(icd);
- if (ret < 0)
- goto evdc;
-
- /* Non-i2c cameras, e.g., soc_camera_platform, have no board_info */
- if (icl->board_info) {
- ret = soc_camera_init_i2c(icd, icl);
- if (ret < 0)
- goto eadddev;
- } else if (!icl->add_device || !icl->del_device) {
- ret = -EINVAL;
- goto eadddev;
- } else {
- if (icl->module_name)
- ret = request_module(icl->module_name);
-
- ret = icl->add_device(icd);
- if (ret < 0)
- goto eadddev;
-
- /*
- * FIXME: this is racy, have to use driver-binding notification,
- * when it is available
- */
- control = to_soc_camera_control(icd);
- if (!control || !control->driver || !dev_get_drvdata(control) ||
- !try_module_get(control->driver->owner)) {
- icl->del_device(icd);
- ret = -ENODEV;
- goto enodrv;
- }
- }
-
- sd = soc_camera_to_subdev(icd);
- sd->grp_id = soc_camera_grp_id(icd);
- v4l2_set_subdev_hostdata(sd, icd);
-
- if (v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler))
- goto ectrl;
-
- /* At this point client .probe() should have run already */
- ret = soc_camera_init_user_formats(icd);
- if (ret < 0)
- goto eiufmt;
-
- icd->field = V4L2_FIELD_ANY;
-
- /*
- * ..._video_start() will create a device node, video_register_device()
- * itself is protected against concurrent open() calls, but we also have
- * to protect our data.
- */
- mutex_lock(&icd->video_lock);
-
- ret = soc_camera_video_start(icd);
- if (ret < 0)
- goto evidstart;
-
- ret = v4l2_subdev_call(sd, core, s_power, 1);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- goto esdpwr;
-
- /* Try to improve our guess of a reasonable window format */
- if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
- icd->user_width = mf.width;
- icd->user_height = mf.height;
- icd->colorspace = mf.colorspace;
- icd->field = mf.field;
- }
-
- ici->ops->remove(icd);
-
- soc_camera_power_off(icd, icl);
-
- mutex_unlock(&icd->video_lock);
-
- return 0;
-
-esdpwr:
- video_unregister_device(icd->vdev);
-evidstart:
- mutex_unlock(&icd->video_lock);
- soc_camera_free_user_formats(icd);
-eiufmt:
-ectrl:
- if (icl->board_info) {
- soc_camera_free_i2c(icd);
- } else {
- icl->del_device(icd);
- module_put(control->driver->owner);
- }
-enodrv:
-eadddev:
- video_device_release(icd->vdev);
- icd->vdev = NULL;
-evdc:
- soc_camera_power_off(icd, icl);
-epower:
- ici->ops->remove(icd);
-eadd:
- regulator_bulk_free(icl->num_regulators, icl->regulators);
-ereg:
- v4l2_ctrl_handler_free(&icd->ctrl_handler);
- return ret;
-}
-
-/*
- * This is called on device_unregister, which only means we have to disconnect
- * from the host, but not remove ourselves from the device list
- */
-static int soc_camera_remove(struct soc_camera_device *icd)
-{
- struct soc_camera_link *icl = to_soc_camera_link(icd);
- struct video_device *vdev = icd->vdev;
-
- BUG_ON(!icd->parent);
-
- v4l2_ctrl_handler_free(&icd->ctrl_handler);
- if (vdev) {
- video_unregister_device(vdev);
- icd->vdev = NULL;
- }
-
- if (icl->board_info) {
- soc_camera_free_i2c(icd);
- } else {
- struct device_driver *drv = to_soc_camera_control(icd)->driver;
- if (drv) {
- icl->del_device(icd);
- module_put(drv->owner);
- }
- }
- soc_camera_free_user_formats(icd);
-
- regulator_bulk_free(icl->num_regulators, icl->regulators);
-
- return 0;
-}
-
-static int default_cropcap(struct soc_camera_device *icd,
- struct v4l2_cropcap *a)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- return v4l2_subdev_call(sd, video, cropcap, a);
-}
-
-static int default_g_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- return v4l2_subdev_call(sd, video, g_crop, a);
-}
-
-static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- return v4l2_subdev_call(sd, video, s_crop, a);
-}
-
-static int default_g_parm(struct soc_camera_device *icd,
- struct v4l2_streamparm *parm)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- return v4l2_subdev_call(sd, video, g_parm, parm);
-}
-
-static int default_s_parm(struct soc_camera_device *icd,
- struct v4l2_streamparm *parm)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- return v4l2_subdev_call(sd, video, s_parm, parm);
-}
-
-static int default_enum_framesizes(struct soc_camera_device *icd,
- struct v4l2_frmsizeenum *fsize)
-{
- int ret;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- __u32 pixfmt = fsize->pixel_format;
- struct v4l2_frmsizeenum fsize_mbus = *fsize;
-
- xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
- if (!xlate)
- return -EINVAL;
- /* map xlate-code to pixel_format, sensor only handle xlate-code*/
- fsize_mbus.pixel_format = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, enum_framesizes, &fsize_mbus);
- if (ret < 0)
- return ret;
-
- *fsize = fsize_mbus;
- fsize->pixel_format = pixfmt;
-
- return 0;
-}
-
-int soc_camera_host_register(struct soc_camera_host *ici)
-{
- struct soc_camera_host *ix;
- int ret;
-
- if (!ici || !ici->ops ||
- !ici->ops->try_fmt ||
- !ici->ops->set_fmt ||
- !ici->ops->set_bus_param ||
- !ici->ops->querycap ||
- ((!ici->ops->init_videobuf ||
- !ici->ops->reqbufs) &&
- !ici->ops->init_videobuf2) ||
- !ici->ops->add ||
- !ici->ops->remove ||
- !ici->ops->poll ||
- !ici->v4l2_dev.dev)
- return -EINVAL;
-
- if (!ici->ops->set_crop)
- ici->ops->set_crop = default_s_crop;
- if (!ici->ops->get_crop)
- ici->ops->get_crop = default_g_crop;
- if (!ici->ops->cropcap)
- ici->ops->cropcap = default_cropcap;
- if (!ici->ops->set_parm)
- ici->ops->set_parm = default_s_parm;
- if (!ici->ops->get_parm)
- ici->ops->get_parm = default_g_parm;
- if (!ici->ops->enum_framesizes)
- ici->ops->enum_framesizes = default_enum_framesizes;
-
- mutex_lock(&list_lock);
- list_for_each_entry(ix, &hosts, list) {
- if (ix->nr == ici->nr) {
- ret = -EBUSY;
- goto edevreg;
- }
- }
-
- ret = v4l2_device_register(ici->v4l2_dev.dev, &ici->v4l2_dev);
- if (ret < 0)
- goto edevreg;
-
- list_add_tail(&ici->list, &hosts);
- mutex_unlock(&list_lock);
-
- mutex_init(&ici->host_lock);
- scan_add_host(ici);
-
- return 0;
-
-edevreg:
- mutex_unlock(&list_lock);
- return ret;
-}
-EXPORT_SYMBOL(soc_camera_host_register);
-
-/* Unregister all clients! */
-void soc_camera_host_unregister(struct soc_camera_host *ici)
-{
- struct soc_camera_device *icd;
-
- mutex_lock(&list_lock);
-
- list_del(&ici->list);
- list_for_each_entry(icd, &devices, list)
- if (icd->iface == ici->nr && to_soc_camera_control(icd))
- soc_camera_remove(icd);
-
- mutex_unlock(&list_lock);
-
- v4l2_device_unregister(&ici->v4l2_dev);
-}
-EXPORT_SYMBOL(soc_camera_host_unregister);
-
-/* Image capture device */
-static int soc_camera_device_register(struct soc_camera_device *icd)
-{
- struct soc_camera_device *ix;
- int num = -1, i;
-
- for (i = 0; i < 256 && num < 0; i++) {
- num = i;
- /* Check if this index is available on this interface */
- list_for_each_entry(ix, &devices, list) {
- if (ix->iface == icd->iface && ix->devnum == i) {
- num = -1;
- break;
- }
- }
- }
-
- if (num < 0)
- /*
- * ok, we have 256 cameras on this host...
- * man, stay reasonable...
- */
- return -ENOMEM;
-
- icd->devnum = num;
- icd->use_count = 0;
- icd->host_priv = NULL;
- mutex_init(&icd->video_lock);
-
- list_add_tail(&icd->list, &devices);
-
- return 0;
-}
-
-static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
- .vidioc_querycap = soc_camera_querycap,
- .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap,
- .vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap,
- .vidioc_enum_input = soc_camera_enum_input,
- .vidioc_g_input = soc_camera_g_input,
- .vidioc_s_input = soc_camera_s_input,
- .vidioc_s_std = soc_camera_s_std,
- .vidioc_g_std = soc_camera_g_std,
- .vidioc_enum_framesizes = soc_camera_enum_framesizes,
- .vidioc_reqbufs = soc_camera_reqbufs,
- .vidioc_querybuf = soc_camera_querybuf,
- .vidioc_qbuf = soc_camera_qbuf,
- .vidioc_dqbuf = soc_camera_dqbuf,
- .vidioc_create_bufs = soc_camera_create_bufs,
- .vidioc_prepare_buf = soc_camera_prepare_buf,
- .vidioc_streamon = soc_camera_streamon,
- .vidioc_streamoff = soc_camera_streamoff,
- .vidioc_cropcap = soc_camera_cropcap,
- .vidioc_g_crop = soc_camera_g_crop,
- .vidioc_s_crop = soc_camera_s_crop,
- .vidioc_g_parm = soc_camera_g_parm,
- .vidioc_s_parm = soc_camera_s_parm,
- .vidioc_g_chip_ident = soc_camera_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = soc_camera_g_register,
- .vidioc_s_register = soc_camera_s_register,
-#endif
-};
-
-static int video_dev_create(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct video_device *vdev = video_device_alloc();
-
- if (!vdev)
- return -ENOMEM;
-
- strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
-
- vdev->parent = icd->pdev;
- vdev->current_norm = V4L2_STD_UNKNOWN;
- vdev->fops = &soc_camera_fops;
- vdev->ioctl_ops = &soc_camera_ioctl_ops;
- vdev->release = video_device_release;
- vdev->tvnorms = V4L2_STD_UNKNOWN;
- vdev->ctrl_handler = &icd->ctrl_handler;
- vdev->lock = &icd->video_lock;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags);
-
- icd->vdev = vdev;
-
- return 0;
-}
-
-/*
- * Called from soc_camera_probe() above (with .video_lock held???)
- */
-static int soc_camera_video_start(struct soc_camera_device *icd)
-{
- const struct device_type *type = icd->vdev->dev.type;
- int ret;
-
- if (!icd->parent)
- return -ENODEV;
-
- ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1);
- if (ret < 0) {
- dev_err(icd->pdev, "video_register_device failed: %d\n", ret);
- return ret;
- }
-
- /* Restore device type, possibly set by the subdevice driver */
- icd->vdev->dev.type = type;
-
- return 0;
-}
-
-static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
-{
- struct soc_camera_link *icl = pdev->dev.platform_data;
- struct soc_camera_device *icd;
- int ret;
-
- if (!icl)
- return -EINVAL;
-
- icd = kzalloc(sizeof(*icd), GFP_KERNEL);
- if (!icd)
- return -ENOMEM;
-
- icd->iface = icl->bus_id;
- icd->link = icl;
- icd->pdev = &pdev->dev;
- platform_set_drvdata(pdev, icd);
-
- ret = soc_camera_device_register(icd);
- if (ret < 0)
- goto escdevreg;
-
- icd->user_width = DEFAULT_WIDTH;
- icd->user_height = DEFAULT_HEIGHT;
-
- return 0;
-
-escdevreg:
- kfree(icd);
-
- return ret;
-}
-
-/*
- * Only called on rmmod for each platform device, since they are not
- * hot-pluggable. Now we know, that all our users - hosts and devices have
- * been unloaded already
- */
-static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
-{
- struct soc_camera_device *icd = platform_get_drvdata(pdev);
-
- if (!icd)
- return -EINVAL;
-
- list_del(&icd->list);
-
- kfree(icd);
-
- return 0;
-}
-
-static struct platform_driver __refdata soc_camera_pdrv = {
- .probe = soc_camera_pdrv_probe,
- .remove = __devexit_p(soc_camera_pdrv_remove),
- .driver = {
- .name = "soc-camera-pdrv",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init soc_camera_init(void)
-{
- return platform_driver_register(&soc_camera_pdrv);
-}
-
-static void __exit soc_camera_exit(void)
-{
- platform_driver_unregister(&soc_camera_pdrv);
-}
-
-module_init(soc_camera_init);
-module_exit(soc_camera_exit);
-
-MODULE_DESCRIPTION("Image capture bus driver");
-MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:soc-camera-pdrv");
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
deleted file mode 100644
index f59ccade07c..00000000000
--- a/drivers/media/video/soc_camera_platform.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Generic Platform Camera Driver
- *
- * Copyright (C) 2008 Magnus Damm
- * Based on mt9m001 driver,
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-subdev.h>
-#include <media/soc_camera.h>
-#include <media/soc_camera_platform.h>
-
-struct soc_camera_platform_priv {
- struct v4l2_subdev subdev;
-};
-
-static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev)
-{
- struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
- return container_of(subdev, struct soc_camera_platform_priv, subdev);
-}
-
-static int soc_camera_platform_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
- return p->set_capture(p, enable);
-}
-
-static int soc_camera_platform_fill_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
-
- mf->width = p->format.width;
- mf->height = p->format.height;
- mf->code = p->format.code;
- mf->colorspace = p->format.colorspace;
- mf->field = p->format.field;
-
- return 0;
-}
-
-static struct v4l2_subdev_core_ops platform_subdev_core_ops;
-
-static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
-
- if (index)
- return -EINVAL;
-
- *code = p->format.code;
- return 0;
-}
-
-static int soc_camera_platform_g_crop(struct v4l2_subdev *sd,
- struct v4l2_crop *a)
-{
- struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
-
- a->c.left = 0;
- a->c.top = 0;
- a->c.width = p->format.width;
- a->c.height = p->format.height;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int soc_camera_platform_cropcap(struct v4l2_subdev *sd,
- struct v4l2_cropcap *a)
-{
- struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
-
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = p->format.width;
- a->bounds.height = p->format.height;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int soc_camera_platform_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
-
- cfg->flags = p->mbus_param;
- cfg->type = p->mbus_type;
-
- return 0;
-}
-
-static struct v4l2_subdev_video_ops platform_subdev_video_ops = {
- .s_stream = soc_camera_platform_s_stream,
- .enum_mbus_fmt = soc_camera_platform_enum_fmt,
- .cropcap = soc_camera_platform_cropcap,
- .g_crop = soc_camera_platform_g_crop,
- .try_mbus_fmt = soc_camera_platform_fill_fmt,
- .g_mbus_fmt = soc_camera_platform_fill_fmt,
- .s_mbus_fmt = soc_camera_platform_fill_fmt,
- .g_mbus_config = soc_camera_platform_g_mbus_config,
-};
-
-static struct v4l2_subdev_ops platform_subdev_ops = {
- .core = &platform_subdev_core_ops,
- .video = &platform_subdev_video_ops,
-};
-
-static int soc_camera_platform_probe(struct platform_device *pdev)
-{
- struct soc_camera_host *ici;
- struct soc_camera_platform_priv *priv;
- struct soc_camera_platform_info *p = pdev->dev.platform_data;
- struct soc_camera_device *icd;
- int ret;
-
- if (!p)
- return -EINVAL;
-
- if (!p->icd) {
- dev_err(&pdev->dev,
- "Platform has not set soc_camera_device pointer!\n");
- return -EINVAL;
- }
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- icd = p->icd;
-
- /* soc-camera convention: control's drvdata points to the subdev */
- platform_set_drvdata(pdev, &priv->subdev);
- /* Set the control device reference */
- icd->control = &pdev->dev;
-
- ici = to_soc_camera_host(icd->parent);
-
- v4l2_subdev_init(&priv->subdev, &platform_subdev_ops);
- v4l2_set_subdevdata(&priv->subdev, p);
- strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE);
-
- ret = v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev);
- if (ret)
- goto evdrs;
-
- return ret;
-
-evdrs:
- platform_set_drvdata(pdev, NULL);
- kfree(priv);
- return ret;
-}
-
-static int soc_camera_platform_remove(struct platform_device *pdev)
-{
- struct soc_camera_platform_priv *priv = get_priv(pdev);
- struct soc_camera_platform_info *p = v4l2_get_subdevdata(&priv->subdev);
-
- p->icd->control = NULL;
- v4l2_device_unregister_subdev(&priv->subdev);
- platform_set_drvdata(pdev, NULL);
- kfree(priv);
- return 0;
-}
-
-static struct platform_driver soc_camera_platform_driver = {
- .driver = {
- .name = "soc_camera_platform",
- .owner = THIS_MODULE,
- },
- .probe = soc_camera_platform_probe,
- .remove = soc_camera_platform_remove,
-};
-
-module_platform_driver(soc_camera_platform_driver);
-
-MODULE_DESCRIPTION("SoC Camera Platform driver");
-MODULE_AUTHOR("Magnus Damm");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:soc_camera_platform");
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c
deleted file mode 100644
index a397812635d..00000000000
--- a/drivers/media/video/soc_mediabus.c
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * soc-camera media bus helper routines
- *
- * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-mediabus.h>
-#include <media/soc_mediabus.h>
-
-static const struct soc_mbus_lookup mbus_fmt[] = {
-{
- .code = V4L2_MBUS_FMT_YUYV8_2X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_YUYV,
- .name = "YUYV",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_YVYU8_2X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_YVYU,
- .name = "YVYU",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_UYVY8_2X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_UYVY,
- .name = "UYVY",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_VYUY8_2X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_VYUY,
- .name = "VYUY",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_RGB555,
- .name = "RGB555",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_RGB555X,
- .name = "RGB555X",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_RGB565,
- .name = "RGB565",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_RGB565X,
- .name = "RGB565X",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SBGGR8_1X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SBGGR8,
- .name = "Bayer 8 BGGR",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_NONE,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SBGGR10_1X10,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SBGGR10,
- .name = "Bayer 10 BGGR",
- .bits_per_sample = 10,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_Y8_1X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_GREY,
- .name = "Grey",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_NONE,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_Y10_1X10,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_Y10,
- .name = "Grey 10bit",
- .bits_per_sample = 10,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SBGGR10,
- .name = "Bayer 10 BGGR",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SBGGR10,
- .name = "Bayer 10 BGGR",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADLO,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SBGGR10,
- .name = "Bayer 10 BGGR",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_BE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SBGGR10,
- .name = "Bayer 10 BGGR",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADLO,
- .order = SOC_MBUS_ORDER_BE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_JPEG_1X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_JPEG,
- .name = "JPEG",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_VARIABLE,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_RGB444,
- .name = "RGB444",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_BE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_YUYV8_1_5X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_YUV420,
- .name = "YUYV 4:2:0",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_1_5X8,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_YVYU8_1_5X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_YVU420,
- .name = "YVYU 4:2:0",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_1_5X8,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_UYVY8_1X16,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_UYVY,
- .name = "UYVY 16bit",
- .bits_per_sample = 16,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_VYUY8_1X16,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_VYUY,
- .name = "VYUY 16bit",
- .bits_per_sample = 16,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_YUYV8_1X16,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_YUYV,
- .name = "YUYV 16bit",
- .bits_per_sample = 16,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_YVYU8_1X16,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_YVYU,
- .name = "YVYU 16bit",
- .bits_per_sample = 16,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SGRBG8_1X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SGRBG8,
- .name = "Bayer 8 GRBG",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_NONE,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SGRBG10DPCM8,
- .name = "Bayer 10 BGGR DPCM 8",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_NONE,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SGBRG10_1X10,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SGBRG10,
- .name = "Bayer 10 GBRG",
- .bits_per_sample = 10,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SGRBG10_1X10,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SGRBG10,
- .name = "Bayer 10 GRBG",
- .bits_per_sample = 10,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SRGGB10_1X10,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SRGGB10,
- .name = "Bayer 10 RGGB",
- .bits_per_sample = 10,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SBGGR12_1X12,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SBGGR12,
- .name = "Bayer 12 BGGR",
- .bits_per_sample = 12,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SGBRG12_1X12,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SGBRG12,
- .name = "Bayer 12 GBRG",
- .bits_per_sample = 12,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SGRBG12_1X12,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SGRBG12,
- .name = "Bayer 12 GRBG",
- .bits_per_sample = 12,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-}, {
- .code = V4L2_MBUS_FMT_SRGGB12_1X12,
- .fmt = {
- .fourcc = V4L2_PIX_FMT_SRGGB12,
- .name = "Bayer 12 RGGB",
- .bits_per_sample = 12,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- .layout = SOC_MBUS_LAYOUT_PACKED,
- },
-},
-};
-
-int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
- unsigned int *numerator, unsigned int *denominator)
-{
- switch (mf->packing) {
- case SOC_MBUS_PACKING_NONE:
- case SOC_MBUS_PACKING_EXTEND16:
- *numerator = 1;
- *denominator = 1;
- return 0;
- case SOC_MBUS_PACKING_2X8_PADHI:
- case SOC_MBUS_PACKING_2X8_PADLO:
- *numerator = 2;
- *denominator = 1;
- return 0;
- case SOC_MBUS_PACKING_1_5X8:
- *numerator = 3;
- *denominator = 2;
- return 0;
- case SOC_MBUS_PACKING_VARIABLE:
- *numerator = 0;
- *denominator = 1;
- return 0;
- }
- return -EINVAL;
-}
-EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
-
-s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
-{
- if (mf->fourcc == V4L2_PIX_FMT_JPEG)
- return 0;
-
- if (mf->layout != SOC_MBUS_LAYOUT_PACKED)
- return width * mf->bits_per_sample / 8;
-
- switch (mf->packing) {
- case SOC_MBUS_PACKING_NONE:
- return width * mf->bits_per_sample / 8;
- case SOC_MBUS_PACKING_2X8_PADHI:
- case SOC_MBUS_PACKING_2X8_PADLO:
- case SOC_MBUS_PACKING_EXTEND16:
- return width * 2;
- case SOC_MBUS_PACKING_1_5X8:
- return width * 3 / 2;
- case SOC_MBUS_PACKING_VARIABLE:
- return 0;
- }
- return -EINVAL;
-}
-EXPORT_SYMBOL(soc_mbus_bytes_per_line);
-
-s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf,
- u32 bytes_per_line, u32 height)
-{
- if (mf->fourcc == V4L2_PIX_FMT_JPEG)
- return 0;
-
- if (mf->layout == SOC_MBUS_LAYOUT_PACKED)
- return bytes_per_line * height;
-
- switch (mf->packing) {
- case SOC_MBUS_PACKING_2X8_PADHI:
- case SOC_MBUS_PACKING_2X8_PADLO:
- return bytes_per_line * height * 2;
- case SOC_MBUS_PACKING_1_5X8:
- return bytes_per_line * height * 3 / 2;
- default:
- return -EINVAL;
- }
-}
-EXPORT_SYMBOL(soc_mbus_image_size);
-
-const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc(
- enum v4l2_mbus_pixelcode code,
- const struct soc_mbus_lookup *lookup,
- int n)
-{
- int i;
-
- for (i = 0; i < n; i++)
- if (lookup[i].code == code)
- return &lookup[i].fmt;
-
- return NULL;
-}
-EXPORT_SYMBOL(soc_mbus_find_fmtdesc);
-
-const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
- enum v4l2_mbus_pixelcode code)
-{
- return soc_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt));
-}
-EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
-
-unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
- unsigned int flags)
-{
- unsigned long common_flags;
- bool hsync = true, vsync = true, pclk, data, mode;
- bool mipi_lanes, mipi_clock;
-
- common_flags = cfg->flags & flags;
-
- switch (cfg->type) {
- case V4L2_MBUS_PARALLEL:
- hsync = common_flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH |
- V4L2_MBUS_HSYNC_ACTIVE_LOW);
- vsync = common_flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH |
- V4L2_MBUS_VSYNC_ACTIVE_LOW);
- case V4L2_MBUS_BT656:
- pclk = common_flags & (V4L2_MBUS_PCLK_SAMPLE_RISING |
- V4L2_MBUS_PCLK_SAMPLE_FALLING);
- data = common_flags & (V4L2_MBUS_DATA_ACTIVE_HIGH |
- V4L2_MBUS_DATA_ACTIVE_LOW);
- mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE);
- return (!hsync || !vsync || !pclk || !data || !mode) ?
- 0 : common_flags;
- case V4L2_MBUS_CSI2:
- mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES;
- mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK |
- V4L2_MBUS_CSI2_CONTINUOUS_CLOCK);
- return (!mipi_lanes || !mipi_clock) ? 0 : common_flags;
- }
- return 0;
-}
-EXPORT_SYMBOL(soc_mbus_config_compatible);
-
-static int __init soc_mbus_init(void)
-{
- return 0;
-}
-
-static void __exit soc_mbus_exit(void)
-{
-}
-
-module_init(soc_mbus_init);
-module_exit(soc_mbus_exit);
-
-MODULE_DESCRIPTION("soc-camera media bus interface");
-MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/sr030pc30.c b/drivers/media/video/sr030pc30.c
deleted file mode 100644
index e9d95bda2ab..00000000000
--- a/drivers/media/video/sr030pc30.c
+++ /dev/null
@@ -1,871 +0,0 @@
-/*
- * Driver for SiliconFile SR030PC30 VGA (1/10-Inch) Image Sensor with ISP
- *
- * Copyright (C) 2010 Samsung Electronics Co., Ltd
- * Author: Sylwester Nawrocki, s.nawrocki@samsung.com
- *
- * Based on original driver authored by Dongsoo Nathaniel Kim
- * and HeungJun Kim <riverful.kim@samsung.com>.
- *
- * Based on mt9v011 Micron Digital Image Sensor driver
- * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-mediabus.h>
-#include <media/sr030pc30.h>
-
-static int debug;
-module_param(debug, int, 0644);
-
-#define MODULE_NAME "SR030PC30"
-
-/*
- * Register offsets within a page
- * b15..b8 - page id, b7..b0 - register address
- */
-#define POWER_CTRL_REG 0x0001
-#define PAGEMODE_REG 0x03
-#define DEVICE_ID_REG 0x0004
-#define NOON010PC30_ID 0x86
-#define SR030PC30_ID 0x8C
-#define VDO_CTL1_REG 0x0010
-#define SUBSAMPL_NONE_VGA 0
-#define SUBSAMPL_QVGA 0x10
-#define SUBSAMPL_QQVGA 0x20
-#define VDO_CTL2_REG 0x0011
-#define SYNC_CTL_REG 0x0012
-#define WIN_ROWH_REG 0x0020
-#define WIN_ROWL_REG 0x0021
-#define WIN_COLH_REG 0x0022
-#define WIN_COLL_REG 0x0023
-#define WIN_HEIGHTH_REG 0x0024
-#define WIN_HEIGHTL_REG 0x0025
-#define WIN_WIDTHH_REG 0x0026
-#define WIN_WIDTHL_REG 0x0027
-#define HBLANKH_REG 0x0040
-#define HBLANKL_REG 0x0041
-#define VSYNCH_REG 0x0042
-#define VSYNCL_REG 0x0043
-/* page 10 */
-#define ISP_CTL_REG(n) (0x1010 + (n))
-#define YOFS_REG 0x1040
-#define DARK_YOFS_REG 0x1041
-#define AG_ABRTH_REG 0x1050
-#define SAT_CTL_REG 0x1060
-#define BSAT_REG 0x1061
-#define RSAT_REG 0x1062
-#define AG_SAT_TH_REG 0x1063
-/* page 11 */
-#define ZLPF_CTRL_REG 0x1110
-#define ZLPF_CTRL2_REG 0x1112
-#define ZLPF_AGH_THR_REG 0x1121
-#define ZLPF_THR_REG 0x1160
-#define ZLPF_DYN_THR_REG 0x1160
-/* page 12 */
-#define YCLPF_CTL1_REG 0x1240
-#define YCLPF_CTL2_REG 0x1241
-#define YCLPF_THR_REG 0x1250
-#define BLPF_CTL_REG 0x1270
-#define BLPF_THR1_REG 0x1274
-#define BLPF_THR2_REG 0x1275
-/* page 14 - Lens Shading Compensation */
-#define LENS_CTRL_REG 0x1410
-#define LENS_XCEN_REG 0x1420
-#define LENS_YCEN_REG 0x1421
-#define LENS_R_COMP_REG 0x1422
-#define LENS_G_COMP_REG 0x1423
-#define LENS_B_COMP_REG 0x1424
-/* page 15 - Color correction */
-#define CMC_CTL_REG 0x1510
-#define CMC_OFSGH_REG 0x1514
-#define CMC_OFSGL_REG 0x1516
-#define CMC_SIGN_REG 0x1517
-/* Color correction coefficients */
-#define CMC_COEF_REG(n) (0x1530 + (n))
-/* Color correction offset coefficients */
-#define CMC_OFS_REG(n) (0x1540 + (n))
-/* page 16 - Gamma correction */
-#define GMA_CTL_REG 0x1610
-/* Gamma correction coefficients 0.14 */
-#define GMA_COEF_REG(n) (0x1630 + (n))
-/* page 20 - Auto Exposure */
-#define AE_CTL1_REG 0x2010
-#define AE_CTL2_REG 0x2011
-#define AE_FRM_CTL_REG 0x2020
-#define AE_FINE_CTL_REG(n) (0x2028 + (n))
-#define EXP_TIMEH_REG 0x2083
-#define EXP_TIMEM_REG 0x2084
-#define EXP_TIMEL_REG 0x2085
-#define EXP_MMINH_REG 0x2086
-#define EXP_MMINL_REG 0x2087
-#define EXP_MMAXH_REG 0x2088
-#define EXP_MMAXM_REG 0x2089
-#define EXP_MMAXL_REG 0x208A
-/* page 22 - Auto White Balance */
-#define AWB_CTL1_REG 0x2210
-#define AWB_ENABLE 0x80
-#define AWB_CTL2_REG 0x2211
-#define MWB_ENABLE 0x01
-/* RGB gain control (manual WB) when AWB_CTL1[7]=0 */
-#define AWB_RGAIN_REG 0x2280
-#define AWB_GGAIN_REG 0x2281
-#define AWB_BGAIN_REG 0x2282
-#define AWB_RMAX_REG 0x2283
-#define AWB_RMIN_REG 0x2284
-#define AWB_BMAX_REG 0x2285
-#define AWB_BMIN_REG 0x2286
-/* R, B gain range in bright light conditions */
-#define AWB_RMAXB_REG 0x2287
-#define AWB_RMINB_REG 0x2288
-#define AWB_BMAXB_REG 0x2289
-#define AWB_BMINB_REG 0x228A
-/* manual white balance, when AWB_CTL2[0]=1 */
-#define MWB_RGAIN_REG 0x22B2
-#define MWB_BGAIN_REG 0x22B3
-/* the token to mark an array end */
-#define REG_TERM 0xFFFF
-
-/* Minimum and maximum exposure time in ms */
-#define EXPOS_MIN_MS 1
-#define EXPOS_MAX_MS 125
-
-struct sr030pc30_info {
- struct v4l2_subdev sd;
- const struct sr030pc30_platform_data *pdata;
- const struct sr030pc30_format *curr_fmt;
- const struct sr030pc30_frmsize *curr_win;
- unsigned int auto_wb:1;
- unsigned int auto_exp:1;
- unsigned int hflip:1;
- unsigned int vflip:1;
- unsigned int sleep:1;
- unsigned int exposure;
- u8 blue_balance;
- u8 red_balance;
- u8 i2c_reg_page;
-};
-
-struct sr030pc30_format {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
- u16 ispctl1_reg;
-};
-
-struct sr030pc30_frmsize {
- u16 width;
- u16 height;
- int vid_ctl1;
-};
-
-struct i2c_regval {
- u16 addr;
- u16 val;
-};
-
-static const struct v4l2_queryctrl sr030pc30_ctrl[] = {
- {
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Auto White Balance",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1,
- }, {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Red Balance",
- .minimum = 0,
- .maximum = 127,
- .step = 1,
- .default_value = 64,
- .flags = 0,
- }, {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Blue Balance",
- .minimum = 0,
- .maximum = 127,
- .step = 1,
- .default_value = 64,
- }, {
- .id = V4L2_CID_EXPOSURE_AUTO,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Auto Exposure",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1,
- }, {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Exposure",
- .minimum = EXPOS_MIN_MS,
- .maximum = EXPOS_MAX_MS,
- .step = 1,
- .default_value = 1,
- }, {
- }
-};
-
-/* supported resolutions */
-static const struct sr030pc30_frmsize sr030pc30_sizes[] = {
- {
- .width = 640,
- .height = 480,
- .vid_ctl1 = SUBSAMPL_NONE_VGA,
- }, {
- .width = 320,
- .height = 240,
- .vid_ctl1 = SUBSAMPL_QVGA,
- }, {
- .width = 160,
- .height = 120,
- .vid_ctl1 = SUBSAMPL_QQVGA,
- },
-};
-
-/* supported pixel formats */
-static const struct sr030pc30_format sr030pc30_formats[] = {
- {
- .code = V4L2_MBUS_FMT_YUYV8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .ispctl1_reg = 0x03,
- }, {
- .code = V4L2_MBUS_FMT_YVYU8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .ispctl1_reg = 0x02,
- }, {
- .code = V4L2_MBUS_FMT_VYUY8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .ispctl1_reg = 0,
- }, {
- .code = V4L2_MBUS_FMT_UYVY8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .ispctl1_reg = 0x01,
- }, {
- .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .ispctl1_reg = 0x40,
- },
-};
-
-static const struct i2c_regval sr030pc30_base_regs[] = {
- /* Window size and position within pixel matrix */
- { WIN_ROWH_REG, 0x00 }, { WIN_ROWL_REG, 0x06 },
- { WIN_COLH_REG, 0x00 }, { WIN_COLL_REG, 0x06 },
- { WIN_HEIGHTH_REG, 0x01 }, { WIN_HEIGHTL_REG, 0xE0 },
- { WIN_WIDTHH_REG, 0x02 }, { WIN_WIDTHL_REG, 0x80 },
- { HBLANKH_REG, 0x01 }, { HBLANKL_REG, 0x50 },
- { VSYNCH_REG, 0x00 }, { VSYNCL_REG, 0x14 },
- { SYNC_CTL_REG, 0 },
- /* Color corection and saturation */
- { ISP_CTL_REG(0), 0x30 }, { YOFS_REG, 0x80 },
- { DARK_YOFS_REG, 0x04 }, { AG_ABRTH_REG, 0x78 },
- { SAT_CTL_REG, 0x1F }, { BSAT_REG, 0x90 },
- { AG_SAT_TH_REG, 0xF0 }, { 0x1064, 0x80 },
- { CMC_CTL_REG, 0x03 }, { CMC_OFSGH_REG, 0x3C },
- { CMC_OFSGL_REG, 0x2C }, { CMC_SIGN_REG, 0x2F },
- { CMC_COEF_REG(0), 0xCB }, { CMC_OFS_REG(0), 0x87 },
- { CMC_COEF_REG(1), 0x61 }, { CMC_OFS_REG(1), 0x18 },
- { CMC_COEF_REG(2), 0x16 }, { CMC_OFS_REG(2), 0x91 },
- { CMC_COEF_REG(3), 0x23 }, { CMC_OFS_REG(3), 0x94 },
- { CMC_COEF_REG(4), 0xCE }, { CMC_OFS_REG(4), 0x9f },
- { CMC_COEF_REG(5), 0x2B }, { CMC_OFS_REG(5), 0x33 },
- { CMC_COEF_REG(6), 0x01 }, { CMC_OFS_REG(6), 0x00 },
- { CMC_COEF_REG(7), 0x34 }, { CMC_OFS_REG(7), 0x94 },
- { CMC_COEF_REG(8), 0x75 }, { CMC_OFS_REG(8), 0x14 },
- /* Color corection coefficients */
- { GMA_CTL_REG, 0x03 }, { GMA_COEF_REG(0), 0x00 },
- { GMA_COEF_REG(1), 0x19 }, { GMA_COEF_REG(2), 0x26 },
- { GMA_COEF_REG(3), 0x3B }, { GMA_COEF_REG(4), 0x5D },
- { GMA_COEF_REG(5), 0x79 }, { GMA_COEF_REG(6), 0x8E },
- { GMA_COEF_REG(7), 0x9F }, { GMA_COEF_REG(8), 0xAF },
- { GMA_COEF_REG(9), 0xBD }, { GMA_COEF_REG(10), 0xCA },
- { GMA_COEF_REG(11), 0xDD }, { GMA_COEF_REG(12), 0xEC },
- { GMA_COEF_REG(13), 0xF7 }, { GMA_COEF_REG(14), 0xFF },
- /* Noise reduction, Z-LPF, YC-LPF and BLPF filters setup */
- { ZLPF_CTRL_REG, 0x99 }, { ZLPF_CTRL2_REG, 0x0E },
- { ZLPF_AGH_THR_REG, 0x29 }, { ZLPF_THR_REG, 0x0F },
- { ZLPF_DYN_THR_REG, 0x63 }, { YCLPF_CTL1_REG, 0x23 },
- { YCLPF_CTL2_REG, 0x3B }, { YCLPF_THR_REG, 0x05 },
- { BLPF_CTL_REG, 0x1D }, { BLPF_THR1_REG, 0x05 },
- { BLPF_THR2_REG, 0x04 },
- /* Automatic white balance */
- { AWB_CTL1_REG, 0xFB }, { AWB_CTL2_REG, 0x26 },
- { AWB_RMAX_REG, 0x54 }, { AWB_RMIN_REG, 0x2B },
- { AWB_BMAX_REG, 0x57 }, { AWB_BMIN_REG, 0x29 },
- { AWB_RMAXB_REG, 0x50 }, { AWB_RMINB_REG, 0x43 },
- { AWB_BMAXB_REG, 0x30 }, { AWB_BMINB_REG, 0x22 },
- /* Auto exposure */
- { AE_CTL1_REG, 0x8C }, { AE_CTL2_REG, 0x04 },
- { AE_FRM_CTL_REG, 0x01 }, { AE_FINE_CTL_REG(0), 0x3F },
- { AE_FINE_CTL_REG(1), 0xA3 }, { AE_FINE_CTL_REG(3), 0x34 },
- /* Lens shading compensation */
- { LENS_CTRL_REG, 0x01 }, { LENS_XCEN_REG, 0x80 },
- { LENS_YCEN_REG, 0x70 }, { LENS_R_COMP_REG, 0x53 },
- { LENS_G_COMP_REG, 0x40 }, { LENS_B_COMP_REG, 0x3e },
- { REG_TERM, 0 },
-};
-
-static inline struct sr030pc30_info *to_sr030pc30(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct sr030pc30_info, sd);
-}
-
-static inline int set_i2c_page(struct sr030pc30_info *info,
- struct i2c_client *client, unsigned int reg)
-{
- int ret = 0;
- u32 page = reg >> 8 & 0xFF;
-
- if (info->i2c_reg_page != page && (reg & 0xFF) != 0x03) {
- ret = i2c_smbus_write_byte_data(client, PAGEMODE_REG, page);
- if (!ret)
- info->i2c_reg_page = page;
- }
- return ret;
-}
-
-static int cam_i2c_read(struct v4l2_subdev *sd, u32 reg_addr)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct sr030pc30_info *info = to_sr030pc30(sd);
-
- int ret = set_i2c_page(info, client, reg_addr);
- if (!ret)
- ret = i2c_smbus_read_byte_data(client, reg_addr & 0xFF);
- return ret;
-}
-
-static int cam_i2c_write(struct v4l2_subdev *sd, u32 reg_addr, u32 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct sr030pc30_info *info = to_sr030pc30(sd);
-
- int ret = set_i2c_page(info, client, reg_addr);
- if (!ret)
- ret = i2c_smbus_write_byte_data(
- client, reg_addr & 0xFF, val);
- return ret;
-}
-
-static inline int sr030pc30_bulk_write_reg(struct v4l2_subdev *sd,
- const struct i2c_regval *msg)
-{
- while (msg->addr != REG_TERM) {
- int ret = cam_i2c_write(sd, msg->addr, msg->val);
- if (ret)
- return ret;
- msg++;
- }
- return 0;
-}
-
-/* Device reset and sleep mode control */
-static int sr030pc30_pwr_ctrl(struct v4l2_subdev *sd,
- bool reset, bool sleep)
-{
- struct sr030pc30_info *info = to_sr030pc30(sd);
- u8 reg = sleep ? 0xF1 : 0xF0;
- int ret = 0;
-
- if (reset)
- ret = cam_i2c_write(sd, POWER_CTRL_REG, reg | 0x02);
- if (!ret) {
- ret = cam_i2c_write(sd, POWER_CTRL_REG, reg);
- if (!ret) {
- info->sleep = sleep;
- if (reset)
- info->i2c_reg_page = -1;
- }
- }
- return ret;
-}
-
-static inline int sr030pc30_enable_autoexposure(struct v4l2_subdev *sd, int on)
-{
- struct sr030pc30_info *info = to_sr030pc30(sd);
- /* auto anti-flicker is also enabled here */
- int ret = cam_i2c_write(sd, AE_CTL1_REG, on ? 0xDC : 0x0C);
- if (!ret)
- info->auto_exp = on;
- return ret;
-}
-
-static int sr030pc30_set_exposure(struct v4l2_subdev *sd, int value)
-{
- struct sr030pc30_info *info = to_sr030pc30(sd);
-
- unsigned long expos = value * info->pdata->clk_rate / (8 * 1000);
-
- int ret = cam_i2c_write(sd, EXP_TIMEH_REG, expos >> 16 & 0xFF);
- if (!ret)
- ret = cam_i2c_write(sd, EXP_TIMEM_REG, expos >> 8 & 0xFF);
- if (!ret)
- ret = cam_i2c_write(sd, EXP_TIMEL_REG, expos & 0xFF);
- if (!ret) { /* Turn off AE */
- info->exposure = value;
- ret = sr030pc30_enable_autoexposure(sd, 0);
- }
- return ret;
-}
-
-/* Automatic white balance control */
-static int sr030pc30_enable_autowhitebalance(struct v4l2_subdev *sd, int on)
-{
- struct sr030pc30_info *info = to_sr030pc30(sd);
-
- int ret = cam_i2c_write(sd, AWB_CTL2_REG, on ? 0x2E : 0x2F);
- if (!ret)
- ret = cam_i2c_write(sd, AWB_CTL1_REG, on ? 0xFB : 0x7B);
- if (!ret)
- info->auto_wb = on;
-
- return ret;
-}
-
-static int sr030pc30_set_flip(struct v4l2_subdev *sd)
-{
- struct sr030pc30_info *info = to_sr030pc30(sd);
-
- s32 reg = cam_i2c_read(sd, VDO_CTL2_REG);
- if (reg < 0)
- return reg;
-
- reg &= 0x7C;
- if (info->hflip)
- reg |= 0x01;
- if (info->vflip)
- reg |= 0x02;
- return cam_i2c_write(sd, VDO_CTL2_REG, reg | 0x80);
-}
-
-/* Configure resolution, color format and image flip */
-static int sr030pc30_set_params(struct v4l2_subdev *sd)
-{
- struct sr030pc30_info *info = to_sr030pc30(sd);
- int ret;
-
- if (!info->curr_win)
- return -EINVAL;
-
- /* Configure the resolution through subsampling */
- ret = cam_i2c_write(sd, VDO_CTL1_REG,
- info->curr_win->vid_ctl1);
-
- if (!ret && info->curr_fmt)
- ret = cam_i2c_write(sd, ISP_CTL_REG(0),
- info->curr_fmt->ispctl1_reg);
- if (!ret)
- ret = sr030pc30_set_flip(sd);
-
- return ret;
-}
-
-/* Find nearest matching image pixel size. */
-static int sr030pc30_try_frame_size(struct v4l2_mbus_framefmt *mf)
-{
- unsigned int min_err = ~0;
- int i = ARRAY_SIZE(sr030pc30_sizes);
- const struct sr030pc30_frmsize *fsize = &sr030pc30_sizes[0],
- *match = NULL;
- while (i--) {
- int err = abs(fsize->width - mf->width)
- + abs(fsize->height - mf->height);
- if (err < min_err) {
- min_err = err;
- match = fsize;
- }
- fsize++;
- }
- if (match) {
- mf->width = match->width;
- mf->height = match->height;
- return 0;
- }
- return -EINVAL;
-}
-
-static int sr030pc30_queryctrl(struct v4l2_subdev *sd,
- struct v4l2_queryctrl *qc)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(sr030pc30_ctrl); i++)
- if (qc->id == sr030pc30_ctrl[i].id) {
- *qc = sr030pc30_ctrl[i];
- v4l2_dbg(1, debug, sd, "%s id: %d\n",
- __func__, qc->id);
- return 0;
- }
-
- return -EINVAL;
-}
-
-static inline int sr030pc30_set_bluebalance(struct v4l2_subdev *sd, int value)
-{
- int ret = cam_i2c_write(sd, MWB_BGAIN_REG, value);
- if (!ret)
- to_sr030pc30(sd)->blue_balance = value;
- return ret;
-}
-
-static inline int sr030pc30_set_redbalance(struct v4l2_subdev *sd, int value)
-{
- int ret = cam_i2c_write(sd, MWB_RGAIN_REG, value);
- if (!ret)
- to_sr030pc30(sd)->red_balance = value;
- return ret;
-}
-
-static int sr030pc30_s_ctrl(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
-{
- int i, ret = 0;
-
- for (i = 0; i < ARRAY_SIZE(sr030pc30_ctrl); i++)
- if (ctrl->id == sr030pc30_ctrl[i].id)
- break;
-
- if (i == ARRAY_SIZE(sr030pc30_ctrl))
- return -EINVAL;
-
- if (ctrl->value < sr030pc30_ctrl[i].minimum ||
- ctrl->value > sr030pc30_ctrl[i].maximum)
- return -ERANGE;
-
- v4l2_dbg(1, debug, sd, "%s: ctrl_id: %d, value: %d\n",
- __func__, ctrl->id, ctrl->value);
-
- switch (ctrl->id) {
- case V4L2_CID_AUTO_WHITE_BALANCE:
- sr030pc30_enable_autowhitebalance(sd, ctrl->value);
- break;
- case V4L2_CID_BLUE_BALANCE:
- ret = sr030pc30_set_bluebalance(sd, ctrl->value);
- break;
- case V4L2_CID_RED_BALANCE:
- ret = sr030pc30_set_redbalance(sd, ctrl->value);
- break;
- case V4L2_CID_EXPOSURE_AUTO:
- sr030pc30_enable_autoexposure(sd,
- ctrl->value == V4L2_EXPOSURE_AUTO);
- break;
- case V4L2_CID_EXPOSURE:
- ret = sr030pc30_set_exposure(sd, ctrl->value);
- break;
- default:
- return -EINVAL;
- }
-
- return ret;
-}
-
-static int sr030pc30_g_ctrl(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
-{
- struct sr030pc30_info *info = to_sr030pc30(sd);
-
- v4l2_dbg(1, debug, sd, "%s: id: %d\n", __func__, ctrl->id);
-
- switch (ctrl->id) {
- case V4L2_CID_AUTO_WHITE_BALANCE:
- ctrl->value = info->auto_wb;
- break;
- case V4L2_CID_BLUE_BALANCE:
- ctrl->value = info->blue_balance;
- break;
- case V4L2_CID_RED_BALANCE:
- ctrl->value = info->red_balance;
- break;
- case V4L2_CID_EXPOSURE_AUTO:
- ctrl->value = info->auto_exp;
- break;
- case V4L2_CID_EXPOSURE:
- ctrl->value = info->exposure;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int sr030pc30_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (!code || index >= ARRAY_SIZE(sr030pc30_formats))
- return -EINVAL;
-
- *code = sr030pc30_formats[index].code;
- return 0;
-}
-
-static int sr030pc30_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct sr030pc30_info *info = to_sr030pc30(sd);
- int ret;
-
- if (!mf)
- return -EINVAL;
-
- if (!info->curr_win || !info->curr_fmt) {
- ret = sr030pc30_set_params(sd);
- if (ret)
- return ret;
- }
-
- mf->width = info->curr_win->width;
- mf->height = info->curr_win->height;
- mf->code = info->curr_fmt->code;
- mf->colorspace = info->curr_fmt->colorspace;
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-/* Return nearest media bus frame format. */
-static const struct sr030pc30_format *try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- int i = ARRAY_SIZE(sr030pc30_formats);
-
- sr030pc30_try_frame_size(mf);
-
- while (i--)
- if (mf->code == sr030pc30_formats[i].code)
- break;
-
- mf->code = sr030pc30_formats[i].code;
-
- return &sr030pc30_formats[i];
-}
-
-/* Return nearest media bus frame format. */
-static int sr030pc30_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- if (!sd || !mf)
- return -EINVAL;
-
- try_fmt(sd, mf);
- return 0;
-}
-
-static int sr030pc30_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct sr030pc30_info *info = to_sr030pc30(sd);
-
- if (!sd || !mf)
- return -EINVAL;
-
- info->curr_fmt = try_fmt(sd, mf);
-
- return sr030pc30_set_params(sd);
-}
-
-static int sr030pc30_base_config(struct v4l2_subdev *sd)
-{
- struct sr030pc30_info *info = to_sr030pc30(sd);
- int ret;
- unsigned long expmin, expmax;
-
- ret = sr030pc30_bulk_write_reg(sd, sr030pc30_base_regs);
- if (!ret) {
- info->curr_fmt = &sr030pc30_formats[0];
- info->curr_win = &sr030pc30_sizes[0];
- ret = sr030pc30_set_params(sd);
- }
- if (!ret)
- ret = sr030pc30_pwr_ctrl(sd, false, false);
-
- if (!ret && !info->pdata)
- return ret;
-
- expmin = EXPOS_MIN_MS * info->pdata->clk_rate / (8 * 1000);
- expmax = EXPOS_MAX_MS * info->pdata->clk_rate / (8 * 1000);
-
- v4l2_dbg(1, debug, sd, "%s: expmin= %lx, expmax= %lx", __func__,
- expmin, expmax);
-
- /* Setting up manual exposure time range */
- ret = cam_i2c_write(sd, EXP_MMINH_REG, expmin >> 8 & 0xFF);
- if (!ret)
- ret = cam_i2c_write(sd, EXP_MMINL_REG, expmin & 0xFF);
- if (!ret)
- ret = cam_i2c_write(sd, EXP_MMAXH_REG, expmax >> 16 & 0xFF);
- if (!ret)
- ret = cam_i2c_write(sd, EXP_MMAXM_REG, expmax >> 8 & 0xFF);
- if (!ret)
- ret = cam_i2c_write(sd, EXP_MMAXL_REG, expmax & 0xFF);
-
- return ret;
-}
-
-static int sr030pc30_s_power(struct v4l2_subdev *sd, int on)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct sr030pc30_info *info = to_sr030pc30(sd);
- const struct sr030pc30_platform_data *pdata = info->pdata;
- int ret;
-
- if (pdata == NULL) {
- WARN(1, "No platform data!\n");
- return -EINVAL;
- }
-
- /*
- * Put sensor into power sleep mode before switching off
- * power and disabling MCLK.
- */
- if (!on)
- sr030pc30_pwr_ctrl(sd, false, true);
-
- /* set_power controls sensor's power and clock */
- if (pdata->set_power) {
- ret = pdata->set_power(&client->dev, on);
- if (ret)
- return ret;
- }
-
- if (on) {
- ret = sr030pc30_base_config(sd);
- } else {
- ret = 0;
- info->curr_win = NULL;
- info->curr_fmt = NULL;
- }
-
- return ret;
-}
-
-static const struct v4l2_subdev_core_ops sr030pc30_core_ops = {
- .s_power = sr030pc30_s_power,
- .queryctrl = sr030pc30_queryctrl,
- .s_ctrl = sr030pc30_s_ctrl,
- .g_ctrl = sr030pc30_g_ctrl,
-};
-
-static const struct v4l2_subdev_video_ops sr030pc30_video_ops = {
- .g_mbus_fmt = sr030pc30_g_fmt,
- .s_mbus_fmt = sr030pc30_s_fmt,
- .try_mbus_fmt = sr030pc30_try_fmt,
- .enum_mbus_fmt = sr030pc30_enum_fmt,
-};
-
-static const struct v4l2_subdev_ops sr030pc30_ops = {
- .core = &sr030pc30_core_ops,
- .video = &sr030pc30_video_ops,
-};
-
-/*
- * Detect sensor type. Return 0 if SR030PC30 was detected
- * or -ENODEV otherwise.
- */
-static int sr030pc30_detect(struct i2c_client *client)
-{
- const struct sr030pc30_platform_data *pdata
- = client->dev.platform_data;
- int ret;
-
- /* Enable sensor's power and clock */
- if (pdata->set_power) {
- ret = pdata->set_power(&client->dev, 1);
- if (ret)
- return ret;
- }
-
- ret = i2c_smbus_read_byte_data(client, DEVICE_ID_REG);
-
- if (pdata->set_power)
- pdata->set_power(&client->dev, 0);
-
- if (ret < 0) {
- dev_err(&client->dev, "%s: I2C read failed\n", __func__);
- return ret;
- }
-
- return ret == SR030PC30_ID ? 0 : -ENODEV;
-}
-
-
-static int sr030pc30_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct sr030pc30_info *info;
- struct v4l2_subdev *sd;
- const struct sr030pc30_platform_data *pdata
- = client->dev.platform_data;
- int ret;
-
- if (!pdata) {
- dev_err(&client->dev, "No platform data!");
- return -EIO;
- }
-
- ret = sr030pc30_detect(client);
- if (ret)
- return ret;
-
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- sd = &info->sd;
- strcpy(sd->name, MODULE_NAME);
- info->pdata = client->dev.platform_data;
-
- v4l2_i2c_subdev_init(sd, client, &sr030pc30_ops);
-
- info->i2c_reg_page = -1;
- info->hflip = 1;
- info->auto_exp = 1;
- info->exposure = 30;
-
- return 0;
-}
-
-static int sr030pc30_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct sr030pc30_info *info = to_sr030pc30(sd);
-
- v4l2_device_unregister_subdev(sd);
- kfree(info);
- return 0;
-}
-
-static const struct i2c_device_id sr030pc30_id[] = {
- { MODULE_NAME, 0 },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, sr030pc30_id);
-
-
-static struct i2c_driver sr030pc30_i2c_driver = {
- .driver = {
- .name = MODULE_NAME
- },
- .probe = sr030pc30_probe,
- .remove = sr030pc30_remove,
- .id_table = sr030pc30_id,
-};
-
-module_i2c_driver(sr030pc30_i2c_driver);
-
-MODULE_DESCRIPTION("Siliconfile SR030PC30 camera driver");
-MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/sta2x11_vip.c b/drivers/media/video/sta2x11_vip.c
deleted file mode 100644
index 4c10205264d..00000000000
--- a/drivers/media/video/sta2x11_vip.c
+++ /dev/null
@@ -1,1550 +0,0 @@
-/*
- * This is the driver for the STA2x11 Video Input Port.
- *
- * Copyright (C) 2010 WindRiver Systems, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * The full GNU General Public License is included in this distribution in
- * the file called "COPYING".
- *
- * Author: Andreas Kies <andreas.kies@windriver.com>
- * Vlad Lungu <vlad.lungu@windriver.com>
- *
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/vmalloc.h>
-
-#include <linux/videodev2.h>
-
-#include <linux/kmod.h>
-
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf-dma-contig.h>
-
-#include "sta2x11_vip.h"
-
-#define DRV_NAME "sta2x11_vip"
-#define DRV_VERSION "1.3"
-
-#ifndef PCI_DEVICE_ID_STMICRO_VIP
-#define PCI_DEVICE_ID_STMICRO_VIP 0xCC0D
-#endif
-
-#define MAX_FRAMES 4
-
-/*Register offsets*/
-#define DVP_CTL 0x00
-#define DVP_TFO 0x04
-#define DVP_TFS 0x08
-#define DVP_BFO 0x0C
-#define DVP_BFS 0x10
-#define DVP_VTP 0x14
-#define DVP_VBP 0x18
-#define DVP_VMP 0x1C
-#define DVP_ITM 0x98
-#define DVP_ITS 0x9C
-#define DVP_STA 0xA0
-#define DVP_HLFLN 0xA8
-#define DVP_RGB 0xC0
-#define DVP_PKZ 0xF0
-
-/*Register fields*/
-#define DVP_CTL_ENA 0x00000001
-#define DVP_CTL_RST 0x80000000
-#define DVP_CTL_DIS (~0x00040001)
-
-#define DVP_IT_VSB 0x00000008
-#define DVP_IT_VST 0x00000010
-#define DVP_IT_FIFO 0x00000020
-
-#define DVP_HLFLN_SD 0x00000001
-
-#define REG_WRITE(vip, reg, value) iowrite32((value), (vip->iomem)+(reg))
-#define REG_READ(vip, reg) ioread32((vip->iomem)+(reg))
-
-#define SAVE_COUNT 8
-#define AUX_COUNT 3
-#define IRQ_COUNT 1
-
-/**
- * struct sta2x11_vip - All internal data for one instance of device
- * @v4l2_dev: device registered in v4l layer
- * @video_dev: properties of our device
- * @pdev: PCI device
- * @adapter: contains I2C adapter information
- * @register_save_area: All relevant register are saved here during suspend
- * @decoder: contains information about video DAC
- * @format: pixel format, fixed UYVY
- * @std: video standard (e.g. PAL/NTSC)
- * @input: input line for video signal ( 0 or 1 )
- * @users: Number of open of device ( max. 1 )
- * @disabled: Device is in power down state
- * @mutex: ensures exclusive opening of device
- * @slock: for excluse acces of registers
- * @vb_vidq: queue maintained by videobuf layer
- * @capture: linked list of capture buffer
- * @active: struct videobuf_buffer currently beingg filled
- * @started: device is ready to capture frame
- * @closing: device will be shut down
- * @tcount: Number of top frames
- * @bcount: Number of bottom frames
- * @overflow: Number of FIFO overflows
- * @mem_spare: small buffer of unused frame
- * @dma_spare: dma addres of mem_spare
- * @iomem: hardware base address
- * @config: I2C and gpio config from platform
- *
- * All non-local data is accessed via this structure.
- */
-
-struct sta2x11_vip {
- struct v4l2_device v4l2_dev;
- struct video_device *video_dev;
- struct pci_dev *pdev;
- struct i2c_adapter *adapter;
- unsigned int register_save_area[IRQ_COUNT + SAVE_COUNT + AUX_COUNT];
- struct v4l2_subdev *decoder;
- struct v4l2_pix_format format;
- v4l2_std_id std;
- unsigned int input;
- int users;
- int disabled;
- struct mutex mutex; /* exclusive access during open */
- spinlock_t slock; /* spin lock for hardware and queue access */
- struct videobuf_queue vb_vidq;
- struct list_head capture;
- struct videobuf_buffer *active;
- int started, closing, tcount, bcount;
- int overflow;
- void *mem_spare;
- dma_addr_t dma_spare;
- void *iomem;
- struct vip_config *config;
-};
-
-static const unsigned int registers_to_save[AUX_COUNT] = {
- DVP_HLFLN, DVP_RGB, DVP_PKZ
-};
-
-static struct v4l2_pix_format formats_50[] = {
- { /*PAL interlaced */
- .width = 720,
- .height = 576,
- .pixelformat = V4L2_PIX_FMT_UYVY,
- .field = V4L2_FIELD_INTERLACED,
- .bytesperline = 720 * 2,
- .sizeimage = 720 * 2 * 576,
- .colorspace = V4L2_COLORSPACE_SMPTE170M},
- { /*PAL top */
- .width = 720,
- .height = 288,
- .pixelformat = V4L2_PIX_FMT_UYVY,
- .field = V4L2_FIELD_TOP,
- .bytesperline = 720 * 2,
- .sizeimage = 720 * 2 * 288,
- .colorspace = V4L2_COLORSPACE_SMPTE170M},
- { /*PAL bottom */
- .width = 720,
- .height = 288,
- .pixelformat = V4L2_PIX_FMT_UYVY,
- .field = V4L2_FIELD_BOTTOM,
- .bytesperline = 720 * 2,
- .sizeimage = 720 * 2 * 288,
- .colorspace = V4L2_COLORSPACE_SMPTE170M},
-
-};
-
-static struct v4l2_pix_format formats_60[] = {
- { /*NTSC interlaced */
- .width = 720,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_UYVY,
- .field = V4L2_FIELD_INTERLACED,
- .bytesperline = 720 * 2,
- .sizeimage = 720 * 2 * 480,
- .colorspace = V4L2_COLORSPACE_SMPTE170M},
- { /*NTSC top */
- .width = 720,
- .height = 240,
- .pixelformat = V4L2_PIX_FMT_UYVY,
- .field = V4L2_FIELD_TOP,
- .bytesperline = 720 * 2,
- .sizeimage = 720 * 2 * 240,
- .colorspace = V4L2_COLORSPACE_SMPTE170M},
- { /*NTSC bottom */
- .width = 720,
- .height = 240,
- .pixelformat = V4L2_PIX_FMT_UYVY,
- .field = V4L2_FIELD_BOTTOM,
- .bytesperline = 720 * 2,
- .sizeimage = 720 * 2 * 240,
- .colorspace = V4L2_COLORSPACE_SMPTE170M},
-};
-
-/**
- * buf_setup - Get size and number of video buffer
- * @vq: queue in videobuf
- * @count: Number of buffers (1..MAX_FRAMES).
- * 0 use default value.
- * @size: size of buffer in bytes
- *
- * returns size and number of buffers
- * a preset value of 0 returns the default number.
- * return value: 0, always succesfull.
- */
-static int buf_setup(struct videobuf_queue *vq, unsigned int *count,
- unsigned int *size)
-{
- struct sta2x11_vip *vip = vq->priv_data;
-
- *size = vip->format.width * vip->format.height * 2;
- if (0 == *count || MAX_FRAMES < *count)
- *count = MAX_FRAMES;
- return 0;
-};
-
-/**
- * buf_prepare - prepare buffer for usage
- * @vq: queue in videobuf layer
- * @vb: buffer to be prepared
- * @field: type of video data (interlaced/non-interlaced)
- *
- * Allocate or realloc buffer
- * return value: 0, successful.
- *
- * -EINVAL, supplied buffer is too small.
- *
- * other, buffer could not be locked.
- */
-static int buf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct sta2x11_vip *vip = vq->priv_data;
- int ret;
-
- vb->size = vip->format.width * vip->format.height * 2;
- if ((0 != vb->baddr) && (vb->bsize < vb->size))
- return -EINVAL;
- vb->width = vip->format.width;
- vb->height = vip->format.height;
- vb->field = field;
-
- if (VIDEOBUF_NEEDS_INIT == vb->state) {
- ret = videobuf_iolock(vq, vb, NULL);
- if (ret)
- goto fail;
- }
- vb->state = VIDEOBUF_PREPARED;
- return 0;
-fail:
- videobuf_dma_contig_free(vq, vb);
- vb->state = VIDEOBUF_NEEDS_INIT;
- return ret;
-}
-
-/**
- * buf_queu - queue buffer for filling
- * @vq: queue in videobuf layer
- * @vb: buffer to be queued
- *
- * if capturing is already running, the buffer will be queued. Otherwise
- * capture is started and the buffer is used directly.
- */
-static void buf_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct sta2x11_vip *vip = vq->priv_data;
- u32 dma;
-
- vb->state = VIDEOBUF_QUEUED;
-
- if (vip->active) {
- list_add_tail(&vb->queue, &vip->capture);
- return;
- }
-
- vip->started = 1;
- vip->tcount = 0;
- vip->bcount = 0;
- vip->active = vb;
- vb->state = VIDEOBUF_ACTIVE;
-
- dma = videobuf_to_dma_contig(vb);
-
- REG_WRITE(vip, DVP_TFO, (0 << 16) | (0));
- /* despite of interlace mode, upper and lower frames start at zero */
- REG_WRITE(vip, DVP_BFO, (0 << 16) | (0));
-
- switch (vip->format.field) {
- case V4L2_FIELD_INTERLACED:
- REG_WRITE(vip, DVP_TFS,
- ((vip->format.height / 2 - 1) << 16) |
- (2 * vip->format.width - 1));
- REG_WRITE(vip, DVP_BFS, ((vip->format.height / 2 - 1) << 16) |
- (2 * vip->format.width - 1));
- REG_WRITE(vip, DVP_VTP, dma);
- REG_WRITE(vip, DVP_VBP, dma + vip->format.width * 2);
- REG_WRITE(vip, DVP_VMP, 4 * vip->format.width);
- break;
- case V4L2_FIELD_TOP:
- REG_WRITE(vip, DVP_TFS,
- ((vip->format.height - 1) << 16) |
- (2 * vip->format.width - 1));
- REG_WRITE(vip, DVP_BFS, ((0) << 16) |
- (2 * vip->format.width - 1));
- REG_WRITE(vip, DVP_VTP, dma);
- REG_WRITE(vip, DVP_VBP, dma);
- REG_WRITE(vip, DVP_VMP, 2 * vip->format.width);
- break;
- case V4L2_FIELD_BOTTOM:
- REG_WRITE(vip, DVP_TFS, ((0) << 16) |
- (2 * vip->format.width - 1));
- REG_WRITE(vip, DVP_BFS,
- ((vip->format.height) << 16) |
- (2 * vip->format.width - 1));
- REG_WRITE(vip, DVP_VTP, dma);
- REG_WRITE(vip, DVP_VBP, dma);
- REG_WRITE(vip, DVP_VMP, 2 * vip->format.width);
- break;
-
- default:
- pr_warning("VIP: unknown field format\n");
- return;
- }
-
- REG_WRITE(vip, DVP_CTL, DVP_CTL_ENA);
-}
-
-/**
- * buff_release - release buffer
- * @vq: queue in videobuf layer
- * @vb: buffer to be released
- *
- * release buffer in videobuf layer
- */
-static void buf_release(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
-
- videobuf_dma_contig_free(vq, vb);
- vb->state = VIDEOBUF_NEEDS_INIT;
-}
-
-static struct videobuf_queue_ops vip_qops = {
- .buf_setup = buf_setup,
- .buf_prepare = buf_prepare,
- .buf_queue = buf_queue,
- .buf_release = buf_release,
-};
-
-/**
- * vip_open - open video device
- * @file: descriptor of device
- *
- * open device, make sure it is only opened once.
- * return value: 0, no error.
- *
- * -EBUSY, device is already opened
- *
- * -ENOMEM, no memory for auxiliary DMA buffer
- */
-static int vip_open(struct file *file)
-{
- struct video_device *dev = video_devdata(file);
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- mutex_lock(&vip->mutex);
- vip->users++;
-
- if (vip->users > 1) {
- vip->users--;
- mutex_unlock(&vip->mutex);
- return -EBUSY;
- }
-
- file->private_data = dev;
- vip->overflow = 0;
- vip->started = 0;
- vip->closing = 0;
- vip->active = NULL;
-
- INIT_LIST_HEAD(&vip->capture);
- vip->mem_spare = dma_alloc_coherent(&vip->pdev->dev, 64,
- &vip->dma_spare, GFP_KERNEL);
- if (!vip->mem_spare) {
- vip->users--;
- mutex_unlock(&vip->mutex);
- return -ENOMEM;
- }
-
- mutex_unlock(&vip->mutex);
- videobuf_queue_dma_contig_init_cached(&vip->vb_vidq,
- &vip_qops,
- &vip->pdev->dev,
- &vip->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct videobuf_buffer),
- vip, NULL);
- REG_READ(vip, DVP_ITS);
- REG_WRITE(vip, DVP_HLFLN, DVP_HLFLN_SD);
- REG_WRITE(vip, DVP_ITM, DVP_IT_VSB | DVP_IT_VST);
- REG_WRITE(vip, DVP_CTL, DVP_CTL_RST);
- REG_WRITE(vip, DVP_CTL, 0);
- REG_READ(vip, DVP_ITS);
- return 0;
-}
-
-/**
- * vip_close - close video device
- * @file: descriptor of device
- *
- * close video device, wait until all pending operations are finished
- * ( maximum FRAME_MAX buffers pending )
- * Turn off interrupts.
- *
- * return value: 0, always succesful.
- */
-static int vip_close(struct file *file)
-{
- struct video_device *dev = video_devdata(file);
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- vip->closing = 1;
- if (vip->active)
- videobuf_waiton(&vip->vb_vidq, vip->active, 0, 0);
- spin_lock_irq(&vip->slock);
-
- REG_WRITE(vip, DVP_ITM, 0);
- REG_WRITE(vip, DVP_CTL, DVP_CTL_RST);
- REG_WRITE(vip, DVP_CTL, 0);
- REG_READ(vip, DVP_ITS);
-
- vip->started = 0;
- vip->active = NULL;
-
- spin_unlock_irq(&vip->slock);
-
- videobuf_stop(&vip->vb_vidq);
- videobuf_mmap_free(&vip->vb_vidq);
-
- dma_free_coherent(&vip->pdev->dev, 64, vip->mem_spare, vip->dma_spare);
- file->private_data = NULL;
- mutex_lock(&vip->mutex);
- vip->users--;
- mutex_unlock(&vip->mutex);
- return 0;
-}
-
-/**
- * vip_read - read from video input
- * @file: descriptor of device
- * @data: user buffer
- * @count: number of bytes to be read
- * @ppos: position within stream
- *
- * read video data from video device.
- * handling is done in generic videobuf layer
- * return value: provided by videobuf layer
- */
-static ssize_t vip_read(struct file *file, char __user *data,
- size_t count, loff_t *ppos)
-{
- struct video_device *dev = file->private_data;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- return videobuf_read_stream(&vip->vb_vidq, data, count, ppos, 0,
- file->f_flags & O_NONBLOCK);
-}
-
-/**
- * vip_mmap - map user buffer
- * @file: descriptor of device
- * @vma: user buffer
- *
- * map user space buffer into kernel mode, including DMA address.
- * handling is done in generic videobuf layer.
- * return value: provided by videobuf layer
- */
-static int vip_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct video_device *dev = file->private_data;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- return videobuf_mmap_mapper(&vip->vb_vidq, vma);
-}
-
-/**
- * vip_poll - poll for event
- * @file: descriptor of device
- * @wait: contains events to be waited for
- *
- * wait for event related to video device.
- * handling is done in generic videobuf layer.
- * return value: provided by videobuf layer
- */
-static unsigned int vip_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct video_device *dev = file->private_data;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- return videobuf_poll_stream(file, &vip->vb_vidq, wait);
-}
-
-/**
- * vidioc_querycap - return capabilities of device
- * @file: descriptor of device (not used)
- * @priv: points to current videodevice
- * @cap: contains return values
- *
- * the capabilities of the device are returned
- *
- * return value: 0, no error.
- */
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- memset(cap, 0, sizeof(struct v4l2_capability));
- strcpy(cap->driver, DRV_NAME);
- strcpy(cap->card, DRV_NAME);
- cap->version = 0;
- snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
- pci_name(vip->pdev));
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING;
-
- return 0;
-}
-
-/**
- * vidioc_s_std - set video standard
- * @file: descriptor of device (not used)
- * @priv: points to current videodevice
- * @std: contains standard to be set
- *
- * the video standard is set
- *
- * return value: 0, no error.
- *
- * -EIO, no input signal detected
- *
- * other, returned from video DAC.
- */
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
- v4l2_std_id oldstd = vip->std, newstd;
- int status;
-
- if (V4L2_STD_ALL == *std) {
- v4l2_subdev_call(vip->decoder, core, s_std, *std);
- ssleep(2);
- v4l2_subdev_call(vip->decoder, video, querystd, &newstd);
- v4l2_subdev_call(vip->decoder, video, g_input_status, &status);
- if (status & V4L2_IN_ST_NO_SIGNAL)
- return -EIO;
- *std = vip->std = newstd;
- if (oldstd != *std) {
- if (V4L2_STD_525_60 & (*std))
- vip->format = formats_60[0];
- else
- vip->format = formats_50[0];
- }
- return 0;
- }
-
- if (oldstd != *std) {
- if (V4L2_STD_525_60 & (*std))
- vip->format = formats_60[0];
- else
- vip->format = formats_50[0];
- }
-
- return v4l2_subdev_call(vip->decoder, core, s_std, *std);
-}
-
-/**
- * vidioc_g_std - get video standard
- * @file: descriptor of device (not used)
- * @priv: points to current videodevice
- * @std: contains return values
- *
- * the current video standard is returned
- *
- * return value: 0, no error.
- */
-static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- *std = vip->std;
- return 0;
-}
-
-/**
- * vidioc_querystd - get possible video standards
- * @file: descriptor of device (not used)
- * @priv: points to current videodevice
- * @std: contains return values
- *
- * all possible video standards are returned
- *
- * return value: delivered by video DAC routine.
- */
-static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- return v4l2_subdev_call(vip->decoder, video, querystd, std);
-
-}
-
-/**
- * vidioc_queryctl - get possible control settings
- * @file: descriptor of device (not used)
- * @priv: points to current videodevice
- * @ctrl: contains return values
- *
- * return possible values for a control
- * return value: delivered by video DAC routine.
- */
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *ctrl)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- return v4l2_subdev_call(vip->decoder, core, queryctrl, ctrl);
-}
-
-/**
- * vidioc_g_ctl - get control value
- * @file: descriptor of device (not used)
- * @priv: points to current videodevice
- * @ctrl: contains return values
- *
- * return setting for a control value
- * return value: delivered by video DAC routine.
- */
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- return v4l2_subdev_call(vip->decoder, core, g_ctrl, ctrl);
-}
-
-/**
- * vidioc_s_ctl - set control value
- * @file: descriptor of device (not used)
- * @priv: points to current videodevice
- * @ctrl: contains value to be set
- *
- * set value for a specific control
- * return value: delivered by video DAC routine.
- */
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- return v4l2_subdev_call(vip->decoder, core, s_ctrl, ctrl);
-}
-
-/**
- * vidioc_enum_input - return name of input line
- * @file: descriptor of device (not used)
- * @priv: points to current videodevice
- * @inp: contains return values
- *
- * the user friendly name of the input line is returned
- *
- * return value: 0, no error.
- *
- * -EINVAL, input line number out of range
- */
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *inp)
-{
- if (inp->index > 1)
- return -EINVAL;
-
- inp->type = V4L2_INPUT_TYPE_CAMERA;
- inp->std = V4L2_STD_ALL;
- sprintf(inp->name, "Camera %u", inp->index);
-
- return 0;
-}
-
-/**
- * vidioc_s_input - set input line
- * @file: descriptor of device ( not used)
- * @priv: points to current videodevice
- * @i: new input line number
- *
- * the current active input line is set
- *
- * return value: 0, no error.
- *
- * -EINVAL, line number out of range
- */
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
- int ret;
-
- if (i > 1)
- return -EINVAL;
- ret = v4l2_subdev_call(vip->decoder, video, s_routing, i, 0, 0);
-
- if (!ret)
- vip->input = i;
-
- return 0;
-}
-
-/**
- * vidioc_g_input - return input line
- * @file: descriptor of device ( not used)
- * @priv: points to current videodevice
- * @i: returned input line number
- *
- * the current active input line is returned
- *
- * return value: always 0.
- */
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- *i = vip->input;
- return 0;
-}
-
-/**
- * vidioc_enum_fmt_vid_cap - return video capture format
- * @file: descriptor of device ( not used)
- * @priv: points to current videodevice
- * @f: returned format information
- *
- * returns name and format of video capture
- * Only UYVY is supported by hardware.
- *
- * return value: always 0.
- */
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
-
- if (f->index != 0)
- return -EINVAL;
-
- strcpy(f->description, "4:2:2, packed, UYVY");
- f->pixelformat = V4L2_PIX_FMT_UYVY;
- f->flags = 0;
- return 0;
-}
-
-/**
- * vidioc_try_fmt_vid_cap - set video capture format
- * @file: descriptor of device ( not used)
- * @priv: points to current videodevice
- * @f: new format
- *
- * new video format is set which includes width and
- * field type. width is fixed to 720, no scaling.
- * Only UYVY is supported by this hardware.
- * the minimum height is 200, the maximum is 576 (PAL)
- *
- * return value: 0, no error
- *
- * -EINVAL, pixel or field format not supported
- *
- */
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
- int interlace_lim;
-
- if (V4L2_PIX_FMT_UYVY != f->fmt.pix.pixelformat)
- return -EINVAL;
-
- if (V4L2_STD_525_60 & vip->std)
- interlace_lim = 240;
- else
- interlace_lim = 288;
-
- switch (f->fmt.pix.field) {
- case V4L2_FIELD_ANY:
- if (interlace_lim < f->fmt.pix.height)
- f->fmt.pix.field = V4L2_FIELD_INTERLACED;
- else
- f->fmt.pix.field = V4L2_FIELD_BOTTOM;
- break;
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- if (interlace_lim < f->fmt.pix.height)
- f->fmt.pix.height = interlace_lim;
- break;
- case V4L2_FIELD_INTERLACED:
- break;
- default:
- return -EINVAL;
- }
-
- f->fmt.pix.height &= ~1;
- if (2 * interlace_lim < f->fmt.pix.height)
- f->fmt.pix.height = 2 * interlace_lim;
- if (200 > f->fmt.pix.height)
- f->fmt.pix.height = 200;
- f->fmt.pix.width = 720;
- f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
- f->fmt.pix.sizeimage = f->fmt.pix.width * 2 * f->fmt.pix.height;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- f->fmt.pix.priv = 0;
- return 0;
-}
-
-/**
- * vidioc_s_fmt_vid_cap - set current video format parameters
- * @file: descriptor of device ( not used)
- * @priv: points to current videodevice
- * @f: returned format information
- *
- * set new capture format
- * return value: 0, no error
- *
- * other, delivered by video DAC routine.
- */
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
- int ret;
-
- ret = vidioc_try_fmt_vid_cap(file, priv, f);
- if (ret)
- return ret;
-
- memcpy(&vip->format, &f->fmt.pix, sizeof(struct v4l2_pix_format));
- return 0;
-}
-
-/**
- * vidioc_g_fmt_vid_cap - get current video format parameters
- * @file: descriptor of device ( not used)
- * @priv: points to current videodevice
- * @f: contains format information
- *
- * returns current video format parameters
- *
- * return value: 0, always successful
- */
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- memcpy(&f->fmt.pix, &vip->format, sizeof(struct v4l2_pix_format));
- return 0;
-}
-
-/**
- * vidioc_reqfs - request buffer
- * @file: descriptor of device ( not used)
- * @priv: points to current videodevice
- * @p: video buffer
- *
- * Handling is done in generic videobuf layer.
- */
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- return videobuf_reqbufs(&vip->vb_vidq, p);
-}
-
-/**
- * vidioc_querybuf - query buffer
- * @file: descriptor of device ( not used)
- * @priv: points to current videodevice
- * @p: video buffer
- *
- * query buffer state.
- * Handling is done in generic videobuf layer.
- */
-static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- return videobuf_querybuf(&vip->vb_vidq, p);
-}
-
-/**
- * vidioc_qbuf - queue a buffer
- * @file: descriptor of device ( not used)
- * @priv: points to current videodevice
- * @p: video buffer
- *
- * Handling is done in generic videobuf layer.
- */
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- return videobuf_qbuf(&vip->vb_vidq, p);
-}
-
-/**
- * vidioc_dqbuf - dequeue a buffer
- * @file: descriptor of device ( not used)
- * @priv: points to current videodevice
- * @p: video buffer
- *
- * Handling is done in generic videobuf layer.
- */
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- return videobuf_dqbuf(&vip->vb_vidq, p, file->f_flags & O_NONBLOCK);
-}
-
-/**
- * vidioc_streamon - turn on streaming
- * @file: descriptor of device ( not used)
- * @priv: points to current videodevice
- * @type: type of capture
- *
- * turn on streaming.
- * Handling is done in generic videobuf layer.
- */
-static int vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- return videobuf_streamon(&vip->vb_vidq);
-}
-
-/**
- * vidioc_streamoff - turn off streaming
- * @file: descriptor of device ( not used)
- * @priv: points to current videodevice
- * @type: type of capture
- *
- * turn off streaming.
- * Handling is done in generic videobuf layer.
- */
-static int vidioc_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct video_device *dev = priv;
- struct sta2x11_vip *vip = video_get_drvdata(dev);
-
- return videobuf_streamoff(&vip->vb_vidq);
-}
-
-static const struct v4l2_file_operations vip_fops = {
- .owner = THIS_MODULE,
- .open = vip_open,
- .release = vip_close,
- .ioctl = video_ioctl2,
- .read = vip_read,
- .mmap = vip_mmap,
- .poll = vip_poll
-};
-
-static const struct v4l2_ioctl_ops vip_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_g_std = vidioc_g_std,
- .vidioc_querystd = vidioc_querystd,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
-};
-
-static struct video_device video_dev_template = {
- .name = DRV_NAME,
- .release = video_device_release,
- .fops = &vip_fops,
- .ioctl_ops = &vip_ioctl_ops,
- .tvnorms = V4L2_STD_ALL,
-};
-
-/**
- * vip_irq - interrupt routine
- * @irq: Number of interrupt ( not used, correct number is assumed )
- * @vip: local data structure containing all information
- *
- * check for both frame interrupts set ( top and bottom ).
- * check FIFO overflow, but limit number of log messages after open.
- * signal a complete buffer if done.
- * dequeue a new buffer if available.
- * disable VIP if no buffer available.
- *
- * return value: IRQ_NONE, interrupt was not generated by VIP
- *
- * IRQ_HANDLED, interrupt done.
- */
-static irqreturn_t vip_irq(int irq, struct sta2x11_vip *vip)
-{
- u32 status, dma;
- unsigned long flags;
- struct videobuf_buffer *vb;
-
- status = REG_READ(vip, DVP_ITS);
-
- if (!status) {
- pr_debug("VIP: irq ignored\n");
- return IRQ_NONE;
- }
-
- if (!vip->started)
- return IRQ_HANDLED;
-
- if (status & DVP_IT_VSB)
- vip->bcount++;
-
- if (status & DVP_IT_VST)
- vip->tcount++;
-
- if ((DVP_IT_VSB | DVP_IT_VST) == (status & (DVP_IT_VST | DVP_IT_VSB))) {
- /* this is bad, we are too slow, hope the condition is gone
- * on the next frame */
- pr_info("VIP: both irqs\n");
- return IRQ_HANDLED;
- }
-
- if (status & DVP_IT_FIFO) {
- if (5 > vip->overflow++)
- pr_info("VIP: fifo overflow\n");
- }
-
- if (2 > vip->tcount)
- return IRQ_HANDLED;
-
- if (status & DVP_IT_VSB)
- return IRQ_HANDLED;
-
- spin_lock_irqsave(&vip->slock, flags);
-
- REG_WRITE(vip, DVP_CTL, REG_READ(vip, DVP_CTL) & ~DVP_CTL_ENA);
- if (vip->active) {
- do_gettimeofday(&vip->active->ts);
- vip->active->field_count++;
- vip->active->state = VIDEOBUF_DONE;
- wake_up(&vip->active->done);
- vip->active = NULL;
- }
- if (!vip->closing) {
- if (list_empty(&vip->capture))
- goto done;
-
- vb = list_first_entry(&vip->capture, struct videobuf_buffer,
- queue);
- if (NULL == vb) {
- pr_info("VIP: no buffer\n");
- goto done;
- }
- vb->state = VIDEOBUF_ACTIVE;
- list_del(&vb->queue);
- vip->active = vb;
- dma = videobuf_to_dma_contig(vb);
- switch (vip->format.field) {
- case V4L2_FIELD_INTERLACED:
- REG_WRITE(vip, DVP_VTP, dma);
- REG_WRITE(vip, DVP_VBP, dma + vip->format.width * 2);
- break;
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- REG_WRITE(vip, DVP_VTP, dma);
- REG_WRITE(vip, DVP_VBP, dma);
- break;
- default:
- pr_warning("VIP: unknown field format\n");
- goto done;
- break;
- }
- REG_WRITE(vip, DVP_CTL, REG_READ(vip, DVP_CTL) | DVP_CTL_ENA);
- }
-done:
- spin_unlock_irqrestore(&vip->slock, flags);
- return IRQ_HANDLED;
-}
-
-/**
- * vip_gpio_reserve - reserve gpio pin
- * @dev: device
- * @pin: GPIO pin number
- * @dir: direction, input or output
- * @name: GPIO pin name
- *
- */
-static int vip_gpio_reserve(struct device *dev, int pin, int dir,
- const char *name)
-{
- int ret;
-
- if (pin == -1)
- return 0;
-
- ret = gpio_request(pin, name);
- if (ret) {
- dev_err(dev, "Failed to allocate pin %d (%s)\n", pin, name);
- return ret;
- }
-
- ret = gpio_direction_output(pin, dir);
- if (ret) {
- dev_err(dev, "Failed to set direction for pin %d (%s)\n",
- pin, name);
- gpio_free(pin);
- return ret;
- }
-
- ret = gpio_export(pin, false);
- if (ret) {
- dev_err(dev, "Failed to export pin %d (%s)\n", pin, name);
- gpio_free(pin);
- return ret;
- }
-
- return 0;
-}
-
-/**
- * vip_gpio_release - release gpio pin
- * @dev: device
- * @pin: GPIO pin number
- * @name: GPIO pin name
- *
- */
-static void vip_gpio_release(struct device *dev, int pin, const char *name)
-{
- if (pin != -1) {
- dev_dbg(dev, "releasing pin %d (%s)\n", pin, name);
- gpio_unexport(pin);
- gpio_free(pin);
- }
-}
-
-/**
- * sta2x11_vip_init_one - init one instance of video device
- * @pdev: PCI device
- * @ent: (not used)
- *
- * allocate reset pins for DAC.
- * Reset video DAC, this is done via reset line.
- * allocate memory for managing device
- * request interrupt
- * map IO region
- * register device
- * find and initialize video DAC
- *
- * return value: 0, no error
- *
- * -ENOMEM, no memory
- *
- * -ENODEV, device could not be detected or registered
- */
-static int __devinit sta2x11_vip_init_one(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- int ret;
- struct sta2x11_vip *vip;
- struct vip_config *config;
-
- ret = pci_enable_device(pdev);
- if (ret)
- return ret;
-
- config = dev_get_platdata(&pdev->dev);
- if (!config) {
- dev_info(&pdev->dev, "VIP slot disabled\n");
- ret = -EINVAL;
- goto disable;
- }
-
- ret = vip_gpio_reserve(&pdev->dev, config->pwr_pin, 0,
- config->pwr_name);
- if (ret)
- goto disable;
-
- if (config->reset_pin >= 0) {
- ret = vip_gpio_reserve(&pdev->dev, config->reset_pin, 0,
- config->reset_name);
- if (ret) {
- vip_gpio_release(&pdev->dev, config->pwr_pin,
- config->pwr_name);
- goto disable;
- }
- }
-
- if (config->pwr_pin != -1) {
- /* Datasheet says 5ms between PWR and RST */
- usleep_range(5000, 25000);
- ret = gpio_direction_output(config->pwr_pin, 1);
- }
-
- if (config->reset_pin != -1) {
- /* Datasheet says 5ms between PWR and RST */
- usleep_range(5000, 25000);
- ret = gpio_direction_output(config->reset_pin, 1);
- }
- usleep_range(5000, 25000);
-
- vip = kzalloc(sizeof(struct sta2x11_vip), GFP_KERNEL);
- if (!vip) {
- ret = -ENOMEM;
- goto release_gpios;
- }
-
- vip->pdev = pdev;
- vip->std = V4L2_STD_PAL;
- vip->format = formats_50[0];
- vip->config = config;
-
- if (v4l2_device_register(&pdev->dev, &vip->v4l2_dev))
- goto free_mem;
-
- dev_dbg(&pdev->dev, "BAR #0 at 0x%lx 0x%lx irq %d\n",
- (unsigned long)pci_resource_start(pdev, 0),
- (unsigned long)pci_resource_len(pdev, 0), pdev->irq);
-
- pci_set_master(pdev);
-
- ret = pci_request_regions(pdev, DRV_NAME);
- if (ret)
- goto unreg;
-
- vip->iomem = pci_iomap(pdev, 0, 0x100);
- if (!vip->iomem) {
- ret = -ENOMEM; /* FIXME */
- goto release;
- }
-
- pci_enable_msi(pdev);
-
- INIT_LIST_HEAD(&vip->capture);
- spin_lock_init(&vip->slock);
- mutex_init(&vip->mutex);
- vip->started = 0;
- vip->disabled = 0;
-
- ret = request_irq(pdev->irq,
- (irq_handler_t) vip_irq,
- IRQF_SHARED, DRV_NAME, vip);
- if (ret) {
- dev_err(&pdev->dev, "request_irq failed\n");
- ret = -ENODEV;
- goto unmap;
- }
-
- vip->video_dev = video_device_alloc();
- if (!vip->video_dev) {
- ret = -ENOMEM;
- goto release_irq;
- }
-
- *(vip->video_dev) = video_dev_template;
- video_set_drvdata(vip->video_dev, vip);
-
- ret = video_register_device(vip->video_dev, VFL_TYPE_GRABBER, -1);
- if (ret)
- goto vrelease;
-
- vip->adapter = i2c_get_adapter(vip->config->i2c_id);
- if (!vip->adapter) {
- ret = -ENODEV;
- dev_err(&pdev->dev, "no I2C adapter found\n");
- goto vunreg;
- }
-
- vip->decoder = v4l2_i2c_new_subdev(&vip->v4l2_dev, vip->adapter,
- "adv7180", vip->config->i2c_addr,
- NULL);
- if (!vip->decoder) {
- ret = -ENODEV;
- dev_err(&pdev->dev, "no decoder found\n");
- goto vunreg;
- }
-
- i2c_put_adapter(vip->adapter);
-
- v4l2_subdev_call(vip->decoder, core, init, 0);
-
- pr_info("STA2X11 Video Input Port (VIP) loaded\n");
- return 0;
-
-vunreg:
- video_set_drvdata(vip->video_dev, NULL);
-vrelease:
- if (video_is_registered(vip->video_dev))
- video_unregister_device(vip->video_dev);
- else
- video_device_release(vip->video_dev);
-release_irq:
- free_irq(pdev->irq, vip);
- pci_disable_msi(pdev);
-unmap:
- pci_iounmap(pdev, vip->iomem);
- mutex_destroy(&vip->mutex);
-release:
- pci_release_regions(pdev);
-unreg:
- v4l2_device_unregister(&vip->v4l2_dev);
-free_mem:
- kfree(vip);
-release_gpios:
- vip_gpio_release(&pdev->dev, config->reset_pin, config->reset_name);
- vip_gpio_release(&pdev->dev, config->pwr_pin, config->pwr_name);
-disable:
- /*
- * do not call pci_disable_device on sta2x11 because it break all
- * other Bus masters on this EP
- */
- return ret;
-}
-
-/**
- * sta2x11_vip_remove_one - release device
- * @pdev: PCI device
- *
- * Undo everything done in .._init_one
- *
- * unregister video device
- * free interrupt
- * unmap ioadresses
- * free memory
- * free GPIO pins
- */
-static void __devexit sta2x11_vip_remove_one(struct pci_dev *pdev)
-{
- struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
- struct sta2x11_vip *vip =
- container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);
-
- video_set_drvdata(vip->video_dev, NULL);
- video_unregister_device(vip->video_dev);
- /*do not call video_device_release() here, is already done */
- free_irq(pdev->irq, vip);
- pci_disable_msi(pdev);
- pci_iounmap(pdev, vip->iomem);
- pci_release_regions(pdev);
-
- v4l2_device_unregister(&vip->v4l2_dev);
- mutex_destroy(&vip->mutex);
-
- vip_gpio_release(&pdev->dev, vip->config->pwr_pin,
- vip->config->pwr_name);
- vip_gpio_release(&pdev->dev, vip->config->reset_pin,
- vip->config->reset_name);
-
- kfree(vip);
- /*
- * do not call pci_disable_device on sta2x11 because it break all
- * other Bus masters on this EP
- */
-}
-
-#ifdef CONFIG_PM
-
-/**
- * sta2x11_vip_suspend - set device into power save mode
- * @pdev: PCI device
- * @state: new state of device
- *
- * all relevant registers are saved and an attempt to set a new state is made.
- *
- * return value: 0 always indicate success,
- * even if device could not be disabled. (workaround for hardware problem)
- *
- * reurn value : 0, always succesful, even if hardware does not not support
- * power down mode.
- */
-static int sta2x11_vip_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
- struct sta2x11_vip *vip =
- container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&vip->slock, flags);
- vip->register_save_area[0] = REG_READ(vip, DVP_CTL);
- REG_WRITE(vip, DVP_CTL, vip->register_save_area[0] & DVP_CTL_DIS);
- vip->register_save_area[SAVE_COUNT] = REG_READ(vip, DVP_ITM);
- REG_WRITE(vip, DVP_ITM, 0);
- for (i = 1; i < SAVE_COUNT; i++)
- vip->register_save_area[i] = REG_READ(vip, 4 * i);
- for (i = 0; i < AUX_COUNT; i++)
- vip->register_save_area[SAVE_COUNT + IRQ_COUNT + i] =
- REG_READ(vip, registers_to_save[i]);
- spin_unlock_irqrestore(&vip->slock, flags);
- /* save pci state */
- pci_save_state(pdev);
- if (pci_set_power_state(pdev, pci_choose_state(pdev, state))) {
- /*
- * do not call pci_disable_device on sta2x11 because it
- * break all other Bus masters on this EP
- */
- vip->disabled = 1;
- }
-
- pr_info("VIP: suspend\n");
- return 0;
-}
-
-/**
- * sta2x11_vip_resume - resume device operation
- * @pdev : PCI device
- *
- * re-enable device, set PCI state to powered and restore registers.
- * resume normal device operation afterwards.
- *
- * return value: 0, no error.
- *
- * other, could not set device to power on state.
- */
-static int sta2x11_vip_resume(struct pci_dev *pdev)
-{
- struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
- struct sta2x11_vip *vip =
- container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);
- unsigned long flags;
- int ret, i;
-
- pr_info("VIP: resume\n");
- /* restore pci state */
- if (vip->disabled) {
- ret = pci_enable_device(pdev);
- if (ret) {
- pr_warning("VIP: Can't enable device.\n");
- return ret;
- }
- vip->disabled = 0;
- }
- ret = pci_set_power_state(pdev, PCI_D0);
- if (ret) {
- /*
- * do not call pci_disable_device on sta2x11 because it
- * break all other Bus masters on this EP
- */
- pr_warning("VIP: Can't enable device.\n");
- vip->disabled = 1;
- return ret;
- }
-
- pci_restore_state(pdev);
-
- spin_lock_irqsave(&vip->slock, flags);
- for (i = 1; i < SAVE_COUNT; i++)
- REG_WRITE(vip, 4 * i, vip->register_save_area[i]);
- for (i = 0; i < AUX_COUNT; i++)
- REG_WRITE(vip, registers_to_save[i],
- vip->register_save_area[SAVE_COUNT + IRQ_COUNT + i]);
- REG_WRITE(vip, DVP_CTL, vip->register_save_area[0]);
- REG_WRITE(vip, DVP_ITM, vip->register_save_area[SAVE_COUNT]);
- spin_unlock_irqrestore(&vip->slock, flags);
- return 0;
-}
-
-#endif
-
-static DEFINE_PCI_DEVICE_TABLE(sta2x11_vip_pci_tbl) = {
- {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIP)},
- {0,}
-};
-
-static struct pci_driver sta2x11_vip_driver = {
- .name = DRV_NAME,
- .probe = sta2x11_vip_init_one,
- .remove = __devexit_p(sta2x11_vip_remove_one),
- .id_table = sta2x11_vip_pci_tbl,
-#ifdef CONFIG_PM
- .suspend = sta2x11_vip_suspend,
- .resume = sta2x11_vip_resume,
-#endif
-};
-
-static int __init sta2x11_vip_init_module(void)
-{
- return pci_register_driver(&sta2x11_vip_driver);
-}
-
-static void __exit sta2x11_vip_exit_module(void)
-{
- pci_unregister_driver(&sta2x11_vip_driver);
-}
-
-#ifdef MODULE
-module_init(sta2x11_vip_init_module);
-module_exit(sta2x11_vip_exit_module);
-#else
-late_initcall_sync(sta2x11_vip_init_module);
-#endif
-
-MODULE_DESCRIPTION("STA2X11 Video Input Port driver");
-MODULE_AUTHOR("Wind River");
-MODULE_LICENSE("GPL v2");
-MODULE_SUPPORTED_DEVICE("sta2x11 video input");
-MODULE_VERSION(DRV_VERSION);
-MODULE_DEVICE_TABLE(pci, sta2x11_vip_pci_tbl);
diff --git a/drivers/media/video/sta2x11_vip.h b/drivers/media/video/sta2x11_vip.h
deleted file mode 100644
index 4f81a13666e..00000000000
--- a/drivers/media/video/sta2x11_vip.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2011 Wind River Systems, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Anders Wallin <anders.wallin@windriver.com>
- *
- */
-
-#ifndef __STA2X11_VIP_H
-#define __STA2X11_VIP_H
-
-/**
- * struct vip_config - video input configuration data
- * @pwr_name: ADV powerdown name
- * @pwr_pin: ADV powerdown pin
- * @reset_name: ADV reset name
- * @reset_pin: ADV reset pin
- */
-struct vip_config {
- const char *pwr_name;
- int pwr_pin;
- const char *reset_name;
- int reset_pin;
- int i2c_id;
- int i2c_addr;
-};
-
-#endif /* __STA2X11_VIP_H */
diff --git a/drivers/media/video/stk-sensor.c b/drivers/media/video/stk-sensor.c
deleted file mode 100644
index e546b014d7a..00000000000
--- a/drivers/media/video/stk-sensor.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/* stk-sensor.c: Driver for ov96xx sensor (used in some Syntek webcams)
- *
- * Copyright 2007-2008 Jaime Velasco Juan <jsagarribay@gmail.com>
- *
- * Some parts derived from ov7670.c:
- * Copyright 2006 One Laptop Per Child Association, Inc. Written
- * by Jonathan Corbet with substantial inspiration from Mark
- * McClelland's ovcamchip code.
- *
- * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
- *
- * This file may be distributed under the terms of the GNU General
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* Controlling the sensor via the STK1125 vendor specific control interface:
- * The camera uses an OmniVision sensor and the stk1125 provides an
- * SCCB(i2c)-USB bridge which let us program the sensor.
- * In my case the sensor id is 0x9652, it can be read from sensor's register
- * 0x0A and 0x0B as follows:
- * - read register #R:
- * output #R to index 0x0208
- * output 0x0070 to index 0x0200
- * input 1 byte from index 0x0201 (some kind of status register)
- * until its value is 0x01
- * input 1 byte from index 0x0209. This is the value of #R
- * - write value V to register #R
- * output #R to index 0x0204
- * output V to index 0x0205
- * output 0x0005 to index 0x0200
- * input 1 byte from index 0x0201 until its value becomes 0x04
- */
-
-/* It seems the i2c bus is controlled with these registers */
-
-#include "stk-webcam.h"
-
-#define STK_IIC_BASE (0x0200)
-# define STK_IIC_OP (STK_IIC_BASE)
-# define STK_IIC_OP_TX (0x05)
-# define STK_IIC_OP_RX (0x70)
-# define STK_IIC_STAT (STK_IIC_BASE+1)
-# define STK_IIC_STAT_TX_OK (0x04)
-# define STK_IIC_STAT_RX_OK (0x01)
-/* I don't know what does this register.
- * when it is 0x00 or 0x01, we cannot talk to the sensor,
- * other values work */
-# define STK_IIC_ENABLE (STK_IIC_BASE+2)
-# define STK_IIC_ENABLE_NO (0x00)
-/* This is what the driver writes in windows */
-# define STK_IIC_ENABLE_YES (0x1e)
-/*
- * Address of the slave. Seems like the binary driver look for the
- * sensor in multiple places, attempting a reset sequence.
- * We only know about the ov9650
- */
-# define STK_IIC_ADDR (STK_IIC_BASE+3)
-# define STK_IIC_TX_INDEX (STK_IIC_BASE+4)
-# define STK_IIC_TX_VALUE (STK_IIC_BASE+5)
-# define STK_IIC_RX_INDEX (STK_IIC_BASE+8)
-# define STK_IIC_RX_VALUE (STK_IIC_BASE+9)
-
-#define MAX_RETRIES (50)
-
-#define SENSOR_ADDRESS (0x60)
-
-/* From ov7670.c (These registers aren't fully accurate) */
-
-/* Registers */
-#define REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
-#define REG_BLUE 0x01 /* blue gain */
-#define REG_RED 0x02 /* red gain */
-#define REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
-#define REG_COM1 0x04 /* Control 1 */
-#define COM1_CCIR656 0x40 /* CCIR656 enable */
-#define COM1_QFMT 0x20 /* QVGA/QCIF format */
-#define COM1_SKIP_0 0x00 /* Do not skip any row */
-#define COM1_SKIP_2 0x04 /* Skip 2 rows of 4 */
-#define COM1_SKIP_3 0x08 /* Skip 3 rows of 4 */
-#define REG_BAVE 0x05 /* U/B Average level */
-#define REG_GbAVE 0x06 /* Y/Gb Average level */
-#define REG_AECHH 0x07 /* AEC MS 5 bits */
-#define REG_RAVE 0x08 /* V/R Average level */
-#define REG_COM2 0x09 /* Control 2 */
-#define COM2_SSLEEP 0x10 /* Soft sleep mode */
-#define REG_PID 0x0a /* Product ID MSB */
-#define REG_VER 0x0b /* Product ID LSB */
-#define REG_COM3 0x0c /* Control 3 */
-#define COM3_SWAP 0x40 /* Byte swap */
-#define COM3_SCALEEN 0x08 /* Enable scaling */
-#define COM3_DCWEN 0x04 /* Enable downsamp/crop/window */
-#define REG_COM4 0x0d /* Control 4 */
-#define REG_COM5 0x0e /* All "reserved" */
-#define REG_COM6 0x0f /* Control 6 */
-#define REG_AECH 0x10 /* More bits of AEC value */
-#define REG_CLKRC 0x11 /* Clock control */
-#define CLK_PLL 0x80 /* Enable internal PLL */
-#define CLK_EXT 0x40 /* Use external clock directly */
-#define CLK_SCALE 0x3f /* Mask for internal clock scale */
-#define REG_COM7 0x12 /* Control 7 */
-#define COM7_RESET 0x80 /* Register reset */
-#define COM7_FMT_MASK 0x38
-#define COM7_FMT_SXGA 0x00
-#define COM7_FMT_VGA 0x40
-#define COM7_FMT_CIF 0x20 /* CIF format */
-#define COM7_FMT_QVGA 0x10 /* QVGA format */
-#define COM7_FMT_QCIF 0x08 /* QCIF format */
-#define COM7_RGB 0x04 /* bits 0 and 2 - RGB format */
-#define COM7_YUV 0x00 /* YUV */
-#define COM7_BAYER 0x01 /* Bayer format */
-#define COM7_PBAYER 0x05 /* "Processed bayer" */
-#define REG_COM8 0x13 /* Control 8 */
-#define COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
-#define COM8_AECSTEP 0x40 /* Unlimited AEC step size */
-#define COM8_BFILT 0x20 /* Band filter enable */
-#define COM8_AGC 0x04 /* Auto gain enable */
-#define COM8_AWB 0x02 /* White balance enable */
-#define COM8_AEC 0x01 /* Auto exposure enable */
-#define REG_COM9 0x14 /* Control 9 - gain ceiling */
-#define REG_COM10 0x15 /* Control 10 */
-#define COM10_HSYNC 0x40 /* HSYNC instead of HREF */
-#define COM10_PCLK_HB 0x20 /* Suppress PCLK on horiz blank */
-#define COM10_HREF_REV 0x08 /* Reverse HREF */
-#define COM10_VS_LEAD 0x04 /* VSYNC on clock leading edge */
-#define COM10_VS_NEG 0x02 /* VSYNC negative */
-#define COM10_HS_NEG 0x01 /* HSYNC negative */
-#define REG_HSTART 0x17 /* Horiz start high bits */
-#define REG_HSTOP 0x18 /* Horiz stop high bits */
-#define REG_VSTART 0x19 /* Vert start high bits */
-#define REG_VSTOP 0x1a /* Vert stop high bits */
-#define REG_PSHFT 0x1b /* Pixel delay after HREF */
-#define REG_MIDH 0x1c /* Manuf. ID high */
-#define REG_MIDL 0x1d /* Manuf. ID low */
-#define REG_MVFP 0x1e /* Mirror / vflip */
-#define MVFP_MIRROR 0x20 /* Mirror image */
-#define MVFP_FLIP 0x10 /* Vertical flip */
-
-#define REG_AEW 0x24 /* AGC upper limit */
-#define REG_AEB 0x25 /* AGC lower limit */
-#define REG_VPT 0x26 /* AGC/AEC fast mode op region */
-#define REG_ADVFL 0x2d /* Insert dummy lines (LSB) */
-#define REG_ADVFH 0x2e /* Insert dummy lines (MSB) */
-#define REG_HSYST 0x30 /* HSYNC rising edge delay */
-#define REG_HSYEN 0x31 /* HSYNC falling edge delay */
-#define REG_HREF 0x32 /* HREF pieces */
-#define REG_TSLB 0x3a /* lots of stuff */
-#define TSLB_YLAST 0x04 /* UYVY or VYUY - see com13 */
-#define TSLB_BYTEORD 0x08 /* swap bytes in 16bit mode? */
-#define REG_COM11 0x3b /* Control 11 */
-#define COM11_NIGHT 0x80 /* NIght mode enable */
-#define COM11_NMFR 0x60 /* Two bit NM frame rate */
-#define COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
-#define COM11_50HZ 0x08 /* Manual 50Hz select */
-#define COM11_EXP 0x02
-#define REG_COM12 0x3c /* Control 12 */
-#define COM12_HREF 0x80 /* HREF always */
-#define REG_COM13 0x3d /* Control 13 */
-#define COM13_GAMMA 0x80 /* Gamma enable */
-#define COM13_UVSAT 0x40 /* UV saturation auto adjustment */
-#define COM13_CMATRIX 0x10 /* Enable color matrix for RGB or YUV */
-#define COM13_UVSWAP 0x01 /* V before U - w/TSLB */
-#define REG_COM14 0x3e /* Control 14 */
-#define COM14_DCWEN 0x10 /* DCW/PCLK-scale enable */
-#define REG_EDGE 0x3f /* Edge enhancement factor */
-#define REG_COM15 0x40 /* Control 15 */
-#define COM15_R10F0 0x00 /* Data range 10 to F0 */
-#define COM15_R01FE 0x80 /* 01 to FE */
-#define COM15_R00FF 0xc0 /* 00 to FF */
-#define COM15_RGB565 0x10 /* RGB565 output */
-#define COM15_RGBFIXME 0x20 /* FIXME */
-#define COM15_RGB555 0x30 /* RGB555 output */
-#define REG_COM16 0x41 /* Control 16 */
-#define COM16_AWBGAIN 0x08 /* AWB gain enable */
-#define REG_COM17 0x42 /* Control 17 */
-#define COM17_AECWIN 0xc0 /* AEC window - must match COM4 */
-#define COM17_CBAR 0x08 /* DSP Color bar */
-
-/*
- * This matrix defines how the colors are generated, must be
- * tweaked to adjust hue and saturation.
- *
- * Order: v-red, v-green, v-blue, u-red, u-green, u-blue
- *
- * They are nine-bit signed quantities, with the sign bit
- * stored in 0x58. Sign for v-red is bit 0, and up from there.
- */
-#define REG_CMATRIX_BASE 0x4f
-#define CMATRIX_LEN 6
-#define REG_CMATRIX_SIGN 0x58
-
-
-#define REG_BRIGHT 0x55 /* Brightness */
-#define REG_CONTRAS 0x56 /* Contrast control */
-
-#define REG_GFIX 0x69 /* Fix gain control */
-
-#define REG_RGB444 0x8c /* RGB 444 control */
-#define R444_ENABLE 0x02 /* Turn on RGB444, overrides 5x5 */
-#define R444_RGBX 0x01 /* Empty nibble at end */
-
-#define REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */
-#define REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
-
-#define REG_BD50MAX 0xa5 /* 50hz banding step limit */
-#define REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
-#define REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
-#define REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
-#define REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
-#define REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
-#define REG_BD60MAX 0xab /* 60hz banding step limit */
-
-
-
-
-/* Returns 0 if OK */
-static int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
-{
- int i = 0;
- int tmpval = 0;
-
- if (stk_camera_write_reg(dev, STK_IIC_TX_INDEX, reg))
- return 1;
- if (stk_camera_write_reg(dev, STK_IIC_TX_VALUE, val))
- return 1;
- if (stk_camera_write_reg(dev, STK_IIC_OP, STK_IIC_OP_TX))
- return 1;
- do {
- if (stk_camera_read_reg(dev, STK_IIC_STAT, &tmpval))
- return 1;
- i++;
- } while (tmpval == 0 && i < MAX_RETRIES);
- if (tmpval != STK_IIC_STAT_TX_OK) {
- if (tmpval)
- STK_ERROR("stk_sensor_outb failed, status=0x%02x\n",
- tmpval);
- return 1;
- } else
- return 0;
-}
-
-static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val)
-{
- int i = 0;
- int tmpval = 0;
-
- if (stk_camera_write_reg(dev, STK_IIC_RX_INDEX, reg))
- return 1;
- if (stk_camera_write_reg(dev, STK_IIC_OP, STK_IIC_OP_RX))
- return 1;
- do {
- if (stk_camera_read_reg(dev, STK_IIC_STAT, &tmpval))
- return 1;
- i++;
- } while (tmpval == 0 && i < MAX_RETRIES);
- if (tmpval != STK_IIC_STAT_RX_OK) {
- if (tmpval)
- STK_ERROR("stk_sensor_inb failed, status=0x%02x\n",
- tmpval);
- return 1;
- }
-
- if (stk_camera_read_reg(dev, STK_IIC_RX_VALUE, &tmpval))
- return 1;
-
- *val = (u8) tmpval;
- return 0;
-}
-
-static int stk_sensor_write_regvals(struct stk_camera *dev,
- struct regval *rv)
-{
- int ret;
- if (rv == NULL)
- return 0;
- while (rv->reg != 0xff || rv->val != 0xff) {
- ret = stk_sensor_outb(dev, rv->reg, rv->val);
- if (ret != 0)
- return ret;
- rv++;
- }
- return 0;
-}
-
-int stk_sensor_sleep(struct stk_camera *dev)
-{
- u8 tmp;
- return stk_sensor_inb(dev, REG_COM2, &tmp)
- || stk_sensor_outb(dev, REG_COM2, tmp|COM2_SSLEEP);
-}
-
-int stk_sensor_wakeup(struct stk_camera *dev)
-{
- u8 tmp;
- return stk_sensor_inb(dev, REG_COM2, &tmp)
- || stk_sensor_outb(dev, REG_COM2, tmp&~COM2_SSLEEP);
-}
-
-static struct regval ov_initvals[] = {
- {REG_CLKRC, CLK_PLL},
- {REG_COM11, 0x01},
- {0x6a, 0x7d},
- {REG_AECH, 0x40},
- {REG_GAIN, 0x00},
- {REG_BLUE, 0x80},
- {REG_RED, 0x80},
- /* Do not enable fast AEC for now */
- /*{REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC},*/
- {REG_COM8, COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC},
- {0x39, 0x50}, {0x38, 0x93},
- {0x37, 0x00}, {0x35, 0x81},
- {REG_COM5, 0x20},
- {REG_COM1, 0x00},
- {REG_COM3, 0x00},
- {REG_COM4, 0x00},
- {REG_PSHFT, 0x00},
- {0x16, 0x07},
- {0x33, 0xe2}, {0x34, 0xbf},
- {REG_COM16, 0x00},
- {0x96, 0x04},
- /* Gamma curve values */
-/* { 0x7a, 0x20 }, { 0x7b, 0x10 },
- { 0x7c, 0x1e }, { 0x7d, 0x35 },
- { 0x7e, 0x5a }, { 0x7f, 0x69 },
- { 0x80, 0x76 }, { 0x81, 0x80 },
- { 0x82, 0x88 }, { 0x83, 0x8f },
- { 0x84, 0x96 }, { 0x85, 0xa3 },
- { 0x86, 0xaf }, { 0x87, 0xc4 },
- { 0x88, 0xd7 }, { 0x89, 0xe8 },
-*/
- {REG_GFIX, 0x40},
- {0x8e, 0x00},
- {REG_COM12, 0x73},
- {0x8f, 0xdf}, {0x8b, 0x06},
- {0x8c, 0x20},
- {0x94, 0x88}, {0x95, 0x88},
-/* {REG_COM15, 0xc1}, TODO */
- {0x29, 0x3f},
- {REG_COM6, 0x42},
- {REG_BD50MAX, 0x80},
- {REG_HAECC6, 0xb8}, {REG_HAECC7, 0x92},
- {REG_BD60MAX, 0x0a},
- {0x90, 0x00}, {0x91, 0x00},
- {REG_HAECC1, 0x00}, {REG_HAECC2, 0x00},
- {REG_AEW, 0x68}, {REG_AEB, 0x5c},
- {REG_VPT, 0xc3},
- {REG_COM9, 0x2e},
- {0x2a, 0x00}, {0x2b, 0x00},
-
- {0xff, 0xff}, /* END MARKER */
-};
-
-/* Probe the I2C bus and initialise the sensor chip */
-int stk_sensor_init(struct stk_camera *dev)
-{
- u8 idl = 0;
- u8 idh = 0;
-
- if (stk_camera_write_reg(dev, STK_IIC_ENABLE, STK_IIC_ENABLE_YES)
- || stk_camera_write_reg(dev, STK_IIC_ADDR, SENSOR_ADDRESS)
- || stk_sensor_outb(dev, REG_COM7, COM7_RESET)) {
- STK_ERROR("Sensor resetting failed\n");
- return -ENODEV;
- }
- msleep(10);
- /* Read the manufacturer ID: ov = 0x7FA2 */
- if (stk_sensor_inb(dev, REG_MIDH, &idh)
- || stk_sensor_inb(dev, REG_MIDL, &idl)) {
- STK_ERROR("Strange error reading sensor ID\n");
- return -ENODEV;
- }
- if (idh != 0x7f || idl != 0xa2) {
- STK_ERROR("Huh? you don't have a sensor from ovt\n");
- return -ENODEV;
- }
- if (stk_sensor_inb(dev, REG_PID, &idh)
- || stk_sensor_inb(dev, REG_VER, &idl)) {
- STK_ERROR("Could not read sensor model\n");
- return -ENODEV;
- }
- stk_sensor_write_regvals(dev, ov_initvals);
- msleep(10);
- STK_INFO("OmniVision sensor detected, id %02X%02X"
- " at address %x\n", idh, idl, SENSOR_ADDRESS);
- return 0;
-}
-
-/* V4L2_PIX_FMT_UYVY */
-static struct regval ov_fmt_uyvy[] = {
- {REG_TSLB, TSLB_YLAST|0x08 },
- { 0x4f, 0x80 }, /* "matrix coefficient 1" */
- { 0x50, 0x80 }, /* "matrix coefficient 2" */
- { 0x51, 0 }, /* vb */
- { 0x52, 0x22 }, /* "matrix coefficient 4" */
- { 0x53, 0x5e }, /* "matrix coefficient 5" */
- { 0x54, 0x80 }, /* "matrix coefficient 6" */
- {REG_COM13, COM13_UVSAT|COM13_CMATRIX},
- {REG_COM15, COM15_R00FF },
- {0xff, 0xff}, /* END MARKER */
-};
-/* V4L2_PIX_FMT_YUYV */
-static struct regval ov_fmt_yuyv[] = {
- {REG_TSLB, 0 },
- { 0x4f, 0x80 }, /* "matrix coefficient 1" */
- { 0x50, 0x80 }, /* "matrix coefficient 2" */
- { 0x51, 0 }, /* vb */
- { 0x52, 0x22 }, /* "matrix coefficient 4" */
- { 0x53, 0x5e }, /* "matrix coefficient 5" */
- { 0x54, 0x80 }, /* "matrix coefficient 6" */
- {REG_COM13, COM13_UVSAT|COM13_CMATRIX},
- {REG_COM15, COM15_R00FF },
- {0xff, 0xff}, /* END MARKER */
-};
-
-/* V4L2_PIX_FMT_RGB565X rrrrrggg gggbbbbb */
-static struct regval ov_fmt_rgbr[] = {
- { REG_RGB444, 0 }, /* No RGB444 please */
- {REG_TSLB, 0x00},
- { REG_COM1, 0x0 },
- { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */
- { 0x4f, 0xb3 }, /* "matrix coefficient 1" */
- { 0x50, 0xb3 }, /* "matrix coefficient 2" */
- { 0x51, 0 }, /* vb */
- { 0x52, 0x3d }, /* "matrix coefficient 4" */
- { 0x53, 0xa7 }, /* "matrix coefficient 5" */
- { 0x54, 0xe4 }, /* "matrix coefficient 6" */
- { REG_COM13, COM13_GAMMA },
- { REG_COM15, COM15_RGB565|COM15_R00FF },
- { 0xff, 0xff },
-};
-
-/* V4L2_PIX_FMT_RGB565 gggbbbbb rrrrrggg */
-static struct regval ov_fmt_rgbp[] = {
- { REG_RGB444, 0 }, /* No RGB444 please */
- {REG_TSLB, TSLB_BYTEORD },
- { REG_COM1, 0x0 },
- { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */
- { 0x4f, 0xb3 }, /* "matrix coefficient 1" */
- { 0x50, 0xb3 }, /* "matrix coefficient 2" */
- { 0x51, 0 }, /* vb */
- { 0x52, 0x3d }, /* "matrix coefficient 4" */
- { 0x53, 0xa7 }, /* "matrix coefficient 5" */
- { 0x54, 0xe4 }, /* "matrix coefficient 6" */
- { REG_COM13, COM13_GAMMA },
- { REG_COM15, COM15_RGB565|COM15_R00FF },
- { 0xff, 0xff },
-};
-
-/* V4L2_PIX_FMT_SRGGB8 */
-static struct regval ov_fmt_bayer[] = {
- /* This changes color order */
- {REG_TSLB, 0x40}, /* BGGR */
- /* {REG_TSLB, 0x08}, */ /* BGGR with vertical image flipping */
- {REG_COM15, COM15_R00FF },
- {0xff, 0xff}, /* END MARKER */
-};
-/*
- * Store a set of start/stop values into the camera.
- */
-static int stk_sensor_set_hw(struct stk_camera *dev,
- int hstart, int hstop, int vstart, int vstop)
-{
- int ret;
- unsigned char v;
-/*
- * Horizontal: 11 bits, top 8 live in hstart and hstop. Bottom 3 of
- * hstart are in href[2:0], bottom 3 of hstop in href[5:3]. There is
- * a mystery "edge offset" value in the top two bits of href.
- */
- ret = stk_sensor_outb(dev, REG_HSTART, (hstart >> 3) & 0xff);
- ret += stk_sensor_outb(dev, REG_HSTOP, (hstop >> 3) & 0xff);
- ret += stk_sensor_inb(dev, REG_HREF, &v);
- v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x7);
- msleep(10);
- ret += stk_sensor_outb(dev, REG_HREF, v);
-/*
- * Vertical: similar arrangement (note: this is different from ov7670.c)
- */
- ret += stk_sensor_outb(dev, REG_VSTART, (vstart >> 3) & 0xff);
- ret += stk_sensor_outb(dev, REG_VSTOP, (vstop >> 3) & 0xff);
- ret += stk_sensor_inb(dev, REG_VREF, &v);
- v = (v & 0xc0) | ((vstop & 0x7) << 3) | (vstart & 0x7);
- msleep(10);
- ret += stk_sensor_outb(dev, REG_VREF, v);
- return ret;
-}
-
-
-int stk_sensor_configure(struct stk_camera *dev)
-{
- int com7;
- /*
- * We setup the sensor to output dummy lines in low-res modes,
- * so we don't get absurdly hight framerates.
- */
- unsigned dummylines;
- int flip;
- struct regval *rv;
-
- switch (dev->vsettings.mode) {
- case MODE_QCIF: com7 = COM7_FMT_QCIF;
- dummylines = 604;
- break;
- case MODE_QVGA: com7 = COM7_FMT_QVGA;
- dummylines = 267;
- break;
- case MODE_CIF: com7 = COM7_FMT_CIF;
- dummylines = 412;
- break;
- case MODE_VGA: com7 = COM7_FMT_VGA;
- dummylines = 11;
- break;
- case MODE_SXGA: com7 = COM7_FMT_SXGA;
- dummylines = 0;
- break;
- default: STK_ERROR("Unsupported mode %d\n", dev->vsettings.mode);
- return -EFAULT;
- }
- switch (dev->vsettings.palette) {
- case V4L2_PIX_FMT_UYVY:
- com7 |= COM7_YUV;
- rv = ov_fmt_uyvy;
- break;
- case V4L2_PIX_FMT_YUYV:
- com7 |= COM7_YUV;
- rv = ov_fmt_yuyv;
- break;
- case V4L2_PIX_FMT_RGB565:
- com7 |= COM7_RGB;
- rv = ov_fmt_rgbp;
- break;
- case V4L2_PIX_FMT_RGB565X:
- com7 |= COM7_RGB;
- rv = ov_fmt_rgbr;
- break;
- case V4L2_PIX_FMT_SBGGR8:
- com7 |= COM7_PBAYER;
- rv = ov_fmt_bayer;
- break;
- default: STK_ERROR("Unsupported colorspace\n");
- return -EFAULT;
- }
- /*FIXME sometimes the sensor go to a bad state
- stk_sensor_write_regvals(dev, ov_initvals); */
- stk_sensor_outb(dev, REG_COM7, com7);
- msleep(50);
- stk_sensor_write_regvals(dev, rv);
- flip = (dev->vsettings.vflip?MVFP_FLIP:0)
- | (dev->vsettings.hflip?MVFP_MIRROR:0);
- stk_sensor_outb(dev, REG_MVFP, flip);
- if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8
- && !dev->vsettings.vflip)
- stk_sensor_outb(dev, REG_TSLB, 0x08);
- stk_sensor_outb(dev, REG_ADVFH, dummylines >> 8);
- stk_sensor_outb(dev, REG_ADVFL, dummylines & 0xff);
- msleep(50);
- switch (dev->vsettings.mode) {
- case MODE_VGA:
- if (stk_sensor_set_hw(dev, 302, 1582, 6, 486))
- STK_ERROR("stk_sensor_set_hw failed (VGA)\n");
- break;
- case MODE_SXGA:
- case MODE_CIF:
- case MODE_QVGA:
- case MODE_QCIF:
- /*FIXME These settings seem ignored by the sensor
- if (stk_sensor_set_hw(dev, 220, 1500, 10, 1034))
- STK_ERROR("stk_sensor_set_hw failed (SXGA)\n");
- */
- break;
- }
- msleep(10);
- return 0;
-}
-
-int stk_sensor_set_brightness(struct stk_camera *dev, int br)
-{
- if (br < 0 || br > 0xff)
- return -EINVAL;
- stk_sensor_outb(dev, REG_AEB, max(0x00, br - 6));
- stk_sensor_outb(dev, REG_AEW, min(0xff, br + 6));
- return 0;
-}
-
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
deleted file mode 100644
index 86a0fc56c33..00000000000
--- a/drivers/media/video/stk-webcam.c
+++ /dev/null
@@ -1,1380 +0,0 @@
-/*
- * stk-webcam.c : Driver for Syntek 1125 USB webcam controller
- *
- * Copyright (C) 2006 Nicolas VIVIEN
- * Copyright 2007-2008 Jaime Velasco Juan <jsagarribay@gmail.com>
- *
- * Some parts are inspired from cafe_ccic.c
- * Copyright 2006-2007 Jonathan Corbet
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-
-#include <linux/usb.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-
-#include "stk-webcam.h"
-
-
-static bool hflip;
-module_param(hflip, bool, 0444);
-MODULE_PARM_DESC(hflip, "Horizontal image flip (mirror). Defaults to 0");
-
-static bool vflip;
-module_param(vflip, bool, 0444);
-MODULE_PARM_DESC(vflip, "Vertical image flip. Defaults to 0");
-
-static int debug;
-module_param(debug, int, 0444);
-MODULE_PARM_DESC(debug, "Debug v4l ioctls. Defaults to 0");
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jaime Velasco Juan <jsagarribay@gmail.com> and Nicolas VIVIEN");
-MODULE_DESCRIPTION("Syntek DC1125 webcam driver");
-
-
-/* bool for webcam LED management */
-int first_init = 1;
-
-/* Some cameras have audio interfaces, we aren't interested in those */
-static struct usb_device_id stkwebcam_table[] = {
- { USB_DEVICE_AND_INTERFACE_INFO(0x174f, 0xa311, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(0x05e1, 0x0501, 0xff, 0xff, 0xff) },
- { }
-};
-MODULE_DEVICE_TABLE(usb, stkwebcam_table);
-
-/*
- * Basic stuff
- */
-int stk_camera_write_reg(struct stk_camera *dev, u16 index, u8 value)
-{
- struct usb_device *udev = dev->udev;
- int ret;
-
- ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- 0x01,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value,
- index,
- NULL,
- 0,
- 500);
- if (ret < 0)
- return ret;
- else
- return 0;
-}
-
-int stk_camera_read_reg(struct stk_camera *dev, u16 index, int *value)
-{
- struct usb_device *udev = dev->udev;
- int ret;
-
- ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- 0x00,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x00,
- index,
- (u8 *) value,
- sizeof(u8),
- 500);
- if (ret < 0)
- return ret;
- else
- return 0;
-}
-
-static int stk_start_stream(struct stk_camera *dev)
-{
- int value;
- int i, ret;
- int value_116, value_117;
-
- if (!is_present(dev))
- return -ENODEV;
- if (!is_memallocd(dev) || !is_initialised(dev)) {
- STK_ERROR("FIXME: Buffers are not allocated\n");
- return -EFAULT;
- }
- ret = usb_set_interface(dev->udev, 0, 5);
-
- if (ret < 0)
- STK_ERROR("usb_set_interface failed !\n");
- if (stk_sensor_wakeup(dev))
- STK_ERROR("error awaking the sensor\n");
-
- stk_camera_read_reg(dev, 0x0116, &value_116);
- stk_camera_read_reg(dev, 0x0117, &value_117);
-
- stk_camera_write_reg(dev, 0x0116, 0x0000);
- stk_camera_write_reg(dev, 0x0117, 0x0000);
-
- stk_camera_read_reg(dev, 0x0100, &value);
- stk_camera_write_reg(dev, 0x0100, value | 0x80);
-
- stk_camera_write_reg(dev, 0x0116, value_116);
- stk_camera_write_reg(dev, 0x0117, value_117);
- for (i = 0; i < MAX_ISO_BUFS; i++) {
- if (dev->isobufs[i].urb) {
- ret = usb_submit_urb(dev->isobufs[i].urb, GFP_KERNEL);
- atomic_inc(&dev->urbs_used);
- if (ret)
- return ret;
- }
- }
- set_streaming(dev);
- return 0;
-}
-
-static int stk_stop_stream(struct stk_camera *dev)
-{
- int value;
- int i;
- if (is_present(dev)) {
- stk_camera_read_reg(dev, 0x0100, &value);
- stk_camera_write_reg(dev, 0x0100, value & ~0x80);
- if (dev->isobufs != NULL) {
- for (i = 0; i < MAX_ISO_BUFS; i++) {
- if (dev->isobufs[i].urb)
- usb_kill_urb(dev->isobufs[i].urb);
- }
- }
- unset_streaming(dev);
-
- if (usb_set_interface(dev->udev, 0, 0))
- STK_ERROR("usb_set_interface failed !\n");
- if (stk_sensor_sleep(dev))
- STK_ERROR("error suspending the sensor\n");
- }
- return 0;
-}
-
-/*
- * This seems to be the shortest init sequence we
- * must do in order to find the sensor
- * Bit 5 of reg. 0x0000 here is important, when reset to 0 the sensor
- * is also reset. Maybe powers down it?
- * Rest of values don't make a difference
- */
-
-static struct regval stk1125_initvals[] = {
- /*TODO: What means this sequence? */
- {0x0000, 0x24},
- {0x0100, 0x21},
- {0x0002, 0x68},
- {0x0003, 0x80},
- {0x0005, 0x00},
- {0x0007, 0x03},
- {0x000d, 0x00},
- {0x000f, 0x02},
- {0x0300, 0x12},
- {0x0350, 0x41},
- {0x0351, 0x00},
- {0x0352, 0x00},
- {0x0353, 0x00},
- {0x0018, 0x10},
- {0x0019, 0x00},
- {0x001b, 0x0e},
- {0x001c, 0x46},
- {0x0300, 0x80},
- {0x001a, 0x04},
- {0x0110, 0x00},
- {0x0111, 0x00},
- {0x0112, 0x00},
- {0x0113, 0x00},
-
- {0xffff, 0xff},
-};
-
-
-static int stk_initialise(struct stk_camera *dev)
-{
- struct regval *rv;
- int ret;
- if (!is_present(dev))
- return -ENODEV;
- if (is_initialised(dev))
- return 0;
- rv = stk1125_initvals;
- while (rv->reg != 0xffff) {
- ret = stk_camera_write_reg(dev, rv->reg, rv->val);
- if (ret)
- return ret;
- rv++;
- }
- if (stk_sensor_init(dev) == 0) {
- set_initialised(dev);
- return 0;
- } else
- return -1;
-}
-
-/* *********************************************** */
-/*
- * This function is called as an URB transfert is complete (Isochronous pipe).
- * So, the traitement is done in interrupt time, so it has be fast, not crash,
- * and not stall. Neat.
- */
-static void stk_isoc_handler(struct urb *urb)
-{
- int i;
- int ret;
- int framelen;
- unsigned long flags;
-
- unsigned char *fill = NULL;
- unsigned char *iso_buf = NULL;
-
- struct stk_camera *dev;
- struct stk_sio_buffer *fb;
-
- dev = (struct stk_camera *) urb->context;
-
- if (dev == NULL) {
- STK_ERROR("isoc_handler called with NULL device !\n");
- return;
- }
-
- if (urb->status == -ENOENT || urb->status == -ECONNRESET
- || urb->status == -ESHUTDOWN) {
- atomic_dec(&dev->urbs_used);
- return;
- }
-
- spin_lock_irqsave(&dev->spinlock, flags);
-
- if (urb->status != -EINPROGRESS && urb->status != 0) {
- STK_ERROR("isoc_handler: urb->status == %d\n", urb->status);
- goto resubmit;
- }
-
- if (list_empty(&dev->sio_avail)) {
- /*FIXME Stop streaming after a while */
- (void) (printk_ratelimit() &&
- STK_ERROR("isoc_handler without available buffer!\n"));
- goto resubmit;
- }
- fb = list_first_entry(&dev->sio_avail,
- struct stk_sio_buffer, list);
- fill = fb->buffer + fb->v4lbuf.bytesused;
-
- for (i = 0; i < urb->number_of_packets; i++) {
- if (urb->iso_frame_desc[i].status != 0) {
- if (urb->iso_frame_desc[i].status != -EXDEV)
- STK_ERROR("Frame %d has error %d\n", i,
- urb->iso_frame_desc[i].status);
- continue;
- }
- framelen = urb->iso_frame_desc[i].actual_length;
- iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
-
- if (framelen <= 4)
- continue; /* no data */
-
- /*
- * we found something informational from there
- * the isoc frames have to type of headers
- * type1: 00 xx 00 00 or 20 xx 00 00
- * type2: 80 xx 00 00 00 00 00 00 or a0 xx 00 00 00 00 00 00
- * xx is a sequencer which has never been seen over 0x3f
- * imho data written down looks like bayer, i see similarities
- * after every 640 bytes
- */
- if (*iso_buf & 0x80) {
- framelen -= 8;
- iso_buf += 8;
- /* This marks a new frame */
- if (fb->v4lbuf.bytesused != 0
- && fb->v4lbuf.bytesused != dev->frame_size) {
- (void) (printk_ratelimit() &&
- STK_ERROR("frame %d, "
- "bytesused=%d, skipping\n",
- i, fb->v4lbuf.bytesused));
- fb->v4lbuf.bytesused = 0;
- fill = fb->buffer;
- } else if (fb->v4lbuf.bytesused == dev->frame_size) {
- if (list_is_singular(&dev->sio_avail)) {
- /* Always reuse the last buffer */
- fb->v4lbuf.bytesused = 0;
- fill = fb->buffer;
- } else {
- list_move_tail(dev->sio_avail.next,
- &dev->sio_full);
- wake_up(&dev->wait_frame);
- fb = list_first_entry(&dev->sio_avail,
- struct stk_sio_buffer, list);
- fb->v4lbuf.bytesused = 0;
- fill = fb->buffer;
- }
- }
- } else {
- framelen -= 4;
- iso_buf += 4;
- }
-
- /* Our buffer is full !!! */
- if (framelen + fb->v4lbuf.bytesused > dev->frame_size) {
- (void) (printk_ratelimit() &&
- STK_ERROR("Frame buffer overflow, lost sync\n"));
- /*FIXME Do something here? */
- continue;
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
- memcpy(fill, iso_buf, framelen);
- spin_lock_irqsave(&dev->spinlock, flags);
- fill += framelen;
-
- /* New size of our buffer */
- fb->v4lbuf.bytesused += framelen;
- }
-
-resubmit:
- spin_unlock_irqrestore(&dev->spinlock, flags);
- urb->dev = dev->udev;
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret != 0) {
- STK_ERROR("Error (%d) re-submitting urb in stk_isoc_handler.\n",
- ret);
- }
-}
-
-/* -------------------------------------------- */
-
-static int stk_prepare_iso(struct stk_camera *dev)
-{
- void *kbuf;
- int i, j;
- struct urb *urb;
- struct usb_device *udev;
-
- if (dev == NULL)
- return -ENXIO;
- udev = dev->udev;
-
- if (dev->isobufs)
- STK_ERROR("isobufs already allocated. Bad\n");
- else
- dev->isobufs = kcalloc(MAX_ISO_BUFS, sizeof(*dev->isobufs),
- GFP_KERNEL);
- if (dev->isobufs == NULL) {
- STK_ERROR("Unable to allocate iso buffers\n");
- return -ENOMEM;
- }
- for (i = 0; i < MAX_ISO_BUFS; i++) {
- if (dev->isobufs[i].data == NULL) {
- kbuf = kzalloc(ISO_BUFFER_SIZE, GFP_KERNEL);
- if (kbuf == NULL) {
- STK_ERROR("Failed to allocate iso buffer %d\n",
- i);
- goto isobufs_out;
- }
- dev->isobufs[i].data = kbuf;
- } else
- STK_ERROR("isobuf data already allocated\n");
- if (dev->isobufs[i].urb == NULL) {
- urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
- if (urb == NULL) {
- STK_ERROR("Failed to allocate URB %d\n", i);
- goto isobufs_out;
- }
- dev->isobufs[i].urb = urb;
- } else {
- STK_ERROR("Killing URB\n");
- usb_kill_urb(dev->isobufs[i].urb);
- urb = dev->isobufs[i].urb;
- }
- urb->interval = 1;
- urb->dev = udev;
- urb->pipe = usb_rcvisocpipe(udev, dev->isoc_ep);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = dev->isobufs[i].data;
- urb->transfer_buffer_length = ISO_BUFFER_SIZE;
- urb->complete = stk_isoc_handler;
- urb->context = dev;
- urb->start_frame = 0;
- urb->number_of_packets = ISO_FRAMES_PER_DESC;
-
- for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
- urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE;
- urb->iso_frame_desc[j].length = ISO_MAX_FRAME_SIZE;
- }
- }
- set_memallocd(dev);
- return 0;
-
-isobufs_out:
- for (i = 0; i < MAX_ISO_BUFS && dev->isobufs[i].data; i++)
- kfree(dev->isobufs[i].data);
- for (i = 0; i < MAX_ISO_BUFS && dev->isobufs[i].urb; i++)
- usb_free_urb(dev->isobufs[i].urb);
- kfree(dev->isobufs);
- dev->isobufs = NULL;
- return -ENOMEM;
-}
-
-static void stk_clean_iso(struct stk_camera *dev)
-{
- int i;
-
- if (dev == NULL || dev->isobufs == NULL)
- return;
-
- for (i = 0; i < MAX_ISO_BUFS; i++) {
- struct urb *urb;
-
- urb = dev->isobufs[i].urb;
- if (urb) {
- if (atomic_read(&dev->urbs_used) && is_present(dev))
- usb_kill_urb(urb);
- usb_free_urb(urb);
- }
- kfree(dev->isobufs[i].data);
- }
- kfree(dev->isobufs);
- dev->isobufs = NULL;
- unset_memallocd(dev);
-}
-
-static int stk_setup_siobuf(struct stk_camera *dev, int index)
-{
- struct stk_sio_buffer *buf = dev->sio_bufs + index;
- INIT_LIST_HEAD(&buf->list);
- buf->v4lbuf.length = PAGE_ALIGN(dev->frame_size);
- buf->buffer = vmalloc_user(buf->v4lbuf.length);
- if (buf->buffer == NULL)
- return -ENOMEM;
- buf->mapcount = 0;
- buf->dev = dev;
- buf->v4lbuf.index = index;
- buf->v4lbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- buf->v4lbuf.field = V4L2_FIELD_NONE;
- buf->v4lbuf.memory = V4L2_MEMORY_MMAP;
- buf->v4lbuf.m.offset = 2*index*buf->v4lbuf.length;
- return 0;
-}
-
-static int stk_free_sio_buffers(struct stk_camera *dev)
-{
- int i;
- int nbufs;
- unsigned long flags;
- if (dev->n_sbufs == 0 || dev->sio_bufs == NULL)
- return 0;
- /*
- * If any buffers are mapped, we cannot free them at all.
- */
- for (i = 0; i < dev->n_sbufs; i++) {
- if (dev->sio_bufs[i].mapcount > 0)
- return -EBUSY;
- }
- /*
- * OK, let's do it.
- */
- spin_lock_irqsave(&dev->spinlock, flags);
- INIT_LIST_HEAD(&dev->sio_avail);
- INIT_LIST_HEAD(&dev->sio_full);
- nbufs = dev->n_sbufs;
- dev->n_sbufs = 0;
- spin_unlock_irqrestore(&dev->spinlock, flags);
- for (i = 0; i < nbufs; i++) {
- if (dev->sio_bufs[i].buffer != NULL)
- vfree(dev->sio_bufs[i].buffer);
- }
- kfree(dev->sio_bufs);
- dev->sio_bufs = NULL;
- return 0;
-}
-
-static int stk_prepare_sio_buffers(struct stk_camera *dev, unsigned n_sbufs)
-{
- int i;
- if (dev->sio_bufs != NULL)
- STK_ERROR("sio_bufs already allocated\n");
- else {
- dev->sio_bufs = kzalloc(n_sbufs * sizeof(struct stk_sio_buffer),
- GFP_KERNEL);
- if (dev->sio_bufs == NULL)
- return -ENOMEM;
- for (i = 0; i < n_sbufs; i++) {
- if (stk_setup_siobuf(dev, i))
- return (dev->n_sbufs > 1 ? 0 : -ENOMEM);
- dev->n_sbufs = i+1;
- }
- }
- return 0;
-}
-
-static int stk_allocate_buffers(struct stk_camera *dev, unsigned n_sbufs)
-{
- int err;
- err = stk_prepare_iso(dev);
- if (err) {
- stk_clean_iso(dev);
- return err;
- }
- err = stk_prepare_sio_buffers(dev, n_sbufs);
- if (err) {
- stk_free_sio_buffers(dev);
- return err;
- }
- return 0;
-}
-
-static void stk_free_buffers(struct stk_camera *dev)
-{
- stk_clean_iso(dev);
- stk_free_sio_buffers(dev);
-}
-/* -------------------------------------------- */
-
-/* v4l file operations */
-
-static int v4l_stk_open(struct file *fp)
-{
- struct stk_camera *dev;
- struct video_device *vdev;
-
- vdev = video_devdata(fp);
- dev = vdev_to_camera(vdev);
-
- if (dev == NULL || !is_present(dev))
- return -ENXIO;
-
- if (!first_init)
- stk_camera_write_reg(dev, 0x0, 0x24);
- else
- first_init = 0;
-
- fp->private_data = dev;
- usb_autopm_get_interface(dev->interface);
-
- return 0;
-}
-
-static int v4l_stk_release(struct file *fp)
-{
- struct stk_camera *dev = fp->private_data;
-
- if (dev->owner == fp) {
- stk_stop_stream(dev);
- stk_free_buffers(dev);
- stk_camera_write_reg(dev, 0x0, 0x49); /* turn off the LED */
- unset_initialised(dev);
- dev->owner = NULL;
- }
-
- if (is_present(dev))
- usb_autopm_put_interface(dev->interface);
-
- return 0;
-}
-
-static ssize_t v4l_stk_read(struct file *fp, char __user *buf,
- size_t count, loff_t *f_pos)
-{
- int i;
- int ret;
- unsigned long flags;
- struct stk_sio_buffer *sbuf;
- struct stk_camera *dev = fp->private_data;
-
- if (!is_present(dev))
- return -EIO;
- if (dev->owner && dev->owner != fp)
- return -EBUSY;
- dev->owner = fp;
- if (!is_streaming(dev)) {
- if (stk_initialise(dev)
- || stk_allocate_buffers(dev, 3)
- || stk_start_stream(dev))
- return -ENOMEM;
- spin_lock_irqsave(&dev->spinlock, flags);
- for (i = 0; i < dev->n_sbufs; i++) {
- list_add_tail(&dev->sio_bufs[i].list, &dev->sio_avail);
- dev->sio_bufs[i].v4lbuf.flags = V4L2_BUF_FLAG_QUEUED;
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
- }
- if (*f_pos == 0) {
- if (fp->f_flags & O_NONBLOCK && list_empty(&dev->sio_full))
- return -EWOULDBLOCK;
- ret = wait_event_interruptible(dev->wait_frame,
- !list_empty(&dev->sio_full) || !is_present(dev));
- if (ret)
- return ret;
- if (!is_present(dev))
- return -EIO;
- }
- if (count + *f_pos > dev->frame_size)
- count = dev->frame_size - *f_pos;
- spin_lock_irqsave(&dev->spinlock, flags);
- if (list_empty(&dev->sio_full)) {
- spin_unlock_irqrestore(&dev->spinlock, flags);
- STK_ERROR("BUG: No siobufs ready\n");
- return 0;
- }
- sbuf = list_first_entry(&dev->sio_full, struct stk_sio_buffer, list);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- if (copy_to_user(buf, sbuf->buffer + *f_pos, count))
- return -EFAULT;
-
- *f_pos += count;
-
- if (*f_pos >= dev->frame_size) {
- *f_pos = 0;
- spin_lock_irqsave(&dev->spinlock, flags);
- list_move_tail(&sbuf->list, &dev->sio_avail);
- spin_unlock_irqrestore(&dev->spinlock, flags);
- }
- return count;
-}
-
-static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait)
-{
- struct stk_camera *dev = fp->private_data;
-
- poll_wait(fp, &dev->wait_frame, wait);
-
- if (!is_present(dev))
- return POLLERR;
-
- if (!list_empty(&dev->sio_full))
- return POLLIN | POLLRDNORM;
-
- return 0;
-}
-
-
-static void stk_v4l_vm_open(struct vm_area_struct *vma)
-{
- struct stk_sio_buffer *sbuf = vma->vm_private_data;
- sbuf->mapcount++;
-}
-static void stk_v4l_vm_close(struct vm_area_struct *vma)
-{
- struct stk_sio_buffer *sbuf = vma->vm_private_data;
- sbuf->mapcount--;
- if (sbuf->mapcount == 0)
- sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_MAPPED;
-}
-static const struct vm_operations_struct stk_v4l_vm_ops = {
- .open = stk_v4l_vm_open,
- .close = stk_v4l_vm_close
-};
-
-static int v4l_stk_mmap(struct file *fp, struct vm_area_struct *vma)
-{
- unsigned int i;
- int ret;
- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
- struct stk_camera *dev = fp->private_data;
- struct stk_sio_buffer *sbuf = NULL;
-
- if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
- return -EINVAL;
-
- for (i = 0; i < dev->n_sbufs; i++) {
- if (dev->sio_bufs[i].v4lbuf.m.offset == offset) {
- sbuf = dev->sio_bufs + i;
- break;
- }
- }
- if (sbuf == NULL)
- return -EINVAL;
- ret = remap_vmalloc_range(vma, sbuf->buffer, 0);
- if (ret)
- return ret;
- vma->vm_flags |= VM_DONTEXPAND;
- vma->vm_private_data = sbuf;
- vma->vm_ops = &stk_v4l_vm_ops;
- sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_MAPPED;
- stk_v4l_vm_open(vma);
- return 0;
-}
-
-/* v4l ioctl handlers */
-
-static int stk_vidioc_querycap(struct file *filp,
- void *priv, struct v4l2_capability *cap)
-{
- strcpy(cap->driver, "stk");
- strcpy(cap->card, "stk");
- cap->version = DRIVER_VERSION_NUM;
-
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
- | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
- return 0;
-}
-
-static int stk_vidioc_enum_input(struct file *filp,
- void *priv, struct v4l2_input *input)
-{
- if (input->index != 0)
- return -EINVAL;
-
- strcpy(input->name, "Syntek USB Camera");
- input->type = V4L2_INPUT_TYPE_CAMERA;
- return 0;
-}
-
-
-static int stk_vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int stk_vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
- if (i != 0)
- return -EINVAL;
- else
- return 0;
-}
-
-/* from vivi.c */
-static int stk_vidioc_s_std(struct file *filp, void *priv, v4l2_std_id *a)
-{
- return 0;
-}
-
-/* List of all V4Lv2 controls supported by the driver */
-static struct v4l2_queryctrl stk_controls[] = {
- {
- .id = V4L2_CID_BRIGHTNESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Brightness",
- .minimum = 0,
- .maximum = 0xffff,
- .step = 0x0100,
- .default_value = 0x6000,
- },
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Horizontal Flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1,
- },
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Vertical Flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1,
- },
-};
-
-static int stk_vidioc_queryctrl(struct file *filp,
- void *priv, struct v4l2_queryctrl *c)
-{
- int i;
- int nbr;
- nbr = ARRAY_SIZE(stk_controls);
-
- for (i = 0; i < nbr; i++) {
- if (stk_controls[i].id == c->id) {
- memcpy(c, &stk_controls[i],
- sizeof(struct v4l2_queryctrl));
- return 0;
- }
- }
- return -EINVAL;
-}
-
-static int stk_vidioc_g_ctrl(struct file *filp,
- void *priv, struct v4l2_control *c)
-{
- struct stk_camera *dev = priv;
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- c->value = dev->vsettings.brightness;
- break;
- case V4L2_CID_HFLIP:
- c->value = dev->vsettings.hflip;
- break;
- case V4L2_CID_VFLIP:
- c->value = dev->vsettings.vflip;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int stk_vidioc_s_ctrl(struct file *filp,
- void *priv, struct v4l2_control *c)
-{
- struct stk_camera *dev = priv;
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- dev->vsettings.brightness = c->value;
- return stk_sensor_set_brightness(dev, c->value >> 8);
- case V4L2_CID_HFLIP:
- dev->vsettings.hflip = c->value;
- return 0;
- case V4L2_CID_VFLIP:
- dev->vsettings.vflip = c->value;
- return 0;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-
-static int stk_vidioc_enum_fmt_vid_cap(struct file *filp,
- void *priv, struct v4l2_fmtdesc *fmtd)
-{
- switch (fmtd->index) {
- case 0:
- fmtd->pixelformat = V4L2_PIX_FMT_RGB565;
- strcpy(fmtd->description, "r5g6b5");
- break;
- case 1:
- fmtd->pixelformat = V4L2_PIX_FMT_RGB565X;
- strcpy(fmtd->description, "r5g6b5BE");
- break;
- case 2:
- fmtd->pixelformat = V4L2_PIX_FMT_UYVY;
- strcpy(fmtd->description, "yuv4:2:2");
- break;
- case 3:
- fmtd->pixelformat = V4L2_PIX_FMT_SBGGR8;
- strcpy(fmtd->description, "Raw bayer");
- break;
- case 4:
- fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
- strcpy(fmtd->description, "yuv4:2:2");
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static struct stk_size {
- unsigned w;
- unsigned h;
- enum stk_mode m;
-} stk_sizes[] = {
- { .w = 1280, .h = 1024, .m = MODE_SXGA, },
- { .w = 640, .h = 480, .m = MODE_VGA, },
- { .w = 352, .h = 288, .m = MODE_CIF, },
- { .w = 320, .h = 240, .m = MODE_QVGA, },
- { .w = 176, .h = 144, .m = MODE_QCIF, },
-};
-
-static int stk_vidioc_g_fmt_vid_cap(struct file *filp,
- void *priv, struct v4l2_format *f)
-{
- struct v4l2_pix_format *pix_format = &f->fmt.pix;
- struct stk_camera *dev = priv;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(stk_sizes) &&
- stk_sizes[i].m != dev->vsettings.mode; i++)
- ;
- if (i == ARRAY_SIZE(stk_sizes)) {
- STK_ERROR("ERROR: mode invalid\n");
- return -EINVAL;
- }
- pix_format->width = stk_sizes[i].w;
- pix_format->height = stk_sizes[i].h;
- pix_format->field = V4L2_FIELD_NONE;
- pix_format->colorspace = V4L2_COLORSPACE_SRGB;
- pix_format->pixelformat = dev->vsettings.palette;
- if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8)
- pix_format->bytesperline = pix_format->width;
- else
- pix_format->bytesperline = 2 * pix_format->width;
- pix_format->sizeimage = pix_format->bytesperline
- * pix_format->height;
- return 0;
-}
-
-static int stk_vidioc_try_fmt_vid_cap(struct file *filp,
- void *priv, struct v4l2_format *fmtd)
-{
- int i;
- switch (fmtd->fmt.pix.pixelformat) {
- case V4L2_PIX_FMT_RGB565:
- case V4L2_PIX_FMT_RGB565X:
- case V4L2_PIX_FMT_UYVY:
- case V4L2_PIX_FMT_YUYV:
- case V4L2_PIX_FMT_SBGGR8:
- break;
- default:
- return -EINVAL;
- }
- for (i = 1; i < ARRAY_SIZE(stk_sizes); i++) {
- if (fmtd->fmt.pix.width > stk_sizes[i].w)
- break;
- }
- if (i == ARRAY_SIZE(stk_sizes)
- || (abs(fmtd->fmt.pix.width - stk_sizes[i-1].w)
- < abs(fmtd->fmt.pix.width - stk_sizes[i].w))) {
- fmtd->fmt.pix.height = stk_sizes[i-1].h;
- fmtd->fmt.pix.width = stk_sizes[i-1].w;
- fmtd->fmt.pix.priv = i - 1;
- } else {
- fmtd->fmt.pix.height = stk_sizes[i].h;
- fmtd->fmt.pix.width = stk_sizes[i].w;
- fmtd->fmt.pix.priv = i;
- }
-
- fmtd->fmt.pix.field = V4L2_FIELD_NONE;
- fmtd->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
- if (fmtd->fmt.pix.pixelformat == V4L2_PIX_FMT_SBGGR8)
- fmtd->fmt.pix.bytesperline = fmtd->fmt.pix.width;
- else
- fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width;
- fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.bytesperline
- * fmtd->fmt.pix.height;
- return 0;
-}
-
-static int stk_setup_format(struct stk_camera *dev)
-{
- int i = 0;
- int depth;
- if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8)
- depth = 1;
- else
- depth = 2;
- while (i < ARRAY_SIZE(stk_sizes) &&
- stk_sizes[i].m != dev->vsettings.mode)
- i++;
- if (i == ARRAY_SIZE(stk_sizes)) {
- STK_ERROR("Something is broken in %s\n", __func__);
- return -EFAULT;
- }
- /* This registers controls some timings, not sure of what. */
- stk_camera_write_reg(dev, 0x001b, 0x0e);
- if (dev->vsettings.mode == MODE_SXGA)
- stk_camera_write_reg(dev, 0x001c, 0x0e);
- else
- stk_camera_write_reg(dev, 0x001c, 0x46);
- /*
- * Registers 0x0115 0x0114 are the size of each line (bytes),
- * regs 0x0117 0x0116 are the heigth of the image.
- */
- stk_camera_write_reg(dev, 0x0115,
- ((stk_sizes[i].w * depth) >> 8) & 0xff);
- stk_camera_write_reg(dev, 0x0114,
- (stk_sizes[i].w * depth) & 0xff);
- stk_camera_write_reg(dev, 0x0117,
- (stk_sizes[i].h >> 8) & 0xff);
- stk_camera_write_reg(dev, 0x0116,
- stk_sizes[i].h & 0xff);
- return stk_sensor_configure(dev);
-}
-
-static int stk_vidioc_s_fmt_vid_cap(struct file *filp,
- void *priv, struct v4l2_format *fmtd)
-{
- int ret;
- struct stk_camera *dev = priv;
-
- if (dev == NULL)
- return -ENODEV;
- if (!is_present(dev))
- return -ENODEV;
- if (is_streaming(dev))
- return -EBUSY;
- if (dev->owner && dev->owner != filp)
- return -EBUSY;
- ret = stk_vidioc_try_fmt_vid_cap(filp, priv, fmtd);
- if (ret)
- return ret;
- dev->owner = filp;
-
- dev->vsettings.palette = fmtd->fmt.pix.pixelformat;
- stk_free_buffers(dev);
- dev->frame_size = fmtd->fmt.pix.sizeimage;
- dev->vsettings.mode = stk_sizes[fmtd->fmt.pix.priv].m;
-
- stk_initialise(dev);
- return stk_setup_format(dev);
-}
-
-static int stk_vidioc_reqbufs(struct file *filp,
- void *priv, struct v4l2_requestbuffers *rb)
-{
- struct stk_camera *dev = priv;
-
- if (dev == NULL)
- return -ENODEV;
- if (rb->memory != V4L2_MEMORY_MMAP)
- return -EINVAL;
- if (is_streaming(dev)
- || (dev->owner && dev->owner != filp))
- return -EBUSY;
- dev->owner = filp;
-
- /*FIXME If they ask for zero, we must stop streaming and free */
- if (rb->count < 3)
- rb->count = 3;
- /* Arbitrary limit */
- else if (rb->count > 5)
- rb->count = 5;
-
- stk_allocate_buffers(dev, rb->count);
- rb->count = dev->n_sbufs;
- return 0;
-}
-
-static int stk_vidioc_querybuf(struct file *filp,
- void *priv, struct v4l2_buffer *buf)
-{
- struct stk_camera *dev = priv;
- struct stk_sio_buffer *sbuf;
-
- if (buf->index >= dev->n_sbufs)
- return -EINVAL;
- sbuf = dev->sio_bufs + buf->index;
- *buf = sbuf->v4lbuf;
- return 0;
-}
-
-static int stk_vidioc_qbuf(struct file *filp,
- void *priv, struct v4l2_buffer *buf)
-{
- struct stk_camera *dev = priv;
- struct stk_sio_buffer *sbuf;
- unsigned long flags;
-
- if (buf->memory != V4L2_MEMORY_MMAP)
- return -EINVAL;
-
- if (buf->index >= dev->n_sbufs)
- return -EINVAL;
- sbuf = dev->sio_bufs + buf->index;
- if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED)
- return 0;
- sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_QUEUED;
- sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_DONE;
- spin_lock_irqsave(&dev->spinlock, flags);
- list_add_tail(&sbuf->list, &dev->sio_avail);
- *buf = sbuf->v4lbuf;
- spin_unlock_irqrestore(&dev->spinlock, flags);
- return 0;
-}
-
-static int stk_vidioc_dqbuf(struct file *filp,
- void *priv, struct v4l2_buffer *buf)
-{
- struct stk_camera *dev = priv;
- struct stk_sio_buffer *sbuf;
- unsigned long flags;
- int ret;
-
- if (!is_streaming(dev))
- return -EINVAL;
-
- if (filp->f_flags & O_NONBLOCK && list_empty(&dev->sio_full))
- return -EWOULDBLOCK;
- ret = wait_event_interruptible(dev->wait_frame,
- !list_empty(&dev->sio_full) || !is_present(dev));
- if (ret)
- return ret;
- if (!is_present(dev))
- return -EIO;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- sbuf = list_first_entry(&dev->sio_full, struct stk_sio_buffer, list);
- list_del_init(&sbuf->list);
- spin_unlock_irqrestore(&dev->spinlock, flags);
- sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED;
- sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE;
- sbuf->v4lbuf.sequence = ++dev->sequence;
- do_gettimeofday(&sbuf->v4lbuf.timestamp);
-
- *buf = sbuf->v4lbuf;
- return 0;
-}
-
-static int stk_vidioc_streamon(struct file *filp,
- void *priv, enum v4l2_buf_type type)
-{
- struct stk_camera *dev = priv;
- if (is_streaming(dev))
- return 0;
- if (dev->sio_bufs == NULL)
- return -EINVAL;
- dev->sequence = 0;
- return stk_start_stream(dev);
-}
-
-static int stk_vidioc_streamoff(struct file *filp,
- void *priv, enum v4l2_buf_type type)
-{
- struct stk_camera *dev = priv;
- unsigned long flags;
- int i;
- stk_stop_stream(dev);
- spin_lock_irqsave(&dev->spinlock, flags);
- INIT_LIST_HEAD(&dev->sio_avail);
- INIT_LIST_HEAD(&dev->sio_full);
- for (i = 0; i < dev->n_sbufs; i++) {
- INIT_LIST_HEAD(&dev->sio_bufs[i].list);
- dev->sio_bufs[i].v4lbuf.flags = 0;
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
- return 0;
-}
-
-
-static int stk_vidioc_g_parm(struct file *filp,
- void *priv, struct v4l2_streamparm *sp)
-{
- /*FIXME This is not correct */
- sp->parm.capture.timeperframe.numerator = 1;
- sp->parm.capture.timeperframe.denominator = 30;
- sp->parm.capture.readbuffers = 2;
- return 0;
-}
-
-static int stk_vidioc_enum_framesizes(struct file *filp,
- void *priv, struct v4l2_frmsizeenum *frms)
-{
- if (frms->index >= ARRAY_SIZE(stk_sizes))
- return -EINVAL;
- switch (frms->pixel_format) {
- case V4L2_PIX_FMT_RGB565:
- case V4L2_PIX_FMT_RGB565X:
- case V4L2_PIX_FMT_UYVY:
- case V4L2_PIX_FMT_YUYV:
- case V4L2_PIX_FMT_SBGGR8:
- frms->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- frms->discrete.width = stk_sizes[frms->index].w;
- frms->discrete.height = stk_sizes[frms->index].h;
- return 0;
- default: return -EINVAL;
- }
-}
-
-static struct v4l2_file_operations v4l_stk_fops = {
- .owner = THIS_MODULE,
- .open = v4l_stk_open,
- .release = v4l_stk_release,
- .read = v4l_stk_read,
- .poll = v4l_stk_poll,
- .mmap = v4l_stk_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = {
- .vidioc_querycap = stk_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = stk_vidioc_enum_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = stk_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = stk_vidioc_s_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = stk_vidioc_g_fmt_vid_cap,
- .vidioc_enum_input = stk_vidioc_enum_input,
- .vidioc_s_input = stk_vidioc_s_input,
- .vidioc_g_input = stk_vidioc_g_input,
- .vidioc_s_std = stk_vidioc_s_std,
- .vidioc_reqbufs = stk_vidioc_reqbufs,
- .vidioc_querybuf = stk_vidioc_querybuf,
- .vidioc_qbuf = stk_vidioc_qbuf,
- .vidioc_dqbuf = stk_vidioc_dqbuf,
- .vidioc_streamon = stk_vidioc_streamon,
- .vidioc_streamoff = stk_vidioc_streamoff,
- .vidioc_queryctrl = stk_vidioc_queryctrl,
- .vidioc_g_ctrl = stk_vidioc_g_ctrl,
- .vidioc_s_ctrl = stk_vidioc_s_ctrl,
- .vidioc_g_parm = stk_vidioc_g_parm,
- .vidioc_enum_framesizes = stk_vidioc_enum_framesizes,
-};
-
-static void stk_v4l_dev_release(struct video_device *vd)
-{
- struct stk_camera *dev = vdev_to_camera(vd);
-
- if (dev->sio_bufs != NULL || dev->isobufs != NULL)
- STK_ERROR("We are leaking memory\n");
- usb_put_intf(dev->interface);
- kfree(dev);
-}
-
-static struct video_device stk_v4l_data = {
- .name = "stkwebcam",
- .tvnorms = V4L2_STD_UNKNOWN,
- .current_norm = V4L2_STD_UNKNOWN,
- .fops = &v4l_stk_fops,
- .ioctl_ops = &v4l_stk_ioctl_ops,
- .release = stk_v4l_dev_release,
-};
-
-
-static int stk_register_video_device(struct stk_camera *dev)
-{
- int err;
-
- dev->vdev = stk_v4l_data;
- dev->vdev.debug = debug;
- dev->vdev.parent = &dev->interface->dev;
- err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1);
- if (err)
- STK_ERROR("v4l registration failed\n");
- else
- STK_INFO("Syntek USB2.0 Camera is now controlling device %s\n",
- video_device_node_name(&dev->vdev));
- return err;
-}
-
-
-/* USB Stuff */
-
-static int stk_camera_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- int i;
- int err = 0;
-
- struct stk_camera *dev = NULL;
- struct usb_device *udev = interface_to_usbdev(interface);
- struct usb_host_interface *iface_desc;
- struct usb_endpoint_descriptor *endpoint;
-
- dev = kzalloc(sizeof(struct stk_camera), GFP_KERNEL);
- if (dev == NULL) {
- STK_ERROR("Out of memory !\n");
- return -ENOMEM;
- }
-
- spin_lock_init(&dev->spinlock);
- init_waitqueue_head(&dev->wait_frame);
-
- dev->udev = udev;
- dev->interface = interface;
- usb_get_intf(interface);
-
- dev->vsettings.vflip = vflip;
- dev->vsettings.hflip = hflip;
- dev->n_sbufs = 0;
- set_present(dev);
-
- /* Set up the endpoint information
- * use only the first isoc-in endpoint
- * for the current alternate setting */
- iface_desc = interface->cur_altsetting;
-
- for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
- endpoint = &iface_desc->endpoint[i].desc;
-
- if (!dev->isoc_ep
- && usb_endpoint_is_isoc_in(endpoint)) {
- /* we found an isoc in endpoint */
- dev->isoc_ep = usb_endpoint_num(endpoint);
- break;
- }
- }
- if (!dev->isoc_ep) {
- STK_ERROR("Could not find isoc-in endpoint");
- err = -ENODEV;
- goto error;
- }
- dev->vsettings.brightness = 0x7fff;
- dev->vsettings.palette = V4L2_PIX_FMT_RGB565;
- dev->vsettings.mode = MODE_VGA;
- dev->frame_size = 640 * 480 * 2;
-
- INIT_LIST_HEAD(&dev->sio_avail);
- INIT_LIST_HEAD(&dev->sio_full);
-
- usb_set_intfdata(interface, dev);
-
- err = stk_register_video_device(dev);
- if (err)
- goto error;
-
- return 0;
-
-error:
- kfree(dev);
- return err;
-}
-
-static void stk_camera_disconnect(struct usb_interface *interface)
-{
- struct stk_camera *dev = usb_get_intfdata(interface);
-
- usb_set_intfdata(interface, NULL);
- unset_present(dev);
-
- wake_up_interruptible(&dev->wait_frame);
-
- STK_INFO("Syntek USB2.0 Camera release resources device %s\n",
- video_device_node_name(&dev->vdev));
-
- video_unregister_device(&dev->vdev);
-}
-
-#ifdef CONFIG_PM
-static int stk_camera_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct stk_camera *dev = usb_get_intfdata(intf);
- if (is_streaming(dev)) {
- stk_stop_stream(dev);
- /* yes, this is ugly */
- set_streaming(dev);
- }
- return 0;
-}
-
-static int stk_camera_resume(struct usb_interface *intf)
-{
- struct stk_camera *dev = usb_get_intfdata(intf);
- if (!is_initialised(dev))
- return 0;
- unset_initialised(dev);
- stk_initialise(dev);
- stk_camera_write_reg(dev, 0x0, 0x49);
- stk_setup_format(dev);
- if (is_streaming(dev))
- stk_start_stream(dev);
- return 0;
-}
-#endif
-
-static struct usb_driver stk_camera_driver = {
- .name = "stkwebcam",
- .probe = stk_camera_probe,
- .disconnect = stk_camera_disconnect,
- .id_table = stkwebcam_table,
-#ifdef CONFIG_PM
- .suspend = stk_camera_suspend,
- .resume = stk_camera_resume,
-#endif
-};
-
-module_usb_driver(stk_camera_driver);
diff --git a/drivers/media/video/stk-webcam.h b/drivers/media/video/stk-webcam.h
deleted file mode 100644
index 9f673663757..00000000000
--- a/drivers/media/video/stk-webcam.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * stk-webcam.h : Driver for Syntek 1125 USB webcam controller
- *
- * Copyright (C) 2006 Nicolas VIVIEN
- * Copyright 2007-2008 Jaime Velasco Juan <jsagarribay@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef STKWEBCAM_H
-#define STKWEBCAM_H
-
-#include <linux/usb.h>
-#include <media/v4l2-common.h>
-
-#define DRIVER_VERSION "v0.0.1"
-#define DRIVER_VERSION_NUM 0x000001
-
-#define MAX_ISO_BUFS 3
-#define ISO_FRAMES_PER_DESC 16
-#define ISO_MAX_FRAME_SIZE 3 * 1024
-#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
-
-
-#define PREFIX "stkwebcam: "
-#define STK_INFO(str, args...) printk(KERN_INFO PREFIX str, ##args)
-#define STK_ERROR(str, args...) printk(KERN_ERR PREFIX str, ##args)
-#define STK_WARNING(str, args...) printk(KERN_WARNING PREFIX str, ##args)
-
-struct stk_iso_buf {
- void *data;
- int length;
- int read;
- struct urb *urb;
-};
-
-/* Streaming IO buffers */
-struct stk_sio_buffer {
- struct v4l2_buffer v4lbuf;
- char *buffer;
- int mapcount;
- struct stk_camera *dev;
- struct list_head list;
-};
-
-enum stk_mode {MODE_VGA, MODE_SXGA, MODE_CIF, MODE_QVGA, MODE_QCIF};
-
-struct stk_video {
- enum stk_mode mode;
- int brightness;
- __u32 palette;
- int hflip;
- int vflip;
-};
-
-enum stk_status {
- S_PRESENT = 1,
- S_INITIALISED = 2,
- S_MEMALLOCD = 4,
- S_STREAMING = 8,
-};
-#define is_present(dev) ((dev)->status & S_PRESENT)
-#define is_initialised(dev) ((dev)->status & S_INITIALISED)
-#define is_streaming(dev) ((dev)->status & S_STREAMING)
-#define is_memallocd(dev) ((dev)->status & S_MEMALLOCD)
-#define set_present(dev) ((dev)->status = S_PRESENT)
-#define unset_present(dev) ((dev)->status &= \
- ~(S_PRESENT|S_INITIALISED|S_STREAMING))
-#define set_initialised(dev) ((dev)->status |= S_INITIALISED)
-#define unset_initialised(dev) ((dev)->status &= ~S_INITIALISED)
-#define set_memallocd(dev) ((dev)->status |= S_MEMALLOCD)
-#define unset_memallocd(dev) ((dev)->status &= ~S_MEMALLOCD)
-#define set_streaming(dev) ((dev)->status |= S_STREAMING)
-#define unset_streaming(dev) ((dev)->status &= ~S_STREAMING)
-
-struct regval {
- unsigned reg;
- unsigned val;
-};
-
-struct stk_camera {
- struct video_device vdev;
- struct usb_device *udev;
- struct usb_interface *interface;
- int webcam_model;
- struct file *owner;
-
- u8 isoc_ep;
-
- /* Not sure if this is right */
- atomic_t urbs_used;
-
- struct stk_video vsettings;
-
- enum stk_status status;
-
- spinlock_t spinlock;
- wait_queue_head_t wait_frame;
-
- struct stk_iso_buf *isobufs;
-
- int frame_size;
- /* Streaming buffers */
- unsigned int n_sbufs;
- struct stk_sio_buffer *sio_bufs;
- struct list_head sio_avail;
- struct list_head sio_full;
- unsigned sequence;
-};
-
-#define vdev_to_camera(d) container_of(d, struct stk_camera, vdev)
-
-int stk_camera_write_reg(struct stk_camera *, u16, u8);
-int stk_camera_read_reg(struct stk_camera *, u16, int *);
-
-int stk_sensor_init(struct stk_camera *);
-int stk_sensor_configure(struct stk_camera *);
-int stk_sensor_sleep(struct stk_camera *dev);
-int stk_sensor_wakeup(struct stk_camera *dev);
-int stk_sensor_set_brightness(struct stk_camera *dev, int br);
-
-#endif
diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c
deleted file mode 100644
index 462caa44ae0..00000000000
--- a/drivers/media/video/tcm825x.c
+++ /dev/null
@@ -1,937 +0,0 @@
-/*
- * drivers/media/video/tcm825x.c
- *
- * TCM825X camera sensor driver.
- *
- * Copyright (C) 2007 Nokia Corporation.
- *
- * Contact: Sakari Ailus <sakari.ailus@nokia.com>
- *
- * Based on code from David Cohen <david.cohen@indt.org.br>
- *
- * This driver was based on ov9640 sensor driver from MontaVista
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/i2c.h>
-#include <linux/module.h>
-#include <media/v4l2-int-device.h>
-
-#include "tcm825x.h"
-
-/*
- * The sensor has two fps modes: the lower one just gives half the fps
- * at the same xclk than the high one.
- */
-#define MAX_FPS 30
-#define MIN_FPS 8
-#define MAX_HALF_FPS (MAX_FPS / 2)
-#define HIGH_FPS_MODE_LOWER_LIMIT 14
-#define DEFAULT_FPS MAX_HALF_FPS
-
-struct tcm825x_sensor {
- const struct tcm825x_platform_data *platform_data;
- struct v4l2_int_device *v4l2_int_device;
- struct i2c_client *i2c_client;
- struct v4l2_pix_format pix;
- struct v4l2_fract timeperframe;
-};
-
-/* list of image formats supported by TCM825X sensor */
-static const struct v4l2_fmtdesc tcm825x_formats[] = {
- {
- .description = "YUYV (YUV 4:2:2), packed",
- .pixelformat = V4L2_PIX_FMT_UYVY,
- }, {
- /* Note: V4L2 defines RGB565 as:
- *
- * Byte 0 Byte 1
- * g2 g1 g0 r4 r3 r2 r1 r0 b4 b3 b2 b1 b0 g5 g4 g3
- *
- * We interpret RGB565 as:
- *
- * Byte 0 Byte 1
- * g2 g1 g0 b4 b3 b2 b1 b0 r4 r3 r2 r1 r0 g5 g4 g3
- */
- .description = "RGB565, le",
- .pixelformat = V4L2_PIX_FMT_RGB565,
- },
-};
-
-#define TCM825X_NUM_CAPTURE_FORMATS ARRAY_SIZE(tcm825x_formats)
-
-/*
- * TCM825X register configuration for all combinations of pixel format and
- * image size
- */
-static const struct tcm825x_reg subqcif = { 0x20, TCM825X_PICSIZ };
-static const struct tcm825x_reg qcif = { 0x18, TCM825X_PICSIZ };
-static const struct tcm825x_reg cif = { 0x14, TCM825X_PICSIZ };
-static const struct tcm825x_reg qqvga = { 0x0c, TCM825X_PICSIZ };
-static const struct tcm825x_reg qvga = { 0x04, TCM825X_PICSIZ };
-static const struct tcm825x_reg vga = { 0x00, TCM825X_PICSIZ };
-
-static const struct tcm825x_reg yuv422 = { 0x00, TCM825X_PICFMT };
-static const struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT };
-
-/* Our own specific controls */
-#define V4L2_CID_ALC V4L2_CID_PRIVATE_BASE
-#define V4L2_CID_H_EDGE_EN V4L2_CID_PRIVATE_BASE + 1
-#define V4L2_CID_V_EDGE_EN V4L2_CID_PRIVATE_BASE + 2
-#define V4L2_CID_LENS V4L2_CID_PRIVATE_BASE + 3
-#define V4L2_CID_MAX_EXPOSURE_TIME V4L2_CID_PRIVATE_BASE + 4
-#define V4L2_CID_LAST_PRIV V4L2_CID_MAX_EXPOSURE_TIME
-
-/* Video controls */
-static struct vcontrol {
- struct v4l2_queryctrl qc;
- u16 reg;
- u16 start_bit;
-} video_control[] = {
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain",
- .minimum = 0,
- .maximum = 63,
- .step = 1,
- },
- .reg = TCM825X_AG,
- .start_bit = 0,
- },
- {
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Red Balance",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- },
- .reg = TCM825X_MRG,
- .start_bit = 0,
- },
- {
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Blue Balance",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- },
- .reg = TCM825X_MBG,
- .start_bit = 0,
- },
- {
- {
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Auto White Balance",
- .minimum = 0,
- .maximum = 1,
- .step = 0,
- },
- .reg = TCM825X_AWBSW,
- .start_bit = 7,
- },
- {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Exposure Time",
- .minimum = 0,
- .maximum = 0x1fff,
- .step = 1,
- },
- .reg = TCM825X_ESRSPD_U,
- .start_bit = 0,
- },
- {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Mirror Image",
- .minimum = 0,
- .maximum = 1,
- .step = 0,
- },
- .reg = TCM825X_H_INV,
- .start_bit = 6,
- },
- {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Vertical Flip",
- .minimum = 0,
- .maximum = 1,
- .step = 0,
- },
- .reg = TCM825X_V_INV,
- .start_bit = 7,
- },
- /* Private controls */
- {
- {
- .id = V4L2_CID_ALC,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Auto Luminance Control",
- .minimum = 0,
- .maximum = 1,
- .step = 0,
- },
- .reg = TCM825X_ALCSW,
- .start_bit = 7,
- },
- {
- {
- .id = V4L2_CID_H_EDGE_EN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Horizontal Edge Enhancement",
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- },
- .reg = TCM825X_HDTG,
- .start_bit = 0,
- },
- {
- {
- .id = V4L2_CID_V_EDGE_EN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Vertical Edge Enhancement",
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- },
- .reg = TCM825X_VDTG,
- .start_bit = 0,
- },
- {
- {
- .id = V4L2_CID_LENS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Lens Shading Compensation",
- .minimum = 0,
- .maximum = 0x3f,
- .step = 1,
- },
- .reg = TCM825X_LENS,
- .start_bit = 0,
- },
- {
- {
- .id = V4L2_CID_MAX_EXPOSURE_TIME,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Maximum Exposure Time",
- .minimum = 0,
- .maximum = 0x3,
- .step = 1,
- },
- .reg = TCM825X_ESRLIM,
- .start_bit = 5,
- },
-};
-
-
-static const struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] =
-{ &subqcif, &qqvga, &qcif, &qvga, &cif, &vga };
-
-static const struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] =
-{ &yuv422, &rgb565 };
-
-/*
- * Read a value from a register in an TCM825X sensor device. The value is
- * returned in 'val'.
- * Returns zero if successful, or non-zero otherwise.
- */
-static int tcm825x_read_reg(struct i2c_client *client, int reg)
-{
- int err;
- struct i2c_msg msg[2];
- u8 reg_buf, data_buf = 0;
-
- if (!client->adapter)
- return -ENODEV;
-
- msg[0].addr = client->addr;
- msg[0].flags = 0;
- msg[0].len = 1;
- msg[0].buf = &reg_buf;
- msg[1].addr = client->addr;
- msg[1].flags = I2C_M_RD;
- msg[1].len = 1;
- msg[1].buf = &data_buf;
-
- reg_buf = reg;
-
- err = i2c_transfer(client->adapter, msg, 2);
- if (err < 0)
- return err;
- return data_buf;
-}
-
-/*
- * Write a value to a register in an TCM825X sensor device.
- * Returns zero if successful, or non-zero otherwise.
- */
-static int tcm825x_write_reg(struct i2c_client *client, u8 reg, u8 val)
-{
- int err;
- struct i2c_msg msg[1];
- unsigned char data[2];
-
- if (!client->adapter)
- return -ENODEV;
-
- msg->addr = client->addr;
- msg->flags = 0;
- msg->len = 2;
- msg->buf = data;
- data[0] = reg;
- data[1] = val;
- err = i2c_transfer(client->adapter, msg, 1);
- if (err >= 0)
- return 0;
- return err;
-}
-
-static int __tcm825x_write_reg_mask(struct i2c_client *client,
- u8 reg, u8 val, u8 mask)
-{
- int rc;
-
- /* need to do read - modify - write */
- rc = tcm825x_read_reg(client, reg);
- if (rc < 0)
- return rc;
-
- rc &= (~mask); /* Clear the masked bits */
- val &= mask; /* Enforce mask on value */
- val |= rc;
-
- /* write the new value to the register */
- rc = tcm825x_write_reg(client, reg, val);
- if (rc)
- return rc;
-
- return 0;
-}
-
-#define tcm825x_write_reg_mask(client, regmask, val) \
- __tcm825x_write_reg_mask(client, TCM825X_ADDR((regmask)), val, \
- TCM825X_MASK((regmask)))
-
-
-/*
- * Initialize a list of TCM825X registers.
- * The list of registers is terminated by the pair of values
- * { TCM825X_REG_TERM, TCM825X_VAL_TERM }.
- * Returns zero if successful, or non-zero otherwise.
- */
-static int tcm825x_write_default_regs(struct i2c_client *client,
- const struct tcm825x_reg *reglist)
-{
- int err;
- const struct tcm825x_reg *next = reglist;
-
- while (!((next->reg == TCM825X_REG_TERM)
- && (next->val == TCM825X_VAL_TERM))) {
- err = tcm825x_write_reg(client, next->reg, next->val);
- if (err) {
- dev_err(&client->dev, "register writing failed\n");
- return err;
- }
- next++;
- }
-
- return 0;
-}
-
-static struct vcontrol *find_vctrl(int id)
-{
- int i;
-
- if (id < V4L2_CID_BASE)
- return NULL;
-
- for (i = 0; i < ARRAY_SIZE(video_control); i++)
- if (video_control[i].qc.id == id)
- return &video_control[i];
-
- return NULL;
-}
-
-/*
- * Find the best match for a requested image capture size. The best match
- * is chosen as the nearest match that has the same number or fewer pixels
- * as the requested size, or the smallest image size if the requested size
- * has fewer pixels than the smallest image.
- */
-static enum image_size tcm825x_find_size(struct v4l2_int_device *s,
- unsigned int width,
- unsigned int height)
-{
- enum image_size isize;
- unsigned long pixels = width * height;
- struct tcm825x_sensor *sensor = s->priv;
-
- for (isize = subQCIF; isize < VGA; isize++) {
- if (tcm825x_sizes[isize + 1].height
- * tcm825x_sizes[isize + 1].width > pixels) {
- dev_dbg(&sensor->i2c_client->dev, "size %d\n", isize);
-
- return isize;
- }
- }
-
- dev_dbg(&sensor->i2c_client->dev, "format default VGA\n");
-
- return VGA;
-}
-
-/*
- * Configure the TCM825X for current image size, pixel format, and
- * frame period. fper is the frame period (in seconds) expressed as a
- * fraction. Returns zero if successful, or non-zero otherwise. The
- * actual frame period is returned in fper.
- */
-static int tcm825x_configure(struct v4l2_int_device *s)
-{
- struct tcm825x_sensor *sensor = s->priv;
- struct v4l2_pix_format *pix = &sensor->pix;
- enum image_size isize = tcm825x_find_size(s, pix->width, pix->height);
- struct v4l2_fract *fper = &sensor->timeperframe;
- enum pixel_format pfmt;
- int err;
- u32 tgt_fps;
- u8 val;
-
- /* common register initialization */
- err = tcm825x_write_default_regs(
- sensor->i2c_client, sensor->platform_data->default_regs());
- if (err)
- return err;
-
- /* configure image size */
- val = tcm825x_siz_reg[isize]->val;
- dev_dbg(&sensor->i2c_client->dev,
- "configuring image size %d\n", isize);
- err = tcm825x_write_reg_mask(sensor->i2c_client,
- tcm825x_siz_reg[isize]->reg, val);
- if (err)
- return err;
-
- /* configure pixel format */
- switch (pix->pixelformat) {
- default:
- case V4L2_PIX_FMT_RGB565:
- pfmt = RGB565;
- break;
- case V4L2_PIX_FMT_UYVY:
- pfmt = YUV422;
- break;
- }
-
- dev_dbg(&sensor->i2c_client->dev,
- "configuring pixel format %d\n", pfmt);
- val = tcm825x_fmt_reg[pfmt]->val;
-
- err = tcm825x_write_reg_mask(sensor->i2c_client,
- tcm825x_fmt_reg[pfmt]->reg, val);
- if (err)
- return err;
-
- /*
- * For frame rate < 15, the FPS reg (addr 0x02, bit 7) must be
- * set. Frame rate will be halved from the normal.
- */
- tgt_fps = fper->denominator / fper->numerator;
- if (tgt_fps <= HIGH_FPS_MODE_LOWER_LIMIT) {
- val = tcm825x_read_reg(sensor->i2c_client, 0x02);
- val |= 0x80;
- tcm825x_write_reg(sensor->i2c_client, 0x02, val);
- }
-
- return 0;
-}
-
-static int ioctl_queryctrl(struct v4l2_int_device *s,
- struct v4l2_queryctrl *qc)
-{
- struct vcontrol *control;
-
- control = find_vctrl(qc->id);
-
- if (control == NULL)
- return -EINVAL;
-
- *qc = control->qc;
-
- return 0;
-}
-
-static int ioctl_g_ctrl(struct v4l2_int_device *s,
- struct v4l2_control *vc)
-{
- struct tcm825x_sensor *sensor = s->priv;
- struct i2c_client *client = sensor->i2c_client;
- int val, r;
- struct vcontrol *lvc;
-
- /* exposure time is special, spread across 2 registers */
- if (vc->id == V4L2_CID_EXPOSURE) {
- int val_lower, val_upper;
-
- val_upper = tcm825x_read_reg(client,
- TCM825X_ADDR(TCM825X_ESRSPD_U));
- if (val_upper < 0)
- return val_upper;
- val_lower = tcm825x_read_reg(client,
- TCM825X_ADDR(TCM825X_ESRSPD_L));
- if (val_lower < 0)
- return val_lower;
-
- vc->value = ((val_upper & 0x1f) << 8) | (val_lower);
- return 0;
- }
-
- lvc = find_vctrl(vc->id);
- if (lvc == NULL)
- return -EINVAL;
-
- r = tcm825x_read_reg(client, TCM825X_ADDR(lvc->reg));
- if (r < 0)
- return r;
- val = r & TCM825X_MASK(lvc->reg);
- val >>= lvc->start_bit;
-
- if (val < 0)
- return val;
-
- if (vc->id == V4L2_CID_HFLIP || vc->id == V4L2_CID_VFLIP)
- val ^= sensor->platform_data->is_upside_down();
-
- vc->value = val;
- return 0;
-}
-
-static int ioctl_s_ctrl(struct v4l2_int_device *s,
- struct v4l2_control *vc)
-{
- struct tcm825x_sensor *sensor = s->priv;
- struct i2c_client *client = sensor->i2c_client;
- struct vcontrol *lvc;
- int val = vc->value;
-
- /* exposure time is special, spread across 2 registers */
- if (vc->id == V4L2_CID_EXPOSURE) {
- int val_lower, val_upper;
- val_lower = val & TCM825X_MASK(TCM825X_ESRSPD_L);
- val_upper = (val >> 8) & TCM825X_MASK(TCM825X_ESRSPD_U);
-
- if (tcm825x_write_reg_mask(client,
- TCM825X_ESRSPD_U, val_upper))
- return -EIO;
-
- if (tcm825x_write_reg_mask(client,
- TCM825X_ESRSPD_L, val_lower))
- return -EIO;
-
- return 0;
- }
-
- lvc = find_vctrl(vc->id);
- if (lvc == NULL)
- return -EINVAL;
-
- if (vc->id == V4L2_CID_HFLIP || vc->id == V4L2_CID_VFLIP)
- val ^= sensor->platform_data->is_upside_down();
-
- val = val << lvc->start_bit;
- if (tcm825x_write_reg_mask(client, lvc->reg, val))
- return -EIO;
-
- return 0;
-}
-
-static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
- struct v4l2_fmtdesc *fmt)
-{
- int index = fmt->index;
-
- switch (fmt->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (index >= TCM825X_NUM_CAPTURE_FORMATS)
- return -EINVAL;
- break;
-
- default:
- return -EINVAL;
- }
-
- fmt->flags = tcm825x_formats[index].flags;
- strlcpy(fmt->description, tcm825x_formats[index].description,
- sizeof(fmt->description));
- fmt->pixelformat = tcm825x_formats[index].pixelformat;
-
- return 0;
-}
-
-static int ioctl_try_fmt_cap(struct v4l2_int_device *s,
- struct v4l2_format *f)
-{
- struct tcm825x_sensor *sensor = s->priv;
- enum image_size isize;
- int ifmt;
- struct v4l2_pix_format *pix = &f->fmt.pix;
-
- isize = tcm825x_find_size(s, pix->width, pix->height);
- dev_dbg(&sensor->i2c_client->dev, "isize = %d num_capture = %lu\n",
- isize, (unsigned long)TCM825X_NUM_CAPTURE_FORMATS);
-
- pix->width = tcm825x_sizes[isize].width;
- pix->height = tcm825x_sizes[isize].height;
-
- for (ifmt = 0; ifmt < TCM825X_NUM_CAPTURE_FORMATS; ifmt++)
- if (pix->pixelformat == tcm825x_formats[ifmt].pixelformat)
- break;
-
- if (ifmt == TCM825X_NUM_CAPTURE_FORMATS)
- ifmt = 0; /* Default = YUV 4:2:2 */
-
- pix->pixelformat = tcm825x_formats[ifmt].pixelformat;
- pix->field = V4L2_FIELD_NONE;
- pix->bytesperline = pix->width * TCM825X_BYTES_PER_PIXEL;
- pix->sizeimage = pix->bytesperline * pix->height;
- pix->priv = 0;
- dev_dbg(&sensor->i2c_client->dev, "format = 0x%08x\n",
- pix->pixelformat);
-
- switch (pix->pixelformat) {
- case V4L2_PIX_FMT_UYVY:
- default:
- pix->colorspace = V4L2_COLORSPACE_JPEG;
- break;
- case V4L2_PIX_FMT_RGB565:
- pix->colorspace = V4L2_COLORSPACE_SRGB;
- break;
- }
-
- return 0;
-}
-
-static int ioctl_s_fmt_cap(struct v4l2_int_device *s,
- struct v4l2_format *f)
-{
- struct tcm825x_sensor *sensor = s->priv;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- int rval;
-
- rval = ioctl_try_fmt_cap(s, f);
- if (rval)
- return rval;
-
- rval = tcm825x_configure(s);
-
- sensor->pix = *pix;
-
- return rval;
-}
-
-static int ioctl_g_fmt_cap(struct v4l2_int_device *s,
- struct v4l2_format *f)
-{
- struct tcm825x_sensor *sensor = s->priv;
-
- f->fmt.pix = sensor->pix;
-
- return 0;
-}
-
-static int ioctl_g_parm(struct v4l2_int_device *s,
- struct v4l2_streamparm *a)
-{
- struct tcm825x_sensor *sensor = s->priv;
- struct v4l2_captureparm *cparm = &a->parm.capture;
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- memset(a, 0, sizeof(*a));
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- cparm->capability = V4L2_CAP_TIMEPERFRAME;
- cparm->timeperframe = sensor->timeperframe;
-
- return 0;
-}
-
-static int ioctl_s_parm(struct v4l2_int_device *s,
- struct v4l2_streamparm *a)
-{
- struct tcm825x_sensor *sensor = s->priv;
- struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
- u32 tgt_fps; /* target frames per secound */
- int rval;
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if ((timeperframe->numerator == 0)
- || (timeperframe->denominator == 0)) {
- timeperframe->denominator = DEFAULT_FPS;
- timeperframe->numerator = 1;
- }
-
- tgt_fps = timeperframe->denominator / timeperframe->numerator;
-
- if (tgt_fps > MAX_FPS) {
- timeperframe->denominator = MAX_FPS;
- timeperframe->numerator = 1;
- } else if (tgt_fps < MIN_FPS) {
- timeperframe->denominator = MIN_FPS;
- timeperframe->numerator = 1;
- }
-
- sensor->timeperframe = *timeperframe;
-
- rval = tcm825x_configure(s);
-
- return rval;
-}
-
-static int ioctl_s_power(struct v4l2_int_device *s, int on)
-{
- struct tcm825x_sensor *sensor = s->priv;
-
- return sensor->platform_data->power_set(on);
-}
-
-/*
- * Given the image capture format in pix, the nominal frame period in
- * timeperframe, calculate the required xclk frequency.
- *
- * TCM825X input frequency characteristics are:
- * Minimum 11.9 MHz, Typical 24.57 MHz and maximum 25/27 MHz
- */
-
-static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
-{
- struct tcm825x_sensor *sensor = s->priv;
- struct v4l2_fract *timeperframe = &sensor->timeperframe;
- u32 tgt_xclk; /* target xclk */
- u32 tgt_fps; /* target frames per secound */
- int rval;
-
- rval = sensor->platform_data->ifparm(p);
- if (rval)
- return rval;
-
- tgt_fps = timeperframe->denominator / timeperframe->numerator;
-
- tgt_xclk = (tgt_fps <= HIGH_FPS_MODE_LOWER_LIMIT) ?
- (2457 * tgt_fps) / MAX_HALF_FPS :
- (2457 * tgt_fps) / MAX_FPS;
- tgt_xclk *= 10000;
-
- tgt_xclk = min(tgt_xclk, (u32)TCM825X_XCLK_MAX);
- tgt_xclk = max(tgt_xclk, (u32)TCM825X_XCLK_MIN);
-
- p->u.bt656.clock_curr = tgt_xclk;
-
- return 0;
-}
-
-static int ioctl_g_needs_reset(struct v4l2_int_device *s, void *buf)
-{
- struct tcm825x_sensor *sensor = s->priv;
-
- return sensor->platform_data->needs_reset(s, buf, &sensor->pix);
-}
-
-static int ioctl_reset(struct v4l2_int_device *s)
-{
- return -EBUSY;
-}
-
-static int ioctl_init(struct v4l2_int_device *s)
-{
- return tcm825x_configure(s);
-}
-
-static int ioctl_dev_exit(struct v4l2_int_device *s)
-{
- return 0;
-}
-
-static int ioctl_dev_init(struct v4l2_int_device *s)
-{
- struct tcm825x_sensor *sensor = s->priv;
- int r;
-
- r = tcm825x_read_reg(sensor->i2c_client, 0x01);
- if (r < 0)
- return r;
- if (r == 0) {
- dev_err(&sensor->i2c_client->dev, "device not detected\n");
- return -EIO;
- }
- return 0;
-}
-
-static struct v4l2_int_ioctl_desc tcm825x_ioctl_desc[] = {
- { vidioc_int_dev_init_num,
- (v4l2_int_ioctl_func *)ioctl_dev_init },
- { vidioc_int_dev_exit_num,
- (v4l2_int_ioctl_func *)ioctl_dev_exit },
- { vidioc_int_s_power_num,
- (v4l2_int_ioctl_func *)ioctl_s_power },
- { vidioc_int_g_ifparm_num,
- (v4l2_int_ioctl_func *)ioctl_g_ifparm },
- { vidioc_int_g_needs_reset_num,
- (v4l2_int_ioctl_func *)ioctl_g_needs_reset },
- { vidioc_int_reset_num,
- (v4l2_int_ioctl_func *)ioctl_reset },
- { vidioc_int_init_num,
- (v4l2_int_ioctl_func *)ioctl_init },
- { vidioc_int_enum_fmt_cap_num,
- (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap },
- { vidioc_int_try_fmt_cap_num,
- (v4l2_int_ioctl_func *)ioctl_try_fmt_cap },
- { vidioc_int_g_fmt_cap_num,
- (v4l2_int_ioctl_func *)ioctl_g_fmt_cap },
- { vidioc_int_s_fmt_cap_num,
- (v4l2_int_ioctl_func *)ioctl_s_fmt_cap },
- { vidioc_int_g_parm_num,
- (v4l2_int_ioctl_func *)ioctl_g_parm },
- { vidioc_int_s_parm_num,
- (v4l2_int_ioctl_func *)ioctl_s_parm },
- { vidioc_int_queryctrl_num,
- (v4l2_int_ioctl_func *)ioctl_queryctrl },
- { vidioc_int_g_ctrl_num,
- (v4l2_int_ioctl_func *)ioctl_g_ctrl },
- { vidioc_int_s_ctrl_num,
- (v4l2_int_ioctl_func *)ioctl_s_ctrl },
-};
-
-static struct v4l2_int_slave tcm825x_slave = {
- .ioctls = tcm825x_ioctl_desc,
- .num_ioctls = ARRAY_SIZE(tcm825x_ioctl_desc),
-};
-
-static struct tcm825x_sensor tcm825x;
-
-static struct v4l2_int_device tcm825x_int_device = {
- .module = THIS_MODULE,
- .name = TCM825X_NAME,
- .priv = &tcm825x,
- .type = v4l2_int_type_slave,
- .u = {
- .slave = &tcm825x_slave,
- },
-};
-
-static int tcm825x_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct tcm825x_sensor *sensor = &tcm825x;
-
- if (i2c_get_clientdata(client))
- return -EBUSY;
-
- sensor->platform_data = client->dev.platform_data;
-
- if (sensor->platform_data == NULL
- || !sensor->platform_data->is_okay())
- return -ENODEV;
-
- sensor->v4l2_int_device = &tcm825x_int_device;
-
- sensor->i2c_client = client;
- i2c_set_clientdata(client, sensor);
-
- /* Make the default capture format QVGA RGB565 */
- sensor->pix.width = tcm825x_sizes[QVGA].width;
- sensor->pix.height = tcm825x_sizes[QVGA].height;
- sensor->pix.pixelformat = V4L2_PIX_FMT_RGB565;
-
- return v4l2_int_device_register(sensor->v4l2_int_device);
-}
-
-static int tcm825x_remove(struct i2c_client *client)
-{
- struct tcm825x_sensor *sensor = i2c_get_clientdata(client);
-
- if (!client->adapter)
- return -ENODEV; /* our client isn't attached */
-
- v4l2_int_device_unregister(sensor->v4l2_int_device);
-
- return 0;
-}
-
-static const struct i2c_device_id tcm825x_id[] = {
- { "tcm825x", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tcm825x_id);
-
-static struct i2c_driver tcm825x_i2c_driver = {
- .driver = {
- .name = TCM825X_NAME,
- },
- .probe = tcm825x_probe,
- .remove = tcm825x_remove,
- .id_table = tcm825x_id,
-};
-
-static struct tcm825x_sensor tcm825x = {
- .timeperframe = {
- .numerator = 1,
- .denominator = DEFAULT_FPS,
- },
-};
-
-static int __init tcm825x_init(void)
-{
- int rval;
-
- rval = i2c_add_driver(&tcm825x_i2c_driver);
- if (rval)
- printk(KERN_INFO "%s: failed registering " TCM825X_NAME "\n",
- __func__);
-
- return rval;
-}
-
-static void __exit tcm825x_exit(void)
-{
- i2c_del_driver(&tcm825x_i2c_driver);
-}
-
-/*
- * FIXME: Menelaus isn't ready (?) at module_init stage, so use
- * late_initcall for now.
- */
-late_initcall(tcm825x_init);
-module_exit(tcm825x_exit);
-
-MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>");
-MODULE_DESCRIPTION("TCM825x camera sensor driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tcm825x.h b/drivers/media/video/tcm825x.h
deleted file mode 100644
index 5b7e6968236..00000000000
--- a/drivers/media/video/tcm825x.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * drivers/media/video/tcm825x.h
- *
- * Register definitions for the TCM825X CameraChip.
- *
- * Author: David Cohen (david.cohen@indt.org.br)
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- *
- * This file was based on ov9640.h from MontaVista
- */
-
-#ifndef TCM825X_H
-#define TCM825X_H
-
-#include <linux/videodev2.h>
-
-#include <media/v4l2-int-device.h>
-
-#define TCM825X_NAME "tcm825x"
-
-#define TCM825X_MASK(x) x & 0x00ff
-#define TCM825X_ADDR(x) (x & 0xff00) >> 8
-
-/* The TCM825X I2C sensor chip has a fixed slave address of 0x3d. */
-#define TCM825X_I2C_ADDR 0x3d
-
-/*
- * define register offsets for the TCM825X sensor chip
- * OFFSET(8 bits) + MASK(8 bits)
- * MASK bit 4 and 3 are used when the register uses more than one address
- */
-#define TCM825X_FPS 0x0280
-#define TCM825X_ACF 0x0240
-#define TCM825X_DOUTBUF 0x020C
-#define TCM825X_DCLKP 0x0202
-#define TCM825X_ACFDET 0x0201
-#define TCM825X_DOUTSW 0x0380
-#define TCM825X_DATAHZ 0x0340
-#define TCM825X_PICSIZ 0x033c
-#define TCM825X_PICFMT 0x0302
-#define TCM825X_V_INV 0x0480
-#define TCM825X_H_INV 0x0440
-#define TCM825X_ESRLSW 0x0430
-#define TCM825X_V_LENGTH 0x040F
-#define TCM825X_ALCSW 0x0580
-#define TCM825X_ESRLIM 0x0560
-#define TCM825X_ESRSPD_U 0x051F
-#define TCM825X_ESRSPD_L 0x06FF
-#define TCM825X_AG 0x07FF
-#define TCM825X_ESRSPD2 0x06FF
-#define TCM825X_ALCMODE 0x0830
-#define TCM825X_ALCH 0x080F
-#define TCM825X_ALCL 0x09FF
-#define TCM825X_AWBSW 0x0A80
-#define TCM825X_MRG 0x0BFF
-#define TCM825X_MBG 0x0CFF
-#define TCM825X_GAMSW 0x0D80
-#define TCM825X_HDTG 0x0EFF
-#define TCM825X_VDTG 0x0FFF
-#define TCM825X_HDTCORE 0x10F0
-#define TCM825X_VDTCORE 0x100F
-#define TCM825X_CONT 0x11FF
-#define TCM825X_BRIGHT 0x12FF
-#define TCM825X_VHUE 0x137F
-#define TCM825X_UHUE 0x147F
-#define TCM825X_VGAIN 0x153F
-#define TCM825X_UGAIN 0x163F
-#define TCM825X_UVCORE 0x170F
-#define TCM825X_SATU 0x187F
-#define TCM825X_MHMODE 0x1980
-#define TCM825X_MHLPFSEL 0x1940
-#define TCM825X_YMODE 0x1930
-#define TCM825X_MIXHG 0x1907
-#define TCM825X_LENS 0x1A3F
-#define TCM825X_AGLIM 0x1BE0
-#define TCM825X_LENSRPOL 0x1B10
-#define TCM825X_LENSRGAIN 0x1B0F
-#define TCM825X_ES100S 0x1CFF
-#define TCM825X_ES120S 0x1DFF
-#define TCM825X_DMASK 0x1EC0
-#define TCM825X_CODESW 0x1E20
-#define TCM825X_CODESEL 0x1E10
-#define TCM825X_TESPIC 0x1E04
-#define TCM825X_PICSEL 0x1E03
-#define TCM825X_HNUM 0x20FF
-#define TCM825X_VOUTPH 0x287F
-#define TCM825X_ESROUT 0x327F
-#define TCM825X_ESROUT2 0x33FF
-#define TCM825X_AGOUT 0x34FF
-#define TCM825X_DGOUT 0x353F
-#define TCM825X_AGSLOW1 0x39C0
-#define TCM825X_FLLSMODE 0x3930
-#define TCM825X_FLLSLIM 0x390F
-#define TCM825X_DETSEL 0x3AF0
-#define TCM825X_ACDETNC 0x3A0F
-#define TCM825X_AGSLOW2 0x3BC0
-#define TCM825X_DG 0x3B3F
-#define TCM825X_REJHLEV 0x3CFF
-#define TCM825X_ALCLOCK 0x3D80
-#define TCM825X_FPSLNKSW 0x3D40
-#define TCM825X_ALCSPD 0x3D30
-#define TCM825X_REJH 0x3D03
-#define TCM825X_SHESRSW 0x3E80
-#define TCM825X_ESLIMSEL 0x3E40
-#define TCM825X_SHESRSPD 0x3E30
-#define TCM825X_ELSTEP 0x3E0C
-#define TCM825X_ELSTART 0x3E03
-#define TCM825X_AGMIN 0x3FFF
-#define TCM825X_PREGRG 0x423F
-#define TCM825X_PREGBG 0x433F
-#define TCM825X_PRERG 0x443F
-#define TCM825X_PREBG 0x453F
-#define TCM825X_MSKBR 0x477F
-#define TCM825X_MSKGR 0x487F
-#define TCM825X_MSKRB 0x497F
-#define TCM825X_MSKGB 0x4A7F
-#define TCM825X_MSKRG 0x4B7F
-#define TCM825X_MSKBG 0x4C7F
-#define TCM825X_HDTCSW 0x4D80
-#define TCM825X_VDTCSW 0x4D40
-#define TCM825X_DTCYL 0x4D3F
-#define TCM825X_HDTPSW 0x4E80
-#define TCM825X_VDTPSW 0x4E40
-#define TCM825X_DTCGAIN 0x4E3F
-#define TCM825X_DTLLIMSW 0x4F10
-#define TCM825X_DTLYLIM 0x4F0F
-#define TCM825X_YLCUTLMSK 0x5080
-#define TCM825X_YLCUTL 0x503F
-#define TCM825X_YLCUTHMSK 0x5180
-#define TCM825X_YLCUTH 0x513F
-#define TCM825X_UVSKNC 0x527F
-#define TCM825X_UVLJ 0x537F
-#define TCM825X_WBGMIN 0x54FF
-#define TCM825X_WBGMAX 0x55FF
-#define TCM825X_WBSPDUP 0x5603
-#define TCM825X_ALLAREA 0x5820
-#define TCM825X_WBLOCK 0x5810
-#define TCM825X_WB2SP 0x580F
-#define TCM825X_KIZUSW 0x5920
-#define TCM825X_PBRSW 0x5910
-#define TCM825X_ABCSW 0x5903
-#define TCM825X_PBDLV 0x5AFF
-#define TCM825X_PBC1LV 0x5BFF
-
-#define TCM825X_NUM_REGS (TCM825X_ADDR(TCM825X_PBC1LV) + 1)
-
-#define TCM825X_BYTES_PER_PIXEL 2
-
-#define TCM825X_REG_TERM 0xff /* terminating list entry for reg */
-#define TCM825X_VAL_TERM 0xff /* terminating list entry for val */
-
-/* define a structure for tcm825x register initialization values */
-struct tcm825x_reg {
- u8 val;
- u16 reg;
-};
-
-enum image_size { subQCIF = 0, QQVGA, QCIF, QVGA, CIF, VGA };
-enum pixel_format { YUV422 = 0, RGB565 };
-#define NUM_IMAGE_SIZES 6
-#define NUM_PIXEL_FORMATS 2
-
-#define TCM825X_XCLK_MIN 11900000
-#define TCM825X_XCLK_MAX 25000000
-
-struct capture_size {
- unsigned long width;
- unsigned long height;
-};
-
-struct tcm825x_platform_data {
- /* Is the sensor usable? Doesn't yet mean it's there, but you
- * can try! */
- int (*is_okay)(void);
- /* Set power state, zero is off, non-zero is on. */
- int (*power_set)(int power);
- /* Default registers written after power-on or reset. */
- const struct tcm825x_reg *(*default_regs)(void);
- int (*needs_reset)(struct v4l2_int_device *s, void *buf,
- struct v4l2_pix_format *fmt);
- int (*ifparm)(struct v4l2_ifparm *p);
- int (*is_upside_down)(void);
-};
-
-/* Array of image sizes supported by TCM825X. These must be ordered from
- * smallest image size to largest.
- */
-static const struct capture_size tcm825x_sizes[] = {
- { 128, 96 }, /* subQCIF */
- { 160, 120 }, /* QQVGA */
- { 176, 144 }, /* QCIF */
- { 320, 240 }, /* QVGA */
- { 352, 288 }, /* CIF */
- { 640, 480 }, /* VGA */
-};
-
-#endif /* ifndef TCM825X_H */
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
deleted file mode 100644
index f7707e65761..00000000000
--- a/drivers/media/video/tda7432.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * For the STS-Thompson TDA7432 audio processor chip
- *
- * Handles audio functions: volume, balance, tone, loudness
- * This driver will not complain if used with any
- * other i2c device with the same address.
- *
- * Muting and tone control by Jonathan Isom <jisom@ematic.com>
- *
- * Copyright (c) 2000 Eric Sandeen <eric_sandeen@bigfoot.com>
- * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org>
- * This code is placed under the terms of the GNU General Public License
- * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu)
- * Which was based on tda8425.c by Greg Alexander (c) 1998
- *
- * OPTIONS:
- * debug - set to 1 if you'd like to see debug messages
- * set to 2 if you'd like to be inundated with debug messages
- *
- * loudness - set between 0 and 15 for varying degrees of loudness effect
- *
- * maxvol - set maximium volume to +20db (1), default is 0db(0)
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/i2c.h>
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/i2c-addr.h>
-
-#ifndef VIDEO_AUDIO_BALANCE
-# define VIDEO_AUDIO_BALANCE 32
-#endif
-
-MODULE_AUTHOR("Eric Sandeen <eric_sandeen@bigfoot.com>");
-MODULE_DESCRIPTION("bttv driver for the tda7432 audio processor chip");
-MODULE_LICENSE("GPL");
-
-static int maxvol;
-static int loudness; /* disable loudness by default */
-static int debug; /* insmod parameter */
-module_param(debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Set debugging level from 0 to 3. Default is off(0).");
-module_param(loudness, int, S_IRUGO);
-MODULE_PARM_DESC(loudness, "Turn loudness on(1) else off(0). Default is off(0).");
-module_param(maxvol, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(maxvol, "Set maximium volume to +20dB(0) else +0dB(1). Default is +20dB(0).");
-
-
-/* Structure of address and subaddresses for the tda7432 */
-
-struct tda7432 {
- struct v4l2_subdev sd;
- int addr;
- int input;
- int volume;
- int muted;
- int bass, treble;
- int lf, lr, rf, rr;
- int loud;
-};
-
-static inline struct tda7432 *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct tda7432, sd);
-}
-
-/* The TDA7432 is made by STS-Thompson
- * http://www.st.com
- * http://us.st.com/stonline/books/pdf/docs/4056.pdf
- *
- * TDA7432: I2C-bus controlled basic audio processor
- *
- * The TDA7432 controls basic audio functions like volume, balance,
- * and tone control (including loudness). It also has four channel
- * output (for front and rear). Since most vidcap cards probably
- * don't have 4 channel output, this driver will set front & rear
- * together (no independent control).
- */
-
- /* Subaddresses for TDA7432 */
-
-#define TDA7432_IN 0x00 /* Input select */
-#define TDA7432_VL 0x01 /* Volume */
-#define TDA7432_TN 0x02 /* Bass, Treble (Tone) */
-#define TDA7432_LF 0x03 /* Attenuation LF (Left Front) */
-#define TDA7432_LR 0x04 /* Attenuation LR (Left Rear) */
-#define TDA7432_RF 0x05 /* Attenuation RF (Right Front) */
-#define TDA7432_RR 0x06 /* Attenuation RR (Right Rear) */
-#define TDA7432_LD 0x07 /* Loudness */
-
-
- /* Masks for bits in TDA7432 subaddresses */
-
-/* Many of these not used - just for documentation */
-
-/* Subaddress 0x00 - Input selection and bass control */
-
-/* Bits 0,1,2 control input:
- * 0x00 - Stereo input
- * 0x02 - Mono input
- * 0x03 - Mute (Using Attenuators Plays better with modules)
- * Mono probably isn't used - I'm guessing only the stereo
- * input is connected on most cards, so we'll set it to stereo.
- *
- * Bit 3 controls bass cut: 0/1 is non-symmetric/symmetric bass cut
- * Bit 4 controls bass range: 0/1 is extended/standard bass range
- *
- * Highest 3 bits not used
- */
-
-#define TDA7432_STEREO_IN 0
-#define TDA7432_MONO_IN 2 /* Probably won't be used */
-#define TDA7432_BASS_SYM 1 << 3
-#define TDA7432_BASS_NORM 1 << 4
-
-/* Subaddress 0x01 - Volume */
-
-/* Lower 7 bits control volume from -79dB to +32dB in 1dB steps
- * Recommended maximum is +20 dB
- *
- * +32dB: 0x00
- * +20dB: 0x0c
- * 0dB: 0x20
- * -79dB: 0x6f
- *
- * MSB (bit 7) controls loudness: 1/0 is loudness on/off
- */
-
-#define TDA7432_VOL_0DB 0x20
-#define TDA7432_LD_ON 1 << 7
-
-
-/* Subaddress 0x02 - Tone control */
-
-/* Bits 0,1,2 control absolute treble gain from 0dB to 14dB
- * 0x0 is 14dB, 0x7 is 0dB
- *
- * Bit 3 controls treble attenuation/gain (sign)
- * 1 = gain (+)
- * 0 = attenuation (-)
- *
- * Bits 4,5,6 control absolute bass gain from 0dB to 14dB
- * (This is only true for normal base range, set in 0x00)
- * 0x0 << 4 is 14dB, 0x7 is 0dB
- *
- * Bit 7 controls bass attenuation/gain (sign)
- * 1 << 7 = gain (+)
- * 0 << 7 = attenuation (-)
- *
- * Example:
- * 1 1 0 1 0 1 0 1 is +4dB bass, -4dB treble
- */
-
-#define TDA7432_TREBLE_0DB 0xf
-#define TDA7432_TREBLE 7
-#define TDA7432_TREBLE_GAIN 1 << 3
-#define TDA7432_BASS_0DB 0xf
-#define TDA7432_BASS 7 << 4
-#define TDA7432_BASS_GAIN 1 << 7
-
-
-/* Subaddress 0x03 - Left Front attenuation */
-/* Subaddress 0x04 - Left Rear attenuation */
-/* Subaddress 0x05 - Right Front attenuation */
-/* Subaddress 0x06 - Right Rear attenuation */
-
-/* Bits 0,1,2,3,4 control attenuation from 0dB to -37.5dB
- * in 1.5dB steps.
- *
- * 0x00 is 0dB
- * 0x1f is -37.5dB
- *
- * Bit 5 mutes that channel when set (1 = mute, 0 = unmute)
- * We'll use the mute on the input, though (above)
- * Bits 6,7 unused
- */
-
-#define TDA7432_ATTEN_0DB 0x00
-#define TDA7432_MUTE 0x1 << 5
-
-
-/* Subaddress 0x07 - Loudness Control */
-
-/* Bits 0,1,2,3 control loudness from 0dB to -15dB in 1dB steps
- * when bit 4 is NOT set
- *
- * 0x0 is 0dB
- * 0xf is -15dB
- *
- * If bit 4 is set, then there is a flat attenuation according to
- * the lower 4 bits, as above.
- *
- * Bits 5,6,7 unused
- */
-
-
-
-/* Begin code */
-
-static int tda7432_write(struct v4l2_subdev *sd, int subaddr, int val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- unsigned char buffer[2];
-
- v4l2_dbg(2, debug, sd, "In tda7432_write\n");
- v4l2_dbg(1, debug, sd, "Writing %d 0x%x\n", subaddr, val);
- buffer[0] = subaddr;
- buffer[1] = val;
- if (2 != i2c_master_send(client, buffer, 2)) {
- v4l2_err(sd, "I/O error, trying (write %d 0x%x)\n",
- subaddr, val);
- return -1;
- }
- return 0;
-}
-
-static int tda7432_set(struct v4l2_subdev *sd)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tda7432 *t = to_state(sd);
- unsigned char buf[16];
-
- v4l2_dbg(1, debug, sd,
- "tda7432: 7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n",
- t->input, t->volume, t->bass, t->treble, t->lf, t->lr,
- t->rf, t->rr, t->loud);
- buf[0] = TDA7432_IN;
- buf[1] = t->input;
- buf[2] = t->volume;
- buf[3] = t->bass;
- buf[4] = t->treble;
- buf[5] = t->lf;
- buf[6] = t->lr;
- buf[7] = t->rf;
- buf[8] = t->rr;
- buf[9] = t->loud;
- if (10 != i2c_master_send(client, buf, 10)) {
- v4l2_err(sd, "I/O error, trying tda7432_set\n");
- return -1;
- }
-
- return 0;
-}
-
-static void do_tda7432_init(struct v4l2_subdev *sd)
-{
- struct tda7432 *t = to_state(sd);
-
- v4l2_dbg(2, debug, sd, "In tda7432_init\n");
-
- t->input = TDA7432_STEREO_IN | /* Main (stereo) input */
- TDA7432_BASS_SYM | /* Symmetric bass cut */
- TDA7432_BASS_NORM; /* Normal bass range */
- t->volume = 0x3b ; /* -27dB Volume */
- if (loudness) /* Turn loudness on? */
- t->volume |= TDA7432_LD_ON;
- t->muted = 1;
- t->treble = TDA7432_TREBLE_0DB; /* 0dB Treble */
- t->bass = TDA7432_BASS_0DB; /* 0dB Bass */
- t->lf = TDA7432_ATTEN_0DB; /* 0dB attenuation */
- t->lr = TDA7432_ATTEN_0DB; /* 0dB attenuation */
- t->rf = TDA7432_ATTEN_0DB; /* 0dB attenuation */
- t->rr = TDA7432_ATTEN_0DB; /* 0dB attenuation */
- t->loud = loudness; /* insmod parameter */
-
- tda7432_set(sd);
-}
-
-static int tda7432_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- struct tda7432 *t = to_state(sd);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=t->muted;
- return 0;
- case V4L2_CID_AUDIO_VOLUME:
- if (!maxvol){ /* max +20db */
- ctrl->value = ( 0x6f - (t->volume & 0x7F) ) * 630;
- } else { /* max 0db */
- ctrl->value = ( 0x6f - (t->volume & 0x7F) ) * 829;
- }
- return 0;
- case V4L2_CID_AUDIO_BALANCE:
- {
- if ( (t->lf) < (t->rf) )
- /* right is attenuated, balance shifted left */
- ctrl->value = (32768 - 1057*(t->rf));
- else
- /* left is attenuated, balance shifted right */
- ctrl->value = (32768 + 1057*(t->lf));
- return 0;
- }
- case V4L2_CID_AUDIO_BASS:
- {
- /* Bass/treble 4 bits each */
- int bass=t->bass;
- if(bass >= 0x8)
- bass = ~(bass - 0x8) & 0xf;
- ctrl->value = (bass << 12)+(bass << 8)+(bass << 4)+(bass);
- return 0;
- }
- case V4L2_CID_AUDIO_TREBLE:
- {
- int treble=t->treble;
- if(treble >= 0x8)
- treble = ~(treble - 0x8) & 0xf;
- ctrl->value = (treble << 12)+(treble << 8)+(treble << 4)+(treble);
- return 0;
- }
- }
- return -EINVAL;
-}
-
-static int tda7432_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- struct tda7432 *t = to_state(sd);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- t->muted=ctrl->value;
- break;
- case V4L2_CID_AUDIO_VOLUME:
- if(!maxvol){ /* max +20db */
- t->volume = 0x6f - ((ctrl->value)/630);
- } else { /* max 0db */
- t->volume = 0x6f - ((ctrl->value)/829);
- }
- if (loudness) /* Turn on the loudness bit */
- t->volume |= TDA7432_LD_ON;
-
- tda7432_write(sd, TDA7432_VL, t->volume);
- return 0;
- case V4L2_CID_AUDIO_BALANCE:
- if (ctrl->value < 32768) {
- /* shifted to left, attenuate right */
- t->rr = (32768 - ctrl->value)/1057;
- t->rf = t->rr;
- t->lr = TDA7432_ATTEN_0DB;
- t->lf = TDA7432_ATTEN_0DB;
- } else if(ctrl->value > 32769) {
- /* shifted to right, attenuate left */
- t->lf = (ctrl->value - 32768)/1057;
- t->lr = t->lf;
- t->rr = TDA7432_ATTEN_0DB;
- t->rf = TDA7432_ATTEN_0DB;
- } else {
- /* centered */
- t->rr = TDA7432_ATTEN_0DB;
- t->rf = TDA7432_ATTEN_0DB;
- t->lf = TDA7432_ATTEN_0DB;
- t->lr = TDA7432_ATTEN_0DB;
- }
- break;
- case V4L2_CID_AUDIO_BASS:
- t->bass = ctrl->value >> 12;
- if(t->bass>= 0x8)
- t->bass = (~t->bass & 0xf) + 0x8 ;
-
- tda7432_write(sd, TDA7432_TN, 0x10 | (t->bass << 4) | t->treble);
- return 0;
- case V4L2_CID_AUDIO_TREBLE:
- t->treble= ctrl->value >> 12;
- if(t->treble>= 0x8)
- t->treble = (~t->treble & 0xf) + 0x8 ;
-
- tda7432_write(sd, TDA7432_TN, 0x10 | (t->bass << 4) | t->treble);
- return 0;
- default:
- return -EINVAL;
- }
-
- /* Used for both mute and balance changes */
- if (t->muted)
- {
- /* Mute & update balance*/
- tda7432_write(sd, TDA7432_LF, t->lf | TDA7432_MUTE);
- tda7432_write(sd, TDA7432_LR, t->lr | TDA7432_MUTE);
- tda7432_write(sd, TDA7432_RF, t->rf | TDA7432_MUTE);
- tda7432_write(sd, TDA7432_RR, t->rr | TDA7432_MUTE);
- } else {
- tda7432_write(sd, TDA7432_LF, t->lf);
- tda7432_write(sd, TDA7432_LR, t->lr);
- tda7432_write(sd, TDA7432_RF, t->rf);
- tda7432_write(sd, TDA7432_RR, t->rr);
- }
- return 0;
-}
-
-static int tda7432_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
-{
- switch (qc->id) {
- case V4L2_CID_AUDIO_VOLUME:
- return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
- case V4L2_CID_AUDIO_MUTE:
- return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
- case V4L2_CID_AUDIO_BALANCE:
- case V4L2_CID_AUDIO_BASS:
- case V4L2_CID_AUDIO_TREBLE:
- return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
- }
- return -EINVAL;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops tda7432_core_ops = {
- .queryctrl = tda7432_queryctrl,
- .g_ctrl = tda7432_g_ctrl,
- .s_ctrl = tda7432_s_ctrl,
-};
-
-static const struct v4l2_subdev_ops tda7432_ops = {
- .core = &tda7432_core_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-/* *********************** *
- * i2c interface functions *
- * *********************** */
-
-static int tda7432_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct tda7432 *t;
- struct v4l2_subdev *sd;
-
- v4l_info(client, "chip found @ 0x%02x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- t = kzalloc(sizeof(*t), GFP_KERNEL);
- if (!t)
- return -ENOMEM;
- sd = &t->sd;
- v4l2_i2c_subdev_init(sd, client, &tda7432_ops);
- if (loudness < 0 || loudness > 15) {
- v4l2_warn(sd, "loudness parameter must be between 0 and 15\n");
- if (loudness < 0)
- loudness = 0;
- if (loudness > 15)
- loudness = 15;
- }
-
- do_tda7432_init(sd);
- return 0;
-}
-
-static int tda7432_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- do_tda7432_init(sd);
- v4l2_device_unregister_subdev(sd);
- kfree(to_state(sd));
- return 0;
-}
-
-static const struct i2c_device_id tda7432_id[] = {
- { "tda7432", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tda7432_id);
-
-static struct i2c_driver tda7432_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "tda7432",
- },
- .probe = tda7432_probe,
- .remove = tda7432_remove,
- .id_table = tda7432_id,
-};
-
-module_i2c_driver(tda7432_driver);
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
deleted file mode 100644
index 3d7ddd93282..00000000000
--- a/drivers/media/video/tda9840.c
+++ /dev/null
@@ -1,224 +0,0 @@
- /*
- tda9840 - i2c-driver for the tda9840 by SGS Thomson
-
- Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
- Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
-
- The tda9840 is a stereo/dual sound processor with digital
- identification. It can be found at address 0x84 on the i2c-bus.
-
- For detailed informations download the specifications directly
- from SGS Thomson at http://www.st.com
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include <linux/module.h>
-#include <linux/ioctl.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-
-MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
-MODULE_DESCRIPTION("tda9840 driver");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0644);
-
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-#define SWITCH 0x00
-#define LEVEL_ADJUST 0x02
-#define STEREO_ADJUST 0x03
-#define TEST 0x04
-
-#define TDA9840_SET_MUTE 0x00
-#define TDA9840_SET_MONO 0x10
-#define TDA9840_SET_STEREO 0x2a
-#define TDA9840_SET_LANG1 0x12
-#define TDA9840_SET_LANG2 0x1e
-#define TDA9840_SET_BOTH 0x1a
-#define TDA9840_SET_BOTH_R 0x16
-#define TDA9840_SET_EXTERNAL 0x7a
-
-
-static void tda9840_write(struct v4l2_subdev *sd, u8 reg, u8 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (i2c_smbus_write_byte_data(client, reg, val))
- v4l2_dbg(1, debug, sd, "error writing %02x to %02x\n",
- val, reg);
-}
-
-static int tda9840_status(struct v4l2_subdev *sd)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 byte;
-
- if (1 != i2c_master_recv(client, &byte, 1)) {
- v4l2_dbg(1, debug, sd,
- "i2c_master_recv() failed\n");
- return -EIO;
- }
-
- if (byte & 0x80) {
- v4l2_dbg(1, debug, sd,
- "TDA9840_DETECT: register contents invalid\n");
- return -EINVAL;
- }
-
- v4l2_dbg(1, debug, sd, "TDA9840_DETECT: byte: 0x%02x\n", byte);
- return byte & 0x60;
-}
-
-static int tda9840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
-{
- int stat = tda9840_status(sd);
- int byte;
-
- if (t->index)
- return -EINVAL;
-
- stat = stat < 0 ? 0 : stat;
- if (stat == 0 || stat == 0x60) /* mono input */
- byte = TDA9840_SET_MONO;
- else if (stat == 0x40) /* stereo input */
- byte = (t->audmode == V4L2_TUNER_MODE_MONO) ?
- TDA9840_SET_MONO : TDA9840_SET_STEREO;
- else { /* bilingual */
- switch (t->audmode) {
- case V4L2_TUNER_MODE_LANG1_LANG2:
- byte = TDA9840_SET_BOTH;
- break;
- case V4L2_TUNER_MODE_LANG2:
- byte = TDA9840_SET_LANG2;
- break;
- default:
- byte = TDA9840_SET_LANG1;
- break;
- }
- }
- v4l2_dbg(1, debug, sd, "TDA9840_SWITCH: 0x%02x\n", byte);
- tda9840_write(sd, SWITCH, byte);
- return 0;
-}
-
-static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
-{
- int stat = tda9840_status(sd);
-
- if (stat < 0)
- return stat;
-
- t->rxsubchans = V4L2_TUNER_SUB_MONO;
-
- switch (stat & 0x60) {
- case 0x00:
- t->rxsubchans = V4L2_TUNER_SUB_MONO;
- break;
- case 0x20:
- t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- break;
- case 0x40:
- t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
- break;
- default: /* Incorrect detect */
- t->rxsubchans = V4L2_TUNER_MODE_MONO;
- break;
- }
- return 0;
-}
-
-static int tda9840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TDA9840, 0);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops tda9840_core_ops = {
- .g_chip_ident = tda9840_g_chip_ident,
-};
-
-static const struct v4l2_subdev_tuner_ops tda9840_tuner_ops = {
- .s_tuner = tda9840_s_tuner,
- .g_tuner = tda9840_g_tuner,
-};
-
-static const struct v4l2_subdev_ops tda9840_ops = {
- .core = &tda9840_core_ops,
- .tuner = &tda9840_tuner_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int tda9840_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct v4l2_subdev *sd;
-
- /* let's see whether this adapter can support what we need */
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_READ_BYTE_DATA |
- I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
- return -EIO;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
- if (sd == NULL)
- return -ENOMEM;
- v4l2_i2c_subdev_init(sd, client, &tda9840_ops);
-
- /* set initial values for level & stereo - adjustment, mode */
- tda9840_write(sd, LEVEL_ADJUST, 0);
- tda9840_write(sd, STEREO_ADJUST, 0);
- tda9840_write(sd, SWITCH, TDA9840_SET_STEREO);
- return 0;
-}
-
-static int tda9840_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(sd);
- return 0;
-}
-
-static const struct i2c_device_id tda9840_id[] = {
- { "tda9840", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tda9840_id);
-
-static struct i2c_driver tda9840_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "tda9840",
- },
- .probe = tda9840_probe,
- .remove = tda9840_remove,
- .id_table = tda9840_id,
-};
-
-module_i2c_driver(tda9840_driver);
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
deleted file mode 100644
index d1d6ea1dd27..00000000000
--- a/drivers/media/video/tea6415c.c
+++ /dev/null
@@ -1,187 +0,0 @@
- /*
- tea6415c - i2c-driver for the tea6415c by SGS Thomson
-
- Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
- Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
-
- The tea6415c is a bus controlled video-matrix-switch
- with 8 inputs and 6 outputs.
- It is cascadable, i.e. it can be found at the addresses
- 0x86 and 0x06 on the i2c-bus.
-
- For detailed informations download the specifications directly
- from SGS Thomson at http://www.st.com
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License vs published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mvss Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include <linux/module.h>
-#include <linux/ioctl.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include "tea6415c.h"
-
-MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
-MODULE_DESCRIPTION("tea6415c driver");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0644);
-
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-
-/* makes a connection between the input-pin 'i' and the output-pin 'o' */
-static int tea6415c_s_routing(struct v4l2_subdev *sd,
- u32 i, u32 o, u32 config)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 byte = 0;
- int ret;
-
- v4l2_dbg(1, debug, sd, "i=%d, o=%d\n", i, o);
-
- /* check if the pins are valid */
- if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i)
- && (18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o)))
- return -EINVAL;
-
- /* to understand this, have a look at the tea6415c-specs (p.5) */
- switch (o) {
- case 18:
- byte = 0x00;
- break;
- case 14:
- byte = 0x20;
- break;
- case 16:
- byte = 0x10;
- break;
- case 17:
- byte = 0x08;
- break;
- case 15:
- byte = 0x18;
- break;
- case 13:
- byte = 0x28;
- break;
- };
-
- switch (i) {
- case 5:
- byte |= 0x00;
- break;
- case 8:
- byte |= 0x04;
- break;
- case 3:
- byte |= 0x02;
- break;
- case 20:
- byte |= 0x06;
- break;
- case 6:
- byte |= 0x01;
- break;
- case 10:
- byte |= 0x05;
- break;
- case 1:
- byte |= 0x03;
- break;
- case 11:
- byte |= 0x07;
- break;
- };
-
- ret = i2c_smbus_write_byte(client, byte);
- if (ret) {
- v4l2_dbg(1, debug, sd,
- "i2c_smbus_write_byte() failed, ret:%d\n", ret);
- return -EIO;
- }
- return ret;
-}
-
-static int tea6415c_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6415C, 0);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops tea6415c_core_ops = {
- .g_chip_ident = tea6415c_g_chip_ident,
-};
-
-static const struct v4l2_subdev_video_ops tea6415c_video_ops = {
- .s_routing = tea6415c_s_routing,
-};
-
-static const struct v4l2_subdev_ops tea6415c_ops = {
- .core = &tea6415c_core_ops,
- .video = &tea6415c_video_ops,
-};
-
-static int tea6415c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct v4l2_subdev *sd;
-
- /* let's see whether this adapter can support what we need */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE))
- return -EIO;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
- sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
- if (sd == NULL)
- return -ENOMEM;
- v4l2_i2c_subdev_init(sd, client, &tea6415c_ops);
- return 0;
-}
-
-static int tea6415c_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(sd);
- return 0;
-}
-
-static const struct i2c_device_id tea6415c_id[] = {
- { "tea6415c", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tea6415c_id);
-
-static struct i2c_driver tea6415c_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "tea6415c",
- },
- .probe = tea6415c_probe,
- .remove = tea6415c_remove,
- .id_table = tea6415c_id,
-};
-
-module_i2c_driver(tea6415c_driver);
diff --git a/drivers/media/video/tea6415c.h b/drivers/media/video/tea6415c.h
deleted file mode 100644
index 3a47d697536..00000000000
--- a/drivers/media/video/tea6415c.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef __INCLUDED_TEA6415C__
-#define __INCLUDED_TEA6415C__
-
-/* the tea6415c's design is quite brain-dead. although there are
- 8 inputs and 6 outputs, these aren't enumerated in any way. because
- I don't want to say "connect input pin 20 to output pin 17", I define
- a "virtual" pin-order. */
-
-/* input pins */
-#define TEA6415C_OUTPUT1 18
-#define TEA6415C_OUTPUT2 14
-#define TEA6415C_OUTPUT3 16
-#define TEA6415C_OUTPUT4 17
-#define TEA6415C_OUTPUT5 13
-#define TEA6415C_OUTPUT6 15
-
-/* output pins */
-#define TEA6415C_INPUT1 5
-#define TEA6415C_INPUT2 8
-#define TEA6415C_INPUT3 3
-#define TEA6415C_INPUT4 20
-#define TEA6415C_INPUT5 6
-#define TEA6415C_INPUT6 10
-#define TEA6415C_INPUT7 1
-#define TEA6415C_INPUT8 11
-
-#endif
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
deleted file mode 100644
index 38757217a07..00000000000
--- a/drivers/media/video/tea6420.c
+++ /dev/null
@@ -1,169 +0,0 @@
- /*
- tea6420 - i2c-driver for the tea6420 by SGS Thomson
-
- Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
- Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
-
- The tea6420 is a bus controlled audio-matrix with 5 stereo inputs,
- 4 stereo outputs and gain control for each output.
- It is cascadable, i.e. it can be found at the addresses 0x98
- and 0x9a on the i2c-bus.
-
- For detailed informations download the specifications directly
- from SGS Thomson at http://www.st.com
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include <linux/module.h>
-#include <linux/ioctl.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include "tea6420.h"
-
-MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
-MODULE_DESCRIPTION("tea6420 driver");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0644);
-
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-
-/* make a connection between the input 'i' and the output 'o'
- with gain 'g' (note: i = 6 means 'mute') */
-static int tea6420_s_routing(struct v4l2_subdev *sd,
- u32 i, u32 o, u32 config)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int g = (o >> 4) & 0xf;
- u8 byte;
- int ret;
-
- o &= 0xf;
- v4l2_dbg(1, debug, sd, "i=%d, o=%d, g=%d\n", i, o, g);
-
- /* check if the parameters are valid */
- if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0)
- return -EINVAL;
-
- byte = ((o - 1) << 5);
- byte |= (i - 1);
-
- /* to understand this, have a look at the tea6420-specs (p.5) */
- switch (g) {
- case 0:
- byte |= (3 << 3);
- break;
- case 2:
- byte |= (2 << 3);
- break;
- case 4:
- byte |= (1 << 3);
- break;
- case 6:
- break;
- }
-
- ret = i2c_smbus_write_byte(client, byte);
- if (ret) {
- v4l2_dbg(1, debug, sd,
- "i2c_smbus_write_byte() failed, ret:%d\n", ret);
- return -EIO;
- }
- return 0;
-}
-
-static int tea6420_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6420, 0);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops tea6420_core_ops = {
- .g_chip_ident = tea6420_g_chip_ident,
-};
-
-static const struct v4l2_subdev_audio_ops tea6420_audio_ops = {
- .s_routing = tea6420_s_routing,
-};
-
-static const struct v4l2_subdev_ops tea6420_ops = {
- .core = &tea6420_core_ops,
- .audio = &tea6420_audio_ops,
-};
-
-static int tea6420_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct v4l2_subdev *sd;
- int err, i;
-
- /* let's see whether this adapter can support what we need */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE))
- return -EIO;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
- if (sd == NULL)
- return -ENOMEM;
- v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
-
- /* set initial values: set "mute"-input to all outputs at gain 0 */
- err = 0;
- for (i = 1; i < 5; i++)
- err += tea6420_s_routing(sd, 6, i, 0);
- if (err) {
- v4l_dbg(1, debug, client, "could not initialize tea6420\n");
- return -ENODEV;
- }
- return 0;
-}
-
-static int tea6420_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(sd);
- return 0;
-}
-
-static const struct i2c_device_id tea6420_id[] = {
- { "tea6420", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tea6420_id);
-
-static struct i2c_driver tea6420_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "tea6420",
- },
- .probe = tea6420_probe,
- .remove = tea6420_remove,
- .id_table = tea6420_id,
-};
-
-module_i2c_driver(tea6420_driver);
diff --git a/drivers/media/video/tea6420.h b/drivers/media/video/tea6420.h
deleted file mode 100644
index 4aa3edb3e19..00000000000
--- a/drivers/media/video/tea6420.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef __INCLUDED_TEA6420__
-#define __INCLUDED_TEA6420__
-
-/* input pins */
-#define TEA6420_OUTPUT1 1
-#define TEA6420_OUTPUT2 2
-#define TEA6420_OUTPUT3 3
-#define TEA6420_OUTPUT4 4
-
-/* output pins */
-#define TEA6420_INPUT1 1
-#define TEA6420_INPUT2 2
-#define TEA6420_INPUT3 3
-#define TEA6420_INPUT4 4
-#define TEA6420_INPUT5 5
-#define TEA6420_INPUT6 6
-
-/* gain on the output pins, ORed with the output pin */
-#define TEA6420_GAIN0 0x00
-#define TEA6420_GAIN2 0x20
-#define TEA6420_GAIN4 0x40
-#define TEA6420_GAIN6 0x60
-
-#endif
diff --git a/drivers/media/video/ths7303.c b/drivers/media/video/ths7303.c
deleted file mode 100644
index e5c0eedebc5..00000000000
--- a/drivers/media/video/ths7303.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * ths7303- THS7303 Video Amplifier driver
- *
- * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ctype.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/uaccess.h>
-#include <linux/videodev2.h>
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
-
-MODULE_DESCRIPTION("TI THS7303 video amplifier driver");
-MODULE_AUTHOR("Chaithrika U S");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level 0-1");
-
-/* following function is used to set ths7303 */
-static int ths7303_setvalue(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- int err = 0;
- u8 val;
- struct i2c_client *client;
-
- client = v4l2_get_subdevdata(sd);
-
- if (std & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) {
- val = 0x02;
- v4l2_dbg(1, debug, sd, "setting value for SDTV format\n");
- } else {
- val = 0x00;
- v4l2_dbg(1, debug, sd, "disabling all channels\n");
- }
-
- err |= i2c_smbus_write_byte_data(client, 0x01, val);
- err |= i2c_smbus_write_byte_data(client, 0x02, val);
- err |= i2c_smbus_write_byte_data(client, 0x03, val);
-
- if (err)
- v4l2_err(sd, "write failed\n");
-
- return err;
-}
-
-static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
- return ths7303_setvalue(sd, norm);
-}
-
-static int ths7303_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_THS7303, 0);
-}
-
-static const struct v4l2_subdev_video_ops ths7303_video_ops = {
- .s_std_output = ths7303_s_std_output,
-};
-
-static const struct v4l2_subdev_core_ops ths7303_core_ops = {
- .g_chip_ident = ths7303_g_chip_ident,
-};
-
-static const struct v4l2_subdev_ops ths7303_ops = {
- .core = &ths7303_core_ops,
- .video = &ths7303_video_ops,
-};
-
-static int ths7303_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct v4l2_subdev *sd;
- v4l2_std_id std_id = V4L2_STD_NTSC;
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
- if (sd == NULL)
- return -ENOMEM;
-
- v4l2_i2c_subdev_init(sd, client, &ths7303_ops);
-
- return ths7303_setvalue(sd, std_id);
-}
-
-static int ths7303_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(sd);
-
- return 0;
-}
-
-static const struct i2c_device_id ths7303_id[] = {
- {"ths7303", 0},
- {},
-};
-
-MODULE_DEVICE_TABLE(i2c, ths7303_id);
-
-static struct i2c_driver ths7303_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "ths7303",
- },
- .probe = ths7303_probe,
- .remove = ths7303_remove,
- .id_table = ths7303_id,
-};
-
-module_i2c_driver(ths7303_driver);
diff --git a/drivers/media/video/timblogiw.c b/drivers/media/video/timblogiw.c
deleted file mode 100644
index 02194c056b0..00000000000
--- a/drivers/media/video/timblogiw.c
+++ /dev/null
@@ -1,880 +0,0 @@
-/*
- * timblogiw.c timberdale FPGA LogiWin Video In driver
- * Copyright (c) 2009-2010 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* Supports:
- * Timberdale FPGA LogiWin Video In
- */
-
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/dmaengine.h>
-#include <linux/scatterlist.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/i2c.h>
-#include <linux/module.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <media/videobuf-dma-contig.h>
-#include <media/timb_video.h>
-
-#define DRIVER_NAME "timb-video"
-
-#define TIMBLOGIWIN_NAME "Timberdale Video-In"
-#define TIMBLOGIW_VERSION_CODE 0x04
-
-#define TIMBLOGIW_LINES_PER_DESC 44
-#define TIMBLOGIW_MAX_VIDEO_MEM 16
-
-#define TIMBLOGIW_HAS_DECODER(lw) (lw->pdata.encoder.module_name)
-
-
-struct timblogiw {
- struct video_device video_dev;
- struct v4l2_device v4l2_dev; /* mutual exclusion */
- struct mutex lock;
- struct device *dev;
- struct timb_video_platform_data pdata;
- struct v4l2_subdev *sd_enc; /* encoder */
- bool opened;
-};
-
-struct timblogiw_tvnorm {
- v4l2_std_id std;
- u16 width;
- u16 height;
- u8 fps;
-};
-
-struct timblogiw_fh {
- struct videobuf_queue vb_vidq;
- struct timblogiw_tvnorm const *cur_norm;
- struct list_head capture;
- struct dma_chan *chan;
- spinlock_t queue_lock; /* mutual exclusion */
- unsigned int frame_count;
-};
-
-struct timblogiw_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
- struct scatterlist sg[16];
- dma_cookie_t cookie;
- struct timblogiw_fh *fh;
-};
-
-const struct timblogiw_tvnorm timblogiw_tvnorms[] = {
- {
- .std = V4L2_STD_PAL,
- .width = 720,
- .height = 576,
- .fps = 25
- },
- {
- .std = V4L2_STD_NTSC,
- .width = 720,
- .height = 480,
- .fps = 30
- }
-};
-
-static int timblogiw_bytes_per_line(const struct timblogiw_tvnorm *norm)
-{
- return norm->width * 2;
-}
-
-
-static int timblogiw_frame_size(const struct timblogiw_tvnorm *norm)
-{
- return norm->height * timblogiw_bytes_per_line(norm);
-}
-
-static const struct timblogiw_tvnorm *timblogiw_get_norm(const v4l2_std_id std)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++)
- if (timblogiw_tvnorms[i].std & std)
- return timblogiw_tvnorms + i;
-
- /* default to first element */
- return timblogiw_tvnorms;
-}
-
-static void timblogiw_dma_cb(void *data)
-{
- struct timblogiw_buffer *buf = data;
- struct timblogiw_fh *fh = buf->fh;
- struct videobuf_buffer *vb = &buf->vb;
-
- spin_lock(&fh->queue_lock);
-
- /* mark the transfer done */
- buf->cookie = -1;
-
- fh->frame_count++;
-
- if (vb->state != VIDEOBUF_ERROR) {
- list_del(&vb->queue);
- do_gettimeofday(&vb->ts);
- vb->field_count = fh->frame_count * 2;
- vb->state = VIDEOBUF_DONE;
-
- wake_up(&vb->done);
- }
-
- if (!list_empty(&fh->capture)) {
- vb = list_entry(fh->capture.next, struct videobuf_buffer,
- queue);
- vb->state = VIDEOBUF_ACTIVE;
- }
-
- spin_unlock(&fh->queue_lock);
-}
-
-static bool timblogiw_dma_filter_fn(struct dma_chan *chan, void *filter_param)
-{
- return chan->chan_id == (uintptr_t)filter_param;
-}
-
-/* IOCTL functions */
-
-static int timblogiw_g_fmt(struct file *file, void *priv,
- struct v4l2_format *format)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw *lw = video_get_drvdata(vdev);
- struct timblogiw_fh *fh = priv;
-
- dev_dbg(&vdev->dev, "%s entry\n", __func__);
-
- if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- mutex_lock(&lw->lock);
-
- format->fmt.pix.width = fh->cur_norm->width;
- format->fmt.pix.height = fh->cur_norm->height;
- format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
- format->fmt.pix.bytesperline = timblogiw_bytes_per_line(fh->cur_norm);
- format->fmt.pix.sizeimage = timblogiw_frame_size(fh->cur_norm);
- format->fmt.pix.field = V4L2_FIELD_NONE;
-
- mutex_unlock(&lw->lock);
-
- return 0;
-}
-
-static int timblogiw_try_fmt(struct file *file, void *priv,
- struct v4l2_format *format)
-{
- struct video_device *vdev = video_devdata(file);
- struct v4l2_pix_format *pix = &format->fmt.pix;
-
- dev_dbg(&vdev->dev,
- "%s - width=%d, height=%d, pixelformat=%d, field=%d\n"
- "bytes per line %d, size image: %d, colorspace: %d\n",
- __func__,
- pix->width, pix->height, pix->pixelformat, pix->field,
- pix->bytesperline, pix->sizeimage, pix->colorspace);
-
- if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (pix->field != V4L2_FIELD_NONE)
- return -EINVAL;
-
- if (pix->pixelformat != V4L2_PIX_FMT_UYVY)
- return -EINVAL;
-
- return 0;
-}
-
-static int timblogiw_s_fmt(struct file *file, void *priv,
- struct v4l2_format *format)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw *lw = video_get_drvdata(vdev);
- struct timblogiw_fh *fh = priv;
- struct v4l2_pix_format *pix = &format->fmt.pix;
- int err;
-
- mutex_lock(&lw->lock);
-
- err = timblogiw_try_fmt(file, priv, format);
- if (err)
- goto out;
-
- if (videobuf_queue_is_busy(&fh->vb_vidq)) {
- dev_err(&vdev->dev, "%s queue busy\n", __func__);
- err = -EBUSY;
- goto out;
- }
-
- pix->width = fh->cur_norm->width;
- pix->height = fh->cur_norm->height;
-
-out:
- mutex_unlock(&lw->lock);
- return err;
-}
-
-static int timblogiw_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct video_device *vdev = video_devdata(file);
-
- dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
- memset(cap, 0, sizeof(*cap));
- strncpy(cap->card, TIMBLOGIWIN_NAME, sizeof(cap->card)-1);
- strncpy(cap->driver, DRIVER_NAME, sizeof(cap->driver) - 1);
- strlcpy(cap->bus_info, vdev->name, sizeof(cap->bus_info));
- cap->version = TIMBLOGIW_VERSION_CODE;
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
- V4L2_CAP_READWRITE;
-
- return 0;
-}
-
-static int timblogiw_enum_fmt(struct file *file, void *priv,
- struct v4l2_fmtdesc *fmt)
-{
- struct video_device *vdev = video_devdata(file);
-
- dev_dbg(&vdev->dev, "%s, index: %d\n", __func__, fmt->index);
-
- if (fmt->index != 0)
- return -EINVAL;
- memset(fmt, 0, sizeof(*fmt));
- fmt->index = 0;
- fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- strncpy(fmt->description, "4:2:2, packed, YUYV",
- sizeof(fmt->description)-1);
- fmt->pixelformat = V4L2_PIX_FMT_UYVY;
-
- return 0;
-}
-
-static int timblogiw_g_parm(struct file *file, void *priv,
- struct v4l2_streamparm *sp)
-{
- struct timblogiw_fh *fh = priv;
- struct v4l2_captureparm *cp = &sp->parm.capture;
-
- cp->capability = V4L2_CAP_TIMEPERFRAME;
- cp->timeperframe.numerator = 1;
- cp->timeperframe.denominator = fh->cur_norm->fps;
-
- return 0;
-}
-
-static int timblogiw_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *rb)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw_fh *fh = priv;
-
- dev_dbg(&vdev->dev, "%s: entry\n", __func__);
-
- return videobuf_reqbufs(&fh->vb_vidq, rb);
-}
-
-static int timblogiw_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw_fh *fh = priv;
-
- dev_dbg(&vdev->dev, "%s: entry\n", __func__);
-
- return videobuf_querybuf(&fh->vb_vidq, b);
-}
-
-static int timblogiw_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw_fh *fh = priv;
-
- dev_dbg(&vdev->dev, "%s: entry\n", __func__);
-
- return videobuf_qbuf(&fh->vb_vidq, b);
-}
-
-static int timblogiw_dqbuf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw_fh *fh = priv;
-
- dev_dbg(&vdev->dev, "%s: entry\n", __func__);
-
- return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
-}
-
-static int timblogiw_g_std(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw_fh *fh = priv;
-
- dev_dbg(&vdev->dev, "%s: entry\n", __func__);
-
- *std = fh->cur_norm->std;
- return 0;
-}
-
-static int timblogiw_s_std(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw *lw = video_get_drvdata(vdev);
- struct timblogiw_fh *fh = priv;
- int err = 0;
-
- dev_dbg(&vdev->dev, "%s: entry\n", __func__);
-
- mutex_lock(&lw->lock);
-
- if (TIMBLOGIW_HAS_DECODER(lw))
- err = v4l2_subdev_call(lw->sd_enc, core, s_std, *std);
-
- if (!err)
- fh->cur_norm = timblogiw_get_norm(*std);
-
- mutex_unlock(&lw->lock);
-
- return err;
-}
-
-static int timblogiw_enuminput(struct file *file, void *priv,
- struct v4l2_input *inp)
-{
- struct video_device *vdev = video_devdata(file);
- int i;
-
- dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
-
- if (inp->index != 0)
- return -EINVAL;
-
- inp->index = 0;
-
- strncpy(inp->name, "Timb input 1", sizeof(inp->name) - 1);
- inp->type = V4L2_INPUT_TYPE_CAMERA;
-
- inp->std = 0;
- for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++)
- inp->std |= timblogiw_tvnorms[i].std;
-
- return 0;
-}
-
-static int timblogiw_g_input(struct file *file, void *priv,
- unsigned int *input)
-{
- struct video_device *vdev = video_devdata(file);
-
- dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
-
- *input = 0;
-
- return 0;
-}
-
-static int timblogiw_s_input(struct file *file, void *priv, unsigned int input)
-{
- struct video_device *vdev = video_devdata(file);
-
- dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
-
- if (input != 0)
- return -EINVAL;
- return 0;
-}
-
-static int timblogiw_streamon(struct file *file, void *priv, unsigned int type)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw_fh *fh = priv;
-
- dev_dbg(&vdev->dev, "%s: entry\n", __func__);
-
- if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- dev_dbg(&vdev->dev, "%s - No capture device\n", __func__);
- return -EINVAL;
- }
-
- fh->frame_count = 0;
- return videobuf_streamon(&fh->vb_vidq);
-}
-
-static int timblogiw_streamoff(struct file *file, void *priv,
- unsigned int type)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw_fh *fh = priv;
-
- dev_dbg(&vdev->dev, "%s entry\n", __func__);
-
- if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- return videobuf_streamoff(&fh->vb_vidq);
-}
-
-static int timblogiw_querystd(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw *lw = video_get_drvdata(vdev);
- struct timblogiw_fh *fh = priv;
-
- dev_dbg(&vdev->dev, "%s entry\n", __func__);
-
- if (TIMBLOGIW_HAS_DECODER(lw))
- return v4l2_subdev_call(lw->sd_enc, video, querystd, std);
- else {
- *std = fh->cur_norm->std;
- return 0;
- }
-}
-
-static int timblogiw_enum_framesizes(struct file *file, void *priv,
- struct v4l2_frmsizeenum *fsize)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw_fh *fh = priv;
-
- dev_dbg(&vdev->dev, "%s - index: %d, format: %d\n", __func__,
- fsize->index, fsize->pixel_format);
-
- if ((fsize->index != 0) ||
- (fsize->pixel_format != V4L2_PIX_FMT_UYVY))
- return -EINVAL;
-
- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fsize->discrete.width = fh->cur_norm->width;
- fsize->discrete.height = fh->cur_norm->height;
-
- return 0;
-}
-
-/* Video buffer functions */
-
-static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
- unsigned int *size)
-{
- struct timblogiw_fh *fh = vq->priv_data;
-
- *size = timblogiw_frame_size(fh->cur_norm);
-
- if (!*count)
- *count = 32;
-
- while (*size * *count > TIMBLOGIW_MAX_VIDEO_MEM * 1024 * 1024)
- (*count)--;
-
- return 0;
-}
-
-static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct timblogiw_fh *fh = vq->priv_data;
- struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
- vb);
- unsigned int data_size = timblogiw_frame_size(fh->cur_norm);
- int err = 0;
-
- if (vb->baddr && vb->bsize < data_size)
- /* User provided buffer, but it is too small */
- return -ENOMEM;
-
- vb->size = data_size;
- vb->width = fh->cur_norm->width;
- vb->height = fh->cur_norm->height;
- vb->field = field;
-
- if (vb->state == VIDEOBUF_NEEDS_INIT) {
- int i;
- unsigned int size;
- unsigned int bytes_per_desc = TIMBLOGIW_LINES_PER_DESC *
- timblogiw_bytes_per_line(fh->cur_norm);
- dma_addr_t addr;
-
- sg_init_table(buf->sg, ARRAY_SIZE(buf->sg));
-
- err = videobuf_iolock(vq, vb, NULL);
- if (err)
- goto err;
-
- addr = videobuf_to_dma_contig(vb);
- for (i = 0, size = 0; size < data_size; i++) {
- sg_dma_address(buf->sg + i) = addr + size;
- size += bytes_per_desc;
- sg_dma_len(buf->sg + i) = (size > data_size) ?
- (bytes_per_desc - (size - data_size)) :
- bytes_per_desc;
- }
-
- vb->state = VIDEOBUF_PREPARED;
- buf->cookie = -1;
- buf->fh = fh;
- }
-
- return 0;
-
-err:
- videobuf_dma_contig_free(vq, vb);
- vb->state = VIDEOBUF_NEEDS_INIT;
- return err;
-}
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct timblogiw_fh *fh = vq->priv_data;
- struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
- vb);
- struct dma_async_tx_descriptor *desc;
- int sg_elems;
- int bytes_per_desc = TIMBLOGIW_LINES_PER_DESC *
- timblogiw_bytes_per_line(fh->cur_norm);
-
- sg_elems = timblogiw_frame_size(fh->cur_norm) / bytes_per_desc;
- sg_elems +=
- (timblogiw_frame_size(fh->cur_norm) % bytes_per_desc) ? 1 : 0;
-
- if (list_empty(&fh->capture))
- vb->state = VIDEOBUF_ACTIVE;
- else
- vb->state = VIDEOBUF_QUEUED;
-
- list_add_tail(&vb->queue, &fh->capture);
-
- spin_unlock_irq(&fh->queue_lock);
-
- desc = dmaengine_prep_slave_sg(fh->chan,
- buf->sg, sg_elems, DMA_DEV_TO_MEM,
- DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP);
- if (!desc) {
- spin_lock_irq(&fh->queue_lock);
- list_del_init(&vb->queue);
- vb->state = VIDEOBUF_PREPARED;
- return;
- }
-
- desc->callback_param = buf;
- desc->callback = timblogiw_dma_cb;
-
- buf->cookie = desc->tx_submit(desc);
-
- spin_lock_irq(&fh->queue_lock);
-}
-
-static void buffer_release(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct timblogiw_fh *fh = vq->priv_data;
- struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
- vb);
-
- videobuf_waiton(vq, vb, 0, 0);
- if (buf->cookie >= 0)
- dma_sync_wait(fh->chan, buf->cookie);
-
- videobuf_dma_contig_free(vq, vb);
- vb->state = VIDEOBUF_NEEDS_INIT;
-}
-
-static struct videobuf_queue_ops timblogiw_video_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-/* Device Operations functions */
-
-static int timblogiw_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw *lw = video_get_drvdata(vdev);
- struct timblogiw_fh *fh;
- v4l2_std_id std;
- dma_cap_mask_t mask;
- int err = 0;
-
- dev_dbg(&vdev->dev, "%s: entry\n", __func__);
-
- mutex_lock(&lw->lock);
- if (lw->opened) {
- err = -EBUSY;
- goto out;
- }
-
- if (TIMBLOGIW_HAS_DECODER(lw) && !lw->sd_enc) {
- struct i2c_adapter *adapt;
-
- /* find the video decoder */
- adapt = i2c_get_adapter(lw->pdata.i2c_adapter);
- if (!adapt) {
- dev_err(&vdev->dev, "No I2C bus #%d\n",
- lw->pdata.i2c_adapter);
- err = -ENODEV;
- goto out;
- }
-
- /* now find the encoder */
- lw->sd_enc = v4l2_i2c_new_subdev_board(&lw->v4l2_dev, adapt,
- lw->pdata.encoder.info, NULL);
-
- i2c_put_adapter(adapt);
-
- if (!lw->sd_enc) {
- dev_err(&vdev->dev, "Failed to get encoder: %s\n",
- lw->pdata.encoder.module_name);
- err = -ENODEV;
- goto out;
- }
- }
-
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (!fh) {
- err = -ENOMEM;
- goto out;
- }
-
- fh->cur_norm = timblogiw_tvnorms;
- timblogiw_querystd(file, fh, &std);
- fh->cur_norm = timblogiw_get_norm(std);
-
- INIT_LIST_HEAD(&fh->capture);
- spin_lock_init(&fh->queue_lock);
-
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
- dma_cap_set(DMA_PRIVATE, mask);
-
- /* find the DMA channel */
- fh->chan = dma_request_channel(mask, timblogiw_dma_filter_fn,
- (void *)(uintptr_t)lw->pdata.dma_channel);
- if (!fh->chan) {
- dev_err(&vdev->dev, "Failed to get DMA channel\n");
- kfree(fh);
- err = -ENODEV;
- goto out;
- }
-
- file->private_data = fh;
- videobuf_queue_dma_contig_init(&fh->vb_vidq,
- &timblogiw_video_qops, lw->dev, &fh->queue_lock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
- sizeof(struct timblogiw_buffer), fh, NULL);
-
- lw->opened = true;
-out:
- mutex_unlock(&lw->lock);
-
- return err;
-}
-
-static int timblogiw_close(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw *lw = video_get_drvdata(vdev);
- struct timblogiw_fh *fh = file->private_data;
-
- dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
-
- videobuf_stop(&fh->vb_vidq);
- videobuf_mmap_free(&fh->vb_vidq);
-
- dma_release_channel(fh->chan);
-
- kfree(fh);
-
- mutex_lock(&lw->lock);
- lw->opened = false;
- mutex_unlock(&lw->lock);
- return 0;
-}
-
-static ssize_t timblogiw_read(struct file *file, char __user *data,
- size_t count, loff_t *ppos)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw_fh *fh = file->private_data;
-
- dev_dbg(&vdev->dev, "%s: entry\n", __func__);
-
- return videobuf_read_stream(&fh->vb_vidq, data, count, ppos, 0,
- file->f_flags & O_NONBLOCK);
-}
-
-static unsigned int timblogiw_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw_fh *fh = file->private_data;
-
- dev_dbg(&vdev->dev, "%s: entry\n", __func__);
-
- return videobuf_poll_stream(file, &fh->vb_vidq, wait);
-}
-
-static int timblogiw_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct video_device *vdev = video_devdata(file);
- struct timblogiw_fh *fh = file->private_data;
-
- dev_dbg(&vdev->dev, "%s: entry\n", __func__);
-
- return videobuf_mmap_mapper(&fh->vb_vidq, vma);
-}
-
-/* Platform device functions */
-
-static __devinitconst struct v4l2_ioctl_ops timblogiw_ioctl_ops = {
- .vidioc_querycap = timblogiw_querycap,
- .vidioc_enum_fmt_vid_cap = timblogiw_enum_fmt,
- .vidioc_g_fmt_vid_cap = timblogiw_g_fmt,
- .vidioc_try_fmt_vid_cap = timblogiw_try_fmt,
- .vidioc_s_fmt_vid_cap = timblogiw_s_fmt,
- .vidioc_g_parm = timblogiw_g_parm,
- .vidioc_reqbufs = timblogiw_reqbufs,
- .vidioc_querybuf = timblogiw_querybuf,
- .vidioc_qbuf = timblogiw_qbuf,
- .vidioc_dqbuf = timblogiw_dqbuf,
- .vidioc_g_std = timblogiw_g_std,
- .vidioc_s_std = timblogiw_s_std,
- .vidioc_enum_input = timblogiw_enuminput,
- .vidioc_g_input = timblogiw_g_input,
- .vidioc_s_input = timblogiw_s_input,
- .vidioc_streamon = timblogiw_streamon,
- .vidioc_streamoff = timblogiw_streamoff,
- .vidioc_querystd = timblogiw_querystd,
- .vidioc_enum_framesizes = timblogiw_enum_framesizes,
-};
-
-static __devinitconst struct v4l2_file_operations timblogiw_fops = {
- .owner = THIS_MODULE,
- .open = timblogiw_open,
- .release = timblogiw_close,
- .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
- .mmap = timblogiw_mmap,
- .read = timblogiw_read,
- .poll = timblogiw_poll,
-};
-
-static __devinitconst struct video_device timblogiw_template = {
- .name = TIMBLOGIWIN_NAME,
- .fops = &timblogiw_fops,
- .ioctl_ops = &timblogiw_ioctl_ops,
- .release = video_device_release_empty,
- .minor = -1,
- .tvnorms = V4L2_STD_PAL | V4L2_STD_NTSC
-};
-
-static int __devinit timblogiw_probe(struct platform_device *pdev)
-{
- int err;
- struct timblogiw *lw = NULL;
- struct timb_video_platform_data *pdata = pdev->dev.platform_data;
-
- if (!pdata) {
- dev_err(&pdev->dev, "No platform data\n");
- err = -EINVAL;
- goto err;
- }
-
- if (!pdata->encoder.module_name)
- dev_info(&pdev->dev, "Running without decoder\n");
-
- lw = kzalloc(sizeof(*lw), GFP_KERNEL);
- if (!lw) {
- err = -ENOMEM;
- goto err;
- }
-
- if (pdev->dev.parent)
- lw->dev = pdev->dev.parent;
- else
- lw->dev = &pdev->dev;
-
- memcpy(&lw->pdata, pdata, sizeof(lw->pdata));
-
- mutex_init(&lw->lock);
-
- lw->video_dev = timblogiw_template;
-
- strlcpy(lw->v4l2_dev.name, DRIVER_NAME, sizeof(lw->v4l2_dev.name));
- err = v4l2_device_register(NULL, &lw->v4l2_dev);
- if (err)
- goto err_register;
-
- lw->video_dev.v4l2_dev = &lw->v4l2_dev;
-
- platform_set_drvdata(pdev, lw);
- video_set_drvdata(&lw->video_dev, lw);
-
- err = video_register_device(&lw->video_dev, VFL_TYPE_GRABBER, 0);
- if (err) {
- dev_err(&pdev->dev, "Error reg video: %d\n", err);
- goto err_request;
- }
-
-
- return 0;
-
-err_request:
- platform_set_drvdata(pdev, NULL);
- v4l2_device_unregister(&lw->v4l2_dev);
-err_register:
- kfree(lw);
-err:
- dev_err(&pdev->dev, "Failed to register: %d\n", err);
-
- return err;
-}
-
-static int __devexit timblogiw_remove(struct platform_device *pdev)
-{
- struct timblogiw *lw = platform_get_drvdata(pdev);
-
- video_unregister_device(&lw->video_dev);
-
- v4l2_device_unregister(&lw->v4l2_dev);
-
- kfree(lw);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-static struct platform_driver timblogiw_platform_driver = {
- .driver = {
- .name = DRIVER_NAME,
- .owner = THIS_MODULE,
- },
- .probe = timblogiw_probe,
- .remove = __devexit_p(timblogiw_remove),
-};
-
-module_platform_driver(timblogiw_platform_driver);
-
-MODULE_DESCRIPTION(TIMBLOGIWIN_NAME);
-MODULE_AUTHOR("Pelagicore AB <info@pelagicore.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:"DRIVER_NAME);
diff --git a/drivers/media/video/tlg2300/Kconfig b/drivers/media/video/tlg2300/Kconfig
deleted file mode 100644
index 645d915267e..00000000000
--- a/drivers/media/video/tlg2300/Kconfig
+++ /dev/null
@@ -1,16 +0,0 @@
-config VIDEO_TLG2300
- tristate "Telegent TLG2300 USB video capture support"
- depends on VIDEO_DEV && I2C && SND && DVB_CORE
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- depends on RC_CORE
- select VIDEOBUF_VMALLOC
- select SND_PCM
- select VIDEOBUF_DVB
-
- ---help---
- This is a video4linux driver for Telegent tlg2300 based TV cards.
- The driver supports V4L2, DVB-T and radio.
-
- To compile this driver as a module, choose M here: the
- module will be called poseidon
diff --git a/drivers/media/video/tlg2300/Makefile b/drivers/media/video/tlg2300/Makefile
deleted file mode 100644
index ea09b9af2d3..00000000000
--- a/drivers/media/video/tlg2300/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-poseidon-objs := pd-video.o pd-alsa.o pd-dvb.o pd-radio.o pd-main.o
-
-obj-$(CONFIG_VIDEO_TLG2300) += poseidon.o
-
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
-
diff --git a/drivers/media/video/tlg2300/pd-alsa.c b/drivers/media/video/tlg2300/pd-alsa.c
deleted file mode 100644
index 9f8b7da56b6..00000000000
--- a/drivers/media/video/tlg2300/pd-alsa.c
+++ /dev/null
@@ -1,332 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/usb.h>
-#include <linux/init.h>
-#include <linux/sound.h>
-#include <linux/spinlock.h>
-#include <linux/soundcard.h>
-#include <linux/vmalloc.h>
-#include <linux/proc_fs.h>
-#include <linux/module.h>
-#include <linux/gfp.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/info.h>
-#include <sound/initval.h>
-#include <sound/control.h>
-#include <media/v4l2-common.h>
-#include "pd-common.h"
-#include "vendorcmds.h"
-
-static void complete_handler_audio(struct urb *urb);
-#define AUDIO_EP (0x83)
-#define AUDIO_BUF_SIZE (512)
-#define PERIOD_SIZE (1024 * 8)
-#define PERIOD_MIN (4)
-#define PERIOD_MAX PERIOD_MIN
-
-static struct snd_pcm_hardware snd_pd_hw_capture = {
- .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID,
-
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_48000,
-
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = PERIOD_SIZE * PERIOD_MIN,
- .period_bytes_min = PERIOD_SIZE,
- .period_bytes_max = PERIOD_SIZE,
- .periods_min = PERIOD_MIN,
- .periods_max = PERIOD_MAX,
- /*
- .buffer_bytes_max = 62720 * 8,
- .period_bytes_min = 64,
- .period_bytes_max = 12544,
- .periods_min = 2,
- .periods_max = 98
- */
-};
-
-static int snd_pd_capture_open(struct snd_pcm_substream *substream)
-{
- struct poseidon *p = snd_pcm_substream_chip(substream);
- struct poseidon_audio *pa = &p->audio;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (!p)
- return -ENODEV;
- pa->users++;
- pa->card_close = 0;
- pa->capture_pcm_substream = substream;
- runtime->private_data = p;
-
- runtime->hw = snd_pd_hw_capture;
- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- usb_autopm_get_interface(p->interface);
- kref_get(&p->kref);
- return 0;
-}
-
-static int snd_pd_pcm_close(struct snd_pcm_substream *substream)
-{
- struct poseidon *p = snd_pcm_substream_chip(substream);
- struct poseidon_audio *pa = &p->audio;
-
- pa->users--;
- pa->card_close = 1;
- usb_autopm_put_interface(p->interface);
- kref_put(&p->kref, poseidon_delete);
- return 0;
-}
-
-static int snd_pd_hw_capture_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int size;
-
- size = params_buffer_bytes(hw_params);
- if (runtime->dma_area) {
- if (runtime->dma_bytes > size)
- return 0;
- vfree(runtime->dma_area);
- }
- runtime->dma_area = vmalloc(size);
- if (!runtime->dma_area)
- return -ENOMEM;
- else
- runtime->dma_bytes = size;
- return 0;
-}
-
-static int audio_buf_free(struct poseidon *p)
-{
- struct poseidon_audio *pa = &p->audio;
- int i;
-
- for (i = 0; i < AUDIO_BUFS; i++)
- if (pa->urb_array[i])
- usb_kill_urb(pa->urb_array[i]);
- free_all_urb_generic(pa->urb_array, AUDIO_BUFS);
- logpm();
- return 0;
-}
-
-static int snd_pd_hw_capture_free(struct snd_pcm_substream *substream)
-{
- struct poseidon *p = snd_pcm_substream_chip(substream);
-
- logpm();
- audio_buf_free(p);
- return 0;
-}
-
-static int snd_pd_prepare(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-#define AUDIO_TRAILER_SIZE (16)
-static inline void handle_audio_data(struct urb *urb, int *period_elapsed)
-{
- struct poseidon_audio *pa = urb->context;
- struct snd_pcm_runtime *runtime = pa->capture_pcm_substream->runtime;
-
- int stride = runtime->frame_bits >> 3;
- int len = urb->actual_length / stride;
- unsigned char *cp = urb->transfer_buffer;
- unsigned int oldptr = pa->rcv_position;
-
- if (urb->actual_length == AUDIO_BUF_SIZE - 4)
- len -= (AUDIO_TRAILER_SIZE / stride);
-
- /* do the copy */
- if (oldptr + len >= runtime->buffer_size) {
- unsigned int cnt = runtime->buffer_size - oldptr;
-
- memcpy(runtime->dma_area + oldptr * stride, cp, cnt * stride);
- memcpy(runtime->dma_area, (cp + cnt * stride),
- (len * stride - cnt * stride));
- } else
- memcpy(runtime->dma_area + oldptr * stride, cp, len * stride);
-
- /* update the statas */
- snd_pcm_stream_lock(pa->capture_pcm_substream);
- pa->rcv_position += len;
- if (pa->rcv_position >= runtime->buffer_size)
- pa->rcv_position -= runtime->buffer_size;
-
- pa->copied_position += (len);
- if (pa->copied_position >= runtime->period_size) {
- pa->copied_position -= runtime->period_size;
- *period_elapsed = 1;
- }
- snd_pcm_stream_unlock(pa->capture_pcm_substream);
-}
-
-static void complete_handler_audio(struct urb *urb)
-{
- struct poseidon_audio *pa = urb->context;
- struct snd_pcm_substream *substream = pa->capture_pcm_substream;
- int period_elapsed = 0;
- int ret;
-
- if (1 == pa->card_close || pa->capture_stream != STREAM_ON)
- return;
-
- if (urb->status != 0) {
- /*if (urb->status == -ESHUTDOWN)*/
- return;
- }
-
- if (substream) {
- if (urb->actual_length) {
- handle_audio_data(urb, &period_elapsed);
- if (period_elapsed)
- snd_pcm_period_elapsed(substream);
- }
- }
-
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0)
- log("audio urb failed (errcod = %i)", ret);
- return;
-}
-
-static int fire_audio_urb(struct poseidon *p)
-{
- int i, ret = 0;
- struct poseidon_audio *pa = &p->audio;
-
- alloc_bulk_urbs_generic(pa->urb_array, AUDIO_BUFS,
- p->udev, AUDIO_EP,
- AUDIO_BUF_SIZE, GFP_ATOMIC,
- complete_handler_audio, pa);
-
- for (i = 0; i < AUDIO_BUFS; i++) {
- ret = usb_submit_urb(pa->urb_array[i], GFP_KERNEL);
- if (ret)
- log("urb err : %d", ret);
- }
- log();
- return ret;
-}
-
-static int snd_pd_capture_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct poseidon *p = snd_pcm_substream_chip(substream);
- struct poseidon_audio *pa = &p->audio;
-
- if (debug_mode)
- log("cmd %d, audio stat : %d\n", cmd, pa->capture_stream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_START:
- if (pa->capture_stream == STREAM_ON)
- return 0;
-
- pa->rcv_position = pa->copied_position = 0;
- pa->capture_stream = STREAM_ON;
-
- if (in_hibernation(p))
- return 0;
- fire_audio_urb(p);
- return 0;
-
- case SNDRV_PCM_TRIGGER_SUSPEND:
- pa->capture_stream = STREAM_SUSPEND;
- return 0;
- case SNDRV_PCM_TRIGGER_STOP:
- pa->capture_stream = STREAM_OFF;
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static snd_pcm_uframes_t
-snd_pd_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct poseidon *p = snd_pcm_substream_chip(substream);
- struct poseidon_audio *pa = &p->audio;
- return pa->rcv_position;
-}
-
-static struct page *snd_pcm_pd_get_page(struct snd_pcm_substream *subs,
- unsigned long offset)
-{
- void *pageptr = subs->runtime->dma_area + offset;
- return vmalloc_to_page(pageptr);
-}
-
-static struct snd_pcm_ops pcm_capture_ops = {
- .open = snd_pd_capture_open,
- .close = snd_pd_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_pd_hw_capture_params,
- .hw_free = snd_pd_hw_capture_free,
- .prepare = snd_pd_prepare,
- .trigger = snd_pd_capture_trigger,
- .pointer = snd_pd_capture_pointer,
- .page = snd_pcm_pd_get_page,
-};
-
-#ifdef CONFIG_PM
-int pm_alsa_suspend(struct poseidon *p)
-{
- logpm(p);
- audio_buf_free(p);
- return 0;
-}
-
-int pm_alsa_resume(struct poseidon *p)
-{
- logpm(p);
- fire_audio_urb(p);
- return 0;
-}
-#endif
-
-int poseidon_audio_init(struct poseidon *p)
-{
- struct poseidon_audio *pa = &p->audio;
- struct snd_card *card;
- struct snd_pcm *pcm;
- int ret;
-
- ret = snd_card_create(-1, "Telegent", THIS_MODULE, 0, &card);
- if (ret != 0)
- return ret;
-
- ret = snd_pcm_new(card, "poseidon audio", 0, 0, 1, &pcm);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
- pcm->info_flags = 0;
- pcm->private_data = p;
- strcpy(pcm->name, "poseidon audio capture");
-
- strcpy(card->driver, "ALSA driver");
- strcpy(card->shortname, "poseidon Audio");
- strcpy(card->longname, "poseidon ALSA Audio");
-
- if (snd_card_register(card)) {
- snd_card_free(card);
- return -ENOMEM;
- }
- pa->card = card;
- return 0;
-}
-
-int poseidon_audio_free(struct poseidon *p)
-{
- struct poseidon_audio *pa = &p->audio;
-
- if (pa->card)
- snd_card_free(pa->card);
- return 0;
-}
diff --git a/drivers/media/video/tlg2300/pd-common.h b/drivers/media/video/tlg2300/pd-common.h
deleted file mode 100644
index 5dd73b7857d..00000000000
--- a/drivers/media/video/tlg2300/pd-common.h
+++ /dev/null
@@ -1,281 +0,0 @@
-#ifndef PD_COMMON_H
-#define PD_COMMON_H
-
-#include <linux/fs.h>
-#include <linux/wait.h>
-#include <linux/list.h>
-#include <linux/videodev2.h>
-#include <linux/semaphore.h>
-#include <linux/usb.h>
-#include <linux/poll.h>
-#include <media/videobuf-vmalloc.h>
-#include <media/v4l2-device.h>
-
-#include "dvb_frontend.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dmxdev.h"
-
-#define SBUF_NUM 8
-#define MAX_BUFFER_NUM 6
-#define PK_PER_URB 32
-#define ISO_PKT_SIZE 3072
-
-#define POSEIDON_STATE_NONE (0x0000)
-#define POSEIDON_STATE_ANALOG (0x0001)
-#define POSEIDON_STATE_FM (0x0002)
-#define POSEIDON_STATE_DVBT (0x0004)
-#define POSEIDON_STATE_VBI (0x0008)
-#define POSEIDON_STATE_DISCONNECT (0x0080)
-
-#define PM_SUSPEND_DELAY 3
-
-#define V4L_PAL_VBI_LINES 18
-#define V4L_NTSC_VBI_LINES 12
-#define V4L_PAL_VBI_FRAMESIZE (V4L_PAL_VBI_LINES * 1440 * 2)
-#define V4L_NTSC_VBI_FRAMESIZE (V4L_NTSC_VBI_LINES * 1440 * 2)
-
-#define TUNER_FREQ_MIN (45000000)
-#define TUNER_FREQ_MAX (862000000)
-
-struct vbi_data {
- struct video_device *v_dev;
- struct video_data *video;
- struct front_face *front;
-
- unsigned int copied;
- unsigned int vbi_size; /* the whole size of two fields */
- int users;
-};
-
-/*
- * This is the running context of the video, it is useful for
- * resume()
- */
-struct running_context {
- u32 freq; /* VIDIOC_S_FREQUENCY */
- int audio_idx; /* VIDIOC_S_TUNER */
- v4l2_std_id tvnormid; /* VIDIOC_S_STD */
- int sig_index; /* VIDIOC_S_INPUT */
- struct v4l2_pix_format pix; /* VIDIOC_S_FMT */
-};
-
-struct video_data {
- /* v4l2 video device */
- struct video_device *v_dev;
-
- /* the working context */
- struct running_context context;
-
- /* for data copy */
- int field_count;
-
- char *dst;
- int lines_copied;
- int prev_left;
-
- int lines_per_field;
- int lines_size;
-
- /* for communication */
- u8 endpoint_addr;
- struct urb *urb_array[SBUF_NUM];
- struct vbi_data *vbi;
- struct poseidon *pd;
- struct front_face *front;
-
- int is_streaming;
- int users;
-
- /* for bubble handler */
- struct work_struct bubble_work;
-};
-
-enum pcm_stream_state {
- STREAM_OFF,
- STREAM_ON,
- STREAM_SUSPEND,
-};
-
-#define AUDIO_BUFS (3)
-#define CAPTURE_STREAM_EN 1
-struct poseidon_audio {
- struct urb *urb_array[AUDIO_BUFS];
- unsigned int copied_position;
- struct snd_pcm_substream *capture_pcm_substream;
-
- unsigned int rcv_position;
- struct snd_card *card;
- int card_close;
-
- int users;
- int pm_state;
- enum pcm_stream_state capture_stream;
-};
-
-struct radio_data {
- __u32 fm_freq;
- int users;
- unsigned int is_radio_streaming;
- int pre_emphasis;
- struct video_device *fm_dev;
-};
-
-#define DVB_SBUF_NUM 4
-#define DVB_URB_BUF_SIZE 0x2000
-struct pd_dvb_adapter {
- struct dvb_adapter dvb_adap;
- struct dvb_frontend dvb_fe;
- struct dmxdev dmxdev;
- struct dvb_demux demux;
-
- atomic_t users;
- atomic_t active_feed;
-
- /* data transfer */
- s32 is_streaming;
- struct urb *urb_array[DVB_SBUF_NUM];
- struct poseidon *pd_device;
- u8 ep_addr;
- u8 reserved[3];
-
- /* data for power resume*/
- struct dtv_frontend_properties fe_param;
-
- /* for channel scanning */
- int prev_freq;
- int bandwidth;
- unsigned long last_jiffies;
-};
-
-struct front_face {
- /* use this field to distinguish VIDEO and VBI */
- enum v4l2_buf_type type;
-
- /* for host */
- struct videobuf_queue q;
-
- /* the bridge for host and device */
- struct videobuf_buffer *curr_frame;
-
- /* for device */
- spinlock_t queue_lock;
- struct list_head active;
- struct poseidon *pd;
-};
-
-struct poseidon {
- struct list_head device_list;
-
- struct mutex lock;
- struct kref kref;
-
- /* for V4L2 */
- struct v4l2_device v4l2_dev;
-
- /* hardware info */
- struct usb_device *udev;
- struct usb_interface *interface;
- int cur_transfer_mode;
-
- struct video_data video_data; /* video */
- struct vbi_data vbi_data; /* vbi */
- struct poseidon_audio audio; /* audio (alsa) */
- struct radio_data radio_data; /* FM */
- struct pd_dvb_adapter dvb_data; /* DVB */
-
- u32 state;
- struct file *file_for_stream; /* the active stream*/
-
-#ifdef CONFIG_PM
- int (*pm_suspend)(struct poseidon *);
- int (*pm_resume)(struct poseidon *);
- pm_message_t msg;
-
- struct work_struct pm_work;
- u8 portnum;
-#endif
-};
-
-struct poseidon_format {
- char *name;
- int fourcc; /* video4linux 2 */
- int depth; /* bit/pixel */
- int flags;
-};
-
-struct poseidon_tvnorm {
- v4l2_std_id v4l2_id;
- char name[12];
- u32 tlg_tvnorm;
-};
-
-/* video */
-int pd_video_init(struct poseidon *);
-void pd_video_exit(struct poseidon *);
-int stop_all_video_stream(struct poseidon *);
-
-/* alsa audio */
-int poseidon_audio_init(struct poseidon *);
-int poseidon_audio_free(struct poseidon *);
-#ifdef CONFIG_PM
-int pm_alsa_suspend(struct poseidon *);
-int pm_alsa_resume(struct poseidon *);
-#endif
-
-/* dvb */
-int pd_dvb_usb_device_init(struct poseidon *);
-void pd_dvb_usb_device_exit(struct poseidon *);
-void pd_dvb_usb_device_cleanup(struct poseidon *);
-int pd_dvb_get_adapter_num(struct pd_dvb_adapter *);
-void dvb_stop_streaming(struct pd_dvb_adapter *);
-
-/* FM */
-int poseidon_fm_init(struct poseidon *);
-int poseidon_fm_exit(struct poseidon *);
-struct video_device *vdev_init(struct poseidon *, struct video_device *);
-
-/* vendor command ops */
-int send_set_req(struct poseidon*, u8, s32, s32*);
-int send_get_req(struct poseidon*, u8, s32, void*, s32*, s32);
-s32 set_tuner_mode(struct poseidon*, unsigned char);
-
-/* bulk urb alloc/free */
-int alloc_bulk_urbs_generic(struct urb **urb_array, int num,
- struct usb_device *udev, u8 ep_addr,
- int buf_size, gfp_t gfp_flags,
- usb_complete_t complete_fn, void *context);
-void free_all_urb_generic(struct urb **urb_array, int num);
-
-/* misc */
-void poseidon_delete(struct kref *kref);
-void destroy_video_device(struct video_device **v_dev);
-extern int debug_mode;
-void set_debug_mode(struct video_device *vfd, int debug_mode);
-
-#ifdef CONFIG_PM
-#define in_hibernation(pd) (pd->msg.event == PM_EVENT_FREEZE)
-#else
-#define in_hibernation(pd) (0)
-#endif
-#define get_pm_count(p) (atomic_read(&(p)->interface->pm_usage_cnt))
-
-#define log(a, ...) printk(KERN_DEBUG "\t[ %s : %.3d ] "a"\n", \
- __func__, __LINE__, ## __VA_ARGS__)
-
-/* for power management */
-#define logpm(pd) do {\
- if (debug_mode & 0x10)\
- log();\
- } while (0)
-
-#define logs(f) do { \
- if ((debug_mode & 0x4) && \
- (f)->type == V4L2_BUF_TYPE_VBI_CAPTURE) \
- log("type : VBI");\
- \
- if ((debug_mode & 0x8) && \
- (f)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) \
- log("type : VIDEO");\
- } while (0)
-#endif
diff --git a/drivers/media/video/tlg2300/pd-dvb.c b/drivers/media/video/tlg2300/pd-dvb.c
deleted file mode 100644
index 30fcb117e89..00000000000
--- a/drivers/media/video/tlg2300/pd-dvb.c
+++ /dev/null
@@ -1,596 +0,0 @@
-#include "pd-common.h"
-#include <linux/kernel.h>
-#include <linux/usb.h>
-#include <linux/dvb/dmx.h>
-#include <linux/delay.h>
-#include <linux/gfp.h>
-
-#include "vendorcmds.h"
-#include <linux/sched.h>
-#include <linux/atomic.h>
-
-static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb);
-
-static int dvb_bandwidth[][2] = {
- { TLG_BW_8, 8000000 },
- { TLG_BW_7, 7000000 },
- { TLG_BW_6, 6000000 }
-};
-static int dvb_bandwidth_length = ARRAY_SIZE(dvb_bandwidth);
-
-static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb);
-static int poseidon_check_mode_dvbt(struct poseidon *pd)
-{
- s32 ret = 0, cmd_status = 0;
-
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ/4);
-
- ret = usb_set_interface(pd->udev, 0, BULK_ALTERNATE_IFACE);
- if (ret != 0)
- return ret;
-
- ret = set_tuner_mode(pd, TLG_MODE_CAPS_DVB_T);
- if (ret)
- return ret;
-
- /* signal source */
- ret = send_set_req(pd, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &cmd_status);
- if (ret|cmd_status)
- return ret;
-
- return 0;
-}
-
-/* acquire :
- * 1 == open
- * 0 == release
- */
-static int poseidon_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
-{
- struct poseidon *pd = fe->demodulator_priv;
- struct pd_dvb_adapter *pd_dvb;
- int ret = 0;
-
- if (!pd)
- return -ENODEV;
-
- pd_dvb = container_of(fe, struct pd_dvb_adapter, dvb_fe);
- if (acquire) {
- mutex_lock(&pd->lock);
- if (pd->state & POSEIDON_STATE_DISCONNECT) {
- ret = -ENODEV;
- goto open_out;
- }
-
- if (pd->state && !(pd->state & POSEIDON_STATE_DVBT)) {
- ret = -EBUSY;
- goto open_out;
- }
-
- usb_autopm_get_interface(pd->interface);
- if (0 == pd->state) {
- ret = poseidon_check_mode_dvbt(pd);
- if (ret < 0) {
- usb_autopm_put_interface(pd->interface);
- goto open_out;
- }
- pd->state |= POSEIDON_STATE_DVBT;
- pd_dvb->bandwidth = 0;
- pd_dvb->prev_freq = 0;
- }
- atomic_inc(&pd_dvb->users);
- kref_get(&pd->kref);
-open_out:
- mutex_unlock(&pd->lock);
- } else {
- dvb_stop_streaming(pd_dvb);
-
- if (atomic_dec_and_test(&pd_dvb->users)) {
- mutex_lock(&pd->lock);
- pd->state &= ~POSEIDON_STATE_DVBT;
- mutex_unlock(&pd->lock);
- }
- kref_put(&pd->kref, poseidon_delete);
- usb_autopm_put_interface(pd->interface);
- }
- return ret;
-}
-
-#ifdef CONFIG_PM
-static void poseidon_fe_release(struct dvb_frontend *fe)
-{
- struct poseidon *pd = fe->demodulator_priv;
-
- pd->pm_suspend = NULL;
- pd->pm_resume = NULL;
-}
-#else
-#define poseidon_fe_release NULL
-#endif
-
-static s32 poseidon_fe_sleep(struct dvb_frontend *fe)
-{
- return 0;
-}
-
-/*
- * return true if we can satisfy the conditions, else return false.
- */
-static bool check_scan_ok(__u32 freq, int bandwidth,
- struct pd_dvb_adapter *adapter)
-{
- if (bandwidth < 0)
- return false;
-
- if (adapter->prev_freq == freq
- && adapter->bandwidth == bandwidth) {
- long nl = jiffies - adapter->last_jiffies;
- unsigned int msec ;
-
- msec = jiffies_to_msecs(abs(nl));
- return msec > 15000 ? true : false;
- }
- return true;
-}
-
-/*
- * Check if the firmware delays too long for an invalid frequency.
- */
-static int fw_delay_overflow(struct pd_dvb_adapter *adapter)
-{
- long nl = jiffies - adapter->last_jiffies;
- unsigned int msec ;
-
- msec = jiffies_to_msecs(abs(nl));
- return msec > 800 ? true : false;
-}
-
-static int poseidon_set_fe(struct dvb_frontend *fe)
-{
- struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
- s32 ret = 0, cmd_status = 0;
- s32 i, bandwidth = -1;
- struct poseidon *pd = fe->demodulator_priv;
- struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
-
- if (in_hibernation(pd))
- return -EBUSY;
-
- mutex_lock(&pd->lock);
- for (i = 0; i < dvb_bandwidth_length; i++)
- if (fep->bandwidth_hz == dvb_bandwidth[i][1])
- bandwidth = dvb_bandwidth[i][0];
-
- if (check_scan_ok(fep->frequency, bandwidth, pd_dvb)) {
- ret = send_set_req(pd, TUNE_FREQ_SELECT,
- fep->frequency / 1000, &cmd_status);
- if (ret | cmd_status) {
- log("error line");
- goto front_out;
- }
-
- ret = send_set_req(pd, DVBT_BANDW_SEL,
- bandwidth, &cmd_status);
- if (ret | cmd_status) {
- log("error line");
- goto front_out;
- }
-
- ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
- if (ret | cmd_status) {
- log("error line");
- goto front_out;
- }
-
- /* save the context for future */
- memcpy(&pd_dvb->fe_param, fep, sizeof(*fep));
- pd_dvb->bandwidth = bandwidth;
- pd_dvb->prev_freq = fep->frequency;
- pd_dvb->last_jiffies = jiffies;
- }
-front_out:
- mutex_unlock(&pd->lock);
- return ret;
-}
-
-#ifdef CONFIG_PM
-static int pm_dvb_suspend(struct poseidon *pd)
-{
- struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
- dvb_stop_streaming(pd_dvb);
- dvb_urb_cleanup(pd_dvb);
- msleep(500);
- return 0;
-}
-
-static int pm_dvb_resume(struct poseidon *pd)
-{
- struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
-
- poseidon_check_mode_dvbt(pd);
- msleep(300);
- poseidon_set_fe(&pd_dvb->dvb_fe);
-
- dvb_start_streaming(pd_dvb);
- return 0;
-}
-#endif
-
-static s32 poseidon_fe_init(struct dvb_frontend *fe)
-{
- struct poseidon *pd = fe->demodulator_priv;
- struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
-
-#ifdef CONFIG_PM
- pd->pm_suspend = pm_dvb_suspend;
- pd->pm_resume = pm_dvb_resume;
-#endif
- memset(&pd_dvb->fe_param, 0,
- sizeof(struct dtv_frontend_properties));
- return 0;
-}
-
-static int poseidon_get_fe(struct dvb_frontend *fe)
-{
- struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
- struct poseidon *pd = fe->demodulator_priv;
- struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
-
- memcpy(fep, &pd_dvb->fe_param, sizeof(*fep));
- return 0;
-}
-
-static int poseidon_fe_get_tune_settings(struct dvb_frontend *fe,
- struct dvb_frontend_tune_settings *tune)
-{
- tune->min_delay_ms = 1000;
- return 0;
-}
-
-static int poseidon_read_status(struct dvb_frontend *fe, fe_status_t *stat)
-{
- struct poseidon *pd = fe->demodulator_priv;
- s32 ret = -1, cmd_status;
- struct tuner_dtv_sig_stat_s status = {};
-
- if (in_hibernation(pd))
- return -EBUSY;
- mutex_lock(&pd->lock);
-
- ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T,
- &status, &cmd_status, sizeof(status));
- if (ret | cmd_status) {
- log("get tuner status error");
- goto out;
- }
-
- if (debug_mode)
- log("P : %d, L %d, LB :%d", status.sig_present,
- status.sig_locked, status.sig_lock_busy);
-
- if (status.sig_lock_busy) {
- goto out;
- } else if (status.sig_present || status.sig_locked) {
- *stat |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER
- | FE_HAS_SYNC | FE_HAS_VITERBI;
- } else {
- if (fw_delay_overflow(&pd->dvb_data))
- *stat |= FE_TIMEDOUT;
- }
-out:
- mutex_unlock(&pd->lock);
- return ret;
-}
-
-static int poseidon_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
- struct poseidon *pd = fe->demodulator_priv;
- struct tuner_ber_rate_s tlg_ber = {};
- s32 ret = -1, cmd_status;
-
- mutex_lock(&pd->lock);
- ret = send_get_req(pd, TUNER_BER_RATE, 0,
- &tlg_ber, &cmd_status, sizeof(tlg_ber));
- if (ret | cmd_status)
- goto out;
- *ber = tlg_ber.ber_rate;
-out:
- mutex_unlock(&pd->lock);
- return ret;
-}
-
-static s32 poseidon_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
- struct poseidon *pd = fe->demodulator_priv;
- struct tuner_dtv_sig_stat_s status = {};
- s32 ret = 0, cmd_status;
-
- mutex_lock(&pd->lock);
- ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T,
- &status, &cmd_status, sizeof(status));
- if (ret | cmd_status)
- goto out;
- if ((status.sig_present || status.sig_locked) && !status.sig_strength)
- *strength = 0xFFFF;
- else
- *strength = status.sig_strength;
-out:
- mutex_unlock(&pd->lock);
- return ret;
-}
-
-static int poseidon_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
- return 0;
-}
-
-static int poseidon_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
-{
- *unc = 0;
- return 0;
-}
-
-static struct dvb_frontend_ops poseidon_frontend_ops = {
- .delsys = { SYS_DVBT },
- .info = {
- .name = "Poseidon DVB-T",
- .frequency_min = 174000000,
- .frequency_max = 862000000,
- .frequency_stepsize = 62500,/* FIXME */
- .caps = FE_CAN_INVERSION_AUTO |
- FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
- FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
- FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
- FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
- FE_CAN_GUARD_INTERVAL_AUTO |
- FE_CAN_RECOVER |
- FE_CAN_HIERARCHY_AUTO,
- },
-
- .release = poseidon_fe_release,
-
- .init = poseidon_fe_init,
- .sleep = poseidon_fe_sleep,
-
- .set_frontend = poseidon_set_fe,
- .get_frontend = poseidon_get_fe,
- .get_tune_settings = poseidon_fe_get_tune_settings,
-
- .read_status = poseidon_read_status,
- .read_ber = poseidon_read_ber,
- .read_signal_strength = poseidon_read_signal_strength,
- .read_snr = poseidon_read_snr,
- .read_ucblocks = poseidon_read_unc_blocks,
-
- .ts_bus_ctrl = poseidon_ts_bus_ctrl,
-};
-
-static void dvb_urb_irq(struct urb *urb)
-{
- struct pd_dvb_adapter *pd_dvb = urb->context;
- int len = urb->transfer_buffer_length;
- struct dvb_demux *demux = &pd_dvb->demux;
- s32 ret;
-
- if (!pd_dvb->is_streaming || urb->status) {
- if (urb->status == -EPROTO)
- goto resend;
- return;
- }
-
- if (urb->actual_length == len)
- dvb_dmx_swfilter(demux, urb->transfer_buffer, len);
- else if (urb->actual_length == len - 4) {
- int offset;
- u8 *buf = urb->transfer_buffer;
-
- /*
- * The packet size is 512,
- * last packet contains 456 bytes tsp data
- */
- for (offset = 456; offset < len; offset += 512) {
- if (!strncmp(buf + offset, "DVHS", 4)) {
- dvb_dmx_swfilter(demux, buf, offset);
- if (len > offset + 52 + 4) {
- /*16 bytes trailer + 36 bytes padding */
- buf += offset + 52;
- len -= offset + 52 + 4;
- dvb_dmx_swfilter(demux, buf, len);
- }
- break;
- }
- }
- }
-
-resend:
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret)
- log(" usb_submit_urb failed: error %d", ret);
-}
-
-static int dvb_urb_init(struct pd_dvb_adapter *pd_dvb)
-{
- if (pd_dvb->urb_array[0])
- return 0;
-
- alloc_bulk_urbs_generic(pd_dvb->urb_array, DVB_SBUF_NUM,
- pd_dvb->pd_device->udev, pd_dvb->ep_addr,
- DVB_URB_BUF_SIZE, GFP_KERNEL,
- dvb_urb_irq, pd_dvb);
- return 0;
-}
-
-static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb)
-{
- free_all_urb_generic(pd_dvb->urb_array, DVB_SBUF_NUM);
-}
-
-static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb)
-{
- struct poseidon *pd = pd_dvb->pd_device;
- int ret = 0;
-
- if (pd->state & POSEIDON_STATE_DISCONNECT)
- return -ENODEV;
-
- mutex_lock(&pd->lock);
- if (!pd_dvb->is_streaming) {
- s32 i, cmd_status = 0;
- /*
- * Once upon a time, there was a difficult bug lying here.
- * ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
- */
-
- ret = send_set_req(pd, PLAY_SERVICE, 1, &cmd_status);
- if (ret | cmd_status)
- goto out;
-
- ret = dvb_urb_init(pd_dvb);
- if (ret < 0)
- goto out;
-
- pd_dvb->is_streaming = 1;
- for (i = 0; i < DVB_SBUF_NUM; i++) {
- ret = usb_submit_urb(pd_dvb->urb_array[i],
- GFP_KERNEL);
- if (ret) {
- log(" submit urb error %d", ret);
- goto out;
- }
- }
- }
-out:
- mutex_unlock(&pd->lock);
- return ret;
-}
-
-void dvb_stop_streaming(struct pd_dvb_adapter *pd_dvb)
-{
- struct poseidon *pd = pd_dvb->pd_device;
-
- mutex_lock(&pd->lock);
- if (pd_dvb->is_streaming) {
- s32 i, ret, cmd_status = 0;
-
- pd_dvb->is_streaming = 0;
-
- for (i = 0; i < DVB_SBUF_NUM; i++)
- if (pd_dvb->urb_array[i])
- usb_kill_urb(pd_dvb->urb_array[i]);
-
- ret = send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP,
- &cmd_status);
- if (ret | cmd_status)
- log("error");
- }
- mutex_unlock(&pd->lock);
-}
-
-static int pd_start_feed(struct dvb_demux_feed *feed)
-{
- struct pd_dvb_adapter *pd_dvb = feed->demux->priv;
- int ret = 0;
-
- if (!pd_dvb)
- return -1;
- if (atomic_inc_return(&pd_dvb->active_feed) == 1)
- ret = dvb_start_streaming(pd_dvb);
- return ret;
-}
-
-static int pd_stop_feed(struct dvb_demux_feed *feed)
-{
- struct pd_dvb_adapter *pd_dvb = feed->demux->priv;
-
- if (!pd_dvb)
- return -1;
- if (atomic_dec_and_test(&pd_dvb->active_feed))
- dvb_stop_streaming(pd_dvb);
- return 0;
-}
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-int pd_dvb_usb_device_init(struct poseidon *pd)
-{
- struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
- struct dvb_demux *dvbdemux;
- int ret = 0;
-
- pd_dvb->ep_addr = 0x82;
- atomic_set(&pd_dvb->users, 0);
- atomic_set(&pd_dvb->active_feed, 0);
- pd_dvb->pd_device = pd;
-
- ret = dvb_register_adapter(&pd_dvb->dvb_adap,
- "Poseidon dvbt adapter",
- THIS_MODULE,
- NULL /* for hibernation correctly*/,
- adapter_nr);
- if (ret < 0)
- goto error1;
-
- /* register frontend */
- pd_dvb->dvb_fe.demodulator_priv = pd;
- memcpy(&pd_dvb->dvb_fe.ops, &poseidon_frontend_ops,
- sizeof(struct dvb_frontend_ops));
- ret = dvb_register_frontend(&pd_dvb->dvb_adap, &pd_dvb->dvb_fe);
- if (ret < 0)
- goto error2;
-
- /* register demux device */
- dvbdemux = &pd_dvb->demux;
- dvbdemux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
- dvbdemux->priv = pd_dvb;
- dvbdemux->feednum = dvbdemux->filternum = 64;
- dvbdemux->start_feed = pd_start_feed;
- dvbdemux->stop_feed = pd_stop_feed;
- dvbdemux->write_to_decoder = NULL;
-
- ret = dvb_dmx_init(dvbdemux);
- if (ret < 0)
- goto error3;
-
- pd_dvb->dmxdev.filternum = pd_dvb->demux.filternum;
- pd_dvb->dmxdev.demux = &pd_dvb->demux.dmx;
- pd_dvb->dmxdev.capabilities = 0;
-
- ret = dvb_dmxdev_init(&pd_dvb->dmxdev, &pd_dvb->dvb_adap);
- if (ret < 0)
- goto error3;
- return 0;
-
-error3:
- dvb_unregister_frontend(&pd_dvb->dvb_fe);
-error2:
- dvb_unregister_adapter(&pd_dvb->dvb_adap);
-error1:
- return ret;
-}
-
-void pd_dvb_usb_device_exit(struct poseidon *pd)
-{
- struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
-
- while (atomic_read(&pd_dvb->users) != 0
- || atomic_read(&pd_dvb->active_feed) != 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ);
- }
- dvb_dmxdev_release(&pd_dvb->dmxdev);
- dvb_unregister_frontend(&pd_dvb->dvb_fe);
- dvb_unregister_adapter(&pd_dvb->dvb_adap);
- pd_dvb_usb_device_cleanup(pd);
-}
-
-void pd_dvb_usb_device_cleanup(struct poseidon *pd)
-{
- struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
-
- dvb_urb_cleanup(pd_dvb);
-}
-
-int pd_dvb_get_adapter_num(struct pd_dvb_adapter *pd_dvb)
-{
- return pd_dvb->dvb_adap.num;
-}
diff --git a/drivers/media/video/tlg2300/pd-main.c b/drivers/media/video/tlg2300/pd-main.c
deleted file mode 100644
index 7b1f6ebd0e2..00000000000
--- a/drivers/media/video/tlg2300/pd-main.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * device driver for Telegent tlg2300 based TV cards
- *
- * Author :
- * Kang Yong <kangyong@telegent.com>
- * Zhang Xiaobing <xbzhang@telegent.com>
- * Huang Shijie <zyziii@telegent.com> or <shijie8@gmail.com>
- *
- * (c) 2009 Telegent Systems
- * (c) 2010 Telegent Systems
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kref.h>
-#include <linux/suspend.h>
-#include <linux/usb/quirks.h>
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/firmware.h>
-
-#include "vendorcmds.h"
-#include "pd-common.h"
-
-#define VENDOR_ID 0x1B24
-#define PRODUCT_ID 0x4001
-static struct usb_device_id id_table[] = {
- { USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ID, PRODUCT_ID, 255, 1, 0) },
- { USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ID, PRODUCT_ID, 255, 1, 1) },
- { },
-};
-MODULE_DEVICE_TABLE(usb, id_table);
-
-int debug_mode;
-module_param(debug_mode, int, 0644);
-MODULE_PARM_DESC(debug_mode, "0 = disable, 1 = enable, 2 = verbose");
-
-#define TLG2300_FIRMWARE "tlg2300_firmware.bin"
-static const char *firmware_name = TLG2300_FIRMWARE;
-static struct usb_driver poseidon_driver;
-static LIST_HEAD(pd_device_list);
-
-/*
- * send set request to USB firmware.
- */
-s32 send_set_req(struct poseidon *pd, u8 cmdid, s32 param, s32 *cmd_status)
-{
- s32 ret;
- s8 data[32] = {};
- u16 lower_16, upper_16;
-
- if (pd->state & POSEIDON_STATE_DISCONNECT)
- return -ENODEV;
-
- mdelay(30);
-
- if (param == 0) {
- upper_16 = lower_16 = 0;
- } else {
- /* send 32 bit param as two 16 bit param,little endian */
- lower_16 = (unsigned short)(param & 0xffff);
- upper_16 = (unsigned short)((param >> 16) & 0xffff);
- }
- ret = usb_control_msg(pd->udev,
- usb_rcvctrlpipe(pd->udev, 0),
- REQ_SET_CMD | cmdid,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- lower_16,
- upper_16,
- &data,
- sizeof(*cmd_status),
- USB_CTRL_GET_TIMEOUT);
-
- if (!ret) {
- return -ENXIO;
- } else {
- /* 1st 4 bytes into cmd_status */
- memcpy((char *)cmd_status, &(data[0]), sizeof(*cmd_status));
- }
- return 0;
-}
-
-/*
- * send get request to Poseidon firmware.
- */
-s32 send_get_req(struct poseidon *pd, u8 cmdid, s32 param,
- void *buf, s32 *cmd_status, s32 datalen)
-{
- s32 ret;
- s8 data[128] = {};
- u16 lower_16, upper_16;
-
- if (pd->state & POSEIDON_STATE_DISCONNECT)
- return -ENODEV;
-
- mdelay(30);
- if (param == 0) {
- upper_16 = lower_16 = 0;
- } else {
- /*send 32 bit param as two 16 bit param, little endian */
- lower_16 = (unsigned short)(param & 0xffff);
- upper_16 = (unsigned short)((param >> 16) & 0xffff);
- }
- ret = usb_control_msg(pd->udev,
- usb_rcvctrlpipe(pd->udev, 0),
- REQ_GET_CMD | cmdid,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- lower_16,
- upper_16,
- &data,
- (datalen + sizeof(*cmd_status)),
- USB_CTRL_GET_TIMEOUT);
-
- if (ret < 0) {
- return -ENXIO;
- } else {
- /* 1st 4 bytes into cmd_status, remaining data into cmd_data */
- memcpy((char *)cmd_status, &data[0], sizeof(*cmd_status));
- memcpy((char *)buf, &data[sizeof(*cmd_status)], datalen);
- }
- return 0;
-}
-
-static int pm_notifier_block(struct notifier_block *nb,
- unsigned long event, void *dummy)
-{
- struct poseidon *pd = NULL;
- struct list_head *node, *next;
-
- switch (event) {
- case PM_POST_HIBERNATION:
- list_for_each_safe(node, next, &pd_device_list) {
- struct usb_device *udev;
- struct usb_interface *iface;
- int rc = 0;
-
- pd = container_of(node, struct poseidon, device_list);
- udev = pd->udev;
- iface = pd->interface;
-
- /* It will cause the system to reload the firmware */
- rc = usb_lock_device_for_reset(udev, iface);
- if (rc >= 0) {
- usb_reset_device(udev);
- usb_unlock_device(udev);
- }
- }
- break;
- default:
- break;
- }
- log("event :%ld\n", event);
- return 0;
-}
-
-static struct notifier_block pm_notifer = {
- .notifier_call = pm_notifier_block,
-};
-
-int set_tuner_mode(struct poseidon *pd, unsigned char mode)
-{
- s32 ret, cmd_status;
-
- if (pd->state & POSEIDON_STATE_DISCONNECT)
- return -ENODEV;
-
- ret = send_set_req(pd, TUNE_MODE_SELECT, mode, &cmd_status);
- if (ret || cmd_status)
- return -ENXIO;
- return 0;
-}
-
-void poseidon_delete(struct kref *kref)
-{
- struct poseidon *pd = container_of(kref, struct poseidon, kref);
-
- if (!pd)
- return;
- list_del_init(&pd->device_list);
-
- pd_dvb_usb_device_cleanup(pd);
- /* clean_audio_data(&pd->audio_data);*/
-
- if (pd->udev) {
- usb_put_dev(pd->udev);
- pd->udev = NULL;
- }
- if (pd->interface) {
- usb_put_intf(pd->interface);
- pd->interface = NULL;
- }
- kfree(pd);
- log();
-}
-
-static int firmware_download(struct usb_device *udev)
-{
- int ret = 0, actual_length;
- const struct firmware *fw = NULL;
- void *fwbuf = NULL;
- size_t fwlength = 0, offset;
- size_t max_packet_size;
-
- ret = request_firmware(&fw, firmware_name, &udev->dev);
- if (ret) {
- log("download err : %d", ret);
- return ret;
- }
-
- fwlength = fw->size;
-
- fwbuf = kmemdup(fw->data, fwlength, GFP_KERNEL);
- if (!fwbuf) {
- ret = -ENOMEM;
- goto out;
- }
-
- max_packet_size = udev->ep_out[0x1]->desc.wMaxPacketSize;
- log("\t\t download size : %d", (int)max_packet_size);
-
- for (offset = 0; offset < fwlength; offset += max_packet_size) {
- actual_length = 0;
- ret = usb_bulk_msg(udev,
- usb_sndbulkpipe(udev, 0x01), /* ep 1 */
- fwbuf + offset,
- min(max_packet_size, fwlength - offset),
- &actual_length,
- HZ * 10);
- if (ret)
- break;
- }
- kfree(fwbuf);
-out:
- release_firmware(fw);
- return ret;
-}
-
-static inline struct poseidon *get_pd(struct usb_interface *intf)
-{
- return usb_get_intfdata(intf);
-}
-
-#ifdef CONFIG_PM
-/* one-to-one map : poseidon{} <----> usb_device{}'s port */
-static inline void set_map_flags(struct poseidon *pd, struct usb_device *udev)
-{
- pd->portnum = udev->portnum;
-}
-
-static inline int get_autopm_ref(struct poseidon *pd)
-{
- return pd->video_data.users + pd->vbi_data.users + pd->audio.users
- + atomic_read(&pd->dvb_data.users) + pd->radio_data.users;
-}
-
-/* fixup something for poseidon */
-static inline struct poseidon *fixup(struct poseidon *pd)
-{
- int count;
-
- /* old udev and interface have gone, so put back reference . */
- count = get_autopm_ref(pd);
- log("count : %d, ref count : %d", count, get_pm_count(pd));
- while (count--)
- usb_autopm_put_interface(pd->interface);
- /*usb_autopm_set_interface(pd->interface); */
-
- usb_put_dev(pd->udev);
- usb_put_intf(pd->interface);
- log("event : %d\n", pd->msg.event);
- return pd;
-}
-
-static struct poseidon *find_old_poseidon(struct usb_device *udev)
-{
- struct poseidon *pd;
-
- list_for_each_entry(pd, &pd_device_list, device_list) {
- if (pd->portnum == udev->portnum && in_hibernation(pd))
- return fixup(pd);
- }
- return NULL;
-}
-
-/* Is the card working now ? */
-static inline int is_working(struct poseidon *pd)
-{
- return get_pm_count(pd) > 0;
-}
-
-static int poseidon_suspend(struct usb_interface *intf, pm_message_t msg)
-{
- struct poseidon *pd = get_pd(intf);
-
- if (!pd)
- return 0;
- if (!is_working(pd)) {
- if (get_pm_count(pd) <= 0 && !in_hibernation(pd)) {
- pd->msg.event = PM_EVENT_AUTO_SUSPEND;
- pd->pm_resume = NULL; /* a good guard */
- printk(KERN_DEBUG "\n\t+ TLG2300 auto suspend +\n\n");
- }
- return 0;
- }
- pd->msg = msg; /* save it here */
- logpm(pd);
- return pd->pm_suspend ? pd->pm_suspend(pd) : 0;
-}
-
-static int poseidon_resume(struct usb_interface *intf)
-{
- struct poseidon *pd = get_pd(intf);
-
- if (!pd)
- return 0;
- printk(KERN_DEBUG "\n\t ++ TLG2300 resume ++\n\n");
-
- if (!is_working(pd)) {
- if (PM_EVENT_AUTO_SUSPEND == pd->msg.event)
- pd->msg = PMSG_ON;
- return 0;
- }
- if (in_hibernation(pd)) {
- logpm(pd);
- return 0;
- }
- logpm(pd);
- return pd->pm_resume ? pd->pm_resume(pd) : 0;
-}
-
-static void hibernation_resume(struct work_struct *w)
-{
- struct poseidon *pd = container_of(w, struct poseidon, pm_work);
- int count;
-
- pd->msg.event = 0; /* clear it here */
- pd->state &= ~POSEIDON_STATE_DISCONNECT;
-
- /* set the new interface's reference */
- count = get_autopm_ref(pd);
- while (count--)
- usb_autopm_get_interface(pd->interface);
-
- /* resume the context */
- logpm(pd);
- if (pd->pm_resume)
- pd->pm_resume(pd);
-}
-#else /* CONFIG_PM is not enabled: */
-static inline struct poseidon *find_old_poseidon(struct usb_device *udev)
-{
- return NULL;
-}
-
-static inline void set_map_flags(struct poseidon *pd, struct usb_device *udev)
-{
-}
-#endif
-
-static int check_firmware(struct usb_device *udev, int *down_firmware)
-{
- void *buf;
- int ret;
- struct cmd_firmware_vers_s *cmd_firm;
-
- buf = kzalloc(sizeof(*cmd_firm) + sizeof(u32), GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- ret = usb_control_msg(udev,
- usb_rcvctrlpipe(udev, 0),
- REQ_GET_CMD | GET_FW_ID,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0,
- 0,
- buf,
- sizeof(*cmd_firm) + sizeof(u32),
- USB_CTRL_GET_TIMEOUT);
- kfree(buf);
-
- if (ret < 0) {
- *down_firmware = 1;
- return firmware_download(udev);
- }
- return 0;
-}
-
-static int poseidon_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(interface);
- struct poseidon *pd = NULL;
- int ret = 0;
- int new_one = 0;
-
- /* download firmware */
- check_firmware(udev, &ret);
- if (ret)
- return 0;
-
- /* Do I recovery from the hibernate ? */
- pd = find_old_poseidon(udev);
- if (!pd) {
- pd = kzalloc(sizeof(*pd), GFP_KERNEL);
- if (!pd)
- return -ENOMEM;
- kref_init(&pd->kref);
- set_map_flags(pd, udev);
- new_one = 1;
- }
-
- pd->udev = usb_get_dev(udev);
- pd->interface = usb_get_intf(interface);
- usb_set_intfdata(interface, pd);
-
- if (new_one) {
- struct device *dev = &interface->dev;
-
- logpm(pd);
- mutex_init(&pd->lock);
-
- /* register v4l2 device */
- snprintf(pd->v4l2_dev.name, sizeof(pd->v4l2_dev.name), "%s %s",
- dev->driver->name, dev_name(dev));
- ret = v4l2_device_register(NULL, &pd->v4l2_dev);
-
- /* register devices in directory /dev */
- ret = pd_video_init(pd);
- poseidon_audio_init(pd);
- poseidon_fm_init(pd);
- pd_dvb_usb_device_init(pd);
-
- INIT_LIST_HEAD(&pd->device_list);
- list_add_tail(&pd->device_list, &pd_device_list);
- }
-
- device_init_wakeup(&udev->dev, 1);
-#ifdef CONFIG_PM
- pm_runtime_set_autosuspend_delay(&pd->udev->dev,
- 1000 * PM_SUSPEND_DELAY);
- usb_enable_autosuspend(pd->udev);
-
- if (in_hibernation(pd)) {
- INIT_WORK(&pd->pm_work, hibernation_resume);
- schedule_work(&pd->pm_work);
- }
-#endif
- return 0;
-}
-
-static void poseidon_disconnect(struct usb_interface *interface)
-{
- struct poseidon *pd = get_pd(interface);
-
- if (!pd)
- return;
- logpm(pd);
- if (in_hibernation(pd))
- return;
-
- mutex_lock(&pd->lock);
- pd->state |= POSEIDON_STATE_DISCONNECT;
- mutex_unlock(&pd->lock);
-
- /* stop urb transferring */
- stop_all_video_stream(pd);
- dvb_stop_streaming(&pd->dvb_data);
-
- /*unregister v4l2 device */
- v4l2_device_unregister(&pd->v4l2_dev);
-
- pd_dvb_usb_device_exit(pd);
- poseidon_fm_exit(pd);
-
- poseidon_audio_free(pd);
- pd_video_exit(pd);
-
- usb_set_intfdata(interface, NULL);
- kref_put(&pd->kref, poseidon_delete);
-}
-
-static struct usb_driver poseidon_driver = {
- .name = "poseidon",
- .probe = poseidon_probe,
- .disconnect = poseidon_disconnect,
- .id_table = id_table,
-#ifdef CONFIG_PM
- .suspend = poseidon_suspend,
- .resume = poseidon_resume,
-#endif
- .supports_autosuspend = 1,
-};
-
-static int __init poseidon_init(void)
-{
- int ret;
-
- ret = usb_register(&poseidon_driver);
- if (ret)
- return ret;
- register_pm_notifier(&pm_notifer);
- return ret;
-}
-
-static void __exit poseidon_exit(void)
-{
- log();
- unregister_pm_notifier(&pm_notifer);
- usb_deregister(&poseidon_driver);
-}
-
-module_init(poseidon_init);
-module_exit(poseidon_exit);
-
-MODULE_AUTHOR("Telegent Systems");
-MODULE_DESCRIPTION("For tlg2300-based USB device ");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.2");
-MODULE_FIRMWARE(TLG2300_FIRMWARE);
diff --git a/drivers/media/video/tlg2300/pd-radio.c b/drivers/media/video/tlg2300/pd-radio.c
deleted file mode 100644
index 4fad1dfb92c..00000000000
--- a/drivers/media/video/tlg2300/pd-radio.c
+++ /dev/null
@@ -1,421 +0,0 @@
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/bitmap.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <media/v4l2-dev.h>
-#include <linux/mm.h>
-#include <linux/mutex.h>
-#include <media/v4l2-ioctl.h>
-#include <linux/sched.h>
-
-#include "pd-common.h"
-#include "vendorcmds.h"
-
-static int set_frequency(struct poseidon *p, __u32 frequency);
-static int poseidon_fm_close(struct file *filp);
-static int poseidon_fm_open(struct file *filp);
-
-#define TUNER_FREQ_MIN_FM 76000000
-#define TUNER_FREQ_MAX_FM 108000000
-
-#define MAX_PREEMPHASIS (V4L2_PREEMPHASIS_75_uS + 1)
-static int preemphasis[MAX_PREEMPHASIS] = {
- TLG_TUNE_ASTD_NONE, /* V4L2_PREEMPHASIS_DISABLED */
- TLG_TUNE_ASTD_FM_EUR, /* V4L2_PREEMPHASIS_50_uS */
- TLG_TUNE_ASTD_FM_US, /* V4L2_PREEMPHASIS_75_uS */
-};
-
-static int poseidon_check_mode_radio(struct poseidon *p)
-{
- int ret;
- u32 status;
-
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ/2);
- ret = usb_set_interface(p->udev, 0, BULK_ALTERNATE_IFACE);
- if (ret < 0)
- goto out;
-
- ret = set_tuner_mode(p, TLG_MODE_FM_RADIO);
- if (ret != 0)
- goto out;
-
- ret = send_set_req(p, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &status);
- ret = send_set_req(p, TUNER_AUD_ANA_STD,
- p->radio_data.pre_emphasis, &status);
- ret |= send_set_req(p, TUNER_AUD_MODE,
- TLG_TUNE_TVAUDIO_MODE_STEREO, &status);
- ret |= send_set_req(p, AUDIO_SAMPLE_RATE_SEL,
- ATV_AUDIO_RATE_48K, &status);
- ret |= send_set_req(p, TUNE_FREQ_SELECT, TUNER_FREQ_MIN_FM, &status);
-out:
- return ret;
-}
-
-#ifdef CONFIG_PM
-static int pm_fm_suspend(struct poseidon *p)
-{
- logpm(p);
- pm_alsa_suspend(p);
- usb_set_interface(p->udev, 0, 0);
- msleep(300);
- return 0;
-}
-
-static int pm_fm_resume(struct poseidon *p)
-{
- logpm(p);
- poseidon_check_mode_radio(p);
- set_frequency(p, p->radio_data.fm_freq);
- pm_alsa_resume(p);
- return 0;
-}
-#endif
-
-static int poseidon_fm_open(struct file *filp)
-{
- struct video_device *vfd = video_devdata(filp);
- struct poseidon *p = video_get_drvdata(vfd);
- int ret = 0;
-
- if (!p)
- return -1;
-
- mutex_lock(&p->lock);
- if (p->state & POSEIDON_STATE_DISCONNECT) {
- ret = -ENODEV;
- goto out;
- }
-
- if (p->state && !(p->state & POSEIDON_STATE_FM)) {
- ret = -EBUSY;
- goto out;
- }
-
- usb_autopm_get_interface(p->interface);
- if (0 == p->state) {
- /* default pre-emphasis */
- if (p->radio_data.pre_emphasis == 0)
- p->radio_data.pre_emphasis = TLG_TUNE_ASTD_FM_EUR;
- set_debug_mode(vfd, debug_mode);
-
- ret = poseidon_check_mode_radio(p);
- if (ret < 0) {
- usb_autopm_put_interface(p->interface);
- goto out;
- }
- p->state |= POSEIDON_STATE_FM;
- }
- p->radio_data.users++;
- kref_get(&p->kref);
- filp->private_data = p;
-out:
- mutex_unlock(&p->lock);
- return ret;
-}
-
-static int poseidon_fm_close(struct file *filp)
-{
- struct poseidon *p = filp->private_data;
- struct radio_data *fm = &p->radio_data;
- uint32_t status;
-
- mutex_lock(&p->lock);
- fm->users--;
- if (0 == fm->users)
- p->state &= ~POSEIDON_STATE_FM;
-
- if (fm->is_radio_streaming && filp == p->file_for_stream) {
- fm->is_radio_streaming = 0;
- send_set_req(p, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP, &status);
- }
- usb_autopm_put_interface(p->interface);
- mutex_unlock(&p->lock);
-
- kref_put(&p->kref, poseidon_delete);
- filp->private_data = NULL;
- return 0;
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *v)
-{
- struct poseidon *p = file->private_data;
-
- strlcpy(v->driver, "tele-radio", sizeof(v->driver));
- strlcpy(v->card, "Telegent Poseidon", sizeof(v->card));
- usb_make_path(p->udev, v->bus_info, sizeof(v->bus_info));
- v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
- return 0;
-}
-
-static const struct v4l2_file_operations poseidon_fm_fops = {
- .owner = THIS_MODULE,
- .open = poseidon_fm_open,
- .release = poseidon_fm_close,
- .ioctl = video_ioctl2,
-};
-
-static int tlg_fm_vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *vt)
-{
- struct tuner_fm_sig_stat_s fm_stat = {};
- int ret, status, count = 5;
- struct poseidon *p = file->private_data;
-
- if (vt->index != 0)
- return -EINVAL;
-
- vt->type = V4L2_TUNER_RADIO;
- vt->capability = V4L2_TUNER_CAP_STEREO;
- vt->rangelow = TUNER_FREQ_MIN_FM / 62500;
- vt->rangehigh = TUNER_FREQ_MAX_FM / 62500;
- vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
- vt->audmode = V4L2_TUNER_MODE_STEREO;
- vt->signal = 0;
- vt->afc = 0;
-
- mutex_lock(&p->lock);
- ret = send_get_req(p, TUNER_STATUS, TLG_MODE_FM_RADIO,
- &fm_stat, &status, sizeof(fm_stat));
-
- while (fm_stat.sig_lock_busy && count-- && !ret) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ);
-
- ret = send_get_req(p, TUNER_STATUS, TLG_MODE_FM_RADIO,
- &fm_stat, &status, sizeof(fm_stat));
- }
- mutex_unlock(&p->lock);
-
- if (ret || status) {
- vt->signal = 0;
- } else if ((fm_stat.sig_present || fm_stat.sig_locked)
- && fm_stat.sig_strength == 0) {
- vt->signal = 0xffff;
- } else
- vt->signal = (fm_stat.sig_strength * 255 / 10) << 8;
-
- return 0;
-}
-
-static int fm_get_freq(struct file *file, void *priv,
- struct v4l2_frequency *argp)
-{
- struct poseidon *p = file->private_data;
-
- argp->frequency = p->radio_data.fm_freq;
- return 0;
-}
-
-static int set_frequency(struct poseidon *p, __u32 frequency)
-{
- __u32 freq ;
- int ret, status;
-
- mutex_lock(&p->lock);
-
- ret = send_set_req(p, TUNER_AUD_ANA_STD,
- p->radio_data.pre_emphasis, &status);
-
- freq = (frequency * 125) * 500 / 1000;/* kHZ */
- if (freq < TUNER_FREQ_MIN_FM/1000 || freq > TUNER_FREQ_MAX_FM/1000) {
- ret = -EINVAL;
- goto error;
- }
-
- ret = send_set_req(p, TUNE_FREQ_SELECT, freq, &status);
- if (ret < 0)
- goto error ;
- ret = send_set_req(p, TAKE_REQUEST, 0, &status);
-
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ/4);
- if (!p->radio_data.is_radio_streaming) {
- ret = send_set_req(p, TAKE_REQUEST, 0, &status);
- ret = send_set_req(p, PLAY_SERVICE,
- TLG_TUNE_PLAY_SVC_START, &status);
- p->radio_data.is_radio_streaming = 1;
- }
- p->radio_data.fm_freq = frequency;
-error:
- mutex_unlock(&p->lock);
- return ret;
-}
-
-static int fm_set_freq(struct file *file, void *priv,
- struct v4l2_frequency *argp)
-{
- struct poseidon *p = file->private_data;
-
- p->file_for_stream = file;
-#ifdef CONFIG_PM
- p->pm_suspend = pm_fm_suspend;
- p->pm_resume = pm_fm_resume;
-#endif
- return set_frequency(p, argp->frequency);
-}
-
-static int tlg_fm_vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *arg)
-{
- return 0;
-}
-
-static int tlg_fm_vidioc_g_exts_ctrl(struct file *file, void *fh,
- struct v4l2_ext_controls *ctrls)
-{
- struct poseidon *p = file->private_data;
- int i;
-
- if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
- return -EINVAL;
-
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS)
- continue;
-
- if (i < MAX_PREEMPHASIS)
- ctrl->value = p->radio_data.pre_emphasis;
- }
- return 0;
-}
-
-static int tlg_fm_vidioc_s_exts_ctrl(struct file *file, void *fh,
- struct v4l2_ext_controls *ctrls)
-{
- int i;
-
- if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
- return -EINVAL;
-
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS)
- continue;
-
- if (ctrl->value >= 0 && ctrl->value < MAX_PREEMPHASIS) {
- struct poseidon *p = file->private_data;
- int pre_emphasis = preemphasis[ctrl->value];
- u32 status;
-
- send_set_req(p, TUNER_AUD_ANA_STD,
- pre_emphasis, &status);
- p->radio_data.pre_emphasis = pre_emphasis;
- }
- }
- return 0;
-}
-
-static int tlg_fm_vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- return 0;
-}
-
-static int tlg_fm_vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *ctrl)
-{
- if (!(ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL))
- return -EINVAL;
-
- ctrl->id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
- if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS) {
- /* return the next supported control */
- ctrl->id = V4L2_CID_TUNE_PREEMPHASIS;
- v4l2_ctrl_query_fill(ctrl, V4L2_PREEMPHASIS_DISABLED,
- V4L2_PREEMPHASIS_75_uS, 1,
- V4L2_PREEMPHASIS_50_uS);
- ctrl->flags = V4L2_CTRL_FLAG_UPDATE;
- return 0;
- }
- return -EINVAL;
-}
-
-static int tlg_fm_vidioc_querymenu(struct file *file, void *fh,
- struct v4l2_querymenu *qmenu)
-{
- return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
-{
- return vt->index > 0 ? -EINVAL : 0;
-}
-static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *va)
-{
- return (va->index != 0) ? -EINVAL : 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- a->index = 0;
- a->mode = 0;
- a->capability = V4L2_AUDCAP_STEREO;
- strcpy(a->name, "Radio");
- return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, u32 i)
-{
- return (i != 0) ? -EINVAL : 0;
-}
-
-static int vidioc_g_input(struct file *filp, void *priv, u32 *i)
-{
- return (*i != 0) ? -EINVAL : 0;
-}
-
-static const struct v4l2_ioctl_ops poseidon_fm_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = tlg_fm_vidioc_queryctrl,
- .vidioc_querymenu = tlg_fm_vidioc_querymenu,
- .vidioc_g_ctrl = tlg_fm_vidioc_g_ctrl,
- .vidioc_s_ctrl = tlg_fm_vidioc_s_ctrl,
- .vidioc_s_ext_ctrls = tlg_fm_vidioc_s_exts_ctrl,
- .vidioc_g_ext_ctrls = tlg_fm_vidioc_g_exts_ctrl,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_tuner = tlg_fm_vidioc_g_tuner,
- .vidioc_g_frequency = fm_get_freq,
- .vidioc_s_frequency = fm_set_freq,
-};
-
-static struct video_device poseidon_fm_template = {
- .name = "Telegent-Radio",
- .fops = &poseidon_fm_fops,
- .minor = -1,
- .release = video_device_release,
- .ioctl_ops = &poseidon_fm_ioctl_ops,
-};
-
-int poseidon_fm_init(struct poseidon *p)
-{
- struct video_device *fm_dev;
-
- fm_dev = vdev_init(p, &poseidon_fm_template);
- if (fm_dev == NULL)
- return -1;
-
- if (video_register_device(fm_dev, VFL_TYPE_RADIO, -1) < 0) {
- video_device_release(fm_dev);
- return -1;
- }
- p->radio_data.fm_dev = fm_dev;
- return 0;
-}
-
-int poseidon_fm_exit(struct poseidon *p)
-{
- destroy_video_device(&p->radio_data.fm_dev);
- return 0;
-}
diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c
deleted file mode 100644
index bfbf9e56b0a..00000000000
--- a/drivers/media/video/tlg2300/pd-video.c
+++ /dev/null
@@ -1,1668 +0,0 @@
-#include <linux/fs.h>
-#include <linux/vmalloc.h>
-#include <linux/videodev2.h>
-#include <linux/usb.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-dev.h>
-
-#include "pd-common.h"
-#include "vendorcmds.h"
-
-#ifdef CONFIG_PM
-static int pm_video_suspend(struct poseidon *pd);
-static int pm_video_resume(struct poseidon *pd);
-#endif
-static void iso_bubble_handler(struct work_struct *w);
-
-static int usb_transfer_mode;
-module_param(usb_transfer_mode, int, 0644);
-MODULE_PARM_DESC(usb_transfer_mode, "0 = Bulk, 1 = Isochronous");
-
-static const struct poseidon_format poseidon_formats[] = {
- { "YUV 422", V4L2_PIX_FMT_YUYV, 16, 0},
- { "RGB565", V4L2_PIX_FMT_RGB565, 16, 0},
-};
-
-static const struct poseidon_tvnorm poseidon_tvnorms[] = {
- { V4L2_STD_PAL_D, "PAL-D", TLG_TUNE_VSTD_PAL_D },
- { V4L2_STD_PAL_B, "PAL-B", TLG_TUNE_VSTD_PAL_B },
- { V4L2_STD_PAL_G, "PAL-G", TLG_TUNE_VSTD_PAL_G },
- { V4L2_STD_PAL_H, "PAL-H", TLG_TUNE_VSTD_PAL_H },
- { V4L2_STD_PAL_I, "PAL-I", TLG_TUNE_VSTD_PAL_I },
- { V4L2_STD_PAL_M, "PAL-M", TLG_TUNE_VSTD_PAL_M },
- { V4L2_STD_PAL_N, "PAL-N", TLG_TUNE_VSTD_PAL_N_COMBO },
- { V4L2_STD_PAL_Nc, "PAL-Nc", TLG_TUNE_VSTD_PAL_N_COMBO },
- { V4L2_STD_NTSC_M, "NTSC-M", TLG_TUNE_VSTD_NTSC_M },
- { V4L2_STD_NTSC_M_JP, "NTSC-JP", TLG_TUNE_VSTD_NTSC_M_J },
- { V4L2_STD_SECAM_B, "SECAM-B", TLG_TUNE_VSTD_SECAM_B },
- { V4L2_STD_SECAM_D, "SECAM-D", TLG_TUNE_VSTD_SECAM_D },
- { V4L2_STD_SECAM_G, "SECAM-G", TLG_TUNE_VSTD_SECAM_G },
- { V4L2_STD_SECAM_H, "SECAM-H", TLG_TUNE_VSTD_SECAM_H },
- { V4L2_STD_SECAM_K, "SECAM-K", TLG_TUNE_VSTD_SECAM_K },
- { V4L2_STD_SECAM_K1, "SECAM-K1", TLG_TUNE_VSTD_SECAM_K1 },
- { V4L2_STD_SECAM_L, "SECAM-L", TLG_TUNE_VSTD_SECAM_L },
- { V4L2_STD_SECAM_LC, "SECAM-LC", TLG_TUNE_VSTD_SECAM_L1 },
-};
-static const unsigned int POSEIDON_TVNORMS = ARRAY_SIZE(poseidon_tvnorms);
-
-struct pd_audio_mode {
- u32 tlg_audio_mode;
- u32 v4l2_audio_sub;
- u32 v4l2_audio_mode;
-};
-
-static const struct pd_audio_mode pd_audio_modes[] = {
- { TLG_TUNE_TVAUDIO_MODE_MONO, V4L2_TUNER_SUB_MONO,
- V4L2_TUNER_MODE_MONO },
- { TLG_TUNE_TVAUDIO_MODE_STEREO, V4L2_TUNER_SUB_STEREO,
- V4L2_TUNER_MODE_STEREO },
- { TLG_TUNE_TVAUDIO_MODE_LANG_A, V4L2_TUNER_SUB_LANG1,
- V4L2_TUNER_MODE_LANG1 },
- { TLG_TUNE_TVAUDIO_MODE_LANG_B, V4L2_TUNER_SUB_LANG2,
- V4L2_TUNER_MODE_LANG2 },
- { TLG_TUNE_TVAUDIO_MODE_LANG_C, V4L2_TUNER_SUB_LANG1,
- V4L2_TUNER_MODE_LANG1_LANG2 }
-};
-static const unsigned int POSEIDON_AUDIOMODS = ARRAY_SIZE(pd_audio_modes);
-
-struct pd_input {
- char *name;
- uint32_t tlg_src;
-};
-
-static const struct pd_input pd_inputs[] = {
- { "TV Antenna", TLG_SIG_SRC_ANTENNA },
- { "TV Cable", TLG_SIG_SRC_CABLE },
- { "TV SVideo", TLG_SIG_SRC_SVIDEO },
- { "TV Composite", TLG_SIG_SRC_COMPOSITE }
-};
-static const unsigned int POSEIDON_INPUTS = ARRAY_SIZE(pd_inputs);
-
-struct poseidon_control {
- struct v4l2_queryctrl v4l2_ctrl;
- enum cmd_custom_param_id vc_id;
-};
-
-static struct poseidon_control controls[] = {
- {
- { V4L2_CID_BRIGHTNESS, V4L2_CTRL_TYPE_INTEGER,
- "brightness", 0, 10000, 1, 100, 0, },
- CUST_PARM_ID_BRIGHTNESS_CTRL
- }, {
- { V4L2_CID_CONTRAST, V4L2_CTRL_TYPE_INTEGER,
- "contrast", 0, 10000, 1, 100, 0, },
- CUST_PARM_ID_CONTRAST_CTRL,
- }, {
- { V4L2_CID_HUE, V4L2_CTRL_TYPE_INTEGER,
- "hue", 0, 10000, 1, 100, 0, },
- CUST_PARM_ID_HUE_CTRL,
- }, {
- { V4L2_CID_SATURATION, V4L2_CTRL_TYPE_INTEGER,
- "saturation", 0, 10000, 1, 100, 0, },
- CUST_PARM_ID_SATURATION_CTRL,
- },
-};
-
-struct video_std_to_audio_std {
- v4l2_std_id video_std;
- int audio_std;
-};
-
-static const struct video_std_to_audio_std video_to_audio_map[] = {
- /* country : { 27, 32, 33, 34, 36, 44, 45, 46, 47, 48, 64,
- 65, 86, 351, 352, 353, 354, 358, 372, 852, 972 } */
- { (V4L2_STD_PAL_I | V4L2_STD_PAL_B | V4L2_STD_PAL_D |
- V4L2_STD_SECAM_L | V4L2_STD_SECAM_D), TLG_TUNE_ASTD_NICAM },
-
- /* country : { 1, 52, 54, 55, 886 } */
- {V4L2_STD_NTSC_M | V4L2_STD_PAL_N | V4L2_STD_PAL_M, TLG_TUNE_ASTD_BTSC},
-
- /* country : { 81 } */
- { V4L2_STD_NTSC_M_JP, TLG_TUNE_ASTD_EIAJ },
-
- /* other country : TLG_TUNE_ASTD_A2 */
-};
-static const unsigned int map_size = ARRAY_SIZE(video_to_audio_map);
-
-static int get_audio_std(v4l2_std_id v4l2_std)
-{
- int i = 0;
-
- for (; i < map_size; i++) {
- if (v4l2_std & video_to_audio_map[i].video_std)
- return video_to_audio_map[i].audio_std;
- }
- return TLG_TUNE_ASTD_A2;
-}
-
-static int vidioc_querycap(struct file *file, void *fh,
- struct v4l2_capability *cap)
-{
- struct front_face *front = fh;
- struct poseidon *p = front->pd;
-
- logs(front);
-
- strcpy(cap->driver, "tele-video");
- strcpy(cap->card, "Telegent Poseidon");
- usb_make_path(p->udev, cap->bus_info, sizeof(cap->bus_info));
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
- V4L2_CAP_AUDIO | V4L2_CAP_STREAMING |
- V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE;
- return 0;
-}
-
-/*====================================================================*/
-static void init_copy(struct video_data *video, bool index)
-{
- struct front_face *front = video->front;
-
- video->field_count = index;
- video->lines_copied = 0;
- video->prev_left = 0 ;
- video->dst = (char *)videobuf_to_vmalloc(front->curr_frame)
- + index * video->lines_size;
- video->vbi->copied = 0; /* set it here */
-}
-
-static bool get_frame(struct front_face *front, int *need_init)
-{
- struct videobuf_buffer *vb = front->curr_frame;
-
- if (vb)
- return true;
-
- spin_lock(&front->queue_lock);
- if (!list_empty(&front->active)) {
- vb = list_entry(front->active.next,
- struct videobuf_buffer, queue);
- if (need_init)
- *need_init = 1;
- front->curr_frame = vb;
- list_del_init(&vb->queue);
- }
- spin_unlock(&front->queue_lock);
-
- return !!vb;
-}
-
-/* check if the video's buffer is ready */
-static bool get_video_frame(struct front_face *front, struct video_data *video)
-{
- int need_init = 0;
- bool ret = true;
-
- ret = get_frame(front, &need_init);
- if (ret && need_init)
- init_copy(video, 0);
- return ret;
-}
-
-static void submit_frame(struct front_face *front)
-{
- struct videobuf_buffer *vb = front->curr_frame;
-
- if (vb == NULL)
- return;
-
- front->curr_frame = NULL;
- vb->state = VIDEOBUF_DONE;
- vb->field_count++;
- do_gettimeofday(&vb->ts);
-
- wake_up(&vb->done);
-}
-
-/*
- * A frame is composed of two fields. If we receive all the two fields,
- * call the submit_frame() to submit the whole frame to applications.
- */
-static void end_field(struct video_data *video)
-{
- /* logs(video->front); */
- if (1 == video->field_count)
- submit_frame(video->front);
- else
- init_copy(video, 1);
-}
-
-static void copy_video_data(struct video_data *video, char *src,
- unsigned int count)
-{
-#define copy_data(len) \
- do { \
- if (++video->lines_copied > video->lines_per_field) \
- goto overflow; \
- memcpy(video->dst, src, len);\
- video->dst += len + video->lines_size; \
- src += len; \
- count -= len; \
- } while (0)
-
- while (count && count >= video->lines_size) {
- if (video->prev_left) {
- copy_data(video->prev_left);
- video->prev_left = 0;
- continue;
- }
- copy_data(video->lines_size);
- }
- if (count && count < video->lines_size) {
- memcpy(video->dst, src, count);
-
- video->prev_left = video->lines_size - count;
- video->dst += count;
- }
- return;
-
-overflow:
- end_field(video);
-}
-
-static void check_trailer(struct video_data *video, char *src, int count)
-{
- struct vbi_data *vbi = video->vbi;
- int offset; /* trailer's offset */
- char *buf;
-
- offset = (video->context.pix.sizeimage / 2 + vbi->vbi_size / 2)
- - (vbi->copied + video->lines_size * video->lines_copied);
- if (video->prev_left)
- offset -= (video->lines_size - video->prev_left);
-
- if (offset > count || offset <= 0)
- goto short_package;
-
- buf = src + offset;
-
- /* trailer : (VFHS) + U32 + U32 + field_num */
- if (!strncmp(buf, "VFHS", 4)) {
- int field_num = *((u32 *)(buf + 12));
-
- if ((field_num & 1) ^ video->field_count) {
- init_copy(video, video->field_count);
- return;
- }
- copy_video_data(video, src, offset);
- }
-short_package:
- end_field(video);
-}
-
-/* ========== Check this more carefully! =========== */
-static inline void copy_vbi_data(struct vbi_data *vbi,
- char *src, unsigned int count)
-{
- struct front_face *front = vbi->front;
-
- if (front && get_frame(front, NULL)) {
- char *buf = videobuf_to_vmalloc(front->curr_frame);
-
- if (vbi->video->field_count)
- buf += (vbi->vbi_size / 2);
- memcpy(buf + vbi->copied, src, count);
- }
- vbi->copied += count;
-}
-
-/*
- * Copy the normal data (VBI or VIDEO) without the trailer.
- * VBI is not interlaced, while VIDEO is interlaced.
- */
-static inline void copy_vbi_video_data(struct video_data *video,
- char *src, unsigned int count)
-{
- struct vbi_data *vbi = video->vbi;
- unsigned int vbi_delta = (vbi->vbi_size / 2) - vbi->copied;
-
- if (vbi_delta >= count) {
- copy_vbi_data(vbi, src, count);
- } else {
- if (vbi_delta) {
- copy_vbi_data(vbi, src, vbi_delta);
-
- /* we receive the two fields of the VBI*/
- if (vbi->front && video->field_count)
- submit_frame(vbi->front);
- }
- copy_video_data(video, src + vbi_delta, count - vbi_delta);
- }
-}
-
-static void urb_complete_bulk(struct urb *urb)
-{
- struct front_face *front = urb->context;
- struct video_data *video = &front->pd->video_data;
- char *src = (char *)urb->transfer_buffer;
- int count = urb->actual_length;
- int ret = 0;
-
- if (!video->is_streaming || urb->status) {
- if (urb->status == -EPROTO)
- goto resend_it;
- return;
- }
- if (!get_video_frame(front, video))
- goto resend_it;
-
- if (count == urb->transfer_buffer_length)
- copy_vbi_video_data(video, src, count);
- else
- check_trailer(video, src, count);
-
-resend_it:
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret)
- log(" submit failed: error %d", ret);
-}
-
-/************************* for ISO *********************/
-#define GET_SUCCESS (0)
-#define GET_TRAILER (1)
-#define GET_TOO_MUCH_BUBBLE (2)
-#define GET_NONE (3)
-static int get_chunk(int start, struct urb *urb,
- int *head, int *tail, int *bubble_err)
-{
- struct usb_iso_packet_descriptor *pkt = NULL;
- int ret = GET_SUCCESS;
-
- for (*head = *tail = -1; start < urb->number_of_packets; start++) {
- pkt = &urb->iso_frame_desc[start];
-
- /* handle the bubble of the Hub */
- if (-EOVERFLOW == pkt->status) {
- if (++*bubble_err > urb->number_of_packets / 3)
- return GET_TOO_MUCH_BUBBLE;
- continue;
- }
-
- /* This is the gap */
- if (pkt->status || pkt->actual_length <= 0
- || pkt->actual_length > ISO_PKT_SIZE) {
- if (*head != -1)
- break;
- continue;
- }
-
- /* a good isochronous packet */
- if (pkt->actual_length == ISO_PKT_SIZE) {
- if (*head == -1)
- *head = start;
- *tail = start;
- continue;
- }
-
- /* trailer is here */
- if (pkt->actual_length < ISO_PKT_SIZE) {
- if (*head == -1) {
- *head = start;
- *tail = start;
- return GET_TRAILER;
- }
- break;
- }
- }
-
- if (*head == -1 && *tail == -1)
- ret = GET_NONE;
- return ret;
-}
-
-/*
- * |__|------|___|-----|_______|
- * ^ ^
- * | |
- * gap gap
- */
-static void urb_complete_iso(struct urb *urb)
-{
- struct front_face *front = urb->context;
- struct video_data *video = &front->pd->video_data;
- int bubble_err = 0, head = 0, tail = 0;
- char *src = (char *)urb->transfer_buffer;
- int ret = 0;
-
- if (!video->is_streaming)
- return;
-
- do {
- if (!get_video_frame(front, video))
- goto out;
-
- switch (get_chunk(head, urb, &head, &tail, &bubble_err)) {
- case GET_SUCCESS:
- copy_vbi_video_data(video, src + (head * ISO_PKT_SIZE),
- (tail - head + 1) * ISO_PKT_SIZE);
- break;
- case GET_TRAILER:
- check_trailer(video, src + (head * ISO_PKT_SIZE),
- ISO_PKT_SIZE);
- break;
- case GET_NONE:
- goto out;
- case GET_TOO_MUCH_BUBBLE:
- log("\t We got too much bubble");
- schedule_work(&video->bubble_work);
- return;
- }
- } while (head = tail + 1, head < urb->number_of_packets);
-
-out:
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret)
- log("usb_submit_urb err : %d", ret);
-}
-/*============================= [ end ] =====================*/
-
-static int prepare_iso_urb(struct video_data *video)
-{
- struct usb_device *udev = video->pd->udev;
- int i;
-
- if (video->urb_array[0])
- return 0;
-
- for (i = 0; i < SBUF_NUM; i++) {
- struct urb *urb;
- void *mem;
- int j;
-
- urb = usb_alloc_urb(PK_PER_URB, GFP_KERNEL);
- if (urb == NULL)
- goto out;
-
- video->urb_array[i] = urb;
- mem = usb_alloc_coherent(udev,
- ISO_PKT_SIZE * PK_PER_URB,
- GFP_KERNEL,
- &urb->transfer_dma);
-
- urb->complete = urb_complete_iso; /* handler */
- urb->dev = udev;
- urb->context = video->front;
- urb->pipe = usb_rcvisocpipe(udev,
- video->endpoint_addr);
- urb->interval = 1;
- urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
- urb->number_of_packets = PK_PER_URB;
- urb->transfer_buffer = mem;
- urb->transfer_buffer_length = PK_PER_URB * ISO_PKT_SIZE;
-
- for (j = 0; j < PK_PER_URB; j++) {
- urb->iso_frame_desc[j].offset = ISO_PKT_SIZE * j;
- urb->iso_frame_desc[j].length = ISO_PKT_SIZE;
- }
- }
- return 0;
-out:
- for (; i > 0; i--)
- ;
- return -ENOMEM;
-}
-
-/* return the succeeded number of the allocation */
-int alloc_bulk_urbs_generic(struct urb **urb_array, int num,
- struct usb_device *udev, u8 ep_addr,
- int buf_size, gfp_t gfp_flags,
- usb_complete_t complete_fn, void *context)
-{
- int i = 0;
-
- for (; i < num; i++) {
- void *mem;
- struct urb *urb = usb_alloc_urb(0, gfp_flags);
- if (urb == NULL)
- return i;
-
- mem = usb_alloc_coherent(udev, buf_size, gfp_flags,
- &urb->transfer_dma);
- if (mem == NULL) {
- usb_free_urb(urb);
- return i;
- }
-
- usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, ep_addr),
- mem, buf_size, complete_fn, context);
- urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- urb_array[i] = urb;
- }
- return i;
-}
-
-void free_all_urb_generic(struct urb **urb_array, int num)
-{
- int i;
- struct urb *urb;
-
- for (i = 0; i < num; i++) {
- urb = urb_array[i];
- if (urb) {
- usb_free_coherent(urb->dev,
- urb->transfer_buffer_length,
- urb->transfer_buffer,
- urb->transfer_dma);
- usb_free_urb(urb);
- urb_array[i] = NULL;
- }
- }
-}
-
-static int prepare_bulk_urb(struct video_data *video)
-{
- if (video->urb_array[0])
- return 0;
-
- alloc_bulk_urbs_generic(video->urb_array, SBUF_NUM,
- video->pd->udev, video->endpoint_addr,
- 0x2000, GFP_KERNEL,
- urb_complete_bulk, video->front);
- return 0;
-}
-
-/* free the URBs */
-static void free_all_urb(struct video_data *video)
-{
- free_all_urb_generic(video->urb_array, SBUF_NUM);
-}
-
-static void pd_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- videobuf_vmalloc_free(vb);
- vb->state = VIDEOBUF_NEEDS_INIT;
-}
-
-static void pd_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct front_face *front = q->priv_data;
- vb->state = VIDEOBUF_QUEUED;
- list_add_tail(&vb->queue, &front->active);
-}
-
-static int pd_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct front_face *front = q->priv_data;
- int rc;
-
- switch (front->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (VIDEOBUF_NEEDS_INIT == vb->state) {
- struct v4l2_pix_format *pix;
-
- pix = &front->pd->video_data.context.pix;
- vb->size = pix->sizeimage; /* real frame size */
- vb->width = pix->width;
- vb->height = pix->height;
- rc = videobuf_iolock(q, vb, NULL);
- if (rc < 0)
- return rc;
- }
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (VIDEOBUF_NEEDS_INIT == vb->state) {
- vb->size = front->pd->vbi_data.vbi_size;
- rc = videobuf_iolock(q, vb, NULL);
- if (rc < 0)
- return rc;
- }
- break;
- default:
- return -EINVAL;
- }
- vb->field = field;
- vb->state = VIDEOBUF_PREPARED;
- return 0;
-}
-
-static int fire_all_urb(struct video_data *video)
-{
- int i, ret;
-
- video->is_streaming = 1;
-
- for (i = 0; i < SBUF_NUM; i++) {
- ret = usb_submit_urb(video->urb_array[i], GFP_KERNEL);
- if (ret)
- log("(%d) failed: error %d", i, ret);
- }
- return ret;
-}
-
-static int start_video_stream(struct poseidon *pd)
-{
- struct video_data *video = &pd->video_data;
- s32 cmd_status;
-
- send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
- send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_START, &cmd_status);
-
- if (pd->cur_transfer_mode) {
- prepare_iso_urb(video);
- INIT_WORK(&video->bubble_work, iso_bubble_handler);
- } else {
- /* The bulk mode does not need a bubble handler */
- prepare_bulk_urb(video);
- }
- fire_all_urb(video);
- return 0;
-}
-
-static int pd_buf_setup(struct videobuf_queue *q, unsigned int *count,
- unsigned int *size)
-{
- struct front_face *front = q->priv_data;
- struct poseidon *pd = front->pd;
-
- switch (front->type) {
- default:
- return -EINVAL;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct video_data *video = &pd->video_data;
- struct v4l2_pix_format *pix = &video->context.pix;
-
- *size = PAGE_ALIGN(pix->sizeimage);/* page aligned frame size */
- if (*count < 4)
- *count = 4;
- if (1) {
- /* same in different altersetting */
- video->endpoint_addr = 0x82;
- video->vbi = &pd->vbi_data;
- video->vbi->video = video;
- video->pd = pd;
- video->lines_per_field = pix->height / 2;
- video->lines_size = pix->width * 2;
- video->front = front;
- }
- return start_video_stream(pd);
- }
-
- case V4L2_BUF_TYPE_VBI_CAPTURE: {
- struct vbi_data *vbi = &pd->vbi_data;
-
- *size = PAGE_ALIGN(vbi->vbi_size);
- log("size : %d", *size);
- if (*count == 0)
- *count = 4;
- }
- break;
- }
- return 0;
-}
-
-static struct videobuf_queue_ops pd_video_qops = {
- .buf_setup = pd_buf_setup,
- .buf_prepare = pd_buf_prepare,
- .buf_queue = pd_buf_queue,
- .buf_release = pd_buf_release,
-};
-
-static int vidioc_enum_fmt(struct file *file, void *fh,
- struct v4l2_fmtdesc *f)
-{
- if (ARRAY_SIZE(poseidon_formats) <= f->index)
- return -EINVAL;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- f->flags = 0;
- f->pixelformat = poseidon_formats[f->index].fourcc;
- strcpy(f->description, poseidon_formats[f->index].name);
- return 0;
-}
-
-static int vidioc_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
-{
- struct front_face *front = fh;
- struct poseidon *pd = front->pd;
-
- logs(front);
- f->fmt.pix = pd->video_data.context.pix;
- return 0;
-}
-
-static int vidioc_try_fmt(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- return 0;
-}
-
-/*
- * VLC calls VIDIOC_S_STD before VIDIOC_S_FMT, while
- * Mplayer calls them in the reverse order.
- */
-static int pd_vidioc_s_fmt(struct poseidon *pd, struct v4l2_pix_format *pix)
-{
- struct video_data *video = &pd->video_data;
- struct running_context *context = &video->context;
- struct v4l2_pix_format *pix_def = &context->pix;
- s32 ret = 0, cmd_status = 0, vid_resol;
-
- /* set the pixel format to firmware */
- if (pix->pixelformat == V4L2_PIX_FMT_RGB565) {
- vid_resol = TLG_TUNER_VID_FORMAT_RGB_565;
- } else {
- pix->pixelformat = V4L2_PIX_FMT_YUYV;
- vid_resol = TLG_TUNER_VID_FORMAT_YUV;
- }
- ret = send_set_req(pd, VIDEO_STREAM_FMT_SEL,
- vid_resol, &cmd_status);
-
- /* set the resolution to firmware */
- vid_resol = TLG_TUNE_VID_RES_720;
- switch (pix->width) {
- case 704:
- vid_resol = TLG_TUNE_VID_RES_704;
- break;
- default:
- pix->width = 720;
- case 720:
- break;
- }
- ret |= send_set_req(pd, VIDEO_ROSOLU_SEL,
- vid_resol, &cmd_status);
- if (ret || cmd_status)
- return -EBUSY;
-
- pix_def->pixelformat = pix->pixelformat; /* save it */
- pix->height = (context->tvnormid & V4L2_STD_525_60) ? 480 : 576;
-
- /* Compare with the default setting */
- if ((pix_def->width != pix->width)
- || (pix_def->height != pix->height)) {
- pix_def->width = pix->width;
- pix_def->height = pix->height;
- pix_def->bytesperline = pix->width * 2;
- pix_def->sizeimage = pix->width * pix->height * 2;
- }
- *pix = *pix_def;
-
- return 0;
-}
-
-static int vidioc_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
-{
- struct front_face *front = fh;
- struct poseidon *pd = front->pd;
-
- logs(front);
- /* stop VBI here */
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != f->type)
- return -EINVAL;
-
- mutex_lock(&pd->lock);
- if (pd->file_for_stream == NULL)
- pd->file_for_stream = file;
- else if (file != pd->file_for_stream) {
- mutex_unlock(&pd->lock);
- return -EINVAL;
- }
-
- pd_vidioc_s_fmt(pd, &f->fmt.pix);
- mutex_unlock(&pd->lock);
- return 0;
-}
-
-static int vidioc_g_fmt_vbi(struct file *file, void *fh,
- struct v4l2_format *v4l2_f)
-{
- struct front_face *front = fh;
- struct poseidon *pd = front->pd;
- struct v4l2_vbi_format *vbi_fmt = &v4l2_f->fmt.vbi;
-
- vbi_fmt->samples_per_line = 720 * 2;
- vbi_fmt->sampling_rate = 6750000 * 4;
- vbi_fmt->sample_format = V4L2_PIX_FMT_GREY;
- vbi_fmt->offset = 64 * 4; /*FIXME: why offset */
- if (pd->video_data.context.tvnormid & V4L2_STD_525_60) {
- vbi_fmt->start[0] = 10;
- vbi_fmt->start[1] = 264;
- vbi_fmt->count[0] = V4L_NTSC_VBI_LINES;
- vbi_fmt->count[1] = V4L_NTSC_VBI_LINES;
- } else {
- vbi_fmt->start[0] = 6;
- vbi_fmt->start[1] = 314;
- vbi_fmt->count[0] = V4L_PAL_VBI_LINES;
- vbi_fmt->count[1] = V4L_PAL_VBI_LINES;
- }
- vbi_fmt->flags = V4L2_VBI_UNSYNC;
- logs(front);
- return 0;
-}
-
-static int set_std(struct poseidon *pd, v4l2_std_id *norm)
-{
- struct video_data *video = &pd->video_data;
- struct vbi_data *vbi = &pd->vbi_data;
- struct running_context *context;
- struct v4l2_pix_format *pix;
- s32 i, ret = 0, cmd_status, param;
- int height;
-
- for (i = 0; i < POSEIDON_TVNORMS; i++) {
- if (*norm & poseidon_tvnorms[i].v4l2_id) {
- param = poseidon_tvnorms[i].tlg_tvnorm;
- log("name : %s", poseidon_tvnorms[i].name);
- goto found;
- }
- }
- return -EINVAL;
-found:
- mutex_lock(&pd->lock);
- ret = send_set_req(pd, VIDEO_STD_SEL, param, &cmd_status);
- if (ret || cmd_status)
- goto out;
-
- /* Set vbi size and check the height of the frame */
- context = &video->context;
- context->tvnormid = poseidon_tvnorms[i].v4l2_id;
- if (context->tvnormid & V4L2_STD_525_60) {
- vbi->vbi_size = V4L_NTSC_VBI_FRAMESIZE;
- height = 480;
- } else {
- vbi->vbi_size = V4L_PAL_VBI_FRAMESIZE;
- height = 576;
- }
-
- pix = &context->pix;
- if (pix->height != height) {
- pix->height = height;
- pix->sizeimage = pix->width * pix->height * 2;
- }
-
-out:
- mutex_unlock(&pd->lock);
- return ret;
-}
-
-static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *norm)
-{
- struct front_face *front = fh;
- logs(front);
- return set_std(front->pd, norm);
-}
-
-static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *in)
-{
- struct front_face *front = fh;
-
- if (in->index < 0 || in->index >= POSEIDON_INPUTS)
- return -EINVAL;
- strcpy(in->name, pd_inputs[in->index].name);
- in->type = V4L2_INPUT_TYPE_TUNER;
-
- /*
- * the audio input index mixed with this video input,
- * Poseidon only have one audio/video, set to "0"
- */
- in->audioset = 0;
- in->tuner = 0;
- in->std = V4L2_STD_ALL;
- in->status = 0;
- logs(front);
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
-{
- struct front_face *front = fh;
- struct poseidon *pd = front->pd;
- struct running_context *context = &pd->video_data.context;
-
- logs(front);
- *i = context->sig_index;
- return 0;
-}
-
-/* We can support several inputs */
-static int vidioc_s_input(struct file *file, void *fh, unsigned int i)
-{
- struct front_face *front = fh;
- struct poseidon *pd = front->pd;
- s32 ret, cmd_status;
-
- if (i < 0 || i >= POSEIDON_INPUTS)
- return -EINVAL;
- ret = send_set_req(pd, SGNL_SRC_SEL,
- pd_inputs[i].tlg_src, &cmd_status);
- if (ret)
- return ret;
-
- pd->video_data.context.sig_index = i;
- return 0;
-}
-
-static struct poseidon_control *check_control_id(__u32 id)
-{
- struct poseidon_control *control = &controls[0];
- int array_size = ARRAY_SIZE(controls);
-
- for (; control < &controls[array_size]; control++)
- if (control->v4l2_ctrl.id == id)
- return control;
- return NULL;
-}
-
-static int vidioc_queryctrl(struct file *file, void *fh,
- struct v4l2_queryctrl *a)
-{
- struct poseidon_control *control = NULL;
-
- control = check_control_id(a->id);
- if (!control)
- return -EINVAL;
-
- *a = control->v4l2_ctrl;
- return 0;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *ctrl)
-{
- struct front_face *front = fh;
- struct poseidon *pd = front->pd;
- struct poseidon_control *control = NULL;
- struct tuner_custom_parameter_s tuner_param;
- s32 ret = 0, cmd_status;
-
- control = check_control_id(ctrl->id);
- if (!control)
- return -EINVAL;
-
- mutex_lock(&pd->lock);
- ret = send_get_req(pd, TUNER_CUSTOM_PARAMETER, control->vc_id,
- &tuner_param, &cmd_status, sizeof(tuner_param));
- mutex_unlock(&pd->lock);
-
- if (ret || cmd_status)
- return -1;
-
- ctrl->value = tuner_param.param_value;
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a)
-{
- struct tuner_custom_parameter_s param = {0};
- struct poseidon_control *control = NULL;
- struct front_face *front = fh;
- struct poseidon *pd = front->pd;
- s32 ret = 0, cmd_status, params;
-
- control = check_control_id(a->id);
- if (!control)
- return -EINVAL;
-
- param.param_value = a->value;
- param.param_id = control->vc_id;
- params = *(s32 *)&param; /* temp code */
-
- mutex_lock(&pd->lock);
- ret = send_set_req(pd, TUNER_CUSTOM_PARAMETER, params, &cmd_status);
- ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
- mutex_unlock(&pd->lock);
-
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ/4);
- return ret;
-}
-
-/* Audio ioctls */
-static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
-{
- if (0 != a->index)
- return -EINVAL;
- a->capability = V4L2_AUDCAP_STEREO;
- strcpy(a->name, "USB audio in");
- /*Poseidon have no AVL function.*/
- a->mode = 0;
- return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
-{
- a->index = 0;
- a->capability = V4L2_AUDCAP_STEREO;
- strcpy(a->name, "USB audio in");
- a->mode = 0;
- return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
-{
- return (0 == a->index) ? 0 : -EINVAL;
-}
-
-/* Tuner ioctls */
-static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *tuner)
-{
- struct front_face *front = fh;
- struct poseidon *pd = front->pd;
- struct tuner_atv_sig_stat_s atv_stat;
- s32 count = 5, ret, cmd_status;
- int index;
-
- if (0 != tuner->index)
- return -EINVAL;
-
- mutex_lock(&pd->lock);
- ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_ANALOG_TV,
- &atv_stat, &cmd_status, sizeof(atv_stat));
-
- while (atv_stat.sig_lock_busy && count-- && !ret) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ);
-
- ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_ANALOG_TV,
- &atv_stat, &cmd_status, sizeof(atv_stat));
- }
- mutex_unlock(&pd->lock);
-
- if (debug_mode)
- log("P:%d,S:%d", atv_stat.sig_present, atv_stat.sig_strength);
-
- if (ret || cmd_status)
- tuner->signal = 0;
- else if (atv_stat.sig_present && !atv_stat.sig_strength)
- tuner->signal = 0xFFFF;
- else
- tuner->signal = (atv_stat.sig_strength * 255 / 10) << 8;
-
- strcpy(tuner->name, "Telegent Systems");
- tuner->type = V4L2_TUNER_ANALOG_TV;
- tuner->rangelow = TUNER_FREQ_MIN / 62500;
- tuner->rangehigh = TUNER_FREQ_MAX / 62500;
- tuner->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
- V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
- index = pd->video_data.context.audio_idx;
- tuner->rxsubchans = pd_audio_modes[index].v4l2_audio_sub;
- tuner->audmode = pd_audio_modes[index].v4l2_audio_mode;
- tuner->afc = 0;
- logs(front);
- return 0;
-}
-
-static int pd_vidioc_s_tuner(struct poseidon *pd, int index)
-{
- s32 ret = 0, cmd_status, param, audiomode;
-
- mutex_lock(&pd->lock);
- param = pd_audio_modes[index].tlg_audio_mode;
- ret = send_set_req(pd, TUNER_AUD_MODE, param, &cmd_status);
- audiomode = get_audio_std(pd->video_data.context.tvnormid);
- ret |= send_set_req(pd, TUNER_AUD_ANA_STD, audiomode,
- &cmd_status);
- if (!ret)
- pd->video_data.context.audio_idx = index;
- mutex_unlock(&pd->lock);
- return ret;
-}
-
-static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *a)
-{
- struct front_face *front = fh;
- struct poseidon *pd = front->pd;
- int index;
-
- if (0 != a->index)
- return -EINVAL;
- logs(front);
- for (index = 0; index < POSEIDON_AUDIOMODS; index++)
- if (a->audmode == pd_audio_modes[index].v4l2_audio_mode)
- return pd_vidioc_s_tuner(pd, index);
- return -EINVAL;
-}
-
-static int vidioc_g_frequency(struct file *file, void *fh,
- struct v4l2_frequency *freq)
-{
- struct front_face *front = fh;
- struct poseidon *pd = front->pd;
- struct running_context *context = &pd->video_data.context;
-
- if (0 != freq->tuner)
- return -EINVAL;
- freq->frequency = context->freq;
- freq->type = V4L2_TUNER_ANALOG_TV;
- return 0;
-}
-
-static int set_frequency(struct poseidon *pd, __u32 frequency)
-{
- s32 ret = 0, param, cmd_status;
- struct running_context *context = &pd->video_data.context;
-
- param = frequency * 62500 / 1000;
- if (param < TUNER_FREQ_MIN/1000 || param > TUNER_FREQ_MAX / 1000)
- return -EINVAL;
-
- mutex_lock(&pd->lock);
- ret = send_set_req(pd, TUNE_FREQ_SELECT, param, &cmd_status);
- ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
-
- msleep(250); /* wait for a while until the hardware is ready. */
- context->freq = frequency;
- mutex_unlock(&pd->lock);
- return ret;
-}
-
-static int vidioc_s_frequency(struct file *file, void *fh,
- struct v4l2_frequency *freq)
-{
- struct front_face *front = fh;
- struct poseidon *pd = front->pd;
-
- logs(front);
-#ifdef CONFIG_PM
- pd->pm_suspend = pm_video_suspend;
- pd->pm_resume = pm_video_resume;
-#endif
- return set_frequency(pd, freq->frequency);
-}
-
-static int vidioc_reqbufs(struct file *file, void *fh,
- struct v4l2_requestbuffers *b)
-{
- struct front_face *front = file->private_data;
- logs(front);
- return videobuf_reqbufs(&front->q, b);
-}
-
-static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
-{
- struct front_face *front = file->private_data;
- logs(front);
- return videobuf_querybuf(&front->q, b);
-}
-
-static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
-{
- struct front_face *front = file->private_data;
- return videobuf_qbuf(&front->q, b);
-}
-
-static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
-{
- struct front_face *front = file->private_data;
- return videobuf_dqbuf(&front->q, b, file->f_flags & O_NONBLOCK);
-}
-
-/* Just stop the URBs, do not free the URBs */
-static int usb_transfer_stop(struct video_data *video)
-{
- if (video->is_streaming) {
- int i;
- s32 cmd_status;
- struct poseidon *pd = video->pd;
-
- video->is_streaming = 0;
- for (i = 0; i < SBUF_NUM; ++i) {
- if (video->urb_array[i])
- usb_kill_urb(video->urb_array[i]);
- }
-
- send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP,
- &cmd_status);
- }
- return 0;
-}
-
-int stop_all_video_stream(struct poseidon *pd)
-{
- struct video_data *video = &pd->video_data;
- struct vbi_data *vbi = &pd->vbi_data;
-
- mutex_lock(&pd->lock);
- if (video->is_streaming) {
- struct front_face *front = video->front;
-
- /* stop the URBs */
- usb_transfer_stop(video);
- free_all_urb(video);
-
- /* stop the host side of VIDEO */
- videobuf_stop(&front->q);
- videobuf_mmap_free(&front->q);
-
- /* stop the host side of VBI */
- front = vbi->front;
- if (front) {
- videobuf_stop(&front->q);
- videobuf_mmap_free(&front->q);
- }
- }
- mutex_unlock(&pd->lock);
- return 0;
-}
-
-/*
- * The bubbles can seriously damage the video's quality,
- * though it occurs in very rare situation.
- */
-static void iso_bubble_handler(struct work_struct *w)
-{
- struct video_data *video;
- struct poseidon *pd;
-
- video = container_of(w, struct video_data, bubble_work);
- pd = video->pd;
-
- mutex_lock(&pd->lock);
- usb_transfer_stop(video);
- msleep(500);
- start_video_stream(pd);
- mutex_unlock(&pd->lock);
-}
-
-
-static int vidioc_streamon(struct file *file, void *fh,
- enum v4l2_buf_type type)
-{
- struct front_face *front = fh;
-
- logs(front);
- if (unlikely(type != front->type))
- return -EINVAL;
- return videobuf_streamon(&front->q);
-}
-
-static int vidioc_streamoff(struct file *file, void *fh,
- enum v4l2_buf_type type)
-{
- struct front_face *front = file->private_data;
-
- logs(front);
- if (unlikely(type != front->type))
- return -EINVAL;
- return videobuf_streamoff(&front->q);
-}
-
-/* Set the firmware's default values : need altersetting */
-static int pd_video_checkmode(struct poseidon *pd)
-{
- s32 ret = 0, cmd_status, audiomode;
-
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ/2);
-
- /* choose the altersetting */
- ret = usb_set_interface(pd->udev, 0,
- (pd->cur_transfer_mode ?
- ISO_3K_BULK_ALTERNATE_IFACE :
- BULK_ALTERNATE_IFACE));
- if (ret < 0)
- goto error;
-
- /* set default parameters for PAL-D , with the VBI enabled*/
- ret = set_tuner_mode(pd, TLG_MODE_ANALOG_TV);
- ret |= send_set_req(pd, SGNL_SRC_SEL,
- TLG_SIG_SRC_ANTENNA, &cmd_status);
- ret |= send_set_req(pd, VIDEO_STD_SEL,
- TLG_TUNE_VSTD_PAL_D, &cmd_status);
- ret |= send_set_req(pd, VIDEO_STREAM_FMT_SEL,
- TLG_TUNER_VID_FORMAT_YUV, &cmd_status);
- ret |= send_set_req(pd, VIDEO_ROSOLU_SEL,
- TLG_TUNE_VID_RES_720, &cmd_status);
- ret |= send_set_req(pd, TUNE_FREQ_SELECT, TUNER_FREQ_MIN, &cmd_status);
- ret |= send_set_req(pd, VBI_DATA_SEL, 1, &cmd_status);/* enable vbi */
-
- /* set the audio */
- audiomode = get_audio_std(pd->video_data.context.tvnormid);
- ret |= send_set_req(pd, TUNER_AUD_ANA_STD, audiomode, &cmd_status);
- ret |= send_set_req(pd, TUNER_AUD_MODE,
- TLG_TUNE_TVAUDIO_MODE_STEREO, &cmd_status);
- ret |= send_set_req(pd, AUDIO_SAMPLE_RATE_SEL,
- ATV_AUDIO_RATE_48K, &cmd_status);
-error:
- return ret;
-}
-
-#ifdef CONFIG_PM
-static int pm_video_suspend(struct poseidon *pd)
-{
- /* stop audio */
- pm_alsa_suspend(pd);
-
- /* stop and free all the URBs */
- usb_transfer_stop(&pd->video_data);
- free_all_urb(&pd->video_data);
-
- /* reset the interface */
- usb_set_interface(pd->udev, 0, 0);
- msleep(300);
- return 0;
-}
-
-static int restore_v4l2_context(struct poseidon *pd,
- struct running_context *context)
-{
- struct front_face *front = pd->video_data.front;
-
- pd_video_checkmode(pd);
-
- set_std(pd, &context->tvnormid);
- vidioc_s_input(NULL, front, context->sig_index);
- pd_vidioc_s_tuner(pd, context->audio_idx);
- pd_vidioc_s_fmt(pd, &context->pix);
- set_frequency(pd, context->freq);
- return 0;
-}
-
-static int pm_video_resume(struct poseidon *pd)
-{
- struct video_data *video = &pd->video_data;
-
- /* resume the video */
- /* [1] restore the origin V4L2 parameters */
- restore_v4l2_context(pd, &video->context);
-
- /* [2] initiate video copy variables */
- if (video->front->curr_frame)
- init_copy(video, 0);
-
- /* [3] fire urbs */
- start_video_stream(pd);
-
- /* resume the audio */
- pm_alsa_resume(pd);
- return 0;
-}
-#endif
-
-void set_debug_mode(struct video_device *vfd, int debug_mode)
-{
- vfd->debug = 0;
- if (debug_mode & 0x1)
- vfd->debug = V4L2_DEBUG_IOCTL;
- if (debug_mode & 0x2)
- vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
-}
-
-static void init_video_context(struct running_context *context)
-{
- context->sig_index = 0;
- context->audio_idx = 1; /* stereo */
- context->tvnormid = V4L2_STD_PAL_D;
- context->pix = (struct v4l2_pix_format) {
- .width = 720,
- .height = 576,
- .pixelformat = V4L2_PIX_FMT_YUYV,
- .field = V4L2_FIELD_INTERLACED,
- .bytesperline = 720 * 2,
- .sizeimage = 720 * 576 * 2,
- .colorspace = V4L2_COLORSPACE_SMPTE170M,
- .priv = 0
- };
-}
-
-static int pd_video_open(struct file *file)
-{
- struct video_device *vfd = video_devdata(file);
- struct poseidon *pd = video_get_drvdata(vfd);
- struct front_face *front = NULL;
- int ret = -ENOMEM;
-
- mutex_lock(&pd->lock);
- usb_autopm_get_interface(pd->interface);
-
- if (vfd->vfl_type == VFL_TYPE_GRABBER
- && !(pd->state & POSEIDON_STATE_ANALOG)) {
- front = kzalloc(sizeof(struct front_face), GFP_KERNEL);
- if (!front)
- goto out;
-
- pd->cur_transfer_mode = usb_transfer_mode;/* bulk or iso */
- init_video_context(&pd->video_data.context);
-
- ret = pd_video_checkmode(pd);
- if (ret < 0) {
- kfree(front);
- ret = -1;
- goto out;
- }
-
- pd->state |= POSEIDON_STATE_ANALOG;
- front->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- pd->video_data.users++;
- set_debug_mode(vfd, debug_mode);
-
- videobuf_queue_vmalloc_init(&front->q, &pd_video_qops,
- NULL, &front->queue_lock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,/* video is interlacd */
- sizeof(struct videobuf_buffer),/*it's enough*/
- front, NULL);
- } else if (vfd->vfl_type == VFL_TYPE_VBI
- && !(pd->state & POSEIDON_STATE_VBI)) {
- front = kzalloc(sizeof(struct front_face), GFP_KERNEL);
- if (!front)
- goto out;
-
- pd->state |= POSEIDON_STATE_VBI;
- front->type = V4L2_BUF_TYPE_VBI_CAPTURE;
- pd->vbi_data.front = front;
- pd->vbi_data.users++;
-
- videobuf_queue_vmalloc_init(&front->q, &pd_video_qops,
- NULL, &front->queue_lock,
- V4L2_BUF_TYPE_VBI_CAPTURE,
- V4L2_FIELD_NONE, /* vbi is NONE mode */
- sizeof(struct videobuf_buffer),
- front, NULL);
- } else {
- /* maybe add FM support here */
- log("other ");
- ret = -EINVAL;
- goto out;
- }
-
- front->pd = pd;
- front->curr_frame = NULL;
- INIT_LIST_HEAD(&front->active);
- spin_lock_init(&front->queue_lock);
-
- file->private_data = front;
- kref_get(&pd->kref);
-
- mutex_unlock(&pd->lock);
- return 0;
-out:
- usb_autopm_put_interface(pd->interface);
- mutex_unlock(&pd->lock);
- return ret;
-}
-
-static int pd_video_release(struct file *file)
-{
- struct front_face *front = file->private_data;
- struct poseidon *pd = front->pd;
- s32 cmd_status = 0;
-
- logs(front);
- mutex_lock(&pd->lock);
-
- if (front->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- pd->state &= ~POSEIDON_STATE_ANALOG;
-
- /* stop the device, and free the URBs */
- usb_transfer_stop(&pd->video_data);
- free_all_urb(&pd->video_data);
-
- /* stop the firmware */
- send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP,
- &cmd_status);
-
- pd->file_for_stream = NULL;
- pd->video_data.users--;
- } else if (front->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- pd->state &= ~POSEIDON_STATE_VBI;
- pd->vbi_data.front = NULL;
- pd->vbi_data.users--;
- }
- videobuf_stop(&front->q);
- videobuf_mmap_free(&front->q);
-
- usb_autopm_put_interface(pd->interface);
- mutex_unlock(&pd->lock);
-
- kfree(front);
- file->private_data = NULL;
- kref_put(&pd->kref, poseidon_delete);
- return 0;
-}
-
-static int pd_video_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct front_face *front = file->private_data;
- return videobuf_mmap_mapper(&front->q, vma);
-}
-
-static unsigned int pd_video_poll(struct file *file, poll_table *table)
-{
- struct front_face *front = file->private_data;
- return videobuf_poll_stream(file, &front->q, table);
-}
-
-static ssize_t pd_video_read(struct file *file, char __user *buffer,
- size_t count, loff_t *ppos)
-{
- struct front_face *front = file->private_data;
- return videobuf_read_stream(&front->q, buffer, count, ppos,
- 0, file->f_flags & O_NONBLOCK);
-}
-
-/* This struct works for both VIDEO and VBI */
-static const struct v4l2_file_operations pd_video_fops = {
- .owner = THIS_MODULE,
- .open = pd_video_open,
- .release = pd_video_release,
- .read = pd_video_read,
- .poll = pd_video_poll,
- .mmap = pd_video_mmap,
- .ioctl = video_ioctl2, /* maybe changed in future */
-};
-
-static const struct v4l2_ioctl_ops pd_video_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
-
- /* Video format */
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt,
- .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi, /* VBI */
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt,
-
- /* Input */
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_enum_input = vidioc_enum_input,
-
- /* Audio ioctls */
- .vidioc_enumaudio = vidioc_enumaudio,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
-
- /* Tuner ioctls */
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
-
- /* Buffer handlers */
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-
- /* Stream on/off */
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
-
- /* Control handling */
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
-};
-
-static struct video_device pd_video_template = {
- .name = "Telegent-Video",
- .fops = &pd_video_fops,
- .minor = -1,
- .release = video_device_release,
- .tvnorms = V4L2_STD_ALL,
- .ioctl_ops = &pd_video_ioctl_ops,
-};
-
-struct video_device *vdev_init(struct poseidon *pd, struct video_device *tmp)
-{
- struct video_device *vfd;
-
- vfd = video_device_alloc();
- if (vfd == NULL)
- return NULL;
- *vfd = *tmp;
- vfd->minor = -1;
- vfd->v4l2_dev = &pd->v4l2_dev;
- /*vfd->parent = &(pd->udev->dev); */
- vfd->release = video_device_release;
- video_set_drvdata(vfd, pd);
- return vfd;
-}
-
-void destroy_video_device(struct video_device **v_dev)
-{
- struct video_device *dev = *v_dev;
-
- if (dev == NULL)
- return;
-
- if (video_is_registered(dev))
- video_unregister_device(dev);
- else
- video_device_release(dev);
- *v_dev = NULL;
-}
-
-void pd_video_exit(struct poseidon *pd)
-{
- struct video_data *video = &pd->video_data;
- struct vbi_data *vbi = &pd->vbi_data;
-
- destroy_video_device(&video->v_dev);
- destroy_video_device(&vbi->v_dev);
- log();
-}
-
-int pd_video_init(struct poseidon *pd)
-{
- struct video_data *video = &pd->video_data;
- struct vbi_data *vbi = &pd->vbi_data;
- int ret = -ENOMEM;
-
- video->v_dev = vdev_init(pd, &pd_video_template);
- if (video->v_dev == NULL)
- goto out;
-
- ret = video_register_device(video->v_dev, VFL_TYPE_GRABBER, -1);
- if (ret != 0)
- goto out;
-
- /* VBI uses the same template as video */
- vbi->v_dev = vdev_init(pd, &pd_video_template);
- if (vbi->v_dev == NULL) {
- ret = -ENOMEM;
- goto out;
- }
- ret = video_register_device(vbi->v_dev, VFL_TYPE_VBI, -1);
- if (ret != 0)
- goto out;
- log("register VIDEO/VBI devices");
- return 0;
-out:
- log("VIDEO/VBI devices register failed, : %d", ret);
- pd_video_exit(pd);
- return ret;
-}
-
diff --git a/drivers/media/video/tlg2300/vendorcmds.h b/drivers/media/video/tlg2300/vendorcmds.h
deleted file mode 100644
index ba6f4ae3b2c..00000000000
--- a/drivers/media/video/tlg2300/vendorcmds.h
+++ /dev/null
@@ -1,243 +0,0 @@
-#ifndef VENDOR_CMD_H_
-#define VENDOR_CMD_H_
-
-#define BULK_ALTERNATE_IFACE (2)
-#define ISO_3K_BULK_ALTERNATE_IFACE (1)
-#define REQ_SET_CMD (0X00)
-#define REQ_GET_CMD (0X80)
-
-enum tlg__analog_audio_standard {
- TLG_TUNE_ASTD_NONE = 0x00000000,
- TLG_TUNE_ASTD_A2 = 0x00000001,
- TLG_TUNE_ASTD_NICAM = 0x00000002,
- TLG_TUNE_ASTD_EIAJ = 0x00000004,
- TLG_TUNE_ASTD_BTSC = 0x00000008,
- TLG_TUNE_ASTD_FM_US = 0x00000010,
- TLG_TUNE_ASTD_FM_EUR = 0x00000020,
- TLG_TUNE_ASTD_ALL = 0x0000003f
-};
-
-/*
- * identifiers for Custom Parameter messages.
- * @typedef cmd_custom_param_id_t
- */
-enum cmd_custom_param_id {
- CUST_PARM_ID_NONE = 0x00,
- CUST_PARM_ID_BRIGHTNESS_CTRL = 0x01,
- CUST_PARM_ID_CONTRAST_CTRL = 0x02,
- CUST_PARM_ID_HUE_CTRL = 0x03,
- CUST_PARM_ID_SATURATION_CTRL = 0x04,
- CUST_PARM_ID_AUDIO_SNR_THRESHOLD = 0x10,
- CUST_PARM_ID_AUDIO_AGC_THRESHOLD = 0x11,
- CUST_PARM_ID_MAX
-};
-
-struct tuner_custom_parameter_s {
- uint16_t param_id; /* Parameter identifier */
- uint16_t param_value; /* Parameter value */
-};
-
-struct tuner_ber_rate_s {
- uint32_t ber_rate; /* BER sample rate in seconds */
-};
-
-struct tuner_atv_sig_stat_s {
- uint32_t sig_present;
- uint32_t sig_locked;
- uint32_t sig_lock_busy;
- uint32_t sig_strength; /* milliDb */
- uint32_t tv_audio_chan; /* mono/stereo/sap*/
- uint32_t mvision_stat; /* macrovision status */
-};
-
-struct tuner_dtv_sig_stat_s {
- uint32_t sig_present; /* Boolean*/
- uint32_t sig_locked; /* Boolean */
- uint32_t sig_lock_busy; /* Boolean (Can this time-out?) */
- uint32_t sig_strength; /* milliDb*/
-};
-
-struct tuner_fm_sig_stat_s {
- uint32_t sig_present; /* Boolean*/
- uint32_t sig_locked; /* Boolean */
- uint32_t sig_lock_busy; /* Boolean */
- uint32_t sig_stereo_mono;/* TBD*/
- uint32_t sig_strength; /* milliDb*/
-};
-
-enum _tag_tlg_tune_srv_cmd {
- TLG_TUNE_PLAY_SVC_START = 1,
- TLG_TUNE_PLAY_SVC_STOP
-};
-
-enum _tag_tune_atv_audio_mode_caps {
- TLG_TUNE_TVAUDIO_MODE_MONO = 0x00000001,
- TLG_TUNE_TVAUDIO_MODE_STEREO = 0x00000002,
- TLG_TUNE_TVAUDIO_MODE_LANG_A = 0x00000010,/* Primary language*/
- TLG_TUNE_TVAUDIO_MODE_LANG_B = 0x00000020,/* 2nd avail language*/
- TLG_TUNE_TVAUDIO_MODE_LANG_C = 0x00000040
-};
-
-
-enum _tag_tuner_atv_audio_rates {
- ATV_AUDIO_RATE_NONE = 0x00,/* Audio not supported*/
- ATV_AUDIO_RATE_32K = 0x01,/* Audio rate = 32 KHz*/
- ATV_AUDIO_RATE_48K = 0x02, /* Audio rate = 48 KHz*/
- ATV_AUDIO_RATE_31_25K = 0x04 /* Audio rate = 31.25KHz */
-};
-
-enum _tag_tune_atv_vid_res_caps {
- TLG_TUNE_VID_RES_NONE = 0x00000000,
- TLG_TUNE_VID_RES_720 = 0x00000001,
- TLG_TUNE_VID_RES_704 = 0x00000002,
- TLG_TUNE_VID_RES_360 = 0x00000004
-};
-
-enum _tag_tuner_analog_video_format {
- TLG_TUNER_VID_FORMAT_YUV = 0x00000001,
- TLG_TUNER_VID_FORMAT_YCRCB = 0x00000002,
- TLG_TUNER_VID_FORMAT_RGB_565 = 0x00000004,
-};
-
-enum tlg_ext_audio_support {
- TLG_EXT_AUDIO_NONE = 0x00,/* No external audio input supported */
- TLG_EXT_AUDIO_LR = 0x01/* LR external audio inputs supported*/
-};
-
-enum {
- TLG_MODE_NONE = 0x00, /* No Mode specified*/
- TLG_MODE_ANALOG_TV = 0x01, /* Analog Television mode*/
- TLG_MODE_ANALOG_TV_UNCOMP = 0x01, /* Analog Television mode*/
- TLG_MODE_ANALOG_TV_COMP = 0x02, /* Analog TV mode (compressed)*/
- TLG_MODE_FM_RADIO = 0x04, /* FM Radio mode*/
- TLG_MODE_DVB_T = 0x08, /* Digital TV (DVB-T)*/
-};
-
-enum tlg_signal_sources_t {
- TLG_SIG_SRC_NONE = 0x00,/* Signal source not specified */
- TLG_SIG_SRC_ANTENNA = 0x01,/* Signal src is: Antenna */
- TLG_SIG_SRC_CABLE = 0x02,/* Signal src is: Coax Cable*/
- TLG_SIG_SRC_SVIDEO = 0x04,/* Signal src is: S_VIDEO */
- TLG_SIG_SRC_COMPOSITE = 0x08 /* Signal src is: Composite Video */
-};
-
-enum tuner_analog_video_standard {
- TLG_TUNE_VSTD_NONE = 0x00000000,
- TLG_TUNE_VSTD_NTSC_M = 0x00000001,
- TLG_TUNE_VSTD_NTSC_M_J = 0x00000002,/* Japan */
- TLG_TUNE_VSTD_PAL_B = 0x00000010,
- TLG_TUNE_VSTD_PAL_D = 0x00000020,
- TLG_TUNE_VSTD_PAL_G = 0x00000040,
- TLG_TUNE_VSTD_PAL_H = 0x00000080,
- TLG_TUNE_VSTD_PAL_I = 0x00000100,
- TLG_TUNE_VSTD_PAL_M = 0x00000200,
- TLG_TUNE_VSTD_PAL_N = 0x00000400,
- TLG_TUNE_VSTD_SECAM_B = 0x00001000,
- TLG_TUNE_VSTD_SECAM_D = 0x00002000,
- TLG_TUNE_VSTD_SECAM_G = 0x00004000,
- TLG_TUNE_VSTD_SECAM_H = 0x00008000,
- TLG_TUNE_VSTD_SECAM_K = 0x00010000,
- TLG_TUNE_VSTD_SECAM_K1 = 0x00020000,
- TLG_TUNE_VSTD_SECAM_L = 0x00040000,
- TLG_TUNE_VSTD_SECAM_L1 = 0x00080000,
- TLG_TUNE_VSTD_PAL_N_COMBO = 0x00100000
-};
-
-enum tlg_mode_caps {
- TLG_MODE_CAPS_NONE = 0x00, /* No Mode specified */
- TLG_MODE_CAPS_ANALOG_TV_UNCOMP = 0x01, /* Analog TV mode */
- TLG_MODE_CAPS_ANALOG_TV_COMP = 0x02, /* Analog TV (compressed)*/
- TLG_MODE_CAPS_FM_RADIO = 0x04, /* FM Radio mode */
- TLG_MODE_CAPS_DVB_T = 0x08, /* Digital TV (DVB-T) */
-};
-
-enum poseidon_vendor_cmds {
- LAST_CMD_STAT = 0x00,
- GET_CHIP_ID = 0x01,
- GET_FW_ID = 0x02,
- PRODUCT_CAPS = 0x03,
-
- TUNE_MODE_CAP_ATV = 0x10,
- TUNE_MODE_CAP_ATVCOMP = 0X10,
- TUNE_MODE_CAP_DVBT = 0x10,
- TUNE_MODE_CAP_FM = 0x10,
- TUNE_MODE_SELECT = 0x11,
- TUNE_FREQ_SELECT = 0x12,
- SGNL_SRC_SEL = 0x13,
-
- VIDEO_STD_SEL = 0x14,
- VIDEO_STREAM_FMT_SEL = 0x15,
- VIDEO_ROSOLU_AVAIL = 0x16,
- VIDEO_ROSOLU_SEL = 0x17,
- VIDEO_CONT_PROTECT = 0x20,
-
- VCR_TIMING_MODSEL = 0x21,
- EXT_AUDIO_CAP = 0x22,
- EXT_AUDIO_SEL = 0x23,
- TEST_PATTERN_SEL = 0x24,
- VBI_DATA_SEL = 0x25,
- AUDIO_SAMPLE_RATE_CAP = 0x28,
- AUDIO_SAMPLE_RATE_SEL = 0x29,
- TUNER_AUD_MODE = 0x2a,
- TUNER_AUD_MODE_AVAIL = 0x2b,
- TUNER_AUD_ANA_STD = 0x2c,
- TUNER_CUSTOM_PARAMETER = 0x2f,
-
- DVBT_TUNE_MODE_SEL = 0x30,
- DVBT_BANDW_CAP = 0x31,
- DVBT_BANDW_SEL = 0x32,
- DVBT_GUARD_INTERV_CAP = 0x33,
- DVBT_GUARD_INTERV_SEL = 0x34,
- DVBT_MODULATION_CAP = 0x35,
- DVBT_MODULATION_SEL = 0x36,
- DVBT_INNER_FEC_RATE_CAP = 0x37,
- DVBT_INNER_FEC_RATE_SEL = 0x38,
- DVBT_TRANS_MODE_CAP = 0x39,
- DVBT_TRANS_MODE_SEL = 0x3a,
- DVBT_SEARCH_RANG = 0x3c,
-
- TUNER_SETUP_ANALOG = 0x40,
- TUNER_SETUP_DIGITAL = 0x41,
- TUNER_SETUP_FM_RADIO = 0x42,
- TAKE_REQUEST = 0x43, /* Take effect of the command */
- PLAY_SERVICE = 0x44, /* Play start or Play stop */
- TUNER_STATUS = 0x45,
- TUNE_PROP_DVBT = 0x46,
- ERR_RATE_STATS = 0x47,
- TUNER_BER_RATE = 0x48,
-
- SCAN_CAPS = 0x50,
- SCAN_SETUP = 0x51,
- SCAN_SERVICE = 0x52,
- SCAN_STATS = 0x53,
-
- PID_SET = 0x58,
- PID_UNSET = 0x59,
- PID_LIST = 0x5a,
-
- IRD_CAP = 0x60,
- IRD_MODE_SEL = 0x61,
- IRD_SETUP = 0x62,
-
- PTM_MODE_CAP = 0x70,
- PTM_MODE_SEL = 0x71,
- PTM_SERVICE = 0x72,
- TUNER_REG_SCRIPT = 0x73,
- CMD_CHIP_RST = 0x74,
-};
-
-enum tlg_bw {
- TLG_BW_5 = 5,
- TLG_BW_6 = 6,
- TLG_BW_7 = 7,
- TLG_BW_8 = 8,
- TLG_BW_12 = 12,
- TLG_BW_15 = 15
-};
-
-struct cmd_firmware_vers_s {
- uint8_t fw_rev_major;
- uint8_t fw_rev_minor;
- uint16_t fw_patch;
-};
-#endif /* VENDOR_CMD_H_ */
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
deleted file mode 100644
index 809a75a558e..00000000000
--- a/drivers/media/video/tlv320aic23b.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * tlv320aic23b - driver version 0.0.1
- *
- * Copyright (C) 2006 Scott Alfter <salfter@ssai.us>
- *
- * Based on wm8775 driver
- *
- * Copyright (C) 2004 Ulf Eklund <ivtv at eklund.to>
- * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-
-MODULE_DESCRIPTION("tlv320aic23b driver");
-MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil");
-MODULE_LICENSE("GPL");
-
-
-/* ----------------------------------------------------------------------- */
-
-struct tlv320aic23b_state {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
-};
-
-static inline struct tlv320aic23b_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct tlv320aic23b_state, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct tlv320aic23b_state, hdl)->sd;
-}
-
-static int tlv320aic23b_write(struct v4l2_subdev *sd, int reg, u16 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int i;
-
- if ((reg < 0 || reg > 9) && (reg != 15)) {
- v4l2_err(sd, "Invalid register R%d\n", reg);
- return -1;
- }
-
- for (i = 0; i < 3; i++)
- if (i2c_smbus_write_byte_data(client,
- (reg << 1) | (val >> 8), val & 0xff) == 0)
- return 0;
- v4l2_err(sd, "I2C: cannot write %03x to register R%d\n", val, reg);
- return -1;
-}
-
-static int tlv320aic23b_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
-{
- switch (freq) {
- case 32000: /* set sample rate to 32 kHz */
- tlv320aic23b_write(sd, 8, 0x018);
- break;
- case 44100: /* set sample rate to 44.1 kHz */
- tlv320aic23b_write(sd, 8, 0x022);
- break;
- case 48000: /* set sample rate to 48 kHz */
- tlv320aic23b_write(sd, 8, 0x000);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int tlv320aic23b_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- tlv320aic23b_write(sd, 0, 0x180); /* mute both channels */
- /* set gain on both channels to +3.0 dB */
- if (!ctrl->val)
- tlv320aic23b_write(sd, 0, 0x119);
- return 0;
- }
- return -EINVAL;
-}
-
-static int tlv320aic23b_log_status(struct v4l2_subdev *sd)
-{
- struct tlv320aic23b_state *state = to_state(sd);
-
- v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_ctrl_ops tlv320aic23b_ctrl_ops = {
- .s_ctrl = tlv320aic23b_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops tlv320aic23b_core_ops = {
- .log_status = tlv320aic23b_log_status,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
-};
-
-static const struct v4l2_subdev_audio_ops tlv320aic23b_audio_ops = {
- .s_clock_freq = tlv320aic23b_s_clock_freq,
-};
-
-static const struct v4l2_subdev_ops tlv320aic23b_ops = {
- .core = &tlv320aic23b_core_ops,
- .audio = &tlv320aic23b_audio_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-/* i2c implementation */
-
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-
-static int tlv320aic23b_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct tlv320aic23b_state *state;
- struct v4l2_subdev *sd;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- state = kzalloc(sizeof(struct tlv320aic23b_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &tlv320aic23b_ops);
-
- /* Initialize tlv320aic23b */
-
- /* RESET */
- tlv320aic23b_write(sd, 15, 0x000);
- /* turn off DAC & mic input */
- tlv320aic23b_write(sd, 6, 0x00A);
- /* left-justified, 24-bit, master mode */
- tlv320aic23b_write(sd, 7, 0x049);
- /* set gain on both channels to +3.0 dB */
- tlv320aic23b_write(sd, 0, 0x119);
- /* set sample rate to 48 kHz */
- tlv320aic23b_write(sd, 8, 0x000);
- /* activate digital interface */
- tlv320aic23b_write(sd, 9, 0x001);
-
- v4l2_ctrl_handler_init(&state->hdl, 1);
- v4l2_ctrl_new_std(&state->hdl, &tlv320aic23b_ctrl_ops,
- V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
- sd->ctrl_handler = &state->hdl;
- if (state->hdl.error) {
- int err = state->hdl.error;
-
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return err;
- }
- v4l2_ctrl_handler_setup(&state->hdl);
- return 0;
-}
-
-static int tlv320aic23b_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct tlv320aic23b_state *state = to_state(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id tlv320aic23b_id[] = {
- { "tlv320aic23b", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id);
-
-static struct i2c_driver tlv320aic23b_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "tlv320aic23b",
- },
- .probe = tlv320aic23b_probe,
- .remove = tlv320aic23b_remove,
- .id_table = tlv320aic23b_id,
-};
-
-module_i2c_driver(tlv320aic23b_driver);
diff --git a/drivers/media/video/tm6000/Kconfig b/drivers/media/video/tm6000/Kconfig
deleted file mode 100644
index a43b77abd93..00000000000
--- a/drivers/media/video/tm6000/Kconfig
+++ /dev/null
@@ -1,33 +0,0 @@
-config VIDEO_TM6000
- tristate "TV Master TM5600/6000/6010 driver"
- depends on VIDEO_DEV && I2C && INPUT && RC_CORE && USB
- select VIDEO_TUNER
- select MEDIA_TUNER_XC2028
- select MEDIA_TUNER_XC5000
- select VIDEOBUF_VMALLOC
- help
- Support for TM5600/TM6000/TM6010 USB Device
-
- Since these cards have no MPEG decoder onboard, they transmit
- only compressed MPEG data over the usb bus, so you need
- an external software decoder to watch TV on your computer.
-
- Say Y if you own such a device and want to use it.
-
-config VIDEO_TM6000_ALSA
- tristate "TV Master TM5600/6000/6010 audio support"
- depends on VIDEO_TM6000 && SND
- select SND_PCM
- ---help---
- This is a video4linux driver for direct (DMA) audio for
- TM5600/TM6000/TM6010 USB Devices.
-
- To compile this driver as a module, choose M here: the
- module will be called tm6000-alsa.
-
-config VIDEO_TM6000_DVB
- tristate "DVB Support for tm6000 based TV cards"
- depends on VIDEO_TM6000 && DVB_CORE && USB
- select DVB_ZL10353
- ---help---
- This adds support for DVB cards based on the tm5600/tm6000 chip.
diff --git a/drivers/media/video/tm6000/Makefile b/drivers/media/video/tm6000/Makefile
deleted file mode 100644
index 395515b4a88..00000000000
--- a/drivers/media/video/tm6000/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-tm6000-y := tm6000-cards.o \
- tm6000-core.o \
- tm6000-i2c.o \
- tm6000-video.o \
- tm6000-stds.o \
- tm6000-input.o
-
-obj-$(CONFIG_VIDEO_TM6000) += tm6000.o
-obj-$(CONFIG_VIDEO_TM6000_ALSA) += tm6000-alsa.o
-obj-$(CONFIG_VIDEO_TM6000_DVB) += tm6000-dvb.o
-
-ccflags-y := -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/video/tm6000/tm6000-alsa.c b/drivers/media/video/tm6000/tm6000-alsa.c
deleted file mode 100644
index bd07ec70795..00000000000
--- a/drivers/media/video/tm6000/tm6000-alsa.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- *
- * Support for audio capture for tm5600/6000/6010
- * (c) 2007-2008 Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * Based on cx88-alsa.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/usb.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/control.h>
-#include <sound/initval.h>
-
-
-#include "tm6000.h"
-#include "tm6000-regs.h"
-
-#undef dprintk
-
-#define dprintk(level, fmt, arg...) do { \
- if (debug >= level) \
- printk(KERN_INFO "%s/1: " fmt, chip->core->name , ## arg); \
- } while (0)
-
-/****************************************************************************
- Module global static vars
- ****************************************************************************/
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-
-static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
-
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable tm6000x soundcard. default enabled.");
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for tm6000x capture interface(s).");
-
-
-/****************************************************************************
- Module macros
- ****************************************************************************/
-
-MODULE_DESCRIPTION("ALSA driver module for tm5600/tm6000/tm6010 based TV cards");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Trident,tm5600},"
- "{{Trident,tm6000},"
- "{{Trident,tm6010}");
-static unsigned int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debug messages");
-
-/****************************************************************************
- Module specific funtions
- ****************************************************************************/
-
-/*
- * BOARD Specific: Sets audio DMA
- */
-
-static int _tm6000_start_audio_dma(struct snd_tm6000_card *chip)
-{
- struct tm6000_core *core = chip->core;
-
- dprintk(1, "Starting audio DMA\n");
-
- /* Enables audio */
- tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_IF, 0x40, 0x40);
-
- tm6000_set_audio_bitrate(core, 48000);
-
- return 0;
-}
-
-/*
- * BOARD Specific: Resets audio DMA
- */
-static int _tm6000_stop_audio_dma(struct snd_tm6000_card *chip)
-{
- struct tm6000_core *core = chip->core;
-
- dprintk(1, "Stopping audio DMA\n");
-
- /* Disables audio */
- tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_IF, 0x00, 0x40);
-
- return 0;
-}
-
-static void dsp_buffer_free(struct snd_pcm_substream *substream)
-{
- struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
-
- dprintk(2, "Freeing buffer\n");
-
- vfree(substream->runtime->dma_area);
- substream->runtime->dma_area = NULL;
- substream->runtime->dma_bytes = 0;
-}
-
-static int dsp_buffer_alloc(struct snd_pcm_substream *substream, int size)
-{
- struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
-
- dprintk(2, "Allocating buffer\n");
-
- if (substream->runtime->dma_area) {
- if (substream->runtime->dma_bytes > size)
- return 0;
-
- dsp_buffer_free(substream);
- }
-
- substream->runtime->dma_area = vmalloc(size);
- if (!substream->runtime->dma_area)
- return -ENOMEM;
-
- substream->runtime->dma_bytes = size;
-
- return 0;
-}
-
-
-/****************************************************************************
- ALSA PCM Interface
- ****************************************************************************/
-
-/*
- * Digital hardware definition
- */
-#define DEFAULT_FIFO_SIZE 4096
-
-static struct snd_pcm_hardware snd_tm6000_digital_hw = {
- .info = SNDRV_PCM_INFO_BATCH |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
-
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .period_bytes_min = 64,
- .period_bytes_max = 12544,
- .periods_min = 2,
- .periods_max = 98,
- .buffer_bytes_max = 62720 * 8,
-};
-
-/*
- * audio pcm capture open callback
- */
-static int snd_tm6000_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- err = snd_pcm_hw_constraint_pow2(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0)
- goto _error;
-
- chip->substream = substream;
-
- runtime->hw = snd_tm6000_digital_hw;
- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
-
- return 0;
-_error:
- dprintk(1, "Error opening PCM!\n");
- return err;
-}
-
-/*
- * audio close callback
- */
-static int snd_tm6000_close(struct snd_pcm_substream *substream)
-{
- struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
- struct tm6000_core *core = chip->core;
-
- if (atomic_read(&core->stream_started) > 0) {
- atomic_set(&core->stream_started, 0);
- schedule_work(&core->wq_trigger);
- }
-
- return 0;
-}
-
-static int tm6000_fillbuf(struct tm6000_core *core, char *buf, int size)
-{
- struct snd_tm6000_card *chip = core->adev;
- struct snd_pcm_substream *substream = chip->substream;
- struct snd_pcm_runtime *runtime;
- int period_elapsed = 0;
- unsigned int stride, buf_pos;
- int length;
-
- if (atomic_read(&core->stream_started) == 0)
- return 0;
-
- if (!size || !substream) {
- dprintk(1, "substream was NULL\n");
- return -EINVAL;
- }
-
- runtime = substream->runtime;
- if (!runtime || !runtime->dma_area) {
- dprintk(1, "runtime was NULL\n");
- return -EINVAL;
- }
-
- buf_pos = chip->buf_pos;
- stride = runtime->frame_bits >> 3;
-
- if (stride == 0) {
- dprintk(1, "stride is zero\n");
- return -EINVAL;
- }
-
- length = size / stride;
- if (length == 0) {
- dprintk(1, "%s: length was zero\n", __func__);
- return -EINVAL;
- }
-
- dprintk(1, "Copying %d bytes at %p[%d] - buf size=%d x %d\n", size,
- runtime->dma_area, buf_pos,
- (unsigned int)runtime->buffer_size, stride);
-
- if (buf_pos + length >= runtime->buffer_size) {
- unsigned int cnt = runtime->buffer_size - buf_pos;
- memcpy(runtime->dma_area + buf_pos * stride, buf, cnt * stride);
- memcpy(runtime->dma_area, buf + cnt * stride,
- length * stride - cnt * stride);
- } else
- memcpy(runtime->dma_area + buf_pos * stride, buf,
- length * stride);
-
- snd_pcm_stream_lock(substream);
-
- chip->buf_pos += length;
- if (chip->buf_pos >= runtime->buffer_size)
- chip->buf_pos -= runtime->buffer_size;
-
- chip->period_pos += length;
- if (chip->period_pos >= runtime->period_size) {
- chip->period_pos -= runtime->period_size;
- period_elapsed = 1;
- }
-
- snd_pcm_stream_unlock(substream);
-
- if (period_elapsed)
- snd_pcm_period_elapsed(substream);
-
- return 0;
-}
-
-/*
- * hw_params callback
- */
-static int snd_tm6000_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- int size, rc;
-
- size = params_period_bytes(hw_params) * params_periods(hw_params);
-
- rc = dsp_buffer_alloc(substream, size);
- if (rc < 0)
- return rc;
-
- return 0;
-}
-
-/*
- * hw free callback
- */
-static int snd_tm6000_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
- struct tm6000_core *core = chip->core;
-
- if (atomic_read(&core->stream_started) > 0) {
- atomic_set(&core->stream_started, 0);
- schedule_work(&core->wq_trigger);
- }
-
- dsp_buffer_free(substream);
- return 0;
-}
-
-/*
- * prepare callback
- */
-static int snd_tm6000_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
-
- chip->buf_pos = 0;
- chip->period_pos = 0;
-
- return 0;
-}
-
-
-/*
- * trigger callback
- */
-static void audio_trigger(struct work_struct *work)
-{
- struct tm6000_core *core = container_of(work, struct tm6000_core,
- wq_trigger);
- struct snd_tm6000_card *chip = core->adev;
-
- if (atomic_read(&core->stream_started)) {
- dprintk(1, "starting capture");
- _tm6000_start_audio_dma(chip);
- } else {
- dprintk(1, "stopping capture");
- _tm6000_stop_audio_dma(chip);
- }
-}
-
-static int snd_tm6000_card_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
- struct tm6000_core *core = chip->core;
- int err = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
- case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
- case SNDRV_PCM_TRIGGER_START:
- atomic_set(&core->stream_started, 1);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
- case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
- case SNDRV_PCM_TRIGGER_STOP:
- atomic_set(&core->stream_started, 0);
- break;
- default:
- err = -EINVAL;
- break;
- }
- schedule_work(&core->wq_trigger);
-
- return err;
-}
-/*
- * pointer callback
- */
-static snd_pcm_uframes_t snd_tm6000_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
-
- return chip->buf_pos;
-}
-
-static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
- unsigned long offset)
-{
- void *pageptr = subs->runtime->dma_area + offset;
-
- return vmalloc_to_page(pageptr);
-}
-
-/*
- * operators
- */
-static struct snd_pcm_ops snd_tm6000_pcm_ops = {
- .open = snd_tm6000_pcm_open,
- .close = snd_tm6000_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_tm6000_hw_params,
- .hw_free = snd_tm6000_hw_free,
- .prepare = snd_tm6000_prepare,
- .trigger = snd_tm6000_card_trigger,
- .pointer = snd_tm6000_pointer,
- .page = snd_pcm_get_vmalloc_page,
-};
-
-/*
- * create a PCM device
- */
-
-/* FIXME: Control interface - How to control volume/mute? */
-
-/****************************************************************************
- Basic Flow for Sound Devices
- ****************************************************************************/
-
-/*
- * Alsa Constructor - Component probe
- */
-static int tm6000_audio_init(struct tm6000_core *dev)
-{
- struct snd_card *card;
- struct snd_tm6000_card *chip;
- int rc;
- static int devnr;
- char component[14];
- struct snd_pcm *pcm;
-
- if (!dev)
- return 0;
-
- if (devnr >= SNDRV_CARDS)
- return -ENODEV;
-
- if (!enable[devnr])
- return -ENOENT;
-
- rc = snd_card_create(index[devnr], "tm6000", THIS_MODULE, 0, &card);
- if (rc < 0) {
- snd_printk(KERN_ERR "cannot create card instance %d\n", devnr);
- return rc;
- }
- strcpy(card->driver, "tm6000-alsa");
- strcpy(card->shortname, "TM5600/60x0");
- sprintf(card->longname, "TM5600/60x0 Audio at bus %d device %d",
- dev->udev->bus->busnum, dev->udev->devnum);
-
- sprintf(component, "USB%04x:%04x",
- le16_to_cpu(dev->udev->descriptor.idVendor),
- le16_to_cpu(dev->udev->descriptor.idProduct));
- snd_component_add(card, component);
- snd_card_set_dev(card, &dev->udev->dev);
-
- chip = kzalloc(sizeof(struct snd_tm6000_card), GFP_KERNEL);
- if (!chip) {
- rc = -ENOMEM;
- goto error;
- }
-
- chip->core = dev;
- chip->card = card;
- dev->adev = chip;
- spin_lock_init(&chip->reg_lock);
-
- rc = snd_pcm_new(card, "TM6000 Audio", 0, 0, 1, &pcm);
- if (rc < 0)
- goto error_chip;
-
- pcm->info_flags = 0;
- pcm->private_data = chip;
- strcpy(pcm->name, "Trident TM5600/60x0");
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_tm6000_pcm_ops);
-
- INIT_WORK(&dev->wq_trigger, audio_trigger);
- rc = snd_card_register(card);
- if (rc < 0)
- goto error_chip;
-
- dprintk(1, "Registered audio driver for %s\n", card->longname);
-
- return 0;
-
-error_chip:
- kfree(chip);
- dev->adev = NULL;
-error:
- snd_card_free(card);
- return rc;
-}
-
-static int tm6000_audio_fini(struct tm6000_core *dev)
-{
- struct snd_tm6000_card *chip = dev->adev;
-
- if (!dev)
- return 0;
-
- if (!chip)
- return 0;
-
- if (!chip->card)
- return 0;
-
- snd_card_free(chip->card);
- chip->card = NULL;
- kfree(chip);
- dev->adev = NULL;
-
- return 0;
-}
-
-static struct tm6000_ops audio_ops = {
- .type = TM6000_AUDIO,
- .name = "TM6000 Audio Extension",
- .init = tm6000_audio_init,
- .fini = tm6000_audio_fini,
- .fillbuf = tm6000_fillbuf,
-};
-
-static int __init tm6000_alsa_register(void)
-{
- return tm6000_register_extension(&audio_ops);
-}
-
-static void __exit tm6000_alsa_unregister(void)
-{
- tm6000_unregister_extension(&audio_ops);
-}
-
-module_init(tm6000_alsa_register);
-module_exit(tm6000_alsa_unregister);
diff --git a/drivers/media/video/tm6000/tm6000-cards.c b/drivers/media/video/tm6000/tm6000-cards.c
deleted file mode 100644
index 307d8c5fb7c..00000000000
--- a/drivers/media/video/tm6000/tm6000-cards.c
+++ /dev/null
@@ -1,1413 +0,0 @@
-/*
- * tm6000-cards.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/usb.h>
-#include <linux/slab.h>
-#include <media/v4l2-common.h>
-#include <media/tuner.h>
-#include <media/tvaudio.h>
-#include <media/i2c-addr.h>
-#include <media/rc-map.h>
-
-#include "tm6000.h"
-#include "tm6000-regs.h"
-#include "tuner-xc2028.h"
-#include "xc5000.h"
-
-#define TM6000_BOARD_UNKNOWN 0
-#define TM5600_BOARD_GENERIC 1
-#define TM6000_BOARD_GENERIC 2
-#define TM6010_BOARD_GENERIC 3
-#define TM5600_BOARD_10MOONS_UT821 4
-#define TM5600_BOARD_10MOONS_UT330 5
-#define TM6000_BOARD_ADSTECH_DUAL_TV 6
-#define TM6000_BOARD_FREECOM_AND_SIMILAR 7
-#define TM6000_BOARD_ADSTECH_MINI_DUAL_TV 8
-#define TM6010_BOARD_HAUPPAUGE_900H 9
-#define TM6010_BOARD_BEHOLD_WANDER 10
-#define TM6010_BOARD_BEHOLD_VOYAGER 11
-#define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12
-#define TM6010_BOARD_TWINHAN_TU501 13
-#define TM6010_BOARD_BEHOLD_WANDER_LITE 14
-#define TM6010_BOARD_BEHOLD_VOYAGER_LITE 15
-#define TM5600_BOARD_TERRATEC_GRABSTER 16
-
-#define is_generic(model) ((model == TM6000_BOARD_UNKNOWN) || \
- (model == TM5600_BOARD_GENERIC) || \
- (model == TM6000_BOARD_GENERIC) || \
- (model == TM6010_BOARD_GENERIC))
-
-#define TM6000_MAXBOARDS 16
-static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET };
-
-module_param_array(card, int, NULL, 0444);
-
-static unsigned long tm6000_devused;
-
-
-struct tm6000_board {
- char *name;
- char eename[16]; /* EEPROM name */
- unsigned eename_size; /* size of EEPROM name */
- unsigned eename_pos; /* Position where it appears at ROM */
-
- struct tm6000_capabilities caps;
-
- enum tm6000_devtype type; /* variant of the chipset */
- int tuner_type; /* type of the tuner */
- int tuner_addr; /* tuner address */
- int demod_addr; /* demodulator address */
-
- struct tm6000_gpio gpio;
-
- struct tm6000_input vinput[3];
- struct tm6000_input rinput;
-
- char *ir_codes;
-};
-
-static struct tm6000_board tm6000_boards[] = {
- [TM6000_BOARD_UNKNOWN] = {
- .name = "Unknown tm6000 video grabber",
- .caps = {
- .has_tuner = 1,
- .has_eeprom = 1,
- },
- .gpio = {
- .tuner_reset = TM6000_GPIO_1,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_ADC1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- },
- [TM5600_BOARD_GENERIC] = {
- .name = "Generic tm5600 board",
- .type = TM5600,
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0xc2 >> 1,
- .caps = {
- .has_tuner = 1,
- .has_eeprom = 1,
- },
- .gpio = {
- .tuner_reset = TM6000_GPIO_1,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_ADC1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- },
- [TM6000_BOARD_GENERIC] = {
- .name = "Generic tm6000 board",
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0xc2 >> 1,
- .caps = {
- .has_tuner = 1,
- .has_eeprom = 1,
- },
- .gpio = {
- .tuner_reset = TM6000_GPIO_1,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_ADC1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- },
- [TM6010_BOARD_GENERIC] = {
- .name = "Generic tm6010 board",
- .type = TM6010,
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0xc2 >> 1,
- .demod_addr = 0x1e >> 1,
- .caps = {
- .has_tuner = 1,
- .has_dvb = 1,
- .has_zl10353 = 1,
- .has_eeprom = 1,
- .has_remote = 1,
- },
- .gpio = {
- .tuner_reset = TM6010_GPIO_2,
- .tuner_on = TM6010_GPIO_3,
- .demod_reset = TM6010_GPIO_1,
- .demod_on = TM6010_GPIO_4,
- .power_led = TM6010_GPIO_7,
- .dvb_led = TM6010_GPIO_5,
- .ir = TM6010_GPIO_0,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_SIF1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- },
- [TM5600_BOARD_10MOONS_UT821] = {
- .name = "10Moons UT 821",
- .tuner_type = TUNER_XC2028,
- .eename = { '1', '0', 'M', 'O', 'O', 'N', 'S', '5', '6', '0', '0', 0xff, 0x45, 0x5b},
- .eename_size = 14,
- .eename_pos = 0x14,
- .type = TM5600,
- .tuner_addr = 0xc2 >> 1,
- .caps = {
- .has_tuner = 1,
- .has_eeprom = 1,
- },
- .gpio = {
- .tuner_reset = TM6000_GPIO_1,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_ADC1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- },
- [TM5600_BOARD_10MOONS_UT330] = {
- .name = "10Moons UT 330",
- .tuner_type = TUNER_PHILIPS_FQ1216AME_MK4,
- .tuner_addr = 0xc8 >> 1,
- .caps = {
- .has_tuner = 1,
- .has_dvb = 0,
- .has_zl10353 = 0,
- .has_eeprom = 1,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_ADC1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- },
- [TM6000_BOARD_ADSTECH_DUAL_TV] = {
- .name = "ADSTECH Dual TV USB",
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0xc8 >> 1,
- .caps = {
- .has_tuner = 1,
- .has_tda9874 = 1,
- .has_dvb = 1,
- .has_zl10353 = 1,
- .has_eeprom = 1,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_ADC1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- },
- [TM6000_BOARD_FREECOM_AND_SIMILAR] = {
- .name = "Freecom Hybrid Stick / Moka DVB-T Receiver Dual",
- .tuner_type = TUNER_XC2028, /* has a XC3028 */
- .tuner_addr = 0xc2 >> 1,
- .demod_addr = 0x1e >> 1,
- .caps = {
- .has_tuner = 1,
- .has_dvb = 1,
- .has_zl10353 = 1,
- .has_eeprom = 0,
- .has_remote = 1,
- },
- .gpio = {
- .tuner_reset = TM6000_GPIO_4,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_ADC1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- },
- [TM6000_BOARD_ADSTECH_MINI_DUAL_TV] = {
- .name = "ADSTECH Mini Dual TV USB",
- .tuner_type = TUNER_XC2028, /* has a XC3028 */
- .tuner_addr = 0xc8 >> 1,
- .demod_addr = 0x1e >> 1,
- .caps = {
- .has_tuner = 1,
- .has_dvb = 1,
- .has_zl10353 = 1,
- .has_eeprom = 0,
- },
- .gpio = {
- .tuner_reset = TM6000_GPIO_4,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_ADC1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- },
- [TM6010_BOARD_HAUPPAUGE_900H] = {
- .name = "Hauppauge WinTV HVR-900H / WinTV USB2-Stick",
- .eename = { 'H', 0, 'V', 0, 'R', 0, '9', 0, '0', 0, '0', 0, 'H', 0 },
- .eename_size = 14,
- .eename_pos = 0x42,
- .tuner_type = TUNER_XC2028, /* has a XC3028 */
- .tuner_addr = 0xc2 >> 1,
- .demod_addr = 0x1e >> 1,
- .type = TM6010,
- .ir_codes = RC_MAP_HAUPPAUGE,
- .caps = {
- .has_tuner = 1,
- .has_dvb = 1,
- .has_zl10353 = 1,
- .has_eeprom = 1,
- .has_remote = 1,
- },
- .gpio = {
- .tuner_reset = TM6010_GPIO_2,
- .tuner_on = TM6010_GPIO_3,
- .demod_reset = TM6010_GPIO_1,
- .demod_on = TM6010_GPIO_4,
- .power_led = TM6010_GPIO_7,
- .dvb_led = TM6010_GPIO_5,
- .ir = TM6010_GPIO_0,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_SIF1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- },
- [TM6010_BOARD_BEHOLD_WANDER] = {
- .name = "Beholder Wander DVB-T/TV/FM USB2.0",
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0xc2 >> 1,
- .demod_addr = 0x1e >> 1,
- .type = TM6010,
- .caps = {
- .has_tuner = 1,
- .has_dvb = 1,
- .has_zl10353 = 1,
- .has_eeprom = 1,
- .has_remote = 1,
- .has_radio = 1,
- },
- .gpio = {
- .tuner_reset = TM6010_GPIO_0,
- .demod_reset = TM6010_GPIO_1,
- .power_led = TM6010_GPIO_6,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_SIF1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- .rinput = {
- .type = TM6000_INPUT_RADIO,
- .amux = TM6000_AMUX_ADC1,
- },
- },
- [TM6010_BOARD_BEHOLD_VOYAGER] = {
- .name = "Beholder Voyager TV/FM USB2.0",
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0xc2 >> 1,
- .type = TM6010,
- .caps = {
- .has_tuner = 1,
- .has_dvb = 0,
- .has_zl10353 = 0,
- .has_eeprom = 1,
- .has_remote = 1,
- .has_radio = 1,
- },
- .gpio = {
- .tuner_reset = TM6010_GPIO_0,
- .power_led = TM6010_GPIO_6,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_SIF1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- .rinput = {
- .type = TM6000_INPUT_RADIO,
- .amux = TM6000_AMUX_ADC1,
- },
- },
- [TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = {
- .name = "Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick",
- .tuner_type = TUNER_XC2028, /* has a XC3028 */
- .tuner_addr = 0xc2 >> 1,
- .demod_addr = 0x1e >> 1,
- .type = TM6010,
- .caps = {
- .has_tuner = 1,
- .has_dvb = 1,
- .has_zl10353 = 1,
- .has_eeprom = 1,
- .has_remote = 1,
- .has_radio = 1,
- },
- .gpio = {
- .tuner_reset = TM6010_GPIO_2,
- .tuner_on = TM6010_GPIO_3,
- .demod_reset = TM6010_GPIO_1,
- .demod_on = TM6010_GPIO_4,
- .power_led = TM6010_GPIO_7,
- .dvb_led = TM6010_GPIO_5,
- .ir = TM6010_GPIO_0,
- },
- .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS,
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_SIF1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- .rinput = {
- .type = TM6000_INPUT_RADIO,
- .amux = TM6000_AMUX_SIF1,
- },
- },
- [TM5600_BOARD_TERRATEC_GRABSTER] = {
- .name = "Terratec Grabster AV 150/250 MX",
- .type = TM5600,
- .tuner_type = TUNER_ABSENT,
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_ADC1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- },
- [TM6010_BOARD_TWINHAN_TU501] = {
- .name = "Twinhan TU501(704D1)",
- .tuner_type = TUNER_XC2028, /* has a XC3028 */
- .tuner_addr = 0xc2 >> 1,
- .demod_addr = 0x1e >> 1,
- .type = TM6010,
- .caps = {
- .has_tuner = 1,
- .has_dvb = 1,
- .has_zl10353 = 1,
- .has_eeprom = 1,
- .has_remote = 1,
- },
- .gpio = {
- .tuner_reset = TM6010_GPIO_2,
- .tuner_on = TM6010_GPIO_3,
- .demod_reset = TM6010_GPIO_1,
- .demod_on = TM6010_GPIO_4,
- .power_led = TM6010_GPIO_7,
- .dvb_led = TM6010_GPIO_5,
- .ir = TM6010_GPIO_0,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_SIF1,
- }, {
- .type = TM6000_INPUT_COMPOSITE1,
- .vmux = TM6000_VMUX_VIDEO_A,
- .amux = TM6000_AMUX_ADC2,
- }, {
- .type = TM6000_INPUT_SVIDEO,
- .vmux = TM6000_VMUX_VIDEO_AB,
- .amux = TM6000_AMUX_ADC2,
- },
- },
- },
- [TM6010_BOARD_BEHOLD_WANDER_LITE] = {
- .name = "Beholder Wander Lite DVB-T/TV/FM USB2.0",
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0xc2 >> 1,
- .demod_addr = 0x1e >> 1,
- .type = TM6010,
- .caps = {
- .has_tuner = 1,
- .has_dvb = 1,
- .has_zl10353 = 1,
- .has_eeprom = 1,
- .has_remote = 0,
- .has_radio = 1,
- },
- .gpio = {
- .tuner_reset = TM6010_GPIO_0,
- .demod_reset = TM6010_GPIO_1,
- .power_led = TM6010_GPIO_6,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_SIF1,
- },
- },
- .rinput = {
- .type = TM6000_INPUT_RADIO,
- .amux = TM6000_AMUX_ADC1,
- },
- },
- [TM6010_BOARD_BEHOLD_VOYAGER_LITE] = {
- .name = "Beholder Voyager Lite TV/FM USB2.0",
- .tuner_type = TUNER_XC5000,
- .tuner_addr = 0xc2 >> 1,
- .type = TM6010,
- .caps = {
- .has_tuner = 1,
- .has_dvb = 0,
- .has_zl10353 = 0,
- .has_eeprom = 1,
- .has_remote = 0,
- .has_radio = 1,
- },
- .gpio = {
- .tuner_reset = TM6010_GPIO_0,
- .power_led = TM6010_GPIO_6,
- },
- .vinput = { {
- .type = TM6000_INPUT_TV,
- .vmux = TM6000_VMUX_VIDEO_B,
- .amux = TM6000_AMUX_SIF1,
- },
- },
- .rinput = {
- .type = TM6000_INPUT_RADIO,
- .amux = TM6000_AMUX_ADC1,
- },
- },
-};
-
-/* table of devices that work with this driver */
-static struct usb_device_id tm6000_id_table[] = {
- { USB_DEVICE(0x6000, 0x0001), .driver_info = TM5600_BOARD_GENERIC },
- { USB_DEVICE(0x6000, 0x0002), .driver_info = TM6010_BOARD_GENERIC },
- { USB_DEVICE(0x06e1, 0xf332), .driver_info = TM6000_BOARD_ADSTECH_DUAL_TV },
- { USB_DEVICE(0x14aa, 0x0620), .driver_info = TM6000_BOARD_FREECOM_AND_SIMILAR },
- { USB_DEVICE(0x06e1, 0xb339), .driver_info = TM6000_BOARD_ADSTECH_MINI_DUAL_TV },
- { USB_DEVICE(0x2040, 0x6600), .driver_info = TM6010_BOARD_HAUPPAUGE_900H },
- { USB_DEVICE(0x2040, 0x6601), .driver_info = TM6010_BOARD_HAUPPAUGE_900H },
- { USB_DEVICE(0x2040, 0x6610), .driver_info = TM6010_BOARD_HAUPPAUGE_900H },
- { USB_DEVICE(0x2040, 0x6611), .driver_info = TM6010_BOARD_HAUPPAUGE_900H },
- { USB_DEVICE(0x6000, 0xdec0), .driver_info = TM6010_BOARD_BEHOLD_WANDER },
- { USB_DEVICE(0x6000, 0xdec1), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER },
- { USB_DEVICE(0x0ccd, 0x0086), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
- { USB_DEVICE(0x0ccd, 0x00A5), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
- { USB_DEVICE(0x0ccd, 0x0079), .driver_info = TM5600_BOARD_TERRATEC_GRABSTER },
- { USB_DEVICE(0x13d3, 0x3240), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
- { USB_DEVICE(0x13d3, 0x3241), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
- { USB_DEVICE(0x13d3, 0x3243), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
- { USB_DEVICE(0x13d3, 0x3264), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
- { USB_DEVICE(0x6000, 0xdec2), .driver_info = TM6010_BOARD_BEHOLD_WANDER_LITE },
- { USB_DEVICE(0x6000, 0xdec3), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER_LITE },
- { }
-};
-MODULE_DEVICE_TABLE(usb, tm6000_id_table);
-
-/* Control power led for show some activity */
-void tm6000_flash_led(struct tm6000_core *dev, u8 state)
-{
- /* Power LED unconfigured */
- if (!dev->gpio.power_led)
- return;
-
- /* ON Power LED */
- if (state) {
- switch (dev->model) {
- case TM6010_BOARD_HAUPPAUGE_900H:
- case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
- case TM6010_BOARD_TWINHAN_TU501:
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.power_led, 0x00);
- break;
- case TM6010_BOARD_BEHOLD_WANDER:
- case TM6010_BOARD_BEHOLD_VOYAGER:
- case TM6010_BOARD_BEHOLD_WANDER_LITE:
- case TM6010_BOARD_BEHOLD_VOYAGER_LITE:
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.power_led, 0x01);
- break;
- }
- }
- /* OFF Power LED */
- else {
- switch (dev->model) {
- case TM6010_BOARD_HAUPPAUGE_900H:
- case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
- case TM6010_BOARD_TWINHAN_TU501:
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.power_led, 0x01);
- break;
- case TM6010_BOARD_BEHOLD_WANDER:
- case TM6010_BOARD_BEHOLD_VOYAGER:
- case TM6010_BOARD_BEHOLD_WANDER_LITE:
- case TM6010_BOARD_BEHOLD_VOYAGER_LITE:
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.power_led, 0x00);
- break;
- }
- }
-}
-
-/* Tuner callback to provide the proper gpio changes needed for xc5000 */
-int tm6000_xc5000_callback(void *ptr, int component, int command, int arg)
-{
- int rc = 0;
- struct tm6000_core *dev = ptr;
-
- if (dev->tuner_type != TUNER_XC5000)
- return 0;
-
- switch (command) {
- case XC5000_TUNER_RESET:
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.tuner_reset, 0x01);
- msleep(15);
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.tuner_reset, 0x00);
- msleep(15);
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.tuner_reset, 0x01);
- break;
- }
- return rc;
-}
-EXPORT_SYMBOL_GPL(tm6000_xc5000_callback);
-
-/* Tuner callback to provide the proper gpio changes needed for xc2028 */
-
-int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
-{
- int rc = 0;
- struct tm6000_core *dev = ptr;
-
- if (dev->tuner_type != TUNER_XC2028)
- return 0;
-
- switch (command) {
- case XC2028_RESET_CLK:
- tm6000_ir_wait(dev, 0);
-
- tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT,
- 0x02, arg);
- msleep(10);
- rc = tm6000_i2c_reset(dev, 10);
- break;
- case XC2028_TUNER_RESET:
- /* Reset codes during load firmware */
- switch (arg) {
- case 0:
- /* newer tuner can faster reset */
- switch (dev->model) {
- case TM5600_BOARD_10MOONS_UT821:
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.tuner_reset, 0x01);
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- 0x300, 0x01);
- msleep(10);
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.tuner_reset, 0x00);
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- 0x300, 0x00);
- msleep(10);
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.tuner_reset, 0x01);
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- 0x300, 0x01);
- break;
- case TM6010_BOARD_HAUPPAUGE_900H:
- case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
- case TM6010_BOARD_TWINHAN_TU501:
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.tuner_reset, 0x01);
- msleep(60);
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.tuner_reset, 0x00);
- msleep(75);
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.tuner_reset, 0x01);
- msleep(60);
- break;
- default:
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.tuner_reset, 0x00);
- msleep(130);
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.tuner_reset, 0x01);
- msleep(130);
- break;
- }
-
- tm6000_ir_wait(dev, 1);
- break;
- case 1:
- tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT,
- 0x02, 0x01);
- msleep(10);
- break;
- case 2:
- rc = tm6000_i2c_reset(dev, 100);
- break;
- }
- break;
- case XC2028_I2C_FLUSH:
- tm6000_set_reg(dev, REQ_50_SET_START, 0, 0);
- tm6000_set_reg(dev, REQ_51_SET_STOP, 0, 0);
- break;
- }
- return rc;
-}
-EXPORT_SYMBOL_GPL(tm6000_tuner_callback);
-
-int tm6000_cards_setup(struct tm6000_core *dev)
-{
- /*
- * Board-specific initialization sequence. Handles all GPIO
- * initialization sequences that are board-specific.
- * Up to now, all found devices use GPIO1 and GPIO4 at the same way.
- * Probably, they're all based on some reference device. Due to that,
- * there's a common routine at the end to handle those GPIO's. Devices
- * that use different pinups or init sequences can just return at
- * the board-specific session.
- */
- switch (dev->model) {
- case TM6010_BOARD_HAUPPAUGE_900H:
- case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
- case TM6010_BOARD_TWINHAN_TU501:
- case TM6010_BOARD_GENERIC:
- /* Turn xceive 3028 on */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.tuner_on, 0x01);
- msleep(15);
- /* Turn zarlink zl10353 on */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_on, 0x00);
- msleep(15);
- /* Reset zarlink zl10353 */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x00);
- msleep(50);
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x01);
- msleep(15);
- /* Turn zarlink zl10353 off */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_on, 0x01);
- msleep(15);
- /* ir ? */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.ir, 0x01);
- msleep(15);
- /* Power led on (blue) */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x00);
- msleep(15);
- /* DVB led off (orange) */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.dvb_led, 0x01);
- msleep(15);
- /* Turn zarlink zl10353 on */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_on, 0x00);
- msleep(15);
- break;
- case TM6010_BOARD_BEHOLD_WANDER:
- case TM6010_BOARD_BEHOLD_WANDER_LITE:
- /* Power led on (blue) */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01);
- msleep(15);
- /* Reset zarlink zl10353 */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x00);
- msleep(50);
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x01);
- msleep(15);
- break;
- case TM6010_BOARD_BEHOLD_VOYAGER:
- case TM6010_BOARD_BEHOLD_VOYAGER_LITE:
- /* Power led on (blue) */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01);
- msleep(15);
- break;
- default:
- break;
- }
-
- /*
- * Default initialization. Most of the devices seem to use GPIO1
- * and GPIO4.on the same way, so, this handles the common sequence
- * used by most devices.
- * If a device uses a different sequence or different GPIO pins for
- * reset, just add the code at the board-specific part
- */
-
- if (dev->gpio.tuner_reset) {
- int rc;
- int i;
-
- for (i = 0; i < 2; i++) {
- rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.tuner_reset, 0x00);
- if (rc < 0) {
- printk(KERN_ERR "Error %i doing tuner reset\n", rc);
- return rc;
- }
-
- msleep(10); /* Just to be conservative */
- rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.tuner_reset, 0x01);
- if (rc < 0) {
- printk(KERN_ERR "Error %i doing tuner reset\n", rc);
- return rc;
- }
- }
- } else {
- printk(KERN_ERR "Tuner reset is not configured\n");
- return -1;
- }
-
- msleep(50);
-
- return 0;
-};
-
-static void tm6000_config_tuner(struct tm6000_core *dev)
-{
- struct tuner_setup tun_setup;
-
- /* Load tuner module */
- v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- "tuner", dev->tuner_addr, NULL);
-
- memset(&tun_setup, 0, sizeof(tun_setup));
- tun_setup.type = dev->tuner_type;
- tun_setup.addr = dev->tuner_addr;
-
- tun_setup.mode_mask = 0;
- if (dev->caps.has_tuner)
- tun_setup.mode_mask |= (T_ANALOG_TV | T_RADIO);
-
- switch (dev->tuner_type) {
- case TUNER_XC2028:
- tun_setup.tuner_callback = tm6000_tuner_callback;
- break;
- case TUNER_XC5000:
- tun_setup.tuner_callback = tm6000_xc5000_callback;
- break;
- }
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
-
- switch (dev->tuner_type) {
- case TUNER_XC2028: {
- struct v4l2_priv_tun_config xc2028_cfg;
- struct xc2028_ctrl ctl;
-
- memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
- memset(&ctl, 0, sizeof(ctl));
-
- ctl.demod = XC3028_FE_ZARLINK456;
-
- xc2028_cfg.tuner = TUNER_XC2028;
- xc2028_cfg.priv = &ctl;
-
- switch (dev->model) {
- case TM6010_BOARD_HAUPPAUGE_900H:
- case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
- case TM6010_BOARD_TWINHAN_TU501:
- ctl.max_len = 80;
- ctl.fname = "xc3028L-v36.fw";
- break;
- default:
- if (dev->dev_type == TM6010)
- ctl.fname = "xc3028-v27.fw";
- else
- ctl.fname = "xc3028-v24.fw";
- }
-
- printk(KERN_INFO "Setting firmware parameters for xc2028\n");
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config,
- &xc2028_cfg);
-
- }
- break;
- case TUNER_XC5000:
- {
- struct v4l2_priv_tun_config xc5000_cfg;
- struct xc5000_config ctl = {
- .i2c_address = dev->tuner_addr,
- .if_khz = 4570,
- .radio_input = XC5000_RADIO_FM1_MONO,
- };
-
- xc5000_cfg.tuner = TUNER_XC5000;
- xc5000_cfg.priv = &ctl;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config,
- &xc5000_cfg);
- }
- break;
- default:
- printk(KERN_INFO "Unknown tuner type. Tuner is not configured.\n");
- break;
- }
-}
-
-static int fill_board_specific_data(struct tm6000_core *dev)
-{
- int rc;
-
- dev->dev_type = tm6000_boards[dev->model].type;
- dev->tuner_type = tm6000_boards[dev->model].tuner_type;
- dev->tuner_addr = tm6000_boards[dev->model].tuner_addr;
-
- dev->gpio = tm6000_boards[dev->model].gpio;
-
- dev->ir_codes = tm6000_boards[dev->model].ir_codes;
-
- dev->demod_addr = tm6000_boards[dev->model].demod_addr;
-
- dev->caps = tm6000_boards[dev->model].caps;
-
- dev->vinput[0] = tm6000_boards[dev->model].vinput[0];
- dev->vinput[1] = tm6000_boards[dev->model].vinput[1];
- dev->vinput[2] = tm6000_boards[dev->model].vinput[2];
- dev->rinput = tm6000_boards[dev->model].rinput;
-
- /* setup per-model quirks */
- switch (dev->model) {
- case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
- case TM6010_BOARD_HAUPPAUGE_900H:
- dev->quirks |= TM6000_QUIRK_NO_USB_DELAY;
- break;
-
- default:
- break;
- }
-
- /* initialize hardware */
- rc = tm6000_init(dev);
- if (rc < 0)
- return rc;
-
- return v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev);
-}
-
-
-static void use_alternative_detection_method(struct tm6000_core *dev)
-{
- int i, model = -1;
-
- if (!dev->eedata_size)
- return;
-
- for (i = 0; i < ARRAY_SIZE(tm6000_boards); i++) {
- if (!tm6000_boards[i].eename_size)
- continue;
- if (dev->eedata_size < tm6000_boards[i].eename_pos +
- tm6000_boards[i].eename_size)
- continue;
-
- if (!memcmp(&dev->eedata[tm6000_boards[i].eename_pos],
- tm6000_boards[i].eename,
- tm6000_boards[i].eename_size)) {
- model = i;
- break;
- }
- }
- if (model < 0) {
- printk(KERN_INFO "Device has eeprom but is currently unknown\n");
- return;
- }
-
- dev->model = model;
-
- printk(KERN_INFO "Device identified via eeprom as %s (type = %d)\n",
- tm6000_boards[model].name, model);
-}
-
-#if defined(CONFIG_MODULES) && defined(MODULE)
-static void request_module_async(struct work_struct *work)
-{
- struct tm6000_core *dev = container_of(work, struct tm6000_core,
- request_module_wk);
-
- request_module("tm6000-alsa");
-
- if (dev->caps.has_dvb)
- request_module("tm6000-dvb");
-}
-
-static void request_modules(struct tm6000_core *dev)
-{
- INIT_WORK(&dev->request_module_wk, request_module_async);
- schedule_work(&dev->request_module_wk);
-}
-
-static void flush_request_modules(struct tm6000_core *dev)
-{
- flush_work(&dev->request_module_wk);
-}
-#else
-#define request_modules(dev)
-#define flush_request_modules(dev)
-#endif /* CONFIG_MODULES */
-
-static int tm6000_init_dev(struct tm6000_core *dev)
-{
- struct v4l2_frequency f;
- int rc = 0;
-
- mutex_init(&dev->lock);
- mutex_lock(&dev->lock);
-
- if (!is_generic(dev->model)) {
- rc = fill_board_specific_data(dev);
- if (rc < 0)
- goto err;
-
- /* register i2c bus */
- rc = tm6000_i2c_register(dev);
- if (rc < 0)
- goto err;
- } else {
- /* register i2c bus */
- rc = tm6000_i2c_register(dev);
- if (rc < 0)
- goto err;
-
- use_alternative_detection_method(dev);
-
- rc = fill_board_specific_data(dev);
- if (rc < 0)
- goto err;
- }
-
- /* Default values for STD and resolutions */
- dev->width = 720;
- dev->height = 480;
- dev->norm = V4L2_STD_PAL_M;
-
- /* Configure tuner */
- tm6000_config_tuner(dev);
-
- /* Set video standard */
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
-
- /* Set tuner frequency - also loads firmware on xc2028/xc3028 */
- f.tuner = 0;
- f.type = V4L2_TUNER_ANALOG_TV;
- f.frequency = 3092; /* 193.25 MHz */
- dev->freq = f.frequency;
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
-
- if (dev->caps.has_tda9874)
- v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- "tvaudio", I2C_ADDR_TDA9874, NULL);
-
- /* register and initialize V4L2 */
- rc = tm6000_v4l2_register(dev);
- if (rc < 0)
- goto err;
-
- tm6000_add_into_devlist(dev);
- tm6000_init_extension(dev);
-
- tm6000_ir_init(dev);
-
- request_modules(dev);
-
- mutex_unlock(&dev->lock);
- return 0;
-
-err:
- mutex_unlock(&dev->lock);
- return rc;
-}
-
-/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
-#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
-
-static void get_max_endpoint(struct usb_device *udev,
- struct usb_host_interface *alt,
- char *msgtype,
- struct usb_host_endpoint *curr_e,
- struct tm6000_endpoint *tm_ep)
-{
- u16 tmp = le16_to_cpu(curr_e->desc.wMaxPacketSize);
- unsigned int size = tmp & 0x7ff;
-
- if (udev->speed == USB_SPEED_HIGH)
- size = size * hb_mult(tmp);
-
- if (size > tm_ep->maxsize) {
- tm_ep->endp = curr_e;
- tm_ep->maxsize = size;
- tm_ep->bInterfaceNumber = alt->desc.bInterfaceNumber;
- tm_ep->bAlternateSetting = alt->desc.bAlternateSetting;
-
- printk(KERN_INFO "tm6000: %s endpoint: 0x%02x (max size=%u bytes)\n",
- msgtype, curr_e->desc.bEndpointAddress,
- size);
- }
-}
-
-/*
- * tm6000_usb_probe()
- * checks for supported devices
- */
-static int tm6000_usb_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- struct usb_device *usbdev;
- struct tm6000_core *dev = NULL;
- int i, rc = 0;
- int nr = 0;
- char *speed;
-
- usbdev = usb_get_dev(interface_to_usbdev(interface));
-
- /* Selects the proper interface */
- rc = usb_set_interface(usbdev, 0, 1);
- if (rc < 0)
- goto err;
-
- /* Check to see next free device and mark as used */
- nr = find_first_zero_bit(&tm6000_devused, TM6000_MAXBOARDS);
- if (nr >= TM6000_MAXBOARDS) {
- printk(KERN_ERR "tm6000: Supports only %i tm60xx boards.\n", TM6000_MAXBOARDS);
- usb_put_dev(usbdev);
- return -ENOMEM;
- }
-
- /* Create and initialize dev struct */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL) {
- printk(KERN_ERR "tm6000" ": out of memory!\n");
- usb_put_dev(usbdev);
- return -ENOMEM;
- }
- spin_lock_init(&dev->slock);
- mutex_init(&dev->usb_lock);
-
- /* Increment usage count */
- set_bit(nr, &tm6000_devused);
- snprintf(dev->name, 29, "tm6000 #%d", nr);
-
- dev->model = id->driver_info;
- if (card[nr] < ARRAY_SIZE(tm6000_boards))
- dev->model = card[nr];
-
- dev->udev = usbdev;
- dev->devno = nr;
-
- switch (usbdev->speed) {
- case USB_SPEED_LOW:
- speed = "1.5";
- break;
- case USB_SPEED_UNKNOWN:
- case USB_SPEED_FULL:
- speed = "12";
- break;
- case USB_SPEED_HIGH:
- speed = "480";
- break;
- default:
- speed = "unknown";
- }
-
- /* Get endpoints */
- for (i = 0; i < interface->num_altsetting; i++) {
- int ep;
-
- for (ep = 0; ep < interface->altsetting[i].desc.bNumEndpoints; ep++) {
- struct usb_host_endpoint *e;
- int dir_out;
-
- e = &interface->altsetting[i].endpoint[ep];
-
- dir_out = ((e->desc.bEndpointAddress &
- USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
-
- printk(KERN_INFO "tm6000: alt %d, interface %i, class %i\n",
- i,
- interface->altsetting[i].desc.bInterfaceNumber,
- interface->altsetting[i].desc.bInterfaceClass);
-
- switch (e->desc.bmAttributes) {
- case USB_ENDPOINT_XFER_BULK:
- if (!dir_out) {
- get_max_endpoint(usbdev,
- &interface->altsetting[i],
- "Bulk IN", e,
- &dev->bulk_in);
- } else {
- get_max_endpoint(usbdev,
- &interface->altsetting[i],
- "Bulk OUT", e,
- &dev->bulk_out);
- }
- break;
- case USB_ENDPOINT_XFER_ISOC:
- if (!dir_out) {
- get_max_endpoint(usbdev,
- &interface->altsetting[i],
- "ISOC IN", e,
- &dev->isoc_in);
- } else {
- get_max_endpoint(usbdev,
- &interface->altsetting[i],
- "ISOC OUT", e,
- &dev->isoc_out);
- }
- break;
- case USB_ENDPOINT_XFER_INT:
- if (!dir_out) {
- get_max_endpoint(usbdev,
- &interface->altsetting[i],
- "INT IN", e,
- &dev->int_in);
- } else {
- get_max_endpoint(usbdev,
- &interface->altsetting[i],
- "INT OUT", e,
- &dev->int_out);
- }
- break;
- }
- }
- }
-
-
- printk(KERN_INFO "tm6000: New video device @ %s Mbps (%04x:%04x, ifnum %d)\n",
- speed,
- le16_to_cpu(dev->udev->descriptor.idVendor),
- le16_to_cpu(dev->udev->descriptor.idProduct),
- interface->altsetting->desc.bInterfaceNumber);
-
-/* check if the the device has the iso in endpoint at the correct place */
- if (!dev->isoc_in.endp) {
- printk(KERN_ERR "tm6000: probing error: no IN ISOC endpoint!\n");
- rc = -ENODEV;
-
- goto err;
- }
-
- /* save our data pointer in this interface device */
- usb_set_intfdata(interface, dev);
-
- printk(KERN_INFO "tm6000: Found %s\n", tm6000_boards[dev->model].name);
-
- rc = tm6000_init_dev(dev);
- if (rc < 0)
- goto err;
-
- return 0;
-
-err:
- printk(KERN_ERR "tm6000: Error %d while registering\n", rc);
-
- clear_bit(nr, &tm6000_devused);
- usb_put_dev(usbdev);
-
- kfree(dev);
- return rc;
-}
-
-/*
- * tm6000_usb_disconnect()
- * called when the device gets diconencted
- * video device will be unregistered on v4l2_close in case it is still open
- */
-static void tm6000_usb_disconnect(struct usb_interface *interface)
-{
- struct tm6000_core *dev = usb_get_intfdata(interface);
- usb_set_intfdata(interface, NULL);
-
- if (!dev)
- return;
-
- printk(KERN_INFO "tm6000: disconnecting %s\n", dev->name);
-
- flush_request_modules(dev);
-
- tm6000_ir_fini(dev);
-
- if (dev->gpio.power_led) {
- switch (dev->model) {
- case TM6010_BOARD_HAUPPAUGE_900H:
- case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
- case TM6010_BOARD_TWINHAN_TU501:
- /* Power led off */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.power_led, 0x01);
- msleep(15);
- break;
- case TM6010_BOARD_BEHOLD_WANDER:
- case TM6010_BOARD_BEHOLD_VOYAGER:
- case TM6010_BOARD_BEHOLD_WANDER_LITE:
- case TM6010_BOARD_BEHOLD_VOYAGER_LITE:
- /* Power led off */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.power_led, 0x00);
- msleep(15);
- break;
- }
- }
- tm6000_v4l2_unregister(dev);
-
- tm6000_i2c_unregister(dev);
-
- v4l2_device_unregister(&dev->v4l2_dev);
-
- dev->state |= DEV_DISCONNECTED;
-
- usb_put_dev(dev->udev);
-
- tm6000_close_extension(dev);
- tm6000_remove_from_devlist(dev);
-
- clear_bit(dev->devno, &tm6000_devused);
- kfree(dev);
-}
-
-static struct usb_driver tm6000_usb_driver = {
- .name = "tm6000",
- .probe = tm6000_usb_probe,
- .disconnect = tm6000_usb_disconnect,
- .id_table = tm6000_id_table,
-};
-
-module_usb_driver(tm6000_usb_driver);
-
-MODULE_DESCRIPTION("Trident TVMaster TM5600/TM6000/TM6010 USB2 adapter");
-MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tm6000/tm6000-core.c b/drivers/media/video/tm6000/tm6000-core.c
deleted file mode 100644
index 22cc0116deb..00000000000
--- a/drivers/media/video/tm6000/tm6000-core.c
+++ /dev/null
@@ -1,935 +0,0 @@
-/*
- * tm6000-core.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
- * - DVB-T support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include "tm6000.h"
-#include "tm6000-regs.h"
-#include <media/v4l2-common.h>
-#include <media/tuner.h>
-
-#define USB_TIMEOUT (5 * HZ) /* ms */
-
-int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req,
- u16 value, u16 index, u8 *buf, u16 len)
-{
- int ret, i;
- unsigned int pipe;
- u8 *data = NULL;
- int delay = 5000;
-
- mutex_lock(&dev->usb_lock);
-
- if (len)
- data = kzalloc(len, GFP_KERNEL);
-
- if (req_type & USB_DIR_IN)
- pipe = usb_rcvctrlpipe(dev->udev, 0);
- else {
- pipe = usb_sndctrlpipe(dev->udev, 0);
- memcpy(data, buf, len);
- }
-
- if (tm6000_debug & V4L2_DEBUG_I2C) {
- printk(KERN_DEBUG "(dev %p, pipe %08x): ", dev->udev, pipe);
-
- printk(KERN_CONT "%s: %02x %02x %02x %02x %02x %02x %02x %02x ",
- (req_type & USB_DIR_IN) ? " IN" : "OUT",
- req_type, req, value&0xff, value>>8, index&0xff,
- index>>8, len&0xff, len>>8);
-
- if (!(req_type & USB_DIR_IN)) {
- printk(KERN_CONT ">>> ");
- for (i = 0; i < len; i++)
- printk(KERN_CONT " %02x", buf[i]);
- printk(KERN_CONT "\n");
- }
- }
-
- ret = usb_control_msg(dev->udev, pipe, req, req_type, value, index,
- data, len, USB_TIMEOUT);
-
- if (req_type & USB_DIR_IN)
- memcpy(buf, data, len);
-
- if (tm6000_debug & V4L2_DEBUG_I2C) {
- if (ret < 0) {
- if (req_type & USB_DIR_IN)
- printk(KERN_DEBUG "<<< (len=%d)\n", len);
-
- printk(KERN_CONT "%s: Error #%d\n", __func__, ret);
- } else if (req_type & USB_DIR_IN) {
- printk(KERN_CONT "<<< ");
- for (i = 0; i < len; i++)
- printk(KERN_CONT " %02x", buf[i]);
- printk(KERN_CONT "\n");
- }
- }
-
- kfree(data);
-
- if (dev->quirks & TM6000_QUIRK_NO_USB_DELAY)
- delay = 0;
-
- if (req == REQ_16_SET_GET_I2C_WR1_RDN && !(req_type & USB_DIR_IN)) {
- unsigned int tsleep;
- /* Calculate delay time, 14000us for 64 bytes */
- tsleep = (len * 200) + 200;
- if (tsleep < delay)
- tsleep = delay;
- usleep_range(tsleep, tsleep + 1000);
- }
- else if (delay)
- usleep_range(delay, delay + 1000);
-
- mutex_unlock(&dev->usb_lock);
- return ret;
-}
-
-int tm6000_set_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index)
-{
- return
- tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR,
- req, value, index, NULL, 0);
-}
-EXPORT_SYMBOL_GPL(tm6000_set_reg);
-
-int tm6000_get_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index)
-{
- int rc;
- u8 buf[1];
-
- rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
- value, index, buf, 1);
-
- if (rc < 0)
- return rc;
-
- return *buf;
-}
-EXPORT_SYMBOL_GPL(tm6000_get_reg);
-
-int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value,
- u16 index, u16 mask)
-{
- int rc;
- u8 buf[1];
- u8 new_index;
-
- rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
- value, 0, buf, 1);
-
- if (rc < 0)
- return rc;
-
- new_index = (buf[0] & ~mask) | (index & mask);
-
- if (new_index == buf[0])
- return 0;
-
- return tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR,
- req, value, new_index, NULL, 0);
-}
-EXPORT_SYMBOL_GPL(tm6000_set_reg_mask);
-
-int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index)
-{
- int rc;
- u8 buf[2];
-
- rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
- value, index, buf, 2);
-
- if (rc < 0)
- return rc;
-
- return buf[1]|buf[0]<<8;
-}
-
-int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index)
-{
- int rc;
- u8 buf[4];
-
- rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
- value, index, buf, 4);
-
- if (rc < 0)
- return rc;
-
- return buf[3] | buf[2] << 8 | buf[1] << 16 | buf[0] << 24;
-}
-
-int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep)
-{
- int rc;
-
- rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 0);
- if (rc < 0)
- return rc;
-
- msleep(tsleep);
-
- rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 1);
- msleep(tsleep);
-
- return rc;
-}
-
-void tm6000_set_fourcc_format(struct tm6000_core *dev)
-{
- if (dev->dev_type == TM6010) {
- int val;
-
- val = tm6000_get_reg(dev, TM6010_REQ07_RCC_ACTIVE_IF, 0) & 0xfc;
- if (dev->fourcc == V4L2_PIX_FMT_UYVY)
- tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_IF, val);
- else
- tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_IF, val | 1);
- } else {
- if (dev->fourcc == V4L2_PIX_FMT_UYVY)
- tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0xd0);
- else
- tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0x90);
- }
-}
-
-static void tm6000_set_vbi(struct tm6000_core *dev)
-{
- /*
- * FIXME:
- * VBI lines and start/end are different between 60Hz and 50Hz
- * So, it is very likely that we need to change the config to
- * something that takes it into account, doing something different
- * if (dev->norm & V4L2_STD_525_60)
- */
-
- if (dev->dev_type == TM6010) {
- tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01);
- tm6000_set_reg(dev, TM6010_REQ07_R41_TELETEXT_VBI_CODE1, 0x27);
- tm6000_set_reg(dev, TM6010_REQ07_R42_VBI_DATA_HIGH_LEVEL, 0x55);
- tm6000_set_reg(dev, TM6010_REQ07_R43_VBI_DATA_TYPE_LINE7, 0x66);
- tm6000_set_reg(dev, TM6010_REQ07_R44_VBI_DATA_TYPE_LINE8, 0x66);
- tm6000_set_reg(dev, TM6010_REQ07_R45_VBI_DATA_TYPE_LINE9, 0x66);
- tm6000_set_reg(dev,
- TM6010_REQ07_R46_VBI_DATA_TYPE_LINE10, 0x66);
- tm6000_set_reg(dev,
- TM6010_REQ07_R47_VBI_DATA_TYPE_LINE11, 0x66);
- tm6000_set_reg(dev,
- TM6010_REQ07_R48_VBI_DATA_TYPE_LINE12, 0x66);
- tm6000_set_reg(dev,
- TM6010_REQ07_R49_VBI_DATA_TYPE_LINE13, 0x66);
- tm6000_set_reg(dev,
- TM6010_REQ07_R4A_VBI_DATA_TYPE_LINE14, 0x66);
- tm6000_set_reg(dev,
- TM6010_REQ07_R4B_VBI_DATA_TYPE_LINE15, 0x66);
- tm6000_set_reg(dev,
- TM6010_REQ07_R4C_VBI_DATA_TYPE_LINE16, 0x66);
- tm6000_set_reg(dev,
- TM6010_REQ07_R4D_VBI_DATA_TYPE_LINE17, 0x66);
- tm6000_set_reg(dev,
- TM6010_REQ07_R4E_VBI_DATA_TYPE_LINE18, 0x66);
- tm6000_set_reg(dev,
- TM6010_REQ07_R4F_VBI_DATA_TYPE_LINE19, 0x66);
- tm6000_set_reg(dev,
- TM6010_REQ07_R50_VBI_DATA_TYPE_LINE20, 0x66);
- tm6000_set_reg(dev,
- TM6010_REQ07_R51_VBI_DATA_TYPE_LINE21, 0x66);
- tm6000_set_reg(dev,
- TM6010_REQ07_R52_VBI_DATA_TYPE_LINE22, 0x66);
- tm6000_set_reg(dev,
- TM6010_REQ07_R53_VBI_DATA_TYPE_LINE23, 0x00);
- tm6000_set_reg(dev,
- TM6010_REQ07_R54_VBI_DATA_TYPE_RLINES, 0x00);
- tm6000_set_reg(dev,
- TM6010_REQ07_R55_VBI_LOOP_FILTER_GAIN, 0x01);
- tm6000_set_reg(dev,
- TM6010_REQ07_R56_VBI_LOOP_FILTER_I_GAIN, 0x00);
- tm6000_set_reg(dev,
- TM6010_REQ07_R57_VBI_LOOP_FILTER_P_GAIN, 0x02);
- tm6000_set_reg(dev, TM6010_REQ07_R58_VBI_CAPTION_DTO1, 0x35);
- tm6000_set_reg(dev, TM6010_REQ07_R59_VBI_CAPTION_DTO0, 0xa0);
- tm6000_set_reg(dev, TM6010_REQ07_R5A_VBI_TELETEXT_DTO1, 0x11);
- tm6000_set_reg(dev, TM6010_REQ07_R5B_VBI_TELETEXT_DTO0, 0x4c);
- tm6000_set_reg(dev, TM6010_REQ07_R40_TELETEXT_VBI_CODE0, 0x01);
- tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00);
- }
-}
-
-int tm6000_init_analog_mode(struct tm6000_core *dev)
-{
- struct v4l2_frequency f;
-
- if (dev->dev_type == TM6010) {
- u8 active = TM6010_REQ07_RCC_ACTIVE_IF_AUDIO_ENABLE;
-
- if (!dev->radio)
- active |= TM6010_REQ07_RCC_ACTIVE_IF_VIDEO_ENABLE;
-
- /* Enable video and audio */
- tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_IF,
- active, 0x60);
- /* Disable TS input */
- tm6000_set_reg_mask(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE,
- 0x00, 0x40);
- } else {
- /* Enables soft reset */
- tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01);
-
- if (dev->scaler)
- /* Disable Hfilter and Enable TS Drop err */
- tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x20);
- else /* Enable Hfilter and disable TS Drop err */
- tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x80);
-
- tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x88);
- tm6000_set_reg(dev, TM6000_REQ07_RDA_CLK_SEL, 0x23);
- tm6000_set_reg(dev, TM6010_REQ07_RD1_ADDR_FOR_REQ1, 0xc0);
- tm6000_set_reg(dev, TM6010_REQ07_RD2_ADDR_FOR_REQ2, 0xd8);
- tm6000_set_reg(dev, TM6010_REQ07_RD6_ENDP_REQ1_REQ2, 0x06);
- tm6000_set_reg(dev, TM6000_REQ07_RDF_PWDOWN_ACLK, 0x1f);
-
- /* AP Software reset */
- tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08);
- tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00);
-
- tm6000_set_fourcc_format(dev);
-
- /* Disables soft reset */
- tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00);
- }
- msleep(20);
-
- /* Tuner firmware can now be loaded */
-
- /*
- * FIXME: This is a hack! xc3028 "sleeps" when no channel is detected
- * for more than a few seconds. Not sure why, as this behavior does
- * not happen on other devices with xc3028. So, I suspect that it
- * is yet another bug at tm6000. After start sleeping, decoding
- * doesn't start automatically. Instead, it requires some
- * I2C commands to wake it up. As we want to have image at the
- * beginning, we needed to add this hack. The better would be to
- * discover some way to make tm6000 to wake up without this hack.
- */
- f.frequency = dev->freq;
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
-
- msleep(100);
- tm6000_set_standard(dev);
- tm6000_set_vbi(dev);
- tm6000_set_audio_bitrate(dev, 48000);
-
- /* switch dvb led off */
- if (dev->gpio.dvb_led) {
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.dvb_led, 0x01);
- }
-
- return 0;
-}
-
-int tm6000_init_digital_mode(struct tm6000_core *dev)
-{
- if (dev->dev_type == TM6010) {
- /* Disable video and audio */
- tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_IF,
- 0x00, 0x60);
- /* Enable TS input */
- tm6000_set_reg_mask(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE,
- 0x40, 0x40);
- /* all power down, but not the digital data port */
- tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, 0x28);
- tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xfc);
- tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0xff);
- } else {
- tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08);
- tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00);
- tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01);
- tm6000_set_reg(dev, TM6000_REQ07_RDF_PWDOWN_ACLK, 0x08);
- tm6000_set_reg(dev, TM6000_REQ07_RE2_VADC_STATUS_CTL, 0x0c);
- tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0xff);
- tm6000_set_reg(dev, TM6000_REQ07_REB_VADC_AADC_MODE, 0xd8);
- tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x40);
- tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0xd0);
- tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x09);
- tm6000_set_reg(dev, TM6000_REQ07_RDA_CLK_SEL, 0x37);
- tm6000_set_reg(dev, TM6010_REQ07_RD1_ADDR_FOR_REQ1, 0xd8);
- tm6000_set_reg(dev, TM6010_REQ07_RD2_ADDR_FOR_REQ2, 0xc0);
- tm6000_set_reg(dev, TM6010_REQ07_RD6_ENDP_REQ1_REQ2, 0x60);
-
- tm6000_set_reg(dev, TM6000_REQ07_RE2_VADC_STATUS_CTL, 0x0c);
- tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0xff);
- tm6000_set_reg(dev, TM6000_REQ07_REB_VADC_AADC_MODE, 0x08);
- msleep(50);
-
- tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
- msleep(50);
- tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
- msleep(50);
- tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
- msleep(100);
- }
-
- /* switch dvb led on */
- if (dev->gpio.dvb_led) {
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->gpio.dvb_led, 0x00);
- }
-
- return 0;
-}
-EXPORT_SYMBOL(tm6000_init_digital_mode);
-
-struct reg_init {
- u8 req;
- u8 reg;
- u8 val;
-};
-
-/* The meaning of those initializations are unknown */
-static struct reg_init tm6000_init_tab[] = {
- /* REG VALUE */
- { TM6000_REQ07_RDF_PWDOWN_ACLK, 0x1f },
- { TM6010_REQ07_RFF_SOFT_RESET, 0x08 },
- { TM6010_REQ07_RFF_SOFT_RESET, 0x00 },
- { TM6010_REQ07_RD5_POWERSAVE, 0x4f },
- { TM6000_REQ07_RDA_CLK_SEL, 0x23 },
- { TM6000_REQ07_RDB_OUT_SEL, 0x08 },
- { TM6000_REQ07_RE2_VADC_STATUS_CTL, 0x00 },
- { TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10 },
- { TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00 },
- { TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x00 },
- { TM6000_REQ07_REB_VADC_AADC_MODE, 0x64 }, /* 48000 bits/sample, external input */
- { TM6000_REQ07_REE_VADC_CTRL_SEL_CONTROL, 0xc2 },
-
- { TM6010_REQ07_R3F_RESET, 0x01 }, /* Start of soft reset */
- { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00 },
- { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x07 },
- { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
- { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00 },
- { TM6010_REQ07_R05_NOISE_THRESHOLD, 0x64 },
- { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01 },
- { TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, 0x82 },
- { TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, 0x36 },
- { TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, 0x50 },
- { TM6010_REQ07_R0C_CHROMA_AGC_CONTROL, 0x6a },
- { TM6010_REQ07_R11_AGC_PEAK_CONTROL, 0xc9 },
- { TM6010_REQ07_R12_AGC_GATE_STARTH, 0x07 },
- { TM6010_REQ07_R13_AGC_GATE_STARTL, 0x3b },
- { TM6010_REQ07_R14_AGC_GATE_WIDTH, 0x47 },
- { TM6010_REQ07_R15_AGC_BP_DELAY, 0x6f },
- { TM6010_REQ07_R17_HLOOP_MAXSTATE, 0xcd },
- { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
- { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b },
- { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2 },
- { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9 },
- { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
- { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
- { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
- { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
- { TM6010_REQ07_R20_HSYNC_RISING_EDGE_TIME, 0x3c },
- { TM6010_REQ07_R21_HSYNC_PHASE_OFFSET, 0x3c },
- { TM6010_REQ07_R2D_CHROMA_BURST_END, 0x48 },
- { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
- { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
- { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
- { TM6010_REQ07_R32_VSYNC_HLOCK_MIN, 0x74 },
- { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c },
- { TM6010_REQ07_R34_VSYNC_AGC_MIN, 0x74 },
- { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
- { TM6010_REQ07_R36_VSYNC_VBI_MIN, 0x7a },
- { TM6010_REQ07_R37_VSYNC_VBI_MAX, 0x26 },
- { TM6010_REQ07_R38_VSYNC_THRESHOLD, 0x40 },
- { TM6010_REQ07_R39_VSYNC_TIME_CONSTANT, 0x0a },
- { TM6010_REQ07_R42_VBI_DATA_HIGH_LEVEL, 0x55 },
- { TM6010_REQ07_R51_VBI_DATA_TYPE_LINE21, 0x11 },
- { TM6010_REQ07_R55_VBI_LOOP_FILTER_GAIN, 0x01 },
- { TM6010_REQ07_R57_VBI_LOOP_FILTER_P_GAIN, 0x02 },
- { TM6010_REQ07_R58_VBI_CAPTION_DTO1, 0x35 },
- { TM6010_REQ07_R59_VBI_CAPTION_DTO0, 0xa0 },
- { TM6010_REQ07_R80_COMB_FILTER_TRESHOLD, 0x15 },
- { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
- { TM6010_REQ07_RC1_TRESHOLD, 0xd0 },
- { TM6010_REQ07_RC3_HSTART1, 0x88 },
- { TM6010_REQ07_R3F_RESET, 0x00 }, /* End of the soft reset */
- { TM6010_REQ05_R18_IMASK7, 0x00 },
-};
-
-static struct reg_init tm6010_init_tab[] = {
- { TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x00 },
- { TM6010_REQ07_RC4_HSTART0, 0xa0 },
- { TM6010_REQ07_RC6_HEND0, 0x40 },
- { TM6010_REQ07_RCA_VEND0, 0x31 },
- { TM6010_REQ07_RCC_ACTIVE_IF, 0xe1 },
- { TM6010_REQ07_RE0_DVIDEO_SOURCE, 0x03 },
- { TM6010_REQ07_RFE_POWER_DOWN, 0x7f },
-
- { TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0 },
- { TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4 },
- { TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8 },
- { TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00 },
- { TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2 },
- { TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0 },
- { TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2 },
- { TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60 },
- { TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc },
-
- { TM6010_REQ07_R3F_RESET, 0x01 },
- { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00 },
- { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x07 },
- { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
- { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00 },
- { TM6010_REQ07_R05_NOISE_THRESHOLD, 0x64 },
- { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01 },
- { TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, 0x82 },
- { TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, 0x36 },
- { TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, 0x50 },
- { TM6010_REQ07_R0C_CHROMA_AGC_CONTROL, 0x6a },
- { TM6010_REQ07_R11_AGC_PEAK_CONTROL, 0xc9 },
- { TM6010_REQ07_R12_AGC_GATE_STARTH, 0x07 },
- { TM6010_REQ07_R13_AGC_GATE_STARTL, 0x3b },
- { TM6010_REQ07_R14_AGC_GATE_WIDTH, 0x47 },
- { TM6010_REQ07_R15_AGC_BP_DELAY, 0x6f },
- { TM6010_REQ07_R17_HLOOP_MAXSTATE, 0xcd },
- { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
- { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b },
- { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2 },
- { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9 },
- { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
- { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
- { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
- { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
- { TM6010_REQ07_R20_HSYNC_RISING_EDGE_TIME, 0x3c },
- { TM6010_REQ07_R21_HSYNC_PHASE_OFFSET, 0x3c },
- { TM6010_REQ07_R2D_CHROMA_BURST_END, 0x48 },
- { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
- { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
- { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
- { TM6010_REQ07_R32_VSYNC_HLOCK_MIN, 0x74 },
- { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c },
- { TM6010_REQ07_R34_VSYNC_AGC_MIN, 0x74 },
- { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
- { TM6010_REQ07_R36_VSYNC_VBI_MIN, 0x7a },
- { TM6010_REQ07_R37_VSYNC_VBI_MAX, 0x26 },
- { TM6010_REQ07_R38_VSYNC_THRESHOLD, 0x40 },
- { TM6010_REQ07_R39_VSYNC_TIME_CONSTANT, 0x0a },
- { TM6010_REQ07_R42_VBI_DATA_HIGH_LEVEL, 0x55 },
- { TM6010_REQ07_R51_VBI_DATA_TYPE_LINE21, 0x11 },
- { TM6010_REQ07_R55_VBI_LOOP_FILTER_GAIN, 0x01 },
- { TM6010_REQ07_R57_VBI_LOOP_FILTER_P_GAIN, 0x02 },
- { TM6010_REQ07_R58_VBI_CAPTION_DTO1, 0x35 },
- { TM6010_REQ07_R59_VBI_CAPTION_DTO0, 0xa0 },
- { TM6010_REQ07_R80_COMB_FILTER_TRESHOLD, 0x15 },
- { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
- { TM6010_REQ07_RC1_TRESHOLD, 0xd0 },
- { TM6010_REQ07_RC3_HSTART1, 0x88 },
- { TM6010_REQ07_R3F_RESET, 0x00 },
-
- { TM6010_REQ05_R18_IMASK7, 0x00 },
-
- { TM6010_REQ07_RDC_IR_LEADER1, 0xaa },
- { TM6010_REQ07_RDD_IR_LEADER0, 0x30 },
- { TM6010_REQ07_RDE_IR_PULSE_CNT1, 0x20 },
- { TM6010_REQ07_RDF_IR_PULSE_CNT0, 0xd0 },
- { REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x00 },
- { TM6010_REQ07_RD8_IR, 0x0f },
-
- /* set remote wakeup key:any key wakeup */
- { TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe },
- { TM6010_REQ07_RDA_IR_WAKEUP_SEL, 0xff },
-};
-
-int tm6000_init(struct tm6000_core *dev)
-{
- int board, rc = 0, i, size;
- struct reg_init *tab;
-
- /* Check board revision */
- board = tm6000_get_reg32(dev, REQ_40_GET_VERSION, 0, 0);
- if (board >= 0) {
- switch (board & 0xff) {
- case 0xf3:
- printk(KERN_INFO "Found tm6000\n");
- if (dev->dev_type != TM6000)
- dev->dev_type = TM6000;
- break;
- case 0xf4:
- printk(KERN_INFO "Found tm6010\n");
- if (dev->dev_type != TM6010)
- dev->dev_type = TM6010;
- break;
- default:
- printk(KERN_INFO "Unknown board version = 0x%08x\n", board);
- }
- } else
- printk(KERN_ERR "Error %i while retrieving board version\n", board);
-
- if (dev->dev_type == TM6010) {
- tab = tm6010_init_tab;
- size = ARRAY_SIZE(tm6010_init_tab);
- } else {
- tab = tm6000_init_tab;
- size = ARRAY_SIZE(tm6000_init_tab);
- }
-
- /* Load board's initialization table */
- for (i = 0; i < size; i++) {
- rc = tm6000_set_reg(dev, tab[i].req, tab[i].reg, tab[i].val);
- if (rc < 0) {
- printk(KERN_ERR "Error %i while setting req %d, "
- "reg %d to value %d\n", rc,
- tab[i].req, tab[i].reg, tab[i].val);
- return rc;
- }
- }
-
- msleep(5); /* Just to be conservative */
-
- rc = tm6000_cards_setup(dev);
-
- return rc;
-}
-
-
-int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate)
-{
- int val = 0;
- u8 areg_f0 = 0x60; /* ADC MCLK = 250 Fs */
- u8 areg_0a = 0x91; /* SIF 48KHz */
-
- switch (bitrate) {
- case 48000:
- areg_f0 = 0x60; /* ADC MCLK = 250 Fs */
- areg_0a = 0x91; /* SIF 48KHz */
- dev->audio_bitrate = bitrate;
- break;
- case 32000:
- areg_f0 = 0x00; /* ADC MCLK = 375 Fs */
- areg_0a = 0x90; /* SIF 32KHz */
- dev->audio_bitrate = bitrate;
- break;
- default:
- return -EINVAL;
- }
-
-
- /* enable I2S, if we use sif or external I2S device */
- if (dev->dev_type == TM6010) {
- val = tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, areg_0a);
- if (val < 0)
- return val;
-
- val = tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
- areg_f0, 0xf0);
- if (val < 0)
- return val;
- } else {
- val = tm6000_set_reg_mask(dev, TM6000_REQ07_REB_VADC_AADC_MODE,
- areg_f0, 0xf0);
- if (val < 0)
- return val;
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate);
-
-int tm6000_set_audio_rinput(struct tm6000_core *dev)
-{
- if (dev->dev_type == TM6010) {
- /* Audio crossbar setting, default SIF1 */
- u8 areg_f0;
- u8 areg_07 = 0x10;
-
- switch (dev->rinput.amux) {
- case TM6000_AMUX_SIF1:
- case TM6000_AMUX_SIF2:
- areg_f0 = 0x03;
- areg_07 = 0x30;
- break;
- case TM6000_AMUX_ADC1:
- areg_f0 = 0x00;
- break;
- case TM6000_AMUX_ADC2:
- areg_f0 = 0x08;
- break;
- case TM6000_AMUX_I2S:
- areg_f0 = 0x04;
- break;
- default:
- printk(KERN_INFO "%s: audio input dosn't support\n",
- dev->name);
- return 0;
- break;
- }
- /* Set audio input crossbar */
- tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
- areg_f0, 0x0f);
- /* Mux overflow workaround */
- tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
- areg_07, 0xf0);
- } else {
- u8 areg_eb;
- /* Audio setting, default LINE1 */
- switch (dev->rinput.amux) {
- case TM6000_AMUX_ADC1:
- areg_eb = 0x00;
- break;
- case TM6000_AMUX_ADC2:
- areg_eb = 0x04;
- break;
- default:
- printk(KERN_INFO "%s: audio input dosn't support\n",
- dev->name);
- return 0;
- break;
- }
- /* Set audio input */
- tm6000_set_reg_mask(dev, TM6000_REQ07_REB_VADC_AADC_MODE,
- areg_eb, 0x0f);
- }
- return 0;
-}
-
-static void tm6010_set_mute_sif(struct tm6000_core *dev, u8 mute)
-{
- u8 mute_reg = 0;
-
- if (mute)
- mute_reg = 0x08;
-
- tm6000_set_reg_mask(dev, TM6010_REQ08_R0A_A_I2S_MOD, mute_reg, 0x08);
-}
-
-static void tm6010_set_mute_adc(struct tm6000_core *dev, u8 mute)
-{
- u8 mute_reg = 0;
-
- if (mute)
- mute_reg = 0x20;
-
- if (dev->dev_type == TM6010) {
- tm6000_set_reg_mask(dev, TM6010_REQ08_RF2_LEFT_CHANNEL_VOL,
- mute_reg, 0x20);
- tm6000_set_reg_mask(dev, TM6010_REQ08_RF3_RIGHT_CHANNEL_VOL,
- mute_reg, 0x20);
- } else {
- tm6000_set_reg_mask(dev, TM6000_REQ07_REC_VADC_AADC_LVOL,
- mute_reg, 0x20);
- tm6000_set_reg_mask(dev, TM6000_REQ07_RED_VADC_AADC_RVOL,
- mute_reg, 0x20);
- }
-}
-
-int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute)
-{
- enum tm6000_mux mux;
-
- if (dev->radio)
- mux = dev->rinput.amux;
- else
- mux = dev->vinput[dev->input].amux;
-
- switch (mux) {
- case TM6000_AMUX_SIF1:
- case TM6000_AMUX_SIF2:
- if (dev->dev_type == TM6010)
- tm6010_set_mute_sif(dev, mute);
- else {
- printk(KERN_INFO "ERROR: TM5600 and TM6000 don't has"
- " SIF audio inputs. Please check the %s"
- " configuration.\n", dev->name);
- return -EINVAL;
- }
- break;
- case TM6000_AMUX_ADC1:
- case TM6000_AMUX_ADC2:
- tm6010_set_mute_adc(dev, mute);
- break;
- default:
- return -EINVAL;
- break;
- }
- return 0;
-}
-
-static void tm6010_set_volume_sif(struct tm6000_core *dev, int vol)
-{
- u8 vol_reg;
-
- vol_reg = vol & 0x0F;
-
- if (vol < 0)
- vol_reg |= 0x40;
-
- tm6000_set_reg(dev, TM6010_REQ08_R07_A_LEFT_VOL, vol_reg);
- tm6000_set_reg(dev, TM6010_REQ08_R08_A_RIGHT_VOL, vol_reg);
-}
-
-static void tm6010_set_volume_adc(struct tm6000_core *dev, int vol)
-{
- u8 vol_reg;
-
- vol_reg = (vol + 0x10) & 0x1f;
-
- if (dev->dev_type == TM6010) {
- tm6000_set_reg(dev, TM6010_REQ08_RF2_LEFT_CHANNEL_VOL, vol_reg);
- tm6000_set_reg(dev, TM6010_REQ08_RF3_RIGHT_CHANNEL_VOL, vol_reg);
- } else {
- tm6000_set_reg(dev, TM6000_REQ07_REC_VADC_AADC_LVOL, vol_reg);
- tm6000_set_reg(dev, TM6000_REQ07_RED_VADC_AADC_RVOL, vol_reg);
- }
-}
-
-void tm6000_set_volume(struct tm6000_core *dev, int vol)
-{
- enum tm6000_mux mux;
-
- if (dev->radio) {
- mux = dev->rinput.amux;
- vol += 8; /* Offset to 0 dB */
- } else
- mux = dev->vinput[dev->input].amux;
-
- switch (mux) {
- case TM6000_AMUX_SIF1:
- case TM6000_AMUX_SIF2:
- if (dev->dev_type == TM6010)
- tm6010_set_volume_sif(dev, vol);
- else
- printk(KERN_INFO "ERROR: TM5600 and TM6000 don't has"
- " SIF audio inputs. Please check the %s"
- " configuration.\n", dev->name);
- break;
- case TM6000_AMUX_ADC1:
- case TM6000_AMUX_ADC2:
- tm6010_set_volume_adc(dev, vol);
- break;
- default:
- break;
- }
-}
-
-static LIST_HEAD(tm6000_devlist);
-static DEFINE_MUTEX(tm6000_devlist_mutex);
-
-/*
- * tm6000_realease_resource()
- */
-
-void tm6000_remove_from_devlist(struct tm6000_core *dev)
-{
- mutex_lock(&tm6000_devlist_mutex);
- list_del(&dev->devlist);
- mutex_unlock(&tm6000_devlist_mutex);
-};
-
-void tm6000_add_into_devlist(struct tm6000_core *dev)
-{
- mutex_lock(&tm6000_devlist_mutex);
- list_add_tail(&dev->devlist, &tm6000_devlist);
- mutex_unlock(&tm6000_devlist_mutex);
-};
-
-/*
- * Extension interface
- */
-
-static LIST_HEAD(tm6000_extension_devlist);
-
-int tm6000_call_fillbuf(struct tm6000_core *dev, enum tm6000_ops_type type,
- char *buf, int size)
-{
- struct tm6000_ops *ops = NULL;
-
- /* FIXME: tm6000_extension_devlist_lock should be a spinlock */
-
- if (!list_empty(&tm6000_extension_devlist)) {
- list_for_each_entry(ops, &tm6000_extension_devlist, next) {
- if (ops->fillbuf && ops->type == type)
- ops->fillbuf(dev, buf, size);
- }
- }
-
- return 0;
-}
-
-int tm6000_register_extension(struct tm6000_ops *ops)
-{
- struct tm6000_core *dev = NULL;
-
- mutex_lock(&tm6000_devlist_mutex);
- list_add_tail(&ops->next, &tm6000_extension_devlist);
- list_for_each_entry(dev, &tm6000_devlist, devlist) {
- ops->init(dev);
- printk(KERN_INFO "%s: Initialized (%s) extension\n",
- dev->name, ops->name);
- }
- mutex_unlock(&tm6000_devlist_mutex);
- return 0;
-}
-EXPORT_SYMBOL(tm6000_register_extension);
-
-void tm6000_unregister_extension(struct tm6000_ops *ops)
-{
- struct tm6000_core *dev = NULL;
-
- mutex_lock(&tm6000_devlist_mutex);
- list_for_each_entry(dev, &tm6000_devlist, devlist)
- ops->fini(dev);
-
- printk(KERN_INFO "tm6000: Remove (%s) extension\n", ops->name);
- list_del(&ops->next);
- mutex_unlock(&tm6000_devlist_mutex);
-}
-EXPORT_SYMBOL(tm6000_unregister_extension);
-
-void tm6000_init_extension(struct tm6000_core *dev)
-{
- struct tm6000_ops *ops = NULL;
-
- mutex_lock(&tm6000_devlist_mutex);
- if (!list_empty(&tm6000_extension_devlist)) {
- list_for_each_entry(ops, &tm6000_extension_devlist, next) {
- if (ops->init)
- ops->init(dev);
- }
- }
- mutex_unlock(&tm6000_devlist_mutex);
-}
-
-void tm6000_close_extension(struct tm6000_core *dev)
-{
- struct tm6000_ops *ops = NULL;
-
- mutex_lock(&tm6000_devlist_mutex);
- if (!list_empty(&tm6000_extension_devlist)) {
- list_for_each_entry(ops, &tm6000_extension_devlist, next) {
- if (ops->fini)
- ops->fini(dev);
- }
- }
- mutex_unlock(&tm6000_devlist_mutex);
-}
diff --git a/drivers/media/video/tm6000/tm6000-dvb.c b/drivers/media/video/tm6000/tm6000-dvb.c
deleted file mode 100644
index e1f3f66e1e6..00000000000
--- a/drivers/media/video/tm6000/tm6000-dvb.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * tm6000-dvb.c - dvb-t support for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-
-#include "tm6000.h"
-#include "tm6000-regs.h"
-
-#include "zl10353.h"
-
-#include <media/tuner.h>
-
-#include "tuner-xc2028.h"
-#include "xc5000.h"
-
-MODULE_DESCRIPTION("DVB driver extension module for tm5600/6000/6010 based TV cards");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
-MODULE_LICENSE("GPL");
-
-MODULE_SUPPORTED_DEVICE("{{Trident, tm5600},"
- "{{Trident, tm6000},"
- "{{Trident, tm6010}");
-
-static int debug;
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debug message");
-
-static inline void print_err_status(struct tm6000_core *dev,
- int packet, int status)
-{
- char *errmsg = "Unknown";
-
- switch (status) {
- case -ENOENT:
- errmsg = "unlinked synchronuously";
- break;
- case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
- break;
- case -ENOSR:
- errmsg = "Buffer error (overrun)";
- break;
- case -EPIPE:
- errmsg = "Stalled (device not responding)";
- break;
- case -EOVERFLOW:
- errmsg = "Babble (bad cable?)";
- break;
- case -EPROTO:
- errmsg = "Bit-stuff error (bad cable?)";
- break;
- case -EILSEQ:
- errmsg = "CRC/Timeout (could be anything)";
- break;
- case -ETIME:
- errmsg = "Device does not respond";
- break;
- }
- if (packet < 0) {
- dprintk(dev, 1, "URB status %d [%s].\n",
- status, errmsg);
- } else {
- dprintk(dev, 1, "URB packet %d, status %d [%s].\n",
- packet, status, errmsg);
- }
-}
-
-static void tm6000_urb_received(struct urb *urb)
-{
- int ret;
- struct tm6000_core *dev = urb->context;
-
- switch (urb->status) {
- case 0:
- case -ETIMEDOUT:
- break;
- case -ENOENT:
- case -ECONNRESET:
- case -ESHUTDOWN:
- return;
- default:
- print_err_status(dev, 0, urb->status);
- }
-
- if (urb->actual_length > 0)
- dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
- urb->actual_length);
-
- if (dev->dvb->streams > 0) {
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0) {
- printk(KERN_ERR "tm6000: error %s\n", __func__);
- kfree(urb->transfer_buffer);
- usb_free_urb(urb);
- }
- }
-}
-
-static int tm6000_start_stream(struct tm6000_core *dev)
-{
- int ret;
- unsigned int pipe, size;
- struct tm6000_dvb *dvb = dev->dvb;
-
- printk(KERN_INFO "tm6000: got start stream request %s\n", __func__);
-
- if (dev->mode != TM6000_MODE_DIGITAL) {
- tm6000_init_digital_mode(dev);
- dev->mode = TM6000_MODE_DIGITAL;
- }
-
- dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (dvb->bulk_urb == NULL) {
- printk(KERN_ERR "tm6000: couldn't allocate urb\n");
- return -ENOMEM;
- }
-
- pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in.endp->desc.bEndpointAddress
- & USB_ENDPOINT_NUMBER_MASK);
-
- size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
- size = size * 15; /* 512 x 8 or 12 or 15 */
-
- dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
- if (dvb->bulk_urb->transfer_buffer == NULL) {
- usb_free_urb(dvb->bulk_urb);
- printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n");
- return -ENOMEM;
- }
-
- usb_fill_bulk_urb(dvb->bulk_urb, dev->udev, pipe,
- dvb->bulk_urb->transfer_buffer,
- size,
- tm6000_urb_received, dev);
-
- ret = usb_clear_halt(dev->udev, pipe);
- if (ret < 0) {
- printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n",
- ret, __func__);
- return ret;
- } else
- printk(KERN_ERR "tm6000: pipe resetted\n");
-
-/* mutex_lock(&tm6000_driver.open_close_mutex); */
- ret = usb_submit_urb(dvb->bulk_urb, GFP_ATOMIC);
-
-/* mutex_unlock(&tm6000_driver.open_close_mutex); */
- if (ret) {
- printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",
- ret);
-
- kfree(dvb->bulk_urb->transfer_buffer);
- usb_free_urb(dvb->bulk_urb);
- return ret;
- }
-
- return 0;
-}
-
-static void tm6000_stop_stream(struct tm6000_core *dev)
-{
- struct tm6000_dvb *dvb = dev->dvb;
-
- if (dvb->bulk_urb) {
- printk(KERN_INFO "urb killing\n");
- usb_kill_urb(dvb->bulk_urb);
- printk(KERN_INFO "urb buffer free\n");
- kfree(dvb->bulk_urb->transfer_buffer);
- usb_free_urb(dvb->bulk_urb);
- dvb->bulk_urb = NULL;
- }
-}
-
-static int tm6000_start_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct tm6000_core *dev = demux->priv;
- struct tm6000_dvb *dvb = dev->dvb;
- printk(KERN_INFO "tm6000: got start feed request %s\n", __func__);
-
- mutex_lock(&dvb->mutex);
- if (dvb->streams == 0) {
- dvb->streams = 1;
-/* mutex_init(&tm6000_dev->streming_mutex); */
- tm6000_start_stream(dev);
- } else
- ++(dvb->streams);
- mutex_unlock(&dvb->mutex);
-
- return 0;
-}
-
-static int tm6000_stop_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct tm6000_core *dev = demux->priv;
- struct tm6000_dvb *dvb = dev->dvb;
-
- printk(KERN_INFO "tm6000: got stop feed request %s\n", __func__);
-
- mutex_lock(&dvb->mutex);
-
- printk(KERN_INFO "stream %#x\n", dvb->streams);
- --(dvb->streams);
- if (dvb->streams == 0) {
- printk(KERN_INFO "stop stream\n");
- tm6000_stop_stream(dev);
-/* mutex_destroy(&tm6000_dev->streaming_mutex); */
- }
- mutex_unlock(&dvb->mutex);
-/* mutex_destroy(&tm6000_dev->streaming_mutex); */
-
- return 0;
-}
-
-static int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
-{
- struct tm6000_dvb *dvb = dev->dvb;
-
- if (dev->caps.has_zl10353) {
- struct zl10353_config config = {
- .demod_address = dev->demod_addr,
- .no_tuner = 1,
- .parallel_ts = 1,
- .if2 = 45700,
- .disable_i2c_gate_ctrl = 1,
- };
-
- dvb->frontend = dvb_attach(zl10353_attach, &config,
- &dev->i2c_adap);
- } else {
- printk(KERN_ERR "tm6000: no frontend defined for the device!\n");
- return -1;
- }
-
- return (!dvb->frontend) ? -1 : 0;
-}
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int register_dvb(struct tm6000_core *dev)
-{
- int ret = -1;
- struct tm6000_dvb *dvb = dev->dvb;
-
- mutex_init(&dvb->mutex);
-
- dvb->streams = 0;
-
- /* attach the frontend */
- ret = tm6000_dvb_attach_frontend(dev);
- if (ret < 0) {
- printk(KERN_ERR "tm6000: couldn't attach the frontend!\n");
- goto err;
- }
-
- ret = dvb_register_adapter(&dvb->adapter, "Trident TVMaster 6000 DVB-T",
- THIS_MODULE, &dev->udev->dev, adapter_nr);
- dvb->adapter.priv = dev;
-
- if (dvb->frontend) {
- switch (dev->tuner_type) {
- case TUNER_XC2028: {
- struct xc2028_config cfg = {
- .i2c_adap = &dev->i2c_adap,
- .i2c_addr = dev->tuner_addr,
- };
-
- dvb->frontend->callback = tm6000_tuner_callback;
- ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
- if (ret < 0) {
- printk(KERN_ERR
- "tm6000: couldn't register frontend\n");
- goto adapter_err;
- }
-
- if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) {
- printk(KERN_ERR "tm6000: couldn't register "
- "frontend (xc3028)\n");
- ret = -EINVAL;
- goto frontend_err;
- }
- printk(KERN_INFO "tm6000: XC2028/3028 asked to be "
- "attached to frontend!\n");
- break;
- }
- case TUNER_XC5000: {
- struct xc5000_config cfg = {
- .i2c_address = dev->tuner_addr,
- };
-
- dvb->frontend->callback = tm6000_xc5000_callback;
- ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
- if (ret < 0) {
- printk(KERN_ERR
- "tm6000: couldn't register frontend\n");
- goto adapter_err;
- }
-
- if (!dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, &cfg)) {
- printk(KERN_ERR "tm6000: couldn't register "
- "frontend (xc5000)\n");
- ret = -EINVAL;
- goto frontend_err;
- }
- printk(KERN_INFO "tm6000: XC5000 asked to be "
- "attached to frontend!\n");
- break;
- }
- }
- } else
- printk(KERN_ERR "tm6000: no frontend found\n");
-
- dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING
- | DMX_MEMORY_BASED_FILTERING;
- dvb->demux.priv = dev;
- dvb->demux.filternum = 8;
- dvb->demux.feednum = 8;
- dvb->demux.start_feed = tm6000_start_feed;
- dvb->demux.stop_feed = tm6000_stop_feed;
- dvb->demux.write_to_decoder = NULL;
- ret = dvb_dmx_init(&dvb->demux);
- if (ret < 0) {
- printk(KERN_ERR "tm6000: dvb_dmx_init failed (errno = %d)\n", ret);
- goto frontend_err;
- }
-
- dvb->dmxdev.filternum = dev->dvb->demux.filternum;
- dvb->dmxdev.demux = &dev->dvb->demux.dmx;
- dvb->dmxdev.capabilities = 0;
-
- ret = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
- if (ret < 0) {
- printk(KERN_ERR "tm6000: dvb_dmxdev_init failed (errno = %d)\n", ret);
- goto dvb_dmx_err;
- }
-
- return 0;
-
-dvb_dmx_err:
- dvb_dmx_release(&dvb->demux);
-frontend_err:
- if (dvb->frontend) {
- dvb_frontend_detach(dvb->frontend);
- dvb_unregister_frontend(dvb->frontend);
- }
-adapter_err:
- dvb_unregister_adapter(&dvb->adapter);
-err:
- return ret;
-}
-
-static void unregister_dvb(struct tm6000_core *dev)
-{
- struct tm6000_dvb *dvb = dev->dvb;
-
- if (dvb->bulk_urb != NULL) {
- struct urb *bulk_urb = dvb->bulk_urb;
-
- kfree(bulk_urb->transfer_buffer);
- bulk_urb->transfer_buffer = NULL;
- usb_unlink_urb(bulk_urb);
- usb_free_urb(bulk_urb);
- }
-
-/* mutex_lock(&tm6000_driver.open_close_mutex); */
- if (dvb->frontend) {
- dvb_frontend_detach(dvb->frontend);
- dvb_unregister_frontend(dvb->frontend);
- }
-
- dvb_dmxdev_release(&dvb->dmxdev);
- dvb_dmx_release(&dvb->demux);
- dvb_unregister_adapter(&dvb->adapter);
- mutex_destroy(&dvb->mutex);
-/* mutex_unlock(&tm6000_driver.open_close_mutex); */
-}
-
-static int dvb_init(struct tm6000_core *dev)
-{
- struct tm6000_dvb *dvb;
- int rc;
-
- if (!dev)
- return 0;
-
- if (!dev->caps.has_dvb)
- return 0;
-
- if (dev->udev->speed == USB_SPEED_FULL) {
- printk(KERN_INFO "This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)\n");
- return 0;
- }
-
- dvb = kzalloc(sizeof(struct tm6000_dvb), GFP_KERNEL);
- if (!dvb) {
- printk(KERN_INFO "Cannot allocate memory\n");
- return -ENOMEM;
- }
-
- dev->dvb = dvb;
-
- rc = register_dvb(dev);
- if (rc < 0) {
- kfree(dvb);
- dev->dvb = NULL;
- return 0;
- }
-
- return 0;
-}
-
-static int dvb_fini(struct tm6000_core *dev)
-{
- if (!dev)
- return 0;
-
- if (!dev->caps.has_dvb)
- return 0;
-
- if (dev->dvb) {
- unregister_dvb(dev);
- kfree(dev->dvb);
- dev->dvb = NULL;
- }
-
- return 0;
-}
-
-static struct tm6000_ops dvb_ops = {
- .type = TM6000_DVB,
- .name = "TM6000 dvb Extension",
- .init = dvb_init,
- .fini = dvb_fini,
-};
-
-static int __init tm6000_dvb_register(void)
-{
- return tm6000_register_extension(&dvb_ops);
-}
-
-static void __exit tm6000_dvb_unregister(void)
-{
- tm6000_unregister_extension(&dvb_ops);
-}
-
-module_init(tm6000_dvb_register);
-module_exit(tm6000_dvb_unregister);
diff --git a/drivers/media/video/tm6000/tm6000-i2c.c b/drivers/media/video/tm6000/tm6000-i2c.c
deleted file mode 100644
index c7e23e3dd75..00000000000
--- a/drivers/media/video/tm6000/tm6000-i2c.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * tm6000-i2c.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
- * - Fix SMBus Read Byte command
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-
-#include "tm6000.h"
-#include "tm6000-regs.h"
-#include <media/v4l2-common.h>
-#include <media/tuner.h>
-#include "tuner-xc2028.h"
-
-
-/* ----------------------------------------------------------- */
-
-static unsigned int i2c_debug;
-module_param(i2c_debug, int, 0644);
-MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
-
-#define i2c_dprintk(lvl, fmt, args...) if (i2c_debug >= lvl) do { \
- printk(KERN_DEBUG "%s at %s: " fmt, \
- dev->name, __func__, ##args); } while (0)
-
-static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr,
- __u8 reg, char *buf, int len)
-{
- int rc;
- unsigned int i2c_packet_limit = 16;
-
- if (dev->dev_type == TM6010)
- i2c_packet_limit = 80;
-
- if (!buf)
- return -1;
-
- if (len < 1 || len > i2c_packet_limit) {
- printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n",
- len, i2c_packet_limit);
- return -1;
- }
-
- /* capture mutex */
- rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN,
- addr | reg << 8, 0, buf, len);
-
- if (rc < 0) {
- /* release mutex */
- return rc;
- }
-
- /* release mutex */
- return rc;
-}
-
-/* Generic read - doesn't work fine with 16bit registers */
-static int tm6000_i2c_recv_regs(struct tm6000_core *dev, unsigned char addr,
- __u8 reg, char *buf, int len)
-{
- int rc;
- u8 b[2];
- unsigned int i2c_packet_limit = 16;
-
- if (dev->dev_type == TM6010)
- i2c_packet_limit = 64;
-
- if (!buf)
- return -1;
-
- if (len < 1 || len > i2c_packet_limit) {
- printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n",
- len, i2c_packet_limit);
- return -1;
- }
-
- /* capture mutex */
- if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) {
- /*
- * Workaround an I2C bug when reading from zl10353
- */
- reg -= 1;
- len += 1;
-
- rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, b, len);
-
- *buf = b[1];
- } else {
- rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len);
- }
-
- /* release mutex */
- return rc;
-}
-
-/*
- * read from a 16bit register
- * for example xc2028, xc3028 or xc3028L
- */
-static int tm6000_i2c_recv_regs16(struct tm6000_core *dev, unsigned char addr,
- __u16 reg, char *buf, int len)
-{
- int rc;
- unsigned char ureg;
-
- if (!buf || len != 2)
- return -1;
-
- /* capture mutex */
- if (dev->dev_type == TM6010) {
- ureg = reg & 0xFF;
- rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN,
- addr | (reg & 0xFF00), 0, &ureg, 1);
-
- if (rc < 0) {
- /* release mutex */
- return rc;
- }
-
- rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR |
- USB_RECIP_DEVICE, REQ_35_AFTEK_TUNER_READ,
- reg, 0, buf, len);
- } else {
- rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR |
- USB_RECIP_DEVICE, REQ_14_SET_GET_I2C_WR2_RDN,
- addr, reg, buf, len);
- }
-
- /* release mutex */
- return rc;
-}
-
-static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg msgs[], int num)
-{
- struct tm6000_core *dev = i2c_adap->algo_data;
- int addr, rc, i, byte;
-
- if (num <= 0)
- return 0;
- for (i = 0; i < num; i++) {
- addr = (msgs[i].addr << 1) & 0xff;
- i2c_dprintk(2, "%s %s addr=0x%x len=%d:",
- (msgs[i].flags & I2C_M_RD) ? "read" : "write",
- i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
- if (msgs[i].flags & I2C_M_RD) {
- /* read request without preceding register selection */
- /*
- * The TM6000 only supports a read transaction
- * immediately after a 1 or 2 byte write to select
- * a register. We cannot fulfil this request.
- */
- i2c_dprintk(2, " read without preceding write not"
- " supported");
- rc = -EOPNOTSUPP;
- goto err;
- } else if (i + 1 < num && msgs[i].len <= 2 &&
- (msgs[i + 1].flags & I2C_M_RD) &&
- msgs[i].addr == msgs[i + 1].addr) {
- /* 1 or 2 byte write followed by a read */
- if (i2c_debug >= 2)
- for (byte = 0; byte < msgs[i].len; byte++)
- printk(KERN_CONT " %02x", msgs[i].buf[byte]);
- i2c_dprintk(2, "; joined to read %s len=%d:",
- i == num - 2 ? "stop" : "nonstop",
- msgs[i + 1].len);
-
- if (msgs[i].len == 2) {
- rc = tm6000_i2c_recv_regs16(dev, addr,
- msgs[i].buf[0] << 8 | msgs[i].buf[1],
- msgs[i + 1].buf, msgs[i + 1].len);
- } else {
- rc = tm6000_i2c_recv_regs(dev, addr, msgs[i].buf[0],
- msgs[i + 1].buf, msgs[i + 1].len);
- }
-
- i++;
-
- if (addr == dev->tuner_addr << 1) {
- tm6000_set_reg(dev, REQ_50_SET_START, 0, 0);
- tm6000_set_reg(dev, REQ_51_SET_STOP, 0, 0);
- }
- if (i2c_debug >= 2)
- for (byte = 0; byte < msgs[i].len; byte++)
- printk(KERN_CONT " %02x", msgs[i].buf[byte]);
- } else {
- /* write bytes */
- if (i2c_debug >= 2)
- for (byte = 0; byte < msgs[i].len; byte++)
- printk(KERN_CONT " %02x", msgs[i].buf[byte]);
- rc = tm6000_i2c_send_regs(dev, addr, msgs[i].buf[0],
- msgs[i].buf + 1, msgs[i].len - 1);
- }
- if (i2c_debug >= 2)
- printk(KERN_CONT "\n");
- if (rc < 0)
- goto err;
- }
-
- return num;
-err:
- i2c_dprintk(2, " ERROR: %i\n", rc);
- return rc;
-}
-
-static int tm6000_i2c_eeprom(struct tm6000_core *dev)
-{
- int i, rc;
- unsigned char *p = dev->eedata;
- unsigned char bytes[17];
-
- dev->i2c_client.addr = 0xa0 >> 1;
- dev->eedata_size = 0;
-
- bytes[16] = '\0';
- for (i = 0; i < sizeof(dev->eedata); ) {
- *p = i;
- rc = tm6000_i2c_recv_regs(dev, 0xa0, i, p, 1);
- if (rc < 1) {
- if (p == dev->eedata)
- goto noeeprom;
- else {
- printk(KERN_WARNING
- "%s: i2c eeprom read error (err=%d)\n",
- dev->name, rc);
- }
- return -EINVAL;
- }
- dev->eedata_size++;
- p++;
- if (0 == (i % 16))
- printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);
- printk(KERN_CONT " %02x", dev->eedata[i]);
- if ((dev->eedata[i] >= ' ') && (dev->eedata[i] <= 'z'))
- bytes[i%16] = dev->eedata[i];
- else
- bytes[i%16] = '.';
-
- i++;
-
- if (0 == (i % 16)) {
- bytes[16] = '\0';
- printk(KERN_CONT " %s\n", bytes);
- }
- }
- if (0 != (i%16)) {
- bytes[i%16] = '\0';
- for (i %= 16; i < 16; i++)
- printk(KERN_CONT " ");
- printk(KERN_CONT " %s\n", bytes);
- }
-
- return 0;
-
-noeeprom:
- printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
- dev->name, rc);
- return -EINVAL;
-}
-
-/* ----------------------------------------------------------- */
-
-/*
- * functionality()
- */
-static u32 functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm tm6000_algo = {
- .master_xfer = tm6000_i2c_xfer,
- .functionality = functionality,
-};
-
-/* ----------------------------------------------------------- */
-
-/*
- * tm6000_i2c_register()
- * register i2c bus
- */
-int tm6000_i2c_register(struct tm6000_core *dev)
-{
- int rc;
-
- dev->i2c_adap.owner = THIS_MODULE;
- dev->i2c_adap.algo = &tm6000_algo;
- dev->i2c_adap.dev.parent = &dev->udev->dev;
- strlcpy(dev->i2c_adap.name, dev->name, sizeof(dev->i2c_adap.name));
- dev->i2c_adap.algo_data = dev;
- i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
- rc = i2c_add_adapter(&dev->i2c_adap);
- if (rc)
- return rc;
-
- dev->i2c_client.adapter = &dev->i2c_adap;
- strlcpy(dev->i2c_client.name, "tm6000 internal", I2C_NAME_SIZE);
- tm6000_i2c_eeprom(dev);
-
- return 0;
-}
-
-/*
- * tm6000_i2c_unregister()
- * unregister i2c_bus
- */
-int tm6000_i2c_unregister(struct tm6000_core *dev)
-{
- i2c_del_adapter(&dev->i2c_adap);
- return 0;
-}
diff --git a/drivers/media/video/tm6000/tm6000-input.c b/drivers/media/video/tm6000/tm6000-input.c
deleted file mode 100644
index e80b7e19047..00000000000
--- a/drivers/media/video/tm6000/tm6000-input.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * tm6000-input.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2010 Stefan Ringel <stefan.ringel@arcor.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include <linux/input.h>
-#include <linux/usb.h>
-
-#include <media/rc-core.h>
-
-#include "tm6000.h"
-#include "tm6000-regs.h"
-
-static unsigned int ir_debug;
-module_param(ir_debug, int, 0644);
-MODULE_PARM_DESC(ir_debug, "debug message level");
-
-static unsigned int enable_ir = 1;
-module_param(enable_ir, int, 0644);
-MODULE_PARM_DESC(enable_ir, "enable ir (default is enable)");
-
-static unsigned int ir_clock_mhz = 12;
-module_param(ir_clock_mhz, int, 0644);
-MODULE_PARM_DESC(enable_ir, "ir clock, in MHz");
-
-#define URB_SUBMIT_DELAY 100 /* ms - Delay to submit an URB request on retrial and init */
-#define URB_INT_LED_DELAY 100 /* ms - Delay to turn led on again on int mode */
-
-#undef dprintk
-
-#define dprintk(level, fmt, arg...) do {\
- if (ir_debug >= level) \
- printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
- } while (0)
-
-struct tm6000_ir_poll_result {
- u16 rc_data;
-};
-
-struct tm6000_IR {
- struct tm6000_core *dev;
- struct rc_dev *rc;
- char name[32];
- char phys[32];
-
- /* poll expernal decoder */
- int polling;
- struct delayed_work work;
- u8 wait:1;
- u8 pwled:2;
- u8 submit_urb:1;
- u16 key_addr;
- struct urb *int_urb;
-
- /* IR device properties */
- u64 rc_type;
-};
-
-void tm6000_ir_wait(struct tm6000_core *dev, u8 state)
-{
- struct tm6000_IR *ir = dev->ir;
-
- if (!dev->ir)
- return;
-
- dprintk(2, "%s: %i\n",__func__, ir->wait);
-
- if (state)
- ir->wait = 1;
- else
- ir->wait = 0;
-}
-
-static int tm6000_ir_config(struct tm6000_IR *ir)
-{
- struct tm6000_core *dev = ir->dev;
- u32 pulse = 0, leader = 0;
-
- dprintk(2, "%s\n",__func__);
-
- /*
- * The IR decoder supports RC-5 or NEC, with a configurable timing.
- * The timing configuration there is not that accurate, as it uses
- * approximate values. The NEC spec mentions a 562.5 unit period,
- * and RC-5 uses a 888.8 period.
- * Currently, driver assumes a clock provided by a 12 MHz XTAL, but
- * a modprobe parameter can adjust it.
- * Adjustments are required for other timings.
- * It seems that the 900ms timing for NEC is used to detect a RC-5
- * IR, in order to discard such decoding
- */
-
- switch (ir->rc_type) {
- case RC_TYPE_NEC:
- leader = 900; /* ms */
- pulse = 700; /* ms - the actual value would be 562 */
- break;
- default:
- case RC_TYPE_RC5:
- leader = 900; /* ms - from the NEC decoding */
- pulse = 1780; /* ms - The actual value would be 1776 */
- break;
- }
-
- pulse = ir_clock_mhz * pulse;
- leader = ir_clock_mhz * leader;
- if (ir->rc_type == RC_TYPE_NEC)
- leader = leader | 0x8000;
-
- dprintk(2, "%s: %s, %d MHz, leader = 0x%04x, pulse = 0x%06x \n",
- __func__,
- (ir->rc_type == RC_TYPE_NEC) ? "NEC" : "RC-5",
- ir_clock_mhz, leader, pulse);
-
- /* Remote WAKEUP = enable, normal mode, from IR decoder output */
- tm6000_set_reg(dev, TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe);
-
- /* Enable IR reception on non-busrt mode */
- tm6000_set_reg(dev, TM6010_REQ07_RD8_IR, 0x2f);
-
- /* IR_WKUP_SEL = Low byte in decoded IR data */
- tm6000_set_reg(dev, TM6010_REQ07_RDA_IR_WAKEUP_SEL, 0xff);
- /* IR_WKU_ADD code */
- tm6000_set_reg(dev, TM6010_REQ07_RDB_IR_WAKEUP_ADD, 0xff);
-
- tm6000_set_reg(dev, TM6010_REQ07_RDC_IR_LEADER1, leader >> 8);
- tm6000_set_reg(dev, TM6010_REQ07_RDD_IR_LEADER0, leader);
-
- tm6000_set_reg(dev, TM6010_REQ07_RDE_IR_PULSE_CNT1, pulse >> 8);
- tm6000_set_reg(dev, TM6010_REQ07_RDF_IR_PULSE_CNT0, pulse);
-
- if (!ir->polling)
- tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
- else
- tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1);
- msleep(10);
-
- /* Shows that IR is working via the LED */
- tm6000_flash_led(dev, 0);
- msleep(100);
- tm6000_flash_led(dev, 1);
- ir->pwled = 1;
-
- return 0;
-}
-
-static void tm6000_ir_urb_received(struct urb *urb)
-{
- struct tm6000_core *dev = urb->context;
- struct tm6000_IR *ir = dev->ir;
- struct tm6000_ir_poll_result poll_result;
- char *buf;
-
- dprintk(2, "%s\n",__func__);
- if (urb->status < 0 || urb->actual_length <= 0) {
- printk(KERN_INFO "tm6000: IR URB failure: status: %i, length %i\n",
- urb->status, urb->actual_length);
- ir->submit_urb = 1;
- schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY));
- return;
- }
- buf = urb->transfer_buffer;
-
- if (ir_debug)
- print_hex_dump(KERN_DEBUG, "tm6000: IR data: ",
- DUMP_PREFIX_OFFSET,16, 1,
- buf, urb->actual_length, false);
-
- poll_result.rc_data = buf[0];
- if (urb->actual_length > 1)
- poll_result.rc_data |= buf[1] << 8;
-
- dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data);
- rc_keydown(ir->rc, poll_result.rc_data, 0);
-
- usb_submit_urb(urb, GFP_ATOMIC);
- /*
- * Flash the led. We can't do it here, as it is running on IRQ context.
- * So, use the scheduler to do it, in a few ms.
- */
- ir->pwled = 2;
- schedule_delayed_work(&ir->work, msecs_to_jiffies(10));
-}
-
-static void tm6000_ir_handle_key(struct work_struct *work)
-{
- struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work);
- struct tm6000_core *dev = ir->dev;
- struct tm6000_ir_poll_result poll_result;
- int rc;
- u8 buf[2];
-
- if (ir->wait)
- return;
-
- dprintk(3, "%s\n",__func__);
-
- rc = tm6000_read_write_usb(dev, USB_DIR_IN |
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- REQ_02_GET_IR_CODE, 0, 0, buf, 2);
- if (rc < 0)
- return;
-
- if (rc > 1)
- poll_result.rc_data = buf[0] | buf[1] << 8;
- else
- poll_result.rc_data = buf[0];
-
- /* Check if something was read */
- if ((poll_result.rc_data & 0xff) == 0xff) {
- if (!ir->pwled) {
- tm6000_flash_led(dev, 1);
- ir->pwled = 1;
- }
- return;
- }
-
- dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data);
- rc_keydown(ir->rc, poll_result.rc_data, 0);
- tm6000_flash_led(dev, 0);
- ir->pwled = 0;
-
- /* Re-schedule polling */
- schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
-}
-
-static void tm6000_ir_int_work(struct work_struct *work)
-{
- struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work);
- struct tm6000_core *dev = ir->dev;
- int rc;
-
- dprintk(3, "%s, submit_urb = %d, pwled = %d\n",__func__, ir->submit_urb,
- ir->pwled);
-
- if (ir->submit_urb) {
- dprintk(3, "Resubmit urb\n");
- tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
-
- rc = usb_submit_urb(ir->int_urb, GFP_ATOMIC);
- if (rc < 0) {
- printk(KERN_ERR "tm6000: Can't submit an IR interrupt. Error %i\n",
- rc);
- /* Retry in 100 ms */
- schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY));
- return;
- }
- ir->submit_urb = 0;
- }
-
- /* Led is enabled only if USB submit doesn't fail */
- if (ir->pwled == 2) {
- tm6000_flash_led(dev, 0);
- ir->pwled = 0;
- schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_INT_LED_DELAY));
- } else if (!ir->pwled) {
- tm6000_flash_led(dev, 1);
- ir->pwled = 1;
- }
-}
-
-static int tm6000_ir_start(struct rc_dev *rc)
-{
- struct tm6000_IR *ir = rc->priv;
-
- dprintk(2, "%s\n",__func__);
-
- schedule_delayed_work(&ir->work, 0);
-
- return 0;
-}
-
-static void tm6000_ir_stop(struct rc_dev *rc)
-{
- struct tm6000_IR *ir = rc->priv;
-
- dprintk(2, "%s\n",__func__);
-
- cancel_delayed_work_sync(&ir->work);
-}
-
-static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
-{
- struct tm6000_IR *ir = rc->priv;
-
- if (!ir)
- return 0;
-
- dprintk(2, "%s\n",__func__);
-
- if ((rc->rc_map.scan) && (rc_type == RC_TYPE_NEC))
- ir->key_addr = ((rc->rc_map.scan[0].scancode >> 8) & 0xffff);
-
- ir->rc_type = rc_type;
-
- tm6000_ir_config(ir);
- /* TODO */
- return 0;
-}
-
-static int __tm6000_ir_int_start(struct rc_dev *rc)
-{
- struct tm6000_IR *ir = rc->priv;
- struct tm6000_core *dev = ir->dev;
- int pipe, size;
- int err = -ENOMEM;
-
- if (!ir)
- return -ENODEV;
-
- dprintk(2, "%s\n",__func__);
-
- ir->int_urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!ir->int_urb)
- return -ENOMEM;
-
- pipe = usb_rcvintpipe(dev->udev,
- dev->int_in.endp->desc.bEndpointAddress
- & USB_ENDPOINT_NUMBER_MASK);
-
- size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
- dprintk(1, "IR max size: %d\n", size);
-
- ir->int_urb->transfer_buffer = kzalloc(size, GFP_ATOMIC);
- if (ir->int_urb->transfer_buffer == NULL) {
- usb_free_urb(ir->int_urb);
- return err;
- }
- dprintk(1, "int interval: %d\n", dev->int_in.endp->desc.bInterval);
-
- usb_fill_int_urb(ir->int_urb, dev->udev, pipe,
- ir->int_urb->transfer_buffer, size,
- tm6000_ir_urb_received, dev,
- dev->int_in.endp->desc.bInterval);
-
- ir->submit_urb = 1;
- schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY));
-
- return 0;
-}
-
-static void __tm6000_ir_int_stop(struct rc_dev *rc)
-{
- struct tm6000_IR *ir = rc->priv;
-
- if (!ir || !ir->int_urb)
- return;
-
- dprintk(2, "%s\n",__func__);
-
- usb_kill_urb(ir->int_urb);
- kfree(ir->int_urb->transfer_buffer);
- usb_free_urb(ir->int_urb);
- ir->int_urb = NULL;
-}
-
-int tm6000_ir_int_start(struct tm6000_core *dev)
-{
- struct tm6000_IR *ir = dev->ir;
-
- if (!ir)
- return 0;
-
- return __tm6000_ir_int_start(ir->rc);
-}
-
-void tm6000_ir_int_stop(struct tm6000_core *dev)
-{
- struct tm6000_IR *ir = dev->ir;
-
- if (!ir || !ir->rc)
- return;
-
- __tm6000_ir_int_stop(ir->rc);
-}
-
-int tm6000_ir_init(struct tm6000_core *dev)
-{
- struct tm6000_IR *ir;
- struct rc_dev *rc;
- int err = -ENOMEM;
-
- if (!enable_ir)
- return -ENODEV;
-
- if (!dev->caps.has_remote)
- return 0;
-
- if (!dev->ir_codes)
- return 0;
-
- ir = kzalloc(sizeof(*ir), GFP_ATOMIC);
- rc = rc_allocate_device();
- if (!ir || !rc)
- goto out;
-
- dprintk(2, "%s\n", __func__);
-
- /* record handles to ourself */
- ir->dev = dev;
- dev->ir = ir;
- ir->rc = rc;
-
- /* input setup */
- rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
- /* Neded, in order to support NEC remotes with 24 or 32 bits */
- rc->scanmask = 0xffff;
- rc->priv = ir;
- rc->change_protocol = tm6000_ir_change_protocol;
- if (dev->int_in.endp) {
- rc->open = __tm6000_ir_int_start;
- rc->close = __tm6000_ir_int_stop;
- INIT_DELAYED_WORK(&ir->work, tm6000_ir_int_work);
- } else {
- rc->open = tm6000_ir_start;
- rc->close = tm6000_ir_stop;
- ir->polling = 50;
- INIT_DELAYED_WORK(&ir->work, tm6000_ir_handle_key);
- }
- rc->driver_type = RC_DRIVER_SCANCODE;
-
- snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
- dev->name);
-
- usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
- strlcat(ir->phys, "/input0", sizeof(ir->phys));
-
- tm6000_ir_change_protocol(rc, RC_TYPE_UNKNOWN);
-
- rc->input_name = ir->name;
- rc->input_phys = ir->phys;
- rc->input_id.bustype = BUS_USB;
- rc->input_id.version = 1;
- rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
- rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
- rc->map_name = dev->ir_codes;
- rc->driver_name = "tm6000";
- rc->dev.parent = &dev->udev->dev;
-
- /* ir register */
- err = rc_register_device(rc);
- if (err)
- goto out;
-
- return 0;
-
-out:
- dev->ir = NULL;
- rc_free_device(rc);
- kfree(ir);
- return err;
-}
-
-int tm6000_ir_fini(struct tm6000_core *dev)
-{
- struct tm6000_IR *ir = dev->ir;
-
- /* skip detach on non attached board */
-
- if (!ir)
- return 0;
-
- dprintk(2, "%s\n",__func__);
-
- if (!ir->polling)
- __tm6000_ir_int_stop(ir->rc);
-
- tm6000_ir_stop(ir->rc);
-
- /* Turn off the led */
- tm6000_flash_led(dev, 0);
- ir->pwled = 0;
-
- rc_unregister_device(ir->rc);
-
- kfree(ir);
- dev->ir = NULL;
-
- return 0;
-}
diff --git a/drivers/media/video/tm6000/tm6000-regs.h b/drivers/media/video/tm6000/tm6000-regs.h
deleted file mode 100644
index a38c251ed57..00000000000
--- a/drivers/media/video/tm6000/tm6000-regs.h
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * tm6000-regs.h - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * Define TV Master TM5600/TM6000/TM6010 Request codes
- */
-#define REQ_00_SET_IR_VALUE 0
-#define REQ_01_SET_WAKEUP_IRCODE 1
-#define REQ_02_GET_IR_CODE 2
-#define REQ_03_SET_GET_MCU_PIN 3
-#define REQ_04_EN_DISABLE_MCU_INT 4
-#define REQ_05_SET_GET_USBREG 5
- /* Write: RegNum, Value, 0 */
- /* Read : RegNum, Value, 1, RegStatus */
-#define REQ_06_SET_GET_USBREG_BIT 6
-#define REQ_07_SET_GET_AVREG 7
- /* Write: RegNum, Value, 0 */
- /* Read : RegNum, Value, 1, RegStatus */
-#define REQ_08_SET_GET_AVREG_BIT 8
-#define REQ_09_SET_GET_TUNER_FQ 9
-#define REQ_10_SET_TUNER_SYSTEM 10
-#define REQ_11_SET_EEPROM_ADDR 11
-#define REQ_12_SET_GET_EEPROMBYTE 12
-#define REQ_13_GET_EEPROM_SEQREAD 13
-#define REQ_14_SET_GET_I2C_WR2_RDN 14
-#define REQ_15_SET_GET_I2CBYTE 15
- /* Write: Subaddr, Slave Addr, value, 0 */
- /* Read : Subaddr, Slave Addr, value, 1 */
-#define REQ_16_SET_GET_I2C_WR1_RDN 16
- /* Subaddr, Slave Addr, 0, length */
-#define REQ_17_SET_GET_I2CFP 17
- /* Write: Slave Addr, register, value */
- /* Read : Slave Addr, register, 2, data */
-#define REQ_20_DATA_TRANSFER 20
-#define REQ_30_I2C_WRITE 30
-#define REQ_31_I2C_READ 31
-#define REQ_35_AFTEK_TUNER_READ 35
-#define REQ_40_GET_VERSION 40
-#define REQ_50_SET_START 50
-#define REQ_51_SET_STOP 51
-#define REQ_52_TRANSMIT_DATA 52
-#define REQ_53_SPI_INITIAL 53
-#define REQ_54_SPI_SETSTART 54
-#define REQ_55_SPI_INOUTDATA 55
-#define REQ_56_SPI_SETSTOP 56
-
-/*
- * Define TV Master TM5600/TM6000/TM6010 GPIO lines
- */
-
-#define TM6000_GPIO_CLK 0x101
-#define TM6000_GPIO_DATA 0x100
-
-#define TM6000_GPIO_1 0x102
-#define TM6000_GPIO_2 0x103
-#define TM6000_GPIO_3 0x104
-#define TM6000_GPIO_4 0x300
-#define TM6000_GPIO_5 0x301
-#define TM6000_GPIO_6 0x304
-#define TM6000_GPIO_7 0x305
-
-/* tm6010 defines GPIO with different values */
-#define TM6010_GPIO_0 0x0102
-#define TM6010_GPIO_1 0x0103
-#define TM6010_GPIO_2 0x0104
-#define TM6010_GPIO_3 0x0105
-#define TM6010_GPIO_4 0x0106
-#define TM6010_GPIO_5 0x0107
-#define TM6010_GPIO_6 0x0300
-#define TM6010_GPIO_7 0x0301
-#define TM6010_GPIO_9 0x0305
-/*
- * Define TV Master TM5600/TM6000/TM6010 URB message codes and length
- */
-
-enum {
- TM6000_URB_MSG_VIDEO = 1,
- TM6000_URB_MSG_AUDIO,
- TM6000_URB_MSG_VBI,
- TM6000_URB_MSG_PTS,
- TM6000_URB_MSG_ERR,
-};
-
-/* Define specific TM6000 Video decoder registers */
-#define TM6000_REQ07_RD8_TEST_SEL 0x07, 0xd8
-#define TM6000_REQ07_RD9_A_SIM_SEL 0x07, 0xd9
-#define TM6000_REQ07_RDA_CLK_SEL 0x07, 0xda
-#define TM6000_REQ07_RDB_OUT_SEL 0x07, 0xdb
-#define TM6000_REQ07_RDC_NSEL_I2S 0x07, 0xdc
-#define TM6000_REQ07_RDD_GPIO2_MDRV 0x07, 0xdd
-#define TM6000_REQ07_RDE_GPIO1_MDRV 0x07, 0xde
-#define TM6000_REQ07_RDF_PWDOWN_ACLK 0x07, 0xdf
-#define TM6000_REQ07_RE0_VADC_REF_CTL 0x07, 0xe0
-#define TM6000_REQ07_RE1_VADC_DACLIMP 0x07, 0xe1
-#define TM6000_REQ07_RE2_VADC_STATUS_CTL 0x07, 0xe2
-#define TM6000_REQ07_RE3_VADC_INP_LPF_SEL1 0x07, 0xe3
-#define TM6000_REQ07_RE4_VADC_TARGET1 0x07, 0xe4
-#define TM6000_REQ07_RE5_VADC_INP_LPF_SEL2 0x07, 0xe5
-#define TM6000_REQ07_RE6_VADC_TARGET2 0x07, 0xe6
-#define TM6000_REQ07_RE7_VADC_AGAIN_CTL 0x07, 0xe7
-#define TM6000_REQ07_RE8_VADC_PWDOWN_CTL 0x07, 0xe8
-#define TM6000_REQ07_RE9_VADC_INPUT_CTL1 0x07, 0xe9
-#define TM6000_REQ07_REA_VADC_INPUT_CTL2 0x07, 0xea
-#define TM6000_REQ07_REB_VADC_AADC_MODE 0x07, 0xeb
-#define TM6000_REQ07_REC_VADC_AADC_LVOL 0x07, 0xec
-#define TM6000_REQ07_RED_VADC_AADC_RVOL 0x07, 0xed
-#define TM6000_REQ07_REE_VADC_CTRL_SEL_CONTROL 0x07, 0xee
-#define TM6000_REQ07_REF_VADC_GAIN_MAP_CTL 0x07, 0xef
-#define TM6000_REQ07_RFD_BIST_ERR_VST_LOW 0x07, 0xfd
-#define TM6000_REQ07_RFE_BIST_ERR_VST_HIGH 0x07, 0xfe
-
-/* Define TM6000/TM6010 Video decoder registers */
-#define TM6010_REQ07_R00_VIDEO_CONTROL0 0x07, 0x00
-#define TM6010_REQ07_R01_VIDEO_CONTROL1 0x07, 0x01
-#define TM6010_REQ07_R02_VIDEO_CONTROL2 0x07, 0x02
-#define TM6010_REQ07_R03_YC_SEP_CONTROL 0x07, 0x03
-#define TM6010_REQ07_R04_LUMA_HAGC_CONTROL 0x07, 0x04
-#define TM6010_REQ07_R05_NOISE_THRESHOLD 0x07, 0x05
-#define TM6010_REQ07_R06_AGC_GATE_THRESHOLD 0x07, 0x06
-#define TM6010_REQ07_R07_OUTPUT_CONTROL 0x07, 0x07
-#define TM6010_REQ07_R08_LUMA_CONTRAST_ADJ 0x07, 0x08
-#define TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ 0x07, 0x09
-#define TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ 0x07, 0x0a
-#define TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ 0x07, 0x0b
-#define TM6010_REQ07_R0C_CHROMA_AGC_CONTROL 0x07, 0x0c
-#define TM6010_REQ07_R0D_CHROMA_KILL_LEVEL 0x07, 0x0d
-#define TM6010_REQ07_R0F_CHROMA_AUTO_POSITION 0x07, 0x0f
-#define TM6010_REQ07_R10_AGC_PEAK_NOMINAL 0x07, 0x10
-#define TM6010_REQ07_R11_AGC_PEAK_CONTROL 0x07, 0x11
-#define TM6010_REQ07_R12_AGC_GATE_STARTH 0x07, 0x12
-#define TM6010_REQ07_R13_AGC_GATE_STARTL 0x07, 0x13
-#define TM6010_REQ07_R14_AGC_GATE_WIDTH 0x07, 0x14
-#define TM6010_REQ07_R15_AGC_BP_DELAY 0x07, 0x15
-#define TM6010_REQ07_R16_LOCK_COUNT 0x07, 0x16
-#define TM6010_REQ07_R17_HLOOP_MAXSTATE 0x07, 0x17
-#define TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3 0x07, 0x18
-#define TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2 0x07, 0x19
-#define TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1 0x07, 0x1a
-#define TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0 0x07, 0x1b
-#define TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3 0x07, 0x1c
-#define TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2 0x07, 0x1d
-#define TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1 0x07, 0x1e
-#define TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0 0x07, 0x1f
-#define TM6010_REQ07_R20_HSYNC_RISING_EDGE_TIME 0x07, 0x20
-#define TM6010_REQ07_R21_HSYNC_PHASE_OFFSET 0x07, 0x21
-#define TM6010_REQ07_R22_HSYNC_PLL_START_TIME 0x07, 0x22
-#define TM6010_REQ07_R23_HSYNC_PLL_END_TIME 0x07, 0x23
-#define TM6010_REQ07_R24_HSYNC_TIP_START_TIME 0x07, 0x24
-#define TM6010_REQ07_R25_HSYNC_TIP_END_TIME 0x07, 0x25
-#define TM6010_REQ07_R26_HSYNC_RISING_EDGE_START 0x07, 0x26
-#define TM6010_REQ07_R27_HSYNC_RISING_EDGE_END 0x07, 0x27
-#define TM6010_REQ07_R28_BACKPORCH_START 0x07, 0x28
-#define TM6010_REQ07_R29_BACKPORCH_END 0x07, 0x29
-#define TM6010_REQ07_R2A_HSYNC_FILTER_START 0x07, 0x2a
-#define TM6010_REQ07_R2B_HSYNC_FILTER_END 0x07, 0x2b
-#define TM6010_REQ07_R2C_CHROMA_BURST_START 0x07, 0x2c
-#define TM6010_REQ07_R2D_CHROMA_BURST_END 0x07, 0x2d
-#define TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART 0x07, 0x2e
-#define TM6010_REQ07_R2F_ACTIVE_VIDEO_HWIDTH 0x07, 0x2f
-#define TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART 0x07, 0x30
-#define TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT 0x07, 0x31
-#define TM6010_REQ07_R32_VSYNC_HLOCK_MIN 0x07, 0x32
-#define TM6010_REQ07_R33_VSYNC_HLOCK_MAX 0x07, 0x33
-#define TM6010_REQ07_R34_VSYNC_AGC_MIN 0x07, 0x34
-#define TM6010_REQ07_R35_VSYNC_AGC_MAX 0x07, 0x35
-#define TM6010_REQ07_R36_VSYNC_VBI_MIN 0x07, 0x36
-#define TM6010_REQ07_R37_VSYNC_VBI_MAX 0x07, 0x37
-#define TM6010_REQ07_R38_VSYNC_THRESHOLD 0x07, 0x38
-#define TM6010_REQ07_R39_VSYNC_TIME_CONSTANT 0x07, 0x39
-#define TM6010_REQ07_R3A_STATUS1 0x07, 0x3a
-#define TM6010_REQ07_R3B_STATUS2 0x07, 0x3b
-#define TM6010_REQ07_R3C_STATUS3 0x07, 0x3c
-#define TM6010_REQ07_R3F_RESET 0x07, 0x3f
-#define TM6010_REQ07_R40_TELETEXT_VBI_CODE0 0x07, 0x40
-#define TM6010_REQ07_R41_TELETEXT_VBI_CODE1 0x07, 0x41
-#define TM6010_REQ07_R42_VBI_DATA_HIGH_LEVEL 0x07, 0x42
-#define TM6010_REQ07_R43_VBI_DATA_TYPE_LINE7 0x07, 0x43
-#define TM6010_REQ07_R44_VBI_DATA_TYPE_LINE8 0x07, 0x44
-#define TM6010_REQ07_R45_VBI_DATA_TYPE_LINE9 0x07, 0x45
-#define TM6010_REQ07_R46_VBI_DATA_TYPE_LINE10 0x07, 0x46
-#define TM6010_REQ07_R47_VBI_DATA_TYPE_LINE11 0x07, 0x47
-#define TM6010_REQ07_R48_VBI_DATA_TYPE_LINE12 0x07, 0x48
-#define TM6010_REQ07_R49_VBI_DATA_TYPE_LINE13 0x07, 0x49
-#define TM6010_REQ07_R4A_VBI_DATA_TYPE_LINE14 0x07, 0x4a
-#define TM6010_REQ07_R4B_VBI_DATA_TYPE_LINE15 0x07, 0x4b
-#define TM6010_REQ07_R4C_VBI_DATA_TYPE_LINE16 0x07, 0x4c
-#define TM6010_REQ07_R4D_VBI_DATA_TYPE_LINE17 0x07, 0x4d
-#define TM6010_REQ07_R4E_VBI_DATA_TYPE_LINE18 0x07, 0x4e
-#define TM6010_REQ07_R4F_VBI_DATA_TYPE_LINE19 0x07, 0x4f
-#define TM6010_REQ07_R50_VBI_DATA_TYPE_LINE20 0x07, 0x50
-#define TM6010_REQ07_R51_VBI_DATA_TYPE_LINE21 0x07, 0x51
-#define TM6010_REQ07_R52_VBI_DATA_TYPE_LINE22 0x07, 0x52
-#define TM6010_REQ07_R53_VBI_DATA_TYPE_LINE23 0x07, 0x53
-#define TM6010_REQ07_R54_VBI_DATA_TYPE_RLINES 0x07, 0x54
-#define TM6010_REQ07_R55_VBI_LOOP_FILTER_GAIN 0x07, 0x55
-#define TM6010_REQ07_R56_VBI_LOOP_FILTER_I_GAIN 0x07, 0x56
-#define TM6010_REQ07_R57_VBI_LOOP_FILTER_P_GAIN 0x07, 0x57
-#define TM6010_REQ07_R58_VBI_CAPTION_DTO1 0x07, 0x58
-#define TM6010_REQ07_R59_VBI_CAPTION_DTO0 0x07, 0x59
-#define TM6010_REQ07_R5A_VBI_TELETEXT_DTO1 0x07, 0x5a
-#define TM6010_REQ07_R5B_VBI_TELETEXT_DTO0 0x07, 0x5b
-#define TM6010_REQ07_R5C_VBI_WSS625_DTO1 0x07, 0x5c
-#define TM6010_REQ07_R5D_VBI_WSS625_DTO0 0x07, 0x5d
-#define TM6010_REQ07_R5E_VBI_CAPTION_FRAME_START 0x07, 0x5e
-#define TM6010_REQ07_R5F_VBI_WSS625_FRAME_START 0x07, 0x5f
-#define TM6010_REQ07_R60_TELETEXT_FRAME_START 0x07, 0x60
-#define TM6010_REQ07_R61_VBI_CCDATA1 0x07, 0x61
-#define TM6010_REQ07_R62_VBI_CCDATA2 0x07, 0x62
-#define TM6010_REQ07_R63_VBI_WSS625_DATA1 0x07, 0x63
-#define TM6010_REQ07_R64_VBI_WSS625_DATA2 0x07, 0x64
-#define TM6010_REQ07_R65_VBI_DATA_STATUS 0x07, 0x65
-#define TM6010_REQ07_R66_VBI_CAPTION_START 0x07, 0x66
-#define TM6010_REQ07_R67_VBI_WSS625_START 0x07, 0x67
-#define TM6010_REQ07_R68_VBI_TELETEXT_START 0x07, 0x68
-#define TM6010_REQ07_R70_HSYNC_DTO_INC_STATUS3 0x07, 0x70
-#define TM6010_REQ07_R71_HSYNC_DTO_INC_STATUS2 0x07, 0x71
-#define TM6010_REQ07_R72_HSYNC_DTO_INC_STATUS1 0x07, 0x72
-#define TM6010_REQ07_R73_HSYNC_DTO_INC_STATUS0 0x07, 0x73
-#define TM6010_REQ07_R74_CHROMA_DTO_INC_STATUS3 0x07, 0x74
-#define TM6010_REQ07_R75_CHROMA_DTO_INC_STATUS2 0x07, 0x75
-#define TM6010_REQ07_R76_CHROMA_DTO_INC_STATUS1 0x07, 0x76
-#define TM6010_REQ07_R77_CHROMA_DTO_INC_STATUS0 0x07, 0x77
-#define TM6010_REQ07_R78_AGC_AGAIN_STATUS 0x07, 0x78
-#define TM6010_REQ07_R79_AGC_DGAIN_STATUS 0x07, 0x79
-#define TM6010_REQ07_R7A_CHROMA_MAG_STATUS 0x07, 0x7a
-#define TM6010_REQ07_R7B_CHROMA_GAIN_STATUS1 0x07, 0x7b
-#define TM6010_REQ07_R7C_CHROMA_GAIN_STATUS0 0x07, 0x7c
-#define TM6010_REQ07_R7D_CORDIC_FREQ_STATUS 0x07, 0x7d
-#define TM6010_REQ07_R7F_STATUS_NOISE 0x07, 0x7f
-#define TM6010_REQ07_R80_COMB_FILTER_TRESHOLD 0x07, 0x80
-#define TM6010_REQ07_R82_COMB_FILTER_CONFIG 0x07, 0x82
-#define TM6010_REQ07_R83_CHROMA_LOCK_CONFIG 0x07, 0x83
-#define TM6010_REQ07_R84_NOISE_NTSC_C 0x07, 0x84
-#define TM6010_REQ07_R85_NOISE_PAL_C 0x07, 0x85
-#define TM6010_REQ07_R86_NOISE_PHASE_C 0x07, 0x86
-#define TM6010_REQ07_R87_NOISE_PHASE_Y 0x07, 0x87
-#define TM6010_REQ07_R8A_CHROMA_LOOPFILTER_STATE 0x07, 0x8a
-#define TM6010_REQ07_R8B_CHROMA_HRESAMPLER 0x07, 0x8b
-#define TM6010_REQ07_R8D_CPUMP_DELAY_ADJ 0x07, 0x8d
-#define TM6010_REQ07_R8E_CPUMP_ADJ 0x07, 0x8e
-#define TM6010_REQ07_R8F_CPUMP_DELAY 0x07, 0x8f
-
-/* Define TM6000/TM6010 Miscellaneous registers */
-#define TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE 0x07, 0xc0
-#define TM6010_REQ07_RC1_TRESHOLD 0x07, 0xc1
-#define TM6010_REQ07_RC2_HSYNC_WIDTH 0x07, 0xc2
-#define TM6010_REQ07_RC3_HSTART1 0x07, 0xc3
-#define TM6010_REQ07_RC4_HSTART0 0x07, 0xc4
-#define TM6010_REQ07_RC5_HEND1 0x07, 0xc5
-#define TM6010_REQ07_RC6_HEND0 0x07, 0xc6
-#define TM6010_REQ07_RC7_VSTART1 0x07, 0xc7
-#define TM6010_REQ07_RC8_VSTART0 0x07, 0xc8
-#define TM6010_REQ07_RC9_VEND1 0x07, 0xc9
-#define TM6010_REQ07_RCA_VEND0 0x07, 0xca
-#define TM6010_REQ07_RCB_DELAY 0x07, 0xcb
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RCC_ACTIVE_IF 0x07, 0xcc
-#define TM6010_REQ07_RCC_ACTIVE_IF_VIDEO_ENABLE (1 << 5)
-#define TM6010_REQ07_RCC_ACTIVE_IF_AUDIO_ENABLE (1 << 6)
-#define TM6010_REQ07_RD0_USB_PERIPHERY_CONTROL 0x07, 0xd0
-#define TM6010_REQ07_RD1_ADDR_FOR_REQ1 0x07, 0xd1
-#define TM6010_REQ07_RD2_ADDR_FOR_REQ2 0x07, 0xd2
-#define TM6010_REQ07_RD3_ADDR_FOR_REQ3 0x07, 0xd3
-#define TM6010_REQ07_RD4_ADDR_FOR_REQ4 0x07, 0xd4
-#define TM6010_REQ07_RD5_POWERSAVE 0x07, 0xd5
-#define TM6010_REQ07_RD6_ENDP_REQ1_REQ2 0x07, 0xd6
-#define TM6010_REQ07_RD7_ENDP_REQ3_REQ4 0x07, 0xd7
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RD8_IR 0x07, 0xd8
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RD9_IR_BSIZE 0x07, 0xd9
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RDA_IR_WAKEUP_SEL 0x07, 0xda
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RDB_IR_WAKEUP_ADD 0x07, 0xdb
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RDC_IR_LEADER1 0x07, 0xdc
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RDD_IR_LEADER0 0x07, 0xdd
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RDE_IR_PULSE_CNT1 0x07, 0xde
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RDF_IR_PULSE_CNT0 0x07, 0xdf
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RE0_DVIDEO_SOURCE 0x07, 0xe0
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RE0_DVIDEO_SOURCE_IF 0x07, 0xe1
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RE2_OUT_SEL2 0x07, 0xe2
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RE3_OUT_SEL1 0x07, 0xe3
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RE4_OUT_SEL0 0x07, 0xe4
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RE5_REMOTE_WAKEUP 0x07, 0xe5
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RE7_PUB_GPIO 0x07, 0xe7
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RE8_TYPESEL_MOS_I2S 0x07, 0xe8
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RE9_TYPESEL_MOS_TS 0x07, 0xe9
-/* ONLY for TM6010 */
-#define TM6010_REQ07_REA_TYPESEL_MOS_CCIR 0x07, 0xea
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RF0_BIST_CRC_RESULT0 0x07, 0xf0
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RF1_BIST_CRC_RESULT1 0x07, 0xf1
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RF2_BIST_CRC_RESULT2 0x07, 0xf2
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RF3_BIST_CRC_RESULT3 0x07, 0xf3
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RF4_BIST_ERR_VST2 0x07, 0xf4
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RF5_BIST_ERR_VST1 0x07, 0xf5
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RF6_BIST_ERR_VST0 0x07, 0xf6
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RF7_BIST 0x07, 0xf7
-/* ONLY for TM6010 */
-#define TM6010_REQ07_RFE_POWER_DOWN 0x07, 0xfe
-#define TM6010_REQ07_RFF_SOFT_RESET 0x07, 0xff
-
-/* Define TM6000/TM6010 USB registers */
-#define TM6010_REQ05_R00_MAIN_CTRL 0x05, 0x00
-#define TM6010_REQ05_R01_DEVADDR 0x05, 0x01
-#define TM6010_REQ05_R02_TEST 0x05, 0x02
-#define TM6010_REQ05_R04_SOFN0 0x05, 0x04
-#define TM6010_REQ05_R05_SOFN1 0x05, 0x05
-#define TM6010_REQ05_R06_SOFTM0 0x05, 0x06
-#define TM6010_REQ05_R07_SOFTM1 0x05, 0x07
-#define TM6010_REQ05_R08_PHY_TEST 0x05, 0x08
-#define TM6010_REQ05_R09_VCTL 0x05, 0x09
-#define TM6010_REQ05_R0A_VSTA 0x05, 0x0a
-#define TM6010_REQ05_R0B_CX_CFG 0x05, 0x0b
-#define TM6010_REQ05_R0C_ENDP0_REG0 0x05, 0x0c
-#define TM6010_REQ05_R10_GMASK 0x05, 0x10
-#define TM6010_REQ05_R11_IMASK0 0x05, 0x11
-#define TM6010_REQ05_R12_IMASK1 0x05, 0x12
-#define TM6010_REQ05_R13_IMASK2 0x05, 0x13
-#define TM6010_REQ05_R14_IMASK3 0x05, 0x14
-#define TM6010_REQ05_R15_IMASK4 0x05, 0x15
-#define TM6010_REQ05_R16_IMASK5 0x05, 0x16
-#define TM6010_REQ05_R17_IMASK6 0x05, 0x17
-#define TM6010_REQ05_R18_IMASK7 0x05, 0x18
-#define TM6010_REQ05_R19_ZEROP0 0x05, 0x19
-#define TM6010_REQ05_R1A_ZEROP1 0x05, 0x1a
-#define TM6010_REQ05_R1C_FIFO_EMP0 0x05, 0x1c
-#define TM6010_REQ05_R1D_FIFO_EMP1 0x05, 0x1d
-#define TM6010_REQ05_R20_IRQ_GROUP 0x05, 0x20
-#define TM6010_REQ05_R21_IRQ_SOURCE0 0x05, 0x21
-#define TM6010_REQ05_R22_IRQ_SOURCE1 0x05, 0x22
-#define TM6010_REQ05_R23_IRQ_SOURCE2 0x05, 0x23
-#define TM6010_REQ05_R24_IRQ_SOURCE3 0x05, 0x24
-#define TM6010_REQ05_R25_IRQ_SOURCE4 0x05, 0x25
-#define TM6010_REQ05_R26_IRQ_SOURCE5 0x05, 0x26
-#define TM6010_REQ05_R27_IRQ_SOURCE6 0x05, 0x27
-#define TM6010_REQ05_R28_IRQ_SOURCE7 0x05, 0x28
-#define TM6010_REQ05_R29_SEQ_ERR0 0x05, 0x29
-#define TM6010_REQ05_R2A_SEQ_ERR1 0x05, 0x2a
-#define TM6010_REQ05_R2B_SEQ_ABORT0 0x05, 0x2b
-#define TM6010_REQ05_R2C_SEQ_ABORT1 0x05, 0x2c
-#define TM6010_REQ05_R2D_TX_ZERO0 0x05, 0x2d
-#define TM6010_REQ05_R2E_TX_ZERO1 0x05, 0x2e
-#define TM6010_REQ05_R2F_IDLE_CNT 0x05, 0x2f
-#define TM6010_REQ05_R30_FNO_P1 0x05, 0x30
-#define TM6010_REQ05_R31_FNO_P2 0x05, 0x31
-#define TM6010_REQ05_R32_FNO_P3 0x05, 0x32
-#define TM6010_REQ05_R33_FNO_P4 0x05, 0x33
-#define TM6010_REQ05_R34_FNO_P5 0x05, 0x34
-#define TM6010_REQ05_R35_FNO_P6 0x05, 0x35
-#define TM6010_REQ05_R36_FNO_P7 0x05, 0x36
-#define TM6010_REQ05_R37_FNO_P8 0x05, 0x37
-#define TM6010_REQ05_R38_FNO_P9 0x05, 0x38
-#define TM6010_REQ05_R30_FNO_P10 0x05, 0x39
-#define TM6010_REQ05_R30_FNO_P11 0x05, 0x3a
-#define TM6010_REQ05_R30_FNO_P12 0x05, 0x3b
-#define TM6010_REQ05_R30_FNO_P13 0x05, 0x3c
-#define TM6010_REQ05_R30_FNO_P14 0x05, 0x3d
-#define TM6010_REQ05_R30_FNO_P15 0x05, 0x3e
-#define TM6010_REQ05_R40_IN_MAXPS_LOW1 0x05, 0x40
-#define TM6010_REQ05_R41_IN_MAXPS_HIGH1 0x05, 0x41
-#define TM6010_REQ05_R42_IN_MAXPS_LOW2 0x05, 0x42
-#define TM6010_REQ05_R43_IN_MAXPS_HIGH2 0x05, 0x43
-#define TM6010_REQ05_R44_IN_MAXPS_LOW3 0x05, 0x44
-#define TM6010_REQ05_R45_IN_MAXPS_HIGH3 0x05, 0x45
-#define TM6010_REQ05_R46_IN_MAXPS_LOW4 0x05, 0x46
-#define TM6010_REQ05_R47_IN_MAXPS_HIGH4 0x05, 0x47
-#define TM6010_REQ05_R48_IN_MAXPS_LOW5 0x05, 0x48
-#define TM6010_REQ05_R49_IN_MAXPS_HIGH5 0x05, 0x49
-#define TM6010_REQ05_R4A_IN_MAXPS_LOW6 0x05, 0x4a
-#define TM6010_REQ05_R4B_IN_MAXPS_HIGH6 0x05, 0x4b
-#define TM6010_REQ05_R4C_IN_MAXPS_LOW7 0x05, 0x4c
-#define TM6010_REQ05_R4D_IN_MAXPS_HIGH7 0x05, 0x4d
-#define TM6010_REQ05_R4E_IN_MAXPS_LOW8 0x05, 0x4e
-#define TM6010_REQ05_R4F_IN_MAXPS_HIGH8 0x05, 0x4f
-#define TM6010_REQ05_R50_IN_MAXPS_LOW9 0x05, 0x50
-#define TM6010_REQ05_R51_IN_MAXPS_HIGH9 0x05, 0x51
-#define TM6010_REQ05_R40_IN_MAXPS_LOW10 0x05, 0x52
-#define TM6010_REQ05_R41_IN_MAXPS_HIGH10 0x05, 0x53
-#define TM6010_REQ05_R40_IN_MAXPS_LOW11 0x05, 0x54
-#define TM6010_REQ05_R41_IN_MAXPS_HIGH11 0x05, 0x55
-#define TM6010_REQ05_R40_IN_MAXPS_LOW12 0x05, 0x56
-#define TM6010_REQ05_R41_IN_MAXPS_HIGH12 0x05, 0x57
-#define TM6010_REQ05_R40_IN_MAXPS_LOW13 0x05, 0x58
-#define TM6010_REQ05_R41_IN_MAXPS_HIGH13 0x05, 0x59
-#define TM6010_REQ05_R40_IN_MAXPS_LOW14 0x05, 0x5a
-#define TM6010_REQ05_R41_IN_MAXPS_HIGH14 0x05, 0x5b
-#define TM6010_REQ05_R40_IN_MAXPS_LOW15 0x05, 0x5c
-#define TM6010_REQ05_R41_IN_MAXPS_HIGH15 0x05, 0x5d
-#define TM6010_REQ05_R60_OUT_MAXPS_LOW1 0x05, 0x60
-#define TM6010_REQ05_R61_OUT_MAXPS_HIGH1 0x05, 0x61
-#define TM6010_REQ05_R62_OUT_MAXPS_LOW2 0x05, 0x62
-#define TM6010_REQ05_R63_OUT_MAXPS_HIGH2 0x05, 0x63
-#define TM6010_REQ05_R64_OUT_MAXPS_LOW3 0x05, 0x64
-#define TM6010_REQ05_R65_OUT_MAXPS_HIGH3 0x05, 0x65
-#define TM6010_REQ05_R66_OUT_MAXPS_LOW4 0x05, 0x66
-#define TM6010_REQ05_R67_OUT_MAXPS_HIGH4 0x05, 0x67
-#define TM6010_REQ05_R68_OUT_MAXPS_LOW5 0x05, 0x68
-#define TM6010_REQ05_R69_OUT_MAXPS_HIGH5 0x05, 0x69
-#define TM6010_REQ05_R6A_OUT_MAXPS_LOW6 0x05, 0x6a
-#define TM6010_REQ05_R6B_OUT_MAXPS_HIGH6 0x05, 0x6b
-#define TM6010_REQ05_R6C_OUT_MAXPS_LOW7 0x05, 0x6c
-#define TM6010_REQ05_R6D_OUT_MAXPS_HIGH7 0x05, 0x6d
-#define TM6010_REQ05_R6E_OUT_MAXPS_LOW8 0x05, 0x6e
-#define TM6010_REQ05_R6F_OUT_MAXPS_HIGH8 0x05, 0x6f
-#define TM6010_REQ05_R70_OUT_MAXPS_LOW9 0x05, 0x70
-#define TM6010_REQ05_R71_OUT_MAXPS_HIGH9 0x05, 0x71
-#define TM6010_REQ05_R60_OUT_MAXPS_LOW10 0x05, 0x72
-#define TM6010_REQ05_R61_OUT_MAXPS_HIGH10 0x05, 0x73
-#define TM6010_REQ05_R60_OUT_MAXPS_LOW11 0x05, 0x74
-#define TM6010_REQ05_R61_OUT_MAXPS_HIGH11 0x05, 0x75
-#define TM6010_REQ05_R60_OUT_MAXPS_LOW12 0x05, 0x76
-#define TM6010_REQ05_R61_OUT_MAXPS_HIGH12 0x05, 0x77
-#define TM6010_REQ05_R60_OUT_MAXPS_LOW13 0x05, 0x78
-#define TM6010_REQ05_R61_OUT_MAXPS_HIGH13 0x05, 0x79
-#define TM6010_REQ05_R60_OUT_MAXPS_LOW14 0x05, 0x7a
-#define TM6010_REQ05_R61_OUT_MAXPS_HIGH14 0x05, 0x7b
-#define TM6010_REQ05_R60_OUT_MAXPS_LOW15 0x05, 0x7c
-#define TM6010_REQ05_R61_OUT_MAXPS_HIGH15 0x05, 0x7d
-#define TM6010_REQ05_R80_FIFO0 0x05, 0x80
-#define TM6010_REQ05_R81_FIFO1 0x05, 0x81
-#define TM6010_REQ05_R82_FIFO2 0x05, 0x82
-#define TM6010_REQ05_R83_FIFO3 0x05, 0x83
-#define TM6010_REQ05_R84_FIFO4 0x05, 0x84
-#define TM6010_REQ05_R85_FIFO5 0x05, 0x85
-#define TM6010_REQ05_R86_FIFO6 0x05, 0x86
-#define TM6010_REQ05_R87_FIFO7 0x05, 0x87
-#define TM6010_REQ05_R88_FIFO8 0x05, 0x88
-#define TM6010_REQ05_R89_FIFO9 0x05, 0x89
-#define TM6010_REQ05_R81_FIFO10 0x05, 0x8a
-#define TM6010_REQ05_R81_FIFO11 0x05, 0x8b
-#define TM6010_REQ05_R81_FIFO12 0x05, 0x8c
-#define TM6010_REQ05_R81_FIFO13 0x05, 0x8d
-#define TM6010_REQ05_R81_FIFO14 0x05, 0x8e
-#define TM6010_REQ05_R81_FIFO15 0x05, 0x8f
-#define TM6010_REQ05_R90_CFG_FIFO0 0x05, 0x90
-#define TM6010_REQ05_R91_CFG_FIFO1 0x05, 0x91
-#define TM6010_REQ05_R92_CFG_FIFO2 0x05, 0x92
-#define TM6010_REQ05_R93_CFG_FIFO3 0x05, 0x93
-#define TM6010_REQ05_R94_CFG_FIFO4 0x05, 0x94
-#define TM6010_REQ05_R95_CFG_FIFO5 0x05, 0x95
-#define TM6010_REQ05_R96_CFG_FIFO6 0x05, 0x96
-#define TM6010_REQ05_R97_CFG_FIFO7 0x05, 0x97
-#define TM6010_REQ05_R98_CFG_FIFO8 0x05, 0x98
-#define TM6010_REQ05_R99_CFG_FIFO9 0x05, 0x99
-#define TM6010_REQ05_R91_CFG_FIFO10 0x05, 0x9a
-#define TM6010_REQ05_R91_CFG_FIFO11 0x05, 0x9b
-#define TM6010_REQ05_R91_CFG_FIFO12 0x05, 0x9c
-#define TM6010_REQ05_R91_CFG_FIFO13 0x05, 0x9d
-#define TM6010_REQ05_R91_CFG_FIFO14 0x05, 0x9e
-#define TM6010_REQ05_R91_CFG_FIFO15 0x05, 0x9f
-#define TM6010_REQ05_RA0_CTL_FIFO0 0x05, 0xa0
-#define TM6010_REQ05_RA1_CTL_FIFO1 0x05, 0xa1
-#define TM6010_REQ05_RA2_CTL_FIFO2 0x05, 0xa2
-#define TM6010_REQ05_RA3_CTL_FIFO3 0x05, 0xa3
-#define TM6010_REQ05_RA4_CTL_FIFO4 0x05, 0xa4
-#define TM6010_REQ05_RA5_CTL_FIFO5 0x05, 0xa5
-#define TM6010_REQ05_RA6_CTL_FIFO6 0x05, 0xa6
-#define TM6010_REQ05_RA7_CTL_FIFO7 0x05, 0xa7
-#define TM6010_REQ05_RA8_CTL_FIFO8 0x05, 0xa8
-#define TM6010_REQ05_RA9_CTL_FIFO9 0x05, 0xa9
-#define TM6010_REQ05_RA1_CTL_FIFO10 0x05, 0xaa
-#define TM6010_REQ05_RA1_CTL_FIFO11 0x05, 0xab
-#define TM6010_REQ05_RA1_CTL_FIFO12 0x05, 0xac
-#define TM6010_REQ05_RA1_CTL_FIFO13 0x05, 0xad
-#define TM6010_REQ05_RA1_CTL_FIFO14 0x05, 0xae
-#define TM6010_REQ05_RA1_CTL_FIFO15 0x05, 0xaf
-#define TM6010_REQ05_RB0_BC_LOW_FIFO0 0x05, 0xb0
-#define TM6010_REQ05_RB1_BC_LOW_FIFO1 0x05, 0xb1
-#define TM6010_REQ05_RB2_BC_LOW_FIFO2 0x05, 0xb2
-#define TM6010_REQ05_RB3_BC_LOW_FIFO3 0x05, 0xb3
-#define TM6010_REQ05_RB4_BC_LOW_FIFO4 0x05, 0xb4
-#define TM6010_REQ05_RB5_BC_LOW_FIFO5 0x05, 0xb5
-#define TM6010_REQ05_RB6_BC_LOW_FIFO6 0x05, 0xb6
-#define TM6010_REQ05_RB7_BC_LOW_FIFO7 0x05, 0xb7
-#define TM6010_REQ05_RB8_BC_LOW_FIFO8 0x05, 0xb8
-#define TM6010_REQ05_RB9_BC_LOW_FIFO9 0x05, 0xb9
-#define TM6010_REQ05_RB1_BC_LOW_FIFO10 0x05, 0xba
-#define TM6010_REQ05_RB1_BC_LOW_FIFO11 0x05, 0xbb
-#define TM6010_REQ05_RB1_BC_LOW_FIFO12 0x05, 0xbc
-#define TM6010_REQ05_RB1_BC_LOW_FIFO13 0x05, 0xbd
-#define TM6010_REQ05_RB1_BC_LOW_FIFO14 0x05, 0xbe
-#define TM6010_REQ05_RB1_BC_LOW_FIFO15 0x05, 0xbf
-#define TM6010_REQ05_RC0_DATA_FIFO0 0x05, 0xc0
-#define TM6010_REQ05_RC4_DATA_FIFO1 0x05, 0xc4
-#define TM6010_REQ05_RC8_DATA_FIFO2 0x05, 0xc8
-#define TM6010_REQ05_RCC_DATA_FIFO3 0x05, 0xcc
-#define TM6010_REQ05_RD0_DATA_FIFO4 0x05, 0xd0
-#define TM6010_REQ05_RD4_DATA_FIFO5 0x05, 0xd4
-#define TM6010_REQ05_RD8_DATA_FIFO6 0x05, 0xd8
-#define TM6010_REQ05_RDC_DATA_FIFO7 0x05, 0xdc
-#define TM6010_REQ05_RE0_DATA_FIFO8 0x05, 0xe0
-#define TM6010_REQ05_RE4_DATA_FIFO9 0x05, 0xe4
-#define TM6010_REQ05_RC4_DATA_FIFO10 0x05, 0xe8
-#define TM6010_REQ05_RC4_DATA_FIFO11 0x05, 0xec
-#define TM6010_REQ05_RC4_DATA_FIFO12 0x05, 0xf0
-#define TM6010_REQ05_RC4_DATA_FIFO13 0x05, 0xf4
-#define TM6010_REQ05_RC4_DATA_FIFO14 0x05, 0xf8
-#define TM6010_REQ05_RC4_DATA_FIFO15 0x05, 0xfc
-
-/* Define TM6010 Audio decoder registers */
-/* This core available only in TM6010 */
-#define TM6010_REQ08_R00_A_VERSION 0x08, 0x00
-#define TM6010_REQ08_R01_A_INIT 0x08, 0x01
-#define TM6010_REQ08_R02_A_FIX_GAIN_CTRL 0x08, 0x02
-#define TM6010_REQ08_R03_A_AUTO_GAIN_CTRL 0x08, 0x03
-#define TM6010_REQ08_R04_A_SIF_AMP_CTRL 0x08, 0x04
-#define TM6010_REQ08_R05_A_STANDARD_MOD 0x08, 0x05
-#define TM6010_REQ08_R06_A_SOUND_MOD 0x08, 0x06
-#define TM6010_REQ08_R07_A_LEFT_VOL 0x08, 0x07
-#define TM6010_REQ08_R08_A_RIGHT_VOL 0x08, 0x08
-#define TM6010_REQ08_R09_A_MAIN_VOL 0x08, 0x09
-#define TM6010_REQ08_R0A_A_I2S_MOD 0x08, 0x0a
-#define TM6010_REQ08_R0B_A_ASD_THRES1 0x08, 0x0b
-#define TM6010_REQ08_R0C_A_ASD_THRES2 0x08, 0x0c
-#define TM6010_REQ08_R0D_A_AMD_THRES 0x08, 0x0d
-#define TM6010_REQ08_R0E_A_MONO_THRES1 0x08, 0x0e
-#define TM6010_REQ08_R0F_A_MONO_THRES2 0x08, 0x0f
-#define TM6010_REQ08_R10_A_MUTE_THRES1 0x08, 0x10
-#define TM6010_REQ08_R11_A_MUTE_THRES2 0x08, 0x11
-#define TM6010_REQ08_R12_A_AGC_U 0x08, 0x12
-#define TM6010_REQ08_R13_A_AGC_ERR_T 0x08, 0x13
-#define TM6010_REQ08_R14_A_AGC_GAIN_INIT 0x08, 0x14
-#define TM6010_REQ08_R15_A_AGC_STEP_THR 0x08, 0x15
-#define TM6010_REQ08_R16_A_AGC_GAIN_MAX 0x08, 0x16
-#define TM6010_REQ08_R17_A_AGC_GAIN_MIN 0x08, 0x17
-#define TM6010_REQ08_R18_A_TR_CTRL 0x08, 0x18
-#define TM6010_REQ08_R19_A_FH_2FH_GAIN 0x08, 0x19
-#define TM6010_REQ08_R1A_A_NICAM_SER_MAX 0x08, 0x1a
-#define TM6010_REQ08_R1B_A_NICAM_SER_MIN 0x08, 0x1b
-#define TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT 0x08, 0x1e
-#define TM6010_REQ08_R1F_A_TEST_INTF_SEL 0x08, 0x1f
-#define TM6010_REQ08_R20_A_TEST_PIN_SEL 0x08, 0x20
-#define TM6010_REQ08_R21_A_AGC_ERR 0x08, 0x21
-#define TM6010_REQ08_R22_A_AGC_GAIN 0x08, 0x22
-#define TM6010_REQ08_R23_A_NICAM_INFO 0x08, 0x23
-#define TM6010_REQ08_R24_A_SER 0x08, 0x24
-#define TM6010_REQ08_R25_A_C1_AMP 0x08, 0x25
-#define TM6010_REQ08_R26_A_C2_AMP 0x08, 0x26
-#define TM6010_REQ08_R27_A_NOISE_AMP 0x08, 0x27
-#define TM6010_REQ08_R28_A_AUDIO_MODE_RES 0x08, 0x28
-
-/* Define TM6010 Video ADC registers */
-#define TM6010_REQ08_RE0_ADC_REF 0x08, 0xe0
-#define TM6010_REQ08_RE1_DAC_CLMP 0x08, 0xe1
-#define TM6010_REQ08_RE2_POWER_DOWN_CTRL1 0x08, 0xe2
-#define TM6010_REQ08_RE3_ADC_IN1_SEL 0x08, 0xe3
-#define TM6010_REQ08_RE4_ADC_IN2_SEL 0x08, 0xe4
-#define TM6010_REQ08_RE5_GAIN_PARAM 0x08, 0xe5
-#define TM6010_REQ08_RE6_POWER_DOWN_CTRL2 0x08, 0xe6
-#define TM6010_REQ08_RE7_REG_GAIN_Y 0x08, 0xe7
-#define TM6010_REQ08_RE8_REG_GAIN_C 0x08, 0xe8
-#define TM6010_REQ08_RE9_BIAS_CTRL 0x08, 0xe9
-#define TM6010_REQ08_REA_BUFF_DRV_CTRL 0x08, 0xea
-#define TM6010_REQ08_REB_SIF_GAIN_CTRL 0x08, 0xeb
-#define TM6010_REQ08_REC_REVERSE_YC_CTRL 0x08, 0xec
-#define TM6010_REQ08_RED_GAIN_SEL 0x08, 0xed
-
-/* Define TM6010 Audio ADC registers */
-#define TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG 0x08, 0xf0
-#define TM6010_REQ08_RF1_AADC_POWER_DOWN 0x08, 0xf1
-#define TM6010_REQ08_RF2_LEFT_CHANNEL_VOL 0x08, 0xf2
-#define TM6010_REQ08_RF3_RIGHT_CHANNEL_VOL 0x08, 0xf3
diff --git a/drivers/media/video/tm6000/tm6000-stds.c b/drivers/media/video/tm6000/tm6000-stds.c
deleted file mode 100644
index 5e28d6a2412..00000000000
--- a/drivers/media/video/tm6000/tm6000-stds.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/*
- * tm6000-stds.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2007 Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include "tm6000.h"
-#include "tm6000-regs.h"
-
-static unsigned int tm6010_a_mode;
-module_param(tm6010_a_mode, int, 0644);
-MODULE_PARM_DESC(tm6010_a_mode, "set tm6010 sif audio mode");
-
-struct tm6000_reg_settings {
- unsigned char req;
- unsigned char reg;
- unsigned char value;
-};
-
-
-struct tm6000_std_settings {
- v4l2_std_id id;
- struct tm6000_reg_settings *common;
-};
-
-static struct tm6000_reg_settings composite_pal_m[] = {
- { TM6010_REQ07_R3F_RESET, 0x01 },
- { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x04 },
- { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
- { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
- { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00 },
- { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
- { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
- { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83 },
- { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a },
- { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0 },
- { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
- { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
- { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
- { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
- { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
- { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x20 },
- { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
- { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
- { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
- { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
- { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
- { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
- { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
- { TM6010_REQ07_R3F_RESET, 0x00 },
- { 0, 0, 0 }
-};
-
-static struct tm6000_reg_settings composite_pal_nc[] = {
- { TM6010_REQ07_R3F_RESET, 0x01 },
- { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x36 },
- { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
- { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
- { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02 },
- { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
- { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
- { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91 },
- { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f },
- { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c },
- { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
- { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
- { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
- { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
- { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
- { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c },
- { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
- { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
- { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
- { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
- { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
- { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
- { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
- { TM6010_REQ07_R3F_RESET, 0x00 },
- { 0, 0, 0 }
-};
-
-static struct tm6000_reg_settings composite_pal[] = {
- { TM6010_REQ07_R3F_RESET, 0x01 },
- { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x32 },
- { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
- { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
- { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02 },
- { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
- { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25 },
- { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5 },
- { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63 },
- { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50 },
- { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
- { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
- { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
- { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
- { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
- { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c },
- { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
- { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
- { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
- { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
- { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
- { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
- { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
- { TM6010_REQ07_R3F_RESET, 0x00 },
- { 0, 0, 0 }
-};
-
-static struct tm6000_reg_settings composite_secam[] = {
- { TM6010_REQ07_R3F_RESET, 0x01 },
- { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38 },
- { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
- { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
- { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02 },
- { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
- { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24 },
- { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92 },
- { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8 },
- { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed },
- { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
- { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
- { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
- { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
- { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
- { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c },
- { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
- { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c },
- { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18 },
- { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
- { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xff },
- { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
- { TM6010_REQ07_R3F_RESET, 0x00 },
- { 0, 0, 0 }
-};
-
-static struct tm6000_reg_settings composite_ntsc[] = {
- { TM6010_REQ07_R3F_RESET, 0x01 },
- { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00 },
- { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f },
- { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
- { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00 },
- { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
- { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
- { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b },
- { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2 },
- { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9 },
- { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
- { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
- { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
- { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
- { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
- { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
- { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
- { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c },
- { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
- { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
- { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
- { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd },
- { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
- { TM6010_REQ07_R3F_RESET, 0x00 },
- { 0, 0, 0 }
-};
-
-static struct tm6000_std_settings composite_stds[] = {
- { .id = V4L2_STD_PAL_M, .common = composite_pal_m, },
- { .id = V4L2_STD_PAL_Nc, .common = composite_pal_nc, },
- { .id = V4L2_STD_PAL, .common = composite_pal, },
- { .id = V4L2_STD_SECAM, .common = composite_secam, },
- { .id = V4L2_STD_NTSC, .common = composite_ntsc, },
-};
-
-static struct tm6000_reg_settings svideo_pal_m[] = {
- { TM6010_REQ07_R3F_RESET, 0x01 },
- { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x05 },
- { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
- { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
- { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04 },
- { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
- { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
- { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83 },
- { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a },
- { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0 },
- { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
- { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
- { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
- { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
- { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
- { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
- { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
- { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
- { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
- { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
- { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
- { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
- { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
- { TM6010_REQ07_R3F_RESET, 0x00 },
- { 0, 0, 0 }
-};
-
-static struct tm6000_reg_settings svideo_pal_nc[] = {
- { TM6010_REQ07_R3F_RESET, 0x01 },
- { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x37 },
- { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
- { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
- { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04 },
- { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
- { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
- { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91 },
- { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f },
- { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c },
- { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
- { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
- { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
- { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
- { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
- { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
- { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
- { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
- { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
- { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
- { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
- { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
- { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
- { TM6010_REQ07_R3F_RESET, 0x00 },
- { 0, 0, 0 }
-};
-
-static struct tm6000_reg_settings svideo_pal[] = {
- { TM6010_REQ07_R3F_RESET, 0x01 },
- { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x33 },
- { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
- { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
- { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04 },
- { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30 },
- { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25 },
- { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5 },
- { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63 },
- { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50 },
- { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
- { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
- { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
- { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
- { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
- { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a },
- { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
- { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
- { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
- { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
- { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
- { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
- { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
- { TM6010_REQ07_R3F_RESET, 0x00 },
- { 0, 0, 0 }
-};
-
-static struct tm6000_reg_settings svideo_secam[] = {
- { TM6010_REQ07_R3F_RESET, 0x01 },
- { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x39 },
- { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
- { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
- { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03 },
- { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
- { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24 },
- { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92 },
- { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8 },
- { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed },
- { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
- { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
- { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
- { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
- { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
- { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a },
- { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
- { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c },
- { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18 },
- { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
- { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xff },
- { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
- { TM6010_REQ07_R3F_RESET, 0x00 },
- { 0, 0, 0 }
-};
-
-static struct tm6000_reg_settings svideo_ntsc[] = {
- { TM6010_REQ07_R3F_RESET, 0x01 },
- { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x01 },
- { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f },
- { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
- { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03 },
- { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30 },
- { TM6010_REQ07_R17_HLOOP_MAXSTATE, 0x8b },
- { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
- { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b },
- { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2 },
- { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9 },
- { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
- { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
- { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
- { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
- { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
- { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
- { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
- { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c },
- { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
- { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
- { TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
- { TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd },
- { TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
- { TM6010_REQ07_R3F_RESET, 0x00 },
- { 0, 0, 0 }
-};
-
-static struct tm6000_std_settings svideo_stds[] = {
- { .id = V4L2_STD_PAL_M, .common = svideo_pal_m, },
- { .id = V4L2_STD_PAL_Nc, .common = svideo_pal_nc, },
- { .id = V4L2_STD_PAL, .common = svideo_pal, },
- { .id = V4L2_STD_SECAM, .common = svideo_secam, },
- { .id = V4L2_STD_NTSC, .common = svideo_ntsc, },
-};
-
-static int tm6000_set_audio_std(struct tm6000_core *dev)
-{
- uint8_t areg_02 = 0x04; /* GC1 Fixed gain 0dB */
- uint8_t areg_05 = 0x01; /* Auto 4.5 = M Japan, Auto 6.5 = DK */
- uint8_t areg_06 = 0x02; /* Auto de-emphasis, mannual channel mode */
-
- if (dev->radio) {
- tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00);
- tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, 0x04);
- tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00);
- tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0x80);
- tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x0c);
- /* set mono or stereo */
- if (dev->amode == V4L2_TUNER_MODE_MONO)
- tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00);
- else if (dev->amode == V4L2_TUNER_MODE_STEREO)
- tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x02);
- tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x18);
- tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x0a);
- tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x40);
- tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe);
- tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
- tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
- tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, 0xff);
- return 0;
- }
-
- /*
- * STD/MN shouldn't be affected by tm6010_a_mode, as there's just one
- * audio standard for each V4L2_STD type.
- */
- if ((dev->norm & V4L2_STD_NTSC) == V4L2_STD_NTSC_M_KR) {
- areg_05 |= 0x04;
- } else if ((dev->norm & V4L2_STD_NTSC) == V4L2_STD_NTSC_M_JP) {
- areg_05 |= 0x43;
- } else if (dev->norm & V4L2_STD_MN) {
- areg_05 |= 0x22;
- } else switch (tm6010_a_mode) {
- /* auto */
- case 0:
- if ((dev->norm & V4L2_STD_SECAM) == V4L2_STD_SECAM_L)
- areg_05 |= 0x00;
- else /* Other PAL/SECAM standards */
- areg_05 |= 0x10;
- break;
- /* A2 */
- case 1:
- if (dev->norm & V4L2_STD_DK)
- areg_05 = 0x09;
- else
- areg_05 = 0x05;
- break;
- /* NICAM */
- case 2:
- if (dev->norm & V4L2_STD_DK) {
- areg_05 = 0x06;
- } else if (dev->norm & V4L2_STD_PAL_I) {
- areg_05 = 0x08;
- } else if (dev->norm & V4L2_STD_SECAM_L) {
- areg_05 = 0x0a;
- areg_02 = 0x02;
- } else {
- areg_05 = 0x07;
- }
- break;
- /* other */
- case 3:
- if (dev->norm & V4L2_STD_DK) {
- areg_05 = 0x0b;
- } else {
- areg_05 = 0x02;
- }
- break;
- }
-
- tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00);
- tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, areg_02);
- tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00);
- tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0xa0);
- tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, areg_05);
- tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, areg_06);
- tm6000_set_reg(dev, TM6010_REQ08_R07_A_LEFT_VOL, 0x00);
- tm6000_set_reg(dev, TM6010_REQ08_R08_A_RIGHT_VOL, 0x00);
- tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x08);
- tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, 0x91);
- tm6000_set_reg(dev, TM6010_REQ08_R0B_A_ASD_THRES1, 0x20);
- tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x12);
- tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x20);
- tm6000_set_reg(dev, TM6010_REQ08_R0E_A_MONO_THRES1, 0xf0);
- tm6000_set_reg(dev, TM6010_REQ08_R0F_A_MONO_THRES2, 0x80);
- tm6000_set_reg(dev, TM6010_REQ08_R10_A_MUTE_THRES1, 0xc0);
- tm6000_set_reg(dev, TM6010_REQ08_R11_A_MUTE_THRES2, 0x80);
- tm6000_set_reg(dev, TM6010_REQ08_R12_A_AGC_U, 0x12);
- tm6000_set_reg(dev, TM6010_REQ08_R13_A_AGC_ERR_T, 0xfe);
- tm6000_set_reg(dev, TM6010_REQ08_R14_A_AGC_GAIN_INIT, 0x20);
- tm6000_set_reg(dev, TM6010_REQ08_R15_A_AGC_STEP_THR, 0x14);
- tm6000_set_reg(dev, TM6010_REQ08_R16_A_AGC_GAIN_MAX, 0xfe);
- tm6000_set_reg(dev, TM6010_REQ08_R17_A_AGC_GAIN_MIN, 0x01);
- tm6000_set_reg(dev, TM6010_REQ08_R18_A_TR_CTRL, 0xa0);
- tm6000_set_reg(dev, TM6010_REQ08_R19_A_FH_2FH_GAIN, 0x32);
- tm6000_set_reg(dev, TM6010_REQ08_R1A_A_NICAM_SER_MAX, 0x64);
- tm6000_set_reg(dev, TM6010_REQ08_R1B_A_NICAM_SER_MIN, 0x20);
- tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0x1c, 0x00);
- tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0x1d, 0x00);
- tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
- tm6000_set_reg(dev, TM6010_REQ08_R1F_A_TEST_INTF_SEL, 0x00);
- tm6000_set_reg(dev, TM6010_REQ08_R20_A_TEST_PIN_SEL, 0x00);
- tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
-
- return 0;
-}
-
-void tm6000_get_std_res(struct tm6000_core *dev)
-{
- /* Currently, those are the only supported resoltions */
- if (dev->norm & V4L2_STD_525_60)
- dev->height = 480;
- else
- dev->height = 576;
-
- dev->width = 720;
-}
-
-static int tm6000_load_std(struct tm6000_core *dev, struct tm6000_reg_settings *set)
-{
- int i, rc;
-
- /* Load board's initialization table */
- for (i = 0; set[i].req; i++) {
- rc = tm6000_set_reg(dev, set[i].req, set[i].reg, set[i].value);
- if (rc < 0) {
- printk(KERN_ERR "Error %i while setting "
- "req %d, reg %d to value %d\n",
- rc, set[i].req, set[i].reg, set[i].value);
- return rc;
- }
- }
-
- return 0;
-}
-
-int tm6000_set_standard(struct tm6000_core *dev)
-{
- struct tm6000_input *input;
- int i, rc = 0;
- u8 reg_07_fe = 0x8a;
- u8 reg_08_f1 = 0xfc;
- u8 reg_08_e2 = 0xf0;
- u8 reg_08_e6 = 0x0f;
-
- tm6000_get_std_res(dev);
-
- if (!dev->radio)
- input = &dev->vinput[dev->input];
- else
- input = &dev->rinput;
-
- if (dev->dev_type == TM6010) {
- switch (input->vmux) {
- case TM6000_VMUX_VIDEO_A:
- tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4);
- tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1);
- tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0);
- tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
- tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe8);
- reg_07_fe |= 0x01;
- break;
- case TM6000_VMUX_VIDEO_B:
- tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8);
- tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1);
- tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0);
- tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
- tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe8);
- reg_07_fe |= 0x01;
- break;
- case TM6000_VMUX_VIDEO_AB:
- tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc);
- tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8);
- reg_08_e6 = 0x00;
- tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2);
- tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0);
- tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
- tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe0);
- break;
- default:
- break;
- }
- switch (input->amux) {
- case TM6000_AMUX_ADC1:
- tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
- 0x00, 0x0f);
- /* Mux overflow workaround */
- tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
- 0x10, 0xf0);
- break;
- case TM6000_AMUX_ADC2:
- tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
- 0x08, 0x0f);
- /* Mux overflow workaround */
- tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
- 0x10, 0xf0);
- break;
- case TM6000_AMUX_SIF1:
- reg_08_e2 |= 0x02;
- reg_08_e6 = 0x08;
- reg_07_fe |= 0x40;
- reg_08_f1 |= 0x02;
- tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3);
- tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
- 0x02, 0x0f);
- /* Mux overflow workaround */
- tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
- 0x30, 0xf0);
- break;
- case TM6000_AMUX_SIF2:
- reg_08_e2 |= 0x02;
- reg_08_e6 = 0x08;
- reg_07_fe |= 0x40;
- reg_08_f1 |= 0x02;
- tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf7);
- tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
- 0x02, 0x0f);
- /* Mux overflow workaround */
- tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
- 0x30, 0xf0);
- break;
- default:
- break;
- }
- tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, reg_08_e2);
- tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, reg_08_e6);
- tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, reg_08_f1);
- tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, reg_07_fe);
- } else {
- switch (input->vmux) {
- case TM6000_VMUX_VIDEO_A:
- tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10);
- tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00);
- tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x0f);
- tm6000_set_reg(dev,
- REQ_03_SET_GET_MCU_PIN, input->v_gpio, 0);
- break;
- case TM6000_VMUX_VIDEO_B:
- tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x00);
- tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00);
- tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x0f);
- tm6000_set_reg(dev,
- REQ_03_SET_GET_MCU_PIN, input->v_gpio, 0);
- break;
- case TM6000_VMUX_VIDEO_AB:
- tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10);
- tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x10);
- tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x00);
- tm6000_set_reg(dev,
- REQ_03_SET_GET_MCU_PIN, input->v_gpio, 1);
- break;
- default:
- break;
- }
- switch (input->amux) {
- case TM6000_AMUX_ADC1:
- tm6000_set_reg_mask(dev,
- TM6000_REQ07_REB_VADC_AADC_MODE, 0x00, 0x0f);
- break;
- case TM6000_AMUX_ADC2:
- tm6000_set_reg_mask(dev,
- TM6000_REQ07_REB_VADC_AADC_MODE, 0x04, 0x0f);
- break;
- default:
- break;
- }
- }
- if (input->type == TM6000_INPUT_SVIDEO) {
- for (i = 0; i < ARRAY_SIZE(svideo_stds); i++) {
- if (dev->norm & svideo_stds[i].id) {
- rc = tm6000_load_std(dev, svideo_stds[i].common);
- goto ret;
- }
- }
- return -EINVAL;
- } else {
- for (i = 0; i < ARRAY_SIZE(composite_stds); i++) {
- if (dev->norm & composite_stds[i].id) {
- rc = tm6000_load_std(dev, composite_stds[i].common);
- goto ret;
- }
- }
- return -EINVAL;
- }
-
-ret:
- if (rc < 0)
- return rc;
-
- if ((dev->dev_type == TM6010) &&
- ((input->amux == TM6000_AMUX_SIF1) ||
- (input->amux == TM6000_AMUX_SIF2)))
- tm6000_set_audio_std(dev);
-
- msleep(40);
-
- return 0;
-}
diff --git a/drivers/media/video/tm6000/tm6000-usb-isoc.h b/drivers/media/video/tm6000/tm6000-usb-isoc.h
deleted file mode 100644
index 99d15a55aa0..00000000000
--- a/drivers/media/video/tm6000/tm6000-usb-isoc.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/videodev2.h>
-
-#define TM6000_URB_MSG_LEN 180
-
-struct usb_isoc_ctl {
- /* max packet size of isoc transaction */
- int max_pkt_size;
-
- /* number of allocated urbs */
- int num_bufs;
-
- /* urb for isoc transfers */
- struct urb **urb;
-
- /* transfer buffers for isoc transfer */
- char **transfer_buffer;
-
- /* Last buffer command and region */
- u8 cmd;
- int pos, size, pktsize;
-
- /* Last field: ODD or EVEN? */
- int vfield, field;
-
- /* Stores incomplete commands */
- u32 tmp_buf;
- int tmp_buf_len;
-
- /* Stores already requested buffers */
- struct tm6000_buffer *buf;
-};
diff --git a/drivers/media/video/tm6000/tm6000-video.c b/drivers/media/video/tm6000/tm6000-video.c
deleted file mode 100644
index f7034df94e0..00000000000
--- a/drivers/media/video/tm6000/tm6000-video.c
+++ /dev/null
@@ -1,1818 +0,0 @@
-/*
- * tm6000-video.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
- * - Fixed module load/unload
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/random.h>
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-ioctl.h>
-#include <media/tuner.h>
-#include <linux/interrupt.h>
-#include <linux/kthread.h>
-#include <linux/highmem.h>
-#include <linux/freezer.h>
-
-#include "tm6000-regs.h"
-#include "tm6000.h"
-
-#define BUFFER_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
-
-/* Limits minimum and default number of buffers */
-#define TM6000_MIN_BUF 4
-#define TM6000_DEF_BUF 8
-
-#define TM6000_MAX_ISO_PACKETS 46 /* Max number of ISO packets */
-
-/* Declare static vars that will be used as parameters */
-static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
-static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
-static int radio_nr = -1; /* /dev/radioN, -1 for autodetect */
-
-/* Debug level */
-int tm6000_debug;
-EXPORT_SYMBOL_GPL(tm6000_debug);
-
-static const struct v4l2_queryctrl no_ctrl = {
- .name = "42",
- .flags = V4L2_CTRL_FLAG_DISABLED,
-};
-
-/* supported controls */
-static struct v4l2_queryctrl tm6000_qctrl[] = {
- {
- .id = V4L2_CID_BRIGHTNESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Brightness",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 54,
- .flags = 0,
- }, {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 255,
- .step = 0x1,
- .default_value = 119,
- .flags = 0,
- }, {
- .id = V4L2_CID_SATURATION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 255,
- .step = 0x1,
- .default_value = 112,
- .flags = 0,
- }, {
- .id = V4L2_CID_HUE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Hue",
- .minimum = -128,
- .maximum = 127,
- .step = 0x1,
- .default_value = 0,
- .flags = 0,
- },
- /* --- audio --- */
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- }, {
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = -15,
- .maximum = 15,
- .step = 1,
- .default_value = 0,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
-
-static const unsigned int CTRLS = ARRAY_SIZE(tm6000_qctrl);
-static int qctl_regs[ARRAY_SIZE(tm6000_qctrl)];
-
-static struct tm6000_fmt format[] = {
- {
- .name = "4:2:2, packed, YVY2",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = 16,
- }, {
- .name = "4:2:2, packed, UYVY",
- .fourcc = V4L2_PIX_FMT_UYVY,
- .depth = 16,
- }, {
- .name = "A/V + VBI mux packet",
- .fourcc = V4L2_PIX_FMT_TM6000,
- .depth = 16,
- }
-};
-
-static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
-{
- unsigned int i;
-
- for (i = 0; i < CTRLS; i++)
- if (tm6000_qctrl[i].id == id)
- return tm6000_qctrl+i;
- return NULL;
-}
-
-/* ------------------------------------------------------------------
- * DMA and thread functions
- * ------------------------------------------------------------------
- */
-
-#define norm_maxw(a) 720
-#define norm_maxh(a) 576
-
-#define norm_minw(a) norm_maxw(a)
-#define norm_minh(a) norm_maxh(a)
-
-/*
- * video-buf generic routine to get the next available buffer
- */
-static inline void get_next_buf(struct tm6000_dmaqueue *dma_q,
- struct tm6000_buffer **buf)
-{
- struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
-
- if (list_empty(&dma_q->active)) {
- dprintk(dev, V4L2_DEBUG_QUEUE, "No active queue to serve\n");
- *buf = NULL;
- return;
- }
-
- *buf = list_entry(dma_q->active.next,
- struct tm6000_buffer, vb.queue);
-}
-
-/*
- * Announces that a buffer were filled and request the next
- */
-static inline void buffer_filled(struct tm6000_core *dev,
- struct tm6000_dmaqueue *dma_q,
- struct tm6000_buffer *buf)
-{
- /* Advice that buffer was filled */
- dprintk(dev, V4L2_DEBUG_ISOC, "[%p/%d] wakeup\n", buf, buf->vb.i);
- buf->vb.state = VIDEOBUF_DONE;
- buf->vb.field_count++;
- do_gettimeofday(&buf->vb.ts);
-
- list_del(&buf->vb.queue);
- wake_up(&buf->vb.done);
-}
-
-/*
- * Identify the tm5600/6000 buffer header type and properly handles
- */
-static int copy_streams(u8 *data, unsigned long len,
- struct urb *urb)
-{
- struct tm6000_dmaqueue *dma_q = urb->context;
- struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
- u8 *ptr = data, *endp = data+len;
- unsigned long header = 0;
- int rc = 0;
- unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
- struct tm6000_buffer *vbuf = NULL;
- char *voutp = NULL;
- unsigned int linewidth;
-
- if (!dev->radio) {
- /* get video buffer */
- get_next_buf(dma_q, &vbuf);
-
- if (!vbuf)
- return rc;
- voutp = videobuf_to_vmalloc(&vbuf->vb);
-
- if (!voutp)
- return 0;
- }
-
- for (ptr = data; ptr < endp;) {
- if (!dev->isoc_ctl.cmd) {
- /* Header */
- if (dev->isoc_ctl.tmp_buf_len > 0) {
- /* from last urb or packet */
- header = dev->isoc_ctl.tmp_buf;
- if (4 - dev->isoc_ctl.tmp_buf_len > 0) {
- memcpy((u8 *)&header +
- dev->isoc_ctl.tmp_buf_len,
- ptr,
- 4 - dev->isoc_ctl.tmp_buf_len);
- ptr += 4 - dev->isoc_ctl.tmp_buf_len;
- }
- dev->isoc_ctl.tmp_buf_len = 0;
- } else {
- if (ptr + 3 >= endp) {
- /* have incomplete header */
- dev->isoc_ctl.tmp_buf_len = endp - ptr;
- memcpy(&dev->isoc_ctl.tmp_buf, ptr,
- dev->isoc_ctl.tmp_buf_len);
- return rc;
- }
- /* Seek for sync */
- for (; ptr < endp - 3; ptr++) {
- if (*(ptr + 3) == 0x47)
- break;
- }
- /* Get message header */
- header = *(unsigned long *)ptr;
- ptr += 4;
- }
-
- /* split the header fields */
- size = ((header & 0x7e) << 1);
- if (size > 0)
- size -= 4;
- block = (header >> 7) & 0xf;
- field = (header >> 11) & 0x1;
- line = (header >> 12) & 0x1ff;
- cmd = (header >> 21) & 0x7;
- /* Validates haeder fields */
- if (size > TM6000_URB_MSG_LEN)
- size = TM6000_URB_MSG_LEN;
- pktsize = TM6000_URB_MSG_LEN;
- /*
- * calculate position in buffer and change the buffer
- */
- switch (cmd) {
- case TM6000_URB_MSG_VIDEO:
- if (!dev->radio) {
- if ((dev->isoc_ctl.vfield != field) &&
- (field == 1)) {
- /*
- * Announces that a new buffer
- * were filled
- */
- buffer_filled(dev, dma_q, vbuf);
- dprintk(dev, V4L2_DEBUG_ISOC,
- "new buffer filled\n");
- get_next_buf(dma_q, &vbuf);
- if (!vbuf)
- return rc;
- voutp = videobuf_to_vmalloc(&vbuf->vb);
- if (!voutp)
- return rc;
- memset(voutp, 0, vbuf->vb.size);
- }
- linewidth = vbuf->vb.width << 1;
- pos = ((line << 1) - field - 1) *
- linewidth + block * TM6000_URB_MSG_LEN;
- /* Don't allow to write out of the buffer */
- if (pos + size > vbuf->vb.size)
- cmd = TM6000_URB_MSG_ERR;
- dev->isoc_ctl.vfield = field;
- }
- break;
- case TM6000_URB_MSG_VBI:
- break;
- case TM6000_URB_MSG_AUDIO:
- case TM6000_URB_MSG_PTS:
- size = pktsize; /* Size is always 180 bytes */
- break;
- }
- } else {
- /* Continue the last copy */
- cmd = dev->isoc_ctl.cmd;
- size = dev->isoc_ctl.size;
- pos = dev->isoc_ctl.pos;
- pktsize = dev->isoc_ctl.pktsize;
- field = dev->isoc_ctl.field;
- }
- cpysize = (endp - ptr > size) ? size : endp - ptr;
- if (cpysize) {
- /* copy data in different buffers */
- switch (cmd) {
- case TM6000_URB_MSG_VIDEO:
- /* Fills video buffer */
- if (vbuf)
- memcpy(&voutp[pos], ptr, cpysize);
- break;
- case TM6000_URB_MSG_AUDIO: {
- int i;
- for (i = 0; i < cpysize; i += 2)
- swab16s((u16 *)(ptr + i));
-
- tm6000_call_fillbuf(dev, TM6000_AUDIO, ptr, cpysize);
- break;
- }
- case TM6000_URB_MSG_VBI:
- /* Need some code to copy vbi buffer */
- break;
- case TM6000_URB_MSG_PTS: {
- /* Need some code to copy pts */
- u32 pts;
- pts = *(u32 *)ptr;
- dprintk(dev, V4L2_DEBUG_ISOC, "field %d, PTS %x",
- field, pts);
- break;
- }
- }
- }
- if (ptr + pktsize > endp) {
- /*
- * End of URB packet, but cmd processing is not
- * complete. Preserve the state for a next packet
- */
- dev->isoc_ctl.pos = pos + cpysize;
- dev->isoc_ctl.size = size - cpysize;
- dev->isoc_ctl.cmd = cmd;
- dev->isoc_ctl.field = field;
- dev->isoc_ctl.pktsize = pktsize - (endp - ptr);
- ptr += endp - ptr;
- } else {
- dev->isoc_ctl.cmd = 0;
- ptr += pktsize;
- }
- }
- return 0;
-}
-
-/*
- * Identify the tm5600/6000 buffer header type and properly handles
- */
-static int copy_multiplexed(u8 *ptr, unsigned long len,
- struct urb *urb)
-{
- struct tm6000_dmaqueue *dma_q = urb->context;
- struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
- unsigned int pos = dev->isoc_ctl.pos, cpysize;
- int rc = 1;
- struct tm6000_buffer *buf;
- char *outp = NULL;
-
- get_next_buf(dma_q, &buf);
- if (buf)
- outp = videobuf_to_vmalloc(&buf->vb);
-
- if (!outp)
- return 0;
-
- while (len > 0) {
- cpysize = min(len, buf->vb.size-pos);
- memcpy(&outp[pos], ptr, cpysize);
- pos += cpysize;
- ptr += cpysize;
- len -= cpysize;
- if (pos >= buf->vb.size) {
- pos = 0;
- /* Announces that a new buffer were filled */
- buffer_filled(dev, dma_q, buf);
- dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n");
- get_next_buf(dma_q, &buf);
- if (!buf)
- break;
- outp = videobuf_to_vmalloc(&(buf->vb));
- if (!outp)
- return rc;
- pos = 0;
- }
- }
-
- dev->isoc_ctl.pos = pos;
- return rc;
-}
-
-static inline void print_err_status(struct tm6000_core *dev,
- int packet, int status)
-{
- char *errmsg = "Unknown";
-
- switch (status) {
- case -ENOENT:
- errmsg = "unlinked synchronuously";
- break;
- case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
- break;
- case -ENOSR:
- errmsg = "Buffer error (overrun)";
- break;
- case -EPIPE:
- errmsg = "Stalled (device not responding)";
- break;
- case -EOVERFLOW:
- errmsg = "Babble (bad cable?)";
- break;
- case -EPROTO:
- errmsg = "Bit-stuff error (bad cable?)";
- break;
- case -EILSEQ:
- errmsg = "CRC/Timeout (could be anything)";
- break;
- case -ETIME:
- errmsg = "Device does not respond";
- break;
- }
- if (packet < 0) {
- dprintk(dev, V4L2_DEBUG_QUEUE, "URB status %d [%s].\n",
- status, errmsg);
- } else {
- dprintk(dev, V4L2_DEBUG_QUEUE, "URB packet %d, status %d [%s].\n",
- packet, status, errmsg);
- }
-}
-
-
-/*
- * Controls the isoc copy of each urb packet
- */
-static inline int tm6000_isoc_copy(struct urb *urb)
-{
- struct tm6000_dmaqueue *dma_q = urb->context;
- struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
- int i, len = 0, rc = 1, status;
- char *p;
-
- if (urb->status < 0) {
- print_err_status(dev, -1, urb->status);
- return 0;
- }
-
- for (i = 0; i < urb->number_of_packets; i++) {
- status = urb->iso_frame_desc[i].status;
-
- if (status < 0) {
- print_err_status(dev, i, status);
- continue;
- }
-
- len = urb->iso_frame_desc[i].actual_length;
-
- if (len > 0) {
- p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
- if (!urb->iso_frame_desc[i].status) {
- if ((dev->fourcc) == V4L2_PIX_FMT_TM6000) {
- rc = copy_multiplexed(p, len, urb);
- if (rc <= 0)
- return rc;
- } else {
- copy_streams(p, len, urb);
- }
- }
- }
- }
- return rc;
-}
-
-/* ------------------------------------------------------------------
- * URB control
- * ------------------------------------------------------------------
- */
-
-/*
- * IRQ callback, called by URB callback
- */
-static void tm6000_irq_callback(struct urb *urb)
-{
- struct tm6000_dmaqueue *dma_q = urb->context;
- struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
- int i;
-
- switch (urb->status) {
- case 0:
- case -ETIMEDOUT:
- break;
-
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- return;
-
- default:
- tm6000_err("urb completion error %d.\n", urb->status);
- break;
- }
-
- spin_lock(&dev->slock);
- tm6000_isoc_copy(urb);
- spin_unlock(&dev->slock);
-
- /* Reset urb buffers */
- for (i = 0; i < urb->number_of_packets; i++) {
- urb->iso_frame_desc[i].status = 0;
- urb->iso_frame_desc[i].actual_length = 0;
- }
-
- urb->status = usb_submit_urb(urb, GFP_ATOMIC);
- if (urb->status)
- tm6000_err("urb resubmit failed (error=%i)\n",
- urb->status);
-}
-
-/*
- * Stop and Deallocate URBs
- */
-static void tm6000_uninit_isoc(struct tm6000_core *dev)
-{
- struct urb *urb;
- int i;
-
- dev->isoc_ctl.buf = NULL;
- for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
- urb = dev->isoc_ctl.urb[i];
- if (urb) {
- usb_kill_urb(urb);
- usb_unlink_urb(urb);
- if (dev->isoc_ctl.transfer_buffer[i]) {
- usb_free_coherent(dev->udev,
- urb->transfer_buffer_length,
- dev->isoc_ctl.transfer_buffer[i],
- urb->transfer_dma);
- }
- usb_free_urb(urb);
- dev->isoc_ctl.urb[i] = NULL;
- }
- dev->isoc_ctl.transfer_buffer[i] = NULL;
- }
-
- kfree(dev->isoc_ctl.urb);
- kfree(dev->isoc_ctl.transfer_buffer);
-
- dev->isoc_ctl.urb = NULL;
- dev->isoc_ctl.transfer_buffer = NULL;
- dev->isoc_ctl.num_bufs = 0;
-}
-
-/*
- * Allocate URBs and start IRQ
- */
-static int tm6000_prepare_isoc(struct tm6000_core *dev)
-{
- struct tm6000_dmaqueue *dma_q = &dev->vidq;
- int i, j, sb_size, pipe, size, max_packets, num_bufs = 8;
- struct urb *urb;
-
- /* De-allocates all pending stuff */
- tm6000_uninit_isoc(dev);
- /* Stop interrupt USB pipe */
- tm6000_ir_int_stop(dev);
-
- usb_set_interface(dev->udev,
- dev->isoc_in.bInterfaceNumber,
- dev->isoc_in.bAlternateSetting);
-
- /* Start interrupt USB pipe */
- tm6000_ir_int_start(dev);
-
- pipe = usb_rcvisocpipe(dev->udev,
- dev->isoc_in.endp->desc.bEndpointAddress &
- USB_ENDPOINT_NUMBER_MASK);
-
- size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
-
- if (size > dev->isoc_in.maxsize)
- size = dev->isoc_in.maxsize;
-
- dev->isoc_ctl.max_pkt_size = size;
-
- max_packets = TM6000_MAX_ISO_PACKETS;
- sb_size = max_packets * size;
-
- dev->isoc_ctl.num_bufs = num_bufs;
-
- dev->isoc_ctl.urb = kmalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
- if (!dev->isoc_ctl.urb) {
- tm6000_err("cannot alloc memory for usb buffers\n");
- return -ENOMEM;
- }
-
- dev->isoc_ctl.transfer_buffer = kmalloc(sizeof(void *)*num_bufs,
- GFP_KERNEL);
- if (!dev->isoc_ctl.transfer_buffer) {
- tm6000_err("cannot allocate memory for usbtransfer\n");
- kfree(dev->isoc_ctl.urb);
- return -ENOMEM;
- }
-
- dprintk(dev, V4L2_DEBUG_QUEUE, "Allocating %d x %d packets"
- " (%d bytes) of %d bytes each to handle %u size\n",
- max_packets, num_bufs, sb_size,
- dev->isoc_in.maxsize, size);
-
- /* allocate urbs and transfer buffers */
- for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
- urb = usb_alloc_urb(max_packets, GFP_KERNEL);
- if (!urb) {
- tm6000_err("cannot alloc isoc_ctl.urb %i\n", i);
- tm6000_uninit_isoc(dev);
- usb_free_urb(urb);
- return -ENOMEM;
- }
- dev->isoc_ctl.urb[i] = urb;
-
- dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->udev,
- sb_size, GFP_KERNEL, &urb->transfer_dma);
- if (!dev->isoc_ctl.transfer_buffer[i]) {
- tm6000_err("unable to allocate %i bytes for transfer"
- " buffer %i%s\n",
- sb_size, i,
- in_interrupt() ? " while in int" : "");
- tm6000_uninit_isoc(dev);
- return -ENOMEM;
- }
- memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
-
- usb_fill_bulk_urb(urb, dev->udev, pipe,
- dev->isoc_ctl.transfer_buffer[i], sb_size,
- tm6000_irq_callback, dma_q);
- urb->interval = dev->isoc_in.endp->desc.bInterval;
- urb->number_of_packets = max_packets;
- urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
-
- for (j = 0; j < max_packets; j++) {
- urb->iso_frame_desc[j].offset = size * j;
- urb->iso_frame_desc[j].length = size;
- }
- }
-
- return 0;
-}
-
-static int tm6000_start_thread(struct tm6000_core *dev)
-{
- struct tm6000_dmaqueue *dma_q = &dev->vidq;
- int i;
-
- dma_q->frame = 0;
- dma_q->ini_jiffies = jiffies;
-
- init_waitqueue_head(&dma_q->wq);
-
- /* submit urbs and enables IRQ */
- for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
- int rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
- if (rc) {
- tm6000_err("submit of urb %i failed (error=%i)\n", i,
- rc);
- tm6000_uninit_isoc(dev);
- return rc;
- }
- }
-
- return 0;
-}
-
-/* ------------------------------------------------------------------
- * Videobuf operations
- * ------------------------------------------------------------------
- */
-
-static int
-buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
-{
- struct tm6000_fh *fh = vq->priv_data;
-
- *size = fh->fmt->depth * fh->width * fh->height >> 3;
- if (0 == *count)
- *count = TM6000_DEF_BUF;
-
- if (*count < TM6000_MIN_BUF)
- *count = TM6000_MIN_BUF;
-
- while (*size * *count > vid_limit * 1024 * 1024)
- (*count)--;
-
- return 0;
-}
-
-static void free_buffer(struct videobuf_queue *vq, struct tm6000_buffer *buf)
-{
- struct tm6000_fh *fh = vq->priv_data;
- struct tm6000_core *dev = fh->dev;
- unsigned long flags;
-
- if (in_interrupt())
- BUG();
-
- /* We used to wait for the buffer to finish here, but this didn't work
- because, as we were keeping the state as VIDEOBUF_QUEUED,
- videobuf_queue_cancel marked it as finished for us.
- (Also, it could wedge forever if the hardware was misconfigured.)
-
- This should be safe; by the time we get here, the buffer isn't
- queued anymore. If we ever start marking the buffers as
- VIDEOBUF_ACTIVE, it won't be, though.
- */
- spin_lock_irqsave(&dev->slock, flags);
- if (dev->isoc_ctl.buf == buf)
- dev->isoc_ctl.buf = NULL;
- spin_unlock_irqrestore(&dev->slock, flags);
-
- videobuf_vmalloc_free(&buf->vb);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int
-buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct tm6000_fh *fh = vq->priv_data;
- struct tm6000_buffer *buf = container_of(vb, struct tm6000_buffer, vb);
- struct tm6000_core *dev = fh->dev;
- int rc = 0;
-
- BUG_ON(NULL == fh->fmt);
-
-
- /* FIXME: It assumes depth=2 */
- /* The only currently supported format is 16 bits/pixel */
- buf->vb.size = fh->fmt->depth*fh->width*fh->height >> 3;
- if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
- return -EINVAL;
-
- if (buf->fmt != fh->fmt ||
- buf->vb.width != fh->width ||
- buf->vb.height != fh->height ||
- buf->vb.field != field) {
- buf->fmt = fh->fmt;
- buf->vb.width = fh->width;
- buf->vb.height = fh->height;
- buf->vb.field = field;
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
- }
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- rc = videobuf_iolock(vq, &buf->vb, NULL);
- if (rc != 0)
- goto fail;
- }
-
- if (!dev->isoc_ctl.num_bufs) {
- rc = tm6000_prepare_isoc(dev);
- if (rc < 0)
- goto fail;
-
- rc = tm6000_start_thread(dev);
- if (rc < 0)
- goto fail;
-
- }
-
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-
-fail:
- free_buffer(vq, buf);
- return rc;
-}
-
-static void
-buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct tm6000_buffer *buf = container_of(vb, struct tm6000_buffer, vb);
- struct tm6000_fh *fh = vq->priv_data;
- struct tm6000_core *dev = fh->dev;
- struct tm6000_dmaqueue *vidq = &dev->vidq;
-
- buf->vb.state = VIDEOBUF_QUEUED;
- list_add_tail(&buf->vb.queue, &vidq->active);
-}
-
-static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct tm6000_buffer *buf = container_of(vb, struct tm6000_buffer, vb);
-
- free_buffer(vq, buf);
-}
-
-static struct videobuf_queue_ops tm6000_video_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-/* ------------------------------------------------------------------
- * IOCTL handling
- * ------------------------------------------------------------------
- */
-
-static bool is_res_read(struct tm6000_core *dev, struct tm6000_fh *fh)
-{
- /* Is the current fh handling it? if so, that's OK */
- if (dev->resources == fh && dev->is_res_read)
- return true;
-
- return false;
-}
-
-static bool is_res_streaming(struct tm6000_core *dev, struct tm6000_fh *fh)
-{
- /* Is the current fh handling it? if so, that's OK */
- if (dev->resources == fh)
- return true;
-
- return false;
-}
-
-static bool res_get(struct tm6000_core *dev, struct tm6000_fh *fh,
- bool is_res_read)
-{
- /* Is the current fh handling it? if so, that's OK */
- if (dev->resources == fh && dev->is_res_read == is_res_read)
- return true;
-
- /* is it free? */
- if (dev->resources)
- return false;
-
- /* grab it */
- dev->resources = fh;
- dev->is_res_read = is_res_read;
- dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: get\n");
- return true;
-}
-
-static void res_free(struct tm6000_core *dev, struct tm6000_fh *fh)
-{
- /* Is the current fh handling it? if so, that's OK */
- if (dev->resources != fh)
- return;
-
- dev->resources = NULL;
- dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: put\n");
-}
-
-/* ------------------------------------------------------------------
- * IOCTL vidioc handling
- * ------------------------------------------------------------------
- */
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev;
-
- strlcpy(cap->driver, "tm6000", sizeof(cap->driver));
- strlcpy(cap->card, "Trident TVMaster TM5600/6000/6010", sizeof(cap->card));
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_STREAMING |
- V4L2_CAP_AUDIO |
- V4L2_CAP_READWRITE;
-
- if (dev->tuner_type != TUNER_ABSENT)
- cap->capabilities |= V4L2_CAP_TUNER;
-
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (unlikely(f->index >= ARRAY_SIZE(format)))
- return -EINVAL;
-
- strlcpy(f->description, format[f->index].name, sizeof(f->description));
- f->pixelformat = format[f->index].fourcc;
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct tm6000_fh *fh = priv;
-
- f->fmt.pix.width = fh->width;
- f->fmt.pix.height = fh->height;
- f->fmt.pix.field = fh->vb_vidq.field;
- f->fmt.pix.pixelformat = fh->fmt->fourcc;
- f->fmt.pix.bytesperline =
- (f->fmt.pix.width * fh->fmt->depth) >> 3;
- f->fmt.pix.sizeimage =
- f->fmt.pix.height * f->fmt.pix.bytesperline;
-
- return 0;
-}
-
-static struct tm6000_fmt *format_by_fourcc(unsigned int fourcc)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(format); i++)
- if (format[i].fourcc == fourcc)
- return format+i;
- return NULL;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev;
- struct tm6000_fmt *fmt;
- enum v4l2_field field;
-
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- if (NULL == fmt) {
- dprintk(dev, V4L2_DEBUG_IOCTL_ARG, "Fourcc format (0x%08x)"
- " invalid.\n", f->fmt.pix.pixelformat);
- return -EINVAL;
- }
-
- field = f->fmt.pix.field;
-
- if (field == V4L2_FIELD_ANY)
- field = V4L2_FIELD_SEQ_TB;
- else if (V4L2_FIELD_INTERLACED != field) {
- dprintk(dev, V4L2_DEBUG_IOCTL_ARG, "Field type invalid.\n");
- return -EINVAL;
- }
-
- tm6000_get_std_res(dev);
-
- f->fmt.pix.width = dev->width;
- f->fmt.pix.height = dev->height;
-
- f->fmt.pix.width &= ~0x01;
-
- f->fmt.pix.field = field;
-
- f->fmt.pix.bytesperline =
- (f->fmt.pix.width * fmt->depth) >> 3;
- f->fmt.pix.sizeimage =
- f->fmt.pix.height * f->fmt.pix.bytesperline;
-
- return 0;
-}
-
-/*FIXME: This seems to be generic enough to be at videodev2 */
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
- int ret = vidioc_try_fmt_vid_cap(file, fh, f);
- if (ret < 0)
- return ret;
-
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->width = f->fmt.pix.width;
- fh->height = f->fmt.pix.height;
- fh->vb_vidq.field = f->fmt.pix.field;
- fh->type = f->type;
-
- dev->fourcc = f->fmt.pix.pixelformat;
-
- tm6000_set_fourcc_format(dev);
-
- return 0;
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct tm6000_fh *fh = priv;
-
- return videobuf_reqbufs(&fh->vb_vidq, p);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct tm6000_fh *fh = priv;
-
- return videobuf_querybuf(&fh->vb_vidq, p);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct tm6000_fh *fh = priv;
-
- return videobuf_qbuf(&fh->vb_vidq, p);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct tm6000_fh *fh = priv;
-
- return videobuf_dqbuf(&fh->vb_vidq, p,
- file->f_flags & O_NONBLOCK);
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- if (!res_get(dev, fh, false))
- return -EBUSY;
- return videobuf_streamon(&fh->vb_vidq);
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (i != fh->type)
- return -EINVAL;
-
- videobuf_streamoff(&fh->vb_vidq);
- res_free(dev, fh);
-
- return 0;
-}
-
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
-{
- int rc = 0;
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
-
- dev->norm = *norm;
- rc = tm6000_init_analog_mode(dev);
-
- fh->width = dev->width;
- fh->height = dev->height;
-
- if (rc < 0)
- return rc;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
-
- return 0;
-}
-
-static const char *iname[] = {
- [TM6000_INPUT_TV] = "Television",
- [TM6000_INPUT_COMPOSITE1] = "Composite 1",
- [TM6000_INPUT_COMPOSITE2] = "Composite 2",
- [TM6000_INPUT_SVIDEO] = "S-Video",
-};
-
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
- unsigned int n;
-
- n = i->index;
- if (n >= 3)
- return -EINVAL;
-
- if (!dev->vinput[n].type)
- return -EINVAL;
-
- i->index = n;
-
- if (dev->vinput[n].type == TM6000_INPUT_TV)
- i->type = V4L2_INPUT_TYPE_TUNER;
- else
- i->type = V4L2_INPUT_TYPE_CAMERA;
-
- strcpy(i->name, iname[dev->vinput[n].type]);
-
- i->std = TM6000_STD;
-
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
-
- *i = dev->input;
-
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
- int rc = 0;
-
- if (i >= 3)
- return -EINVAL;
- if (!dev->vinput[i].type)
- return -EINVAL;
-
- dev->input = i;
-
- rc = vidioc_s_std(file, priv, &dev->vfd->current_norm);
-
- return rc;
-}
-
-/* --- controls ---------------------------------------------- */
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qc)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(tm6000_qctrl); i++)
- if (qc->id && qc->id == tm6000_qctrl[i].id) {
- memcpy(qc, &(tm6000_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
- int val;
-
- /* FIXME: Probably, those won't work! Maybe we need shadow regs */
- switch (ctrl->id) {
- case V4L2_CID_CONTRAST:
- val = tm6000_get_reg(dev, TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, 0);
- break;
- case V4L2_CID_BRIGHTNESS:
- val = tm6000_get_reg(dev, TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, 0);
- return 0;
- case V4L2_CID_SATURATION:
- val = tm6000_get_reg(dev, TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, 0);
- return 0;
- case V4L2_CID_HUE:
- val = tm6000_get_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, 0);
- return 0;
- case V4L2_CID_AUDIO_MUTE:
- val = dev->ctl_mute;
- return 0;
- case V4L2_CID_AUDIO_VOLUME:
- val = dev->ctl_volume;
- return 0;
- default:
- return -EINVAL;
- }
-
- if (val < 0)
- return val;
-
- ctrl->value = val;
-
- return 0;
-}
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
- u8 val = ctrl->value;
-
- switch (ctrl->id) {
- case V4L2_CID_CONTRAST:
- tm6000_set_reg(dev, TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, val);
- return 0;
- case V4L2_CID_BRIGHTNESS:
- tm6000_set_reg(dev, TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, val);
- return 0;
- case V4L2_CID_SATURATION:
- tm6000_set_reg(dev, TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, val);
- return 0;
- case V4L2_CID_HUE:
- tm6000_set_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, val);
- return 0;
- case V4L2_CID_AUDIO_MUTE:
- dev->ctl_mute = val;
- tm6000_tvaudio_set_mute(dev, val);
- return 0;
- case V4L2_CID_AUDIO_VOLUME:
- dev->ctl_volume = val;
- tm6000_set_volume(dev, val);
- return 0;
- }
- return -EINVAL;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
-
- if (unlikely(UNSET == dev->tuner_type))
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
-
- strcpy(t->name, "Television");
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM;
- t->rangehigh = 0xffffffffUL;
- t->rxsubchans = V4L2_TUNER_SUB_STEREO;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
-
- t->audmode = dev->amode;
-
- return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
-
- if (UNSET == dev->tuner_type)
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
-
- dev->amode = t->audmode;
- dprintk(dev, 3, "audio mode: %x\n", t->audmode);
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
-
- return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
-
- if (unlikely(UNSET == dev->tuner_type))
- return -EINVAL;
-
- f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- f->frequency = dev->freq;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, f);
-
- return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
-
- if (unlikely(UNSET == dev->tuner_type))
- return -EINVAL;
- if (unlikely(f->tuner != 0))
- return -EINVAL;
- if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
- return -EINVAL;
- if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
- return -EINVAL;
-
- dev->freq = f->frequency;
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f);
-
- return 0;
-}
-
-static int radio_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct tm6000_fh *fh = file->private_data;
- struct tm6000_core *dev = fh->dev;
-
- strcpy(cap->driver, "tm6000");
- strlcpy(cap->card, dev->name, sizeof(dev->name));
- sprintf(cap->bus_info, "USB%04x:%04x",
- le16_to_cpu(dev->udev->descriptor.idVendor),
- le16_to_cpu(dev->udev->descriptor.idProduct));
- cap->version = dev->dev_type;
- cap->capabilities = V4L2_CAP_TUNER |
- V4L2_CAP_AUDIO |
- V4L2_CAP_RADIO |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING;
-
- return 0;
-}
-
-static int radio_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct tm6000_fh *fh = file->private_data;
- struct tm6000_core *dev = fh->dev;
-
- if (0 != t->index)
- return -EINVAL;
-
- memset(t, 0, sizeof(*t));
- strcpy(t->name, "Radio");
- t->type = V4L2_TUNER_RADIO;
- t->rxsubchans = V4L2_TUNER_SUB_STEREO;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
-
- return 0;
-}
-
-static int radio_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct tm6000_fh *fh = file->private_data;
- struct tm6000_core *dev = fh->dev;
-
- if (0 != t->index)
- return -EINVAL;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
-
- return 0;
-}
-
-static int radio_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
-
- if (i->index != 0)
- return -EINVAL;
-
- if (!dev->rinput.type)
- return -EINVAL;
-
- strcpy(i->name, "Radio");
- i->type = V4L2_INPUT_TYPE_TUNER;
-
- return 0;
-}
-
-static int radio_g_input(struct file *filp, void *priv, unsigned int *i)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
-
- if (dev->input != 5)
- return -EINVAL;
-
- *i = dev->input - 5;
-
- return 0;
-}
-
-static int radio_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- memset(a, 0, sizeof(*a));
- strcpy(a->name, "Radio");
- return 0;
-}
-
-static int radio_s_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- return 0;
-}
-
-static int radio_s_input(struct file *filp, void *priv, unsigned int i)
-{
- struct tm6000_fh *fh = priv;
- struct tm6000_core *dev = fh->dev;
-
- if (i)
- return -EINVAL;
-
- if (!dev->rinput.type)
- return -EINVAL;
-
- dev->input = i + 5;
-
- return 0;
-}
-
-static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm)
-{
- return 0;
-}
-
-static int radio_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *c)
-{
- const struct v4l2_queryctrl *ctrl;
-
- if (c->id < V4L2_CID_BASE ||
- c->id >= V4L2_CID_LASTP1)
- return -EINVAL;
- if (c->id == V4L2_CID_AUDIO_MUTE) {
- ctrl = ctrl_by_id(c->id);
- *c = *ctrl;
- } else
- *c = no_ctrl;
-
- return 0;
-}
-
-/* ------------------------------------------------------------------
- File operations for the device
- ------------------------------------------------------------------*/
-
-static int tm6000_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct tm6000_core *dev = video_drvdata(file);
- struct tm6000_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- int i, rc;
- int radio = 0;
-
- dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: open called (dev=%s)\n",
- video_device_node_name(vdev));
-
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- case VFL_TYPE_VBI:
- type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- case VFL_TYPE_RADIO:
- radio = 1;
- break;
- }
-
- /* If more than one user, mutex should be added */
- dev->users++;
-
- dprintk(dev, V4L2_DEBUG_OPEN, "open dev=%s type=%s users=%d\n",
- video_device_node_name(vdev), v4l2_type_names[type],
- dev->users);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh) {
- dev->users--;
- return -ENOMEM;
- }
-
- file->private_data = fh;
- fh->dev = dev;
- fh->radio = radio;
- dev->radio = radio;
- fh->type = type;
- dev->fourcc = format[0].fourcc;
-
- fh->fmt = format_by_fourcc(dev->fourcc);
-
- tm6000_get_std_res(dev);
-
- fh->width = dev->width;
- fh->height = dev->height;
-
- dprintk(dev, V4L2_DEBUG_OPEN, "Open: fh=0x%08lx, dev=0x%08lx, "
- "dev->vidq=0x%08lx\n",
- (unsigned long)fh, (unsigned long)dev,
- (unsigned long)&dev->vidq);
- dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty "
- "queued=%d\n", list_empty(&dev->vidq.queued));
- dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty "
- "active=%d\n", list_empty(&dev->vidq.active));
-
- /* initialize hardware on analog mode */
- rc = tm6000_init_analog_mode(dev);
- if (rc < 0)
- return rc;
-
- if (dev->mode != TM6000_MODE_ANALOG) {
- /* Put all controls at a sane state */
- for (i = 0; i < ARRAY_SIZE(tm6000_qctrl); i++)
- qctl_regs[i] = tm6000_qctrl[i].default_value;
-
- dev->mode = TM6000_MODE_ANALOG;
- }
-
- if (!fh->radio) {
- videobuf_queue_vmalloc_init(&fh->vb_vidq, &tm6000_video_qops,
- NULL, &dev->slock,
- fh->type,
- V4L2_FIELD_INTERLACED,
- sizeof(struct tm6000_buffer), fh, &dev->lock);
- } else {
- dprintk(dev, V4L2_DEBUG_OPEN, "video_open: setting radio device\n");
- dev->input = 5;
- tm6000_set_audio_rinput(dev);
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
- tm6000_prepare_isoc(dev);
- tm6000_start_thread(dev);
- }
-
- return 0;
-}
-
-static ssize_t
-tm6000_read(struct file *file, char __user *data, size_t count, loff_t *pos)
-{
- struct tm6000_fh *fh = file->private_data;
-
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- if (!res_get(fh->dev, fh, true))
- return -EBUSY;
-
- return videobuf_read_stream(&fh->vb_vidq, data, count, pos, 0,
- file->f_flags & O_NONBLOCK);
- }
- return 0;
-}
-
-static unsigned int
-tm6000_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct tm6000_fh *fh = file->private_data;
- struct tm6000_buffer *buf;
-
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
- return POLLERR;
-
- if (!!is_res_streaming(fh->dev, fh))
- return POLLERR;
-
- if (!is_res_read(fh->dev, fh)) {
- /* streaming capture */
- if (list_empty(&fh->vb_vidq.stream))
- return POLLERR;
- buf = list_entry(fh->vb_vidq.stream.next, struct tm6000_buffer, vb.stream);
- } else {
- /* read() capture */
- return videobuf_poll_stream(file, &fh->vb_vidq, wait);
- }
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE ||
- buf->vb.state == VIDEOBUF_ERROR)
- return POLLIN | POLLRDNORM;
- return 0;
-}
-
-static int tm6000_release(struct file *file)
-{
- struct tm6000_fh *fh = file->private_data;
- struct tm6000_core *dev = fh->dev;
- struct video_device *vdev = video_devdata(file);
-
- dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: close called (dev=%s, users=%d)\n",
- video_device_node_name(vdev), dev->users);
-
- dev->users--;
-
- res_free(dev, fh);
-
- if (!dev->users) {
- tm6000_uninit_isoc(dev);
-
- /* Stop interrupt USB pipe */
- tm6000_ir_int_stop(dev);
-
- usb_reset_configuration(dev->udev);
-
- if (dev->int_in.endp)
- usb_set_interface(dev->udev,
- dev->isoc_in.bInterfaceNumber, 2);
- else
- usb_set_interface(dev->udev,
- dev->isoc_in.bInterfaceNumber, 0);
-
- /* Start interrupt USB pipe */
- tm6000_ir_int_start(dev);
-
- if (!fh->radio)
- videobuf_mmap_free(&fh->vb_vidq);
- }
-
- kfree(fh);
-
- return 0;
-}
-
-static int tm6000_mmap(struct file *file, struct vm_area_struct * vma)
-{
- struct tm6000_fh *fh = file->private_data;
-
- return videobuf_mmap_mapper(&fh->vb_vidq, vma);
-}
-
-static struct v4l2_file_operations tm6000_fops = {
- .owner = THIS_MODULE,
- .open = tm6000_open,
- .release = tm6000_release,
- .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
- .read = tm6000_read,
- .poll = tm6000_poll,
- .mmap = tm6000_mmap,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-};
-
-static struct video_device tm6000_template = {
- .name = "tm6000",
- .fops = &tm6000_fops,
- .ioctl_ops = &video_ioctl_ops,
- .release = video_device_release,
- .tvnorms = TM6000_STD,
- .current_norm = V4L2_STD_NTSC_M,
-};
-
-static const struct v4l2_file_operations radio_fops = {
- .owner = THIS_MODULE,
- .open = tm6000_open,
- .release = tm6000_release,
- .unlocked_ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops radio_ioctl_ops = {
- .vidioc_querycap = radio_querycap,
- .vidioc_g_tuner = radio_g_tuner,
- .vidioc_enum_input = radio_enum_input,
- .vidioc_g_audio = radio_g_audio,
- .vidioc_s_tuner = radio_s_tuner,
- .vidioc_s_audio = radio_s_audio,
- .vidioc_s_input = radio_s_input,
- .vidioc_s_std = radio_s_std,
- .vidioc_queryctrl = radio_queryctrl,
- .vidioc_g_input = radio_g_input,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
-};
-
-static struct video_device tm6000_radio_template = {
- .name = "tm6000",
- .fops = &radio_fops,
- .ioctl_ops = &radio_ioctl_ops,
-};
-
-/* -----------------------------------------------------------------
- * Initialization and module stuff
- * ------------------------------------------------------------------
- */
-
-static struct video_device *vdev_init(struct tm6000_core *dev,
- const struct video_device
- *template, const char *type_name)
-{
- struct video_device *vfd;
-
- vfd = video_device_alloc();
- if (NULL == vfd)
- return NULL;
-
- *vfd = *template;
- vfd->v4l2_dev = &dev->v4l2_dev;
- vfd->release = video_device_release;
- vfd->debug = tm6000_debug;
- vfd->lock = &dev->lock;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
-
- snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
-
- video_set_drvdata(vfd, dev);
- return vfd;
-}
-
-int tm6000_v4l2_register(struct tm6000_core *dev)
-{
- int ret = -1;
-
- dev->vfd = vdev_init(dev, &tm6000_template, "video");
-
- if (!dev->vfd) {
- printk(KERN_INFO "%s: can't register video device\n",
- dev->name);
- return -ENOMEM;
- }
-
- /* init video dma queues */
- INIT_LIST_HEAD(&dev->vidq.active);
- INIT_LIST_HEAD(&dev->vidq.queued);
-
- ret = video_register_device(dev->vfd, VFL_TYPE_GRABBER, video_nr);
-
- if (ret < 0) {
- printk(KERN_INFO "%s: can't register video device\n",
- dev->name);
- return ret;
- }
-
- printk(KERN_INFO "%s: registered device %s\n",
- dev->name, video_device_node_name(dev->vfd));
-
- if (dev->caps.has_radio) {
- dev->radio_dev = vdev_init(dev, &tm6000_radio_template,
- "radio");
- if (!dev->radio_dev) {
- printk(KERN_INFO "%s: can't register radio device\n",
- dev->name);
- return ret; /* FIXME release resource */
- }
-
- ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
- radio_nr);
- if (ret < 0) {
- printk(KERN_INFO "%s: can't register radio device\n",
- dev->name);
- return ret; /* FIXME release resource */
- }
-
- printk(KERN_INFO "%s: registered device %s\n",
- dev->name, video_device_node_name(dev->radio_dev));
- }
-
- printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret);
- return ret;
-}
-
-int tm6000_v4l2_unregister(struct tm6000_core *dev)
-{
- video_unregister_device(dev->vfd);
-
- if (dev->radio_dev) {
- if (video_is_registered(dev->radio_dev))
- video_unregister_device(dev->radio_dev);
- else
- video_device_release(dev->radio_dev);
- dev->radio_dev = NULL;
- }
-
- return 0;
-}
-
-int tm6000_v4l2_exit(void)
-{
- return 0;
-}
-
-module_param(video_nr, int, 0);
-MODULE_PARM_DESC(video_nr, "Allow changing video device number");
-
-module_param_named(debug, tm6000_debug, int, 0444);
-MODULE_PARM_DESC(debug, "activates debug info");
-
-module_param(vid_limit, int, 0644);
-MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
-
diff --git a/drivers/media/video/tm6000/tm6000.h b/drivers/media/video/tm6000/tm6000.h
deleted file mode 100644
index 6df418658c9..00000000000
--- a/drivers/media/video/tm6000/tm6000.h
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * tm6000.h - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
- * - DVB-T support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/videobuf-vmalloc.h>
-#include "tm6000-usb-isoc.h"
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <media/v4l2-device.h>
-
-#include <linux/dvb/frontend.h>
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dmxdev.h"
-
-/* Inputs */
-enum tm6000_itype {
- TM6000_INPUT_TV = 1,
- TM6000_INPUT_COMPOSITE1,
- TM6000_INPUT_COMPOSITE2,
- TM6000_INPUT_SVIDEO,
- TM6000_INPUT_DVB,
- TM6000_INPUT_RADIO,
-};
-
-enum tm6000_mux {
- TM6000_VMUX_VIDEO_A = 1,
- TM6000_VMUX_VIDEO_B,
- TM6000_VMUX_VIDEO_AB,
- TM6000_AMUX_ADC1,
- TM6000_AMUX_ADC2,
- TM6000_AMUX_SIF1,
- TM6000_AMUX_SIF2,
- TM6000_AMUX_I2S,
-};
-
-enum tm6000_devtype {
- TM6000 = 0,
- TM5600,
- TM6010,
-};
-
-struct tm6000_input {
- enum tm6000_itype type;
- enum tm6000_mux vmux;
- enum tm6000_mux amux;
- unsigned int v_gpio;
- unsigned int a_gpio;
-};
-
-/* ------------------------------------------------------------------
- * Basic structures
- * ------------------------------------------------------------------
- */
-
-struct tm6000_fmt {
- char *name;
- u32 fourcc; /* v4l2 format id */
- int depth;
-};
-
-/* buffer for one video frame */
-struct tm6000_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
-
- struct tm6000_fmt *fmt;
-};
-
-struct tm6000_dmaqueue {
- struct list_head active;
- struct list_head queued;
-
- /* thread for generating video stream*/
- struct task_struct *kthread;
- wait_queue_head_t wq;
- /* Counters to control fps rate */
- int frame;
- int ini_jiffies;
-};
-
-/* device states */
-enum tm6000_core_state {
- DEV_INITIALIZED = 0x01,
- DEV_DISCONNECTED = 0x02,
- DEV_MISCONFIGURED = 0x04,
-};
-
-/* io methods */
-enum tm6000_io_method {
- IO_NONE,
- IO_READ,
- IO_MMAP,
-};
-
-enum tm6000_mode {
- TM6000_MODE_UNKNOWN = 0,
- TM6000_MODE_ANALOG,
- TM6000_MODE_DIGITAL,
-};
-
-struct tm6000_gpio {
- int tuner_reset;
- int tuner_on;
- int demod_reset;
- int demod_on;
- int power_led;
- int dvb_led;
- int ir;
-};
-
-struct tm6000_capabilities {
- unsigned int has_tuner:1;
- unsigned int has_tda9874:1;
- unsigned int has_dvb:1;
- unsigned int has_zl10353:1;
- unsigned int has_eeprom:1;
- unsigned int has_remote:1;
- unsigned int has_radio:1;
-};
-
-struct tm6000_dvb {
- struct dvb_adapter adapter;
- struct dvb_demux demux;
- struct dvb_frontend *frontend;
- struct dmxdev dmxdev;
- unsigned int streams;
- struct urb *bulk_urb;
- struct mutex mutex;
-};
-
-struct snd_tm6000_card {
- struct snd_card *card;
- spinlock_t reg_lock;
- struct tm6000_core *core;
- struct snd_pcm_substream *substream;
-
- /* temporary data for buffer fill processing */
- unsigned buf_pos;
- unsigned period_pos;
-};
-
-struct tm6000_endpoint {
- struct usb_host_endpoint *endp;
- __u8 bInterfaceNumber;
- __u8 bAlternateSetting;
- unsigned maxsize;
-};
-
-#define TM6000_QUIRK_NO_USB_DELAY (1 << 0)
-
-struct tm6000_core {
- /* generic device properties */
- char name[30]; /* name (including minor) of the device */
- int model; /* index in the device_data struct */
- int devno; /* marks the number of this device */
- enum tm6000_devtype dev_type; /* type of device */
- unsigned char eedata[256]; /* Eeprom data */
- unsigned eedata_size; /* Size of the eeprom info */
-
- v4l2_std_id norm; /* Current norm */
- int width, height; /* Selected resolution */
-
- enum tm6000_core_state state;
-
- /* Device Capabilities*/
- struct tm6000_capabilities caps;
-
- /* Used to load alsa/dvb */
- struct work_struct request_module_wk;
-
- /* Tuner configuration */
- int tuner_type; /* type of the tuner */
- int tuner_addr; /* tuner address */
-
- struct tm6000_gpio gpio;
-
- char *ir_codes;
-
- __u8 radio;
-
- /* Demodulator configuration */
- int demod_addr; /* demodulator address */
-
- int audio_bitrate;
- /* i2c i/o */
- struct i2c_adapter i2c_adap;
- struct i2c_client i2c_client;
-
-
- /* extension */
- struct list_head devlist;
-
- /* video for linux */
- int users;
-
- /* various device info */
- struct tm6000_fh *resources; /* Points to fh that is streaming */
- bool is_res_read;
-
- struct video_device *vfd;
- struct video_device *radio_dev;
- struct tm6000_dmaqueue vidq;
- struct v4l2_device v4l2_dev;
-
- int input;
- struct tm6000_input vinput[3]; /* video input */
- struct tm6000_input rinput; /* radio input */
-
- int freq;
- unsigned int fourcc;
-
- enum tm6000_mode mode;
-
- int ctl_mute; /* audio */
- int ctl_volume;
- int amode;
-
- /* DVB-T support */
- struct tm6000_dvb *dvb;
-
- /* audio support */
- struct snd_tm6000_card *adev;
- struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */
- atomic_t stream_started; /* stream should be running if true */
-
- struct tm6000_IR *ir;
-
- /* locks */
- struct mutex lock;
- struct mutex usb_lock;
-
- /* usb transfer */
- struct usb_device *udev; /* the usb device */
-
- struct tm6000_endpoint bulk_in, bulk_out, isoc_in, isoc_out;
- struct tm6000_endpoint int_in, int_out;
-
- /* scaler!=0 if scaler is active*/
- int scaler;
-
- /* Isoc control struct */
- struct usb_isoc_ctl isoc_ctl;
-
- spinlock_t slock;
-
- unsigned long quirks;
-};
-
-enum tm6000_ops_type {
- TM6000_AUDIO = 0x10,
- TM6000_DVB = 0x20,
-};
-
-struct tm6000_ops {
- struct list_head next;
- char *name;
- enum tm6000_ops_type type;
- int (*init)(struct tm6000_core *);
- int (*fini)(struct tm6000_core *);
- int (*fillbuf)(struct tm6000_core *, char *buf, int size);
-};
-
-struct tm6000_fh {
- struct tm6000_core *dev;
- unsigned int radio;
-
- /* video capture */
- struct tm6000_fmt *fmt;
- unsigned int width, height;
- struct videobuf_queue vb_vidq;
-
- enum v4l2_buf_type type;
-};
-
-#define TM6000_STD (V4L2_STD_PAL|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc| \
- V4L2_STD_PAL_M|V4L2_STD_PAL_60|V4L2_STD_NTSC_M| \
- V4L2_STD_NTSC_M_JP|V4L2_STD_SECAM)
-
-/* In tm6000-cards.c */
-
-int tm6000_tuner_callback(void *ptr, int component, int command, int arg);
-int tm6000_xc5000_callback(void *ptr, int component, int command, int arg);
-int tm6000_cards_setup(struct tm6000_core *dev);
-void tm6000_flash_led(struct tm6000_core *dev, u8 state);
-
-/* In tm6000-core.c */
-
-int tm6000_read_write_usb(struct tm6000_core *dev, u8 reqtype, u8 req,
- u16 value, u16 index, u8 *buf, u16 len);
-int tm6000_get_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index);
-int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index);
-int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index);
-int tm6000_set_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index);
-int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value,
- u16 index, u16 mask);
-int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep);
-int tm6000_init(struct tm6000_core *dev);
-int tm6000_reset(struct tm6000_core *dev);
-
-int tm6000_init_analog_mode(struct tm6000_core *dev);
-int tm6000_init_digital_mode(struct tm6000_core *dev);
-int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate);
-int tm6000_set_audio_rinput(struct tm6000_core *dev);
-int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute);
-void tm6000_set_volume(struct tm6000_core *dev, int vol);
-
-int tm6000_v4l2_register(struct tm6000_core *dev);
-int tm6000_v4l2_unregister(struct tm6000_core *dev);
-int tm6000_v4l2_exit(void);
-void tm6000_set_fourcc_format(struct tm6000_core *dev);
-
-void tm6000_remove_from_devlist(struct tm6000_core *dev);
-void tm6000_add_into_devlist(struct tm6000_core *dev);
-int tm6000_register_extension(struct tm6000_ops *ops);
-void tm6000_unregister_extension(struct tm6000_ops *ops);
-void tm6000_init_extension(struct tm6000_core *dev);
-void tm6000_close_extension(struct tm6000_core *dev);
-int tm6000_call_fillbuf(struct tm6000_core *dev, enum tm6000_ops_type type,
- char *buf, int size);
-
-
-/* In tm6000-stds.c */
-void tm6000_get_std_res(struct tm6000_core *dev);
-int tm6000_set_standard(struct tm6000_core *dev);
-
-/* In tm6000-i2c.c */
-int tm6000_i2c_register(struct tm6000_core *dev);
-int tm6000_i2c_unregister(struct tm6000_core *dev);
-
-/* In tm6000-queue.c */
-
-int tm6000_v4l2_mmap(struct file *filp, struct vm_area_struct *vma);
-
-int tm6000_vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type i);
-int tm6000_vidioc_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type i);
-int tm6000_vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *rb);
-int tm6000_vidioc_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *b);
-int tm6000_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b);
-int tm6000_vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b);
-ssize_t tm6000_v4l2_read(struct file *filp, char __user * buf, size_t count,
- loff_t *f_pos);
-unsigned int tm6000_v4l2_poll(struct file *file,
- struct poll_table_struct *wait);
-int tm6000_queue_init(struct tm6000_core *dev);
-
-/* In tm6000-alsa.c */
-/*int tm6000_audio_init(struct tm6000_core *dev, int idx);*/
-
-/* In tm6000-input.c */
-int tm6000_ir_init(struct tm6000_core *dev);
-int tm6000_ir_fini(struct tm6000_core *dev);
-void tm6000_ir_wait(struct tm6000_core *dev, u8 state);
-int tm6000_ir_int_start(struct tm6000_core *dev);
-void tm6000_ir_int_stop(struct tm6000_core *dev);
-
-/* Debug stuff */
-
-extern int tm6000_debug;
-
-#define dprintk(dev, level, fmt, arg...) do {\
- if (tm6000_debug & level) \
- printk(KERN_INFO "(%lu) %s %s :"fmt, jiffies, \
- dev->name, __func__ , ##arg); } while (0)
-
-#define V4L2_DEBUG_REG 0x0004
-#define V4L2_DEBUG_I2C 0x0008
-#define V4L2_DEBUG_QUEUE 0x0010
-#define V4L2_DEBUG_ISOC 0x0020
-#define V4L2_DEBUG_RES_LOCK 0x0040 /* Resource locking */
-#define V4L2_DEBUG_OPEN 0x0080 /* video open/close debug */
-
-#define tm6000_err(fmt, arg...) do {\
- printk(KERN_ERR "tm6000 %s :"fmt, \
- __func__ , ##arg); } while (0)
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
deleted file mode 100644
index b5a819af2b8..00000000000
--- a/drivers/media/video/tuner-core.c
+++ /dev/null
@@ -1,1354 +0,0 @@
-/*
- * i2c tv tuner chip device driver
- * core core, i.e. kernel interfaces, registering and so on
- *
- * Copyright(c) by Ralph Metzler, Gerd Knorr, Gunther Mayer
- *
- * Copyright(c) 2005-2011 by Mauro Carvalho Chehab
- * - Added support for a separate Radio tuner
- * - Major rework and cleanups at the code
- *
- * This driver supports many devices and the idea is to let the driver
- * detect which device is present. So rather than listing all supported
- * devices here, we pretend to support a single, fake device type that will
- * handle both radio and analog TV tuning.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/i2c.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/videodev2.h>
-#include <media/tuner.h>
-#include <media/tuner-types.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include "mt20xx.h"
-#include "tda8290.h"
-#include "tea5761.h"
-#include "tea5767.h"
-#include "tuner-xc2028.h"
-#include "tuner-simple.h"
-#include "tda9887.h"
-#include "xc5000.h"
-#include "tda18271.h"
-#include "xc4000.h"
-
-#define UNSET (-1U)
-
-#define PREFIX (t->i2c->driver->driver.name)
-
-/*
- * Driver modprobe parameters
- */
-
-/* insmod options used at init time => read/only */
-static unsigned int addr;
-static unsigned int no_autodetect;
-static unsigned int show_i2c;
-
-module_param(addr, int, 0444);
-module_param(no_autodetect, int, 0444);
-module_param(show_i2c, int, 0444);
-
-/* insmod options used at runtime => read/write */
-static int tuner_debug;
-static unsigned int tv_range[2] = { 44, 958 };
-static unsigned int radio_range[2] = { 65, 108 };
-static char pal[] = "--";
-static char secam[] = "--";
-static char ntsc[] = "-";
-
-module_param_named(debug, tuner_debug, int, 0644);
-module_param_array(tv_range, int, NULL, 0644);
-module_param_array(radio_range, int, NULL, 0644);
-module_param_string(pal, pal, sizeof(pal), 0644);
-module_param_string(secam, secam, sizeof(secam), 0644);
-module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
-
-/*
- * Static vars
- */
-
-static LIST_HEAD(tuner_list);
-static const struct v4l2_subdev_ops tuner_ops;
-
-/*
- * Debug macros
- */
-
-#define tuner_warn(fmt, arg...) do { \
- printk(KERN_WARNING "%s %d-%04x: " fmt, PREFIX, \
- i2c_adapter_id(t->i2c->adapter), \
- t->i2c->addr, ##arg); \
- } while (0)
-
-#define tuner_info(fmt, arg...) do { \
- printk(KERN_INFO "%s %d-%04x: " fmt, PREFIX, \
- i2c_adapter_id(t->i2c->adapter), \
- t->i2c->addr, ##arg); \
- } while (0)
-
-#define tuner_err(fmt, arg...) do { \
- printk(KERN_ERR "%s %d-%04x: " fmt, PREFIX, \
- i2c_adapter_id(t->i2c->adapter), \
- t->i2c->addr, ##arg); \
- } while (0)
-
-#define tuner_dbg(fmt, arg...) do { \
- if (tuner_debug) \
- printk(KERN_DEBUG "%s %d-%04x: " fmt, PREFIX, \
- i2c_adapter_id(t->i2c->adapter), \
- t->i2c->addr, ##arg); \
- } while (0)
-
-/*
- * Internal struct used inside the driver
- */
-
-struct tuner {
- /* device */
- struct dvb_frontend fe;
- struct i2c_client *i2c;
- struct v4l2_subdev sd;
- struct list_head list;
-
- /* keep track of the current settings */
- v4l2_std_id std;
- unsigned int tv_freq;
- unsigned int radio_freq;
- unsigned int audmode;
-
- enum v4l2_tuner_type mode;
- unsigned int mode_mask; /* Combination of allowable modes */
-
- bool standby; /* Standby mode */
-
- unsigned int type; /* chip type id */
- unsigned int config;
- const char *name;
-};
-
-/*
- * Function prototypes
- */
-
-static void set_tv_freq(struct i2c_client *c, unsigned int freq);
-static void set_radio_freq(struct i2c_client *c, unsigned int freq);
-
-/*
- * tuner attach/detach logic
- */
-
-/* This macro allows us to probe dynamically, avoiding static links */
-#ifdef CONFIG_MEDIA_ATTACH
-#define tuner_symbol_probe(FUNCTION, ARGS...) ({ \
- int __r = -EINVAL; \
- typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
- if (__a) { \
- __r = (int) __a(ARGS); \
- symbol_put(FUNCTION); \
- } else { \
- printk(KERN_ERR "TUNER: Unable to find " \
- "symbol "#FUNCTION"()\n"); \
- } \
- __r; \
-})
-
-static void tuner_detach(struct dvb_frontend *fe)
-{
- if (fe->ops.tuner_ops.release) {
- fe->ops.tuner_ops.release(fe);
- symbol_put_addr(fe->ops.tuner_ops.release);
- }
- if (fe->ops.analog_ops.release) {
- fe->ops.analog_ops.release(fe);
- symbol_put_addr(fe->ops.analog_ops.release);
- }
-}
-#else
-#define tuner_symbol_probe(FUNCTION, ARGS...) ({ \
- FUNCTION(ARGS); \
-})
-
-static void tuner_detach(struct dvb_frontend *fe)
-{
- if (fe->ops.tuner_ops.release)
- fe->ops.tuner_ops.release(fe);
- if (fe->ops.analog_ops.release)
- fe->ops.analog_ops.release(fe);
-}
-#endif
-
-
-static inline struct tuner *to_tuner(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct tuner, sd);
-}
-
-/*
- * struct analog_demod_ops callbacks
- */
-
-static void fe_set_params(struct dvb_frontend *fe,
- struct analog_parameters *params)
-{
- struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops;
- struct tuner *t = fe->analog_demod_priv;
-
- if (NULL == fe_tuner_ops->set_analog_params) {
- tuner_warn("Tuner frontend module has no way to set freq\n");
- return;
- }
- fe_tuner_ops->set_analog_params(fe, params);
-}
-
-static void fe_standby(struct dvb_frontend *fe)
-{
- struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops;
-
- if (fe_tuner_ops->sleep)
- fe_tuner_ops->sleep(fe);
-}
-
-static int fe_has_signal(struct dvb_frontend *fe)
-{
- u16 strength = 0;
-
- if (fe->ops.tuner_ops.get_rf_strength)
- fe->ops.tuner_ops.get_rf_strength(fe, &strength);
-
- return strength;
-}
-
-static int fe_get_afc(struct dvb_frontend *fe)
-{
- s32 afc = 0;
-
- if (fe->ops.tuner_ops.get_afc)
- fe->ops.tuner_ops.get_afc(fe, &afc);
-
- return 0;
-}
-
-static int fe_set_config(struct dvb_frontend *fe, void *priv_cfg)
-{
- struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops;
- struct tuner *t = fe->analog_demod_priv;
-
- if (fe_tuner_ops->set_config)
- return fe_tuner_ops->set_config(fe, priv_cfg);
-
- tuner_warn("Tuner frontend module has no way to set config\n");
-
- return 0;
-}
-
-static void tuner_status(struct dvb_frontend *fe);
-
-static struct analog_demod_ops tuner_analog_ops = {
- .set_params = fe_set_params,
- .standby = fe_standby,
- .has_signal = fe_has_signal,
- .get_afc = fe_get_afc,
- .set_config = fe_set_config,
- .tuner_status = tuner_status
-};
-
-/*
- * Functions to select between radio and TV and tuner probe/remove functions
- */
-
-/**
- * set_type - Sets the tuner type for a given device
- *
- * @c: i2c_client descriptoy
- * @type: type of the tuner (e. g. tuner number)
- * @new_mode_mask: Indicates if tuner supports TV and/or Radio
- * @new_config: an optional parameter ranging from 0-255 used by
- a few tuners to adjust an internal parameter,
- like LNA mode
- * @tuner_callback: an optional function to be called when switching
- * to analog mode
- *
- * This function applys the tuner config to tuner specified
- * by tun_setup structure. It contains several per-tuner initialization "magic"
- */
-static void set_type(struct i2c_client *c, unsigned int type,
- unsigned int new_mode_mask, unsigned int new_config,
- int (*tuner_callback) (void *dev, int component, int cmd, int arg))
-{
- struct tuner *t = to_tuner(i2c_get_clientdata(c));
- struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
- struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
- unsigned char buffer[4];
- int tune_now = 1;
-
- if (type == UNSET || type == TUNER_ABSENT) {
- tuner_dbg("tuner 0x%02x: Tuner type absent\n", c->addr);
- return;
- }
-
- t->type = type;
- /* prevent invalid config values */
- t->config = new_config < 256 ? new_config : 0;
- if (tuner_callback != NULL) {
- tuner_dbg("defining GPIO callback\n");
- t->fe.callback = tuner_callback;
- }
-
- /* discard private data, in case set_type() was previously called */
- tuner_detach(&t->fe);
- t->fe.analog_demod_priv = NULL;
-
- switch (t->type) {
- case TUNER_MT2032:
- if (!dvb_attach(microtune_attach,
- &t->fe, t->i2c->adapter, t->i2c->addr))
- goto attach_failed;
- break;
- case TUNER_PHILIPS_TDA8290:
- {
- struct tda829x_config cfg = {
- .lna_cfg = t->config,
- };
- if (!dvb_attach(tda829x_attach, &t->fe, t->i2c->adapter,
- t->i2c->addr, &cfg))
- goto attach_failed;
- break;
- }
- case TUNER_TEA5767:
- if (!dvb_attach(tea5767_attach, &t->fe,
- t->i2c->adapter, t->i2c->addr))
- goto attach_failed;
- t->mode_mask = T_RADIO;
- break;
- case TUNER_TEA5761:
- if (!dvb_attach(tea5761_attach, &t->fe,
- t->i2c->adapter, t->i2c->addr))
- goto attach_failed;
- t->mode_mask = T_RADIO;
- break;
- case TUNER_PHILIPS_FMD1216ME_MK3:
- case TUNER_PHILIPS_FMD1216MEX_MK3:
- buffer[0] = 0x0b;
- buffer[1] = 0xdc;
- buffer[2] = 0x9c;
- buffer[3] = 0x60;
- i2c_master_send(c, buffer, 4);
- mdelay(1);
- buffer[2] = 0x86;
- buffer[3] = 0x54;
- i2c_master_send(c, buffer, 4);
- if (!dvb_attach(simple_tuner_attach, &t->fe,
- t->i2c->adapter, t->i2c->addr, t->type))
- goto attach_failed;
- break;
- case TUNER_PHILIPS_TD1316:
- buffer[0] = 0x0b;
- buffer[1] = 0xdc;
- buffer[2] = 0x86;
- buffer[3] = 0xa4;
- i2c_master_send(c, buffer, 4);
- if (!dvb_attach(simple_tuner_attach, &t->fe,
- t->i2c->adapter, t->i2c->addr, t->type))
- goto attach_failed;
- break;
- case TUNER_XC2028:
- {
- struct xc2028_config cfg = {
- .i2c_adap = t->i2c->adapter,
- .i2c_addr = t->i2c->addr,
- };
- if (!dvb_attach(xc2028_attach, &t->fe, &cfg))
- goto attach_failed;
- tune_now = 0;
- break;
- }
- case TUNER_TDA9887:
- if (!dvb_attach(tda9887_attach,
- &t->fe, t->i2c->adapter, t->i2c->addr))
- goto attach_failed;
- break;
- case TUNER_XC5000:
- {
- struct xc5000_config xc5000_cfg = {
- .i2c_address = t->i2c->addr,
- /* if_khz will be set at dvb_attach() */
- .if_khz = 0,
- };
-
- if (!dvb_attach(xc5000_attach,
- &t->fe, t->i2c->adapter, &xc5000_cfg))
- goto attach_failed;
- tune_now = 0;
- break;
- }
- case TUNER_XC5000C:
- {
- struct xc5000_config xc5000c_cfg = {
- .i2c_address = t->i2c->addr,
- /* if_khz will be set at dvb_attach() */
- .if_khz = 0,
- .chip_id = XC5000C,
- };
-
- if (!dvb_attach(xc5000_attach,
- &t->fe, t->i2c->adapter, &xc5000c_cfg))
- goto attach_failed;
- tune_now = 0;
- break;
- }
- case TUNER_NXP_TDA18271:
- {
- struct tda18271_config cfg = {
- .config = t->config,
- .small_i2c = TDA18271_03_BYTE_CHUNK_INIT,
- };
-
- if (!dvb_attach(tda18271_attach, &t->fe, t->i2c->addr,
- t->i2c->adapter, &cfg))
- goto attach_failed;
- tune_now = 0;
- break;
- }
- case TUNER_XC4000:
- {
- struct xc4000_config xc4000_cfg = {
- .i2c_address = t->i2c->addr,
- /* FIXME: the correct parameters will be set */
- /* only when the digital dvb_attach() occurs */
- .default_pm = 0,
- .dvb_amplitude = 0,
- .set_smoothedcvbs = 0,
- .if_khz = 0
- };
- if (!dvb_attach(xc4000_attach,
- &t->fe, t->i2c->adapter, &xc4000_cfg))
- goto attach_failed;
- tune_now = 0;
- break;
- }
- default:
- if (!dvb_attach(simple_tuner_attach, &t->fe,
- t->i2c->adapter, t->i2c->addr, t->type))
- goto attach_failed;
-
- break;
- }
-
- if ((NULL == analog_ops->set_params) &&
- (fe_tuner_ops->set_analog_params)) {
-
- t->name = fe_tuner_ops->info.name;
-
- t->fe.analog_demod_priv = t;
- memcpy(analog_ops, &tuner_analog_ops,
- sizeof(struct analog_demod_ops));
-
- } else {
- t->name = analog_ops->info.name;
- }
-
- tuner_dbg("type set to %s\n", t->name);
-
- t->mode_mask = new_mode_mask;
-
- /* Some tuners require more initialization setup before use,
- such as firmware download or device calibration.
- trying to set a frequency here will just fail
- FIXME: better to move set_freq to the tuner code. This is needed
- on analog tuners for PLL to properly work
- */
- if (tune_now) {
- if (V4L2_TUNER_RADIO == t->mode)
- set_radio_freq(c, t->radio_freq);
- else
- set_tv_freq(c, t->tv_freq);
- }
-
- tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
- c->adapter->name, c->driver->driver.name, c->addr << 1, type,
- t->mode_mask);
- return;
-
-attach_failed:
- tuner_dbg("Tuner attach for type = %d failed.\n", t->type);
- t->type = TUNER_ABSENT;
-
- return;
-}
-
-/**
- * tuner_s_type_addr - Sets the tuner type for a device
- *
- * @sd: subdev descriptor
- * @tun_setup: type to be associated to a given tuner i2c address
- *
- * This function applys the tuner config to tuner specified
- * by tun_setup structure.
- * If tuner I2C address is UNSET, then it will only set the device
- * if the tuner supports the mode specified in the call.
- * If the address is specified, the change will be applied only if
- * tuner I2C address matches.
- * The call can change the tuner number and the tuner mode.
- */
-static int tuner_s_type_addr(struct v4l2_subdev *sd,
- struct tuner_setup *tun_setup)
-{
- struct tuner *t = to_tuner(sd);
- struct i2c_client *c = v4l2_get_subdevdata(sd);
-
- tuner_dbg("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=0x%02x\n",
- tun_setup->type,
- tun_setup->addr,
- tun_setup->mode_mask,
- tun_setup->config);
-
- if ((t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) &&
- (t->mode_mask & tun_setup->mode_mask))) ||
- (tun_setup->addr == c->addr)) {
- set_type(c, tun_setup->type, tun_setup->mode_mask,
- tun_setup->config, tun_setup->tuner_callback);
- } else
- tuner_dbg("set addr discarded for type %i, mask %x. "
- "Asked to change tuner at addr 0x%02x, with mask %x\n",
- t->type, t->mode_mask,
- tun_setup->addr, tun_setup->mode_mask);
-
- return 0;
-}
-
-/**
- * tuner_s_config - Sets tuner configuration
- *
- * @sd: subdev descriptor
- * @cfg: tuner configuration
- *
- * Calls tuner set_config() private function to set some tuner-internal
- * parameters
- */
-static int tuner_s_config(struct v4l2_subdev *sd,
- const struct v4l2_priv_tun_config *cfg)
-{
- struct tuner *t = to_tuner(sd);
- struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
-
- if (t->type != cfg->tuner)
- return 0;
-
- if (analog_ops->set_config) {
- analog_ops->set_config(&t->fe, cfg->priv);
- return 0;
- }
-
- tuner_dbg("Tuner frontend module has no way to set config\n");
- return 0;
-}
-
-/**
- * tuner_lookup - Seek for tuner adapters
- *
- * @adap: i2c_adapter struct
- * @radio: pointer to be filled if the adapter is radio
- * @tv: pointer to be filled if the adapter is TV
- *
- * Search for existing radio and/or TV tuners on the given I2C adapter,
- * discarding demod-only adapters (tda9887).
- *
- * Note that when this function is called from tuner_probe you can be
- * certain no other devices will be added/deleted at the same time, I2C
- * core protects against that.
- */
-static void tuner_lookup(struct i2c_adapter *adap,
- struct tuner **radio, struct tuner **tv)
-{
- struct tuner *pos;
-
- *radio = NULL;
- *tv = NULL;
-
- list_for_each_entry(pos, &tuner_list, list) {
- int mode_mask;
-
- if (pos->i2c->adapter != adap ||
- strcmp(pos->i2c->driver->driver.name, "tuner"))
- continue;
-
- mode_mask = pos->mode_mask;
- if (*radio == NULL && mode_mask == T_RADIO)
- *radio = pos;
- /* Note: currently TDA9887 is the only demod-only
- device. If other devices appear then we need to
- make this test more general. */
- else if (*tv == NULL && pos->type != TUNER_TDA9887 &&
- (pos->mode_mask & T_ANALOG_TV))
- *tv = pos;
- }
-}
-
-/**
- *tuner_probe - Probes the existing tuners on an I2C bus
- *
- * @client: i2c_client descriptor
- * @id: not used
- *
- * This routine probes for tuners at the expected I2C addresses. On most
- * cases, if a device answers to a given I2C address, it assumes that the
- * device is a tuner. On a few cases, however, an additional logic is needed
- * to double check if the device is really a tuner, or to identify the tuner
- * type, like on tea5767/5761 devices.
- *
- * During client attach, set_type is called by adapter's attach_inform callback.
- * set_type must then be completed by tuner_probe.
- */
-static int tuner_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct tuner *t;
- struct tuner *radio;
- struct tuner *tv;
-
- t = kzalloc(sizeof(struct tuner), GFP_KERNEL);
- if (NULL == t)
- return -ENOMEM;
- v4l2_i2c_subdev_init(&t->sd, client, &tuner_ops);
- t->i2c = client;
- t->name = "(tuner unset)";
- t->type = UNSET;
- t->audmode = V4L2_TUNER_MODE_STEREO;
- t->standby = 1;
- t->radio_freq = 87.5 * 16000; /* Initial freq range */
- t->tv_freq = 400 * 16; /* Sets freq to VHF High - needed for some PLL's to properly start */
-
- if (show_i2c) {
- unsigned char buffer[16];
- int i, rc;
-
- memset(buffer, 0, sizeof(buffer));
- rc = i2c_master_recv(client, buffer, sizeof(buffer));
- tuner_info("I2C RECV = ");
- for (i = 0; i < rc; i++)
- printk(KERN_CONT "%02x ", buffer[i]);
- printk("\n");
- }
-
- /* autodetection code based on the i2c addr */
- if (!no_autodetect) {
- switch (client->addr) {
- case 0x10:
- if (tuner_symbol_probe(tea5761_autodetection,
- t->i2c->adapter,
- t->i2c->addr) >= 0) {
- t->type = TUNER_TEA5761;
- t->mode_mask = T_RADIO;
- tuner_lookup(t->i2c->adapter, &radio, &tv);
- if (tv)
- tv->mode_mask &= ~T_RADIO;
-
- goto register_client;
- }
- kfree(t);
- return -ENODEV;
- case 0x42:
- case 0x43:
- case 0x4a:
- case 0x4b:
- /* If chip is not tda8290, don't register.
- since it can be tda9887*/
- if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
- t->i2c->addr) >= 0) {
- tuner_dbg("tda829x detected\n");
- } else {
- /* Default is being tda9887 */
- t->type = TUNER_TDA9887;
- t->mode_mask = T_RADIO | T_ANALOG_TV;
- goto register_client;
- }
- break;
- case 0x60:
- if (tuner_symbol_probe(tea5767_autodetection,
- t->i2c->adapter, t->i2c->addr)
- >= 0) {
- t->type = TUNER_TEA5767;
- t->mode_mask = T_RADIO;
- /* Sets freq to FM range */
- tuner_lookup(t->i2c->adapter, &radio, &tv);
- if (tv)
- tv->mode_mask &= ~T_RADIO;
-
- goto register_client;
- }
- break;
- }
- }
-
- /* Initializes only the first TV tuner on this adapter. Why only the
- first? Because there are some devices (notably the ones with TI
- tuners) that have more than one i2c address for the *same* device.
- Experience shows that, except for just one case, the first
- address is the right one. The exception is a Russian tuner
- (ACORP_Y878F). So, the desired behavior is just to enable the
- first found TV tuner. */
- tuner_lookup(t->i2c->adapter, &radio, &tv);
- if (tv == NULL) {
- t->mode_mask = T_ANALOG_TV;
- if (radio == NULL)
- t->mode_mask |= T_RADIO;
- tuner_dbg("Setting mode_mask to 0x%02x\n", t->mode_mask);
- }
-
- /* Should be just before return */
-register_client:
- /* Sets a default mode */
- if (t->mode_mask & T_ANALOG_TV)
- t->mode = V4L2_TUNER_ANALOG_TV;
- else
- t->mode = V4L2_TUNER_RADIO;
- set_type(client, t->type, t->mode_mask, t->config, t->fe.callback);
- list_add_tail(&t->list, &tuner_list);
-
- tuner_info("Tuner %d found with type(s)%s%s.\n",
- t->type,
- t->mode_mask & T_RADIO ? " Radio" : "",
- t->mode_mask & T_ANALOG_TV ? " TV" : "");
- return 0;
-}
-
-/**
- * tuner_remove - detaches a tuner
- *
- * @client: i2c_client descriptor
- */
-
-static int tuner_remove(struct i2c_client *client)
-{
- struct tuner *t = to_tuner(i2c_get_clientdata(client));
-
- v4l2_device_unregister_subdev(&t->sd);
- tuner_detach(&t->fe);
- t->fe.analog_demod_priv = NULL;
-
- list_del(&t->list);
- kfree(t);
- return 0;
-}
-
-/*
- * Functions to switch between Radio and TV
- *
- * A few cards have a separate I2C tuner for radio. Those routines
- * take care of switching between TV/Radio mode, filtering only the
- * commands that apply to the Radio or TV tuner.
- */
-
-/**
- * check_mode - Verify if tuner supports the requested mode
- * @t: a pointer to the module's internal struct_tuner
- *
- * This function checks if the tuner is capable of tuning analog TV,
- * digital TV or radio, depending on what the caller wants. If the
- * tuner can't support that mode, it returns -EINVAL. Otherwise, it
- * returns 0.
- * This function is needed for boards that have a separate tuner for
- * radio (like devices with tea5767).
- * NOTE: mt20xx uses V4L2_TUNER_DIGITAL_TV and calls set_tv_freq to
- * select a TV frequency. So, t_mode = T_ANALOG_TV could actually
- * be used to represent a Digital TV too.
- */
-static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode)
-{
- int t_mode;
- if (mode == V4L2_TUNER_RADIO)
- t_mode = T_RADIO;
- else
- t_mode = T_ANALOG_TV;
-
- if ((t_mode & t->mode_mask) == 0)
- return -EINVAL;
-
- return 0;
-}
-
-/**
- * set_mode - Switch tuner to other mode.
- * @t: a pointer to the module's internal struct_tuner
- * @mode: enum v4l2_type (radio or TV)
- *
- * If tuner doesn't support the needed mode (radio or TV), prints a
- * debug message and returns -EINVAL, changing its state to standby.
- * Otherwise, changes the mode and returns 0.
- */
-static int set_mode(struct tuner *t, enum v4l2_tuner_type mode)
-{
- struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
-
- if (mode != t->mode) {
- if (check_mode(t, mode) == -EINVAL) {
- tuner_dbg("Tuner doesn't support mode %d. "
- "Putting tuner to sleep\n", mode);
- t->standby = true;
- if (analog_ops->standby)
- analog_ops->standby(&t->fe);
- return -EINVAL;
- }
- t->mode = mode;
- tuner_dbg("Changing to mode %d\n", mode);
- }
- return 0;
-}
-
-/**
- * set_freq - Set the tuner to the desired frequency.
- * @t: a pointer to the module's internal struct_tuner
- * @freq: frequency to set (0 means to use the current frequency)
- */
-static void set_freq(struct tuner *t, unsigned int freq)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
-
- if (t->mode == V4L2_TUNER_RADIO) {
- if (!freq)
- freq = t->radio_freq;
- set_radio_freq(client, freq);
- } else {
- if (!freq)
- freq = t->tv_freq;
- set_tv_freq(client, freq);
- }
-}
-
-/*
- * Functions that are specific for TV mode
- */
-
-/**
- * set_tv_freq - Set tuner frequency, freq in Units of 62.5 kHz = 1/16MHz
- *
- * @c: i2c_client descriptor
- * @freq: frequency
- */
-static void set_tv_freq(struct i2c_client *c, unsigned int freq)
-{
- struct tuner *t = to_tuner(i2c_get_clientdata(c));
- struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
-
- struct analog_parameters params = {
- .mode = t->mode,
- .audmode = t->audmode,
- .std = t->std
- };
-
- if (t->type == UNSET) {
- tuner_warn("tuner type not set\n");
- return;
- }
- if (NULL == analog_ops->set_params) {
- tuner_warn("Tuner has no way to set tv freq\n");
- return;
- }
- if (freq < tv_range[0] * 16 || freq > tv_range[1] * 16) {
- tuner_dbg("TV freq (%d.%02d) out of range (%d-%d)\n",
- freq / 16, freq % 16 * 100 / 16, tv_range[0],
- tv_range[1]);
- /* V4L2 spec: if the freq is not possible then the closest
- possible value should be selected */
- if (freq < tv_range[0] * 16)
- freq = tv_range[0] * 16;
- else
- freq = tv_range[1] * 16;
- }
- params.frequency = freq;
- tuner_dbg("tv freq set to %d.%02d\n",
- freq / 16, freq % 16 * 100 / 16);
- t->tv_freq = freq;
- t->standby = false;
-
- analog_ops->set_params(&t->fe, &params);
-}
-
-/**
- * tuner_fixup_std - force a given video standard variant
- *
- * @t: tuner internal struct
- * @std: TV standard
- *
- * A few devices or drivers have problem to detect some standard variations.
- * On other operational systems, the drivers generally have a per-country
- * code, and some logic to apply per-country hacks. V4L2 API doesn't provide
- * such hacks. Instead, it relies on a proper video standard selection from
- * the userspace application. However, as some apps are buggy, not allowing
- * to distinguish all video standard variations, a modprobe parameter can
- * be used to force a video standard match.
- */
-static v4l2_std_id tuner_fixup_std(struct tuner *t, v4l2_std_id std)
-{
- if (pal[0] != '-' && (std & V4L2_STD_PAL) == V4L2_STD_PAL) {
- switch (pal[0]) {
- case '6':
- return V4L2_STD_PAL_60;
- case 'b':
- case 'B':
- case 'g':
- case 'G':
- return V4L2_STD_PAL_BG;
- case 'i':
- case 'I':
- return V4L2_STD_PAL_I;
- case 'd':
- case 'D':
- case 'k':
- case 'K':
- return V4L2_STD_PAL_DK;
- case 'M':
- case 'm':
- return V4L2_STD_PAL_M;
- case 'N':
- case 'n':
- if (pal[1] == 'c' || pal[1] == 'C')
- return V4L2_STD_PAL_Nc;
- return V4L2_STD_PAL_N;
- default:
- tuner_warn("pal= argument not recognised\n");
- break;
- }
- }
- if (secam[0] != '-' && (std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
- switch (secam[0]) {
- case 'b':
- case 'B':
- case 'g':
- case 'G':
- case 'h':
- case 'H':
- return V4L2_STD_SECAM_B |
- V4L2_STD_SECAM_G |
- V4L2_STD_SECAM_H;
- case 'd':
- case 'D':
- case 'k':
- case 'K':
- return V4L2_STD_SECAM_DK;
- case 'l':
- case 'L':
- if ((secam[1] == 'C') || (secam[1] == 'c'))
- return V4L2_STD_SECAM_LC;
- return V4L2_STD_SECAM_L;
- default:
- tuner_warn("secam= argument not recognised\n");
- break;
- }
- }
-
- if (ntsc[0] != '-' && (std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
- switch (ntsc[0]) {
- case 'm':
- case 'M':
- return V4L2_STD_NTSC_M;
- case 'j':
- case 'J':
- return V4L2_STD_NTSC_M_JP;
- case 'k':
- case 'K':
- return V4L2_STD_NTSC_M_KR;
- default:
- tuner_info("ntsc= argument not recognised\n");
- break;
- }
- }
- return std;
-}
-
-/*
- * Functions that are specific for Radio mode
- */
-
-/**
- * set_radio_freq - Set tuner frequency, freq in Units of 62.5 Hz = 1/16kHz
- *
- * @c: i2c_client descriptor
- * @freq: frequency
- */
-static void set_radio_freq(struct i2c_client *c, unsigned int freq)
-{
- struct tuner *t = to_tuner(i2c_get_clientdata(c));
- struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
-
- struct analog_parameters params = {
- .mode = t->mode,
- .audmode = t->audmode,
- .std = t->std
- };
-
- if (t->type == UNSET) {
- tuner_warn("tuner type not set\n");
- return;
- }
- if (NULL == analog_ops->set_params) {
- tuner_warn("tuner has no way to set radio frequency\n");
- return;
- }
- if (freq < radio_range[0] * 16000 || freq > radio_range[1] * 16000) {
- tuner_dbg("radio freq (%d.%02d) out of range (%d-%d)\n",
- freq / 16000, freq % 16000 * 100 / 16000,
- radio_range[0], radio_range[1]);
- /* V4L2 spec: if the freq is not possible then the closest
- possible value should be selected */
- if (freq < radio_range[0] * 16000)
- freq = radio_range[0] * 16000;
- else
- freq = radio_range[1] * 16000;
- }
- params.frequency = freq;
- tuner_dbg("radio freq set to %d.%02d\n",
- freq / 16000, freq % 16000 * 100 / 16000);
- t->radio_freq = freq;
- t->standby = false;
-
- analog_ops->set_params(&t->fe, &params);
-}
-
-/*
- * Debug function for reporting tuner status to userspace
- */
-
-/**
- * tuner_status - Dumps the current tuner status at dmesg
- * @fe: pointer to struct dvb_frontend
- *
- * This callback is used only for driver debug purposes, answering to
- * VIDIOC_LOG_STATUS. No changes should happen on this call.
- */
-static void tuner_status(struct dvb_frontend *fe)
-{
- struct tuner *t = fe->analog_demod_priv;
- unsigned long freq, freq_fraction;
- struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops;
- struct analog_demod_ops *analog_ops = &fe->ops.analog_ops;
- const char *p;
-
- switch (t->mode) {
- case V4L2_TUNER_RADIO:
- p = "radio";
- break;
- case V4L2_TUNER_DIGITAL_TV: /* Used by mt20xx */
- p = "digital TV";
- break;
- case V4L2_TUNER_ANALOG_TV:
- default:
- p = "analog TV";
- break;
- }
- if (t->mode == V4L2_TUNER_RADIO) {
- freq = t->radio_freq / 16000;
- freq_fraction = (t->radio_freq % 16000) * 100 / 16000;
- } else {
- freq = t->tv_freq / 16;
- freq_fraction = (t->tv_freq % 16) * 100 / 16;
- }
- tuner_info("Tuner mode: %s%s\n", p,
- t->standby ? " on standby mode" : "");
- tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction);
- tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std);
- if (t->mode != V4L2_TUNER_RADIO)
- return;
- if (fe_tuner_ops->get_status) {
- u32 tuner_status;
-
- fe_tuner_ops->get_status(&t->fe, &tuner_status);
- if (tuner_status & TUNER_STATUS_LOCKED)
- tuner_info("Tuner is locked.\n");
- if (tuner_status & TUNER_STATUS_STEREO)
- tuner_info("Stereo: yes\n");
- }
- if (analog_ops->has_signal)
- tuner_info("Signal strength: %d\n",
- analog_ops->has_signal(fe));
-}
-
-/*
- * Function to splicitly change mode to radio. Probably not needed anymore
- */
-
-static int tuner_s_radio(struct v4l2_subdev *sd)
-{
- struct tuner *t = to_tuner(sd);
-
- if (set_mode(t, V4L2_TUNER_RADIO) == 0)
- set_freq(t, 0);
- return 0;
-}
-
-/*
- * Tuner callbacks to handle userspace ioctl's
- */
-
-/**
- * tuner_s_power - controls the power state of the tuner
- * @sd: pointer to struct v4l2_subdev
- * @on: a zero value puts the tuner to sleep, non-zero wakes it up
- */
-static int tuner_s_power(struct v4l2_subdev *sd, int on)
-{
- struct tuner *t = to_tuner(sd);
- struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
-
- if (on) {
- if (t->standby && set_mode(t, t->mode) == 0) {
- tuner_dbg("Waking up tuner\n");
- set_freq(t, 0);
- }
- return 0;
- }
-
- tuner_dbg("Putting tuner to sleep\n");
- t->standby = true;
- if (analog_ops->standby)
- analog_ops->standby(&t->fe);
- return 0;
-}
-
-static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct tuner *t = to_tuner(sd);
-
- if (set_mode(t, V4L2_TUNER_ANALOG_TV))
- return 0;
-
- t->std = tuner_fixup_std(t, std);
- if (t->std != std)
- tuner_dbg("Fixup standard %llx to %llx\n", std, t->std);
- set_freq(t, 0);
- return 0;
-}
-
-static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
-{
- struct tuner *t = to_tuner(sd);
-
- if (set_mode(t, f->type) == 0)
- set_freq(t, f->frequency);
- return 0;
-}
-
-/**
- * tuner_g_frequency - Get the tuned frequency for the tuner
- * @sd: pointer to struct v4l2_subdev
- * @f: pointer to struct v4l2_frequency
- *
- * At return, the structure f will be filled with tuner frequency
- * if the tuner matches the f->type.
- * Note: f->type should be initialized before calling it.
- * This is done by either video_ioctl2 or by the bridge driver.
- */
-static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
-{
- struct tuner *t = to_tuner(sd);
- struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
-
- if (check_mode(t, f->type) == -EINVAL)
- return 0;
- if (f->type == t->mode && fe_tuner_ops->get_frequency && !t->standby) {
- u32 abs_freq;
-
- fe_tuner_ops->get_frequency(&t->fe, &abs_freq);
- f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
- DIV_ROUND_CLOSEST(abs_freq * 2, 125) :
- DIV_ROUND_CLOSEST(abs_freq, 62500);
- } else {
- f->frequency = (V4L2_TUNER_RADIO == f->type) ?
- t->radio_freq : t->tv_freq;
- }
- return 0;
-}
-
-/**
- * tuner_g_tuner - Fill in tuner information
- * @sd: pointer to struct v4l2_subdev
- * @vt: pointer to struct v4l2_tuner
- *
- * At return, the structure vt will be filled with tuner information
- * if the tuner matches vt->type.
- * Note: vt->type should be initialized before calling it.
- * This is done by either video_ioctl2 or by the bridge driver.
- */
-static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct tuner *t = to_tuner(sd);
- struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
- struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
-
- if (check_mode(t, vt->type) == -EINVAL)
- return 0;
- if (vt->type == t->mode && analog_ops->get_afc)
- vt->afc = analog_ops->get_afc(&t->fe);
- if (analog_ops->has_signal)
- vt->signal = analog_ops->has_signal(&t->fe);
- if (vt->type != V4L2_TUNER_RADIO) {
- vt->capability |= V4L2_TUNER_CAP_NORM;
- vt->rangelow = tv_range[0] * 16;
- vt->rangehigh = tv_range[1] * 16;
- return 0;
- }
-
- /* radio mode */
- if (vt->type == t->mode) {
- vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
- if (fe_tuner_ops->get_status) {
- u32 tuner_status;
-
- fe_tuner_ops->get_status(&t->fe, &tuner_status);
- vt->rxsubchans =
- (tuner_status & TUNER_STATUS_STEREO) ?
- V4L2_TUNER_SUB_STEREO :
- V4L2_TUNER_SUB_MONO;
- }
- vt->audmode = t->audmode;
- }
- vt->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
- vt->rangelow = radio_range[0] * 16000;
- vt->rangehigh = radio_range[1] * 16000;
-
- return 0;
-}
-
-/**
- * tuner_s_tuner - Set the tuner's audio mode
- * @sd: pointer to struct v4l2_subdev
- * @vt: pointer to struct v4l2_tuner
- *
- * Sets the audio mode if the tuner matches vt->type.
- * Note: vt->type should be initialized before calling it.
- * This is done by either video_ioctl2 or by the bridge driver.
- */
-static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct tuner *t = to_tuner(sd);
-
- if (set_mode(t, vt->type))
- return 0;
-
- if (t->mode == V4L2_TUNER_RADIO)
- t->audmode = vt->audmode;
- set_freq(t, 0);
-
- return 0;
-}
-
-static int tuner_log_status(struct v4l2_subdev *sd)
-{
- struct tuner *t = to_tuner(sd);
- struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
-
- if (analog_ops->tuner_status)
- analog_ops->tuner_status(&t->fe);
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int tuner_suspend(struct device *dev)
-{
- struct i2c_client *c = to_i2c_client(dev);
- struct tuner *t = to_tuner(i2c_get_clientdata(c));
- struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
-
- tuner_dbg("suspend\n");
-
- if (!t->standby && analog_ops->standby)
- analog_ops->standby(&t->fe);
-
- return 0;
-}
-
-static int tuner_resume(struct device *dev)
-{
- struct i2c_client *c = to_i2c_client(dev);
- struct tuner *t = to_tuner(i2c_get_clientdata(c));
-
- tuner_dbg("resume\n");
-
- if (!t->standby)
- if (set_mode(t, t->mode) == 0)
- set_freq(t, 0);
-
- return 0;
-}
-#endif
-
-static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- /* TUNER_SET_CONFIG is still called by tuner-simple.c, so we have
- to handle it here.
- There must be a better way of doing this... */
- switch (cmd) {
- case TUNER_SET_CONFIG:
- return tuner_s_config(sd, arg);
- }
- return -ENOIOCTLCMD;
-}
-
-/*
- * Callback structs
- */
-
-static const struct v4l2_subdev_core_ops tuner_core_ops = {
- .log_status = tuner_log_status,
- .s_std = tuner_s_std,
- .s_power = tuner_s_power,
-};
-
-static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
- .s_radio = tuner_s_radio,
- .g_tuner = tuner_g_tuner,
- .s_tuner = tuner_s_tuner,
- .s_frequency = tuner_s_frequency,
- .g_frequency = tuner_g_frequency,
- .s_type_addr = tuner_s_type_addr,
- .s_config = tuner_s_config,
-};
-
-static const struct v4l2_subdev_ops tuner_ops = {
- .core = &tuner_core_ops,
- .tuner = &tuner_tuner_ops,
-};
-
-/*
- * I2C structs and module init functions
- */
-
-static const struct dev_pm_ops tuner_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(tuner_suspend, tuner_resume)
-};
-
-static const struct i2c_device_id tuner_id[] = {
- { "tuner", }, /* autodetect */
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tuner_id);
-
-static struct i2c_driver tuner_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "tuner",
- .pm = &tuner_pm_ops,
- },
- .probe = tuner_probe,
- .remove = tuner_remove,
- .command = tuner_command,
- .id_table = tuner_id,
-};
-
-module_i2c_driver(tuner_driver);
-
-MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
-MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
deleted file mode 100644
index 321b3153df8..00000000000
--- a/drivers/media/video/tvaudio.c
+++ /dev/null
@@ -1,2118 +0,0 @@
-/*
- * Driver for simple i2c audio chips.
- *
- * Copyright (c) 2000 Gerd Knorr
- * based on code by:
- * Eric Sandeen (eric_sandeen@bigfoot.com)
- * Steve VanDeBogart (vandebo@uclink.berkeley.edu)
- * Greg Alexander (galexand@acm.org)
- *
- * Copyright(c) 2005-2008 Mauro Carvalho Chehab
- * - Some cleanups, code fixes, etc
- * - Convert it to V4L2 API
- *
- * This code is placed under the terms of the GNU General Public License
- *
- * OPTIONS:
- * debug - set to 1 if you'd like to see debug messages
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-
-#include <media/tvaudio.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-
-#include <media/i2c-addr.h>
-
-/* ---------------------------------------------------------------------- */
-/* insmod args */
-
-static int debug; /* insmod parameter */
-module_param(debug, int, 0644);
-
-MODULE_DESCRIPTION("device driver for various i2c TV sound decoder / audiomux chips");
-MODULE_AUTHOR("Eric Sandeen, Steve VanDeBogart, Greg Alexander, Gerd Knorr");
-MODULE_LICENSE("GPL");
-
-#define UNSET (-1U)
-
-/* ---------------------------------------------------------------------- */
-/* our structs */
-
-#define MAXREGS 256
-
-struct CHIPSTATE;
-typedef int (*getvalue)(int);
-typedef int (*checkit)(struct CHIPSTATE*);
-typedef int (*initialize)(struct CHIPSTATE*);
-typedef int (*getrxsubchans)(struct CHIPSTATE *);
-typedef void (*setaudmode)(struct CHIPSTATE*, int mode);
-
-/* i2c command */
-typedef struct AUDIOCMD {
- int count; /* # of bytes to send */
- unsigned char bytes[MAXREGS+1]; /* addr, data, data, ... */
-} audiocmd;
-
-/* chip description */
-struct CHIPDESC {
- char *name; /* chip name */
- int addr_lo, addr_hi; /* i2c address range */
- int registers; /* # of registers */
-
- int *insmodopt;
- checkit checkit;
- initialize initialize;
- int flags;
-#define CHIP_HAS_VOLUME 1
-#define CHIP_HAS_BASSTREBLE 2
-#define CHIP_HAS_INPUTSEL 4
-#define CHIP_NEED_CHECKMODE 8
-
- /* various i2c command sequences */
- audiocmd init;
-
- /* which register has which value */
- int leftreg,rightreg,treblereg,bassreg;
-
- /* initialize with (defaults to 65535/65535/32768/32768 */
- int leftinit,rightinit,trebleinit,bassinit;
-
- /* functions to convert the values (v4l -> chip) */
- getvalue volfunc,treblefunc,bassfunc;
-
- /* get/set mode */
- getrxsubchans getrxsubchans;
- setaudmode setaudmode;
-
- /* input switch register + values for v4l inputs */
- int inputreg;
- int inputmap[4];
- int inputmute;
- int inputmask;
-};
-
-/* current state of the chip */
-struct CHIPSTATE {
- struct v4l2_subdev sd;
-
- /* chip-specific description - should point to
- an entry at CHIPDESC table */
- struct CHIPDESC *desc;
-
- /* shadow register set */
- audiocmd shadow;
-
- /* current settings */
- __u16 left, right, treble, bass, muted;
- int prevmode;
- int radio;
- int input;
-
- /* thread */
- struct task_struct *thread;
- struct timer_list wt;
- int audmode;
-};
-
-static inline struct CHIPSTATE *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct CHIPSTATE, sd);
-}
-
-
-/* ---------------------------------------------------------------------- */
-/* i2c I/O functions */
-
-static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
-{
- struct v4l2_subdev *sd = &chip->sd;
- struct i2c_client *c = v4l2_get_subdevdata(sd);
- unsigned char buffer[2];
-
- if (subaddr < 0) {
- v4l2_dbg(1, debug, sd, "chip_write: 0x%x\n", val);
- chip->shadow.bytes[1] = val;
- buffer[0] = val;
- if (1 != i2c_master_send(c, buffer, 1)) {
- v4l2_warn(sd, "I/O error (write 0x%x)\n", val);
- return -1;
- }
- } else {
- if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
- v4l2_info(sd,
- "Tried to access a non-existent register: %d\n",
- subaddr);
- return -EINVAL;
- }
-
- v4l2_dbg(1, debug, sd, "chip_write: reg%d=0x%x\n",
- subaddr, val);
- chip->shadow.bytes[subaddr+1] = val;
- buffer[0] = subaddr;
- buffer[1] = val;
- if (2 != i2c_master_send(c, buffer, 2)) {
- v4l2_warn(sd, "I/O error (write reg%d=0x%x)\n",
- subaddr, val);
- return -1;
- }
- }
- return 0;
-}
-
-static int chip_write_masked(struct CHIPSTATE *chip,
- int subaddr, int val, int mask)
-{
- struct v4l2_subdev *sd = &chip->sd;
-
- if (mask != 0) {
- if (subaddr < 0) {
- val = (chip->shadow.bytes[1] & ~mask) | (val & mask);
- } else {
- if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
- v4l2_info(sd,
- "Tried to access a non-existent register: %d\n",
- subaddr);
- return -EINVAL;
- }
-
- val = (chip->shadow.bytes[subaddr+1] & ~mask) | (val & mask);
- }
- }
- return chip_write(chip, subaddr, val);
-}
-
-static int chip_read(struct CHIPSTATE *chip)
-{
- struct v4l2_subdev *sd = &chip->sd;
- struct i2c_client *c = v4l2_get_subdevdata(sd);
- unsigned char buffer;
-
- if (1 != i2c_master_recv(c, &buffer, 1)) {
- v4l2_warn(sd, "I/O error (read)\n");
- return -1;
- }
- v4l2_dbg(1, debug, sd, "chip_read: 0x%x\n", buffer);
- return buffer;
-}
-
-static int chip_read2(struct CHIPSTATE *chip, int subaddr)
-{
- struct v4l2_subdev *sd = &chip->sd;
- struct i2c_client *c = v4l2_get_subdevdata(sd);
- unsigned char write[1];
- unsigned char read[1];
- struct i2c_msg msgs[2] = {
- { c->addr, 0, 1, write },
- { c->addr, I2C_M_RD, 1, read }
- };
-
- write[0] = subaddr;
-
- if (2 != i2c_transfer(c->adapter, msgs, 2)) {
- v4l2_warn(sd, "I/O error (read2)\n");
- return -1;
- }
- v4l2_dbg(1, debug, sd, "chip_read2: reg%d=0x%x\n",
- subaddr, read[0]);
- return read[0];
-}
-
-static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
-{
- struct v4l2_subdev *sd = &chip->sd;
- struct i2c_client *c = v4l2_get_subdevdata(sd);
- int i;
-
- if (0 == cmd->count)
- return 0;
-
- if (cmd->count + cmd->bytes[0] - 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
- v4l2_info(sd,
- "Tried to access a non-existent register range: %d to %d\n",
- cmd->bytes[0] + 1, cmd->bytes[0] + cmd->count - 1);
- return -EINVAL;
- }
-
- /* FIXME: it seems that the shadow bytes are wrong bellow !*/
-
- /* update our shadow register set; print bytes if (debug > 0) */
- v4l2_dbg(1, debug, sd, "chip_cmd(%s): reg=%d, data:",
- name, cmd->bytes[0]);
- for (i = 1; i < cmd->count; i++) {
- if (debug)
- printk(KERN_CONT " 0x%x", cmd->bytes[i]);
- chip->shadow.bytes[i+cmd->bytes[0]] = cmd->bytes[i];
- }
- if (debug)
- printk(KERN_CONT "\n");
-
- /* send data to the chip */
- if (cmd->count != i2c_master_send(c, cmd->bytes, cmd->count)) {
- v4l2_warn(sd, "I/O error (%s)\n", name);
- return -1;
- }
- return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-/* kernel thread for doing i2c stuff asyncronly
- * right now it is used only to check the audio mode (mono/stereo/whatever)
- * some time after switching to another TV channel, then turn on stereo
- * if available, ...
- */
-
-static void chip_thread_wake(unsigned long data)
-{
- struct CHIPSTATE *chip = (struct CHIPSTATE*)data;
- wake_up_process(chip->thread);
-}
-
-static int chip_thread(void *data)
-{
- struct CHIPSTATE *chip = data;
- struct CHIPDESC *desc = chip->desc;
- struct v4l2_subdev *sd = &chip->sd;
- int mode, selected;
-
- v4l2_dbg(1, debug, sd, "thread started\n");
- set_freezable();
- for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (!kthread_should_stop())
- schedule();
- set_current_state(TASK_RUNNING);
- try_to_freeze();
- if (kthread_should_stop())
- break;
- v4l2_dbg(1, debug, sd, "thread wakeup\n");
-
- /* don't do anything for radio */
- if (chip->radio)
- continue;
-
- /* have a look what's going on */
- mode = desc->getrxsubchans(chip);
- if (mode == chip->prevmode)
- continue;
-
- /* chip detected a new audio mode - set it */
- v4l2_dbg(1, debug, sd, "thread checkmode\n");
-
- chip->prevmode = mode;
-
- selected = V4L2_TUNER_MODE_MONO;
- switch (chip->audmode) {
- case V4L2_TUNER_MODE_MONO:
- if (mode & V4L2_TUNER_SUB_LANG1)
- selected = V4L2_TUNER_MODE_LANG1;
- break;
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1:
- if (mode & V4L2_TUNER_SUB_LANG1)
- selected = V4L2_TUNER_MODE_LANG1;
- else if (mode & V4L2_TUNER_SUB_STEREO)
- selected = V4L2_TUNER_MODE_STEREO;
- break;
- case V4L2_TUNER_MODE_LANG2:
- if (mode & V4L2_TUNER_SUB_LANG2)
- selected = V4L2_TUNER_MODE_LANG2;
- else if (mode & V4L2_TUNER_SUB_STEREO)
- selected = V4L2_TUNER_MODE_STEREO;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- if (mode & V4L2_TUNER_SUB_LANG2)
- selected = V4L2_TUNER_MODE_LANG1_LANG2;
- else if (mode & V4L2_TUNER_SUB_STEREO)
- selected = V4L2_TUNER_MODE_STEREO;
- }
- desc->setaudmode(chip, selected);
-
- /* schedule next check */
- mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000));
- }
-
- v4l2_dbg(1, debug, sd, "thread exiting\n");
- return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-/* audio chip descriptions - defines+functions for tda9840 */
-
-#define TDA9840_SW 0x00
-#define TDA9840_LVADJ 0x02
-#define TDA9840_STADJ 0x03
-#define TDA9840_TEST 0x04
-
-#define TDA9840_MONO 0x10
-#define TDA9840_STEREO 0x2a
-#define TDA9840_DUALA 0x12
-#define TDA9840_DUALB 0x1e
-#define TDA9840_DUALAB 0x1a
-#define TDA9840_DUALBA 0x16
-#define TDA9840_EXTERNAL 0x7a
-
-#define TDA9840_DS_DUAL 0x20 /* Dual sound identified */
-#define TDA9840_ST_STEREO 0x40 /* Stereo sound identified */
-#define TDA9840_PONRES 0x80 /* Power-on reset detected if = 1 */
-
-#define TDA9840_TEST_INT1SN 0x1 /* Integration time 0.5s when set */
-#define TDA9840_TEST_INTFU 0x02 /* Disables integrator function */
-
-static int tda9840_getrxsubchans(struct CHIPSTATE *chip)
-{
- struct v4l2_subdev *sd = &chip->sd;
- int val, mode;
-
- val = chip_read(chip);
- mode = V4L2_TUNER_SUB_MONO;
- if (val & TDA9840_DS_DUAL)
- mode |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- if (val & TDA9840_ST_STEREO)
- mode = V4L2_TUNER_SUB_STEREO;
-
- v4l2_dbg(1, debug, sd,
- "tda9840_getrxsubchans(): raw chip read: %d, return: %d\n",
- val, mode);
- return mode;
-}
-
-static void tda9840_setaudmode(struct CHIPSTATE *chip, int mode)
-{
- int update = 1;
- int t = chip->shadow.bytes[TDA9840_SW + 1] & ~0x7e;
-
- switch (mode) {
- case V4L2_TUNER_MODE_MONO:
- t |= TDA9840_MONO;
- break;
- case V4L2_TUNER_MODE_STEREO:
- t |= TDA9840_STEREO;
- break;
- case V4L2_TUNER_MODE_LANG1:
- t |= TDA9840_DUALA;
- break;
- case V4L2_TUNER_MODE_LANG2:
- t |= TDA9840_DUALB;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- t |= TDA9840_DUALAB;
- break;
- default:
- update = 0;
- }
-
- if (update)
- chip_write(chip, TDA9840_SW, t);
-}
-
-static int tda9840_checkit(struct CHIPSTATE *chip)
-{
- int rc;
- rc = chip_read(chip);
- /* lower 5 bits should be 0 */
- return ((rc & 0x1f) == 0) ? 1 : 0;
-}
-
-/* ---------------------------------------------------------------------- */
-/* audio chip descriptions - defines+functions for tda985x */
-
-/* subaddresses for TDA9855 */
-#define TDA9855_VR 0x00 /* Volume, right */
-#define TDA9855_VL 0x01 /* Volume, left */
-#define TDA9855_BA 0x02 /* Bass */
-#define TDA9855_TR 0x03 /* Treble */
-#define TDA9855_SW 0x04 /* Subwoofer - not connected on DTV2000 */
-
-/* subaddresses for TDA9850 */
-#define TDA9850_C4 0x04 /* Control 1 for TDA9850 */
-
-/* subaddesses for both chips */
-#define TDA985x_C5 0x05 /* Control 2 for TDA9850, Control 1 for TDA9855 */
-#define TDA985x_C6 0x06 /* Control 3 for TDA9850, Control 2 for TDA9855 */
-#define TDA985x_C7 0x07 /* Control 4 for TDA9850, Control 3 for TDA9855 */
-#define TDA985x_A1 0x08 /* Alignment 1 for both chips */
-#define TDA985x_A2 0x09 /* Alignment 2 for both chips */
-#define TDA985x_A3 0x0a /* Alignment 3 for both chips */
-
-/* Masks for bits in TDA9855 subaddresses */
-/* 0x00 - VR in TDA9855 */
-/* 0x01 - VL in TDA9855 */
-/* lower 7 bits control gain from -71dB (0x28) to 16dB (0x7f)
- * in 1dB steps - mute is 0x27 */
-
-
-/* 0x02 - BA in TDA9855 */
-/* lower 5 bits control bass gain from -12dB (0x06) to 16.5dB (0x19)
- * in .5dB steps - 0 is 0x0E */
-
-
-/* 0x03 - TR in TDA9855 */
-/* 4 bits << 1 control treble gain from -12dB (0x3) to 12dB (0xb)
- * in 3dB steps - 0 is 0x7 */
-
-/* Masks for bits in both chips' subaddresses */
-/* 0x04 - SW in TDA9855, C4/Control 1 in TDA9850 */
-/* Unique to TDA9855: */
-/* 4 bits << 2 control subwoofer/surround gain from -14db (0x1) to 14db (0xf)
- * in 3dB steps - mute is 0x0 */
-
-/* Unique to TDA9850: */
-/* lower 4 bits control stereo noise threshold, over which stereo turns off
- * set to values of 0x00 through 0x0f for Ster1 through Ster16 */
-
-
-/* 0x05 - C5 - Control 1 in TDA9855 , Control 2 in TDA9850*/
-/* Unique to TDA9855: */
-#define TDA9855_MUTE 1<<7 /* GMU, Mute at outputs */
-#define TDA9855_AVL 1<<6 /* AVL, Automatic Volume Level */
-#define TDA9855_LOUD 1<<5 /* Loudness, 1==off */
-#define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */
- /* Bits 0 to 3 select various combinations
- * of line in and line out, only the
- * interesting ones are defined */
-#define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */
-#define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */
-
-/* Unique to TDA9850: */
-/* lower 4 bits contol SAP noise threshold, over which SAP turns off
- * set to values of 0x00 through 0x0f for SAP1 through SAP16 */
-
-
-/* 0x06 - C6 - Control 2 in TDA9855, Control 3 in TDA9850 */
-/* Common to TDA9855 and TDA9850: */
-#define TDA985x_SAP 3<<6 /* Selects SAP output, mute if not received */
-#define TDA985x_MONOSAP 2<<6 /* Selects Mono on left, SAP on right */
-#define TDA985x_STEREO 1<<6 /* Selects Stereo ouput, mono if not received */
-#define TDA985x_MONO 0 /* Forces Mono output */
-#define TDA985x_LMU 1<<3 /* Mute (LOR/LOL for 9855, OUTL/OUTR for 9850) */
-
-/* Unique to TDA9855: */
-#define TDA9855_TZCM 1<<5 /* If set, don't mute till zero crossing */
-#define TDA9855_VZCM 1<<4 /* If set, don't change volume till zero crossing*/
-#define TDA9855_LINEAR 0 /* Linear Stereo */
-#define TDA9855_PSEUDO 1 /* Pseudo Stereo */
-#define TDA9855_SPAT_30 2 /* Spatial Stereo, 30% anti-phase crosstalk */
-#define TDA9855_SPAT_50 3 /* Spatial Stereo, 52% anti-phase crosstalk */
-#define TDA9855_E_MONO 7 /* Forced mono - mono select elseware, so useless*/
-
-/* 0x07 - C7 - Control 3 in TDA9855, Control 4 in TDA9850 */
-/* Common to both TDA9855 and TDA9850: */
-/* lower 4 bits control input gain from -3.5dB (0x0) to 4dB (0xF)
- * in .5dB steps - 0dB is 0x7 */
-
-/* 0x08, 0x09 - A1 and A2 (read/write) */
-/* Common to both TDA9855 and TDA9850: */
-/* lower 5 bites are wideband and spectral expander alignment
- * from 0x00 to 0x1f - nominal at 0x0f and 0x10 (read/write) */
-#define TDA985x_STP 1<<5 /* Stereo Pilot/detect (read-only) */
-#define TDA985x_SAPP 1<<6 /* SAP Pilot/detect (read-only) */
-#define TDA985x_STS 1<<7 /* Stereo trigger 1= <35mV 0= <30mV (write-only)*/
-
-/* 0x0a - A3 */
-/* Common to both TDA9855 and TDA9850: */
-/* lower 3 bits control timing current for alignment: -30% (0x0), -20% (0x1),
- * -10% (0x2), nominal (0x3), +10% (0x6), +20% (0x5), +30% (0x4) */
-#define TDA985x_ADJ 1<<7 /* Stereo adjust on/off (wideband and spectral */
-
-static int tda9855_volume(int val) { return val/0x2e8+0x27; }
-static int tda9855_bass(int val) { return val/0xccc+0x06; }
-static int tda9855_treble(int val) { return (val/0x1c71+0x3)<<1; }
-
-static int tda985x_getrxsubchans(struct CHIPSTATE *chip)
-{
- int mode, val;
-
- /* Add mono mode regardless of SAP and stereo */
- /* Allows forced mono */
- mode = V4L2_TUNER_SUB_MONO;
- val = chip_read(chip);
- if (val & TDA985x_STP)
- mode = V4L2_TUNER_SUB_STEREO;
- if (val & TDA985x_SAPP)
- mode |= V4L2_TUNER_SUB_SAP;
- return mode;
-}
-
-static void tda985x_setaudmode(struct CHIPSTATE *chip, int mode)
-{
- int update = 1;
- int c6 = chip->shadow.bytes[TDA985x_C6+1] & 0x3f;
-
- switch (mode) {
- case V4L2_TUNER_MODE_MONO:
- c6 |= TDA985x_MONO;
- break;
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1:
- c6 |= TDA985x_STEREO;
- break;
- case V4L2_TUNER_MODE_SAP:
- c6 |= TDA985x_SAP;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- c6 |= TDA985x_MONOSAP;
- break;
- default:
- update = 0;
- }
- if (update)
- chip_write(chip,TDA985x_C6,c6);
-}
-
-
-/* ---------------------------------------------------------------------- */
-/* audio chip descriptions - defines+functions for tda9873h */
-
-/* Subaddresses for TDA9873H */
-
-#define TDA9873_SW 0x00 /* Switching */
-#define TDA9873_AD 0x01 /* Adjust */
-#define TDA9873_PT 0x02 /* Port */
-
-/* Subaddress 0x00: Switching Data
- * B7..B0:
- *
- * B1, B0: Input source selection
- * 0, 0 internal
- * 1, 0 external stereo
- * 0, 1 external mono
- */
-#define TDA9873_INP_MASK 3
-#define TDA9873_INTERNAL 0
-#define TDA9873_EXT_STEREO 2
-#define TDA9873_EXT_MONO 1
-
-/* B3, B2: output signal select
- * B4 : transmission mode
- * 0, 0, 1 Mono
- * 1, 0, 0 Stereo
- * 1, 1, 1 Stereo (reversed channel)
- * 0, 0, 0 Dual AB
- * 0, 0, 1 Dual AA
- * 0, 1, 0 Dual BB
- * 0, 1, 1 Dual BA
- */
-
-#define TDA9873_TR_MASK (7 << 2)
-#define TDA9873_TR_MONO 4
-#define TDA9873_TR_STEREO 1 << 4
-#define TDA9873_TR_REVERSE ((1 << 3) | (1 << 2))
-#define TDA9873_TR_DUALA 1 << 2
-#define TDA9873_TR_DUALB 1 << 3
-#define TDA9873_TR_DUALAB 0
-
-/* output level controls
- * B5: output level switch (0 = reduced gain, 1 = normal gain)
- * B6: mute (1 = muted)
- * B7: auto-mute (1 = auto-mute enabled)
- */
-
-#define TDA9873_GAIN_NORMAL 1 << 5
-#define TDA9873_MUTE 1 << 6
-#define TDA9873_AUTOMUTE 1 << 7
-
-/* Subaddress 0x01: Adjust/standard */
-
-/* Lower 4 bits (C3..C0) control stereo adjustment on R channel (-0.6 - +0.7 dB)
- * Recommended value is +0 dB
- */
-
-#define TDA9873_STEREO_ADJ 0x06 /* 0dB gain */
-
-/* Bits C6..C4 control FM stantard
- * C6, C5, C4
- * 0, 0, 0 B/G (PAL FM)
- * 0, 0, 1 M
- * 0, 1, 0 D/K(1)
- * 0, 1, 1 D/K(2)
- * 1, 0, 0 D/K(3)
- * 1, 0, 1 I
- */
-#define TDA9873_BG 0
-#define TDA9873_M 1
-#define TDA9873_DK1 2
-#define TDA9873_DK2 3
-#define TDA9873_DK3 4
-#define TDA9873_I 5
-
-/* C7 controls identification response time (1=fast/0=normal)
- */
-#define TDA9873_IDR_NORM 0
-#define TDA9873_IDR_FAST 1 << 7
-
-
-/* Subaddress 0x02: Port data */
-
-/* E1, E0 free programmable ports P1/P2
- 0, 0 both ports low
- 0, 1 P1 high
- 1, 0 P2 high
- 1, 1 both ports high
-*/
-
-#define TDA9873_PORTS 3
-
-/* E2: test port */
-#define TDA9873_TST_PORT 1 << 2
-
-/* E5..E3 control mono output channel (together with transmission mode bit B4)
- *
- * E5 E4 E3 B4 OUTM
- * 0 0 0 0 mono
- * 0 0 1 0 DUAL B
- * 0 1 0 1 mono (from stereo decoder)
- */
-#define TDA9873_MOUT_MONO 0
-#define TDA9873_MOUT_FMONO 0
-#define TDA9873_MOUT_DUALA 0
-#define TDA9873_MOUT_DUALB 1 << 3
-#define TDA9873_MOUT_ST 1 << 4
-#define TDA9873_MOUT_EXTM ((1 << 4) | (1 << 3))
-#define TDA9873_MOUT_EXTL 1 << 5
-#define TDA9873_MOUT_EXTR ((1 << 5) | (1 << 3))
-#define TDA9873_MOUT_EXTLR ((1 << 5) | (1 << 4))
-#define TDA9873_MOUT_MUTE ((1 << 5) | (1 << 4) | (1 << 3))
-
-/* Status bits: (chip read) */
-#define TDA9873_PONR 0 /* Power-on reset detected if = 1 */
-#define TDA9873_STEREO 2 /* Stereo sound is identified */
-#define TDA9873_DUAL 4 /* Dual sound is identified */
-
-static int tda9873_getrxsubchans(struct CHIPSTATE *chip)
-{
- struct v4l2_subdev *sd = &chip->sd;
- int val,mode;
-
- val = chip_read(chip);
- mode = V4L2_TUNER_SUB_MONO;
- if (val & TDA9873_STEREO)
- mode = V4L2_TUNER_SUB_STEREO;
- if (val & TDA9873_DUAL)
- mode |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- v4l2_dbg(1, debug, sd,
- "tda9873_getrxsubchans(): raw chip read: %d, return: %d\n",
- val, mode);
- return mode;
-}
-
-static void tda9873_setaudmode(struct CHIPSTATE *chip, int mode)
-{
- struct v4l2_subdev *sd = &chip->sd;
- int sw_data = chip->shadow.bytes[TDA9873_SW+1] & ~ TDA9873_TR_MASK;
- /* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */
-
- if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) {
- v4l2_dbg(1, debug, sd,
- "tda9873_setaudmode(): external input\n");
- return;
- }
-
- v4l2_dbg(1, debug, sd,
- "tda9873_setaudmode(): chip->shadow.bytes[%d] = %d\n",
- TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]);
- v4l2_dbg(1, debug, sd, "tda9873_setaudmode(): sw_data = %d\n",
- sw_data);
-
- switch (mode) {
- case V4L2_TUNER_MODE_MONO:
- sw_data |= TDA9873_TR_MONO;
- break;
- case V4L2_TUNER_MODE_STEREO:
- sw_data |= TDA9873_TR_STEREO;
- break;
- case V4L2_TUNER_MODE_LANG1:
- sw_data |= TDA9873_TR_DUALA;
- break;
- case V4L2_TUNER_MODE_LANG2:
- sw_data |= TDA9873_TR_DUALB;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- sw_data |= TDA9873_TR_DUALAB;
- break;
- default:
- return;
- }
-
- chip_write(chip, TDA9873_SW, sw_data);
- v4l2_dbg(1, debug, sd,
- "tda9873_setaudmode(): req. mode %d; chip_write: %d\n",
- mode, sw_data);
-}
-
-static int tda9873_checkit(struct CHIPSTATE *chip)
-{
- int rc;
-
- if (-1 == (rc = chip_read2(chip,254)))
- return 0;
- return (rc & ~0x1f) == 0x80;
-}
-
-
-/* ---------------------------------------------------------------------- */
-/* audio chip description - defines+functions for tda9874h and tda9874a */
-/* Dariusz Kowalewski <darekk@automex.pl> */
-
-/* Subaddresses for TDA9874H and TDA9874A (slave rx) */
-#define TDA9874A_AGCGR 0x00 /* AGC gain */
-#define TDA9874A_GCONR 0x01 /* general config */
-#define TDA9874A_MSR 0x02 /* monitor select */
-#define TDA9874A_C1FRA 0x03 /* carrier 1 freq. */
-#define TDA9874A_C1FRB 0x04 /* carrier 1 freq. */
-#define TDA9874A_C1FRC 0x05 /* carrier 1 freq. */
-#define TDA9874A_C2FRA 0x06 /* carrier 2 freq. */
-#define TDA9874A_C2FRB 0x07 /* carrier 2 freq. */
-#define TDA9874A_C2FRC 0x08 /* carrier 2 freq. */
-#define TDA9874A_DCR 0x09 /* demodulator config */
-#define TDA9874A_FMER 0x0a /* FM de-emphasis */
-#define TDA9874A_FMMR 0x0b /* FM dematrix */
-#define TDA9874A_C1OLAR 0x0c /* ch.1 output level adj. */
-#define TDA9874A_C2OLAR 0x0d /* ch.2 output level adj. */
-#define TDA9874A_NCONR 0x0e /* NICAM config */
-#define TDA9874A_NOLAR 0x0f /* NICAM output level adj. */
-#define TDA9874A_NLELR 0x10 /* NICAM lower error limit */
-#define TDA9874A_NUELR 0x11 /* NICAM upper error limit */
-#define TDA9874A_AMCONR 0x12 /* audio mute control */
-#define TDA9874A_SDACOSR 0x13 /* stereo DAC output select */
-#define TDA9874A_AOSR 0x14 /* analog output select */
-#define TDA9874A_DAICONR 0x15 /* digital audio interface config */
-#define TDA9874A_I2SOSR 0x16 /* I2S-bus output select */
-#define TDA9874A_I2SOLAR 0x17 /* I2S-bus output level adj. */
-#define TDA9874A_MDACOSR 0x18 /* mono DAC output select (tda9874a) */
-#define TDA9874A_ESP 0xFF /* easy standard progr. (tda9874a) */
-
-/* Subaddresses for TDA9874H and TDA9874A (slave tx) */
-#define TDA9874A_DSR 0x00 /* device status */
-#define TDA9874A_NSR 0x01 /* NICAM status */
-#define TDA9874A_NECR 0x02 /* NICAM error count */
-#define TDA9874A_DR1 0x03 /* add. data LSB */
-#define TDA9874A_DR2 0x04 /* add. data MSB */
-#define TDA9874A_LLRA 0x05 /* monitor level read-out LSB */
-#define TDA9874A_LLRB 0x06 /* monitor level read-out MSB */
-#define TDA9874A_SIFLR 0x07 /* SIF level */
-#define TDA9874A_TR2 252 /* test reg. 2 */
-#define TDA9874A_TR1 253 /* test reg. 1 */
-#define TDA9874A_DIC 254 /* device id. code */
-#define TDA9874A_SIC 255 /* software id. code */
-
-
-static int tda9874a_mode = 1; /* 0: A2, 1: NICAM */
-static int tda9874a_GCONR = 0xc0; /* default config. input pin: SIFSEL=0 */
-static int tda9874a_NCONR = 0x01; /* default NICAM config.: AMSEL=0,AMUTE=1 */
-static int tda9874a_ESP = 0x07; /* default standard: NICAM D/K */
-static int tda9874a_dic = -1; /* device id. code */
-
-/* insmod options for tda9874a */
-static unsigned int tda9874a_SIF = UNSET;
-static unsigned int tda9874a_AMSEL = UNSET;
-static unsigned int tda9874a_STD = UNSET;
-module_param(tda9874a_SIF, int, 0444);
-module_param(tda9874a_AMSEL, int, 0444);
-module_param(tda9874a_STD, int, 0444);
-
-/*
- * initialization table for tda9874 decoder:
- * - carrier 1 freq. registers (3 bytes)
- * - carrier 2 freq. registers (3 bytes)
- * - demudulator config register
- * - FM de-emphasis register (slow identification mode)
- * Note: frequency registers must be written in single i2c transfer.
- */
-static struct tda9874a_MODES {
- char *name;
- audiocmd cmd;
-} tda9874a_modelist[9] = {
- { "A2, B/G", /* default */
- { 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x77,0xA0,0x00, 0x00,0x00 }} },
- { "A2, M (Korea)",
- { 9, { TDA9874A_C1FRA, 0x5D,0xC0,0x00, 0x62,0x6A,0xAA, 0x20,0x22 }} },
- { "A2, D/K (1)",
- { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x82,0x60,0x00, 0x00,0x00 }} },
- { "A2, D/K (2)",
- { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x8C,0x75,0x55, 0x00,0x00 }} },
- { "A2, D/K (3)",
- { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x77,0xA0,0x00, 0x00,0x00 }} },
- { "NICAM, I",
- { 9, { TDA9874A_C1FRA, 0x7D,0x00,0x00, 0x88,0x8A,0xAA, 0x08,0x33 }} },
- { "NICAM, B/G",
- { 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x79,0xEA,0xAA, 0x08,0x33 }} },
- { "NICAM, D/K",
- { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x08,0x33 }} },
- { "NICAM, L",
- { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x09,0x33 }} }
-};
-
-static int tda9874a_setup(struct CHIPSTATE *chip)
-{
- struct v4l2_subdev *sd = &chip->sd;
-
- chip_write(chip, TDA9874A_AGCGR, 0x00); /* 0 dB */
- chip_write(chip, TDA9874A_GCONR, tda9874a_GCONR);
- chip_write(chip, TDA9874A_MSR, (tda9874a_mode) ? 0x03:0x02);
- if(tda9874a_dic == 0x11) {
- chip_write(chip, TDA9874A_FMMR, 0x80);
- } else { /* dic == 0x07 */
- chip_cmd(chip,"tda9874_modelist",&tda9874a_modelist[tda9874a_STD].cmd);
- chip_write(chip, TDA9874A_FMMR, 0x00);
- }
- chip_write(chip, TDA9874A_C1OLAR, 0x00); /* 0 dB */
- chip_write(chip, TDA9874A_C2OLAR, 0x00); /* 0 dB */
- chip_write(chip, TDA9874A_NCONR, tda9874a_NCONR);
- chip_write(chip, TDA9874A_NOLAR, 0x00); /* 0 dB */
- /* Note: If signal quality is poor you may want to change NICAM */
- /* error limit registers (NLELR and NUELR) to some greater values. */
- /* Then the sound would remain stereo, but won't be so clear. */
- chip_write(chip, TDA9874A_NLELR, 0x14); /* default */
- chip_write(chip, TDA9874A_NUELR, 0x50); /* default */
-
- if(tda9874a_dic == 0x11) {
- chip_write(chip, TDA9874A_AMCONR, 0xf9);
- chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80);
- chip_write(chip, TDA9874A_AOSR, 0x80);
- chip_write(chip, TDA9874A_MDACOSR, (tda9874a_mode) ? 0x82:0x80);
- chip_write(chip, TDA9874A_ESP, tda9874a_ESP);
- } else { /* dic == 0x07 */
- chip_write(chip, TDA9874A_AMCONR, 0xfb);
- chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80);
- chip_write(chip, TDA9874A_AOSR, 0x00); /* or 0x10 */
- }
- v4l2_dbg(1, debug, sd, "tda9874a_setup(): %s [0x%02X].\n",
- tda9874a_modelist[tda9874a_STD].name,tda9874a_STD);
- return 1;
-}
-
-static int tda9874a_getrxsubchans(struct CHIPSTATE *chip)
-{
- struct v4l2_subdev *sd = &chip->sd;
- int dsr,nsr,mode;
- int necr; /* just for debugging */
-
- mode = V4L2_TUNER_SUB_MONO;
-
- if(-1 == (dsr = chip_read2(chip,TDA9874A_DSR)))
- return mode;
- if(-1 == (nsr = chip_read2(chip,TDA9874A_NSR)))
- return mode;
- if(-1 == (necr = chip_read2(chip,TDA9874A_NECR)))
- return mode;
-
- /* need to store dsr/nsr somewhere */
- chip->shadow.bytes[MAXREGS-2] = dsr;
- chip->shadow.bytes[MAXREGS-1] = nsr;
-
- if(tda9874a_mode) {
- /* Note: DSR.RSSF and DSR.AMSTAT bits are also checked.
- * If NICAM auto-muting is enabled, DSR.AMSTAT=1 indicates
- * that sound has (temporarily) switched from NICAM to
- * mono FM (or AM) on 1st sound carrier due to high NICAM bit
- * error count. So in fact there is no stereo in this case :-(
- * But changing the mode to V4L2_TUNER_MODE_MONO would switch
- * external 4052 multiplexer in audio_hook().
- */
- if(nsr & 0x02) /* NSR.S/MB=1 */
- mode = V4L2_TUNER_SUB_STEREO;
- if(nsr & 0x01) /* NSR.D/SB=1 */
- mode |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- } else {
- if(dsr & 0x02) /* DSR.IDSTE=1 */
- mode = V4L2_TUNER_SUB_STEREO;
- if(dsr & 0x04) /* DSR.IDDUA=1 */
- mode |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- }
-
- v4l2_dbg(1, debug, sd,
- "tda9874a_getrxsubchans(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n",
- dsr, nsr, necr, mode);
- return mode;
-}
-
-static void tda9874a_setaudmode(struct CHIPSTATE *chip, int mode)
-{
- struct v4l2_subdev *sd = &chip->sd;
-
- /* Disable/enable NICAM auto-muting (based on DSR.RSSF status bit). */
- /* If auto-muting is disabled, we can hear a signal of degrading quality. */
- if (tda9874a_mode) {
- if(chip->shadow.bytes[MAXREGS-2] & 0x20) /* DSR.RSSF=1 */
- tda9874a_NCONR &= 0xfe; /* enable */
- else
- tda9874a_NCONR |= 0x01; /* disable */
- chip_write(chip, TDA9874A_NCONR, tda9874a_NCONR);
- }
-
- /* Note: TDA9874A supports automatic FM dematrixing (FMMR register)
- * and has auto-select function for audio output (AOSR register).
- * Old TDA9874H doesn't support these features.
- * TDA9874A also has additional mono output pin (OUTM), which
- * on same (all?) tv-cards is not used, anyway (as well as MONOIN).
- */
- if(tda9874a_dic == 0x11) {
- int aosr = 0x80;
- int mdacosr = (tda9874a_mode) ? 0x82:0x80;
-
- switch(mode) {
- case V4L2_TUNER_MODE_MONO:
- case V4L2_TUNER_MODE_STEREO:
- break;
- case V4L2_TUNER_MODE_LANG1:
- aosr = 0x80; /* auto-select, dual A/A */
- mdacosr = (tda9874a_mode) ? 0x82:0x80;
- break;
- case V4L2_TUNER_MODE_LANG2:
- aosr = 0xa0; /* auto-select, dual B/B */
- mdacosr = (tda9874a_mode) ? 0x83:0x81;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- aosr = 0x00; /* always route L to L and R to R */
- mdacosr = (tda9874a_mode) ? 0x82:0x80;
- break;
- default:
- return;
- }
- chip_write(chip, TDA9874A_AOSR, aosr);
- chip_write(chip, TDA9874A_MDACOSR, mdacosr);
-
- v4l2_dbg(1, debug, sd,
- "tda9874a_setaudmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",
- mode, aosr, mdacosr);
-
- } else { /* dic == 0x07 */
- int fmmr,aosr;
-
- switch(mode) {
- case V4L2_TUNER_MODE_MONO:
- fmmr = 0x00; /* mono */
- aosr = 0x10; /* A/A */
- break;
- case V4L2_TUNER_MODE_STEREO:
- if(tda9874a_mode) {
- fmmr = 0x00;
- aosr = 0x00; /* handled by NICAM auto-mute */
- } else {
- fmmr = (tda9874a_ESP == 1) ? 0x05 : 0x04; /* stereo */
- aosr = 0x00;
- }
- break;
- case V4L2_TUNER_MODE_LANG1:
- fmmr = 0x02; /* dual */
- aosr = 0x10; /* dual A/A */
- break;
- case V4L2_TUNER_MODE_LANG2:
- fmmr = 0x02; /* dual */
- aosr = 0x20; /* dual B/B */
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- fmmr = 0x02; /* dual */
- aosr = 0x00; /* dual A/B */
- break;
- default:
- return;
- }
- chip_write(chip, TDA9874A_FMMR, fmmr);
- chip_write(chip, TDA9874A_AOSR, aosr);
-
- v4l2_dbg(1, debug, sd,
- "tda9874a_setaudmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n",
- mode, fmmr, aosr);
- }
-}
-
-static int tda9874a_checkit(struct CHIPSTATE *chip)
-{
- struct v4l2_subdev *sd = &chip->sd;
- int dic,sic; /* device id. and software id. codes */
-
- if(-1 == (dic = chip_read2(chip,TDA9874A_DIC)))
- return 0;
- if(-1 == (sic = chip_read2(chip,TDA9874A_SIC)))
- return 0;
-
- v4l2_dbg(1, debug, sd, "tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
-
- if((dic == 0x11)||(dic == 0x07)) {
- v4l2_info(sd, "found tda9874%s.\n", (dic == 0x11) ? "a" : "h");
- tda9874a_dic = dic; /* remember device id. */
- return 1;
- }
- return 0; /* not found */
-}
-
-static int tda9874a_initialize(struct CHIPSTATE *chip)
-{
- if (tda9874a_SIF > 2)
- tda9874a_SIF = 1;
- if (tda9874a_STD >= ARRAY_SIZE(tda9874a_modelist))
- tda9874a_STD = 0;
- if(tda9874a_AMSEL > 1)
- tda9874a_AMSEL = 0;
-
- if(tda9874a_SIF == 1)
- tda9874a_GCONR = 0xc0; /* sound IF input 1 */
- else
- tda9874a_GCONR = 0xc1; /* sound IF input 2 */
-
- tda9874a_ESP = tda9874a_STD;
- tda9874a_mode = (tda9874a_STD < 5) ? 0 : 1;
-
- if(tda9874a_AMSEL == 0)
- tda9874a_NCONR = 0x01; /* auto-mute: analog mono input */
- else
- tda9874a_NCONR = 0x05; /* auto-mute: 1st carrier FM or AM */
-
- tda9874a_setup(chip);
- return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-/* audio chip description - defines+functions for tda9875 */
-/* The TDA9875 is made by Philips Semiconductor
- * http://www.semiconductors.philips.com
- * TDA9875: I2C-bus controlled DSP audio processor, FM demodulator
- *
- */
-
-/* subaddresses for TDA9875 */
-#define TDA9875_MUT 0x12 /*General mute (value --> 0b11001100*/
-#define TDA9875_CFG 0x01 /* Config register (value --> 0b00000000 */
-#define TDA9875_DACOS 0x13 /*DAC i/o select (ADC) 0b0000100*/
-#define TDA9875_LOSR 0x16 /*Line output select regirter 0b0100 0001*/
-
-#define TDA9875_CH1V 0x0c /*Channel 1 volume (mute)*/
-#define TDA9875_CH2V 0x0d /*Channel 2 volume (mute)*/
-#define TDA9875_SC1 0x14 /*SCART 1 in (mono)*/
-#define TDA9875_SC2 0x15 /*SCART 2 in (mono)*/
-
-#define TDA9875_ADCIS 0x17 /*ADC input select (mono) 0b0110 000*/
-#define TDA9875_AER 0x19 /*Audio effect (AVL+Pseudo) 0b0000 0110*/
-#define TDA9875_MCS 0x18 /*Main channel select (DAC) 0b0000100*/
-#define TDA9875_MVL 0x1a /* Main volume gauche */
-#define TDA9875_MVR 0x1b /* Main volume droite */
-#define TDA9875_MBA 0x1d /* Main Basse */
-#define TDA9875_MTR 0x1e /* Main treble */
-#define TDA9875_ACS 0x1f /* Auxiliary channel select (FM) 0b0000000*/
-#define TDA9875_AVL 0x20 /* Auxiliary volume gauche */
-#define TDA9875_AVR 0x21 /* Auxiliary volume droite */
-#define TDA9875_ABA 0x22 /* Auxiliary Basse */
-#define TDA9875_ATR 0x23 /* Auxiliary treble */
-
-#define TDA9875_MSR 0x02 /* Monitor select register */
-#define TDA9875_C1MSB 0x03 /* Carrier 1 (FM) frequency register MSB */
-#define TDA9875_C1MIB 0x04 /* Carrier 1 (FM) frequency register (16-8]b */
-#define TDA9875_C1LSB 0x05 /* Carrier 1 (FM) frequency register LSB */
-#define TDA9875_C2MSB 0x06 /* Carrier 2 (nicam) frequency register MSB */
-#define TDA9875_C2MIB 0x07 /* Carrier 2 (nicam) frequency register (16-8]b */
-#define TDA9875_C2LSB 0x08 /* Carrier 2 (nicam) frequency register LSB */
-#define TDA9875_DCR 0x09 /* Demodulateur configuration regirter*/
-#define TDA9875_DEEM 0x0a /* FM de-emphasis regirter*/
-#define TDA9875_FMAT 0x0b /* FM Matrix regirter*/
-
-/* values */
-#define TDA9875_MUTE_ON 0xff /* general mute */
-#define TDA9875_MUTE_OFF 0xcc /* general no mute */
-
-static int tda9875_initialize(struct CHIPSTATE *chip)
-{
- chip_write(chip, TDA9875_CFG, 0xd0); /*reg de config 0 (reset)*/
- chip_write(chip, TDA9875_MSR, 0x03); /* Monitor 0b00000XXX*/
- chip_write(chip, TDA9875_C1MSB, 0x00); /*Car1(FM) MSB XMHz*/
- chip_write(chip, TDA9875_C1MIB, 0x00); /*Car1(FM) MIB XMHz*/
- chip_write(chip, TDA9875_C1LSB, 0x00); /*Car1(FM) LSB XMHz*/
- chip_write(chip, TDA9875_C2MSB, 0x00); /*Car2(NICAM) MSB XMHz*/
- chip_write(chip, TDA9875_C2MIB, 0x00); /*Car2(NICAM) MIB XMHz*/
- chip_write(chip, TDA9875_C2LSB, 0x00); /*Car2(NICAM) LSB XMHz*/
- chip_write(chip, TDA9875_DCR, 0x00); /*Demod config 0x00*/
- chip_write(chip, TDA9875_DEEM, 0x44); /*DE-Emph 0b0100 0100*/
- chip_write(chip, TDA9875_FMAT, 0x00); /*FM Matrix reg 0x00*/
- chip_write(chip, TDA9875_SC1, 0x00); /* SCART 1 (SC1)*/
- chip_write(chip, TDA9875_SC2, 0x01); /* SCART 2 (sc2)*/
-
- chip_write(chip, TDA9875_CH1V, 0x10); /* Channel volume 1 mute*/
- chip_write(chip, TDA9875_CH2V, 0x10); /* Channel volume 2 mute */
- chip_write(chip, TDA9875_DACOS, 0x02); /* sig DAC i/o(in:nicam)*/
- chip_write(chip, TDA9875_ADCIS, 0x6f); /* sig ADC input(in:mono)*/
- chip_write(chip, TDA9875_LOSR, 0x00); /* line out (in:mono)*/
- chip_write(chip, TDA9875_AER, 0x00); /*06 Effect (AVL+PSEUDO) */
- chip_write(chip, TDA9875_MCS, 0x44); /* Main ch select (DAC) */
- chip_write(chip, TDA9875_MVL, 0x03); /* Vol Main left 10dB */
- chip_write(chip, TDA9875_MVR, 0x03); /* Vol Main right 10dB*/
- chip_write(chip, TDA9875_MBA, 0x00); /* Main Bass Main 0dB*/
- chip_write(chip, TDA9875_MTR, 0x00); /* Main Treble Main 0dB*/
- chip_write(chip, TDA9875_ACS, 0x44); /* Aux chan select (dac)*/
- chip_write(chip, TDA9875_AVL, 0x00); /* Vol Aux left 0dB*/
- chip_write(chip, TDA9875_AVR, 0x00); /* Vol Aux right 0dB*/
- chip_write(chip, TDA9875_ABA, 0x00); /* Aux Bass Main 0dB*/
- chip_write(chip, TDA9875_ATR, 0x00); /* Aux Aigus Main 0dB*/
-
- chip_write(chip, TDA9875_MUT, 0xcc); /* General mute */
- return 0;
-}
-
-static int tda9875_volume(int val) { return (unsigned char)(val / 602 - 84); }
-static int tda9875_bass(int val) { return (unsigned char)(max(-12, val / 2115 - 15)); }
-static int tda9875_treble(int val) { return (unsigned char)(val / 2622 - 12); }
-
-/* ----------------------------------------------------------------------- */
-
-
-/* *********************** *
- * i2c interface functions *
- * *********************** */
-
-static int tda9875_checkit(struct CHIPSTATE *chip)
-{
- struct v4l2_subdev *sd = &chip->sd;
- int dic, rev;
-
- dic = chip_read2(chip, 254);
- rev = chip_read2(chip, 255);
-
- if (dic == 0 || dic == 2) { /* tda9875 and tda9875A */
- v4l2_info(sd, "found tda9875%s rev. %d.\n",
- dic == 0 ? "" : "A", rev);
- return 1;
- }
- return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-/* audio chip descriptions - defines+functions for tea6420 */
-
-#define TEA6300_VL 0x00 /* volume left */
-#define TEA6300_VR 0x01 /* volume right */
-#define TEA6300_BA 0x02 /* bass */
-#define TEA6300_TR 0x03 /* treble */
-#define TEA6300_FA 0x04 /* fader control */
-#define TEA6300_S 0x05 /* switch register */
- /* values for those registers: */
-#define TEA6300_S_SA 0x01 /* stereo A input */
-#define TEA6300_S_SB 0x02 /* stereo B */
-#define TEA6300_S_SC 0x04 /* stereo C */
-#define TEA6300_S_GMU 0x80 /* general mute */
-
-#define TEA6320_V 0x00 /* volume (0-5)/loudness off (6)/zero crossing mute(7) */
-#define TEA6320_FFR 0x01 /* fader front right (0-5) */
-#define TEA6320_FFL 0x02 /* fader front left (0-5) */
-#define TEA6320_FRR 0x03 /* fader rear right (0-5) */
-#define TEA6320_FRL 0x04 /* fader rear left (0-5) */
-#define TEA6320_BA 0x05 /* bass (0-4) */
-#define TEA6320_TR 0x06 /* treble (0-4) */
-#define TEA6320_S 0x07 /* switch register */
- /* values for those registers: */
-#define TEA6320_S_SA 0x07 /* stereo A input */
-#define TEA6320_S_SB 0x06 /* stereo B */
-#define TEA6320_S_SC 0x05 /* stereo C */
-#define TEA6320_S_SD 0x04 /* stereo D */
-#define TEA6320_S_GMU 0x80 /* general mute */
-
-#define TEA6420_S_SA 0x00 /* stereo A input */
-#define TEA6420_S_SB 0x01 /* stereo B */
-#define TEA6420_S_SC 0x02 /* stereo C */
-#define TEA6420_S_SD 0x03 /* stereo D */
-#define TEA6420_S_SE 0x04 /* stereo E */
-#define TEA6420_S_GMU 0x05 /* general mute */
-
-static int tea6300_shift10(int val) { return val >> 10; }
-static int tea6300_shift12(int val) { return val >> 12; }
-
-/* Assumes 16bit input (values 0x3f to 0x0c are unique, values less than */
-/* 0x0c mirror those immediately higher) */
-static int tea6320_volume(int val) { return (val / (65535/(63-12)) + 12) & 0x3f; }
-static int tea6320_shift11(int val) { return val >> 11; }
-static int tea6320_initialize(struct CHIPSTATE * chip)
-{
- chip_write(chip, TEA6320_FFR, 0x3f);
- chip_write(chip, TEA6320_FFL, 0x3f);
- chip_write(chip, TEA6320_FRR, 0x3f);
- chip_write(chip, TEA6320_FRL, 0x3f);
-
- return 0;
-}
-
-
-/* ---------------------------------------------------------------------- */
-/* audio chip descriptions - defines+functions for tda8425 */
-
-#define TDA8425_VL 0x00 /* volume left */
-#define TDA8425_VR 0x01 /* volume right */
-#define TDA8425_BA 0x02 /* bass */
-#define TDA8425_TR 0x03 /* treble */
-#define TDA8425_S1 0x08 /* switch functions */
- /* values for those registers: */
-#define TDA8425_S1_OFF 0xEE /* audio off (mute on) */
-#define TDA8425_S1_CH1 0xCE /* audio channel 1 (mute off) - "linear stereo" mode */
-#define TDA8425_S1_CH2 0xCF /* audio channel 2 (mute off) - "linear stereo" mode */
-#define TDA8425_S1_MU 0x20 /* mute bit */
-#define TDA8425_S1_STEREO 0x18 /* stereo bits */
-#define TDA8425_S1_STEREO_SPATIAL 0x18 /* spatial stereo */
-#define TDA8425_S1_STEREO_LINEAR 0x08 /* linear stereo */
-#define TDA8425_S1_STEREO_PSEUDO 0x10 /* pseudo stereo */
-#define TDA8425_S1_STEREO_MONO 0x00 /* forced mono */
-#define TDA8425_S1_ML 0x06 /* language selector */
-#define TDA8425_S1_ML_SOUND_A 0x02 /* sound a */
-#define TDA8425_S1_ML_SOUND_B 0x04 /* sound b */
-#define TDA8425_S1_ML_STEREO 0x06 /* stereo */
-#define TDA8425_S1_IS 0x01 /* channel selector */
-
-
-static int tda8425_shift10(int val) { return (val >> 10) | 0xc0; }
-static int tda8425_shift12(int val) { return (val >> 12) | 0xf0; }
-
-static void tda8425_setaudmode(struct CHIPSTATE *chip, int mode)
-{
- int s1 = chip->shadow.bytes[TDA8425_S1+1] & 0xe1;
-
- switch (mode) {
- case V4L2_TUNER_MODE_LANG1:
- s1 |= TDA8425_S1_ML_SOUND_A;
- s1 |= TDA8425_S1_STEREO_PSEUDO;
- break;
- case V4L2_TUNER_MODE_LANG2:
- s1 |= TDA8425_S1_ML_SOUND_B;
- s1 |= TDA8425_S1_STEREO_PSEUDO;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- s1 |= TDA8425_S1_ML_STEREO;
- s1 |= TDA8425_S1_STEREO_LINEAR;
- break;
- case V4L2_TUNER_MODE_MONO:
- s1 |= TDA8425_S1_ML_STEREO;
- s1 |= TDA8425_S1_STEREO_MONO;
- break;
- case V4L2_TUNER_MODE_STEREO:
- s1 |= TDA8425_S1_ML_STEREO;
- s1 |= TDA8425_S1_STEREO_SPATIAL;
- break;
- default:
- return;
- }
- chip_write(chip,TDA8425_S1,s1);
-}
-
-
-/* ---------------------------------------------------------------------- */
-/* audio chip descriptions - defines+functions for pic16c54 (PV951) */
-
-/* the registers of 16C54, I2C sub address. */
-#define PIC16C54_REG_KEY_CODE 0x01 /* Not use. */
-#define PIC16C54_REG_MISC 0x02
-
-/* bit definition of the RESET register, I2C data. */
-#define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */
- /* code of remote controller */
-#define PIC16C54_MISC_MTS_MAIN 0x02 /* bit 1 */
-#define PIC16C54_MISC_MTS_SAP 0x04 /* bit 2 */
-#define PIC16C54_MISC_MTS_BOTH 0x08 /* bit 3 */
-#define PIC16C54_MISC_SND_MUTE 0x10 /* bit 4, Mute Audio(Line-in and Tuner) */
-#define PIC16C54_MISC_SND_NOTMUTE 0x20 /* bit 5 */
-#define PIC16C54_MISC_SWITCH_TUNER 0x40 /* bit 6 , Switch to Line-in */
-#define PIC16C54_MISC_SWITCH_LINE 0x80 /* bit 7 , Switch to Tuner */
-
-/* ---------------------------------------------------------------------- */
-/* audio chip descriptions - defines+functions for TA8874Z */
-
-/* write 1st byte */
-#define TA8874Z_LED_STE 0x80
-#define TA8874Z_LED_BIL 0x40
-#define TA8874Z_LED_EXT 0x20
-#define TA8874Z_MONO_SET 0x10
-#define TA8874Z_MUTE 0x08
-#define TA8874Z_F_MONO 0x04
-#define TA8874Z_MODE_SUB 0x02
-#define TA8874Z_MODE_MAIN 0x01
-
-/* write 2nd byte */
-/*#define TA8874Z_TI 0x80 */ /* test mode */
-#define TA8874Z_SEPARATION 0x3f
-#define TA8874Z_SEPARATION_DEFAULT 0x10
-
-/* read */
-#define TA8874Z_B1 0x80
-#define TA8874Z_B0 0x40
-#define TA8874Z_CHAG_FLAG 0x20
-
-/*
- * B1 B0
- * mono L H
- * stereo L L
- * BIL H L
- */
-static int ta8874z_getrxsubchans(struct CHIPSTATE *chip)
-{
- int val, mode;
-
- val = chip_read(chip);
- mode = V4L2_TUNER_SUB_MONO;
- if (val & TA8874Z_B1){
- mode |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- }else if (!(val & TA8874Z_B0)){
- mode = V4L2_TUNER_SUB_STEREO;
- }
- /* v4l2_dbg(1, debug, &chip->sd,
- "ta8874z_getrxsubchans(): raw chip read: 0x%02x, return: 0x%02x\n",
- val, mode); */
- return mode;
-}
-
-static audiocmd ta8874z_stereo = { 2, {0, TA8874Z_SEPARATION_DEFAULT}};
-static audiocmd ta8874z_mono = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}};
-static audiocmd ta8874z_main = {2, { 0, TA8874Z_SEPARATION_DEFAULT}};
-static audiocmd ta8874z_sub = {2, { TA8874Z_MODE_SUB, TA8874Z_SEPARATION_DEFAULT}};
-static audiocmd ta8874z_both = {2, { TA8874Z_MODE_MAIN | TA8874Z_MODE_SUB, TA8874Z_SEPARATION_DEFAULT}};
-
-static void ta8874z_setaudmode(struct CHIPSTATE *chip, int mode)
-{
- struct v4l2_subdev *sd = &chip->sd;
- int update = 1;
- audiocmd *t = NULL;
-
- v4l2_dbg(1, debug, sd, "ta8874z_setaudmode(): mode: 0x%02x\n", mode);
-
- switch(mode){
- case V4L2_TUNER_MODE_MONO:
- t = &ta8874z_mono;
- break;
- case V4L2_TUNER_MODE_STEREO:
- t = &ta8874z_stereo;
- break;
- case V4L2_TUNER_MODE_LANG1:
- t = &ta8874z_main;
- break;
- case V4L2_TUNER_MODE_LANG2:
- t = &ta8874z_sub;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- t = &ta8874z_both;
- break;
- default:
- update = 0;
- }
-
- if(update)
- chip_cmd(chip, "TA8874Z", t);
-}
-
-static int ta8874z_checkit(struct CHIPSTATE *chip)
-{
- int rc;
- rc = chip_read(chip);
- return ((rc & 0x1f) == 0x1f) ? 1 : 0;
-}
-
-/* ---------------------------------------------------------------------- */
-/* audio chip descriptions - struct CHIPDESC */
-
-/* insmod options to enable/disable individual audio chips */
-static int tda8425 = 1;
-static int tda9840 = 1;
-static int tda9850 = 1;
-static int tda9855 = 1;
-static int tda9873 = 1;
-static int tda9874a = 1;
-static int tda9875 = 1;
-static int tea6300; /* default 0 - address clash with msp34xx */
-static int tea6320; /* default 0 - address clash with msp34xx */
-static int tea6420 = 1;
-static int pic16c54 = 1;
-static int ta8874z; /* default 0 - address clash with tda9840 */
-
-module_param(tda8425, int, 0444);
-module_param(tda9840, int, 0444);
-module_param(tda9850, int, 0444);
-module_param(tda9855, int, 0444);
-module_param(tda9873, int, 0444);
-module_param(tda9874a, int, 0444);
-module_param(tda9875, int, 0444);
-module_param(tea6300, int, 0444);
-module_param(tea6320, int, 0444);
-module_param(tea6420, int, 0444);
-module_param(pic16c54, int, 0444);
-module_param(ta8874z, int, 0444);
-
-static struct CHIPDESC chiplist[] = {
- {
- .name = "tda9840",
- .insmodopt = &tda9840,
- .addr_lo = I2C_ADDR_TDA9840 >> 1,
- .addr_hi = I2C_ADDR_TDA9840 >> 1,
- .registers = 5,
- .flags = CHIP_NEED_CHECKMODE,
-
- /* callbacks */
- .checkit = tda9840_checkit,
- .getrxsubchans = tda9840_getrxsubchans,
- .setaudmode = tda9840_setaudmode,
-
- .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN
- /* ,TDA9840_SW, TDA9840_MONO */} }
- },
- {
- .name = "tda9873h",
- .insmodopt = &tda9873,
- .addr_lo = I2C_ADDR_TDA985x_L >> 1,
- .addr_hi = I2C_ADDR_TDA985x_H >> 1,
- .registers = 3,
- .flags = CHIP_HAS_INPUTSEL | CHIP_NEED_CHECKMODE,
-
- /* callbacks */
- .checkit = tda9873_checkit,
- .getrxsubchans = tda9873_getrxsubchans,
- .setaudmode = tda9873_setaudmode,
-
- .init = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } },
- .inputreg = TDA9873_SW,
- .inputmute = TDA9873_MUTE | TDA9873_AUTOMUTE,
- .inputmap = {0xa0, 0xa2, 0xa0, 0xa0},
- .inputmask = TDA9873_INP_MASK|TDA9873_MUTE|TDA9873_AUTOMUTE,
-
- },
- {
- .name = "tda9874h/a",
- .insmodopt = &tda9874a,
- .addr_lo = I2C_ADDR_TDA9874 >> 1,
- .addr_hi = I2C_ADDR_TDA9874 >> 1,
- .flags = CHIP_NEED_CHECKMODE,
-
- /* callbacks */
- .initialize = tda9874a_initialize,
- .checkit = tda9874a_checkit,
- .getrxsubchans = tda9874a_getrxsubchans,
- .setaudmode = tda9874a_setaudmode,
- },
- {
- .name = "tda9875",
- .insmodopt = &tda9875,
- .addr_lo = I2C_ADDR_TDA9875 >> 1,
- .addr_hi = I2C_ADDR_TDA9875 >> 1,
- .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE,
-
- /* callbacks */
- .initialize = tda9875_initialize,
- .checkit = tda9875_checkit,
- .volfunc = tda9875_volume,
- .bassfunc = tda9875_bass,
- .treblefunc = tda9875_treble,
- .leftreg = TDA9875_MVL,
- .rightreg = TDA9875_MVR,
- .bassreg = TDA9875_MBA,
- .treblereg = TDA9875_MTR,
- .leftinit = 58880,
- .rightinit = 58880,
- },
- {
- .name = "tda9850",
- .insmodopt = &tda9850,
- .addr_lo = I2C_ADDR_TDA985x_L >> 1,
- .addr_hi = I2C_ADDR_TDA985x_H >> 1,
- .registers = 11,
-
- .getrxsubchans = tda985x_getrxsubchans,
- .setaudmode = tda985x_setaudmode,
-
- .init = { 8, { TDA9850_C4, 0x08, 0x08, TDA985x_STEREO, 0x07, 0x10, 0x10, 0x03 } }
- },
- {
- .name = "tda9855",
- .insmodopt = &tda9855,
- .addr_lo = I2C_ADDR_TDA985x_L >> 1,
- .addr_hi = I2C_ADDR_TDA985x_H >> 1,
- .registers = 11,
- .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE,
-
- .leftreg = TDA9855_VL,
- .rightreg = TDA9855_VR,
- .bassreg = TDA9855_BA,
- .treblereg = TDA9855_TR,
-
- /* callbacks */
- .volfunc = tda9855_volume,
- .bassfunc = tda9855_bass,
- .treblefunc = tda9855_treble,
- .getrxsubchans = tda985x_getrxsubchans,
- .setaudmode = tda985x_setaudmode,
-
- .init = { 12, { 0, 0x6f, 0x6f, 0x0e, 0x07<<1, 0x8<<2,
- TDA9855_MUTE | TDA9855_AVL | TDA9855_LOUD | TDA9855_INT,
- TDA985x_STEREO | TDA9855_LINEAR | TDA9855_TZCM | TDA9855_VZCM,
- 0x07, 0x10, 0x10, 0x03 }}
- },
- {
- .name = "tea6300",
- .insmodopt = &tea6300,
- .addr_lo = I2C_ADDR_TEA6300 >> 1,
- .addr_hi = I2C_ADDR_TEA6300 >> 1,
- .registers = 6,
- .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
-
- .leftreg = TEA6300_VR,
- .rightreg = TEA6300_VL,
- .bassreg = TEA6300_BA,
- .treblereg = TEA6300_TR,
-
- /* callbacks */
- .volfunc = tea6300_shift10,
- .bassfunc = tea6300_shift12,
- .treblefunc = tea6300_shift12,
-
- .inputreg = TEA6300_S,
- .inputmap = { TEA6300_S_SA, TEA6300_S_SB, TEA6300_S_SC },
- .inputmute = TEA6300_S_GMU,
- },
- {
- .name = "tea6320",
- .insmodopt = &tea6320,
- .addr_lo = I2C_ADDR_TEA6300 >> 1,
- .addr_hi = I2C_ADDR_TEA6300 >> 1,
- .registers = 8,
- .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
-
- .leftreg = TEA6320_V,
- .rightreg = TEA6320_V,
- .bassreg = TEA6320_BA,
- .treblereg = TEA6320_TR,
-
- /* callbacks */
- .initialize = tea6320_initialize,
- .volfunc = tea6320_volume,
- .bassfunc = tea6320_shift11,
- .treblefunc = tea6320_shift11,
-
- .inputreg = TEA6320_S,
- .inputmap = { TEA6320_S_SA, TEA6420_S_SB, TEA6300_S_SC, TEA6320_S_SD },
- .inputmute = TEA6300_S_GMU,
- },
- {
- .name = "tea6420",
- .insmodopt = &tea6420,
- .addr_lo = I2C_ADDR_TEA6420 >> 1,
- .addr_hi = I2C_ADDR_TEA6420 >> 1,
- .registers = 1,
- .flags = CHIP_HAS_INPUTSEL,
-
- .inputreg = -1,
- .inputmap = { TEA6420_S_SA, TEA6420_S_SB, TEA6420_S_SC },
- .inputmute = TEA6300_S_GMU,
- },
- {
- .name = "tda8425",
- .insmodopt = &tda8425,
- .addr_lo = I2C_ADDR_TDA8425 >> 1,
- .addr_hi = I2C_ADDR_TDA8425 >> 1,
- .registers = 9,
- .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
-
- .leftreg = TDA8425_VL,
- .rightreg = TDA8425_VR,
- .bassreg = TDA8425_BA,
- .treblereg = TDA8425_TR,
-
- /* callbacks */
- .volfunc = tda8425_shift10,
- .bassfunc = tda8425_shift12,
- .treblefunc = tda8425_shift12,
- .setaudmode = tda8425_setaudmode,
-
- .inputreg = TDA8425_S1,
- .inputmap = { TDA8425_S1_CH1, TDA8425_S1_CH1, TDA8425_S1_CH1 },
- .inputmute = TDA8425_S1_OFF,
-
- },
- {
- .name = "pic16c54 (PV951)",
- .insmodopt = &pic16c54,
- .addr_lo = I2C_ADDR_PIC16C54 >> 1,
- .addr_hi = I2C_ADDR_PIC16C54>> 1,
- .registers = 2,
- .flags = CHIP_HAS_INPUTSEL,
-
- .inputreg = PIC16C54_REG_MISC,
- .inputmap = {PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_TUNER,
- PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE,
- PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE,
- PIC16C54_MISC_SND_MUTE},
- .inputmute = PIC16C54_MISC_SND_MUTE,
- },
- {
- .name = "ta8874z",
- .checkit = ta8874z_checkit,
- .insmodopt = &ta8874z,
- .addr_lo = I2C_ADDR_TDA9840 >> 1,
- .addr_hi = I2C_ADDR_TDA9840 >> 1,
- .registers = 2,
-
- /* callbacks */
- .getrxsubchans = ta8874z_getrxsubchans,
- .setaudmode = ta8874z_setaudmode,
-
- .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}},
- },
- { .name = NULL } /* EOF */
-};
-
-
-/* ---------------------------------------------------------------------- */
-
-static int tvaudio_g_ctrl(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
-{
- struct CHIPSTATE *chip = to_state(sd);
- struct CHIPDESC *desc = chip->desc;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (!(desc->flags & CHIP_HAS_INPUTSEL))
- break;
- ctrl->value=chip->muted;
- return 0;
- case V4L2_CID_AUDIO_VOLUME:
- if (!(desc->flags & CHIP_HAS_VOLUME))
- break;
- ctrl->value = max(chip->left,chip->right);
- return 0;
- case V4L2_CID_AUDIO_BALANCE:
- {
- int volume;
- if (!(desc->flags & CHIP_HAS_VOLUME))
- break;
- volume = max(chip->left,chip->right);
- if (volume)
- ctrl->value=(32768*min(chip->left,chip->right))/volume;
- else
- ctrl->value=32768;
- return 0;
- }
- case V4L2_CID_AUDIO_BASS:
- if (!(desc->flags & CHIP_HAS_BASSTREBLE))
- break;
- ctrl->value = chip->bass;
- return 0;
- case V4L2_CID_AUDIO_TREBLE:
- if (!(desc->flags & CHIP_HAS_BASSTREBLE))
- break;
- ctrl->value = chip->treble;
- return 0;
- }
- return -EINVAL;
-}
-
-static int tvaudio_s_ctrl(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
-{
- struct CHIPSTATE *chip = to_state(sd);
- struct CHIPDESC *desc = chip->desc;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (!(desc->flags & CHIP_HAS_INPUTSEL))
- break;
-
- if (ctrl->value < 0 || ctrl->value >= 2)
- return -ERANGE;
- chip->muted = ctrl->value;
- if (chip->muted)
- chip_write_masked(chip,desc->inputreg,desc->inputmute,desc->inputmask);
- else
- chip_write_masked(chip,desc->inputreg,
- desc->inputmap[chip->input],desc->inputmask);
- return 0;
- case V4L2_CID_AUDIO_VOLUME:
- {
- int volume,balance;
-
- if (!(desc->flags & CHIP_HAS_VOLUME))
- break;
-
- volume = max(chip->left,chip->right);
- if (volume)
- balance=(32768*min(chip->left,chip->right))/volume;
- else
- balance=32768;
-
- volume=ctrl->value;
- chip->left = (min(65536 - balance,32768) * volume) / 32768;
- chip->right = (min(balance,volume *(__u16)32768)) / 32768;
-
- chip_write(chip,desc->leftreg,desc->volfunc(chip->left));
- chip_write(chip,desc->rightreg,desc->volfunc(chip->right));
-
- return 0;
- }
- case V4L2_CID_AUDIO_BALANCE:
- {
- int volume, balance;
-
- if (!(desc->flags & CHIP_HAS_VOLUME))
- break;
-
- volume = max(chip->left, chip->right);
- balance = ctrl->value;
- chip->left = (min(65536 - balance, 32768) * volume) / 32768;
- chip->right = (min(balance, volume * (__u16)32768)) / 32768;
-
- chip_write(chip, desc->leftreg, desc->volfunc(chip->left));
- chip_write(chip, desc->rightreg, desc->volfunc(chip->right));
-
- return 0;
- }
- case V4L2_CID_AUDIO_BASS:
- if (!(desc->flags & CHIP_HAS_BASSTREBLE))
- break;
- chip->bass = ctrl->value;
- chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
-
- return 0;
- case V4L2_CID_AUDIO_TREBLE:
- if (!(desc->flags & CHIP_HAS_BASSTREBLE))
- break;
- chip->treble = ctrl->value;
- chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
-
- return 0;
- }
- return -EINVAL;
-}
-
-
-/* ---------------------------------------------------------------------- */
-/* video4linux interface */
-
-static int tvaudio_s_radio(struct v4l2_subdev *sd)
-{
- struct CHIPSTATE *chip = to_state(sd);
-
- chip->radio = 1;
- /* del_timer(&chip->wt); */
- return 0;
-}
-
-static int tvaudio_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
-{
- struct CHIPSTATE *chip = to_state(sd);
- struct CHIPDESC *desc = chip->desc;
-
- switch (qc->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (desc->flags & CHIP_HAS_INPUTSEL)
- return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
- break;
- case V4L2_CID_AUDIO_VOLUME:
- if (desc->flags & CHIP_HAS_VOLUME)
- return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- if (desc->flags & CHIP_HAS_VOLUME)
- return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
- break;
- case V4L2_CID_AUDIO_BASS:
- case V4L2_CID_AUDIO_TREBLE:
- if (desc->flags & CHIP_HAS_BASSTREBLE)
- return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
- break;
- default:
- break;
- }
- return -EINVAL;
-}
-
-static int tvaudio_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct CHIPSTATE *chip = to_state(sd);
- struct CHIPDESC *desc = chip->desc;
-
- if (!(desc->flags & CHIP_HAS_INPUTSEL))
- return 0;
- if (input >= 4)
- return -EINVAL;
- /* There are four inputs: tuner, radio, extern and intern. */
- chip->input = input;
- if (chip->muted)
- return 0;
- chip_write_masked(chip, desc->inputreg,
- desc->inputmap[chip->input], desc->inputmask);
- return 0;
-}
-
-static int tvaudio_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct CHIPSTATE *chip = to_state(sd);
- struct CHIPDESC *desc = chip->desc;
-
- if (!desc->setaudmode)
- return 0;
- if (chip->radio)
- return 0;
-
- switch (vt->audmode) {
- case V4L2_TUNER_MODE_MONO:
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1:
- case V4L2_TUNER_MODE_LANG2:
- case V4L2_TUNER_MODE_LANG1_LANG2:
- break;
- default:
- return -EINVAL;
- }
- chip->audmode = vt->audmode;
-
- if (chip->thread)
- wake_up_process(chip->thread);
- else
- desc->setaudmode(chip, vt->audmode);
-
- return 0;
-}
-
-static int tvaudio_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct CHIPSTATE *chip = to_state(sd);
- struct CHIPDESC *desc = chip->desc;
-
- if (!desc->getrxsubchans)
- return 0;
- if (chip->radio)
- return 0;
-
- vt->audmode = chip->audmode;
- vt->rxsubchans = desc->getrxsubchans(chip);
- vt->capability = V4L2_TUNER_CAP_STEREO |
- V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
-
- return 0;
-}
-
-static int tvaudio_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct CHIPSTATE *chip = to_state(sd);
-
- chip->radio = 0;
- return 0;
-}
-
-static int tvaudio_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
-{
- struct CHIPSTATE *chip = to_state(sd);
- struct CHIPDESC *desc = chip->desc;
-
- /* For chips that provide getrxsubchans and setaudmode, and doesn't
- automatically follows the stereo carrier, a kthread is
- created to set the audio standard. In this case, when then
- the video channel is changed, tvaudio starts on MONO mode.
- After waiting for 2 seconds, the kernel thread is called,
- to follow whatever audio standard is pointed by the
- audio carrier.
- */
- if (chip->thread) {
- desc->setaudmode(chip, V4L2_TUNER_MODE_MONO);
- chip->prevmode = -1; /* reset previous mode */
- mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000));
- }
- return 0;
-}
-
-static int tvaudio_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVAUDIO, 0);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops tvaudio_core_ops = {
- .g_chip_ident = tvaudio_g_chip_ident,
- .queryctrl = tvaudio_queryctrl,
- .g_ctrl = tvaudio_g_ctrl,
- .s_ctrl = tvaudio_s_ctrl,
- .s_std = tvaudio_s_std,
-};
-
-static const struct v4l2_subdev_tuner_ops tvaudio_tuner_ops = {
- .s_radio = tvaudio_s_radio,
- .s_frequency = tvaudio_s_frequency,
- .s_tuner = tvaudio_s_tuner,
- .g_tuner = tvaudio_g_tuner,
-};
-
-static const struct v4l2_subdev_audio_ops tvaudio_audio_ops = {
- .s_routing = tvaudio_s_routing,
-};
-
-static const struct v4l2_subdev_ops tvaudio_ops = {
- .core = &tvaudio_core_ops,
- .tuner = &tvaudio_tuner_ops,
- .audio = &tvaudio_audio_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-
-/* i2c registration */
-
-static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
- struct CHIPSTATE *chip;
- struct CHIPDESC *desc;
- struct v4l2_subdev *sd;
-
- if (debug) {
- printk(KERN_INFO "tvaudio: TV audio decoder + audio/video mux driver\n");
- printk(KERN_INFO "tvaudio: known chips: ");
- for (desc = chiplist; desc->name != NULL; desc++)
- printk("%s%s", (desc == chiplist) ? "" : ", ", desc->name);
- printk("\n");
- }
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
- sd = &chip->sd;
- v4l2_i2c_subdev_init(sd, client, &tvaudio_ops);
-
- /* find description for the chip */
- v4l2_dbg(1, debug, sd, "chip found @ 0x%x\n", client->addr<<1);
- for (desc = chiplist; desc->name != NULL; desc++) {
- if (0 == *(desc->insmodopt))
- continue;
- if (client->addr < desc->addr_lo ||
- client->addr > desc->addr_hi)
- continue;
- if (desc->checkit && !desc->checkit(chip))
- continue;
- break;
- }
- if (desc->name == NULL) {
- v4l2_dbg(1, debug, sd, "no matching chip description found\n");
- kfree(chip);
- return -EIO;
- }
- v4l2_info(sd, "%s found @ 0x%x (%s)\n", desc->name, client->addr<<1, client->adapter->name);
- if (desc->flags) {
- v4l2_dbg(1, debug, sd, "matches:%s%s%s.\n",
- (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "",
- (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
- (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : "");
- }
-
- /* fill required data structures */
- if (!id)
- strlcpy(client->name, desc->name, I2C_NAME_SIZE);
- chip->desc = desc;
- chip->shadow.count = desc->registers+1;
- chip->prevmode = -1;
- chip->audmode = V4L2_TUNER_MODE_LANG1;
-
- /* initialization */
- if (desc->initialize != NULL)
- desc->initialize(chip);
- else
- chip_cmd(chip, "init", &desc->init);
-
- if (desc->flags & CHIP_HAS_VOLUME) {
- if (!desc->volfunc) {
- /* This shouldn't be happen. Warn user, but keep working
- without volume controls
- */
- v4l2_info(sd, "volume callback undefined!\n");
- desc->flags &= ~CHIP_HAS_VOLUME;
- } else {
- chip->left = desc->leftinit ? desc->leftinit : 65535;
- chip->right = desc->rightinit ? desc->rightinit : 65535;
- chip_write(chip, desc->leftreg,
- desc->volfunc(chip->left));
- chip_write(chip, desc->rightreg,
- desc->volfunc(chip->right));
- }
- }
- if (desc->flags & CHIP_HAS_BASSTREBLE) {
- if (!desc->bassfunc || !desc->treblefunc) {
- /* This shouldn't be happen. Warn user, but keep working
- without bass/treble controls
- */
- v4l2_info(sd, "bass/treble callbacks undefined!\n");
- desc->flags &= ~CHIP_HAS_BASSTREBLE;
- } else {
- chip->treble = desc->trebleinit ?
- desc->trebleinit : 32768;
- chip->bass = desc->bassinit ?
- desc->bassinit : 32768;
- chip_write(chip, desc->bassreg,
- desc->bassfunc(chip->bass));
- chip_write(chip, desc->treblereg,
- desc->treblefunc(chip->treble));
- }
- }
-
- chip->thread = NULL;
- init_timer(&chip->wt);
- if (desc->flags & CHIP_NEED_CHECKMODE) {
- if (!desc->getrxsubchans || !desc->setaudmode) {
- /* This shouldn't be happen. Warn user, but keep working
- without kthread
- */
- v4l2_info(sd, "set/get mode callbacks undefined!\n");
- return 0;
- }
- /* start async thread */
- chip->wt.function = chip_thread_wake;
- chip->wt.data = (unsigned long)chip;
- chip->thread = kthread_run(chip_thread, chip, client->name);
- if (IS_ERR(chip->thread)) {
- v4l2_warn(sd, "failed to create kthread\n");
- chip->thread = NULL;
- }
- }
- return 0;
-}
-
-static int tvaudio_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct CHIPSTATE *chip = to_state(sd);
-
- del_timer_sync(&chip->wt);
- if (chip->thread) {
- /* shutdown async thread */
- kthread_stop(chip->thread);
- chip->thread = NULL;
- }
-
- v4l2_device_unregister_subdev(sd);
- kfree(chip);
- return 0;
-}
-
-/* This driver supports many devices and the idea is to let the driver
- detect which device is present. So rather than listing all supported
- devices here, we pretend to support a single, fake device type. */
-static const struct i2c_device_id tvaudio_id[] = {
- { "tvaudio", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tvaudio_id);
-
-static struct i2c_driver tvaudio_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "tvaudio",
- },
- .probe = tvaudio_probe,
- .remove = tvaudio_remove,
- .id_table = tvaudio_id,
-};
-
-module_i2c_driver(tvaudio_driver);
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
deleted file mode 100644
index 3b6cf034976..00000000000
--- a/drivers/media/video/tveeprom.c
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- * tveeprom - eeprom decoder for tvcard configuration eeproms
- *
- * Data and decoding routines shamelessly borrowed from bttv-cards.c
- * eeprom access routine shamelessly borrowed from bttv-if.c
- * which are:
-
- Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
- (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
-
- * Adjustments to fit a more general model and all bugs:
-
- Copyright (C) 2003 John Klar <linpvr at projectplasma.com>
-
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-#include <linux/i2c.h>
-
-#include <media/tuner.h>
-#include <media/tveeprom.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-
-MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
-MODULE_AUTHOR("John Klar");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-#define STRM(array, i) \
- (i < sizeof(array) / sizeof(char *) ? array[i] : "unknown")
-
-#define tveeprom_info(fmt, arg...) \
- v4l_printk(KERN_INFO, "tveeprom", c->adapter, c->addr, fmt , ## arg)
-#define tveeprom_warn(fmt, arg...) \
- v4l_printk(KERN_WARNING, "tveeprom", c->adapter, c->addr, fmt , ## arg)
-#define tveeprom_dbg(fmt, arg...) do { \
- if (debug) \
- v4l_printk(KERN_DEBUG, "tveeprom", \
- c->adapter, c->addr, fmt , ## arg); \
- } while (0)
-
-/*
- * The Hauppauge eeprom uses an 8bit field to determine which
- * tuner formats the tuner supports.
- */
-static struct HAUPPAUGE_TUNER_FMT
-{
- int id;
- char *name;
-}
-hauppauge_tuner_fmt[] =
-{
- { V4L2_STD_UNKNOWN, " UNKNOWN" },
- { V4L2_STD_UNKNOWN, " FM" },
- { V4L2_STD_B|V4L2_STD_GH, " PAL(B/G)" },
- { V4L2_STD_MN, " NTSC(M)" },
- { V4L2_STD_PAL_I, " PAL(I)" },
- { V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC, " SECAM(L/L')" },
- { V4L2_STD_DK, " PAL(D/D1/K)" },
- { V4L2_STD_ATSC, " ATSC/DVB Digital" },
-};
-
-/* This is the full list of possible tuners. Many thanks to Hauppauge for
- supplying this information. Note that many tuners where only used for
- testing and never made it to the outside world. So you will only see
- a subset in actual produced cards. */
-static struct HAUPPAUGE_TUNER
-{
- int id;
- char *name;
-}
-hauppauge_tuner[] =
-{
- /* 0-9 */
- { TUNER_ABSENT, "None" },
- { TUNER_ABSENT, "External" },
- { TUNER_ABSENT, "Unspecified" },
- { TUNER_PHILIPS_PAL, "Philips FI1216" },
- { TUNER_PHILIPS_SECAM, "Philips FI1216MF" },
- { TUNER_PHILIPS_NTSC, "Philips FI1236" },
- { TUNER_PHILIPS_PAL_I, "Philips FI1246" },
- { TUNER_PHILIPS_PAL_DK, "Philips FI1256" },
- { TUNER_PHILIPS_PAL, "Philips FI1216 MK2" },
- { TUNER_PHILIPS_SECAM, "Philips FI1216MF MK2" },
- /* 10-19 */
- { TUNER_PHILIPS_NTSC, "Philips FI1236 MK2" },
- { TUNER_PHILIPS_PAL_I, "Philips FI1246 MK2" },
- { TUNER_PHILIPS_PAL_DK, "Philips FI1256 MK2" },
- { TUNER_TEMIC_NTSC, "Temic 4032FY5" },
- { TUNER_TEMIC_PAL, "Temic 4002FH5" },
- { TUNER_TEMIC_PAL_I, "Temic 4062FY5" },
- { TUNER_PHILIPS_PAL, "Philips FR1216 MK2" },
- { TUNER_PHILIPS_SECAM, "Philips FR1216MF MK2" },
- { TUNER_PHILIPS_NTSC, "Philips FR1236 MK2" },
- { TUNER_PHILIPS_PAL_I, "Philips FR1246 MK2" },
- /* 20-29 */
- { TUNER_PHILIPS_PAL_DK, "Philips FR1256 MK2" },
- { TUNER_PHILIPS_PAL, "Philips FM1216" },
- { TUNER_PHILIPS_SECAM, "Philips FM1216MF" },
- { TUNER_PHILIPS_NTSC, "Philips FM1236" },
- { TUNER_PHILIPS_PAL_I, "Philips FM1246" },
- { TUNER_PHILIPS_PAL_DK, "Philips FM1256" },
- { TUNER_TEMIC_4036FY5_NTSC, "Temic 4036FY5" },
- { TUNER_ABSENT, "Samsung TCPN9082D" },
- { TUNER_ABSENT, "Samsung TCPM9092P" },
- { TUNER_TEMIC_4006FH5_PAL, "Temic 4006FH5" },
- /* 30-39 */
- { TUNER_ABSENT, "Samsung TCPN9085D" },
- { TUNER_ABSENT, "Samsung TCPB9085P" },
- { TUNER_ABSENT, "Samsung TCPL9091P" },
- { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
- { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" },
- { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" },
- { TUNER_PHILIPS_NTSC, "Philips TD1536" },
- { TUNER_PHILIPS_NTSC, "Philips TD1536D" },
- { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */
- { TUNER_ABSENT, "Philips FI1256MP" },
- /* 40-49 */
- { TUNER_ABSENT, "Samsung TCPQ9091P" },
- { TUNER_TEMIC_4006FN5_MULTI_PAL, "Temic 4006FN5" },
- { TUNER_TEMIC_4009FR5_PAL, "Temic 4009FR5" },
- { TUNER_TEMIC_4046FM5, "Temic 4046FM5" },
- { TUNER_TEMIC_4009FN5_MULTI_PAL_FM, "Temic 4009FN5" },
- { TUNER_ABSENT, "Philips TD1536D FH 44"},
- { TUNER_LG_NTSC_FM, "LG TP18NSR01F"},
- { TUNER_LG_PAL_FM, "LG TP18PSB01D"},
- { TUNER_LG_PAL, "LG TP18PSB11D"},
- { TUNER_LG_PAL_I_FM, "LG TAPC-I001D"},
- /* 50-59 */
- { TUNER_LG_PAL_I, "LG TAPC-I701D"},
- { TUNER_ABSENT, "Temic 4042FI5"},
- { TUNER_MICROTUNE_4049FM5, "Microtune 4049 FM5"},
- { TUNER_ABSENT, "LG TPI8NSR11F"},
- { TUNER_ABSENT, "Microtune 4049 FM5 Alt I2C"},
- { TUNER_PHILIPS_FM1216ME_MK3, "Philips FQ1216ME MK3"},
- { TUNER_ABSENT, "Philips FI1236 MK3"},
- { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216 ME MK3"},
- { TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK3"},
- { TUNER_ABSENT, "Philips FM1216MP MK3"},
- /* 60-69 */
- { TUNER_PHILIPS_FM1216ME_MK3, "LG S001D MK3"},
- { TUNER_ABSENT, "LG M001D MK3"},
- { TUNER_PHILIPS_FM1216ME_MK3, "LG S701D MK3"},
- { TUNER_ABSENT, "LG M701D MK3"},
- { TUNER_ABSENT, "Temic 4146FM5"},
- { TUNER_ABSENT, "Temic 4136FY5"},
- { TUNER_ABSENT, "Temic 4106FH5"},
- { TUNER_ABSENT, "Philips FQ1216LMP MK3"},
- { TUNER_LG_NTSC_TAPE, "LG TAPE H001F MK3"},
- { TUNER_LG_NTSC_TAPE, "LG TAPE H701F MK3"},
- /* 70-79 */
- { TUNER_ABSENT, "LG TALN H200T"},
- { TUNER_ABSENT, "LG TALN H250T"},
- { TUNER_ABSENT, "LG TALN M200T"},
- { TUNER_ABSENT, "LG TALN Z200T"},
- { TUNER_ABSENT, "LG TALN S200T"},
- { TUNER_ABSENT, "Thompson DTT7595"},
- { TUNER_ABSENT, "Thompson DTT7592"},
- { TUNER_ABSENT, "Silicon TDA8275C1 8290"},
- { TUNER_ABSENT, "Silicon TDA8275C1 8290 FM"},
- { TUNER_ABSENT, "Thompson DTT757"},
- /* 80-89 */
- { TUNER_PHILIPS_FQ1216LME_MK3, "Philips FQ1216LME MK3"},
- { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"},
- { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"},
- { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
- { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
- { TUNER_TCL_2002N, "TCL 2002N 6A"},
- { TUNER_PHILIPS_FM1236_MK3, "Philips FQ1236 MK3"},
- { TUNER_SAMSUNG_TCPN_2121P30A, "Samsung TCPN 2121P30A"},
- { TUNER_ABSENT, "Samsung TCPE 4121P30A"},
- { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"},
- /* 90-99 */
- { TUNER_ABSENT, "LG TALN H202T"},
- { TUNER_PHILIPS_FQ1216AME_MK4, "Philips FQ1216AME MK4"},
- { TUNER_PHILIPS_FQ1236A_MK4, "Philips FQ1236A MK4"},
- { TUNER_ABSENT, "Philips FQ1286A MK4"},
- { TUNER_ABSENT, "Philips FQ1216ME MK5"},
- { TUNER_ABSENT, "Philips FQ1236 MK5"},
- { TUNER_SAMSUNG_TCPG_6121P30A, "Samsung TCPG 6121P30A"},
- { TUNER_TCL_2002MB, "TCL 2002MB_3H"},
- { TUNER_ABSENT, "TCL 2002MI_3H"},
- { TUNER_TCL_2002N, "TCL 2002N 5H"},
- /* 100-109 */
- { TUNER_PHILIPS_FMD1216ME_MK3, "Philips FMD1216ME"},
- { TUNER_TEA5767, "Philips TEA5768HL FM Radio"},
- { TUNER_ABSENT, "Panasonic ENV57H12D5"},
- { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"},
- { TUNER_PHILIPS_FM1236_MK3, "TCL MNM05-4"},
- { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"},
- { TUNER_ABSENT, "TCL MQNM05-4"},
- { TUNER_ABSENT, "LG TAPC-W701D"},
- { TUNER_ABSENT, "TCL 9886P-WM"},
- { TUNER_ABSENT, "TCL 1676NM-WM"},
- /* 110-119 */
- { TUNER_ABSENT, "Thompson DTT75105"},
- { TUNER_ABSENT, "Conexant_CX24109"},
- { TUNER_TCL_2002N, "TCL M2523_5N_E"},
- { TUNER_TCL_2002MB, "TCL M2523_3DB_E"},
- { TUNER_ABSENT, "Philips 8275A"},
- { TUNER_ABSENT, "Microtune MT2060"},
- { TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK5"},
- { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216ME MK5"},
- { TUNER_ABSENT, "TCL M2523_3DI_E"},
- { TUNER_ABSENT, "Samsung THPD5222FG30A"},
- /* 120-129 */
- { TUNER_XC2028, "Xceive XC3028"},
- { TUNER_PHILIPS_FQ1216LME_MK3, "Philips FQ1216LME MK5"},
- { TUNER_ABSENT, "Philips FQD1216LME"},
- { TUNER_ABSENT, "Conexant CX24118A"},
- { TUNER_ABSENT, "TCL DMF11WIP"},
- { TUNER_ABSENT, "TCL MFNM05_4H_E"},
- { TUNER_ABSENT, "TCL MNM05_4H_E"},
- { TUNER_ABSENT, "TCL MPE05_2H_E"},
- { TUNER_ABSENT, "TCL MQNM05_4_U"},
- { TUNER_ABSENT, "TCL M2523_5NH_E"},
- /* 130-139 */
- { TUNER_ABSENT, "TCL M2523_3DBH_E"},
- { TUNER_ABSENT, "TCL M2523_3DIH_E"},
- { TUNER_ABSENT, "TCL MFPE05_2_U"},
- { TUNER_PHILIPS_FMD1216MEX_MK3, "Philips FMD1216MEX"},
- { TUNER_ABSENT, "Philips FRH2036B"},
- { TUNER_ABSENT, "Panasonic ENGF75_01GF"},
- { TUNER_ABSENT, "MaxLinear MXL5005"},
- { TUNER_ABSENT, "MaxLinear MXL5003"},
- { TUNER_ABSENT, "Xceive XC2028"},
- { TUNER_ABSENT, "Microtune MT2131"},
- /* 140-149 */
- { TUNER_ABSENT, "Philips 8275A_8295"},
- { TUNER_ABSENT, "TCL MF02GIP_5N_E"},
- { TUNER_ABSENT, "TCL MF02GIP_3DB_E"},
- { TUNER_ABSENT, "TCL MF02GIP_3DI_E"},
- { TUNER_ABSENT, "Microtune MT2266"},
- { TUNER_ABSENT, "TCL MF10WPP_4N_E"},
- { TUNER_ABSENT, "LG TAPQ_H702F"},
- { TUNER_ABSENT, "TCL M09WPP_4N_E"},
- { TUNER_ABSENT, "MaxLinear MXL5005_v2"},
- { TUNER_PHILIPS_TDA8290, "Philips 18271_8295"},
- /* 150-159 */
- { TUNER_XC5000, "Xceive XC5000"},
- { TUNER_ABSENT, "Xceive XC3028L"},
- { TUNER_ABSENT, "NXP 18271C2_716x"},
- { TUNER_ABSENT, "Xceive XC4000"},
- { TUNER_ABSENT, "Dibcom 7070"},
- { TUNER_PHILIPS_TDA8290, "NXP 18271C2"},
- { TUNER_ABSENT, "Siano SMS1010"},
- { TUNER_ABSENT, "Siano SMS1150"},
- { TUNER_ABSENT, "MaxLinear 5007"},
- { TUNER_ABSENT, "TCL M09WPP_2P_E"},
- /* 160-169 */
- { TUNER_ABSENT, "Siano SMS1180"},
- { TUNER_ABSENT, "Maxim_MAX2165"},
- { TUNER_ABSENT, "Siano SMS1140"},
- { TUNER_ABSENT, "Siano SMS1150 B1"},
- { TUNER_ABSENT, "MaxLinear 111"},
- { TUNER_ABSENT, "Dibcom 7770"},
- { TUNER_ABSENT, "Siano SMS1180VNS"},
- { TUNER_ABSENT, "Siano SMS1184"},
- { TUNER_PHILIPS_FQ1236_MK5, "TCL M30WTP-4N-E"},
- { TUNER_ABSENT, "TCL_M11WPP_2PN_E"},
- /* 170-179 */
- { TUNER_ABSENT, "MaxLinear 301"},
- { TUNER_ABSENT, "Mirics MSi001"},
- { TUNER_ABSENT, "MaxLinear MxL241SF"},
- { TUNER_XC5000C, "Xceive XC5000C"},
- { TUNER_ABSENT, "Montage M68TS2020"},
- { TUNER_ABSENT, "Siano SMS1530"},
- { TUNER_ABSENT, "Dibcom 7090"},
- { TUNER_ABSENT, "Xceive XC5200C"},
- { TUNER_ABSENT, "NXP 18273"},
- { TUNER_ABSENT, "Montage M88TS2022"},
- /* 180-189 */
- { TUNER_ABSENT, "NXP 18272M"},
- { TUNER_ABSENT, "NXP 18272S"},
-};
-
-/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
- * internal to a video chip, i.e. not a separate audio chip. */
-static struct HAUPPAUGE_AUDIOIC
-{
- u32 id;
- char *name;
-}
-audioIC[] =
-{
- /* 0-4 */
- { V4L2_IDENT_NONE, "None" },
- { V4L2_IDENT_UNKNOWN, "TEA6300" },
- { V4L2_IDENT_UNKNOWN, "TEA6320" },
- { V4L2_IDENT_UNKNOWN, "TDA9850" },
- { V4L2_IDENT_MSPX4XX, "MSP3400C" },
- /* 5-9 */
- { V4L2_IDENT_MSPX4XX, "MSP3410D" },
- { V4L2_IDENT_MSPX4XX, "MSP3415" },
- { V4L2_IDENT_MSPX4XX, "MSP3430" },
- { V4L2_IDENT_MSPX4XX, "MSP3438" },
- { V4L2_IDENT_UNKNOWN, "CS5331" },
- /* 10-14 */
- { V4L2_IDENT_MSPX4XX, "MSP3435" },
- { V4L2_IDENT_MSPX4XX, "MSP3440" },
- { V4L2_IDENT_MSPX4XX, "MSP3445" },
- { V4L2_IDENT_MSPX4XX, "MSP3411" },
- { V4L2_IDENT_MSPX4XX, "MSP3416" },
- /* 15-19 */
- { V4L2_IDENT_MSPX4XX, "MSP3425" },
- { V4L2_IDENT_MSPX4XX, "MSP3451" },
- { V4L2_IDENT_MSPX4XX, "MSP3418" },
- { V4L2_IDENT_UNKNOWN, "Type 0x12" },
- { V4L2_IDENT_UNKNOWN, "OKI7716" },
- /* 20-24 */
- { V4L2_IDENT_MSPX4XX, "MSP4410" },
- { V4L2_IDENT_MSPX4XX, "MSP4420" },
- { V4L2_IDENT_MSPX4XX, "MSP4440" },
- { V4L2_IDENT_MSPX4XX, "MSP4450" },
- { V4L2_IDENT_MSPX4XX, "MSP4408" },
- /* 25-29 */
- { V4L2_IDENT_MSPX4XX, "MSP4418" },
- { V4L2_IDENT_MSPX4XX, "MSP4428" },
- { V4L2_IDENT_MSPX4XX, "MSP4448" },
- { V4L2_IDENT_MSPX4XX, "MSP4458" },
- { V4L2_IDENT_MSPX4XX, "Type 0x1d" },
- /* 30-34 */
- { V4L2_IDENT_AMBIGUOUS, "CX880" },
- { V4L2_IDENT_AMBIGUOUS, "CX881" },
- { V4L2_IDENT_AMBIGUOUS, "CX883" },
- { V4L2_IDENT_AMBIGUOUS, "CX882" },
- { V4L2_IDENT_AMBIGUOUS, "CX25840" },
- /* 35-39 */
- { V4L2_IDENT_AMBIGUOUS, "CX25841" },
- { V4L2_IDENT_AMBIGUOUS, "CX25842" },
- { V4L2_IDENT_AMBIGUOUS, "CX25843" },
- { V4L2_IDENT_AMBIGUOUS, "CX23418" },
- { V4L2_IDENT_AMBIGUOUS, "CX23885" },
- /* 40-44 */
- { V4L2_IDENT_AMBIGUOUS, "CX23888" },
- { V4L2_IDENT_AMBIGUOUS, "SAA7131" },
- { V4L2_IDENT_AMBIGUOUS, "CX23887" },
- { V4L2_IDENT_AMBIGUOUS, "SAA7164" },
- { V4L2_IDENT_AMBIGUOUS, "AU8522" },
-};
-
-/* This list is supplied by Hauppauge. Thanks! */
-static const char *decoderIC[] = {
- /* 0-4 */
- "None", "BT815", "BT817", "BT819", "BT815A",
- /* 5-9 */
- "BT817A", "BT819A", "BT827", "BT829", "BT848",
- /* 10-14 */
- "BT848A", "BT849A", "BT829A", "BT827A", "BT878",
- /* 15-19 */
- "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
- /* 20-24 */
- "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
- /* 25-29 */
- "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
- /* 30-34 */
- "CX25843", "CX23418", "NEC61153", "CX23885", "CX23888",
- /* 35-39 */
- "SAA7131", "CX25837", "CX23887", "CX23885A", "CX23887A",
- /* 40-42 */
- "SAA7164", "CX23885B", "AU8522"
-};
-
-static int hasRadioTuner(int tunerType)
-{
- switch (tunerType) {
- case 18: /* PNPEnv_TUNER_FR1236_MK2 */
- case 23: /* PNPEnv_TUNER_FM1236 */
- case 38: /* PNPEnv_TUNER_FMR1236 */
- case 16: /* PNPEnv_TUNER_FR1216_MK2 */
- case 19: /* PNPEnv_TUNER_FR1246_MK2 */
- case 21: /* PNPEnv_TUNER_FM1216 */
- case 24: /* PNPEnv_TUNER_FM1246 */
- case 17: /* PNPEnv_TUNER_FR1216MF_MK2 */
- case 22: /* PNPEnv_TUNER_FM1216MF */
- case 20: /* PNPEnv_TUNER_FR1256_MK2 */
- case 25: /* PNPEnv_TUNER_FM1256 */
- case 33: /* PNPEnv_TUNER_4039FR5 */
- case 42: /* PNPEnv_TUNER_4009FR5 */
- case 52: /* PNPEnv_TUNER_4049FM5 */
- case 54: /* PNPEnv_TUNER_4049FM5_AltI2C */
- case 44: /* PNPEnv_TUNER_4009FN5 */
- case 31: /* PNPEnv_TUNER_TCPB9085P */
- case 30: /* PNPEnv_TUNER_TCPN9085D */
- case 46: /* PNPEnv_TUNER_TP18NSR01F */
- case 47: /* PNPEnv_TUNER_TP18PSB01D */
- case 49: /* PNPEnv_TUNER_TAPC_I001D */
- case 60: /* PNPEnv_TUNER_TAPE_S001D_MK3 */
- case 57: /* PNPEnv_TUNER_FM1216ME_MK3 */
- case 59: /* PNPEnv_TUNER_FM1216MP_MK3 */
- case 58: /* PNPEnv_TUNER_FM1236_MK3 */
- case 68: /* PNPEnv_TUNER_TAPE_H001F_MK3 */
- case 61: /* PNPEnv_TUNER_TAPE_M001D_MK3 */
- case 78: /* PNPEnv_TUNER_TDA8275C1_8290_FM */
- case 89: /* PNPEnv_TUNER_TCL_MFPE05_2 */
- case 92: /* PNPEnv_TUNER_PHILIPS_FQ1236A_MK4 */
- case 105:
- return 1;
- }
- return 0;
-}
-
-void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
- unsigned char *eeprom_data)
-{
- /* ----------------------------------------------
- ** The hauppauge eeprom format is tagged
- **
- ** if packet[0] == 0x84, then packet[0..1] == length
- ** else length = packet[0] & 3f;
- ** if packet[0] & f8 == f8, then EOD and packet[1] == checksum
- **
- ** In our (ivtv) case we're interested in the following:
- ** tuner type: tag [00].05 or [0a].01 (index into hauppauge_tuner)
- ** tuner fmts: tag [00].04 or [0a].00 (bitmask index into
- ** hauppauge_tuner_fmt)
- ** radio: tag [00].{last} or [0e].00 (bitmask. bit2=FM)
- ** audio proc: tag [02].01 or [05].00 (mask with 0x7f)
- ** decoder proc: tag [09].01)
-
- ** Fun info:
- ** model: tag [00].07-08 or [06].00-01
- ** revision: tag [00].09-0b or [06].04-06
- ** serial#: tag [01].05-07 or [04].04-06
-
- ** # of inputs/outputs ???
- */
-
- int i, j, len, done, beenhere, tag, start;
-
- int tuner1 = 0, t_format1 = 0, audioic = -1;
- char *t_name1 = NULL;
- const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
-
- int tuner2 = 0, t_format2 = 0;
- char *t_name2 = NULL;
- const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
-
- memset(tvee, 0, sizeof(*tvee));
- tvee->tuner_type = TUNER_ABSENT;
- tvee->tuner2_type = TUNER_ABSENT;
-
- done = len = beenhere = 0;
-
- /* Different eeprom start offsets for em28xx, cx2388x and cx23418 */
- if (eeprom_data[0] == 0x1a &&
- eeprom_data[1] == 0xeb &&
- eeprom_data[2] == 0x67 &&
- eeprom_data[3] == 0x95)
- start = 0xa0; /* Generic em28xx offset */
- else if ((eeprom_data[0] & 0xe1) == 0x01 &&
- eeprom_data[1] == 0x00 &&
- eeprom_data[2] == 0x00 &&
- eeprom_data[8] == 0x84)
- start = 8; /* Generic cx2388x offset */
- else if (eeprom_data[1] == 0x70 &&
- eeprom_data[2] == 0x00 &&
- eeprom_data[4] == 0x74 &&
- eeprom_data[8] == 0x84)
- start = 8; /* Generic cx23418 offset (models 74xxx) */
- else
- start = 0;
-
- for (i = start; !done && i < 256; i += len) {
- if (eeprom_data[i] == 0x84) {
- len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
- i += 3;
- } else if ((eeprom_data[i] & 0xf0) == 0x70) {
- if (eeprom_data[i] & 0x08) {
- /* verify checksum! */
- done = 1;
- break;
- }
- len = eeprom_data[i] & 0x07;
- ++i;
- } else {
- tveeprom_warn("Encountered bad packet header [%02x]. "
- "Corrupt or not a Hauppauge eeprom.\n",
- eeprom_data[i]);
- return;
- }
-
- if (debug) {
- tveeprom_info("Tag [%02x] + %d bytes:",
- eeprom_data[i], len - 1);
- for (j = 1; j < len; j++)
- printk(KERN_CONT " %02x", eeprom_data[i + j]);
- printk(KERN_CONT "\n");
- }
-
- /* process by tag */
- tag = eeprom_data[i];
- switch (tag) {
- case 0x00:
- /* tag: 'Comprehensive' */
- tuner1 = eeprom_data[i+6];
- t_format1 = eeprom_data[i+5];
- tvee->has_radio = eeprom_data[i+len-1];
- /* old style tag, don't know how to detect
- IR presence, mark as unknown. */
- tvee->has_ir = 0;
- tvee->model =
- eeprom_data[i+8] +
- (eeprom_data[i+9] << 8);
- tvee->revision = eeprom_data[i+10] +
- (eeprom_data[i+11] << 8) +
- (eeprom_data[i+12] << 16);
- break;
-
- case 0x01:
- /* tag: 'SerialID' */
- tvee->serial_number =
- eeprom_data[i+6] +
- (eeprom_data[i+7] << 8) +
- (eeprom_data[i+8] << 16);
- break;
-
- case 0x02:
- /* tag 'AudioInfo'
- Note mask with 0x7F, high bit used on some older models
- to indicate 4052 mux was removed in favor of using MSP
- inputs directly. */
- audioic = eeprom_data[i+2] & 0x7f;
- if (audioic < ARRAY_SIZE(audioIC))
- tvee->audio_processor = audioIC[audioic].id;
- else
- tvee->audio_processor = V4L2_IDENT_UNKNOWN;
- break;
-
- /* case 0x03: tag 'EEInfo' */
-
- case 0x04:
- /* tag 'SerialID2' */
- tvee->serial_number =
- eeprom_data[i+5] +
- (eeprom_data[i+6] << 8) +
- (eeprom_data[i+7] << 16);
-
- if ((eeprom_data[i + 8] & 0xf0) &&
- (tvee->serial_number < 0xffffff)) {
- tvee->MAC_address[0] = 0x00;
- tvee->MAC_address[1] = 0x0D;
- tvee->MAC_address[2] = 0xFE;
- tvee->MAC_address[3] = eeprom_data[i + 7];
- tvee->MAC_address[4] = eeprom_data[i + 6];
- tvee->MAC_address[5] = eeprom_data[i + 5];
- tvee->has_MAC_address = 1;
- }
- break;
-
- case 0x05:
- /* tag 'Audio2'
- Note mask with 0x7F, high bit used on some older models
- to indicate 4052 mux was removed in favor of using MSP
- inputs directly. */
- audioic = eeprom_data[i+1] & 0x7f;
- if (audioic < ARRAY_SIZE(audioIC))
- tvee->audio_processor = audioIC[audioic].id;
- else
- tvee->audio_processor = V4L2_IDENT_UNKNOWN;
-
- break;
-
- case 0x06:
- /* tag 'ModelRev' */
- tvee->model =
- eeprom_data[i + 1] +
- (eeprom_data[i + 2] << 8) +
- (eeprom_data[i + 3] << 16) +
- (eeprom_data[i + 4] << 24);
- tvee->revision =
- eeprom_data[i + 5] +
- (eeprom_data[i + 6] << 8) +
- (eeprom_data[i + 7] << 16);
- break;
-
- case 0x07:
- /* tag 'Details': according to Hauppauge not interesting
- on any PCI-era or later boards. */
- break;
-
- /* there is no tag 0x08 defined */
-
- case 0x09:
- /* tag 'Video' */
- tvee->decoder_processor = eeprom_data[i + 1];
- break;
-
- case 0x0a:
- /* tag 'Tuner' */
- if (beenhere == 0) {
- tuner1 = eeprom_data[i + 2];
- t_format1 = eeprom_data[i + 1];
- beenhere = 1;
- } else {
- /* a second (radio) tuner may be present */
- tuner2 = eeprom_data[i + 2];
- t_format2 = eeprom_data[i + 1];
- /* not a TV tuner? */
- if (t_format2 == 0)
- tvee->has_radio = 1; /* must be radio */
- }
- break;
-
- case 0x0b:
- /* tag 'Inputs': according to Hauppauge this is specific
- to each driver family, so no good assumptions can be
- made. */
- break;
-
- /* case 0x0c: tag 'Balun' */
- /* case 0x0d: tag 'Teletext' */
-
- case 0x0e:
- /* tag: 'Radio' */
- tvee->has_radio = eeprom_data[i+1];
- break;
-
- case 0x0f:
- /* tag 'IRInfo' */
- tvee->has_ir = 1 | (eeprom_data[i+1] << 1);
- break;
-
- /* case 0x10: tag 'VBIInfo' */
- /* case 0x11: tag 'QCInfo' */
- /* case 0x12: tag 'InfoBits' */
-
- default:
- tveeprom_dbg("Not sure what to do with tag [%02x]\n",
- tag);
- /* dump the rest of the packet? */
- }
- }
-
- if (!done) {
- tveeprom_warn("Ran out of data!\n");
- return;
- }
-
- if (tvee->revision != 0) {
- tvee->rev_str[0] = 32 + ((tvee->revision >> 18) & 0x3f);
- tvee->rev_str[1] = 32 + ((tvee->revision >> 12) & 0x3f);
- tvee->rev_str[2] = 32 + ((tvee->revision >> 6) & 0x3f);
- tvee->rev_str[3] = 32 + (tvee->revision & 0x3f);
- tvee->rev_str[4] = 0;
- }
-
- if (hasRadioTuner(tuner1) && !tvee->has_radio) {
- tveeprom_info("The eeprom says no radio is present, but the tuner type\n");
- tveeprom_info("indicates otherwise. I will assume that radio is present.\n");
- tvee->has_radio = 1;
- }
-
- if (tuner1 < ARRAY_SIZE(hauppauge_tuner)) {
- tvee->tuner_type = hauppauge_tuner[tuner1].id;
- t_name1 = hauppauge_tuner[tuner1].name;
- } else {
- t_name1 = "unknown";
- }
-
- if (tuner2 < ARRAY_SIZE(hauppauge_tuner)) {
- tvee->tuner2_type = hauppauge_tuner[tuner2].id;
- t_name2 = hauppauge_tuner[tuner2].name;
- } else {
- t_name2 = "unknown";
- }
-
- tvee->tuner_hauppauge_model = tuner1;
- tvee->tuner2_hauppauge_model = tuner2;
- tvee->tuner_formats = 0;
- tvee->tuner2_formats = 0;
- for (i = j = 0; i < 8; i++) {
- if (t_format1 & (1 << i)) {
- tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
- t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
- }
- }
- for (i = j = 0; i < 8; i++) {
- if (t_format2 & (1 << i)) {
- tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
- t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
- }
- }
-
- tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
- tvee->model, tvee->rev_str, tvee->serial_number);
- if (tvee->has_MAC_address == 1)
- tveeprom_info("MAC address is %pM\n", tvee->MAC_address);
- tveeprom_info("tuner model is %s (idx %d, type %d)\n",
- t_name1, tuner1, tvee->tuner_type);
- tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
- t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2],
- t_fmt_name1[3], t_fmt_name1[4], t_fmt_name1[5],
- t_fmt_name1[6], t_fmt_name1[7], t_format1);
- if (tuner2)
- tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
- t_name2, tuner2, tvee->tuner2_type);
- if (t_format2)
- tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
- t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2],
- t_fmt_name2[3], t_fmt_name2[4], t_fmt_name2[5],
- t_fmt_name2[6], t_fmt_name2[7], t_format2);
- if (audioic < 0) {
- tveeprom_info("audio processor is unknown (no idx)\n");
- tvee->audio_processor = V4L2_IDENT_UNKNOWN;
- } else {
- if (audioic < ARRAY_SIZE(audioIC))
- tveeprom_info("audio processor is %s (idx %d)\n",
- audioIC[audioic].name, audioic);
- else
- tveeprom_info("audio processor is unknown (idx %d)\n",
- audioic);
- }
- if (tvee->decoder_processor)
- tveeprom_info("decoder processor is %s (idx %d)\n",
- STRM(decoderIC, tvee->decoder_processor),
- tvee->decoder_processor);
- if (tvee->has_ir)
- tveeprom_info("has %sradio, has %sIR receiver, has %sIR transmitter\n",
- tvee->has_radio ? "" : "no ",
- (tvee->has_ir & 2) ? "" : "no ",
- (tvee->has_ir & 4) ? "" : "no ");
- else
- tveeprom_info("has %sradio\n",
- tvee->has_radio ? "" : "no ");
-}
-EXPORT_SYMBOL(tveeprom_hauppauge_analog);
-
-/* ----------------------------------------------------------------------- */
-/* generic helper functions */
-
-int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
-{
- unsigned char buf;
- int err;
-
- buf = 0;
- err = i2c_master_send(c, &buf, 1);
- if (err != 1) {
- tveeprom_info("Huh, no eeprom present (err=%d)?\n", err);
- return -1;
- }
- err = i2c_master_recv(c, eedata, len);
- if (err != len) {
- tveeprom_warn("i2c eeprom read error (err=%d)\n", err);
- return -1;
- }
- if (debug) {
- int i;
-
- tveeprom_info("full 256-byte eeprom dump:\n");
- for (i = 0; i < len; i++) {
- if (0 == (i % 16))
- tveeprom_info("%02x:", i);
- printk(KERN_CONT " %02x", eedata[i]);
- if (15 == (i % 16))
- printk(KERN_CONT "\n");
- }
- }
- return 0;
-}
-EXPORT_SYMBOL(tveeprom_read);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
deleted file mode 100644
index cd615c1d601..00000000000
--- a/drivers/media/video/tvp514x.c
+++ /dev/null
@@ -1,1166 +0,0 @@
-/*
- * drivers/media/video/tvp514x.c
- *
- * TI TVP5146/47 decoder driver
- *
- * Copyright (C) 2008 Texas Instruments Inc
- * Author: Vaibhav Hiremath <hvaibhav@ti.com>
- *
- * Contributors:
- * Sivaraj R <sivaraj@ti.com>
- * Brijesh R Jadav <brijesh.j@ti.com>
- * Hardik Shah <hardik.shah@ti.com>
- * Manjunath Hadli <mrh@ti.com>
- * Karicheri Muralidharan <m-karicheri2@ti.com>
- *
- * This package is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include <linux/module.h>
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-mediabus.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-#include <media/tvp514x.h>
-
-#include "tvp514x_regs.h"
-
-/* Module Name */
-#define TVP514X_MODULE_NAME "tvp514x"
-
-/* Private macros for TVP */
-#define I2C_RETRY_COUNT (5)
-#define LOCK_RETRY_COUNT (5)
-#define LOCK_RETRY_DELAY (200)
-
-/* Debug functions */
-static bool debug;
-module_param(debug, bool, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-MODULE_AUTHOR("Texas Instruments");
-MODULE_DESCRIPTION("TVP514X linux decoder driver");
-MODULE_LICENSE("GPL");
-
-/* enum tvp514x_std - enum for supported standards */
-enum tvp514x_std {
- STD_NTSC_MJ = 0,
- STD_PAL_BDGHIN,
- STD_INVALID
-};
-
-/**
- * struct tvp514x_std_info - Structure to store standard informations
- * @width: Line width in pixels
- * @height:Number of active lines
- * @video_std: Value to write in REG_VIDEO_STD register
- * @standard: v4l2 standard structure information
- */
-struct tvp514x_std_info {
- unsigned long width;
- unsigned long height;
- u8 video_std;
- struct v4l2_standard standard;
-};
-
-static struct tvp514x_reg tvp514x_reg_list_default[0x40];
-
-static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable);
-/**
- * struct tvp514x_decoder - TVP5146/47 decoder object
- * @sd: Subdevice Slave handle
- * @tvp514x_regs: copy of hw's regs with preset values.
- * @pdata: Board specific
- * @ver: Chip version
- * @streaming: TVP5146/47 decoder streaming - enabled or disabled.
- * @current_std: Current standard
- * @num_stds: Number of standards
- * @std_list: Standards list
- * @input: Input routing at chip level
- * @output: Output routing at chip level
- */
-struct tvp514x_decoder {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)];
- const struct tvp514x_platform_data *pdata;
-
- int ver;
- int streaming;
-
- enum tvp514x_std current_std;
- int num_stds;
- const struct tvp514x_std_info *std_list;
- /* Input and Output Routing parameters */
- u32 input;
- u32 output;
-};
-
-/* TVP514x default register values */
-static struct tvp514x_reg tvp514x_reg_list_default[] = {
- /* Composite selected */
- {TOK_WRITE, REG_INPUT_SEL, 0x05},
- {TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F},
- /* Auto mode */
- {TOK_WRITE, REG_VIDEO_STD, 0x00},
- {TOK_WRITE, REG_OPERATION_MODE, 0x00},
- {TOK_SKIP, REG_AUTOSWITCH_MASK, 0x3F},
- {TOK_WRITE, REG_COLOR_KILLER, 0x10},
- {TOK_WRITE, REG_LUMA_CONTROL1, 0x00},
- {TOK_WRITE, REG_LUMA_CONTROL2, 0x00},
- {TOK_WRITE, REG_LUMA_CONTROL3, 0x02},
- {TOK_WRITE, REG_BRIGHTNESS, 0x80},
- {TOK_WRITE, REG_CONTRAST, 0x80},
- {TOK_WRITE, REG_SATURATION, 0x80},
- {TOK_WRITE, REG_HUE, 0x00},
- {TOK_WRITE, REG_CHROMA_CONTROL1, 0x00},
- {TOK_WRITE, REG_CHROMA_CONTROL2, 0x0E},
- /* Reserved */
- {TOK_SKIP, 0x0F, 0x00},
- {TOK_WRITE, REG_COMP_PR_SATURATION, 0x80},
- {TOK_WRITE, REG_COMP_Y_CONTRAST, 0x80},
- {TOK_WRITE, REG_COMP_PB_SATURATION, 0x80},
- /* Reserved */
- {TOK_SKIP, 0x13, 0x00},
- {TOK_WRITE, REG_COMP_Y_BRIGHTNESS, 0x80},
- /* Reserved */
- {TOK_SKIP, 0x15, 0x00},
- /* NTSC timing */
- {TOK_SKIP, REG_AVID_START_PIXEL_LSB, 0x55},
- {TOK_SKIP, REG_AVID_START_PIXEL_MSB, 0x00},
- {TOK_SKIP, REG_AVID_STOP_PIXEL_LSB, 0x25},
- {TOK_SKIP, REG_AVID_STOP_PIXEL_MSB, 0x03},
- /* NTSC timing */
- {TOK_SKIP, REG_HSYNC_START_PIXEL_LSB, 0x00},
- {TOK_SKIP, REG_HSYNC_START_PIXEL_MSB, 0x00},
- {TOK_SKIP, REG_HSYNC_STOP_PIXEL_LSB, 0x40},
- {TOK_SKIP, REG_HSYNC_STOP_PIXEL_MSB, 0x00},
- /* NTSC timing */
- {TOK_SKIP, REG_VSYNC_START_LINE_LSB, 0x04},
- {TOK_SKIP, REG_VSYNC_START_LINE_MSB, 0x00},
- {TOK_SKIP, REG_VSYNC_STOP_LINE_LSB, 0x07},
- {TOK_SKIP, REG_VSYNC_STOP_LINE_MSB, 0x00},
- /* NTSC timing */
- {TOK_SKIP, REG_VBLK_START_LINE_LSB, 0x01},
- {TOK_SKIP, REG_VBLK_START_LINE_MSB, 0x00},
- {TOK_SKIP, REG_VBLK_STOP_LINE_LSB, 0x15},
- {TOK_SKIP, REG_VBLK_STOP_LINE_MSB, 0x00},
- /* Reserved */
- {TOK_SKIP, 0x26, 0x00},
- /* Reserved */
- {TOK_SKIP, 0x27, 0x00},
- {TOK_SKIP, REG_FAST_SWTICH_CONTROL, 0xCC},
- /* Reserved */
- {TOK_SKIP, 0x29, 0x00},
- {TOK_SKIP, REG_FAST_SWTICH_SCART_DELAY, 0x00},
- /* Reserved */
- {TOK_SKIP, 0x2B, 0x00},
- {TOK_SKIP, REG_SCART_DELAY, 0x00},
- {TOK_SKIP, REG_CTI_DELAY, 0x00},
- {TOK_SKIP, REG_CTI_CONTROL, 0x00},
- /* Reserved */
- {TOK_SKIP, 0x2F, 0x00},
- /* Reserved */
- {TOK_SKIP, 0x30, 0x00},
- /* Reserved */
- {TOK_SKIP, 0x31, 0x00},
- /* HS, VS active high */
- {TOK_WRITE, REG_SYNC_CONTROL, 0x00},
- /* 10-bit BT.656 */
- {TOK_WRITE, REG_OUTPUT_FORMATTER1, 0x00},
- /* Enable clk & data */
- {TOK_WRITE, REG_OUTPUT_FORMATTER2, 0x11},
- /* Enable AVID & FLD */
- {TOK_WRITE, REG_OUTPUT_FORMATTER3, 0xEE},
- /* Enable VS & HS */
- {TOK_WRITE, REG_OUTPUT_FORMATTER4, 0xAF},
- {TOK_WRITE, REG_OUTPUT_FORMATTER5, 0xFF},
- {TOK_WRITE, REG_OUTPUT_FORMATTER6, 0xFF},
- /* Clear status */
- {TOK_WRITE, REG_CLEAR_LOST_LOCK, 0x01},
- {TOK_TERM, 0, 0},
-};
-
-/**
- * Supported standards -
- *
- * Currently supports two standards only, need to add support for rest of the
- * modes, like SECAM, etc...
- */
-static const struct tvp514x_std_info tvp514x_std_list[] = {
- /* Standard: STD_NTSC_MJ */
- [STD_NTSC_MJ] = {
- .width = NTSC_NUM_ACTIVE_PIXELS,
- .height = NTSC_NUM_ACTIVE_LINES,
- .video_std = VIDEO_STD_NTSC_MJ_BIT,
- .standard = {
- .index = 0,
- .id = V4L2_STD_NTSC,
- .name = "NTSC",
- .frameperiod = {1001, 30000},
- .framelines = 525
- },
- /* Standard: STD_PAL_BDGHIN */
- },
- [STD_PAL_BDGHIN] = {
- .width = PAL_NUM_ACTIVE_PIXELS,
- .height = PAL_NUM_ACTIVE_LINES,
- .video_std = VIDEO_STD_PAL_BDGHIN_BIT,
- .standard = {
- .index = 1,
- .id = V4L2_STD_PAL,
- .name = "PAL",
- .frameperiod = {1, 25},
- .framelines = 625
- },
- },
- /* Standard: need to add for additional standard */
-};
-
-
-static inline struct tvp514x_decoder *to_decoder(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct tvp514x_decoder, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct tvp514x_decoder, hdl)->sd;
-}
-
-
-/**
- * tvp514x_read_reg() - Read a value from a register in an TVP5146/47.
- * @sd: ptr to v4l2_subdev struct
- * @reg: TVP5146/47 register address
- *
- * Returns value read if successful, or non-zero (-1) otherwise.
- */
-static int tvp514x_read_reg(struct v4l2_subdev *sd, u8 reg)
-{
- int err, retry = 0;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-read_again:
-
- err = i2c_smbus_read_byte_data(client, reg);
- if (err < 0) {
- if (retry <= I2C_RETRY_COUNT) {
- v4l2_warn(sd, "Read: retry ... %d\n", retry);
- retry++;
- msleep_interruptible(10);
- goto read_again;
- }
- }
-
- return err;
-}
-
-/**
- * dump_reg() - dump the register content of TVP5146/47.
- * @sd: ptr to v4l2_subdev struct
- * @reg: TVP5146/47 register address
- */
-static void dump_reg(struct v4l2_subdev *sd, u8 reg)
-{
- u32 val;
-
- val = tvp514x_read_reg(sd, reg);
- v4l2_info(sd, "Reg(0x%.2X): 0x%.2X\n", reg, val);
-}
-
-/**
- * tvp514x_write_reg() - Write a value to a register in TVP5146/47
- * @sd: ptr to v4l2_subdev struct
- * @reg: TVP5146/47 register address
- * @val: value to be written to the register
- *
- * Write a value to a register in an TVP5146/47 decoder device.
- * Returns zero if successful, or non-zero otherwise.
- */
-static int tvp514x_write_reg(struct v4l2_subdev *sd, u8 reg, u8 val)
-{
- int err, retry = 0;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-write_again:
-
- err = i2c_smbus_write_byte_data(client, reg, val);
- if (err) {
- if (retry <= I2C_RETRY_COUNT) {
- v4l2_warn(sd, "Write: retry ... %d\n", retry);
- retry++;
- msleep_interruptible(10);
- goto write_again;
- }
- }
-
- return err;
-}
-
-/**
- * tvp514x_write_regs() : Initializes a list of TVP5146/47 registers
- * @sd: ptr to v4l2_subdev struct
- * @reglist: list of TVP5146/47 registers and values
- *
- * Initializes a list of TVP5146/47 registers:-
- * if token is TOK_TERM, then entire write operation terminates
- * if token is TOK_DELAY, then a delay of 'val' msec is introduced
- * if token is TOK_SKIP, then the register write is skipped
- * if token is TOK_WRITE, then the register write is performed
- * Returns zero if successful, or non-zero otherwise.
- */
-static int tvp514x_write_regs(struct v4l2_subdev *sd,
- const struct tvp514x_reg reglist[])
-{
- int err;
- const struct tvp514x_reg *next = reglist;
-
- for (; next->token != TOK_TERM; next++) {
- if (next->token == TOK_DELAY) {
- msleep(next->val);
- continue;
- }
-
- if (next->token == TOK_SKIP)
- continue;
-
- err = tvp514x_write_reg(sd, next->reg, (u8) next->val);
- if (err) {
- v4l2_err(sd, "Write failed. Err[%d]\n", err);
- return err;
- }
- }
- return 0;
-}
-
-/**
- * tvp514x_query_current_std() : Query the current standard detected by TVP5146/47
- * @sd: ptr to v4l2_subdev struct
- *
- * Returns the current standard detected by TVP5146/47, STD_INVALID if there is no
- * standard detected.
- */
-static enum tvp514x_std tvp514x_query_current_std(struct v4l2_subdev *sd)
-{
- u8 std, std_status;
-
- std = tvp514x_read_reg(sd, REG_VIDEO_STD);
- if ((std & VIDEO_STD_MASK) == VIDEO_STD_AUTO_SWITCH_BIT)
- /* use the standard status register */
- std_status = tvp514x_read_reg(sd, REG_VIDEO_STD_STATUS);
- else
- /* use the standard register itself */
- std_status = std;
-
- switch (std_status & VIDEO_STD_MASK) {
- case VIDEO_STD_NTSC_MJ_BIT:
- return STD_NTSC_MJ;
-
- case VIDEO_STD_PAL_BDGHIN_BIT:
- return STD_PAL_BDGHIN;
-
- default:
- return STD_INVALID;
- }
-
- return STD_INVALID;
-}
-
-/* TVP5146/47 register dump function */
-static void tvp514x_reg_dump(struct v4l2_subdev *sd)
-{
- dump_reg(sd, REG_INPUT_SEL);
- dump_reg(sd, REG_AFE_GAIN_CTRL);
- dump_reg(sd, REG_VIDEO_STD);
- dump_reg(sd, REG_OPERATION_MODE);
- dump_reg(sd, REG_COLOR_KILLER);
- dump_reg(sd, REG_LUMA_CONTROL1);
- dump_reg(sd, REG_LUMA_CONTROL2);
- dump_reg(sd, REG_LUMA_CONTROL3);
- dump_reg(sd, REG_BRIGHTNESS);
- dump_reg(sd, REG_CONTRAST);
- dump_reg(sd, REG_SATURATION);
- dump_reg(sd, REG_HUE);
- dump_reg(sd, REG_CHROMA_CONTROL1);
- dump_reg(sd, REG_CHROMA_CONTROL2);
- dump_reg(sd, REG_COMP_PR_SATURATION);
- dump_reg(sd, REG_COMP_Y_CONTRAST);
- dump_reg(sd, REG_COMP_PB_SATURATION);
- dump_reg(sd, REG_COMP_Y_BRIGHTNESS);
- dump_reg(sd, REG_AVID_START_PIXEL_LSB);
- dump_reg(sd, REG_AVID_START_PIXEL_MSB);
- dump_reg(sd, REG_AVID_STOP_PIXEL_LSB);
- dump_reg(sd, REG_AVID_STOP_PIXEL_MSB);
- dump_reg(sd, REG_HSYNC_START_PIXEL_LSB);
- dump_reg(sd, REG_HSYNC_START_PIXEL_MSB);
- dump_reg(sd, REG_HSYNC_STOP_PIXEL_LSB);
- dump_reg(sd, REG_HSYNC_STOP_PIXEL_MSB);
- dump_reg(sd, REG_VSYNC_START_LINE_LSB);
- dump_reg(sd, REG_VSYNC_START_LINE_MSB);
- dump_reg(sd, REG_VSYNC_STOP_LINE_LSB);
- dump_reg(sd, REG_VSYNC_STOP_LINE_MSB);
- dump_reg(sd, REG_VBLK_START_LINE_LSB);
- dump_reg(sd, REG_VBLK_START_LINE_MSB);
- dump_reg(sd, REG_VBLK_STOP_LINE_LSB);
- dump_reg(sd, REG_VBLK_STOP_LINE_MSB);
- dump_reg(sd, REG_SYNC_CONTROL);
- dump_reg(sd, REG_OUTPUT_FORMATTER1);
- dump_reg(sd, REG_OUTPUT_FORMATTER2);
- dump_reg(sd, REG_OUTPUT_FORMATTER3);
- dump_reg(sd, REG_OUTPUT_FORMATTER4);
- dump_reg(sd, REG_OUTPUT_FORMATTER5);
- dump_reg(sd, REG_OUTPUT_FORMATTER6);
- dump_reg(sd, REG_CLEAR_LOST_LOCK);
-}
-
-/**
- * tvp514x_configure() - Configure the TVP5146/47 registers
- * @sd: ptr to v4l2_subdev struct
- * @decoder: ptr to tvp514x_decoder structure
- *
- * Returns zero if successful, or non-zero otherwise.
- */
-static int tvp514x_configure(struct v4l2_subdev *sd,
- struct tvp514x_decoder *decoder)
-{
- int err;
-
- /* common register initialization */
- err =
- tvp514x_write_regs(sd, decoder->tvp514x_regs);
- if (err)
- return err;
-
- if (debug)
- tvp514x_reg_dump(sd);
-
- return 0;
-}
-
-/**
- * tvp514x_detect() - Detect if an tvp514x is present, and if so which revision.
- * @sd: pointer to standard V4L2 sub-device structure
- * @decoder: pointer to tvp514x_decoder structure
- *
- * A device is considered to be detected if the chip ID (LSB and MSB)
- * registers match the expected values.
- * Any value of the rom version register is accepted.
- * Returns ENODEV error number if no device is detected, or zero
- * if a device is detected.
- */
-static int tvp514x_detect(struct v4l2_subdev *sd,
- struct tvp514x_decoder *decoder)
-{
- u8 chip_id_msb, chip_id_lsb, rom_ver;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- chip_id_msb = tvp514x_read_reg(sd, REG_CHIP_ID_MSB);
- chip_id_lsb = tvp514x_read_reg(sd, REG_CHIP_ID_LSB);
- rom_ver = tvp514x_read_reg(sd, REG_ROM_VERSION);
-
- v4l2_dbg(1, debug, sd,
- "chip id detected msb:0x%x lsb:0x%x rom version:0x%x\n",
- chip_id_msb, chip_id_lsb, rom_ver);
- if ((chip_id_msb != TVP514X_CHIP_ID_MSB)
- || ((chip_id_lsb != TVP5146_CHIP_ID_LSB)
- && (chip_id_lsb != TVP5147_CHIP_ID_LSB))) {
- /* We didn't read the values we expected, so this must not be
- * an TVP5146/47.
- */
- v4l2_err(sd, "chip id mismatch msb:0x%x lsb:0x%x\n",
- chip_id_msb, chip_id_lsb);
- return -ENODEV;
- }
-
- decoder->ver = rom_ver;
-
- v4l2_info(sd, "%s (Version - 0x%.2x) found at 0x%x (%s)\n",
- client->name, decoder->ver,
- client->addr << 1, client->adapter->name);
- return 0;
-}
-
-/**
- * tvp514x_querystd() - V4L2 decoder interface handler for querystd
- * @sd: pointer to standard V4L2 sub-device structure
- * @std_id: standard V4L2 std_id ioctl enum
- *
- * Returns the current standard detected by TVP5146/47. If no active input is
- * detected then *std_id is set to 0 and the function returns 0.
- */
-static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id)
-{
- struct tvp514x_decoder *decoder = to_decoder(sd);
- enum tvp514x_std current_std;
- enum tvp514x_input input_sel;
- u8 sync_lock_status, lock_mask;
-
- if (std_id == NULL)
- return -EINVAL;
-
- *std_id = V4L2_STD_UNKNOWN;
-
- /* query the current standard */
- current_std = tvp514x_query_current_std(sd);
- if (current_std == STD_INVALID)
- return 0;
-
- input_sel = decoder->input;
-
- switch (input_sel) {
- case INPUT_CVBS_VI1A:
- case INPUT_CVBS_VI1B:
- case INPUT_CVBS_VI1C:
- case INPUT_CVBS_VI2A:
- case INPUT_CVBS_VI2B:
- case INPUT_CVBS_VI2C:
- case INPUT_CVBS_VI3A:
- case INPUT_CVBS_VI3B:
- case INPUT_CVBS_VI3C:
- case INPUT_CVBS_VI4A:
- lock_mask = STATUS_CLR_SUBCAR_LOCK_BIT |
- STATUS_HORZ_SYNC_LOCK_BIT |
- STATUS_VIRT_SYNC_LOCK_BIT;
- break;
-
- case INPUT_SVIDEO_VI2A_VI1A:
- case INPUT_SVIDEO_VI2B_VI1B:
- case INPUT_SVIDEO_VI2C_VI1C:
- case INPUT_SVIDEO_VI2A_VI3A:
- case INPUT_SVIDEO_VI2B_VI3B:
- case INPUT_SVIDEO_VI2C_VI3C:
- case INPUT_SVIDEO_VI4A_VI1A:
- case INPUT_SVIDEO_VI4A_VI1B:
- case INPUT_SVIDEO_VI4A_VI1C:
- case INPUT_SVIDEO_VI4A_VI3A:
- case INPUT_SVIDEO_VI4A_VI3B:
- case INPUT_SVIDEO_VI4A_VI3C:
- lock_mask = STATUS_HORZ_SYNC_LOCK_BIT |
- STATUS_VIRT_SYNC_LOCK_BIT;
- break;
- /*Need to add other interfaces*/
- default:
- return -EINVAL;
- }
- /* check whether signal is locked */
- sync_lock_status = tvp514x_read_reg(sd, REG_STATUS1);
- if (lock_mask != (sync_lock_status & lock_mask))
- return 0; /* No input detected */
-
- *std_id = decoder->std_list[current_std].standard.id;
-
- v4l2_dbg(1, debug, sd, "Current STD: %s\n",
- decoder->std_list[current_std].standard.name);
- return 0;
-}
-
-/**
- * tvp514x_s_std() - V4L2 decoder interface handler for s_std
- * @sd: pointer to standard V4L2 sub-device structure
- * @std_id: standard V4L2 v4l2_std_id ioctl enum
- *
- * If std_id is supported, sets the requested standard. Otherwise, returns
- * -EINVAL
- */
-static int tvp514x_s_std(struct v4l2_subdev *sd, v4l2_std_id std_id)
-{
- struct tvp514x_decoder *decoder = to_decoder(sd);
- int err, i;
-
- for (i = 0; i < decoder->num_stds; i++)
- if (std_id & decoder->std_list[i].standard.id)
- break;
-
- if ((i == decoder->num_stds) || (i == STD_INVALID))
- return -EINVAL;
-
- err = tvp514x_write_reg(sd, REG_VIDEO_STD,
- decoder->std_list[i].video_std);
- if (err)
- return err;
-
- decoder->current_std = i;
- decoder->tvp514x_regs[REG_VIDEO_STD].val =
- decoder->std_list[i].video_std;
-
- v4l2_dbg(1, debug, sd, "Standard set to: %s\n",
- decoder->std_list[i].standard.name);
- return 0;
-}
-
-/**
- * tvp514x_s_routing() - V4L2 decoder interface handler for s_routing
- * @sd: pointer to standard V4L2 sub-device structure
- * @input: input selector for routing the signal
- * @output: output selector for routing the signal
- * @config: config value. Not used
- *
- * If index is valid, selects the requested input. Otherwise, returns -EINVAL if
- * the input is not supported or there is no active signal present in the
- * selected input.
- */
-static int tvp514x_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct tvp514x_decoder *decoder = to_decoder(sd);
- int err;
- enum tvp514x_input input_sel;
- enum tvp514x_output output_sel;
- u8 sync_lock_status, lock_mask;
- int try_count = LOCK_RETRY_COUNT;
-
- if ((input >= INPUT_INVALID) ||
- (output >= OUTPUT_INVALID))
- /* Index out of bound */
- return -EINVAL;
-
- /*
- * For the sequence streamon -> streamoff and again s_input
- * it fails to lock the signal, since streamoff puts TVP514x
- * into power off state which leads to failure in sub-sequent s_input.
- *
- * So power up the TVP514x device here, since it is important to lock
- * the signal at this stage.
- */
- if (!decoder->streaming)
- tvp514x_s_stream(sd, 1);
-
- input_sel = input;
- output_sel = output;
-
- err = tvp514x_write_reg(sd, REG_INPUT_SEL, input_sel);
- if (err)
- return err;
-
- output_sel |= tvp514x_read_reg(sd,
- REG_OUTPUT_FORMATTER1) & 0x7;
- err = tvp514x_write_reg(sd, REG_OUTPUT_FORMATTER1,
- output_sel);
- if (err)
- return err;
-
- decoder->tvp514x_regs[REG_INPUT_SEL].val = input_sel;
- decoder->tvp514x_regs[REG_OUTPUT_FORMATTER1].val = output_sel;
-
- /* Clear status */
- msleep(LOCK_RETRY_DELAY);
- err =
- tvp514x_write_reg(sd, REG_CLEAR_LOST_LOCK, 0x01);
- if (err)
- return err;
-
- switch (input_sel) {
- case INPUT_CVBS_VI1A:
- case INPUT_CVBS_VI1B:
- case INPUT_CVBS_VI1C:
- case INPUT_CVBS_VI2A:
- case INPUT_CVBS_VI2B:
- case INPUT_CVBS_VI2C:
- case INPUT_CVBS_VI3A:
- case INPUT_CVBS_VI3B:
- case INPUT_CVBS_VI3C:
- case INPUT_CVBS_VI4A:
- lock_mask = STATUS_CLR_SUBCAR_LOCK_BIT |
- STATUS_HORZ_SYNC_LOCK_BIT |
- STATUS_VIRT_SYNC_LOCK_BIT;
- break;
-
- case INPUT_SVIDEO_VI2A_VI1A:
- case INPUT_SVIDEO_VI2B_VI1B:
- case INPUT_SVIDEO_VI2C_VI1C:
- case INPUT_SVIDEO_VI2A_VI3A:
- case INPUT_SVIDEO_VI2B_VI3B:
- case INPUT_SVIDEO_VI2C_VI3C:
- case INPUT_SVIDEO_VI4A_VI1A:
- case INPUT_SVIDEO_VI4A_VI1B:
- case INPUT_SVIDEO_VI4A_VI1C:
- case INPUT_SVIDEO_VI4A_VI3A:
- case INPUT_SVIDEO_VI4A_VI3B:
- case INPUT_SVIDEO_VI4A_VI3C:
- lock_mask = STATUS_HORZ_SYNC_LOCK_BIT |
- STATUS_VIRT_SYNC_LOCK_BIT;
- break;
- /* Need to add other interfaces*/
- default:
- return -EINVAL;
- }
-
- while (try_count-- > 0) {
- /* Allow decoder to sync up with new input */
- msleep(LOCK_RETRY_DELAY);
-
- sync_lock_status = tvp514x_read_reg(sd,
- REG_STATUS1);
- if (lock_mask == (sync_lock_status & lock_mask))
- /* Input detected */
- break;
- }
-
- if (try_count < 0)
- return -EINVAL;
-
- decoder->input = input;
- decoder->output = output;
-
- v4l2_dbg(1, debug, sd, "Input set to: %d\n", input_sel);
-
- return 0;
-}
-
-/**
- * tvp514x_s_ctrl() - V4L2 decoder interface handler for s_ctrl
- * @ctrl: pointer to v4l2_ctrl structure
- *
- * If the requested control is supported, sets the control's current
- * value in HW. Otherwise, returns -EINVAL if the control is not supported.
- */
-static int tvp514x_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct tvp514x_decoder *decoder = to_decoder(sd);
- int err = -EINVAL, value;
-
- value = ctrl->val;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- err = tvp514x_write_reg(sd, REG_BRIGHTNESS, value);
- if (!err)
- decoder->tvp514x_regs[REG_BRIGHTNESS].val = value;
- break;
- case V4L2_CID_CONTRAST:
- err = tvp514x_write_reg(sd, REG_CONTRAST, value);
- if (!err)
- decoder->tvp514x_regs[REG_CONTRAST].val = value;
- break;
- case V4L2_CID_SATURATION:
- err = tvp514x_write_reg(sd, REG_SATURATION, value);
- if (!err)
- decoder->tvp514x_regs[REG_SATURATION].val = value;
- break;
- case V4L2_CID_HUE:
- if (value == 180)
- value = 0x7F;
- else if (value == -180)
- value = 0x80;
- err = tvp514x_write_reg(sd, REG_HUE, value);
- if (!err)
- decoder->tvp514x_regs[REG_HUE].val = value;
- break;
- case V4L2_CID_AUTOGAIN:
- err = tvp514x_write_reg(sd, REG_AFE_GAIN_CTRL, value ? 0x0f : 0x0c);
- if (!err)
- decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value;
- break;
- }
-
- v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d\n",
- ctrl->id, ctrl->val);
- return err;
-}
-
-/**
- * tvp514x_enum_mbus_fmt() - V4L2 decoder interface handler for enum_mbus_fmt
- * @sd: pointer to standard V4L2 sub-device structure
- * @index: index of pixelcode to retrieve
- * @code: receives the pixelcode
- *
- * Enumerates supported mediabus formats
- */
-static int
-tvp514x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index)
- return -EINVAL;
-
- *code = V4L2_MBUS_FMT_YUYV10_2X10;
- return 0;
-}
-
-/**
- * tvp514x_mbus_fmt_cap() - V4L2 decoder interface handler for try/s/g_mbus_fmt
- * @sd: pointer to standard V4L2 sub-device structure
- * @f: pointer to the mediabus format structure
- *
- * Negotiates the image capture size and mediabus format.
- */
-static int
-tvp514x_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
-{
- struct tvp514x_decoder *decoder = to_decoder(sd);
- enum tvp514x_std current_std;
-
- if (f == NULL)
- return -EINVAL;
-
- /* Calculate height and width based on current standard */
- current_std = decoder->current_std;
-
- f->code = V4L2_MBUS_FMT_YUYV10_2X10;
- f->width = decoder->std_list[current_std].width;
- f->height = decoder->std_list[current_std].height;
- f->field = V4L2_FIELD_INTERLACED;
- f->colorspace = V4L2_COLORSPACE_SMPTE170M;
-
- v4l2_dbg(1, debug, sd, "MBUS_FMT: Width - %d, Height - %d\n",
- f->width, f->height);
- return 0;
-}
-
-/**
- * tvp514x_g_parm() - V4L2 decoder interface handler for g_parm
- * @sd: pointer to standard V4L2 sub-device structure
- * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
- *
- * Returns the decoder's video CAPTURE parameters.
- */
-static int
-tvp514x_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
-{
- struct tvp514x_decoder *decoder = to_decoder(sd);
- struct v4l2_captureparm *cparm;
- enum tvp514x_std current_std;
-
- if (a == NULL)
- return -EINVAL;
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- /* only capture is supported */
- return -EINVAL;
-
- /* get the current standard */
- current_std = decoder->current_std;
-
- cparm = &a->parm.capture;
- cparm->capability = V4L2_CAP_TIMEPERFRAME;
- cparm->timeperframe =
- decoder->std_list[current_std].standard.frameperiod;
-
- return 0;
-}
-
-/**
- * tvp514x_s_parm() - V4L2 decoder interface handler for s_parm
- * @sd: pointer to standard V4L2 sub-device structure
- * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
- *
- * Configures the decoder to use the input parameters, if possible. If
- * not possible, returns the appropriate error code.
- */
-static int
-tvp514x_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
-{
- struct tvp514x_decoder *decoder = to_decoder(sd);
- struct v4l2_fract *timeperframe;
- enum tvp514x_std current_std;
-
- if (a == NULL)
- return -EINVAL;
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- /* only capture is supported */
- return -EINVAL;
-
- timeperframe = &a->parm.capture.timeperframe;
-
- /* get the current standard */
- current_std = decoder->current_std;
-
- *timeperframe =
- decoder->std_list[current_std].standard.frameperiod;
-
- return 0;
-}
-
-/**
- * tvp514x_s_stream() - V4L2 decoder i/f handler for s_stream
- * @sd: pointer to standard V4L2 sub-device structure
- * @enable: streaming enable or disable
- *
- * Sets streaming to enable or disable, if possible.
- */
-static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable)
-{
- int err = 0;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tvp514x_decoder *decoder = to_decoder(sd);
-
- if (decoder->streaming == enable)
- return 0;
-
- switch (enable) {
- case 0:
- {
- /* Power Down Sequence */
- err = tvp514x_write_reg(sd, REG_OPERATION_MODE, 0x01);
- if (err) {
- v4l2_err(sd, "Unable to turn off decoder\n");
- return err;
- }
- decoder->streaming = enable;
- break;
- }
- case 1:
- {
- struct tvp514x_reg *int_seq = (struct tvp514x_reg *)
- client->driver->id_table->driver_data;
-
- /* Power Up Sequence */
- err = tvp514x_write_regs(sd, int_seq);
- if (err) {
- v4l2_err(sd, "Unable to turn on decoder\n");
- return err;
- }
- /* Detect if not already detected */
- err = tvp514x_detect(sd, decoder);
- if (err) {
- v4l2_err(sd, "Unable to detect decoder\n");
- return err;
- }
- err = tvp514x_configure(sd, decoder);
- if (err) {
- v4l2_err(sd, "Unable to configure decoder\n");
- return err;
- }
- decoder->streaming = enable;
- break;
- }
- default:
- err = -ENODEV;
- break;
- }
-
- return err;
-}
-
-static const struct v4l2_ctrl_ops tvp514x_ctrl_ops = {
- .s_ctrl = tvp514x_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops tvp514x_core_ops = {
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
- .s_std = tvp514x_s_std,
-};
-
-static const struct v4l2_subdev_video_ops tvp514x_video_ops = {
- .s_routing = tvp514x_s_routing,
- .querystd = tvp514x_querystd,
- .enum_mbus_fmt = tvp514x_enum_mbus_fmt,
- .g_mbus_fmt = tvp514x_mbus_fmt,
- .try_mbus_fmt = tvp514x_mbus_fmt,
- .s_mbus_fmt = tvp514x_mbus_fmt,
- .g_parm = tvp514x_g_parm,
- .s_parm = tvp514x_s_parm,
- .s_stream = tvp514x_s_stream,
-};
-
-static const struct v4l2_subdev_ops tvp514x_ops = {
- .core = &tvp514x_core_ops,
- .video = &tvp514x_video_ops,
-};
-
-static struct tvp514x_decoder tvp514x_dev = {
- .streaming = 0,
- .current_std = STD_NTSC_MJ,
- .std_list = tvp514x_std_list,
- .num_stds = ARRAY_SIZE(tvp514x_std_list),
-
-};
-
-/**
- * tvp514x_probe() - decoder driver i2c probe handler
- * @client: i2c driver client device structure
- * @id: i2c driver id table
- *
- * Register decoder as an i2c client device and V4L2
- * device.
- */
-static int
-tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
- struct tvp514x_decoder *decoder;
- struct v4l2_subdev *sd;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- if (!client->dev.platform_data) {
- v4l2_err(client, "No platform data!!\n");
- return -ENODEV;
- }
-
- decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
- if (!decoder)
- return -ENOMEM;
-
- /* Initialize the tvp514x_decoder with default configuration */
- *decoder = tvp514x_dev;
- /* Copy default register configuration */
- memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default,
- sizeof(tvp514x_reg_list_default));
-
- /* Copy board specific information here */
- decoder->pdata = client->dev.platform_data;
-
- /**
- * Fetch platform specific data, and configure the
- * tvp514x_reg_list[] accordingly. Since this is one
- * time configuration, no need to preserve.
- */
- decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |=
- (decoder->pdata->clk_polarity << 1);
- decoder->tvp514x_regs[REG_SYNC_CONTROL].val |=
- ((decoder->pdata->hs_polarity << 2) |
- (decoder->pdata->vs_polarity << 3));
- /* Set default standard to auto */
- decoder->tvp514x_regs[REG_VIDEO_STD].val =
- VIDEO_STD_AUTO_SWITCH_BIT;
-
- /* Register with V4L2 layer as slave device */
- sd = &decoder->sd;
- v4l2_i2c_subdev_init(sd, client, &tvp514x_ops);
-
- v4l2_ctrl_handler_init(&decoder->hdl, 5);
- v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
- V4L2_CID_HUE, -180, 180, 180, 0);
- v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- sd->ctrl_handler = &decoder->hdl;
- if (decoder->hdl.error) {
- int err = decoder->hdl.error;
-
- v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(decoder);
- return err;
- }
- v4l2_ctrl_handler_setup(&decoder->hdl);
-
- v4l2_info(sd, "%s decoder driver registered !!\n", sd->name);
-
- return 0;
-
-}
-
-/**
- * tvp514x_remove() - decoder driver i2c remove handler
- * @client: i2c driver client device structure
- *
- * Unregister decoder as an i2c client device and V4L2
- * device. Complement of tvp514x_probe().
- */
-static int tvp514x_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct tvp514x_decoder *decoder = to_decoder(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(decoder);
- return 0;
-}
-/* TVP5146 Init/Power on Sequence */
-static const struct tvp514x_reg tvp5146_init_reg_seq[] = {
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0x80},
- {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
- {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
- {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
- {TOK_WRITE, REG_OPERATION_MODE, 0x01},
- {TOK_WRITE, REG_OPERATION_MODE, 0x00},
- {TOK_TERM, 0, 0},
-};
-
-/* TVP5147 Init/Power on Sequence */
-static const struct tvp514x_reg tvp5147_init_reg_seq[] = {
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0x80},
- {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
- {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x16},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xA0},
- {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x16},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
- {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
- {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
- {TOK_WRITE, REG_OPERATION_MODE, 0x01},
- {TOK_WRITE, REG_OPERATION_MODE, 0x00},
- {TOK_TERM, 0, 0},
-};
-
-/* TVP5146M2/TVP5147M1 Init/Power on Sequence */
-static const struct tvp514x_reg tvp514xm_init_reg_seq[] = {
- {TOK_WRITE, REG_OPERATION_MODE, 0x01},
- {TOK_WRITE, REG_OPERATION_MODE, 0x00},
- {TOK_TERM, 0, 0},
-};
-
-/**
- * I2C Device Table -
- *
- * name - Name of the actual device/chip.
- * driver_data - Driver data
- */
-static const struct i2c_device_id tvp514x_id[] = {
- {"tvp5146", (unsigned long)tvp5146_init_reg_seq},
- {"tvp5146m2", (unsigned long)tvp514xm_init_reg_seq},
- {"tvp5147", (unsigned long)tvp5147_init_reg_seq},
- {"tvp5147m1", (unsigned long)tvp514xm_init_reg_seq},
- {},
-};
-
-MODULE_DEVICE_TABLE(i2c, tvp514x_id);
-
-static struct i2c_driver tvp514x_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = TVP514X_MODULE_NAME,
- },
- .probe = tvp514x_probe,
- .remove = tvp514x_remove,
- .id_table = tvp514x_id,
-};
-
-module_i2c_driver(tvp514x_driver);
diff --git a/drivers/media/video/tvp514x_regs.h b/drivers/media/video/tvp514x_regs.h
deleted file mode 100644
index 18f29ad0dfe..00000000000
--- a/drivers/media/video/tvp514x_regs.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * drivers/media/video/tvp514x_regs.h
- *
- * Copyright (C) 2008 Texas Instruments Inc
- * Author: Vaibhav Hiremath <hvaibhav@ti.com>
- *
- * Contributors:
- * Sivaraj R <sivaraj@ti.com>
- * Brijesh R Jadav <brijesh.j@ti.com>
- * Hardik Shah <hardik.shah@ti.com>
- * Manjunath Hadli <mrh@ti.com>
- * Karicheri Muralidharan <m-karicheri2@ti.com>
- *
- * This package is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef _TVP514X_REGS_H
-#define _TVP514X_REGS_H
-
-/*
- * TVP5146/47 registers
- */
-#define REG_INPUT_SEL (0x00)
-#define REG_AFE_GAIN_CTRL (0x01)
-#define REG_VIDEO_STD (0x02)
-#define REG_OPERATION_MODE (0x03)
-#define REG_AUTOSWITCH_MASK (0x04)
-
-#define REG_COLOR_KILLER (0x05)
-#define REG_LUMA_CONTROL1 (0x06)
-#define REG_LUMA_CONTROL2 (0x07)
-#define REG_LUMA_CONTROL3 (0x08)
-
-#define REG_BRIGHTNESS (0x09)
-#define REG_CONTRAST (0x0A)
-#define REG_SATURATION (0x0B)
-#define REG_HUE (0x0C)
-
-#define REG_CHROMA_CONTROL1 (0x0D)
-#define REG_CHROMA_CONTROL2 (0x0E)
-
-/* 0x0F Reserved */
-
-#define REG_COMP_PR_SATURATION (0x10)
-#define REG_COMP_Y_CONTRAST (0x11)
-#define REG_COMP_PB_SATURATION (0x12)
-
-/* 0x13 Reserved */
-
-#define REG_COMP_Y_BRIGHTNESS (0x14)
-
-/* 0x15 Reserved */
-
-#define REG_AVID_START_PIXEL_LSB (0x16)
-#define REG_AVID_START_PIXEL_MSB (0x17)
-#define REG_AVID_STOP_PIXEL_LSB (0x18)
-#define REG_AVID_STOP_PIXEL_MSB (0x19)
-
-#define REG_HSYNC_START_PIXEL_LSB (0x1A)
-#define REG_HSYNC_START_PIXEL_MSB (0x1B)
-#define REG_HSYNC_STOP_PIXEL_LSB (0x1C)
-#define REG_HSYNC_STOP_PIXEL_MSB (0x1D)
-
-#define REG_VSYNC_START_LINE_LSB (0x1E)
-#define REG_VSYNC_START_LINE_MSB (0x1F)
-#define REG_VSYNC_STOP_LINE_LSB (0x20)
-#define REG_VSYNC_STOP_LINE_MSB (0x21)
-
-#define REG_VBLK_START_LINE_LSB (0x22)
-#define REG_VBLK_START_LINE_MSB (0x23)
-#define REG_VBLK_STOP_LINE_LSB (0x24)
-#define REG_VBLK_STOP_LINE_MSB (0x25)
-
-/* 0x26 - 0x27 Reserved */
-
-#define REG_FAST_SWTICH_CONTROL (0x28)
-
-/* 0x29 Reserved */
-
-#define REG_FAST_SWTICH_SCART_DELAY (0x2A)
-
-/* 0x2B Reserved */
-
-#define REG_SCART_DELAY (0x2C)
-#define REG_CTI_DELAY (0x2D)
-#define REG_CTI_CONTROL (0x2E)
-
-/* 0x2F - 0x31 Reserved */
-
-#define REG_SYNC_CONTROL (0x32)
-#define REG_OUTPUT_FORMATTER1 (0x33)
-#define REG_OUTPUT_FORMATTER2 (0x34)
-#define REG_OUTPUT_FORMATTER3 (0x35)
-#define REG_OUTPUT_FORMATTER4 (0x36)
-#define REG_OUTPUT_FORMATTER5 (0x37)
-#define REG_OUTPUT_FORMATTER6 (0x38)
-#define REG_CLEAR_LOST_LOCK (0x39)
-
-#define REG_STATUS1 (0x3A)
-#define REG_STATUS2 (0x3B)
-
-#define REG_AGC_GAIN_STATUS_LSB (0x3C)
-#define REG_AGC_GAIN_STATUS_MSB (0x3D)
-
-/* 0x3E Reserved */
-
-#define REG_VIDEO_STD_STATUS (0x3F)
-#define REG_GPIO_INPUT1 (0x40)
-#define REG_GPIO_INPUT2 (0x41)
-
-/* 0x42 - 0x45 Reserved */
-
-#define REG_AFE_COARSE_GAIN_CH1 (0x46)
-#define REG_AFE_COARSE_GAIN_CH2 (0x47)
-#define REG_AFE_COARSE_GAIN_CH3 (0x48)
-#define REG_AFE_COARSE_GAIN_CH4 (0x49)
-
-#define REG_AFE_FINE_GAIN_PB_B_LSB (0x4A)
-#define REG_AFE_FINE_GAIN_PB_B_MSB (0x4B)
-#define REG_AFE_FINE_GAIN_Y_G_CHROMA_LSB (0x4C)
-#define REG_AFE_FINE_GAIN_Y_G_CHROMA_MSB (0x4D)
-#define REG_AFE_FINE_GAIN_PR_R_LSB (0x4E)
-#define REG_AFE_FINE_GAIN_PR_R_MSB (0x4F)
-#define REG_AFE_FINE_GAIN_CVBS_LUMA_LSB (0x50)
-#define REG_AFE_FINE_GAIN_CVBS_LUMA_MSB (0x51)
-
-/* 0x52 - 0x68 Reserved */
-
-#define REG_FBIT_VBIT_CONTROL1 (0x69)
-
-/* 0x6A - 0x6B Reserved */
-
-#define REG_BACKEND_AGC_CONTROL (0x6C)
-
-/* 0x6D - 0x6E Reserved */
-
-#define REG_AGC_DECREMENT_SPEED_CONTROL (0x6F)
-#define REG_ROM_VERSION (0x70)
-
-/* 0x71 - 0x73 Reserved */
-
-#define REG_AGC_WHITE_PEAK_PROCESSING (0x74)
-#define REG_FBIT_VBIT_CONTROL2 (0x75)
-#define REG_VCR_TRICK_MODE_CONTROL (0x76)
-#define REG_HORIZONTAL_SHAKE_INCREMENT (0x77)
-#define REG_AGC_INCREMENT_SPEED (0x78)
-#define REG_AGC_INCREMENT_DELAY (0x79)
-
-/* 0x7A - 0x7F Reserved */
-
-#define REG_CHIP_ID_MSB (0x80)
-#define REG_CHIP_ID_LSB (0x81)
-
-/* 0x82 Reserved */
-
-#define REG_CPLL_SPEED_CONTROL (0x83)
-
-/* 0x84 - 0x96 Reserved */
-
-#define REG_STATUS_REQUEST (0x97)
-
-/* 0x98 - 0x99 Reserved */
-
-#define REG_VERTICAL_LINE_COUNT_LSB (0x9A)
-#define REG_VERTICAL_LINE_COUNT_MSB (0x9B)
-
-/* 0x9C - 0x9D Reserved */
-
-#define REG_AGC_DECREMENT_DELAY (0x9E)
-
-/* 0x9F - 0xB0 Reserved */
-
-#define REG_VDP_TTX_FILTER_1_MASK1 (0xB1)
-#define REG_VDP_TTX_FILTER_1_MASK2 (0xB2)
-#define REG_VDP_TTX_FILTER_1_MASK3 (0xB3)
-#define REG_VDP_TTX_FILTER_1_MASK4 (0xB4)
-#define REG_VDP_TTX_FILTER_1_MASK5 (0xB5)
-#define REG_VDP_TTX_FILTER_2_MASK1 (0xB6)
-#define REG_VDP_TTX_FILTER_2_MASK2 (0xB7)
-#define REG_VDP_TTX_FILTER_2_MASK3 (0xB8)
-#define REG_VDP_TTX_FILTER_2_MASK4 (0xB9)
-#define REG_VDP_TTX_FILTER_2_MASK5 (0xBA)
-#define REG_VDP_TTX_FILTER_CONTROL (0xBB)
-#define REG_VDP_FIFO_WORD_COUNT (0xBC)
-#define REG_VDP_FIFO_INTERRUPT_THRLD (0xBD)
-
-/* 0xBE Reserved */
-
-#define REG_VDP_FIFO_RESET (0xBF)
-#define REG_VDP_FIFO_OUTPUT_CONTROL (0xC0)
-#define REG_VDP_LINE_NUMBER_INTERRUPT (0xC1)
-#define REG_VDP_PIXEL_ALIGNMENT_LSB (0xC2)
-#define REG_VDP_PIXEL_ALIGNMENT_MSB (0xC3)
-
-/* 0xC4 - 0xD5 Reserved */
-
-#define REG_VDP_LINE_START (0xD6)
-#define REG_VDP_LINE_STOP (0xD7)
-#define REG_VDP_GLOBAL_LINE_MODE (0xD8)
-#define REG_VDP_FULL_FIELD_ENABLE (0xD9)
-#define REG_VDP_FULL_FIELD_MODE (0xDA)
-
-/* 0xDB - 0xDF Reserved */
-
-#define REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR (0xE0)
-#define REG_VBUS_DATA_ACCESS_VBUS_ADDR_INCR (0xE1)
-#define REG_FIFO_READ_DATA (0xE2)
-
-/* 0xE3 - 0xE7 Reserved */
-
-#define REG_VBUS_ADDRESS_ACCESS1 (0xE8)
-#define REG_VBUS_ADDRESS_ACCESS2 (0xE9)
-#define REG_VBUS_ADDRESS_ACCESS3 (0xEA)
-
-/* 0xEB - 0xEF Reserved */
-
-#define REG_INTERRUPT_RAW_STATUS0 (0xF0)
-#define REG_INTERRUPT_RAW_STATUS1 (0xF1)
-#define REG_INTERRUPT_STATUS0 (0xF2)
-#define REG_INTERRUPT_STATUS1 (0xF3)
-#define REG_INTERRUPT_MASK0 (0xF4)
-#define REG_INTERRUPT_MASK1 (0xF5)
-#define REG_INTERRUPT_CLEAR0 (0xF6)
-#define REG_INTERRUPT_CLEAR1 (0xF7)
-
-/* 0xF8 - 0xFF Reserved */
-
-/*
- * Mask and bit definitions of TVP5146/47 registers
- */
-/* The ID values we are looking for */
-#define TVP514X_CHIP_ID_MSB (0x51)
-#define TVP5146_CHIP_ID_LSB (0x46)
-#define TVP5147_CHIP_ID_LSB (0x47)
-
-#define VIDEO_STD_MASK (0x07)
-#define VIDEO_STD_AUTO_SWITCH_BIT (0x00)
-#define VIDEO_STD_NTSC_MJ_BIT (0x01)
-#define VIDEO_STD_PAL_BDGHIN_BIT (0x02)
-#define VIDEO_STD_PAL_M_BIT (0x03)
-#define VIDEO_STD_PAL_COMBINATION_N_BIT (0x04)
-#define VIDEO_STD_NTSC_4_43_BIT (0x05)
-#define VIDEO_STD_SECAM_BIT (0x06)
-#define VIDEO_STD_PAL_60_BIT (0x07)
-
-/*
- * Status bit
- */
-#define STATUS_TV_VCR_BIT (1<<0)
-#define STATUS_HORZ_SYNC_LOCK_BIT (1<<1)
-#define STATUS_VIRT_SYNC_LOCK_BIT (1<<2)
-#define STATUS_CLR_SUBCAR_LOCK_BIT (1<<3)
-#define STATUS_LOST_LOCK_DETECT_BIT (1<<4)
-#define STATUS_FEILD_RATE_BIT (1<<5)
-#define STATUS_LINE_ALTERNATING_BIT (1<<6)
-#define STATUS_PEAK_WHITE_DETECT_BIT (1<<7)
-
-/* Tokens for register write */
-#define TOK_WRITE (0) /* token for write operation */
-#define TOK_TERM (1) /* terminating token */
-#define TOK_DELAY (2) /* delay token for reg list */
-#define TOK_SKIP (3) /* token to skip a register */
-/**
- * struct tvp514x_reg - Structure for TVP5146/47 register initialization values
- * @token - Token: TOK_WRITE, TOK_TERM etc..
- * @reg - Register offset
- * @val - Register Value for TOK_WRITE or delay in ms for TOK_DELAY
- */
-struct tvp514x_reg {
- u8 token;
- u8 reg;
- u32 val;
-};
-
-#endif /* ifndef _TVP514X_REGS_H */
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
deleted file mode 100644
index a751b6c146f..00000000000
--- a/drivers/media/video/tvp5150.c
+++ /dev/null
@@ -1,1274 +0,0 @@
-/*
- * tvp5150 - Texas Instruments TVP5150A/AM1 video decoder driver
- *
- * Copyright (c) 2005,2006 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License v2
- */
-
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <media/v4l2-device.h>
-#include <media/tvp5150.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-
-#include "tvp5150_reg.h"
-
-#define TVP5150_H_MAX 720
-#define TVP5150_V_MAX_525_60 480
-#define TVP5150_V_MAX_OTHERS 576
-#define TVP5150_MAX_CROP_LEFT 511
-#define TVP5150_MAX_CROP_TOP 127
-#define TVP5150_CROP_SHIFT 2
-
-MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver");
-MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
-
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-2)");
-
-struct tvp5150 {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- struct v4l2_rect rect;
-
- v4l2_std_id norm; /* Current set standard */
- u32 input;
- u32 output;
- int enable;
-};
-
-static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct tvp5150, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct tvp5150, hdl)->sd;
-}
-
-static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr)
-{
- struct i2c_client *c = v4l2_get_subdevdata(sd);
- unsigned char buffer[1];
- int rc;
-
- buffer[0] = addr;
-
- rc = i2c_master_send(c, buffer, 1);
- if (rc < 0) {
- v4l2_err(sd, "i2c i/o error: rc == %d (should be 1)\n", rc);
- return rc;
- }
-
- msleep(10);
-
- rc = i2c_master_recv(c, buffer, 1);
- if (rc < 0) {
- v4l2_err(sd, "i2c i/o error: rc == %d (should be 1)\n", rc);
- return rc;
- }
-
- v4l2_dbg(2, debug, sd, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]);
-
- return (buffer[0]);
-}
-
-static inline void tvp5150_write(struct v4l2_subdev *sd, unsigned char addr,
- unsigned char value)
-{
- struct i2c_client *c = v4l2_get_subdevdata(sd);
- unsigned char buffer[2];
- int rc;
-
- buffer[0] = addr;
- buffer[1] = value;
- v4l2_dbg(2, debug, sd, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]);
- if (2 != (rc = i2c_master_send(c, buffer, 2)))
- v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d (should be 2)\n", rc);
-}
-
-static void dump_reg_range(struct v4l2_subdev *sd, char *s, u8 init,
- const u8 end, int max_line)
-{
- int i = 0;
-
- while (init != (u8)(end + 1)) {
- if ((i % max_line) == 0) {
- if (i > 0)
- printk("\n");
- printk("tvp5150: %s reg 0x%02x = ", s, init);
- }
- printk("%02x ", tvp5150_read(sd, init));
-
- init++;
- i++;
- }
- printk("\n");
-}
-
-static int tvp5150_log_status(struct v4l2_subdev *sd)
-{
- printk("tvp5150: Video input source selection #1 = 0x%02x\n",
- tvp5150_read(sd, TVP5150_VD_IN_SRC_SEL_1));
- printk("tvp5150: Analog channel controls = 0x%02x\n",
- tvp5150_read(sd, TVP5150_ANAL_CHL_CTL));
- printk("tvp5150: Operation mode controls = 0x%02x\n",
- tvp5150_read(sd, TVP5150_OP_MODE_CTL));
- printk("tvp5150: Miscellaneous controls = 0x%02x\n",
- tvp5150_read(sd, TVP5150_MISC_CTL));
- printk("tvp5150: Autoswitch mask= 0x%02x\n",
- tvp5150_read(sd, TVP5150_AUTOSW_MSK));
- printk("tvp5150: Color killer threshold control = 0x%02x\n",
- tvp5150_read(sd, TVP5150_COLOR_KIL_THSH_CTL));
- printk("tvp5150: Luminance processing controls #1 #2 and #3 = %02x %02x %02x\n",
- tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_1),
- tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_2),
- tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_3));
- printk("tvp5150: Brightness control = 0x%02x\n",
- tvp5150_read(sd, TVP5150_BRIGHT_CTL));
- printk("tvp5150: Color saturation control = 0x%02x\n",
- tvp5150_read(sd, TVP5150_SATURATION_CTL));
- printk("tvp5150: Hue control = 0x%02x\n",
- tvp5150_read(sd, TVP5150_HUE_CTL));
- printk("tvp5150: Contrast control = 0x%02x\n",
- tvp5150_read(sd, TVP5150_CONTRAST_CTL));
- printk("tvp5150: Outputs and data rates select = 0x%02x\n",
- tvp5150_read(sd, TVP5150_DATA_RATE_SEL));
- printk("tvp5150: Configuration shared pins = 0x%02x\n",
- tvp5150_read(sd, TVP5150_CONF_SHARED_PIN));
- printk("tvp5150: Active video cropping start = 0x%02x%02x\n",
- tvp5150_read(sd, TVP5150_ACT_VD_CROP_ST_MSB),
- tvp5150_read(sd, TVP5150_ACT_VD_CROP_ST_LSB));
- printk("tvp5150: Active video cropping stop = 0x%02x%02x\n",
- tvp5150_read(sd, TVP5150_ACT_VD_CROP_STP_MSB),
- tvp5150_read(sd, TVP5150_ACT_VD_CROP_STP_LSB));
- printk("tvp5150: Genlock/RTC = 0x%02x\n",
- tvp5150_read(sd, TVP5150_GENLOCK));
- printk("tvp5150: Horizontal sync start = 0x%02x\n",
- tvp5150_read(sd, TVP5150_HORIZ_SYNC_START));
- printk("tvp5150: Vertical blanking start = 0x%02x\n",
- tvp5150_read(sd, TVP5150_VERT_BLANKING_START));
- printk("tvp5150: Vertical blanking stop = 0x%02x\n",
- tvp5150_read(sd, TVP5150_VERT_BLANKING_STOP));
- printk("tvp5150: Chrominance processing control #1 and #2 = %02x %02x\n",
- tvp5150_read(sd, TVP5150_CHROMA_PROC_CTL_1),
- tvp5150_read(sd, TVP5150_CHROMA_PROC_CTL_2));
- printk("tvp5150: Interrupt reset register B = 0x%02x\n",
- tvp5150_read(sd, TVP5150_INT_RESET_REG_B));
- printk("tvp5150: Interrupt enable register B = 0x%02x\n",
- tvp5150_read(sd, TVP5150_INT_ENABLE_REG_B));
- printk("tvp5150: Interrupt configuration register B = 0x%02x\n",
- tvp5150_read(sd, TVP5150_INTT_CONFIG_REG_B));
- printk("tvp5150: Video standard = 0x%02x\n",
- tvp5150_read(sd, TVP5150_VIDEO_STD));
- printk("tvp5150: Chroma gain factor: Cb=0x%02x Cr=0x%02x\n",
- tvp5150_read(sd, TVP5150_CB_GAIN_FACT),
- tvp5150_read(sd, TVP5150_CR_GAIN_FACTOR));
- printk("tvp5150: Macrovision on counter = 0x%02x\n",
- tvp5150_read(sd, TVP5150_MACROVISION_ON_CTR));
- printk("tvp5150: Macrovision off counter = 0x%02x\n",
- tvp5150_read(sd, TVP5150_MACROVISION_OFF_CTR));
- printk("tvp5150: ITU-R BT.656.%d timing(TVP5150AM1 only)\n",
- (tvp5150_read(sd, TVP5150_REV_SELECT) & 1) ? 3 : 4);
- printk("tvp5150: Device ID = %02x%02x\n",
- tvp5150_read(sd, TVP5150_MSB_DEV_ID),
- tvp5150_read(sd, TVP5150_LSB_DEV_ID));
- printk("tvp5150: ROM version = (hex) %02x.%02x\n",
- tvp5150_read(sd, TVP5150_ROM_MAJOR_VER),
- tvp5150_read(sd, TVP5150_ROM_MINOR_VER));
- printk("tvp5150: Vertical line count = 0x%02x%02x\n",
- tvp5150_read(sd, TVP5150_VERT_LN_COUNT_MSB),
- tvp5150_read(sd, TVP5150_VERT_LN_COUNT_LSB));
- printk("tvp5150: Interrupt status register B = 0x%02x\n",
- tvp5150_read(sd, TVP5150_INT_STATUS_REG_B));
- printk("tvp5150: Interrupt active register B = 0x%02x\n",
- tvp5150_read(sd, TVP5150_INT_ACTIVE_REG_B));
- printk("tvp5150: Status regs #1 to #5 = %02x %02x %02x %02x %02x\n",
- tvp5150_read(sd, TVP5150_STATUS_REG_1),
- tvp5150_read(sd, TVP5150_STATUS_REG_2),
- tvp5150_read(sd, TVP5150_STATUS_REG_3),
- tvp5150_read(sd, TVP5150_STATUS_REG_4),
- tvp5150_read(sd, TVP5150_STATUS_REG_5));
-
- dump_reg_range(sd, "Teletext filter 1", TVP5150_TELETEXT_FIL1_INI,
- TVP5150_TELETEXT_FIL1_END, 8);
- dump_reg_range(sd, "Teletext filter 2", TVP5150_TELETEXT_FIL2_INI,
- TVP5150_TELETEXT_FIL2_END, 8);
-
- printk("tvp5150: Teletext filter enable = 0x%02x\n",
- tvp5150_read(sd, TVP5150_TELETEXT_FIL_ENA));
- printk("tvp5150: Interrupt status register A = 0x%02x\n",
- tvp5150_read(sd, TVP5150_INT_STATUS_REG_A));
- printk("tvp5150: Interrupt enable register A = 0x%02x\n",
- tvp5150_read(sd, TVP5150_INT_ENABLE_REG_A));
- printk("tvp5150: Interrupt configuration = 0x%02x\n",
- tvp5150_read(sd, TVP5150_INT_CONF));
- printk("tvp5150: VDP status register = 0x%02x\n",
- tvp5150_read(sd, TVP5150_VDP_STATUS_REG));
- printk("tvp5150: FIFO word count = 0x%02x\n",
- tvp5150_read(sd, TVP5150_FIFO_WORD_COUNT));
- printk("tvp5150: FIFO interrupt threshold = 0x%02x\n",
- tvp5150_read(sd, TVP5150_FIFO_INT_THRESHOLD));
- printk("tvp5150: FIFO reset = 0x%02x\n",
- tvp5150_read(sd, TVP5150_FIFO_RESET));
- printk("tvp5150: Line number interrupt = 0x%02x\n",
- tvp5150_read(sd, TVP5150_LINE_NUMBER_INT));
- printk("tvp5150: Pixel alignment register = 0x%02x%02x\n",
- tvp5150_read(sd, TVP5150_PIX_ALIGN_REG_HIGH),
- tvp5150_read(sd, TVP5150_PIX_ALIGN_REG_LOW));
- printk("tvp5150: FIFO output control = 0x%02x\n",
- tvp5150_read(sd, TVP5150_FIFO_OUT_CTRL));
- printk("tvp5150: Full field enable = 0x%02x\n",
- tvp5150_read(sd, TVP5150_FULL_FIELD_ENA));
- printk("tvp5150: Full field mode register = 0x%02x\n",
- tvp5150_read(sd, TVP5150_FULL_FIELD_MODE_REG));
-
- dump_reg_range(sd, "CC data", TVP5150_CC_DATA_INI,
- TVP5150_CC_DATA_END, 8);
-
- dump_reg_range(sd, "WSS data", TVP5150_WSS_DATA_INI,
- TVP5150_WSS_DATA_END, 8);
-
- dump_reg_range(sd, "VPS data", TVP5150_VPS_DATA_INI,
- TVP5150_VPS_DATA_END, 8);
-
- dump_reg_range(sd, "VITC data", TVP5150_VITC_DATA_INI,
- TVP5150_VITC_DATA_END, 10);
-
- dump_reg_range(sd, "Line mode", TVP5150_LINE_MODE_INI,
- TVP5150_LINE_MODE_END, 8);
- return 0;
-}
-
-/****************************************************************************
- Basic functions
- ****************************************************************************/
-
-static inline void tvp5150_selmux(struct v4l2_subdev *sd)
-{
- int opmode = 0;
- struct tvp5150 *decoder = to_tvp5150(sd);
- int input = 0;
- int val;
-
- if ((decoder->output & TVP5150_BLACK_SCREEN) || !decoder->enable)
- input = 8;
-
- switch (decoder->input) {
- case TVP5150_COMPOSITE1:
- input |= 2;
- /* fall through */
- case TVP5150_COMPOSITE0:
- break;
- case TVP5150_SVIDEO:
- default:
- input |= 1;
- break;
- }
-
- v4l2_dbg(1, debug, sd, "Selecting video route: route input=%i, output=%i "
- "=> tvp5150 input=%i, opmode=%i\n",
- decoder->input, decoder->output,
- input, opmode);
-
- tvp5150_write(sd, TVP5150_OP_MODE_CTL, opmode);
- tvp5150_write(sd, TVP5150_VD_IN_SRC_SEL_1, input);
-
- /* Svideo should enable YCrCb output and disable GPCL output
- * For Composite and TV, it should be the reverse
- */
- val = tvp5150_read(sd, TVP5150_MISC_CTL);
- if (val < 0) {
- v4l2_err(sd, "%s: failed with error = %d\n", __func__, val);
- return;
- }
-
- if (decoder->input == TVP5150_SVIDEO)
- val = (val & ~0x40) | 0x10;
- else
- val = (val & ~0x10) | 0x40;
- tvp5150_write(sd, TVP5150_MISC_CTL, val);
-};
-
-struct i2c_reg_value {
- unsigned char reg;
- unsigned char value;
-};
-
-/* Default values as sugested at TVP5150AM1 datasheet */
-static const struct i2c_reg_value tvp5150_init_default[] = {
- { /* 0x00 */
- TVP5150_VD_IN_SRC_SEL_1,0x00
- },
- { /* 0x01 */
- TVP5150_ANAL_CHL_CTL,0x15
- },
- { /* 0x02 */
- TVP5150_OP_MODE_CTL,0x00
- },
- { /* 0x03 */
- TVP5150_MISC_CTL,0x01
- },
- { /* 0x06 */
- TVP5150_COLOR_KIL_THSH_CTL,0x10
- },
- { /* 0x07 */
- TVP5150_LUMA_PROC_CTL_1,0x60
- },
- { /* 0x08 */
- TVP5150_LUMA_PROC_CTL_2,0x00
- },
- { /* 0x09 */
- TVP5150_BRIGHT_CTL,0x80
- },
- { /* 0x0a */
- TVP5150_SATURATION_CTL,0x80
- },
- { /* 0x0b */
- TVP5150_HUE_CTL,0x00
- },
- { /* 0x0c */
- TVP5150_CONTRAST_CTL,0x80
- },
- { /* 0x0d */
- TVP5150_DATA_RATE_SEL,0x47
- },
- { /* 0x0e */
- TVP5150_LUMA_PROC_CTL_3,0x00
- },
- { /* 0x0f */
- TVP5150_CONF_SHARED_PIN,0x08
- },
- { /* 0x11 */
- TVP5150_ACT_VD_CROP_ST_MSB,0x00
- },
- { /* 0x12 */
- TVP5150_ACT_VD_CROP_ST_LSB,0x00
- },
- { /* 0x13 */
- TVP5150_ACT_VD_CROP_STP_MSB,0x00
- },
- { /* 0x14 */
- TVP5150_ACT_VD_CROP_STP_LSB,0x00
- },
- { /* 0x15 */
- TVP5150_GENLOCK,0x01
- },
- { /* 0x16 */
- TVP5150_HORIZ_SYNC_START,0x80
- },
- { /* 0x18 */
- TVP5150_VERT_BLANKING_START,0x00
- },
- { /* 0x19 */
- TVP5150_VERT_BLANKING_STOP,0x00
- },
- { /* 0x1a */
- TVP5150_CHROMA_PROC_CTL_1,0x0c
- },
- { /* 0x1b */
- TVP5150_CHROMA_PROC_CTL_2,0x14
- },
- { /* 0x1c */
- TVP5150_INT_RESET_REG_B,0x00
- },
- { /* 0x1d */
- TVP5150_INT_ENABLE_REG_B,0x00
- },
- { /* 0x1e */
- TVP5150_INTT_CONFIG_REG_B,0x00
- },
- { /* 0x28 */
- TVP5150_VIDEO_STD,0x00
- },
- { /* 0x2e */
- TVP5150_MACROVISION_ON_CTR,0x0f
- },
- { /* 0x2f */
- TVP5150_MACROVISION_OFF_CTR,0x01
- },
- { /* 0xbb */
- TVP5150_TELETEXT_FIL_ENA,0x00
- },
- { /* 0xc0 */
- TVP5150_INT_STATUS_REG_A,0x00
- },
- { /* 0xc1 */
- TVP5150_INT_ENABLE_REG_A,0x00
- },
- { /* 0xc2 */
- TVP5150_INT_CONF,0x04
- },
- { /* 0xc8 */
- TVP5150_FIFO_INT_THRESHOLD,0x80
- },
- { /* 0xc9 */
- TVP5150_FIFO_RESET,0x00
- },
- { /* 0xca */
- TVP5150_LINE_NUMBER_INT,0x00
- },
- { /* 0xcb */
- TVP5150_PIX_ALIGN_REG_LOW,0x4e
- },
- { /* 0xcc */
- TVP5150_PIX_ALIGN_REG_HIGH,0x00
- },
- { /* 0xcd */
- TVP5150_FIFO_OUT_CTRL,0x01
- },
- { /* 0xcf */
- TVP5150_FULL_FIELD_ENA,0x00
- },
- { /* 0xd0 */
- TVP5150_LINE_MODE_INI,0x00
- },
- { /* 0xfc */
- TVP5150_FULL_FIELD_MODE_REG,0x7f
- },
- { /* end of data */
- 0xff,0xff
- }
-};
-
-/* Default values as sugested at TVP5150AM1 datasheet */
-static const struct i2c_reg_value tvp5150_init_enable[] = {
- {
- TVP5150_CONF_SHARED_PIN, 2
- },{ /* Automatic offset and AGC enabled */
- TVP5150_ANAL_CHL_CTL, 0x15
- },{ /* Activate YCrCb output 0x9 or 0xd ? */
- TVP5150_MISC_CTL, 0x6f
- },{ /* Activates video std autodetection for all standards */
- TVP5150_AUTOSW_MSK, 0x0
- },{ /* Default format: 0x47. For 4:2:2: 0x40 */
- TVP5150_DATA_RATE_SEL, 0x47
- },{
- TVP5150_CHROMA_PROC_CTL_1, 0x0c
- },{
- TVP5150_CHROMA_PROC_CTL_2, 0x54
- },{ /* Non documented, but initialized on WinTV USB2 */
- 0x27, 0x20
- },{
- 0xff,0xff
- }
-};
-
-struct tvp5150_vbi_type {
- unsigned int vbi_type;
- unsigned int ini_line;
- unsigned int end_line;
- unsigned int by_field :1;
-};
-
-struct i2c_vbi_ram_value {
- u16 reg;
- struct tvp5150_vbi_type type;
- unsigned char values[16];
-};
-
-/* This struct have the values for each supported VBI Standard
- * by
- tvp5150_vbi_types should follow the same order as vbi_ram_default
- * value 0 means rom position 0x10, value 1 means rom position 0x30
- * and so on. There are 16 possible locations from 0 to 15.
- */
-
-static struct i2c_vbi_ram_value vbi_ram_default[] =
-{
- /* FIXME: Current api doesn't handle all VBI types, those not
- yet supported are placed under #if 0 */
-#if 0
- {0x010, /* Teletext, SECAM, WST System A */
- {V4L2_SLICED_TELETEXT_SECAM,6,23,1},
- { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26,
- 0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 }
- },
-#endif
- {0x030, /* Teletext, PAL, WST System B */
- {V4L2_SLICED_TELETEXT_B,6,22,1},
- { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b,
- 0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 }
- },
-#if 0
- {0x050, /* Teletext, PAL, WST System C */
- {V4L2_SLICED_TELETEXT_PAL_C,6,22,1},
- { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
- 0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
- },
- {0x070, /* Teletext, NTSC, WST System B */
- {V4L2_SLICED_TELETEXT_NTSC_B,10,21,1},
- { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23,
- 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
- },
- {0x090, /* Tetetext, NTSC NABTS System C */
- {V4L2_SLICED_TELETEXT_NTSC_C,10,21,1},
- { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
- 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 }
- },
- {0x0b0, /* Teletext, NTSC-J, NABTS System D */
- {V4L2_SLICED_TELETEXT_NTSC_D,10,21,1},
- { 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23,
- 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
- },
- {0x0d0, /* Closed Caption, PAL/SECAM */
- {V4L2_SLICED_CAPTION_625,22,22,1},
- { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
- 0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
- },
-#endif
- {0x0f0, /* Closed Caption, NTSC */
- {V4L2_SLICED_CAPTION_525,21,21,1},
- { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
- 0x69, 0x8c, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
- },
- {0x110, /* Wide Screen Signal, PAL/SECAM */
- {V4L2_SLICED_WSS_625,23,23,1},
- { 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42,
- 0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 }
- },
-#if 0
- {0x130, /* Wide Screen Signal, NTSC C */
- {V4L2_SLICED_WSS_525,20,20,1},
- { 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43,
- 0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 }
- },
- {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */
- {V4l2_SLICED_VITC_625,6,22,0},
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
- 0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
- },
- {0x170, /* Vertical Interval Timecode (VITC), NTSC */
- {V4l2_SLICED_VITC_525,10,20,0},
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
- 0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
- },
-#endif
- {0x190, /* Video Program System (VPS), PAL */
- {V4L2_SLICED_VPS,16,16,0},
- { 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d,
- 0xa6, 0xda, 0x0b, 0x00, 0x00, 0x00, 0x60, 0x00 }
- },
- /* 0x1d0 User programmable */
-
- /* End of struct */
- { (u16)-1 }
-};
-
-static int tvp5150_write_inittab(struct v4l2_subdev *sd,
- const struct i2c_reg_value *regs)
-{
- while (regs->reg != 0xff) {
- tvp5150_write(sd, regs->reg, regs->value);
- regs++;
- }
- return 0;
-}
-
-static int tvp5150_vdp_init(struct v4l2_subdev *sd,
- const struct i2c_vbi_ram_value *regs)
-{
- unsigned int i;
-
- /* Disable Full Field */
- tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0);
-
- /* Before programming, Line mode should be at 0xff */
- for (i = TVP5150_LINE_MODE_INI; i <= TVP5150_LINE_MODE_END; i++)
- tvp5150_write(sd, i, 0xff);
-
- /* Load Ram Table */
- while (regs->reg != (u16)-1) {
- tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8);
- tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_LOW, regs->reg);
-
- for (i = 0; i < 16; i++)
- tvp5150_write(sd, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]);
-
- regs++;
- }
- return 0;
-}
-
-/* Fills VBI capabilities based on i2c_vbi_ram_value struct */
-static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd,
- struct v4l2_sliced_vbi_cap *cap)
-{
- const struct i2c_vbi_ram_value *regs = vbi_ram_default;
- int line;
-
- v4l2_dbg(1, debug, sd, "g_sliced_vbi_cap\n");
- memset(cap, 0, sizeof *cap);
-
- while (regs->reg != (u16)-1 ) {
- for (line=regs->type.ini_line;line<=regs->type.end_line;line++) {
- cap->service_lines[0][line] |= regs->type.vbi_type;
- }
- cap->service_set |= regs->type.vbi_type;
-
- regs++;
- }
- return 0;
-}
-
-/* Set vbi processing
- * type - one of tvp5150_vbi_types
- * line - line to gather data
- * fields: bit 0 field1, bit 1, field2
- * flags (default=0xf0) is a bitmask, were set means:
- * bit 7: enable filtering null bytes on CC
- * bit 6: send data also to FIFO
- * bit 5: don't allow data with errors on FIFO
- * bit 4: enable ECC when possible
- * pix_align = pix alignment:
- * LSB = field1
- * MSB = field2
- */
-static int tvp5150_set_vbi(struct v4l2_subdev *sd,
- const struct i2c_vbi_ram_value *regs,
- unsigned int type,u8 flags, int line,
- const int fields)
-{
- struct tvp5150 *decoder = to_tvp5150(sd);
- v4l2_std_id std = decoder->norm;
- u8 reg;
- int pos=0;
-
- if (std == V4L2_STD_ALL) {
- v4l2_err(sd, "VBI can't be configured without knowing number of lines\n");
- return 0;
- } else if (std & V4L2_STD_625_50) {
- /* Don't follow NTSC Line number convension */
- line += 3;
- }
-
- if (line<6||line>27)
- return 0;
-
- while (regs->reg != (u16)-1 ) {
- if ((type & regs->type.vbi_type) &&
- (line>=regs->type.ini_line) &&
- (line<=regs->type.end_line)) {
- type=regs->type.vbi_type;
- break;
- }
-
- regs++;
- pos++;
- }
- if (regs->reg == (u16)-1)
- return 0;
-
- type=pos | (flags & 0xf0);
- reg=((line-6)<<1)+TVP5150_LINE_MODE_INI;
-
- if (fields&1) {
- tvp5150_write(sd, reg, type);
- }
-
- if (fields&2) {
- tvp5150_write(sd, reg+1, type);
- }
-
- return type;
-}
-
-static int tvp5150_get_vbi(struct v4l2_subdev *sd,
- const struct i2c_vbi_ram_value *regs, int line)
-{
- struct tvp5150 *decoder = to_tvp5150(sd);
- v4l2_std_id std = decoder->norm;
- u8 reg;
- int pos, type = 0;
- int i, ret = 0;
-
- if (std == V4L2_STD_ALL) {
- v4l2_err(sd, "VBI can't be configured without knowing number of lines\n");
- return 0;
- } else if (std & V4L2_STD_625_50) {
- /* Don't follow NTSC Line number convension */
- line += 3;
- }
-
- if (line < 6 || line > 27)
- return 0;
-
- reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI;
-
- for (i = 0; i <= 1; i++) {
- ret = tvp5150_read(sd, reg + i);
- if (ret < 0) {
- v4l2_err(sd, "%s: failed with error = %d\n",
- __func__, ret);
- return 0;
- }
- pos = ret & 0x0f;
- if (pos < 0x0f)
- type |= regs[pos].type.vbi_type;
- }
-
- return type;
-}
-
-static int tvp5150_set_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct tvp5150 *decoder = to_tvp5150(sd);
- int fmt = 0;
-
- decoder->norm = std;
-
- /* First tests should be against specific std */
-
- if (std == V4L2_STD_ALL) {
- fmt = VIDEO_STD_AUTO_SWITCH_BIT; /* Autodetect mode */
- } else if (std & V4L2_STD_NTSC_443) {
- fmt = VIDEO_STD_NTSC_4_43_BIT;
- } else if (std & V4L2_STD_PAL_M) {
- fmt = VIDEO_STD_PAL_M_BIT;
- } else if (std & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) {
- fmt = VIDEO_STD_PAL_COMBINATION_N_BIT;
- } else {
- /* Then, test against generic ones */
- if (std & V4L2_STD_NTSC)
- fmt = VIDEO_STD_NTSC_MJ_BIT;
- else if (std & V4L2_STD_PAL)
- fmt = VIDEO_STD_PAL_BDGHIN_BIT;
- else if (std & V4L2_STD_SECAM)
- fmt = VIDEO_STD_SECAM_BIT;
- }
-
- v4l2_dbg(1, debug, sd, "Set video std register to %d.\n", fmt);
- tvp5150_write(sd, TVP5150_VIDEO_STD, fmt);
- return 0;
-}
-
-static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct tvp5150 *decoder = to_tvp5150(sd);
-
- if (decoder->norm == std)
- return 0;
-
- /* Change cropping height limits */
- if (std & V4L2_STD_525_60)
- decoder->rect.height = TVP5150_V_MAX_525_60;
- else
- decoder->rect.height = TVP5150_V_MAX_OTHERS;
-
-
- return tvp5150_set_std(sd, std);
-}
-
-static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
-{
- struct tvp5150 *decoder = to_tvp5150(sd);
-
- /* Initializes TVP5150 to its default values */
- tvp5150_write_inittab(sd, tvp5150_init_default);
-
- /* Initializes VDP registers */
- tvp5150_vdp_init(sd, vbi_ram_default);
-
- /* Selects decoder input */
- tvp5150_selmux(sd);
-
- /* Initializes TVP5150 to stream enabled values */
- tvp5150_write_inittab(sd, tvp5150_init_enable);
-
- /* Initialize image preferences */
- v4l2_ctrl_handler_setup(&decoder->hdl);
-
- tvp5150_set_std(sd, decoder->norm);
- return 0;
-};
-
-static int tvp5150_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- tvp5150_write(sd, TVP5150_BRIGHT_CTL, ctrl->val);
- return 0;
- case V4L2_CID_CONTRAST:
- tvp5150_write(sd, TVP5150_CONTRAST_CTL, ctrl->val);
- return 0;
- case V4L2_CID_SATURATION:
- tvp5150_write(sd, TVP5150_SATURATION_CTL, ctrl->val);
- return 0;
- case V4L2_CID_HUE:
- tvp5150_write(sd, TVP5150_HUE_CTL, ctrl->val);
- return 0;
- }
- return -EINVAL;
-}
-
-static v4l2_std_id tvp5150_read_std(struct v4l2_subdev *sd)
-{
- int val = tvp5150_read(sd, TVP5150_STATUS_REG_5);
-
- switch (val & 0x0F) {
- case 0x01:
- return V4L2_STD_NTSC;
- case 0x03:
- return V4L2_STD_PAL;
- case 0x05:
- return V4L2_STD_PAL_M;
- case 0x07:
- return V4L2_STD_PAL_N | V4L2_STD_PAL_Nc;
- case 0x09:
- return V4L2_STD_NTSC_443;
- case 0xb:
- return V4L2_STD_SECAM;
- default:
- return V4L2_STD_UNKNOWN;
- }
-}
-
-static int tvp5150_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index)
- return -EINVAL;
-
- *code = V4L2_MBUS_FMT_UYVY8_2X8;
- return 0;
-}
-
-static int tvp5150_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *f)
-{
- struct tvp5150 *decoder = to_tvp5150(sd);
-
- if (f == NULL)
- return -EINVAL;
-
- tvp5150_reset(sd, 0);
-
- f->width = decoder->rect.width;
- f->height = decoder->rect.height;
-
- f->code = V4L2_MBUS_FMT_UYVY8_2X8;
- f->field = V4L2_FIELD_SEQ_TB;
- f->colorspace = V4L2_COLORSPACE_SMPTE170M;
-
- v4l2_dbg(1, debug, sd, "width = %d, height = %d\n", f->width,
- f->height);
- return 0;
-}
-
-static int tvp5150_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct v4l2_rect rect = a->c;
- struct tvp5150 *decoder = to_tvp5150(sd);
- v4l2_std_id std;
- int hmax;
-
- v4l2_dbg(1, debug, sd, "%s left=%d, top=%d, width=%d, height=%d\n",
- __func__, rect.left, rect.top, rect.width, rect.height);
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- /* tvp5150 has some special limits */
- rect.left = clamp(rect.left, 0, TVP5150_MAX_CROP_LEFT);
- rect.width = clamp(rect.width,
- TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT - rect.left,
- TVP5150_H_MAX - rect.left);
- rect.top = clamp(rect.top, 0, TVP5150_MAX_CROP_TOP);
-
- /* Calculate height based on current standard */
- if (decoder->norm == V4L2_STD_ALL)
- std = tvp5150_read_std(sd);
- else
- std = decoder->norm;
-
- if (std & V4L2_STD_525_60)
- hmax = TVP5150_V_MAX_525_60;
- else
- hmax = TVP5150_V_MAX_OTHERS;
-
- rect.height = clamp(rect.height,
- hmax - TVP5150_MAX_CROP_TOP - rect.top,
- hmax - rect.top);
-
- tvp5150_write(sd, TVP5150_VERT_BLANKING_START, rect.top);
- tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP,
- rect.top + rect.height - hmax);
- tvp5150_write(sd, TVP5150_ACT_VD_CROP_ST_MSB,
- rect.left >> TVP5150_CROP_SHIFT);
- tvp5150_write(sd, TVP5150_ACT_VD_CROP_ST_LSB,
- rect.left | (1 << TVP5150_CROP_SHIFT));
- tvp5150_write(sd, TVP5150_ACT_VD_CROP_STP_MSB,
- (rect.left + rect.width - TVP5150_MAX_CROP_LEFT) >>
- TVP5150_CROP_SHIFT);
- tvp5150_write(sd, TVP5150_ACT_VD_CROP_STP_LSB,
- rect.left + rect.width - TVP5150_MAX_CROP_LEFT);
-
- decoder->rect = rect;
-
- return 0;
-}
-
-static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd);
-
- a->c = decoder->rect;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int tvp5150_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd);
- v4l2_std_id std;
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = TVP5150_H_MAX;
-
- /* Calculate height based on current standard */
- if (decoder->norm == V4L2_STD_ALL)
- std = tvp5150_read_std(sd);
- else
- std = decoder->norm;
-
- if (std & V4L2_STD_525_60)
- a->bounds.height = TVP5150_V_MAX_525_60;
- else
- a->bounds.height = TVP5150_V_MAX_OTHERS;
-
- a->defrect = a->bounds;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-/****************************************************************************
- I2C Command
- ****************************************************************************/
-
-static int tvp5150_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct tvp5150 *decoder = to_tvp5150(sd);
-
- decoder->input = input;
- decoder->output = output;
- tvp5150_selmux(sd);
- return 0;
-}
-
-static int tvp5150_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
-{
- /* this is for capturing 36 raw vbi lines
- if there's a way to cut off the beginning 2 vbi lines
- with the tvp5150 then the vbi line count could be lowered
- to 17 lines/field again, although I couldn't find a register
- which could do that cropping */
- if (fmt->sample_format == V4L2_PIX_FMT_GREY)
- tvp5150_write(sd, TVP5150_LUMA_PROC_CTL_1, 0x70);
- if (fmt->count[0] == 18 && fmt->count[1] == 18) {
- tvp5150_write(sd, TVP5150_VERT_BLANKING_START, 0x00);
- tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP, 0x01);
- }
- return 0;
-}
-
-static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
-{
- int i;
-
- if (svbi->service_set != 0) {
- for (i = 0; i <= 23; i++) {
- svbi->service_lines[1][i] = 0;
- svbi->service_lines[0][i] =
- tvp5150_set_vbi(sd, vbi_ram_default,
- svbi->service_lines[0][i], 0xf0, i, 3);
- }
- /* Enables FIFO */
- tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 1);
- } else {
- /* Disables FIFO*/
- tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 0);
-
- /* Disable Full Field */
- tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0);
-
- /* Disable Line modes */
- for (i = TVP5150_LINE_MODE_INI; i <= TVP5150_LINE_MODE_END; i++)
- tvp5150_write(sd, i, 0xff);
- }
- return 0;
-}
-
-static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
-{
- int i, mask = 0;
-
- memset(svbi, 0, sizeof(*svbi));
-
- for (i = 0; i <= 23; i++) {
- svbi->service_lines[0][i] =
- tvp5150_get_vbi(sd, vbi_ram_default, i);
- mask |= svbi->service_lines[0][i];
- }
- svbi->service_set = mask;
- return 0;
-}
-
-static int tvp5150_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- int rev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- rev = tvp5150_read(sd, TVP5150_ROM_MAJOR_VER) << 8 |
- tvp5150_read(sd, TVP5150_ROM_MINOR_VER);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP5150,
- rev);
-}
-
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- int res;
-
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- res = tvp5150_read(sd, reg->reg & 0xff);
- if (res < 0) {
- v4l2_err(sd, "%s: failed with error = %d\n", __func__, res);
- return res;
- }
-
- reg->val = res;
- reg->size = 1;
- return 0;
-}
-
-static int tvp5150_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- tvp5150_write(sd, reg->reg & 0xff, reg->val & 0xff);
- return 0;
-}
-#endif
-
-static int tvp5150_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- int status = tvp5150_read(sd, 0x88);
-
- vt->signal = ((status & 0x04) && (status & 0x02)) ? 0xffff : 0x0;
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_ctrl_ops tvp5150_ctrl_ops = {
- .s_ctrl = tvp5150_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops tvp5150_core_ops = {
- .log_status = tvp5150_log_status,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
- .s_std = tvp5150_s_std,
- .reset = tvp5150_reset,
- .g_chip_ident = tvp5150_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = tvp5150_g_register,
- .s_register = tvp5150_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = {
- .g_tuner = tvp5150_g_tuner,
-};
-
-static const struct v4l2_subdev_video_ops tvp5150_video_ops = {
- .s_routing = tvp5150_s_routing,
- .enum_mbus_fmt = tvp5150_enum_mbus_fmt,
- .s_mbus_fmt = tvp5150_mbus_fmt,
- .try_mbus_fmt = tvp5150_mbus_fmt,
- .g_mbus_fmt = tvp5150_mbus_fmt,
- .s_crop = tvp5150_s_crop,
- .g_crop = tvp5150_g_crop,
- .cropcap = tvp5150_cropcap,
-};
-
-static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = {
- .g_sliced_vbi_cap = tvp5150_g_sliced_vbi_cap,
- .g_sliced_fmt = tvp5150_g_sliced_fmt,
- .s_sliced_fmt = tvp5150_s_sliced_fmt,
- .s_raw_fmt = tvp5150_s_raw_fmt,
-};
-
-static const struct v4l2_subdev_ops tvp5150_ops = {
- .core = &tvp5150_core_ops,
- .tuner = &tvp5150_tuner_ops,
- .video = &tvp5150_video_ops,
- .vbi = &tvp5150_vbi_ops,
-};
-
-
-/****************************************************************************
- I2C Client & Driver
- ****************************************************************************/
-
-static int tvp5150_probe(struct i2c_client *c,
- const struct i2c_device_id *id)
-{
- struct tvp5150 *core;
- struct v4l2_subdev *sd;
- int tvp5150_id[4];
- int i, res;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(c->adapter,
- I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
- return -EIO;
-
- core = kzalloc(sizeof(struct tvp5150), GFP_KERNEL);
- if (!core) {
- return -ENOMEM;
- }
- sd = &core->sd;
- v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
-
- /*
- * Read consequent registers - TVP5150_MSB_DEV_ID, TVP5150_LSB_DEV_ID,
- * TVP5150_ROM_MAJOR_VER, TVP5150_ROM_MINOR_VER
- */
- for (i = 0; i < 4; i++) {
- res = tvp5150_read(sd, TVP5150_MSB_DEV_ID + i);
- if (res < 0)
- goto free_core;
- tvp5150_id[i] = res;
- }
-
- v4l_info(c, "chip found @ 0x%02x (%s)\n",
- c->addr << 1, c->adapter->name);
-
- if (tvp5150_id[2] == 4 && tvp5150_id[3] == 0) { /* Is TVP5150AM1 */
- v4l2_info(sd, "tvp%02x%02xam1 detected.\n",
- tvp5150_id[0], tvp5150_id[1]);
-
- /* ITU-T BT.656.4 timing */
- tvp5150_write(sd, TVP5150_REV_SELECT, 0);
- } else {
- /* Is TVP5150A */
- if (tvp5150_id[2] == 3 || tvp5150_id[3] == 0x21) {
- v4l2_info(sd, "tvp%02x%02xa detected.\n",
- tvp5150_id[2], tvp5150_id[3]);
- } else {
- v4l2_info(sd, "*** unknown tvp%02x%02x chip detected.\n",
- tvp5150_id[2], tvp5150_id[3]);
- v4l2_info(sd, "*** Rom ver is %d.%d\n",
- tvp5150_id[2], tvp5150_id[3]);
- }
- }
-
- core->norm = V4L2_STD_ALL; /* Default is autodetect */
- core->input = TVP5150_COMPOSITE1;
- core->enable = 1;
-
- v4l2_ctrl_handler_init(&core->hdl, 4);
- v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
- V4L2_CID_HUE, -128, 127, 1, 0);
- sd->ctrl_handler = &core->hdl;
- if (core->hdl.error) {
- res = core->hdl.error;
- v4l2_ctrl_handler_free(&core->hdl);
- goto free_core;
- }
- v4l2_ctrl_handler_setup(&core->hdl);
-
- /* Default is no cropping */
- core->rect.top = 0;
- if (tvp5150_read_std(sd) & V4L2_STD_525_60)
- core->rect.height = TVP5150_V_MAX_525_60;
- else
- core->rect.height = TVP5150_V_MAX_OTHERS;
- core->rect.left = 0;
- core->rect.width = TVP5150_H_MAX;
-
- if (debug > 1)
- tvp5150_log_status(sd);
- return 0;
-
-free_core:
- kfree(core);
- return res;
-}
-
-static int tvp5150_remove(struct i2c_client *c)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(c);
- struct tvp5150 *decoder = to_tvp5150(sd);
-
- v4l2_dbg(1, debug, sd,
- "tvp5150.c: removing tvp5150 adapter on address 0x%x\n",
- c->addr << 1);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(to_tvp5150(sd));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id tvp5150_id[] = {
- { "tvp5150", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tvp5150_id);
-
-static struct i2c_driver tvp5150_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "tvp5150",
- },
- .probe = tvp5150_probe,
- .remove = tvp5150_remove,
- .id_table = tvp5150_id,
-};
-
-module_i2c_driver(tvp5150_driver);
diff --git a/drivers/media/video/tvp5150_reg.h b/drivers/media/video/tvp5150_reg.h
deleted file mode 100644
index 25a99494491..00000000000
--- a/drivers/media/video/tvp5150_reg.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * tvp5150 - Texas Instruments TVP5150A/AM1 video decoder registers
- *
- * Copyright (c) 2005,2006 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License v2
- */
-
-#define TVP5150_VD_IN_SRC_SEL_1 0x00 /* Video input source selection #1 */
-#define TVP5150_ANAL_CHL_CTL 0x01 /* Analog channel controls */
-#define TVP5150_OP_MODE_CTL 0x02 /* Operation mode controls */
-#define TVP5150_MISC_CTL 0x03 /* Miscellaneous controls */
-#define TVP5150_AUTOSW_MSK 0x04 /* Autoswitch mask: TVP5150A / TVP5150AM */
-
-/* Reserved 05h */
-
-#define TVP5150_COLOR_KIL_THSH_CTL 0x06 /* Color killer threshold control */
-#define TVP5150_LUMA_PROC_CTL_1 0x07 /* Luminance processing control #1 */
-#define TVP5150_LUMA_PROC_CTL_2 0x08 /* Luminance processing control #2 */
-#define TVP5150_BRIGHT_CTL 0x09 /* Brightness control */
-#define TVP5150_SATURATION_CTL 0x0a /* Color saturation control */
-#define TVP5150_HUE_CTL 0x0b /* Hue control */
-#define TVP5150_CONTRAST_CTL 0x0c /* Contrast control */
-#define TVP5150_DATA_RATE_SEL 0x0d /* Outputs and data rates select */
-#define TVP5150_LUMA_PROC_CTL_3 0x0e /* Luminance processing control #3 */
-#define TVP5150_CONF_SHARED_PIN 0x0f /* Configuration shared pins */
-
-/* Reserved 10h */
-
-#define TVP5150_ACT_VD_CROP_ST_MSB 0x11 /* Active video cropping start MSB */
-#define TVP5150_ACT_VD_CROP_ST_LSB 0x12 /* Active video cropping start LSB */
-#define TVP5150_ACT_VD_CROP_STP_MSB 0x13 /* Active video cropping stop MSB */
-#define TVP5150_ACT_VD_CROP_STP_LSB 0x14 /* Active video cropping stop LSB */
-#define TVP5150_GENLOCK 0x15 /* Genlock/RTC */
-#define TVP5150_HORIZ_SYNC_START 0x16 /* Horizontal sync start */
-
-/* Reserved 17h */
-
-#define TVP5150_VERT_BLANKING_START 0x18 /* Vertical blanking start */
-#define TVP5150_VERT_BLANKING_STOP 0x19 /* Vertical blanking stop */
-#define TVP5150_CHROMA_PROC_CTL_1 0x1a /* Chrominance processing control #1 */
-#define TVP5150_CHROMA_PROC_CTL_2 0x1b /* Chrominance processing control #2 */
-#define TVP5150_INT_RESET_REG_B 0x1c /* Interrupt reset register B */
-#define TVP5150_INT_ENABLE_REG_B 0x1d /* Interrupt enable register B */
-#define TVP5150_INTT_CONFIG_REG_B 0x1e /* Interrupt configuration register B */
-
-/* Reserved 1Fh-27h */
-
-#define VIDEO_STD_MASK (0x07 >> 1)
-#define TVP5150_VIDEO_STD 0x28 /* Video standard */
-#define VIDEO_STD_AUTO_SWITCH_BIT 0x00
-#define VIDEO_STD_NTSC_MJ_BIT 0x02
-#define VIDEO_STD_PAL_BDGHIN_BIT 0x04
-#define VIDEO_STD_PAL_M_BIT 0x06
-#define VIDEO_STD_PAL_COMBINATION_N_BIT 0x08
-#define VIDEO_STD_NTSC_4_43_BIT 0x0a
-#define VIDEO_STD_SECAM_BIT 0x0c
-
-#define VIDEO_STD_NTSC_MJ_BIT_AS 0x01
-#define VIDEO_STD_PAL_BDGHIN_BIT_AS 0x03
-#define VIDEO_STD_PAL_M_BIT_AS 0x05
-#define VIDEO_STD_PAL_COMBINATION_N_BIT_AS 0x07
-#define VIDEO_STD_NTSC_4_43_BIT_AS 0x09
-#define VIDEO_STD_SECAM_BIT_AS 0x0b
-
-/* Reserved 29h-2bh */
-
-#define TVP5150_CB_GAIN_FACT 0x2c /* Cb gain factor */
-#define TVP5150_CR_GAIN_FACTOR 0x2d /* Cr gain factor */
-#define TVP5150_MACROVISION_ON_CTR 0x2e /* Macrovision on counter */
-#define TVP5150_MACROVISION_OFF_CTR 0x2f /* Macrovision off counter */
-#define TVP5150_REV_SELECT 0x30 /* revision select (TVP5150AM1 only) */
-
-/* Reserved 31h-7Fh */
-
-#define TVP5150_MSB_DEV_ID 0x80 /* MSB of device ID */
-#define TVP5150_LSB_DEV_ID 0x81 /* LSB of device ID */
-#define TVP5150_ROM_MAJOR_VER 0x82 /* ROM major version */
-#define TVP5150_ROM_MINOR_VER 0x83 /* ROM minor version */
-#define TVP5150_VERT_LN_COUNT_MSB 0x84 /* Vertical line count MSB */
-#define TVP5150_VERT_LN_COUNT_LSB 0x85 /* Vertical line count LSB */
-#define TVP5150_INT_STATUS_REG_B 0x86 /* Interrupt status register B */
-#define TVP5150_INT_ACTIVE_REG_B 0x87 /* Interrupt active register B */
-#define TVP5150_STATUS_REG_1 0x88 /* Status register #1 */
-#define TVP5150_STATUS_REG_2 0x89 /* Status register #2 */
-#define TVP5150_STATUS_REG_3 0x8a /* Status register #3 */
-#define TVP5150_STATUS_REG_4 0x8b /* Status register #4 */
-#define TVP5150_STATUS_REG_5 0x8c /* Status register #5 */
-/* Reserved 8Dh-8Fh */
- /* Closed caption data registers */
-#define TVP5150_CC_DATA_INI 0x90
-#define TVP5150_CC_DATA_END 0x93
-
- /* WSS data registers */
-#define TVP5150_WSS_DATA_INI 0x94
-#define TVP5150_WSS_DATA_END 0x99
-
-/* VPS data registers */
-#define TVP5150_VPS_DATA_INI 0x9a
-#define TVP5150_VPS_DATA_END 0xa6
-
-/* VITC data registers */
-#define TVP5150_VITC_DATA_INI 0xa7
-#define TVP5150_VITC_DATA_END 0xaf
-
-#define TVP5150_VBI_FIFO_READ_DATA 0xb0 /* VBI FIFO read data */
-
-/* Teletext filter 1 */
-#define TVP5150_TELETEXT_FIL1_INI 0xb1
-#define TVP5150_TELETEXT_FIL1_END 0xb5
-
-/* Teletext filter 2 */
-#define TVP5150_TELETEXT_FIL2_INI 0xb6
-#define TVP5150_TELETEXT_FIL2_END 0xba
-
-#define TVP5150_TELETEXT_FIL_ENA 0xbb /* Teletext filter enable */
-/* Reserved BCh-BFh */
-#define TVP5150_INT_STATUS_REG_A 0xc0 /* Interrupt status register A */
-#define TVP5150_INT_ENABLE_REG_A 0xc1 /* Interrupt enable register A */
-#define TVP5150_INT_CONF 0xc2 /* Interrupt configuration */
-#define TVP5150_VDP_CONF_RAM_DATA 0xc3 /* VDP configuration RAM data */
-#define TVP5150_CONF_RAM_ADDR_LOW 0xc4 /* Configuration RAM address low byte */
-#define TVP5150_CONF_RAM_ADDR_HIGH 0xc5 /* Configuration RAM address high byte */
-#define TVP5150_VDP_STATUS_REG 0xc6 /* VDP status register */
-#define TVP5150_FIFO_WORD_COUNT 0xc7 /* FIFO word count */
-#define TVP5150_FIFO_INT_THRESHOLD 0xc8 /* FIFO interrupt threshold */
-#define TVP5150_FIFO_RESET 0xc9 /* FIFO reset */
-#define TVP5150_LINE_NUMBER_INT 0xca /* Line number interrupt */
-#define TVP5150_PIX_ALIGN_REG_LOW 0xcb /* Pixel alignment register low byte */
-#define TVP5150_PIX_ALIGN_REG_HIGH 0xcc /* Pixel alignment register high byte */
-#define TVP5150_FIFO_OUT_CTRL 0xcd /* FIFO output control */
-/* Reserved CEh */
-#define TVP5150_FULL_FIELD_ENA 0xcf /* Full field enable 1 */
-
-/* Line mode registers */
-#define TVP5150_LINE_MODE_INI 0xd0
-#define TVP5150_LINE_MODE_END 0xfb
-
-#define TVP5150_FULL_FIELD_MODE_REG 0xfc /* Full field mode register */
-/* Reserved FDh-FFh */
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c
deleted file mode 100644
index fb6a5b57eb8..00000000000
--- a/drivers/media/video/tvp7002.c
+++ /dev/null
@@ -1,1145 +0,0 @@
-/* Texas Instruments Triple 8-/10-BIT 165-/110-MSPS Video and Graphics
- * Digitizer with Horizontal PLL registers
- *
- * Copyright (C) 2009 Texas Instruments Inc
- * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>
- *
- * This code is partially based upon the TVP5150 driver
- * written by Mauro Carvalho Chehab (mchehab@infradead.org),
- * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com>
- * and the TVP7002 driver in the TI LSP 2.10.00.14. Revisions by
- * Muralidharan Karicheri and Snehaprabha Narnakaje (TI).
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/module.h>
-#include <linux/v4l2-dv-timings.h>
-#include <media/tvp7002.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ctrls.h>
-#include "tvp7002_reg.h"
-
-MODULE_DESCRIPTION("TI TVP7002 Video and Graphics Digitizer driver");
-MODULE_AUTHOR("Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>");
-MODULE_LICENSE("GPL");
-
-/* Module Name */
-#define TVP7002_MODULE_NAME "tvp7002"
-
-/* I2C retry attempts */
-#define I2C_RETRY_COUNT (5)
-
-/* End of registers */
-#define TVP7002_EOR 0x5c
-
-/* Read write definition for registers */
-#define TVP7002_READ 0
-#define TVP7002_WRITE 1
-#define TVP7002_RESERVED 2
-
-/* Interlaced vs progressive mask and shift */
-#define TVP7002_IP_SHIFT 5
-#define TVP7002_INPR_MASK (0x01 << TVP7002_IP_SHIFT)
-
-/* Shift for CPL and LPF registers */
-#define TVP7002_CL_SHIFT 8
-#define TVP7002_CL_MASK 0x0f
-
-/* Debug functions */
-static bool debug;
-module_param(debug, bool, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-2)");
-
-/* Structure for register values */
-struct i2c_reg_value {
- u8 reg;
- u8 value;
- u8 type;
-};
-
-/*
- * Register default values (according to tvp7002 datasheet)
- * In the case of read-only registers, the value (0xff) is
- * never written. R/W functionality is controlled by the
- * writable bit in the register struct definition.
- */
-static const struct i2c_reg_value tvp7002_init_default[] = {
- { TVP7002_CHIP_REV, 0xff, TVP7002_READ },
- { TVP7002_HPLL_FDBK_DIV_MSBS, 0x67, TVP7002_WRITE },
- { TVP7002_HPLL_FDBK_DIV_LSBS, 0x20, TVP7002_WRITE },
- { TVP7002_HPLL_CRTL, 0xa0, TVP7002_WRITE },
- { TVP7002_HPLL_PHASE_SEL, 0x80, TVP7002_WRITE },
- { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
- { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
- { TVP7002_HSYNC_OUT_W, 0x60, TVP7002_WRITE },
- { TVP7002_B_FINE_GAIN, 0x00, TVP7002_WRITE },
- { TVP7002_G_FINE_GAIN, 0x00, TVP7002_WRITE },
- { TVP7002_R_FINE_GAIN, 0x00, TVP7002_WRITE },
- { TVP7002_B_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
- { TVP7002_G_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
- { TVP7002_R_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
- { TVP7002_SYNC_CTL_1, 0x20, TVP7002_WRITE },
- { TVP7002_HPLL_AND_CLAMP_CTL, 0x2e, TVP7002_WRITE },
- { TVP7002_SYNC_ON_G_THRS, 0x5d, TVP7002_WRITE },
- { TVP7002_SYNC_SEPARATOR_THRS, 0x47, TVP7002_WRITE },
- { TVP7002_HPLL_PRE_COAST, 0x00, TVP7002_WRITE },
- { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
- { TVP7002_SYNC_DETECT_STAT, 0xff, TVP7002_READ },
- { TVP7002_OUT_FORMATTER, 0x47, TVP7002_WRITE },
- { TVP7002_MISC_CTL_1, 0x01, TVP7002_WRITE },
- { TVP7002_MISC_CTL_2, 0x00, TVP7002_WRITE },
- { TVP7002_MISC_CTL_3, 0x01, TVP7002_WRITE },
- { TVP7002_IN_MUX_SEL_1, 0x00, TVP7002_WRITE },
- { TVP7002_IN_MUX_SEL_2, 0x67, TVP7002_WRITE },
- { TVP7002_B_AND_G_COARSE_GAIN, 0x77, TVP7002_WRITE },
- { TVP7002_R_COARSE_GAIN, 0x07, TVP7002_WRITE },
- { TVP7002_FINE_OFF_LSBS, 0x00, TVP7002_WRITE },
- { TVP7002_B_COARSE_OFF, 0x10, TVP7002_WRITE },
- { TVP7002_G_COARSE_OFF, 0x10, TVP7002_WRITE },
- { TVP7002_R_COARSE_OFF, 0x10, TVP7002_WRITE },
- { TVP7002_HSOUT_OUT_START, 0x08, TVP7002_WRITE },
- { TVP7002_MISC_CTL_4, 0x00, TVP7002_WRITE },
- { TVP7002_B_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
- { TVP7002_G_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
- { TVP7002_R_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
- { TVP7002_AUTO_LVL_CTL_ENABLE, 0x80, TVP7002_WRITE },
- { TVP7002_DGTL_ALC_OUT_MSBS, 0xff, TVP7002_READ },
- { TVP7002_AUTO_LVL_CTL_FILTER, 0x53, TVP7002_WRITE },
- { 0x29, 0x08, TVP7002_RESERVED },
- { TVP7002_FINE_CLAMP_CTL, 0x07, TVP7002_WRITE },
- /* PWR_CTL is controlled only by the probe and reset functions */
- { TVP7002_PWR_CTL, 0x00, TVP7002_RESERVED },
- { TVP7002_ADC_SETUP, 0x50, TVP7002_WRITE },
- { TVP7002_COARSE_CLAMP_CTL, 0x00, TVP7002_WRITE },
- { TVP7002_SOG_CLAMP, 0x80, TVP7002_WRITE },
- { TVP7002_RGB_COARSE_CLAMP_CTL, 0x8c, TVP7002_WRITE },
- { TVP7002_SOG_COARSE_CLAMP_CTL, 0x04, TVP7002_WRITE },
- { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
- { 0x32, 0x18, TVP7002_RESERVED },
- { 0x33, 0x60, TVP7002_RESERVED },
- { TVP7002_MVIS_STRIPPER_W, 0xff, TVP7002_RESERVED },
- { TVP7002_VSYNC_ALGN, 0x10, TVP7002_WRITE },
- { TVP7002_SYNC_BYPASS, 0x00, TVP7002_WRITE },
- { TVP7002_L_FRAME_STAT_LSBS, 0xff, TVP7002_READ },
- { TVP7002_L_FRAME_STAT_MSBS, 0xff, TVP7002_READ },
- { TVP7002_CLK_L_STAT_LSBS, 0xff, TVP7002_READ },
- { TVP7002_CLK_L_STAT_MSBS, 0xff, TVP7002_READ },
- { TVP7002_HSYNC_W, 0xff, TVP7002_READ },
- { TVP7002_VSYNC_W, 0xff, TVP7002_READ },
- { TVP7002_L_LENGTH_TOL, 0x03, TVP7002_WRITE },
- { 0x3e, 0x60, TVP7002_RESERVED },
- { TVP7002_VIDEO_BWTH_CTL, 0x01, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_LSBS, 0x01, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_MSBS, 0x2c, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_LSBS, 0x06, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_MSBS, 0x2c, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_DURATION, 0x1e, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
- { TVP7002_FBIT_F_0_START_L_OFF, 0x00, TVP7002_WRITE },
- { TVP7002_FBIT_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
- { TVP7002_YUV_Y_G_COEF_LSBS, 0xe3, TVP7002_WRITE },
- { TVP7002_YUV_Y_G_COEF_MSBS, 0x16, TVP7002_WRITE },
- { TVP7002_YUV_Y_B_COEF_LSBS, 0x4f, TVP7002_WRITE },
- { TVP7002_YUV_Y_B_COEF_MSBS, 0x02, TVP7002_WRITE },
- { TVP7002_YUV_Y_R_COEF_LSBS, 0xce, TVP7002_WRITE },
- { TVP7002_YUV_Y_R_COEF_MSBS, 0x06, TVP7002_WRITE },
- { TVP7002_YUV_U_G_COEF_LSBS, 0xab, TVP7002_WRITE },
- { TVP7002_YUV_U_G_COEF_MSBS, 0xf3, TVP7002_WRITE },
- { TVP7002_YUV_U_B_COEF_LSBS, 0x00, TVP7002_WRITE },
- { TVP7002_YUV_U_B_COEF_MSBS, 0x10, TVP7002_WRITE },
- { TVP7002_YUV_U_R_COEF_LSBS, 0x55, TVP7002_WRITE },
- { TVP7002_YUV_U_R_COEF_MSBS, 0xfc, TVP7002_WRITE },
- { TVP7002_YUV_V_G_COEF_LSBS, 0x78, TVP7002_WRITE },
- { TVP7002_YUV_V_G_COEF_MSBS, 0xf1, TVP7002_WRITE },
- { TVP7002_YUV_V_B_COEF_LSBS, 0x88, TVP7002_WRITE },
- { TVP7002_YUV_V_B_COEF_MSBS, 0xfe, TVP7002_WRITE },
- { TVP7002_YUV_V_R_COEF_LSBS, 0x00, TVP7002_WRITE },
- { TVP7002_YUV_V_R_COEF_MSBS, 0x10, TVP7002_WRITE },
- /* This signals end of register values */
- { TVP7002_EOR, 0xff, TVP7002_RESERVED }
-};
-
-/* Register parameters for 480P */
-static const struct i2c_reg_value tvp7002_parms_480P[] = {
- { TVP7002_HPLL_FDBK_DIV_MSBS, 0x35, TVP7002_WRITE },
- { TVP7002_HPLL_FDBK_DIV_LSBS, 0xa0, TVP7002_WRITE },
- { TVP7002_HPLL_CRTL, 0x02, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_LSBS, 0x91, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_MSBS, 0x00, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_LSBS, 0x0B, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_MSBS, 0x00, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_START_L_OFF, 0x03, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_START_L_OFF, 0x01, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_DURATION, 0x13, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_DURATION, 0x13, TVP7002_WRITE },
- { TVP7002_ALC_PLACEMENT, 0x18, TVP7002_WRITE },
- { TVP7002_CLAMP_START, 0x06, TVP7002_WRITE },
- { TVP7002_CLAMP_W, 0x10, TVP7002_WRITE },
- { TVP7002_HPLL_PRE_COAST, 0x03, TVP7002_WRITE },
- { TVP7002_HPLL_POST_COAST, 0x03, TVP7002_WRITE },
- { TVP7002_EOR, 0xff, TVP7002_RESERVED }
-};
-
-/* Register parameters for 576P */
-static const struct i2c_reg_value tvp7002_parms_576P[] = {
- { TVP7002_HPLL_FDBK_DIV_MSBS, 0x36, TVP7002_WRITE },
- { TVP7002_HPLL_FDBK_DIV_LSBS, 0x00, TVP7002_WRITE },
- { TVP7002_HPLL_CRTL, 0x18, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_LSBS, 0x9B, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_MSBS, 0x00, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_LSBS, 0x0F, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_MSBS, 0x00, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_START_L_OFF, 0x00, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
- { TVP7002_ALC_PLACEMENT, 0x18, TVP7002_WRITE },
- { TVP7002_CLAMP_START, 0x06, TVP7002_WRITE },
- { TVP7002_CLAMP_W, 0x10, TVP7002_WRITE },
- { TVP7002_HPLL_PRE_COAST, 0x03, TVP7002_WRITE },
- { TVP7002_HPLL_POST_COAST, 0x03, TVP7002_WRITE },
- { TVP7002_EOR, 0xff, TVP7002_RESERVED }
-};
-
-/* Register parameters for 1080I60 */
-static const struct i2c_reg_value tvp7002_parms_1080I60[] = {
- { TVP7002_HPLL_FDBK_DIV_MSBS, 0x89, TVP7002_WRITE },
- { TVP7002_HPLL_FDBK_DIV_LSBS, 0x80, TVP7002_WRITE },
- { TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
- { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
- { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
- { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
- { TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
- { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
- { TVP7002_EOR, 0xff, TVP7002_RESERVED }
-};
-
-/* Register parameters for 1080P60 */
-static const struct i2c_reg_value tvp7002_parms_1080P60[] = {
- { TVP7002_HPLL_FDBK_DIV_MSBS, 0x89, TVP7002_WRITE },
- { TVP7002_HPLL_FDBK_DIV_LSBS, 0x80, TVP7002_WRITE },
- { TVP7002_HPLL_CRTL, 0xE0, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
- { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
- { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
- { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
- { TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
- { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
- { TVP7002_EOR, 0xff, TVP7002_RESERVED }
-};
-
-/* Register parameters for 1080I50 */
-static const struct i2c_reg_value tvp7002_parms_1080I50[] = {
- { TVP7002_HPLL_FDBK_DIV_MSBS, 0xa5, TVP7002_WRITE },
- { TVP7002_HPLL_FDBK_DIV_LSBS, 0x00, TVP7002_WRITE },
- { TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
- { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
- { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
- { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
- { TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
- { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
- { TVP7002_EOR, 0xff, TVP7002_RESERVED }
-};
-
-/* Register parameters for 720P60 */
-static const struct i2c_reg_value tvp7002_parms_720P60[] = {
- { TVP7002_HPLL_FDBK_DIV_MSBS, 0x67, TVP7002_WRITE },
- { TVP7002_HPLL_FDBK_DIV_LSBS, 0x20, TVP7002_WRITE },
- { TVP7002_HPLL_CRTL, 0xa0, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_LSBS, 0x47, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_LSBS, 0x4B, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_MSBS, 0x06, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
- { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
- { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
- { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
- { TVP7002_HPLL_PRE_COAST, 0x00, TVP7002_WRITE },
- { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
- { TVP7002_EOR, 0xff, TVP7002_RESERVED }
-};
-
-/* Register parameters for 720P50 */
-static const struct i2c_reg_value tvp7002_parms_720P50[] = {
- { TVP7002_HPLL_FDBK_DIV_MSBS, 0x7b, TVP7002_WRITE },
- { TVP7002_HPLL_FDBK_DIV_LSBS, 0xc0, TVP7002_WRITE },
- { TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_LSBS, 0x47, TVP7002_WRITE },
- { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_LSBS, 0x4B, TVP7002_WRITE },
- { TVP7002_AVID_STOP_PIXEL_MSBS, 0x06, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
- { TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
- { TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
- { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
- { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
- { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
- { TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
- { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
- { TVP7002_EOR, 0xff, TVP7002_RESERVED }
-};
-
-/* Preset definition for handling device operation */
-struct tvp7002_preset_definition {
- u32 preset;
- struct v4l2_dv_timings timings;
- const struct i2c_reg_value *p_settings;
- enum v4l2_colorspace color_space;
- enum v4l2_field scanmode;
- u16 progressive;
- u16 lines_per_frame;
- u16 cpl_min;
- u16 cpl_max;
-};
-
-/* Struct list for digital video presets */
-static const struct tvp7002_preset_definition tvp7002_presets[] = {
- {
- V4L2_DV_720P60,
- V4L2_DV_BT_CEA_1280X720P60,
- tvp7002_parms_720P60,
- V4L2_COLORSPACE_REC709,
- V4L2_FIELD_NONE,
- 1,
- 0x2EE,
- 135,
- 153
- },
- {
- V4L2_DV_1080I60,
- V4L2_DV_BT_CEA_1920X1080I60,
- tvp7002_parms_1080I60,
- V4L2_COLORSPACE_REC709,
- V4L2_FIELD_INTERLACED,
- 0,
- 0x465,
- 181,
- 205
- },
- {
- V4L2_DV_1080I50,
- V4L2_DV_BT_CEA_1920X1080I50,
- tvp7002_parms_1080I50,
- V4L2_COLORSPACE_REC709,
- V4L2_FIELD_INTERLACED,
- 0,
- 0x465,
- 217,
- 245
- },
- {
- V4L2_DV_720P50,
- V4L2_DV_BT_CEA_1280X720P50,
- tvp7002_parms_720P50,
- V4L2_COLORSPACE_REC709,
- V4L2_FIELD_NONE,
- 1,
- 0x2EE,
- 163,
- 183
- },
- {
- V4L2_DV_1080P60,
- V4L2_DV_BT_CEA_1920X1080P60,
- tvp7002_parms_1080P60,
- V4L2_COLORSPACE_REC709,
- V4L2_FIELD_NONE,
- 1,
- 0x465,
- 90,
- 102
- },
- {
- V4L2_DV_480P59_94,
- V4L2_DV_BT_CEA_720X480P59_94,
- tvp7002_parms_480P,
- V4L2_COLORSPACE_SMPTE170M,
- V4L2_FIELD_NONE,
- 1,
- 0x20D,
- 0xffff,
- 0xffff
- },
- {
- V4L2_DV_576P50,
- V4L2_DV_BT_CEA_720X576P50,
- tvp7002_parms_576P,
- V4L2_COLORSPACE_SMPTE170M,
- V4L2_FIELD_NONE,
- 1,
- 0x271,
- 0xffff,
- 0xffff
- }
-};
-
-#define NUM_PRESETS ARRAY_SIZE(tvp7002_presets)
-
-/* Device definition */
-struct tvp7002 {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- const struct tvp7002_config *pdata;
-
- int ver;
- int streaming;
-
- const struct tvp7002_preset_definition *current_preset;
-};
-
-/*
- * to_tvp7002 - Obtain device handler TVP7002
- * @sd: ptr to v4l2_subdev struct
- *
- * Returns device handler tvp7002.
- */
-static inline struct tvp7002 *to_tvp7002(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct tvp7002, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct tvp7002, hdl)->sd;
-}
-
-/*
- * tvp7002_read - Read a value from a register in an TVP7002
- * @sd: ptr to v4l2_subdev struct
- * @addr: TVP7002 register address
- * @dst: pointer to 8-bit destination
- *
- * Returns value read if successful, or non-zero (-1) otherwise.
- */
-static int tvp7002_read(struct v4l2_subdev *sd, u8 addr, u8 *dst)
-{
- struct i2c_client *c = v4l2_get_subdevdata(sd);
- int retry;
- int error;
-
- for (retry = 0; retry < I2C_RETRY_COUNT; retry++) {
- error = i2c_smbus_read_byte_data(c, addr);
-
- if (error >= 0) {
- *dst = (u8)error;
- return 0;
- }
-
- msleep_interruptible(10);
- }
- v4l2_err(sd, "TVP7002 read error %d\n", error);
- return error;
-}
-
-/*
- * tvp7002_read_err() - Read a register value with error code
- * @sd: pointer to standard V4L2 sub-device structure
- * @reg: destination register
- * @val: value to be read
- * @err: pointer to error value
- *
- * Read a value in a register and save error value in pointer.
- * Also update the register table if successful
- */
-static inline void tvp7002_read_err(struct v4l2_subdev *sd, u8 reg,
- u8 *dst, int *err)
-{
- if (!*err)
- *err = tvp7002_read(sd, reg, dst);
-}
-
-/*
- * tvp7002_write() - Write a value to a register in TVP7002
- * @sd: ptr to v4l2_subdev struct
- * @addr: TVP7002 register address
- * @value: value to be written to the register
- *
- * Write a value to a register in an TVP7002 decoder device.
- * Returns zero if successful, or non-zero otherwise.
- */
-static int tvp7002_write(struct v4l2_subdev *sd, u8 addr, u8 value)
-{
- struct i2c_client *c;
- int retry;
- int error;
-
- c = v4l2_get_subdevdata(sd);
-
- for (retry = 0; retry < I2C_RETRY_COUNT; retry++) {
- error = i2c_smbus_write_byte_data(c, addr, value);
-
- if (error >= 0)
- return 0;
-
- v4l2_warn(sd, "Write: retry ... %d\n", retry);
- msleep_interruptible(10);
- }
- v4l2_err(sd, "TVP7002 write error %d\n", error);
- return error;
-}
-
-/*
- * tvp7002_write_err() - Write a register value with error code
- * @sd: pointer to standard V4L2 sub-device structure
- * @reg: destination register
- * @val: value to be written
- * @err: pointer to error value
- *
- * Write a value in a register and save error value in pointer.
- * Also update the register table if successful
- */
-static inline void tvp7002_write_err(struct v4l2_subdev *sd, u8 reg,
- u8 val, int *err)
-{
- if (!*err)
- *err = tvp7002_write(sd, reg, val);
-}
-
-/*
- * tvp7002_g_chip_ident() - Get chip identification number
- * @sd: ptr to v4l2_subdev struct
- * @chip: ptr to v4l2_dbg_chip_ident struct
- *
- * Obtains the chip's identification number.
- * Returns zero or -EINVAL if read operation fails.
- */
-static int tvp7002_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- u8 rev;
- int error;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- error = tvp7002_read(sd, TVP7002_CHIP_REV, &rev);
-
- if (error < 0)
- return error;
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP7002, rev);
-}
-
-/*
- * tvp7002_write_inittab() - Write initialization values
- * @sd: ptr to v4l2_subdev struct
- * @regs: ptr to i2c_reg_value struct
- *
- * Write initialization values.
- * Returns zero or -EINVAL if read operation fails.
- */
-static int tvp7002_write_inittab(struct v4l2_subdev *sd,
- const struct i2c_reg_value *regs)
-{
- int error = 0;
-
- /* Initialize the first (defined) registers */
- while (TVP7002_EOR != regs->reg) {
- if (TVP7002_WRITE == regs->type)
- tvp7002_write_err(sd, regs->reg, regs->value, &error);
- regs++;
- }
-
- return error;
-}
-
-/*
- * tvp7002_s_dv_preset() - Set digital video preset
- * @sd: ptr to v4l2_subdev struct
- * @dv_preset: ptr to v4l2_dv_preset struct
- *
- * Set the digital video preset for a TVP7002 decoder device.
- * Returns zero when successful or -EINVAL if register access fails.
- */
-static int tvp7002_s_dv_preset(struct v4l2_subdev *sd,
- struct v4l2_dv_preset *dv_preset)
-{
- struct tvp7002 *device = to_tvp7002(sd);
- u32 preset;
- int i;
-
- for (i = 0; i < NUM_PRESETS; i++) {
- preset = tvp7002_presets[i].preset;
- if (preset == dv_preset->preset) {
- device->current_preset = &tvp7002_presets[i];
- return tvp7002_write_inittab(sd, tvp7002_presets[i].p_settings);
- }
- }
-
- return -EINVAL;
-}
-
-static int tvp7002_s_dv_timings(struct v4l2_subdev *sd,
- struct v4l2_dv_timings *dv_timings)
-{
- struct tvp7002 *device = to_tvp7002(sd);
- const struct v4l2_bt_timings *bt = &dv_timings->bt;
- int i;
-
- if (dv_timings->type != V4L2_DV_BT_656_1120)
- return -EINVAL;
- for (i = 0; i < NUM_PRESETS; i++) {
- const struct v4l2_bt_timings *t = &tvp7002_presets[i].timings.bt;
-
- if (!memcmp(bt, t, &bt->standards - &bt->width)) {
- device->current_preset = &tvp7002_presets[i];
- return tvp7002_write_inittab(sd, tvp7002_presets[i].p_settings);
- }
- }
- return -EINVAL;
-}
-
-static int tvp7002_g_dv_timings(struct v4l2_subdev *sd,
- struct v4l2_dv_timings *dv_timings)
-{
- struct tvp7002 *device = to_tvp7002(sd);
-
- *dv_timings = device->current_preset->timings;
- return 0;
-}
-
-/*
- * tvp7002_s_ctrl() - Set a control
- * @ctrl: ptr to v4l2_ctrl struct
- *
- * Set a control in TVP7002 decoder device.
- * Returns zero when successful or -EINVAL if register access fails.
- */
-static int tvp7002_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- int error = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- tvp7002_write_err(sd, TVP7002_R_FINE_GAIN, ctrl->val, &error);
- tvp7002_write_err(sd, TVP7002_G_FINE_GAIN, ctrl->val, &error);
- tvp7002_write_err(sd, TVP7002_B_FINE_GAIN, ctrl->val, &error);
- return error;
- }
- return -EINVAL;
-}
-
-/*
- * tvp7002_mbus_fmt() - V4L2 decoder interface handler for try/s/g_mbus_fmt
- * @sd: pointer to standard V4L2 sub-device structure
- * @f: pointer to mediabus format structure
- *
- * Negotiate the image capture size and mediabus format.
- * There is only one possible format, so this single function works for
- * get, set and try.
- */
-static int tvp7002_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
-{
- struct tvp7002 *device = to_tvp7002(sd);
- struct v4l2_dv_enum_preset e_preset;
- int error;
-
- /* Calculate height and width based on current standard */
- error = v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset);
- if (error)
- return error;
-
- f->width = e_preset.width;
- f->height = e_preset.height;
- f->code = V4L2_MBUS_FMT_YUYV10_1X20;
- f->field = device->current_preset->scanmode;
- f->colorspace = device->current_preset->color_space;
-
- v4l2_dbg(1, debug, sd, "MBUS_FMT: Width - %d, Height - %d",
- f->width, f->height);
- return 0;
-}
-
-/*
- * tvp7002_query_dv_preset() - query DV preset
- * @sd: pointer to standard V4L2 sub-device structure
- * @qpreset: standard V4L2 v4l2_dv_preset structure
- *
- * Returns the current DV preset by TVP7002. If no active input is
- * detected, returns -EINVAL
- */
-static int tvp7002_query_dv(struct v4l2_subdev *sd, int *index)
-{
- const struct tvp7002_preset_definition *presets = tvp7002_presets;
- u8 progressive;
- u32 lpfr;
- u32 cpln;
- int error = 0;
- u8 lpf_lsb;
- u8 lpf_msb;
- u8 cpl_lsb;
- u8 cpl_msb;
-
- /* Return invalid index if no active input is detected */
- *index = NUM_PRESETS;
-
- /* Read standards from device registers */
- tvp7002_read_err(sd, TVP7002_L_FRAME_STAT_LSBS, &lpf_lsb, &error);
- tvp7002_read_err(sd, TVP7002_L_FRAME_STAT_MSBS, &lpf_msb, &error);
-
- if (error < 0)
- return error;
-
- tvp7002_read_err(sd, TVP7002_CLK_L_STAT_LSBS, &cpl_lsb, &error);
- tvp7002_read_err(sd, TVP7002_CLK_L_STAT_MSBS, &cpl_msb, &error);
-
- if (error < 0)
- return error;
-
- /* Get lines per frame, clocks per line and interlaced/progresive */
- lpfr = lpf_lsb | ((TVP7002_CL_MASK & lpf_msb) << TVP7002_CL_SHIFT);
- cpln = cpl_lsb | ((TVP7002_CL_MASK & cpl_msb) << TVP7002_CL_SHIFT);
- progressive = (lpf_msb & TVP7002_INPR_MASK) >> TVP7002_IP_SHIFT;
-
- /* Do checking of video modes */
- for (*index = 0; *index < NUM_PRESETS; (*index)++, presets++)
- if (lpfr == presets->lines_per_frame &&
- progressive == presets->progressive) {
- if (presets->cpl_min == 0xffff)
- break;
- if (cpln >= presets->cpl_min && cpln <= presets->cpl_max)
- break;
- }
-
- if (*index == NUM_PRESETS) {
- v4l2_dbg(1, debug, sd, "detection failed: lpf = %x, cpl = %x\n",
- lpfr, cpln);
- return -ENOLINK;
- }
-
- /* Update lines per frame and clocks per line info */
- v4l2_dbg(1, debug, sd, "detected preset: %d\n", *index);
- return 0;
-}
-
-static int tvp7002_query_dv_preset(struct v4l2_subdev *sd,
- struct v4l2_dv_preset *qpreset)
-{
- int index;
- int err = tvp7002_query_dv(sd, &index);
-
- if (err || index == NUM_PRESETS) {
- qpreset->preset = V4L2_DV_INVALID;
- if (err == -ENOLINK)
- err = 0;
- return err;
- }
- qpreset->preset = tvp7002_presets[index].preset;
- return 0;
-}
-
-static int tvp7002_query_dv_timings(struct v4l2_subdev *sd,
- struct v4l2_dv_timings *timings)
-{
- int index;
- int err = tvp7002_query_dv(sd, &index);
-
- if (err)
- return err;
- *timings = tvp7002_presets[index].timings;
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-/*
- * tvp7002_g_register() - Get the value of a register
- * @sd: ptr to v4l2_subdev struct
- * @reg: ptr to v4l2_dbg_register struct
- *
- * Get the value of a TVP7002 decoder device register.
- * Returns zero when successful, -EINVAL if register read fails or
- * access to I2C client fails, -EPERM if the call is not allowed
- * by disabled CAP_SYS_ADMIN.
- */
-static int tvp7002_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 val;
- int ret;
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- ret = tvp7002_read(sd, reg->reg & 0xff, &val);
- reg->val = val;
- return ret;
-}
-
-/*
- * tvp7002_s_register() - set a control
- * @sd: ptr to v4l2_subdev struct
- * @reg: ptr to v4l2_dbg_register struct
- *
- * Get the value of a TVP7002 decoder device register.
- * Returns zero when successful, -EINVAL if register read fails or
- * -EPERM if call not allowed.
- */
-static int tvp7002_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- return tvp7002_write(sd, reg->reg & 0xff, reg->val & 0xff);
-}
-#endif
-
-/*
- * tvp7002_enum_mbus_fmt() - Enum supported mediabus formats
- * @sd: pointer to standard V4L2 sub-device structure
- * @index: format index
- * @code: pointer to mediabus format
- *
- * Enumerate supported mediabus formats.
- */
-
-static int tvp7002_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
- enum v4l2_mbus_pixelcode *code)
-{
- /* Check requested format index is within range */
- if (index)
- return -EINVAL;
- *code = V4L2_MBUS_FMT_YUYV10_1X20;
- return 0;
-}
-
-/*
- * tvp7002_s_stream() - V4L2 decoder i/f handler for s_stream
- * @sd: pointer to standard V4L2 sub-device structure
- * @enable: streaming enable or disable
- *
- * Sets streaming to enable or disable, if possible.
- */
-static int tvp7002_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct tvp7002 *device = to_tvp7002(sd);
- int error = 0;
-
- if (device->streaming == enable)
- return 0;
-
- if (enable) {
- /* Set output state on (low impedance means stream on) */
- error = tvp7002_write(sd, TVP7002_MISC_CTL_2, 0x00);
- device->streaming = enable;
- } else {
- /* Set output state off (high impedance means stream off) */
- error = tvp7002_write(sd, TVP7002_MISC_CTL_2, 0x03);
- if (error)
- v4l2_dbg(1, debug, sd, "Unable to stop streaming\n");
-
- device->streaming = enable;
- }
-
- return error;
-}
-
-/*
- * tvp7002_log_status() - Print information about register settings
- * @sd: ptr to v4l2_subdev struct
- *
- * Log register values of a TVP7002 decoder device.
- * Returns zero or -EINVAL if read operation fails.
- */
-static int tvp7002_log_status(struct v4l2_subdev *sd)
-{
- const struct tvp7002_preset_definition *presets = tvp7002_presets;
- struct tvp7002 *device = to_tvp7002(sd);
- struct v4l2_dv_enum_preset e_preset;
- struct v4l2_dv_preset detected;
- int i;
-
- detected.preset = V4L2_DV_INVALID;
- /* Find my current standard*/
- tvp7002_query_dv_preset(sd, &detected);
-
- /* Print standard related code values */
- for (i = 0; i < NUM_PRESETS; i++, presets++)
- if (presets->preset == detected.preset)
- break;
-
- if (v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset))
- return -EINVAL;
-
- v4l2_info(sd, "Selected DV Preset: %s\n", e_preset.name);
- v4l2_info(sd, " Pixels per line: %u\n", e_preset.width);
- v4l2_info(sd, " Lines per frame: %u\n\n", e_preset.height);
- if (i == NUM_PRESETS) {
- v4l2_info(sd, "Detected DV Preset: None\n");
- } else {
- if (v4l_fill_dv_preset_info(presets->preset, &e_preset))
- return -EINVAL;
- v4l2_info(sd, "Detected DV Preset: %s\n", e_preset.name);
- v4l2_info(sd, " Pixels per line: %u\n", e_preset.width);
- v4l2_info(sd, " Lines per frame: %u\n\n", e_preset.height);
- }
- v4l2_info(sd, "Streaming enabled: %s\n",
- device->streaming ? "yes" : "no");
-
- /* Print the current value of the gain control */
- v4l2_ctrl_handler_log_status(&device->hdl, sd->name);
-
- return 0;
-}
-
-/*
- * tvp7002_enum_dv_presets() - Enum supported digital video formats
- * @sd: pointer to standard V4L2 sub-device structure
- * @preset: pointer to format struct
- *
- * Enumerate supported digital video formats.
- */
-static int tvp7002_enum_dv_presets(struct v4l2_subdev *sd,
- struct v4l2_dv_enum_preset *preset)
-{
- /* Check requested format index is within range */
- if (preset->index >= NUM_PRESETS)
- return -EINVAL;
-
- return v4l_fill_dv_preset_info(tvp7002_presets[preset->index].preset, preset);
-}
-
-static int tvp7002_enum_dv_timings(struct v4l2_subdev *sd,
- struct v4l2_enum_dv_timings *timings)
-{
- /* Check requested format index is within range */
- if (timings->index >= NUM_PRESETS)
- return -EINVAL;
-
- timings->timings = tvp7002_presets[timings->index].timings;
- return 0;
-}
-
-static const struct v4l2_ctrl_ops tvp7002_ctrl_ops = {
- .s_ctrl = tvp7002_s_ctrl,
-};
-
-/* V4L2 core operation handlers */
-static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
- .g_chip_ident = tvp7002_g_chip_ident,
- .log_status = tvp7002_log_status,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = tvp7002_g_register,
- .s_register = tvp7002_s_register,
-#endif
-};
-
-/* Specific video subsystem operation handlers */
-static const struct v4l2_subdev_video_ops tvp7002_video_ops = {
- .enum_dv_presets = tvp7002_enum_dv_presets,
- .s_dv_preset = tvp7002_s_dv_preset,
- .query_dv_preset = tvp7002_query_dv_preset,
- .g_dv_timings = tvp7002_g_dv_timings,
- .s_dv_timings = tvp7002_s_dv_timings,
- .enum_dv_timings = tvp7002_enum_dv_timings,
- .query_dv_timings = tvp7002_query_dv_timings,
- .s_stream = tvp7002_s_stream,
- .g_mbus_fmt = tvp7002_mbus_fmt,
- .try_mbus_fmt = tvp7002_mbus_fmt,
- .s_mbus_fmt = tvp7002_mbus_fmt,
- .enum_mbus_fmt = tvp7002_enum_mbus_fmt,
-};
-
-/* V4L2 top level operation handlers */
-static const struct v4l2_subdev_ops tvp7002_ops = {
- .core = &tvp7002_core_ops,
- .video = &tvp7002_video_ops,
-};
-
-/*
- * tvp7002_probe - Probe a TVP7002 device
- * @c: ptr to i2c_client struct
- * @id: ptr to i2c_device_id struct
- *
- * Initialize the TVP7002 device
- * Returns zero when successful, -EINVAL if register read fails or
- * -EIO if i2c access is not available.
- */
-static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
-{
- struct v4l2_subdev *sd;
- struct tvp7002 *device;
- struct v4l2_dv_preset preset;
- int polarity_a;
- int polarity_b;
- u8 revision;
-
- int error;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(c->adapter,
- I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
- return -EIO;
-
- if (!c->dev.platform_data) {
- v4l_err(c, "No platform data!!\n");
- return -ENODEV;
- }
-
- device = kzalloc(sizeof(struct tvp7002), GFP_KERNEL);
-
- if (!device)
- return -ENOMEM;
-
- sd = &device->sd;
- device->pdata = c->dev.platform_data;
- device->current_preset = tvp7002_presets;
-
- /* Tell v4l2 the device is ready */
- v4l2_i2c_subdev_init(sd, c, &tvp7002_ops);
- v4l_info(c, "tvp7002 found @ 0x%02x (%s)\n",
- c->addr, c->adapter->name);
-
- error = tvp7002_read(sd, TVP7002_CHIP_REV, &revision);
- if (error < 0)
- goto found_error;
-
- /* Get revision number */
- v4l2_info(sd, "Rev. %02x detected.\n", revision);
- if (revision != 0x02)
- v4l2_info(sd, "Unknown revision detected.\n");
-
- /* Initializes TVP7002 to its default values */
- error = tvp7002_write_inittab(sd, tvp7002_init_default);
-
- if (error < 0)
- goto found_error;
-
- /* Set polarity information after registers have been set */
- polarity_a = 0x20 | device->pdata->hs_polarity << 5
- | device->pdata->vs_polarity << 2;
- error = tvp7002_write(sd, TVP7002_SYNC_CTL_1, polarity_a);
- if (error < 0)
- goto found_error;
-
- polarity_b = 0x01 | device->pdata->fid_polarity << 2
- | device->pdata->sog_polarity << 1
- | device->pdata->clk_polarity;
- error = tvp7002_write(sd, TVP7002_MISC_CTL_3, polarity_b);
- if (error < 0)
- goto found_error;
-
- /* Set registers according to default video mode */
- preset.preset = device->current_preset->preset;
- error = tvp7002_s_dv_preset(sd, &preset);
-
- v4l2_ctrl_handler_init(&device->hdl, 1);
- v4l2_ctrl_new_std(&device->hdl, &tvp7002_ctrl_ops,
- V4L2_CID_GAIN, 0, 255, 1, 0);
- sd->ctrl_handler = &device->hdl;
- if (device->hdl.error) {
- int err = device->hdl.error;
-
- v4l2_ctrl_handler_free(&device->hdl);
- kfree(device);
- return err;
- }
- v4l2_ctrl_handler_setup(&device->hdl);
-
-found_error:
- if (error < 0)
- kfree(device);
-
- return error;
-}
-
-/*
- * tvp7002_remove - Remove TVP7002 device support
- * @c: ptr to i2c_client struct
- *
- * Reset the TVP7002 device
- * Returns zero.
- */
-static int tvp7002_remove(struct i2c_client *c)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(c);
- struct tvp7002 *device = to_tvp7002(sd);
-
- v4l2_dbg(1, debug, sd, "Removing tvp7002 adapter"
- "on address 0x%x\n", c->addr);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&device->hdl);
- kfree(device);
- return 0;
-}
-
-/* I2C Device ID table */
-static const struct i2c_device_id tvp7002_id[] = {
- { "tvp7002", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tvp7002_id);
-
-/* I2C driver data */
-static struct i2c_driver tvp7002_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = TVP7002_MODULE_NAME,
- },
- .probe = tvp7002_probe,
- .remove = tvp7002_remove,
- .id_table = tvp7002_id,
-};
-
-module_i2c_driver(tvp7002_driver);
diff --git a/drivers/media/video/tvp7002_reg.h b/drivers/media/video/tvp7002_reg.h
deleted file mode 100644
index 0e34ca9bccf..00000000000
--- a/drivers/media/video/tvp7002_reg.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/* Texas Instruments Triple 8-/10-BIT 165-/110-MSPS Video and Graphics
- * Digitizer with Horizontal PLL registers
- *
- * Copyright (C) 2009 Texas Instruments Inc
- * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>
- *
- * This code is partially based upon the TVP5150 driver
- * written by Mauro Carvalho Chehab (mchehab@infradead.org),
- * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com>
- * and the TVP7002 driver in the TI LSP 2.10.00.14
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* Naming conventions
- * ------------------
- *
- * FDBK: Feedback
- * DIV: Divider
- * CTL: Control
- * SEL: Select
- * IN: Input
- * OUT: Output
- * R: Red
- * G: Green
- * B: Blue
- * OFF: Offset
- * THRS: Threshold
- * DGTL: Digital
- * LVL: Level
- * PWR: Power
- * MVIS: Macrovision
- * W: Width
- * H: Height
- * ALGN: Alignment
- * CLK: Clocks
- * TOL: Tolerance
- * BWTH: Bandwidth
- * COEF: Coefficient
- * STAT: Status
- * AUTO: Automatic
- * FLD: Field
- * L: Line
- */
-
-#define TVP7002_CHIP_REV 0x00
-#define TVP7002_HPLL_FDBK_DIV_MSBS 0x01
-#define TVP7002_HPLL_FDBK_DIV_LSBS 0x02
-#define TVP7002_HPLL_CRTL 0x03
-#define TVP7002_HPLL_PHASE_SEL 0x04
-#define TVP7002_CLAMP_START 0x05
-#define TVP7002_CLAMP_W 0x06
-#define TVP7002_HSYNC_OUT_W 0x07
-#define TVP7002_B_FINE_GAIN 0x08
-#define TVP7002_G_FINE_GAIN 0x09
-#define TVP7002_R_FINE_GAIN 0x0a
-#define TVP7002_B_FINE_OFF_MSBS 0x0b
-#define TVP7002_G_FINE_OFF_MSBS 0x0c
-#define TVP7002_R_FINE_OFF_MSBS 0x0d
-#define TVP7002_SYNC_CTL_1 0x0e
-#define TVP7002_HPLL_AND_CLAMP_CTL 0x0f
-#define TVP7002_SYNC_ON_G_THRS 0x10
-#define TVP7002_SYNC_SEPARATOR_THRS 0x11
-#define TVP7002_HPLL_PRE_COAST 0x12
-#define TVP7002_HPLL_POST_COAST 0x13
-#define TVP7002_SYNC_DETECT_STAT 0x14
-#define TVP7002_OUT_FORMATTER 0x15
-#define TVP7002_MISC_CTL_1 0x16
-#define TVP7002_MISC_CTL_2 0x17
-#define TVP7002_MISC_CTL_3 0x18
-#define TVP7002_IN_MUX_SEL_1 0x19
-#define TVP7002_IN_MUX_SEL_2 0x1a
-#define TVP7002_B_AND_G_COARSE_GAIN 0x1b
-#define TVP7002_R_COARSE_GAIN 0x1c
-#define TVP7002_FINE_OFF_LSBS 0x1d
-#define TVP7002_B_COARSE_OFF 0x1e
-#define TVP7002_G_COARSE_OFF 0x1f
-#define TVP7002_R_COARSE_OFF 0x20
-#define TVP7002_HSOUT_OUT_START 0x21
-#define TVP7002_MISC_CTL_4 0x22
-#define TVP7002_B_DGTL_ALC_OUT_LSBS 0x23
-#define TVP7002_G_DGTL_ALC_OUT_LSBS 0x24
-#define TVP7002_R_DGTL_ALC_OUT_LSBS 0x25
-#define TVP7002_AUTO_LVL_CTL_ENABLE 0x26
-#define TVP7002_DGTL_ALC_OUT_MSBS 0x27
-#define TVP7002_AUTO_LVL_CTL_FILTER 0x28
-/* Reserved 0x29*/
-#define TVP7002_FINE_CLAMP_CTL 0x2a
-#define TVP7002_PWR_CTL 0x2b
-#define TVP7002_ADC_SETUP 0x2c
-#define TVP7002_COARSE_CLAMP_CTL 0x2d
-#define TVP7002_SOG_CLAMP 0x2e
-#define TVP7002_RGB_COARSE_CLAMP_CTL 0x2f
-#define TVP7002_SOG_COARSE_CLAMP_CTL 0x30
-#define TVP7002_ALC_PLACEMENT 0x31
-/* Reserved 0x32 */
-/* Reserved 0x33 */
-#define TVP7002_MVIS_STRIPPER_W 0x34
-#define TVP7002_VSYNC_ALGN 0x35
-#define TVP7002_SYNC_BYPASS 0x36
-#define TVP7002_L_FRAME_STAT_LSBS 0x37
-#define TVP7002_L_FRAME_STAT_MSBS 0x38
-#define TVP7002_CLK_L_STAT_LSBS 0x39
-#define TVP7002_CLK_L_STAT_MSBS 0x3a
-#define TVP7002_HSYNC_W 0x3b
-#define TVP7002_VSYNC_W 0x3c
-#define TVP7002_L_LENGTH_TOL 0x3d
-/* Reserved 0x3e */
-#define TVP7002_VIDEO_BWTH_CTL 0x3f
-#define TVP7002_AVID_START_PIXEL_LSBS 0x40
-#define TVP7002_AVID_START_PIXEL_MSBS 0x41
-#define TVP7002_AVID_STOP_PIXEL_LSBS 0x42
-#define TVP7002_AVID_STOP_PIXEL_MSBS 0x43
-#define TVP7002_VBLK_F_0_START_L_OFF 0x44
-#define TVP7002_VBLK_F_1_START_L_OFF 0x45
-#define TVP7002_VBLK_F_0_DURATION 0x46
-#define TVP7002_VBLK_F_1_DURATION 0x47
-#define TVP7002_FBIT_F_0_START_L_OFF 0x48
-#define TVP7002_FBIT_F_1_START_L_OFF 0x49
-#define TVP7002_YUV_Y_G_COEF_LSBS 0x4a
-#define TVP7002_YUV_Y_G_COEF_MSBS 0x4b
-#define TVP7002_YUV_Y_B_COEF_LSBS 0x4c
-#define TVP7002_YUV_Y_B_COEF_MSBS 0x4d
-#define TVP7002_YUV_Y_R_COEF_LSBS 0x4e
-#define TVP7002_YUV_Y_R_COEF_MSBS 0x4f
-#define TVP7002_YUV_U_G_COEF_LSBS 0x50
-#define TVP7002_YUV_U_G_COEF_MSBS 0x51
-#define TVP7002_YUV_U_B_COEF_LSBS 0x52
-#define TVP7002_YUV_U_B_COEF_MSBS 0x53
-#define TVP7002_YUV_U_R_COEF_LSBS 0x54
-#define TVP7002_YUV_U_R_COEF_MSBS 0x55
-#define TVP7002_YUV_V_G_COEF_LSBS 0x56
-#define TVP7002_YUV_V_G_COEF_MSBS 0x57
-#define TVP7002_YUV_V_B_COEF_LSBS 0x58
-#define TVP7002_YUV_V_B_COEF_MSBS 0x59
-#define TVP7002_YUV_V_R_COEF_LSBS 0x5a
-#define TVP7002_YUV_V_R_COEF_MSBS 0x5b
-
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
deleted file mode 100644
index 9f53eacb66e..00000000000
--- a/drivers/media/video/tw9910.c
+++ /dev/null
@@ -1,956 +0,0 @@
-/*
- * tw9910 Video Driver
- *
- * Copyright (C) 2008 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on ov772x driver,
- *
- * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
- * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
- * Copyright (C) 2008 Magnus Damm
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/videodev2.h>
-
-#include <media/soc_camera.h>
-#include <media/tw9910.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-subdev.h>
-
-#define GET_ID(val) ((val & 0xF8) >> 3)
-#define GET_REV(val) (val & 0x07)
-
-/*
- * register offset
- */
-#define ID 0x00 /* Product ID Code Register */
-#define STATUS1 0x01 /* Chip Status Register I */
-#define INFORM 0x02 /* Input Format */
-#define OPFORM 0x03 /* Output Format Control Register */
-#define DLYCTR 0x04 /* Hysteresis and HSYNC Delay Control */
-#define OUTCTR1 0x05 /* Output Control I */
-#define ACNTL1 0x06 /* Analog Control Register 1 */
-#define CROP_HI 0x07 /* Cropping Register, High */
-#define VDELAY_LO 0x08 /* Vertical Delay Register, Low */
-#define VACTIVE_LO 0x09 /* Vertical Active Register, Low */
-#define HDELAY_LO 0x0A /* Horizontal Delay Register, Low */
-#define HACTIVE_LO 0x0B /* Horizontal Active Register, Low */
-#define CNTRL1 0x0C /* Control Register I */
-#define VSCALE_LO 0x0D /* Vertical Scaling Register, Low */
-#define SCALE_HI 0x0E /* Scaling Register, High */
-#define HSCALE_LO 0x0F /* Horizontal Scaling Register, Low */
-#define BRIGHT 0x10 /* BRIGHTNESS Control Register */
-#define CONTRAST 0x11 /* CONTRAST Control Register */
-#define SHARPNESS 0x12 /* SHARPNESS Control Register I */
-#define SAT_U 0x13 /* Chroma (U) Gain Register */
-#define SAT_V 0x14 /* Chroma (V) Gain Register */
-#define HUE 0x15 /* Hue Control Register */
-#define CORING1 0x17
-#define CORING2 0x18 /* Coring and IF compensation */
-#define VBICNTL 0x19 /* VBI Control Register */
-#define ACNTL2 0x1A /* Analog Control 2 */
-#define OUTCTR2 0x1B /* Output Control 2 */
-#define SDT 0x1C /* Standard Selection */
-#define SDTR 0x1D /* Standard Recognition */
-#define TEST 0x1F /* Test Control Register */
-#define CLMPG 0x20 /* Clamping Gain */
-#define IAGC 0x21 /* Individual AGC Gain */
-#define AGCGAIN 0x22 /* AGC Gain */
-#define PEAKWT 0x23 /* White Peak Threshold */
-#define CLMPL 0x24 /* Clamp level */
-#define SYNCT 0x25 /* Sync Amplitude */
-#define MISSCNT 0x26 /* Sync Miss Count Register */
-#define PCLAMP 0x27 /* Clamp Position Register */
-#define VCNTL1 0x28 /* Vertical Control I */
-#define VCNTL2 0x29 /* Vertical Control II */
-#define CKILL 0x2A /* Color Killer Level Control */
-#define COMB 0x2B /* Comb Filter Control */
-#define LDLY 0x2C /* Luma Delay and H Filter Control */
-#define MISC1 0x2D /* Miscellaneous Control I */
-#define LOOP 0x2E /* LOOP Control Register */
-#define MISC2 0x2F /* Miscellaneous Control II */
-#define MVSN 0x30 /* Macrovision Detection */
-#define STATUS2 0x31 /* Chip STATUS II */
-#define HFREF 0x32 /* H monitor */
-#define CLMD 0x33 /* CLAMP MODE */
-#define IDCNTL 0x34 /* ID Detection Control */
-#define CLCNTL1 0x35 /* Clamp Control I */
-#define ANAPLLCTL 0x4C
-#define VBIMIN 0x4D
-#define HSLOWCTL 0x4E
-#define WSS3 0x4F
-#define FILLDATA 0x50
-#define SDID 0x51
-#define DID 0x52
-#define WSS1 0x53
-#define WSS2 0x54
-#define VVBI 0x55
-#define LCTL6 0x56
-#define LCTL7 0x57
-#define LCTL8 0x58
-#define LCTL9 0x59
-#define LCTL10 0x5A
-#define LCTL11 0x5B
-#define LCTL12 0x5C
-#define LCTL13 0x5D
-#define LCTL14 0x5E
-#define LCTL15 0x5F
-#define LCTL16 0x60
-#define LCTL17 0x61
-#define LCTL18 0x62
-#define LCTL19 0x63
-#define LCTL20 0x64
-#define LCTL21 0x65
-#define LCTL22 0x66
-#define LCTL23 0x67
-#define LCTL24 0x68
-#define LCTL25 0x69
-#define LCTL26 0x6A
-#define HSBEGIN 0x6B
-#define HSEND 0x6C
-#define OVSDLY 0x6D
-#define OVSEND 0x6E
-#define VBIDELAY 0x6F
-
-/*
- * register detail
- */
-
-/* INFORM */
-#define FC27_ON 0x40 /* 1 : Input crystal clock frequency is 27MHz */
-#define FC27_FF 0x00 /* 0 : Square pixel mode. */
- /* Must use 24.54MHz for 60Hz field rate */
- /* source or 29.5MHz for 50Hz field rate */
-#define IFSEL_S 0x10 /* 01 : S-video decoding */
-#define IFSEL_C 0x00 /* 00 : Composite video decoding */
- /* Y input video selection */
-#define YSEL_M0 0x00 /* 00 : Mux0 selected */
-#define YSEL_M1 0x04 /* 01 : Mux1 selected */
-#define YSEL_M2 0x08 /* 10 : Mux2 selected */
-#define YSEL_M3 0x10 /* 11 : Mux3 selected */
-
-/* OPFORM */
-#define MODE 0x80 /* 0 : CCIR601 compatible YCrCb 4:2:2 format */
- /* 1 : ITU-R-656 compatible data sequence format */
-#define LEN 0x40 /* 0 : 8-bit YCrCb 4:2:2 output format */
- /* 1 : 16-bit YCrCb 4:2:2 output format.*/
-#define LLCMODE 0x20 /* 1 : LLC output mode. */
- /* 0 : free-run output mode */
-#define AINC 0x10 /* Serial interface auto-indexing control */
- /* 0 : auto-increment */
- /* 1 : non-auto */
-#define VSCTL 0x08 /* 1 : Vertical out ctrl by DVALID */
- /* 0 : Vertical out ctrl by HACTIVE and DVALID */
-#define OEN_TRI_SEL_MASK 0x07
-#define OEN_TRI_SEL_ALL_ON 0x00 /* Enable output for Rev0/Rev1 */
-#define OEN_TRI_SEL_ALL_OFF_r0 0x06 /* All tri-stated for Rev0 */
-#define OEN_TRI_SEL_ALL_OFF_r1 0x07 /* All tri-stated for Rev1 */
-
-/* OUTCTR1 */
-#define VSP_LO 0x00 /* 0 : VS pin output polarity is active low */
-#define VSP_HI 0x80 /* 1 : VS pin output polarity is active high. */
- /* VS pin output control */
-#define VSSL_VSYNC 0x00 /* 0 : VSYNC */
-#define VSSL_VACT 0x10 /* 1 : VACT */
-#define VSSL_FIELD 0x20 /* 2 : FIELD */
-#define VSSL_VVALID 0x30 /* 3 : VVALID */
-#define VSSL_ZERO 0x70 /* 7 : 0 */
-#define HSP_LOW 0x00 /* 0 : HS pin output polarity is active low */
-#define HSP_HI 0x08 /* 1 : HS pin output polarity is active high.*/
- /* HS pin output control */
-#define HSSL_HACT 0x00 /* 0 : HACT */
-#define HSSL_HSYNC 0x01 /* 1 : HSYNC */
-#define HSSL_DVALID 0x02 /* 2 : DVALID */
-#define HSSL_HLOCK 0x03 /* 3 : HLOCK */
-#define HSSL_ASYNCW 0x04 /* 4 : ASYNCW */
-#define HSSL_ZERO 0x07 /* 7 : 0 */
-
-/* ACNTL1 */
-#define SRESET 0x80 /* resets the device to its default state
- * but all register content remain unchanged.
- * This bit is self-resetting.
- */
-#define ACNTL1_PDN_MASK 0x0e
-#define CLK_PDN 0x08 /* system clock power down */
-#define Y_PDN 0x04 /* Luma ADC power down */
-#define C_PDN 0x02 /* Chroma ADC power down */
-
-/* ACNTL2 */
-#define ACNTL2_PDN_MASK 0x40
-#define PLL_PDN 0x40 /* PLL power down */
-
-/* VBICNTL */
-
-/* RTSEL : control the real time signal output from the MPOUT pin */
-#define RTSEL_MASK 0x07
-#define RTSEL_VLOSS 0x00 /* 0000 = Video loss */
-#define RTSEL_HLOCK 0x01 /* 0001 = H-lock */
-#define RTSEL_SLOCK 0x02 /* 0010 = S-lock */
-#define RTSEL_VLOCK 0x03 /* 0011 = V-lock */
-#define RTSEL_MONO 0x04 /* 0100 = MONO */
-#define RTSEL_DET50 0x05 /* 0101 = DET50 */
-#define RTSEL_FIELD 0x06 /* 0110 = FIELD */
-#define RTSEL_RTCO 0x07 /* 0111 = RTCO ( Real Time Control ) */
-
-/* HSYNC start and end are constant for now */
-#define HSYNC_START 0x0260
-#define HSYNC_END 0x0300
-
-/*
- * structure
- */
-
-struct regval_list {
- unsigned char reg_num;
- unsigned char value;
-};
-
-struct tw9910_scale_ctrl {
- char *name;
- unsigned short width;
- unsigned short height;
- u16 hscale;
- u16 vscale;
-};
-
-struct tw9910_priv {
- struct v4l2_subdev subdev;
- struct tw9910_video_info *info;
- const struct tw9910_scale_ctrl *scale;
- v4l2_std_id norm;
- u32 revision;
-};
-
-static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = {
- {
- .name = "NTSC SQ",
- .width = 640,
- .height = 480,
- .hscale = 0x0100,
- .vscale = 0x0100,
- },
- {
- .name = "NTSC CCIR601",
- .width = 720,
- .height = 480,
- .hscale = 0x0100,
- .vscale = 0x0100,
- },
- {
- .name = "NTSC SQ (CIF)",
- .width = 320,
- .height = 240,
- .hscale = 0x0200,
- .vscale = 0x0200,
- },
- {
- .name = "NTSC CCIR601 (CIF)",
- .width = 360,
- .height = 240,
- .hscale = 0x0200,
- .vscale = 0x0200,
- },
- {
- .name = "NTSC SQ (QCIF)",
- .width = 160,
- .height = 120,
- .hscale = 0x0400,
- .vscale = 0x0400,
- },
- {
- .name = "NTSC CCIR601 (QCIF)",
- .width = 180,
- .height = 120,
- .hscale = 0x0400,
- .vscale = 0x0400,
- },
-};
-
-static const struct tw9910_scale_ctrl tw9910_pal_scales[] = {
- {
- .name = "PAL SQ",
- .width = 768,
- .height = 576,
- .hscale = 0x0100,
- .vscale = 0x0100,
- },
- {
- .name = "PAL CCIR601",
- .width = 720,
- .height = 576,
- .hscale = 0x0100,
- .vscale = 0x0100,
- },
- {
- .name = "PAL SQ (CIF)",
- .width = 384,
- .height = 288,
- .hscale = 0x0200,
- .vscale = 0x0200,
- },
- {
- .name = "PAL CCIR601 (CIF)",
- .width = 360,
- .height = 288,
- .hscale = 0x0200,
- .vscale = 0x0200,
- },
- {
- .name = "PAL SQ (QCIF)",
- .width = 192,
- .height = 144,
- .hscale = 0x0400,
- .vscale = 0x0400,
- },
- {
- .name = "PAL CCIR601 (QCIF)",
- .width = 180,
- .height = 144,
- .hscale = 0x0400,
- .vscale = 0x0400,
- },
-};
-
-/*
- * general function
- */
-static struct tw9910_priv *to_tw9910(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client), struct tw9910_priv,
- subdev);
-}
-
-static int tw9910_mask_set(struct i2c_client *client, u8 command,
- u8 mask, u8 set)
-{
- s32 val = i2c_smbus_read_byte_data(client, command);
- if (val < 0)
- return val;
-
- val &= ~mask;
- val |= set & mask;
-
- return i2c_smbus_write_byte_data(client, command, val);
-}
-
-static int tw9910_set_scale(struct i2c_client *client,
- const struct tw9910_scale_ctrl *scale)
-{
- int ret;
-
- ret = i2c_smbus_write_byte_data(client, SCALE_HI,
- (scale->vscale & 0x0F00) >> 4 |
- (scale->hscale & 0x0F00) >> 8);
- if (ret < 0)
- return ret;
-
- ret = i2c_smbus_write_byte_data(client, HSCALE_LO,
- scale->hscale & 0x00FF);
- if (ret < 0)
- return ret;
-
- ret = i2c_smbus_write_byte_data(client, VSCALE_LO,
- scale->vscale & 0x00FF);
-
- return ret;
-}
-
-static int tw9910_set_hsync(struct i2c_client *client)
-{
- struct tw9910_priv *priv = to_tw9910(client);
- int ret;
-
- /* bit 10 - 3 */
- ret = i2c_smbus_write_byte_data(client, HSBEGIN,
- (HSYNC_START & 0x07F8) >> 3);
- if (ret < 0)
- return ret;
-
- /* bit 10 - 3 */
- ret = i2c_smbus_write_byte_data(client, HSEND,
- (HSYNC_END & 0x07F8) >> 3);
- if (ret < 0)
- return ret;
-
- /* So far only revisions 0 and 1 have been seen */
- /* bit 2 - 0 */
- if (1 == priv->revision)
- ret = tw9910_mask_set(client, HSLOWCTL, 0x77,
- (HSYNC_START & 0x0007) << 4 |
- (HSYNC_END & 0x0007));
-
- return ret;
-}
-
-static void tw9910_reset(struct i2c_client *client)
-{
- tw9910_mask_set(client, ACNTL1, SRESET, SRESET);
- msleep(1);
-}
-
-static int tw9910_power(struct i2c_client *client, int enable)
-{
- int ret;
- u8 acntl1;
- u8 acntl2;
-
- if (enable) {
- acntl1 = 0;
- acntl2 = 0;
- } else {
- acntl1 = CLK_PDN | Y_PDN | C_PDN;
- acntl2 = PLL_PDN;
- }
-
- ret = tw9910_mask_set(client, ACNTL1, ACNTL1_PDN_MASK, acntl1);
- if (ret < 0)
- return ret;
-
- return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2);
-}
-
-static const struct tw9910_scale_ctrl *tw9910_select_norm(v4l2_std_id norm,
- u32 width, u32 height)
-{
- const struct tw9910_scale_ctrl *scale;
- const struct tw9910_scale_ctrl *ret = NULL;
- __u32 diff = 0xffffffff, tmp;
- int size, i;
-
- if (norm & V4L2_STD_NTSC) {
- scale = tw9910_ntsc_scales;
- size = ARRAY_SIZE(tw9910_ntsc_scales);
- } else if (norm & V4L2_STD_PAL) {
- scale = tw9910_pal_scales;
- size = ARRAY_SIZE(tw9910_pal_scales);
- } else {
- return NULL;
- }
-
- for (i = 0; i < size; i++) {
- tmp = abs(width - scale[i].width) +
- abs(height - scale[i].height);
- if (tmp < diff) {
- diff = tmp;
- ret = scale + i;
- }
- }
-
- return ret;
-}
-
-/*
- * subdevice operations
- */
-static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tw9910_priv *priv = to_tw9910(client);
- u8 val;
- int ret;
-
- if (!enable) {
- switch (priv->revision) {
- case 0:
- val = OEN_TRI_SEL_ALL_OFF_r0;
- break;
- case 1:
- val = OEN_TRI_SEL_ALL_OFF_r1;
- break;
- default:
- dev_err(&client->dev, "un-supported revision\n");
- return -EINVAL;
- }
- } else {
- val = OEN_TRI_SEL_ALL_ON;
-
- if (!priv->scale) {
- dev_err(&client->dev, "norm select error\n");
- return -EPERM;
- }
-
- dev_dbg(&client->dev, "%s %dx%d\n",
- priv->scale->name,
- priv->scale->width,
- priv->scale->height);
- }
-
- ret = tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val);
- if (ret < 0)
- return ret;
-
- return tw9910_power(client, enable);
-}
-
-static int tw9910_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tw9910_priv *priv = to_tw9910(client);
-
- *norm = priv->norm;
-
- return 0;
-}
-
-static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tw9910_priv *priv = to_tw9910(client);
-
- if (!(norm & (V4L2_STD_NTSC | V4L2_STD_PAL)))
- return -EINVAL;
-
- priv->norm = norm;
-
- return 0;
-}
-
-static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tw9910_priv *priv = to_tw9910(client);
-
- id->ident = V4L2_IDENT_TW9910;
- id->revision = priv->revision;
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int tw9910_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
-
- if (reg->reg > 0xff)
- return -EINVAL;
-
- ret = i2c_smbus_read_byte_data(client, reg->reg);
- if (ret < 0)
- return ret;
-
- /*
- * ret = int
- * reg->val = __u64
- */
- reg->val = (__u64)ret;
-
- return 0;
-}
-
-static int tw9910_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->reg > 0xff ||
- reg->val > 0xff)
- return -EINVAL;
-
- return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
-}
-#endif
-
-static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tw9910_priv *priv = to_tw9910(client);
- int ret = -EINVAL;
- u8 val;
-
- /*
- * select suitable norm
- */
- priv->scale = tw9910_select_norm(priv->norm, *width, *height);
- if (!priv->scale)
- goto tw9910_set_fmt_error;
-
- /*
- * reset hardware
- */
- tw9910_reset(client);
-
- /*
- * set bus width
- */
- val = 0x00;
- if (SOCAM_DATAWIDTH_16 == priv->info->buswidth)
- val = LEN;
-
- ret = tw9910_mask_set(client, OPFORM, LEN, val);
- if (ret < 0)
- goto tw9910_set_fmt_error;
-
- /*
- * select MPOUT behavior
- */
- switch (priv->info->mpout) {
- case TW9910_MPO_VLOSS:
- val = RTSEL_VLOSS; break;
- case TW9910_MPO_HLOCK:
- val = RTSEL_HLOCK; break;
- case TW9910_MPO_SLOCK:
- val = RTSEL_SLOCK; break;
- case TW9910_MPO_VLOCK:
- val = RTSEL_VLOCK; break;
- case TW9910_MPO_MONO:
- val = RTSEL_MONO; break;
- case TW9910_MPO_DET50:
- val = RTSEL_DET50; break;
- case TW9910_MPO_FIELD:
- val = RTSEL_FIELD; break;
- case TW9910_MPO_RTCO:
- val = RTSEL_RTCO; break;
- default:
- val = 0;
- }
-
- ret = tw9910_mask_set(client, VBICNTL, RTSEL_MASK, val);
- if (ret < 0)
- goto tw9910_set_fmt_error;
-
- /*
- * set scale
- */
- ret = tw9910_set_scale(client, priv->scale);
- if (ret < 0)
- goto tw9910_set_fmt_error;
-
- /*
- * set hsync
- */
- ret = tw9910_set_hsync(client);
- if (ret < 0)
- goto tw9910_set_fmt_error;
-
- *width = priv->scale->width;
- *height = priv->scale->height;
-
- return ret;
-
-tw9910_set_fmt_error:
-
- tw9910_reset(client);
- priv->scale = NULL;
-
- return ret;
-}
-
-static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tw9910_priv *priv = to_tw9910(client);
-
- a->c.left = 0;
- a->c.top = 0;
- if (priv->norm & V4L2_STD_NTSC) {
- a->c.width = 640;
- a->c.height = 480;
- } else {
- a->c.width = 768;
- a->c.height = 576;
- }
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tw9910_priv *priv = to_tw9910(client);
-
- a->bounds.left = 0;
- a->bounds.top = 0;
- if (priv->norm & V4L2_STD_NTSC) {
- a->bounds.width = 640;
- a->bounds.height = 480;
- } else {
- a->bounds.width = 768;
- a->bounds.height = 576;
- }
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int tw9910_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tw9910_priv *priv = to_tw9910(client);
-
- if (!priv->scale) {
- priv->scale = tw9910_select_norm(priv->norm, 640, 480);
- if (!priv->scale)
- return -EINVAL;
- }
-
- mf->width = priv->scale->width;
- mf->height = priv->scale->height;
- mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- mf->field = V4L2_FIELD_INTERLACED_BT;
-
- return 0;
-}
-
-static int tw9910_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- u32 width = mf->width, height = mf->height;
- int ret;
-
- WARN_ON(mf->field != V4L2_FIELD_ANY &&
- mf->field != V4L2_FIELD_INTERLACED_BT);
-
- /*
- * check color format
- */
- if (mf->code != V4L2_MBUS_FMT_UYVY8_2X8)
- return -EINVAL;
-
- mf->colorspace = V4L2_COLORSPACE_JPEG;
-
- ret = tw9910_set_frame(sd, &width, &height);
- if (!ret) {
- mf->width = width;
- mf->height = height;
- }
- return ret;
-}
-
-static int tw9910_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tw9910_priv *priv = to_tw9910(client);
- const struct tw9910_scale_ctrl *scale;
-
- if (V4L2_FIELD_ANY == mf->field) {
- mf->field = V4L2_FIELD_INTERLACED_BT;
- } else if (V4L2_FIELD_INTERLACED_BT != mf->field) {
- dev_err(&client->dev, "Field type %d invalid.\n", mf->field);
- return -EINVAL;
- }
-
- mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
- mf->colorspace = V4L2_COLORSPACE_JPEG;
-
- /*
- * select suitable norm
- */
- scale = tw9910_select_norm(priv->norm, mf->width, mf->height);
- if (!scale)
- return -EINVAL;
-
- mf->width = scale->width;
- mf->height = scale->height;
-
- return 0;
-}
-
-static int tw9910_video_probe(struct i2c_client *client)
-{
- struct tw9910_priv *priv = to_tw9910(client);
- s32 id;
-
- /*
- * tw9910 only use 8 or 16 bit bus width
- */
- if (SOCAM_DATAWIDTH_16 != priv->info->buswidth &&
- SOCAM_DATAWIDTH_8 != priv->info->buswidth) {
- dev_err(&client->dev, "bus width error\n");
- return -ENODEV;
- }
-
- /*
- * check and show Product ID
- * So far only revisions 0 and 1 have been seen
- */
- id = i2c_smbus_read_byte_data(client, ID);
- priv->revision = GET_REV(id);
- id = GET_ID(id);
-
- if (0x0B != id ||
- 0x01 < priv->revision) {
- dev_err(&client->dev,
- "Product ID error %x:%x\n",
- id, priv->revision);
- return -ENODEV;
- }
-
- dev_info(&client->dev,
- "tw9910 Product ID %0x:%0x\n", id, priv->revision);
-
- priv->norm = V4L2_STD_NTSC;
-
- return 0;
-}
-
-static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
- .g_chip_ident = tw9910_g_chip_ident,
- .s_std = tw9910_s_std,
- .g_std = tw9910_g_std,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = tw9910_g_register,
- .s_register = tw9910_s_register,
-#endif
-};
-
-static int tw9910_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index)
- return -EINVAL;
-
- *code = V4L2_MBUS_FMT_UYVY8_2X8;
- return 0;
-}
-
-static int tw9910_g_mbus_config(struct v4l2_subdev *sd,
- struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
-
- cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
- V4L2_MBUS_DATA_ACTIVE_HIGH;
- cfg->type = V4L2_MBUS_PARALLEL;
- cfg->flags = soc_camera_apply_board_flags(icl, cfg);
-
- return 0;
-}
-
-static int tw9910_s_mbus_config(struct v4l2_subdev *sd,
- const struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- u8 val = VSSL_VVALID | HSSL_DVALID;
- unsigned long flags = soc_camera_apply_board_flags(icl, cfg);
-
- /*
- * set OUTCTR1
- *
- * We use VVALID and DVALID signals to control VSYNC and HSYNC
- * outputs, in this mode their polarity is inverted.
- */
- if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
- val |= HSP_HI;
-
- if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
- val |= VSP_HI;
-
- return i2c_smbus_write_byte_data(client, OUTCTR1, val);
-}
-
-static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
- .s_stream = tw9910_s_stream,
- .g_mbus_fmt = tw9910_g_fmt,
- .s_mbus_fmt = tw9910_s_fmt,
- .try_mbus_fmt = tw9910_try_fmt,
- .cropcap = tw9910_cropcap,
- .g_crop = tw9910_g_crop,
- .enum_mbus_fmt = tw9910_enum_fmt,
- .g_mbus_config = tw9910_g_mbus_config,
- .s_mbus_config = tw9910_s_mbus_config,
-};
-
-static struct v4l2_subdev_ops tw9910_subdev_ops = {
- .core = &tw9910_subdev_core_ops,
- .video = &tw9910_subdev_video_ops,
-};
-
-/*
- * i2c_driver function
- */
-
-static int tw9910_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-
-{
- struct tw9910_priv *priv;
- struct tw9910_video_info *info;
- struct i2c_adapter *adapter =
- to_i2c_adapter(client->dev.parent);
- struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- int ret;
-
- if (!icl || !icl->priv) {
- dev_err(&client->dev, "TW9910: missing platform data!\n");
- return -EINVAL;
- }
-
- info = icl->priv;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_err(&client->dev,
- "I2C-Adapter doesn't support "
- "I2C_FUNC_SMBUS_BYTE_DATA\n");
- return -EIO;
- }
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->info = info;
-
- v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
-
- ret = tw9910_video_probe(client);
- if (ret)
- kfree(priv);
-
- return ret;
-}
-
-static int tw9910_remove(struct i2c_client *client)
-{
- struct tw9910_priv *priv = to_tw9910(client);
-
- kfree(priv);
- return 0;
-}
-
-static const struct i2c_device_id tw9910_id[] = {
- { "tw9910", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tw9910_id);
-
-static struct i2c_driver tw9910_i2c_driver = {
- .driver = {
- .name = "tw9910",
- },
- .probe = tw9910_probe,
- .remove = tw9910_remove,
- .id_table = tw9910_id,
-};
-
-module_i2c_driver(tw9910_i2c_driver);
-
-MODULE_DESCRIPTION("SoC Camera driver for tw9910");
-MODULE_AUTHOR("Kuninori Morimoto");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
deleted file mode 100644
index 1e744654209..00000000000
--- a/drivers/media/video/upd64031a.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * upd64031A - NEC Electronics Ghost Reduction for NTSC in Japan
- *
- * 2003 by T.Adachi <tadachi@tadachi-net.com>
- * 2003 by Takeru KOMORIYA <komoriya@paken.org>
- * 2006 by Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/upd64031a.h>
-
-/* --------------------- read registers functions define -------------------- */
-
-/* bit masks */
-#define GR_MODE_MASK 0xc0
-#define DIRECT_3DYCS_CONNECT_MASK 0xc0
-#define SYNC_CIRCUIT_MASK 0xa0
-
-/* -------------------------------------------------------------------------- */
-
-MODULE_DESCRIPTION("uPD64031A driver");
-MODULE_AUTHOR("T. Adachi, Takeru KOMORIYA, Hans Verkuil");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0644);
-
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-
-enum {
- R00 = 0, R01, R02, R03, R04,
- R05, R06, R07, R08, R09,
- R0A, R0B, R0C, R0D, R0E, R0F,
- /* unused registers
- R10, R11, R12, R13, R14,
- R15, R16, R17,
- */
- TOT_REGS
-};
-
-struct upd64031a_state {
- struct v4l2_subdev sd;
- u8 regs[TOT_REGS];
- u8 gr_mode;
- u8 direct_3dycs_connect;
- u8 ext_comp_sync;
- u8 ext_vert_sync;
-};
-
-static inline struct upd64031a_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct upd64031a_state, sd);
-}
-
-static u8 upd64031a_init[] = {
- 0x00, 0xb8, 0x48, 0xd2, 0xe6,
- 0x03, 0x10, 0x0b, 0xaf, 0x7f,
- 0x00, 0x00, 0x1d, 0x5e, 0x00,
- 0xd0
-};
-
-/* ------------------------------------------------------------------------ */
-
-static u8 upd64031a_read(struct v4l2_subdev *sd, u8 reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 buf[2];
-
- if (reg >= sizeof(buf))
- return 0xff;
- i2c_master_recv(client, buf, 2);
- return buf[reg];
-}
-
-/* ------------------------------------------------------------------------ */
-
-static void upd64031a_write(struct v4l2_subdev *sd, u8 reg, u8 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 buf[2];
-
- buf[0] = reg;
- buf[1] = val;
- v4l2_dbg(1, debug, sd, "write reg: %02X val: %02X\n", reg, val);
- if (i2c_master_send(client, buf, 2) != 2)
- v4l2_err(sd, "I/O error write 0x%02x/0x%02x\n", reg, val);
-}
-
-/* ------------------------------------------------------------------------ */
-
-/* The input changed due to new input or channel changed */
-static int upd64031a_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
-{
- struct upd64031a_state *state = to_state(sd);
- u8 reg = state->regs[R00];
-
- v4l2_dbg(1, debug, sd, "changed input or channel\n");
- upd64031a_write(sd, R00, reg | 0x10);
- upd64031a_write(sd, R00, reg & ~0x10);
- return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int upd64031a_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct upd64031a_state *state = to_state(sd);
- u8 r00, r05, r08;
-
- state->gr_mode = (input & 3) << 6;
- state->direct_3dycs_connect = (input & 0xc) << 4;
- state->ext_comp_sync =
- (input & UPD64031A_COMPOSITE_EXTERNAL) << 1;
- state->ext_vert_sync =
- (input & UPD64031A_VERTICAL_EXTERNAL) << 2;
- r00 = (state->regs[R00] & ~GR_MODE_MASK) | state->gr_mode;
- r05 = (state->regs[R00] & ~SYNC_CIRCUIT_MASK) |
- state->ext_comp_sync | state->ext_vert_sync;
- r08 = (state->regs[R08] & ~DIRECT_3DYCS_CONNECT_MASK) |
- state->direct_3dycs_connect;
- upd64031a_write(sd, R00, r00);
- upd64031a_write(sd, R05, r05);
- upd64031a_write(sd, R08, r08);
- return upd64031a_s_frequency(sd, NULL);
-}
-
-static int upd64031a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_UPD64031A, 0);
-}
-
-static int upd64031a_log_status(struct v4l2_subdev *sd)
-{
- v4l2_info(sd, "Status: SA00=0x%02x SA01=0x%02x\n",
- upd64031a_read(sd, 0), upd64031a_read(sd, 1));
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int upd64031a_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- reg->val = upd64031a_read(sd, reg->reg & 0xff);
- reg->size = 1;
- return 0;
-}
-
-static int upd64031a_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- upd64031a_write(sd, reg->reg & 0xff, reg->val & 0xff);
- return 0;
-}
-#endif
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops upd64031a_core_ops = {
- .log_status = upd64031a_log_status,
- .g_chip_ident = upd64031a_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = upd64031a_g_register,
- .s_register = upd64031a_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_tuner_ops upd64031a_tuner_ops = {
- .s_frequency = upd64031a_s_frequency,
-};
-
-static const struct v4l2_subdev_video_ops upd64031a_video_ops = {
- .s_routing = upd64031a_s_routing,
-};
-
-static const struct v4l2_subdev_ops upd64031a_ops = {
- .core = &upd64031a_core_ops,
- .tuner = &upd64031a_tuner_ops,
- .video = &upd64031a_video_ops,
-};
-
-/* ------------------------------------------------------------------------ */
-
-/* i2c implementation */
-
-static int upd64031a_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct upd64031a_state *state;
- struct v4l2_subdev *sd;
- int i;
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- state = kzalloc(sizeof(struct upd64031a_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &upd64031a_ops);
- memcpy(state->regs, upd64031a_init, sizeof(state->regs));
- state->gr_mode = UPD64031A_GR_ON << 6;
- state->direct_3dycs_connect = UPD64031A_3DYCS_COMPOSITE << 4;
- state->ext_comp_sync = state->ext_vert_sync = 0;
- for (i = 0; i < TOT_REGS; i++)
- upd64031a_write(sd, i, state->regs[i]);
- return 0;
-}
-
-static int upd64031a_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(to_state(sd));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id upd64031a_id[] = {
- { "upd64031a", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, upd64031a_id);
-
-static struct i2c_driver upd64031a_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "upd64031a",
- },
- .probe = upd64031a_probe,
- .remove = upd64031a_remove,
- .id_table = upd64031a_id,
-};
-
-module_i2c_driver(upd64031a_driver);
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
deleted file mode 100644
index 75d6acc6201..00000000000
--- a/drivers/media/video/upd64083.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * upd6408x - NEC Electronics 3-Dimensional Y/C separation driver
- *
- * 2003 by T.Adachi (tadachi@tadachi-net.com)
- * 2003 by Takeru KOMORIYA <komoriya@paken.org>
- * 2006 by Hans Verkuil <hverkuil@xs4all.nl>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/upd64083.h>
-
-MODULE_DESCRIPTION("uPD64083 driver");
-MODULE_AUTHOR("T. Adachi, Takeru KOMORIYA, Hans Verkuil");
-MODULE_LICENSE("GPL");
-
-static bool debug;
-module_param(debug, bool, 0644);
-
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-
-enum {
- R00 = 0, R01, R02, R03, R04,
- R05, R06, R07, R08, R09,
- R0A, R0B, R0C, R0D, R0E, R0F,
- R10, R11, R12, R13, R14,
- R15, R16,
- TOT_REGS
-};
-
-struct upd64083_state {
- struct v4l2_subdev sd;
- u8 mode;
- u8 ext_y_adc;
- u8 regs[TOT_REGS];
-};
-
-static inline struct upd64083_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct upd64083_state, sd);
-}
-
-/* Initial values when used in combination with the
- NEC upd64031a ghost reduction chip. */
-static u8 upd64083_init[] = {
- 0x1f, 0x01, 0xa0, 0x2d, 0x29, /* we use EXCSS=0 */
- 0x36, 0xdd, 0x05, 0x56, 0x48,
- 0x00, 0x3a, 0xa0, 0x05, 0x08,
- 0x44, 0x60, 0x08, 0x52, 0xf8,
- 0x53, 0x60, 0x10
-};
-
-/* ------------------------------------------------------------------------ */
-
-static void upd64083_write(struct v4l2_subdev *sd, u8 reg, u8 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 buf[2];
-
- buf[0] = reg;
- buf[1] = val;
- v4l2_dbg(1, debug, sd, "write reg: %02x val: %02x\n", reg, val);
- if (i2c_master_send(client, buf, 2) != 2)
- v4l2_err(sd, "I/O error write 0x%02x/0x%02x\n", reg, val);
-}
-
-/* ------------------------------------------------------------------------ */
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static u8 upd64083_read(struct v4l2_subdev *sd, u8 reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 buf[7];
-
- if (reg >= sizeof(buf))
- return 0xff;
- i2c_master_recv(client, buf, sizeof(buf));
- return buf[reg];
-}
-#endif
-
-/* ------------------------------------------------------------------------ */
-
-static int upd64083_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct upd64083_state *state = to_state(sd);
- u8 r00, r02;
-
- if (input > 7 || (input & 6) == 6)
- return -EINVAL;
- state->mode = (input & 3) << 6;
- state->ext_y_adc = (input & UPD64083_EXT_Y_ADC) << 3;
- r00 = (state->regs[R00] & ~(3 << 6)) | state->mode;
- r02 = (state->regs[R02] & ~(1 << 5)) | state->ext_y_adc;
- upd64083_write(sd, R00, r00);
- upd64083_write(sd, R02, r02);
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int upd64083_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- reg->val = upd64083_read(sd, reg->reg & 0xff);
- reg->size = 1;
- return 0;
-}
-
-static int upd64083_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- upd64083_write(sd, reg->reg & 0xff, reg->val & 0xff);
- return 0;
-}
-#endif
-
-static int upd64083_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_UPD64083, 0);
-}
-
-static int upd64083_log_status(struct v4l2_subdev *sd)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 buf[7];
-
- i2c_master_recv(client, buf, 7);
- v4l2_info(sd, "Status: SA00=%02x SA01=%02x SA02=%02x SA03=%02x "
- "SA04=%02x SA05=%02x SA06=%02x\n",
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops upd64083_core_ops = {
- .log_status = upd64083_log_status,
- .g_chip_ident = upd64083_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = upd64083_g_register,
- .s_register = upd64083_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_video_ops upd64083_video_ops = {
- .s_routing = upd64083_s_routing,
-};
-
-static const struct v4l2_subdev_ops upd64083_ops = {
- .core = &upd64083_core_ops,
- .video = &upd64083_video_ops,
-};
-
-/* ------------------------------------------------------------------------ */
-
-/* i2c implementation */
-
-static int upd64083_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct upd64083_state *state;
- struct v4l2_subdev *sd;
- int i;
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- state = kzalloc(sizeof(struct upd64083_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &upd64083_ops);
- /* Initially assume that a ghost reduction chip is present */
- state->mode = 0; /* YCS mode */
- state->ext_y_adc = (1 << 5);
- memcpy(state->regs, upd64083_init, TOT_REGS);
- for (i = 0; i < TOT_REGS; i++)
- upd64083_write(sd, i, state->regs[i]);
- return 0;
-}
-
-static int upd64083_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(to_state(sd));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id upd64083_id[] = {
- { "upd64083", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, upd64083_id);
-
-static struct i2c_driver upd64083_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "upd64083",
- },
- .probe = upd64083_probe,
- .remove = upd64083_remove,
- .id_table = upd64083_id,
-};
-
-module_i2c_driver(upd64083_driver);
diff --git a/drivers/media/video/usbvision/Kconfig b/drivers/media/video/usbvision/Kconfig
deleted file mode 100644
index fc24ef05b3f..00000000000
--- a/drivers/media/video/usbvision/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-config VIDEO_USBVISION
- tristate "USB video devices based on Nogatech NT1003/1004/1005"
- depends on I2C && VIDEO_V4L2
- select VIDEO_TUNER
- select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
- ---help---
- There are more than 50 different USB video devices based on
- NT1003/1004/1005 USB Bridges. This driver enables using those
- devices.
-
- To compile this driver as a module, choose M here: the
- module will be called usbvision.
diff --git a/drivers/media/video/usbvision/Makefile b/drivers/media/video/usbvision/Makefile
deleted file mode 100644
index aea1e3b5f06..00000000000
--- a/drivers/media/video/usbvision/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-usbvision-objs := usbvision-core.o usbvision-video.o usbvision-i2c.o usbvision-cards.o
-
-obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o
-
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/usbvision/usbvision-cards.c b/drivers/media/video/usbvision/usbvision-cards.c
deleted file mode 100644
index 3103d0d020e..00000000000
--- a/drivers/media/video/usbvision/usbvision-cards.c
+++ /dev/null
@@ -1,1133 +0,0 @@
-/*
- * usbvision-cards.c
- * usbvision cards definition file
- *
- * Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de>
- *
- * This module is part of usbvision driver project.
- * Updates to driver completed by Dwaine P. Garden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include <linux/list.h>
-#include <linux/module.h>
-#include <media/v4l2-dev.h>
-#include <media/tuner.h>
-#include "usbvision.h"
-#include "usbvision-cards.h"
-
-/* Supported Devices: A table for usbvision.c*/
-struct usbvision_device_data_st usbvision_device_data[] = {
- [XANBOO] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 4,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Xanboo",
- },
- [BELKIN_VIDEOBUS_II] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 2,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Belkin USB VideoBus II Adapter",
- },
- [BELKIN_VIDEOBUS] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 2,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Belkin Components USB VideoBus",
- },
- [BELKIN_USB_VIDEOBUS_II] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 2,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Belkin USB VideoBus II",
- },
- [ECHOFX_INTERVIEW_LITE] = {
- .interface = 0,
- .codec = CODEC_SAA7111,
- .video_channels = 2,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 0,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = -1,
- .y_offset = -1,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "echoFX InterView Lite",
- },
- [USBGEAR_USBG_V1] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 2,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "USBGear USBG-V1 resp. HAMA USB",
- },
- [D_LINK_V100] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 4,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 0,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "D-Link V100",
- },
- [X10_USB_CAMERA] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 2,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "X10 USB Camera",
- },
- [HPG_WINTV_LIVE_PAL_BG] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 2,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = -1,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Live (PAL B/G)",
- },
- [HPG_WINTV_LIVE_PRO_NTSC_MN] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 2,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 0,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Live Pro (NTSC M/N)",
- },
- [ZORAN_PMD_NOGATECH] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 2,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 2,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Zoran Co. PMD (Nogatech) AV-grabber Manhattan",
- },
- [NOGATECH_USB_TV_NTSC_FM] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .x_offset = -1,
- .y_offset = 20,
- .model_string = "Nogatech USB-TV (NTSC) FM",
- },
- [PNY_USB_TV_NTSC_FM] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .x_offset = -1,
- .y_offset = 20,
- .model_string = "PNY USB-TV (NTSC) FM",
- },
- [PV_PLAYTV_USB_PRO_PAL_FM] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "PixelView PlayTv-USB PRO (PAL) FM",
- },
- [ZT_721] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "ZTV ZT-721 2.4GHz USB A/V Receiver",
- },
- [HPG_WINTV_NTSC_MN] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .x_offset = -1,
- .y_offset = 20,
- .model_string = "Hauppauge WinTV USB (NTSC M/N)",
- },
- [HPG_WINTV_PAL_BG] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Hauppauge WinTV USB (PAL B/G)",
- },
- [HPG_WINTV_PAL_I] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Hauppauge WinTV USB (PAL I)",
- },
- [HPG_WINTV_PAL_SECAM_L] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_SECAM,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_SECAM,
- .x_offset = 0x80,
- .y_offset = 0x16,
- .model_string = "Hauppauge WinTV USB (PAL/SECAM L)",
- },
- [HPG_WINTV_PAL_D_K] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Hauppauge WinTV USB (PAL D/K)",
- },
- [HPG_WINTV_NTSC_FM] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Hauppauge WinTV USB (NTSC FM)",
- },
- [HPG_WINTV_PAL_BG_FM] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Hauppauge WinTV USB (PAL B/G FM)",
- },
- [HPG_WINTV_PAL_I_FM] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Hauppauge WinTV USB (PAL I FM)",
- },
- [HPG_WINTV_PAL_D_K_FM] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Hauppauge WinTV USB (PAL D/K FM)",
- },
- [HPG_WINTV_PRO_NTSC_MN] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_MICROTUNE_4049FM5,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (NTSC M/N)",
- },
- [HPG_WINTV_PRO_NTSC_MN_V2] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_MICROTUNE_4049FM5,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (NTSC M/N) V2",
- },
- [HPG_WINTV_PRO_PAL] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L)",
- },
- [HPG_WINTV_PRO_NTSC_MN_V3] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (NTSC M/N) V3",
- },
- [HPG_WINTV_PRO_PAL_BG] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (PAL B/G)",
- },
- [HPG_WINTV_PRO_PAL_I] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (PAL I)",
- },
- [HPG_WINTV_PRO_PAL_SECAM_L] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_SECAM,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_SECAM,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM L)",
- },
- [HPG_WINTV_PRO_PAL_D_K] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (PAL D/K)",
- },
- [HPG_WINTV_PRO_PAL_SECAM] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_SECAM,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_SECAM,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)",
- },
- [HPG_WINTV_PRO_PAL_SECAM_V2] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_SECAM,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_SECAM,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2",
- },
- [HPG_WINTV_PRO_PAL_BG_V2] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_ALPS_TSBE1_PAL,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (PAL B/G) V2",
- },
- [HPG_WINTV_PRO_PAL_BG_D_K] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_ALPS_TSBE1_PAL,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (PAL B/G,D/K)",
- },
- [HPG_WINTV_PRO_PAL_I_D_K] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (PAL I,D/K)",
- },
- [HPG_WINTV_PRO_NTSC_MN_FM] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (NTSC M/N FM)",
- },
- [HPG_WINTV_PRO_PAL_BG_FM] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (PAL B/G FM)",
- },
- [HPG_WINTV_PRO_PAL_I_FM] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (PAL I FM)",
- },
- [HPG_WINTV_PRO_PAL_D_K_FM] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (PAL D/K FM)",
- },
- [HPG_WINTV_PRO_TEMIC_PAL_FM] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_MICROTUNE_4049FM5,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM)",
- },
- [HPG_WINTV_PRO_TEMIC_PAL_BG_FM] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_MICROTUNE_4049FM5,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (Temic PAL B/G FM)",
- },
- [HPG_WINTV_PRO_PAL_FM] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM)",
- },
- [HPG_WINTV_PRO_NTSC_MN_FM_V2] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Hauppauge WinTV USB Pro (NTSC M/N FM) V2",
- },
- [CAMTEL_TVB330] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .x_offset = 5,
- .y_offset = 5,
- .model_string = "Camtel Technology USB TV Genie Pro FM Model TVB330",
- },
- [DIGITAL_VIDEO_CREATOR_I] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 2,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 0,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Digital Video Creator I",
- },
- [GLOBAL_VILLAGE_GV_007_NTSC] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 2,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 0,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = 82,
- .y_offset = 20,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Global Village GV-007 (NTSC)",
- },
- [DAZZLE_DVC_50_REV_1_NTSC] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 2,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 0,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Dazzle Fusion Model DVC-50 Rev 1 (NTSC)",
- },
- [DAZZLE_DVC_80_REV_1_PAL] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 2,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 0,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Dazzle Fusion Model DVC-80 Rev 1 (PAL)",
- },
- [DAZZLE_DVC_90_REV_1_SECAM] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 2,
- .video_norm = V4L2_STD_SECAM,
- .audio_channels = 0,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)",
- },
- [ESKAPE_LABS_MYTV2GO] = {
- .interface = 0,
- .codec = CODEC_SAA7113,
- .video_channels = 2,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Eskape Labs MyTV2Go",
- },
- [PINNA_PCTV_USB_PAL] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 0,
- .tuner = 1,
- .tuner_type = TUNER_TEMIC_4066FY5_PAL_I,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Pinnacle Studio PCTV USB (PAL)",
- },
- [PINNA_PCTV_USB_SECAM] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_SECAM,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_SECAM,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Pinnacle Studio PCTV USB (SECAM)",
- },
- [PINNA_PCTV_USB_PAL_FM] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = 128,
- .y_offset = 23,
- .model_string = "Pinnacle Studio PCTV USB (PAL) FM",
- },
- [MIRO_PCTV_USB] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Miro PCTV USB",
- },
- [PINNA_PCTV_USB_NTSC_FM] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Pinnacle Studio PCTV USB (NTSC) FM",
- },
- [PINNA_PCTV_USB_NTSC_FM_V3] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Pinnacle Studio PCTV USB (NTSC) FM V3",
- },
- [PINNA_PCTV_USB_PAL_FM_V2] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_TEMIC_4009FR5_PAL,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Pinnacle Studio PCTV USB (PAL) FM V2",
- },
- [PINNA_PCTV_USB_NTSC_FM_V2] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_TEMIC_4039FR5_NTSC,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Pinnacle Studio PCTV USB (NTSC) FM V2",
- },
- [PINNA_PCTV_USB_PAL_FM_V3] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_TEMIC_4009FR5_PAL,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Pinnacle Studio PCTV USB (PAL) FM V3",
- },
- [PINNA_LINX_VD_IN_CAB_NTSC] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 2,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Pinnacle Studio Linx Video input cable (NTSC)",
- },
- [PINNA_LINX_VD_IN_CAB_PAL] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 2,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Pinnacle Studio Linx Video input cable (PAL)",
- },
- [PINNA_PCTV_BUNGEE_PAL_FM] = {
- .interface = -1,
- .codec = CODEC_SAA7113,
- .video_channels = 3,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 1,
- .radio = 1,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_TEMIC_4009FR5_PAL,
- .x_offset = 0,
- .y_offset = 3,
- .dvi_yuv_override = 1,
- .dvi_yuv = 7,
- .model_string = "Pinnacle PCTV Bungee USB (PAL) FM",
- },
- [HPG_WINTV] = {
- .interface = -1,
- .codec = CODEC_SAA7111,
- .video_channels = 3,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 1,
- .radio = 0,
- .vbi = 1,
- .tuner = 1,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .x_offset = -1,
- .y_offset = -1,
- .model_string = "Hauppauge WinTv-USB",
- },
- [MICROCAM_NTSC] = {
- .interface = -1,
- .codec = CODEC_WEBCAM,
- .video_channels = 1,
- .video_norm = V4L2_STD_NTSC,
- .audio_channels = 0,
- .radio = 0,
- .vbi = 0,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = 71,
- .y_offset = 15,
- .model_string = "Nogatech USB MicroCam NTSC (NV3000N)",
- },
- [MICROCAM_PAL] = {
- .interface = -1,
- .codec = CODEC_WEBCAM,
- .video_channels = 1,
- .video_norm = V4L2_STD_PAL,
- .audio_channels = 0,
- .radio = 0,
- .vbi = 0,
- .tuner = 0,
- .tuner_type = 0,
- .x_offset = 71,
- .y_offset = 18,
- .model_string = "Nogatech USB MicroCam PAL (NV3001P)",
- },
-};
-const int usbvision_device_data_size = ARRAY_SIZE(usbvision_device_data);
-
-/* Supported Devices */
-
-struct usb_device_id usbvision_table[] = {
- { USB_DEVICE(0x0a6f, 0x0400), .driver_info = XANBOO },
- { USB_DEVICE(0x050d, 0x0106), .driver_info = BELKIN_VIDEOBUS_II },
- { USB_DEVICE(0x050d, 0x0207), .driver_info = BELKIN_VIDEOBUS },
- { USB_DEVICE(0x050d, 0x0208), .driver_info = BELKIN_USB_VIDEOBUS_II },
- { USB_DEVICE(0x0571, 0x0002), .driver_info = ECHOFX_INTERVIEW_LITE },
- { USB_DEVICE(0x0573, 0x0003), .driver_info = USBGEAR_USBG_V1 },
- { USB_DEVICE(0x0573, 0x0400), .driver_info = D_LINK_V100 },
- { USB_DEVICE(0x0573, 0x2000), .driver_info = X10_USB_CAMERA },
- { USB_DEVICE(0x0573, 0x2d00), .driver_info = HPG_WINTV_LIVE_PAL_BG },
- { USB_DEVICE(0x0573, 0x2d01), .driver_info = HPG_WINTV_LIVE_PRO_NTSC_MN },
- { USB_DEVICE(0x0573, 0x2101), .driver_info = ZORAN_PMD_NOGATECH },
- { USB_DEVICE(0x0573, 0x3000), .driver_info = MICROCAM_NTSC },
- { USB_DEVICE(0x0573, 0x3001), .driver_info = MICROCAM_PAL },
- { USB_DEVICE(0x0573, 0x4100), .driver_info = NOGATECH_USB_TV_NTSC_FM },
- { USB_DEVICE(0x0573, 0x4110), .driver_info = PNY_USB_TV_NTSC_FM },
- { USB_DEVICE(0x0573, 0x4450), .driver_info = PV_PLAYTV_USB_PRO_PAL_FM },
- { USB_DEVICE(0x0573, 0x4550), .driver_info = ZT_721 },
- { USB_DEVICE(0x0573, 0x4d00), .driver_info = HPG_WINTV_NTSC_MN },
- { USB_DEVICE(0x0573, 0x4d01), .driver_info = HPG_WINTV_PAL_BG },
- { USB_DEVICE(0x0573, 0x4d02), .driver_info = HPG_WINTV_PAL_I },
- { USB_DEVICE(0x0573, 0x4d03), .driver_info = HPG_WINTV_PAL_SECAM_L },
- { USB_DEVICE(0x0573, 0x4d04), .driver_info = HPG_WINTV_PAL_D_K },
- { USB_DEVICE(0x0573, 0x4d10), .driver_info = HPG_WINTV_NTSC_FM },
- { USB_DEVICE(0x0573, 0x4d11), .driver_info = HPG_WINTV_PAL_BG_FM },
- { USB_DEVICE(0x0573, 0x4d12), .driver_info = HPG_WINTV_PAL_I_FM },
- { USB_DEVICE(0x0573, 0x4d14), .driver_info = HPG_WINTV_PAL_D_K_FM },
- { USB_DEVICE(0x0573, 0x4d2a), .driver_info = HPG_WINTV_PRO_NTSC_MN },
- { USB_DEVICE(0x0573, 0x4d2b), .driver_info = HPG_WINTV_PRO_NTSC_MN_V2 },
- { USB_DEVICE(0x0573, 0x4d2c), .driver_info = HPG_WINTV_PRO_PAL },
- { USB_DEVICE(0x0573, 0x4d20), .driver_info = HPG_WINTV_PRO_NTSC_MN_V3 },
- { USB_DEVICE(0x0573, 0x4d21), .driver_info = HPG_WINTV_PRO_PAL_BG },
- { USB_DEVICE(0x0573, 0x4d22), .driver_info = HPG_WINTV_PRO_PAL_I },
- { USB_DEVICE(0x0573, 0x4d23), .driver_info = HPG_WINTV_PRO_PAL_SECAM_L },
- { USB_DEVICE(0x0573, 0x4d24), .driver_info = HPG_WINTV_PRO_PAL_D_K },
- { USB_DEVICE(0x0573, 0x4d25), .driver_info = HPG_WINTV_PRO_PAL_SECAM },
- { USB_DEVICE(0x0573, 0x4d26), .driver_info = HPG_WINTV_PRO_PAL_SECAM_V2 },
- { USB_DEVICE(0x0573, 0x4d27), .driver_info = HPG_WINTV_PRO_PAL_BG_V2 },
- { USB_DEVICE(0x0573, 0x4d28), .driver_info = HPG_WINTV_PRO_PAL_BG_D_K },
- { USB_DEVICE(0x0573, 0x4d29), .driver_info = HPG_WINTV_PRO_PAL_I_D_K },
- { USB_DEVICE(0x0573, 0x4d30), .driver_info = HPG_WINTV_PRO_NTSC_MN_FM },
- { USB_DEVICE(0x0573, 0x4d31), .driver_info = HPG_WINTV_PRO_PAL_BG_FM },
- { USB_DEVICE(0x0573, 0x4d32), .driver_info = HPG_WINTV_PRO_PAL_I_FM },
- { USB_DEVICE(0x0573, 0x4d34), .driver_info = HPG_WINTV_PRO_PAL_D_K_FM },
- { USB_DEVICE(0x0573, 0x4d35), .driver_info = HPG_WINTV_PRO_TEMIC_PAL_FM },
- { USB_DEVICE(0x0573, 0x4d36), .driver_info = HPG_WINTV_PRO_TEMIC_PAL_BG_FM },
- { USB_DEVICE(0x0573, 0x4d37), .driver_info = HPG_WINTV_PRO_PAL_FM },
- { USB_DEVICE(0x0573, 0x4d38), .driver_info = HPG_WINTV_PRO_NTSC_MN_FM_V2 },
- { USB_DEVICE(0x0768, 0x0006), .driver_info = CAMTEL_TVB330 },
- { USB_DEVICE(0x07d0, 0x0001), .driver_info = DIGITAL_VIDEO_CREATOR_I },
- { USB_DEVICE(0x07d0, 0x0002), .driver_info = GLOBAL_VILLAGE_GV_007_NTSC },
- { USB_DEVICE(0x07d0, 0x0003), .driver_info = DAZZLE_DVC_50_REV_1_NTSC },
- { USB_DEVICE(0x07d0, 0x0004), .driver_info = DAZZLE_DVC_80_REV_1_PAL },
- { USB_DEVICE(0x07d0, 0x0005), .driver_info = DAZZLE_DVC_90_REV_1_SECAM },
- { USB_DEVICE(0x07f8, 0x9104), .driver_info = ESKAPE_LABS_MYTV2GO },
- { USB_DEVICE(0x2304, 0x010d), .driver_info = PINNA_PCTV_USB_PAL },
- { USB_DEVICE(0x2304, 0x0109), .driver_info = PINNA_PCTV_USB_SECAM },
- { USB_DEVICE(0x2304, 0x0110), .driver_info = PINNA_PCTV_USB_PAL_FM },
- { USB_DEVICE(0x2304, 0x0111), .driver_info = MIRO_PCTV_USB },
- { USB_DEVICE(0x2304, 0x0112), .driver_info = PINNA_PCTV_USB_NTSC_FM },
- { USB_DEVICE(0x2304, 0x0113), .driver_info = PINNA_PCTV_USB_NTSC_FM_V3 },
- { USB_DEVICE(0x2304, 0x0210), .driver_info = PINNA_PCTV_USB_PAL_FM_V2 },
- { USB_DEVICE(0x2304, 0x0212), .driver_info = PINNA_PCTV_USB_NTSC_FM_V2 },
- { USB_DEVICE(0x2304, 0x0214), .driver_info = PINNA_PCTV_USB_PAL_FM_V3 },
- { USB_DEVICE(0x2304, 0x0300), .driver_info = PINNA_LINX_VD_IN_CAB_NTSC },
- { USB_DEVICE(0x2304, 0x0301), .driver_info = PINNA_LINX_VD_IN_CAB_PAL },
- { USB_DEVICE(0x2304, 0x0419), .driver_info = PINNA_PCTV_BUNGEE_PAL_FM },
- { USB_DEVICE(0x2400, 0x4200), .driver_info = HPG_WINTV },
- { }, /* terminate list */
-};
-
-MODULE_DEVICE_TABLE(usb, usbvision_table);
diff --git a/drivers/media/video/usbvision/usbvision-cards.h b/drivers/media/video/usbvision/usbvision-cards.h
deleted file mode 100644
index a51cc1185cc..00000000000
--- a/drivers/media/video/usbvision/usbvision-cards.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#define XANBOO 0
-#define BELKIN_VIDEOBUS_II 1
-#define BELKIN_VIDEOBUS 2
-#define BELKIN_USB_VIDEOBUS_II 3
-#define ECHOFX_INTERVIEW_LITE 4
-#define USBGEAR_USBG_V1 5
-#define D_LINK_V100 6
-#define X10_USB_CAMERA 7
-#define HPG_WINTV_LIVE_PAL_BG 8
-#define HPG_WINTV_LIVE_PRO_NTSC_MN 9
-#define ZORAN_PMD_NOGATECH 10
-#define NOGATECH_USB_TV_NTSC_FM 11
-#define PNY_USB_TV_NTSC_FM 12
-#define PV_PLAYTV_USB_PRO_PAL_FM 13
-#define ZT_721 14
-#define HPG_WINTV_NTSC_MN 15
-#define HPG_WINTV_PAL_BG 16
-#define HPG_WINTV_PAL_I 17
-#define HPG_WINTV_PAL_SECAM_L 18
-#define HPG_WINTV_PAL_D_K 19
-#define HPG_WINTV_NTSC_FM 20
-#define HPG_WINTV_PAL_BG_FM 21
-#define HPG_WINTV_PAL_I_FM 22
-#define HPG_WINTV_PAL_D_K_FM 23
-#define HPG_WINTV_PRO_NTSC_MN 24
-#define HPG_WINTV_PRO_NTSC_MN_V2 25
-#define HPG_WINTV_PRO_PAL 26
-#define HPG_WINTV_PRO_NTSC_MN_V3 27
-#define HPG_WINTV_PRO_PAL_BG 28
-#define HPG_WINTV_PRO_PAL_I 29
-#define HPG_WINTV_PRO_PAL_SECAM_L 30
-#define HPG_WINTV_PRO_PAL_D_K 31
-#define HPG_WINTV_PRO_PAL_SECAM 32
-#define HPG_WINTV_PRO_PAL_SECAM_V2 33
-#define HPG_WINTV_PRO_PAL_BG_V2 34
-#define HPG_WINTV_PRO_PAL_BG_D_K 35
-#define HPG_WINTV_PRO_PAL_I_D_K 36
-#define HPG_WINTV_PRO_NTSC_MN_FM 37
-#define HPG_WINTV_PRO_PAL_BG_FM 38
-#define HPG_WINTV_PRO_PAL_I_FM 39
-#define HPG_WINTV_PRO_PAL_D_K_FM 40
-#define HPG_WINTV_PRO_TEMIC_PAL_FM 41
-#define HPG_WINTV_PRO_TEMIC_PAL_BG_FM 42
-#define HPG_WINTV_PRO_PAL_FM 43
-#define HPG_WINTV_PRO_NTSC_MN_FM_V2 44
-#define CAMTEL_TVB330 45
-#define DIGITAL_VIDEO_CREATOR_I 46
-#define GLOBAL_VILLAGE_GV_007_NTSC 47
-#define DAZZLE_DVC_50_REV_1_NTSC 48
-#define DAZZLE_DVC_80_REV_1_PAL 49
-#define DAZZLE_DVC_90_REV_1_SECAM 50
-#define ESKAPE_LABS_MYTV2GO 51
-#define PINNA_PCTV_USB_PAL 52
-#define PINNA_PCTV_USB_SECAM 53
-#define PINNA_PCTV_USB_PAL_FM 54
-#define MIRO_PCTV_USB 55
-#define PINNA_PCTV_USB_NTSC_FM 56
-#define PINNA_PCTV_USB_PAL_FM_V2 57
-#define PINNA_PCTV_USB_NTSC_FM_V2 58
-#define PINNA_PCTV_USB_PAL_FM_V3 59
-#define PINNA_LINX_VD_IN_CAB_NTSC 60
-#define PINNA_LINX_VD_IN_CAB_PAL 61
-#define PINNA_PCTV_BUNGEE_PAL_FM 62
-#define HPG_WINTV 63
-#define PINNA_PCTV_USB_NTSC_FM_V3 64
-#define MICROCAM_NTSC 65
-#define MICROCAM_PAL 66
-
-extern const int usbvision_device_data_size;
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
deleted file mode 100644
index c9b2042f8bd..00000000000
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ /dev/null
@@ -1,2518 +0,0 @@
-/*
- * usbvision-core.c - driver for NT100x USB video capture devices
- *
- *
- * Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de>
- * Dwaine Garden <dwainegarden@rogers.com>
- *
- * This module is part of usbvision driver project.
- * Updates to driver completed by Dwaine P. Garden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/gfp.h>
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/videodev2.h>
-#include <linux/i2c.h>
-
-#include <media/saa7115.h>
-#include <media/v4l2-common.h>
-#include <media/tuner.h>
-
-#include <linux/workqueue.h>
-
-#include "usbvision.h"
-
-static unsigned int core_debug;
-module_param(core_debug, int, 0644);
-MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
-
-static int adjust_compression = 1; /* Set the compression to be adaptive */
-module_param(adjust_compression, int, 0444);
-MODULE_PARM_DESC(adjust_compression, " Set the ADPCM compression for the device. Default: 1 (On)");
-
-/* To help people with Black and White output with using s-video input.
- * Some cables and input device are wired differently. */
-static int switch_svideo_input;
-module_param(switch_svideo_input, int, 0444);
-MODULE_PARM_DESC(switch_svideo_input, " Set the S-Video input. Some cables and input device are wired differently. Default: 0 (Off)");
-
-static unsigned int adjust_x_offset = -1;
-module_param(adjust_x_offset, int, 0644);
-MODULE_PARM_DESC(adjust_x_offset, "adjust X offset display [core]");
-
-static unsigned int adjust_y_offset = -1;
-module_param(adjust_y_offset, int, 0644);
-MODULE_PARM_DESC(adjust_y_offset, "adjust Y offset display [core]");
-
-
-#define ENABLE_HEXDUMP 0 /* Enable if you need it */
-
-
-#ifdef USBVISION_DEBUG
- #define PDEBUG(level, fmt, args...) { \
- if (core_debug & (level)) \
- printk(KERN_INFO KBUILD_MODNAME ":[%s:%d] " fmt, \
- __func__, __LINE__ , ## args); \
- }
-#else
- #define PDEBUG(level, fmt, args...) do {} while (0)
-#endif
-
-#define DBG_HEADER (1 << 0)
-#define DBG_IRQ (1 << 1)
-#define DBG_ISOC (1 << 2)
-#define DBG_PARSE (1 << 3)
-#define DBG_SCRATCH (1 << 4)
-#define DBG_FUNC (1 << 5)
-
-static const int max_imgwidth = MAX_FRAME_WIDTH;
-static const int max_imgheight = MAX_FRAME_HEIGHT;
-static const int min_imgwidth = MIN_FRAME_WIDTH;
-static const int min_imgheight = MIN_FRAME_HEIGHT;
-
-/* The value of 'scratch_buf_size' affects quality of the picture
- * in many ways. Shorter buffers may cause loss of data when client
- * is too slow. Larger buffers are memory-consuming and take longer
- * to work with. This setting can be adjusted, but the default value
- * should be OK for most desktop users.
- */
-#define DEFAULT_SCRATCH_BUF_SIZE (0x20000) /* 128kB memory scratch buffer */
-static const int scratch_buf_size = DEFAULT_SCRATCH_BUF_SIZE;
-
-/* Function prototypes */
-static int usbvision_request_intra(struct usb_usbvision *usbvision);
-static int usbvision_unrequest_intra(struct usb_usbvision *usbvision);
-static int usbvision_adjust_compression(struct usb_usbvision *usbvision);
-static int usbvision_measure_bandwidth(struct usb_usbvision *usbvision);
-
-/*******************************/
-/* Memory management functions */
-/*******************************/
-
-/*
- * Here we want the physical address of the memory.
- * This is used when initializing the contents of the area.
- */
-
-static void *usbvision_rvmalloc(unsigned long size)
-{
- void *mem;
- unsigned long adr;
-
- size = PAGE_ALIGN(size);
- mem = vmalloc_32(size);
- if (!mem)
- return NULL;
-
- memset(mem, 0, size); /* Clear the ram out, no junk to the user */
- adr = (unsigned long) mem;
- while (size > 0) {
- SetPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- return mem;
-}
-
-static void usbvision_rvfree(void *mem, unsigned long size)
-{
- unsigned long adr;
-
- if (!mem)
- return;
-
- size = PAGE_ALIGN(size);
-
- adr = (unsigned long) mem;
- while ((long) size > 0) {
- ClearPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- vfree(mem);
-}
-
-
-#if ENABLE_HEXDUMP
-static void usbvision_hexdump(const unsigned char *data, int len)
-{
- char tmp[80];
- int i, k;
-
- for (i = k = 0; len > 0; i++, len--) {
- if (i > 0 && (i % 16 == 0)) {
- printk("%s\n", tmp);
- k = 0;
- }
- k += sprintf(&tmp[k], "%02x ", data[i]);
- }
- if (k > 0)
- printk(KERN_CONT "%s\n", tmp);
-}
-#endif
-
-/********************************
- * scratch ring buffer handling
- ********************************/
-static int scratch_len(struct usb_usbvision *usbvision) /* This returns the amount of data actually in the buffer */
-{
- int len = usbvision->scratch_write_ptr - usbvision->scratch_read_ptr;
-
- if (len < 0)
- len += scratch_buf_size;
- PDEBUG(DBG_SCRATCH, "scratch_len() = %d\n", len);
-
- return len;
-}
-
-
-/* This returns the free space left in the buffer */
-static int scratch_free(struct usb_usbvision *usbvision)
-{
- int free = usbvision->scratch_read_ptr - usbvision->scratch_write_ptr;
- if (free <= 0)
- free += scratch_buf_size;
- if (free) {
- free -= 1; /* at least one byte in the buffer must */
- /* left blank, otherwise there is no chance to differ between full and empty */
- }
- PDEBUG(DBG_SCRATCH, "return %d\n", free);
-
- return free;
-}
-
-
-/* This puts data into the buffer */
-static int scratch_put(struct usb_usbvision *usbvision, unsigned char *data,
- int len)
-{
- int len_part;
-
- if (usbvision->scratch_write_ptr + len < scratch_buf_size) {
- memcpy(usbvision->scratch + usbvision->scratch_write_ptr, data, len);
- usbvision->scratch_write_ptr += len;
- } else {
- len_part = scratch_buf_size - usbvision->scratch_write_ptr;
- memcpy(usbvision->scratch + usbvision->scratch_write_ptr, data, len_part);
- if (len == len_part) {
- usbvision->scratch_write_ptr = 0; /* just set write_ptr to zero */
- } else {
- memcpy(usbvision->scratch, data + len_part, len - len_part);
- usbvision->scratch_write_ptr = len - len_part;
- }
- }
-
- PDEBUG(DBG_SCRATCH, "len=%d, new write_ptr=%d\n", len, usbvision->scratch_write_ptr);
-
- return len;
-}
-
-/* This marks the write_ptr as position of new frame header */
-static void scratch_mark_header(struct usb_usbvision *usbvision)
-{
- PDEBUG(DBG_SCRATCH, "header at write_ptr=%d\n", usbvision->scratch_headermarker_write_ptr);
-
- usbvision->scratch_headermarker[usbvision->scratch_headermarker_write_ptr] =
- usbvision->scratch_write_ptr;
- usbvision->scratch_headermarker_write_ptr += 1;
- usbvision->scratch_headermarker_write_ptr %= USBVISION_NUM_HEADERMARKER;
-}
-
-/* This gets data from the buffer at the given "ptr" position */
-static int scratch_get_extra(struct usb_usbvision *usbvision,
- unsigned char *data, int *ptr, int len)
-{
- int len_part;
-
- if (*ptr + len < scratch_buf_size) {
- memcpy(data, usbvision->scratch + *ptr, len);
- *ptr += len;
- } else {
- len_part = scratch_buf_size - *ptr;
- memcpy(data, usbvision->scratch + *ptr, len_part);
- if (len == len_part) {
- *ptr = 0; /* just set the y_ptr to zero */
- } else {
- memcpy(data + len_part, usbvision->scratch, len - len_part);
- *ptr = len - len_part;
- }
- }
-
- PDEBUG(DBG_SCRATCH, "len=%d, new ptr=%d\n", len, *ptr);
-
- return len;
-}
-
-
-/* This sets the scratch extra read pointer */
-static void scratch_set_extra_ptr(struct usb_usbvision *usbvision, int *ptr,
- int len)
-{
- *ptr = (usbvision->scratch_read_ptr + len) % scratch_buf_size;
-
- PDEBUG(DBG_SCRATCH, "ptr=%d\n", *ptr);
-}
-
-
-/* This increments the scratch extra read pointer */
-static void scratch_inc_extra_ptr(int *ptr, int len)
-{
- *ptr = (*ptr + len) % scratch_buf_size;
-
- PDEBUG(DBG_SCRATCH, "ptr=%d\n", *ptr);
-}
-
-
-/* This gets data from the buffer */
-static int scratch_get(struct usb_usbvision *usbvision, unsigned char *data,
- int len)
-{
- int len_part;
-
- if (usbvision->scratch_read_ptr + len < scratch_buf_size) {
- memcpy(data, usbvision->scratch + usbvision->scratch_read_ptr, len);
- usbvision->scratch_read_ptr += len;
- } else {
- len_part = scratch_buf_size - usbvision->scratch_read_ptr;
- memcpy(data, usbvision->scratch + usbvision->scratch_read_ptr, len_part);
- if (len == len_part) {
- usbvision->scratch_read_ptr = 0; /* just set the read_ptr to zero */
- } else {
- memcpy(data + len_part, usbvision->scratch, len - len_part);
- usbvision->scratch_read_ptr = len - len_part;
- }
- }
-
- PDEBUG(DBG_SCRATCH, "len=%d, new read_ptr=%d\n", len, usbvision->scratch_read_ptr);
-
- return len;
-}
-
-
-/* This sets read pointer to next header and returns it */
-static int scratch_get_header(struct usb_usbvision *usbvision,
- struct usbvision_frame_header *header)
-{
- int err_code = 0;
-
- PDEBUG(DBG_SCRATCH, "from read_ptr=%d", usbvision->scratch_headermarker_read_ptr);
-
- while (usbvision->scratch_headermarker_write_ptr -
- usbvision->scratch_headermarker_read_ptr != 0) {
- usbvision->scratch_read_ptr =
- usbvision->scratch_headermarker[usbvision->scratch_headermarker_read_ptr];
- usbvision->scratch_headermarker_read_ptr += 1;
- usbvision->scratch_headermarker_read_ptr %= USBVISION_NUM_HEADERMARKER;
- scratch_get(usbvision, (unsigned char *)header, USBVISION_HEADER_LENGTH);
- if ((header->magic_1 == USBVISION_MAGIC_1)
- && (header->magic_2 == USBVISION_MAGIC_2)
- && (header->header_length == USBVISION_HEADER_LENGTH)) {
- err_code = USBVISION_HEADER_LENGTH;
- header->frame_width = header->frame_width_lo + (header->frame_width_hi << 8);
- header->frame_height = header->frame_height_lo + (header->frame_height_hi << 8);
- break;
- }
- }
-
- return err_code;
-}
-
-
-/* This removes len bytes of old data from the buffer */
-static void scratch_rm_old(struct usb_usbvision *usbvision, int len)
-{
- usbvision->scratch_read_ptr += len;
- usbvision->scratch_read_ptr %= scratch_buf_size;
- PDEBUG(DBG_SCRATCH, "read_ptr is now %d\n", usbvision->scratch_read_ptr);
-}
-
-
-/* This resets the buffer - kills all data in it too */
-static void scratch_reset(struct usb_usbvision *usbvision)
-{
- PDEBUG(DBG_SCRATCH, "\n");
-
- usbvision->scratch_read_ptr = 0;
- usbvision->scratch_write_ptr = 0;
- usbvision->scratch_headermarker_read_ptr = 0;
- usbvision->scratch_headermarker_write_ptr = 0;
- usbvision->isocstate = isoc_state_no_frame;
-}
-
-int usbvision_scratch_alloc(struct usb_usbvision *usbvision)
-{
- usbvision->scratch = vmalloc_32(scratch_buf_size);
- scratch_reset(usbvision);
- if (usbvision->scratch == NULL) {
- dev_err(&usbvision->dev->dev,
- "%s: unable to allocate %d bytes for scratch\n",
- __func__, scratch_buf_size);
- return -ENOMEM;
- }
- return 0;
-}
-
-void usbvision_scratch_free(struct usb_usbvision *usbvision)
-{
- vfree(usbvision->scratch);
- usbvision->scratch = NULL;
-}
-
-/*
- * usbvision_decompress_alloc()
- *
- * allocates intermediate buffer for decompression
- */
-int usbvision_decompress_alloc(struct usb_usbvision *usbvision)
-{
- int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2;
-
- usbvision->intra_frame_buffer = vmalloc_32(IFB_size);
- if (usbvision->intra_frame_buffer == NULL) {
- dev_err(&usbvision->dev->dev,
- "%s: unable to allocate %d for compr. frame buffer\n",
- __func__, IFB_size);
- return -ENOMEM;
- }
- return 0;
-}
-
-/*
- * usbvision_decompress_free()
- *
- * frees intermediate buffer for decompression
- */
-void usbvision_decompress_free(struct usb_usbvision *usbvision)
-{
- vfree(usbvision->intra_frame_buffer);
- usbvision->intra_frame_buffer = NULL;
-
-}
-
-/************************************************************
- * Here comes the data parsing stuff that is run as interrupt
- ************************************************************/
-/*
- * usbvision_find_header()
- *
- * Locate one of supported header markers in the scratch buffer.
- */
-static enum parse_state usbvision_find_header(struct usb_usbvision *usbvision)
-{
- struct usbvision_frame *frame;
- int found_header = 0;
-
- frame = usbvision->cur_frame;
-
- while (scratch_get_header(usbvision, &frame->isoc_header) == USBVISION_HEADER_LENGTH) {
- /* found header in scratch */
- PDEBUG(DBG_HEADER, "found header: 0x%02x%02x %d %d %d %d %#x 0x%02x %u %u",
- frame->isoc_header.magic_2,
- frame->isoc_header.magic_1,
- frame->isoc_header.header_length,
- frame->isoc_header.frame_num,
- frame->isoc_header.frame_phase,
- frame->isoc_header.frame_latency,
- frame->isoc_header.data_format,
- frame->isoc_header.format_param,
- frame->isoc_header.frame_width,
- frame->isoc_header.frame_height);
-
- if (usbvision->request_intra) {
- if (frame->isoc_header.format_param & 0x80) {
- found_header = 1;
- usbvision->last_isoc_frame_num = -1; /* do not check for lost frames this time */
- usbvision_unrequest_intra(usbvision);
- break;
- }
- } else {
- found_header = 1;
- break;
- }
- }
-
- if (found_header) {
- frame->frmwidth = frame->isoc_header.frame_width * usbvision->stretch_width;
- frame->frmheight = frame->isoc_header.frame_height * usbvision->stretch_height;
- frame->v4l2_linesize = (frame->frmwidth * frame->v4l2_format.depth) >> 3;
- } else { /* no header found */
- PDEBUG(DBG_HEADER, "skipping scratch data, no header");
- scratch_reset(usbvision);
- return parse_state_end_parse;
- }
-
- /* found header */
- if (frame->isoc_header.data_format == ISOC_MODE_COMPRESS) {
- /* check isoc_header.frame_num for lost frames */
- if (usbvision->last_isoc_frame_num >= 0) {
- if (((usbvision->last_isoc_frame_num + 1) % 32) != frame->isoc_header.frame_num) {
- /* unexpected frame drop: need to request new intra frame */
- PDEBUG(DBG_HEADER, "Lost frame before %d on USB", frame->isoc_header.frame_num);
- usbvision_request_intra(usbvision);
- return parse_state_next_frame;
- }
- }
- usbvision->last_isoc_frame_num = frame->isoc_header.frame_num;
- }
- usbvision->header_count++;
- frame->scanstate = scan_state_lines;
- frame->curline = 0;
-
- return parse_state_continue;
-}
-
-static enum parse_state usbvision_parse_lines_422(struct usb_usbvision *usbvision,
- long *pcopylen)
-{
- volatile struct usbvision_frame *frame;
- unsigned char *f;
- int len;
- int i;
- unsigned char yuyv[4] = { 180, 128, 10, 128 }; /* YUV components */
- unsigned char rv, gv, bv; /* RGB components */
- int clipmask_index, bytes_per_pixel;
- int stretch_bytes, clipmask_add;
-
- frame = usbvision->cur_frame;
- f = frame->data + (frame->v4l2_linesize * frame->curline);
-
- /* Make sure there's enough data for the entire line */
- len = (frame->isoc_header.frame_width * 2) + 5;
- if (scratch_len(usbvision) < len) {
- PDEBUG(DBG_PARSE, "out of data in line %d, need %u.\n", frame->curline, len);
- return parse_state_out;
- }
-
- if ((frame->curline + 1) >= frame->frmheight)
- return parse_state_next_frame;
-
- bytes_per_pixel = frame->v4l2_format.bytes_per_pixel;
- stretch_bytes = (usbvision->stretch_width - 1) * bytes_per_pixel;
- clipmask_index = frame->curline * MAX_FRAME_WIDTH;
- clipmask_add = usbvision->stretch_width;
-
- for (i = 0; i < frame->frmwidth; i += (2 * usbvision->stretch_width)) {
- scratch_get(usbvision, &yuyv[0], 4);
-
- if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
- *f++ = yuyv[0]; /* Y */
- *f++ = yuyv[3]; /* U */
- } else {
- YUV_TO_RGB_BY_THE_BOOK(yuyv[0], yuyv[1], yuyv[3], rv, gv, bv);
- switch (frame->v4l2_format.format) {
- case V4L2_PIX_FMT_RGB565:
- *f++ = (0x1F & rv) |
- (0xE0 & (gv << 5));
- *f++ = (0x07 & (gv >> 3)) |
- (0xF8 & bv);
- break;
- case V4L2_PIX_FMT_RGB24:
- *f++ = rv;
- *f++ = gv;
- *f++ = bv;
- break;
- case V4L2_PIX_FMT_RGB32:
- *f++ = rv;
- *f++ = gv;
- *f++ = bv;
- f++;
- break;
- case V4L2_PIX_FMT_RGB555:
- *f++ = (0x1F & rv) |
- (0xE0 & (gv << 5));
- *f++ = (0x03 & (gv >> 3)) |
- (0x7C & (bv << 2));
- break;
- }
- }
- clipmask_index += clipmask_add;
- f += stretch_bytes;
-
- if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
- *f++ = yuyv[2]; /* Y */
- *f++ = yuyv[1]; /* V */
- } else {
- YUV_TO_RGB_BY_THE_BOOK(yuyv[2], yuyv[1], yuyv[3], rv, gv, bv);
- switch (frame->v4l2_format.format) {
- case V4L2_PIX_FMT_RGB565:
- *f++ = (0x1F & rv) |
- (0xE0 & (gv << 5));
- *f++ = (0x07 & (gv >> 3)) |
- (0xF8 & bv);
- break;
- case V4L2_PIX_FMT_RGB24:
- *f++ = rv;
- *f++ = gv;
- *f++ = bv;
- break;
- case V4L2_PIX_FMT_RGB32:
- *f++ = rv;
- *f++ = gv;
- *f++ = bv;
- f++;
- break;
- case V4L2_PIX_FMT_RGB555:
- *f++ = (0x1F & rv) |
- (0xE0 & (gv << 5));
- *f++ = (0x03 & (gv >> 3)) |
- (0x7C & (bv << 2));
- break;
- }
- }
- clipmask_index += clipmask_add;
- f += stretch_bytes;
- }
-
- frame->curline += usbvision->stretch_height;
- *pcopylen += frame->v4l2_linesize * usbvision->stretch_height;
-
- if (frame->curline >= frame->frmheight)
- return parse_state_next_frame;
- return parse_state_continue;
-}
-
-/* The decompression routine */
-static int usbvision_decompress(struct usb_usbvision *usbvision, unsigned char *compressed,
- unsigned char *decompressed, int *start_pos,
- int *block_typestart_pos, int len)
-{
- int rest_pixel, idx, pos, extra_pos, block_len, block_type_pos, block_type_len;
- unsigned char block_byte, block_code, block_type, block_type_byte, integrator;
-
- integrator = 0;
- pos = *start_pos;
- block_type_pos = *block_typestart_pos;
- extra_pos = pos;
- block_len = 0;
- block_byte = 0;
- block_code = 0;
- block_type = 0;
- block_type_byte = 0;
- block_type_len = 0;
- rest_pixel = len;
-
- for (idx = 0; idx < len; idx++) {
- if (block_len == 0) {
- if (block_type_len == 0) {
- block_type_byte = compressed[block_type_pos];
- block_type_pos++;
- block_type_len = 4;
- }
- block_type = (block_type_byte & 0xC0) >> 6;
-
- /* statistic: */
- usbvision->compr_block_types[block_type]++;
-
- pos = extra_pos;
- if (block_type == 0) {
- if (rest_pixel >= 24) {
- idx += 23;
- rest_pixel -= 24;
- integrator = decompressed[idx];
- } else {
- idx += rest_pixel - 1;
- rest_pixel = 0;
- }
- } else {
- block_code = compressed[pos];
- pos++;
- if (rest_pixel >= 24)
- block_len = 24;
- else
- block_len = rest_pixel;
- rest_pixel -= block_len;
- extra_pos = pos + (block_len / 4);
- }
- block_type_byte <<= 2;
- block_type_len -= 1;
- }
- if (block_len > 0) {
- if ((block_len % 4) == 0) {
- block_byte = compressed[pos];
- pos++;
- }
- if (block_type == 1) /* inter Block */
- integrator = decompressed[idx];
- switch (block_byte & 0xC0) {
- case 0x03 << 6:
- integrator += compressed[extra_pos];
- extra_pos++;
- break;
- case 0x02 << 6:
- integrator += block_code;
- break;
- case 0x00:
- integrator -= block_code;
- break;
- }
- decompressed[idx] = integrator;
- block_byte <<= 2;
- block_len -= 1;
- }
- }
- *start_pos = extra_pos;
- *block_typestart_pos = block_type_pos;
- return idx;
-}
-
-
-/*
- * usbvision_parse_compress()
- *
- * Parse compressed frame from the scratch buffer, put
- * decoded RGB value into the current frame buffer and add the written
- * number of bytes (RGB) to the *pcopylen.
- *
- */
-static enum parse_state usbvision_parse_compress(struct usb_usbvision *usbvision,
- long *pcopylen)
-{
-#define USBVISION_STRIP_MAGIC 0x5A
-#define USBVISION_STRIP_LEN_MAX 400
-#define USBVISION_STRIP_HEADER_LEN 3
-
- struct usbvision_frame *frame;
- unsigned char *f, *u = NULL, *v = NULL;
- unsigned char strip_data[USBVISION_STRIP_LEN_MAX];
- unsigned char strip_header[USBVISION_STRIP_HEADER_LEN];
- int idx, idx_end, strip_len, strip_ptr, startblock_pos, block_pos, block_type_pos;
- int clipmask_index;
- int image_size;
- unsigned char rv, gv, bv;
- static unsigned char *Y, *U, *V;
-
- frame = usbvision->cur_frame;
- image_size = frame->frmwidth * frame->frmheight;
- if ((frame->v4l2_format.format == V4L2_PIX_FMT_YUV422P) ||
- (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420)) { /* this is a planar format */
- /* ... v4l2_linesize not used here. */
- f = frame->data + (frame->width * frame->curline);
- } else
- f = frame->data + (frame->v4l2_linesize * frame->curline);
-
- if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) { /* initialise u and v pointers */
- /* get base of u and b planes add halfoffset */
- u = frame->data
- + image_size
- + (frame->frmwidth >> 1) * frame->curline;
- v = u + (image_size >> 1);
- } else if (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420) {
- v = frame->data + image_size + ((frame->curline * (frame->width)) >> 2);
- u = v + (image_size >> 2);
- }
-
- if (frame->curline == 0)
- usbvision_adjust_compression(usbvision);
-
- if (scratch_len(usbvision) < USBVISION_STRIP_HEADER_LEN)
- return parse_state_out;
-
- /* get strip header without changing the scratch_read_ptr */
- scratch_set_extra_ptr(usbvision, &strip_ptr, 0);
- scratch_get_extra(usbvision, &strip_header[0], &strip_ptr,
- USBVISION_STRIP_HEADER_LEN);
-
- if (strip_header[0] != USBVISION_STRIP_MAGIC) {
- /* wrong strip magic */
- usbvision->strip_magic_errors++;
- return parse_state_next_frame;
- }
-
- if (frame->curline != (int)strip_header[2]) {
- /* line number mismatch error */
- usbvision->strip_line_number_errors++;
- }
-
- strip_len = 2 * (unsigned int)strip_header[1];
- if (strip_len > USBVISION_STRIP_LEN_MAX) {
- /* strip overrun */
- /* I think this never happens */
- usbvision_request_intra(usbvision);
- }
-
- if (scratch_len(usbvision) < strip_len) {
- /* there is not enough data for the strip */
- return parse_state_out;
- }
-
- if (usbvision->intra_frame_buffer) {
- Y = usbvision->intra_frame_buffer + frame->frmwidth * frame->curline;
- U = usbvision->intra_frame_buffer + image_size + (frame->frmwidth / 2) * (frame->curline / 2);
- V = usbvision->intra_frame_buffer + image_size / 4 * 5 + (frame->frmwidth / 2) * (frame->curline / 2);
- } else {
- return parse_state_next_frame;
- }
-
- clipmask_index = frame->curline * MAX_FRAME_WIDTH;
-
- scratch_get(usbvision, strip_data, strip_len);
-
- idx_end = frame->frmwidth;
- block_type_pos = USBVISION_STRIP_HEADER_LEN;
- startblock_pos = block_type_pos + (idx_end - 1) / 96 + (idx_end / 2 - 1) / 96 + 2;
- block_pos = startblock_pos;
-
- usbvision->block_pos = block_pos;
-
- usbvision_decompress(usbvision, strip_data, Y, &block_pos, &block_type_pos, idx_end);
- if (strip_len > usbvision->max_strip_len)
- usbvision->max_strip_len = strip_len;
-
- if (frame->curline % 2)
- usbvision_decompress(usbvision, strip_data, V, &block_pos, &block_type_pos, idx_end / 2);
- else
- usbvision_decompress(usbvision, strip_data, U, &block_pos, &block_type_pos, idx_end / 2);
-
- if (block_pos > usbvision->comprblock_pos)
- usbvision->comprblock_pos = block_pos;
- if (block_pos > strip_len)
- usbvision->strip_len_errors++;
-
- for (idx = 0; idx < idx_end; idx++) {
- if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
- *f++ = Y[idx];
- *f++ = idx & 0x01 ? U[idx / 2] : V[idx / 2];
- } else if (frame->v4l2_format.format == V4L2_PIX_FMT_YUV422P) {
- *f++ = Y[idx];
- if (idx & 0x01)
- *u++ = U[idx >> 1];
- else
- *v++ = V[idx >> 1];
- } else if (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420) {
- *f++ = Y[idx];
- if (!((idx & 0x01) | (frame->curline & 0x01))) {
- /* only need do this for 1 in 4 pixels */
- /* intraframe buffer is YUV420 format */
- *u++ = U[idx >> 1];
- *v++ = V[idx >> 1];
- }
- } else {
- YUV_TO_RGB_BY_THE_BOOK(Y[idx], U[idx / 2], V[idx / 2], rv, gv, bv);
- switch (frame->v4l2_format.format) {
- case V4L2_PIX_FMT_GREY:
- *f++ = Y[idx];
- break;
- case V4L2_PIX_FMT_RGB555:
- *f++ = (0x1F & rv) |
- (0xE0 & (gv << 5));
- *f++ = (0x03 & (gv >> 3)) |
- (0x7C & (bv << 2));
- break;
- case V4L2_PIX_FMT_RGB565:
- *f++ = (0x1F & rv) |
- (0xE0 & (gv << 5));
- *f++ = (0x07 & (gv >> 3)) |
- (0xF8 & bv);
- break;
- case V4L2_PIX_FMT_RGB24:
- *f++ = rv;
- *f++ = gv;
- *f++ = bv;
- break;
- case V4L2_PIX_FMT_RGB32:
- *f++ = rv;
- *f++ = gv;
- *f++ = bv;
- f++;
- break;
- }
- }
- clipmask_index++;
- }
- /* Deal with non-integer no. of bytes for YUV420P */
- if (frame->v4l2_format.format != V4L2_PIX_FMT_YVU420)
- *pcopylen += frame->v4l2_linesize;
- else
- *pcopylen += frame->curline & 0x01 ? frame->v4l2_linesize : frame->v4l2_linesize << 1;
-
- frame->curline += 1;
-
- if (frame->curline >= frame->frmheight)
- return parse_state_next_frame;
- return parse_state_continue;
-
-}
-
-
-/*
- * usbvision_parse_lines_420()
- *
- * Parse two lines from the scratch buffer, put
- * decoded RGB value into the current frame buffer and add the written
- * number of bytes (RGB) to the *pcopylen.
- *
- */
-static enum parse_state usbvision_parse_lines_420(struct usb_usbvision *usbvision,
- long *pcopylen)
-{
- struct usbvision_frame *frame;
- unsigned char *f_even = NULL, *f_odd = NULL;
- unsigned int pixel_per_line, block;
- int pixel, block_split;
- int y_ptr, u_ptr, v_ptr, y_odd_offset;
- const int y_block_size = 128;
- const int uv_block_size = 64;
- const int sub_block_size = 32;
- const int y_step[] = { 0, 0, 0, 2 }, y_step_size = 4;
- const int uv_step[] = { 0, 0, 0, 4 }, uv_step_size = 4;
- unsigned char y[2], u, v; /* YUV components */
- int y_, u_, v_, vb, uvg, ur;
- int r_, g_, b_; /* RGB components */
- unsigned char g;
- int clipmask_even_index, clipmask_odd_index, bytes_per_pixel;
- int clipmask_add, stretch_bytes;
-
- frame = usbvision->cur_frame;
- f_even = frame->data + (frame->v4l2_linesize * frame->curline);
- f_odd = f_even + frame->v4l2_linesize * usbvision->stretch_height;
-
- /* Make sure there's enough data for the entire line */
- /* In this mode usbvision transfer 3 bytes for every 2 pixels */
- /* I need two lines to decode the color */
- bytes_per_pixel = frame->v4l2_format.bytes_per_pixel;
- stretch_bytes = (usbvision->stretch_width - 1) * bytes_per_pixel;
- clipmask_even_index = frame->curline * MAX_FRAME_WIDTH;
- clipmask_odd_index = clipmask_even_index + MAX_FRAME_WIDTH;
- clipmask_add = usbvision->stretch_width;
- pixel_per_line = frame->isoc_header.frame_width;
-
- if (scratch_len(usbvision) < (int)pixel_per_line * 3) {
- /* printk(KERN_DEBUG "out of data, need %d\n", len); */
- return parse_state_out;
- }
-
- if ((frame->curline + 1) >= frame->frmheight)
- return parse_state_next_frame;
-
- block_split = (pixel_per_line%y_block_size) ? 1 : 0; /* are some blocks splitted into different lines? */
-
- y_odd_offset = (pixel_per_line / y_block_size) * (y_block_size + uv_block_size)
- + block_split * uv_block_size;
-
- scratch_set_extra_ptr(usbvision, &y_ptr, y_odd_offset);
- scratch_set_extra_ptr(usbvision, &u_ptr, y_block_size);
- scratch_set_extra_ptr(usbvision, &v_ptr, y_odd_offset
- + (4 - block_split) * sub_block_size);
-
- for (block = 0; block < (pixel_per_line / sub_block_size); block++) {
- for (pixel = 0; pixel < sub_block_size; pixel += 2) {
- scratch_get(usbvision, &y[0], 2);
- scratch_get_extra(usbvision, &u, &u_ptr, 1);
- scratch_get_extra(usbvision, &v, &v_ptr, 1);
-
- /* I don't use the YUV_TO_RGB macro for better performance */
- v_ = v - 128;
- u_ = u - 128;
- vb = 132252 * v_;
- uvg = -53281 * u_ - 25625 * v_;
- ur = 104595 * u_;
-
- if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
- *f_even++ = y[0];
- *f_even++ = v;
- } else {
- y_ = 76284 * (y[0] - 16);
-
- b_ = (y_ + vb) >> 16;
- g_ = (y_ + uvg) >> 16;
- r_ = (y_ + ur) >> 16;
-
- switch (frame->v4l2_format.format) {
- case V4L2_PIX_FMT_RGB565:
- g = LIMIT_RGB(g_);
- *f_even++ =
- (0x1F & LIMIT_RGB(r_)) |
- (0xE0 & (g << 5));
- *f_even++ =
- (0x07 & (g >> 3)) |
- (0xF8 & LIMIT_RGB(b_));
- break;
- case V4L2_PIX_FMT_RGB24:
- *f_even++ = LIMIT_RGB(r_);
- *f_even++ = LIMIT_RGB(g_);
- *f_even++ = LIMIT_RGB(b_);
- break;
- case V4L2_PIX_FMT_RGB32:
- *f_even++ = LIMIT_RGB(r_);
- *f_even++ = LIMIT_RGB(g_);
- *f_even++ = LIMIT_RGB(b_);
- f_even++;
- break;
- case V4L2_PIX_FMT_RGB555:
- g = LIMIT_RGB(g_);
- *f_even++ = (0x1F & LIMIT_RGB(r_)) |
- (0xE0 & (g << 5));
- *f_even++ = (0x03 & (g >> 3)) |
- (0x7C & (LIMIT_RGB(b_) << 2));
- break;
- }
- }
- clipmask_even_index += clipmask_add;
- f_even += stretch_bytes;
-
- if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
- *f_even++ = y[1];
- *f_even++ = u;
- } else {
- y_ = 76284 * (y[1] - 16);
-
- b_ = (y_ + vb) >> 16;
- g_ = (y_ + uvg) >> 16;
- r_ = (y_ + ur) >> 16;
-
- switch (frame->v4l2_format.format) {
- case V4L2_PIX_FMT_RGB565:
- g = LIMIT_RGB(g_);
- *f_even++ =
- (0x1F & LIMIT_RGB(r_)) |
- (0xE0 & (g << 5));
- *f_even++ =
- (0x07 & (g >> 3)) |
- (0xF8 & LIMIT_RGB(b_));
- break;
- case V4L2_PIX_FMT_RGB24:
- *f_even++ = LIMIT_RGB(r_);
- *f_even++ = LIMIT_RGB(g_);
- *f_even++ = LIMIT_RGB(b_);
- break;
- case V4L2_PIX_FMT_RGB32:
- *f_even++ = LIMIT_RGB(r_);
- *f_even++ = LIMIT_RGB(g_);
- *f_even++ = LIMIT_RGB(b_);
- f_even++;
- break;
- case V4L2_PIX_FMT_RGB555:
- g = LIMIT_RGB(g_);
- *f_even++ = (0x1F & LIMIT_RGB(r_)) |
- (0xE0 & (g << 5));
- *f_even++ = (0x03 & (g >> 3)) |
- (0x7C & (LIMIT_RGB(b_) << 2));
- break;
- }
- }
- clipmask_even_index += clipmask_add;
- f_even += stretch_bytes;
-
- scratch_get_extra(usbvision, &y[0], &y_ptr, 2);
-
- if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
- *f_odd++ = y[0];
- *f_odd++ = v;
- } else {
- y_ = 76284 * (y[0] - 16);
-
- b_ = (y_ + vb) >> 16;
- g_ = (y_ + uvg) >> 16;
- r_ = (y_ + ur) >> 16;
-
- switch (frame->v4l2_format.format) {
- case V4L2_PIX_FMT_RGB565:
- g = LIMIT_RGB(g_);
- *f_odd++ =
- (0x1F & LIMIT_RGB(r_)) |
- (0xE0 & (g << 5));
- *f_odd++ =
- (0x07 & (g >> 3)) |
- (0xF8 & LIMIT_RGB(b_));
- break;
- case V4L2_PIX_FMT_RGB24:
- *f_odd++ = LIMIT_RGB(r_);
- *f_odd++ = LIMIT_RGB(g_);
- *f_odd++ = LIMIT_RGB(b_);
- break;
- case V4L2_PIX_FMT_RGB32:
- *f_odd++ = LIMIT_RGB(r_);
- *f_odd++ = LIMIT_RGB(g_);
- *f_odd++ = LIMIT_RGB(b_);
- f_odd++;
- break;
- case V4L2_PIX_FMT_RGB555:
- g = LIMIT_RGB(g_);
- *f_odd++ = (0x1F & LIMIT_RGB(r_)) |
- (0xE0 & (g << 5));
- *f_odd++ = (0x03 & (g >> 3)) |
- (0x7C & (LIMIT_RGB(b_) << 2));
- break;
- }
- }
- clipmask_odd_index += clipmask_add;
- f_odd += stretch_bytes;
-
- if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
- *f_odd++ = y[1];
- *f_odd++ = u;
- } else {
- y_ = 76284 * (y[1] - 16);
-
- b_ = (y_ + vb) >> 16;
- g_ = (y_ + uvg) >> 16;
- r_ = (y_ + ur) >> 16;
-
- switch (frame->v4l2_format.format) {
- case V4L2_PIX_FMT_RGB565:
- g = LIMIT_RGB(g_);
- *f_odd++ =
- (0x1F & LIMIT_RGB(r_)) |
- (0xE0 & (g << 5));
- *f_odd++ =
- (0x07 & (g >> 3)) |
- (0xF8 & LIMIT_RGB(b_));
- break;
- case V4L2_PIX_FMT_RGB24:
- *f_odd++ = LIMIT_RGB(r_);
- *f_odd++ = LIMIT_RGB(g_);
- *f_odd++ = LIMIT_RGB(b_);
- break;
- case V4L2_PIX_FMT_RGB32:
- *f_odd++ = LIMIT_RGB(r_);
- *f_odd++ = LIMIT_RGB(g_);
- *f_odd++ = LIMIT_RGB(b_);
- f_odd++;
- break;
- case V4L2_PIX_FMT_RGB555:
- g = LIMIT_RGB(g_);
- *f_odd++ = (0x1F & LIMIT_RGB(r_)) |
- (0xE0 & (g << 5));
- *f_odd++ = (0x03 & (g >> 3)) |
- (0x7C & (LIMIT_RGB(b_) << 2));
- break;
- }
- }
- clipmask_odd_index += clipmask_add;
- f_odd += stretch_bytes;
- }
-
- scratch_rm_old(usbvision, y_step[block % y_step_size] * sub_block_size);
- scratch_inc_extra_ptr(&y_ptr, y_step[(block + 2 * block_split) % y_step_size]
- * sub_block_size);
- scratch_inc_extra_ptr(&u_ptr, uv_step[block % uv_step_size]
- * sub_block_size);
- scratch_inc_extra_ptr(&v_ptr, uv_step[(block + 2 * block_split) % uv_step_size]
- * sub_block_size);
- }
-
- scratch_rm_old(usbvision, pixel_per_line * 3 / 2
- + block_split * sub_block_size);
-
- frame->curline += 2 * usbvision->stretch_height;
- *pcopylen += frame->v4l2_linesize * 2 * usbvision->stretch_height;
-
- if (frame->curline >= frame->frmheight)
- return parse_state_next_frame;
- return parse_state_continue;
-}
-
-/*
- * usbvision_parse_data()
- *
- * Generic routine to parse the scratch buffer. It employs either
- * usbvision_find_header() or usbvision_parse_lines() to do most
- * of work.
- *
- */
-static void usbvision_parse_data(struct usb_usbvision *usbvision)
-{
- struct usbvision_frame *frame;
- enum parse_state newstate;
- long copylen = 0;
- unsigned long lock_flags;
-
- frame = usbvision->cur_frame;
-
- PDEBUG(DBG_PARSE, "parsing len=%d\n", scratch_len(usbvision));
-
- while (1) {
- newstate = parse_state_out;
- if (scratch_len(usbvision)) {
- if (frame->scanstate == scan_state_scanning) {
- newstate = usbvision_find_header(usbvision);
- } else if (frame->scanstate == scan_state_lines) {
- if (usbvision->isoc_mode == ISOC_MODE_YUV420)
- newstate = usbvision_parse_lines_420(usbvision, &copylen);
- else if (usbvision->isoc_mode == ISOC_MODE_YUV422)
- newstate = usbvision_parse_lines_422(usbvision, &copylen);
- else if (usbvision->isoc_mode == ISOC_MODE_COMPRESS)
- newstate = usbvision_parse_compress(usbvision, &copylen);
- }
- }
- if (newstate == parse_state_continue)
- continue;
- if ((newstate == parse_state_next_frame) || (newstate == parse_state_out))
- break;
- return; /* parse_state_end_parse */
- }
-
- if (newstate == parse_state_next_frame) {
- frame->grabstate = frame_state_done;
- do_gettimeofday(&(frame->timestamp));
- frame->sequence = usbvision->frame_num;
-
- spin_lock_irqsave(&usbvision->queue_lock, lock_flags);
- list_move_tail(&(frame->frame), &usbvision->outqueue);
- usbvision->cur_frame = NULL;
- spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);
-
- usbvision->frame_num++;
-
- /* This will cause the process to request another frame. */
- if (waitqueue_active(&usbvision->wait_frame)) {
- PDEBUG(DBG_PARSE, "Wake up !");
- wake_up_interruptible(&usbvision->wait_frame);
- }
- } else {
- frame->grabstate = frame_state_grabbing;
- }
-
- /* Update the frame's uncompressed length. */
- frame->scanlength += copylen;
-}
-
-
-/*
- * Make all of the blocks of data contiguous
- */
-static int usbvision_compress_isochronous(struct usb_usbvision *usbvision,
- struct urb *urb)
-{
- unsigned char *packet_data;
- int i, totlen = 0;
-
- for (i = 0; i < urb->number_of_packets; i++) {
- int packet_len = urb->iso_frame_desc[i].actual_length;
- int packet_stat = urb->iso_frame_desc[i].status;
-
- packet_data = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
-
- /* Detect and ignore errored packets */
- if (packet_stat) { /* packet_stat != 0 ????????????? */
- PDEBUG(DBG_ISOC, "data error: [%d] len=%d, status=%X", i, packet_len, packet_stat);
- usbvision->isoc_err_count++;
- continue;
- }
-
- /* Detect and ignore empty packets */
- if (packet_len < 0) {
- PDEBUG(DBG_ISOC, "error packet [%d]", i);
- usbvision->isoc_skip_count++;
- continue;
- } else if (packet_len == 0) { /* Frame end ????? */
- PDEBUG(DBG_ISOC, "null packet [%d]", i);
- usbvision->isocstate = isoc_state_no_frame;
- usbvision->isoc_skip_count++;
- continue;
- } else if (packet_len > usbvision->isoc_packet_size) {
- PDEBUG(DBG_ISOC, "packet[%d] > isoc_packet_size", i);
- usbvision->isoc_skip_count++;
- continue;
- }
-
- PDEBUG(DBG_ISOC, "packet ok [%d] len=%d", i, packet_len);
-
- if (usbvision->isocstate == isoc_state_no_frame) { /* new frame begins */
- usbvision->isocstate = isoc_state_in_frame;
- scratch_mark_header(usbvision);
- usbvision_measure_bandwidth(usbvision);
- PDEBUG(DBG_ISOC, "packet with header");
- }
-
- /*
- * If usbvision continues to feed us with data but there is no
- * consumption (if, for example, V4L client fell asleep) we
- * may overflow the buffer. We have to move old data over to
- * free room for new data. This is bad for old data. If we
- * just drop new data then it's bad for new data... choose
- * your favorite evil here.
- */
- if (scratch_free(usbvision) < packet_len) {
- usbvision->scratch_ovf_count++;
- PDEBUG(DBG_ISOC, "scratch buf overflow! scr_len: %d, n: %d",
- scratch_len(usbvision), packet_len);
- scratch_rm_old(usbvision, packet_len - scratch_free(usbvision));
- }
-
- /* Now we know that there is enough room in scratch buffer */
- scratch_put(usbvision, packet_data, packet_len);
- totlen += packet_len;
- usbvision->isoc_data_count += packet_len;
- usbvision->isoc_packet_count++;
- }
-#if ENABLE_HEXDUMP
- if (totlen > 0) {
- static int foo;
-
- if (foo < 1) {
- printk(KERN_DEBUG "+%d.\n", usbvision->scratchlen);
- usbvision_hexdump(data0, (totlen > 64) ? 64 : totlen);
- ++foo;
- }
- }
-#endif
- return totlen;
-}
-
-static void usbvision_isoc_irq(struct urb *urb)
-{
- int err_code = 0;
- int len;
- struct usb_usbvision *usbvision = urb->context;
- int i;
- unsigned long start_time = jiffies;
- struct usbvision_frame **f;
-
- /* We don't want to do anything if we are about to be removed! */
- if (!USBVISION_IS_OPERATIONAL(usbvision))
- return;
-
- /* any urb with wrong status is ignored without acknowledgement */
- if (urb->status == -ENOENT)
- return;
-
- f = &usbvision->cur_frame;
-
- /* Manage streaming interruption */
- if (usbvision->streaming == stream_interrupt) {
- usbvision->streaming = stream_idle;
- if ((*f)) {
- (*f)->grabstate = frame_state_ready;
- (*f)->scanstate = scan_state_scanning;
- }
- PDEBUG(DBG_IRQ, "stream interrupted");
- wake_up_interruptible(&usbvision->wait_stream);
- }
-
- /* Copy the data received into our scratch buffer */
- len = usbvision_compress_isochronous(usbvision, urb);
-
- usbvision->isoc_urb_count++;
- usbvision->urb_length = len;
-
- if (usbvision->streaming == stream_on) {
- /* If we collected enough data let's parse! */
- if (scratch_len(usbvision) > USBVISION_HEADER_LENGTH &&
- !list_empty(&(usbvision->inqueue))) {
- if (!(*f)) {
- (*f) = list_entry(usbvision->inqueue.next,
- struct usbvision_frame,
- frame);
- }
- usbvision_parse_data(usbvision);
- } else {
- /* If we don't have a frame
- we're current working on, complain */
- PDEBUG(DBG_IRQ,
- "received data, but no one needs it");
- scratch_reset(usbvision);
- }
- } else {
- PDEBUG(DBG_IRQ, "received data, but no one needs it");
- scratch_reset(usbvision);
- }
-
- usbvision->time_in_irq += jiffies - start_time;
-
- for (i = 0; i < USBVISION_URB_FRAMES; i++) {
- urb->iso_frame_desc[i].status = 0;
- urb->iso_frame_desc[i].actual_length = 0;
- }
-
- urb->status = 0;
- urb->dev = usbvision->dev;
- err_code = usb_submit_urb(urb, GFP_ATOMIC);
-
- if (err_code) {
- dev_err(&usbvision->dev->dev,
- "%s: usb_submit_urb failed: error %d\n",
- __func__, err_code);
- }
-
- return;
-}
-
-/*************************************/
-/* Low level usbvision access functions */
-/*************************************/
-
-/*
- * usbvision_read_reg()
- *
- * return < 0 -> Error
- * >= 0 -> Data
- */
-
-int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg)
-{
- int err_code = 0;
- unsigned char buffer[1];
-
- if (!USBVISION_IS_OPERATIONAL(usbvision))
- return -1;
-
- err_code = usb_control_msg(usbvision->dev, usb_rcvctrlpipe(usbvision->dev, 1),
- USBVISION_OP_CODE,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
- 0, (__u16) reg, buffer, 1, HZ);
-
- if (err_code < 0) {
- dev_err(&usbvision->dev->dev,
- "%s: failed: error %d\n", __func__, err_code);
- return err_code;
- }
- return buffer[0];
-}
-
-/*
- * usbvision_write_reg()
- *
- * return 1 -> Reg written
- * 0 -> usbvision is not yet ready
- * -1 -> Something went wrong
- */
-
-int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg,
- unsigned char value)
-{
- int err_code = 0;
-
- if (!USBVISION_IS_OPERATIONAL(usbvision))
- return 0;
-
- err_code = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
- USBVISION_OP_CODE,
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ);
-
- if (err_code < 0) {
- dev_err(&usbvision->dev->dev,
- "%s: failed: error %d\n", __func__, err_code);
- }
- return err_code;
-}
-
-
-static void usbvision_ctrl_urb_complete(struct urb *urb)
-{
- struct usb_usbvision *usbvision = (struct usb_usbvision *)urb->context;
-
- PDEBUG(DBG_IRQ, "");
- usbvision->ctrl_urb_busy = 0;
- if (waitqueue_active(&usbvision->ctrl_urb_wq))
- wake_up_interruptible(&usbvision->ctrl_urb_wq);
-}
-
-
-static int usbvision_write_reg_irq(struct usb_usbvision *usbvision, int address,
- unsigned char *data, int len)
-{
- int err_code = 0;
-
- PDEBUG(DBG_IRQ, "");
- if (len > 8)
- return -EFAULT;
- if (usbvision->ctrl_urb_busy)
- return -EBUSY;
- usbvision->ctrl_urb_busy = 1;
-
- usbvision->ctrl_urb_setup.bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
- usbvision->ctrl_urb_setup.bRequest = USBVISION_OP_CODE;
- usbvision->ctrl_urb_setup.wValue = 0;
- usbvision->ctrl_urb_setup.wIndex = cpu_to_le16(address);
- usbvision->ctrl_urb_setup.wLength = cpu_to_le16(len);
- usb_fill_control_urb(usbvision->ctrl_urb, usbvision->dev,
- usb_sndctrlpipe(usbvision->dev, 1),
- (unsigned char *)&usbvision->ctrl_urb_setup,
- (void *)usbvision->ctrl_urb_buffer, len,
- usbvision_ctrl_urb_complete,
- (void *)usbvision);
-
- memcpy(usbvision->ctrl_urb_buffer, data, len);
-
- err_code = usb_submit_urb(usbvision->ctrl_urb, GFP_ATOMIC);
- if (err_code < 0) {
- /* error in usb_submit_urb() */
- usbvision->ctrl_urb_busy = 0;
- }
- PDEBUG(DBG_IRQ, "submit %d byte: error %d", len, err_code);
- return err_code;
-}
-
-
-static int usbvision_init_compression(struct usb_usbvision *usbvision)
-{
- int err_code = 0;
-
- usbvision->last_isoc_frame_num = -1;
- usbvision->isoc_data_count = 0;
- usbvision->isoc_packet_count = 0;
- usbvision->isoc_skip_count = 0;
- usbvision->compr_level = 50;
- usbvision->last_compr_level = -1;
- usbvision->isoc_urb_count = 0;
- usbvision->request_intra = 1;
- usbvision->isoc_measure_bandwidth_count = 0;
-
- return err_code;
-}
-
-/* this function measures the used bandwidth since last call
- * return: 0 : no error
- * sets used_bandwidth to 1-100 : 1-100% of full bandwidth resp. to isoc_packet_size
- */
-static int usbvision_measure_bandwidth(struct usb_usbvision *usbvision)
-{
- int err_code = 0;
-
- if (usbvision->isoc_measure_bandwidth_count < 2) { /* this gives an average bandwidth of 3 frames */
- usbvision->isoc_measure_bandwidth_count++;
- return err_code;
- }
- if ((usbvision->isoc_packet_size > 0) && (usbvision->isoc_packet_count > 0)) {
- usbvision->used_bandwidth = usbvision->isoc_data_count /
- (usbvision->isoc_packet_count + usbvision->isoc_skip_count) *
- 100 / usbvision->isoc_packet_size;
- }
- usbvision->isoc_measure_bandwidth_count = 0;
- usbvision->isoc_data_count = 0;
- usbvision->isoc_packet_count = 0;
- usbvision->isoc_skip_count = 0;
- return err_code;
-}
-
-static int usbvision_adjust_compression(struct usb_usbvision *usbvision)
-{
- int err_code = 0;
- unsigned char buffer[6];
-
- PDEBUG(DBG_IRQ, "");
- if ((adjust_compression) && (usbvision->used_bandwidth > 0)) {
- usbvision->compr_level += (usbvision->used_bandwidth - 90) / 2;
- RESTRICT_TO_RANGE(usbvision->compr_level, 0, 100);
- if (usbvision->compr_level != usbvision->last_compr_level) {
- int distortion;
-
- if (usbvision->bridge_type == BRIDGE_NT1004 || usbvision->bridge_type == BRIDGE_NT1005) {
- buffer[0] = (unsigned char)(4 + 16 * usbvision->compr_level / 100); /* PCM Threshold 1 */
- buffer[1] = (unsigned char)(4 + 8 * usbvision->compr_level / 100); /* PCM Threshold 2 */
- distortion = 7 + 248 * usbvision->compr_level / 100;
- buffer[2] = (unsigned char)(distortion & 0xFF); /* Average distortion Threshold (inter) */
- buffer[3] = (unsigned char)(distortion & 0xFF); /* Average distortion Threshold (intra) */
- distortion = 1 + 42 * usbvision->compr_level / 100;
- buffer[4] = (unsigned char)(distortion & 0xFF); /* Maximum distortion Threshold (inter) */
- buffer[5] = (unsigned char)(distortion & 0xFF); /* Maximum distortion Threshold (intra) */
- } else { /* BRIDGE_NT1003 */
- buffer[0] = (unsigned char)(4 + 16 * usbvision->compr_level / 100); /* PCM threshold 1 */
- buffer[1] = (unsigned char)(4 + 8 * usbvision->compr_level / 100); /* PCM threshold 2 */
- distortion = 2 + 253 * usbvision->compr_level / 100;
- buffer[2] = (unsigned char)(distortion & 0xFF); /* distortion threshold bit0-7 */
- buffer[3] = 0; /* (unsigned char)((distortion >> 8) & 0x0F); distortion threshold bit 8-11 */
- distortion = 0 + 43 * usbvision->compr_level / 100;
- buffer[4] = (unsigned char)(distortion & 0xFF); /* maximum distortion bit0-7 */
- buffer[5] = 0; /* (unsigned char)((distortion >> 8) & 0x01); maximum distortion bit 8 */
- }
- err_code = usbvision_write_reg_irq(usbvision, USBVISION_PCM_THR1, buffer, 6);
- if (err_code == 0) {
- PDEBUG(DBG_IRQ, "new compr params %#02x %#02x %#02x %#02x %#02x %#02x", buffer[0],
- buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
- usbvision->last_compr_level = usbvision->compr_level;
- }
- }
- }
- return err_code;
-}
-
-static int usbvision_request_intra(struct usb_usbvision *usbvision)
-{
- int err_code = 0;
- unsigned char buffer[1];
-
- PDEBUG(DBG_IRQ, "");
- usbvision->request_intra = 1;
- buffer[0] = 1;
- usbvision_write_reg_irq(usbvision, USBVISION_FORCE_INTRA, buffer, 1);
- return err_code;
-}
-
-static int usbvision_unrequest_intra(struct usb_usbvision *usbvision)
-{
- int err_code = 0;
- unsigned char buffer[1];
-
- PDEBUG(DBG_IRQ, "");
- usbvision->request_intra = 0;
- buffer[0] = 0;
- usbvision_write_reg_irq(usbvision, USBVISION_FORCE_INTRA, buffer, 1);
- return err_code;
-}
-
-/*******************************
- * usbvision utility functions
- *******************************/
-
-int usbvision_power_off(struct usb_usbvision *usbvision)
-{
- int err_code = 0;
-
- PDEBUG(DBG_FUNC, "");
-
- err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN);
- if (err_code == 1)
- usbvision->power = 0;
- PDEBUG(DBG_FUNC, "%s: err_code %d", (err_code != 1) ? "ERROR" : "power is off", err_code);
- return err_code;
-}
-
-/* configure webcam image sensor using the serial port */
-static int usbvision_init_webcam(struct usb_usbvision *usbvision)
-{
- int rc;
- int i;
- static char init_values[38][3] = {
- { 0x04, 0x12, 0x08 }, { 0x05, 0xff, 0xc8 }, { 0x06, 0x18, 0x07 }, { 0x07, 0x90, 0x00 },
- { 0x09, 0x00, 0x00 }, { 0x0a, 0x00, 0x00 }, { 0x0b, 0x08, 0x00 }, { 0x0d, 0xcc, 0xcc },
- { 0x0e, 0x13, 0x14 }, { 0x10, 0x9b, 0x83 }, { 0x11, 0x5a, 0x3f }, { 0x12, 0xe4, 0x73 },
- { 0x13, 0x88, 0x84 }, { 0x14, 0x89, 0x80 }, { 0x15, 0x00, 0x20 }, { 0x16, 0x00, 0x00 },
- { 0x17, 0xff, 0xa0 }, { 0x18, 0x6b, 0x20 }, { 0x19, 0x22, 0x40 }, { 0x1a, 0x10, 0x07 },
- { 0x1b, 0x00, 0x47 }, { 0x1c, 0x03, 0xe0 }, { 0x1d, 0x00, 0x00 }, { 0x1e, 0x00, 0x00 },
- { 0x1f, 0x00, 0x00 }, { 0x20, 0x00, 0x00 }, { 0x21, 0x00, 0x00 }, { 0x22, 0x00, 0x00 },
- { 0x23, 0x00, 0x00 }, { 0x24, 0x00, 0x00 }, { 0x25, 0x00, 0x00 }, { 0x26, 0x00, 0x00 },
- { 0x27, 0x00, 0x00 }, { 0x28, 0x00, 0x00 }, { 0x29, 0x00, 0x00 }, { 0x08, 0x80, 0x60 },
- { 0x0f, 0x2d, 0x24 }, { 0x0c, 0x80, 0x80 }
- };
- char value[3];
-
- /* the only difference between PAL and NTSC init_values */
- if (usbvision_device_data[usbvision->dev_model].video_norm == V4L2_STD_NTSC)
- init_values[4][1] = 0x34;
-
- for (i = 0; i < sizeof(init_values) / 3; i++) {
- usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT);
- memcpy(value, init_values[i], 3);
- rc = usb_control_msg(usbvision->dev,
- usb_sndctrlpipe(usbvision->dev, 1),
- USBVISION_OP_CODE,
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_ENDPOINT, 0,
- (__u16) USBVISION_SER_DAT1, value,
- 3, HZ);
- if (rc < 0)
- return rc;
- usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SIO);
- /* write 3 bytes to the serial port using SIO mode */
- usbvision_write_reg(usbvision, USBVISION_SER_CONT, 3 | 0x10);
- usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, 0);
- usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT);
- usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, USBVISION_IO_2);
- usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_CLK_OUT);
- usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_DAT_IO);
- usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_CLK_OUT | USBVISION_DAT_IO);
- }
-
- return 0;
-}
-
-/*
- * usbvision_set_video_format()
- *
- */
-static int usbvision_set_video_format(struct usb_usbvision *usbvision, int format)
-{
- static const char proc[] = "usbvision_set_video_format";
- int rc;
- unsigned char value[2];
-
- if (!USBVISION_IS_OPERATIONAL(usbvision))
- return 0;
-
- PDEBUG(DBG_FUNC, "isoc_mode %#02x", format);
-
- if ((format != ISOC_MODE_YUV422)
- && (format != ISOC_MODE_YUV420)
- && (format != ISOC_MODE_COMPRESS)) {
- printk(KERN_ERR "usbvision: unknown video format %02x, using default YUV420",
- format);
- format = ISOC_MODE_YUV420;
- }
- value[0] = 0x0A; /* TODO: See the effect of the filter */
- value[1] = format; /* Sets the VO_MODE register which follows FILT_CONT */
- rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
- USBVISION_OP_CODE,
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_ENDPOINT, 0,
- (__u16) USBVISION_FILT_CONT, value, 2, HZ);
-
- if (rc < 0) {
- printk(KERN_ERR "%s: ERROR=%d. USBVISION stopped - "
- "reconnect or reload driver.\n", proc, rc);
- }
- usbvision->isoc_mode = format;
- return rc;
-}
-
-/*
- * usbvision_set_output()
- *
- */
-
-int usbvision_set_output(struct usb_usbvision *usbvision, int width,
- int height)
-{
- int err_code = 0;
- int usb_width, usb_height;
- unsigned int frame_rate = 0, frame_drop = 0;
- unsigned char value[4];
-
- if (!USBVISION_IS_OPERATIONAL(usbvision))
- return 0;
-
- if (width > MAX_USB_WIDTH) {
- usb_width = width / 2;
- usbvision->stretch_width = 2;
- } else {
- usb_width = width;
- usbvision->stretch_width = 1;
- }
-
- if (height > MAX_USB_HEIGHT) {
- usb_height = height / 2;
- usbvision->stretch_height = 2;
- } else {
- usb_height = height;
- usbvision->stretch_height = 1;
- }
-
- RESTRICT_TO_RANGE(usb_width, MIN_FRAME_WIDTH, MAX_USB_WIDTH);
- usb_width &= ~(MIN_FRAME_WIDTH-1);
- RESTRICT_TO_RANGE(usb_height, MIN_FRAME_HEIGHT, MAX_USB_HEIGHT);
- usb_height &= ~(1);
-
- PDEBUG(DBG_FUNC, "usb %dx%d; screen %dx%d; stretch %dx%d",
- usb_width, usb_height, width, height,
- usbvision->stretch_width, usbvision->stretch_height);
-
- /* I'll not rewrite the same values */
- if ((usb_width != usbvision->curwidth) || (usb_height != usbvision->curheight)) {
- value[0] = usb_width & 0xff; /* LSB */
- value[1] = (usb_width >> 8) & 0x03; /* MSB */
- value[2] = usb_height & 0xff; /* LSB */
- value[3] = (usb_height >> 8) & 0x03; /* MSB */
-
- err_code = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
- USBVISION_OP_CODE,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
- 0, (__u16) USBVISION_LXSIZE_O, value, 4, HZ);
-
- if (err_code < 0) {
- dev_err(&usbvision->dev->dev,
- "%s failed: error %d\n", __func__, err_code);
- return err_code;
- }
- usbvision->curwidth = usbvision->stretch_width * usb_width;
- usbvision->curheight = usbvision->stretch_height * usb_height;
- }
-
- if (usbvision->isoc_mode == ISOC_MODE_YUV422)
- frame_rate = (usbvision->isoc_packet_size * 1000) / (usb_width * usb_height * 2);
- else if (usbvision->isoc_mode == ISOC_MODE_YUV420)
- frame_rate = (usbvision->isoc_packet_size * 1000) / ((usb_width * usb_height * 12) / 8);
- else
- frame_rate = FRAMERATE_MAX;
-
- if (usbvision->tvnorm_id & V4L2_STD_625_50)
- frame_drop = frame_rate * 32 / 25 - 1;
- else if (usbvision->tvnorm_id & V4L2_STD_525_60)
- frame_drop = frame_rate * 32 / 30 - 1;
-
- RESTRICT_TO_RANGE(frame_drop, FRAMERATE_MIN, FRAMERATE_MAX);
-
- PDEBUG(DBG_FUNC, "frame_rate %d fps, frame_drop %d", frame_rate, frame_drop);
-
- frame_drop = FRAMERATE_MAX; /* We can allow the maximum here, because dropping is controlled */
-
- if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
- if (usbvision_device_data[usbvision->dev_model].video_norm == V4L2_STD_PAL)
- frame_drop = 25;
- else
- frame_drop = 30;
- }
-
- /* frame_drop = 7; => frame_phase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ...
- => frame_skip = 4;
- => frame_rate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25;
-
- frame_drop = 9; => frame_phase = 1, 5, 8, 11, 14, 17, 21, 24, 27, 1, 4, 8, ...
- => frame_skip = 4, 3, 3, 3, 3, 4, 3, 3, 3, 3, 4, ...
- => frame_rate = (9 + 1) * 25 / 32 = 250 / 32 = 7.8125;
- */
- err_code = usbvision_write_reg(usbvision, USBVISION_FRM_RATE, frame_drop);
- return err_code;
-}
-
-
-/*
- * usbvision_frames_alloc
- * allocate the required frames
- */
-int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames)
-{
- int i;
-
- /* needs to be page aligned cause the buffers can be mapped individually! */
- usbvision->max_frame_size = PAGE_ALIGN(usbvision->curwidth *
- usbvision->curheight *
- usbvision->palette.bytes_per_pixel);
-
- /* Try to do my best to allocate the frames the user want in the remaining memory */
- usbvision->num_frames = number_of_frames;
- while (usbvision->num_frames > 0) {
- usbvision->fbuf_size = usbvision->num_frames * usbvision->max_frame_size;
- usbvision->fbuf = usbvision_rvmalloc(usbvision->fbuf_size);
- if (usbvision->fbuf)
- break;
- usbvision->num_frames--;
- }
-
- spin_lock_init(&usbvision->queue_lock);
- init_waitqueue_head(&usbvision->wait_frame);
- init_waitqueue_head(&usbvision->wait_stream);
-
- /* Allocate all buffers */
- for (i = 0; i < usbvision->num_frames; i++) {
- usbvision->frame[i].index = i;
- usbvision->frame[i].grabstate = frame_state_unused;
- usbvision->frame[i].data = usbvision->fbuf +
- i * usbvision->max_frame_size;
- /*
- * Set default sizes for read operation.
- */
- usbvision->stretch_width = 1;
- usbvision->stretch_height = 1;
- usbvision->frame[i].width = usbvision->curwidth;
- usbvision->frame[i].height = usbvision->curheight;
- usbvision->frame[i].bytes_read = 0;
- }
- PDEBUG(DBG_FUNC, "allocated %d frames (%d bytes per frame)",
- usbvision->num_frames, usbvision->max_frame_size);
- return usbvision->num_frames;
-}
-
-/*
- * usbvision_frames_free
- * frees memory allocated for the frames
- */
-void usbvision_frames_free(struct usb_usbvision *usbvision)
-{
- /* Have to free all that memory */
- PDEBUG(DBG_FUNC, "free %d frames", usbvision->num_frames);
-
- if (usbvision->fbuf != NULL) {
- usbvision_rvfree(usbvision->fbuf, usbvision->fbuf_size);
- usbvision->fbuf = NULL;
-
- usbvision->num_frames = 0;
- }
-}
-/*
- * usbvision_empty_framequeues()
- * prepare queues for incoming and outgoing frames
- */
-void usbvision_empty_framequeues(struct usb_usbvision *usbvision)
-{
- u32 i;
-
- INIT_LIST_HEAD(&(usbvision->inqueue));
- INIT_LIST_HEAD(&(usbvision->outqueue));
-
- for (i = 0; i < USBVISION_NUMFRAMES; i++) {
- usbvision->frame[i].grabstate = frame_state_unused;
- usbvision->frame[i].bytes_read = 0;
- }
-}
-
-/*
- * usbvision_stream_interrupt()
- * stops streaming
- */
-int usbvision_stream_interrupt(struct usb_usbvision *usbvision)
-{
- int ret = 0;
-
- /* stop reading from the device */
-
- usbvision->streaming = stream_interrupt;
- ret = wait_event_timeout(usbvision->wait_stream,
- (usbvision->streaming == stream_idle),
- msecs_to_jiffies(USBVISION_NUMSBUF*USBVISION_URB_FRAMES));
- return ret;
-}
-
-/*
- * usbvision_set_compress_params()
- *
- */
-
-static int usbvision_set_compress_params(struct usb_usbvision *usbvision)
-{
- static const char proc[] = "usbvision_set_compresion_params: ";
- int rc;
- unsigned char value[6];
-
- value[0] = 0x0F; /* Intra-Compression cycle */
- value[1] = 0x01; /* Reg.45 one line per strip */
- value[2] = 0x00; /* Reg.46 Force intra mode on all new frames */
- value[3] = 0x00; /* Reg.47 FORCE_UP <- 0 normal operation (not force) */
- value[4] = 0xA2; /* Reg.48 BUF_THR I'm not sure if this does something in not compressed mode. */
- value[5] = 0x00; /* Reg.49 DVI_YUV This has nothing to do with compression */
-
- /* catched values for NT1004 */
- /* value[0] = 0xFF; Never apply intra mode automatically */
- /* value[1] = 0xF1; Use full frame height for virtual strip width; One line per strip */
- /* value[2] = 0x01; Force intra mode on all new frames */
- /* value[3] = 0x00; Strip size 400 Bytes; do not force up */
- /* value[4] = 0xA2; */
- if (!USBVISION_IS_OPERATIONAL(usbvision))
- return 0;
-
- rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
- USBVISION_OP_CODE,
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_ENDPOINT, 0,
- (__u16) USBVISION_INTRA_CYC, value, 5, HZ);
-
- if (rc < 0) {
- printk(KERN_ERR "%sERROR=%d. USBVISION stopped - "
- "reconnect or reload driver.\n", proc, rc);
- return rc;
- }
-
- if (usbvision->bridge_type == BRIDGE_NT1004) {
- value[0] = 20; /* PCM Threshold 1 */
- value[1] = 12; /* PCM Threshold 2 */
- value[2] = 255; /* Distortion Threshold inter */
- value[3] = 255; /* Distortion Threshold intra */
- value[4] = 43; /* Max Distortion inter */
- value[5] = 43; /* Max Distortion intra */
- } else {
- value[0] = 20; /* PCM Threshold 1 */
- value[1] = 12; /* PCM Threshold 2 */
- value[2] = 255; /* Distortion Threshold d7-d0 */
- value[3] = 0; /* Distortion Threshold d11-d8 */
- value[4] = 43; /* Max Distortion d7-d0 */
- value[5] = 0; /* Max Distortion d8 */
- }
-
- if (!USBVISION_IS_OPERATIONAL(usbvision))
- return 0;
-
- rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
- USBVISION_OP_CODE,
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_ENDPOINT, 0,
- (__u16) USBVISION_PCM_THR1, value, 6, HZ);
-
- if (rc < 0) {
- printk(KERN_ERR "%sERROR=%d. USBVISION stopped - "
- "reconnect or reload driver.\n", proc, rc);
- }
- return rc;
-}
-
-
-/*
- * usbvision_set_input()
- *
- * Set the input (saa711x, ...) size x y and other misc input params
- * I've no idea if this parameters are right
- *
- */
-int usbvision_set_input(struct usb_usbvision *usbvision)
-{
- static const char proc[] = "usbvision_set_input: ";
- int rc;
- unsigned char value[8];
- unsigned char dvi_yuv_value;
-
- if (!USBVISION_IS_OPERATIONAL(usbvision))
- return 0;
-
- /* Set input format expected from decoder*/
- if (usbvision_device_data[usbvision->dev_model].vin_reg1_override) {
- value[0] = usbvision_device_data[usbvision->dev_model].vin_reg1;
- } else if (usbvision_device_data[usbvision->dev_model].codec == CODEC_SAA7113) {
- /* SAA7113 uses 8 bit output */
- value[0] = USBVISION_8_422_SYNC;
- } else {
- /* I'm sure only about d2-d0 [010] 16 bit 4:2:2 usin sync pulses
- * as that is how saa7111 is configured */
- value[0] = USBVISION_16_422_SYNC;
- /* | USBVISION_VSNC_POL | USBVISION_VCLK_POL);*/
- }
-
- rc = usbvision_write_reg(usbvision, USBVISION_VIN_REG1, value[0]);
- if (rc < 0) {
- printk(KERN_ERR "%sERROR=%d. USBVISION stopped - "
- "reconnect or reload driver.\n", proc, rc);
- return rc;
- }
-
-
- if (usbvision->tvnorm_id & V4L2_STD_PAL) {
- value[0] = 0xC0;
- value[1] = 0x02; /* 0x02C0 -> 704 Input video line length */
- value[2] = 0x20;
- value[3] = 0x01; /* 0x0120 -> 288 Input video n. of lines */
- value[4] = 0x60;
- value[5] = 0x00; /* 0x0060 -> 96 Input video h offset */
- value[6] = 0x16;
- value[7] = 0x00; /* 0x0016 -> 22 Input video v offset */
- } else if (usbvision->tvnorm_id & V4L2_STD_SECAM) {
- value[0] = 0xC0;
- value[1] = 0x02; /* 0x02C0 -> 704 Input video line length */
- value[2] = 0x20;
- value[3] = 0x01; /* 0x0120 -> 288 Input video n. of lines */
- value[4] = 0x01;
- value[5] = 0x00; /* 0x0001 -> 01 Input video h offset */
- value[6] = 0x01;
- value[7] = 0x00; /* 0x0001 -> 01 Input video v offset */
- } else { /* V4L2_STD_NTSC */
- value[0] = 0xD0;
- value[1] = 0x02; /* 0x02D0 -> 720 Input video line length */
- value[2] = 0xF0;
- value[3] = 0x00; /* 0x00F0 -> 240 Input video number of lines */
- value[4] = 0x50;
- value[5] = 0x00; /* 0x0050 -> 80 Input video h offset */
- value[6] = 0x10;
- value[7] = 0x00; /* 0x0010 -> 16 Input video v offset */
- }
-
- /* webcam is only 480 pixels wide, both PAL and NTSC version */
- if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
- value[0] = 0xe0;
- value[1] = 0x01; /* 0x01E0 -> 480 Input video line length */
- }
-
- if (usbvision_device_data[usbvision->dev_model].x_offset >= 0) {
- value[4] = usbvision_device_data[usbvision->dev_model].x_offset & 0xff;
- value[5] = (usbvision_device_data[usbvision->dev_model].x_offset & 0x0300) >> 8;
- }
-
- if (adjust_x_offset != -1) {
- value[4] = adjust_x_offset & 0xff;
- value[5] = (adjust_x_offset & 0x0300) >> 8;
- }
-
- if (usbvision_device_data[usbvision->dev_model].y_offset >= 0) {
- value[6] = usbvision_device_data[usbvision->dev_model].y_offset & 0xff;
- value[7] = (usbvision_device_data[usbvision->dev_model].y_offset & 0x0300) >> 8;
- }
-
- if (adjust_y_offset != -1) {
- value[6] = adjust_y_offset & 0xff;
- value[7] = (adjust_y_offset & 0x0300) >> 8;
- }
-
- rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
- USBVISION_OP_CODE, /* USBVISION specific code */
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0,
- (__u16) USBVISION_LXSIZE_I, value, 8, HZ);
- if (rc < 0) {
- printk(KERN_ERR "%sERROR=%d. USBVISION stopped - "
- "reconnect or reload driver.\n", proc, rc);
- return rc;
- }
-
-
- dvi_yuv_value = 0x00; /* U comes after V, Ya comes after U/V, Yb comes after Yb */
-
- if (usbvision_device_data[usbvision->dev_model].dvi_yuv_override) {
- dvi_yuv_value = usbvision_device_data[usbvision->dev_model].dvi_yuv;
- } else if (usbvision_device_data[usbvision->dev_model].codec == CODEC_SAA7113) {
- /* This changes as the fine sync control changes. Further investigation necessary */
- dvi_yuv_value = 0x06;
- }
-
- return usbvision_write_reg(usbvision, USBVISION_DVI_YUV, dvi_yuv_value);
-}
-
-
-/*
- * usbvision_set_dram_settings()
- *
- * Set the buffer address needed by the usbvision dram to operate
- * This values has been taken with usbsnoop.
- *
- */
-
-static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
-{
- int rc;
- unsigned char value[8];
-
- if (usbvision->isoc_mode == ISOC_MODE_COMPRESS) {
- value[0] = 0x42;
- value[1] = 0x71;
- value[2] = 0xff;
- value[3] = 0x00;
- value[4] = 0x98;
- value[5] = 0xe0;
- value[6] = 0x71;
- value[7] = 0xff;
- /* UR: 0x0E200-0x3FFFF = 204288 Words (1 Word = 2 Byte) */
- /* FDL: 0x00000-0x0E099 = 57498 Words */
- /* VDW: 0x0E3FF-0x3FFFF */
- } else {
- value[0] = 0x42;
- value[1] = 0x00;
- value[2] = 0xff;
- value[3] = 0x00;
- value[4] = 0x00;
- value[5] = 0x00;
- value[6] = 0x00;
- value[7] = 0xff;
- }
- /* These are the values of the address of the video buffer,
- * they have to be loaded into the USBVISION_DRM_PRM1-8
- *
- * Start address of video output buffer for read: drm_prm1-2 -> 0x00000
- * End address of video output buffer for read: drm_prm1-3 -> 0x1ffff
- * Start address of video frame delay buffer: drm_prm1-4 -> 0x20000
- * Only used in compressed mode
- * End address of video frame delay buffer: drm_prm1-5-6 -> 0x3ffff
- * Only used in compressed mode
- * Start address of video output buffer for write: drm_prm1-7 -> 0x00000
- * End address of video output buffer for write: drm_prm1-8 -> 0x1ffff
- */
-
- if (!USBVISION_IS_OPERATIONAL(usbvision))
- return 0;
-
- rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
- USBVISION_OP_CODE, /* USBVISION specific code */
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_ENDPOINT, 0,
- (__u16) USBVISION_DRM_PRM1, value, 8, HZ);
-
- if (rc < 0) {
- dev_err(&usbvision->dev->dev, "%s: ERROR=%d\n", __func__, rc);
- return rc;
- }
-
- /* Restart the video buffer logic */
- rc = usbvision_write_reg(usbvision, USBVISION_DRM_CONT, USBVISION_RES_UR |
- USBVISION_RES_FDL | USBVISION_RES_VDW);
- if (rc < 0)
- return rc;
- rc = usbvision_write_reg(usbvision, USBVISION_DRM_CONT, 0x00);
-
- return rc;
-}
-
-/*
- * ()
- *
- * Power on the device, enables suspend-resume logic
- * & reset the isoc End-Point
- *
- */
-
-int usbvision_power_on(struct usb_usbvision *usbvision)
-{
- int err_code = 0;
-
- PDEBUG(DBG_FUNC, "");
-
- usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN);
- usbvision_write_reg(usbvision, USBVISION_PWR_REG,
- USBVISION_SSPND_EN | USBVISION_RES2);
-
- if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
- usbvision_write_reg(usbvision, USBVISION_VIN_REG1,
- USBVISION_16_422_SYNC | USBVISION_HVALID_PO);
- usbvision_write_reg(usbvision, USBVISION_VIN_REG2,
- USBVISION_NOHVALID | USBVISION_KEEP_BLANK);
- }
- usbvision_write_reg(usbvision, USBVISION_PWR_REG,
- USBVISION_SSPND_EN | USBVISION_PWR_VID);
- mdelay(10);
- err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
- USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2);
- if (err_code == 1)
- usbvision->power = 1;
- PDEBUG(DBG_FUNC, "%s: err_code %d", (err_code < 0) ? "ERROR" : "power is on", err_code);
- return err_code;
-}
-
-
-/*
- * usbvision timer stuff
- */
-
-/* to call usbvision_power_off from task queue */
-static void call_usbvision_power_off(struct work_struct *work)
-{
- struct usb_usbvision *usbvision = container_of(work, struct usb_usbvision, power_off_work);
-
- PDEBUG(DBG_FUNC, "");
- if (mutex_lock_interruptible(&usbvision->v4l2_lock))
- return;
-
- if (usbvision->user == 0) {
- usbvision_i2c_unregister(usbvision);
-
- usbvision_power_off(usbvision);
- usbvision->initialized = 0;
- }
- mutex_unlock(&usbvision->v4l2_lock);
-}
-
-static void usbvision_power_off_timer(unsigned long data)
-{
- struct usb_usbvision *usbvision = (void *)data;
-
- PDEBUG(DBG_FUNC, "");
- del_timer(&usbvision->power_off_timer);
- INIT_WORK(&usbvision->power_off_work, call_usbvision_power_off);
- (void) schedule_work(&usbvision->power_off_work);
-}
-
-void usbvision_init_power_off_timer(struct usb_usbvision *usbvision)
-{
- init_timer(&usbvision->power_off_timer);
- usbvision->power_off_timer.data = (long)usbvision;
- usbvision->power_off_timer.function = usbvision_power_off_timer;
-}
-
-void usbvision_set_power_off_timer(struct usb_usbvision *usbvision)
-{
- mod_timer(&usbvision->power_off_timer, jiffies + USBVISION_POWEROFF_TIME);
-}
-
-void usbvision_reset_power_off_timer(struct usb_usbvision *usbvision)
-{
- if (timer_pending(&usbvision->power_off_timer))
- del_timer(&usbvision->power_off_timer);
-}
-
-/*
- * usbvision_begin_streaming()
- * Sure you have to put bit 7 to 0, if not incoming frames are droped, but no
- * idea about the rest
- */
-int usbvision_begin_streaming(struct usb_usbvision *usbvision)
-{
- if (usbvision->isoc_mode == ISOC_MODE_COMPRESS)
- usbvision_init_compression(usbvision);
- return usbvision_write_reg(usbvision, USBVISION_VIN_REG2,
- USBVISION_NOHVALID | usbvision->vin_reg2_preset);
-}
-
-/*
- * usbvision_restart_isoc()
- * Not sure yet if touching here PWR_REG make loose the config
- */
-
-int usbvision_restart_isoc(struct usb_usbvision *usbvision)
-{
- int ret;
-
- ret = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
- USBVISION_SSPND_EN | USBVISION_PWR_VID);
- if (ret < 0)
- return ret;
- ret = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
- USBVISION_SSPND_EN | USBVISION_PWR_VID |
- USBVISION_RES2);
- if (ret < 0)
- return ret;
- ret = usbvision_write_reg(usbvision, USBVISION_VIN_REG2,
- USBVISION_KEEP_BLANK | USBVISION_NOHVALID |
- usbvision->vin_reg2_preset);
- if (ret < 0)
- return ret;
-
- /* TODO: schedule timeout */
- while ((usbvision_read_reg(usbvision, USBVISION_STATUS_REG) & 0x01) != 1)
- ;
-
- return 0;
-}
-
-int usbvision_audio_off(struct usb_usbvision *usbvision)
-{
- if (usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, USBVISION_AUDIO_MUTE) < 0) {
- printk(KERN_ERR "usbvision_audio_off: can't write reg\n");
- return -1;
- }
- usbvision->audio_mute = 0;
- usbvision->audio_channel = USBVISION_AUDIO_MUTE;
- return 0;
-}
-
-int usbvision_set_audio(struct usb_usbvision *usbvision, int audio_channel)
-{
- if (!usbvision->audio_mute) {
- if (usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, audio_channel) < 0) {
- printk(KERN_ERR "usbvision_set_audio: can't write iopin register for audio switching\n");
- return -1;
- }
- }
- usbvision->audio_channel = audio_channel;
- return 0;
-}
-
-int usbvision_setup(struct usb_usbvision *usbvision, int format)
-{
- if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM)
- usbvision_init_webcam(usbvision);
- usbvision_set_video_format(usbvision, format);
- usbvision_set_dram_settings(usbvision);
- usbvision_set_compress_params(usbvision);
- usbvision_set_input(usbvision);
- usbvision_set_output(usbvision, MAX_USB_WIDTH, MAX_USB_HEIGHT);
- usbvision_restart_isoc(usbvision);
-
- /* cosas del PCM */
- return USBVISION_IS_OPERATIONAL(usbvision);
-}
-
-int usbvision_set_alternate(struct usb_usbvision *dev)
-{
- int err_code, prev_alt = dev->iface_alt;
- int i;
-
- dev->iface_alt = 0;
- for (i = 0; i < dev->num_alt; i++)
- if (dev->alt_max_pkt_size[i] > dev->alt_max_pkt_size[dev->iface_alt])
- dev->iface_alt = i;
-
- if (dev->iface_alt != prev_alt) {
- dev->isoc_packet_size = dev->alt_max_pkt_size[dev->iface_alt];
- PDEBUG(DBG_FUNC, "setting alternate %d with max_packet_size=%u",
- dev->iface_alt, dev->isoc_packet_size);
- err_code = usb_set_interface(dev->dev, dev->iface, dev->iface_alt);
- if (err_code < 0) {
- dev_err(&dev->dev->dev,
- "cannot change alternate number to %d (error=%i)\n",
- dev->iface_alt, err_code);
- return err_code;
- }
- }
-
- PDEBUG(DBG_ISOC, "ISO Packet Length:%d", dev->isoc_packet_size);
-
- return 0;
-}
-
-/*
- * usbvision_init_isoc()
- *
- */
-int usbvision_init_isoc(struct usb_usbvision *usbvision)
-{
- struct usb_device *dev = usbvision->dev;
- int buf_idx, err_code, reg_value;
- int sb_size;
-
- if (!USBVISION_IS_OPERATIONAL(usbvision))
- return -EFAULT;
-
- usbvision->cur_frame = NULL;
- scratch_reset(usbvision);
-
- /* Alternate interface 1 is is the biggest frame size */
- err_code = usbvision_set_alternate(usbvision);
- if (err_code < 0) {
- usbvision->last_error = err_code;
- return -EBUSY;
- }
- sb_size = USBVISION_URB_FRAMES * usbvision->isoc_packet_size;
-
- reg_value = (16 - usbvision_read_reg(usbvision,
- USBVISION_ALTER_REG)) & 0x0F;
-
- usbvision->usb_bandwidth = reg_value >> 1;
- PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
- usbvision->usb_bandwidth);
-
-
-
- /* We double buffer the Iso lists */
-
- for (buf_idx = 0; buf_idx < USBVISION_NUMSBUF; buf_idx++) {
- int j, k;
- struct urb *urb;
-
- urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
- if (urb == NULL) {
- dev_err(&usbvision->dev->dev,
- "%s: usb_alloc_urb() failed\n", __func__);
- return -ENOMEM;
- }
- usbvision->sbuf[buf_idx].urb = urb;
- usbvision->sbuf[buf_idx].data =
- usb_alloc_coherent(usbvision->dev,
- sb_size,
- GFP_KERNEL,
- &urb->transfer_dma);
- urb->dev = dev;
- urb->context = usbvision;
- urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
- urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
- urb->interval = 1;
- urb->transfer_buffer = usbvision->sbuf[buf_idx].data;
- urb->complete = usbvision_isoc_irq;
- urb->number_of_packets = USBVISION_URB_FRAMES;
- urb->transfer_buffer_length =
- usbvision->isoc_packet_size * USBVISION_URB_FRAMES;
- for (j = k = 0; j < USBVISION_URB_FRAMES; j++,
- k += usbvision->isoc_packet_size) {
- urb->iso_frame_desc[j].offset = k;
- urb->iso_frame_desc[j].length =
- usbvision->isoc_packet_size;
- }
- }
-
- /* Submit all URBs */
- for (buf_idx = 0; buf_idx < USBVISION_NUMSBUF; buf_idx++) {
- err_code = usb_submit_urb(usbvision->sbuf[buf_idx].urb,
- GFP_KERNEL);
- if (err_code) {
- dev_err(&usbvision->dev->dev,
- "%s: usb_submit_urb(%d) failed: error %d\n",
- __func__, buf_idx, err_code);
- }
- }
-
- usbvision->streaming = stream_idle;
- PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x",
- __func__,
- usbvision->video_endp);
- return 0;
-}
-
-/*
- * usbvision_stop_isoc()
- *
- * This procedure stops streaming and deallocates URBs. Then it
- * activates zero-bandwidth alt. setting of the video interface.
- *
- */
-void usbvision_stop_isoc(struct usb_usbvision *usbvision)
-{
- int buf_idx, err_code, reg_value;
- int sb_size = USBVISION_URB_FRAMES * usbvision->isoc_packet_size;
-
- if ((usbvision->streaming == stream_off) || (usbvision->dev == NULL))
- return;
-
- /* Unschedule all of the iso td's */
- for (buf_idx = 0; buf_idx < USBVISION_NUMSBUF; buf_idx++) {
- usb_kill_urb(usbvision->sbuf[buf_idx].urb);
- if (usbvision->sbuf[buf_idx].data) {
- usb_free_coherent(usbvision->dev,
- sb_size,
- usbvision->sbuf[buf_idx].data,
- usbvision->sbuf[buf_idx].urb->transfer_dma);
- }
- usb_free_urb(usbvision->sbuf[buf_idx].urb);
- usbvision->sbuf[buf_idx].urb = NULL;
- }
-
- PDEBUG(DBG_ISOC, "%s: streaming=stream_off\n", __func__);
- usbvision->streaming = stream_off;
-
- if (!usbvision->remove_pending) {
- /* Set packet size to 0 */
- usbvision->iface_alt = 0;
- err_code = usb_set_interface(usbvision->dev, usbvision->iface,
- usbvision->iface_alt);
- if (err_code < 0) {
- dev_err(&usbvision->dev->dev,
- "%s: usb_set_interface() failed: error %d\n",
- __func__, err_code);
- usbvision->last_error = err_code;
- }
- reg_value = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
- usbvision->isoc_packet_size =
- (reg_value == 0) ? 0 : (reg_value * 64) - 1;
- PDEBUG(DBG_ISOC, "ISO Packet Length:%d",
- usbvision->isoc_packet_size);
-
- usbvision->usb_bandwidth = reg_value >> 1;
- PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
- usbvision->usb_bandwidth);
- }
-}
-
-int usbvision_muxsel(struct usb_usbvision *usbvision, int channel)
-{
- /* inputs #0 and #3 are constant for every SAA711x. */
- /* inputs #1 and #2 are variable for SAA7111 and SAA7113 */
- int mode[4] = { SAA7115_COMPOSITE0, 0, 0, SAA7115_COMPOSITE3 };
- int audio[] = { 1, 0, 0, 0 };
- /* channel 0 is TV with audiochannel 1 (tuner mono) */
- /* channel 1 is Composite with audio channel 0 (line in) */
- /* channel 2 is S-Video with audio channel 0 (line in) */
- /* channel 3 is additional video inputs to the device with audio channel 0 (line in) */
-
- RESTRICT_TO_RANGE(channel, 0, usbvision->video_inputs);
- usbvision->ctl_input = channel;
-
- /* set the new channel */
- /* Regular USB TV Tuners -> channel: 0 = Television, 1 = Composite, 2 = S-Video */
- /* Four video input devices -> channel: 0 = Chan White, 1 = Chan Green, 2 = Chan Yellow, 3 = Chan Red */
-
- switch (usbvision_device_data[usbvision->dev_model].codec) {
- case CODEC_SAA7113:
- mode[1] = SAA7115_COMPOSITE2;
- if (switch_svideo_input) {
- /* To handle problems with S-Video Input for
- * some devices. Use switch_svideo_input
- * parameter when loading the module.*/
- mode[2] = SAA7115_COMPOSITE1;
- } else {
- mode[2] = SAA7115_SVIDEO1;
- }
- break;
- case CODEC_SAA7111:
- default:
- /* modes for saa7111 */
- mode[1] = SAA7115_COMPOSITE1;
- mode[2] = SAA7115_SVIDEO1;
- break;
- }
- call_all(usbvision, video, s_routing, mode[channel], 0, 0);
- usbvision_set_audio(usbvision, audio[channel]);
- return 0;
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
deleted file mode 100644
index 89fec029e92..00000000000
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * usbvision_i2c.c
- * i2c algorithm for USB-I2C Bridges
- *
- * Copyright (c) 1999-2007 Joerg Heckenbach <joerg@heckenbach-aw.de>
- * Dwaine Garden <dwainegarden@rogers.com>
- *
- * This module is part of usbvision driver project.
- * Updates to driver completed by Dwaine P. Garden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/uaccess.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include "usbvision.h"
-
-#define DBG_I2C (1 << 0)
-
-static int i2c_debug;
-
-module_param(i2c_debug, int, 0644); /* debug_i2c_usb mode of the device driver */
-MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
-
-#define PDEBUG(level, fmt, args...) { \
- if (i2c_debug & (level)) \
- printk(KERN_INFO KBUILD_MODNAME ":[%s:%d] " fmt, \
- __func__, __LINE__ , ## args); \
- }
-
-static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
- short len);
-static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
- short len);
-
-static inline int try_write_address(struct i2c_adapter *i2c_adap,
- unsigned char addr, int retries)
-{
- struct usb_usbvision *usbvision;
- int i, ret = -1;
- char buf[4];
-
- usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
- buf[0] = 0x00;
- for (i = 0; i <= retries; i++) {
- ret = (usbvision_i2c_write(usbvision, addr, buf, 1));
- if (ret == 1)
- break; /* success! */
- udelay(5);
- if (i == retries) /* no success */
- break;
- udelay(10);
- }
- if (i) {
- PDEBUG(DBG_I2C, "Needed %d retries for address %#2x", i, addr);
- PDEBUG(DBG_I2C, "Maybe there's no device at this address");
- }
- return ret;
-}
-
-static inline int try_read_address(struct i2c_adapter *i2c_adap,
- unsigned char addr, int retries)
-{
- struct usb_usbvision *usbvision;
- int i, ret = -1;
- char buf[4];
-
- usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
- for (i = 0; i <= retries; i++) {
- ret = (usbvision_i2c_read(usbvision, addr, buf, 1));
- if (ret == 1)
- break; /* success! */
- udelay(5);
- if (i == retries) /* no success */
- break;
- udelay(10);
- }
- if (i) {
- PDEBUG(DBG_I2C, "Needed %d retries for address %#2x", i, addr);
- PDEBUG(DBG_I2C, "Maybe there's no device at this address");
- }
- return ret;
-}
-
-static inline int usb_find_address(struct i2c_adapter *i2c_adap,
- struct i2c_msg *msg, int retries,
- unsigned char *add)
-{
- unsigned short flags = msg->flags;
-
- unsigned char addr;
- int ret;
-
- addr = (msg->addr << 1);
- if (flags & I2C_M_RD)
- addr |= 1;
-
- add[0] = addr;
- if (flags & I2C_M_RD)
- ret = try_read_address(i2c_adap, addr, retries);
- else
- ret = try_write_address(i2c_adap, addr, retries);
-
- if (ret != 1)
- return -EREMOTEIO;
-
- return 0;
-}
-
-static int
-usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
-{
- struct i2c_msg *pmsg;
- struct usb_usbvision *usbvision;
- int i, ret;
- unsigned char addr = 0;
-
- usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
-
- for (i = 0; i < num; i++) {
- pmsg = &msgs[i];
- ret = usb_find_address(i2c_adap, pmsg, i2c_adap->retries, &addr);
- if (ret != 0) {
- PDEBUG(DBG_I2C, "got NAK from device, message #%d", i);
- return (ret < 0) ? ret : -EREMOTEIO;
- }
-
- if (pmsg->flags & I2C_M_RD) {
- /* read bytes into buffer */
- ret = (usbvision_i2c_read(usbvision, addr, pmsg->buf, pmsg->len));
- if (ret < pmsg->len)
- return (ret < 0) ? ret : -EREMOTEIO;
- } else {
- /* write bytes from buffer */
- ret = (usbvision_i2c_write(usbvision, addr, pmsg->buf, pmsg->len));
- if (ret < pmsg->len)
- return (ret < 0) ? ret : -EREMOTEIO;
- }
- }
- return num;
-}
-
-static u32 functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-/* -----exported algorithm data: ------------------------------------- */
-
-static struct i2c_algorithm usbvision_algo = {
- .master_xfer = usbvision_i2c_xfer,
- .smbus_xfer = NULL,
- .functionality = functionality,
-};
-
-
-/* ----------------------------------------------------------------------- */
-/* usbvision specific I2C functions */
-/* ----------------------------------------------------------------------- */
-static struct i2c_adapter i2c_adap_template;
-
-int usbvision_i2c_register(struct usb_usbvision *usbvision)
-{
- static unsigned short saa711x_addrs[] = {
- 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
- 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
- I2C_CLIENT_END };
-
- if (usbvision->registered_i2c)
- return 0;
-
- memcpy(&usbvision->i2c_adap, &i2c_adap_template,
- sizeof(struct i2c_adapter));
-
- sprintf(usbvision->i2c_adap.name, "%s-%d-%s", i2c_adap_template.name,
- usbvision->dev->bus->busnum, usbvision->dev->devpath);
- PDEBUG(DBG_I2C, "Adaptername: %s", usbvision->i2c_adap.name);
- usbvision->i2c_adap.dev.parent = &usbvision->dev->dev;
-
- i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev);
-
- if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
- printk(KERN_ERR "usbvision_i2c_register: can't write reg\n");
- return -EBUSY;
- }
-
- PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]");
- PDEBUG(DBG_I2C, "ALGO debugging is enabled [i2c]");
-
- /* register new adapter to i2c module... */
-
- usbvision->i2c_adap.algo = &usbvision_algo;
-
- usbvision->i2c_adap.timeout = 100; /* default values, should */
- usbvision->i2c_adap.retries = 3; /* be replaced by defines */
-
- i2c_add_adapter(&usbvision->i2c_adap);
-
- PDEBUG(DBG_I2C, "i2c bus for %s registered", usbvision->i2c_adap.name);
-
- /* Request the load of the i2c modules we need */
- switch (usbvision_device_data[usbvision->dev_model].codec) {
- case CODEC_SAA7113:
- case CODEC_SAA7111:
- /* Without this delay the detection of the saa711x is
- hit-and-miss. */
- mdelay(10);
- v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
- &usbvision->i2c_adap,
- "saa7115_auto", 0, saa711x_addrs);
- break;
- }
- if (usbvision_device_data[usbvision->dev_model].tuner == 1) {
- struct v4l2_subdev *sd;
- enum v4l2_i2c_tuner_type type;
- struct tuner_setup tun_setup;
-
- sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
- &usbvision->i2c_adap,
- "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
- /* depending on whether we found a demod or not, select
- the tuner type. */
- type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
-
- sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
- &usbvision->i2c_adap,
- "tuner", 0, v4l2_i2c_tuner_addrs(type));
-
- if (sd == NULL)
- return -ENODEV;
- if (usbvision->tuner_type != -1) {
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.type = usbvision->tuner_type;
- tun_setup.addr = v4l2_i2c_subdev_addr(sd);
- call_all(usbvision, tuner, s_type_addr, &tun_setup);
- }
- }
- usbvision->registered_i2c = 1;
-
- return 0;
-}
-
-int usbvision_i2c_unregister(struct usb_usbvision *usbvision)
-{
- if (!usbvision->registered_i2c)
- return 0;
-
- i2c_del_adapter(&(usbvision->i2c_adap));
- usbvision->registered_i2c = 0;
-
- PDEBUG(DBG_I2C, "i2c bus for %s unregistered", usbvision->i2c_adap.name);
-
- return 0;
-}
-
-static int
-usbvision_i2c_read_max4(struct usb_usbvision *usbvision, unsigned char addr,
- char *buf, short len)
-{
- int rc, retries;
-
- for (retries = 5;;) {
- rc = usbvision_write_reg(usbvision, USBVISION_SER_ADRS, addr);
- if (rc < 0)
- return rc;
-
- /* Initiate byte read cycle */
- /* USBVISION_SER_CONT <- d0-d2 n. of bytes to r/w */
- /* d3 0=Wr 1=Rd */
- rc = usbvision_write_reg(usbvision, USBVISION_SER_CONT,
- (len & 0x07) | 0x18);
- if (rc < 0)
- return rc;
-
- /* Test for Busy and ACK */
- do {
- /* USBVISION_SER_CONT -> d4 == 0 busy */
- rc = usbvision_read_reg(usbvision, USBVISION_SER_CONT);
- } while (rc > 0 && ((rc & 0x10) != 0)); /* Retry while busy */
- if (rc < 0)
- return rc;
-
- /* USBVISION_SER_CONT -> d5 == 1 Not ack */
- if ((rc & 0x20) == 0) /* Ack? */
- break;
-
- /* I2C abort */
- rc = usbvision_write_reg(usbvision, USBVISION_SER_CONT, 0x00);
- if (rc < 0)
- return rc;
-
- if (--retries < 0)
- return -1;
- }
-
- switch (len) {
- case 4:
- buf[3] = usbvision_read_reg(usbvision, USBVISION_SER_DAT4);
- case 3:
- buf[2] = usbvision_read_reg(usbvision, USBVISION_SER_DAT3);
- case 2:
- buf[1] = usbvision_read_reg(usbvision, USBVISION_SER_DAT2);
- case 1:
- buf[0] = usbvision_read_reg(usbvision, USBVISION_SER_DAT1);
- break;
- default:
- printk(KERN_ERR
- "usbvision_i2c_read_max4: buffer length > 4\n");
- }
-
- if (i2c_debug & DBG_I2C) {
- int idx;
-
- for (idx = 0; idx < len; idx++)
- PDEBUG(DBG_I2C, "read %x from address %x", (unsigned char)buf[idx], addr);
- }
- return len;
-}
-
-
-static int usbvision_i2c_write_max4(struct usb_usbvision *usbvision,
- unsigned char addr, const char *buf,
- short len)
-{
- int rc, retries;
- int i;
- unsigned char value[6];
- unsigned char ser_cont;
-
- ser_cont = (len & 0x07) | 0x10;
-
- value[0] = addr;
- value[1] = ser_cont;
- for (i = 0; i < len; i++)
- value[i + 2] = buf[i];
-
- for (retries = 5;;) {
- rc = usb_control_msg(usbvision->dev,
- usb_sndctrlpipe(usbvision->dev, 1),
- USBVISION_OP_CODE,
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_ENDPOINT, 0,
- (__u16) USBVISION_SER_ADRS, value,
- len + 2, HZ);
-
- if (rc < 0)
- return rc;
-
- rc = usbvision_write_reg(usbvision, USBVISION_SER_CONT,
- (len & 0x07) | 0x10);
- if (rc < 0)
- return rc;
-
- /* Test for Busy and ACK */
- do {
- rc = usbvision_read_reg(usbvision, USBVISION_SER_CONT);
- } while (rc > 0 && ((rc & 0x10) != 0)); /* Retry while busy */
- if (rc < 0)
- return rc;
-
- if ((rc & 0x20) == 0) /* Ack? */
- break;
-
- /* I2C abort */
- usbvision_write_reg(usbvision, USBVISION_SER_CONT, 0x00);
-
- if (--retries < 0)
- return -1;
-
- }
-
- if (i2c_debug & DBG_I2C) {
- int idx;
-
- for (idx = 0; idx < len; idx++)
- PDEBUG(DBG_I2C, "wrote %x at address %x", (unsigned char)buf[idx], addr);
- }
- return len;
-}
-
-static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
- short len)
-{
- char *buf_ptr = buf;
- int retval;
- int wrcount = 0;
- int count;
- int max_len = 4;
-
- while (len > 0) {
- count = (len > max_len) ? max_len : len;
- retval = usbvision_i2c_write_max4(usbvision, addr, buf_ptr, count);
- if (retval > 0) {
- len -= count;
- buf_ptr += count;
- wrcount += count;
- } else
- return (retval < 0) ? retval : -EFAULT;
- }
- return wrcount;
-}
-
-static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
- short len)
-{
- char temp[4];
- int retval, i;
- int rdcount = 0;
- int count;
-
- while (len > 0) {
- count = (len > 3) ? 4 : len;
- retval = usbvision_i2c_read_max4(usbvision, addr, temp, count);
- if (retval > 0) {
- for (i = 0; i < len; i++)
- buf[rdcount + i] = temp[i];
- len -= count;
- rdcount += count;
- } else
- return (retval < 0) ? retval : -EFAULT;
- }
- return rdcount;
-}
-
-static struct i2c_adapter i2c_adap_template = {
- .owner = THIS_MODULE,
- .name = "usbvision",
-};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
deleted file mode 100644
index 9bd8f084f34..00000000000
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ /dev/null
@@ -1,1690 +0,0 @@
-/*
- * USB USBVISION Video device driver 0.9.10
- *
- *
- *
- * Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de>
- *
- * This module is part of usbvision driver project.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Let's call the version 0.... until compression decoding is completely
- * implemented.
- *
- * This driver is written by Jose Ignacio Gijon and Joerg Heckenbach.
- * It was based on USB CPiA driver written by Peter Pregler,
- * Scott J. Bertin and Johannes Erdfelt
- * Ideas are taken from bttv driver by Ralph Metzler, Marcus Metzler &
- * Gerd Knorr and zoran 36120/36125 driver by Pauline Middelink
- * Updates to driver completed by Dwaine P. Garden
- *
- *
- * TODO:
- * - use submit_urb for all setup packets
- * - Fix memory settings for nt1004. It is 4 times as big as the
- * nt1003 memory.
- * - Add audio on endpoint 3 for nt1004 chip.
- * Seems impossible, needs a codec interface. Which one?
- * - Clean up the driver.
- * - optimization for performance.
- * - Add Videotext capability (VBI). Working on it.....
- * - Check audio for other devices
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/videodev2.h>
-#include <linux/i2c.h>
-
-#include <media/saa7115.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/tuner.h>
-
-#include <linux/workqueue.h>
-
-#include "usbvision.h"
-#include "usbvision-cards.h"
-
-#define DRIVER_AUTHOR \
- "Joerg Heckenbach <joerg@heckenbach-aw.de>, " \
- "Dwaine Garden <DwaineGarden@rogers.com>"
-#define DRIVER_NAME "usbvision"
-#define DRIVER_ALIAS "USBVision"
-#define DRIVER_DESC "USBVision USB Video Device Driver for Linux"
-#define DRIVER_LICENSE "GPL"
-#define USBVISION_VERSION_STRING "0.9.11"
-
-#define ENABLE_HEXDUMP 0 /* Enable if you need it */
-
-
-#ifdef USBVISION_DEBUG
- #define PDEBUG(level, fmt, args...) { \
- if (video_debug & (level)) \
- printk(KERN_INFO KBUILD_MODNAME ":[%s:%d] " fmt, \
- __func__, __LINE__ , ## args); \
- }
-#else
- #define PDEBUG(level, fmt, args...) do {} while (0)
-#endif
-
-#define DBG_IO (1 << 1)
-#define DBG_PROBE (1 << 2)
-#define DBG_MMAP (1 << 3)
-
-/* String operations */
-#define rmspace(str) while (*str == ' ') str++;
-#define goto2next(str) while (*str != ' ') str++; while (*str == ' ') str++;
-
-
-/* sequential number of usbvision device */
-static int usbvision_nr;
-
-static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = {
- { 1, 1, 8, V4L2_PIX_FMT_GREY , "GREY" },
- { 1, 2, 16, V4L2_PIX_FMT_RGB565 , "RGB565" },
- { 1, 3, 24, V4L2_PIX_FMT_RGB24 , "RGB24" },
- { 1, 4, 32, V4L2_PIX_FMT_RGB32 , "RGB32" },
- { 1, 2, 16, V4L2_PIX_FMT_RGB555 , "RGB555" },
- { 1, 2, 16, V4L2_PIX_FMT_YUYV , "YUV422" },
- { 1, 2, 12, V4L2_PIX_FMT_YVU420 , "YUV420P" }, /* 1.5 ! */
- { 1, 2, 16, V4L2_PIX_FMT_YUV422P , "YUV422P" }
-};
-
-/* Function prototypes */
-static void usbvision_release(struct usb_usbvision *usbvision);
-
-/* Default initialization of device driver parameters */
-/* Set the default format for ISOC endpoint */
-static int isoc_mode = ISOC_MODE_COMPRESS;
-/* Set the default Debug Mode of the device driver */
-static int video_debug;
-/* Set the default device to power on at startup */
-static int power_on_at_open = 1;
-/* Sequential Number of Video Device */
-static int video_nr = -1;
-/* Sequential Number of Radio Device */
-static int radio_nr = -1;
-
-/* Grab parameters for the device driver */
-
-/* Showing parameters under SYSFS */
-module_param(isoc_mode, int, 0444);
-module_param(video_debug, int, 0444);
-module_param(power_on_at_open, int, 0444);
-module_param(video_nr, int, 0444);
-module_param(radio_nr, int, 0444);
-
-MODULE_PARM_DESC(isoc_mode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)");
-MODULE_PARM_DESC(video_debug, " Set the default Debug Mode of the device driver. Default: 0 (Off)");
-MODULE_PARM_DESC(power_on_at_open, " Set the default device to power on when device is opened. Default: 1 (On)");
-MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX). Default: -1 (autodetect)");
-MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
-
-
-/* Misc stuff */
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
-MODULE_VERSION(USBVISION_VERSION_STRING);
-MODULE_ALIAS(DRIVER_ALIAS);
-
-
-/*****************************************************************************/
-/* SYSFS Code - Copied from the stv680.c usb module. */
-/* Device information is located at /sys/class/video4linux/video0 */
-/* Device parameters information is located at /sys/module/usbvision */
-/* Device USB Information is located at */
-/* /sys/bus/usb/drivers/USBVision Video Grabber */
-/*****************************************************************************/
-
-#define YES_NO(x) ((x) ? "Yes" : "No")
-
-static inline struct usb_usbvision *cd_to_usbvision(struct device *cd)
-{
- struct video_device *vdev =
- container_of(cd, struct video_device, dev);
- return video_get_drvdata(vdev);
-}
-
-static ssize_t show_version(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%s\n", USBVISION_VERSION_STRING);
-}
-static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
-
-static ssize_t show_model(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vdev =
- container_of(cd, struct video_device, dev);
- struct usb_usbvision *usbvision = video_get_drvdata(vdev);
- return sprintf(buf, "%s\n",
- usbvision_device_data[usbvision->dev_model].model_string);
-}
-static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
-
-static ssize_t show_hue(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vdev =
- container_of(cd, struct video_device, dev);
- struct usb_usbvision *usbvision = video_get_drvdata(vdev);
- struct v4l2_control ctrl;
- ctrl.id = V4L2_CID_HUE;
- ctrl.value = 0;
- if (usbvision->user)
- call_all(usbvision, core, g_ctrl, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value);
-}
-static DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
-
-static ssize_t show_contrast(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vdev =
- container_of(cd, struct video_device, dev);
- struct usb_usbvision *usbvision = video_get_drvdata(vdev);
- struct v4l2_control ctrl;
- ctrl.id = V4L2_CID_CONTRAST;
- ctrl.value = 0;
- if (usbvision->user)
- call_all(usbvision, core, g_ctrl, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value);
-}
-static DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
-
-static ssize_t show_brightness(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vdev =
- container_of(cd, struct video_device, dev);
- struct usb_usbvision *usbvision = video_get_drvdata(vdev);
- struct v4l2_control ctrl;
- ctrl.id = V4L2_CID_BRIGHTNESS;
- ctrl.value = 0;
- if (usbvision->user)
- call_all(usbvision, core, g_ctrl, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value);
-}
-static DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
-
-static ssize_t show_saturation(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vdev =
- container_of(cd, struct video_device, dev);
- struct usb_usbvision *usbvision = video_get_drvdata(vdev);
- struct v4l2_control ctrl;
- ctrl.id = V4L2_CID_SATURATION;
- ctrl.value = 0;
- if (usbvision->user)
- call_all(usbvision, core, g_ctrl, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value);
-}
-static DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
-
-static ssize_t show_streaming(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vdev =
- container_of(cd, struct video_device, dev);
- struct usb_usbvision *usbvision = video_get_drvdata(vdev);
- return sprintf(buf, "%s\n",
- YES_NO(usbvision->streaming == stream_on ? 1 : 0));
-}
-static DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL);
-
-static ssize_t show_compression(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vdev =
- container_of(cd, struct video_device, dev);
- struct usb_usbvision *usbvision = video_get_drvdata(vdev);
- return sprintf(buf, "%s\n",
- YES_NO(usbvision->isoc_mode == ISOC_MODE_COMPRESS));
-}
-static DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL);
-
-static ssize_t show_device_bridge(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vdev =
- container_of(cd, struct video_device, dev);
- struct usb_usbvision *usbvision = video_get_drvdata(vdev);
- return sprintf(buf, "%d\n", usbvision->bridge_type);
-}
-static DEVICE_ATTR(bridge, S_IRUGO, show_device_bridge, NULL);
-
-static void usbvision_create_sysfs(struct video_device *vdev)
-{
- int res;
-
- if (!vdev)
- return;
- do {
- res = device_create_file(&vdev->dev, &dev_attr_version);
- if (res < 0)
- break;
- res = device_create_file(&vdev->dev, &dev_attr_model);
- if (res < 0)
- break;
- res = device_create_file(&vdev->dev, &dev_attr_hue);
- if (res < 0)
- break;
- res = device_create_file(&vdev->dev, &dev_attr_contrast);
- if (res < 0)
- break;
- res = device_create_file(&vdev->dev, &dev_attr_brightness);
- if (res < 0)
- break;
- res = device_create_file(&vdev->dev, &dev_attr_saturation);
- if (res < 0)
- break;
- res = device_create_file(&vdev->dev, &dev_attr_streaming);
- if (res < 0)
- break;
- res = device_create_file(&vdev->dev, &dev_attr_compression);
- if (res < 0)
- break;
- res = device_create_file(&vdev->dev, &dev_attr_bridge);
- if (res >= 0)
- return;
- } while (0);
-
- dev_err(&vdev->dev, "%s error: %d\n", __func__, res);
-}
-
-static void usbvision_remove_sysfs(struct video_device *vdev)
-{
- if (vdev) {
- device_remove_file(&vdev->dev, &dev_attr_version);
- device_remove_file(&vdev->dev, &dev_attr_model);
- device_remove_file(&vdev->dev, &dev_attr_hue);
- device_remove_file(&vdev->dev, &dev_attr_contrast);
- device_remove_file(&vdev->dev, &dev_attr_brightness);
- device_remove_file(&vdev->dev, &dev_attr_saturation);
- device_remove_file(&vdev->dev, &dev_attr_streaming);
- device_remove_file(&vdev->dev, &dev_attr_compression);
- device_remove_file(&vdev->dev, &dev_attr_bridge);
- }
-}
-
-/*
- * usbvision_open()
- *
- * This is part of Video 4 Linux API. The driver can be opened by one
- * client only (checks internal counter 'usbvision->user'). The procedure
- * then allocates buffers needed for video processing.
- *
- */
-static int usbvision_v4l2_open(struct file *file)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
- int err_code = 0;
-
- PDEBUG(DBG_IO, "open");
-
- usbvision_reset_power_off_timer(usbvision);
-
- if (usbvision->user)
- err_code = -EBUSY;
- else {
- /* Allocate memory for the scratch ring buffer */
- err_code = usbvision_scratch_alloc(usbvision);
- if (isoc_mode == ISOC_MODE_COMPRESS) {
- /* Allocate intermediate decompression buffers
- only if needed */
- err_code = usbvision_decompress_alloc(usbvision);
- }
- if (err_code) {
- /* Deallocate all buffers if trouble */
- usbvision_scratch_free(usbvision);
- usbvision_decompress_free(usbvision);
- }
- }
-
- /* If so far no errors then we shall start the camera */
- if (!err_code) {
- if (usbvision->power == 0) {
- usbvision_power_on(usbvision);
- usbvision_i2c_register(usbvision);
- }
-
- /* Send init sequence only once, it's large! */
- if (!usbvision->initialized) {
- int setup_ok = 0;
- setup_ok = usbvision_setup(usbvision, isoc_mode);
- if (setup_ok)
- usbvision->initialized = 1;
- else
- err_code = -EBUSY;
- }
-
- if (!err_code) {
- usbvision_begin_streaming(usbvision);
- err_code = usbvision_init_isoc(usbvision);
- /* device must be initialized before isoc transfer */
- usbvision_muxsel(usbvision, 0);
- usbvision->user++;
- } else {
- if (power_on_at_open) {
- usbvision_i2c_unregister(usbvision);
- usbvision_power_off(usbvision);
- usbvision->initialized = 0;
- }
- }
- }
-
- /* prepare queues */
- usbvision_empty_framequeues(usbvision);
-
- PDEBUG(DBG_IO, "success");
- return err_code;
-}
-
-/*
- * usbvision_v4l2_close()
- *
- * This is part of Video 4 Linux API. The procedure
- * stops streaming and deallocates all buffers that were earlier
- * allocated in usbvision_v4l2_open().
- *
- */
-static int usbvision_v4l2_close(struct file *file)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- PDEBUG(DBG_IO, "close");
-
- usbvision_audio_off(usbvision);
- usbvision_restart_isoc(usbvision);
- usbvision_stop_isoc(usbvision);
-
- usbvision_decompress_free(usbvision);
- usbvision_frames_free(usbvision);
- usbvision_empty_framequeues(usbvision);
- usbvision_scratch_free(usbvision);
-
- usbvision->user--;
-
- if (power_on_at_open) {
- /* power off in a little while
- to avoid off/on every close/open short sequences */
- usbvision_set_power_off_timer(usbvision);
- usbvision->initialized = 0;
- }
-
- if (usbvision->remove_pending) {
- printk(KERN_INFO "%s: Final disconnect\n", __func__);
- usbvision_release(usbvision);
- }
-
- PDEBUG(DBG_IO, "success");
- return 0;
-}
-
-
-/*
- * usbvision_ioctl()
- *
- * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
- *
- */
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vidioc_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
- int err_code;
-
- if (!v4l2_chip_match_host(&reg->match))
- return -EINVAL;
- /* NT100x has a 8-bit register space */
- err_code = usbvision_read_reg(usbvision, reg->reg&0xff);
- if (err_code < 0) {
- dev_err(&usbvision->vdev->dev,
- "%s: VIDIOC_DBG_G_REGISTER failed: error %d\n",
- __func__, err_code);
- return err_code;
- }
- reg->val = err_code;
- reg->size = 1;
- return 0;
-}
-
-static int vidioc_s_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
- int err_code;
-
- if (!v4l2_chip_match_host(&reg->match))
- return -EINVAL;
- /* NT100x has a 8-bit register space */
- err_code = usbvision_write_reg(usbvision, reg->reg & 0xff, reg->val);
- if (err_code < 0) {
- dev_err(&usbvision->vdev->dev,
- "%s: VIDIOC_DBG_S_REGISTER failed: error %d\n",
- __func__, err_code);
- return err_code;
- }
- return 0;
-}
-#endif
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *vc)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- strlcpy(vc->driver, "USBVision", sizeof(vc->driver));
- strlcpy(vc->card,
- usbvision_device_data[usbvision->dev_model].model_string,
- sizeof(vc->card));
- usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info));
- vc->capabilities = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_AUDIO |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING |
- (usbvision->have_tuner ? V4L2_CAP_TUNER : 0);
- return 0;
-}
-
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *vi)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
- int chan;
-
- if (vi->index >= usbvision->video_inputs)
- return -EINVAL;
- if (usbvision->have_tuner)
- chan = vi->index;
- else
- chan = vi->index + 1; /* skip Television string*/
-
- /* Determine the requested input characteristics
- specific for each usbvision card model */
- switch (chan) {
- case 0:
- if (usbvision_device_data[usbvision->dev_model].video_channels == 4) {
- strcpy(vi->name, "White Video Input");
- } else {
- strcpy(vi->name, "Television");
- vi->type = V4L2_INPUT_TYPE_TUNER;
- vi->audioset = 1;
- vi->tuner = chan;
- vi->std = USBVISION_NORMS;
- }
- break;
- case 1:
- vi->type = V4L2_INPUT_TYPE_CAMERA;
- if (usbvision_device_data[usbvision->dev_model].video_channels == 4)
- strcpy(vi->name, "Green Video Input");
- else
- strcpy(vi->name, "Composite Video Input");
- vi->std = V4L2_STD_PAL;
- break;
- case 2:
- vi->type = V4L2_INPUT_TYPE_CAMERA;
- if (usbvision_device_data[usbvision->dev_model].video_channels == 4)
- strcpy(vi->name, "Yellow Video Input");
- else
- strcpy(vi->name, "S-Video Input");
- vi->std = V4L2_STD_PAL;
- break;
- case 3:
- vi->type = V4L2_INPUT_TYPE_CAMERA;
- strcpy(vi->name, "Red Video Input");
- vi->std = V4L2_STD_PAL;
- break;
- }
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- *input = usbvision->ctl_input;
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- if (input >= usbvision->video_inputs)
- return -EINVAL;
-
- usbvision_muxsel(usbvision, input);
- usbvision_set_input(usbvision);
- usbvision_set_output(usbvision,
- usbvision->curwidth,
- usbvision->curheight);
- return 0;
-}
-
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- usbvision->tvnorm_id = *id;
-
- call_all(usbvision, core, s_std, usbvision->tvnorm_id);
- /* propagate the change to the decoder */
- usbvision_muxsel(usbvision, usbvision->ctl_input);
-
- return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *vt)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- if (!usbvision->have_tuner || vt->index) /* Only tuner 0 */
- return -EINVAL;
- if (usbvision->radio) {
- strcpy(vt->name, "Radio");
- vt->type = V4L2_TUNER_RADIO;
- } else {
- strcpy(vt->name, "Television");
- }
- /* Let clients fill in the remainder of this struct */
- call_all(usbvision, tuner, g_tuner, vt);
-
- return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *vt)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- /* Only no or one tuner for now */
- if (!usbvision->have_tuner || vt->index)
- return -EINVAL;
- /* let clients handle this */
- call_all(usbvision, tuner, s_tuner, vt);
-
- return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *freq)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- freq->tuner = 0; /* Only one tuner */
- if (usbvision->radio)
- freq->type = V4L2_TUNER_RADIO;
- else
- freq->type = V4L2_TUNER_ANALOG_TV;
- freq->frequency = usbvision->freq;
-
- return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *freq)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- /* Only no or one tuner for now */
- if (!usbvision->have_tuner || freq->tuner)
- return -EINVAL;
-
- usbvision->freq = freq->frequency;
- call_all(usbvision, tuner, s_frequency, freq);
-
- return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- if (usbvision->radio)
- strcpy(a->name, "Radio");
- else
- strcpy(a->name, "TV");
-
- return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *fh,
- struct v4l2_audio *a)
-{
- if (a->index)
- return -EINVAL;
- return 0;
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *ctrl)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- call_all(usbvision, core, queryctrl, ctrl);
-
- if (!ctrl->type)
- return -EINVAL;
-
- return 0;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- call_all(usbvision, core, g_ctrl, ctrl);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- call_all(usbvision, core, s_ctrl, ctrl);
- return 0;
-}
-
-static int vidioc_reqbufs(struct file *file,
- void *priv, struct v4l2_requestbuffers *vr)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
- int ret;
-
- RESTRICT_TO_RANGE(vr->count, 1, USBVISION_NUMFRAMES);
-
- /* Check input validity:
- the user must do a VIDEO CAPTURE and MMAP method. */
- if (vr->memory != V4L2_MEMORY_MMAP)
- return -EINVAL;
-
- if (usbvision->streaming == stream_on) {
- ret = usbvision_stream_interrupt(usbvision);
- if (ret)
- return ret;
- }
-
- usbvision_frames_free(usbvision);
- usbvision_empty_framequeues(usbvision);
- vr->count = usbvision_frames_alloc(usbvision, vr->count);
-
- usbvision->cur_frame = NULL;
-
- return 0;
-}
-
-static int vidioc_querybuf(struct file *file,
- void *priv, struct v4l2_buffer *vb)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
- struct usbvision_frame *frame;
-
- /* FIXME : must control
- that buffers are mapped (VIDIOC_REQBUFS has been called) */
- if (vb->index >= usbvision->num_frames)
- return -EINVAL;
- /* Updating the corresponding frame state */
- vb->flags = 0;
- frame = &usbvision->frame[vb->index];
- if (frame->grabstate >= frame_state_ready)
- vb->flags |= V4L2_BUF_FLAG_QUEUED;
- if (frame->grabstate >= frame_state_done)
- vb->flags |= V4L2_BUF_FLAG_DONE;
- if (frame->grabstate == frame_state_unused)
- vb->flags |= V4L2_BUF_FLAG_MAPPED;
- vb->memory = V4L2_MEMORY_MMAP;
-
- vb->m.offset = vb->index * PAGE_ALIGN(usbvision->max_frame_size);
-
- vb->memory = V4L2_MEMORY_MMAP;
- vb->field = V4L2_FIELD_NONE;
- vb->length = usbvision->curwidth *
- usbvision->curheight *
- usbvision->palette.bytes_per_pixel;
- vb->timestamp = usbvision->frame[vb->index].timestamp;
- vb->sequence = usbvision->frame[vb->index].sequence;
- return 0;
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *vb)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
- struct usbvision_frame *frame;
- unsigned long lock_flags;
-
- /* FIXME : works only on VIDEO_CAPTURE MODE, MMAP. */
- if (vb->index >= usbvision->num_frames)
- return -EINVAL;
-
- frame = &usbvision->frame[vb->index];
-
- if (frame->grabstate != frame_state_unused)
- return -EAGAIN;
-
- /* Mark it as ready and enqueue frame */
- frame->grabstate = frame_state_ready;
- frame->scanstate = scan_state_scanning;
- frame->scanlength = 0; /* Accumulated in usbvision_parse_data() */
-
- vb->flags &= ~V4L2_BUF_FLAG_DONE;
-
- /* set v4l2_format index */
- frame->v4l2_format = usbvision->palette;
-
- spin_lock_irqsave(&usbvision->queue_lock, lock_flags);
- list_add_tail(&usbvision->frame[vb->index].frame, &usbvision->inqueue);
- spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);
-
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *vb)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
- int ret;
- struct usbvision_frame *f;
- unsigned long lock_flags;
-
- if (list_empty(&(usbvision->outqueue))) {
- if (usbvision->streaming == stream_idle)
- return -EINVAL;
- ret = wait_event_interruptible
- (usbvision->wait_frame,
- !list_empty(&(usbvision->outqueue)));
- if (ret)
- return ret;
- }
-
- spin_lock_irqsave(&usbvision->queue_lock, lock_flags);
- f = list_entry(usbvision->outqueue.next,
- struct usbvision_frame, frame);
- list_del(usbvision->outqueue.next);
- spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);
-
- f->grabstate = frame_state_unused;
-
- vb->memory = V4L2_MEMORY_MMAP;
- vb->flags = V4L2_BUF_FLAG_MAPPED |
- V4L2_BUF_FLAG_QUEUED |
- V4L2_BUF_FLAG_DONE;
- vb->index = f->index;
- vb->sequence = f->sequence;
- vb->timestamp = f->timestamp;
- vb->field = V4L2_FIELD_NONE;
- vb->bytesused = f->scanlength;
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- usbvision->streaming = stream_on;
- call_all(usbvision, video, s_stream, 1);
-
- return 0;
-}
-
-static int vidioc_streamoff(struct file *file,
- void *priv, enum v4l2_buf_type type)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (usbvision->streaming == stream_on) {
- usbvision_stream_interrupt(usbvision);
- /* Stop all video streamings */
- call_all(usbvision, video, s_stream, 0);
- }
- usbvision_empty_framequeues(usbvision);
-
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *vfd)
-{
- if (vfd->index >= USBVISION_SUPPORTED_PALETTES - 1)
- return -EINVAL;
- strcpy(vfd->description, usbvision_v4l2_format[vfd->index].desc);
- vfd->pixelformat = usbvision_v4l2_format[vfd->index].format;
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *vf)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
- vf->fmt.pix.width = usbvision->curwidth;
- vf->fmt.pix.height = usbvision->curheight;
- vf->fmt.pix.pixelformat = usbvision->palette.format;
- vf->fmt.pix.bytesperline =
- usbvision->curwidth * usbvision->palette.bytes_per_pixel;
- vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline * usbvision->curheight;
- vf->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- vf->fmt.pix.field = V4L2_FIELD_NONE; /* Always progressive image */
-
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *vf)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
- int format_idx;
-
- /* Find requested format in available ones */
- for (format_idx = 0; format_idx < USBVISION_SUPPORTED_PALETTES; format_idx++) {
- if (vf->fmt.pix.pixelformat ==
- usbvision_v4l2_format[format_idx].format) {
- usbvision->palette = usbvision_v4l2_format[format_idx];
- break;
- }
- }
- /* robustness */
- if (format_idx == USBVISION_SUPPORTED_PALETTES)
- return -EINVAL;
- RESTRICT_TO_RANGE(vf->fmt.pix.width, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH);
- RESTRICT_TO_RANGE(vf->fmt.pix.height, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT);
-
- vf->fmt.pix.bytesperline = vf->fmt.pix.width*
- usbvision->palette.bytes_per_pixel;
- vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline*vf->fmt.pix.height;
-
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *vf)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
- int ret;
-
- ret = vidioc_try_fmt_vid_cap(file, priv, vf);
- if (ret)
- return ret;
-
- /* stop io in case it is already in progress */
- if (usbvision->streaming == stream_on) {
- ret = usbvision_stream_interrupt(usbvision);
- if (ret)
- return ret;
- }
- usbvision_frames_free(usbvision);
- usbvision_empty_framequeues(usbvision);
-
- usbvision->cur_frame = NULL;
-
- /* by now we are committed to the new data... */
- usbvision_set_output(usbvision, vf->fmt.pix.width, vf->fmt.pix.height);
-
- return 0;
-}
-
-static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
- int noblock = file->f_flags & O_NONBLOCK;
- unsigned long lock_flags;
- int ret, i;
- struct usbvision_frame *frame;
-
- PDEBUG(DBG_IO, "%s: %ld bytes, noblock=%d", __func__,
- (unsigned long)count, noblock);
-
- if (!USBVISION_IS_OPERATIONAL(usbvision) || (buf == NULL))
- return -EFAULT;
-
- /* This entry point is compatible with the mmap routines
- so that a user can do either VIDIOC_QBUF/VIDIOC_DQBUF
- to get frames or call read on the device. */
- if (!usbvision->num_frames) {
- /* First, allocate some frames to work with
- if this has not been done with VIDIOC_REQBUF */
- usbvision_frames_free(usbvision);
- usbvision_empty_framequeues(usbvision);
- usbvision_frames_alloc(usbvision, USBVISION_NUMFRAMES);
- }
-
- if (usbvision->streaming != stream_on) {
- /* no stream is running, make it running ! */
- usbvision->streaming = stream_on;
- call_all(usbvision, video, s_stream, 1);
- }
-
- /* Then, enqueue as many frames as possible
- (like a user of VIDIOC_QBUF would do) */
- for (i = 0; i < usbvision->num_frames; i++) {
- frame = &usbvision->frame[i];
- if (frame->grabstate == frame_state_unused) {
- /* Mark it as ready and enqueue frame */
- frame->grabstate = frame_state_ready;
- frame->scanstate = scan_state_scanning;
- /* Accumulated in usbvision_parse_data() */
- frame->scanlength = 0;
-
- /* set v4l2_format index */
- frame->v4l2_format = usbvision->palette;
-
- spin_lock_irqsave(&usbvision->queue_lock, lock_flags);
- list_add_tail(&frame->frame, &usbvision->inqueue);
- spin_unlock_irqrestore(&usbvision->queue_lock,
- lock_flags);
- }
- }
-
- /* Then try to steal a frame (like a VIDIOC_DQBUF would do) */
- if (list_empty(&(usbvision->outqueue))) {
- if (noblock)
- return -EAGAIN;
-
- ret = wait_event_interruptible
- (usbvision->wait_frame,
- !list_empty(&(usbvision->outqueue)));
- if (ret)
- return ret;
- }
-
- spin_lock_irqsave(&usbvision->queue_lock, lock_flags);
- frame = list_entry(usbvision->outqueue.next,
- struct usbvision_frame, frame);
- list_del(usbvision->outqueue.next);
- spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);
-
- /* An error returns an empty frame */
- if (frame->grabstate == frame_state_error) {
- frame->bytes_read = 0;
- return 0;
- }
-
- PDEBUG(DBG_IO, "%s: frmx=%d, bytes_read=%ld, scanlength=%ld",
- __func__,
- frame->index, frame->bytes_read, frame->scanlength);
-
- /* copy bytes to user space; we allow for partials reads */
- if ((count + frame->bytes_read) > (unsigned long)frame->scanlength)
- count = frame->scanlength - frame->bytes_read;
-
- if (copy_to_user(buf, frame->data + frame->bytes_read, count))
- return -EFAULT;
-
- frame->bytes_read += count;
- PDEBUG(DBG_IO, "%s: {copy} count used=%ld, new bytes_read=%ld",
- __func__,
- (unsigned long)count, frame->bytes_read);
-
- /* For now, forget the frame if it has not been read in one shot. */
-/* if (frame->bytes_read >= frame->scanlength) {*/ /* All data has been read */
- frame->bytes_read = 0;
-
- /* Mark it as available to be used again. */
- frame->grabstate = frame_state_unused;
-/* } */
-
- return count;
-}
-
-static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
-{
- unsigned long size = vma->vm_end - vma->vm_start,
- start = vma->vm_start;
- void *pos;
- u32 i;
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- PDEBUG(DBG_MMAP, "mmap");
-
- if (!USBVISION_IS_OPERATIONAL(usbvision))
- return -EFAULT;
-
- if (!(vma->vm_flags & VM_WRITE) ||
- size != PAGE_ALIGN(usbvision->max_frame_size)) {
- return -EINVAL;
- }
-
- for (i = 0; i < usbvision->num_frames; i++) {
- if (((PAGE_ALIGN(usbvision->max_frame_size)*i) >> PAGE_SHIFT) ==
- vma->vm_pgoff)
- break;
- }
- if (i == usbvision->num_frames) {
- PDEBUG(DBG_MMAP,
- "mmap: user supplied mapping address is out of range");
- return -EINVAL;
- }
-
- /* VM_IO is eventually going to replace PageReserved altogether */
- vma->vm_flags |= VM_IO;
- vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
-
- pos = usbvision->frame[i].data;
- while (size > 0) {
- if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
- PDEBUG(DBG_MMAP, "mmap: vm_insert_page failed");
- return -EAGAIN;
- }
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- return 0;
-}
-
-
-/*
- * Here comes the stuff for radio on usbvision based devices
- *
- */
-static int usbvision_radio_open(struct file *file)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
- int err_code = 0;
-
- PDEBUG(DBG_IO, "%s:", __func__);
-
- if (usbvision->user) {
- dev_err(&usbvision->rdev->dev,
- "%s: Someone tried to open an already opened USBVision Radio!\n",
- __func__);
- err_code = -EBUSY;
- } else {
- if (power_on_at_open) {
- usbvision_reset_power_off_timer(usbvision);
- if (usbvision->power == 0) {
- usbvision_power_on(usbvision);
- usbvision_i2c_register(usbvision);
- }
- }
-
- /* Alternate interface 1 is is the biggest frame size */
- err_code = usbvision_set_alternate(usbvision);
- if (err_code < 0) {
- usbvision->last_error = err_code;
- err_code = -EBUSY;
- goto out;
- }
-
- /* If so far no errors then we shall start the radio */
- usbvision->radio = 1;
- call_all(usbvision, tuner, s_radio);
- usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO);
- usbvision->user++;
- }
-
- if (err_code) {
- if (power_on_at_open) {
- usbvision_i2c_unregister(usbvision);
- usbvision_power_off(usbvision);
- usbvision->initialized = 0;
- }
- }
-out:
- return err_code;
-}
-
-
-static int usbvision_radio_close(struct file *file)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
- int err_code = 0;
-
- PDEBUG(DBG_IO, "");
-
- /* Set packet size to 0 */
- usbvision->iface_alt = 0;
- err_code = usb_set_interface(usbvision->dev, usbvision->iface,
- usbvision->iface_alt);
-
- usbvision_audio_off(usbvision);
- usbvision->radio = 0;
- usbvision->user--;
-
- if (power_on_at_open) {
- usbvision_set_power_off_timer(usbvision);
- usbvision->initialized = 0;
- }
-
- if (usbvision->remove_pending) {
- printk(KERN_INFO "%s: Final disconnect\n", __func__);
- usbvision_release(usbvision);
- }
-
- PDEBUG(DBG_IO, "success");
- return err_code;
-}
-
-/* Video registration stuff */
-
-/* Video template */
-static const struct v4l2_file_operations usbvision_fops = {
- .owner = THIS_MODULE,
- .open = usbvision_v4l2_open,
- .release = usbvision_v4l2_close,
- .read = usbvision_v4l2_read,
- .mmap = usbvision_v4l2_mmap,
- .unlocked_ioctl = video_ioctl2,
-/* .poll = video_poll, */
-};
-
-static const struct v4l2_ioctl_ops usbvision_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = vidioc_reqbufs,
- .vidioc_querybuf = vidioc_querybuf,
- .vidioc_qbuf = vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vidioc_g_register,
- .vidioc_s_register = vidioc_s_register,
-#endif
-};
-
-static struct video_device usbvision_video_template = {
- .fops = &usbvision_fops,
- .ioctl_ops = &usbvision_ioctl_ops,
- .name = "usbvision-video",
- .release = video_device_release,
- .tvnorms = USBVISION_NORMS,
- .current_norm = V4L2_STD_PAL
-};
-
-
-/* Radio template */
-static const struct v4l2_file_operations usbvision_radio_fops = {
- .owner = THIS_MODULE,
- .open = usbvision_radio_open,
- .release = usbvision_radio_close,
- .unlocked_ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
-};
-
-static struct video_device usbvision_radio_template = {
- .fops = &usbvision_radio_fops,
- .name = "usbvision-radio",
- .release = video_device_release,
- .ioctl_ops = &usbvision_radio_ioctl_ops,
-
- .tvnorms = USBVISION_NORMS,
- .current_norm = V4L2_STD_PAL
-};
-
-
-static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,
- struct video_device *vdev_template,
- char *name)
-{
- struct usb_device *usb_dev = usbvision->dev;
- struct video_device *vdev;
-
- if (usb_dev == NULL) {
- dev_err(&usbvision->dev->dev,
- "%s: usbvision->dev is not set\n", __func__);
- return NULL;
- }
-
- vdev = video_device_alloc();
- if (NULL == vdev)
- return NULL;
- *vdev = *vdev_template;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags);
- vdev->lock = &usbvision->v4l2_lock;
- vdev->v4l2_dev = &usbvision->v4l2_dev;
- snprintf(vdev->name, sizeof(vdev->name), "%s", name);
- video_set_drvdata(vdev, usbvision);
- return vdev;
-}
-
-/* unregister video4linux devices */
-static void usbvision_unregister_video(struct usb_usbvision *usbvision)
-{
- /* Radio Device: */
- if (usbvision->rdev) {
- PDEBUG(DBG_PROBE, "unregister %s [v4l2]",
- video_device_node_name(usbvision->rdev));
- if (video_is_registered(usbvision->rdev))
- video_unregister_device(usbvision->rdev);
- else
- video_device_release(usbvision->rdev);
- usbvision->rdev = NULL;
- }
-
- /* Video Device: */
- if (usbvision->vdev) {
- PDEBUG(DBG_PROBE, "unregister %s [v4l2]",
- video_device_node_name(usbvision->vdev));
- if (video_is_registered(usbvision->vdev))
- video_unregister_device(usbvision->vdev);
- else
- video_device_release(usbvision->vdev);
- usbvision->vdev = NULL;
- }
-}
-
-/* register video4linux devices */
-static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
-{
- /* Video Device: */
- usbvision->vdev = usbvision_vdev_init(usbvision,
- &usbvision_video_template,
- "USBVision Video");
- if (usbvision->vdev == NULL)
- goto err_exit;
- if (video_register_device(usbvision->vdev, VFL_TYPE_GRABBER, video_nr) < 0)
- goto err_exit;
- printk(KERN_INFO "USBVision[%d]: registered USBVision Video device %s [v4l2]\n",
- usbvision->nr, video_device_node_name(usbvision->vdev));
-
- /* Radio Device: */
- if (usbvision_device_data[usbvision->dev_model].radio) {
- /* usbvision has radio */
- usbvision->rdev = usbvision_vdev_init(usbvision,
- &usbvision_radio_template,
- "USBVision Radio");
- if (usbvision->rdev == NULL)
- goto err_exit;
- if (video_register_device(usbvision->rdev, VFL_TYPE_RADIO, radio_nr) < 0)
- goto err_exit;
- printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device %s [v4l2]\n",
- usbvision->nr, video_device_node_name(usbvision->rdev));
- }
- /* all done */
- return 0;
-
- err_exit:
- dev_err(&usbvision->dev->dev,
- "USBVision[%d]: video_register_device() failed\n",
- usbvision->nr);
- usbvision_unregister_video(usbvision);
- return -1;
-}
-
-/*
- * usbvision_alloc()
- *
- * This code allocates the struct usb_usbvision.
- * It is filled with default values.
- *
- * Returns NULL on error, a pointer to usb_usbvision else.
- *
- */
-static struct usb_usbvision *usbvision_alloc(struct usb_device *dev,
- struct usb_interface *intf)
-{
- struct usb_usbvision *usbvision;
-
- usbvision = kzalloc(sizeof(struct usb_usbvision), GFP_KERNEL);
- if (usbvision == NULL)
- return NULL;
-
- usbvision->dev = dev;
- if (v4l2_device_register(&intf->dev, &usbvision->v4l2_dev))
- goto err_free;
-
- mutex_init(&usbvision->v4l2_lock);
-
- /* prepare control urb for control messages during interrupts */
- usbvision->ctrl_urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
- if (usbvision->ctrl_urb == NULL)
- goto err_unreg;
- init_waitqueue_head(&usbvision->ctrl_urb_wq);
-
- usbvision_init_power_off_timer(usbvision);
-
- return usbvision;
-
-err_unreg:
- v4l2_device_unregister(&usbvision->v4l2_dev);
-err_free:
- kfree(usbvision);
- return NULL;
-}
-
-/*
- * usbvision_release()
- *
- * This code does final release of struct usb_usbvision. This happens
- * after the device is disconnected -and- all clients closed their files.
- *
- */
-static void usbvision_release(struct usb_usbvision *usbvision)
-{
- PDEBUG(DBG_PROBE, "");
-
- usbvision_reset_power_off_timer(usbvision);
-
- usbvision->initialized = 0;
-
- usbvision_remove_sysfs(usbvision->vdev);
- usbvision_unregister_video(usbvision);
-
- usb_free_urb(usbvision->ctrl_urb);
-
- v4l2_device_unregister(&usbvision->v4l2_dev);
- kfree(usbvision);
-
- PDEBUG(DBG_PROBE, "success");
-}
-
-
-/*********************** usb interface **********************************/
-
-static void usbvision_configure_video(struct usb_usbvision *usbvision)
-{
- int model;
-
- if (usbvision == NULL)
- return;
-
- model = usbvision->dev_model;
- usbvision->palette = usbvision_v4l2_format[2]; /* V4L2_PIX_FMT_RGB24; */
-
- if (usbvision_device_data[usbvision->dev_model].vin_reg2_override) {
- usbvision->vin_reg2_preset =
- usbvision_device_data[usbvision->dev_model].vin_reg2;
- } else {
- usbvision->vin_reg2_preset = 0;
- }
-
- usbvision->tvnorm_id = usbvision_device_data[model].video_norm;
-
- usbvision->video_inputs = usbvision_device_data[model].video_channels;
- usbvision->ctl_input = 0;
-
- /* This should be here to make i2c clients to be able to register */
- /* first switch off audio */
- if (usbvision_device_data[model].audio_channels > 0)
- usbvision_audio_off(usbvision);
- if (!power_on_at_open) {
- /* and then power up the noisy tuner */
- usbvision_power_on(usbvision);
- usbvision_i2c_register(usbvision);
- }
-}
-
-/*
- * usbvision_probe()
- *
- * This procedure queries device descriptor and accepts the interface
- * if it looks like USBVISION video device
- *
- */
-static int __devinit usbvision_probe(struct usb_interface *intf,
- const struct usb_device_id *devid)
-{
- struct usb_device *dev = usb_get_dev(interface_to_usbdev(intf));
- struct usb_interface *uif;
- __u8 ifnum = intf->altsetting->desc.bInterfaceNumber;
- const struct usb_host_interface *interface;
- struct usb_usbvision *usbvision = NULL;
- const struct usb_endpoint_descriptor *endpoint;
- int model, i;
-
- PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u",
- dev->descriptor.idVendor,
- dev->descriptor.idProduct, ifnum);
-
- model = devid->driver_info;
- if (model < 0 || model >= usbvision_device_data_size) {
- PDEBUG(DBG_PROBE, "model out of bounds %d", model);
- return -ENODEV;
- }
- printk(KERN_INFO "%s: %s found\n", __func__,
- usbvision_device_data[model].model_string);
-
- if (usbvision_device_data[model].interface >= 0)
- interface = &dev->actconfig->interface[usbvision_device_data[model].interface]->altsetting[0];
- else
- interface = &dev->actconfig->interface[ifnum]->altsetting[0];
- endpoint = &interface->endpoint[1].desc;
- if (!usb_endpoint_xfer_isoc(endpoint)) {
- dev_err(&intf->dev, "%s: interface %d. has non-ISO endpoint!\n",
- __func__, ifnum);
- dev_err(&intf->dev, "%s: Endpoint attributes %d",
- __func__, endpoint->bmAttributes);
- return -ENODEV;
- }
- if (usb_endpoint_dir_out(endpoint)) {
- dev_err(&intf->dev, "%s: interface %d. has ISO OUT endpoint!\n",
- __func__, ifnum);
- return -ENODEV;
- }
-
- usbvision = usbvision_alloc(dev, intf);
- if (usbvision == NULL) {
- dev_err(&intf->dev, "%s: couldn't allocate USBVision struct\n", __func__);
- return -ENOMEM;
- }
-
- if (dev->descriptor.bNumConfigurations > 1)
- usbvision->bridge_type = BRIDGE_NT1004;
- else if (model == DAZZLE_DVC_90_REV_1_SECAM)
- usbvision->bridge_type = BRIDGE_NT1005;
- else
- usbvision->bridge_type = BRIDGE_NT1003;
- PDEBUG(DBG_PROBE, "bridge_type %d", usbvision->bridge_type);
-
- /* compute alternate max packet sizes */
- uif = dev->actconfig->interface[0];
-
- usbvision->num_alt = uif->num_altsetting;
- PDEBUG(DBG_PROBE, "Alternate settings: %i", usbvision->num_alt);
- usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, GFP_KERNEL);
- if (usbvision->alt_max_pkt_size == NULL) {
- dev_err(&intf->dev, "usbvision: out of memory!\n");
- return -ENOMEM;
- }
-
- for (i = 0; i < usbvision->num_alt; i++) {
- u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
- wMaxPacketSize);
- usbvision->alt_max_pkt_size[i] =
- (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
- PDEBUG(DBG_PROBE, "Alternate setting %i, max size= %i", i,
- usbvision->alt_max_pkt_size[i]);
- }
-
-
- usbvision->nr = usbvision_nr++;
-
- usbvision->have_tuner = usbvision_device_data[model].tuner;
- if (usbvision->have_tuner)
- usbvision->tuner_type = usbvision_device_data[model].tuner_type;
-
- usbvision->dev_model = model;
- usbvision->remove_pending = 0;
- usbvision->iface = ifnum;
- usbvision->iface_alt = 0;
- usbvision->video_endp = endpoint->bEndpointAddress;
- usbvision->isoc_packet_size = 0;
- usbvision->usb_bandwidth = 0;
- usbvision->user = 0;
- usbvision->streaming = stream_off;
- usbvision_configure_video(usbvision);
- usbvision_register_video(usbvision);
-
- usbvision_create_sysfs(usbvision->vdev);
-
- PDEBUG(DBG_PROBE, "success");
- return 0;
-}
-
-
-/*
- * usbvision_disconnect()
- *
- * This procedure stops all driver activity, deallocates interface-private
- * structure (pointed by 'ptr') and after that driver should be removable
- * with no ill consequences.
- *
- */
-static void __devexit usbvision_disconnect(struct usb_interface *intf)
-{
- struct usb_usbvision *usbvision = to_usbvision(usb_get_intfdata(intf));
-
- PDEBUG(DBG_PROBE, "");
-
- if (usbvision == NULL) {
- pr_err("%s: usb_get_intfdata() failed\n", __func__);
- return;
- }
-
- mutex_lock(&usbvision->v4l2_lock);
-
- /* At this time we ask to cancel outstanding URBs */
- usbvision_stop_isoc(usbvision);
-
- v4l2_device_disconnect(&usbvision->v4l2_dev);
-
- if (usbvision->power) {
- usbvision_i2c_unregister(usbvision);
- usbvision_power_off(usbvision);
- }
- usbvision->remove_pending = 1; /* Now all ISO data will be ignored */
-
- usb_put_dev(usbvision->dev);
- usbvision->dev = NULL; /* USB device is no more */
-
- mutex_unlock(&usbvision->v4l2_lock);
-
- if (usbvision->user) {
- printk(KERN_INFO "%s: In use, disconnect pending\n",
- __func__);
- wake_up_interruptible(&usbvision->wait_frame);
- wake_up_interruptible(&usbvision->wait_stream);
- } else {
- usbvision_release(usbvision);
- }
-
- PDEBUG(DBG_PROBE, "success");
-}
-
-static struct usb_driver usbvision_driver = {
- .name = "usbvision",
- .id_table = usbvision_table,
- .probe = usbvision_probe,
- .disconnect = __devexit_p(usbvision_disconnect),
-};
-
-/*
- * usbvision_init()
- *
- * This code is run to initialize the driver.
- *
- */
-static int __init usbvision_init(void)
-{
- int err_code;
-
- PDEBUG(DBG_PROBE, "");
-
- PDEBUG(DBG_IO, "IO debugging is enabled [video]");
- PDEBUG(DBG_PROBE, "PROBE debugging is enabled [video]");
- PDEBUG(DBG_MMAP, "MMAP debugging is enabled [video]");
-
- /* disable planar mode support unless compression enabled */
- if (isoc_mode != ISOC_MODE_COMPRESS) {
- /* FIXME : not the right way to set supported flag */
- usbvision_v4l2_format[6].supported = 0; /* V4L2_PIX_FMT_YVU420 */
- usbvision_v4l2_format[7].supported = 0; /* V4L2_PIX_FMT_YUV422P */
- }
-
- err_code = usb_register(&usbvision_driver);
-
- if (err_code == 0) {
- printk(KERN_INFO DRIVER_DESC " : " USBVISION_VERSION_STRING "\n");
- PDEBUG(DBG_PROBE, "success");
- }
- return err_code;
-}
-
-static void __exit usbvision_exit(void)
-{
- PDEBUG(DBG_PROBE, "");
-
- usb_deregister(&usbvision_driver);
- PDEBUG(DBG_PROBE, "success");
-}
-
-module_init(usbvision_init);
-module_exit(usbvision_exit);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h
deleted file mode 100644
index 43cf61fe494..00000000000
--- a/drivers/media/video/usbvision/usbvision.h
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * USBVISION.H
- * usbvision header file
- *
- * Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de>
- * Dwaine Garden <dwainegarden@rogers.com>
- *
- *
- * Report problems to v4l MailingList: linux-media@vger.kernel.org
- *
- * This module is part of usbvision driver project.
- * Updates to driver completed by Dwaine P. Garden
- * v4l2 conversion by Thierry Merle <thierry.merle@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#ifndef __LINUX_USBVISION_H
-#define __LINUX_USBVISION_H
-
-#include <linux/list.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <media/v4l2-device.h>
-#include <media/tuner.h>
-#include <linux/videodev2.h>
-
-#define USBVISION_DEBUG /* Turn on debug messages */
-
-#define USBVISION_PWR_REG 0x00
- #define USBVISION_SSPND_EN (1 << 1)
- #define USBVISION_RES2 (1 << 2)
- #define USBVISION_PWR_VID (1 << 5)
- #define USBVISION_E2_EN (1 << 7)
-#define USBVISION_CONFIG_REG 0x01
-#define USBVISION_ADRS_REG 0x02
-#define USBVISION_ALTER_REG 0x03
-#define USBVISION_FORCE_ALTER_REG 0x04
-#define USBVISION_STATUS_REG 0x05
-#define USBVISION_IOPIN_REG 0x06
- #define USBVISION_IO_1 (1 << 0)
- #define USBVISION_IO_2 (1 << 1)
- #define USBVISION_AUDIO_IN 0
- #define USBVISION_AUDIO_TV 1
- #define USBVISION_AUDIO_RADIO 2
- #define USBVISION_AUDIO_MUTE 3
-#define USBVISION_SER_MODE 0x07
- #define USBVISION_CLK_OUT (1 << 0)
- #define USBVISION_DAT_IO (1 << 1)
- #define USBVISION_SENS_OUT (1 << 2)
- #define USBVISION_SER_MODE_SOFT (0 << 4)
- #define USBVISION_SER_MODE_SIO (1 << 4)
-#define USBVISION_SER_ADRS 0x08
-#define USBVISION_SER_CONT 0x09
-#define USBVISION_SER_DAT1 0x0A
-#define USBVISION_SER_DAT2 0x0B
-#define USBVISION_SER_DAT3 0x0C
-#define USBVISION_SER_DAT4 0x0D
-#define USBVISION_EE_DATA 0x0E
-#define USBVISION_EE_LSBAD 0x0F
-#define USBVISION_EE_CONT 0x10
-#define USBVISION_DRM_CONT 0x12
- #define USBVISION_REF (1 << 0)
- #define USBVISION_RES_UR (1 << 2)
- #define USBVISION_RES_FDL (1 << 3)
- #define USBVISION_RES_VDW (1 << 4)
-#define USBVISION_DRM_PRM1 0x13
-#define USBVISION_DRM_PRM2 0x14
-#define USBVISION_DRM_PRM3 0x15
-#define USBVISION_DRM_PRM4 0x16
-#define USBVISION_DRM_PRM5 0x17
-#define USBVISION_DRM_PRM6 0x18
-#define USBVISION_DRM_PRM7 0x19
-#define USBVISION_DRM_PRM8 0x1A
-#define USBVISION_VIN_REG1 0x1B
- #define USBVISION_8_422_SYNC 0x01
- #define USBVISION_16_422_SYNC 0x02
- #define USBVISION_VSNC_POL (1 << 3)
- #define USBVISION_HSNC_POL (1 << 4)
- #define USBVISION_FID_POL (1 << 5)
- #define USBVISION_HVALID_PO (1 << 6)
- #define USBVISION_VCLK_POL (1 << 7)
-#define USBVISION_VIN_REG2 0x1C
- #define USBVISION_AUTO_FID (1 << 0)
- #define USBVISION_NONE_INTER (1 << 1)
- #define USBVISION_NOHVALID (1 << 2)
- #define USBVISION_UV_ID (1 << 3)
- #define USBVISION_FIX_2C (1 << 4)
- #define USBVISION_SEND_FID (1 << 5)
- #define USBVISION_KEEP_BLANK (1 << 7)
-#define USBVISION_LXSIZE_I 0x1D
-#define USBVISION_MXSIZE_I 0x1E
-#define USBVISION_LYSIZE_I 0x1F
-#define USBVISION_MYSIZE_I 0x20
-#define USBVISION_LX_OFFST 0x21
-#define USBVISION_MX_OFFST 0x22
-#define USBVISION_LY_OFFST 0x23
-#define USBVISION_MY_OFFST 0x24
-#define USBVISION_FRM_RATE 0x25
-#define USBVISION_LXSIZE_O 0x26
-#define USBVISION_MXSIZE_O 0x27
-#define USBVISION_LYSIZE_O 0x28
-#define USBVISION_MYSIZE_O 0x29
-#define USBVISION_FILT_CONT 0x2A
-#define USBVISION_VO_MODE 0x2B
-#define USBVISION_INTRA_CYC 0x2C
-#define USBVISION_STRIP_SZ 0x2D
-#define USBVISION_FORCE_INTRA 0x2E
-#define USBVISION_FORCE_UP 0x2F
-#define USBVISION_BUF_THR 0x30
-#define USBVISION_DVI_YUV 0x31
-#define USBVISION_AUDIO_CONT 0x32
-#define USBVISION_AUD_PK_LEN 0x33
-#define USBVISION_BLK_PK_LEN 0x34
-#define USBVISION_PCM_THR1 0x38
-#define USBVISION_PCM_THR2 0x39
-#define USBVISION_DIST_THR_L 0x3A
-#define USBVISION_DIST_THR_H 0x3B
-#define USBVISION_MAX_DIST_L 0x3C
-#define USBVISION_MAX_DIST_H 0x3D
-#define USBVISION_OP_CODE 0x33
-
-#define MAX_BYTES_PER_PIXEL 4
-
-#define MIN_FRAME_WIDTH 64
-#define MAX_USB_WIDTH 320 /* 384 */
-#define MAX_FRAME_WIDTH 320 /* 384 */ /* streching sometimes causes crashes*/
-
-#define MIN_FRAME_HEIGHT 48
-#define MAX_USB_HEIGHT 240 /* 288 */
-#define MAX_FRAME_HEIGHT 240 /* 288 */ /* Streching sometimes causes crashes*/
-
-#define MAX_FRAME_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * MAX_BYTES_PER_PIXEL)
-#define USBVISION_CLIPMASK_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 8) /* bytesize of clipmask */
-
-#define USBVISION_URB_FRAMES 32
-
-#define USBVISION_NUM_HEADERMARKER 20
-#define USBVISION_NUMFRAMES 3 /* Maximum number of frames an application can get */
-#define USBVISION_NUMSBUF 2 /* Dimensioning the USB S buffering */
-
-#define USBVISION_POWEROFF_TIME (3 * HZ) /* 3 seconds */
-
-
-#define FRAMERATE_MIN 0
-#define FRAMERATE_MAX 31
-
-enum {
- ISOC_MODE_YUV422 = 0x03,
- ISOC_MODE_YUV420 = 0x14,
- ISOC_MODE_COMPRESS = 0x60,
-};
-
-/* This macro restricts an int variable to an inclusive range */
-#define RESTRICT_TO_RANGE(v, mi, ma) \
- { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
-
-/*
- * We use macros to do YUV -> RGB conversion because this is
- * very important for speed and totally unimportant for size.
- *
- * YUV -> RGB Conversion
- * ---------------------
- *
- * B = 1.164*(Y-16) + 2.018*(V-128)
- * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128)
- * R = 1.164*(Y-16) + 1.596*(U-128)
- *
- * If you fancy integer arithmetics (as you should), hear this:
- *
- * 65536*B = 76284*(Y-16) + 132252*(V-128)
- * 65536*G = 76284*(Y-16) - 53281*(U-128) - 25625*(V-128)
- * 65536*R = 76284*(Y-16) + 104595*(U-128)
- *
- * Make sure the output values are within [0..255] range.
- */
-#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
-#define YUV_TO_RGB_BY_THE_BOOK(my, mu, mv, mr, mg, mb) { \
- int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \
- mm_y = (my) - 16; \
- mm_u = (mu) - 128; \
- mm_v = (mv) - 128; \
- mm_yc = mm_y * 76284; \
- mm_b = (mm_yc + 132252 * mm_v) >> 16; \
- mm_g = (mm_yc - 53281 * mm_u - 25625 * mm_v) >> 16; \
- mm_r = (mm_yc + 104595 * mm_u) >> 16; \
- mb = LIMIT_RGB(mm_b); \
- mg = LIMIT_RGB(mm_g); \
- mr = LIMIT_RGB(mm_r); \
-}
-
-/* Debugging aid */
-#define USBVISION_SAY_AND_WAIT(what) { \
- wait_queue_head_t wq; \
- init_waitqueue_head(&wq); \
- printk(KERN_INFO "Say: %s\n", what); \
- interruptible_sleep_on_timeout(&wq, HZ * 3); \
-}
-
-/*
- * This macro checks if usbvision is still operational. The 'usbvision'
- * pointer must be valid, usbvision->dev must be valid, we are not
- * removing the device and the device has not erred on us.
- */
-#define USBVISION_IS_OPERATIONAL(udevice) (\
- (udevice != NULL) && \
- ((udevice)->dev != NULL) && \
- ((udevice)->last_error == 0) && \
- (!(udevice)->remove_pending))
-
-#define I2C_USB_ADAP_MAX 16
-
-#define USBVISION_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC | V4L2_STD_SECAM | V4L2_STD_PAL_M)
-
-/* ----------------------------------------------------------------- */
-/* usbvision video structures */
-/* ----------------------------------------------------------------- */
-enum scan_state {
- scan_state_scanning, /* Scanning for header */
- scan_state_lines /* Parsing lines */
-};
-
-/* Completion states of the data parser */
-enum parse_state {
- parse_state_continue, /* Just parse next item */
- parse_state_next_frame, /* Frame done, send it to V4L */
- parse_state_out, /* Not enough data for frame */
- parse_state_end_parse /* End parsing */
-};
-
-enum frame_state {
- frame_state_unused, /* Unused (no MCAPTURE) */
- frame_state_ready, /* Ready to start grabbing */
- frame_state_grabbing, /* In the process of being grabbed into */
- frame_state_done, /* Finished grabbing, but not been synced yet */
- frame_state_done_hold, /* Are syncing or reading */
- frame_state_error, /* Something bad happened while processing */
-};
-
-/* stream states */
-enum stream_state {
- stream_off, /* Driver streaming is completely OFF */
- stream_idle, /* Driver streaming is ready to be put ON by the application */
- stream_interrupt, /* Driver streaming must be interrupted */
- stream_on, /* Driver streaming is put ON by the application */
-};
-
-enum isoc_state {
- isoc_state_in_frame, /* Isoc packet is member of frame */
- isoc_state_no_frame, /* Isoc packet is not member of any frame */
-};
-
-struct usb_device;
-
-struct usbvision_sbuf {
- char *data;
- struct urb *urb;
-};
-
-#define USBVISION_MAGIC_1 0x55
-#define USBVISION_MAGIC_2 0xAA
-#define USBVISION_HEADER_LENGTH 0x0c
-#define USBVISION_SAA7111_ADDR 0x48
-#define USBVISION_SAA7113_ADDR 0x4a
-#define USBVISION_IIC_LRACK 0x20
-#define USBVISION_IIC_LRNACK 0x30
-#define USBVISION_FRAME_FORMAT_PARAM_INTRA (1<<7)
-
-struct usbvision_v4l2_format_st {
- int supported;
- int bytes_per_pixel;
- int depth;
- int format;
- char *desc;
-};
-#define USBVISION_SUPPORTED_PALETTES ARRAY_SIZE(usbvision_v4l2_format)
-
-struct usbvision_frame_header {
- unsigned char magic_1; /* 0 magic */
- unsigned char magic_2; /* 1 magic */
- unsigned char header_length; /* 2 */
- unsigned char frame_num; /* 3 */
- unsigned char frame_phase; /* 4 */
- unsigned char frame_latency; /* 5 */
- unsigned char data_format; /* 6 */
- unsigned char format_param; /* 7 */
- unsigned char frame_width_lo; /* 8 */
- unsigned char frame_width_hi; /* 9 */
- unsigned char frame_height_lo; /* 10 */
- unsigned char frame_height_hi; /* 11 */
- __u16 frame_width; /* 8 - 9 after endian correction*/
- __u16 frame_height; /* 10 - 11 after endian correction*/
-};
-
-struct usbvision_frame {
- char *data; /* Frame buffer */
- struct usbvision_frame_header isoc_header; /* Header from stream */
-
- int width; /* Width application is expecting */
- int height; /* Height */
- int index; /* Frame index */
- int frmwidth; /* Width the frame actually is */
- int frmheight; /* Height */
-
- volatile int grabstate; /* State of grabbing */
- int scanstate; /* State of scanning */
-
- struct list_head frame;
-
- int curline; /* Line of frame we're working on */
-
- long scanlength; /* uncompressed, raw data length of frame */
- long bytes_read; /* amount of scanlength that has been read from data */
- struct usbvision_v4l2_format_st v4l2_format; /* format the user needs*/
- int v4l2_linesize; /* bytes for one videoline*/
- struct timeval timestamp;
- int sequence; /* How many video frames we send to user */
-};
-
-#define CODEC_SAA7113 7113
-#define CODEC_SAA7111 7111
-#define CODEC_WEBCAM 3000
-#define BRIDGE_NT1003 1003
-#define BRIDGE_NT1004 1004
-#define BRIDGE_NT1005 1005
-
-struct usbvision_device_data_st {
- __u64 video_norm;
- const char *model_string;
- int interface; /* to handle special interface number like BELKIN and Hauppauge WinTV-USB II */
- __u16 codec;
- unsigned video_channels:3;
- unsigned audio_channels:2;
- unsigned radio:1;
- unsigned vbi:1;
- unsigned tuner:1;
- unsigned vin_reg1_override:1; /* Override default value with */
- unsigned vin_reg2_override:1; /* vin_reg1, vin_reg2, etc. */
- unsigned dvi_yuv_override:1;
- __u8 vin_reg1;
- __u8 vin_reg2;
- __u8 dvi_yuv;
- __u8 tuner_type;
- __s16 x_offset;
- __s16 y_offset;
-};
-
-/* Declared on usbvision-cards.c */
-extern struct usbvision_device_data_st usbvision_device_data[];
-extern struct usb_device_id usbvision_table[];
-
-struct usb_usbvision {
- struct v4l2_device v4l2_dev;
- struct video_device *vdev; /* Video Device */
- struct video_device *rdev; /* Radio Device */
-
- /* i2c Declaration Section*/
- struct i2c_adapter i2c_adap;
- int registered_i2c;
-
- struct urb *ctrl_urb;
- unsigned char ctrl_urb_buffer[8];
- int ctrl_urb_busy;
- struct usb_ctrlrequest ctrl_urb_setup;
- wait_queue_head_t ctrl_urb_wq; /* Processes waiting */
-
- /* configuration part */
- int have_tuner;
- int tuner_type;
- int bridge_type; /* NT1003, NT1004, NT1005 */
- int radio;
- int video_inputs; /* # of inputs */
- unsigned long freq;
- int audio_mute;
- int audio_channel;
- int isoc_mode; /* format of video data for the usb isoc-transfer */
- unsigned int nr; /* Number of the device */
-
- /* Device structure */
- struct usb_device *dev;
- /* usb transfer */
- int num_alt; /* Number of alternative settings */
- unsigned int *alt_max_pkt_size; /* array of max_packet_size */
- unsigned char iface; /* Video interface number */
- unsigned char iface_alt; /* Alt settings */
- unsigned char vin_reg2_preset;
- struct mutex v4l2_lock;
- struct timer_list power_off_timer;
- struct work_struct power_off_work;
- int power; /* is the device powered on? */
- int user; /* user count for exclusive use */
- int initialized; /* Had we already sent init sequence? */
- int dev_model; /* What type of USBVISION device we got? */
- enum stream_state streaming; /* Are we streaming Isochronous? */
- int last_error; /* What calamity struck us? */
- int curwidth; /* width of the frame the device is currently set to*/
- int curheight; /* height of the frame the device is currently set to*/
- int stretch_width; /* stretch-factor for frame width (from usb to screen)*/
- int stretch_height; /* stretch-factor for frame height (from usb to screen)*/
- char *fbuf; /* Videodev buffer area for mmap*/
- int max_frame_size; /* Bytes in one video frame */
- int fbuf_size; /* Videodev buffer size */
- spinlock_t queue_lock; /* spinlock for protecting mods on inqueue and outqueue */
- struct list_head inqueue, outqueue; /* queued frame list and ready to dequeue frame list */
- wait_queue_head_t wait_frame; /* Processes waiting */
- wait_queue_head_t wait_stream; /* Processes waiting */
- struct usbvision_frame *cur_frame; /* pointer to current frame, set by usbvision_find_header */
- struct usbvision_frame frame[USBVISION_NUMFRAMES]; /* frame buffer */
- int num_frames; /* number of frames allocated */
- struct usbvision_sbuf sbuf[USBVISION_NUMSBUF]; /* S buffering */
- volatile int remove_pending; /* If set then about to exit */
-
- /* Scratch space from the Isochronous Pipe.*/
- unsigned char *scratch;
- int scratch_read_ptr;
- int scratch_write_ptr;
- int scratch_headermarker[USBVISION_NUM_HEADERMARKER];
- int scratch_headermarker_read_ptr;
- int scratch_headermarker_write_ptr;
- enum isoc_state isocstate;
- struct usbvision_v4l2_format_st palette;
-
- struct v4l2_capability vcap; /* Video capabilities */
- unsigned int ctl_input; /* selected input */
- v4l2_std_id tvnorm_id; /* selected tv norm */
- unsigned char video_endp; /* 0x82 for USBVISION devices based */
-
- /* Decompression stuff: */
- unsigned char *intra_frame_buffer; /* Buffer for reference frame */
- int block_pos; /* for test only */
- int request_intra; /* 0 = normal; 1 = intra frame is requested; */
- int last_isoc_frame_num; /* check for lost isoc frames */
- int isoc_packet_size; /* need to calculate used_bandwidth */
- int used_bandwidth; /* used bandwidth 0-100%, need to set compr_level */
- int compr_level; /* How strong (100) or weak (0) is compression */
- int last_compr_level; /* How strong (100) or weak (0) was compression */
- int usb_bandwidth; /* Mbit/s */
-
- /* Statistics that can be overlayed on the screen */
- unsigned long isoc_urb_count; /* How many URBs we received so far */
- unsigned long urb_length; /* Length of last URB */
- unsigned long isoc_data_count; /* How many bytes we received */
- unsigned long header_count; /* How many frame headers we found */
- unsigned long scratch_ovf_count; /* How many times we overflowed scratch */
- unsigned long isoc_skip_count; /* How many empty ISO packets received */
- unsigned long isoc_err_count; /* How many bad ISO packets received */
- unsigned long isoc_packet_count; /* How many packets we totally got */
- unsigned long time_in_irq; /* How long do we need for interrupt */
- int isoc_measure_bandwidth_count;
- int frame_num; /* How many video frames we send to user */
- int max_strip_len; /* How big is the biggest strip */
- int comprblock_pos;
- int strip_len_errors; /* How many times was block_pos greater than strip_len */
- int strip_magic_errors;
- int strip_line_number_errors;
- int compr_block_types[4];
-};
-
-static inline struct usb_usbvision *to_usbvision(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct usb_usbvision, v4l2_dev);
-}
-
-#define call_all(usbvision, o, f, args...) \
- v4l2_device_call_all(&usbvision->v4l2_dev, 0, o, f, ##args)
-
-/* --------------------------------------------------------------- */
-/* defined in usbvision-i2c.c */
-/* i2c-algo-usb declaration */
-/* --------------------------------------------------------------- */
-
-/* ----------------------------------------------------------------------- */
-/* usbvision specific I2C functions */
-/* ----------------------------------------------------------------------- */
-int usbvision_i2c_register(struct usb_usbvision *usbvision);
-int usbvision_i2c_unregister(struct usb_usbvision *usbvision);
-
-/* defined in usbvision-core.c */
-int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg);
-int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg,
- unsigned char value);
-
-int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames);
-void usbvision_frames_free(struct usb_usbvision *usbvision);
-int usbvision_scratch_alloc(struct usb_usbvision *usbvision);
-void usbvision_scratch_free(struct usb_usbvision *usbvision);
-int usbvision_decompress_alloc(struct usb_usbvision *usbvision);
-void usbvision_decompress_free(struct usb_usbvision *usbvision);
-
-int usbvision_setup(struct usb_usbvision *usbvision, int format);
-int usbvision_init_isoc(struct usb_usbvision *usbvision);
-int usbvision_restart_isoc(struct usb_usbvision *usbvision);
-void usbvision_stop_isoc(struct usb_usbvision *usbvision);
-int usbvision_set_alternate(struct usb_usbvision *dev);
-
-int usbvision_set_audio(struct usb_usbvision *usbvision, int audio_channel);
-int usbvision_audio_off(struct usb_usbvision *usbvision);
-
-int usbvision_begin_streaming(struct usb_usbvision *usbvision);
-void usbvision_empty_framequeues(struct usb_usbvision *dev);
-int usbvision_stream_interrupt(struct usb_usbvision *dev);
-
-int usbvision_muxsel(struct usb_usbvision *usbvision, int channel);
-int usbvision_set_input(struct usb_usbvision *usbvision);
-int usbvision_set_output(struct usb_usbvision *usbvision, int width, int height);
-
-void usbvision_init_power_off_timer(struct usb_usbvision *usbvision);
-void usbvision_set_power_off_timer(struct usb_usbvision *usbvision);
-void usbvision_reset_power_off_timer(struct usb_usbvision *usbvision);
-int usbvision_power_off(struct usb_usbvision *usbvision);
-int usbvision_power_on(struct usb_usbvision *usbvision);
-
-#endif /* __LINUX_USBVISION_H */
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/uvc/Kconfig b/drivers/media/video/uvc/Kconfig
deleted file mode 100644
index 541c9f1e4c6..00000000000
--- a/drivers/media/video/uvc/Kconfig
+++ /dev/null
@@ -1,19 +0,0 @@
-config USB_VIDEO_CLASS
- tristate "USB Video Class (UVC)"
- select VIDEOBUF2_VMALLOC
- ---help---
- Support for the USB Video Class (UVC). Currently only video
- input devices, such as webcams, are supported.
-
- For more information see: <http://linux-uvc.berlios.de/>
-
-config USB_VIDEO_CLASS_INPUT_EVDEV
- bool "UVC input events device support"
- default y
- depends on USB_VIDEO_CLASS
- depends on USB_VIDEO_CLASS=INPUT || INPUT=y
- ---help---
- This option makes USB Video Class devices register an input device
- to report button events.
-
- If you are in doubt, say Y.
diff --git a/drivers/media/video/uvc/Makefile b/drivers/media/video/uvc/Makefile
deleted file mode 100644
index c26d12fdb8f..00000000000
--- a/drivers/media/video/uvc/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-uvcvideo-objs := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \
- uvc_status.o uvc_isight.o uvc_debugfs.o
-ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
-uvcvideo-objs += uvc_entity.o
-endif
-obj-$(CONFIG_USB_VIDEO_CLASS) += uvcvideo.o
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
deleted file mode 100644
index f7061a5ef1d..00000000000
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ /dev/null
@@ -1,2165 +0,0 @@
-/*
- * uvc_ctrl.c -- USB Video Class driver - Controls
- *
- * Copyright (C) 2005-2010
- * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include <linux/vmalloc.h>
-#include <linux/wait.h>
-#include <linux/atomic.h>
-#include <media/v4l2-ctrls.h>
-
-#include "uvcvideo.h"
-
-#define UVC_CTRL_DATA_CURRENT 0
-#define UVC_CTRL_DATA_BACKUP 1
-#define UVC_CTRL_DATA_MIN 2
-#define UVC_CTRL_DATA_MAX 3
-#define UVC_CTRL_DATA_RES 4
-#define UVC_CTRL_DATA_DEF 5
-#define UVC_CTRL_DATA_LAST 6
-
-/* ------------------------------------------------------------------------
- * Controls
- */
-
-static struct uvc_control_info uvc_ctrls[] = {
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_BRIGHTNESS_CONTROL,
- .index = 0,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_CONTRAST_CONTROL,
- .index = 1,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_HUE_CONTROL,
- .index = 2,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE
- | UVC_CTRL_FLAG_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_SATURATION_CONTROL,
- .index = 3,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_SHARPNESS_CONTROL,
- .index = 4,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_GAMMA_CONTROL,
- .index = 5,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
- .index = 6,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE
- | UVC_CTRL_FLAG_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
- .index = 7,
- .size = 4,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE
- | UVC_CTRL_FLAG_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
- .index = 8,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_GAIN_CONTROL,
- .index = 9,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
- .index = 10,
- .size = 1,
- .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
- | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_HUE_AUTO_CONTROL,
- .index = 11,
- .size = 1,
- .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
- | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
- .index = 12,
- .size = 1,
- .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
- | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
- .index = 13,
- .size = 1,
- .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
- | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_DIGITAL_MULTIPLIER_CONTROL,
- .index = 14,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL,
- .index = 15,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL,
- .index = 16,
- .size = 1,
- .flags = UVC_CTRL_FLAG_GET_CUR,
- },
- {
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_ANALOG_LOCK_STATUS_CONTROL,
- .index = 17,
- .size = 1,
- .flags = UVC_CTRL_FLAG_GET_CUR,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_SCANNING_MODE_CONTROL,
- .index = 0,
- .size = 1,
- .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
- | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_AE_MODE_CONTROL,
- .index = 1,
- .size = 1,
- .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
- | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_GET_RES
- | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_AE_PRIORITY_CONTROL,
- .index = 2,
- .size = 1,
- .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
- | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
- .index = 3,
- .size = 4,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL,
- .index = 4,
- .size = 1,
- .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL,
- .index = 5,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE
- | UVC_CTRL_FLAG_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_FOCUS_RELATIVE_CONTROL,
- .index = 6,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
- | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
- | UVC_CTRL_FLAG_GET_DEF
- | UVC_CTRL_FLAG_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL,
- .index = 7,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE
- | UVC_CTRL_FLAG_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_IRIS_RELATIVE_CONTROL,
- .index = 8,
- .size = 1,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL,
- .index = 9,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE
- | UVC_CTRL_FLAG_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_ZOOM_RELATIVE_CONTROL,
- .index = 10,
- .size = 3,
- .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
- | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
- | UVC_CTRL_FLAG_GET_DEF
- | UVC_CTRL_FLAG_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
- .index = 11,
- .size = 8,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE
- | UVC_CTRL_FLAG_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_PANTILT_RELATIVE_CONTROL,
- .index = 12,
- .size = 4,
- .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
- | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
- | UVC_CTRL_FLAG_GET_DEF
- | UVC_CTRL_FLAG_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_ROLL_ABSOLUTE_CONTROL,
- .index = 13,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR
- | UVC_CTRL_FLAG_GET_RANGE
- | UVC_CTRL_FLAG_RESTORE
- | UVC_CTRL_FLAG_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_ROLL_RELATIVE_CONTROL,
- .index = 14,
- .size = 2,
- .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
- | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
- | UVC_CTRL_FLAG_GET_DEF
- | UVC_CTRL_FLAG_AUTO_UPDATE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_FOCUS_AUTO_CONTROL,
- .index = 17,
- .size = 1,
- .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
- | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
- },
- {
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_PRIVACY_CONTROL,
- .index = 18,
- .size = 1,
- .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
- | UVC_CTRL_FLAG_RESTORE
- | UVC_CTRL_FLAG_AUTO_UPDATE,
- },
-};
-
-static struct uvc_menu_info power_line_frequency_controls[] = {
- { 0, "Disabled" },
- { 1, "50 Hz" },
- { 2, "60 Hz" },
-};
-
-static struct uvc_menu_info exposure_auto_controls[] = {
- { 2, "Auto Mode" },
- { 1, "Manual Mode" },
- { 4, "Shutter Priority Mode" },
- { 8, "Aperture Priority Mode" },
-};
-
-static __s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping,
- __u8 query, const __u8 *data)
-{
- __s8 zoom = (__s8)data[0];
-
- switch (query) {
- case UVC_GET_CUR:
- return (zoom == 0) ? 0 : (zoom > 0 ? data[2] : -data[2]);
-
- case UVC_GET_MIN:
- case UVC_GET_MAX:
- case UVC_GET_RES:
- case UVC_GET_DEF:
- default:
- return data[2];
- }
-}
-
-static void uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping,
- __s32 value, __u8 *data)
-{
- data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff;
- data[2] = min((int)abs(value), 0xff);
-}
-
-static struct uvc_control_mapping uvc_ctrl_mappings[] = {
- {
- .id = V4L2_CID_BRIGHTNESS,
- .name = "Brightness",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_BRIGHTNESS_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
- },
- {
- .id = V4L2_CID_CONTRAST,
- .name = "Contrast",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_CONTRAST_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_HUE,
- .name = "Hue",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_HUE_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
- .master_id = V4L2_CID_HUE_AUTO,
- .master_manual = 0,
- },
- {
- .id = V4L2_CID_SATURATION,
- .name = "Saturation",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_SATURATION_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_SHARPNESS,
- .name = "Sharpness",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_SHARPNESS_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_GAMMA,
- .name = "Gamma",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_GAMMA_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_BACKLIGHT_COMPENSATION,
- .name = "Backlight Compensation",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_GAIN,
- .name = "Gain",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_GAIN_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_POWER_LINE_FREQUENCY,
- .name = "Power Line Frequency",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
- .size = 2,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_MENU,
- .data_type = UVC_CTRL_DATA_TYPE_ENUM,
- .menu_info = power_line_frequency_controls,
- .menu_count = ARRAY_SIZE(power_line_frequency_controls),
- },
- {
- .id = V4L2_CID_HUE_AUTO,
- .name = "Hue, Auto",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_HUE_AUTO_CONTROL,
- .size = 1,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
- .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
- .slave_ids = { V4L2_CID_HUE, },
- },
- {
- .id = V4L2_CID_EXPOSURE_AUTO,
- .name = "Exposure, Auto",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_AE_MODE_CONTROL,
- .size = 4,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_MENU,
- .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
- .menu_info = exposure_auto_controls,
- .menu_count = ARRAY_SIZE(exposure_auto_controls),
- .slave_ids = { V4L2_CID_EXPOSURE_ABSOLUTE, },
- },
- {
- .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY,
- .name = "Exposure, Auto Priority",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_AE_PRIORITY_CONTROL,
- .size = 1,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
- .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
- },
- {
- .id = V4L2_CID_EXPOSURE_ABSOLUTE,
- .name = "Exposure (Absolute)",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
- .size = 32,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- .master_id = V4L2_CID_EXPOSURE_AUTO,
- .master_manual = V4L2_EXPOSURE_MANUAL,
- },
- {
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .name = "White Balance Temperature, Auto",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
- .size = 1,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
- .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
- .slave_ids = { V4L2_CID_WHITE_BALANCE_TEMPERATURE, },
- },
- {
- .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
- .name = "White Balance Temperature",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- .master_id = V4L2_CID_AUTO_WHITE_BALANCE,
- .master_manual = 0,
- },
- {
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .name = "White Balance Component, Auto",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
- .size = 1,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
- .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
- .slave_ids = { V4L2_CID_BLUE_BALANCE,
- V4L2_CID_RED_BALANCE },
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .name = "White Balance Blue Component",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
- .master_id = V4L2_CID_AUTO_WHITE_BALANCE,
- .master_manual = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .name = "White Balance Red Component",
- .entity = UVC_GUID_UVC_PROCESSING,
- .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
- .size = 16,
- .offset = 16,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
- .master_id = V4L2_CID_AUTO_WHITE_BALANCE,
- .master_manual = 0,
- },
- {
- .id = V4L2_CID_FOCUS_ABSOLUTE,
- .name = "Focus (absolute)",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- .master_id = V4L2_CID_FOCUS_AUTO,
- .master_manual = 0,
- },
- {
- .id = V4L2_CID_FOCUS_AUTO,
- .name = "Focus, Auto",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_FOCUS_AUTO_CONTROL,
- .size = 1,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
- .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
- .slave_ids = { V4L2_CID_FOCUS_ABSOLUTE, },
- },
- {
- .id = V4L2_CID_IRIS_ABSOLUTE,
- .name = "Iris, Absolute",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_IRIS_RELATIVE,
- .name = "Iris, Relative",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_IRIS_RELATIVE_CONTROL,
- .size = 8,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
- },
- {
- .id = V4L2_CID_ZOOM_ABSOLUTE,
- .name = "Zoom, Absolute",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL,
- .size = 16,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_ZOOM_CONTINUOUS,
- .name = "Zoom, Continuous",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_ZOOM_RELATIVE_CONTROL,
- .size = 0,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
- .get = uvc_ctrl_get_zoom,
- .set = uvc_ctrl_set_zoom,
- },
- {
- .id = V4L2_CID_PAN_ABSOLUTE,
- .name = "Pan (Absolute)",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
- .size = 32,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_TILT_ABSOLUTE,
- .name = "Tilt (Absolute)",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
- .size = 32,
- .offset = 32,
- .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
- .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
- },
- {
- .id = V4L2_CID_PRIVACY,
- .name = "Privacy",
- .entity = UVC_GUID_UVC_CAMERA,
- .selector = UVC_CT_PRIVACY_CONTROL,
- .size = 1,
- .offset = 0,
- .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
- .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
- },
-};
-
-/* ------------------------------------------------------------------------
- * Utility functions
- */
-
-static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id)
-{
- return ctrl->uvc_data + id * ctrl->info.size;
-}
-
-static inline int uvc_test_bit(const __u8 *data, int bit)
-{
- return (data[bit >> 3] >> (bit & 7)) & 1;
-}
-
-static inline void uvc_clear_bit(__u8 *data, int bit)
-{
- data[bit >> 3] &= ~(1 << (bit & 7));
-}
-
-/* Extract the bit string specified by mapping->offset and mapping->size
- * from the little-endian data stored at 'data' and return the result as
- * a signed 32bit integer. Sign extension will be performed if the mapping
- * references a signed data type.
- */
-static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping,
- __u8 query, const __u8 *data)
-{
- int bits = mapping->size;
- int offset = mapping->offset;
- __s32 value = 0;
- __u8 mask;
-
- data += offset / 8;
- offset &= 7;
- mask = ((1LL << bits) - 1) << offset;
-
- for (; bits > 0; data++) {
- __u8 byte = *data & mask;
- value |= offset > 0 ? (byte >> offset) : (byte << (-offset));
- bits -= 8 - (offset > 0 ? offset : 0);
- offset -= 8;
- mask = (1 << bits) - 1;
- }
-
- /* Sign-extend the value if needed. */
- if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)
- value |= -(value & (1 << (mapping->size - 1)));
-
- return value;
-}
-
-/* Set the bit string specified by mapping->offset and mapping->size
- * in the little-endian data stored at 'data' to the value 'value'.
- */
-static void uvc_set_le_value(struct uvc_control_mapping *mapping,
- __s32 value, __u8 *data)
-{
- int bits = mapping->size;
- int offset = mapping->offset;
- __u8 mask;
-
- /* According to the v4l2 spec, writing any value to a button control
- * should result in the action belonging to the button control being
- * triggered. UVC devices however want to see a 1 written -> override
- * value.
- */
- if (mapping->v4l2_type == V4L2_CTRL_TYPE_BUTTON)
- value = -1;
-
- data += offset / 8;
- offset &= 7;
-
- for (; bits > 0; data++) {
- mask = ((1LL << bits) - 1) << offset;
- *data = (*data & ~mask) | ((value << offset) & mask);
- value >>= offset ? offset : 8;
- bits -= 8 - offset;
- offset = 0;
- }
-}
-
-/* ------------------------------------------------------------------------
- * Terminal and unit management
- */
-
-static const __u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING;
-static const __u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA;
-static const __u8 uvc_media_transport_input_guid[16] =
- UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT;
-
-static int uvc_entity_match_guid(const struct uvc_entity *entity,
- const __u8 guid[16])
-{
- switch (UVC_ENTITY_TYPE(entity)) {
- case UVC_ITT_CAMERA:
- return memcmp(uvc_camera_guid, guid, 16) == 0;
-
- case UVC_ITT_MEDIA_TRANSPORT_INPUT:
- return memcmp(uvc_media_transport_input_guid, guid, 16) == 0;
-
- case UVC_VC_PROCESSING_UNIT:
- return memcmp(uvc_processing_guid, guid, 16) == 0;
-
- case UVC_VC_EXTENSION_UNIT:
- return memcmp(entity->extension.guidExtensionCode,
- guid, 16) == 0;
-
- default:
- return 0;
- }
-}
-
-/* ------------------------------------------------------------------------
- * UVC Controls
- */
-
-static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id,
- struct uvc_control_mapping **mapping, struct uvc_control **control,
- int next)
-{
- struct uvc_control *ctrl;
- struct uvc_control_mapping *map;
- unsigned int i;
-
- if (entity == NULL)
- return;
-
- for (i = 0; i < entity->ncontrols; ++i) {
- ctrl = &entity->controls[i];
- if (!ctrl->initialized)
- continue;
-
- list_for_each_entry(map, &ctrl->info.mappings, list) {
- if ((map->id == v4l2_id) && !next) {
- *control = ctrl;
- *mapping = map;
- return;
- }
-
- if ((*mapping == NULL || (*mapping)->id > map->id) &&
- (map->id > v4l2_id) && next) {
- *control = ctrl;
- *mapping = map;
- }
- }
- }
-}
-
-static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
- __u32 v4l2_id, struct uvc_control_mapping **mapping)
-{
- struct uvc_control *ctrl = NULL;
- struct uvc_entity *entity;
- int next = v4l2_id & V4L2_CTRL_FLAG_NEXT_CTRL;
-
- *mapping = NULL;
-
- /* Mask the query flags. */
- v4l2_id &= V4L2_CTRL_ID_MASK;
-
- /* Find the control. */
- list_for_each_entry(entity, &chain->entities, chain) {
- __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
- if (ctrl && !next)
- return ctrl;
- }
-
- if (ctrl == NULL && !next)
- uvc_trace(UVC_TRACE_CONTROL, "Control 0x%08x not found.\n",
- v4l2_id);
-
- return ctrl;
-}
-
-static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
- struct uvc_control *ctrl)
-{
- int ret;
-
- if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {
- ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id,
- chain->dev->intfnum, ctrl->info.selector,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF),
- ctrl->info.size);
- if (ret < 0)
- return ret;
- }
-
- if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN) {
- ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id,
- chain->dev->intfnum, ctrl->info.selector,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN),
- ctrl->info.size);
- if (ret < 0)
- return ret;
- }
- if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX) {
- ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
- chain->dev->intfnum, ctrl->info.selector,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX),
- ctrl->info.size);
- if (ret < 0)
- return ret;
- }
- if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {
- ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
- chain->dev->intfnum, ctrl->info.selector,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES),
- ctrl->info.size);
- if (ret < 0) {
- if (UVC_ENTITY_TYPE(ctrl->entity) !=
- UVC_VC_EXTENSION_UNIT)
- return ret;
-
- /* GET_RES is mandatory for XU controls, but some
- * cameras still choke on it. Ignore errors and set the
- * resolution value to zero.
- */
- uvc_warn_once(chain->dev, UVC_WARN_XU_GET_RES,
- "UVC non compliance - GET_RES failed on "
- "an XU control. Enabling workaround.\n");
- memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), 0,
- ctrl->info.size);
- }
- }
-
- ctrl->cached = 1;
- return 0;
-}
-
-static int __uvc_ctrl_get(struct uvc_video_chain *chain,
- struct uvc_control *ctrl, struct uvc_control_mapping *mapping,
- s32 *value)
-{
- struct uvc_menu_info *menu;
- unsigned int i;
- int ret;
-
- if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
- return -EINVAL;
-
- if (!ctrl->loaded) {
- ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id,
- chain->dev->intfnum, ctrl->info.selector,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
- ctrl->info.size);
- if (ret < 0)
- return ret;
-
- ctrl->loaded = 1;
- }
-
- *value = mapping->get(mapping, UVC_GET_CUR,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
-
- if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
- menu = mapping->menu_info;
- for (i = 0; i < mapping->menu_count; ++i, ++menu) {
- if (menu->value == *value) {
- *value = i;
- break;
- }
- }
- }
-
- return 0;
-}
-
-static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
- struct uvc_control *ctrl,
- struct uvc_control_mapping *mapping,
- struct v4l2_queryctrl *v4l2_ctrl)
-{
- struct uvc_control_mapping *master_map = NULL;
- struct uvc_control *master_ctrl = NULL;
- struct uvc_menu_info *menu;
- unsigned int i;
-
- memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
- v4l2_ctrl->id = mapping->id;
- v4l2_ctrl->type = mapping->v4l2_type;
- strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
- v4l2_ctrl->flags = 0;
-
- if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))
- v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
- if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
- v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
-
- if (mapping->master_id)
- __uvc_find_control(ctrl->entity, mapping->master_id,
- &master_map, &master_ctrl, 0);
- if (master_ctrl && (master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) {
- s32 val;
- int ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val);
- if (ret < 0)
- return ret;
-
- if (val != mapping->master_manual)
- v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- }
-
- if (!ctrl->cached) {
- int ret = uvc_ctrl_populate_cache(chain, ctrl);
- if (ret < 0)
- return ret;
- }
-
- if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {
- v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF));
- }
-
- switch (mapping->v4l2_type) {
- case V4L2_CTRL_TYPE_MENU:
- v4l2_ctrl->minimum = 0;
- v4l2_ctrl->maximum = mapping->menu_count - 1;
- v4l2_ctrl->step = 1;
-
- menu = mapping->menu_info;
- for (i = 0; i < mapping->menu_count; ++i, ++menu) {
- if (menu->value == v4l2_ctrl->default_value) {
- v4l2_ctrl->default_value = i;
- break;
- }
- }
-
- return 0;
-
- case V4L2_CTRL_TYPE_BOOLEAN:
- v4l2_ctrl->minimum = 0;
- v4l2_ctrl->maximum = 1;
- v4l2_ctrl->step = 1;
- return 0;
-
- case V4L2_CTRL_TYPE_BUTTON:
- v4l2_ctrl->minimum = 0;
- v4l2_ctrl->maximum = 0;
- v4l2_ctrl->step = 0;
- return 0;
-
- default:
- break;
- }
-
- if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN)
- v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
-
- if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX)
- v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
-
- if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)
- v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
-
- return 0;
-}
-
-int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
- struct v4l2_queryctrl *v4l2_ctrl)
-{
- struct uvc_control *ctrl;
- struct uvc_control_mapping *mapping;
- int ret;
-
- ret = mutex_lock_interruptible(&chain->ctrl_mutex);
- if (ret < 0)
- return -ERESTARTSYS;
-
- ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
- if (ctrl == NULL) {
- ret = -EINVAL;
- goto done;
- }
-
- ret = __uvc_query_v4l2_ctrl(chain, ctrl, mapping, v4l2_ctrl);
-done:
- mutex_unlock(&chain->ctrl_mutex);
- return ret;
-}
-
-/*
- * Mapping V4L2 controls to UVC controls can be straighforward if done well.
- * Most of the UVC controls exist in V4L2, and can be mapped directly. Some
- * must be grouped (for instance the Red Balance, Blue Balance and Do White
- * Balance V4L2 controls use the White Balance Component UVC control) or
- * otherwise translated. The approach we take here is to use a translation
- * table for the controls that can be mapped directly, and handle the others
- * manually.
- */
-int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
- struct v4l2_querymenu *query_menu)
-{
- struct uvc_menu_info *menu_info;
- struct uvc_control_mapping *mapping;
- struct uvc_control *ctrl;
- u32 index = query_menu->index;
- u32 id = query_menu->id;
- int ret;
-
- memset(query_menu, 0, sizeof(*query_menu));
- query_menu->id = id;
- query_menu->index = index;
-
- ret = mutex_lock_interruptible(&chain->ctrl_mutex);
- if (ret < 0)
- return -ERESTARTSYS;
-
- ctrl = uvc_find_control(chain, query_menu->id, &mapping);
- if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) {
- ret = -EINVAL;
- goto done;
- }
-
- if (query_menu->index >= mapping->menu_count) {
- ret = -EINVAL;
- goto done;
- }
-
- menu_info = &mapping->menu_info[query_menu->index];
-
- if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK &&
- (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) {
- s32 bitmap;
-
- if (!ctrl->cached) {
- ret = uvc_ctrl_populate_cache(chain, ctrl);
- if (ret < 0)
- goto done;
- }
-
- bitmap = mapping->get(mapping, UVC_GET_RES,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
- if (!(bitmap & menu_info->value)) {
- ret = -EINVAL;
- goto done;
- }
- }
-
- strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
-
-done:
- mutex_unlock(&chain->ctrl_mutex);
- return ret;
-}
-
-/* --------------------------------------------------------------------------
- * Ctrl event handling
- */
-
-static void uvc_ctrl_fill_event(struct uvc_video_chain *chain,
- struct v4l2_event *ev,
- struct uvc_control *ctrl,
- struct uvc_control_mapping *mapping,
- s32 value, u32 changes)
-{
- struct v4l2_queryctrl v4l2_ctrl;
-
- __uvc_query_v4l2_ctrl(chain, ctrl, mapping, &v4l2_ctrl);
-
- memset(ev->reserved, 0, sizeof(ev->reserved));
- ev->type = V4L2_EVENT_CTRL;
- ev->id = v4l2_ctrl.id;
- ev->u.ctrl.value = value;
- ev->u.ctrl.changes = changes;
- ev->u.ctrl.type = v4l2_ctrl.type;
- ev->u.ctrl.flags = v4l2_ctrl.flags;
- ev->u.ctrl.minimum = v4l2_ctrl.minimum;
- ev->u.ctrl.maximum = v4l2_ctrl.maximum;
- ev->u.ctrl.step = v4l2_ctrl.step;
- ev->u.ctrl.default_value = v4l2_ctrl.default_value;
-}
-
-static void uvc_ctrl_send_event(struct uvc_fh *handle,
- struct uvc_control *ctrl, struct uvc_control_mapping *mapping,
- s32 value, u32 changes)
-{
- struct v4l2_subscribed_event *sev;
- struct v4l2_event ev;
-
- if (list_empty(&mapping->ev_subs))
- return;
-
- uvc_ctrl_fill_event(handle->chain, &ev, ctrl, mapping, value, changes);
-
- list_for_each_entry(sev, &mapping->ev_subs, node) {
- if (sev->fh && (sev->fh != &handle->vfh ||
- (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK) ||
- (changes & V4L2_EVENT_CTRL_CH_FLAGS)))
- v4l2_event_queue_fh(sev->fh, &ev);
- }
-}
-
-static void uvc_ctrl_send_slave_event(struct uvc_fh *handle,
- struct uvc_control *master, u32 slave_id,
- const struct v4l2_ext_control *xctrls, unsigned int xctrls_count)
-{
- struct uvc_control_mapping *mapping = NULL;
- struct uvc_control *ctrl = NULL;
- u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;
- unsigned int i;
- s32 val = 0;
-
- /*
- * We can skip sending an event for the slave if the slave
- * is being modified in the same transaction.
- */
- for (i = 0; i < xctrls_count; i++) {
- if (xctrls[i].id == slave_id)
- return;
- }
-
- __uvc_find_control(master->entity, slave_id, &mapping, &ctrl, 0);
- if (ctrl == NULL)
- return;
-
- if (__uvc_ctrl_get(handle->chain, ctrl, mapping, &val) == 0)
- changes |= V4L2_EVENT_CTRL_CH_VALUE;
-
- uvc_ctrl_send_event(handle, ctrl, mapping, val, changes);
-}
-
-static void uvc_ctrl_send_events(struct uvc_fh *handle,
- const struct v4l2_ext_control *xctrls, unsigned int xctrls_count)
-{
- struct uvc_control_mapping *mapping;
- struct uvc_control *ctrl;
- u32 changes = V4L2_EVENT_CTRL_CH_VALUE;
- unsigned int i;
- unsigned int j;
-
- for (i = 0; i < xctrls_count; ++i) {
- ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping);
-
- for (j = 0; j < ARRAY_SIZE(mapping->slave_ids); ++j) {
- if (!mapping->slave_ids[j])
- break;
- uvc_ctrl_send_slave_event(handle, ctrl,
- mapping->slave_ids[j],
- xctrls, xctrls_count);
- }
-
- /*
- * If the master is being modified in the same transaction
- * flags may change too.
- */
- if (mapping->master_id) {
- for (j = 0; j < xctrls_count; j++) {
- if (xctrls[j].id == mapping->master_id) {
- changes |= V4L2_EVENT_CTRL_CH_FLAGS;
- break;
- }
- }
- }
-
- uvc_ctrl_send_event(handle, ctrl, mapping, xctrls[i].value,
- changes);
- }
-}
-
-static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
-{
- struct uvc_fh *handle = container_of(sev->fh, struct uvc_fh, vfh);
- struct uvc_control_mapping *mapping;
- struct uvc_control *ctrl;
- int ret;
-
- ret = mutex_lock_interruptible(&handle->chain->ctrl_mutex);
- if (ret < 0)
- return -ERESTARTSYS;
-
- ctrl = uvc_find_control(handle->chain, sev->id, &mapping);
- if (ctrl == NULL) {
- ret = -EINVAL;
- goto done;
- }
-
- list_add_tail(&sev->node, &mapping->ev_subs);
- if (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL) {
- struct v4l2_event ev;
- u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;
- s32 val = 0;
-
- if (__uvc_ctrl_get(handle->chain, ctrl, mapping, &val) == 0)
- changes |= V4L2_EVENT_CTRL_CH_VALUE;
-
- uvc_ctrl_fill_event(handle->chain, &ev, ctrl, mapping, val,
- changes);
- /* Mark the queue as active, allowing this initial
- event to be accepted. */
- sev->elems = elems;
- v4l2_event_queue_fh(sev->fh, &ev);
- }
-
-done:
- mutex_unlock(&handle->chain->ctrl_mutex);
- return ret;
-}
-
-static void uvc_ctrl_del_event(struct v4l2_subscribed_event *sev)
-{
- struct uvc_fh *handle = container_of(sev->fh, struct uvc_fh, vfh);
-
- mutex_lock(&handle->chain->ctrl_mutex);
- list_del(&sev->node);
- mutex_unlock(&handle->chain->ctrl_mutex);
-}
-
-const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops = {
- .add = uvc_ctrl_add_event,
- .del = uvc_ctrl_del_event,
- .replace = v4l2_ctrl_replace,
- .merge = v4l2_ctrl_merge,
-};
-
-/* --------------------------------------------------------------------------
- * Control transactions
- *
- * To make extended set operations as atomic as the hardware allows, controls
- * are handled using begin/commit/rollback operations.
- *
- * At the beginning of a set request, uvc_ctrl_begin should be called to
- * initialize the request. This function acquires the control lock.
- *
- * When setting a control, the new value is stored in the control data field
- * at position UVC_CTRL_DATA_CURRENT. The control is then marked as dirty for
- * later processing. If the UVC and V4L2 control sizes differ, the current
- * value is loaded from the hardware before storing the new value in the data
- * field.
- *
- * After processing all controls in the transaction, uvc_ctrl_commit or
- * uvc_ctrl_rollback must be called to apply the pending changes to the
- * hardware or revert them. When applying changes, all controls marked as
- * dirty will be modified in the UVC device, and the dirty flag will be
- * cleared. When reverting controls, the control data field
- * UVC_CTRL_DATA_CURRENT is reverted to its previous value
- * (UVC_CTRL_DATA_BACKUP) for all dirty controls. Both functions release the
- * control lock.
- */
-int uvc_ctrl_begin(struct uvc_video_chain *chain)
-{
- return mutex_lock_interruptible(&chain->ctrl_mutex) ? -ERESTARTSYS : 0;
-}
-
-static int uvc_ctrl_commit_entity(struct uvc_device *dev,
- struct uvc_entity *entity, int rollback)
-{
- struct uvc_control *ctrl;
- unsigned int i;
- int ret;
-
- if (entity == NULL)
- return 0;
-
- for (i = 0; i < entity->ncontrols; ++i) {
- ctrl = &entity->controls[i];
- if (!ctrl->initialized)
- continue;
-
- /* Reset the loaded flag for auto-update controls that were
- * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent
- * uvc_ctrl_get from using the cached value, and for write-only
- * controls to prevent uvc_ctrl_set from setting bits not
- * explicitly set by the user.
- */
- if (ctrl->info.flags & UVC_CTRL_FLAG_AUTO_UPDATE ||
- !(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))
- ctrl->loaded = 0;
-
- if (!ctrl->dirty)
- continue;
-
- if (!rollback)
- ret = uvc_query_ctrl(dev, UVC_SET_CUR, ctrl->entity->id,
- dev->intfnum, ctrl->info.selector,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
- ctrl->info.size);
- else
- ret = 0;
-
- if (rollback || ret < 0)
- memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
- ctrl->info.size);
-
- ctrl->dirty = 0;
-
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
- const struct v4l2_ext_control *xctrls,
- unsigned int xctrls_count)
-{
- struct uvc_video_chain *chain = handle->chain;
- struct uvc_entity *entity;
- int ret = 0;
-
- /* Find the control. */
- list_for_each_entry(entity, &chain->entities, chain) {
- ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
- if (ret < 0)
- goto done;
- }
-
- if (!rollback)
- uvc_ctrl_send_events(handle, xctrls, xctrls_count);
-done:
- mutex_unlock(&chain->ctrl_mutex);
- return ret;
-}
-
-int uvc_ctrl_get(struct uvc_video_chain *chain,
- struct v4l2_ext_control *xctrl)
-{
- struct uvc_control *ctrl;
- struct uvc_control_mapping *mapping;
-
- ctrl = uvc_find_control(chain, xctrl->id, &mapping);
- if (ctrl == NULL)
- return -EINVAL;
-
- return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
-}
-
-int uvc_ctrl_set(struct uvc_video_chain *chain,
- struct v4l2_ext_control *xctrl)
-{
- struct uvc_control *ctrl;
- struct uvc_control_mapping *mapping;
- s32 value;
- u32 step;
- s32 min;
- s32 max;
- int ret;
-
- ctrl = uvc_find_control(chain, xctrl->id, &mapping);
- if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) == 0)
- return -EINVAL;
-
- /* Clamp out of range values. */
- switch (mapping->v4l2_type) {
- case V4L2_CTRL_TYPE_INTEGER:
- if (!ctrl->cached) {
- ret = uvc_ctrl_populate_cache(chain, ctrl);
- if (ret < 0)
- return ret;
- }
-
- min = mapping->get(mapping, UVC_GET_MIN,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
- max = mapping->get(mapping, UVC_GET_MAX,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
- step = mapping->get(mapping, UVC_GET_RES,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
- if (step == 0)
- step = 1;
-
- xctrl->value = min + (xctrl->value - min + step/2) / step * step;
- xctrl->value = clamp(xctrl->value, min, max);
- value = xctrl->value;
- break;
-
- case V4L2_CTRL_TYPE_BOOLEAN:
- xctrl->value = clamp(xctrl->value, 0, 1);
- value = xctrl->value;
- break;
-
- case V4L2_CTRL_TYPE_MENU:
- if (xctrl->value < 0 || xctrl->value >= mapping->menu_count)
- return -ERANGE;
- value = mapping->menu_info[xctrl->value].value;
-
- /* Valid menu indices are reported by the GET_RES request for
- * UVC controls that support it.
- */
- if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK &&
- (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) {
- if (!ctrl->cached) {
- ret = uvc_ctrl_populate_cache(chain, ctrl);
- if (ret < 0)
- return ret;
- }
-
- step = mapping->get(mapping, UVC_GET_RES,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
- if (!(step & value))
- return -ERANGE;
- }
-
- break;
-
- default:
- value = xctrl->value;
- break;
- }
-
- /* If the mapping doesn't span the whole UVC control, the current value
- * needs to be loaded from the device to perform the read-modify-write
- * operation.
- */
- if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) {
- if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
- memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
- 0, ctrl->info.size);
- } else {
- ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
- ctrl->entity->id, chain->dev->intfnum,
- ctrl->info.selector,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
- ctrl->info.size);
- if (ret < 0)
- return ret;
- }
-
- ctrl->loaded = 1;
- }
-
- /* Backup the current value in case we need to rollback later. */
- if (!ctrl->dirty) {
- memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
- ctrl->info.size);
- }
-
- mapping->set(mapping, value,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
-
- ctrl->dirty = 1;
- ctrl->modified = 1;
- return 0;
-}
-
-/* --------------------------------------------------------------------------
- * Dynamic controls
- */
-
-static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev,
- const struct uvc_control *ctrl, struct uvc_control_info *info)
-{
- struct uvc_ctrl_fixup {
- struct usb_device_id id;
- u8 entity;
- u8 selector;
- u8 flags;
- };
-
- static const struct uvc_ctrl_fixup fixups[] = {
- { { USB_DEVICE(0x046d, 0x08c2) }, 9, 1,
- UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
- UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
- UVC_CTRL_FLAG_AUTO_UPDATE },
- { { USB_DEVICE(0x046d, 0x08cc) }, 9, 1,
- UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
- UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
- UVC_CTRL_FLAG_AUTO_UPDATE },
- { { USB_DEVICE(0x046d, 0x0994) }, 9, 1,
- UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
- UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
- UVC_CTRL_FLAG_AUTO_UPDATE },
- };
-
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(fixups); ++i) {
- if (!usb_match_one_id(dev->intf, &fixups[i].id))
- continue;
-
- if (fixups[i].entity == ctrl->entity->id &&
- fixups[i].selector == info->selector) {
- info->flags = fixups[i].flags;
- return;
- }
- }
-}
-
-/*
- * Query control information (size and flags) for XU controls.
- */
-static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
- const struct uvc_control *ctrl, struct uvc_control_info *info)
-{
- u8 *data;
- int ret;
-
- data = kmalloc(2, GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
-
- memcpy(info->entity, ctrl->entity->extension.guidExtensionCode,
- sizeof(info->entity));
- info->index = ctrl->index;
- info->selector = ctrl->index + 1;
-
- /* Query and verify the control length (GET_LEN) */
- ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id, dev->intfnum,
- info->selector, data, 2);
- if (ret < 0) {
- uvc_trace(UVC_TRACE_CONTROL,
- "GET_LEN failed on control %pUl/%u (%d).\n",
- info->entity, info->selector, ret);
- goto done;
- }
-
- info->size = le16_to_cpup((__le16 *)data);
-
- /* Query the control information (GET_INFO) */
- ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum,
- info->selector, data, 1);
- if (ret < 0) {
- uvc_trace(UVC_TRACE_CONTROL,
- "GET_INFO failed on control %pUl/%u (%d).\n",
- info->entity, info->selector, ret);
- goto done;
- }
-
- info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
- | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF
- | (data[0] & UVC_CONTROL_CAP_GET ?
- UVC_CTRL_FLAG_GET_CUR : 0)
- | (data[0] & UVC_CONTROL_CAP_SET ?
- UVC_CTRL_FLAG_SET_CUR : 0)
- | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?
- UVC_CTRL_FLAG_AUTO_UPDATE : 0);
-
- uvc_ctrl_fixup_xu_info(dev, ctrl, info);
-
- uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, "
- "flags { get %u set %u auto %u }.\n",
- info->entity, info->selector, info->size,
- (info->flags & UVC_CTRL_FLAG_GET_CUR) ? 1 : 0,
- (info->flags & UVC_CTRL_FLAG_SET_CUR) ? 1 : 0,
- (info->flags & UVC_CTRL_FLAG_AUTO_UPDATE) ? 1 : 0);
-
-done:
- kfree(data);
- return ret;
-}
-
-static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl,
- const struct uvc_control_info *info);
-
-static int uvc_ctrl_init_xu_ctrl(struct uvc_device *dev,
- struct uvc_control *ctrl)
-{
- struct uvc_control_info info;
- int ret;
-
- if (ctrl->initialized)
- return 0;
-
- ret = uvc_ctrl_fill_xu_info(dev, ctrl, &info);
- if (ret < 0)
- return ret;
-
- ret = uvc_ctrl_add_info(dev, ctrl, &info);
- if (ret < 0)
- uvc_trace(UVC_TRACE_CONTROL, "Failed to initialize control "
- "%pUl/%u on device %s entity %u\n", info.entity,
- info.selector, dev->udev->devpath, ctrl->entity->id);
-
- return ret;
-}
-
-int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
- struct uvc_xu_control_query *xqry)
-{
- struct uvc_entity *entity;
- struct uvc_control *ctrl;
- unsigned int i, found = 0;
- __u32 reqflags;
- __u16 size;
- __u8 *data = NULL;
- int ret;
-
- /* Find the extension unit. */
- list_for_each_entry(entity, &chain->entities, chain) {
- if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
- entity->id == xqry->unit)
- break;
- }
-
- if (entity->id != xqry->unit) {
- uvc_trace(UVC_TRACE_CONTROL, "Extension unit %u not found.\n",
- xqry->unit);
- return -ENOENT;
- }
-
- /* Find the control and perform delayed initialization if needed. */
- for (i = 0; i < entity->ncontrols; ++i) {
- ctrl = &entity->controls[i];
- if (ctrl->index == xqry->selector - 1) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u not found.\n",
- entity->extension.guidExtensionCode, xqry->selector);
- return -ENOENT;
- }
-
- if (mutex_lock_interruptible(&chain->ctrl_mutex))
- return -ERESTARTSYS;
-
- ret = uvc_ctrl_init_xu_ctrl(chain->dev, ctrl);
- if (ret < 0) {
- ret = -ENOENT;
- goto done;
- }
-
- /* Validate the required buffer size and flags for the request */
- reqflags = 0;
- size = ctrl->info.size;
-
- switch (xqry->query) {
- case UVC_GET_CUR:
- reqflags = UVC_CTRL_FLAG_GET_CUR;
- break;
- case UVC_GET_MIN:
- reqflags = UVC_CTRL_FLAG_GET_MIN;
- break;
- case UVC_GET_MAX:
- reqflags = UVC_CTRL_FLAG_GET_MAX;
- break;
- case UVC_GET_DEF:
- reqflags = UVC_CTRL_FLAG_GET_DEF;
- break;
- case UVC_GET_RES:
- reqflags = UVC_CTRL_FLAG_GET_RES;
- break;
- case UVC_SET_CUR:
- reqflags = UVC_CTRL_FLAG_SET_CUR;
- break;
- case UVC_GET_LEN:
- size = 2;
- break;
- case UVC_GET_INFO:
- size = 1;
- break;
- default:
- ret = -EINVAL;
- goto done;
- }
-
- if (size != xqry->size) {
- ret = -ENOBUFS;
- goto done;
- }
-
- if (reqflags && !(ctrl->info.flags & reqflags)) {
- ret = -EBADRQC;
- goto done;
- }
-
- data = kmalloc(size, GFP_KERNEL);
- if (data == NULL) {
- ret = -ENOMEM;
- goto done;
- }
-
- if (xqry->query == UVC_SET_CUR &&
- copy_from_user(data, xqry->data, size)) {
- ret = -EFAULT;
- goto done;
- }
-
- ret = uvc_query_ctrl(chain->dev, xqry->query, xqry->unit,
- chain->dev->intfnum, xqry->selector, data, size);
- if (ret < 0)
- goto done;
-
- if (xqry->query != UVC_SET_CUR &&
- copy_to_user(xqry->data, data, size))
- ret = -EFAULT;
-done:
- kfree(data);
- mutex_unlock(&chain->ctrl_mutex);
- return ret;
-}
-
-/* --------------------------------------------------------------------------
- * Suspend/resume
- */
-
-/*
- * Restore control values after resume, skipping controls that haven't been
- * changed.
- *
- * TODO
- * - Don't restore modified controls that are back to their default value.
- * - Handle restore order (Auto-Exposure Mode should be restored before
- * Exposure Time).
- */
-int uvc_ctrl_resume_device(struct uvc_device *dev)
-{
- struct uvc_control *ctrl;
- struct uvc_entity *entity;
- unsigned int i;
- int ret;
-
- /* Walk the entities list and restore controls when possible. */
- list_for_each_entry(entity, &dev->entities, list) {
-
- for (i = 0; i < entity->ncontrols; ++i) {
- ctrl = &entity->controls[i];
-
- if (!ctrl->initialized || !ctrl->modified ||
- (ctrl->info.flags & UVC_CTRL_FLAG_RESTORE) == 0)
- continue;
-
- printk(KERN_INFO "restoring control %pUl/%u/%u\n",
- ctrl->info.entity, ctrl->info.index,
- ctrl->info.selector);
- ctrl->dirty = 1;
- }
-
- ret = uvc_ctrl_commit_entity(dev, entity, 0);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-/* --------------------------------------------------------------------------
- * Control and mapping handling
- */
-
-/*
- * Add control information to a given control.
- */
-static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl,
- const struct uvc_control_info *info)
-{
- int ret = 0;
-
- memcpy(&ctrl->info, info, sizeof(*info));
- INIT_LIST_HEAD(&ctrl->info.mappings);
-
- /* Allocate an array to save control values (cur, def, max, etc.) */
- ctrl->uvc_data = kzalloc(ctrl->info.size * UVC_CTRL_DATA_LAST + 1,
- GFP_KERNEL);
- if (ctrl->uvc_data == NULL) {
- ret = -ENOMEM;
- goto done;
- }
-
- ctrl->initialized = 1;
-
- uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s "
- "entity %u\n", ctrl->info.entity, ctrl->info.selector,
- dev->udev->devpath, ctrl->entity->id);
-
-done:
- if (ret < 0)
- kfree(ctrl->uvc_data);
- return ret;
-}
-
-/*
- * Add a control mapping to a given control.
- */
-static int __uvc_ctrl_add_mapping(struct uvc_device *dev,
- struct uvc_control *ctrl, const struct uvc_control_mapping *mapping)
-{
- struct uvc_control_mapping *map;
- unsigned int size;
-
- /* Most mappings come from static kernel data and need to be duplicated.
- * Mappings that come from userspace will be unnecessarily duplicated,
- * this could be optimized.
- */
- map = kmemdup(mapping, sizeof(*mapping), GFP_KERNEL);
- if (map == NULL)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&map->ev_subs);
-
- size = sizeof(*mapping->menu_info) * mapping->menu_count;
- map->menu_info = kmemdup(mapping->menu_info, size, GFP_KERNEL);
- if (map->menu_info == NULL) {
- kfree(map);
- return -ENOMEM;
- }
-
- if (map->get == NULL)
- map->get = uvc_get_le_value;
- if (map->set == NULL)
- map->set = uvc_set_le_value;
-
- list_add_tail(&map->list, &ctrl->info.mappings);
- uvc_trace(UVC_TRACE_CONTROL,
- "Adding mapping '%s' to control %pUl/%u.\n",
- map->name, ctrl->info.entity, ctrl->info.selector);
-
- return 0;
-}
-
-int uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
- const struct uvc_control_mapping *mapping)
-{
- struct uvc_device *dev = chain->dev;
- struct uvc_control_mapping *map;
- struct uvc_entity *entity;
- struct uvc_control *ctrl;
- int found = 0;
- int ret;
-
- if (mapping->id & ~V4L2_CTRL_ID_MASK) {
- uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', control "
- "id 0x%08x is invalid.\n", mapping->name,
- mapping->id);
- return -EINVAL;
- }
-
- /* Search for the matching (GUID/CS) control on the current chain */
- list_for_each_entry(entity, &chain->entities, chain) {
- unsigned int i;
-
- if (UVC_ENTITY_TYPE(entity) != UVC_VC_EXTENSION_UNIT ||
- !uvc_entity_match_guid(entity, mapping->entity))
- continue;
-
- for (i = 0; i < entity->ncontrols; ++i) {
- ctrl = &entity->controls[i];
- if (ctrl->index == mapping->selector - 1) {
- found = 1;
- break;
- }
- }
-
- if (found)
- break;
- }
- if (!found)
- return -ENOENT;
-
- if (mutex_lock_interruptible(&chain->ctrl_mutex))
- return -ERESTARTSYS;
-
- /* Perform delayed initialization of XU controls */
- ret = uvc_ctrl_init_xu_ctrl(dev, ctrl);
- if (ret < 0) {
- ret = -ENOENT;
- goto done;
- }
-
- list_for_each_entry(map, &ctrl->info.mappings, list) {
- if (mapping->id == map->id) {
- uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', "
- "control id 0x%08x already exists.\n",
- mapping->name, mapping->id);
- ret = -EEXIST;
- goto done;
- }
- }
-
- /* Prevent excess memory consumption */
- if (atomic_inc_return(&dev->nmappings) > UVC_MAX_CONTROL_MAPPINGS) {
- atomic_dec(&dev->nmappings);
- uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', maximum "
- "mappings count (%u) exceeded.\n", mapping->name,
- UVC_MAX_CONTROL_MAPPINGS);
- ret = -ENOMEM;
- goto done;
- }
-
- ret = __uvc_ctrl_add_mapping(dev, ctrl, mapping);
- if (ret < 0)
- atomic_dec(&dev->nmappings);
-
-done:
- mutex_unlock(&chain->ctrl_mutex);
- return ret;
-}
-
-/*
- * Prune an entity of its bogus controls using a blacklist. Bogus controls
- * are currently the ones that crash the camera or unconditionally return an
- * error when queried.
- */
-static void uvc_ctrl_prune_entity(struct uvc_device *dev,
- struct uvc_entity *entity)
-{
- struct uvc_ctrl_blacklist {
- struct usb_device_id id;
- u8 index;
- };
-
- static const struct uvc_ctrl_blacklist processing_blacklist[] = {
- { { USB_DEVICE(0x13d3, 0x509b) }, 9 }, /* Gain */
- { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */
- { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */
- };
- static const struct uvc_ctrl_blacklist camera_blacklist[] = {
- { { USB_DEVICE(0x06f8, 0x3005) }, 9 }, /* Zoom, Absolute */
- };
-
- const struct uvc_ctrl_blacklist *blacklist;
- unsigned int size;
- unsigned int count;
- unsigned int i;
- u8 *controls;
-
- switch (UVC_ENTITY_TYPE(entity)) {
- case UVC_VC_PROCESSING_UNIT:
- blacklist = processing_blacklist;
- count = ARRAY_SIZE(processing_blacklist);
- controls = entity->processing.bmControls;
- size = entity->processing.bControlSize;
- break;
-
- case UVC_ITT_CAMERA:
- blacklist = camera_blacklist;
- count = ARRAY_SIZE(camera_blacklist);
- controls = entity->camera.bmControls;
- size = entity->camera.bControlSize;
- break;
-
- default:
- return;
- }
-
- for (i = 0; i < count; ++i) {
- if (!usb_match_one_id(dev->intf, &blacklist[i].id))
- continue;
-
- if (blacklist[i].index >= 8 * size ||
- !uvc_test_bit(controls, blacklist[i].index))
- continue;
-
- uvc_trace(UVC_TRACE_CONTROL, "%u/%u control is black listed, "
- "removing it.\n", entity->id, blacklist[i].index);
-
- uvc_clear_bit(controls, blacklist[i].index);
- }
-}
-
-/*
- * Add control information and hardcoded stock control mappings to the given
- * device.
- */
-static void uvc_ctrl_init_ctrl(struct uvc_device *dev, struct uvc_control *ctrl)
-{
- const struct uvc_control_info *info = uvc_ctrls;
- const struct uvc_control_info *iend = info + ARRAY_SIZE(uvc_ctrls);
- const struct uvc_control_mapping *mapping = uvc_ctrl_mappings;
- const struct uvc_control_mapping *mend =
- mapping + ARRAY_SIZE(uvc_ctrl_mappings);
-
- /* XU controls initialization requires querying the device for control
- * information. As some buggy UVC devices will crash when queried
- * repeatedly in a tight loop, delay XU controls initialization until
- * first use.
- */
- if (UVC_ENTITY_TYPE(ctrl->entity) == UVC_VC_EXTENSION_UNIT)
- return;
-
- for (; info < iend; ++info) {
- if (uvc_entity_match_guid(ctrl->entity, info->entity) &&
- ctrl->index == info->index) {
- uvc_ctrl_add_info(dev, ctrl, info);
- break;
- }
- }
-
- if (!ctrl->initialized)
- return;
-
- for (; mapping < mend; ++mapping) {
- if (uvc_entity_match_guid(ctrl->entity, mapping->entity) &&
- ctrl->info.selector == mapping->selector)
- __uvc_ctrl_add_mapping(dev, ctrl, mapping);
- }
-}
-
-/*
- * Initialize device controls.
- */
-int uvc_ctrl_init_device(struct uvc_device *dev)
-{
- struct uvc_entity *entity;
- unsigned int i;
-
- /* Walk the entities list and instantiate controls */
- list_for_each_entry(entity, &dev->entities, list) {
- struct uvc_control *ctrl;
- unsigned int bControlSize = 0, ncontrols;
- __u8 *bmControls = NULL;
-
- if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) {
- bmControls = entity->extension.bmControls;
- bControlSize = entity->extension.bControlSize;
- } else if (UVC_ENTITY_TYPE(entity) == UVC_VC_PROCESSING_UNIT) {
- bmControls = entity->processing.bmControls;
- bControlSize = entity->processing.bControlSize;
- } else if (UVC_ENTITY_TYPE(entity) == UVC_ITT_CAMERA) {
- bmControls = entity->camera.bmControls;
- bControlSize = entity->camera.bControlSize;
- }
-
- /* Remove bogus/blacklisted controls */
- uvc_ctrl_prune_entity(dev, entity);
-
- /* Count supported controls and allocate the controls array */
- ncontrols = memweight(bmControls, bControlSize);
- if (ncontrols == 0)
- continue;
-
- entity->controls = kcalloc(ncontrols, sizeof(*ctrl),
- GFP_KERNEL);
- if (entity->controls == NULL)
- return -ENOMEM;
- entity->ncontrols = ncontrols;
-
- /* Initialize all supported controls */
- ctrl = entity->controls;
- for (i = 0; i < bControlSize * 8; ++i) {
- if (uvc_test_bit(bmControls, i) == 0)
- continue;
-
- ctrl->entity = entity;
- ctrl->index = i;
-
- uvc_ctrl_init_ctrl(dev, ctrl);
- ctrl++;
- }
- }
-
- return 0;
-}
-
-/*
- * Cleanup device controls.
- */
-static void uvc_ctrl_cleanup_mappings(struct uvc_device *dev,
- struct uvc_control *ctrl)
-{
- struct uvc_control_mapping *mapping, *nm;
-
- list_for_each_entry_safe(mapping, nm, &ctrl->info.mappings, list) {
- list_del(&mapping->list);
- kfree(mapping->menu_info);
- kfree(mapping);
- }
-}
-
-void uvc_ctrl_cleanup_device(struct uvc_device *dev)
-{
- struct uvc_entity *entity;
- unsigned int i;
-
- /* Free controls and control mappings for all entities. */
- list_for_each_entry(entity, &dev->entities, list) {
- for (i = 0; i < entity->ncontrols; ++i) {
- struct uvc_control *ctrl = &entity->controls[i];
-
- if (!ctrl->initialized)
- continue;
-
- uvc_ctrl_cleanup_mappings(dev, ctrl);
- kfree(ctrl->uvc_data);
- }
-
- kfree(entity->controls);
- }
-}
diff --git a/drivers/media/video/uvc/uvc_debugfs.c b/drivers/media/video/uvc/uvc_debugfs.c
deleted file mode 100644
index 14561a5abb7..00000000000
--- a/drivers/media/video/uvc/uvc_debugfs.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * uvc_debugfs.c -- USB Video Class driver - Debugging support
- *
- * Copyright (C) 2011
- * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-
-#include "uvcvideo.h"
-
-/* -----------------------------------------------------------------------------
- * Statistics
- */
-
-#define UVC_DEBUGFS_BUF_SIZE 1024
-
-struct uvc_debugfs_buffer {
- size_t count;
- char data[UVC_DEBUGFS_BUF_SIZE];
-};
-
-static int uvc_debugfs_stats_open(struct inode *inode, struct file *file)
-{
- struct uvc_streaming *stream = inode->i_private;
- struct uvc_debugfs_buffer *buf;
-
- buf = kmalloc(sizeof(*buf), GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- buf->count = uvc_video_stats_dump(stream, buf->data, sizeof(buf->data));
-
- file->private_data = buf;
- return 0;
-}
-
-static ssize_t uvc_debugfs_stats_read(struct file *file, char __user *user_buf,
- size_t nbytes, loff_t *ppos)
-{
- struct uvc_debugfs_buffer *buf = file->private_data;
-
- return simple_read_from_buffer(user_buf, nbytes, ppos, buf->data,
- buf->count);
-}
-
-static int uvc_debugfs_stats_release(struct inode *inode, struct file *file)
-{
- kfree(file->private_data);
- file->private_data = NULL;
-
- return 0;
-}
-
-static const struct file_operations uvc_debugfs_stats_fops = {
- .owner = THIS_MODULE,
- .open = uvc_debugfs_stats_open,
- .llseek = no_llseek,
- .read = uvc_debugfs_stats_read,
- .release = uvc_debugfs_stats_release,
-};
-
-/* -----------------------------------------------------------------------------
- * Global and stream initialization/cleanup
- */
-
-static struct dentry *uvc_debugfs_root_dir;
-
-int uvc_debugfs_init_stream(struct uvc_streaming *stream)
-{
- struct usb_device *udev = stream->dev->udev;
- struct dentry *dent;
- char dir_name[32];
-
- if (uvc_debugfs_root_dir == NULL)
- return -ENODEV;
-
- sprintf(dir_name, "%u-%u", udev->bus->busnum, udev->devnum);
-
- dent = debugfs_create_dir(dir_name, uvc_debugfs_root_dir);
- if (IS_ERR_OR_NULL(dent)) {
- uvc_printk(KERN_INFO, "Unable to create debugfs %s "
- "directory.\n", dir_name);
- return -ENODEV;
- }
-
- stream->debugfs_dir = dent;
-
- dent = debugfs_create_file("stats", 0444, stream->debugfs_dir,
- stream, &uvc_debugfs_stats_fops);
- if (IS_ERR_OR_NULL(dent)) {
- uvc_printk(KERN_INFO, "Unable to create debugfs stats file.\n");
- uvc_debugfs_cleanup_stream(stream);
- return -ENODEV;
- }
-
- return 0;
-}
-
-void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream)
-{
- if (stream->debugfs_dir == NULL)
- return;
-
- debugfs_remove_recursive(stream->debugfs_dir);
- stream->debugfs_dir = NULL;
-}
-
-int uvc_debugfs_init(void)
-{
- struct dentry *dir;
-
- dir = debugfs_create_dir("uvcvideo", usb_debug_root);
- if (IS_ERR_OR_NULL(dir)) {
- uvc_printk(KERN_INFO, "Unable to create debugfs directory\n");
- return -ENODATA;
- }
-
- uvc_debugfs_root_dir = dir;
- return 0;
-}
-
-void uvc_debugfs_cleanup(void)
-{
- if (uvc_debugfs_root_dir != NULL)
- debugfs_remove_recursive(uvc_debugfs_root_dir);
-}
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
deleted file mode 100644
index 1d131720b6d..00000000000
--- a/drivers/media/video/uvc/uvc_driver.c
+++ /dev/null
@@ -1,2448 +0,0 @@
-/*
- * uvc_driver.c -- USB Video Class driver
- *
- * Copyright (C) 2005-2010
- * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-/*
- * This driver aims to support video input and ouput devices compliant with the
- * 'USB Video Class' specification.
- *
- * The driver doesn't support the deprecated v4l1 interface. It implements the
- * mmap capture method only, and doesn't do any image format conversion in
- * software. If your user-space application doesn't support YUYV or MJPEG, fix
- * it :-). Please note that the MJPEG data have been stripped from their
- * Huffman tables (DHT marker), you will need to add it back if your JPEG
- * codec can't handle MJPEG data.
- */
-
-#include <linux/atomic.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include <linux/vmalloc.h>
-#include <linux/wait.h>
-#include <linux/version.h>
-#include <asm/unaligned.h>
-
-#include <media/v4l2-common.h>
-
-#include "uvcvideo.h"
-
-#define DRIVER_AUTHOR "Laurent Pinchart " \
- "<laurent.pinchart@ideasonboard.com>"
-#define DRIVER_DESC "USB Video Class driver"
-
-unsigned int uvc_clock_param = CLOCK_MONOTONIC;
-unsigned int uvc_no_drop_param;
-static unsigned int uvc_quirks_param = -1;
-unsigned int uvc_trace_param;
-unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
-
-/* ------------------------------------------------------------------------
- * Video formats
- */
-
-static struct uvc_format_desc uvc_fmts[] = {
- {
- .name = "YUV 4:2:2 (YUYV)",
- .guid = UVC_GUID_FORMAT_YUY2,
- .fcc = V4L2_PIX_FMT_YUYV,
- },
- {
- .name = "YUV 4:2:2 (YUYV)",
- .guid = UVC_GUID_FORMAT_YUY2_ISIGHT,
- .fcc = V4L2_PIX_FMT_YUYV,
- },
- {
- .name = "YUV 4:2:0 (NV12)",
- .guid = UVC_GUID_FORMAT_NV12,
- .fcc = V4L2_PIX_FMT_NV12,
- },
- {
- .name = "MJPEG",
- .guid = UVC_GUID_FORMAT_MJPEG,
- .fcc = V4L2_PIX_FMT_MJPEG,
- },
- {
- .name = "YVU 4:2:0 (YV12)",
- .guid = UVC_GUID_FORMAT_YV12,
- .fcc = V4L2_PIX_FMT_YVU420,
- },
- {
- .name = "YUV 4:2:0 (I420)",
- .guid = UVC_GUID_FORMAT_I420,
- .fcc = V4L2_PIX_FMT_YUV420,
- },
- {
- .name = "YUV 4:2:0 (M420)",
- .guid = UVC_GUID_FORMAT_M420,
- .fcc = V4L2_PIX_FMT_M420,
- },
- {
- .name = "YUV 4:2:2 (UYVY)",
- .guid = UVC_GUID_FORMAT_UYVY,
- .fcc = V4L2_PIX_FMT_UYVY,
- },
- {
- .name = "Greyscale (8-bit)",
- .guid = UVC_GUID_FORMAT_Y800,
- .fcc = V4L2_PIX_FMT_GREY,
- },
- {
- .name = "Greyscale (16-bit)",
- .guid = UVC_GUID_FORMAT_Y16,
- .fcc = V4L2_PIX_FMT_Y16,
- },
- {
- .name = "RGB Bayer",
- .guid = UVC_GUID_FORMAT_BY8,
- .fcc = V4L2_PIX_FMT_SBGGR8,
- },
- {
- .name = "RGB565",
- .guid = UVC_GUID_FORMAT_RGBP,
- .fcc = V4L2_PIX_FMT_RGB565,
- },
- {
- .name = "H.264",
- .guid = UVC_GUID_FORMAT_H264,
- .fcc = V4L2_PIX_FMT_H264,
- },
-};
-
-/* ------------------------------------------------------------------------
- * Utility functions
- */
-
-struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts,
- __u8 epaddr)
-{
- struct usb_host_endpoint *ep;
- unsigned int i;
-
- for (i = 0; i < alts->desc.bNumEndpoints; ++i) {
- ep = &alts->endpoint[i];
- if (ep->desc.bEndpointAddress == epaddr)
- return ep;
- }
-
- return NULL;
-}
-
-static struct uvc_format_desc *uvc_format_by_guid(const __u8 guid[16])
-{
- unsigned int len = ARRAY_SIZE(uvc_fmts);
- unsigned int i;
-
- for (i = 0; i < len; ++i) {
- if (memcmp(guid, uvc_fmts[i].guid, 16) == 0)
- return &uvc_fmts[i];
- }
-
- return NULL;
-}
-
-static __u32 uvc_colorspace(const __u8 primaries)
-{
- static const __u8 colorprimaries[] = {
- 0,
- V4L2_COLORSPACE_SRGB,
- V4L2_COLORSPACE_470_SYSTEM_M,
- V4L2_COLORSPACE_470_SYSTEM_BG,
- V4L2_COLORSPACE_SMPTE170M,
- V4L2_COLORSPACE_SMPTE240M,
- };
-
- if (primaries < ARRAY_SIZE(colorprimaries))
- return colorprimaries[primaries];
-
- return 0;
-}
-
-/* Simplify a fraction using a simple continued fraction decomposition. The
- * idea here is to convert fractions such as 333333/10000000 to 1/30 using
- * 32 bit arithmetic only. The algorithm is not perfect and relies upon two
- * arbitrary parameters to remove non-significative terms from the simple
- * continued fraction decomposition. Using 8 and 333 for n_terms and threshold
- * respectively seems to give nice results.
- */
-void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator,
- unsigned int n_terms, unsigned int threshold)
-{
- uint32_t *an;
- uint32_t x, y, r;
- unsigned int i, n;
-
- an = kmalloc(n_terms * sizeof *an, GFP_KERNEL);
- if (an == NULL)
- return;
-
- /* Convert the fraction to a simple continued fraction. See
- * http://mathforum.org/dr.math/faq/faq.fractions.html
- * Stop if the current term is bigger than or equal to the given
- * threshold.
- */
- x = *numerator;
- y = *denominator;
-
- for (n = 0; n < n_terms && y != 0; ++n) {
- an[n] = x / y;
- if (an[n] >= threshold) {
- if (n < 2)
- n++;
- break;
- }
-
- r = x - an[n] * y;
- x = y;
- y = r;
- }
-
- /* Expand the simple continued fraction back to an integer fraction. */
- x = 0;
- y = 1;
-
- for (i = n; i > 0; --i) {
- r = y;
- y = an[i-1] * y + x;
- x = r;
- }
-
- *numerator = y;
- *denominator = x;
- kfree(an);
-}
-
-/* Convert a fraction to a frame interval in 100ns multiples. The idea here is
- * to compute numerator / denominator * 10000000 using 32 bit fixed point
- * arithmetic only.
- */
-uint32_t uvc_fraction_to_interval(uint32_t numerator, uint32_t denominator)
-{
- uint32_t multiplier;
-
- /* Saturate the result if the operation would overflow. */
- if (denominator == 0 ||
- numerator/denominator >= ((uint32_t)-1)/10000000)
- return (uint32_t)-1;
-
- /* Divide both the denominator and the multiplier by two until
- * numerator * multiplier doesn't overflow. If anyone knows a better
- * algorithm please let me know.
- */
- multiplier = 10000000;
- while (numerator > ((uint32_t)-1)/multiplier) {
- multiplier /= 2;
- denominator /= 2;
- }
-
- return denominator ? numerator * multiplier / denominator : 0;
-}
-
-/* ------------------------------------------------------------------------
- * Terminal and unit management
- */
-
-struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id)
-{
- struct uvc_entity *entity;
-
- list_for_each_entry(entity, &dev->entities, list) {
- if (entity->id == id)
- return entity;
- }
-
- return NULL;
-}
-
-static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
- int id, struct uvc_entity *entity)
-{
- unsigned int i;
-
- if (entity == NULL)
- entity = list_entry(&dev->entities, struct uvc_entity, list);
-
- list_for_each_entry_continue(entity, &dev->entities, list) {
- for (i = 0; i < entity->bNrInPins; ++i)
- if (entity->baSourceID[i] == id)
- return entity;
- }
-
- return NULL;
-}
-
-static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id)
-{
- struct uvc_streaming *stream;
-
- list_for_each_entry(stream, &dev->streams, list) {
- if (stream->header.bTerminalLink == id)
- return stream;
- }
-
- return NULL;
-}
-
-/* ------------------------------------------------------------------------
- * Descriptors parsing
- */
-
-static int uvc_parse_format(struct uvc_device *dev,
- struct uvc_streaming *streaming, struct uvc_format *format,
- __u32 **intervals, unsigned char *buffer, int buflen)
-{
- struct usb_interface *intf = streaming->intf;
- struct usb_host_interface *alts = intf->cur_altsetting;
- struct uvc_format_desc *fmtdesc;
- struct uvc_frame *frame;
- const unsigned char *start = buffer;
- unsigned int interval;
- unsigned int i, n;
- __u8 ftype;
-
- format->type = buffer[2];
- format->index = buffer[3];
-
- switch (buffer[2]) {
- case UVC_VS_FORMAT_UNCOMPRESSED:
- case UVC_VS_FORMAT_FRAME_BASED:
- n = buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED ? 27 : 28;
- if (buflen < n) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
- "interface %d FORMAT error\n",
- dev->udev->devnum,
- alts->desc.bInterfaceNumber);
- return -EINVAL;
- }
-
- /* Find the format descriptor from its GUID. */
- fmtdesc = uvc_format_by_guid(&buffer[5]);
-
- if (fmtdesc != NULL) {
- strlcpy(format->name, fmtdesc->name,
- sizeof format->name);
- format->fcc = fmtdesc->fcc;
- } else {
- uvc_printk(KERN_INFO, "Unknown video format %pUl\n",
- &buffer[5]);
- snprintf(format->name, sizeof(format->name), "%pUl\n",
- &buffer[5]);
- format->fcc = 0;
- }
-
- format->bpp = buffer[21];
- if (buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED) {
- ftype = UVC_VS_FRAME_UNCOMPRESSED;
- } else {
- ftype = UVC_VS_FRAME_FRAME_BASED;
- if (buffer[27])
- format->flags = UVC_FMT_FLAG_COMPRESSED;
- }
- break;
-
- case UVC_VS_FORMAT_MJPEG:
- if (buflen < 11) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
- "interface %d FORMAT error\n",
- dev->udev->devnum,
- alts->desc.bInterfaceNumber);
- return -EINVAL;
- }
-
- strlcpy(format->name, "MJPEG", sizeof format->name);
- format->fcc = V4L2_PIX_FMT_MJPEG;
- format->flags = UVC_FMT_FLAG_COMPRESSED;
- format->bpp = 0;
- ftype = UVC_VS_FRAME_MJPEG;
- break;
-
- case UVC_VS_FORMAT_DV:
- if (buflen < 9) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
- "interface %d FORMAT error\n",
- dev->udev->devnum,
- alts->desc.bInterfaceNumber);
- return -EINVAL;
- }
-
- switch (buffer[8] & 0x7f) {
- case 0:
- strlcpy(format->name, "SD-DV", sizeof format->name);
- break;
- case 1:
- strlcpy(format->name, "SDL-DV", sizeof format->name);
- break;
- case 2:
- strlcpy(format->name, "HD-DV", sizeof format->name);
- break;
- default:
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
- "interface %d: unknown DV format %u\n",
- dev->udev->devnum,
- alts->desc.bInterfaceNumber, buffer[8]);
- return -EINVAL;
- }
-
- strlcat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
- sizeof format->name);
-
- format->fcc = V4L2_PIX_FMT_DV;
- format->flags = UVC_FMT_FLAG_COMPRESSED | UVC_FMT_FLAG_STREAM;
- format->bpp = 0;
- ftype = 0;
-
- /* Create a dummy frame descriptor. */
- frame = &format->frame[0];
- memset(&format->frame[0], 0, sizeof format->frame[0]);
- frame->bFrameIntervalType = 1;
- frame->dwDefaultFrameInterval = 1;
- frame->dwFrameInterval = *intervals;
- *(*intervals)++ = 1;
- format->nframes = 1;
- break;
-
- case UVC_VS_FORMAT_MPEG2TS:
- case UVC_VS_FORMAT_STREAM_BASED:
- /* Not supported yet. */
- default:
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
- "interface %d unsupported format %u\n",
- dev->udev->devnum, alts->desc.bInterfaceNumber,
- buffer[2]);
- return -EINVAL;
- }
-
- uvc_trace(UVC_TRACE_DESCR, "Found format %s.\n", format->name);
-
- buflen -= buffer[0];
- buffer += buffer[0];
-
- /* Parse the frame descriptors. Only uncompressed, MJPEG and frame
- * based formats have frame descriptors.
- */
- while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
- buffer[2] == ftype) {
- frame = &format->frame[format->nframes];
- if (ftype != UVC_VS_FRAME_FRAME_BASED)
- n = buflen > 25 ? buffer[25] : 0;
- else
- n = buflen > 21 ? buffer[21] : 0;
-
- n = n ? n : 3;
-
- if (buflen < 26 + 4*n) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
- "interface %d FRAME error\n", dev->udev->devnum,
- alts->desc.bInterfaceNumber);
- return -EINVAL;
- }
-
- frame->bFrameIndex = buffer[3];
- frame->bmCapabilities = buffer[4];
- frame->wWidth = get_unaligned_le16(&buffer[5]);
- frame->wHeight = get_unaligned_le16(&buffer[7]);
- frame->dwMinBitRate = get_unaligned_le32(&buffer[9]);
- frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]);
- if (ftype != UVC_VS_FRAME_FRAME_BASED) {
- frame->dwMaxVideoFrameBufferSize =
- get_unaligned_le32(&buffer[17]);
- frame->dwDefaultFrameInterval =
- get_unaligned_le32(&buffer[21]);
- frame->bFrameIntervalType = buffer[25];
- } else {
- frame->dwMaxVideoFrameBufferSize = 0;
- frame->dwDefaultFrameInterval =
- get_unaligned_le32(&buffer[17]);
- frame->bFrameIntervalType = buffer[21];
- }
- frame->dwFrameInterval = *intervals;
-
- /* Several UVC chipsets screw up dwMaxVideoFrameBufferSize
- * completely. Observed behaviours range from setting the
- * value to 1.1x the actual frame size to hardwiring the
- * 16 low bits to 0. This results in a higher than necessary
- * memory usage as well as a wrong image size information. For
- * uncompressed formats this can be fixed by computing the
- * value from the frame size.
- */
- if (!(format->flags & UVC_FMT_FLAG_COMPRESSED))
- frame->dwMaxVideoFrameBufferSize = format->bpp
- * frame->wWidth * frame->wHeight / 8;
-
- /* Some bogus devices report dwMinFrameInterval equal to
- * dwMaxFrameInterval and have dwFrameIntervalStep set to
- * zero. Setting all null intervals to 1 fixes the problem and
- * some other divisions by zero that could happen.
- */
- for (i = 0; i < n; ++i) {
- interval = get_unaligned_le32(&buffer[26+4*i]);
- *(*intervals)++ = interval ? interval : 1;
- }
-
- /* Make sure that the default frame interval stays between
- * the boundaries.
- */
- n -= frame->bFrameIntervalType ? 1 : 2;
- frame->dwDefaultFrameInterval =
- min(frame->dwFrameInterval[n],
- max(frame->dwFrameInterval[0],
- frame->dwDefaultFrameInterval));
-
- if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) {
- frame->bFrameIntervalType = 1;
- frame->dwFrameInterval[0] =
- frame->dwDefaultFrameInterval;
- }
-
- uvc_trace(UVC_TRACE_DESCR, "- %ux%u (%u.%u fps)\n",
- frame->wWidth, frame->wHeight,
- 10000000/frame->dwDefaultFrameInterval,
- (100000000/frame->dwDefaultFrameInterval)%10);
-
- format->nframes++;
- buflen -= buffer[0];
- buffer += buffer[0];
- }
-
- if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
- buffer[2] == UVC_VS_STILL_IMAGE_FRAME) {
- buflen -= buffer[0];
- buffer += buffer[0];
- }
-
- if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
- buffer[2] == UVC_VS_COLORFORMAT) {
- if (buflen < 6) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
- "interface %d COLORFORMAT error\n",
- dev->udev->devnum,
- alts->desc.bInterfaceNumber);
- return -EINVAL;
- }
-
- format->colorspace = uvc_colorspace(buffer[3]);
-
- buflen -= buffer[0];
- buffer += buffer[0];
- }
-
- return buffer - start;
-}
-
-static int uvc_parse_streaming(struct uvc_device *dev,
- struct usb_interface *intf)
-{
- struct uvc_streaming *streaming = NULL;
- struct uvc_format *format;
- struct uvc_frame *frame;
- struct usb_host_interface *alts = &intf->altsetting[0];
- unsigned char *_buffer, *buffer = alts->extra;
- int _buflen, buflen = alts->extralen;
- unsigned int nformats = 0, nframes = 0, nintervals = 0;
- unsigned int size, i, n, p;
- __u32 *interval;
- __u16 psize;
- int ret = -EINVAL;
-
- if (intf->cur_altsetting->desc.bInterfaceSubClass
- != UVC_SC_VIDEOSTREAMING) {
- uvc_trace(UVC_TRACE_DESCR, "device %d interface %d isn't a "
- "video streaming interface\n", dev->udev->devnum,
- intf->altsetting[0].desc.bInterfaceNumber);
- return -EINVAL;
- }
-
- if (usb_driver_claim_interface(&uvc_driver.driver, intf, dev)) {
- uvc_trace(UVC_TRACE_DESCR, "device %d interface %d is already "
- "claimed\n", dev->udev->devnum,
- intf->altsetting[0].desc.bInterfaceNumber);
- return -EINVAL;
- }
-
- streaming = kzalloc(sizeof *streaming, GFP_KERNEL);
- if (streaming == NULL) {
- usb_driver_release_interface(&uvc_driver.driver, intf);
- return -EINVAL;
- }
-
- mutex_init(&streaming->mutex);
- streaming->dev = dev;
- streaming->intf = usb_get_intf(intf);
- streaming->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
-
- /* The Pico iMage webcam has its class-specific interface descriptors
- * after the endpoint descriptors.
- */
- if (buflen == 0) {
- for (i = 0; i < alts->desc.bNumEndpoints; ++i) {
- struct usb_host_endpoint *ep = &alts->endpoint[i];
-
- if (ep->extralen == 0)
- continue;
-
- if (ep->extralen > 2 &&
- ep->extra[1] == USB_DT_CS_INTERFACE) {
- uvc_trace(UVC_TRACE_DESCR, "trying extra data "
- "from endpoint %u.\n", i);
- buffer = alts->endpoint[i].extra;
- buflen = alts->endpoint[i].extralen;
- break;
- }
- }
- }
-
- /* Skip the standard interface descriptors. */
- while (buflen > 2 && buffer[1] != USB_DT_CS_INTERFACE) {
- buflen -= buffer[0];
- buffer += buffer[0];
- }
-
- if (buflen <= 2) {
- uvc_trace(UVC_TRACE_DESCR, "no class-specific streaming "
- "interface descriptors found.\n");
- goto error;
- }
-
- /* Parse the header descriptor. */
- switch (buffer[2]) {
- case UVC_VS_OUTPUT_HEADER:
- streaming->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- size = 9;
- break;
-
- case UVC_VS_INPUT_HEADER:
- streaming->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- size = 13;
- break;
-
- default:
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
- "%d HEADER descriptor not found.\n", dev->udev->devnum,
- alts->desc.bInterfaceNumber);
- goto error;
- }
-
- p = buflen >= 4 ? buffer[3] : 0;
- n = buflen >= size ? buffer[size-1] : 0;
-
- if (buflen < size + p*n) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
- "interface %d HEADER descriptor is invalid.\n",
- dev->udev->devnum, alts->desc.bInterfaceNumber);
- goto error;
- }
-
- streaming->header.bNumFormats = p;
- streaming->header.bEndpointAddress = buffer[6];
- if (buffer[2] == UVC_VS_INPUT_HEADER) {
- streaming->header.bmInfo = buffer[7];
- streaming->header.bTerminalLink = buffer[8];
- streaming->header.bStillCaptureMethod = buffer[9];
- streaming->header.bTriggerSupport = buffer[10];
- streaming->header.bTriggerUsage = buffer[11];
- } else {
- streaming->header.bTerminalLink = buffer[7];
- }
- streaming->header.bControlSize = n;
-
- streaming->header.bmaControls = kmemdup(&buffer[size], p * n,
- GFP_KERNEL);
- if (streaming->header.bmaControls == NULL) {
- ret = -ENOMEM;
- goto error;
- }
-
- buflen -= buffer[0];
- buffer += buffer[0];
-
- _buffer = buffer;
- _buflen = buflen;
-
- /* Count the format and frame descriptors. */
- while (_buflen > 2 && _buffer[1] == USB_DT_CS_INTERFACE) {
- switch (_buffer[2]) {
- case UVC_VS_FORMAT_UNCOMPRESSED:
- case UVC_VS_FORMAT_MJPEG:
- case UVC_VS_FORMAT_FRAME_BASED:
- nformats++;
- break;
-
- case UVC_VS_FORMAT_DV:
- /* DV format has no frame descriptor. We will create a
- * dummy frame descriptor with a dummy frame interval.
- */
- nformats++;
- nframes++;
- nintervals++;
- break;
-
- case UVC_VS_FORMAT_MPEG2TS:
- case UVC_VS_FORMAT_STREAM_BASED:
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
- "interface %d FORMAT %u is not supported.\n",
- dev->udev->devnum,
- alts->desc.bInterfaceNumber, _buffer[2]);
- break;
-
- case UVC_VS_FRAME_UNCOMPRESSED:
- case UVC_VS_FRAME_MJPEG:
- nframes++;
- if (_buflen > 25)
- nintervals += _buffer[25] ? _buffer[25] : 3;
- break;
-
- case UVC_VS_FRAME_FRAME_BASED:
- nframes++;
- if (_buflen > 21)
- nintervals += _buffer[21] ? _buffer[21] : 3;
- break;
- }
-
- _buflen -= _buffer[0];
- _buffer += _buffer[0];
- }
-
- if (nformats == 0) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
- "%d has no supported formats defined.\n",
- dev->udev->devnum, alts->desc.bInterfaceNumber);
- goto error;
- }
-
- size = nformats * sizeof *format + nframes * sizeof *frame
- + nintervals * sizeof *interval;
- format = kzalloc(size, GFP_KERNEL);
- if (format == NULL) {
- ret = -ENOMEM;
- goto error;
- }
-
- frame = (struct uvc_frame *)&format[nformats];
- interval = (__u32 *)&frame[nframes];
-
- streaming->format = format;
- streaming->nformats = nformats;
-
- /* Parse the format descriptors. */
- while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE) {
- switch (buffer[2]) {
- case UVC_VS_FORMAT_UNCOMPRESSED:
- case UVC_VS_FORMAT_MJPEG:
- case UVC_VS_FORMAT_DV:
- case UVC_VS_FORMAT_FRAME_BASED:
- format->frame = frame;
- ret = uvc_parse_format(dev, streaming, format,
- &interval, buffer, buflen);
- if (ret < 0)
- goto error;
-
- frame += format->nframes;
- format++;
-
- buflen -= ret;
- buffer += ret;
- continue;
-
- default:
- break;
- }
-
- buflen -= buffer[0];
- buffer += buffer[0];
- }
-
- if (buflen)
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
- "%d has %u bytes of trailing descriptor garbage.\n",
- dev->udev->devnum, alts->desc.bInterfaceNumber, buflen);
-
- /* Parse the alternate settings to find the maximum bandwidth. */
- for (i = 0; i < intf->num_altsetting; ++i) {
- struct usb_host_endpoint *ep;
- alts = &intf->altsetting[i];
- ep = uvc_find_endpoint(alts,
- streaming->header.bEndpointAddress);
- if (ep == NULL)
- continue;
-
- psize = le16_to_cpu(ep->desc.wMaxPacketSize);
- psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
- if (psize > streaming->maxpsize)
- streaming->maxpsize = psize;
- }
-
- list_add_tail(&streaming->list, &dev->streams);
- return 0;
-
-error:
- usb_driver_release_interface(&uvc_driver.driver, intf);
- usb_put_intf(intf);
- kfree(streaming->format);
- kfree(streaming->header.bmaControls);
- kfree(streaming);
- return ret;
-}
-
-static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
- unsigned int num_pads, unsigned int extra_size)
-{
- struct uvc_entity *entity;
- unsigned int num_inputs;
- unsigned int size;
- unsigned int i;
-
- extra_size = ALIGN(extra_size, sizeof(*entity->pads));
- num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;
- size = sizeof(*entity) + extra_size + sizeof(*entity->pads) * num_pads
- + num_inputs;
- entity = kzalloc(size, GFP_KERNEL);
- if (entity == NULL)
- return NULL;
-
- entity->id = id;
- entity->type = type;
-
- entity->num_links = 0;
- entity->num_pads = num_pads;
- entity->pads = ((void *)(entity + 1)) + extra_size;
-
- for (i = 0; i < num_inputs; ++i)
- entity->pads[i].flags = MEDIA_PAD_FL_SINK;
- if (!UVC_ENTITY_IS_OTERM(entity))
- entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE;
-
- entity->bNrInPins = num_inputs;
- entity->baSourceID = (__u8 *)(&entity->pads[num_pads]);
-
- return entity;
-}
-
-/* Parse vendor-specific extensions. */
-static int uvc_parse_vendor_control(struct uvc_device *dev,
- const unsigned char *buffer, int buflen)
-{
- struct usb_device *udev = dev->udev;
- struct usb_host_interface *alts = dev->intf->cur_altsetting;
- struct uvc_entity *unit;
- unsigned int n, p;
- int handled = 0;
-
- switch (le16_to_cpu(dev->udev->descriptor.idVendor)) {
- case 0x046d: /* Logitech */
- if (buffer[1] != 0x41 || buffer[2] != 0x01)
- break;
-
- /* Logitech implements several vendor specific functions
- * through vendor specific extension units (LXU).
- *
- * The LXU descriptors are similar to XU descriptors
- * (see "USB Device Video Class for Video Devices", section
- * 3.7.2.6 "Extension Unit Descriptor") with the following
- * differences:
- *
- * ----------------------------------------------------------
- * 0 bLength 1 Number
- * Size of this descriptor, in bytes: 24+p+n*2
- * ----------------------------------------------------------
- * 23+p+n bmControlsType N Bitmap
- * Individual bits in the set are defined:
- * 0: Absolute
- * 1: Relative
- *
- * This bitset is mapped exactly the same as bmControls.
- * ----------------------------------------------------------
- * 23+p+n*2 bReserved 1 Boolean
- * ----------------------------------------------------------
- * 24+p+n*2 iExtension 1 Index
- * Index of a string descriptor that describes this
- * extension unit.
- * ----------------------------------------------------------
- */
- p = buflen >= 22 ? buffer[21] : 0;
- n = buflen >= 25 + p ? buffer[22+p] : 0;
-
- if (buflen < 25 + p + 2*n) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
- "interface %d EXTENSION_UNIT error\n",
- udev->devnum, alts->desc.bInterfaceNumber);
- break;
- }
-
- unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3],
- p + 1, 2*n);
- if (unit == NULL)
- return -ENOMEM;
-
- memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
- unit->extension.bNumControls = buffer[20];
- memcpy(unit->baSourceID, &buffer[22], p);
- unit->extension.bControlSize = buffer[22+p];
- unit->extension.bmControls = (__u8 *)unit + sizeof(*unit);
- unit->extension.bmControlsType = (__u8 *)unit + sizeof(*unit)
- + n;
- memcpy(unit->extension.bmControls, &buffer[23+p], 2*n);
-
- if (buffer[24+p+2*n] != 0)
- usb_string(udev, buffer[24+p+2*n], unit->name,
- sizeof unit->name);
- else
- sprintf(unit->name, "Extension %u", buffer[3]);
-
- list_add_tail(&unit->list, &dev->entities);
- handled = 1;
- break;
- }
-
- return handled;
-}
-
-static int uvc_parse_standard_control(struct uvc_device *dev,
- const unsigned char *buffer, int buflen)
-{
- struct usb_device *udev = dev->udev;
- struct uvc_entity *unit, *term;
- struct usb_interface *intf;
- struct usb_host_interface *alts = dev->intf->cur_altsetting;
- unsigned int i, n, p, len;
- __u16 type;
-
- switch (buffer[2]) {
- case UVC_VC_HEADER:
- n = buflen >= 12 ? buffer[11] : 0;
-
- if (buflen < 12 || buflen < 12 + n) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
- "interface %d HEADER error\n", udev->devnum,
- alts->desc.bInterfaceNumber);
- return -EINVAL;
- }
-
- dev->uvc_version = get_unaligned_le16(&buffer[3]);
- dev->clock_frequency = get_unaligned_le32(&buffer[7]);
-
- /* Parse all USB Video Streaming interfaces. */
- for (i = 0; i < n; ++i) {
- intf = usb_ifnum_to_if(udev, buffer[12+i]);
- if (intf == NULL) {
- uvc_trace(UVC_TRACE_DESCR, "device %d "
- "interface %d doesn't exists\n",
- udev->devnum, i);
- continue;
- }
-
- uvc_parse_streaming(dev, intf);
- }
- break;
-
- case UVC_VC_INPUT_TERMINAL:
- if (buflen < 8) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
- "interface %d INPUT_TERMINAL error\n",
- udev->devnum, alts->desc.bInterfaceNumber);
- return -EINVAL;
- }
-
- /* Make sure the terminal type MSB is not null, otherwise it
- * could be confused with a unit.
- */
- type = get_unaligned_le16(&buffer[4]);
- if ((type & 0xff00) == 0) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
- "interface %d INPUT_TERMINAL %d has invalid "
- "type 0x%04x, skipping\n", udev->devnum,
- alts->desc.bInterfaceNumber,
- buffer[3], type);
- return 0;
- }
-
- n = 0;
- p = 0;
- len = 8;
-
- if (type == UVC_ITT_CAMERA) {
- n = buflen >= 15 ? buffer[14] : 0;
- len = 15;
-
- } else if (type == UVC_ITT_MEDIA_TRANSPORT_INPUT) {
- n = buflen >= 9 ? buffer[8] : 0;
- p = buflen >= 10 + n ? buffer[9+n] : 0;
- len = 10;
- }
-
- if (buflen < len + n + p) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
- "interface %d INPUT_TERMINAL error\n",
- udev->devnum, alts->desc.bInterfaceNumber);
- return -EINVAL;
- }
-
- term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],
- 1, n + p);
- if (term == NULL)
- return -ENOMEM;
-
- if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
- term->camera.bControlSize = n;
- term->camera.bmControls = (__u8 *)term + sizeof *term;
- term->camera.wObjectiveFocalLengthMin =
- get_unaligned_le16(&buffer[8]);
- term->camera.wObjectiveFocalLengthMax =
- get_unaligned_le16(&buffer[10]);
- term->camera.wOcularFocalLength =
- get_unaligned_le16(&buffer[12]);
- memcpy(term->camera.bmControls, &buffer[15], n);
- } else if (UVC_ENTITY_TYPE(term) ==
- UVC_ITT_MEDIA_TRANSPORT_INPUT) {
- term->media.bControlSize = n;
- term->media.bmControls = (__u8 *)term + sizeof *term;
- term->media.bTransportModeSize = p;
- term->media.bmTransportModes = (__u8 *)term
- + sizeof *term + n;
- memcpy(term->media.bmControls, &buffer[9], n);
- memcpy(term->media.bmTransportModes, &buffer[10+n], p);
- }
-
- if (buffer[7] != 0)
- usb_string(udev, buffer[7], term->name,
- sizeof term->name);
- else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA)
- sprintf(term->name, "Camera %u", buffer[3]);
- else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT)
- sprintf(term->name, "Media %u", buffer[3]);
- else
- sprintf(term->name, "Input %u", buffer[3]);
-
- list_add_tail(&term->list, &dev->entities);
- break;
-
- case UVC_VC_OUTPUT_TERMINAL:
- if (buflen < 9) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
- "interface %d OUTPUT_TERMINAL error\n",
- udev->devnum, alts->desc.bInterfaceNumber);
- return -EINVAL;
- }
-
- /* Make sure the terminal type MSB is not null, otherwise it
- * could be confused with a unit.
- */
- type = get_unaligned_le16(&buffer[4]);
- if ((type & 0xff00) == 0) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
- "interface %d OUTPUT_TERMINAL %d has invalid "
- "type 0x%04x, skipping\n", udev->devnum,
- alts->desc.bInterfaceNumber, buffer[3], type);
- return 0;
- }
-
- term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],
- 1, 0);
- if (term == NULL)
- return -ENOMEM;
-
- memcpy(term->baSourceID, &buffer[7], 1);
-
- if (buffer[8] != 0)
- usb_string(udev, buffer[8], term->name,
- sizeof term->name);
- else
- sprintf(term->name, "Output %u", buffer[3]);
-
- list_add_tail(&term->list, &dev->entities);
- break;
-
- case UVC_VC_SELECTOR_UNIT:
- p = buflen >= 5 ? buffer[4] : 0;
-
- if (buflen < 5 || buflen < 6 + p) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
- "interface %d SELECTOR_UNIT error\n",
- udev->devnum, alts->desc.bInterfaceNumber);
- return -EINVAL;
- }
-
- unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);
- if (unit == NULL)
- return -ENOMEM;
-
- memcpy(unit->baSourceID, &buffer[5], p);
-
- if (buffer[5+p] != 0)
- usb_string(udev, buffer[5+p], unit->name,
- sizeof unit->name);
- else
- sprintf(unit->name, "Selector %u", buffer[3]);
-
- list_add_tail(&unit->list, &dev->entities);
- break;
-
- case UVC_VC_PROCESSING_UNIT:
- n = buflen >= 8 ? buffer[7] : 0;
- p = dev->uvc_version >= 0x0110 ? 10 : 9;
-
- if (buflen < p + n) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
- "interface %d PROCESSING_UNIT error\n",
- udev->devnum, alts->desc.bInterfaceNumber);
- return -EINVAL;
- }
-
- unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);
- if (unit == NULL)
- return -ENOMEM;
-
- memcpy(unit->baSourceID, &buffer[4], 1);
- unit->processing.wMaxMultiplier =
- get_unaligned_le16(&buffer[5]);
- unit->processing.bControlSize = buffer[7];
- unit->processing.bmControls = (__u8 *)unit + sizeof *unit;
- memcpy(unit->processing.bmControls, &buffer[8], n);
- if (dev->uvc_version >= 0x0110)
- unit->processing.bmVideoStandards = buffer[9+n];
-
- if (buffer[8+n] != 0)
- usb_string(udev, buffer[8+n], unit->name,
- sizeof unit->name);
- else
- sprintf(unit->name, "Processing %u", buffer[3]);
-
- list_add_tail(&unit->list, &dev->entities);
- break;
-
- case UVC_VC_EXTENSION_UNIT:
- p = buflen >= 22 ? buffer[21] : 0;
- n = buflen >= 24 + p ? buffer[22+p] : 0;
-
- if (buflen < 24 + p + n) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
- "interface %d EXTENSION_UNIT error\n",
- udev->devnum, alts->desc.bInterfaceNumber);
- return -EINVAL;
- }
-
- unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);
- if (unit == NULL)
- return -ENOMEM;
-
- memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
- unit->extension.bNumControls = buffer[20];
- memcpy(unit->baSourceID, &buffer[22], p);
- unit->extension.bControlSize = buffer[22+p];
- unit->extension.bmControls = (__u8 *)unit + sizeof *unit;
- memcpy(unit->extension.bmControls, &buffer[23+p], n);
-
- if (buffer[23+p+n] != 0)
- usb_string(udev, buffer[23+p+n], unit->name,
- sizeof unit->name);
- else
- sprintf(unit->name, "Extension %u", buffer[3]);
-
- list_add_tail(&unit->list, &dev->entities);
- break;
-
- default:
- uvc_trace(UVC_TRACE_DESCR, "Found an unknown CS_INTERFACE "
- "descriptor (%u)\n", buffer[2]);
- break;
- }
-
- return 0;
-}
-
-static int uvc_parse_control(struct uvc_device *dev)
-{
- struct usb_host_interface *alts = dev->intf->cur_altsetting;
- unsigned char *buffer = alts->extra;
- int buflen = alts->extralen;
- int ret;
-
- /* Parse the default alternate setting only, as the UVC specification
- * defines a single alternate setting, the default alternate setting
- * zero.
- */
-
- while (buflen > 2) {
- if (uvc_parse_vendor_control(dev, buffer, buflen) ||
- buffer[1] != USB_DT_CS_INTERFACE)
- goto next_descriptor;
-
- if ((ret = uvc_parse_standard_control(dev, buffer, buflen)) < 0)
- return ret;
-
-next_descriptor:
- buflen -= buffer[0];
- buffer += buffer[0];
- }
-
- /* Check if the optional status endpoint is present. Built-in iSight
- * webcams have an interrupt endpoint but spit proprietary data that
- * don't conform to the UVC status endpoint messages. Don't try to
- * handle the interrupt endpoint for those cameras.
- */
- if (alts->desc.bNumEndpoints == 1 &&
- !(dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)) {
- struct usb_host_endpoint *ep = &alts->endpoint[0];
- struct usb_endpoint_descriptor *desc = &ep->desc;
-
- if (usb_endpoint_is_int_in(desc) &&
- le16_to_cpu(desc->wMaxPacketSize) >= 8 &&
- desc->bInterval != 0) {
- uvc_trace(UVC_TRACE_DESCR, "Found a Status endpoint "
- "(addr %02x).\n", desc->bEndpointAddress);
- dev->int_ep = ep;
- }
- }
-
- return 0;
-}
-
-/* ------------------------------------------------------------------------
- * UVC device scan
- */
-
-/*
- * Scan the UVC descriptors to locate a chain starting at an Output Terminal
- * and containing the following units:
- *
- * - one or more Output Terminals (USB Streaming or Display)
- * - zero or one Processing Unit
- * - zero, one or more single-input Selector Units
- * - zero or one multiple-input Selector Units, provided all inputs are
- * connected to input terminals
- * - zero, one or mode single-input Extension Units
- * - one or more Input Terminals (Camera, External or USB Streaming)
- *
- * The terminal and units must match on of the following structures:
- *
- * ITT_*(0) -> +---------+ +---------+ +---------+ -> TT_STREAMING(0)
- * ... | SU{0,1} | -> | PU{0,1} | -> | XU{0,n} | ...
- * ITT_*(n) -> +---------+ +---------+ +---------+ -> TT_STREAMING(n)
- *
- * +---------+ +---------+ -> OTT_*(0)
- * TT_STREAMING -> | PU{0,1} | -> | XU{0,n} | ...
- * +---------+ +---------+ -> OTT_*(n)
- *
- * The Processing Unit and Extension Units can be in any order. Additional
- * Extension Units connected to the main chain as single-unit branches are
- * also supported. Single-input Selector Units are ignored.
- */
-static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
- struct uvc_entity *entity)
-{
- switch (UVC_ENTITY_TYPE(entity)) {
- case UVC_VC_EXTENSION_UNIT:
- if (uvc_trace_param & UVC_TRACE_PROBE)
- printk(" <- XU %d", entity->id);
-
- if (entity->bNrInPins != 1) {
- uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more "
- "than 1 input pin.\n", entity->id);
- return -1;
- }
-
- break;
-
- case UVC_VC_PROCESSING_UNIT:
- if (uvc_trace_param & UVC_TRACE_PROBE)
- printk(" <- PU %d", entity->id);
-
- if (chain->processing != NULL) {
- uvc_trace(UVC_TRACE_DESCR, "Found multiple "
- "Processing Units in chain.\n");
- return -1;
- }
-
- chain->processing = entity;
- break;
-
- case UVC_VC_SELECTOR_UNIT:
- if (uvc_trace_param & UVC_TRACE_PROBE)
- printk(" <- SU %d", entity->id);
-
- /* Single-input selector units are ignored. */
- if (entity->bNrInPins == 1)
- break;
-
- if (chain->selector != NULL) {
- uvc_trace(UVC_TRACE_DESCR, "Found multiple Selector "
- "Units in chain.\n");
- return -1;
- }
-
- chain->selector = entity;
- break;
-
- case UVC_ITT_VENDOR_SPECIFIC:
- case UVC_ITT_CAMERA:
- case UVC_ITT_MEDIA_TRANSPORT_INPUT:
- if (uvc_trace_param & UVC_TRACE_PROBE)
- printk(" <- IT %d\n", entity->id);
-
- break;
-
- case UVC_OTT_VENDOR_SPECIFIC:
- case UVC_OTT_DISPLAY:
- case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
- if (uvc_trace_param & UVC_TRACE_PROBE)
- printk(" OT %d", entity->id);
-
- break;
-
- case UVC_TT_STREAMING:
- if (UVC_ENTITY_IS_ITERM(entity)) {
- if (uvc_trace_param & UVC_TRACE_PROBE)
- printk(" <- IT %d\n", entity->id);
- } else {
- if (uvc_trace_param & UVC_TRACE_PROBE)
- printk(" OT %d", entity->id);
- }
-
- break;
-
- default:
- uvc_trace(UVC_TRACE_DESCR, "Unsupported entity type "
- "0x%04x found in chain.\n", UVC_ENTITY_TYPE(entity));
- return -1;
- }
-
- list_add_tail(&entity->chain, &chain->entities);
- return 0;
-}
-
-static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
- struct uvc_entity *entity, struct uvc_entity *prev)
-{
- struct uvc_entity *forward;
- int found;
-
- /* Forward scan */
- forward = NULL;
- found = 0;
-
- while (1) {
- forward = uvc_entity_by_reference(chain->dev, entity->id,
- forward);
- if (forward == NULL)
- break;
- if (forward == prev)
- continue;
-
- switch (UVC_ENTITY_TYPE(forward)) {
- case UVC_VC_EXTENSION_UNIT:
- if (forward->bNrInPins != 1) {
- uvc_trace(UVC_TRACE_DESCR, "Extension unit %d "
- "has more than 1 input pin.\n",
- entity->id);
- return -EINVAL;
- }
-
- list_add_tail(&forward->chain, &chain->entities);
- if (uvc_trace_param & UVC_TRACE_PROBE) {
- if (!found)
- printk(" (->");
-
- printk(" XU %d", forward->id);
- found = 1;
- }
- break;
-
- case UVC_OTT_VENDOR_SPECIFIC:
- case UVC_OTT_DISPLAY:
- case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
- case UVC_TT_STREAMING:
- if (UVC_ENTITY_IS_ITERM(forward)) {
- uvc_trace(UVC_TRACE_DESCR, "Unsupported input "
- "terminal %u.\n", forward->id);
- return -EINVAL;
- }
-
- list_add_tail(&forward->chain, &chain->entities);
- if (uvc_trace_param & UVC_TRACE_PROBE) {
- if (!found)
- printk(" (->");
-
- printk(" OT %d", forward->id);
- found = 1;
- }
- break;
- }
- }
- if (found)
- printk(")");
-
- return 0;
-}
-
-static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
- struct uvc_entity **_entity)
-{
- struct uvc_entity *entity = *_entity;
- struct uvc_entity *term;
- int id = -EINVAL, i;
-
- switch (UVC_ENTITY_TYPE(entity)) {
- case UVC_VC_EXTENSION_UNIT:
- case UVC_VC_PROCESSING_UNIT:
- id = entity->baSourceID[0];
- break;
-
- case UVC_VC_SELECTOR_UNIT:
- /* Single-input selector units are ignored. */
- if (entity->bNrInPins == 1) {
- id = entity->baSourceID[0];
- break;
- }
-
- if (uvc_trace_param & UVC_TRACE_PROBE)
- printk(" <- IT");
-
- chain->selector = entity;
- for (i = 0; i < entity->bNrInPins; ++i) {
- id = entity->baSourceID[i];
- term = uvc_entity_by_id(chain->dev, id);
- if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) {
- uvc_trace(UVC_TRACE_DESCR, "Selector unit %d "
- "input %d isn't connected to an "
- "input terminal\n", entity->id, i);
- return -1;
- }
-
- if (uvc_trace_param & UVC_TRACE_PROBE)
- printk(" %d", term->id);
-
- list_add_tail(&term->chain, &chain->entities);
- uvc_scan_chain_forward(chain, term, entity);
- }
-
- if (uvc_trace_param & UVC_TRACE_PROBE)
- printk("\n");
-
- id = 0;
- break;
-
- case UVC_ITT_VENDOR_SPECIFIC:
- case UVC_ITT_CAMERA:
- case UVC_ITT_MEDIA_TRANSPORT_INPUT:
- case UVC_OTT_VENDOR_SPECIFIC:
- case UVC_OTT_DISPLAY:
- case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
- case UVC_TT_STREAMING:
- id = UVC_ENTITY_IS_OTERM(entity) ? entity->baSourceID[0] : 0;
- break;
- }
-
- if (id <= 0) {
- *_entity = NULL;
- return id;
- }
-
- entity = uvc_entity_by_id(chain->dev, id);
- if (entity == NULL) {
- uvc_trace(UVC_TRACE_DESCR, "Found reference to "
- "unknown entity %d.\n", id);
- return -EINVAL;
- }
-
- *_entity = entity;
- return 0;
-}
-
-static int uvc_scan_chain(struct uvc_video_chain *chain,
- struct uvc_entity *term)
-{
- struct uvc_entity *entity, *prev;
-
- uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain:");
-
- entity = term;
- prev = NULL;
-
- while (entity != NULL) {
- /* Entity must not be part of an existing chain */
- if (entity->chain.next || entity->chain.prev) {
- uvc_trace(UVC_TRACE_DESCR, "Found reference to "
- "entity %d already in chain.\n", entity->id);
- return -EINVAL;
- }
-
- /* Process entity */
- if (uvc_scan_chain_entity(chain, entity) < 0)
- return -EINVAL;
-
- /* Forward scan */
- if (uvc_scan_chain_forward(chain, entity, prev) < 0)
- return -EINVAL;
-
- /* Backward scan */
- prev = entity;
- if (uvc_scan_chain_backward(chain, &entity) < 0)
- return -EINVAL;
- }
-
- return 0;
-}
-
-static unsigned int uvc_print_terms(struct list_head *terms, u16 dir,
- char *buffer)
-{
- struct uvc_entity *term;
- unsigned int nterms = 0;
- char *p = buffer;
-
- list_for_each_entry(term, terms, chain) {
- if (!UVC_ENTITY_IS_TERM(term) ||
- UVC_TERM_DIRECTION(term) != dir)
- continue;
-
- if (nterms)
- p += sprintf(p, ",");
- if (++nterms >= 4) {
- p += sprintf(p, "...");
- break;
- }
- p += sprintf(p, "%u", term->id);
- }
-
- return p - buffer;
-}
-
-static const char *uvc_print_chain(struct uvc_video_chain *chain)
-{
- static char buffer[43];
- char *p = buffer;
-
- p += uvc_print_terms(&chain->entities, UVC_TERM_INPUT, p);
- p += sprintf(p, " -> ");
- uvc_print_terms(&chain->entities, UVC_TERM_OUTPUT, p);
-
- return buffer;
-}
-
-/*
- * Scan the device for video chains and register video devices.
- *
- * Chains are scanned starting at their output terminals and walked backwards.
- */
-static int uvc_scan_device(struct uvc_device *dev)
-{
- struct uvc_video_chain *chain;
- struct uvc_entity *term;
-
- list_for_each_entry(term, &dev->entities, list) {
- if (!UVC_ENTITY_IS_OTERM(term))
- continue;
-
- /* If the terminal is already included in a chain, skip it.
- * This can happen for chains that have multiple output
- * terminals, where all output terminals beside the first one
- * will be inserted in the chain in forward scans.
- */
- if (term->chain.next || term->chain.prev)
- continue;
-
- chain = kzalloc(sizeof(*chain), GFP_KERNEL);
- if (chain == NULL)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&chain->entities);
- mutex_init(&chain->ctrl_mutex);
- chain->dev = dev;
-
- if (uvc_scan_chain(chain, term) < 0) {
- kfree(chain);
- continue;
- }
-
- uvc_trace(UVC_TRACE_PROBE, "Found a valid video chain (%s).\n",
- uvc_print_chain(chain));
-
- list_add_tail(&chain->list, &dev->chains);
- }
-
- if (list_empty(&dev->chains)) {
- uvc_printk(KERN_INFO, "No valid video chain found.\n");
- return -1;
- }
-
- return 0;
-}
-
-/* ------------------------------------------------------------------------
- * Video device registration and unregistration
- */
-
-/*
- * Delete the UVC device.
- *
- * Called by the kernel when the last reference to the uvc_device structure
- * is released.
- *
- * As this function is called after or during disconnect(), all URBs have
- * already been canceled by the USB core. There is no need to kill the
- * interrupt URB manually.
- */
-static void uvc_delete(struct uvc_device *dev)
-{
- struct list_head *p, *n;
-
- usb_put_intf(dev->intf);
- usb_put_dev(dev->udev);
-
- uvc_status_cleanup(dev);
- uvc_ctrl_cleanup_device(dev);
-
- if (dev->vdev.dev)
- v4l2_device_unregister(&dev->vdev);
-#ifdef CONFIG_MEDIA_CONTROLLER
- if (media_devnode_is_registered(&dev->mdev.devnode))
- media_device_unregister(&dev->mdev);
-#endif
-
- list_for_each_safe(p, n, &dev->chains) {
- struct uvc_video_chain *chain;
- chain = list_entry(p, struct uvc_video_chain, list);
- kfree(chain);
- }
-
- list_for_each_safe(p, n, &dev->entities) {
- struct uvc_entity *entity;
- entity = list_entry(p, struct uvc_entity, list);
-#ifdef CONFIG_MEDIA_CONTROLLER
- uvc_mc_cleanup_entity(entity);
-#endif
- if (entity->vdev) {
- video_device_release(entity->vdev);
- entity->vdev = NULL;
- }
- kfree(entity);
- }
-
- list_for_each_safe(p, n, &dev->streams) {
- struct uvc_streaming *streaming;
- streaming = list_entry(p, struct uvc_streaming, list);
- usb_driver_release_interface(&uvc_driver.driver,
- streaming->intf);
- usb_put_intf(streaming->intf);
- kfree(streaming->format);
- kfree(streaming->header.bmaControls);
- kfree(streaming);
- }
-
- kfree(dev);
-}
-
-static void uvc_release(struct video_device *vdev)
-{
- struct uvc_streaming *stream = video_get_drvdata(vdev);
- struct uvc_device *dev = stream->dev;
-
- /* Decrement the registered streams count and delete the device when it
- * reaches zero.
- */
- if (atomic_dec_and_test(&dev->nstreams))
- uvc_delete(dev);
-}
-
-/*
- * Unregister the video devices.
- */
-static void uvc_unregister_video(struct uvc_device *dev)
-{
- struct uvc_streaming *stream;
-
- /* Unregistering all video devices might result in uvc_delete() being
- * called from inside the loop if there's no open file handle. To avoid
- * that, increment the stream count before iterating over the streams
- * and decrement it when done.
- */
- atomic_inc(&dev->nstreams);
-
- list_for_each_entry(stream, &dev->streams, list) {
- if (stream->vdev == NULL)
- continue;
-
- video_unregister_device(stream->vdev);
- stream->vdev = NULL;
-
- uvc_debugfs_cleanup_stream(stream);
- }
-
- /* Decrement the stream count and call uvc_delete explicitly if there
- * are no stream left.
- */
- if (atomic_dec_and_test(&dev->nstreams))
- uvc_delete(dev);
-}
-
-static int uvc_register_video(struct uvc_device *dev,
- struct uvc_streaming *stream)
-{
- struct video_device *vdev;
- int ret;
-
- /* Initialize the streaming interface with default streaming
- * parameters.
- */
- ret = uvc_video_init(stream);
- if (ret < 0) {
- uvc_printk(KERN_ERR, "Failed to initialize the device "
- "(%d).\n", ret);
- return ret;
- }
-
- uvc_debugfs_init_stream(stream);
-
- /* Register the device with V4L. */
- vdev = video_device_alloc();
- if (vdev == NULL) {
- uvc_printk(KERN_ERR, "Failed to allocate video device (%d).\n",
- ret);
- return -ENOMEM;
- }
-
- /* We already hold a reference to dev->udev. The video device will be
- * unregistered before the reference is released, so we don't need to
- * get another one.
- */
- vdev->v4l2_dev = &dev->vdev;
- vdev->fops = &uvc_fops;
- vdev->release = uvc_release;
- strlcpy(vdev->name, dev->name, sizeof vdev->name);
-
- /* Set the driver data before calling video_register_device, otherwise
- * uvc_v4l2_open might race us.
- */
- stream->vdev = vdev;
- video_set_drvdata(vdev, stream);
-
- ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
- if (ret < 0) {
- uvc_printk(KERN_ERR, "Failed to register video device (%d).\n",
- ret);
- stream->vdev = NULL;
- video_device_release(vdev);
- return ret;
- }
-
- atomic_inc(&dev->nstreams);
- return 0;
-}
-
-/*
- * Register all video devices in all chains.
- */
-static int uvc_register_terms(struct uvc_device *dev,
- struct uvc_video_chain *chain)
-{
- struct uvc_streaming *stream;
- struct uvc_entity *term;
- int ret;
-
- list_for_each_entry(term, &chain->entities, chain) {
- if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING)
- continue;
-
- stream = uvc_stream_by_id(dev, term->id);
- if (stream == NULL) {
- uvc_printk(KERN_INFO, "No streaming interface found "
- "for terminal %u.", term->id);
- continue;
- }
-
- stream->chain = chain;
- ret = uvc_register_video(dev, stream);
- if (ret < 0)
- return ret;
-
- term->vdev = stream->vdev;
- }
-
- return 0;
-}
-
-static int uvc_register_chains(struct uvc_device *dev)
-{
- struct uvc_video_chain *chain;
- int ret;
-
- list_for_each_entry(chain, &dev->chains, list) {
- ret = uvc_register_terms(dev, chain);
- if (ret < 0)
- return ret;
-
-#ifdef CONFIG_MEDIA_CONTROLLER
- ret = uvc_mc_register_entities(chain);
- if (ret < 0) {
- uvc_printk(KERN_INFO, "Failed to register entites "
- "(%d).\n", ret);
- }
-#endif
- }
-
- return 0;
-}
-
-/* ------------------------------------------------------------------------
- * USB probe, disconnect, suspend and resume
- */
-
-static int uvc_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct uvc_device *dev;
- int ret;
-
- if (id->idVendor && id->idProduct)
- uvc_trace(UVC_TRACE_PROBE, "Probing known UVC device %s "
- "(%04x:%04x)\n", udev->devpath, id->idVendor,
- id->idProduct);
- else
- uvc_trace(UVC_TRACE_PROBE, "Probing generic UVC device %s\n",
- udev->devpath);
-
- /* Allocate memory for the device and initialize it. */
- if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&dev->entities);
- INIT_LIST_HEAD(&dev->chains);
- INIT_LIST_HEAD(&dev->streams);
- atomic_set(&dev->nstreams, 0);
- atomic_set(&dev->users, 0);
- atomic_set(&dev->nmappings, 0);
-
- dev->udev = usb_get_dev(udev);
- dev->intf = usb_get_intf(intf);
- dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
- dev->quirks = (uvc_quirks_param == -1)
- ? id->driver_info : uvc_quirks_param;
-
- if (udev->product != NULL)
- strlcpy(dev->name, udev->product, sizeof dev->name);
- else
- snprintf(dev->name, sizeof dev->name,
- "UVC Camera (%04x:%04x)",
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct));
-
- /* Parse the Video Class control descriptor. */
- if (uvc_parse_control(dev) < 0) {
- uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC "
- "descriptors.\n");
- goto error;
- }
-
- uvc_printk(KERN_INFO, "Found UVC %u.%02x device %s (%04x:%04x)\n",
- dev->uvc_version >> 8, dev->uvc_version & 0xff,
- udev->product ? udev->product : "<unnamed>",
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct));
-
- if (dev->quirks != id->driver_info) {
- uvc_printk(KERN_INFO, "Forcing device quirks to 0x%x by module "
- "parameter for testing purpose.\n", dev->quirks);
- uvc_printk(KERN_INFO, "Please report required quirks to the "
- "linux-uvc-devel mailing list.\n");
- }
-
- /* Register the media and V4L2 devices. */
-#ifdef CONFIG_MEDIA_CONTROLLER
- dev->mdev.dev = &intf->dev;
- strlcpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model));
- if (udev->serial)
- strlcpy(dev->mdev.serial, udev->serial,
- sizeof(dev->mdev.serial));
- strcpy(dev->mdev.bus_info, udev->devpath);
- dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
- dev->mdev.driver_version = LINUX_VERSION_CODE;
- if (media_device_register(&dev->mdev) < 0)
- goto error;
-
- dev->vdev.mdev = &dev->mdev;
-#endif
- if (v4l2_device_register(&intf->dev, &dev->vdev) < 0)
- goto error;
-
- /* Initialize controls. */
- if (uvc_ctrl_init_device(dev) < 0)
- goto error;
-
- /* Scan the device for video chains. */
- if (uvc_scan_device(dev) < 0)
- goto error;
-
- /* Register video device nodes. */
- if (uvc_register_chains(dev) < 0)
- goto error;
-
- /* Save our data pointer in the interface data. */
- usb_set_intfdata(intf, dev);
-
- /* Initialize the interrupt URB. */
- if ((ret = uvc_status_init(dev)) < 0) {
- uvc_printk(KERN_INFO, "Unable to initialize the status "
- "endpoint (%d), status interrupt will not be "
- "supported.\n", ret);
- }
-
- uvc_trace(UVC_TRACE_PROBE, "UVC device initialized.\n");
- usb_enable_autosuspend(udev);
- return 0;
-
-error:
- uvc_unregister_video(dev);
- return -ENODEV;
-}
-
-static void uvc_disconnect(struct usb_interface *intf)
-{
- struct uvc_device *dev = usb_get_intfdata(intf);
-
- /* Set the USB interface data to NULL. This can be done outside the
- * lock, as there's no other reader.
- */
- usb_set_intfdata(intf, NULL);
-
- if (intf->cur_altsetting->desc.bInterfaceSubClass ==
- UVC_SC_VIDEOSTREAMING)
- return;
-
- dev->state |= UVC_DEV_DISCONNECTED;
-
- uvc_unregister_video(dev);
-}
-
-static int uvc_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct uvc_device *dev = usb_get_intfdata(intf);
- struct uvc_streaming *stream;
-
- uvc_trace(UVC_TRACE_SUSPEND, "Suspending interface %u\n",
- intf->cur_altsetting->desc.bInterfaceNumber);
-
- /* Controls are cached on the fly so they don't need to be saved. */
- if (intf->cur_altsetting->desc.bInterfaceSubClass ==
- UVC_SC_VIDEOCONTROL)
- return uvc_status_suspend(dev);
-
- list_for_each_entry(stream, &dev->streams, list) {
- if (stream->intf == intf)
- return uvc_video_suspend(stream);
- }
-
- uvc_trace(UVC_TRACE_SUSPEND, "Suspend: video streaming USB interface "
- "mismatch.\n");
- return -EINVAL;
-}
-
-static int __uvc_resume(struct usb_interface *intf, int reset)
-{
- struct uvc_device *dev = usb_get_intfdata(intf);
- struct uvc_streaming *stream;
-
- uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n",
- intf->cur_altsetting->desc.bInterfaceNumber);
-
- if (intf->cur_altsetting->desc.bInterfaceSubClass ==
- UVC_SC_VIDEOCONTROL) {
- if (reset) {
- int ret = uvc_ctrl_resume_device(dev);
-
- if (ret < 0)
- return ret;
- }
-
- return uvc_status_resume(dev);
- }
-
- list_for_each_entry(stream, &dev->streams, list) {
- if (stream->intf == intf)
- return uvc_video_resume(stream, reset);
- }
-
- uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB interface "
- "mismatch.\n");
- return -EINVAL;
-}
-
-static int uvc_resume(struct usb_interface *intf)
-{
- return __uvc_resume(intf, 0);
-}
-
-static int uvc_reset_resume(struct usb_interface *intf)
-{
- return __uvc_resume(intf, 1);
-}
-
-/* ------------------------------------------------------------------------
- * Module parameters
- */
-
-static int uvc_clock_param_get(char *buffer, struct kernel_param *kp)
-{
- if (uvc_clock_param == CLOCK_MONOTONIC)
- return sprintf(buffer, "CLOCK_MONOTONIC");
- else
- return sprintf(buffer, "CLOCK_REALTIME");
-}
-
-static int uvc_clock_param_set(const char *val, struct kernel_param *kp)
-{
- if (strncasecmp(val, "clock_", strlen("clock_")) == 0)
- val += strlen("clock_");
-
- if (strcasecmp(val, "monotonic") == 0)
- uvc_clock_param = CLOCK_MONOTONIC;
- else if (strcasecmp(val, "realtime") == 0)
- uvc_clock_param = CLOCK_REALTIME;
- else
- return -EINVAL;
-
- return 0;
-}
-
-module_param_call(clock, uvc_clock_param_set, uvc_clock_param_get,
- &uvc_clock_param, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(clock, "Video buffers timestamp clock");
-module_param_named(nodrop, uvc_no_drop_param, uint, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(nodrop, "Don't drop incomplete frames");
-module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(quirks, "Forced device quirks");
-module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(trace, "Trace level bitmask");
-module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
-
-/* ------------------------------------------------------------------------
- * Driver initialization and cleanup
- */
-
-/*
- * The Logitech cameras listed below have their interface class set to
- * VENDOR_SPEC because they don't announce themselves as UVC devices, even
- * though they are compliant.
- */
-static struct usb_device_id uvc_ids[] = {
- /* LogiLink Wireless Webcam */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x0416,
- .idProduct = 0xa91a,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Genius eFace 2025 */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x0458,
- .idProduct = 0x706e,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Microsoft Lifecam NX-6000 */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x045e,
- .idProduct = 0x00f8,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Microsoft Lifecam VX-7000 */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x045e,
- .idProduct = 0x0723,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Logitech Quickcam Fusion */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x046d,
- .idProduct = 0x08c1,
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0 },
- /* Logitech Quickcam Orbit MP */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x046d,
- .idProduct = 0x08c2,
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0 },
- /* Logitech Quickcam Pro for Notebook */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x046d,
- .idProduct = 0x08c3,
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0 },
- /* Logitech Quickcam Pro 5000 */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x046d,
- .idProduct = 0x08c5,
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0 },
- /* Logitech Quickcam OEM Dell Notebook */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x046d,
- .idProduct = 0x08c6,
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0 },
- /* Logitech Quickcam OEM Cisco VT Camera II */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x046d,
- .idProduct = 0x08c7,
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0 },
- /* Chicony CNF7129 (Asus EEE 100HE) */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x04f2,
- .idProduct = 0xb071,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_RESTRICT_FRAME_RATE },
- /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x058f,
- .idProduct = 0x3820,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Dell XPS m1530 */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x05a9,
- .idProduct = 0x2640,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_DEF },
- /* Apple Built-In iSight */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x05ac,
- .idProduct = 0x8501,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX
- | UVC_QUIRK_BUILTIN_ISIGHT },
- /* Foxlink ("HP Webcam" on HP Mini 5103) */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x05c8,
- .idProduct = 0x0403,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
- /* Genesys Logic USB 2.0 PC Camera */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x05e3,
- .idProduct = 0x0505,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Hercules Classic Silver */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x06f8,
- .idProduct = 0x300c,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
- /* ViMicro Vega */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x0ac8,
- .idProduct = 0x332d,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
- /* ViMicro - Minoru3D */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x0ac8,
- .idProduct = 0x3410,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
- /* ViMicro Venus - Minoru3D */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x0ac8,
- .idProduct = 0x3420,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
- /* MT6227 */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x0e8d,
- .idProduct = 0x0004,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX
- | UVC_QUIRK_PROBE_DEF },
- /* IMC Networks (Medion Akoya) */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x13d3,
- .idProduct = 0x5103,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* JMicron USB2.0 XGA WebCam */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x152d,
- .idProduct = 0x0310,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Syntek (HP Spartan) */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x174f,
- .idProduct = 0x5212,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Syntek (Samsung Q310) */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x174f,
- .idProduct = 0x5931,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Syntek (Packard Bell EasyNote MX52 */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x174f,
- .idProduct = 0x8a12,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Syntek (Asus F9SG) */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x174f,
- .idProduct = 0x8a31,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Syntek (Asus U3S) */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x174f,
- .idProduct = 0x8a33,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Syntek (JAOtech Smart Terminal) */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x174f,
- .idProduct = 0x8a34,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Miricle 307K */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x17dc,
- .idProduct = 0x0202,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Lenovo Thinkpad SL400/SL500 */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x17ef,
- .idProduct = 0x480b,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Aveo Technology USB 2.0 Camera */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x1871,
- .idProduct = 0x0306,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX
- | UVC_QUIRK_PROBE_EXTRAFIELDS },
- /* Ecamm Pico iMage */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x18cd,
- .idProduct = 0xcafe,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS },
- /* Manta MM-353 Plako */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x18ec,
- .idProduct = 0x3188,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* FSC WebCam V30S */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x18ec,
- .idProduct = 0x3288,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Arkmicro unbranded */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x18ec,
- .idProduct = 0x3290,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_DEF },
- /* The Imaging Source USB CCD cameras */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x199e,
- .idProduct = 0x8102,
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0 },
- /* Bodelin ProScopeHR */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_DEV_HI
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x19ab,
- .idProduct = 0x1000,
- .bcdDevice_hi = 0x0126,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STATUS_INTERVAL },
- /* MSI StarCam 370i */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x1b3b,
- .idProduct = 0x2951,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* SiGma Micro USB Web Camera */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x1c4f,
- .idProduct = 0x3000,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX
- | UVC_QUIRK_IGNORE_SELECTOR_UNIT },
- /* Generic USB Video Class */
- { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, uvc_ids);
-
-struct uvc_driver uvc_driver = {
- .driver = {
- .name = "uvcvideo",
- .probe = uvc_probe,
- .disconnect = uvc_disconnect,
- .suspend = uvc_suspend,
- .resume = uvc_resume,
- .reset_resume = uvc_reset_resume,
- .id_table = uvc_ids,
- .supports_autosuspend = 1,
- },
-};
-
-static int __init uvc_init(void)
-{
- int ret;
-
- uvc_debugfs_init();
-
- ret = usb_register(&uvc_driver.driver);
- if (ret < 0) {
- uvc_debugfs_cleanup();
- return ret;
- }
-
- printk(KERN_INFO DRIVER_DESC " (" DRIVER_VERSION ")\n");
- return 0;
-}
-
-static void __exit uvc_cleanup(void)
-{
- usb_deregister(&uvc_driver.driver);
- uvc_debugfs_cleanup();
-}
-
-module_init(uvc_init);
-module_exit(uvc_cleanup);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
-
diff --git a/drivers/media/video/uvc/uvc_entity.c b/drivers/media/video/uvc/uvc_entity.c
deleted file mode 100644
index 29e239911d0..00000000000
--- a/drivers/media/video/uvc/uvc_entity.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * uvc_entity.c -- USB Video Class driver
- *
- * Copyright (C) 2005-2011
- * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/videodev2.h>
-
-#include <media/v4l2-common.h>
-
-#include "uvcvideo.h"
-
-/* ------------------------------------------------------------------------
- * Video subdevices registration and unregistration
- */
-
-static int uvc_mc_register_entity(struct uvc_video_chain *chain,
- struct uvc_entity *entity)
-{
- const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
- struct media_entity *sink;
- unsigned int i;
- int ret;
-
- sink = (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING)
- ? (entity->vdev ? &entity->vdev->entity : NULL)
- : &entity->subdev.entity;
- if (sink == NULL)
- return 0;
-
- for (i = 0; i < entity->num_pads; ++i) {
- struct media_entity *source;
- struct uvc_entity *remote;
- u8 remote_pad;
-
- if (!(entity->pads[i].flags & MEDIA_PAD_FL_SINK))
- continue;
-
- remote = uvc_entity_by_id(chain->dev, entity->baSourceID[i]);
- if (remote == NULL)
- return -EINVAL;
-
- source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING)
- ? (remote->vdev ? &remote->vdev->entity : NULL)
- : &remote->subdev.entity;
- if (source == NULL)
- continue;
-
- remote_pad = remote->num_pads - 1;
- ret = media_entity_create_link(source, remote_pad,
- sink, i, flags);
- if (ret < 0)
- return ret;
- }
-
- if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING)
- return 0;
-
- return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev);
-}
-
-static struct v4l2_subdev_ops uvc_subdev_ops = {
-};
-
-void uvc_mc_cleanup_entity(struct uvc_entity *entity)
-{
- if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING)
- media_entity_cleanup(&entity->subdev.entity);
- else if (entity->vdev != NULL)
- media_entity_cleanup(&entity->vdev->entity);
-}
-
-static int uvc_mc_init_entity(struct uvc_entity *entity)
-{
- int ret;
-
- if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING) {
- v4l2_subdev_init(&entity->subdev, &uvc_subdev_ops);
- strlcpy(entity->subdev.name, entity->name,
- sizeof(entity->subdev.name));
-
- ret = media_entity_init(&entity->subdev.entity,
- entity->num_pads, entity->pads, 0);
- } else if (entity->vdev != NULL) {
- ret = media_entity_init(&entity->vdev->entity,
- entity->num_pads, entity->pads, 0);
- } else
- ret = 0;
-
- return ret;
-}
-
-int uvc_mc_register_entities(struct uvc_video_chain *chain)
-{
- struct uvc_entity *entity;
- int ret;
-
- list_for_each_entry(entity, &chain->entities, chain) {
- ret = uvc_mc_init_entity(entity);
- if (ret < 0) {
- uvc_printk(KERN_INFO, "Failed to initialize entity for "
- "entity %u\n", entity->id);
- return ret;
- }
- }
-
- list_for_each_entry(entity, &chain->entities, chain) {
- ret = uvc_mc_register_entity(chain, entity);
- if (ret < 0) {
- uvc_printk(KERN_INFO, "Failed to register entity for "
- "entity %u\n", entity->id);
- return ret;
- }
- }
-
- return 0;
-}
diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/video/uvc/uvc_isight.c
deleted file mode 100644
index 8510e7259e7..00000000000
--- a/drivers/media/video/uvc/uvc_isight.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * uvc_isight.c -- USB Video Class driver - iSight support
- *
- * Copyright (C) 2006-2007
- * Ivan N. Zlatev <contact@i-nz.net>
- * Copyright (C) 2008-2009
- * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/usb.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-
-#include "uvcvideo.h"
-
-/* Built-in iSight webcams implements most of UVC 1.0 except a
- * different packet format. Instead of sending a header at the
- * beginning of each isochronous transfer payload, the webcam sends a
- * single header per image (on its own in a packet), followed by
- * packets containing data only.
- *
- * Offset Size (bytes) Description
- * ------------------------------------------------------------------
- * 0x00 1 Header length
- * 0x01 1 Flags (UVC-compliant)
- * 0x02 4 Always equal to '11223344'
- * 0x06 8 Always equal to 'deadbeefdeadface'
- * 0x0e 16 Unknown
- *
- * The header can be prefixed by an optional, unknown-purpose byte.
- */
-
-static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf,
- const __u8 *data, unsigned int len)
-{
- static const __u8 hdr[] = {
- 0x11, 0x22, 0x33, 0x44,
- 0xde, 0xad, 0xbe, 0xef,
- 0xde, 0xad, 0xfa, 0xce
- };
-
- unsigned int maxlen, nbytes;
- __u8 *mem;
- int is_header = 0;
-
- if (buf == NULL)
- return 0;
-
- if ((len >= 14 && memcmp(&data[2], hdr, 12) == 0) ||
- (len >= 15 && memcmp(&data[3], hdr, 12) == 0)) {
- uvc_trace(UVC_TRACE_FRAME, "iSight header found\n");
- is_header = 1;
- }
-
- /* Synchronize to the input stream by waiting for a header packet. */
- if (buf->state != UVC_BUF_STATE_ACTIVE) {
- if (!is_header) {
- uvc_trace(UVC_TRACE_FRAME, "Dropping packet (out of "
- "sync).\n");
- return 0;
- }
-
- buf->state = UVC_BUF_STATE_ACTIVE;
- }
-
- /* Mark the buffer as done if we're at the beginning of a new frame.
- *
- * Empty buffers (bytesused == 0) don't trigger end of frame detection
- * as it doesn't make sense to return an empty buffer.
- */
- if (is_header && buf->bytesused != 0) {
- buf->state = UVC_BUF_STATE_DONE;
- return -EAGAIN;
- }
-
- /* Copy the video data to the buffer. Skip header packets, as they
- * contain no data.
- */
- if (!is_header) {
- maxlen = buf->length - buf->bytesused;
- mem = buf->mem + buf->bytesused;
- nbytes = min(len, maxlen);
- memcpy(mem, data, nbytes);
- buf->bytesused += nbytes;
-
- if (len > maxlen || buf->bytesused == buf->length) {
- uvc_trace(UVC_TRACE_FRAME, "Frame complete "
- "(overflow).\n");
- buf->state = UVC_BUF_STATE_DONE;
- }
- }
-
- return 0;
-}
-
-void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
- struct uvc_buffer *buf)
-{
- int ret, i;
-
- for (i = 0; i < urb->number_of_packets; ++i) {
- if (urb->iso_frame_desc[i].status < 0) {
- uvc_trace(UVC_TRACE_FRAME, "USB isochronous frame "
- "lost (%d).\n",
- urb->iso_frame_desc[i].status);
- }
-
- /* Decode the payload packet.
- * uvc_video_decode is entered twice when a frame transition
- * has been detected because the end of frame can only be
- * reliably detected when the first packet of the new frame
- * is processed. The first pass detects the transition and
- * closes the previous frame's buffer, the second pass
- * processes the data of the first payload of the new frame.
- */
- do {
- ret = isight_decode(&stream->queue, buf,
- urb->transfer_buffer +
- urb->iso_frame_desc[i].offset,
- urb->iso_frame_desc[i].actual_length);
-
- if (buf == NULL)
- break;
-
- if (buf->state == UVC_BUF_STATE_DONE ||
- buf->state == UVC_BUF_STATE_ERROR)
- buf = uvc_queue_next_buffer(&stream->queue,
- buf);
- } while (ret == -EAGAIN);
- }
-}
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
deleted file mode 100644
index 5577381b5bf..00000000000
--- a/drivers/media/video/uvc/uvc_queue.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * uvc_queue.c -- USB Video Class driver - Buffers management
- *
- * Copyright (C) 2005-2010
- * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/atomic.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include <linux/vmalloc.h>
-#include <linux/wait.h>
-#include <media/videobuf2-vmalloc.h>
-
-#include "uvcvideo.h"
-
-/* ------------------------------------------------------------------------
- * Video buffers queue management.
- *
- * Video queues is initialized by uvc_queue_init(). The function performs
- * basic initialization of the uvc_video_queue struct and never fails.
- *
- * Video buffers are managed by videobuf2. The driver uses a mutex to protect
- * the videobuf2 queue operations by serializing calls to videobuf2 and a
- * spinlock to protect the IRQ queue that holds the buffers to be processed by
- * the driver.
- */
-
-/* -----------------------------------------------------------------------------
- * videobuf2 queue operations
- */
-
-static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
- unsigned int *nbuffers, unsigned int *nplanes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
- struct uvc_streaming *stream =
- container_of(queue, struct uvc_streaming, queue);
-
- if (*nbuffers > UVC_MAX_VIDEO_BUFFERS)
- *nbuffers = UVC_MAX_VIDEO_BUFFERS;
-
- *nplanes = 1;
-
- sizes[0] = stream->ctrl.dwMaxVideoFrameSize;
-
- return 0;
-}
-
-static int uvc_buffer_prepare(struct vb2_buffer *vb)
-{
- struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
- struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf);
-
- if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
- uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n");
- return -EINVAL;
- }
-
- if (unlikely(queue->flags & UVC_QUEUE_DISCONNECTED))
- return -ENODEV;
-
- buf->state = UVC_BUF_STATE_QUEUED;
- buf->error = 0;
- buf->mem = vb2_plane_vaddr(vb, 0);
- buf->length = vb2_plane_size(vb, 0);
- if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- buf->bytesused = 0;
- else
- buf->bytesused = vb2_get_plane_payload(vb, 0);
-
- return 0;
-}
-
-static void uvc_buffer_queue(struct vb2_buffer *vb)
-{
- struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
- struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf);
- unsigned long flags;
-
- spin_lock_irqsave(&queue->irqlock, flags);
- if (likely(!(queue->flags & UVC_QUEUE_DISCONNECTED))) {
- list_add_tail(&buf->queue, &queue->irqqueue);
- } else {
- /* If the device is disconnected return the buffer to userspace
- * directly. The next QBUF call will fail with -ENODEV.
- */
- buf->state = UVC_BUF_STATE_ERROR;
- vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR);
- }
-
- spin_unlock_irqrestore(&queue->irqlock, flags);
-}
-
-static int uvc_buffer_finish(struct vb2_buffer *vb)
-{
- struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
- struct uvc_streaming *stream =
- container_of(queue, struct uvc_streaming, queue);
- struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf);
-
- uvc_video_clock_update(stream, &vb->v4l2_buf, buf);
- return 0;
-}
-
-static struct vb2_ops uvc_queue_qops = {
- .queue_setup = uvc_queue_setup,
- .buf_prepare = uvc_buffer_prepare,
- .buf_queue = uvc_buffer_queue,
- .buf_finish = uvc_buffer_finish,
-};
-
-void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
- int drop_corrupted)
-{
- queue->queue.type = type;
- queue->queue.io_modes = VB2_MMAP | VB2_USERPTR;
- queue->queue.drv_priv = queue;
- queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
- queue->queue.ops = &uvc_queue_qops;
- queue->queue.mem_ops = &vb2_vmalloc_memops;
- vb2_queue_init(&queue->queue);
-
- mutex_init(&queue->mutex);
- spin_lock_init(&queue->irqlock);
- INIT_LIST_HEAD(&queue->irqqueue);
- queue->flags = drop_corrupted ? UVC_QUEUE_DROP_CORRUPTED : 0;
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 queue operations
- */
-
-int uvc_alloc_buffers(struct uvc_video_queue *queue,
- struct v4l2_requestbuffers *rb)
-{
- int ret;
-
- mutex_lock(&queue->mutex);
- ret = vb2_reqbufs(&queue->queue, rb);
- mutex_unlock(&queue->mutex);
-
- return ret ? ret : rb->count;
-}
-
-void uvc_free_buffers(struct uvc_video_queue *queue)
-{
- mutex_lock(&queue->mutex);
- vb2_queue_release(&queue->queue);
- mutex_unlock(&queue->mutex);
-}
-
-int uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf)
-{
- int ret;
-
- mutex_lock(&queue->mutex);
- ret = vb2_querybuf(&queue->queue, buf);
- mutex_unlock(&queue->mutex);
-
- return ret;
-}
-
-int uvc_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf)
-{
- int ret;
-
- mutex_lock(&queue->mutex);
- ret = vb2_qbuf(&queue->queue, buf);
- mutex_unlock(&queue->mutex);
-
- return ret;
-}
-
-int uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf,
- int nonblocking)
-{
- int ret;
-
- mutex_lock(&queue->mutex);
- ret = vb2_dqbuf(&queue->queue, buf, nonblocking);
- mutex_unlock(&queue->mutex);
-
- return ret;
-}
-
-int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
-{
- int ret;
-
- mutex_lock(&queue->mutex);
- ret = vb2_mmap(&queue->queue, vma);
- mutex_unlock(&queue->mutex);
-
- return ret;
-}
-
-#ifndef CONFIG_MMU
-unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
- unsigned long pgoff)
-{
- unsigned long ret;
-
- mutex_lock(&queue->mutex);
- ret = vb2_get_unmapped_area(&queue->queue, 0, 0, pgoff, 0);
- mutex_unlock(&queue->mutex);
- return ret;
-}
-#endif
-
-unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
- poll_table *wait)
-{
- unsigned int ret;
-
- mutex_lock(&queue->mutex);
- ret = vb2_poll(&queue->queue, file, wait);
- mutex_unlock(&queue->mutex);
-
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- *
- */
-
-/*
- * Check if buffers have been allocated.
- */
-int uvc_queue_allocated(struct uvc_video_queue *queue)
-{
- int allocated;
-
- mutex_lock(&queue->mutex);
- allocated = vb2_is_busy(&queue->queue);
- mutex_unlock(&queue->mutex);
-
- return allocated;
-}
-
-/*
- * Enable or disable the video buffers queue.
- *
- * The queue must be enabled before starting video acquisition and must be
- * disabled after stopping it. This ensures that the video buffers queue
- * state can be properly initialized before buffers are accessed from the
- * interrupt handler.
- *
- * Enabling the video queue returns -EBUSY if the queue is already enabled.
- *
- * Disabling the video queue cancels the queue and removes all buffers from
- * the main queue.
- *
- * This function can't be called from interrupt context. Use
- * uvc_queue_cancel() instead.
- */
-int uvc_queue_enable(struct uvc_video_queue *queue, int enable)
-{
- unsigned long flags;
- int ret;
-
- mutex_lock(&queue->mutex);
- if (enable) {
- ret = vb2_streamon(&queue->queue, queue->queue.type);
- if (ret < 0)
- goto done;
-
- queue->buf_used = 0;
- } else {
- ret = vb2_streamoff(&queue->queue, queue->queue.type);
- if (ret < 0)
- goto done;
-
- spin_lock_irqsave(&queue->irqlock, flags);
- INIT_LIST_HEAD(&queue->irqqueue);
- spin_unlock_irqrestore(&queue->irqlock, flags);
- }
-
-done:
- mutex_unlock(&queue->mutex);
- return ret;
-}
-
-/*
- * Cancel the video buffers queue.
- *
- * Cancelling the queue marks all buffers on the irq queue as erroneous,
- * wakes them up and removes them from the queue.
- *
- * If the disconnect parameter is set, further calls to uvc_queue_buffer will
- * fail with -ENODEV.
- *
- * This function acquires the irq spinlock and can be called from interrupt
- * context.
- */
-void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect)
-{
- struct uvc_buffer *buf;
- unsigned long flags;
-
- spin_lock_irqsave(&queue->irqlock, flags);
- while (!list_empty(&queue->irqqueue)) {
- buf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
- queue);
- list_del(&buf->queue);
- buf->state = UVC_BUF_STATE_ERROR;
- vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR);
- }
- /* This must be protected by the irqlock spinlock to avoid race
- * conditions between uvc_buffer_queue and the disconnection event that
- * could result in an interruptible wait in uvc_dequeue_buffer. Do not
- * blindly replace this logic by checking for the UVC_QUEUE_DISCONNECTED
- * state outside the queue code.
- */
- if (disconnect)
- queue->flags |= UVC_QUEUE_DISCONNECTED;
- spin_unlock_irqrestore(&queue->irqlock, flags);
-}
-
-struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
- struct uvc_buffer *buf)
-{
- struct uvc_buffer *nextbuf;
- unsigned long flags;
-
- if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) {
- buf->error = 0;
- buf->state = UVC_BUF_STATE_QUEUED;
- buf->bytesused = 0;
- vb2_set_plane_payload(&buf->buf, 0, 0);
- return buf;
- }
-
- spin_lock_irqsave(&queue->irqlock, flags);
- list_del(&buf->queue);
- if (!list_empty(&queue->irqqueue))
- nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
- queue);
- else
- nextbuf = NULL;
- spin_unlock_irqrestore(&queue->irqlock, flags);
-
- buf->state = buf->error ? VB2_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
- vb2_set_plane_payload(&buf->buf, 0, buf->bytesused);
- vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE);
-
- return nextbuf;
-}
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c
deleted file mode 100644
index b7492775e6a..00000000000
--- a/drivers/media/video/uvc/uvc_status.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * uvc_status.c -- USB Video Class driver - Status endpoint
- *
- * Copyright (C) 2005-2009
- * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/input.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/input.h>
-
-#include "uvcvideo.h"
-
-/* --------------------------------------------------------------------------
- * Input device
- */
-#ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV
-static int uvc_input_init(struct uvc_device *dev)
-{
- struct input_dev *input;
- int ret;
-
- input = input_allocate_device();
- if (input == NULL)
- return -ENOMEM;
-
- usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys));
- strlcat(dev->input_phys, "/button", sizeof(dev->input_phys));
-
- input->name = dev->name;
- input->phys = dev->input_phys;
- usb_to_input_id(dev->udev, &input->id);
- input->dev.parent = &dev->intf->dev;
-
- __set_bit(EV_KEY, input->evbit);
- __set_bit(KEY_CAMERA, input->keybit);
-
- if ((ret = input_register_device(input)) < 0)
- goto error;
-
- dev->input = input;
- return 0;
-
-error:
- input_free_device(input);
- return ret;
-}
-
-static void uvc_input_cleanup(struct uvc_device *dev)
-{
- if (dev->input)
- input_unregister_device(dev->input);
-}
-
-static void uvc_input_report_key(struct uvc_device *dev, unsigned int code,
- int value)
-{
- if (dev->input) {
- input_report_key(dev->input, code, value);
- input_sync(dev->input);
- }
-}
-
-#else
-#define uvc_input_init(dev)
-#define uvc_input_cleanup(dev)
-#define uvc_input_report_key(dev, code, value)
-#endif /* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV */
-
-/* --------------------------------------------------------------------------
- * Status interrupt endpoint
- */
-static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len)
-{
- if (len < 3) {
- uvc_trace(UVC_TRACE_STATUS, "Invalid streaming status event "
- "received.\n");
- return;
- }
-
- if (data[2] == 0) {
- if (len < 4)
- return;
- uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n",
- data[1], data[3] ? "pressed" : "released", len);
- uvc_input_report_key(dev, KEY_CAMERA, data[3]);
- } else {
- uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x "
- "len %d.\n", data[1], data[2], data[3], len);
- }
-}
-
-static void uvc_event_control(struct uvc_device *dev, __u8 *data, int len)
-{
- char *attrs[3] = { "value", "info", "failure" };
-
- if (len < 6 || data[2] != 0 || data[4] > 2) {
- uvc_trace(UVC_TRACE_STATUS, "Invalid control status event "
- "received.\n");
- return;
- }
-
- uvc_trace(UVC_TRACE_STATUS, "Control %u/%u %s change len %d.\n",
- data[1], data[3], attrs[data[4]], len);
-}
-
-static void uvc_status_complete(struct urb *urb)
-{
- struct uvc_device *dev = urb->context;
- int len, ret;
-
- switch (urb->status) {
- case 0:
- break;
-
- case -ENOENT: /* usb_kill_urb() called. */
- case -ECONNRESET: /* usb_unlink_urb() called. */
- case -ESHUTDOWN: /* The endpoint is being disabled. */
- case -EPROTO: /* Device is disconnected (reported by some
- * host controller). */
- return;
-
- default:
- uvc_printk(KERN_WARNING, "Non-zero status (%d) in status "
- "completion handler.\n", urb->status);
- return;
- }
-
- len = urb->actual_length;
- if (len > 0) {
- switch (dev->status[0] & 0x0f) {
- case UVC_STATUS_TYPE_CONTROL:
- uvc_event_control(dev, dev->status, len);
- break;
-
- case UVC_STATUS_TYPE_STREAMING:
- uvc_event_streaming(dev, dev->status, len);
- break;
-
- default:
- uvc_trace(UVC_TRACE_STATUS, "Unknown status event "
- "type %u.\n", dev->status[0]);
- break;
- }
- }
-
- /* Resubmit the URB. */
- urb->interval = dev->int_ep->desc.bInterval;
- if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- uvc_printk(KERN_ERR, "Failed to resubmit status URB (%d).\n",
- ret);
- }
-}
-
-int uvc_status_init(struct uvc_device *dev)
-{
- struct usb_host_endpoint *ep = dev->int_ep;
- unsigned int pipe;
- int interval;
-
- if (ep == NULL)
- return 0;
-
- uvc_input_init(dev);
-
- dev->status = kzalloc(UVC_MAX_STATUS_SIZE, GFP_KERNEL);
- if (dev->status == NULL)
- return -ENOMEM;
-
- dev->int_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (dev->int_urb == NULL) {
- kfree(dev->status);
- return -ENOMEM;
- }
-
- pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress);
-
- /* For high-speed interrupt endpoints, the bInterval value is used as
- * an exponent of two. Some developers forgot about it.
- */
- interval = ep->desc.bInterval;
- if (interval > 16 && dev->udev->speed == USB_SPEED_HIGH &&
- (dev->quirks & UVC_QUIRK_STATUS_INTERVAL))
- interval = fls(interval) - 1;
-
- usb_fill_int_urb(dev->int_urb, dev->udev, pipe,
- dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete,
- dev, interval);
-
- return 0;
-}
-
-void uvc_status_cleanup(struct uvc_device *dev)
-{
- usb_kill_urb(dev->int_urb);
- usb_free_urb(dev->int_urb);
- kfree(dev->status);
- uvc_input_cleanup(dev);
-}
-
-int uvc_status_start(struct uvc_device *dev)
-{
- if (dev->int_urb == NULL)
- return 0;
-
- return usb_submit_urb(dev->int_urb, GFP_KERNEL);
-}
-
-void uvc_status_stop(struct uvc_device *dev)
-{
- usb_kill_urb(dev->int_urb);
-}
-
-int uvc_status_suspend(struct uvc_device *dev)
-{
- if (atomic_read(&dev->users))
- usb_kill_urb(dev->int_urb);
-
- return 0;
-}
-
-int uvc_status_resume(struct uvc_device *dev)
-{
- if (dev->int_urb == NULL || atomic_read(&dev->users) == 0)
- return 0;
-
- return usb_submit_urb(dev->int_urb, GFP_NOIO);
-}
-
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
deleted file mode 100644
index f00db3060e0..00000000000
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ /dev/null
@@ -1,1317 +0,0 @@
-/*
- * uvc_v4l2.c -- USB Video Class driver - V4L2 API
- *
- * Copyright (C) 2005-2010
- * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/compat.h>
-#include <linux/kernel.h>
-#include <linux/version.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include <linux/vmalloc.h>
-#include <linux/mm.h>
-#include <linux/wait.h>
-#include <linux/atomic.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-ioctl.h>
-
-#include "uvcvideo.h"
-
-/* ------------------------------------------------------------------------
- * UVC ioctls
- */
-static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
- struct uvc_xu_control_mapping *xmap)
-{
- struct uvc_control_mapping *map;
- unsigned int size;
- int ret;
-
- map = kzalloc(sizeof *map, GFP_KERNEL);
- if (map == NULL)
- return -ENOMEM;
-
- map->id = xmap->id;
- memcpy(map->name, xmap->name, sizeof map->name);
- memcpy(map->entity, xmap->entity, sizeof map->entity);
- map->selector = xmap->selector;
- map->size = xmap->size;
- map->offset = xmap->offset;
- map->v4l2_type = xmap->v4l2_type;
- map->data_type = xmap->data_type;
-
- switch (xmap->v4l2_type) {
- case V4L2_CTRL_TYPE_INTEGER:
- case V4L2_CTRL_TYPE_BOOLEAN:
- case V4L2_CTRL_TYPE_BUTTON:
- break;
-
- case V4L2_CTRL_TYPE_MENU:
- /* Prevent excessive memory consumption, as well as integer
- * overflows.
- */
- if (xmap->menu_count == 0 ||
- xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) {
- ret = -EINVAL;
- goto done;
- }
-
- size = xmap->menu_count * sizeof(*map->menu_info);
- map->menu_info = kmalloc(size, GFP_KERNEL);
- if (map->menu_info == NULL) {
- ret = -ENOMEM;
- goto done;
- }
-
- if (copy_from_user(map->menu_info, xmap->menu_info, size)) {
- ret = -EFAULT;
- goto done;
- }
-
- map->menu_count = xmap->menu_count;
- break;
-
- default:
- uvc_trace(UVC_TRACE_CONTROL, "Unsupported V4L2 control type "
- "%u.\n", xmap->v4l2_type);
- ret = -ENOTTY;
- goto done;
- }
-
- ret = uvc_ctrl_add_mapping(chain, map);
-
-done:
- kfree(map->menu_info);
- kfree(map);
-
- return ret;
-}
-
-/* ------------------------------------------------------------------------
- * V4L2 interface
- */
-
-/*
- * Find the frame interval closest to the requested frame interval for the
- * given frame format and size. This should be done by the device as part of
- * the Video Probe and Commit negotiation, but some hardware don't implement
- * that feature.
- */
-static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval)
-{
- unsigned int i;
-
- if (frame->bFrameIntervalType) {
- __u32 best = -1, dist;
-
- for (i = 0; i < frame->bFrameIntervalType; ++i) {
- dist = interval > frame->dwFrameInterval[i]
- ? interval - frame->dwFrameInterval[i]
- : frame->dwFrameInterval[i] - interval;
-
- if (dist > best)
- break;
-
- best = dist;
- }
-
- interval = frame->dwFrameInterval[i-1];
- } else {
- const __u32 min = frame->dwFrameInterval[0];
- const __u32 max = frame->dwFrameInterval[1];
- const __u32 step = frame->dwFrameInterval[2];
-
- interval = min + (interval - min + step/2) / step * step;
- if (interval > max)
- interval = max;
- }
-
- return interval;
-}
-
-static int uvc_v4l2_try_format(struct uvc_streaming *stream,
- struct v4l2_format *fmt, struct uvc_streaming_control *probe,
- struct uvc_format **uvc_format, struct uvc_frame **uvc_frame)
-{
- struct uvc_format *format = NULL;
- struct uvc_frame *frame = NULL;
- __u16 rw, rh;
- unsigned int d, maxd;
- unsigned int i;
- __u32 interval;
- int ret = 0;
- __u8 *fcc;
-
- if (fmt->type != stream->type)
- return -EINVAL;
-
- fcc = (__u8 *)&fmt->fmt.pix.pixelformat;
- uvc_trace(UVC_TRACE_FORMAT, "Trying format 0x%08x (%c%c%c%c): %ux%u.\n",
- fmt->fmt.pix.pixelformat,
- fcc[0], fcc[1], fcc[2], fcc[3],
- fmt->fmt.pix.width, fmt->fmt.pix.height);
-
- /* Check if the hardware supports the requested format. */
- for (i = 0; i < stream->nformats; ++i) {
- format = &stream->format[i];
- if (format->fcc == fmt->fmt.pix.pixelformat)
- break;
- }
-
- if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) {
- uvc_trace(UVC_TRACE_FORMAT, "Unsupported format 0x%08x.\n",
- fmt->fmt.pix.pixelformat);
- return -EINVAL;
- }
-
- /* Find the closest image size. The distance between image sizes is
- * the size in pixels of the non-overlapping regions between the
- * requested size and the frame-specified size.
- */
- rw = fmt->fmt.pix.width;
- rh = fmt->fmt.pix.height;
- maxd = (unsigned int)-1;
-
- for (i = 0; i < format->nframes; ++i) {
- __u16 w = format->frame[i].wWidth;
- __u16 h = format->frame[i].wHeight;
-
- d = min(w, rw) * min(h, rh);
- d = w*h + rw*rh - 2*d;
- if (d < maxd) {
- maxd = d;
- frame = &format->frame[i];
- }
-
- if (maxd == 0)
- break;
- }
-
- if (frame == NULL) {
- uvc_trace(UVC_TRACE_FORMAT, "Unsupported size %ux%u.\n",
- fmt->fmt.pix.width, fmt->fmt.pix.height);
- return -EINVAL;
- }
-
- /* Use the default frame interval. */
- interval = frame->dwDefaultFrameInterval;
- uvc_trace(UVC_TRACE_FORMAT, "Using default frame interval %u.%u us "
- "(%u.%u fps).\n", interval/10, interval%10, 10000000/interval,
- (100000000/interval)%10);
-
- /* Set the format index, frame index and frame interval. */
- memset(probe, 0, sizeof *probe);
- probe->bmHint = 1; /* dwFrameInterval */
- probe->bFormatIndex = format->index;
- probe->bFrameIndex = frame->bFrameIndex;
- probe->dwFrameInterval = uvc_try_frame_interval(frame, interval);
- /* Some webcams stall the probe control set request when the
- * dwMaxVideoFrameSize field is set to zero. The UVC specification
- * clearly states that the field is read-only from the host, so this
- * is a webcam bug. Set dwMaxVideoFrameSize to the value reported by
- * the webcam to work around the problem.
- *
- * The workaround could probably be enabled for all webcams, so the
- * quirk can be removed if needed. It's currently useful to detect
- * webcam bugs and fix them before they hit the market (providing
- * developers test their webcams with the Linux driver as well as with
- * the Windows driver).
- */
- mutex_lock(&stream->mutex);
- if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
- probe->dwMaxVideoFrameSize =
- stream->ctrl.dwMaxVideoFrameSize;
-
- /* Probe the device. */
- ret = uvc_probe_video(stream, probe);
- mutex_unlock(&stream->mutex);
- if (ret < 0)
- goto done;
-
- fmt->fmt.pix.width = frame->wWidth;
- fmt->fmt.pix.height = frame->wHeight;
- fmt->fmt.pix.field = V4L2_FIELD_NONE;
- fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
- fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize;
- fmt->fmt.pix.colorspace = format->colorspace;
- fmt->fmt.pix.priv = 0;
-
- if (uvc_format != NULL)
- *uvc_format = format;
- if (uvc_frame != NULL)
- *uvc_frame = frame;
-
-done:
- return ret;
-}
-
-static int uvc_v4l2_get_format(struct uvc_streaming *stream,
- struct v4l2_format *fmt)
-{
- struct uvc_format *format;
- struct uvc_frame *frame;
- int ret = 0;
-
- if (fmt->type != stream->type)
- return -EINVAL;
-
- mutex_lock(&stream->mutex);
- format = stream->cur_format;
- frame = stream->cur_frame;
-
- if (format == NULL || frame == NULL) {
- ret = -EINVAL;
- goto done;
- }
-
- fmt->fmt.pix.pixelformat = format->fcc;
- fmt->fmt.pix.width = frame->wWidth;
- fmt->fmt.pix.height = frame->wHeight;
- fmt->fmt.pix.field = V4L2_FIELD_NONE;
- fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
- fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize;
- fmt->fmt.pix.colorspace = format->colorspace;
- fmt->fmt.pix.priv = 0;
-
-done:
- mutex_unlock(&stream->mutex);
- return ret;
-}
-
-static int uvc_v4l2_set_format(struct uvc_streaming *stream,
- struct v4l2_format *fmt)
-{
- struct uvc_streaming_control probe;
- struct uvc_format *format;
- struct uvc_frame *frame;
- int ret;
-
- if (fmt->type != stream->type)
- return -EINVAL;
-
- ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
- if (ret < 0)
- return ret;
-
- mutex_lock(&stream->mutex);
-
- if (uvc_queue_allocated(&stream->queue)) {
- ret = -EBUSY;
- goto done;
- }
-
- memcpy(&stream->ctrl, &probe, sizeof probe);
- stream->cur_format = format;
- stream->cur_frame = frame;
-
-done:
- mutex_unlock(&stream->mutex);
- return ret;
-}
-
-static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
- struct v4l2_streamparm *parm)
-{
- uint32_t numerator, denominator;
-
- if (parm->type != stream->type)
- return -EINVAL;
-
- mutex_lock(&stream->mutex);
- numerator = stream->ctrl.dwFrameInterval;
- mutex_unlock(&stream->mutex);
-
- denominator = 10000000;
- uvc_simplify_fraction(&numerator, &denominator, 8, 333);
-
- memset(parm, 0, sizeof *parm);
- parm->type = stream->type;
-
- if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
- parm->parm.capture.capturemode = 0;
- parm->parm.capture.timeperframe.numerator = numerator;
- parm->parm.capture.timeperframe.denominator = denominator;
- parm->parm.capture.extendedmode = 0;
- parm->parm.capture.readbuffers = 0;
- } else {
- parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
- parm->parm.output.outputmode = 0;
- parm->parm.output.timeperframe.numerator = numerator;
- parm->parm.output.timeperframe.denominator = denominator;
- }
-
- return 0;
-}
-
-static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
- struct v4l2_streamparm *parm)
-{
- struct uvc_streaming_control probe;
- struct v4l2_fract timeperframe;
- uint32_t interval;
- int ret;
-
- if (parm->type != stream->type)
- return -EINVAL;
-
- if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- timeperframe = parm->parm.capture.timeperframe;
- else
- timeperframe = parm->parm.output.timeperframe;
-
- interval = uvc_fraction_to_interval(timeperframe.numerator,
- timeperframe.denominator);
- uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n",
- timeperframe.numerator, timeperframe.denominator, interval);
-
- mutex_lock(&stream->mutex);
-
- if (uvc_queue_streaming(&stream->queue)) {
- mutex_unlock(&stream->mutex);
- return -EBUSY;
- }
-
- memcpy(&probe, &stream->ctrl, sizeof probe);
- probe.dwFrameInterval =
- uvc_try_frame_interval(stream->cur_frame, interval);
-
- /* Probe the device with the new settings. */
- ret = uvc_probe_video(stream, &probe);
- if (ret < 0) {
- mutex_unlock(&stream->mutex);
- return ret;
- }
-
- memcpy(&stream->ctrl, &probe, sizeof probe);
- mutex_unlock(&stream->mutex);
-
- /* Return the actual frame period. */
- timeperframe.numerator = probe.dwFrameInterval;
- timeperframe.denominator = 10000000;
- uvc_simplify_fraction(&timeperframe.numerator,
- &timeperframe.denominator, 8, 333);
-
- if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- parm->parm.capture.timeperframe = timeperframe;
- else
- parm->parm.output.timeperframe = timeperframe;
-
- return 0;
-}
-
-/* ------------------------------------------------------------------------
- * Privilege management
- */
-
-/*
- * Privilege management is the multiple-open implementation basis. The current
- * implementation is completely transparent for the end-user and doesn't
- * require explicit use of the VIDIOC_G_PRIORITY and VIDIOC_S_PRIORITY ioctls.
- * Those ioctls enable finer control on the device (by making possible for a
- * user to request exclusive access to a device), but are not mature yet.
- * Switching to the V4L2 priority mechanism might be considered in the future
- * if this situation changes.
- *
- * Each open instance of a UVC device can either be in a privileged or
- * unprivileged state. Only a single instance can be in a privileged state at
- * a given time. Trying to perform an operation that requires privileges will
- * automatically acquire the required privileges if possible, or return -EBUSY
- * otherwise. Privileges are dismissed when closing the instance or when
- * freeing the video buffers using VIDIOC_REQBUFS.
- *
- * Operations that require privileges are:
- *
- * - VIDIOC_S_INPUT
- * - VIDIOC_S_PARM
- * - VIDIOC_S_FMT
- * - VIDIOC_REQBUFS
- */
-static int uvc_acquire_privileges(struct uvc_fh *handle)
-{
- /* Always succeed if the handle is already privileged. */
- if (handle->state == UVC_HANDLE_ACTIVE)
- return 0;
-
- /* Check if the device already has a privileged handle. */
- if (atomic_inc_return(&handle->stream->active) != 1) {
- atomic_dec(&handle->stream->active);
- return -EBUSY;
- }
-
- handle->state = UVC_HANDLE_ACTIVE;
- return 0;
-}
-
-static void uvc_dismiss_privileges(struct uvc_fh *handle)
-{
- if (handle->state == UVC_HANDLE_ACTIVE)
- atomic_dec(&handle->stream->active);
-
- handle->state = UVC_HANDLE_PASSIVE;
-}
-
-static int uvc_has_privileges(struct uvc_fh *handle)
-{
- return handle->state == UVC_HANDLE_ACTIVE;
-}
-
-/* ------------------------------------------------------------------------
- * V4L2 file operations
- */
-
-static int uvc_v4l2_open(struct file *file)
-{
- struct uvc_streaming *stream;
- struct uvc_fh *handle;
- int ret = 0;
-
- uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n");
- stream = video_drvdata(file);
-
- if (stream->dev->state & UVC_DEV_DISCONNECTED)
- return -ENODEV;
-
- ret = usb_autopm_get_interface(stream->dev->intf);
- if (ret < 0)
- return ret;
-
- /* Create the device handle. */
- handle = kzalloc(sizeof *handle, GFP_KERNEL);
- if (handle == NULL) {
- usb_autopm_put_interface(stream->dev->intf);
- return -ENOMEM;
- }
-
- if (atomic_inc_return(&stream->dev->users) == 1) {
- ret = uvc_status_start(stream->dev);
- if (ret < 0) {
- usb_autopm_put_interface(stream->dev->intf);
- atomic_dec(&stream->dev->users);
- kfree(handle);
- return ret;
- }
- }
-
- v4l2_fh_init(&handle->vfh, stream->vdev);
- v4l2_fh_add(&handle->vfh);
- handle->chain = stream->chain;
- handle->stream = stream;
- handle->state = UVC_HANDLE_PASSIVE;
- file->private_data = handle;
-
- return 0;
-}
-
-static int uvc_v4l2_release(struct file *file)
-{
- struct uvc_fh *handle = file->private_data;
- struct uvc_streaming *stream = handle->stream;
-
- uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n");
-
- /* Only free resources if this is a privileged handle. */
- if (uvc_has_privileges(handle)) {
- uvc_video_enable(stream, 0);
- uvc_free_buffers(&stream->queue);
- }
-
- /* Release the file handle. */
- uvc_dismiss_privileges(handle);
- v4l2_fh_del(&handle->vfh);
- v4l2_fh_exit(&handle->vfh);
- kfree(handle);
- file->private_data = NULL;
-
- if (atomic_dec_return(&stream->dev->users) == 0)
- uvc_status_stop(stream->dev);
-
- usb_autopm_put_interface(stream->dev->intf);
- return 0;
-}
-
-static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
-{
- struct video_device *vdev = video_devdata(file);
- struct uvc_fh *handle = file->private_data;
- struct uvc_video_chain *chain = handle->chain;
- struct uvc_streaming *stream = handle->stream;
- long ret = 0;
-
- switch (cmd) {
- /* Query capabilities */
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *cap = arg;
-
- memset(cap, 0, sizeof *cap);
- strlcpy(cap->driver, "uvcvideo", sizeof cap->driver);
- strlcpy(cap->card, vdev->name, sizeof cap->card);
- usb_make_path(stream->dev->udev,
- cap->bus_info, sizeof(cap->bus_info));
- cap->version = LINUX_VERSION_CODE;
- if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
- | V4L2_CAP_STREAMING;
- else
- cap->capabilities = V4L2_CAP_VIDEO_OUTPUT
- | V4L2_CAP_STREAMING;
- break;
- }
-
- /* Get, Set & Query control */
- case VIDIOC_QUERYCTRL:
- return uvc_query_v4l2_ctrl(chain, arg);
-
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl = arg;
- struct v4l2_ext_control xctrl;
-
- memset(&xctrl, 0, sizeof xctrl);
- xctrl.id = ctrl->id;
-
- ret = uvc_ctrl_begin(chain);
- if (ret < 0)
- return ret;
-
- ret = uvc_ctrl_get(chain, &xctrl);
- uvc_ctrl_rollback(handle);
- if (ret >= 0)
- ctrl->value = xctrl.value;
- break;
- }
-
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl = arg;
- struct v4l2_ext_control xctrl;
-
- memset(&xctrl, 0, sizeof xctrl);
- xctrl.id = ctrl->id;
- xctrl.value = ctrl->value;
-
- ret = uvc_ctrl_begin(chain);
- if (ret < 0)
- return ret;
-
- ret = uvc_ctrl_set(chain, &xctrl);
- if (ret < 0) {
- uvc_ctrl_rollback(handle);
- return ret;
- }
- ret = uvc_ctrl_commit(handle, &xctrl, 1);
- if (ret == 0)
- ctrl->value = xctrl.value;
- break;
- }
-
- case VIDIOC_QUERYMENU:
- return uvc_query_v4l2_menu(chain, arg);
-
- case VIDIOC_G_EXT_CTRLS:
- {
- struct v4l2_ext_controls *ctrls = arg;
- struct v4l2_ext_control *ctrl = ctrls->controls;
- unsigned int i;
-
- ret = uvc_ctrl_begin(chain);
- if (ret < 0)
- return ret;
-
- for (i = 0; i < ctrls->count; ++ctrl, ++i) {
- ret = uvc_ctrl_get(chain, ctrl);
- if (ret < 0) {
- uvc_ctrl_rollback(handle);
- ctrls->error_idx = i;
- return ret;
- }
- }
- ctrls->error_idx = 0;
- ret = uvc_ctrl_rollback(handle);
- break;
- }
-
- case VIDIOC_S_EXT_CTRLS:
- case VIDIOC_TRY_EXT_CTRLS:
- {
- struct v4l2_ext_controls *ctrls = arg;
- struct v4l2_ext_control *ctrl = ctrls->controls;
- unsigned int i;
-
- ret = uvc_ctrl_begin(chain);
- if (ret < 0)
- return ret;
-
- for (i = 0; i < ctrls->count; ++ctrl, ++i) {
- ret = uvc_ctrl_set(chain, ctrl);
- if (ret < 0) {
- uvc_ctrl_rollback(handle);
- ctrls->error_idx = i;
- return ret;
- }
- }
-
- ctrls->error_idx = 0;
-
- if (cmd == VIDIOC_S_EXT_CTRLS)
- ret = uvc_ctrl_commit(handle,
- ctrls->controls, ctrls->count);
- else
- ret = uvc_ctrl_rollback(handle);
- break;
- }
-
- /* Get, Set & Enum input */
- case VIDIOC_ENUMINPUT:
- {
- const struct uvc_entity *selector = chain->selector;
- struct v4l2_input *input = arg;
- struct uvc_entity *iterm = NULL;
- u32 index = input->index;
- int pin = 0;
-
- if (selector == NULL ||
- (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
- if (index != 0)
- return -EINVAL;
- list_for_each_entry(iterm, &chain->entities, chain) {
- if (UVC_ENTITY_IS_ITERM(iterm))
- break;
- }
- pin = iterm->id;
- } else if (index < selector->bNrInPins) {
- pin = selector->baSourceID[index];
- list_for_each_entry(iterm, &chain->entities, chain) {
- if (!UVC_ENTITY_IS_ITERM(iterm))
- continue;
- if (iterm->id == pin)
- break;
- }
- }
-
- if (iterm == NULL || iterm->id != pin)
- return -EINVAL;
-
- memset(input, 0, sizeof *input);
- input->index = index;
- strlcpy(input->name, iterm->name, sizeof input->name);
- if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA)
- input->type = V4L2_INPUT_TYPE_CAMERA;
- break;
- }
-
- case VIDIOC_G_INPUT:
- {
- u8 input;
-
- if (chain->selector == NULL ||
- (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
- *(int *)arg = 0;
- break;
- }
-
- ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
- chain->selector->id, chain->dev->intfnum,
- UVC_SU_INPUT_SELECT_CONTROL, &input, 1);
- if (ret < 0)
- return ret;
-
- *(int *)arg = input - 1;
- break;
- }
-
- case VIDIOC_S_INPUT:
- {
- u32 input = *(u32 *)arg + 1;
-
- if ((ret = uvc_acquire_privileges(handle)) < 0)
- return ret;
-
- if (chain->selector == NULL ||
- (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
- if (input != 1)
- return -EINVAL;
- break;
- }
-
- if (input == 0 || input > chain->selector->bNrInPins)
- return -EINVAL;
-
- return uvc_query_ctrl(chain->dev, UVC_SET_CUR,
- chain->selector->id, chain->dev->intfnum,
- UVC_SU_INPUT_SELECT_CONTROL, &input, 1);
- }
-
- /* Try, Get, Set & Enum format */
- case VIDIOC_ENUM_FMT:
- {
- struct v4l2_fmtdesc *fmt = arg;
- struct uvc_format *format;
- enum v4l2_buf_type type = fmt->type;
- __u32 index = fmt->index;
-
- if (fmt->type != stream->type ||
- fmt->index >= stream->nformats)
- return -EINVAL;
-
- memset(fmt, 0, sizeof(*fmt));
- fmt->index = index;
- fmt->type = type;
-
- format = &stream->format[fmt->index];
- fmt->flags = 0;
- if (format->flags & UVC_FMT_FLAG_COMPRESSED)
- fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
- strlcpy(fmt->description, format->name,
- sizeof fmt->description);
- fmt->description[sizeof fmt->description - 1] = 0;
- fmt->pixelformat = format->fcc;
- break;
- }
-
- case VIDIOC_TRY_FMT:
- {
- struct uvc_streaming_control probe;
-
- return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL);
- }
-
- case VIDIOC_S_FMT:
- if ((ret = uvc_acquire_privileges(handle)) < 0)
- return ret;
-
- return uvc_v4l2_set_format(stream, arg);
-
- case VIDIOC_G_FMT:
- return uvc_v4l2_get_format(stream, arg);
-
- /* Frame size enumeration */
- case VIDIOC_ENUM_FRAMESIZES:
- {
- struct v4l2_frmsizeenum *fsize = arg;
- struct uvc_format *format = NULL;
- struct uvc_frame *frame;
- int i;
-
- /* Look for the given pixel format */
- for (i = 0; i < stream->nformats; i++) {
- if (stream->format[i].fcc ==
- fsize->pixel_format) {
- format = &stream->format[i];
- break;
- }
- }
- if (format == NULL)
- return -EINVAL;
-
- if (fsize->index >= format->nframes)
- return -EINVAL;
-
- frame = &format->frame[fsize->index];
- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fsize->discrete.width = frame->wWidth;
- fsize->discrete.height = frame->wHeight;
- break;
- }
-
- /* Frame interval enumeration */
- case VIDIOC_ENUM_FRAMEINTERVALS:
- {
- struct v4l2_frmivalenum *fival = arg;
- struct uvc_format *format = NULL;
- struct uvc_frame *frame = NULL;
- int i;
-
- /* Look for the given pixel format and frame size */
- for (i = 0; i < stream->nformats; i++) {
- if (stream->format[i].fcc ==
- fival->pixel_format) {
- format = &stream->format[i];
- break;
- }
- }
- if (format == NULL)
- return -EINVAL;
-
- for (i = 0; i < format->nframes; i++) {
- if (format->frame[i].wWidth == fival->width &&
- format->frame[i].wHeight == fival->height) {
- frame = &format->frame[i];
- break;
- }
- }
- if (frame == NULL)
- return -EINVAL;
-
- if (frame->bFrameIntervalType) {
- if (fival->index >= frame->bFrameIntervalType)
- return -EINVAL;
-
- fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
- fival->discrete.numerator =
- frame->dwFrameInterval[fival->index];
- fival->discrete.denominator = 10000000;
- uvc_simplify_fraction(&fival->discrete.numerator,
- &fival->discrete.denominator, 8, 333);
- } else {
- fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
- fival->stepwise.min.numerator =
- frame->dwFrameInterval[0];
- fival->stepwise.min.denominator = 10000000;
- fival->stepwise.max.numerator =
- frame->dwFrameInterval[1];
- fival->stepwise.max.denominator = 10000000;
- fival->stepwise.step.numerator =
- frame->dwFrameInterval[2];
- fival->stepwise.step.denominator = 10000000;
- uvc_simplify_fraction(&fival->stepwise.min.numerator,
- &fival->stepwise.min.denominator, 8, 333);
- uvc_simplify_fraction(&fival->stepwise.max.numerator,
- &fival->stepwise.max.denominator, 8, 333);
- uvc_simplify_fraction(&fival->stepwise.step.numerator,
- &fival->stepwise.step.denominator, 8, 333);
- }
- break;
- }
-
- /* Get & Set streaming parameters */
- case VIDIOC_G_PARM:
- return uvc_v4l2_get_streamparm(stream, arg);
-
- case VIDIOC_S_PARM:
- if ((ret = uvc_acquire_privileges(handle)) < 0)
- return ret;
-
- return uvc_v4l2_set_streamparm(stream, arg);
-
- /* Cropping and scaling */
- case VIDIOC_CROPCAP:
- {
- struct v4l2_cropcap *ccap = arg;
-
- if (ccap->type != stream->type)
- return -EINVAL;
-
- ccap->bounds.left = 0;
- ccap->bounds.top = 0;
-
- mutex_lock(&stream->mutex);
- ccap->bounds.width = stream->cur_frame->wWidth;
- ccap->bounds.height = stream->cur_frame->wHeight;
- mutex_unlock(&stream->mutex);
-
- ccap->defrect = ccap->bounds;
-
- ccap->pixelaspect.numerator = 1;
- ccap->pixelaspect.denominator = 1;
- break;
- }
-
- case VIDIOC_G_CROP:
- case VIDIOC_S_CROP:
- return -EINVAL;
-
- /* Buffers & streaming */
- case VIDIOC_REQBUFS:
- if ((ret = uvc_acquire_privileges(handle)) < 0)
- return ret;
-
- mutex_lock(&stream->mutex);
- ret = uvc_alloc_buffers(&stream->queue, arg);
- mutex_unlock(&stream->mutex);
- if (ret < 0)
- return ret;
-
- if (ret == 0)
- uvc_dismiss_privileges(handle);
-
- ret = 0;
- break;
-
- case VIDIOC_QUERYBUF:
- {
- struct v4l2_buffer *buf = arg;
-
- if (!uvc_has_privileges(handle))
- return -EBUSY;
-
- return uvc_query_buffer(&stream->queue, buf);
- }
-
- case VIDIOC_QBUF:
- if (!uvc_has_privileges(handle))
- return -EBUSY;
-
- return uvc_queue_buffer(&stream->queue, arg);
-
- case VIDIOC_DQBUF:
- if (!uvc_has_privileges(handle))
- return -EBUSY;
-
- return uvc_dequeue_buffer(&stream->queue, arg,
- file->f_flags & O_NONBLOCK);
-
- case VIDIOC_STREAMON:
- {
- int *type = arg;
-
- if (*type != stream->type)
- return -EINVAL;
-
- if (!uvc_has_privileges(handle))
- return -EBUSY;
-
- mutex_lock(&stream->mutex);
- ret = uvc_video_enable(stream, 1);
- mutex_unlock(&stream->mutex);
- if (ret < 0)
- return ret;
- break;
- }
-
- case VIDIOC_STREAMOFF:
- {
- int *type = arg;
-
- if (*type != stream->type)
- return -EINVAL;
-
- if (!uvc_has_privileges(handle))
- return -EBUSY;
-
- return uvc_video_enable(stream, 0);
- }
-
- case VIDIOC_SUBSCRIBE_EVENT:
- {
- struct v4l2_event_subscription *sub = arg;
-
- switch (sub->type) {
- case V4L2_EVENT_CTRL:
- return v4l2_event_subscribe(&handle->vfh, sub, 0,
- &uvc_ctrl_sub_ev_ops);
- default:
- return -EINVAL;
- }
- }
-
- case VIDIOC_UNSUBSCRIBE_EVENT:
- return v4l2_event_unsubscribe(&handle->vfh, arg);
-
- case VIDIOC_DQEVENT:
- return v4l2_event_dequeue(&handle->vfh, arg,
- file->f_flags & O_NONBLOCK);
-
- /* Analog video standards make no sense for digital cameras. */
- case VIDIOC_ENUMSTD:
- case VIDIOC_QUERYSTD:
- case VIDIOC_G_STD:
- case VIDIOC_S_STD:
-
- case VIDIOC_OVERLAY:
-
- case VIDIOC_ENUMAUDIO:
- case VIDIOC_ENUMAUDOUT:
-
- case VIDIOC_ENUMOUTPUT:
- uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd);
- return -EINVAL;
-
- case UVCIOC_CTRL_MAP:
- return uvc_ioctl_ctrl_map(chain, arg);
-
- case UVCIOC_CTRL_QUERY:
- return uvc_xu_ctrl_query(chain, arg);
-
- default:
- uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd);
- return -ENOTTY;
- }
-
- return ret;
-}
-
-static long uvc_v4l2_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- if (uvc_trace_param & UVC_TRACE_IOCTL) {
- uvc_printk(KERN_DEBUG, "uvc_v4l2_ioctl(");
- v4l_printk_ioctl(NULL, cmd);
- printk(")\n");
- }
-
- return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl);
-}
-
-#ifdef CONFIG_COMPAT
-struct uvc_xu_control_mapping32 {
- __u32 id;
- __u8 name[32];
- __u8 entity[16];
- __u8 selector;
-
- __u8 size;
- __u8 offset;
- __u32 v4l2_type;
- __u32 data_type;
-
- compat_caddr_t menu_info;
- __u32 menu_count;
-
- __u32 reserved[4];
-};
-
-static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp,
- const struct uvc_xu_control_mapping32 __user *up)
-{
- struct uvc_menu_info __user *umenus;
- struct uvc_menu_info __user *kmenus;
- compat_caddr_t p;
-
- if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
- __copy_from_user(kp, up, offsetof(typeof(*up), menu_info)) ||
- __get_user(kp->menu_count, &up->menu_count))
- return -EFAULT;
-
- memset(kp->reserved, 0, sizeof(kp->reserved));
-
- if (kp->menu_count == 0) {
- kp->menu_info = NULL;
- return 0;
- }
-
- if (__get_user(p, &up->menu_info))
- return -EFAULT;
- umenus = compat_ptr(p);
- if (!access_ok(VERIFY_READ, umenus, kp->menu_count * sizeof(*umenus)))
- return -EFAULT;
-
- kmenus = compat_alloc_user_space(kp->menu_count * sizeof(*kmenus));
- if (kmenus == NULL)
- return -EFAULT;
- kp->menu_info = kmenus;
-
- if (copy_in_user(kmenus, umenus, kp->menu_count * sizeof(*umenus)))
- return -EFAULT;
-
- return 0;
-}
-
-static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp,
- struct uvc_xu_control_mapping32 __user *up)
-{
- struct uvc_menu_info __user *umenus;
- struct uvc_menu_info __user *kmenus = kp->menu_info;
- compat_caddr_t p;
-
- if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
- __copy_to_user(up, kp, offsetof(typeof(*up), menu_info)) ||
- __put_user(kp->menu_count, &up->menu_count))
- return -EFAULT;
-
- if (__clear_user(up->reserved, sizeof(up->reserved)))
- return -EFAULT;
-
- if (kp->menu_count == 0)
- return 0;
-
- if (get_user(p, &up->menu_info))
- return -EFAULT;
- umenus = compat_ptr(p);
-
- if (copy_in_user(umenus, kmenus, kp->menu_count * sizeof(*umenus)))
- return -EFAULT;
-
- return 0;
-}
-
-struct uvc_xu_control_query32 {
- __u8 unit;
- __u8 selector;
- __u8 query;
- __u16 size;
- compat_caddr_t data;
-};
-
-static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp,
- const struct uvc_xu_control_query32 __user *up)
-{
- u8 __user *udata;
- u8 __user *kdata;
- compat_caddr_t p;
-
- if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
- __copy_from_user(kp, up, offsetof(typeof(*up), data)))
- return -EFAULT;
-
- if (kp->size == 0) {
- kp->data = NULL;
- return 0;
- }
-
- if (__get_user(p, &up->data))
- return -EFAULT;
- udata = compat_ptr(p);
- if (!access_ok(VERIFY_READ, udata, kp->size))
- return -EFAULT;
-
- kdata = compat_alloc_user_space(kp->size);
- if (kdata == NULL)
- return -EFAULT;
- kp->data = kdata;
-
- if (copy_in_user(kdata, udata, kp->size))
- return -EFAULT;
-
- return 0;
-}
-
-static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp,
- struct uvc_xu_control_query32 __user *up)
-{
- u8 __user *udata;
- u8 __user *kdata = kp->data;
- compat_caddr_t p;
-
- if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
- __copy_to_user(up, kp, offsetof(typeof(*up), data)))
- return -EFAULT;
-
- if (kp->size == 0)
- return 0;
-
- if (get_user(p, &up->data))
- return -EFAULT;
- udata = compat_ptr(p);
- if (!access_ok(VERIFY_READ, udata, kp->size))
- return -EFAULT;
-
- if (copy_in_user(udata, kdata, kp->size))
- return -EFAULT;
-
- return 0;
-}
-
-#define UVCIOC_CTRL_MAP32 _IOWR('u', 0x20, struct uvc_xu_control_mapping32)
-#define UVCIOC_CTRL_QUERY32 _IOWR('u', 0x21, struct uvc_xu_control_query32)
-
-static long uvc_v4l2_compat_ioctl32(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- union {
- struct uvc_xu_control_mapping xmap;
- struct uvc_xu_control_query xqry;
- } karg;
- void __user *up = compat_ptr(arg);
- mm_segment_t old_fs;
- long ret;
-
- switch (cmd) {
- case UVCIOC_CTRL_MAP32:
- cmd = UVCIOC_CTRL_MAP;
- ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);
- break;
-
- case UVCIOC_CTRL_QUERY32:
- cmd = UVCIOC_CTRL_QUERY;
- ret = uvc_v4l2_get_xu_query(&karg.xqry, up);
- break;
-
- default:
- return -ENOIOCTLCMD;
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = uvc_v4l2_ioctl(file, cmd, (unsigned long)&karg);
- set_fs(old_fs);
-
- if (ret < 0)
- return ret;
-
- switch (cmd) {
- case UVCIOC_CTRL_MAP:
- ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
- break;
-
- case UVCIOC_CTRL_QUERY:
- ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
- break;
- }
-
- return ret;
-}
-#endif
-
-static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
- size_t count, loff_t *ppos)
-{
- uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n");
- return -EINVAL;
-}
-
-static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct uvc_fh *handle = file->private_data;
- struct uvc_streaming *stream = handle->stream;
-
- uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n");
-
- return uvc_queue_mmap(&stream->queue, vma);
-}
-
-static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait)
-{
- struct uvc_fh *handle = file->private_data;
- struct uvc_streaming *stream = handle->stream;
-
- uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n");
-
- return uvc_queue_poll(&stream->queue, file, wait);
-}
-
-#ifndef CONFIG_MMU
-static unsigned long uvc_v4l2_get_unmapped_area(struct file *file,
- unsigned long addr, unsigned long len, unsigned long pgoff,
- unsigned long flags)
-{
- struct uvc_fh *handle = file->private_data;
- struct uvc_streaming *stream = handle->stream;
-
- uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_get_unmapped_area\n");
-
- return uvc_queue_get_unmapped_area(&stream->queue, pgoff);
-}
-#endif
-
-const struct v4l2_file_operations uvc_fops = {
- .owner = THIS_MODULE,
- .open = uvc_v4l2_open,
- .release = uvc_v4l2_release,
- .unlocked_ioctl = uvc_v4l2_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl32 = uvc_v4l2_compat_ioctl32,
-#endif
- .read = uvc_v4l2_read,
- .mmap = uvc_v4l2_mmap,
- .poll = uvc_v4l2_poll,
-#ifndef CONFIG_MMU
- .get_unmapped_area = uvc_v4l2_get_unmapped_area,
-#endif
-};
-
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
deleted file mode 100644
index 7ac4347ca09..00000000000
--- a/drivers/media/video/uvc/uvc_video.c
+++ /dev/null
@@ -1,1861 +0,0 @@
-/*
- * uvc_video.c -- USB Video Class driver - Video handling
- *
- * Copyright (C) 2005-2010
- * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include <linux/vmalloc.h>
-#include <linux/wait.h>
-#include <linux/atomic.h>
-#include <asm/unaligned.h>
-
-#include <media/v4l2-common.h>
-
-#include "uvcvideo.h"
-
-/* ------------------------------------------------------------------------
- * UVC Controls
- */
-
-static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
- __u8 intfnum, __u8 cs, void *data, __u16 size,
- int timeout)
-{
- __u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
- unsigned int pipe;
-
- pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0)
- : usb_sndctrlpipe(dev->udev, 0);
- type |= (query & 0x80) ? USB_DIR_IN : USB_DIR_OUT;
-
- return usb_control_msg(dev->udev, pipe, query, type, cs << 8,
- unit << 8 | intfnum, data, size, timeout);
-}
-
-static const char *uvc_query_name(__u8 query)
-{
- switch (query) {
- case UVC_SET_CUR:
- return "SET_CUR";
- case UVC_GET_CUR:
- return "GET_CUR";
- case UVC_GET_MIN:
- return "GET_MIN";
- case UVC_GET_MAX:
- return "GET_MAX";
- case UVC_GET_RES:
- return "GET_RES";
- case UVC_GET_LEN:
- return "GET_LEN";
- case UVC_GET_INFO:
- return "GET_INFO";
- case UVC_GET_DEF:
- return "GET_DEF";
- default:
- return "<invalid>";
- }
-}
-
-int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
- __u8 intfnum, __u8 cs, void *data, __u16 size)
-{
- int ret;
-
- ret = __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size,
- UVC_CTRL_CONTROL_TIMEOUT);
- if (ret != size) {
- uvc_printk(KERN_ERR, "Failed to query (%s) UVC control %u on "
- "unit %u: %d (exp. %u).\n", uvc_query_name(query), cs,
- unit, ret, size);
- return -EIO;
- }
-
- return 0;
-}
-
-static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
- struct uvc_streaming_control *ctrl)
-{
- struct uvc_format *format = NULL;
- struct uvc_frame *frame = NULL;
- unsigned int i;
-
- for (i = 0; i < stream->nformats; ++i) {
- if (stream->format[i].index == ctrl->bFormatIndex) {
- format = &stream->format[i];
- break;
- }
- }
-
- if (format == NULL)
- return;
-
- for (i = 0; i < format->nframes; ++i) {
- if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) {
- frame = &format->frame[i];
- break;
- }
- }
-
- if (frame == NULL)
- return;
-
- if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) ||
- (ctrl->dwMaxVideoFrameSize == 0 &&
- stream->dev->uvc_version < 0x0110))
- ctrl->dwMaxVideoFrameSize =
- frame->dwMaxVideoFrameBufferSize;
-
- if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) &&
- stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
- stream->intf->num_altsetting > 1) {
- u32 interval;
- u32 bandwidth;
-
- interval = (ctrl->dwFrameInterval > 100000)
- ? ctrl->dwFrameInterval
- : frame->dwFrameInterval[0];
-
- /* Compute a bandwidth estimation by multiplying the frame
- * size by the number of video frames per second, divide the
- * result by the number of USB frames (or micro-frames for
- * high-speed devices) per second and add the UVC header size
- * (assumed to be 12 bytes long).
- */
- bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp;
- bandwidth *= 10000000 / interval + 1;
- bandwidth /= 1000;
- if (stream->dev->udev->speed == USB_SPEED_HIGH)
- bandwidth /= 8;
- bandwidth += 12;
-
- /* The bandwidth estimate is too low for many cameras. Don't use
- * maximum packet sizes lower than 1024 bytes to try and work
- * around the problem. According to measurements done on two
- * different camera models, the value is high enough to get most
- * resolutions working while not preventing two simultaneous
- * VGA streams at 15 fps.
- */
- bandwidth = max_t(u32, bandwidth, 1024);
-
- ctrl->dwMaxPayloadTransferSize = bandwidth;
- }
-}
-
-static int uvc_get_video_ctrl(struct uvc_streaming *stream,
- struct uvc_streaming_control *ctrl, int probe, __u8 query)
-{
- __u8 *data;
- __u16 size;
- int ret;
-
- size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
- if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) &&
- query == UVC_GET_DEF)
- return -EIO;
-
- data = kmalloc(size, GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
-
- ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum,
- probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
- size, uvc_timeout_param);
-
- if ((query == UVC_GET_MIN || query == UVC_GET_MAX) && ret == 2) {
- /* Some cameras, mostly based on Bison Electronics chipsets,
- * answer a GET_MIN or GET_MAX request with the wCompQuality
- * field only.
- */
- uvc_warn_once(stream->dev, UVC_WARN_MINMAX, "UVC non "
- "compliance - GET_MIN/MAX(PROBE) incorrectly "
- "supported. Enabling workaround.\n");
- memset(ctrl, 0, sizeof *ctrl);
- ctrl->wCompQuality = le16_to_cpup((__le16 *)data);
- ret = 0;
- goto out;
- } else if (query == UVC_GET_DEF && probe == 1 && ret != size) {
- /* Many cameras don't support the GET_DEF request on their
- * video probe control. Warn once and return, the caller will
- * fall back to GET_CUR.
- */
- uvc_warn_once(stream->dev, UVC_WARN_PROBE_DEF, "UVC non "
- "compliance - GET_DEF(PROBE) not supported. "
- "Enabling workaround.\n");
- ret = -EIO;
- goto out;
- } else if (ret != size) {
- uvc_printk(KERN_ERR, "Failed to query (%u) UVC %s control : "
- "%d (exp. %u).\n", query, probe ? "probe" : "commit",
- ret, size);
- ret = -EIO;
- goto out;
- }
-
- ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]);
- ctrl->bFormatIndex = data[2];
- ctrl->bFrameIndex = data[3];
- ctrl->dwFrameInterval = le32_to_cpup((__le32 *)&data[4]);
- ctrl->wKeyFrameRate = le16_to_cpup((__le16 *)&data[8]);
- ctrl->wPFrameRate = le16_to_cpup((__le16 *)&data[10]);
- ctrl->wCompQuality = le16_to_cpup((__le16 *)&data[12]);
- ctrl->wCompWindowSize = le16_to_cpup((__le16 *)&data[14]);
- ctrl->wDelay = le16_to_cpup((__le16 *)&data[16]);
- ctrl->dwMaxVideoFrameSize = get_unaligned_le32(&data[18]);
- ctrl->dwMaxPayloadTransferSize = get_unaligned_le32(&data[22]);
-
- if (size == 34) {
- ctrl->dwClockFrequency = get_unaligned_le32(&data[26]);
- ctrl->bmFramingInfo = data[30];
- ctrl->bPreferedVersion = data[31];
- ctrl->bMinVersion = data[32];
- ctrl->bMaxVersion = data[33];
- } else {
- ctrl->dwClockFrequency = stream->dev->clock_frequency;
- ctrl->bmFramingInfo = 0;
- ctrl->bPreferedVersion = 0;
- ctrl->bMinVersion = 0;
- ctrl->bMaxVersion = 0;
- }
-
- /* Some broken devices return null or wrong dwMaxVideoFrameSize and
- * dwMaxPayloadTransferSize fields. Try to get the value from the
- * format and frame descriptors.
- */
- uvc_fixup_video_ctrl(stream, ctrl);
- ret = 0;
-
-out:
- kfree(data);
- return ret;
-}
-
-static int uvc_set_video_ctrl(struct uvc_streaming *stream,
- struct uvc_streaming_control *ctrl, int probe)
-{
- __u8 *data;
- __u16 size;
- int ret;
-
- size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
- data = kzalloc(size, GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
-
- *(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint);
- data[2] = ctrl->bFormatIndex;
- data[3] = ctrl->bFrameIndex;
- *(__le32 *)&data[4] = cpu_to_le32(ctrl->dwFrameInterval);
- *(__le16 *)&data[8] = cpu_to_le16(ctrl->wKeyFrameRate);
- *(__le16 *)&data[10] = cpu_to_le16(ctrl->wPFrameRate);
- *(__le16 *)&data[12] = cpu_to_le16(ctrl->wCompQuality);
- *(__le16 *)&data[14] = cpu_to_le16(ctrl->wCompWindowSize);
- *(__le16 *)&data[16] = cpu_to_le16(ctrl->wDelay);
- put_unaligned_le32(ctrl->dwMaxVideoFrameSize, &data[18]);
- put_unaligned_le32(ctrl->dwMaxPayloadTransferSize, &data[22]);
-
- if (size == 34) {
- put_unaligned_le32(ctrl->dwClockFrequency, &data[26]);
- data[30] = ctrl->bmFramingInfo;
- data[31] = ctrl->bPreferedVersion;
- data[32] = ctrl->bMinVersion;
- data[33] = ctrl->bMaxVersion;
- }
-
- ret = __uvc_query_ctrl(stream->dev, UVC_SET_CUR, 0, stream->intfnum,
- probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
- size, uvc_timeout_param);
- if (ret != size) {
- uvc_printk(KERN_ERR, "Failed to set UVC %s control : "
- "%d (exp. %u).\n", probe ? "probe" : "commit",
- ret, size);
- ret = -EIO;
- }
-
- kfree(data);
- return ret;
-}
-
-int uvc_probe_video(struct uvc_streaming *stream,
- struct uvc_streaming_control *probe)
-{
- struct uvc_streaming_control probe_min, probe_max;
- __u16 bandwidth;
- unsigned int i;
- int ret;
-
- /* Perform probing. The device should adjust the requested values
- * according to its capabilities. However, some devices, namely the
- * first generation UVC Logitech webcams, don't implement the Video
- * Probe control properly, and just return the needed bandwidth. For
- * that reason, if the needed bandwidth exceeds the maximum available
- * bandwidth, try to lower the quality.
- */
- ret = uvc_set_video_ctrl(stream, probe, 1);
- if (ret < 0)
- goto done;
-
- /* Get the minimum and maximum values for compression settings. */
- if (!(stream->dev->quirks & UVC_QUIRK_PROBE_MINMAX)) {
- ret = uvc_get_video_ctrl(stream, &probe_min, 1, UVC_GET_MIN);
- if (ret < 0)
- goto done;
- ret = uvc_get_video_ctrl(stream, &probe_max, 1, UVC_GET_MAX);
- if (ret < 0)
- goto done;
-
- probe->wCompQuality = probe_max.wCompQuality;
- }
-
- for (i = 0; i < 2; ++i) {
- ret = uvc_set_video_ctrl(stream, probe, 1);
- if (ret < 0)
- goto done;
- ret = uvc_get_video_ctrl(stream, probe, 1, UVC_GET_CUR);
- if (ret < 0)
- goto done;
-
- if (stream->intf->num_altsetting == 1)
- break;
-
- bandwidth = probe->dwMaxPayloadTransferSize;
- if (bandwidth <= stream->maxpsize)
- break;
-
- if (stream->dev->quirks & UVC_QUIRK_PROBE_MINMAX) {
- ret = -ENOSPC;
- goto done;
- }
-
- /* TODO: negotiate compression parameters */
- probe->wKeyFrameRate = probe_min.wKeyFrameRate;
- probe->wPFrameRate = probe_min.wPFrameRate;
- probe->wCompQuality = probe_max.wCompQuality;
- probe->wCompWindowSize = probe_min.wCompWindowSize;
- }
-
-done:
- return ret;
-}
-
-static int uvc_commit_video(struct uvc_streaming *stream,
- struct uvc_streaming_control *probe)
-{
- return uvc_set_video_ctrl(stream, probe, 0);
-}
-
-/* -----------------------------------------------------------------------------
- * Clocks and timestamps
- */
-
-static void
-uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
- const __u8 *data, int len)
-{
- struct uvc_clock_sample *sample;
- unsigned int header_size;
- bool has_pts = false;
- bool has_scr = false;
- unsigned long flags;
- struct timespec ts;
- u16 host_sof;
- u16 dev_sof;
-
- switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) {
- case UVC_STREAM_PTS | UVC_STREAM_SCR:
- header_size = 12;
- has_pts = true;
- has_scr = true;
- break;
- case UVC_STREAM_PTS:
- header_size = 6;
- has_pts = true;
- break;
- case UVC_STREAM_SCR:
- header_size = 8;
- has_scr = true;
- break;
- default:
- header_size = 2;
- break;
- }
-
- /* Check for invalid headers. */
- if (len < header_size)
- return;
-
- /* Extract the timestamps:
- *
- * - store the frame PTS in the buffer structure
- * - if the SCR field is present, retrieve the host SOF counter and
- * kernel timestamps and store them with the SCR STC and SOF fields
- * in the ring buffer
- */
- if (has_pts && buf != NULL)
- buf->pts = get_unaligned_le32(&data[2]);
-
- if (!has_scr)
- return;
-
- /* To limit the amount of data, drop SCRs with an SOF identical to the
- * previous one.
- */
- dev_sof = get_unaligned_le16(&data[header_size - 2]);
- if (dev_sof == stream->clock.last_sof)
- return;
-
- stream->clock.last_sof = dev_sof;
-
- host_sof = usb_get_current_frame_number(stream->dev->udev);
- ktime_get_ts(&ts);
-
- /* The UVC specification allows device implementations that can't obtain
- * the USB frame number to keep their own frame counters as long as they
- * match the size and frequency of the frame number associated with USB
- * SOF tokens. The SOF values sent by such devices differ from the USB
- * SOF tokens by a fixed offset that needs to be estimated and accounted
- * for to make timestamp recovery as accurate as possible.
- *
- * The offset is estimated the first time a device SOF value is received
- * as the difference between the host and device SOF values. As the two
- * SOF values can differ slightly due to transmission delays, consider
- * that the offset is null if the difference is not higher than 10 ms
- * (negative differences can not happen and are thus considered as an
- * offset). The video commit control wDelay field should be used to
- * compute a dynamic threshold instead of using a fixed 10 ms value, but
- * devices don't report reliable wDelay values.
- *
- * See uvc_video_clock_host_sof() for an explanation regarding why only
- * the 8 LSBs of the delta are kept.
- */
- if (stream->clock.sof_offset == (u16)-1) {
- u16 delta_sof = (host_sof - dev_sof) & 255;
- if (delta_sof >= 10)
- stream->clock.sof_offset = delta_sof;
- else
- stream->clock.sof_offset = 0;
- }
-
- dev_sof = (dev_sof + stream->clock.sof_offset) & 2047;
-
- spin_lock_irqsave(&stream->clock.lock, flags);
-
- sample = &stream->clock.samples[stream->clock.head];
- sample->dev_stc = get_unaligned_le32(&data[header_size - 6]);
- sample->dev_sof = dev_sof;
- sample->host_sof = host_sof;
- sample->host_ts = ts;
-
- /* Update the sliding window head and count. */
- stream->clock.head = (stream->clock.head + 1) % stream->clock.size;
-
- if (stream->clock.count < stream->clock.size)
- stream->clock.count++;
-
- spin_unlock_irqrestore(&stream->clock.lock, flags);
-}
-
-static void uvc_video_clock_reset(struct uvc_streaming *stream)
-{
- struct uvc_clock *clock = &stream->clock;
-
- clock->head = 0;
- clock->count = 0;
- clock->last_sof = -1;
- clock->sof_offset = -1;
-}
-
-static int uvc_video_clock_init(struct uvc_streaming *stream)
-{
- struct uvc_clock *clock = &stream->clock;
-
- spin_lock_init(&clock->lock);
- clock->size = 32;
-
- clock->samples = kmalloc(clock->size * sizeof(*clock->samples),
- GFP_KERNEL);
- if (clock->samples == NULL)
- return -ENOMEM;
-
- uvc_video_clock_reset(stream);
-
- return 0;
-}
-
-static void uvc_video_clock_cleanup(struct uvc_streaming *stream)
-{
- kfree(stream->clock.samples);
- stream->clock.samples = NULL;
-}
-
-/*
- * uvc_video_clock_host_sof - Return the host SOF value for a clock sample
- *
- * Host SOF counters reported by usb_get_current_frame_number() usually don't
- * cover the whole 11-bits SOF range (0-2047) but are limited to the HCI frame
- * schedule window. They can be limited to 8, 9 or 10 bits depending on the host
- * controller and its configuration.
- *
- * We thus need to recover the SOF value corresponding to the host frame number.
- * As the device and host frame numbers are sampled in a short interval, the
- * difference between their values should be equal to a small delta plus an
- * integer multiple of 256 caused by the host frame number limited precision.
- *
- * To obtain the recovered host SOF value, compute the small delta by masking
- * the high bits of the host frame counter and device SOF difference and add it
- * to the device SOF value.
- */
-static u16 uvc_video_clock_host_sof(const struct uvc_clock_sample *sample)
-{
- /* The delta value can be negative. */
- s8 delta_sof;
-
- delta_sof = (sample->host_sof - sample->dev_sof) & 255;
-
- return (sample->dev_sof + delta_sof) & 2047;
-}
-
-/*
- * uvc_video_clock_update - Update the buffer timestamp
- *
- * This function converts the buffer PTS timestamp to the host clock domain by
- * going through the USB SOF clock domain and stores the result in the V4L2
- * buffer timestamp field.
- *
- * The relationship between the device clock and the host clock isn't known.
- * However, the device and the host share the common USB SOF clock which can be
- * used to recover that relationship.
- *
- * The relationship between the device clock and the USB SOF clock is considered
- * to be linear over the clock samples sliding window and is given by
- *
- * SOF = m * PTS + p
- *
- * Several methods to compute the slope (m) and intercept (p) can be used. As
- * the clock drift should be small compared to the sliding window size, we
- * assume that the line that goes through the points at both ends of the window
- * is a good approximation. Naming those points P1 and P2, we get
- *
- * SOF = (SOF2 - SOF1) / (STC2 - STC1) * PTS
- * + (SOF1 * STC2 - SOF2 * STC1) / (STC2 - STC1)
- *
- * or
- *
- * SOF = ((SOF2 - SOF1) * PTS + SOF1 * STC2 - SOF2 * STC1) / (STC2 - STC1) (1)
- *
- * to avoid loosing precision in the division. Similarly, the host timestamp is
- * computed with
- *
- * TS = ((TS2 - TS1) * PTS + TS1 * SOF2 - TS2 * SOF1) / (SOF2 - SOF1) (2)
- *
- * SOF values are coded on 11 bits by USB. We extend their precision with 16
- * decimal bits, leading to a 11.16 coding.
- *
- * TODO: To avoid surprises with device clock values, PTS/STC timestamps should
- * be normalized using the nominal device clock frequency reported through the
- * UVC descriptors.
- *
- * Both the PTS/STC and SOF counters roll over, after a fixed but device
- * specific amount of time for PTS/STC and after 2048ms for SOF. As long as the
- * sliding window size is smaller than the rollover period, differences computed
- * on unsigned integers will produce the correct result. However, the p term in
- * the linear relations will be miscomputed.
- *
- * To fix the issue, we subtract a constant from the PTS and STC values to bring
- * PTS to half the 32 bit STC range. The sliding window STC values then fit into
- * the 32 bit range without any rollover.
- *
- * Similarly, we add 2048 to the device SOF values to make sure that the SOF
- * computed by (1) will never be smaller than 0. This offset is then compensated
- * by adding 2048 to the SOF values used in (2). However, this doesn't prevent
- * rollovers between (1) and (2): the SOF value computed by (1) can be slightly
- * lower than 4096, and the host SOF counters can have rolled over to 2048. This
- * case is handled by subtracting 2048 from the SOF value if it exceeds the host
- * SOF value at the end of the sliding window.
- *
- * Finally we subtract a constant from the host timestamps to bring the first
- * timestamp of the sliding window to 1s.
- */
-void uvc_video_clock_update(struct uvc_streaming *stream,
- struct v4l2_buffer *v4l2_buf,
- struct uvc_buffer *buf)
-{
- struct uvc_clock *clock = &stream->clock;
- struct uvc_clock_sample *first;
- struct uvc_clock_sample *last;
- unsigned long flags;
- struct timespec ts;
- u32 delta_stc;
- u32 y1, y2;
- u32 x1, x2;
- u32 mean;
- u32 sof;
- u32 div;
- u32 rem;
- u64 y;
-
- spin_lock_irqsave(&clock->lock, flags);
-
- if (clock->count < clock->size)
- goto done;
-
- first = &clock->samples[clock->head];
- last = &clock->samples[(clock->head - 1) % clock->size];
-
- /* First step, PTS to SOF conversion. */
- delta_stc = buf->pts - (1UL << 31);
- x1 = first->dev_stc - delta_stc;
- x2 = last->dev_stc - delta_stc;
- if (x1 == x2)
- goto done;
-
- y1 = (first->dev_sof + 2048) << 16;
- y2 = (last->dev_sof + 2048) << 16;
- if (y2 < y1)
- y2 += 2048 << 16;
-
- y = (u64)(y2 - y1) * (1ULL << 31) + (u64)y1 * (u64)x2
- - (u64)y2 * (u64)x1;
- y = div_u64(y, x2 - x1);
-
- sof = y;
-
- uvc_trace(UVC_TRACE_CLOCK, "%s: PTS %u y %llu.%06llu SOF %u.%06llu "
- "(x1 %u x2 %u y1 %u y2 %u SOF offset %u)\n",
- stream->dev->name, buf->pts,
- y >> 16, div_u64((y & 0xffff) * 1000000, 65536),
- sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536),
- x1, x2, y1, y2, clock->sof_offset);
-
- /* Second step, SOF to host clock conversion. */
- x1 = (uvc_video_clock_host_sof(first) + 2048) << 16;
- x2 = (uvc_video_clock_host_sof(last) + 2048) << 16;
- if (x2 < x1)
- x2 += 2048 << 16;
- if (x1 == x2)
- goto done;
-
- ts = timespec_sub(last->host_ts, first->host_ts);
- y1 = NSEC_PER_SEC;
- y2 = (ts.tv_sec + 1) * NSEC_PER_SEC + ts.tv_nsec;
-
- /* Interpolated and host SOF timestamps can wrap around at slightly
- * different times. Handle this by adding or removing 2048 to or from
- * the computed SOF value to keep it close to the SOF samples mean
- * value.
- */
- mean = (x1 + x2) / 2;
- if (mean - (1024 << 16) > sof)
- sof += 2048 << 16;
- else if (sof > mean + (1024 << 16))
- sof -= 2048 << 16;
-
- y = (u64)(y2 - y1) * (u64)sof + (u64)y1 * (u64)x2
- - (u64)y2 * (u64)x1;
- y = div_u64(y, x2 - x1);
-
- div = div_u64_rem(y, NSEC_PER_SEC, &rem);
- ts.tv_sec = first->host_ts.tv_sec - 1 + div;
- ts.tv_nsec = first->host_ts.tv_nsec + rem;
- if (ts.tv_nsec >= NSEC_PER_SEC) {
- ts.tv_sec++;
- ts.tv_nsec -= NSEC_PER_SEC;
- }
-
- uvc_trace(UVC_TRACE_CLOCK, "%s: SOF %u.%06llu y %llu ts %lu.%06lu "
- "buf ts %lu.%06lu (x1 %u/%u/%u x2 %u/%u/%u y1 %u y2 %u)\n",
- stream->dev->name,
- sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536),
- y, ts.tv_sec, ts.tv_nsec / NSEC_PER_USEC,
- v4l2_buf->timestamp.tv_sec, v4l2_buf->timestamp.tv_usec,
- x1, first->host_sof, first->dev_sof,
- x2, last->host_sof, last->dev_sof, y1, y2);
-
- /* Update the V4L2 buffer. */
- v4l2_buf->timestamp.tv_sec = ts.tv_sec;
- v4l2_buf->timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
-
-done:
- spin_unlock_irqrestore(&stream->clock.lock, flags);
-}
-
-/* ------------------------------------------------------------------------
- * Stream statistics
- */
-
-static void uvc_video_stats_decode(struct uvc_streaming *stream,
- const __u8 *data, int len)
-{
- unsigned int header_size;
- bool has_pts = false;
- bool has_scr = false;
- u16 uninitialized_var(scr_sof);
- u32 uninitialized_var(scr_stc);
- u32 uninitialized_var(pts);
-
- if (stream->stats.stream.nb_frames == 0 &&
- stream->stats.frame.nb_packets == 0)
- ktime_get_ts(&stream->stats.stream.start_ts);
-
- switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) {
- case UVC_STREAM_PTS | UVC_STREAM_SCR:
- header_size = 12;
- has_pts = true;
- has_scr = true;
- break;
- case UVC_STREAM_PTS:
- header_size = 6;
- has_pts = true;
- break;
- case UVC_STREAM_SCR:
- header_size = 8;
- has_scr = true;
- break;
- default:
- header_size = 2;
- break;
- }
-
- /* Check for invalid headers. */
- if (len < header_size || data[0] < header_size) {
- stream->stats.frame.nb_invalid++;
- return;
- }
-
- /* Extract the timestamps. */
- if (has_pts)
- pts = get_unaligned_le32(&data[2]);
-
- if (has_scr) {
- scr_stc = get_unaligned_le32(&data[header_size - 6]);
- scr_sof = get_unaligned_le16(&data[header_size - 2]);
- }
-
- /* Is PTS constant through the whole frame ? */
- if (has_pts && stream->stats.frame.nb_pts) {
- if (stream->stats.frame.pts != pts) {
- stream->stats.frame.nb_pts_diffs++;
- stream->stats.frame.last_pts_diff =
- stream->stats.frame.nb_packets;
- }
- }
-
- if (has_pts) {
- stream->stats.frame.nb_pts++;
- stream->stats.frame.pts = pts;
- }
-
- /* Do all frames have a PTS in their first non-empty packet, or before
- * their first empty packet ?
- */
- if (stream->stats.frame.size == 0) {
- if (len > header_size)
- stream->stats.frame.has_initial_pts = has_pts;
- if (len == header_size && has_pts)
- stream->stats.frame.has_early_pts = true;
- }
-
- /* Do the SCR.STC and SCR.SOF fields vary through the frame ? */
- if (has_scr && stream->stats.frame.nb_scr) {
- if (stream->stats.frame.scr_stc != scr_stc)
- stream->stats.frame.nb_scr_diffs++;
- }
-
- if (has_scr) {
- /* Expand the SOF counter to 32 bits and store its value. */
- if (stream->stats.stream.nb_frames > 0 ||
- stream->stats.frame.nb_scr > 0)
- stream->stats.stream.scr_sof_count +=
- (scr_sof - stream->stats.stream.scr_sof) % 2048;
- stream->stats.stream.scr_sof = scr_sof;
-
- stream->stats.frame.nb_scr++;
- stream->stats.frame.scr_stc = scr_stc;
- stream->stats.frame.scr_sof = scr_sof;
-
- if (scr_sof < stream->stats.stream.min_sof)
- stream->stats.stream.min_sof = scr_sof;
- if (scr_sof > stream->stats.stream.max_sof)
- stream->stats.stream.max_sof = scr_sof;
- }
-
- /* Record the first non-empty packet number. */
- if (stream->stats.frame.size == 0 && len > header_size)
- stream->stats.frame.first_data = stream->stats.frame.nb_packets;
-
- /* Update the frame size. */
- stream->stats.frame.size += len - header_size;
-
- /* Update the packets counters. */
- stream->stats.frame.nb_packets++;
- if (len > header_size)
- stream->stats.frame.nb_empty++;
-
- if (data[1] & UVC_STREAM_ERR)
- stream->stats.frame.nb_errors++;
-}
-
-static void uvc_video_stats_update(struct uvc_streaming *stream)
-{
- struct uvc_stats_frame *frame = &stream->stats.frame;
-
- uvc_trace(UVC_TRACE_STATS, "frame %u stats: %u/%u/%u packets, "
- "%u/%u/%u pts (%searly %sinitial), %u/%u scr, "
- "last pts/stc/sof %u/%u/%u\n",
- stream->sequence, frame->first_data,
- frame->nb_packets - frame->nb_empty, frame->nb_packets,
- frame->nb_pts_diffs, frame->last_pts_diff, frame->nb_pts,
- frame->has_early_pts ? "" : "!",
- frame->has_initial_pts ? "" : "!",
- frame->nb_scr_diffs, frame->nb_scr,
- frame->pts, frame->scr_stc, frame->scr_sof);
-
- stream->stats.stream.nb_frames++;
- stream->stats.stream.nb_packets += stream->stats.frame.nb_packets;
- stream->stats.stream.nb_empty += stream->stats.frame.nb_empty;
- stream->stats.stream.nb_errors += stream->stats.frame.nb_errors;
- stream->stats.stream.nb_invalid += stream->stats.frame.nb_invalid;
-
- if (frame->has_early_pts)
- stream->stats.stream.nb_pts_early++;
- if (frame->has_initial_pts)
- stream->stats.stream.nb_pts_initial++;
- if (frame->last_pts_diff <= frame->first_data)
- stream->stats.stream.nb_pts_constant++;
- if (frame->nb_scr >= frame->nb_packets - frame->nb_empty)
- stream->stats.stream.nb_scr_count_ok++;
- if (frame->nb_scr_diffs + 1 == frame->nb_scr)
- stream->stats.stream.nb_scr_diffs_ok++;
-
- memset(&stream->stats.frame, 0, sizeof(stream->stats.frame));
-}
-
-size_t uvc_video_stats_dump(struct uvc_streaming *stream, char *buf,
- size_t size)
-{
- unsigned int scr_sof_freq;
- unsigned int duration;
- struct timespec ts;
- size_t count = 0;
-
- ts.tv_sec = stream->stats.stream.stop_ts.tv_sec
- - stream->stats.stream.start_ts.tv_sec;
- ts.tv_nsec = stream->stats.stream.stop_ts.tv_nsec
- - stream->stats.stream.start_ts.tv_nsec;
- if (ts.tv_nsec < 0) {
- ts.tv_sec--;
- ts.tv_nsec += 1000000000;
- }
-
- /* Compute the SCR.SOF frequency estimate. At the nominal 1kHz SOF
- * frequency this will not overflow before more than 1h.
- */
- duration = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
- if (duration != 0)
- scr_sof_freq = stream->stats.stream.scr_sof_count * 1000
- / duration;
- else
- scr_sof_freq = 0;
-
- count += scnprintf(buf + count, size - count,
- "frames: %u\npackets: %u\nempty: %u\n"
- "errors: %u\ninvalid: %u\n",
- stream->stats.stream.nb_frames,
- stream->stats.stream.nb_packets,
- stream->stats.stream.nb_empty,
- stream->stats.stream.nb_errors,
- stream->stats.stream.nb_invalid);
- count += scnprintf(buf + count, size - count,
- "pts: %u early, %u initial, %u ok\n",
- stream->stats.stream.nb_pts_early,
- stream->stats.stream.nb_pts_initial,
- stream->stats.stream.nb_pts_constant);
- count += scnprintf(buf + count, size - count,
- "scr: %u count ok, %u diff ok\n",
- stream->stats.stream.nb_scr_count_ok,
- stream->stats.stream.nb_scr_diffs_ok);
- count += scnprintf(buf + count, size - count,
- "sof: %u <= sof <= %u, freq %u.%03u kHz\n",
- stream->stats.stream.min_sof,
- stream->stats.stream.max_sof,
- scr_sof_freq / 1000, scr_sof_freq % 1000);
-
- return count;
-}
-
-static void uvc_video_stats_start(struct uvc_streaming *stream)
-{
- memset(&stream->stats, 0, sizeof(stream->stats));
- stream->stats.stream.min_sof = 2048;
-}
-
-static void uvc_video_stats_stop(struct uvc_streaming *stream)
-{
- ktime_get_ts(&stream->stats.stream.stop_ts);
-}
-
-/* ------------------------------------------------------------------------
- * Video codecs
- */
-
-/* Video payload decoding is handled by uvc_video_decode_start(),
- * uvc_video_decode_data() and uvc_video_decode_end().
- *
- * uvc_video_decode_start is called with URB data at the start of a bulk or
- * isochronous payload. It processes header data and returns the header size
- * in bytes if successful. If an error occurs, it returns a negative error
- * code. The following error codes have special meanings.
- *
- * - EAGAIN informs the caller that the current video buffer should be marked
- * as done, and that the function should be called again with the same data
- * and a new video buffer. This is used when end of frame conditions can be
- * reliably detected at the beginning of the next frame only.
- *
- * If an error other than -EAGAIN is returned, the caller will drop the current
- * payload. No call to uvc_video_decode_data and uvc_video_decode_end will be
- * made until the next payload. -ENODATA can be used to drop the current
- * payload if no other error code is appropriate.
- *
- * uvc_video_decode_data is called for every URB with URB data. It copies the
- * data to the video buffer.
- *
- * uvc_video_decode_end is called with header data at the end of a bulk or
- * isochronous payload. It performs any additional header data processing and
- * returns 0 or a negative error code if an error occurred. As header data have
- * already been processed by uvc_video_decode_start, this functions isn't
- * required to perform sanity checks a second time.
- *
- * For isochronous transfers where a payload is always transferred in a single
- * URB, the three functions will be called in a row.
- *
- * To let the decoder process header data and update its internal state even
- * when no video buffer is available, uvc_video_decode_start must be prepared
- * to be called with a NULL buf parameter. uvc_video_decode_data and
- * uvc_video_decode_end will never be called with a NULL buffer.
- */
-static int uvc_video_decode_start(struct uvc_streaming *stream,
- struct uvc_buffer *buf, const __u8 *data, int len)
-{
- __u8 fid;
-
- /* Sanity checks:
- * - packet must be at least 2 bytes long
- * - bHeaderLength value must be at least 2 bytes (see above)
- * - bHeaderLength value can't be larger than the packet size.
- */
- if (len < 2 || data[0] < 2 || data[0] > len) {
- stream->stats.frame.nb_invalid++;
- return -EINVAL;
- }
-
- fid = data[1] & UVC_STREAM_FID;
-
- /* Increase the sequence number regardless of any buffer states, so
- * that discontinuous sequence numbers always indicate lost frames.
- */
- if (stream->last_fid != fid) {
- stream->sequence++;
- if (stream->sequence)
- uvc_video_stats_update(stream);
- }
-
- uvc_video_clock_decode(stream, buf, data, len);
- uvc_video_stats_decode(stream, data, len);
-
- /* Store the payload FID bit and return immediately when the buffer is
- * NULL.
- */
- if (buf == NULL) {
- stream->last_fid = fid;
- return -ENODATA;
- }
-
- /* Mark the buffer as bad if the error bit is set. */
- if (data[1] & UVC_STREAM_ERR) {
- uvc_trace(UVC_TRACE_FRAME, "Marking buffer as bad (error bit "
- "set).\n");
- buf->error = 1;
- }
-
- /* Synchronize to the input stream by waiting for the FID bit to be
- * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE.
- * stream->last_fid is initialized to -1, so the first isochronous
- * frame will always be in sync.
- *
- * If the device doesn't toggle the FID bit, invert stream->last_fid
- * when the EOF bit is set to force synchronisation on the next packet.
- */
- if (buf->state != UVC_BUF_STATE_ACTIVE) {
- struct timespec ts;
-
- if (fid == stream->last_fid) {
- uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of "
- "sync).\n");
- if ((stream->dev->quirks & UVC_QUIRK_STREAM_NO_FID) &&
- (data[1] & UVC_STREAM_EOF))
- stream->last_fid ^= UVC_STREAM_FID;
- return -ENODATA;
- }
-
- if (uvc_clock_param == CLOCK_MONOTONIC)
- ktime_get_ts(&ts);
- else
- ktime_get_real_ts(&ts);
-
- buf->buf.v4l2_buf.sequence = stream->sequence;
- buf->buf.v4l2_buf.timestamp.tv_sec = ts.tv_sec;
- buf->buf.v4l2_buf.timestamp.tv_usec =
- ts.tv_nsec / NSEC_PER_USEC;
-
- /* TODO: Handle PTS and SCR. */
- buf->state = UVC_BUF_STATE_ACTIVE;
- }
-
- /* Mark the buffer as done if we're at the beginning of a new frame.
- * End of frame detection is better implemented by checking the EOF
- * bit (FID bit toggling is delayed by one frame compared to the EOF
- * bit), but some devices don't set the bit at end of frame (and the
- * last payload can be lost anyway). We thus must check if the FID has
- * been toggled.
- *
- * stream->last_fid is initialized to -1, so the first isochronous
- * frame will never trigger an end of frame detection.
- *
- * Empty buffers (bytesused == 0) don't trigger end of frame detection
- * as it doesn't make sense to return an empty buffer. This also
- * avoids detecting end of frame conditions at FID toggling if the
- * previous payload had the EOF bit set.
- */
- if (fid != stream->last_fid && buf->bytesused != 0) {
- uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit "
- "toggled).\n");
- buf->state = UVC_BUF_STATE_READY;
- return -EAGAIN;
- }
-
- stream->last_fid = fid;
-
- return data[0];
-}
-
-static void uvc_video_decode_data(struct uvc_streaming *stream,
- struct uvc_buffer *buf, const __u8 *data, int len)
-{
- unsigned int maxlen, nbytes;
- void *mem;
-
- if (len <= 0)
- return;
-
- /* Copy the video data to the buffer. */
- maxlen = buf->length - buf->bytesused;
- mem = buf->mem + buf->bytesused;
- nbytes = min((unsigned int)len, maxlen);
- memcpy(mem, data, nbytes);
- buf->bytesused += nbytes;
-
- /* Complete the current frame if the buffer size was exceeded. */
- if (len > maxlen) {
- uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n");
- buf->state = UVC_BUF_STATE_READY;
- }
-}
-
-static void uvc_video_decode_end(struct uvc_streaming *stream,
- struct uvc_buffer *buf, const __u8 *data, int len)
-{
- /* Mark the buffer as done if the EOF marker is set. */
- if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) {
- uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n");
- if (data[0] == len)
- uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n");
- buf->state = UVC_BUF_STATE_READY;
- if (stream->dev->quirks & UVC_QUIRK_STREAM_NO_FID)
- stream->last_fid ^= UVC_STREAM_FID;
- }
-}
-
-/* Video payload encoding is handled by uvc_video_encode_header() and
- * uvc_video_encode_data(). Only bulk transfers are currently supported.
- *
- * uvc_video_encode_header is called at the start of a payload. It adds header
- * data to the transfer buffer and returns the header size. As the only known
- * UVC output device transfers a whole frame in a single payload, the EOF bit
- * is always set in the header.
- *
- * uvc_video_encode_data is called for every URB and copies the data from the
- * video buffer to the transfer buffer.
- */
-static int uvc_video_encode_header(struct uvc_streaming *stream,
- struct uvc_buffer *buf, __u8 *data, int len)
-{
- data[0] = 2; /* Header length */
- data[1] = UVC_STREAM_EOH | UVC_STREAM_EOF
- | (stream->last_fid & UVC_STREAM_FID);
- return 2;
-}
-
-static int uvc_video_encode_data(struct uvc_streaming *stream,
- struct uvc_buffer *buf, __u8 *data, int len)
-{
- struct uvc_video_queue *queue = &stream->queue;
- unsigned int nbytes;
- void *mem;
-
- /* Copy video data to the URB buffer. */
- mem = buf->mem + queue->buf_used;
- nbytes = min((unsigned int)len, buf->bytesused - queue->buf_used);
- nbytes = min(stream->bulk.max_payload_size - stream->bulk.payload_size,
- nbytes);
- memcpy(data, mem, nbytes);
-
- queue->buf_used += nbytes;
-
- return nbytes;
-}
-
-/* ------------------------------------------------------------------------
- * URB handling
- */
-
-/*
- * Completion handler for video URBs.
- */
-static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream,
- struct uvc_buffer *buf)
-{
- u8 *mem;
- int ret, i;
-
- for (i = 0; i < urb->number_of_packets; ++i) {
- if (urb->iso_frame_desc[i].status < 0) {
- uvc_trace(UVC_TRACE_FRAME, "USB isochronous frame "
- "lost (%d).\n", urb->iso_frame_desc[i].status);
- /* Mark the buffer as faulty. */
- if (buf != NULL)
- buf->error = 1;
- continue;
- }
-
- /* Decode the payload header. */
- mem = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
- do {
- ret = uvc_video_decode_start(stream, buf, mem,
- urb->iso_frame_desc[i].actual_length);
- if (ret == -EAGAIN)
- buf = uvc_queue_next_buffer(&stream->queue,
- buf);
- } while (ret == -EAGAIN);
-
- if (ret < 0)
- continue;
-
- /* Decode the payload data. */
- uvc_video_decode_data(stream, buf, mem + ret,
- urb->iso_frame_desc[i].actual_length - ret);
-
- /* Process the header again. */
- uvc_video_decode_end(stream, buf, mem,
- urb->iso_frame_desc[i].actual_length);
-
- if (buf->state == UVC_BUF_STATE_READY) {
- if (buf->length != buf->bytesused &&
- !(stream->cur_format->flags &
- UVC_FMT_FLAG_COMPRESSED))
- buf->error = 1;
-
- buf = uvc_queue_next_buffer(&stream->queue, buf);
- }
- }
-}
-
-static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
- struct uvc_buffer *buf)
-{
- u8 *mem;
- int len, ret;
-
- /*
- * Ignore ZLPs if they're not part of a frame, otherwise process them
- * to trigger the end of payload detection.
- */
- if (urb->actual_length == 0 && stream->bulk.header_size == 0)
- return;
-
- mem = urb->transfer_buffer;
- len = urb->actual_length;
- stream->bulk.payload_size += len;
-
- /* If the URB is the first of its payload, decode and save the
- * header.
- */
- if (stream->bulk.header_size == 0 && !stream->bulk.skip_payload) {
- do {
- ret = uvc_video_decode_start(stream, buf, mem, len);
- if (ret == -EAGAIN)
- buf = uvc_queue_next_buffer(&stream->queue,
- buf);
- } while (ret == -EAGAIN);
-
- /* If an error occurred skip the rest of the payload. */
- if (ret < 0 || buf == NULL) {
- stream->bulk.skip_payload = 1;
- } else {
- memcpy(stream->bulk.header, mem, ret);
- stream->bulk.header_size = ret;
-
- mem += ret;
- len -= ret;
- }
- }
-
- /* The buffer queue might have been cancelled while a bulk transfer
- * was in progress, so we can reach here with buf equal to NULL. Make
- * sure buf is never dereferenced if NULL.
- */
-
- /* Process video data. */
- if (!stream->bulk.skip_payload && buf != NULL)
- uvc_video_decode_data(stream, buf, mem, len);
-
- /* Detect the payload end by a URB smaller than the maximum size (or
- * a payload size equal to the maximum) and process the header again.
- */
- if (urb->actual_length < urb->transfer_buffer_length ||
- stream->bulk.payload_size >= stream->bulk.max_payload_size) {
- if (!stream->bulk.skip_payload && buf != NULL) {
- uvc_video_decode_end(stream, buf, stream->bulk.header,
- stream->bulk.payload_size);
- if (buf->state == UVC_BUF_STATE_READY)
- buf = uvc_queue_next_buffer(&stream->queue,
- buf);
- }
-
- stream->bulk.header_size = 0;
- stream->bulk.skip_payload = 0;
- stream->bulk.payload_size = 0;
- }
-}
-
-static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream,
- struct uvc_buffer *buf)
-{
- u8 *mem = urb->transfer_buffer;
- int len = stream->urb_size, ret;
-
- if (buf == NULL) {
- urb->transfer_buffer_length = 0;
- return;
- }
-
- /* If the URB is the first of its payload, add the header. */
- if (stream->bulk.header_size == 0) {
- ret = uvc_video_encode_header(stream, buf, mem, len);
- stream->bulk.header_size = ret;
- stream->bulk.payload_size += ret;
- mem += ret;
- len -= ret;
- }
-
- /* Process video data. */
- ret = uvc_video_encode_data(stream, buf, mem, len);
-
- stream->bulk.payload_size += ret;
- len -= ret;
-
- if (buf->bytesused == stream->queue.buf_used ||
- stream->bulk.payload_size == stream->bulk.max_payload_size) {
- if (buf->bytesused == stream->queue.buf_used) {
- stream->queue.buf_used = 0;
- buf->state = UVC_BUF_STATE_READY;
- buf->buf.v4l2_buf.sequence = ++stream->sequence;
- uvc_queue_next_buffer(&stream->queue, buf);
- stream->last_fid ^= UVC_STREAM_FID;
- }
-
- stream->bulk.header_size = 0;
- stream->bulk.payload_size = 0;
- }
-
- urb->transfer_buffer_length = stream->urb_size - len;
-}
-
-static void uvc_video_complete(struct urb *urb)
-{
- struct uvc_streaming *stream = urb->context;
- struct uvc_video_queue *queue = &stream->queue;
- struct uvc_buffer *buf = NULL;
- unsigned long flags;
- int ret;
-
- switch (urb->status) {
- case 0:
- break;
-
- default:
- uvc_printk(KERN_WARNING, "Non-zero status (%d) in video "
- "completion handler.\n", urb->status);
-
- case -ENOENT: /* usb_kill_urb() called. */
- if (stream->frozen)
- return;
-
- case -ECONNRESET: /* usb_unlink_urb() called. */
- case -ESHUTDOWN: /* The endpoint is being disabled. */
- uvc_queue_cancel(queue, urb->status == -ESHUTDOWN);
- return;
- }
-
- spin_lock_irqsave(&queue->irqlock, flags);
- if (!list_empty(&queue->irqqueue))
- buf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
- queue);
- spin_unlock_irqrestore(&queue->irqlock, flags);
-
- stream->decode(urb, stream, buf);
-
- if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n",
- ret);
- }
-}
-
-/*
- * Free transfer buffers.
- */
-static void uvc_free_urb_buffers(struct uvc_streaming *stream)
-{
- unsigned int i;
-
- for (i = 0; i < UVC_URBS; ++i) {
- if (stream->urb_buffer[i]) {
-#ifndef CONFIG_DMA_NONCOHERENT
- usb_free_coherent(stream->dev->udev, stream->urb_size,
- stream->urb_buffer[i], stream->urb_dma[i]);
-#else
- kfree(stream->urb_buffer[i]);
-#endif
- stream->urb_buffer[i] = NULL;
- }
- }
-
- stream->urb_size = 0;
-}
-
-/*
- * Allocate transfer buffers. This function can be called with buffers
- * already allocated when resuming from suspend, in which case it will
- * return without touching the buffers.
- *
- * Limit the buffer size to UVC_MAX_PACKETS bulk/isochronous packets. If the
- * system is too low on memory try successively smaller numbers of packets
- * until allocation succeeds.
- *
- * Return the number of allocated packets on success or 0 when out of memory.
- */
-static int uvc_alloc_urb_buffers(struct uvc_streaming *stream,
- unsigned int size, unsigned int psize, gfp_t gfp_flags)
-{
- unsigned int npackets;
- unsigned int i;
-
- /* Buffers are already allocated, bail out. */
- if (stream->urb_size)
- return stream->urb_size / psize;
-
- /* Compute the number of packets. Bulk endpoints might transfer UVC
- * payloads across multiple URBs.
- */
- npackets = DIV_ROUND_UP(size, psize);
- if (npackets > UVC_MAX_PACKETS)
- npackets = UVC_MAX_PACKETS;
-
- /* Retry allocations until one succeed. */
- for (; npackets > 1; npackets /= 2) {
- for (i = 0; i < UVC_URBS; ++i) {
- stream->urb_size = psize * npackets;
-#ifndef CONFIG_DMA_NONCOHERENT
- stream->urb_buffer[i] = usb_alloc_coherent(
- stream->dev->udev, stream->urb_size,
- gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]);
-#else
- stream->urb_buffer[i] =
- kmalloc(stream->urb_size, gfp_flags | __GFP_NOWARN);
-#endif
- if (!stream->urb_buffer[i]) {
- uvc_free_urb_buffers(stream);
- break;
- }
- }
-
- if (i == UVC_URBS) {
- uvc_trace(UVC_TRACE_VIDEO, "Allocated %u URB buffers "
- "of %ux%u bytes each.\n", UVC_URBS, npackets,
- psize);
- return npackets;
- }
- }
-
- uvc_trace(UVC_TRACE_VIDEO, "Failed to allocate URB buffers (%u bytes "
- "per packet).\n", psize);
- return 0;
-}
-
-/*
- * Uninitialize isochronous/bulk URBs and free transfer buffers.
- */
-static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers)
-{
- struct urb *urb;
- unsigned int i;
-
- uvc_video_stats_stop(stream);
-
- for (i = 0; i < UVC_URBS; ++i) {
- urb = stream->urb[i];
- if (urb == NULL)
- continue;
-
- usb_kill_urb(urb);
- usb_free_urb(urb);
- stream->urb[i] = NULL;
- }
-
- if (free_buffers)
- uvc_free_urb_buffers(stream);
-}
-
-/*
- * Initialize isochronous URBs and allocate transfer buffers. The packet size
- * is given by the endpoint.
- */
-static int uvc_init_video_isoc(struct uvc_streaming *stream,
- struct usb_host_endpoint *ep, gfp_t gfp_flags)
-{
- struct urb *urb;
- unsigned int npackets, i, j;
- u16 psize;
- u32 size;
-
- psize = le16_to_cpu(ep->desc.wMaxPacketSize);
- psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
- size = stream->ctrl.dwMaxVideoFrameSize;
-
- npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags);
- if (npackets == 0)
- return -ENOMEM;
-
- size = npackets * psize;
-
- for (i = 0; i < UVC_URBS; ++i) {
- urb = usb_alloc_urb(npackets, gfp_flags);
- if (urb == NULL) {
- uvc_uninit_video(stream, 1);
- return -ENOMEM;
- }
-
- urb->dev = stream->dev->udev;
- urb->context = stream;
- urb->pipe = usb_rcvisocpipe(stream->dev->udev,
- ep->desc.bEndpointAddress);
-#ifndef CONFIG_DMA_NONCOHERENT
- urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
- urb->transfer_dma = stream->urb_dma[i];
-#else
- urb->transfer_flags = URB_ISO_ASAP;
-#endif
- urb->interval = ep->desc.bInterval;
- urb->transfer_buffer = stream->urb_buffer[i];
- urb->complete = uvc_video_complete;
- urb->number_of_packets = npackets;
- urb->transfer_buffer_length = size;
-
- for (j = 0; j < npackets; ++j) {
- urb->iso_frame_desc[j].offset = j * psize;
- urb->iso_frame_desc[j].length = psize;
- }
-
- stream->urb[i] = urb;
- }
-
- return 0;
-}
-
-/*
- * Initialize bulk URBs and allocate transfer buffers. The packet size is
- * given by the endpoint.
- */
-static int uvc_init_video_bulk(struct uvc_streaming *stream,
- struct usb_host_endpoint *ep, gfp_t gfp_flags)
-{
- struct urb *urb;
- unsigned int npackets, pipe, i;
- u16 psize;
- u32 size;
-
- psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff;
- size = stream->ctrl.dwMaxPayloadTransferSize;
- stream->bulk.max_payload_size = size;
-
- npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags);
- if (npackets == 0)
- return -ENOMEM;
-
- size = npackets * psize;
-
- if (usb_endpoint_dir_in(&ep->desc))
- pipe = usb_rcvbulkpipe(stream->dev->udev,
- ep->desc.bEndpointAddress);
- else
- pipe = usb_sndbulkpipe(stream->dev->udev,
- ep->desc.bEndpointAddress);
-
- if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
- size = 0;
-
- for (i = 0; i < UVC_URBS; ++i) {
- urb = usb_alloc_urb(0, gfp_flags);
- if (urb == NULL) {
- uvc_uninit_video(stream, 1);
- return -ENOMEM;
- }
-
- usb_fill_bulk_urb(urb, stream->dev->udev, pipe,
- stream->urb_buffer[i], size, uvc_video_complete,
- stream);
-#ifndef CONFIG_DMA_NONCOHERENT
- urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
- urb->transfer_dma = stream->urb_dma[i];
-#endif
-
- stream->urb[i] = urb;
- }
-
- return 0;
-}
-
-/*
- * Initialize isochronous/bulk URBs and allocate transfer buffers.
- */
-static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
-{
- struct usb_interface *intf = stream->intf;
- struct usb_host_endpoint *ep;
- unsigned int i;
- int ret;
-
- stream->sequence = -1;
- stream->last_fid = -1;
- stream->bulk.header_size = 0;
- stream->bulk.skip_payload = 0;
- stream->bulk.payload_size = 0;
-
- uvc_video_stats_start(stream);
-
- if (intf->num_altsetting > 1) {
- struct usb_host_endpoint *best_ep = NULL;
- unsigned int best_psize = 3 * 1024;
- unsigned int bandwidth;
- unsigned int uninitialized_var(altsetting);
- int intfnum = stream->intfnum;
-
- /* Isochronous endpoint, select the alternate setting. */
- bandwidth = stream->ctrl.dwMaxPayloadTransferSize;
-
- if (bandwidth == 0) {
- uvc_trace(UVC_TRACE_VIDEO, "Device requested null "
- "bandwidth, defaulting to lowest.\n");
- bandwidth = 1;
- } else {
- uvc_trace(UVC_TRACE_VIDEO, "Device requested %u "
- "B/frame bandwidth.\n", bandwidth);
- }
-
- for (i = 0; i < intf->num_altsetting; ++i) {
- struct usb_host_interface *alts;
- unsigned int psize;
-
- alts = &intf->altsetting[i];
- ep = uvc_find_endpoint(alts,
- stream->header.bEndpointAddress);
- if (ep == NULL)
- continue;
-
- /* Check if the bandwidth is high enough. */
- psize = le16_to_cpu(ep->desc.wMaxPacketSize);
- psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
- if (psize >= bandwidth && psize <= best_psize) {
- altsetting = alts->desc.bAlternateSetting;
- best_psize = psize;
- best_ep = ep;
- }
- }
-
- if (best_ep == NULL) {
- uvc_trace(UVC_TRACE_VIDEO, "No fast enough alt setting "
- "for requested bandwidth.\n");
- return -EIO;
- }
-
- uvc_trace(UVC_TRACE_VIDEO, "Selecting alternate setting %u "
- "(%u B/frame bandwidth).\n", altsetting, best_psize);
-
- ret = usb_set_interface(stream->dev->udev, intfnum, altsetting);
- if (ret < 0)
- return ret;
-
- ret = uvc_init_video_isoc(stream, best_ep, gfp_flags);
- } else {
- /* Bulk endpoint, proceed to URB initialization. */
- ep = uvc_find_endpoint(&intf->altsetting[0],
- stream->header.bEndpointAddress);
- if (ep == NULL)
- return -EIO;
-
- ret = uvc_init_video_bulk(stream, ep, gfp_flags);
- }
-
- if (ret < 0)
- return ret;
-
- /* Submit the URBs. */
- for (i = 0; i < UVC_URBS; ++i) {
- ret = usb_submit_urb(stream->urb[i], gfp_flags);
- if (ret < 0) {
- uvc_printk(KERN_ERR, "Failed to submit URB %u "
- "(%d).\n", i, ret);
- uvc_uninit_video(stream, 1);
- return ret;
- }
- }
-
- return 0;
-}
-
-/* --------------------------------------------------------------------------
- * Suspend/resume
- */
-
-/*
- * Stop streaming without disabling the video queue.
- *
- * To let userspace applications resume without trouble, we must not touch the
- * video buffers in any way. We mark the device as frozen to make sure the URB
- * completion handler won't try to cancel the queue when we kill the URBs.
- */
-int uvc_video_suspend(struct uvc_streaming *stream)
-{
- if (!uvc_queue_streaming(&stream->queue))
- return 0;
-
- stream->frozen = 1;
- uvc_uninit_video(stream, 0);
- usb_set_interface(stream->dev->udev, stream->intfnum, 0);
- return 0;
-}
-
-/*
- * Reconfigure the video interface and restart streaming if it was enabled
- * before suspend.
- *
- * If an error occurs, disable the video queue. This will wake all pending
- * buffers, making sure userspace applications are notified of the problem
- * instead of waiting forever.
- */
-int uvc_video_resume(struct uvc_streaming *stream, int reset)
-{
- int ret;
-
- /* If the bus has been reset on resume, set the alternate setting to 0.
- * This should be the default value, but some devices crash or otherwise
- * misbehave if they don't receive a SET_INTERFACE request before any
- * other video control request.
- */
- if (reset)
- usb_set_interface(stream->dev->udev, stream->intfnum, 0);
-
- stream->frozen = 0;
-
- uvc_video_clock_reset(stream);
-
- ret = uvc_commit_video(stream, &stream->ctrl);
- if (ret < 0) {
- uvc_queue_enable(&stream->queue, 0);
- return ret;
- }
-
- if (!uvc_queue_streaming(&stream->queue))
- return 0;
-
- ret = uvc_init_video(stream, GFP_NOIO);
- if (ret < 0)
- uvc_queue_enable(&stream->queue, 0);
-
- return ret;
-}
-
-/* ------------------------------------------------------------------------
- * Video device
- */
-
-/*
- * Initialize the UVC video device by switching to alternate setting 0 and
- * retrieve the default format.
- *
- * Some cameras (namely the Fuji Finepix) set the format and frame
- * indexes to zero. The UVC standard doesn't clearly make this a spec
- * violation, so try to silently fix the values if possible.
- *
- * This function is called before registering the device with V4L.
- */
-int uvc_video_init(struct uvc_streaming *stream)
-{
- struct uvc_streaming_control *probe = &stream->ctrl;
- struct uvc_format *format = NULL;
- struct uvc_frame *frame = NULL;
- unsigned int i;
- int ret;
-
- if (stream->nformats == 0) {
- uvc_printk(KERN_INFO, "No supported video formats found.\n");
- return -EINVAL;
- }
-
- atomic_set(&stream->active, 0);
-
- /* Initialize the video buffers queue. */
- uvc_queue_init(&stream->queue, stream->type, !uvc_no_drop_param);
-
- /* Alternate setting 0 should be the default, yet the XBox Live Vision
- * Cam (and possibly other devices) crash or otherwise misbehave if
- * they don't receive a SET_INTERFACE request before any other video
- * control request.
- */
- usb_set_interface(stream->dev->udev, stream->intfnum, 0);
-
- /* Set the streaming probe control with default streaming parameters
- * retrieved from the device. Webcams that don't suport GET_DEF
- * requests on the probe control will just keep their current streaming
- * parameters.
- */
- if (uvc_get_video_ctrl(stream, probe, 1, UVC_GET_DEF) == 0)
- uvc_set_video_ctrl(stream, probe, 1);
-
- /* Initialize the streaming parameters with the probe control current
- * value. This makes sure SET_CUR requests on the streaming commit
- * control will always use values retrieved from a successful GET_CUR
- * request on the probe control, as required by the UVC specification.
- */
- ret = uvc_get_video_ctrl(stream, probe, 1, UVC_GET_CUR);
- if (ret < 0)
- return ret;
-
- /* Check if the default format descriptor exists. Use the first
- * available format otherwise.
- */
- for (i = stream->nformats; i > 0; --i) {
- format = &stream->format[i-1];
- if (format->index == probe->bFormatIndex)
- break;
- }
-
- if (format->nframes == 0) {
- uvc_printk(KERN_INFO, "No frame descriptor found for the "
- "default format.\n");
- return -EINVAL;
- }
-
- /* Zero bFrameIndex might be correct. Stream-based formats (including
- * MPEG-2 TS and DV) do not support frames but have a dummy frame
- * descriptor with bFrameIndex set to zero. If the default frame
- * descriptor is not found, use the first available frame.
- */
- for (i = format->nframes; i > 0; --i) {
- frame = &format->frame[i-1];
- if (frame->bFrameIndex == probe->bFrameIndex)
- break;
- }
-
- probe->bFormatIndex = format->index;
- probe->bFrameIndex = frame->bFrameIndex;
-
- stream->cur_format = format;
- stream->cur_frame = frame;
-
- /* Select the video decoding function */
- if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- if (stream->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)
- stream->decode = uvc_video_decode_isight;
- else if (stream->intf->num_altsetting > 1)
- stream->decode = uvc_video_decode_isoc;
- else
- stream->decode = uvc_video_decode_bulk;
- } else {
- if (stream->intf->num_altsetting == 1)
- stream->decode = uvc_video_encode_bulk;
- else {
- uvc_printk(KERN_INFO, "Isochronous endpoints are not "
- "supported for video output devices.\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-/*
- * Enable or disable the video stream.
- */
-int uvc_video_enable(struct uvc_streaming *stream, int enable)
-{
- int ret;
-
- if (!enable) {
- uvc_uninit_video(stream, 1);
- usb_set_interface(stream->dev->udev, stream->intfnum, 0);
- uvc_queue_enable(&stream->queue, 0);
- uvc_video_clock_cleanup(stream);
- return 0;
- }
-
- ret = uvc_video_clock_init(stream);
- if (ret < 0)
- return ret;
-
- ret = uvc_queue_enable(&stream->queue, 1);
- if (ret < 0)
- goto error_queue;
-
- /* Commit the streaming parameters. */
- ret = uvc_commit_video(stream, &stream->ctrl);
- if (ret < 0)
- goto error_commit;
-
- ret = uvc_init_video(stream, GFP_KERNEL);
- if (ret < 0)
- goto error_video;
-
- return 0;
-
-error_video:
- usb_set_interface(stream->dev->udev, stream->intfnum, 0);
-error_commit:
- uvc_queue_enable(&stream->queue, 0);
-error_queue:
- uvc_video_clock_cleanup(stream);
-
- return ret;
-}
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
deleted file mode 100644
index 7c3d082505b..00000000000
--- a/drivers/media/video/uvc/uvcvideo.h
+++ /dev/null
@@ -1,709 +0,0 @@
-#ifndef _USB_VIDEO_H_
-#define _USB_VIDEO_H_
-
-#ifndef __KERNEL__
-#error "The uvcvideo.h header is deprecated, use linux/uvcvideo.h instead."
-#endif /* __KERNEL__ */
-
-#include <linux/kernel.h>
-#include <linux/poll.h>
-#include <linux/usb.h>
-#include <linux/usb/video.h>
-#include <linux/uvcvideo.h>
-#include <linux/videodev2.h>
-#include <media/media-device.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-fh.h>
-#include <media/videobuf2-core.h>
-
-/* --------------------------------------------------------------------------
- * UVC constants
- */
-
-#define UVC_TERM_INPUT 0x0000
-#define UVC_TERM_OUTPUT 0x8000
-#define UVC_TERM_DIRECTION(term) ((term)->type & 0x8000)
-
-#define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff)
-#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0)
-#define UVC_ENTITY_IS_TERM(entity) (((entity)->type & 0xff00) != 0)
-#define UVC_ENTITY_IS_ITERM(entity) \
- (UVC_ENTITY_IS_TERM(entity) && \
- ((entity)->type & 0x8000) == UVC_TERM_INPUT)
-#define UVC_ENTITY_IS_OTERM(entity) \
- (UVC_ENTITY_IS_TERM(entity) && \
- ((entity)->type & 0x8000) == UVC_TERM_OUTPUT)
-
-
-/* ------------------------------------------------------------------------
- * GUIDs
- */
-#define UVC_GUID_UVC_CAMERA \
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}
-#define UVC_GUID_UVC_OUTPUT \
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}
-#define UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT \
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
-#define UVC_GUID_UVC_PROCESSING \
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01}
-#define UVC_GUID_UVC_SELECTOR \
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02}
-
-#define UVC_GUID_FORMAT_MJPEG \
- { 'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, \
- 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
-#define UVC_GUID_FORMAT_YUY2 \
- { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \
- 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
-#define UVC_GUID_FORMAT_YUY2_ISIGHT \
- { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x38, 0x9b, 0x71}
-#define UVC_GUID_FORMAT_NV12 \
- { 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \
- 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
-#define UVC_GUID_FORMAT_YV12 \
- { 'Y', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \
- 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
-#define UVC_GUID_FORMAT_I420 \
- { 'I', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \
- 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
-#define UVC_GUID_FORMAT_UYVY \
- { 'U', 'Y', 'V', 'Y', 0x00, 0x00, 0x10, 0x00, \
- 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
-#define UVC_GUID_FORMAT_Y800 \
- { 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \
- 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
-#define UVC_GUID_FORMAT_Y16 \
- { 'Y', '1', '6', ' ', 0x00, 0x00, 0x10, 0x00, \
- 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
-#define UVC_GUID_FORMAT_BY8 \
- { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \
- 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
-#define UVC_GUID_FORMAT_RGBP \
- { 'R', 'G', 'B', 'P', 0x00, 0x00, 0x10, 0x00, \
- 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
-#define UVC_GUID_FORMAT_M420 \
- { 'M', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \
- 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
-
-#define UVC_GUID_FORMAT_H264 \
- { 'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, \
- 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
-
-/* ------------------------------------------------------------------------
- * Driver specific constants.
- */
-
-#define DRIVER_VERSION "1.1.1"
-
-/* Number of isochronous URBs. */
-#define UVC_URBS 5
-/* Maximum number of packets per URB. */
-#define UVC_MAX_PACKETS 32
-/* Maximum number of video buffers. */
-#define UVC_MAX_VIDEO_BUFFERS 32
-/* Maximum status buffer size in bytes of interrupt URB. */
-#define UVC_MAX_STATUS_SIZE 16
-
-#define UVC_CTRL_CONTROL_TIMEOUT 300
-#define UVC_CTRL_STREAMING_TIMEOUT 5000
-
-/* Maximum allowed number of control mappings per device */
-#define UVC_MAX_CONTROL_MAPPINGS 1024
-#define UVC_MAX_CONTROL_MENU_ENTRIES 32
-
-/* Devices quirks */
-#define UVC_QUIRK_STATUS_INTERVAL 0x00000001
-#define UVC_QUIRK_PROBE_MINMAX 0x00000002
-#define UVC_QUIRK_PROBE_EXTRAFIELDS 0x00000004
-#define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008
-#define UVC_QUIRK_STREAM_NO_FID 0x00000010
-#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020
-#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080
-#define UVC_QUIRK_PROBE_DEF 0x00000100
-#define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200
-
-/* Format flags */
-#define UVC_FMT_FLAG_COMPRESSED 0x00000001
-#define UVC_FMT_FLAG_STREAM 0x00000002
-
-/* ------------------------------------------------------------------------
- * Structures.
- */
-
-struct uvc_device;
-
-/* TODO: Put the most frequently accessed fields at the beginning of
- * structures to maximize cache efficiency.
- */
-struct uvc_control_info {
- struct list_head mappings;
-
- __u8 entity[16];
- __u8 index; /* Bit index in bmControls */
- __u8 selector;
-
- __u16 size;
- __u32 flags;
-};
-
-struct uvc_control_mapping {
- struct list_head list;
- struct list_head ev_subs;
-
- __u32 id;
- __u8 name[32];
- __u8 entity[16];
- __u8 selector;
-
- __u8 size;
- __u8 offset;
- enum v4l2_ctrl_type v4l2_type;
- __u32 data_type;
-
- struct uvc_menu_info *menu_info;
- __u32 menu_count;
-
- __u32 master_id;
- __s32 master_manual;
- __u32 slave_ids[2];
-
- __s32 (*get) (struct uvc_control_mapping *mapping, __u8 query,
- const __u8 *data);
- void (*set) (struct uvc_control_mapping *mapping, __s32 value,
- __u8 *data);
-};
-
-struct uvc_control {
- struct uvc_entity *entity;
- struct uvc_control_info info;
-
- __u8 index; /* Used to match the uvc_control entry with a
- uvc_control_info. */
- __u8 dirty:1,
- loaded:1,
- modified:1,
- cached:1,
- initialized:1;
-
- __u8 *uvc_data;
-};
-
-struct uvc_format_desc {
- char *name;
- __u8 guid[16];
- __u32 fcc;
-};
-
-/* The term 'entity' refers to both UVC units and UVC terminals.
- *
- * The type field is either the terminal type (wTerminalType in the terminal
- * descriptor), or the unit type (bDescriptorSubtype in the unit descriptor).
- * As the bDescriptorSubtype field is one byte long, the type value will
- * always have a null MSB for units. All terminal types defined by the UVC
- * specification have a non-null MSB, so it is safe to use the MSB to
- * differentiate between units and terminals as long as the descriptor parsing
- * code makes sure terminal types have a non-null MSB.
- *
- * For terminals, the type's most significant bit stores the terminal
- * direction (either UVC_TERM_INPUT or UVC_TERM_OUTPUT). The type field should
- * always be accessed with the UVC_ENTITY_* macros and never directly.
- */
-
-struct uvc_entity {
- struct list_head list; /* Entity as part of a UVC device. */
- struct list_head chain; /* Entity as part of a video device
- * chain. */
- __u8 id;
- __u16 type;
- char name[64];
-
- /* Media controller-related fields. */
- struct video_device *vdev;
- struct v4l2_subdev subdev;
- unsigned int num_pads;
- unsigned int num_links;
- struct media_pad *pads;
-
- union {
- struct {
- __u16 wObjectiveFocalLengthMin;
- __u16 wObjectiveFocalLengthMax;
- __u16 wOcularFocalLength;
- __u8 bControlSize;
- __u8 *bmControls;
- } camera;
-
- struct {
- __u8 bControlSize;
- __u8 *bmControls;
- __u8 bTransportModeSize;
- __u8 *bmTransportModes;
- } media;
-
- struct {
- } output;
-
- struct {
- __u16 wMaxMultiplier;
- __u8 bControlSize;
- __u8 *bmControls;
- __u8 bmVideoStandards;
- } processing;
-
- struct {
- } selector;
-
- struct {
- __u8 guidExtensionCode[16];
- __u8 bNumControls;
- __u8 bControlSize;
- __u8 *bmControls;
- __u8 *bmControlsType;
- } extension;
- };
-
- __u8 bNrInPins;
- __u8 *baSourceID;
-
- unsigned int ncontrols;
- struct uvc_control *controls;
-};
-
-struct uvc_frame {
- __u8 bFrameIndex;
- __u8 bmCapabilities;
- __u16 wWidth;
- __u16 wHeight;
- __u32 dwMinBitRate;
- __u32 dwMaxBitRate;
- __u32 dwMaxVideoFrameBufferSize;
- __u8 bFrameIntervalType;
- __u32 dwDefaultFrameInterval;
- __u32 *dwFrameInterval;
-};
-
-struct uvc_format {
- __u8 type;
- __u8 index;
- __u8 bpp;
- __u8 colorspace;
- __u32 fcc;
- __u32 flags;
-
- char name[32];
-
- unsigned int nframes;
- struct uvc_frame *frame;
-};
-
-struct uvc_streaming_header {
- __u8 bNumFormats;
- __u8 bEndpointAddress;
- __u8 bTerminalLink;
- __u8 bControlSize;
- __u8 *bmaControls;
- /* The following fields are used by input headers only. */
- __u8 bmInfo;
- __u8 bStillCaptureMethod;
- __u8 bTriggerSupport;
- __u8 bTriggerUsage;
-};
-
-enum uvc_buffer_state {
- UVC_BUF_STATE_IDLE = 0,
- UVC_BUF_STATE_QUEUED = 1,
- UVC_BUF_STATE_ACTIVE = 2,
- UVC_BUF_STATE_READY = 3,
- UVC_BUF_STATE_DONE = 4,
- UVC_BUF_STATE_ERROR = 5,
-};
-
-struct uvc_buffer {
- struct vb2_buffer buf;
- struct list_head queue;
-
- enum uvc_buffer_state state;
- unsigned int error;
-
- void *mem;
- unsigned int length;
- unsigned int bytesused;
-
- u32 pts;
-};
-
-#define UVC_QUEUE_DISCONNECTED (1 << 0)
-#define UVC_QUEUE_DROP_CORRUPTED (1 << 1)
-
-struct uvc_video_queue {
- struct vb2_queue queue;
- struct mutex mutex; /* Protects queue */
-
- unsigned int flags;
- unsigned int buf_used;
-
- spinlock_t irqlock; /* Protects irqqueue */
- struct list_head irqqueue;
-};
-
-struct uvc_video_chain {
- struct uvc_device *dev;
- struct list_head list;
-
- struct list_head entities; /* All entities */
- struct uvc_entity *processing; /* Processing unit */
- struct uvc_entity *selector; /* Selector unit */
-
- struct mutex ctrl_mutex; /* Protects ctrl.info */
-};
-
-struct uvc_stats_frame {
- unsigned int size; /* Number of bytes captured */
- unsigned int first_data; /* Index of the first non-empty packet */
-
- unsigned int nb_packets; /* Number of packets */
- unsigned int nb_empty; /* Number of empty packets */
- unsigned int nb_invalid; /* Number of packets with an invalid header */
- unsigned int nb_errors; /* Number of packets with the error bit set */
-
- unsigned int nb_pts; /* Number of packets with a PTS timestamp */
- unsigned int nb_pts_diffs; /* Number of PTS differences inside a frame */
- unsigned int last_pts_diff; /* Index of the last PTS difference */
- bool has_initial_pts; /* Whether the first non-empty packet has a PTS */
- bool has_early_pts; /* Whether a PTS is present before the first non-empty packet */
- u32 pts; /* PTS of the last packet */
-
- unsigned int nb_scr; /* Number of packets with a SCR timestamp */
- unsigned int nb_scr_diffs; /* Number of SCR.STC differences inside a frame */
- u16 scr_sof; /* SCR.SOF of the last packet */
- u32 scr_stc; /* SCR.STC of the last packet */
-};
-
-struct uvc_stats_stream {
- struct timespec start_ts; /* Stream start timestamp */
- struct timespec stop_ts; /* Stream stop timestamp */
-
- unsigned int nb_frames; /* Number of frames */
-
- unsigned int nb_packets; /* Number of packets */
- unsigned int nb_empty; /* Number of empty packets */
- unsigned int nb_invalid; /* Number of packets with an invalid header */
- unsigned int nb_errors; /* Number of packets with the error bit set */
-
- unsigned int nb_pts_constant; /* Number of frames with constant PTS */
- unsigned int nb_pts_early; /* Number of frames with early PTS */
- unsigned int nb_pts_initial; /* Number of frames with initial PTS */
-
- unsigned int nb_scr_count_ok; /* Number of frames with at least one SCR per non empty packet */
- unsigned int nb_scr_diffs_ok; /* Number of frames with varying SCR.STC */
- unsigned int scr_sof_count; /* STC.SOF counter accumulated since stream start */
- unsigned int scr_sof; /* STC.SOF of the last packet */
- unsigned int min_sof; /* Minimum STC.SOF value */
- unsigned int max_sof; /* Maximum STC.SOF value */
-};
-
-struct uvc_streaming {
- struct list_head list;
- struct uvc_device *dev;
- struct video_device *vdev;
- struct uvc_video_chain *chain;
- atomic_t active;
-
- struct usb_interface *intf;
- int intfnum;
- __u16 maxpsize;
-
- struct uvc_streaming_header header;
- enum v4l2_buf_type type;
-
- unsigned int nformats;
- struct uvc_format *format;
-
- struct uvc_streaming_control ctrl;
- struct uvc_format *cur_format;
- struct uvc_frame *cur_frame;
- /* Protect access to ctrl, cur_format, cur_frame and hardware video
- * probe control.
- */
- struct mutex mutex;
-
- /* Buffers queue. */
- unsigned int frozen : 1;
- struct uvc_video_queue queue;
- void (*decode) (struct urb *urb, struct uvc_streaming *video,
- struct uvc_buffer *buf);
-
- /* Context data used by the bulk completion handler. */
- struct {
- __u8 header[256];
- unsigned int header_size;
- int skip_payload;
- __u32 payload_size;
- __u32 max_payload_size;
- } bulk;
-
- struct urb *urb[UVC_URBS];
- char *urb_buffer[UVC_URBS];
- dma_addr_t urb_dma[UVC_URBS];
- unsigned int urb_size;
-
- __u32 sequence;
- __u8 last_fid;
-
- /* debugfs */
- struct dentry *debugfs_dir;
- struct {
- struct uvc_stats_frame frame;
- struct uvc_stats_stream stream;
- } stats;
-
- /* Timestamps support. */
- struct uvc_clock {
- struct uvc_clock_sample {
- u32 dev_stc;
- u16 dev_sof;
- struct timespec host_ts;
- u16 host_sof;
- } *samples;
-
- unsigned int head;
- unsigned int count;
- unsigned int size;
-
- u16 last_sof;
- u16 sof_offset;
-
- spinlock_t lock;
- } clock;
-};
-
-enum uvc_device_state {
- UVC_DEV_DISCONNECTED = 1,
-};
-
-struct uvc_device {
- struct usb_device *udev;
- struct usb_interface *intf;
- unsigned long warnings;
- __u32 quirks;
- int intfnum;
- char name[32];
-
- enum uvc_device_state state;
- atomic_t users;
- atomic_t nmappings;
-
- /* Video control interface */
-#ifdef CONFIG_MEDIA_CONTROLLER
- struct media_device mdev;
-#endif
- struct v4l2_device vdev;
- __u16 uvc_version;
- __u32 clock_frequency;
-
- struct list_head entities;
- struct list_head chains;
-
- /* Video Streaming interfaces */
- struct list_head streams;
- atomic_t nstreams;
-
- /* Status Interrupt Endpoint */
- struct usb_host_endpoint *int_ep;
- struct urb *int_urb;
- __u8 *status;
- struct input_dev *input;
- char input_phys[64];
-};
-
-enum uvc_handle_state {
- UVC_HANDLE_PASSIVE = 0,
- UVC_HANDLE_ACTIVE = 1,
-};
-
-struct uvc_fh {
- struct v4l2_fh vfh;
- struct uvc_video_chain *chain;
- struct uvc_streaming *stream;
- enum uvc_handle_state state;
-};
-
-struct uvc_driver {
- struct usb_driver driver;
-};
-
-/* ------------------------------------------------------------------------
- * Debugging, printing and logging
- */
-
-#define UVC_TRACE_PROBE (1 << 0)
-#define UVC_TRACE_DESCR (1 << 1)
-#define UVC_TRACE_CONTROL (1 << 2)
-#define UVC_TRACE_FORMAT (1 << 3)
-#define UVC_TRACE_CAPTURE (1 << 4)
-#define UVC_TRACE_CALLS (1 << 5)
-#define UVC_TRACE_IOCTL (1 << 6)
-#define UVC_TRACE_FRAME (1 << 7)
-#define UVC_TRACE_SUSPEND (1 << 8)
-#define UVC_TRACE_STATUS (1 << 9)
-#define UVC_TRACE_VIDEO (1 << 10)
-#define UVC_TRACE_STATS (1 << 11)
-#define UVC_TRACE_CLOCK (1 << 12)
-
-#define UVC_WARN_MINMAX 0
-#define UVC_WARN_PROBE_DEF 1
-#define UVC_WARN_XU_GET_RES 2
-
-extern unsigned int uvc_clock_param;
-extern unsigned int uvc_no_drop_param;
-extern unsigned int uvc_trace_param;
-extern unsigned int uvc_timeout_param;
-
-#define uvc_trace(flag, msg...) \
- do { \
- if (uvc_trace_param & flag) \
- printk(KERN_DEBUG "uvcvideo: " msg); \
- } while (0)
-
-#define uvc_warn_once(dev, warn, msg...) \
- do { \
- if (!test_and_set_bit(warn, &dev->warnings)) \
- printk(KERN_INFO "uvcvideo: " msg); \
- } while (0)
-
-#define uvc_printk(level, msg...) \
- printk(level "uvcvideo: " msg)
-
-/* --------------------------------------------------------------------------
- * Internal functions.
- */
-
-/* Core driver */
-extern struct uvc_driver uvc_driver;
-
-extern struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id);
-
-/* Video buffers queue management. */
-extern void uvc_queue_init(struct uvc_video_queue *queue,
- enum v4l2_buf_type type, int drop_corrupted);
-extern int uvc_alloc_buffers(struct uvc_video_queue *queue,
- struct v4l2_requestbuffers *rb);
-extern void uvc_free_buffers(struct uvc_video_queue *queue);
-extern int uvc_query_buffer(struct uvc_video_queue *queue,
- struct v4l2_buffer *v4l2_buf);
-extern int uvc_queue_buffer(struct uvc_video_queue *queue,
- struct v4l2_buffer *v4l2_buf);
-extern int uvc_dequeue_buffer(struct uvc_video_queue *queue,
- struct v4l2_buffer *v4l2_buf, int nonblocking);
-extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable);
-extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
-extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
- struct uvc_buffer *buf);
-extern int uvc_queue_mmap(struct uvc_video_queue *queue,
- struct vm_area_struct *vma);
-extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
- struct file *file, poll_table *wait);
-#ifndef CONFIG_MMU
-extern unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
- unsigned long pgoff);
-#endif
-extern int uvc_queue_allocated(struct uvc_video_queue *queue);
-static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
-{
- return vb2_is_streaming(&queue->queue);
-}
-
-/* V4L2 interface */
-extern const struct v4l2_file_operations uvc_fops;
-
-/* Media controller */
-extern int uvc_mc_register_entities(struct uvc_video_chain *chain);
-extern void uvc_mc_cleanup_entity(struct uvc_entity *entity);
-
-/* Video */
-extern int uvc_video_init(struct uvc_streaming *stream);
-extern int uvc_video_suspend(struct uvc_streaming *stream);
-extern int uvc_video_resume(struct uvc_streaming *stream, int reset);
-extern int uvc_video_enable(struct uvc_streaming *stream, int enable);
-extern int uvc_probe_video(struct uvc_streaming *stream,
- struct uvc_streaming_control *probe);
-extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
- __u8 intfnum, __u8 cs, void *data, __u16 size);
-void uvc_video_clock_update(struct uvc_streaming *stream,
- struct v4l2_buffer *v4l2_buf,
- struct uvc_buffer *buf);
-
-/* Status */
-extern int uvc_status_init(struct uvc_device *dev);
-extern void uvc_status_cleanup(struct uvc_device *dev);
-extern int uvc_status_start(struct uvc_device *dev);
-extern void uvc_status_stop(struct uvc_device *dev);
-extern int uvc_status_suspend(struct uvc_device *dev);
-extern int uvc_status_resume(struct uvc_device *dev);
-
-/* Controls */
-extern const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops;
-
-extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
- struct v4l2_queryctrl *v4l2_ctrl);
-extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
- struct v4l2_querymenu *query_menu);
-
-extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
- const struct uvc_control_mapping *mapping);
-extern int uvc_ctrl_init_device(struct uvc_device *dev);
-extern void uvc_ctrl_cleanup_device(struct uvc_device *dev);
-extern int uvc_ctrl_resume_device(struct uvc_device *dev);
-
-extern int uvc_ctrl_begin(struct uvc_video_chain *chain);
-extern int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
- const struct v4l2_ext_control *xctrls,
- unsigned int xctrls_count);
-static inline int uvc_ctrl_commit(struct uvc_fh *handle,
- const struct v4l2_ext_control *xctrls,
- unsigned int xctrls_count)
-{
- return __uvc_ctrl_commit(handle, 0, xctrls, xctrls_count);
-}
-static inline int uvc_ctrl_rollback(struct uvc_fh *handle)
-{
- return __uvc_ctrl_commit(handle, 1, NULL, 0);
-}
-
-extern int uvc_ctrl_get(struct uvc_video_chain *chain,
- struct v4l2_ext_control *xctrl);
-extern int uvc_ctrl_set(struct uvc_video_chain *chain,
- struct v4l2_ext_control *xctrl);
-
-extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
- struct uvc_xu_control_query *xqry);
-
-/* Utility functions */
-extern void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator,
- unsigned int n_terms, unsigned int threshold);
-extern uint32_t uvc_fraction_to_interval(uint32_t numerator,
- uint32_t denominator);
-extern struct usb_host_endpoint *uvc_find_endpoint(
- struct usb_host_interface *alts, __u8 epaddr);
-
-/* Quirks support */
-void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
- struct uvc_buffer *buf);
-
-/* debugfs and statistics */
-int uvc_debugfs_init(void);
-void uvc_debugfs_cleanup(void);
-int uvc_debugfs_init_stream(struct uvc_streaming *stream);
-void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream);
-
-size_t uvc_video_stats_dump(struct uvc_streaming *stream, char *buf,
- size_t size);
-
-#endif
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
deleted file mode 100644
index 1baec839330..00000000000
--- a/drivers/media/video/v4l2-common.c
+++ /dev/null
@@ -1,623 +0,0 @@
-/*
- * Video for Linux Two
- *
- * A generic video device interface for the LINUX operating system
- * using a set of device structures/vectors for low level operations.
- *
- * This file replaces the videodev.c file that comes with the
- * regular kernel distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Author: Bill Dirks <bill@thedirks.org>
- * based on code by Alan Cox, <alan@cymru.net>
- *
- */
-
-/*
- * Video capture interface for Linux
- *
- * A generic video device interface for the LINUX operating system
- * using a set of device structures/vectors for low level operations.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Author: Alan Cox, <alan@lxorguk.ukuu.org.uk>
- *
- * Fixes:
- */
-
-/*
- * Video4linux 1/2 integration by Justin Schoeman
- * <justin@suntiger.ee.up.ac.za>
- * 2.4 PROCFS support ported from 2.4 kernels by
- * Iñaki García Etxebarria <garetxe@euskalnet.net>
- * Makefile fix by "W. Michael Petullo" <mike@flyn.org>
- * 2.4 devfs support ported from 2.4 kernels by
- * Dan Merillat <dan@merillat.org>
- * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman)
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/i2c.h>
-#if defined(CONFIG_SPI)
-#include <linux/spi/spi.h>
-#endif
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/io.h>
-#include <asm/div64.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
-
-#include <linux/videodev2.h>
-
-MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
-MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
-MODULE_LICENSE("GPL");
-
-/*
- *
- * V 4 L 2 D R I V E R H E L P E R A P I
- *
- */
-
-/*
- * Video Standard Operations (contributed by Michael Schimek)
- */
-
-/* Helper functions for control handling */
-
-/* Check for correctness of the ctrl's value based on the data from
- struct v4l2_queryctrl and the available menu items. Note that
- menu_items may be NULL, in that case it is ignored. */
-int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
- const char * const *menu_items)
-{
- if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED)
- return -EINVAL;
- if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED)
- return -EBUSY;
- if (qctrl->type == V4L2_CTRL_TYPE_STRING)
- return 0;
- if (qctrl->type == V4L2_CTRL_TYPE_BUTTON ||
- qctrl->type == V4L2_CTRL_TYPE_INTEGER64 ||
- qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
- return 0;
- if (ctrl->value < qctrl->minimum || ctrl->value > qctrl->maximum)
- return -ERANGE;
- if (qctrl->type == V4L2_CTRL_TYPE_MENU && menu_items != NULL) {
- if (menu_items[ctrl->value] == NULL ||
- menu_items[ctrl->value][0] == '\0')
- return -EINVAL;
- }
- if (qctrl->type == V4L2_CTRL_TYPE_BITMASK &&
- (ctrl->value & ~qctrl->maximum))
- return -ERANGE;
- return 0;
-}
-EXPORT_SYMBOL(v4l2_ctrl_check);
-
-/* Fill in a struct v4l2_queryctrl */
-int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
-{
- const char *name;
-
- v4l2_ctrl_fill(qctrl->id, &name, &qctrl->type,
- &min, &max, &step, &def, &qctrl->flags);
-
- if (name == NULL)
- return -EINVAL;
-
- qctrl->minimum = min;
- qctrl->maximum = max;
- qctrl->step = step;
- qctrl->default_value = def;
- qctrl->reserved[0] = qctrl->reserved[1] = 0;
- strlcpy(qctrl->name, name, sizeof(qctrl->name));
- return 0;
-}
-EXPORT_SYMBOL(v4l2_ctrl_query_fill);
-
-/* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and
- the menu. The qctrl pointer may be NULL, in which case it is ignored.
- If menu_items is NULL, then the menu items are retrieved using
- v4l2_ctrl_get_menu. */
-int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl,
- const char * const *menu_items)
-{
- int i;
-
- qmenu->reserved = 0;
- if (menu_items == NULL)
- menu_items = v4l2_ctrl_get_menu(qmenu->id);
- if (menu_items == NULL ||
- (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum)))
- return -EINVAL;
- for (i = 0; i < qmenu->index && menu_items[i]; i++) ;
- if (menu_items[i] == NULL || menu_items[i][0] == '\0')
- return -EINVAL;
- strlcpy(qmenu->name, menu_items[qmenu->index], sizeof(qmenu->name));
- return 0;
-}
-EXPORT_SYMBOL(v4l2_ctrl_query_menu);
-
-/* Fill in a struct v4l2_querymenu based on the specified array of valid
- menu items (terminated by V4L2_CTRL_MENU_IDS_END).
- Use this if there are 'holes' in the list of valid menu items. */
-int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids)
-{
- const char * const *menu_items = v4l2_ctrl_get_menu(qmenu->id);
-
- qmenu->reserved = 0;
- if (menu_items == NULL || ids == NULL)
- return -EINVAL;
- while (*ids != V4L2_CTRL_MENU_IDS_END) {
- if (*ids++ == qmenu->index) {
- strlcpy(qmenu->name, menu_items[qmenu->index],
- sizeof(qmenu->name));
- return 0;
- }
- }
- return -EINVAL;
-}
-EXPORT_SYMBOL(v4l2_ctrl_query_menu_valid_items);
-
-/* ctrl_classes points to an array of u32 pointers, the last element is
- a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
- Each array must be sorted low to high and belong to the same control
- class. The array of u32 pointers must also be sorted, from low class IDs
- to high class IDs.
-
- This function returns the first ID that follows after the given ID.
- When no more controls are available 0 is returned. */
-u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id)
-{
- u32 ctrl_class = V4L2_CTRL_ID2CLASS(id);
- const u32 *pctrl;
-
- if (ctrl_classes == NULL)
- return 0;
-
- /* if no query is desired, then check if the ID is part of ctrl_classes */
- if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0) {
- /* find class */
- while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) != ctrl_class)
- ctrl_classes++;
- if (*ctrl_classes == NULL)
- return 0;
- pctrl = *ctrl_classes;
- /* find control ID */
- while (*pctrl && *pctrl != id) pctrl++;
- return *pctrl ? id : 0;
- }
- id &= V4L2_CTRL_ID_MASK;
- id++; /* select next control */
- /* find first class that matches (or is greater than) the class of
- the ID */
- while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) < ctrl_class)
- ctrl_classes++;
- /* no more classes */
- if (*ctrl_classes == NULL)
- return 0;
- pctrl = *ctrl_classes;
- /* find first ctrl within the class that is >= ID */
- while (*pctrl && *pctrl < id) pctrl++;
- if (*pctrl)
- return *pctrl;
- /* we are at the end of the controls of the current class. */
- /* continue with next class if available */
- ctrl_classes++;
- if (*ctrl_classes == NULL)
- return 0;
- return **ctrl_classes;
-}
-EXPORT_SYMBOL(v4l2_ctrl_next);
-
-int v4l2_chip_match_host(const struct v4l2_dbg_match *match)
-{
- switch (match->type) {
- case V4L2_CHIP_MATCH_HOST:
- return match->addr == 0;
- default:
- return 0;
- }
-}
-EXPORT_SYMBOL(v4l2_chip_match_host);
-
-#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
-int v4l2_chip_match_i2c_client(struct i2c_client *c, const struct v4l2_dbg_match *match)
-{
- int len;
-
- if (c == NULL || match == NULL)
- return 0;
-
- switch (match->type) {
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- if (c->driver == NULL || c->driver->driver.name == NULL)
- return 0;
- len = strlen(c->driver->driver.name);
- /* legacy drivers have a ' suffix, don't try to match that */
- if (len && c->driver->driver.name[len - 1] == '\'')
- len--;
- return len && !strncmp(c->driver->driver.name, match->name, len);
- case V4L2_CHIP_MATCH_I2C_ADDR:
- return c->addr == match->addr;
- default:
- return 0;
- }
-}
-EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
-
-int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_dbg_chip_ident *chip,
- u32 ident, u32 revision)
-{
- if (!v4l2_chip_match_i2c_client(c, &chip->match))
- return 0;
- if (chip->ident == V4L2_IDENT_NONE) {
- chip->ident = ident;
- chip->revision = revision;
- }
- else {
- chip->ident = V4L2_IDENT_AMBIGUOUS;
- chip->revision = 0;
- }
- return 0;
-}
-EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
-
-/* ----------------------------------------------------------------- */
-
-/* I2C Helper functions */
-
-
-void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
- const struct v4l2_subdev_ops *ops)
-{
- v4l2_subdev_init(sd, ops);
- sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
- /* the owner is the same as the i2c_client's driver owner */
- sd->owner = client->driver->driver.owner;
- /* i2c_client and v4l2_subdev point to one another */
- v4l2_set_subdevdata(sd, client);
- i2c_set_clientdata(client, sd);
- /* initialize name */
- snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",
- client->driver->driver.name, i2c_adapter_id(client->adapter),
- client->addr);
-}
-EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
-
-
-
-/* Load an i2c sub-device. */
-struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
- struct i2c_adapter *adapter, struct i2c_board_info *info,
- const unsigned short *probe_addrs)
-{
- struct v4l2_subdev *sd = NULL;
- struct i2c_client *client;
-
- BUG_ON(!v4l2_dev);
-
- request_module(I2C_MODULE_PREFIX "%s", info->type);
-
- /* Create the i2c client */
- if (info->addr == 0 && probe_addrs)
- client = i2c_new_probed_device(adapter, info, probe_addrs,
- NULL);
- else
- client = i2c_new_device(adapter, info);
-
- /* Note: by loading the module first we are certain that c->driver
- will be set if the driver was found. If the module was not loaded
- first, then the i2c core tries to delay-load the module for us,
- and then c->driver is still NULL until the module is finally
- loaded. This delay-load mechanism doesn't work if other drivers
- want to use the i2c device, so explicitly loading the module
- is the best alternative. */
- if (client == NULL || client->driver == NULL)
- goto error;
-
- /* Lock the module so we can safely get the v4l2_subdev pointer */
- if (!try_module_get(client->driver->driver.owner))
- goto error;
- sd = i2c_get_clientdata(client);
-
- /* Register with the v4l2_device which increases the module's
- use count as well. */
- if (v4l2_device_register_subdev(v4l2_dev, sd))
- sd = NULL;
- /* Decrease the module use count to match the first try_module_get. */
- module_put(client->driver->driver.owner);
-
-error:
- /* If we have a client but no subdev, then something went wrong and
- we must unregister the client. */
- if (client && sd == NULL)
- i2c_unregister_device(client);
- return sd;
-}
-EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
-
-struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
- struct i2c_adapter *adapter, const char *client_type,
- u8 addr, const unsigned short *probe_addrs)
-{
- struct i2c_board_info info;
-
- /* Setup the i2c board info with the device type and
- the device address. */
- memset(&info, 0, sizeof(info));
- strlcpy(info.type, client_type, sizeof(info.type));
- info.addr = addr;
-
- return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs);
-}
-EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
-
-/* Return i2c client address of v4l2_subdev. */
-unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return client ? client->addr : I2C_CLIENT_END;
-}
-EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_addr);
-
-/* Return a list of I2C tuner addresses to probe. Use only if the tuner
- addresses are unknown. */
-const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
-{
- static const unsigned short radio_addrs[] = {
-#if defined(CONFIG_MEDIA_TUNER_TEA5761) || defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE)
- 0x10,
-#endif
- 0x60,
- I2C_CLIENT_END
- };
- static const unsigned short demod_addrs[] = {
- 0x42, 0x43, 0x4a, 0x4b,
- I2C_CLIENT_END
- };
- static const unsigned short tv_addrs[] = {
- 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
- 0x60, 0x61, 0x62, 0x63, 0x64,
- I2C_CLIENT_END
- };
-
- switch (type) {
- case ADDRS_RADIO:
- return radio_addrs;
- case ADDRS_DEMOD:
- return demod_addrs;
- case ADDRS_TV:
- return tv_addrs;
- case ADDRS_TV_WITH_DEMOD:
- return tv_addrs + 4;
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
-
-#endif /* defined(CONFIG_I2C) */
-
-#if defined(CONFIG_SPI)
-
-/* Load a spi sub-device. */
-
-void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
- const struct v4l2_subdev_ops *ops)
-{
- v4l2_subdev_init(sd, ops);
- sd->flags |= V4L2_SUBDEV_FL_IS_SPI;
- /* the owner is the same as the spi_device's driver owner */
- sd->owner = spi->dev.driver->owner;
- /* spi_device and v4l2_subdev point to one another */
- v4l2_set_subdevdata(sd, spi);
- spi_set_drvdata(spi, sd);
- /* initialize name */
- strlcpy(sd->name, spi->dev.driver->name, sizeof(sd->name));
-}
-EXPORT_SYMBOL_GPL(v4l2_spi_subdev_init);
-
-struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
- struct spi_master *master, struct spi_board_info *info)
-{
- struct v4l2_subdev *sd = NULL;
- struct spi_device *spi = NULL;
-
- BUG_ON(!v4l2_dev);
-
- if (info->modalias)
- request_module(info->modalias);
-
- spi = spi_new_device(master, info);
-
- if (spi == NULL || spi->dev.driver == NULL)
- goto error;
-
- if (!try_module_get(spi->dev.driver->owner))
- goto error;
-
- sd = spi_get_drvdata(spi);
-
- /* Register with the v4l2_device which increases the module's
- use count as well. */
- if (v4l2_device_register_subdev(v4l2_dev, sd))
- sd = NULL;
-
- /* Decrease the module use count to match the first try_module_get. */
- module_put(spi->dev.driver->owner);
-
-error:
- /* If we have a client but no subdev, then something went wrong and
- we must unregister the client. */
- if (spi && sd == NULL)
- spi_unregister_device(spi);
-
- return sd;
-}
-EXPORT_SYMBOL_GPL(v4l2_spi_new_subdev);
-
-#endif /* defined(CONFIG_SPI) */
-
-/* Clamp x to be between min and max, aligned to a multiple of 2^align. min
- * and max don't have to be aligned, but there must be at least one valid
- * value. E.g., min=17,max=31,align=4 is not allowed as there are no multiples
- * of 16 between 17 and 31. */
-static unsigned int clamp_align(unsigned int x, unsigned int min,
- unsigned int max, unsigned int align)
-{
- /* Bits that must be zero to be aligned */
- unsigned int mask = ~((1 << align) - 1);
-
- /* Round to nearest aligned value */
- if (align)
- x = (x + (1 << (align - 1))) & mask;
-
- /* Clamp to aligned value of min and max */
- if (x < min)
- x = (min + ~mask) & mask;
- else if (x > max)
- x = max & mask;
-
- return x;
-}
-
-/* Bound an image to have a width between wmin and wmax, and height between
- * hmin and hmax, inclusive. Additionally, the width will be a multiple of
- * 2^walign, the height will be a multiple of 2^halign, and the overall size
- * (width*height) will be a multiple of 2^salign. The image may be shrunk
- * or enlarged to fit the alignment constraints.
- *
- * The width or height maximum must not be smaller than the corresponding
- * minimum. The alignments must not be so high there are no possible image
- * sizes within the allowed bounds. wmin and hmin must be at least 1
- * (don't use 0). If you don't care about a certain alignment, specify 0,
- * as 2^0 is 1 and one byte alignment is equivalent to no alignment. If
- * you only want to adjust downward, specify a maximum that's the same as
- * the initial value.
- */
-void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
- unsigned int walign,
- u32 *h, unsigned int hmin, unsigned int hmax,
- unsigned int halign, unsigned int salign)
-{
- *w = clamp_align(*w, wmin, wmax, walign);
- *h = clamp_align(*h, hmin, hmax, halign);
-
- /* Usually we don't need to align the size and are done now. */
- if (!salign)
- return;
-
- /* How much alignment do we have? */
- walign = __ffs(*w);
- halign = __ffs(*h);
- /* Enough to satisfy the image alignment? */
- if (walign + halign < salign) {
- /* Max walign where there is still a valid width */
- unsigned int wmaxa = __fls(wmax ^ (wmin - 1));
- /* Max halign where there is still a valid height */
- unsigned int hmaxa = __fls(hmax ^ (hmin - 1));
-
- /* up the smaller alignment until we have enough */
- do {
- if (halign >= hmaxa ||
- (walign <= halign && walign < wmaxa)) {
- *w = clamp_align(*w, wmin, wmax, walign + 1);
- walign = __ffs(*w);
- } else {
- *h = clamp_align(*h, hmin, hmax, halign + 1);
- halign = __ffs(*h);
- }
- } while (halign + walign < salign);
- }
-}
-EXPORT_SYMBOL_GPL(v4l_bound_align_image);
-
-/**
- * v4l_fill_dv_preset_info - fill description of a digital video preset
- * @preset - preset value
- * @info - pointer to struct v4l2_dv_enum_preset
- *
- * drivers can use this helper function to fill description of dv preset
- * in info.
- */
-int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info)
-{
- static const struct v4l2_dv_preset_info {
- u16 width;
- u16 height;
- const char *name;
- } dv_presets[] = {
- { 0, 0, "Invalid" }, /* V4L2_DV_INVALID */
- { 720, 480, "480p@59.94" }, /* V4L2_DV_480P59_94 */
- { 720, 576, "576p@50" }, /* V4L2_DV_576P50 */
- { 1280, 720, "720p@24" }, /* V4L2_DV_720P24 */
- { 1280, 720, "720p@25" }, /* V4L2_DV_720P25 */
- { 1280, 720, "720p@30" }, /* V4L2_DV_720P30 */
- { 1280, 720, "720p@50" }, /* V4L2_DV_720P50 */
- { 1280, 720, "720p@59.94" }, /* V4L2_DV_720P59_94 */
- { 1280, 720, "720p@60" }, /* V4L2_DV_720P60 */
- { 1920, 1080, "1080i@29.97" }, /* V4L2_DV_1080I29_97 */
- { 1920, 1080, "1080i@30" }, /* V4L2_DV_1080I30 */
- { 1920, 1080, "1080i@25" }, /* V4L2_DV_1080I25 */
- { 1920, 1080, "1080i@50" }, /* V4L2_DV_1080I50 */
- { 1920, 1080, "1080i@60" }, /* V4L2_DV_1080I60 */
- { 1920, 1080, "1080p@24" }, /* V4L2_DV_1080P24 */
- { 1920, 1080, "1080p@25" }, /* V4L2_DV_1080P25 */
- { 1920, 1080, "1080p@30" }, /* V4L2_DV_1080P30 */
- { 1920, 1080, "1080p@50" }, /* V4L2_DV_1080P50 */
- { 1920, 1080, "1080p@60" }, /* V4L2_DV_1080P60 */
- };
-
- if (info == NULL || preset >= ARRAY_SIZE(dv_presets))
- return -EINVAL;
-
- info->preset = preset;
- info->width = dv_presets[preset].width;
- info->height = dv_presets[preset].height;
- strlcpy(info->name, dv_presets[preset].name, sizeof(info->name));
- return 0;
-}
-EXPORT_SYMBOL_GPL(v4l_fill_dv_preset_info);
-
-const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
- const struct v4l2_discrete_probe *probe,
- s32 width, s32 height)
-{
- int i;
- u32 error, min_error = UINT_MAX;
- const struct v4l2_frmsize_discrete *size, *best = NULL;
-
- if (!probe)
- return best;
-
- for (i = 0, size = probe->sizes; i < probe->num_sizes; i++, size++) {
- error = abs(size->width - width) + abs(size->height - height);
- if (error < min_error) {
- min_error = error;
- best = size;
- }
- if (!error)
- break;
- }
-
- return best;
-}
-EXPORT_SYMBOL_GPL(v4l2_find_nearest_format);
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
deleted file mode 100644
index 9ebd5c540d1..00000000000
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ /dev/null
@@ -1,1045 +0,0 @@
-/*
- * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
- * Separated from fs stuff by Arnd Bergmann <arnd@arndb.de>
- *
- * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
- * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
- * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
- * Copyright (C) 2003 Pavel Machek (pavel@ucw.cz)
- * Copyright (C) 2005 Philippe De Muyter (phdm@macqel.be)
- * Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * These routines maintain argument size conversion between 32bit and 64bit
- * ioctls.
- */
-
-#include <linux/compat.h>
-#include <linux/module.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-ioctl.h>
-
-static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- long ret = -ENOIOCTLCMD;
-
- if (file->f_op->unlocked_ioctl)
- ret = file->f_op->unlocked_ioctl(file, cmd, arg);
-
- return ret;
-}
-
-
-struct v4l2_clip32 {
- struct v4l2_rect c;
- compat_caddr_t next;
-};
-
-struct v4l2_window32 {
- struct v4l2_rect w;
- __u32 field; /* enum v4l2_field */
- __u32 chromakey;
- compat_caddr_t clips; /* actually struct v4l2_clip32 * */
- __u32 clipcount;
- compat_caddr_t bitmap;
-};
-
-static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
-{
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_window32)) ||
- copy_from_user(&kp->w, &up->w, sizeof(up->w)) ||
- get_user(kp->field, &up->field) ||
- get_user(kp->chromakey, &up->chromakey) ||
- get_user(kp->clipcount, &up->clipcount))
- return -EFAULT;
- if (kp->clipcount > 2048)
- return -EINVAL;
- if (kp->clipcount) {
- struct v4l2_clip32 __user *uclips;
- struct v4l2_clip __user *kclips;
- int n = kp->clipcount;
- compat_caddr_t p;
-
- if (get_user(p, &up->clips))
- return -EFAULT;
- uclips = compat_ptr(p);
- kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));
- kp->clips = kclips;
- while (--n >= 0) {
- if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
- return -EFAULT;
- if (put_user(n ? kclips + 1 : NULL, &kclips->next))
- return -EFAULT;
- uclips += 1;
- kclips += 1;
- }
- } else
- kp->clips = NULL;
- return 0;
-}
-
-static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
-{
- if (copy_to_user(&up->w, &kp->w, sizeof(kp->w)) ||
- put_user(kp->field, &up->field) ||
- put_user(kp->chromakey, &up->chromakey) ||
- put_user(kp->clipcount, &up->clipcount))
- return -EFAULT;
- return 0;
-}
-
-static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
-{
- if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
- return -EFAULT;
- return 0;
-}
-
-static inline int get_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
- struct v4l2_pix_format_mplane __user *up)
-{
- if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format_mplane)))
- return -EFAULT;
- return 0;
-}
-
-static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
-{
- if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
- return -EFAULT;
- return 0;
-}
-
-static inline int put_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
- struct v4l2_pix_format_mplane __user *up)
-{
- if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format_mplane)))
- return -EFAULT;
- return 0;
-}
-
-static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
-{
- if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
- return -EFAULT;
- return 0;
-}
-
-static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
-{
- if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
- return -EFAULT;
- return 0;
-}
-
-static inline int get_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up)
-{
- if (copy_from_user(kp, up, sizeof(struct v4l2_sliced_vbi_format)))
- return -EFAULT;
- return 0;
-}
-
-static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up)
-{
- if (copy_to_user(up, kp, sizeof(struct v4l2_sliced_vbi_format)))
- return -EFAULT;
- return 0;
-}
-
-struct v4l2_format32 {
- __u32 type; /* enum v4l2_buf_type */
- union {
- struct v4l2_pix_format pix;
- struct v4l2_pix_format_mplane pix_mp;
- struct v4l2_window32 win;
- struct v4l2_vbi_format vbi;
- struct v4l2_sliced_vbi_format sliced;
- __u8 raw_data[200]; /* user-defined */
- } fmt;
-};
-
-/**
- * struct v4l2_create_buffers32 - VIDIOC_CREATE_BUFS32 argument
- * @index: on return, index of the first created buffer
- * @count: entry: number of requested buffers,
- * return: number of created buffers
- * @memory: buffer memory type
- * @format: frame format, for which buffers are requested
- * @reserved: future extensions
- */
-struct v4l2_create_buffers32 {
- __u32 index;
- __u32 count;
- __u32 memory; /* enum v4l2_memory */
- struct v4l2_format32 format;
- __u32 reserved[8];
-};
-
-static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
-{
- switch (kp->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- return get_v4l2_pix_format_mplane(&kp->fmt.pix_mp,
- &up->fmt.pix_mp);
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- return get_v4l2_window32(&kp->fmt.win, &up->fmt.win);
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- return get_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced);
- case V4L2_BUF_TYPE_PRIVATE:
- if (copy_from_user(kp, up, sizeof(kp->fmt.raw_data)))
- return -EFAULT;
- return 0;
- default:
- printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
- kp->type);
- return -EINVAL;
- }
-}
-
-static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
-{
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
- get_user(kp->type, &up->type))
- return -EFAULT;
- return __get_v4l2_format32(kp, up);
-}
-
-static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
-{
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
- copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
- return -EFAULT;
- return __get_v4l2_format32(&kp->format, &up->format);
-}
-
-static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
-{
- switch (kp->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- return put_v4l2_pix_format_mplane(&kp->fmt.pix_mp,
- &up->fmt.pix_mp);
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- return put_v4l2_window32(&kp->fmt.win, &up->fmt.win);
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- return put_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced);
- case V4L2_BUF_TYPE_PRIVATE:
- if (copy_to_user(up, kp, sizeof(up->fmt.raw_data)))
- return -EFAULT;
- return 0;
- default:
- printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
- kp->type);
- return -EINVAL;
- }
-}
-
-static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
-{
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
- put_user(kp->type, &up->type))
- return -EFAULT;
- return __put_v4l2_format32(kp, up);
-}
-
-static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
-{
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
- copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
- return -EFAULT;
- return __put_v4l2_format32(&kp->format, &up->format);
-}
-
-struct v4l2_standard32 {
- __u32 index;
- __u32 id[2]; /* __u64 would get the alignment wrong */
- __u8 name[24];
- struct v4l2_fract frameperiod; /* Frames, not fields */
- __u32 framelines;
- __u32 reserved[4];
-};
-
-static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
-{
- /* other fields are not set by the user, nor used by the driver */
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard32)) ||
- get_user(kp->index, &up->index))
- return -EFAULT;
- return 0;
-}
-
-static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
-{
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
- put_user(kp->index, &up->index) ||
- copy_to_user(up->id, &kp->id, sizeof(__u64)) ||
- copy_to_user(up->name, kp->name, 24) ||
- copy_to_user(&up->frameperiod, &kp->frameperiod, sizeof(kp->frameperiod)) ||
- put_user(kp->framelines, &up->framelines) ||
- copy_to_user(up->reserved, kp->reserved, 4 * sizeof(__u32)))
- return -EFAULT;
- return 0;
-}
-
-struct v4l2_plane32 {
- __u32 bytesused;
- __u32 length;
- union {
- __u32 mem_offset;
- compat_long_t userptr;
- } m;
- __u32 data_offset;
- __u32 reserved[11];
-};
-
-struct v4l2_buffer32 {
- __u32 index;
- __u32 type; /* enum v4l2_buf_type */
- __u32 bytesused;
- __u32 flags;
- __u32 field; /* enum v4l2_field */
- struct compat_timeval timestamp;
- struct v4l2_timecode timecode;
- __u32 sequence;
-
- /* memory location */
- __u32 memory; /* enum v4l2_memory */
- union {
- __u32 offset;
- compat_long_t userptr;
- compat_caddr_t planes;
- } m;
- __u32 length;
- __u32 reserved2;
- __u32 reserved;
-};
-
-static int get_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32,
- enum v4l2_memory memory)
-{
- void __user *up_pln;
- compat_long_t p;
-
- if (copy_in_user(up, up32, 2 * sizeof(__u32)) ||
- copy_in_user(&up->data_offset, &up32->data_offset,
- sizeof(__u32)))
- return -EFAULT;
-
- if (memory == V4L2_MEMORY_USERPTR) {
- if (get_user(p, &up32->m.userptr))
- return -EFAULT;
- up_pln = compat_ptr(p);
- if (put_user((unsigned long)up_pln, &up->m.userptr))
- return -EFAULT;
- } else {
- if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
- sizeof(__u32)))
- return -EFAULT;
- }
-
- return 0;
-}
-
-static int put_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32,
- enum v4l2_memory memory)
-{
- if (copy_in_user(up32, up, 2 * sizeof(__u32)) ||
- copy_in_user(&up32->data_offset, &up->data_offset,
- sizeof(__u32)))
- return -EFAULT;
-
- /* For MMAP, driver might've set up the offset, so copy it back.
- * USERPTR stays the same (was userspace-provided), so no copying. */
- if (memory == V4L2_MEMORY_MMAP)
- if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset,
- sizeof(__u32)))
- return -EFAULT;
-
- return 0;
-}
-
-static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
-{
- struct v4l2_plane32 __user *uplane32;
- struct v4l2_plane __user *uplane;
- compat_caddr_t p;
- int num_planes;
- int ret;
-
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) ||
- get_user(kp->index, &up->index) ||
- get_user(kp->type, &up->type) ||
- get_user(kp->flags, &up->flags) ||
- get_user(kp->memory, &up->memory))
- return -EFAULT;
-
- if (V4L2_TYPE_IS_OUTPUT(kp->type))
- if (get_user(kp->bytesused, &up->bytesused) ||
- get_user(kp->field, &up->field) ||
- get_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
- get_user(kp->timestamp.tv_usec,
- &up->timestamp.tv_usec))
- return -EFAULT;
-
- if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
- if (get_user(kp->length, &up->length))
- return -EFAULT;
-
- num_planes = kp->length;
- if (num_planes == 0) {
- kp->m.planes = NULL;
- /* num_planes == 0 is legal, e.g. when userspace doesn't
- * need planes array on DQBUF*/
- return 0;
- }
-
- if (get_user(p, &up->m.planes))
- return -EFAULT;
-
- uplane32 = compat_ptr(p);
- if (!access_ok(VERIFY_READ, uplane32,
- num_planes * sizeof(struct v4l2_plane32)))
- return -EFAULT;
-
- /* We don't really care if userspace decides to kill itself
- * by passing a very big num_planes value */
- uplane = compat_alloc_user_space(num_planes *
- sizeof(struct v4l2_plane));
- kp->m.planes = uplane;
-
- while (--num_planes >= 0) {
- ret = get_v4l2_plane32(uplane, uplane32, kp->memory);
- if (ret)
- return ret;
- ++uplane;
- ++uplane32;
- }
- } else {
- switch (kp->memory) {
- case V4L2_MEMORY_MMAP:
- if (get_user(kp->length, &up->length) ||
- get_user(kp->m.offset, &up->m.offset))
- return -EFAULT;
- break;
- case V4L2_MEMORY_USERPTR:
- {
- compat_long_t tmp;
-
- if (get_user(kp->length, &up->length) ||
- get_user(tmp, &up->m.userptr))
- return -EFAULT;
-
- kp->m.userptr = (unsigned long)compat_ptr(tmp);
- }
- break;
- case V4L2_MEMORY_OVERLAY:
- if (get_user(kp->m.offset, &up->m.offset))
- return -EFAULT;
- break;
- }
- }
-
- return 0;
-}
-
-static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
-{
- struct v4l2_plane32 __user *uplane32;
- struct v4l2_plane __user *uplane;
- compat_caddr_t p;
- int num_planes;
- int ret;
-
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) ||
- put_user(kp->index, &up->index) ||
- put_user(kp->type, &up->type) ||
- put_user(kp->flags, &up->flags) ||
- put_user(kp->memory, &up->memory))
- return -EFAULT;
-
- if (put_user(kp->bytesused, &up->bytesused) ||
- put_user(kp->field, &up->field) ||
- put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
- put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec) ||
- copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) ||
- put_user(kp->sequence, &up->sequence) ||
- put_user(kp->reserved2, &up->reserved2) ||
- put_user(kp->reserved, &up->reserved))
- return -EFAULT;
-
- if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
- num_planes = kp->length;
- if (num_planes == 0)
- return 0;
-
- uplane = kp->m.planes;
- if (get_user(p, &up->m.planes))
- return -EFAULT;
- uplane32 = compat_ptr(p);
-
- while (--num_planes >= 0) {
- ret = put_v4l2_plane32(uplane, uplane32, kp->memory);
- if (ret)
- return ret;
- ++uplane;
- ++uplane32;
- }
- } else {
- switch (kp->memory) {
- case V4L2_MEMORY_MMAP:
- if (put_user(kp->length, &up->length) ||
- put_user(kp->m.offset, &up->m.offset))
- return -EFAULT;
- break;
- case V4L2_MEMORY_USERPTR:
- if (put_user(kp->length, &up->length) ||
- put_user(kp->m.userptr, &up->m.userptr))
- return -EFAULT;
- break;
- case V4L2_MEMORY_OVERLAY:
- if (put_user(kp->m.offset, &up->m.offset))
- return -EFAULT;
- break;
- }
- }
-
- return 0;
-}
-
-struct v4l2_framebuffer32 {
- __u32 capability;
- __u32 flags;
- compat_caddr_t base;
- struct v4l2_pix_format fmt;
-};
-
-static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
-{
- u32 tmp;
-
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_framebuffer32)) ||
- get_user(tmp, &up->base) ||
- get_user(kp->capability, &up->capability) ||
- get_user(kp->flags, &up->flags))
- return -EFAULT;
- kp->base = compat_ptr(tmp);
- get_v4l2_pix_format(&kp->fmt, &up->fmt);
- return 0;
-}
-
-static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
-{
- u32 tmp = (u32)((unsigned long)kp->base);
-
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) ||
- put_user(tmp, &up->base) ||
- put_user(kp->capability, &up->capability) ||
- put_user(kp->flags, &up->flags))
- return -EFAULT;
- put_v4l2_pix_format(&kp->fmt, &up->fmt);
- return 0;
-}
-
-struct v4l2_input32 {
- __u32 index; /* Which input */
- __u8 name[32]; /* Label */
- __u32 type; /* Type of input */
- __u32 audioset; /* Associated audios (bitfield) */
- __u32 tuner; /* Associated tuner */
- v4l2_std_id std;
- __u32 status;
- __u32 reserved[4];
-} __attribute__ ((packed));
-
-/* The 64-bit v4l2_input struct has extra padding at the end of the struct.
- Otherwise it is identical to the 32-bit version. */
-static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
-{
- if (copy_from_user(kp, up, sizeof(struct v4l2_input32)))
- return -EFAULT;
- return 0;
-}
-
-static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
-{
- if (copy_to_user(up, kp, sizeof(struct v4l2_input32)))
- return -EFAULT;
- return 0;
-}
-
-struct v4l2_ext_controls32 {
- __u32 ctrl_class;
- __u32 count;
- __u32 error_idx;
- __u32 reserved[2];
- compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */
-};
-
-struct v4l2_ext_control32 {
- __u32 id;
- __u32 size;
- __u32 reserved2[1];
- union {
- __s32 value;
- __s64 value64;
- compat_caddr_t string; /* actually char * */
- };
-} __attribute__ ((packed));
-
-/* The following function really belong in v4l2-common, but that causes
- a circular dependency between modules. We need to think about this, but
- for now this will do. */
-
-/* Return non-zero if this control is a pointer type. Currently only
- type STRING is a pointer type. */
-static inline int ctrl_is_pointer(u32 id)
-{
- switch (id) {
- case V4L2_CID_RDS_TX_PS_NAME:
- case V4L2_CID_RDS_TX_RADIO_TEXT:
- return 1;
- default:
- return 0;
- }
-}
-
-static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
-{
- struct v4l2_ext_control32 __user *ucontrols;
- struct v4l2_ext_control __user *kcontrols;
- int n;
- compat_caddr_t p;
-
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_ext_controls32)) ||
- get_user(kp->ctrl_class, &up->ctrl_class) ||
- get_user(kp->count, &up->count) ||
- get_user(kp->error_idx, &up->error_idx) ||
- copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
- return -EFAULT;
- n = kp->count;
- if (n == 0) {
- kp->controls = NULL;
- return 0;
- }
- if (get_user(p, &up->controls))
- return -EFAULT;
- ucontrols = compat_ptr(p);
- if (!access_ok(VERIFY_READ, ucontrols,
- n * sizeof(struct v4l2_ext_control32)))
- return -EFAULT;
- kcontrols = compat_alloc_user_space(n * sizeof(struct v4l2_ext_control));
- kp->controls = kcontrols;
- while (--n >= 0) {
- if (copy_in_user(kcontrols, ucontrols, sizeof(*ucontrols)))
- return -EFAULT;
- if (ctrl_is_pointer(kcontrols->id)) {
- void __user *s;
-
- if (get_user(p, &ucontrols->string))
- return -EFAULT;
- s = compat_ptr(p);
- if (put_user(s, &kcontrols->string))
- return -EFAULT;
- }
- ucontrols++;
- kcontrols++;
- }
- return 0;
-}
-
-static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
-{
- struct v4l2_ext_control32 __user *ucontrols;
- struct v4l2_ext_control __user *kcontrols = kp->controls;
- int n = kp->count;
- compat_caddr_t p;
-
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_ext_controls32)) ||
- put_user(kp->ctrl_class, &up->ctrl_class) ||
- put_user(kp->count, &up->count) ||
- put_user(kp->error_idx, &up->error_idx) ||
- copy_to_user(up->reserved, kp->reserved, sizeof(up->reserved)))
- return -EFAULT;
- if (!kp->count)
- return 0;
-
- if (get_user(p, &up->controls))
- return -EFAULT;
- ucontrols = compat_ptr(p);
- if (!access_ok(VERIFY_WRITE, ucontrols,
- n * sizeof(struct v4l2_ext_control32)))
- return -EFAULT;
-
- while (--n >= 0) {
- unsigned size = sizeof(*ucontrols);
-
- /* Do not modify the pointer when copying a pointer control.
- The contents of the pointer was changed, not the pointer
- itself. */
- if (ctrl_is_pointer(kcontrols->id))
- size -= sizeof(ucontrols->value64);
- if (copy_in_user(ucontrols, kcontrols, size))
- return -EFAULT;
- ucontrols++;
- kcontrols++;
- }
- return 0;
-}
-
-struct v4l2_event32 {
- __u32 type;
- union {
- __u8 data[64];
- } u;
- __u32 pending;
- __u32 sequence;
- struct compat_timespec timestamp;
- __u32 id;
- __u32 reserved[8];
-};
-
-static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *up)
-{
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_event32)) ||
- put_user(kp->type, &up->type) ||
- copy_to_user(&up->u, &kp->u, sizeof(kp->u)) ||
- put_user(kp->pending, &up->pending) ||
- put_user(kp->sequence, &up->sequence) ||
- put_compat_timespec(&kp->timestamp, &up->timestamp) ||
- put_user(kp->id, &up->id) ||
- copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32)))
- return -EFAULT;
- return 0;
-}
-
-#define VIDIOC_G_FMT32 _IOWR('V', 4, struct v4l2_format32)
-#define VIDIOC_S_FMT32 _IOWR('V', 5, struct v4l2_format32)
-#define VIDIOC_QUERYBUF32 _IOWR('V', 9, struct v4l2_buffer32)
-#define VIDIOC_G_FBUF32 _IOR ('V', 10, struct v4l2_framebuffer32)
-#define VIDIOC_S_FBUF32 _IOW ('V', 11, struct v4l2_framebuffer32)
-#define VIDIOC_QBUF32 _IOWR('V', 15, struct v4l2_buffer32)
-#define VIDIOC_DQBUF32 _IOWR('V', 17, struct v4l2_buffer32)
-#define VIDIOC_ENUMSTD32 _IOWR('V', 25, struct v4l2_standard32)
-#define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32)
-#define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32)
-#define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32)
-#define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32)
-#define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32)
-#define VIDIOC_DQEVENT32 _IOR ('V', 89, struct v4l2_event32)
-#define VIDIOC_CREATE_BUFS32 _IOWR('V', 92, struct v4l2_create_buffers32)
-#define VIDIOC_PREPARE_BUF32 _IOWR('V', 93, struct v4l2_buffer32)
-
-#define VIDIOC_OVERLAY32 _IOW ('V', 14, s32)
-#define VIDIOC_STREAMON32 _IOW ('V', 18, s32)
-#define VIDIOC_STREAMOFF32 _IOW ('V', 19, s32)
-#define VIDIOC_G_INPUT32 _IOR ('V', 38, s32)
-#define VIDIOC_S_INPUT32 _IOWR('V', 39, s32)
-#define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32)
-#define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32)
-
-static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- union {
- struct v4l2_format v2f;
- struct v4l2_buffer v2b;
- struct v4l2_framebuffer v2fb;
- struct v4l2_input v2i;
- struct v4l2_standard v2s;
- struct v4l2_ext_controls v2ecs;
- struct v4l2_event v2ev;
- struct v4l2_create_buffers v2crt;
- unsigned long vx;
- int vi;
- } karg;
- void __user *up = compat_ptr(arg);
- int compatible_arg = 1;
- long err = 0;
-
- /* First, convert the command. */
- switch (cmd) {
- case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break;
- case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break;
- case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break;
- case VIDIOC_G_FBUF32: cmd = VIDIOC_G_FBUF; break;
- case VIDIOC_S_FBUF32: cmd = VIDIOC_S_FBUF; break;
- case VIDIOC_QBUF32: cmd = VIDIOC_QBUF; break;
- case VIDIOC_DQBUF32: cmd = VIDIOC_DQBUF; break;
- case VIDIOC_ENUMSTD32: cmd = VIDIOC_ENUMSTD; break;
- case VIDIOC_ENUMINPUT32: cmd = VIDIOC_ENUMINPUT; break;
- case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break;
- case VIDIOC_G_EXT_CTRLS32: cmd = VIDIOC_G_EXT_CTRLS; break;
- case VIDIOC_S_EXT_CTRLS32: cmd = VIDIOC_S_EXT_CTRLS; break;
- case VIDIOC_TRY_EXT_CTRLS32: cmd = VIDIOC_TRY_EXT_CTRLS; break;
- case VIDIOC_DQEVENT32: cmd = VIDIOC_DQEVENT; break;
- case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break;
- case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break;
- case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break;
- case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break;
- case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
- case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
- case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
- case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
- case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
- }
-
- switch (cmd) {
- case VIDIOC_OVERLAY:
- case VIDIOC_STREAMON:
- case VIDIOC_STREAMOFF:
- case VIDIOC_S_INPUT:
- case VIDIOC_S_OUTPUT:
- err = get_user(karg.vi, (s32 __user *)up);
- compatible_arg = 0;
- break;
-
- case VIDIOC_G_INPUT:
- case VIDIOC_G_OUTPUT:
- compatible_arg = 0;
- break;
-
- case VIDIOC_G_FMT:
- case VIDIOC_S_FMT:
- case VIDIOC_TRY_FMT:
- err = get_v4l2_format32(&karg.v2f, up);
- compatible_arg = 0;
- break;
-
- case VIDIOC_CREATE_BUFS:
- err = get_v4l2_create32(&karg.v2crt, up);
- compatible_arg = 0;
- break;
-
- case VIDIOC_PREPARE_BUF:
- case VIDIOC_QUERYBUF:
- case VIDIOC_QBUF:
- case VIDIOC_DQBUF:
- err = get_v4l2_buffer32(&karg.v2b, up);
- compatible_arg = 0;
- break;
-
- case VIDIOC_S_FBUF:
- err = get_v4l2_framebuffer32(&karg.v2fb, up);
- compatible_arg = 0;
- break;
-
- case VIDIOC_G_FBUF:
- compatible_arg = 0;
- break;
-
- case VIDIOC_ENUMSTD:
- err = get_v4l2_standard32(&karg.v2s, up);
- compatible_arg = 0;
- break;
-
- case VIDIOC_ENUMINPUT:
- err = get_v4l2_input32(&karg.v2i, up);
- compatible_arg = 0;
- break;
-
- case VIDIOC_G_EXT_CTRLS:
- case VIDIOC_S_EXT_CTRLS:
- case VIDIOC_TRY_EXT_CTRLS:
- err = get_v4l2_ext_controls32(&karg.v2ecs, up);
- compatible_arg = 0;
- break;
- case VIDIOC_DQEVENT:
- compatible_arg = 0;
- break;
- }
- if (err)
- return err;
-
- if (compatible_arg)
- err = native_ioctl(file, cmd, (unsigned long)up);
- else {
- mm_segment_t old_fs = get_fs();
-
- set_fs(KERNEL_DS);
- err = native_ioctl(file, cmd, (unsigned long)&karg);
- set_fs(old_fs);
- }
-
- /* Special case: even after an error we need to put the
- results back for these ioctls since the error_idx will
- contain information on which control failed. */
- switch (cmd) {
- case VIDIOC_G_EXT_CTRLS:
- case VIDIOC_S_EXT_CTRLS:
- case VIDIOC_TRY_EXT_CTRLS:
- if (put_v4l2_ext_controls32(&karg.v2ecs, up))
- err = -EFAULT;
- break;
- }
- if (err)
- return err;
-
- switch (cmd) {
- case VIDIOC_S_INPUT:
- case VIDIOC_S_OUTPUT:
- case VIDIOC_G_INPUT:
- case VIDIOC_G_OUTPUT:
- err = put_user(((s32)karg.vi), (s32 __user *)up);
- break;
-
- case VIDIOC_G_FBUF:
- err = put_v4l2_framebuffer32(&karg.v2fb, up);
- break;
-
- case VIDIOC_DQEVENT:
- err = put_v4l2_event32(&karg.v2ev, up);
- break;
-
- case VIDIOC_G_FMT:
- case VIDIOC_S_FMT:
- case VIDIOC_TRY_FMT:
- err = put_v4l2_format32(&karg.v2f, up);
- break;
-
- case VIDIOC_CREATE_BUFS:
- err = put_v4l2_create32(&karg.v2crt, up);
- break;
-
- case VIDIOC_QUERYBUF:
- case VIDIOC_QBUF:
- case VIDIOC_DQBUF:
- err = put_v4l2_buffer32(&karg.v2b, up);
- break;
-
- case VIDIOC_ENUMSTD:
- err = put_v4l2_standard32(&karg.v2s, up);
- break;
-
- case VIDIOC_ENUMINPUT:
- err = put_v4l2_input32(&karg.v2i, up);
- break;
- }
- return err;
-}
-
-long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct video_device *vdev = video_devdata(file);
- long ret = -ENOIOCTLCMD;
-
- if (!file->f_op->unlocked_ioctl)
- return ret;
-
- switch (cmd) {
- case VIDIOC_QUERYCAP:
- case VIDIOC_RESERVED:
- case VIDIOC_ENUM_FMT:
- case VIDIOC_G_FMT32:
- case VIDIOC_S_FMT32:
- case VIDIOC_REQBUFS:
- case VIDIOC_QUERYBUF32:
- case VIDIOC_G_FBUF32:
- case VIDIOC_S_FBUF32:
- case VIDIOC_OVERLAY32:
- case VIDIOC_QBUF32:
- case VIDIOC_DQBUF32:
- case VIDIOC_STREAMON32:
- case VIDIOC_STREAMOFF32:
- case VIDIOC_G_PARM:
- case VIDIOC_S_PARM:
- case VIDIOC_G_STD:
- case VIDIOC_S_STD:
- case VIDIOC_ENUMSTD32:
- case VIDIOC_ENUMINPUT32:
- case VIDIOC_G_CTRL:
- case VIDIOC_S_CTRL:
- case VIDIOC_G_TUNER:
- case VIDIOC_S_TUNER:
- case VIDIOC_G_AUDIO:
- case VIDIOC_S_AUDIO:
- case VIDIOC_QUERYCTRL:
- case VIDIOC_QUERYMENU:
- case VIDIOC_G_INPUT32:
- case VIDIOC_S_INPUT32:
- case VIDIOC_G_OUTPUT32:
- case VIDIOC_S_OUTPUT32:
- case VIDIOC_ENUMOUTPUT:
- case VIDIOC_G_AUDOUT:
- case VIDIOC_S_AUDOUT:
- case VIDIOC_G_MODULATOR:
- case VIDIOC_S_MODULATOR:
- case VIDIOC_S_FREQUENCY:
- case VIDIOC_G_FREQUENCY:
- case VIDIOC_CROPCAP:
- case VIDIOC_G_CROP:
- case VIDIOC_S_CROP:
- case VIDIOC_G_SELECTION:
- case VIDIOC_S_SELECTION:
- case VIDIOC_G_JPEGCOMP:
- case VIDIOC_S_JPEGCOMP:
- case VIDIOC_QUERYSTD:
- case VIDIOC_TRY_FMT32:
- case VIDIOC_ENUMAUDIO:
- case VIDIOC_ENUMAUDOUT:
- case VIDIOC_G_PRIORITY:
- case VIDIOC_S_PRIORITY:
- case VIDIOC_G_SLICED_VBI_CAP:
- case VIDIOC_LOG_STATUS:
- case VIDIOC_G_EXT_CTRLS32:
- case VIDIOC_S_EXT_CTRLS32:
- case VIDIOC_TRY_EXT_CTRLS32:
- case VIDIOC_ENUM_FRAMESIZES:
- case VIDIOC_ENUM_FRAMEINTERVALS:
- case VIDIOC_G_ENC_INDEX:
- case VIDIOC_ENCODER_CMD:
- case VIDIOC_TRY_ENCODER_CMD:
- case VIDIOC_DECODER_CMD:
- case VIDIOC_TRY_DECODER_CMD:
- case VIDIOC_DBG_S_REGISTER:
- case VIDIOC_DBG_G_REGISTER:
- case VIDIOC_DBG_G_CHIP_IDENT:
- case VIDIOC_S_HW_FREQ_SEEK:
- case VIDIOC_ENUM_DV_PRESETS:
- case VIDIOC_S_DV_PRESET:
- case VIDIOC_G_DV_PRESET:
- case VIDIOC_QUERY_DV_PRESET:
- case VIDIOC_S_DV_TIMINGS:
- case VIDIOC_G_DV_TIMINGS:
- case VIDIOC_DQEVENT:
- case VIDIOC_DQEVENT32:
- case VIDIOC_SUBSCRIBE_EVENT:
- case VIDIOC_UNSUBSCRIBE_EVENT:
- case VIDIOC_CREATE_BUFS32:
- case VIDIOC_PREPARE_BUF32:
- case VIDIOC_ENUM_DV_TIMINGS:
- case VIDIOC_QUERY_DV_TIMINGS:
- case VIDIOC_DV_TIMINGS_CAP:
- case VIDIOC_ENUM_FREQ_BANDS:
- ret = do_video_ioctl(file, cmd, arg);
- break;
-
- default:
- if (vdev->fops->compat_ioctl32)
- ret = vdev->fops->compat_ioctl32(file, cmd, arg);
-
- if (ret == -ENOIOCTLCMD)
- printk(KERN_WARNING "compat_ioctl32: "
- "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
- _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd),
- cmd);
- break;
- }
- return ret;
-}
-EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32);
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
deleted file mode 100644
index b6a2ee71e5c..00000000000
--- a/drivers/media/video/v4l2-ctrls.c
+++ /dev/null
@@ -1,2651 +0,0 @@
-/*
- V4L2 controls framework implementation.
-
- Copyright (C) 2010 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/ctype.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-dev.h>
-
-#define has_op(master, op) \
- (master->ops && master->ops->op)
-#define call_op(master, op) \
- (has_op(master, op) ? master->ops->op(master) : 0)
-
-/* Internal temporary helper struct, one for each v4l2_ext_control */
-struct v4l2_ctrl_helper {
- /* Pointer to the control reference of the master control */
- struct v4l2_ctrl_ref *mref;
- /* The control corresponding to the v4l2_ext_control ID field. */
- struct v4l2_ctrl *ctrl;
- /* v4l2_ext_control index of the next control belonging to the
- same cluster, or 0 if there isn't any. */
- u32 next;
-};
-
-/* Small helper function to determine if the autocluster is set to manual
- mode. */
-static bool is_cur_manual(const struct v4l2_ctrl *master)
-{
- return master->is_auto && master->cur.val == master->manual_mode_value;
-}
-
-/* Same as above, but this checks the against the new value instead of the
- current value. */
-static bool is_new_manual(const struct v4l2_ctrl *master)
-{
- return master->is_auto && master->val == master->manual_mode_value;
-}
-
-/* Returns NULL or a character pointer array containing the menu for
- the given control ID. The pointer array ends with a NULL pointer.
- An empty string signifies a menu entry that is invalid. This allows
- drivers to disable certain options if it is not supported. */
-const char * const *v4l2_ctrl_get_menu(u32 id)
-{
- static const char * const mpeg_audio_sampling_freq[] = {
- "44.1 kHz",
- "48 kHz",
- "32 kHz",
- NULL
- };
- static const char * const mpeg_audio_encoding[] = {
- "MPEG-1/2 Layer I",
- "MPEG-1/2 Layer II",
- "MPEG-1/2 Layer III",
- "MPEG-2/4 AAC",
- "AC-3",
- NULL
- };
- static const char * const mpeg_audio_l1_bitrate[] = {
- "32 kbps",
- "64 kbps",
- "96 kbps",
- "128 kbps",
- "160 kbps",
- "192 kbps",
- "224 kbps",
- "256 kbps",
- "288 kbps",
- "320 kbps",
- "352 kbps",
- "384 kbps",
- "416 kbps",
- "448 kbps",
- NULL
- };
- static const char * const mpeg_audio_l2_bitrate[] = {
- "32 kbps",
- "48 kbps",
- "56 kbps",
- "64 kbps",
- "80 kbps",
- "96 kbps",
- "112 kbps",
- "128 kbps",
- "160 kbps",
- "192 kbps",
- "224 kbps",
- "256 kbps",
- "320 kbps",
- "384 kbps",
- NULL
- };
- static const char * const mpeg_audio_l3_bitrate[] = {
- "32 kbps",
- "40 kbps",
- "48 kbps",
- "56 kbps",
- "64 kbps",
- "80 kbps",
- "96 kbps",
- "112 kbps",
- "128 kbps",
- "160 kbps",
- "192 kbps",
- "224 kbps",
- "256 kbps",
- "320 kbps",
- NULL
- };
- static const char * const mpeg_audio_ac3_bitrate[] = {
- "32 kbps",
- "40 kbps",
- "48 kbps",
- "56 kbps",
- "64 kbps",
- "80 kbps",
- "96 kbps",
- "112 kbps",
- "128 kbps",
- "160 kbps",
- "192 kbps",
- "224 kbps",
- "256 kbps",
- "320 kbps",
- "384 kbps",
- "448 kbps",
- "512 kbps",
- "576 kbps",
- "640 kbps",
- NULL
- };
- static const char * const mpeg_audio_mode[] = {
- "Stereo",
- "Joint Stereo",
- "Dual",
- "Mono",
- NULL
- };
- static const char * const mpeg_audio_mode_extension[] = {
- "Bound 4",
- "Bound 8",
- "Bound 12",
- "Bound 16",
- NULL
- };
- static const char * const mpeg_audio_emphasis[] = {
- "No Emphasis",
- "50/15 us",
- "CCITT J17",
- NULL
- };
- static const char * const mpeg_audio_crc[] = {
- "No CRC",
- "16-bit CRC",
- NULL
- };
- static const char * const mpeg_audio_dec_playback[] = {
- "Auto",
- "Stereo",
- "Left",
- "Right",
- "Mono",
- "Swapped Stereo",
- NULL
- };
- static const char * const mpeg_video_encoding[] = {
- "MPEG-1",
- "MPEG-2",
- "MPEG-4 AVC",
- NULL
- };
- static const char * const mpeg_video_aspect[] = {
- "1x1",
- "4x3",
- "16x9",
- "2.21x1",
- NULL
- };
- static const char * const mpeg_video_bitrate_mode[] = {
- "Variable Bitrate",
- "Constant Bitrate",
- NULL
- };
- static const char * const mpeg_stream_type[] = {
- "MPEG-2 Program Stream",
- "MPEG-2 Transport Stream",
- "MPEG-1 System Stream",
- "MPEG-2 DVD-compatible Stream",
- "MPEG-1 VCD-compatible Stream",
- "MPEG-2 SVCD-compatible Stream",
- NULL
- };
- static const char * const mpeg_stream_vbi_fmt[] = {
- "No VBI",
- "Private Packet, IVTV Format",
- NULL
- };
- static const char * const camera_power_line_frequency[] = {
- "Disabled",
- "50 Hz",
- "60 Hz",
- "Auto",
- NULL
- };
- static const char * const camera_exposure_auto[] = {
- "Auto Mode",
- "Manual Mode",
- "Shutter Priority Mode",
- "Aperture Priority Mode",
- NULL
- };
- static const char * const camera_exposure_metering[] = {
- "Average",
- "Center Weighted",
- "Spot",
- NULL
- };
- static const char * const camera_auto_focus_range[] = {
- "Auto",
- "Normal",
- "Macro",
- "Infinity",
- NULL
- };
- static const char * const colorfx[] = {
- "None",
- "Black & White",
- "Sepia",
- "Negative",
- "Emboss",
- "Sketch",
- "Sky Blue",
- "Grass Green",
- "Skin Whiten",
- "Vivid",
- "Aqua",
- "Art Freeze",
- "Silhouette",
- "Solarization",
- "Antique",
- "Set Cb/Cr",
- NULL
- };
- static const char * const auto_n_preset_white_balance[] = {
- "Manual",
- "Auto",
- "Incandescent",
- "Fluorescent",
- "Fluorescent H",
- "Horizon",
- "Daylight",
- "Flash",
- "Cloudy",
- "Shade",
- NULL,
- };
- static const char * const camera_iso_sensitivity_auto[] = {
- "Manual",
- "Auto",
- NULL
- };
- static const char * const scene_mode[] = {
- "None",
- "Backlight",
- "Beach/Snow",
- "Candle Light",
- "Dusk/Dawn",
- "Fall Colors",
- "Fireworks",
- "Landscape",
- "Night",
- "Party/Indoor",
- "Portrait",
- "Sports",
- "Sunset",
- "Text",
- NULL
- };
- static const char * const tune_preemphasis[] = {
- "No Preemphasis",
- "50 Microseconds",
- "75 Microseconds",
- NULL,
- };
- static const char * const header_mode[] = {
- "Separate Buffer",
- "Joined With 1st Frame",
- NULL,
- };
- static const char * const multi_slice[] = {
- "Single",
- "Max Macroblocks",
- "Max Bytes",
- NULL,
- };
- static const char * const entropy_mode[] = {
- "CAVLC",
- "CABAC",
- NULL,
- };
- static const char * const mpeg_h264_level[] = {
- "1",
- "1b",
- "1.1",
- "1.2",
- "1.3",
- "2",
- "2.1",
- "2.2",
- "3",
- "3.1",
- "3.2",
- "4",
- "4.1",
- "4.2",
- "5",
- "5.1",
- NULL,
- };
- static const char * const h264_loop_filter[] = {
- "Enabled",
- "Disabled",
- "Disabled at Slice Boundary",
- NULL,
- };
- static const char * const h264_profile[] = {
- "Baseline",
- "Constrained Baseline",
- "Main",
- "Extended",
- "High",
- "High 10",
- "High 422",
- "High 444 Predictive",
- "High 10 Intra",
- "High 422 Intra",
- "High 444 Intra",
- "CAVLC 444 Intra",
- "Scalable Baseline",
- "Scalable High",
- "Scalable High Intra",
- "Multiview High",
- NULL,
- };
- static const char * const vui_sar_idc[] = {
- "Unspecified",
- "1:1",
- "12:11",
- "10:11",
- "16:11",
- "40:33",
- "24:11",
- "20:11",
- "32:11",
- "80:33",
- "18:11",
- "15:11",
- "64:33",
- "160:99",
- "4:3",
- "3:2",
- "2:1",
- "Extended SAR",
- NULL,
- };
- static const char * const mpeg_mpeg4_level[] = {
- "0",
- "0b",
- "1",
- "2",
- "3",
- "3b",
- "4",
- "5",
- NULL,
- };
- static const char * const mpeg4_profile[] = {
- "Simple",
- "Advanced Simple",
- "Core",
- "Simple Scalable",
- "Advanced Coding Efficency",
- NULL,
- };
-
- static const char * const flash_led_mode[] = {
- "Off",
- "Flash",
- "Torch",
- NULL,
- };
- static const char * const flash_strobe_source[] = {
- "Software",
- "External",
- NULL,
- };
-
- static const char * const jpeg_chroma_subsampling[] = {
- "4:4:4",
- "4:2:2",
- "4:2:0",
- "4:1:1",
- "4:1:0",
- "Gray",
- NULL,
- };
-
- switch (id) {
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- return mpeg_audio_sampling_freq;
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- return mpeg_audio_encoding;
- case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
- return mpeg_audio_l1_bitrate;
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- return mpeg_audio_l2_bitrate;
- case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
- return mpeg_audio_l3_bitrate;
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- return mpeg_audio_ac3_bitrate;
- case V4L2_CID_MPEG_AUDIO_MODE:
- return mpeg_audio_mode;
- case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
- return mpeg_audio_mode_extension;
- case V4L2_CID_MPEG_AUDIO_EMPHASIS:
- return mpeg_audio_emphasis;
- case V4L2_CID_MPEG_AUDIO_CRC:
- return mpeg_audio_crc;
- case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
- case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK:
- return mpeg_audio_dec_playback;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- return mpeg_video_encoding;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- return mpeg_video_aspect;
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- return mpeg_video_bitrate_mode;
- case V4L2_CID_MPEG_STREAM_TYPE:
- return mpeg_stream_type;
- case V4L2_CID_MPEG_STREAM_VBI_FMT:
- return mpeg_stream_vbi_fmt;
- case V4L2_CID_POWER_LINE_FREQUENCY:
- return camera_power_line_frequency;
- case V4L2_CID_EXPOSURE_AUTO:
- return camera_exposure_auto;
- case V4L2_CID_EXPOSURE_METERING:
- return camera_exposure_metering;
- case V4L2_CID_AUTO_FOCUS_RANGE:
- return camera_auto_focus_range;
- case V4L2_CID_COLORFX:
- return colorfx;
- case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
- return auto_n_preset_white_balance;
- case V4L2_CID_ISO_SENSITIVITY_AUTO:
- return camera_iso_sensitivity_auto;
- case V4L2_CID_SCENE_MODE:
- return scene_mode;
- case V4L2_CID_TUNE_PREEMPHASIS:
- return tune_preemphasis;
- case V4L2_CID_FLASH_LED_MODE:
- return flash_led_mode;
- case V4L2_CID_FLASH_STROBE_SOURCE:
- return flash_strobe_source;
- case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
- return header_mode;
- case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
- return multi_slice;
- case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
- return entropy_mode;
- case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
- return mpeg_h264_level;
- case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
- return h264_loop_filter;
- case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
- return h264_profile;
- case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
- return vui_sar_idc;
- case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
- return mpeg_mpeg4_level;
- case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
- return mpeg4_profile;
- case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
- return jpeg_chroma_subsampling;
-
- default:
- return NULL;
- }
-}
-EXPORT_SYMBOL(v4l2_ctrl_get_menu);
-
-/* Return the control name. */
-const char *v4l2_ctrl_get_name(u32 id)
-{
- switch (id) {
- /* USER controls */
- /* Keep the order of the 'case's the same as in videodev2.h! */
- case V4L2_CID_USER_CLASS: return "User Controls";
- case V4L2_CID_BRIGHTNESS: return "Brightness";
- case V4L2_CID_CONTRAST: return "Contrast";
- case V4L2_CID_SATURATION: return "Saturation";
- case V4L2_CID_HUE: return "Hue";
- case V4L2_CID_AUDIO_VOLUME: return "Volume";
- case V4L2_CID_AUDIO_BALANCE: return "Balance";
- case V4L2_CID_AUDIO_BASS: return "Bass";
- case V4L2_CID_AUDIO_TREBLE: return "Treble";
- case V4L2_CID_AUDIO_MUTE: return "Mute";
- case V4L2_CID_AUDIO_LOUDNESS: return "Loudness";
- case V4L2_CID_BLACK_LEVEL: return "Black Level";
- case V4L2_CID_AUTO_WHITE_BALANCE: return "White Balance, Automatic";
- case V4L2_CID_DO_WHITE_BALANCE: return "Do White Balance";
- case V4L2_CID_RED_BALANCE: return "Red Balance";
- case V4L2_CID_BLUE_BALANCE: return "Blue Balance";
- case V4L2_CID_GAMMA: return "Gamma";
- case V4L2_CID_EXPOSURE: return "Exposure";
- case V4L2_CID_AUTOGAIN: return "Gain, Automatic";
- case V4L2_CID_GAIN: return "Gain";
- case V4L2_CID_HFLIP: return "Horizontal Flip";
- case V4L2_CID_VFLIP: return "Vertical Flip";
- case V4L2_CID_HCENTER: return "Horizontal Center";
- case V4L2_CID_VCENTER: return "Vertical Center";
- case V4L2_CID_POWER_LINE_FREQUENCY: return "Power Line Frequency";
- case V4L2_CID_HUE_AUTO: return "Hue, Automatic";
- case V4L2_CID_WHITE_BALANCE_TEMPERATURE: return "White Balance Temperature";
- case V4L2_CID_SHARPNESS: return "Sharpness";
- case V4L2_CID_BACKLIGHT_COMPENSATION: return "Backlight Compensation";
- case V4L2_CID_CHROMA_AGC: return "Chroma AGC";
- case V4L2_CID_COLOR_KILLER: return "Color Killer";
- case V4L2_CID_COLORFX: return "Color Effects";
- case V4L2_CID_AUTOBRIGHTNESS: return "Brightness, Automatic";
- case V4L2_CID_BAND_STOP_FILTER: return "Band-Stop Filter";
- case V4L2_CID_ROTATE: return "Rotate";
- case V4L2_CID_BG_COLOR: return "Background Color";
- case V4L2_CID_CHROMA_GAIN: return "Chroma Gain";
- case V4L2_CID_ILLUMINATORS_1: return "Illuminator 1";
- case V4L2_CID_ILLUMINATORS_2: return "Illuminator 2";
- case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Min Number of Capture Buffers";
- case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Min Number of Output Buffers";
- case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component";
- case V4L2_CID_COLORFX_CBCR: return "Color Effects, CbCr";
-
- /* MPEG controls */
- /* Keep the order of the 'case's the same as in videodev2.h! */
- case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls";
- case V4L2_CID_MPEG_STREAM_TYPE: return "Stream Type";
- case V4L2_CID_MPEG_STREAM_PID_PMT: return "Stream PMT Program ID";
- case V4L2_CID_MPEG_STREAM_PID_AUDIO: return "Stream Audio Program ID";
- case V4L2_CID_MPEG_STREAM_PID_VIDEO: return "Stream Video Program ID";
- case V4L2_CID_MPEG_STREAM_PID_PCR: return "Stream PCR Program ID";
- case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: return "Stream PES Audio ID";
- case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: return "Stream PES Video ID";
- case V4L2_CID_MPEG_STREAM_VBI_FMT: return "Stream VBI Format";
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: return "Audio Sampling Frequency";
- case V4L2_CID_MPEG_AUDIO_ENCODING: return "Audio Encoding";
- case V4L2_CID_MPEG_AUDIO_L1_BITRATE: return "Audio Layer I Bitrate";
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE: return "Audio Layer II Bitrate";
- case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return "Audio Layer III Bitrate";
- case V4L2_CID_MPEG_AUDIO_MODE: return "Audio Stereo Mode";
- case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: return "Audio Stereo Mode Extension";
- case V4L2_CID_MPEG_AUDIO_EMPHASIS: return "Audio Emphasis";
- case V4L2_CID_MPEG_AUDIO_CRC: return "Audio CRC";
- case V4L2_CID_MPEG_AUDIO_MUTE: return "Audio Mute";
- case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: return "Audio AAC Bitrate";
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return "Audio AC-3 Bitrate";
- case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: return "Audio Playback";
- case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: return "Audio Multilingual Playback";
- case V4L2_CID_MPEG_VIDEO_ENCODING: return "Video Encoding";
- case V4L2_CID_MPEG_VIDEO_ASPECT: return "Video Aspect";
- case V4L2_CID_MPEG_VIDEO_B_FRAMES: return "Video B Frames";
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE: return "Video GOP Size";
- case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: return "Video GOP Closure";
- case V4L2_CID_MPEG_VIDEO_PULLDOWN: return "Video Pulldown";
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: return "Video Bitrate Mode";
- case V4L2_CID_MPEG_VIDEO_BITRATE: return "Video Bitrate";
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: return "Video Peak Bitrate";
- case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: return "Video Temporal Decimation";
- case V4L2_CID_MPEG_VIDEO_MUTE: return "Video Mute";
- case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV";
- case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: return "Decoder Slice Interface";
- case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: return "MPEG4 Loop Filter Enable";
- case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "Number of Intra Refresh MBs";
- case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: return "Frame Level Rate Control Enable";
- case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control";
- case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode";
- case V4L2_CID_MPEG_VIDEO_MAX_REF_PIC: return "Max Number of Reference Pics";
- case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: return "H263 I-Frame QP Value";
- case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: return "H263 P-Frame QP Value";
- case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: return "H263 B-Frame QP Value";
- case V4L2_CID_MPEG_VIDEO_H263_MIN_QP: return "H263 Minimum QP Value";
- case V4L2_CID_MPEG_VIDEO_H263_MAX_QP: return "H263 Maximum QP Value";
- case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: return "H264 I-Frame QP Value";
- case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: return "H264 P-Frame QP Value";
- case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: return "H264 B-Frame QP Value";
- case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: return "H264 Maximum QP Value";
- case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: return "H264 Minimum QP Value";
- case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: return "H264 8x8 Transform Enable";
- case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: return "H264 CPB Buffer Size";
- case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: return "H264 Entropy Mode";
- case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: return "H264 I-Frame Period";
- case V4L2_CID_MPEG_VIDEO_H264_LEVEL: return "H264 Level";
- case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: return "H264 Loop Filter Alpha Offset";
- case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: return "H264 Loop Filter Beta Offset";
- case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: return "H264 Loop Filter Mode";
- case V4L2_CID_MPEG_VIDEO_H264_PROFILE: return "H264 Profile";
- case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT: return "Vertical Size of SAR";
- case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH: return "Horizontal Size of SAR";
- case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: return "Aspect Ratio VUI Enable";
- case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: return "VUI Aspect Ratio IDC";
- case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value";
- case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value";
- case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value";
- case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: return "MPEG4 Minimum QP Value";
- case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: return "MPEG4 Maximum QP Value";
- case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: return "MPEG4 Level";
- case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: return "MPEG4 Profile";
- case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: return "Quarter Pixel Search Enable";
- case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: return "Maximum Bytes in a Slice";
- case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "Number of MBs in a Slice";
- case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "Slice Partitioning Method";
- case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size";
- case V4L2_CID_MPEG_VIDEO_DEC_PTS: return "Video Decoder PTS";
- case V4L2_CID_MPEG_VIDEO_DEC_FRAME: return "Video Decoder Frame Count";
-
- /* CAMERA controls */
- /* Keep the order of the 'case's the same as in videodev2.h! */
- case V4L2_CID_CAMERA_CLASS: return "Camera Controls";
- case V4L2_CID_EXPOSURE_AUTO: return "Auto Exposure";
- case V4L2_CID_EXPOSURE_ABSOLUTE: return "Exposure Time, Absolute";
- case V4L2_CID_EXPOSURE_AUTO_PRIORITY: return "Exposure, Dynamic Framerate";
- case V4L2_CID_PAN_RELATIVE: return "Pan, Relative";
- case V4L2_CID_TILT_RELATIVE: return "Tilt, Relative";
- case V4L2_CID_PAN_RESET: return "Pan, Reset";
- case V4L2_CID_TILT_RESET: return "Tilt, Reset";
- case V4L2_CID_PAN_ABSOLUTE: return "Pan, Absolute";
- case V4L2_CID_TILT_ABSOLUTE: return "Tilt, Absolute";
- case V4L2_CID_FOCUS_ABSOLUTE: return "Focus, Absolute";
- case V4L2_CID_FOCUS_RELATIVE: return "Focus, Relative";
- case V4L2_CID_FOCUS_AUTO: return "Focus, Automatic Continuous";
- case V4L2_CID_ZOOM_ABSOLUTE: return "Zoom, Absolute";
- case V4L2_CID_ZOOM_RELATIVE: return "Zoom, Relative";
- case V4L2_CID_ZOOM_CONTINUOUS: return "Zoom, Continuous";
- case V4L2_CID_PRIVACY: return "Privacy";
- case V4L2_CID_IRIS_ABSOLUTE: return "Iris, Absolute";
- case V4L2_CID_IRIS_RELATIVE: return "Iris, Relative";
- case V4L2_CID_AUTO_EXPOSURE_BIAS: return "Auto Exposure, Bias";
- case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto & Preset";
- case V4L2_CID_WIDE_DYNAMIC_RANGE: return "Wide Dynamic Range";
- case V4L2_CID_IMAGE_STABILIZATION: return "Image Stabilization";
- case V4L2_CID_ISO_SENSITIVITY: return "ISO Sensitivity";
- case V4L2_CID_ISO_SENSITIVITY_AUTO: return "ISO Sensitivity, Auto";
- case V4L2_CID_EXPOSURE_METERING: return "Exposure, Metering Mode";
- case V4L2_CID_SCENE_MODE: return "Scene Mode";
- case V4L2_CID_3A_LOCK: return "3A Lock";
- case V4L2_CID_AUTO_FOCUS_START: return "Auto Focus, Start";
- case V4L2_CID_AUTO_FOCUS_STOP: return "Auto Focus, Stop";
- case V4L2_CID_AUTO_FOCUS_STATUS: return "Auto Focus, Status";
- case V4L2_CID_AUTO_FOCUS_RANGE: return "Auto Focus, Range";
-
- /* FM Radio Modulator control */
- /* Keep the order of the 'case's the same as in videodev2.h! */
- case V4L2_CID_FM_TX_CLASS: return "FM Radio Modulator Controls";
- case V4L2_CID_RDS_TX_DEVIATION: return "RDS Signal Deviation";
- case V4L2_CID_RDS_TX_PI: return "RDS Program ID";
- case V4L2_CID_RDS_TX_PTY: return "RDS Program Type";
- case V4L2_CID_RDS_TX_PS_NAME: return "RDS PS Name";
- case V4L2_CID_RDS_TX_RADIO_TEXT: return "RDS Radio Text";
- case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled";
- case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time";
- case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation";
- case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Enabled";
- case V4L2_CID_AUDIO_COMPRESSION_GAIN: return "Audio Compression Gain";
- case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: return "Audio Compression Threshold";
- case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: return "Audio Compression Attack Time";
- case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME: return "Audio Compression Release Time";
- case V4L2_CID_PILOT_TONE_ENABLED: return "Pilot Tone Feature Enabled";
- case V4L2_CID_PILOT_TONE_DEVIATION: return "Pilot Tone Deviation";
- case V4L2_CID_PILOT_TONE_FREQUENCY: return "Pilot Tone Frequency";
- case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-Emphasis";
- case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level";
- case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor";
-
- /* Flash controls */
- case V4L2_CID_FLASH_CLASS: return "Flash Controls";
- case V4L2_CID_FLASH_LED_MODE: return "LED Mode";
- case V4L2_CID_FLASH_STROBE_SOURCE: return "Strobe Source";
- case V4L2_CID_FLASH_STROBE: return "Strobe";
- case V4L2_CID_FLASH_STROBE_STOP: return "Stop Strobe";
- case V4L2_CID_FLASH_STROBE_STATUS: return "Strobe Status";
- case V4L2_CID_FLASH_TIMEOUT: return "Strobe Timeout";
- case V4L2_CID_FLASH_INTENSITY: return "Intensity, Flash Mode";
- case V4L2_CID_FLASH_TORCH_INTENSITY: return "Intensity, Torch Mode";
- case V4L2_CID_FLASH_INDICATOR_INTENSITY: return "Intensity, Indicator";
- case V4L2_CID_FLASH_FAULT: return "Faults";
- case V4L2_CID_FLASH_CHARGE: return "Charge";
- case V4L2_CID_FLASH_READY: return "Ready to Strobe";
-
- /* JPEG encoder controls */
- /* Keep the order of the 'case's the same as in videodev2.h! */
- case V4L2_CID_JPEG_CLASS: return "JPEG Compression Controls";
- case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: return "Chroma Subsampling";
- case V4L2_CID_JPEG_RESTART_INTERVAL: return "Restart Interval";
- case V4L2_CID_JPEG_COMPRESSION_QUALITY: return "Compression Quality";
- case V4L2_CID_JPEG_ACTIVE_MARKER: return "Active Markers";
-
- /* Image source controls */
- case V4L2_CID_IMAGE_SOURCE_CLASS: return "Image Source Controls";
- case V4L2_CID_VBLANK: return "Vertical Blanking";
- case V4L2_CID_HBLANK: return "Horizontal Blanking";
- case V4L2_CID_ANALOGUE_GAIN: return "Analogue Gain";
-
- /* Image processing controls */
- case V4L2_CID_IMAGE_PROC_CLASS: return "Image Processing Controls";
- case V4L2_CID_LINK_FREQ: return "Link Frequency";
- case V4L2_CID_PIXEL_RATE: return "Pixel Rate";
-
- default:
- return NULL;
- }
-}
-EXPORT_SYMBOL(v4l2_ctrl_get_name);
-
-void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
- s32 *min, s32 *max, s32 *step, s32 *def, u32 *flags)
-{
- *name = v4l2_ctrl_get_name(id);
- *flags = 0;
-
- switch (id) {
- case V4L2_CID_AUDIO_MUTE:
- case V4L2_CID_AUDIO_LOUDNESS:
- case V4L2_CID_AUTO_WHITE_BALANCE:
- case V4L2_CID_AUTOGAIN:
- case V4L2_CID_HFLIP:
- case V4L2_CID_VFLIP:
- case V4L2_CID_HUE_AUTO:
- case V4L2_CID_CHROMA_AGC:
- case V4L2_CID_COLOR_KILLER:
- case V4L2_CID_AUTOBRIGHTNESS:
- case V4L2_CID_MPEG_AUDIO_MUTE:
- case V4L2_CID_MPEG_VIDEO_MUTE:
- case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
- case V4L2_CID_MPEG_VIDEO_PULLDOWN:
- case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
- case V4L2_CID_FOCUS_AUTO:
- case V4L2_CID_PRIVACY:
- case V4L2_CID_AUDIO_LIMITER_ENABLED:
- case V4L2_CID_AUDIO_COMPRESSION_ENABLED:
- case V4L2_CID_PILOT_TONE_ENABLED:
- case V4L2_CID_ILLUMINATORS_1:
- case V4L2_CID_ILLUMINATORS_2:
- case V4L2_CID_FLASH_STROBE_STATUS:
- case V4L2_CID_FLASH_CHARGE:
- case V4L2_CID_FLASH_READY:
- case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
- case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE:
- case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
- case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
- case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
- case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
- case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
- case V4L2_CID_WIDE_DYNAMIC_RANGE:
- case V4L2_CID_IMAGE_STABILIZATION:
- *type = V4L2_CTRL_TYPE_BOOLEAN;
- *min = 0;
- *max = *step = 1;
- break;
- case V4L2_CID_PAN_RESET:
- case V4L2_CID_TILT_RESET:
- case V4L2_CID_FLASH_STROBE:
- case V4L2_CID_FLASH_STROBE_STOP:
- case V4L2_CID_AUTO_FOCUS_START:
- case V4L2_CID_AUTO_FOCUS_STOP:
- *type = V4L2_CTRL_TYPE_BUTTON;
- *flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
- *min = *max = *step = *def = 0;
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY:
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- case V4L2_CID_MPEG_AUDIO_MODE:
- case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
- case V4L2_CID_MPEG_AUDIO_EMPHASIS:
- case V4L2_CID_MPEG_AUDIO_CRC:
- case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
- case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK:
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- case V4L2_CID_MPEG_STREAM_TYPE:
- case V4L2_CID_MPEG_STREAM_VBI_FMT:
- case V4L2_CID_EXPOSURE_AUTO:
- case V4L2_CID_AUTO_FOCUS_RANGE:
- case V4L2_CID_COLORFX:
- case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
- case V4L2_CID_TUNE_PREEMPHASIS:
- case V4L2_CID_FLASH_LED_MODE:
- case V4L2_CID_FLASH_STROBE_SOURCE:
- case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
- case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
- case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
- case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
- case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
- case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
- case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
- case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
- case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
- case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
- case V4L2_CID_ISO_SENSITIVITY_AUTO:
- case V4L2_CID_EXPOSURE_METERING:
- case V4L2_CID_SCENE_MODE:
- *type = V4L2_CTRL_TYPE_MENU;
- break;
- case V4L2_CID_LINK_FREQ:
- *type = V4L2_CTRL_TYPE_INTEGER_MENU;
- break;
- case V4L2_CID_RDS_TX_PS_NAME:
- case V4L2_CID_RDS_TX_RADIO_TEXT:
- *type = V4L2_CTRL_TYPE_STRING;
- break;
- case V4L2_CID_ISO_SENSITIVITY:
- case V4L2_CID_AUTO_EXPOSURE_BIAS:
- *type = V4L2_CTRL_TYPE_INTEGER_MENU;
- break;
- case V4L2_CID_USER_CLASS:
- case V4L2_CID_CAMERA_CLASS:
- case V4L2_CID_MPEG_CLASS:
- case V4L2_CID_FM_TX_CLASS:
- case V4L2_CID_FLASH_CLASS:
- case V4L2_CID_JPEG_CLASS:
- case V4L2_CID_IMAGE_SOURCE_CLASS:
- case V4L2_CID_IMAGE_PROC_CLASS:
- *type = V4L2_CTRL_TYPE_CTRL_CLASS;
- /* You can neither read not write these */
- *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
- *min = *max = *step = *def = 0;
- break;
- case V4L2_CID_BG_COLOR:
- *type = V4L2_CTRL_TYPE_INTEGER;
- *step = 1;
- *min = 0;
- /* Max is calculated as RGB888 that is 2^24 */
- *max = 0xFFFFFF;
- break;
- case V4L2_CID_FLASH_FAULT:
- case V4L2_CID_JPEG_ACTIVE_MARKER:
- case V4L2_CID_3A_LOCK:
- case V4L2_CID_AUTO_FOCUS_STATUS:
- *type = V4L2_CTRL_TYPE_BITMASK;
- break;
- case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
- case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
- *type = V4L2_CTRL_TYPE_INTEGER;
- *flags |= V4L2_CTRL_FLAG_READ_ONLY;
- break;
- case V4L2_CID_MPEG_VIDEO_DEC_FRAME:
- case V4L2_CID_MPEG_VIDEO_DEC_PTS:
- *flags |= V4L2_CTRL_FLAG_VOLATILE;
- /* Fall through */
- case V4L2_CID_PIXEL_RATE:
- *type = V4L2_CTRL_TYPE_INTEGER64;
- *flags |= V4L2_CTRL_FLAG_READ_ONLY;
- *min = *max = *step = *def = 0;
- break;
- default:
- *type = V4L2_CTRL_TYPE_INTEGER;
- break;
- }
- switch (id) {
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- case V4L2_CID_MPEG_AUDIO_MODE:
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- case V4L2_CID_MPEG_STREAM_TYPE:
- *flags |= V4L2_CTRL_FLAG_UPDATE;
- break;
- case V4L2_CID_AUDIO_VOLUME:
- case V4L2_CID_AUDIO_BALANCE:
- case V4L2_CID_AUDIO_BASS:
- case V4L2_CID_AUDIO_TREBLE:
- case V4L2_CID_BRIGHTNESS:
- case V4L2_CID_CONTRAST:
- case V4L2_CID_SATURATION:
- case V4L2_CID_HUE:
- case V4L2_CID_RED_BALANCE:
- case V4L2_CID_BLUE_BALANCE:
- case V4L2_CID_GAMMA:
- case V4L2_CID_SHARPNESS:
- case V4L2_CID_CHROMA_GAIN:
- case V4L2_CID_RDS_TX_DEVIATION:
- case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME:
- case V4L2_CID_AUDIO_LIMITER_DEVIATION:
- case V4L2_CID_AUDIO_COMPRESSION_GAIN:
- case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD:
- case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME:
- case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME:
- case V4L2_CID_PILOT_TONE_DEVIATION:
- case V4L2_CID_PILOT_TONE_FREQUENCY:
- case V4L2_CID_TUNE_POWER_LEVEL:
- case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
- *flags |= V4L2_CTRL_FLAG_SLIDER;
- break;
- case V4L2_CID_PAN_RELATIVE:
- case V4L2_CID_TILT_RELATIVE:
- case V4L2_CID_FOCUS_RELATIVE:
- case V4L2_CID_IRIS_RELATIVE:
- case V4L2_CID_ZOOM_RELATIVE:
- *flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
- break;
- case V4L2_CID_FLASH_STROBE_STATUS:
- case V4L2_CID_AUTO_FOCUS_STATUS:
- case V4L2_CID_FLASH_READY:
- *flags |= V4L2_CTRL_FLAG_READ_ONLY;
- break;
- }
-}
-EXPORT_SYMBOL(v4l2_ctrl_fill);
-
-/* Helper function to determine whether the control type is compatible with
- VIDIOC_G/S_CTRL. */
-static bool type_is_int(const struct v4l2_ctrl *ctrl)
-{
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_INTEGER64:
- case V4L2_CTRL_TYPE_STRING:
- /* Nope, these need v4l2_ext_control */
- return false;
- default:
- return true;
- }
-}
-
-static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 changes)
-{
- memset(ev->reserved, 0, sizeof(ev->reserved));
- ev->type = V4L2_EVENT_CTRL;
- ev->id = ctrl->id;
- ev->u.ctrl.changes = changes;
- ev->u.ctrl.type = ctrl->type;
- ev->u.ctrl.flags = ctrl->flags;
- if (ctrl->type == V4L2_CTRL_TYPE_STRING)
- ev->u.ctrl.value64 = 0;
- else
- ev->u.ctrl.value64 = ctrl->cur.val64;
- ev->u.ctrl.minimum = ctrl->minimum;
- ev->u.ctrl.maximum = ctrl->maximum;
- if (ctrl->type == V4L2_CTRL_TYPE_MENU
- || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU)
- ev->u.ctrl.step = 1;
- else
- ev->u.ctrl.step = ctrl->step;
- ev->u.ctrl.default_value = ctrl->default_value;
-}
-
-static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes)
-{
- struct v4l2_event ev;
- struct v4l2_subscribed_event *sev;
-
- if (list_empty(&ctrl->ev_subs))
- return;
- fill_event(&ev, ctrl, changes);
-
- list_for_each_entry(sev, &ctrl->ev_subs, node)
- if (sev->fh != fh ||
- (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK))
- v4l2_event_queue_fh(sev->fh, &ev);
-}
-
-/* Helper function: copy the current control value back to the caller */
-static int cur_to_user(struct v4l2_ext_control *c,
- struct v4l2_ctrl *ctrl)
-{
- u32 len;
-
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_STRING:
- len = strlen(ctrl->cur.string);
- if (c->size < len + 1) {
- c->size = len + 1;
- return -ENOSPC;
- }
- return copy_to_user(c->string, ctrl->cur.string,
- len + 1) ? -EFAULT : 0;
- case V4L2_CTRL_TYPE_INTEGER64:
- c->value64 = ctrl->cur.val64;
- break;
- default:
- c->value = ctrl->cur.val;
- break;
- }
- return 0;
-}
-
-/* Helper function: copy the caller-provider value as the new control value */
-static int user_to_new(struct v4l2_ext_control *c,
- struct v4l2_ctrl *ctrl)
-{
- int ret;
- u32 size;
-
- ctrl->is_new = 1;
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_INTEGER64:
- ctrl->val64 = c->value64;
- break;
- case V4L2_CTRL_TYPE_STRING:
- size = c->size;
- if (size == 0)
- return -ERANGE;
- if (size > ctrl->maximum + 1)
- size = ctrl->maximum + 1;
- ret = copy_from_user(ctrl->string, c->string, size);
- if (!ret) {
- char last = ctrl->string[size - 1];
-
- ctrl->string[size - 1] = 0;
- /* If the string was longer than ctrl->maximum,
- then return an error. */
- if (strlen(ctrl->string) == ctrl->maximum && last)
- return -ERANGE;
- }
- return ret ? -EFAULT : 0;
- default:
- ctrl->val = c->value;
- break;
- }
- return 0;
-}
-
-/* Helper function: copy the new control value back to the caller */
-static int new_to_user(struct v4l2_ext_control *c,
- struct v4l2_ctrl *ctrl)
-{
- u32 len;
-
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_STRING:
- len = strlen(ctrl->string);
- if (c->size < len + 1) {
- c->size = ctrl->maximum + 1;
- return -ENOSPC;
- }
- return copy_to_user(c->string, ctrl->string,
- len + 1) ? -EFAULT : 0;
- case V4L2_CTRL_TYPE_INTEGER64:
- c->value64 = ctrl->val64;
- break;
- default:
- c->value = ctrl->val;
- break;
- }
- return 0;
-}
-
-/* Copy the new value to the current value. */
-static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,
- bool update_inactive)
-{
- bool changed = false;
-
- if (ctrl == NULL)
- return;
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_BUTTON:
- changed = true;
- break;
- case V4L2_CTRL_TYPE_STRING:
- /* strings are always 0-terminated */
- changed = strcmp(ctrl->string, ctrl->cur.string);
- strcpy(ctrl->cur.string, ctrl->string);
- break;
- case V4L2_CTRL_TYPE_INTEGER64:
- changed = ctrl->val64 != ctrl->cur.val64;
- ctrl->cur.val64 = ctrl->val64;
- break;
- default:
- changed = ctrl->val != ctrl->cur.val;
- ctrl->cur.val = ctrl->val;
- break;
- }
- if (update_inactive) {
- /* Note: update_inactive can only be true for auto clusters. */
- ctrl->flags &=
- ~(V4L2_CTRL_FLAG_INACTIVE | V4L2_CTRL_FLAG_VOLATILE);
- if (!is_cur_manual(ctrl->cluster[0])) {
- ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- if (ctrl->cluster[0]->has_volatiles)
- ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
- }
- fh = NULL;
- }
- if (changed || update_inactive) {
- /* If a control was changed that was not one of the controls
- modified by the application, then send the event to all. */
- if (!ctrl->is_new)
- fh = NULL;
- send_event(fh, ctrl,
- (changed ? V4L2_EVENT_CTRL_CH_VALUE : 0) |
- (update_inactive ? V4L2_EVENT_CTRL_CH_FLAGS : 0));
- }
-}
-
-/* Copy the current value to the new value */
-static void cur_to_new(struct v4l2_ctrl *ctrl)
-{
- if (ctrl == NULL)
- return;
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_STRING:
- /* strings are always 0-terminated */
- strcpy(ctrl->string, ctrl->cur.string);
- break;
- case V4L2_CTRL_TYPE_INTEGER64:
- ctrl->val64 = ctrl->cur.val64;
- break;
- default:
- ctrl->val = ctrl->cur.val;
- break;
- }
-}
-
-/* Return non-zero if one or more of the controls in the cluster has a new
- value that differs from the current value. */
-static int cluster_changed(struct v4l2_ctrl *master)
-{
- int diff = 0;
- int i;
-
- for (i = 0; !diff && i < master->ncontrols; i++) {
- struct v4l2_ctrl *ctrl = master->cluster[i];
-
- if (ctrl == NULL)
- continue;
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_BUTTON:
- /* Button controls are always 'different' */
- return 1;
- case V4L2_CTRL_TYPE_STRING:
- /* strings are always 0-terminated */
- diff = strcmp(ctrl->string, ctrl->cur.string);
- break;
- case V4L2_CTRL_TYPE_INTEGER64:
- diff = ctrl->val64 != ctrl->cur.val64;
- break;
- default:
- diff = ctrl->val != ctrl->cur.val;
- break;
- }
- }
- return diff;
-}
-
-/* Validate integer-type control */
-static int validate_new_int(const struct v4l2_ctrl *ctrl, s32 *pval)
-{
- s32 val = *pval;
- u32 offset;
-
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_INTEGER:
- /* Round towards the closest legal value */
- val += ctrl->step / 2;
- if (val < ctrl->minimum)
- val = ctrl->minimum;
- if (val > ctrl->maximum)
- val = ctrl->maximum;
- offset = val - ctrl->minimum;
- offset = ctrl->step * (offset / ctrl->step);
- val = ctrl->minimum + offset;
- *pval = val;
- return 0;
-
- case V4L2_CTRL_TYPE_BOOLEAN:
- *pval = !!val;
- return 0;
-
- case V4L2_CTRL_TYPE_MENU:
- case V4L2_CTRL_TYPE_INTEGER_MENU:
- if (val < ctrl->minimum || val > ctrl->maximum)
- return -ERANGE;
- if (ctrl->menu_skip_mask & (1 << val))
- return -EINVAL;
- if (ctrl->type == V4L2_CTRL_TYPE_MENU &&
- ctrl->qmenu[val][0] == '\0')
- return -EINVAL;
- return 0;
-
- case V4L2_CTRL_TYPE_BITMASK:
- *pval &= ctrl->maximum;
- return 0;
-
- case V4L2_CTRL_TYPE_BUTTON:
- case V4L2_CTRL_TYPE_CTRL_CLASS:
- *pval = 0;
- return 0;
-
- default:
- return -EINVAL;
- }
-}
-
-/* Validate a new control */
-static int validate_new(const struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c)
-{
- char *s = c->string;
- size_t len;
-
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_INTEGER:
- case V4L2_CTRL_TYPE_BOOLEAN:
- case V4L2_CTRL_TYPE_MENU:
- case V4L2_CTRL_TYPE_INTEGER_MENU:
- case V4L2_CTRL_TYPE_BITMASK:
- case V4L2_CTRL_TYPE_BUTTON:
- case V4L2_CTRL_TYPE_CTRL_CLASS:
- return validate_new_int(ctrl, &c->value);
-
- case V4L2_CTRL_TYPE_INTEGER64:
- return 0;
-
- case V4L2_CTRL_TYPE_STRING:
- len = strlen(s);
- if (len < ctrl->minimum)
- return -ERANGE;
- if ((len - ctrl->minimum) % ctrl->step)
- return -ERANGE;
- return 0;
-
- default:
- return -EINVAL;
- }
-}
-
-static inline u32 node2id(struct list_head *node)
-{
- return list_entry(node, struct v4l2_ctrl_ref, node)->ctrl->id;
-}
-
-/* Set the handler's error code if it wasn't set earlier already */
-static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err)
-{
- if (hdl->error == 0)
- hdl->error = err;
- return err;
-}
-
-/* Initialize the handler */
-int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl,
- unsigned nr_of_controls_hint)
-{
- hdl->lock = &hdl->_lock;
- mutex_init(hdl->lock);
- INIT_LIST_HEAD(&hdl->ctrls);
- INIT_LIST_HEAD(&hdl->ctrl_refs);
- hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8;
- hdl->buckets = kcalloc(hdl->nr_of_buckets, sizeof(hdl->buckets[0]),
- GFP_KERNEL);
- hdl->error = hdl->buckets ? 0 : -ENOMEM;
- return hdl->error;
-}
-EXPORT_SYMBOL(v4l2_ctrl_handler_init);
-
-/* Free all controls and control refs */
-void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
-{
- struct v4l2_ctrl_ref *ref, *next_ref;
- struct v4l2_ctrl *ctrl, *next_ctrl;
- struct v4l2_subscribed_event *sev, *next_sev;
-
- if (hdl == NULL || hdl->buckets == NULL)
- return;
-
- mutex_lock(hdl->lock);
- /* Free all nodes */
- list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) {
- list_del(&ref->node);
- kfree(ref);
- }
- /* Free all controls owned by the handler */
- list_for_each_entry_safe(ctrl, next_ctrl, &hdl->ctrls, node) {
- list_del(&ctrl->node);
- list_for_each_entry_safe(sev, next_sev, &ctrl->ev_subs, node)
- list_del(&sev->node);
- kfree(ctrl);
- }
- kfree(hdl->buckets);
- hdl->buckets = NULL;
- hdl->cached = NULL;
- hdl->error = 0;
- mutex_unlock(hdl->lock);
-}
-EXPORT_SYMBOL(v4l2_ctrl_handler_free);
-
-/* For backwards compatibility: V4L2_CID_PRIVATE_BASE should no longer
- be used except in G_CTRL, S_CTRL, QUERYCTRL and QUERYMENU when dealing
- with applications that do not use the NEXT_CTRL flag.
-
- We just find the n-th private user control. It's O(N), but that should not
- be an issue in this particular case. */
-static struct v4l2_ctrl_ref *find_private_ref(
- struct v4l2_ctrl_handler *hdl, u32 id)
-{
- struct v4l2_ctrl_ref *ref;
-
- id -= V4L2_CID_PRIVATE_BASE;
- list_for_each_entry(ref, &hdl->ctrl_refs, node) {
- /* Search for private user controls that are compatible with
- VIDIOC_G/S_CTRL. */
- if (V4L2_CTRL_ID2CLASS(ref->ctrl->id) == V4L2_CTRL_CLASS_USER &&
- V4L2_CTRL_DRIVER_PRIV(ref->ctrl->id)) {
- if (!type_is_int(ref->ctrl))
- continue;
- if (id == 0)
- return ref;
- id--;
- }
- }
- return NULL;
-}
-
-/* Find a control with the given ID. */
-static struct v4l2_ctrl_ref *find_ref(struct v4l2_ctrl_handler *hdl, u32 id)
-{
- struct v4l2_ctrl_ref *ref;
- int bucket;
-
- id &= V4L2_CTRL_ID_MASK;
-
- /* Old-style private controls need special handling */
- if (id >= V4L2_CID_PRIVATE_BASE)
- return find_private_ref(hdl, id);
- bucket = id % hdl->nr_of_buckets;
-
- /* Simple optimization: cache the last control found */
- if (hdl->cached && hdl->cached->ctrl->id == id)
- return hdl->cached;
-
- /* Not in cache, search the hash */
- ref = hdl->buckets ? hdl->buckets[bucket] : NULL;
- while (ref && ref->ctrl->id != id)
- ref = ref->next;
-
- if (ref)
- hdl->cached = ref; /* cache it! */
- return ref;
-}
-
-/* Find a control with the given ID. Take the handler's lock first. */
-static struct v4l2_ctrl_ref *find_ref_lock(
- struct v4l2_ctrl_handler *hdl, u32 id)
-{
- struct v4l2_ctrl_ref *ref = NULL;
-
- if (hdl) {
- mutex_lock(hdl->lock);
- ref = find_ref(hdl, id);
- mutex_unlock(hdl->lock);
- }
- return ref;
-}
-
-/* Find a control with the given ID. */
-struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id)
-{
- struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id);
-
- return ref ? ref->ctrl : NULL;
-}
-EXPORT_SYMBOL(v4l2_ctrl_find);
-
-/* Allocate a new v4l2_ctrl_ref and hook it into the handler. */
-static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
- struct v4l2_ctrl *ctrl)
-{
- struct v4l2_ctrl_ref *ref;
- struct v4l2_ctrl_ref *new_ref;
- u32 id = ctrl->id;
- u32 class_ctrl = V4L2_CTRL_ID2CLASS(id) | 1;
- int bucket = id % hdl->nr_of_buckets; /* which bucket to use */
-
- /* Automatically add the control class if it is not yet present. */
- if (id != class_ctrl && find_ref_lock(hdl, class_ctrl) == NULL)
- if (!v4l2_ctrl_new_std(hdl, NULL, class_ctrl, 0, 0, 0, 0))
- return hdl->error;
-
- if (hdl->error)
- return hdl->error;
-
- new_ref = kzalloc(sizeof(*new_ref), GFP_KERNEL);
- if (!new_ref)
- return handler_set_err(hdl, -ENOMEM);
- new_ref->ctrl = ctrl;
- if (ctrl->handler == hdl) {
- /* By default each control starts in a cluster of its own.
- new_ref->ctrl is basically a cluster array with one
- element, so that's perfect to use as the cluster pointer.
- But only do this for the handler that owns the control. */
- ctrl->cluster = &new_ref->ctrl;
- ctrl->ncontrols = 1;
- }
-
- INIT_LIST_HEAD(&new_ref->node);
-
- mutex_lock(hdl->lock);
-
- /* Add immediately at the end of the list if the list is empty, or if
- the last element in the list has a lower ID.
- This ensures that when elements are added in ascending order the
- insertion is an O(1) operation. */
- if (list_empty(&hdl->ctrl_refs) || id > node2id(hdl->ctrl_refs.prev)) {
- list_add_tail(&new_ref->node, &hdl->ctrl_refs);
- goto insert_in_hash;
- }
-
- /* Find insert position in sorted list */
- list_for_each_entry(ref, &hdl->ctrl_refs, node) {
- if (ref->ctrl->id < id)
- continue;
- /* Don't add duplicates */
- if (ref->ctrl->id == id) {
- kfree(new_ref);
- goto unlock;
- }
- list_add(&new_ref->node, ref->node.prev);
- break;
- }
-
-insert_in_hash:
- /* Insert the control node in the hash */
- new_ref->next = hdl->buckets[bucket];
- hdl->buckets[bucket] = new_ref;
-
-unlock:
- mutex_unlock(hdl->lock);
- return 0;
-}
-
-/* Add a new control */
-static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
- const struct v4l2_ctrl_ops *ops,
- u32 id, const char *name, enum v4l2_ctrl_type type,
- s32 min, s32 max, u32 step, s32 def,
- u32 flags, const char * const *qmenu,
- const s64 *qmenu_int, void *priv)
-{
- struct v4l2_ctrl *ctrl;
- unsigned sz_extra = 0;
-
- if (hdl->error)
- return NULL;
-
- /* Sanity checks */
- if (id == 0 || name == NULL || id >= V4L2_CID_PRIVATE_BASE ||
- (type == V4L2_CTRL_TYPE_INTEGER && step == 0) ||
- (type == V4L2_CTRL_TYPE_BITMASK && max == 0) ||
- (type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) ||
- (type == V4L2_CTRL_TYPE_INTEGER_MENU && qmenu_int == NULL) ||
- (type == V4L2_CTRL_TYPE_STRING && max == 0)) {
- handler_set_err(hdl, -ERANGE);
- return NULL;
- }
- if (type != V4L2_CTRL_TYPE_BITMASK && max < min) {
- handler_set_err(hdl, -ERANGE);
- return NULL;
- }
- if ((type == V4L2_CTRL_TYPE_INTEGER ||
- type == V4L2_CTRL_TYPE_MENU ||
- type == V4L2_CTRL_TYPE_INTEGER_MENU ||
- type == V4L2_CTRL_TYPE_BOOLEAN) &&
- (def < min || def > max)) {
- handler_set_err(hdl, -ERANGE);
- return NULL;
- }
- if (type == V4L2_CTRL_TYPE_BITMASK && ((def & ~max) || min || step)) {
- handler_set_err(hdl, -ERANGE);
- return NULL;
- }
-
- if (type == V4L2_CTRL_TYPE_BUTTON)
- flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
- else if (type == V4L2_CTRL_TYPE_CTRL_CLASS)
- flags |= V4L2_CTRL_FLAG_READ_ONLY;
- else if (type == V4L2_CTRL_TYPE_STRING)
- sz_extra += 2 * (max + 1);
-
- ctrl = kzalloc(sizeof(*ctrl) + sz_extra, GFP_KERNEL);
- if (ctrl == NULL) {
- handler_set_err(hdl, -ENOMEM);
- return NULL;
- }
-
- INIT_LIST_HEAD(&ctrl->node);
- INIT_LIST_HEAD(&ctrl->ev_subs);
- ctrl->handler = hdl;
- ctrl->ops = ops;
- ctrl->id = id;
- ctrl->name = name;
- ctrl->type = type;
- ctrl->flags = flags;
- ctrl->minimum = min;
- ctrl->maximum = max;
- ctrl->step = step;
- if (type == V4L2_CTRL_TYPE_MENU)
- ctrl->qmenu = qmenu;
- else if (type == V4L2_CTRL_TYPE_INTEGER_MENU)
- ctrl->qmenu_int = qmenu_int;
- ctrl->priv = priv;
- ctrl->cur.val = ctrl->val = ctrl->default_value = def;
-
- if (ctrl->type == V4L2_CTRL_TYPE_STRING) {
- ctrl->cur.string = (char *)&ctrl[1] + sz_extra - (max + 1);
- ctrl->string = (char *)&ctrl[1] + sz_extra - 2 * (max + 1);
- if (ctrl->minimum)
- memset(ctrl->cur.string, ' ', ctrl->minimum);
- }
- if (handler_new_ref(hdl, ctrl)) {
- kfree(ctrl);
- return NULL;
- }
- mutex_lock(hdl->lock);
- list_add_tail(&ctrl->node, &hdl->ctrls);
- mutex_unlock(hdl->lock);
- return ctrl;
-}
-
-struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
- const struct v4l2_ctrl_config *cfg, void *priv)
-{
- bool is_menu;
- struct v4l2_ctrl *ctrl;
- const char *name = cfg->name;
- const char * const *qmenu = cfg->qmenu;
- const s64 *qmenu_int = cfg->qmenu_int;
- enum v4l2_ctrl_type type = cfg->type;
- u32 flags = cfg->flags;
- s32 min = cfg->min;
- s32 max = cfg->max;
- u32 step = cfg->step;
- s32 def = cfg->def;
-
- if (name == NULL)
- v4l2_ctrl_fill(cfg->id, &name, &type, &min, &max, &step,
- &def, &flags);
-
- is_menu = (cfg->type == V4L2_CTRL_TYPE_MENU ||
- cfg->type == V4L2_CTRL_TYPE_INTEGER_MENU);
- if (is_menu)
- WARN_ON(step);
- else
- WARN_ON(cfg->menu_skip_mask);
- if (cfg->type == V4L2_CTRL_TYPE_MENU && qmenu == NULL)
- qmenu = v4l2_ctrl_get_menu(cfg->id);
- else if (cfg->type == V4L2_CTRL_TYPE_INTEGER_MENU &&
- qmenu_int == NULL) {
- handler_set_err(hdl, -EINVAL);
- return NULL;
- }
-
- ctrl = v4l2_ctrl_new(hdl, cfg->ops, cfg->id, name,
- type, min, max,
- is_menu ? cfg->menu_skip_mask : step,
- def, flags, qmenu, qmenu_int, priv);
- if (ctrl)
- ctrl->is_private = cfg->is_private;
- return ctrl;
-}
-EXPORT_SYMBOL(v4l2_ctrl_new_custom);
-
-/* Helper function for standard non-menu controls */
-struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
- const struct v4l2_ctrl_ops *ops,
- u32 id, s32 min, s32 max, u32 step, s32 def)
-{
- const char *name;
- enum v4l2_ctrl_type type;
- u32 flags;
-
- v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
- if (type == V4L2_CTRL_TYPE_MENU
- || type == V4L2_CTRL_TYPE_INTEGER_MENU) {
- handler_set_err(hdl, -EINVAL);
- return NULL;
- }
- return v4l2_ctrl_new(hdl, ops, id, name, type,
- min, max, step, def, flags, NULL, NULL, NULL);
-}
-EXPORT_SYMBOL(v4l2_ctrl_new_std);
-
-/* Helper function for standard menu controls */
-struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
- const struct v4l2_ctrl_ops *ops,
- u32 id, s32 max, s32 mask, s32 def)
-{
- const char * const *qmenu = v4l2_ctrl_get_menu(id);
- const char *name;
- enum v4l2_ctrl_type type;
- s32 min;
- s32 step;
- u32 flags;
-
- v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
- if (type != V4L2_CTRL_TYPE_MENU) {
- handler_set_err(hdl, -EINVAL);
- return NULL;
- }
- return v4l2_ctrl_new(hdl, ops, id, name, type,
- 0, max, mask, def, flags, qmenu, NULL, NULL);
-}
-EXPORT_SYMBOL(v4l2_ctrl_new_std_menu);
-
-/* Helper function for standard integer menu controls */
-struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
- const struct v4l2_ctrl_ops *ops,
- u32 id, s32 max, s32 def, const s64 *qmenu_int)
-{
- const char *name;
- enum v4l2_ctrl_type type;
- s32 min;
- s32 step;
- u32 flags;
-
- v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
- if (type != V4L2_CTRL_TYPE_INTEGER_MENU) {
- handler_set_err(hdl, -EINVAL);
- return NULL;
- }
- return v4l2_ctrl_new(hdl, ops, id, name, type,
- 0, max, 0, def, flags, NULL, qmenu_int, NULL);
-}
-EXPORT_SYMBOL(v4l2_ctrl_new_int_menu);
-
-/* Add a control from another handler to this handler */
-struct v4l2_ctrl *v4l2_ctrl_add_ctrl(struct v4l2_ctrl_handler *hdl,
- struct v4l2_ctrl *ctrl)
-{
- if (hdl == NULL || hdl->error)
- return NULL;
- if (ctrl == NULL) {
- handler_set_err(hdl, -EINVAL);
- return NULL;
- }
- if (ctrl->handler == hdl)
- return ctrl;
- return handler_new_ref(hdl, ctrl) ? NULL : ctrl;
-}
-EXPORT_SYMBOL(v4l2_ctrl_add_ctrl);
-
-/* Add the controls from another handler to our own. */
-int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
- struct v4l2_ctrl_handler *add)
-{
- struct v4l2_ctrl_ref *ref;
- int ret = 0;
-
- /* Do nothing if either handler is NULL or if they are the same */
- if (!hdl || !add || hdl == add)
- return 0;
- if (hdl->error)
- return hdl->error;
- mutex_lock(add->lock);
- list_for_each_entry(ref, &add->ctrl_refs, node) {
- struct v4l2_ctrl *ctrl = ref->ctrl;
-
- /* Skip handler-private controls. */
- if (ctrl->is_private)
- continue;
- /* And control classes */
- if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
- continue;
- ret = handler_new_ref(hdl, ctrl);
- if (ret)
- break;
- }
- mutex_unlock(add->lock);
- return ret;
-}
-EXPORT_SYMBOL(v4l2_ctrl_add_handler);
-
-/* Cluster controls */
-void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls)
-{
- bool has_volatiles = false;
- int i;
-
- /* The first control is the master control and it must not be NULL */
- BUG_ON(ncontrols == 0 || controls[0] == NULL);
-
- for (i = 0; i < ncontrols; i++) {
- if (controls[i]) {
- controls[i]->cluster = controls;
- controls[i]->ncontrols = ncontrols;
- if (controls[i]->flags & V4L2_CTRL_FLAG_VOLATILE)
- has_volatiles = true;
- }
- }
- controls[0]->has_volatiles = has_volatiles;
-}
-EXPORT_SYMBOL(v4l2_ctrl_cluster);
-
-void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls,
- u8 manual_val, bool set_volatile)
-{
- struct v4l2_ctrl *master = controls[0];
- u32 flag = 0;
- int i;
-
- v4l2_ctrl_cluster(ncontrols, controls);
- WARN_ON(ncontrols <= 1);
- WARN_ON(manual_val < master->minimum || manual_val > master->maximum);
- WARN_ON(set_volatile && !has_op(master, g_volatile_ctrl));
- master->is_auto = true;
- master->has_volatiles = set_volatile;
- master->manual_mode_value = manual_val;
- master->flags |= V4L2_CTRL_FLAG_UPDATE;
-
- if (!is_cur_manual(master))
- flag = V4L2_CTRL_FLAG_INACTIVE |
- (set_volatile ? V4L2_CTRL_FLAG_VOLATILE : 0);
-
- for (i = 1; i < ncontrols; i++)
- if (controls[i])
- controls[i]->flags |= flag;
-}
-EXPORT_SYMBOL(v4l2_ctrl_auto_cluster);
-
-/* Activate/deactivate a control. */
-void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active)
-{
- /* invert since the actual flag is called 'inactive' */
- bool inactive = !active;
- bool old;
-
- if (ctrl == NULL)
- return;
-
- if (inactive)
- /* set V4L2_CTRL_FLAG_INACTIVE */
- old = test_and_set_bit(4, &ctrl->flags);
- else
- /* clear V4L2_CTRL_FLAG_INACTIVE */
- old = test_and_clear_bit(4, &ctrl->flags);
- if (old != inactive)
- send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS);
-}
-EXPORT_SYMBOL(v4l2_ctrl_activate);
-
-/* Grab/ungrab a control.
- Typically used when streaming starts and you want to grab controls,
- preventing the user from changing them.
-
- Just call this and the framework will block any attempts to change
- these controls. */
-void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed)
-{
- bool old;
-
- if (ctrl == NULL)
- return;
-
- v4l2_ctrl_lock(ctrl);
- if (grabbed)
- /* set V4L2_CTRL_FLAG_GRABBED */
- old = test_and_set_bit(1, &ctrl->flags);
- else
- /* clear V4L2_CTRL_FLAG_GRABBED */
- old = test_and_clear_bit(1, &ctrl->flags);
- if (old != grabbed)
- send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS);
- v4l2_ctrl_unlock(ctrl);
-}
-EXPORT_SYMBOL(v4l2_ctrl_grab);
-
-/* Log the control name and value */
-static void log_ctrl(const struct v4l2_ctrl *ctrl,
- const char *prefix, const char *colon)
-{
- if (ctrl->flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_WRITE_ONLY))
- return;
- if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
- return;
-
- printk(KERN_INFO "%s%s%s: ", prefix, colon, ctrl->name);
-
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_INTEGER:
- printk(KERN_CONT "%d", ctrl->cur.val);
- break;
- case V4L2_CTRL_TYPE_BOOLEAN:
- printk(KERN_CONT "%s", ctrl->cur.val ? "true" : "false");
- break;
- case V4L2_CTRL_TYPE_MENU:
- printk(KERN_CONT "%s", ctrl->qmenu[ctrl->cur.val]);
- break;
- case V4L2_CTRL_TYPE_INTEGER_MENU:
- printk(KERN_CONT "%lld", ctrl->qmenu_int[ctrl->cur.val]);
- break;
- case V4L2_CTRL_TYPE_BITMASK:
- printk(KERN_CONT "0x%08x", ctrl->cur.val);
- break;
- case V4L2_CTRL_TYPE_INTEGER64:
- printk(KERN_CONT "%lld", ctrl->cur.val64);
- break;
- case V4L2_CTRL_TYPE_STRING:
- printk(KERN_CONT "%s", ctrl->cur.string);
- break;
- default:
- printk(KERN_CONT "unknown type %d", ctrl->type);
- break;
- }
- if (ctrl->flags & (V4L2_CTRL_FLAG_INACTIVE |
- V4L2_CTRL_FLAG_GRABBED |
- V4L2_CTRL_FLAG_VOLATILE)) {
- if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
- printk(KERN_CONT " inactive");
- if (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)
- printk(KERN_CONT " grabbed");
- if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE)
- printk(KERN_CONT " volatile");
- }
- printk(KERN_CONT "\n");
-}
-
-/* Log all controls owned by the handler */
-void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl,
- const char *prefix)
-{
- struct v4l2_ctrl *ctrl;
- const char *colon = "";
- int len;
-
- if (hdl == NULL)
- return;
- if (prefix == NULL)
- prefix = "";
- len = strlen(prefix);
- if (len && prefix[len - 1] != ' ')
- colon = ": ";
- mutex_lock(hdl->lock);
- list_for_each_entry(ctrl, &hdl->ctrls, node)
- if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED))
- log_ctrl(ctrl, prefix, colon);
- mutex_unlock(hdl->lock);
-}
-EXPORT_SYMBOL(v4l2_ctrl_handler_log_status);
-
-/* Call s_ctrl for all controls owned by the handler */
-int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
-{
- struct v4l2_ctrl *ctrl;
- int ret = 0;
-
- if (hdl == NULL)
- return 0;
- mutex_lock(hdl->lock);
- list_for_each_entry(ctrl, &hdl->ctrls, node)
- ctrl->done = false;
-
- list_for_each_entry(ctrl, &hdl->ctrls, node) {
- struct v4l2_ctrl *master = ctrl->cluster[0];
- int i;
-
- /* Skip if this control was already handled by a cluster. */
- /* Skip button controls and read-only controls. */
- if (ctrl->done || ctrl->type == V4L2_CTRL_TYPE_BUTTON ||
- (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY))
- continue;
-
- for (i = 0; i < master->ncontrols; i++) {
- if (master->cluster[i]) {
- cur_to_new(master->cluster[i]);
- master->cluster[i]->is_new = 1;
- master->cluster[i]->done = true;
- }
- }
- ret = call_op(master, s_ctrl);
- if (ret)
- break;
- }
- mutex_unlock(hdl->lock);
- return ret;
-}
-EXPORT_SYMBOL(v4l2_ctrl_handler_setup);
-
-/* Implement VIDIOC_QUERYCTRL */
-int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
-{
- u32 id = qc->id & V4L2_CTRL_ID_MASK;
- struct v4l2_ctrl_ref *ref;
- struct v4l2_ctrl *ctrl;
-
- if (hdl == NULL)
- return -EINVAL;
-
- mutex_lock(hdl->lock);
-
- /* Try to find it */
- ref = find_ref(hdl, id);
-
- if ((qc->id & V4L2_CTRL_FLAG_NEXT_CTRL) && !list_empty(&hdl->ctrl_refs)) {
- /* Find the next control with ID > qc->id */
-
- /* Did we reach the end of the control list? */
- if (id >= node2id(hdl->ctrl_refs.prev)) {
- ref = NULL; /* Yes, so there is no next control */
- } else if (ref) {
- /* We found a control with the given ID, so just get
- the next one in the list. */
- ref = list_entry(ref->node.next, typeof(*ref), node);
- } else {
- /* No control with the given ID exists, so start
- searching for the next largest ID. We know there
- is one, otherwise the first 'if' above would have
- been true. */
- list_for_each_entry(ref, &hdl->ctrl_refs, node)
- if (id < ref->ctrl->id)
- break;
- }
- }
- mutex_unlock(hdl->lock);
- if (!ref)
- return -EINVAL;
-
- ctrl = ref->ctrl;
- memset(qc, 0, sizeof(*qc));
- if (id >= V4L2_CID_PRIVATE_BASE)
- qc->id = id;
- else
- qc->id = ctrl->id;
- strlcpy(qc->name, ctrl->name, sizeof(qc->name));
- qc->minimum = ctrl->minimum;
- qc->maximum = ctrl->maximum;
- qc->default_value = ctrl->default_value;
- if (ctrl->type == V4L2_CTRL_TYPE_MENU
- || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU)
- qc->step = 1;
- else
- qc->step = ctrl->step;
- qc->flags = ctrl->flags;
- qc->type = ctrl->type;
- return 0;
-}
-EXPORT_SYMBOL(v4l2_queryctrl);
-
-int v4l2_subdev_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
-{
- if (qc->id & V4L2_CTRL_FLAG_NEXT_CTRL)
- return -EINVAL;
- return v4l2_queryctrl(sd->ctrl_handler, qc);
-}
-EXPORT_SYMBOL(v4l2_subdev_queryctrl);
-
-/* Implement VIDIOC_QUERYMENU */
-int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm)
-{
- struct v4l2_ctrl *ctrl;
- u32 i = qm->index;
-
- ctrl = v4l2_ctrl_find(hdl, qm->id);
- if (!ctrl)
- return -EINVAL;
-
- qm->reserved = 0;
- /* Sanity checks */
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_MENU:
- if (ctrl->qmenu == NULL)
- return -EINVAL;
- break;
- case V4L2_CTRL_TYPE_INTEGER_MENU:
- if (ctrl->qmenu_int == NULL)
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
-
- if (i < ctrl->minimum || i > ctrl->maximum)
- return -EINVAL;
-
- /* Use mask to see if this menu item should be skipped */
- if (ctrl->menu_skip_mask & (1 << i))
- return -EINVAL;
- /* Empty menu items should also be skipped */
- if (ctrl->type == V4L2_CTRL_TYPE_MENU) {
- if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0')
- return -EINVAL;
- strlcpy(qm->name, ctrl->qmenu[i], sizeof(qm->name));
- } else {
- qm->value = ctrl->qmenu_int[i];
- }
- return 0;
-}
-EXPORT_SYMBOL(v4l2_querymenu);
-
-int v4l2_subdev_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qm)
-{
- return v4l2_querymenu(sd->ctrl_handler, qm);
-}
-EXPORT_SYMBOL(v4l2_subdev_querymenu);
-
-
-
-/* Some general notes on the atomic requirements of VIDIOC_G/TRY/S_EXT_CTRLS:
-
- It is not a fully atomic operation, just best-effort only. After all, if
- multiple controls have to be set through multiple i2c writes (for example)
- then some initial writes may succeed while others fail. Thus leaving the
- system in an inconsistent state. The question is how much effort you are
- willing to spend on trying to make something atomic that really isn't.
-
- From the point of view of an application the main requirement is that
- when you call VIDIOC_S_EXT_CTRLS and some values are invalid then an
- error should be returned without actually affecting any controls.
-
- If all the values are correct, then it is acceptable to just give up
- in case of low-level errors.
-
- It is important though that the application can tell when only a partial
- configuration was done. The way we do that is through the error_idx field
- of struct v4l2_ext_controls: if that is equal to the count field then no
- controls were affected. Otherwise all controls before that index were
- successful in performing their 'get' or 'set' operation, the control at
- the given index failed, and you don't know what happened with the controls
- after the failed one. Since if they were part of a control cluster they
- could have been successfully processed (if a cluster member was encountered
- at index < error_idx), they could have failed (if a cluster member was at
- error_idx), or they may not have been processed yet (if the first cluster
- member appeared after error_idx).
-
- It is all fairly theoretical, though. In practice all you can do is to
- bail out. If error_idx == count, then it is an application bug. If
- error_idx < count then it is only an application bug if the error code was
- EBUSY. That usually means that something started streaming just when you
- tried to set the controls. In all other cases it is a driver/hardware
- problem and all you can do is to retry or bail out.
-
- Note that these rules do not apply to VIDIOC_TRY_EXT_CTRLS: since that
- never modifies controls the error_idx is just set to whatever control
- has an invalid value.
- */
-
-/* Prepare for the extended g/s/try functions.
- Find the controls in the control array and do some basic checks. */
-static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
- struct v4l2_ext_controls *cs,
- struct v4l2_ctrl_helper *helpers)
-{
- struct v4l2_ctrl_helper *h;
- bool have_clusters = false;
- u32 i;
-
- for (i = 0, h = helpers; i < cs->count; i++, h++) {
- struct v4l2_ext_control *c = &cs->controls[i];
- struct v4l2_ctrl_ref *ref;
- struct v4l2_ctrl *ctrl;
- u32 id = c->id & V4L2_CTRL_ID_MASK;
-
- cs->error_idx = i;
-
- if (cs->ctrl_class && V4L2_CTRL_ID2CLASS(id) != cs->ctrl_class)
- return -EINVAL;
-
- /* Old-style private controls are not allowed for
- extended controls */
- if (id >= V4L2_CID_PRIVATE_BASE)
- return -EINVAL;
- ref = find_ref_lock(hdl, id);
- if (ref == NULL)
- return -EINVAL;
- ctrl = ref->ctrl;
- if (ctrl->flags & V4L2_CTRL_FLAG_DISABLED)
- return -EINVAL;
-
- if (ctrl->cluster[0]->ncontrols > 1)
- have_clusters = true;
- if (ctrl->cluster[0] != ctrl)
- ref = find_ref_lock(hdl, ctrl->cluster[0]->id);
- /* Store the ref to the master control of the cluster */
- h->mref = ref;
- h->ctrl = ctrl;
- /* Initially set next to 0, meaning that there is no other
- control in this helper array belonging to the same
- cluster */
- h->next = 0;
- }
-
- /* We are done if there were no controls that belong to a multi-
- control cluster. */
- if (!have_clusters)
- return 0;
-
- /* The code below figures out in O(n) time which controls in the list
- belong to the same cluster. */
-
- /* This has to be done with the handler lock taken. */
- mutex_lock(hdl->lock);
-
- /* First zero the helper field in the master control references */
- for (i = 0; i < cs->count; i++)
- helpers[i].mref->helper = NULL;
- for (i = 0, h = helpers; i < cs->count; i++, h++) {
- struct v4l2_ctrl_ref *mref = h->mref;
-
- /* If the mref->helper is set, then it points to an earlier
- helper that belongs to the same cluster. */
- if (mref->helper) {
- /* Set the next field of mref->helper to the current
- index: this means that that earlier helper now
- points to the next helper in the same cluster. */
- mref->helper->next = i;
- /* mref should be set only for the first helper in the
- cluster, clear the others. */
- h->mref = NULL;
- }
- /* Point the mref helper to the current helper struct. */
- mref->helper = h;
- }
- mutex_unlock(hdl->lock);
- return 0;
-}
-
-/* Handles the corner case where cs->count == 0. It checks whether the
- specified control class exists. If that class ID is 0, then it checks
- whether there are any controls at all. */
-static int class_check(struct v4l2_ctrl_handler *hdl, u32 ctrl_class)
-{
- if (ctrl_class == 0)
- return list_empty(&hdl->ctrl_refs) ? -EINVAL : 0;
- return find_ref_lock(hdl, ctrl_class | 1) ? 0 : -EINVAL;
-}
-
-
-
-/* Get extended controls. Allocates the helpers array if needed. */
-int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs)
-{
- struct v4l2_ctrl_helper helper[4];
- struct v4l2_ctrl_helper *helpers = helper;
- int ret;
- int i, j;
-
- cs->error_idx = cs->count;
- cs->ctrl_class = V4L2_CTRL_ID2CLASS(cs->ctrl_class);
-
- if (hdl == NULL)
- return -EINVAL;
-
- if (cs->count == 0)
- return class_check(hdl, cs->ctrl_class);
-
- if (cs->count > ARRAY_SIZE(helper)) {
- helpers = kmalloc_array(cs->count, sizeof(helper[0]),
- GFP_KERNEL);
- if (helpers == NULL)
- return -ENOMEM;
- }
-
- ret = prepare_ext_ctrls(hdl, cs, helpers);
- cs->error_idx = cs->count;
-
- for (i = 0; !ret && i < cs->count; i++)
- if (helpers[i].ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
- ret = -EACCES;
-
- for (i = 0; !ret && i < cs->count; i++) {
- int (*ctrl_to_user)(struct v4l2_ext_control *c,
- struct v4l2_ctrl *ctrl) = cur_to_user;
- struct v4l2_ctrl *master;
-
- if (helpers[i].mref == NULL)
- continue;
-
- master = helpers[i].mref->ctrl;
- cs->error_idx = i;
-
- v4l2_ctrl_lock(master);
-
- /* g_volatile_ctrl will update the new control values */
- if ((master->flags & V4L2_CTRL_FLAG_VOLATILE) ||
- (master->has_volatiles && !is_cur_manual(master))) {
- for (j = 0; j < master->ncontrols; j++)
- cur_to_new(master->cluster[j]);
- ret = call_op(master, g_volatile_ctrl);
- ctrl_to_user = new_to_user;
- }
- /* If OK, then copy the current (for non-volatile controls)
- or the new (for volatile controls) control values to the
- caller */
- if (!ret) {
- u32 idx = i;
-
- do {
- ret = ctrl_to_user(cs->controls + idx,
- helpers[idx].ctrl);
- idx = helpers[idx].next;
- } while (!ret && idx);
- }
- v4l2_ctrl_unlock(master);
- }
-
- if (cs->count > ARRAY_SIZE(helper))
- kfree(helpers);
- return ret;
-}
-EXPORT_SYMBOL(v4l2_g_ext_ctrls);
-
-int v4l2_subdev_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs)
-{
- return v4l2_g_ext_ctrls(sd->ctrl_handler, cs);
-}
-EXPORT_SYMBOL(v4l2_subdev_g_ext_ctrls);
-
-/* Helper function to get a single control */
-static int get_ctrl(struct v4l2_ctrl *ctrl, s32 *val)
-{
- struct v4l2_ctrl *master = ctrl->cluster[0];
- int ret = 0;
- int i;
-
- if (ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
- return -EACCES;
-
- v4l2_ctrl_lock(master);
- /* g_volatile_ctrl will update the current control values */
- if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) {
- for (i = 0; i < master->ncontrols; i++)
- cur_to_new(master->cluster[i]);
- ret = call_op(master, g_volatile_ctrl);
- *val = ctrl->val;
- } else {
- *val = ctrl->cur.val;
- }
- v4l2_ctrl_unlock(master);
- return ret;
-}
-
-int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *control)
-{
- struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id);
-
- if (ctrl == NULL || !type_is_int(ctrl))
- return -EINVAL;
- return get_ctrl(ctrl, &control->value);
-}
-EXPORT_SYMBOL(v4l2_g_ctrl);
-
-int v4l2_subdev_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *control)
-{
- return v4l2_g_ctrl(sd->ctrl_handler, control);
-}
-EXPORT_SYMBOL(v4l2_subdev_g_ctrl);
-
-s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl)
-{
- s32 val = 0;
-
- /* It's a driver bug if this happens. */
- WARN_ON(!type_is_int(ctrl));
- get_ctrl(ctrl, &val);
- return val;
-}
-EXPORT_SYMBOL(v4l2_ctrl_g_ctrl);
-
-
-/* Core function that calls try/s_ctrl and ensures that the new value is
- copied to the current value on a set.
- Must be called with ctrl->handler->lock held. */
-static int try_or_set_cluster(struct v4l2_fh *fh,
- struct v4l2_ctrl *master, bool set)
-{
- bool update_flag;
- int ret;
- int i;
-
- /* Go through the cluster and either validate the new value or
- (if no new value was set), copy the current value to the new
- value, ensuring a consistent view for the control ops when
- called. */
- for (i = 0; i < master->ncontrols; i++) {
- struct v4l2_ctrl *ctrl = master->cluster[i];
-
- if (ctrl == NULL)
- continue;
-
- if (!ctrl->is_new) {
- cur_to_new(ctrl);
- continue;
- }
- /* Check again: it may have changed since the
- previous check in try_or_set_ext_ctrls(). */
- if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED))
- return -EBUSY;
- }
-
- ret = call_op(master, try_ctrl);
-
- /* Don't set if there is no change */
- if (ret || !set || !cluster_changed(master))
- return ret;
- ret = call_op(master, s_ctrl);
- if (ret)
- return ret;
-
- /* If OK, then make the new values permanent. */
- update_flag = is_cur_manual(master) != is_new_manual(master);
- for (i = 0; i < master->ncontrols; i++)
- new_to_cur(fh, master->cluster[i], update_flag && i > 0);
- return 0;
-}
-
-/* Validate controls. */
-static int validate_ctrls(struct v4l2_ext_controls *cs,
- struct v4l2_ctrl_helper *helpers, bool set)
-{
- unsigned i;
- int ret = 0;
-
- cs->error_idx = cs->count;
- for (i = 0; i < cs->count; i++) {
- struct v4l2_ctrl *ctrl = helpers[i].ctrl;
-
- cs->error_idx = i;
-
- if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
- return -EACCES;
- /* This test is also done in try_set_control_cluster() which
- is called in atomic context, so that has the final say,
- but it makes sense to do an up-front check as well. Once
- an error occurs in try_set_control_cluster() some other
- controls may have been set already and we want to do a
- best-effort to avoid that. */
- if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED))
- return -EBUSY;
- ret = validate_new(ctrl, &cs->controls[i]);
- if (ret)
- return ret;
- }
- return 0;
-}
-
-/* Obtain the current volatile values of an autocluster and mark them
- as new. */
-static void update_from_auto_cluster(struct v4l2_ctrl *master)
-{
- int i;
-
- for (i = 0; i < master->ncontrols; i++)
- cur_to_new(master->cluster[i]);
- if (!call_op(master, g_volatile_ctrl))
- for (i = 1; i < master->ncontrols; i++)
- if (master->cluster[i])
- master->cluster[i]->is_new = 1;
-}
-
-/* Try or try-and-set controls */
-static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
- struct v4l2_ext_controls *cs,
- bool set)
-{
- struct v4l2_ctrl_helper helper[4];
- struct v4l2_ctrl_helper *helpers = helper;
- unsigned i, j;
- int ret;
-
- cs->error_idx = cs->count;
- cs->ctrl_class = V4L2_CTRL_ID2CLASS(cs->ctrl_class);
-
- if (hdl == NULL)
- return -EINVAL;
-
- if (cs->count == 0)
- return class_check(hdl, cs->ctrl_class);
-
- if (cs->count > ARRAY_SIZE(helper)) {
- helpers = kmalloc_array(cs->count, sizeof(helper[0]),
- GFP_KERNEL);
- if (!helpers)
- return -ENOMEM;
- }
- ret = prepare_ext_ctrls(hdl, cs, helpers);
- if (!ret)
- ret = validate_ctrls(cs, helpers, set);
- if (ret && set)
- cs->error_idx = cs->count;
- for (i = 0; !ret && i < cs->count; i++) {
- struct v4l2_ctrl *master;
- u32 idx = i;
-
- if (helpers[i].mref == NULL)
- continue;
-
- cs->error_idx = i;
- master = helpers[i].mref->ctrl;
- v4l2_ctrl_lock(master);
-
- /* Reset the 'is_new' flags of the cluster */
- for (j = 0; j < master->ncontrols; j++)
- if (master->cluster[j])
- master->cluster[j]->is_new = 0;
-
- /* For volatile autoclusters that are currently in auto mode
- we need to discover if it will be set to manual mode.
- If so, then we have to copy the current volatile values
- first since those will become the new manual values (which
- may be overwritten by explicit new values from this set
- of controls). */
- if (master->is_auto && master->has_volatiles &&
- !is_cur_manual(master)) {
- /* Pick an initial non-manual value */
- s32 new_auto_val = master->manual_mode_value + 1;
- u32 tmp_idx = idx;
-
- do {
- /* Check if the auto control is part of the
- list, and remember the new value. */
- if (helpers[tmp_idx].ctrl == master)
- new_auto_val = cs->controls[tmp_idx].value;
- tmp_idx = helpers[tmp_idx].next;
- } while (tmp_idx);
- /* If the new value == the manual value, then copy
- the current volatile values. */
- if (new_auto_val == master->manual_mode_value)
- update_from_auto_cluster(master);
- }
-
- /* Copy the new caller-supplied control values.
- user_to_new() sets 'is_new' to 1. */
- do {
- ret = user_to_new(cs->controls + idx, helpers[idx].ctrl);
- idx = helpers[idx].next;
- } while (!ret && idx);
-
- if (!ret)
- ret = try_or_set_cluster(fh, master, set);
-
- /* Copy the new values back to userspace. */
- if (!ret) {
- idx = i;
- do {
- ret = new_to_user(cs->controls + idx,
- helpers[idx].ctrl);
- idx = helpers[idx].next;
- } while (!ret && idx);
- }
- v4l2_ctrl_unlock(master);
- }
-
- if (cs->count > ARRAY_SIZE(helper))
- kfree(helpers);
- return ret;
-}
-
-int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs)
-{
- return try_set_ext_ctrls(NULL, hdl, cs, false);
-}
-EXPORT_SYMBOL(v4l2_try_ext_ctrls);
-
-int v4l2_s_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
- struct v4l2_ext_controls *cs)
-{
- return try_set_ext_ctrls(fh, hdl, cs, true);
-}
-EXPORT_SYMBOL(v4l2_s_ext_ctrls);
-
-int v4l2_subdev_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs)
-{
- return try_set_ext_ctrls(NULL, sd->ctrl_handler, cs, false);
-}
-EXPORT_SYMBOL(v4l2_subdev_try_ext_ctrls);
-
-int v4l2_subdev_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs)
-{
- return try_set_ext_ctrls(NULL, sd->ctrl_handler, cs, true);
-}
-EXPORT_SYMBOL(v4l2_subdev_s_ext_ctrls);
-
-/* Helper function for VIDIOC_S_CTRL compatibility */
-static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, s32 *val)
-{
- struct v4l2_ctrl *master = ctrl->cluster[0];
- int ret;
- int i;
-
- ret = validate_new_int(ctrl, val);
- if (ret)
- return ret;
-
- v4l2_ctrl_lock(ctrl);
-
- /* Reset the 'is_new' flags of the cluster */
- for (i = 0; i < master->ncontrols; i++)
- if (master->cluster[i])
- master->cluster[i]->is_new = 0;
-
- /* For autoclusters with volatiles that are switched from auto to
- manual mode we have to update the current volatile values since
- those will become the initial manual values after such a switch. */
- if (master->is_auto && master->has_volatiles && ctrl == master &&
- !is_cur_manual(master) && *val == master->manual_mode_value)
- update_from_auto_cluster(master);
- ctrl->val = *val;
- ctrl->is_new = 1;
- ret = try_or_set_cluster(fh, master, true);
- *val = ctrl->cur.val;
- v4l2_ctrl_unlock(ctrl);
- return ret;
-}
-
-int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
- struct v4l2_control *control)
-{
- struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id);
-
- if (ctrl == NULL || !type_is_int(ctrl))
- return -EINVAL;
-
- if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
- return -EACCES;
-
- return set_ctrl(fh, ctrl, &control->value);
-}
-EXPORT_SYMBOL(v4l2_s_ctrl);
-
-int v4l2_subdev_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *control)
-{
- return v4l2_s_ctrl(NULL, sd->ctrl_handler, control);
-}
-EXPORT_SYMBOL(v4l2_subdev_s_ctrl);
-
-int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)
-{
- /* It's a driver bug if this happens. */
- WARN_ON(!type_is_int(ctrl));
- return set_ctrl(NULL, ctrl, &val);
-}
-EXPORT_SYMBOL(v4l2_ctrl_s_ctrl);
-
-static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
-{
- struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
-
- if (ctrl == NULL)
- return -EINVAL;
-
- v4l2_ctrl_lock(ctrl);
- list_add_tail(&sev->node, &ctrl->ev_subs);
- if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS &&
- (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL)) {
- struct v4l2_event ev;
- u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;
-
- if (!(ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY))
- changes |= V4L2_EVENT_CTRL_CH_VALUE;
- fill_event(&ev, ctrl, changes);
- /* Mark the queue as active, allowing this initial
- event to be accepted. */
- sev->elems = elems;
- v4l2_event_queue_fh(sev->fh, &ev);
- }
- v4l2_ctrl_unlock(ctrl);
- return 0;
-}
-
-static void v4l2_ctrl_del_event(struct v4l2_subscribed_event *sev)
-{
- struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
-
- v4l2_ctrl_lock(ctrl);
- list_del(&sev->node);
- v4l2_ctrl_unlock(ctrl);
-}
-
-void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new)
-{
- u32 old_changes = old->u.ctrl.changes;
-
- old->u.ctrl = new->u.ctrl;
- old->u.ctrl.changes |= old_changes;
-}
-EXPORT_SYMBOL(v4l2_ctrl_replace);
-
-void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new)
-{
- new->u.ctrl.changes |= old->u.ctrl.changes;
-}
-EXPORT_SYMBOL(v4l2_ctrl_merge);
-
-const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops = {
- .add = v4l2_ctrl_add_event,
- .del = v4l2_ctrl_del_event,
- .replace = v4l2_ctrl_replace,
- .merge = v4l2_ctrl_merge,
-};
-EXPORT_SYMBOL(v4l2_ctrl_sub_ev_ops);
-
-int v4l2_ctrl_log_status(struct file *file, void *fh)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_fh *vfh = file->private_data;
-
- if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) && vfd->v4l2_dev)
- v4l2_ctrl_handler_log_status(vfh->ctrl_handler,
- vfd->v4l2_dev->name);
- return 0;
-}
-EXPORT_SYMBOL(v4l2_ctrl_log_status);
-
-int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
-{
- if (sub->type == V4L2_EVENT_CTRL)
- return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
- return -EINVAL;
-}
-EXPORT_SYMBOL(v4l2_ctrl_subscribe_event);
-
-unsigned int v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct v4l2_fh *fh = file->private_data;
-
- if (v4l2_event_pending(fh))
- return POLLPRI;
- poll_wait(file, &fh->wait, wait);
- return 0;
-}
-EXPORT_SYMBOL(v4l2_ctrl_poll);
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
deleted file mode 100644
index 07aeafca9ea..00000000000
--- a/drivers/media/video/v4l2-dev.c
+++ /dev/null
@@ -1,1038 +0,0 @@
-/*
- * Video capture interface for Linux version 2
- *
- * A generic video device interface for the LINUX operating system
- * using a set of device structures/vectors for low level operations.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
- * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
- *
- * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com>
- * - Added procfs support
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <asm/uaccess.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-
-#define VIDEO_NUM_DEVICES 256
-#define VIDEO_NAME "video4linux"
-
-/*
- * sysfs stuff
- */
-
-static ssize_t show_index(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vdev = to_video_device(cd);
-
- return sprintf(buf, "%i\n", vdev->index);
-}
-
-static ssize_t show_debug(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vdev = to_video_device(cd);
-
- return sprintf(buf, "%i\n", vdev->debug);
-}
-
-static ssize_t set_debug(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct video_device *vdev = to_video_device(cd);
- int res = 0;
- u16 value;
-
- res = kstrtou16(buf, 0, &value);
- if (res)
- return res;
-
- vdev->debug = value;
- return len;
-}
-
-static ssize_t show_name(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vdev = to_video_device(cd);
-
- return sprintf(buf, "%.*s\n", (int)sizeof(vdev->name), vdev->name);
-}
-
-static struct device_attribute video_device_attrs[] = {
- __ATTR(name, S_IRUGO, show_name, NULL),
- __ATTR(debug, 0644, show_debug, set_debug),
- __ATTR(index, S_IRUGO, show_index, NULL),
- __ATTR_NULL
-};
-
-/*
- * Active devices
- */
-static struct video_device *video_device[VIDEO_NUM_DEVICES];
-static DEFINE_MUTEX(videodev_lock);
-static DECLARE_BITMAP(devnode_nums[VFL_TYPE_MAX], VIDEO_NUM_DEVICES);
-
-/* Device node utility functions */
-
-/* Note: these utility functions all assume that vfl_type is in the range
- [0, VFL_TYPE_MAX-1]. */
-
-#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
-/* Return the bitmap corresponding to vfl_type. */
-static inline unsigned long *devnode_bits(int vfl_type)
-{
- /* Any types not assigned to fixed minor ranges must be mapped to
- one single bitmap for the purposes of finding a free node number
- since all those unassigned types use the same minor range. */
- int idx = (vfl_type > VFL_TYPE_RADIO) ? VFL_TYPE_MAX - 1 : vfl_type;
-
- return devnode_nums[idx];
-}
-#else
-/* Return the bitmap corresponding to vfl_type. */
-static inline unsigned long *devnode_bits(int vfl_type)
-{
- return devnode_nums[vfl_type];
-}
-#endif
-
-/* Mark device node number vdev->num as used */
-static inline void devnode_set(struct video_device *vdev)
-{
- set_bit(vdev->num, devnode_bits(vdev->vfl_type));
-}
-
-/* Mark device node number vdev->num as unused */
-static inline void devnode_clear(struct video_device *vdev)
-{
- clear_bit(vdev->num, devnode_bits(vdev->vfl_type));
-}
-
-/* Try to find a free device node number in the range [from, to> */
-static inline int devnode_find(struct video_device *vdev, int from, int to)
-{
- return find_next_zero_bit(devnode_bits(vdev->vfl_type), to, from);
-}
-
-struct video_device *video_device_alloc(void)
-{
- return kzalloc(sizeof(struct video_device), GFP_KERNEL);
-}
-EXPORT_SYMBOL(video_device_alloc);
-
-void video_device_release(struct video_device *vdev)
-{
- kfree(vdev);
-}
-EXPORT_SYMBOL(video_device_release);
-
-void video_device_release_empty(struct video_device *vdev)
-{
- /* Do nothing */
- /* Only valid when the video_device struct is a static. */
-}
-EXPORT_SYMBOL(video_device_release_empty);
-
-static inline void video_get(struct video_device *vdev)
-{
- get_device(&vdev->dev);
-}
-
-static inline void video_put(struct video_device *vdev)
-{
- put_device(&vdev->dev);
-}
-
-/* Called when the last user of the video device exits. */
-static void v4l2_device_release(struct device *cd)
-{
- struct video_device *vdev = to_video_device(cd);
- struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
-
- mutex_lock(&videodev_lock);
- if (WARN_ON(video_device[vdev->minor] != vdev)) {
- /* should not happen */
- mutex_unlock(&videodev_lock);
- return;
- }
-
- /* Free up this device for reuse */
- video_device[vdev->minor] = NULL;
-
- /* Delete the cdev on this minor as well */
- cdev_del(vdev->cdev);
- /* Just in case some driver tries to access this from
- the release() callback. */
- vdev->cdev = NULL;
-
- /* Mark device node number as free */
- devnode_clear(vdev);
-
- mutex_unlock(&videodev_lock);
-
-#if defined(CONFIG_MEDIA_CONTROLLER)
- if (v4l2_dev && v4l2_dev->mdev &&
- vdev->vfl_type != VFL_TYPE_SUBDEV)
- media_device_unregister_entity(&vdev->entity);
-#endif
-
- /* Do not call v4l2_device_put if there is no release callback set.
- * Drivers that have no v4l2_device release callback might free the
- * v4l2_dev instance in the video_device release callback below, so we
- * must perform this check here.
- *
- * TODO: In the long run all drivers that use v4l2_device should use the
- * v4l2_device release callback. This check will then be unnecessary.
- */
- if (v4l2_dev && v4l2_dev->release == NULL)
- v4l2_dev = NULL;
-
- /* Release video_device and perform other
- cleanups as needed. */
- vdev->release(vdev);
-
- /* Decrease v4l2_device refcount */
- if (v4l2_dev)
- v4l2_device_put(v4l2_dev);
-}
-
-static struct class video_class = {
- .name = VIDEO_NAME,
- .dev_attrs = video_device_attrs,
-};
-
-struct video_device *video_devdata(struct file *file)
-{
- return video_device[iminor(file->f_path.dentry->d_inode)];
-}
-EXPORT_SYMBOL(video_devdata);
-
-
-/* Priority handling */
-
-static inline bool prio_is_valid(enum v4l2_priority prio)
-{
- return prio == V4L2_PRIORITY_BACKGROUND ||
- prio == V4L2_PRIORITY_INTERACTIVE ||
- prio == V4L2_PRIORITY_RECORD;
-}
-
-void v4l2_prio_init(struct v4l2_prio_state *global)
-{
- memset(global, 0, sizeof(*global));
-}
-EXPORT_SYMBOL(v4l2_prio_init);
-
-int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
- enum v4l2_priority new)
-{
- if (!prio_is_valid(new))
- return -EINVAL;
- if (*local == new)
- return 0;
-
- atomic_inc(&global->prios[new]);
- if (prio_is_valid(*local))
- atomic_dec(&global->prios[*local]);
- *local = new;
- return 0;
-}
-EXPORT_SYMBOL(v4l2_prio_change);
-
-void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
-{
- v4l2_prio_change(global, local, V4L2_PRIORITY_DEFAULT);
-}
-EXPORT_SYMBOL(v4l2_prio_open);
-
-void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local)
-{
- if (prio_is_valid(local))
- atomic_dec(&global->prios[local]);
-}
-EXPORT_SYMBOL(v4l2_prio_close);
-
-enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
-{
- if (atomic_read(&global->prios[V4L2_PRIORITY_RECORD]) > 0)
- return V4L2_PRIORITY_RECORD;
- if (atomic_read(&global->prios[V4L2_PRIORITY_INTERACTIVE]) > 0)
- return V4L2_PRIORITY_INTERACTIVE;
- if (atomic_read(&global->prios[V4L2_PRIORITY_BACKGROUND]) > 0)
- return V4L2_PRIORITY_BACKGROUND;
- return V4L2_PRIORITY_UNSET;
-}
-EXPORT_SYMBOL(v4l2_prio_max);
-
-int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local)
-{
- return (local < v4l2_prio_max(global)) ? -EBUSY : 0;
-}
-EXPORT_SYMBOL(v4l2_prio_check);
-
-
-static ssize_t v4l2_read(struct file *filp, char __user *buf,
- size_t sz, loff_t *off)
-{
- struct video_device *vdev = video_devdata(filp);
- int ret = -ENODEV;
-
- if (!vdev->fops->read)
- return -EINVAL;
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) &&
- mutex_lock_interruptible(vdev->lock))
- return -ERESTARTSYS;
- if (video_is_registered(vdev))
- ret = vdev->fops->read(filp, buf, sz, off);
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_unlock(vdev->lock);
- if (vdev->debug)
- printk(KERN_DEBUG "%s: read: %zd (%d)\n",
- video_device_node_name(vdev), sz, ret);
- return ret;
-}
-
-static ssize_t v4l2_write(struct file *filp, const char __user *buf,
- size_t sz, loff_t *off)
-{
- struct video_device *vdev = video_devdata(filp);
- int ret = -ENODEV;
-
- if (!vdev->fops->write)
- return -EINVAL;
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) &&
- mutex_lock_interruptible(vdev->lock))
- return -ERESTARTSYS;
- if (video_is_registered(vdev))
- ret = vdev->fops->write(filp, buf, sz, off);
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_unlock(vdev->lock);
- if (vdev->debug)
- printk(KERN_DEBUG "%s: write: %zd (%d)\n",
- video_device_node_name(vdev), sz, ret);
- return ret;
-}
-
-static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll)
-{
- struct video_device *vdev = video_devdata(filp);
- int ret = POLLERR | POLLHUP;
-
- if (!vdev->fops->poll)
- return DEFAULT_POLLMASK;
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_lock(vdev->lock);
- if (video_is_registered(vdev))
- ret = vdev->fops->poll(filp, poll);
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_unlock(vdev->lock);
- if (vdev->debug)
- printk(KERN_DEBUG "%s: poll: %08x\n",
- video_device_node_name(vdev), ret);
- return ret;
-}
-
-static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- struct video_device *vdev = video_devdata(filp);
- int ret = -ENODEV;
-
- if (vdev->fops->unlocked_ioctl) {
- struct mutex *lock = v4l2_ioctl_get_lock(vdev, cmd);
-
- if (lock && mutex_lock_interruptible(lock))
- return -ERESTARTSYS;
- if (video_is_registered(vdev))
- ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
- if (lock)
- mutex_unlock(lock);
- } else if (vdev->fops->ioctl) {
- /* This code path is a replacement for the BKL. It is a major
- * hack but it will have to do for those drivers that are not
- * yet converted to use unlocked_ioctl.
- *
- * There are two options: if the driver implements struct
- * v4l2_device, then the lock defined there is used to
- * serialize the ioctls. Otherwise the v4l2 core lock defined
- * below is used. This lock is really bad since it serializes
- * completely independent devices.
- *
- * Both variants suffer from the same problem: if the driver
- * sleeps, then it blocks all ioctls since the lock is still
- * held. This is very common for VIDIOC_DQBUF since that
- * normally waits for a frame to arrive. As a result any other
- * ioctl calls will proceed very, very slowly since each call
- * will have to wait for the VIDIOC_QBUF to finish. Things that
- * should take 0.01s may now take 10-20 seconds.
- *
- * The workaround is to *not* take the lock for VIDIOC_DQBUF.
- * This actually works OK for videobuf-based drivers, since
- * videobuf will take its own internal lock.
- */
- static DEFINE_MUTEX(v4l2_ioctl_mutex);
- struct mutex *m = vdev->v4l2_dev ?
- &vdev->v4l2_dev->ioctl_lock : &v4l2_ioctl_mutex;
-
- if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m))
- return -ERESTARTSYS;
- if (video_is_registered(vdev))
- ret = vdev->fops->ioctl(filp, cmd, arg);
- if (cmd != VIDIOC_DQBUF)
- mutex_unlock(m);
- } else
- ret = -ENOTTY;
-
- return ret;
-}
-
-#ifdef CONFIG_MMU
-#define v4l2_get_unmapped_area NULL
-#else
-static unsigned long v4l2_get_unmapped_area(struct file *filp,
- unsigned long addr, unsigned long len, unsigned long pgoff,
- unsigned long flags)
-{
- struct video_device *vdev = video_devdata(filp);
- int ret;
-
- if (!vdev->fops->get_unmapped_area)
- return -ENOSYS;
- if (!video_is_registered(vdev))
- return -ENODEV;
- ret = vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags);
- if (vdev->debug)
- printk(KERN_DEBUG "%s: get_unmapped_area (%d)\n",
- video_device_node_name(vdev), ret);
- return ret;
-}
-#endif
-
-static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
-{
- struct video_device *vdev = video_devdata(filp);
- int ret = -ENODEV;
-
- if (!vdev->fops->mmap)
- return ret;
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) &&
- mutex_lock_interruptible(vdev->lock))
- return -ERESTARTSYS;
- if (video_is_registered(vdev))
- ret = vdev->fops->mmap(filp, vm);
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_unlock(vdev->lock);
- if (vdev->debug)
- printk(KERN_DEBUG "%s: mmap (%d)\n",
- video_device_node_name(vdev), ret);
- return ret;
-}
-
-/* Override for the open function */
-static int v4l2_open(struct inode *inode, struct file *filp)
-{
- struct video_device *vdev;
- int ret = 0;
-
- /* Check if the video device is available */
- mutex_lock(&videodev_lock);
- vdev = video_devdata(filp);
- /* return ENODEV if the video device has already been removed. */
- if (vdev == NULL || !video_is_registered(vdev)) {
- mutex_unlock(&videodev_lock);
- return -ENODEV;
- }
- /* and increase the device refcount */
- video_get(vdev);
- mutex_unlock(&videodev_lock);
- if (vdev->fops->open) {
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) &&
- mutex_lock_interruptible(vdev->lock)) {
- ret = -ERESTARTSYS;
- goto err;
- }
- if (video_is_registered(vdev))
- ret = vdev->fops->open(filp);
- else
- ret = -ENODEV;
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_unlock(vdev->lock);
- }
-
-err:
- if (vdev->debug)
- printk(KERN_DEBUG "%s: open (%d)\n",
- video_device_node_name(vdev), ret);
- /* decrease the refcount in case of an error */
- if (ret)
- video_put(vdev);
- return ret;
-}
-
-/* Override for the release function */
-static int v4l2_release(struct inode *inode, struct file *filp)
-{
- struct video_device *vdev = video_devdata(filp);
- int ret = 0;
-
- if (vdev->fops->release) {
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_lock(vdev->lock);
- vdev->fops->release(filp);
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_unlock(vdev->lock);
- }
- if (vdev->debug)
- printk(KERN_DEBUG "%s: release\n",
- video_device_node_name(vdev));
- /* decrease the refcount unconditionally since the release()
- return value is ignored. */
- video_put(vdev);
- return ret;
-}
-
-static const struct file_operations v4l2_fops = {
- .owner = THIS_MODULE,
- .read = v4l2_read,
- .write = v4l2_write,
- .open = v4l2_open,
- .get_unmapped_area = v4l2_get_unmapped_area,
- .mmap = v4l2_mmap,
- .unlocked_ioctl = v4l2_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = v4l2_compat_ioctl32,
-#endif
- .release = v4l2_release,
- .poll = v4l2_poll,
- .llseek = no_llseek,
-};
-
-/**
- * get_index - assign stream index number based on parent device
- * @vdev: video_device to assign index number to, vdev->parent should be assigned
- *
- * Note that when this is called the new device has not yet been registered
- * in the video_device array, but it was able to obtain a minor number.
- *
- * This means that we can always obtain a free stream index number since
- * the worst case scenario is that there are VIDEO_NUM_DEVICES - 1 slots in
- * use of the video_device array.
- *
- * Returns a free index number.
- */
-static int get_index(struct video_device *vdev)
-{
- /* This can be static since this function is called with the global
- videodev_lock held. */
- static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES);
- int i;
-
- /* Some drivers do not set the parent. In that case always return 0. */
- if (vdev->parent == NULL)
- return 0;
-
- bitmap_zero(used, VIDEO_NUM_DEVICES);
-
- for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
- if (video_device[i] != NULL &&
- video_device[i]->parent == vdev->parent) {
- set_bit(video_device[i]->index, used);
- }
- }
-
- return find_first_zero_bit(used, VIDEO_NUM_DEVICES);
-}
-
-#define SET_VALID_IOCTL(ops, cmd, op) \
- if (ops->op) \
- set_bit(_IOC_NR(cmd), valid_ioctls)
-
-/* This determines which ioctls are actually implemented in the driver.
- It's a one-time thing which simplifies video_ioctl2 as it can just do
- a bit test.
-
- Note that drivers can override this by setting bits to 1 in
- vdev->valid_ioctls. If an ioctl is marked as 1 when this function is
- called, then that ioctl will actually be marked as unimplemented.
-
- It does that by first setting up the local valid_ioctls bitmap, and
- at the end do a:
-
- vdev->valid_ioctls = valid_ioctls & ~(vdev->valid_ioctls)
- */
-static void determine_valid_ioctls(struct video_device *vdev)
-{
- DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);
- const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
-
- bitmap_zero(valid_ioctls, BASE_VIDIOC_PRIVATE);
-
- SET_VALID_IOCTL(ops, VIDIOC_QUERYCAP, vidioc_querycap);
- if (ops->vidioc_g_priority ||
- test_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags))
- set_bit(_IOC_NR(VIDIOC_G_PRIORITY), valid_ioctls);
- if (ops->vidioc_s_priority ||
- test_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags))
- set_bit(_IOC_NR(VIDIOC_S_PRIORITY), valid_ioctls);
- if (ops->vidioc_enum_fmt_vid_cap ||
- ops->vidioc_enum_fmt_vid_out ||
- ops->vidioc_enum_fmt_vid_cap_mplane ||
- ops->vidioc_enum_fmt_vid_out_mplane ||
- ops->vidioc_enum_fmt_vid_overlay ||
- ops->vidioc_enum_fmt_type_private)
- set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
- if (ops->vidioc_g_fmt_vid_cap ||
- ops->vidioc_g_fmt_vid_out ||
- ops->vidioc_g_fmt_vid_cap_mplane ||
- ops->vidioc_g_fmt_vid_out_mplane ||
- ops->vidioc_g_fmt_vid_overlay ||
- ops->vidioc_g_fmt_vbi_cap ||
- ops->vidioc_g_fmt_vid_out_overlay ||
- ops->vidioc_g_fmt_vbi_out ||
- ops->vidioc_g_fmt_sliced_vbi_cap ||
- ops->vidioc_g_fmt_sliced_vbi_out ||
- ops->vidioc_g_fmt_type_private)
- set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
- if (ops->vidioc_s_fmt_vid_cap ||
- ops->vidioc_s_fmt_vid_out ||
- ops->vidioc_s_fmt_vid_cap_mplane ||
- ops->vidioc_s_fmt_vid_out_mplane ||
- ops->vidioc_s_fmt_vid_overlay ||
- ops->vidioc_s_fmt_vbi_cap ||
- ops->vidioc_s_fmt_vid_out_overlay ||
- ops->vidioc_s_fmt_vbi_out ||
- ops->vidioc_s_fmt_sliced_vbi_cap ||
- ops->vidioc_s_fmt_sliced_vbi_out ||
- ops->vidioc_s_fmt_type_private)
- set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
- if (ops->vidioc_try_fmt_vid_cap ||
- ops->vidioc_try_fmt_vid_out ||
- ops->vidioc_try_fmt_vid_cap_mplane ||
- ops->vidioc_try_fmt_vid_out_mplane ||
- ops->vidioc_try_fmt_vid_overlay ||
- ops->vidioc_try_fmt_vbi_cap ||
- ops->vidioc_try_fmt_vid_out_overlay ||
- ops->vidioc_try_fmt_vbi_out ||
- ops->vidioc_try_fmt_sliced_vbi_cap ||
- ops->vidioc_try_fmt_sliced_vbi_out ||
- ops->vidioc_try_fmt_type_private)
- set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
- SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
- SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
- SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
- SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf);
- SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay);
- SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf);
- SET_VALID_IOCTL(ops, VIDIOC_S_FBUF, vidioc_s_fbuf);
- SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon);
- SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
- if (vdev->tvnorms)
- set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
- if (ops->vidioc_g_std || vdev->current_norm)
- set_bit(_IOC_NR(VIDIOC_G_STD), valid_ioctls);
- SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std);
- SET_VALID_IOCTL(ops, VIDIOC_QUERYSTD, vidioc_querystd);
- SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input);
- SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input);
- SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input);
- SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output);
- SET_VALID_IOCTL(ops, VIDIOC_G_OUTPUT, vidioc_g_output);
- SET_VALID_IOCTL(ops, VIDIOC_S_OUTPUT, vidioc_s_output);
- /* Note: the control handler can also be passed through the filehandle,
- and that can't be tested here. If the bit for these control ioctls
- is set, then the ioctl is valid. But if it is 0, then it can still
- be valid if the filehandle passed the control handler. */
- if (vdev->ctrl_handler || ops->vidioc_queryctrl)
- set_bit(_IOC_NR(VIDIOC_QUERYCTRL), valid_ioctls);
- if (vdev->ctrl_handler || ops->vidioc_g_ctrl || ops->vidioc_g_ext_ctrls)
- set_bit(_IOC_NR(VIDIOC_G_CTRL), valid_ioctls);
- if (vdev->ctrl_handler || ops->vidioc_s_ctrl || ops->vidioc_s_ext_ctrls)
- set_bit(_IOC_NR(VIDIOC_S_CTRL), valid_ioctls);
- if (vdev->ctrl_handler || ops->vidioc_g_ext_ctrls)
- set_bit(_IOC_NR(VIDIOC_G_EXT_CTRLS), valid_ioctls);
- if (vdev->ctrl_handler || ops->vidioc_s_ext_ctrls)
- set_bit(_IOC_NR(VIDIOC_S_EXT_CTRLS), valid_ioctls);
- if (vdev->ctrl_handler || ops->vidioc_try_ext_ctrls)
- set_bit(_IOC_NR(VIDIOC_TRY_EXT_CTRLS), valid_ioctls);
- if (vdev->ctrl_handler || ops->vidioc_querymenu)
- set_bit(_IOC_NR(VIDIOC_QUERYMENU), valid_ioctls);
- SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDIO, vidioc_enumaudio);
- SET_VALID_IOCTL(ops, VIDIOC_G_AUDIO, vidioc_g_audio);
- SET_VALID_IOCTL(ops, VIDIOC_S_AUDIO, vidioc_s_audio);
- SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDOUT, vidioc_enumaudout);
- SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout);
- SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout);
- SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator);
- SET_VALID_IOCTL(ops, VIDIOC_S_MODULATOR, vidioc_s_modulator);
- if (ops->vidioc_g_crop || ops->vidioc_g_selection)
- set_bit(_IOC_NR(VIDIOC_G_CROP), valid_ioctls);
- if (ops->vidioc_s_crop || ops->vidioc_s_selection)
- set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls);
- SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection);
- SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection);
- if (ops->vidioc_cropcap || ops->vidioc_g_selection)
- set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls);
- SET_VALID_IOCTL(ops, VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp);
- SET_VALID_IOCTL(ops, VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp);
- SET_VALID_IOCTL(ops, VIDIOC_G_ENC_INDEX, vidioc_g_enc_index);
- SET_VALID_IOCTL(ops, VIDIOC_ENCODER_CMD, vidioc_encoder_cmd);
- SET_VALID_IOCTL(ops, VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd);
- SET_VALID_IOCTL(ops, VIDIOC_DECODER_CMD, vidioc_decoder_cmd);
- SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd);
- if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER &&
- (ops->vidioc_g_std || vdev->tvnorms)))
- set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls);
- SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm);
- SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner);
- SET_VALID_IOCTL(ops, VIDIOC_S_TUNER, vidioc_s_tuner);
- SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency);
- SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency);
- SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap);
- SET_VALID_IOCTL(ops, VIDIOC_LOG_STATUS, vidioc_log_status);
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- SET_VALID_IOCTL(ops, VIDIOC_DBG_G_REGISTER, vidioc_g_register);
- SET_VALID_IOCTL(ops, VIDIOC_DBG_S_REGISTER, vidioc_s_register);
-#endif
- SET_VALID_IOCTL(ops, VIDIOC_DBG_G_CHIP_IDENT, vidioc_g_chip_ident);
- SET_VALID_IOCTL(ops, VIDIOC_S_HW_FREQ_SEEK, vidioc_s_hw_freq_seek);
- SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes);
- SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals);
- SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_PRESETS, vidioc_enum_dv_presets);
- SET_VALID_IOCTL(ops, VIDIOC_S_DV_PRESET, vidioc_s_dv_preset);
- SET_VALID_IOCTL(ops, VIDIOC_G_DV_PRESET, vidioc_g_dv_preset);
- SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_PRESET, vidioc_query_dv_preset);
- SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings);
- SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings);
- SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings);
- SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings);
- SET_VALID_IOCTL(ops, VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap);
- /* yes, really vidioc_subscribe_event */
- SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event);
- SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event);
- SET_VALID_IOCTL(ops, VIDIOC_UNSUBSCRIBE_EVENT, vidioc_unsubscribe_event);
- SET_VALID_IOCTL(ops, VIDIOC_CREATE_BUFS, vidioc_create_bufs);
- SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf);
- if (ops->vidioc_enum_freq_bands || ops->vidioc_g_tuner || ops->vidioc_g_modulator)
- set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls);
- bitmap_andnot(vdev->valid_ioctls, valid_ioctls, vdev->valid_ioctls,
- BASE_VIDIOC_PRIVATE);
-}
-
-/**
- * __video_register_device - register video4linux devices
- * @vdev: video device structure we want to register
- * @type: type of device to register
- * @nr: which device node number (0 == /dev/video0, 1 == /dev/video1, ...
- * -1 == first free)
- * @warn_if_nr_in_use: warn if the desired device node number
- * was already in use and another number was chosen instead.
- * @owner: module that owns the video device node
- *
- * The registration code assigns minor numbers and device node numbers
- * based on the requested type and registers the new device node with
- * the kernel.
- *
- * This function assumes that struct video_device was zeroed when it
- * was allocated and does not contain any stale date.
- *
- * An error is returned if no free minor or device node number could be
- * found, or if the registration of the device node failed.
- *
- * Zero is returned on success.
- *
- * Valid types are
- *
- * %VFL_TYPE_GRABBER - A frame grabber
- *
- * %VFL_TYPE_VBI - Vertical blank data (undecoded)
- *
- * %VFL_TYPE_RADIO - A radio card
- *
- * %VFL_TYPE_SUBDEV - A subdevice
- */
-int __video_register_device(struct video_device *vdev, int type, int nr,
- int warn_if_nr_in_use, struct module *owner)
-{
- int i = 0;
- int ret;
- int minor_offset = 0;
- int minor_cnt = VIDEO_NUM_DEVICES;
- const char *name_base;
-
- /* A minor value of -1 marks this video device as never
- having been registered */
- vdev->minor = -1;
-
- /* the release callback MUST be present */
- if (WARN_ON(!vdev->release))
- return -EINVAL;
-
- /* v4l2_fh support */
- spin_lock_init(&vdev->fh_lock);
- INIT_LIST_HEAD(&vdev->fh_list);
-
- /* Part 1: check device type */
- switch (type) {
- case VFL_TYPE_GRABBER:
- name_base = "video";
- break;
- case VFL_TYPE_VBI:
- name_base = "vbi";
- break;
- case VFL_TYPE_RADIO:
- name_base = "radio";
- break;
- case VFL_TYPE_SUBDEV:
- name_base = "v4l-subdev";
- break;
- default:
- printk(KERN_ERR "%s called with unknown type: %d\n",
- __func__, type);
- return -EINVAL;
- }
-
- vdev->vfl_type = type;
- vdev->cdev = NULL;
- if (vdev->v4l2_dev) {
- if (vdev->v4l2_dev->dev)
- vdev->parent = vdev->v4l2_dev->dev;
- if (vdev->ctrl_handler == NULL)
- vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
- /* If the prio state pointer is NULL, then use the v4l2_device
- prio state. */
- if (vdev->prio == NULL)
- vdev->prio = &vdev->v4l2_dev->prio;
- }
-
- /* Part 2: find a free minor, device node number and device index. */
-#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
- /* Keep the ranges for the first four types for historical
- * reasons.
- * Newer devices (not yet in place) should use the range
- * of 128-191 and just pick the first free minor there
- * (new style). */
- switch (type) {
- case VFL_TYPE_GRABBER:
- minor_offset = 0;
- minor_cnt = 64;
- break;
- case VFL_TYPE_RADIO:
- minor_offset = 64;
- minor_cnt = 64;
- break;
- case VFL_TYPE_VBI:
- minor_offset = 224;
- minor_cnt = 32;
- break;
- default:
- minor_offset = 128;
- minor_cnt = 64;
- break;
- }
-#endif
-
- /* Pick a device node number */
- mutex_lock(&videodev_lock);
- nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt);
- if (nr == minor_cnt)
- nr = devnode_find(vdev, 0, minor_cnt);
- if (nr == minor_cnt) {
- printk(KERN_ERR "could not get a free device node number\n");
- mutex_unlock(&videodev_lock);
- return -ENFILE;
- }
-#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
- /* 1-on-1 mapping of device node number to minor number */
- i = nr;
-#else
- /* The device node number and minor numbers are independent, so
- we just find the first free minor number. */
- for (i = 0; i < VIDEO_NUM_DEVICES; i++)
- if (video_device[i] == NULL)
- break;
- if (i == VIDEO_NUM_DEVICES) {
- mutex_unlock(&videodev_lock);
- printk(KERN_ERR "could not get a free minor\n");
- return -ENFILE;
- }
-#endif
- vdev->minor = i + minor_offset;
- vdev->num = nr;
- devnode_set(vdev);
-
- /* Should not happen since we thought this minor was free */
- WARN_ON(video_device[vdev->minor] != NULL);
- vdev->index = get_index(vdev);
- mutex_unlock(&videodev_lock);
- /* if no lock was passed, then make sure the LOCK_ALL_FOPS bit is
- clear and warn if it wasn't. */
- if (vdev->lock == NULL)
- WARN_ON(test_and_clear_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags));
-
- if (vdev->ioctl_ops)
- determine_valid_ioctls(vdev);
-
- /* Part 3: Initialize the character device */
- vdev->cdev = cdev_alloc();
- if (vdev->cdev == NULL) {
- ret = -ENOMEM;
- goto cleanup;
- }
- vdev->cdev->ops = &v4l2_fops;
- vdev->cdev->owner = owner;
- ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1);
- if (ret < 0) {
- printk(KERN_ERR "%s: cdev_add failed\n", __func__);
- kfree(vdev->cdev);
- vdev->cdev = NULL;
- goto cleanup;
- }
-
- /* Part 4: register the device with sysfs */
- vdev->dev.class = &video_class;
- vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
- if (vdev->parent)
- vdev->dev.parent = vdev->parent;
- dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
- ret = device_register(&vdev->dev);
- if (ret < 0) {
- printk(KERN_ERR "%s: device_register failed\n", __func__);
- goto cleanup;
- }
- /* Register the release callback that will be called when the last
- reference to the device goes away. */
- vdev->dev.release = v4l2_device_release;
-
- if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
- printk(KERN_WARNING "%s: requested %s%d, got %s\n", __func__,
- name_base, nr, video_device_node_name(vdev));
-
- /* Increase v4l2_device refcount */
- if (vdev->v4l2_dev)
- v4l2_device_get(vdev->v4l2_dev);
-
-#if defined(CONFIG_MEDIA_CONTROLLER)
- /* Part 5: Register the entity. */
- if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
- vdev->vfl_type != VFL_TYPE_SUBDEV) {
- vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
- vdev->entity.name = vdev->name;
- vdev->entity.info.v4l.major = VIDEO_MAJOR;
- vdev->entity.info.v4l.minor = vdev->minor;
- ret = media_device_register_entity(vdev->v4l2_dev->mdev,
- &vdev->entity);
- if (ret < 0)
- printk(KERN_WARNING
- "%s: media_device_register_entity failed\n",
- __func__);
- }
-#endif
- /* Part 6: Activate this minor. The char device can now be used. */
- set_bit(V4L2_FL_REGISTERED, &vdev->flags);
- mutex_lock(&videodev_lock);
- video_device[vdev->minor] = vdev;
- mutex_unlock(&videodev_lock);
-
- return 0;
-
-cleanup:
- mutex_lock(&videodev_lock);
- if (vdev->cdev)
- cdev_del(vdev->cdev);
- devnode_clear(vdev);
- mutex_unlock(&videodev_lock);
- /* Mark this video device as never having been registered. */
- vdev->minor = -1;
- return ret;
-}
-EXPORT_SYMBOL(__video_register_device);
-
-/**
- * video_unregister_device - unregister a video4linux device
- * @vdev: the device to unregister
- *
- * This unregisters the passed device. Future open calls will
- * be met with errors.
- */
-void video_unregister_device(struct video_device *vdev)
-{
- /* Check if vdev was ever registered at all */
- if (!vdev || !video_is_registered(vdev))
- return;
-
- mutex_lock(&videodev_lock);
- /* This must be in a critical section to prevent a race with v4l2_open.
- * Once this bit has been cleared video_get may never be called again.
- */
- clear_bit(V4L2_FL_REGISTERED, &vdev->flags);
- mutex_unlock(&videodev_lock);
- device_unregister(&vdev->dev);
-}
-EXPORT_SYMBOL(video_unregister_device);
-
-/*
- * Initialise video for linux
- */
-static int __init videodev_init(void)
-{
- dev_t dev = MKDEV(VIDEO_MAJOR, 0);
- int ret;
-
- printk(KERN_INFO "Linux video capture interface: v2.00\n");
- ret = register_chrdev_region(dev, VIDEO_NUM_DEVICES, VIDEO_NAME);
- if (ret < 0) {
- printk(KERN_WARNING "videodev: unable to get major %d\n",
- VIDEO_MAJOR);
- return ret;
- }
-
- ret = class_register(&video_class);
- if (ret < 0) {
- unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
- printk(KERN_WARNING "video_dev: class_register failed\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static void __exit videodev_exit(void)
-{
- dev_t dev = MKDEV(VIDEO_MAJOR, 0);
-
- class_unregister(&video_class);
- unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
-}
-
-subsys_initcall(videodev_init);
-module_exit(videodev_exit)
-
-MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR);
-
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
deleted file mode 100644
index 1f203b85a63..00000000000
--- a/drivers/media/video/v4l2-device.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- V4L2 device support.
-
- Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#if defined(CONFIG_SPI)
-#include <linux/spi/spi.h>
-#endif
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-
-int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
-{
- if (v4l2_dev == NULL)
- return -EINVAL;
-
- INIT_LIST_HEAD(&v4l2_dev->subdevs);
- spin_lock_init(&v4l2_dev->lock);
- mutex_init(&v4l2_dev->ioctl_lock);
- v4l2_prio_init(&v4l2_dev->prio);
- kref_init(&v4l2_dev->ref);
- get_device(dev);
- v4l2_dev->dev = dev;
- if (dev == NULL) {
- /* If dev == NULL, then name must be filled in by the caller */
- WARN_ON(!v4l2_dev->name[0]);
- return 0;
- }
-
- /* Set name to driver name + device name if it is empty. */
- if (!v4l2_dev->name[0])
- snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
- dev->driver->name, dev_name(dev));
- if (!dev_get_drvdata(dev))
- dev_set_drvdata(dev, v4l2_dev);
- return 0;
-}
-EXPORT_SYMBOL_GPL(v4l2_device_register);
-
-static void v4l2_device_release(struct kref *ref)
-{
- struct v4l2_device *v4l2_dev =
- container_of(ref, struct v4l2_device, ref);
-
- if (v4l2_dev->release)
- v4l2_dev->release(v4l2_dev);
-}
-
-int v4l2_device_put(struct v4l2_device *v4l2_dev)
-{
- return kref_put(&v4l2_dev->ref, v4l2_device_release);
-}
-EXPORT_SYMBOL_GPL(v4l2_device_put);
-
-int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
- atomic_t *instance)
-{
- int num = atomic_inc_return(instance) - 1;
- int len = strlen(basename);
-
- if (basename[len - 1] >= '0' && basename[len - 1] <= '9')
- snprintf(v4l2_dev->name, sizeof(v4l2_dev->name),
- "%s-%d", basename, num);
- else
- snprintf(v4l2_dev->name, sizeof(v4l2_dev->name),
- "%s%d", basename, num);
- return num;
-}
-EXPORT_SYMBOL_GPL(v4l2_device_set_name);
-
-void v4l2_device_disconnect(struct v4l2_device *v4l2_dev)
-{
- if (v4l2_dev->dev == NULL)
- return;
-
- if (dev_get_drvdata(v4l2_dev->dev) == v4l2_dev)
- dev_set_drvdata(v4l2_dev->dev, NULL);
- put_device(v4l2_dev->dev);
- v4l2_dev->dev = NULL;
-}
-EXPORT_SYMBOL_GPL(v4l2_device_disconnect);
-
-void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
-{
- struct v4l2_subdev *sd, *next;
-
- if (v4l2_dev == NULL)
- return;
- v4l2_device_disconnect(v4l2_dev);
-
- /* Unregister subdevs */
- list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) {
- v4l2_device_unregister_subdev(sd);
-#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
- if (sd->flags & V4L2_SUBDEV_FL_IS_I2C) {
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- /* We need to unregister the i2c client explicitly.
- We cannot rely on i2c_del_adapter to always
- unregister clients for us, since if the i2c bus
- is a platform bus, then it is never deleted. */
- if (client)
- i2c_unregister_device(client);
- continue;
- }
-#endif
-#if defined(CONFIG_SPI)
- if (sd->flags & V4L2_SUBDEV_FL_IS_SPI) {
- struct spi_device *spi = v4l2_get_subdevdata(sd);
-
- if (spi)
- spi_unregister_device(spi);
- continue;
- }
-#endif
- }
-}
-EXPORT_SYMBOL_GPL(v4l2_device_unregister);
-
-int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
- struct v4l2_subdev *sd)
-{
-#if defined(CONFIG_MEDIA_CONTROLLER)
- struct media_entity *entity = &sd->entity;
-#endif
- int err;
-
- /* Check for valid input */
- if (v4l2_dev == NULL || sd == NULL || !sd->name[0])
- return -EINVAL;
-
- /* Warn if we apparently re-register a subdev */
- WARN_ON(sd->v4l2_dev != NULL);
-
- if (!try_module_get(sd->owner))
- return -ENODEV;
-
- sd->v4l2_dev = v4l2_dev;
- if (sd->internal_ops && sd->internal_ops->registered) {
- err = sd->internal_ops->registered(sd);
- if (err) {
- module_put(sd->owner);
- return err;
- }
- }
-
- /* This just returns 0 if either of the two args is NULL */
- err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler);
- if (err) {
- if (sd->internal_ops && sd->internal_ops->unregistered)
- sd->internal_ops->unregistered(sd);
- module_put(sd->owner);
- return err;
- }
-
-#if defined(CONFIG_MEDIA_CONTROLLER)
- /* Register the entity. */
- if (v4l2_dev->mdev) {
- err = media_device_register_entity(v4l2_dev->mdev, entity);
- if (err < 0) {
- if (sd->internal_ops && sd->internal_ops->unregistered)
- sd->internal_ops->unregistered(sd);
- module_put(sd->owner);
- return err;
- }
- }
-#endif
-
- spin_lock(&v4l2_dev->lock);
- list_add_tail(&sd->list, &v4l2_dev->subdevs);
- spin_unlock(&v4l2_dev->lock);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
-
-static void v4l2_device_release_subdev_node(struct video_device *vdev)
-{
- struct v4l2_subdev *sd = video_get_drvdata(vdev);
- sd->devnode = NULL;
- kfree(vdev);
-}
-
-int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
-{
- struct video_device *vdev;
- struct v4l2_subdev *sd;
- int err;
-
- /* Register a device node for every subdev marked with the
- * V4L2_SUBDEV_FL_HAS_DEVNODE flag.
- */
- list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
- if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
- continue;
-
- vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
- if (!vdev) {
- err = -ENOMEM;
- goto clean_up;
- }
-
- video_set_drvdata(vdev, sd);
- strlcpy(vdev->name, sd->name, sizeof(vdev->name));
- vdev->v4l2_dev = v4l2_dev;
- vdev->fops = &v4l2_subdev_fops;
- vdev->release = v4l2_device_release_subdev_node;
- vdev->ctrl_handler = sd->ctrl_handler;
- err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
- sd->owner);
- if (err < 0) {
- kfree(vdev);
- goto clean_up;
- }
-#if defined(CONFIG_MEDIA_CONTROLLER)
- sd->entity.info.v4l.major = VIDEO_MAJOR;
- sd->entity.info.v4l.minor = vdev->minor;
-#endif
- sd->devnode = vdev;
- }
- return 0;
-
-clean_up:
- list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
- if (!sd->devnode)
- break;
- video_unregister_device(sd->devnode);
- }
-
- return err;
-}
-EXPORT_SYMBOL_GPL(v4l2_device_register_subdev_nodes);
-
-void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
-{
- struct v4l2_device *v4l2_dev;
-
- /* return if it isn't registered */
- if (sd == NULL || sd->v4l2_dev == NULL)
- return;
-
- v4l2_dev = sd->v4l2_dev;
-
- spin_lock(&v4l2_dev->lock);
- list_del(&sd->list);
- spin_unlock(&v4l2_dev->lock);
-
- if (sd->internal_ops && sd->internal_ops->unregistered)
- sd->internal_ops->unregistered(sd);
- sd->v4l2_dev = NULL;
-
-#if defined(CONFIG_MEDIA_CONTROLLER)
- if (v4l2_dev->mdev)
- media_device_unregister_entity(&sd->entity);
-#endif
- video_unregister_device(sd->devnode);
- module_put(sd->owner);
-}
-EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);
diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c
deleted file mode 100644
index ef2a33c9404..00000000000
--- a/drivers/media/video/v4l2-event.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * v4l2-event.c
- *
- * V4L2 events.
- *
- * Copyright (C) 2009--2010 Nokia Corporation.
- *
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <media/v4l2-dev.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-
-static unsigned sev_pos(const struct v4l2_subscribed_event *sev, unsigned idx)
-{
- idx += sev->first;
- return idx >= sev->elems ? idx - sev->elems : idx;
-}
-
-static int __v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event)
-{
- struct v4l2_kevent *kev;
- unsigned long flags;
-
- spin_lock_irqsave(&fh->vdev->fh_lock, flags);
-
- if (list_empty(&fh->available)) {
- spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
- return -ENOENT;
- }
-
- WARN_ON(fh->navailable == 0);
-
- kev = list_first_entry(&fh->available, struct v4l2_kevent, list);
- list_del(&kev->list);
- fh->navailable--;
-
- kev->event.pending = fh->navailable;
- *event = kev->event;
- kev->sev->first = sev_pos(kev->sev, 1);
- kev->sev->in_use--;
-
- spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
-
- return 0;
-}
-
-int v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event,
- int nonblocking)
-{
- int ret;
-
- if (nonblocking)
- return __v4l2_event_dequeue(fh, event);
-
- /* Release the vdev lock while waiting */
- if (fh->vdev->lock)
- mutex_unlock(fh->vdev->lock);
-
- do {
- ret = wait_event_interruptible(fh->wait,
- fh->navailable != 0);
- if (ret < 0)
- break;
-
- ret = __v4l2_event_dequeue(fh, event);
- } while (ret == -ENOENT);
-
- if (fh->vdev->lock)
- mutex_lock(fh->vdev->lock);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(v4l2_event_dequeue);
-
-/* Caller must hold fh->vdev->fh_lock! */
-static struct v4l2_subscribed_event *v4l2_event_subscribed(
- struct v4l2_fh *fh, u32 type, u32 id)
-{
- struct v4l2_subscribed_event *sev;
-
- assert_spin_locked(&fh->vdev->fh_lock);
-
- list_for_each_entry(sev, &fh->subscribed, list)
- if (sev->type == type && sev->id == id)
- return sev;
-
- return NULL;
-}
-
-static void __v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev,
- const struct timespec *ts)
-{
- struct v4l2_subscribed_event *sev;
- struct v4l2_kevent *kev;
- bool copy_payload = true;
-
- /* Are we subscribed? */
- sev = v4l2_event_subscribed(fh, ev->type, ev->id);
- if (sev == NULL)
- return;
-
- /*
- * If the event has been added to the fh->subscribed list, but its
- * add op has not completed yet elems will be 0, treat this as
- * not being subscribed.
- */
- if (!sev->elems)
- return;
-
- /* Increase event sequence number on fh. */
- fh->sequence++;
-
- /* Do we have any free events? */
- if (sev->in_use == sev->elems) {
- /* no, remove the oldest one */
- kev = sev->events + sev_pos(sev, 0);
- list_del(&kev->list);
- sev->in_use--;
- sev->first = sev_pos(sev, 1);
- fh->navailable--;
- if (sev->elems == 1) {
- if (sev->ops && sev->ops->replace) {
- sev->ops->replace(&kev->event, ev);
- copy_payload = false;
- }
- } else if (sev->ops && sev->ops->merge) {
- struct v4l2_kevent *second_oldest =
- sev->events + sev_pos(sev, 0);
- sev->ops->merge(&kev->event, &second_oldest->event);
- }
- }
-
- /* Take one and fill it. */
- kev = sev->events + sev_pos(sev, sev->in_use);
- kev->event.type = ev->type;
- if (copy_payload)
- kev->event.u = ev->u;
- kev->event.id = ev->id;
- kev->event.timestamp = *ts;
- kev->event.sequence = fh->sequence;
- sev->in_use++;
- list_add_tail(&kev->list, &fh->available);
-
- fh->navailable++;
-
- wake_up_all(&fh->wait);
-}
-
-void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev)
-{
- struct v4l2_fh *fh;
- unsigned long flags;
- struct timespec timestamp;
-
- ktime_get_ts(&timestamp);
-
- spin_lock_irqsave(&vdev->fh_lock, flags);
-
- list_for_each_entry(fh, &vdev->fh_list, list)
- __v4l2_event_queue_fh(fh, ev, &timestamp);
-
- spin_unlock_irqrestore(&vdev->fh_lock, flags);
-}
-EXPORT_SYMBOL_GPL(v4l2_event_queue);
-
-void v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev)
-{
- unsigned long flags;
- struct timespec timestamp;
-
- ktime_get_ts(&timestamp);
-
- spin_lock_irqsave(&fh->vdev->fh_lock, flags);
- __v4l2_event_queue_fh(fh, ev, &timestamp);
- spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
-}
-EXPORT_SYMBOL_GPL(v4l2_event_queue_fh);
-
-int v4l2_event_pending(struct v4l2_fh *fh)
-{
- return fh->navailable;
-}
-EXPORT_SYMBOL_GPL(v4l2_event_pending);
-
-int v4l2_event_subscribe(struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub, unsigned elems,
- const struct v4l2_subscribed_event_ops *ops)
-{
- struct v4l2_subscribed_event *sev, *found_ev;
- unsigned long flags;
- unsigned i;
-
- if (sub->type == V4L2_EVENT_ALL)
- return -EINVAL;
-
- if (elems < 1)
- elems = 1;
-
- sev = kzalloc(sizeof(*sev) + sizeof(struct v4l2_kevent) * elems, GFP_KERNEL);
- if (!sev)
- return -ENOMEM;
- for (i = 0; i < elems; i++)
- sev->events[i].sev = sev;
- sev->type = sub->type;
- sev->id = sub->id;
- sev->flags = sub->flags;
- sev->fh = fh;
- sev->ops = ops;
-
- spin_lock_irqsave(&fh->vdev->fh_lock, flags);
- found_ev = v4l2_event_subscribed(fh, sub->type, sub->id);
- if (!found_ev)
- list_add(&sev->list, &fh->subscribed);
- spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
-
- if (found_ev) {
- kfree(sev);
- return 0; /* Already listening */
- }
-
- if (sev->ops && sev->ops->add) {
- int ret = sev->ops->add(sev, elems);
- if (ret) {
- sev->ops = NULL;
- v4l2_event_unsubscribe(fh, sub);
- return ret;
- }
- }
-
- /* Mark as ready for use */
- sev->elems = elems;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(v4l2_event_subscribe);
-
-void v4l2_event_unsubscribe_all(struct v4l2_fh *fh)
-{
- struct v4l2_event_subscription sub;
- struct v4l2_subscribed_event *sev;
- unsigned long flags;
-
- do {
- sev = NULL;
-
- spin_lock_irqsave(&fh->vdev->fh_lock, flags);
- if (!list_empty(&fh->subscribed)) {
- sev = list_first_entry(&fh->subscribed,
- struct v4l2_subscribed_event, list);
- sub.type = sev->type;
- sub.id = sev->id;
- }
- spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
- if (sev)
- v4l2_event_unsubscribe(fh, &sub);
- } while (sev);
-}
-EXPORT_SYMBOL_GPL(v4l2_event_unsubscribe_all);
-
-int v4l2_event_unsubscribe(struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
-{
- struct v4l2_subscribed_event *sev;
- unsigned long flags;
- int i;
-
- if (sub->type == V4L2_EVENT_ALL) {
- v4l2_event_unsubscribe_all(fh);
- return 0;
- }
-
- spin_lock_irqsave(&fh->vdev->fh_lock, flags);
-
- sev = v4l2_event_subscribed(fh, sub->type, sub->id);
- if (sev != NULL) {
- /* Remove any pending events for this subscription */
- for (i = 0; i < sev->in_use; i++) {
- list_del(&sev->events[sev_pos(sev, i)].list);
- fh->navailable--;
- }
- list_del(&sev->list);
- }
-
- spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
-
- if (sev && sev->ops && sev->ops->del)
- sev->ops->del(sev);
-
- kfree(sev);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(v4l2_event_unsubscribe);
diff --git a/drivers/media/video/v4l2-fh.c b/drivers/media/video/v4l2-fh.c
deleted file mode 100644
index 9e3fc040ea2..00000000000
--- a/drivers/media/video/v4l2-fh.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * v4l2-fh.c
- *
- * V4L2 file handles.
- *
- * Copyright (C) 2009--2010 Nokia Corporation.
- *
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/bitops.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-ioctl.h>
-
-void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
-{
- fh->vdev = vdev;
- /* Inherit from video_device. May be overridden by the driver. */
- fh->ctrl_handler = vdev->ctrl_handler;
- INIT_LIST_HEAD(&fh->list);
- set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags);
- fh->prio = V4L2_PRIORITY_UNSET;
- init_waitqueue_head(&fh->wait);
- INIT_LIST_HEAD(&fh->available);
- INIT_LIST_HEAD(&fh->subscribed);
- fh->sequence = -1;
-}
-EXPORT_SYMBOL_GPL(v4l2_fh_init);
-
-void v4l2_fh_add(struct v4l2_fh *fh)
-{
- unsigned long flags;
-
- if (test_bit(V4L2_FL_USE_FH_PRIO, &fh->vdev->flags))
- v4l2_prio_open(fh->vdev->prio, &fh->prio);
- spin_lock_irqsave(&fh->vdev->fh_lock, flags);
- list_add(&fh->list, &fh->vdev->fh_list);
- spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
-}
-EXPORT_SYMBOL_GPL(v4l2_fh_add);
-
-int v4l2_fh_open(struct file *filp)
-{
- struct video_device *vdev = video_devdata(filp);
- struct v4l2_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
-
- filp->private_data = fh;
- if (fh == NULL)
- return -ENOMEM;
- v4l2_fh_init(fh, vdev);
- v4l2_fh_add(fh);
- return 0;
-}
-EXPORT_SYMBOL_GPL(v4l2_fh_open);
-
-void v4l2_fh_del(struct v4l2_fh *fh)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&fh->vdev->fh_lock, flags);
- list_del_init(&fh->list);
- spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
- if (test_bit(V4L2_FL_USE_FH_PRIO, &fh->vdev->flags))
- v4l2_prio_close(fh->vdev->prio, fh->prio);
-}
-EXPORT_SYMBOL_GPL(v4l2_fh_del);
-
-void v4l2_fh_exit(struct v4l2_fh *fh)
-{
- if (fh->vdev == NULL)
- return;
- v4l2_event_unsubscribe_all(fh);
- fh->vdev = NULL;
-}
-EXPORT_SYMBOL_GPL(v4l2_fh_exit);
-
-int v4l2_fh_release(struct file *filp)
-{
- struct v4l2_fh *fh = filp->private_data;
-
- if (fh) {
- v4l2_fh_del(fh);
- v4l2_fh_exit(fh);
- kfree(fh);
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(v4l2_fh_release);
-
-int v4l2_fh_is_singular(struct v4l2_fh *fh)
-{
- unsigned long flags;
- int is_singular;
-
- if (fh == NULL || fh->vdev == NULL)
- return 0;
- spin_lock_irqsave(&fh->vdev->fh_lock, flags);
- is_singular = list_is_singular(&fh->list);
- spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
- return is_singular;
-}
-EXPORT_SYMBOL_GPL(v4l2_fh_is_singular);
diff --git a/drivers/media/video/v4l2-int-device.c b/drivers/media/video/v4l2-int-device.c
deleted file mode 100644
index f4473494af7..00000000000
--- a/drivers/media/video/v4l2-int-device.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * drivers/media/video/v4l2-int-device.c
- *
- * V4L2 internal ioctl interface.
- *
- * Copyright (C) 2007 Nokia Corporation.
- *
- * Contact: Sakari Ailus <sakari.ailus@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/sort.h>
-#include <linux/string.h>
-#include <linux/module.h>
-
-#include <media/v4l2-int-device.h>
-
-static DEFINE_MUTEX(mutex);
-static LIST_HEAD(int_list);
-
-void v4l2_int_device_try_attach_all(void)
-{
- struct v4l2_int_device *m, *s;
-
- list_for_each_entry(m, &int_list, head) {
- if (m->type != v4l2_int_type_master)
- continue;
-
- list_for_each_entry(s, &int_list, head) {
- if (s->type != v4l2_int_type_slave)
- continue;
-
- /* Slave is connected? */
- if (s->u.slave->master)
- continue;
-
- /* Slave wants to attach to master? */
- if (s->u.slave->attach_to[0] != 0
- && strncmp(m->name, s->u.slave->attach_to,
- V4L2NAMESIZE))
- continue;
-
- if (!try_module_get(m->module))
- continue;
-
- s->u.slave->master = m;
- if (m->u.master->attach(s)) {
- s->u.slave->master = NULL;
- module_put(m->module);
- continue;
- }
- }
- }
-}
-EXPORT_SYMBOL_GPL(v4l2_int_device_try_attach_all);
-
-static int ioctl_sort_cmp(const void *a, const void *b)
-{
- const struct v4l2_int_ioctl_desc *d1 = a, *d2 = b;
-
- if (d1->num > d2->num)
- return 1;
-
- if (d1->num < d2->num)
- return -1;
-
- return 0;
-}
-
-int v4l2_int_device_register(struct v4l2_int_device *d)
-{
- if (d->type == v4l2_int_type_slave)
- sort(d->u.slave->ioctls, d->u.slave->num_ioctls,
- sizeof(struct v4l2_int_ioctl_desc),
- &ioctl_sort_cmp, NULL);
- mutex_lock(&mutex);
- list_add(&d->head, &int_list);
- v4l2_int_device_try_attach_all();
- mutex_unlock(&mutex);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(v4l2_int_device_register);
-
-void v4l2_int_device_unregister(struct v4l2_int_device *d)
-{
- mutex_lock(&mutex);
- list_del(&d->head);
- if (d->type == v4l2_int_type_slave
- && d->u.slave->master != NULL) {
- d->u.slave->master->u.master->detach(d);
- module_put(d->u.slave->master->module);
- d->u.slave->master = NULL;
- }
- mutex_unlock(&mutex);
-}
-EXPORT_SYMBOL_GPL(v4l2_int_device_unregister);
-
-/* Adapted from search_extable in extable.c. */
-static v4l2_int_ioctl_func *find_ioctl(struct v4l2_int_slave *slave, int cmd,
- v4l2_int_ioctl_func *no_such_ioctl)
-{
- const struct v4l2_int_ioctl_desc *first = slave->ioctls;
- const struct v4l2_int_ioctl_desc *last =
- first + slave->num_ioctls - 1;
-
- while (first <= last) {
- const struct v4l2_int_ioctl_desc *mid;
-
- mid = (last - first) / 2 + first;
-
- if (mid->num < cmd)
- first = mid + 1;
- else if (mid->num > cmd)
- last = mid - 1;
- else
- return mid->func;
- }
-
- return no_such_ioctl;
-}
-
-static int no_such_ioctl_0(struct v4l2_int_device *d)
-{
- return -ENOIOCTLCMD;
-}
-
-int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd)
-{
- return ((v4l2_int_ioctl_func_0 *)
- find_ioctl(d->u.slave, cmd,
- (v4l2_int_ioctl_func *)no_such_ioctl_0))(d);
-}
-EXPORT_SYMBOL_GPL(v4l2_int_ioctl_0);
-
-static int no_such_ioctl_1(struct v4l2_int_device *d, void *arg)
-{
- return -ENOIOCTLCMD;
-}
-
-int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg)
-{
- return ((v4l2_int_ioctl_func_1 *)
- find_ioctl(d->u.slave, cmd,
- (v4l2_int_ioctl_func *)no_such_ioctl_1))(d, arg);
-}
-EXPORT_SYMBOL_GPL(v4l2_int_ioctl_1);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
deleted file mode 100644
index 6bc47fc82fe..00000000000
--- a/drivers/media/video/v4l2-ioctl.c
+++ /dev/null
@@ -1,2330 +0,0 @@
-/*
- * Video capture interface for Linux version 2
- *
- * A generic framework to process V4L2 ioctl commands.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
- * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/version.h>
-
-#include <linux/videodev2.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/videobuf2-core.h>
-
-/* Zero out the end of the struct pointed to by p. Everything after, but
- * not including, the specified field is cleared. */
-#define CLEAR_AFTER_FIELD(p, field) \
- memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
- 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
-
-struct std_descr {
- v4l2_std_id std;
- const char *descr;
-};
-
-static const struct std_descr standards[] = {
- { V4L2_STD_NTSC, "NTSC" },
- { V4L2_STD_NTSC_M, "NTSC-M" },
- { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" },
- { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" },
- { V4L2_STD_NTSC_443, "NTSC-443" },
- { V4L2_STD_PAL, "PAL" },
- { V4L2_STD_PAL_BG, "PAL-BG" },
- { V4L2_STD_PAL_B, "PAL-B" },
- { V4L2_STD_PAL_B1, "PAL-B1" },
- { V4L2_STD_PAL_G, "PAL-G" },
- { V4L2_STD_PAL_H, "PAL-H" },
- { V4L2_STD_PAL_I, "PAL-I" },
- { V4L2_STD_PAL_DK, "PAL-DK" },
- { V4L2_STD_PAL_D, "PAL-D" },
- { V4L2_STD_PAL_D1, "PAL-D1" },
- { V4L2_STD_PAL_K, "PAL-K" },
- { V4L2_STD_PAL_M, "PAL-M" },
- { V4L2_STD_PAL_N, "PAL-N" },
- { V4L2_STD_PAL_Nc, "PAL-Nc" },
- { V4L2_STD_PAL_60, "PAL-60" },
- { V4L2_STD_SECAM, "SECAM" },
- { V4L2_STD_SECAM_B, "SECAM-B" },
- { V4L2_STD_SECAM_G, "SECAM-G" },
- { V4L2_STD_SECAM_H, "SECAM-H" },
- { V4L2_STD_SECAM_DK, "SECAM-DK" },
- { V4L2_STD_SECAM_D, "SECAM-D" },
- { V4L2_STD_SECAM_K, "SECAM-K" },
- { V4L2_STD_SECAM_K1, "SECAM-K1" },
- { V4L2_STD_SECAM_L, "SECAM-L" },
- { V4L2_STD_SECAM_LC, "SECAM-Lc" },
- { 0, "Unknown" }
-};
-
-/* video4linux standard ID conversion to standard name
- */
-const char *v4l2_norm_to_name(v4l2_std_id id)
-{
- u32 myid = id;
- int i;
-
- /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
- 64 bit comparations. So, on that architecture, with some gcc
- variants, compilation fails. Currently, the max value is 30bit wide.
- */
- BUG_ON(myid != id);
-
- for (i = 0; standards[i].std; i++)
- if (myid == standards[i].std)
- break;
- return standards[i].descr;
-}
-EXPORT_SYMBOL(v4l2_norm_to_name);
-
-/* Returns frame period for the given standard */
-void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
-{
- if (id & V4L2_STD_525_60) {
- frameperiod->numerator = 1001;
- frameperiod->denominator = 30000;
- } else {
- frameperiod->numerator = 1;
- frameperiod->denominator = 25;
- }
-}
-EXPORT_SYMBOL(v4l2_video_std_frame_period);
-
-/* Fill in the fields of a v4l2_standard structure according to the
- 'id' and 'transmission' parameters. Returns negative on error. */
-int v4l2_video_std_construct(struct v4l2_standard *vs,
- int id, const char *name)
-{
- vs->id = id;
- v4l2_video_std_frame_period(id, &vs->frameperiod);
- vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
- strlcpy(vs->name, name, sizeof(vs->name));
- return 0;
-}
-EXPORT_SYMBOL(v4l2_video_std_construct);
-
-/* ----------------------------------------------------------------- */
-/* some arrays for pretty-printing debug messages of enum types */
-
-const char *v4l2_field_names[] = {
- [V4L2_FIELD_ANY] = "any",
- [V4L2_FIELD_NONE] = "none",
- [V4L2_FIELD_TOP] = "top",
- [V4L2_FIELD_BOTTOM] = "bottom",
- [V4L2_FIELD_INTERLACED] = "interlaced",
- [V4L2_FIELD_SEQ_TB] = "seq-tb",
- [V4L2_FIELD_SEQ_BT] = "seq-bt",
- [V4L2_FIELD_ALTERNATE] = "alternate",
- [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
- [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
-};
-EXPORT_SYMBOL(v4l2_field_names);
-
-const char *v4l2_type_names[] = {
- [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap",
- [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay",
- [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out",
- [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
- [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
- [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
- [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
- [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
- [V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
- [V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
-};
-EXPORT_SYMBOL(v4l2_type_names);
-
-static const char *v4l2_memory_names[] = {
- [V4L2_MEMORY_MMAP] = "mmap",
- [V4L2_MEMORY_USERPTR] = "userptr",
- [V4L2_MEMORY_OVERLAY] = "overlay",
-};
-
-#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
- arr[a] : "unknown")
-
-/* ------------------------------------------------------------------ */
-/* debug help functions */
-
-static void v4l_print_querycap(const void *arg, bool write_only)
-{
- const struct v4l2_capability *p = arg;
-
- pr_cont("driver=%s, card=%s, bus=%s, version=0x%08x, "
- "capabilities=0x%08x, device_caps=0x%08x\n",
- p->driver, p->card, p->bus_info,
- p->version, p->capabilities, p->device_caps);
-}
-
-static void v4l_print_enuminput(const void *arg, bool write_only)
-{
- const struct v4l2_input *p = arg;
-
- pr_cont("index=%u, name=%s, type=%u, audioset=0x%x, tuner=%u, "
- "std=0x%08Lx, status=0x%x, capabilities=0x%x\n",
- p->index, p->name, p->type, p->audioset, p->tuner,
- (unsigned long long)p->std, p->status, p->capabilities);
-}
-
-static void v4l_print_enumoutput(const void *arg, bool write_only)
-{
- const struct v4l2_output *p = arg;
-
- pr_cont("index=%u, name=%s, type=%u, audioset=0x%x, "
- "modulator=%u, std=0x%08Lx, capabilities=0x%x\n",
- p->index, p->name, p->type, p->audioset, p->modulator,
- (unsigned long long)p->std, p->capabilities);
-}
-
-static void v4l_print_audio(const void *arg, bool write_only)
-{
- const struct v4l2_audio *p = arg;
-
- if (write_only)
- pr_cont("index=%u, mode=0x%x\n", p->index, p->mode);
- else
- pr_cont("index=%u, name=%s, capability=0x%x, mode=0x%x\n",
- p->index, p->name, p->capability, p->mode);
-}
-
-static void v4l_print_audioout(const void *arg, bool write_only)
-{
- const struct v4l2_audioout *p = arg;
-
- if (write_only)
- pr_cont("index=%u\n", p->index);
- else
- pr_cont("index=%u, name=%s, capability=0x%x, mode=0x%x\n",
- p->index, p->name, p->capability, p->mode);
-}
-
-static void v4l_print_fmtdesc(const void *arg, bool write_only)
-{
- const struct v4l2_fmtdesc *p = arg;
-
- pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%c%c%c%c, description='%s'\n",
- p->index, prt_names(p->type, v4l2_type_names),
- p->flags, (p->pixelformat & 0xff),
- (p->pixelformat >> 8) & 0xff,
- (p->pixelformat >> 16) & 0xff,
- (p->pixelformat >> 24) & 0xff,
- p->description);
-}
-
-static void v4l_print_format(const void *arg, bool write_only)
-{
- const struct v4l2_format *p = arg;
- const struct v4l2_pix_format *pix;
- const struct v4l2_pix_format_mplane *mp;
- const struct v4l2_vbi_format *vbi;
- const struct v4l2_sliced_vbi_format *sliced;
- const struct v4l2_window *win;
- const struct v4l2_clip *clip;
- unsigned i;
-
- pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
- switch (p->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- pix = &p->fmt.pix;
- pr_cont(", width=%u, height=%u, "
- "pixelformat=%c%c%c%c, field=%s, "
- "bytesperline=%u sizeimage=%u, colorspace=%d\n",
- pix->width, pix->height,
- (pix->pixelformat & 0xff),
- (pix->pixelformat >> 8) & 0xff,
- (pix->pixelformat >> 16) & 0xff,
- (pix->pixelformat >> 24) & 0xff,
- prt_names(pix->field, v4l2_field_names),
- pix->bytesperline, pix->sizeimage,
- pix->colorspace);
- break;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- mp = &p->fmt.pix_mp;
- pr_cont(", width=%u, height=%u, "
- "format=%c%c%c%c, field=%s, "
- "colorspace=%d, num_planes=%u\n",
- mp->width, mp->height,
- (mp->pixelformat & 0xff),
- (mp->pixelformat >> 8) & 0xff,
- (mp->pixelformat >> 16) & 0xff,
- (mp->pixelformat >> 24) & 0xff,
- prt_names(mp->field, v4l2_field_names),
- mp->colorspace, mp->num_planes);
- for (i = 0; i < mp->num_planes; i++)
- printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
- mp->plane_fmt[i].bytesperline,
- mp->plane_fmt[i].sizeimage);
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- win = &p->fmt.win;
- pr_cont(", wxh=%dx%d, x,y=%d,%d, field=%s, "
- "chromakey=0x%08x, bitmap=%p, "
- "global_alpha=0x%02x\n",
- win->w.width, win->w.height,
- win->w.left, win->w.top,
- prt_names(win->field, v4l2_field_names),
- win->chromakey, win->bitmap, win->global_alpha);
- clip = win->clips;
- for (i = 0; i < win->clipcount; i++) {
- printk(KERN_DEBUG "clip %u: wxh=%dx%d, x,y=%d,%d\n",
- i, clip->c.width, clip->c.height,
- clip->c.left, clip->c.top);
- clip = clip->next;
- }
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- vbi = &p->fmt.vbi;
- pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, "
- "sample_format=%c%c%c%c, start=%u,%u, count=%u,%u\n",
- vbi->sampling_rate, vbi->offset,
- vbi->samples_per_line,
- (vbi->sample_format & 0xff),
- (vbi->sample_format >> 8) & 0xff,
- (vbi->sample_format >> 16) & 0xff,
- (vbi->sample_format >> 24) & 0xff,
- vbi->start[0], vbi->start[1],
- vbi->count[0], vbi->count[1]);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- sliced = &p->fmt.sliced;
- pr_cont(", service_set=0x%08x, io_size=%d\n",
- sliced->service_set, sliced->io_size);
- for (i = 0; i < 24; i++)
- printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
- sliced->service_lines[0][i],
- sliced->service_lines[1][i]);
- break;
- case V4L2_BUF_TYPE_PRIVATE:
- pr_cont("\n");
- break;
- }
-}
-
-static void v4l_print_framebuffer(const void *arg, bool write_only)
-{
- const struct v4l2_framebuffer *p = arg;
-
- pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, "
- "height=%u, pixelformat=%c%c%c%c, "
- "bytesperline=%u sizeimage=%u, colorspace=%d\n",
- p->capability, p->flags, p->base,
- p->fmt.width, p->fmt.height,
- (p->fmt.pixelformat & 0xff),
- (p->fmt.pixelformat >> 8) & 0xff,
- (p->fmt.pixelformat >> 16) & 0xff,
- (p->fmt.pixelformat >> 24) & 0xff,
- p->fmt.bytesperline, p->fmt.sizeimage,
- p->fmt.colorspace);
-}
-
-static void v4l_print_buftype(const void *arg, bool write_only)
-{
- pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
-}
-
-static void v4l_print_modulator(const void *arg, bool write_only)
-{
- const struct v4l2_modulator *p = arg;
-
- if (write_only)
- pr_cont("index=%u, txsubchans=0x%x", p->index, p->txsubchans);
- else
- pr_cont("index=%u, name=%s, capability=0x%x, "
- "rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
- p->index, p->name, p->capability,
- p->rangelow, p->rangehigh, p->txsubchans);
-}
-
-static void v4l_print_tuner(const void *arg, bool write_only)
-{
- const struct v4l2_tuner *p = arg;
-
- if (write_only)
- pr_cont("index=%u, audmode=%u\n", p->index, p->audmode);
- else
- pr_cont("index=%u, name=%s, type=%u, capability=0x%x, "
- "rangelow=%u, rangehigh=%u, signal=%u, afc=%d, "
- "rxsubchans=0x%x, audmode=%u\n",
- p->index, p->name, p->type,
- p->capability, p->rangelow,
- p->rangehigh, p->signal, p->afc,
- p->rxsubchans, p->audmode);
-}
-
-static void v4l_print_frequency(const void *arg, bool write_only)
-{
- const struct v4l2_frequency *p = arg;
-
- pr_cont("tuner=%u, type=%u, frequency=%u\n",
- p->tuner, p->type, p->frequency);
-}
-
-static void v4l_print_standard(const void *arg, bool write_only)
-{
- const struct v4l2_standard *p = arg;
-
- pr_cont("index=%u, id=0x%Lx, name=%s, fps=%u/%u, "
- "framelines=%u\n", p->index,
- (unsigned long long)p->id, p->name,
- p->frameperiod.numerator,
- p->frameperiod.denominator,
- p->framelines);
-}
-
-static void v4l_print_std(const void *arg, bool write_only)
-{
- pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg);
-}
-
-static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
-{
- const struct v4l2_hw_freq_seek *p = arg;
-
- pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, "
- "rangelow=%u, rangehigh=%u\n",
- p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
- p->rangelow, p->rangehigh);
-}
-
-static void v4l_print_requestbuffers(const void *arg, bool write_only)
-{
- const struct v4l2_requestbuffers *p = arg;
-
- pr_cont("count=%d, type=%s, memory=%s\n",
- p->count,
- prt_names(p->type, v4l2_type_names),
- prt_names(p->memory, v4l2_memory_names));
-}
-
-static void v4l_print_buffer(const void *arg, bool write_only)
-{
- const struct v4l2_buffer *p = arg;
- const struct v4l2_timecode *tc = &p->timecode;
- const struct v4l2_plane *plane;
- int i;
-
- pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, "
- "flags=0x%08x, field=%s, sequence=%d, memory=%s",
- p->timestamp.tv_sec / 3600,
- (int)(p->timestamp.tv_sec / 60) % 60,
- (int)(p->timestamp.tv_sec % 60),
- (long)p->timestamp.tv_usec,
- p->index,
- prt_names(p->type, v4l2_type_names),
- p->flags, prt_names(p->field, v4l2_field_names),
- p->sequence, prt_names(p->memory, v4l2_memory_names));
-
- if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
- pr_cont("\n");
- for (i = 0; i < p->length; ++i) {
- plane = &p->m.planes[i];
- printk(KERN_DEBUG
- "plane %d: bytesused=%d, data_offset=0x%08x "
- "offset/userptr=0x%lx, length=%d\n",
- i, plane->bytesused, plane->data_offset,
- plane->m.userptr, plane->length);
- }
- } else {
- pr_cont("bytesused=%d, offset/userptr=0x%lx, length=%d\n",
- p->bytesused, p->m.userptr, p->length);
- }
-
- printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, "
- "flags=0x%08x, frames=%d, userbits=0x%08x\n",
- tc->hours, tc->minutes, tc->seconds,
- tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
-}
-
-static void v4l_print_create_buffers(const void *arg, bool write_only)
-{
- const struct v4l2_create_buffers *p = arg;
-
- pr_cont("index=%d, count=%d, memory=%s, ",
- p->index, p->count,
- prt_names(p->memory, v4l2_memory_names));
- v4l_print_format(&p->format, write_only);
-}
-
-static void v4l_print_streamparm(const void *arg, bool write_only)
-{
- const struct v4l2_streamparm *p = arg;
-
- pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
-
- if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- const struct v4l2_captureparm *c = &p->parm.capture;
-
- pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, "
- "extendedmode=%d, readbuffers=%d\n",
- c->capability, c->capturemode,
- c->timeperframe.numerator, c->timeperframe.denominator,
- c->extendedmode, c->readbuffers);
- } else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
- p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- const struct v4l2_outputparm *c = &p->parm.output;
-
- pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, "
- "extendedmode=%d, writebuffers=%d\n",
- c->capability, c->outputmode,
- c->timeperframe.numerator, c->timeperframe.denominator,
- c->extendedmode, c->writebuffers);
- }
-}
-
-static void v4l_print_queryctrl(const void *arg, bool write_only)
-{
- const struct v4l2_queryctrl *p = arg;
-
- pr_cont("id=0x%x, type=%d, name=%s, min/max=%d/%d, "
- "step=%d, default=%d, flags=0x%08x\n",
- p->id, p->type, p->name,
- p->minimum, p->maximum,
- p->step, p->default_value, p->flags);
-}
-
-static void v4l_print_querymenu(const void *arg, bool write_only)
-{
- const struct v4l2_querymenu *p = arg;
-
- pr_cont("id=0x%x, index=%d\n", p->id, p->index);
-}
-
-static void v4l_print_control(const void *arg, bool write_only)
-{
- const struct v4l2_control *p = arg;
-
- pr_cont("id=0x%x, value=%d\n", p->id, p->value);
-}
-
-static void v4l_print_ext_controls(const void *arg, bool write_only)
-{
- const struct v4l2_ext_controls *p = arg;
- int i;
-
- pr_cont("class=0x%x, count=%d, error_idx=%d",
- p->ctrl_class, p->count, p->error_idx);
- for (i = 0; i < p->count; i++) {
- if (p->controls[i].size)
- pr_cont(", id/val=0x%x/0x%x",
- p->controls[i].id, p->controls[i].value);
- else
- pr_cont(", id/size=0x%x/%u",
- p->controls[i].id, p->controls[i].size);
- }
- pr_cont("\n");
-}
-
-static void v4l_print_cropcap(const void *arg, bool write_only)
-{
- const struct v4l2_cropcap *p = arg;
-
- pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, "
- "defrect wxh=%dx%d, x,y=%d,%d\n, "
- "pixelaspect %d/%d\n",
- prt_names(p->type, v4l2_type_names),
- p->bounds.width, p->bounds.height,
- p->bounds.left, p->bounds.top,
- p->defrect.width, p->defrect.height,
- p->defrect.left, p->defrect.top,
- p->pixelaspect.numerator, p->pixelaspect.denominator);
-}
-
-static void v4l_print_crop(const void *arg, bool write_only)
-{
- const struct v4l2_crop *p = arg;
-
- pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n",
- prt_names(p->type, v4l2_type_names),
- p->c.width, p->c.height,
- p->c.left, p->c.top);
-}
-
-static void v4l_print_selection(const void *arg, bool write_only)
-{
- const struct v4l2_selection *p = arg;
-
- pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n",
- prt_names(p->type, v4l2_type_names),
- p->target, p->flags,
- p->r.width, p->r.height, p->r.left, p->r.top);
-}
-
-static void v4l_print_jpegcompression(const void *arg, bool write_only)
-{
- const struct v4l2_jpegcompression *p = arg;
-
- pr_cont("quality=%d, APPn=%d, APP_len=%d, "
- "COM_len=%d, jpeg_markers=0x%x\n",
- p->quality, p->APPn, p->APP_len,
- p->COM_len, p->jpeg_markers);
-}
-
-static void v4l_print_enc_idx(const void *arg, bool write_only)
-{
- const struct v4l2_enc_idx *p = arg;
-
- pr_cont("entries=%d, entries_cap=%d\n",
- p->entries, p->entries_cap);
-}
-
-static void v4l_print_encoder_cmd(const void *arg, bool write_only)
-{
- const struct v4l2_encoder_cmd *p = arg;
-
- pr_cont("cmd=%d, flags=0x%x\n",
- p->cmd, p->flags);
-}
-
-static void v4l_print_decoder_cmd(const void *arg, bool write_only)
-{
- const struct v4l2_decoder_cmd *p = arg;
-
- pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags);
-
- if (p->cmd == V4L2_DEC_CMD_START)
- pr_info("speed=%d, format=%u\n",
- p->start.speed, p->start.format);
- else if (p->cmd == V4L2_DEC_CMD_STOP)
- pr_info("pts=%llu\n", p->stop.pts);
-}
-
-static void v4l_print_dbg_chip_ident(const void *arg, bool write_only)
-{
- const struct v4l2_dbg_chip_ident *p = arg;
-
- pr_cont("type=%u, ", p->match.type);
- if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
- pr_cont("name=%s, ", p->match.name);
- else
- pr_cont("addr=%u, ", p->match.addr);
- pr_cont("chip_ident=%u, revision=0x%x\n",
- p->ident, p->revision);
-}
-
-static void v4l_print_dbg_register(const void *arg, bool write_only)
-{
- const struct v4l2_dbg_register *p = arg;
-
- pr_cont("type=%u, ", p->match.type);
- if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
- pr_cont("name=%s, ", p->match.name);
- else
- pr_cont("addr=%u, ", p->match.addr);
- pr_cont("reg=0x%llx, val=0x%llx\n",
- p->reg, p->val);
-}
-
-static void v4l_print_dv_enum_presets(const void *arg, bool write_only)
-{
- const struct v4l2_dv_enum_preset *p = arg;
-
- pr_cont("index=%u, preset=%u, name=%s, width=%u, height=%u\n",
- p->index, p->preset, p->name, p->width, p->height);
-}
-
-static void v4l_print_dv_preset(const void *arg, bool write_only)
-{
- const struct v4l2_dv_preset *p = arg;
-
- pr_cont("preset=%u\n", p->preset);
-}
-
-static void v4l_print_dv_timings(const void *arg, bool write_only)
-{
- const struct v4l2_dv_timings *p = arg;
-
- switch (p->type) {
- case V4L2_DV_BT_656_1120:
- pr_cont("type=bt-656/1120, interlaced=%u, "
- "pixelclock=%llu, "
- "width=%u, height=%u, polarities=0x%x, "
- "hfrontporch=%u, hsync=%u, "
- "hbackporch=%u, vfrontporch=%u, "
- "vsync=%u, vbackporch=%u, "
- "il_vfrontporch=%u, il_vsync=%u, "
- "il_vbackporch=%u, standards=0x%x, flags=0x%x\n",
- p->bt.interlaced, p->bt.pixelclock,
- p->bt.width, p->bt.height,
- p->bt.polarities, p->bt.hfrontporch,
- p->bt.hsync, p->bt.hbackporch,
- p->bt.vfrontporch, p->bt.vsync,
- p->bt.vbackporch, p->bt.il_vfrontporch,
- p->bt.il_vsync, p->bt.il_vbackporch,
- p->bt.standards, p->bt.flags);
- break;
- default:
- pr_cont("type=%d\n", p->type);
- break;
- }
-}
-
-static void v4l_print_enum_dv_timings(const void *arg, bool write_only)
-{
- const struct v4l2_enum_dv_timings *p = arg;
-
- pr_cont("index=%u, ", p->index);
- v4l_print_dv_timings(&p->timings, write_only);
-}
-
-static void v4l_print_dv_timings_cap(const void *arg, bool write_only)
-{
- const struct v4l2_dv_timings_cap *p = arg;
-
- switch (p->type) {
- case V4L2_DV_BT_656_1120:
- pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, "
- "pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n",
- p->bt.min_width, p->bt.max_width,
- p->bt.min_height, p->bt.max_height,
- p->bt.min_pixelclock, p->bt.max_pixelclock,
- p->bt.standards, p->bt.capabilities);
- break;
- default:
- pr_cont("type=%u\n", p->type);
- break;
- }
-}
-
-static void v4l_print_frmsizeenum(const void *arg, bool write_only)
-{
- const struct v4l2_frmsizeenum *p = arg;
-
- pr_cont("index=%u, pixelformat=%c%c%c%c, type=%u",
- p->index,
- (p->pixel_format & 0xff),
- (p->pixel_format >> 8) & 0xff,
- (p->pixel_format >> 16) & 0xff,
- (p->pixel_format >> 24) & 0xff,
- p->type);
- switch (p->type) {
- case V4L2_FRMSIZE_TYPE_DISCRETE:
- pr_cont(" wxh=%ux%u\n",
- p->discrete.width, p->discrete.height);
- break;
- case V4L2_FRMSIZE_TYPE_STEPWISE:
- pr_cont(" min=%ux%u, max=%ux%u, step=%ux%u\n",
- p->stepwise.min_width, p->stepwise.min_height,
- p->stepwise.step_width, p->stepwise.step_height,
- p->stepwise.max_width, p->stepwise.max_height);
- break;
- case V4L2_FRMSIZE_TYPE_CONTINUOUS:
- /* fall through */
- default:
- pr_cont("\n");
- break;
- }
-}
-
-static void v4l_print_frmivalenum(const void *arg, bool write_only)
-{
- const struct v4l2_frmivalenum *p = arg;
-
- pr_cont("index=%u, pixelformat=%c%c%c%c, wxh=%ux%u, type=%u",
- p->index,
- (p->pixel_format & 0xff),
- (p->pixel_format >> 8) & 0xff,
- (p->pixel_format >> 16) & 0xff,
- (p->pixel_format >> 24) & 0xff,
- p->width, p->height, p->type);
- switch (p->type) {
- case V4L2_FRMIVAL_TYPE_DISCRETE:
- pr_cont(" fps=%d/%d\n",
- p->discrete.numerator,
- p->discrete.denominator);
- break;
- case V4L2_FRMIVAL_TYPE_STEPWISE:
- pr_cont(" min=%d/%d, max=%d/%d, step=%d/%d\n",
- p->stepwise.min.numerator,
- p->stepwise.min.denominator,
- p->stepwise.max.numerator,
- p->stepwise.max.denominator,
- p->stepwise.step.numerator,
- p->stepwise.step.denominator);
- break;
- case V4L2_FRMIVAL_TYPE_CONTINUOUS:
- /* fall through */
- default:
- pr_cont("\n");
- break;
- }
-}
-
-static void v4l_print_event(const void *arg, bool write_only)
-{
- const struct v4l2_event *p = arg;
- const struct v4l2_event_ctrl *c;
-
- pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, "
- "timestamp=%lu.%9.9lu\n",
- p->type, p->pending, p->sequence, p->id,
- p->timestamp.tv_sec, p->timestamp.tv_nsec);
- switch (p->type) {
- case V4L2_EVENT_VSYNC:
- printk(KERN_DEBUG "field=%s\n",
- prt_names(p->u.vsync.field, v4l2_field_names));
- break;
- case V4L2_EVENT_CTRL:
- c = &p->u.ctrl;
- printk(KERN_DEBUG "changes=0x%x, type=%u, ",
- c->changes, c->type);
- if (c->type == V4L2_CTRL_TYPE_INTEGER64)
- pr_cont("value64=%lld, ", c->value64);
- else
- pr_cont("value=%d, ", c->value);
- pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d,"
- " default_value=%d\n",
- c->flags, c->minimum, c->maximum,
- c->step, c->default_value);
- break;
- case V4L2_EVENT_FRAME_SYNC:
- pr_cont("frame_sequence=%u\n",
- p->u.frame_sync.frame_sequence);
- break;
- }
-}
-
-static void v4l_print_event_subscription(const void *arg, bool write_only)
-{
- const struct v4l2_event_subscription *p = arg;
-
- pr_cont("type=0x%x, id=0x%x, flags=0x%x\n",
- p->type, p->id, p->flags);
-}
-
-static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only)
-{
- const struct v4l2_sliced_vbi_cap *p = arg;
- int i;
-
- pr_cont("type=%s, service_set=0x%08x\n",
- prt_names(p->type, v4l2_type_names), p->service_set);
- for (i = 0; i < 24; i++)
- printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i,
- p->service_lines[0][i],
- p->service_lines[1][i]);
-}
-
-static void v4l_print_freq_band(const void *arg, bool write_only)
-{
- const struct v4l2_frequency_band *p = arg;
-
- pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, "
- "rangelow=%u, rangehigh=%u, modulation=0x%x\n",
- p->tuner, p->type, p->index,
- p->capability, p->rangelow,
- p->rangehigh, p->modulation);
-}
-
-static void v4l_print_u32(const void *arg, bool write_only)
-{
- pr_cont("value=%u\n", *(const u32 *)arg);
-}
-
-static void v4l_print_newline(const void *arg, bool write_only)
-{
- pr_cont("\n");
-}
-
-static void v4l_print_default(const void *arg, bool write_only)
-{
- pr_cont("driver-specific ioctl\n");
-}
-
-static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
-{
- __u32 i;
-
- /* zero the reserved fields */
- c->reserved[0] = c->reserved[1] = 0;
- for (i = 0; i < c->count; i++)
- c->controls[i].reserved2[0] = 0;
-
- /* V4L2_CID_PRIVATE_BASE cannot be used as control class
- when using extended controls.
- Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
- is it allowed for backwards compatibility.
- */
- if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
- return 0;
- /* Check that all controls are from the same control class. */
- for (i = 0; i < c->count; i++) {
- if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
- c->error_idx = i;
- return 0;
- }
- }
- return 1;
-}
-
-static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
-{
- if (ops == NULL)
- return -EINVAL;
-
- switch (type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (ops->vidioc_g_fmt_vid_cap ||
- ops->vidioc_g_fmt_vid_cap_mplane)
- return 0;
- break;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (ops->vidioc_g_fmt_vid_cap_mplane)
- return 0;
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (ops->vidioc_g_fmt_vid_overlay)
- return 0;
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (ops->vidioc_g_fmt_vid_out ||
- ops->vidioc_g_fmt_vid_out_mplane)
- return 0;
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (ops->vidioc_g_fmt_vid_out_mplane)
- return 0;
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (ops->vidioc_g_fmt_vid_out_overlay)
- return 0;
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (ops->vidioc_g_fmt_vbi_cap)
- return 0;
- break;
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (ops->vidioc_g_fmt_vbi_out)
- return 0;
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (ops->vidioc_g_fmt_sliced_vbi_cap)
- return 0;
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (ops->vidioc_g_fmt_sliced_vbi_out)
- return 0;
- break;
- case V4L2_BUF_TYPE_PRIVATE:
- if (ops->vidioc_g_fmt_type_private)
- return 0;
- break;
- }
- return -EINVAL;
-}
-
-static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_capability *cap = (struct v4l2_capability *)arg;
-
- cap->version = LINUX_VERSION_CODE;
- return ops->vidioc_querycap(file, fh, cap);
-}
-
-static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
-}
-
-static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
-}
-
-static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd;
- u32 *p = arg;
-
- if (ops->vidioc_g_priority)
- return ops->vidioc_g_priority(file, fh, arg);
- vfd = video_devdata(file);
- *p = v4l2_prio_max(&vfd->v4l2_dev->prio);
- return 0;
-}
-
-static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd;
- struct v4l2_fh *vfh;
- u32 *p = arg;
-
- if (ops->vidioc_s_priority)
- return ops->vidioc_s_priority(file, fh, *p);
- vfd = video_devdata(file);
- vfh = file->private_data;
- return v4l2_prio_change(&vfd->v4l2_dev->prio, &vfh->prio, *p);
-}
-
-static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_input *p = arg;
-
- /*
- * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS &
- * CAP_STD here based on ioctl handler provided by the
- * driver. If the driver doesn't support these
- * for a specific input, it must override these flags.
- */
- if (ops->vidioc_s_std)
- p->capabilities |= V4L2_IN_CAP_STD;
- if (ops->vidioc_s_dv_preset)
- p->capabilities |= V4L2_IN_CAP_PRESETS;
- if (ops->vidioc_s_dv_timings)
- p->capabilities |= V4L2_IN_CAP_CUSTOM_TIMINGS;
-
- return ops->vidioc_enum_input(file, fh, p);
-}
-
-static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_output *p = arg;
-
- /*
- * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS &
- * CAP_STD here based on ioctl handler provided by the
- * driver. If the driver doesn't support these
- * for a specific output, it must override these flags.
- */
- if (ops->vidioc_s_std)
- p->capabilities |= V4L2_OUT_CAP_STD;
- if (ops->vidioc_s_dv_preset)
- p->capabilities |= V4L2_OUT_CAP_PRESETS;
- if (ops->vidioc_s_dv_timings)
- p->capabilities |= V4L2_OUT_CAP_CUSTOM_TIMINGS;
-
- return ops->vidioc_enum_output(file, fh, p);
-}
-
-static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_fmtdesc *p = arg;
-
- switch (p->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (unlikely(!ops->vidioc_enum_fmt_vid_cap))
- break;
- return ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (unlikely(!ops->vidioc_enum_fmt_vid_cap_mplane))
- break;
- return ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (unlikely(!ops->vidioc_enum_fmt_vid_overlay))
- break;
- return ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (unlikely(!ops->vidioc_enum_fmt_vid_out))
- break;
- return ops->vidioc_enum_fmt_vid_out(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (unlikely(!ops->vidioc_enum_fmt_vid_out_mplane))
- break;
- return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
- case V4L2_BUF_TYPE_PRIVATE:
- if (unlikely(!ops->vidioc_enum_fmt_type_private))
- break;
- return ops->vidioc_enum_fmt_type_private(file, fh, arg);
- }
- return -EINVAL;
-}
-
-static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_format *p = arg;
-
- switch (p->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (unlikely(!ops->vidioc_g_fmt_vid_cap))
- break;
- return ops->vidioc_g_fmt_vid_cap(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (unlikely(!ops->vidioc_g_fmt_vid_cap_mplane))
- break;
- return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (unlikely(!ops->vidioc_g_fmt_vid_overlay))
- break;
- return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (unlikely(!ops->vidioc_g_fmt_vid_out))
- break;
- return ops->vidioc_g_fmt_vid_out(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (unlikely(!ops->vidioc_g_fmt_vid_out_mplane))
- break;
- return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (unlikely(!ops->vidioc_g_fmt_vid_out_overlay))
- break;
- return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (unlikely(!ops->vidioc_g_fmt_vbi_cap))
- break;
- return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (unlikely(!ops->vidioc_g_fmt_vbi_out))
- break;
- return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (unlikely(!ops->vidioc_g_fmt_sliced_vbi_cap))
- break;
- return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (unlikely(!ops->vidioc_g_fmt_sliced_vbi_out))
- break;
- return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
- case V4L2_BUF_TYPE_PRIVATE:
- if (unlikely(!ops->vidioc_g_fmt_type_private))
- break;
- return ops->vidioc_g_fmt_type_private(file, fh, arg);
- }
- return -EINVAL;
-}
-
-static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_format *p = arg;
-
- switch (p->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (unlikely(!ops->vidioc_s_fmt_vid_cap))
- break;
- CLEAR_AFTER_FIELD(p, fmt.pix);
- return ops->vidioc_s_fmt_vid_cap(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane))
- break;
- CLEAR_AFTER_FIELD(p, fmt.pix_mp);
- return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (unlikely(!ops->vidioc_s_fmt_vid_overlay))
- break;
- CLEAR_AFTER_FIELD(p, fmt.win);
- return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (unlikely(!ops->vidioc_s_fmt_vid_out))
- break;
- CLEAR_AFTER_FIELD(p, fmt.pix);
- return ops->vidioc_s_fmt_vid_out(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane))
- break;
- CLEAR_AFTER_FIELD(p, fmt.pix_mp);
- return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay))
- break;
- CLEAR_AFTER_FIELD(p, fmt.win);
- return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (unlikely(!ops->vidioc_s_fmt_vbi_cap))
- break;
- CLEAR_AFTER_FIELD(p, fmt.vbi);
- return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (unlikely(!ops->vidioc_s_fmt_vbi_out))
- break;
- CLEAR_AFTER_FIELD(p, fmt.vbi);
- return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap))
- break;
- CLEAR_AFTER_FIELD(p, fmt.sliced);
- return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out))
- break;
- CLEAR_AFTER_FIELD(p, fmt.sliced);
- return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
- case V4L2_BUF_TYPE_PRIVATE:
- if (unlikely(!ops->vidioc_s_fmt_type_private))
- break;
- return ops->vidioc_s_fmt_type_private(file, fh, arg);
- }
- return -EINVAL;
-}
-
-static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_format *p = arg;
-
- switch (p->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (unlikely(!ops->vidioc_try_fmt_vid_cap))
- break;
- CLEAR_AFTER_FIELD(p, fmt.pix);
- return ops->vidioc_try_fmt_vid_cap(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
- break;
- CLEAR_AFTER_FIELD(p, fmt.pix_mp);
- return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (unlikely(!ops->vidioc_try_fmt_vid_overlay))
- break;
- CLEAR_AFTER_FIELD(p, fmt.win);
- return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (unlikely(!ops->vidioc_try_fmt_vid_out))
- break;
- CLEAR_AFTER_FIELD(p, fmt.pix);
- return ops->vidioc_try_fmt_vid_out(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane))
- break;
- CLEAR_AFTER_FIELD(p, fmt.pix_mp);
- return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay))
- break;
- CLEAR_AFTER_FIELD(p, fmt.win);
- return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (unlikely(!ops->vidioc_try_fmt_vbi_cap))
- break;
- CLEAR_AFTER_FIELD(p, fmt.vbi);
- return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (unlikely(!ops->vidioc_try_fmt_vbi_out))
- break;
- CLEAR_AFTER_FIELD(p, fmt.vbi);
- return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap))
- break;
- CLEAR_AFTER_FIELD(p, fmt.sliced);
- return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out))
- break;
- CLEAR_AFTER_FIELD(p, fmt.sliced);
- return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
- case V4L2_BUF_TYPE_PRIVATE:
- if (unlikely(!ops->vidioc_try_fmt_type_private))
- break;
- return ops->vidioc_try_fmt_type_private(file, fh, arg);
- }
- return -EINVAL;
-}
-
-static int v4l_streamon(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- return ops->vidioc_streamon(file, fh, *(unsigned int *)arg);
-}
-
-static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
-}
-
-static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_tuner *p = arg;
- int err;
-
- p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
- V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- err = ops->vidioc_g_tuner(file, fh, p);
- if (!err)
- p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
- return err;
-}
-
-static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_tuner *p = arg;
-
- p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
- V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- return ops->vidioc_s_tuner(file, fh, p);
-}
-
-static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_modulator *p = arg;
- int err;
-
- err = ops->vidioc_g_modulator(file, fh, p);
- if (!err)
- p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
- return err;
-}
-
-static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_frequency *p = arg;
-
- p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
- V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- return ops->vidioc_g_frequency(file, fh, p);
-}
-
-static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_frequency *p = arg;
- enum v4l2_tuner_type type;
-
- type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
- V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- if (p->type != type)
- return -EINVAL;
- return ops->vidioc_s_frequency(file, fh, p);
-}
-
-static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_standard *p = arg;
- v4l2_std_id id = vfd->tvnorms, curr_id = 0;
- unsigned int index = p->index, i, j = 0;
- const char *descr = "";
-
- /* Return norm array in a canonical way */
- for (i = 0; i <= index && id; i++) {
- /* last std value in the standards array is 0, so this
- while always ends there since (id & 0) == 0. */
- while ((id & standards[j].std) != standards[j].std)
- j++;
- curr_id = standards[j].std;
- descr = standards[j].descr;
- j++;
- if (curr_id == 0)
- break;
- if (curr_id != V4L2_STD_PAL &&
- curr_id != V4L2_STD_SECAM &&
- curr_id != V4L2_STD_NTSC)
- id &= ~curr_id;
- }
- if (i <= index)
- return -EINVAL;
-
- v4l2_video_std_construct(p, curr_id, descr);
- return 0;
-}
-
-static int v4l_g_std(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- v4l2_std_id *id = arg;
-
- /* Calls the specific handler */
- if (ops->vidioc_g_std)
- return ops->vidioc_g_std(file, fh, arg);
- if (vfd->current_norm) {
- *id = vfd->current_norm;
- return 0;
- }
- return -ENOTTY;
-}
-
-static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- v4l2_std_id *id = arg, norm;
- int ret;
-
- norm = (*id) & vfd->tvnorms;
- if (vfd->tvnorms && !norm) /* Check if std is supported */
- return -EINVAL;
-
- /* Calls the specific handler */
- ret = ops->vidioc_s_std(file, fh, &norm);
-
- /* Updates standard information */
- if (ret >= 0)
- vfd->current_norm = norm;
- return ret;
-}
-
-static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- v4l2_std_id *p = arg;
-
- /*
- * If nothing detected, it should return all supported
- * standard.
- * Drivers just need to mask the std argument, in order
- * to remove the standards that don't apply from the mask.
- * This means that tuners, audio and video decoders can join
- * their efforts to improve the standards detection.
- */
- *p = vfd->tvnorms;
- return ops->vidioc_querystd(file, fh, arg);
-}
-
-static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_hw_freq_seek *p = arg;
- enum v4l2_tuner_type type;
-
- type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
- V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- if (p->type != type)
- return -EINVAL;
- return ops->vidioc_s_hw_freq_seek(file, fh, p);
-}
-
-static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_requestbuffers *p = arg;
- int ret = check_fmt(ops, p->type);
-
- if (ret)
- return ret;
-
- if (p->type < V4L2_BUF_TYPE_PRIVATE)
- CLEAR_AFTER_FIELD(p, memory);
-
- return ops->vidioc_reqbufs(file, fh, p);
-}
-
-static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_buffer *p = arg;
- int ret = check_fmt(ops, p->type);
-
- return ret ? ret : ops->vidioc_querybuf(file, fh, p);
-}
-
-static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_buffer *p = arg;
- int ret = check_fmt(ops, p->type);
-
- return ret ? ret : ops->vidioc_qbuf(file, fh, p);
-}
-
-static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_buffer *p = arg;
- int ret = check_fmt(ops, p->type);
-
- return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
-}
-
-static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_create_buffers *create = arg;
- int ret = check_fmt(ops, create->format.type);
-
- return ret ? ret : ops->vidioc_create_bufs(file, fh, create);
-}
-
-static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_buffer *b = arg;
- int ret = check_fmt(ops, b->type);
-
- return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
-}
-
-static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_streamparm *p = arg;
- v4l2_std_id std;
- int ret = check_fmt(ops, p->type);
-
- if (ret)
- return ret;
- if (ops->vidioc_g_parm)
- return ops->vidioc_g_parm(file, fh, p);
- std = vfd->current_norm;
- if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
- p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return -EINVAL;
- p->parm.capture.readbuffers = 2;
- if (ops->vidioc_g_std)
- ret = ops->vidioc_g_std(file, fh, &std);
- if (ret == 0)
- v4l2_video_std_frame_period(std,
- &p->parm.capture.timeperframe);
- return ret;
-}
-
-static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_streamparm *p = arg;
- int ret = check_fmt(ops, p->type);
-
- return ret ? ret : ops->vidioc_s_parm(file, fh, p);
-}
-
-static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_queryctrl *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
-
- if (vfh && vfh->ctrl_handler)
- return v4l2_queryctrl(vfh->ctrl_handler, p);
- if (vfd->ctrl_handler)
- return v4l2_queryctrl(vfd->ctrl_handler, p);
- if (ops->vidioc_queryctrl)
- return ops->vidioc_queryctrl(file, fh, p);
- return -ENOTTY;
-}
-
-static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_querymenu *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
-
- if (vfh && vfh->ctrl_handler)
- return v4l2_querymenu(vfh->ctrl_handler, p);
- if (vfd->ctrl_handler)
- return v4l2_querymenu(vfd->ctrl_handler, p);
- if (ops->vidioc_querymenu)
- return ops->vidioc_querymenu(file, fh, p);
- return -ENOTTY;
-}
-
-static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_control *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
- struct v4l2_ext_controls ctrls;
- struct v4l2_ext_control ctrl;
-
- if (vfh && vfh->ctrl_handler)
- return v4l2_g_ctrl(vfh->ctrl_handler, p);
- if (vfd->ctrl_handler)
- return v4l2_g_ctrl(vfd->ctrl_handler, p);
- if (ops->vidioc_g_ctrl)
- return ops->vidioc_g_ctrl(file, fh, p);
- if (ops->vidioc_g_ext_ctrls == NULL)
- return -ENOTTY;
-
- ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
- ctrls.count = 1;
- ctrls.controls = &ctrl;
- ctrl.id = p->id;
- ctrl.value = p->value;
- if (check_ext_ctrls(&ctrls, 1)) {
- int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
-
- if (ret == 0)
- p->value = ctrl.value;
- return ret;
- }
- return -EINVAL;
-}
-
-static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_control *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
- struct v4l2_ext_controls ctrls;
- struct v4l2_ext_control ctrl;
-
- if (vfh && vfh->ctrl_handler)
- return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
- if (vfd->ctrl_handler)
- return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
- if (ops->vidioc_s_ctrl)
- return ops->vidioc_s_ctrl(file, fh, p);
- if (ops->vidioc_s_ext_ctrls == NULL)
- return -ENOTTY;
-
- ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
- ctrls.count = 1;
- ctrls.controls = &ctrl;
- ctrl.id = p->id;
- ctrl.value = p->value;
- if (check_ext_ctrls(&ctrls, 1))
- return ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
- return -EINVAL;
-}
-
-static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_ext_controls *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
-
- p->error_idx = p->count;
- if (vfh && vfh->ctrl_handler)
- return v4l2_g_ext_ctrls(vfh->ctrl_handler, p);
- if (vfd->ctrl_handler)
- return v4l2_g_ext_ctrls(vfd->ctrl_handler, p);
- if (ops->vidioc_g_ext_ctrls == NULL)
- return -ENOTTY;
- return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) :
- -EINVAL;
-}
-
-static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_ext_controls *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
-
- p->error_idx = p->count;
- if (vfh && vfh->ctrl_handler)
- return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p);
- if (vfd->ctrl_handler)
- return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, p);
- if (ops->vidioc_s_ext_ctrls == NULL)
- return -ENOTTY;
- return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) :
- -EINVAL;
-}
-
-static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_ext_controls *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
-
- p->error_idx = p->count;
- if (vfh && vfh->ctrl_handler)
- return v4l2_try_ext_ctrls(vfh->ctrl_handler, p);
- if (vfd->ctrl_handler)
- return v4l2_try_ext_ctrls(vfd->ctrl_handler, p);
- if (ops->vidioc_try_ext_ctrls == NULL)
- return -ENOTTY;
- return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) :
- -EINVAL;
-}
-
-static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_crop *p = arg;
- struct v4l2_selection s = {
- .type = p->type,
- };
- int ret;
-
- if (ops->vidioc_g_crop)
- return ops->vidioc_g_crop(file, fh, p);
- /* simulate capture crop using selection api */
-
- /* crop means compose for output devices */
- if (V4L2_TYPE_IS_OUTPUT(p->type))
- s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
- else
- s.target = V4L2_SEL_TGT_CROP_ACTIVE;
-
- ret = ops->vidioc_g_selection(file, fh, &s);
-
- /* copying results to old structure on success */
- if (!ret)
- p->c = s.r;
- return ret;
-}
-
-static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_crop *p = arg;
- struct v4l2_selection s = {
- .type = p->type,
- .r = p->c,
- };
-
- if (ops->vidioc_s_crop)
- return ops->vidioc_s_crop(file, fh, p);
- /* simulate capture crop using selection api */
-
- /* crop means compose for output devices */
- if (V4L2_TYPE_IS_OUTPUT(p->type))
- s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
- else
- s.target = V4L2_SEL_TGT_CROP_ACTIVE;
-
- return ops->vidioc_s_selection(file, fh, &s);
-}
-
-static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_cropcap *p = arg;
- struct v4l2_selection s = { .type = p->type };
- int ret;
-
- if (ops->vidioc_cropcap)
- return ops->vidioc_cropcap(file, fh, p);
-
- /* obtaining bounds */
- if (V4L2_TYPE_IS_OUTPUT(p->type))
- s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
- else
- s.target = V4L2_SEL_TGT_CROP_BOUNDS;
-
- ret = ops->vidioc_g_selection(file, fh, &s);
- if (ret)
- return ret;
- p->bounds = s.r;
-
- /* obtaining defrect */
- if (V4L2_TYPE_IS_OUTPUT(p->type))
- s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
- else
- s.target = V4L2_SEL_TGT_CROP_DEFAULT;
-
- ret = ops->vidioc_g_selection(file, fh, &s);
- if (ret)
- return ret;
- p->defrect = s.r;
-
- /* setting trivial pixelaspect */
- p->pixelaspect.numerator = 1;
- p->pixelaspect.denominator = 1;
- return 0;
-}
-
-static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- int ret;
-
- if (vfd->v4l2_dev)
- pr_info("%s: ================= START STATUS =================\n",
- vfd->v4l2_dev->name);
- ret = ops->vidioc_log_status(file, fh);
- if (vfd->v4l2_dev)
- pr_info("%s: ================== END STATUS ==================\n",
- vfd->v4l2_dev->name);
- return ret;
-}
-
-static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- struct v4l2_dbg_register *p = arg;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- return ops->vidioc_g_register(file, fh, p);
-#else
- return -ENOTTY;
-#endif
-}
-
-static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- struct v4l2_dbg_register *p = arg;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- return ops->vidioc_s_register(file, fh, p);
-#else
- return -ENOTTY;
-#endif
-}
-
-static int v4l_dbg_g_chip_ident(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_dbg_chip_ident *p = arg;
-
- p->ident = V4L2_IDENT_NONE;
- p->revision = 0;
- return ops->vidioc_g_chip_ident(file, fh, p);
-}
-
-static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK);
-}
-
-static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- return ops->vidioc_subscribe_event(fh, arg);
-}
-
-static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- return ops->vidioc_unsubscribe_event(fh, arg);
-}
-
-static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_sliced_vbi_cap *p = arg;
-
- /* Clear up to type, everything after type is zeroed already */
- memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
-
- return ops->vidioc_g_sliced_vbi_cap(file, fh, p);
-}
-
-static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- struct v4l2_frequency_band *p = arg;
- enum v4l2_tuner_type type;
- int err;
-
- type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
- V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
-
- if (type != p->type)
- return -EINVAL;
- if (ops->vidioc_enum_freq_bands)
- return ops->vidioc_enum_freq_bands(file, fh, p);
- if (ops->vidioc_g_tuner) {
- struct v4l2_tuner t = {
- .index = p->tuner,
- .type = type,
- };
-
- if (p->index)
- return -EINVAL;
- err = ops->vidioc_g_tuner(file, fh, &t);
- if (err)
- return err;
- p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS;
- p->rangelow = t.rangelow;
- p->rangehigh = t.rangehigh;
- p->modulation = (type == V4L2_TUNER_RADIO) ?
- V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
- return 0;
- }
- if (ops->vidioc_g_modulator) {
- struct v4l2_modulator m = {
- .index = p->tuner,
- };
-
- if (type != V4L2_TUNER_RADIO)
- return -EINVAL;
- if (p->index)
- return -EINVAL;
- err = ops->vidioc_g_modulator(file, fh, &m);
- if (err)
- return err;
- p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS;
- p->rangelow = m.rangelow;
- p->rangehigh = m.rangehigh;
- p->modulation = (type == V4L2_TUNER_RADIO) ?
- V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
- return 0;
- }
- return -ENOTTY;
-}
-
-struct v4l2_ioctl_info {
- unsigned int ioctl;
- u32 flags;
- const char * const name;
- union {
- u32 offset;
- int (*func)(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *p);
- } u;
- void (*debug)(const void *arg, bool write_only);
-};
-
-/* This control needs a priority check */
-#define INFO_FL_PRIO (1 << 0)
-/* This control can be valid if the filehandle passes a control handler. */
-#define INFO_FL_CTRL (1 << 1)
-/* This is a standard ioctl, no need for special code */
-#define INFO_FL_STD (1 << 2)
-/* This is ioctl has its own function */
-#define INFO_FL_FUNC (1 << 3)
-/* Queuing ioctl */
-#define INFO_FL_QUEUE (1 << 4)
-/* Zero struct from after the field to the end */
-#define INFO_FL_CLEAR(v4l2_struct, field) \
- ((offsetof(struct v4l2_struct, field) + \
- sizeof(((struct v4l2_struct *)0)->field)) << 16)
-#define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16)
-
-#define IOCTL_INFO_STD(_ioctl, _vidioc, _debug, _flags) \
- [_IOC_NR(_ioctl)] = { \
- .ioctl = _ioctl, \
- .flags = _flags | INFO_FL_STD, \
- .name = #_ioctl, \
- .u.offset = offsetof(struct v4l2_ioctl_ops, _vidioc), \
- .debug = _debug, \
- }
-
-#define IOCTL_INFO_FNC(_ioctl, _func, _debug, _flags) \
- [_IOC_NR(_ioctl)] = { \
- .ioctl = _ioctl, \
- .flags = _flags | INFO_FL_FUNC, \
- .name = #_ioctl, \
- .u.func = _func, \
- .debug = _debug, \
- }
-
-static struct v4l2_ioctl_info v4l2_ioctls[] = {
- IOCTL_INFO_FNC(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0),
- IOCTL_INFO_FNC(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)),
- IOCTL_INFO_FNC(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, INFO_FL_CLEAR(v4l2_format, type)),
- IOCTL_INFO_FNC(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
- IOCTL_INFO_FNC(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
- IOCTL_INFO_FNC(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
- IOCTL_INFO_STD(VIDIOC_G_FBUF, vidioc_g_fbuf, v4l_print_framebuffer, 0),
- IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
- IOCTL_INFO_STD(VIDIOC_OVERLAY, vidioc_overlay, v4l_print_u32, INFO_FL_PRIO),
- IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
- IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
- IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
- IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
- IOCTL_INFO_FNC(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
- IOCTL_INFO_FNC(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
- IOCTL_INFO_FNC(VIDIOC_G_STD, v4l_g_std, v4l_print_std, 0),
- IOCTL_INFO_FNC(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
- IOCTL_INFO_FNC(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
- IOCTL_INFO_FNC(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
- IOCTL_INFO_FNC(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)),
- IOCTL_INFO_FNC(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL),
- IOCTL_INFO_FNC(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)),
- IOCTL_INFO_FNC(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO),
- IOCTL_INFO_STD(VIDIOC_G_AUDIO, vidioc_g_audio, v4l_print_audio, 0),
- IOCTL_INFO_STD(VIDIOC_S_AUDIO, vidioc_s_audio, v4l_print_audio, INFO_FL_PRIO),
- IOCTL_INFO_FNC(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
- IOCTL_INFO_FNC(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
- IOCTL_INFO_STD(VIDIOC_G_INPUT, vidioc_g_input, v4l_print_u32, 0),
- IOCTL_INFO_FNC(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
- IOCTL_INFO_STD(VIDIOC_G_OUTPUT, vidioc_g_output, v4l_print_u32, 0),
- IOCTL_INFO_FNC(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
- IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
- IOCTL_INFO_STD(VIDIOC_G_AUDOUT, vidioc_g_audout, v4l_print_audioout, 0),
- IOCTL_INFO_STD(VIDIOC_S_AUDOUT, vidioc_s_audout, v4l_print_audioout, INFO_FL_PRIO),
- IOCTL_INFO_FNC(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
- IOCTL_INFO_STD(VIDIOC_S_MODULATOR, vidioc_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
- IOCTL_INFO_FNC(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
- IOCTL_INFO_FNC(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
- IOCTL_INFO_FNC(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
- IOCTL_INFO_FNC(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)),
- IOCTL_INFO_FNC(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO),
- IOCTL_INFO_STD(VIDIOC_G_SELECTION, vidioc_g_selection, v4l_print_selection, 0),
- IOCTL_INFO_STD(VIDIOC_S_SELECTION, vidioc_s_selection, v4l_print_selection, INFO_FL_PRIO),
- IOCTL_INFO_STD(VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp, v4l_print_jpegcompression, 0),
- IOCTL_INFO_STD(VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO),
- IOCTL_INFO_FNC(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
- IOCTL_INFO_FNC(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
- IOCTL_INFO_STD(VIDIOC_ENUMAUDIO, vidioc_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
- IOCTL_INFO_STD(VIDIOC_ENUMAUDOUT, vidioc_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
- IOCTL_INFO_FNC(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0),
- IOCTL_INFO_FNC(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO),
- IOCTL_INFO_FNC(VIDIOC_G_SLICED_VBI_CAP, v4l_g_sliced_vbi_cap, v4l_print_sliced_vbi_cap, INFO_FL_CLEAR(v4l2_sliced_vbi_cap, type)),
- IOCTL_INFO_FNC(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0),
- IOCTL_INFO_FNC(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
- IOCTL_INFO_FNC(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL),
- IOCTL_INFO_FNC(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL),
- IOCTL_INFO_STD(VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)),
- IOCTL_INFO_STD(VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)),
- IOCTL_INFO_STD(VIDIOC_G_ENC_INDEX, vidioc_g_enc_index, v4l_print_enc_idx, 0),
- IOCTL_INFO_STD(VIDIOC_ENCODER_CMD, vidioc_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
- IOCTL_INFO_STD(VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)),
- IOCTL_INFO_STD(VIDIOC_DECODER_CMD, vidioc_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO),
- IOCTL_INFO_STD(VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd, v4l_print_decoder_cmd, 0),
- IOCTL_INFO_FNC(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
- IOCTL_INFO_FNC(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
- IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_IDENT, v4l_dbg_g_chip_ident, v4l_print_dbg_chip_ident, 0),
- IOCTL_INFO_FNC(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
- IOCTL_INFO_STD(VIDIOC_ENUM_DV_PRESETS, vidioc_enum_dv_presets, v4l_print_dv_enum_presets, 0),
- IOCTL_INFO_STD(VIDIOC_S_DV_PRESET, vidioc_s_dv_preset, v4l_print_dv_preset, INFO_FL_PRIO),
- IOCTL_INFO_STD(VIDIOC_G_DV_PRESET, vidioc_g_dv_preset, v4l_print_dv_preset, 0),
- IOCTL_INFO_STD(VIDIOC_QUERY_DV_PRESET, vidioc_query_dv_preset, v4l_print_dv_preset, 0),
- IOCTL_INFO_STD(VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings, v4l_print_dv_timings, INFO_FL_PRIO),
- IOCTL_INFO_STD(VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings, v4l_print_dv_timings, 0),
- IOCTL_INFO_FNC(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
- IOCTL_INFO_FNC(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0),
- IOCTL_INFO_FNC(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0),
- IOCTL_INFO_FNC(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE),
- IOCTL_INFO_FNC(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE),
- IOCTL_INFO_STD(VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings, v4l_print_enum_dv_timings, 0),
- IOCTL_INFO_STD(VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings, v4l_print_dv_timings, 0),
- IOCTL_INFO_STD(VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap, v4l_print_dv_timings_cap, INFO_FL_CLEAR(v4l2_dv_timings_cap, type)),
- IOCTL_INFO_FNC(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
-};
-#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
-
-bool v4l2_is_known_ioctl(unsigned int cmd)
-{
- if (_IOC_NR(cmd) >= V4L2_IOCTLS)
- return false;
- return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
-}
-
-struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd)
-{
- if (_IOC_NR(cmd) >= V4L2_IOCTLS)
- return vdev->lock;
- if (test_bit(_IOC_NR(cmd), vdev->disable_locking))
- return NULL;
- if (vdev->queue && vdev->queue->lock &&
- (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
- return vdev->queue->lock;
- return vdev->lock;
-}
-
-/* Common ioctl debug function. This function can be used by
- external ioctl messages as well as internal V4L ioctl */
-void v4l_printk_ioctl(const char *prefix, unsigned int cmd)
-{
- const char *dir, *type;
-
- if (prefix)
- printk(KERN_DEBUG "%s: ", prefix);
-
- switch (_IOC_TYPE(cmd)) {
- case 'd':
- type = "v4l2_int";
- break;
- case 'V':
- if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
- type = "v4l2";
- break;
- }
- pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
- return;
- default:
- type = "unknown";
- break;
- }
-
- switch (_IOC_DIR(cmd)) {
- case _IOC_NONE: dir = "--"; break;
- case _IOC_READ: dir = "r-"; break;
- case _IOC_WRITE: dir = "-w"; break;
- case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
- default: dir = "*ERR*"; break;
- }
- pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)",
- type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
-}
-EXPORT_SYMBOL(v4l_printk_ioctl);
-
-static long __video_do_ioctl(struct file *file,
- unsigned int cmd, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
- bool write_only = false;
- struct v4l2_ioctl_info default_info;
- const struct v4l2_ioctl_info *info;
- void *fh = file->private_data;
- struct v4l2_fh *vfh = NULL;
- int use_fh_prio = 0;
- int debug = vfd->debug;
- long ret = -ENOTTY;
-
- if (ops == NULL) {
- pr_warn("%s: has no ioctl_ops.\n",
- video_device_node_name(vfd));
- return ret;
- }
-
- if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
- vfh = file->private_data;
- use_fh_prio = test_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
- }
-
- if (v4l2_is_known_ioctl(cmd)) {
- info = &v4l2_ioctls[_IOC_NR(cmd)];
-
- if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
- !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
- goto done;
-
- if (use_fh_prio && (info->flags & INFO_FL_PRIO)) {
- ret = v4l2_prio_check(vfd->prio, vfh->prio);
- if (ret)
- goto done;
- }
- } else {
- default_info.ioctl = cmd;
- default_info.flags = 0;
- default_info.debug = v4l_print_default;
- info = &default_info;
- }
-
- write_only = _IOC_DIR(cmd) == _IOC_WRITE;
- if (write_only && debug > V4L2_DEBUG_IOCTL) {
- v4l_printk_ioctl(video_device_node_name(vfd), cmd);
- pr_cont(": ");
- info->debug(arg, write_only);
- }
- if (info->flags & INFO_FL_STD) {
- typedef int (*vidioc_op)(struct file *file, void *fh, void *p);
- const void *p = vfd->ioctl_ops;
- const vidioc_op *vidioc = p + info->u.offset;
-
- ret = (*vidioc)(file, fh, arg);
- } else if (info->flags & INFO_FL_FUNC) {
- ret = info->u.func(ops, file, fh, arg);
- } else if (!ops->vidioc_default) {
- ret = -ENOTTY;
- } else {
- ret = ops->vidioc_default(file, fh,
- use_fh_prio ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
- cmd, arg);
- }
-
-done:
- if (debug) {
- if (write_only && debug > V4L2_DEBUG_IOCTL) {
- if (ret < 0)
- printk(KERN_DEBUG "%s: error %ld\n",
- video_device_node_name(vfd), ret);
- return ret;
- }
- v4l_printk_ioctl(video_device_node_name(vfd), cmd);
- if (ret < 0)
- pr_cont(": error %ld\n", ret);
- else if (debug == V4L2_DEBUG_IOCTL)
- pr_cont("\n");
- else if (_IOC_DIR(cmd) == _IOC_NONE)
- info->debug(arg, write_only);
- else {
- pr_cont(": ");
- info->debug(arg, write_only);
- }
- }
-
- return ret;
-}
-
-static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
- void * __user *user_ptr, void ***kernel_ptr)
-{
- int ret = 0;
-
- switch (cmd) {
- case VIDIOC_QUERYBUF:
- case VIDIOC_QBUF:
- case VIDIOC_DQBUF: {
- struct v4l2_buffer *buf = parg;
-
- if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
- if (buf->length > VIDEO_MAX_PLANES) {
- ret = -EINVAL;
- break;
- }
- *user_ptr = (void __user *)buf->m.planes;
- *kernel_ptr = (void *)&buf->m.planes;
- *array_size = sizeof(struct v4l2_plane) * buf->length;
- ret = 1;
- }
- break;
- }
-
- case VIDIOC_S_EXT_CTRLS:
- case VIDIOC_G_EXT_CTRLS:
- case VIDIOC_TRY_EXT_CTRLS: {
- struct v4l2_ext_controls *ctrls = parg;
-
- if (ctrls->count != 0) {
- if (ctrls->count > V4L2_CID_MAX_CTRLS) {
- ret = -EINVAL;
- break;
- }
- *user_ptr = (void __user *)ctrls->controls;
- *kernel_ptr = (void *)&ctrls->controls;
- *array_size = sizeof(struct v4l2_ext_control)
- * ctrls->count;
- ret = 1;
- }
- break;
- }
- }
-
- return ret;
-}
-
-long
-video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
- v4l2_kioctl func)
-{
- char sbuf[128];
- void *mbuf = NULL;
- void *parg = (void *)arg;
- long err = -EINVAL;
- bool has_array_args;
- size_t array_size = 0;
- void __user *user_ptr = NULL;
- void **kernel_ptr = NULL;
-
- /* Copy arguments into temp kernel buffer */
- if (_IOC_DIR(cmd) != _IOC_NONE) {
- if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
- parg = sbuf;
- } else {
- /* too big to allocate from stack */
- mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
- if (NULL == mbuf)
- return -ENOMEM;
- parg = mbuf;
- }
-
- err = -EFAULT;
- if (_IOC_DIR(cmd) & _IOC_WRITE) {
- unsigned int n = _IOC_SIZE(cmd);
-
- /*
- * In some cases, only a few fields are used as input,
- * i.e. when the app sets "index" and then the driver
- * fills in the rest of the structure for the thing
- * with that index. We only need to copy up the first
- * non-input field.
- */
- if (v4l2_is_known_ioctl(cmd)) {
- u32 flags = v4l2_ioctls[_IOC_NR(cmd)].flags;
- if (flags & INFO_FL_CLEAR_MASK)
- n = (flags & INFO_FL_CLEAR_MASK) >> 16;
- }
-
- if (copy_from_user(parg, (void __user *)arg, n))
- goto out;
-
- /* zero out anything we don't copy from userspace */
- if (n < _IOC_SIZE(cmd))
- memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
- } else {
- /* read-only ioctl */
- memset(parg, 0, _IOC_SIZE(cmd));
- }
- }
-
- err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
- if (err < 0)
- goto out;
- has_array_args = err;
-
- if (has_array_args) {
- /*
- * When adding new types of array args, make sure that the
- * parent argument to ioctl (which contains the pointer to the
- * array) fits into sbuf (so that mbuf will still remain
- * unused up to here).
- */
- mbuf = kmalloc(array_size, GFP_KERNEL);
- err = -ENOMEM;
- if (NULL == mbuf)
- goto out_array_args;
- err = -EFAULT;
- if (copy_from_user(mbuf, user_ptr, array_size))
- goto out_array_args;
- *kernel_ptr = mbuf;
- }
-
- /* Handles IOCTL */
- err = func(file, cmd, parg);
- if (err == -ENOIOCTLCMD)
- err = -ENOTTY;
-
- if (has_array_args) {
- *kernel_ptr = user_ptr;
- if (copy_to_user(user_ptr, mbuf, array_size))
- err = -EFAULT;
- goto out_array_args;
- }
- /* VIDIOC_QUERY_DV_TIMINGS can return an error, but still have valid
- results that must be returned. */
- if (err < 0 && cmd != VIDIOC_QUERY_DV_TIMINGS)
- goto out;
-
-out_array_args:
- /* Copy results into user buffer */
- switch (_IOC_DIR(cmd)) {
- case _IOC_READ:
- case (_IOC_WRITE | _IOC_READ):
- if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
- err = -EFAULT;
- break;
- }
-
-out:
- kfree(mbuf);
- return err;
-}
-EXPORT_SYMBOL(video_usercopy);
-
-long video_ioctl2(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- return video_usercopy(file, cmd, arg, __video_do_ioctl);
-}
-EXPORT_SYMBOL(video_ioctl2);
diff --git a/drivers/media/video/v4l2-mem2mem.c b/drivers/media/video/v4l2-mem2mem.c
deleted file mode 100644
index 97b48318aee..00000000000
--- a/drivers/media/video/v4l2-mem2mem.c
+++ /dev/null
@@ -1,647 +0,0 @@
-/*
- * Memory-to-memory device framework for Video for Linux 2 and videobuf.
- *
- * Helper functions for devices that use videobuf buffers for both their
- * source and destination.
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- * Pawel Osciak, <pawel@osciak.com>
- * Marek Szyprowski, <m.szyprowski@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-
-#include <media/videobuf2-core.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-
-MODULE_DESCRIPTION("Mem to mem device framework for videobuf");
-MODULE_AUTHOR("Pawel Osciak, <pawel@osciak.com>");
-MODULE_LICENSE("GPL");
-
-static bool debug;
-module_param(debug, bool, 0644);
-
-#define dprintk(fmt, arg...) \
- do { \
- if (debug) \
- printk(KERN_DEBUG "%s: " fmt, __func__, ## arg);\
- } while (0)
-
-
-/* Instance is already queued on the job_queue */
-#define TRANS_QUEUED (1 << 0)
-/* Instance is currently running in hardware */
-#define TRANS_RUNNING (1 << 1)
-
-
-/* Offset base for buffers on the destination queue - used to distinguish
- * between source and destination buffers when mmapping - they receive the same
- * offsets but for different queues */
-#define DST_QUEUE_OFF_BASE (1 << 30)
-
-
-/**
- * struct v4l2_m2m_dev - per-device context
- * @curr_ctx: currently running instance
- * @job_queue: instances queued to run
- * @job_spinlock: protects job_queue
- * @m2m_ops: driver callbacks
- */
-struct v4l2_m2m_dev {
- struct v4l2_m2m_ctx *curr_ctx;
-
- struct list_head job_queue;
- spinlock_t job_spinlock;
-
- struct v4l2_m2m_ops *m2m_ops;
-};
-
-static struct v4l2_m2m_queue_ctx *get_queue_ctx(struct v4l2_m2m_ctx *m2m_ctx,
- enum v4l2_buf_type type)
-{
- if (V4L2_TYPE_IS_OUTPUT(type))
- return &m2m_ctx->out_q_ctx;
- else
- return &m2m_ctx->cap_q_ctx;
-}
-
-/**
- * v4l2_m2m_get_vq() - return vb2_queue for the given type
- */
-struct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx,
- enum v4l2_buf_type type)
-{
- struct v4l2_m2m_queue_ctx *q_ctx;
-
- q_ctx = get_queue_ctx(m2m_ctx, type);
- if (!q_ctx)
- return NULL;
-
- return &q_ctx->q;
-}
-EXPORT_SYMBOL(v4l2_m2m_get_vq);
-
-/**
- * v4l2_m2m_next_buf() - return next buffer from the list of ready buffers
- */
-void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx)
-{
- struct v4l2_m2m_buffer *b = NULL;
- unsigned long flags;
-
- spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
-
- if (list_empty(&q_ctx->rdy_queue)) {
- spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
- return NULL;
- }
-
- b = list_entry(q_ctx->rdy_queue.next, struct v4l2_m2m_buffer, list);
- spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
- return &b->vb;
-}
-EXPORT_SYMBOL_GPL(v4l2_m2m_next_buf);
-
-/**
- * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and
- * return it
- */
-void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
-{
- struct v4l2_m2m_buffer *b = NULL;
- unsigned long flags;
-
- spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
- if (list_empty(&q_ctx->rdy_queue)) {
- spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
- return NULL;
- }
- b = list_entry(q_ctx->rdy_queue.next, struct v4l2_m2m_buffer, list);
- list_del(&b->list);
- q_ctx->num_rdy--;
- spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
-
- return &b->vb;
-}
-EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
-
-/*
- * Scheduling handlers
- */
-
-/**
- * v4l2_m2m_get_curr_priv() - return driver private data for the currently
- * running instance or NULL if no instance is running
- */
-void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev)
-{
- unsigned long flags;
- void *ret = NULL;
-
- spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
- if (m2m_dev->curr_ctx)
- ret = m2m_dev->curr_ctx->priv;
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL(v4l2_m2m_get_curr_priv);
-
-/**
- * v4l2_m2m_try_run() - select next job to perform and run it if possible
- *
- * Get next transaction (if present) from the waiting jobs list and run it.
- */
-static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
- if (NULL != m2m_dev->curr_ctx) {
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
- dprintk("Another instance is running, won't run now\n");
- return;
- }
-
- if (list_empty(&m2m_dev->job_queue)) {
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
- dprintk("No job pending\n");
- return;
- }
-
- m2m_dev->curr_ctx = list_entry(m2m_dev->job_queue.next,
- struct v4l2_m2m_ctx, queue);
- m2m_dev->curr_ctx->job_flags |= TRANS_RUNNING;
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
-
- m2m_dev->m2m_ops->device_run(m2m_dev->curr_ctx->priv);
-}
-
-/**
- * v4l2_m2m_try_schedule() - check whether an instance is ready to be added to
- * the pending job queue and add it if so.
- * @m2m_ctx: m2m context assigned to the instance to be checked
- *
- * There are three basic requirements an instance has to meet to be able to run:
- * 1) at least one source buffer has to be queued,
- * 2) at least one destination buffer has to be queued,
- * 3) streaming has to be on.
- *
- * There may also be additional, custom requirements. In such case the driver
- * should supply a custom callback (job_ready in v4l2_m2m_ops) that should
- * return 1 if the instance is ready.
- * An example of the above could be an instance that requires more than one
- * src/dst buffer per transaction.
- */
-static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx)
-{
- struct v4l2_m2m_dev *m2m_dev;
- unsigned long flags_job, flags;
-
- m2m_dev = m2m_ctx->m2m_dev;
- dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
-
- if (!m2m_ctx->out_q_ctx.q.streaming
- || !m2m_ctx->cap_q_ctx.q.streaming) {
- dprintk("Streaming needs to be on for both queues\n");
- return;
- }
-
- spin_lock_irqsave(&m2m_dev->job_spinlock, flags_job);
- if (m2m_ctx->job_flags & TRANS_QUEUED) {
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
- dprintk("On job queue already\n");
- return;
- }
-
- spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
- if (list_empty(&m2m_ctx->out_q_ctx.rdy_queue)) {
- spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
- dprintk("No input buffers available\n");
- return;
- }
- if (list_empty(&m2m_ctx->cap_q_ctx.rdy_queue)) {
- spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
- dprintk("No output buffers available\n");
- return;
- }
- spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
-
- if (m2m_dev->m2m_ops->job_ready
- && (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) {
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
- dprintk("Driver not ready\n");
- return;
- }
-
- list_add_tail(&m2m_ctx->queue, &m2m_dev->job_queue);
- m2m_ctx->job_flags |= TRANS_QUEUED;
-
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
-
- v4l2_m2m_try_run(m2m_dev);
-}
-
-/**
- * v4l2_m2m_job_finish() - inform the framework that a job has been finished
- * and have it clean up
- *
- * Called by a driver to yield back the device after it has finished with it.
- * Should be called as soon as possible after reaching a state which allows
- * other instances to take control of the device.
- *
- * This function has to be called only after device_run() callback has been
- * called on the driver. To prevent recursion, it should not be called directly
- * from the device_run() callback though.
- */
-void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
- struct v4l2_m2m_ctx *m2m_ctx)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
- if (!m2m_dev->curr_ctx || m2m_dev->curr_ctx != m2m_ctx) {
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
- dprintk("Called by an instance not currently running\n");
- return;
- }
-
- list_del(&m2m_dev->curr_ctx->queue);
- m2m_dev->curr_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING);
- wake_up(&m2m_dev->curr_ctx->finished);
- m2m_dev->curr_ctx = NULL;
-
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
-
- /* This instance might have more buffers ready, but since we do not
- * allow more than one job on the job_queue per instance, each has
- * to be scheduled separately after the previous one finishes. */
- v4l2_m2m_try_schedule(m2m_ctx);
- v4l2_m2m_try_run(m2m_dev);
-}
-EXPORT_SYMBOL(v4l2_m2m_job_finish);
-
-/**
- * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer
- */
-int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct vb2_queue *vq;
-
- vq = v4l2_m2m_get_vq(m2m_ctx, reqbufs->type);
- return vb2_reqbufs(vq, reqbufs);
-}
-EXPORT_SYMBOL_GPL(v4l2_m2m_reqbufs);
-
-/**
- * v4l2_m2m_querybuf() - multi-queue-aware QUERYBUF multiplexer
- *
- * See v4l2_m2m_mmap() documentation for details.
- */
-int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
- struct v4l2_buffer *buf)
-{
- struct vb2_queue *vq;
- int ret = 0;
- unsigned int i;
-
- vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
- ret = vb2_querybuf(vq, buf);
-
- /* Adjust MMAP memory offsets for the CAPTURE queue */
- if (buf->memory == V4L2_MEMORY_MMAP && !V4L2_TYPE_IS_OUTPUT(vq->type)) {
- if (V4L2_TYPE_IS_MULTIPLANAR(vq->type)) {
- for (i = 0; i < buf->length; ++i)
- buf->m.planes[i].m.mem_offset
- += DST_QUEUE_OFF_BASE;
- } else {
- buf->m.offset += DST_QUEUE_OFF_BASE;
- }
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(v4l2_m2m_querybuf);
-
-/**
- * v4l2_m2m_qbuf() - enqueue a source or destination buffer, depending on
- * the type
- */
-int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
- struct v4l2_buffer *buf)
-{
- struct vb2_queue *vq;
- int ret;
-
- vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
- ret = vb2_qbuf(vq, buf);
- if (!ret)
- v4l2_m2m_try_schedule(m2m_ctx);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(v4l2_m2m_qbuf);
-
-/**
- * v4l2_m2m_dqbuf() - dequeue a source or destination buffer, depending on
- * the type
- */
-int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
- struct v4l2_buffer *buf)
-{
- struct vb2_queue *vq;
-
- vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
- return vb2_dqbuf(vq, buf, file->f_flags & O_NONBLOCK);
-}
-EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);
-
-/**
- * v4l2_m2m_streamon() - turn on streaming for a video queue
- */
-int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
- enum v4l2_buf_type type)
-{
- struct vb2_queue *vq;
- int ret;
-
- vq = v4l2_m2m_get_vq(m2m_ctx, type);
- ret = vb2_streamon(vq, type);
- if (!ret)
- v4l2_m2m_try_schedule(m2m_ctx);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(v4l2_m2m_streamon);
-
-/**
- * v4l2_m2m_streamoff() - turn off streaming for a video queue
- */
-int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
- enum v4l2_buf_type type)
-{
- struct vb2_queue *vq;
-
- vq = v4l2_m2m_get_vq(m2m_ctx, type);
- return vb2_streamoff(vq, type);
-}
-EXPORT_SYMBOL_GPL(v4l2_m2m_streamoff);
-
-/**
- * v4l2_m2m_poll() - poll replacement, for destination buffers only
- *
- * Call from the driver's poll() function. Will poll both queues. If a buffer
- * is available to dequeue (with dqbuf) from the source queue, this will
- * indicate that a non-blocking write can be performed, while read will be
- * returned in case of the destination queue.
- */
-unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
- struct poll_table_struct *wait)
-{
- struct video_device *vfd = video_devdata(file);
- unsigned long req_events = poll_requested_events(wait);
- struct vb2_queue *src_q, *dst_q;
- struct vb2_buffer *src_vb = NULL, *dst_vb = NULL;
- unsigned int rc = 0;
- unsigned long flags;
-
- if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
- struct v4l2_fh *fh = file->private_data;
-
- if (v4l2_event_pending(fh))
- rc = POLLPRI;
- else if (req_events & POLLPRI)
- poll_wait(file, &fh->wait, wait);
- if (!(req_events & (POLLOUT | POLLWRNORM | POLLIN | POLLRDNORM)))
- return rc;
- }
-
- src_q = v4l2_m2m_get_src_vq(m2m_ctx);
- dst_q = v4l2_m2m_get_dst_vq(m2m_ctx);
-
- /*
- * There has to be at least one buffer queued on each queued_list, which
- * means either in driver already or waiting for driver to claim it
- * and start processing.
- */
- if ((!src_q->streaming || list_empty(&src_q->queued_list))
- && (!dst_q->streaming || list_empty(&dst_q->queued_list))) {
- rc |= POLLERR;
- goto end;
- }
-
- if (m2m_ctx->m2m_dev->m2m_ops->unlock)
- m2m_ctx->m2m_dev->m2m_ops->unlock(m2m_ctx->priv);
-
- poll_wait(file, &src_q->done_wq, wait);
- poll_wait(file, &dst_q->done_wq, wait);
-
- if (m2m_ctx->m2m_dev->m2m_ops->lock)
- m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv);
-
- spin_lock_irqsave(&src_q->done_lock, flags);
- if (!list_empty(&src_q->done_list))
- src_vb = list_first_entry(&src_q->done_list, struct vb2_buffer,
- done_entry);
- if (src_vb && (src_vb->state == VB2_BUF_STATE_DONE
- || src_vb->state == VB2_BUF_STATE_ERROR))
- rc |= POLLOUT | POLLWRNORM;
- spin_unlock_irqrestore(&src_q->done_lock, flags);
-
- spin_lock_irqsave(&dst_q->done_lock, flags);
- if (!list_empty(&dst_q->done_list))
- dst_vb = list_first_entry(&dst_q->done_list, struct vb2_buffer,
- done_entry);
- if (dst_vb && (dst_vb->state == VB2_BUF_STATE_DONE
- || dst_vb->state == VB2_BUF_STATE_ERROR))
- rc |= POLLIN | POLLRDNORM;
- spin_unlock_irqrestore(&dst_q->done_lock, flags);
-
-end:
- return rc;
-}
-EXPORT_SYMBOL_GPL(v4l2_m2m_poll);
-
-/**
- * v4l2_m2m_mmap() - source and destination queues-aware mmap multiplexer
- *
- * Call from driver's mmap() function. Will handle mmap() for both queues
- * seamlessly for videobuffer, which will receive normal per-queue offsets and
- * proper videobuf queue pointers. The differentiation is made outside videobuf
- * by adding a predefined offset to buffers from one of the queues and
- * subtracting it before passing it back to videobuf. Only drivers (and
- * thus applications) receive modified offsets.
- */
-int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
- struct vm_area_struct *vma)
-{
- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
- struct vb2_queue *vq;
-
- if (offset < DST_QUEUE_OFF_BASE) {
- vq = v4l2_m2m_get_src_vq(m2m_ctx);
- } else {
- vq = v4l2_m2m_get_dst_vq(m2m_ctx);
- vma->vm_pgoff -= (DST_QUEUE_OFF_BASE >> PAGE_SHIFT);
- }
-
- return vb2_mmap(vq, vma);
-}
-EXPORT_SYMBOL(v4l2_m2m_mmap);
-
-/**
- * v4l2_m2m_init() - initialize per-driver m2m data
- *
- * Usually called from driver's probe() function.
- */
-struct v4l2_m2m_dev *v4l2_m2m_init(struct v4l2_m2m_ops *m2m_ops)
-{
- struct v4l2_m2m_dev *m2m_dev;
-
- if (!m2m_ops)
- return ERR_PTR(-EINVAL);
-
- BUG_ON(!m2m_ops->device_run);
- BUG_ON(!m2m_ops->job_abort);
-
- m2m_dev = kzalloc(sizeof *m2m_dev, GFP_KERNEL);
- if (!m2m_dev)
- return ERR_PTR(-ENOMEM);
-
- m2m_dev->curr_ctx = NULL;
- m2m_dev->m2m_ops = m2m_ops;
- INIT_LIST_HEAD(&m2m_dev->job_queue);
- spin_lock_init(&m2m_dev->job_spinlock);
-
- return m2m_dev;
-}
-EXPORT_SYMBOL_GPL(v4l2_m2m_init);
-
-/**
- * v4l2_m2m_release() - cleans up and frees a m2m_dev structure
- *
- * Usually called from driver's remove() function.
- */
-void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev)
-{
- kfree(m2m_dev);
-}
-EXPORT_SYMBOL_GPL(v4l2_m2m_release);
-
-/**
- * v4l2_m2m_ctx_init() - allocate and initialize a m2m context
- * @priv - driver's instance private data
- * @m2m_dev - a previously initialized m2m_dev struct
- * @vq_init - a callback for queue type-specific initialization function to be
- * used for initializing videobuf_queues
- *
- * Usually called from driver's open() function.
- */
-struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
- void *drv_priv,
- int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq))
-{
- struct v4l2_m2m_ctx *m2m_ctx;
- struct v4l2_m2m_queue_ctx *out_q_ctx, *cap_q_ctx;
- int ret;
-
- m2m_ctx = kzalloc(sizeof *m2m_ctx, GFP_KERNEL);
- if (!m2m_ctx)
- return ERR_PTR(-ENOMEM);
-
- m2m_ctx->priv = drv_priv;
- m2m_ctx->m2m_dev = m2m_dev;
- init_waitqueue_head(&m2m_ctx->finished);
-
- out_q_ctx = &m2m_ctx->out_q_ctx;
- cap_q_ctx = &m2m_ctx->cap_q_ctx;
-
- INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
- INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
- spin_lock_init(&out_q_ctx->rdy_spinlock);
- spin_lock_init(&cap_q_ctx->rdy_spinlock);
-
- INIT_LIST_HEAD(&m2m_ctx->queue);
-
- ret = queue_init(drv_priv, &out_q_ctx->q, &cap_q_ctx->q);
-
- if (ret)
- goto err;
-
- return m2m_ctx;
-err:
- kfree(m2m_ctx);
- return ERR_PTR(ret);
-}
-EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_init);
-
-/**
- * v4l2_m2m_ctx_release() - release m2m context
- *
- * Usually called from driver's release() function.
- */
-void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx)
-{
- struct v4l2_m2m_dev *m2m_dev;
- unsigned long flags;
-
- m2m_dev = m2m_ctx->m2m_dev;
-
- spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
- if (m2m_ctx->job_flags & TRANS_RUNNING) {
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
- m2m_dev->m2m_ops->job_abort(m2m_ctx->priv);
- dprintk("m2m_ctx %p running, will wait to complete", m2m_ctx);
- wait_event(m2m_ctx->finished, !(m2m_ctx->job_flags & TRANS_RUNNING));
- } else if (m2m_ctx->job_flags & TRANS_QUEUED) {
- list_del(&m2m_ctx->queue);
- m2m_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING);
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
- dprintk("m2m_ctx: %p had been on queue and was removed\n",
- m2m_ctx);
- } else {
- /* Do nothing, was not on queue/running */
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
- }
-
- vb2_queue_release(&m2m_ctx->cap_q_ctx.q);
- vb2_queue_release(&m2m_ctx->out_q_ctx.q);
-
- kfree(m2m_ctx);
-}
-EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_release);
-
-/**
- * v4l2_m2m_buf_queue() - add a buffer to the proper ready buffers list.
- *
- * Call from buf_queue(), videobuf_queue_ops callback.
- */
-void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_buffer *vb)
-{
- struct v4l2_m2m_buffer *b = container_of(vb, struct v4l2_m2m_buffer, vb);
- struct v4l2_m2m_queue_ctx *q_ctx;
- unsigned long flags;
-
- q_ctx = get_queue_ctx(m2m_ctx, vb->vb2_queue->type);
- if (!q_ctx)
- return;
-
- spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
- list_add_tail(&b->list, &q_ctx->rdy_queue);
- q_ctx->num_rdy++;
- spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
-}
-EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue);
-
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
deleted file mode 100644
index 9182f81deb5..00000000000
--- a/drivers/media/video/v4l2-subdev.c
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * V4L2 sub-device
- *
- * Copyright (C) 2010 Nokia Corporation
- *
- * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- * Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/ioctl.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-#include <linux/export.h>
-
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-
-static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
-{
-#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
- fh->pad = kzalloc(sizeof(*fh->pad) * sd->entity.num_pads, GFP_KERNEL);
- if (fh->pad == NULL)
- return -ENOMEM;
-#endif
- return 0;
-}
-
-static void subdev_fh_free(struct v4l2_subdev_fh *fh)
-{
-#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
- kfree(fh->pad);
- fh->pad = NULL;
-#endif
-}
-
-static int subdev_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
- struct v4l2_subdev_fh *subdev_fh;
-#if defined(CONFIG_MEDIA_CONTROLLER)
- struct media_entity *entity = NULL;
-#endif
- int ret;
-
- subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL);
- if (subdev_fh == NULL)
- return -ENOMEM;
-
- ret = subdev_fh_init(subdev_fh, sd);
- if (ret) {
- kfree(subdev_fh);
- return ret;
- }
-
- v4l2_fh_init(&subdev_fh->vfh, vdev);
- v4l2_fh_add(&subdev_fh->vfh);
- file->private_data = &subdev_fh->vfh;
-#if defined(CONFIG_MEDIA_CONTROLLER)
- if (sd->v4l2_dev->mdev) {
- entity = media_entity_get(&sd->entity);
- if (!entity) {
- ret = -EBUSY;
- goto err;
- }
- }
-#endif
-
- if (sd->internal_ops && sd->internal_ops->open) {
- ret = sd->internal_ops->open(sd, subdev_fh);
- if (ret < 0)
- goto err;
- }
-
- return 0;
-
-err:
-#if defined(CONFIG_MEDIA_CONTROLLER)
- if (entity)
- media_entity_put(entity);
-#endif
- v4l2_fh_del(&subdev_fh->vfh);
- v4l2_fh_exit(&subdev_fh->vfh);
- subdev_fh_free(subdev_fh);
- kfree(subdev_fh);
-
- return ret;
-}
-
-static int subdev_close(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
- struct v4l2_fh *vfh = file->private_data;
- struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
-
- if (sd->internal_ops && sd->internal_ops->close)
- sd->internal_ops->close(sd, subdev_fh);
-#if defined(CONFIG_MEDIA_CONTROLLER)
- if (sd->v4l2_dev->mdev)
- media_entity_put(&sd->entity);
-#endif
- v4l2_fh_del(vfh);
- v4l2_fh_exit(vfh);
- subdev_fh_free(subdev_fh);
- kfree(subdev_fh);
- file->private_data = NULL;
-
- return 0;
-}
-
-static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
-{
- struct video_device *vdev = video_devdata(file);
- struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
- struct v4l2_fh *vfh = file->private_data;
-#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
- struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
-#endif
-
- switch (cmd) {
- case VIDIOC_QUERYCTRL:
- return v4l2_queryctrl(vfh->ctrl_handler, arg);
-
- case VIDIOC_QUERYMENU:
- return v4l2_querymenu(vfh->ctrl_handler, arg);
-
- case VIDIOC_G_CTRL:
- return v4l2_g_ctrl(vfh->ctrl_handler, arg);
-
- case VIDIOC_S_CTRL:
- return v4l2_s_ctrl(vfh, vfh->ctrl_handler, arg);
-
- case VIDIOC_G_EXT_CTRLS:
- return v4l2_g_ext_ctrls(vfh->ctrl_handler, arg);
-
- case VIDIOC_S_EXT_CTRLS:
- return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, arg);
-
- case VIDIOC_TRY_EXT_CTRLS:
- return v4l2_try_ext_ctrls(vfh->ctrl_handler, arg);
-
- case VIDIOC_DQEVENT:
- if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
- return -ENOIOCTLCMD;
-
- return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);
-
- case VIDIOC_SUBSCRIBE_EVENT:
- return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
-
- case VIDIOC_UNSUBSCRIBE_EVENT:
- return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_DBG_G_REGISTER:
- {
- struct v4l2_dbg_register *p = arg;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- return v4l2_subdev_call(sd, core, g_register, p);
- }
- case VIDIOC_DBG_S_REGISTER:
- {
- struct v4l2_dbg_register *p = arg;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- return v4l2_subdev_call(sd, core, s_register, p);
- }
-#endif
-
- case VIDIOC_LOG_STATUS: {
- int ret;
-
- pr_info("%s: ================= START STATUS =================\n",
- sd->name);
- ret = v4l2_subdev_call(sd, core, log_status);
- pr_info("%s: ================== END STATUS ==================\n",
- sd->name);
- return ret;
- }
-
-#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
- case VIDIOC_SUBDEV_G_FMT: {
- struct v4l2_subdev_format *format = arg;
-
- if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
- format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
-
- if (format->pad >= sd->entity.num_pads)
- return -EINVAL;
-
- return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh, format);
- }
-
- case VIDIOC_SUBDEV_S_FMT: {
- struct v4l2_subdev_format *format = arg;
-
- if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
- format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
-
- if (format->pad >= sd->entity.num_pads)
- return -EINVAL;
-
- return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format);
- }
-
- case VIDIOC_SUBDEV_G_CROP: {
- struct v4l2_subdev_crop *crop = arg;
- struct v4l2_subdev_selection sel;
- int rval;
-
- if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
- crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
-
- if (crop->pad >= sd->entity.num_pads)
- return -EINVAL;
-
- rval = v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
- if (rval != -ENOIOCTLCMD)
- return rval;
-
- memset(&sel, 0, sizeof(sel));
- sel.which = crop->which;
- sel.pad = crop->pad;
- sel.target = V4L2_SEL_TGT_CROP;
-
- rval = v4l2_subdev_call(
- sd, pad, get_selection, subdev_fh, &sel);
-
- crop->rect = sel.r;
-
- return rval;
- }
-
- case VIDIOC_SUBDEV_S_CROP: {
- struct v4l2_subdev_crop *crop = arg;
- struct v4l2_subdev_selection sel;
- int rval;
-
- if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
- crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
-
- if (crop->pad >= sd->entity.num_pads)
- return -EINVAL;
-
- rval = v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
- if (rval != -ENOIOCTLCMD)
- return rval;
-
- memset(&sel, 0, sizeof(sel));
- sel.which = crop->which;
- sel.pad = crop->pad;
- sel.target = V4L2_SEL_TGT_CROP;
- sel.r = crop->rect;
-
- rval = v4l2_subdev_call(
- sd, pad, set_selection, subdev_fh, &sel);
-
- crop->rect = sel.r;
-
- return rval;
- }
-
- case VIDIOC_SUBDEV_ENUM_MBUS_CODE: {
- struct v4l2_subdev_mbus_code_enum *code = arg;
-
- if (code->pad >= sd->entity.num_pads)
- return -EINVAL;
-
- return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh,
- code);
- }
-
- case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: {
- struct v4l2_subdev_frame_size_enum *fse = arg;
-
- if (fse->pad >= sd->entity.num_pads)
- return -EINVAL;
-
- return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh,
- fse);
- }
-
- case VIDIOC_SUBDEV_G_FRAME_INTERVAL:
- return v4l2_subdev_call(sd, video, g_frame_interval, arg);
-
- case VIDIOC_SUBDEV_S_FRAME_INTERVAL:
- return v4l2_subdev_call(sd, video, s_frame_interval, arg);
-
- case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: {
- struct v4l2_subdev_frame_interval_enum *fie = arg;
-
- if (fie->pad >= sd->entity.num_pads)
- return -EINVAL;
-
- return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh,
- fie);
- }
-
- case VIDIOC_SUBDEV_G_SELECTION: {
- struct v4l2_subdev_selection *sel = arg;
-
- if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
- sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
-
- if (sel->pad >= sd->entity.num_pads)
- return -EINVAL;
-
- return v4l2_subdev_call(
- sd, pad, get_selection, subdev_fh, sel);
- }
-
- case VIDIOC_SUBDEV_S_SELECTION: {
- struct v4l2_subdev_selection *sel = arg;
-
- if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
- sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
-
- if (sel->pad >= sd->entity.num_pads)
- return -EINVAL;
-
- return v4l2_subdev_call(
- sd, pad, set_selection, subdev_fh, sel);
- }
-#endif
- default:
- return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
- }
-
- return 0;
-}
-
-static long subdev_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- return video_usercopy(file, cmd, arg, subdev_do_ioctl);
-}
-
-static unsigned int subdev_poll(struct file *file, poll_table *wait)
-{
- struct video_device *vdev = video_devdata(file);
- struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
- struct v4l2_fh *fh = file->private_data;
-
- if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
- return POLLERR;
-
- poll_wait(file, &fh->wait, wait);
-
- if (v4l2_event_pending(fh))
- return POLLPRI;
-
- return 0;
-}
-
-const struct v4l2_file_operations v4l2_subdev_fops = {
- .owner = THIS_MODULE,
- .open = subdev_open,
- .unlocked_ioctl = subdev_ioctl,
- .release = subdev_close,
- .poll = subdev_poll,
-};
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
- struct media_link *link,
- struct v4l2_subdev_format *source_fmt,
- struct v4l2_subdev_format *sink_fmt)
-{
- if (source_fmt->format.width != sink_fmt->format.width
- || source_fmt->format.height != sink_fmt->format.height
- || source_fmt->format.code != sink_fmt->format.code)
- return -EINVAL;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate_default);
-
-static int
-v4l2_subdev_link_validate_get_format(struct media_pad *pad,
- struct v4l2_subdev_format *fmt)
-{
- switch (media_entity_type(pad->entity)) {
- case MEDIA_ENT_T_V4L2_SUBDEV:
- fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
- fmt->pad = pad->index;
- return v4l2_subdev_call(media_entity_to_v4l2_subdev(
- pad->entity),
- pad, get_fmt, NULL, fmt);
- default:
- WARN(1, "Driver bug! Wrong media entity type %d, entity %s\n",
- media_entity_type(pad->entity), pad->entity->name);
- /* Fall through */
- case MEDIA_ENT_T_DEVNODE_V4L:
- return -EINVAL;
- }
-}
-
-int v4l2_subdev_link_validate(struct media_link *link)
-{
- struct v4l2_subdev *sink;
- struct v4l2_subdev_format sink_fmt, source_fmt;
- int rval;
-
- rval = v4l2_subdev_link_validate_get_format(
- link->source, &source_fmt);
- if (rval < 0)
- return 0;
-
- rval = v4l2_subdev_link_validate_get_format(
- link->sink, &sink_fmt);
- if (rval < 0)
- return 0;
-
- sink = media_entity_to_v4l2_subdev(link->sink->entity);
-
- rval = v4l2_subdev_call(sink, pad, link_validate, link,
- &source_fmt, &sink_fmt);
- if (rval != -ENOIOCTLCMD)
- return rval;
-
- return v4l2_subdev_link_validate_default(
- sink, link, &source_fmt, &sink_fmt);
-}
-EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate);
-#endif /* CONFIG_MEDIA_CONTROLLER */
-
-void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)
-{
- INIT_LIST_HEAD(&sd->list);
- BUG_ON(!ops);
- sd->ops = ops;
- sd->v4l2_dev = NULL;
- sd->flags = 0;
- sd->name[0] = '\0';
- sd->grp_id = 0;
- sd->dev_priv = NULL;
- sd->host_priv = NULL;
-#if defined(CONFIG_MEDIA_CONTROLLER)
- sd->entity.name = sd->name;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-#endif
-}
-EXPORT_SYMBOL(v4l2_subdev_init);
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
deleted file mode 100644
index eb404c2ce27..00000000000
--- a/drivers/media/video/via-camera.c
+++ /dev/null
@@ -1,1514 +0,0 @@
-/*
- * Driver for the VIA Chrome integrated camera controller.
- *
- * Copyright 2009,2010 Jonathan Corbet <corbet@lwn.net>
- * Distributable under the terms of the GNU General Public License, version 2
- *
- * This work was supported by the One Laptop Per Child project
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/pci.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/ov7670.h>
-#include <media/videobuf-dma-sg.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/pm_qos.h>
-#include <linux/via-core.h>
-#include <linux/via-gpio.h>
-#include <linux/via_i2c.h>
-#include <asm/olpc.h>
-
-#include "via-camera.h"
-
-MODULE_ALIAS("platform:viafb-camera");
-MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
-MODULE_DESCRIPTION("VIA framebuffer-based camera controller driver");
-MODULE_LICENSE("GPL");
-
-static bool flip_image;
-module_param(flip_image, bool, 0444);
-MODULE_PARM_DESC(flip_image,
- "If set, the sensor will be instructed to flip the image "
- "vertically.");
-
-static bool override_serial;
-module_param(override_serial, bool, 0444);
-MODULE_PARM_DESC(override_serial,
- "The camera driver will normally refuse to load if "
- "the XO 1.5 serial port is enabled. Set this option "
- "to force-enable the camera.");
-
-/*
- * Basic window sizes.
- */
-#define VGA_WIDTH 640
-#define VGA_HEIGHT 480
-#define QCIF_WIDTH 176
-#define QCIF_HEIGHT 144
-
-/*
- * The structure describing our camera.
- */
-enum viacam_opstate { S_IDLE = 0, S_RUNNING = 1 };
-
-struct via_camera {
- struct v4l2_device v4l2_dev;
- struct video_device vdev;
- struct v4l2_subdev *sensor;
- struct platform_device *platdev;
- struct viafb_dev *viadev;
- struct mutex lock;
- enum viacam_opstate opstate;
- unsigned long flags;
- struct pm_qos_request qos_request;
- /*
- * GPIO info for power/reset management
- */
- int power_gpio;
- int reset_gpio;
- /*
- * I/O memory stuff.
- */
- void __iomem *mmio; /* Where the registers live */
- void __iomem *fbmem; /* Frame buffer memory */
- u32 fb_offset; /* Reserved memory offset (FB) */
- /*
- * Capture buffers and related. The controller supports
- * up to three, so that's what we have here. These buffers
- * live in frame buffer memory, so we don't call them "DMA".
- */
- unsigned int cb_offsets[3]; /* offsets into fb mem */
- u8 *cb_addrs[3]; /* Kernel-space addresses */
- int n_cap_bufs; /* How many are we using? */
- int next_buf;
- struct videobuf_queue vb_queue;
- struct list_head buffer_queue; /* prot. by reg_lock */
- /*
- * User tracking.
- */
- int users;
- struct file *owner;
- /*
- * Video format information. sensor_format is kept in a form
- * that we can use to pass to the sensor. We always run the
- * sensor in VGA resolution, though, and let the controller
- * downscale things if need be. So we keep the "real*
- * dimensions separately.
- */
- struct v4l2_pix_format sensor_format;
- struct v4l2_pix_format user_format;
- enum v4l2_mbus_pixelcode mbus_code;
-};
-
-/*
- * Yes, this is a hack, but there's only going to be one of these
- * on any system we know of.
- */
-static struct via_camera *via_cam_info;
-
-/*
- * Flag values, manipulated with bitops
- */
-#define CF_DMA_ACTIVE 0 /* A frame is incoming */
-#define CF_CONFIG_NEEDED 1 /* Must configure hardware */
-
-
-/*
- * Nasty ugly v4l2 boilerplate.
- */
-#define sensor_call(cam, optype, func, args...) \
- v4l2_subdev_call(cam->sensor, optype, func, ##args)
-
-/*
- * Debugging and related.
- */
-#define cam_err(cam, fmt, arg...) \
- dev_err(&(cam)->platdev->dev, fmt, ##arg);
-#define cam_warn(cam, fmt, arg...) \
- dev_warn(&(cam)->platdev->dev, fmt, ##arg);
-#define cam_dbg(cam, fmt, arg...) \
- dev_dbg(&(cam)->platdev->dev, fmt, ##arg);
-
-/*
- * Format handling. This is ripped almost directly from Hans's changes
- * to cafe_ccic.c. It's a little unfortunate; until this change, we
- * didn't need to know anything about the format except its byte depth;
- * now this information must be managed at this level too.
- */
-static struct via_format {
- __u8 *desc;
- __u32 pixelformat;
- int bpp; /* Bytes per pixel */
- enum v4l2_mbus_pixelcode mbus_code;
-} via_formats[] = {
- {
- .desc = "YUYV 4:2:2",
- .pixelformat = V4L2_PIX_FMT_YUYV,
- .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
- .bpp = 2,
- },
- /* RGB444 and Bayer should be doable, but have never been
- tested with this driver. RGB565 seems to work at the default
- resolution, but results in color corruption when being scaled by
- viacam_set_scaled(), and is disabled as a result. */
-};
-#define N_VIA_FMTS ARRAY_SIZE(via_formats)
-
-static struct via_format *via_find_format(u32 pixelformat)
-{
- unsigned i;
-
- for (i = 0; i < N_VIA_FMTS; i++)
- if (via_formats[i].pixelformat == pixelformat)
- return via_formats + i;
- /* Not found? Then return the first format. */
- return via_formats;
-}
-
-
-/*--------------------------------------------------------------------------*/
-/*
- * Sensor power/reset management. This piece is OLPC-specific for
- * sure; other configurations will have things connected differently.
- */
-static int via_sensor_power_setup(struct via_camera *cam)
-{
- int ret;
-
- cam->power_gpio = viafb_gpio_lookup("VGPIO3");
- cam->reset_gpio = viafb_gpio_lookup("VGPIO2");
- if (cam->power_gpio < 0 || cam->reset_gpio < 0) {
- dev_err(&cam->platdev->dev, "Unable to find GPIO lines\n");
- return -EINVAL;
- }
- ret = gpio_request(cam->power_gpio, "viafb-camera");
- if (ret) {
- dev_err(&cam->platdev->dev, "Unable to request power GPIO\n");
- return ret;
- }
- ret = gpio_request(cam->reset_gpio, "viafb-camera");
- if (ret) {
- dev_err(&cam->platdev->dev, "Unable to request reset GPIO\n");
- gpio_free(cam->power_gpio);
- return ret;
- }
- gpio_direction_output(cam->power_gpio, 0);
- gpio_direction_output(cam->reset_gpio, 0);
- return 0;
-}
-
-/*
- * Power up the sensor and perform the reset dance.
- */
-static void via_sensor_power_up(struct via_camera *cam)
-{
- gpio_set_value(cam->power_gpio, 1);
- gpio_set_value(cam->reset_gpio, 0);
- msleep(20); /* Probably excessive */
- gpio_set_value(cam->reset_gpio, 1);
- msleep(20);
-}
-
-static void via_sensor_power_down(struct via_camera *cam)
-{
- gpio_set_value(cam->power_gpio, 0);
- gpio_set_value(cam->reset_gpio, 0);
-}
-
-
-static void via_sensor_power_release(struct via_camera *cam)
-{
- via_sensor_power_down(cam);
- gpio_free(cam->power_gpio);
- gpio_free(cam->reset_gpio);
-}
-
-/* --------------------------------------------------------------------------*/
-/* Sensor ops */
-
-/*
- * Manage the ov7670 "flip" bit, which needs special help.
- */
-static int viacam_set_flip(struct via_camera *cam)
-{
- struct v4l2_control ctrl;
-
- memset(&ctrl, 0, sizeof(ctrl));
- ctrl.id = V4L2_CID_VFLIP;
- ctrl.value = flip_image;
- return sensor_call(cam, core, s_ctrl, &ctrl);
-}
-
-/*
- * Configure the sensor. It's up to the caller to ensure
- * that the camera is in the correct operating state.
- */
-static int viacam_configure_sensor(struct via_camera *cam)
-{
- struct v4l2_mbus_framefmt mbus_fmt;
- int ret;
-
- v4l2_fill_mbus_format(&mbus_fmt, &cam->sensor_format, cam->mbus_code);
- ret = sensor_call(cam, core, init, 0);
- if (ret == 0)
- ret = sensor_call(cam, video, s_mbus_fmt, &mbus_fmt);
- /*
- * OV7670 does weird things if flip is set *before* format...
- */
- if (ret == 0)
- ret = viacam_set_flip(cam);
- return ret;
-}
-
-
-
-/* --------------------------------------------------------------------------*/
-/*
- * Some simple register accessors; they assume that the lock is held.
- *
- * Should we want to support the second capture engine, we could
- * hide the register difference by adding 0x1000 to registers in the
- * 0x300-350 range.
- */
-static inline void viacam_write_reg(struct via_camera *cam,
- int reg, int value)
-{
- iowrite32(value, cam->mmio + reg);
-}
-
-static inline int viacam_read_reg(struct via_camera *cam, int reg)
-{
- return ioread32(cam->mmio + reg);
-}
-
-static inline void viacam_write_reg_mask(struct via_camera *cam,
- int reg, int value, int mask)
-{
- int tmp = viacam_read_reg(cam, reg);
-
- tmp = (tmp & ~mask) | (value & mask);
- viacam_write_reg(cam, reg, tmp);
-}
-
-
-/* --------------------------------------------------------------------------*/
-/* Interrupt management and handling */
-
-static irqreturn_t viacam_quick_irq(int irq, void *data)
-{
- struct via_camera *cam = data;
- irqreturn_t ret = IRQ_NONE;
- int icv;
-
- /*
- * All we do here is to clear the interrupts and tell
- * the handler thread to wake up.
- */
- spin_lock(&cam->viadev->reg_lock);
- icv = viacam_read_reg(cam, VCR_INTCTRL);
- if (icv & VCR_IC_EAV) {
- icv |= VCR_IC_EAV|VCR_IC_EVBI|VCR_IC_FFULL;
- viacam_write_reg(cam, VCR_INTCTRL, icv);
- ret = IRQ_WAKE_THREAD;
- }
- spin_unlock(&cam->viadev->reg_lock);
- return ret;
-}
-
-/*
- * Find the next videobuf buffer which has somebody waiting on it.
- */
-static struct videobuf_buffer *viacam_next_buffer(struct via_camera *cam)
-{
- unsigned long flags;
- struct videobuf_buffer *buf = NULL;
-
- spin_lock_irqsave(&cam->viadev->reg_lock, flags);
- if (cam->opstate != S_RUNNING)
- goto out;
- if (list_empty(&cam->buffer_queue))
- goto out;
- buf = list_entry(cam->buffer_queue.next, struct videobuf_buffer, queue);
- if (!waitqueue_active(&buf->done)) {/* Nobody waiting */
- buf = NULL;
- goto out;
- }
- list_del(&buf->queue);
- buf->state = VIDEOBUF_ACTIVE;
-out:
- spin_unlock_irqrestore(&cam->viadev->reg_lock, flags);
- return buf;
-}
-
-/*
- * The threaded IRQ handler.
- */
-static irqreturn_t viacam_irq(int irq, void *data)
-{
- int bufn;
- struct videobuf_buffer *vb;
- struct via_camera *cam = data;
- struct videobuf_dmabuf *vdma;
-
- /*
- * If there is no place to put the data frame, don't bother
- * with anything else.
- */
- vb = viacam_next_buffer(cam);
- if (vb == NULL)
- goto done;
- /*
- * Figure out which buffer we just completed.
- */
- bufn = (viacam_read_reg(cam, VCR_INTCTRL) & VCR_IC_ACTBUF) >> 3;
- bufn -= 1;
- if (bufn < 0)
- bufn = cam->n_cap_bufs - 1;
- /*
- * Copy over the data and let any waiters know.
- */
- vdma = videobuf_to_dma(vb);
- viafb_dma_copy_out_sg(cam->cb_offsets[bufn], vdma->sglist, vdma->sglen);
- vb->state = VIDEOBUF_DONE;
- vb->size = cam->user_format.sizeimage;
- wake_up(&vb->done);
-done:
- return IRQ_HANDLED;
-}
-
-
-/*
- * These functions must mess around with the general interrupt
- * control register, which is relevant to much more than just the
- * camera. Nothing else uses interrupts, though, as of this writing.
- * Should that situation change, we'll have to improve support at
- * the via-core level.
- */
-static void viacam_int_enable(struct via_camera *cam)
-{
- viacam_write_reg(cam, VCR_INTCTRL,
- VCR_IC_INTEN|VCR_IC_EAV|VCR_IC_EVBI|VCR_IC_FFULL);
- viafb_irq_enable(VDE_I_C0AVEN);
-}
-
-static void viacam_int_disable(struct via_camera *cam)
-{
- viafb_irq_disable(VDE_I_C0AVEN);
- viacam_write_reg(cam, VCR_INTCTRL, 0);
-}
-
-
-
-/* --------------------------------------------------------------------------*/
-/* Controller operations */
-
-/*
- * Set up our capture buffers in framebuffer memory.
- */
-static int viacam_ctlr_cbufs(struct via_camera *cam)
-{
- int nbuf = cam->viadev->camera_fbmem_size/cam->sensor_format.sizeimage;
- int i;
- unsigned int offset;
-
- /*
- * See how many buffers we can work with.
- */
- if (nbuf >= 3) {
- cam->n_cap_bufs = 3;
- viacam_write_reg_mask(cam, VCR_CAPINTC, VCR_CI_3BUFS,
- VCR_CI_3BUFS);
- } else if (nbuf == 2) {
- cam->n_cap_bufs = 2;
- viacam_write_reg_mask(cam, VCR_CAPINTC, 0, VCR_CI_3BUFS);
- } else {
- cam_warn(cam, "Insufficient frame buffer memory\n");
- return -ENOMEM;
- }
- /*
- * Set them up.
- */
- offset = cam->fb_offset;
- for (i = 0; i < cam->n_cap_bufs; i++) {
- cam->cb_offsets[i] = offset;
- cam->cb_addrs[i] = cam->fbmem + offset;
- viacam_write_reg(cam, VCR_VBUF1 + i*4, offset & VCR_VBUF_MASK);
- offset += cam->sensor_format.sizeimage;
- }
- return 0;
-}
-
-/*
- * Set the scaling register for downscaling the image.
- *
- * This register works like this... Vertical scaling is enabled
- * by bit 26; if that bit is set, downscaling is controlled by the
- * value in bits 16:25. Those bits are divided by 1024 to get
- * the scaling factor; setting just bit 25 thus cuts the height
- * in half.
- *
- * Horizontal scaling works about the same, but it's enabled by
- * bit 11, with bits 0:10 giving the numerator of a fraction
- * (over 2048) for the scaling value.
- *
- * This function is naive in that, if the user departs from
- * the 3x4 VGA scaling factor, the image will distort. We
- * could work around that if it really seemed important.
- */
-static void viacam_set_scale(struct via_camera *cam)
-{
- unsigned int avscale;
- int sf;
-
- if (cam->user_format.width == VGA_WIDTH)
- avscale = 0;
- else {
- sf = (cam->user_format.width*2048)/VGA_WIDTH;
- avscale = VCR_AVS_HEN | sf;
- }
- if (cam->user_format.height < VGA_HEIGHT) {
- sf = (1024*cam->user_format.height)/VGA_HEIGHT;
- avscale |= VCR_AVS_VEN | (sf << 16);
- }
- viacam_write_reg(cam, VCR_AVSCALE, avscale);
-}
-
-
-/*
- * Configure image-related information into the capture engine.
- */
-static void viacam_ctlr_image(struct via_camera *cam)
-{
- int cicreg;
-
- /*
- * Disable clock before messing with stuff - from the via
- * sample driver.
- */
- viacam_write_reg(cam, VCR_CAPINTC, ~(VCR_CI_ENABLE|VCR_CI_CLKEN));
- /*
- * Set up the controller for VGA resolution, modulo magic
- * offsets from the via sample driver.
- */
- viacam_write_reg(cam, VCR_HORRANGE, 0x06200120);
- viacam_write_reg(cam, VCR_VERTRANGE, 0x01de0000);
- viacam_set_scale(cam);
- /*
- * Image size info.
- */
- viacam_write_reg(cam, VCR_MAXDATA,
- (cam->sensor_format.height << 16) |
- (cam->sensor_format.bytesperline >> 3));
- viacam_write_reg(cam, VCR_MAXVBI, 0);
- viacam_write_reg(cam, VCR_VSTRIDE,
- cam->user_format.bytesperline & VCR_VS_STRIDE);
- /*
- * Set up the capture interface control register,
- * everything but the "go" bit.
- *
- * The FIFO threshold is a bit of a magic number; 8 is what
- * VIA's sample code uses.
- */
- cicreg = VCR_CI_CLKEN |
- 0x08000000 | /* FIFO threshold */
- VCR_CI_FLDINV | /* OLPC-specific? */
- VCR_CI_VREFINV | /* OLPC-specific? */
- VCR_CI_DIBOTH | /* Capture both fields */
- VCR_CI_CCIR601_8;
- if (cam->n_cap_bufs == 3)
- cicreg |= VCR_CI_3BUFS;
- /*
- * YUV formats need different byte swapping than RGB.
- */
- if (cam->user_format.pixelformat == V4L2_PIX_FMT_YUYV)
- cicreg |= VCR_CI_YUYV;
- else
- cicreg |= VCR_CI_UYVY;
- viacam_write_reg(cam, VCR_CAPINTC, cicreg);
-}
-
-
-static int viacam_config_controller(struct via_camera *cam)
-{
- int ret;
- unsigned long flags;
-
- spin_lock_irqsave(&cam->viadev->reg_lock, flags);
- ret = viacam_ctlr_cbufs(cam);
- if (!ret)
- viacam_ctlr_image(cam);
- spin_unlock_irqrestore(&cam->viadev->reg_lock, flags);
- clear_bit(CF_CONFIG_NEEDED, &cam->flags);
- return ret;
-}
-
-/*
- * Make it start grabbing data.
- */
-static void viacam_start_engine(struct via_camera *cam)
-{
- spin_lock_irq(&cam->viadev->reg_lock);
- cam->next_buf = 0;
- viacam_write_reg_mask(cam, VCR_CAPINTC, VCR_CI_ENABLE, VCR_CI_ENABLE);
- viacam_int_enable(cam);
- (void) viacam_read_reg(cam, VCR_CAPINTC); /* Force post */
- cam->opstate = S_RUNNING;
- spin_unlock_irq(&cam->viadev->reg_lock);
-}
-
-
-static void viacam_stop_engine(struct via_camera *cam)
-{
- spin_lock_irq(&cam->viadev->reg_lock);
- viacam_int_disable(cam);
- viacam_write_reg_mask(cam, VCR_CAPINTC, 0, VCR_CI_ENABLE);
- (void) viacam_read_reg(cam, VCR_CAPINTC); /* Force post */
- cam->opstate = S_IDLE;
- spin_unlock_irq(&cam->viadev->reg_lock);
-}
-
-
-/* --------------------------------------------------------------------------*/
-/* Videobuf callback ops */
-
-/*
- * buffer_setup. The purpose of this one would appear to be to tell
- * videobuf how big a single image is. It's also evidently up to us
- * to put some sort of limit on the maximum number of buffers allowed.
- */
-static int viacam_vb_buf_setup(struct videobuf_queue *q,
- unsigned int *count, unsigned int *size)
-{
- struct via_camera *cam = q->priv_data;
-
- *size = cam->user_format.sizeimage;
- if (*count == 0 || *count > 6) /* Arbitrary number */
- *count = 6;
- return 0;
-}
-
-/*
- * Prepare a buffer.
- */
-static int viacam_vb_buf_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb, enum v4l2_field field)
-{
- struct via_camera *cam = q->priv_data;
-
- vb->size = cam->user_format.sizeimage;
- vb->width = cam->user_format.width; /* bytesperline???? */
- vb->height = cam->user_format.height;
- vb->field = field;
- if (vb->state == VIDEOBUF_NEEDS_INIT) {
- int ret = videobuf_iolock(q, vb, NULL);
- if (ret)
- return ret;
- }
- vb->state = VIDEOBUF_PREPARED;
- return 0;
-}
-
-/*
- * We've got a buffer to put data into.
- *
- * FIXME: check for a running engine and valid buffers?
- */
-static void viacam_vb_buf_queue(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- struct via_camera *cam = q->priv_data;
-
- /*
- * Note that videobuf holds the lock when it calls
- * us, so we need not (indeed, cannot) take it here.
- */
- vb->state = VIDEOBUF_QUEUED;
- list_add_tail(&vb->queue, &cam->buffer_queue);
-}
-
-/*
- * Free a buffer.
- */
-static void viacam_vb_buf_release(struct videobuf_queue *q,
- struct videobuf_buffer *vb)
-{
- struct via_camera *cam = q->priv_data;
-
- videobuf_dma_unmap(&cam->platdev->dev, videobuf_to_dma(vb));
- videobuf_dma_free(videobuf_to_dma(vb));
- vb->state = VIDEOBUF_NEEDS_INIT;
-}
-
-static const struct videobuf_queue_ops viacam_vb_ops = {
- .buf_setup = viacam_vb_buf_setup,
- .buf_prepare = viacam_vb_buf_prepare,
- .buf_queue = viacam_vb_buf_queue,
- .buf_release = viacam_vb_buf_release,
-};
-
-/* --------------------------------------------------------------------------*/
-/* File operations */
-
-static int viacam_open(struct file *filp)
-{
- struct via_camera *cam = video_drvdata(filp);
-
- filp->private_data = cam;
- /*
- * Note the new user. If this is the first one, we'll also
- * need to power up the sensor.
- */
- mutex_lock(&cam->lock);
- if (cam->users == 0) {
- int ret = viafb_request_dma();
-
- if (ret) {
- mutex_unlock(&cam->lock);
- return ret;
- }
- via_sensor_power_up(cam);
- set_bit(CF_CONFIG_NEEDED, &cam->flags);
- /*
- * Hook into videobuf. Evidently this cannot fail.
- */
- videobuf_queue_sg_init(&cam->vb_queue, &viacam_vb_ops,
- &cam->platdev->dev, &cam->viadev->reg_lock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
- sizeof(struct videobuf_buffer), cam, NULL);
- }
- (cam->users)++;
- mutex_unlock(&cam->lock);
- return 0;
-}
-
-static int viacam_release(struct file *filp)
-{
- struct via_camera *cam = video_drvdata(filp);
-
- mutex_lock(&cam->lock);
- (cam->users)--;
- /*
- * If the "owner" is closing, shut down any ongoing
- * operations.
- */
- if (filp == cam->owner) {
- videobuf_stop(&cam->vb_queue);
- /*
- * We don't hold the spinlock here, but, if release()
- * is being called by the owner, nobody else will
- * be changing the state. And an extra stop would
- * not hurt anyway.
- */
- if (cam->opstate != S_IDLE)
- viacam_stop_engine(cam);
- cam->owner = NULL;
- }
- /*
- * Last one out needs to turn out the lights.
- */
- if (cam->users == 0) {
- videobuf_mmap_free(&cam->vb_queue);
- via_sensor_power_down(cam);
- viafb_release_dma();
- }
- mutex_unlock(&cam->lock);
- return 0;
-}
-
-/*
- * Read a frame from the device.
- */
-static ssize_t viacam_read(struct file *filp, char __user *buffer,
- size_t len, loff_t *pos)
-{
- struct via_camera *cam = video_drvdata(filp);
- int ret;
-
- mutex_lock(&cam->lock);
- /*
- * Enforce the V4l2 "only one owner gets to read data" rule.
- */
- if (cam->owner && cam->owner != filp) {
- ret = -EBUSY;
- goto out_unlock;
- }
- cam->owner = filp;
- /*
- * Do we need to configure the hardware?
- */
- if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) {
- ret = viacam_configure_sensor(cam);
- if (!ret)
- ret = viacam_config_controller(cam);
- if (ret)
- goto out_unlock;
- }
- /*
- * Fire up the capture engine, then have videobuf do
- * the heavy lifting. Someday it would be good to avoid
- * stopping and restarting the engine each time.
- */
- INIT_LIST_HEAD(&cam->buffer_queue);
- viacam_start_engine(cam);
- ret = videobuf_read_stream(&cam->vb_queue, buffer, len, pos, 0,
- filp->f_flags & O_NONBLOCK);
- viacam_stop_engine(cam);
- /* videobuf_stop() ?? */
-
-out_unlock:
- mutex_unlock(&cam->lock);
- return ret;
-}
-
-
-static unsigned int viacam_poll(struct file *filp, struct poll_table_struct *pt)
-{
- struct via_camera *cam = video_drvdata(filp);
-
- return videobuf_poll_stream(filp, &cam->vb_queue, pt);
-}
-
-
-static int viacam_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- struct via_camera *cam = video_drvdata(filp);
-
- return videobuf_mmap_mapper(&cam->vb_queue, vma);
-}
-
-
-
-static const struct v4l2_file_operations viacam_fops = {
- .owner = THIS_MODULE,
- .open = viacam_open,
- .release = viacam_release,
- .read = viacam_read,
- .poll = viacam_poll,
- .mmap = viacam_mmap,
- .unlocked_ioctl = video_ioctl2,
-};
-
-/*----------------------------------------------------------------------------*/
-/*
- * The long list of v4l2 ioctl ops
- */
-
-static int viacam_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *ident)
-{
- struct via_camera *cam = priv;
-
- ident->ident = V4L2_IDENT_NONE;
- ident->revision = 0;
- if (v4l2_chip_match_host(&ident->match)) {
- ident->ident = V4L2_IDENT_VIA_VX855;
- return 0;
- }
- return sensor_call(cam, core, g_chip_ident, ident);
-}
-
-/*
- * Control ops are passed through to the sensor.
- */
-static int viacam_queryctrl(struct file *filp, void *priv,
- struct v4l2_queryctrl *qc)
-{
- struct via_camera *cam = priv;
- int ret;
-
- mutex_lock(&cam->lock);
- ret = sensor_call(cam, core, queryctrl, qc);
- mutex_unlock(&cam->lock);
- return ret;
-}
-
-
-static int viacam_g_ctrl(struct file *filp, void *priv,
- struct v4l2_control *ctrl)
-{
- struct via_camera *cam = priv;
- int ret;
-
- mutex_lock(&cam->lock);
- ret = sensor_call(cam, core, g_ctrl, ctrl);
- mutex_unlock(&cam->lock);
- return ret;
-}
-
-
-static int viacam_s_ctrl(struct file *filp, void *priv,
- struct v4l2_control *ctrl)
-{
- struct via_camera *cam = priv;
- int ret;
-
- mutex_lock(&cam->lock);
- ret = sensor_call(cam, core, s_ctrl, ctrl);
- mutex_unlock(&cam->lock);
- return ret;
-}
-
-/*
- * Only one input.
- */
-static int viacam_enum_input(struct file *filp, void *priv,
- struct v4l2_input *input)
-{
- if (input->index != 0)
- return -EINVAL;
-
- input->type = V4L2_INPUT_TYPE_CAMERA;
- input->std = V4L2_STD_ALL; /* Not sure what should go here */
- strcpy(input->name, "Camera");
- return 0;
-}
-
-static int viacam_g_input(struct file *filp, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int viacam_s_input(struct file *filp, void *priv, unsigned int i)
-{
- if (i != 0)
- return -EINVAL;
- return 0;
-}
-
-static int viacam_s_std(struct file *filp, void *priv, v4l2_std_id *std)
-{
- return 0;
-}
-
-/*
- * Video format stuff. Here is our default format until
- * user space messes with things.
- */
-static const struct v4l2_pix_format viacam_def_pix_format = {
- .width = VGA_WIDTH,
- .height = VGA_HEIGHT,
- .pixelformat = V4L2_PIX_FMT_YUYV,
- .field = V4L2_FIELD_NONE,
- .bytesperline = VGA_WIDTH * 2,
- .sizeimage = VGA_WIDTH * VGA_HEIGHT * 2,
-};
-
-static const enum v4l2_mbus_pixelcode via_def_mbus_code = V4L2_MBUS_FMT_YUYV8_2X8;
-
-static int viacam_enum_fmt_vid_cap(struct file *filp, void *priv,
- struct v4l2_fmtdesc *fmt)
-{
- if (fmt->index >= N_VIA_FMTS)
- return -EINVAL;
- strlcpy(fmt->description, via_formats[fmt->index].desc,
- sizeof(fmt->description));
- fmt->pixelformat = via_formats[fmt->index].pixelformat;
- return 0;
-}
-
-/*
- * Figure out proper image dimensions, but always force the
- * sensor to VGA.
- */
-static void viacam_fmt_pre(struct v4l2_pix_format *userfmt,
- struct v4l2_pix_format *sensorfmt)
-{
- *sensorfmt = *userfmt;
- if (userfmt->width < QCIF_WIDTH || userfmt->height < QCIF_HEIGHT) {
- userfmt->width = QCIF_WIDTH;
- userfmt->height = QCIF_HEIGHT;
- }
- if (userfmt->width > VGA_WIDTH || userfmt->height > VGA_HEIGHT) {
- userfmt->width = VGA_WIDTH;
- userfmt->height = VGA_HEIGHT;
- }
- sensorfmt->width = VGA_WIDTH;
- sensorfmt->height = VGA_HEIGHT;
-}
-
-static void viacam_fmt_post(struct v4l2_pix_format *userfmt,
- struct v4l2_pix_format *sensorfmt)
-{
- struct via_format *f = via_find_format(userfmt->pixelformat);
-
- sensorfmt->bytesperline = sensorfmt->width * f->bpp;
- sensorfmt->sizeimage = sensorfmt->height * sensorfmt->bytesperline;
- userfmt->pixelformat = sensorfmt->pixelformat;
- userfmt->field = sensorfmt->field;
- userfmt->bytesperline = 2 * userfmt->width;
- userfmt->sizeimage = userfmt->bytesperline * userfmt->height;
-}
-
-
-/*
- * The real work of figuring out a workable format.
- */
-static int viacam_do_try_fmt(struct via_camera *cam,
- struct v4l2_pix_format *upix, struct v4l2_pix_format *spix)
-{
- int ret;
- struct v4l2_mbus_framefmt mbus_fmt;
- struct via_format *f = via_find_format(upix->pixelformat);
-
- upix->pixelformat = f->pixelformat;
- viacam_fmt_pre(upix, spix);
- v4l2_fill_mbus_format(&mbus_fmt, spix, f->mbus_code);
- ret = sensor_call(cam, video, try_mbus_fmt, &mbus_fmt);
- v4l2_fill_pix_format(spix, &mbus_fmt);
- viacam_fmt_post(upix, spix);
- return ret;
-}
-
-
-
-static int viacam_try_fmt_vid_cap(struct file *filp, void *priv,
- struct v4l2_format *fmt)
-{
- struct via_camera *cam = priv;
- struct v4l2_format sfmt;
- int ret;
-
- mutex_lock(&cam->lock);
- ret = viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix);
- mutex_unlock(&cam->lock);
- return ret;
-}
-
-
-static int viacam_g_fmt_vid_cap(struct file *filp, void *priv,
- struct v4l2_format *fmt)
-{
- struct via_camera *cam = priv;
-
- mutex_lock(&cam->lock);
- fmt->fmt.pix = cam->user_format;
- mutex_unlock(&cam->lock);
- return 0;
-}
-
-static int viacam_s_fmt_vid_cap(struct file *filp, void *priv,
- struct v4l2_format *fmt)
-{
- struct via_camera *cam = priv;
- int ret;
- struct v4l2_format sfmt;
- struct via_format *f = via_find_format(fmt->fmt.pix.pixelformat);
-
- /*
- * Camera must be idle or we can't mess with the
- * video setup.
- */
- mutex_lock(&cam->lock);
- if (cam->opstate != S_IDLE) {
- ret = -EBUSY;
- goto out;
- }
- /*
- * Let the sensor code look over and tweak the
- * requested formatting.
- */
- ret = viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix);
- if (ret)
- goto out;
- /*
- * OK, let's commit to the new format.
- */
- cam->user_format = fmt->fmt.pix;
- cam->sensor_format = sfmt.fmt.pix;
- cam->mbus_code = f->mbus_code;
- ret = viacam_configure_sensor(cam);
- if (!ret)
- ret = viacam_config_controller(cam);
-out:
- mutex_unlock(&cam->lock);
- return ret;
-}
-
-static int viacam_querycap(struct file *filp, void *priv,
- struct v4l2_capability *cap)
-{
- strcpy(cap->driver, "via-camera");
- strcpy(cap->card, "via-camera");
- cap->version = 1;
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
- return 0;
-}
-
-/*
- * Streaming operations - pure videobuf stuff.
- */
-static int viacam_reqbufs(struct file *filp, void *priv,
- struct v4l2_requestbuffers *rb)
-{
- struct via_camera *cam = priv;
-
- return videobuf_reqbufs(&cam->vb_queue, rb);
-}
-
-static int viacam_querybuf(struct file *filp, void *priv,
- struct v4l2_buffer *buf)
-{
- struct via_camera *cam = priv;
-
- return videobuf_querybuf(&cam->vb_queue, buf);
-}
-
-static int viacam_qbuf(struct file *filp, void *priv, struct v4l2_buffer *buf)
-{
- struct via_camera *cam = priv;
-
- return videobuf_qbuf(&cam->vb_queue, buf);
-}
-
-static int viacam_dqbuf(struct file *filp, void *priv, struct v4l2_buffer *buf)
-{
- struct via_camera *cam = priv;
-
- return videobuf_dqbuf(&cam->vb_queue, buf, filp->f_flags & O_NONBLOCK);
-}
-
-static int viacam_streamon(struct file *filp, void *priv, enum v4l2_buf_type t)
-{
- struct via_camera *cam = priv;
- int ret = 0;
-
- if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- mutex_lock(&cam->lock);
- if (cam->opstate != S_IDLE) {
- ret = -EBUSY;
- goto out;
- }
- /*
- * Enforce the V4l2 "only one owner gets to read data" rule.
- */
- if (cam->owner && cam->owner != filp) {
- ret = -EBUSY;
- goto out;
- }
- cam->owner = filp;
- /*
- * Configure things if need be.
- */
- if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) {
- ret = viacam_configure_sensor(cam);
- if (ret)
- goto out;
- ret = viacam_config_controller(cam);
- if (ret)
- goto out;
- }
- /*
- * If the CPU goes into C3, the DMA transfer gets corrupted and
- * users start filing unsightly bug reports. Put in a "latency"
- * requirement which will keep the CPU out of the deeper sleep
- * states.
- */
- pm_qos_add_request(&cam->qos_request, PM_QOS_CPU_DMA_LATENCY, 50);
- /*
- * Fire things up.
- */
- INIT_LIST_HEAD(&cam->buffer_queue);
- ret = videobuf_streamon(&cam->vb_queue);
- if (!ret)
- viacam_start_engine(cam);
-out:
- mutex_unlock(&cam->lock);
- return ret;
-}
-
-static int viacam_streamoff(struct file *filp, void *priv, enum v4l2_buf_type t)
-{
- struct via_camera *cam = priv;
- int ret;
-
- if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- mutex_lock(&cam->lock);
- if (cam->opstate != S_RUNNING) {
- ret = -EINVAL;
- goto out;
- }
- pm_qos_remove_request(&cam->qos_request);
- viacam_stop_engine(cam);
- /*
- * Videobuf will recycle all of the outstanding buffers, but
- * we should be sure we don't retain any references to
- * any of them.
- */
- ret = videobuf_streamoff(&cam->vb_queue);
- INIT_LIST_HEAD(&cam->buffer_queue);
-out:
- mutex_unlock(&cam->lock);
- return ret;
-}
-
-/* G/S_PARM */
-
-static int viacam_g_parm(struct file *filp, void *priv,
- struct v4l2_streamparm *parm)
-{
- struct via_camera *cam = priv;
- int ret;
-
- mutex_lock(&cam->lock);
- ret = sensor_call(cam, video, g_parm, parm);
- mutex_unlock(&cam->lock);
- parm->parm.capture.readbuffers = cam->n_cap_bufs;
- return ret;
-}
-
-static int viacam_s_parm(struct file *filp, void *priv,
- struct v4l2_streamparm *parm)
-{
- struct via_camera *cam = priv;
- int ret;
-
- mutex_lock(&cam->lock);
- ret = sensor_call(cam, video, s_parm, parm);
- mutex_unlock(&cam->lock);
- parm->parm.capture.readbuffers = cam->n_cap_bufs;
- return ret;
-}
-
-static int viacam_enum_framesizes(struct file *filp, void *priv,
- struct v4l2_frmsizeenum *sizes)
-{
- if (sizes->index != 0)
- return -EINVAL;
- sizes->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
- sizes->stepwise.min_width = QCIF_WIDTH;
- sizes->stepwise.min_height = QCIF_HEIGHT;
- sizes->stepwise.max_width = VGA_WIDTH;
- sizes->stepwise.max_height = VGA_HEIGHT;
- sizes->stepwise.step_width = sizes->stepwise.step_height = 1;
- return 0;
-}
-
-static int viacam_enum_frameintervals(struct file *filp, void *priv,
- struct v4l2_frmivalenum *interval)
-{
- struct via_camera *cam = priv;
- int ret;
-
- mutex_lock(&cam->lock);
- ret = sensor_call(cam, video, enum_frameintervals, interval);
- mutex_unlock(&cam->lock);
- return ret;
-}
-
-
-
-static const struct v4l2_ioctl_ops viacam_ioctl_ops = {
- .vidioc_g_chip_ident = viacam_g_chip_ident,
- .vidioc_queryctrl = viacam_queryctrl,
- .vidioc_g_ctrl = viacam_g_ctrl,
- .vidioc_s_ctrl = viacam_s_ctrl,
- .vidioc_enum_input = viacam_enum_input,
- .vidioc_g_input = viacam_g_input,
- .vidioc_s_input = viacam_s_input,
- .vidioc_s_std = viacam_s_std,
- .vidioc_enum_fmt_vid_cap = viacam_enum_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = viacam_try_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = viacam_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = viacam_s_fmt_vid_cap,
- .vidioc_querycap = viacam_querycap,
- .vidioc_reqbufs = viacam_reqbufs,
- .vidioc_querybuf = viacam_querybuf,
- .vidioc_qbuf = viacam_qbuf,
- .vidioc_dqbuf = viacam_dqbuf,
- .vidioc_streamon = viacam_streamon,
- .vidioc_streamoff = viacam_streamoff,
- .vidioc_g_parm = viacam_g_parm,
- .vidioc_s_parm = viacam_s_parm,
- .vidioc_enum_framesizes = viacam_enum_framesizes,
- .vidioc_enum_frameintervals = viacam_enum_frameintervals,
-};
-
-/*----------------------------------------------------------------------------*/
-
-/*
- * Power management.
- */
-#ifdef CONFIG_PM
-
-static int viacam_suspend(void *priv)
-{
- struct via_camera *cam = priv;
- enum viacam_opstate state = cam->opstate;
-
- if (cam->opstate != S_IDLE) {
- viacam_stop_engine(cam);
- cam->opstate = state; /* So resume restarts */
- }
-
- return 0;
-}
-
-static int viacam_resume(void *priv)
-{
- struct via_camera *cam = priv;
- int ret = 0;
-
- /*
- * Get back to a reasonable operating state.
- */
- via_write_reg_mask(VIASR, 0x78, 0, 0x80);
- via_write_reg_mask(VIASR, 0x1e, 0xc0, 0xc0);
- viacam_int_disable(cam);
- set_bit(CF_CONFIG_NEEDED, &cam->flags);
- /*
- * Make sure the sensor's power state is correct
- */
- if (cam->users > 0)
- via_sensor_power_up(cam);
- else
- via_sensor_power_down(cam);
- /*
- * If it was operating, try to restart it.
- */
- if (cam->opstate != S_IDLE) {
- mutex_lock(&cam->lock);
- ret = viacam_configure_sensor(cam);
- if (!ret)
- ret = viacam_config_controller(cam);
- mutex_unlock(&cam->lock);
- if (!ret)
- viacam_start_engine(cam);
- }
-
- return ret;
-}
-
-static struct viafb_pm_hooks viacam_pm_hooks = {
- .suspend = viacam_suspend,
- .resume = viacam_resume
-};
-
-#endif /* CONFIG_PM */
-
-/*
- * Setup stuff.
- */
-
-static struct video_device viacam_v4l_template = {
- .name = "via-camera",
- .minor = -1,
- .tvnorms = V4L2_STD_NTSC_M,
- .current_norm = V4L2_STD_NTSC_M,
- .fops = &viacam_fops,
- .ioctl_ops = &viacam_ioctl_ops,
- .release = video_device_release_empty, /* Check this */
-};
-
-/*
- * The OLPC folks put the serial port on the same pin as
- * the camera. They also get grumpy if we break the
- * serial port and keep them from using it. So we have
- * to check the serial enable bit and not step on it.
- */
-#define VIACAM_SERIAL_DEVFN 0x88
-#define VIACAM_SERIAL_CREG 0x46
-#define VIACAM_SERIAL_BIT 0x40
-
-static __devinit bool viacam_serial_is_enabled(void)
-{
- struct pci_bus *pbus = pci_find_bus(0, 0);
- u8 cbyte;
-
- if (!pbus)
- return false;
- pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
- VIACAM_SERIAL_CREG, &cbyte);
- if ((cbyte & VIACAM_SERIAL_BIT) == 0)
- return false; /* Not enabled */
- if (override_serial == 0) {
- printk(KERN_NOTICE "Via camera: serial port is enabled, " \
- "refusing to load.\n");
- printk(KERN_NOTICE "Specify override_serial=1 to force " \
- "module loading.\n");
- return true;
- }
- printk(KERN_NOTICE "Via camera: overriding serial port\n");
- pci_bus_write_config_byte(pbus, VIACAM_SERIAL_DEVFN,
- VIACAM_SERIAL_CREG, cbyte & ~VIACAM_SERIAL_BIT);
- return false;
-}
-
-static struct ov7670_config sensor_cfg = {
- /* The XO-1.5 (only known user) clocks the camera at 90MHz. */
- .clock_speed = 90,
-};
-
-static __devinit int viacam_probe(struct platform_device *pdev)
-{
- int ret;
- struct i2c_adapter *sensor_adapter;
- struct viafb_dev *viadev = pdev->dev.platform_data;
- struct i2c_board_info ov7670_info = {
- .type = "ov7670",
- .addr = 0x42 >> 1,
- .platform_data = &sensor_cfg,
- };
-
- /*
- * Note that there are actually two capture channels on
- * the device. We only deal with one for now. That
- * is encoded here; nothing else assumes it's dealing with
- * a unique capture device.
- */
- struct via_camera *cam;
-
- /*
- * Ensure that frame buffer memory has been set aside for
- * this purpose. As an arbitrary limit, refuse to work
- * with less than two frames of VGA 16-bit data.
- *
- * If we ever support the second port, we'll need to set
- * aside more memory.
- */
- if (viadev->camera_fbmem_size < (VGA_HEIGHT*VGA_WIDTH*4)) {
- printk(KERN_ERR "viacam: insufficient FB memory reserved\n");
- return -ENOMEM;
- }
- if (viadev->engine_mmio == NULL) {
- printk(KERN_ERR "viacam: No I/O memory, so no pictures\n");
- return -ENOMEM;
- }
-
- if (machine_is_olpc() && viacam_serial_is_enabled())
- return -EBUSY;
-
- /*
- * Basic structure initialization.
- */
- cam = kzalloc (sizeof(struct via_camera), GFP_KERNEL);
- if (cam == NULL)
- return -ENOMEM;
- via_cam_info = cam;
- cam->platdev = pdev;
- cam->viadev = viadev;
- cam->users = 0;
- cam->owner = NULL;
- cam->opstate = S_IDLE;
- cam->user_format = cam->sensor_format = viacam_def_pix_format;
- mutex_init(&cam->lock);
- INIT_LIST_HEAD(&cam->buffer_queue);
- cam->mmio = viadev->engine_mmio;
- cam->fbmem = viadev->fbmem;
- cam->fb_offset = viadev->camera_fbmem_offset;
- cam->flags = 1 << CF_CONFIG_NEEDED;
- cam->mbus_code = via_def_mbus_code;
- /*
- * Tell V4L that we exist.
- */
- ret = v4l2_device_register(&pdev->dev, &cam->v4l2_dev);
- if (ret) {
- dev_err(&pdev->dev, "Unable to register v4l2 device\n");
- return ret;
- }
- /*
- * Convince the system that we can do DMA.
- */
- pdev->dev.dma_mask = &viadev->pdev->dma_mask;
- dma_set_mask(&pdev->dev, 0xffffffff);
- /*
- * Fire up the capture port. The write to 0x78 looks purely
- * OLPCish; any system will need to tweak 0x1e.
- */
- via_write_reg_mask(VIASR, 0x78, 0, 0x80);
- via_write_reg_mask(VIASR, 0x1e, 0xc0, 0xc0);
- /*
- * Get the sensor powered up.
- */
- ret = via_sensor_power_setup(cam);
- if (ret)
- goto out_unregister;
- via_sensor_power_up(cam);
-
- /*
- * See if we can't find it on the bus. The VIA_PORT_31 assumption
- * is OLPC-specific. 0x42 assumption is ov7670-specific.
- */
- sensor_adapter = viafb_find_i2c_adapter(VIA_PORT_31);
- cam->sensor = v4l2_i2c_new_subdev_board(&cam->v4l2_dev, sensor_adapter,
- &ov7670_info, NULL);
- if (cam->sensor == NULL) {
- dev_err(&pdev->dev, "Unable to find the sensor!\n");
- ret = -ENODEV;
- goto out_power_down;
- }
- /*
- * Get the IRQ.
- */
- viacam_int_disable(cam);
- ret = request_threaded_irq(viadev->pdev->irq, viacam_quick_irq,
- viacam_irq, IRQF_SHARED, "via-camera", cam);
- if (ret)
- goto out_power_down;
- /*
- * Tell V4l2 that we exist.
- */
- cam->vdev = viacam_v4l_template;
- cam->vdev.v4l2_dev = &cam->v4l2_dev;
- ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);
- if (ret)
- goto out_irq;
- video_set_drvdata(&cam->vdev, cam);
-
-#ifdef CONFIG_PM
- /*
- * Hook into PM events
- */
- viacam_pm_hooks.private = cam;
- viafb_pm_register(&viacam_pm_hooks);
-#endif
-
- /* Power the sensor down until somebody opens the device */
- via_sensor_power_down(cam);
- return 0;
-
-out_irq:
- free_irq(viadev->pdev->irq, cam);
-out_power_down:
- via_sensor_power_release(cam);
-out_unregister:
- v4l2_device_unregister(&cam->v4l2_dev);
- return ret;
-}
-
-static __devexit int viacam_remove(struct platform_device *pdev)
-{
- struct via_camera *cam = via_cam_info;
- struct viafb_dev *viadev = pdev->dev.platform_data;
-
- video_unregister_device(&cam->vdev);
- v4l2_device_unregister(&cam->v4l2_dev);
- free_irq(viadev->pdev->irq, cam);
- via_sensor_power_release(cam);
- via_cam_info = NULL;
- return 0;
-}
-
-static struct platform_driver viacam_driver = {
- .driver = {
- .name = "viafb-camera",
- },
- .probe = viacam_probe,
- .remove = viacam_remove,
-};
-
-module_platform_driver(viacam_driver);
diff --git a/drivers/media/video/via-camera.h b/drivers/media/video/via-camera.h
deleted file mode 100644
index b12a4b3d616..00000000000
--- a/drivers/media/video/via-camera.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * VIA Camera register definitions.
- */
-#define VCR_INTCTRL 0x300 /* Capture interrupt control */
-#define VCR_IC_EAV 0x0001 /* End of active video status */
-#define VCR_IC_EVBI 0x0002 /* End of VBI status */
-#define VCR_IC_FBOTFLD 0x0004 /* "flipping" Bottom field is active */
-#define VCR_IC_ACTBUF 0x0018 /* Active video buffer */
-#define VCR_IC_VSYNC 0x0020 /* 0 = VB, 1 = active video */
-#define VCR_IC_BOTFLD 0x0040 /* Bottom field is active */
-#define VCR_IC_FFULL 0x0080 /* FIFO full */
-#define VCR_IC_INTEN 0x0100 /* End of active video int. enable */
-#define VCR_IC_VBIINT 0x0200 /* End of VBI int enable */
-#define VCR_IC_VBIBUF 0x0400 /* Current VBI buffer */
-
-#define VCR_TSC 0x308 /* Transport stream control */
-#define VCR_TSC_ENABLE 0x000001 /* Transport stream input enable */
-#define VCR_TSC_DROPERR 0x000002 /* Drop error packets */
-#define VCR_TSC_METHOD 0x00000c /* DMA method (non-functional) */
-#define VCR_TSC_COUNT 0x07fff0 /* KByte or packet count */
-#define VCR_TSC_CBMODE 0x080000 /* Change buffer by byte count */
-#define VCR_TSC_PSSIG 0x100000 /* Packet starting signal disable */
-#define VCR_TSC_BE 0x200000 /* MSB first (serial mode) */
-#define VCR_TSC_SERIAL 0x400000 /* Serial input (0 = parallel) */
-
-#define VCR_CAPINTC 0x310 /* Capture interface control */
-#define VCR_CI_ENABLE 0x00000001 /* Capture enable */
-#define VCR_CI_BSS 0x00000002 /* WTF "bit stream selection" */
-#define VCR_CI_3BUFS 0x00000004 /* 1 = 3 buffers, 0 = 2 buffers */
-#define VCR_CI_VIPEN 0x00000008 /* VIP enable */
-#define VCR_CI_CCIR601_8 0 /* CCIR601 input stream, 8 bit */
-#define VCR_CI_CCIR656_8 0x00000010 /* ... CCIR656, 8 bit */
-#define VCR_CI_CCIR601_16 0x00000020 /* ... CCIR601, 16 bit */
-#define VCR_CI_CCIR656_16 0x00000030 /* ... CCIR656, 16 bit */
-#define VCR_CI_HDMODE 0x00000040 /* CCIR656-16 hdr decode mode; 1=16b */
-#define VCR_CI_BSWAP 0x00000080 /* Swap bytes (16-bit) */
-#define VCR_CI_YUYV 0 /* Byte order 0123 */
-#define VCR_CI_UYVY 0x00000100 /* Byte order 1032 */
-#define VCR_CI_YVYU 0x00000200 /* Byte order 0321 */
-#define VCR_CI_VYUY 0x00000300 /* Byte order 3012 */
-#define VCR_CI_VIPTYPE 0x00000400 /* VIP type */
-#define VCR_CI_IFSEN 0x00000800 /* Input field signal enable */
-#define VCR_CI_DIODD 0 /* De-interlace odd, 30fps */
-#define VCR_CI_DIEVEN 0x00001000 /* ...even field, 30fps */
-#define VCR_CI_DIBOTH 0x00002000 /* ...both fields, 60fps */
-#define VCR_CI_DIBOTH30 0x00003000 /* ...both fields, 30fps interlace */
-#define VCR_CI_CONVTYPE 0x00004000 /* 4:2:2 to 4:4:4; 1 = interpolate */
-#define VCR_CI_CFC 0x00008000 /* Capture flipping control */
-#define VCR_CI_FILTER 0x00070000 /* Horiz filter mode select
- 000 = none
- 001 = 2 tap
- 010 = 3 tap
- 011 = 4 tap
- 100 = 5 tap */
-#define VCR_CI_CLKINV 0x00080000 /* Input CLK inverted */
-#define VCR_CI_VREFINV 0x00100000 /* VREF inverted */
-#define VCR_CI_HREFINV 0x00200000 /* HREF inverted */
-#define VCR_CI_FLDINV 0x00400000 /* Field inverted */
-#define VCR_CI_CLKPIN 0x00800000 /* Capture clock pin */
-#define VCR_CI_THRESH 0x0f000000 /* Capture fifo threshold */
-#define VCR_CI_HRLE 0x10000000 /* Positive edge of HREF */
-#define VCR_CI_VRLE 0x20000000 /* Positive edge of VREF */
-#define VCR_CI_OFLDINV 0x40000000 /* Field output inverted */
-#define VCR_CI_CLKEN 0x80000000 /* Capture clock enable */
-
-#define VCR_HORRANGE 0x314 /* Active video horizontal range */
-#define VCR_VERTRANGE 0x318 /* Active video vertical range */
-#define VCR_AVSCALE 0x31c /* Active video scaling control */
-#define VCR_AVS_HEN 0x00000800 /* Horizontal scale enable */
-#define VCR_AVS_VEN 0x04000000 /* Vertical enable */
-#define VCR_VBIHOR 0x320 /* VBI Data horizontal range */
-#define VCR_VBIVERT 0x324 /* VBI data vertical range */
-#define VCR_VBIBUF1 0x328 /* First VBI buffer */
-#define VCR_VBISTRIDE 0x32c /* VBI stride */
-#define VCR_ANCDATACNT 0x330 /* Ancillary data count setting */
-#define VCR_MAXDATA 0x334 /* Active data count of active video */
-#define VCR_MAXVBI 0x338 /* Maximum data count of VBI */
-#define VCR_CAPDATA 0x33c /* Capture data count */
-#define VCR_VBUF1 0x340 /* First video buffer */
-#define VCR_VBUF2 0x344 /* Second video buffer */
-#define VCR_VBUF3 0x348 /* Third video buffer */
-#define VCR_VBUF_MASK 0x1ffffff0 /* Bits 28:4 */
-#define VCR_VBIBUF2 0x34c /* Second VBI buffer */
-#define VCR_VSTRIDE 0x350 /* Stride of video + coring control */
-#define VCR_VS_STRIDE_SHIFT 4
-#define VCR_VS_STRIDE 0x00001ff0 /* Stride (8-byte units) */
-#define VCR_VS_CCD 0x007f0000 /* Coring compare data */
-#define VCR_VS_COREEN 0x00800000 /* Coring enable */
-#define VCR_TS0ERR 0x354 /* TS buffer 0 error indicator */
-#define VCR_TS1ERR 0x358 /* TS buffer 0 error indicator */
-#define VCR_TS2ERR 0x35c /* TS buffer 0 error indicator */
-
-/* Add 0x1000 for the second capture engine registers */
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
deleted file mode 100644
index bf7a326b1cd..00000000000
--- a/drivers/media/video/videobuf-core.c
+++ /dev/null
@@ -1,1189 +0,0 @@
-/*
- * generic helper functions for handling video4linux capture buffers
- *
- * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
- *
- * Highly based on video-buf written originally by:
- * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
- * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org>
- * (c) 2006 Ted Walther and John Sokol
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-
-#include <media/videobuf-core.h>
-
-#define MAGIC_BUFFER 0x20070728
-#define MAGIC_CHECK(is, should) \
- do { \
- if (unlikely((is) != (should))) { \
- printk(KERN_ERR \
- "magic mismatch: %x (expected %x)\n", \
- is, should); \
- BUG(); \
- } \
- } while (0)
-
-static int debug;
-module_param(debug, int, 0644);
-
-MODULE_DESCRIPTION("helper module to manage video4linux buffers");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_LICENSE("GPL");
-
-#define dprintk(level, fmt, arg...) \
- do { \
- if (debug >= level) \
- printk(KERN_DEBUG "vbuf: " fmt, ## arg); \
- } while (0)
-
-/* --------------------------------------------------------------------- */
-
-#define CALL(q, f, arg...) \
- ((q->int_ops->f) ? q->int_ops->f(arg) : 0)
-
-struct videobuf_buffer *videobuf_alloc_vb(struct videobuf_queue *q)
-{
- struct videobuf_buffer *vb;
-
- BUG_ON(q->msize < sizeof(*vb));
-
- if (!q->int_ops || !q->int_ops->alloc_vb) {
- printk(KERN_ERR "No specific ops defined!\n");
- BUG();
- }
-
- vb = q->int_ops->alloc_vb(q->msize);
- if (NULL != vb) {
- init_waitqueue_head(&vb->done);
- vb->magic = MAGIC_BUFFER;
- }
-
- return vb;
-}
-EXPORT_SYMBOL_GPL(videobuf_alloc_vb);
-
-static int is_state_active_or_queued(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- unsigned long flags;
- bool rc;
-
- spin_lock_irqsave(q->irqlock, flags);
- rc = vb->state != VIDEOBUF_ACTIVE && vb->state != VIDEOBUF_QUEUED;
- spin_unlock_irqrestore(q->irqlock, flags);
- return rc;
-};
-
-int videobuf_waiton(struct videobuf_queue *q, struct videobuf_buffer *vb,
- int non_blocking, int intr)
-{
- bool is_ext_locked;
- int ret = 0;
-
- MAGIC_CHECK(vb->magic, MAGIC_BUFFER);
-
- if (non_blocking) {
- if (is_state_active_or_queued(q, vb))
- return 0;
- return -EAGAIN;
- }
-
- is_ext_locked = q->ext_lock && mutex_is_locked(q->ext_lock);
-
- /* Release vdev lock to prevent this wait from blocking outside access to
- the device. */
- if (is_ext_locked)
- mutex_unlock(q->ext_lock);
- if (intr)
- ret = wait_event_interruptible(vb->done, is_state_active_or_queued(q, vb));
- else
- wait_event(vb->done, is_state_active_or_queued(q, vb));
- /* Relock */
- if (is_ext_locked)
- mutex_lock(q->ext_lock);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(videobuf_waiton);
-
-int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb,
- struct v4l2_framebuffer *fbuf)
-{
- MAGIC_CHECK(vb->magic, MAGIC_BUFFER);
- MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
-
- return CALL(q, iolock, q, vb, fbuf);
-}
-EXPORT_SYMBOL_GPL(videobuf_iolock);
-
-void *videobuf_queue_to_vaddr(struct videobuf_queue *q,
- struct videobuf_buffer *buf)
-{
- if (q->int_ops->vaddr)
- return q->int_ops->vaddr(buf);
- return NULL;
-}
-EXPORT_SYMBOL_GPL(videobuf_queue_to_vaddr);
-
-/* --------------------------------------------------------------------- */
-
-
-void videobuf_queue_core_init(struct videobuf_queue *q,
- const struct videobuf_queue_ops *ops,
- struct device *dev,
- spinlock_t *irqlock,
- enum v4l2_buf_type type,
- enum v4l2_field field,
- unsigned int msize,
- void *priv,
- struct videobuf_qtype_ops *int_ops,
- struct mutex *ext_lock)
-{
- BUG_ON(!q);
- memset(q, 0, sizeof(*q));
- q->irqlock = irqlock;
- q->ext_lock = ext_lock;
- q->dev = dev;
- q->type = type;
- q->field = field;
- q->msize = msize;
- q->ops = ops;
- q->priv_data = priv;
- q->int_ops = int_ops;
-
- /* All buffer operations are mandatory */
- BUG_ON(!q->ops->buf_setup);
- BUG_ON(!q->ops->buf_prepare);
- BUG_ON(!q->ops->buf_queue);
- BUG_ON(!q->ops->buf_release);
-
- /* Lock is mandatory for queue_cancel to work */
- BUG_ON(!irqlock);
-
- /* Having implementations for abstract methods are mandatory */
- BUG_ON(!q->int_ops);
-
- mutex_init(&q->vb_lock);
- init_waitqueue_head(&q->wait);
- INIT_LIST_HEAD(&q->stream);
-}
-EXPORT_SYMBOL_GPL(videobuf_queue_core_init);
-
-/* Locking: Only usage in bttv unsafe find way to remove */
-int videobuf_queue_is_busy(struct videobuf_queue *q)
-{
- int i;
-
- MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
-
- if (q->streaming) {
- dprintk(1, "busy: streaming active\n");
- return 1;
- }
- if (q->reading) {
- dprintk(1, "busy: pending read #1\n");
- return 1;
- }
- if (q->read_buf) {
- dprintk(1, "busy: pending read #2\n");
- return 1;
- }
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- if (NULL == q->bufs[i])
- continue;
- if (q->bufs[i]->map) {
- dprintk(1, "busy: buffer #%d mapped\n", i);
- return 1;
- }
- if (q->bufs[i]->state == VIDEOBUF_QUEUED) {
- dprintk(1, "busy: buffer #%d queued\n", i);
- return 1;
- }
- if (q->bufs[i]->state == VIDEOBUF_ACTIVE) {
- dprintk(1, "busy: buffer #%d avtive\n", i);
- return 1;
- }
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(videobuf_queue_is_busy);
-
-/**
- * __videobuf_free() - free all the buffers and their control structures
- *
- * This function can only be called if streaming/reading is off, i.e. no buffers
- * are under control of the driver.
- */
-/* Locking: Caller holds q->vb_lock */
-static int __videobuf_free(struct videobuf_queue *q)
-{
- int i;
-
- dprintk(1, "%s\n", __func__);
- if (!q)
- return 0;
-
- if (q->streaming || q->reading) {
- dprintk(1, "Cannot free buffers when streaming or reading\n");
- return -EBUSY;
- }
-
- MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
-
- for (i = 0; i < VIDEO_MAX_FRAME; i++)
- if (q->bufs[i] && q->bufs[i]->map) {
- dprintk(1, "Cannot free mmapped buffers\n");
- return -EBUSY;
- }
-
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- if (NULL == q->bufs[i])
- continue;
- q->ops->buf_release(q, q->bufs[i]);
- kfree(q->bufs[i]);
- q->bufs[i] = NULL;
- }
-
- return 0;
-}
-
-/* Locking: Caller holds q->vb_lock */
-void videobuf_queue_cancel(struct videobuf_queue *q)
-{
- unsigned long flags = 0;
- int i;
-
- q->streaming = 0;
- q->reading = 0;
- wake_up_interruptible_sync(&q->wait);
-
- /* remove queued buffers from list */
- spin_lock_irqsave(q->irqlock, flags);
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- if (NULL == q->bufs[i])
- continue;
- if (q->bufs[i]->state == VIDEOBUF_QUEUED) {
- list_del(&q->bufs[i]->queue);
- q->bufs[i]->state = VIDEOBUF_ERROR;
- wake_up_all(&q->bufs[i]->done);
- }
- }
- spin_unlock_irqrestore(q->irqlock, flags);
-
- /* free all buffers + clear queue */
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- if (NULL == q->bufs[i])
- continue;
- q->ops->buf_release(q, q->bufs[i]);
- }
- INIT_LIST_HEAD(&q->stream);
-}
-EXPORT_SYMBOL_GPL(videobuf_queue_cancel);
-
-/* --------------------------------------------------------------------- */
-
-/* Locking: Caller holds q->vb_lock */
-enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
-{
- enum v4l2_field field = q->field;
-
- BUG_ON(V4L2_FIELD_ANY == field);
-
- if (V4L2_FIELD_ALTERNATE == field) {
- if (V4L2_FIELD_TOP == q->last) {
- field = V4L2_FIELD_BOTTOM;
- q->last = V4L2_FIELD_BOTTOM;
- } else {
- field = V4L2_FIELD_TOP;
- q->last = V4L2_FIELD_TOP;
- }
- }
- return field;
-}
-EXPORT_SYMBOL_GPL(videobuf_next_field);
-
-/* Locking: Caller holds q->vb_lock */
-static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
- struct videobuf_buffer *vb, enum v4l2_buf_type type)
-{
- MAGIC_CHECK(vb->magic, MAGIC_BUFFER);
- MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
-
- b->index = vb->i;
- b->type = type;
-
- b->memory = vb->memory;
- switch (b->memory) {
- case V4L2_MEMORY_MMAP:
- b->m.offset = vb->boff;
- b->length = vb->bsize;
- break;
- case V4L2_MEMORY_USERPTR:
- b->m.userptr = vb->baddr;
- b->length = vb->bsize;
- break;
- case V4L2_MEMORY_OVERLAY:
- b->m.offset = vb->boff;
- break;
- }
-
- b->flags = 0;
- if (vb->map)
- b->flags |= V4L2_BUF_FLAG_MAPPED;
-
- switch (vb->state) {
- case VIDEOBUF_PREPARED:
- case VIDEOBUF_QUEUED:
- case VIDEOBUF_ACTIVE:
- b->flags |= V4L2_BUF_FLAG_QUEUED;
- break;
- case VIDEOBUF_ERROR:
- b->flags |= V4L2_BUF_FLAG_ERROR;
- /* fall through */
- case VIDEOBUF_DONE:
- b->flags |= V4L2_BUF_FLAG_DONE;
- break;
- case VIDEOBUF_NEEDS_INIT:
- case VIDEOBUF_IDLE:
- /* nothing */
- break;
- }
-
- b->field = vb->field;
- b->timestamp = vb->ts;
- b->bytesused = vb->size;
- b->sequence = vb->field_count >> 1;
-}
-
-int videobuf_mmap_free(struct videobuf_queue *q)
-{
- int ret;
- videobuf_queue_lock(q);
- ret = __videobuf_free(q);
- videobuf_queue_unlock(q);
- return ret;
-}
-EXPORT_SYMBOL_GPL(videobuf_mmap_free);
-
-/* Locking: Caller holds q->vb_lock */
-int __videobuf_mmap_setup(struct videobuf_queue *q,
- unsigned int bcount, unsigned int bsize,
- enum v4l2_memory memory)
-{
- unsigned int i;
- int err;
-
- MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
-
- err = __videobuf_free(q);
- if (0 != err)
- return err;
-
- /* Allocate and initialize buffers */
- for (i = 0; i < bcount; i++) {
- q->bufs[i] = videobuf_alloc_vb(q);
-
- if (NULL == q->bufs[i])
- break;
-
- q->bufs[i]->i = i;
- q->bufs[i]->memory = memory;
- q->bufs[i]->bsize = bsize;
- switch (memory) {
- case V4L2_MEMORY_MMAP:
- q->bufs[i]->boff = PAGE_ALIGN(bsize) * i;
- break;
- case V4L2_MEMORY_USERPTR:
- case V4L2_MEMORY_OVERLAY:
- /* nothing */
- break;
- }
- }
-
- if (!i)
- return -ENOMEM;
-
- dprintk(1, "mmap setup: %d buffers, %d bytes each\n", i, bsize);
-
- return i;
-}
-EXPORT_SYMBOL_GPL(__videobuf_mmap_setup);
-
-int videobuf_mmap_setup(struct videobuf_queue *q,
- unsigned int bcount, unsigned int bsize,
- enum v4l2_memory memory)
-{
- int ret;
- videobuf_queue_lock(q);
- ret = __videobuf_mmap_setup(q, bcount, bsize, memory);
- videobuf_queue_unlock(q);
- return ret;
-}
-EXPORT_SYMBOL_GPL(videobuf_mmap_setup);
-
-int videobuf_reqbufs(struct videobuf_queue *q,
- struct v4l2_requestbuffers *req)
-{
- unsigned int size, count;
- int retval;
-
- if (req->count < 1) {
- dprintk(1, "reqbufs: count invalid (%d)\n", req->count);
- return -EINVAL;
- }
-
- if (req->memory != V4L2_MEMORY_MMAP &&
- req->memory != V4L2_MEMORY_USERPTR &&
- req->memory != V4L2_MEMORY_OVERLAY) {
- dprintk(1, "reqbufs: memory type invalid\n");
- return -EINVAL;
- }
-
- videobuf_queue_lock(q);
- if (req->type != q->type) {
- dprintk(1, "reqbufs: queue type invalid\n");
- retval = -EINVAL;
- goto done;
- }
-
- if (q->streaming) {
- dprintk(1, "reqbufs: streaming already exists\n");
- retval = -EBUSY;
- goto done;
- }
- if (!list_empty(&q->stream)) {
- dprintk(1, "reqbufs: stream running\n");
- retval = -EBUSY;
- goto done;
- }
-
- count = req->count;
- if (count > VIDEO_MAX_FRAME)
- count = VIDEO_MAX_FRAME;
- size = 0;
- q->ops->buf_setup(q, &count, &size);
- dprintk(1, "reqbufs: bufs=%d, size=0x%x [%u pages total]\n",
- count, size,
- (unsigned int)((count * PAGE_ALIGN(size)) >> PAGE_SHIFT));
-
- retval = __videobuf_mmap_setup(q, count, size, req->memory);
- if (retval < 0) {
- dprintk(1, "reqbufs: mmap setup returned %d\n", retval);
- goto done;
- }
-
- req->count = retval;
- retval = 0;
-
- done:
- videobuf_queue_unlock(q);
- return retval;
-}
-EXPORT_SYMBOL_GPL(videobuf_reqbufs);
-
-int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
-{
- int ret = -EINVAL;
-
- videobuf_queue_lock(q);
- if (unlikely(b->type != q->type)) {
- dprintk(1, "querybuf: Wrong type.\n");
- goto done;
- }
- if (unlikely(b->index >= VIDEO_MAX_FRAME)) {
- dprintk(1, "querybuf: index out of range.\n");
- goto done;
- }
- if (unlikely(NULL == q->bufs[b->index])) {
- dprintk(1, "querybuf: buffer is null.\n");
- goto done;
- }
-
- videobuf_status(q, b, q->bufs[b->index], q->type);
-
- ret = 0;
-done:
- videobuf_queue_unlock(q);
- return ret;
-}
-EXPORT_SYMBOL_GPL(videobuf_querybuf);
-
-int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b)
-{
- struct videobuf_buffer *buf;
- enum v4l2_field field;
- unsigned long flags = 0;
- int retval;
-
- MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
-
- if (b->memory == V4L2_MEMORY_MMAP)
- down_read(&current->mm->mmap_sem);
-
- videobuf_queue_lock(q);
- retval = -EBUSY;
- if (q->reading) {
- dprintk(1, "qbuf: Reading running...\n");
- goto done;
- }
- retval = -EINVAL;
- if (b->type != q->type) {
- dprintk(1, "qbuf: Wrong type.\n");
- goto done;
- }
- if (b->index >= VIDEO_MAX_FRAME) {
- dprintk(1, "qbuf: index out of range.\n");
- goto done;
- }
- buf = q->bufs[b->index];
- if (NULL == buf) {
- dprintk(1, "qbuf: buffer is null.\n");
- goto done;
- }
- MAGIC_CHECK(buf->magic, MAGIC_BUFFER);
- if (buf->memory != b->memory) {
- dprintk(1, "qbuf: memory type is wrong.\n");
- goto done;
- }
- if (buf->state != VIDEOBUF_NEEDS_INIT && buf->state != VIDEOBUF_IDLE) {
- dprintk(1, "qbuf: buffer is already queued or active.\n");
- goto done;
- }
-
- switch (b->memory) {
- case V4L2_MEMORY_MMAP:
- if (0 == buf->baddr) {
- dprintk(1, "qbuf: mmap requested "
- "but buffer addr is zero!\n");
- goto done;
- }
- if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT
- || q->type == V4L2_BUF_TYPE_VBI_OUTPUT
- || q->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
- buf->size = b->bytesused;
- buf->field = b->field;
- buf->ts = b->timestamp;
- }
- break;
- case V4L2_MEMORY_USERPTR:
- if (b->length < buf->bsize) {
- dprintk(1, "qbuf: buffer length is not enough\n");
- goto done;
- }
- if (VIDEOBUF_NEEDS_INIT != buf->state &&
- buf->baddr != b->m.userptr)
- q->ops->buf_release(q, buf);
- buf->baddr = b->m.userptr;
- break;
- case V4L2_MEMORY_OVERLAY:
- buf->boff = b->m.offset;
- break;
- default:
- dprintk(1, "qbuf: wrong memory type\n");
- goto done;
- }
-
- dprintk(1, "qbuf: requesting next field\n");
- field = videobuf_next_field(q);
- retval = q->ops->buf_prepare(q, buf, field);
- if (0 != retval) {
- dprintk(1, "qbuf: buffer_prepare returned %d\n", retval);
- goto done;
- }
-
- list_add_tail(&buf->stream, &q->stream);
- if (q->streaming) {
- spin_lock_irqsave(q->irqlock, flags);
- q->ops->buf_queue(q, buf);
- spin_unlock_irqrestore(q->irqlock, flags);
- }
- dprintk(1, "qbuf: succeeded\n");
- retval = 0;
- wake_up_interruptible_sync(&q->wait);
-
-done:
- videobuf_queue_unlock(q);
-
- if (b->memory == V4L2_MEMORY_MMAP)
- up_read(&current->mm->mmap_sem);
-
- return retval;
-}
-EXPORT_SYMBOL_GPL(videobuf_qbuf);
-
-/* Locking: Caller holds q->vb_lock */
-static int stream_next_buffer_check_queue(struct videobuf_queue *q, int noblock)
-{
- int retval;
-
-checks:
- if (!q->streaming) {
- dprintk(1, "next_buffer: Not streaming\n");
- retval = -EINVAL;
- goto done;
- }
-
- if (list_empty(&q->stream)) {
- if (noblock) {
- retval = -EAGAIN;
- dprintk(2, "next_buffer: no buffers to dequeue\n");
- goto done;
- } else {
- dprintk(2, "next_buffer: waiting on buffer\n");
-
- /* Drop lock to avoid deadlock with qbuf */
- videobuf_queue_unlock(q);
-
- /* Checking list_empty and streaming is safe without
- * locks because we goto checks to validate while
- * holding locks before proceeding */
- retval = wait_event_interruptible(q->wait,
- !list_empty(&q->stream) || !q->streaming);
- videobuf_queue_lock(q);
-
- if (retval)
- goto done;
-
- goto checks;
- }
- }
-
- retval = 0;
-
-done:
- return retval;
-}
-
-/* Locking: Caller holds q->vb_lock */
-static int stream_next_buffer(struct videobuf_queue *q,
- struct videobuf_buffer **vb, int nonblocking)
-{
- int retval;
- struct videobuf_buffer *buf = NULL;
-
- retval = stream_next_buffer_check_queue(q, nonblocking);
- if (retval)
- goto done;
-
- buf = list_entry(q->stream.next, struct videobuf_buffer, stream);
- retval = videobuf_waiton(q, buf, nonblocking, 1);
- if (retval < 0)
- goto done;
-
- *vb = buf;
-done:
- return retval;
-}
-
-int videobuf_dqbuf(struct videobuf_queue *q,
- struct v4l2_buffer *b, int nonblocking)
-{
- struct videobuf_buffer *buf = NULL;
- int retval;
-
- MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
-
- memset(b, 0, sizeof(*b));
- videobuf_queue_lock(q);
-
- retval = stream_next_buffer(q, &buf, nonblocking);
- if (retval < 0) {
- dprintk(1, "dqbuf: next_buffer error: %i\n", retval);
- goto done;
- }
-
- switch (buf->state) {
- case VIDEOBUF_ERROR:
- dprintk(1, "dqbuf: state is error\n");
- break;
- case VIDEOBUF_DONE:
- dprintk(1, "dqbuf: state is done\n");
- break;
- default:
- dprintk(1, "dqbuf: state invalid\n");
- retval = -EINVAL;
- goto done;
- }
- CALL(q, sync, q, buf);
- videobuf_status(q, b, buf, q->type);
- list_del(&buf->stream);
- buf->state = VIDEOBUF_IDLE;
- b->flags &= ~V4L2_BUF_FLAG_DONE;
-done:
- videobuf_queue_unlock(q);
- return retval;
-}
-EXPORT_SYMBOL_GPL(videobuf_dqbuf);
-
-int videobuf_streamon(struct videobuf_queue *q)
-{
- struct videobuf_buffer *buf;
- unsigned long flags = 0;
- int retval;
-
- videobuf_queue_lock(q);
- retval = -EBUSY;
- if (q->reading)
- goto done;
- retval = 0;
- if (q->streaming)
- goto done;
- q->streaming = 1;
- spin_lock_irqsave(q->irqlock, flags);
- list_for_each_entry(buf, &q->stream, stream)
- if (buf->state == VIDEOBUF_PREPARED)
- q->ops->buf_queue(q, buf);
- spin_unlock_irqrestore(q->irqlock, flags);
-
- wake_up_interruptible_sync(&q->wait);
-done:
- videobuf_queue_unlock(q);
- return retval;
-}
-EXPORT_SYMBOL_GPL(videobuf_streamon);
-
-/* Locking: Caller holds q->vb_lock */
-static int __videobuf_streamoff(struct videobuf_queue *q)
-{
- if (!q->streaming)
- return -EINVAL;
-
- videobuf_queue_cancel(q);
-
- return 0;
-}
-
-int videobuf_streamoff(struct videobuf_queue *q)
-{
- int retval;
-
- videobuf_queue_lock(q);
- retval = __videobuf_streamoff(q);
- videobuf_queue_unlock(q);
-
- return retval;
-}
-EXPORT_SYMBOL_GPL(videobuf_streamoff);
-
-/* Locking: Caller holds q->vb_lock */
-static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
- char __user *data,
- size_t count, loff_t *ppos)
-{
- enum v4l2_field field;
- unsigned long flags = 0;
- int retval;
-
- MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
-
- /* setup stuff */
- q->read_buf = videobuf_alloc_vb(q);
- if (NULL == q->read_buf)
- return -ENOMEM;
-
- q->read_buf->memory = V4L2_MEMORY_USERPTR;
- q->read_buf->baddr = (unsigned long)data;
- q->read_buf->bsize = count;
-
- field = videobuf_next_field(q);
- retval = q->ops->buf_prepare(q, q->read_buf, field);
- if (0 != retval)
- goto done;
-
- /* start capture & wait */
- spin_lock_irqsave(q->irqlock, flags);
- q->ops->buf_queue(q, q->read_buf);
- spin_unlock_irqrestore(q->irqlock, flags);
- retval = videobuf_waiton(q, q->read_buf, 0, 0);
- if (0 == retval) {
- CALL(q, sync, q, q->read_buf);
- if (VIDEOBUF_ERROR == q->read_buf->state)
- retval = -EIO;
- else
- retval = q->read_buf->size;
- }
-
-done:
- /* cleanup */
- q->ops->buf_release(q, q->read_buf);
- kfree(q->read_buf);
- q->read_buf = NULL;
- return retval;
-}
-
-static int __videobuf_copy_to_user(struct videobuf_queue *q,
- struct videobuf_buffer *buf,
- char __user *data, size_t count,
- int nonblocking)
-{
- void *vaddr = CALL(q, vaddr, buf);
-
- /* copy to userspace */
- if (count > buf->size - q->read_off)
- count = buf->size - q->read_off;
-
- if (copy_to_user(data, vaddr + q->read_off, count))
- return -EFAULT;
-
- return count;
-}
-
-static int __videobuf_copy_stream(struct videobuf_queue *q,
- struct videobuf_buffer *buf,
- char __user *data, size_t count, size_t pos,
- int vbihack, int nonblocking)
-{
- unsigned int *fc = CALL(q, vaddr, buf);
-
- if (vbihack) {
- /* dirty, undocumented hack -- pass the frame counter
- * within the last four bytes of each vbi data block.
- * We need that one to maintain backward compatibility
- * to all vbi decoding software out there ... */
- fc += (buf->size >> 2) - 1;
- *fc = buf->field_count >> 1;
- dprintk(1, "vbihack: %d\n", *fc);
- }
-
- /* copy stuff using the common method */
- count = __videobuf_copy_to_user(q, buf, data, count, nonblocking);
-
- if ((count == -EFAULT) && (pos == 0))
- return -EFAULT;
-
- return count;
-}
-
-ssize_t videobuf_read_one(struct videobuf_queue *q,
- char __user *data, size_t count, loff_t *ppos,
- int nonblocking)
-{
- enum v4l2_field field;
- unsigned long flags = 0;
- unsigned size = 0, nbufs = 1;
- int retval;
-
- MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
-
- videobuf_queue_lock(q);
-
- q->ops->buf_setup(q, &nbufs, &size);
-
- if (NULL == q->read_buf &&
- count >= size &&
- !nonblocking) {
- retval = videobuf_read_zerocopy(q, data, count, ppos);
- if (retval >= 0 || retval == -EIO)
- /* ok, all done */
- goto done;
- /* fallback to kernel bounce buffer on failures */
- }
-
- if (NULL == q->read_buf) {
- /* need to capture a new frame */
- retval = -ENOMEM;
- q->read_buf = videobuf_alloc_vb(q);
-
- dprintk(1, "video alloc=0x%p\n", q->read_buf);
- if (NULL == q->read_buf)
- goto done;
- q->read_buf->memory = V4L2_MEMORY_USERPTR;
- q->read_buf->bsize = count; /* preferred size */
- field = videobuf_next_field(q);
- retval = q->ops->buf_prepare(q, q->read_buf, field);
-
- if (0 != retval) {
- kfree(q->read_buf);
- q->read_buf = NULL;
- goto done;
- }
-
- spin_lock_irqsave(q->irqlock, flags);
- q->ops->buf_queue(q, q->read_buf);
- spin_unlock_irqrestore(q->irqlock, flags);
-
- q->read_off = 0;
- }
-
- /* wait until capture is done */
- retval = videobuf_waiton(q, q->read_buf, nonblocking, 1);
- if (0 != retval)
- goto done;
-
- CALL(q, sync, q, q->read_buf);
-
- if (VIDEOBUF_ERROR == q->read_buf->state) {
- /* catch I/O errors */
- q->ops->buf_release(q, q->read_buf);
- kfree(q->read_buf);
- q->read_buf = NULL;
- retval = -EIO;
- goto done;
- }
-
- /* Copy to userspace */
- retval = __videobuf_copy_to_user(q, q->read_buf, data, count, nonblocking);
- if (retval < 0)
- goto done;
-
- q->read_off += retval;
- if (q->read_off == q->read_buf->size) {
- /* all data copied, cleanup */
- q->ops->buf_release(q, q->read_buf);
- kfree(q->read_buf);
- q->read_buf = NULL;
- }
-
-done:
- videobuf_queue_unlock(q);
- return retval;
-}
-EXPORT_SYMBOL_GPL(videobuf_read_one);
-
-/* Locking: Caller holds q->vb_lock */
-static int __videobuf_read_start(struct videobuf_queue *q)
-{
- enum v4l2_field field;
- unsigned long flags = 0;
- unsigned int count = 0, size = 0;
- int err, i;
-
- q->ops->buf_setup(q, &count, &size);
- if (count < 2)
- count = 2;
- if (count > VIDEO_MAX_FRAME)
- count = VIDEO_MAX_FRAME;
- size = PAGE_ALIGN(size);
-
- err = __videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR);
- if (err < 0)
- return err;
-
- count = err;
-
- for (i = 0; i < count; i++) {
- field = videobuf_next_field(q);
- err = q->ops->buf_prepare(q, q->bufs[i], field);
- if (err)
- return err;
- list_add_tail(&q->bufs[i]->stream, &q->stream);
- }
- spin_lock_irqsave(q->irqlock, flags);
- for (i = 0; i < count; i++)
- q->ops->buf_queue(q, q->bufs[i]);
- spin_unlock_irqrestore(q->irqlock, flags);
- q->reading = 1;
- return 0;
-}
-
-static void __videobuf_read_stop(struct videobuf_queue *q)
-{
- int i;
-
- videobuf_queue_cancel(q);
- __videobuf_free(q);
- INIT_LIST_HEAD(&q->stream);
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- if (NULL == q->bufs[i])
- continue;
- kfree(q->bufs[i]);
- q->bufs[i] = NULL;
- }
- q->read_buf = NULL;
-}
-
-int videobuf_read_start(struct videobuf_queue *q)
-{
- int rc;
-
- videobuf_queue_lock(q);
- rc = __videobuf_read_start(q);
- videobuf_queue_unlock(q);
-
- return rc;
-}
-EXPORT_SYMBOL_GPL(videobuf_read_start);
-
-void videobuf_read_stop(struct videobuf_queue *q)
-{
- videobuf_queue_lock(q);
- __videobuf_read_stop(q);
- videobuf_queue_unlock(q);
-}
-EXPORT_SYMBOL_GPL(videobuf_read_stop);
-
-void videobuf_stop(struct videobuf_queue *q)
-{
- videobuf_queue_lock(q);
-
- if (q->streaming)
- __videobuf_streamoff(q);
-
- if (q->reading)
- __videobuf_read_stop(q);
-
- videobuf_queue_unlock(q);
-}
-EXPORT_SYMBOL_GPL(videobuf_stop);
-
-ssize_t videobuf_read_stream(struct videobuf_queue *q,
- char __user *data, size_t count, loff_t *ppos,
- int vbihack, int nonblocking)
-{
- int rc, retval;
- unsigned long flags = 0;
-
- MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
-
- dprintk(2, "%s\n", __func__);
- videobuf_queue_lock(q);
- retval = -EBUSY;
- if (q->streaming)
- goto done;
- if (!q->reading) {
- retval = __videobuf_read_start(q);
- if (retval < 0)
- goto done;
- }
-
- retval = 0;
- while (count > 0) {
- /* get / wait for data */
- if (NULL == q->read_buf) {
- q->read_buf = list_entry(q->stream.next,
- struct videobuf_buffer,
- stream);
- list_del(&q->read_buf->stream);
- q->read_off = 0;
- }
- rc = videobuf_waiton(q, q->read_buf, nonblocking, 1);
- if (rc < 0) {
- if (0 == retval)
- retval = rc;
- break;
- }
-
- if (q->read_buf->state == VIDEOBUF_DONE) {
- rc = __videobuf_copy_stream(q, q->read_buf, data + retval, count,
- retval, vbihack, nonblocking);
- if (rc < 0) {
- retval = rc;
- break;
- }
- retval += rc;
- count -= rc;
- q->read_off += rc;
- } else {
- /* some error */
- q->read_off = q->read_buf->size;
- if (0 == retval)
- retval = -EIO;
- }
-
- /* requeue buffer when done with copying */
- if (q->read_off == q->read_buf->size) {
- list_add_tail(&q->read_buf->stream,
- &q->stream);
- spin_lock_irqsave(q->irqlock, flags);
- q->ops->buf_queue(q, q->read_buf);
- spin_unlock_irqrestore(q->irqlock, flags);
- q->read_buf = NULL;
- }
- if (retval < 0)
- break;
- }
-
-done:
- videobuf_queue_unlock(q);
- return retval;
-}
-EXPORT_SYMBOL_GPL(videobuf_read_stream);
-
-unsigned int videobuf_poll_stream(struct file *file,
- struct videobuf_queue *q,
- poll_table *wait)
-{
- unsigned long req_events = poll_requested_events(wait);
- struct videobuf_buffer *buf = NULL;
- unsigned int rc = 0;
-
- videobuf_queue_lock(q);
- if (q->streaming) {
- if (!list_empty(&q->stream))
- buf = list_entry(q->stream.next,
- struct videobuf_buffer, stream);
- } else if (req_events & (POLLIN | POLLRDNORM)) {
- if (!q->reading)
- __videobuf_read_start(q);
- if (!q->reading) {
- rc = POLLERR;
- } else if (NULL == q->read_buf) {
- q->read_buf = list_entry(q->stream.next,
- struct videobuf_buffer,
- stream);
- list_del(&q->read_buf->stream);
- q->read_off = 0;
- }
- buf = q->read_buf;
- }
- if (!buf)
- rc = POLLERR;
-
- if (0 == rc) {
- poll_wait(file, &buf->done, wait);
- if (buf->state == VIDEOBUF_DONE ||
- buf->state == VIDEOBUF_ERROR) {
- switch (q->type) {
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- rc = POLLOUT | POLLWRNORM;
- break;
- default:
- rc = POLLIN | POLLRDNORM;
- break;
- }
- }
- }
- videobuf_queue_unlock(q);
- return rc;
-}
-EXPORT_SYMBOL_GPL(videobuf_poll_stream);
-
-int videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma)
-{
- int rc = -EINVAL;
- int i;
-
- MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
-
- if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) {
- dprintk(1, "mmap appl bug: PROT_WRITE and MAP_SHARED are required\n");
- return -EINVAL;
- }
-
- videobuf_queue_lock(q);
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- struct videobuf_buffer *buf = q->bufs[i];
-
- if (buf && buf->memory == V4L2_MEMORY_MMAP &&
- buf->boff == (vma->vm_pgoff << PAGE_SHIFT)) {
- rc = CALL(q, mmap_mapper, q, buf, vma);
- break;
- }
- }
- videobuf_queue_unlock(q);
-
- return rc;
-}
-EXPORT_SYMBOL_GPL(videobuf_mmap_mapper);
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
deleted file mode 100644
index 3a43ba0959b..00000000000
--- a/drivers/media/video/videobuf-dma-contig.c
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * helper functions for physically contiguous capture buffers
- *
- * The functions support hardware lacking scatter gather support
- * (i.e. the buffers must be linear in physical memory)
- *
- * Copyright (c) 2008 Magnus Damm
- *
- * Based on videobuf-vmalloc.c,
- * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-#include <linux/dma-mapping.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <media/videobuf-dma-contig.h>
-
-struct videobuf_dma_contig_memory {
- u32 magic;
- void *vaddr;
- dma_addr_t dma_handle;
- bool cached;
- unsigned long size;
-};
-
-#define MAGIC_DC_MEM 0x0733ac61
-#define MAGIC_CHECK(is, should) \
- if (unlikely((is) != (should))) { \
- pr_err("magic mismatch: %x expected %x\n", (is), (should)); \
- BUG(); \
- }
-
-static int __videobuf_dc_alloc(struct device *dev,
- struct videobuf_dma_contig_memory *mem,
- unsigned long size, gfp_t flags)
-{
- mem->size = size;
- if (mem->cached) {
- mem->vaddr = alloc_pages_exact(mem->size, flags | GFP_DMA);
- if (mem->vaddr) {
- int err;
-
- mem->dma_handle = dma_map_single(dev, mem->vaddr,
- mem->size,
- DMA_FROM_DEVICE);
- err = dma_mapping_error(dev, mem->dma_handle);
- if (err) {
- dev_err(dev, "dma_map_single failed\n");
-
- free_pages_exact(mem->vaddr, mem->size);
- mem->vaddr = NULL;
- return err;
- }
- }
- } else
- mem->vaddr = dma_alloc_coherent(dev, mem->size,
- &mem->dma_handle, flags);
-
- if (!mem->vaddr) {
- dev_err(dev, "memory alloc size %ld failed\n", mem->size);
- return -ENOMEM;
- }
-
- dev_dbg(dev, "dma mapped data is at %p (%ld)\n", mem->vaddr, mem->size);
-
- return 0;
-}
-
-static void __videobuf_dc_free(struct device *dev,
- struct videobuf_dma_contig_memory *mem)
-{
- if (mem->cached) {
- if (!mem->vaddr)
- return;
- dma_unmap_single(dev, mem->dma_handle, mem->size,
- DMA_FROM_DEVICE);
- free_pages_exact(mem->vaddr, mem->size);
- } else
- dma_free_coherent(dev, mem->size, mem->vaddr, mem->dma_handle);
-
- mem->vaddr = NULL;
-}
-
-static void videobuf_vm_open(struct vm_area_struct *vma)
-{
- struct videobuf_mapping *map = vma->vm_private_data;
-
- dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
- map, map->count, vma->vm_start, vma->vm_end);
-
- map->count++;
-}
-
-static void videobuf_vm_close(struct vm_area_struct *vma)
-{
- struct videobuf_mapping *map = vma->vm_private_data;
- struct videobuf_queue *q = map->q;
- int i;
-
- dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
- map, map->count, vma->vm_start, vma->vm_end);
-
- map->count--;
- if (0 == map->count) {
- struct videobuf_dma_contig_memory *mem;
-
- dev_dbg(q->dev, "munmap %p q=%p\n", map, q);
- videobuf_queue_lock(q);
-
- /* We need first to cancel streams, before unmapping */
- if (q->streaming)
- videobuf_queue_cancel(q);
-
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- if (NULL == q->bufs[i])
- continue;
-
- if (q->bufs[i]->map != map)
- continue;
-
- mem = q->bufs[i]->priv;
- if (mem) {
- /* This callback is called only if kernel has
- allocated memory and this memory is mmapped.
- In this case, memory should be freed,
- in order to do memory unmap.
- */
-
- MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
-
- /* vfree is not atomic - can't be
- called with IRQ's disabled
- */
- dev_dbg(q->dev, "buf[%d] freeing %p\n",
- i, mem->vaddr);
-
- __videobuf_dc_free(q->dev, mem);
- mem->vaddr = NULL;
- }
-
- q->bufs[i]->map = NULL;
- q->bufs[i]->baddr = 0;
- }
-
- kfree(map);
-
- videobuf_queue_unlock(q);
- }
-}
-
-static const struct vm_operations_struct videobuf_vm_ops = {
- .open = videobuf_vm_open,
- .close = videobuf_vm_close,
-};
-
-/**
- * videobuf_dma_contig_user_put() - reset pointer to user space buffer
- * @mem: per-buffer private videobuf-dma-contig data
- *
- * This function resets the user space pointer
- */
-static void videobuf_dma_contig_user_put(struct videobuf_dma_contig_memory *mem)
-{
- mem->dma_handle = 0;
- mem->size = 0;
-}
-
-/**
- * videobuf_dma_contig_user_get() - setup user space memory pointer
- * @mem: per-buffer private videobuf-dma-contig data
- * @vb: video buffer to map
- *
- * This function validates and sets up a pointer to user space memory.
- * Only physically contiguous pfn-mapped memory is accepted.
- *
- * Returns 0 if successful.
- */
-static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
- struct videobuf_buffer *vb)
-{
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
- unsigned long prev_pfn, this_pfn;
- unsigned long pages_done, user_address;
- unsigned int offset;
- int ret;
-
- offset = vb->baddr & ~PAGE_MASK;
- mem->size = PAGE_ALIGN(vb->size + offset);
- ret = -EINVAL;
-
- down_read(&mm->mmap_sem);
-
- vma = find_vma(mm, vb->baddr);
- if (!vma)
- goto out_up;
-
- if ((vb->baddr + mem->size) > vma->vm_end)
- goto out_up;
-
- pages_done = 0;
- prev_pfn = 0; /* kill warning */
- user_address = vb->baddr;
-
- while (pages_done < (mem->size >> PAGE_SHIFT)) {
- ret = follow_pfn(vma, user_address, &this_pfn);
- if (ret)
- break;
-
- if (pages_done == 0)
- mem->dma_handle = (this_pfn << PAGE_SHIFT) + offset;
- else if (this_pfn != (prev_pfn + 1))
- ret = -EFAULT;
-
- if (ret)
- break;
-
- prev_pfn = this_pfn;
- user_address += PAGE_SIZE;
- pages_done++;
- }
-
-out_up:
- up_read(&current->mm->mmap_sem);
-
- return ret;
-}
-
-static struct videobuf_buffer *__videobuf_alloc_vb(size_t size, bool cached)
-{
- struct videobuf_dma_contig_memory *mem;
- struct videobuf_buffer *vb;
-
- vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
- if (vb) {
- vb->priv = ((char *)vb) + size;
- mem = vb->priv;
- mem->magic = MAGIC_DC_MEM;
- mem->cached = cached;
- }
-
- return vb;
-}
-
-static struct videobuf_buffer *__videobuf_alloc_uncached(size_t size)
-{
- return __videobuf_alloc_vb(size, false);
-}
-
-static struct videobuf_buffer *__videobuf_alloc_cached(size_t size)
-{
- return __videobuf_alloc_vb(size, true);
-}
-
-static void *__videobuf_to_vaddr(struct videobuf_buffer *buf)
-{
- struct videobuf_dma_contig_memory *mem = buf->priv;
-
- BUG_ON(!mem);
- MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
-
- return mem->vaddr;
-}
-
-static int __videobuf_iolock(struct videobuf_queue *q,
- struct videobuf_buffer *vb,
- struct v4l2_framebuffer *fbuf)
-{
- struct videobuf_dma_contig_memory *mem = vb->priv;
-
- BUG_ON(!mem);
- MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
-
- switch (vb->memory) {
- case V4L2_MEMORY_MMAP:
- dev_dbg(q->dev, "%s memory method MMAP\n", __func__);
-
- /* All handling should be done by __videobuf_mmap_mapper() */
- if (!mem->vaddr) {
- dev_err(q->dev, "memory is not alloced/mmapped.\n");
- return -EINVAL;
- }
- break;
- case V4L2_MEMORY_USERPTR:
- dev_dbg(q->dev, "%s memory method USERPTR\n", __func__);
-
- /* handle pointer from user space */
- if (vb->baddr)
- return videobuf_dma_contig_user_get(mem, vb);
-
- /* allocate memory for the read() method */
- if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(vb->size),
- GFP_KERNEL))
- return -ENOMEM;
- break;
- case V4L2_MEMORY_OVERLAY:
- default:
- dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int __videobuf_sync(struct videobuf_queue *q,
- struct videobuf_buffer *buf)
-{
- struct videobuf_dma_contig_memory *mem = buf->priv;
- BUG_ON(!mem);
- MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
-
- dma_sync_single_for_cpu(q->dev, mem->dma_handle, mem->size,
- DMA_FROM_DEVICE);
-
- return 0;
-}
-
-static int __videobuf_mmap_mapper(struct videobuf_queue *q,
- struct videobuf_buffer *buf,
- struct vm_area_struct *vma)
-{
- struct videobuf_dma_contig_memory *mem;
- struct videobuf_mapping *map;
- int retval;
- unsigned long size;
- unsigned long pos, start = vma->vm_start;
- struct page *page;
-
- dev_dbg(q->dev, "%s\n", __func__);
-
- /* create mapping + update buffer list */
- map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
- if (!map)
- return -ENOMEM;
-
- buf->map = map;
- map->q = q;
-
- buf->baddr = vma->vm_start;
-
- mem = buf->priv;
- BUG_ON(!mem);
- MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
-
- if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(buf->bsize),
- GFP_KERNEL | __GFP_COMP))
- goto error;
-
- /* Try to remap memory */
-
- size = vma->vm_end - vma->vm_start;
- size = (size < mem->size) ? size : mem->size;
-
- if (!mem->cached) {
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- retval = remap_pfn_range(vma, vma->vm_start,
- mem->dma_handle >> PAGE_SHIFT,
- size, vma->vm_page_prot);
- if (retval) {
- dev_err(q->dev, "mmap: remap failed with error %d. ",
- retval);
- dma_free_coherent(q->dev, mem->size,
- mem->vaddr, mem->dma_handle);
- goto error;
- }
- } else {
- pos = (unsigned long)mem->vaddr;
-
- while (size > 0) {
- page = virt_to_page((void *)pos);
- if (NULL == page) {
- dev_err(q->dev, "mmap: virt_to_page failed\n");
- __videobuf_dc_free(q->dev, mem);
- goto error;
- }
- retval = vm_insert_page(vma, start, page);
- if (retval) {
- dev_err(q->dev, "mmap: insert failed with error %d\n",
- retval);
- __videobuf_dc_free(q->dev, mem);
- goto error;
- }
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
-
- if (size > PAGE_SIZE)
- size -= PAGE_SIZE;
- else
- size = 0;
- }
- }
-
- vma->vm_ops = &videobuf_vm_ops;
- vma->vm_flags |= VM_DONTEXPAND;
- vma->vm_private_data = map;
-
- dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
- map, q, vma->vm_start, vma->vm_end,
- (long int)buf->bsize, vma->vm_pgoff, buf->i);
-
- videobuf_vm_open(vma);
-
- return 0;
-
-error:
- kfree(map);
- return -ENOMEM;
-}
-
-static struct videobuf_qtype_ops qops = {
- .magic = MAGIC_QTYPE_OPS,
- .alloc_vb = __videobuf_alloc_uncached,
- .iolock = __videobuf_iolock,
- .mmap_mapper = __videobuf_mmap_mapper,
- .vaddr = __videobuf_to_vaddr,
-};
-
-static struct videobuf_qtype_ops qops_cached = {
- .magic = MAGIC_QTYPE_OPS,
- .alloc_vb = __videobuf_alloc_cached,
- .iolock = __videobuf_iolock,
- .sync = __videobuf_sync,
- .mmap_mapper = __videobuf_mmap_mapper,
- .vaddr = __videobuf_to_vaddr,
-};
-
-void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
- const struct videobuf_queue_ops *ops,
- struct device *dev,
- spinlock_t *irqlock,
- enum v4l2_buf_type type,
- enum v4l2_field field,
- unsigned int msize,
- void *priv,
- struct mutex *ext_lock)
-{
- videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
- priv, &qops, ext_lock);
-}
-EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init);
-
-void videobuf_queue_dma_contig_init_cached(struct videobuf_queue *q,
- const struct videobuf_queue_ops *ops,
- struct device *dev,
- spinlock_t *irqlock,
- enum v4l2_buf_type type,
- enum v4l2_field field,
- unsigned int msize,
- void *priv, struct mutex *ext_lock)
-{
- videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
- priv, &qops_cached, ext_lock);
-}
-EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init_cached);
-
-dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf)
-{
- struct videobuf_dma_contig_memory *mem = buf->priv;
-
- BUG_ON(!mem);
- MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
-
- return mem->dma_handle;
-}
-EXPORT_SYMBOL_GPL(videobuf_to_dma_contig);
-
-void videobuf_dma_contig_free(struct videobuf_queue *q,
- struct videobuf_buffer *buf)
-{
- struct videobuf_dma_contig_memory *mem = buf->priv;
-
- /* mmapped memory can't be freed here, otherwise mmapped region
- would be released, while still needed. In this case, the memory
- release should happen inside videobuf_vm_close().
- So, it should free memory only if the memory were allocated for
- read() operation.
- */
- if (buf->memory != V4L2_MEMORY_USERPTR)
- return;
-
- if (!mem)
- return;
-
- MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
-
- /* handle user space pointer case */
- if (buf->baddr) {
- videobuf_dma_contig_user_put(mem);
- return;
- }
-
- /* read() method */
- if (mem->vaddr) {
- __videobuf_dc_free(q->dev, mem);
- mem->vaddr = NULL;
- }
-}
-EXPORT_SYMBOL_GPL(videobuf_dma_contig_free);
-
-MODULE_DESCRIPTION("helper module to manage video4linux dma contig buffers");
-MODULE_AUTHOR("Magnus Damm");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
deleted file mode 100644
index f300deafd26..00000000000
--- a/drivers/media/video/videobuf-dma-sg.c
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- * helper functions for SG DMA video4linux capture buffers
- *
- * The functions expect the hardware being able to scatter gather
- * (i.e. the buffers are not linear in physical memory, but fragmented
- * into PAGE_SIZE chunks). They also assume the driver does not need
- * to touch the video data.
- *
- * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
- *
- * Highly based on video-buf written originally by:
- * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
- * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org>
- * (c) 2006 Ted Walther and John Sokol
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-
-#include <linux/dma-mapping.h>
-#include <linux/vmalloc.h>
-#include <linux/pagemap.h>
-#include <linux/scatterlist.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-#include <media/videobuf-dma-sg.h>
-
-#define MAGIC_DMABUF 0x19721112
-#define MAGIC_SG_MEM 0x17890714
-
-#define MAGIC_CHECK(is, should) \
- if (unlikely((is) != (should))) { \
- printk(KERN_ERR "magic mismatch: %x (expected %x)\n", \
- is, should); \
- BUG(); \
- }
-
-static int debug;
-module_param(debug, int, 0644);
-
-MODULE_DESCRIPTION("helper module to manage video4linux dma sg buffers");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_LICENSE("GPL");
-
-#define dprintk(level, fmt, arg...) \
- if (debug >= level) \
- printk(KERN_DEBUG "vbuf-sg: " fmt , ## arg)
-
-/* --------------------------------------------------------------------- */
-
-/*
- * Return a scatterlist for some page-aligned vmalloc()'ed memory
- * block (NULL on errors). Memory for the scatterlist is allocated
- * using kmalloc. The caller must free the memory.
- */
-static struct scatterlist *videobuf_vmalloc_to_sg(unsigned char *virt,
- int nr_pages)
-{
- struct scatterlist *sglist;
- struct page *pg;
- int i;
-
- sglist = vzalloc(nr_pages * sizeof(*sglist));
- if (NULL == sglist)
- return NULL;
- sg_init_table(sglist, nr_pages);
- for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
- pg = vmalloc_to_page(virt);
- if (NULL == pg)
- goto err;
- BUG_ON(PageHighMem(pg));
- sg_set_page(&sglist[i], pg, PAGE_SIZE, 0);
- }
- return sglist;
-
-err:
- vfree(sglist);
- return NULL;
-}
-
-/*
- * Return a scatterlist for a an array of userpages (NULL on errors).
- * Memory for the scatterlist is allocated using kmalloc. The caller
- * must free the memory.
- */
-static struct scatterlist *videobuf_pages_to_sg(struct page **pages,
- int nr_pages, int offset, size_t size)
-{
- struct scatterlist *sglist;
- int i;
-
- if (NULL == pages[0])
- return NULL;
- sglist = vmalloc(nr_pages * sizeof(*sglist));
- if (NULL == sglist)
- return NULL;
- sg_init_table(sglist, nr_pages);
-
- if (PageHighMem(pages[0]))
- /* DMA to highmem pages might not work */
- goto highmem;
- sg_set_page(&sglist[0], pages[0],
- min_t(size_t, PAGE_SIZE - offset, size), offset);
- size -= min_t(size_t, PAGE_SIZE - offset, size);
- for (i = 1; i < nr_pages; i++) {
- if (NULL == pages[i])
- goto nopage;
- if (PageHighMem(pages[i]))
- goto highmem;
- sg_set_page(&sglist[i], pages[i], min_t(size_t, PAGE_SIZE, size), 0);
- size -= min_t(size_t, PAGE_SIZE, size);
- }
- return sglist;
-
-nopage:
- dprintk(2, "sgl: oops - no page\n");
- vfree(sglist);
- return NULL;
-
-highmem:
- dprintk(2, "sgl: oops - highmem page\n");
- vfree(sglist);
- return NULL;
-}
-
-/* --------------------------------------------------------------------- */
-
-struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf)
-{
- struct videobuf_dma_sg_memory *mem = buf->priv;
- BUG_ON(!mem);
-
- MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
-
- return &mem->dma;
-}
-EXPORT_SYMBOL_GPL(videobuf_to_dma);
-
-void videobuf_dma_init(struct videobuf_dmabuf *dma)
-{
- memset(dma, 0, sizeof(*dma));
- dma->magic = MAGIC_DMABUF;
-}
-EXPORT_SYMBOL_GPL(videobuf_dma_init);
-
-static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma,
- int direction, unsigned long data, unsigned long size)
-{
- unsigned long first, last;
- int err, rw = 0;
-
- dma->direction = direction;
- switch (dma->direction) {
- case DMA_FROM_DEVICE:
- rw = READ;
- break;
- case DMA_TO_DEVICE:
- rw = WRITE;
- break;
- default:
- BUG();
- }
-
- first = (data & PAGE_MASK) >> PAGE_SHIFT;
- last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT;
- dma->offset = data & ~PAGE_MASK;
- dma->size = size;
- dma->nr_pages = last-first+1;
- dma->pages = kmalloc(dma->nr_pages * sizeof(struct page *), GFP_KERNEL);
- if (NULL == dma->pages)
- return -ENOMEM;
-
- dprintk(1, "init user [0x%lx+0x%lx => %d pages]\n",
- data, size, dma->nr_pages);
-
- err = get_user_pages(current, current->mm,
- data & PAGE_MASK, dma->nr_pages,
- rw == READ, 1, /* force */
- dma->pages, NULL);
-
- if (err != dma->nr_pages) {
- dma->nr_pages = (err >= 0) ? err : 0;
- dprintk(1, "get_user_pages: err=%d [%d]\n", err, dma->nr_pages);
- return err < 0 ? err : -EINVAL;
- }
- return 0;
-}
-
-int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
- unsigned long data, unsigned long size)
-{
- int ret;
-
- down_read(&current->mm->mmap_sem);
- ret = videobuf_dma_init_user_locked(dma, direction, data, size);
- up_read(&current->mm->mmap_sem);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(videobuf_dma_init_user);
-
-int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
- int nr_pages)
-{
- dprintk(1, "init kernel [%d pages]\n", nr_pages);
-
- dma->direction = direction;
- dma->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
- if (NULL == dma->vaddr) {
- dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages);
- return -ENOMEM;
- }
-
- dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n",
- (unsigned long)dma->vaddr,
- nr_pages << PAGE_SHIFT);
-
- memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT);
- dma->nr_pages = nr_pages;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(videobuf_dma_init_kernel);
-
-int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
- dma_addr_t addr, int nr_pages)
-{
- dprintk(1, "init overlay [%d pages @ bus 0x%lx]\n",
- nr_pages, (unsigned long)addr);
- dma->direction = direction;
-
- if (0 == addr)
- return -EINVAL;
-
- dma->bus_addr = addr;
- dma->nr_pages = nr_pages;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(videobuf_dma_init_overlay);
-
-int videobuf_dma_map(struct device *dev, struct videobuf_dmabuf *dma)
-{
- MAGIC_CHECK(dma->magic, MAGIC_DMABUF);
- BUG_ON(0 == dma->nr_pages);
-
- if (dma->pages) {
- dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages,
- dma->offset, dma->size);
- }
- if (dma->vaddr) {
- dma->sglist = videobuf_vmalloc_to_sg(dma->vaddr,
- dma->nr_pages);
- }
- if (dma->bus_addr) {
- dma->sglist = vmalloc(sizeof(*dma->sglist));
- if (NULL != dma->sglist) {
- dma->sglen = 1;
- sg_dma_address(&dma->sglist[0]) = dma->bus_addr
- & PAGE_MASK;
- dma->sglist[0].offset = dma->bus_addr & ~PAGE_MASK;
- sg_dma_len(&dma->sglist[0]) = dma->nr_pages * PAGE_SIZE;
- }
- }
- if (NULL == dma->sglist) {
- dprintk(1, "scatterlist is NULL\n");
- return -ENOMEM;
- }
- if (!dma->bus_addr) {
- dma->sglen = dma_map_sg(dev, dma->sglist,
- dma->nr_pages, dma->direction);
- if (0 == dma->sglen) {
- printk(KERN_WARNING
- "%s: videobuf_map_sg failed\n", __func__);
- vfree(dma->sglist);
- dma->sglist = NULL;
- dma->sglen = 0;
- return -ENOMEM;
- }
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(videobuf_dma_map);
-
-int videobuf_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma)
-{
- MAGIC_CHECK(dma->magic, MAGIC_DMABUF);
-
- if (!dma->sglen)
- return 0;
-
- dma_unmap_sg(dev, dma->sglist, dma->sglen, dma->direction);
-
- vfree(dma->sglist);
- dma->sglist = NULL;
- dma->sglen = 0;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(videobuf_dma_unmap);
-
-int videobuf_dma_free(struct videobuf_dmabuf *dma)
-{
- int i;
- MAGIC_CHECK(dma->magic, MAGIC_DMABUF);
- BUG_ON(dma->sglen);
-
- if (dma->pages) {
- for (i = 0; i < dma->nr_pages; i++)
- page_cache_release(dma->pages[i]);
- kfree(dma->pages);
- dma->pages = NULL;
- }
-
- vfree(dma->vaddr);
- dma->vaddr = NULL;
-
- if (dma->bus_addr)
- dma->bus_addr = 0;
- dma->direction = DMA_NONE;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(videobuf_dma_free);
-
-/* --------------------------------------------------------------------- */
-
-static void videobuf_vm_open(struct vm_area_struct *vma)
-{
- struct videobuf_mapping *map = vma->vm_private_data;
-
- dprintk(2, "vm_open %p [count=%d,vma=%08lx-%08lx]\n", map,
- map->count, vma->vm_start, vma->vm_end);
-
- map->count++;
-}
-
-static void videobuf_vm_close(struct vm_area_struct *vma)
-{
- struct videobuf_mapping *map = vma->vm_private_data;
- struct videobuf_queue *q = map->q;
- struct videobuf_dma_sg_memory *mem;
- int i;
-
- dprintk(2, "vm_close %p [count=%d,vma=%08lx-%08lx]\n", map,
- map->count, vma->vm_start, vma->vm_end);
-
- map->count--;
- if (0 == map->count) {
- dprintk(1, "munmap %p q=%p\n", map, q);
- videobuf_queue_lock(q);
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- if (NULL == q->bufs[i])
- continue;
- mem = q->bufs[i]->priv;
- if (!mem)
- continue;
-
- MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
-
- if (q->bufs[i]->map != map)
- continue;
- q->bufs[i]->map = NULL;
- q->bufs[i]->baddr = 0;
- q->ops->buf_release(q, q->bufs[i]);
- }
- videobuf_queue_unlock(q);
- kfree(map);
- }
- return;
-}
-
-/*
- * Get a anonymous page for the mapping. Make sure we can DMA to that
- * memory location with 32bit PCI devices (i.e. don't use highmem for
- * now ...). Bounce buffers don't work very well for the data rates
- * video capture has.
- */
-static int videobuf_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
- struct page *page;
-
- dprintk(3, "fault: fault @ %08lx [vma %08lx-%08lx]\n",
- (unsigned long)vmf->virtual_address,
- vma->vm_start, vma->vm_end);
-
- page = alloc_page(GFP_USER | __GFP_DMA32);
- if (!page)
- return VM_FAULT_OOM;
- clear_user_highpage(page, (unsigned long)vmf->virtual_address);
- vmf->page = page;
-
- return 0;
-}
-
-static const struct vm_operations_struct videobuf_vm_ops = {
- .open = videobuf_vm_open,
- .close = videobuf_vm_close,
- .fault = videobuf_vm_fault,
-};
-
-/* ---------------------------------------------------------------------
- * SG handlers for the generic methods
- */
-
-/* Allocated area consists on 3 parts:
- struct video_buffer
- struct <driver>_buffer (cx88_buffer, saa7134_buf, ...)
- struct videobuf_dma_sg_memory
- */
-
-static struct videobuf_buffer *__videobuf_alloc_vb(size_t size)
-{
- struct videobuf_dma_sg_memory *mem;
- struct videobuf_buffer *vb;
-
- vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
- if (!vb)
- return vb;
-
- mem = vb->priv = ((char *)vb) + size;
- mem->magic = MAGIC_SG_MEM;
-
- videobuf_dma_init(&mem->dma);
-
- dprintk(1, "%s: allocated at %p(%ld+%ld) & %p(%ld)\n",
- __func__, vb, (long)sizeof(*vb), (long)size - sizeof(*vb),
- mem, (long)sizeof(*mem));
-
- return vb;
-}
-
-static void *__videobuf_to_vaddr(struct videobuf_buffer *buf)
-{
- struct videobuf_dma_sg_memory *mem = buf->priv;
- BUG_ON(!mem);
-
- MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
-
- return mem->dma.vaddr;
-}
-
-static int __videobuf_iolock(struct videobuf_queue *q,
- struct videobuf_buffer *vb,
- struct v4l2_framebuffer *fbuf)
-{
- int err, pages;
- dma_addr_t bus;
- struct videobuf_dma_sg_memory *mem = vb->priv;
- BUG_ON(!mem);
-
- MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
-
- switch (vb->memory) {
- case V4L2_MEMORY_MMAP:
- case V4L2_MEMORY_USERPTR:
- if (0 == vb->baddr) {
- /* no userspace addr -- kernel bounce buffer */
- pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
- err = videobuf_dma_init_kernel(&mem->dma,
- DMA_FROM_DEVICE,
- pages);
- if (0 != err)
- return err;
- } else if (vb->memory == V4L2_MEMORY_USERPTR) {
- /* dma directly to userspace */
- err = videobuf_dma_init_user(&mem->dma,
- DMA_FROM_DEVICE,
- vb->baddr, vb->bsize);
- if (0 != err)
- return err;
- } else {
- /* NOTE: HACK: videobuf_iolock on V4L2_MEMORY_MMAP
- buffers can only be called from videobuf_qbuf
- we take current->mm->mmap_sem there, to prevent
- locking inversion, so don't take it here */
-
- err = videobuf_dma_init_user_locked(&mem->dma,
- DMA_FROM_DEVICE,
- vb->baddr, vb->bsize);
- if (0 != err)
- return err;
- }
- break;
- case V4L2_MEMORY_OVERLAY:
- if (NULL == fbuf)
- return -EINVAL;
- /* FIXME: need sanity checks for vb->boff */
- /*
- * Using a double cast to avoid compiler warnings when
- * building for PAE. Compiler doesn't like direct casting
- * of a 32 bit ptr to 64 bit integer.
- */
- bus = (dma_addr_t)(unsigned long)fbuf->base + vb->boff;
- pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
- err = videobuf_dma_init_overlay(&mem->dma, DMA_FROM_DEVICE,
- bus, pages);
- if (0 != err)
- return err;
- break;
- default:
- BUG();
- }
- err = videobuf_dma_map(q->dev, &mem->dma);
- if (0 != err)
- return err;
-
- return 0;
-}
-
-static int __videobuf_sync(struct videobuf_queue *q,
- struct videobuf_buffer *buf)
-{
- struct videobuf_dma_sg_memory *mem = buf->priv;
- BUG_ON(!mem || !mem->dma.sglen);
-
- MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
- MAGIC_CHECK(mem->dma.magic, MAGIC_DMABUF);
-
- dma_sync_sg_for_cpu(q->dev, mem->dma.sglist,
- mem->dma.sglen, mem->dma.direction);
-
- return 0;
-}
-
-static int __videobuf_mmap_mapper(struct videobuf_queue *q,
- struct videobuf_buffer *buf,
- struct vm_area_struct *vma)
-{
- struct videobuf_dma_sg_memory *mem = buf->priv;
- struct videobuf_mapping *map;
- unsigned int first, last, size = 0, i;
- int retval;
-
- retval = -EINVAL;
-
- BUG_ON(!mem);
- MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
-
- /* look for first buffer to map */
- for (first = 0; first < VIDEO_MAX_FRAME; first++) {
- if (buf == q->bufs[first]) {
- size = PAGE_ALIGN(q->bufs[first]->bsize);
- break;
- }
- }
-
- /* paranoia, should never happen since buf is always valid. */
- if (!size) {
- dprintk(1, "mmap app bug: offset invalid [offset=0x%lx]\n",
- (vma->vm_pgoff << PAGE_SHIFT));
- goto done;
- }
-
- last = first;
-
- /* create mapping + update buffer list */
- retval = -ENOMEM;
- map = kmalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
- if (NULL == map)
- goto done;
-
- size = 0;
- for (i = first; i <= last; i++) {
- if (NULL == q->bufs[i])
- continue;
- q->bufs[i]->map = map;
- q->bufs[i]->baddr = vma->vm_start + size;
- size += PAGE_ALIGN(q->bufs[i]->bsize);
- }
-
- map->count = 1;
- map->q = q;
- vma->vm_ops = &videobuf_vm_ops;
- vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
- vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
- vma->vm_private_data = map;
- dprintk(1, "mmap %p: q=%p %08lx-%08lx pgoff %08lx bufs %d-%d\n",
- map, q, vma->vm_start, vma->vm_end, vma->vm_pgoff, first, last);
- retval = 0;
-
-done:
- return retval;
-}
-
-static struct videobuf_qtype_ops sg_ops = {
- .magic = MAGIC_QTYPE_OPS,
-
- .alloc_vb = __videobuf_alloc_vb,
- .iolock = __videobuf_iolock,
- .sync = __videobuf_sync,
- .mmap_mapper = __videobuf_mmap_mapper,
- .vaddr = __videobuf_to_vaddr,
-};
-
-void *videobuf_sg_alloc(size_t size)
-{
- struct videobuf_queue q;
-
- /* Required to make generic handler to call __videobuf_alloc */
- q.int_ops = &sg_ops;
-
- q.msize = size;
-
- return videobuf_alloc_vb(&q);
-}
-EXPORT_SYMBOL_GPL(videobuf_sg_alloc);
-
-void videobuf_queue_sg_init(struct videobuf_queue *q,
- const struct videobuf_queue_ops *ops,
- struct device *dev,
- spinlock_t *irqlock,
- enum v4l2_buf_type type,
- enum v4l2_field field,
- unsigned int msize,
- void *priv,
- struct mutex *ext_lock)
-{
- videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
- priv, &sg_ops, ext_lock);
-}
-EXPORT_SYMBOL_GPL(videobuf_queue_sg_init);
-
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c
deleted file mode 100644
index 94d83a41381..00000000000
--- a/drivers/media/video/videobuf-dvb.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- *
- * some helper function for simple DVB cards which simply DMA the
- * complete transport stream and let the computer sort everything else
- * (i.e. we are using the software demux, ...). Also uses the
- * video-buf to manage DMA buffers.
- *
- * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/fs.h>
-#include <linux/kthread.h>
-#include <linux/file.h>
-#include <linux/slab.h>
-
-#include <linux/freezer.h>
-
-#include <media/videobuf-core.h>
-#include <media/videobuf-dvb.h>
-
-/* ------------------------------------------------------------------ */
-
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
-MODULE_LICENSE("GPL");
-
-static unsigned int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug,"enable debug messages");
-
-#define dprintk(fmt, arg...) if (debug) \
- printk(KERN_DEBUG "%s/dvb: " fmt, dvb->name , ## arg)
-
-/* ------------------------------------------------------------------ */
-
-static int videobuf_dvb_thread(void *data)
-{
- struct videobuf_dvb *dvb = data;
- struct videobuf_buffer *buf;
- unsigned long flags;
- void *outp;
-
- dprintk("dvb thread started\n");
- set_freezable();
- videobuf_read_start(&dvb->dvbq);
-
- for (;;) {
- /* fetch next buffer */
- buf = list_entry(dvb->dvbq.stream.next,
- struct videobuf_buffer, stream);
- list_del(&buf->stream);
- videobuf_waiton(&dvb->dvbq, buf, 0, 1);
-
- /* no more feeds left or stop_feed() asked us to quit */
- if (0 == dvb->nfeeds)
- break;
- if (kthread_should_stop())
- break;
- try_to_freeze();
-
- /* feed buffer data to demux */
- outp = videobuf_queue_to_vaddr(&dvb->dvbq, buf);
-
- if (buf->state == VIDEOBUF_DONE)
- dvb_dmx_swfilter(&dvb->demux, outp,
- buf->size);
-
- /* requeue buffer */
- list_add_tail(&buf->stream,&dvb->dvbq.stream);
- spin_lock_irqsave(dvb->dvbq.irqlock,flags);
- dvb->dvbq.ops->buf_queue(&dvb->dvbq,buf);
- spin_unlock_irqrestore(dvb->dvbq.irqlock,flags);
- }
-
- videobuf_read_stop(&dvb->dvbq);
- dprintk("dvb thread stopped\n");
-
- /* Hmm, linux becomes *very* unhappy without this ... */
- while (!kthread_should_stop()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- }
- return 0;
-}
-
-static int videobuf_dvb_start_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct videobuf_dvb *dvb = demux->priv;
- int rc;
-
- if (!demux->dmx.frontend)
- return -EINVAL;
-
- mutex_lock(&dvb->lock);
- dvb->nfeeds++;
- rc = dvb->nfeeds;
-
- if (NULL != dvb->thread)
- goto out;
- dvb->thread = kthread_run(videobuf_dvb_thread,
- dvb, "%s dvb", dvb->name);
- if (IS_ERR(dvb->thread)) {
- rc = PTR_ERR(dvb->thread);
- dvb->thread = NULL;
- }
-
-out:
- mutex_unlock(&dvb->lock);
- return rc;
-}
-
-static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed)
-{
- struct dvb_demux *demux = feed->demux;
- struct videobuf_dvb *dvb = demux->priv;
- int err = 0;
-
- mutex_lock(&dvb->lock);
- dvb->nfeeds--;
- if (0 == dvb->nfeeds && NULL != dvb->thread) {
- err = kthread_stop(dvb->thread);
- dvb->thread = NULL;
- }
- mutex_unlock(&dvb->lock);
- return err;
-}
-
-static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
- struct module *module,
- void *adapter_priv,
- struct device *device,
- char *adapter_name,
- short *adapter_nr,
- int mfe_shared,
- int (*fe_ioctl_override)(struct dvb_frontend *,
- unsigned int, void *, unsigned int))
-{
- int result;
-
- mutex_init(&fe->lock);
-
- /* register adapter */
- result = dvb_register_adapter(&fe->adapter, adapter_name, module,
- device, adapter_nr);
- if (result < 0) {
- printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n",
- adapter_name, result);
- }
- fe->adapter.priv = adapter_priv;
- fe->adapter.mfe_shared = mfe_shared;
- fe->adapter.fe_ioctl_override = fe_ioctl_override;
-
- return result;
-}
-
-static int videobuf_dvb_register_frontend(struct dvb_adapter *adapter,
- struct videobuf_dvb *dvb)
-{
- int result;
-
- /* register frontend */
- result = dvb_register_frontend(adapter, dvb->frontend);
- if (result < 0) {
- printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
- dvb->name, result);
- goto fail_frontend;
- }
-
- /* register demux stuff */
- dvb->demux.dmx.capabilities =
- DMX_TS_FILTERING | DMX_SECTION_FILTERING |
- DMX_MEMORY_BASED_FILTERING;
- dvb->demux.priv = dvb;
- dvb->demux.filternum = 256;
- dvb->demux.feednum = 256;
- dvb->demux.start_feed = videobuf_dvb_start_feed;
- dvb->demux.stop_feed = videobuf_dvb_stop_feed;
- result = dvb_dmx_init(&dvb->demux);
- if (result < 0) {
- printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n",
- dvb->name, result);
- goto fail_dmx;
- }
-
- dvb->dmxdev.filternum = 256;
- dvb->dmxdev.demux = &dvb->demux.dmx;
- dvb->dmxdev.capabilities = 0;
- result = dvb_dmxdev_init(&dvb->dmxdev, adapter);
-
- if (result < 0) {
- printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
- dvb->name, result);
- goto fail_dmxdev;
- }
-
- dvb->fe_hw.source = DMX_FRONTEND_0;
- result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- if (result < 0) {
- printk(KERN_WARNING "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
- dvb->name, result);
- goto fail_fe_hw;
- }
-
- dvb->fe_mem.source = DMX_MEMORY_FE;
- result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
- if (result < 0) {
- printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
- dvb->name, result);
- goto fail_fe_mem;
- }
-
- result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- if (result < 0) {
- printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n",
- dvb->name, result);
- goto fail_fe_conn;
- }
-
- /* register network adapter */
- result = dvb_net_init(adapter, &dvb->net, &dvb->demux.dmx);
- if (result < 0) {
- printk(KERN_WARNING "%s: dvb_net_init failed (errno = %d)\n",
- dvb->name, result);
- goto fail_fe_conn;
- }
- return 0;
-
-fail_fe_conn:
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
-fail_fe_mem:
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
-fail_fe_hw:
- dvb_dmxdev_release(&dvb->dmxdev);
-fail_dmxdev:
- dvb_dmx_release(&dvb->demux);
-fail_dmx:
- dvb_unregister_frontend(dvb->frontend);
-fail_frontend:
- dvb_frontend_detach(dvb->frontend);
- dvb->frontend = NULL;
-
- return result;
-}
-
-/* ------------------------------------------------------------------ */
-/* Register a single adapter and one or more frontends */
-int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
- struct module *module,
- void *adapter_priv,
- struct device *device,
- short *adapter_nr,
- int mfe_shared,
- int (*fe_ioctl_override)(struct dvb_frontend *,
- unsigned int, void *, unsigned int))
-{
- struct list_head *list, *q;
- struct videobuf_dvb_frontend *fe;
- int res;
-
- fe = videobuf_dvb_get_frontend(f, 1);
- if (!fe) {
- printk(KERN_WARNING "Unable to register the adapter which has no frontends\n");
- return -EINVAL;
- }
-
- /* Bring up the adapter */
- res = videobuf_dvb_register_adapter(f, module, adapter_priv, device,
- fe->dvb.name, adapter_nr, mfe_shared, fe_ioctl_override);
- if (res < 0) {
- printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res);
- return res;
- }
-
- /* Attach all of the frontends to the adapter */
- mutex_lock(&f->lock);
- list_for_each_safe(list, q, &f->felist) {
- fe = list_entry(list, struct videobuf_dvb_frontend, felist);
- res = videobuf_dvb_register_frontend(&f->adapter, &fe->dvb);
- if (res < 0) {
- printk(KERN_WARNING "%s: videobuf_dvb_register_frontend failed (errno = %d)\n",
- fe->dvb.name, res);
- goto err;
- }
- }
- mutex_unlock(&f->lock);
- return 0;
-
-err:
- mutex_unlock(&f->lock);
- videobuf_dvb_unregister_bus(f);
- return res;
-}
-EXPORT_SYMBOL(videobuf_dvb_register_bus);
-
-void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f)
-{
- videobuf_dvb_dealloc_frontends(f);
-
- dvb_unregister_adapter(&f->adapter);
-}
-EXPORT_SYMBOL(videobuf_dvb_unregister_bus);
-
-struct videobuf_dvb_frontend *videobuf_dvb_get_frontend(
- struct videobuf_dvb_frontends *f, int id)
-{
- struct list_head *list, *q;
- struct videobuf_dvb_frontend *fe, *ret = NULL;
-
- mutex_lock(&f->lock);
-
- list_for_each_safe(list, q, &f->felist) {
- fe = list_entry(list, struct videobuf_dvb_frontend, felist);
- if (fe->id == id) {
- ret = fe;
- break;
- }
- }
-
- mutex_unlock(&f->lock);
-
- return ret;
-}
-EXPORT_SYMBOL(videobuf_dvb_get_frontend);
-
-int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f,
- struct dvb_frontend *p)
-{
- struct list_head *list, *q;
- struct videobuf_dvb_frontend *fe = NULL;
- int ret = 0;
-
- mutex_lock(&f->lock);
-
- list_for_each_safe(list, q, &f->felist) {
- fe = list_entry(list, struct videobuf_dvb_frontend, felist);
- if (fe->dvb.frontend == p) {
- ret = fe->id;
- break;
- }
- }
-
- mutex_unlock(&f->lock);
-
- return ret;
-}
-EXPORT_SYMBOL(videobuf_dvb_find_frontend);
-
-struct videobuf_dvb_frontend *videobuf_dvb_alloc_frontend(
- struct videobuf_dvb_frontends *f, int id)
-{
- struct videobuf_dvb_frontend *fe;
-
- fe = kzalloc(sizeof(struct videobuf_dvb_frontend), GFP_KERNEL);
- if (fe == NULL)
- goto fail_alloc;
-
- fe->id = id;
- mutex_init(&fe->dvb.lock);
-
- mutex_lock(&f->lock);
- list_add_tail(&fe->felist, &f->felist);
- mutex_unlock(&f->lock);
-
-fail_alloc:
- return fe;
-}
-EXPORT_SYMBOL(videobuf_dvb_alloc_frontend);
-
-void videobuf_dvb_dealloc_frontends(struct videobuf_dvb_frontends *f)
-{
- struct list_head *list, *q;
- struct videobuf_dvb_frontend *fe;
-
- mutex_lock(&f->lock);
- list_for_each_safe(list, q, &f->felist) {
- fe = list_entry(list, struct videobuf_dvb_frontend, felist);
- if (fe->dvb.net.dvbdev) {
- dvb_net_release(&fe->dvb.net);
- fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx,
- &fe->dvb.fe_mem);
- fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx,
- &fe->dvb.fe_hw);
- dvb_dmxdev_release(&fe->dvb.dmxdev);
- dvb_dmx_release(&fe->dvb.demux);
- dvb_unregister_frontend(fe->dvb.frontend);
- }
- if (fe->dvb.frontend)
- /* always allocated, may have been reset */
- dvb_frontend_detach(fe->dvb.frontend);
- list_del(list); /* remove list entry */
- kfree(fe); /* free frontend allocation */
- }
- mutex_unlock(&f->lock);
-}
-EXPORT_SYMBOL(videobuf_dvb_dealloc_frontends);
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
deleted file mode 100644
index df142580e44..00000000000
--- a/drivers/media/video/videobuf-vmalloc.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * helper functions for vmalloc video4linux capture buffers
- *
- * The functions expect the hardware being able to scatter gather
- * (i.e. the buffers are not linear in physical memory, but fragmented
- * into PAGE_SIZE chunks). They also assume the driver does not need
- * to touch the video data.
- *
- * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-
-#include <linux/pci.h>
-#include <linux/vmalloc.h>
-#include <linux/pagemap.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-#include <media/videobuf-vmalloc.h>
-
-#define MAGIC_DMABUF 0x17760309
-#define MAGIC_VMAL_MEM 0x18221223
-
-#define MAGIC_CHECK(is, should) \
- if (unlikely((is) != (should))) { \
- printk(KERN_ERR "magic mismatch: %x (expected %x)\n", \
- is, should); \
- BUG(); \
- }
-
-static int debug;
-module_param(debug, int, 0644);
-
-MODULE_DESCRIPTION("helper module to manage video4linux vmalloc buffers");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_LICENSE("GPL");
-
-#define dprintk(level, fmt, arg...) \
- if (debug >= level) \
- printk(KERN_DEBUG "vbuf-vmalloc: " fmt , ## arg)
-
-
-/***************************************************************************/
-
-static void videobuf_vm_open(struct vm_area_struct *vma)
-{
- struct videobuf_mapping *map = vma->vm_private_data;
-
- dprintk(2, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", map,
- map->count, vma->vm_start, vma->vm_end);
-
- map->count++;
-}
-
-static void videobuf_vm_close(struct vm_area_struct *vma)
-{
- struct videobuf_mapping *map = vma->vm_private_data;
- struct videobuf_queue *q = map->q;
- int i;
-
- dprintk(2, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", map,
- map->count, vma->vm_start, vma->vm_end);
-
- map->count--;
- if (0 == map->count) {
- struct videobuf_vmalloc_memory *mem;
-
- dprintk(1, "munmap %p q=%p\n", map, q);
- videobuf_queue_lock(q);
-
- /* We need first to cancel streams, before unmapping */
- if (q->streaming)
- videobuf_queue_cancel(q);
-
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- if (NULL == q->bufs[i])
- continue;
-
- if (q->bufs[i]->map != map)
- continue;
-
- mem = q->bufs[i]->priv;
- if (mem) {
- /* This callback is called only if kernel has
- allocated memory and this memory is mmapped.
- In this case, memory should be freed,
- in order to do memory unmap.
- */
-
- MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
-
- /* vfree is not atomic - can't be
- called with IRQ's disabled
- */
- dprintk(1, "%s: buf[%d] freeing (%p)\n",
- __func__, i, mem->vaddr);
-
- vfree(mem->vaddr);
- mem->vaddr = NULL;
- }
-
- q->bufs[i]->map = NULL;
- q->bufs[i]->baddr = 0;
- }
-
- kfree(map);
-
- videobuf_queue_unlock(q);
- }
-
- return;
-}
-
-static const struct vm_operations_struct videobuf_vm_ops = {
- .open = videobuf_vm_open,
- .close = videobuf_vm_close,
-};
-
-/* ---------------------------------------------------------------------
- * vmalloc handlers for the generic methods
- */
-
-/* Allocated area consists on 3 parts:
- struct video_buffer
- struct <driver>_buffer (cx88_buffer, saa7134_buf, ...)
- struct videobuf_dma_sg_memory
- */
-
-static struct videobuf_buffer *__videobuf_alloc_vb(size_t size)
-{
- struct videobuf_vmalloc_memory *mem;
- struct videobuf_buffer *vb;
-
- vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
- if (!vb)
- return vb;
-
- mem = vb->priv = ((char *)vb) + size;
- mem->magic = MAGIC_VMAL_MEM;
-
- dprintk(1, "%s: allocated at %p(%ld+%ld) & %p(%ld)\n",
- __func__, vb, (long)sizeof(*vb), (long)size - sizeof(*vb),
- mem, (long)sizeof(*mem));
-
- return vb;
-}
-
-static int __videobuf_iolock(struct videobuf_queue *q,
- struct videobuf_buffer *vb,
- struct v4l2_framebuffer *fbuf)
-{
- struct videobuf_vmalloc_memory *mem = vb->priv;
- int pages;
-
- BUG_ON(!mem);
-
- MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
-
- switch (vb->memory) {
- case V4L2_MEMORY_MMAP:
- dprintk(1, "%s memory method MMAP\n", __func__);
-
- /* All handling should be done by __videobuf_mmap_mapper() */
- if (!mem->vaddr) {
- printk(KERN_ERR "memory is not alloced/mmapped.\n");
- return -EINVAL;
- }
- break;
- case V4L2_MEMORY_USERPTR:
- pages = PAGE_ALIGN(vb->size);
-
- dprintk(1, "%s memory method USERPTR\n", __func__);
-
- if (vb->baddr) {
- printk(KERN_ERR "USERPTR is currently not supported\n");
- return -EINVAL;
- }
-
- /* The only USERPTR currently supported is the one needed for
- * read() method.
- */
-
- mem->vaddr = vmalloc_user(pages);
- if (!mem->vaddr) {
- printk(KERN_ERR "vmalloc (%d pages) failed\n", pages);
- return -ENOMEM;
- }
- dprintk(1, "vmalloc is at addr %p (%d pages)\n",
- mem->vaddr, pages);
-
-#if 0
- int rc;
- /* Kernel userptr is used also by read() method. In this case,
- there's no need to remap, since data will be copied to user
- */
- if (!vb->baddr)
- return 0;
-
- /* FIXME: to properly support USERPTR, remap should occur.
- The code below won't work, since mem->vma = NULL
- */
- /* Try to remap memory */
- rc = remap_vmalloc_range(mem->vma, (void *)vb->baddr, 0);
- if (rc < 0) {
- printk(KERN_ERR "mmap: remap failed with error %d", rc);
- return -ENOMEM;
- }
-#endif
-
- break;
- case V4L2_MEMORY_OVERLAY:
- default:
- dprintk(1, "%s memory method OVERLAY/unknown\n", __func__);
-
- /* Currently, doesn't support V4L2_MEMORY_OVERLAY */
- printk(KERN_ERR "Memory method currently unsupported.\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int __videobuf_mmap_mapper(struct videobuf_queue *q,
- struct videobuf_buffer *buf,
- struct vm_area_struct *vma)
-{
- struct videobuf_vmalloc_memory *mem;
- struct videobuf_mapping *map;
- int retval, pages;
-
- dprintk(1, "%s\n", __func__);
-
- /* create mapping + update buffer list */
- map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
- if (NULL == map)
- return -ENOMEM;
-
- buf->map = map;
- map->q = q;
-
- buf->baddr = vma->vm_start;
-
- mem = buf->priv;
- BUG_ON(!mem);
- MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
-
- pages = PAGE_ALIGN(vma->vm_end - vma->vm_start);
- mem->vaddr = vmalloc_user(pages);
- if (!mem->vaddr) {
- printk(KERN_ERR "vmalloc (%d pages) failed\n", pages);
- goto error;
- }
- dprintk(1, "vmalloc is at addr %p (%d pages)\n", mem->vaddr, pages);
-
- /* Try to remap memory */
- retval = remap_vmalloc_range(vma, mem->vaddr, 0);
- if (retval < 0) {
- printk(KERN_ERR "mmap: remap failed with error %d. ", retval);
- vfree(mem->vaddr);
- goto error;
- }
-
- vma->vm_ops = &videobuf_vm_ops;
- vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
- vma->vm_private_data = map;
-
- dprintk(1, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
- map, q, vma->vm_start, vma->vm_end,
- (long int)buf->bsize,
- vma->vm_pgoff, buf->i);
-
- videobuf_vm_open(vma);
-
- return 0;
-
-error:
- mem = NULL;
- kfree(map);
- return -ENOMEM;
-}
-
-static struct videobuf_qtype_ops qops = {
- .magic = MAGIC_QTYPE_OPS,
-
- .alloc_vb = __videobuf_alloc_vb,
- .iolock = __videobuf_iolock,
- .mmap_mapper = __videobuf_mmap_mapper,
- .vaddr = videobuf_to_vmalloc,
-};
-
-void videobuf_queue_vmalloc_init(struct videobuf_queue *q,
- const struct videobuf_queue_ops *ops,
- struct device *dev,
- spinlock_t *irqlock,
- enum v4l2_buf_type type,
- enum v4l2_field field,
- unsigned int msize,
- void *priv,
- struct mutex *ext_lock)
-{
- videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
- priv, &qops, ext_lock);
-}
-EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init);
-
-void *videobuf_to_vmalloc(struct videobuf_buffer *buf)
-{
- struct videobuf_vmalloc_memory *mem = buf->priv;
- BUG_ON(!mem);
- MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
-
- return mem->vaddr;
-}
-EXPORT_SYMBOL_GPL(videobuf_to_vmalloc);
-
-void videobuf_vmalloc_free(struct videobuf_buffer *buf)
-{
- struct videobuf_vmalloc_memory *mem = buf->priv;
-
- /* mmapped memory can't be freed here, otherwise mmapped region
- would be released, while still needed. In this case, the memory
- release should happen inside videobuf_vm_close().
- So, it should free memory only if the memory were allocated for
- read() operation.
- */
- if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
- return;
-
- if (!mem)
- return;
-
- MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
-
- vfree(mem->vaddr);
- mem->vaddr = NULL;
-
- return;
-}
-EXPORT_SYMBOL_GPL(videobuf_vmalloc_free);
-
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
deleted file mode 100644
index 268c7dd4f82..00000000000
--- a/drivers/media/video/videobuf2-core.c
+++ /dev/null
@@ -1,2387 +0,0 @@
-/*
- * videobuf2-core.c - V4L2 driver helper framework
- *
- * Copyright (C) 2010 Samsung Electronics
- *
- * Author: Pawel Osciak <pawel@osciak.com>
- * Marek Szyprowski <m.szyprowski@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- */
-
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-
-#include <media/v4l2-dev.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-#include <media/videobuf2-core.h>
-
-static int debug;
-module_param(debug, int, 0644);
-
-#define dprintk(level, fmt, arg...) \
- do { \
- if (debug >= level) \
- printk(KERN_DEBUG "vb2: " fmt, ## arg); \
- } while (0)
-
-#define call_memop(q, op, args...) \
- (((q)->mem_ops->op) ? \
- ((q)->mem_ops->op(args)) : 0)
-
-#define call_qop(q, op, args...) \
- (((q)->ops->op) ? ((q)->ops->op(args)) : 0)
-
-#define V4L2_BUFFER_STATE_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \
- V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR | \
- V4L2_BUF_FLAG_PREPARED)
-
-/**
- * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
- */
-static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
-{
- struct vb2_queue *q = vb->vb2_queue;
- void *mem_priv;
- int plane;
-
- /* Allocate memory for all planes in this buffer */
- for (plane = 0; plane < vb->num_planes; ++plane) {
- mem_priv = call_memop(q, alloc, q->alloc_ctx[plane],
- q->plane_sizes[plane]);
- if (IS_ERR_OR_NULL(mem_priv))
- goto free;
-
- /* Associate allocator private data with this plane */
- vb->planes[plane].mem_priv = mem_priv;
- vb->v4l2_planes[plane].length = q->plane_sizes[plane];
- }
-
- return 0;
-free:
- /* Free already allocated memory if one of the allocations failed */
- for (; plane > 0; --plane) {
- call_memop(q, put, vb->planes[plane - 1].mem_priv);
- vb->planes[plane - 1].mem_priv = NULL;
- }
-
- return -ENOMEM;
-}
-
-/**
- * __vb2_buf_mem_free() - free memory of the given buffer
- */
-static void __vb2_buf_mem_free(struct vb2_buffer *vb)
-{
- struct vb2_queue *q = vb->vb2_queue;
- unsigned int plane;
-
- for (plane = 0; plane < vb->num_planes; ++plane) {
- call_memop(q, put, vb->planes[plane].mem_priv);
- vb->planes[plane].mem_priv = NULL;
- dprintk(3, "Freed plane %d of buffer %d\n", plane,
- vb->v4l2_buf.index);
- }
-}
-
-/**
- * __vb2_buf_userptr_put() - release userspace memory associated with
- * a USERPTR buffer
- */
-static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
-{
- struct vb2_queue *q = vb->vb2_queue;
- unsigned int plane;
-
- for (plane = 0; plane < vb->num_planes; ++plane) {
- if (vb->planes[plane].mem_priv)
- call_memop(q, put_userptr, vb->planes[plane].mem_priv);
- vb->planes[plane].mem_priv = NULL;
- }
-}
-
-/**
- * __setup_offsets() - setup unique offsets ("cookies") for every plane in
- * every buffer on the queue
- */
-static void __setup_offsets(struct vb2_queue *q, unsigned int n)
-{
- unsigned int buffer, plane;
- struct vb2_buffer *vb;
- unsigned long off;
-
- if (q->num_buffers) {
- struct v4l2_plane *p;
- vb = q->bufs[q->num_buffers - 1];
- p = &vb->v4l2_planes[vb->num_planes - 1];
- off = PAGE_ALIGN(p->m.mem_offset + p->length);
- } else {
- off = 0;
- }
-
- for (buffer = q->num_buffers; buffer < q->num_buffers + n; ++buffer) {
- vb = q->bufs[buffer];
- if (!vb)
- continue;
-
- for (plane = 0; plane < vb->num_planes; ++plane) {
- vb->v4l2_planes[plane].length = q->plane_sizes[plane];
- vb->v4l2_planes[plane].m.mem_offset = off;
-
- dprintk(3, "Buffer %d, plane %d offset 0x%08lx\n",
- buffer, plane, off);
-
- off += vb->v4l2_planes[plane].length;
- off = PAGE_ALIGN(off);
- }
- }
-}
-
-/**
- * __vb2_queue_alloc() - allocate videobuf buffer structures and (for MMAP type)
- * video buffer memory for all buffers/planes on the queue and initializes the
- * queue
- *
- * Returns the number of buffers successfully allocated.
- */
-static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
- unsigned int num_buffers, unsigned int num_planes)
-{
- unsigned int buffer;
- struct vb2_buffer *vb;
- int ret;
-
- for (buffer = 0; buffer < num_buffers; ++buffer) {
- /* Allocate videobuf buffer structures */
- vb = kzalloc(q->buf_struct_size, GFP_KERNEL);
- if (!vb) {
- dprintk(1, "Memory alloc for buffer struct failed\n");
- break;
- }
-
- /* Length stores number of planes for multiplanar buffers */
- if (V4L2_TYPE_IS_MULTIPLANAR(q->type))
- vb->v4l2_buf.length = num_planes;
-
- vb->state = VB2_BUF_STATE_DEQUEUED;
- vb->vb2_queue = q;
- vb->num_planes = num_planes;
- vb->v4l2_buf.index = q->num_buffers + buffer;
- vb->v4l2_buf.type = q->type;
- vb->v4l2_buf.memory = memory;
-
- /* Allocate video buffer memory for the MMAP type */
- if (memory == V4L2_MEMORY_MMAP) {
- ret = __vb2_buf_mem_alloc(vb);
- if (ret) {
- dprintk(1, "Failed allocating memory for "
- "buffer %d\n", buffer);
- kfree(vb);
- break;
- }
- /*
- * Call the driver-provided buffer initialization
- * callback, if given. An error in initialization
- * results in queue setup failure.
- */
- ret = call_qop(q, buf_init, vb);
- if (ret) {
- dprintk(1, "Buffer %d %p initialization"
- " failed\n", buffer, vb);
- __vb2_buf_mem_free(vb);
- kfree(vb);
- break;
- }
- }
-
- q->bufs[q->num_buffers + buffer] = vb;
- }
-
- __setup_offsets(q, buffer);
-
- dprintk(1, "Allocated %d buffers, %d plane(s) each\n",
- buffer, num_planes);
-
- return buffer;
-}
-
-/**
- * __vb2_free_mem() - release all video buffer memory for a given queue
- */
-static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers)
-{
- unsigned int buffer;
- struct vb2_buffer *vb;
-
- for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
- ++buffer) {
- vb = q->bufs[buffer];
- if (!vb)
- continue;
-
- /* Free MMAP buffers or release USERPTR buffers */
- if (q->memory == V4L2_MEMORY_MMAP)
- __vb2_buf_mem_free(vb);
- else
- __vb2_buf_userptr_put(vb);
- }
-}
-
-/**
- * __vb2_queue_free() - free buffers at the end of the queue - video memory and
- * related information, if no buffers are left return the queue to an
- * uninitialized state. Might be called even if the queue has already been freed.
- */
-static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
-{
- unsigned int buffer;
-
- /* Call driver-provided cleanup function for each buffer, if provided */
- if (q->ops->buf_cleanup) {
- for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
- ++buffer) {
- if (NULL == q->bufs[buffer])
- continue;
- q->ops->buf_cleanup(q->bufs[buffer]);
- }
- }
-
- /* Release video buffer memory */
- __vb2_free_mem(q, buffers);
-
- /* Free videobuf buffers */
- for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
- ++buffer) {
- kfree(q->bufs[buffer]);
- q->bufs[buffer] = NULL;
- }
-
- q->num_buffers -= buffers;
- if (!q->num_buffers)
- q->memory = 0;
- INIT_LIST_HEAD(&q->queued_list);
-}
-
-/**
- * __verify_planes_array() - verify that the planes array passed in struct
- * v4l2_buffer from userspace can be safely used
- */
-static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer *b)
-{
- /* Is memory for copying plane information present? */
- if (NULL == b->m.planes) {
- dprintk(1, "Multi-planar buffer passed but "
- "planes array not provided\n");
- return -EINVAL;
- }
-
- if (b->length < vb->num_planes || b->length > VIDEO_MAX_PLANES) {
- dprintk(1, "Incorrect planes array length, "
- "expected %d, got %d\n", vb->num_planes, b->length);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/**
- * __buffer_in_use() - return true if the buffer is in use and
- * the queue cannot be freed (by the means of REQBUFS(0)) call
- */
-static bool __buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb)
-{
- unsigned int plane;
- for (plane = 0; plane < vb->num_planes; ++plane) {
- void *mem_priv = vb->planes[plane].mem_priv;
- /*
- * If num_users() has not been provided, call_memop
- * will return 0, apparently nobody cares about this
- * case anyway. If num_users() returns more than 1,
- * we are not the only user of the plane's memory.
- */
- if (mem_priv && call_memop(q, num_users, mem_priv) > 1)
- return true;
- }
- return false;
-}
-
-/**
- * __buffers_in_use() - return true if any buffers on the queue are in use and
- * the queue cannot be freed (by the means of REQBUFS(0)) call
- */
-static bool __buffers_in_use(struct vb2_queue *q)
-{
- unsigned int buffer;
- for (buffer = 0; buffer < q->num_buffers; ++buffer) {
- if (__buffer_in_use(q, q->bufs[buffer]))
- return true;
- }
- return false;
-}
-
-/**
- * __fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be
- * returned to userspace
- */
-static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
-{
- struct vb2_queue *q = vb->vb2_queue;
- int ret;
-
- /* Copy back data such as timestamp, flags, etc. */
- memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m));
- b->reserved2 = vb->v4l2_buf.reserved2;
- b->reserved = vb->v4l2_buf.reserved;
-
- if (V4L2_TYPE_IS_MULTIPLANAR(q->type)) {
- ret = __verify_planes_array(vb, b);
- if (ret)
- return ret;
-
- /*
- * Fill in plane-related data if userspace provided an array
- * for it. The memory and size is verified above.
- */
- memcpy(b->m.planes, vb->v4l2_planes,
- b->length * sizeof(struct v4l2_plane));
- } else {
- /*
- * We use length and offset in v4l2_planes array even for
- * single-planar buffers, but userspace does not.
- */
- b->length = vb->v4l2_planes[0].length;
- b->bytesused = vb->v4l2_planes[0].bytesused;
- if (q->memory == V4L2_MEMORY_MMAP)
- b->m.offset = vb->v4l2_planes[0].m.mem_offset;
- else if (q->memory == V4L2_MEMORY_USERPTR)
- b->m.userptr = vb->v4l2_planes[0].m.userptr;
- }
-
- /*
- * Clear any buffer state related flags.
- */
- b->flags &= ~V4L2_BUFFER_STATE_FLAGS;
-
- switch (vb->state) {
- case VB2_BUF_STATE_QUEUED:
- case VB2_BUF_STATE_ACTIVE:
- b->flags |= V4L2_BUF_FLAG_QUEUED;
- break;
- case VB2_BUF_STATE_ERROR:
- b->flags |= V4L2_BUF_FLAG_ERROR;
- /* fall through */
- case VB2_BUF_STATE_DONE:
- b->flags |= V4L2_BUF_FLAG_DONE;
- break;
- case VB2_BUF_STATE_PREPARED:
- b->flags |= V4L2_BUF_FLAG_PREPARED;
- break;
- case VB2_BUF_STATE_DEQUEUED:
- /* nothing */
- break;
- }
-
- if (__buffer_in_use(q, vb))
- b->flags |= V4L2_BUF_FLAG_MAPPED;
-
- return 0;
-}
-
-/**
- * vb2_querybuf() - query video buffer information
- * @q: videobuf queue
- * @b: buffer struct passed from userspace to vidioc_querybuf handler
- * in driver
- *
- * Should be called from vidioc_querybuf ioctl handler in driver.
- * This function will verify the passed v4l2_buffer structure and fill the
- * relevant information for the userspace.
- *
- * The return values from this function are intended to be directly returned
- * from vidioc_querybuf handler in driver.
- */
-int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
-{
- struct vb2_buffer *vb;
-
- if (b->type != q->type) {
- dprintk(1, "querybuf: wrong buffer type\n");
- return -EINVAL;
- }
-
- if (b->index >= q->num_buffers) {
- dprintk(1, "querybuf: buffer index out of range\n");
- return -EINVAL;
- }
- vb = q->bufs[b->index];
-
- return __fill_v4l2_buffer(vb, b);
-}
-EXPORT_SYMBOL(vb2_querybuf);
-
-/**
- * __verify_userptr_ops() - verify that all memory operations required for
- * USERPTR queue type have been provided
- */
-static int __verify_userptr_ops(struct vb2_queue *q)
-{
- if (!(q->io_modes & VB2_USERPTR) || !q->mem_ops->get_userptr ||
- !q->mem_ops->put_userptr)
- return -EINVAL;
-
- return 0;
-}
-
-/**
- * __verify_mmap_ops() - verify that all memory operations required for
- * MMAP queue type have been provided
- */
-static int __verify_mmap_ops(struct vb2_queue *q)
-{
- if (!(q->io_modes & VB2_MMAP) || !q->mem_ops->alloc ||
- !q->mem_ops->put || !q->mem_ops->mmap)
- return -EINVAL;
-
- return 0;
-}
-
-/**
- * __verify_memory_type() - Check whether the memory type and buffer type
- * passed to a buffer operation are compatible with the queue.
- */
-static int __verify_memory_type(struct vb2_queue *q,
- enum v4l2_memory memory, enum v4l2_buf_type type)
-{
- if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR) {
- dprintk(1, "reqbufs: unsupported memory type\n");
- return -EINVAL;
- }
-
- if (type != q->type) {
- dprintk(1, "reqbufs: requested type is incorrect\n");
- return -EINVAL;
- }
-
- /*
- * Make sure all the required memory ops for given memory type
- * are available.
- */
- if (memory == V4L2_MEMORY_MMAP && __verify_mmap_ops(q)) {
- dprintk(1, "reqbufs: MMAP for current setup unsupported\n");
- return -EINVAL;
- }
-
- if (memory == V4L2_MEMORY_USERPTR && __verify_userptr_ops(q)) {
- dprintk(1, "reqbufs: USERPTR for current setup unsupported\n");
- return -EINVAL;
- }
-
- /*
- * Place the busy tests at the end: -EBUSY can be ignored when
- * create_bufs is called with count == 0, but count == 0 should still
- * do the memory and type validation.
- */
- if (q->fileio) {
- dprintk(1, "reqbufs: file io in progress\n");
- return -EBUSY;
- }
- return 0;
-}
-
-/**
- * __reqbufs() - Initiate streaming
- * @q: videobuf2 queue
- * @req: struct passed from userspace to vidioc_reqbufs handler in driver
- *
- * Should be called from vidioc_reqbufs ioctl handler of a driver.
- * This function:
- * 1) verifies streaming parameters passed from the userspace,
- * 2) sets up the queue,
- * 3) negotiates number of buffers and planes per buffer with the driver
- * to be used during streaming,
- * 4) allocates internal buffer structures (struct vb2_buffer), according to
- * the agreed parameters,
- * 5) for MMAP memory type, allocates actual video memory, using the
- * memory handling/allocation routines provided during queue initialization
- *
- * If req->count is 0, all the memory will be freed instead.
- * If the queue has been allocated previously (by a previous vb2_reqbufs) call
- * and the queue is not busy, memory will be reallocated.
- *
- * The return values from this function are intended to be directly returned
- * from vidioc_reqbufs handler in driver.
- */
-static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
-{
- unsigned int num_buffers, allocated_buffers, num_planes = 0;
- int ret;
-
- if (q->streaming) {
- dprintk(1, "reqbufs: streaming active\n");
- return -EBUSY;
- }
-
- if (req->count == 0 || q->num_buffers != 0 || q->memory != req->memory) {
- /*
- * We already have buffers allocated, so first check if they
- * are not in use and can be freed.
- */
- if (q->memory == V4L2_MEMORY_MMAP && __buffers_in_use(q)) {
- dprintk(1, "reqbufs: memory in use, cannot free\n");
- return -EBUSY;
- }
-
- __vb2_queue_free(q, q->num_buffers);
-
- /*
- * In case of REQBUFS(0) return immediately without calling
- * driver's queue_setup() callback and allocating resources.
- */
- if (req->count == 0)
- return 0;
- }
-
- /*
- * Make sure the requested values and current defaults are sane.
- */
- num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME);
- memset(q->plane_sizes, 0, sizeof(q->plane_sizes));
- memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
- q->memory = req->memory;
-
- /*
- * Ask the driver how many buffers and planes per buffer it requires.
- * Driver also sets the size and allocator context for each plane.
- */
- ret = call_qop(q, queue_setup, q, NULL, &num_buffers, &num_planes,
- q->plane_sizes, q->alloc_ctx);
- if (ret)
- return ret;
-
- /* Finally, allocate buffers and video memory */
- ret = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes);
- if (ret == 0) {
- dprintk(1, "Memory allocation failed\n");
- return -ENOMEM;
- }
-
- allocated_buffers = ret;
-
- /*
- * Check if driver can handle the allocated number of buffers.
- */
- if (allocated_buffers < num_buffers) {
- num_buffers = allocated_buffers;
-
- ret = call_qop(q, queue_setup, q, NULL, &num_buffers,
- &num_planes, q->plane_sizes, q->alloc_ctx);
-
- if (!ret && allocated_buffers < num_buffers)
- ret = -ENOMEM;
-
- /*
- * Either the driver has accepted a smaller number of buffers,
- * or .queue_setup() returned an error
- */
- }
-
- q->num_buffers = allocated_buffers;
-
- if (ret < 0) {
- __vb2_queue_free(q, allocated_buffers);
- return ret;
- }
-
- /*
- * Return the number of successfully allocated buffers
- * to the userspace.
- */
- req->count = allocated_buffers;
-
- return 0;
-}
-
-/**
- * vb2_reqbufs() - Wrapper for __reqbufs() that also verifies the memory and
- * type values.
- * @q: videobuf2 queue
- * @req: struct passed from userspace to vidioc_reqbufs handler in driver
- */
-int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
-{
- int ret = __verify_memory_type(q, req->memory, req->type);
-
- return ret ? ret : __reqbufs(q, req);
-}
-EXPORT_SYMBOL_GPL(vb2_reqbufs);
-
-/**
- * __create_bufs() - Allocate buffers and any required auxiliary structs
- * @q: videobuf2 queue
- * @create: creation parameters, passed from userspace to vidioc_create_bufs
- * handler in driver
- *
- * Should be called from vidioc_create_bufs ioctl handler of a driver.
- * This function:
- * 1) verifies parameter sanity
- * 2) calls the .queue_setup() queue operation
- * 3) performs any necessary memory allocations
- *
- * The return values from this function are intended to be directly returned
- * from vidioc_create_bufs handler in driver.
- */
-static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
-{
- unsigned int num_planes = 0, num_buffers, allocated_buffers;
- int ret;
-
- if (q->num_buffers == VIDEO_MAX_FRAME) {
- dprintk(1, "%s(): maximum number of buffers already allocated\n",
- __func__);
- return -ENOBUFS;
- }
-
- if (!q->num_buffers) {
- memset(q->plane_sizes, 0, sizeof(q->plane_sizes));
- memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
- q->memory = create->memory;
- }
-
- num_buffers = min(create->count, VIDEO_MAX_FRAME - q->num_buffers);
-
- /*
- * Ask the driver, whether the requested number of buffers, planes per
- * buffer and their sizes are acceptable
- */
- ret = call_qop(q, queue_setup, q, &create->format, &num_buffers,
- &num_planes, q->plane_sizes, q->alloc_ctx);
- if (ret)
- return ret;
-
- /* Finally, allocate buffers and video memory */
- ret = __vb2_queue_alloc(q, create->memory, num_buffers,
- num_planes);
- if (ret == 0) {
- dprintk(1, "Memory allocation failed\n");
- return -ENOMEM;
- }
-
- allocated_buffers = ret;
-
- /*
- * Check if driver can handle the so far allocated number of buffers.
- */
- if (ret < num_buffers) {
- num_buffers = ret;
-
- /*
- * q->num_buffers contains the total number of buffers, that the
- * queue driver has set up
- */
- ret = call_qop(q, queue_setup, q, &create->format, &num_buffers,
- &num_planes, q->plane_sizes, q->alloc_ctx);
-
- if (!ret && allocated_buffers < num_buffers)
- ret = -ENOMEM;
-
- /*
- * Either the driver has accepted a smaller number of buffers,
- * or .queue_setup() returned an error
- */
- }
-
- q->num_buffers += allocated_buffers;
-
- if (ret < 0) {
- __vb2_queue_free(q, allocated_buffers);
- return -ENOMEM;
- }
-
- /*
- * Return the number of successfully allocated buffers
- * to the userspace.
- */
- create->count = allocated_buffers;
-
- return 0;
-}
-
-/**
- * vb2_create_bufs() - Wrapper for __create_bufs() that also verifies the
- * memory and type values.
- * @q: videobuf2 queue
- * @create: creation parameters, passed from userspace to vidioc_create_bufs
- * handler in driver
- */
-int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
-{
- int ret = __verify_memory_type(q, create->memory, create->format.type);
-
- create->index = q->num_buffers;
- if (create->count == 0)
- return ret != -EBUSY ? ret : 0;
- return ret ? ret : __create_bufs(q, create);
-}
-EXPORT_SYMBOL_GPL(vb2_create_bufs);
-
-/**
- * vb2_plane_vaddr() - Return a kernel virtual address of a given plane
- * @vb: vb2_buffer to which the plane in question belongs to
- * @plane_no: plane number for which the address is to be returned
- *
- * This function returns a kernel virtual address of a given plane if
- * such a mapping exist, NULL otherwise.
- */
-void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no)
-{
- struct vb2_queue *q = vb->vb2_queue;
-
- if (plane_no > vb->num_planes || !vb->planes[plane_no].mem_priv)
- return NULL;
-
- return call_memop(q, vaddr, vb->planes[plane_no].mem_priv);
-
-}
-EXPORT_SYMBOL_GPL(vb2_plane_vaddr);
-
-/**
- * vb2_plane_cookie() - Return allocator specific cookie for the given plane
- * @vb: vb2_buffer to which the plane in question belongs to
- * @plane_no: plane number for which the cookie is to be returned
- *
- * This function returns an allocator specific cookie for a given plane if
- * available, NULL otherwise. The allocator should provide some simple static
- * inline function, which would convert this cookie to the allocator specific
- * type that can be used directly by the driver to access the buffer. This can
- * be for example physical address, pointer to scatter list or IOMMU mapping.
- */
-void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no)
-{
- struct vb2_queue *q = vb->vb2_queue;
-
- if (plane_no > vb->num_planes || !vb->planes[plane_no].mem_priv)
- return NULL;
-
- return call_memop(q, cookie, vb->planes[plane_no].mem_priv);
-}
-EXPORT_SYMBOL_GPL(vb2_plane_cookie);
-
-/**
- * vb2_buffer_done() - inform videobuf that an operation on a buffer is finished
- * @vb: vb2_buffer returned from the driver
- * @state: either VB2_BUF_STATE_DONE if the operation finished successfully
- * or VB2_BUF_STATE_ERROR if the operation finished with an error
- *
- * This function should be called by the driver after a hardware operation on
- * a buffer is finished and the buffer may be returned to userspace. The driver
- * cannot use this buffer anymore until it is queued back to it by videobuf
- * by the means of buf_queue callback. Only buffers previously queued to the
- * driver by buf_queue can be passed to this function.
- */
-void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
-{
- struct vb2_queue *q = vb->vb2_queue;
- unsigned long flags;
-
- if (vb->state != VB2_BUF_STATE_ACTIVE)
- return;
-
- if (state != VB2_BUF_STATE_DONE && state != VB2_BUF_STATE_ERROR)
- return;
-
- dprintk(4, "Done processing on buffer %d, state: %d\n",
- vb->v4l2_buf.index, vb->state);
-
- /* Add the buffer to the done buffers list */
- spin_lock_irqsave(&q->done_lock, flags);
- vb->state = state;
- list_add_tail(&vb->done_entry, &q->done_list);
- atomic_dec(&q->queued_count);
- spin_unlock_irqrestore(&q->done_lock, flags);
-
- /* Inform any processes that may be waiting for buffers */
- wake_up(&q->done_wq);
-}
-EXPORT_SYMBOL_GPL(vb2_buffer_done);
-
-/**
- * __fill_vb2_buffer() - fill a vb2_buffer with information provided in
- * a v4l2_buffer by the userspace
- */
-static int __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b,
- struct v4l2_plane *v4l2_planes)
-{
- unsigned int plane;
- int ret;
-
- if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
- /*
- * Verify that the userspace gave us a valid array for
- * plane information.
- */
- ret = __verify_planes_array(vb, b);
- if (ret)
- return ret;
-
- /* Fill in driver-provided information for OUTPUT types */
- if (V4L2_TYPE_IS_OUTPUT(b->type)) {
- /*
- * Will have to go up to b->length when API starts
- * accepting variable number of planes.
- */
- for (plane = 0; plane < vb->num_planes; ++plane) {
- v4l2_planes[plane].bytesused =
- b->m.planes[plane].bytesused;
- v4l2_planes[plane].data_offset =
- b->m.planes[plane].data_offset;
- }
- }
-
- if (b->memory == V4L2_MEMORY_USERPTR) {
- for (plane = 0; plane < vb->num_planes; ++plane) {
- v4l2_planes[plane].m.userptr =
- b->m.planes[plane].m.userptr;
- v4l2_planes[plane].length =
- b->m.planes[plane].length;
- }
- }
- } else {
- /*
- * Single-planar buffers do not use planes array,
- * so fill in relevant v4l2_buffer struct fields instead.
- * In videobuf we use our internal V4l2_planes struct for
- * single-planar buffers as well, for simplicity.
- */
- if (V4L2_TYPE_IS_OUTPUT(b->type))
- v4l2_planes[0].bytesused = b->bytesused;
-
- if (b->memory == V4L2_MEMORY_USERPTR) {
- v4l2_planes[0].m.userptr = b->m.userptr;
- v4l2_planes[0].length = b->length;
- }
- }
-
- vb->v4l2_buf.field = b->field;
- vb->v4l2_buf.timestamp = b->timestamp;
- vb->v4l2_buf.flags = b->flags & ~V4L2_BUFFER_STATE_FLAGS;
-
- return 0;
-}
-
-/**
- * __qbuf_userptr() - handle qbuf of a USERPTR buffer
- */
-static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
-{
- struct v4l2_plane planes[VIDEO_MAX_PLANES];
- struct vb2_queue *q = vb->vb2_queue;
- void *mem_priv;
- unsigned int plane;
- int ret;
- int write = !V4L2_TYPE_IS_OUTPUT(q->type);
-
- /* Verify and copy relevant information provided by the userspace */
- ret = __fill_vb2_buffer(vb, b, planes);
- if (ret)
- return ret;
-
- for (plane = 0; plane < vb->num_planes; ++plane) {
- /* Skip the plane if already verified */
- if (vb->v4l2_planes[plane].m.userptr &&
- vb->v4l2_planes[plane].m.userptr == planes[plane].m.userptr
- && vb->v4l2_planes[plane].length == planes[plane].length)
- continue;
-
- dprintk(3, "qbuf: userspace address for plane %d changed, "
- "reacquiring memory\n", plane);
-
- /* Check if the provided plane buffer is large enough */
- if (planes[plane].length < q->plane_sizes[plane]) {
- ret = -EINVAL;
- goto err;
- }
-
- /* Release previously acquired memory if present */
- if (vb->planes[plane].mem_priv)
- call_memop(q, put_userptr, vb->planes[plane].mem_priv);
-
- vb->planes[plane].mem_priv = NULL;
- vb->v4l2_planes[plane].m.userptr = 0;
- vb->v4l2_planes[plane].length = 0;
-
- /* Acquire each plane's memory */
- mem_priv = call_memop(q, get_userptr, q->alloc_ctx[plane],
- planes[plane].m.userptr,
- planes[plane].length, write);
- if (IS_ERR_OR_NULL(mem_priv)) {
- dprintk(1, "qbuf: failed acquiring userspace "
- "memory for plane %d\n", plane);
- ret = mem_priv ? PTR_ERR(mem_priv) : -EINVAL;
- goto err;
- }
- vb->planes[plane].mem_priv = mem_priv;
- }
-
- /*
- * Call driver-specific initialization on the newly acquired buffer,
- * if provided.
- */
- ret = call_qop(q, buf_init, vb);
- if (ret) {
- dprintk(1, "qbuf: buffer initialization failed\n");
- goto err;
- }
-
- /*
- * Now that everything is in order, copy relevant information
- * provided by userspace.
- */
- for (plane = 0; plane < vb->num_planes; ++plane)
- vb->v4l2_planes[plane] = planes[plane];
-
- return 0;
-err:
- /* In case of errors, release planes that were already acquired */
- for (plane = 0; plane < vb->num_planes; ++plane) {
- if (vb->planes[plane].mem_priv)
- call_memop(q, put_userptr, vb->planes[plane].mem_priv);
- vb->planes[plane].mem_priv = NULL;
- vb->v4l2_planes[plane].m.userptr = 0;
- vb->v4l2_planes[plane].length = 0;
- }
-
- return ret;
-}
-
-/**
- * __qbuf_mmap() - handle qbuf of an MMAP buffer
- */
-static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b)
-{
- return __fill_vb2_buffer(vb, b, vb->v4l2_planes);
-}
-
-/**
- * __enqueue_in_driver() - enqueue a vb2_buffer in driver for processing
- */
-static void __enqueue_in_driver(struct vb2_buffer *vb)
-{
- struct vb2_queue *q = vb->vb2_queue;
-
- vb->state = VB2_BUF_STATE_ACTIVE;
- atomic_inc(&q->queued_count);
- q->ops->buf_queue(vb);
-}
-
-static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
-{
- struct vb2_queue *q = vb->vb2_queue;
- int ret;
-
- switch (q->memory) {
- case V4L2_MEMORY_MMAP:
- ret = __qbuf_mmap(vb, b);
- break;
- case V4L2_MEMORY_USERPTR:
- ret = __qbuf_userptr(vb, b);
- break;
- default:
- WARN(1, "Invalid queue type\n");
- ret = -EINVAL;
- }
-
- if (!ret)
- ret = call_qop(q, buf_prepare, vb);
- if (ret)
- dprintk(1, "qbuf: buffer preparation failed: %d\n", ret);
- else
- vb->state = VB2_BUF_STATE_PREPARED;
-
- return ret;
-}
-
-/**
- * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel
- * @q: videobuf2 queue
- * @b: buffer structure passed from userspace to vidioc_prepare_buf
- * handler in driver
- *
- * Should be called from vidioc_prepare_buf ioctl handler of a driver.
- * This function:
- * 1) verifies the passed buffer,
- * 2) calls buf_prepare callback in the driver (if provided), in which
- * driver-specific buffer initialization can be performed,
- *
- * The return values from this function are intended to be directly returned
- * from vidioc_prepare_buf handler in driver.
- */
-int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b)
-{
- struct vb2_buffer *vb;
- int ret;
-
- if (q->fileio) {
- dprintk(1, "%s(): file io in progress\n", __func__);
- return -EBUSY;
- }
-
- if (b->type != q->type) {
- dprintk(1, "%s(): invalid buffer type\n", __func__);
- return -EINVAL;
- }
-
- if (b->index >= q->num_buffers) {
- dprintk(1, "%s(): buffer index out of range\n", __func__);
- return -EINVAL;
- }
-
- vb = q->bufs[b->index];
- if (NULL == vb) {
- /* Should never happen */
- dprintk(1, "%s(): buffer is NULL\n", __func__);
- return -EINVAL;
- }
-
- if (b->memory != q->memory) {
- dprintk(1, "%s(): invalid memory type\n", __func__);
- return -EINVAL;
- }
-
- if (vb->state != VB2_BUF_STATE_DEQUEUED) {
- dprintk(1, "%s(): invalid buffer state %d\n", __func__, vb->state);
- return -EINVAL;
- }
-
- ret = __buf_prepare(vb, b);
- if (ret < 0)
- return ret;
-
- __fill_v4l2_buffer(vb, b);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_prepare_buf);
-
-/**
- * vb2_qbuf() - Queue a buffer from userspace
- * @q: videobuf2 queue
- * @b: buffer structure passed from userspace to vidioc_qbuf handler
- * in driver
- *
- * Should be called from vidioc_qbuf ioctl handler of a driver.
- * This function:
- * 1) verifies the passed buffer,
- * 2) if necessary, calls buf_prepare callback in the driver (if provided), in
- * which driver-specific buffer initialization can be performed,
- * 3) if streaming is on, queues the buffer in driver by the means of buf_queue
- * callback for processing.
- *
- * The return values from this function are intended to be directly returned
- * from vidioc_qbuf handler in driver.
- */
-int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
-{
- struct rw_semaphore *mmap_sem = NULL;
- struct vb2_buffer *vb;
- int ret = 0;
-
- /*
- * In case of user pointer buffers vb2 allocator needs to get direct
- * access to userspace pages. This requires getting read access on
- * mmap semaphore in the current process structure. The same
- * semaphore is taken before calling mmap operation, while both mmap
- * and qbuf are called by the driver or v4l2 core with driver's lock
- * held. To avoid a AB-BA deadlock (mmap_sem then driver's lock in
- * mmap and driver's lock then mmap_sem in qbuf) the videobuf2 core
- * release driver's lock, takes mmap_sem and then takes again driver's
- * lock.
- *
- * To avoid race with other vb2 calls, which might be called after
- * releasing driver's lock, this operation is performed at the
- * beggining of qbuf processing. This way the queue status is
- * consistent after getting driver's lock back.
- */
- if (q->memory == V4L2_MEMORY_USERPTR) {
- mmap_sem = &current->mm->mmap_sem;
- call_qop(q, wait_prepare, q);
- down_read(mmap_sem);
- call_qop(q, wait_finish, q);
- }
-
- if (q->fileio) {
- dprintk(1, "qbuf: file io in progress\n");
- ret = -EBUSY;
- goto unlock;
- }
-
- if (b->type != q->type) {
- dprintk(1, "qbuf: invalid buffer type\n");
- ret = -EINVAL;
- goto unlock;
- }
-
- if (b->index >= q->num_buffers) {
- dprintk(1, "qbuf: buffer index out of range\n");
- ret = -EINVAL;
- goto unlock;
- }
-
- vb = q->bufs[b->index];
- if (NULL == vb) {
- /* Should never happen */
- dprintk(1, "qbuf: buffer is NULL\n");
- ret = -EINVAL;
- goto unlock;
- }
-
- if (b->memory != q->memory) {
- dprintk(1, "qbuf: invalid memory type\n");
- ret = -EINVAL;
- goto unlock;
- }
-
- switch (vb->state) {
- case VB2_BUF_STATE_DEQUEUED:
- ret = __buf_prepare(vb, b);
- if (ret)
- goto unlock;
- case VB2_BUF_STATE_PREPARED:
- break;
- default:
- dprintk(1, "qbuf: buffer already in use\n");
- ret = -EINVAL;
- goto unlock;
- }
-
- /*
- * Add to the queued buffers list, a buffer will stay on it until
- * dequeued in dqbuf.
- */
- list_add_tail(&vb->queued_entry, &q->queued_list);
- vb->state = VB2_BUF_STATE_QUEUED;
-
- /*
- * If already streaming, give the buffer to driver for processing.
- * If not, the buffer will be given to driver on next streamon.
- */
- if (q->streaming)
- __enqueue_in_driver(vb);
-
- /* Fill buffer information for the userspace */
- __fill_v4l2_buffer(vb, b);
-
- dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index);
-unlock:
- if (mmap_sem)
- up_read(mmap_sem);
- return ret;
-}
-EXPORT_SYMBOL_GPL(vb2_qbuf);
-
-/**
- * __vb2_wait_for_done_vb() - wait for a buffer to become available
- * for dequeuing
- *
- * Will sleep if required for nonblocking == false.
- */
-static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
-{
- /*
- * All operations on vb_done_list are performed under done_lock
- * spinlock protection. However, buffers may be removed from
- * it and returned to userspace only while holding both driver's
- * lock and the done_lock spinlock. Thus we can be sure that as
- * long as we hold the driver's lock, the list will remain not
- * empty if list_empty() check succeeds.
- */
-
- for (;;) {
- int ret;
-
- if (!q->streaming) {
- dprintk(1, "Streaming off, will not wait for buffers\n");
- return -EINVAL;
- }
-
- if (!list_empty(&q->done_list)) {
- /*
- * Found a buffer that we were waiting for.
- */
- break;
- }
-
- if (nonblocking) {
- dprintk(1, "Nonblocking and no buffers to dequeue, "
- "will not wait\n");
- return -EAGAIN;
- }
-
- /*
- * We are streaming and blocking, wait for another buffer to
- * become ready or for streamoff. Driver's lock is released to
- * allow streamoff or qbuf to be called while waiting.
- */
- call_qop(q, wait_prepare, q);
-
- /*
- * All locks have been released, it is safe to sleep now.
- */
- dprintk(3, "Will sleep waiting for buffers\n");
- ret = wait_event_interruptible(q->done_wq,
- !list_empty(&q->done_list) || !q->streaming);
-
- /*
- * We need to reevaluate both conditions again after reacquiring
- * the locks or return an error if one occurred.
- */
- call_qop(q, wait_finish, q);
- if (ret)
- return ret;
- }
- return 0;
-}
-
-/**
- * __vb2_get_done_vb() - get a buffer ready for dequeuing
- *
- * Will sleep if required for nonblocking == false.
- */
-static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb,
- int nonblocking)
-{
- unsigned long flags;
- int ret;
-
- /*
- * Wait for at least one buffer to become available on the done_list.
- */
- ret = __vb2_wait_for_done_vb(q, nonblocking);
- if (ret)
- return ret;
-
- /*
- * Driver's lock has been held since we last verified that done_list
- * is not empty, so no need for another list_empty(done_list) check.
- */
- spin_lock_irqsave(&q->done_lock, flags);
- *vb = list_first_entry(&q->done_list, struct vb2_buffer, done_entry);
- list_del(&(*vb)->done_entry);
- spin_unlock_irqrestore(&q->done_lock, flags);
-
- return 0;
-}
-
-/**
- * vb2_wait_for_all_buffers() - wait until all buffers are given back to vb2
- * @q: videobuf2 queue
- *
- * This function will wait until all buffers that have been given to the driver
- * by buf_queue() are given back to vb2 with vb2_buffer_done(). It doesn't call
- * wait_prepare, wait_finish pair. It is intended to be called with all locks
- * taken, for example from stop_streaming() callback.
- */
-int vb2_wait_for_all_buffers(struct vb2_queue *q)
-{
- if (!q->streaming) {
- dprintk(1, "Streaming off, will not wait for buffers\n");
- return -EINVAL;
- }
-
- wait_event(q->done_wq, !atomic_read(&q->queued_count));
- return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_wait_for_all_buffers);
-
-/**
- * vb2_dqbuf() - Dequeue a buffer to the userspace
- * @q: videobuf2 queue
- * @b: buffer structure passed from userspace to vidioc_dqbuf handler
- * in driver
- * @nonblocking: if true, this call will not sleep waiting for a buffer if no
- * buffers ready for dequeuing are present. Normally the driver
- * would be passing (file->f_flags & O_NONBLOCK) here
- *
- * Should be called from vidioc_dqbuf ioctl handler of a driver.
- * This function:
- * 1) verifies the passed buffer,
- * 2) calls buf_finish callback in the driver (if provided), in which
- * driver can perform any additional operations that may be required before
- * returning the buffer to userspace, such as cache sync,
- * 3) the buffer struct members are filled with relevant information for
- * the userspace.
- *
- * The return values from this function are intended to be directly returned
- * from vidioc_dqbuf handler in driver.
- */
-int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
-{
- struct vb2_buffer *vb = NULL;
- int ret;
-
- if (q->fileio) {
- dprintk(1, "dqbuf: file io in progress\n");
- return -EBUSY;
- }
-
- if (b->type != q->type) {
- dprintk(1, "dqbuf: invalid buffer type\n");
- return -EINVAL;
- }
-
- ret = __vb2_get_done_vb(q, &vb, nonblocking);
- if (ret < 0) {
- dprintk(1, "dqbuf: error getting next done buffer\n");
- return ret;
- }
-
- ret = call_qop(q, buf_finish, vb);
- if (ret) {
- dprintk(1, "dqbuf: buffer finish failed\n");
- return ret;
- }
-
- switch (vb->state) {
- case VB2_BUF_STATE_DONE:
- dprintk(3, "dqbuf: Returning done buffer\n");
- break;
- case VB2_BUF_STATE_ERROR:
- dprintk(3, "dqbuf: Returning done buffer with errors\n");
- break;
- default:
- dprintk(1, "dqbuf: Invalid buffer state\n");
- return -EINVAL;
- }
-
- /* Fill buffer information for the userspace */
- __fill_v4l2_buffer(vb, b);
- /* Remove from videobuf queue */
- list_del(&vb->queued_entry);
-
- dprintk(1, "dqbuf of buffer %d, with state %d\n",
- vb->v4l2_buf.index, vb->state);
-
- vb->state = VB2_BUF_STATE_DEQUEUED;
- return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_dqbuf);
-
-/**
- * __vb2_queue_cancel() - cancel and stop (pause) streaming
- *
- * Removes all queued buffers from driver's queue and all buffers queued by
- * userspace from videobuf's queue. Returns to state after reqbufs.
- */
-static void __vb2_queue_cancel(struct vb2_queue *q)
-{
- unsigned int i;
-
- /*
- * Tell driver to stop all transactions and release all queued
- * buffers.
- */
- if (q->streaming)
- call_qop(q, stop_streaming, q);
- q->streaming = 0;
-
- /*
- * Remove all buffers from videobuf's list...
- */
- INIT_LIST_HEAD(&q->queued_list);
- /*
- * ...and done list; userspace will not receive any buffers it
- * has not already dequeued before initiating cancel.
- */
- INIT_LIST_HEAD(&q->done_list);
- atomic_set(&q->queued_count, 0);
- wake_up_all(&q->done_wq);
-
- /*
- * Reinitialize all buffers for next use.
- */
- for (i = 0; i < q->num_buffers; ++i)
- q->bufs[i]->state = VB2_BUF_STATE_DEQUEUED;
-}
-
-/**
- * vb2_streamon - start streaming
- * @q: videobuf2 queue
- * @type: type argument passed from userspace to vidioc_streamon handler
- *
- * Should be called from vidioc_streamon handler of a driver.
- * This function:
- * 1) verifies current state
- * 2) passes any previously queued buffers to the driver and starts streaming
- *
- * The return values from this function are intended to be directly returned
- * from vidioc_streamon handler in the driver.
- */
-int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
-{
- struct vb2_buffer *vb;
- int ret;
-
- if (q->fileio) {
- dprintk(1, "streamon: file io in progress\n");
- return -EBUSY;
- }
-
- if (type != q->type) {
- dprintk(1, "streamon: invalid stream type\n");
- return -EINVAL;
- }
-
- if (q->streaming) {
- dprintk(1, "streamon: already streaming\n");
- return -EBUSY;
- }
-
- /*
- * If any buffers were queued before streamon,
- * we can now pass them to driver for processing.
- */
- list_for_each_entry(vb, &q->queued_list, queued_entry)
- __enqueue_in_driver(vb);
-
- /*
- * Let driver notice that streaming state has been enabled.
- */
- ret = call_qop(q, start_streaming, q, atomic_read(&q->queued_count));
- if (ret) {
- dprintk(1, "streamon: driver refused to start streaming\n");
- __vb2_queue_cancel(q);
- return ret;
- }
-
- q->streaming = 1;
-
- dprintk(3, "Streamon successful\n");
- return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_streamon);
-
-
-/**
- * vb2_streamoff - stop streaming
- * @q: videobuf2 queue
- * @type: type argument passed from userspace to vidioc_streamoff handler
- *
- * Should be called from vidioc_streamoff handler of a driver.
- * This function:
- * 1) verifies current state,
- * 2) stop streaming and dequeues any queued buffers, including those previously
- * passed to the driver (after waiting for the driver to finish).
- *
- * This call can be used for pausing playback.
- * The return values from this function are intended to be directly returned
- * from vidioc_streamoff handler in the driver
- */
-int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
-{
- if (q->fileio) {
- dprintk(1, "streamoff: file io in progress\n");
- return -EBUSY;
- }
-
- if (type != q->type) {
- dprintk(1, "streamoff: invalid stream type\n");
- return -EINVAL;
- }
-
- if (!q->streaming) {
- dprintk(1, "streamoff: not streaming\n");
- return -EINVAL;
- }
-
- /*
- * Cancel will pause streaming and remove all buffers from the driver
- * and videobuf, effectively returning control over them to userspace.
- */
- __vb2_queue_cancel(q);
-
- dprintk(3, "Streamoff successful\n");
- return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_streamoff);
-
-/**
- * __find_plane_by_offset() - find plane associated with the given offset off
- */
-static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
- unsigned int *_buffer, unsigned int *_plane)
-{
- struct vb2_buffer *vb;
- unsigned int buffer, plane;
-
- /*
- * Go over all buffers and their planes, comparing the given offset
- * with an offset assigned to each plane. If a match is found,
- * return its buffer and plane numbers.
- */
- for (buffer = 0; buffer < q->num_buffers; ++buffer) {
- vb = q->bufs[buffer];
-
- for (plane = 0; plane < vb->num_planes; ++plane) {
- if (vb->v4l2_planes[plane].m.mem_offset == off) {
- *_buffer = buffer;
- *_plane = plane;
- return 0;
- }
- }
- }
-
- return -EINVAL;
-}
-
-/**
- * vb2_mmap() - map video buffers into application address space
- * @q: videobuf2 queue
- * @vma: vma passed to the mmap file operation handler in the driver
- *
- * Should be called from mmap file operation handler of a driver.
- * This function maps one plane of one of the available video buffers to
- * userspace. To map whole video memory allocated on reqbufs, this function
- * has to be called once per each plane per each buffer previously allocated.
- *
- * When the userspace application calls mmap, it passes to it an offset returned
- * to it earlier by the means of vidioc_querybuf handler. That offset acts as
- * a "cookie", which is then used to identify the plane to be mapped.
- * This function finds a plane with a matching offset and a mapping is performed
- * by the means of a provided memory operation.
- *
- * The return values from this function are intended to be directly returned
- * from the mmap handler in driver.
- */
-int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
-{
- unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
- struct vb2_buffer *vb;
- unsigned int buffer, plane;
- int ret;
-
- if (q->memory != V4L2_MEMORY_MMAP) {
- dprintk(1, "Queue is not currently set up for mmap\n");
- return -EINVAL;
- }
-
- /*
- * Check memory area access mode.
- */
- if (!(vma->vm_flags & VM_SHARED)) {
- dprintk(1, "Invalid vma flags, VM_SHARED needed\n");
- return -EINVAL;
- }
- if (V4L2_TYPE_IS_OUTPUT(q->type)) {
- if (!(vma->vm_flags & VM_WRITE)) {
- dprintk(1, "Invalid vma flags, VM_WRITE needed\n");
- return -EINVAL;
- }
- } else {
- if (!(vma->vm_flags & VM_READ)) {
- dprintk(1, "Invalid vma flags, VM_READ needed\n");
- return -EINVAL;
- }
- }
-
- /*
- * Find the plane corresponding to the offset passed by userspace.
- */
- ret = __find_plane_by_offset(q, off, &buffer, &plane);
- if (ret)
- return ret;
-
- vb = q->bufs[buffer];
-
- ret = call_memop(q, mmap, vb->planes[plane].mem_priv, vma);
- if (ret)
- return ret;
-
- dprintk(3, "Buffer %d, plane %d successfully mapped\n", buffer, plane);
- return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_mmap);
-
-#ifndef CONFIG_MMU
-unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
- unsigned long addr,
- unsigned long len,
- unsigned long pgoff,
- unsigned long flags)
-{
- unsigned long off = pgoff << PAGE_SHIFT;
- struct vb2_buffer *vb;
- unsigned int buffer, plane;
- int ret;
-
- if (q->memory != V4L2_MEMORY_MMAP) {
- dprintk(1, "Queue is not currently set up for mmap\n");
- return -EINVAL;
- }
-
- /*
- * Find the plane corresponding to the offset passed by userspace.
- */
- ret = __find_plane_by_offset(q, off, &buffer, &plane);
- if (ret)
- return ret;
-
- vb = q->bufs[buffer];
-
- return (unsigned long)vb2_plane_vaddr(vb, plane);
-}
-EXPORT_SYMBOL_GPL(vb2_get_unmapped_area);
-#endif
-
-static int __vb2_init_fileio(struct vb2_queue *q, int read);
-static int __vb2_cleanup_fileio(struct vb2_queue *q);
-
-/**
- * vb2_poll() - implements poll userspace operation
- * @q: videobuf2 queue
- * @file: file argument passed to the poll file operation handler
- * @wait: wait argument passed to the poll file operation handler
- *
- * This function implements poll file operation handler for a driver.
- * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will
- * be informed that the file descriptor of a video device is available for
- * reading.
- * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor
- * will be reported as available for writing.
- *
- * If the driver uses struct v4l2_fh, then vb2_poll() will also check for any
- * pending events.
- *
- * The return values from this function are intended to be directly returned
- * from poll handler in driver.
- */
-unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
-{
- struct video_device *vfd = video_devdata(file);
- unsigned long req_events = poll_requested_events(wait);
- struct vb2_buffer *vb = NULL;
- unsigned int res = 0;
- unsigned long flags;
-
- if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
- struct v4l2_fh *fh = file->private_data;
-
- if (v4l2_event_pending(fh))
- res = POLLPRI;
- else if (req_events & POLLPRI)
- poll_wait(file, &fh->wait, wait);
- }
-
- /*
- * Start file I/O emulator only if streaming API has not been used yet.
- */
- if (q->num_buffers == 0 && q->fileio == NULL) {
- if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ) &&
- (req_events & (POLLIN | POLLRDNORM))) {
- if (__vb2_init_fileio(q, 1))
- return res | POLLERR;
- }
- if (V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_WRITE) &&
- (req_events & (POLLOUT | POLLWRNORM))) {
- if (__vb2_init_fileio(q, 0))
- return res | POLLERR;
- /*
- * Write to OUTPUT queue can be done immediately.
- */
- return res | POLLOUT | POLLWRNORM;
- }
- }
-
- /*
- * There is nothing to wait for if no buffers have already been queued.
- */
- if (list_empty(&q->queued_list))
- return res | POLLERR;
-
- poll_wait(file, &q->done_wq, wait);
-
- /*
- * Take first buffer available for dequeuing.
- */
- spin_lock_irqsave(&q->done_lock, flags);
- if (!list_empty(&q->done_list))
- vb = list_first_entry(&q->done_list, struct vb2_buffer,
- done_entry);
- spin_unlock_irqrestore(&q->done_lock, flags);
-
- if (vb && (vb->state == VB2_BUF_STATE_DONE
- || vb->state == VB2_BUF_STATE_ERROR)) {
- return (V4L2_TYPE_IS_OUTPUT(q->type)) ?
- res | POLLOUT | POLLWRNORM :
- res | POLLIN | POLLRDNORM;
- }
- return res;
-}
-EXPORT_SYMBOL_GPL(vb2_poll);
-
-/**
- * vb2_queue_init() - initialize a videobuf2 queue
- * @q: videobuf2 queue; this structure should be allocated in driver
- *
- * The vb2_queue structure should be allocated by the driver. The driver is
- * responsible of clearing it's content and setting initial values for some
- * required entries before calling this function.
- * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer
- * to the struct vb2_queue description in include/media/videobuf2-core.h
- * for more information.
- */
-int vb2_queue_init(struct vb2_queue *q)
-{
- BUG_ON(!q);
- BUG_ON(!q->ops);
- BUG_ON(!q->mem_ops);
- BUG_ON(!q->type);
- BUG_ON(!q->io_modes);
-
- BUG_ON(!q->ops->queue_setup);
- BUG_ON(!q->ops->buf_queue);
-
- INIT_LIST_HEAD(&q->queued_list);
- INIT_LIST_HEAD(&q->done_list);
- spin_lock_init(&q->done_lock);
- init_waitqueue_head(&q->done_wq);
-
- if (q->buf_struct_size == 0)
- q->buf_struct_size = sizeof(struct vb2_buffer);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_queue_init);
-
-/**
- * vb2_queue_release() - stop streaming, release the queue and free memory
- * @q: videobuf2 queue
- *
- * This function stops streaming and performs necessary clean ups, including
- * freeing video buffer memory. The driver is responsible for freeing
- * the vb2_queue structure itself.
- */
-void vb2_queue_release(struct vb2_queue *q)
-{
- __vb2_cleanup_fileio(q);
- __vb2_queue_cancel(q);
- __vb2_queue_free(q, q->num_buffers);
-}
-EXPORT_SYMBOL_GPL(vb2_queue_release);
-
-/**
- * struct vb2_fileio_buf - buffer context used by file io emulator
- *
- * vb2 provides a compatibility layer and emulator of file io (read and
- * write) calls on top of streaming API. This structure is used for
- * tracking context related to the buffers.
- */
-struct vb2_fileio_buf {
- void *vaddr;
- unsigned int size;
- unsigned int pos;
- unsigned int queued:1;
-};
-
-/**
- * struct vb2_fileio_data - queue context used by file io emulator
- *
- * vb2 provides a compatibility layer and emulator of file io (read and
- * write) calls on top of streaming API. For proper operation it required
- * this structure to save the driver state between each call of the read
- * or write function.
- */
-struct vb2_fileio_data {
- struct v4l2_requestbuffers req;
- struct v4l2_buffer b;
- struct vb2_fileio_buf bufs[VIDEO_MAX_FRAME];
- unsigned int index;
- unsigned int q_count;
- unsigned int dq_count;
- unsigned int flags;
-};
-
-/**
- * __vb2_init_fileio() - initialize file io emulator
- * @q: videobuf2 queue
- * @read: mode selector (1 means read, 0 means write)
- */
-static int __vb2_init_fileio(struct vb2_queue *q, int read)
-{
- struct vb2_fileio_data *fileio;
- int i, ret;
- unsigned int count = 0;
-
- /*
- * Sanity check
- */
- if ((read && !(q->io_modes & VB2_READ)) ||
- (!read && !(q->io_modes & VB2_WRITE)))
- BUG();
-
- /*
- * Check if device supports mapping buffers to kernel virtual space.
- */
- if (!q->mem_ops->vaddr)
- return -EBUSY;
-
- /*
- * Check if streaming api has not been already activated.
- */
- if (q->streaming || q->num_buffers > 0)
- return -EBUSY;
-
- /*
- * Start with count 1, driver can increase it in queue_setup()
- */
- count = 1;
-
- dprintk(3, "setting up file io: mode %s, count %d, flags %08x\n",
- (read) ? "read" : "write", count, q->io_flags);
-
- fileio = kzalloc(sizeof(struct vb2_fileio_data), GFP_KERNEL);
- if (fileio == NULL)
- return -ENOMEM;
-
- fileio->flags = q->io_flags;
-
- /*
- * Request buffers and use MMAP type to force driver
- * to allocate buffers by itself.
- */
- fileio->req.count = count;
- fileio->req.memory = V4L2_MEMORY_MMAP;
- fileio->req.type = q->type;
- ret = vb2_reqbufs(q, &fileio->req);
- if (ret)
- goto err_kfree;
-
- /*
- * Check if plane_count is correct
- * (multiplane buffers are not supported).
- */
- if (q->bufs[0]->num_planes != 1) {
- ret = -EBUSY;
- goto err_reqbufs;
- }
-
- /*
- * Get kernel address of each buffer.
- */
- for (i = 0; i < q->num_buffers; i++) {
- fileio->bufs[i].vaddr = vb2_plane_vaddr(q->bufs[i], 0);
- if (fileio->bufs[i].vaddr == NULL)
- goto err_reqbufs;
- fileio->bufs[i].size = vb2_plane_size(q->bufs[i], 0);
- }
-
- /*
- * Read mode requires pre queuing of all buffers.
- */
- if (read) {
- /*
- * Queue all buffers.
- */
- for (i = 0; i < q->num_buffers; i++) {
- struct v4l2_buffer *b = &fileio->b;
- memset(b, 0, sizeof(*b));
- b->type = q->type;
- b->memory = q->memory;
- b->index = i;
- ret = vb2_qbuf(q, b);
- if (ret)
- goto err_reqbufs;
- fileio->bufs[i].queued = 1;
- }
-
- /*
- * Start streaming.
- */
- ret = vb2_streamon(q, q->type);
- if (ret)
- goto err_reqbufs;
- }
-
- q->fileio = fileio;
-
- return ret;
-
-err_reqbufs:
- fileio->req.count = 0;
- vb2_reqbufs(q, &fileio->req);
-
-err_kfree:
- kfree(fileio);
- return ret;
-}
-
-/**
- * __vb2_cleanup_fileio() - free resourced used by file io emulator
- * @q: videobuf2 queue
- */
-static int __vb2_cleanup_fileio(struct vb2_queue *q)
-{
- struct vb2_fileio_data *fileio = q->fileio;
-
- if (fileio) {
- /*
- * Hack fileio context to enable direct calls to vb2 ioctl
- * interface.
- */
- q->fileio = NULL;
-
- vb2_streamoff(q, q->type);
- fileio->req.count = 0;
- vb2_reqbufs(q, &fileio->req);
- kfree(fileio);
- dprintk(3, "file io emulator closed\n");
- }
- return 0;
-}
-
-/**
- * __vb2_perform_fileio() - perform a single file io (read or write) operation
- * @q: videobuf2 queue
- * @data: pointed to target userspace buffer
- * @count: number of bytes to read or write
- * @ppos: file handle position tracking pointer
- * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking)
- * @read: access mode selector (1 means read, 0 means write)
- */
-static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_t count,
- loff_t *ppos, int nonblock, int read)
-{
- struct vb2_fileio_data *fileio;
- struct vb2_fileio_buf *buf;
- int ret, index;
-
- dprintk(3, "file io: mode %s, offset %ld, count %zd, %sblocking\n",
- read ? "read" : "write", (long)*ppos, count,
- nonblock ? "non" : "");
-
- if (!data)
- return -EINVAL;
-
- /*
- * Initialize emulator on first call.
- */
- if (!q->fileio) {
- ret = __vb2_init_fileio(q, read);
- dprintk(3, "file io: vb2_init_fileio result: %d\n", ret);
- if (ret)
- return ret;
- }
- fileio = q->fileio;
-
- /*
- * Hack fileio context to enable direct calls to vb2 ioctl interface.
- * The pointer will be restored before returning from this function.
- */
- q->fileio = NULL;
-
- index = fileio->index;
- buf = &fileio->bufs[index];
-
- /*
- * Check if we need to dequeue the buffer.
- */
- if (buf->queued) {
- struct vb2_buffer *vb;
-
- /*
- * Call vb2_dqbuf to get buffer back.
- */
- memset(&fileio->b, 0, sizeof(fileio->b));
- fileio->b.type = q->type;
- fileio->b.memory = q->memory;
- fileio->b.index = index;
- ret = vb2_dqbuf(q, &fileio->b, nonblock);
- dprintk(5, "file io: vb2_dqbuf result: %d\n", ret);
- if (ret)
- goto end;
- fileio->dq_count += 1;
-
- /*
- * Get number of bytes filled by the driver
- */
- vb = q->bufs[index];
- buf->size = vb2_get_plane_payload(vb, 0);
- buf->queued = 0;
- }
-
- /*
- * Limit count on last few bytes of the buffer.
- */
- if (buf->pos + count > buf->size) {
- count = buf->size - buf->pos;
- dprintk(5, "reducing read count: %zd\n", count);
- }
-
- /*
- * Transfer data to userspace.
- */
- dprintk(3, "file io: copying %zd bytes - buffer %d, offset %u\n",
- count, index, buf->pos);
- if (read)
- ret = copy_to_user(data, buf->vaddr + buf->pos, count);
- else
- ret = copy_from_user(buf->vaddr + buf->pos, data, count);
- if (ret) {
- dprintk(3, "file io: error copying data\n");
- ret = -EFAULT;
- goto end;
- }
-
- /*
- * Update counters.
- */
- buf->pos += count;
- *ppos += count;
-
- /*
- * Queue next buffer if required.
- */
- if (buf->pos == buf->size ||
- (!read && (fileio->flags & VB2_FILEIO_WRITE_IMMEDIATELY))) {
- /*
- * Check if this is the last buffer to read.
- */
- if (read && (fileio->flags & VB2_FILEIO_READ_ONCE) &&
- fileio->dq_count == 1) {
- dprintk(3, "file io: read limit reached\n");
- /*
- * Restore fileio pointer and release the context.
- */
- q->fileio = fileio;
- return __vb2_cleanup_fileio(q);
- }
-
- /*
- * Call vb2_qbuf and give buffer to the driver.
- */
- memset(&fileio->b, 0, sizeof(fileio->b));
- fileio->b.type = q->type;
- fileio->b.memory = q->memory;
- fileio->b.index = index;
- fileio->b.bytesused = buf->pos;
- ret = vb2_qbuf(q, &fileio->b);
- dprintk(5, "file io: vb2_dbuf result: %d\n", ret);
- if (ret)
- goto end;
-
- /*
- * Buffer has been queued, update the status
- */
- buf->pos = 0;
- buf->queued = 1;
- buf->size = q->bufs[0]->v4l2_planes[0].length;
- fileio->q_count += 1;
-
- /*
- * Switch to the next buffer
- */
- fileio->index = (index + 1) % q->num_buffers;
-
- /*
- * Start streaming if required.
- */
- if (!read && !q->streaming) {
- ret = vb2_streamon(q, q->type);
- if (ret)
- goto end;
- }
- }
-
- /*
- * Return proper number of bytes processed.
- */
- if (ret == 0)
- ret = count;
-end:
- /*
- * Restore the fileio context and block vb2 ioctl interface.
- */
- q->fileio = fileio;
- return ret;
-}
-
-size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
- loff_t *ppos, int nonblocking)
-{
- return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 1);
-}
-EXPORT_SYMBOL_GPL(vb2_read);
-
-size_t vb2_write(struct vb2_queue *q, char __user *data, size_t count,
- loff_t *ppos, int nonblocking)
-{
- return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 0);
-}
-EXPORT_SYMBOL_GPL(vb2_write);
-
-
-/*
- * The following functions are not part of the vb2 core API, but are helper
- * functions that plug into struct v4l2_ioctl_ops, struct v4l2_file_operations
- * and struct vb2_ops.
- * They contain boilerplate code that most if not all drivers have to do
- * and so they simplify the driver code.
- */
-
-/* The queue is busy if there is a owner and you are not that owner. */
-static inline bool vb2_queue_is_busy(struct video_device *vdev, struct file *file)
-{
- return vdev->queue->owner && vdev->queue->owner != file->private_data;
-}
-
-/* vb2 ioctl helpers */
-
-int vb2_ioctl_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct video_device *vdev = video_devdata(file);
- int res = __verify_memory_type(vdev->queue, p->memory, p->type);
-
- if (res)
- return res;
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- res = __reqbufs(vdev->queue, p);
- /* If count == 0, then the owner has released all buffers and he
- is no longer owner of the queue. Otherwise we have a new owner. */
- if (res == 0)
- vdev->queue->owner = p->count ? file->private_data : NULL;
- return res;
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_reqbufs);
-
-int vb2_ioctl_create_bufs(struct file *file, void *priv,
- struct v4l2_create_buffers *p)
-{
- struct video_device *vdev = video_devdata(file);
- int res = __verify_memory_type(vdev->queue, p->memory, p->format.type);
-
- p->index = vdev->queue->num_buffers;
- /* If count == 0, then just check if memory and type are valid.
- Any -EBUSY result from __verify_memory_type can be mapped to 0. */
- if (p->count == 0)
- return res != -EBUSY ? res : 0;
- if (res)
- return res;
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- res = __create_bufs(vdev->queue, p);
- if (res == 0)
- vdev->queue->owner = file->private_data;
- return res;
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_create_bufs);
-
-int vb2_ioctl_prepare_buf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct video_device *vdev = video_devdata(file);
-
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- return vb2_prepare_buf(vdev->queue, p);
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_prepare_buf);
-
-int vb2_ioctl_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct video_device *vdev = video_devdata(file);
-
- /* No need to call vb2_queue_is_busy(), anyone can query buffers. */
- return vb2_querybuf(vdev->queue, p);
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_querybuf);
-
-int vb2_ioctl_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct video_device *vdev = video_devdata(file);
-
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- return vb2_qbuf(vdev->queue, p);
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_qbuf);
-
-int vb2_ioctl_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct video_device *vdev = video_devdata(file);
-
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- return vb2_dqbuf(vdev->queue, p, file->f_flags & O_NONBLOCK);
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_dqbuf);
-
-int vb2_ioctl_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct video_device *vdev = video_devdata(file);
-
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- return vb2_streamon(vdev->queue, i);
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_streamon);
-
-int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct video_device *vdev = video_devdata(file);
-
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- return vb2_streamoff(vdev->queue, i);
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff);
-
-/* v4l2_file_operations helpers */
-
-int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct video_device *vdev = video_devdata(file);
-
- return vb2_mmap(vdev->queue, vma);
-}
-EXPORT_SYMBOL_GPL(vb2_fop_mmap);
-
-int vb2_fop_release(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
-
- if (file->private_data == vdev->queue->owner) {
- vb2_queue_release(vdev->queue);
- vdev->queue->owner = NULL;
- }
- return v4l2_fh_release(file);
-}
-EXPORT_SYMBOL_GPL(vb2_fop_release);
-
-ssize_t vb2_fop_write(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct video_device *vdev = video_devdata(file);
- struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock;
- bool must_lock = !test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && lock;
- int err = -EBUSY;
-
- if (must_lock && mutex_lock_interruptible(lock))
- return -ERESTARTSYS;
- if (vb2_queue_is_busy(vdev, file))
- goto exit;
- err = vb2_write(vdev->queue, buf, count, ppos,
- file->f_flags & O_NONBLOCK);
- if (err >= 0)
- vdev->queue->owner = file->private_data;
-exit:
- if (must_lock)
- mutex_unlock(lock);
- return err;
-}
-EXPORT_SYMBOL_GPL(vb2_fop_write);
-
-ssize_t vb2_fop_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct video_device *vdev = video_devdata(file);
- struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock;
- bool must_lock = !test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && vdev->lock;
- int err = -EBUSY;
-
- if (must_lock && mutex_lock_interruptible(lock))
- return -ERESTARTSYS;
- if (vb2_queue_is_busy(vdev, file))
- goto exit;
- err = vb2_read(vdev->queue, buf, count, ppos,
- file->f_flags & O_NONBLOCK);
- if (err >= 0)
- vdev->queue->owner = file->private_data;
-exit:
- if (must_lock)
- mutex_unlock(lock);
- return err;
-}
-EXPORT_SYMBOL_GPL(vb2_fop_read);
-
-unsigned int vb2_fop_poll(struct file *file, poll_table *wait)
-{
- struct video_device *vdev = video_devdata(file);
- struct vb2_queue *q = vdev->queue;
- struct mutex *lock = q->lock ? q->lock : vdev->lock;
- unsigned long req_events = poll_requested_events(wait);
- unsigned res;
- void *fileio;
- /* Yuck. We really need to get rid of this flag asap. If it is
- set, then the core took the serialization lock before calling
- poll(). This is being phased out, but for now we have to handle
- this case. */
- bool locked = test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags);
- bool must_lock = false;
-
- /* Try to be smart: only lock if polling might start fileio,
- otherwise locking will only introduce unwanted delays. */
- if (q->num_buffers == 0 && q->fileio == NULL) {
- if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ) &&
- (req_events & (POLLIN | POLLRDNORM)))
- must_lock = true;
- else if (V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_WRITE) &&
- (req_events & (POLLOUT | POLLWRNORM)))
- must_lock = true;
- }
-
- /* If locking is needed, but this helper doesn't know how, then you
- shouldn't be using this helper but you should write your own. */
- WARN_ON(must_lock && !locked && !lock);
-
- if (must_lock && !locked && lock && mutex_lock_interruptible(lock))
- return POLLERR;
-
- fileio = q->fileio;
-
- res = vb2_poll(vdev->queue, file, wait);
-
- /* If fileio was started, then we have a new queue owner. */
- if (must_lock && !fileio && q->fileio)
- q->owner = file->private_data;
- if (must_lock && !locked && lock)
- mutex_unlock(lock);
- return res;
-}
-EXPORT_SYMBOL_GPL(vb2_fop_poll);
-
-#ifndef CONFIG_MMU
-unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff, unsigned long flags)
-{
- struct video_device *vdev = video_devdata(file);
-
- return vb2_get_unmapped_area(vdev->queue, addr, len, pgoff, flags);
-}
-EXPORT_SYMBOL_GPL(vb2_fop_get_unmapped_area);
-#endif
-
-/* vb2_ops helpers. Only use if vq->lock is non-NULL. */
-
-void vb2_ops_wait_prepare(struct vb2_queue *vq)
-{
- mutex_unlock(vq->lock);
-}
-EXPORT_SYMBOL_GPL(vb2_ops_wait_prepare);
-
-void vb2_ops_wait_finish(struct vb2_queue *vq)
-{
- mutex_lock(vq->lock);
-}
-EXPORT_SYMBOL_GPL(vb2_ops_wait_finish);
-
-MODULE_DESCRIPTION("Driver helper framework for Video for Linux 2");
-MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>, Marek Szyprowski");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videobuf2-dma-contig.c b/drivers/media/video/videobuf2-dma-contig.c
deleted file mode 100644
index 4b7132660a9..00000000000
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * videobuf2-dma-contig.c - DMA contig memory allocator for videobuf2
- *
- * Copyright (C) 2010 Samsung Electronics
- *
- * Author: Pawel Osciak <pawel@osciak.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/dma-mapping.h>
-
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-contig.h>
-#include <media/videobuf2-memops.h>
-
-struct vb2_dc_conf {
- struct device *dev;
-};
-
-struct vb2_dc_buf {
- struct vb2_dc_conf *conf;
- void *vaddr;
- dma_addr_t dma_addr;
- unsigned long size;
- struct vm_area_struct *vma;
- atomic_t refcount;
- struct vb2_vmarea_handler handler;
-};
-
-static void vb2_dma_contig_put(void *buf_priv);
-
-static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size)
-{
- struct vb2_dc_conf *conf = alloc_ctx;
- struct vb2_dc_buf *buf;
-
- buf = kzalloc(sizeof *buf, GFP_KERNEL);
- if (!buf)
- return ERR_PTR(-ENOMEM);
-
- buf->vaddr = dma_alloc_coherent(conf->dev, size, &buf->dma_addr,
- GFP_KERNEL);
- if (!buf->vaddr) {
- dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n",
- size);
- kfree(buf);
- return ERR_PTR(-ENOMEM);
- }
-
- buf->conf = conf;
- buf->size = size;
-
- buf->handler.refcount = &buf->refcount;
- buf->handler.put = vb2_dma_contig_put;
- buf->handler.arg = buf;
-
- atomic_inc(&buf->refcount);
-
- return buf;
-}
-
-static void vb2_dma_contig_put(void *buf_priv)
-{
- struct vb2_dc_buf *buf = buf_priv;
-
- if (atomic_dec_and_test(&buf->refcount)) {
- dma_free_coherent(buf->conf->dev, buf->size, buf->vaddr,
- buf->dma_addr);
- kfree(buf);
- }
-}
-
-static void *vb2_dma_contig_cookie(void *buf_priv)
-{
- struct vb2_dc_buf *buf = buf_priv;
-
- return &buf->dma_addr;
-}
-
-static void *vb2_dma_contig_vaddr(void *buf_priv)
-{
- struct vb2_dc_buf *buf = buf_priv;
- if (!buf)
- return NULL;
-
- return buf->vaddr;
-}
-
-static unsigned int vb2_dma_contig_num_users(void *buf_priv)
-{
- struct vb2_dc_buf *buf = buf_priv;
-
- return atomic_read(&buf->refcount);
-}
-
-static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma)
-{
- struct vb2_dc_buf *buf = buf_priv;
-
- if (!buf) {
- printk(KERN_ERR "No buffer to map\n");
- return -EINVAL;
- }
-
- return vb2_mmap_pfn_range(vma, buf->dma_addr, buf->size,
- &vb2_common_vm_ops, &buf->handler);
-}
-
-static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr,
- unsigned long size, int write)
-{
- struct vb2_dc_buf *buf;
- struct vm_area_struct *vma;
- dma_addr_t dma_addr = 0;
- int ret;
-
- buf = kzalloc(sizeof *buf, GFP_KERNEL);
- if (!buf)
- return ERR_PTR(-ENOMEM);
-
- ret = vb2_get_contig_userptr(vaddr, size, &vma, &dma_addr);
- if (ret) {
- printk(KERN_ERR "Failed acquiring VMA for vaddr 0x%08lx\n",
- vaddr);
- kfree(buf);
- return ERR_PTR(ret);
- }
-
- buf->size = size;
- buf->dma_addr = dma_addr;
- buf->vma = vma;
-
- return buf;
-}
-
-static void vb2_dma_contig_put_userptr(void *mem_priv)
-{
- struct vb2_dc_buf *buf = mem_priv;
-
- if (!buf)
- return;
-
- vb2_put_vma(buf->vma);
- kfree(buf);
-}
-
-const struct vb2_mem_ops vb2_dma_contig_memops = {
- .alloc = vb2_dma_contig_alloc,
- .put = vb2_dma_contig_put,
- .cookie = vb2_dma_contig_cookie,
- .vaddr = vb2_dma_contig_vaddr,
- .mmap = vb2_dma_contig_mmap,
- .get_userptr = vb2_dma_contig_get_userptr,
- .put_userptr = vb2_dma_contig_put_userptr,
- .num_users = vb2_dma_contig_num_users,
-};
-EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
-
-void *vb2_dma_contig_init_ctx(struct device *dev)
-{
- struct vb2_dc_conf *conf;
-
- conf = kzalloc(sizeof *conf, GFP_KERNEL);
- if (!conf)
- return ERR_PTR(-ENOMEM);
-
- conf->dev = dev;
-
- return conf;
-}
-EXPORT_SYMBOL_GPL(vb2_dma_contig_init_ctx);
-
-void vb2_dma_contig_cleanup_ctx(void *alloc_ctx)
-{
- kfree(alloc_ctx);
-}
-EXPORT_SYMBOL_GPL(vb2_dma_contig_cleanup_ctx);
-
-MODULE_DESCRIPTION("DMA-contig memory handling routines for videobuf2");
-MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videobuf2-dma-sg.c b/drivers/media/video/videobuf2-dma-sg.c
deleted file mode 100644
index 25c3b360e1a..00000000000
--- a/drivers/media/video/videobuf2-dma-sg.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * videobuf2-dma-sg.c - dma scatter/gather memory allocator for videobuf2
- *
- * Copyright (C) 2010 Samsung Electronics
- *
- * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-memops.h>
-#include <media/videobuf2-dma-sg.h>
-
-struct vb2_dma_sg_buf {
- void *vaddr;
- struct page **pages;
- int write;
- int offset;
- struct vb2_dma_sg_desc sg_desc;
- atomic_t refcount;
- struct vb2_vmarea_handler handler;
-};
-
-static void vb2_dma_sg_put(void *buf_priv);
-
-static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size)
-{
- struct vb2_dma_sg_buf *buf;
- int i;
-
- buf = kzalloc(sizeof *buf, GFP_KERNEL);
- if (!buf)
- return NULL;
-
- buf->vaddr = NULL;
- buf->write = 0;
- buf->offset = 0;
- buf->sg_desc.size = size;
- buf->sg_desc.num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
- buf->sg_desc.sglist = vzalloc(buf->sg_desc.num_pages *
- sizeof(*buf->sg_desc.sglist));
- if (!buf->sg_desc.sglist)
- goto fail_sglist_alloc;
- sg_init_table(buf->sg_desc.sglist, buf->sg_desc.num_pages);
-
- buf->pages = kzalloc(buf->sg_desc.num_pages * sizeof(struct page *),
- GFP_KERNEL);
- if (!buf->pages)
- goto fail_pages_array_alloc;
-
- for (i = 0; i < buf->sg_desc.num_pages; ++i) {
- buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN);
- if (NULL == buf->pages[i])
- goto fail_pages_alloc;
- sg_set_page(&buf->sg_desc.sglist[i],
- buf->pages[i], PAGE_SIZE, 0);
- }
-
- buf->handler.refcount = &buf->refcount;
- buf->handler.put = vb2_dma_sg_put;
- buf->handler.arg = buf;
-
- atomic_inc(&buf->refcount);
-
- printk(KERN_DEBUG "%s: Allocated buffer of %d pages\n",
- __func__, buf->sg_desc.num_pages);
- return buf;
-
-fail_pages_alloc:
- while (--i >= 0)
- __free_page(buf->pages[i]);
- kfree(buf->pages);
-
-fail_pages_array_alloc:
- vfree(buf->sg_desc.sglist);
-
-fail_sglist_alloc:
- kfree(buf);
- return NULL;
-}
-
-static void vb2_dma_sg_put(void *buf_priv)
-{
- struct vb2_dma_sg_buf *buf = buf_priv;
- int i = buf->sg_desc.num_pages;
-
- if (atomic_dec_and_test(&buf->refcount)) {
- printk(KERN_DEBUG "%s: Freeing buffer of %d pages\n", __func__,
- buf->sg_desc.num_pages);
- if (buf->vaddr)
- vm_unmap_ram(buf->vaddr, buf->sg_desc.num_pages);
- vfree(buf->sg_desc.sglist);
- while (--i >= 0)
- __free_page(buf->pages[i]);
- kfree(buf->pages);
- kfree(buf);
- }
-}
-
-static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr,
- unsigned long size, int write)
-{
- struct vb2_dma_sg_buf *buf;
- unsigned long first, last;
- int num_pages_from_user, i;
-
- buf = kzalloc(sizeof *buf, GFP_KERNEL);
- if (!buf)
- return NULL;
-
- buf->vaddr = NULL;
- buf->write = write;
- buf->offset = vaddr & ~PAGE_MASK;
- buf->sg_desc.size = size;
-
- first = (vaddr & PAGE_MASK) >> PAGE_SHIFT;
- last = ((vaddr + size - 1) & PAGE_MASK) >> PAGE_SHIFT;
- buf->sg_desc.num_pages = last - first + 1;
-
- buf->sg_desc.sglist = vzalloc(
- buf->sg_desc.num_pages * sizeof(*buf->sg_desc.sglist));
- if (!buf->sg_desc.sglist)
- goto userptr_fail_sglist_alloc;
-
- sg_init_table(buf->sg_desc.sglist, buf->sg_desc.num_pages);
-
- buf->pages = kzalloc(buf->sg_desc.num_pages * sizeof(struct page *),
- GFP_KERNEL);
- if (!buf->pages)
- goto userptr_fail_pages_array_alloc;
-
- num_pages_from_user = get_user_pages(current, current->mm,
- vaddr & PAGE_MASK,
- buf->sg_desc.num_pages,
- write,
- 1, /* force */
- buf->pages,
- NULL);
-
- if (num_pages_from_user != buf->sg_desc.num_pages)
- goto userptr_fail_get_user_pages;
-
- sg_set_page(&buf->sg_desc.sglist[0], buf->pages[0],
- PAGE_SIZE - buf->offset, buf->offset);
- size -= PAGE_SIZE - buf->offset;
- for (i = 1; i < buf->sg_desc.num_pages; ++i) {
- sg_set_page(&buf->sg_desc.sglist[i], buf->pages[i],
- min_t(size_t, PAGE_SIZE, size), 0);
- size -= min_t(size_t, PAGE_SIZE, size);
- }
- return buf;
-
-userptr_fail_get_user_pages:
- printk(KERN_DEBUG "get_user_pages requested/got: %d/%d]\n",
- num_pages_from_user, buf->sg_desc.num_pages);
- while (--num_pages_from_user >= 0)
- put_page(buf->pages[num_pages_from_user]);
- kfree(buf->pages);
-
-userptr_fail_pages_array_alloc:
- vfree(buf->sg_desc.sglist);
-
-userptr_fail_sglist_alloc:
- kfree(buf);
- return NULL;
-}
-
-/*
- * @put_userptr: inform the allocator that a USERPTR buffer will no longer
- * be used
- */
-static void vb2_dma_sg_put_userptr(void *buf_priv)
-{
- struct vb2_dma_sg_buf *buf = buf_priv;
- int i = buf->sg_desc.num_pages;
-
- printk(KERN_DEBUG "%s: Releasing userspace buffer of %d pages\n",
- __func__, buf->sg_desc.num_pages);
- if (buf->vaddr)
- vm_unmap_ram(buf->vaddr, buf->sg_desc.num_pages);
- while (--i >= 0) {
- if (buf->write)
- set_page_dirty_lock(buf->pages[i]);
- put_page(buf->pages[i]);
- }
- vfree(buf->sg_desc.sglist);
- kfree(buf->pages);
- kfree(buf);
-}
-
-static void *vb2_dma_sg_vaddr(void *buf_priv)
-{
- struct vb2_dma_sg_buf *buf = buf_priv;
-
- BUG_ON(!buf);
-
- if (!buf->vaddr)
- buf->vaddr = vm_map_ram(buf->pages,
- buf->sg_desc.num_pages,
- -1,
- PAGE_KERNEL);
-
- /* add offset in case userptr is not page-aligned */
- return buf->vaddr + buf->offset;
-}
-
-static unsigned int vb2_dma_sg_num_users(void *buf_priv)
-{
- struct vb2_dma_sg_buf *buf = buf_priv;
-
- return atomic_read(&buf->refcount);
-}
-
-static int vb2_dma_sg_mmap(void *buf_priv, struct vm_area_struct *vma)
-{
- struct vb2_dma_sg_buf *buf = buf_priv;
- unsigned long uaddr = vma->vm_start;
- unsigned long usize = vma->vm_end - vma->vm_start;
- int i = 0;
-
- if (!buf) {
- printk(KERN_ERR "No memory to map\n");
- return -EINVAL;
- }
-
- do {
- int ret;
-
- ret = vm_insert_page(vma, uaddr, buf->pages[i++]);
- if (ret) {
- printk(KERN_ERR "Remapping memory, error: %d\n", ret);
- return ret;
- }
-
- uaddr += PAGE_SIZE;
- usize -= PAGE_SIZE;
- } while (usize > 0);
-
-
- /*
- * Use common vm_area operations to track buffer refcount.
- */
- vma->vm_private_data = &buf->handler;
- vma->vm_ops = &vb2_common_vm_ops;
-
- vma->vm_ops->open(vma);
-
- return 0;
-}
-
-static void *vb2_dma_sg_cookie(void *buf_priv)
-{
- struct vb2_dma_sg_buf *buf = buf_priv;
-
- return &buf->sg_desc;
-}
-
-const struct vb2_mem_ops vb2_dma_sg_memops = {
- .alloc = vb2_dma_sg_alloc,
- .put = vb2_dma_sg_put,
- .get_userptr = vb2_dma_sg_get_userptr,
- .put_userptr = vb2_dma_sg_put_userptr,
- .vaddr = vb2_dma_sg_vaddr,
- .mmap = vb2_dma_sg_mmap,
- .num_users = vb2_dma_sg_num_users,
- .cookie = vb2_dma_sg_cookie,
-};
-EXPORT_SYMBOL_GPL(vb2_dma_sg_memops);
-
-MODULE_DESCRIPTION("dma scatter/gather memory handling routines for videobuf2");
-MODULE_AUTHOR("Andrzej Pietrasiewicz");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videobuf2-memops.c b/drivers/media/video/videobuf2-memops.c
deleted file mode 100644
index 504cd4cbe29..00000000000
--- a/drivers/media/video/videobuf2-memops.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * videobuf2-memops.c - generic memory handling routines for videobuf2
- *
- * Copyright (C) 2010 Samsung Electronics
- *
- * Author: Pawel Osciak <pawel@osciak.com>
- * Marek Szyprowski <m.szyprowski@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- */
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <linux/vmalloc.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/file.h>
-
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-memops.h>
-
-/**
- * vb2_get_vma() - acquire and lock the virtual memory area
- * @vma: given virtual memory area
- *
- * This function attempts to acquire an area mapped in the userspace for
- * the duration of a hardware operation. The area is "locked" by performing
- * the same set of operation that are done when process calls fork() and
- * memory areas are duplicated.
- *
- * Returns a copy of a virtual memory region on success or NULL.
- */
-struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma)
-{
- struct vm_area_struct *vma_copy;
-
- vma_copy = kmalloc(sizeof(*vma_copy), GFP_KERNEL);
- if (vma_copy == NULL)
- return NULL;
-
- if (vma->vm_ops && vma->vm_ops->open)
- vma->vm_ops->open(vma);
-
- if (vma->vm_file)
- get_file(vma->vm_file);
-
- memcpy(vma_copy, vma, sizeof(*vma));
-
- vma_copy->vm_mm = NULL;
- vma_copy->vm_next = NULL;
- vma_copy->vm_prev = NULL;
-
- return vma_copy;
-}
-EXPORT_SYMBOL_GPL(vb2_get_vma);
-
-/**
- * vb2_put_userptr() - release a userspace virtual memory area
- * @vma: virtual memory region associated with the area to be released
- *
- * This function releases the previously acquired memory area after a hardware
- * operation.
- */
-void vb2_put_vma(struct vm_area_struct *vma)
-{
- if (!vma)
- return;
-
- if (vma->vm_ops && vma->vm_ops->close)
- vma->vm_ops->close(vma);
-
- if (vma->vm_file)
- fput(vma->vm_file);
-
- kfree(vma);
-}
-EXPORT_SYMBOL_GPL(vb2_put_vma);
-
-/**
- * vb2_get_contig_userptr() - lock physically contiguous userspace mapped memory
- * @vaddr: starting virtual address of the area to be verified
- * @size: size of the area
- * @res_paddr: will return physical address for the given vaddr
- * @res_vma: will return locked copy of struct vm_area for the given area
- *
- * This function will go through memory area of size @size mapped at @vaddr and
- * verify that the underlying physical pages are contiguous. If they are
- * contiguous the virtual memory area is locked and a @res_vma is filled with
- * the copy and @res_pa set to the physical address of the buffer.
- *
- * Returns 0 on success.
- */
-int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size,
- struct vm_area_struct **res_vma, dma_addr_t *res_pa)
-{
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
- unsigned long offset, start, end;
- unsigned long this_pfn, prev_pfn;
- dma_addr_t pa = 0;
-
- start = vaddr;
- offset = start & ~PAGE_MASK;
- end = start + size;
-
- vma = find_vma(mm, start);
-
- if (vma == NULL || vma->vm_end < end)
- return -EFAULT;
-
- for (prev_pfn = 0; start < end; start += PAGE_SIZE) {
- int ret = follow_pfn(vma, start, &this_pfn);
- if (ret)
- return ret;
-
- if (prev_pfn == 0)
- pa = this_pfn << PAGE_SHIFT;
- else if (this_pfn != prev_pfn + 1)
- return -EFAULT;
-
- prev_pfn = this_pfn;
- }
-
- /*
- * Memory is contigous, lock vma and return to the caller
- */
- *res_vma = vb2_get_vma(vma);
- if (*res_vma == NULL)
- return -ENOMEM;
-
- *res_pa = pa + offset;
- return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_get_contig_userptr);
-
-/**
- * vb2_mmap_pfn_range() - map physical pages to userspace
- * @vma: virtual memory region for the mapping
- * @paddr: starting physical address of the memory to be mapped
- * @size: size of the memory to be mapped
- * @vm_ops: vm operations to be assigned to the created area
- * @priv: private data to be associated with the area
- *
- * Returns 0 on success.
- */
-int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
- unsigned long size,
- const struct vm_operations_struct *vm_ops,
- void *priv)
-{
- int ret;
-
- size = min_t(unsigned long, vma->vm_end - vma->vm_start, size);
-
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- ret = remap_pfn_range(vma, vma->vm_start, paddr >> PAGE_SHIFT,
- size, vma->vm_page_prot);
- if (ret) {
- printk(KERN_ERR "Remapping memory failed, error: %d\n", ret);
- return ret;
- }
-
- vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
- vma->vm_private_data = priv;
- vma->vm_ops = vm_ops;
-
- vma->vm_ops->open(vma);
-
- pr_debug("%s: mapped paddr 0x%08lx at 0x%08lx, size %ld\n",
- __func__, paddr, vma->vm_start, size);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_mmap_pfn_range);
-
-/**
- * vb2_common_vm_open() - increase refcount of the vma
- * @vma: virtual memory region for the mapping
- *
- * This function adds another user to the provided vma. It expects
- * struct vb2_vmarea_handler pointer in vma->vm_private_data.
- */
-static void vb2_common_vm_open(struct vm_area_struct *vma)
-{
- struct vb2_vmarea_handler *h = vma->vm_private_data;
-
- pr_debug("%s: %p, refcount: %d, vma: %08lx-%08lx\n",
- __func__, h, atomic_read(h->refcount), vma->vm_start,
- vma->vm_end);
-
- atomic_inc(h->refcount);
-}
-
-/**
- * vb2_common_vm_close() - decrease refcount of the vma
- * @vma: virtual memory region for the mapping
- *
- * This function releases the user from the provided vma. It expects
- * struct vb2_vmarea_handler pointer in vma->vm_private_data.
- */
-static void vb2_common_vm_close(struct vm_area_struct *vma)
-{
- struct vb2_vmarea_handler *h = vma->vm_private_data;
-
- pr_debug("%s: %p, refcount: %d, vma: %08lx-%08lx\n",
- __func__, h, atomic_read(h->refcount), vma->vm_start,
- vma->vm_end);
-
- h->put(h->arg);
-}
-
-/**
- * vb2_common_vm_ops - common vm_ops used for tracking refcount of mmaped
- * video buffers
- */
-const struct vm_operations_struct vb2_common_vm_ops = {
- .open = vb2_common_vm_open,
- .close = vb2_common_vm_close,
-};
-EXPORT_SYMBOL_GPL(vb2_common_vm_ops);
-
-MODULE_DESCRIPTION("common memory handling routines for videobuf2");
-MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videobuf2-vmalloc.c b/drivers/media/video/videobuf2-vmalloc.c
deleted file mode 100644
index 6b5ca6c70a4..00000000000
--- a/drivers/media/video/videobuf2-vmalloc.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * videobuf2-vmalloc.c - vmalloc memory allocator for videobuf2
- *
- * Copyright (C) 2010 Samsung Electronics
- *
- * Author: Pawel Osciak <pawel@osciak.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- */
-
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-memops.h>
-
-struct vb2_vmalloc_buf {
- void *vaddr;
- struct page **pages;
- struct vm_area_struct *vma;
- int write;
- unsigned long size;
- unsigned int n_pages;
- atomic_t refcount;
- struct vb2_vmarea_handler handler;
-};
-
-static void vb2_vmalloc_put(void *buf_priv);
-
-static void *vb2_vmalloc_alloc(void *alloc_ctx, unsigned long size)
-{
- struct vb2_vmalloc_buf *buf;
-
- buf = kzalloc(sizeof(*buf), GFP_KERNEL);
- if (!buf)
- return NULL;
-
- buf->size = size;
- buf->vaddr = vmalloc_user(buf->size);
- buf->handler.refcount = &buf->refcount;
- buf->handler.put = vb2_vmalloc_put;
- buf->handler.arg = buf;
-
- if (!buf->vaddr) {
- pr_debug("vmalloc of size %ld failed\n", buf->size);
- kfree(buf);
- return NULL;
- }
-
- atomic_inc(&buf->refcount);
- return buf;
-}
-
-static void vb2_vmalloc_put(void *buf_priv)
-{
- struct vb2_vmalloc_buf *buf = buf_priv;
-
- if (atomic_dec_and_test(&buf->refcount)) {
- vfree(buf->vaddr);
- kfree(buf);
- }
-}
-
-static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr,
- unsigned long size, int write)
-{
- struct vb2_vmalloc_buf *buf;
- unsigned long first, last;
- int n_pages, offset;
- struct vm_area_struct *vma;
- dma_addr_t physp;
-
- buf = kzalloc(sizeof(*buf), GFP_KERNEL);
- if (!buf)
- return NULL;
-
- buf->write = write;
- offset = vaddr & ~PAGE_MASK;
- buf->size = size;
-
-
- vma = find_vma(current->mm, vaddr);
- if (vma && (vma->vm_flags & VM_PFNMAP) && (vma->vm_pgoff)) {
- if (vb2_get_contig_userptr(vaddr, size, &vma, &physp))
- goto fail_pages_array_alloc;
- buf->vma = vma;
- buf->vaddr = ioremap_nocache(physp, size);
- if (!buf->vaddr)
- goto fail_pages_array_alloc;
- } else {
- first = vaddr >> PAGE_SHIFT;
- last = (vaddr + size - 1) >> PAGE_SHIFT;
- buf->n_pages = last - first + 1;
- buf->pages = kzalloc(buf->n_pages * sizeof(struct page *),
- GFP_KERNEL);
- if (!buf->pages)
- goto fail_pages_array_alloc;
-
- /* current->mm->mmap_sem is taken by videobuf2 core */
- n_pages = get_user_pages(current, current->mm,
- vaddr & PAGE_MASK, buf->n_pages,
- write, 1, /* force */
- buf->pages, NULL);
- if (n_pages != buf->n_pages)
- goto fail_get_user_pages;
-
- buf->vaddr = vm_map_ram(buf->pages, buf->n_pages, -1,
- PAGE_KERNEL);
- if (!buf->vaddr)
- goto fail_get_user_pages;
- }
-
- buf->vaddr += offset;
- return buf;
-
-fail_get_user_pages:
- pr_debug("get_user_pages requested/got: %d/%d]\n", n_pages,
- buf->n_pages);
- while (--n_pages >= 0)
- put_page(buf->pages[n_pages]);
- kfree(buf->pages);
-
-fail_pages_array_alloc:
- kfree(buf);
-
- return NULL;
-}
-
-static void vb2_vmalloc_put_userptr(void *buf_priv)
-{
- struct vb2_vmalloc_buf *buf = buf_priv;
- unsigned long vaddr = (unsigned long)buf->vaddr & PAGE_MASK;
- unsigned int i;
-
- if (buf->pages) {
- if (vaddr)
- vm_unmap_ram((void *)vaddr, buf->n_pages);
- for (i = 0; i < buf->n_pages; ++i) {
- if (buf->write)
- set_page_dirty_lock(buf->pages[i]);
- put_page(buf->pages[i]);
- }
- kfree(buf->pages);
- } else {
- if (buf->vma)
- vb2_put_vma(buf->vma);
- iounmap(buf->vaddr);
- }
- kfree(buf);
-}
-
-static void *vb2_vmalloc_vaddr(void *buf_priv)
-{
- struct vb2_vmalloc_buf *buf = buf_priv;
-
- if (!buf->vaddr) {
- pr_err("Address of an unallocated plane requested "
- "or cannot map user pointer\n");
- return NULL;
- }
-
- return buf->vaddr;
-}
-
-static unsigned int vb2_vmalloc_num_users(void *buf_priv)
-{
- struct vb2_vmalloc_buf *buf = buf_priv;
- return atomic_read(&buf->refcount);
-}
-
-static int vb2_vmalloc_mmap(void *buf_priv, struct vm_area_struct *vma)
-{
- struct vb2_vmalloc_buf *buf = buf_priv;
- int ret;
-
- if (!buf) {
- pr_err("No memory to map\n");
- return -EINVAL;
- }
-
- ret = remap_vmalloc_range(vma, buf->vaddr, 0);
- if (ret) {
- pr_err("Remapping vmalloc memory, error: %d\n", ret);
- return ret;
- }
-
- /*
- * Make sure that vm_areas for 2 buffers won't be merged together
- */
- vma->vm_flags |= VM_DONTEXPAND;
-
- /*
- * Use common vm_area operations to track buffer refcount.
- */
- vma->vm_private_data = &buf->handler;
- vma->vm_ops = &vb2_common_vm_ops;
-
- vma->vm_ops->open(vma);
-
- return 0;
-}
-
-const struct vb2_mem_ops vb2_vmalloc_memops = {
- .alloc = vb2_vmalloc_alloc,
- .put = vb2_vmalloc_put,
- .get_userptr = vb2_vmalloc_get_userptr,
- .put_userptr = vb2_vmalloc_put_userptr,
- .vaddr = vb2_vmalloc_vaddr,
- .mmap = vb2_vmalloc_mmap,
- .num_users = vb2_vmalloc_num_users,
-};
-EXPORT_SYMBOL_GPL(vb2_vmalloc_memops);
-
-MODULE_DESCRIPTION("vmalloc memory handling routines for videobuf2");
-MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
deleted file mode 100644
index aae1720b2f2..00000000000
--- a/drivers/media/video/vino.c
+++ /dev/null
@@ -1,4349 +0,0 @@
-/*
- * Driver for the VINO (Video In No Out) system found in SGI Indys.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
- *
- * Based on the previous version of the driver for 2.4 kernels by:
- * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
- *
- * v4l2_device/v4l2_subdev conversion by:
- * Copyright (C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * Note: this conversion is untested! Please contact the linux-media
- * mailinglist if you can test this, together with the test results.
- */
-
-/*
- * TODO:
- * - remove "mark pages reserved-hacks" from memory allocation code
- * and implement fault()
- * - check decimation, calculating and reporting image size when
- * using decimation
- * - implement read(), user mode buffers and overlay (?)
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/time.h>
-#include <linux/kmod.h>
-
-#include <linux/i2c.h>
-
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <linux/mutex.h>
-
-#include <asm/paccess.h>
-#include <asm/io.h>
-#include <asm/sgi/ip22.h>
-#include <asm/sgi/mc.h>
-
-#include "vino.h"
-#include "saa7191.h"
-#include "indycam.h"
-
-/* Uncomment the following line to get lots and lots of (mostly useless)
- * debug info.
- * Note that the debug output also slows down the driver significantly */
-// #define VINO_DEBUG
-// #define VINO_DEBUG_INT
-
-#define VINO_MODULE_VERSION "0.0.7"
-
-MODULE_DESCRIPTION("SGI VINO Video4Linux2 driver");
-MODULE_VERSION(VINO_MODULE_VERSION);
-MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
-MODULE_LICENSE("GPL");
-
-#ifdef VINO_DEBUG
-#define dprintk(x...) printk("VINO: " x);
-#else
-#define dprintk(x...)
-#endif
-
-#define VINO_NO_CHANNEL 0
-#define VINO_CHANNEL_A 1
-#define VINO_CHANNEL_B 2
-
-#define VINO_PAL_WIDTH 768
-#define VINO_PAL_HEIGHT 576
-#define VINO_NTSC_WIDTH 640
-#define VINO_NTSC_HEIGHT 480
-
-#define VINO_MIN_WIDTH 32
-#define VINO_MIN_HEIGHT 32
-
-#define VINO_CLIPPING_START_ODD_D1 1
-#define VINO_CLIPPING_START_ODD_PAL 15
-#define VINO_CLIPPING_START_ODD_NTSC 12
-
-#define VINO_CLIPPING_START_EVEN_D1 2
-#define VINO_CLIPPING_START_EVEN_PAL 15
-#define VINO_CLIPPING_START_EVEN_NTSC 12
-
-#define VINO_INPUT_CHANNEL_COUNT 3
-
-/* the number is the index for vino_inputs */
-#define VINO_INPUT_NONE -1
-#define VINO_INPUT_COMPOSITE 0
-#define VINO_INPUT_SVIDEO 1
-#define VINO_INPUT_D1 2
-
-#define VINO_PAGE_RATIO (PAGE_SIZE / VINO_PAGE_SIZE)
-
-#define VINO_FIFO_THRESHOLD_DEFAULT 16
-
-#define VINO_FRAMEBUFFER_SIZE ((VINO_PAL_WIDTH \
- * VINO_PAL_HEIGHT * 4 \
- + 3 * PAGE_SIZE) & ~(PAGE_SIZE - 1))
-
-#define VINO_FRAMEBUFFER_COUNT_MAX 8
-
-#define VINO_FRAMEBUFFER_UNUSED 0
-#define VINO_FRAMEBUFFER_IN_USE 1
-#define VINO_FRAMEBUFFER_READY 2
-
-#define VINO_QUEUE_ERROR -1
-#define VINO_QUEUE_MAGIC 0x20050125
-
-#define VINO_MEMORY_NONE 0
-#define VINO_MEMORY_MMAP 1
-#define VINO_MEMORY_USERPTR 2
-
-#define VINO_DUMMY_DESC_COUNT 4
-#define VINO_DESC_FETCH_DELAY 5 /* microseconds */
-
-#define VINO_MAX_FRAME_SKIP_COUNT 128
-
-/* the number is the index for vino_data_formats */
-#define VINO_DATA_FMT_NONE -1
-#define VINO_DATA_FMT_GREY 0
-#define VINO_DATA_FMT_RGB332 1
-#define VINO_DATA_FMT_RGB32 2
-#define VINO_DATA_FMT_YUV 3
-
-#define VINO_DATA_FMT_COUNT 4
-
-/* the number is the index for vino_data_norms */
-#define VINO_DATA_NORM_NONE -1
-#define VINO_DATA_NORM_NTSC 0
-#define VINO_DATA_NORM_PAL 1
-#define VINO_DATA_NORM_SECAM 2
-#define VINO_DATA_NORM_D1 3
-
-#define VINO_DATA_NORM_COUNT 4
-
-/* I2C controller flags */
-#define SGI_I2C_FORCE_IDLE (0 << 0)
-#define SGI_I2C_NOT_IDLE (1 << 0)
-#define SGI_I2C_WRITE (0 << 1)
-#define SGI_I2C_READ (1 << 1)
-#define SGI_I2C_RELEASE_BUS (0 << 2)
-#define SGI_I2C_HOLD_BUS (1 << 2)
-#define SGI_I2C_XFER_DONE (0 << 4)
-#define SGI_I2C_XFER_BUSY (1 << 4)
-#define SGI_I2C_ACK (0 << 5)
-#define SGI_I2C_NACK (1 << 5)
-#define SGI_I2C_BUS_OK (0 << 7)
-#define SGI_I2C_BUS_ERR (1 << 7)
-
-/* Internal data structure definitions */
-
-struct vino_input {
- char *name;
- v4l2_std_id std;
-};
-
-struct vino_clipping {
- unsigned int left, right, top, bottom;
-};
-
-struct vino_data_format {
- /* the description */
- char *description;
- /* bytes per pixel */
- unsigned int bpp;
- /* V4L2 fourcc code */
- __u32 pixelformat;
- /* V4L2 colorspace (duh!) */
- enum v4l2_colorspace colorspace;
-};
-
-struct vino_data_norm {
- char *description;
- unsigned int width, height;
- struct vino_clipping odd;
- struct vino_clipping even;
-
- v4l2_std_id std;
- unsigned int fps_min, fps_max;
- __u32 framelines;
-};
-
-struct vino_descriptor_table {
- /* the number of PAGE_SIZE sized pages in the buffer */
- unsigned int page_count;
- /* virtual (kmalloc'd) pointers to the actual data
- * (in PAGE_SIZE chunks, used with mmap streaming) */
- unsigned long *virtual;
-
- /* cpu address for the VINO descriptor table
- * (contains DMA addresses, VINO_PAGE_SIZE chunks) */
- unsigned long *dma_cpu;
- /* dma address for the VINO descriptor table
- * (contains DMA addresses, VINO_PAGE_SIZE chunks) */
- dma_addr_t dma;
-};
-
-struct vino_framebuffer {
- /* identifier nubmer */
- unsigned int id;
- /* the length of the whole buffer */
- unsigned int size;
- /* the length of actual data in buffer */
- unsigned int data_size;
- /* the data format */
- unsigned int data_format;
- /* the state of buffer data */
- unsigned int state;
- /* is the buffer mapped in user space? */
- unsigned int map_count;
- /* memory offset for mmap() */
- unsigned int offset;
- /* frame counter */
- unsigned int frame_counter;
- /* timestamp (written when image capture finishes) */
- struct timeval timestamp;
-
- struct vino_descriptor_table desc_table;
-
- spinlock_t state_lock;
-};
-
-struct vino_framebuffer_fifo {
- unsigned int length;
-
- unsigned int used;
- unsigned int head;
- unsigned int tail;
-
- unsigned int data[VINO_FRAMEBUFFER_COUNT_MAX];
-};
-
-struct vino_framebuffer_queue {
- unsigned int magic;
-
- /* VINO_MEMORY_NONE, VINO_MEMORY_MMAP or VINO_MEMORY_USERPTR */
- unsigned int type;
- unsigned int length;
-
- /* data field of in and out contain index numbers for buffer */
- struct vino_framebuffer_fifo in;
- struct vino_framebuffer_fifo out;
-
- struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_COUNT_MAX];
-
- spinlock_t queue_lock;
- struct mutex queue_mutex;
- wait_queue_head_t frame_wait_queue;
-};
-
-struct vino_interrupt_data {
- struct timeval timestamp;
- unsigned int frame_counter;
- unsigned int skip_count;
- unsigned int skip;
-};
-
-struct vino_channel_settings {
- unsigned int channel;
-
- int input;
- unsigned int data_format;
- unsigned int data_norm;
- struct vino_clipping clipping;
- unsigned int decimation;
- unsigned int line_size;
- unsigned int alpha;
- unsigned int fps;
- unsigned int framert_reg;
-
- unsigned int fifo_threshold;
-
- struct vino_framebuffer_queue fb_queue;
-
- /* number of the current field */
- unsigned int field;
-
- /* read in progress */
- int reading;
- /* streaming is active */
- int streaming;
- /* the driver is currently processing the queue */
- int capturing;
-
- struct mutex mutex;
- spinlock_t capture_lock;
-
- unsigned int users;
-
- struct vino_interrupt_data int_data;
-
- /* V4L support */
- struct video_device *vdev;
-};
-
-struct vino_settings {
- struct v4l2_device v4l2_dev;
- struct vino_channel_settings a;
- struct vino_channel_settings b;
-
- /* the channel which owns this client:
- * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
- unsigned int decoder_owner;
- struct v4l2_subdev *decoder;
- unsigned int camera_owner;
- struct v4l2_subdev *camera;
-
- /* a lock for vino register access */
- spinlock_t vino_lock;
- /* a lock for channel input changes */
- spinlock_t input_lock;
-
- unsigned long dummy_page;
- struct vino_descriptor_table dummy_desc_table;
-};
-
-/* Module parameters */
-
-/*
- * Using vino_pixel_conversion the ABGR32-format pixels supplied
- * by the VINO chip can be converted to more common formats
- * like RGBA32 (or probably RGB24 in the future). This way we
- * can give out data that can be specified correctly with
- * the V4L2-definitions.
- *
- * The pixel format is specified as RGBA32 when no conversion
- * is used.
- *
- * Note that this only affects the 32-bit bit depth.
- *
- * Use non-zero value to enable conversion.
- */
-static int vino_pixel_conversion;
-
-module_param_named(pixelconv, vino_pixel_conversion, int, 0);
-
-MODULE_PARM_DESC(pixelconv,
- "enable pixel conversion (non-zero value enables)");
-
-/* Internal data structures */
-
-static struct sgi_vino *vino;
-
-static struct vino_settings *vino_drvdata;
-
-#define camera_call(o, f, args...) \
- v4l2_subdev_call(vino_drvdata->camera, o, f, ##args)
-#define decoder_call(o, f, args...) \
- v4l2_subdev_call(vino_drvdata->decoder, o, f, ##args)
-
-static const char *vino_driver_name = "vino";
-static const char *vino_driver_description = "SGI VINO";
-static const char *vino_bus_name = "GIO64 bus";
-static const char *vino_vdev_name_a = "SGI VINO Channel A";
-static const char *vino_vdev_name_b = "SGI VINO Channel B";
-
-static void vino_capture_tasklet(unsigned long channel);
-
-DECLARE_TASKLET(vino_tasklet_a, vino_capture_tasklet, VINO_CHANNEL_A);
-DECLARE_TASKLET(vino_tasklet_b, vino_capture_tasklet, VINO_CHANNEL_B);
-
-static const struct vino_input vino_inputs[] = {
- {
- .name = "Composite",
- .std = V4L2_STD_NTSC | V4L2_STD_PAL
- | V4L2_STD_SECAM,
- }, {
- .name = "S-Video",
- .std = V4L2_STD_NTSC | V4L2_STD_PAL
- | V4L2_STD_SECAM,
- }, {
- .name = "D1/IndyCam",
- .std = V4L2_STD_NTSC,
- }
-};
-
-static const struct vino_data_format vino_data_formats[] = {
- {
- .description = "8-bit greyscale",
- .bpp = 1,
- .pixelformat = V4L2_PIX_FMT_GREY,
- .colorspace = V4L2_COLORSPACE_SMPTE170M,
- }, {
- .description = "8-bit dithered RGB 3-3-2",
- .bpp = 1,
- .pixelformat = V4L2_PIX_FMT_RGB332,
- .colorspace = V4L2_COLORSPACE_SRGB,
- }, {
- .description = "32-bit RGB",
- .bpp = 4,
- .pixelformat = V4L2_PIX_FMT_RGB32,
- .colorspace = V4L2_COLORSPACE_SRGB,
- }, {
- .description = "YUV 4:2:2",
- .bpp = 2,
- .pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped?
- .colorspace = V4L2_COLORSPACE_SMPTE170M,
- }
-};
-
-static const struct vino_data_norm vino_data_norms[] = {
- {
- .description = "NTSC",
- .std = V4L2_STD_NTSC,
- .fps_min = 6,
- .fps_max = 30,
- .framelines = 525,
- .width = VINO_NTSC_WIDTH,
- .height = VINO_NTSC_HEIGHT,
- .odd = {
- .top = VINO_CLIPPING_START_ODD_NTSC,
- .left = 0,
- .bottom = VINO_CLIPPING_START_ODD_NTSC
- + VINO_NTSC_HEIGHT / 2 - 1,
- .right = VINO_NTSC_WIDTH,
- },
- .even = {
- .top = VINO_CLIPPING_START_EVEN_NTSC,
- .left = 0,
- .bottom = VINO_CLIPPING_START_EVEN_NTSC
- + VINO_NTSC_HEIGHT / 2 - 1,
- .right = VINO_NTSC_WIDTH,
- },
- }, {
- .description = "PAL",
- .std = V4L2_STD_PAL,
- .fps_min = 5,
- .fps_max = 25,
- .framelines = 625,
- .width = VINO_PAL_WIDTH,
- .height = VINO_PAL_HEIGHT,
- .odd = {
- .top = VINO_CLIPPING_START_ODD_PAL,
- .left = 0,
- .bottom = VINO_CLIPPING_START_ODD_PAL
- + VINO_PAL_HEIGHT / 2 - 1,
- .right = VINO_PAL_WIDTH,
- },
- .even = {
- .top = VINO_CLIPPING_START_EVEN_PAL,
- .left = 0,
- .bottom = VINO_CLIPPING_START_EVEN_PAL
- + VINO_PAL_HEIGHT / 2 - 1,
- .right = VINO_PAL_WIDTH,
- },
- }, {
- .description = "SECAM",
- .std = V4L2_STD_SECAM,
- .fps_min = 5,
- .fps_max = 25,
- .framelines = 625,
- .width = VINO_PAL_WIDTH,
- .height = VINO_PAL_HEIGHT,
- .odd = {
- .top = VINO_CLIPPING_START_ODD_PAL,
- .left = 0,
- .bottom = VINO_CLIPPING_START_ODD_PAL
- + VINO_PAL_HEIGHT / 2 - 1,
- .right = VINO_PAL_WIDTH,
- },
- .even = {
- .top = VINO_CLIPPING_START_EVEN_PAL,
- .left = 0,
- .bottom = VINO_CLIPPING_START_EVEN_PAL
- + VINO_PAL_HEIGHT / 2 - 1,
- .right = VINO_PAL_WIDTH,
- },
- }, {
- .description = "NTSC/D1",
- .std = V4L2_STD_NTSC,
- .fps_min = 6,
- .fps_max = 30,
- .framelines = 525,
- .width = VINO_NTSC_WIDTH,
- .height = VINO_NTSC_HEIGHT,
- .odd = {
- .top = VINO_CLIPPING_START_ODD_D1,
- .left = 0,
- .bottom = VINO_CLIPPING_START_ODD_D1
- + VINO_NTSC_HEIGHT / 2 - 1,
- .right = VINO_NTSC_WIDTH,
- },
- .even = {
- .top = VINO_CLIPPING_START_EVEN_D1,
- .left = 0,
- .bottom = VINO_CLIPPING_START_EVEN_D1
- + VINO_NTSC_HEIGHT / 2 - 1,
- .right = VINO_NTSC_WIDTH,
- },
- }
-};
-
-#define VINO_INDYCAM_V4L2_CONTROL_COUNT 9
-
-struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
- {
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Automatic Gain Control",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = INDYCAM_AGC_DEFAULT,
- }, {
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Automatic White Balance",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = INDYCAM_AWB_DEFAULT,
- }, {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain",
- .minimum = INDYCAM_GAIN_MIN,
- .maximum = INDYCAM_GAIN_MAX,
- .step = 1,
- .default_value = INDYCAM_GAIN_DEFAULT,
- }, {
- .id = INDYCAM_CONTROL_RED_SATURATION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Red Saturation",
- .minimum = INDYCAM_RED_SATURATION_MIN,
- .maximum = INDYCAM_RED_SATURATION_MAX,
- .step = 1,
- .default_value = INDYCAM_RED_SATURATION_DEFAULT,
- }, {
- .id = INDYCAM_CONTROL_BLUE_SATURATION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Blue Saturation",
- .minimum = INDYCAM_BLUE_SATURATION_MIN,
- .maximum = INDYCAM_BLUE_SATURATION_MAX,
- .step = 1,
- .default_value = INDYCAM_BLUE_SATURATION_DEFAULT,
- }, {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Red Balance",
- .minimum = INDYCAM_RED_BALANCE_MIN,
- .maximum = INDYCAM_RED_BALANCE_MAX,
- .step = 1,
- .default_value = INDYCAM_RED_BALANCE_DEFAULT,
- }, {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Blue Balance",
- .minimum = INDYCAM_BLUE_BALANCE_MIN,
- .maximum = INDYCAM_BLUE_BALANCE_MAX,
- .step = 1,
- .default_value = INDYCAM_BLUE_BALANCE_DEFAULT,
- }, {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Shutter Control",
- .minimum = INDYCAM_SHUTTER_MIN,
- .maximum = INDYCAM_SHUTTER_MAX,
- .step = 1,
- .default_value = INDYCAM_SHUTTER_DEFAULT,
- }, {
- .id = V4L2_CID_GAMMA,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gamma",
- .minimum = INDYCAM_GAMMA_MIN,
- .maximum = INDYCAM_GAMMA_MAX,
- .step = 1,
- .default_value = INDYCAM_GAMMA_DEFAULT,
- }
-};
-
-#define VINO_SAA7191_V4L2_CONTROL_COUNT 9
-
-struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
- {
- .id = V4L2_CID_HUE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Hue",
- .minimum = SAA7191_HUE_MIN,
- .maximum = SAA7191_HUE_MAX,
- .step = 1,
- .default_value = SAA7191_HUE_DEFAULT,
- }, {
- .id = SAA7191_CONTROL_BANDPASS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Luminance Bandpass",
- .minimum = SAA7191_BANDPASS_MIN,
- .maximum = SAA7191_BANDPASS_MAX,
- .step = 1,
- .default_value = SAA7191_BANDPASS_DEFAULT,
- }, {
- .id = SAA7191_CONTROL_BANDPASS_WEIGHT,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Luminance Bandpass Weight",
- .minimum = SAA7191_BANDPASS_WEIGHT_MIN,
- .maximum = SAA7191_BANDPASS_WEIGHT_MAX,
- .step = 1,
- .default_value = SAA7191_BANDPASS_WEIGHT_DEFAULT,
- }, {
- .id = SAA7191_CONTROL_CORING,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "HF Luminance Coring",
- .minimum = SAA7191_CORING_MIN,
- .maximum = SAA7191_CORING_MAX,
- .step = 1,
- .default_value = SAA7191_CORING_DEFAULT,
- }, {
- .id = SAA7191_CONTROL_FORCE_COLOUR,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Force Colour",
- .minimum = SAA7191_FORCE_COLOUR_MIN,
- .maximum = SAA7191_FORCE_COLOUR_MAX,
- .step = 1,
- .default_value = SAA7191_FORCE_COLOUR_DEFAULT,
- }, {
- .id = SAA7191_CONTROL_CHROMA_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Chrominance Gain Control",
- .minimum = SAA7191_CHROMA_GAIN_MIN,
- .maximum = SAA7191_CHROMA_GAIN_MAX,
- .step = 1,
- .default_value = SAA7191_CHROMA_GAIN_DEFAULT,
- }, {
- .id = SAA7191_CONTROL_VTRC,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "VTR Time Constant",
- .minimum = SAA7191_VTRC_MIN,
- .maximum = SAA7191_VTRC_MAX,
- .step = 1,
- .default_value = SAA7191_VTRC_DEFAULT,
- }, {
- .id = SAA7191_CONTROL_LUMA_DELAY,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Luminance Delay Compensation",
- .minimum = SAA7191_LUMA_DELAY_MIN,
- .maximum = SAA7191_LUMA_DELAY_MAX,
- .step = 1,
- .default_value = SAA7191_LUMA_DELAY_DEFAULT,
- }, {
- .id = SAA7191_CONTROL_VNR,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Vertical Noise Reduction",
- .minimum = SAA7191_VNR_MIN,
- .maximum = SAA7191_VNR_MAX,
- .step = 1,
- .default_value = SAA7191_VNR_DEFAULT,
- }
-};
-
-/* VINO framebuffer/DMA descriptor management */
-
-static void vino_free_buffer_with_count(struct vino_framebuffer *fb,
- unsigned int count)
-{
- unsigned int i;
-
- dprintk("vino_free_buffer_with_count(): count = %d\n", count);
-
- for (i = 0; i < count; i++) {
- ClearPageReserved(virt_to_page((void *)fb->desc_table.virtual[i]));
- dma_unmap_single(NULL,
- fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
- PAGE_SIZE, DMA_FROM_DEVICE);
- free_page(fb->desc_table.virtual[i]);
- }
-
- dma_free_coherent(NULL,
- VINO_PAGE_RATIO * (fb->desc_table.page_count + 4) *
- sizeof(dma_addr_t), (void *)fb->desc_table.dma_cpu,
- fb->desc_table.dma);
- kfree(fb->desc_table.virtual);
-
- memset(fb, 0, sizeof(struct vino_framebuffer));
-}
-
-static void vino_free_buffer(struct vino_framebuffer *fb)
-{
- vino_free_buffer_with_count(fb, fb->desc_table.page_count);
-}
-
-static int vino_allocate_buffer(struct vino_framebuffer *fb,
- unsigned int size)
-{
- unsigned int count, i, j;
- int ret = 0;
-
- dprintk("vino_allocate_buffer():\n");
-
- if (size < 1)
- return -EINVAL;
-
- memset(fb, 0, sizeof(struct vino_framebuffer));
-
- count = ((size / PAGE_SIZE) + 4) & ~3;
-
- dprintk("vino_allocate_buffer(): size = %d, count = %d\n",
- size, count);
-
- /* allocate memory for table with virtual (page) addresses */
- fb->desc_table.virtual =
- kmalloc(count * sizeof(unsigned long), GFP_KERNEL);
- if (!fb->desc_table.virtual)
- return -ENOMEM;
-
- /* allocate memory for table with dma addresses
- * (has space for four extra descriptors) */
- fb->desc_table.dma_cpu =
- dma_alloc_coherent(NULL, VINO_PAGE_RATIO * (count + 4) *
- sizeof(dma_addr_t), &fb->desc_table.dma,
- GFP_KERNEL | GFP_DMA);
- if (!fb->desc_table.dma_cpu) {
- ret = -ENOMEM;
- goto out_free_virtual;
- }
-
- /* allocate pages for the buffer and acquire the according
- * dma addresses */
- for (i = 0; i < count; i++) {
- dma_addr_t dma_data_addr;
-
- fb->desc_table.virtual[i] =
- get_zeroed_page(GFP_KERNEL | GFP_DMA);
- if (!fb->desc_table.virtual[i]) {
- ret = -ENOBUFS;
- break;
- }
-
- dma_data_addr =
- dma_map_single(NULL,
- (void *)fb->desc_table.virtual[i],
- PAGE_SIZE, DMA_FROM_DEVICE);
-
- for (j = 0; j < VINO_PAGE_RATIO; j++) {
- fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i + j] =
- dma_data_addr + VINO_PAGE_SIZE * j;
- }
-
- SetPageReserved(virt_to_page((void *)fb->desc_table.virtual[i]));
- }
-
- /* page_count needs to be set anyway, because the descriptor table has
- * been allocated according to this number */
- fb->desc_table.page_count = count;
-
- if (ret) {
- /* the descriptor with index i doesn't contain
- * a valid address yet */
- vino_free_buffer_with_count(fb, i);
- return ret;
- }
-
- //fb->size = size;
- fb->size = count * PAGE_SIZE;
- fb->data_format = VINO_DATA_FMT_NONE;
-
- /* set the dma stop-bit for the last (count+1)th descriptor */
- fb->desc_table.dma_cpu[VINO_PAGE_RATIO * count] = VINO_DESC_STOP;
- return 0;
-
- out_free_virtual:
- kfree(fb->desc_table.virtual);
- return ret;
-}
-
-#if 0
-/* user buffers not fully implemented yet */
-static int vino_prepare_user_buffer(struct vino_framebuffer *fb,
- void *user,
- unsigned int size)
-{
- unsigned int count, i, j;
- int ret = 0;
-
- dprintk("vino_prepare_user_buffer():\n");
-
- if (size < 1)
- return -EINVAL;
-
- memset(fb, 0, sizeof(struct vino_framebuffer));
-
- count = ((size / PAGE_SIZE)) & ~3;
-
- dprintk("vino_prepare_user_buffer(): size = %d, count = %d\n",
- size, count);
-
- /* allocate memory for table with virtual (page) addresses */
- fb->desc_table.virtual = (unsigned long *)
- kmalloc(count * sizeof(unsigned long), GFP_KERNEL);
- if (!fb->desc_table.virtual)
- return -ENOMEM;
-
- /* allocate memory for table with dma addresses
- * (has space for four extra descriptors) */
- fb->desc_table.dma_cpu =
- dma_alloc_coherent(NULL, VINO_PAGE_RATIO * (count + 4) *
- sizeof(dma_addr_t), &fb->desc_table.dma,
- GFP_KERNEL | GFP_DMA);
- if (!fb->desc_table.dma_cpu) {
- ret = -ENOMEM;
- goto out_free_virtual;
- }
-
- /* allocate pages for the buffer and acquire the according
- * dma addresses */
- for (i = 0; i < count; i++) {
- dma_addr_t dma_data_addr;
-
- fb->desc_table.virtual[i] =
- get_zeroed_page(GFP_KERNEL | GFP_DMA);
- if (!fb->desc_table.virtual[i]) {
- ret = -ENOBUFS;
- break;
- }
-
- dma_data_addr =
- dma_map_single(NULL,
- (void *)fb->desc_table.virtual[i],
- PAGE_SIZE, DMA_FROM_DEVICE);
-
- for (j = 0; j < VINO_PAGE_RATIO; j++) {
- fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i + j] =
- dma_data_addr + VINO_PAGE_SIZE * j;
- }
-
- SetPageReserved(virt_to_page((void *)fb->desc_table.virtual[i]));
- }
-
- /* page_count needs to be set anyway, because the descriptor table has
- * been allocated according to this number */
- fb->desc_table.page_count = count;
-
- if (ret) {
- /* the descriptor with index i doesn't contain
- * a valid address yet */
- vino_free_buffer_with_count(fb, i);
- return ret;
- }
-
- //fb->size = size;
- fb->size = count * PAGE_SIZE;
-
- /* set the dma stop-bit for the last (count+1)th descriptor */
- fb->desc_table.dma_cpu[VINO_PAGE_RATIO * count] = VINO_DESC_STOP;
- return 0;
-
- out_free_virtual:
- kfree(fb->desc_table.virtual);
- return ret;
-}
-#endif
-
-static void vino_sync_buffer(struct vino_framebuffer *fb)
-{
- int i;
-
- dprintk("vino_sync_buffer():\n");
-
- for (i = 0; i < fb->desc_table.page_count; i++)
- dma_sync_single_for_cpu(NULL,
- fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
- PAGE_SIZE, DMA_FROM_DEVICE);
-}
-
-/* Framebuffer fifo functions (need to be locked externally) */
-
-static inline void vino_fifo_init(struct vino_framebuffer_fifo *f,
- unsigned int length)
-{
- f->length = 0;
- f->used = 0;
- f->head = 0;
- f->tail = 0;
-
- if (length > VINO_FRAMEBUFFER_COUNT_MAX)
- length = VINO_FRAMEBUFFER_COUNT_MAX;
-
- f->length = length;
-}
-
-/* returns true/false */
-static inline int vino_fifo_has_id(struct vino_framebuffer_fifo *f,
- unsigned int id)
-{
- unsigned int i;
-
- for (i = f->head; i == (f->tail - 1); i = (i + 1) % f->length) {
- if (f->data[i] == id)
- return 1;
- }
-
- return 0;
-}
-
-#if 0
-/* returns true/false */
-static inline int vino_fifo_full(struct vino_framebuffer_fifo *f)
-{
- return (f->used == f->length);
-}
-#endif
-
-static inline unsigned int vino_fifo_get_used(struct vino_framebuffer_fifo *f)
-{
- return f->used;
-}
-
-static int vino_fifo_enqueue(struct vino_framebuffer_fifo *f, unsigned int id)
-{
- if (id >= f->length) {
- return VINO_QUEUE_ERROR;
- }
-
- if (vino_fifo_has_id(f, id)) {
- return VINO_QUEUE_ERROR;
- }
-
- if (f->used < f->length) {
- f->data[f->tail] = id;
- f->tail = (f->tail + 1) % f->length;
- f->used++;
- } else {
- return VINO_QUEUE_ERROR;
- }
-
- return 0;
-}
-
-static int vino_fifo_peek(struct vino_framebuffer_fifo *f, unsigned int *id)
-{
- if (f->used > 0) {
- *id = f->data[f->head];
- } else {
- return VINO_QUEUE_ERROR;
- }
-
- return 0;
-}
-
-static int vino_fifo_dequeue(struct vino_framebuffer_fifo *f, unsigned int *id)
-{
- if (f->used > 0) {
- *id = f->data[f->head];
- f->head = (f->head + 1) % f->length;
- f->used--;
- } else {
- return VINO_QUEUE_ERROR;
- }
-
- return 0;
-}
-
-/* Framebuffer queue functions */
-
-/* execute with queue_lock locked */
-static void vino_queue_free_with_count(struct vino_framebuffer_queue *q,
- unsigned int length)
-{
- unsigned int i;
-
- q->length = 0;
- memset(&q->in, 0, sizeof(struct vino_framebuffer_fifo));
- memset(&q->out, 0, sizeof(struct vino_framebuffer_fifo));
- for (i = 0; i < length; i++) {
- dprintk("vino_queue_free_with_count(): freeing buffer %d\n",
- i);
- vino_free_buffer(q->buffer[i]);
- kfree(q->buffer[i]);
- }
-
- q->type = VINO_MEMORY_NONE;
- q->magic = 0;
-}
-
-static void vino_queue_free(struct vino_framebuffer_queue *q)
-{
- dprintk("vino_queue_free():\n");
-
- if (q->magic != VINO_QUEUE_MAGIC)
- return;
- if (q->type != VINO_MEMORY_MMAP)
- return;
-
- mutex_lock(&q->queue_mutex);
-
- vino_queue_free_with_count(q, q->length);
-
- mutex_unlock(&q->queue_mutex);
-}
-
-static int vino_queue_init(struct vino_framebuffer_queue *q,
- unsigned int *length)
-{
- unsigned int i;
- int ret = 0;
-
- dprintk("vino_queue_init(): length = %d\n", *length);
-
- if (q->magic == VINO_QUEUE_MAGIC) {
- dprintk("vino_queue_init(): queue already initialized!\n");
- return -EINVAL;
- }
-
- if (q->type != VINO_MEMORY_NONE) {
- dprintk("vino_queue_init(): queue already initialized!\n");
- return -EINVAL;
- }
-
- if (*length < 1)
- return -EINVAL;
-
- mutex_lock(&q->queue_mutex);
-
- if (*length > VINO_FRAMEBUFFER_COUNT_MAX)
- *length = VINO_FRAMEBUFFER_COUNT_MAX;
-
- q->length = 0;
-
- for (i = 0; i < *length; i++) {
- dprintk("vino_queue_init(): allocating buffer %d\n", i);
- q->buffer[i] = kmalloc(sizeof(struct vino_framebuffer),
- GFP_KERNEL);
- if (!q->buffer[i]) {
- dprintk("vino_queue_init(): kmalloc() failed\n");
- ret = -ENOMEM;
- break;
- }
-
- ret = vino_allocate_buffer(q->buffer[i],
- VINO_FRAMEBUFFER_SIZE);
- if (ret) {
- kfree(q->buffer[i]);
- dprintk("vino_queue_init(): "
- "vino_allocate_buffer() failed\n");
- break;
- }
-
- q->buffer[i]->id = i;
- if (i > 0) {
- q->buffer[i]->offset = q->buffer[i - 1]->offset +
- q->buffer[i - 1]->size;
- } else {
- q->buffer[i]->offset = 0;
- }
-
- spin_lock_init(&q->buffer[i]->state_lock);
-
- dprintk("vino_queue_init(): buffer = %d, offset = %d, "
- "size = %d\n", i, q->buffer[i]->offset,
- q->buffer[i]->size);
- }
-
- if (ret) {
- vino_queue_free_with_count(q, i);
- *length = 0;
- } else {
- q->length = *length;
- vino_fifo_init(&q->in, q->length);
- vino_fifo_init(&q->out, q->length);
- q->type = VINO_MEMORY_MMAP;
- q->magic = VINO_QUEUE_MAGIC;
- }
-
- mutex_unlock(&q->queue_mutex);
-
- return ret;
-}
-
-static struct vino_framebuffer *vino_queue_add(struct
- vino_framebuffer_queue *q,
- unsigned int id)
-{
- struct vino_framebuffer *ret = NULL;
- unsigned int total;
- unsigned long flags;
-
- dprintk("vino_queue_add(): id = %d\n", id);
-
- if (q->magic != VINO_QUEUE_MAGIC) {
- return ret;
- }
-
- spin_lock_irqsave(&q->queue_lock, flags);
-
- if (q->length == 0)
- goto out;
-
- if (id >= q->length)
- goto out;
-
- /* not needed?: if (vino_fifo_full(&q->out)) {
- goto out;
- }*/
- /* check that outgoing queue isn't already full
- * (or that it won't become full) */
- total = vino_fifo_get_used(&q->in) +
- vino_fifo_get_used(&q->out);
- if (total >= q->length)
- goto out;
-
- if (vino_fifo_enqueue(&q->in, id))
- goto out;
-
- ret = q->buffer[id];
-
-out:
- spin_unlock_irqrestore(&q->queue_lock, flags);
-
- return ret;
-}
-
-static struct vino_framebuffer *vino_queue_transfer(struct
- vino_framebuffer_queue *q)
-{
- struct vino_framebuffer *ret = NULL;
- struct vino_framebuffer *fb;
- int id;
- unsigned long flags;
-
- dprintk("vino_queue_transfer():\n");
-
- if (q->magic != VINO_QUEUE_MAGIC) {
- return ret;
- }
-
- spin_lock_irqsave(&q->queue_lock, flags);
-
- if (q->length == 0)
- goto out;
-
- // now this actually removes an entry from the incoming queue
- if (vino_fifo_dequeue(&q->in, &id)) {
- goto out;
- }
-
- dprintk("vino_queue_transfer(): id = %d\n", id);
- fb = q->buffer[id];
-
- // we have already checked that the outgoing queue is not full, but...
- if (vino_fifo_enqueue(&q->out, id)) {
- printk(KERN_ERR "vino_queue_transfer(): "
- "outgoing queue is full, this shouldn't happen!\n");
- goto out;
- }
-
- ret = fb;
-out:
- spin_unlock_irqrestore(&q->queue_lock, flags);
-
- return ret;
-}
-
-/* returns true/false */
-static int vino_queue_incoming_contains(struct vino_framebuffer_queue *q,
- unsigned int id)
-{
- int ret = 0;
- unsigned long flags;
-
- if (q->magic != VINO_QUEUE_MAGIC) {
- return ret;
- }
-
- spin_lock_irqsave(&q->queue_lock, flags);
-
- if (q->length == 0)
- goto out;
-
- ret = vino_fifo_has_id(&q->in, id);
-
-out:
- spin_unlock_irqrestore(&q->queue_lock, flags);
-
- return ret;
-}
-
-/* returns true/false */
-static int vino_queue_outgoing_contains(struct vino_framebuffer_queue *q,
- unsigned int id)
-{
- int ret = 0;
- unsigned long flags;
-
- if (q->magic != VINO_QUEUE_MAGIC) {
- return ret;
- }
-
- spin_lock_irqsave(&q->queue_lock, flags);
-
- if (q->length == 0)
- goto out;
-
- ret = vino_fifo_has_id(&q->out, id);
-
-out:
- spin_unlock_irqrestore(&q->queue_lock, flags);
-
- return ret;
-}
-
-static int vino_queue_get_incoming(struct vino_framebuffer_queue *q,
- unsigned int *used)
-{
- int ret = 0;
- unsigned long flags;
-
- if (q->magic != VINO_QUEUE_MAGIC) {
- return VINO_QUEUE_ERROR;
- }
-
- spin_lock_irqsave(&q->queue_lock, flags);
-
- if (q->length == 0) {
- ret = VINO_QUEUE_ERROR;
- goto out;
- }
-
- *used = vino_fifo_get_used(&q->in);
-
-out:
- spin_unlock_irqrestore(&q->queue_lock, flags);
-
- return ret;
-}
-
-static int vino_queue_get_outgoing(struct vino_framebuffer_queue *q,
- unsigned int *used)
-{
- int ret = 0;
- unsigned long flags;
-
- if (q->magic != VINO_QUEUE_MAGIC) {
- return VINO_QUEUE_ERROR;
- }
-
- spin_lock_irqsave(&q->queue_lock, flags);
-
- if (q->length == 0) {
- ret = VINO_QUEUE_ERROR;
- goto out;
- }
-
- *used = vino_fifo_get_used(&q->out);
-
-out:
- spin_unlock_irqrestore(&q->queue_lock, flags);
-
- return ret;
-}
-
-#if 0
-static int vino_queue_get_total(struct vino_framebuffer_queue *q,
- unsigned int *total)
-{
- int ret = 0;
- unsigned long flags;
-
- if (q->magic != VINO_QUEUE_MAGIC) {
- return VINO_QUEUE_ERROR;
- }
-
- spin_lock_irqsave(&q->queue_lock, flags);
-
- if (q->length == 0) {
- ret = VINO_QUEUE_ERROR;
- goto out;
- }
-
- *total = vino_fifo_get_used(&q->in) +
- vino_fifo_get_used(&q->out);
-
-out:
- spin_unlock_irqrestore(&q->queue_lock, flags);
-
- return ret;
-}
-#endif
-
-static struct vino_framebuffer *vino_queue_peek(struct
- vino_framebuffer_queue *q,
- unsigned int *id)
-{
- struct vino_framebuffer *ret = NULL;
- unsigned long flags;
-
- if (q->magic != VINO_QUEUE_MAGIC) {
- return ret;
- }
-
- spin_lock_irqsave(&q->queue_lock, flags);
-
- if (q->length == 0)
- goto out;
-
- if (vino_fifo_peek(&q->in, id)) {
- goto out;
- }
-
- ret = q->buffer[*id];
-out:
- spin_unlock_irqrestore(&q->queue_lock, flags);
-
- return ret;
-}
-
-static struct vino_framebuffer *vino_queue_remove(struct
- vino_framebuffer_queue *q,
- unsigned int *id)
-{
- struct vino_framebuffer *ret = NULL;
- unsigned long flags;
- dprintk("vino_queue_remove():\n");
-
- if (q->magic != VINO_QUEUE_MAGIC) {
- return ret;
- }
-
- spin_lock_irqsave(&q->queue_lock, flags);
-
- if (q->length == 0)
- goto out;
-
- if (vino_fifo_dequeue(&q->out, id)) {
- goto out;
- }
-
- dprintk("vino_queue_remove(): id = %d\n", *id);
- ret = q->buffer[*id];
-out:
- spin_unlock_irqrestore(&q->queue_lock, flags);
-
- return ret;
-}
-
-static struct
-vino_framebuffer *vino_queue_get_buffer(struct vino_framebuffer_queue *q,
- unsigned int id)
-{
- struct vino_framebuffer *ret = NULL;
- unsigned long flags;
-
- if (q->magic != VINO_QUEUE_MAGIC) {
- return ret;
- }
-
- spin_lock_irqsave(&q->queue_lock, flags);
-
- if (q->length == 0)
- goto out;
-
- if (id >= q->length)
- goto out;
-
- ret = q->buffer[id];
- out:
- spin_unlock_irqrestore(&q->queue_lock, flags);
-
- return ret;
-}
-
-static unsigned int vino_queue_get_length(struct vino_framebuffer_queue *q)
-{
- unsigned int length = 0;
- unsigned long flags;
-
- if (q->magic != VINO_QUEUE_MAGIC) {
- return length;
- }
-
- spin_lock_irqsave(&q->queue_lock, flags);
- length = q->length;
- spin_unlock_irqrestore(&q->queue_lock, flags);
-
- return length;
-}
-
-static int vino_queue_has_mapped_buffers(struct vino_framebuffer_queue *q)
-{
- unsigned int i;
- int ret = 0;
- unsigned long flags;
-
- if (q->magic != VINO_QUEUE_MAGIC) {
- return ret;
- }
-
- spin_lock_irqsave(&q->queue_lock, flags);
- for (i = 0; i < q->length; i++) {
- if (q->buffer[i]->map_count > 0) {
- ret = 1;
- break;
- }
- }
- spin_unlock_irqrestore(&q->queue_lock, flags);
-
- return ret;
-}
-
-/* VINO functions */
-
-/* execute with input_lock locked */
-static void vino_update_line_size(struct vino_channel_settings *vcs)
-{
- unsigned int w = vcs->clipping.right - vcs->clipping.left;
- unsigned int d = vcs->decimation;
- unsigned int bpp = vino_data_formats[vcs->data_format].bpp;
- unsigned int lsize;
-
- dprintk("update_line_size(): before: w = %d, d = %d, "
- "line_size = %d\n", w, d, vcs->line_size);
-
- /* line size must be multiple of 8 bytes */
- lsize = (bpp * (w / d)) & ~7;
- w = (lsize / bpp) * d;
-
- vcs->clipping.right = vcs->clipping.left + w;
- vcs->line_size = lsize;
-
- dprintk("update_line_size(): after: w = %d, d = %d, "
- "line_size = %d\n", w, d, vcs->line_size);
-}
-
-/* execute with input_lock locked */
-static void vino_set_clipping(struct vino_channel_settings *vcs,
- unsigned int x, unsigned int y,
- unsigned int w, unsigned int h)
-{
- unsigned int maxwidth, maxheight;
- unsigned int d;
-
- maxwidth = vino_data_norms[vcs->data_norm].width;
- maxheight = vino_data_norms[vcs->data_norm].height;
- d = vcs->decimation;
-
- y &= ~1; /* odd/even fields */
-
- if (x > maxwidth) {
- x = 0;
- }
- if (y > maxheight) {
- y = 0;
- }
-
- if (((w / d) < VINO_MIN_WIDTH)
- || ((h / d) < VINO_MIN_HEIGHT)) {
- w = VINO_MIN_WIDTH * d;
- h = VINO_MIN_HEIGHT * d;
- }
-
- if ((x + w) > maxwidth) {
- w = maxwidth - x;
- if ((w / d) < VINO_MIN_WIDTH)
- x = maxwidth - VINO_MIN_WIDTH * d;
- }
- if ((y + h) > maxheight) {
- h = maxheight - y;
- if ((h / d) < VINO_MIN_HEIGHT)
- y = maxheight - VINO_MIN_HEIGHT * d;
- }
-
- vcs->clipping.left = x;
- vcs->clipping.top = y;
- vcs->clipping.right = x + w;
- vcs->clipping.bottom = y + h;
-
- vino_update_line_size(vcs);
-
- dprintk("clipping %d, %d, %d, %d / %d - %d\n",
- vcs->clipping.left, vcs->clipping.top, vcs->clipping.right,
- vcs->clipping.bottom, vcs->decimation, vcs->line_size);
-}
-
-/* execute with input_lock locked */
-static inline void vino_set_default_clipping(struct vino_channel_settings *vcs)
-{
- vino_set_clipping(vcs, 0, 0, vino_data_norms[vcs->data_norm].width,
- vino_data_norms[vcs->data_norm].height);
-}
-
-/* execute with input_lock locked */
-static void vino_set_scaling(struct vino_channel_settings *vcs,
- unsigned int w, unsigned int h)
-{
- unsigned int x, y, curw, curh, d;
-
- x = vcs->clipping.left;
- y = vcs->clipping.top;
- curw = vcs->clipping.right - vcs->clipping.left;
- curh = vcs->clipping.bottom - vcs->clipping.top;
-
- d = max(curw / w, curh / h);
-
- dprintk("scaling w: %d, h: %d, curw: %d, curh: %d, d: %d\n",
- w, h, curw, curh, d);
-
- if (d < 1) {
- d = 1;
- } else if (d > 8) {
- d = 8;
- }
-
- vcs->decimation = d;
- vino_set_clipping(vcs, x, y, w * d, h * d);
-
- dprintk("scaling %d, %d, %d, %d / %d - %d\n", vcs->clipping.left,
- vcs->clipping.top, vcs->clipping.right, vcs->clipping.bottom,
- vcs->decimation, vcs->line_size);
-}
-
-/* execute with input_lock locked */
-static inline void vino_set_default_scaling(struct vino_channel_settings *vcs)
-{
- vino_set_scaling(vcs, vcs->clipping.right - vcs->clipping.left,
- vcs->clipping.bottom - vcs->clipping.top);
-}
-
-/* execute with input_lock locked */
-static void vino_set_framerate(struct vino_channel_settings *vcs,
- unsigned int fps)
-{
- unsigned int mask;
-
- switch (vcs->data_norm) {
- case VINO_DATA_NORM_NTSC:
- case VINO_DATA_NORM_D1:
- fps = (unsigned int)(fps / 6) * 6; // FIXME: round!
-
- if (fps < vino_data_norms[vcs->data_norm].fps_min)
- fps = vino_data_norms[vcs->data_norm].fps_min;
- if (fps > vino_data_norms[vcs->data_norm].fps_max)
- fps = vino_data_norms[vcs->data_norm].fps_max;
-
- switch (fps) {
- case 6:
- mask = 0x003;
- break;
- case 12:
- mask = 0x0c3;
- break;
- case 18:
- mask = 0x333;
- break;
- case 24:
- mask = 0x3ff;
- break;
- case 30:
- mask = 0xfff;
- break;
- default:
- mask = VINO_FRAMERT_FULL;
- }
- vcs->framert_reg = VINO_FRAMERT_RT(mask);
- break;
- case VINO_DATA_NORM_PAL:
- case VINO_DATA_NORM_SECAM:
- fps = (unsigned int)(fps / 5) * 5; // FIXME: round!
-
- if (fps < vino_data_norms[vcs->data_norm].fps_min)
- fps = vino_data_norms[vcs->data_norm].fps_min;
- if (fps > vino_data_norms[vcs->data_norm].fps_max)
- fps = vino_data_norms[vcs->data_norm].fps_max;
-
- switch (fps) {
- case 5:
- mask = 0x003;
- break;
- case 10:
- mask = 0x0c3;
- break;
- case 15:
- mask = 0x333;
- break;
- case 20:
- mask = 0x0ff;
- break;
- case 25:
- mask = 0x3ff;
- break;
- default:
- mask = VINO_FRAMERT_FULL;
- }
- vcs->framert_reg = VINO_FRAMERT_RT(mask) | VINO_FRAMERT_PAL;
- break;
- }
-
- vcs->fps = fps;
-}
-
-/* execute with input_lock locked */
-static inline void vino_set_default_framerate(struct
- vino_channel_settings *vcs)
-{
- vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max);
-}
-
-/* VINO I2C bus functions */
-
-struct i2c_algo_sgi_data {
- void *data; /* private data for lowlevel routines */
- unsigned (*getctrl)(void *data);
- void (*setctrl)(void *data, unsigned val);
- unsigned (*rdata)(void *data);
- void (*wdata)(void *data, unsigned val);
-
- int xfer_timeout;
- int ack_timeout;
-};
-
-static int wait_xfer_done(struct i2c_algo_sgi_data *adap)
-{
- int i;
-
- for (i = 0; i < adap->xfer_timeout; i++) {
- if ((adap->getctrl(adap->data) & SGI_I2C_XFER_BUSY) == 0)
- return 0;
- udelay(1);
- }
-
- return -ETIMEDOUT;
-}
-
-static int wait_ack(struct i2c_algo_sgi_data *adap)
-{
- int i;
-
- if (wait_xfer_done(adap))
- return -ETIMEDOUT;
- for (i = 0; i < adap->ack_timeout; i++) {
- if ((adap->getctrl(adap->data) & SGI_I2C_NACK) == 0)
- return 0;
- udelay(1);
- }
-
- return -ETIMEDOUT;
-}
-
-static int force_idle(struct i2c_algo_sgi_data *adap)
-{
- int i;
-
- adap->setctrl(adap->data, SGI_I2C_FORCE_IDLE);
- for (i = 0; i < adap->xfer_timeout; i++) {
- if ((adap->getctrl(adap->data) & SGI_I2C_NOT_IDLE) == 0)
- goto out;
- udelay(1);
- }
- return -ETIMEDOUT;
-out:
- if (adap->getctrl(adap->data) & SGI_I2C_BUS_ERR)
- return -EIO;
- return 0;
-}
-
-static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr,
- int rd)
-{
- if (rd)
- adap->setctrl(adap->data, SGI_I2C_NOT_IDLE);
- /* Check if bus is idle, eventually force it to do so */
- if (adap->getctrl(adap->data) & SGI_I2C_NOT_IDLE)
- if (force_idle(adap))
- return -EIO;
- /* Write out the i2c chip address and specify operation */
- adap->setctrl(adap->data,
- SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE);
- if (rd)
- addr |= 1;
- adap->wdata(adap->data, addr);
- if (wait_ack(adap))
- return -EIO;
- return 0;
-}
-
-static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf,
- unsigned int len)
-{
- int i;
-
- adap->setctrl(adap->data,
- SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE);
- for (i = 0; i < len; i++) {
- if (wait_xfer_done(adap))
- return -EIO;
- buf[i] = adap->rdata(adap->data);
- }
- adap->setctrl(adap->data, SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE);
-
- return 0;
-
-}
-
-static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf,
- unsigned int len)
-{
- int i;
-
- /* We are already in write state */
- for (i = 0; i < len; i++) {
- adap->wdata(adap->data, buf[i]);
- if (wait_ack(adap))
- return -EIO;
- }
- return 0;
-}
-
-static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
- int num)
-{
- struct i2c_algo_sgi_data *adap = i2c_adap->algo_data;
- struct i2c_msg *p;
- int i, err = 0;
-
- for (i = 0; !err && i < num; i++) {
- p = &msgs[i];
- err = do_address(adap, p->addr, p->flags & I2C_M_RD);
- if (err || !p->len)
- continue;
- if (p->flags & I2C_M_RD)
- err = i2c_read(adap, p->buf, p->len);
- else
- err = i2c_write(adap, p->buf, p->len);
- }
-
- return (err < 0) ? err : i;
-}
-
-static u32 sgi_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm sgi_algo = {
- .master_xfer = sgi_xfer,
- .functionality = sgi_func,
-};
-
-static unsigned i2c_vino_getctrl(void *data)
-{
- return vino->i2c_control;
-}
-
-static void i2c_vino_setctrl(void *data, unsigned val)
-{
- vino->i2c_control = val;
-}
-
-static unsigned i2c_vino_rdata(void *data)
-{
- return vino->i2c_data;
-}
-
-static void i2c_vino_wdata(void *data, unsigned val)
-{
- vino->i2c_data = val;
-}
-
-static struct i2c_algo_sgi_data i2c_sgi_vino_data = {
- .getctrl = &i2c_vino_getctrl,
- .setctrl = &i2c_vino_setctrl,
- .rdata = &i2c_vino_rdata,
- .wdata = &i2c_vino_wdata,
- .xfer_timeout = 200,
- .ack_timeout = 1000,
-};
-
-static struct i2c_adapter vino_i2c_adapter = {
- .name = "VINO I2C bus",
- .algo = &sgi_algo,
- .algo_data = &i2c_sgi_vino_data,
- .owner = THIS_MODULE,
-};
-
-/*
- * Prepare VINO for DMA transfer...
- * (execute only with vino_lock and input_lock locked)
- */
-static int vino_dma_setup(struct vino_channel_settings *vcs,
- struct vino_framebuffer *fb)
-{
- u32 ctrl, intr;
- struct sgi_vino_channel *ch;
- const struct vino_data_norm *norm;
-
- dprintk("vino_dma_setup():\n");
-
- vcs->field = 0;
- fb->frame_counter = 0;
-
- ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b;
- norm = &vino_data_norms[vcs->data_norm];
-
- ch->page_index = 0;
- ch->line_count = 0;
-
- /* VINO line size register is set 8 bytes less than actual */
- ch->line_size = vcs->line_size - 8;
-
- /* let VINO know where to transfer data */
- ch->start_desc_tbl = fb->desc_table.dma;
- ch->next_4_desc = fb->desc_table.dma;
-
- /* give vino time to fetch the first four descriptors, 5 usec
- * should be more than enough time */
- udelay(VINO_DESC_FETCH_DELAY);
-
- dprintk("vino_dma_setup(): start desc = %08x, next 4 desc = %08x\n",
- ch->start_desc_tbl, ch->next_4_desc);
-
- /* set the alpha register */
- ch->alpha = vcs->alpha;
-
- /* set clipping registers */
- ch->clip_start = VINO_CLIP_ODD(norm->odd.top + vcs->clipping.top / 2) |
- VINO_CLIP_EVEN(norm->even.top +
- vcs->clipping.top / 2) |
- VINO_CLIP_X(vcs->clipping.left);
- ch->clip_end = VINO_CLIP_ODD(norm->odd.top +
- vcs->clipping.bottom / 2 - 1) |
- VINO_CLIP_EVEN(norm->even.top +
- vcs->clipping.bottom / 2 - 1) |
- VINO_CLIP_X(vcs->clipping.right);
-
- /* set the size of actual content in the buffer (DECIMATION !) */
- fb->data_size = ((vcs->clipping.right - vcs->clipping.left) /
- vcs->decimation) *
- ((vcs->clipping.bottom - vcs->clipping.top) /
- vcs->decimation) *
- vino_data_formats[vcs->data_format].bpp;
-
- ch->frame_rate = vcs->framert_reg;
-
- ctrl = vino->control;
- intr = vino->intr_status;
-
- if (vcs->channel == VINO_CHANNEL_A) {
- /* All interrupt conditions for this channel was cleared
- * so clear the interrupt status register and enable
- * interrupts */
- intr &= ~VINO_INTSTAT_A;
- ctrl |= VINO_CTRL_A_INT;
-
- /* enable synchronization */
- ctrl |= VINO_CTRL_A_SYNC_ENBL;
-
- /* enable frame assembly */
- ctrl |= VINO_CTRL_A_INTERLEAVE_ENBL;
-
- /* set decimation used */
- if (vcs->decimation < 2)
- ctrl &= ~VINO_CTRL_A_DEC_ENBL;
- else {
- ctrl |= VINO_CTRL_A_DEC_ENBL;
- ctrl &= ~VINO_CTRL_A_DEC_SCALE_MASK;
- ctrl |= (vcs->decimation - 1) <<
- VINO_CTRL_A_DEC_SCALE_SHIFT;
- }
-
- /* select input interface */
- if (vcs->input == VINO_INPUT_D1)
- ctrl |= VINO_CTRL_A_SELECT;
- else
- ctrl &= ~VINO_CTRL_A_SELECT;
-
- /* palette */
- ctrl &= ~(VINO_CTRL_A_LUMA_ONLY | VINO_CTRL_A_RGB |
- VINO_CTRL_A_DITHER);
- } else {
- intr &= ~VINO_INTSTAT_B;
- ctrl |= VINO_CTRL_B_INT;
-
- ctrl |= VINO_CTRL_B_SYNC_ENBL;
- ctrl |= VINO_CTRL_B_INTERLEAVE_ENBL;
-
- if (vcs->decimation < 2)
- ctrl &= ~VINO_CTRL_B_DEC_ENBL;
- else {
- ctrl |= VINO_CTRL_B_DEC_ENBL;
- ctrl &= ~VINO_CTRL_B_DEC_SCALE_MASK;
- ctrl |= (vcs->decimation - 1) <<
- VINO_CTRL_B_DEC_SCALE_SHIFT;
-
- }
- if (vcs->input == VINO_INPUT_D1)
- ctrl |= VINO_CTRL_B_SELECT;
- else
- ctrl &= ~VINO_CTRL_B_SELECT;
-
- ctrl &= ~(VINO_CTRL_B_LUMA_ONLY | VINO_CTRL_B_RGB |
- VINO_CTRL_B_DITHER);
- }
-
- /* set palette */
- fb->data_format = vcs->data_format;
-
- switch (vcs->data_format) {
- case VINO_DATA_FMT_GREY:
- ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
- VINO_CTRL_A_LUMA_ONLY : VINO_CTRL_B_LUMA_ONLY;
- break;
- case VINO_DATA_FMT_RGB32:
- ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
- VINO_CTRL_A_RGB : VINO_CTRL_B_RGB;
- break;
- case VINO_DATA_FMT_YUV:
- /* nothing needs to be done */
- break;
- case VINO_DATA_FMT_RGB332:
- ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
- VINO_CTRL_A_RGB | VINO_CTRL_A_DITHER :
- VINO_CTRL_B_RGB | VINO_CTRL_B_DITHER;
- break;
- }
-
- vino->intr_status = intr;
- vino->control = ctrl;
-
- return 0;
-}
-
-/* (execute only with vino_lock locked) */
-static inline void vino_dma_start(struct vino_channel_settings *vcs)
-{
- u32 ctrl = vino->control;
-
- dprintk("vino_dma_start():\n");
- ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
- VINO_CTRL_A_DMA_ENBL : VINO_CTRL_B_DMA_ENBL;
- vino->control = ctrl;
-}
-
-/* (execute only with vino_lock locked) */
-static inline void vino_dma_stop(struct vino_channel_settings *vcs)
-{
- u32 ctrl = vino->control;
-
- ctrl &= (vcs->channel == VINO_CHANNEL_A) ?
- ~VINO_CTRL_A_DMA_ENBL : ~VINO_CTRL_B_DMA_ENBL;
- ctrl &= (vcs->channel == VINO_CHANNEL_A) ?
- ~VINO_CTRL_A_INT : ~VINO_CTRL_B_INT;
- vino->control = ctrl;
- dprintk("vino_dma_stop():\n");
-}
-
-/*
- * Load dummy page to descriptor registers. This prevents generating of
- * spurious interrupts. (execute only with vino_lock locked)
- */
-static void vino_clear_interrupt(struct vino_channel_settings *vcs)
-{
- struct sgi_vino_channel *ch;
-
- ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b;
-
- ch->page_index = 0;
- ch->line_count = 0;
-
- ch->start_desc_tbl = vino_drvdata->dummy_desc_table.dma;
- ch->next_4_desc = vino_drvdata->dummy_desc_table.dma;
-
- udelay(VINO_DESC_FETCH_DELAY);
- dprintk("channel %c clear interrupt condition\n",
- (vcs->channel == VINO_CHANNEL_A) ? 'A':'B');
-}
-
-static int vino_capture(struct vino_channel_settings *vcs,
- struct vino_framebuffer *fb)
-{
- int err = 0;
- unsigned long flags, flags2;
-
- spin_lock_irqsave(&fb->state_lock, flags);
-
- if (fb->state == VINO_FRAMEBUFFER_IN_USE)
- err = -EBUSY;
- fb->state = VINO_FRAMEBUFFER_IN_USE;
-
- spin_unlock_irqrestore(&fb->state_lock, flags);
-
- if (err)
- return err;
-
- spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
- spin_lock_irqsave(&vino_drvdata->input_lock, flags2);
-
- vino_dma_setup(vcs, fb);
- vino_dma_start(vcs);
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags2);
- spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
-
- return err;
-}
-
-static
-struct vino_framebuffer *vino_capture_enqueue(struct
- vino_channel_settings *vcs,
- unsigned int index)
-{
- struct vino_framebuffer *fb;
- unsigned long flags;
-
- dprintk("vino_capture_enqueue():\n");
-
- spin_lock_irqsave(&vcs->capture_lock, flags);
-
- fb = vino_queue_add(&vcs->fb_queue, index);
- if (fb == NULL) {
- dprintk("vino_capture_enqueue(): vino_queue_add() failed, "
- "queue full?\n");
- goto out;
- }
-out:
- spin_unlock_irqrestore(&vcs->capture_lock, flags);
-
- return fb;
-}
-
-static int vino_capture_next(struct vino_channel_settings *vcs, int start)
-{
- struct vino_framebuffer *fb;
- unsigned int incoming, id;
- int err = 0;
- unsigned long flags;
-
- dprintk("vino_capture_next():\n");
-
- spin_lock_irqsave(&vcs->capture_lock, flags);
-
- if (start) {
- /* start capture only if capture isn't in progress already */
- if (vcs->capturing) {
- spin_unlock_irqrestore(&vcs->capture_lock, flags);
- return 0;
- }
-
- } else {
- /* capture next frame:
- * stop capture if capturing is not set */
- if (!vcs->capturing) {
- spin_unlock_irqrestore(&vcs->capture_lock, flags);
- return 0;
- }
- }
-
- err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
- if (err) {
- dprintk("vino_capture_next(): vino_queue_get_incoming() "
- "failed\n");
- err = -EINVAL;
- goto out;
- }
- if (incoming == 0) {
- dprintk("vino_capture_next(): no buffers available\n");
- goto out;
- }
-
- fb = vino_queue_peek(&vcs->fb_queue, &id);
- if (fb == NULL) {
- dprintk("vino_capture_next(): vino_queue_peek() failed\n");
- err = -EINVAL;
- goto out;
- }
-
- if (start) {
- vcs->capturing = 1;
- }
-
- spin_unlock_irqrestore(&vcs->capture_lock, flags);
-
- err = vino_capture(vcs, fb);
-
- return err;
-
-out:
- vcs->capturing = 0;
- spin_unlock_irqrestore(&vcs->capture_lock, flags);
-
- return err;
-}
-
-static inline int vino_is_capturing(struct vino_channel_settings *vcs)
-{
- int ret;
- unsigned long flags;
-
- spin_lock_irqsave(&vcs->capture_lock, flags);
-
- ret = vcs->capturing;
-
- spin_unlock_irqrestore(&vcs->capture_lock, flags);
-
- return ret;
-}
-
-/* waits until a frame is captured */
-static int vino_wait_for_frame(struct vino_channel_settings *vcs)
-{
- wait_queue_t wait;
- int err = 0;
-
- dprintk("vino_wait_for_frame():\n");
-
- init_waitqueue_entry(&wait, current);
- /* add ourselves into wait queue */
- add_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait);
-
- /* to ensure that schedule_timeout will return immediately
- * if VINO interrupt was triggered meanwhile */
- schedule_timeout_interruptible(msecs_to_jiffies(100));
-
- if (signal_pending(current))
- err = -EINTR;
-
- remove_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait);
-
- dprintk("vino_wait_for_frame(): waiting for frame %s\n",
- err ? "failed" : "ok");
-
- return err;
-}
-
-/* the function assumes that PAGE_SIZE % 4 == 0 */
-static void vino_convert_to_rgba(struct vino_framebuffer *fb) {
- unsigned char *pageptr;
- unsigned int page, i;
- unsigned char a;
-
- for (page = 0; page < fb->desc_table.page_count; page++) {
- pageptr = (unsigned char *)fb->desc_table.virtual[page];
-
- for (i = 0; i < PAGE_SIZE; i += 4) {
- a = pageptr[0];
- pageptr[0] = pageptr[3];
- pageptr[1] = pageptr[2];
- pageptr[2] = pageptr[1];
- pageptr[3] = a;
- pageptr += 4;
- }
- }
-}
-
-/* checks if the buffer is in correct state and syncs data */
-static int vino_check_buffer(struct vino_channel_settings *vcs,
- struct vino_framebuffer *fb)
-{
- int err = 0;
- unsigned long flags;
-
- dprintk("vino_check_buffer():\n");
-
- spin_lock_irqsave(&fb->state_lock, flags);
- switch (fb->state) {
- case VINO_FRAMEBUFFER_IN_USE:
- err = -EIO;
- break;
- case VINO_FRAMEBUFFER_READY:
- vino_sync_buffer(fb);
- fb->state = VINO_FRAMEBUFFER_UNUSED;
- break;
- default:
- err = -EINVAL;
- }
- spin_unlock_irqrestore(&fb->state_lock, flags);
-
- if (!err) {
- if (vino_pixel_conversion
- && (fb->data_format == VINO_DATA_FMT_RGB32)) {
- vino_convert_to_rgba(fb);
- }
- } else if (err && (err != -EINVAL)) {
- dprintk("vino_check_buffer(): buffer not ready\n");
-
- spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
- vino_dma_stop(vcs);
- vino_clear_interrupt(vcs);
- spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
- }
-
- return err;
-}
-
-/* forcefully terminates capture */
-static void vino_capture_stop(struct vino_channel_settings *vcs)
-{
- unsigned int incoming = 0, outgoing = 0, id;
- unsigned long flags, flags2;
-
- dprintk("vino_capture_stop():\n");
-
- spin_lock_irqsave(&vcs->capture_lock, flags);
-
- /* unset capturing to stop queue processing */
- vcs->capturing = 0;
-
- spin_lock_irqsave(&vino_drvdata->vino_lock, flags2);
-
- vino_dma_stop(vcs);
- vino_clear_interrupt(vcs);
-
- spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags2);
-
- /* remove all items from the queue */
- if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) {
- dprintk("vino_capture_stop(): "
- "vino_queue_get_incoming() failed\n");
- goto out;
- }
- while (incoming > 0) {
- vino_queue_transfer(&vcs->fb_queue);
-
- if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) {
- dprintk("vino_capture_stop(): "
- "vino_queue_get_incoming() failed\n");
- goto out;
- }
- }
-
- if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
- dprintk("vino_capture_stop(): "
- "vino_queue_get_outgoing() failed\n");
- goto out;
- }
- while (outgoing > 0) {
- vino_queue_remove(&vcs->fb_queue, &id);
-
- if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
- dprintk("vino_capture_stop(): "
- "vino_queue_get_outgoing() failed\n");
- goto out;
- }
- }
-
-out:
- spin_unlock_irqrestore(&vcs->capture_lock, flags);
-}
-
-#if 0
-static int vino_capture_failed(struct vino_channel_settings *vcs)
-{
- struct vino_framebuffer *fb;
- unsigned long flags;
- unsigned int i;
- int ret;
-
- dprintk("vino_capture_failed():\n");
-
- spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
-
- vino_dma_stop(vcs);
- vino_clear_interrupt(vcs);
-
- spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
-
- ret = vino_queue_get_incoming(&vcs->fb_queue, &i);
- if (ret == VINO_QUEUE_ERROR) {
- dprintk("vino_queue_get_incoming() failed\n");
- return -EINVAL;
- }
- if (i == 0) {
- /* no buffers to process */
- return 0;
- }
-
- fb = vino_queue_peek(&vcs->fb_queue, &i);
- if (fb == NULL) {
- dprintk("vino_queue_peek() failed\n");
- return -EINVAL;
- }
-
- spin_lock_irqsave(&fb->state_lock, flags);
- if (fb->state == VINO_FRAMEBUFFER_IN_USE) {
- fb->state = VINO_FRAMEBUFFER_UNUSED;
- vino_queue_transfer(&vcs->fb_queue);
- vino_queue_remove(&vcs->fb_queue, &i);
- /* we should actually discard the newest frame,
- * but who cares ... */
- }
- spin_unlock_irqrestore(&fb->state_lock, flags);
-
- return 0;
-}
-#endif
-
-static void vino_skip_frame(struct vino_channel_settings *vcs)
-{
- struct vino_framebuffer *fb;
- unsigned long flags;
- unsigned int id;
-
- spin_lock_irqsave(&vcs->capture_lock, flags);
- fb = vino_queue_peek(&vcs->fb_queue, &id);
- if (!fb) {
- spin_unlock_irqrestore(&vcs->capture_lock, flags);
- dprintk("vino_skip_frame(): vino_queue_peek() failed!\n");
- return;
- }
- spin_unlock_irqrestore(&vcs->capture_lock, flags);
-
- spin_lock_irqsave(&fb->state_lock, flags);
- fb->state = VINO_FRAMEBUFFER_UNUSED;
- spin_unlock_irqrestore(&fb->state_lock, flags);
-
- vino_capture_next(vcs, 0);
-}
-
-static void vino_frame_done(struct vino_channel_settings *vcs)
-{
- struct vino_framebuffer *fb;
- unsigned long flags;
-
- spin_lock_irqsave(&vcs->capture_lock, flags);
- fb = vino_queue_transfer(&vcs->fb_queue);
- if (!fb) {
- spin_unlock_irqrestore(&vcs->capture_lock, flags);
- dprintk("vino_frame_done(): vino_queue_transfer() failed!\n");
- return;
- }
- spin_unlock_irqrestore(&vcs->capture_lock, flags);
-
- fb->frame_counter = vcs->int_data.frame_counter;
- memcpy(&fb->timestamp, &vcs->int_data.timestamp,
- sizeof(struct timeval));
-
- spin_lock_irqsave(&fb->state_lock, flags);
- if (fb->state == VINO_FRAMEBUFFER_IN_USE)
- fb->state = VINO_FRAMEBUFFER_READY;
- spin_unlock_irqrestore(&fb->state_lock, flags);
-
- wake_up(&vcs->fb_queue.frame_wait_queue);
-
- vino_capture_next(vcs, 0);
-}
-
-static void vino_capture_tasklet(unsigned long channel) {
- struct vino_channel_settings *vcs;
-
- vcs = (channel == VINO_CHANNEL_A)
- ? &vino_drvdata->a : &vino_drvdata->b;
-
- if (vcs->int_data.skip)
- vcs->int_data.skip_count++;
-
- if (vcs->int_data.skip && (vcs->int_data.skip_count
- <= VINO_MAX_FRAME_SKIP_COUNT)) {
- vino_skip_frame(vcs);
- } else {
- vcs->int_data.skip_count = 0;
- vino_frame_done(vcs);
- }
-}
-
-static irqreturn_t vino_interrupt(int irq, void *dev_id)
-{
- u32 ctrl, intr;
- unsigned int fc_a, fc_b;
- int handled_a = 0, skip_a = 0, done_a = 0;
- int handled_b = 0, skip_b = 0, done_b = 0;
-
-#ifdef VINO_DEBUG_INT
- int loop = 0;
- unsigned int line_count = vino->a.line_count,
- page_index = vino->a.page_index,
- field_counter = vino->a.field_counter,
- start_desc_tbl = vino->a.start_desc_tbl,
- next_4_desc = vino->a.next_4_desc;
- unsigned int line_count_2,
- page_index_2,
- field_counter_2,
- start_desc_tbl_2,
- next_4_desc_2;
-#endif
-
- spin_lock(&vino_drvdata->vino_lock);
-
- while ((intr = vino->intr_status)) {
- fc_a = vino->a.field_counter >> 1;
- fc_b = vino->b.field_counter >> 1;
-
- /* handle error-interrupts in some special way ?
- * --> skips frames */
- if (intr & VINO_INTSTAT_A) {
- if (intr & VINO_INTSTAT_A_EOF) {
- vino_drvdata->a.field++;
- if (vino_drvdata->a.field > 1) {
- vino_dma_stop(&vino_drvdata->a);
- vino_clear_interrupt(&vino_drvdata->a);
- vino_drvdata->a.field = 0;
- done_a = 1;
- } else {
- if (vino->a.page_index
- != vino_drvdata->a.line_size) {
- vino->a.line_count = 0;
- vino->a.page_index =
- vino_drvdata->
- a.line_size;
- vino->a.next_4_desc =
- vino->a.start_desc_tbl;
- }
- }
- dprintk("channel A end-of-field "
- "interrupt: %04x\n", intr);
- } else {
- vino_dma_stop(&vino_drvdata->a);
- vino_clear_interrupt(&vino_drvdata->a);
- vino_drvdata->a.field = 0;
- skip_a = 1;
- dprintk("channel A error interrupt: %04x\n",
- intr);
- }
-
-#ifdef VINO_DEBUG_INT
- line_count_2 = vino->a.line_count;
- page_index_2 = vino->a.page_index;
- field_counter_2 = vino->a.field_counter;
- start_desc_tbl_2 = vino->a.start_desc_tbl;
- next_4_desc_2 = vino->a.next_4_desc;
-
- printk("intr = %04x, loop = %d, field = %d\n",
- intr, loop, vino_drvdata->a.field);
- printk("1- line count = %04d, page index = %04d, "
- "start = %08x, next = %08x\n"
- " fieldc = %d, framec = %d\n",
- line_count, page_index, start_desc_tbl,
- next_4_desc, field_counter, fc_a);
- printk("12-line count = %04d, page index = %04d, "
- " start = %08x, next = %08x\n",
- line_count_2, page_index_2, start_desc_tbl_2,
- next_4_desc_2);
-
- if (done_a)
- printk("\n");
-#endif
- }
-
- if (intr & VINO_INTSTAT_B) {
- if (intr & VINO_INTSTAT_B_EOF) {
- vino_drvdata->b.field++;
- if (vino_drvdata->b.field > 1) {
- vino_dma_stop(&vino_drvdata->b);
- vino_clear_interrupt(&vino_drvdata->b);
- vino_drvdata->b.field = 0;
- done_b = 1;
- }
- dprintk("channel B end-of-field "
- "interrupt: %04x\n", intr);
- } else {
- vino_dma_stop(&vino_drvdata->b);
- vino_clear_interrupt(&vino_drvdata->b);
- vino_drvdata->b.field = 0;
- skip_b = 1;
- dprintk("channel B error interrupt: %04x\n",
- intr);
- }
- }
-
- /* Always remember to clear interrupt status.
- * Disable VINO interrupts while we do this. */
- ctrl = vino->control;
- vino->control = ctrl & ~(VINO_CTRL_A_INT | VINO_CTRL_B_INT);
- vino->intr_status = ~intr;
- vino->control = ctrl;
-
- spin_unlock(&vino_drvdata->vino_lock);
-
- if ((!handled_a) && (done_a || skip_a)) {
- if (!skip_a) {
- do_gettimeofday(&vino_drvdata->
- a.int_data.timestamp);
- vino_drvdata->a.int_data.frame_counter = fc_a;
- }
- vino_drvdata->a.int_data.skip = skip_a;
-
- dprintk("channel A %s, interrupt: %d\n",
- skip_a ? "skipping frame" : "frame done",
- intr);
- tasklet_hi_schedule(&vino_tasklet_a);
- handled_a = 1;
- }
-
- if ((!handled_b) && (done_b || skip_b)) {
- if (!skip_b) {
- do_gettimeofday(&vino_drvdata->
- b.int_data.timestamp);
- vino_drvdata->b.int_data.frame_counter = fc_b;
- }
- vino_drvdata->b.int_data.skip = skip_b;
-
- dprintk("channel B %s, interrupt: %d\n",
- skip_b ? "skipping frame" : "frame done",
- intr);
- tasklet_hi_schedule(&vino_tasklet_b);
- handled_b = 1;
- }
-
-#ifdef VINO_DEBUG_INT
- loop++;
-#endif
- spin_lock(&vino_drvdata->vino_lock);
- }
-
- spin_unlock(&vino_drvdata->vino_lock);
-
- return IRQ_HANDLED;
-}
-
-/* VINO video input management */
-
-static int vino_get_saa7191_input(int input)
-{
- switch (input) {
- case VINO_INPUT_COMPOSITE:
- return SAA7191_INPUT_COMPOSITE;
- case VINO_INPUT_SVIDEO:
- return SAA7191_INPUT_SVIDEO;
- default:
- printk(KERN_ERR "VINO: vino_get_saa7191_input(): "
- "invalid input!\n");
- return -1;
- }
-}
-
-/* execute with input_lock locked */
-static int vino_is_input_owner(struct vino_channel_settings *vcs)
-{
- switch(vcs->input) {
- case VINO_INPUT_COMPOSITE:
- case VINO_INPUT_SVIDEO:
- return vino_drvdata->decoder_owner == vcs->channel;
- case VINO_INPUT_D1:
- return vino_drvdata->camera_owner == vcs->channel;
- default:
- return 0;
- }
-}
-
-static int vino_acquire_input(struct vino_channel_settings *vcs)
-{
- unsigned long flags;
- int ret = 0;
-
- dprintk("vino_acquire_input():\n");
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- /* First try D1 and then SAA7191 */
- if (vino_drvdata->camera
- && (vino_drvdata->camera_owner == VINO_NO_CHANNEL)) {
- vino_drvdata->camera_owner = vcs->channel;
- vcs->input = VINO_INPUT_D1;
- vcs->data_norm = VINO_DATA_NORM_D1;
- } else if (vino_drvdata->decoder
- && (vino_drvdata->decoder_owner == VINO_NO_CHANNEL)) {
- int input;
- int data_norm = 0;
- v4l2_std_id norm;
-
- input = VINO_INPUT_COMPOSITE;
-
- ret = decoder_call(video, s_routing,
- vino_get_saa7191_input(input), 0, 0);
- if (ret) {
- ret = -EINVAL;
- goto out;
- }
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- /* Don't hold spinlocks while auto-detecting norm
- * as it may take a while... */
-
- ret = decoder_call(video, querystd, &norm);
- if (!ret) {
- for (data_norm = 0; data_norm < 3; data_norm++) {
- if (vino_data_norms[data_norm].std & norm)
- break;
- }
- if (data_norm == 3)
- data_norm = VINO_DATA_NORM_PAL;
- ret = decoder_call(core, s_std, norm);
- }
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- if (ret) {
- ret = -EINVAL;
- goto out;
- }
-
- vino_drvdata->decoder_owner = vcs->channel;
-
- vcs->input = input;
- vcs->data_norm = data_norm;
- } else {
- vcs->input = (vcs->channel == VINO_CHANNEL_A) ?
- vino_drvdata->b.input : vino_drvdata->a.input;
- vcs->data_norm = (vcs->channel == VINO_CHANNEL_A) ?
- vino_drvdata->b.data_norm : vino_drvdata->a.data_norm;
- }
-
- if (vcs->input == VINO_INPUT_NONE) {
- ret = -ENODEV;
- goto out;
- }
-
- vino_set_default_clipping(vcs);
- vino_set_default_scaling(vcs);
- vino_set_default_framerate(vcs);
-
- dprintk("vino_acquire_input(): %s\n", vino_inputs[vcs->input].name);
-
-out:
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return ret;
-}
-
-static int vino_set_input(struct vino_channel_settings *vcs, int input)
-{
- struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
- &vino_drvdata->b : &vino_drvdata->a;
- unsigned long flags;
- int ret = 0;
-
- dprintk("vino_set_input():\n");
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- if (vcs->input == input)
- goto out;
-
- switch (input) {
- case VINO_INPUT_COMPOSITE:
- case VINO_INPUT_SVIDEO:
- if (!vino_drvdata->decoder) {
- ret = -EINVAL;
- goto out;
- }
-
- if (vino_drvdata->decoder_owner == VINO_NO_CHANNEL) {
- vino_drvdata->decoder_owner = vcs->channel;
- }
-
- if (vino_drvdata->decoder_owner == vcs->channel) {
- int data_norm = 0;
- v4l2_std_id norm;
-
- ret = decoder_call(video, s_routing,
- vino_get_saa7191_input(input), 0, 0);
- if (ret) {
- vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
- ret = -EINVAL;
- goto out;
- }
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- /* Don't hold spinlocks while auto-detecting norm
- * as it may take a while... */
-
- ret = decoder_call(video, querystd, &norm);
- if (!ret) {
- for (data_norm = 0; data_norm < 3; data_norm++) {
- if (vino_data_norms[data_norm].std & norm)
- break;
- }
- if (data_norm == 3)
- data_norm = VINO_DATA_NORM_PAL;
- ret = decoder_call(core, s_std, norm);
- }
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- if (ret) {
- vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
- ret = -EINVAL;
- goto out;
- }
-
- vcs->input = input;
- vcs->data_norm = data_norm;
- } else {
- if (input != vcs2->input) {
- ret = -EBUSY;
- goto out;
- }
-
- vcs->input = input;
- vcs->data_norm = vcs2->data_norm;
- }
-
- if (vino_drvdata->camera_owner == vcs->channel) {
- /* Transfer the ownership or release the input */
- if (vcs2->input == VINO_INPUT_D1) {
- vino_drvdata->camera_owner = vcs2->channel;
- } else {
- vino_drvdata->camera_owner = VINO_NO_CHANNEL;
- }
- }
- break;
- case VINO_INPUT_D1:
- if (!vino_drvdata->camera) {
- ret = -EINVAL;
- goto out;
- }
-
- if (vino_drvdata->camera_owner == VINO_NO_CHANNEL)
- vino_drvdata->camera_owner = vcs->channel;
-
- if (vino_drvdata->decoder_owner == vcs->channel) {
- /* Transfer the ownership or release the input */
- if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
- (vcs2->input == VINO_INPUT_SVIDEO)) {
- vino_drvdata->decoder_owner = vcs2->channel;
- } else {
- vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
- }
- }
-
- vcs->input = input;
- vcs->data_norm = VINO_DATA_NORM_D1;
- break;
- default:
- ret = -EINVAL;
- goto out;
- }
-
- vino_set_default_clipping(vcs);
- vino_set_default_scaling(vcs);
- vino_set_default_framerate(vcs);
-
- dprintk("vino_set_input(): %s\n", vino_inputs[vcs->input].name);
-
-out:
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return ret;
-}
-
-static void vino_release_input(struct vino_channel_settings *vcs)
-{
- struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
- &vino_drvdata->b : &vino_drvdata->a;
- unsigned long flags;
-
- dprintk("vino_release_input():\n");
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- /* Release ownership of the channel
- * and if the other channel takes input from
- * the same source, transfer the ownership */
- if (vino_drvdata->camera_owner == vcs->channel) {
- if (vcs2->input == VINO_INPUT_D1) {
- vino_drvdata->camera_owner = vcs2->channel;
- } else {
- vino_drvdata->camera_owner = VINO_NO_CHANNEL;
- }
- } else if (vino_drvdata->decoder_owner == vcs->channel) {
- if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
- (vcs2->input == VINO_INPUT_SVIDEO)) {
- vino_drvdata->decoder_owner = vcs2->channel;
- } else {
- vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
- }
- }
- vcs->input = VINO_INPUT_NONE;
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-}
-
-/* execute with input_lock locked */
-static int vino_set_data_norm(struct vino_channel_settings *vcs,
- unsigned int data_norm,
- unsigned long *flags)
-{
- int err = 0;
-
- if (data_norm == vcs->data_norm)
- return 0;
-
- switch (vcs->input) {
- case VINO_INPUT_D1:
- /* only one "norm" supported */
- if (data_norm != VINO_DATA_NORM_D1)
- return -EINVAL;
- break;
- case VINO_INPUT_COMPOSITE:
- case VINO_INPUT_SVIDEO: {
- v4l2_std_id norm;
-
- if ((data_norm != VINO_DATA_NORM_PAL)
- && (data_norm != VINO_DATA_NORM_NTSC)
- && (data_norm != VINO_DATA_NORM_SECAM))
- return -EINVAL;
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags);
-
- /* Don't hold spinlocks while setting norm
- * as it may take a while... */
-
- norm = vino_data_norms[data_norm].std;
- err = decoder_call(core, s_std, norm);
-
- spin_lock_irqsave(&vino_drvdata->input_lock, *flags);
-
- if (err)
- goto out;
-
- vcs->data_norm = data_norm;
-
- vino_set_default_clipping(vcs);
- vino_set_default_scaling(vcs);
- vino_set_default_framerate(vcs);
- break;
- }
- default:
- return -EINVAL;
- }
-
-out:
- return err;
-}
-
-/* V4L2 helper functions */
-
-static int vino_find_data_format(__u32 pixelformat)
-{
- int i;
-
- for (i = 0; i < VINO_DATA_FMT_COUNT; i++) {
- if (vino_data_formats[i].pixelformat == pixelformat)
- return i;
- }
-
- return VINO_DATA_FMT_NONE;
-}
-
-static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index)
-{
- int input = VINO_INPUT_NONE;
- unsigned long flags;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- if (vino_drvdata->decoder && vino_drvdata->camera) {
- switch (index) {
- case 0:
- input = VINO_INPUT_COMPOSITE;
- break;
- case 1:
- input = VINO_INPUT_SVIDEO;
- break;
- case 2:
- input = VINO_INPUT_D1;
- break;
- }
- } else if (vino_drvdata->decoder) {
- switch (index) {
- case 0:
- input = VINO_INPUT_COMPOSITE;
- break;
- case 1:
- input = VINO_INPUT_SVIDEO;
- break;
- }
- } else if (vino_drvdata->camera) {
- switch (index) {
- case 0:
- input = VINO_INPUT_D1;
- break;
- }
- }
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return input;
-}
-
-/* execute with input_lock locked */
-static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
-{
- __u32 index = 0;
- // FIXME: detect when no inputs available
-
- if (vino_drvdata->decoder && vino_drvdata->camera) {
- switch (vcs->input) {
- case VINO_INPUT_COMPOSITE:
- index = 0;
- break;
- case VINO_INPUT_SVIDEO:
- index = 1;
- break;
- case VINO_INPUT_D1:
- index = 2;
- break;
- }
- } else if (vino_drvdata->decoder) {
- switch (vcs->input) {
- case VINO_INPUT_COMPOSITE:
- index = 0;
- break;
- case VINO_INPUT_SVIDEO:
- index = 1;
- break;
- }
- } else if (vino_drvdata->camera) {
- switch (vcs->input) {
- case VINO_INPUT_D1:
- index = 0;
- break;
- }
- }
-
- return index;
-}
-
-/* V4L2 ioctls */
-
-static int vino_querycap(struct file *file, void *__fh,
- struct v4l2_capability *cap)
-{
- memset(cap, 0, sizeof(struct v4l2_capability));
-
- strcpy(cap->driver, vino_driver_name);
- strcpy(cap->card, vino_driver_description);
- strcpy(cap->bus_info, vino_bus_name);
- cap->capabilities =
- V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_STREAMING;
- // V4L2_CAP_OVERLAY, V4L2_CAP_READWRITE
- return 0;
-}
-
-static int vino_enum_input(struct file *file, void *__fh,
- struct v4l2_input *i)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- __u32 index = i->index;
- int input;
- dprintk("requested index = %d\n", index);
-
- input = vino_int_enum_input(vcs, index);
- if (input == VINO_INPUT_NONE)
- return -EINVAL;
-
- i->type = V4L2_INPUT_TYPE_CAMERA;
- i->std = vino_inputs[input].std;
- strcpy(i->name, vino_inputs[input].name);
-
- if (input == VINO_INPUT_COMPOSITE || input == VINO_INPUT_SVIDEO)
- decoder_call(video, g_input_status, &i->status);
- return 0;
-}
-
-static int vino_g_input(struct file *file, void *__fh,
- unsigned int *i)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- __u32 index;
- int input;
- unsigned long flags;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- input = vcs->input;
- index = vino_find_input_index(vcs);
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- dprintk("input = %d\n", input);
-
- if (input == VINO_INPUT_NONE) {
- return -EINVAL;
- }
-
- *i = index;
-
- return 0;
-}
-
-static int vino_s_input(struct file *file, void *__fh,
- unsigned int i)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- int input;
- dprintk("requested input = %d\n", i);
-
- input = vino_int_enum_input(vcs, i);
- if (input == VINO_INPUT_NONE)
- return -EINVAL;
-
- return vino_set_input(vcs, input);
-}
-
-static int vino_querystd(struct file *file, void *__fh,
- v4l2_std_id *std)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- unsigned long flags;
- int err = 0;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- switch (vcs->input) {
- case VINO_INPUT_D1:
- *std = vino_inputs[vcs->input].std;
- break;
- case VINO_INPUT_COMPOSITE:
- case VINO_INPUT_SVIDEO: {
- decoder_call(video, querystd, std);
- break;
- }
- default:
- err = -EINVAL;
- }
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return err;
-}
-
-static int vino_g_std(struct file *file, void *__fh,
- v4l2_std_id *std)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- unsigned long flags;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- *std = vino_data_norms[vcs->data_norm].std;
- dprintk("current standard = %d\n", vcs->data_norm);
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return 0;
-}
-
-static int vino_s_std(struct file *file, void *__fh,
- v4l2_std_id *std)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- if (!vino_is_input_owner(vcs)) {
- ret = -EBUSY;
- goto out;
- }
-
- /* check if the standard is valid for the current input */
- if ((*std) & vino_inputs[vcs->input].std) {
- dprintk("standard accepted\n");
-
- /* change the video norm for SAA7191
- * and accept NTSC for D1 (do nothing) */
-
- if (vcs->input == VINO_INPUT_D1)
- goto out;
-
- if ((*std) & V4L2_STD_PAL) {
- ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL,
- &flags);
- } else if ((*std) & V4L2_STD_NTSC) {
- ret = vino_set_data_norm(vcs, VINO_DATA_NORM_NTSC,
- &flags);
- } else if ((*std) & V4L2_STD_SECAM) {
- ret = vino_set_data_norm(vcs, VINO_DATA_NORM_SECAM,
- &flags);
- } else {
- ret = -EINVAL;
- }
-
- if (ret) {
- ret = -EINVAL;
- }
- } else {
- ret = -EINVAL;
- }
-
-out:
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return ret;
-}
-
-static int vino_enum_fmt_vid_cap(struct file *file, void *__fh,
- struct v4l2_fmtdesc *fd)
-{
- dprintk("format index = %d\n", fd->index);
-
- if (fd->index >= VINO_DATA_FMT_COUNT)
- return -EINVAL;
- dprintk("format name = %s\n", vino_data_formats[fd->index].description);
-
- fd->pixelformat = vino_data_formats[fd->index].pixelformat;
- strcpy(fd->description, vino_data_formats[fd->index].description);
- return 0;
-}
-
-static int vino_try_fmt_vid_cap(struct file *file, void *__fh,
- struct v4l2_format *f)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- struct vino_channel_settings tempvcs;
- unsigned long flags;
- struct v4l2_pix_format *pf = &f->fmt.pix;
-
- dprintk("requested: w = %d, h = %d\n",
- pf->width, pf->height);
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- tempvcs.data_format = vino_find_data_format(pf->pixelformat);
- if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
- tempvcs.data_format = VINO_DATA_FMT_GREY;
- pf->pixelformat =
- vino_data_formats[tempvcs.data_format].
- pixelformat;
- }
-
- /* data format must be set before clipping/scaling */
- vino_set_scaling(&tempvcs, pf->width, pf->height);
-
- dprintk("data format = %s\n",
- vino_data_formats[tempvcs.data_format].description);
-
- pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) /
- tempvcs.decimation;
- pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
- tempvcs.decimation;
-
- pf->field = V4L2_FIELD_INTERLACED;
- pf->bytesperline = tempvcs.line_size;
- pf->sizeimage = tempvcs.line_size *
- (tempvcs.clipping.bottom - tempvcs.clipping.top) /
- tempvcs.decimation;
- pf->colorspace =
- vino_data_formats[tempvcs.data_format].colorspace;
-
- pf->priv = 0;
- return 0;
-}
-
-static int vino_g_fmt_vid_cap(struct file *file, void *__fh,
- struct v4l2_format *f)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- unsigned long flags;
- struct v4l2_pix_format *pf = &f->fmt.pix;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- pf->width = (vcs->clipping.right - vcs->clipping.left) /
- vcs->decimation;
- pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
- vcs->decimation;
- pf->pixelformat =
- vino_data_formats[vcs->data_format].pixelformat;
-
- pf->field = V4L2_FIELD_INTERLACED;
- pf->bytesperline = vcs->line_size;
- pf->sizeimage = vcs->line_size *
- (vcs->clipping.bottom - vcs->clipping.top) /
- vcs->decimation;
- pf->colorspace =
- vino_data_formats[vcs->data_format].colorspace;
-
- pf->priv = 0;
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- return 0;
-}
-
-static int vino_s_fmt_vid_cap(struct file *file, void *__fh,
- struct v4l2_format *f)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- int data_format;
- unsigned long flags;
- struct v4l2_pix_format *pf = &f->fmt.pix;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- data_format = vino_find_data_format(pf->pixelformat);
-
- if (data_format == VINO_DATA_FMT_NONE) {
- vcs->data_format = VINO_DATA_FMT_GREY;
- pf->pixelformat =
- vino_data_formats[vcs->data_format].
- pixelformat;
- } else {
- vcs->data_format = data_format;
- }
-
- /* data format must be set before clipping/scaling */
- vino_set_scaling(vcs, pf->width, pf->height);
-
- dprintk("data format = %s\n",
- vino_data_formats[vcs->data_format].description);
-
- pf->width = vcs->clipping.right - vcs->clipping.left;
- pf->height = vcs->clipping.bottom - vcs->clipping.top;
-
- pf->field = V4L2_FIELD_INTERLACED;
- pf->bytesperline = vcs->line_size;
- pf->sizeimage = vcs->line_size *
- (vcs->clipping.bottom - vcs->clipping.top) /
- vcs->decimation;
- pf->colorspace =
- vino_data_formats[vcs->data_format].colorspace;
-
- pf->priv = 0;
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- return 0;
-}
-
-static int vino_cropcap(struct file *file, void *__fh,
- struct v4l2_cropcap *ccap)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- const struct vino_data_norm *norm;
- unsigned long flags;
-
- switch (ccap->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- norm = &vino_data_norms[vcs->data_norm];
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- ccap->bounds.left = 0;
- ccap->bounds.top = 0;
- ccap->bounds.width = norm->width;
- ccap->bounds.height = norm->height;
- memcpy(&ccap->defrect, &ccap->bounds,
- sizeof(struct v4l2_rect));
-
- ccap->pixelaspect.numerator = 1;
- ccap->pixelaspect.denominator = 1;
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vino_g_crop(struct file *file, void *__fh,
- struct v4l2_crop *c)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- unsigned long flags;
-
- switch (c->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- c->c.left = vcs->clipping.left;
- c->c.top = vcs->clipping.top;
- c->c.width = vcs->clipping.right - vcs->clipping.left;
- c->c.height = vcs->clipping.bottom - vcs->clipping.top;
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vino_s_crop(struct file *file, void *__fh,
- struct v4l2_crop *c)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- unsigned long flags;
-
- switch (c->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- vino_set_clipping(vcs, c->c.left, c->c.top,
- c->c.width, c->c.height);
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vino_g_parm(struct file *file, void *__fh,
- struct v4l2_streamparm *sp)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- unsigned long flags;
- struct v4l2_captureparm *cp = &sp->parm.capture;
-
- cp->capability = V4L2_CAP_TIMEPERFRAME;
- cp->timeperframe.numerator = 1;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- cp->timeperframe.denominator = vcs->fps;
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- /* TODO: cp->readbuffers = xxx; */
-
- return 0;
-}
-
-static int vino_s_parm(struct file *file, void *__fh,
- struct v4l2_streamparm *sp)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- unsigned long flags;
- struct v4l2_captureparm *cp = &sp->parm.capture;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- if ((cp->timeperframe.numerator == 0) ||
- (cp->timeperframe.denominator == 0)) {
- /* reset framerate */
- vino_set_default_framerate(vcs);
- } else {
- vino_set_framerate(vcs, cp->timeperframe.denominator /
- cp->timeperframe.numerator);
- }
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return 0;
-}
-
-static int vino_reqbufs(struct file *file, void *__fh,
- struct v4l2_requestbuffers *rb)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
-
- if (vcs->reading)
- return -EBUSY;
-
- /* TODO: check queue type */
- if (rb->memory != V4L2_MEMORY_MMAP) {
- dprintk("type not mmap\n");
- return -EINVAL;
- }
-
- dprintk("count = %d\n", rb->count);
- if (rb->count > 0) {
- if (vino_is_capturing(vcs)) {
- dprintk("busy, capturing\n");
- return -EBUSY;
- }
-
- if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
- dprintk("busy, buffers still mapped\n");
- return -EBUSY;
- } else {
- vcs->streaming = 0;
- vino_queue_free(&vcs->fb_queue);
- vino_queue_init(&vcs->fb_queue, &rb->count);
- }
- } else {
- vcs->streaming = 0;
- vino_capture_stop(vcs);
- vino_queue_free(&vcs->fb_queue);
- }
-
- return 0;
-}
-
-static void vino_v4l2_get_buffer_status(struct vino_channel_settings *vcs,
- struct vino_framebuffer *fb,
- struct v4l2_buffer *b)
-{
- if (vino_queue_outgoing_contains(&vcs->fb_queue,
- fb->id)) {
- b->flags &= ~V4L2_BUF_FLAG_QUEUED;
- b->flags |= V4L2_BUF_FLAG_DONE;
- } else if (vino_queue_incoming_contains(&vcs->fb_queue,
- fb->id)) {
- b->flags &= ~V4L2_BUF_FLAG_DONE;
- b->flags |= V4L2_BUF_FLAG_QUEUED;
- } else {
- b->flags &= ~(V4L2_BUF_FLAG_DONE |
- V4L2_BUF_FLAG_QUEUED);
- }
-
- b->flags &= ~(V4L2_BUF_FLAG_TIMECODE);
-
- if (fb->map_count > 0)
- b->flags |= V4L2_BUF_FLAG_MAPPED;
-
- b->index = fb->id;
- b->memory = (vcs->fb_queue.type == VINO_MEMORY_MMAP) ?
- V4L2_MEMORY_MMAP : V4L2_MEMORY_USERPTR;
- b->m.offset = fb->offset;
- b->bytesused = fb->data_size;
- b->length = fb->size;
- b->field = V4L2_FIELD_INTERLACED;
- b->sequence = fb->frame_counter;
- memcpy(&b->timestamp, &fb->timestamp,
- sizeof(struct timeval));
- // b->input ?
-
- dprintk("buffer %d: length = %d, bytesused = %d, offset = %d\n",
- fb->id, fb->size, fb->data_size, fb->offset);
-}
-
-static int vino_querybuf(struct file *file, void *__fh,
- struct v4l2_buffer *b)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- struct vino_framebuffer *fb;
-
- if (vcs->reading)
- return -EBUSY;
-
- /* TODO: check queue type */
- if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
- dprintk("invalid index = %d\n",
- b->index);
- return -EINVAL;
- }
-
- fb = vino_queue_get_buffer(&vcs->fb_queue,
- b->index);
- if (fb == NULL) {
- dprintk("vino_queue_get_buffer() failed");
- return -EINVAL;
- }
-
- vino_v4l2_get_buffer_status(vcs, fb, b);
-
- return 0;
-}
-
-static int vino_qbuf(struct file *file, void *__fh,
- struct v4l2_buffer *b)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- struct vino_framebuffer *fb;
- int ret;
-
- if (vcs->reading)
- return -EBUSY;
-
- /* TODO: check queue type */
- if (b->memory != V4L2_MEMORY_MMAP) {
- dprintk("type not mmap\n");
- return -EINVAL;
- }
-
- fb = vino_capture_enqueue(vcs, b->index);
- if (fb == NULL)
- return -EINVAL;
-
- vino_v4l2_get_buffer_status(vcs, fb, b);
-
- if (vcs->streaming) {
- ret = vino_capture_next(vcs, 1);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static int vino_dqbuf(struct file *file, void *__fh,
- struct v4l2_buffer *b)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- unsigned int nonblocking = file->f_flags & O_NONBLOCK;
- struct vino_framebuffer *fb;
- unsigned int incoming, outgoing;
- int err;
-
- if (vcs->reading)
- return -EBUSY;
-
- /* TODO: check queue type */
-
- err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
- if (err) {
- dprintk("vino_queue_get_incoming() failed\n");
- return -EINVAL;
- }
- err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
- if (err) {
- dprintk("vino_queue_get_outgoing() failed\n");
- return -EINVAL;
- }
-
- dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
-
- if (outgoing == 0) {
- if (incoming == 0) {
- dprintk("no incoming or outgoing buffers\n");
- return -EINVAL;
- }
- if (nonblocking) {
- dprintk("non-blocking I/O was selected and "
- "there are no buffers to dequeue\n");
- return -EAGAIN;
- }
-
- err = vino_wait_for_frame(vcs);
- if (err) {
- err = vino_wait_for_frame(vcs);
- if (err) {
- /* interrupted or no frames captured because of
- * frame skipping */
- /* vino_capture_failed(vcs); */
- return -EIO;
- }
- }
- }
-
- fb = vino_queue_remove(&vcs->fb_queue, &b->index);
- if (fb == NULL) {
- dprintk("vino_queue_remove() failed\n");
- return -EINVAL;
- }
-
- err = vino_check_buffer(vcs, fb);
-
- vino_v4l2_get_buffer_status(vcs, fb, b);
-
- if (err)
- return -EIO;
-
- return 0;
-}
-
-static int vino_streamon(struct file *file, void *__fh,
- enum v4l2_buf_type i)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- unsigned int incoming;
- int ret;
- if (vcs->reading)
- return -EBUSY;
-
- if (vcs->streaming)
- return 0;
-
- // TODO: check queue type
-
- if (vino_queue_get_length(&vcs->fb_queue) < 1) {
- dprintk("no buffers allocated\n");
- return -EINVAL;
- }
-
- ret = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
- if (ret) {
- dprintk("vino_queue_get_incoming() failed\n");
- return -EINVAL;
- }
-
- vcs->streaming = 1;
-
- if (incoming > 0) {
- ret = vino_capture_next(vcs, 1);
- if (ret) {
- vcs->streaming = 0;
-
- dprintk("couldn't start capture\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int vino_streamoff(struct file *file, void *__fh,
- enum v4l2_buf_type i)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- if (vcs->reading)
- return -EBUSY;
-
- if (!vcs->streaming)
- return 0;
-
- vcs->streaming = 0;
- vino_capture_stop(vcs);
-
- return 0;
-}
-
-static int vino_queryctrl(struct file *file, void *__fh,
- struct v4l2_queryctrl *queryctrl)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- unsigned long flags;
- int i;
- int err = 0;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- switch (vcs->input) {
- case VINO_INPUT_D1:
- for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
- if (vino_indycam_v4l2_controls[i].id ==
- queryctrl->id) {
- memcpy(queryctrl,
- &vino_indycam_v4l2_controls[i],
- sizeof(struct v4l2_queryctrl));
- queryctrl->reserved[0] = 0;
- goto found;
- }
- }
-
- err = -EINVAL;
- break;
- case VINO_INPUT_COMPOSITE:
- case VINO_INPUT_SVIDEO:
- for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
- if (vino_saa7191_v4l2_controls[i].id ==
- queryctrl->id) {
- memcpy(queryctrl,
- &vino_saa7191_v4l2_controls[i],
- sizeof(struct v4l2_queryctrl));
- queryctrl->reserved[0] = 0;
- goto found;
- }
- }
-
- err = -EINVAL;
- break;
- default:
- err = -EINVAL;
- }
-
- found:
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return err;
-}
-
-static int vino_g_ctrl(struct file *file, void *__fh,
- struct v4l2_control *control)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- unsigned long flags;
- int i;
- int err = 0;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- switch (vcs->input) {
- case VINO_INPUT_D1: {
- err = -EINVAL;
- for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
- if (vino_indycam_v4l2_controls[i].id == control->id) {
- err = 0;
- break;
- }
- }
-
- if (err)
- goto out;
-
- err = camera_call(core, g_ctrl, control);
- if (err)
- err = -EINVAL;
- break;
- }
- case VINO_INPUT_COMPOSITE:
- case VINO_INPUT_SVIDEO: {
- err = -EINVAL;
- for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
- if (vino_saa7191_v4l2_controls[i].id == control->id) {
- err = 0;
- break;
- }
- }
-
- if (err)
- goto out;
-
- err = decoder_call(core, g_ctrl, control);
- if (err)
- err = -EINVAL;
- break;
- }
- default:
- err = -EINVAL;
- }
-
-out:
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return err;
-}
-
-static int vino_s_ctrl(struct file *file, void *__fh,
- struct v4l2_control *control)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- unsigned long flags;
- int i;
- int err = 0;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- if (!vino_is_input_owner(vcs)) {
- err = -EBUSY;
- goto out;
- }
-
- switch (vcs->input) {
- case VINO_INPUT_D1: {
- err = -EINVAL;
- for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
- if (vino_indycam_v4l2_controls[i].id == control->id) {
- err = 0;
- break;
- }
- }
- if (err)
- goto out;
- if (control->value < vino_indycam_v4l2_controls[i].minimum ||
- control->value > vino_indycam_v4l2_controls[i].maximum) {
- err = -ERANGE;
- goto out;
- }
- err = camera_call(core, s_ctrl, control);
- if (err)
- err = -EINVAL;
- break;
- }
- case VINO_INPUT_COMPOSITE:
- case VINO_INPUT_SVIDEO: {
- err = -EINVAL;
- for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
- if (vino_saa7191_v4l2_controls[i].id == control->id) {
- err = 0;
- break;
- }
- }
- if (err)
- goto out;
- if (control->value < vino_saa7191_v4l2_controls[i].minimum ||
- control->value > vino_saa7191_v4l2_controls[i].maximum) {
- err = -ERANGE;
- goto out;
- }
-
- err = decoder_call(core, s_ctrl, control);
- if (err)
- err = -EINVAL;
- break;
- }
- default:
- err = -EINVAL;
- }
-
-out:
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return err;
-}
-
-/* File operations */
-
-static int vino_open(struct file *file)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- int ret = 0;
- dprintk("open(): channel = %c\n",
- (vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B');
-
- mutex_lock(&vcs->mutex);
-
- if (vcs->users) {
- dprintk("open(): driver busy\n");
- ret = -EBUSY;
- goto out;
- }
-
- ret = vino_acquire_input(vcs);
- if (ret) {
- dprintk("open(): vino_acquire_input() failed\n");
- goto out;
- }
-
- vcs->users++;
-
- out:
- mutex_unlock(&vcs->mutex);
-
- dprintk("open(): %s!\n", ret ? "failed" : "complete");
-
- return ret;
-}
-
-static int vino_close(struct file *file)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- dprintk("close():\n");
-
- mutex_lock(&vcs->mutex);
-
- vcs->users--;
-
- if (!vcs->users) {
- vino_release_input(vcs);
-
- /* stop DMA and free buffers */
- vino_capture_stop(vcs);
- vino_queue_free(&vcs->fb_queue);
- }
-
- mutex_unlock(&vcs->mutex);
-
- return 0;
-}
-
-static void vino_vm_open(struct vm_area_struct *vma)
-{
- struct vino_framebuffer *fb = vma->vm_private_data;
-
- fb->map_count++;
- dprintk("vino_vm_open(): count = %d\n", fb->map_count);
-}
-
-static void vino_vm_close(struct vm_area_struct *vma)
-{
- struct vino_framebuffer *fb = vma->vm_private_data;
-
- fb->map_count--;
- dprintk("vino_vm_close(): count = %d\n", fb->map_count);
-}
-
-static const struct vm_operations_struct vino_vm_ops = {
- .open = vino_vm_open,
- .close = vino_vm_close,
-};
-
-static int vino_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
-
- unsigned long start = vma->vm_start;
- unsigned long size = vma->vm_end - vma->vm_start;
- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-
- struct vino_framebuffer *fb = NULL;
- unsigned int i, length;
- int ret = 0;
-
- dprintk("mmap():\n");
-
- // TODO: reject mmap if already mapped
-
- if (mutex_lock_interruptible(&vcs->mutex))
- return -EINTR;
-
- if (vcs->reading) {
- ret = -EBUSY;
- goto out;
- }
-
- // TODO: check queue type
-
- if (!(vma->vm_flags & VM_WRITE)) {
- dprintk("mmap(): app bug: PROT_WRITE please\n");
- ret = -EINVAL;
- goto out;
- }
- if (!(vma->vm_flags & VM_SHARED)) {
- dprintk("mmap(): app bug: MAP_SHARED please\n");
- ret = -EINVAL;
- goto out;
- }
-
- /* find the correct buffer using offset */
- length = vino_queue_get_length(&vcs->fb_queue);
- if (length == 0) {
- dprintk("mmap(): queue not initialized\n");
- ret = -EINVAL;
- goto out;
- }
-
- for (i = 0; i < length; i++) {
- fb = vino_queue_get_buffer(&vcs->fb_queue, i);
- if (fb == NULL) {
- dprintk("mmap(): vino_queue_get_buffer() failed\n");
- ret = -EINVAL;
- goto out;
- }
-
- if (fb->offset == offset)
- goto found;
- }
-
- dprintk("mmap(): invalid offset = %lu\n", offset);
- ret = -EINVAL;
- goto out;
-
-found:
- dprintk("mmap(): buffer = %d\n", i);
-
- if (size > (fb->desc_table.page_count * PAGE_SIZE)) {
- dprintk("mmap(): failed: size = %lu > %lu\n",
- size, fb->desc_table.page_count * PAGE_SIZE);
- ret = -EINVAL;
- goto out;
- }
-
- for (i = 0; i < fb->desc_table.page_count; i++) {
- unsigned long pfn =
- virt_to_phys((void *)fb->desc_table.virtual[i]) >>
- PAGE_SHIFT;
-
- if (size < PAGE_SIZE)
- break;
-
- // protection was: PAGE_READONLY
- if (remap_pfn_range(vma, start, pfn, PAGE_SIZE,
- vma->vm_page_prot)) {
- dprintk("mmap(): remap_pfn_range() failed\n");
- ret = -EAGAIN;
- goto out;
- }
-
- start += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- fb->map_count = 1;
-
- vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
- vma->vm_flags &= ~VM_IO;
- vma->vm_private_data = fb;
- vma->vm_file = file;
- vma->vm_ops = &vino_vm_ops;
-
-out:
- mutex_unlock(&vcs->mutex);
-
- return ret;
-}
-
-static unsigned int vino_poll(struct file *file, poll_table *pt)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- unsigned int outgoing;
- unsigned int ret = 0;
-
- // lock mutex (?)
- // TODO: this has to be corrected for different read modes
-
- dprintk("poll():\n");
-
- if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
- dprintk("poll(): vino_queue_get_outgoing() failed\n");
- ret = POLLERR;
- goto error;
- }
- if (outgoing > 0)
- goto over;
-
- poll_wait(file, &vcs->fb_queue.frame_wait_queue, pt);
-
- if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
- dprintk("poll(): vino_queue_get_outgoing() failed\n");
- ret = POLLERR;
- goto error;
- }
-
-over:
- dprintk("poll(): data %savailable\n",
- (outgoing > 0) ? "" : "not ");
-
- if (outgoing > 0)
- ret = POLLIN | POLLRDNORM;
-
-error:
- return ret;
-}
-
-static long vino_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
- long ret;
-
- if (mutex_lock_interruptible(&vcs->mutex))
- return -EINTR;
-
- ret = video_ioctl2(file, cmd, arg);
-
- mutex_unlock(&vcs->mutex);
-
- return ret;
-}
-
-/* Initialization and cleanup */
-
-/* __initdata */
-static int vino_init_stage;
-
-const struct v4l2_ioctl_ops vino_ioctl_ops = {
- .vidioc_enum_fmt_vid_cap = vino_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vino_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vino_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vino_try_fmt_vid_cap,
- .vidioc_querycap = vino_querycap,
- .vidioc_enum_input = vino_enum_input,
- .vidioc_g_input = vino_g_input,
- .vidioc_s_input = vino_s_input,
- .vidioc_g_std = vino_g_std,
- .vidioc_s_std = vino_s_std,
- .vidioc_querystd = vino_querystd,
- .vidioc_cropcap = vino_cropcap,
- .vidioc_s_crop = vino_s_crop,
- .vidioc_g_crop = vino_g_crop,
- .vidioc_s_parm = vino_s_parm,
- .vidioc_g_parm = vino_g_parm,
- .vidioc_reqbufs = vino_reqbufs,
- .vidioc_querybuf = vino_querybuf,
- .vidioc_qbuf = vino_qbuf,
- .vidioc_dqbuf = vino_dqbuf,
- .vidioc_streamon = vino_streamon,
- .vidioc_streamoff = vino_streamoff,
- .vidioc_queryctrl = vino_queryctrl,
- .vidioc_g_ctrl = vino_g_ctrl,
- .vidioc_s_ctrl = vino_s_ctrl,
-};
-
-static const struct v4l2_file_operations vino_fops = {
- .owner = THIS_MODULE,
- .open = vino_open,
- .release = vino_close,
- .unlocked_ioctl = vino_ioctl,
- .mmap = vino_mmap,
- .poll = vino_poll,
-};
-
-static struct video_device vdev_template = {
- .name = "NOT SET",
- .fops = &vino_fops,
- .ioctl_ops = &vino_ioctl_ops,
- .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
-};
-
-static void vino_module_cleanup(int stage)
-{
- switch(stage) {
- case 11:
- video_unregister_device(vino_drvdata->b.vdev);
- vino_drvdata->b.vdev = NULL;
- case 10:
- video_unregister_device(vino_drvdata->a.vdev);
- vino_drvdata->a.vdev = NULL;
- case 9:
- i2c_del_adapter(&vino_i2c_adapter);
- case 8:
- free_irq(SGI_VINO_IRQ, NULL);
- case 7:
- if (vino_drvdata->b.vdev) {
- video_device_release(vino_drvdata->b.vdev);
- vino_drvdata->b.vdev = NULL;
- }
- case 6:
- if (vino_drvdata->a.vdev) {
- video_device_release(vino_drvdata->a.vdev);
- vino_drvdata->a.vdev = NULL;
- }
- case 5:
- /* all entries in dma_cpu dummy table have the same address */
- dma_unmap_single(NULL,
- vino_drvdata->dummy_desc_table.dma_cpu[0],
- PAGE_SIZE, DMA_FROM_DEVICE);
- dma_free_coherent(NULL, VINO_DUMMY_DESC_COUNT
- * sizeof(dma_addr_t),
- (void *)vino_drvdata->
- dummy_desc_table.dma_cpu,
- vino_drvdata->dummy_desc_table.dma);
- case 4:
- free_page(vino_drvdata->dummy_page);
- case 3:
- v4l2_device_unregister(&vino_drvdata->v4l2_dev);
- case 2:
- kfree(vino_drvdata);
- case 1:
- iounmap(vino);
- case 0:
- break;
- default:
- dprintk("vino_module_cleanup(): invalid cleanup stage = %d\n",
- stage);
- }
-}
-
-static int vino_probe(void)
-{
- unsigned long rev_id;
-
- if (ip22_is_fullhouse()) {
- printk(KERN_ERR "VINO doesn't exist in IP22 Fullhouse\n");
- return -ENODEV;
- }
-
- if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
- printk(KERN_ERR "VINO is not found (EISA BUS not present)\n");
- return -ENODEV;
- }
-
- vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino));
- if (!vino) {
- printk(KERN_ERR "VINO: ioremap() failed\n");
- return -EIO;
- }
- vino_init_stage++;
-
- if (get_dbe(rev_id, &(vino->rev_id))) {
- printk(KERN_ERR "Failed to read VINO revision register\n");
- vino_module_cleanup(vino_init_stage);
- return -ENODEV;
- }
-
- if (VINO_ID_VALUE(rev_id) != VINO_CHIP_ID) {
- printk(KERN_ERR "Unknown VINO chip ID (Rev/ID: 0x%02lx)\n",
- rev_id);
- vino_module_cleanup(vino_init_stage);
- return -ENODEV;
- }
-
- printk(KERN_INFO "VINO revision %ld found\n", VINO_REV_NUM(rev_id));
-
- return 0;
-}
-
-static int vino_init(void)
-{
- dma_addr_t dma_dummy_address;
- int err;
- int i;
-
- vino_drvdata = kzalloc(sizeof(struct vino_settings), GFP_KERNEL);
- if (!vino_drvdata) {
- vino_module_cleanup(vino_init_stage);
- return -ENOMEM;
- }
- vino_init_stage++;
- strlcpy(vino_drvdata->v4l2_dev.name, "vino",
- sizeof(vino_drvdata->v4l2_dev.name));
- err = v4l2_device_register(NULL, &vino_drvdata->v4l2_dev);
- if (err)
- return err;
- vino_init_stage++;
-
- /* create a dummy dma descriptor */
- vino_drvdata->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
- if (!vino_drvdata->dummy_page) {
- vino_module_cleanup(vino_init_stage);
- return -ENOMEM;
- }
- vino_init_stage++;
-
- // TODO: use page_count in dummy_desc_table
-
- vino_drvdata->dummy_desc_table.dma_cpu =
- dma_alloc_coherent(NULL,
- VINO_DUMMY_DESC_COUNT * sizeof(dma_addr_t),
- &vino_drvdata->dummy_desc_table.dma,
- GFP_KERNEL | GFP_DMA);
- if (!vino_drvdata->dummy_desc_table.dma_cpu) {
- vino_module_cleanup(vino_init_stage);
- return -ENOMEM;
- }
- vino_init_stage++;
-
- dma_dummy_address = dma_map_single(NULL,
- (void *)vino_drvdata->dummy_page,
- PAGE_SIZE, DMA_FROM_DEVICE);
- for (i = 0; i < VINO_DUMMY_DESC_COUNT; i++) {
- vino_drvdata->dummy_desc_table.dma_cpu[i] = dma_dummy_address;
- }
-
- /* initialize VINO */
-
- vino->control = 0;
- vino->a.next_4_desc = vino_drvdata->dummy_desc_table.dma;
- vino->b.next_4_desc = vino_drvdata->dummy_desc_table.dma;
- udelay(VINO_DESC_FETCH_DELAY);
-
- vino->intr_status = 0;
-
- vino->a.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT;
- vino->b.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT;
-
- return 0;
-}
-
-static int vino_init_channel_settings(struct vino_channel_settings *vcs,
- unsigned int channel, const char *name)
-{
- vcs->channel = channel;
- vcs->input = VINO_INPUT_NONE;
- vcs->alpha = 0;
- vcs->users = 0;
- vcs->data_format = VINO_DATA_FMT_GREY;
- vcs->data_norm = VINO_DATA_NORM_NTSC;
- vcs->decimation = 1;
- vino_set_default_clipping(vcs);
- vino_set_default_framerate(vcs);
-
- vcs->capturing = 0;
-
- mutex_init(&vcs->mutex);
- spin_lock_init(&vcs->capture_lock);
-
- mutex_init(&vcs->fb_queue.queue_mutex);
- spin_lock_init(&vcs->fb_queue.queue_lock);
- init_waitqueue_head(&vcs->fb_queue.frame_wait_queue);
-
- vcs->vdev = video_device_alloc();
- if (!vcs->vdev) {
- vino_module_cleanup(vino_init_stage);
- return -ENOMEM;
- }
- vino_init_stage++;
-
- memcpy(vcs->vdev, &vdev_template,
- sizeof(struct video_device));
- strcpy(vcs->vdev->name, name);
- vcs->vdev->release = video_device_release;
- vcs->vdev->v4l2_dev = &vino_drvdata->v4l2_dev;
-
- video_set_drvdata(vcs->vdev, vcs);
-
- return 0;
-}
-
-static int __init vino_module_init(void)
-{
- int ret;
-
- printk(KERN_INFO "SGI VINO driver version %s\n",
- VINO_MODULE_VERSION);
-
- ret = vino_probe();
- if (ret)
- return ret;
-
- ret = vino_init();
- if (ret)
- return ret;
-
- /* initialize data structures */
-
- spin_lock_init(&vino_drvdata->vino_lock);
- spin_lock_init(&vino_drvdata->input_lock);
-
- ret = vino_init_channel_settings(&vino_drvdata->a, VINO_CHANNEL_A,
- vino_vdev_name_a);
- if (ret)
- return ret;
-
- ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B,
- vino_vdev_name_b);
- if (ret)
- return ret;
-
- /* initialize hardware and register V4L devices */
-
- ret = request_irq(SGI_VINO_IRQ, vino_interrupt, 0,
- vino_driver_description, NULL);
- if (ret) {
- printk(KERN_ERR "VINO: requesting IRQ %02d failed\n",
- SGI_VINO_IRQ);
- vino_module_cleanup(vino_init_stage);
- return -EAGAIN;
- }
- vino_init_stage++;
-
- ret = i2c_add_adapter(&vino_i2c_adapter);
- if (ret) {
- printk(KERN_ERR "VINO I2C bus registration failed\n");
- vino_module_cleanup(vino_init_stage);
- return ret;
- }
- i2c_set_adapdata(&vino_i2c_adapter, &vino_drvdata->v4l2_dev);
- vino_init_stage++;
-
- ret = video_register_device(vino_drvdata->a.vdev,
- VFL_TYPE_GRABBER, -1);
- if (ret < 0) {
- printk(KERN_ERR "VINO channel A Video4Linux-device "
- "registration failed\n");
- vino_module_cleanup(vino_init_stage);
- return -EINVAL;
- }
- vino_init_stage++;
-
- ret = video_register_device(vino_drvdata->b.vdev,
- VFL_TYPE_GRABBER, -1);
- if (ret < 0) {
- printk(KERN_ERR "VINO channel B Video4Linux-device "
- "registration failed\n");
- vino_module_cleanup(vino_init_stage);
- return -EINVAL;
- }
- vino_init_stage++;
-
- vino_drvdata->decoder =
- v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
- "saa7191", 0, I2C_ADDRS(0x45));
- vino_drvdata->camera =
- v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
- "indycam", 0, I2C_ADDRS(0x2b));
-
- dprintk("init complete!\n");
-
- return 0;
-}
-
-static void __exit vino_module_exit(void)
-{
- dprintk("exiting, stage = %d ...\n", vino_init_stage);
- vino_module_cleanup(vino_init_stage);
- dprintk("cleanup complete, exit!\n");
-}
-
-module_init(vino_module_init);
-module_exit(vino_module_exit);
diff --git a/drivers/media/video/vino.h b/drivers/media/video/vino.h
deleted file mode 100644
index de2d615ae7c..00000000000
--- a/drivers/media/video/vino.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Driver for the VINO (Video In No Out) system found in SGI Indys.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * Copyright (C) 1999 Ulf Karlsson <ulfc@bun.falkenberg.se>
- * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
- */
-
-#ifndef _VINO_H_
-#define _VINO_H_
-
-#define VINO_BASE 0x00080000 /* Vino is in the EISA address space,
- * but it is not an EISA bus card */
-#define VINO_PAGE_SIZE 4096
-
-struct sgi_vino_channel {
- u32 _pad_alpha;
- volatile u32 alpha;
-
-#define VINO_CLIP_X(x) ((x) & 0x3ff) /* bits 0:9 */
-#define VINO_CLIP_ODD(x) (((x) & 0x1ff) << 10) /* bits 10:18 */
-#define VINO_CLIP_EVEN(x) (((x) & 0x1ff) << 19) /* bits 19:27 */
- u32 _pad_clip_start;
- volatile u32 clip_start;
- u32 _pad_clip_end;
- volatile u32 clip_end;
-
-#define VINO_FRAMERT_FULL 0xfff
-#define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */
-#define VINO_FRAMERT_RT(x) (((x) & 0xfff) << 1) /* bits 1:12 */
- u32 _pad_frame_rate;
- volatile u32 frame_rate;
-
- u32 _pad_field_counter;
- volatile u32 field_counter;
- u32 _pad_line_size;
- volatile u32 line_size;
- u32 _pad_line_count;
- volatile u32 line_count;
- u32 _pad_page_index;
- volatile u32 page_index;
- u32 _pad_next_4_desc;
- volatile u32 next_4_desc;
- u32 _pad_start_desc_tbl;
- volatile u32 start_desc_tbl;
-
-#define VINO_DESC_JUMP (1<<30)
-#define VINO_DESC_STOP (1<<31)
-#define VINO_DESC_VALID (1<<32)
- u32 _pad_desc_0;
- volatile u32 desc_0;
- u32 _pad_desc_1;
- volatile u32 desc_1;
- u32 _pad_desc_2;
- volatile u32 desc_2;
- u32 _pad_Bdesc_3;
- volatile u32 desc_3;
-
- u32 _pad_fifo_thres;
- volatile u32 fifo_thres;
- u32 _pad_fifo_read;
- volatile u32 fifo_read;
- u32 _pad_fifo_write;
- volatile u32 fifo_write;
-};
-
-struct sgi_vino {
-#define VINO_CHIP_ID 0xb
-#define VINO_REV_NUM(x) ((x) & 0x0f)
-#define VINO_ID_VALUE(x) (((x) & 0xf0) >> 4)
- u32 _pad_rev_id;
- volatile u32 rev_id;
-
-#define VINO_CTRL_LITTLE_ENDIAN (1<<0)
-#define VINO_CTRL_A_EOF_INT (1<<1) /* Field transferred int */
-#define VINO_CTRL_A_FIFO_INT (1<<2) /* FIFO overflow int */
-#define VINO_CTRL_A_EOD_INT (1<<3) /* End of desc table int */
-#define VINO_CTRL_A_INT (VINO_CTRL_A_EOF_INT | \
- VINO_CTRL_A_FIFO_INT | \
- VINO_CTRL_A_EOD_INT)
-#define VINO_CTRL_B_EOF_INT (1<<4) /* Field transferred int */
-#define VINO_CTRL_B_FIFO_INT (1<<5) /* FIFO overflow int */
-#define VINO_CTRL_B_EOD_INT (1<<6) /* End of desc table int */
-#define VINO_CTRL_B_INT (VINO_CTRL_B_EOF_INT | \
- VINO_CTRL_B_FIFO_INT | \
- VINO_CTRL_B_EOD_INT)
-#define VINO_CTRL_A_DMA_ENBL (1<<7)
-#define VINO_CTRL_A_INTERLEAVE_ENBL (1<<8)
-#define VINO_CTRL_A_SYNC_ENBL (1<<9)
-#define VINO_CTRL_A_SELECT (1<<10) /* 1=D1 0=Philips */
-#define VINO_CTRL_A_RGB (1<<11) /* 1=RGB 0=YUV */
-#define VINO_CTRL_A_LUMA_ONLY (1<<12)
-#define VINO_CTRL_A_DEC_ENBL (1<<13) /* Decimation */
-#define VINO_CTRL_A_DEC_SCALE_MASK 0x1c000 /* bits 14:17 */
-#define VINO_CTRL_A_DEC_SCALE_SHIFT (14)
-#define VINO_CTRL_A_DEC_HOR_ONLY (1<<17) /* Horizontal only */
-#define VINO_CTRL_A_DITHER (1<<18) /* 24 -> 8 bit dither */
-#define VINO_CTRL_B_DMA_ENBL (1<<19)
-#define VINO_CTRL_B_INTERLEAVE_ENBL (1<<20)
-#define VINO_CTRL_B_SYNC_ENBL (1<<21)
-#define VINO_CTRL_B_SELECT (1<<22) /* 1=D1 0=Philips */
-#define VINO_CTRL_B_RGB (1<<23) /* 1=RGB 0=YUV */
-#define VINO_CTRL_B_LUMA_ONLY (1<<24)
-#define VINO_CTRL_B_DEC_ENBL (1<<25) /* Decimation */
-#define VINO_CTRL_B_DEC_SCALE_MASK 0x1c000000 /* bits 26:28 */
-#define VINO_CTRL_B_DEC_SCALE_SHIFT (26)
-#define VINO_CTRL_B_DEC_HOR_ONLY (1<<29) /* Decimation horizontal only */
-#define VINO_CTRL_B_DITHER (1<<30) /* ChanB 24 -> 8 bit dither */
- u32 _pad_control;
- volatile u32 control;
-
-#define VINO_INTSTAT_A_EOF (1<<0) /* Field transferred int */
-#define VINO_INTSTAT_A_FIFO (1<<1) /* FIFO overflow int */
-#define VINO_INTSTAT_A_EOD (1<<2) /* End of desc table int */
-#define VINO_INTSTAT_A (VINO_INTSTAT_A_EOF | \
- VINO_INTSTAT_A_FIFO | \
- VINO_INTSTAT_A_EOD)
-#define VINO_INTSTAT_B_EOF (1<<3) /* Field transferred int */
-#define VINO_INTSTAT_B_FIFO (1<<4) /* FIFO overflow int */
-#define VINO_INTSTAT_B_EOD (1<<5) /* End of desc table int */
-#define VINO_INTSTAT_B (VINO_INTSTAT_B_EOF | \
- VINO_INTSTAT_B_FIFO | \
- VINO_INTSTAT_B_EOD)
- u32 _pad_intr_status;
- volatile u32 intr_status;
-
- u32 _pad_i2c_control;
- volatile u32 i2c_control;
- u32 _pad_i2c_data;
- volatile u32 i2c_data;
-
- struct sgi_vino_channel a;
- struct sgi_vino_channel b;
-};
-
-#endif
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
deleted file mode 100644
index a05494b71b2..00000000000
--- a/drivers/media/video/vivi.c
+++ /dev/null
@@ -1,1385 +0,0 @@
-/*
- * Virtual Video driver - This code emulates a real video device with v4l2 api
- *
- * Copyright (c) 2006 by:
- * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
- * Ted Walther <ted--a.t--enumera.com>
- * John Sokol <sokol--a.t--videotechnology.com>
- * http://v4l.videotechnology.com/
- *
- * Conversion to videobuf2 by Pawel Osciak & Marek Szyprowski
- * Copyright (c) 2010 Samsung Electronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the BSD Licence, GNU General Public License
- * as published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version
- */
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/font.h>
-#include <linux/mutex.h>
-#include <linux/videodev2.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-#include <media/videobuf2-vmalloc.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-common.h>
-
-#define VIVI_MODULE_NAME "vivi"
-
-/* Wake up at about 30 fps */
-#define WAKE_NUMERATOR 30
-#define WAKE_DENOMINATOR 1001
-#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
-
-#define MAX_WIDTH 1920
-#define MAX_HEIGHT 1200
-
-#define VIVI_VERSION "0.8.1"
-
-MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
-MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION(VIVI_VERSION);
-
-static unsigned video_nr = -1;
-module_param(video_nr, uint, 0644);
-MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
-
-static unsigned n_devs = 1;
-module_param(n_devs, uint, 0644);
-MODULE_PARM_DESC(n_devs, "number of video devices to create");
-
-static unsigned debug;
-module_param(debug, uint, 0644);
-MODULE_PARM_DESC(debug, "activates debug info");
-
-static unsigned int vid_limit = 16;
-module_param(vid_limit, uint, 0644);
-MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
-
-/* Global font descriptor */
-static const u8 *font8x16;
-
-#define dprintk(dev, level, fmt, arg...) \
- v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
-
-/* ------------------------------------------------------------------
- Basic structures
- ------------------------------------------------------------------*/
-
-struct vivi_fmt {
- char *name;
- u32 fourcc; /* v4l2 format id */
- int depth;
-};
-
-static struct vivi_fmt formats[] = {
- {
- .name = "4:2:2, packed, YUYV",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = 16,
- },
- {
- .name = "4:2:2, packed, UYVY",
- .fourcc = V4L2_PIX_FMT_UYVY,
- .depth = 16,
- },
- {
- .name = "4:2:2, packed, YVYU",
- .fourcc = V4L2_PIX_FMT_YVYU,
- .depth = 16,
- },
- {
- .name = "4:2:2, packed, VYUY",
- .fourcc = V4L2_PIX_FMT_VYUY,
- .depth = 16,
- },
- {
- .name = "RGB565 (LE)",
- .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
- .depth = 16,
- },
- {
- .name = "RGB565 (BE)",
- .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
- .depth = 16,
- },
- {
- .name = "RGB555 (LE)",
- .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
- .depth = 16,
- },
- {
- .name = "RGB555 (BE)",
- .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
- .depth = 16,
- },
- {
- .name = "RGB24 (LE)",
- .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */
- .depth = 24,
- },
- {
- .name = "RGB24 (BE)",
- .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */
- .depth = 24,
- },
- {
- .name = "RGB32 (LE)",
- .fourcc = V4L2_PIX_FMT_RGB32, /* argb */
- .depth = 32,
- },
- {
- .name = "RGB32 (BE)",
- .fourcc = V4L2_PIX_FMT_BGR32, /* bgra */
- .depth = 32,
- },
-};
-
-static struct vivi_fmt *get_format(struct v4l2_format *f)
-{
- struct vivi_fmt *fmt;
- unsigned int k;
-
- for (k = 0; k < ARRAY_SIZE(formats); k++) {
- fmt = &formats[k];
- if (fmt->fourcc == f->fmt.pix.pixelformat)
- break;
- }
-
- if (k == ARRAY_SIZE(formats))
- return NULL;
-
- return &formats[k];
-}
-
-/* buffer for one video frame */
-struct vivi_buffer {
- /* common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
- struct list_head list;
- struct vivi_fmt *fmt;
-};
-
-struct vivi_dmaqueue {
- struct list_head active;
-
- /* thread for generating video stream*/
- struct task_struct *kthread;
- wait_queue_head_t wq;
- /* Counters to control fps rate */
- int frame;
- int ini_jiffies;
-};
-
-static LIST_HEAD(vivi_devlist);
-
-struct vivi_dev {
- struct list_head vivi_devlist;
- struct v4l2_device v4l2_dev;
- struct v4l2_ctrl_handler ctrl_handler;
- struct video_device vdev;
-
- /* controls */
- struct v4l2_ctrl *brightness;
- struct v4l2_ctrl *contrast;
- struct v4l2_ctrl *saturation;
- struct v4l2_ctrl *hue;
- struct {
- /* autogain/gain cluster */
- struct v4l2_ctrl *autogain;
- struct v4l2_ctrl *gain;
- };
- struct v4l2_ctrl *volume;
- struct v4l2_ctrl *alpha;
- struct v4l2_ctrl *button;
- struct v4l2_ctrl *boolean;
- struct v4l2_ctrl *int32;
- struct v4l2_ctrl *int64;
- struct v4l2_ctrl *menu;
- struct v4l2_ctrl *string;
- struct v4l2_ctrl *bitmask;
- struct v4l2_ctrl *int_menu;
-
- spinlock_t slock;
- struct mutex mutex;
-
- struct vivi_dmaqueue vidq;
-
- /* Several counters */
- unsigned ms;
- unsigned long jiffies;
- unsigned button_pressed;
-
- int mv_count; /* Controls bars movement */
-
- /* Input Number */
- int input;
-
- /* video capture */
- struct vivi_fmt *fmt;
- unsigned int width, height;
- struct vb2_queue vb_vidq;
- unsigned int field_count;
-
- u8 bars[9][3];
- u8 line[MAX_WIDTH * 8];
- unsigned int pixelsize;
- u8 alpha_component;
-};
-
-/* ------------------------------------------------------------------
- DMA and thread functions
- ------------------------------------------------------------------*/
-
-/* Bars and Colors should match positions */
-
-enum colors {
- WHITE,
- AMBER,
- CYAN,
- GREEN,
- MAGENTA,
- RED,
- BLUE,
- BLACK,
- TEXT_BLACK,
-};
-
-/* R G B */
-#define COLOR_WHITE {204, 204, 204}
-#define COLOR_AMBER {208, 208, 0}
-#define COLOR_CYAN { 0, 206, 206}
-#define COLOR_GREEN { 0, 239, 0}
-#define COLOR_MAGENTA {239, 0, 239}
-#define COLOR_RED {205, 0, 0}
-#define COLOR_BLUE { 0, 0, 255}
-#define COLOR_BLACK { 0, 0, 0}
-
-struct bar_std {
- u8 bar[9][3];
-};
-
-/* Maximum number of bars are 10 - otherwise, the input print code
- should be modified */
-static struct bar_std bars[] = {
- { /* Standard ITU-R color bar sequence */
- { COLOR_WHITE, COLOR_AMBER, COLOR_CYAN, COLOR_GREEN,
- COLOR_MAGENTA, COLOR_RED, COLOR_BLUE, COLOR_BLACK, COLOR_BLACK }
- }, {
- { COLOR_WHITE, COLOR_AMBER, COLOR_BLACK, COLOR_WHITE,
- COLOR_AMBER, COLOR_BLACK, COLOR_WHITE, COLOR_AMBER, COLOR_BLACK }
- }, {
- { COLOR_WHITE, COLOR_CYAN, COLOR_BLACK, COLOR_WHITE,
- COLOR_CYAN, COLOR_BLACK, COLOR_WHITE, COLOR_CYAN, COLOR_BLACK }
- }, {
- { COLOR_WHITE, COLOR_GREEN, COLOR_BLACK, COLOR_WHITE,
- COLOR_GREEN, COLOR_BLACK, COLOR_WHITE, COLOR_GREEN, COLOR_BLACK }
- },
-};
-
-#define NUM_INPUTS ARRAY_SIZE(bars)
-
-#define TO_Y(r, g, b) \
- (((16829 * r + 33039 * g + 6416 * b + 32768) >> 16) + 16)
-/* RGB to V(Cr) Color transform */
-#define TO_V(r, g, b) \
- (((28784 * r - 24103 * g - 4681 * b + 32768) >> 16) + 128)
-/* RGB to U(Cb) Color transform */
-#define TO_U(r, g, b) \
- (((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128)
-
-/* precalculate color bar values to speed up rendering */
-static void precalculate_bars(struct vivi_dev *dev)
-{
- u8 r, g, b;
- int k, is_yuv;
-
- for (k = 0; k < 9; k++) {
- r = bars[dev->input].bar[k][0];
- g = bars[dev->input].bar[k][1];
- b = bars[dev->input].bar[k][2];
- is_yuv = 0;
-
- switch (dev->fmt->fourcc) {
- case V4L2_PIX_FMT_YUYV:
- case V4L2_PIX_FMT_UYVY:
- case V4L2_PIX_FMT_YVYU:
- case V4L2_PIX_FMT_VYUY:
- is_yuv = 1;
- break;
- case V4L2_PIX_FMT_RGB565:
- case V4L2_PIX_FMT_RGB565X:
- r >>= 3;
- g >>= 2;
- b >>= 3;
- break;
- case V4L2_PIX_FMT_RGB555:
- case V4L2_PIX_FMT_RGB555X:
- r >>= 3;
- g >>= 3;
- b >>= 3;
- break;
- case V4L2_PIX_FMT_RGB24:
- case V4L2_PIX_FMT_BGR24:
- case V4L2_PIX_FMT_RGB32:
- case V4L2_PIX_FMT_BGR32:
- break;
- }
-
- if (is_yuv) {
- dev->bars[k][0] = TO_Y(r, g, b); /* Luma */
- dev->bars[k][1] = TO_U(r, g, b); /* Cb */
- dev->bars[k][2] = TO_V(r, g, b); /* Cr */
- } else {
- dev->bars[k][0] = r;
- dev->bars[k][1] = g;
- dev->bars[k][2] = b;
- }
- }
-}
-
-#define TSTAMP_MIN_Y 24
-#define TSTAMP_MAX_Y (TSTAMP_MIN_Y + 15)
-#define TSTAMP_INPUT_X 10
-#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X)
-
-/* 'odd' is true for pixels 1, 3, 5, etc. and false for pixels 0, 2, 4, etc. */
-static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos, bool odd)
-{
- u8 r_y, g_u, b_v;
- u8 alpha = dev->alpha_component;
- int color;
- u8 *p;
-
- r_y = dev->bars[colorpos][0]; /* R or precalculated Y */
- g_u = dev->bars[colorpos][1]; /* G or precalculated U */
- b_v = dev->bars[colorpos][2]; /* B or precalculated V */
-
- for (color = 0; color < dev->pixelsize; color++) {
- p = buf + color;
-
- switch (dev->fmt->fourcc) {
- case V4L2_PIX_FMT_YUYV:
- switch (color) {
- case 0:
- *p = r_y;
- break;
- case 1:
- *p = odd ? b_v : g_u;
- break;
- }
- break;
- case V4L2_PIX_FMT_UYVY:
- switch (color) {
- case 0:
- *p = odd ? b_v : g_u;
- break;
- case 1:
- *p = r_y;
- break;
- }
- break;
- case V4L2_PIX_FMT_YVYU:
- switch (color) {
- case 0:
- *p = r_y;
- break;
- case 1:
- *p = odd ? g_u : b_v;
- break;
- }
- break;
- case V4L2_PIX_FMT_VYUY:
- switch (color) {
- case 0:
- *p = odd ? g_u : b_v;
- break;
- case 1:
- *p = r_y;
- break;
- }
- break;
- case V4L2_PIX_FMT_RGB565:
- switch (color) {
- case 0:
- *p = (g_u << 5) | b_v;
- break;
- case 1:
- *p = (r_y << 3) | (g_u >> 3);
- break;
- }
- break;
- case V4L2_PIX_FMT_RGB565X:
- switch (color) {
- case 0:
- *p = (r_y << 3) | (g_u >> 3);
- break;
- case 1:
- *p = (g_u << 5) | b_v;
- break;
- }
- break;
- case V4L2_PIX_FMT_RGB555:
- switch (color) {
- case 0:
- *p = (g_u << 5) | b_v;
- break;
- case 1:
- *p = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
- break;
- }
- break;
- case V4L2_PIX_FMT_RGB555X:
- switch (color) {
- case 0:
- *p = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
- break;
- case 1:
- *p = (g_u << 5) | b_v;
- break;
- }
- break;
- case V4L2_PIX_FMT_RGB24:
- switch (color) {
- case 0:
- *p = r_y;
- break;
- case 1:
- *p = g_u;
- break;
- case 2:
- *p = b_v;
- break;
- }
- break;
- case V4L2_PIX_FMT_BGR24:
- switch (color) {
- case 0:
- *p = b_v;
- break;
- case 1:
- *p = g_u;
- break;
- case 2:
- *p = r_y;
- break;
- }
- break;
- case V4L2_PIX_FMT_RGB32:
- switch (color) {
- case 0:
- *p = alpha;
- break;
- case 1:
- *p = r_y;
- break;
- case 2:
- *p = g_u;
- break;
- case 3:
- *p = b_v;
- break;
- }
- break;
- case V4L2_PIX_FMT_BGR32:
- switch (color) {
- case 0:
- *p = b_v;
- break;
- case 1:
- *p = g_u;
- break;
- case 2:
- *p = r_y;
- break;
- case 3:
- *p = alpha;
- break;
- }
- break;
- }
- }
-}
-
-static void precalculate_line(struct vivi_dev *dev)
-{
- int w;
-
- for (w = 0; w < dev->width * 2; w++) {
- int colorpos = w / (dev->width / 8) % 8;
-
- gen_twopix(dev, dev->line + w * dev->pixelsize, colorpos, w & 1);
- }
-}
-
-static void gen_text(struct vivi_dev *dev, char *basep,
- int y, int x, char *text)
-{
- int line;
-
- /* Checks if it is possible to show string */
- if (y + 16 >= dev->height || x + strlen(text) * 8 >= dev->width)
- return;
-
- /* Print stream time */
- for (line = y; line < y + 16; line++) {
- int j = 0;
- char *pos = basep + line * dev->width * dev->pixelsize + x * dev->pixelsize;
- char *s;
-
- for (s = text; *s; s++) {
- u8 chr = font8x16[*s * 16 + line - y];
- int i;
-
- for (i = 0; i < 7; i++, j++) {
- /* Draw white font on black background */
- if (chr & (1 << (7 - i)))
- gen_twopix(dev, pos + j * dev->pixelsize, WHITE, (x+y) & 1);
- else
- gen_twopix(dev, pos + j * dev->pixelsize, TEXT_BLACK, (x+y) & 1);
- }
- }
- }
-}
-
-static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
-{
- int wmax = dev->width;
- int hmax = dev->height;
- struct timeval ts;
- void *vbuf = vb2_plane_vaddr(&buf->vb, 0);
- unsigned ms;
- char str[100];
- int h, line = 1;
- s32 gain;
-
- if (!vbuf)
- return;
-
- for (h = 0; h < hmax; h++)
- memcpy(vbuf + h * wmax * dev->pixelsize,
- dev->line + (dev->mv_count % wmax) * dev->pixelsize,
- wmax * dev->pixelsize);
-
- /* Updates stream time */
-
- dev->ms += jiffies_to_msecs(jiffies - dev->jiffies);
- dev->jiffies = jiffies;
- ms = dev->ms;
- snprintf(str, sizeof(str), " %02d:%02d:%02d:%03d ",
- (ms / (60 * 60 * 1000)) % 24,
- (ms / (60 * 1000)) % 60,
- (ms / 1000) % 60,
- ms % 1000);
- gen_text(dev, vbuf, line++ * 16, 16, str);
- snprintf(str, sizeof(str), " %dx%d, input %d ",
- dev->width, dev->height, dev->input);
- gen_text(dev, vbuf, line++ * 16, 16, str);
-
- gain = v4l2_ctrl_g_ctrl(dev->gain);
- mutex_lock(dev->ctrl_handler.lock);
- snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ",
- dev->brightness->cur.val,
- dev->contrast->cur.val,
- dev->saturation->cur.val,
- dev->hue->cur.val);
- gen_text(dev, vbuf, line++ * 16, 16, str);
- snprintf(str, sizeof(str), " autogain %d, gain %3d, volume %3d, alpha 0x%02x ",
- dev->autogain->cur.val, gain, dev->volume->cur.val,
- dev->alpha->cur.val);
- gen_text(dev, vbuf, line++ * 16, 16, str);
- snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ",
- dev->int32->cur.val,
- dev->int64->cur.val64,
- dev->bitmask->cur.val);
- gen_text(dev, vbuf, line++ * 16, 16, str);
- snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ",
- dev->boolean->cur.val,
- dev->menu->qmenu[dev->menu->cur.val],
- dev->string->cur.string);
- gen_text(dev, vbuf, line++ * 16, 16, str);
- snprintf(str, sizeof(str), " integer_menu %lld, value %d ",
- dev->int_menu->qmenu_int[dev->int_menu->cur.val],
- dev->int_menu->cur.val);
- gen_text(dev, vbuf, line++ * 16, 16, str);
- mutex_unlock(dev->ctrl_handler.lock);
- if (dev->button_pressed) {
- dev->button_pressed--;
- snprintf(str, sizeof(str), " button pressed!");
- gen_text(dev, vbuf, line++ * 16, 16, str);
- }
-
- dev->mv_count += 2;
-
- buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
- dev->field_count++;
- buf->vb.v4l2_buf.sequence = dev->field_count >> 1;
- do_gettimeofday(&ts);
- buf->vb.v4l2_buf.timestamp = ts;
-}
-
-static void vivi_thread_tick(struct vivi_dev *dev)
-{
- struct vivi_dmaqueue *dma_q = &dev->vidq;
- struct vivi_buffer *buf;
- unsigned long flags = 0;
-
- dprintk(dev, 1, "Thread tick\n");
-
- spin_lock_irqsave(&dev->slock, flags);
- if (list_empty(&dma_q->active)) {
- dprintk(dev, 1, "No active queue to serve\n");
- spin_unlock_irqrestore(&dev->slock, flags);
- return;
- }
-
- buf = list_entry(dma_q->active.next, struct vivi_buffer, list);
- list_del(&buf->list);
- spin_unlock_irqrestore(&dev->slock, flags);
-
- do_gettimeofday(&buf->vb.v4l2_buf.timestamp);
-
- /* Fill buffer */
- vivi_fillbuff(dev, buf);
- dprintk(dev, 1, "filled buffer %p\n", buf);
-
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
- dprintk(dev, 2, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index);
-}
-
-#define frames_to_ms(frames) \
- ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR)
-
-static void vivi_sleep(struct vivi_dev *dev)
-{
- struct vivi_dmaqueue *dma_q = &dev->vidq;
- int timeout;
- DECLARE_WAITQUEUE(wait, current);
-
- dprintk(dev, 1, "%s dma_q=0x%08lx\n", __func__,
- (unsigned long)dma_q);
-
- add_wait_queue(&dma_q->wq, &wait);
- if (kthread_should_stop())
- goto stop_task;
-
- /* Calculate time to wake up */
- timeout = msecs_to_jiffies(frames_to_ms(1));
-
- vivi_thread_tick(dev);
-
- schedule_timeout_interruptible(timeout);
-
-stop_task:
- remove_wait_queue(&dma_q->wq, &wait);
- try_to_freeze();
-}
-
-static int vivi_thread(void *data)
-{
- struct vivi_dev *dev = data;
-
- dprintk(dev, 1, "thread started\n");
-
- set_freezable();
-
- for (;;) {
- vivi_sleep(dev);
-
- if (kthread_should_stop())
- break;
- }
- dprintk(dev, 1, "thread: exit\n");
- return 0;
-}
-
-static int vivi_start_generating(struct vivi_dev *dev)
-{
- struct vivi_dmaqueue *dma_q = &dev->vidq;
-
- dprintk(dev, 1, "%s\n", __func__);
-
- /* Resets frame counters */
- dev->ms = 0;
- dev->mv_count = 0;
- dev->jiffies = jiffies;
-
- dma_q->frame = 0;
- dma_q->ini_jiffies = jiffies;
- dma_q->kthread = kthread_run(vivi_thread, dev, dev->v4l2_dev.name);
-
- if (IS_ERR(dma_q->kthread)) {
- v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
- return PTR_ERR(dma_q->kthread);
- }
- /* Wakes thread */
- wake_up_interruptible(&dma_q->wq);
-
- dprintk(dev, 1, "returning from %s\n", __func__);
- return 0;
-}
-
-static void vivi_stop_generating(struct vivi_dev *dev)
-{
- struct vivi_dmaqueue *dma_q = &dev->vidq;
-
- dprintk(dev, 1, "%s\n", __func__);
-
- /* shutdown control thread */
- if (dma_q->kthread) {
- kthread_stop(dma_q->kthread);
- dma_q->kthread = NULL;
- }
-
- /*
- * Typical driver might need to wait here until dma engine stops.
- * In this case we can abort imiedetly, so it's just a noop.
- */
-
- /* Release all active buffers */
- while (!list_empty(&dma_q->active)) {
- struct vivi_buffer *buf;
- buf = list_entry(dma_q->active.next, struct vivi_buffer, list);
- list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- dprintk(dev, 2, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index);
- }
-}
-/* ------------------------------------------------------------------
- Videobuf operations
- ------------------------------------------------------------------*/
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
- unsigned int *nbuffers, unsigned int *nplanes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- struct vivi_dev *dev = vb2_get_drv_priv(vq);
- unsigned long size;
-
- if (fmt)
- size = fmt->fmt.pix.sizeimage;
- else
- size = dev->width * dev->height * dev->pixelsize;
-
- if (size == 0)
- return -EINVAL;
-
- if (0 == *nbuffers)
- *nbuffers = 32;
-
- while (size * *nbuffers > vid_limit * 1024 * 1024)
- (*nbuffers)--;
-
- *nplanes = 1;
-
- sizes[0] = size;
-
- /*
- * videobuf2-vmalloc allocator is context-less so no need to set
- * alloc_ctxs array.
- */
-
- dprintk(dev, 1, "%s, count=%d, size=%ld\n", __func__,
- *nbuffers, size);
-
- return 0;
-}
-
-static int buffer_prepare(struct vb2_buffer *vb)
-{
- struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
- unsigned long size;
-
- dprintk(dev, 1, "%s, field=%d\n", __func__, vb->v4l2_buf.field);
-
- BUG_ON(NULL == dev->fmt);
-
- /*
- * Theses properties only change when queue is idle, see s_fmt.
- * The below checks should not be performed here, on each
- * buffer_prepare (i.e. on each qbuf). Most of the code in this function
- * should thus be moved to buffer_init and s_fmt.
- */
- if (dev->width < 48 || dev->width > MAX_WIDTH ||
- dev->height < 32 || dev->height > MAX_HEIGHT)
- return -EINVAL;
-
- size = dev->width * dev->height * dev->pixelsize;
- if (vb2_plane_size(vb, 0) < size) {
- dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n",
- __func__, vb2_plane_size(vb, 0), size);
- return -EINVAL;
- }
-
- vb2_set_plane_payload(&buf->vb, 0, size);
-
- buf->fmt = dev->fmt;
-
- precalculate_bars(dev);
- precalculate_line(dev);
-
- return 0;
-}
-
-static void buffer_queue(struct vb2_buffer *vb)
-{
- struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
- struct vivi_dmaqueue *vidq = &dev->vidq;
- unsigned long flags = 0;
-
- dprintk(dev, 1, "%s\n", __func__);
-
- spin_lock_irqsave(&dev->slock, flags);
- list_add_tail(&buf->list, &vidq->active);
- spin_unlock_irqrestore(&dev->slock, flags);
-}
-
-static int start_streaming(struct vb2_queue *vq, unsigned int count)
-{
- struct vivi_dev *dev = vb2_get_drv_priv(vq);
- dprintk(dev, 1, "%s\n", __func__);
- return vivi_start_generating(dev);
-}
-
-/* abort streaming and wait for last buffer */
-static int stop_streaming(struct vb2_queue *vq)
-{
- struct vivi_dev *dev = vb2_get_drv_priv(vq);
- dprintk(dev, 1, "%s\n", __func__);
- vivi_stop_generating(dev);
- return 0;
-}
-
-static void vivi_lock(struct vb2_queue *vq)
-{
- struct vivi_dev *dev = vb2_get_drv_priv(vq);
- mutex_lock(&dev->mutex);
-}
-
-static void vivi_unlock(struct vb2_queue *vq)
-{
- struct vivi_dev *dev = vb2_get_drv_priv(vq);
- mutex_unlock(&dev->mutex);
-}
-
-
-static struct vb2_ops vivi_video_qops = {
- .queue_setup = queue_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .start_streaming = start_streaming,
- .stop_streaming = stop_streaming,
- .wait_prepare = vivi_unlock,
- .wait_finish = vivi_lock,
-};
-
-/* ------------------------------------------------------------------
- IOCTL vidioc handling
- ------------------------------------------------------------------*/
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct vivi_dev *dev = video_drvdata(file);
-
- strcpy(cap->driver, "vivi");
- strcpy(cap->card, "vivi");
- strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
- cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
- V4L2_CAP_READWRITE;
- cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct vivi_fmt *fmt;
-
- if (f->index >= ARRAY_SIZE(formats))
- return -EINVAL;
-
- fmt = &formats[f->index];
-
- strlcpy(f->description, fmt->name, sizeof(f->description));
- f->pixelformat = fmt->fourcc;
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct vivi_dev *dev = video_drvdata(file);
-
- f->fmt.pix.width = dev->width;
- f->fmt.pix.height = dev->height;
- f->fmt.pix.field = V4L2_FIELD_INTERLACED;
- f->fmt.pix.pixelformat = dev->fmt->fourcc;
- f->fmt.pix.bytesperline =
- (f->fmt.pix.width * dev->fmt->depth) >> 3;
- f->fmt.pix.sizeimage =
- f->fmt.pix.height * f->fmt.pix.bytesperline;
- if (dev->fmt->fourcc == V4L2_PIX_FMT_YUYV ||
- dev->fmt->fourcc == V4L2_PIX_FMT_UYVY)
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- else
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct vivi_dev *dev = video_drvdata(file);
- struct vivi_fmt *fmt;
-
- fmt = get_format(f);
- if (!fmt) {
- dprintk(dev, 1, "Fourcc format (0x%08x) unknown.\n",
- f->fmt.pix.pixelformat);
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
- fmt = get_format(f);
- }
-
- f->fmt.pix.field = V4L2_FIELD_INTERLACED;
- v4l_bound_align_image(&f->fmt.pix.width, 48, MAX_WIDTH, 2,
- &f->fmt.pix.height, 32, MAX_HEIGHT, 0, 0);
- f->fmt.pix.bytesperline =
- (f->fmt.pix.width * fmt->depth) >> 3;
- f->fmt.pix.sizeimage =
- f->fmt.pix.height * f->fmt.pix.bytesperline;
- if (fmt->fourcc == V4L2_PIX_FMT_YUYV ||
- fmt->fourcc == V4L2_PIX_FMT_UYVY)
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- else
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct vivi_dev *dev = video_drvdata(file);
- struct vb2_queue *q = &dev->vb_vidq;
-
- int ret = vidioc_try_fmt_vid_cap(file, priv, f);
- if (ret < 0)
- return ret;
-
- if (vb2_is_busy(q)) {
- dprintk(dev, 1, "%s device busy\n", __func__);
- return -EBUSY;
- }
-
- dev->fmt = get_format(f);
- dev->pixelsize = dev->fmt->depth / 8;
- dev->width = f->fmt.pix.width;
- dev->height = f->fmt.pix.height;
-
- return 0;
-}
-
-/* only one input in this sample driver */
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *inp)
-{
- if (inp->index >= NUM_INPUTS)
- return -EINVAL;
-
- inp->type = V4L2_INPUT_TYPE_CAMERA;
- sprintf(inp->name, "Camera %u", inp->index);
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- struct vivi_dev *dev = video_drvdata(file);
-
- *i = dev->input;
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- struct vivi_dev *dev = video_drvdata(file);
-
- if (i >= NUM_INPUTS)
- return -EINVAL;
-
- if (i == dev->input)
- return 0;
-
- dev->input = i;
- precalculate_bars(dev);
- precalculate_line(dev);
- return 0;
-}
-
-/* --- controls ---------------------------------------------- */
-
-static int vivi_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, ctrl_handler);
-
- if (ctrl == dev->autogain)
- dev->gain->val = jiffies & 0xff;
- return 0;
-}
-
-static int vivi_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, ctrl_handler);
-
- switch (ctrl->id) {
- case V4L2_CID_ALPHA_COMPONENT:
- dev->alpha_component = ctrl->val;
- break;
- default:
- if (ctrl == dev->button)
- dev->button_pressed = 30;
- break;
- }
- return 0;
-}
-
-/* ------------------------------------------------------------------
- File operations for the device
- ------------------------------------------------------------------*/
-
-static const struct v4l2_ctrl_ops vivi_ctrl_ops = {
- .g_volatile_ctrl = vivi_g_volatile_ctrl,
- .s_ctrl = vivi_s_ctrl,
-};
-
-#define VIVI_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)
-
-static const struct v4l2_ctrl_config vivi_ctrl_button = {
- .ops = &vivi_ctrl_ops,
- .id = VIVI_CID_CUSTOM_BASE + 0,
- .name = "Button",
- .type = V4L2_CTRL_TYPE_BUTTON,
-};
-
-static const struct v4l2_ctrl_config vivi_ctrl_boolean = {
- .ops = &vivi_ctrl_ops,
- .id = VIVI_CID_CUSTOM_BASE + 1,
- .name = "Boolean",
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .min = 0,
- .max = 1,
- .step = 1,
- .def = 1,
-};
-
-static const struct v4l2_ctrl_config vivi_ctrl_int32 = {
- .ops = &vivi_ctrl_ops,
- .id = VIVI_CID_CUSTOM_BASE + 2,
- .name = "Integer 32 Bits",
- .type = V4L2_CTRL_TYPE_INTEGER,
- .min = 0x80000000,
- .max = 0x7fffffff,
- .step = 1,
-};
-
-static const struct v4l2_ctrl_config vivi_ctrl_int64 = {
- .ops = &vivi_ctrl_ops,
- .id = VIVI_CID_CUSTOM_BASE + 3,
- .name = "Integer 64 Bits",
- .type = V4L2_CTRL_TYPE_INTEGER64,
-};
-
-static const char * const vivi_ctrl_menu_strings[] = {
- "Menu Item 0 (Skipped)",
- "Menu Item 1",
- "Menu Item 2 (Skipped)",
- "Menu Item 3",
- "Menu Item 4",
- "Menu Item 5 (Skipped)",
- NULL,
-};
-
-static const struct v4l2_ctrl_config vivi_ctrl_menu = {
- .ops = &vivi_ctrl_ops,
- .id = VIVI_CID_CUSTOM_BASE + 4,
- .name = "Menu",
- .type = V4L2_CTRL_TYPE_MENU,
- .min = 1,
- .max = 4,
- .def = 3,
- .menu_skip_mask = 0x04,
- .qmenu = vivi_ctrl_menu_strings,
-};
-
-static const struct v4l2_ctrl_config vivi_ctrl_string = {
- .ops = &vivi_ctrl_ops,
- .id = VIVI_CID_CUSTOM_BASE + 5,
- .name = "String",
- .type = V4L2_CTRL_TYPE_STRING,
- .min = 2,
- .max = 4,
- .step = 1,
-};
-
-static const struct v4l2_ctrl_config vivi_ctrl_bitmask = {
- .ops = &vivi_ctrl_ops,
- .id = VIVI_CID_CUSTOM_BASE + 6,
- .name = "Bitmask",
- .type = V4L2_CTRL_TYPE_BITMASK,
- .def = 0x80002000,
- .min = 0,
- .max = 0x80402010,
- .step = 0,
-};
-
-static const s64 vivi_ctrl_int_menu_values[] = {
- 1, 1, 2, 3, 5, 8, 13, 21, 42,
-};
-
-static const struct v4l2_ctrl_config vivi_ctrl_int_menu = {
- .ops = &vivi_ctrl_ops,
- .id = VIVI_CID_CUSTOM_BASE + 7,
- .name = "Integer menu",
- .type = V4L2_CTRL_TYPE_INTEGER_MENU,
- .min = 1,
- .max = 8,
- .def = 4,
- .menu_skip_mask = 0x02,
- .qmenu_int = vivi_ctrl_int_menu_values,
-};
-
-static const struct v4l2_file_operations vivi_fops = {
- .owner = THIS_MODULE,
- .open = v4l2_fh_open,
- .release = vb2_fop_release,
- .read = vb2_fop_read,
- .poll = vb2_fop_poll,
- .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
- .mmap = vb2_fop_mmap,
-};
-
-static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = vb2_ioctl_reqbufs,
- .vidioc_create_bufs = vb2_ioctl_create_bufs,
- .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
- .vidioc_querybuf = vb2_ioctl_querybuf,
- .vidioc_qbuf = vb2_ioctl_qbuf,
- .vidioc_dqbuf = vb2_ioctl_dqbuf,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_streamon = vb2_ioctl_streamon,
- .vidioc_streamoff = vb2_ioctl_streamoff,
- .vidioc_log_status = v4l2_ctrl_log_status,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static struct video_device vivi_template = {
- .name = "vivi",
- .fops = &vivi_fops,
- .ioctl_ops = &vivi_ioctl_ops,
- .release = video_device_release_empty,
-};
-
-/* -----------------------------------------------------------------
- Initialization and module stuff
- ------------------------------------------------------------------*/
-
-static int vivi_release(void)
-{
- struct vivi_dev *dev;
- struct list_head *list;
-
- while (!list_empty(&vivi_devlist)) {
- list = vivi_devlist.next;
- list_del(list);
- dev = list_entry(list, struct vivi_dev, vivi_devlist);
-
- v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
- video_device_node_name(&dev->vdev));
- video_unregister_device(&dev->vdev);
- v4l2_device_unregister(&dev->v4l2_dev);
- v4l2_ctrl_handler_free(&dev->ctrl_handler);
- kfree(dev);
- }
-
- return 0;
-}
-
-static int __init vivi_create_instance(int inst)
-{
- struct vivi_dev *dev;
- struct video_device *vfd;
- struct v4l2_ctrl_handler *hdl;
- struct vb2_queue *q;
- int ret;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
-
- snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
- "%s-%03d", VIVI_MODULE_NAME, inst);
- ret = v4l2_device_register(NULL, &dev->v4l2_dev);
- if (ret)
- goto free_dev;
-
- dev->fmt = &formats[0];
- dev->width = 640;
- dev->height = 480;
- dev->pixelsize = dev->fmt->depth / 8;
- hdl = &dev->ctrl_handler;
- v4l2_ctrl_handler_init(hdl, 11);
- dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
- V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
- dev->brightness = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
- dev->contrast = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 16);
- dev->saturation = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, 127);
- dev->hue = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
- V4L2_CID_HUE, -128, 127, 1, 0);
- dev->autogain = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- dev->gain = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
- V4L2_CID_GAIN, 0, 255, 1, 100);
- dev->alpha = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
- V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
- dev->button = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_button, NULL);
- dev->int32 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int32, NULL);
- dev->int64 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int64, NULL);
- dev->boolean = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_boolean, NULL);
- dev->menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_menu, NULL);
- dev->string = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_string, NULL);
- dev->bitmask = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_bitmask, NULL);
- dev->int_menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int_menu, NULL);
- if (hdl->error) {
- ret = hdl->error;
- goto unreg_dev;
- }
- v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
- dev->v4l2_dev.ctrl_handler = hdl;
-
- /* initialize locks */
- spin_lock_init(&dev->slock);
-
- /* initialize queue */
- q = &dev->vb_vidq;
- memset(q, 0, sizeof(dev->vb_vidq));
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
- q->drv_priv = dev;
- q->buf_struct_size = sizeof(struct vivi_buffer);
- q->ops = &vivi_video_qops;
- q->mem_ops = &vb2_vmalloc_memops;
-
- vb2_queue_init(q);
-
- mutex_init(&dev->mutex);
-
- /* init video dma queues */
- INIT_LIST_HEAD(&dev->vidq.active);
- init_waitqueue_head(&dev->vidq.wq);
-
- vfd = &dev->vdev;
- *vfd = vivi_template;
- vfd->debug = debug;
- vfd->v4l2_dev = &dev->v4l2_dev;
- vfd->queue = q;
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
-
- /*
- * Provide a mutex to v4l2 core. It will be used to protect
- * all fops and v4l2 ioctls.
- */
- vfd->lock = &dev->mutex;
- video_set_drvdata(vfd, dev);
-
- ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
- if (ret < 0)
- goto unreg_dev;
-
- /* Now that everything is fine, let's add it to device list */
- list_add_tail(&dev->vivi_devlist, &vivi_devlist);
-
- v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
- video_device_node_name(vfd));
- return 0;
-
-unreg_dev:
- v4l2_ctrl_handler_free(hdl);
- v4l2_device_unregister(&dev->v4l2_dev);
-free_dev:
- kfree(dev);
- return ret;
-}
-
-/* This routine allocates from 1 to n_devs virtual drivers.
-
- The real maximum number of virtual drivers will depend on how many drivers
- will succeed. This is limited to the maximum number of devices that
- videodev supports, which is equal to VIDEO_NUM_DEVICES.
- */
-static int __init vivi_init(void)
-{
- const struct font_desc *font = find_font("VGA8x16");
- int ret = 0, i;
-
- if (font == NULL) {
- printk(KERN_ERR "vivi: could not find font\n");
- return -ENODEV;
- }
- font8x16 = font->data;
-
- if (n_devs <= 0)
- n_devs = 1;
-
- for (i = 0; i < n_devs; i++) {
- ret = vivi_create_instance(i);
- if (ret) {
- /* If some instantiations succeeded, keep driver */
- if (i)
- ret = 0;
- break;
- }
- }
-
- if (ret < 0) {
- printk(KERN_ERR "vivi: error %d while loading driver\n", ret);
- return ret;
- }
-
- printk(KERN_INFO "Video Technology Magazine Virtual Video "
- "Capture Board ver %s successfully loaded.\n",
- VIVI_VERSION);
-
- /* n_devs will reflect the actual number of allocated devices */
- n_devs = i;
-
- return ret;
-}
-
-static void __exit vivi_exit(void)
-{
- vivi_release();
-}
-
-module_init(vivi_init);
-module_exit(vivi_exit);
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
deleted file mode 100644
index 7cfbc9d94a4..00000000000
--- a/drivers/media/video/vp27smpx.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * vp27smpx - driver version 0.0.1
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * Based on a tvaudio patch from Takahiro Adachi <tadachi@tadachi-net.com>
- * and Kazuhiko Kawakami <kazz-0@mail.goo.ne.jp>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-
-MODULE_DESCRIPTION("vp27smpx driver");
-MODULE_AUTHOR("Hans Verkuil");
-MODULE_LICENSE("GPL");
-
-
-/* ----------------------------------------------------------------------- */
-
-struct vp27smpx_state {
- struct v4l2_subdev sd;
- int radio;
- u32 audmode;
-};
-
-static inline struct vp27smpx_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct vp27smpx_state, sd);
-}
-
-static void vp27smpx_set_audmode(struct v4l2_subdev *sd, u32 audmode)
-{
- struct vp27smpx_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 data[3] = { 0x00, 0x00, 0x04 };
-
- switch (audmode) {
- case V4L2_TUNER_MODE_MONO:
- case V4L2_TUNER_MODE_LANG1:
- break;
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1_LANG2:
- data[1] = 0x01;
- break;
- case V4L2_TUNER_MODE_LANG2:
- data[1] = 0x02;
- break;
- }
-
- if (i2c_master_send(client, data, sizeof(data)) != sizeof(data))
- v4l2_err(sd, "I/O error setting audmode\n");
- else
- state->audmode = audmode;
-}
-
-static int vp27smpx_s_radio(struct v4l2_subdev *sd)
-{
- struct vp27smpx_state *state = to_state(sd);
-
- state->radio = 1;
- return 0;
-}
-
-static int vp27smpx_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
- struct vp27smpx_state *state = to_state(sd);
-
- state->radio = 0;
- return 0;
-}
-
-static int vp27smpx_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct vp27smpx_state *state = to_state(sd);
-
- if (!state->radio)
- vp27smpx_set_audmode(sd, vt->audmode);
- return 0;
-}
-
-static int vp27smpx_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct vp27smpx_state *state = to_state(sd);
-
- if (state->radio)
- return 0;
- vt->audmode = state->audmode;
- vt->capability = V4L2_TUNER_CAP_STEREO |
- V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
- vt->rxsubchans = V4L2_TUNER_SUB_MONO;
- return 0;
-}
-
-static int vp27smpx_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_VP27SMPX, 0);
-}
-
-static int vp27smpx_log_status(struct v4l2_subdev *sd)
-{
- struct vp27smpx_state *state = to_state(sd);
-
- v4l2_info(sd, "Audio Mode: %u%s\n", state->audmode,
- state->radio ? " (Radio)" : "");
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops vp27smpx_core_ops = {
- .log_status = vp27smpx_log_status,
- .g_chip_ident = vp27smpx_g_chip_ident,
- .s_std = vp27smpx_s_std,
-};
-
-static const struct v4l2_subdev_tuner_ops vp27smpx_tuner_ops = {
- .s_radio = vp27smpx_s_radio,
- .s_tuner = vp27smpx_s_tuner,
- .g_tuner = vp27smpx_g_tuner,
-};
-
-static const struct v4l2_subdev_ops vp27smpx_ops = {
- .core = &vp27smpx_core_ops,
- .tuner = &vp27smpx_tuner_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-/* i2c implementation */
-
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-
-static int vp27smpx_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct vp27smpx_state *state;
- struct v4l2_subdev *sd;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- state = kzalloc(sizeof(struct vp27smpx_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &vp27smpx_ops);
- state->audmode = V4L2_TUNER_MODE_STEREO;
-
- /* initialize vp27smpx */
- vp27smpx_set_audmode(sd, state->audmode);
- return 0;
-}
-
-static int vp27smpx_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
- v4l2_device_unregister_subdev(sd);
- kfree(to_state(sd));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id vp27smpx_id[] = {
- { "vp27smpx", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, vp27smpx_id);
-
-static struct i2c_driver vp27smpx_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "vp27smpx",
- },
- .probe = vp27smpx_probe,
- .remove = vp27smpx_remove,
- .id_table = vp27smpx_id,
-};
-
-module_i2c_driver(vp27smpx_driver);
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
deleted file mode 100644
index 2f67b4c5c82..00000000000
--- a/drivers/media/video/vpx3220.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
- * vpx3220a, vpx3216b & vpx3214c video decoder driver version 0.0.1
- *
- * Copyright (C) 2001 Laurent Pinchart <lpinchart@freegates.be>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-
-MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
-MODULE_AUTHOR("Laurent Pinchart");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-
-#define VPX_TIMEOUT_COUNT 10
-
-/* ----------------------------------------------------------------------- */
-
-struct vpx3220 {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- unsigned char reg[255];
-
- v4l2_std_id norm;
- int ident;
- int input;
- int enable;
-};
-
-static inline struct vpx3220 *to_vpx3220(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct vpx3220, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct vpx3220, hdl)->sd;
-}
-
-static char *inputs[] = { "internal", "composite", "svideo" };
-
-/* ----------------------------------------------------------------------- */
-
-static inline int vpx3220_write(struct v4l2_subdev *sd, u8 reg, u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct vpx3220 *decoder = i2c_get_clientdata(client);
-
- decoder->reg[reg] = value;
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static inline int vpx3220_read(struct v4l2_subdev *sd, u8 reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int vpx3220_fp_status(struct v4l2_subdev *sd)
-{
- unsigned char status;
- unsigned int i;
-
- for (i = 0; i < VPX_TIMEOUT_COUNT; i++) {
- status = vpx3220_read(sd, 0x29);
-
- if (!(status & 4))
- return 0;
-
- udelay(10);
-
- if (need_resched())
- cond_resched();
- }
-
- return -1;
-}
-
-static int vpx3220_fp_write(struct v4l2_subdev *sd, u8 fpaddr, u16 data)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- /* Write the 16-bit address to the FPWR register */
- if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) {
- v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
- return -1;
- }
-
- if (vpx3220_fp_status(sd) < 0)
- return -1;
-
- /* Write the 16-bit data to the FPDAT register */
- if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) {
- v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
- return -1;
- }
-
- return 0;
-}
-
-static u16 vpx3220_fp_read(struct v4l2_subdev *sd, u16 fpaddr)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- s16 data;
-
- /* Write the 16-bit address to the FPRD register */
- if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) {
- v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
- return -1;
- }
-
- if (vpx3220_fp_status(sd) < 0)
- return -1;
-
- /* Read the 16-bit data from the FPDAT register */
- data = i2c_smbus_read_word_data(client, 0x28);
- if (data == -1) {
- v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
- return -1;
- }
-
- return swab16(data);
-}
-
-static int vpx3220_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
-{
- u8 reg;
- int ret = -1;
-
- while (len >= 2) {
- reg = *data++;
- ret = vpx3220_write(sd, reg, *data++);
- if (ret < 0)
- break;
- len -= 2;
- }
-
- return ret;
-}
-
-static int vpx3220_write_fp_block(struct v4l2_subdev *sd,
- const u16 *data, unsigned int len)
-{
- u8 reg;
- int ret = 0;
-
- while (len > 1) {
- reg = *data++;
- ret |= vpx3220_fp_write(sd, reg, *data++);
- len -= 2;
- }
-
- return ret;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static const unsigned short init_ntsc[] = {
- 0x1c, 0x00, /* NTSC tint angle */
- 0x88, 17, /* Window 1 vertical */
- 0x89, 240, /* Vertical lines in */
- 0x8a, 240, /* Vertical lines out */
- 0x8b, 000, /* Horizontal begin */
- 0x8c, 640, /* Horizontal length */
- 0x8d, 640, /* Number of pixels */
- 0x8f, 0xc00, /* Disable window 2 */
- 0xf0, 0x73, /* 13.5 MHz transport, Forced
- * mode, latch windows */
- 0xf2, 0x13, /* NTSC M, composite input */
- 0xe7, 0x1e1, /* Enable vertical standard
- * locking @ 240 lines */
-};
-
-static const unsigned short init_pal[] = {
- 0x88, 23, /* Window 1 vertical begin */
- 0x89, 288, /* Vertical lines in (16 lines
- * skipped by the VFE) */
- 0x8a, 288, /* Vertical lines out (16 lines
- * skipped by the VFE) */
- 0x8b, 16, /* Horizontal begin */
- 0x8c, 768, /* Horizontal length */
- 0x8d, 784, /* Number of pixels
- * Must be >= Horizontal begin + Horizontal length */
- 0x8f, 0xc00, /* Disable window 2 */
- 0xf0, 0x77, /* 13.5 MHz transport, Forced
- * mode, latch windows */
- 0xf2, 0x3d1, /* PAL B,G,H,I, composite input */
- 0xe7, 0x241, /* PAL/SECAM set to 288 lines */
-};
-
-static const unsigned short init_secam[] = {
- 0x88, 23, /* Window 1 vertical begin */
- 0x89, 288, /* Vertical lines in (16 lines
- * skipped by the VFE) */
- 0x8a, 288, /* Vertical lines out (16 lines
- * skipped by the VFE) */
- 0x8b, 16, /* Horizontal begin */
- 0x8c, 768, /* Horizontal length */
- 0x8d, 784, /* Number of pixels
- * Must be >= Horizontal begin + Horizontal length */
- 0x8f, 0xc00, /* Disable window 2 */
- 0xf0, 0x77, /* 13.5 MHz transport, Forced
- * mode, latch windows */
- 0xf2, 0x3d5, /* SECAM, composite input */
- 0xe7, 0x241, /* PAL/SECAM set to 288 lines */
-};
-
-static const unsigned char init_common[] = {
- 0xf2, 0x00, /* Disable all outputs */
- 0x33, 0x0d, /* Luma : VIN2, Chroma : CIN
- * (clamp off) */
- 0xd8, 0xa8, /* HREF/VREF active high, VREF
- * pulse = 2, Odd/Even flag */
- 0x20, 0x03, /* IF compensation 0dB/oct */
- 0xe0, 0xff, /* Open up all comparators */
- 0xe1, 0x00,
- 0xe2, 0x7f,
- 0xe3, 0x80,
- 0xe4, 0x7f,
- 0xe5, 0x80,
- 0xe6, 0x00, /* Brightness set to 0 */
- 0xe7, 0xe0, /* Contrast to 1.0, noise shaping
- * 10 to 8 2-bit error diffusion */
- 0xe8, 0xf8, /* YUV422, CbCr binary offset,
- * ... (p.32) */
- 0xea, 0x18, /* LLC2 connected, output FIFO
- * reset with VACTintern */
- 0xf0, 0x8a, /* Half full level to 10, bus
- * shuffler [7:0, 23:16, 15:8] */
- 0xf1, 0x18, /* Single clock, sync mode, no
- * FE delay, no HLEN counter */
- 0xf8, 0x12, /* Port A, PIXCLK, HF# & FE#
- * strength to 2 */
- 0xf9, 0x24, /* Port B, HREF, VREF, PREF &
- * ALPHA strength to 4 */
-};
-
-static const unsigned short init_fp[] = {
- 0x59, 0,
- 0xa0, 2070, /* ACC reference */
- 0xa3, 0,
- 0xa4, 0,
- 0xa8, 30,
- 0xb2, 768,
- 0xbe, 27,
- 0x58, 0,
- 0x26, 0,
- 0x4b, 0x298, /* PLL gain */
-};
-
-
-static int vpx3220_init(struct v4l2_subdev *sd, u32 val)
-{
- struct vpx3220 *decoder = to_vpx3220(sd);
-
- vpx3220_write_block(sd, init_common, sizeof(init_common));
- vpx3220_write_fp_block(sd, init_fp, sizeof(init_fp) >> 1);
- if (decoder->norm & V4L2_STD_NTSC)
- vpx3220_write_fp_block(sd, init_ntsc, sizeof(init_ntsc) >> 1);
- else if (decoder->norm & V4L2_STD_PAL)
- vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
- else if (decoder->norm & V4L2_STD_SECAM)
- vpx3220_write_fp_block(sd, init_secam, sizeof(init_secam) >> 1);
- else
- vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
- return 0;
-}
-
-static int vpx3220_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
-{
- int res = V4L2_IN_ST_NO_SIGNAL, status;
- v4l2_std_id std = 0;
-
- status = vpx3220_fp_read(sd, 0x0f3);
-
- v4l2_dbg(1, debug, sd, "status: 0x%04x\n", status);
-
- if (status < 0)
- return status;
-
- if ((status & 0x20) == 0) {
- res = 0;
-
- switch (status & 0x18) {
- case 0x00:
- case 0x10:
- case 0x14:
- case 0x18:
- std = V4L2_STD_PAL;
- break;
-
- case 0x08:
- std = V4L2_STD_SECAM;
- break;
-
- case 0x04:
- case 0x0c:
- case 0x1c:
- std = V4L2_STD_NTSC;
- break;
- }
- }
- if (pstd)
- *pstd = std;
- if (pstatus)
- *pstatus = res;
- return 0;
-}
-
-static int vpx3220_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
-{
- v4l2_dbg(1, debug, sd, "querystd\n");
- return vpx3220_status(sd, NULL, std);
-}
-
-static int vpx3220_g_input_status(struct v4l2_subdev *sd, u32 *status)
-{
- v4l2_dbg(1, debug, sd, "g_input_status\n");
- return vpx3220_status(sd, status, NULL);
-}
-
-static int vpx3220_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
- struct vpx3220 *decoder = to_vpx3220(sd);
- int temp_input;
-
- /* Here we back up the input selection because it gets
- overwritten when we fill the registers with the
- chosen video norm */
- temp_input = vpx3220_fp_read(sd, 0xf2);
-
- v4l2_dbg(1, debug, sd, "s_std %llx\n", (unsigned long long)std);
- if (std & V4L2_STD_NTSC) {
- vpx3220_write_fp_block(sd, init_ntsc, sizeof(init_ntsc) >> 1);
- v4l2_dbg(1, debug, sd, "norm switched to NTSC\n");
- } else if (std & V4L2_STD_PAL) {
- vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
- v4l2_dbg(1, debug, sd, "norm switched to PAL\n");
- } else if (std & V4L2_STD_SECAM) {
- vpx3220_write_fp_block(sd, init_secam, sizeof(init_secam) >> 1);
- v4l2_dbg(1, debug, sd, "norm switched to SECAM\n");
- } else {
- return -EINVAL;
- }
-
- decoder->norm = std;
-
- /* And here we set the backed up video input again */
- vpx3220_fp_write(sd, 0xf2, temp_input | 0x0010);
- udelay(10);
- return 0;
-}
-
-static int vpx3220_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- int data;
-
- /* RJ: input = 0: ST8 (PCTV) input
- input = 1: COMPOSITE input
- input = 2: SVHS input */
-
- const int input_vals[3][2] = {
- {0x0c, 0},
- {0x0d, 0},
- {0x0e, 1}
- };
-
- if (input > 2)
- return -EINVAL;
-
- v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[input]);
-
- vpx3220_write(sd, 0x33, input_vals[input][0]);
-
- data = vpx3220_fp_read(sd, 0xf2) & ~(0x0020);
- if (data < 0)
- return data;
- /* 0x0010 is required to latch the setting */
- vpx3220_fp_write(sd, 0xf2,
- data | (input_vals[input][1] << 5) | 0x0010);
-
- udelay(10);
- return 0;
-}
-
-static int vpx3220_s_stream(struct v4l2_subdev *sd, int enable)
-{
- v4l2_dbg(1, debug, sd, "s_stream %s\n", enable ? "on" : "off");
-
- vpx3220_write(sd, 0xf2, (enable ? 0x1b : 0x00));
- return 0;
-}
-
-static int vpx3220_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- vpx3220_write(sd, 0xe6, ctrl->val);
- return 0;
- case V4L2_CID_CONTRAST:
- /* Bit 7 and 8 is for noise shaping */
- vpx3220_write(sd, 0xe7, ctrl->val + 192);
- return 0;
- case V4L2_CID_SATURATION:
- vpx3220_fp_write(sd, 0xa0, ctrl->val);
- return 0;
- case V4L2_CID_HUE:
- vpx3220_fp_write(sd, 0x1c, ctrl->val);
- return 0;
- }
- return -EINVAL;
-}
-
-static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct vpx3220 *decoder = to_vpx3220(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_ctrl_ops vpx3220_ctrl_ops = {
- .s_ctrl = vpx3220_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops vpx3220_core_ops = {
- .g_chip_ident = vpx3220_g_chip_ident,
- .init = vpx3220_init,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
- .s_std = vpx3220_s_std,
-};
-
-static const struct v4l2_subdev_video_ops vpx3220_video_ops = {
- .s_routing = vpx3220_s_routing,
- .s_stream = vpx3220_s_stream,
- .querystd = vpx3220_querystd,
- .g_input_status = vpx3220_g_input_status,
-};
-
-static const struct v4l2_subdev_ops vpx3220_ops = {
- .core = &vpx3220_core_ops,
- .video = &vpx3220_video_ops,
-};
-
-/* -----------------------------------------------------------------------
- * Client management code
- */
-
-static int vpx3220_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct vpx3220 *decoder;
- struct v4l2_subdev *sd;
- const char *name = NULL;
- u8 ver;
- u16 pn;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
- return -ENODEV;
-
- decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL);
- if (decoder == NULL)
- return -ENOMEM;
- sd = &decoder->sd;
- v4l2_i2c_subdev_init(sd, client, &vpx3220_ops);
- decoder->norm = V4L2_STD_PAL;
- decoder->input = 0;
- decoder->enable = 1;
- v4l2_ctrl_handler_init(&decoder->hdl, 4);
- v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
- V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
- v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 63, 1, 32);
- v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
- V4L2_CID_SATURATION, 0, 4095, 1, 2048);
- v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
- V4L2_CID_HUE, -512, 511, 1, 0);
- sd->ctrl_handler = &decoder->hdl;
- if (decoder->hdl.error) {
- int err = decoder->hdl.error;
-
- v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(decoder);
- return err;
- }
- v4l2_ctrl_handler_setup(&decoder->hdl);
-
- ver = i2c_smbus_read_byte_data(client, 0x00);
- pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) +
- i2c_smbus_read_byte_data(client, 0x01);
- decoder->ident = V4L2_IDENT_VPX3220A;
- if (ver == 0xec) {
- switch (pn) {
- case 0x4680:
- name = "vpx3220a";
- break;
- case 0x4260:
- name = "vpx3216b";
- decoder->ident = V4L2_IDENT_VPX3216B;
- break;
- case 0x4280:
- name = "vpx3214c";
- decoder->ident = V4L2_IDENT_VPX3214C;
- break;
- }
- }
- if (name)
- v4l2_info(sd, "%s found @ 0x%x (%s)\n", name,
- client->addr << 1, client->adapter->name);
- else
- v4l2_info(sd, "chip (%02x:%04x) found @ 0x%x (%s)\n",
- ver, pn, client->addr << 1, client->adapter->name);
-
- vpx3220_write_block(sd, init_common, sizeof(init_common));
- vpx3220_write_fp_block(sd, init_fp, sizeof(init_fp) >> 1);
- /* Default to PAL */
- vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
- return 0;
-}
-
-static int vpx3220_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct vpx3220 *decoder = to_vpx3220(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(decoder);
- return 0;
-}
-
-static const struct i2c_device_id vpx3220_id[] = {
- { "vpx3220a", 0 },
- { "vpx3216b", 0 },
- { "vpx3214c", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, vpx3220_id);
-
-static struct i2c_driver vpx3220_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "vpx3220",
- },
- .probe = vpx3220_probe,
- .remove = vpx3220_remove,
- .id_table = vpx3220_id,
-};
-
-module_i2c_driver(vpx3220_driver);
diff --git a/drivers/media/video/vs6624.c b/drivers/media/video/vs6624.c
deleted file mode 100644
index 42ae9dc9c57..00000000000
--- a/drivers/media/video/vs6624.c
+++ /dev/null
@@ -1,928 +0,0 @@
-/*
- * vs6624.c ST VS6624 CMOS image sensor driver
- *
- * Copyright (c) 2011 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-mediabus.h>
-
-#include "vs6624_regs.h"
-
-#define VGA_WIDTH 640
-#define VGA_HEIGHT 480
-#define QVGA_WIDTH 320
-#define QVGA_HEIGHT 240
-#define QQVGA_WIDTH 160
-#define QQVGA_HEIGHT 120
-#define CIF_WIDTH 352
-#define CIF_HEIGHT 288
-#define QCIF_WIDTH 176
-#define QCIF_HEIGHT 144
-#define QQCIF_WIDTH 88
-#define QQCIF_HEIGHT 72
-
-#define MAX_FRAME_RATE 30
-
-struct vs6624 {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- struct v4l2_fract frame_rate;
- struct v4l2_mbus_framefmt fmt;
- unsigned ce_pin;
-};
-
-static const struct vs6624_format {
- enum v4l2_mbus_pixelcode mbus_code;
- enum v4l2_colorspace colorspace;
-} vs6624_formats[] = {
- {
- .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- },
- {
- .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- },
- {
- .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- },
-};
-
-static struct v4l2_mbus_framefmt vs6624_default_fmt = {
- .width = VGA_WIDTH,
- .height = VGA_HEIGHT,
- .code = V4L2_MBUS_FMT_UYVY8_2X8,
- .field = V4L2_FIELD_NONE,
- .colorspace = V4L2_COLORSPACE_JPEG,
-};
-
-static const u16 vs6624_p1[] = {
- 0x8104, 0x03,
- 0x8105, 0x01,
- 0xc900, 0x03,
- 0xc904, 0x47,
- 0xc905, 0x10,
- 0xc906, 0x80,
- 0xc907, 0x3a,
- 0x903a, 0x02,
- 0x903b, 0x47,
- 0x903c, 0x15,
- 0xc908, 0x31,
- 0xc909, 0xdc,
- 0xc90a, 0x80,
- 0xc90b, 0x44,
- 0x9044, 0x02,
- 0x9045, 0x31,
- 0x9046, 0xe2,
- 0xc90c, 0x07,
- 0xc90d, 0xe0,
- 0xc90e, 0x80,
- 0xc90f, 0x47,
- 0x9047, 0x90,
- 0x9048, 0x83,
- 0x9049, 0x81,
- 0x904a, 0xe0,
- 0x904b, 0x60,
- 0x904c, 0x08,
- 0x904d, 0x90,
- 0x904e, 0xc0,
- 0x904f, 0x43,
- 0x9050, 0x74,
- 0x9051, 0x01,
- 0x9052, 0xf0,
- 0x9053, 0x80,
- 0x9054, 0x05,
- 0x9055, 0xE4,
- 0x9056, 0x90,
- 0x9057, 0xc0,
- 0x9058, 0x43,
- 0x9059, 0xf0,
- 0x905a, 0x02,
- 0x905b, 0x07,
- 0x905c, 0xec,
- 0xc910, 0x5d,
- 0xc911, 0xca,
- 0xc912, 0x80,
- 0xc913, 0x5d,
- 0x905d, 0xa3,
- 0x905e, 0x04,
- 0x905f, 0xf0,
- 0x9060, 0xa3,
- 0x9061, 0x04,
- 0x9062, 0xf0,
- 0x9063, 0x22,
- 0xc914, 0x72,
- 0xc915, 0x92,
- 0xc916, 0x80,
- 0xc917, 0x64,
- 0x9064, 0x74,
- 0x9065, 0x01,
- 0x9066, 0x02,
- 0x9067, 0x72,
- 0x9068, 0x95,
- 0xc918, 0x47,
- 0xc919, 0xf2,
- 0xc91a, 0x81,
- 0xc91b, 0x69,
- 0x9169, 0x74,
- 0x916a, 0x02,
- 0x916b, 0xf0,
- 0x916c, 0xec,
- 0x916d, 0xb4,
- 0x916e, 0x10,
- 0x916f, 0x0a,
- 0x9170, 0x90,
- 0x9171, 0x80,
- 0x9172, 0x16,
- 0x9173, 0xe0,
- 0x9174, 0x70,
- 0x9175, 0x04,
- 0x9176, 0x90,
- 0x9177, 0xd3,
- 0x9178, 0xc4,
- 0x9179, 0xf0,
- 0x917a, 0x22,
- 0xc91c, 0x0a,
- 0xc91d, 0xbe,
- 0xc91e, 0x80,
- 0xc91f, 0x73,
- 0x9073, 0xfc,
- 0x9074, 0xa3,
- 0x9075, 0xe0,
- 0x9076, 0xf5,
- 0x9077, 0x82,
- 0x9078, 0x8c,
- 0x9079, 0x83,
- 0x907a, 0xa3,
- 0x907b, 0xa3,
- 0x907c, 0xe0,
- 0x907d, 0xfc,
- 0x907e, 0xa3,
- 0x907f, 0xe0,
- 0x9080, 0xc3,
- 0x9081, 0x9f,
- 0x9082, 0xff,
- 0x9083, 0xec,
- 0x9084, 0x9e,
- 0x9085, 0xfe,
- 0x9086, 0x02,
- 0x9087, 0x0a,
- 0x9088, 0xea,
- 0xc920, 0x47,
- 0xc921, 0x38,
- 0xc922, 0x80,
- 0xc923, 0x89,
- 0x9089, 0xec,
- 0x908a, 0xd3,
- 0x908b, 0x94,
- 0x908c, 0x20,
- 0x908d, 0x40,
- 0x908e, 0x01,
- 0x908f, 0x1c,
- 0x9090, 0x90,
- 0x9091, 0xd3,
- 0x9092, 0xd4,
- 0x9093, 0xec,
- 0x9094, 0xf0,
- 0x9095, 0x02,
- 0x9096, 0x47,
- 0x9097, 0x3d,
- 0xc924, 0x45,
- 0xc925, 0xca,
- 0xc926, 0x80,
- 0xc927, 0x98,
- 0x9098, 0x12,
- 0x9099, 0x77,
- 0x909a, 0xd6,
- 0x909b, 0x02,
- 0x909c, 0x45,
- 0x909d, 0xcd,
- 0xc928, 0x20,
- 0xc929, 0xd5,
- 0xc92a, 0x80,
- 0xc92b, 0x9e,
- 0x909e, 0x90,
- 0x909f, 0x82,
- 0x90a0, 0x18,
- 0x90a1, 0xe0,
- 0x90a2, 0xb4,
- 0x90a3, 0x03,
- 0x90a4, 0x0e,
- 0x90a5, 0x90,
- 0x90a6, 0x83,
- 0x90a7, 0xbf,
- 0x90a8, 0xe0,
- 0x90a9, 0x60,
- 0x90aa, 0x08,
- 0x90ab, 0x90,
- 0x90ac, 0x81,
- 0x90ad, 0xfc,
- 0x90ae, 0xe0,
- 0x90af, 0xff,
- 0x90b0, 0xc3,
- 0x90b1, 0x13,
- 0x90b2, 0xf0,
- 0x90b3, 0x90,
- 0x90b4, 0x81,
- 0x90b5, 0xfc,
- 0x90b6, 0xe0,
- 0x90b7, 0xff,
- 0x90b8, 0x02,
- 0x90b9, 0x20,
- 0x90ba, 0xda,
- 0xc92c, 0x70,
- 0xc92d, 0xbc,
- 0xc92e, 0x80,
- 0xc92f, 0xbb,
- 0x90bb, 0x90,
- 0x90bc, 0x82,
- 0x90bd, 0x18,
- 0x90be, 0xe0,
- 0x90bf, 0xb4,
- 0x90c0, 0x03,
- 0x90c1, 0x06,
- 0x90c2, 0x90,
- 0x90c3, 0xc1,
- 0x90c4, 0x06,
- 0x90c5, 0x74,
- 0x90c6, 0x05,
- 0x90c7, 0xf0,
- 0x90c8, 0x90,
- 0x90c9, 0xd3,
- 0x90ca, 0xa0,
- 0x90cb, 0x02,
- 0x90cc, 0x70,
- 0x90cd, 0xbf,
- 0xc930, 0x72,
- 0xc931, 0x21,
- 0xc932, 0x81,
- 0xc933, 0x3b,
- 0x913b, 0x7d,
- 0x913c, 0x02,
- 0x913d, 0x7f,
- 0x913e, 0x7b,
- 0x913f, 0x02,
- 0x9140, 0x72,
- 0x9141, 0x25,
- 0xc934, 0x28,
- 0xc935, 0xae,
- 0xc936, 0x80,
- 0xc937, 0xd2,
- 0x90d2, 0xf0,
- 0x90d3, 0x90,
- 0x90d4, 0xd2,
- 0x90d5, 0x0a,
- 0x90d6, 0x02,
- 0x90d7, 0x28,
- 0x90d8, 0xb4,
- 0xc938, 0x28,
- 0xc939, 0xb1,
- 0xc93a, 0x80,
- 0xc93b, 0xd9,
- 0x90d9, 0x90,
- 0x90da, 0x83,
- 0x90db, 0xba,
- 0x90dc, 0xe0,
- 0x90dd, 0xff,
- 0x90de, 0x90,
- 0x90df, 0xd2,
- 0x90e0, 0x08,
- 0x90e1, 0xe0,
- 0x90e2, 0xe4,
- 0x90e3, 0xef,
- 0x90e4, 0xf0,
- 0x90e5, 0xa3,
- 0x90e6, 0xe0,
- 0x90e7, 0x74,
- 0x90e8, 0xff,
- 0x90e9, 0xf0,
- 0x90ea, 0x90,
- 0x90eb, 0xd2,
- 0x90ec, 0x0a,
- 0x90ed, 0x02,
- 0x90ee, 0x28,
- 0x90ef, 0xb4,
- 0xc93c, 0x29,
- 0xc93d, 0x79,
- 0xc93e, 0x80,
- 0xc93f, 0xf0,
- 0x90f0, 0xf0,
- 0x90f1, 0x90,
- 0x90f2, 0xd2,
- 0x90f3, 0x0e,
- 0x90f4, 0x02,
- 0x90f5, 0x29,
- 0x90f6, 0x7f,
- 0xc940, 0x29,
- 0xc941, 0x7c,
- 0xc942, 0x80,
- 0xc943, 0xf7,
- 0x90f7, 0x90,
- 0x90f8, 0x83,
- 0x90f9, 0xba,
- 0x90fa, 0xe0,
- 0x90fb, 0xff,
- 0x90fc, 0x90,
- 0x90fd, 0xd2,
- 0x90fe, 0x0c,
- 0x90ff, 0xe0,
- 0x9100, 0xe4,
- 0x9101, 0xef,
- 0x9102, 0xf0,
- 0x9103, 0xa3,
- 0x9104, 0xe0,
- 0x9105, 0x74,
- 0x9106, 0xff,
- 0x9107, 0xf0,
- 0x9108, 0x90,
- 0x9109, 0xd2,
- 0x910a, 0x0e,
- 0x910b, 0x02,
- 0x910c, 0x29,
- 0x910d, 0x7f,
- 0xc944, 0x2a,
- 0xc945, 0x42,
- 0xc946, 0x81,
- 0xc947, 0x0e,
- 0x910e, 0xf0,
- 0x910f, 0x90,
- 0x9110, 0xd2,
- 0x9111, 0x12,
- 0x9112, 0x02,
- 0x9113, 0x2a,
- 0x9114, 0x48,
- 0xc948, 0x2a,
- 0xc949, 0x45,
- 0xc94a, 0x81,
- 0xc94b, 0x15,
- 0x9115, 0x90,
- 0x9116, 0x83,
- 0x9117, 0xba,
- 0x9118, 0xe0,
- 0x9119, 0xff,
- 0x911a, 0x90,
- 0x911b, 0xd2,
- 0x911c, 0x10,
- 0x911d, 0xe0,
- 0x911e, 0xe4,
- 0x911f, 0xef,
- 0x9120, 0xf0,
- 0x9121, 0xa3,
- 0x9122, 0xe0,
- 0x9123, 0x74,
- 0x9124, 0xff,
- 0x9125, 0xf0,
- 0x9126, 0x90,
- 0x9127, 0xd2,
- 0x9128, 0x12,
- 0x9129, 0x02,
- 0x912a, 0x2a,
- 0x912b, 0x48,
- 0xc900, 0x01,
- 0x0000, 0x00,
-};
-
-static const u16 vs6624_p2[] = {
- 0x806f, 0x01,
- 0x058c, 0x01,
- 0x0000, 0x00,
-};
-
-static const u16 vs6624_run_setup[] = {
- 0x1d18, 0x00, /* Enableconstrainedwhitebalance */
- VS6624_PEAK_MIN_OUT_G_MSB, 0x3c, /* Damper PeakGain Output MSB */
- VS6624_PEAK_MIN_OUT_G_LSB, 0x66, /* Damper PeakGain Output LSB */
- VS6624_CM_LOW_THR_MSB, 0x65, /* Damper Low MSB */
- VS6624_CM_LOW_THR_LSB, 0xd1, /* Damper Low LSB */
- VS6624_CM_HIGH_THR_MSB, 0x66, /* Damper High MSB */
- VS6624_CM_HIGH_THR_LSB, 0x62, /* Damper High LSB */
- VS6624_CM_MIN_OUT_MSB, 0x00, /* Damper Min output MSB */
- VS6624_CM_MIN_OUT_LSB, 0x00, /* Damper Min output LSB */
- VS6624_NORA_DISABLE, 0x00, /* Nora fDisable */
- VS6624_NORA_USAGE, 0x04, /* Nora usage */
- VS6624_NORA_LOW_THR_MSB, 0x63, /* Damper Low MSB Changed 0x63 to 0x65 */
- VS6624_NORA_LOW_THR_LSB, 0xd1, /* Damper Low LSB */
- VS6624_NORA_HIGH_THR_MSB, 0x68, /* Damper High MSB */
- VS6624_NORA_HIGH_THR_LSB, 0xdd, /* Damper High LSB */
- VS6624_NORA_MIN_OUT_MSB, 0x3a, /* Damper Min output MSB */
- VS6624_NORA_MIN_OUT_LSB, 0x00, /* Damper Min output LSB */
- VS6624_F2B_DISABLE, 0x00, /* Disable */
- 0x1d8a, 0x30, /* MAXWeightHigh */
- 0x1d91, 0x62, /* fpDamperLowThresholdHigh MSB */
- 0x1d92, 0x4a, /* fpDamperLowThresholdHigh LSB */
- 0x1d95, 0x65, /* fpDamperHighThresholdHigh MSB */
- 0x1d96, 0x0e, /* fpDamperHighThresholdHigh LSB */
- 0x1da1, 0x3a, /* fpMinimumDamperOutputLow MSB */
- 0x1da2, 0xb8, /* fpMinimumDamperOutputLow LSB */
- 0x1e08, 0x06, /* MAXWeightLow */
- 0x1e0a, 0x0a, /* MAXWeightHigh */
- 0x1601, 0x3a, /* Red A MSB */
- 0x1602, 0x14, /* Red A LSB */
- 0x1605, 0x3b, /* Blue A MSB */
- 0x1606, 0x85, /* BLue A LSB */
- 0x1609, 0x3b, /* RED B MSB */
- 0x160a, 0x85, /* RED B LSB */
- 0x160d, 0x3a, /* Blue B MSB */
- 0x160e, 0x14, /* Blue B LSB */
- 0x1611, 0x30, /* Max Distance from Locus MSB */
- 0x1612, 0x8f, /* Max Distance from Locus MSB */
- 0x1614, 0x01, /* Enable constrainer */
- 0x0000, 0x00,
-};
-
-static const u16 vs6624_default[] = {
- VS6624_CONTRAST0, 0x84,
- VS6624_SATURATION0, 0x75,
- VS6624_GAMMA0, 0x11,
- VS6624_CONTRAST1, 0x84,
- VS6624_SATURATION1, 0x75,
- VS6624_GAMMA1, 0x11,
- VS6624_MAN_RG, 0x80,
- VS6624_MAN_GG, 0x80,
- VS6624_MAN_BG, 0x80,
- VS6624_WB_MODE, 0x1,
- VS6624_EXPO_COMPENSATION, 0xfe,
- VS6624_EXPO_METER, 0x0,
- VS6624_LIGHT_FREQ, 0x64,
- VS6624_PEAK_GAIN, 0xe,
- VS6624_PEAK_LOW_THR, 0x28,
- VS6624_HMIRROR0, 0x0,
- VS6624_VFLIP0, 0x0,
- VS6624_ZOOM_HSTEP0_MSB, 0x0,
- VS6624_ZOOM_HSTEP0_LSB, 0x1,
- VS6624_ZOOM_VSTEP0_MSB, 0x0,
- VS6624_ZOOM_VSTEP0_LSB, 0x1,
- VS6624_PAN_HSTEP0_MSB, 0x0,
- VS6624_PAN_HSTEP0_LSB, 0xf,
- VS6624_PAN_VSTEP0_MSB, 0x0,
- VS6624_PAN_VSTEP0_LSB, 0xf,
- VS6624_SENSOR_MODE, 0x1,
- VS6624_SYNC_CODE_SETUP, 0x21,
- VS6624_DISABLE_FR_DAMPER, 0x0,
- VS6624_FR_DEN, 0x1,
- VS6624_FR_NUM_LSB, 0xf,
- VS6624_INIT_PIPE_SETUP, 0x0,
- VS6624_IMG_FMT0, 0x0,
- VS6624_YUV_SETUP, 0x1,
- VS6624_IMAGE_SIZE0, 0x2,
- 0x0000, 0x00,
-};
-
-static inline struct vs6624 *to_vs6624(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct vs6624, sd);
-}
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct vs6624, hdl)->sd;
-}
-
-static int vs6624_read(struct v4l2_subdev *sd, u16 index)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 buf[2];
-
- buf[0] = index >> 8;
- buf[1] = index;
- i2c_master_send(client, buf, 2);
- i2c_master_recv(client, buf, 1);
-
- return buf[0];
-}
-
-static int vs6624_write(struct v4l2_subdev *sd, u16 index,
- u8 value)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 buf[3];
-
- buf[0] = index >> 8;
- buf[1] = index;
- buf[2] = value;
-
- return i2c_master_send(client, buf, 3);
-}
-
-static int vs6624_writeregs(struct v4l2_subdev *sd, const u16 *regs)
-{
- u16 reg;
- u8 data;
-
- while (*regs != 0x00) {
- reg = *regs++;
- data = *regs++;
-
- vs6624_write(sd, reg, data);
- }
- return 0;
-}
-
-static int vs6624_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
-
- switch (ctrl->id) {
- case V4L2_CID_CONTRAST:
- vs6624_write(sd, VS6624_CONTRAST0, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- vs6624_write(sd, VS6624_SATURATION0, ctrl->val);
- break;
- case V4L2_CID_HFLIP:
- vs6624_write(sd, VS6624_HMIRROR0, ctrl->val);
- break;
- case V4L2_CID_VFLIP:
- vs6624_write(sd, VS6624_VFLIP0, ctrl->val);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vs6624_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index >= ARRAY_SIZE(vs6624_formats))
- return -EINVAL;
-
- *code = vs6624_formats[index].mbus_code;
- return 0;
-}
-
-static int vs6624_try_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *fmt)
-{
- int index;
-
- for (index = 0; index < ARRAY_SIZE(vs6624_formats); index++)
- if (vs6624_formats[index].mbus_code == fmt->code)
- break;
- if (index >= ARRAY_SIZE(vs6624_formats)) {
- /* default to first format */
- index = 0;
- fmt->code = vs6624_formats[0].mbus_code;
- }
-
- /* sensor mode is VGA */
- if (fmt->width > VGA_WIDTH)
- fmt->width = VGA_WIDTH;
- if (fmt->height > VGA_HEIGHT)
- fmt->height = VGA_HEIGHT;
- fmt->width = fmt->width & (~3);
- fmt->height = fmt->height & (~3);
- fmt->field = V4L2_FIELD_NONE;
- fmt->colorspace = vs6624_formats[index].colorspace;
- return 0;
-}
-
-static int vs6624_s_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *fmt)
-{
- struct vs6624 *sensor = to_vs6624(sd);
- int ret;
-
- ret = vs6624_try_mbus_fmt(sd, fmt);
- if (ret)
- return ret;
-
- /* set image format */
- switch (fmt->code) {
- case V4L2_MBUS_FMT_UYVY8_2X8:
- vs6624_write(sd, VS6624_IMG_FMT0, 0x0);
- vs6624_write(sd, VS6624_YUV_SETUP, 0x1);
- break;
- case V4L2_MBUS_FMT_YUYV8_2X8:
- vs6624_write(sd, VS6624_IMG_FMT0, 0x0);
- vs6624_write(sd, VS6624_YUV_SETUP, 0x3);
- break;
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- vs6624_write(sd, VS6624_IMG_FMT0, 0x4);
- vs6624_write(sd, VS6624_RGB_SETUP, 0x0);
- break;
- default:
- return -EINVAL;
- }
-
- /* set image size */
- if ((fmt->width == VGA_WIDTH) && (fmt->height == VGA_HEIGHT))
- vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x2);
- else if ((fmt->width == QVGA_WIDTH) && (fmt->height == QVGA_HEIGHT))
- vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x4);
- else if ((fmt->width == QQVGA_WIDTH) && (fmt->height == QQVGA_HEIGHT))
- vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x6);
- else if ((fmt->width == CIF_WIDTH) && (fmt->height == CIF_HEIGHT))
- vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x3);
- else if ((fmt->width == QCIF_WIDTH) && (fmt->height == QCIF_HEIGHT))
- vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x5);
- else if ((fmt->width == QQCIF_WIDTH) && (fmt->height == QQCIF_HEIGHT))
- vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x7);
- else {
- vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x8);
- vs6624_write(sd, VS6624_MAN_HSIZE0_MSB, fmt->width >> 8);
- vs6624_write(sd, VS6624_MAN_HSIZE0_LSB, fmt->width & 0xFF);
- vs6624_write(sd, VS6624_MAN_VSIZE0_MSB, fmt->height >> 8);
- vs6624_write(sd, VS6624_MAN_VSIZE0_LSB, fmt->height & 0xFF);
- vs6624_write(sd, VS6624_CROP_CTRL0, 0x1);
- }
-
- sensor->fmt = *fmt;
-
- return 0;
-}
-
-static int vs6624_g_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *fmt)
-{
- struct vs6624 *sensor = to_vs6624(sd);
-
- *fmt = sensor->fmt;
- return 0;
-}
-
-static int vs6624_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
-{
- struct vs6624 *sensor = to_vs6624(sd);
- struct v4l2_captureparm *cp = &parms->parm.capture;
-
- if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- memset(cp, 0, sizeof(*cp));
- cp->capability = V4L2_CAP_TIMEPERFRAME;
- cp->timeperframe.numerator = sensor->frame_rate.denominator;
- cp->timeperframe.denominator = sensor->frame_rate.numerator;
- return 0;
-}
-
-static int vs6624_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
-{
- struct vs6624 *sensor = to_vs6624(sd);
- struct v4l2_captureparm *cp = &parms->parm.capture;
- struct v4l2_fract *tpf = &cp->timeperframe;
-
- if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (cp->extendedmode != 0)
- return -EINVAL;
-
- if (tpf->numerator == 0 || tpf->denominator == 0
- || (tpf->denominator > tpf->numerator * MAX_FRAME_RATE)) {
- /* reset to max frame rate */
- tpf->numerator = 1;
- tpf->denominator = MAX_FRAME_RATE;
- }
- sensor->frame_rate.numerator = tpf->denominator;
- sensor->frame_rate.denominator = tpf->numerator;
- vs6624_write(sd, VS6624_DISABLE_FR_DAMPER, 0x0);
- vs6624_write(sd, VS6624_FR_NUM_MSB,
- sensor->frame_rate.numerator >> 8);
- vs6624_write(sd, VS6624_FR_NUM_LSB,
- sensor->frame_rate.numerator & 0xFF);
- vs6624_write(sd, VS6624_FR_DEN,
- sensor->frame_rate.denominator & 0xFF);
- return 0;
-}
-
-static int vs6624_s_stream(struct v4l2_subdev *sd, int enable)
-{
- if (enable)
- vs6624_write(sd, VS6624_USER_CMD, 0x2);
- else
- vs6624_write(sd, VS6624_USER_CMD, 0x4);
- udelay(100);
- return 0;
-}
-
-static int vs6624_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- int rev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- rev = (vs6624_read(sd, VS6624_FW_VSN_MAJOR) << 8)
- | vs6624_read(sd, VS6624_FW_VSN_MINOR);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_VS6624, rev);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vs6624_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- reg->val = vs6624_read(sd, reg->reg & 0xffff);
- reg->size = 1;
- return 0;
-}
-
-static int vs6624_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, &reg->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- vs6624_write(sd, reg->reg & 0xffff, reg->val & 0xff);
- return 0;
-}
-#endif
-
-static const struct v4l2_ctrl_ops vs6624_ctrl_ops = {
- .s_ctrl = vs6624_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops vs6624_core_ops = {
- .g_chip_ident = vs6624_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = vs6624_g_register,
- .s_register = vs6624_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_video_ops vs6624_video_ops = {
- .enum_mbus_fmt = vs6624_enum_mbus_fmt,
- .try_mbus_fmt = vs6624_try_mbus_fmt,
- .s_mbus_fmt = vs6624_s_mbus_fmt,
- .g_mbus_fmt = vs6624_g_mbus_fmt,
- .s_parm = vs6624_s_parm,
- .g_parm = vs6624_g_parm,
- .s_stream = vs6624_s_stream,
-};
-
-static const struct v4l2_subdev_ops vs6624_ops = {
- .core = &vs6624_core_ops,
- .video = &vs6624_video_ops,
-};
-
-static int __devinit vs6624_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct vs6624 *sensor;
- struct v4l2_subdev *sd;
- struct v4l2_ctrl_handler *hdl;
- const unsigned *ce;
- int ret;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
- return -EIO;
-
- ce = client->dev.platform_data;
- if (ce == NULL)
- return -EINVAL;
-
- ret = gpio_request(*ce, "VS6624 Chip Enable");
- if (ret) {
- v4l_err(client, "failed to request GPIO %d\n", *ce);
- return ret;
- }
- gpio_direction_output(*ce, 1);
- /* wait 100ms before any further i2c writes are performed */
- mdelay(100);
-
- sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
- if (sensor == NULL) {
- gpio_free(*ce);
- return -ENOMEM;
- }
-
- sd = &sensor->sd;
- v4l2_i2c_subdev_init(sd, client, &vs6624_ops);
-
- vs6624_writeregs(sd, vs6624_p1);
- vs6624_write(sd, VS6624_MICRO_EN, 0x2);
- vs6624_write(sd, VS6624_DIO_EN, 0x1);
- mdelay(10);
- vs6624_writeregs(sd, vs6624_p2);
-
- vs6624_writeregs(sd, vs6624_default);
- vs6624_write(sd, VS6624_HSYNC_SETUP, 0xF);
- vs6624_writeregs(sd, vs6624_run_setup);
-
- /* set frame rate */
- sensor->frame_rate.numerator = MAX_FRAME_RATE;
- sensor->frame_rate.denominator = 1;
- vs6624_write(sd, VS6624_DISABLE_FR_DAMPER, 0x0);
- vs6624_write(sd, VS6624_FR_NUM_MSB,
- sensor->frame_rate.numerator >> 8);
- vs6624_write(sd, VS6624_FR_NUM_LSB,
- sensor->frame_rate.numerator & 0xFF);
- vs6624_write(sd, VS6624_FR_DEN,
- sensor->frame_rate.denominator & 0xFF);
-
- sensor->fmt = vs6624_default_fmt;
- sensor->ce_pin = *ce;
-
- v4l_info(client, "chip found @ 0x%02x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- hdl = &sensor->hdl;
- v4l2_ctrl_handler_init(hdl, 4);
- v4l2_ctrl_new_std(hdl, &vs6624_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 0xFF, 1, 0x87);
- v4l2_ctrl_new_std(hdl, &vs6624_ctrl_ops,
- V4L2_CID_SATURATION, 0, 0xFF, 1, 0x78);
- v4l2_ctrl_new_std(hdl, &vs6624_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(hdl, &vs6624_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- /* hook the control handler into the driver */
- sd->ctrl_handler = hdl;
- if (hdl->error) {
- int err = hdl->error;
-
- v4l2_ctrl_handler_free(hdl);
- kfree(sensor);
- gpio_free(*ce);
- return err;
- }
-
- /* initialize the hardware to the default control values */
- ret = v4l2_ctrl_handler_setup(hdl);
- if (ret) {
- v4l2_ctrl_handler_free(hdl);
- kfree(sensor);
- gpio_free(*ce);
- }
- return ret;
-}
-
-static int __devexit vs6624_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct vs6624 *sensor = to_vs6624(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(sd->ctrl_handler);
- gpio_free(sensor->ce_pin);
- kfree(sensor);
- return 0;
-}
-
-static const struct i2c_device_id vs6624_id[] = {
- {"vs6624", 0},
- {},
-};
-
-MODULE_DEVICE_TABLE(i2c, vs6624_id);
-
-static struct i2c_driver vs6624_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "vs6624",
- },
- .probe = vs6624_probe,
- .remove = __devexit_p(vs6624_remove),
- .id_table = vs6624_id,
-};
-
-static __init int vs6624_init(void)
-{
- return i2c_add_driver(&vs6624_driver);
-}
-
-static __exit void vs6624_exit(void)
-{
- i2c_del_driver(&vs6624_driver);
-}
-
-module_init(vs6624_init);
-module_exit(vs6624_exit);
-
-MODULE_DESCRIPTION("VS6624 sensor driver");
-MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/vs6624_regs.h b/drivers/media/video/vs6624_regs.h
deleted file mode 100644
index 6ba2ee25827..00000000000
--- a/drivers/media/video/vs6624_regs.h
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * vs6624 - ST VS6624 CMOS image sensor registers
- *
- * Copyright (c) 2011 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _VS6624_REGS_H_
-#define _VS6624_REGS_H_
-
-/* low level control registers */
-#define VS6624_MICRO_EN 0xC003 /* power enable for all MCU clock */
-#define VS6624_DIO_EN 0xC044 /* enable digital I/O */
-/* device parameters */
-#define VS6624_DEV_ID_MSB 0x0001 /* device id MSB */
-#define VS6624_DEV_ID_LSB 0x0002 /* device id LSB */
-#define VS6624_FW_VSN_MAJOR 0x0004 /* firmware version major */
-#define VS6624_FW_VSN_MINOR 0x0006 /* firmware version minor */
-#define VS6624_PATCH_VSN_MAJOR 0x0008 /* patch version major */
-#define VS6624_PATCH_VSN_MINOR 0x000A /* patch version minor */
-/* host interface manager control */
-#define VS6624_USER_CMD 0x0180 /* user level control of operating states */
-/* host interface manager status */
-#define VS6624_STATE 0x0202 /* current state of the mode manager */
-/* run mode control */
-#define VS6624_METER_ON 0x0280 /* if false AE and AWB are disabled */
-/* mode setup */
-#define VS6624_ACTIVE_PIPE_SETUP 0x0302 /* select the active bank for non view live mode */
-#define VS6624_SENSOR_MODE 0x0308 /* select the different sensor mode */
-/* pipe setup bank0 */
-#define VS6624_IMAGE_SIZE0 0x0380 /* required output dimension */
-#define VS6624_MAN_HSIZE0_MSB 0x0383 /* input required manual H size MSB */
-#define VS6624_MAN_HSIZE0_LSB 0x0384 /* input required manual H size LSB */
-#define VS6624_MAN_VSIZE0_MSB 0x0387 /* input required manual V size MSB */
-#define VS6624_MAN_VSIZE0_LSB 0x0388 /* input required manual V size LSB */
-#define VS6624_ZOOM_HSTEP0_MSB 0x038B /* set the zoom H step MSB */
-#define VS6624_ZOOM_HSTEP0_LSB 0x038C /* set the zoom H step LSB */
-#define VS6624_ZOOM_VSTEP0_MSB 0x038F /* set the zoom V step MSB */
-#define VS6624_ZOOM_VSTEP0_LSB 0x0390 /* set the zoom V step LSB */
-#define VS6624_ZOOM_CTRL0 0x0392 /* control zoon in, out and stop */
-#define VS6624_PAN_HSTEP0_MSB 0x0395 /* set the pan H step MSB */
-#define VS6624_PAN_HSTEP0_LSB 0x0396 /* set the pan H step LSB */
-#define VS6624_PAN_VSTEP0_MSB 0x0399 /* set the pan V step MSB */
-#define VS6624_PAN_VSTEP0_LSB 0x039A /* set the pan V step LSB */
-#define VS6624_PAN_CTRL0 0x039C /* control pan operation */
-#define VS6624_CROP_CTRL0 0x039E /* select cropping mode */
-#define VS6624_CROP_HSTART0_MSB 0x03A1 /* set the cropping H start address MSB */
-#define VS6624_CROP_HSTART0_LSB 0x03A2 /* set the cropping H start address LSB */
-#define VS6624_CROP_HSIZE0_MSB 0x03A5 /* set the cropping H size MSB */
-#define VS6624_CROP_HSIZE0_LSB 0x03A6 /* set the cropping H size LSB */
-#define VS6624_CROP_VSTART0_MSB 0x03A9 /* set the cropping V start address MSB */
-#define VS6624_CROP_VSTART0_LSB 0x03AA /* set the cropping V start address LSB */
-#define VS6624_CROP_VSIZE0_MSB 0x03AD /* set the cropping V size MSB */
-#define VS6624_CROP_VSIZE0_LSB 0x03AE /* set the cropping V size LSB */
-#define VS6624_IMG_FMT0 0x03B0 /* select required output image format */
-#define VS6624_BAYER_OUT_ALIGN0 0x03B2 /* set bayer output alignment */
-#define VS6624_CONTRAST0 0x03B4 /* contrast control for output */
-#define VS6624_SATURATION0 0x03B6 /* saturation control for output */
-#define VS6624_GAMMA0 0x03B8 /* gamma settings */
-#define VS6624_HMIRROR0 0x03BA /* horizontal image orientation flip */
-#define VS6624_VFLIP0 0x03BC /* vertical image orientation flip */
-#define VS6624_CHANNEL_ID0 0x03BE /* logical DMA channel number */
-/* pipe setup bank1 */
-#define VS6624_IMAGE_SIZE1 0x0400 /* required output dimension */
-#define VS6624_MAN_HSIZE1_MSB 0x0403 /* input required manual H size MSB */
-#define VS6624_MAN_HSIZE1_LSB 0x0404 /* input required manual H size LSB */
-#define VS6624_MAN_VSIZE1_MSB 0x0407 /* input required manual V size MSB */
-#define VS6624_MAN_VSIZE1_LSB 0x0408 /* input required manual V size LSB */
-#define VS6624_ZOOM_HSTEP1_MSB 0x040B /* set the zoom H step MSB */
-#define VS6624_ZOOM_HSTEP1_LSB 0x040C /* set the zoom H step LSB */
-#define VS6624_ZOOM_VSTEP1_MSB 0x040F /* set the zoom V step MSB */
-#define VS6624_ZOOM_VSTEP1_LSB 0x0410 /* set the zoom V step LSB */
-#define VS6624_ZOOM_CTRL1 0x0412 /* control zoon in, out and stop */
-#define VS6624_PAN_HSTEP1_MSB 0x0415 /* set the pan H step MSB */
-#define VS6624_PAN_HSTEP1_LSB 0x0416 /* set the pan H step LSB */
-#define VS6624_PAN_VSTEP1_MSB 0x0419 /* set the pan V step MSB */
-#define VS6624_PAN_VSTEP1_LSB 0x041A /* set the pan V step LSB */
-#define VS6624_PAN_CTRL1 0x041C /* control pan operation */
-#define VS6624_CROP_CTRL1 0x041E /* select cropping mode */
-#define VS6624_CROP_HSTART1_MSB 0x0421 /* set the cropping H start address MSB */
-#define VS6624_CROP_HSTART1_LSB 0x0422 /* set the cropping H start address LSB */
-#define VS6624_CROP_HSIZE1_MSB 0x0425 /* set the cropping H size MSB */
-#define VS6624_CROP_HSIZE1_LSB 0x0426 /* set the cropping H size LSB */
-#define VS6624_CROP_VSTART1_MSB 0x0429 /* set the cropping V start address MSB */
-#define VS6624_CROP_VSTART1_LSB 0x042A /* set the cropping V start address LSB */
-#define VS6624_CROP_VSIZE1_MSB 0x042D /* set the cropping V size MSB */
-#define VS6624_CROP_VSIZE1_LSB 0x042E /* set the cropping V size LSB */
-#define VS6624_IMG_FMT1 0x0430 /* select required output image format */
-#define VS6624_BAYER_OUT_ALIGN1 0x0432 /* set bayer output alignment */
-#define VS6624_CONTRAST1 0x0434 /* contrast control for output */
-#define VS6624_SATURATION1 0x0436 /* saturation control for output */
-#define VS6624_GAMMA1 0x0438 /* gamma settings */
-#define VS6624_HMIRROR1 0x043A /* horizontal image orientation flip */
-#define VS6624_VFLIP1 0x043C /* vertical image orientation flip */
-#define VS6624_CHANNEL_ID1 0x043E /* logical DMA channel number */
-/* view live control */
-#define VS6624_VIEW_LIVE_EN 0x0480 /* enable view live mode */
-#define VS6624_INIT_PIPE_SETUP 0x0482 /* select initial pipe setup bank */
-/* view live status */
-#define VS6624_CUR_PIPE_SETUP 0x0500 /* indicates most recently applied setup bank */
-/* power management */
-#define VS6624_TIME_TO_POWER_DOWN 0x0580 /* automatically transition time to stop mode */
-/* video timing parameter host inputs */
-#define VS6624_EXT_CLK_FREQ_NUM_MSB 0x0605 /* external clock frequency numerator MSB */
-#define VS6624_EXT_CLK_FREQ_NUM_LSB 0x0606 /* external clock frequency numerator LSB */
-#define VS6624_EXT_CLK_FREQ_DEN 0x0608 /* external clock frequency denominator */
-/* video timing control */
-#define VS6624_SYS_CLK_MODE 0x0880 /* decides system clock frequency */
-/* frame dimension parameter host inputs */
-#define VS6624_LIGHT_FREQ 0x0C80 /* AC frequency used for flicker free time */
-#define VS6624_FLICKER_COMPAT 0x0C82 /* flicker compatible frame length */
-/* static frame rate control */
-#define VS6624_FR_NUM_MSB 0x0D81 /* desired frame rate numerator MSB */
-#define VS6624_FR_NUM_LSB 0x0D82 /* desired frame rate numerator LSB */
-#define VS6624_FR_DEN 0x0D84 /* desired frame rate denominator */
-/* automatic frame rate control */
-#define VS6624_DISABLE_FR_DAMPER 0x0E80 /* defines frame rate mode */
-#define VS6624_MIN_DAMPER_OUT_MSB 0x0E8C /* minimum frame rate MSB */
-#define VS6624_MIN_DAMPER_OUT_LSB 0x0E8A /* minimum frame rate LSB */
-/* exposure controls */
-#define VS6624_EXPO_MODE 0x1180 /* exposure mode */
-#define VS6624_EXPO_METER 0x1182 /* weights to be associated with the zones */
-#define VS6624_EXPO_TIME_NUM 0x1184 /* exposure time numerator */
-#define VS6624_EXPO_TIME_DEN 0x1186 /* exposure time denominator */
-#define VS6624_EXPO_TIME_MSB 0x1189 /* exposure time for the Manual Mode MSB */
-#define VS6624_EXPO_TIME_LSB 0x118A /* exposure time for the Manual Mode LSB */
-#define VS6624_EXPO_COMPENSATION 0x1190 /* exposure compensation */
-#define VS6624_DIRECT_COARSE_MSB 0x1195 /* coarse integration lines for Direct Mode MSB */
-#define VS6624_DIRECT_COARSE_LSB 0x1196 /* coarse integration lines for Direct Mode LSB */
-#define VS6624_DIRECT_FINE_MSB 0x1199 /* fine integration pixels for Direct Mode MSB */
-#define VS6624_DIRECT_FINE_LSB 0x119A /* fine integration pixels for Direct Mode LSB */
-#define VS6624_DIRECT_ANAL_GAIN_MSB 0x119D /* analog gain for Direct Mode MSB */
-#define VS6624_DIRECT_ANAL_GAIN_LSB 0x119E /* analog gain for Direct Mode LSB */
-#define VS6624_DIRECT_DIGI_GAIN_MSB 0x11A1 /* digital gain for Direct Mode MSB */
-#define VS6624_DIRECT_DIGI_GAIN_LSB 0x11A2 /* digital gain for Direct Mode LSB */
-#define VS6624_FLASH_COARSE_MSB 0x11A5 /* coarse integration lines for Flash Gun Mode MSB */
-#define VS6624_FLASH_COARSE_LSB 0x11A6 /* coarse integration lines for Flash Gun Mode LSB */
-#define VS6624_FLASH_FINE_MSB 0x11A9 /* fine integration pixels for Flash Gun Mode MSB */
-#define VS6624_FLASH_FINE_LSB 0x11AA /* fine integration pixels for Flash Gun Mode LSB */
-#define VS6624_FLASH_ANAL_GAIN_MSB 0x11AD /* analog gain for Flash Gun Mode MSB */
-#define VS6624_FLASH_ANAL_GAIN_LSB 0x11AE /* analog gain for Flash Gun Mode LSB */
-#define VS6624_FLASH_DIGI_GAIN_MSB 0x11B1 /* digital gain for Flash Gun Mode MSB */
-#define VS6624_FLASH_DIGI_GAIN_LSB 0x11B2 /* digital gain for Flash Gun Mode LSB */
-#define VS6624_FREEZE_AE 0x11B4 /* freeze auto exposure */
-#define VS6624_MAX_INT_TIME_MSB 0x11B7 /* user maximum integration time MSB */
-#define VS6624_MAX_INT_TIME_LSB 0x11B8 /* user maximum integration time LSB */
-#define VS6624_FLASH_AG_THR_MSB 0x11BB /* recommend flash gun analog gain threshold MSB */
-#define VS6624_FLASH_AG_THR_LSB 0x11BC /* recommend flash gun analog gain threshold LSB */
-#define VS6624_ANTI_FLICKER_MODE 0x11C0 /* anti flicker mode */
-/* white balance control */
-#define VS6624_WB_MODE 0x1480 /* set white balance mode */
-#define VS6624_MAN_RG 0x1482 /* user setting for red channel gain */
-#define VS6624_MAN_GG 0x1484 /* user setting for green channel gain */
-#define VS6624_MAN_BG 0x1486 /* user setting for blue channel gain */
-#define VS6624_FLASH_RG_MSB 0x148B /* red gain for Flash Gun MSB */
-#define VS6624_FLASH_RG_LSB 0x148C /* red gain for Flash Gun LSB */
-#define VS6624_FLASH_GG_MSB 0x148F /* green gain for Flash Gun MSB */
-#define VS6624_FLASH_GG_LSB 0x1490 /* green gain for Flash Gun LSB */
-#define VS6624_FLASH_BG_MSB 0x1493 /* blue gain for Flash Gun MSB */
-#define VS6624_FLASH_BG_LSB 0x1494 /* blue gain for Flash Gun LSB */
-/* sensor setup */
-#define VS6624_BC_OFFSET 0x1990 /* Black Correction Offset */
-/* image stability */
-#define VS6624_STABLE_WB 0x1900 /* white balance stable */
-#define VS6624_STABLE_EXPO 0x1902 /* exposure stable */
-#define VS6624_STABLE 0x1906 /* system stable */
-/* flash control */
-#define VS6624_FLASH_MODE 0x1A80 /* flash mode */
-#define VS6624_FLASH_OFF_LINE_MSB 0x1A83 /* off line at flash pulse mode MSB */
-#define VS6624_FLASH_OFF_LINE_LSB 0x1A84 /* off line at flash pulse mode LSB */
-/* flash status */
-#define VS6624_FLASH_RECOM 0x1B00 /* flash gun is recommended */
-#define VS6624_FLASH_GRAB_COMPLETE 0x1B02 /* flash gun image has been grabbed */
-/* scythe filter controls */
-#define VS6624_SCYTHE_FILTER 0x1D80 /* disable scythe defect correction */
-/* jack filter controls */
-#define VS6624_JACK_FILTER 0x1E00 /* disable jack defect correction */
-/* demosaic control */
-#define VS6624_ANTI_ALIAS_FILTER 0x1E80 /* anti alias filter suppress */
-/* color matrix dampers */
-#define VS6624_CM_DISABLE 0x1F00 /* disable color matrix damper */
-#define VS6624_CM_LOW_THR_MSB 0x1F03 /* low threshold for exposure MSB */
-#define VS6624_CM_LOW_THR_LSB 0x1F04 /* low threshold for exposure LSB */
-#define VS6624_CM_HIGH_THR_MSB 0x1F07 /* high threshold for exposure MSB */
-#define VS6624_CM_HIGH_THR_LSB 0x1F08 /* high threshold for exposure LSB */
-#define VS6624_CM_MIN_OUT_MSB 0x1F0B /* minimum possible damper output MSB */
-#define VS6624_CM_MIN_OUT_LSB 0x1F0C /* minimum possible damper output LSB */
-/* peaking control */
-#define VS6624_PEAK_GAIN 0x2000 /* controls peaking gain */
-#define VS6624_PEAK_G_DISABLE 0x2002 /* disable peak gain damping */
-#define VS6624_PEAK_LOW_THR_G_MSB 0x2005 /* low threshold for exposure for gain MSB */
-#define VS6624_PEAK_LOW_THR_G_LSB 0x2006 /* low threshold for exposure for gain LSB */
-#define VS6624_PEAK_HIGH_THR_G_MSB 0x2009 /* high threshold for exposure for gain MSB */
-#define VS6624_PEAK_HIGH_THR_G_LSB 0x200A /* high threshold for exposure for gain LSB */
-#define VS6624_PEAK_MIN_OUT_G_MSB 0x200D /* minimum damper output for gain MSB */
-#define VS6624_PEAK_MIN_OUT_G_LSB 0x200E /* minimum damper output for gain LSB */
-#define VS6624_PEAK_LOW_THR 0x2010 /* adjust degree of coring */
-#define VS6624_PEAK_C_DISABLE 0x2012 /* disable coring damping */
-#define VS6624_PEAK_HIGH_THR 0x2014 /* adjust maximum gain */
-#define VS6624_PEAK_LOW_THR_C_MSB 0x2017 /* low threshold for exposure for coring MSB */
-#define VS6624_PEAK_LOW_THR_C_LSB 0x2018 /* low threshold for exposure for coring LSB */
-#define VS6624_PEAK_HIGH_THR_C_MSB 0x201B /* high threshold for exposure for coring MSB */
-#define VS6624_PEAK_HIGH_THR_C_LSB 0x201C /* high threshold for exposure for coring LSB */
-#define VS6624_PEAK_MIN_OUT_C_MSB 0x201F /* minimum damper output for coring MSB */
-#define VS6624_PEAK_MIN_OUT_C_LSB 0x2020 /* minimum damper output for coring LSB */
-/* pipe 0 RGB to YUV matrix manual control */
-#define VS6624_RYM0_MAN_CTRL 0x2180 /* enable manual RGB to YUV matrix */
-#define VS6624_RYM0_W00_MSB 0x2183 /* row 0 column 0 of YUV matrix MSB */
-#define VS6624_RYM0_W00_LSB 0x2184 /* row 0 column 0 of YUV matrix LSB */
-#define VS6624_RYM0_W01_MSB 0x2187 /* row 0 column 1 of YUV matrix MSB */
-#define VS6624_RYM0_W01_LSB 0x2188 /* row 0 column 1 of YUV matrix LSB */
-#define VS6624_RYM0_W02_MSB 0x218C /* row 0 column 2 of YUV matrix MSB */
-#define VS6624_RYM0_W02_LSB 0x218D /* row 0 column 2 of YUV matrix LSB */
-#define VS6624_RYM0_W10_MSB 0x2190 /* row 1 column 0 of YUV matrix MSB */
-#define VS6624_RYM0_W10_LSB 0x218F /* row 1 column 0 of YUV matrix LSB */
-#define VS6624_RYM0_W11_MSB 0x2193 /* row 1 column 1 of YUV matrix MSB */
-#define VS6624_RYM0_W11_LSB 0x2194 /* row 1 column 1 of YUV matrix LSB */
-#define VS6624_RYM0_W12_MSB 0x2197 /* row 1 column 2 of YUV matrix MSB */
-#define VS6624_RYM0_W12_LSB 0x2198 /* row 1 column 2 of YUV matrix LSB */
-#define VS6624_RYM0_W20_MSB 0x219B /* row 2 column 0 of YUV matrix MSB */
-#define VS6624_RYM0_W20_LSB 0x219C /* row 2 column 0 of YUV matrix LSB */
-#define VS6624_RYM0_W21_MSB 0x21A0 /* row 2 column 1 of YUV matrix MSB */
-#define VS6624_RYM0_W21_LSB 0x219F /* row 2 column 1 of YUV matrix LSB */
-#define VS6624_RYM0_W22_MSB 0x21A3 /* row 2 column 2 of YUV matrix MSB */
-#define VS6624_RYM0_W22_LSB 0x21A4 /* row 2 column 2 of YUV matrix LSB */
-#define VS6624_RYM0_YINY_MSB 0x21A7 /* Y in Y MSB */
-#define VS6624_RYM0_YINY_LSB 0x21A8 /* Y in Y LSB */
-#define VS6624_RYM0_YINCB_MSB 0x21AB /* Y in Cb MSB */
-#define VS6624_RYM0_YINCB_LSB 0x21AC /* Y in Cb LSB */
-#define VS6624_RYM0_YINCR_MSB 0x21B0 /* Y in Cr MSB */
-#define VS6624_RYM0_YINCR_LSB 0x21AF /* Y in Cr LSB */
-/* pipe 1 RGB to YUV matrix manual control */
-#define VS6624_RYM1_MAN_CTRL 0x2200 /* enable manual RGB to YUV matrix */
-#define VS6624_RYM1_W00_MSB 0x2203 /* row 0 column 0 of YUV matrix MSB */
-#define VS6624_RYM1_W00_LSB 0x2204 /* row 0 column 0 of YUV matrix LSB */
-#define VS6624_RYM1_W01_MSB 0x2207 /* row 0 column 1 of YUV matrix MSB */
-#define VS6624_RYM1_W01_LSB 0x2208 /* row 0 column 1 of YUV matrix LSB */
-#define VS6624_RYM1_W02_MSB 0x220C /* row 0 column 2 of YUV matrix MSB */
-#define VS6624_RYM1_W02_LSB 0x220D /* row 0 column 2 of YUV matrix LSB */
-#define VS6624_RYM1_W10_MSB 0x2210 /* row 1 column 0 of YUV matrix MSB */
-#define VS6624_RYM1_W10_LSB 0x220F /* row 1 column 0 of YUV matrix LSB */
-#define VS6624_RYM1_W11_MSB 0x2213 /* row 1 column 1 of YUV matrix MSB */
-#define VS6624_RYM1_W11_LSB 0x2214 /* row 1 column 1 of YUV matrix LSB */
-#define VS6624_RYM1_W12_MSB 0x2217 /* row 1 column 2 of YUV matrix MSB */
-#define VS6624_RYM1_W12_LSB 0x2218 /* row 1 column 2 of YUV matrix LSB */
-#define VS6624_RYM1_W20_MSB 0x221B /* row 2 column 0 of YUV matrix MSB */
-#define VS6624_RYM1_W20_LSB 0x221C /* row 2 column 0 of YUV matrix LSB */
-#define VS6624_RYM1_W21_MSB 0x2220 /* row 2 column 1 of YUV matrix MSB */
-#define VS6624_RYM1_W21_LSB 0x221F /* row 2 column 1 of YUV matrix LSB */
-#define VS6624_RYM1_W22_MSB 0x2223 /* row 2 column 2 of YUV matrix MSB */
-#define VS6624_RYM1_W22_LSB 0x2224 /* row 2 column 2 of YUV matrix LSB */
-#define VS6624_RYM1_YINY_MSB 0x2227 /* Y in Y MSB */
-#define VS6624_RYM1_YINY_LSB 0x2228 /* Y in Y LSB */
-#define VS6624_RYM1_YINCB_MSB 0x222B /* Y in Cb MSB */
-#define VS6624_RYM1_YINCB_LSB 0x222C /* Y in Cb LSB */
-#define VS6624_RYM1_YINCR_MSB 0x2220 /* Y in Cr MSB */
-#define VS6624_RYM1_YINCR_LSB 0x222F /* Y in Cr LSB */
-/* pipe 0 gamma manual control */
-#define VS6624_GAMMA_MAN_CTRL0 0x2280 /* enable manual gamma setup */
-#define VS6624_GAMMA_PEAK_R0 0x2282 /* peaked red channel gamma value */
-#define VS6624_GAMMA_PEAK_G0 0x2284 /* peaked green channel gamma value */
-#define VS6624_GAMMA_PEAK_B0 0x2286 /* peaked blue channel gamma value */
-#define VS6624_GAMMA_UNPEAK_R0 0x2288 /* unpeaked red channel gamma value */
-#define VS6624_GAMMA_UNPEAK_G0 0x228A /* unpeaked green channel gamma value */
-#define VS6624_GAMMA_UNPEAK_B0 0x228C /* unpeaked blue channel gamma value */
-/* pipe 1 gamma manual control */
-#define VS6624_GAMMA_MAN_CTRL1 0x2300 /* enable manual gamma setup */
-#define VS6624_GAMMA_PEAK_R1 0x2302 /* peaked red channel gamma value */
-#define VS6624_GAMMA_PEAK_G1 0x2304 /* peaked green channel gamma value */
-#define VS6624_GAMMA_PEAK_B1 0x2306 /* peaked blue channel gamma value */
-#define VS6624_GAMMA_UNPEAK_R1 0x2308 /* unpeaked red channel gamma value */
-#define VS6624_GAMMA_UNPEAK_G1 0x230A /* unpeaked green channel gamma value */
-#define VS6624_GAMMA_UNPEAK_B1 0x230C /* unpeaked blue channel gamma value */
-/* fade to black */
-#define VS6624_F2B_DISABLE 0x2480 /* disable fade to black */
-#define VS6624_F2B_BLACK_VAL_MSB 0x2483 /* black value MSB */
-#define VS6624_F2B_BLACK_VAL_LSB 0x2484 /* black value LSB */
-#define VS6624_F2B_LOW_THR_MSB 0x2487 /* low threshold for exposure MSB */
-#define VS6624_F2B_LOW_THR_LSB 0x2488 /* low threshold for exposure LSB */
-#define VS6624_F2B_HIGH_THR_MSB 0x248B /* high threshold for exposure MSB */
-#define VS6624_F2B_HIGH_THR_LSB 0x248C /* high threshold for exposure LSB */
-#define VS6624_F2B_MIN_OUT_MSB 0x248F /* minimum damper output MSB */
-#define VS6624_F2B_MIN_OUT_LSB 0x2490 /* minimum damper output LSB */
-/* output formatter control */
-#define VS6624_CODE_CK_EN 0x2580 /* code check enable */
-#define VS6624_BLANK_FMT 0x2582 /* blank format */
-#define VS6624_SYNC_CODE_SETUP 0x2584 /* sync code setup */
-#define VS6624_HSYNC_SETUP 0x2586 /* H sync setup */
-#define VS6624_VSYNC_SETUP 0x2588 /* V sync setup */
-#define VS6624_PCLK_SETUP 0x258A /* PCLK setup */
-#define VS6624_PCLK_EN 0x258C /* PCLK enable */
-#define VS6624_OPF_SP_SETUP 0x258E /* output formatter sp setup */
-#define VS6624_BLANK_DATA_MSB 0x2590 /* blank data MSB */
-#define VS6624_BLANK_DATA_LSB 0x2592 /* blank data LSB */
-#define VS6624_RGB_SETUP 0x2594 /* RGB setup */
-#define VS6624_YUV_SETUP 0x2596 /* YUV setup */
-#define VS6624_VSYNC_RIS_COARSE_H 0x2598 /* V sync rising coarse high */
-#define VS6624_VSYNC_RIS_COARSE_L 0x259A /* V sync rising coarse low */
-#define VS6624_VSYNC_RIS_FINE_H 0x259C /* V sync rising fine high */
-#define VS6624_VSYNC_RIS_FINE_L 0x259E /* V sync rising fine low */
-#define VS6624_VSYNC_FALL_COARSE_H 0x25A0 /* V sync falling coarse high */
-#define VS6624_VSYNC_FALL_COARSE_L 0x25A2 /* V sync falling coarse low */
-#define VS6624_VSYNC_FALL_FINE_H 0x25A4 /* V sync falling fine high */
-#define VS6624_VSYNC_FALL_FINE_L 0x25A6 /* V sync falling fine low */
-#define VS6624_HSYNC_RIS_H 0x25A8 /* H sync rising high */
-#define VS6624_HSYNC_RIS_L 0x25AA /* H sync rising low */
-#define VS6624_HSYNC_FALL_H 0x25AC /* H sync falling high */
-#define VS6624_HSYNC_FALL_L 0x25AE /* H sync falling low */
-#define VS6624_OUT_IF 0x25B0 /* output interface */
-#define VS6624_CCP_EXT_DATA 0x25B2 /* CCP extra data */
-/* NoRA controls */
-#define VS6624_NORA_DISABLE 0x2600 /* NoRA control mode */
-#define VS6624_NORA_USAGE 0x2602 /* usage */
-#define VS6624_NORA_SPLIT_KN 0x2604 /* split kn */
-#define VS6624_NORA_SPLIT_NI 0x2606 /* split ni */
-#define VS6624_NORA_TIGHT_G 0x2608 /* tight green */
-#define VS6624_NORA_DISABLE_NP 0x260A /* disable noro promoting */
-#define VS6624_NORA_LOW_THR_MSB 0x260D /* low threshold for exposure MSB */
-#define VS6624_NORA_LOW_THR_LSB 0x260E /* low threshold for exposure LSB */
-#define VS6624_NORA_HIGH_THR_MSB 0x2611 /* high threshold for exposure MSB */
-#define VS6624_NORA_HIGH_THR_LSB 0x2612 /* high threshold for exposure LSB */
-#define VS6624_NORA_MIN_OUT_MSB 0x2615 /* minimum damper output MSB */
-#define VS6624_NORA_MIN_OUT_LSB 0x2616 /* minimum damper output LSB */
-
-#endif
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
deleted file mode 100644
index db2a6003a1c..00000000000
--- a/drivers/media/video/w9966.c
+++ /dev/null
@@ -1,981 +0,0 @@
-/*
- Winbond w9966cf Webcam parport driver.
-
- Version 0.33
-
- Copyright (C) 2001 Jakob Kemi <jakob.kemi@post.utfors.se>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-/*
- Supported devices:
- *Lifeview FlyCam Supra (using the Philips saa7111a chip)
-
- Does any other model using the w9966 interface chip exist ?
-
- Todo:
-
- *Add a working EPP mode, since DMA ECP read isn't implemented
- in the parport drivers. (That's why it's so sloow)
-
- *Add support for other ccd-control chips than the saa7111
- please send me feedback on what kind of chips you have.
-
- *Add proper probing. I don't know what's wrong with the IEEE1284
- parport drivers but (IEEE1284_MODE_NIBBLE|IEEE1284_DEVICE_ID)
- and nibble read seems to be broken for some peripherals.
-
- *Add probing for onboard SRAM, port directions etc. (if possible)
-
- *Add support for the hardware compressed modes (maybe using v4l2)
-
- *Fix better support for the capture window (no skewed images, v4l
- interface to capt. window)
-
- *Probably some bugs that I don't know of
-
- Please support me by sending feedback!
-
- Changes:
-
- Alan Cox: Removed RGB mode for kernel merge, added THIS_MODULE
- and owner support for newer module locks
-*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
-#include <linux/parport.h>
-
-/*#define DEBUG*/ /* Undef me for production */
-
-#ifdef DEBUG
-#define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: %s(): "x, __func__ , ##a)
-#else
-#define DPRINTF(x...)
-#endif
-
-/*
- * Defines, simple typedefs etc.
- */
-
-#define W9966_DRIVERNAME "W9966CF Webcam"
-#define W9966_MAXCAMS 4 /* Maximum number of cameras */
-#define W9966_RBUFFER 2048 /* Read buffer (must be an even number) */
-#define W9966_SRAMSIZE 131072 /* 128kb */
-#define W9966_SRAMID 0x02 /* check w9966cf.pdf */
-
-/* Empirically determined window limits */
-#define W9966_WND_MIN_X 16
-#define W9966_WND_MIN_Y 14
-#define W9966_WND_MAX_X 705
-#define W9966_WND_MAX_Y 253
-#define W9966_WND_MAX_W (W9966_WND_MAX_X - W9966_WND_MIN_X)
-#define W9966_WND_MAX_H (W9966_WND_MAX_Y - W9966_WND_MIN_Y)
-
-/* Keep track of our current state */
-#define W9966_STATE_PDEV 0x01
-#define W9966_STATE_CLAIMED 0x02
-#define W9966_STATE_VDEV 0x04
-
-#define W9966_I2C_W_ID 0x48
-#define W9966_I2C_R_ID 0x49
-#define W9966_I2C_R_DATA 0x08
-#define W9966_I2C_R_CLOCK 0x04
-#define W9966_I2C_W_DATA 0x02
-#define W9966_I2C_W_CLOCK 0x01
-
-struct w9966 {
- struct v4l2_device v4l2_dev;
- struct v4l2_ctrl_handler hdl;
- unsigned char dev_state;
- unsigned char i2c_state;
- unsigned short ppmode;
- struct parport *pport;
- struct pardevice *pdev;
- struct video_device vdev;
- unsigned short width;
- unsigned short height;
- unsigned char brightness;
- signed char contrast;
- signed char color;
- signed char hue;
- struct mutex lock;
-};
-
-/*
- * Module specific properties
- */
-
-MODULE_AUTHOR("Jakob Kemi <jakob.kemi@post.utfors.se>");
-MODULE_DESCRIPTION("Winbond w9966cf WebCam driver (0.32)");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.33.1");
-
-#ifdef MODULE
-static char *pardev[] = {[0 ... W9966_MAXCAMS] = ""};
-#else
-static char *pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"};
-#endif
-module_param_array(pardev, charp, NULL, 0);
-MODULE_PARM_DESC(pardev, "pardev: where to search for\n"
- "\teach camera. 'aggressive' means brute-force search.\n"
- "\tEg: >pardev=parport3,aggressive,parport2,parport1< would assign\n"
- "\tcam 1 to parport3 and search every parport for cam 2 etc...");
-
-static int parmode;
-module_param(parmode, int, 0);
-MODULE_PARM_DESC(parmode, "parmode: transfer mode (0=auto, 1=ecp, 2=epp");
-
-static int video_nr = -1;
-module_param(video_nr, int, 0);
-
-static struct w9966 w9966_cams[W9966_MAXCAMS];
-
-/*
- * Private function defines
- */
-
-
-/* Set camera phase flags, so we know what to uninit when terminating */
-static inline void w9966_set_state(struct w9966 *cam, int mask, int val)
-{
- cam->dev_state = (cam->dev_state & ~mask) ^ val;
-}
-
-/* Get camera phase flags */
-static inline int w9966_get_state(struct w9966 *cam, int mask, int val)
-{
- return ((cam->dev_state & mask) == val);
-}
-
-/* Claim parport for ourself */
-static void w9966_pdev_claim(struct w9966 *cam)
-{
- if (w9966_get_state(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED))
- return;
- parport_claim_or_block(cam->pdev);
- w9966_set_state(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED);
-}
-
-/* Release parport for others to use */
-static void w9966_pdev_release(struct w9966 *cam)
-{
- if (w9966_get_state(cam, W9966_STATE_CLAIMED, 0))
- return;
- parport_release(cam->pdev);
- w9966_set_state(cam, W9966_STATE_CLAIMED, 0);
-}
-
-/* Read register from W9966 interface-chip
- Expects a claimed pdev
- -1 on error, else register data (byte) */
-static int w9966_read_reg(struct w9966 *cam, int reg)
-{
- /* ECP, read, regtransfer, REG, REG, REG, REG, REG */
- const unsigned char addr = 0x80 | (reg & 0x1f);
- unsigned char val;
-
- if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
- return -1;
- if (parport_write(cam->pport, &addr, 1) != 1)
- return -1;
- if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
- return -1;
- if (parport_read(cam->pport, &val, 1) != 1)
- return -1;
-
- return val;
-}
-
-/* Write register to W9966 interface-chip
- Expects a claimed pdev
- -1 on error */
-static int w9966_write_reg(struct w9966 *cam, int reg, int data)
-{
- /* ECP, write, regtransfer, REG, REG, REG, REG, REG */
- const unsigned char addr = 0xc0 | (reg & 0x1f);
- const unsigned char val = data;
-
- if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
- return -1;
- if (parport_write(cam->pport, &addr, 1) != 1)
- return -1;
- if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
- return -1;
- if (parport_write(cam->pport, &val, 1) != 1)
- return -1;
-
- return 0;
-}
-
-/*
- * Ugly and primitive i2c protocol functions
- */
-
-/* Sets the data line on the i2c bus.
- Expects a claimed pdev. */
-static void w9966_i2c_setsda(struct w9966 *cam, int state)
-{
- if (state)
- cam->i2c_state |= W9966_I2C_W_DATA;
- else
- cam->i2c_state &= ~W9966_I2C_W_DATA;
-
- w9966_write_reg(cam, 0x18, cam->i2c_state);
- udelay(5);
-}
-
-/* Get peripheral clock line
- Expects a claimed pdev. */
-static int w9966_i2c_getscl(struct w9966 *cam)
-{
- const unsigned char state = w9966_read_reg(cam, 0x18);
- return ((state & W9966_I2C_R_CLOCK) > 0);
-}
-
-/* Sets the clock line on the i2c bus.
- Expects a claimed pdev. -1 on error */
-static int w9966_i2c_setscl(struct w9966 *cam, int state)
-{
- unsigned long timeout;
-
- if (state)
- cam->i2c_state |= W9966_I2C_W_CLOCK;
- else
- cam->i2c_state &= ~W9966_I2C_W_CLOCK;
-
- w9966_write_reg(cam, 0x18, cam->i2c_state);
- udelay(5);
-
- /* we go to high, we also expect the peripheral to ack. */
- if (state) {
- timeout = jiffies + 100;
- while (!w9966_i2c_getscl(cam)) {
- if (time_after(jiffies, timeout))
- return -1;
- }
- }
- return 0;
-}
-
-#if 0
-/* Get peripheral data line
- Expects a claimed pdev. */
-static int w9966_i2c_getsda(struct w9966 *cam)
-{
- const unsigned char state = w9966_read_reg(cam, 0x18);
- return ((state & W9966_I2C_R_DATA) > 0);
-}
-#endif
-
-/* Write a byte with ack to the i2c bus.
- Expects a claimed pdev. -1 on error */
-static int w9966_i2c_wbyte(struct w9966 *cam, int data)
-{
- int i;
-
- for (i = 7; i >= 0; i--) {
- w9966_i2c_setsda(cam, (data >> i) & 0x01);
-
- if (w9966_i2c_setscl(cam, 1) == -1)
- return -1;
- w9966_i2c_setscl(cam, 0);
- }
-
- w9966_i2c_setsda(cam, 1);
-
- if (w9966_i2c_setscl(cam, 1) == -1)
- return -1;
- w9966_i2c_setscl(cam, 0);
-
- return 0;
-}
-
-/* Read a data byte with ack from the i2c-bus
- Expects a claimed pdev. -1 on error */
-#if 0
-static int w9966_i2c_rbyte(struct w9966 *cam)
-{
- unsigned char data = 0x00;
- int i;
-
- w9966_i2c_setsda(cam, 1);
-
- for (i = 0; i < 8; i++) {
- if (w9966_i2c_setscl(cam, 1) == -1)
- return -1;
- data = data << 1;
- if (w9966_i2c_getsda(cam))
- data |= 0x01;
-
- w9966_i2c_setscl(cam, 0);
- }
- return data;
-}
-#endif
-
-/* Read a register from the i2c device.
- Expects claimed pdev. -1 on error */
-#if 0
-static int w9966_read_reg_i2c(struct w9966 *cam, int reg)
-{
- int data;
-
- w9966_i2c_setsda(cam, 0);
- w9966_i2c_setscl(cam, 0);
-
- if (w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
- w9966_i2c_wbyte(cam, reg) == -1)
- return -1;
-
- w9966_i2c_setsda(cam, 1);
- if (w9966_i2c_setscl(cam, 1) == -1)
- return -1;
- w9966_i2c_setsda(cam, 0);
- w9966_i2c_setscl(cam, 0);
-
- if (w9966_i2c_wbyte(cam, W9966_I2C_R_ID) == -1)
- return -1;
- data = w9966_i2c_rbyte(cam);
- if (data == -1)
- return -1;
-
- w9966_i2c_setsda(cam, 0);
-
- if (w9966_i2c_setscl(cam, 1) == -1)
- return -1;
- w9966_i2c_setsda(cam, 1);
-
- return data;
-}
-#endif
-
-/* Write a register to the i2c device.
- Expects claimed pdev. -1 on error */
-static int w9966_write_reg_i2c(struct w9966 *cam, int reg, int data)
-{
- w9966_i2c_setsda(cam, 0);
- w9966_i2c_setscl(cam, 0);
-
- if (w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
- w9966_i2c_wbyte(cam, reg) == -1 ||
- w9966_i2c_wbyte(cam, data) == -1)
- return -1;
-
- w9966_i2c_setsda(cam, 0);
- if (w9966_i2c_setscl(cam, 1) == -1)
- return -1;
-
- w9966_i2c_setsda(cam, 1);
-
- return 0;
-}
-
-/* Find a good length for capture window (used both for W and H)
- A bit ugly but pretty functional. The capture length
- have to match the downscale */
-static int w9966_findlen(int near, int size, int maxlen)
-{
- int bestlen = size;
- int besterr = abs(near - bestlen);
- int len;
-
- for (len = size + 1; len < maxlen; len++) {
- int err;
- if (((64 * size) % len) != 0)
- continue;
-
- err = abs(near - len);
-
- /* Only continue as long as we keep getting better values */
- if (err > besterr)
- break;
-
- besterr = err;
- bestlen = len;
- }
-
- return bestlen;
-}
-
-/* Modify capture window (if necessary)
- and calculate downscaling
- Return -1 on error */
-static int w9966_calcscale(int size, int min, int max, int *beg, int *end, unsigned char *factor)
-{
- int maxlen = max - min;
- int len = *end - *beg + 1;
- int newlen = w9966_findlen(len, size, maxlen);
- int err = newlen - len;
-
- /* Check for bad format */
- if (newlen > maxlen || newlen < size)
- return -1;
-
- /* Set factor (6 bit fixed) */
- *factor = (64 * size) / newlen;
- if (*factor == 64)
- *factor = 0x00; /* downscale is disabled */
- else
- *factor |= 0x80; /* set downscale-enable bit */
-
- /* Modify old beginning and end */
- *beg -= err / 2;
- *end += err - (err / 2);
-
- /* Move window if outside borders */
- if (*beg < min) {
- *end += min - *beg;
- *beg += min - *beg;
- }
- if (*end > max) {
- *beg -= *end - max;
- *end -= *end - max;
- }
-
- return 0;
-}
-
-/* Setup the cameras capture window etc.
- Expects a claimed pdev
- return -1 on error */
-static int w9966_setup(struct w9966 *cam, int x1, int y1, int x2, int y2, int w, int h)
-{
- unsigned int i;
- unsigned int enh_s, enh_e;
- unsigned char scale_x, scale_y;
- unsigned char regs[0x1c];
- unsigned char saa7111_regs[] = {
- 0x21, 0x00, 0xd8, 0x23, 0x00, 0x80, 0x80, 0x00,
- 0x88, 0x10, 0x80, 0x40, 0x40, 0x00, 0x01, 0x00,
- 0x48, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x71, 0xe7, 0x00, 0x00, 0xc0
- };
-
-
- if (w * h * 2 > W9966_SRAMSIZE) {
- DPRINTF("capture window exceeds SRAM size!.\n");
- w = 200; h = 160; /* Pick default values */
- }
-
- w &= ~0x1;
- if (w < 2)
- w = 2;
- if (h < 1)
- h = 1;
- if (w > W9966_WND_MAX_W)
- w = W9966_WND_MAX_W;
- if (h > W9966_WND_MAX_H)
- h = W9966_WND_MAX_H;
-
- cam->width = w;
- cam->height = h;
-
- enh_s = 0;
- enh_e = w * h * 2;
-
- /* Modify capture window if necessary and calculate downscaling */
- if (w9966_calcscale(w, W9966_WND_MIN_X, W9966_WND_MAX_X, &x1, &x2, &scale_x) != 0 ||
- w9966_calcscale(h, W9966_WND_MIN_Y, W9966_WND_MAX_Y, &y1, &y2, &scale_y) != 0)
- return -1;
-
- DPRINTF("%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n",
- w, h, x1, x2, y1, y2, scale_x & ~0x80, scale_y & ~0x80);
-
- /* Setup registers */
- regs[0x00] = 0x00; /* Set normal operation */
- regs[0x01] = 0x18; /* Capture mode */
- regs[0x02] = scale_y; /* V-scaling */
- regs[0x03] = scale_x; /* H-scaling */
-
- /* Capture window */
- regs[0x04] = (x1 & 0x0ff); /* X-start (8 low bits) */
- regs[0x05] = (x1 & 0x300)>>8; /* X-start (2 high bits) */
- regs[0x06] = (y1 & 0x0ff); /* Y-start (8 low bits) */
- regs[0x07] = (y1 & 0x300)>>8; /* Y-start (2 high bits) */
- regs[0x08] = (x2 & 0x0ff); /* X-end (8 low bits) */
- regs[0x09] = (x2 & 0x300)>>8; /* X-end (2 high bits) */
- regs[0x0a] = (y2 & 0x0ff); /* Y-end (8 low bits) */
-
- regs[0x0c] = W9966_SRAMID; /* SRAM-banks (1x 128kb) */
-
- /* Enhancement layer */
- regs[0x0d] = (enh_s & 0x000ff); /* Enh. start (0-7) */
- regs[0x0e] = (enh_s & 0x0ff00) >> 8; /* Enh. start (8-15) */
- regs[0x0f] = (enh_s & 0x70000) >> 16; /* Enh. start (16-17/18??) */
- regs[0x10] = (enh_e & 0x000ff); /* Enh. end (0-7) */
- regs[0x11] = (enh_e & 0x0ff00) >> 8; /* Enh. end (8-15) */
- regs[0x12] = (enh_e & 0x70000) >> 16; /* Enh. end (16-17/18??) */
-
- /* Misc */
- regs[0x13] = 0x40; /* VEE control (raw 4:2:2) */
- regs[0x17] = 0x00; /* ??? */
- regs[0x18] = cam->i2c_state = 0x00; /* Serial bus */
- regs[0x19] = 0xff; /* I/O port direction control */
- regs[0x1a] = 0xff; /* I/O port data register */
- regs[0x1b] = 0x10; /* ??? */
-
- /* SAA7111 chip settings */
- saa7111_regs[0x0a] = cam->brightness;
- saa7111_regs[0x0b] = cam->contrast;
- saa7111_regs[0x0c] = cam->color;
- saa7111_regs[0x0d] = cam->hue;
-
- /* Reset (ECP-fifo & serial-bus) */
- if (w9966_write_reg(cam, 0x00, 0x03) == -1)
- return -1;
-
- /* Write regs to w9966cf chip */
- for (i = 0; i < 0x1c; i++)
- if (w9966_write_reg(cam, i, regs[i]) == -1)
- return -1;
-
- /* Write regs to saa7111 chip */
- for (i = 0; i < 0x20; i++)
- if (w9966_write_reg_i2c(cam, i, saa7111_regs[i]) == -1)
- return -1;
-
- return 0;
-}
-
-/*
- * Video4linux interfacing
- */
-
-static int cam_querycap(struct file *file, void *priv,
- struct v4l2_capability *vcap)
-{
- struct w9966 *cam = video_drvdata(file);
-
- strlcpy(vcap->driver, cam->v4l2_dev.name, sizeof(vcap->driver));
- strlcpy(vcap->card, W9966_DRIVERNAME, sizeof(vcap->card));
- strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
- vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
- vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
- return 0;
-}
-
-static int cam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
-{
- if (vin->index > 0)
- return -EINVAL;
- strlcpy(vin->name, "Camera", sizeof(vin->name));
- vin->type = V4L2_INPUT_TYPE_CAMERA;
- vin->audioset = 0;
- vin->tuner = 0;
- vin->std = 0;
- vin->status = 0;
- return 0;
-}
-
-static int cam_g_input(struct file *file, void *fh, unsigned int *inp)
-{
- *inp = 0;
- return 0;
-}
-
-static int cam_s_input(struct file *file, void *fh, unsigned int inp)
-{
- return (inp > 0) ? -EINVAL : 0;
-}
-
-static int cam_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct w9966 *cam =
- container_of(ctrl->handler, struct w9966, hdl);
- int ret = 0;
-
- mutex_lock(&cam->lock);
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- cam->brightness = ctrl->val;
- break;
- case V4L2_CID_CONTRAST:
- cam->contrast = ctrl->val;
- break;
- case V4L2_CID_SATURATION:
- cam->color = ctrl->val;
- break;
- case V4L2_CID_HUE:
- cam->hue = ctrl->val;
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- if (ret == 0) {
- w9966_pdev_claim(cam);
-
- if (w9966_write_reg_i2c(cam, 0x0a, cam->brightness) == -1 ||
- w9966_write_reg_i2c(cam, 0x0b, cam->contrast) == -1 ||
- w9966_write_reg_i2c(cam, 0x0c, cam->color) == -1 ||
- w9966_write_reg_i2c(cam, 0x0d, cam->hue) == -1) {
- ret = -EIO;
- }
-
- w9966_pdev_release(cam);
- }
- mutex_unlock(&cam->lock);
- return ret;
-}
-
-static int cam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct w9966 *cam = video_drvdata(file);
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
-
- pix->width = cam->width;
- pix->height = cam->height;
- pix->pixelformat = V4L2_PIX_FMT_YUYV;
- pix->field = V4L2_FIELD_NONE;
- pix->bytesperline = 2 * cam->width;
- pix->sizeimage = 2 * cam->width * cam->height;
- /* Just a guess */
- pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
- return 0;
-}
-
-static int cam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
-
- if (pix->width < 2)
- pix->width = 2;
- if (pix->height < 1)
- pix->height = 1;
- if (pix->width > W9966_WND_MAX_W)
- pix->width = W9966_WND_MAX_W;
- if (pix->height > W9966_WND_MAX_H)
- pix->height = W9966_WND_MAX_H;
- pix->pixelformat = V4L2_PIX_FMT_YUYV;
- pix->field = V4L2_FIELD_NONE;
- pix->bytesperline = 2 * pix->width;
- pix->sizeimage = 2 * pix->width * pix->height;
- /* Just a guess */
- pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
- return 0;
-}
-
-static int cam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct w9966 *cam = video_drvdata(file);
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
- int ret = cam_try_fmt_vid_cap(file, fh, fmt);
-
- if (ret)
- return ret;
-
- mutex_lock(&cam->lock);
- /* Update camera regs */
- w9966_pdev_claim(cam);
- ret = w9966_setup(cam, 0, 0, 1023, 1023, pix->width, pix->height);
- w9966_pdev_release(cam);
- mutex_unlock(&cam->lock);
- return ret;
-}
-
-static int cam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
-{
- static struct v4l2_fmtdesc formats[] = {
- { 0, 0, 0,
- "YUV 4:2:2", V4L2_PIX_FMT_YUYV,
- { 0, 0, 0, 0 }
- },
- };
- enum v4l2_buf_type type = fmt->type;
-
- if (fmt->index > 0)
- return -EINVAL;
-
- *fmt = formats[fmt->index];
- fmt->type = type;
- return 0;
-}
-
-/* Capture data */
-static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct w9966 *cam = video_drvdata(file);
- unsigned char addr = 0xa0; /* ECP, read, CCD-transfer, 00000 */
- unsigned char __user *dest = (unsigned char __user *)buf;
- unsigned long dleft = count;
- unsigned char *tbuf;
-
- /* Why would anyone want more than this?? */
- if (count > cam->width * cam->height * 2)
- return -EINVAL;
-
- mutex_lock(&cam->lock);
- w9966_pdev_claim(cam);
- w9966_write_reg(cam, 0x00, 0x02); /* Reset ECP-FIFO buffer */
- w9966_write_reg(cam, 0x00, 0x00); /* Return to normal operation */
- w9966_write_reg(cam, 0x01, 0x98); /* Enable capture */
-
- /* write special capture-addr and negotiate into data transfer */
- if ((parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0) ||
- (parport_write(cam->pport, &addr, 1) != 1) ||
- (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0)) {
- w9966_pdev_release(cam);
- mutex_unlock(&cam->lock);
- return -EFAULT;
- }
-
- tbuf = kmalloc(W9966_RBUFFER, GFP_KERNEL);
- if (tbuf == NULL) {
- count = -ENOMEM;
- goto out;
- }
-
- while (dleft > 0) {
- unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
-
- if (parport_read(cam->pport, tbuf, tsize) < tsize) {
- count = -EFAULT;
- goto out;
- }
- if (copy_to_user(dest, tbuf, tsize) != 0) {
- count = -EFAULT;
- goto out;
- }
- dest += tsize;
- dleft -= tsize;
- }
-
- w9966_write_reg(cam, 0x01, 0x18); /* Disable capture */
-
-out:
- kfree(tbuf);
- w9966_pdev_release(cam);
- mutex_unlock(&cam->lock);
-
- return count;
-}
-
-static const struct v4l2_file_operations w9966_fops = {
- .owner = THIS_MODULE,
- .open = v4l2_fh_open,
- .release = v4l2_fh_release,
- .poll = v4l2_ctrl_poll,
- .unlocked_ioctl = video_ioctl2,
- .read = w9966_v4l_read,
-};
-
-static const struct v4l2_ioctl_ops w9966_ioctl_ops = {
- .vidioc_querycap = cam_querycap,
- .vidioc_g_input = cam_g_input,
- .vidioc_s_input = cam_s_input,
- .vidioc_enum_input = cam_enum_input,
- .vidioc_enum_fmt_vid_cap = cam_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cam_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = cam_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cam_try_fmt_vid_cap,
- .vidioc_log_status = v4l2_ctrl_log_status,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static const struct v4l2_ctrl_ops cam_ctrl_ops = {
- .s_ctrl = cam_s_ctrl,
-};
-
-
-/* Initialize camera device. Setup all internal flags, set a
- default video mode, setup ccd-chip, register v4l device etc..
- Also used for 'probing' of hardware.
- -1 on error */
-static int w9966_init(struct w9966 *cam, struct parport *port)
-{
- struct v4l2_device *v4l2_dev = &cam->v4l2_dev;
-
- if (cam->dev_state != 0)
- return -1;
-
- strlcpy(v4l2_dev->name, "w9966", sizeof(v4l2_dev->name));
-
- if (v4l2_device_register(NULL, v4l2_dev) < 0) {
- v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
- return -1;
- }
-
- v4l2_ctrl_handler_init(&cam->hdl, 4);
- v4l2_ctrl_new_std(&cam->hdl, &cam_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&cam->hdl, &cam_ctrl_ops,
- V4L2_CID_CONTRAST, -64, 64, 1, 64);
- v4l2_ctrl_new_std(&cam->hdl, &cam_ctrl_ops,
- V4L2_CID_SATURATION, -64, 64, 1, 64);
- v4l2_ctrl_new_std(&cam->hdl, &cam_ctrl_ops,
- V4L2_CID_HUE, -128, 127, 1, 0);
- if (cam->hdl.error) {
- v4l2_err(v4l2_dev, "couldn't register controls\n");
- return -1;
- }
- cam->pport = port;
- cam->brightness = 128;
- cam->contrast = 64;
- cam->color = 64;
- cam->hue = 0;
-
- /* Select requested transfer mode */
- switch (parmode) {
- default: /* Auto-detect (priority: hw-ecp, hw-epp, sw-ecp) */
- case 0:
- if (port->modes & PARPORT_MODE_ECP)
- cam->ppmode = IEEE1284_MODE_ECP;
- else if (port->modes & PARPORT_MODE_EPP)
- cam->ppmode = IEEE1284_MODE_EPP;
- else
- cam->ppmode = IEEE1284_MODE_ECP;
- break;
- case 1: /* hw- or sw-ecp */
- cam->ppmode = IEEE1284_MODE_ECP;
- break;
- case 2: /* hw- or sw-epp */
- cam->ppmode = IEEE1284_MODE_EPP;
- break;
- }
-
- /* Tell the parport driver that we exists */
- cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL);
- if (cam->pdev == NULL) {
- DPRINTF("parport_register_device() failed\n");
- return -1;
- }
- w9966_set_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV);
-
- w9966_pdev_claim(cam);
-
- /* Setup a default capture mode */
- if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) {
- DPRINTF("w9966_setup() failed.\n");
- return -1;
- }
-
- w9966_pdev_release(cam);
-
- /* Fill in the video_device struct and register us to v4l */
- strlcpy(cam->vdev.name, W9966_DRIVERNAME, sizeof(cam->vdev.name));
- cam->vdev.v4l2_dev = v4l2_dev;
- cam->vdev.fops = &w9966_fops;
- cam->vdev.ioctl_ops = &w9966_ioctl_ops;
- cam->vdev.release = video_device_release_empty;
- cam->vdev.ctrl_handler = &cam->hdl;
- set_bit(V4L2_FL_USE_FH_PRIO, &cam->vdev.flags);
- video_set_drvdata(&cam->vdev, cam);
-
- mutex_init(&cam->lock);
-
- if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0)
- return -1;
-
- w9966_set_state(cam, W9966_STATE_VDEV, W9966_STATE_VDEV);
-
- /* All ok */
- v4l2_info(v4l2_dev, "Found and initialized a webcam on %s.\n",
- cam->pport->name);
- return 0;
-}
-
-
-/* Terminate everything gracefully */
-static void w9966_term(struct w9966 *cam)
-{
- /* Unregister from v4l */
- if (w9966_get_state(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) {
- video_unregister_device(&cam->vdev);
- w9966_set_state(cam, W9966_STATE_VDEV, 0);
- }
-
- v4l2_ctrl_handler_free(&cam->hdl);
-
- /* Terminate from IEEE1284 mode and release pdev block */
- if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
- w9966_pdev_claim(cam);
- parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
- w9966_pdev_release(cam);
- }
-
- /* Unregister from parport */
- if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
- parport_unregister_device(cam->pdev);
- w9966_set_state(cam, W9966_STATE_PDEV, 0);
- }
- memset(cam, 0, sizeof(*cam));
-}
-
-
-/* Called once for every parport on init */
-static void w9966_attach(struct parport *port)
-{
- int i;
-
- for (i = 0; i < W9966_MAXCAMS; i++) {
- if (w9966_cams[i].dev_state != 0) /* Cam is already assigned */
- continue;
- if (strcmp(pardev[i], "aggressive") == 0 || strcmp(pardev[i], port->name) == 0) {
- if (w9966_init(&w9966_cams[i], port) != 0)
- w9966_term(&w9966_cams[i]);
- break; /* return */
- }
- }
-}
-
-/* Called once for every parport on termination */
-static void w9966_detach(struct parport *port)
-{
- int i;
-
- for (i = 0; i < W9966_MAXCAMS; i++)
- if (w9966_cams[i].dev_state != 0 && w9966_cams[i].pport == port)
- w9966_term(&w9966_cams[i]);
-}
-
-
-static struct parport_driver w9966_ppd = {
- .name = W9966_DRIVERNAME,
- .attach = w9966_attach,
- .detach = w9966_detach,
-};
-
-/* Module entry point */
-static int __init w9966_mod_init(void)
-{
- int i;
-
- for (i = 0; i < W9966_MAXCAMS; i++)
- w9966_cams[i].dev_state = 0;
-
- return parport_register_driver(&w9966_ppd);
-}
-
-/* Module cleanup */
-static void __exit w9966_mod_term(void)
-{
- parport_unregister_driver(&w9966_ppd);
-}
-
-module_init(w9966_mod_init);
-module_exit(w9966_mod_term);
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
deleted file mode 100644
index 3bb99e93feb..00000000000
--- a/drivers/media/video/wm8739.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * wm8739
- *
- * Copyright (C) 2005 T. Adachi <tadachi@tadachi-net.com>
- *
- * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl>
- * - Cleanup
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-
-MODULE_DESCRIPTION("wm8739 driver");
-MODULE_AUTHOR("T. Adachi, Hans Verkuil");
-MODULE_LICENSE("GPL");
-
-static int debug;
-
-module_param(debug, int, 0644);
-
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-
-/* ------------------------------------------------------------------------ */
-
-enum {
- R0 = 0, R1,
- R5 = 5, R6, R7, R8, R9, R15 = 15,
- TOT_REGS
-};
-
-struct wm8739_state {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- struct {
- /* audio cluster */
- struct v4l2_ctrl *volume;
- struct v4l2_ctrl *mute;
- struct v4l2_ctrl *balance;
- };
- u32 clock_freq;
-};
-
-static inline struct wm8739_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct wm8739_state, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct wm8739_state, hdl)->sd;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int wm8739_write(struct v4l2_subdev *sd, int reg, u16 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int i;
-
- if (reg < 0 || reg >= TOT_REGS) {
- v4l2_err(sd, "Invalid register R%d\n", reg);
- return -1;
- }
-
- v4l2_dbg(1, debug, sd, "write: %02x %02x\n", reg, val);
-
- for (i = 0; i < 3; i++)
- if (i2c_smbus_write_byte_data(client,
- (reg << 1) | (val >> 8), val & 0xff) == 0)
- return 0;
- v4l2_err(sd, "I2C: cannot write %03x to register R%d\n", val, reg);
- return -1;
-}
-
-static int wm8739_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct wm8739_state *state = to_state(sd);
- unsigned int work_l, work_r;
- u8 vol_l; /* +12dB to -34.5dB 1.5dB step (5bit) def:0dB */
- u8 vol_r; /* +12dB to -34.5dB 1.5dB step (5bit) def:0dB */
- u16 mute;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- break;
-
- default:
- return -EINVAL;
- }
-
- /* normalize ( 65535 to 0 -> 31 to 0 (12dB to -34.5dB) ) */
- work_l = (min(65536 - state->balance->val, 32768) * state->volume->val) / 32768;
- work_r = (min(state->balance->val, 32768) * state->volume->val) / 32768;
-
- vol_l = (long)work_l * 31 / 65535;
- vol_r = (long)work_r * 31 / 65535;
-
- /* set audio volume etc. */
- mute = state->mute->val ? 0x80 : 0;
-
- /* Volume setting: bits 0-4, 0x1f = 12 dB, 0x00 = -34.5 dB
- * Default setting: 0x17 = 0 dB
- */
- wm8739_write(sd, R0, (vol_l & 0x1f) | mute);
- wm8739_write(sd, R1, (vol_r & 0x1f) | mute);
- return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int wm8739_s_clock_freq(struct v4l2_subdev *sd, u32 audiofreq)
-{
- struct wm8739_state *state = to_state(sd);
-
- state->clock_freq = audiofreq;
- /* de-activate */
- wm8739_write(sd, R9, 0x000);
- switch (audiofreq) {
- case 44100:
- /* 256fps, fs=44.1k */
- wm8739_write(sd, R8, 0x020);
- break;
- case 48000:
- /* 256fps, fs=48k */
- wm8739_write(sd, R8, 0x000);
- break;
- case 32000:
- /* 256fps, fs=32k */
- wm8739_write(sd, R8, 0x018);
- break;
- default:
- break;
- }
- /* activate */
- wm8739_write(sd, R9, 0x001);
- return 0;
-}
-
-static int wm8739_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_WM8739, 0);
-}
-
-static int wm8739_log_status(struct v4l2_subdev *sd)
-{
- struct wm8739_state *state = to_state(sd);
-
- v4l2_info(sd, "Frequency: %u Hz\n", state->clock_freq);
- v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_ctrl_ops wm8739_ctrl_ops = {
- .s_ctrl = wm8739_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops wm8739_core_ops = {
- .log_status = wm8739_log_status,
- .g_chip_ident = wm8739_g_chip_ident,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
-};
-
-static const struct v4l2_subdev_audio_ops wm8739_audio_ops = {
- .s_clock_freq = wm8739_s_clock_freq,
-};
-
-static const struct v4l2_subdev_ops wm8739_ops = {
- .core = &wm8739_core_ops,
- .audio = &wm8739_audio_ops,
-};
-
-/* ------------------------------------------------------------------------ */
-
-/* i2c implementation */
-
-static int wm8739_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct wm8739_state *state;
- struct v4l2_subdev *sd;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- state = kzalloc(sizeof(struct wm8739_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &wm8739_ops);
- v4l2_ctrl_handler_init(&state->hdl, 2);
- state->volume = v4l2_ctrl_new_std(&state->hdl, &wm8739_ctrl_ops,
- V4L2_CID_AUDIO_VOLUME, 0, 65535, 65535 / 100, 50736);
- state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8739_ctrl_ops,
- V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
- state->balance = v4l2_ctrl_new_std(&state->hdl, &wm8739_ctrl_ops,
- V4L2_CID_AUDIO_BALANCE, 0, 65535, 65535 / 100, 32768);
- sd->ctrl_handler = &state->hdl;
- if (state->hdl.error) {
- int err = state->hdl.error;
-
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return err;
- }
- v4l2_ctrl_cluster(3, &state->volume);
-
- state->clock_freq = 48000;
-
- /* Initialize wm8739 */
-
- /* reset */
- wm8739_write(sd, R15, 0x00);
- /* filter setting, high path, offet clear */
- wm8739_write(sd, R5, 0x000);
- /* ADC, OSC, Power Off mode Disable */
- wm8739_write(sd, R6, 0x000);
- /* Digital Audio interface format:
- Enable Master mode, 24 bit, MSB first/left justified */
- wm8739_write(sd, R7, 0x049);
- /* sampling control: normal, 256fs, 48KHz sampling rate */
- wm8739_write(sd, R8, 0x000);
- /* activate */
- wm8739_write(sd, R9, 0x001);
- /* set volume/mute */
- v4l2_ctrl_handler_setup(&state->hdl);
- return 0;
-}
-
-static int wm8739_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct wm8739_state *state = to_state(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(to_state(sd));
- return 0;
-}
-
-static const struct i2c_device_id wm8739_id[] = {
- { "wm8739", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8739_id);
-
-static struct i2c_driver wm8739_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "wm8739",
- },
- .probe = wm8739_probe,
- .remove = wm8739_remove,
- .id_table = wm8739_id,
-};
-
-module_i2c_driver(wm8739_driver);
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
deleted file mode 100644
index bee77ea9f49..00000000000
--- a/drivers/media/video/wm8775.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * wm8775 - driver version 0.0.1
- *
- * Copyright (C) 2004 Ulf Eklund <ivtv at eklund.to>
- *
- * Based on saa7115 driver
- *
- * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl>
- * - Cleanup
- * - V4L2 API update
- * - sound fixes
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-ctrls.h>
-#include <media/wm8775.h>
-
-MODULE_DESCRIPTION("wm8775 driver");
-MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
-MODULE_LICENSE("GPL");
-
-
-
-/* ----------------------------------------------------------------------- */
-
-enum {
- R7 = 7, R11 = 11,
- R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R23 = 23,
- TOT_REGS
-};
-
-#define ALC_HOLD 0x85 /* R17: use zero cross detection, ALC hold time 42.6 ms */
-#define ALC_EN 0x100 /* R17: ALC enable */
-
-struct wm8775_state {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- struct v4l2_ctrl *mute;
- struct v4l2_ctrl *vol;
- struct v4l2_ctrl *bal;
- struct v4l2_ctrl *loud;
- u8 input; /* Last selected input (0-0xf) */
-};
-
-static inline struct wm8775_state *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct wm8775_state, sd);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct wm8775_state, hdl)->sd;
-}
-
-static int wm8775_write(struct v4l2_subdev *sd, int reg, u16 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int i;
-
- if (reg < 0 || reg >= TOT_REGS) {
- v4l2_err(sd, "Invalid register R%d\n", reg);
- return -1;
- }
-
- for (i = 0; i < 3; i++)
- if (i2c_smbus_write_byte_data(client,
- (reg << 1) | (val >> 8), val & 0xff) == 0)
- return 0;
- v4l2_err(sd, "I2C: cannot write %03x to register R%d\n", val, reg);
- return -1;
-}
-
-static void wm8775_set_audio(struct v4l2_subdev *sd, int quietly)
-{
- struct wm8775_state *state = to_state(sd);
- u8 vol_l, vol_r;
- int muted = 0 != state->mute->val;
- u16 volume = (u16)state->vol->val;
- u16 balance = (u16)state->bal->val;
-
- /* normalize ( 65535 to 0 -> 255 to 0 (+24dB to -103dB) ) */
- vol_l = (min(65536 - balance, 32768) * volume) >> 23;
- vol_r = (min(balance, (u16)32768) * volume) >> 23;
-
- /* Mute */
- if (muted || quietly)
- wm8775_write(sd, R21, 0x0c0 | state->input);
-
- wm8775_write(sd, R14, vol_l | 0x100); /* 0x100= Left channel ADC zero cross enable */
- wm8775_write(sd, R15, vol_r | 0x100); /* 0x100= Right channel ADC zero cross enable */
-
- /* Un-mute */
- if (!muted)
- wm8775_write(sd, R21, state->input);
-}
-
-static int wm8775_s_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct wm8775_state *state = to_state(sd);
-
- /* There are 4 inputs and one output. Zero or more inputs
- are multiplexed together to the output. Hence there are
- 16 combinations.
- If only one input is active (the normal case) then the
- input values 1, 2, 4 or 8 should be used. */
- if (input > 15) {
- v4l2_err(sd, "Invalid input %d.\n", input);
- return -EINVAL;
- }
- state->input = input;
- if (!v4l2_ctrl_g_ctrl(state->mute))
- return 0;
- if (!v4l2_ctrl_g_ctrl(state->vol))
- return 0;
- if (!v4l2_ctrl_g_ctrl(state->bal))
- return 0;
- wm8775_set_audio(sd, 1);
- return 0;
-}
-
-static int wm8775_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- case V4L2_CID_AUDIO_VOLUME:
- case V4L2_CID_AUDIO_BALANCE:
- wm8775_set_audio(sd, 0);
- return 0;
- case V4L2_CID_AUDIO_LOUDNESS:
- wm8775_write(sd, R17, (ctrl->val ? ALC_EN : 0) | ALC_HOLD);
- return 0;
- }
- return -EINVAL;
-}
-
-static int wm8775_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_WM8775, 0);
-}
-
-static int wm8775_log_status(struct v4l2_subdev *sd)
-{
- struct wm8775_state *state = to_state(sd);
-
- v4l2_info(sd, "Input: %d\n", state->input);
- v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
- return 0;
-}
-
-static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
-{
- wm8775_set_audio(sd, 0);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_ctrl_ops wm8775_ctrl_ops = {
- .s_ctrl = wm8775_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops wm8775_core_ops = {
- .log_status = wm8775_log_status,
- .g_chip_ident = wm8775_g_chip_ident,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
-};
-
-static const struct v4l2_subdev_tuner_ops wm8775_tuner_ops = {
- .s_frequency = wm8775_s_frequency,
-};
-
-static const struct v4l2_subdev_audio_ops wm8775_audio_ops = {
- .s_routing = wm8775_s_routing,
-};
-
-static const struct v4l2_subdev_ops wm8775_ops = {
- .core = &wm8775_core_ops,
- .tuner = &wm8775_tuner_ops,
- .audio = &wm8775_audio_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-/* i2c implementation */
-
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-
-static int wm8775_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct wm8775_state *state;
- struct v4l2_subdev *sd;
- int err;
- bool is_nova_s = false;
-
- if (client->dev.platform_data) {
- struct wm8775_platform_data *data = client->dev.platform_data;
- is_nova_s = data->is_nova_s;
- }
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- v4l_info(client, "chip found @ 0x%02x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- state = kzalloc(sizeof(struct wm8775_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &wm8775_ops);
- state->input = 2;
-
- v4l2_ctrl_handler_init(&state->hdl, 4);
- state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
- V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
- state->vol = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
- V4L2_CID_AUDIO_VOLUME, 0, 65535, (65535+99)/100, 0xCF00); /* 0dB*/
- state->bal = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
- V4L2_CID_AUDIO_BALANCE, 0, 65535, (65535+99)/100, 32768);
- state->loud = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
- V4L2_CID_AUDIO_LOUDNESS, 0, 1, 1, 1);
- sd->ctrl_handler = &state->hdl;
- err = state->hdl.error;
- if (err) {
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return err;
- }
-
- /* Initialize wm8775 */
-
- /* RESET */
- wm8775_write(sd, R23, 0x000);
- /* Disable zero cross detect timeout */
- wm8775_write(sd, R7, 0x000);
- /* HPF enable, left justified, 24-bit (Philips) mode */
- wm8775_write(sd, R11, 0x021);
- /* Master mode, clock ratio 256fs */
- wm8775_write(sd, R12, 0x102);
- /* Powered up */
- wm8775_write(sd, R13, 0x000);
-
- if (!is_nova_s) {
- /* ADC gain +2.5dB, enable zero cross */
- wm8775_write(sd, R14, 0x1d4);
- /* ADC gain +2.5dB, enable zero cross */
- wm8775_write(sd, R15, 0x1d4);
- /* ALC Stereo, ALC target level -1dB FS max gain +8dB */
- wm8775_write(sd, R16, 0x1bf);
- /* Enable gain control, use zero cross detection,
- ALC hold time 42.6 ms */
- wm8775_write(sd, R17, 0x185);
- } else {
- /* ALC stereo, ALC target level -5dB FS, ALC max gain +8dB */
- wm8775_write(sd, R16, 0x1bb);
- /* Set ALC mode and hold time */
- wm8775_write(sd, R17, (state->loud->val ? ALC_EN : 0) | ALC_HOLD);
- }
- /* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */
- wm8775_write(sd, R18, 0x0a2);
- /* Enable noise gate, threshold -72dBfs */
- wm8775_write(sd, R19, 0x005);
- if (!is_nova_s) {
- /* Transient window 4ms, lower PGA gain limit -1dB */
- wm8775_write(sd, R20, 0x07a);
- /* LRBOTH = 1, use input 2. */
- wm8775_write(sd, R21, 0x102);
- } else {
- /* Transient window 4ms, ALC min gain -5dB */
- wm8775_write(sd, R20, 0x0fb);
-
- wm8775_set_audio(sd, 1); /* set volume/mute/mux */
- }
- return 0;
-}
-
-static int wm8775_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct wm8775_state *state = to_state(sd);
-
- v4l2_device_unregister_subdev(sd);
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return 0;
-}
-
-static const struct i2c_device_id wm8775_id[] = {
- { "wm8775", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8775_id);
-
-static struct i2c_driver wm8775_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "wm8775",
- },
- .probe = wm8775_probe,
- .remove = wm8775_remove,
- .id_table = wm8775_id,
-};
-
-module_i2c_driver(wm8775_driver);
diff --git a/drivers/media/video/zoran/Kconfig b/drivers/media/video/zoran/Kconfig
deleted file mode 100644
index fd4120e4c10..00000000000
--- a/drivers/media/video/zoran/Kconfig
+++ /dev/null
@@ -1,74 +0,0 @@
-config VIDEO_ZORAN
- tristate "Zoran ZR36057/36067 Video For Linux"
- depends on PCI && I2C_ALGOBIT && VIDEO_V4L2 && VIRT_TO_BUS
- help
- Say Y for support for MJPEG capture cards based on the Zoran
- 36057/36067 PCI controller chipset. This includes the Iomega
- Buz, Pinnacle DC10+ and the Linux Media Labs LML33. There is
- a driver homepage at <http://mjpeg.sf.net/driver-zoran/>. For
- more information, check <file:Documentation/video4linux/Zoran>.
-
- To compile this driver as a module, choose M here: the
- module will be called zr36067.
-
-config VIDEO_ZORAN_DC30
- tristate "Pinnacle/Miro DC30(+) support"
- depends on VIDEO_ZORAN
- select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_VPX3220 if VIDEO_HELPER_CHIPS_AUTO
- help
- Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback
- card. This also supports really old DC10 cards based on the
- zr36050 MJPEG codec and zr36016 VFE.
-
-config VIDEO_ZORAN_ZR36060
- tristate "Zoran ZR36060"
- depends on VIDEO_ZORAN
- help
- Say Y to support Zoran boards based on 36060 chips.
- This includes Iomega Buz, Pinnacle DC10, Linux media Labs 33
- and 33 R10 and AverMedia 6 boards.
-
-config VIDEO_ZORAN_BUZ
- tristate "Iomega Buz support"
- depends on VIDEO_ZORAN_ZR36060
- select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO
- help
- Support for the Iomega Buz MJPEG capture/playback card.
-
-config VIDEO_ZORAN_DC10
- tristate "Pinnacle/Miro DC10(+) support"
- depends on VIDEO_ZORAN_ZR36060
- select VIDEO_SAA7110 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO
- help
- Support for the Pinnacle/Miro DC10(+) MJPEG capture/playback
- card.
-
-config VIDEO_ZORAN_LML33
- tristate "Linux Media Labs LML33 support"
- depends on VIDEO_ZORAN_ZR36060
- select VIDEO_BT819 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO
- help
- Support for the Linux Media Labs LML33 MJPEG capture/playback
- card.
-
-config VIDEO_ZORAN_LML33R10
- tristate "Linux Media Labs LML33R10 support"
- depends on VIDEO_ZORAN_ZR36060
- select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO
- help
- support for the Linux Media Labs LML33R10 MJPEG capture/playback
- card.
-
-config VIDEO_ZORAN_AVS6EYES
- tristate "AverMedia 6 Eyes support (EXPERIMENTAL)"
- depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL
- select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_BT866 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO
- help
- Support for the AverMedia 6 Eyes video surveillance card.
diff --git a/drivers/media/video/zoran/Makefile b/drivers/media/video/zoran/Makefile
deleted file mode 100644
index 44cc13352c8..00000000000
--- a/drivers/media/video/zoran/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-zr36067-objs := zoran_procfs.o zoran_device.o \
- zoran_driver.o zoran_card.o
-
-obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o
-obj-$(CONFIG_VIDEO_ZORAN_DC30) += zr36050.o zr36016.o
-obj-$(CONFIG_VIDEO_ZORAN_ZR36060) += zr36060.o
diff --git a/drivers/media/video/zoran/videocodec.c b/drivers/media/video/zoran/videocodec.c
deleted file mode 100644
index c0107163529..00000000000
--- a/drivers/media/video/zoran/videocodec.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * VIDEO MOTION CODECs internal API for video devices
- *
- * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's
- * bound to a master device.
- *
- * (c) 2002 Wolfgang Scherr <scherr@net4you.at>
- *
- * $Id: videocodec.c,v 1.1.2.8 2003/03/29 07:16:04 rbultje Exp $
- *
- * ------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * ------------------------------------------------------------------------
- */
-
-#define VIDEOCODEC_VERSION "v0.2"
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-
-// kernel config is here (procfs flag)
-
-#ifdef CONFIG_PROC_FS
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <asm/uaccess.h>
-#endif
-
-#include "videocodec.h"
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-4)");
-
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
-struct attached_list {
- struct videocodec *codec;
- struct attached_list *next;
-};
-
-struct codec_list {
- const struct videocodec *codec;
- int attached;
- struct attached_list *list;
- struct codec_list *next;
-};
-
-static struct codec_list *codeclist_top = NULL;
-
-/* ================================================= */
-/* function prototypes of the master/slave interface */
-/* ================================================= */
-
-struct videocodec *
-videocodec_attach (struct videocodec_master *master)
-{
- struct codec_list *h = codeclist_top;
- struct attached_list *a, *ptr;
- struct videocodec *codec;
- int res;
-
- if (!master) {
- dprintk(1, KERN_ERR "videocodec_attach: no data\n");
- return NULL;
- }
-
- dprintk(2,
- "videocodec_attach: '%s', flags %lx, magic %lx\n",
- master->name, master->flags, master->magic);
-
- if (!h) {
- dprintk(1,
- KERN_ERR
- "videocodec_attach: no device available\n");
- return NULL;
- }
-
- while (h) {
- // attach only if the slave has at least the flags
- // expected by the master
- if ((master->flags & h->codec->flags) == master->flags) {
- dprintk(4, "videocodec_attach: try '%s'\n",
- h->codec->name);
-
- if (!try_module_get(h->codec->owner))
- return NULL;
-
- codec = kmemdup(h->codec, sizeof(struct videocodec),
- GFP_KERNEL);
- if (!codec) {
- dprintk(1,
- KERN_ERR
- "videocodec_attach: no mem\n");
- goto out_module_put;
- }
-
- snprintf(codec->name, sizeof(codec->name),
- "%s[%d]", codec->name, h->attached);
- codec->master_data = master;
- res = codec->setup(codec);
- if (res == 0) {
- dprintk(3, "videocodec_attach '%s'\n",
- codec->name);
- ptr = kzalloc(sizeof(struct attached_list), GFP_KERNEL);
- if (!ptr) {
- dprintk(1,
- KERN_ERR
- "videocodec_attach: no memory\n");
- goto out_kfree;
- }
- ptr->codec = codec;
-
- a = h->list;
- if (!a) {
- h->list = ptr;
- dprintk(4,
- "videocodec: first element\n");
- } else {
- while (a->next)
- a = a->next; // find end
- a->next = ptr;
- dprintk(4,
- "videocodec: in after '%s'\n",
- h->codec->name);
- }
-
- h->attached += 1;
- return codec;
- } else {
- kfree(codec);
- }
- }
- h = h->next;
- }
-
- dprintk(1, KERN_ERR "videocodec_attach: no codec found!\n");
- return NULL;
-
- out_module_put:
- module_put(h->codec->owner);
- out_kfree:
- kfree(codec);
- return NULL;
-}
-
-int
-videocodec_detach (struct videocodec *codec)
-{
- struct codec_list *h = codeclist_top;
- struct attached_list *a, *prev;
- int res;
-
- if (!codec) {
- dprintk(1, KERN_ERR "videocodec_detach: no data\n");
- return -EINVAL;
- }
-
- dprintk(2,
- "videocodec_detach: '%s', type: %x, flags %lx, magic %lx\n",
- codec->name, codec->type, codec->flags, codec->magic);
-
- if (!h) {
- dprintk(1,
- KERN_ERR "videocodec_detach: no device left...\n");
- return -ENXIO;
- }
-
- while (h) {
- a = h->list;
- prev = NULL;
- while (a) {
- if (codec == a->codec) {
- res = a->codec->unset(a->codec);
- if (res >= 0) {
- dprintk(3,
- "videocodec_detach: '%s'\n",
- a->codec->name);
- a->codec->master_data = NULL;
- } else {
- dprintk(1,
- KERN_ERR
- "videocodec_detach: '%s'\n",
- a->codec->name);
- a->codec->master_data = NULL;
- }
- if (prev == NULL) {
- h->list = a->next;
- dprintk(4,
- "videocodec: delete first\n");
- } else {
- prev->next = a->next;
- dprintk(4,
- "videocodec: delete middle\n");
- }
- module_put(a->codec->owner);
- kfree(a->codec);
- kfree(a);
- h->attached -= 1;
- return 0;
- }
- prev = a;
- a = a->next;
- }
- h = h->next;
- }
-
- dprintk(1, KERN_ERR "videocodec_detach: given codec not found!\n");
- return -EINVAL;
-}
-
-int
-videocodec_register (const struct videocodec *codec)
-{
- struct codec_list *ptr, *h = codeclist_top;
-
- if (!codec) {
- dprintk(1, KERN_ERR "videocodec_register: no data!\n");
- return -EINVAL;
- }
-
- dprintk(2,
- "videocodec: register '%s', type: %x, flags %lx, magic %lx\n",
- codec->name, codec->type, codec->flags, codec->magic);
-
- ptr = kzalloc(sizeof(struct codec_list), GFP_KERNEL);
- if (!ptr) {
- dprintk(1, KERN_ERR "videocodec_register: no memory\n");
- return -ENOMEM;
- }
- ptr->codec = codec;
-
- if (!h) {
- codeclist_top = ptr;
- dprintk(4, "videocodec: hooked in as first element\n");
- } else {
- while (h->next)
- h = h->next; // find the end
- h->next = ptr;
- dprintk(4, "videocodec: hooked in after '%s'\n",
- h->codec->name);
- }
-
- return 0;
-}
-
-int
-videocodec_unregister (const struct videocodec *codec)
-{
- struct codec_list *prev = NULL, *h = codeclist_top;
-
- if (!codec) {
- dprintk(1, KERN_ERR "videocodec_unregister: no data!\n");
- return -EINVAL;
- }
-
- dprintk(2,
- "videocodec: unregister '%s', type: %x, flags %lx, magic %lx\n",
- codec->name, codec->type, codec->flags, codec->magic);
-
- if (!h) {
- dprintk(1,
- KERN_ERR
- "videocodec_unregister: no device left...\n");
- return -ENXIO;
- }
-
- while (h) {
- if (codec == h->codec) {
- if (h->attached) {
- dprintk(1,
- KERN_ERR
- "videocodec: '%s' is used\n",
- h->codec->name);
- return -EBUSY;
- }
- dprintk(3, "videocodec: unregister '%s' is ok.\n",
- h->codec->name);
- if (prev == NULL) {
- codeclist_top = h->next;
- dprintk(4,
- "videocodec: delete first element\n");
- } else {
- prev->next = h->next;
- dprintk(4,
- "videocodec: delete middle element\n");
- }
- kfree(h);
- return 0;
- }
- prev = h;
- h = h->next;
- }
-
- dprintk(1,
- KERN_ERR
- "videocodec_unregister: given codec not found!\n");
- return -EINVAL;
-}
-
-#ifdef CONFIG_PROC_FS
-static int proc_videocodecs_show(struct seq_file *m, void *v)
-{
- struct codec_list *h = codeclist_top;
- struct attached_list *a;
-
- seq_printf(m, "<S>lave or attached <M>aster name type flags magic ");
- seq_printf(m, "(connected as)\n");
-
- h = codeclist_top;
- while (h) {
- seq_printf(m, "S %32s %04x %08lx %08lx (TEMPLATE)\n",
- h->codec->name, h->codec->type,
- h->codec->flags, h->codec->magic);
- a = h->list;
- while (a) {
- seq_printf(m, "M %32s %04x %08lx %08lx (%s)\n",
- a->codec->master_data->name,
- a->codec->master_data->type,
- a->codec->master_data->flags,
- a->codec->master_data->magic,
- a->codec->name);
- a = a->next;
- }
- h = h->next;
- }
-
- return 0;
-}
-
-static int proc_videocodecs_open(struct inode *inode, struct file *file)
-{
- return single_open(file, proc_videocodecs_show, NULL);
-}
-
-static const struct file_operations videocodecs_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_videocodecs_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-#endif
-
-/* ===================== */
-/* hook in driver module */
-/* ===================== */
-static int __init
-videocodec_init (void)
-{
-#ifdef CONFIG_PROC_FS
- static struct proc_dir_entry *videocodec_proc_entry;
-#endif
-
- printk(KERN_INFO "Linux video codec intermediate layer: %s\n",
- VIDEOCODEC_VERSION);
-
-#ifdef CONFIG_PROC_FS
- videocodec_proc_entry = proc_create("videocodecs", 0, NULL, &videocodecs_proc_fops);
- if (!videocodec_proc_entry) {
- dprintk(1, KERN_ERR "videocodec: can't init procfs.\n");
- }
-#endif
- return 0;
-}
-
-static void __exit
-videocodec_exit (void)
-{
-#ifdef CONFIG_PROC_FS
- remove_proc_entry("videocodecs", NULL);
-#endif
-}
-
-EXPORT_SYMBOL(videocodec_attach);
-EXPORT_SYMBOL(videocodec_detach);
-EXPORT_SYMBOL(videocodec_register);
-EXPORT_SYMBOL(videocodec_unregister);
-
-module_init(videocodec_init);
-module_exit(videocodec_exit);
-
-MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>");
-MODULE_DESCRIPTION("Intermediate API module for video codecs "
- VIDEOCODEC_VERSION);
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zoran/videocodec.h b/drivers/media/video/zoran/videocodec.h
deleted file mode 100644
index def55585ad2..00000000000
--- a/drivers/media/video/zoran/videocodec.h
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * VIDEO MOTION CODECs internal API for video devices
- *
- * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's
- * bound to a master device.
- *
- * (c) 2002 Wolfgang Scherr <scherr@net4you.at>
- *
- * $Id: videocodec.h,v 1.1.2.4 2003/01/14 21:15:03 rbultje Exp $
- *
- * ------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * ------------------------------------------------------------------------
- */
-
-/* =================== */
-/* general description */
-/* =================== */
-
-/* Should ease the (re-)usage of drivers supporting cards with (different)
- video codecs. The codecs register to this module their functionality,
- and the processors (masters) can attach to them if they fit.
-
- The codecs are typically have a "strong" binding to their master - so I
- don't think it makes sense to have a full blown interfacing as with e.g.
- i2c. If you have an other opinion, let's discuss & implement it :-)))
-
- Usage:
-
- The slave has just to setup the videocodec structure and use two functions:
- videocodec_register(codecdata);
- videocodec_unregister(codecdata);
- The best is just calling them at module (de-)initialisation.
-
- The master sets up the structure videocodec_master and calls:
- codecdata=videocodec_attach(master_codecdata);
- videocodec_detach(codecdata);
-
- The slave is called during attach/detach via functions setup previously
- during register. At that time, the master_data pointer is set up
- and the slave can access any io registers of the master device (in the case
- the slave is bound to it). Otherwise it doesn't need this functions and
- therfor they may not be initialized.
-
- The other functions are just for convenience, as they are for sure used by
- most/all of the codecs. The last ones may be omitted, too.
-
- See the structure declaration below for more information and which data has
- to be set up for the master and the slave.
-
- ----------------------------------------------------------------------------
- The master should have "knowledge" of the slave and vice versa. So the data
- structures sent to/from slave via set_data/get_data set_image/get_image are
- device dependent and vary between MJPEG/MPEG/WAVELET/... devices. (!!!!)
- ----------------------------------------------------------------------------
-*/
-
-
-/* ========================================== */
-/* description of the videocodec_io structure */
-/* ========================================== */
-
-/*
- ==== master setup ====
- name -> name of the device structure for reference and debugging
- master_data -> data ref. for the master (e.g. the zr36055,57,67)
- readreg -> ref. to read-fn from register (setup by master, used by slave)
- writereg -> ref. to write-fn to register (setup by master, used by slave)
- this two functions do the lowlevel I/O job
-
- ==== slave functionality setup ====
- slave_data -> data ref. for the slave (e.g. the zr36050,60)
- check -> fn-ref. checks availability of an device, returns -EIO on failure or
- the type on success
- this makes espcecially sense if a driver module supports more than
- one codec which may be quite similar to access, nevertheless it
- is good for a first functionality check
-
- -- main functions you always need for compression/decompression --
-
- set_mode -> this fn-ref. resets the entire codec, and sets up the mode
- with the last defined norm/size (or device default if not
- available) - it returns 0 if the mode is possible
- set_size -> this fn-ref. sets the norm and image size for
- compression/decompression (returns 0 on success)
- the norm param is defined in videodev2.h (V4L2_STD_*)
-
- additional setup may be available, too - but the codec should work with
- some default values even without this
-
- set_data -> sets device-specific data (tables, quality etc.)
- get_data -> query device-specific data (tables, quality etc.)
-
- if the device delivers interrupts, they may be setup/handled here
- setup_interrupt -> codec irq setup (not needed for 36050/60)
- handle_interrupt -> codec irq handling (not needed for 36050/60)
-
- if the device delivers pictures, they may be handled here
- put_image -> puts image data to the codec (not needed for 36050/60)
- get_image -> gets image data from the codec (not needed for 36050/60)
- the calls include frame numbers and flags (even/odd/...)
- if needed and a flag which allows blocking until its ready
-*/
-
-/* ============== */
-/* user interface */
-/* ============== */
-
-/*
- Currently there is only a information display planned, as the layer
- is not visible for the user space at all.
-
- Information is available via procfs. The current entry is "/proc/videocodecs"
- but it makes sense to "hide" it in the /proc/video tree of v4l(2) --TODO--.
-
-A example for such an output is:
-
-<S>lave or attached <M>aster name type flags magic (connected as)
-S zr36050 0002 0000d001 00000000 (TEMPLATE)
-M zr36055[0] 0001 0000c001 00000000 (zr36050[0])
-M zr36055[1] 0001 0000c001 00000000 (zr36050[1])
-
-*/
-
-
-/* =============================================== */
-/* special defines for the videocodec_io structure */
-/* =============================================== */
-
-#ifndef __LINUX_VIDEOCODEC_H
-#define __LINUX_VIDEOCODEC_H
-
-#include <linux/videodev2.h>
-
-#define CODEC_DO_COMPRESSION 0
-#define CODEC_DO_EXPANSION 1
-
-/* this are the current codec flags I think they are needed */
-/* -> type value in structure */
-#define CODEC_FLAG_JPEG 0x00000001L // JPEG codec
-#define CODEC_FLAG_MPEG 0x00000002L // MPEG1/2/4 codec
-#define CODEC_FLAG_DIVX 0x00000004L // DIVX codec
-#define CODEC_FLAG_WAVELET 0x00000008L // WAVELET codec
- // room for other types
-
-#define CODEC_FLAG_MAGIC 0x00000800L // magic key must match
-#define CODEC_FLAG_HARDWARE 0x00001000L // is a hardware codec
-#define CODEC_FLAG_VFE 0x00002000L // has direct video frontend
-#define CODEC_FLAG_ENCODER 0x00004000L // compression capability
-#define CODEC_FLAG_DECODER 0x00008000L // decompression capability
-#define CODEC_FLAG_NEEDIRQ 0x00010000L // needs irq handling
-#define CODEC_FLAG_RDWRPIC 0x00020000L // handles picture I/O
-
-/* a list of modes, some are just examples (is there any HW?) */
-#define CODEC_MODE_BJPG 0x0001 // Baseline JPEG
-#define CODEC_MODE_LJPG 0x0002 // Lossless JPEG
-#define CODEC_MODE_MPEG1 0x0003 // MPEG 1
-#define CODEC_MODE_MPEG2 0x0004 // MPEG 2
-#define CODEC_MODE_MPEG4 0x0005 // MPEG 4
-#define CODEC_MODE_MSDIVX 0x0006 // MS DivX
-#define CODEC_MODE_ODIVX 0x0007 // Open DivX
-#define CODEC_MODE_WAVELET 0x0008 // Wavelet
-
-/* this are the current codec types I want to implement */
-/* -> type value in structure */
-#define CODEC_TYPE_NONE 0
-#define CODEC_TYPE_L64702 1
-#define CODEC_TYPE_ZR36050 2
-#define CODEC_TYPE_ZR36016 3
-#define CODEC_TYPE_ZR36060 4
-
-/* the type of data may be enhanced by future implementations (data-fn.'s) */
-/* -> used in command */
-#define CODEC_G_STATUS 0x0000 /* codec status (query only) */
-#define CODEC_S_CODEC_MODE 0x0001 /* codec mode (baseline JPEG, MPEG1,... */
-#define CODEC_G_CODEC_MODE 0x8001
-#define CODEC_S_VFE 0x0002 /* additional video frontend setup */
-#define CODEC_G_VFE 0x8002
-#define CODEC_S_MMAP 0x0003 /* MMAP setup (if available) */
-
-#define CODEC_S_JPEG_TDS_BYTE 0x0010 /* target data size in bytes */
-#define CODEC_G_JPEG_TDS_BYTE 0x8010
-#define CODEC_S_JPEG_SCALE 0x0011 /* scaling factor for quant. tables */
-#define CODEC_G_JPEG_SCALE 0x8011
-#define CODEC_S_JPEG_HDT_DATA 0x0018 /* huffman-tables */
-#define CODEC_G_JPEG_HDT_DATA 0x8018
-#define CODEC_S_JPEG_QDT_DATA 0x0019 /* quantizing-tables */
-#define CODEC_G_JPEG_QDT_DATA 0x8019
-#define CODEC_S_JPEG_APP_DATA 0x001A /* APP marker */
-#define CODEC_G_JPEG_APP_DATA 0x801A
-#define CODEC_S_JPEG_COM_DATA 0x001B /* COM marker */
-#define CODEC_G_JPEG_COM_DATA 0x801B
-
-#define CODEC_S_PRIVATE 0x1000 /* "private" commands start here */
-#define CODEC_G_PRIVATE 0x9000
-
-#define CODEC_G_FLAG 0x8000 /* this is how 'get' is detected */
-
-/* types of transfer, directly user space or a kernel buffer (image-fn.'s) */
-/* -> used in get_image, put_image */
-#define CODEC_TRANSFER_KERNEL 0 /* use "memcopy" */
-#define CODEC_TRANSFER_USER 1 /* use "to/from_user" */
-
-
-/* ========================= */
-/* the structures itself ... */
-/* ========================= */
-
-struct vfe_polarity {
- unsigned int vsync_pol:1;
- unsigned int hsync_pol:1;
- unsigned int field_pol:1;
- unsigned int blank_pol:1;
- unsigned int subimg_pol:1;
- unsigned int poe_pol:1;
- unsigned int pvalid_pol:1;
- unsigned int vclk_pol:1;
-};
-
-struct vfe_settings {
- __u32 x, y; /* Offsets into image */
- __u32 width, height; /* Area to capture */
- __u16 decimation; /* Decimation divider */
- __u16 flags; /* Flags for capture */
- __u16 quality; /* quality of the video */
-};
-
-struct tvnorm {
- u16 Wt, Wa, HStart, HSyncStart, Ht, Ha, VStart;
-};
-
-struct jpeg_com_marker {
- int len; /* number of usable bytes in data */
- char data[60];
-};
-
-struct jpeg_app_marker {
- int appn; /* number app segment */
- int len; /* number of usable bytes in data */
- char data[60];
-};
-
-struct videocodec {
- struct module *owner;
- /* -- filled in by slave device during register -- */
- char name[32];
- unsigned long magic; /* may be used for client<->master attaching */
- unsigned long flags; /* functionality flags */
- unsigned int type; /* codec type */
-
- /* -- these is filled in later during master device attach -- */
-
- struct videocodec_master *master_data;
-
- /* -- these are filled in by the slave device during register -- */
-
- void *data; /* private slave data */
-
- /* attach/detach client functions (indirect call) */
- int (*setup) (struct videocodec * codec);
- int (*unset) (struct videocodec * codec);
-
- /* main functions, every client needs them for sure! */
- // set compression or decompression (or freeze, stop, standby, etc)
- int (*set_mode) (struct videocodec * codec,
- int mode);
- // setup picture size and norm (for the codec's video frontend)
- int (*set_video) (struct videocodec * codec,
- struct tvnorm * norm,
- struct vfe_settings * cap,
- struct vfe_polarity * pol);
- // other control commands, also mmap setup etc.
- int (*control) (struct videocodec * codec,
- int type,
- int size,
- void *data);
-
- /* additional setup/query/processing (may be NULL pointer) */
- // interrupt setup / handling (for irq's delivered by master)
- int (*setup_interrupt) (struct videocodec * codec,
- long mode);
- int (*handle_interrupt) (struct videocodec * codec,
- int source,
- long flag);
- // picture interface (if any)
- long (*put_image) (struct videocodec * codec,
- int tr_type,
- int block,
- long *fr_num,
- long *flag,
- long size,
- void *buf);
- long (*get_image) (struct videocodec * codec,
- int tr_type,
- int block,
- long *fr_num,
- long *flag,
- long size,
- void *buf);
-};
-
-struct videocodec_master {
- /* -- filled in by master device for registration -- */
- char name[32];
- unsigned long magic; /* may be used for client<->master attaching */
- unsigned long flags; /* functionality flags */
- unsigned int type; /* master type */
-
- void *data; /* private master data */
-
- __u32(*readreg) (struct videocodec * codec,
- __u16 reg);
- void (*writereg) (struct videocodec * codec,
- __u16 reg,
- __u32 value);
-};
-
-
-/* ================================================= */
-/* function prototypes of the master/slave interface */
-/* ================================================= */
-
-/* attach and detach commands for the master */
-// * master structure needs to be kmalloc'ed before calling attach
-// and free'd after calling detach
-// * returns pointer on success, NULL on failure
-extern struct videocodec *videocodec_attach(struct videocodec_master *);
-// * 0 on success, <0 (errno) on failure
-extern int videocodec_detach(struct videocodec *);
-
-/* register and unregister commands for the slaves */
-// * 0 on success, <0 (errno) on failure
-extern int videocodec_register(const struct videocodec *);
-// * 0 on success, <0 (errno) on failure
-extern int videocodec_unregister(const struct videocodec *);
-
-/* the other calls are directly done via the videocodec structure! */
-
-#endif /*ifndef __LINUX_VIDEOCODEC_H */
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h
deleted file mode 100644
index ca2754a3cd6..00000000000
--- a/drivers/media/video/zoran/zoran.h
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * zoran - Iomega Buz driver
- *
- * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
- *
- * based on
- *
- * zoran.0.0.3 Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- *
- * and
- *
- * bttv - Bt848 frame grabber driver
- * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- * & Marcus Metzler (mocm@thp.uni-koeln.de)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _BUZ_H_
-#define _BUZ_H_
-
-#include <media/v4l2-device.h>
-
-struct zoran_sync {
- unsigned long frame; /* number of buffer that has been free'd */
- unsigned long length; /* number of code bytes in buffer (capture only) */
- unsigned long seq; /* frame sequence number */
- struct timeval timestamp; /* timestamp */
-};
-
-
-#define ZORAN_NAME "ZORAN" /* name of the device */
-
-#define ZR_DEVNAME(zr) ((zr)->name)
-
-#define BUZ_MAX_WIDTH (zr->timing->Wa)
-#define BUZ_MAX_HEIGHT (zr->timing->Ha)
-#define BUZ_MIN_WIDTH 32 /* never display less than 32 pixels */
-#define BUZ_MIN_HEIGHT 24 /* never display less than 24 rows */
-
-#define BUZ_NUM_STAT_COM 4
-#define BUZ_MASK_STAT_COM 3
-
-#define BUZ_MAX_FRAME 256 /* Must be a power of 2 */
-#define BUZ_MASK_FRAME 255 /* Must be BUZ_MAX_FRAME-1 */
-
-#define BUZ_MAX_INPUT 16
-
-#if VIDEO_MAX_FRAME <= 32
-# define V4L_MAX_FRAME 32
-#elif VIDEO_MAX_FRAME <= 64
-# define V4L_MAX_FRAME 64
-#else
-# error "Too many video frame buffers to handle"
-#endif
-#define V4L_MASK_FRAME (V4L_MAX_FRAME - 1)
-
-#define MAX_FRAME (BUZ_MAX_FRAME > VIDEO_MAX_FRAME ? BUZ_MAX_FRAME : VIDEO_MAX_FRAME)
-
-#include "zr36057.h"
-
-enum card_type {
- UNKNOWN = -1,
-
- /* Pinnacle/Miro */
- DC10_old, /* DC30 like */
- DC10_new, /* DC10plus like */
- DC10plus,
- DC30,
- DC30plus,
-
- /* Linux Media Labs */
- LML33,
- LML33R10,
-
- /* Iomega */
- BUZ,
-
- /* AverMedia */
- AVS6EYES,
-
- /* total number of cards */
- NUM_CARDS
-};
-
-enum zoran_codec_mode {
- BUZ_MODE_IDLE, /* nothing going on */
- BUZ_MODE_MOTION_COMPRESS, /* grabbing frames */
- BUZ_MODE_MOTION_DECOMPRESS, /* playing frames */
- BUZ_MODE_STILL_COMPRESS, /* still frame conversion */
- BUZ_MODE_STILL_DECOMPRESS /* still frame conversion */
-};
-
-enum zoran_buffer_state {
- BUZ_STATE_USER, /* buffer is owned by application */
- BUZ_STATE_PEND, /* buffer is queued in pend[] ready to feed to I/O */
- BUZ_STATE_DMA, /* buffer is queued in dma[] for I/O */
- BUZ_STATE_DONE /* buffer is ready to return to application */
-};
-
-enum zoran_map_mode {
- ZORAN_MAP_MODE_RAW,
- ZORAN_MAP_MODE_JPG_REC,
-#define ZORAN_MAP_MODE_JPG ZORAN_MAP_MODE_JPG_REC
- ZORAN_MAP_MODE_JPG_PLAY,
-};
-
-enum gpio_type {
- ZR_GPIO_JPEG_SLEEP = 0,
- ZR_GPIO_JPEG_RESET,
- ZR_GPIO_JPEG_FRAME,
- ZR_GPIO_VID_DIR,
- ZR_GPIO_VID_EN,
- ZR_GPIO_VID_RESET,
- ZR_GPIO_CLK_SEL1,
- ZR_GPIO_CLK_SEL2,
- ZR_GPIO_MAX,
-};
-
-enum gpcs_type {
- GPCS_JPEG_RESET = 0,
- GPCS_JPEG_START,
- GPCS_MAX,
-};
-
-struct zoran_format {
- char *name;
- __u32 fourcc;
- int colorspace;
- int depth;
- __u32 flags;
- __u32 vfespfr;
-};
-/* flags */
-#define ZORAN_FORMAT_COMPRESSED 1<<0
-#define ZORAN_FORMAT_OVERLAY 1<<1
-#define ZORAN_FORMAT_CAPTURE 1<<2
-#define ZORAN_FORMAT_PLAYBACK 1<<3
-
-/* overlay-settings */
-struct zoran_overlay_settings {
- int is_set;
- int x, y, width, height; /* position */
- int clipcount; /* position and number of clips */
- const struct zoran_format *format; /* overlay format */
-};
-
-/* v4l-capture settings */
-struct zoran_v4l_settings {
- int width, height, bytesperline; /* capture size */
- const struct zoran_format *format; /* capture format */
-};
-
-/* jpg-capture/-playback settings */
-struct zoran_jpg_settings {
- int decimation; /* this bit is used to set everything to default */
- int HorDcm, VerDcm, TmpDcm; /* capture decimation settings (TmpDcm=1 means both fields) */
- int field_per_buff, odd_even; /* field-settings (odd_even=1 (+TmpDcm=1) means top-field-first) */
- int img_x, img_y, img_width, img_height; /* crop settings (subframe capture) */
- struct v4l2_jpegcompression jpg_comp; /* JPEG-specific capture settings */
-};
-
-struct zoran_fh;
-
-struct zoran_mapping {
- struct zoran_fh *fh;
- int count;
-};
-
-struct zoran_buffer {
- struct zoran_mapping *map;
- enum zoran_buffer_state state; /* state: unused/pending/dma/done */
- struct zoran_sync bs; /* DONE: info to return to application */
- union {
- struct {
- __le32 *frag_tab; /* addresses of frag table */
- u32 frag_tab_bus; /* same value cached to save time in ISR */
- } jpg;
- struct {
- char *fbuffer; /* virtual address of frame buffer */
- unsigned long fbuffer_phys;/* physical address of frame buffer */
- unsigned long fbuffer_bus;/* bus address of frame buffer */
- } v4l;
- };
-};
-
-enum zoran_lock_activity {
- ZORAN_FREE, /* free for use */
- ZORAN_ACTIVE, /* active but unlocked */
- ZORAN_LOCKED, /* locked */
-};
-
-/* buffer collections */
-struct zoran_buffer_col {
- enum zoran_lock_activity active; /* feature currently in use? */
- unsigned int num_buffers, buffer_size;
- struct zoran_buffer buffer[MAX_FRAME]; /* buffers */
- u8 allocated; /* Flag if buffers are allocated */
- u8 need_contiguous; /* Flag if contiguous buffers are needed */
- /* only applies to jpg buffers, raw buffers are always contiguous */
-};
-
-struct zoran;
-
-/* zoran_fh contains per-open() settings */
-struct zoran_fh {
- struct zoran *zr;
-
- enum zoran_map_mode map_mode; /* Flag which bufferset will map by next mmap() */
-
- struct zoran_overlay_settings overlay_settings;
- u32 *overlay_mask; /* overlay mask */
- enum zoran_lock_activity overlay_active;/* feature currently in use? */
-
- struct zoran_buffer_col buffers; /* buffers' info */
-
- struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */
- struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */
-};
-
-struct card_info {
- enum card_type type;
- char name[32];
- const char *i2c_decoder; /* i2c decoder device */
- const unsigned short *addrs_decoder;
- const char *i2c_encoder; /* i2c encoder device */
- const unsigned short *addrs_encoder;
- u16 video_vfe, video_codec; /* videocodec types */
- u16 audio_chip; /* audio type */
-
- int inputs; /* number of video inputs */
- struct input {
- int muxsel;
- char name[32];
- } input[BUZ_MAX_INPUT];
-
- v4l2_std_id norms;
- struct tvnorm *tvn[3]; /* supported TV norms */
-
- u32 jpeg_int; /* JPEG interrupt */
- u32 vsync_int; /* VSYNC interrupt */
- s8 gpio[ZR_GPIO_MAX];
- u8 gpcs[GPCS_MAX];
-
- struct vfe_polarity vfe_pol;
- u8 gpio_pol[ZR_GPIO_MAX];
-
- /* is the /GWS line connected? */
- u8 gws_not_connected;
-
- /* avs6eyes mux setting */
- u8 input_mux;
-
- void (*init) (struct zoran * zr);
-};
-
-struct zoran {
- struct v4l2_device v4l2_dev;
- struct video_device *video_dev;
-
- struct i2c_adapter i2c_adapter; /* */
- struct i2c_algo_bit_data i2c_algo; /* */
- u32 i2cbr;
-
- struct v4l2_subdev *decoder; /* video decoder sub-device */
- struct v4l2_subdev *encoder; /* video encoder sub-device */
-
- struct videocodec *codec; /* video codec */
- struct videocodec *vfe; /* video front end */
-
- struct mutex resource_lock; /* prevent evil stuff */
- struct mutex other_lock; /* please merge with above */
-
- u8 initialized; /* flag if zoran has been correctly initialized */
- int user; /* number of current users */
- struct card_info card;
- struct tvnorm *timing;
-
- unsigned short id; /* number of this device */
- char name[32]; /* name of this device */
- struct pci_dev *pci_dev; /* PCI device */
- unsigned char revision; /* revision of zr36057 */
- unsigned char __iomem *zr36057_mem;/* pointer to mapped IO memory */
-
- spinlock_t spinlock; /* Spinlock */
-
- /* Video for Linux parameters */
- int input; /* card's norm and input */
- v4l2_std_id norm;
-
- /* Current buffer params */
- void *vbuf_base;
- int vbuf_height, vbuf_width;
- int vbuf_depth;
- int vbuf_bytesperline;
-
- struct zoran_overlay_settings overlay_settings;
- u32 *overlay_mask; /* overlay mask */
- enum zoran_lock_activity overlay_active; /* feature currently in use? */
-
- wait_queue_head_t v4l_capq;
-
- int v4l_overlay_active; /* Overlay grab is activated */
- int v4l_memgrab_active; /* Memory grab is activated */
-
- int v4l_grab_frame; /* Frame number being currently grabbed */
-#define NO_GRAB_ACTIVE (-1)
- unsigned long v4l_grab_seq; /* Number of frames grabbed */
- struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */
-
- /* V4L grab queue of frames pending */
- unsigned long v4l_pend_head;
- unsigned long v4l_pend_tail;
- unsigned long v4l_sync_tail;
- int v4l_pend[V4L_MAX_FRAME];
- struct zoran_buffer_col v4l_buffers; /* V4L buffers' info */
-
- /* Buz MJPEG parameters */
- enum zoran_codec_mode codec_mode; /* status of codec */
- struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */
-
- wait_queue_head_t jpg_capq; /* wait here for grab to finish */
-
- /* grab queue counts/indices, mask with BUZ_MASK_STAT_COM before using as index */
- /* (dma_head - dma_tail) is number active in DMA, must be <= BUZ_NUM_STAT_COM */
- /* (value & BUZ_MASK_STAT_COM) corresponds to index in stat_com table */
- unsigned long jpg_que_head; /* Index where to put next buffer which is queued */
- unsigned long jpg_dma_head; /* Index of next buffer which goes into stat_com */
- unsigned long jpg_dma_tail; /* Index of last buffer in stat_com */
- unsigned long jpg_que_tail; /* Index of last buffer in queue */
- unsigned long jpg_seq_num; /* count of frames since grab/play started */
- unsigned long jpg_err_seq; /* last seq_num before error */
- unsigned long jpg_err_shift;
- unsigned long jpg_queued_num; /* count of frames queued since grab/play started */
-
- /* zr36057's code buffer table */
- __le32 *stat_com; /* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */
-
- /* (value & BUZ_MASK_FRAME) corresponds to index in pend[] queue */
- int jpg_pend[BUZ_MAX_FRAME];
-
- /* array indexed by frame number */
- struct zoran_buffer_col jpg_buffers; /* MJPEG buffers' info */
-
- /* Additional stuff for testing */
-#ifdef CONFIG_PROC_FS
- struct proc_dir_entry *zoran_proc;
-#else
- void *zoran_proc;
-#endif
- int testing;
- int jpeg_error;
- int intr_counter_GIRQ1;
- int intr_counter_GIRQ0;
- int intr_counter_CodRepIRQ;
- int intr_counter_JPEGRepIRQ;
- int field_counter;
- int IRQ1_in;
- int IRQ1_out;
- int JPEG_in;
- int JPEG_out;
- int JPEG_0;
- int JPEG_1;
- int END_event_missed;
- int JPEG_missed;
- int JPEG_error;
- int num_errors;
- int JPEG_max_missed;
- int JPEG_min_missed;
-
- u32 last_isr;
- unsigned long frame_num;
-
- wait_queue_head_t test_q;
-};
-
-static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct zoran, v4l2_dev);
-}
-
-/* There was something called _ALPHA_BUZ that used the PCI address instead of
- * the kernel iomapped address for btread/btwrite. */
-#define btwrite(dat,adr) writel((dat), zr->zr36057_mem+(adr))
-#define btread(adr) readl(zr->zr36057_mem+(adr))
-
-#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
-#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
-#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
-
-#endif
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
deleted file mode 100644
index c3602d6cd48..00000000000
--- a/drivers/media/video/zoran/zoran_card.c
+++ /dev/null
@@ -1,1524 +0,0 @@
-/*
- * Zoran zr36057/zr36067 PCI controller driver, for the
- * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
- * Media Labs LML33/LML33R10.
- *
- * This part handles card-specific data and detection
- *
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- *
- * Currently maintained by:
- * Ronald Bultje <rbultje@ronald.bitfreak.net>
- * Laurent Pinchart <laurent.pinchart@skynet.be>
- * Mailinglist <mjpeg-users@lists.sf.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/delay.h>
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-
-#include <linux/proc_fs.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/videodev2.h>
-#include <linux/spinlock.h>
-#include <linux/sem.h>
-#include <linux/kmod.h>
-#include <linux/wait.h>
-
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/io.h>
-#include <media/v4l2-common.h>
-#include <media/bt819.h>
-
-#include "videocodec.h"
-#include "zoran.h"
-#include "zoran_card.h"
-#include "zoran_device.h"
-#include "zoran_procfs.h"
-
-extern const struct zoran_format zoran_formats[];
-
-static int card[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
-module_param_array(card, int, NULL, 0444);
-MODULE_PARM_DESC(card, "Card type");
-
-/*
- The video mem address of the video card.
- The driver has a little database for some videocards
- to determine it from there. If your video card is not in there
- you have either to give it to the driver as a parameter
- or set in in a VIDIOCSFBUF ioctl
- */
-
-static unsigned long vidmem; /* default = 0 - Video memory base address */
-module_param(vidmem, ulong, 0444);
-MODULE_PARM_DESC(vidmem, "Default video memory base address");
-
-/*
- Default input and video norm at startup of the driver.
-*/
-
-static unsigned int default_input; /* default 0 = Composite, 1 = S-Video */
-module_param(default_input, uint, 0444);
-MODULE_PARM_DESC(default_input,
- "Default input (0=Composite, 1=S-Video, 2=Internal)");
-
-static int default_mux = 1; /* 6 Eyes input selection */
-module_param(default_mux, int, 0644);
-MODULE_PARM_DESC(default_mux,
- "Default 6 Eyes mux setting (Input selection)");
-
-static int default_norm; /* default 0 = PAL, 1 = NTSC 2 = SECAM */
-module_param(default_norm, int, 0444);
-MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
-
-/* /dev/videoN, -1 for autodetect */
-static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
-module_param_array(video_nr, int, NULL, 0444);
-MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)");
-
-int v4l_nbufs = 4;
-int v4l_bufsize = 864; /* Everybody should be able to work with this setting */
-module_param(v4l_nbufs, int, 0644);
-MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use");
-module_param(v4l_bufsize, int, 0644);
-MODULE_PARM_DESC(v4l_bufsize, "Maximum size per V4L buffer (in kB)");
-
-int jpg_nbufs = 32;
-int jpg_bufsize = 512; /* max size for 100% quality full-PAL frame */
-module_param(jpg_nbufs, int, 0644);
-MODULE_PARM_DESC(jpg_nbufs, "Maximum number of JPG buffers to use");
-module_param(jpg_bufsize, int, 0644);
-MODULE_PARM_DESC(jpg_bufsize, "Maximum size per JPG buffer (in kB)");
-
-int pass_through = 0; /* 1=Pass through TV signal when device is not used */
- /* 0=Show color bar when device is not used (LML33: only if lml33dpath=1) */
-module_param(pass_through, int, 0644);
-MODULE_PARM_DESC(pass_through,
- "Pass TV signal through to TV-out when idling");
-
-int zr36067_debug = 1;
-module_param_named(debug, zr36067_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-5)");
-
-#define ZORAN_VERSION "0.10.1"
-
-MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
-MODULE_AUTHOR("Serguei Miridonov");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(ZORAN_VERSION);
-
-#define ZR_DEVICE(subven, subdev, data) { \
- .vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \
- .subvendor = (subven), .subdevice = (subdev), .driver_data = (data) }
-
-static struct pci_device_id zr36067_pci_tbl[] = {
- ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10plus),
- ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30plus),
- ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10),
- ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ),
- ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS),
- {0}
-};
-MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
-
-static unsigned int zoran_num; /* number of cards found */
-
-/* videocodec bus functions ZR36060 */
-static u32
-zr36060_read (struct videocodec *codec,
- u16 reg)
-{
- struct zoran *zr = (struct zoran *) codec->master_data->data;
- __u32 data;
-
- if (post_office_wait(zr)
- || post_office_write(zr, 0, 1, reg >> 8)
- || post_office_write(zr, 0, 2, reg & 0xff)) {
- return -1;
- }
-
- data = post_office_read(zr, 0, 3) & 0xff;
- return data;
-}
-
-static void
-zr36060_write (struct videocodec *codec,
- u16 reg,
- u32 val)
-{
- struct zoran *zr = (struct zoran *) codec->master_data->data;
-
- if (post_office_wait(zr)
- || post_office_write(zr, 0, 1, reg >> 8)
- || post_office_write(zr, 0, 2, reg & 0xff)) {
- return;
- }
-
- post_office_write(zr, 0, 3, val & 0xff);
-}
-
-/* videocodec bus functions ZR36050 */
-static u32
-zr36050_read (struct videocodec *codec,
- u16 reg)
-{
- struct zoran *zr = (struct zoran *) codec->master_data->data;
- __u32 data;
-
- if (post_office_wait(zr)
- || post_office_write(zr, 1, 0, reg >> 2)) { // reg. HIGHBYTES
- return -1;
- }
-
- data = post_office_read(zr, 0, reg & 0x03) & 0xff; // reg. LOWBYTES + read
- return data;
-}
-
-static void
-zr36050_write (struct videocodec *codec,
- u16 reg,
- u32 val)
-{
- struct zoran *zr = (struct zoran *) codec->master_data->data;
-
- if (post_office_wait(zr)
- || post_office_write(zr, 1, 0, reg >> 2)) { // reg. HIGHBYTES
- return;
- }
-
- post_office_write(zr, 0, reg & 0x03, val & 0xff); // reg. LOWBYTES + wr. data
-}
-
-/* videocodec bus functions ZR36016 */
-static u32
-zr36016_read (struct videocodec *codec,
- u16 reg)
-{
- struct zoran *zr = (struct zoran *) codec->master_data->data;
- __u32 data;
-
- if (post_office_wait(zr)) {
- return -1;
- }
-
- data = post_office_read(zr, 2, reg & 0x03) & 0xff; // read
- return data;
-}
-
-/* hack for in zoran_device.c */
-void
-zr36016_write (struct videocodec *codec,
- u16 reg,
- u32 val)
-{
- struct zoran *zr = (struct zoran *) codec->master_data->data;
-
- if (post_office_wait(zr)) {
- return;
- }
-
- post_office_write(zr, 2, reg & 0x03, val & 0x0ff); // wr. data
-}
-
-/*
- * Board specific information
- */
-
-static void
-dc10_init (struct zoran *zr)
-{
- dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
-
- /* Pixel clock selection */
- GPIO(zr, 4, 0);
- GPIO(zr, 5, 1);
- /* Enable the video bus sync signals */
- GPIO(zr, 7, 0);
-}
-
-static void
-dc10plus_init (struct zoran *zr)
-{
- dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
-}
-
-static void
-buz_init (struct zoran *zr)
-{
- dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
-
- /* some stuff from Iomega */
- pci_write_config_dword(zr->pci_dev, 0xfc, 0x90680f15);
- pci_write_config_dword(zr->pci_dev, 0x0c, 0x00012020);
- pci_write_config_dword(zr->pci_dev, 0xe8, 0xc0200000);
-}
-
-static void
-lml33_init (struct zoran *zr)
-{
- dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
-
- GPIO(zr, 2, 1); // Set Composite input/output
-}
-
-static void
-avs6eyes_init (struct zoran *zr)
-{
- // AverMedia 6-Eyes original driver by Christer Weinigel
-
- // Lifted straight from Christer's old driver and
- // modified slightly by Martin Samuelsson.
-
- int mux = default_mux; /* 1 = BT866, 7 = VID1 */
-
- GPIO(zr, 4, 1); /* Bt866 SLEEP on */
- udelay(2);
-
- GPIO(zr, 0, 1); /* ZR36060 /RESET on */
- GPIO(zr, 1, 0); /* ZR36060 /SLEEP on */
- GPIO(zr, 2, mux & 1); /* MUX S0 */
- GPIO(zr, 3, 0); /* /FRAME on */
- GPIO(zr, 4, 0); /* Bt866 SLEEP off */
- GPIO(zr, 5, mux & 2); /* MUX S1 */
- GPIO(zr, 6, 0); /* ? */
- GPIO(zr, 7, mux & 4); /* MUX S2 */
-
-}
-
-static char *
-codecid_to_modulename (u16 codecid)
-{
- char *name = NULL;
-
- switch (codecid) {
- case CODEC_TYPE_ZR36060:
- name = "zr36060";
- break;
- case CODEC_TYPE_ZR36050:
- name = "zr36050";
- break;
- case CODEC_TYPE_ZR36016:
- name = "zr36016";
- break;
- }
-
- return name;
-}
-
-// struct tvnorm {
-// u16 Wt, Wa, HStart, HSyncStart, Ht, Ha, VStart;
-// };
-
-static struct tvnorm f50sqpixel = { 944, 768, 83, 880, 625, 576, 16 };
-static struct tvnorm f60sqpixel = { 780, 640, 51, 716, 525, 480, 12 };
-static struct tvnorm f50ccir601 = { 864, 720, 75, 804, 625, 576, 18 };
-static struct tvnorm f60ccir601 = { 858, 720, 57, 788, 525, 480, 16 };
-
-static struct tvnorm f50ccir601_lml33 = { 864, 720, 75+34, 804, 625, 576, 18 };
-static struct tvnorm f60ccir601_lml33 = { 858, 720, 57+34, 788, 525, 480, 16 };
-
-/* The DC10 (57/16/50) uses VActive as HSync, so HStart must be 0 */
-static struct tvnorm f50sqpixel_dc10 = { 944, 768, 0, 880, 625, 576, 0 };
-static struct tvnorm f60sqpixel_dc10 = { 780, 640, 0, 716, 525, 480, 12 };
-
-/* FIXME: I cannot swap U and V in saa7114, so i do one
- * pixel left shift in zoran (75 -> 74)
- * (Maxim Yevtyushkin <max@linuxmedialabs.com>) */
-static struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74+54, 804, 625, 576, 18 };
-static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 };
-
-/* FIXME: The ks0127 seem incapable of swapping U and V, too, which is why I
- * copy Maxim's left shift hack for the 6 Eyes.
- *
- * Christer's driver used the unshifted norms, though...
- * /Sam */
-static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 };
-static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 };
-
-static const unsigned short vpx3220_addrs[] = { 0x43, 0x47, I2C_CLIENT_END };
-static const unsigned short saa7110_addrs[] = { 0x4e, 0x4f, I2C_CLIENT_END };
-static const unsigned short saa7111_addrs[] = { 0x25, 0x24, I2C_CLIENT_END };
-static const unsigned short saa7114_addrs[] = { 0x21, 0x20, I2C_CLIENT_END };
-static const unsigned short adv717x_addrs[] = { 0x6a, 0x6b, 0x2a, 0x2b, I2C_CLIENT_END };
-static const unsigned short ks0127_addrs[] = { 0x6c, 0x6d, I2C_CLIENT_END };
-static const unsigned short saa7185_addrs[] = { 0x44, I2C_CLIENT_END };
-static const unsigned short bt819_addrs[] = { 0x45, I2C_CLIENT_END };
-static const unsigned short bt856_addrs[] = { 0x44, I2C_CLIENT_END };
-static const unsigned short bt866_addrs[] = { 0x44, I2C_CLIENT_END };
-
-static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
- {
- .type = DC10_old,
- .name = "DC10(old)",
- .i2c_decoder = "vpx3220a",
- .addrs_decoder = vpx3220_addrs,
- .video_codec = CODEC_TYPE_ZR36050,
- .video_vfe = CODEC_TYPE_ZR36016,
-
- .inputs = 3,
- .input = {
- { 1, "Composite" },
- { 2, "S-Video" },
- { 0, "Internal/comp" }
- },
- .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
- .tvn = {
- &f50sqpixel_dc10,
- &f60sqpixel_dc10,
- &f50sqpixel_dc10
- },
- .jpeg_int = 0,
- .vsync_int = ZR36057_ISR_GIRQ1,
- .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
- .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
- .gpcs = { -1, 0 },
- .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
- .gws_not_connected = 0,
- .input_mux = 0,
- .init = &dc10_init,
- }, {
- .type = DC10_new,
- .name = "DC10(new)",
- .i2c_decoder = "saa7110",
- .addrs_decoder = saa7110_addrs,
- .i2c_encoder = "adv7175",
- .addrs_encoder = adv717x_addrs,
- .video_codec = CODEC_TYPE_ZR36060,
-
- .inputs = 3,
- .input = {
- { 0, "Composite" },
- { 7, "S-Video" },
- { 5, "Internal/comp" }
- },
- .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
- .tvn = {
- &f50sqpixel,
- &f60sqpixel,
- &f50sqpixel},
- .jpeg_int = ZR36057_ISR_GIRQ0,
- .vsync_int = ZR36057_ISR_GIRQ1,
- .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 },
- .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
- .gpcs = { -1, 1},
- .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
- .gws_not_connected = 0,
- .input_mux = 0,
- .init = &dc10plus_init,
- }, {
- .type = DC10plus,
- .name = "DC10plus",
- .i2c_decoder = "saa7110",
- .addrs_decoder = saa7110_addrs,
- .i2c_encoder = "adv7175",
- .addrs_encoder = adv717x_addrs,
- .video_codec = CODEC_TYPE_ZR36060,
-
- .inputs = 3,
- .input = {
- { 0, "Composite" },
- { 7, "S-Video" },
- { 5, "Internal/comp" }
- },
- .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
- .tvn = {
- &f50sqpixel,
- &f60sqpixel,
- &f50sqpixel
- },
- .jpeg_int = ZR36057_ISR_GIRQ0,
- .vsync_int = ZR36057_ISR_GIRQ1,
- .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 },
- .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
- .gpcs = { -1, 1 },
- .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
- .gws_not_connected = 0,
- .input_mux = 0,
- .init = &dc10plus_init,
- }, {
- .type = DC30,
- .name = "DC30",
- .i2c_decoder = "vpx3220a",
- .addrs_decoder = vpx3220_addrs,
- .i2c_encoder = "adv7175",
- .addrs_encoder = adv717x_addrs,
- .video_codec = CODEC_TYPE_ZR36050,
- .video_vfe = CODEC_TYPE_ZR36016,
-
- .inputs = 3,
- .input = {
- { 1, "Composite" },
- { 2, "S-Video" },
- { 0, "Internal/comp" }
- },
- .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
- .tvn = {
- &f50sqpixel_dc10,
- &f60sqpixel_dc10,
- &f50sqpixel_dc10
- },
- .jpeg_int = 0,
- .vsync_int = ZR36057_ISR_GIRQ1,
- .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
- .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
- .gpcs = { -1, 0 },
- .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
- .gws_not_connected = 0,
- .input_mux = 0,
- .init = &dc10_init,
- }, {
- .type = DC30plus,
- .name = "DC30plus",
- .i2c_decoder = "vpx3220a",
- .addrs_decoder = vpx3220_addrs,
- .i2c_encoder = "adv7175",
- .addrs_encoder = adv717x_addrs,
- .video_codec = CODEC_TYPE_ZR36050,
- .video_vfe = CODEC_TYPE_ZR36016,
-
- .inputs = 3,
- .input = {
- { 1, "Composite" },
- { 2, "S-Video" },
- { 0, "Internal/comp" }
- },
- .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
- .tvn = {
- &f50sqpixel_dc10,
- &f60sqpixel_dc10,
- &f50sqpixel_dc10
- },
- .jpeg_int = 0,
- .vsync_int = ZR36057_ISR_GIRQ1,
- .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
- .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
- .gpcs = { -1, 0 },
- .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
- .gws_not_connected = 0,
- .input_mux = 0,
- .init = &dc10_init,
- }, {
- .type = LML33,
- .name = "LML33",
- .i2c_decoder = "bt819a",
- .addrs_decoder = bt819_addrs,
- .i2c_encoder = "bt856",
- .addrs_encoder = bt856_addrs,
- .video_codec = CODEC_TYPE_ZR36060,
-
- .inputs = 2,
- .input = {
- { 0, "Composite" },
- { 7, "S-Video" }
- },
- .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
- .tvn = {
- &f50ccir601_lml33,
- &f60ccir601_lml33,
- NULL
- },
- .jpeg_int = ZR36057_ISR_GIRQ1,
- .vsync_int = ZR36057_ISR_GIRQ0,
- .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 },
- .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 },
- .gpcs = { 3, 1 },
- .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
- .gws_not_connected = 1,
- .input_mux = 0,
- .init = &lml33_init,
- }, {
- .type = LML33R10,
- .name = "LML33R10",
- .i2c_decoder = "saa7114",
- .addrs_decoder = saa7114_addrs,
- .i2c_encoder = "adv7170",
- .addrs_encoder = adv717x_addrs,
- .video_codec = CODEC_TYPE_ZR36060,
-
- .inputs = 2,
- .input = {
- { 0, "Composite" },
- { 7, "S-Video" }
- },
- .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
- .tvn = {
- &f50ccir601_lm33r10,
- &f60ccir601_lm33r10,
- NULL
- },
- .jpeg_int = ZR36057_ISR_GIRQ1,
- .vsync_int = ZR36057_ISR_GIRQ0,
- .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 },
- .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 },
- .gpcs = { 3, 1 },
- .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
- .gws_not_connected = 1,
- .input_mux = 0,
- .init = &lml33_init,
- }, {
- .type = BUZ,
- .name = "Buz",
- .i2c_decoder = "saa7111",
- .addrs_decoder = saa7111_addrs,
- .i2c_encoder = "saa7185",
- .addrs_encoder = saa7185_addrs,
- .video_codec = CODEC_TYPE_ZR36060,
-
- .inputs = 2,
- .input = {
- { 3, "Composite" },
- { 7, "S-Video" }
- },
- .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
- .tvn = {
- &f50ccir601,
- &f60ccir601,
- &f50ccir601
- },
- .jpeg_int = ZR36057_ISR_GIRQ1,
- .vsync_int = ZR36057_ISR_GIRQ0,
- .gpio = { 1, -1, 3, -1, -1, -1, -1, -1 },
- .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
- .gpcs = { 3, 1 },
- .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
- .gws_not_connected = 1,
- .input_mux = 0,
- .init = &buz_init,
- }, {
- .type = AVS6EYES,
- .name = "6-Eyes",
- /* AverMedia chose not to brand the 6-Eyes. Thus it
- can't be autodetected, and requires card=x. */
- .i2c_decoder = "ks0127",
- .addrs_decoder = ks0127_addrs,
- .i2c_encoder = "bt866",
- .addrs_encoder = bt866_addrs,
- .video_codec = CODEC_TYPE_ZR36060,
-
- .inputs = 10,
- .input = {
- { 0, "Composite 1" },
- { 1, "Composite 2" },
- { 2, "Composite 3" },
- { 4, "Composite 4" },
- { 5, "Composite 5" },
- { 6, "Composite 6" },
- { 8, "S-Video 1" },
- { 9, "S-Video 2" },
- {10, "S-Video 3" },
- {15, "YCbCr" }
- },
- .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
- .tvn = {
- &f50ccir601_avs6eyes,
- &f60ccir601_avs6eyes,
- NULL
- },
- .jpeg_int = ZR36057_ISR_GIRQ1,
- .vsync_int = ZR36057_ISR_GIRQ0,
- .gpio = { 1, 0, 3, -1, -1, -1, -1, -1 },// Validity unknown /Sam
- .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, // Validity unknown /Sam
- .gpcs = { 3, 1 }, // Validity unknown /Sam
- .vfe_pol = { 1, 0, 0, 0, 0, 1, 0, 0 }, // Validity unknown /Sam
- .gws_not_connected = 1,
- .input_mux = 1,
- .init = &avs6eyes_init,
- }
-
-};
-
-/*
- * I2C functions
- */
-/* software I2C functions */
-static int
-zoran_i2c_getsda (void *data)
-{
- struct zoran *zr = (struct zoran *) data;
-
- return (btread(ZR36057_I2CBR) >> 1) & 1;
-}
-
-static int
-zoran_i2c_getscl (void *data)
-{
- struct zoran *zr = (struct zoran *) data;
-
- return btread(ZR36057_I2CBR) & 1;
-}
-
-static void
-zoran_i2c_setsda (void *data,
- int state)
-{
- struct zoran *zr = (struct zoran *) data;
-
- if (state)
- zr->i2cbr |= 2;
- else
- zr->i2cbr &= ~2;
- btwrite(zr->i2cbr, ZR36057_I2CBR);
-}
-
-static void
-zoran_i2c_setscl (void *data,
- int state)
-{
- struct zoran *zr = (struct zoran *) data;
-
- if (state)
- zr->i2cbr |= 1;
- else
- zr->i2cbr &= ~1;
- btwrite(zr->i2cbr, ZR36057_I2CBR);
-}
-
-static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
- .setsda = zoran_i2c_setsda,
- .setscl = zoran_i2c_setscl,
- .getsda = zoran_i2c_getsda,
- .getscl = zoran_i2c_getscl,
- .udelay = 10,
- .timeout = 100,
-};
-
-static int
-zoran_register_i2c (struct zoran *zr)
-{
- memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
- sizeof(struct i2c_algo_bit_data));
- zr->i2c_algo.data = zr;
- strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr),
- sizeof(zr->i2c_adapter.name));
- i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev);
- zr->i2c_adapter.algo_data = &zr->i2c_algo;
- zr->i2c_adapter.dev.parent = &zr->pci_dev->dev;
- return i2c_bit_add_bus(&zr->i2c_adapter);
-}
-
-static void
-zoran_unregister_i2c (struct zoran *zr)
-{
- i2c_del_adapter(&zr->i2c_adapter);
-}
-
-/* Check a zoran_params struct for correctness, insert default params */
-
-int
-zoran_check_jpg_settings (struct zoran *zr,
- struct zoran_jpg_settings *settings,
- int try)
-{
- int err = 0, err0 = 0;
-
- dprintk(4,
- KERN_DEBUG
- "%s: %s - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n",
- ZR_DEVNAME(zr), __func__, settings->decimation, settings->HorDcm,
- settings->VerDcm, settings->TmpDcm);
- dprintk(4,
- KERN_DEBUG
- "%s: %s - x: %d, y: %d, w: %d, y: %d\n",
- ZR_DEVNAME(zr), __func__, settings->img_x, settings->img_y,
- settings->img_width, settings->img_height);
- /* Check decimation, set default values for decimation = 1, 2, 4 */
- switch (settings->decimation) {
- case 1:
-
- settings->HorDcm = 1;
- settings->VerDcm = 1;
- settings->TmpDcm = 1;
- settings->field_per_buff = 2;
- settings->img_x = 0;
- settings->img_y = 0;
- settings->img_width = BUZ_MAX_WIDTH;
- settings->img_height = BUZ_MAX_HEIGHT / 2;
- break;
- case 2:
-
- settings->HorDcm = 2;
- settings->VerDcm = 1;
- settings->TmpDcm = 2;
- settings->field_per_buff = 1;
- settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
- settings->img_y = 0;
- settings->img_width =
- (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
- settings->img_height = BUZ_MAX_HEIGHT / 2;
- break;
- case 4:
-
- if (zr->card.type == DC10_new) {
- dprintk(1,
- KERN_DEBUG
- "%s: %s - HDec by 4 is not supported on the DC10\n",
- ZR_DEVNAME(zr), __func__);
- err0++;
- break;
- }
-
- settings->HorDcm = 4;
- settings->VerDcm = 2;
- settings->TmpDcm = 2;
- settings->field_per_buff = 1;
- settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
- settings->img_y = 0;
- settings->img_width =
- (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
- settings->img_height = BUZ_MAX_HEIGHT / 2;
- break;
- case 0:
-
- /* We have to check the data the user has set */
-
- if (settings->HorDcm != 1 && settings->HorDcm != 2 &&
- (zr->card.type == DC10_new || settings->HorDcm != 4)) {
- settings->HorDcm = clamp(settings->HorDcm, 1, 2);
- err0++;
- }
- if (settings->VerDcm != 1 && settings->VerDcm != 2) {
- settings->VerDcm = clamp(settings->VerDcm, 1, 2);
- err0++;
- }
- if (settings->TmpDcm != 1 && settings->TmpDcm != 2) {
- settings->TmpDcm = clamp(settings->TmpDcm, 1, 2);
- err0++;
- }
- if (settings->field_per_buff != 1 &&
- settings->field_per_buff != 2) {
- settings->field_per_buff = clamp(settings->field_per_buff, 1, 2);
- err0++;
- }
- if (settings->img_x < 0) {
- settings->img_x = 0;
- err0++;
- }
- if (settings->img_y < 0) {
- settings->img_y = 0;
- err0++;
- }
- if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) {
- settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH);
- err0++;
- }
- if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) {
- settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2);
- err0++;
- }
- if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) {
- settings->img_x = BUZ_MAX_WIDTH - settings->img_width;
- err0++;
- }
- if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) {
- settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height;
- err0++;
- }
- if (settings->img_width % (16 * settings->HorDcm) != 0) {
- settings->img_width -= settings->img_width % (16 * settings->HorDcm);
- if (settings->img_width == 0)
- settings->img_width = 16 * settings->HorDcm;
- err0++;
- }
- if (settings->img_height % (8 * settings->VerDcm) != 0) {
- settings->img_height -= settings->img_height % (8 * settings->VerDcm);
- if (settings->img_height == 0)
- settings->img_height = 8 * settings->VerDcm;
- err0++;
- }
-
- if (!try && err0) {
- dprintk(1,
- KERN_ERR
- "%s: %s - error in params for decimation = 0\n",
- ZR_DEVNAME(zr), __func__);
- err++;
- }
- break;
- default:
- dprintk(1,
- KERN_ERR
- "%s: %s - decimation = %d, must be 0, 1, 2 or 4\n",
- ZR_DEVNAME(zr), __func__, settings->decimation);
- err++;
- break;
- }
-
- if (settings->jpg_comp.quality > 100)
- settings->jpg_comp.quality = 100;
- if (settings->jpg_comp.quality < 5)
- settings->jpg_comp.quality = 5;
- if (settings->jpg_comp.APPn < 0)
- settings->jpg_comp.APPn = 0;
- if (settings->jpg_comp.APPn > 15)
- settings->jpg_comp.APPn = 15;
- if (settings->jpg_comp.APP_len < 0)
- settings->jpg_comp.APP_len = 0;
- if (settings->jpg_comp.APP_len > 60)
- settings->jpg_comp.APP_len = 60;
- if (settings->jpg_comp.COM_len < 0)
- settings->jpg_comp.COM_len = 0;
- if (settings->jpg_comp.COM_len > 60)
- settings->jpg_comp.COM_len = 60;
- if (err)
- return -EINVAL;
- return 0;
-}
-
-void
-zoran_open_init_params (struct zoran *zr)
-{
- int i;
-
- /* User must explicitly set a window */
- zr->overlay_settings.is_set = 0;
- zr->overlay_mask = NULL;
- zr->overlay_active = ZORAN_FREE;
-
- zr->v4l_memgrab_active = 0;
- zr->v4l_overlay_active = 0;
- zr->v4l_grab_frame = NO_GRAB_ACTIVE;
- zr->v4l_grab_seq = 0;
- zr->v4l_settings.width = 192;
- zr->v4l_settings.height = 144;
- zr->v4l_settings.format = &zoran_formats[7]; /* YUY2 - YUV-4:2:2 packed */
- zr->v4l_settings.bytesperline =
- zr->v4l_settings.width *
- ((zr->v4l_settings.format->depth + 7) / 8);
-
- /* DMA ring stuff for V4L */
- zr->v4l_pend_tail = 0;
- zr->v4l_pend_head = 0;
- zr->v4l_sync_tail = 0;
- zr->v4l_buffers.active = ZORAN_FREE;
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
- }
- zr->v4l_buffers.allocated = 0;
-
- for (i = 0; i < BUZ_MAX_FRAME; i++) {
- zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
- }
- zr->jpg_buffers.active = ZORAN_FREE;
- zr->jpg_buffers.allocated = 0;
- /* Set necessary params and call zoran_check_jpg_settings to set the defaults */
- zr->jpg_settings.decimation = 1;
- zr->jpg_settings.jpg_comp.quality = 50; /* default compression factor 8 */
- if (zr->card.type != BUZ)
- zr->jpg_settings.odd_even = 1;
- else
- zr->jpg_settings.odd_even = 0;
- zr->jpg_settings.jpg_comp.APPn = 0;
- zr->jpg_settings.jpg_comp.APP_len = 0; /* No APPn marker */
- memset(zr->jpg_settings.jpg_comp.APP_data, 0,
- sizeof(zr->jpg_settings.jpg_comp.APP_data));
- zr->jpg_settings.jpg_comp.COM_len = 0; /* No COM marker */
- memset(zr->jpg_settings.jpg_comp.COM_data, 0,
- sizeof(zr->jpg_settings.jpg_comp.COM_data));
- zr->jpg_settings.jpg_comp.jpeg_markers =
- V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT;
- i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0);
- if (i)
- dprintk(1, KERN_ERR "%s: %s internal error\n",
- ZR_DEVNAME(zr), __func__);
-
- clear_interrupt_counters(zr);
- zr->testing = 0;
-}
-
-static void __devinit
-test_interrupts (struct zoran *zr)
-{
- DEFINE_WAIT(wait);
- int timeout, icr;
-
- clear_interrupt_counters(zr);
-
- zr->testing = 1;
- icr = btread(ZR36057_ICR);
- btwrite(0x78000000 | ZR36057_ICR_IntPinEn, ZR36057_ICR);
- prepare_to_wait(&zr->test_q, &wait, TASK_INTERRUPTIBLE);
- timeout = schedule_timeout(HZ);
- finish_wait(&zr->test_q, &wait);
- btwrite(0, ZR36057_ICR);
- btwrite(0x78000000, ZR36057_ISR);
- zr->testing = 0;
- dprintk(5, KERN_INFO "%s: Testing interrupts...\n", ZR_DEVNAME(zr));
- if (timeout) {
- dprintk(1, ": time spent: %d\n", 1 * HZ - timeout);
- }
- if (zr36067_debug > 1)
- print_interrupts(zr);
- btwrite(icr, ZR36057_ICR);
-}
-
-static int __devinit
-zr36057_init (struct zoran *zr)
-{
- int j, err;
-
- dprintk(1,
- KERN_INFO
- "%s: %s - initializing card[%d], zr=%p\n",
- ZR_DEVNAME(zr), __func__, zr->id, zr);
-
- /* default setup of all parameters which will persist between opens */
- zr->user = 0;
-
- init_waitqueue_head(&zr->v4l_capq);
- init_waitqueue_head(&zr->jpg_capq);
- init_waitqueue_head(&zr->test_q);
- zr->jpg_buffers.allocated = 0;
- zr->v4l_buffers.allocated = 0;
-
- zr->vbuf_base = (void *) vidmem;
- zr->vbuf_width = 0;
- zr->vbuf_height = 0;
- zr->vbuf_depth = 0;
- zr->vbuf_bytesperline = 0;
-
- /* Avoid nonsense settings from user for default input/norm */
- if (default_norm < 0 || default_norm > 2)
- default_norm = 0;
- if (default_norm == 0) {
- zr->norm = V4L2_STD_PAL;
- zr->timing = zr->card.tvn[0];
- } else if (default_norm == 1) {
- zr->norm = V4L2_STD_NTSC;
- zr->timing = zr->card.tvn[1];
- } else {
- zr->norm = V4L2_STD_SECAM;
- zr->timing = zr->card.tvn[2];
- }
- if (zr->timing == NULL) {
- dprintk(1,
- KERN_WARNING
- "%s: %s - default TV standard not supported by hardware. PAL will be used.\n",
- ZR_DEVNAME(zr), __func__);
- zr->norm = V4L2_STD_PAL;
- zr->timing = zr->card.tvn[0];
- }
-
- if (default_input > zr->card.inputs-1) {
- dprintk(1,
- KERN_WARNING
- "%s: default_input value %d out of range (0-%d)\n",
- ZR_DEVNAME(zr), default_input, zr->card.inputs-1);
- default_input = 0;
- }
- zr->input = default_input;
-
- /* default setup (will be repeated at every open) */
- zoran_open_init_params(zr);
-
- /* allocate memory *before* doing anything to the hardware
- * in case allocation fails */
- zr->stat_com = kzalloc(BUZ_NUM_STAT_COM * 4, GFP_KERNEL);
- zr->video_dev = video_device_alloc();
- if (!zr->stat_com || !zr->video_dev) {
- dprintk(1,
- KERN_ERR
- "%s: %s - kmalloc (STAT_COM) failed\n",
- ZR_DEVNAME(zr), __func__);
- err = -ENOMEM;
- goto exit_free;
- }
- for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
- zr->stat_com[j] = cpu_to_le32(1); /* mark as unavailable to zr36057 */
- }
-
- /*
- * Now add the template and register the device unit.
- */
- memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template));
- zr->video_dev->parent = &zr->pci_dev->dev;
- strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
- err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
- if (err < 0)
- goto exit_free;
- video_set_drvdata(zr->video_dev, zr);
-
- zoran_init_hardware(zr);
- if (zr36067_debug > 2)
- detect_guest_activity(zr);
- test_interrupts(zr);
- if (!pass_through) {
- decoder_call(zr, video, s_stream, 0);
- encoder_call(zr, video, s_routing, 2, 0, 0);
- }
-
- zr->zoran_proc = NULL;
- zr->initialized = 1;
- return 0;
-
-exit_free:
- kfree(zr->stat_com);
- kfree(zr->video_dev);
- return err;
-}
-
-static void __devexit zoran_remove(struct pci_dev *pdev)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
- struct zoran *zr = to_zoran(v4l2_dev);
-
- if (!zr->initialized)
- goto exit_free;
-
- /* unregister videocodec bus */
- if (zr->codec) {
- struct videocodec_master *master = zr->codec->master_data;
-
- videocodec_detach(zr->codec);
- kfree(master);
- }
- if (zr->vfe) {
- struct videocodec_master *master = zr->vfe->master_data;
-
- videocodec_detach(zr->vfe);
- kfree(master);
- }
-
- /* unregister i2c bus */
- zoran_unregister_i2c(zr);
- /* disable PCI bus-mastering */
- zoran_set_pci_master(zr, 0);
- /* put chip into reset */
- btwrite(0, ZR36057_SPGPPCR);
- free_irq(zr->pci_dev->irq, zr);
- /* unmap and free memory */
- kfree(zr->stat_com);
- zoran_proc_cleanup(zr);
- iounmap(zr->zr36057_mem);
- pci_disable_device(zr->pci_dev);
- video_unregister_device(zr->video_dev);
-exit_free:
- v4l2_device_unregister(&zr->v4l2_dev);
- kfree(zr);
-}
-
-void
-zoran_vdev_release (struct video_device *vdev)
-{
- kfree(vdev);
-}
-
-static struct videocodec_master * __devinit
-zoran_setup_videocodec (struct zoran *zr,
- int type)
-{
- struct videocodec_master *m = NULL;
-
- m = kmalloc(sizeof(struct videocodec_master), GFP_KERNEL);
- if (!m) {
- dprintk(1, KERN_ERR "%s: %s - no memory\n",
- ZR_DEVNAME(zr), __func__);
- return m;
- }
-
- /* magic and type are unused for master struct. Makes sense only at
- codec structs.
- In the past, .type were initialized to the old V4L1 .hardware
- value, as VID_HARDWARE_ZR36067
- */
- m->magic = 0L;
- m->type = 0;
-
- m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER;
- strlcpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
- m->data = zr;
-
- switch (type)
- {
- case CODEC_TYPE_ZR36060:
- m->readreg = zr36060_read;
- m->writereg = zr36060_write;
- m->flags |= CODEC_FLAG_JPEG | CODEC_FLAG_VFE;
- break;
- case CODEC_TYPE_ZR36050:
- m->readreg = zr36050_read;
- m->writereg = zr36050_write;
- m->flags |= CODEC_FLAG_JPEG;
- break;
- case CODEC_TYPE_ZR36016:
- m->readreg = zr36016_read;
- m->writereg = zr36016_write;
- m->flags |= CODEC_FLAG_VFE;
- break;
- }
-
- return m;
-}
-
-static void zoran_subdev_notify(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
- struct zoran *zr = to_zoran(sd->v4l2_dev);
-
- /* Bt819 needs to reset its FIFO buffer using #FRST pin and
- LML33 card uses GPIO(7) for that. */
- if (cmd == BT819_FIFO_RESET_LOW)
- GPIO(zr, 7, 0);
- else if (cmd == BT819_FIFO_RESET_HIGH)
- GPIO(zr, 7, 1);
-}
-
-/*
- * Scan for a Buz card (actually for the PCI controller ZR36057),
- * request the irq and map the io memory
- */
-static int __devinit zoran_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- unsigned char latency, need_latency;
- struct zoran *zr;
- int result;
- struct videocodec_master *master_vfe = NULL;
- struct videocodec_master *master_codec = NULL;
- int card_num;
- char *codec_name, *vfe_name;
- unsigned int nr;
-
-
- nr = zoran_num++;
- if (nr >= BUZ_MAX) {
- dprintk(1, KERN_ERR "%s: driver limited to %d card(s) maximum\n",
- ZORAN_NAME, BUZ_MAX);
- return -ENOENT;
- }
-
- zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
- if (!zr) {
- dprintk(1, KERN_ERR "%s: %s - kzalloc failed\n",
- ZORAN_NAME, __func__);
- return -ENOMEM;
- }
- zr->v4l2_dev.notify = zoran_subdev_notify;
- if (v4l2_device_register(&pdev->dev, &zr->v4l2_dev))
- goto zr_free_mem;
- zr->pci_dev = pdev;
- zr->id = nr;
- snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
- spin_lock_init(&zr->spinlock);
- mutex_init(&zr->resource_lock);
- mutex_init(&zr->other_lock);
- if (pci_enable_device(pdev))
- goto zr_unreg;
- zr->revision = zr->pci_dev->revision;
-
- dprintk(1,
- KERN_INFO
- "%s: Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08llx\n",
- ZR_DEVNAME(zr), zr->revision < 2 ? '5' : '6', zr->revision,
- zr->pci_dev->irq, (uint64_t)pci_resource_start(zr->pci_dev, 0));
- if (zr->revision >= 2) {
- dprintk(1,
- KERN_INFO
- "%s: Subsystem vendor=0x%04x id=0x%04x\n",
- ZR_DEVNAME(zr), zr->pci_dev->subsystem_vendor,
- zr->pci_dev->subsystem_device);
- }
-
- /* Use auto-detected card type? */
- if (card[nr] == -1) {
- if (zr->revision < 2) {
- dprintk(1,
- KERN_ERR
- "%s: No card type specified, please use the card=X module parameter\n",
- ZR_DEVNAME(zr));
- dprintk(1,
- KERN_ERR
- "%s: It is not possible to auto-detect ZR36057 based cards\n",
- ZR_DEVNAME(zr));
- goto zr_unreg;
- }
-
- card_num = ent->driver_data;
- if (card_num >= NUM_CARDS) {
- dprintk(1,
- KERN_ERR
- "%s: Unknown card, try specifying card=X module parameter\n",
- ZR_DEVNAME(zr));
- goto zr_unreg;
- }
- dprintk(3,
- KERN_DEBUG
- "%s: %s() - card %s detected\n",
- ZR_DEVNAME(zr), __func__, zoran_cards[card_num].name);
- } else {
- card_num = card[nr];
- if (card_num >= NUM_CARDS || card_num < 0) {
- dprintk(1,
- KERN_ERR
- "%s: User specified card type %d out of range (0 .. %d)\n",
- ZR_DEVNAME(zr), card_num, NUM_CARDS - 1);
- goto zr_unreg;
- }
- }
-
- /* even though we make this a non pointer and thus
- * theoretically allow for making changes to this struct
- * on a per-individual card basis at runtime, this is
- * strongly discouraged. This structure is intended to
- * keep general card information, no settings or anything */
- zr->card = zoran_cards[card_num];
- snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
- "%s[%u]", zr->card.name, zr->id);
-
- zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0);
- if (!zr->zr36057_mem) {
- dprintk(1, KERN_ERR "%s: %s() - ioremap failed\n",
- ZR_DEVNAME(zr), __func__);
- goto zr_unreg;
- }
-
- result = request_irq(zr->pci_dev->irq, zoran_irq,
- IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr);
- if (result < 0) {
- if (result == -EINVAL) {
- dprintk(1,
- KERN_ERR
- "%s: %s - bad irq number or handler\n",
- ZR_DEVNAME(zr), __func__);
- } else if (result == -EBUSY) {
- dprintk(1,
- KERN_ERR
- "%s: %s - IRQ %d busy, change your PnP config in BIOS\n",
- ZR_DEVNAME(zr), __func__, zr->pci_dev->irq);
- } else {
- dprintk(1,
- KERN_ERR
- "%s: %s - can't assign irq, error code %d\n",
- ZR_DEVNAME(zr), __func__, result);
- }
- goto zr_unmap;
- }
-
- /* set PCI latency timer */
- pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
- &latency);
- need_latency = zr->revision > 1 ? 32 : 48;
- if (latency != need_latency) {
- dprintk(2, KERN_INFO "%s: Changing PCI latency from %d to %d\n",
- ZR_DEVNAME(zr), latency, need_latency);
- pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
- need_latency);
- }
-
- zr36057_restart(zr);
- /* i2c */
- dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
- ZR_DEVNAME(zr));
-
- if (zoran_register_i2c(zr) < 0) {
- dprintk(1, KERN_ERR "%s: %s - can't initialize i2c bus\n",
- ZR_DEVNAME(zr), __func__);
- goto zr_free_irq;
- }
-
- zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
- &zr->i2c_adapter, zr->card.i2c_decoder,
- 0, zr->card.addrs_decoder);
-
- if (zr->card.i2c_encoder)
- zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
- &zr->i2c_adapter, zr->card.i2c_encoder,
- 0, zr->card.addrs_encoder);
-
- dprintk(2,
- KERN_INFO "%s: Initializing videocodec bus...\n",
- ZR_DEVNAME(zr));
-
- if (zr->card.video_codec) {
- codec_name = codecid_to_modulename(zr->card.video_codec);
- if (codec_name) {
- result = request_module(codec_name);
- if (result) {
- dprintk(1,
- KERN_ERR
- "%s: failed to load modules %s: %d\n",
- ZR_DEVNAME(zr), codec_name, result);
- }
- }
- }
- if (zr->card.video_vfe) {
- vfe_name = codecid_to_modulename(zr->card.video_vfe);
- if (vfe_name) {
- result = request_module(vfe_name);
- if (result < 0) {
- dprintk(1,
- KERN_ERR
- "%s: failed to load modules %s: %d\n",
- ZR_DEVNAME(zr), vfe_name, result);
- }
- }
- }
-
- /* reset JPEG codec */
- jpeg_codec_sleep(zr, 1);
- jpeg_codec_reset(zr);
- /* video bus enabled */
- /* display codec revision */
- if (zr->card.video_codec != 0) {
- master_codec = zoran_setup_videocodec(zr, zr->card.video_codec);
- if (!master_codec)
- goto zr_unreg_i2c;
- zr->codec = videocodec_attach(master_codec);
- if (!zr->codec) {
- dprintk(1, KERN_ERR "%s: %s - no codec found\n",
- ZR_DEVNAME(zr), __func__);
- goto zr_free_codec;
- }
- if (zr->codec->type != zr->card.video_codec) {
- dprintk(1, KERN_ERR "%s: %s - wrong codec\n",
- ZR_DEVNAME(zr), __func__);
- goto zr_detach_codec;
- }
- }
- if (zr->card.video_vfe != 0) {
- master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe);
- if (!master_vfe)
- goto zr_detach_codec;
- zr->vfe = videocodec_attach(master_vfe);
- if (!zr->vfe) {
- dprintk(1, KERN_ERR "%s: %s - no VFE found\n",
- ZR_DEVNAME(zr), __func__);
- goto zr_free_vfe;
- }
- if (zr->vfe->type != zr->card.video_vfe) {
- dprintk(1, KERN_ERR "%s: %s = wrong VFE\n",
- ZR_DEVNAME(zr), __func__);
- goto zr_detach_vfe;
- }
- }
-
- /* take care of Natoma chipset and a revision 1 zr36057 */
- if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
- zr->jpg_buffers.need_contiguous = 1;
- dprintk(1, KERN_INFO
- "%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
- ZR_DEVNAME(zr));
- }
-
- if (zr36057_init(zr) < 0)
- goto zr_detach_vfe;
-
- zoran_proc_init(zr);
-
- return 0;
-
-zr_detach_vfe:
- videocodec_detach(zr->vfe);
-zr_free_vfe:
- kfree(master_vfe);
-zr_detach_codec:
- videocodec_detach(zr->codec);
-zr_free_codec:
- kfree(master_codec);
-zr_unreg_i2c:
- zoran_unregister_i2c(zr);
-zr_free_irq:
- btwrite(0, ZR36057_SPGPPCR);
- free_irq(zr->pci_dev->irq, zr);
-zr_unmap:
- iounmap(zr->zr36057_mem);
-zr_unreg:
- v4l2_device_unregister(&zr->v4l2_dev);
-zr_free_mem:
- kfree(zr);
-
- return -ENODEV;
-}
-
-static struct pci_driver zoran_driver = {
- .name = "zr36067",
- .id_table = zr36067_pci_tbl,
- .probe = zoran_probe,
- .remove = __devexit_p(zoran_remove),
-};
-
-static int __init zoran_init(void)
-{
- int res;
-
- printk(KERN_INFO "Zoran MJPEG board driver version %s\n",
- ZORAN_VERSION);
-
- /* check the parameters we have been given, adjust if necessary */
- if (v4l_nbufs < 2)
- v4l_nbufs = 2;
- if (v4l_nbufs > VIDEO_MAX_FRAME)
- v4l_nbufs = VIDEO_MAX_FRAME;
- /* The user specfies the in KB, we want them in byte
- * (and page aligned) */
- v4l_bufsize = PAGE_ALIGN(v4l_bufsize * 1024);
- if (v4l_bufsize < 32768)
- v4l_bufsize = 32768;
- /* 2 MB is arbitrary but sufficient for the maximum possible images */
- if (v4l_bufsize > 2048 * 1024)
- v4l_bufsize = 2048 * 1024;
- if (jpg_nbufs < 4)
- jpg_nbufs = 4;
- if (jpg_nbufs > BUZ_MAX_FRAME)
- jpg_nbufs = BUZ_MAX_FRAME;
- jpg_bufsize = PAGE_ALIGN(jpg_bufsize * 1024);
- if (jpg_bufsize < 8192)
- jpg_bufsize = 8192;
- if (jpg_bufsize > (512 * 1024))
- jpg_bufsize = 512 * 1024;
- /* Use parameter for vidmem or try to find a video card */
- if (vidmem) {
- dprintk(1,
- KERN_INFO
- "%s: Using supplied video memory base address @ 0x%lx\n",
- ZORAN_NAME, vidmem);
- }
-
- /* some mainboards might not do PCI-PCI data transfer well */
- if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL|PCIPCI_ALIMAGIK)) {
- dprintk(1,
- KERN_WARNING
- "%s: chipset does not support reliable PCI-PCI DMA\n",
- ZORAN_NAME);
- }
-
- res = pci_register_driver(&zoran_driver);
- if (res) {
- dprintk(1,
- KERN_ERR
- "%s: Unable to register ZR36057 driver\n",
- ZORAN_NAME);
- return res;
- }
-
- return 0;
-}
-
-static void __exit zoran_exit(void)
-{
- pci_unregister_driver(&zoran_driver);
-}
-
-module_init(zoran_init);
-module_exit(zoran_exit);
diff --git a/drivers/media/video/zoran/zoran_card.h b/drivers/media/video/zoran/zoran_card.h
deleted file mode 100644
index 4936fead73e..00000000000
--- a/drivers/media/video/zoran/zoran_card.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Zoran zr36057/zr36067 PCI controller driver, for the
- * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
- * Media Labs LML33/LML33R10.
- *
- * This part handles card-specific data and detection
- *
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- *
- * Currently maintained by:
- * Ronald Bultje <rbultje@ronald.bitfreak.net>
- * Laurent Pinchart <laurent.pinchart@skynet.be>
- * Mailinglist <mjpeg-users@lists.sf.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ZORAN_CARD_H__
-#define __ZORAN_CARD_H__
-
-extern int zr36067_debug;
-
-#define dprintk(num, format, args...) \
- do { \
- if (zr36067_debug >= num) \
- printk(format, ##args); \
- } while (0)
-
-/* Anybody who uses more than four? */
-#define BUZ_MAX 4
-
-extern struct video_device zoran_template;
-
-extern int zoran_check_jpg_settings(struct zoran *zr,
- struct zoran_jpg_settings *settings,
- int try);
-extern void zoran_open_init_params(struct zoran *zr);
-extern void zoran_vdev_release(struct video_device *vdev);
-
-void zr36016_write(struct videocodec *codec, u16 reg, u32 val);
-
-#endif /* __ZORAN_CARD_H__ */
diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/video/zoran/zoran_device.c
deleted file mode 100644
index a4cd504b8ee..00000000000
--- a/drivers/media/video/zoran/zoran_device.c
+++ /dev/null
@@ -1,1640 +0,0 @@
-/*
- * Zoran zr36057/zr36067 PCI controller driver, for the
- * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
- * Media Labs LML33/LML33R10.
- *
- * This part handles device access (PCI/I2C/codec/...)
- *
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- *
- * Currently maintained by:
- * Ronald Bultje <rbultje@ronald.bitfreak.net>
- * Laurent Pinchart <laurent.pinchart@skynet.be>
- * Mailinglist <mjpeg-users@lists.sf.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <linux/spinlock.h>
-#include <linux/sem.h>
-
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-
-#include "videocodec.h"
-#include "zoran.h"
-#include "zoran_device.h"
-#include "zoran_card.h"
-
-#define IRQ_MASK ( ZR36057_ISR_GIRQ0 | \
- ZR36057_ISR_GIRQ1 | \
- ZR36057_ISR_JPEGRepIRQ )
-
-static bool lml33dpath; /* default = 0
- * 1 will use digital path in capture
- * mode instead of analog. It can be
- * used for picture adjustments using
- * tool like xawtv while watching image
- * on TV monitor connected to the output.
- * However, due to absence of 75 Ohm
- * load on Bt819 input, there will be
- * some image imperfections */
-
-module_param(lml33dpath, bool, 0644);
-MODULE_PARM_DESC(lml33dpath,
- "Use digital path capture mode (on LML33 cards)");
-
-static void
-zr36057_init_vfe (struct zoran *zr);
-
-/*
- * General Purpose I/O and Guest bus access
- */
-
-/*
- * This is a bit tricky. When a board lacks a GPIO function, the corresponding
- * GPIO bit number in the card_info structure is set to 0.
- */
-
-void
-GPIO (struct zoran *zr,
- int bit,
- unsigned int value)
-{
- u32 reg;
- u32 mask;
-
- /* Make sure the bit number is legal
- * A bit number of -1 (lacking) gives a mask of 0,
- * making it harmless */
- mask = (1 << (24 + bit)) & 0xff000000;
- reg = btread(ZR36057_GPPGCR1) & ~mask;
- if (value) {
- reg |= mask;
- }
- btwrite(reg, ZR36057_GPPGCR1);
- udelay(1);
-}
-
-/*
- * Wait til post office is no longer busy
- */
-
-int
-post_office_wait (struct zoran *zr)
-{
- u32 por;
-
-// while (((por = btread(ZR36057_POR)) & (ZR36057_POR_POPen | ZR36057_POR_POTime)) == ZR36057_POR_POPen) {
- while ((por = btread(ZR36057_POR)) & ZR36057_POR_POPen) {
- /* wait for something to happen */
- }
- if ((por & ZR36057_POR_POTime) && !zr->card.gws_not_connected) {
- /* In LML33/BUZ \GWS line is not connected, so it has always timeout set */
- dprintk(1, KERN_INFO "%s: pop timeout %08x\n", ZR_DEVNAME(zr),
- por);
- return -1;
- }
-
- return 0;
-}
-
-int
-post_office_write (struct zoran *zr,
- unsigned int guest,
- unsigned int reg,
- unsigned int value)
-{
- u32 por;
-
- por =
- ZR36057_POR_PODir | ZR36057_POR_POTime | ((guest & 7) << 20) |
- ((reg & 7) << 16) | (value & 0xFF);
- btwrite(por, ZR36057_POR);
-
- return post_office_wait(zr);
-}
-
-int
-post_office_read (struct zoran *zr,
- unsigned int guest,
- unsigned int reg)
-{
- u32 por;
-
- por = ZR36057_POR_POTime | ((guest & 7) << 20) | ((reg & 7) << 16);
- btwrite(por, ZR36057_POR);
- if (post_office_wait(zr) < 0) {
- return -1;
- }
-
- return btread(ZR36057_POR) & 0xFF;
-}
-
-/*
- * detect guests
- */
-
-static void
-dump_guests (struct zoran *zr)
-{
- if (zr36067_debug > 2) {
- int i, guest[8];
-
- for (i = 1; i < 8; i++) { // Don't read jpeg codec here
- guest[i] = post_office_read(zr, i, 0);
- }
-
- printk(KERN_INFO "%s: Guests:", ZR_DEVNAME(zr));
-
- for (i = 1; i < 8; i++) {
- printk(" 0x%02x", guest[i]);
- }
- printk("\n");
- }
-}
-
-static inline unsigned long
-get_time (void)
-{
- struct timeval tv;
-
- do_gettimeofday(&tv);
- return (1000000 * tv.tv_sec + tv.tv_usec);
-}
-
-void
-detect_guest_activity (struct zoran *zr)
-{
- int timeout, i, j, res, guest[8], guest0[8], change[8][3];
- unsigned long t0, t1;
-
- dump_guests(zr);
- printk(KERN_INFO "%s: Detecting guests activity, please wait...\n",
- ZR_DEVNAME(zr));
- for (i = 1; i < 8; i++) { // Don't read jpeg codec here
- guest0[i] = guest[i] = post_office_read(zr, i, 0);
- }
-
- timeout = 0;
- j = 0;
- t0 = get_time();
- while (timeout < 10000) {
- udelay(10);
- timeout++;
- for (i = 1; (i < 8) && (j < 8); i++) {
- res = post_office_read(zr, i, 0);
- if (res != guest[i]) {
- t1 = get_time();
- change[j][0] = (t1 - t0);
- t0 = t1;
- change[j][1] = i;
- change[j][2] = res;
- j++;
- guest[i] = res;
- }
- }
- if (j >= 8)
- break;
- }
- printk(KERN_INFO "%s: Guests:", ZR_DEVNAME(zr));
-
- for (i = 1; i < 8; i++) {
- printk(" 0x%02x", guest0[i]);
- }
- printk("\n");
- if (j == 0) {
- printk(KERN_INFO "%s: No activity detected.\n", ZR_DEVNAME(zr));
- return;
- }
- for (i = 0; i < j; i++) {
- printk(KERN_INFO "%s: %6d: %d => 0x%02x\n", ZR_DEVNAME(zr),
- change[i][0], change[i][1], change[i][2]);
- }
-}
-
-/*
- * JPEG Codec access
- */
-
-void
-jpeg_codec_sleep (struct zoran *zr,
- int sleep)
-{
- GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_SLEEP], !sleep);
- if (!sleep) {
- dprintk(3,
- KERN_DEBUG
- "%s: jpeg_codec_sleep() - wake GPIO=0x%08x\n",
- ZR_DEVNAME(zr), btread(ZR36057_GPPGCR1));
- udelay(500);
- } else {
- dprintk(3,
- KERN_DEBUG
- "%s: jpeg_codec_sleep() - sleep GPIO=0x%08x\n",
- ZR_DEVNAME(zr), btread(ZR36057_GPPGCR1));
- udelay(2);
- }
-}
-
-int
-jpeg_codec_reset (struct zoran *zr)
-{
- /* Take the codec out of sleep */
- jpeg_codec_sleep(zr, 0);
-
- if (zr->card.gpcs[GPCS_JPEG_RESET] != 0xff) {
- post_office_write(zr, zr->card.gpcs[GPCS_JPEG_RESET], 0,
- 0);
- udelay(2);
- } else {
- GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 0);
- udelay(2);
- GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 1);
- udelay(2);
- }
-
- return 0;
-}
-
-/*
- * Set the registers for the size we have specified. Don't bother
- * trying to understand this without the ZR36057 manual in front of
- * you [AC].
- *
- * PS: The manual is free for download in .pdf format from
- * www.zoran.com - nicely done those folks.
- */
-
-static void
-zr36057_adjust_vfe (struct zoran *zr,
- enum zoran_codec_mode mode)
-{
- u32 reg;
-
- switch (mode) {
- case BUZ_MODE_MOTION_DECOMPRESS:
- btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
- reg = btread(ZR36057_VFEHCR);
- if ((reg & (1 << 10)) && zr->card.type != LML33R10) {
- reg += ((1 << 10) | 1);
- }
- btwrite(reg, ZR36057_VFEHCR);
- break;
- case BUZ_MODE_MOTION_COMPRESS:
- case BUZ_MODE_IDLE:
- default:
- if ((zr->norm & V4L2_STD_NTSC) ||
- (zr->card.type == LML33R10 &&
- (zr->norm & V4L2_STD_PAL)))
- btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
- else
- btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
- reg = btread(ZR36057_VFEHCR);
- if (!(reg & (1 << 10)) && zr->card.type != LML33R10) {
- reg -= ((1 << 10) | 1);
- }
- btwrite(reg, ZR36057_VFEHCR);
- break;
- }
-}
-
-/*
- * set geometry
- */
-
-static void
-zr36057_set_vfe (struct zoran *zr,
- int video_width,
- int video_height,
- const struct zoran_format *format)
-{
- struct tvnorm *tvn;
- unsigned HStart, HEnd, VStart, VEnd;
- unsigned DispMode;
- unsigned VidWinWid, VidWinHt;
- unsigned hcrop1, hcrop2, vcrop1, vcrop2;
- unsigned Wa, We, Ha, He;
- unsigned X, Y, HorDcm, VerDcm;
- u32 reg;
- unsigned mask_line_size;
-
- tvn = zr->timing;
-
- Wa = tvn->Wa;
- Ha = tvn->Ha;
-
- dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n",
- ZR_DEVNAME(zr), video_width, video_height);
-
- if (video_width < BUZ_MIN_WIDTH ||
- video_height < BUZ_MIN_HEIGHT ||
- video_width > Wa || video_height > Ha) {
- dprintk(1, KERN_ERR "%s: set_vfe: w=%d h=%d not valid\n",
- ZR_DEVNAME(zr), video_width, video_height);
- return;
- }
-
- /**** zr36057 ****/
-
- /* horizontal */
- VidWinWid = video_width;
- X = DIV_ROUND_UP(VidWinWid * 64, tvn->Wa);
- We = (VidWinWid * 64) / X;
- HorDcm = 64 - X;
- hcrop1 = 2 * ((tvn->Wa - We) / 4);
- hcrop2 = tvn->Wa - We - hcrop1;
- HStart = tvn->HStart ? tvn->HStart : 1;
- /* (Ronald) Original comment:
- * "| 1 Doesn't have any effect, tested on both a DC10 and a DC10+"
- * this is false. It inverses chroma values on the LML33R10 (so Cr
- * suddenly is shown as Cb and reverse, really cool effect if you
- * want to see blue faces, not useful otherwise). So don't use |1.
- * However, the DC10 has '0' as HStart, but does need |1, so we
- * use a dirty check...
- */
- HEnd = HStart + tvn->Wa - 1;
- HStart += hcrop1;
- HEnd -= hcrop2;
- reg = ((HStart & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HStart)
- | ((HEnd & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HEnd);
- if (zr->card.vfe_pol.hsync_pol)
- reg |= ZR36057_VFEHCR_HSPol;
- btwrite(reg, ZR36057_VFEHCR);
-
- /* Vertical */
- DispMode = !(video_height > BUZ_MAX_HEIGHT / 2);
- VidWinHt = DispMode ? video_height : video_height / 2;
- Y = DIV_ROUND_UP(VidWinHt * 64 * 2, tvn->Ha);
- He = (VidWinHt * 64) / Y;
- VerDcm = 64 - Y;
- vcrop1 = (tvn->Ha / 2 - He) / 2;
- vcrop2 = tvn->Ha / 2 - He - vcrop1;
- VStart = tvn->VStart;
- VEnd = VStart + tvn->Ha / 2; // - 1; FIXME SnapShot times out with -1 in 768*576 on the DC10 - LP
- VStart += vcrop1;
- VEnd -= vcrop2;
- reg = ((VStart & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VStart)
- | ((VEnd & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VEnd);
- if (zr->card.vfe_pol.vsync_pol)
- reg |= ZR36057_VFEVCR_VSPol;
- btwrite(reg, ZR36057_VFEVCR);
-
- /* scaler and pixel format */
- reg = 0;
- reg |= (HorDcm << ZR36057_VFESPFR_HorDcm);
- reg |= (VerDcm << ZR36057_VFESPFR_VerDcm);
- reg |= (DispMode << ZR36057_VFESPFR_DispMode);
- /* RJ: I don't know, why the following has to be the opposite
- * of the corresponding ZR36060 setting, but only this way
- * we get the correct colors when uncompressing to the screen */
- //reg |= ZR36057_VFESPFR_VCLKPol; /**/
- /* RJ: Don't know if that is needed for NTSC also */
- if (!(zr->norm & V4L2_STD_NTSC))
- reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang
- reg |= ZR36057_VFESPFR_TopField;
- if (HorDcm >= 48) {
- reg |= 3 << ZR36057_VFESPFR_HFilter; /* 5 tap filter */
- } else if (HorDcm >= 32) {
- reg |= 2 << ZR36057_VFESPFR_HFilter; /* 4 tap filter */
- } else if (HorDcm >= 16) {
- reg |= 1 << ZR36057_VFESPFR_HFilter; /* 3 tap filter */
- }
- reg |= format->vfespfr;
- btwrite(reg, ZR36057_VFESPFR);
-
- /* display configuration */
- reg = (16 << ZR36057_VDCR_MinPix)
- | (VidWinHt << ZR36057_VDCR_VidWinHt)
- | (VidWinWid << ZR36057_VDCR_VidWinWid);
- if (pci_pci_problems & PCIPCI_TRITON)
- // || zr->revision < 1) // Revision 1 has also Triton support
- reg &= ~ZR36057_VDCR_Triton;
- else
- reg |= ZR36057_VDCR_Triton;
- btwrite(reg, ZR36057_VDCR);
-
- /* (Ronald) don't write this if overlay_mask = NULL */
- if (zr->overlay_mask) {
- /* Write overlay clipping mask data, but don't enable overlay clipping */
- /* RJ: since this makes only sense on the screen, we use
- * zr->overlay_settings.width instead of video_width */
-
- mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;
- reg = virt_to_bus(zr->overlay_mask);
- btwrite(reg, ZR36057_MMTR);
- reg = virt_to_bus(zr->overlay_mask + mask_line_size);
- btwrite(reg, ZR36057_MMBR);
- reg =
- mask_line_size - (zr->overlay_settings.width +
- 31) / 32;
- if (DispMode == 0)
- reg += mask_line_size;
- reg <<= ZR36057_OCR_MaskStride;
- btwrite(reg, ZR36057_OCR);
- }
-
- zr36057_adjust_vfe(zr, zr->codec_mode);
-}
-
-/*
- * Switch overlay on or off
- */
-
-void
-zr36057_overlay (struct zoran *zr,
- int on)
-{
- u32 reg;
-
- if (on) {
- /* do the necessary settings ... */
- btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); /* switch it off first */
-
- zr36057_set_vfe(zr,
- zr->overlay_settings.width,
- zr->overlay_settings.height,
- zr->overlay_settings.format);
-
- /* Start and length of each line MUST be 4-byte aligned.
- * This should be already checked before the call to this routine.
- * All error messages are internal driver checking only! */
-
- /* video display top and bottom registers */
- reg = (long) zr->vbuf_base +
- zr->overlay_settings.x *
- ((zr->overlay_settings.format->depth + 7) / 8) +
- zr->overlay_settings.y *
- zr->vbuf_bytesperline;
- btwrite(reg, ZR36057_VDTR);
- if (reg & 3)
- dprintk(1,
- KERN_ERR
- "%s: zr36057_overlay() - video_address not aligned\n",
- ZR_DEVNAME(zr));
- if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2)
- reg += zr->vbuf_bytesperline;
- btwrite(reg, ZR36057_VDBR);
-
- /* video stride, status, and frame grab register */
- reg = zr->vbuf_bytesperline -
- zr->overlay_settings.width *
- ((zr->overlay_settings.format->depth + 7) / 8);
- if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2)
- reg += zr->vbuf_bytesperline;
- if (reg & 3)
- dprintk(1,
- KERN_ERR
- "%s: zr36057_overlay() - video_stride not aligned\n",
- ZR_DEVNAME(zr));
- reg = (reg << ZR36057_VSSFGR_DispStride);
- reg |= ZR36057_VSSFGR_VidOvf; /* clear overflow status */
- btwrite(reg, ZR36057_VSSFGR);
-
- /* Set overlay clipping */
- if (zr->overlay_settings.clipcount > 0)
- btor(ZR36057_OCR_OvlEnable, ZR36057_OCR);
-
- /* ... and switch it on */
- btor(ZR36057_VDCR_VidEn, ZR36057_VDCR);
- } else {
- /* Switch it off */
- btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);
- }
-}
-
-/*
- * The overlay mask has one bit for each pixel on a scan line,
- * and the maximum window size is BUZ_MAX_WIDTH * BUZ_MAX_HEIGHT pixels.
- */
-
-void write_overlay_mask(struct zoran_fh *fh, struct v4l2_clip *vp, int count)
-{
- struct zoran *zr = fh->zr;
- unsigned mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;
- u32 *mask;
- int x, y, width, height;
- unsigned i, j, k;
-
- /* fill mask with one bits */
- memset(fh->overlay_mask, ~0, mask_line_size * 4 * BUZ_MAX_HEIGHT);
-
- for (i = 0; i < count; ++i) {
- /* pick up local copy of clip */
- x = vp[i].c.left;
- y = vp[i].c.top;
- width = vp[i].c.width;
- height = vp[i].c.height;
-
- /* trim clips that extend beyond the window */
- if (x < 0) {
- width += x;
- x = 0;
- }
- if (y < 0) {
- height += y;
- y = 0;
- }
- if (x + width > fh->overlay_settings.width) {
- width = fh->overlay_settings.width - x;
- }
- if (y + height > fh->overlay_settings.height) {
- height = fh->overlay_settings.height - y;
- }
-
- /* ignore degenerate clips */
- if (height <= 0) {
- continue;
- }
- if (width <= 0) {
- continue;
- }
-
- /* apply clip for each scan line */
- for (j = 0; j < height; ++j) {
- /* reset bit for each pixel */
- /* this can be optimized later if need be */
- mask = fh->overlay_mask + (y + j) * mask_line_size;
- for (k = 0; k < width; ++k) {
- mask[(x + k) / 32] &=
- ~((u32) 1 << (x + k) % 32);
- }
- }
- }
-}
-
-/* Enable/Disable uncompressed memory grabbing of the 36057 */
-
-void
-zr36057_set_memgrab (struct zoran *zr,
- int mode)
-{
- if (mode) {
- /* We only check SnapShot and not FrameGrab here. SnapShot==1
- * means a capture is already in progress, but FrameGrab==1
- * doesn't necessary mean that. It's more correct to say a 1
- * to 0 transition indicates a capture completed. If a
- * capture is pending when capturing is tuned off, FrameGrab
- * will be stuck at 1 until capturing is turned back on.
- */
- if (btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot)
- dprintk(1,
- KERN_WARNING
- "%s: zr36057_set_memgrab(1) with SnapShot on!?\n",
- ZR_DEVNAME(zr));
-
- /* switch on VSync interrupts */
- btwrite(IRQ_MASK, ZR36057_ISR); // Clear Interrupts
- btor(zr->card.vsync_int, ZR36057_ICR); // SW
-
- /* enable SnapShot */
- btor(ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR);
-
- /* Set zr36057 video front end and enable video */
- zr36057_set_vfe(zr, zr->v4l_settings.width,
- zr->v4l_settings.height,
- zr->v4l_settings.format);
-
- zr->v4l_memgrab_active = 1;
- } else {
- /* switch off VSync interrupts */
- btand(~zr->card.vsync_int, ZR36057_ICR); // SW
-
- zr->v4l_memgrab_active = 0;
- zr->v4l_grab_frame = NO_GRAB_ACTIVE;
-
- /* reenable grabbing to screen if it was running */
- if (zr->v4l_overlay_active) {
- zr36057_overlay(zr, 1);
- } else {
- btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);
- btand(~ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR);
- }
- }
-}
-
-int
-wait_grab_pending (struct zoran *zr)
-{
- unsigned long flags;
-
- /* wait until all pending grabs are finished */
-
- if (!zr->v4l_memgrab_active)
- return 0;
-
- wait_event_interruptible(zr->v4l_capq,
- (zr->v4l_pend_tail == zr->v4l_pend_head));
- if (signal_pending(current))
- return -ERESTARTSYS;
-
- spin_lock_irqsave(&zr->spinlock, flags);
- zr36057_set_memgrab(zr, 0);
- spin_unlock_irqrestore(&zr->spinlock, flags);
-
- return 0;
-}
-
-/*****************************************************************************
- * *
- * Set up the Buz-specific MJPEG part *
- * *
- *****************************************************************************/
-
-static inline void
-set_frame (struct zoran *zr,
- int val)
-{
- GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_FRAME], val);
-}
-
-static void
-set_videobus_dir (struct zoran *zr,
- int val)
-{
- switch (zr->card.type) {
- case LML33:
- case LML33R10:
- if (lml33dpath == 0)
- GPIO(zr, 5, val);
- else
- GPIO(zr, 5, 1);
- break;
- default:
- GPIO(zr, zr->card.gpio[ZR_GPIO_VID_DIR],
- zr->card.gpio_pol[ZR_GPIO_VID_DIR] ? !val : val);
- break;
- }
-}
-
-static void
-init_jpeg_queue (struct zoran *zr)
-{
- int i;
-
- /* re-initialize DMA ring stuff */
- zr->jpg_que_head = 0;
- zr->jpg_dma_head = 0;
- zr->jpg_dma_tail = 0;
- zr->jpg_que_tail = 0;
- zr->jpg_seq_num = 0;
- zr->JPEG_error = 0;
- zr->num_errors = 0;
- zr->jpg_err_seq = 0;
- zr->jpg_err_shift = 0;
- zr->jpg_queued_num = 0;
- for (i = 0; i < zr->jpg_buffers.num_buffers; i++) {
- zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
- }
- for (i = 0; i < BUZ_NUM_STAT_COM; i++) {
- zr->stat_com[i] = cpu_to_le32(1); /* mark as unavailable to zr36057 */
- }
-}
-
-static void
-zr36057_set_jpg (struct zoran *zr,
- enum zoran_codec_mode mode)
-{
- struct tvnorm *tvn;
- u32 reg;
-
- tvn = zr->timing;
-
- /* assert P_Reset, disable code transfer, deassert Active */
- btwrite(0, ZR36057_JPC);
-
- /* MJPEG compression mode */
- switch (mode) {
-
- case BUZ_MODE_MOTION_COMPRESS:
- default:
- reg = ZR36057_JMC_MJPGCmpMode;
- break;
-
- case BUZ_MODE_MOTION_DECOMPRESS:
- reg = ZR36057_JMC_MJPGExpMode;
- reg |= ZR36057_JMC_SyncMstr;
- /* RJ: The following is experimental - improves the output to screen */
- //if(zr->jpg_settings.VFIFO_FB) reg |= ZR36057_JMC_VFIFO_FB; // No, it doesn't. SM
- break;
-
- case BUZ_MODE_STILL_COMPRESS:
- reg = ZR36057_JMC_JPGCmpMode;
- break;
-
- case BUZ_MODE_STILL_DECOMPRESS:
- reg = ZR36057_JMC_JPGExpMode;
- break;
-
- }
- reg |= ZR36057_JMC_JPG;
- if (zr->jpg_settings.field_per_buff == 1)
- reg |= ZR36057_JMC_Fld_per_buff;
- btwrite(reg, ZR36057_JMC);
-
- /* vertical */
- btor(ZR36057_VFEVCR_VSPol, ZR36057_VFEVCR);
- reg = (6 << ZR36057_VSP_VsyncSize) |
- (tvn->Ht << ZR36057_VSP_FrmTot);
- btwrite(reg, ZR36057_VSP);
- reg = ((zr->jpg_settings.img_y + tvn->VStart) << ZR36057_FVAP_NAY) |
- (zr->jpg_settings.img_height << ZR36057_FVAP_PAY);
- btwrite(reg, ZR36057_FVAP);
-
- /* horizontal */
- if (zr->card.vfe_pol.hsync_pol)
- btor(ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR);
- else
- btand(~ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR);
- reg = ((tvn->HSyncStart) << ZR36057_HSP_HsyncStart) |
- (tvn->Wt << ZR36057_HSP_LineTot);
- btwrite(reg, ZR36057_HSP);
- reg = ((zr->jpg_settings.img_x +
- tvn->HStart + 4) << ZR36057_FHAP_NAX) |
- (zr->jpg_settings.img_width << ZR36057_FHAP_PAX);
- btwrite(reg, ZR36057_FHAP);
-
- /* field process parameters */
- if (zr->jpg_settings.odd_even)
- reg = ZR36057_FPP_Odd_Even;
- else
- reg = 0;
-
- btwrite(reg, ZR36057_FPP);
-
- /* Set proper VCLK Polarity, else colors will be wrong during playback */
- //btor(ZR36057_VFESPFR_VCLKPol, ZR36057_VFESPFR);
-
- /* code base address */
- reg = virt_to_bus(zr->stat_com);
- btwrite(reg, ZR36057_JCBA);
-
- /* FIFO threshold (FIFO is 160. double words) */
- /* NOTE: decimal values here */
- switch (mode) {
-
- case BUZ_MODE_STILL_COMPRESS:
- case BUZ_MODE_MOTION_COMPRESS:
- if (zr->card.type != BUZ)
- reg = 140;
- else
- reg = 60;
- break;
-
- case BUZ_MODE_STILL_DECOMPRESS:
- case BUZ_MODE_MOTION_DECOMPRESS:
- reg = 20;
- break;
-
- default:
- reg = 80;
- break;
-
- }
- btwrite(reg, ZR36057_JCFT);
- zr36057_adjust_vfe(zr, mode);
-
-}
-
-void
-print_interrupts (struct zoran *zr)
-{
- int res, noerr = 0;
-
- printk(KERN_INFO "%s: interrupts received:", ZR_DEVNAME(zr));
- if ((res = zr->field_counter) < -1 || res > 1) {
- printk(" FD:%d", res);
- }
- if ((res = zr->intr_counter_GIRQ1) != 0) {
- printk(" GIRQ1:%d", res);
- noerr++;
- }
- if ((res = zr->intr_counter_GIRQ0) != 0) {
- printk(" GIRQ0:%d", res);
- noerr++;
- }
- if ((res = zr->intr_counter_CodRepIRQ) != 0) {
- printk(" CodRepIRQ:%d", res);
- noerr++;
- }
- if ((res = zr->intr_counter_JPEGRepIRQ) != 0) {
- printk(" JPEGRepIRQ:%d", res);
- noerr++;
- }
- if (zr->JPEG_max_missed) {
- printk(" JPEG delays: max=%d min=%d", zr->JPEG_max_missed,
- zr->JPEG_min_missed);
- }
- if (zr->END_event_missed) {
- printk(" ENDs missed: %d", zr->END_event_missed);
- }
- //if (zr->jpg_queued_num) {
- printk(" queue_state=%ld/%ld/%ld/%ld", zr->jpg_que_tail,
- zr->jpg_dma_tail, zr->jpg_dma_head, zr->jpg_que_head);
- //}
- if (!noerr) {
- printk(": no interrupts detected.");
- }
- printk("\n");
-}
-
-void
-clear_interrupt_counters (struct zoran *zr)
-{
- zr->intr_counter_GIRQ1 = 0;
- zr->intr_counter_GIRQ0 = 0;
- zr->intr_counter_CodRepIRQ = 0;
- zr->intr_counter_JPEGRepIRQ = 0;
- zr->field_counter = 0;
- zr->IRQ1_in = 0;
- zr->IRQ1_out = 0;
- zr->JPEG_in = 0;
- zr->JPEG_out = 0;
- zr->JPEG_0 = 0;
- zr->JPEG_1 = 0;
- zr->END_event_missed = 0;
- zr->JPEG_missed = 0;
- zr->JPEG_max_missed = 0;
- zr->JPEG_min_missed = 0x7fffffff;
-}
-
-static u32
-count_reset_interrupt (struct zoran *zr)
-{
- u32 isr;
-
- if ((isr = btread(ZR36057_ISR) & 0x78000000)) {
- if (isr & ZR36057_ISR_GIRQ1) {
- btwrite(ZR36057_ISR_GIRQ1, ZR36057_ISR);
- zr->intr_counter_GIRQ1++;
- }
- if (isr & ZR36057_ISR_GIRQ0) {
- btwrite(ZR36057_ISR_GIRQ0, ZR36057_ISR);
- zr->intr_counter_GIRQ0++;
- }
- if (isr & ZR36057_ISR_CodRepIRQ) {
- btwrite(ZR36057_ISR_CodRepIRQ, ZR36057_ISR);
- zr->intr_counter_CodRepIRQ++;
- }
- if (isr & ZR36057_ISR_JPEGRepIRQ) {
- btwrite(ZR36057_ISR_JPEGRepIRQ, ZR36057_ISR);
- zr->intr_counter_JPEGRepIRQ++;
- }
- }
- return isr;
-}
-
-void
-jpeg_start (struct zoran *zr)
-{
- int reg;
-
- zr->frame_num = 0;
-
- /* deassert P_reset, disable code transfer, deassert Active */
- btwrite(ZR36057_JPC_P_Reset, ZR36057_JPC);
- /* stop flushing the internal code buffer */
- btand(~ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
- /* enable code transfer */
- btor(ZR36057_JPC_CodTrnsEn, ZR36057_JPC);
-
- /* clear IRQs */
- btwrite(IRQ_MASK, ZR36057_ISR);
- /* enable the JPEG IRQs */
- btwrite(zr->card.jpeg_int |
- ZR36057_ICR_JPEGRepIRQ |
- ZR36057_ICR_IntPinEn,
- ZR36057_ICR);
-
- set_frame(zr, 0); // \FRAME
-
- /* set the JPEG codec guest ID */
- reg = (zr->card.gpcs[1] << ZR36057_JCGI_JPEGuestID) |
- (0 << ZR36057_JCGI_JPEGuestReg);
- btwrite(reg, ZR36057_JCGI);
-
- if (zr->card.video_vfe == CODEC_TYPE_ZR36016 &&
- zr->card.video_codec == CODEC_TYPE_ZR36050) {
- /* Enable processing on the ZR36016 */
- if (zr->vfe)
- zr36016_write(zr->vfe, 0, 1);
-
- /* load the address of the GO register in the ZR36050 latch */
- post_office_write(zr, 0, 0, 0);
- }
-
- /* assert Active */
- btor(ZR36057_JPC_Active, ZR36057_JPC);
-
- /* enable the Go generation */
- btor(ZR36057_JMC_Go_en, ZR36057_JMC);
- udelay(30);
-
- set_frame(zr, 1); // /FRAME
-
- dprintk(3, KERN_DEBUG "%s: jpeg_start\n", ZR_DEVNAME(zr));
-}
-
-void
-zr36057_enable_jpg (struct zoran *zr,
- enum zoran_codec_mode mode)
-{
- struct vfe_settings cap;
- int field_size =
- zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff;
-
- zr->codec_mode = mode;
-
- cap.x = zr->jpg_settings.img_x;
- cap.y = zr->jpg_settings.img_y;
- cap.width = zr->jpg_settings.img_width;
- cap.height = zr->jpg_settings.img_height;
- cap.decimation =
- zr->jpg_settings.HorDcm | (zr->jpg_settings.VerDcm << 8);
- cap.quality = zr->jpg_settings.jpg_comp.quality;
-
- switch (mode) {
-
- case BUZ_MODE_MOTION_COMPRESS: {
- struct jpeg_app_marker app;
- struct jpeg_com_marker com;
-
- /* In motion compress mode, the decoder output must be enabled, and
- * the video bus direction set to input.
- */
- set_videobus_dir(zr, 0);
- decoder_call(zr, video, s_stream, 1);
- encoder_call(zr, video, s_routing, 0, 0, 0);
-
- /* Take the JPEG codec and the VFE out of sleep */
- jpeg_codec_sleep(zr, 0);
-
- /* set JPEG app/com marker */
- app.appn = zr->jpg_settings.jpg_comp.APPn;
- app.len = zr->jpg_settings.jpg_comp.APP_len;
- memcpy(app.data, zr->jpg_settings.jpg_comp.APP_data, 60);
- zr->codec->control(zr->codec, CODEC_S_JPEG_APP_DATA,
- sizeof(struct jpeg_app_marker), &app);
-
- com.len = zr->jpg_settings.jpg_comp.COM_len;
- memcpy(com.data, zr->jpg_settings.jpg_comp.COM_data, 60);
- zr->codec->control(zr->codec, CODEC_S_JPEG_COM_DATA,
- sizeof(struct jpeg_com_marker), &com);
-
- /* Setup the JPEG codec */
- zr->codec->control(zr->codec, CODEC_S_JPEG_TDS_BYTE,
- sizeof(int), &field_size);
- zr->codec->set_video(zr->codec, zr->timing, &cap,
- &zr->card.vfe_pol);
- zr->codec->set_mode(zr->codec, CODEC_DO_COMPRESSION);
-
- /* Setup the VFE */
- if (zr->vfe) {
- zr->vfe->control(zr->vfe, CODEC_S_JPEG_TDS_BYTE,
- sizeof(int), &field_size);
- zr->vfe->set_video(zr->vfe, zr->timing, &cap,
- &zr->card.vfe_pol);
- zr->vfe->set_mode(zr->vfe, CODEC_DO_COMPRESSION);
- }
-
- init_jpeg_queue(zr);
- zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO
-
- clear_interrupt_counters(zr);
- dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_COMPRESS)\n",
- ZR_DEVNAME(zr));
- break;
- }
-
- case BUZ_MODE_MOTION_DECOMPRESS:
- /* In motion decompression mode, the decoder output must be disabled, and
- * the video bus direction set to output.
- */
- decoder_call(zr, video, s_stream, 0);
- set_videobus_dir(zr, 1);
- encoder_call(zr, video, s_routing, 1, 0, 0);
-
- /* Take the JPEG codec and the VFE out of sleep */
- jpeg_codec_sleep(zr, 0);
- /* Setup the VFE */
- if (zr->vfe) {
- zr->vfe->set_video(zr->vfe, zr->timing, &cap,
- &zr->card.vfe_pol);
- zr->vfe->set_mode(zr->vfe, CODEC_DO_EXPANSION);
- }
- /* Setup the JPEG codec */
- zr->codec->set_video(zr->codec, zr->timing, &cap,
- &zr->card.vfe_pol);
- zr->codec->set_mode(zr->codec, CODEC_DO_EXPANSION);
-
- init_jpeg_queue(zr);
- zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO
-
- clear_interrupt_counters(zr);
- dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_DECOMPRESS)\n",
- ZR_DEVNAME(zr));
- break;
-
- case BUZ_MODE_IDLE:
- default:
- /* shut down processing */
- btand(~(zr->card.jpeg_int | ZR36057_ICR_JPEGRepIRQ),
- ZR36057_ICR);
- btwrite(zr->card.jpeg_int | ZR36057_ICR_JPEGRepIRQ,
- ZR36057_ISR);
- btand(~ZR36057_JMC_Go_en, ZR36057_JMC); // \Go_en
-
- msleep(50);
-
- set_videobus_dir(zr, 0);
- set_frame(zr, 1); // /FRAME
- btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); // /CFlush
- btwrite(0, ZR36057_JPC); // \P_Reset,\CodTrnsEn,\Active
- btand(~ZR36057_JMC_VFIFO_FB, ZR36057_JMC);
- btand(~ZR36057_JMC_SyncMstr, ZR36057_JMC);
- jpeg_codec_reset(zr);
- jpeg_codec_sleep(zr, 1);
- zr36057_adjust_vfe(zr, mode);
-
- decoder_call(zr, video, s_stream, 1);
- encoder_call(zr, video, s_routing, 0, 0, 0);
-
- dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr));
- break;
-
- }
-}
-
-/* when this is called the spinlock must be held */
-void
-zoran_feed_stat_com (struct zoran *zr)
-{
- /* move frames from pending queue to DMA */
-
- int frame, i, max_stat_com;
-
- max_stat_com =
- (zr->jpg_settings.TmpDcm ==
- 1) ? BUZ_NUM_STAT_COM : (BUZ_NUM_STAT_COM >> 1);
-
- while ((zr->jpg_dma_head - zr->jpg_dma_tail) < max_stat_com &&
- zr->jpg_dma_head < zr->jpg_que_head) {
-
- frame = zr->jpg_pend[zr->jpg_dma_head & BUZ_MASK_FRAME];
- if (zr->jpg_settings.TmpDcm == 1) {
- /* fill 1 stat_com entry */
- i = (zr->jpg_dma_head -
- zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
- if (!(zr->stat_com[i] & cpu_to_le32(1)))
- break;
- zr->stat_com[i] =
- cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
- } else {
- /* fill 2 stat_com entries */
- i = ((zr->jpg_dma_head -
- zr->jpg_err_shift) & 1) * 2;
- if (!(zr->stat_com[i] & cpu_to_le32(1)))
- break;
- zr->stat_com[i] =
- cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
- zr->stat_com[i + 1] =
- cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
- }
- zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA;
- zr->jpg_dma_head++;
-
- }
- if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS)
- zr->jpg_queued_num++;
-}
-
-/* when this is called the spinlock must be held */
-static void
-zoran_reap_stat_com (struct zoran *zr)
-{
- /* move frames from DMA queue to done queue */
-
- int i;
- u32 stat_com;
- unsigned int seq;
- unsigned int dif;
- struct zoran_buffer *buffer;
- int frame;
-
- /* In motion decompress we don't have a hardware frame counter,
- * we just count the interrupts here */
-
- if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
- zr->jpg_seq_num++;
- }
- while (zr->jpg_dma_tail < zr->jpg_dma_head) {
- if (zr->jpg_settings.TmpDcm == 1)
- i = (zr->jpg_dma_tail -
- zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
- else
- i = ((zr->jpg_dma_tail -
- zr->jpg_err_shift) & 1) * 2 + 1;
-
- stat_com = le32_to_cpu(zr->stat_com[i]);
-
- if ((stat_com & 1) == 0) {
- return;
- }
- frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
- buffer = &zr->jpg_buffers.buffer[frame];
- do_gettimeofday(&buffer->bs.timestamp);
-
- if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
- buffer->bs.length = (stat_com & 0x7fffff) >> 1;
-
- /* update sequence number with the help of the counter in stat_com */
-
- seq = ((stat_com >> 24) + zr->jpg_err_seq) & 0xff;
- dif = (seq - zr->jpg_seq_num) & 0xff;
- zr->jpg_seq_num += dif;
- } else {
- buffer->bs.length = 0;
- }
- buffer->bs.seq =
- zr->jpg_settings.TmpDcm ==
- 2 ? (zr->jpg_seq_num >> 1) : zr->jpg_seq_num;
- buffer->state = BUZ_STATE_DONE;
-
- zr->jpg_dma_tail++;
- }
-}
-
-static void zoran_restart(struct zoran *zr)
-{
- /* Now the stat_comm buffer is ready for restart */
- unsigned int status = 0;
- int mode;
-
- if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
- decoder_call(zr, video, g_input_status, &status);
- mode = CODEC_DO_COMPRESSION;
- } else {
- status = V4L2_IN_ST_NO_SIGNAL;
- mode = CODEC_DO_EXPANSION;
- }
- if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
- !(status & V4L2_IN_ST_NO_SIGNAL)) {
- /********** RESTART code *************/
- jpeg_codec_reset(zr);
- zr->codec->set_mode(zr->codec, mode);
- zr36057_set_jpg(zr, zr->codec_mode);
- jpeg_start(zr);
-
- if (zr->num_errors <= 8)
- dprintk(2, KERN_INFO "%s: Restart\n",
- ZR_DEVNAME(zr));
-
- zr->JPEG_missed = 0;
- zr->JPEG_error = 2;
- /********** End RESTART code ***********/
- }
-}
-
-static void
-error_handler (struct zoran *zr,
- u32 astat,
- u32 stat)
-{
- int i;
-
- /* This is JPEG error handling part */
- if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS &&
- zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS) {
- return;
- }
-
- if ((stat & 1) == 0 &&
- zr->codec_mode == BUZ_MODE_MOTION_COMPRESS &&
- zr->jpg_dma_tail - zr->jpg_que_tail >= zr->jpg_buffers.num_buffers) {
- /* No free buffers... */
- zoran_reap_stat_com(zr);
- zoran_feed_stat_com(zr);
- wake_up_interruptible(&zr->jpg_capq);
- zr->JPEG_missed = 0;
- return;
- }
-
- if (zr->JPEG_error == 1) {
- zoran_restart(zr);
- return;
- }
-
- /*
- * First entry: error just happened during normal operation
- *
- * In BUZ_MODE_MOTION_COMPRESS:
- *
- * Possible glitch in TV signal. In this case we should
- * stop the codec and wait for good quality signal before
- * restarting it to avoid further problems
- *
- * In BUZ_MODE_MOTION_DECOMPRESS:
- *
- * Bad JPEG frame: we have to mark it as processed (codec crashed
- * and was not able to do it itself), and to remove it from queue.
- */
- btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
- udelay(1);
- stat = stat | (post_office_read(zr, 7, 0) & 3) << 8;
- btwrite(0, ZR36057_JPC);
- btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
- jpeg_codec_reset(zr);
- jpeg_codec_sleep(zr, 1);
- zr->JPEG_error = 1;
- zr->num_errors++;
-
- /* Report error */
- if (zr36067_debug > 1 && zr->num_errors <= 8) {
- long frame;
- int j;
-
- frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
- printk(KERN_ERR
- "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ",
- ZR_DEVNAME(zr), stat, zr->last_isr,
- zr->jpg_que_tail, zr->jpg_dma_tail,
- zr->jpg_dma_head, zr->jpg_que_head,
- zr->jpg_seq_num, frame);
- printk(KERN_INFO "stat_com frames:");
- for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
- for (i = 0; i < zr->jpg_buffers.num_buffers; i++) {
- if (le32_to_cpu(zr->stat_com[j]) == zr->jpg_buffers.buffer[i].jpg.frag_tab_bus)
- printk(KERN_CONT "% d->%d", j, i);
- }
- }
- printk(KERN_CONT "\n");
- }
- /* Find an entry in stat_com and rotate contents */
- if (zr->jpg_settings.TmpDcm == 1)
- i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
- else
- i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2;
- if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
- /* Mimic zr36067 operation */
- zr->stat_com[i] |= cpu_to_le32(1);
- if (zr->jpg_settings.TmpDcm != 1)
- zr->stat_com[i + 1] |= cpu_to_le32(1);
- /* Refill */
- zoran_reap_stat_com(zr);
- zoran_feed_stat_com(zr);
- wake_up_interruptible(&zr->jpg_capq);
- /* Find an entry in stat_com again after refill */
- if (zr->jpg_settings.TmpDcm == 1)
- i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
- else
- i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2;
- }
- if (i) {
- /* Rotate stat_comm entries to make current entry first */
- int j;
- __le32 bus_addr[BUZ_NUM_STAT_COM];
-
- /* Here we are copying the stat_com array, which
- * is already in little endian format, so
- * no endian conversions here
- */
- memcpy(bus_addr, zr->stat_com, sizeof(bus_addr));
-
- for (j = 0; j < BUZ_NUM_STAT_COM; j++)
- zr->stat_com[j] = bus_addr[(i + j) & BUZ_MASK_STAT_COM];
-
- zr->jpg_err_shift += i;
- zr->jpg_err_shift &= BUZ_MASK_STAT_COM;
- }
- if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)
- zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */
- zoran_restart(zr);
-}
-
-irqreturn_t
-zoran_irq (int irq,
- void *dev_id)
-{
- u32 stat, astat;
- int count;
- struct zoran *zr;
- unsigned long flags;
-
- zr = dev_id;
- count = 0;
-
- if (zr->testing) {
- /* Testing interrupts */
- spin_lock_irqsave(&zr->spinlock, flags);
- while ((stat = count_reset_interrupt(zr))) {
- if (count++ > 100) {
- btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);
- dprintk(1,
- KERN_ERR
- "%s: IRQ lockup while testing, isr=0x%08x, cleared int mask\n",
- ZR_DEVNAME(zr), stat);
- wake_up_interruptible(&zr->test_q);
- }
- }
- zr->last_isr = stat;
- spin_unlock_irqrestore(&zr->spinlock, flags);
- return IRQ_HANDLED;
- }
-
- spin_lock_irqsave(&zr->spinlock, flags);
- while (1) {
- /* get/clear interrupt status bits */
- stat = count_reset_interrupt(zr);
- astat = stat & IRQ_MASK;
- if (!astat) {
- break;
- }
- dprintk(4,
- KERN_DEBUG
- "zoran_irq: astat: 0x%08x, mask: 0x%08x\n",
- astat, btread(ZR36057_ICR));
- if (astat & zr->card.vsync_int) { // SW
-
- if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
- zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
- /* count missed interrupts */
- zr->JPEG_missed++;
- }
- //post_office_read(zr,1,0);
- /* Interrupts may still happen when
- * zr->v4l_memgrab_active is switched off.
- * We simply ignore them */
-
- if (zr->v4l_memgrab_active) {
- /* A lot more checks should be here ... */
- if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) == 0)
- dprintk(1,
- KERN_WARNING
- "%s: BuzIRQ with SnapShot off ???\n",
- ZR_DEVNAME(zr));
-
- if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) {
- /* There is a grab on a frame going on, check if it has finished */
- if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FrameGrab) == 0) {
- /* it is finished, notify the user */
-
- zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE;
- zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.seq = zr->v4l_grab_seq;
- do_gettimeofday(&zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.timestamp);
- zr->v4l_grab_frame = NO_GRAB_ACTIVE;
- zr->v4l_pend_tail++;
- }
- }
-
- if (zr->v4l_grab_frame == NO_GRAB_ACTIVE)
- wake_up_interruptible(&zr->v4l_capq);
-
- /* Check if there is another grab queued */
-
- if (zr->v4l_grab_frame == NO_GRAB_ACTIVE &&
- zr->v4l_pend_tail != zr->v4l_pend_head) {
- int frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME];
- u32 reg;
-
- zr->v4l_grab_frame = frame;
-
- /* Set zr36057 video front end and enable video */
-
- /* Buffer address */
-
- reg = zr->v4l_buffers.buffer[frame].v4l.fbuffer_bus;
- btwrite(reg, ZR36057_VDTR);
- if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
- reg += zr->v4l_settings.bytesperline;
- btwrite(reg, ZR36057_VDBR);
-
- /* video stride, status, and frame grab register */
- reg = 0;
- if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
- reg += zr->v4l_settings.bytesperline;
- reg = (reg << ZR36057_VSSFGR_DispStride);
- reg |= ZR36057_VSSFGR_VidOvf;
- reg |= ZR36057_VSSFGR_SnapShot;
- reg |= ZR36057_VSSFGR_FrameGrab;
- btwrite(reg, ZR36057_VSSFGR);
-
- btor(ZR36057_VDCR_VidEn,
- ZR36057_VDCR);
- }
- }
-
- /* even if we don't grab, we do want to increment
- * the sequence counter to see lost frames */
- zr->v4l_grab_seq++;
- }
-#if (IRQ_MASK & ZR36057_ISR_CodRepIRQ)
- if (astat & ZR36057_ISR_CodRepIRQ) {
- zr->intr_counter_CodRepIRQ++;
- IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n",
- ZR_DEVNAME(zr)));
- btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR);
- }
-#endif /* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */
-
-#if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ)
- if ((astat & ZR36057_ISR_JPEGRepIRQ) &&
- (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
- zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) {
- if (zr36067_debug > 1 && (!zr->frame_num || zr->JPEG_error)) {
- char sv[BUZ_NUM_STAT_COM + 1];
- int i;
-
- printk(KERN_INFO
- "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n",
- ZR_DEVNAME(zr), stat,
- zr->jpg_settings.odd_even,
- zr->jpg_settings.field_per_buff,
- zr->JPEG_missed);
-
- for (i = 0; i < BUZ_NUM_STAT_COM; i++)
- sv[i] = le32_to_cpu(zr->stat_com[i]) & 1 ? '1' : '0';
- sv[BUZ_NUM_STAT_COM] = 0;
- printk(KERN_INFO
- "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n",
- ZR_DEVNAME(zr), sv,
- zr->jpg_que_tail,
- zr->jpg_dma_tail,
- zr->jpg_dma_head,
- zr->jpg_que_head);
- } else {
- /* Get statistics */
- if (zr->JPEG_missed > zr->JPEG_max_missed)
- zr->JPEG_max_missed = zr->JPEG_missed;
- if (zr->JPEG_missed < zr->JPEG_min_missed)
- zr->JPEG_min_missed = zr->JPEG_missed;
- }
-
- if (zr36067_debug > 2 && zr->frame_num < 6) {
- int i;
-
- printk(KERN_INFO "%s: seq=%ld stat_com:",
- ZR_DEVNAME(zr), zr->jpg_seq_num);
- for (i = 0; i < 4; i++) {
- printk(KERN_CONT " %08x",
- le32_to_cpu(zr->stat_com[i]));
- }
- printk(KERN_CONT "\n");
- }
- zr->frame_num++;
- zr->JPEG_missed = 0;
- zr->JPEG_error = 0;
- zoran_reap_stat_com(zr);
- zoran_feed_stat_com(zr);
- wake_up_interruptible(&zr->jpg_capq);
- }
-#endif /* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */
-
- /* DATERR, too many fields missed, error processing */
- if ((astat & zr->card.jpeg_int) ||
- zr->JPEG_missed > 25 ||
- zr->JPEG_error == 1 ||
- ((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) &&
- (zr->frame_num && (zr->JPEG_missed > zr->jpg_settings.field_per_buff)))) {
- error_handler(zr, astat, stat);
- }
-
- count++;
- if (count > 10) {
- dprintk(2, KERN_WARNING "%s: irq loop %d\n",
- ZR_DEVNAME(zr), count);
- if (count > 20) {
- btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);
- dprintk(2,
- KERN_ERR
- "%s: IRQ lockup, cleared int mask\n",
- ZR_DEVNAME(zr));
- break;
- }
- }
- zr->last_isr = stat;
- }
- spin_unlock_irqrestore(&zr->spinlock, flags);
-
- return IRQ_HANDLED;
-}
-
-void
-zoran_set_pci_master (struct zoran *zr,
- int set_master)
-{
- if (set_master) {
- pci_set_master(zr->pci_dev);
- } else {
- u16 command;
-
- pci_read_config_word(zr->pci_dev, PCI_COMMAND, &command);
- command &= ~PCI_COMMAND_MASTER;
- pci_write_config_word(zr->pci_dev, PCI_COMMAND, command);
- }
-}
-
-void
-zoran_init_hardware (struct zoran *zr)
-{
- /* Enable bus-mastering */
- zoran_set_pci_master(zr, 1);
-
- /* Initialize the board */
- if (zr->card.init) {
- zr->card.init(zr);
- }
-
- decoder_call(zr, core, init, 0);
- decoder_call(zr, core, s_std, zr->norm);
- decoder_call(zr, video, s_routing,
- zr->card.input[zr->input].muxsel, 0, 0);
-
- encoder_call(zr, core, init, 0);
- encoder_call(zr, video, s_std_output, zr->norm);
- encoder_call(zr, video, s_routing, 0, 0, 0);
-
- /* toggle JPEG codec sleep to sync PLL */
- jpeg_codec_sleep(zr, 1);
- jpeg_codec_sleep(zr, 0);
-
- /* set individual interrupt enables (without GIRQ1)
- * but don't global enable until zoran_open() */
-
- //btwrite(IRQ_MASK & ~ZR36057_ISR_GIRQ1, ZR36057_ICR); // SW
- // It looks like using only JPEGRepIRQEn is not always reliable,
- // may be when JPEG codec crashes it won't generate IRQ? So,
- /*CP*/ // btwrite(IRQ_MASK, ZR36057_ICR); // Enable Vsync interrupts too. SM WHY ? LP
- zr36057_init_vfe(zr);
-
- zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
-
- btwrite(IRQ_MASK, ZR36057_ISR); // Clears interrupts
-}
-
-void
-zr36057_restart (struct zoran *zr)
-{
- btwrite(0, ZR36057_SPGPPCR);
- mdelay(1);
- btor(ZR36057_SPGPPCR_SoftReset, ZR36057_SPGPPCR);
- mdelay(1);
-
- /* assert P_Reset */
- btwrite(0, ZR36057_JPC);
- /* set up GPIO direction - all output */
- btwrite(ZR36057_SPGPPCR_SoftReset | 0, ZR36057_SPGPPCR);
-
- /* set up GPIO pins and guest bus timing */
- btwrite((0x81 << 24) | 0x8888, ZR36057_GPPGCR1);
-}
-
-/*
- * initialize video front end
- */
-
-static void
-zr36057_init_vfe (struct zoran *zr)
-{
- u32 reg;
-
- reg = btread(ZR36057_VFESPFR);
- reg |= ZR36057_VFESPFR_LittleEndian;
- reg &= ~ZR36057_VFESPFR_VCLKPol;
- reg |= ZR36057_VFESPFR_ExtFl;
- reg |= ZR36057_VFESPFR_TopField;
- btwrite(reg, ZR36057_VFESPFR);
- reg = btread(ZR36057_VDCR);
- if (pci_pci_problems & PCIPCI_TRITON)
- // || zr->revision < 1) // Revision 1 has also Triton support
- reg &= ~ZR36057_VDCR_Triton;
- else
- reg |= ZR36057_VDCR_Triton;
- btwrite(reg, ZR36057_VDCR);
-}
diff --git a/drivers/media/video/zoran/zoran_device.h b/drivers/media/video/zoran/zoran_device.h
deleted file mode 100644
index 07f2c23ff74..00000000000
--- a/drivers/media/video/zoran/zoran_device.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Zoran zr36057/zr36067 PCI controller driver, for the
- * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
- * Media Labs LML33/LML33R10.
- *
- * This part handles card-specific data and detection
- *
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- *
- * Currently maintained by:
- * Ronald Bultje <rbultje@ronald.bitfreak.net>
- * Laurent Pinchart <laurent.pinchart@skynet.be>
- * Mailinglist <mjpeg-users@lists.sf.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ZORAN_DEVICE_H__
-#define __ZORAN_DEVICE_H__
-
-/* general purpose I/O */
-extern void GPIO(struct zoran *zr,
- int bit,
- unsigned int value);
-
-/* codec (or actually: guest bus) access */
-extern int post_office_wait(struct zoran *zr);
-extern int post_office_write(struct zoran *zr,
- unsigned guest,
- unsigned reg,
- unsigned value);
-extern int post_office_read(struct zoran *zr,
- unsigned guest,
- unsigned reg);
-
-extern void detect_guest_activity(struct zoran *zr);
-
-extern void jpeg_codec_sleep(struct zoran *zr,
- int sleep);
-extern int jpeg_codec_reset(struct zoran *zr);
-
-/* zr360x7 access to raw capture */
-extern void zr36057_overlay(struct zoran *zr,
- int on);
-extern void write_overlay_mask(struct zoran_fh *fh,
- struct v4l2_clip *vp,
- int count);
-extern void zr36057_set_memgrab(struct zoran *zr,
- int mode);
-extern int wait_grab_pending(struct zoran *zr);
-
-/* interrupts */
-extern void print_interrupts(struct zoran *zr);
-extern void clear_interrupt_counters(struct zoran *zr);
-extern irqreturn_t zoran_irq(int irq, void *dev_id);
-
-/* JPEG codec access */
-extern void jpeg_start(struct zoran *zr);
-extern void zr36057_enable_jpg(struct zoran *zr,
- enum zoran_codec_mode mode);
-extern void zoran_feed_stat_com(struct zoran *zr);
-
-/* general */
-extern void zoran_set_pci_master(struct zoran *zr,
- int set_master);
-extern void zoran_init_hardware(struct zoran *zr);
-extern void zr36057_restart(struct zoran *zr);
-
-extern const struct zoran_format zoran_formats[];
-
-extern int v4l_nbufs;
-extern int v4l_bufsize;
-extern int jpg_nbufs;
-extern int jpg_bufsize;
-extern int pass_through;
-
-/* i2c */
-#define decoder_call(zr, o, f, args...) \
- v4l2_subdev_call(zr->decoder, o, f, ##args)
-#define encoder_call(zr, o, f, args...) \
- v4l2_subdev_call(zr->encoder, o, f, ##args)
-
-#endif /* __ZORAN_DEVICE_H__ */
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
deleted file mode 100644
index c6ccdeb6d8d..00000000000
--- a/drivers/media/video/zoran/zoran_driver.c
+++ /dev/null
@@ -1,3090 +0,0 @@
-/*
- * Zoran zr36057/zr36067 PCI controller driver, for the
- * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
- * Media Labs LML33/LML33R10.
- *
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- *
- * Changes for BUZ by Wolfgang Scherr <scherr@net4you.net>
- *
- * Changes for DC10/DC30 by Laurent Pinchart <laurent.pinchart@skynet.be>
- *
- * Changes for LML33R10 by Maxim Yevtyushkin <max@linuxmedialabs.com>
- *
- * Changes for videodev2/v4l2 by Ronald Bultje <rbultje@ronald.bitfreak.net>
- *
- * Based on
- *
- * Miro DC10 driver
- * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
- *
- * Iomega Buz driver version 1.0
- * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
- *
- * buz.0.0.3
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- *
- * bttv - Bt848 frame grabber driver
- * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- * & Marcus Metzler (mocm@thp.uni-koeln.de)
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/vmalloc.h>
-#include <linux/wait.h>
-
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-#include <linux/spinlock.h>
-
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include "videocodec.h"
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/proc_fs.h>
-
-#include <linux/mutex.h>
-#include "zoran.h"
-#include "zoran_device.h"
-#include "zoran_card.h"
-
-
-const struct zoran_format zoran_formats[] = {
- {
- .name = "15-bit RGB LE",
- .fourcc = V4L2_PIX_FMT_RGB555,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .depth = 15,
- .flags = ZORAN_FORMAT_CAPTURE |
- ZORAN_FORMAT_OVERLAY,
- .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif|
- ZR36057_VFESPFR_LittleEndian,
- }, {
- .name = "15-bit RGB BE",
- .fourcc = V4L2_PIX_FMT_RGB555X,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .depth = 15,
- .flags = ZORAN_FORMAT_CAPTURE |
- ZORAN_FORMAT_OVERLAY,
- .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif,
- }, {
- .name = "16-bit RGB LE",
- .fourcc = V4L2_PIX_FMT_RGB565,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .depth = 16,
- .flags = ZORAN_FORMAT_CAPTURE |
- ZORAN_FORMAT_OVERLAY,
- .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif|
- ZR36057_VFESPFR_LittleEndian,
- }, {
- .name = "16-bit RGB BE",
- .fourcc = V4L2_PIX_FMT_RGB565X,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .depth = 16,
- .flags = ZORAN_FORMAT_CAPTURE |
- ZORAN_FORMAT_OVERLAY,
- .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif,
- }, {
- .name = "24-bit RGB",
- .fourcc = V4L2_PIX_FMT_BGR24,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .depth = 24,
- .flags = ZORAN_FORMAT_CAPTURE |
- ZORAN_FORMAT_OVERLAY,
- .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24,
- }, {
- .name = "32-bit RGB LE",
- .fourcc = V4L2_PIX_FMT_BGR32,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .depth = 32,
- .flags = ZORAN_FORMAT_CAPTURE |
- ZORAN_FORMAT_OVERLAY,
- .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian,
- }, {
- .name = "32-bit RGB BE",
- .fourcc = V4L2_PIX_FMT_RGB32,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .depth = 32,
- .flags = ZORAN_FORMAT_CAPTURE |
- ZORAN_FORMAT_OVERLAY,
- .vfespfr = ZR36057_VFESPFR_RGB888,
- }, {
- .name = "4:2:2, packed, YUYV",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .colorspace = V4L2_COLORSPACE_SMPTE170M,
- .depth = 16,
- .flags = ZORAN_FORMAT_CAPTURE |
- ZORAN_FORMAT_OVERLAY,
- .vfespfr = ZR36057_VFESPFR_YUV422,
- }, {
- .name = "4:2:2, packed, UYVY",
- .fourcc = V4L2_PIX_FMT_UYVY,
- .colorspace = V4L2_COLORSPACE_SMPTE170M,
- .depth = 16,
- .flags = ZORAN_FORMAT_CAPTURE |
- ZORAN_FORMAT_OVERLAY,
- .vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian,
- }, {
- .name = "Hardware-encoded Motion-JPEG",
- .fourcc = V4L2_PIX_FMT_MJPEG,
- .colorspace = V4L2_COLORSPACE_SMPTE170M,
- .depth = 0,
- .flags = ZORAN_FORMAT_CAPTURE |
- ZORAN_FORMAT_PLAYBACK |
- ZORAN_FORMAT_COMPRESSED,
- }
-};
-#define NUM_FORMATS ARRAY_SIZE(zoran_formats)
-
- /* small helper function for calculating buffersizes for v4l2
- * we calculate the nearest higher power-of-two, which
- * will be the recommended buffersize */
-static __u32
-zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings)
-{
- __u8 div = settings->VerDcm * settings->HorDcm * settings->TmpDcm;
- __u32 num = (1024 * 512) / (div);
- __u32 result = 2;
-
- num--;
- while (num) {
- num >>= 1;
- result <<= 1;
- }
-
- if (result > jpg_bufsize)
- return jpg_bufsize;
- if (result < 8192)
- return 8192;
- return result;
-}
-
-/* forward references */
-static void v4l_fbuffer_free(struct zoran_fh *fh);
-static void jpg_fbuffer_free(struct zoran_fh *fh);
-
-/* Set mapping mode */
-static void map_mode_raw(struct zoran_fh *fh)
-{
- fh->map_mode = ZORAN_MAP_MODE_RAW;
- fh->buffers.buffer_size = v4l_bufsize;
- fh->buffers.num_buffers = v4l_nbufs;
-}
-static void map_mode_jpg(struct zoran_fh *fh, int play)
-{
- fh->map_mode = play ? ZORAN_MAP_MODE_JPG_PLAY : ZORAN_MAP_MODE_JPG_REC;
- fh->buffers.buffer_size = jpg_bufsize;
- fh->buffers.num_buffers = jpg_nbufs;
-}
-static inline const char *mode_name(enum zoran_map_mode mode)
-{
- return mode == ZORAN_MAP_MODE_RAW ? "V4L" : "JPG";
-}
-
-/*
- * Allocate the V4L grab buffers
- *
- * These have to be pysically contiguous.
- */
-
-static int v4l_fbuffer_alloc(struct zoran_fh *fh)
-{
- struct zoran *zr = fh->zr;
- int i, off;
- unsigned char *mem;
-
- for (i = 0; i < fh->buffers.num_buffers; i++) {
- if (fh->buffers.buffer[i].v4l.fbuffer)
- dprintk(2,
- KERN_WARNING
- "%s: %s - buffer %d already allocated!?\n",
- ZR_DEVNAME(zr), __func__, i);
-
- //udelay(20);
- mem = kmalloc(fh->buffers.buffer_size,
- GFP_KERNEL | __GFP_NOWARN);
- if (!mem) {
- dprintk(1,
- KERN_ERR
- "%s: %s - kmalloc for V4L buf %d failed\n",
- ZR_DEVNAME(zr), __func__, i);
- v4l_fbuffer_free(fh);
- return -ENOBUFS;
- }
- fh->buffers.buffer[i].v4l.fbuffer = mem;
- fh->buffers.buffer[i].v4l.fbuffer_phys = virt_to_phys(mem);
- fh->buffers.buffer[i].v4l.fbuffer_bus = virt_to_bus(mem);
- for (off = 0; off < fh->buffers.buffer_size;
- off += PAGE_SIZE)
- SetPageReserved(virt_to_page(mem + off));
- dprintk(4,
- KERN_INFO
- "%s: %s - V4L frame %d mem 0x%lx (bus: 0x%llx)\n",
- ZR_DEVNAME(zr), __func__, i, (unsigned long) mem,
- (unsigned long long)virt_to_bus(mem));
- }
-
- fh->buffers.allocated = 1;
-
- return 0;
-}
-
-/* free the V4L grab buffers */
-static void v4l_fbuffer_free(struct zoran_fh *fh)
-{
- struct zoran *zr = fh->zr;
- int i, off;
- unsigned char *mem;
-
- dprintk(4, KERN_INFO "%s: %s\n", ZR_DEVNAME(zr), __func__);
-
- for (i = 0; i < fh->buffers.num_buffers; i++) {
- if (!fh->buffers.buffer[i].v4l.fbuffer)
- continue;
-
- mem = fh->buffers.buffer[i].v4l.fbuffer;
- for (off = 0; off < fh->buffers.buffer_size;
- off += PAGE_SIZE)
- ClearPageReserved(virt_to_page(mem + off));
- kfree(fh->buffers.buffer[i].v4l.fbuffer);
- fh->buffers.buffer[i].v4l.fbuffer = NULL;
- }
-
- fh->buffers.allocated = 0;
-}
-
-/*
- * Allocate the MJPEG grab buffers.
- *
- * If a Natoma chipset is present and this is a revision 1 zr36057,
- * each MJPEG buffer needs to be physically contiguous.
- * (RJ: This statement is from Dave Perks' original driver,
- * I could never check it because I have a zr36067)
- *
- * RJ: The contents grab buffers needs never be accessed in the driver.
- * Therefore there is no need to allocate them with vmalloc in order
- * to get a contiguous virtual memory space.
- * I don't understand why many other drivers first allocate them with
- * vmalloc (which uses internally also get_zeroed_page, but delivers you
- * virtual addresses) and then again have to make a lot of efforts
- * to get the physical address.
- *
- * Ben Capper:
- * On big-endian architectures (such as ppc) some extra steps
- * are needed. When reading and writing to the stat_com array
- * and fragment buffers, the device expects to see little-
- * endian values. The use of cpu_to_le32() and le32_to_cpu()
- * in this function (and one or two others in zoran_device.c)
- * ensure that these values are always stored in little-endian
- * form, regardless of architecture. The zr36057 does Very Bad
- * Things on big endian architectures if the stat_com array
- * and fragment buffers are not little-endian.
- */
-
-static int jpg_fbuffer_alloc(struct zoran_fh *fh)
-{
- struct zoran *zr = fh->zr;
- int i, j, off;
- u8 *mem;
-
- for (i = 0; i < fh->buffers.num_buffers; i++) {
- if (fh->buffers.buffer[i].jpg.frag_tab)
- dprintk(2,
- KERN_WARNING
- "%s: %s - buffer %d already allocated!?\n",
- ZR_DEVNAME(zr), __func__, i);
-
- /* Allocate fragment table for this buffer */
-
- mem = (void *)get_zeroed_page(GFP_KERNEL);
- if (!mem) {
- dprintk(1,
- KERN_ERR
- "%s: %s - get_zeroed_page (frag_tab) failed for buffer %d\n",
- ZR_DEVNAME(zr), __func__, i);
- jpg_fbuffer_free(fh);
- return -ENOBUFS;
- }
- fh->buffers.buffer[i].jpg.frag_tab = (__le32 *)mem;
- fh->buffers.buffer[i].jpg.frag_tab_bus = virt_to_bus(mem);
-
- if (fh->buffers.need_contiguous) {
- mem = kmalloc(fh->buffers.buffer_size, GFP_KERNEL);
- if (mem == NULL) {
- dprintk(1,
- KERN_ERR
- "%s: %s - kmalloc failed for buffer %d\n",
- ZR_DEVNAME(zr), __func__, i);
- jpg_fbuffer_free(fh);
- return -ENOBUFS;
- }
- fh->buffers.buffer[i].jpg.frag_tab[0] =
- cpu_to_le32(virt_to_bus(mem));
- fh->buffers.buffer[i].jpg.frag_tab[1] =
- cpu_to_le32((fh->buffers.buffer_size >> 1) | 1);
- for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE)
- SetPageReserved(virt_to_page(mem + off));
- } else {
- /* jpg_bufsize is already page aligned */
- for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) {
- mem = (void *)get_zeroed_page(GFP_KERNEL);
- if (mem == NULL) {
- dprintk(1,
- KERN_ERR
- "%s: %s - get_zeroed_page failed for buffer %d\n",
- ZR_DEVNAME(zr), __func__, i);
- jpg_fbuffer_free(fh);
- return -ENOBUFS;
- }
-
- fh->buffers.buffer[i].jpg.frag_tab[2 * j] =
- cpu_to_le32(virt_to_bus(mem));
- fh->buffers.buffer[i].jpg.frag_tab[2 * j + 1] =
- cpu_to_le32((PAGE_SIZE >> 2) << 1);
- SetPageReserved(virt_to_page(mem));
- }
-
- fh->buffers.buffer[i].jpg.frag_tab[2 * j - 1] |= cpu_to_le32(1);
- }
- }
-
- dprintk(4,
- KERN_DEBUG "%s: %s - %d KB allocated\n",
- ZR_DEVNAME(zr), __func__,
- (fh->buffers.num_buffers * fh->buffers.buffer_size) >> 10);
-
- fh->buffers.allocated = 1;
-
- return 0;
-}
-
-/* free the MJPEG grab buffers */
-static void jpg_fbuffer_free(struct zoran_fh *fh)
-{
- struct zoran *zr = fh->zr;
- int i, j, off;
- unsigned char *mem;
- __le32 frag_tab;
- struct zoran_buffer *buffer;
-
- dprintk(4, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
-
- for (i = 0, buffer = &fh->buffers.buffer[0];
- i < fh->buffers.num_buffers; i++, buffer++) {
- if (!buffer->jpg.frag_tab)
- continue;
-
- if (fh->buffers.need_contiguous) {
- frag_tab = buffer->jpg.frag_tab[0];
-
- if (frag_tab) {
- mem = bus_to_virt(le32_to_cpu(frag_tab));
- for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE)
- ClearPageReserved(virt_to_page(mem + off));
- kfree(mem);
- buffer->jpg.frag_tab[0] = 0;
- buffer->jpg.frag_tab[1] = 0;
- }
- } else {
- for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) {
- frag_tab = buffer->jpg.frag_tab[2 * j];
-
- if (!frag_tab)
- break;
- ClearPageReserved(virt_to_page(bus_to_virt(le32_to_cpu(frag_tab))));
- free_page((unsigned long)bus_to_virt(le32_to_cpu(frag_tab)));
- buffer->jpg.frag_tab[2 * j] = 0;
- buffer->jpg.frag_tab[2 * j + 1] = 0;
- }
- }
-
- free_page((unsigned long)buffer->jpg.frag_tab);
- buffer->jpg.frag_tab = NULL;
- }
-
- fh->buffers.allocated = 0;
-}
-
-/*
- * V4L Buffer grabbing
- */
-
-static int
-zoran_v4l_set_format (struct zoran_fh *fh,
- int width,
- int height,
- const struct zoran_format *format)
-{
- struct zoran *zr = fh->zr;
- int bpp;
-
- /* Check size and format of the grab wanted */
-
- if (height < BUZ_MIN_HEIGHT || width < BUZ_MIN_WIDTH ||
- height > BUZ_MAX_HEIGHT || width > BUZ_MAX_WIDTH) {
- dprintk(1,
- KERN_ERR
- "%s: %s - wrong frame size (%dx%d)\n",
- ZR_DEVNAME(zr), __func__, width, height);
- return -EINVAL;
- }
-
- bpp = (format->depth + 7) / 8;
-
- /* Check against available buffer size */
- if (height * width * bpp > fh->buffers.buffer_size) {
- dprintk(1,
- KERN_ERR
- "%s: %s - video buffer size (%d kB) is too small\n",
- ZR_DEVNAME(zr), __func__, fh->buffers.buffer_size >> 10);
- return -EINVAL;
- }
-
- /* The video front end needs 4-byte alinged line sizes */
-
- if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) {
- dprintk(1,
- KERN_ERR
- "%s: %s - wrong frame alignment\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
-
- fh->v4l_settings.width = width;
- fh->v4l_settings.height = height;
- fh->v4l_settings.format = format;
- fh->v4l_settings.bytesperline = bpp * fh->v4l_settings.width;
-
- return 0;
-}
-
-static int zoran_v4l_queue_frame(struct zoran_fh *fh, int num)
-{
- struct zoran *zr = fh->zr;
- unsigned long flags;
- int res = 0;
-
- if (!fh->buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: %s - buffers not yet allocated\n",
- ZR_DEVNAME(zr), __func__);
- res = -ENOMEM;
- }
-
- /* No grabbing outside the buffer range! */
- if (num >= fh->buffers.num_buffers || num < 0) {
- dprintk(1,
- KERN_ERR
- "%s: %s - buffer %d is out of range\n",
- ZR_DEVNAME(zr), __func__, num);
- res = -EINVAL;
- }
-
- spin_lock_irqsave(&zr->spinlock, flags);
-
- if (fh->buffers.active == ZORAN_FREE) {
- if (zr->v4l_buffers.active == ZORAN_FREE) {
- zr->v4l_buffers = fh->buffers;
- fh->buffers.active = ZORAN_ACTIVE;
- } else {
- dprintk(1,
- KERN_ERR
- "%s: %s - another session is already capturing\n",
- ZR_DEVNAME(zr), __func__);
- res = -EBUSY;
- }
- }
-
- /* make sure a grab isn't going on currently with this buffer */
- if (!res) {
- switch (zr->v4l_buffers.buffer[num].state) {
- default:
- case BUZ_STATE_PEND:
- if (zr->v4l_buffers.active == ZORAN_FREE) {
- fh->buffers.active = ZORAN_FREE;
- zr->v4l_buffers.allocated = 0;
- }
- res = -EBUSY; /* what are you doing? */
- break;
- case BUZ_STATE_DONE:
- dprintk(2,
- KERN_WARNING
- "%s: %s - queueing buffer %d in state DONE!?\n",
- ZR_DEVNAME(zr), __func__, num);
- case BUZ_STATE_USER:
- /* since there is at least one unused buffer there's room for at least
- * one more pend[] entry */
- zr->v4l_pend[zr->v4l_pend_head++ & V4L_MASK_FRAME] = num;
- zr->v4l_buffers.buffer[num].state = BUZ_STATE_PEND;
- zr->v4l_buffers.buffer[num].bs.length =
- fh->v4l_settings.bytesperline *
- zr->v4l_settings.height;
- fh->buffers.buffer[num] = zr->v4l_buffers.buffer[num];
- break;
- }
- }
-
- spin_unlock_irqrestore(&zr->spinlock, flags);
-
- if (!res && zr->v4l_buffers.active == ZORAN_FREE)
- zr->v4l_buffers.active = fh->buffers.active;
-
- return res;
-}
-
-/*
- * Sync on a V4L buffer
- */
-
-static int v4l_sync(struct zoran_fh *fh, int frame)
-{
- struct zoran *zr = fh->zr;
- unsigned long flags;
-
- if (fh->buffers.active == ZORAN_FREE) {
- dprintk(1,
- KERN_ERR
- "%s: %s - no grab active for this session\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
-
- /* check passed-in frame number */
- if (frame >= fh->buffers.num_buffers || frame < 0) {
- dprintk(1,
- KERN_ERR "%s: %s - frame %d is invalid\n",
- ZR_DEVNAME(zr), __func__, frame);
- return -EINVAL;
- }
-
- /* Check if is buffer was queued at all */
- if (zr->v4l_buffers.buffer[frame].state == BUZ_STATE_USER) {
- dprintk(1,
- KERN_ERR
- "%s: %s - attempt to sync on a buffer which was not queued?\n",
- ZR_DEVNAME(zr), __func__);
- return -EPROTO;
- }
-
- /* wait on this buffer to get ready */
- if (!wait_event_interruptible_timeout(zr->v4l_capq,
- (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND), 10*HZ))
- return -ETIME;
- if (signal_pending(current))
- return -ERESTARTSYS;
-
- /* buffer should now be in BUZ_STATE_DONE */
- if (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_DONE)
- dprintk(2,
- KERN_ERR "%s: %s - internal state error\n",
- ZR_DEVNAME(zr), __func__);
-
- zr->v4l_buffers.buffer[frame].state = BUZ_STATE_USER;
- fh->buffers.buffer[frame] = zr->v4l_buffers.buffer[frame];
-
- spin_lock_irqsave(&zr->spinlock, flags);
-
- /* Check if streaming capture has finished */
- if (zr->v4l_pend_tail == zr->v4l_pend_head) {
- zr36057_set_memgrab(zr, 0);
- if (zr->v4l_buffers.active == ZORAN_ACTIVE) {
- fh->buffers.active = zr->v4l_buffers.active = ZORAN_FREE;
- zr->v4l_buffers.allocated = 0;
- }
- }
-
- spin_unlock_irqrestore(&zr->spinlock, flags);
-
- return 0;
-}
-
-/*
- * Queue a MJPEG buffer for capture/playback
- */
-
-static int zoran_jpg_queue_frame(struct zoran_fh *fh, int num,
- enum zoran_codec_mode mode)
-{
- struct zoran *zr = fh->zr;
- unsigned long flags;
- int res = 0;
-
- /* Check if buffers are allocated */
- if (!fh->buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: %s - buffers not yet allocated\n",
- ZR_DEVNAME(zr), __func__);
- return -ENOMEM;
- }
-
- /* No grabbing outside the buffer range! */
- if (num >= fh->buffers.num_buffers || num < 0) {
- dprintk(1,
- KERN_ERR
- "%s: %s - buffer %d out of range\n",
- ZR_DEVNAME(zr), __func__, num);
- return -EINVAL;
- }
-
- /* what is the codec mode right now? */
- if (zr->codec_mode == BUZ_MODE_IDLE) {
- zr->jpg_settings = fh->jpg_settings;
- } else if (zr->codec_mode != mode) {
- /* wrong codec mode active - invalid */
- dprintk(1,
- KERN_ERR
- "%s: %s - codec in wrong mode\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
-
- if (fh->buffers.active == ZORAN_FREE) {
- if (zr->jpg_buffers.active == ZORAN_FREE) {
- zr->jpg_buffers = fh->buffers;
- fh->buffers.active = ZORAN_ACTIVE;
- } else {
- dprintk(1,
- KERN_ERR
- "%s: %s - another session is already capturing\n",
- ZR_DEVNAME(zr), __func__);
- res = -EBUSY;
- }
- }
-
- if (!res && zr->codec_mode == BUZ_MODE_IDLE) {
- /* Ok load up the jpeg codec */
- zr36057_enable_jpg(zr, mode);
- }
-
- spin_lock_irqsave(&zr->spinlock, flags);
-
- if (!res) {
- switch (zr->jpg_buffers.buffer[num].state) {
- case BUZ_STATE_DONE:
- dprintk(2,
- KERN_WARNING
- "%s: %s - queing frame in BUZ_STATE_DONE state!?\n",
- ZR_DEVNAME(zr), __func__);
- case BUZ_STATE_USER:
- /* since there is at least one unused buffer there's room for at
- *least one more pend[] entry */
- zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = num;
- zr->jpg_buffers.buffer[num].state = BUZ_STATE_PEND;
- fh->buffers.buffer[num] = zr->jpg_buffers.buffer[num];
- zoran_feed_stat_com(zr);
- break;
- default:
- case BUZ_STATE_DMA:
- case BUZ_STATE_PEND:
- if (zr->jpg_buffers.active == ZORAN_FREE) {
- fh->buffers.active = ZORAN_FREE;
- zr->jpg_buffers.allocated = 0;
- }
- res = -EBUSY; /* what are you doing? */
- break;
- }
- }
-
- spin_unlock_irqrestore(&zr->spinlock, flags);
-
- if (!res && zr->jpg_buffers.active == ZORAN_FREE)
- zr->jpg_buffers.active = fh->buffers.active;
-
- return res;
-}
-
-static int jpg_qbuf(struct zoran_fh *fh, int frame, enum zoran_codec_mode mode)
-{
- struct zoran *zr = fh->zr;
- int res = 0;
-
- /* Does the user want to stop streaming? */
- if (frame < 0) {
- if (zr->codec_mode == mode) {
- if (fh->buffers.active == ZORAN_FREE) {
- dprintk(1,
- KERN_ERR
- "%s: %s(-1) - session not active\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
- fh->buffers.active = zr->jpg_buffers.active = ZORAN_FREE;
- zr->jpg_buffers.allocated = 0;
- zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
- return 0;
- } else {
- dprintk(1,
- KERN_ERR
- "%s: %s - stop streaming but not in streaming mode\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
- }
-
- if ((res = zoran_jpg_queue_frame(fh, frame, mode)))
- return res;
-
- /* Start the jpeg codec when the first frame is queued */
- if (!res && zr->jpg_que_head == 1)
- jpeg_start(zr);
-
- return res;
-}
-
-/*
- * Sync on a MJPEG buffer
- */
-
-static int jpg_sync(struct zoran_fh *fh, struct zoran_sync *bs)
-{
- struct zoran *zr = fh->zr;
- unsigned long flags;
- int frame;
-
- if (fh->buffers.active == ZORAN_FREE) {
- dprintk(1,
- KERN_ERR
- "%s: %s - capture is not currently active\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
- if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS &&
- zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) {
- dprintk(1,
- KERN_ERR
- "%s: %s - codec not in streaming mode\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
- if (!wait_event_interruptible_timeout(zr->jpg_capq,
- (zr->jpg_que_tail != zr->jpg_dma_tail ||
- zr->jpg_dma_tail == zr->jpg_dma_head),
- 10*HZ)) {
- int isr;
-
- btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
- udelay(1);
- zr->codec->control(zr->codec, CODEC_G_STATUS,
- sizeof(isr), &isr);
- dprintk(1,
- KERN_ERR
- "%s: %s - timeout: codec isr=0x%02x\n",
- ZR_DEVNAME(zr), __func__, isr);
-
- return -ETIME;
-
- }
- if (signal_pending(current))
- return -ERESTARTSYS;
-
- spin_lock_irqsave(&zr->spinlock, flags);
-
- if (zr->jpg_dma_tail != zr->jpg_dma_head)
- frame = zr->jpg_pend[zr->jpg_que_tail++ & BUZ_MASK_FRAME];
- else
- frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
-
- /* buffer should now be in BUZ_STATE_DONE */
- if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE)
- dprintk(2,
- KERN_ERR "%s: %s - internal state error\n",
- ZR_DEVNAME(zr), __func__);
-
- *bs = zr->jpg_buffers.buffer[frame].bs;
- bs->frame = frame;
- zr->jpg_buffers.buffer[frame].state = BUZ_STATE_USER;
- fh->buffers.buffer[frame] = zr->jpg_buffers.buffer[frame];
-
- spin_unlock_irqrestore(&zr->spinlock, flags);
-
- return 0;
-}
-
-static void zoran_open_init_session(struct zoran_fh *fh)
-{
- int i;
- struct zoran *zr = fh->zr;
-
- /* Per default, map the V4L Buffers */
- map_mode_raw(fh);
-
- /* take over the card's current settings */
- fh->overlay_settings = zr->overlay_settings;
- fh->overlay_settings.is_set = 0;
- fh->overlay_settings.format = zr->overlay_settings.format;
- fh->overlay_active = ZORAN_FREE;
-
- /* v4l settings */
- fh->v4l_settings = zr->v4l_settings;
- /* jpg settings */
- fh->jpg_settings = zr->jpg_settings;
-
- /* buffers */
- memset(&fh->buffers, 0, sizeof(fh->buffers));
- for (i = 0; i < MAX_FRAME; i++) {
- fh->buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
- fh->buffers.buffer[i].bs.frame = i;
- }
- fh->buffers.allocated = 0;
- fh->buffers.active = ZORAN_FREE;
-}
-
-static void zoran_close_end_session(struct zoran_fh *fh)
-{
- struct zoran *zr = fh->zr;
-
- /* overlay */
- if (fh->overlay_active != ZORAN_FREE) {
- fh->overlay_active = zr->overlay_active = ZORAN_FREE;
- zr->v4l_overlay_active = 0;
- if (!zr->v4l_memgrab_active)
- zr36057_overlay(zr, 0);
- zr->overlay_mask = NULL;
- }
-
- if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
- /* v4l capture */
- if (fh->buffers.active != ZORAN_FREE) {
- unsigned long flags;
-
- spin_lock_irqsave(&zr->spinlock, flags);
- zr36057_set_memgrab(zr, 0);
- zr->v4l_buffers.allocated = 0;
- zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
- spin_unlock_irqrestore(&zr->spinlock, flags);
- }
-
- /* v4l buffers */
- if (fh->buffers.allocated)
- v4l_fbuffer_free(fh);
- } else {
- /* jpg capture */
- if (fh->buffers.active != ZORAN_FREE) {
- zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
- zr->jpg_buffers.allocated = 0;
- zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE;
- }
-
- /* jpg buffers */
- if (fh->buffers.allocated)
- jpg_fbuffer_free(fh);
- }
-}
-
-/*
- * Open a zoran card. Right now the flags stuff is just playing
- */
-
-static int zoran_open(struct file *file)
-{
- struct zoran *zr = video_drvdata(file);
- struct zoran_fh *fh;
- int res, first_open = 0;
-
- dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(-)=%d\n",
- ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user + 1);
-
- mutex_lock(&zr->other_lock);
-
- if (zr->user >= 2048) {
- dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
- ZR_DEVNAME(zr), zr->user);
- res = -EBUSY;
- goto fail_unlock;
- }
-
- /* now, create the open()-specific file_ops struct */
- fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL);
- if (!fh) {
- dprintk(1,
- KERN_ERR
- "%s: %s - allocation of zoran_fh failed\n",
- ZR_DEVNAME(zr), __func__);
- res = -ENOMEM;
- goto fail_unlock;
- }
- /* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows
- * on norm-change! */
- fh->overlay_mask =
- kmalloc(((768 + 31) / 32) * 576 * 4, GFP_KERNEL);
- if (!fh->overlay_mask) {
- dprintk(1,
- KERN_ERR
- "%s: %s - allocation of overlay_mask failed\n",
- ZR_DEVNAME(zr), __func__);
- res = -ENOMEM;
- goto fail_fh;
- }
-
- if (zr->user++ == 0)
- first_open = 1;
-
- /*mutex_unlock(&zr->resource_lock);*/
-
- /* default setup - TODO: look at flags */
- if (first_open) { /* First device open */
- zr36057_restart(zr);
- zoran_open_init_params(zr);
- zoran_init_hardware(zr);
-
- btor(ZR36057_ICR_IntPinEn, ZR36057_ICR);
- }
-
- /* set file_ops stuff */
- file->private_data = fh;
- fh->zr = zr;
- zoran_open_init_session(fh);
- mutex_unlock(&zr->other_lock);
-
- return 0;
-
-fail_fh:
- kfree(fh);
-fail_unlock:
- mutex_unlock(&zr->other_lock);
-
- dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n",
- ZR_DEVNAME(zr), res, zr->user);
-
- return res;
-}
-
-static int
-zoran_close(struct file *file)
-{
- struct zoran_fh *fh = file->private_data;
- struct zoran *zr = fh->zr;
-
- dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(+)=%d\n",
- ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user - 1);
-
- /* kernel locks (fs/device.c), so don't do that ourselves
- * (prevents deadlocks) */
- mutex_lock(&zr->other_lock);
-
- zoran_close_end_session(fh);
-
- if (zr->user-- == 1) { /* Last process */
- /* Clean up JPEG process */
- wake_up_interruptible(&zr->jpg_capq);
- zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
- zr->jpg_buffers.allocated = 0;
- zr->jpg_buffers.active = ZORAN_FREE;
-
- /* disable interrupts */
- btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);
-
- if (zr36067_debug > 1)
- print_interrupts(zr);
-
- /* Overlay off */
- zr->v4l_overlay_active = 0;
- zr36057_overlay(zr, 0);
- zr->overlay_mask = NULL;
-
- /* capture off */
- wake_up_interruptible(&zr->v4l_capq);
- zr36057_set_memgrab(zr, 0);
- zr->v4l_buffers.allocated = 0;
- zr->v4l_buffers.active = ZORAN_FREE;
- zoran_set_pci_master(zr, 0);
-
- if (!pass_through) { /* Switch to color bar */
- decoder_call(zr, video, s_stream, 0);
- encoder_call(zr, video, s_routing, 2, 0, 0);
- }
- }
- mutex_unlock(&zr->other_lock);
-
- file->private_data = NULL;
- kfree(fh->overlay_mask);
- kfree(fh);
-
- dprintk(4, KERN_INFO "%s: %s done\n", ZR_DEVNAME(zr), __func__);
-
- return 0;
-}
-
-
-static ssize_t
-zoran_read (struct file *file,
- char __user *data,
- size_t count,
- loff_t *ppos)
-{
- /* we simply don't support read() (yet)... */
-
- return -EINVAL;
-}
-
-static ssize_t
-zoran_write (struct file *file,
- const char __user *data,
- size_t count,
- loff_t *ppos)
-{
- /* ...and the same goes for write() */
-
- return -EINVAL;
-}
-
-static int setup_fbuffer(struct zoran_fh *fh,
- void *base,
- const struct zoran_format *fmt,
- int width,
- int height,
- int bytesperline)
-{
- struct zoran *zr = fh->zr;
-
- /* (Ronald) v4l/v4l2 guidelines */
- if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
- return -EPERM;
-
- /* Don't allow frame buffer overlay if PCI or AGP is buggy, or on
- ALi Magik (that needs very low latency while the card needs a
- higher value always) */
-
- if (pci_pci_problems & (PCIPCI_FAIL | PCIAGP_FAIL | PCIPCI_ALIMAGIK))
- return -ENXIO;
-
- /* we need a bytesperline value, even if not given */
- if (!bytesperline)
- bytesperline = width * ((fmt->depth + 7) & ~7) / 8;
-
-#if 0
- if (zr->overlay_active) {
- /* dzjee... stupid users... don't even bother to turn off
- * overlay before changing the memory location...
- * normally, we would return errors here. However, one of
- * the tools that does this is... xawtv! and since xawtv
- * is used by +/- 99% of the users, we'd rather be user-
- * friendly and silently do as if nothing went wrong */
- dprintk(3,
- KERN_ERR
- "%s: %s - forced overlay turnoff because framebuffer changed\n",
- ZR_DEVNAME(zr), __func__);
- zr36057_overlay(zr, 0);
- }
-#endif
-
- if (!(fmt->flags & ZORAN_FORMAT_OVERLAY)) {
- dprintk(1,
- KERN_ERR
- "%s: %s - no valid overlay format given\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
- if (height <= 0 || width <= 0 || bytesperline <= 0) {
- dprintk(1,
- KERN_ERR
- "%s: %s - invalid height/width/bpl value (%d|%d|%d)\n",
- ZR_DEVNAME(zr), __func__, width, height, bytesperline);
- return -EINVAL;
- }
- if (bytesperline & 3) {
- dprintk(1,
- KERN_ERR
- "%s: %s - bytesperline (%d) must be 4-byte aligned\n",
- ZR_DEVNAME(zr), __func__, bytesperline);
- return -EINVAL;
- }
-
- zr->vbuf_base = (void *) ((unsigned long) base & ~3);
- zr->vbuf_height = height;
- zr->vbuf_width = width;
- zr->vbuf_depth = fmt->depth;
- zr->overlay_settings.format = fmt;
- zr->vbuf_bytesperline = bytesperline;
-
- /* The user should set new window parameters */
- zr->overlay_settings.is_set = 0;
-
- return 0;
-}
-
-
-static int setup_window(struct zoran_fh *fh,
- int x,
- int y,
- int width,
- int height,
- struct v4l2_clip __user *clips,
- unsigned int clipcount,
- void __user *bitmap)
-{
- struct zoran *zr = fh->zr;
- struct v4l2_clip *vcp = NULL;
- int on, end;
-
-
- if (!zr->vbuf_base) {
- dprintk(1,
- KERN_ERR
- "%s: %s - frame buffer has to be set first\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
-
- if (!fh->overlay_settings.format) {
- dprintk(1,
- KERN_ERR
- "%s: %s - no overlay format set\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
-
- if (clipcount > 2048) {
- dprintk(1,
- KERN_ERR
- "%s: %s - invalid clipcount\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
-
- /*
- * The video front end needs 4-byte alinged line sizes, we correct that
- * silently here if necessary
- */
- if (zr->vbuf_depth == 15 || zr->vbuf_depth == 16) {
- end = (x + width) & ~1; /* round down */
- x = (x + 1) & ~1; /* round up */
- width = end - x;
- }
-
- if (zr->vbuf_depth == 24) {
- end = (x + width) & ~3; /* round down */
- x = (x + 3) & ~3; /* round up */
- width = end - x;
- }
-
- if (width > BUZ_MAX_WIDTH)
- width = BUZ_MAX_WIDTH;
- if (height > BUZ_MAX_HEIGHT)
- height = BUZ_MAX_HEIGHT;
-
- /* Check for invalid parameters */
- if (width < BUZ_MIN_WIDTH || height < BUZ_MIN_HEIGHT ||
- width > BUZ_MAX_WIDTH || height > BUZ_MAX_HEIGHT) {
- dprintk(1,
- KERN_ERR
- "%s: %s - width = %d or height = %d invalid\n",
- ZR_DEVNAME(zr), __func__, width, height);
- return -EINVAL;
- }
-
- fh->overlay_settings.x = x;
- fh->overlay_settings.y = y;
- fh->overlay_settings.width = width;
- fh->overlay_settings.height = height;
- fh->overlay_settings.clipcount = clipcount;
-
- /*
- * If an overlay is running, we have to switch it off
- * and switch it on again in order to get the new settings in effect.
- *
- * We also want to avoid that the overlay mask is written
- * when an overlay is running.
- */
-
- on = zr->v4l_overlay_active && !zr->v4l_memgrab_active &&
- zr->overlay_active != ZORAN_FREE &&
- fh->overlay_active != ZORAN_FREE;
- if (on)
- zr36057_overlay(zr, 0);
-
- /*
- * Write the overlay mask if clips are wanted.
- * We prefer a bitmap.
- */
- if (bitmap) {
- /* fake value - it just means we want clips */
- fh->overlay_settings.clipcount = 1;
-
- if (copy_from_user(fh->overlay_mask, bitmap,
- (width * height + 7) / 8)) {
- return -EFAULT;
- }
- } else if (clipcount) {
- /* write our own bitmap from the clips */
- vcp = vmalloc(sizeof(struct v4l2_clip) * (clipcount + 4));
- if (vcp == NULL) {
- dprintk(1,
- KERN_ERR
- "%s: %s - Alloc of clip mask failed\n",
- ZR_DEVNAME(zr), __func__);
- return -ENOMEM;
- }
- if (copy_from_user
- (vcp, clips, sizeof(struct v4l2_clip) * clipcount)) {
- vfree(vcp);
- return -EFAULT;
- }
- write_overlay_mask(fh, vcp, clipcount);
- vfree(vcp);
- }
-
- fh->overlay_settings.is_set = 1;
- if (fh->overlay_active != ZORAN_FREE &&
- zr->overlay_active != ZORAN_FREE)
- zr->overlay_settings = fh->overlay_settings;
-
- if (on)
- zr36057_overlay(zr, 1);
-
- /* Make sure the changes come into effect */
- return wait_grab_pending(zr);
-}
-
-static int setup_overlay(struct zoran_fh *fh, int on)
-{
- struct zoran *zr = fh->zr;
-
- /* If there is nothing to do, return immediately */
- if ((on && fh->overlay_active != ZORAN_FREE) ||
- (!on && fh->overlay_active == ZORAN_FREE))
- return 0;
-
- /* check whether we're touching someone else's overlay */
- if (on && zr->overlay_active != ZORAN_FREE &&
- fh->overlay_active == ZORAN_FREE) {
- dprintk(1,
- KERN_ERR
- "%s: %s - overlay is already active for another session\n",
- ZR_DEVNAME(zr), __func__);
- return -EBUSY;
- }
- if (!on && zr->overlay_active != ZORAN_FREE &&
- fh->overlay_active == ZORAN_FREE) {
- dprintk(1,
- KERN_ERR
- "%s: %s - you cannot cancel someone else's session\n",
- ZR_DEVNAME(zr), __func__);
- return -EPERM;
- }
-
- if (on == 0) {
- zr->overlay_active = fh->overlay_active = ZORAN_FREE;
- zr->v4l_overlay_active = 0;
- /* When a grab is running, the video simply
- * won't be switched on any more */
- if (!zr->v4l_memgrab_active)
- zr36057_overlay(zr, 0);
- zr->overlay_mask = NULL;
- } else {
- if (!zr->vbuf_base || !fh->overlay_settings.is_set) {
- dprintk(1,
- KERN_ERR
- "%s: %s - buffer or window not set\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
- if (!fh->overlay_settings.format) {
- dprintk(1,
- KERN_ERR
- "%s: %s - no overlay format set\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
- zr->overlay_active = fh->overlay_active = ZORAN_LOCKED;
- zr->v4l_overlay_active = 1;
- zr->overlay_mask = fh->overlay_mask;
- zr->overlay_settings = fh->overlay_settings;
- if (!zr->v4l_memgrab_active)
- zr36057_overlay(zr, 1);
- /* When a grab is running, the video will be
- * switched on when grab is finished */
- }
-
- /* Make sure the changes come into effect */
- return wait_grab_pending(zr);
-}
-
-/* get the status of a buffer in the clients buffer queue */
-static int zoran_v4l2_buffer_status(struct zoran_fh *fh,
- struct v4l2_buffer *buf, int num)
-{
- struct zoran *zr = fh->zr;
- unsigned long flags;
-
- buf->flags = V4L2_BUF_FLAG_MAPPED;
-
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_RAW:
- /* check range */
- if (num < 0 || num >= fh->buffers.num_buffers ||
- !fh->buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: %s - wrong number or buffers not allocated\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
-
- spin_lock_irqsave(&zr->spinlock, flags);
- dprintk(3,
- KERN_DEBUG
- "%s: %s() - raw active=%c, buffer %d: state=%c, map=%c\n",
- ZR_DEVNAME(zr), __func__,
- "FAL"[fh->buffers.active], num,
- "UPMD"[zr->v4l_buffers.buffer[num].state],
- fh->buffers.buffer[num].map ? 'Y' : 'N');
- spin_unlock_irqrestore(&zr->spinlock, flags);
-
- buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- buf->length = fh->buffers.buffer_size;
-
- /* get buffer */
- buf->bytesused = fh->buffers.buffer[num].bs.length;
- if (fh->buffers.buffer[num].state == BUZ_STATE_DONE ||
- fh->buffers.buffer[num].state == BUZ_STATE_USER) {
- buf->sequence = fh->buffers.buffer[num].bs.seq;
- buf->flags |= V4L2_BUF_FLAG_DONE;
- buf->timestamp = fh->buffers.buffer[num].bs.timestamp;
- } else {
- buf->flags |= V4L2_BUF_FLAG_QUEUED;
- }
-
- if (fh->v4l_settings.height <= BUZ_MAX_HEIGHT / 2)
- buf->field = V4L2_FIELD_TOP;
- else
- buf->field = V4L2_FIELD_INTERLACED;
-
- break;
-
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
-
- /* check range */
- if (num < 0 || num >= fh->buffers.num_buffers ||
- !fh->buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: %s - wrong number or buffers not allocated\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
-
- buf->type = (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ?
- V4L2_BUF_TYPE_VIDEO_CAPTURE :
- V4L2_BUF_TYPE_VIDEO_OUTPUT;
- buf->length = fh->buffers.buffer_size;
-
- /* these variables are only written after frame has been captured */
- if (fh->buffers.buffer[num].state == BUZ_STATE_DONE ||
- fh->buffers.buffer[num].state == BUZ_STATE_USER) {
- buf->sequence = fh->buffers.buffer[num].bs.seq;
- buf->timestamp = fh->buffers.buffer[num].bs.timestamp;
- buf->bytesused = fh->buffers.buffer[num].bs.length;
- buf->flags |= V4L2_BUF_FLAG_DONE;
- } else {
- buf->flags |= V4L2_BUF_FLAG_QUEUED;
- }
-
- /* which fields are these? */
- if (fh->jpg_settings.TmpDcm != 1)
- buf->field = fh->jpg_settings.odd_even ?
- V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
- else
- buf->field = fh->jpg_settings.odd_even ?
- V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT;
-
- break;
-
- default:
-
- dprintk(5,
- KERN_ERR
- "%s: %s - invalid buffer type|map_mode (%d|%d)\n",
- ZR_DEVNAME(zr), __func__, buf->type, fh->map_mode);
- return -EINVAL;
- }
-
- buf->memory = V4L2_MEMORY_MMAP;
- buf->index = num;
- buf->m.offset = buf->length * num;
-
- return 0;
-}
-
-static int
-zoran_set_norm (struct zoran *zr,
- v4l2_std_id norm)
-{
- int on;
-
- if (zr->v4l_buffers.active != ZORAN_FREE ||
- zr->jpg_buffers.active != ZORAN_FREE) {
- dprintk(1,
- KERN_WARNING
- "%s: %s called while in playback/capture mode\n",
- ZR_DEVNAME(zr), __func__);
- return -EBUSY;
- }
-
- if (!(norm & zr->card.norms)) {
- dprintk(1,
- KERN_ERR "%s: %s - unsupported norm %llx\n",
- ZR_DEVNAME(zr), __func__, norm);
- return -EINVAL;
- }
-
- if (norm == V4L2_STD_ALL) {
- unsigned int status = 0;
- v4l2_std_id std = 0;
-
- decoder_call(zr, video, querystd, &std);
- decoder_call(zr, core, s_std, std);
-
- /* let changes come into effect */
- ssleep(2);
-
- decoder_call(zr, video, g_input_status, &status);
- if (status & V4L2_IN_ST_NO_SIGNAL) {
- dprintk(1,
- KERN_ERR
- "%s: %s - no norm detected\n",
- ZR_DEVNAME(zr), __func__);
- /* reset norm */
- decoder_call(zr, core, s_std, zr->norm);
- return -EIO;
- }
-
- norm = std;
- }
- if (norm & V4L2_STD_SECAM)
- zr->timing = zr->card.tvn[2];
- else if (norm & V4L2_STD_NTSC)
- zr->timing = zr->card.tvn[1];
- else
- zr->timing = zr->card.tvn[0];
-
- /* We switch overlay off and on since a change in the
- * norm needs different VFE settings */
- on = zr->overlay_active && !zr->v4l_memgrab_active;
- if (on)
- zr36057_overlay(zr, 0);
-
- decoder_call(zr, core, s_std, norm);
- encoder_call(zr, video, s_std_output, norm);
-
- if (on)
- zr36057_overlay(zr, 1);
-
- /* Make sure the changes come into effect */
- zr->norm = norm;
-
- return 0;
-}
-
-static int
-zoran_set_input (struct zoran *zr,
- int input)
-{
- if (input == zr->input) {
- return 0;
- }
-
- if (zr->v4l_buffers.active != ZORAN_FREE ||
- zr->jpg_buffers.active != ZORAN_FREE) {
- dprintk(1,
- KERN_WARNING
- "%s: %s called while in playback/capture mode\n",
- ZR_DEVNAME(zr), __func__);
- return -EBUSY;
- }
-
- if (input < 0 || input >= zr->card.inputs) {
- dprintk(1,
- KERN_ERR
- "%s: %s - unnsupported input %d\n",
- ZR_DEVNAME(zr), __func__, input);
- return -EINVAL;
- }
-
- zr->input = input;
-
- decoder_call(zr, video, s_routing,
- zr->card.input[input].muxsel, 0, 0);
-
- return 0;
-}
-
-/*
- * ioctl routine
- */
-
-static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- memset(cap, 0, sizeof(*cap));
- strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1);
- strncpy(cap->driver, "zoran", sizeof(cap->driver)-1);
- snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
- pci_name(zr->pci_dev));
- cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OVERLAY;
- return 0;
-}
-
-static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag)
-{
- unsigned int num, i;
-
- for (num = i = 0; i < NUM_FORMATS; i++) {
- if (zoran_formats[i].flags & flag && num++ == fmt->index) {
- strncpy(fmt->description, zoran_formats[i].name,
- sizeof(fmt->description) - 1);
- /* fmt struct pre-zeroed, so adding '\0' not needed */
- fmt->pixelformat = zoran_formats[i].fourcc;
- if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
- fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
- return 0;
- }
- }
- return -EINVAL;
-}
-
-static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh,
- struct v4l2_fmtdesc *f)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE);
-}
-
-static int zoran_enum_fmt_vid_out(struct file *file, void *__fh,
- struct v4l2_fmtdesc *f)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- return zoran_enum_fmt(zr, f, ZORAN_FORMAT_PLAYBACK);
-}
-
-static int zoran_enum_fmt_vid_overlay(struct file *file, void *__fh,
- struct v4l2_fmtdesc *f)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- return zoran_enum_fmt(zr, f, ZORAN_FORMAT_OVERLAY);
-}
-
-static int zoran_g_fmt_vid_out(struct file *file, void *__fh,
- struct v4l2_format *fmt)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- mutex_lock(&zr->resource_lock);
-
- fmt->fmt.pix.width = fh->jpg_settings.img_width / fh->jpg_settings.HorDcm;
- fmt->fmt.pix.height = fh->jpg_settings.img_height * 2 /
- (fh->jpg_settings.VerDcm * fh->jpg_settings.TmpDcm);
- fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
- fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
- if (fh->jpg_settings.TmpDcm == 1)
- fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
- V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
- else
- fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
- V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
- fmt->fmt.pix.bytesperline = 0;
- fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-
- mutex_unlock(&zr->resource_lock);
- return 0;
-}
-
-static int zoran_g_fmt_vid_cap(struct file *file, void *__fh,
- struct v4l2_format *fmt)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- if (fh->map_mode != ZORAN_MAP_MODE_RAW)
- return zoran_g_fmt_vid_out(file, fh, fmt);
-
- mutex_lock(&zr->resource_lock);
- fmt->fmt.pix.width = fh->v4l_settings.width;
- fmt->fmt.pix.height = fh->v4l_settings.height;
- fmt->fmt.pix.sizeimage = fh->v4l_settings.bytesperline *
- fh->v4l_settings.height;
- fmt->fmt.pix.pixelformat = fh->v4l_settings.format->fourcc;
- fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace;
- fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline;
- if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2))
- fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
- else
- fmt->fmt.pix.field = V4L2_FIELD_TOP;
- mutex_unlock(&zr->resource_lock);
- return 0;
-}
-
-static int zoran_g_fmt_vid_overlay(struct file *file, void *__fh,
- struct v4l2_format *fmt)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- mutex_lock(&zr->resource_lock);
-
- fmt->fmt.win.w.left = fh->overlay_settings.x;
- fmt->fmt.win.w.top = fh->overlay_settings.y;
- fmt->fmt.win.w.width = fh->overlay_settings.width;
- fmt->fmt.win.w.height = fh->overlay_settings.height;
- if (fh->overlay_settings.width * 2 > BUZ_MAX_HEIGHT)
- fmt->fmt.win.field = V4L2_FIELD_INTERLACED;
- else
- fmt->fmt.win.field = V4L2_FIELD_TOP;
-
- mutex_unlock(&zr->resource_lock);
- return 0;
-}
-
-static int zoran_try_fmt_vid_overlay(struct file *file, void *__fh,
- struct v4l2_format *fmt)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- mutex_lock(&zr->resource_lock);
-
- if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH)
- fmt->fmt.win.w.width = BUZ_MAX_WIDTH;
- if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH)
- fmt->fmt.win.w.width = BUZ_MIN_WIDTH;
- if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT)
- fmt->fmt.win.w.height = BUZ_MAX_HEIGHT;
- if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT)
- fmt->fmt.win.w.height = BUZ_MIN_HEIGHT;
-
- mutex_unlock(&zr->resource_lock);
- return 0;
-}
-
-static int zoran_try_fmt_vid_out(struct file *file, void *__fh,
- struct v4l2_format *fmt)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- struct zoran_jpg_settings settings;
- int res = 0;
-
- if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
- return -EINVAL;
-
- mutex_lock(&zr->resource_lock);
- settings = fh->jpg_settings;
-
- /* we actually need to set 'real' parameters now */
- if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT)
- settings.TmpDcm = 1;
- else
- settings.TmpDcm = 2;
- settings.decimation = 0;
- if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2)
- settings.VerDcm = 2;
- else
- settings.VerDcm = 1;
- if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4)
- settings.HorDcm = 4;
- else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2)
- settings.HorDcm = 2;
- else
- settings.HorDcm = 1;
- if (settings.TmpDcm == 1)
- settings.field_per_buff = 2;
- else
- settings.field_per_buff = 1;
-
- if (settings.HorDcm > 1) {
- settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
- settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
- } else {
- settings.img_x = 0;
- settings.img_width = BUZ_MAX_WIDTH;
- }
-
- /* check */
- res = zoran_check_jpg_settings(zr, &settings, 1);
- if (res)
- goto tryfmt_unlock_and_return;
-
- /* tell the user what we actually did */
- fmt->fmt.pix.width = settings.img_width / settings.HorDcm;
- fmt->fmt.pix.height = settings.img_height * 2 /
- (settings.TmpDcm * settings.VerDcm);
- if (settings.TmpDcm == 1)
- fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
- V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
- else
- fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
- V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
-
- fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings);
- fmt->fmt.pix.bytesperline = 0;
- fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-tryfmt_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
-}
-
-static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
- struct v4l2_format *fmt)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int bpp;
- int i;
-
- if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
- return zoran_try_fmt_vid_out(file, fh, fmt);
-
- mutex_lock(&zr->resource_lock);
-
- for (i = 0; i < NUM_FORMATS; i++)
- if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat)
- break;
-
- if (i == NUM_FORMATS) {
- mutex_unlock(&zr->resource_lock);
- return -EINVAL;
- }
-
- bpp = DIV_ROUND_UP(zoran_formats[i].depth, 8);
- v4l_bound_align_image(
- &fmt->fmt.pix.width, BUZ_MIN_WIDTH, BUZ_MAX_WIDTH, bpp == 2 ? 1 : 2,
- &fmt->fmt.pix.height, BUZ_MIN_HEIGHT, BUZ_MAX_HEIGHT, 0, 0);
- mutex_unlock(&zr->resource_lock);
-
- return 0;
-}
-
-static int zoran_s_fmt_vid_overlay(struct file *file, void *__fh,
- struct v4l2_format *fmt)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int res;
-
- dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n",
- fmt->fmt.win.w.left, fmt->fmt.win.w.top,
- fmt->fmt.win.w.width,
- fmt->fmt.win.w.height,
- fmt->fmt.win.clipcount,
- fmt->fmt.win.bitmap);
- mutex_lock(&zr->resource_lock);
- res = setup_window(fh, fmt->fmt.win.w.left, fmt->fmt.win.w.top,
- fmt->fmt.win.w.width, fmt->fmt.win.w.height,
- (struct v4l2_clip __user *)fmt->fmt.win.clips,
- fmt->fmt.win.clipcount, fmt->fmt.win.bitmap);
- mutex_unlock(&zr->resource_lock);
- return res;
-}
-
-static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
- struct v4l2_format *fmt)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- __le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat);
- struct zoran_jpg_settings settings;
- int res = 0;
-
- dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n",
- fmt->fmt.pix.width, fmt->fmt.pix.height,
- fmt->fmt.pix.pixelformat,
- (char *) &printformat);
- if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
- return -EINVAL;
-
- mutex_lock(&zr->resource_lock);
-
- if (fh->buffers.allocated) {
- dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto sfmtjpg_unlock_and_return;
- }
-
- settings = fh->jpg_settings;
-
- /* we actually need to set 'real' parameters now */
- if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT)
- settings.TmpDcm = 1;
- else
- settings.TmpDcm = 2;
- settings.decimation = 0;
- if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2)
- settings.VerDcm = 2;
- else
- settings.VerDcm = 1;
- if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4)
- settings.HorDcm = 4;
- else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2)
- settings.HorDcm = 2;
- else
- settings.HorDcm = 1;
- if (settings.TmpDcm == 1)
- settings.field_per_buff = 2;
- else
- settings.field_per_buff = 1;
-
- if (settings.HorDcm > 1) {
- settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
- settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
- } else {
- settings.img_x = 0;
- settings.img_width = BUZ_MAX_WIDTH;
- }
-
- /* check */
- res = zoran_check_jpg_settings(zr, &settings, 0);
- if (res)
- goto sfmtjpg_unlock_and_return;
-
- /* it's ok, so set them */
- fh->jpg_settings = settings;
-
- map_mode_jpg(fh, fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT);
- fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
-
- /* tell the user what we actually did */
- fmt->fmt.pix.width = settings.img_width / settings.HorDcm;
- fmt->fmt.pix.height = settings.img_height * 2 /
- (settings.TmpDcm * settings.VerDcm);
- if (settings.TmpDcm == 1)
- fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
- V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
- else
- fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
- V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
- fmt->fmt.pix.bytesperline = 0;
- fmt->fmt.pix.sizeimage = fh->buffers.buffer_size;
- fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-
-sfmtjpg_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
-}
-
-static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
- struct v4l2_format *fmt)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int i;
- int res = 0;
-
- if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
- return zoran_s_fmt_vid_out(file, fh, fmt);
-
- for (i = 0; i < NUM_FORMATS; i++)
- if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc)
- break;
- if (i == NUM_FORMATS) {
- dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x\n",
- ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat);
- return -EINVAL;
- }
-
- mutex_lock(&zr->resource_lock);
-
- if ((fh->map_mode != ZORAN_MAP_MODE_RAW && fh->buffers.allocated) ||
- fh->buffers.active != ZORAN_FREE) {
- dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto sfmtv4l_unlock_and_return;
- }
- if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
- fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
- if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
- fmt->fmt.pix.width = BUZ_MAX_WIDTH;
-
- map_mode_raw(fh);
-
- res = zoran_v4l_set_format(fh, fmt->fmt.pix.width, fmt->fmt.pix.height,
- &zoran_formats[i]);
- if (res)
- goto sfmtv4l_unlock_and_return;
-
- /* tell the user the results/missing stuff */
- fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline;
- fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline;
- fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace;
- if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2))
- fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
- else
- fmt->fmt.pix.field = V4L2_FIELD_TOP;
-
-sfmtv4l_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
-}
-
-static int zoran_g_fbuf(struct file *file, void *__fh,
- struct v4l2_framebuffer *fb)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- memset(fb, 0, sizeof(*fb));
- mutex_lock(&zr->resource_lock);
- fb->base = zr->vbuf_base;
- fb->fmt.width = zr->vbuf_width;
- fb->fmt.height = zr->vbuf_height;
- if (zr->overlay_settings.format)
- fb->fmt.pixelformat = fh->overlay_settings.format->fourcc;
- fb->fmt.bytesperline = zr->vbuf_bytesperline;
- mutex_unlock(&zr->resource_lock);
- fb->fmt.colorspace = V4L2_COLORSPACE_SRGB;
- fb->fmt.field = V4L2_FIELD_INTERLACED;
- fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
-
- return 0;
-}
-
-static int zoran_s_fbuf(struct file *file, void *__fh,
- struct v4l2_framebuffer *fb)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int i, res = 0;
- __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat);
-
- for (i = 0; i < NUM_FORMATS; i++)
- if (zoran_formats[i].fourcc == fb->fmt.pixelformat)
- break;
- if (i == NUM_FORMATS) {
- dprintk(1, KERN_ERR "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n",
- ZR_DEVNAME(zr), fb->fmt.pixelformat,
- (char *)&printformat);
- return -EINVAL;
- }
-
- mutex_lock(&zr->resource_lock);
- res = setup_fbuffer(fh, fb->base, &zoran_formats[i], fb->fmt.width,
- fb->fmt.height, fb->fmt.bytesperline);
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-
-static int zoran_overlay(struct file *file, void *__fh, unsigned int on)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int res;
-
- mutex_lock(&zr->resource_lock);
- res = setup_overlay(fh, on);
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-
-static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type);
-
-static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *req)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int res = 0;
-
- if (req->memory != V4L2_MEMORY_MMAP) {
- dprintk(2,
- KERN_ERR
- "%s: only MEMORY_MMAP capture is supported, not %d\n",
- ZR_DEVNAME(zr), req->memory);
- return -EINVAL;
- }
-
- if (req->count == 0)
- return zoran_streamoff(file, fh, req->type);
-
- mutex_lock(&zr->resource_lock);
- if (fh->buffers.allocated) {
- dprintk(2,
- KERN_ERR
- "%s: VIDIOC_REQBUFS - buffers already allocated\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto v4l2reqbuf_unlock_and_return;
- }
-
- if (fh->map_mode == ZORAN_MAP_MODE_RAW &&
- req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- /* control user input */
- if (req->count < 2)
- req->count = 2;
- if (req->count > v4l_nbufs)
- req->count = v4l_nbufs;
-
- /* The next mmap will map the V4L buffers */
- map_mode_raw(fh);
- fh->buffers.num_buffers = req->count;
-
- if (v4l_fbuffer_alloc(fh)) {
- res = -ENOMEM;
- goto v4l2reqbuf_unlock_and_return;
- }
- } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC ||
- fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
- /* we need to calculate size ourselves now */
- if (req->count < 4)
- req->count = 4;
- if (req->count > jpg_nbufs)
- req->count = jpg_nbufs;
-
- /* The next mmap will map the MJPEG buffers */
- map_mode_jpg(fh, req->type == V4L2_BUF_TYPE_VIDEO_OUTPUT);
- fh->buffers.num_buffers = req->count;
- fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
-
- if (jpg_fbuffer_alloc(fh)) {
- res = -ENOMEM;
- goto v4l2reqbuf_unlock_and_return;
- }
- } else {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_REQBUFS - unknown type %d\n",
- ZR_DEVNAME(zr), req->type);
- res = -EINVAL;
- goto v4l2reqbuf_unlock_and_return;
- }
-v4l2reqbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-
-static int zoran_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int res;
-
- mutex_lock(&zr->resource_lock);
- res = zoran_v4l2_buffer_status(fh, buf, buf->index);
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-
-static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int res = 0, codec_mode, buf_type;
-
- mutex_lock(&zr->resource_lock);
-
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_RAW:
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- dprintk(1, KERN_ERR
- "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
- ZR_DEVNAME(zr), buf->type, fh->map_mode);
- res = -EINVAL;
- goto qbuf_unlock_and_return;
- }
-
- res = zoran_v4l_queue_frame(fh, buf->index);
- if (res)
- goto qbuf_unlock_and_return;
- if (!zr->v4l_memgrab_active && fh->buffers.active == ZORAN_LOCKED)
- zr36057_set_memgrab(zr, 1);
- break;
-
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
- if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
- buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- codec_mode = BUZ_MODE_MOTION_DECOMPRESS;
- } else {
- buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- codec_mode = BUZ_MODE_MOTION_COMPRESS;
- }
-
- if (buf->type != buf_type) {
- dprintk(1, KERN_ERR
- "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
- ZR_DEVNAME(zr), buf->type, fh->map_mode);
- res = -EINVAL;
- goto qbuf_unlock_and_return;
- }
-
- res = zoran_jpg_queue_frame(fh, buf->index, codec_mode);
- if (res != 0)
- goto qbuf_unlock_and_return;
- if (zr->codec_mode == BUZ_MODE_IDLE &&
- fh->buffers.active == ZORAN_LOCKED)
- zr36057_enable_jpg(zr, codec_mode);
-
- break;
-
- default:
- dprintk(1, KERN_ERR
- "%s: VIDIOC_QBUF - unsupported type %d\n",
- ZR_DEVNAME(zr), buf->type);
- res = -EINVAL;
- break;
- }
-qbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-
-static int zoran_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int res = 0, buf_type, num = -1; /* compiler borks here (?) */
-
- mutex_lock(&zr->resource_lock);
-
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_RAW:
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- dprintk(1, KERN_ERR
- "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
- ZR_DEVNAME(zr), buf->type, fh->map_mode);
- res = -EINVAL;
- goto dqbuf_unlock_and_return;
- }
-
- num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
- if (file->f_flags & O_NONBLOCK &&
- zr->v4l_buffers.buffer[num].state != BUZ_STATE_DONE) {
- res = -EAGAIN;
- goto dqbuf_unlock_and_return;
- }
- res = v4l_sync(fh, num);
- if (res)
- goto dqbuf_unlock_and_return;
- zr->v4l_sync_tail++;
- res = zoran_v4l2_buffer_status(fh, buf, num);
- break;
-
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
- {
- struct zoran_sync bs;
-
- if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY)
- buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- else
- buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- if (buf->type != buf_type) {
- dprintk(1, KERN_ERR
- "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
- ZR_DEVNAME(zr), buf->type, fh->map_mode);
- res = -EINVAL;
- goto dqbuf_unlock_and_return;
- }
-
- num = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
-
- if (file->f_flags & O_NONBLOCK &&
- zr->jpg_buffers.buffer[num].state != BUZ_STATE_DONE) {
- res = -EAGAIN;
- goto dqbuf_unlock_and_return;
- }
- bs.frame = 0; /* suppress compiler warning */
- res = jpg_sync(fh, &bs);
- if (res)
- goto dqbuf_unlock_and_return;
- res = zoran_v4l2_buffer_status(fh, buf, bs.frame);
- break;
- }
-
- default:
- dprintk(1, KERN_ERR
- "%s: VIDIOC_DQBUF - unsupported type %d\n",
- ZR_DEVNAME(zr), buf->type);
- res = -EINVAL;
- break;
- }
-dqbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-
-static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int res = 0;
-
- mutex_lock(&zr->resource_lock);
-
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_RAW: /* raw capture */
- if (zr->v4l_buffers.active != ZORAN_ACTIVE ||
- fh->buffers.active != ZORAN_ACTIVE) {
- res = -EBUSY;
- goto strmon_unlock_and_return;
- }
-
- zr->v4l_buffers.active = fh->buffers.active = ZORAN_LOCKED;
- zr->v4l_settings = fh->v4l_settings;
-
- zr->v4l_sync_tail = zr->v4l_pend_tail;
- if (!zr->v4l_memgrab_active &&
- zr->v4l_pend_head != zr->v4l_pend_tail) {
- zr36057_set_memgrab(zr, 1);
- }
- break;
-
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
- /* what is the codec mode right now? */
- if (zr->jpg_buffers.active != ZORAN_ACTIVE ||
- fh->buffers.active != ZORAN_ACTIVE) {
- res = -EBUSY;
- goto strmon_unlock_and_return;
- }
-
- zr->jpg_buffers.active = fh->buffers.active = ZORAN_LOCKED;
-
- if (zr->jpg_que_head != zr->jpg_que_tail) {
- /* Start the jpeg codec when the first frame is queued */
- jpeg_start(zr);
- }
- break;
-
- default:
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_STREAMON - invalid map mode %d\n",
- ZR_DEVNAME(zr), fh->map_mode);
- res = -EINVAL;
- break;
- }
-strmon_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-
-static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int i, res = 0;
- unsigned long flags;
-
- mutex_lock(&zr->resource_lock);
-
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_RAW: /* raw capture */
- if (fh->buffers.active == ZORAN_FREE &&
- zr->v4l_buffers.active != ZORAN_FREE) {
- res = -EPERM; /* stay off other's settings! */
- goto strmoff_unlock_and_return;
- }
- if (zr->v4l_buffers.active == ZORAN_FREE)
- goto strmoff_unlock_and_return;
-
- spin_lock_irqsave(&zr->spinlock, flags);
- /* unload capture */
- if (zr->v4l_memgrab_active) {
-
- zr36057_set_memgrab(zr, 0);
- }
-
- for (i = 0; i < fh->buffers.num_buffers; i++)
- zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER;
- fh->buffers = zr->v4l_buffers;
-
- zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
-
- zr->v4l_grab_seq = 0;
- zr->v4l_pend_head = zr->v4l_pend_tail = 0;
- zr->v4l_sync_tail = 0;
-
- spin_unlock_irqrestore(&zr->spinlock, flags);
-
- break;
-
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
- if (fh->buffers.active == ZORAN_FREE &&
- zr->jpg_buffers.active != ZORAN_FREE) {
- res = -EPERM; /* stay off other's settings! */
- goto strmoff_unlock_and_return;
- }
- if (zr->jpg_buffers.active == ZORAN_FREE)
- goto strmoff_unlock_and_return;
-
- res = jpg_qbuf(fh, -1,
- (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ?
- BUZ_MODE_MOTION_COMPRESS :
- BUZ_MODE_MOTION_DECOMPRESS);
- if (res)
- goto strmoff_unlock_and_return;
- break;
- default:
- dprintk(1, KERN_ERR
- "%s: VIDIOC_STREAMOFF - invalid map mode %d\n",
- ZR_DEVNAME(zr), fh->map_mode);
- res = -EINVAL;
- break;
- }
-strmoff_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-
-static int zoran_queryctrl(struct file *file, void *__fh,
- struct v4l2_queryctrl *ctrl)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- /* we only support hue/saturation/contrast/brightness */
- if (ctrl->id < V4L2_CID_BRIGHTNESS ||
- ctrl->id > V4L2_CID_HUE)
- return -EINVAL;
-
- decoder_call(zr, core, queryctrl, ctrl);
-
- return 0;
-}
-
-static int zoran_g_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- /* we only support hue/saturation/contrast/brightness */
- if (ctrl->id < V4L2_CID_BRIGHTNESS ||
- ctrl->id > V4L2_CID_HUE)
- return -EINVAL;
-
- mutex_lock(&zr->resource_lock);
- decoder_call(zr, core, g_ctrl, ctrl);
- mutex_unlock(&zr->resource_lock);
-
- return 0;
-}
-
-static int zoran_s_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- /* we only support hue/saturation/contrast/brightness */
- if (ctrl->id < V4L2_CID_BRIGHTNESS ||
- ctrl->id > V4L2_CID_HUE)
- return -EINVAL;
-
- mutex_lock(&zr->resource_lock);
- decoder_call(zr, core, s_ctrl, ctrl);
- mutex_unlock(&zr->resource_lock);
-
- return 0;
-}
-
-static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- mutex_lock(&zr->resource_lock);
- *std = zr->norm;
- mutex_unlock(&zr->resource_lock);
- return 0;
-}
-
-static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int res = 0;
-
- mutex_lock(&zr->resource_lock);
- res = zoran_set_norm(zr, *std);
- if (res)
- goto sstd_unlock_and_return;
-
- res = wait_grab_pending(zr);
-sstd_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
-}
-
-static int zoran_enum_input(struct file *file, void *__fh,
- struct v4l2_input *inp)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- if (inp->index >= zr->card.inputs)
- return -EINVAL;
-
- strncpy(inp->name, zr->card.input[inp->index].name,
- sizeof(inp->name) - 1);
- inp->type = V4L2_INPUT_TYPE_CAMERA;
- inp->std = V4L2_STD_ALL;
-
- /* Get status of video decoder */
- mutex_lock(&zr->resource_lock);
- decoder_call(zr, video, g_input_status, &inp->status);
- mutex_unlock(&zr->resource_lock);
- return 0;
-}
-
-static int zoran_g_input(struct file *file, void *__fh, unsigned int *input)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
-
- mutex_lock(&zr->resource_lock);
- *input = zr->input;
- mutex_unlock(&zr->resource_lock);
-
- return 0;
-}
-
-static int zoran_s_input(struct file *file, void *__fh, unsigned int input)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int res;
-
- mutex_lock(&zr->resource_lock);
- res = zoran_set_input(zr, input);
- if (res)
- goto sinput_unlock_and_return;
-
- /* Make sure the changes come into effect */
- res = wait_grab_pending(zr);
-sinput_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
-}
-
-static int zoran_enum_output(struct file *file, void *__fh,
- struct v4l2_output *outp)
-{
- if (outp->index != 0)
- return -EINVAL;
-
- outp->index = 0;
- outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
- strncpy(outp->name, "Autodetect", sizeof(outp->name)-1);
-
- return 0;
-}
-
-static int zoran_g_output(struct file *file, void *__fh, unsigned int *output)
-{
- *output = 0;
-
- return 0;
-}
-
-static int zoran_s_output(struct file *file, void *__fh, unsigned int output)
-{
- if (output != 0)
- return -EINVAL;
-
- return 0;
-}
-
-/* cropping (sub-frame capture) */
-static int zoran_cropcap(struct file *file, void *__fh,
- struct v4l2_cropcap *cropcap)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int type = cropcap->type, res = 0;
-
- memset(cropcap, 0, sizeof(*cropcap));
- cropcap->type = type;
-
- mutex_lock(&zr->resource_lock);
-
- if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- fh->map_mode == ZORAN_MAP_MODE_RAW)) {
- dprintk(1, KERN_ERR
- "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto cropcap_unlock_and_return;
- }
-
- cropcap->bounds.top = cropcap->bounds.left = 0;
- cropcap->bounds.width = BUZ_MAX_WIDTH;
- cropcap->bounds.height = BUZ_MAX_HEIGHT;
- cropcap->defrect.top = cropcap->defrect.left = 0;
- cropcap->defrect.width = BUZ_MIN_WIDTH;
- cropcap->defrect.height = BUZ_MIN_HEIGHT;
-cropcap_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
-}
-
-static int zoran_g_crop(struct file *file, void *__fh, struct v4l2_crop *crop)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int type = crop->type, res = 0;
-
- memset(crop, 0, sizeof(*crop));
- crop->type = type;
-
- mutex_lock(&zr->resource_lock);
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- fh->map_mode == ZORAN_MAP_MODE_RAW)) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto gcrop_unlock_and_return;
- }
-
- crop->c.top = fh->jpg_settings.img_y;
- crop->c.left = fh->jpg_settings.img_x;
- crop->c.width = fh->jpg_settings.img_width;
- crop->c.height = fh->jpg_settings.img_height;
-
-gcrop_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-
-static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int res = 0;
- struct zoran_jpg_settings settings;
-
- settings = fh->jpg_settings;
-
- mutex_lock(&zr->resource_lock);
-
- if (fh->buffers.allocated) {
- dprintk(1, KERN_ERR
- "%s: VIDIOC_S_CROP - cannot change settings while active\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto scrop_unlock_and_return;
- }
-
- if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- fh->map_mode == ZORAN_MAP_MODE_RAW)) {
- dprintk(1, KERN_ERR
- "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto scrop_unlock_and_return;
- }
-
- /* move into a form that we understand */
- settings.img_x = crop->c.left;
- settings.img_y = crop->c.top;
- settings.img_width = crop->c.width;
- settings.img_height = crop->c.height;
-
- /* check validity */
- res = zoran_check_jpg_settings(zr, &settings, 0);
- if (res)
- goto scrop_unlock_and_return;
-
- /* accept */
- fh->jpg_settings = settings;
-
-scrop_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
-}
-
-static int zoran_g_jpegcomp(struct file *file, void *__fh,
- struct v4l2_jpegcompression *params)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- memset(params, 0, sizeof(*params));
-
- mutex_lock(&zr->resource_lock);
-
- params->quality = fh->jpg_settings.jpg_comp.quality;
- params->APPn = fh->jpg_settings.jpg_comp.APPn;
- memcpy(params->APP_data,
- fh->jpg_settings.jpg_comp.APP_data,
- fh->jpg_settings.jpg_comp.APP_len);
- params->APP_len = fh->jpg_settings.jpg_comp.APP_len;
- memcpy(params->COM_data,
- fh->jpg_settings.jpg_comp.COM_data,
- fh->jpg_settings.jpg_comp.COM_len);
- params->COM_len = fh->jpg_settings.jpg_comp.COM_len;
- params->jpeg_markers =
- fh->jpg_settings.jpg_comp.jpeg_markers;
-
- mutex_unlock(&zr->resource_lock);
-
- return 0;
-}
-
-static int zoran_s_jpegcomp(struct file *file, void *__fh,
- struct v4l2_jpegcompression *params)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int res = 0;
- struct zoran_jpg_settings settings;
-
- settings = fh->jpg_settings;
-
- settings.jpg_comp = *params;
-
- mutex_lock(&zr->resource_lock);
-
- if (fh->buffers.active != ZORAN_FREE) {
- dprintk(1, KERN_WARNING
- "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto sjpegc_unlock_and_return;
- }
-
- res = zoran_check_jpg_settings(zr, &settings, 0);
- if (res)
- goto sjpegc_unlock_and_return;
- if (!fh->buffers.allocated)
- fh->buffers.buffer_size =
- zoran_v4l2_calc_bufsize(&fh->jpg_settings);
- fh->jpg_settings.jpg_comp = *params = settings.jpg_comp;
-sjpegc_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-
-static unsigned int
-zoran_poll (struct file *file,
- poll_table *wait)
-{
- struct zoran_fh *fh = file->private_data;
- struct zoran *zr = fh->zr;
- int res = 0, frame;
- unsigned long flags;
-
- /* we should check whether buffers are ready to be synced on
- * (w/o waits - O_NONBLOCK) here
- * if ready for read (sync), return POLLIN|POLLRDNORM,
- * if ready for write (sync), return POLLOUT|POLLWRNORM,
- * if error, return POLLERR,
- * if no buffers queued or so, return POLLNVAL
- */
-
- mutex_lock(&zr->resource_lock);
-
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_RAW:
- poll_wait(file, &zr->v4l_capq, wait);
- frame = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
-
- spin_lock_irqsave(&zr->spinlock, flags);
- dprintk(3,
- KERN_DEBUG
- "%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n",
- ZR_DEVNAME(zr), __func__,
- "FAL"[fh->buffers.active], zr->v4l_sync_tail,
- "UPMD"[zr->v4l_buffers.buffer[frame].state],
- zr->v4l_pend_tail, zr->v4l_pend_head);
- /* Process is the one capturing? */
- if (fh->buffers.active != ZORAN_FREE &&
- /* Buffer ready to DQBUF? */
- zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE)
- res = POLLIN | POLLRDNORM;
- spin_unlock_irqrestore(&zr->spinlock, flags);
-
- break;
-
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
- poll_wait(file, &zr->jpg_capq, wait);
- frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
-
- spin_lock_irqsave(&zr->spinlock, flags);
- dprintk(3,
- KERN_DEBUG
- "%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n",
- ZR_DEVNAME(zr), __func__,
- "FAL"[fh->buffers.active], zr->jpg_que_tail,
- "UPMD"[zr->jpg_buffers.buffer[frame].state],
- zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head);
- if (fh->buffers.active != ZORAN_FREE &&
- zr->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) {
- if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC)
- res = POLLIN | POLLRDNORM;
- else
- res = POLLOUT | POLLWRNORM;
- }
- spin_unlock_irqrestore(&zr->spinlock, flags);
-
- break;
-
- default:
- dprintk(1,
- KERN_ERR
- "%s: %s - internal error, unknown map_mode=%d\n",
- ZR_DEVNAME(zr), __func__, fh->map_mode);
- res = POLLNVAL;
- }
-
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-
-
-/*
- * This maps the buffers to user space.
- *
- * Depending on the state of fh->map_mode
- * the V4L or the MJPEG buffers are mapped
- * per buffer or all together
- *
- * Note that we need to connect to some
- * unmap signal event to unmap the de-allocate
- * the buffer accordingly (zoran_vm_close())
- */
-
-static void
-zoran_vm_open (struct vm_area_struct *vma)
-{
- struct zoran_mapping *map = vma->vm_private_data;
-
- map->count++;
-}
-
-static void
-zoran_vm_close (struct vm_area_struct *vma)
-{
- struct zoran_mapping *map = vma->vm_private_data;
- struct zoran_fh *fh = map->fh;
- struct zoran *zr = fh->zr;
- int i;
-
- if (--map->count > 0)
- return;
-
- dprintk(3, KERN_INFO "%s: %s - munmap(%s)\n", ZR_DEVNAME(zr),
- __func__, mode_name(fh->map_mode));
-
- for (i = 0; i < fh->buffers.num_buffers; i++) {
- if (fh->buffers.buffer[i].map == map)
- fh->buffers.buffer[i].map = NULL;
- }
- kfree(map);
-
- /* Any buffers still mapped? */
- for (i = 0; i < fh->buffers.num_buffers; i++)
- if (fh->buffers.buffer[i].map)
- return;
-
- dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr),
- __func__, mode_name(fh->map_mode));
-
- mutex_lock(&zr->resource_lock);
-
- if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
- if (fh->buffers.active != ZORAN_FREE) {
- unsigned long flags;
-
- spin_lock_irqsave(&zr->spinlock, flags);
- zr36057_set_memgrab(zr, 0);
- zr->v4l_buffers.allocated = 0;
- zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
- spin_unlock_irqrestore(&zr->spinlock, flags);
- }
- v4l_fbuffer_free(fh);
- } else {
- if (fh->buffers.active != ZORAN_FREE) {
- jpg_qbuf(fh, -1, zr->codec_mode);
- zr->jpg_buffers.allocated = 0;
- zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE;
- }
- jpg_fbuffer_free(fh);
- }
-
- mutex_unlock(&zr->resource_lock);
-}
-
-static const struct vm_operations_struct zoran_vm_ops = {
- .open = zoran_vm_open,
- .close = zoran_vm_close,
-};
-
-static int
-zoran_mmap (struct file *file,
- struct vm_area_struct *vma)
-{
- struct zoran_fh *fh = file->private_data;
- struct zoran *zr = fh->zr;
- unsigned long size = (vma->vm_end - vma->vm_start);
- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
- int i, j;
- unsigned long page, start = vma->vm_start, todo, pos, fraglen;
- int first, last;
- struct zoran_mapping *map;
- int res = 0;
-
- dprintk(3,
- KERN_INFO "%s: %s(%s) of 0x%08lx-0x%08lx (size=%lu)\n",
- ZR_DEVNAME(zr), __func__,
- mode_name(fh->map_mode), vma->vm_start, vma->vm_end, size);
-
- if (!(vma->vm_flags & VM_SHARED) || !(vma->vm_flags & VM_READ) ||
- !(vma->vm_flags & VM_WRITE)) {
- dprintk(1,
- KERN_ERR
- "%s: %s - no MAP_SHARED/PROT_{READ,WRITE} given\n",
- ZR_DEVNAME(zr), __func__);
- return -EINVAL;
- }
-
- mutex_lock(&zr->resource_lock);
-
- if (!fh->buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: %s(%s) - buffers not yet allocated\n",
- ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode));
- res = -ENOMEM;
- goto mmap_unlock_and_return;
- }
-
- first = offset / fh->buffers.buffer_size;
- last = first - 1 + size / fh->buffers.buffer_size;
- if (offset % fh->buffers.buffer_size != 0 ||
- size % fh->buffers.buffer_size != 0 || first < 0 ||
- last < 0 || first >= fh->buffers.num_buffers ||
- last >= fh->buffers.buffer_size) {
- dprintk(1,
- KERN_ERR
- "%s: %s(%s) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
- ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode), offset, size,
- fh->buffers.buffer_size,
- fh->buffers.num_buffers);
- res = -EINVAL;
- goto mmap_unlock_and_return;
- }
-
- /* Check if any buffers are already mapped */
- for (i = first; i <= last; i++) {
- if (fh->buffers.buffer[i].map) {
- dprintk(1,
- KERN_ERR
- "%s: %s(%s) - buffer %d already mapped\n",
- ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode), i);
- res = -EBUSY;
- goto mmap_unlock_and_return;
- }
- }
-
- /* map these buffers */
- map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
- if (!map) {
- res = -ENOMEM;
- goto mmap_unlock_and_return;
- }
- map->fh = fh;
- map->count = 1;
-
- vma->vm_ops = &zoran_vm_ops;
- vma->vm_flags |= VM_DONTEXPAND;
- vma->vm_private_data = map;
-
- if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
- for (i = first; i <= last; i++) {
- todo = size;
- if (todo > fh->buffers.buffer_size)
- todo = fh->buffers.buffer_size;
- page = fh->buffers.buffer[i].v4l.fbuffer_phys;
- if (remap_pfn_range(vma, start, page >> PAGE_SHIFT,
- todo, PAGE_SHARED)) {
- dprintk(1,
- KERN_ERR
- "%s: %s(V4L) - remap_pfn_range failed\n",
- ZR_DEVNAME(zr), __func__);
- res = -EAGAIN;
- goto mmap_unlock_and_return;
- }
- size -= todo;
- start += todo;
- fh->buffers.buffer[i].map = map;
- if (size == 0)
- break;
- }
- } else {
- for (i = first; i <= last; i++) {
- for (j = 0;
- j < fh->buffers.buffer_size / PAGE_SIZE;
- j++) {
- fraglen =
- (le32_to_cpu(fh->buffers.buffer[i].jpg.
- frag_tab[2 * j + 1]) & ~1) << 1;
- todo = size;
- if (todo > fraglen)
- todo = fraglen;
- pos =
- le32_to_cpu(fh->buffers.
- buffer[i].jpg.frag_tab[2 * j]);
- /* should just be pos on i386 */
- page = virt_to_phys(bus_to_virt(pos))
- >> PAGE_SHIFT;
- if (remap_pfn_range(vma, start, page,
- todo, PAGE_SHARED)) {
- dprintk(1,
- KERN_ERR
- "%s: %s(V4L) - remap_pfn_range failed\n",
- ZR_DEVNAME(zr), __func__);
- res = -EAGAIN;
- goto mmap_unlock_and_return;
- }
- size -= todo;
- start += todo;
- if (size == 0)
- break;
- if (le32_to_cpu(fh->buffers.buffer[i].jpg.
- frag_tab[2 * j + 1]) & 1)
- break; /* was last fragment */
- }
- fh->buffers.buffer[i].map = map;
- if (size == 0)
- break;
-
- }
- }
-
-mmap_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-
-static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
- .vidioc_querycap = zoran_querycap,
- .vidioc_cropcap = zoran_cropcap,
- .vidioc_s_crop = zoran_s_crop,
- .vidioc_g_crop = zoran_g_crop,
- .vidioc_enum_input = zoran_enum_input,
- .vidioc_g_input = zoran_g_input,
- .vidioc_s_input = zoran_s_input,
- .vidioc_enum_output = zoran_enum_output,
- .vidioc_g_output = zoran_g_output,
- .vidioc_s_output = zoran_s_output,
- .vidioc_g_fbuf = zoran_g_fbuf,
- .vidioc_s_fbuf = zoran_s_fbuf,
- .vidioc_g_std = zoran_g_std,
- .vidioc_s_std = zoran_s_std,
- .vidioc_g_jpegcomp = zoran_g_jpegcomp,
- .vidioc_s_jpegcomp = zoran_s_jpegcomp,
- .vidioc_overlay = zoran_overlay,
- .vidioc_reqbufs = zoran_reqbufs,
- .vidioc_querybuf = zoran_querybuf,
- .vidioc_qbuf = zoran_qbuf,
- .vidioc_dqbuf = zoran_dqbuf,
- .vidioc_streamon = zoran_streamon,
- .vidioc_streamoff = zoran_streamoff,
- .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap,
- .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out,
- .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay,
- .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap,
- .vidioc_g_fmt_vid_out = zoran_g_fmt_vid_out,
- .vidioc_g_fmt_vid_overlay = zoran_g_fmt_vid_overlay,
- .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap,
- .vidioc_s_fmt_vid_out = zoran_s_fmt_vid_out,
- .vidioc_s_fmt_vid_overlay = zoran_s_fmt_vid_overlay,
- .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap,
- .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out,
- .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay,
- .vidioc_queryctrl = zoran_queryctrl,
- .vidioc_s_ctrl = zoran_s_ctrl,
- .vidioc_g_ctrl = zoran_g_ctrl,
-};
-
-/* please use zr->resource_lock consistently and kill this wrapper */
-static long zoran_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct zoran_fh *fh = file->private_data;
- struct zoran *zr = fh->zr;
- int ret;
-
- mutex_lock(&zr->other_lock);
- ret = video_ioctl2(file, cmd, arg);
- mutex_unlock(&zr->other_lock);
-
- return ret;
-}
-
-static const struct v4l2_file_operations zoran_fops = {
- .owner = THIS_MODULE,
- .open = zoran_open,
- .release = zoran_close,
- .unlocked_ioctl = zoran_ioctl,
- .read = zoran_read,
- .write = zoran_write,
- .mmap = zoran_mmap,
- .poll = zoran_poll,
-};
-
-struct video_device zoran_template __devinitdata = {
- .name = ZORAN_NAME,
- .fops = &zoran_fops,
- .ioctl_ops = &zoran_ioctl_ops,
- .release = &zoran_vdev_release,
- .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
-};
-
diff --git a/drivers/media/video/zoran/zoran_procfs.c b/drivers/media/video/zoran/zoran_procfs.c
deleted file mode 100644
index f1423b777db..00000000000
--- a/drivers/media/video/zoran/zoran_procfs.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Zoran zr36057/zr36067 PCI controller driver, for the
- * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
- * Media Labs LML33/LML33R10.
- *
- * This part handles the procFS entries (/proc/ZORAN[%d])
- *
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- *
- * Currently maintained by:
- * Ronald Bultje <rbultje@ronald.bitfreak.net>
- * Laurent Pinchart <laurent.pinchart@skynet.be>
- * Mailinglist <mjpeg-users@lists.sf.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-
-#include <linux/proc_fs.h>
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/videodev2.h>
-#include <linux/spinlock.h>
-#include <linux/sem.h>
-#include <linux/seq_file.h>
-
-#include <linux/ctype.h>
-#include <linux/poll.h>
-#include <asm/io.h>
-
-#include "videocodec.h"
-#include "zoran.h"
-#include "zoran_procfs.h"
-#include "zoran_card.h"
-
-#ifdef CONFIG_PROC_FS
-struct procfs_params_zr36067 {
- char *name;
- short reg;
- u32 mask;
- short bit;
-};
-
-static const struct procfs_params_zr36067 zr67[] = {
- {"HSPol", 0x000, 1, 30},
- {"HStart", 0x000, 0x3ff, 10},
- {"HEnd", 0x000, 0x3ff, 0},
-
- {"VSPol", 0x004, 1, 30},
- {"VStart", 0x004, 0x3ff, 10},
- {"VEnd", 0x004, 0x3ff, 0},
-
- {"ExtFl", 0x008, 1, 26},
- {"TopField", 0x008, 1, 25},
- {"VCLKPol", 0x008, 1, 24},
- {"DupFld", 0x008, 1, 20},
- {"LittleEndian", 0x008, 1, 0},
-
- {"HsyncStart", 0x10c, 0xffff, 16},
- {"LineTot", 0x10c, 0xffff, 0},
-
- {"NAX", 0x110, 0xffff, 16},
- {"PAX", 0x110, 0xffff, 0},
-
- {"NAY", 0x114, 0xffff, 16},
- {"PAY", 0x114, 0xffff, 0},
-
- /* {"",,,}, */
-
- {NULL, 0, 0, 0},
-};
-
-static void
-setparam (struct zoran *zr,
- char *name,
- char *sval)
-{
- int i = 0, reg0, reg, val;
-
- while (zr67[i].name != NULL) {
- if (!strncmp(name, zr67[i].name, strlen(zr67[i].name))) {
- reg = reg0 = btread(zr67[i].reg);
- reg &= ~(zr67[i].mask << zr67[i].bit);
- if (!isdigit(sval[0]))
- break;
- val = simple_strtoul(sval, NULL, 0);
- if ((val & ~zr67[i].mask))
- break;
- reg |= (val & zr67[i].mask) << zr67[i].bit;
- dprintk(4,
- KERN_INFO
- "%s: setparam: setting ZR36067 register 0x%03x: 0x%08x=>0x%08x %s=%d\n",
- ZR_DEVNAME(zr), zr67[i].reg, reg0, reg,
- zr67[i].name, val);
- btwrite(reg, zr67[i].reg);
- break;
- }
- i++;
- }
-}
-
-static int zoran_show(struct seq_file *p, void *v)
-{
- struct zoran *zr = p->private;
- int i;
-
- seq_printf(p, "ZR36067 registers:\n");
- for (i = 0; i < 0x130; i += 16)
- seq_printf(p, "%03X %08X %08X %08X %08X \n", i,
- btread(i), btread(i+4), btread(i+8), btread(i+12));
- return 0;
-}
-
-static int zoran_open(struct inode *inode, struct file *file)
-{
- struct zoran *data = PDE(inode)->data;
- return single_open(file, zoran_show, data);
-}
-
-static ssize_t zoran_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- struct zoran *zr = PDE(file->f_path.dentry->d_inode)->data;
- char *string, *sp;
- char *line, *ldelim, *varname, *svar, *tdelim;
-
- if (count > 32768) /* Stupidity filter */
- return -EINVAL;
-
- string = sp = vmalloc(count + 1);
- if (!string) {
- dprintk(1,
- KERN_ERR
- "%s: write_proc: can not allocate memory\n",
- ZR_DEVNAME(zr));
- return -ENOMEM;
- }
- if (copy_from_user(string, buffer, count)) {
- vfree (string);
- return -EFAULT;
- }
- string[count] = 0;
- dprintk(4, KERN_INFO "%s: write_proc: name=%s count=%zu zr=%p\n",
- ZR_DEVNAME(zr), file->f_path.dentry->d_name.name, count, zr);
- ldelim = " \t\n";
- tdelim = "=";
- line = strpbrk(sp, ldelim);
- while (line) {
- *line = 0;
- svar = strpbrk(sp, tdelim);
- if (svar) {
- *svar = 0;
- varname = sp;
- svar++;
- setparam(zr, varname, svar);
- }
- sp = line + 1;
- line = strpbrk(sp, ldelim);
- }
- vfree(string);
-
- return count;
-}
-
-static const struct file_operations zoran_operations = {
- .owner = THIS_MODULE,
- .open = zoran_open,
- .read = seq_read,
- .write = zoran_write,
- .llseek = seq_lseek,
- .release = single_release,
-};
-#endif
-
-int
-zoran_proc_init (struct zoran *zr)
-{
-#ifdef CONFIG_PROC_FS
- char name[8];
-
- snprintf(name, 7, "zoran%d", zr->id);
- zr->zoran_proc = proc_create_data(name, 0, NULL, &zoran_operations, zr);
- if (zr->zoran_proc != NULL) {
- dprintk(2,
- KERN_INFO
- "%s: procfs entry /proc/%s allocated. data=%p\n",
- ZR_DEVNAME(zr), name, zr->zoran_proc->data);
- } else {
- dprintk(1, KERN_ERR "%s: Unable to initialise /proc/%s\n",
- ZR_DEVNAME(zr), name);
- return 1;
- }
-#endif
- return 0;
-}
-
-void
-zoran_proc_cleanup (struct zoran *zr)
-{
-#ifdef CONFIG_PROC_FS
- char name[8];
-
- snprintf(name, 7, "zoran%d", zr->id);
- if (zr->zoran_proc)
- remove_proc_entry(name, NULL);
- zr->zoran_proc = NULL;
-#endif
-}
diff --git a/drivers/media/video/zoran/zoran_procfs.h b/drivers/media/video/zoran/zoran_procfs.h
deleted file mode 100644
index f2d5b1ba448..00000000000
--- a/drivers/media/video/zoran/zoran_procfs.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Zoran zr36057/zr36067 PCI controller driver, for the
- * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
- * Media Labs LML33/LML33R10.
- *
- * This part handles card-specific data and detection
- *
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- *
- * Currently maintained by:
- * Ronald Bultje <rbultje@ronald.bitfreak.net>
- * Laurent Pinchart <laurent.pinchart@skynet.be>
- * Mailinglist <mjpeg-users@lists.sf.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ZORAN_PROCFS_H__
-#define __ZORAN_PROCFS_H__
-
-extern int zoran_proc_init(struct zoran *zr);
-extern void zoran_proc_cleanup(struct zoran *zr);
-
-#endif /* __ZORAN_PROCFS_H__ */
diff --git a/drivers/media/video/zoran/zr36016.c b/drivers/media/video/zoran/zr36016.c
deleted file mode 100644
index b87ddba8608..00000000000
--- a/drivers/media/video/zoran/zr36016.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- * Zoran ZR36016 basic configuration functions
- *
- * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
- *
- * $Id: zr36016.c,v 1.1.2.14 2003/08/20 19:46:55 rbultje Exp $
- *
- * ------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * ------------------------------------------------------------------------
- */
-
-#define ZR016_VERSION "v0.7"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-#include <linux/types.h>
-#include <linux/wait.h>
-
-/* I/O commands, error codes */
-#include <asm/io.h>
-
-/* v4l API */
-
-/* headerfile of this module */
-#include "zr36016.h"
-
-/* codec io API */
-#include "videocodec.h"
-
-/* it doesn't make sense to have more than 20 or so,
- just to prevent some unwanted loops */
-#define MAX_CODECS 20
-
-/* amount of chips attached via this driver */
-static int zr36016_codecs;
-
-/* debugging is available via module parameter */
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-4)");
-
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
-/* =========================================================================
- Local hardware I/O functions:
-
- read/write via codec layer (registers are located in the master device)
- ========================================================================= */
-
-/* read and write functions */
-static u8
-zr36016_read (struct zr36016 *ptr,
- u16 reg)
-{
- u8 value = 0;
-
- // just in case something is wrong...
- if (ptr->codec->master_data->readreg)
- value =
- (ptr->codec->master_data->
- readreg(ptr->codec, reg)) & 0xFF;
- else
- dprintk(1,
- KERN_ERR "%s: invalid I/O setup, nothing read!\n",
- ptr->name);
-
- dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg,
- value);
-
- return value;
-}
-
-static void
-zr36016_write (struct zr36016 *ptr,
- u16 reg,
- u8 value)
-{
- dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value,
- reg);
-
- // just in case something is wrong...
- if (ptr->codec->master_data->writereg) {
- ptr->codec->master_data->writereg(ptr->codec, reg, value);
- } else
- dprintk(1,
- KERN_ERR
- "%s: invalid I/O setup, nothing written!\n",
- ptr->name);
-}
-
-/* indirect read and write functions */
-/* the 016 supports auto-addr-increment, but
- * writing it all time cost not much and is safer... */
-static u8
-zr36016_readi (struct zr36016 *ptr,
- u16 reg)
-{
- u8 value = 0;
-
- // just in case something is wrong...
- if ((ptr->codec->master_data->writereg) &&
- (ptr->codec->master_data->readreg)) {
- ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F); // ADDR
- value = (ptr->codec->master_data->readreg(ptr->codec, ZR016_IDATA)) & 0xFF; // DATA
- } else
- dprintk(1,
- KERN_ERR
- "%s: invalid I/O setup, nothing read (i)!\n",
- ptr->name);
-
- dprintk(4, "%s: reading indirect from 0x%04x: %02x\n", ptr->name,
- reg, value);
- return value;
-}
-
-static void
-zr36016_writei (struct zr36016 *ptr,
- u16 reg,
- u8 value)
-{
- dprintk(4, "%s: writing indirect 0x%02x to 0x%04x\n", ptr->name,
- value, reg);
-
- // just in case something is wrong...
- if (ptr->codec->master_data->writereg) {
- ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F); // ADDR
- ptr->codec->master_data->writereg(ptr->codec, ZR016_IDATA, value & 0x0FF); // DATA
- } else
- dprintk(1,
- KERN_ERR
- "%s: invalid I/O setup, nothing written (i)!\n",
- ptr->name);
-}
-
-/* =========================================================================
- Local helper function:
-
- version read
- ========================================================================= */
-
-/* version kept in datastructure */
-static u8
-zr36016_read_version (struct zr36016 *ptr)
-{
- ptr->version = zr36016_read(ptr, 0) >> 4;
- return ptr->version;
-}
-
-/* =========================================================================
- Local helper function:
-
- basic test of "connectivity", writes/reads to/from PAX-Lo register
- ========================================================================= */
-
-static int
-zr36016_basic_test (struct zr36016 *ptr)
-{
- if (debug) {
- int i;
- zr36016_writei(ptr, ZR016I_PAX_LO, 0x55);
- dprintk(1, KERN_INFO "%s: registers: ", ptr->name);
- for (i = 0; i <= 0x0b; i++)
- dprintk(1, "%02x ", zr36016_readi(ptr, i));
- dprintk(1, "\n");
- }
- // for testing just write 0, then the default value to a register and read
- // it back in both cases
- zr36016_writei(ptr, ZR016I_PAX_LO, 0x00);
- if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0) {
- dprintk(1,
- KERN_ERR
- "%s: attach failed, can't connect to vfe processor!\n",
- ptr->name);
- return -ENXIO;
- }
- zr36016_writei(ptr, ZR016I_PAX_LO, 0x0d0);
- if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0d0) {
- dprintk(1,
- KERN_ERR
- "%s: attach failed, can't connect to vfe processor!\n",
- ptr->name);
- return -ENXIO;
- }
- // we allow version numbers from 0-3, should be enough, though
- zr36016_read_version(ptr);
- if (ptr->version & 0x0c) {
- dprintk(1,
- KERN_ERR
- "%s: attach failed, suspicious version %d found...\n",
- ptr->name, ptr->version);
- return -ENXIO;
- }
-
- return 0; /* looks good! */
-}
-
-/* =========================================================================
- Local helper function:
-
- simple loop for pushing the init datasets - NO USE --
- ========================================================================= */
-
-#if 0
-static int zr36016_pushit (struct zr36016 *ptr,
- u16 startreg,
- u16 len,
- const char *data)
-{
- int i=0;
-
- dprintk(4, "%s: write data block to 0x%04x (len=%d)\n",
- ptr->name, startreg,len);
- while (i<len) {
- zr36016_writei(ptr, startreg++, data[i++]);
- }
-
- return i;
-}
-#endif
-
-/* =========================================================================
- Basic datasets & init:
-
- //TODO//
- ========================================================================= */
-
-// needed offset values PAL NTSC SECAM
-static const int zr016_xoff[] = { 20, 20, 20 };
-static const int zr016_yoff[] = { 8, 9, 7 };
-
-static void
-zr36016_init (struct zr36016 *ptr)
-{
- // stop any processing
- zr36016_write(ptr, ZR016_GOSTOP, 0);
-
- // mode setup (yuv422 in and out, compression/expansuon due to mode)
- zr36016_write(ptr, ZR016_MODE,
- ZR016_YUV422 | ZR016_YUV422_YUV422 |
- (ptr->mode == CODEC_DO_COMPRESSION ?
- ZR016_COMPRESSION : ZR016_EXPANSION));
-
- // misc setup
- zr36016_writei(ptr, ZR016I_SETUP1,
- (ptr->xdec ? (ZR016_HRFL | ZR016_HORZ) : 0) |
- (ptr->ydec ? ZR016_VERT : 0) | ZR016_CNTI);
- zr36016_writei(ptr, ZR016I_SETUP2, ZR016_CCIR);
-
- // Window setup
- // (no extra offset for now, norm defines offset, default width height)
- zr36016_writei(ptr, ZR016I_PAX_HI, ptr->width >> 8);
- zr36016_writei(ptr, ZR016I_PAX_LO, ptr->width & 0xFF);
- zr36016_writei(ptr, ZR016I_PAY_HI, ptr->height >> 8);
- zr36016_writei(ptr, ZR016I_PAY_LO, ptr->height & 0xFF);
- zr36016_writei(ptr, ZR016I_NAX_HI, ptr->xoff >> 8);
- zr36016_writei(ptr, ZR016I_NAX_LO, ptr->xoff & 0xFF);
- zr36016_writei(ptr, ZR016I_NAY_HI, ptr->yoff >> 8);
- zr36016_writei(ptr, ZR016I_NAY_LO, ptr->yoff & 0xFF);
-
- /* shall we continue now, please? */
- zr36016_write(ptr, ZR016_GOSTOP, 1);
-}
-
-/* =========================================================================
- CODEC API FUNCTIONS
-
- this functions are accessed by the master via the API structure
- ========================================================================= */
-
-/* set compression/expansion mode and launches codec -
- this should be the last call from the master before starting processing */
-static int
-zr36016_set_mode (struct videocodec *codec,
- int mode)
-{
- struct zr36016 *ptr = (struct zr36016 *) codec->data;
-
- dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
-
- if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
- return -EINVAL;
-
- ptr->mode = mode;
- zr36016_init(ptr);
-
- return 0;
-}
-
-/* set picture size */
-static int
-zr36016_set_video (struct videocodec *codec,
- struct tvnorm *norm,
- struct vfe_settings *cap,
- struct vfe_polarity *pol)
-{
- struct zr36016 *ptr = (struct zr36016 *) codec->data;
-
- dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) call\n",
- ptr->name, norm->HStart, norm->VStart,
- cap->x, cap->y, cap->width, cap->height,
- cap->decimation);
-
- /* if () return -EINVAL;
- * trust the master driver that it knows what it does - so
- * we allow invalid startx/y for now ... */
- ptr->width = cap->width;
- ptr->height = cap->height;
- /* (Ronald) This is ugly. zoran_device.c, line 387
- * already mentions what happens if HStart is even
- * (blue faces, etc., cr/cb inversed). There's probably
- * some good reason why HStart is 0 instead of 1, so I'm
- * leaving it to this for now, but really... This can be
- * done a lot simpler */
- ptr->xoff = (norm->HStart ? norm->HStart : 1) + cap->x;
- /* Something to note here (I don't understand it), setting
- * VStart too high will cause the codec to 'not work'. I
- * really don't get it. values of 16 (VStart) already break
- * it here. Just '0' seems to work. More testing needed! */
- ptr->yoff = norm->VStart + cap->y;
- /* (Ronald) dzjeeh, can't this thing do hor_decimation = 4? */
- ptr->xdec = ((cap->decimation & 0xff) == 1) ? 0 : 1;
- ptr->ydec = (((cap->decimation >> 8) & 0xff) == 1) ? 0 : 1;
-
- return 0;
-}
-
-/* additional control functions */
-static int
-zr36016_control (struct videocodec *codec,
- int type,
- int size,
- void *data)
-{
- struct zr36016 *ptr = (struct zr36016 *) codec->data;
- int *ival = (int *) data;
-
- dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
- size);
-
- switch (type) {
- case CODEC_G_STATUS: /* get last status - we don't know it ... */
- if (size != sizeof(int))
- return -EFAULT;
- *ival = 0;
- break;
-
- case CODEC_G_CODEC_MODE:
- if (size != sizeof(int))
- return -EFAULT;
- *ival = 0;
- break;
-
- case CODEC_S_CODEC_MODE:
- if (size != sizeof(int))
- return -EFAULT;
- if (*ival != 0)
- return -EINVAL;
- /* not needed, do nothing */
- return 0;
-
- case CODEC_G_VFE:
- case CODEC_S_VFE:
- return 0;
-
- case CODEC_S_MMAP:
- /* not available, give an error */
- return -ENXIO;
-
- default:
- return -EINVAL;
- }
-
- return size;
-}
-
-/* =========================================================================
- Exit and unregister function:
-
- Deinitializes Zoran's JPEG processor
- ========================================================================= */
-
-static int
-zr36016_unset (struct videocodec *codec)
-{
- struct zr36016 *ptr = codec->data;
-
- if (ptr) {
- /* do wee need some codec deinit here, too ???? */
-
- dprintk(1, "%s: finished codec #%d\n", ptr->name,
- ptr->num);
- kfree(ptr);
- codec->data = NULL;
-
- zr36016_codecs--;
- return 0;
- }
-
- return -EFAULT;
-}
-
-/* =========================================================================
- Setup and registry function:
-
- Initializes Zoran's JPEG processor
-
- Also sets pixel size, average code size, mode (compr./decompr.)
- (the given size is determined by the processor with the video interface)
- ========================================================================= */
-
-static int
-zr36016_setup (struct videocodec *codec)
-{
- struct zr36016 *ptr;
- int res;
-
- dprintk(2, "zr36016: initializing VFE subsystem #%d.\n",
- zr36016_codecs);
-
- if (zr36016_codecs == MAX_CODECS) {
- dprintk(1,
- KERN_ERR "zr36016: Can't attach more codecs!\n");
- return -ENOSPC;
- }
- //mem structure init
- codec->data = ptr = kzalloc(sizeof(struct zr36016), GFP_KERNEL);
- if (NULL == ptr) {
- dprintk(1, KERN_ERR "zr36016: Can't get enough memory!\n");
- return -ENOMEM;
- }
-
- snprintf(ptr->name, sizeof(ptr->name), "zr36016[%d]",
- zr36016_codecs);
- ptr->num = zr36016_codecs++;
- ptr->codec = codec;
-
- //testing
- res = zr36016_basic_test(ptr);
- if (res < 0) {
- zr36016_unset(codec);
- return res;
- }
- //final setup
- ptr->mode = CODEC_DO_COMPRESSION;
- ptr->width = 768;
- ptr->height = 288;
- ptr->xdec = 1;
- ptr->ydec = 0;
- zr36016_init(ptr);
-
- dprintk(1, KERN_INFO "%s: codec v%d attached and running\n",
- ptr->name, ptr->version);
-
- return 0;
-}
-
-static const struct videocodec zr36016_codec = {
- .owner = THIS_MODULE,
- .name = "zr36016",
- .magic = 0L, // magic not used
- .flags =
- CODEC_FLAG_HARDWARE | CODEC_FLAG_VFE | CODEC_FLAG_ENCODER |
- CODEC_FLAG_DECODER,
- .type = CODEC_TYPE_ZR36016,
- .setup = zr36016_setup, // functionality
- .unset = zr36016_unset,
- .set_mode = zr36016_set_mode,
- .set_video = zr36016_set_video,
- .control = zr36016_control,
- // others are not used
-};
-
-/* =========================================================================
- HOOK IN DRIVER AS KERNEL MODULE
- ========================================================================= */
-
-static int __init
-zr36016_init_module (void)
-{
- //dprintk(1, "ZR36016 driver %s\n",ZR016_VERSION);
- zr36016_codecs = 0;
- return videocodec_register(&zr36016_codec);
-}
-
-static void __exit
-zr36016_cleanup_module (void)
-{
- if (zr36016_codecs) {
- dprintk(1,
- "zr36016: something's wrong - %d codecs left somehow.\n",
- zr36016_codecs);
- }
- videocodec_unregister(&zr36016_codec);
-}
-
-module_init(zr36016_init_module);
-module_exit(zr36016_cleanup_module);
-
-MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>");
-MODULE_DESCRIPTION("Driver module for ZR36016 video frontends "
- ZR016_VERSION);
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zoran/zr36016.h b/drivers/media/video/zoran/zr36016.h
deleted file mode 100644
index 8c79229f69d..00000000000
--- a/drivers/media/video/zoran/zr36016.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Zoran ZR36016 basic configuration functions - header file
- *
- * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
- *
- * $Id: zr36016.h,v 1.1.2.3 2003/01/14 21:18:07 rbultje Exp $
- *
- * ------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * ------------------------------------------------------------------------
- */
-
-#ifndef ZR36016_H
-#define ZR36016_H
-
-/* data stored for each zoran jpeg codec chip */
-struct zr36016 {
- char name[32];
- int num;
- /* io datastructure */
- struct videocodec *codec;
- // coder status
- __u8 version;
- // actual coder setup
- int mode;
-
- __u16 xoff;
- __u16 yoff;
- __u16 width;
- __u16 height;
- __u16 xdec;
- __u16 ydec;
-};
-
-/* direct register addresses */
-#define ZR016_GOSTOP 0x00
-#define ZR016_MODE 0x01
-#define ZR016_IADDR 0x02
-#define ZR016_IDATA 0x03
-
-/* indirect register addresses */
-#define ZR016I_SETUP1 0x00
-#define ZR016I_SETUP2 0x01
-#define ZR016I_NAX_LO 0x02
-#define ZR016I_NAX_HI 0x03
-#define ZR016I_PAX_LO 0x04
-#define ZR016I_PAX_HI 0x05
-#define ZR016I_NAY_LO 0x06
-#define ZR016I_NAY_HI 0x07
-#define ZR016I_PAY_LO 0x08
-#define ZR016I_PAY_HI 0x09
-#define ZR016I_NOL_LO 0x0a
-#define ZR016I_NOL_HI 0x0b
-
-/* possible values for mode register */
-#define ZR016_RGB444_YUV444 0x00
-#define ZR016_RGB444_YUV422 0x01
-#define ZR016_RGB444_YUV411 0x02
-#define ZR016_RGB444_Y400 0x03
-#define ZR016_RGB444_RGB444 0x04
-#define ZR016_YUV444_YUV444 0x08
-#define ZR016_YUV444_YUV422 0x09
-#define ZR016_YUV444_YUV411 0x0a
-#define ZR016_YUV444_Y400 0x0b
-#define ZR016_YUV444_RGB444 0x0c
-#define ZR016_YUV422_YUV422 0x11
-#define ZR016_YUV422_YUV411 0x12
-#define ZR016_YUV422_Y400 0x13
-#define ZR016_YUV411_YUV411 0x16
-#define ZR016_YUV411_Y400 0x17
-#define ZR016_4444_4444 0x19
-#define ZR016_100_100 0x1b
-
-#define ZR016_RGB444 0x00
-#define ZR016_YUV444 0x20
-#define ZR016_YUV422 0x40
-
-#define ZR016_COMPRESSION 0x80
-#define ZR016_EXPANSION 0x80
-
-/* possible values for setup 1 register */
-#define ZR016_CKRT 0x80
-#define ZR016_VERT 0x40
-#define ZR016_HORZ 0x20
-#define ZR016_HRFL 0x10
-#define ZR016_DSFL 0x08
-#define ZR016_SBFL 0x04
-#define ZR016_RSTR 0x02
-#define ZR016_CNTI 0x01
-
-/* possible values for setup 2 register */
-#define ZR016_SYEN 0x40
-#define ZR016_CCIR 0x04
-#define ZR016_SIGN 0x02
-#define ZR016_YMCS 0x01
-
-#endif /*fndef ZR36016_H */
diff --git a/drivers/media/video/zoran/zr36050.c b/drivers/media/video/zoran/zr36050.c
deleted file mode 100644
index e1985609af4..00000000000
--- a/drivers/media/video/zoran/zr36050.c
+++ /dev/null
@@ -1,900 +0,0 @@
-/*
- * Zoran ZR36050 basic configuration functions
- *
- * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
- *
- * $Id: zr36050.c,v 1.1.2.11 2003/08/03 14:54:53 rbultje Exp $
- *
- * ------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * ------------------------------------------------------------------------
- */
-
-#define ZR050_VERSION "v0.7.1"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-#include <linux/types.h>
-#include <linux/wait.h>
-
-/* I/O commands, error codes */
-#include <asm/io.h>
-
-/* headerfile of this module */
-#include "zr36050.h"
-
-/* codec io API */
-#include "videocodec.h"
-
-/* it doesn't make sense to have more than 20 or so,
- just to prevent some unwanted loops */
-#define MAX_CODECS 20
-
-/* amount of chips attached via this driver */
-static int zr36050_codecs;
-
-/* debugging is available via module parameter */
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-4)");
-
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
-/* =========================================================================
- Local hardware I/O functions:
-
- read/write via codec layer (registers are located in the master device)
- ========================================================================= */
-
-/* read and write functions */
-static u8
-zr36050_read (struct zr36050 *ptr,
- u16 reg)
-{
- u8 value = 0;
-
- // just in case something is wrong...
- if (ptr->codec->master_data->readreg)
- value = (ptr->codec->master_data->readreg(ptr->codec,
- reg)) & 0xFF;
- else
- dprintk(1,
- KERN_ERR "%s: invalid I/O setup, nothing read!\n",
- ptr->name);
-
- dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg,
- value);
-
- return value;
-}
-
-static void
-zr36050_write (struct zr36050 *ptr,
- u16 reg,
- u8 value)
-{
- dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value,
- reg);
-
- // just in case something is wrong...
- if (ptr->codec->master_data->writereg)
- ptr->codec->master_data->writereg(ptr->codec, reg, value);
- else
- dprintk(1,
- KERN_ERR
- "%s: invalid I/O setup, nothing written!\n",
- ptr->name);
-}
-
-/* =========================================================================
- Local helper function:
-
- status read
- ========================================================================= */
-
-/* status is kept in datastructure */
-static u8
-zr36050_read_status1 (struct zr36050 *ptr)
-{
- ptr->status1 = zr36050_read(ptr, ZR050_STATUS_1);
-
- zr36050_read(ptr, 0);
- return ptr->status1;
-}
-
-/* =========================================================================
- Local helper function:
-
- scale factor read
- ========================================================================= */
-
-/* scale factor is kept in datastructure */
-static u16
-zr36050_read_scalefactor (struct zr36050 *ptr)
-{
- ptr->scalefact = (zr36050_read(ptr, ZR050_SF_HI) << 8) |
- (zr36050_read(ptr, ZR050_SF_LO) & 0xFF);
-
- /* leave 0 selected for an eventually GO from master */
- zr36050_read(ptr, 0);
- return ptr->scalefact;
-}
-
-/* =========================================================================
- Local helper function:
-
- wait if codec is ready to proceed (end of processing) or time is over
- ========================================================================= */
-
-static void
-zr36050_wait_end (struct zr36050 *ptr)
-{
- int i = 0;
-
- while (!(zr36050_read_status1(ptr) & 0x4)) {
- udelay(1);
- if (i++ > 200000) { // 200ms, there is for sure something wrong!!!
- dprintk(1,
- "%s: timeout at wait_end (last status: 0x%02x)\n",
- ptr->name, ptr->status1);
- break;
- }
- }
-}
-
-/* =========================================================================
- Local helper function:
-
- basic test of "connectivity", writes/reads to/from memory the SOF marker
- ========================================================================= */
-
-static int
-zr36050_basic_test (struct zr36050 *ptr)
-{
- zr36050_write(ptr, ZR050_SOF_IDX, 0x00);
- zr36050_write(ptr, ZR050_SOF_IDX + 1, 0x00);
- if ((zr36050_read(ptr, ZR050_SOF_IDX) |
- zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0x0000) {
- dprintk(1,
- KERN_ERR
- "%s: attach failed, can't connect to jpeg processor!\n",
- ptr->name);
- return -ENXIO;
- }
- zr36050_write(ptr, ZR050_SOF_IDX, 0xff);
- zr36050_write(ptr, ZR050_SOF_IDX + 1, 0xc0);
- if (((zr36050_read(ptr, ZR050_SOF_IDX) << 8) |
- zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0xffc0) {
- dprintk(1,
- KERN_ERR
- "%s: attach failed, can't connect to jpeg processor!\n",
- ptr->name);
- return -ENXIO;
- }
-
- zr36050_wait_end(ptr);
- if ((ptr->status1 & 0x4) == 0) {
- dprintk(1,
- KERN_ERR
- "%s: attach failed, jpeg processor failed (end flag)!\n",
- ptr->name);
- return -EBUSY;
- }
-
- return 0; /* looks good! */
-}
-
-/* =========================================================================
- Local helper function:
-
- simple loop for pushing the init datasets
- ========================================================================= */
-
-static int
-zr36050_pushit (struct zr36050 *ptr,
- u16 startreg,
- u16 len,
- const char *data)
-{
- int i = 0;
-
- dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
- startreg, len);
- while (i < len) {
- zr36050_write(ptr, startreg++, data[i++]);
- }
-
- return i;
-}
-
-/* =========================================================================
- Basic datasets:
-
- jpeg baseline setup data (you find it on lots places in internet, or just
- extract it from any regular .jpg image...)
-
- Could be variable, but until it's not needed it they are just fixed to save
- memory. Otherwise expand zr36050 structure with arrays, push the values to
- it and initialize from there, as e.g. the linux zr36057/60 driver does it.
- ========================================================================= */
-
-static const char zr36050_dqt[0x86] = {
- 0xff, 0xdb, //Marker: DQT
- 0x00, 0x84, //Length: 2*65+2
- 0x00, //Pq,Tq first table
- 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
- 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
- 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
- 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
- 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
- 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
- 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
- 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
- 0x01, //Pq,Tq second table
- 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
- 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
-};
-
-static const char zr36050_dht[0x1a4] = {
- 0xff, 0xc4, //Marker: DHT
- 0x01, 0xa2, //Length: 2*AC, 2*DC
- 0x00, //DC first table
- 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
- 0x01, //DC second table
- 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
- 0x10, //AC first table
- 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
- 0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
- 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
- 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
- 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
- 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
- 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
- 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
- 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
- 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
- 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
- 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
- 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
- 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
- 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
- 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
- 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
- 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- 0xF8, 0xF9, 0xFA,
- 0x11, //AC second table
- 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
- 0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
- 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
- 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
- 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
- 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
- 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
- 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
- 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
- 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
- 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
- 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
- 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
- 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
- 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
- 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
- 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
- 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
- 0xF9, 0xFA
-};
-
-/* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
-#define NO_OF_COMPONENTS 0x3 //Y,U,V
-#define BASELINE_PRECISION 0x8 //MCU size (?)
-static const char zr36050_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT
-static const char zr36050_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC
-static const char zr36050_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC
-
-/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
-static const char zr36050_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
-static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
-
-/* =========================================================================
- Local helper functions:
-
- calculation and setup of parameter-dependent JPEG baseline segments
- (needed for compression only)
- ========================================================================= */
-
-/* ------------------------------------------------------------------------- */
-
-/* SOF (start of frame) segment depends on width, height and sampling ratio
- of each color component */
-
-static int
-zr36050_set_sof (struct zr36050 *ptr)
-{
- char sof_data[34]; // max. size of register set
- int i;
-
- dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
- ptr->width, ptr->height, NO_OF_COMPONENTS);
- sof_data[0] = 0xff;
- sof_data[1] = 0xc0;
- sof_data[2] = 0x00;
- sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
- sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36050
- sof_data[5] = (ptr->height) >> 8;
- sof_data[6] = (ptr->height) & 0xff;
- sof_data[7] = (ptr->width) >> 8;
- sof_data[8] = (ptr->width) & 0xff;
- sof_data[9] = NO_OF_COMPONENTS;
- for (i = 0; i < NO_OF_COMPONENTS; i++) {
- sof_data[10 + (i * 3)] = i; // index identifier
- sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) | (ptr->v_samp_ratio[i]); // sampling ratios
- sof_data[12 + (i * 3)] = zr36050_tq[i]; // Q table selection
- }
- return zr36050_pushit(ptr, ZR050_SOF_IDX,
- (3 * NO_OF_COMPONENTS) + 10, sof_data);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* SOS (start of scan) segment depends on the used scan components
- of each color component */
-
-static int
-zr36050_set_sos (struct zr36050 *ptr)
-{
- char sos_data[16]; // max. size of register set
- int i;
-
- dprintk(3, "%s: write SOS\n", ptr->name);
- sos_data[0] = 0xff;
- sos_data[1] = 0xda;
- sos_data[2] = 0x00;
- sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
- sos_data[4] = NO_OF_COMPONENTS;
- for (i = 0; i < NO_OF_COMPONENTS; i++) {
- sos_data[5 + (i * 2)] = i; // index
- sos_data[6 + (i * 2)] = (zr36050_td[i] << 4) | zr36050_ta[i]; // AC/DC tbl.sel.
- }
- sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start
- sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3F;
- sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
- return zr36050_pushit(ptr, ZR050_SOS1_IDX,
- 4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
- sos_data);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* DRI (define restart interval) */
-
-static int
-zr36050_set_dri (struct zr36050 *ptr)
-{
- char dri_data[6]; // max. size of register set
-
- dprintk(3, "%s: write DRI\n", ptr->name);
- dri_data[0] = 0xff;
- dri_data[1] = 0xdd;
- dri_data[2] = 0x00;
- dri_data[3] = 0x04;
- dri_data[4] = ptr->dri >> 8;
- dri_data[5] = ptr->dri & 0xff;
- return zr36050_pushit(ptr, ZR050_DRI_IDX, 6, dri_data);
-}
-
-/* =========================================================================
- Setup function:
-
- Setup compression/decompression of Zoran's JPEG processor
- ( see also zoran 36050 manual )
-
- ... sorry for the spaghetti code ...
- ========================================================================= */
-static void
-zr36050_init (struct zr36050 *ptr)
-{
- int sum = 0;
- long bitcnt, tmp;
-
- if (ptr->mode == CODEC_DO_COMPRESSION) {
- dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
-
- /* 050 communicates with 057 in master mode */
- zr36050_write(ptr, ZR050_HARDWARE, ZR050_HW_MSTR);
-
- /* encoding table preload for compression */
- zr36050_write(ptr, ZR050_MODE,
- ZR050_MO_COMP | ZR050_MO_TLM);
- zr36050_write(ptr, ZR050_OPTIONS, 0);
-
- /* disable all IRQs */
- zr36050_write(ptr, ZR050_INT_REQ_0, 0);
- zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
-
- /* volume control settings */
- /*zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);*/
- zr36050_write(ptr, ZR050_SF_HI, ptr->scalefact >> 8);
- zr36050_write(ptr, ZR050_SF_LO, ptr->scalefact & 0xff);
-
- zr36050_write(ptr, ZR050_AF_HI, 0xff);
- zr36050_write(ptr, ZR050_AF_M, 0xff);
- zr36050_write(ptr, ZR050_AF_LO, 0xff);
-
- /* setup the variable jpeg tables */
- sum += zr36050_set_sof(ptr);
- sum += zr36050_set_sos(ptr);
- sum += zr36050_set_dri(ptr);
-
- /* setup the fixed jpeg tables - maybe variable, though -
- * (see table init section above) */
- dprintk(3, "%s: write DQT, DHT, APP\n", ptr->name);
- sum += zr36050_pushit(ptr, ZR050_DQT_IDX,
- sizeof(zr36050_dqt), zr36050_dqt);
- sum += zr36050_pushit(ptr, ZR050_DHT_IDX,
- sizeof(zr36050_dht), zr36050_dht);
- zr36050_write(ptr, ZR050_APP_IDX, 0xff);
- zr36050_write(ptr, ZR050_APP_IDX + 1, 0xe0 + ptr->app.appn);
- zr36050_write(ptr, ZR050_APP_IDX + 2, 0x00);
- zr36050_write(ptr, ZR050_APP_IDX + 3, ptr->app.len + 2);
- sum += zr36050_pushit(ptr, ZR050_APP_IDX + 4, 60,
- ptr->app.data) + 4;
- zr36050_write(ptr, ZR050_COM_IDX, 0xff);
- zr36050_write(ptr, ZR050_COM_IDX + 1, 0xfe);
- zr36050_write(ptr, ZR050_COM_IDX + 2, 0x00);
- zr36050_write(ptr, ZR050_COM_IDX + 3, ptr->com.len + 2);
- sum += zr36050_pushit(ptr, ZR050_COM_IDX + 4, 60,
- ptr->com.data) + 4;
-
- /* do the internal huffman table preload */
- zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
-
- zr36050_write(ptr, ZR050_GO, 1); // launch codec
- zr36050_wait_end(ptr);
- dprintk(2, "%s: Status after table preload: 0x%02x\n",
- ptr->name, ptr->status1);
-
- if ((ptr->status1 & 0x4) == 0) {
- dprintk(1, KERN_ERR "%s: init aborted!\n",
- ptr->name);
- return; // something is wrong, its timed out!!!!
- }
-
- /* setup misc. data for compression (target code sizes) */
-
- /* size of compressed code to reach without header data */
- sum = ptr->real_code_vol - sum;
- bitcnt = sum << 3; /* need the size in bits */
-
- tmp = bitcnt >> 16;
- dprintk(3,
- "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
- ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
- zr36050_write(ptr, ZR050_TCV_NET_HI, tmp >> 8);
- zr36050_write(ptr, ZR050_TCV_NET_MH, tmp & 0xff);
- tmp = bitcnt & 0xffff;
- zr36050_write(ptr, ZR050_TCV_NET_ML, tmp >> 8);
- zr36050_write(ptr, ZR050_TCV_NET_LO, tmp & 0xff);
-
- bitcnt -= bitcnt >> 7; // bits without stuffing
- bitcnt -= ((bitcnt * 5) >> 6); // bits without eob
-
- tmp = bitcnt >> 16;
- dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n",
- ptr->name, bitcnt, tmp);
- zr36050_write(ptr, ZR050_TCV_DATA_HI, tmp >> 8);
- zr36050_write(ptr, ZR050_TCV_DATA_MH, tmp & 0xff);
- tmp = bitcnt & 0xffff;
- zr36050_write(ptr, ZR050_TCV_DATA_ML, tmp >> 8);
- zr36050_write(ptr, ZR050_TCV_DATA_LO, tmp & 0xff);
-
- /* compression setup with or without bitrate control */
- zr36050_write(ptr, ZR050_MODE,
- ZR050_MO_COMP | ZR050_MO_PASS2 |
- (ptr->bitrate_ctrl ? ZR050_MO_BRC : 0));
-
- /* this headers seem to deliver "valid AVI" jpeg frames */
- zr36050_write(ptr, ZR050_MARKERS_EN,
- ZR050_ME_DQT | ZR050_ME_DHT |
- ((ptr->app.len > 0) ? ZR050_ME_APP : 0) |
- ((ptr->com.len > 0) ? ZR050_ME_COM : 0));
- } else {
- dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
-
- /* 050 communicates with 055 in master mode */
- zr36050_write(ptr, ZR050_HARDWARE,
- ZR050_HW_MSTR | ZR050_HW_CFIS_2_CLK);
-
- /* encoding table preload */
- zr36050_write(ptr, ZR050_MODE, ZR050_MO_TLM);
-
- /* disable all IRQs */
- zr36050_write(ptr, ZR050_INT_REQ_0, 0);
- zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
-
- dprintk(3, "%s: write DHT\n", ptr->name);
- zr36050_pushit(ptr, ZR050_DHT_IDX, sizeof(zr36050_dht),
- zr36050_dht);
-
- /* do the internal huffman table preload */
- zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
-
- zr36050_write(ptr, ZR050_GO, 1); // launch codec
- zr36050_wait_end(ptr);
- dprintk(2, "%s: Status after table preload: 0x%02x\n",
- ptr->name, ptr->status1);
-
- if ((ptr->status1 & 0x4) == 0) {
- dprintk(1, KERN_ERR "%s: init aborted!\n",
- ptr->name);
- return; // something is wrong, its timed out!!!!
- }
-
- /* setup misc. data for expansion */
- zr36050_write(ptr, ZR050_MODE, 0);
- zr36050_write(ptr, ZR050_MARKERS_EN, 0);
- }
-
- /* adr on selected, to allow GO from master */
- zr36050_read(ptr, 0);
-}
-
-/* =========================================================================
- CODEC API FUNCTIONS
-
- this functions are accessed by the master via the API structure
- ========================================================================= */
-
-/* set compression/expansion mode and launches codec -
- this should be the last call from the master before starting processing */
-static int
-zr36050_set_mode (struct videocodec *codec,
- int mode)
-{
- struct zr36050 *ptr = (struct zr36050 *) codec->data;
-
- dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
-
- if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
- return -EINVAL;
-
- ptr->mode = mode;
- zr36050_init(ptr);
-
- return 0;
-}
-
-/* set picture size (norm is ignored as the codec doesn't know about it) */
-static int
-zr36050_set_video (struct videocodec *codec,
- struct tvnorm *norm,
- struct vfe_settings *cap,
- struct vfe_polarity *pol)
-{
- struct zr36050 *ptr = (struct zr36050 *) codec->data;
- int size;
-
- dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) q%d call\n",
- ptr->name, norm->HStart, norm->VStart,
- cap->x, cap->y, cap->width, cap->height,
- cap->decimation, cap->quality);
- /* if () return -EINVAL;
- * trust the master driver that it knows what it does - so
- * we allow invalid startx/y and norm for now ... */
- ptr->width = cap->width / (cap->decimation & 0xff);
- ptr->height = cap->height / ((cap->decimation >> 8) & 0xff);
-
- /* (KM) JPEG quality */
- size = ptr->width * ptr->height;
- size *= 16; /* size in bits */
- /* apply quality setting */
- size = size * cap->quality / 200;
-
- /* Minimum: 1kb */
- if (size < 8192)
- size = 8192;
- /* Maximum: 7/8 of code buffer */
- if (size > ptr->total_code_vol * 7)
- size = ptr->total_code_vol * 7;
-
- ptr->real_code_vol = size >> 3; /* in bytes */
-
- /* Set max_block_vol here (previously in zr36050_init, moved
- * here for consistency with zr36060 code */
- zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);
-
- return 0;
-}
-
-/* additional control functions */
-static int
-zr36050_control (struct videocodec *codec,
- int type,
- int size,
- void *data)
-{
- struct zr36050 *ptr = (struct zr36050 *) codec->data;
- int *ival = (int *) data;
-
- dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
- size);
-
- switch (type) {
- case CODEC_G_STATUS: /* get last status */
- if (size != sizeof(int))
- return -EFAULT;
- zr36050_read_status1(ptr);
- *ival = ptr->status1;
- break;
-
- case CODEC_G_CODEC_MODE:
- if (size != sizeof(int))
- return -EFAULT;
- *ival = CODEC_MODE_BJPG;
- break;
-
- case CODEC_S_CODEC_MODE:
- if (size != sizeof(int))
- return -EFAULT;
- if (*ival != CODEC_MODE_BJPG)
- return -EINVAL;
- /* not needed, do nothing */
- return 0;
-
- case CODEC_G_VFE:
- case CODEC_S_VFE:
- /* not needed, do nothing */
- return 0;
-
- case CODEC_S_MMAP:
- /* not available, give an error */
- return -ENXIO;
-
- case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */
- if (size != sizeof(int))
- return -EFAULT;
- *ival = ptr->total_code_vol;
- break;
-
- case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */
- if (size != sizeof(int))
- return -EFAULT;
- ptr->total_code_vol = *ival;
- /* (Kieran Morrissey)
- * code copied from zr36060.c to ensure proper bitrate */
- ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
- break;
-
- case CODEC_G_JPEG_SCALE: /* get scaling factor */
- if (size != sizeof(int))
- return -EFAULT;
- *ival = zr36050_read_scalefactor(ptr);
- break;
-
- case CODEC_S_JPEG_SCALE: /* set scaling factor */
- if (size != sizeof(int))
- return -EFAULT;
- ptr->scalefact = *ival;
- break;
-
- case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */
- struct jpeg_app_marker *app = data;
-
- if (size != sizeof(struct jpeg_app_marker))
- return -EFAULT;
-
- *app = ptr->app;
- break;
- }
-
- case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */
- struct jpeg_app_marker *app = data;
-
- if (size != sizeof(struct jpeg_app_marker))
- return -EFAULT;
-
- ptr->app = *app;
- break;
- }
-
- case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */
- struct jpeg_com_marker *com = data;
-
- if (size != sizeof(struct jpeg_com_marker))
- return -EFAULT;
-
- *com = ptr->com;
- break;
- }
-
- case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */
- struct jpeg_com_marker *com = data;
-
- if (size != sizeof(struct jpeg_com_marker))
- return -EFAULT;
-
- ptr->com = *com;
- break;
- }
-
- default:
- return -EINVAL;
- }
-
- return size;
-}
-
-/* =========================================================================
- Exit and unregister function:
-
- Deinitializes Zoran's JPEG processor
- ========================================================================= */
-
-static int
-zr36050_unset (struct videocodec *codec)
-{
- struct zr36050 *ptr = codec->data;
-
- if (ptr) {
- /* do wee need some codec deinit here, too ???? */
-
- dprintk(1, "%s: finished codec #%d\n", ptr->name,
- ptr->num);
- kfree(ptr);
- codec->data = NULL;
-
- zr36050_codecs--;
- return 0;
- }
-
- return -EFAULT;
-}
-
-/* =========================================================================
- Setup and registry function:
-
- Initializes Zoran's JPEG processor
-
- Also sets pixel size, average code size, mode (compr./decompr.)
- (the given size is determined by the processor with the video interface)
- ========================================================================= */
-
-static int
-zr36050_setup (struct videocodec *codec)
-{
- struct zr36050 *ptr;
- int res;
-
- dprintk(2, "zr36050: initializing MJPEG subsystem #%d.\n",
- zr36050_codecs);
-
- if (zr36050_codecs == MAX_CODECS) {
- dprintk(1,
- KERN_ERR "zr36050: Can't attach more codecs!\n");
- return -ENOSPC;
- }
- //mem structure init
- codec->data = ptr = kzalloc(sizeof(struct zr36050), GFP_KERNEL);
- if (NULL == ptr) {
- dprintk(1, KERN_ERR "zr36050: Can't get enough memory!\n");
- return -ENOMEM;
- }
-
- snprintf(ptr->name, sizeof(ptr->name), "zr36050[%d]",
- zr36050_codecs);
- ptr->num = zr36050_codecs++;
- ptr->codec = codec;
-
- //testing
- res = zr36050_basic_test(ptr);
- if (res < 0) {
- zr36050_unset(codec);
- return res;
- }
- //final setup
- memcpy(ptr->h_samp_ratio, zr36050_decimation_h, 8);
- memcpy(ptr->v_samp_ratio, zr36050_decimation_v, 8);
-
- ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag
- * (what is the difference?) */
- ptr->mode = CODEC_DO_COMPRESSION;
- ptr->width = 384;
- ptr->height = 288;
- ptr->total_code_vol = 16000;
- ptr->max_block_vol = 240;
- ptr->scalefact = 0x100;
- ptr->dri = 1;
-
- /* no app/com marker by default */
- ptr->app.appn = 0;
- ptr->app.len = 0;
- ptr->com.len = 0;
-
- zr36050_init(ptr);
-
- dprintk(1, KERN_INFO "%s: codec attached and running\n",
- ptr->name);
-
- return 0;
-}
-
-static const struct videocodec zr36050_codec = {
- .owner = THIS_MODULE,
- .name = "zr36050",
- .magic = 0L, // magic not used
- .flags =
- CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
- CODEC_FLAG_DECODER,
- .type = CODEC_TYPE_ZR36050,
- .setup = zr36050_setup, // functionality
- .unset = zr36050_unset,
- .set_mode = zr36050_set_mode,
- .set_video = zr36050_set_video,
- .control = zr36050_control,
- // others are not used
-};
-
-/* =========================================================================
- HOOK IN DRIVER AS KERNEL MODULE
- ========================================================================= */
-
-static int __init
-zr36050_init_module (void)
-{
- //dprintk(1, "ZR36050 driver %s\n",ZR050_VERSION);
- zr36050_codecs = 0;
- return videocodec_register(&zr36050_codec);
-}
-
-static void __exit
-zr36050_cleanup_module (void)
-{
- if (zr36050_codecs) {
- dprintk(1,
- "zr36050: something's wrong - %d codecs left somehow.\n",
- zr36050_codecs);
- }
- videocodec_unregister(&zr36050_codec);
-}
-
-module_init(zr36050_init_module);
-module_exit(zr36050_cleanup_module);
-
-MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>");
-MODULE_DESCRIPTION("Driver module for ZR36050 jpeg processors "
- ZR050_VERSION);
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zoran/zr36050.h b/drivers/media/video/zoran/zr36050.h
deleted file mode 100644
index 9f52f0cdde5..00000000000
--- a/drivers/media/video/zoran/zr36050.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Zoran ZR36050 basic configuration functions - header file
- *
- * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
- *
- * $Id: zr36050.h,v 1.1.2.2 2003/01/14 21:18:22 rbultje Exp $
- *
- * ------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * ------------------------------------------------------------------------
- */
-
-#ifndef ZR36050_H
-#define ZR36050_H
-
-#include "videocodec.h"
-
-/* data stored for each zoran jpeg codec chip */
-struct zr36050 {
- char name[32];
- int num;
- /* io datastructure */
- struct videocodec *codec;
- // last coder status
- __u8 status1;
- // actual coder setup
- int mode;
-
- __u16 width;
- __u16 height;
-
- __u16 bitrate_ctrl;
-
- __u32 total_code_vol;
- __u32 real_code_vol;
- __u16 max_block_vol;
-
- __u8 h_samp_ratio[8];
- __u8 v_samp_ratio[8];
- __u16 scalefact;
- __u16 dri;
-
- /* com/app marker */
- struct jpeg_com_marker com;
- struct jpeg_app_marker app;
-};
-
-/* zr36050 register addresses */
-#define ZR050_GO 0x000
-#define ZR050_HARDWARE 0x002
-#define ZR050_MODE 0x003
-#define ZR050_OPTIONS 0x004
-#define ZR050_MBCV 0x005
-#define ZR050_MARKERS_EN 0x006
-#define ZR050_INT_REQ_0 0x007
-#define ZR050_INT_REQ_1 0x008
-#define ZR050_TCV_NET_HI 0x009
-#define ZR050_TCV_NET_MH 0x00a
-#define ZR050_TCV_NET_ML 0x00b
-#define ZR050_TCV_NET_LO 0x00c
-#define ZR050_TCV_DATA_HI 0x00d
-#define ZR050_TCV_DATA_MH 0x00e
-#define ZR050_TCV_DATA_ML 0x00f
-#define ZR050_TCV_DATA_LO 0x010
-#define ZR050_SF_HI 0x011
-#define ZR050_SF_LO 0x012
-#define ZR050_AF_HI 0x013
-#define ZR050_AF_M 0x014
-#define ZR050_AF_LO 0x015
-#define ZR050_ACV_HI 0x016
-#define ZR050_ACV_MH 0x017
-#define ZR050_ACV_ML 0x018
-#define ZR050_ACV_LO 0x019
-#define ZR050_ACT_HI 0x01a
-#define ZR050_ACT_MH 0x01b
-#define ZR050_ACT_ML 0x01c
-#define ZR050_ACT_LO 0x01d
-#define ZR050_ACV_TRUN_HI 0x01e
-#define ZR050_ACV_TRUN_MH 0x01f
-#define ZR050_ACV_TRUN_ML 0x020
-#define ZR050_ACV_TRUN_LO 0x021
-#define ZR050_STATUS_0 0x02e
-#define ZR050_STATUS_1 0x02f
-
-#define ZR050_SOF_IDX 0x040
-#define ZR050_SOS1_IDX 0x07a
-#define ZR050_SOS2_IDX 0x08a
-#define ZR050_SOS3_IDX 0x09a
-#define ZR050_SOS4_IDX 0x0aa
-#define ZR050_DRI_IDX 0x0c0
-#define ZR050_DNL_IDX 0x0c6
-#define ZR050_DQT_IDX 0x0cc
-#define ZR050_DHT_IDX 0x1d4
-#define ZR050_APP_IDX 0x380
-#define ZR050_COM_IDX 0x3c0
-
-/* zr36050 hardware register bits */
-
-#define ZR050_HW_BSWD 0x80
-#define ZR050_HW_MSTR 0x40
-#define ZR050_HW_DMA 0x20
-#define ZR050_HW_CFIS_1_CLK 0x00
-#define ZR050_HW_CFIS_2_CLK 0x04
-#define ZR050_HW_CFIS_3_CLK 0x08
-#define ZR050_HW_CFIS_4_CLK 0x0C
-#define ZR050_HW_CFIS_5_CLK 0x10
-#define ZR050_HW_CFIS_6_CLK 0x14
-#define ZR050_HW_CFIS_7_CLK 0x18
-#define ZR050_HW_CFIS_8_CLK 0x1C
-#define ZR050_HW_BELE 0x01
-
-/* zr36050 mode register bits */
-
-#define ZR050_MO_COMP 0x80
-#define ZR050_MO_COMP 0x80
-#define ZR050_MO_ATP 0x40
-#define ZR050_MO_PASS2 0x20
-#define ZR050_MO_TLM 0x10
-#define ZR050_MO_DCONLY 0x08
-#define ZR050_MO_BRC 0x04
-
-#define ZR050_MO_ATP 0x40
-#define ZR050_MO_PASS2 0x20
-#define ZR050_MO_TLM 0x10
-#define ZR050_MO_DCONLY 0x08
-
-/* zr36050 option register bits */
-
-#define ZR050_OP_NSCN_1 0x00
-#define ZR050_OP_NSCN_2 0x20
-#define ZR050_OP_NSCN_3 0x40
-#define ZR050_OP_NSCN_4 0x60
-#define ZR050_OP_NSCN_5 0x80
-#define ZR050_OP_NSCN_6 0xA0
-#define ZR050_OP_NSCN_7 0xC0
-#define ZR050_OP_NSCN_8 0xE0
-#define ZR050_OP_OVF 0x10
-
-
-/* zr36050 markers-enable register bits */
-
-#define ZR050_ME_APP 0x80
-#define ZR050_ME_COM 0x40
-#define ZR050_ME_DRI 0x20
-#define ZR050_ME_DQT 0x10
-#define ZR050_ME_DHT 0x08
-#define ZR050_ME_DNL 0x04
-#define ZR050_ME_DQTI 0x02
-#define ZR050_ME_DHTI 0x01
-
-/* zr36050 status0/1 register bit masks */
-
-#define ZR050_ST_RST_MASK 0x20
-#define ZR050_ST_SOF_MASK 0x02
-#define ZR050_ST_SOS_MASK 0x02
-#define ZR050_ST_DATRDY_MASK 0x80
-#define ZR050_ST_MRKDET_MASK 0x40
-#define ZR050_ST_RFM_MASK 0x10
-#define ZR050_ST_RFD_MASK 0x08
-#define ZR050_ST_END_MASK 0x04
-#define ZR050_ST_TCVOVF_MASK 0x02
-#define ZR050_ST_DATOVF_MASK 0x01
-
-/* pixel component idx */
-
-#define ZR050_Y_COMPONENT 0
-#define ZR050_U_COMPONENT 1
-#define ZR050_V_COMPONENT 2
-
-#endif /*fndef ZR36050_H */
diff --git a/drivers/media/video/zoran/zr36057.h b/drivers/media/video/zoran/zr36057.h
deleted file mode 100644
index 54c9362aa98..00000000000
--- a/drivers/media/video/zoran/zr36057.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * zr36057.h - zr36057 register offsets
- *
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ZR36057_H_
-#define _ZR36057_H_
-
-
-/* Zoran ZR36057 registers */
-
-#define ZR36057_VFEHCR 0x000 /* Video Front End, Horizontal Configuration Register */
-#define ZR36057_VFEHCR_HSPol (1<<30)
-#define ZR36057_VFEHCR_HStart 10
-#define ZR36057_VFEHCR_HEnd 0
-#define ZR36057_VFEHCR_Hmask 0x3ff
-
-#define ZR36057_VFEVCR 0x004 /* Video Front End, Vertical Configuration Register */
-#define ZR36057_VFEVCR_VSPol (1<<30)
-#define ZR36057_VFEVCR_VStart 10
-#define ZR36057_VFEVCR_VEnd 0
-#define ZR36057_VFEVCR_Vmask 0x3ff
-
-#define ZR36057_VFESPFR 0x008 /* Video Front End, Scaler and Pixel Format Register */
-#define ZR36057_VFESPFR_ExtFl (1<<26)
-#define ZR36057_VFESPFR_TopField (1<<25)
-#define ZR36057_VFESPFR_VCLKPol (1<<24)
-#define ZR36057_VFESPFR_HFilter 21
-#define ZR36057_VFESPFR_HorDcm 14
-#define ZR36057_VFESPFR_VerDcm 8
-#define ZR36057_VFESPFR_DispMode 6
-#define ZR36057_VFESPFR_YUV422 (0<<3)
-#define ZR36057_VFESPFR_RGB888 (1<<3)
-#define ZR36057_VFESPFR_RGB565 (2<<3)
-#define ZR36057_VFESPFR_RGB555 (3<<3)
-#define ZR36057_VFESPFR_ErrDif (1<<2)
-#define ZR36057_VFESPFR_Pack24 (1<<1)
-#define ZR36057_VFESPFR_LittleEndian (1<<0)
-
-#define ZR36057_VDTR 0x00c /* Video Display "Top" Register */
-
-#define ZR36057_VDBR 0x010 /* Video Display "Bottom" Register */
-
-#define ZR36057_VSSFGR 0x014 /* Video Stride, Status, and Frame Grab Register */
-#define ZR36057_VSSFGR_DispStride 16
-#define ZR36057_VSSFGR_VidOvf (1<<8)
-#define ZR36057_VSSFGR_SnapShot (1<<1)
-#define ZR36057_VSSFGR_FrameGrab (1<<0)
-
-#define ZR36057_VDCR 0x018 /* Video Display Configuration Register */
-#define ZR36057_VDCR_VidEn (1<<31)
-#define ZR36057_VDCR_MinPix 24
-#define ZR36057_VDCR_Triton (1<<24)
-#define ZR36057_VDCR_VidWinHt 12
-#define ZR36057_VDCR_VidWinWid 0
-
-#define ZR36057_MMTR 0x01c /* Masking Map "Top" Register */
-
-#define ZR36057_MMBR 0x020 /* Masking Map "Bottom" Register */
-
-#define ZR36057_OCR 0x024 /* Overlay Control Register */
-#define ZR36057_OCR_OvlEnable (1 << 15)
-#define ZR36057_OCR_MaskStride 0
-
-#define ZR36057_SPGPPCR 0x028 /* System, PCI, and General Purpose Pins Control Register */
-#define ZR36057_SPGPPCR_SoftReset (1<<24)
-
-#define ZR36057_GPPGCR1 0x02c /* General Purpose Pins and GuestBus Control Register (1) */
-
-#define ZR36057_MCSAR 0x030 /* MPEG Code Source Address Register */
-
-#define ZR36057_MCTCR 0x034 /* MPEG Code Transfer Control Register */
-#define ZR36057_MCTCR_CodTime (1 << 30)
-#define ZR36057_MCTCR_CEmpty (1 << 29)
-#define ZR36057_MCTCR_CFlush (1 << 28)
-#define ZR36057_MCTCR_CodGuestID 20
-#define ZR36057_MCTCR_CodGuestReg 16
-
-#define ZR36057_MCMPR 0x038 /* MPEG Code Memory Pointer Register */
-
-#define ZR36057_ISR 0x03c /* Interrupt Status Register */
-#define ZR36057_ISR_GIRQ1 (1<<30)
-#define ZR36057_ISR_GIRQ0 (1<<29)
-#define ZR36057_ISR_CodRepIRQ (1<<28)
-#define ZR36057_ISR_JPEGRepIRQ (1<<27)
-
-#define ZR36057_ICR 0x040 /* Interrupt Control Register */
-#define ZR36057_ICR_GIRQ1 (1<<30)
-#define ZR36057_ICR_GIRQ0 (1<<29)
-#define ZR36057_ICR_CodRepIRQ (1<<28)
-#define ZR36057_ICR_JPEGRepIRQ (1<<27)
-#define ZR36057_ICR_IntPinEn (1<<24)
-
-#define ZR36057_I2CBR 0x044 /* I2C Bus Register */
-#define ZR36057_I2CBR_SDA (1<<1)
-#define ZR36057_I2CBR_SCL (1<<0)
-
-#define ZR36057_JMC 0x100 /* JPEG Mode and Control */
-#define ZR36057_JMC_JPG (1 << 31)
-#define ZR36057_JMC_JPGExpMode (0 << 29)
-#define ZR36057_JMC_JPGCmpMode (1 << 29)
-#define ZR36057_JMC_MJPGExpMode (2 << 29)
-#define ZR36057_JMC_MJPGCmpMode (3 << 29)
-#define ZR36057_JMC_RTBUSY_FB (1 << 6)
-#define ZR36057_JMC_Go_en (1 << 5)
-#define ZR36057_JMC_SyncMstr (1 << 4)
-#define ZR36057_JMC_Fld_per_buff (1 << 3)
-#define ZR36057_JMC_VFIFO_FB (1 << 2)
-#define ZR36057_JMC_CFIFO_FB (1 << 1)
-#define ZR36057_JMC_Stll_LitEndian (1 << 0)
-
-#define ZR36057_JPC 0x104 /* JPEG Process Control */
-#define ZR36057_JPC_P_Reset (1 << 7)
-#define ZR36057_JPC_CodTrnsEn (1 << 5)
-#define ZR36057_JPC_Active (1 << 0)
-
-#define ZR36057_VSP 0x108 /* Vertical Sync Parameters */
-#define ZR36057_VSP_VsyncSize 16
-#define ZR36057_VSP_FrmTot 0
-
-#define ZR36057_HSP 0x10c /* Horizontal Sync Parameters */
-#define ZR36057_HSP_HsyncStart 16
-#define ZR36057_HSP_LineTot 0
-
-#define ZR36057_FHAP 0x110 /* Field Horizontal Active Portion */
-#define ZR36057_FHAP_NAX 16
-#define ZR36057_FHAP_PAX 0
-
-#define ZR36057_FVAP 0x114 /* Field Vertical Active Portion */
-#define ZR36057_FVAP_NAY 16
-#define ZR36057_FVAP_PAY 0
-
-#define ZR36057_FPP 0x118 /* Field Process Parameters */
-#define ZR36057_FPP_Odd_Even (1 << 0)
-
-#define ZR36057_JCBA 0x11c /* JPEG Code Base Address */
-
-#define ZR36057_JCFT 0x120 /* JPEG Code FIFO Threshold */
-
-#define ZR36057_JCGI 0x124 /* JPEG Codec Guest ID */
-#define ZR36057_JCGI_JPEGuestID 4
-#define ZR36057_JCGI_JPEGuestReg 0
-
-#define ZR36057_GCR2 0x12c /* GuestBus Control Register (2) */
-
-#define ZR36057_POR 0x200 /* Post Office Register */
-#define ZR36057_POR_POPen (1<<25)
-#define ZR36057_POR_POTime (1<<24)
-#define ZR36057_POR_PODir (1<<23)
-
-#define ZR36057_STR 0x300 /* "Still" Transfer Register */
-
-#endif
diff --git a/drivers/media/video/zoran/zr36060.c b/drivers/media/video/zoran/zr36060.c
deleted file mode 100644
index f08546fe223..00000000000
--- a/drivers/media/video/zoran/zr36060.c
+++ /dev/null
@@ -1,1010 +0,0 @@
-/*
- * Zoran ZR36060 basic configuration functions
- *
- * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be>
- *
- * $Id: zr36060.c,v 1.1.2.22 2003/05/06 09:35:36 rbultje Exp $
- *
- * ------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * ------------------------------------------------------------------------
- */
-
-#define ZR060_VERSION "v0.7"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-#include <linux/types.h>
-#include <linux/wait.h>
-
-/* I/O commands, error codes */
-#include <asm/io.h>
-
-/* headerfile of this module */
-#include "zr36060.h"
-
-/* codec io API */
-#include "videocodec.h"
-
-/* it doesn't make sense to have more than 20 or so,
- just to prevent some unwanted loops */
-#define MAX_CODECS 20
-
-/* amount of chips attached via this driver */
-static int zr36060_codecs;
-
-static bool low_bitrate;
-module_param(low_bitrate, bool, 0);
-MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate");
-
-/* debugging is available via module parameter */
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-4)");
-
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
-/* =========================================================================
- Local hardware I/O functions:
-
- read/write via codec layer (registers are located in the master device)
- ========================================================================= */
-
-/* read and write functions */
-static u8
-zr36060_read (struct zr36060 *ptr,
- u16 reg)
-{
- u8 value = 0;
-
- // just in case something is wrong...
- if (ptr->codec->master_data->readreg)
- value = (ptr->codec->master_data->readreg(ptr->codec,
- reg)) & 0xff;
- else
- dprintk(1,
- KERN_ERR "%s: invalid I/O setup, nothing read!\n",
- ptr->name);
-
- //dprintk(4, "%s: reading from 0x%04x: %02x\n",ptr->name,reg,value);
-
- return value;
-}
-
-static void
-zr36060_write(struct zr36060 *ptr,
- u16 reg,
- u8 value)
-{
- //dprintk(4, "%s: writing 0x%02x to 0x%04x\n",ptr->name,value,reg);
- dprintk(4, "0x%02x @0x%04x\n", value, reg);
-
- // just in case something is wrong...
- if (ptr->codec->master_data->writereg)
- ptr->codec->master_data->writereg(ptr->codec, reg, value);
- else
- dprintk(1,
- KERN_ERR
- "%s: invalid I/O setup, nothing written!\n",
- ptr->name);
-}
-
-/* =========================================================================
- Local helper function:
-
- status read
- ========================================================================= */
-
-/* status is kept in datastructure */
-static u8
-zr36060_read_status (struct zr36060 *ptr)
-{
- ptr->status = zr36060_read(ptr, ZR060_CFSR);
-
- zr36060_read(ptr, 0);
- return ptr->status;
-}
-
-/* =========================================================================
- Local helper function:
-
- scale factor read
- ========================================================================= */
-
-/* scale factor is kept in datastructure */
-static u16
-zr36060_read_scalefactor (struct zr36060 *ptr)
-{
- ptr->scalefact = (zr36060_read(ptr, ZR060_SF_HI) << 8) |
- (zr36060_read(ptr, ZR060_SF_LO) & 0xFF);
-
- /* leave 0 selected for an eventually GO from master */
- zr36060_read(ptr, 0);
- return ptr->scalefact;
-}
-
-/* =========================================================================
- Local helper function:
-
- wait if codec is ready to proceed (end of processing) or time is over
- ========================================================================= */
-
-static void
-zr36060_wait_end (struct zr36060 *ptr)
-{
- int i = 0;
-
- while (zr36060_read_status(ptr) & ZR060_CFSR_Busy) {
- udelay(1);
- if (i++ > 200000) { // 200ms, there is for sure something wrong!!!
- dprintk(1,
- "%s: timeout at wait_end (last status: 0x%02x)\n",
- ptr->name, ptr->status);
- break;
- }
- }
-}
-
-/* =========================================================================
- Local helper function:
-
- basic test of "connectivity", writes/reads to/from memory the SOF marker
- ========================================================================= */
-
-static int
-zr36060_basic_test (struct zr36060 *ptr)
-{
- if ((zr36060_read(ptr, ZR060_IDR_DEV) != 0x33) &&
- (zr36060_read(ptr, ZR060_IDR_REV) != 0x01)) {
- dprintk(1,
- KERN_ERR
- "%s: attach failed, can't connect to jpeg processor!\n",
- ptr->name);
- return -ENXIO;
- }
-
- zr36060_wait_end(ptr);
- if (ptr->status & ZR060_CFSR_Busy) {
- dprintk(1,
- KERN_ERR
- "%s: attach failed, jpeg processor failed (end flag)!\n",
- ptr->name);
- return -EBUSY;
- }
-
- return 0; /* looks good! */
-}
-
-/* =========================================================================
- Local helper function:
-
- simple loop for pushing the init datasets
- ========================================================================= */
-
-static int
-zr36060_pushit (struct zr36060 *ptr,
- u16 startreg,
- u16 len,
- const char *data)
-{
- int i = 0;
-
- dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
- startreg, len);
- while (i < len) {
- zr36060_write(ptr, startreg++, data[i++]);
- }
-
- return i;
-}
-
-/* =========================================================================
- Basic datasets:
-
- jpeg baseline setup data (you find it on lots places in internet, or just
- extract it from any regular .jpg image...)
-
- Could be variable, but until it's not needed it they are just fixed to save
- memory. Otherwise expand zr36060 structure with arrays, push the values to
- it and initialize from there, as e.g. the linux zr36057/60 driver does it.
- ========================================================================= */
-
-static const char zr36060_dqt[0x86] = {
- 0xff, 0xdb, //Marker: DQT
- 0x00, 0x84, //Length: 2*65+2
- 0x00, //Pq,Tq first table
- 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
- 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
- 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
- 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
- 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
- 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
- 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
- 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
- 0x01, //Pq,Tq second table
- 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
- 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
-};
-
-static const char zr36060_dht[0x1a4] = {
- 0xff, 0xc4, //Marker: DHT
- 0x01, 0xa2, //Length: 2*AC, 2*DC
- 0x00, //DC first table
- 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
- 0x01, //DC second table
- 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
- 0x10, //AC first table
- 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
- 0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
- 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
- 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
- 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
- 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
- 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
- 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
- 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
- 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
- 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
- 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
- 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
- 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
- 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
- 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
- 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
- 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- 0xF8, 0xF9, 0xFA,
- 0x11, //AC second table
- 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
- 0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
- 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
- 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
- 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
- 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
- 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
- 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
- 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
- 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
- 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
- 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
- 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
- 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
- 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
- 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
- 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
- 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
- 0xF9, 0xFA
-};
-
-/* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
-#define NO_OF_COMPONENTS 0x3 //Y,U,V
-#define BASELINE_PRECISION 0x8 //MCU size (?)
-static const char zr36060_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT
-static const char zr36060_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC
-static const char zr36060_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC
-
-/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
-static const char zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
-static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
-
-/* =========================================================================
- Local helper functions:
-
- calculation and setup of parameter-dependent JPEG baseline segments
- (needed for compression only)
- ========================================================================= */
-
-/* ------------------------------------------------------------------------- */
-
-/* SOF (start of frame) segment depends on width, height and sampling ratio
- of each color component */
-
-static int
-zr36060_set_sof (struct zr36060 *ptr)
-{
- char sof_data[34]; // max. size of register set
- int i;
-
- dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
- ptr->width, ptr->height, NO_OF_COMPONENTS);
- sof_data[0] = 0xff;
- sof_data[1] = 0xc0;
- sof_data[2] = 0x00;
- sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
- sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36060
- sof_data[5] = (ptr->height) >> 8;
- sof_data[6] = (ptr->height) & 0xff;
- sof_data[7] = (ptr->width) >> 8;
- sof_data[8] = (ptr->width) & 0xff;
- sof_data[9] = NO_OF_COMPONENTS;
- for (i = 0; i < NO_OF_COMPONENTS; i++) {
- sof_data[10 + (i * 3)] = i; // index identifier
- sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) |
- (ptr->v_samp_ratio[i]); // sampling ratios
- sof_data[12 + (i * 3)] = zr36060_tq[i]; // Q table selection
- }
- return zr36060_pushit(ptr, ZR060_SOF_IDX,
- (3 * NO_OF_COMPONENTS) + 10, sof_data);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* SOS (start of scan) segment depends on the used scan components
- of each color component */
-
-static int
-zr36060_set_sos (struct zr36060 *ptr)
-{
- char sos_data[16]; // max. size of register set
- int i;
-
- dprintk(3, "%s: write SOS\n", ptr->name);
- sos_data[0] = 0xff;
- sos_data[1] = 0xda;
- sos_data[2] = 0x00;
- sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
- sos_data[4] = NO_OF_COMPONENTS;
- for (i = 0; i < NO_OF_COMPONENTS; i++) {
- sos_data[5 + (i * 2)] = i; // index
- sos_data[6 + (i * 2)] = (zr36060_td[i] << 4) |
- zr36060_ta[i]; // AC/DC tbl.sel.
- }
- sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start
- sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3f;
- sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
- return zr36060_pushit(ptr, ZR060_SOS_IDX,
- 4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
- sos_data);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* DRI (define restart interval) */
-
-static int
-zr36060_set_dri (struct zr36060 *ptr)
-{
- char dri_data[6]; // max. size of register set
-
- dprintk(3, "%s: write DRI\n", ptr->name);
- dri_data[0] = 0xff;
- dri_data[1] = 0xdd;
- dri_data[2] = 0x00;
- dri_data[3] = 0x04;
- dri_data[4] = (ptr->dri) >> 8;
- dri_data[5] = (ptr->dri) & 0xff;
- return zr36060_pushit(ptr, ZR060_DRI_IDX, 6, dri_data);
-}
-
-/* =========================================================================
- Setup function:
-
- Setup compression/decompression of Zoran's JPEG processor
- ( see also zoran 36060 manual )
-
- ... sorry for the spaghetti code ...
- ========================================================================= */
-static void
-zr36060_init (struct zr36060 *ptr)
-{
- int sum = 0;
- long bitcnt, tmp;
-
- if (ptr->mode == CODEC_DO_COMPRESSION) {
- dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
-
- zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
-
- /* 060 communicates with 067 in master mode */
- zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr);
-
- /* Compression with or without variable scale factor */
- /*FIXME: What about ptr->bitrate_ctrl? */
- zr36060_write(ptr, ZR060_CMR,
- ZR060_CMR_Comp | ZR060_CMR_Pass2 |
- ZR060_CMR_BRB);
-
- /* Must be zero */
- zr36060_write(ptr, ZR060_MBZ, 0x00);
- zr36060_write(ptr, ZR060_TCR_HI, 0x00);
- zr36060_write(ptr, ZR060_TCR_LO, 0x00);
-
- /* Disable all IRQs - no DataErr means autoreset */
- zr36060_write(ptr, ZR060_IMR, 0);
-
- /* volume control settings */
- zr36060_write(ptr, ZR060_SF_HI, ptr->scalefact >> 8);
- zr36060_write(ptr, ZR060_SF_LO, ptr->scalefact & 0xff);
-
- zr36060_write(ptr, ZR060_AF_HI, 0xff);
- zr36060_write(ptr, ZR060_AF_M, 0xff);
- zr36060_write(ptr, ZR060_AF_LO, 0xff);
-
- /* setup the variable jpeg tables */
- sum += zr36060_set_sof(ptr);
- sum += zr36060_set_sos(ptr);
- sum += zr36060_set_dri(ptr);
-
- /* setup the fixed jpeg tables - maybe variable, though -
- * (see table init section above) */
- sum +=
- zr36060_pushit(ptr, ZR060_DQT_IDX, sizeof(zr36060_dqt),
- zr36060_dqt);
- sum +=
- zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht),
- zr36060_dht);
- zr36060_write(ptr, ZR060_APP_IDX, 0xff);
- zr36060_write(ptr, ZR060_APP_IDX + 1, 0xe0 + ptr->app.appn);
- zr36060_write(ptr, ZR060_APP_IDX + 2, 0x00);
- zr36060_write(ptr, ZR060_APP_IDX + 3, ptr->app.len + 2);
- sum += zr36060_pushit(ptr, ZR060_APP_IDX + 4, 60,
- ptr->app.data) + 4;
- zr36060_write(ptr, ZR060_COM_IDX, 0xff);
- zr36060_write(ptr, ZR060_COM_IDX + 1, 0xfe);
- zr36060_write(ptr, ZR060_COM_IDX + 2, 0x00);
- zr36060_write(ptr, ZR060_COM_IDX + 3, ptr->com.len + 2);
- sum += zr36060_pushit(ptr, ZR060_COM_IDX + 4, 60,
- ptr->com.data) + 4;
-
- /* setup misc. data for compression (target code sizes) */
-
- /* size of compressed code to reach without header data */
- sum = ptr->real_code_vol - sum;
- bitcnt = sum << 3; /* need the size in bits */
-
- tmp = bitcnt >> 16;
- dprintk(3,
- "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
- ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
- zr36060_write(ptr, ZR060_TCV_NET_HI, tmp >> 8);
- zr36060_write(ptr, ZR060_TCV_NET_MH, tmp & 0xff);
- tmp = bitcnt & 0xffff;
- zr36060_write(ptr, ZR060_TCV_NET_ML, tmp >> 8);
- zr36060_write(ptr, ZR060_TCV_NET_LO, tmp & 0xff);
-
- bitcnt -= bitcnt >> 7; // bits without stuffing
- bitcnt -= ((bitcnt * 5) >> 6); // bits without eob
-
- tmp = bitcnt >> 16;
- dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n",
- ptr->name, bitcnt, tmp);
- zr36060_write(ptr, ZR060_TCV_DATA_HI, tmp >> 8);
- zr36060_write(ptr, ZR060_TCV_DATA_MH, tmp & 0xff);
- tmp = bitcnt & 0xffff;
- zr36060_write(ptr, ZR060_TCV_DATA_ML, tmp >> 8);
- zr36060_write(ptr, ZR060_TCV_DATA_LO, tmp & 0xff);
-
- /* JPEG markers to be included in the compressed stream */
- zr36060_write(ptr, ZR060_MER,
- ZR060_MER_DQT | ZR060_MER_DHT |
- ((ptr->com.len > 0) ? ZR060_MER_Com : 0) |
- ((ptr->app.len > 0) ? ZR060_MER_App : 0));
-
- /* Setup the Video Frontend */
- /* Limit pixel range to 16..235 as per CCIR-601 */
- zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range);
-
- } else {
- dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
-
- zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
-
- /* 060 communicates with 067 in master mode */
- zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr);
-
- /* Decompression */
- zr36060_write(ptr, ZR060_CMR, 0);
-
- /* Must be zero */
- zr36060_write(ptr, ZR060_MBZ, 0x00);
- zr36060_write(ptr, ZR060_TCR_HI, 0x00);
- zr36060_write(ptr, ZR060_TCR_LO, 0x00);
-
- /* Disable all IRQs - no DataErr means autoreset */
- zr36060_write(ptr, ZR060_IMR, 0);
-
- /* setup misc. data for expansion */
- zr36060_write(ptr, ZR060_MER, 0);
-
- /* setup the fixed jpeg tables - maybe variable, though -
- * (see table init section above) */
- zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht),
- zr36060_dht);
-
- /* Setup the Video Frontend */
- //zr36060_write(ptr, ZR060_VCR, ZR060_VCR_FIExt);
- //this doesn't seem right and doesn't work...
- zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range);
- }
-
- /* Load the tables */
- zr36060_write(ptr, ZR060_LOAD,
- ZR060_LOAD_SyncRst | ZR060_LOAD_Load);
- zr36060_wait_end(ptr);
- dprintk(2, "%s: Status after table preload: 0x%02x\n", ptr->name,
- ptr->status);
-
- if (ptr->status & ZR060_CFSR_Busy) {
- dprintk(1, KERN_ERR "%s: init aborted!\n", ptr->name);
- return; // something is wrong, its timed out!!!!
- }
-}
-
-/* =========================================================================
- CODEC API FUNCTIONS
-
- this functions are accessed by the master via the API structure
- ========================================================================= */
-
-/* set compression/expansion mode and launches codec -
- this should be the last call from the master before starting processing */
-static int
-zr36060_set_mode (struct videocodec *codec,
- int mode)
-{
- struct zr36060 *ptr = (struct zr36060 *) codec->data;
-
- dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
-
- if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
- return -EINVAL;
-
- ptr->mode = mode;
- zr36060_init(ptr);
-
- return 0;
-}
-
-/* set picture size (norm is ignored as the codec doesn't know about it) */
-static int
-zr36060_set_video (struct videocodec *codec,
- struct tvnorm *norm,
- struct vfe_settings *cap,
- struct vfe_polarity *pol)
-{
- struct zr36060 *ptr = (struct zr36060 *) codec->data;
- u32 reg;
- int size;
-
- dprintk(2, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name,
- cap->x, cap->y, cap->width, cap->height, cap->decimation);
-
- /* if () return -EINVAL;
- * trust the master driver that it knows what it does - so
- * we allow invalid startx/y and norm for now ... */
- ptr->width = cap->width / (cap->decimation & 0xff);
- ptr->height = cap->height / (cap->decimation >> 8);
-
- zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
-
- /* Note that VSPol/HSPol bits in zr36060 have the opposite
- * meaning of their zr360x7 counterparts with the same names
- * N.b. for VSPol this is only true if FIVEdge = 0 (default,
- * left unchanged here - in accordance with datasheet).
- */
- reg = (!pol->vsync_pol ? ZR060_VPR_VSPol : 0)
- | (!pol->hsync_pol ? ZR060_VPR_HSPol : 0)
- | (pol->field_pol ? ZR060_VPR_FIPol : 0)
- | (pol->blank_pol ? ZR060_VPR_BLPol : 0)
- | (pol->subimg_pol ? ZR060_VPR_SImgPol : 0)
- | (pol->poe_pol ? ZR060_VPR_PoePol : 0)
- | (pol->pvalid_pol ? ZR060_VPR_PValPol : 0)
- | (pol->vclk_pol ? ZR060_VPR_VCLKPol : 0);
- zr36060_write(ptr, ZR060_VPR, reg);
-
- reg = 0;
- switch (cap->decimation & 0xff) {
- default:
- case 1:
- break;
-
- case 2:
- reg |= ZR060_SR_HScale2;
- break;
-
- case 4:
- reg |= ZR060_SR_HScale4;
- break;
- }
-
- switch (cap->decimation >> 8) {
- default:
- case 1:
- break;
-
- case 2:
- reg |= ZR060_SR_VScale;
- break;
- }
- zr36060_write(ptr, ZR060_SR, reg);
-
- zr36060_write(ptr, ZR060_BCR_Y, 0x00);
- zr36060_write(ptr, ZR060_BCR_U, 0x80);
- zr36060_write(ptr, ZR060_BCR_V, 0x80);
-
- /* sync generator */
-
- reg = norm->Ht - 1; /* Vtotal */
- zr36060_write(ptr, ZR060_SGR_VTOTAL_HI, (reg >> 8) & 0xff);
- zr36060_write(ptr, ZR060_SGR_VTOTAL_LO, (reg >> 0) & 0xff);
-
- reg = norm->Wt - 1; /* Htotal */
- zr36060_write(ptr, ZR060_SGR_HTOTAL_HI, (reg >> 8) & 0xff);
- zr36060_write(ptr, ZR060_SGR_HTOTAL_LO, (reg >> 0) & 0xff);
-
- reg = 6 - 1; /* VsyncSize */
- zr36060_write(ptr, ZR060_SGR_VSYNC, reg);
-
- //reg = 30 - 1; /* HsyncSize */
-///*CP*/ reg = (zr->params.norm == 1 ? 57 : 68);
- reg = 68;
- zr36060_write(ptr, ZR060_SGR_HSYNC, reg);
-
- reg = norm->VStart - 1; /* BVstart */
- zr36060_write(ptr, ZR060_SGR_BVSTART, reg);
-
- reg += norm->Ha / 2; /* BVend */
- zr36060_write(ptr, ZR060_SGR_BVEND_HI, (reg >> 8) & 0xff);
- zr36060_write(ptr, ZR060_SGR_BVEND_LO, (reg >> 0) & 0xff);
-
- reg = norm->HStart - 1; /* BHstart */
- zr36060_write(ptr, ZR060_SGR_BHSTART, reg);
-
- reg += norm->Wa; /* BHend */
- zr36060_write(ptr, ZR060_SGR_BHEND_HI, (reg >> 8) & 0xff);
- zr36060_write(ptr, ZR060_SGR_BHEND_LO, (reg >> 0) & 0xff);
-
- /* active area */
- reg = cap->y + norm->VStart; /* Vstart */
- zr36060_write(ptr, ZR060_AAR_VSTART_HI, (reg >> 8) & 0xff);
- zr36060_write(ptr, ZR060_AAR_VSTART_LO, (reg >> 0) & 0xff);
-
- reg += cap->height; /* Vend */
- zr36060_write(ptr, ZR060_AAR_VEND_HI, (reg >> 8) & 0xff);
- zr36060_write(ptr, ZR060_AAR_VEND_LO, (reg >> 0) & 0xff);
-
- reg = cap->x + norm->HStart; /* Hstart */
- zr36060_write(ptr, ZR060_AAR_HSTART_HI, (reg >> 8) & 0xff);
- zr36060_write(ptr, ZR060_AAR_HSTART_LO, (reg >> 0) & 0xff);
-
- reg += cap->width; /* Hend */
- zr36060_write(ptr, ZR060_AAR_HEND_HI, (reg >> 8) & 0xff);
- zr36060_write(ptr, ZR060_AAR_HEND_LO, (reg >> 0) & 0xff);
-
- /* subimage area */
- reg = norm->VStart - 4; /* SVstart */
- zr36060_write(ptr, ZR060_SWR_VSTART_HI, (reg >> 8) & 0xff);
- zr36060_write(ptr, ZR060_SWR_VSTART_LO, (reg >> 0) & 0xff);
-
- reg += norm->Ha / 2 + 8; /* SVend */
- zr36060_write(ptr, ZR060_SWR_VEND_HI, (reg >> 8) & 0xff);
- zr36060_write(ptr, ZR060_SWR_VEND_LO, (reg >> 0) & 0xff);
-
- reg = norm->HStart /*+ 64 */ - 4; /* SHstart */
- zr36060_write(ptr, ZR060_SWR_HSTART_HI, (reg >> 8) & 0xff);
- zr36060_write(ptr, ZR060_SWR_HSTART_LO, (reg >> 0) & 0xff);
-
- reg += norm->Wa + 8; /* SHend */
- zr36060_write(ptr, ZR060_SWR_HEND_HI, (reg >> 8) & 0xff);
- zr36060_write(ptr, ZR060_SWR_HEND_LO, (reg >> 0) & 0xff);
-
- size = ptr->width * ptr->height;
- /* Target compressed field size in bits: */
- size = size * 16; /* uncompressed size in bits */
- /* (Ronald) by default, quality = 100 is a compression
- * ratio 1:2. Setting low_bitrate (insmod option) sets
- * it to 1:4 (instead of 1:2, zr36060 max) as limit because the
- * buz can't handle more at decimation=1... Use low_bitrate if
- * you have a Buz, unless you know what you're doing */
- size = size * cap->quality / (low_bitrate ? 400 : 200);
- /* Lower limit (arbitrary, 1 KB) */
- if (size < 8192)
- size = 8192;
- /* Upper limit: 7/8 of the code buffers */
- if (size > ptr->total_code_vol * 7)
- size = ptr->total_code_vol * 7;
-
- ptr->real_code_vol = size >> 3; /* in bytes */
-
- /* the MBCVR is the *maximum* block volume, according to the
- * JPEG ISO specs, this shouldn't be used, since that allows
- * for the best encoding quality. So set it to it's max value */
- reg = ptr->max_block_vol;
- zr36060_write(ptr, ZR060_MBCVR, reg);
-
- return 0;
-}
-
-/* additional control functions */
-static int
-zr36060_control (struct videocodec *codec,
- int type,
- int size,
- void *data)
-{
- struct zr36060 *ptr = (struct zr36060 *) codec->data;
- int *ival = (int *) data;
-
- dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
- size);
-
- switch (type) {
- case CODEC_G_STATUS: /* get last status */
- if (size != sizeof(int))
- return -EFAULT;
- zr36060_read_status(ptr);
- *ival = ptr->status;
- break;
-
- case CODEC_G_CODEC_MODE:
- if (size != sizeof(int))
- return -EFAULT;
- *ival = CODEC_MODE_BJPG;
- break;
-
- case CODEC_S_CODEC_MODE:
- if (size != sizeof(int))
- return -EFAULT;
- if (*ival != CODEC_MODE_BJPG)
- return -EINVAL;
- /* not needed, do nothing */
- return 0;
-
- case CODEC_G_VFE:
- case CODEC_S_VFE:
- /* not needed, do nothing */
- return 0;
-
- case CODEC_S_MMAP:
- /* not available, give an error */
- return -ENXIO;
-
- case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */
- if (size != sizeof(int))
- return -EFAULT;
- *ival = ptr->total_code_vol;
- break;
-
- case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */
- if (size != sizeof(int))
- return -EFAULT;
- ptr->total_code_vol = *ival;
- ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
- break;
-
- case CODEC_G_JPEG_SCALE: /* get scaling factor */
- if (size != sizeof(int))
- return -EFAULT;
- *ival = zr36060_read_scalefactor(ptr);
- break;
-
- case CODEC_S_JPEG_SCALE: /* set scaling factor */
- if (size != sizeof(int))
- return -EFAULT;
- ptr->scalefact = *ival;
- break;
-
- case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */
- struct jpeg_app_marker *app = data;
-
- if (size != sizeof(struct jpeg_app_marker))
- return -EFAULT;
-
- *app = ptr->app;
- break;
- }
-
- case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */
- struct jpeg_app_marker *app = data;
-
- if (size != sizeof(struct jpeg_app_marker))
- return -EFAULT;
-
- ptr->app = *app;
- break;
- }
-
- case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */
- struct jpeg_com_marker *com = data;
-
- if (size != sizeof(struct jpeg_com_marker))
- return -EFAULT;
-
- *com = ptr->com;
- break;
- }
-
- case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */
- struct jpeg_com_marker *com = data;
-
- if (size != sizeof(struct jpeg_com_marker))
- return -EFAULT;
-
- ptr->com = *com;
- break;
- }
-
- default:
- return -EINVAL;
- }
-
- return size;
-}
-
-/* =========================================================================
- Exit and unregister function:
-
- Deinitializes Zoran's JPEG processor
- ========================================================================= */
-
-static int
-zr36060_unset (struct videocodec *codec)
-{
- struct zr36060 *ptr = codec->data;
-
- if (ptr) {
- /* do wee need some codec deinit here, too ???? */
-
- dprintk(1, "%s: finished codec #%d\n", ptr->name,
- ptr->num);
- kfree(ptr);
- codec->data = NULL;
-
- zr36060_codecs--;
- return 0;
- }
-
- return -EFAULT;
-}
-
-/* =========================================================================
- Setup and registry function:
-
- Initializes Zoran's JPEG processor
-
- Also sets pixel size, average code size, mode (compr./decompr.)
- (the given size is determined by the processor with the video interface)
- ========================================================================= */
-
-static int
-zr36060_setup (struct videocodec *codec)
-{
- struct zr36060 *ptr;
- int res;
-
- dprintk(2, "zr36060: initializing MJPEG subsystem #%d.\n",
- zr36060_codecs);
-
- if (zr36060_codecs == MAX_CODECS) {
- dprintk(1,
- KERN_ERR "zr36060: Can't attach more codecs!\n");
- return -ENOSPC;
- }
- //mem structure init
- codec->data = ptr = kzalloc(sizeof(struct zr36060), GFP_KERNEL);
- if (NULL == ptr) {
- dprintk(1, KERN_ERR "zr36060: Can't get enough memory!\n");
- return -ENOMEM;
- }
-
- snprintf(ptr->name, sizeof(ptr->name), "zr36060[%d]",
- zr36060_codecs);
- ptr->num = zr36060_codecs++;
- ptr->codec = codec;
-
- //testing
- res = zr36060_basic_test(ptr);
- if (res < 0) {
- zr36060_unset(codec);
- return res;
- }
- //final setup
- memcpy(ptr->h_samp_ratio, zr36060_decimation_h, 8);
- memcpy(ptr->v_samp_ratio, zr36060_decimation_v, 8);
-
- ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag
- * (what is the difference?) */
- ptr->mode = CODEC_DO_COMPRESSION;
- ptr->width = 384;
- ptr->height = 288;
- ptr->total_code_vol = 16000; /* CHECKME */
- ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
- ptr->max_block_vol = 240; /* CHECKME, was 120 is 240 */
- ptr->scalefact = 0x100;
- ptr->dri = 1; /* CHECKME, was 8 is 1 */
-
- /* by default, no COM or APP markers - app should set those */
- ptr->com.len = 0;
- ptr->app.appn = 0;
- ptr->app.len = 0;
-
- zr36060_init(ptr);
-
- dprintk(1, KERN_INFO "%s: codec attached and running\n",
- ptr->name);
-
- return 0;
-}
-
-static const struct videocodec zr36060_codec = {
- .owner = THIS_MODULE,
- .name = "zr36060",
- .magic = 0L, // magic not used
- .flags =
- CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
- CODEC_FLAG_DECODER | CODEC_FLAG_VFE,
- .type = CODEC_TYPE_ZR36060,
- .setup = zr36060_setup, // functionality
- .unset = zr36060_unset,
- .set_mode = zr36060_set_mode,
- .set_video = zr36060_set_video,
- .control = zr36060_control,
- // others are not used
-};
-
-/* =========================================================================
- HOOK IN DRIVER AS KERNEL MODULE
- ========================================================================= */
-
-static int __init
-zr36060_init_module (void)
-{
- //dprintk(1, "zr36060 driver %s\n",ZR060_VERSION);
- zr36060_codecs = 0;
- return videocodec_register(&zr36060_codec);
-}
-
-static void __exit
-zr36060_cleanup_module (void)
-{
- if (zr36060_codecs) {
- dprintk(1,
- "zr36060: something's wrong - %d codecs left somehow.\n",
- zr36060_codecs);
- }
-
- /* however, we can't just stay alive */
- videocodec_unregister(&zr36060_codec);
-}
-
-module_init(zr36060_init_module);
-module_exit(zr36060_cleanup_module);
-
-MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@skynet.be>");
-MODULE_DESCRIPTION("Driver module for ZR36060 jpeg processors "
- ZR060_VERSION);
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zoran/zr36060.h b/drivers/media/video/zoran/zr36060.h
deleted file mode 100644
index 914ffa4ad8d..00000000000
--- a/drivers/media/video/zoran/zr36060.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Zoran ZR36060 basic configuration functions - header file
- *
- * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be>
- *
- * $Id: zr36060.h,v 1.1.1.1.2.3 2003/01/14 21:18:47 rbultje Exp $
- *
- * ------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * ------------------------------------------------------------------------
- */
-
-#ifndef ZR36060_H
-#define ZR36060_H
-
-#include "videocodec.h"
-
-/* data stored for each zoran jpeg codec chip */
-struct zr36060 {
- char name[32];
- int num;
- /* io datastructure */
- struct videocodec *codec;
- // last coder status
- __u8 status;
- // actual coder setup
- int mode;
-
- __u16 width;
- __u16 height;
-
- __u16 bitrate_ctrl;
-
- __u32 total_code_vol;
- __u32 real_code_vol;
- __u16 max_block_vol;
-
- __u8 h_samp_ratio[8];
- __u8 v_samp_ratio[8];
- __u16 scalefact;
- __u16 dri;
-
- /* app/com marker data */
- struct jpeg_app_marker app;
- struct jpeg_com_marker com;
-};
-
-/* ZR36060 register addresses */
-#define ZR060_LOAD 0x000
-#define ZR060_CFSR 0x001
-#define ZR060_CIR 0x002
-#define ZR060_CMR 0x003
-#define ZR060_MBZ 0x004
-#define ZR060_MBCVR 0x005
-#define ZR060_MER 0x006
-#define ZR060_IMR 0x007
-#define ZR060_ISR 0x008
-#define ZR060_TCV_NET_HI 0x009
-#define ZR060_TCV_NET_MH 0x00a
-#define ZR060_TCV_NET_ML 0x00b
-#define ZR060_TCV_NET_LO 0x00c
-#define ZR060_TCV_DATA_HI 0x00d
-#define ZR060_TCV_DATA_MH 0x00e
-#define ZR060_TCV_DATA_ML 0x00f
-#define ZR060_TCV_DATA_LO 0x010
-#define ZR060_SF_HI 0x011
-#define ZR060_SF_LO 0x012
-#define ZR060_AF_HI 0x013
-#define ZR060_AF_M 0x014
-#define ZR060_AF_LO 0x015
-#define ZR060_ACV_HI 0x016
-#define ZR060_ACV_MH 0x017
-#define ZR060_ACV_ML 0x018
-#define ZR060_ACV_LO 0x019
-#define ZR060_ACT_HI 0x01a
-#define ZR060_ACT_MH 0x01b
-#define ZR060_ACT_ML 0x01c
-#define ZR060_ACT_LO 0x01d
-#define ZR060_ACV_TRUN_HI 0x01e
-#define ZR060_ACV_TRUN_MH 0x01f
-#define ZR060_ACV_TRUN_ML 0x020
-#define ZR060_ACV_TRUN_LO 0x021
-#define ZR060_IDR_DEV 0x022
-#define ZR060_IDR_REV 0x023
-#define ZR060_TCR_HI 0x024
-#define ZR060_TCR_LO 0x025
-#define ZR060_VCR 0x030
-#define ZR060_VPR 0x031
-#define ZR060_SR 0x032
-#define ZR060_BCR_Y 0x033
-#define ZR060_BCR_U 0x034
-#define ZR060_BCR_V 0x035
-#define ZR060_SGR_VTOTAL_HI 0x036
-#define ZR060_SGR_VTOTAL_LO 0x037
-#define ZR060_SGR_HTOTAL_HI 0x038
-#define ZR060_SGR_HTOTAL_LO 0x039
-#define ZR060_SGR_VSYNC 0x03a
-#define ZR060_SGR_HSYNC 0x03b
-#define ZR060_SGR_BVSTART 0x03c
-#define ZR060_SGR_BHSTART 0x03d
-#define ZR060_SGR_BVEND_HI 0x03e
-#define ZR060_SGR_BVEND_LO 0x03f
-#define ZR060_SGR_BHEND_HI 0x040
-#define ZR060_SGR_BHEND_LO 0x041
-#define ZR060_AAR_VSTART_HI 0x042
-#define ZR060_AAR_VSTART_LO 0x043
-#define ZR060_AAR_VEND_HI 0x044
-#define ZR060_AAR_VEND_LO 0x045
-#define ZR060_AAR_HSTART_HI 0x046
-#define ZR060_AAR_HSTART_LO 0x047
-#define ZR060_AAR_HEND_HI 0x048
-#define ZR060_AAR_HEND_LO 0x049
-#define ZR060_SWR_VSTART_HI 0x04a
-#define ZR060_SWR_VSTART_LO 0x04b
-#define ZR060_SWR_VEND_HI 0x04c
-#define ZR060_SWR_VEND_LO 0x04d
-#define ZR060_SWR_HSTART_HI 0x04e
-#define ZR060_SWR_HSTART_LO 0x04f
-#define ZR060_SWR_HEND_HI 0x050
-#define ZR060_SWR_HEND_LO 0x051
-
-#define ZR060_SOF_IDX 0x060
-#define ZR060_SOS_IDX 0x07a
-#define ZR060_DRI_IDX 0x0c0
-#define ZR060_DQT_IDX 0x0cc
-#define ZR060_DHT_IDX 0x1d4
-#define ZR060_APP_IDX 0x380
-#define ZR060_COM_IDX 0x3c0
-
-/* ZR36060 LOAD register bits */
-
-#define ZR060_LOAD_Load (1 << 7)
-#define ZR060_LOAD_SyncRst (1 << 0)
-
-/* ZR36060 Code FIFO Status register bits */
-
-#define ZR060_CFSR_Busy (1 << 7)
-#define ZR060_CFSR_CBusy (1 << 2)
-#define ZR060_CFSR_CFIFO (3 << 0)
-
-/* ZR36060 Code Interface register */
-
-#define ZR060_CIR_Code16 (1 << 7)
-#define ZR060_CIR_Endian (1 << 6)
-#define ZR060_CIR_CFIS (1 << 2)
-#define ZR060_CIR_CodeMstr (1 << 0)
-
-/* ZR36060 Codec Mode register */
-
-#define ZR060_CMR_Comp (1 << 7)
-#define ZR060_CMR_ATP (1 << 6)
-#define ZR060_CMR_Pass2 (1 << 5)
-#define ZR060_CMR_TLM (1 << 4)
-#define ZR060_CMR_BRB (1 << 2)
-#define ZR060_CMR_FSF (1 << 1)
-
-/* ZR36060 Markers Enable register */
-
-#define ZR060_MER_App (1 << 7)
-#define ZR060_MER_Com (1 << 6)
-#define ZR060_MER_DRI (1 << 5)
-#define ZR060_MER_DQT (1 << 4)
-#define ZR060_MER_DHT (1 << 3)
-
-/* ZR36060 Interrupt Mask register */
-
-#define ZR060_IMR_EOAV (1 << 3)
-#define ZR060_IMR_EOI (1 << 2)
-#define ZR060_IMR_End (1 << 1)
-#define ZR060_IMR_DataErr (1 << 0)
-
-/* ZR36060 Interrupt Status register */
-
-#define ZR060_ISR_ProCnt (3 << 6)
-#define ZR060_ISR_EOAV (1 << 3)
-#define ZR060_ISR_EOI (1 << 2)
-#define ZR060_ISR_End (1 << 1)
-#define ZR060_ISR_DataErr (1 << 0)
-
-/* ZR36060 Video Control register */
-
-#define ZR060_VCR_Video8 (1 << 7)
-#define ZR060_VCR_Range (1 << 6)
-#define ZR060_VCR_FIDet (1 << 3)
-#define ZR060_VCR_FIVedge (1 << 2)
-#define ZR060_VCR_FIExt (1 << 1)
-#define ZR060_VCR_SyncMstr (1 << 0)
-
-/* ZR36060 Video Polarity register */
-
-#define ZR060_VPR_VCLKPol (1 << 7)
-#define ZR060_VPR_PValPol (1 << 6)
-#define ZR060_VPR_PoePol (1 << 5)
-#define ZR060_VPR_SImgPol (1 << 4)
-#define ZR060_VPR_BLPol (1 << 3)
-#define ZR060_VPR_FIPol (1 << 2)
-#define ZR060_VPR_HSPol (1 << 1)
-#define ZR060_VPR_VSPol (1 << 0)
-
-/* ZR36060 Scaling register */
-
-#define ZR060_SR_VScale (1 << 2)
-#define ZR060_SR_HScale2 (1 << 0)
-#define ZR060_SR_HScale4 (2 << 0)
-
-#endif /*fndef ZR36060_H */
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
deleted file mode 100644
index 9afab35878b..00000000000
--- a/drivers/media/video/zr364xx.c
+++ /dev/null
@@ -1,1643 +0,0 @@
-/*
- * Zoran 364xx based USB webcam module version 0.73
- *
- * Allows you to use your USB webcam with V4L2 applications
- * This is still in heavy developpement !
- *
- * Copyright (C) 2004 Antoine Jacquet <royale@zerezo.com>
- * http://royale.zerezo.com/zr364xx/
- *
- * Heavily inspired by usb-skeleton.c, vicam.c, cpia.c and spca50x.c drivers
- * V4L2 version inspired by meye.c driver
- *
- * Some video buffer code by Lamarque based on s2255drv.c and vivi.c drivers.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/highmem.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-#include <media/videobuf-vmalloc.h>
-
-
-/* Version Information */
-#define DRIVER_VERSION "0.7.4"
-#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
-#define DRIVER_DESC "Zoran 364xx"
-
-
-/* Camera */
-#define FRAMES 1
-#define MAX_FRAME_SIZE 200000
-#define BUFFER_SIZE 0x1000
-#define CTRL_TIMEOUT 500
-
-#define ZR364XX_DEF_BUFS 4
-#define ZR364XX_READ_IDLE 0
-#define ZR364XX_READ_FRAME 1
-
-/* Debug macro */
-#define DBG(fmt, args...) \
- do { \
- if (debug) { \
- printk(KERN_INFO KBUILD_MODNAME " " fmt, ##args); \
- } \
- } while (0)
-
-/*#define FULL_DEBUG 1*/
-#ifdef FULL_DEBUG
-#define _DBG DBG
-#else
-#define _DBG(fmt, args...)
-#endif
-
-/* Init methods, need to find nicer names for these
- * the exact names of the chipsets would be the best if someone finds it */
-#define METHOD0 0
-#define METHOD1 1
-#define METHOD2 2
-#define METHOD3 3
-
-
-/* Module parameters */
-static int debug;
-static int mode;
-
-
-/* Module parameters interface */
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level");
-module_param(mode, int, 0644);
-MODULE_PARM_DESC(mode, "0 = 320x240, 1 = 160x120, 2 = 640x480");
-
-
-/* Devices supported by this driver
- * .driver_info contains the init method used by the camera */
-static struct usb_device_id device_table[] = {
- {USB_DEVICE(0x08ca, 0x0109), .driver_info = METHOD0 },
- {USB_DEVICE(0x041e, 0x4024), .driver_info = METHOD0 },
- {USB_DEVICE(0x0d64, 0x0108), .driver_info = METHOD0 },
- {USB_DEVICE(0x0546, 0x3187), .driver_info = METHOD0 },
- {USB_DEVICE(0x0d64, 0x3108), .driver_info = METHOD0 },
- {USB_DEVICE(0x0595, 0x4343), .driver_info = METHOD0 },
- {USB_DEVICE(0x0bb0, 0x500d), .driver_info = METHOD0 },
- {USB_DEVICE(0x0feb, 0x2004), .driver_info = METHOD0 },
- {USB_DEVICE(0x055f, 0xb500), .driver_info = METHOD0 },
- {USB_DEVICE(0x08ca, 0x2062), .driver_info = METHOD2 },
- {USB_DEVICE(0x052b, 0x1a18), .driver_info = METHOD1 },
- {USB_DEVICE(0x04c8, 0x0729), .driver_info = METHOD0 },
- {USB_DEVICE(0x04f2, 0xa208), .driver_info = METHOD0 },
- {USB_DEVICE(0x0784, 0x0040), .driver_info = METHOD1 },
- {USB_DEVICE(0x06d6, 0x0034), .driver_info = METHOD0 },
- {USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 },
- {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
- {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
- {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
- {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD3 },
- {USB_DEVICE(0x06d6, 0x003d), .driver_info = METHOD0 },
- {} /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-/* frame structure */
-struct zr364xx_framei {
- unsigned long ulState; /* ulState:ZR364XX_READ_IDLE,
- ZR364XX_READ_FRAME */
- void *lpvbits; /* image data */
- unsigned long cur_size; /* current data copied to it */
-};
-
-/* image buffer structure */
-struct zr364xx_bufferi {
- unsigned long dwFrames; /* number of frames in buffer */
- struct zr364xx_framei frame[FRAMES]; /* array of FRAME structures */
-};
-
-struct zr364xx_dmaqueue {
- struct list_head active;
- struct zr364xx_camera *cam;
-};
-
-struct zr364xx_pipeinfo {
- u32 transfer_size;
- u8 *transfer_buffer;
- u32 state;
- void *stream_urb;
- void *cam; /* back pointer to zr364xx_camera struct */
- u32 err_count;
- u32 idx;
-};
-
-struct zr364xx_fmt {
- char *name;
- u32 fourcc;
- int depth;
-};
-
-/* image formats. */
-static const struct zr364xx_fmt formats[] = {
- {
- .name = "JPG",
- .fourcc = V4L2_PIX_FMT_JPEG,
- .depth = 24
- }
-};
-
-/* Camera stuff */
-struct zr364xx_camera {
- struct usb_device *udev; /* save off the usb device pointer */
- struct usb_interface *interface;/* the interface for this device */
- struct v4l2_device v4l2_dev;
- struct v4l2_ctrl_handler ctrl_handler;
- struct video_device vdev; /* v4l video device */
- struct v4l2_fh *owner; /* owns the streaming */
- int nb;
- struct zr364xx_bufferi buffer;
- int skip;
- int width;
- int height;
- int method;
- struct mutex lock;
-
- spinlock_t slock;
- struct zr364xx_dmaqueue vidq;
- int last_frame;
- int cur_frame;
- unsigned long frame_count;
- int b_acquire;
- struct zr364xx_pipeinfo pipe[1];
-
- u8 read_endpoint;
-
- const struct zr364xx_fmt *fmt;
- struct videobuf_queue vb_vidq;
- bool was_streaming;
-};
-
-/* buffer for one video frame */
-struct zr364xx_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
- const struct zr364xx_fmt *fmt;
-};
-
-/* function used to send initialisation commands to the camera */
-static int send_control_msg(struct usb_device *udev, u8 request, u16 value,
- u16 index, unsigned char *cp, u16 size)
-{
- int status;
-
- unsigned char *transfer_buffer = kmalloc(size, GFP_KERNEL);
- if (!transfer_buffer) {
- dev_err(&udev->dev, "kmalloc(%d) failed\n", size);
- return -ENOMEM;
- }
-
- memcpy(transfer_buffer, cp, size);
-
- status = usb_control_msg(udev,
- usb_sndctrlpipe(udev, 0),
- request,
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_DEVICE, value, index,
- transfer_buffer, size, CTRL_TIMEOUT);
-
- kfree(transfer_buffer);
- return status;
-}
-
-
-/* Control messages sent to the camera to initialize it
- * and launch the capture */
-typedef struct {
- unsigned int value;
- unsigned int size;
- unsigned char *bytes;
-} message;
-
-/* method 0 */
-static unsigned char m0d1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-static unsigned char m0d2[] = { 0, 0, 0, 0, 0, 0 };
-static unsigned char m0d3[] = { 0, 0 };
-static message m0[] = {
- {0x1f30, 0, NULL},
- {0xd000, 0, NULL},
- {0x3370, sizeof(m0d1), m0d1},
- {0x2000, 0, NULL},
- {0x2f0f, 0, NULL},
- {0x2610, sizeof(m0d2), m0d2},
- {0xe107, 0, NULL},
- {0x2502, 0, NULL},
- {0x1f70, 0, NULL},
- {0xd000, 0, NULL},
- {0x9a01, sizeof(m0d3), m0d3},
- {-1, -1, NULL}
-};
-
-/* method 1 */
-static unsigned char m1d1[] = { 0xff, 0xff };
-static unsigned char m1d2[] = { 0x00, 0x00 };
-static message m1[] = {
- {0x1f30, 0, NULL},
- {0xd000, 0, NULL},
- {0xf000, 0, NULL},
- {0x2000, 0, NULL},
- {0x2f0f, 0, NULL},
- {0x2650, 0, NULL},
- {0xe107, 0, NULL},
- {0x2502, sizeof(m1d1), m1d1},
- {0x1f70, 0, NULL},
- {0xd000, 0, NULL},
- {0xd000, 0, NULL},
- {0xd000, 0, NULL},
- {0x9a01, sizeof(m1d2), m1d2},
- {-1, -1, NULL}
-};
-
-/* method 2 */
-static unsigned char m2d1[] = { 0xff, 0xff };
-static message m2[] = {
- {0x1f30, 0, NULL},
- {0xf000, 0, NULL},
- {0x2000, 0, NULL},
- {0x2f0f, 0, NULL},
- {0x2650, 0, NULL},
- {0xe107, 0, NULL},
- {0x2502, sizeof(m2d1), m2d1},
- {0x1f70, 0, NULL},
- {-1, -1, NULL}
-};
-
-/* init table */
-static message *init[4] = { m0, m1, m2, m2 };
-
-
-/* JPEG static data in header (Huffman table, etc) */
-static unsigned char header1[] = {
- 0xFF, 0xD8,
- /*
- 0xFF, 0xE0, 0x00, 0x10, 'J', 'F', 'I', 'F',
- 0x00, 0x01, 0x01, 0x00, 0x33, 0x8A, 0x00, 0x00, 0x33, 0x88,
- */
- 0xFF, 0xDB, 0x00, 0x84
-};
-static unsigned char header2[] = {
- 0xFF, 0xC4, 0x00, 0x1F, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
- 0xFF, 0xC4, 0x00, 0xB5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02,
- 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01,
- 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
- 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
- 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33,
- 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25,
- 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
- 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54,
- 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
- 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94,
- 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
- 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
- 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
- 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
- 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3,
- 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0xC4, 0x00, 0x1F,
- 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
- 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xFF, 0xC4, 0x00, 0xB5,
- 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05,
- 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11,
- 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
- 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1,
- 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16,
- 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27,
- 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
- 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
- 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84,
- 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96,
- 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
- 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA,
- 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3,
- 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5,
- 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- 0xF8, 0xF9, 0xFA, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01,
- 0x40, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01,
- 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11,
- 0x00, 0x3F, 0x00
-};
-static unsigned char header3;
-
-/* ------------------------------------------------------------------
- Videobuf operations
- ------------------------------------------------------------------*/
-
-static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
- unsigned int *size)
-{
- struct zr364xx_camera *cam = vq->priv_data;
-
- *size = cam->width * cam->height * (cam->fmt->depth >> 3);
-
- if (*count == 0)
- *count = ZR364XX_DEF_BUFS;
-
- if (*size * *count > ZR364XX_DEF_BUFS * 1024 * 1024)
- *count = (ZR364XX_DEF_BUFS * 1024 * 1024) / *size;
-
- return 0;
-}
-
-static void free_buffer(struct videobuf_queue *vq, struct zr364xx_buffer *buf)
-{
- _DBG("%s\n", __func__);
-
- if (in_interrupt())
- BUG();
-
- videobuf_vmalloc_free(&buf->vb);
- buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct zr364xx_camera *cam = vq->priv_data;
- struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer,
- vb);
- int rc;
-
- DBG("%s, field=%d, fmt name = %s\n", __func__, field, cam->fmt != NULL ?
- cam->fmt->name : "");
- if (cam->fmt == NULL)
- return -EINVAL;
-
- buf->vb.size = cam->width * cam->height * (cam->fmt->depth >> 3);
-
- if (buf->vb.baddr != 0 && buf->vb.bsize < buf->vb.size) {
- DBG("invalid buffer prepare\n");
- return -EINVAL;
- }
-
- buf->fmt = cam->fmt;
- buf->vb.width = cam->width;
- buf->vb.height = cam->height;
- buf->vb.field = field;
-
- if (buf->vb.state == VIDEOBUF_NEEDS_INIT) {
- rc = videobuf_iolock(vq, &buf->vb, NULL);
- if (rc < 0)
- goto fail;
- }
-
- buf->vb.state = VIDEOBUF_PREPARED;
- return 0;
-fail:
- free_buffer(vq, buf);
- return rc;
-}
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer,
- vb);
- struct zr364xx_camera *cam = vq->priv_data;
-
- _DBG("%s\n", __func__);
-
- buf->vb.state = VIDEOBUF_QUEUED;
- list_add_tail(&buf->vb.queue, &cam->vidq.active);
-}
-
-static void buffer_release(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer,
- vb);
-
- _DBG("%s\n", __func__);
- free_buffer(vq, buf);
-}
-
-static struct videobuf_queue_ops zr364xx_video_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-/********************/
-/* V4L2 integration */
-/********************/
-static int zr364xx_vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type);
-
-static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t count,
- loff_t * ppos)
-{
- struct zr364xx_camera *cam = video_drvdata(file);
- int err = 0;
-
- _DBG("%s\n", __func__);
-
- if (!buf)
- return -EINVAL;
-
- if (!count)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&cam->lock))
- return -ERESTARTSYS;
-
- err = zr364xx_vidioc_streamon(file, file->private_data,
- V4L2_BUF_TYPE_VIDEO_CAPTURE);
- if (err == 0) {
- DBG("%s: reading %d bytes at pos %d.\n", __func__,
- (int) count, (int) *ppos);
-
- /* NoMan Sux ! */
- err = videobuf_read_one(&cam->vb_vidq, buf, count, ppos,
- file->f_flags & O_NONBLOCK);
- }
- mutex_unlock(&cam->lock);
- return err;
-}
-
-/* video buffer vmalloc implementation based partly on VIVI driver which is
- * Copyright (c) 2006 by
- * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
- * Ted Walther <ted--a.t--enumera.com>
- * John Sokol <sokol--a.t--videotechnology.com>
- * http://v4l.videotechnology.com/
- *
- */
-static void zr364xx_fillbuff(struct zr364xx_camera *cam,
- struct zr364xx_buffer *buf,
- int jpgsize)
-{
- int pos = 0;
- struct timeval ts;
- const char *tmpbuf;
- char *vbuf = videobuf_to_vmalloc(&buf->vb);
- unsigned long last_frame;
-
- if (!vbuf)
- return;
-
- last_frame = cam->last_frame;
- if (last_frame != -1) {
- tmpbuf = (const char *)cam->buffer.frame[last_frame].lpvbits;
- switch (buf->fmt->fourcc) {
- case V4L2_PIX_FMT_JPEG:
- buf->vb.size = jpgsize;
- memcpy(vbuf, tmpbuf, buf->vb.size);
- break;
- default:
- printk(KERN_DEBUG KBUILD_MODNAME ": unknown format?\n");
- }
- cam->last_frame = -1;
- } else {
- printk(KERN_ERR KBUILD_MODNAME ": =======no frame\n");
- return;
- }
- DBG("%s: Buffer 0x%08lx size= %d\n", __func__,
- (unsigned long)vbuf, pos);
- /* tell v4l buffer was filled */
-
- buf->vb.field_count = cam->frame_count * 2;
- do_gettimeofday(&ts);
- buf->vb.ts = ts;
- buf->vb.state = VIDEOBUF_DONE;
-}
-
-static int zr364xx_got_frame(struct zr364xx_camera *cam, int jpgsize)
-{
- struct zr364xx_dmaqueue *dma_q = &cam->vidq;
- struct zr364xx_buffer *buf;
- unsigned long flags = 0;
- int rc = 0;
-
- DBG("wakeup: %p\n", &dma_q);
- spin_lock_irqsave(&cam->slock, flags);
-
- if (list_empty(&dma_q->active)) {
- DBG("No active queue to serve\n");
- rc = -1;
- goto unlock;
- }
- buf = list_entry(dma_q->active.next,
- struct zr364xx_buffer, vb.queue);
-
- if (!waitqueue_active(&buf->vb.done)) {
- /* no one active */
- rc = -1;
- goto unlock;
- }
- list_del(&buf->vb.queue);
- do_gettimeofday(&buf->vb.ts);
- DBG("[%p/%d] wakeup\n", buf, buf->vb.i);
- zr364xx_fillbuff(cam, buf, jpgsize);
- wake_up(&buf->vb.done);
- DBG("wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i);
-unlock:
- spin_unlock_irqrestore(&cam->slock, flags);
- return rc;
-}
-
-/* this function moves the usb stream read pipe data
- * into the system buffers.
- * returns 0 on success, EAGAIN if more data to process (call this
- * function again).
- */
-static int zr364xx_read_video_callback(struct zr364xx_camera *cam,
- struct zr364xx_pipeinfo *pipe_info,
- struct urb *purb)
-{
- unsigned char *pdest;
- unsigned char *psrc;
- s32 idx = -1;
- struct zr364xx_framei *frm;
- int i = 0;
- unsigned char *ptr = NULL;
-
- _DBG("buffer to user\n");
- idx = cam->cur_frame;
- frm = &cam->buffer.frame[idx];
-
- /* swap bytes if camera needs it */
- if (cam->method == METHOD0) {
- u16 *buf = (u16 *)pipe_info->transfer_buffer;
- for (i = 0; i < purb->actual_length/2; i++)
- swab16s(buf + i);
- }
-
- /* search done. now find out if should be acquiring */
- if (!cam->b_acquire) {
- /* we found a frame, but this channel is turned off */
- frm->ulState = ZR364XX_READ_IDLE;
- return -EINVAL;
- }
-
- psrc = (u8 *)pipe_info->transfer_buffer;
- ptr = pdest = frm->lpvbits;
-
- if (frm->ulState == ZR364XX_READ_IDLE) {
- frm->ulState = ZR364XX_READ_FRAME;
- frm->cur_size = 0;
-
- _DBG("jpeg header, ");
- memcpy(ptr, header1, sizeof(header1));
- ptr += sizeof(header1);
- header3 = 0;
- memcpy(ptr, &header3, 1);
- ptr++;
- memcpy(ptr, psrc, 64);
- ptr += 64;
- header3 = 1;
- memcpy(ptr, &header3, 1);
- ptr++;
- memcpy(ptr, psrc + 64, 64);
- ptr += 64;
- memcpy(ptr, header2, sizeof(header2));
- ptr += sizeof(header2);
- memcpy(ptr, psrc + 128,
- purb->actual_length - 128);
- ptr += purb->actual_length - 128;
- _DBG("header : %d %d %d %d %d %d %d %d %d\n",
- psrc[0], psrc[1], psrc[2],
- psrc[3], psrc[4], psrc[5],
- psrc[6], psrc[7], psrc[8]);
- frm->cur_size = ptr - pdest;
- } else {
- if (frm->cur_size + purb->actual_length > MAX_FRAME_SIZE) {
- dev_info(&cam->udev->dev,
- "%s: buffer (%d bytes) too small to hold "
- "frame data. Discarding frame data.\n",
- __func__, MAX_FRAME_SIZE);
- } else {
- pdest += frm->cur_size;
- memcpy(pdest, psrc, purb->actual_length);
- frm->cur_size += purb->actual_length;
- }
- }
- /*_DBG("cur_size %lu urb size %d\n", frm->cur_size,
- purb->actual_length);*/
-
- if (purb->actual_length < pipe_info->transfer_size) {
- _DBG("****************Buffer[%d]full*************\n", idx);
- cam->last_frame = cam->cur_frame;
- cam->cur_frame++;
- /* end of system frame ring buffer, start at zero */
- if (cam->cur_frame == cam->buffer.dwFrames)
- cam->cur_frame = 0;
-
- /* frame ready */
- /* go back to find the JPEG EOI marker */
- ptr = pdest = frm->lpvbits;
- ptr += frm->cur_size - 2;
- while (ptr > pdest) {
- if (*ptr == 0xFF && *(ptr + 1) == 0xD9
- && *(ptr + 2) == 0xFF)
- break;
- ptr--;
- }
- if (ptr == pdest)
- DBG("No EOI marker\n");
-
- /* Sometimes there is junk data in the middle of the picture,
- * we want to skip this bogus frames */
- while (ptr > pdest) {
- if (*ptr == 0xFF && *(ptr + 1) == 0xFF
- && *(ptr + 2) == 0xFF)
- break;
- ptr--;
- }
- if (ptr != pdest) {
- DBG("Bogus frame ? %d\n", ++(cam->nb));
- } else if (cam->b_acquire) {
- /* we skip the 2 first frames which are usually buggy */
- if (cam->skip)
- cam->skip--;
- else {
- _DBG("jpeg(%lu): %d %d %d %d %d %d %d %d\n",
- frm->cur_size,
- pdest[0], pdest[1], pdest[2], pdest[3],
- pdest[4], pdest[5], pdest[6], pdest[7]);
-
- zr364xx_got_frame(cam, frm->cur_size);
- }
- }
- cam->frame_count++;
- frm->ulState = ZR364XX_READ_IDLE;
- frm->cur_size = 0;
- }
- /* done successfully */
- return 0;
-}
-
-static int zr364xx_vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct zr364xx_camera *cam = video_drvdata(file);
-
- strlcpy(cap->driver, DRIVER_DESC, sizeof(cap->driver));
- strlcpy(cap->card, cam->udev->product, sizeof(cap->card));
- strlcpy(cap->bus_info, dev_name(&cam->udev->dev),
- sizeof(cap->bus_info));
- cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING;
- cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-
- return 0;
-}
-
-static int zr364xx_vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- if (i->index != 0)
- return -EINVAL;
- strcpy(i->name, DRIVER_DESC " Camera");
- i->type = V4L2_INPUT_TYPE_CAMERA;
- return 0;
-}
-
-static int zr364xx_vidioc_g_input(struct file *file, void *priv,
- unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int zr364xx_vidioc_s_input(struct file *file, void *priv,
- unsigned int i)
-{
- if (i != 0)
- return -EINVAL;
- return 0;
-}
-
-static int zr364xx_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct zr364xx_camera *cam =
- container_of(ctrl->handler, struct zr364xx_camera, ctrl_handler);
- int temp;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- /* hardware brightness */
- send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0);
- temp = (0x60 << 8) + 127 - ctrl->val;
- send_control_msg(cam->udev, 1, temp, 0, NULL, 0);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int zr364xx_vidioc_enum_fmt_vid_cap(struct file *file,
- void *priv, struct v4l2_fmtdesc *f)
-{
- if (f->index > 0)
- return -EINVAL;
- f->flags = V4L2_FMT_FLAG_COMPRESSED;
- strcpy(f->description, formats[0].name);
- f->pixelformat = formats[0].fourcc;
- return 0;
-}
-
-static char *decode_fourcc(__u32 pixelformat, char *buf)
-{
- buf[0] = pixelformat & 0xff;
- buf[1] = (pixelformat >> 8) & 0xff;
- buf[2] = (pixelformat >> 16) & 0xff;
- buf[3] = (pixelformat >> 24) & 0xff;
- buf[4] = '\0';
- return buf;
-}
-
-static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct zr364xx_camera *cam = video_drvdata(file);
- char pixelformat_name[5];
-
- if (cam == NULL)
- return -ENODEV;
-
- if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) {
- DBG("%s: unsupported pixelformat V4L2_PIX_FMT_%s\n", __func__,
- decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name));
- return -EINVAL;
- }
-
- if (!(f->fmt.pix.width == 160 && f->fmt.pix.height == 120) &&
- !(f->fmt.pix.width == 640 && f->fmt.pix.height == 480)) {
- f->fmt.pix.width = 320;
- f->fmt.pix.height = 240;
- }
-
- f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
- f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
- f->fmt.pix.priv = 0;
- DBG("%s: V4L2_PIX_FMT_%s (%d) ok!\n", __func__,
- decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name),
- f->fmt.pix.field);
- return 0;
-}
-
-static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct zr364xx_camera *cam;
-
- if (file == NULL)
- return -ENODEV;
- cam = video_drvdata(file);
-
- f->fmt.pix.pixelformat = formats[0].fourcc;
- f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.width = cam->width;
- f->fmt.pix.height = cam->height;
- f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
- f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
- f->fmt.pix.priv = 0;
- return 0;
-}
-
-static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct zr364xx_camera *cam = video_drvdata(file);
- struct videobuf_queue *q = &cam->vb_vidq;
- char pixelformat_name[5];
- int ret = zr364xx_vidioc_try_fmt_vid_cap(file, cam, f);
- int i;
-
- if (ret < 0)
- return ret;
-
- mutex_lock(&q->vb_lock);
-
- if (videobuf_queue_is_busy(&cam->vb_vidq)) {
- DBG("%s queue busy\n", __func__);
- ret = -EBUSY;
- goto out;
- }
-
- if (cam->owner) {
- DBG("%s can't change format after started\n", __func__);
- ret = -EBUSY;
- goto out;
- }
-
- cam->width = f->fmt.pix.width;
- cam->height = f->fmt.pix.height;
- DBG("%s: %dx%d mode selected\n", __func__,
- cam->width, cam->height);
- f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
- f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
- f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
- f->fmt.pix.priv = 0;
- cam->vb_vidq.field = f->fmt.pix.field;
-
- if (f->fmt.pix.width == 160 && f->fmt.pix.height == 120)
- mode = 1;
- else if (f->fmt.pix.width == 640 && f->fmt.pix.height == 480)
- mode = 2;
- else
- mode = 0;
-
- m0d1[0] = mode;
- m1[2].value = 0xf000 + mode;
- m2[1].value = 0xf000 + mode;
-
- /* special case for METHOD3, the modes are different */
- if (cam->method == METHOD3) {
- switch (mode) {
- case 1:
- m2[1].value = 0xf000 + 4;
- break;
- case 2:
- m2[1].value = 0xf000 + 0;
- break;
- default:
- m2[1].value = 0xf000 + 1;
- break;
- }
- }
-
- header2[437] = cam->height / 256;
- header2[438] = cam->height % 256;
- header2[439] = cam->width / 256;
- header2[440] = cam->width % 256;
-
- for (i = 0; init[cam->method][i].size != -1; i++) {
- ret =
- send_control_msg(cam->udev, 1, init[cam->method][i].value,
- 0, init[cam->method][i].bytes,
- init[cam->method][i].size);
- if (ret < 0) {
- dev_err(&cam->udev->dev,
- "error during resolution change sequence: %d\n", i);
- goto out;
- }
- }
-
- /* Added some delay here, since opening/closing the camera quickly,
- * like Ekiga does during its startup, can crash the webcam
- */
- mdelay(100);
- cam->skip = 2;
- ret = 0;
-
-out:
- mutex_unlock(&q->vb_lock);
-
- DBG("%s: V4L2_PIX_FMT_%s (%d) ok!\n", __func__,
- decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name),
- f->fmt.pix.field);
- return ret;
-}
-
-static int zr364xx_vidioc_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct zr364xx_camera *cam = video_drvdata(file);
-
- if (cam->owner && cam->owner != priv)
- return -EBUSY;
- return videobuf_reqbufs(&cam->vb_vidq, p);
-}
-
-static int zr364xx_vidioc_querybuf(struct file *file,
- void *priv,
- struct v4l2_buffer *p)
-{
- int rc;
- struct zr364xx_camera *cam = video_drvdata(file);
- rc = videobuf_querybuf(&cam->vb_vidq, p);
- return rc;
-}
-
-static int zr364xx_vidioc_qbuf(struct file *file,
- void *priv,
- struct v4l2_buffer *p)
-{
- int rc;
- struct zr364xx_camera *cam = video_drvdata(file);
- _DBG("%s\n", __func__);
- if (cam->owner && cam->owner != priv)
- return -EBUSY;
- rc = videobuf_qbuf(&cam->vb_vidq, p);
- return rc;
-}
-
-static int zr364xx_vidioc_dqbuf(struct file *file,
- void *priv,
- struct v4l2_buffer *p)
-{
- int rc;
- struct zr364xx_camera *cam = video_drvdata(file);
- _DBG("%s\n", __func__);
- if (cam->owner && cam->owner != priv)
- return -EBUSY;
- rc = videobuf_dqbuf(&cam->vb_vidq, p, file->f_flags & O_NONBLOCK);
- return rc;
-}
-
-static void read_pipe_completion(struct urb *purb)
-{
- struct zr364xx_pipeinfo *pipe_info;
- struct zr364xx_camera *cam;
- int pipe;
-
- pipe_info = purb->context;
- _DBG("%s %p, status %d\n", __func__, purb, purb->status);
- if (pipe_info == NULL) {
- printk(KERN_ERR KBUILD_MODNAME ": no context!\n");
- return;
- }
-
- cam = pipe_info->cam;
- if (cam == NULL) {
- printk(KERN_ERR KBUILD_MODNAME ": no context!\n");
- return;
- }
-
- /* if shutting down, do not resubmit, exit immediately */
- if (purb->status == -ESHUTDOWN) {
- DBG("%s, err shutdown\n", __func__);
- pipe_info->err_count++;
- return;
- }
-
- if (pipe_info->state == 0) {
- DBG("exiting USB pipe\n");
- return;
- }
-
- if (purb->actual_length < 0 ||
- purb->actual_length > pipe_info->transfer_size) {
- dev_err(&cam->udev->dev, "wrong number of bytes\n");
- return;
- }
-
- if (purb->status == 0)
- zr364xx_read_video_callback(cam, pipe_info, purb);
- else {
- pipe_info->err_count++;
- DBG("%s: failed URB %d\n", __func__, purb->status);
- }
-
- pipe = usb_rcvbulkpipe(cam->udev, cam->read_endpoint);
-
- /* reuse urb */
- usb_fill_bulk_urb(pipe_info->stream_urb, cam->udev,
- pipe,
- pipe_info->transfer_buffer,
- pipe_info->transfer_size,
- read_pipe_completion, pipe_info);
-
- if (pipe_info->state != 0) {
- purb->status = usb_submit_urb(pipe_info->stream_urb,
- GFP_ATOMIC);
-
- if (purb->status)
- dev_err(&cam->udev->dev,
- "error submitting urb (error=%i)\n",
- purb->status);
- } else
- DBG("read pipe complete state 0\n");
-}
-
-static int zr364xx_start_readpipe(struct zr364xx_camera *cam)
-{
- int pipe;
- int retval;
- struct zr364xx_pipeinfo *pipe_info = cam->pipe;
- pipe = usb_rcvbulkpipe(cam->udev, cam->read_endpoint);
- DBG("%s: start pipe IN x%x\n", __func__, cam->read_endpoint);
-
- pipe_info->state = 1;
- pipe_info->err_count = 0;
- pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!pipe_info->stream_urb) {
- dev_err(&cam->udev->dev, "ReadStream: Unable to alloc URB\n");
- return -ENOMEM;
- }
- /* transfer buffer allocated in board_init */
- usb_fill_bulk_urb(pipe_info->stream_urb, cam->udev,
- pipe,
- pipe_info->transfer_buffer,
- pipe_info->transfer_size,
- read_pipe_completion, pipe_info);
-
- DBG("submitting URB %p\n", pipe_info->stream_urb);
- retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
- if (retval) {
- printk(KERN_ERR KBUILD_MODNAME ": start read pipe failed\n");
- return retval;
- }
-
- return 0;
-}
-
-static void zr364xx_stop_readpipe(struct zr364xx_camera *cam)
-{
- struct zr364xx_pipeinfo *pipe_info;
-
- if (cam == NULL) {
- printk(KERN_ERR KBUILD_MODNAME ": invalid device\n");
- return;
- }
- DBG("stop read pipe\n");
- pipe_info = cam->pipe;
- if (pipe_info) {
- if (pipe_info->state != 0)
- pipe_info->state = 0;
-
- if (pipe_info->stream_urb) {
- /* cancel urb */
- usb_kill_urb(pipe_info->stream_urb);
- usb_free_urb(pipe_info->stream_urb);
- pipe_info->stream_urb = NULL;
- }
- }
- return;
-}
-
-/* starts acquisition process */
-static int zr364xx_start_acquire(struct zr364xx_camera *cam)
-{
- int j;
-
- DBG("start acquire\n");
-
- cam->last_frame = -1;
- cam->cur_frame = 0;
- for (j = 0; j < FRAMES; j++) {
- cam->buffer.frame[j].ulState = ZR364XX_READ_IDLE;
- cam->buffer.frame[j].cur_size = 0;
- }
- cam->b_acquire = 1;
- return 0;
-}
-
-static inline int zr364xx_stop_acquire(struct zr364xx_camera *cam)
-{
- cam->b_acquire = 0;
- return 0;
-}
-
-static int zr364xx_prepare(struct zr364xx_camera *cam)
-{
- int res;
- int i, j;
-
- for (i = 0; init[cam->method][i].size != -1; i++) {
- res = send_control_msg(cam->udev, 1, init[cam->method][i].value,
- 0, init[cam->method][i].bytes,
- init[cam->method][i].size);
- if (res < 0) {
- dev_err(&cam->udev->dev,
- "error during open sequence: %d\n", i);
- return res;
- }
- }
-
- cam->skip = 2;
- cam->last_frame = -1;
- cam->cur_frame = 0;
- cam->frame_count = 0;
- for (j = 0; j < FRAMES; j++) {
- cam->buffer.frame[j].ulState = ZR364XX_READ_IDLE;
- cam->buffer.frame[j].cur_size = 0;
- }
- v4l2_ctrl_handler_setup(&cam->ctrl_handler);
- return 0;
-}
-
-static int zr364xx_vidioc_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct zr364xx_camera *cam = video_drvdata(file);
- int res;
-
- DBG("%s\n", __func__);
-
- if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (cam->owner && cam->owner != priv)
- return -EBUSY;
-
- res = zr364xx_prepare(cam);
- if (res)
- return res;
- res = videobuf_streamon(&cam->vb_vidq);
- if (res == 0) {
- zr364xx_start_acquire(cam);
- cam->owner = file->private_data;
- }
- return res;
-}
-
-static int zr364xx_vidioc_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct zr364xx_camera *cam = video_drvdata(file);
-
- DBG("%s\n", __func__);
- if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (cam->owner && cam->owner != priv)
- return -EBUSY;
- zr364xx_stop_acquire(cam);
- return videobuf_streamoff(&cam->vb_vidq);
-}
-
-
-/* open the camera */
-static int zr364xx_open(struct file *file)
-{
- struct zr364xx_camera *cam = video_drvdata(file);
- int err;
-
- DBG("%s\n", __func__);
-
- if (mutex_lock_interruptible(&cam->lock))
- return -ERESTARTSYS;
-
- err = v4l2_fh_open(file);
- if (err)
- goto out;
-
- /* Added some delay here, since opening/closing the camera quickly,
- * like Ekiga does during its startup, can crash the webcam
- */
- mdelay(100);
- err = 0;
-
-out:
- mutex_unlock(&cam->lock);
- DBG("%s: %d\n", __func__, err);
- return err;
-}
-
-static void zr364xx_release(struct v4l2_device *v4l2_dev)
-{
- struct zr364xx_camera *cam =
- container_of(v4l2_dev, struct zr364xx_camera, v4l2_dev);
- unsigned long i;
-
- v4l2_device_unregister(&cam->v4l2_dev);
-
- videobuf_mmap_free(&cam->vb_vidq);
-
- /* release sys buffers */
- for (i = 0; i < FRAMES; i++) {
- if (cam->buffer.frame[i].lpvbits) {
- DBG("vfree %p\n", cam->buffer.frame[i].lpvbits);
- vfree(cam->buffer.frame[i].lpvbits);
- }
- cam->buffer.frame[i].lpvbits = NULL;
- }
-
- v4l2_ctrl_handler_free(&cam->ctrl_handler);
- /* release transfer buffer */
- kfree(cam->pipe->transfer_buffer);
- kfree(cam);
-}
-
-/* release the camera */
-static int zr364xx_close(struct file *file)
-{
- struct zr364xx_camera *cam;
- struct usb_device *udev;
- int i;
-
- DBG("%s\n", __func__);
- cam = video_drvdata(file);
-
- mutex_lock(&cam->lock);
- udev = cam->udev;
-
- if (file->private_data == cam->owner) {
- /* turn off stream */
- if (cam->b_acquire)
- zr364xx_stop_acquire(cam);
- videobuf_streamoff(&cam->vb_vidq);
-
- for (i = 0; i < 2; i++) {
- send_control_msg(udev, 1, init[cam->method][i].value,
- 0, init[cam->method][i].bytes,
- init[cam->method][i].size);
- }
- cam->owner = NULL;
- }
-
- /* Added some delay here, since opening/closing the camera quickly,
- * like Ekiga does during its startup, can crash the webcam
- */
- mdelay(100);
- mutex_unlock(&cam->lock);
- return v4l2_fh_release(file);
-}
-
-
-static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct zr364xx_camera *cam = video_drvdata(file);
- int ret;
-
- if (cam == NULL) {
- DBG("%s: cam == NULL\n", __func__);
- return -ENODEV;
- }
- DBG("mmap called, vma=0x%08lx\n", (unsigned long)vma);
-
- ret = videobuf_mmap_mapper(&cam->vb_vidq, vma);
-
- DBG("vma start=0x%08lx, size=%ld, ret=%d\n",
- (unsigned long)vma->vm_start,
- (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
- return ret;
-}
-
-static unsigned int zr364xx_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct zr364xx_camera *cam = video_drvdata(file);
- struct videobuf_queue *q = &cam->vb_vidq;
- unsigned res = v4l2_ctrl_poll(file, wait);
-
- _DBG("%s\n", __func__);
-
- return res | videobuf_poll_stream(file, q, wait);
-}
-
-static const struct v4l2_ctrl_ops zr364xx_ctrl_ops = {
- .s_ctrl = zr364xx_s_ctrl,
-};
-
-static const struct v4l2_file_operations zr364xx_fops = {
- .owner = THIS_MODULE,
- .open = zr364xx_open,
- .release = zr364xx_close,
- .read = zr364xx_read,
- .mmap = zr364xx_mmap,
- .unlocked_ioctl = video_ioctl2,
- .poll = zr364xx_poll,
-};
-
-static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = {
- .vidioc_querycap = zr364xx_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = zr364xx_vidioc_enum_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = zr364xx_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = zr364xx_vidioc_s_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = zr364xx_vidioc_g_fmt_vid_cap,
- .vidioc_enum_input = zr364xx_vidioc_enum_input,
- .vidioc_g_input = zr364xx_vidioc_g_input,
- .vidioc_s_input = zr364xx_vidioc_s_input,
- .vidioc_streamon = zr364xx_vidioc_streamon,
- .vidioc_streamoff = zr364xx_vidioc_streamoff,
- .vidioc_reqbufs = zr364xx_vidioc_reqbufs,
- .vidioc_querybuf = zr364xx_vidioc_querybuf,
- .vidioc_qbuf = zr364xx_vidioc_qbuf,
- .vidioc_dqbuf = zr364xx_vidioc_dqbuf,
- .vidioc_log_status = v4l2_ctrl_log_status,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static struct video_device zr364xx_template = {
- .name = DRIVER_DESC,
- .fops = &zr364xx_fops,
- .ioctl_ops = &zr364xx_ioctl_ops,
- .release = video_device_release_empty,
-};
-
-
-
-/*******************/
-/* USB integration */
-/*******************/
-static int zr364xx_board_init(struct zr364xx_camera *cam)
-{
- struct zr364xx_pipeinfo *pipe = cam->pipe;
- unsigned long i;
-
- DBG("board init: %p\n", cam);
- memset(pipe, 0, sizeof(*pipe));
- pipe->cam = cam;
- pipe->transfer_size = BUFFER_SIZE;
-
- pipe->transfer_buffer = kzalloc(pipe->transfer_size,
- GFP_KERNEL);
- if (pipe->transfer_buffer == NULL) {
- DBG("out of memory!\n");
- return -ENOMEM;
- }
-
- cam->b_acquire = 0;
- cam->frame_count = 0;
-
- /*** start create system buffers ***/
- for (i = 0; i < FRAMES; i++) {
- /* always allocate maximum size for system buffers */
- cam->buffer.frame[i].lpvbits = vmalloc(MAX_FRAME_SIZE);
-
- DBG("valloc %p, idx %lu, pdata %p\n",
- &cam->buffer.frame[i], i,
- cam->buffer.frame[i].lpvbits);
- if (cam->buffer.frame[i].lpvbits == NULL) {
- printk(KERN_INFO KBUILD_MODNAME ": out of memory. "
- "Using less frames\n");
- break;
- }
- }
-
- if (i == 0) {
- printk(KERN_INFO KBUILD_MODNAME ": out of memory. Aborting\n");
- kfree(cam->pipe->transfer_buffer);
- cam->pipe->transfer_buffer = NULL;
- return -ENOMEM;
- } else
- cam->buffer.dwFrames = i;
-
- /* make sure internal states are set */
- for (i = 0; i < FRAMES; i++) {
- cam->buffer.frame[i].ulState = ZR364XX_READ_IDLE;
- cam->buffer.frame[i].cur_size = 0;
- }
-
- cam->cur_frame = 0;
- cam->last_frame = -1;
- /*** end create system buffers ***/
-
- /* start read pipe */
- zr364xx_start_readpipe(cam);
- DBG(": board initialized\n");
- return 0;
-}
-
-static int zr364xx_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct zr364xx_camera *cam = NULL;
- struct usb_host_interface *iface_desc;
- struct usb_endpoint_descriptor *endpoint;
- struct v4l2_ctrl_handler *hdl;
- int err;
- int i;
-
- DBG("probing...\n");
-
- dev_info(&intf->dev, DRIVER_DESC " compatible webcam plugged\n");
- dev_info(&intf->dev, "model %04x:%04x detected\n",
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct));
-
- cam = kzalloc(sizeof(struct zr364xx_camera), GFP_KERNEL);
- if (cam == NULL) {
- dev_err(&udev->dev, "cam: out of memory !\n");
- return -ENOMEM;
- }
-
- cam->v4l2_dev.release = zr364xx_release;
- err = v4l2_device_register(&intf->dev, &cam->v4l2_dev);
- if (err < 0) {
- dev_err(&udev->dev, "couldn't register v4l2_device\n");
- kfree(cam);
- return err;
- }
- hdl = &cam->ctrl_handler;
- v4l2_ctrl_handler_init(hdl, 1);
- v4l2_ctrl_new_std(hdl, &zr364xx_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 127, 1, 64);
- if (hdl->error) {
- err = hdl->error;
- dev_err(&udev->dev, "couldn't register control\n");
- goto fail;
- }
- /* save the init method used by this camera */
- cam->method = id->driver_info;
- mutex_init(&cam->lock);
- cam->vdev = zr364xx_template;
- cam->vdev.lock = &cam->lock;
- cam->vdev.v4l2_dev = &cam->v4l2_dev;
- cam->vdev.ctrl_handler = &cam->ctrl_handler;
- set_bit(V4L2_FL_USE_FH_PRIO, &cam->vdev.flags);
- video_set_drvdata(&cam->vdev, cam);
- if (debug)
- cam->vdev.debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
-
- cam->udev = udev;
-
- switch (mode) {
- case 1:
- dev_info(&udev->dev, "160x120 mode selected\n");
- cam->width = 160;
- cam->height = 120;
- break;
- case 2:
- dev_info(&udev->dev, "640x480 mode selected\n");
- cam->width = 640;
- cam->height = 480;
- break;
- default:
- dev_info(&udev->dev, "320x240 mode selected\n");
- cam->width = 320;
- cam->height = 240;
- break;
- }
-
- m0d1[0] = mode;
- m1[2].value = 0xf000 + mode;
- m2[1].value = 0xf000 + mode;
-
- /* special case for METHOD3, the modes are different */
- if (cam->method == METHOD3) {
- switch (mode) {
- case 1:
- m2[1].value = 0xf000 + 4;
- break;
- case 2:
- m2[1].value = 0xf000 + 0;
- break;
- default:
- m2[1].value = 0xf000 + 1;
- break;
- }
- }
-
- header2[437] = cam->height / 256;
- header2[438] = cam->height % 256;
- header2[439] = cam->width / 256;
- header2[440] = cam->width % 256;
-
- cam->nb = 0;
-
- DBG("dev: %p, udev %p interface %p\n", cam, cam->udev, intf);
-
- /* set up the endpoint information */
- iface_desc = intf->cur_altsetting;
- DBG("num endpoints %d\n", iface_desc->desc.bNumEndpoints);
- for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
- endpoint = &iface_desc->endpoint[i].desc;
- if (!cam->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
- /* we found the bulk in endpoint */
- cam->read_endpoint = endpoint->bEndpointAddress;
- }
- }
-
- if (!cam->read_endpoint) {
- err = -ENOMEM;
- dev_err(&intf->dev, "Could not find bulk-in endpoint\n");
- goto fail;
- }
-
- /* v4l */
- INIT_LIST_HEAD(&cam->vidq.active);
- cam->vidq.cam = cam;
-
- usb_set_intfdata(intf, cam);
-
- /* load zr364xx board specific */
- err = zr364xx_board_init(cam);
- if (!err)
- err = v4l2_ctrl_handler_setup(hdl);
- if (err)
- goto fail;
-
- spin_lock_init(&cam->slock);
-
- cam->fmt = formats;
-
- videobuf_queue_vmalloc_init(&cam->vb_vidq, &zr364xx_video_qops,
- NULL, &cam->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_NONE,
- sizeof(struct zr364xx_buffer), cam, &cam->lock);
-
- err = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);
- if (err) {
- dev_err(&udev->dev, "video_register_device failed\n");
- goto fail;
- }
-
- dev_info(&udev->dev, DRIVER_DESC " controlling device %s\n",
- video_device_node_name(&cam->vdev));
- return 0;
-
-fail:
- v4l2_ctrl_handler_free(hdl);
- v4l2_device_unregister(&cam->v4l2_dev);
- kfree(cam);
- return err;
-}
-
-
-static void zr364xx_disconnect(struct usb_interface *intf)
-{
- struct zr364xx_camera *cam = usb_get_intfdata(intf);
-
- mutex_lock(&cam->lock);
- usb_set_intfdata(intf, NULL);
- dev_info(&intf->dev, DRIVER_DESC " webcam unplugged\n");
- video_unregister_device(&cam->vdev);
- v4l2_device_disconnect(&cam->v4l2_dev);
-
- /* stops the read pipe if it is running */
- if (cam->b_acquire)
- zr364xx_stop_acquire(cam);
-
- zr364xx_stop_readpipe(cam);
- mutex_unlock(&cam->lock);
- v4l2_device_put(&cam->v4l2_dev);
-}
-
-
-#ifdef CONFIG_PM
-static int zr364xx_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct zr364xx_camera *cam = usb_get_intfdata(intf);
-
- cam->was_streaming = cam->b_acquire;
- if (!cam->was_streaming)
- return 0;
- zr364xx_stop_acquire(cam);
- zr364xx_stop_readpipe(cam);
- return 0;
-}
-
-static int zr364xx_resume(struct usb_interface *intf)
-{
- struct zr364xx_camera *cam = usb_get_intfdata(intf);
- int res;
-
- if (!cam->was_streaming)
- return 0;
-
- zr364xx_start_readpipe(cam);
- res = zr364xx_prepare(cam);
- if (!res)
- zr364xx_start_acquire(cam);
- return res;
-}
-#endif
-
-/**********************/
-/* Module integration */
-/**********************/
-
-static struct usb_driver zr364xx_driver = {
- .name = "zr364xx",
- .probe = zr364xx_probe,
- .disconnect = zr364xx_disconnect,
-#ifdef CONFIG_PM
- .suspend = zr364xx_suspend,
- .resume = zr364xx_resume,
- .reset_resume = zr364xx_resume,
-#endif
- .id_table = device_table
-};
-
-module_usb_driver(zr364xx_driver);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);